diff --git a/.gitignore b/.gitignore index 4ed47fac3d..155da55558 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,5 @@ ExternalCoreProjects/Virtu/bin/*.* **/StyleCop.Cache libsnes/vs2015/libsnes.VC.db +waterbox/**/*.wbx +waterbox/**/*.wbx.in diff --git a/.gitmodules b/.gitmodules index 4c6d7804fd..722a7a412c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,7 @@ [submodule "libmupen64plus/mupen64plus-rsp-cxd4"] path = libmupen64plus/mupen64plus-rsp-cxd4 url = https://github.com/TASVideos/mupen64plus-rsp-cxd4.git +[submodule "waterbox/snes9x"] + path = waterbox/snes9x + url = https://github.com/TASVideos/snes9x.git + branch = bizsnes diff --git a/Assets/defctrl.json b/Assets/defctrl.json index 5145e85957..e329f90441 100644 --- a/Assets/defctrl.json +++ b/Assets/defctrl.json @@ -508,19 +508,110 @@ "P1 C": "Z, J1 B4, X1 Y", "P1 L": "Q, J1 B5, X1 LeftShoulder", "P1 R": "W, J1 B6, X1 RightShoulder", - "P2 Up": "", - "P2 Down": "", - "P2 Left": "", - "P2 Right": "", - "P2 Start": "", - "P2 Z": "", - "P2 Y": "", - "P2 X": "", - "P2 C": "", - "P2 B": "", - "P2 A": "", - "P2 L": "", - "P2 R": "" + "P1 Mouse Left": "WMouse L", + "P1 Mouse Center": "WMouse M", + "P1 Mouse Right": "WMouse R", + "P1 Escape": "Escape", + "P1 F1": "F1", + "P1 F2": "F2", + "P1 F3": "F3", + "P1 F4": "F4", + "P1 F5": "F5", + "P1 F6": "F6", + "P1 F7": "F7", + "P1 F8": "F8", + "P1 F9": "F9", + "P1 F10": "F10", + "P1 F11": "F11", + "P1 F12": "F12", + "P1 Grave`": "Grave", + "P1 1(One)": "D1", + "P1 2": "D2", + "P1 3": "D3", + "P1 4": "D4", + "P1 5": "D5", + "P1 6": "D6", + "P1 7": "D7", + "P1 8": "D8", + "P1 9": "D9", + "P1 0(Zero)": "D0", + "P1 Minus-": "Minus", + "P1 Equals=": "Equals", + "P1 Backslash\\": "Backslash", + "P1 Backspace": "Backspace", + "P1 Tab": "Tab", + "P1 Q": "Q", + "P1 W": "W", + "P1 E": "E", + "P1 R(Key)": "R", + "P1 T": "T", + "P1 Y(Key)": "Y", + "P1 U": "U", + "P1 I": "I", + "P1 O": "O", + "P1 P": "P", + "P1 LeftBracket[": "LeftBracket", + "P1 RightBracket]": "RightBracket", + "P1 Enter": "Return", + "P1 CapsLock": "CapsLock", + "P1 A(Key)": "A", + "P1 S": "S", + "P1 D": "D", + "P1 F": "F", + "P1 G": "G", + "P1 H": "H", + "P1 J": "J", + "P1 K": "K", + "P1 L(Key)": "L", + "P1 Semicolon;": "Semicolon", + "P1 Quote'": "Apostrophe", + "P1 LeftShift": "LeftShift", + "P1 Z(Key)": "Z", + "P1 X(Key)": "X", + "P1 C(Key)": "C", + "P1 V": "V", + "P1 B(Key)": "B", + "P1 N": "N", + "P1 M": "M", + "P1 Comma,": "Comma", + "P1 Period.": "Period", + "P1 Slash/": "Slash", + "P1 RightShift": "RightShift", + "P1 LeftCtrl": "LeftControl", + "P1 LeftAlt": "LeftAlt", + "P1 Space": "Space", + "P1 RightAlt": "RightAlt", + "P1 RightCtrl": "RightControl", + "P1 PrintScreen": "", + "P1 ScrollLock": "ScrollLock", + "P1 Pause": "Pause", + "P1 Insert": "Insert", + "P1 Delete": "Delete", + "P1 Home": "Home", + "P1 End": "End", + "P1 PageUp": "PageUp", + "P1 PageDown": "PageDown", + "P1 Up": "UpArrow", + "P1 Down": "DownArrow", + "P1 CursorLeft": "LeftArrow", + "P1 Right": "RightArrow", + "P1 NumLock": "NumberLock", + "P1 KeypadSlash(Divide)": "NumberPadSlash", + "P1 KeypadAsterisk(Multiply)": "NumberPadStar", + "P1 KeypadMinus": "NumberPadMinus", + "P1 KeypadHome/7": "NumberPad7", + "P1 KeypadUp/8": "NumberPad8", + "P1 KeypadPageup/9": "NumberPad9", + "P1 KeypadPlus": "NumberPadPlus", + "P1 KeypadLeft/4": "NumberPad4", + "P1 KeypadCenter/5": "NumberPad5", + "P1 KeypadRight/6": "NumberPad6", + "P1 KeypadEnd/1": "NumberPad1", + "P1 KeypadDown/2": "NumberPad2", + "P1 KeypadPagedown/3": "NumberPad3", + "P1 KeypadEnter": "NumberPadEnter", + "P1 KeypadInsert/0": "NumberPad0", + "P1 KeypadDelete": "NumberPadPeriod" }, "PC Engine Controller": { "Reset": "", @@ -854,6 +945,33 @@ "Caps Lock": "CapsLock", "Previous Disk": "", "Next Disk": "" + }, + "VirtualBoy Controller": { + "L_Up": "UpArrow, X1 DpadUp, X1 LStickUp", + "L_Down": "DownArrow, X1 DpadDown, X1 LStickDown", + "L_Left": "LeftArrow, X1 DpadLeft, X1 LStickLeft", + "L_Right": "RightArrow, X1 DpadRight, X1 LStickRight", + "R_Up": "NumberPad8, X1 RStickUp", + "R_Down": "NumberPad2, X1 RStickDown", + "R_Left": "NumberPad4, X1 RStickLeft", + "R_Right": "NumberPad6, X1 RStickRight", + "B": "Z, X1 X", + "A": "X, X1 A", + "R": "W, X1 LeftShoulder", + "L": "E, X1 RightShoulder", + "Select": "Space, X1 Back", + "Start": "Return, X1 Start", + "Power": "" + }, + "NeoGeo Portable Controller": { + "Up": "UpArrow, X1 DpadUp, X1 LStickUp", + "Down": "DownArrow, X1 DpadDown, X1 LStickDown", + "Left": "LeftArrow, X1 DpadLeft, X1 LStickLeft", + "Right": "RightArrow, X1 DpadRight, X1 LStickRight", + "B": "Z, J1 B1, X1 X", + "A": "X, J1 B2, X1 A", + "Option": "Return, J1 B10, X1 Start", + "Power": "" } }, "AllTrollersAutoFire": { @@ -1100,6 +1218,33 @@ "Caps Lock": "", "Previous Disk": "", "Next Disk": "" + }, + "VirtualBoy Controller": { + "L_Up": "", + "L_Down": "", + "L_Left": "", + "L_Right": "", + "R_Up": "", + "R_Down": "", + "R_Left": "", + "R_Right": "", + "B": "", + "A": "", + "R": "", + "L": "", + "Select": "", + "Start": "", + "Power": "" + }, + "NeoGeo Portable Controller": { + "Up": "", + "Down": "", + "Left": "", + "Right": "", + "B": "", + "A": "", + "Option": "", + "Power": "" } }, "AllTrollersAnalog": { @@ -1286,6 +1431,70 @@ "Mult": 1.0, "Deadzone": 0.1 } + }, + "VirtualBoy Controller": {}, + "NeoGeo Portable Controller": {}, + "Saturn Controller": { + "P1 Right Stick Horizontal": { + "Value": "X1 RightThumbX", + "Mult": 1.0, + "Deadzone": 0.1 + }, + "P1 Right Stick Vertical": { + "Value": "", + "Mult": 1.0, + "Deadzone": 0.1 + }, + "P1 Right Throttle": { + "Value": "X1 RightThumbY", + "Mult": 1.0, + "Deadzone": 0.1 + }, + "P1 Left Stick Horizontal": { + "Value": "X1 LeftThumbX", + "Mult": 1.0, + "Deadzone": 0.1 + }, + "P1 Left Stick Vertical": { + "Value": "X1 LeftThumbY", + "Mult": 1.0, + "Deadzone": 0.1 + }, + "P1 Left Throttle": { + "Value": "", + "Mult": 1.0, + "Deadzone": 0.1 + }, + "P1 Wheel": { + "Value": "X1 LeftThumbX", + "Mult": 1.0, + "Deadzone": 0.1 + }, + "P1 Stick Horizontal": { + "Value": "X1 LeftThumbX", + "Mult": 1.0, + "Deadzone": 0.1 + }, + "P1 Stick Vertical": { + "Value": "X1 LeftThumbY", + "Mult": 1.0, + "Deadzone": 0.1 + }, + "P1 Throttle": { + "Value": "X1 RightThumbX", + "Mult": 1.0, + "Deadzone": 0.1 + }, + "P1 X": { + "Value": "WMouse X", + "Mult": 1.0, + "Deadzone": 0.1 + }, + "P1 Y": { + "Value": "WMouse Y", + "Mult": 1.0, + "Deadzone": 0.1 + } } } } \ No newline at end of file diff --git a/Assets/gamedb/gamedb_snes.txt b/Assets/gamedb/gamedb_snes.txt index 6539c6a775..81abec93dd 100644 --- a/Assets/gamedb/gamedb_snes.txt +++ b/Assets/gamedb/gamedb_snes.txt @@ -81,7 +81,7 @@ A9FC2E46A38FD51EBDC25F6F261925F7CB6754F7 G Aladdin (Japan) SNES DB4C5AE21420AA79F4519B542B03962A9293464D G Aladdin (Spain) SNES 48DDA773437CD755C31D2422F1DFD3A3FD6EE76B G Aladdin (USA) (Beta) SNES BD5FEA18CE7456CC0231A39473927D8EA9C6589B G Aladdin (USA) SNES -A1A682F723573254046A8AF06B92FE408FC4207A G Albert Odyssey (Japan) (BS) SNES +A1A682F723573254046A8AF06B92FE408FC4207A B Albert Odyssey (Japan) (BS) SNES 525AC489230002E2E9294846154D962EF9A2B941 G Albert Odyssey (Japan) SNES B3B78710000D467DC0304EFA0245D2CF7AE23D88 G Albert Odyssey 2 - Jashin no Taidou (Japan) SNES DAC852EA9FF3141DE5DC6377307B16811F607008 G Alcahest (Japan) SNES @@ -3517,4 +3517,12 @@ F650083142D9F3EB2BF1B315B44D18077743FE17 G Zool no Yume Bouken (Japan) SNES 051C767B843FC4112E0B06C2F81B65ABBAC9E7FC G Zoop (USA) SNES 21286747D360C03E3BF86CD4504508CE55DEFF8F G Zootto Mahjong! (Japan) (NP) SNES 2EE76761E023F0C51FBBF4797C175A7C752E788C G Zootto Mahjong! - Event Version (Japan) (BS) SNES -8EC66C5DCDA3392C27BC532A06D726783C3A1565 G Zootto Mahjong! - Preview Ban (Japan) (BS) SNES \ No newline at end of file +8EC66C5DCDA3392C27BC532A06D726783C3A1565 G Zootto Mahjong! - Preview Ban (Japan) (BS) SNES + +;Junk +3064E664D34859649B67559F0ED0C2FFD6948031 B ActRaiser 2 (U) [b1] SNES +BD0C52940A96BF470AB383100A1EA0390B145453 B Addams Family, The - Pugsley's Scavenger Hunt (Beta) [b2] SNES +378D60AEA423F97DAF8314ADCD932F2E1B75A0DC B Addams Family, The - Pugsley's Scavenger Hunt (E) [t1] SNES +75CF0949C6D35FFA5856A11B3449F674038CD7DF B Aerobiz (U) [b1] SNES +CAAAC55BB9450BE2A1827DA1DA81807EC0941906 B Aladdin (Beta) [h1+C] SNES +4AA6D9BA00F80BC2D22ECE4EF9753864380A2B9D B Aladdin (Beta) [h3] SNES \ No newline at end of file diff --git a/BizHawk.Client.ApiHawk/BizHawk.Client.ApiHawk.csproj b/BizHawk.Client.ApiHawk/BizHawk.Client.ApiHawk.csproj index 4444e73164..47c386af86 100644 --- a/BizHawk.Client.ApiHawk/BizHawk.Client.ApiHawk.csproj +++ b/BizHawk.Client.ApiHawk/BizHawk.Client.ApiHawk.csproj @@ -1,8 +1,8 @@  - + true - ..\output64\dll\ + ..\output\dll\ DEBUG;TRACE full x64 @@ -13,21 +13,22 @@ MinimumRecommendedRules.ruleset ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false - ..\output64\dll\ + ..\output\dll\ TRACE true pdbonly x64 - ..\output\dll\BizHawk.Client.ApiHawk.dll.CodeAnalysisLog.xml true GlobalSuppressions.cs prompt MinimumRecommendedRules.ruleset ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - ..\output64\dll\BizHawk.Client.ApiHawk.XML + ..\output\dll\BizHawk.Client.ApiHawk.XML + false @@ -38,51 +39,9 @@ Properties BizHawk.Client.ApiHawk BizHawk.Client.ApiHawk - v4.0 + v4.6.1 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - x86 - - - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - true - ..\output\dll\ - DEBUG;TRACE - full - x86 - prompt - MinimumRecommendedRules.ruleset - - - - - ..\output\dll\ - TRACE - true - pdbonly - x86 - prompt - MinimumRecommendedRules.ruleset - ..\output\dll\BizHawk.Client.ApiHawk.XML + diff --git a/BizHawk.Client.ApiHawk/Classes/BizHawkSystemIdToCoreSystemEnumConverter.cs b/BizHawk.Client.ApiHawk/Classes/BizHawkSystemIdToCoreSystemEnumConverter.cs index 0316c0f78c..0f5d8f475f 100644 --- a/BizHawk.Client.ApiHawk/Classes/BizHawkSystemIdToCoreSystemEnumConverter.cs +++ b/BizHawk.Client.ApiHawk/Classes/BizHawkSystemIdToCoreSystemEnumConverter.cs @@ -99,6 +99,13 @@ namespace BizHawk.Client.ApiHawk case "WSWAN": return CoreSystem.WonderSwan; + case "VB": + case "NGP": + case "DNGP": + case "O2": + case "SGB": + return 0; // like I give a shit + default: throw new IndexOutOfRangeException(string.Format("{0} is missing in convert list", value)); } diff --git a/BizHawk.Client.Common/Api/CoreSystem.cs b/BizHawk.Client.Common/Api/CoreSystem.cs index f81654fe77..132a832b98 100644 --- a/BizHawk.Client.Common/Api/CoreSystem.cs +++ b/BizHawk.Client.Common/Api/CoreSystem.cs @@ -27,6 +27,8 @@ PSP, Playstation, WonderSwan, - Libretro + Libretro, + VirtualBoy, + NeoGeoPocket } } diff --git a/BizHawk.Client.Common/BinarySaveStates.cs b/BizHawk.Client.Common/BinarySaveStates.cs index 64512fa7c8..2554baa941 100644 --- a/BizHawk.Client.Common/BinarySaveStates.cs +++ b/BizHawk.Client.Common/BinarySaveStates.cs @@ -324,9 +324,10 @@ namespace BizHawk.Client.Common public BinaryStateSaver(string path, bool notamovie = true) // notamovie is hack, really should have separate something { - _zip = new IonicZipWriter(path, notamovie ? Global.Config.SaveStateCompressionLevelNormal : Global.Config.MovieCompressionLevel); + ////_zip = new IonicZipWriter(path, notamovie ? Global.Config.SaveStateCompressionLevelNormal : Global.Config.MovieCompressionLevel); ////_zip = new SharpZipWriter(path, Global.Config.SaveStateCompressionLevelNormal); ////_zip = new SevenZipWriter(path, Global.Config.SaveStateCompressionLevelNormal); + _zip = new FrameworkZipWriter(path, notamovie ? Global.Config.SaveStateCompressionLevelNormal : Global.Config.MovieCompressionLevel); if (notamovie) { diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj index 993c7638fd..19bb857602 100644 --- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj +++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj @@ -1,5 +1,5 @@  - + Debug x86 @@ -10,38 +10,17 @@ Properties BizHawk.Client.Common BizHawk.Client.Common - v4.0 + v4.6.1 512 - - - true - full - false - ..\output\dll\ - TRACE;DEBUG;DOTNET20;UNMANAGED;COMPRESS;WINDOWS - prompt - 4 - true - x86 - - - pdbonly - true - ..\output\dll\ - TRACE;DOTNET20;UNMANAGED;COMPRESS;WINDOWS - prompt - 4 - true - x86 + true - ..\output64\dll\ + ..\output\dll\ TRACE;DEBUG;DOTNET20;UNMANAGED;COMPRESS;WINDOWS true full x64 - ..\output\dll\BizHawk.Client.Common.dll.CodeAnalysisLog.xml true GlobalSuppressions.cs prompt @@ -51,15 +30,15 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules false false + false - ..\output64\dll\ + ..\output\dll\ TRACE;DOTNET20;UNMANAGED;COMPRESS;WINDOWS true true pdbonly x64 - ..\output\dll\BizHawk.Client.Common.dll.CodeAnalysisLog.xml true GlobalSuppressions.cs prompt @@ -69,6 +48,7 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules false false + false @@ -87,6 +67,7 @@ + @@ -151,6 +132,8 @@ + + @@ -191,6 +174,8 @@ + + diff --git a/BizHawk.Client.Common/FrameworkFastZipWriter.cs b/BizHawk.Client.Common/FrameworkFastZipWriter.cs new file mode 100644 index 0000000000..8612b66b44 --- /dev/null +++ b/BizHawk.Client.Common/FrameworkFastZipWriter.cs @@ -0,0 +1,296 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Client.Common +{ + /// + /// this almost works, but it loses all of its speed advantages over FrameworkZipWriter from slow CRC calculation. + /// + public class FrameworkFastZipWriter : IZipWriter + { + private Stream _output; + private readonly CompressionLevel _level; + + private byte[] _localHeader; + private List _endBlobs = new List(); + private byte[] _fileHeaderTemplate; + private int _numEntries; + private bool _disposed; + + private class CRC32Stream : Stream + { + // Lookup table for speed. + private static readonly uint[] Crc32Table; + + static CRC32Stream() + { + Crc32Table = new uint[256]; + for (uint i = 0; i < 256; ++i) + { + uint crc = i; + for (int j = 8; j > 0; --j) + { + if ((crc & 1) == 1) + { + crc = (crc >> 1) ^ 0xEDB88320; + } + else + { + crc >>= 1; + } + } + + Crc32Table[i] = crc; + } + } + + private uint _crc = 0xffffffff; + private int _count = 0; + private Stream _baseStream; + + public int Size => _count; + public uint Crc => ~_crc; + + public CRC32Stream(Stream baseStream) + { + _baseStream = baseStream; + } + + private void CalculateByte(byte b) + { + _crc = (_crc >> 8) ^ Crc32Table[b ^ (_crc & 0xff)]; + } + + public override void Write(byte[] buffer, int offset, int count) + { + for (int i = offset; i < offset + count; i++) + { + CalculateByte(buffer[i]); + } + _count += count; + _baseStream.Write(buffer, offset, count); + } + + public override void WriteByte(byte value) + { + CalculateByte(value); + _count++; + _baseStream.WriteByte(value); + } + + public override void Flush() + { + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotImplementedException(); + } + + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + throw new NotImplementedException(); + } + + public override bool CanRead => false; + + public override bool CanSeek => false; + + public override bool CanWrite => true; + + public override long Length + { + get + { + throw new NotImplementedException(); + } + } + + public override long Position + { + get + { + throw new NotImplementedException(); + } + + set + { + throw new NotImplementedException(); + } + } + } + + public FrameworkFastZipWriter(string path, int compressionlevel) + { + _output = new FileStream(path, FileMode.Create, FileAccess.Write); + if (compressionlevel == 0) + throw new NotImplementedException(); + //_level = CompressionLevel.NoCompression; + else if (compressionlevel < 5) + _level = CompressionLevel.Fastest; + else + _level = CompressionLevel.Optimal; + + var dt = DateTime.Now; + var mtime = dt.Second >> 1 + | dt.Minute << 5 + | dt.Hour << 11; + var mdate = dt.Day + | dt.Month << 5 + | (dt.Year - 1980) << 9; + + var modifiedDate = new byte[] + { + (byte)(mtime & 0xff), + (byte)(mtime >> 8), + (byte)(mdate & 0xff), + (byte)(mdate >> 8) + }; + + _localHeader = new byte[] + { + 0x50, 0x4b, 0x03, 0x04, // signature + 0x14, 0x00, // version + 0x08, 0x00, // flags: has data descriptor + 0x08, 0x00, // method: deflate + modifiedDate[0], modifiedDate[1], // mod time + modifiedDate[2], modifiedDate[3], // mod date + 0x00, 0x00, 0x00, 0x00, // crc32 + 0x00, 0x00, 0x00, 0x00, // compressed size + 0x00, 0x00, 0x00, 0x00, // uncompressed size + 0x00, 0x00, // filename length + 0x00, 0x00, // extra field length + }; + + _fileHeaderTemplate = new byte[] + { + 0x50, 0x4b, 0x01, 0x02, // signature + 0x17, 0x03, // ?? + 0x14, 0x00, // version + 0x08, 0x00, // flags: has data descriptor + 0x08, 0x00, // method: deflate + modifiedDate[0], modifiedDate[1], // mod time + modifiedDate[2], modifiedDate[3], // mod date + 0x00, 0x00, 0x00, 0x00, // crc32 + 0x00, 0x00, 0x00, 0x00, // compressed size + 0x00, 0x00, 0x00, 0x00, // uncompressed size + 0x00, 0x00, // filename length + 0x00, 0x00, // extra field length + 0x00, 0x00, // file comment length + 0x00, 0x00, // disk #, + 0x00, 0x00, // internal attributes + 0x00, 0x00, 0x00, 0x00, // external attributes + 0x00, 0x00, 0x00, 0x00, // local header offset + }; + } + + public void Dispose() + { + if (!_disposed) + { + WriteFooter(); + _output.Dispose(); + _output = null; + _disposed = true; + } + } + + public void WriteItem(string name, Action callback) + { + var nameb = Encoding.ASCII.GetBytes(name); + _localHeader[26] = (byte)nameb.Length; + _localHeader[27] = (byte)(nameb.Length >> 8); + + var localHeaderOffset = (int)(_output.Position); + + _output.Write(_localHeader, 0, _localHeader.Length); + _output.Write(nameb, 0, nameb.Length); + + var fileStart = (int)(_output.Position); + + var s2 = new DeflateStream(_output, _level, true); + var s3 = new CRC32Stream(s2); + callback(s3); + s2.Flush(); + + var fileEnd = (int)(_output.Position); + + var crc = s3.Crc; + var compressedSize = fileEnd - fileStart; + var uncompressedSize = s3.Size; + var descriptor = new byte[] + { + (byte)crc, + (byte)(crc >> 8), + (byte)(crc >> 16), + (byte)(crc >> 24), + (byte)compressedSize, + (byte)(compressedSize >> 8), + (byte)(compressedSize >> 16), + (byte)(compressedSize >> 24), + (byte)uncompressedSize, + (byte)(uncompressedSize >> 8), + (byte)(uncompressedSize >> 16), + (byte)(uncompressedSize >> 24) + }; + _output.Write(descriptor, 0, descriptor.Length); + + var fileHeader = (byte[])_fileHeaderTemplate.Clone(); + + fileHeader[28] = (byte)nameb.Length; + fileHeader[29] = (byte)(nameb.Length >> 8); + Array.Copy(descriptor, 0, fileHeader, 16, 12); + fileHeader[42] = (byte)localHeaderOffset; + fileHeader[43] = (byte)(localHeaderOffset >> 8); + fileHeader[44] = (byte)(localHeaderOffset >> 16); + fileHeader[45] = (byte)(localHeaderOffset >> 24); + + _endBlobs.Add(fileHeader); + _endBlobs.Add(nameb); + _numEntries++; + } + + private void WriteFooter() + { + var centralHeaderOffset = (int)(_output.Position); + + foreach (var blob in _endBlobs) + _output.Write(blob, 0, blob.Length); + + var centralHeaderEnd = (int)(_output.Position); + + var centralHeaderSize = centralHeaderEnd - centralHeaderOffset; + + var footer = new byte[] + { + 0x50, 0x4b, 0x05, 0x06, // signature + 0x00, 0x00, // disk number + 0x00, 0x00, // central record disk number + (byte)_numEntries, (byte)(_numEntries >> 8), // number of entries on disk + (byte)_numEntries, (byte)(_numEntries >> 8), // number of entries total + (byte)centralHeaderSize, + (byte)(centralHeaderSize >> 8), + (byte)(centralHeaderSize >> 16), + (byte)(centralHeaderSize >> 24), // central directory size + (byte)centralHeaderOffset, + (byte)(centralHeaderOffset >> 8), + (byte)(centralHeaderOffset >> 16), + (byte)(centralHeaderOffset >> 24), // central directory offset + 0x07, 0x00, // comment length + 0x42, 0x69, 0x7a, 0x48, 0x61, 0x77, 0x6b // comment + }; + + _output.Write(footer, 0, footer.Length); + } + } +} diff --git a/BizHawk.Client.Common/FrameworkZipWriter.cs b/BizHawk.Client.Common/FrameworkZipWriter.cs new file mode 100644 index 0000000000..1bbe33910b --- /dev/null +++ b/BizHawk.Client.Common/FrameworkZipWriter.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Text; + +namespace BizHawk.Client.Common +{ + public class FrameworkZipWriter : IZipWriter + { + private ZipArchive _archive; + private readonly CompressionLevel _level; + + public FrameworkZipWriter(string path, int compressionlevel) + { + _archive = new ZipArchive(new FileStream(path, FileMode.Create, FileAccess.Write), + ZipArchiveMode.Create, false); + if (compressionlevel == 0) + _level = CompressionLevel.NoCompression; + else if (compressionlevel < 5) + _level = CompressionLevel.Fastest; + else + _level = CompressionLevel.Optimal; + } + + public void WriteItem(string name, Action callback) + { + using (var stream = _archive.CreateEntry(name, _level).Open()) + { + callback(stream); + } + } + + public void Dispose() + { + if (_archive != null) + { + _archive.Dispose(); + _archive = null; + } + } + } +} diff --git a/BizHawk.Client.Common/Global.cs b/BizHawk.Client.Common/Global.cs index 76dc7ebc80..42e9a75a89 100644 --- a/BizHawk.Client.Common/Global.cs +++ b/BizHawk.Client.Common/Global.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using BizHawk.Emulation.Common; -using BizHawk.Emulation.Cores.Nintendo.Gameboy; +using BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy; using BizHawk.Emulation.Cores.Sega.MasterSystem; // ReSharper disable StyleCop.SA1401 @@ -112,7 +112,7 @@ namespace BizHawk.Client.Common case "SNES": return SystemInfo.SNES; case "GB": - if ((Emulator as Gameboy).IsCGBMode()) + if ((Emulator as IGameboyCommon).IsCGBMode()) { return SystemInfo.GBC; } @@ -144,6 +144,10 @@ namespace BizHawk.Client.Common return SystemInfo.AppleII; case "Libretro": return SystemInfo.Libretro; + case "VB": + return SystemInfo.VirtualBoy; + case "NGP": + return SystemInfo.NeoGeoPocket; } } } diff --git a/BizHawk.Client.Common/PathManager.cs b/BizHawk.Client.Common/PathManager.cs index fa6475fe67..1b5f5c6706 100644 --- a/BizHawk.Client.Common/PathManager.cs +++ b/BizHawk.Client.Common/PathManager.cs @@ -7,6 +7,7 @@ using BizHawk.Common.StringExtensions; using BizHawk.Emulation.Common; using BizHawk.Emulation.Common.IEmulatorExtensions; using BizHawk.Emulation.Cores.Nintendo.SNES; +using BizHawk.Emulation.Cores.Nintendo.SNES9X; namespace BizHawk.Client.Common { @@ -355,6 +356,11 @@ namespace BizHawk.Client.Common name += "." + Global.Emulator.Attributes().CoreName; } + if (Global.Emulator is Snes9x) // Keep snes9x savestate away from libsnes, we want to not be too tedious so bsnes names will just have the profile name not the core name + { + name += "." + Global.Emulator.Attributes().CoreName; + } + // Bsnes profiles have incompatible savestates so save the profile name if (Global.Emulator is LibsnesCore) { diff --git a/BizHawk.Client.Common/RomLoader.cs b/BizHawk.Client.Common/RomLoader.cs index 3f89408972..1511b9d76c 100644 --- a/BizHawk.Client.Common/RomLoader.cs +++ b/BizHawk.Client.Common/RomLoader.cs @@ -22,6 +22,7 @@ using BizHawk.Emulation.Cores.Sony.PSX; using BizHawk.Emulation.DiscSystem; using GPGX64 = BizHawk.Emulation.Cores.Consoles.Sega.gpgx64; +using BizHawk.Emulation.Cores.Consoles.Sega.Saturn; namespace BizHawk.Client.Common { @@ -487,7 +488,15 @@ namespace BizHawk.Client.Common case DiscType.TurboCD: case DiscType.UnknownCDFS: case DiscType.UnknownFormat: - game.System = "PCECD"; + if (PreferredPlatformIsDefined(ext)) + { + game.System = Global.Config.PreferredPlatformsForExtensions[ext]; + } + else + { + game.System = "PCECD"; + } + break; } } @@ -508,7 +517,9 @@ namespace BizHawk.Client.Common break; case "SAT": - nextEmulator = new Yabause(nextComm, disc, GetCoreSyncSettings()); + //nextEmulator = new Yabause(nextComm, disc, GetCoreSyncSettings()); + nextEmulator = new Saturnus(nextComm, new[] { disc }, Deterministic, + (Saturnus.Settings)GetCoreSettings(), (Saturnus.SyncSettings)GetCoreSyncSettings()); break; case "PSP": nextEmulator = new PSP(nextComm, file.Name); @@ -771,7 +782,7 @@ namespace BizHawk.Client.Common break; case "SNES": - if (Global.Config.SNES_InSnes9x && VersionInfo.DeveloperBuild) + if (Global.Config.SNES_InSnes9x) { core = CoreInventory.Instance["SNES", "Snes9x"]; } @@ -823,6 +834,7 @@ namespace BizHawk.Client.Common case "GBC": if (!Global.Config.GB_AsSGB) { + //core = CoreInventory.Instance["GB", "Pizza Boy"]; core = CoreInventory.Instance["GB", "Gambatte"]; } else diff --git a/BizHawk.Client.Common/SavestateManager.cs b/BizHawk.Client.Common/SavestateManager.cs index 4deff8c3cd..8f250bc135 100644 --- a/BizHawk.Client.Common/SavestateManager.cs +++ b/BizHawk.Client.Common/SavestateManager.cs @@ -201,10 +201,6 @@ namespace BizHawk.Client.Common }); } } - catch - { - return false; - } finally { bl.Dispose(); @@ -212,41 +208,9 @@ namespace BizHawk.Client.Common return true; } - else // text mode + else { - if (Global.MovieSession.HandleMovieLoadState(path)) - { - using (var reader = new StreamReader(path)) - { - core.LoadStateText(reader); - - while (true) - { - var str = reader.ReadLine(); - if (str == null) - { - break; - } - - if (str.Trim() == "") - { - continue; - } - - var args = str.Split(' '); - if (args[0] == "Framebuffer" && Global.Emulator.HasVideoProvider()) - { - Global.Emulator.AsVideoProvider().GetVideoBuffer().ReadFromHex(args[1]); - } - } - } - - return true; - } - else - { - return false; - } + return false; } } } diff --git a/BizHawk.Client.Common/SystemInfo.cs b/BizHawk.Client.Common/SystemInfo.cs index 3ca1864a30..82414adc50 100644 --- a/BizHawk.Client.Common/SystemInfo.cs +++ b/BizHawk.Client.Common/SystemInfo.cs @@ -174,10 +174,20 @@ namespace BizHawk.Client.Common public static SystemInfo TI83 { get; } = new SystemInfo("TI - 83", CoreSystem.TI83, 1); /// - /// Gets the instance for TI-83 + /// Gets the instance for Wonderswan /// public static SystemInfo WonderSwan { get; } = new SystemInfo("WonderSwan", CoreSystem.WonderSwan, 1); + /// + /// Gets the instance for Virtual Boy + /// + public static SystemInfo VirtualBoy { get; } = new SystemInfo("Virtual Boy", CoreSystem.VirtualBoy, 1); + + /// + /// Gets the instance for TI-83 + /// + public static SystemInfo NeoGeoPocket { get; } = new SystemInfo("Neo-Geo Pocket", CoreSystem.NeoGeoPocket, 1); + #endregion Get SystemInfo /// diff --git a/BizHawk.Client.Common/config/Config.cs b/BizHawk.Client.Common/config/Config.cs index 88f2b8b98a..64259c956c 100644 --- a/BizHawk.Client.Common/config/Config.cs +++ b/BizHawk.Client.Common/config/Config.cs @@ -46,6 +46,7 @@ namespace BizHawk.Client.Common { ".rom", "" }, { ".iso", "" }, { ".img", "" }, + { ".cue", "" } }; // Path Settings ************************************/ @@ -217,7 +218,7 @@ namespace BizHawk.Client.Common // Savestate settings public SaveStateTypeE SaveStateType = SaveStateTypeE.Default; - public const int DefaultSaveStateCompressionLevelNormal = 0; + public const int DefaultSaveStateCompressionLevelNormal = 1; public int SaveStateCompressionLevelNormal = DefaultSaveStateCompressionLevelNormal; public const int DefaultSaveStateCompressionLevelRewind = 0; // this isnt actually used yet public int SaveStateCompressionLevelRewind = DefaultSaveStateCompressionLevelRewind; // this isnt actually used yet @@ -398,6 +399,7 @@ namespace BizHawk.Client.Common public string AVICodecToken = ""; public int GifWriterFrameskip = 3; public int GifWriterDelay = -1; + public bool VideoWriterAudioSync = true; #region emulation core settings @@ -535,8 +537,8 @@ namespace BizHawk.Client.Common // it hasn't been absorbed into the new system public bool GB_AsSGB = false; public bool NES_InQuickNES = true; - public bool SNES_InSnes9x = false; - public bool GBA_UsemGBA = false; + public bool SNES_InSnes9x = true; + public bool GBA_UsemGBA = true; public bool A78_UseEmu7800 = true; public bool CoreForcingViaGameDB = true; public string LibretroCore; diff --git a/BizHawk.Client.Common/config/PathEntry.cs b/BizHawk.Client.Common/config/PathEntry.cs index f8178ab80e..898a4efd68 100644 --- a/BizHawk.Client.Common/config/PathEntry.cs +++ b/BizHawk.Client.Common/config/PathEntry.cs @@ -344,6 +344,20 @@ namespace BizHawk.Client.Common new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 4 }, new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 5 }, new PathEntry { System = "Libretro", SystemDisplayName = "Libretro", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 6 }, + + new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "Base", Path = Path.Combine(".", "VB"), Ordinal = 0 }, + new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "VB", SystemDisplayName = "VB", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, + + new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "Base", Path = Path.Combine(".", "NGP"), Ordinal = 0 }, + new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "ROM", Path = ".", Ordinal = 1 }, + new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "Savestates", Path = Path.Combine(".", "State"), Ordinal = 2 }, + new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "Save RAM", Path = Path.Combine(".", "SaveRAM"), Ordinal = 3 }, + new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "Screenshots", Path = Path.Combine(".", "Screenshots"), Ordinal = 4 }, + new PathEntry { System = "NGP", SystemDisplayName = "NGP", Type = "Cheats", Path = Path.Combine(".", "Cheats"), Ordinal = 5 }, }; } } diff --git a/BizHawk.Client.Common/lua/EmuLuaLibrary.Events.cs b/BizHawk.Client.Common/lua/EmuLuaLibrary.Events.cs index 182f578c83..06de09f7a4 100644 --- a/BizHawk.Client.Common/lua/EmuLuaLibrary.Events.cs +++ b/BizHawk.Client.Common/lua/EmuLuaLibrary.Events.cs @@ -135,11 +135,11 @@ namespace BizHawk.Client.Common private bool N64CoreTypeDynarec() { - if ((Emulator as N64)?.GetSyncSettings().Core == N64SyncSettings.CoreType.Dynarec) - { - Log("N64 Error: Memory callbacks are not implemented for Dynamic Recompiler core type\nUse Interpreter or Pure Interpreter\n"); - return true; - } + //if ((Emulator as N64)?.GetSyncSettings().Core == N64SyncSettings.CoreType.Dynarec) + //{ + // Log("N64 Error: Memory callbacks are not implemented for Dynamic Recompiler core type\nUse Interpreter or Pure Interpreter\n"); + // return true; + //} return false; } diff --git a/BizHawk.Client.Common/miniz/LibMiniz.cs b/BizHawk.Client.Common/miniz/LibMiniz.cs new file mode 100644 index 0000000000..32a914b0b5 --- /dev/null +++ b/BizHawk.Client.Common/miniz/LibMiniz.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Client.Common.Miniz +{ + public static class LibMiniz + { + private const string DllName = "libminiz.dll"; + private const CallingConvention CC = CallingConvention.Cdecl; + + public enum mz_zip_flags : uint + { + MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100, + MZ_ZIP_FLAG_IGNORE_PATH = 0x0200, + MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400, + MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800 + }; + + enum mz_compression_level : uint + { + MZ_NO_COMPRESSION = 0, + MZ_BEST_SPEED = 1, + MZ_BEST_COMPRESSION = 9, + MZ_UBER_COMPRESSION = 10, + MZ_DEFAULT_LEVEL = 6, + MZ_DEFAULT_COMPRESSION = unchecked((uint)-1) + }; + + [DllImport(DllName, CallingConvention = CC)] + public static extern bool mz_zip_writer_init_file(IntPtr pZip, string pFilename, long size_to_reserve_at_beginning); + + // Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive. + // To add a directory entry, call this method with an archive name ending in a forwardslash with empty buffer. + // level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. + [DllImport(DllName, CallingConvention = CC)] + public static extern bool mz_zip_writer_add_mem(IntPtr pZip, string pArchive_name, byte[] pBuf, ulong buf_size, uint level_and_flags); + + // Finalizes the archive by writing the central directory records followed by the end of central directory record. + // After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end(). + // An archive must be manually finalized by calling this function for it to be valid. + [DllImport(DllName, CallingConvention = CC)] + public static extern bool mz_zip_writer_finalize_archive(IntPtr pZip); + + // Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used. + // Note for the archive to be valid, it must have been finalized before ending. + [DllImport(DllName, CallingConvention = CC)] + public static extern bool mz_zip_writer_end(IntPtr pZip); + } +} diff --git a/BizHawk.Client.Common/miniz/MinizZipWriter.cs b/BizHawk.Client.Common/miniz/MinizZipWriter.cs new file mode 100644 index 0000000000..19e2c8f672 --- /dev/null +++ b/BizHawk.Client.Common/miniz/MinizZipWriter.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Client.Common.Miniz +{ + public class MinizZipWriter : IZipWriter + { + private IntPtr _zip; + private uint _flags; + private static readonly byte[] _shitcock = new byte[32 * 1024 * 1024]; + + public MinizZipWriter(string path, int compressionlevel) + { + _zip = Marshal.AllocHGlobal(128); + unsafe + { + var p = (int*)_zip; + for (int i = 0; i < 32; i++) + p[i] = 0; + } + if (!LibMiniz.mz_zip_writer_init_file(_zip, path, 0)) + { + Marshal.FreeHGlobal(_zip); + _zip = IntPtr.Zero; + throw new InvalidOperationException("mz_zip_writer_init_file returned FALSE"); + } + _flags = (uint)compressionlevel; + } + + void IDisposable.Dispose() + { + Dispose(); + GC.SuppressFinalize(this); + } + + ~MinizZipWriter() + { + Dispose(); + } + + private void Dispose() + { + if (_zip != IntPtr.Zero) + { + if (LibMiniz.mz_zip_writer_finalize_archive(_zip)) + LibMiniz.mz_zip_writer_end(_zip); + Marshal.FreeHGlobal(_zip); + _zip = IntPtr.Zero; + } + } + + public void WriteItem(string name, Action callback) + { + lock (_shitcock) + { + var ms = new MemoryStream(_shitcock); + callback(ms); + if (!LibMiniz.mz_zip_writer_add_mem(_zip, name, _shitcock /*ms.GetBuffer()*/, (ulong)ms.Position, _flags)) + throw new InvalidOperationException("mz_zip_writer_add_mem returned FALSE"); + } + } + } +} diff --git a/BizHawk.Client.Common/movie/PlatformFrameRates.cs b/BizHawk.Client.Common/movie/PlatformFrameRates.cs index c2db715444..63fa342b55 100644 --- a/BizHawk.Client.Common/movie/PlatformFrameRates.cs +++ b/BizHawk.Client.Common/movie/PlatformFrameRates.cs @@ -33,7 +33,7 @@ namespace BizHawk.Client.Common ["SG"] = (3579545 / 262.0 / 228.0), // 59.9227434043 ["SG_PAL"] = (3546893 / 313.0 / 228.0), // 49.7014320946 ["NGP"] = (6144000.0 / (515 * 198)), // 60.2530155928 - ["VBOY"] = (20000000.0 / (259 * 384 * 4)), // 50.2734877735 + ["VB"] = (20000000.0 / (259 * 384 * 4)), // 50.2734877735 ["Lynx"] = 16000000.0 / (16 * 105 * 159), // 59.89817310572028 ["WSWAN"] = (3072000.0 / (159 * 256)), // 75.4716981132 ["GB"] = 262144.0 / 4389.0, // 59.7275005696 diff --git a/BizHawk.Client.Common/movie/bk2/Bk2MnemonicConstants.cs b/BizHawk.Client.Common/movie/bk2/Bk2MnemonicConstants.cs index f788da2397..45f1d8a888 100644 --- a/BizHawk.Client.Common/movie/bk2/Bk2MnemonicConstants.cs +++ b/BizHawk.Client.Common/movie/bk2/Bk2MnemonicConstants.cs @@ -10,10 +10,18 @@ namespace BizHawk.Client.Common get { var key = button.Replace("Key ", ""); - if (key.StartsWith("P") && key.Length > 1 && key[1] >= '0' && key[1] <= '9') + if (key.StartsWith("P")) { - key = key.Substring(3); + if (key.Length > 2 && key[1] == '1' && key[2] >= '0' && key[1] <= '9') // Hack to support 10-20 controllers, TODO: regex this thing instead + { + key = key.Substring(4); + } + else if (key.Length > 1 && key[1] >= '0' && key[1] <= '9') + { + key = key.Substring(3); + } } + if (_systemOverrides.ContainsKey(Global.Emulator.SystemId) && _systemOverrides[Global.Emulator.SystemId].ContainsKey(key)) { @@ -293,6 +301,10 @@ namespace BizHawk.Client.Common ["Option 1"] = '1', ["Option 2"] = '2' }, + ["NGP"] = new Dictionary + { + ["Option"] = 'O' + }, ["AppleII"] = new Dictionary { ["Tab"] = 't' , @@ -332,6 +344,17 @@ namespace BizHawk.Client.Common ["Red"] = 'R', ["Blue"] = 'B', ["Purple"] = 'P' + }, + ["VB"] = new Dictionary + { + ["L_Up"] = 'U', + ["L_Down"] = 'D', + ["L_Left"] = 'L', + ["L_Right"] = 'R', + ["R_Up"] = 'u', + ["R_Down"] = 'd', + ["R_Left"] = 'l', + ["R_Right"] = 'r', } }; } diff --git a/BizHawk.Client.Common/movie/import/MovieImport.cs b/BizHawk.Client.Common/movie/import/MovieImport.cs index 8c1aa55cc9..af8e69db52 100644 --- a/BizHawk.Client.Common/movie/import/MovieImport.cs +++ b/BizHawk.Client.Common/movie/import/MovieImport.cs @@ -12,6 +12,7 @@ using BizHawk.Emulation.Common; using BizHawk.Client.Common.MovieConversionExtensions; using BizHawk.Emulation.Cores.Nintendo.SNES; +using BizHawk.Emulation.Cores.Nintendo.SNES9X; namespace BizHawk.Client.Common { @@ -1490,8 +1491,9 @@ namespace BizHawk.Client.Common m.Header[HeaderKeys.PLATFORM] = platform; - var ss = new LibsnesCore.SnesSyncSettings { Profile = "Compatibility" }; + var ss = new LibsnesCore.SnesSyncSettings(); m.SyncSettingsJson = ConfigService.SaveWithType(ss); + Global.Config.SNES_InSnes9x = true; // This could be annoying to a user if they don't notice we set this preference, but the alternative is for the movie import to fail to load the movie return m; } @@ -2324,9 +2326,9 @@ namespace BizHawk.Client.Common r.Close(); fs.Close(); - var ss = new LibsnesCore.SnesSyncSettings { Profile = "Compatibility" }; + var ss = new Snes9x.SyncSettings(); m.SyncSettingsJson = ConfigService.SaveWithType(ss); - + Global.Config.SNES_InSnes9x = true; // This could be annoying to a user if they don't notice we set this preference, but the alternative is for the movie import to fail to load the movie return m; } diff --git a/BizHawk.Client.Common/rewind/Rewinder.cs b/BizHawk.Client.Common/rewind/Rewinder.cs index 3f7bbe2704..69d3e8a2a6 100644 --- a/BizHawk.Client.Common/rewind/Rewinder.cs +++ b/BizHawk.Client.Common/rewind/Rewinder.cs @@ -80,8 +80,6 @@ namespace BizHawk.Client.Common public void Uninitialize() { - Clear(); - if (_rewindThread != null) { _rewindThread.Dispose(); @@ -94,6 +92,8 @@ namespace BizHawk.Client.Common _rewindBuffer = null; } + Clear(); + RewindEnabled = false; RewindFrequency = 0; } diff --git a/BizHawk.Client.DBMan/BizHawk.Client.DBMan.csproj b/BizHawk.Client.DBMan/BizHawk.Client.DBMan.csproj index 91ffba02bd..e91fc36711 100644 --- a/BizHawk.Client.DBMan/BizHawk.Client.DBMan.csproj +++ b/BizHawk.Client.DBMan/BizHawk.Client.DBMan.csproj @@ -1,15 +1,14 @@  - + true - ..\output64\ + ..\output\ TRACE;DEBUG;WINDOWS full x64 - ..\output\BizHawk.Client.DBMan.exe.CodeAnalysisLog.xml true GlobalSuppressions.cs false @@ -18,14 +17,14 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules true + false - ..\output64\ + ..\output\ TRACE;WINDOWS true pdbonly x64 - ..\output\BizHawk.Client.DBMan.exe.CodeAnalysisLog.xml true GlobalSuppressions.cs false @@ -33,6 +32,7 @@ MinimumRecommendedRules.ruleset ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false @@ -43,31 +43,10 @@ Properties BizHawk.Client.DBMan BizHawk.Client.DBMan - v4.0 + v4.6.1 512 - - x86 - true - full - false - ..\output\ - TRACE;DEBUG;WINDOWS - prompt - 4 - false - - - x86 - pdbonly - true - ..\output\ - TRACE;WINDOWS - prompt - 4 - false - .\CSharp-SQLite.dll @@ -138,11 +117,11 @@ - \ No newline at end of file diff --git a/BizHawk.Client.DBMan/Properties/Settings.Designer.cs b/BizHawk.Client.DBMan/Properties/Settings.Designer.cs index fb22014f1e..963414f15f 100644 --- a/BizHawk.Client.DBMan/Properties/Settings.Designer.cs +++ b/BizHawk.Client.DBMan/Properties/Settings.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.18034 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -12,7 +12,7 @@ namespace BizHawk.Client.DBMan.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); diff --git a/BizHawk.Client.DBMan/app.config b/BizHawk.Client.DBMan/app.config index cb2586beb1..b33a20518b 100644 --- a/BizHawk.Client.DBMan/app.config +++ b/BizHawk.Client.DBMan/app.config @@ -1,3 +1,3 @@ - + diff --git a/BizHawk.Client.DiscoHawk/BizHawk.Client.DiscoHawk.csproj b/BizHawk.Client.DiscoHawk/BizHawk.Client.DiscoHawk.csproj index 712cbccf12..7acbc6b6a0 100644 --- a/BizHawk.Client.DiscoHawk/BizHawk.Client.DiscoHawk.csproj +++ b/BizHawk.Client.DiscoHawk/BizHawk.Client.DiscoHawk.csproj @@ -1,5 +1,5 @@  - + Debug x86 @@ -10,7 +10,7 @@ Properties BizHawk.Client.DiscoHawk DiscoHawk - v4.0 + v4.6.1 512 @@ -33,30 +33,6 @@ true - - true - full - false - ..\output\ - TRACE;DEBUG;WINDOWS - prompt - 4 - false - AllRules.ruleset - x86 - true - - - pdbonly - true - ..\output\ - TRACE;WINDOWS - prompt - 4 - false - x86 - AllRules.ruleset - true @@ -68,12 +44,11 @@ true - ..\output64\ + ..\output\ TRACE;DEBUG;WINDOWS true full x64 - ..\output\DiscoHawk.exe.CodeAnalysisLog.xml true GlobalSuppressions.cs false @@ -84,14 +59,14 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules true false + false - ..\output64\ + ..\output\ TRACE;WINDOWS true pdbonly x64 - ..\output\DiscoHawk.exe.CodeAnalysisLog.xml true GlobalSuppressions.cs false @@ -102,6 +77,7 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules false false + false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - AAABAAEAgIAAAAEAIAAoCAEAFgAAACgAAACAAAAAAAEAAAEAIAAAAAAAAAABABILAAASCwAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJmZmQWqqqoSu7u7Hr64uCu/u7s8t7S0Tqqf - n2CPiIp0eXV1em1ra3ppZGR1bWdnXnNzc0WIiIgthISEG5mZmQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgAjS0tIR3d3dHs3NzS7V1dU92NjYTtjV1WLW1NR31tbWidbT - 053V0tKx0tLSwtLNzdHPzMzhzMfH7snGxvfCvr7/rqur/5eTk/+Dfn//c29v/25qav9zcHD/fHp6+42M - jO+dnJzepKSkyKioqLKioqKWmJiYfI+Pj2KQkJBHioqKMoCAgBxiYmINAAAAAQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAADDw8Mixby8OcbDw0jKyMhcz8/PcNTU1IPd1taW29vbqt3d3b3d3d3M3d3d3N3d - 3ere3t703d7e/eDg4P/g39//393d/9/d3f/f3d3/39zc/93b2//c29r/29fX/9nV1f/W0tP/0s/P/8XB - wf+uq6r/lZGR/397e/9xbm7/bmtr/3Vycv+DgYH/lJKS/6Sjo/+sra3/ra2t/6eoqP+fn5//mpqa/5mZ - mf+ZmZn/lpaW85aWluSTk5POlZWVupmZmaCUlJSFj4+Pa46Ojk+Li4s3ZmZmCgAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqqqqG8LAwOXPy8v/0M7O/9XS - 0//Z1tb/3Nvb/+Hh4P/l5eX/6Ojo/+rq6v/r6+v/7Ozs/+zs7P/r6+v/6urq/+fn5//i4eH/3dvb/9fV - 1f/Py8v/xMLC/7y4uP+xra7/pqGj/5yXl/+SjI7/hX+A/3dycv9uZ2n/Z2Ji/2VeYP9mYWL/bGho/3Zy - c/+Df4H/kZCQ/5uamv+enp7/nZ2d/5mZmf+Xl5f/l5mZ/5mZmf+ZmZn/mZmZ/5mZmf+ZmZn/mZmZ/5mZ - mf+ZmZn/mZmZ/5mZmf+UlJTWjIyMNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAADBvr5SzsvK/9DMzf/Rz8//1NHR/9bU1P/V1NT/1NLT/9HP0P/Mysr/xMLD/7y6 - uv+0sbL/rKio/6Sfn/+blpf/k4+P/4yHiP+Ff4H/fnl6/3t1dv94cnP/dXBx/3Rub/90bm//dG5v/3Rv - b/92cXL/eXN0/3t1dv98d3j/fnh5/395ev9/eXr/f3l6/396e/+Benv/g3x9/4aAgf+Ig4T/i4aG/42I - if+QjI3/ko+Q/5SRkv+WlJT/mZWW/5mXl/+amZn/mpmZ/5uamv+bmpr/mpub/5qamv+VlZXfY2NjEgAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKmpiuloKKymZKSvpiS - lMmUkpLUkYyN34+Ki+uNh4jyioWG+IqEhf6LhYf/i4WG/4uFhv+Lhof/jIeI/4+Iif+Qiov/kouN/5ON - j/+VjpD/lpGS/5eRkv+YkpP/mJOU/5qTlP+ak5T/mpSV/5qUlf+alJX/mpSU/5qUlP+ak5T/mpOU/5qT - lP+ak5T/mJOU/5iSk/+YkpP/l5GT/5eRkv+Wj5H/lo+Q/5WOkP+VjY//lI2P/5OMjv+Ti43/kouN/5KK - i/+Riov/kYqL/5CKiv+Pior/lpWV/5qamv+QkJBqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARmZmYKh4eHEYB2dhqGgIAmh4KHMZmI - jDyOg4dIi4KFVouDg2WNhIZ0ioKCgYR9gI+EfH6ehH1+rId8fbuAeHjFgHZ50X52d9x8dnfofHR2+X12 - d/97dHX/e3N0/3pyc/94cXL/eHBx/3dvcP92bm//dW1v/3Rrbf9zam3/cmlr/3Joa/9waGr/cGdp/29m - aP9uZWf/bmRn/21jZv9sY2X/bGJl/2thZP9qYWP/amBi/2lfYv9oX2H/aF9h/2ZdX/9uZmn/lJSU/5WV - lbUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAACIAAACFVEVQ9TRkYoYVdZiWVcXvxoX2H/aWBi/2lgYv9qYWP/amJk/2tj - Zf9sY2X/bWRm/21lZ/9uZmj/cGdp/3Boav9xamv/c2ps/3Nsbf91bm//dm9w/3dwcf94cXL/eXN0/3p0 - df98dXf/fXd4/354ef+Benr/gnt8/4N8ff+TkZH/lpaW4GZmZgoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAjouLVqunqfuuq6v/r6yt/7Gur/+zsLL/tbO0/7e1tf+6trf/u7i6/727vP+/vb3/wb+//8PB - wv/Ew8P/x8XF/8jIyP/Kycr/y8vL/87Mzv/Pz8//0dHR/9PT0//V1dT/1tbW/9fX2f/Z2tr/39/f/8PD - xP+RkZHyenp6GQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6u3tn+3w8P/t8PD/7fDw/+3w - 8P/t8PD/7fDw/+3v8P/s7+//7O/v/+zt7f/r7O3/6uzs/+rs7P/p6+v/6erq/+fq6v/m6ej/5efn/+Tm - 5v/i5eX/4eTk/+Hi4v/f4OH/3eDf/9zd3f/d4OD/xcjI/5OTk/Z7e3sfAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAACwq6s6sLCw/bKysv+wr6//rq2u/62srP+rqan/qaio/6empv+mpaX/paOk/6Oh - of+hoKD/oJ+f/5+dnv+enJz/nZub/5uamv+al5f/mZaW/5eVlf+WlJT/lZOT/5SSkv+TkZH/k5CR/5GP - j/+Uk5P/lpaW4GZmZgoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZmZhSEgIDvh4SE/4eE - hP+HhIT/h4SE/4eEhP+HhIT/h4SE/4eEhP+HhIT/h4SE/4eEhP+HhIT/h4SE/4eEhP+IhIT/iISE/4iF - hf+IhYX/iIWF/4iFhf+IhYX/iIWF/4iFhf+IhYX/h4SE/5KRkf+VlZWpAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAARkZGC4aFheOKh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qH - h/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qH - h/+KiIj/lpaW/5GRkWEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB0bGwhh4SE9oqH - h/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qH - h/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/iYaG/46Li/+Xl5f2gICAIAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8fEiKh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qH - h/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qH - h/+Jhob/kpGR/5aWlsQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgoCAcoqH - h/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qH - h/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+VlZX/lZWVfwAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACFhISdioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qH - h/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qHh/+Kh4f/ioeH/4qH - h/+Khof/joqK/5mZmf+Pj487AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIeC - g8SLh4j/i4eI/4uHiP+Lh4j/i4eI/4yHiP+Mh4j/jIeI/4yHiP+Mh4j/jIiI/4yIiP+MiIj/jIiI/4yI - iP+MiIj/jIiI/4yIif+MiIn/jIiJ/4yIif+MiIn/jIiJ/4uHiP+SkJD/mZmZ4WZmZgoAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVVVUMjIWG5I+Jiv+PiYr/j4mK/4+Jiv+PiYr/j4qK/4+K - iv+Pior/j4qK/4+Kiv+Pior/j4qL/4+Ki/+Piov/j4qL/5CKi/+Qiov/kIqL/5CKi/+Qiov/kIqL/5CK - i/+Qiov/kIqK/5WUlf+ZmZmlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB5 - eSiOiYr7kYyN/5GMjv+RjI7/kYyO/5GMjv+RjI7/kYyO/5KMjv+SjI7/koyO/5KNjv+SjY//ko2P/5KN - j/+TjY//k4+P/5OOkP+TjpD/lI6Q/5SOkP+UkJD/lJCR/5SQkf+VkZL/nJyc/4uLi08AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAg7OzsNWlpaEUZGRhZSSkofV1FRKWZmVzJfW1s7ZmZmQV5b - W0lfWVlWZmZmZI6OjnFVVVUMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjIWJRZeSk/+WkpP/lpKT/5aSk/+WkpP/lpKS/5aR - kv+WkZL/lpGS/5WRkv+UkJH/k46Q/5ONj/+SjY7/kYyO/5GMjf+Pior/jomJ/4uHh/+Khob/ioaG/4mE - hf+HgYP/hX+B/4R/gP+DgYH+b2trmGJeXohnZGKXaGRkpGhlZLBrZ2e6aGRkv2lmZshoZmbSaWZm3Gpm - ZuRqZmbra2dn72tmZvRqZmb6bmpq/29ra/9taWn/aGRk/3x5ef/CwsL/19fX/319fTEAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAABDMzMwpEREQPKysrEjExMRVAQEAgR0dHK1VVVTZVVVU/WVVVQlRQ - TUZwbGygg36A/397e/99enn/fXp6/3x4eP96dnb/d3Rz/3Zycv91cXH/dXFx/3NwcP9ybm//cW5t/3Bt - bP9wbWz/cGxs/29sa/9vbGv/bmtq/21qaf9uamr/bmpq/25qav9taWn/bWlp/2xoaP9uamr/b2tr/25q - a/9uamr/bmpq/25pav9taWn/bWlp/2xoaP9saGj/a2dn/2pmZv9qZmb/aWVl/2hkZP9nZGT/ZmJi/2lm - Zv+SkZH+2dnZ/+/v7//i4uL/hISEUQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAABBcXFws8PDwRHBwcEjMzMxQwMDAgOjo6LEBAQDhEQEBAQkJCQkNA - QEhIRkZYSkVFaEpISHVMSEh/TEpKgExKSolQUFCZT01NqFBPT7VVUFC9Uk9PvlRQUMhVU1PUVlNT31hV - VehZVVXtWldX7ltXV/VcWVj7X11c/2BdXf9hXl7/YV5e/2BdXf9gXVz/YV5d/2FdXf9hXl3/YV5d/2Fe - Xf9hXl3/YV5d/2FeXf9hXl3/YF1c/2FdXf9gXVz/YF1c/2BdXP9fXFv/X1tb/15cW/9eW1r/Xlta/15b - Wv9dWlr/XVlZ/1xZWf9cWVn/W1hY/1tYWP9cWVn/XFlZ/1xZWf9cWVn/XFpa/11aWv9dW1v/X1xd/2Be - Xv9hX1//YmFh/2RiYv9lY2T/Z2Vl/2hmZv9samr/rays/ujo6P/q6ur/5+fn/+bm5v+ampp3AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFxcXCzMzMxQwMDAgPTc3LkE9PTtCQkJCQkJCQkFB - QUdFQkJZRkZGakZERnhIREaASERGgEdFRYlHRkaaSEZIq0hHSLhJRki9R0dHvkdGRshIRUfVSUdH4UlH - R+tIRkbtSEZG7klGR/VIRkb8S0lJ/0tJSf9LSUn/S0hJ/0pISP9KSEj/SkhI/0pHSP9KSEj/SkdH/0pH - SP9JR0f/SkdH/0lHR/9KSEj/SkhI/0tJSf9LSkn/S0pK/0xKSv9NS0v/TUtL/09MTf9QTk7/UlBQ/1RS - Uf9VU1P/V1VV/1hWVv9aWFf/XVta/19eXf9iYGD/ZGNj/2ZlZf9paGj/bGpq/25tbf9ycXD/dXR0/3h3 - d/97enr/gH5+/4OCgv+GhYX/iYiI/4yLjP+Qj4//k5OT/5eWlv+ampr/np2e/6Ggof+lpKX/pqan/6mp - qf+srK3/rq6v/7Cwsf+0tLX/trW3/7i4uv+6urv/u7u8/7y7vf+9vb7/vr2//7++wf/BwcL/v7/B/7y8 - vfvr6+v/5+fn/+bm5v/m5ub/6+vr/6ampp0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgIQUZD - Q6FEREThRkJC7kRBQvVEP0H9RkJE/0VCQ/9EQUL/Q0FC/0NAQf9DQEH/QkBB/0JAQf9CQEH/QkBB/0JA - Qf9CQEH/QkBB/0NBQf9EQkP/RkRF/0dERf9IRkf/SkhI/0pJSf9LS0v/TkxM/1FQUP9UUlL/V1VV/1lZ - Wf9dXFz/YF9f/2NiYv9mZWb/amlp/29vb/9zcnL/d3Z2/3x7e/+Bf4D/hYSE/4mIif+Ojo7/lJOT/5eX - l/+dnJz/o6Gh/6enpv+trK3/sLCw/7W0tP+4uLj/vby9/8LCwf/HxcX/ysrK/8/Pz//R0dH/1NTT/9bV - 1f/Z2dn/29ra/93c3P/g4N//4uHh/+Hh4f/h4OD/4ODg/9/f3//f39//393d/93d3f/d3d3/29ra/9nX - 1//W1dX/1NTT/9HQ0P/Qz8//zszN/8zKy//JyMj/x8XF/8TCw//Bvr//v728/7y7u/+7uLj/uLa2/7a0 - tP+0sbL/sa+v/7Ctrf+urKz/ramq/6moqP+joaH+sLCw8+jo6P/n5+f/5+fn/+fn5//t7e3/srKywQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAF5c3MofX19Zl5cXshUU1P/WFZX/1pZWf9dXF3/YWBh/2VkZf9paGn/bm1t/3Jx - cf92dXb/e3t7/4CAgP+FhIX/ioqK/5CQkP+WlZX/nJuc/6CgoP+np6f/rKys/7Kysv+2trb/urq6/7++ - vv/Dw8P/yMjI/83Nzf/Q0ND/09PT/9XV1f/X19f/2tra/93d3f/g4OD/5OTk/+Xl5f/l5eT/5uXl/+bl - 5f/m5uX/5+bm/+jn5//q6Of/6Ofn/+fm5v/m4+X/5eTk/+Ti4f/i4eH/4eDf/+Hf3//f3Nz/3dvb/9rZ - 1//Z1tb/1tTU/9TR0f/S0ND/0M/O/87Ny//Mysn/ysjI/8jFxf/Fw8P/xMHB/8K/vv/Bvb3/vry7/726 - uv+7uLf/ure2/7e1tf+2tLP/tbGy/7Ovr/+zr67/sa6t/7CtrP+vrKz/rauq/62pqv+sqaj/rKem/6um - pv+ppqX/qaWl/6ikpP+npKP/p6Kj/6ajov+loaD/AAAA/6Shn/+koKD/pKCf/6Ofn/+hn57/oJ6e/56c - m/+lo6Py4uPj/ejo6P/n5+f/5+fn/+zs7P/ExMTgVVVVCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcXFxK6KfoOmtrK3/t7a2/7y8 - vP++vr7/w8LC/8XExP/Hx8X/yMjI/8rKyf/Ly8v/zs7O/9DQ0P/T09P/1dTU/9XV1P/W1dX/19bV/9fW - 1v/X1tb/2dfX/9rZ1//b2df/2tnX/9rX1//Z19b/19bV/9fV1P/W1dT/1tTT/9XS0//V0tH/0tHQ/9HQ - z//Qzs3/z8zN/87Lyv/Mysn/y8rJ/8vJyP/Kxsf/ycXF/8fEw//Fw8P/xcLC/8TBwP/DwcD/w8HA/8K+ - vv/Cvr3/wb69/7+8vP+/vLv/vry7/767u/++urr/vbq6/724t/+7uLf/u7e3/7q3tv+6trb/uLa1/7i1 - tP+3tbT/uLS0/7e1tP+3tLP/trSz/7azsv+1sbL/tbGw/7SxsP+0sK//s7Cv/7Gvrv+zr6//sa6u/7Gu - rf+wra3/r62s/6+trf+vraz/r62s/66srP+urKz/raus/6ysq/+tq6z/rKur/6ysrP+sq6z/q6us/6ur - q/+pqav/qaur/6ipq/+oqav/qKmr/6akpP+hn57/oJ6d/6CdnfXa2tr76urq/+jo6P/o6Oj/7Ozs/9LS - 0vdwcHAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAACEhIQbqKWl3a2pqv+ppqb/qKal/6elpP+mpKP/pqOj/6ajov+mo6P/pqSj/6ak - pP+npKT/qKWk/6impf+rp6b/rKio/62pqv+vrKv/sK2s/7Gvrv+0sK//tbGy/7azs/+4tbT/u7a2/7y4 - t/++urn/vru7/8G8vP/Cvb3/wr69/8PBwP/DwcD/w8HA/8PBwP/DwcD/w8HA/8PBwP/DwcD/w8HA/8O/ - wP/Dv8D/wr++/8K/vv/Dvr//w7++/8K/vv/Cv77/wr6+/8K+vf/Bvr3/wb29/8G9vP+/vr3/wb29/7+9 - vP+/vb3/v728/7+9vf++vb3/vr28/769vf++vL3/vr29/76+vf++vb3/vb69/729vf+8vb3/vb29/7y9 - vf+8vb3/u7y9/7u8vP+4urz/t7q6/7a3uP+1tbb/tLS0/7SztP+ysrL/r66t/6ypqv+rpqX/qKGi/6eg - nv+mnpz/pJyZ/5+Ukf+cjYr/mImE/5eEf/+VgXz/lX55/5J6c/+Mcmv/iWxk/4VmXf+BYFb/kIeF/6Sj - o/+hnp7/m5mY99LS0vjs7Oz/6Ojo/+jo6P/r6+v/4ODg/4KCgj8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFVVVQOZmJiynZqZ/52a - mf+dmpr/nZqa/52amv+dmpr/npub/5+dnP+gnp7/oaCf/6WhoP+mo6L/p6Sk/6mmpf+rqKf/rauq/6+s - q/+xrq3/s7Cw/7Wxsv+3tLT/uLW2/7u4t/+8urr/vry7/8G9vP/Cvr7/w7/A/8TCwf/Fw8P/x8TE/8fF - xf/Ix8X/yMfH/8jIx//IyMj/ycjJ/8rJyv/Kysr/ysrK/8rKy//Jysv/ycrK/8rLy//Ky8v/ycvL/8jK - yv/Iysr/x8nJ/8XIyP/Excb/w8TE/8HCwv/BwcH/vb29/7u4uP+4trX/trOy/7SurP+xqqr/r6al/6qg - nf+nmZf/o5SQ/6GPjP+fi4f/nYaC/5eAe/+TeHP/jnFs/4trZf+KZ2D/iWRc/4VeV/+AWFD/fFJI/3dL - Qv91Rz3/dUQ6/3RCOP9xPjT/bTgv/2s1Kf9pMSb/aC8j/2gtIf9oLCD/Zigd/2QnG/9jJBn/YiQY/2Ij - F/9iIhf/YiIW/2IiFv9iIhX/YiEV/1waEP9cSEL/pqeo/6Genv+ZmZn6x8fH9e3t7f/q6ur/6urq/+vr - 6//n5+f/k5OTYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJiWloaenJv/npyb/56cm/+fnZz/n56d/6Cenv+hn5//o6Gg/6Wj - o/+mpqX/qain/6urq/+tra3/rq6v/7Cwsf+ztLT/tba3/7e4uP+6u7z/u72+/73Av/++wcL/wMLD/8DC - w//BwsL/wcLD/8LCw//CwsP/wsLC/76+vv+8urr/ura1/7ezsf+2r63/tK2r/7Gopv+toaD/p5iX/6OT - j/+hjYr/n4mF/5uEgf+Xfnn/k3Zy/4xuaP+JZ2L/h2Jc/4RgWf+AWlL/fFNM/3lMRf90RT//c0I5/3E/ - Nv9uOzP/ajYu/2cyKf9lLiX/ZCoi/2MoIP9iJx7/YCUb/18iGv9dIBj/XR4W/10dFf9dHBX/XRwV/1wb - FP9dGxP/XBoT/1waE/9cGxP/XRsT/10cE/9dHRP/Xh4V/18eFf9fHxX/Xx8V/2AfFv9hIBb/YSEX/2Ii - F/9jIxj/YyMY/2MjGP9kJBn/ZCQZ/2UlGf9lJhr/ZSYa/2UmGv9lJxr/ZSca/2YoGv9mKBv/ZSMX/1E3 - L/+goaP/o5+f/5qVlf28u7v07e3t/+rq6v/q6ur/6urq/+3t7f+goKCJAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAl5SUWJ6c - m/+enJv/np2d/5qbm/+Xl5b/l5WU/5iUkv+blJP/mJGP/5SNjP+SiIb/j4OB/5GBff+Sf3v/lX96/5J7 - df+Lc27/h2xm/4VnYP+FZFv/hWFY/4dfVv+BWVH/elFI/3ZKQP90RTz/dEE4/3Q/Nf9yPTT/bTcv/2gx - KP9mLiX/ZCoh/2EnHv9hJR3/YCQb/14hGv9cHhf/WxwW/1oaFP9aGRP/WhkT/1oYE/9aFxL/WRcS/1kX - Ev9aFhL/WhcS/1oXEv9aGBL/WxgS/1sZE/9bGhP/XBoT/1waE/9cGxT/XRwV/10dFf9eHhb/Xh4W/14f - Fv9eHxf/Xx8X/2AfF/9gIBj/YCEY/2EhGf9hIRn/YiIZ/2IiGf9iIhn/YiIZ/2IjGf9iIxr/YyMa/2Mj - Gv9jIxr/YyQa/2MkGv9jJBr/ZCUa/2QlGv9kJRr/ZCUa/2QlG/9lJhv/ZSYb/2UnG/9lJxv/ZScb/2Yo - Gv9mKBv/Zigb/2YoG/9nKBv/Zigb/2YoG/9oJxr/Ui0k/5aWl/+koaD/m5iY/rCur/Ps7Oz/6+vr/+vr - 6//r6+v/8PDw/7GxsbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACPioowm5mY/KCiof95XFX/Xy0i/14tI/9dKSD/Xice/2Uq - Hv9mKBz/ZSYb/2MjGf9iIRf/YR8W/2IfFP9lHxX/ZyAV/2YeFf9lHhT/ZR0T/2UcE/9lHBL/ZRsS/2Uc - Ev9lHBP/YxwT/2McE/9jHBP/YxwU/2McFP9jHRT/Yh4W/2IeFv9iHhf/YR4X/18eFv9eHhb/Xh4W/18f - F/9fHxf/Xx8X/18fF/9fHxf/Xx8X/18fF/9fHxf/Xx8Y/18fF/9fHxf/XyAY/18gGP9fHxf/XyAX/2Ag - GP9gIBj/YCAY/2AgGP9gIBj/YCAY/2AgGP9gIRn/YCEZ/2AhGf9hIRn/YSEZ/2EhGf9hIRn/YiIZ/2Ii - Gf9iIhn/YiIZ/2IjGf9jIxr/ZCMa/2QjGv9kIxr/ZCQa/2QkGv9kJBr/ZCUa/2QlGv9lJhv/ZSYb/2Um - G/9lJhv/ZSYb/2YnG/9mJxv/Zigb/2YoG/9nKBv/Zygb/2coG/9nKBv/Zygb/2coG/9oKRv/aCkb/2sp - Gv9QJhv/iIiI/6ajo/+fnJv/qKam9Obm5v7s7Oz/6+vr/+vr6//x8fH/wMDA0AAAAAIAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHBg - YBCbmprlo6Wm/21PSP9ZFg7/Xh0T/14dFP9eHRP/YiAV/2UhFv9nIRb/ZyIX/2cjGP9nIhf/ZyIX/2Yi - F/9nIxj/aCMY/2okGf9qJBn/aiQZ/2okGf9pIxj/aSMY/2okGf9pIxj/aCIY/2ciGP9mIhj/ZiEY/2ci - Gf9nIRn/ZiEZ/2UhGf9lIRn/ZSEZ/2IgGP9gHxf/YCAY/2AgF/9fHxf/Xx8X/18fF/9gIBj/YCAY/2Ag - GP9gIBj/YCAY/2AgGP9gIBj/YCAY/2AgGP9gIBj/YCAY/2AgGP9hIRj/YCAY/2AgGP9hIRn/YSEZ/2Eh - Gf9hIRn/YSEZ/2EhGP9iIhn/YiIY/2IiGf9iIhn/YiIZ/2MjGv9kIxr/ZCMa/2QjGv9kJBr/ZCQa/2Uk - G/9lJRr/ZSUa/2UmG/9lJhv/ZSYb/2YmG/9mJxv/Zicb/2YnG/9mKBv/Zygb/2coG/9oKRv/aCkc/2gp - HP9oKRz/aCkc/2gqG/9oKhv/aCob/2gqG/9oKhv/aysc/1UkFv96dnX/qKam/5+dnf+gnp714ODg++3t - 7f/s7Oz/7Ozs//Hx8f/Pz8/tXl5eEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJuYl8KlpKX/d2Vg/1gaEf9gIBb/XyAW/18g - Fv9gIBb/ZiMX/2cjGP9oJBj/aCQY/2ckGP9oJBj/aCQY/2cjGP9nIxj/ZyMY/2gjGP9pJBj/aiUZ/2sl - GP9qJBj/aiQY/2okGP9qJBn/aiQY/2kjGf9oIxn/ZyIZ/2giGf9pIxn/ZyIZ/2ciGf9nIhn/ZyIZ/2Uh - Gf9jIBj/YSAY/18fF/9fIBj/YCAY/2AgGP9gIBj/YSAY/2EgGP9hIRj/YSEY/2EhGP9hIRj/YSEY/2Eh - GP9hIRj/YSEY/2EhGP9hIRj/YiIZ/2EiGf9iIhn/YiIZ/2IiGf9iIhn/YiIZ/2IiGf9iIhn/YyMa/2Mj - Gv9jIxr/ZCMa/2QkGv9lJBr/ZSQa/2UlGv9lJhr/ZiYb/2YmG/9mJhv/Zicb/2cnG/9nJxv/Zigb/2Yo - G/9nKBv/Zygb/2gpG/9nKRz/aCkc/2gpHP9oKRz/aCoc/2gqG/9pKxz/aSsc/2krHP9pKxz/aSsc/2kr - HP9rLBz/WiIV/21jYP+pqKj/oZ6d/5yamffW1tb58PDw/+zs7P/t7e3/8PDw/93d3f19fX0vAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAm5iYl6Sho/+GfHv/Vx4U/2AhFv9fIRb/XyEW/18hFv9kIxf/aCUY/2glGP9pJRj/aSYY/2gl - GP9oJRj/aCUY/2gkGP9oJBj/ZyQY/2cjGP9oIxj/aSQZ/2olGP9rJBj/aiQY/2skGP9rJRj/ayUY/2sl - GP9qJBn/aiQZ/2kkGf9qJBn/aSQZ/2gjGf9nIxn/aCMZ/2cjGf9lIRn/YCAX/2AgF/9iIBj/YyEY/2Mh - GP9jIRj/YyEY/2MhGP9jIRj/ZCEZ/2MiGf9jIRn/YyIZ/2MiGf9iIhn/YiIZ/2EiGf9iIhn/YiIZ/2Ii - Gf9iIhr/YyMa/2MjGv9jIxr/YiIZ/2MjGv9jIxr/ZCMa/2QkGv9lJBr/ZSUa/2UlGv9lJhr/ZiYb/2cm - G/9mJxv/Zycb/2coG/9oKBv/aCgb/2goG/9nKBv/aCkc/2gpHP9oKRz/aSod/2kqHf9pKhz/aSsc/2kr - HP9pLBz/aiwc/2osHP9qLBz/aiwc/2stHP9rLB3/ay0c/2stHP9jJRb/YFFL/6enqP+hnp3/mZaZ+szM - y/bx8fH/7e3t/+3t7f/v7+//6Ojo/4iIiE8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZmZlpoZ+f/5OQkP9aKBz/YSAU/2Ei - Fv9hIhb/YCIW/2EiFv9oJRj/aSYY/2knGP9pJxj/aScY/2kmGP9pJhj/aCYY/2gmGP9oJRj/aCUY/2gl - GP9nJBj/aCQY/2olGP9rJRj/ayUY/2slGP9rJRj/bSYZ/2wlGP9sJRn/ayUZ/2slGf9rJRn/ayUZ/2ol - Gf9pJBr/aiUa/2slGv9oIxn/YyEY/2MhGP9jIhj/ZCIY/2QhGf9kIRn/ZCMZ/2QjGf9lIhn/ZSIZ/2Uj - Gf9lIhn/ZSIZ/2QjGf9kIxn/ZCMZ/2MjGf9jIxn/YyMZ/2MjGf9jIxn/ZCQZ/2QkGf9jIxn/YyMY/2Qk - Gf9kJRn/ZSUa/2UmG/9mJhv/ZiYb/2cnG/9nJxv/aCcb/2goG/9oKBv/aSgb/2kpHP9pKRz/aiod/2oq - Hf9pKxz/aSsc/2orHP9qLBz/aiwc/2osHP9rLRz/aywd/2stHf9rLh3/ay0d/2suHf9rLh3/bC4d/2wt - Hf9sLh3/bC4d/2kpGP9ZQjn/o6Sm/6Genv+YlpX9wL6+9fLy8v/t7e3/7+/v//Dw8P/w8PD/paWldwAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAJiUlD6hnp3/nZ2e/2E2K/9iHhP/YyMW/2MjFv9jIhb/YiEW/2YkF/9rJhj/aiYY/2sn - GP9sJxn/bCcZ/2wmGP9rJhj/ayYY/2smGP9rJhj/aiYY/2olGP9qJRj/aSUY/2smGP9rJhj/ayYY/2wm - GP9tJhj/bicZ/24mGf9uJhn/biYZ/20mGf9tJhn/bSYZ/20mGv9sJhr/bCYa/2wmGv9sJhr/ZyMZ/2Qj - GP9lIxn/ZiMZ/2YjGf9mIxn/ZyQZ/2ckGf9nJBn/ZyQZ/2YkGf9mJBn/ZiQZ/2YkGf9mJBn/ZiQZ/2Uk - Gf9lJBn/ZSQZ/2YlGf9lJRn/ZiUa/2UlGf9kJBn/ZCQZ/2UlGv9mJhr/Zicb/2cnG/9nKBv/aCgb/2go - G/9pKRz/aSkc/2kpHP9qKh3/aiod/2oqHP9rKxz/aysc/2ssHP9rLRz/ay0d/2wtHf9sLR7/bC0e/2wt - Hv9sLR3/bC4d/2wvHf9tLh7/bC4d/20vHf9tLx7/bS8e/20vHv9tLx7/bi0b/1Y3LP+bnJ7/o6Cf/5uY - mP61tLP08fHx/+/v7//v7+//7+/v//T09P+qqqqcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhISEG5yZmfCjpKX/a0o//2Ie - Ev9kIxb/ZCMW/2QjFv9kIxb/ZCMW/2snGP9tJxn/bSgZ/20oGf9uKBn/bigZ/20oGf9tJxn/bScZ/20n - Gf9tJhj/bCYY/2wmGf9sJhj/bCYY/20nGf9sJhn/bScZ/20nGf9uJxn/byga/3AoGf9wKBn/bygZ/3Ao - Gv9vKBr/byga/24nGv9uJxr/bica/28oG/9vKBv/ayYa/2ckGf9oJBn/aSQa/2klGv9pJRr/aiYa/2om - Gv9qJhr/aSUa/2klGv9oJRr/aCUa/2clGf9nJRn/ZyUZ/2clGf9nJRn/ZyUa/2clGv9oJhr/aCYa/2Yl - Gf9nJRn/aCYa/2gmGv9oJxv/aScb/2koG/9pKBv/aSkb/2oqHP9qKhz/aioc/2srHf9sKx3/aysc/2ws - Hf9sLB3/bS0e/20tHv9sLh7/bS4e/20vHv9tLx7/bS8e/20vHv9tMB7/bTAe/24wHv9tMB7/bjAe/24w - Hv9uMB7/bjAe/20xHv9vMR3/VjAh/5GRkf+lo6L/n5ub/6qpqPTr6+v+8fHx//Dw8P/w8PD/9vb2/7u7 - u8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAABVVVUDnJqa0Kamp/90Xlj/Xh0R/2YmF/9mJRf/ZSQX/2UkF/9kIxb/aCYY/24q - Gf9uKhn/byoZ/28qGf9vKhr/byoa/28qGv9vKhr/bika/24pGv9uKBn/bigZ/24oGf9uKBn/bikZ/28p - Gv9vKRr/byka/28pGv9vKRr/byka/3EqGv9yKhr/cioa/3MqGv9zKhv/cioa/3IrG/9xKhv/cCob/3Aq - G/9xKxz/cCoc/2wmGv9qJhr/ayYa/2wmGv9sJxr/ayYa/2smGv9rJhr/aiYa/2omGv9qJhr/aiYa/2km - Gv9pJhn/aCYa/2gmGv9oJxr/aSca/2knGv9pJxv/aCca/2gmGv9oJhr/aSca/2knG/9qKBv/aygc/2sp - G/9rKhz/ayoc/2srHP9sKx3/bCwd/2wtHf9tLR7/bS0e/24tHv9uLR7/bi4e/24vHv9uMB7/bjAe/24w - Hv9uMB7/bjAe/24wHv9vMR//bzEf/28xH/9vMR//bzEf/24yH/9tMh//bTIf/3AzH/9ZKxv/g4GA/6el - pf+fnZz/oqGh9uXn5vzy8vL/8fHx//Hx8f/29vb/zc3N31VVVQkAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACcm5mopqWl/4F2 - cv9aHhL/ZSQW/2gnF/9oJxf/aCYX/2cmF/9nJhf/byoZ/3ArGv9wLBr/cSwa/3EsGv9xLBr/cSwa/3Er - Gv9wKxr/cSsa/3ArGv9wKhr/cCoa/3AqGv9wKhr/cSsa/3ErGv9xKxr/cSsa/3ErGv9xKxr/cSsa/3Mq - Gv9zKxr/cysa/3QrG/91Kxr/dSwb/3UtHP91LRz/dCwc/3QtHP9zLR3/dC4d/3IrHP9uKBv/bica/28o - G/9vKBv/bygb/24oG/9uKBr/bSga/20nGv9sJxr/ayca/2snGv9qJxn/aycZ/2snGv9rKBr/bCga/2so - Gv9rKBr/aCYZ/2knGv9qJxr/aiga/2spG/9rKRv/bCoc/2wrHP9tLBz/biwc/20tHP9tLR3/bS0d/24u - Hv9uLh7/by8e/28vHv9vLx7/bzAf/28xH/9vMR//bzEf/28xH/9wMh//cDIf/3AyH/9wMh//cDIf/3Az - H/9vMx//bjQf/24zH/9vNB//cTQf/18rGf94cW3/qKen/6Genf+dm5r43Nzc+fX19f/x8fH/8fHx//X1 - 9f/Z2dn2c3NzHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJuZmXqko6L/kIqJ/1slF/9kIxT/ZSQW/2knGP9qJxj/aScX/2gm - F/9sKBj/ci0a/3IsGv9yLRr/cy0b/3MtG/9zLRv/cywb/3MsG/9zLBv/cywa/3IrGv9yKxr/cisa/3Es - Gv9yKxr/cy0b/3MtG/9zLBv/cywb/3MsG/9zLRv/cy0b/3UtG/91LRv/dS0b/3YuG/92Lhz/dS4c/3cv - HP94MB3/eDAd/3gwHf93MB7/eDAe/3gwHv9zLBz/cCob/3ErG/9xKxv/cSsb/3AqG/9vKhv/bykb/24p - Gv9uKBr/bSga/2woGv9sKBr/bCka/2wpGv9tKRv/bSob/20qG/9rKBr/ayca/2woGv9sKRr/bCob/20r - G/9sLBz/bSwc/24tHP9vLR3/by0d/28tHf9vLh7/by8e/28wH/9vMB//cDEf/3ExH/9xMR//cDIf/3Ay - H/9wMh//cTMf/3EzH/9xMx//cTMf/3E0H/9xNB//cDUf/280H/9wNB//bzQf/3A1H/9xNR//ZSwY/2lc - V/+pqKj/oZ6e/5qZmfrS0tL39vb2//Ly8v/y8vL/9fX1/+rq6v+IiIg+AAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmJiVTaOg - oP+bm5z/YDEk/2YhE/9mJBb/ZiQW/2snF/9tKRj/aygX/2snF/9yLRr/dC4a/3QvG/91Lxv/dTAb/3Uw - G/91MBz/dS8c/3UvHP90Lhz/dC4b/3QuG/90Lhv/cy4b/3MtG/90Lhv/djAc/3YwHP92Lxz/di8c/3Yw - HP92MBz/djAc/3cwHP94MBz/eTAc/3gwHf93MB7/dzAe/3gxHv95Mh7/ejIe/3szH/98Mx//fTQf/301 - IP96Mh7/dC0c/3MsHP9zLBz/cywc/3IrG/9xLBv/cSsb/3AqGv9vKhr/byka/28pGv9vKhr/byoa/28q - G/9vKxv/cCwb/24qG/9rKBn/bCka/20qG/9tKhv/bisb/28sHP9vLRz/by0d/28uHf9wLx3/cC8d/3Ew - Hv9xMB//cTEf/3AyH/9xMh//cTMf/3IzH/9yMx//cjMf/3E0H/9yNR//cjUf/3I1H/9yNR//cjUf/3E1 - H/9wNh//cTYf/3A2H/9wNh//cDYf/3E2H/9sLxr/Y09F/6WmqP+hnp7/mJaW/cTExPb39/f/8vLy//Ly - 8v/09PT/8fHx/5iYmGMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQiYknoJyb+KSlpv9oQzf/ZiES/2gmFv9nJhb/ZyUW/2so - F/9vKxj/bSkX/3ArGP93MBv/dzAb/3cxG/93MRz/dzEc/3cxHP94MRz/eDEc/3gwHP93MBz/dzAc/3cw - HP93MBz/dzAc/3YwHP93MBz/ejId/3oxHf96Mh3/ejId/3oyHf95Mh3/eTId/3ozHf97Mh3/ezMd/3o0 - H/96NB//ezUf/3s1H/97NR//fDYf/382IP+ANiD/gTcg/4M5Iv+CNyH/ezIe/3YvHP91Lhz/dC0c/3Qt - G/9zLBv/cisa/3EsGv9xKxr/cCsa/3ArGv9wKxr/cSsa/3ErG/9xLBv/cSwb/20oGf9uKRr/bioa/24q - G/9vKxv/bywb/3AsHP9xLR3/cS4d/3EvHf9xMB3/cTEd/3IxHv9zMh7/cjIe/3EzH/9yMx//czQg/3M0 - IP9zNCD/cjUf/3I1H/9zNSD/czYg/3Q2IP9zNiD/cTcg/3I3IP9yNyD/cjcg/3E3IP9yNyD/cjcg/3E0 - HP9aQTT/oKGj/6Ofnv+bmJj+uLe39Pb29//09PT/9PT0//T09P/39/f/pKSkiQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJlm - Zgqgm5vdp6ip/3VaT/9mIRH/aycX/2onFv9pJxb/aSYW/20pF/9xLBn/cCsY/3YwG/97Mhz/ezIc/3s0 - Hf97Mx3/ezQd/3w0Hv97Mx3/ezMd/3szHf97Mx3/ezId/3syHf97Mh3/ejId/3oyHf97Mx3/fTYe/301 - Hv99NR7/fTUe/301Hv99NR7/fTYf/302H/9/OB//fTcg/384IP9/OCD/fzgg/4A5If+AOSH/gTgh/4M5 - If+DOiL/hDsi/4Y8I/+IPiP/hTsi/381IP96Mh3/eTAc/3YuG/91LRv/dC0a/3MsGv9yLBr/cisa/3Ir - Gv9yKxr/cisa/3IsGv9zLBv/byoZ/20pGf9vKhr/cCsa/3EsG/9wLBv/cC0b/3EuG/9yLxz/cy8c/3Mw - Hf9yMR3/czEd/3MyHv90Mh//czMf/3IzH/9zNCD/czQg/3Q1IP9zNiD/dDcg/3Q3IP90NyD/dDcg/3Q3 - IP9yNyH/czch/3M4IP9zOCD/cjgg/3I4IP9zOCD/dDce/1w4KP+Wlpj/pKGg/56bm/+urKz28vLy/vX1 - 9f/19fX/9fX1//r6+v+5ubmvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ+bm7ioqKn/gXFr/2YiEv9tKRf/bSgX/2wo - F/9sKBf/aycX/24qF/9yLRn/dC4a/300Hf99NR3/fTYe/302Hv9/Nx7/fzce/382Hv9/Nx7/fzYe/382 - Hv99Nh7/fTUe/301Hv99NR7/fTUe/3w1Hv9/Nx//gTkg/4A3H/+BNx//gTgg/4E4IP+BOCD/gTkg/4E6 - If+BOiH/gjsi/4I7Iv+CPCL/gzwi/4M8Iv+DPCL/hD0j/4U+I/+GPiP/hz4j/4g/I/+KQST/ikEk/4Y8 - Iv+CNh//gDUe/3syHf94MBv/di0a/3QtGv90LRr/dC0a/3QsGv90LRr/dC0a/3QtGv9zLBr/bigY/28q - Gf9wKxr/cSwa/3EsGv9yLRv/ci4c/3MvHP9yMBz/czEd/3QyHv90Mh7/dDIe/3QzHv91Mx//dTQf/3Q1 - IP90NSD/dDUg/3U2IP90NyD/dDcg/3U4IP91OCD/dDgg/3M4IP9zOCD/czkg/3M5IP9zOSD/czkg/3M5 - IP92OR//WjIf/4uKiv+mpKT/n52c/6Sjo/fr6+v89/f3//X19f/19fX/+/v7/8bGxs8AAAACAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAnpqai6impv+Oh4T/ZikX/28qF/9uKhf/bioX/20pF/9tKRf/bCcX/28rGP91Lxr/fDQc/4M4 - Hv+BNx7/gTce/4E4H/+BOB//gTgf/4E5H/+BOB//gTgf/4E4H/+BNx//gTcf/4E4H/+ANx//gDge/4A3 - H/+DOiD/hDwh/4Q7IP+DOyD/hDsh/4Q7If+EPCH/gz4j/4Q/I/+FPyP/hkAj/4Y/I/+GQCT/h0Ek/4dB - JP+HQSX/iEIl/4lDJf+JQyX/ikIl/4xCJf+MQyb/j0Ul/4xAI/+FOiD/gzcf/4M2H/+ANR3/fDIc/3kw - G/92Lhr/di0Z/3YuGv92Lhr/di4a/3YuGv9wKhj/bykY/3AqGf9xKxn/cisa/3ItGv9zLhv/dC4c/3Qw - HP90MRz/dDId/3UyHf91Mh7/dDMe/3U0H/92NR//dTYf/3U3H/91NiD/dTcf/3U3IP91OCD/dTgg/3Y5 - IP91OSD/dDog/3Q6IP90OiD/dDog/3Q6IP90OiD/czog/3Q7IP9hMhv/fnp3/6impv+hnp3/npyc+OLi - 4vr5+fn/9vb2//b29v/7+/v/2NjY7F5eXhMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACdmJhepqSk/5qZmf9nMiD/cSsW/3As - F/9wLBf/bysX/28rF/9vKhf/bSkX/3IsGP96Mhv/hTsf/4U6H/+EOh//hDof/4Q7IP+EOyD/hDwg/4U7 - IP+FOyD/hTsg/4U7IP+FOyD/hDog/4Q6H/+EOiD/gzof/4Q5H/+HPyL/hz8h/4c/If+HPyH/hz8i/4hA - I/+HQST/h0Il/4hDJv+JQyb/iUMl/4lDJv+KRCb/i0Qm/4tEJv+LRSb/i0Um/4xGJ/+MRif/jkcn/49G - J/+QRyb/kkgm/5JHJv+KPiH/hDce/4Q4Hv+ENx7/gzce/4E1Hf99Mxz/ezEb/3kwGv94Lxr/eTAa/3Qr - Gf9vKRj/cCsY/3ArGP9xLBn/ciwa/3MtGv9zLhr/dC8b/3UwHP91Mhz/dDIc/3UyHf91Mx3/dTUe/3Y2 - Hv92Nh7/dTcf/3U3H/91OB//dTgg/3U4IP91OCD/djkg/3U6IP90OiD/dDog/3Q6IP91OyH/dTsh/3M7 - IP9yPCD/dD0h/2UyGf9yaGP/qaeo/6Genv+bmZj71dXV+Pr7+//29vb/9/f3//r6+v/l5eX9goKCLwAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAJOTkzSioJ/9o6Wn/2tBMf9yKhT/ci0Y/3EsGP9xLBf/cCwX/3AsF/9wLBf/bysX/3Mt - GP+COB7/ikAh/4g9IP+HPiD/hz8h/4g/If+IPyL/iEAi/4g/Iv+IPyL/iD8i/4g/Iv+IPyH/hz8h/4c+ - If+HPiH/hz0h/4c9If+JQyT/iUMj/4lCI/+KQiP/i0Ik/4pEJf+KRSb/i0Yn/4tHKP+MRyf/jEcn/45I - J/+OSCf/jkgo/49JKP+PSij/kEoo/5BKKf+RSij/kUso/5JLKP+SSif/k0on/5VLJ/+RRiT/hzsf/4Q3 - Hf+EOB7/hDcd/4Q3Hv+DNx7/gjYd/4A1Hf99Mxz/eTAa/3ApF/9wKRf/cCsY/3EsGf9yLBn/cy0Z/3Mu - Gf90Lxv/dDAb/3UxG/91Mhz/dTIc/3YzHf92NB3/dTYe/3Y2Hv91Nx7/dTgf/3Y5H/92OR//djog/3Y6 - IP92OiD/djoh/3U7If91OyH/dTsh/3U7If90PCH/czwh/3M8If90PSH/bTYb/2hYT/+nqKn/oZ+f/5iX - lv3Kysr3/Pz8//f39//39/f/+vr6//Ly8v+Ojo5PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeXl5E6Ofnumqq63/dFVH/3Ip - FP90Lxn/dC4Y/3QuGP9zLRj/cy0Y/3ItGP9yLBf/cSsX/3gwGv+JQCH/jUMj/4tBIf+JQSH/ikIi/4pC - I/+KQiP/ikIj/4pCI/+KQiP/ikIj/4pCI/+KQiP/ikIj/4pCI/+KQSP/iUEi/4pCI/+MRyX/jEYl/4xG - Jf+ORiX/jEcm/45JJ/+PSij/jksq/49MKv+QTCn/kUsp/5FMKv+STCr/kk0q/5JNK/+STSv/k04r/5RO - K/+UTyr/k04q/5ROKf+UTCn/lE0n/5dOKP+XTCf/j0Eh/4c5Hv+GOR7/hTke/4U4Hv+FOB7/hTke/4U5 - Hv+EOR7/fDMc/3YuGf9zLBj/cisX/3EsF/9xLBn/cy4Z/3QvGf90MBr/dDEb/3YyG/91Mhz/djQd/3Y1 - Hf91NR3/djYe/3Y3Hv92OB//djkf/3Y5H/92OiD/djsg/3c7If92OyH/dTwh/3U8If92PSH/dT0h/3Q+ - If90PiH/dT8h/3Q+If9yORz/Y0w9/6Slpv+jn5//m5mY/ry7u/b7+/v/9/f3//n5+f/5+fn/+fn5/6am - pnYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAABo6Cfx6ytrv+Aa2P/cSoU/3cxGv93MBr/djEa/3UwGf91MBn/dC8Z/3Qu - GP9zLRj/ciwX/4E4Hf+PRST/kEYk/4xDI/+LQiP/jUMj/45EI/+ORCP/jEQj/45EI/+MRCP/jkQk/4xE - JP+MQyT/jEMj/4xDI/+MQyP/jEMj/4xEJP+QSif/kEkm/5FKJ/+QSyj/kEwp/5FOK/+RTyv/kVEs/5JR - Lf+UUCv/k08r/5RQLP+UUSz/lFEt/5RSLf+VUi3/llIt/5dSLf+WUiz/llEr/5ZQKv+WTyn/lk8o/5dP - KP+bUSj/lUkl/4s9H/+HOR3/iDoe/4c6Hv+GOR7/hjke/4U6Hv+EOR7/gTcd/4A3Hf99NRz/eTEb/3Uv - Gv9zLhn/cy4Z/3QvGf91MRr/djIb/3YyG/91Mxz/djQd/3Y1Hf92Nh3/dzcf/3Y4H/92OR//dzof/3Y7 - H/93PCD/dzwg/3c8IP91PSH/dj0h/3Y9If91PiH/dT8h/3U/If91PyH/dT8h/3U9H/9fQi//nJ2f/6Oh - oP+enJv/sbCw9vf39/76+vr/+fn5//n5+f/+/v7/srKynAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgoJ+crKus/46C - fv9vLhf/eTIa/3gyGv93MRr/dzEa/3YxGv92MRn/djAZ/3UvGf90Lhj/djAZ/4tBIf+SSSX/k0kl/49G - JP+PRiT/kEcl/5BHJf+QRyX/kEcl/5BHJf+QRyX/kEcl/5BGJf+QRyX/j0Yl/5BGJf+PRiX/j0Uk/5BI - Jv+UTin/k00n/5JOKf+TTyv/k1Es/5RTLv+UVS//lVYw/5VWL/+WVC7/llQu/5dVL/+XVS//l1Uv/5dW - L/+ZVy//mVYv/5lWLv+aVS3/mVQs/5lSKv+ZUir/l1Ep/5hRKP+cUyn/m1Io/5JFI/+JOx7/iTwe/4k8 - Hv+IOx7/iDse/4g7Hv+DNx3/gjcd/4I4Hf+DOh7/gzof/4A5Hv97Nh7/dzIb/3UxGv90MRr/dTIb/3Yz - G/92NRz/djUd/3Y2Hf92Nx3/dzge/3Y5H/92OR//dzsf/3c8IP93PCD/dj0h/3Y9If93PSH/dz4h/3U/ - If91QCH/dkAh/3ZAIf91QCH/dkAg/187Jf+TkpP/paOj/5+dnf+mpaT38PDw/fv7+//6+vr/+vr6//// - ///Dw8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKCenm6rqKj/m5eW/3A2H/97Mxr/ejQb/3kzGv96Mxr/eTIa/3kx - Gv94MRn/dzAZ/3gwGf91LRj/gDcc/5NJJf+VSyb/lU0n/5JJJf+RSSX/kkol/5NKJv+TSib/kkom/5JK - Jv+SSib/kkom/5JKJv+SSib/kkom/5FJJv+RSSb/kUgl/5NNJ/+WUir/lFAq/5VSK/+WVC3/llcv/5dZ - Mf+XWjL/mFsz/5lbMv+ZWTD/mlkw/5pZMP+aWTD/mlow/5taMP+bWzD/m1ow/5xZL/+bWC3/mlYs/5pV - K/+aVCr/mlMp/5tSKP+cVCn/nlYq/5hOJv+MPyD/ijwe/4o9H/+KPR//ij4f/4c6Hv+EOB3/gzke/4Q6 - Hv+EOx7/hDwf/4Q9IP+EPSD/gjwg/3w6H/94Nh3/dzMb/3UzG/91NBz/djYd/3Y3Hf93OB7/djkf/3c6 - H/93Ox//dzwg/3c9IP93PSH/dz4h/3c+If93PyH/dkAh/3ZAIf92QCH/dkEh/3RCIf93QyH/Yjke/4aE - g/+opqb/oZ6e/6Cdnfjo6Oj7/v7+//r6+v/6+vr//////9XV1d9VVVUJAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoJycQ6mn - pv+kpaf/dEMu/340Gf98Nhv/fDUb/3w1G/98NBv/ezQa/3ozGv96Mhn/eTEZ/3gwGf93MBj/jEEh/5dN - J/+XTij/mlEq/5VMJ/+UTCf/lU0n/5ZNJ/+VTSf/lU0n/5VNJ/+VTSf/lEwn/5VNJ/+UTCf/lEwn/5RM - J/+UTCf/lEwn/5ZQKv+XVi3/l1Qs/5lXLf+ZWTD/mVwy/5peNP+bXzX/nGA3/5xgNv+cXjP/nV4z/5xe - M/+dXjP/nV4z/55eM/+eXjP/nV0x/55cMP+dWi7/nFks/5xYLP+cViv/nFUq/51TKf+cVCn/n1Yq/59W - Kv+TRyP/iz4f/4w9H/+MPyD/ij4f/4Y6Hf+GOh7/hTse/4U8Hv+GPR//hj0f/4U+IP+FPiD/hUAh/4RB - If+DPyH/fzwg/3k5Hv93Nh3/dTcc/3c4Hf92Oh3/djoe/3c7H/93PSD/eD4g/3c+IP92PyD/d0Ag/3dA - If92QCH/dkAh/3dBIv92QiL/dUIh/3dDIv9nORz/fXZw/6inqP+hn57/nJqZ+9za2vn/////+/v7//v7 - +///////4eHh9nh4eCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZmZkepqSj86ytsP95VEL/fjQX/4A5HP9/OBz/fzcb/303 - G/99Nhv/fDUb/3s0G/98Mxv/ezMb/3owGf+BNRz/l0wn/5pPKP+cUiv/nVMr/5hPKP+YTyn/mE8q/5hQ - Kf+YUCn/mlAq/5hQKf+YUCn/mE8p/5dPKf+XTyn/l08o/5dPKP+XTyj/lEwn/5ZRKv+bWy//m1ku/5tc - MP+cXzP/nWI2/55jN/+eZDj/nmU4/59lOP+eYzb/n2M2/59jNf+fYzX/n2I1/59iNf+fYTT/n2Ay/59f - MP+fXC//nlst/55bLP+eWSz/nlcr/51WKv+dVSn/n1cq/6NZK/+bUSf/kEIh/40+IP+PQCD/iT4f/4g8 - H/+IPR//hz0f/4c+H/+HPh//hz8g/4ZAIP+HQCD/hUEh/4ZBIf+HQyL/hkQj/4NDI/99PyH/eTsf/3Y6 - Hf92Oh3/dzse/3c9H/94PiD/dz4g/3c/IP94QCH/d0Ah/3dAIf93QSL/d0Ei/3ZDIv92QyL/d0Mi/206 - HP9wY1v/qair/6Ofn/+al5f9zc3N9//////7+/v/+/v7//7+/v/x8fH/ioqKPwAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZm - ZgWlpKTVr7K0/4BoXP98Mxf/gjoc/4E5HP+BORz/gTkc/4A4HP+ANxz/gDYb/4A2G/+ANRv/fjQb/3wy - Gv+NQSH/nFIp/5tSKf+eViz/oFYs/5tRKf+bUir/m1Mr/5tTK/+bUyv/mlMq/5pTKv+aUyr/mlMq/5tT - K/+bUir/m1Iq/5pTKv+XUCn/lEsm/5pWLf+dXzH/nV4x/55hNP+fZTf/oGg5/6JoO/+iaTv/o2o8/6Nq - O/+jaDn/o2g5/6NoOf+jZzn/o2Y3/6JlNv+hZDX/oWIz/6FhMf+hXzD/oF4v/6BdLv+fWy3/n1ks/59Y - K/+fWCr/n1Yq/6NaK/+hWCv/lUok/5BBIP+NQSD/iT8g/4o/IP+KPyD/iD8g/4lAIP+JQCH/iEIh/4hC - If+IQiH/h0Mi/4dDIv+HQyL/iEUj/4hGI/+GRiT/gkQj/3xAIv94PSD/dzwf/3g9H/94PyD/dz8g/3hA - If94QCH/d0Ei/3dCIv93QyL/dkMi/3dDIv93QyL/cj4d/2tXSf+lpqj/o6Cf/5uZmf7Av7/2//////v7 - +//8/Pz//v7+//r6+v+ioqJjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKikoq2wsLH/jH54/3k1Gf+FPB7/hDse/4M6 - Hv+DOh7/gzkd/4Q3Hf+DNxz/gjYc/4I1HP+BNhz/gDUb/4I3Hf+aTij/nVUr/51VK/+jWi//oVku/5xU - K/+cViv/nFYs/5xWK/+cViv/nVYr/51WK/+cVSv/nFUr/5xVK/+cVSv/nFUr/5tTK/+XTyn/l04o/51b - MP+gZDT/n2M0/6JoOP+kazv/pWw9/6VtPv+lbj7/pnA//6ZuPv+lbDz/pWw8/6VsO/+lazr/pWs6/6Ro - N/+kZzb/pGU0/6RjM/+jYTH/o2Aw/6FeL/+hXC3/oFst/6BaLP+gWSv/oFkr/6NaK/+lXCz/nFIo/5JF - Iv+MQCD/jEEh/4xBIf+KQiH/ikIh/4tCIf+JQyH/iUMi/4pDIv+IRCL/iEUj/4hFI/+IRSP/iEUj/4hG - I/+IRyT/iEcl/4ZIJf+BRST/ekAh/3g/IP93QCD/eEEg/3hBIf93QiH/eEIi/3dDIv93QyL/d0Mi/3dD - Iv92Qh//Yko4/6Khpf+joKD/npub/7Oysvf8/Pz+/v7+//z8/P/8/Pz//////6urq4kAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAApaGjgLCur/+alJH/eDsg/4g9H/+FPR//hjwe/4Y7Hv+GOh7/hjoe/4Q5Hf+EOB3/hDgd/4M3 - HP+CNxz/gDYb/49DIv+gVyz/n1ks/6FZLv+nYjL/o14w/55YLP+fWi3/n1ot/59ZLf+fWi7/n1kt/59Z - Lf+fWS3/n1gt/59YLf+fWS7/nFUs/5lSKv+ZUir/mFEq/6BgMv+kaDf/pGk3/6VtO/+mcD7/p3E//6hy - QP+oc0H/qHRB/6hyP/+nbz3/p28+/6duPv+nbjz/pm07/6ZqOP+laDb/pWY0/6VlM/+lYzL/pGEw/6Nf - L/+jXi7/oV0t/6FcLf+gWy3/oVos/6NaK/+lXy3/oVss/5RKJf+MQCH/jUMi/4xDIv+MQyL/jUQj/4tE - I/+LRCP/i0Qj/4pFI/+JRiP/ikYj/4lGI/+KRyT/ikck/4hHJP+IRyT/iUgk/4lKJf+ISyb/hEkl/31F - I/95QSH/d0Eg/3dCIf94QiL/d0Mi/3dDIv94RCP/eEQj/3hEIf9jRCz/mZmb/6Wjo/+gnZ3/qain9/T0 - 9P3+/v7//Pz8//z8/P//////v7+/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACjo6BTr62s/6Wlpf95RCv/iT0e/4g/ - IP+JPiD/iD4g/4g9H/+HPR//hzwf/4Y8Hv+FOx7/hToe/4Q5Hv+EOB3/hTkd/5tSKP+hXC//oVsu/6Zh - Mv+raTf/pGAx/6BcLv+gXS//oF4v/6BdL/+gXS//oF0v/6BdL/+gXS//oFwv/6BdL/+dVy3/nFQs/5xU - LP+bVCv/m1Qr/6NjNf+mbDn/p247/6pzQP+rdEH/q3ZC/6t3Q/+rd0T/q3dE/6t2Qv+qc0D/qnNA/6hz - P/+ocj7/p287/6dsOf+majf/pmg1/6ZmNP+mZDL/pWIw/6RhMP+jXy//o14u/6NdLf+jXS3/o1wt/6Nc - LP+lXi3/pWEu/5xWK/+PRSP/jUQi/5BGJP+PRiT/jkYj/45GI/+ORiT/i0ck/4tHJP+LRyT/i0gk/4tI - Jf+LSCX/iUgl/4lIJf+KSSX/iEol/4hKJf+JSyb/ikwm/4dLJ/+BSCX/ekQi/3dDIv93QyL/d0Qj/3hE - I/94RCP/ekYj/2I+I/+PjI3/pqWk/6Gfnv+in6D56+vr+//////+/v7//v7+///////Nzc3QAAAAAgAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAJqamiurqan6rrCz/35UPv+JPRz/iUIh/4pBIf+KQCH/ikAh/4k/IP+IPiD/iD4g/4c9 - H/+HPR//hzwf/4c7Hv+GOR7/j0Mj/6NcL/+jXjH/pWAy/6lpN/+tbzz/o2Iy/6FfMP+jYDH/o2Ax/6Ng - Mf+jYDH/oWAw/6NgMf+hXzD/oWAx/55aLv+dWC3/nVgt/51XLP+dViz/nVUs/6VnN/+qcj3/q3Q//613 - Qv+seUT/rXlF/656Rv+uekb/rnpG/614Q/+sdkH/q3ZB/6t1Qf+qcz//qHE8/6huOv+oazj/p2o1/6do - NP+nZjL/pmQx/6ViMP+kYTD/pGAv/6RfLv+jXi3/o14t/6NeLf+kXi3/qWcz/6NhMv+TTCb/j0Yi/5BI - JP+PSCT/kEgk/49IJP+OSST/jkkl/45JJf+MSiX/jEol/4xKJf+LSiX/ikol/4tKJf+JSyb/iUsm/4lL - Jv+JSyb/iUwm/4pNJv+ITSf/g0sm/3tGJP93QyP/d0Qj/3lFJP96RyT/aT0g/4N9e/+pp6f/o5+f/52a - mvvf3975//////7+/v/+/v7//////97e3u1jY2MSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdnZ2DaqqquGztbj/hGhX/4c8 - HP+KQiL/i0Ii/4xCIv+LQSH/i0Eh/4pBIf+KQCH/ikAg/4o/IP+KPyD/ij4g/4k9H/+JPB//nFMr/6Vh - M/+lYTP/qWc3/65yPv+udD7/pGIz/6RhMv+kYjP/pGIz/6RiM/+lYjP/pGIz/6RiM/+kYjP/nlwv/55b - Lv+eWy7/nlou/55aLv+eWC7/nlgu/6ZqOv+sdkD/rXhC/697Rf+wfEb/r31H/699SP+vfUj/r31I/656 - Rf+ueEP/rnhC/6x2Qf+rdUD/qnI9/6lvOv+obTj/qGs2/6hpNf+nZzP/p2Uy/6ZkMf+lYjD/pWEw/6Rg - L/+kYC7/pF8t/6RfLf+lYi//qWg0/6dnNP+aViz/kEck/5BJJP+RSiX/kEol/49KJf+QSyX/j0sm/49M - Jv+PTCb/j0wm/41MJv+NTCb/jUwm/4tMJv+KTCb/ikwm/4pMJv+ITSb/iE0m/4hOJv+KTyb/iU8n/4VN - J/99RyX/eEUk/3hGJP9sPR7/eW9m/6moqf+joKD/m5iX/dHR0fj//////v7+//7+/v//////6+vr/YKC - gi8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAq6qqvba2uP+OfXP/hT0d/4xEI/+MQyP/jUQj/41DIv+NQiL/jEEi/4xB - If+LQSH/ikAh/4tAIf+LPyH/iz8g/4k8H/+TRiX/pV0x/6VkNf+oaDf/rHA9/7B8Rf+udkD/pGMz/6Vk - NP+lZDT/pWM0/6ZkNf+lYzT/pWM0/6RjNP+gXTH/n1ww/59cL/+fXC//n1wv/59cL/+eWy7/nlou/6ds - Ov+ueUP/sHtG/7J+R/+wgEj/sIBJ/7KASv+wfkn/sH5J/697Rv+ueUT/rnhD/6x3Qf+sdT//q3E9/6lv - Ov+objn/qGs2/6hpNf+nZzT/p2Uy/6ZkMf+mYzH/pWIw/6RhMP+kYDD/o18u/6NfLv+nZTL/qWc0/6hq - Nv+eXjH/kkwn/5FJJf+QSyb/kUwm/5FMJv+QTCb/kE0m/5BNJv+PTSb/jk0m/45NJv+OTSb/i00m/4tN - Jv+LTSb/i00m/4lOJv+JTib/iU4m/4lOJv+JTib/i08n/4pPJ/+FTif/f0om/3JBHv9vYFP/qKir/6Og - oP+cmpr+wsHB9//////////////////////6+vr/lJSUTwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsp6eRtrW2/5eR - jf+BQCH/kEYj/45FI/+ORSP/j0Uj/49DI/+NQyP/jUIj/4xBI/+LQSP/i0Ei/4xAIv+MPyH/iz8h/4w/ - If+eUy3/pmQ1/6hpOP+sbzz/r3pE/7WESv+tcz7/pWM1/6ZmNv+lZjb/pmY2/6ZlNv+mZTX/pWQ1/6Be - Mf+gXjH/oF0x/59dMf+gXTD/oF0w/6BdMP+fXC//n1sv/6luPP+vfEX/sH5H/7KBSf+zgUv/s4FL/7KA - Sv+ygEr/soBJ/698Rv+ueUT/rnhC/613Qf+sdT//q3E8/6lvO/+obTj/qGs2/6dpNf+nZzT/p2U0/6Zk - M/+mZDL/pWIy/6RhMf+jYDD/o18w/6ViMf+mZjT/pmY0/6hpNv+kZTX/llMr/5BKJv+STCf/kk0n/5FO - J/+RTif/kE4n/49OJ/+PTif/j04n/45OJ/+NTif/jU4n/41OJ/+LTSf/ik4n/4lOJ/+JTif/ik8n/4pP - Jv+JTif/iU8n/4pPJ/+KUCj/hEsj/25VQv+kpaf/pKGg/56cnP+2tbT3/////v////////////////7+ - /v+pqal2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKqqqmO1s7P/pKSk/35GKv+RRiP/j0Yk/49GJf+PRST/kEUk/5BE - JP+PRCT/j0Mk/41DJP+NQiP/jEIj/41CI/+NQSP/jEAi/5ZKKP+kXjP/qWo5/6xuPP+wekT/tINL/7aG - Tf+rbTv/pmU2/6ZnN/+mZzf/pmc3/6ZnN/+lZTb/oV8y/6FgMv+hXzL/oV4y/6FfMv+gXjH/oF4x/6Be - Mf+fXTD/oF0w/6pwPv+wfkf/soFJ/7OCS/+0g0z/tINM/7OBS/+zgUv/soBK/698R/+uekT/rnlC/6x3 - Qf+sdD//q3E8/6lvO/+obTj/qGs3/6dpNv+nZzX/pmY0/6ZlNP+mZDP/pWMy/6RiMf+jYTD/o2Ew/6Zl - NP+mZjT/pmY0/6doNf+laDb/m1ow/5JNKP+STif/kk8o/5JPKP+RTyj/kE8o/5BPKP+QTyj/jk8o/45P - KP+OTyj/jk8o/41PKP+LTyj/ik8n/4pPJ/+KTyf/ik8n/4pPJ/+KTyf/iU8n/4lPJ/+NTyX/cU81/52e - of+lo6P/oJ6e/6uqqvj4+Pj9/////////////////////7m5uZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqqqqObSx - sv+vsrT/flI6/5FEIv+QRyb/kEcm/49HJf+QRyb/kUcm/5BGJv+QRSX/kEUl/5BFJf+PRCX/j0Ql/5BD - JP+QQiT/kkYm/51VLv+nZzj/rHA+/694Q/+1g0v/t4hQ/7eGTf+najr/p2g5/6dpOf+naTn/p2k5/6Vm - OP+jYjX/o2M1/6FhNf+hYTT/oWA0/6FgM/+hYDP/oV8y/6FfMv+gXjH/oV4y/6txP/+ygUn/s4NK/7SE - Tf+1hU7/tIRN/7ODTP+zgkz/s4FK/698Rv+uekT/rXhC/6x2QP+sdD7/qnI8/6lxO/+obTn/p2s3/6dp - N/+naDb/p2Y1/6ZlNP+mZTT/pWMy/6RiMf+kYTD/pGQz/6VmNf+lZzX/pWc1/6VnNf+maTf/n2I0/5RS - K/+STij/klAp/5FQKf+SUCn/kVAp/49QKf+PUCn/j1Ap/49QKf+OUCj/jVEo/4tRKP+LUCj/i1Ao/4tQ - KP+LUCj/i1Ao/4pQKP+JUCj/ilAo/45QJ/9zSSv/lpWV/6akpP+jn5//o6Ki+e7u7vv///////////// - ////////xsbGwQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQkJAXsK2s7Le6vP+DY1D/jEMh/5FJJ/+RSSf/kUkn/5FJ - J/+SSSf/k0gn/5JHJ/+SRyf/kUYn/5FGJv+RRib/kEUm/5FEJf+RRib/mk8r/6NfNP+scD//r3hE/7WC - Sv+5iFD/vI5V/7WCSf+najn/qGw7/6hrOv+obDv/pmc5/6NjN/+kZDf/o2M2/6NjNv+jYjb/oWI1/6Fh - Nf+hYDX/oWA0/6FgNP+hXzP/oWAz/6x0Qf+zg0r/tIRN/7WFTv+2hk//tYVO/7SDTf+0g03/s4JK/7B9 - Rv+vekP/rnlC/613Qf+sdD//q3E9/6lvO/+obTn/p2s3/6dqN/+maDb/pmc1/6ZmNP+lZTP/pGQz/6Ni - Mv+jYzP/pWc2/6VnNv+lZzb/pWc2/6VnNv+kaDb/omY2/5dYLv+RUCn/klEq/5JRKv+RUir/kVIq/5BR - Kv+QUSr/j1Eq/45RKv+NUSr/jVEq/41RKf+NUCr/jVAp/4tQKP+LUCj/ilAp/4tQKP+KUCj/jlEo/3dH - Jf+Lh4b/qKan/6ShoP+dm5z74eHh+v/////////////////////Y2NjgVVVVCQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAK0r6/Mu7y+/414bP+JQyH/kUoo/5JKKP+TSij/kkso/5JKKP+TSij/lEko/5NJKP+TSCj/kkco/5JH - KP+RRyf/kUcn/5FGJ/+YTiv/nlYw/6lsPf+vekX/tH9K/7mIUf+8jVT/wJNZ/695RP+mazr/qG08/6hu - Pf+lZzr/pGQ4/6RlOf+kZDj/pGQ4/6RkOP+kZDf/o2M3/6NiNv+jYjb/oWI2/6FhNf+hYTT/oWE1/6x1 - Qv+0hUz/tYVO/7eIUP+3h1D/toVP/7WETv+0hE3/s4JK/7B9Rv+ue0P/rXlC/613Qf+sdT//rHM9/6px - PP+objn/p2w4/6dqN/+naDb/pmc2/6ZmNf+lZTT/pGQ0/6RjM/+kZTb/pGc3/6RnNv+kaDb/pGg2/6Ro - Nv+kaDb/o2g3/5teMv+TUiv/k1Iq/5JTLP+SUiv/kVIr/5BTK/+PUyv/j1Ir/49SK/+PUSv/jlIr/45R - K/+NUSv/jVEr/41RK/+NUSv/i1Eq/41RKf+OUin/f0gj/4Z7df+pqKn/pKGi/5yamP3T09P4//////// - /////////////+Tk5PZ4eHggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALCsrKK8vL3/mY6I/4ZEJP+TSyj/kksp/5NL - Kf+USyn/k0sp/5NLKv+USyr/lUoq/5RKKv+USir/lEoq/5NJKf+TSSn/kkgo/5dOK/+cUy3/pWM4/694 - RP+0f0v/uYlR/7yOV//Ak1r/wJNZ/6txQP+obj3/qnA//6VoO/+lZzr/pWc6/6VmOv+lZjn/pGU5/6Rl - Of+kZTn/pGU5/6NkOP+hYzf/oWM3/6NiNv+hYjX/oWE1/612Q/+1hk7/tohQ/7eLUf+3iFD/t4ZQ/7aE - T/+1hE3/s4FJ/698Rv+vekP/rnlC/613Qf+tdT//q3M9/6pxPP+obTv/p2w5/6drOP+maTf/pmg3/6Vn - Nv+kZjX/o2U0/6NlNP+kaDj/pGg4/6RoN/+kaDf/pGg3/6NoN/+kaDb/o2k3/51kNf+UVi7/klIs/5NU - Lf+SUyz/kVMs/5BTLP+QUyz/kFMs/5BTLP+PUyv/jlIr/45SK/+OUiv/jlIr/41RK/+OUiv/jlIr/45S - K/+FSiP/emtg/6mprP+koaL/nZua/sXFxPf/////////////////////9fX1/4qKij8AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAArqurdLu6uv+mo6H/hEks/5RMKf+STSv/kkwq/5RNKv+UTSv/lEwr/5VMK/+WTCv/l0wr/5ZM - K/+WSyv/lksr/5VLK/+VSir/l04r/51WL/+gWzP/rXJC/7N+Sv+3h1H/vI9X/76SW//DmmD/uopT/6hu - Pv+qcEH/pWk9/6VpPP+laTz/pGg7/6RoO/+lZzr/pWc6/6RmOf+kZjn/pGY5/6RlOf+jZDj/o2Q4/6Nk - OP+hYzb/oWM2/613RP+3iFD/t4tR/7mMUv+3i1H/t4hQ/7aGT/+0hEz/sIBI/698Rf+ve0T/rnpD/614 - Qf+tdT//q3M9/6pwPP+obTv/p2w6/6drOf+majj/pmk3/6VnNv+kZzb/pGY1/6RpOP+lajr/pWo5/6Rp - OP+kaTj/o2g3/6RpOP+jaDf/pGk4/59nOP+WWzL/klQt/5JVLv+SVS3/klQt/5JVLv+RVC3/kFQt/5BU - Lf+PUyz/j1Ms/5BULP+QUyz/j1Ms/49TLP+PUyv/j1Ms/4tOJv95YlD/pqeq/6Shov+gnZ3/uLa29/// - //7////////////////8/Pz/oqKiYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACuqqpIuri3/7CztP+DVDn/lEwo/5RO - K/+TTiv/lE4r/5ZOK/+WTSz/lk0s/5ZNLP+XTi3/mE4t/5dNLP+XTSz/l00s/5dNLP+XTiz/n1Yx/6BY - M/+naD3/snxI/7eGUP+8jlf/vpVb/8GXXv/EnGL/s31J/6twQP+naz7/pmo9/6ZqPf+maj3/pWo9/6Vq - PP+laTz/pWg7/6VoO/+kaDv/pGg7/6RnOv+jZjn/o2Y5/6NlOP+jZTj/oWM3/613RP+3i1H/uo1T/7qN - U/+3i1H/t4hQ/7aGTv+zgkr/r3xH/698Rf+wfEX/r3pD/654Qv+tdT//q3M9/6pwPP+pbjv/qG07/6ds - Ov+nazn/pmo4/6RoN/+kZzb/pGg2/6VqO/+lajr/pGo6/6RpOf+kaTn/pGk5/6NpOP+jaTj/omk4/6Bp - Of+ZYDX/k1Yu/5NVLv+TVi7/klYu/5FWLv+RVS7/kVUu/5FVLv+RVC3/kVUu/5BULf+QVC3/j1Qt/49V - Lf+OVS3/j1Ip/3JVP/+io6b/paOi/6Gfn/+sq6r4+fn5/f////////////////////+vr6+JAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAKigoCO3tLT1ury//4NiTP+STCf/lE8r/5VPLP+VTy3/lU8t/5dPLv+XTy7/l1Au/5dQ - Lv+ZUC7/mlAu/5pQLv+ZTy7/mE8u/5hOLv+eVjL/oFs0/6ViOf+tdET/toVP/7yNV/++k1z/wZde/8Sc - Y//Bll3/q3ND/6dtP/+obT//qG0//6dtP/+nbD//pmw+/6ZrPf+maj3/pmo9/6ZpPP+laTz/pGk8/6Ro - O/+kZzr/pGc6/6RnOf+jZjn/oWQ4/6x2RP+5jFL/u45U/7qNVP+5jFL/t4hQ/7WETP+wgEj/rntG/698 - Rv+wfEX/sHtE/655Qv+tdj//q3M+/6pwPf+pbzv/qW47/6htO/+nazn/pmo4/6VpOP+kaDb/pWs6/6Vr - PP+kajz/pGo7/6RqO/+jaTr/omk5/6JpOf+iaTj/omk4/6JqOf+cZDf/lFkx/5NXL/+TVy//k1cv/5NX - L/+TVy//klcu/5FWLv+QVy7/kFcu/49XLv+PVi7/j1Yu/49WLv+RViz/eFM1/5qbnf+npaX/o6Cg/6Sj - o/nv7+/8/////////////////////7+/v7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASUlJB7ezs9nBwsT/i3Nl/49J - Jv+UUS7/lVEu/5ZRLv+WUS7/llIu/5dRL/+ZUS//mlEw/5lRL/+aUTD/mlEw/5tQMP+bUDD/m1Av/55W - Mv+hXTX/pmM6/6lqQP+0gU3/vI1W/8CTXP/Bll7/wplg/8agZP+1hFD/p20//6hvQf+obkL/qG5B/6ht - QP+nbED/p21A/6dsP/+nbD//p2s+/6ZqPf+maz3/pWo9/6VqPf+laTz/pWg8/6VoO/+kZzr/o2U4/6x1 - RP+6jlP/u5BW/7qOVP+5jFP/t4hQ/7ODS/+wfUf/rnpF/698Rf+wfUb/sHtD/655Qv+tdkD/rHQ//6py - Pf+qcDz/qW47/6htO/+nbDr/pms6/6VqOf+lazn/pW09/6VtPf+kbDz/pGs8/6NrPP+iajv/omo6/6Jq - Ov+iajn/omk5/6BqOf+dZzn/ll0z/5RXMP+UWDD/lFkw/5JZMP+SWTD/kVgv/5FYL/+RWC//kVgv/5FY - L/+RVy7/kFcu/5NYL/96Ti3/k5GP/6impv+lo6L/oZ2d++Li4vr/////////////////////0NDQ0AAA - AAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAtrOzssLCxP+XioH/iUgn/5VSLv+UUi//llIv/5dSMP+XUzD/mVMw/5pS - Mf+bUjH/m1Mx/5tTMf+bUzH/nFMx/51SMf+cUTH/nlYz/6NeN/+mZTz/p2g+/652SP+7ilX/vpNc/8KX - YP/DmWH/xJ5j/8OaYv+rdUb/qG9D/6pvQ/+ocEP/qm9C/6puQv+nbkL/p21C/6dtQf+nbUD/p2w//6ds - P/+mbD//pmw+/6ZrPv+maj3/pmo9/6ZqPf+laTz/pGY6/6x0Q/+7j1X/vJFY/7uPVf+5ilL/toZO/7KC - Sv+vfEf/rXlE/698Rv+wfUb/sHtD/655Qv+tdkH/rXQ//6tzPv+qcj3/qW88/6luO/+obTv/p2w6/6Vq - Of+lbj3/pnA//6VuPv+kbT3/pG09/6NsPP+iazv/oms7/6JrO/+gajr/oGo6/59qOf+eaTr/mGA2/5Va - Mf+TWzL/k1oy/5NaMf+TWjH/k1ox/5NZMP+SWTD/kVkw/5FZMP+RWTD/klow/4JQK/+LhH//qaip/6Wj - o/+cm5r909PT+f/////////////////////g4ODtY2NjEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2srKFwsHB/6Wf - nP+FTC3/l1Mv/5ZTMP+WUzH/mVMx/5lUMf+ZVDH/mVQx/5tUMv+cUzL/nFMy/5xTM/+cVTP/nFUz/5xT - M/+eWDX/pF85/6dmPf+oa0H/qm5D/7aEUv++klz/wZdf/8OZYf/Em2P/x6Fn/7mKV/+ob0P/q3FF/6tx - RP+rcUT/q3BD/6tvQ/+qb0P/qG9D/6hvQv+obkL/qG5B/6dtQP+nbUD/pm1A/6ZsP/+naz7/pms+/6Zr - Pf+maz3/pWc7/6xzQ/+8kFf/vZJZ/7uOVf+3iFD/tIRM/7KASP+vfEf/rXhE/698Rf+yfkb/sHtD/654 - Qv+tdkH/rXVA/6x0P/+rcz7/qnI9/6hvPP+nbTz/pmw6/6ZtO/+ncUD/pXBA/6VuP/+kbj7/o2w+/6Jt - Pf+iaz3/oms8/6BrPP+gazv/n2o6/59qOv+eazv/mWM4/5VcMv+VWzL/lVwy/5NcMv+TWzL/k1sy/5Jb - Mv+RWzH/kVox/5JbMv+TWzL/h1Iq/4R3bf+rq6v/paOj/56cm/7GxsX4/////////////////////+3t - 7f2FhYUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAALSxsVjBvr7/s7Oz/4RTN/+ZUy//l1Qx/5dVMf+XVTH/mlUy/5pV - Mv+aVjP/nFc0/5xXNP+dVjT/nlU1/55WNf+eVjX/nlY1/59YNv+kYTv/qGc+/6ttQv+rb0T/sHlM/72Q - W//Bl1//w5lg/8ScZP/Gn2b/w5pi/696S/+qc0X/q3VG/6t0Rv+rdEb/q3NE/6pzRP+qcUT/qnFD/6hy - Q/+ocEP/qm9C/6hvQv+nbUH/p21B/6dtQP+nbUD/p2w//6dsPv+mbD7/pWg8/6txQ/+8j1f/vpVa/7qN - U/+3h0//tINL/7CASP+ve0b/rXhE/696RP+wfUX/sHpE/694Qv+td0H/rXVA/6x0P/+rcz7/q3E+/6hx - Pf+nbjz/pm07/6dxP/+mckL/pnFB/6VwQP+kbj//o28//6NtPv+ibT3/om09/6BrPf+gazz/n2o8/55p - O/+eaTv/m2Y6/5ZeNf+UXDP/lFw0/5RcNP+UXDT/lFw0/5NbM/+TXDP/k1wz/5NcM/+PViz/f2xc/6qp - rf+lo6P/oJ6e/7m4uPj/////////////////////+vr6/5mZmVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqKioL7u6 - uvy9wML/hmFJ/5ZRLf+XVTH/mVUy/5lWM/+aVzT/mlc0/5xXNf+cVzX/nFg1/51YNf+eVzX/n1c1/6BX - Nv+gWDb/oFg3/6ViPP+paUH/q25D/6xyRv+udkn/uYdW/8GYYP/CmWH/xpxl/8afZ//EnGP/vI9a/6t1 - R/+rd0j/q3ZI/6t2R/+rdkf/q3VG/6t0Rf+qdEX/qnRF/6pzRP+qcUP/qnFD/6pwQ/+ob0P/qG5C/6hu - Qf+obkH/qG1A/6dsP/+nbD//pmo9/6pwQv+7jlb/vpVa/7mKUv+2hk7/s4JK/7B+SP+ve0b/rXhD/655 - Q/+wfEb/sHtF/695Q/+td0H/rXZB/611QP+tdED/q3M//6pwPv+obzz/p28+/6hzQv+nckL/pnFC/6Zx - Qf+lcEH/o28//6JvP/+ibj7/om4+/6BuPv+gbT3/n2s9/55rPP+eazz/m2g7/5ZgN/+VXTX/lV41/5Ve - Nf+VXTX/lF01/5NeNf+TXjX/k141/5JbMP97Ykz/paap/6Wko/+hoKD/rays+Pn5+f3///////////// - ///+/v7/qampdwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACPj48QvLq65cTHyf+OcmH/k08r/5dWM/+ZVzT/mlc0/5pX - NP+aWDX/m1g1/51ZNf+dWjb/nlo2/55bNv+fWzf/n1s3/6BaOP+hWjj/pmM9/6lqQv+scUb/rXRI/693 - Sv+zflD/vpNe/8KZYf/GnWf/xp9o/8OaYv/CmWD/s39Q/612Sf+teEn/rXhJ/6x3SP+sdkj/rHZH/6x1 - Rv+rdUb/q3VG/6t0Rf+qc0T/q3RE/6pzQ/+ockP/qHJD/6hwQ/+ocEL/qm5B/6puQf+qbkH/p2s+/6pv - QP+5jFT/vpNZ/7mJUf+1hU3/s4JK/7B9R/+ve0b/rXdD/653Q/+wfEb/snxG/7B5Q/+ueEL/rXdB/652 - Qf+tdUH/rHNA/6twP/+ocT3/qnNB/6p0RP+oc0P/p3ND/6VyQv+lckL/pHFB/6NwQP+jcED/om8//6Bv - P/+gbj7/n209/55sPP+ebDz/nGs8/5hiOf+WXjX/lWA2/5VgNv+VYDb/lGA2/5VgNf+VYDb/mF8z/31c - Qf+fn6L/p6Wl/6Shov+lo6P67+/v/P/////+/v7//v7+//////+0tLSdAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAC7ubnCyMjK/5eHfP+QTiz/mlc0/5lXNP+aWDX/m1k1/5xaNv+cWjb/nVs3/55bOP+fWzj/oFw5/6Bc - Of+hXTr/oV06/6FdOv+mZD7/qWtD/61ySf+udUr/sHhL/7N+T/+6ilj/wpli/8agaP/Gn2j/wppi/8GY - X/+9kFv/rnlK/695Sv+ueUr/rnlK/654Sv+td0n/rXdI/613SP+td0j/rHZH/6x1Rv+sdUX/rHVF/6t0 - RP+qc0T/qnND/6pzQ/+qcUP/qnBC/6hwQ/+ocUH/qG5A/6puQf+2h1H/vZFY/7mIUP+1hEz/s4JK/7B9 - R/+ve0b/rndD/612Qv+ve0X/snxG/7B6RP+ueEL/rnhC/613Qf+sdUH/q3RB/6pzQP+oc0D/q3ZE/6t1 - RP+odEP/pnND/6ZzQ/+mc0L/pXJC/6RxQf+jckD/onFA/6JxQf+gb0D/oG8//59uPv+ebT3/nWw+/5lm - O/+WYTf/lmE3/5hiOP+WYTf/lWE3/5ViOP+YYjb/f1k5/5qZmf+npqb/paOj/6KeoPvk4+P7//////7+ - /v/+/v7//////8XFxcEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu4uJfJyMn/pJ2Y/4pPL/+bWDX/mlk1/5pa - Nv+bWjb/nVs3/51bOP+dXDn/nVw5/59dOf+gXTr/oV46/6FeOv+jXzv/o186/6ZkP/+rbEX/rnNK/7B2 - TP+yek3/tH9R/7eGVf/Ak2D/xp9o/8agaf/DnGT/wZhf/8KYX/+1hFL/r3pL/7B7TP+vekv/r3pK/695 - Sv+veUr/rnhJ/654Sf+ueEj/rXdI/612R/+tdkb/rXZG/6x1Rf+sdUX/rHVF/6t0RP+rc0T/q3NE/6px - Q/+qc0P/qnBB/6hvQf+0g0//vI9W/7eIT/+1hEz/s4JK/7B9SP+ve0b/rnhE/611Qv+ueUT/sn1H/7B7 - Rf+veUP/rnhC/613Qv+sdUL/rHVB/6t0QP+rdkP/q3dG/6p2Rf+odUT/qHVE/6d0Q/+mc0P/pXND/6Rz - Qv+kc0L/o3JC/6NxQv+icUL/onBB/6BvQP+fbkD/nm5A/5tqPf+YYzn/mGI4/5ZjOf+WYzn/lmM5/5pl - Of+GWzX/kI6K/6moqf+mpKT/nZub/NPT0/n//////v7+//7+/v//////19fX4FVVVQkAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAu7u7acfFxf+ysLD/hVU3/5taNf+aWjb/m1o3/5xbOP+cWzn/nVw5/55dOf+fXTr/n146/6Be - O/+hXzv/o2A8/6NgPP+kYDz/p2VA/6ttRv+udUz/sHdN/7N7T/+1f1L/t4ZW/7uLWv/AlGL/xp9o/8Se - Z//CmWH/wZdf/72RW/+ye03/s3tN/7J7Tf+we0z/sHtL/7J6S/+wekv/r3lK/695Sf+veUn/r3hJ/694 - SP+ud0f/rXZG/612Rv+tdkb/rXZG/611Rf+sdET/rHRE/6x0RP+rc0P/q3ND/6hvQv+yfkz/u45T/7eH - T/+1hEz/s4FK/7J+SP+ve0b/rnhE/6x1Qv+td0T/snxG/7J8Rv+wekX/r3lD/653Q/+ud0P/rHVC/6x1 - Qf+seEb/q3dH/6t3Rv+rd0b/qHVE/6h1RP+ndUT/pnVD/6V0Q/+lc0P/pXND/6RyQ/+kckP/onFC/6Bw - Qv+gb0H/n29B/5xsQP+YZTr/mGQ6/5hkOv+ZZTr/mmY6/4xdM/+MhHz/qamr/6akpP+enJz+x8bG+P// - ///+/v7//v7+///////j4+P2eHh4IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1tbU+xcTD/76/wv+FX0b/mlkz/5pb - N/+bXDn/nFw5/51cOf+eXTr/n147/59eO/+gXzv/oV88/6FgPf+jYT7/o2E+/6RhPv+mZkH/rG5H/693 - Tf+yeU//tH1R/7aCVP+5h1f/uolZ/7mIWP/DmmX/xp1o/8OaZP/Bl1//wpdg/7aFVP+zfE3/sn1O/7J9 - Tv+wfE3/sHtM/7B7S/+we0v/r3pK/696Sv+vekr/r3lK/695Sf+veEj/rndH/653R/+ud0f/rnZG/651 - Rf+tdUX/rXVF/611Rf+tdUX/rHRE/6pwQv+wekn/uopS/7eIT/+1g0z/s4FK/7J9R/+wfEb/rnlE/612 - RP+tdUP/sHtG/7J9R/+we0X/sHlE/694RP+ud0P/rXZC/614RP+teUj/rHhH/6x4R/+rd0b/qndF/6h3 - Rf+od0X/p3ZE/6Z1RP+mdUT/pnRF/6VzRP+jc0T/onJD/6JyQ/+gcUL/n3FC/51vQf+aaT3/mWU7/5lm - O/+aZzz/k2A2/4R2av+rq6z/pqSk/6Gfn/+6ubn4//////7+/v/+/v7///////T09P+Kioo/AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAKqqqhvBv7/wyMnM/4ttW/+XVzL/ml05/5pdOf+cXTr/nl46/55eO/+fXzz/n2A9/6Bg - Pf+iYT7/o2E//6NiP/+kYz//pWI//6dnQ/+sb0n/sHhO/7J7UP+0flH/toNV/7qIV/+6iFn/toRV/7yO - Xf/Em2b/xJxn/8KYYv/ClWD/vZBd/7J+T/+zfk//sn5P/7J9T/+yfU3/sn1N/7J9Tf+wfEz/r3tL/697 - S/+vekr/r3pK/695Sf+ueUn/rnlJ/694SP+veEj/rndH/653R/+vd0b/r3dG/652Rf+tdUX/rXVF/6tx - Q/+veUj/t4dQ/7eHUP+1g0z/soBJ/7J+SP+wfEf/r3lG/653Rf+sdUP/r3lF/7J9R/+yfEf/sHpG/7B5 - Rf+ueUT/rnhD/656R/+uekn/rXlI/615SP+seEf/q3lH/6p4Rv+od0X/qHdG/6h2Rv+odUb/pnVG/6V1 - Rv+kdEX/pHNF/6NzRP+ickP/onJD/59xQ/+baz//mmc9/5toPv+ZZDn/hW9b/6eoqv+mpKT/pKGi/66t - rfj39/f+/v7+//z8/P/+/v7/+vr6/6Ojo2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVVVVA8DAwNDNztD/lYJ1/5JU - Mf+bXTr/nF46/5xeO/+cXzz/nl89/6BgPf+gYT7/omE//6NiP/+jYj//pGRA/6RkQf+lZEH/p2hE/6xw - Sv+veVD/s3xS/7R/Uv+2hFX/u4lZ/7qHWf+3hlb/t4dY/76SYf/Em2b/xJpm/8KVYv/ClWH/toVV/7N/ - UP+0f1D/tIBR/7N/UP+zfk7/s35O/7N9Tv+yfU3/sH1M/7B8S/+we0v/sHtL/696Sv+vekr/r3pK/696 - Sf+veUn/r3hI/654SP+veEf/r3hH/693Rv+udkb/rnZG/610Rf+udkb/toRP/7eHUP+1g0z/s4FK/7N+ - SP+wfEf/r3lG/653Rf+tdUP/rnVD/7B8R/+yfUf/sHxH/697Rv+vekX/rnpG/7B8S/+ve0r/rntK/617 - Sf+se0j/q3lH/6t5R/+qeEf/qnhI/6p3SP+nd0j/pndH/6Z2R/+ldUb/pXVG/6V1Rv+kdEX/pHRE/6Jz - RP+dbUH/nGk//51pPP+CZ07/o6Sm/6alpP+lo6P/pqWk+u7u7vz//////Pz8//z8/P//////q6uriQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAwr+/p87Oz/+kmZL/jVMy/5teOv+bXjv/nF48/55fPf+eYT7/n2E+/6Bh - Pv+iYj//pGRA/6RkQf+lZUP/pmZC/6ZmQ/+naUX/rHFL/7B6UP+zfVL/tIBU/7eEVv+7iVv/uYZY/7mG - V/+3h1j/uYha/8KXZP/Gm2b/w5lk/8OXYv+9j1z/tIBS/7WCUv+1gFH/tIBR/7V/UP+1gFD/tH5P/7N+ - T/+zfk3/sn5N/7N9Tf+zfEz/snxM/7B7S/+we0v/sHtL/7B7S/+wekr/r3lJ/695SP+veUj/r3lI/654 - SP+ud0f/r3dH/651Rv+udkb/tYJN/7mHUP+1g0z/tIFK/7N+SP+yfEj/sHpH/694Rv+udkT/rXRD/694 - Rf+zfkj/sn1H/7B8R/+ve0b/sH1J/7J+TP+wfUv/rnxL/658Sv+te0n/rXtJ/6x6Sf+seUn/q3lK/6h4 - Sf+oeEn/qHhJ/6d3SP+nd0j/p3ZI/6Z2R/+mdkf/pXVG/6R0Rf+fcET/n20//4hmRv+enZ//qKan/6ak - pP+in6D84+Pj+//////8/Pz//Pz8//////++vr6xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+vrx6zsvN/7Ou - rP+JVzn/nF46/5tePP+cYD3/nWE+/59hPv+fYj//oGNA/6BkQf+iZEL/pGVD/6VmRP+mZ0T/pmdE/6hq - Rv+sdEz/sntR/7J9VP+1gFX/t4ZX/7qJWv+3hVj/uYdY/7qJWv+5h1j/vItc/8OZZf/EmmX/w5hk/8KX - Yv+3hlb/toNT/7aDU/+1glL/toJS/7aAUf+1gFD/tH9Q/7R/T/+0f07/tH5O/7N9Tf+zfUz/sn1M/7J8 - TP+yfEz/snxM/7J7S/+ye0v/sntK/7B6Sf+wekn/sHpJ/695Sf+veEj/r3hI/693R/+vdkf/tH5L/7eG - T/+1hE3/tIFK/7R+Sf+yfEn/sHtI/7B5Rv+ud0X/rXVE/651RP+yekf/s35I/7J9R/+wfEf/s39M/7J/ - Tf+wfkz/sH5M/699S/+vfUv/rnxK/657S/+tekr/q3pK/6t6Sv+rekr/qnlJ/6p5Sf+oeEn/qHhJ/6h4 - Sf+nd0n/pndH/6R2R/+kdEX/i2Q//5eUk/+pqKj/pqWk/56dnPzU1NT5//////z8/P/8/Pz//////8zM - zNEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMC5uU3Mysr/v7/C/4lgRf+cXjn/m189/5xhPf+dYT7/nmI//59j - QP+iZEL/o2RC/6NlQ/+kZkP/pWdE/6VoRP+maEX/p2tG/6x0Tf+wfFL/s39U/7WCVv+5hlj/uolb/7aE - WP+6h1n/uolb/7qJWv+5hlf/vY5f/8SaZf/EmmX/w5lk/72QXf+3g1T/t4RU/7eEU/+3hFP/t4NT/7aC - Uv+1gFH/tYBQ/7V/T/+1f0//tX9P/7R/Tv+0fk3/tH1M/7N9TP+zfUz/s3xM/7N8TP+zfEv/snxL/7J8 - S/+ye0r/sHpK/7B6Sv+vekn/r3lJ/694SP+vd0f/snxK/7eFT/+2hE3/tIFL/7R+Sv+zfUr/sHtI/7B6 - R/+veEb/rnVF/65yRP+wd0b/s31I/7N+SP+zf0r/tIJO/7SCTv+zgU3/sn9M/7J/TP+wfkz/sH1M/658 - TP+se0v/rHtL/6x7S/+se0v/q3pK/6t6Sv+rekr/q3pK/6l6Sv+nekn/pnlJ/6h5Sf+YbUH/k4yG/6mp - q/+npaX/n52d/sfHx/n/////+/v7//v7+///////3d3d7V5eXhMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt7GxJ8fF - xfjKzc//jGxY/5ldOP+bYT3/nWE+/55iP/+eY0D/n2RB/6BlQ/+iZkP/o2dE/6RnRP+maEX/pmlG/6dp - Rv+oa0j/rXVO/7B9U/+zf1X/tINY/7mIWv+6iFv/t4RY/7qHWv+6iVv/u4pb/7qJWf+5hlj/wJJi/8Sa - Zv/EmmX/wphj/7qHVv+5hFX/uYRV/7eFVP+2hFT/t4RT/7aDUv+1g1L/tYJR/7aAUP+1gFD/tIBP/7SA - Tv+1f07/tX9O/7V/Tv+0fk3/tH1M/7R9TP+zfUz/s31M/7J8TP+ye0v/sntL/7J7S/+we0v/sHpK/7B6 - Sv+veUj/sHtK/7aETv+2hU7/tIFN/7R+S/+zfUr/sntI/7J6R/+weUb/rndF/650Rf+udET/sHpH/7N/ - Sf+0g07/tYNP/7WDT/+0gk7/s4FN/7OBTf+yf0z/r4BM/659Tf+ufU3/rn1M/659TP+tfEz/rXxM/618 - TP+se0v/q3tL/6p8S/+pe0r/qn1K/55yQv+NgXb/q6ms/6elpf+joKD/urm5+fz8/P/7+/v/+/v7//// - ///q6ur9hYWFMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZmZkKxsXF3dDT1f+Tfm//lFo2/5tiPf+cYz//nWNA/55j - Qf+fZEL/oGZD/6JnRP+iZ0T/o2hF/6RpRv+lakf/pmpH/6htSf+td0//sH1V/7OAVv+1hFn/uYhb/7eG - Wv+2hFj/uYdc/7qKXP+7ilv/u4pb/7qHWP+6h1r/wpVk/8abZv/Gm2b/vY9c/7mFVf+3hlb/t4ZV/7eG - Vf+3hVX/toRT/7aEU/+2hFP/toNS/7aDUv+1g1H/tIJQ/7WAT/+1gE//tYBP/7V/Tv+1fk3/tX5N/7R+ - TP+0fkz/tH5M/7R9TP+zfEz/s3xM/7N8TP+zfEz/s3xM/7J7Sv+wekr/sHpK/7WCTv+3hE//tYJO/7R/ - TP+zfUr/snxJ/7J7SP+weUf/r3dG/691Rf+uckT/r3ZF/7N9Sv+3hVH/t4VQ/7WDT/+1g0//tIJO/7OC - Tv+ygk3/sIFO/6+ATv+vfk7/r35O/69+Tv+ufU3/r31N/659Tf+sfU3/rH1M/6t/Tf+rfUz/p3hG/49+ - av+oqa3/p6Wl/6Sjov+wrq/59/f3/vz8/P/7+/v//Pz8//b29v+ZmZlQAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AADGxsa31NTW/5+Ti/+PWDX/nGI+/5tjP/+cZEH/nmVC/59mQv+gZkP/o2dE/6NoRf+kaEX/pWlH/6Zq - R/+ma0j/qG1J/6x3UP+wflb/soFW/7WEWf+5iV3/toVa/7aEWf+5iFz/uopd/7uLXP+7ilz/u4lb/7qG - Wf+8iV3/w5hl/8abZ//DmGT/u4hY/7qHV/+5h1b/uYZW/7mGVv+5hlX/t4VU/7eFVP+2hFP/t4RS/7aD - Uv+1g1H/tYNR/7WCUP+1glD/tYJQ/7V/Tv+1f07/tYBO/7R/Tf+0f03/tX5N/7V+Tf+0fUz/tH1N/7R9 - TP+0fUz/s3xM/7J7S/+ye0v/snpL/7V/Tf+3hE//tYNO/7V/TP+1f0z/s31K/7J7SP+yeUf/sHhH/693 - Rv+udUX/rXRE/7B6Sv+2g1H/uYdS/7eFUf+1hFD/tIRQ/7ODT/+ygk//soFQ/7KBUP+ygVD/soFQ/7CA - T/+wgE//r4FP/62BT/+tgE7/rYBO/62ATv+tfUr/jXdd/6anqv+npaX/pqSk/6impvru7u79/Pz8//r6 - +v/7+/v/+/v7/6qqqngAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMbExIvU0tT/r6mm/4lYOf+dYz7/nGNA/5xk - Qf+eZkL/nmZD/59mQ/+iaET/o2lG/6RpRv+makf/pmtI/6drSP+obkr/rHhR/7B/Vv+zglj/tYVa/7mJ - Xf+1g1n/toVa/7mJXP+7i17/vIte/7yLXf+7il3/u4hb/7qFWf++jF//xJpm/8acaP++kF7/u4hY/7qI - WP+6h1b/uodW/7uIV/+6h1b/uYZV/7mFVP+5hVP/uYRS/7eEU/+3hFL/toNR/7aDUf+2g1H/tYBP/7WA - T/+1gk//tIBO/7SATv+0f07/tX5O/7V/Tv+1fk3/tX5O/7V+Tf+1fUz/tH1M/7R9TP+zfEz/s3pM/7R+ - Tf+3hE//toNO/7aATf+1fkv/s31K/7N8Sf+zekn/snlI/7B4Rv+udkX/rnVF/652R/+ye0z/toVS/7eH - U/+2hlH/tYVR/7SFUf+0g1H/tINS/7SCUv+zg1L/s4JR/7KBUP+wglH/sINQ/6+CUP+vglD/roFP/7KC - Tf+WeFf/oaGk/6empv+npaX/o6Ki++Li4vv+/v7/+vr6//r6+v/+/v7/tLS0nQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAw8DAXdLQ0P++vr7/h11B/51jPv+cY0D/nWVC/51lQv+eZkP/n2hE/6BpRf+iaUb/ompG/6Rs - R/+lbUn/pm1J/6dvS/+teFH/sX9X/7SCWP+1hlv/t4hd/7SCWP+3hlr/uYld/7uLXv+8i1//vIte/7uL - Xf+8iVz/u4da/7qFWf/AkWH/x5xo/8OYZf+8iln/vIpZ/7yJWP+8iVj/u4hX/7uIV/+6h1b/uodW/7qG - Vf+6hlT/uYVU/7eEU/+5hVP/t4RS/7eEUv+3g1H/t4NR/7aDUP+2glD/tYJP/7WAT/+1gE//tYBP/7WA - T/+1gE//tX9P/7V/Tf+1f03/tX5N/7V9Tv+1fU3/tHxM/7R9Tf+3g0//toRP/7aCTf+1f0z/tH5L/7N9 - Sv+ze0r/snpJ/7J5R/+vd0b/r3hH/651R/+udUj/snxO/7aFU/+3iFT/t4ZT/7aGUv+1hVP/tYRT/7WE - U/+1hFP/tINS/7OEUv+yhFL/soRS/7KEUv+wg1H/tIVQ/5h1T/+dnJv/qKio/6impv+fnZ381NTU+v// - ///6+vr/+vr6///////ExMTCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6uro0zszM/c3M0P+KaFH/m2A7/5xk - Qf+dZUL/nWVC/55mQ/+faET/oGhF/6JpRf+iakb/pGxI/6VtSf+mbUr/p29L/6x5Uv+xf1f/soJZ/7SG - W/+1hlv/s4JY/7aFWv+5iV3/u4te/7uNX/+8i1//vIte/7uKXv+8iFz/u4da/7uGWf/ClGT/xpxo/8CQ - X/+9jVr/vYta/72KWP+8iVj/vIhX/7yJWP+8iFf/vIdW/7uHVf+6hlX/uoZV/7qFVP+6hlT/uYVT/7mE - Uv+5hFL/t4RR/7eEUP+3hFH/toNQ/7aCUf+2glD/toJR/7aCUP+2glD/tYBP/7WATv+1gE7/tX9P/7Z+ - T/+2fk7/tX1O/7V9Tf+3gk//t4RP/7aCTv+2gE3/tX9M/7N9S/+0fEv/s3pJ/7J5SP+yeUj/snlJ/7B3 - Sf+uc0f/r3VJ/7N9T/+3hlX/uYhV/7eHVP+3hlT/toVV/7aFVP+1hVT/tIVU/7SGVP+zhVP/s4VT/7OF - U/+1hlP/pHxO/5eUkP+rqav/qKam/6Genv7IyMj5/v7+//n5+f/6+vr//v7+/9PT0+FmZmYKAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAKGhoRPNzMzp1NbY/5F6aP+WXDj/m2RB/5xkQf+dZUL/nmdD/59nRP+gaEX/omlF/6Nr - R/+ka0j/pGxJ/6ZtSv+nb0v/q3lS/69/V/+xgln/tIZb/7SEWf+zgFj/toVa/7eJXP+7i17/u4tf/7yL - X/+8i17/u4te/7yJXP+8iFv/u4ZZ/7uHW//EmWf/w5dk/8CPXf++jlv/vY1a/72LWf+8ilj/vIpY/7yK - WP+8iVj/vIhX/7uHVv+7h1X/u4dV/7uHVP+7h1T/uoVT/7qFU/+5hVP/uYVS/7eEUf+5hFL/t4NR/7mE - Uf+3g1H/t4NR/7eDUf+3g1D/toJQ/7aCT/+1glD/toBQ/7V/T/+2f0//t39P/7Z+T/+2gFD/t4VQ/7aD - Tv+2gk7/tX9N/7R+TP+0fEv/tHxK/7N6Sf+ze0n/s3pK/7J4Sv+wd0n/r3NH/692Sv+zfVD/t4ZV/7qJ - V/+6iFf/uYdW/7eHVv+1iFX/tYdV/7WHVf+1h1X/tYdV/7aIVf+qfk3/l42D/6urrP+npqb/o6Gh/7q6 - uvn7+/v/+fn5//n5+f/8/Pz/39/f93R0dCEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcvIyMbZ2tv/no6E/5FZ - N/+bZED/m2RB/51lQv+eZkP/n2dE/6BoRf+iakb/o2tH/6RrSP+kbEn/pW1K/6ZwS/+reVP/roBX/7GC - Wf+0hlv/soBY/7KAV/+1hVr/t4hc/7qKXv+7i1//vI1f/7yLX/+8i17/u4pd/7yIW/+8iFv/uoZZ/7yK - XP/EmGb/wpFg/8GQXv/Aj1z/vo5a/72NWv+8i1n/vY1Z/7yLWf+9ilj/vIlX/7uJV/+7iVb/u4hV/7uH - VP+7h1T/u4ZU/7uGVP+6hlP/uoZT/7mFU/+5hFL/uYRS/7mEU/+5hFL/uYRS/7mEUv+3g1H/t4NR/7eD - Uv+2g1H/toJR/7aCUf+2gFD/toBP/7Z+T/+3f0//uYVR/7eET/+2gk7/toBN/7V+Tf+0fUz/tHxL/7V8 - Sv+0fEv/s3pL/7N5S/+yeEr/sHdK/691SP+vdkr/s3xP/7eFVf+7ilj/uYpX/7eJV/+3iVf/t4lX/7eJ - V/+2iFb/t4lW/7SFUP+Vhnb/qqmt/6impv+mpKT/sa6v+fT09P76+vr/+fn5//v7+//w8PD/h4eHQAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAy8fJnNrZ2v+tpaD/jFg5/5xkQP+bZEH/nWVC/55mQ/+fZ0T/n2hE/6Bp - Rv+jakf/o2tI/6RsSf+kbUr/pnBL/6p5U/+tflf/sYJY/7OEW/+vflf/soBX/7SEWv+3iFz/uope/7uL - X/+7jV//vYtf/7yLXv+7il3/vIlc/7yIW/+7h1r/uoVY/76MXv/Ck2L/wpBg/8GQXv/Aj1z/vo5b/76M - Wv+9jVr/vo1a/72NWf+8i1j/vIpY/7yJV/+7ilb/vIpW/7yJVf+8iFb/u4dV/7uHVP+7h1T/u4dU/7uF - VP+6hVT/uoVU/7qFVP+6hVT/uoVT/7qFUv+6hVL/uYRT/7mEU/+5hFL/t4NS/7eDUv+2g1H/t4FR/7eA - UP+3f1D/uYNR/7mFUP+3g0//t4BO/7Z/Tf+1fk3/tH1L/7V9S/+1fUz/tHtM/7N6S/+zeUv/snlL/7J4 - Sv+wdEj/r3VJ/7N7Tv+2hFX/uYpY/7qNWP+6jFj/uYpX/7mKV/+5ilf/uYhT/5mDa/+nqKz/qKam/6el - pf+ppqf67e3t/fr6+v/5+fn/+vr6//X19f+dnZ1lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMxcVu19bX/727 - u/+IW0D/nGNA/5tkQv+cZUL/nGZC/51nRP+fZ0T/oGlF/6BqRv+ia0f/pGxJ/6RsSf+mcEv/qnlT/619 - V/+vgVj/soJZ/658Vf+xgVf/s4Na/7aGXP+5iV3/uYxe/7uLX/+8i1//u4te/7uKXf+7iVz/vIhb/7uI - Wv+7h1n/vIdY/72KXP/BkGD/w5Jg/8GRXv/Aj1z/wI9b/8CMWv++jFr/vo1a/72NWf+9i1n/vYtZ/72L - WP+9ilf/vIpX/7yJV/+8iFf/u4hW/7uIVf+7iFX/u4dV/7uHVv+7hlT/u4ZU/7uGVf+7hlX/u4ZU/7uG - U/+6hVT/uoVU/7qFU/+6hVP/uYRT/7mEU/+5hFL/t4NS/7eBUf+3f1D/uYNS/7mGUf+3hE//t4JO/7eA - Tv+1f03/tX9M/7V+TP+1fk3/tHxM/7N7TP+zekv/snpL/7J5S/+yeEr/sHZJ/691Sf+yeU3/tYJT/7qK - WP+7jlr/vI5a/7uNWf+9jVf/mn9h/6SlqP+op6f/qKam/6Ojo/vg4uL8+/v7//f39//39/f/+/v7/6qq - qooAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMbCwkPW1NT/ysvO/4dkTP+bYD7/m2NC/5xkQv+cZUP/nWZE/51n - RP+faUX/oGpG/6JrR/+ja0j/pGxJ/6VxS/+peVL/rH1W/6+BWP+vf1f/rXtU/69/Vv+zg1n/tYVb/7eI - XP+5il3/uYxe/7uLXv+7i17/u4pd/7qJW/+7iFv/u4da/7uHWf+8h1n/u4VW/7uEV//DkmD/wpJf/8KR - Xv/Bj1v/wI5a/8COWv++jlr/vo5a/76NWv++jVr/votY/76LWP++ilj/vYlY/72KWP+8iVf/vIlX/7uJ - V/+7iFf/vIdX/7yIVv+7iFb/u4dX/7uGVv+7hlX/vIdU/7uGVf+7hlX/u4ZU/7uGVf+6hVT/uoVT/7qF - U/+5hFP/uYRT/7eDUv+3gVH/uYFS/7qGUv+5hVH/uYNP/7eATv+3gE7/tn9N/7Z/Tf+1fk3/tX1O/7R8 - Tf+ze0z/s3tM/7N6S/+zeUv/snlL/7J2Sv+wdEn/sHhL/7V/Uv+6iVj/vI9b/8GQW/+jglv/oaCh/6uo - qP+opqb/oZ6f/dPU0/r8/Pz/9/f3//f39//8/Pz/urq6sQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAu7u7HtLP - z/PW2dv/jHBf/5ZcO/+aYkH/m2NC/5xkQ/+cZkT/nWdE/55nRf+faUb/oGtG/6JrR/+ka0j/pW9L/6l5 - Uv+sfFb/roBX/619Vf+se1T/rn5W/7GCWP+0hVr/todc/7mJXP+5il3/uote/7uKXv+7il3/uolc/7qI - W/+7iFr/vIdZ/7yHWP+8iFn/tnpP/7uEV//Dk2H/wpJg/8KRXv/Cj1v/wY9b/8CPW//Ajlr/wI5a/8CO - Wv++jln/vo1Z/76NWf++i1j/vopY/72KWP+9ilj/vYpY/7yJWP+8iFf/vIhX/7yIV/+8iFf/vIhX/7yI - Vv+8iFb/vIdW/7yIV/+8h1b/vIdW/7yHVf+7hlX/u4ZU/7qFVP+6hVT/uoVT/7mEU/+3g1L/t4NS/7qF - U/+6hlL/uYNQ/7mBT/+3gE7/t4JO/7eATv+2fk3/tX1O/7Z+T/+1fU7/tHxN/7R7TP+ze0z/tHpL/7N5 - S/+yeEr/snZK/7B3Sv+zfE//vIdX/6eBV/+empn/q6mr/6inp/+ioaD+yMjI+fv8/P/39/f/9/f3//z8 - /P/IyMjRAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZmZkF0NDQ1Nzd4P+XhHn/kVg3/5piQf+bY0L/m2NC/5xl - Q/+dZkT/nmZF/59oRf+gaUb/ompH/6JrR/+kb0r/p3hS/6p8VP+tflf/q3pT/6t6U/+tfVb/sYFX/7SE - Wv+1h1v/t4hc/7eJXP+6il3/uopd/7qKXP+6iVv/uohb/7uIWv+8h1n/u4dY/7yIWf+6gVT/s3RL/7yH - WP/Dk2D/wpNe/8KRXf/CkFz/wZBb/8CPW//Ajlr/wI5a/8COWv/Ajln/wIxZ/8CMWf/AjFn/vYtY/72L - WP+9ilj/vYlY/72KV/+9iVj/vIlY/72JWP+9iVj/vYlX/7yJWP+8iFf/vYlX/7yIV/+8iFf/vIhW/7yH - Vv+8h1b/vIdV/7uGVf+7hlX/uoVU/7qFU/+6hVT/uYRT/7qEU/+6hlP/uoRR/7mDUP+5gU//uYNP/7eC - T/+3f0//t39Q/7Z+T/+2fk//tX1O/7V9Tv+0fE3/s3tM/7R7TP+0ekz/tHlL/7J3Sv+0dkr/p3BH/5yS - i/+rq63/qKen/6Wjo/+6urr5+fn5//b29v/29vb/+vr6/9jY2O5eXl4TAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AADQzc2t393f/6edlv+JVTf/mmJB/5piQf+bY0L/m2NC/5xlRP+dZkX/nmdF/59nRv+iaUb/ompG/6Nw - Sv+nd1H/qXpT/6t8Vf+pd1H/qnpT/6x8Vf+vf1b/soNZ/7SFWv+2h1v/tohb/7mJXP+6iVz/uopc/7qI - W/+6iFr/uYhZ/7yHWf+7hlj/u4ZY/7yHV/+1eEz/tHZL/72HWP/Ek2D/w5Je/8ORXf/CkVz/wY9b/8GP - W//Bj1v/wI9a/8CPWf/Ajln/wYxa/8CMWf++jVj/vo1Z/72LWf+9ilj/vYpY/72KWP+9ilj/vYpY/72K - V/+9iVf/vYlY/72JWP+9iVj/vYlY/72JWP+9iVj/vIlX/72IV/+9iFb/vIhW/7yHVv+7hlX/u4ZV/7qF - Vf+6hVT/uoVU/7qEVP+7hlT/uoZS/7mEUf+6g1D/uoRQ/7mDT/+5gFD/uYBR/7mAUf+3f1D/tn5P/7Z+ - T/+1fU7/tX1N/7V8Tf+1fE3/tXtM/7V7Tf+tckX/lod7/6ysrv+pp6f/p6Wl/7Gwr/ny8vL+9/f3//b2 - 9v/6+vr/5eXl/YKCgjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM3Ly4Dc3Nz/urWz/4ZWOv+aYED/mWFB/5pi - Qf+bY0L/nGRD/51lRP+dZkX/n2dF/6BnRv+gaEb/o25K/6Z3UP+peVP/qnpT/6d2UP+peFL/q3tU/659 - Vf+xgVf/soRZ/7SGWf+2h1r/t4hb/7eIW/+5iVv/uohb/7mIWv+3h1n/u4ZY/7uGWP+6hVf/vIdX/7d9 - UP+0dUr/tXZL/72GV//Ek1//w5Je/8KSXf/CkVz/wY9b/8GPW//Bj1r/wY9a/8GOWv/Bjlr/wIxZ/76N - Wf/Ajlj/vo1Y/76LWP++i1j/votY/76LWP+9ilj/votX/76KWP++ilf/vopX/76KWP+9ilj/vopY/72J - WP+9iVj/vYlY/72JV/+9iFf/vYhX/72IV/+8h1b/u4ZV/7uGVf+7hlX/uoVU/7qFVP+7hlX/u4dU/7qF - Uv+6hVD/uoVR/7qDUP+6gVH/uoFS/7mAUf+5gFH/t39Q/7d/UP+2fk//tn5P/7Z+T/+1fU7/tn1O/7R4 - R/+bhHD/qqyv/6mnp/+opqb/qqmp++rq6v35+fn/9vb2//f39//x8fH/jo6OUQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAysrKUtrZ2f/Jycr/hV5E/5lePP+YYED/mWFB/5piQf+bY0L/nGRD/51lRP+eZkX/nmdG/59o - Rv+ibkr/pXZP/6d4Uf+neFH/pnRP/6d3Uf+qeVL/rHxU/6+AVf+xglf/s4RY/7WGWf+2h1r/t4da/7eI - Wv+5iFr/uYdZ/7eHWf+5hlj/uoVY/7qFV/+7h1f/uoJU/7V2S/+1dkv/tXZL/72GV//Dk1//wpJd/8OR - Xf/DkVz/wpBc/8KPW//Bj1r/wo9b/8GPWv/Bjlr/wI5Z/8COWf/Ajln/wIxZ/8CMWf/AjFn/votY/76L - WP++i1f/votX/76LV/++i1f/votX/76LWP++i1j/votX/76LWP+9ilj/vYpY/76JV/++iVf/volX/72I - V/+9iFb/vIdW/7yHVv+8h1b/u4ZV/7uGVf+7hlX/vIhV/7uGU/+6hlH/u4ZR/7qEUf+7glL/uoFS/7qB - Uv+6gVL/uYBR/7mAUf+5gFH/t39Q/7Z+T/+2fk//uHxL/5l7Yf+nqa3/qaen/6inp/+jo6P839/f/Pn5 - +f/19fX/9fX1//b29v+mpqZ5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADEvr4r1tPT+tbZ2/+Kalb/lVs5/5hf - P/+YYED/mWFB/5piQf+bY0L/nGRD/51lQ/+dZUX/nmZF/6BtSf+jdE3/pndQ/6R0Tv+lck7/pXVQ/6l4 - Uf+relP/rX5V/6+BVv+yglj/s4RY/7WGWf+2h1n/toda/7mHWf+2hlj/t4ZY/7mGV/+6hFf/uYRW/7qF - Vv+7hlb/tXhM/7R2S/+1dkv/tXVK/7yFVv/Dk17/wpJe/8ORXf/DkVz/w49b/8KPW//Cj1v/wo9b/8GP - Wv/Ajln/wI5Z/8CMWf/AjFn/wIxZ/8CMWf/AjFn/wIxZ/8CMWP/AjFj/votX/76LV//AjFj/wIxX/76L - V/++i1f/votX/76LWP+9ilf/vopY/76JWP++iVf/volX/72IV/+9iFf/vYhX/72IV/+8h1b/vIdW/7yH - Vf+7hlX/vIhW/7yIVP+7iFL/u4ZR/7uEUf+7hFP/u4JT/7uBU/+6gVL/uoFS/7mAUf+5gFH/uYBR/7mA - Uf+6f07/pH1a/6Wlp/+pqKf/qaen/6KgoP3S09P6+fn6//X19f/19fX/+fn5/7Kysp4AAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAKqqqgzT0tLh3+Di/5R9bv+ITSz/kVc2/5RaOP+WXDr/mF08/5tgPv+cY0D/nWRC/51k - Q/+fZkT/oG1I/6NzTP+ldU7/o3JL/6RyTP+ldE7/p3dP/6p5Uf+sfFP/rn5V/6+BVv+yg1b/s4RW/7SF - WP+1hlj/toZY/7aGWP+3hlf/toVW/7eEVv+5hFX/uYRV/7uGVv+2fE//tHVK/7V2S/+2dkv/tnVL/7uC - Vf/Dkl7/w5Ne/8OSXf/DkFz/w5Bc/8KPW//Dj1v/wY9a/8GPWv/Bj1r/wI5Z/8CMWf/AjFn/wIxZ/8CM - Wf/AjFn/wIxY/8CMWP/AjFj/wIxY/8CMWP/AjFj/votX/76LV/++i1f/wItY/76LV/++i1j/vopY/76K - V/++ilj/volX/76JVv++iVf/vYhX/72IV/+8h1f/vIdW/7yHVv+8h1b/vIdW/72JVv+9ilT/u4dS/7qF - Uv+8hFP/vINU/7uEVP+7glP/uoFS/7uBU/+6gVL/uoFS/7yBUP+leFH/oZ+d/6urq/+pqKj/o6Ki/sfG - xvr5+fn/9fX1//X19f/6+vr/xMTEwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANLS0rzd3d3/v7u5/5eE - ev+ZgXL/lXlm/4ttWf+OalP/jWVL/4deQ/+NXUH/j10//45aOv+VYz//nGtD/5xpQ/+eaEP/omxF/6Rw - SP+ldEr/qnhO/6x8Uf+ufVL/sH9U/7KCVv+zg1b/tIRX/7WFV/+2hVf/toVW/7aFVv+2hFb/toNV/7eD - Vf+3g1X/uoVW/7mBUv+zdEr/tXZL/7V2S/+2dkv/tXVK/7qAUv/DkVz/xJNe/8ORXP/DkVz/w5Bc/8OQ - XP/CkFv/wY9a/8GPWv/Bjlr/wY5a/8GOWv/AjFn/wIxZ/8CMWf/AjFj/wIxY/8CMWP/AjFj/wIxY/8CM - WP/AjFj/wIxY/8CMWP++i1f/wIxY/8CLWP++i1j/votX/76KV//Ailf/volX/76JV/++iVj/vohX/72I - V/+9iFf/vYhX/7yHVv+8h1b/vIdW/72IVv+9ilX/vIhT/7uGUv+7hVT/vIVV/7yDVP+7hFT/u4RT/7uC - U/+6gVL/vIJS/697T/+fmJL/q6ut/6moqP+mpaX/u7q6+ff39//19fX/9fX1//n5+f/R0dHhZmZmCgAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA0tDQktrZ1//d3d3/4uTm/+Dh4//b3eD/2tvd/9XW2P/Nzs//yMfI/8O/ - vv+4s7H/samk/6+imf+llov/n41//5+Idf+XfWj/k3Vf/5l3W/+WclT/lnBO/551T/+fc0z/oXNL/6h4 - Tf+re03/rnxO/7SAUP+1gFH/tYJR/7eDU/+3hFT/uYNT/7mBVP+7hVX/uoVU/7N3Sv+0dUr/tXZL/7Z2 - S/+2eEv/tXVK/7p9T//CjVv/xJNe/8SRXf/EkV3/w5Fc/8KQW//CkFv/wo9b/8GOWv/Bjlr/wY5a/8GO - Wv/Bjlr/wIxZ/8CMWP/AjFj/wIxY/8CMWP/AjFj/wIxY/8CMWP/AjFj/wIxY/8CMWP/AjFj/wIxY/8CL - WP/Ailj/wIpX/8CKV//Ailf/wIpX/8CKV/++iVf/volX/72IVv+9iFb/vYhX/72IVv+8h1b/vIdW/7yH - Vv++i1b/vIhU/7uGU/+7hlT/vIZV/7yFVf+8g1T/vINU/7uCU/+8g1T/s3xM/52Rhv+srK7/qaio/6em - pv+xsbH67+/v/vX19f/09PT/9/f3/9vb2/d0dHQhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADPz89a29nZ/9va - 2v/b2tr/29ra/9va2v/c2tr/3Nvb/93c3P/f3d3/393f/+Hg4P/g4OH/4ODi/+Dg4v/g4OL/3N3g/9fa - 3P/W19v/0NDS/8jIyf/FxMP/v7u5/7Svq/+0qqP/r6SY/6WWiP+nlIH/p494/5yDav+hgmP/pYFf/6B5 - VP+keFL/q3tQ/6h3Sv+ue0v/r3NG/61tQf+xb0P/tXJF/7Z0Rv+3dEb/t3VH/7t7TP/Ci1j/x5Ne/8eT - Xv/Ekl3/wpFb/8OQW//Cj1v/wo9a/8GOWv/Bjlr/wY5a/8GOWv/Bjln/wIxY/8CMWP/AjFj/wIxY/8CM - WP/AjFj/wIxY/8CMWP/AjFj/wIxY/8CMWP/Bi1j/wItY/8CLWP/Ai1f/wYtY/8CKV//Ailf/wIpX/8CK - V/++iVb/volW/76JVv+9iFb/vYhW/72IVv+9iFb/vIdX/72IVf++i1b/vYpU/7uHU/+7hlT/vIZV/72F - Vf+9hVX/vYVU/7yDVP+6f07/n4t5/6usr/+pqKj/qKen/6qqqvvp6en99fX1//T09P/29vb/6+vr/5mZ - mUEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKqqqgbQ0NBc1NLSgdbT05fW09Ot1tXVw9bU1NbX1tbm2NfX9NnY - 2P7b2dn/29nZ/9rZ2f/a2dn/2tnZ/9rX1//a19f/2dfZ/9rZ2f/a19n/2tra/9va2v/b2tv/3Nvc/9vc - 3f/a2tz/2trc/9fZ3P/U1dj/0dPW/8/Q1P/IyMr/wsLC/8K+vf+4tbH/saqk/7Sonv+tnZD/oo5//6iN - eP+khG3/nXpg/6Z7XP+ld1P/onBK/6t0S/+zf1L/t4dV/72LVv/BjFb/wItU/8KOVf/EjVb/w41W/8ON - V//Ej1j/w49Z/8KNWP/CjVj/wo1Z/8GMWP/BjFj/wIxY/8GMWP/BjFj/wYxY/8GLWP/BjFj/wYtY/8GL - WP/Bi1j/wYtY/8GLWP/Bi1j/wIpX/8CKV//Bilj/wIpX/8CKV//Ailf/volW/76JVv++iVb/vYhV/72I - Vv+9iFb/vYhW/72JVv+9ilX/vYpV/72IVP+8h1T/vYZV/72FVf+9hVX/vYVV/72BUP+fhGz/qquu/6mo - qP+pqKj/paWl+9/f3/z39/f/9PT0//X19f/x8fH/oKCgZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAmZmZBcPDwxG5ubkhxsbGMdDMzEbQ0NBc0NDQc9PT04zW09Oh1NPTuNbS - 0s3V09Pe1tTU7tbT0/rX1tb/19bW/9fV1f/W1dX/1dXV/9XU1P/V0tP/1NLT/9TS0//U0dH/09PT/9XS - 0//U0tT/1NLT/9TU1f/V1Nb/09TW/9PS1v/R1Nf/z9HV/8rN0P/Jy8//x8jK/76/wf+8urv/u7a0/7Cp - pf+wqKD/s6ea/6mci/+pl4L/r5h9/6iNcP+pi2j/sY1n/6yGXf+vhVn/tohY/7WGVP+3hVH/vYhS/72I - Uf++h1H/wopT/8OKVP/CilT/w4tV/8SMV//Di1f/wotX/8KLWP/Ci1j/wYtY/8GLV//Ailf/wIpX/8GL - WP/Ailf/wIpX/8CKV//Ailf/volW/76JVv++iVb/volW/76JVv++iVb/vYhW/76KV/++ilX/vopV/76K - Vf+9iFT/vYZV/72GVf++hVX/v4VS/6SCYf+mqKr/qaio/6moqP+ioqL90tLS+/f39//y8vL/8vLy//b2 - 9v+np6eLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIuLiwvMzMwZzMzMKMzMzDzNyclR0tLSZtHN - z3/QzMyX0M3NrdHNzcPPzs7Vz87O5s/OzvTQz8/+0tDQ/9LQ0P/Rz8//0c/P/9DOzv/Qzs7/z8zN/87M - zf/Oy8v/zMrK/8zKyv/Mysr/zMvL/8zKy//Ly8z/zcvM/83Lzv/Jysz/ycnM/8jJzP/Excr/wcPG/8HC - xf+9vL//trW3/7e0s/+0r6z/rKWf/6+lmf+un5H/pZSC/6uVfv+sk3f/pYhp/62KZv+xiWL/rINZ/7SF - WP+3h1b/tYNS/7uGUv++iFP/vYZR/7+IUv/DilP/w4pU/8KKVP/Di1X/w4tW/8GKVv/Bilb/wYpX/76J - Vv++iVb/volW/76JVv+9iFX/vYhW/8CLV/+9iVT/vYlU/76KVf+9iVX/vodV/76GVf/Bh1P/p31Y/6Wj - o/+rqan/q6io/6Siov7Gxsb69vb2//Ly8v/y8vL/9/f3/729vbMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJmZmQWqqqoSt7e3IMHB - wTHGxsZHyMXFXMzMzHPMysqLzMjJoczKyrjMzMzNy8nK3snHx+3JyMj6zMrK/8vKyv/Lycn/ysnJ/8rI - yP/JyMj/ycbH/8jHx//HxcX/x8TE/8XExP/Ew8P/xMLC/8TDw//Fw8P/w8PD/8PCw//Ew8X/wsLE/8HB - xP/BwsT/wMHE/7u9wP+5u77/uLq8/7O0tf+vrq7/s6+s/6ymov+nn5f/rqGV/6eYiP+jkH3/rZV7/6mN - cP+miGf/sYxn/66GX/+ug1j/t4dY/7aFVf+3hFH/vYdS/76HUf++hlH/v4dR/8GIUv/BiFL/wIhT/8OM - Vf/AilP/volT/8CLVf/AilX/vohU/8GIVP+ygVT/pJ+c/6ysrP+rqan/p6am/7y8vPr19fX/8vLy//Ly - 8v/39/f/x8fH0nh4eBEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AACLi4sLo6OjGbm5uSi/u7s8wMDAUcTExGfFxcV/xsTEl8bDxK3ExMTCxMLC1cLBwebCwcH0w8LC/sTD - w//EwsL/w8LC/8LBwf/CwcH/wb+//8G+vv+/vr7/v729/769vf+9vLz/vLy8/7y7u/+8urr/vLu7/7u7 - u/+7urv/u7q8/7u6vP+4urz/uLi8/7e4vP+2trv/srS4/7Kztv+wsrT/q6us/6unp/+sp6T/pZ6Z/6ac - kv+qnZD/opKB/6aQev+sk3j/pYhq/6qHZf+xi2T/rYRa/7OHWP+3h1b/tYRR/7mFUP+9iFH/voZQ/7Z9 - Sv+imI7/rK2u/6upqf+op6f/s7Gx+u/v7/709PT/8vLy//f39//W1tbvgICAKgAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAACZmZkFqqqqEq+vryCzs7Myvba2Rr+6uly8vLxzv729i767u6K+vr64vrm5zbu6 - ut67ubntu7q6+b28vP+8u7v/vLq6/7u6uv+7uLj/uri4/7q3t/+4t7f/t7a2/7e2tv+3tbX/trW1/7a0 - tP+1tLT/tbOz/7SztP+0s7P/tLGz/7Oxs/+0tLX/srO1/7Cytf+wsrT/r7K1/66vtP+rrbD/rK2w/6mp - rP+lpKT/qKWj/6ehnf+gmJH/p5yP/6eYif+gjnv/qpB3/62lnv+rq6z/q6mp/6moqP+rq6v76Ojo/fT0 - 9P/y8vL/9fX1/+Pj4/2amppOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdHR0C6OZmRmzrKwou7u7PLezs1G3tbVnube3f7i2 - tpe3tLStt7S0wri1tda1tLTmtLOz9LSzs/62tbX/tbS0/7W0tP+0s7P/s7Oz/7Oxsv+zsLD/srCw/7Gv - r/+wr6//sK+v/7Curv+vrq7/r62t/66trf+ura3/rq2t/66trv+tra7/rqyt/62ur/+trbD/rK2w/6us - r/+rrbD/q6ur/6upqf+rqan/q6mp/6Wlpfze3t789fX1//Hx8f/19fX/8fHx/5mZmXYAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZmZmBaqqqhKqqqohraioMrCs - rEexr69csa+vc7KwsIuwsLCisLCwuLSvr8yxr6/erqys7a6trPqxr6//sK+u/7Curv+vra3/rq2t/66t - rf+urKz/rq2s/66srP+trKv/rayr/6yrq/+sq6v/rKur/6ypqv+sqar/rKmq/6ypqv+sqar/pKKi/dLS - 0vv39/f/9/f3/+jo6P+ysrK5b29vNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaqq - qgyZmZkZoqKiKaqqqjyqqqpRrKmpaKupqYCsq6uXraqqrqyrq8KsqqrWq6qq5qqpqfSrqqr+rKur/6yr - q/+sq6v/rKmq/6ypqv+sqar/rKmq/6ypqv+npaX/ysrK/+3t7f+4uLi/eXl5SgAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAGZmZgWGhoYTqqqqIa+vrzOppaVHqampXKmnp3SrpaeLq6eno6mpqbipqKjNqaan36up - qeympKTThISEUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAXR0dAuqiooYm5ubKaCgoDuopaVSq6ioZJSUlEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////+AAH////////////////wAAAAAP/////////////AAAAAAAAB///////// - ///gAAAAAAAAP///////////4AAAAAAAAB///////////+AAAAAAAAAf///////////+AAAAAAAAH/// - ////////////AAAAAA////////////////gAAAAP///////////////8AAAAD////////////////AAA - AA////////////////wAAAAf///////////////8AAAAH////////////////AAAAB////////////// - //wAAAA////////////////8AAAAP////////////////AAAAD////////////////wAAAA///////// - ///////4AAAAf///////////////+AAAAH8AAf////////////gAAAAAAAH//////////8AAAAAAAAAB - ///////gAAAAAAAAAAAAAf///gAAAAAAAAAAAAAAAAH///gAAAAAAAAAAAAAAAAB//+AAAAAAAAAAAAA - AAAAAP//gAAAAAAAAAAAAAAAAAD//4AAAAAAAAAAAAAAAAAA//+AAAAAAAAAAAAAAAAAAP//wAAAAAAA - AAAAAAAAAAD//8AAAAAAAAAAAAAAAAAA///AAAAAAAAAAAAAAAAAAH//wAAAAAAAAAAAAAAAAAB//+AA - AAAAAAAAAAAAAAAAf//gAAAAAAAAAAAAAAAAAH//4AAAAAAAAAAAAAAAAAB//+AAAAAAAAAAAAAAAAAA - f//gAAAAAAAAAAAAAAAAAH//4AAAAAAAAAAAAAAAAAA///AAAAAAAAAAAAAAAAAAP//wAAAAAAAAAAAA - AAAAAD//8AAAAAAAAAAAAAAAAAA///AAAAAAAAAAAAAAAAAAP//wAAAAAAAAAAAAAAAAAD//+AAAAAAA - AAAAAAAAAAAf//gAAAAAAAAAAAAAAAAAH//4AAAAAAAAAAAAAAAAAB//+AAAAAAAAAAAAAAAAAAf//gA - AAAAAAAAAAAAAAAAH//4AAAAAAAAAAAAAAAAAB///AAAAAAAAAAAAAAAAAAf//wAAAAAAAAAAAAAAAAA - D//8AAAAAAAAAAAAAAAAAA///AAAAAAAAAAAAAAAAAAP//wAAAAAAAAAAAAAAAAAD//+AAAAAAAAAAAA - AAAAAA///gAAAAAAAAAAAAAAAAAP//4AAAAAAAAAAAAAAAAAB//+AAAAAAAAAAAAAAAAAAf//gAAAAAA - AAAAAAAAAAAH//8AAAAAAAAAAAAAAAAAB///AAAAAAAAAAAAAAAAAAf//wAAAAAAAAAAAAAAAAAH//8A - AAAAAAAAAAAAAAAAB///AAAAAAAAAAAAAAAAAAP//wAAAAAAAAAAAAAAAAAD//+AAAAAAAAAAAAAAAAA - A///gAAAAAAAAAAAAAAAAAP//4AAAAAAAAAAAAAAAAAD//+AAAAAAAAAAAAAAAAAA///gAAAAAAAAAAA - AAAAAAH//8AAAAAAAAAAAAAAAAAB///AAAAAAAAAAAAAAAAAAf//wAAAAAAAAAAAAAAAAAH//8AAAAAA - AAAAAAAAAAAB///AAAAAAAAAAAAAAAAAAf//4AAAAAAAAAAAAAAAAAH//+AAAAAAAAAAAAAAAAAA///g - AAAAAAAAAAAAAAAAAP//4AAAAAAAAAAAAAAAAAD//+AAAAAAAAAAAAAAAAAA///gAAAAAAAAAAAAAAAA - AP//8AAAAAAAAAAAAAAAAAD///AAAAAAAAAAAAAAAAAAf//wAAAAAAAAAAAAAAAAAH//8AAAAAAAAAAA - AAAAAAB///AAAAAAAAAAAAAAAAAAf//4AAAAAAAAAAAAAAAAAH//+AAAAAAAAAAAAAAAAAB///gAAAAA - AAAAAAAAAAAAf//4AAAAAAAAAAAAAAAAAD//+AAAAAAAAAAAAAAAAAA///gAAAAAAAAAAAAAAAAAP//8 - AAAAAAAAAAAAAAAAAD///AAAAAAAAAAAAAAAAAA///wAAAAAAAAAAAAAAAAAP//8AAAAAAAAAAAAAAAA - AB///AAAAAAAAAAAAAAAAAAf//4AAAAAAAAAAAAAAAAAH//+AAAAAAAAAAAAAAAAAB///gAAAAAAAAAA - AAAAAAAf//4AAAAAAAAAAAAAAAAAH//+AAAAAAAAAAAAAAAAAB///wAAAAAAAAAAAAAAAAAP//8AAAAA - AAAAAAAAAAAAD///AAAAAAAAAAAAAAAAAA///wAAAAAAAAAAAAAAAAAP///8AAAAAAAAAAAAAAAAD/// - //+AAAAAAAAAAAAAAA///////+AAAAAAAAAAAAAH/////////AAAAAAAAAAAB///////////AAAAAAAA - AAf////////////gAAAAAAAH//////////////gAAAAAB////////////////gAAAB////////////// - ////wAB///////////////////8A//////////////////////////////////////////////////// - //////////////////////////////////8= - - - \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/config/ProfileConfig.cs b/BizHawk.Client.EmuHawk/config/ProfileConfig.cs index e85359571c..ddbf3b8fc7 100644 --- a/BizHawk.Client.EmuHawk/config/ProfileConfig.cs +++ b/BizHawk.Client.EmuHawk/config/ProfileConfig.cs @@ -87,19 +87,13 @@ namespace BizHawk.Client.EmuHawk // N64 var n64Settings = GetSyncSettings(); n64Settings.Rsp = N64SyncSettings.RspType.Rsp_Hle; - n64Settings.Core = N64SyncSettings.CoreType.Dynarec; + //n64Settings.Core = N64SyncSettings.CoreType.Dynarec; + n64Settings.Core = N64SyncSettings.CoreType.Interpret; Global.Config.N64UseCircularAnalogConstraint = true; PutSyncSettings(n64Settings); // SNES - var snesSettings = GetSyncSettings(); - snesSettings.Profile = "Performance"; - PutSyncSettings(snesSettings); - - // Saturn - var saturnSettings = GetSyncSettings(); - saturnSettings.SkipBios = false; - PutSyncSettings(saturnSettings); + Global.Config.SNES_InSnes9x = true; // Genesis var genesisSettings = GetSyncSettings(); @@ -108,7 +102,7 @@ namespace BizHawk.Client.EmuHawk // SMS var smsSettings = GetSyncSettings(); - smsSettings.UseBIOS = false; + smsSettings.UseBIOS = true; PutSyncSettings(smsSettings); // Coleco @@ -142,20 +136,12 @@ namespace BizHawk.Client.EmuHawk // N64 var n64Settings = GetSyncSettings(); - n64Settings.Rsp = N64SyncSettings.RspType.Rsp_Z64_hlevideo; n64Settings.Core = N64SyncSettings.CoreType.Pure_Interpret; Global.Config.N64UseCircularAnalogConstraint = true; PutSyncSettings(n64Settings); // SNES - var snesSettings = GetSyncSettings(); - snesSettings.Profile = "Compatibility"; - PutSyncSettings(snesSettings); - - // Saturn - var saturnSettings = GetSyncSettings(); - saturnSettings.SkipBios = false; - PutSyncSettings(saturnSettings); + Global.Config.SNES_InSnes9x = false; // Genesis var genesisSettings = GetSyncSettings(); @@ -164,7 +150,7 @@ namespace BizHawk.Client.EmuHawk // SMS var smsSettings = GetSyncSettings(); - smsSettings.UseBIOS = false; + smsSettings.UseBIOS = true; PutSyncSettings(smsSettings); // Coleco @@ -201,20 +187,12 @@ namespace BizHawk.Client.EmuHawk // N64 var n64Settings = GetSyncSettings(); - n64Settings.Rsp = N64SyncSettings.RspType.Rsp_Z64_hlevideo; n64Settings.Core = N64SyncSettings.CoreType.Pure_Interpret; Global.Config.N64UseCircularAnalogConstraint = false; PutSyncSettings(n64Settings); // SNES - var snesSettings = GetSyncSettings(); - snesSettings.Profile = "Compatibility"; - PutSyncSettings(snesSettings); - - // Saturn - var saturnSettings = GetSyncSettings(); - saturnSettings.SkipBios = true; - PutSyncSettings(saturnSettings); + Global.Config.SNES_InSnes9x = false; // Genesis var genesisSettings = GetSyncSettings(); @@ -223,7 +201,7 @@ namespace BizHawk.Client.EmuHawk // SMS var smsSettings = GetSyncSettings(); - smsSettings.UseBIOS = false; + smsSettings.UseBIOS = true; PutSyncSettings(smsSettings); // Coleco @@ -266,14 +244,7 @@ namespace BizHawk.Client.EmuHawk PutSyncSettings(n64Settings); // SNES - var snesSettings = GetSyncSettings(); - snesSettings.Profile = "Compatibility"; - PutSyncSettings(snesSettings); - - // Saturn - var saturnSettings = GetSyncSettings(); - saturnSettings.SkipBios = true; - PutSyncSettings(saturnSettings); + Global.Config.SNES_InSnes9x = false; // Genesis var genesisSettings = GetSyncSettings(); @@ -282,7 +253,7 @@ namespace BizHawk.Client.EmuHawk // SMS var smsSettings = GetSyncSettings(); - smsSettings.UseBIOS = false; + smsSettings.UseBIOS = true; PutSyncSettings(smsSettings); // Coleco diff --git a/BizHawk.Client.EmuHawk/config/RewindConfig.Designer.cs b/BizHawk.Client.EmuHawk/config/RewindConfig.Designer.cs index 0abf182a6b..d9ac383d4a 100644 --- a/BizHawk.Client.EmuHawk/config/RewindConfig.Designer.cs +++ b/BizHawk.Client.EmuHawk/config/RewindConfig.Designer.cs @@ -28,1011 +28,1011 @@ /// private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RewindConfig)); - this.OK = new System.Windows.Forms.Button(); - this.Cancel = new System.Windows.Forms.Button(); - this.SmallLabel1 = new System.Windows.Forms.Label(); - this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.label10 = new System.Windows.Forms.Label(); - this.LargeStateEnabledBox = new System.Windows.Forms.CheckBox(); - this.MediumStateEnabledBox = new System.Windows.Forms.CheckBox(); - this.SmallStateEnabledBox = new System.Windows.Forms.CheckBox(); - this.LargeLabel2 = new System.Windows.Forms.Label(); - this.LargeLabel3 = new System.Windows.Forms.Label(); - this.LargeSavestateNumeric = new System.Windows.Forms.NumericUpDown(); - this.LargeLabel1 = new System.Windows.Forms.Label(); - this.MediumLabel2 = new System.Windows.Forms.Label(); - this.MediumLabel3 = new System.Windows.Forms.Label(); - this.MediumSavestateNumeric = new System.Windows.Forms.NumericUpDown(); - this.MediumLabel1 = new System.Windows.Forms.Label(); - this.SmallLabel2 = new System.Windows.Forms.Label(); - this.SmallLabel3 = new System.Windows.Forms.Label(); - this.SmallSavestateNumeric = new System.Windows.Forms.NumericUpDown(); - this.UseDeltaCompression = new System.Windows.Forms.CheckBox(); - this.label1 = new System.Windows.Forms.Label(); - this.StateSizeLabel = new System.Windows.Forms.Label(); - this.MediumStateTrackbar = new System.Windows.Forms.TrackBar(); - this.groupBox2 = new System.Windows.Forms.GroupBox(); - this.LargeStateUpDown = new System.Windows.Forms.NumericUpDown(); - this.MediumStateUpDown = new System.Windows.Forms.NumericUpDown(); - this.LargeStateSizeLabel = new System.Windows.Forms.Label(); - this.label5 = new System.Windows.Forms.Label(); - this.LargeStateTrackbar = new System.Windows.Forms.TrackBar(); - this.MediumStateSizeLabel = new System.Windows.Forms.Label(); - this.label2 = new System.Windows.Forms.Label(); - this.groupBox3 = new System.Windows.Forms.GroupBox(); - this.label19 = new System.Windows.Forms.Label(); - this.RewindSpeedNumeric = new System.Windows.Forms.NumericUpDown(); - this.label18 = new System.Windows.Forms.Label(); - this.label17 = new System.Windows.Forms.Label(); - this.RewindIsThreadedCheckbox = new System.Windows.Forms.CheckBox(); - this.label4 = new System.Windows.Forms.Label(); - this.BufferSizeUpDown = new System.Windows.Forms.NumericUpDown(); - this.label3 = new System.Windows.Forms.Label(); - this.DiskBufferCheckbox = new System.Windows.Forms.CheckBox(); - this.label6 = new System.Windows.Forms.Label(); - this.FullnessLabel = new System.Windows.Forms.Label(); - this.groupBox4 = new System.Windows.Forms.GroupBox(); - this.EstTimeLabel = new System.Windows.Forms.Label(); - this.label11 = new System.Windows.Forms.Label(); - this.AverageStoredStateSizeLabel = new System.Windows.Forms.Label(); - this.label9 = new System.Windows.Forms.Label(); - this.ApproxFramesLabel = new System.Windows.Forms.Label(); - this.label8 = new System.Windows.Forms.Label(); - this.RewindFramesUsedLabel = new System.Windows.Forms.Label(); - this.label7 = new System.Windows.Forms.Label(); - this.groupBox6 = new System.Windows.Forms.GroupBox(); - this.rbStatesText = new System.Windows.Forms.RadioButton(); - this.rbStatesBinary = new System.Windows.Forms.RadioButton(); - this.rbStatesDefault = new System.Windows.Forms.RadioButton(); - this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); - this.btnResetCompression = new System.Windows.Forms.Button(); - this.trackBarCompression = new System.Windows.Forms.TrackBar(); - this.nudCompression = new System.Windows.Forms.NumericUpDown(); - this.groupBox7 = new System.Windows.Forms.GroupBox(); - this.label20 = new System.Windows.Forms.Label(); - this.KbLabel = new System.Windows.Forms.Label(); - this.BigScreenshotNumeric = new System.Windows.Forms.NumericUpDown(); - this.LowResLargeScreenshotsCheckbox = new System.Windows.Forms.CheckBox(); - this.label13 = new System.Windows.Forms.Label(); - this.label14 = new System.Windows.Forms.Label(); - this.ScreenshotInStatesCheckbox = new System.Windows.Forms.CheckBox(); - this.label15 = new System.Windows.Forms.Label(); - this.label16 = new System.Windows.Forms.Label(); - this.BackupSavestatesCheckbox = new System.Windows.Forms.CheckBox(); - this.label12 = new System.Windows.Forms.Label(); - this.groupBox1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.LargeSavestateNumeric)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.MediumSavestateNumeric)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.SmallSavestateNumeric)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.MediumStateTrackbar)).BeginInit(); - this.groupBox2.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.LargeStateUpDown)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.MediumStateUpDown)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.LargeStateTrackbar)).BeginInit(); - this.groupBox3.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.RewindSpeedNumeric)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.BufferSizeUpDown)).BeginInit(); - this.groupBox4.SuspendLayout(); - this.groupBox6.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.trackBarCompression)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.nudCompression)).BeginInit(); - this.groupBox7.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.BigScreenshotNumeric)).BeginInit(); - this.SuspendLayout(); - // - // OK - // - this.OK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.OK.Location = new System.Drawing.Point(575, 470); - this.OK.Name = "OK"; - this.OK.Size = new System.Drawing.Size(75, 23); - this.OK.TabIndex = 0; - this.OK.Text = "&OK"; - this.OK.UseVisualStyleBackColor = true; - this.OK.Click += new System.EventHandler(this.Ok_Click); - // - // Cancel - // - this.Cancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.Cancel.Location = new System.Drawing.Point(656, 470); - this.Cancel.Name = "Cancel"; - this.Cancel.Size = new System.Drawing.Size(75, 23); - this.Cancel.TabIndex = 1; - this.Cancel.Text = "&Cancel"; - this.Cancel.UseVisualStyleBackColor = true; - this.Cancel.Click += new System.EventHandler(this.Cancel_Click); - // - // SmallLabel1 - // - this.SmallLabel1.AutoSize = true; - this.SmallLabel1.Location = new System.Drawing.Point(40, 40); - this.SmallLabel1.Name = "SmallLabel1"; - this.SmallLabel1.Size = new System.Drawing.Size(166, 13); - this.SmallLabel1.TabIndex = 2; - this.SmallLabel1.Text = "Small savestates (less than 32KB)"; - this.SmallLabel1.Click += new System.EventHandler(this.SmallLabel1_Click); - // - // groupBox1 - // - this.groupBox1.Controls.Add(this.label10); - this.groupBox1.Controls.Add(this.LargeStateEnabledBox); - this.groupBox1.Controls.Add(this.MediumStateEnabledBox); - this.groupBox1.Controls.Add(this.SmallStateEnabledBox); - this.groupBox1.Controls.Add(this.LargeLabel2); - this.groupBox1.Controls.Add(this.LargeLabel3); - this.groupBox1.Controls.Add(this.LargeSavestateNumeric); - this.groupBox1.Controls.Add(this.LargeLabel1); - this.groupBox1.Controls.Add(this.MediumLabel2); - this.groupBox1.Controls.Add(this.MediumLabel3); - this.groupBox1.Controls.Add(this.MediumSavestateNumeric); - this.groupBox1.Controls.Add(this.MediumLabel1); - this.groupBox1.Controls.Add(this.SmallLabel2); - this.groupBox1.Controls.Add(this.SmallLabel3); - this.groupBox1.Controls.Add(this.SmallSavestateNumeric); - this.groupBox1.Controls.Add(this.SmallLabel1); - this.groupBox1.Location = new System.Drawing.Point(12, 90); - this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(371, 118); - this.groupBox1.TabIndex = 3; - this.groupBox1.TabStop = false; - this.groupBox1.Text = "Rewind frequency"; - // - // label10 - // - this.label10.AutoSize = true; - this.label10.Location = new System.Drawing.Point(6, 20); - this.label10.Name = "label10"; - this.label10.Size = new System.Drawing.Size(40, 13); - this.label10.TabIndex = 17; - this.label10.Text = "Enable"; - // - // LargeStateEnabledBox - // - this.LargeStateEnabledBox.AutoSize = true; - this.LargeStateEnabledBox.Location = new System.Drawing.Point(9, 87); - this.LargeStateEnabledBox.Name = "LargeStateEnabledBox"; - this.LargeStateEnabledBox.Size = new System.Drawing.Size(15, 14); - this.LargeStateEnabledBox.TabIndex = 16; - this.LargeStateEnabledBox.UseVisualStyleBackColor = true; - this.LargeStateEnabledBox.CheckStateChanged += new System.EventHandler(this.LargeStateEnabledBox_CheckStateChanged); - // - // MediumStateEnabledBox - // - this.MediumStateEnabledBox.AutoSize = true; - this.MediumStateEnabledBox.Location = new System.Drawing.Point(9, 63); - this.MediumStateEnabledBox.Name = "MediumStateEnabledBox"; - this.MediumStateEnabledBox.Size = new System.Drawing.Size(15, 14); - this.MediumStateEnabledBox.TabIndex = 15; - this.MediumStateEnabledBox.UseVisualStyleBackColor = true; - this.MediumStateEnabledBox.CheckStateChanged += new System.EventHandler(this.MediumStateEnabledBox_CheckStateChanged); - // - // SmallStateEnabledBox - // - this.SmallStateEnabledBox.AutoSize = true; - this.SmallStateEnabledBox.Location = new System.Drawing.Point(9, 39); - this.SmallStateEnabledBox.Name = "SmallStateEnabledBox"; - this.SmallStateEnabledBox.Size = new System.Drawing.Size(15, 14); - this.SmallStateEnabledBox.TabIndex = 14; - this.SmallStateEnabledBox.UseVisualStyleBackColor = true; - this.SmallStateEnabledBox.CheckStateChanged += new System.EventHandler(this.SmallStateEnabledBox_CheckStateChanged); - // - // LargeLabel2 - // - this.LargeLabel2.AutoSize = true; - this.LargeLabel2.Location = new System.Drawing.Point(227, 88); - this.LargeLabel2.Name = "LargeLabel2"; - this.LargeLabel2.Size = new System.Drawing.Size(33, 13); - this.LargeLabel2.TabIndex = 13; - this.LargeLabel2.Text = "every"; - // - // LargeLabel3 - // - this.LargeLabel3.AutoSize = true; - this.LargeLabel3.Location = new System.Drawing.Point(307, 88); - this.LargeLabel3.Name = "LargeLabel3"; - this.LargeLabel3.Size = new System.Drawing.Size(38, 13); - this.LargeLabel3.TabIndex = 12; - this.LargeLabel3.Text = "frames"; - // - // LargeSavestateNumeric - // - this.LargeSavestateNumeric.Location = new System.Drawing.Point(263, 84); - this.LargeSavestateNumeric.Maximum = new decimal(new int[] { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RewindConfig)); + this.OK = new System.Windows.Forms.Button(); + this.Cancel = new System.Windows.Forms.Button(); + this.SmallLabel1 = new System.Windows.Forms.Label(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.label10 = new System.Windows.Forms.Label(); + this.LargeStateEnabledBox = new System.Windows.Forms.CheckBox(); + this.MediumStateEnabledBox = new System.Windows.Forms.CheckBox(); + this.SmallStateEnabledBox = new System.Windows.Forms.CheckBox(); + this.LargeLabel2 = new System.Windows.Forms.Label(); + this.LargeLabel3 = new System.Windows.Forms.Label(); + this.LargeSavestateNumeric = new System.Windows.Forms.NumericUpDown(); + this.LargeLabel1 = new System.Windows.Forms.Label(); + this.MediumLabel2 = new System.Windows.Forms.Label(); + this.MediumLabel3 = new System.Windows.Forms.Label(); + this.MediumSavestateNumeric = new System.Windows.Forms.NumericUpDown(); + this.MediumLabel1 = new System.Windows.Forms.Label(); + this.SmallLabel2 = new System.Windows.Forms.Label(); + this.SmallLabel3 = new System.Windows.Forms.Label(); + this.SmallSavestateNumeric = new System.Windows.Forms.NumericUpDown(); + this.UseDeltaCompression = new System.Windows.Forms.CheckBox(); + this.label1 = new System.Windows.Forms.Label(); + this.StateSizeLabel = new System.Windows.Forms.Label(); + this.MediumStateTrackbar = new System.Windows.Forms.TrackBar(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.LargeStateUpDown = new System.Windows.Forms.NumericUpDown(); + this.MediumStateUpDown = new System.Windows.Forms.NumericUpDown(); + this.LargeStateSizeLabel = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.LargeStateTrackbar = new System.Windows.Forms.TrackBar(); + this.MediumStateSizeLabel = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.label19 = new System.Windows.Forms.Label(); + this.RewindSpeedNumeric = new System.Windows.Forms.NumericUpDown(); + this.label18 = new System.Windows.Forms.Label(); + this.label17 = new System.Windows.Forms.Label(); + this.RewindIsThreadedCheckbox = new System.Windows.Forms.CheckBox(); + this.label4 = new System.Windows.Forms.Label(); + this.BufferSizeUpDown = new System.Windows.Forms.NumericUpDown(); + this.label3 = new System.Windows.Forms.Label(); + this.DiskBufferCheckbox = new System.Windows.Forms.CheckBox(); + this.label6 = new System.Windows.Forms.Label(); + this.FullnessLabel = new System.Windows.Forms.Label(); + this.groupBox4 = new System.Windows.Forms.GroupBox(); + this.EstTimeLabel = new System.Windows.Forms.Label(); + this.label11 = new System.Windows.Forms.Label(); + this.AverageStoredStateSizeLabel = new System.Windows.Forms.Label(); + this.label9 = new System.Windows.Forms.Label(); + this.ApproxFramesLabel = new System.Windows.Forms.Label(); + this.label8 = new System.Windows.Forms.Label(); + this.RewindFramesUsedLabel = new System.Windows.Forms.Label(); + this.label7 = new System.Windows.Forms.Label(); + this.groupBox6 = new System.Windows.Forms.GroupBox(); + this.rbStatesText = new System.Windows.Forms.RadioButton(); + this.rbStatesBinary = new System.Windows.Forms.RadioButton(); + this.rbStatesDefault = new System.Windows.Forms.RadioButton(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.btnResetCompression = new System.Windows.Forms.Button(); + this.trackBarCompression = new System.Windows.Forms.TrackBar(); + this.nudCompression = new System.Windows.Forms.NumericUpDown(); + this.groupBox7 = new System.Windows.Forms.GroupBox(); + this.label20 = new System.Windows.Forms.Label(); + this.KbLabel = new System.Windows.Forms.Label(); + this.BigScreenshotNumeric = new System.Windows.Forms.NumericUpDown(); + this.LowResLargeScreenshotsCheckbox = new System.Windows.Forms.CheckBox(); + this.label13 = new System.Windows.Forms.Label(); + this.label14 = new System.Windows.Forms.Label(); + this.ScreenshotInStatesCheckbox = new System.Windows.Forms.CheckBox(); + this.label15 = new System.Windows.Forms.Label(); + this.label16 = new System.Windows.Forms.Label(); + this.BackupSavestatesCheckbox = new System.Windows.Forms.CheckBox(); + this.label12 = new System.Windows.Forms.Label(); + this.groupBox1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.LargeSavestateNumeric)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.MediumSavestateNumeric)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.SmallSavestateNumeric)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.MediumStateTrackbar)).BeginInit(); + this.groupBox2.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.LargeStateUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.MediumStateUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.LargeStateTrackbar)).BeginInit(); + this.groupBox3.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.RewindSpeedNumeric)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.BufferSizeUpDown)).BeginInit(); + this.groupBox4.SuspendLayout(); + this.groupBox6.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.trackBarCompression)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudCompression)).BeginInit(); + this.groupBox7.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.BigScreenshotNumeric)).BeginInit(); + this.SuspendLayout(); + // + // OK + // + this.OK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.OK.Location = new System.Drawing.Point(575, 470); + this.OK.Name = "OK"; + this.OK.Size = new System.Drawing.Size(75, 23); + this.OK.TabIndex = 0; + this.OK.Text = "&OK"; + this.OK.UseVisualStyleBackColor = true; + this.OK.Click += new System.EventHandler(this.Ok_Click); + // + // Cancel + // + this.Cancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.Cancel.Location = new System.Drawing.Point(656, 470); + this.Cancel.Name = "Cancel"; + this.Cancel.Size = new System.Drawing.Size(75, 23); + this.Cancel.TabIndex = 1; + this.Cancel.Text = "&Cancel"; + this.Cancel.UseVisualStyleBackColor = true; + this.Cancel.Click += new System.EventHandler(this.Cancel_Click); + // + // SmallLabel1 + // + this.SmallLabel1.AutoSize = true; + this.SmallLabel1.Location = new System.Drawing.Point(40, 40); + this.SmallLabel1.Name = "SmallLabel1"; + this.SmallLabel1.Size = new System.Drawing.Size(166, 13); + this.SmallLabel1.TabIndex = 2; + this.SmallLabel1.Text = "Small savestates (less than 32KB)"; + this.SmallLabel1.Click += new System.EventHandler(this.SmallLabel1_Click); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.label10); + this.groupBox1.Controls.Add(this.LargeStateEnabledBox); + this.groupBox1.Controls.Add(this.MediumStateEnabledBox); + this.groupBox1.Controls.Add(this.SmallStateEnabledBox); + this.groupBox1.Controls.Add(this.LargeLabel2); + this.groupBox1.Controls.Add(this.LargeLabel3); + this.groupBox1.Controls.Add(this.LargeSavestateNumeric); + this.groupBox1.Controls.Add(this.LargeLabel1); + this.groupBox1.Controls.Add(this.MediumLabel2); + this.groupBox1.Controls.Add(this.MediumLabel3); + this.groupBox1.Controls.Add(this.MediumSavestateNumeric); + this.groupBox1.Controls.Add(this.MediumLabel1); + this.groupBox1.Controls.Add(this.SmallLabel2); + this.groupBox1.Controls.Add(this.SmallLabel3); + this.groupBox1.Controls.Add(this.SmallSavestateNumeric); + this.groupBox1.Controls.Add(this.SmallLabel1); + this.groupBox1.Location = new System.Drawing.Point(12, 90); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(371, 118); + this.groupBox1.TabIndex = 3; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Rewind frequency"; + // + // label10 + // + this.label10.AutoSize = true; + this.label10.Location = new System.Drawing.Point(6, 20); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(40, 13); + this.label10.TabIndex = 17; + this.label10.Text = "Enable"; + // + // LargeStateEnabledBox + // + this.LargeStateEnabledBox.AutoSize = true; + this.LargeStateEnabledBox.Location = new System.Drawing.Point(9, 87); + this.LargeStateEnabledBox.Name = "LargeStateEnabledBox"; + this.LargeStateEnabledBox.Size = new System.Drawing.Size(15, 14); + this.LargeStateEnabledBox.TabIndex = 16; + this.LargeStateEnabledBox.UseVisualStyleBackColor = true; + this.LargeStateEnabledBox.CheckStateChanged += new System.EventHandler(this.LargeStateEnabledBox_CheckStateChanged); + // + // MediumStateEnabledBox + // + this.MediumStateEnabledBox.AutoSize = true; + this.MediumStateEnabledBox.Location = new System.Drawing.Point(9, 63); + this.MediumStateEnabledBox.Name = "MediumStateEnabledBox"; + this.MediumStateEnabledBox.Size = new System.Drawing.Size(15, 14); + this.MediumStateEnabledBox.TabIndex = 15; + this.MediumStateEnabledBox.UseVisualStyleBackColor = true; + this.MediumStateEnabledBox.CheckStateChanged += new System.EventHandler(this.MediumStateEnabledBox_CheckStateChanged); + // + // SmallStateEnabledBox + // + this.SmallStateEnabledBox.AutoSize = true; + this.SmallStateEnabledBox.Location = new System.Drawing.Point(9, 39); + this.SmallStateEnabledBox.Name = "SmallStateEnabledBox"; + this.SmallStateEnabledBox.Size = new System.Drawing.Size(15, 14); + this.SmallStateEnabledBox.TabIndex = 14; + this.SmallStateEnabledBox.UseVisualStyleBackColor = true; + this.SmallStateEnabledBox.CheckStateChanged += new System.EventHandler(this.SmallStateEnabledBox_CheckStateChanged); + // + // LargeLabel2 + // + this.LargeLabel2.AutoSize = true; + this.LargeLabel2.Location = new System.Drawing.Point(227, 88); + this.LargeLabel2.Name = "LargeLabel2"; + this.LargeLabel2.Size = new System.Drawing.Size(33, 13); + this.LargeLabel2.TabIndex = 13; + this.LargeLabel2.Text = "every"; + // + // LargeLabel3 + // + this.LargeLabel3.AutoSize = true; + this.LargeLabel3.Location = new System.Drawing.Point(307, 88); + this.LargeLabel3.Name = "LargeLabel3"; + this.LargeLabel3.Size = new System.Drawing.Size(38, 13); + this.LargeLabel3.TabIndex = 12; + this.LargeLabel3.Text = "frames"; + // + // LargeSavestateNumeric + // + this.LargeSavestateNumeric.Location = new System.Drawing.Point(263, 84); + this.LargeSavestateNumeric.Maximum = new decimal(new int[] { 1024, 0, 0, 0}); - this.LargeSavestateNumeric.Minimum = new decimal(new int[] { + this.LargeSavestateNumeric.Minimum = new decimal(new int[] { 1, 0, 0, 0}); - this.LargeSavestateNumeric.Name = "LargeSavestateNumeric"; - this.LargeSavestateNumeric.Size = new System.Drawing.Size(38, 20); - this.LargeSavestateNumeric.TabIndex = 11; - this.LargeSavestateNumeric.Value = new decimal(new int[] { + this.LargeSavestateNumeric.Name = "LargeSavestateNumeric"; + this.LargeSavestateNumeric.Size = new System.Drawing.Size(38, 20); + this.LargeSavestateNumeric.TabIndex = 11; + this.LargeSavestateNumeric.Value = new decimal(new int[] { 1, 0, 0, 0}); - this.LargeSavestateNumeric.ValueChanged += new System.EventHandler(this.LargeSavestateNumeric_ValueChanged); - // - // LargeLabel1 - // - this.LargeLabel1.AutoSize = true; - this.LargeLabel1.Location = new System.Drawing.Point(40, 88); - this.LargeLabel1.Name = "LargeLabel1"; - this.LargeLabel1.Size = new System.Drawing.Size(179, 13); - this.LargeLabel1.TabIndex = 10; - this.LargeLabel1.Text = "Large savestates (more than 100KB)"; - this.LargeLabel1.Click += new System.EventHandler(this.LargeLabel1_Click); - // - // MediumLabel2 - // - this.MediumLabel2.AutoSize = true; - this.MediumLabel2.Location = new System.Drawing.Point(227, 64); - this.MediumLabel2.Name = "MediumLabel2"; - this.MediumLabel2.Size = new System.Drawing.Size(33, 13); - this.MediumLabel2.TabIndex = 9; - this.MediumLabel2.Text = "every"; - // - // MediumLabel3 - // - this.MediumLabel3.AutoSize = true; - this.MediumLabel3.Location = new System.Drawing.Point(307, 64); - this.MediumLabel3.Name = "MediumLabel3"; - this.MediumLabel3.Size = new System.Drawing.Size(38, 13); - this.MediumLabel3.TabIndex = 8; - this.MediumLabel3.Text = "frames"; - // - // MediumSavestateNumeric - // - this.MediumSavestateNumeric.Location = new System.Drawing.Point(263, 60); - this.MediumSavestateNumeric.Maximum = new decimal(new int[] { + this.LargeSavestateNumeric.ValueChanged += new System.EventHandler(this.LargeSavestateNumeric_ValueChanged); + // + // LargeLabel1 + // + this.LargeLabel1.AutoSize = true; + this.LargeLabel1.Location = new System.Drawing.Point(40, 88); + this.LargeLabel1.Name = "LargeLabel1"; + this.LargeLabel1.Size = new System.Drawing.Size(179, 13); + this.LargeLabel1.TabIndex = 10; + this.LargeLabel1.Text = "Large savestates (more than 100KB)"; + this.LargeLabel1.Click += new System.EventHandler(this.LargeLabel1_Click); + // + // MediumLabel2 + // + this.MediumLabel2.AutoSize = true; + this.MediumLabel2.Location = new System.Drawing.Point(227, 64); + this.MediumLabel2.Name = "MediumLabel2"; + this.MediumLabel2.Size = new System.Drawing.Size(33, 13); + this.MediumLabel2.TabIndex = 9; + this.MediumLabel2.Text = "every"; + // + // MediumLabel3 + // + this.MediumLabel3.AutoSize = true; + this.MediumLabel3.Location = new System.Drawing.Point(307, 64); + this.MediumLabel3.Name = "MediumLabel3"; + this.MediumLabel3.Size = new System.Drawing.Size(38, 13); + this.MediumLabel3.TabIndex = 8; + this.MediumLabel3.Text = "frames"; + // + // MediumSavestateNumeric + // + this.MediumSavestateNumeric.Location = new System.Drawing.Point(263, 60); + this.MediumSavestateNumeric.Maximum = new decimal(new int[] { 1024, 0, 0, 0}); - this.MediumSavestateNumeric.Minimum = new decimal(new int[] { + this.MediumSavestateNumeric.Minimum = new decimal(new int[] { 1, 0, 0, 0}); - this.MediumSavestateNumeric.Name = "MediumSavestateNumeric"; - this.MediumSavestateNumeric.Size = new System.Drawing.Size(38, 20); - this.MediumSavestateNumeric.TabIndex = 7; - this.MediumSavestateNumeric.Value = new decimal(new int[] { + this.MediumSavestateNumeric.Name = "MediumSavestateNumeric"; + this.MediumSavestateNumeric.Size = new System.Drawing.Size(38, 20); + this.MediumSavestateNumeric.TabIndex = 7; + this.MediumSavestateNumeric.Value = new decimal(new int[] { 1, 0, 0, 0}); - this.MediumSavestateNumeric.ValueChanged += new System.EventHandler(this.MediumSavestateNumeric_ValueChanged); - // - // MediumLabel1 - // - this.MediumLabel1.AutoSize = true; - this.MediumLabel1.Location = new System.Drawing.Point(40, 64); - this.MediumLabel1.Name = "MediumLabel1"; - this.MediumLabel1.Size = new System.Drawing.Size(160, 13); - this.MediumLabel1.TabIndex = 6; - this.MediumLabel1.Text = "Medium savestates (32 - 100KB)"; - this.MediumLabel1.Click += new System.EventHandler(this.MediumLabel1_Click); - // - // SmallLabel2 - // - this.SmallLabel2.AutoSize = true; - this.SmallLabel2.Location = new System.Drawing.Point(227, 40); - this.SmallLabel2.Name = "SmallLabel2"; - this.SmallLabel2.Size = new System.Drawing.Size(33, 13); - this.SmallLabel2.TabIndex = 5; - this.SmallLabel2.Text = "every"; - // - // SmallLabel3 - // - this.SmallLabel3.AutoSize = true; - this.SmallLabel3.Location = new System.Drawing.Point(307, 40); - this.SmallLabel3.Name = "SmallLabel3"; - this.SmallLabel3.Size = new System.Drawing.Size(38, 13); - this.SmallLabel3.TabIndex = 4; - this.SmallLabel3.Text = "frames"; - // - // SmallSavestateNumeric - // - this.SmallSavestateNumeric.Location = new System.Drawing.Point(263, 36); - this.SmallSavestateNumeric.Maximum = new decimal(new int[] { + this.MediumSavestateNumeric.ValueChanged += new System.EventHandler(this.MediumSavestateNumeric_ValueChanged); + // + // MediumLabel1 + // + this.MediumLabel1.AutoSize = true; + this.MediumLabel1.Location = new System.Drawing.Point(40, 64); + this.MediumLabel1.Name = "MediumLabel1"; + this.MediumLabel1.Size = new System.Drawing.Size(160, 13); + this.MediumLabel1.TabIndex = 6; + this.MediumLabel1.Text = "Medium savestates (32 - 100KB)"; + this.MediumLabel1.Click += new System.EventHandler(this.MediumLabel1_Click); + // + // SmallLabel2 + // + this.SmallLabel2.AutoSize = true; + this.SmallLabel2.Location = new System.Drawing.Point(227, 40); + this.SmallLabel2.Name = "SmallLabel2"; + this.SmallLabel2.Size = new System.Drawing.Size(33, 13); + this.SmallLabel2.TabIndex = 5; + this.SmallLabel2.Text = "every"; + // + // SmallLabel3 + // + this.SmallLabel3.AutoSize = true; + this.SmallLabel3.Location = new System.Drawing.Point(307, 40); + this.SmallLabel3.Name = "SmallLabel3"; + this.SmallLabel3.Size = new System.Drawing.Size(38, 13); + this.SmallLabel3.TabIndex = 4; + this.SmallLabel3.Text = "frames"; + // + // SmallSavestateNumeric + // + this.SmallSavestateNumeric.Location = new System.Drawing.Point(263, 36); + this.SmallSavestateNumeric.Maximum = new decimal(new int[] { 1024, 0, 0, 0}); - this.SmallSavestateNumeric.Minimum = new decimal(new int[] { + this.SmallSavestateNumeric.Minimum = new decimal(new int[] { 1, 0, 0, 0}); - this.SmallSavestateNumeric.Name = "SmallSavestateNumeric"; - this.SmallSavestateNumeric.Size = new System.Drawing.Size(38, 20); - this.SmallSavestateNumeric.TabIndex = 3; - this.SmallSavestateNumeric.Value = new decimal(new int[] { + this.SmallSavestateNumeric.Name = "SmallSavestateNumeric"; + this.SmallSavestateNumeric.Size = new System.Drawing.Size(38, 20); + this.SmallSavestateNumeric.TabIndex = 3; + this.SmallSavestateNumeric.Value = new decimal(new int[] { 1, 0, 0, 0}); - this.SmallSavestateNumeric.ValueChanged += new System.EventHandler(this.SmallSavestateNumeric_ValueChanged); - // - // UseDeltaCompression - // - this.UseDeltaCompression.AutoSize = true; - this.UseDeltaCompression.Location = new System.Drawing.Point(16, 89); - this.UseDeltaCompression.Name = "UseDeltaCompression"; - this.UseDeltaCompression.Size = new System.Drawing.Size(332, 17); - this.UseDeltaCompression.TabIndex = 5; - this.UseDeltaCompression.Text = "Use delta compression (economizes buffer usage at cost of CPU)"; - this.UseDeltaCompression.UseVisualStyleBackColor = true; - this.UseDeltaCompression.CheckedChanged += new System.EventHandler(this.UseDeltaCompression_CheckedChanged); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(12, 17); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(81, 13); - this.label1.TabIndex = 5; - this.label1.Text = "Savestate Size:"; - // - // StateSizeLabel - // - this.StateSizeLabel.AutoSize = true; - this.StateSizeLabel.Location = new System.Drawing.Point(92, 17); - this.StateSizeLabel.Name = "StateSizeLabel"; - this.StateSizeLabel.Size = new System.Drawing.Size(30, 13); - this.StateSizeLabel.TabIndex = 6; - this.StateSizeLabel.Text = "0 KB"; - // - // MediumStateTrackbar - // - this.MediumStateTrackbar.LargeChange = 256; - this.MediumStateTrackbar.Location = new System.Drawing.Point(67, 22); - this.MediumStateTrackbar.Maximum = 4096; - this.MediumStateTrackbar.Minimum = 1; - this.MediumStateTrackbar.Name = "MediumStateTrackbar"; - this.MediumStateTrackbar.Size = new System.Drawing.Size(186, 42); - this.MediumStateTrackbar.TabIndex = 7; - this.MediumStateTrackbar.TickFrequency = 256; - this.MediumStateTrackbar.Value = 1; - this.MediumStateTrackbar.ValueChanged += new System.EventHandler(this.MediumStateTrackbar_ValueChanged); - // - // groupBox2 - // - this.groupBox2.Controls.Add(this.LargeStateUpDown); - this.groupBox2.Controls.Add(this.MediumStateUpDown); - this.groupBox2.Controls.Add(this.LargeStateSizeLabel); - this.groupBox2.Controls.Add(this.label5); - this.groupBox2.Controls.Add(this.LargeStateTrackbar); - this.groupBox2.Controls.Add(this.MediumStateSizeLabel); - this.groupBox2.Controls.Add(this.label2); - this.groupBox2.Controls.Add(this.MediumStateTrackbar); - this.groupBox2.Location = new System.Drawing.Point(12, 387); - this.groupBox2.Name = "groupBox2"; - this.groupBox2.Size = new System.Drawing.Size(371, 105); - this.groupBox2.TabIndex = 8; - this.groupBox2.TabStop = false; - this.groupBox2.Text = "State Size Definition"; - // - // LargeStateUpDown - // - this.LargeStateUpDown.Location = new System.Drawing.Point(259, 67); - this.LargeStateUpDown.Maximum = new decimal(new int[] { + this.SmallSavestateNumeric.ValueChanged += new System.EventHandler(this.SmallSavestateNumeric_ValueChanged); + // + // UseDeltaCompression + // + this.UseDeltaCompression.AutoSize = true; + this.UseDeltaCompression.Location = new System.Drawing.Point(16, 89); + this.UseDeltaCompression.Name = "UseDeltaCompression"; + this.UseDeltaCompression.Size = new System.Drawing.Size(332, 17); + this.UseDeltaCompression.TabIndex = 5; + this.UseDeltaCompression.Text = "Use delta compression (economizes buffer usage at cost of CPU)"; + this.UseDeltaCompression.UseVisualStyleBackColor = true; + this.UseDeltaCompression.CheckedChanged += new System.EventHandler(this.UseDeltaCompression_CheckedChanged); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 17); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(81, 13); + this.label1.TabIndex = 5; + this.label1.Text = "Savestate Size:"; + // + // StateSizeLabel + // + this.StateSizeLabel.AutoSize = true; + this.StateSizeLabel.Location = new System.Drawing.Point(92, 17); + this.StateSizeLabel.Name = "StateSizeLabel"; + this.StateSizeLabel.Size = new System.Drawing.Size(30, 13); + this.StateSizeLabel.TabIndex = 6; + this.StateSizeLabel.Text = "0 KB"; + // + // MediumStateTrackbar + // + this.MediumStateTrackbar.LargeChange = 256; + this.MediumStateTrackbar.Location = new System.Drawing.Point(67, 22); + this.MediumStateTrackbar.Maximum = 4096; + this.MediumStateTrackbar.Minimum = 1; + this.MediumStateTrackbar.Name = "MediumStateTrackbar"; + this.MediumStateTrackbar.Size = new System.Drawing.Size(186, 45); + this.MediumStateTrackbar.TabIndex = 7; + this.MediumStateTrackbar.TickFrequency = 256; + this.MediumStateTrackbar.Value = 1; + this.MediumStateTrackbar.ValueChanged += new System.EventHandler(this.MediumStateTrackbar_ValueChanged); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.LargeStateUpDown); + this.groupBox2.Controls.Add(this.MediumStateUpDown); + this.groupBox2.Controls.Add(this.LargeStateSizeLabel); + this.groupBox2.Controls.Add(this.label5); + this.groupBox2.Controls.Add(this.LargeStateTrackbar); + this.groupBox2.Controls.Add(this.MediumStateSizeLabel); + this.groupBox2.Controls.Add(this.label2); + this.groupBox2.Controls.Add(this.MediumStateTrackbar); + this.groupBox2.Location = new System.Drawing.Point(12, 387); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(371, 105); + this.groupBox2.TabIndex = 8; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "State Size Definition"; + // + // LargeStateUpDown + // + this.LargeStateUpDown.Location = new System.Drawing.Point(259, 67); + this.LargeStateUpDown.Maximum = new decimal(new int[] { 16384, 0, 0, 0}); - this.LargeStateUpDown.Minimum = new decimal(new int[] { + this.LargeStateUpDown.Minimum = new decimal(new int[] { 256, 0, 0, 0}); - this.LargeStateUpDown.Name = "LargeStateUpDown"; - this.LargeStateUpDown.Size = new System.Drawing.Size(52, 20); - this.LargeStateUpDown.TabIndex = 14; - this.LargeStateUpDown.Value = new decimal(new int[] { + this.LargeStateUpDown.Name = "LargeStateUpDown"; + this.LargeStateUpDown.Size = new System.Drawing.Size(52, 20); + this.LargeStateUpDown.TabIndex = 14; + this.LargeStateUpDown.Value = new decimal(new int[] { 256, 0, 0, 0}); - this.LargeStateUpDown.ValueChanged += new System.EventHandler(this.LargeStateUpDown_ValueChanged); - // - // MediumStateUpDown - // - this.MediumStateUpDown.Location = new System.Drawing.Point(259, 31); - this.MediumStateUpDown.Maximum = new decimal(new int[] { + this.LargeStateUpDown.ValueChanged += new System.EventHandler(this.LargeStateUpDown_ValueChanged); + // + // MediumStateUpDown + // + this.MediumStateUpDown.Location = new System.Drawing.Point(259, 31); + this.MediumStateUpDown.Maximum = new decimal(new int[] { 4096, 0, 0, 0}); - this.MediumStateUpDown.Minimum = new decimal(new int[] { + this.MediumStateUpDown.Minimum = new decimal(new int[] { 1, 0, 0, 0}); - this.MediumStateUpDown.Name = "MediumStateUpDown"; - this.MediumStateUpDown.Size = new System.Drawing.Size(52, 20); - this.MediumStateUpDown.TabIndex = 13; - this.MediumStateUpDown.Value = new decimal(new int[] { + this.MediumStateUpDown.Name = "MediumStateUpDown"; + this.MediumStateUpDown.Size = new System.Drawing.Size(52, 20); + this.MediumStateUpDown.TabIndex = 13; + this.MediumStateUpDown.Value = new decimal(new int[] { 1, 0, 0, 0}); - this.MediumStateUpDown.ValueChanged += new System.EventHandler(this.MediumStateUpDown_ValueChanged); - // - // LargeStateSizeLabel - // - this.LargeStateSizeLabel.AutoSize = true; - this.LargeStateSizeLabel.Location = new System.Drawing.Point(312, 71); - this.LargeStateSizeLabel.Name = "LargeStateSizeLabel"; - this.LargeStateSizeLabel.Size = new System.Drawing.Size(21, 13); - this.LargeStateSizeLabel.TabIndex = 12; - this.LargeStateSizeLabel.Text = "KB"; - // - // label5 - // - this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(27, 63); - this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(34, 13); - this.label5.TabIndex = 11; - this.label5.Text = "Large"; - // - // LargeStateTrackbar - // - this.LargeStateTrackbar.LargeChange = 1024; - this.LargeStateTrackbar.Location = new System.Drawing.Point(67, 58); - this.LargeStateTrackbar.Maximum = 16384; - this.LargeStateTrackbar.Minimum = 256; - this.LargeStateTrackbar.Name = "LargeStateTrackbar"; - this.LargeStateTrackbar.Size = new System.Drawing.Size(186, 42); - this.LargeStateTrackbar.TabIndex = 10; - this.LargeStateTrackbar.TickFrequency = 1024; - this.LargeStateTrackbar.Value = 256; - this.LargeStateTrackbar.ValueChanged += new System.EventHandler(this.LargeStateTrackbar_ValueChanged); - // - // MediumStateSizeLabel - // - this.MediumStateSizeLabel.AutoSize = true; - this.MediumStateSizeLabel.Location = new System.Drawing.Point(313, 35); - this.MediumStateSizeLabel.Name = "MediumStateSizeLabel"; - this.MediumStateSizeLabel.Size = new System.Drawing.Size(21, 13); - this.MediumStateSizeLabel.TabIndex = 9; - this.MediumStateSizeLabel.Text = "KB"; - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(18, 31); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(44, 13); - this.label2.TabIndex = 8; - this.label2.Text = "Medium"; - // - // groupBox3 - // - this.groupBox3.Controls.Add(this.label19); - this.groupBox3.Controls.Add(this.RewindSpeedNumeric); - this.groupBox3.Controls.Add(this.label18); - this.groupBox3.Controls.Add(this.label17); - this.groupBox3.Controls.Add(this.RewindIsThreadedCheckbox); - this.groupBox3.Controls.Add(this.label4); - this.groupBox3.Controls.Add(this.BufferSizeUpDown); - this.groupBox3.Controls.Add(this.label3); - this.groupBox3.Controls.Add(this.DiskBufferCheckbox); - this.groupBox3.Controls.Add(this.UseDeltaCompression); - this.groupBox3.Location = new System.Drawing.Point(12, 214); - this.groupBox3.Name = "groupBox3"; - this.groupBox3.Size = new System.Drawing.Size(371, 167); - this.groupBox3.TabIndex = 9; - this.groupBox3.TabStop = false; - this.groupBox3.Text = "Rewind Options"; - // - // label19 - // - this.label19.AutoSize = true; - this.label19.Location = new System.Drawing.Point(128, 21); - this.label19.Name = "label19"; - this.label19.Size = new System.Drawing.Size(12, 13); - this.label19.TabIndex = 2; - this.label19.Text = "x"; - // - // RewindSpeedNumeric - // - this.RewindSpeedNumeric.Location = new System.Drawing.Point(90, 19); - this.RewindSpeedNumeric.Maximum = new decimal(new int[] { + this.MediumStateUpDown.ValueChanged += new System.EventHandler(this.MediumStateUpDown_ValueChanged); + // + // LargeStateSizeLabel + // + this.LargeStateSizeLabel.AutoSize = true; + this.LargeStateSizeLabel.Location = new System.Drawing.Point(312, 71); + this.LargeStateSizeLabel.Name = "LargeStateSizeLabel"; + this.LargeStateSizeLabel.Size = new System.Drawing.Size(21, 13); + this.LargeStateSizeLabel.TabIndex = 12; + this.LargeStateSizeLabel.Text = "KB"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(27, 63); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(34, 13); + this.label5.TabIndex = 11; + this.label5.Text = "Large"; + // + // LargeStateTrackbar + // + this.LargeStateTrackbar.LargeChange = 1024; + this.LargeStateTrackbar.Location = new System.Drawing.Point(67, 58); + this.LargeStateTrackbar.Maximum = 16384; + this.LargeStateTrackbar.Minimum = 256; + this.LargeStateTrackbar.Name = "LargeStateTrackbar"; + this.LargeStateTrackbar.Size = new System.Drawing.Size(186, 45); + this.LargeStateTrackbar.TabIndex = 10; + this.LargeStateTrackbar.TickFrequency = 1024; + this.LargeStateTrackbar.Value = 256; + this.LargeStateTrackbar.ValueChanged += new System.EventHandler(this.LargeStateTrackbar_ValueChanged); + // + // MediumStateSizeLabel + // + this.MediumStateSizeLabel.AutoSize = true; + this.MediumStateSizeLabel.Location = new System.Drawing.Point(313, 35); + this.MediumStateSizeLabel.Name = "MediumStateSizeLabel"; + this.MediumStateSizeLabel.Size = new System.Drawing.Size(21, 13); + this.MediumStateSizeLabel.TabIndex = 9; + this.MediumStateSizeLabel.Text = "KB"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(18, 31); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(44, 13); + this.label2.TabIndex = 8; + this.label2.Text = "Medium"; + // + // groupBox3 + // + this.groupBox3.Controls.Add(this.label19); + this.groupBox3.Controls.Add(this.RewindSpeedNumeric); + this.groupBox3.Controls.Add(this.label18); + this.groupBox3.Controls.Add(this.label17); + this.groupBox3.Controls.Add(this.RewindIsThreadedCheckbox); + this.groupBox3.Controls.Add(this.label4); + this.groupBox3.Controls.Add(this.BufferSizeUpDown); + this.groupBox3.Controls.Add(this.label3); + this.groupBox3.Controls.Add(this.DiskBufferCheckbox); + this.groupBox3.Controls.Add(this.UseDeltaCompression); + this.groupBox3.Location = new System.Drawing.Point(12, 214); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Size = new System.Drawing.Size(371, 167); + this.groupBox3.TabIndex = 9; + this.groupBox3.TabStop = false; + this.groupBox3.Text = "Rewind Options"; + // + // label19 + // + this.label19.AutoSize = true; + this.label19.Location = new System.Drawing.Point(128, 21); + this.label19.Name = "label19"; + this.label19.Size = new System.Drawing.Size(12, 13); + this.label19.TabIndex = 2; + this.label19.Text = "x"; + // + // RewindSpeedNumeric + // + this.RewindSpeedNumeric.Location = new System.Drawing.Point(90, 19); + this.RewindSpeedNumeric.Maximum = new decimal(new int[] { 4, 0, 0, 0}); - this.RewindSpeedNumeric.Minimum = new decimal(new int[] { + this.RewindSpeedNumeric.Minimum = new decimal(new int[] { 1, 0, 0, 0}); - this.RewindSpeedNumeric.Name = "RewindSpeedNumeric"; - this.RewindSpeedNumeric.Size = new System.Drawing.Size(36, 20); - this.RewindSpeedNumeric.TabIndex = 1; - this.RewindSpeedNumeric.Value = new decimal(new int[] { + this.RewindSpeedNumeric.Name = "RewindSpeedNumeric"; + this.RewindSpeedNumeric.Size = new System.Drawing.Size(36, 20); + this.RewindSpeedNumeric.TabIndex = 1; + this.RewindSpeedNumeric.Value = new decimal(new int[] { 1, 0, 0, 0}); - // - // label18 - // - this.label18.AutoSize = true; - this.label18.Location = new System.Drawing.Point(6, 21); - this.label18.Name = "label18"; - this.label18.Size = new System.Drawing.Size(78, 13); - this.label18.TabIndex = 0; - this.label18.Text = "Rewind speed:"; - // - // label17 - // - this.label17.AutoSize = true; - this.label17.Location = new System.Drawing.Point(6, 47); - this.label17.Name = "label17"; - this.label17.Size = new System.Drawing.Size(278, 13); - this.label17.TabIndex = 3; - this.label17.Text = "These options affect rewind performance in various ways:"; - // - // RewindIsThreadedCheckbox - // - this.RewindIsThreadedCheckbox.AutoSize = true; - this.RewindIsThreadedCheckbox.Location = new System.Drawing.Point(16, 112); - this.RewindIsThreadedCheckbox.Name = "RewindIsThreadedCheckbox"; - this.RewindIsThreadedCheckbox.Size = new System.Drawing.Size(151, 17); - this.RewindIsThreadedCheckbox.TabIndex = 6; - this.RewindIsThreadedCheckbox.Text = "Use additional CPU thread"; - this.toolTip1.SetToolTip(this.RewindIsThreadedCheckbox, "This doesn\'t always speed things up... that\'s why it\'s an option."); - this.RewindIsThreadedCheckbox.UseVisualStyleBackColor = true; - // - // label4 - // - this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(149, 137); - this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(23, 13); - this.label4.TabIndex = 9; - this.label4.Text = "MB"; - // - // BufferSizeUpDown - // - this.BufferSizeUpDown.Location = new System.Drawing.Point(93, 135); - this.BufferSizeUpDown.Maximum = new decimal(new int[] { + // + // label18 + // + this.label18.AutoSize = true; + this.label18.Location = new System.Drawing.Point(6, 21); + this.label18.Name = "label18"; + this.label18.Size = new System.Drawing.Size(78, 13); + this.label18.TabIndex = 0; + this.label18.Text = "Rewind speed:"; + // + // label17 + // + this.label17.AutoSize = true; + this.label17.Location = new System.Drawing.Point(6, 47); + this.label17.Name = "label17"; + this.label17.Size = new System.Drawing.Size(278, 13); + this.label17.TabIndex = 3; + this.label17.Text = "These options affect rewind performance in various ways:"; + // + // RewindIsThreadedCheckbox + // + this.RewindIsThreadedCheckbox.AutoSize = true; + this.RewindIsThreadedCheckbox.Location = new System.Drawing.Point(16, 112); + this.RewindIsThreadedCheckbox.Name = "RewindIsThreadedCheckbox"; + this.RewindIsThreadedCheckbox.Size = new System.Drawing.Size(151, 17); + this.RewindIsThreadedCheckbox.TabIndex = 6; + this.RewindIsThreadedCheckbox.Text = "Use additional CPU thread"; + this.toolTip1.SetToolTip(this.RewindIsThreadedCheckbox, "This doesn\'t always speed things up... that\'s why it\'s an option."); + this.RewindIsThreadedCheckbox.UseVisualStyleBackColor = true; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(149, 137); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(23, 13); + this.label4.TabIndex = 9; + this.label4.Text = "MB"; + // + // BufferSizeUpDown + // + this.BufferSizeUpDown.Location = new System.Drawing.Point(93, 135); + this.BufferSizeUpDown.Maximum = new decimal(new int[] { 32768, 0, 0, 0}); - this.BufferSizeUpDown.Minimum = new decimal(new int[] { - 1, + this.BufferSizeUpDown.Minimum = new decimal(new int[] { + 50, 0, 0, 0}); - this.BufferSizeUpDown.Name = "BufferSizeUpDown"; - this.BufferSizeUpDown.Size = new System.Drawing.Size(52, 20); - this.BufferSizeUpDown.TabIndex = 8; - this.BufferSizeUpDown.Value = new decimal(new int[] { - 1, + this.BufferSizeUpDown.Name = "BufferSizeUpDown"; + this.BufferSizeUpDown.Size = new System.Drawing.Size(52, 20); + this.BufferSizeUpDown.TabIndex = 8; + this.BufferSizeUpDown.Value = new decimal(new int[] { + 50, 0, 0, 0}); - this.BufferSizeUpDown.ValueChanged += new System.EventHandler(this.BufferSizeUpDown_ValueChanged); - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(6, 137); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(81, 13); - this.label3.TabIndex = 7; - this.label3.Text = "Max buffer size:"; - // - // DiskBufferCheckbox - // - this.DiskBufferCheckbox.AutoSize = true; - this.DiskBufferCheckbox.Location = new System.Drawing.Point(16, 67); - this.DiskBufferCheckbox.Name = "DiskBufferCheckbox"; - this.DiskBufferCheckbox.Size = new System.Drawing.Size(188, 17); - this.DiskBufferCheckbox.TabIndex = 4; - this.DiskBufferCheckbox.Text = "Use disk for buffer instead of RAM"; - this.toolTip1.SetToolTip(this.DiskBufferCheckbox, "To support a longer rewind buffer, you can choose to have it stored on your disk." + + this.BufferSizeUpDown.ValueChanged += new System.EventHandler(this.BufferSizeUpDown_ValueChanged); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(6, 137); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(81, 13); + this.label3.TabIndex = 7; + this.label3.Text = "Max buffer size:"; + // + // DiskBufferCheckbox + // + this.DiskBufferCheckbox.AutoSize = true; + this.DiskBufferCheckbox.Location = new System.Drawing.Point(16, 67); + this.DiskBufferCheckbox.Name = "DiskBufferCheckbox"; + this.DiskBufferCheckbox.Size = new System.Drawing.Size(188, 17); + this.DiskBufferCheckbox.TabIndex = 4; + this.DiskBufferCheckbox.Text = "Use disk for buffer instead of RAM"; + this.toolTip1.SetToolTip(this.DiskBufferCheckbox, "To support a longer rewind buffer, you can choose to have it stored on your disk." + " Where, precisely? Not sure. Probably %TEMP%"); - this.DiskBufferCheckbox.UseVisualStyleBackColor = true; - // - // label6 - // - this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(67, 48); - this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(26, 13); - this.label6.TabIndex = 10; - this.label6.Text = "Full:"; - // - // FullnessLabel - // - this.FullnessLabel.AutoSize = true; - this.FullnessLabel.Location = new System.Drawing.Point(94, 48); - this.FullnessLabel.Name = "FullnessLabel"; - this.FullnessLabel.Size = new System.Drawing.Size(21, 13); - this.FullnessLabel.TabIndex = 11; - this.FullnessLabel.Text = "0%"; - // - // groupBox4 - // - this.groupBox4.Controls.Add(this.EstTimeLabel); - this.groupBox4.Controls.Add(this.label11); - this.groupBox4.Controls.Add(this.AverageStoredStateSizeLabel); - this.groupBox4.Controls.Add(this.label9); - this.groupBox4.Controls.Add(this.ApproxFramesLabel); - this.groupBox4.Controls.Add(this.label8); - this.groupBox4.Controls.Add(this.RewindFramesUsedLabel); - this.groupBox4.Controls.Add(this.label7); - this.groupBox4.Controls.Add(this.label1); - this.groupBox4.Controls.Add(this.FullnessLabel); - this.groupBox4.Controls.Add(this.label6); - this.groupBox4.Controls.Add(this.StateSizeLabel); - this.groupBox4.Location = new System.Drawing.Point(12, 12); - this.groupBox4.Name = "groupBox4"; - this.groupBox4.Size = new System.Drawing.Size(371, 72); - this.groupBox4.TabIndex = 12; - this.groupBox4.TabStop = false; - this.groupBox4.Text = "Current Statistics"; - // - // EstTimeLabel - // - this.EstTimeLabel.AutoSize = true; - this.EstTimeLabel.Location = new System.Drawing.Point(273, 48); - this.EstTimeLabel.Name = "EstTimeLabel"; - this.EstTimeLabel.Size = new System.Drawing.Size(32, 13); - this.EstTimeLabel.TabIndex = 19; - this.EstTimeLabel.Text = "0 min"; - // - // label11 - // - this.label11.AutoSize = true; - this.label11.Location = new System.Drawing.Point(221, 48); - this.label11.Name = "label11"; - this.label11.Size = new System.Drawing.Size(54, 13); - this.label11.TabIndex = 18; - this.label11.Text = "Est. Time:"; - // - // AverageStoredStateSizeLabel - // - this.AverageStoredStateSizeLabel.AutoSize = true; - this.AverageStoredStateSizeLabel.Location = new System.Drawing.Point(273, 16); - this.AverageStoredStateSizeLabel.Name = "AverageStoredStateSizeLabel"; - this.AverageStoredStateSizeLabel.Size = new System.Drawing.Size(41, 13); - this.AverageStoredStateSizeLabel.TabIndex = 17; - this.AverageStoredStateSizeLabel.Text = "0 bytes"; - // - // label9 - // - this.label9.AutoSize = true; - this.label9.Location = new System.Drawing.Point(161, 16); - this.label9.Name = "label9"; - this.label9.Size = new System.Drawing.Size(114, 13); - this.label9.TabIndex = 16; - this.label9.Text = "Avg Stored State Size:"; - // - // ApproxFramesLabel - // - this.ApproxFramesLabel.AutoSize = true; - this.ApproxFramesLabel.Location = new System.Drawing.Point(273, 32); - this.ApproxFramesLabel.Name = "ApproxFramesLabel"; - this.ApproxFramesLabel.Size = new System.Drawing.Size(47, 13); - this.ApproxFramesLabel.TabIndex = 15; - this.ApproxFramesLabel.Text = "0 frames"; - // - // label8 - // - this.label8.AutoSize = true; - this.label8.Location = new System.Drawing.Point(209, 32); - this.label8.Name = "label8"; - this.label8.Size = new System.Drawing.Size(66, 13); - this.label8.TabIndex = 14; - this.label8.Text = "Est. storage:"; - // - // RewindFramesUsedLabel - // - this.RewindFramesUsedLabel.AutoSize = true; - this.RewindFramesUsedLabel.Location = new System.Drawing.Point(94, 32); - this.RewindFramesUsedLabel.Name = "RewindFramesUsedLabel"; - this.RewindFramesUsedLabel.Size = new System.Drawing.Size(13, 13); - this.RewindFramesUsedLabel.TabIndex = 13; - this.RewindFramesUsedLabel.Text = "0"; - // - // label7 - // - this.label7.AutoSize = true; - this.label7.Location = new System.Drawing.Point(15, 32); - this.label7.Name = "label7"; - this.label7.Size = new System.Drawing.Size(78, 13); - this.label7.TabIndex = 12; - this.label7.Text = "Frames Stored:"; - // - // groupBox6 - // - this.groupBox6.Controls.Add(this.rbStatesText); - this.groupBox6.Controls.Add(this.rbStatesBinary); - this.groupBox6.Controls.Add(this.rbStatesDefault); - this.groupBox6.Location = new System.Drawing.Point(22, 78); - this.groupBox6.Name = "groupBox6"; - this.groupBox6.Size = new System.Drawing.Size(215, 48); - this.groupBox6.TabIndex = 0; - this.groupBox6.TabStop = false; - this.groupBox6.Text = "Type"; - // - // rbStatesText - // - this.rbStatesText.AutoSize = true; - this.rbStatesText.Location = new System.Drawing.Point(163, 18); - this.rbStatesText.Name = "rbStatesText"; - this.rbStatesText.Size = new System.Drawing.Size(46, 17); - this.rbStatesText.TabIndex = 1; - this.rbStatesText.TabStop = true; - this.rbStatesText.Text = "Text"; - this.rbStatesText.UseVisualStyleBackColor = true; - // - // rbStatesBinary - // - this.rbStatesBinary.AutoSize = true; - this.rbStatesBinary.Location = new System.Drawing.Point(88, 18); - this.rbStatesBinary.Name = "rbStatesBinary"; - this.rbStatesBinary.Size = new System.Drawing.Size(54, 17); - this.rbStatesBinary.TabIndex = 1; - this.rbStatesBinary.TabStop = true; - this.rbStatesBinary.Text = "Binary"; - this.rbStatesBinary.UseVisualStyleBackColor = true; - // - // rbStatesDefault - // - this.rbStatesDefault.AutoSize = true; - this.rbStatesDefault.Location = new System.Drawing.Point(6, 18); - this.rbStatesDefault.Name = "rbStatesDefault"; - this.rbStatesDefault.Size = new System.Drawing.Size(59, 17); - this.rbStatesDefault.TabIndex = 0; - this.rbStatesDefault.TabStop = true; - this.rbStatesDefault.Text = "Default"; - this.rbStatesDefault.UseVisualStyleBackColor = true; - // - // btnResetCompression - // - this.btnResetCompression.AutoSize = true; - this.btnResetCompression.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.reboot; - this.btnResetCompression.Location = new System.Drawing.Point(243, 34); - this.btnResetCompression.Name = "btnResetCompression"; - this.btnResetCompression.Size = new System.Drawing.Size(27, 27); - this.btnResetCompression.TabIndex = 23; - this.toolTip1.SetToolTip(this.btnResetCompression, "Reset to default"); - this.btnResetCompression.UseVisualStyleBackColor = true; - this.btnResetCompression.Click += new System.EventHandler(this.BtnResetCompression_Click); - // - // trackBarCompression - // - this.trackBarCompression.LargeChange = 1; - this.trackBarCompression.Location = new System.Drawing.Point(22, 37); - this.trackBarCompression.Maximum = 9; - this.trackBarCompression.Name = "trackBarCompression"; - this.trackBarCompression.Size = new System.Drawing.Size(157, 42); - this.trackBarCompression.TabIndex = 20; - this.toolTip1.SetToolTip(this.trackBarCompression, "0 = None; 9 = Maximum"); - this.trackBarCompression.Value = 1; - this.trackBarCompression.ValueChanged += new System.EventHandler(this.TrackBarCompression_ValueChanged); - // - // nudCompression - // - this.nudCompression.Location = new System.Drawing.Point(185, 37); - this.nudCompression.Maximum = new decimal(new int[] { + this.DiskBufferCheckbox.UseVisualStyleBackColor = true; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(67, 48); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(26, 13); + this.label6.TabIndex = 10; + this.label6.Text = "Full:"; + // + // FullnessLabel + // + this.FullnessLabel.AutoSize = true; + this.FullnessLabel.Location = new System.Drawing.Point(94, 48); + this.FullnessLabel.Name = "FullnessLabel"; + this.FullnessLabel.Size = new System.Drawing.Size(21, 13); + this.FullnessLabel.TabIndex = 11; + this.FullnessLabel.Text = "0%"; + // + // groupBox4 + // + this.groupBox4.Controls.Add(this.EstTimeLabel); + this.groupBox4.Controls.Add(this.label11); + this.groupBox4.Controls.Add(this.AverageStoredStateSizeLabel); + this.groupBox4.Controls.Add(this.label9); + this.groupBox4.Controls.Add(this.ApproxFramesLabel); + this.groupBox4.Controls.Add(this.label8); + this.groupBox4.Controls.Add(this.RewindFramesUsedLabel); + this.groupBox4.Controls.Add(this.label7); + this.groupBox4.Controls.Add(this.label1); + this.groupBox4.Controls.Add(this.FullnessLabel); + this.groupBox4.Controls.Add(this.label6); + this.groupBox4.Controls.Add(this.StateSizeLabel); + this.groupBox4.Location = new System.Drawing.Point(12, 12); + this.groupBox4.Name = "groupBox4"; + this.groupBox4.Size = new System.Drawing.Size(371, 72); + this.groupBox4.TabIndex = 12; + this.groupBox4.TabStop = false; + this.groupBox4.Text = "Current Statistics"; + // + // EstTimeLabel + // + this.EstTimeLabel.AutoSize = true; + this.EstTimeLabel.Location = new System.Drawing.Point(273, 48); + this.EstTimeLabel.Name = "EstTimeLabel"; + this.EstTimeLabel.Size = new System.Drawing.Size(32, 13); + this.EstTimeLabel.TabIndex = 19; + this.EstTimeLabel.Text = "0 min"; + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(221, 48); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(54, 13); + this.label11.TabIndex = 18; + this.label11.Text = "Est. Time:"; + // + // AverageStoredStateSizeLabel + // + this.AverageStoredStateSizeLabel.AutoSize = true; + this.AverageStoredStateSizeLabel.Location = new System.Drawing.Point(273, 16); + this.AverageStoredStateSizeLabel.Name = "AverageStoredStateSizeLabel"; + this.AverageStoredStateSizeLabel.Size = new System.Drawing.Size(41, 13); + this.AverageStoredStateSizeLabel.TabIndex = 17; + this.AverageStoredStateSizeLabel.Text = "0 bytes"; + // + // label9 + // + this.label9.AutoSize = true; + this.label9.Location = new System.Drawing.Point(161, 16); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(114, 13); + this.label9.TabIndex = 16; + this.label9.Text = "Avg Stored State Size:"; + // + // ApproxFramesLabel + // + this.ApproxFramesLabel.AutoSize = true; + this.ApproxFramesLabel.Location = new System.Drawing.Point(273, 32); + this.ApproxFramesLabel.Name = "ApproxFramesLabel"; + this.ApproxFramesLabel.Size = new System.Drawing.Size(47, 13); + this.ApproxFramesLabel.TabIndex = 15; + this.ApproxFramesLabel.Text = "0 frames"; + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(209, 32); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(66, 13); + this.label8.TabIndex = 14; + this.label8.Text = "Est. storage:"; + // + // RewindFramesUsedLabel + // + this.RewindFramesUsedLabel.AutoSize = true; + this.RewindFramesUsedLabel.Location = new System.Drawing.Point(94, 32); + this.RewindFramesUsedLabel.Name = "RewindFramesUsedLabel"; + this.RewindFramesUsedLabel.Size = new System.Drawing.Size(13, 13); + this.RewindFramesUsedLabel.TabIndex = 13; + this.RewindFramesUsedLabel.Text = "0"; + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(15, 32); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(78, 13); + this.label7.TabIndex = 12; + this.label7.Text = "Frames Stored:"; + // + // groupBox6 + // + this.groupBox6.Controls.Add(this.rbStatesText); + this.groupBox6.Controls.Add(this.rbStatesBinary); + this.groupBox6.Controls.Add(this.rbStatesDefault); + this.groupBox6.Location = new System.Drawing.Point(22, 78); + this.groupBox6.Name = "groupBox6"; + this.groupBox6.Size = new System.Drawing.Size(215, 48); + this.groupBox6.TabIndex = 0; + this.groupBox6.TabStop = false; + this.groupBox6.Text = "Type"; + // + // rbStatesText + // + this.rbStatesText.AutoSize = true; + this.rbStatesText.Location = new System.Drawing.Point(163, 18); + this.rbStatesText.Name = "rbStatesText"; + this.rbStatesText.Size = new System.Drawing.Size(46, 17); + this.rbStatesText.TabIndex = 1; + this.rbStatesText.TabStop = true; + this.rbStatesText.Text = "Text"; + this.rbStatesText.UseVisualStyleBackColor = true; + // + // rbStatesBinary + // + this.rbStatesBinary.AutoSize = true; + this.rbStatesBinary.Location = new System.Drawing.Point(88, 18); + this.rbStatesBinary.Name = "rbStatesBinary"; + this.rbStatesBinary.Size = new System.Drawing.Size(54, 17); + this.rbStatesBinary.TabIndex = 1; + this.rbStatesBinary.TabStop = true; + this.rbStatesBinary.Text = "Binary"; + this.rbStatesBinary.UseVisualStyleBackColor = true; + // + // rbStatesDefault + // + this.rbStatesDefault.AutoSize = true; + this.rbStatesDefault.Location = new System.Drawing.Point(6, 18); + this.rbStatesDefault.Name = "rbStatesDefault"; + this.rbStatesDefault.Size = new System.Drawing.Size(59, 17); + this.rbStatesDefault.TabIndex = 0; + this.rbStatesDefault.TabStop = true; + this.rbStatesDefault.Text = "Default"; + this.rbStatesDefault.UseVisualStyleBackColor = true; + // + // btnResetCompression + // + this.btnResetCompression.AutoSize = true; + this.btnResetCompression.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.reboot; + this.btnResetCompression.Location = new System.Drawing.Point(243, 34); + this.btnResetCompression.Name = "btnResetCompression"; + this.btnResetCompression.Size = new System.Drawing.Size(27, 27); + this.btnResetCompression.TabIndex = 23; + this.toolTip1.SetToolTip(this.btnResetCompression, "Reset to default"); + this.btnResetCompression.UseVisualStyleBackColor = true; + this.btnResetCompression.Click += new System.EventHandler(this.BtnResetCompression_Click); + // + // trackBarCompression + // + this.trackBarCompression.LargeChange = 1; + this.trackBarCompression.Location = new System.Drawing.Point(22, 37); + this.trackBarCompression.Maximum = 9; + this.trackBarCompression.Name = "trackBarCompression"; + this.trackBarCompression.Size = new System.Drawing.Size(157, 45); + this.trackBarCompression.TabIndex = 20; + this.toolTip1.SetToolTip(this.trackBarCompression, "0 = None; 9 = Maximum"); + this.trackBarCompression.Value = 1; + this.trackBarCompression.ValueChanged += new System.EventHandler(this.TrackBarCompression_ValueChanged); + // + // nudCompression + // + this.nudCompression.Location = new System.Drawing.Point(185, 37); + this.nudCompression.Maximum = new decimal(new int[] { 9, 0, 0, 0}); - this.nudCompression.Name = "nudCompression"; - this.nudCompression.Size = new System.Drawing.Size(52, 20); - this.nudCompression.TabIndex = 22; - this.nudCompression.Value = new decimal(new int[] { + this.nudCompression.Name = "nudCompression"; + this.nudCompression.Size = new System.Drawing.Size(52, 20); + this.nudCompression.TabIndex = 22; + this.nudCompression.Value = new decimal(new int[] { 1, 0, 0, 0}); - this.nudCompression.ValueChanged += new System.EventHandler(this.NudCompression_ValueChanged); - // - // groupBox7 - // - this.groupBox7.Controls.Add(this.label20); - this.groupBox7.Controls.Add(this.KbLabel); - this.groupBox7.Controls.Add(this.BigScreenshotNumeric); - this.groupBox7.Controls.Add(this.LowResLargeScreenshotsCheckbox); - this.groupBox7.Controls.Add(this.label13); - this.groupBox7.Controls.Add(this.label14); - this.groupBox7.Controls.Add(this.ScreenshotInStatesCheckbox); - this.groupBox7.Controls.Add(this.label15); - this.groupBox7.Controls.Add(this.label16); - this.groupBox7.Controls.Add(this.BackupSavestatesCheckbox); - this.groupBox7.Controls.Add(this.label12); - this.groupBox7.Controls.Add(this.groupBox6); - this.groupBox7.Controls.Add(this.btnResetCompression); - this.groupBox7.Controls.Add(this.nudCompression); - this.groupBox7.Controls.Add(this.trackBarCompression); - this.groupBox7.Location = new System.Drawing.Point(389, 12); - this.groupBox7.Name = "groupBox7"; - this.groupBox7.Size = new System.Drawing.Size(342, 408); - this.groupBox7.TabIndex = 2; - this.groupBox7.TabStop = false; - this.groupBox7.Text = "Savestate Options"; - // - // label20 - // - this.label20.AutoSize = true; - this.label20.Location = new System.Drawing.Point(21, 291); - this.label20.Name = "label20"; - this.label20.Size = new System.Drawing.Size(315, 13); - this.label20.TabIndex = 34; - this.label20.Text = "Use a low resolution screenshot for better save/load performance"; - // - // KbLabel - // - this.KbLabel.AutoSize = true; - this.KbLabel.Location = new System.Drawing.Point(276, 271); - this.KbLabel.Name = "KbLabel"; - this.KbLabel.Size = new System.Drawing.Size(21, 13); - this.KbLabel.TabIndex = 33; - this.KbLabel.Text = "KB"; - // - // BigScreenshotNumeric - // - this.BigScreenshotNumeric.Location = new System.Drawing.Point(212, 267); - this.BigScreenshotNumeric.Maximum = new decimal(new int[] { + this.nudCompression.ValueChanged += new System.EventHandler(this.NudCompression_ValueChanged); + // + // groupBox7 + // + this.groupBox7.Controls.Add(this.label20); + this.groupBox7.Controls.Add(this.KbLabel); + this.groupBox7.Controls.Add(this.BigScreenshotNumeric); + this.groupBox7.Controls.Add(this.LowResLargeScreenshotsCheckbox); + this.groupBox7.Controls.Add(this.label13); + this.groupBox7.Controls.Add(this.label14); + this.groupBox7.Controls.Add(this.ScreenshotInStatesCheckbox); + this.groupBox7.Controls.Add(this.label15); + this.groupBox7.Controls.Add(this.label16); + this.groupBox7.Controls.Add(this.BackupSavestatesCheckbox); + this.groupBox7.Controls.Add(this.label12); + this.groupBox7.Controls.Add(this.groupBox6); + this.groupBox7.Controls.Add(this.btnResetCompression); + this.groupBox7.Controls.Add(this.nudCompression); + this.groupBox7.Controls.Add(this.trackBarCompression); + this.groupBox7.Location = new System.Drawing.Point(389, 12); + this.groupBox7.Name = "groupBox7"; + this.groupBox7.Size = new System.Drawing.Size(342, 408); + this.groupBox7.TabIndex = 2; + this.groupBox7.TabStop = false; + this.groupBox7.Text = "Savestate Options"; + // + // label20 + // + this.label20.AutoSize = true; + this.label20.Location = new System.Drawing.Point(21, 291); + this.label20.Name = "label20"; + this.label20.Size = new System.Drawing.Size(315, 13); + this.label20.TabIndex = 34; + this.label20.Text = "Use a low resolution screenshot for better save/load performance"; + // + // KbLabel + // + this.KbLabel.AutoSize = true; + this.KbLabel.Location = new System.Drawing.Point(276, 271); + this.KbLabel.Name = "KbLabel"; + this.KbLabel.Size = new System.Drawing.Size(21, 13); + this.KbLabel.TabIndex = 33; + this.KbLabel.Text = "KB"; + // + // BigScreenshotNumeric + // + this.BigScreenshotNumeric.Location = new System.Drawing.Point(212, 267); + this.BigScreenshotNumeric.Maximum = new decimal(new int[] { 8192, 0, 0, 0}); - this.BigScreenshotNumeric.Minimum = new decimal(new int[] { + this.BigScreenshotNumeric.Minimum = new decimal(new int[] { 1, 0, 0, 0}); - this.BigScreenshotNumeric.Name = "BigScreenshotNumeric"; - this.BigScreenshotNumeric.Size = new System.Drawing.Size(58, 20); - this.BigScreenshotNumeric.TabIndex = 32; - this.BigScreenshotNumeric.Value = new decimal(new int[] { + this.BigScreenshotNumeric.Name = "BigScreenshotNumeric"; + this.BigScreenshotNumeric.Size = new System.Drawing.Size(58, 20); + this.BigScreenshotNumeric.TabIndex = 32; + this.BigScreenshotNumeric.Value = new decimal(new int[] { 128, 0, 0, 0}); - // - // LowResLargeScreenshotsCheckbox - // - this.LowResLargeScreenshotsCheckbox.AutoSize = true; - this.LowResLargeScreenshotsCheckbox.Location = new System.Drawing.Point(21, 269); - this.LowResLargeScreenshotsCheckbox.Name = "LowResLargeScreenshotsCheckbox"; - this.LowResLargeScreenshotsCheckbox.Size = new System.Drawing.Size(195, 17); - this.LowResLargeScreenshotsCheckbox.TabIndex = 31; - this.LowResLargeScreenshotsCheckbox.Text = "Low Res Screenshots on buffers >="; - this.LowResLargeScreenshotsCheckbox.UseVisualStyleBackColor = true; - // - // label13 - // - this.label13.AutoSize = true; - this.label13.Location = new System.Drawing.Point(21, 235); - this.label13.Name = "label13"; - this.label13.Size = new System.Drawing.Size(186, 13); - this.label13.TabIndex = 30; - this.label13.Text = "black screen on the frame it is loaded."; - // - // label14 - // - this.label14.AutoSize = true; - this.label14.Location = new System.Drawing.Point(19, 221); - this.label14.Name = "label14"; - this.label14.Size = new System.Drawing.Size(290, 13); - this.label14.TabIndex = 29; - this.label14.Text = "Saves a screenshot and loads it on loadstate so there isn\'t a"; - // - // ScreenshotInStatesCheckbox - // - this.ScreenshotInStatesCheckbox.AutoSize = true; - this.ScreenshotInStatesCheckbox.Location = new System.Drawing.Point(22, 201); - this.ScreenshotInStatesCheckbox.Name = "ScreenshotInStatesCheckbox"; - this.ScreenshotInStatesCheckbox.Size = new System.Drawing.Size(180, 17); - this.ScreenshotInStatesCheckbox.TabIndex = 28; - this.ScreenshotInStatesCheckbox.Text = "Save a screenshot in savestates"; - this.ScreenshotInStatesCheckbox.UseVisualStyleBackColor = true; - this.ScreenshotInStatesCheckbox.CheckedChanged += new System.EventHandler(this.ScreenshotInStatesCheckbox_CheckedChanged); - // - // label15 - // - this.label15.AutoSize = true; - this.label15.Location = new System.Drawing.Point(39, 171); - this.label15.Name = "label15"; - this.label15.Size = new System.Drawing.Size(102, 13); - this.label15.TabIndex = 27; - this.label15.Text = "before overwriting it."; - // - // label16 - // - this.label16.AutoSize = true; - this.label16.Location = new System.Drawing.Point(39, 158); - this.label16.Name = "label16"; - this.label16.Size = new System.Drawing.Size(292, 13); - this.label16.TabIndex = 26; - this.label16.Text = "When set, the client will make a backup copy of a savestate"; - // - // BackupSavestatesCheckbox - // - this.BackupSavestatesCheckbox.AutoSize = true; - this.BackupSavestatesCheckbox.Location = new System.Drawing.Point(21, 138); - this.BackupSavestatesCheckbox.Name = "BackupSavestatesCheckbox"; - this.BackupSavestatesCheckbox.Size = new System.Drawing.Size(119, 17); - this.BackupSavestatesCheckbox.TabIndex = 25; - this.BackupSavestatesCheckbox.Text = "Backup Savestates"; - this.BackupSavestatesCheckbox.UseVisualStyleBackColor = true; - // - // label12 - // - this.label12.AutoSize = true; - this.label12.Location = new System.Drawing.Point(19, 21); - this.label12.Name = "label12"; - this.label12.Size = new System.Drawing.Size(96, 13); - this.label12.TabIndex = 24; - this.label12.Text = "Compression Level"; - // - // RewindConfig - // - this.AcceptButton = this.OK; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.Cancel; - this.ClientSize = new System.Drawing.Size(741, 505); - this.Controls.Add(this.groupBox7); - this.Controls.Add(this.groupBox4); - this.Controls.Add(this.groupBox3); - this.Controls.Add(this.groupBox2); - this.Controls.Add(this.groupBox1); - this.Controls.Add(this.Cancel); - this.Controls.Add(this.OK); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "RewindConfig"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Rewind & Savestate Cofiguration"; - this.Load += new System.EventHandler(this.RewindConfig_Load); - this.groupBox1.ResumeLayout(false); - this.groupBox1.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.LargeSavestateNumeric)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.MediumSavestateNumeric)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.SmallSavestateNumeric)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.MediumStateTrackbar)).EndInit(); - this.groupBox2.ResumeLayout(false); - this.groupBox2.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.LargeStateUpDown)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.MediumStateUpDown)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.LargeStateTrackbar)).EndInit(); - this.groupBox3.ResumeLayout(false); - this.groupBox3.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.RewindSpeedNumeric)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.BufferSizeUpDown)).EndInit(); - this.groupBox4.ResumeLayout(false); - this.groupBox4.PerformLayout(); - this.groupBox6.ResumeLayout(false); - this.groupBox6.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.trackBarCompression)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.nudCompression)).EndInit(); - this.groupBox7.ResumeLayout(false); - this.groupBox7.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.BigScreenshotNumeric)).EndInit(); - this.ResumeLayout(false); + // + // LowResLargeScreenshotsCheckbox + // + this.LowResLargeScreenshotsCheckbox.AutoSize = true; + this.LowResLargeScreenshotsCheckbox.Location = new System.Drawing.Point(21, 269); + this.LowResLargeScreenshotsCheckbox.Name = "LowResLargeScreenshotsCheckbox"; + this.LowResLargeScreenshotsCheckbox.Size = new System.Drawing.Size(195, 17); + this.LowResLargeScreenshotsCheckbox.TabIndex = 31; + this.LowResLargeScreenshotsCheckbox.Text = "Low Res Screenshots on buffers >="; + this.LowResLargeScreenshotsCheckbox.UseVisualStyleBackColor = true; + // + // label13 + // + this.label13.AutoSize = true; + this.label13.Location = new System.Drawing.Point(21, 235); + this.label13.Name = "label13"; + this.label13.Size = new System.Drawing.Size(186, 13); + this.label13.TabIndex = 30; + this.label13.Text = "black screen on the frame it is loaded."; + // + // label14 + // + this.label14.AutoSize = true; + this.label14.Location = new System.Drawing.Point(19, 221); + this.label14.Name = "label14"; + this.label14.Size = new System.Drawing.Size(290, 13); + this.label14.TabIndex = 29; + this.label14.Text = "Saves a screenshot and loads it on loadstate so there isn\'t a"; + // + // ScreenshotInStatesCheckbox + // + this.ScreenshotInStatesCheckbox.AutoSize = true; + this.ScreenshotInStatesCheckbox.Location = new System.Drawing.Point(22, 201); + this.ScreenshotInStatesCheckbox.Name = "ScreenshotInStatesCheckbox"; + this.ScreenshotInStatesCheckbox.Size = new System.Drawing.Size(180, 17); + this.ScreenshotInStatesCheckbox.TabIndex = 28; + this.ScreenshotInStatesCheckbox.Text = "Save a screenshot in savestates"; + this.ScreenshotInStatesCheckbox.UseVisualStyleBackColor = true; + this.ScreenshotInStatesCheckbox.CheckedChanged += new System.EventHandler(this.ScreenshotInStatesCheckbox_CheckedChanged); + // + // label15 + // + this.label15.AutoSize = true; + this.label15.Location = new System.Drawing.Point(39, 171); + this.label15.Name = "label15"; + this.label15.Size = new System.Drawing.Size(102, 13); + this.label15.TabIndex = 27; + this.label15.Text = "before overwriting it."; + // + // label16 + // + this.label16.AutoSize = true; + this.label16.Location = new System.Drawing.Point(39, 158); + this.label16.Name = "label16"; + this.label16.Size = new System.Drawing.Size(292, 13); + this.label16.TabIndex = 26; + this.label16.Text = "When set, the client will make a backup copy of a savestate"; + // + // BackupSavestatesCheckbox + // + this.BackupSavestatesCheckbox.AutoSize = true; + this.BackupSavestatesCheckbox.Location = new System.Drawing.Point(21, 138); + this.BackupSavestatesCheckbox.Name = "BackupSavestatesCheckbox"; + this.BackupSavestatesCheckbox.Size = new System.Drawing.Size(119, 17); + this.BackupSavestatesCheckbox.TabIndex = 25; + this.BackupSavestatesCheckbox.Text = "Backup Savestates"; + this.BackupSavestatesCheckbox.UseVisualStyleBackColor = true; + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Location = new System.Drawing.Point(19, 21); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(96, 13); + this.label12.TabIndex = 24; + this.label12.Text = "Compression Level"; + // + // RewindConfig + // + this.AcceptButton = this.OK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.Cancel; + this.ClientSize = new System.Drawing.Size(741, 505); + this.Controls.Add(this.groupBox7); + this.Controls.Add(this.groupBox4); + this.Controls.Add(this.groupBox3); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.Cancel); + this.Controls.Add(this.OK); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "RewindConfig"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Rewind & Savestate Cofiguration"; + this.Load += new System.EventHandler(this.RewindConfig_Load); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.LargeSavestateNumeric)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.MediumSavestateNumeric)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.SmallSavestateNumeric)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.MediumStateTrackbar)).EndInit(); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.LargeStateUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.MediumStateUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.LargeStateTrackbar)).EndInit(); + this.groupBox3.ResumeLayout(false); + this.groupBox3.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.RewindSpeedNumeric)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.BufferSizeUpDown)).EndInit(); + this.groupBox4.ResumeLayout(false); + this.groupBox4.PerformLayout(); + this.groupBox6.ResumeLayout(false); + this.groupBox6.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.trackBarCompression)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.nudCompression)).EndInit(); + this.groupBox7.ResumeLayout(false); + this.groupBox7.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.BigScreenshotNumeric)).EndInit(); + this.ResumeLayout(false); } diff --git a/BizHawk.Client.EmuHawk/config/RewindConfig.cs b/BizHawk.Client.EmuHawk/config/RewindConfig.cs index f347802d26..d99daf5456 100644 --- a/BizHawk.Client.EmuHawk/config/RewindConfig.cs +++ b/BizHawk.Client.EmuHawk/config/RewindConfig.cs @@ -36,7 +36,7 @@ namespace BizHawk.Client.EmuHawk DiskBufferCheckbox.Checked = Global.Config.Rewind_OnDisk; RewindIsThreadedCheckbox.Checked = Global.Config.Rewind_IsThreaded; _stateSize = Global.Emulator.AsStatable().SaveStateBinary().Length; - BufferSizeUpDown.Value = Global.Config.Rewind_BufferSize; + BufferSizeUpDown.Value = Math.Max(Global.Config.Rewind_BufferSize, BufferSizeUpDown.Minimum); _mediumStateSize = Global.Config.Rewind_MediumStateSize; _largeStateSize = Global.Config.Rewind_LargeStateSize; diff --git a/BizHawk.Client.EmuHawk/config/SNES/SNESOptions.Designer.cs b/BizHawk.Client.EmuHawk/config/SNES/SNESOptions.Designer.cs index 6a696d4ad7..79aede5cc9 100644 --- a/BizHawk.Client.EmuHawk/config/SNES/SNESOptions.Designer.cs +++ b/BizHawk.Client.EmuHawk/config/SNES/SNESOptions.Designer.cs @@ -28,191 +28,213 @@ /// private void InitializeComponent() { - this.btnOk = new System.Windows.Forms.Button(); - this.btnCancel = new System.Windows.Forms.Button(); - this.rbCompatibility = new System.Windows.Forms.RadioButton(); - this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.label2 = new System.Windows.Forms.Label(); - this.rbAccuracy = new System.Windows.Forms.RadioButton(); - this.rbPerformance = new System.Windows.Forms.RadioButton(); - this.cbDoubleSize = new System.Windows.Forms.CheckBox(); - this.lblDoubleSize = new System.Windows.Forms.Label(); - this.cbForceDeterminism = new System.Windows.Forms.CheckBox(); - this.label3 = new System.Windows.Forms.Label(); - this.radioButton1 = new System.Windows.Forms.RadioButton(); - this.cbCropSGBFrame = new System.Windows.Forms.CheckBox(); - this.groupBox1.SuspendLayout(); - this.SuspendLayout(); - // - // btnOk - // - this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnOk.Location = new System.Drawing.Point(136, 308); - this.btnOk.Name = "btnOk"; - this.btnOk.Size = new System.Drawing.Size(75, 23); - this.btnOk.TabIndex = 0; - this.btnOk.Text = "OK"; - this.btnOk.UseVisualStyleBackColor = true; - this.btnOk.Click += new System.EventHandler(this.BtnOk_Click); - // - // btnCancel - // - this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.btnCancel.Location = new System.Drawing.Point(217, 308); - this.btnCancel.Name = "btnCancel"; - this.btnCancel.Size = new System.Drawing.Size(75, 23); - this.btnCancel.TabIndex = 1; - this.btnCancel.Text = "Cancel"; - this.btnCancel.UseVisualStyleBackColor = true; - this.btnCancel.Click += new System.EventHandler(this.BtnCancel_Click); - // - // rbCompatibility - // - this.rbCompatibility.AutoSize = true; - this.rbCompatibility.Location = new System.Drawing.Point(6, 19); - this.rbCompatibility.Name = "rbCompatibility"; - this.rbCompatibility.Size = new System.Drawing.Size(202, 17); - this.rbCompatibility.TabIndex = 2; - this.rbCompatibility.TabStop = true; - this.rbCompatibility.Text = "Compatibility (more debug tools work!)"; - this.rbCompatibility.UseVisualStyleBackColor = true; - // - // groupBox1 - // - this.groupBox1.Controls.Add(this.radioButton1); - this.groupBox1.Controls.Add(this.label2); - this.groupBox1.Controls.Add(this.rbAccuracy); - this.groupBox1.Controls.Add(this.rbPerformance); - this.groupBox1.Controls.Add(this.rbCompatibility); - this.groupBox1.Location = new System.Drawing.Point(12, 12); - this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(277, 108); - this.groupBox1.TabIndex = 3; - this.groupBox1.TabStop = false; - this.groupBox1.Text = "Core Selection"; - // - // label2 - // - this.label2.Location = new System.Drawing.Point(72, 85); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(136, 21); - this.label2.TabIndex = 8; - this.label2.Text = "NOT SUPPORTED YET!"; - // - // rbAccuracy - // - this.rbAccuracy.AutoSize = true; - this.rbAccuracy.Enabled = false; - this.rbAccuracy.Location = new System.Drawing.Point(6, 65); - this.rbAccuracy.Name = "rbAccuracy"; - this.rbAccuracy.Size = new System.Drawing.Size(224, 17); - this.rbAccuracy.TabIndex = 4; - this.rbAccuracy.TabStop = true; - this.rbAccuracy.Text = "Accuracy (only to fix bugs in Compatibility!)"; - this.rbAccuracy.UseVisualStyleBackColor = true; - this.rbAccuracy.CheckedChanged += new System.EventHandler(this.RbAccuracy_CheckedChanged); - // - // rbPerformance - // - this.rbPerformance.AutoSize = true; - this.rbPerformance.Location = new System.Drawing.Point(6, 42); - this.rbPerformance.Name = "rbPerformance"; - this.rbPerformance.Size = new System.Drawing.Size(202, 17); - this.rbPerformance.TabIndex = 3; - this.rbPerformance.TabStop = true; - this.rbPerformance.Text = "Performance (only for casual gaming!)"; - this.rbPerformance.UseVisualStyleBackColor = true; - // - // cbDoubleSize - // - this.cbDoubleSize.AutoSize = true; - this.cbDoubleSize.Location = new System.Drawing.Point(18, 130); - this.cbDoubleSize.Name = "cbDoubleSize"; - this.cbDoubleSize.Size = new System.Drawing.Size(178, 17); - this.cbDoubleSize.TabIndex = 6; - this.cbDoubleSize.Text = "Always Double-Size Framebuffer"; - this.cbDoubleSize.UseVisualStyleBackColor = true; - this.cbDoubleSize.CheckedChanged += new System.EventHandler(this.CbDoubleSize_CheckedChanged); - // - // lblDoubleSize - // - this.lblDoubleSize.Location = new System.Drawing.Point(36, 151); - this.lblDoubleSize.Name = "lblDoubleSize"; - this.lblDoubleSize.Size = new System.Drawing.Size(254, 57); - this.lblDoubleSize.TabIndex = 7; - this.lblDoubleSize.Text = "Some games are changing the resolution constantly (e.g. SD3) so this option can f" + + this.btnOk = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.cbDoubleSize = new System.Windows.Forms.CheckBox(); + this.lblDoubleSize = new System.Windows.Forms.Label(); + this.radioButton1 = new System.Windows.Forms.RadioButton(); + this.cbCropSGBFrame = new System.Windows.Forms.CheckBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.Obj1Checkbox = new System.Windows.Forms.CheckBox(); + this.Obj2Checkbox = new System.Windows.Forms.CheckBox(); + this.Obj3Checkbox = new System.Windows.Forms.CheckBox(); + this.Obj4Checkbox = new System.Windows.Forms.CheckBox(); + this.Bg1Checkbox = new System.Windows.Forms.CheckBox(); + this.Bg2Checkbox = new System.Windows.Forms.CheckBox(); + this.Bg3Checkbox = new System.Windows.Forms.CheckBox(); + this.Bg4Checkbox = new System.Windows.Forms.CheckBox(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // btnOk + // + this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOk.Location = new System.Drawing.Point(136, 288); + this.btnOk.Name = "btnOk"; + this.btnOk.Size = new System.Drawing.Size(75, 23); + this.btnOk.TabIndex = 0; + this.btnOk.Text = "OK"; + this.btnOk.UseVisualStyleBackColor = true; + this.btnOk.Click += new System.EventHandler(this.BtnOk_Click); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point(217, 288); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 1; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.BtnCancel_Click); + // + // cbDoubleSize + // + this.cbDoubleSize.AutoSize = true; + this.cbDoubleSize.Location = new System.Drawing.Point(18, 20); + this.cbDoubleSize.Name = "cbDoubleSize"; + this.cbDoubleSize.Size = new System.Drawing.Size(178, 17); + this.cbDoubleSize.TabIndex = 6; + this.cbDoubleSize.Text = "Always Double-Size Framebuffer"; + this.cbDoubleSize.UseVisualStyleBackColor = true; + this.cbDoubleSize.CheckedChanged += new System.EventHandler(this.CbDoubleSize_CheckedChanged); + // + // lblDoubleSize + // + this.lblDoubleSize.Location = new System.Drawing.Point(36, 41); + this.lblDoubleSize.Name = "lblDoubleSize"; + this.lblDoubleSize.Size = new System.Drawing.Size(254, 57); + this.lblDoubleSize.TabIndex = 7; + this.lblDoubleSize.Text = "Some games are changing the resolution constantly (e.g. SD3) so this option can f" + "orce the SNES output to stay double-size always. NOTE: The Accuracy core runs as" + " if this is selected.\r\n"; - // - // cbForceDeterminism - // - this.cbForceDeterminism.AutoSize = true; - this.cbForceDeterminism.Location = new System.Drawing.Point(15, 234); - this.cbForceDeterminism.Name = "cbForceDeterminism"; - this.cbForceDeterminism.Size = new System.Drawing.Size(113, 17); - this.cbForceDeterminism.TabIndex = 8; - this.cbForceDeterminism.Text = "Force Determinism"; - this.cbForceDeterminism.UseVisualStyleBackColor = true; - this.cbForceDeterminism.CheckedChanged += new System.EventHandler(this.CbForceDeterminism_CheckedChanged); - // - // label3 - // - this.label3.Location = new System.Drawing.Point(34, 258); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(251, 41); - this.label3.TabIndex = 9; - this.label3.Text = "Guarantee deterministic emulation by savestating every frame. Don\'t TAS without i" + - "t! Only ~75% of runs sync without it, but speed boost is ~30%."; - // - // radioButton1 - // - this.radioButton1.AutoSize = true; - this.radioButton1.Location = new System.Drawing.Point(37, 46); - this.radioButton1.Name = "radioButton1"; - this.radioButton1.Size = new System.Drawing.Size(202, 17); - this.radioButton1.TabIndex = 9; - this.radioButton1.TabStop = true; - this.radioButton1.Text = "Performance (only for casual gaming!)"; - this.radioButton1.UseVisualStyleBackColor = true; - // - // cbCropSGBFrame - // - this.cbCropSGBFrame.AutoSize = true; - this.cbCropSGBFrame.Location = new System.Drawing.Point(15, 211); - this.cbCropSGBFrame.Name = "cbCropSGBFrame"; - this.cbCropSGBFrame.Size = new System.Drawing.Size(105, 17); - this.cbCropSGBFrame.TabIndex = 10; - this.cbCropSGBFrame.Text = "Crop SGB Frame"; - this.cbCropSGBFrame.UseVisualStyleBackColor = true; - // - // SNESOptions - // - this.AcceptButton = this.btnOk; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.btnCancel; - this.ClientSize = new System.Drawing.Size(304, 343); - this.Controls.Add(this.cbCropSGBFrame); - this.Controls.Add(this.label3); - this.Controls.Add(this.cbForceDeterminism); - this.Controls.Add(this.lblDoubleSize); - this.Controls.Add(this.cbDoubleSize); - this.Controls.Add(this.groupBox1); - this.Controls.Add(this.btnCancel); - this.Controls.Add(this.btnOk); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "SNESOptions"; - this.ShowIcon = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "SNES Options"; - this.Load += new System.EventHandler(this.SNESOptions_Load); - this.groupBox1.ResumeLayout(false); - this.groupBox1.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); + // + // radioButton1 + // + this.radioButton1.AutoSize = true; + this.radioButton1.Location = new System.Drawing.Point(37, 46); + this.radioButton1.Name = "radioButton1"; + this.radioButton1.Size = new System.Drawing.Size(202, 17); + this.radioButton1.TabIndex = 9; + this.radioButton1.TabStop = true; + this.radioButton1.Text = "Performance (only for casual gaming!)"; + this.radioButton1.UseVisualStyleBackColor = true; + // + // cbCropSGBFrame + // + this.cbCropSGBFrame.AutoSize = true; + this.cbCropSGBFrame.Location = new System.Drawing.Point(15, 110); + this.cbCropSGBFrame.Name = "cbCropSGBFrame"; + this.cbCropSGBFrame.Size = new System.Drawing.Size(105, 17); + this.cbCropSGBFrame.TabIndex = 10; + this.cbCropSGBFrame.Text = "Crop SGB Frame"; + this.cbCropSGBFrame.UseVisualStyleBackColor = true; + // + // groupBox1 + // + this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupBox1.Controls.Add(this.Bg4Checkbox); + this.groupBox1.Controls.Add(this.Bg3Checkbox); + this.groupBox1.Controls.Add(this.Bg2Checkbox); + this.groupBox1.Controls.Add(this.Bg1Checkbox); + this.groupBox1.Controls.Add(this.Obj4Checkbox); + this.groupBox1.Controls.Add(this.Obj3Checkbox); + this.groupBox1.Controls.Add(this.Obj2Checkbox); + this.groupBox1.Controls.Add(this.Obj1Checkbox); + this.groupBox1.Location = new System.Drawing.Point(18, 142); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(274, 140); + this.groupBox1.TabIndex = 11; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Display"; + // + // Obj1Checkbox + // + this.Obj1Checkbox.AutoSize = true; + this.Obj1Checkbox.Location = new System.Drawing.Point(21, 29); + this.Obj1Checkbox.Name = "Obj1Checkbox"; + this.Obj1Checkbox.Size = new System.Drawing.Size(55, 17); + this.Obj1Checkbox.TabIndex = 0; + this.Obj1Checkbox.Text = "OBJ 1"; + this.Obj1Checkbox.UseVisualStyleBackColor = true; + // + // Obj2Checkbox + // + this.Obj2Checkbox.AutoSize = true; + this.Obj2Checkbox.Location = new System.Drawing.Point(22, 52); + this.Obj2Checkbox.Name = "Obj2Checkbox"; + this.Obj2Checkbox.Size = new System.Drawing.Size(55, 17); + this.Obj2Checkbox.TabIndex = 1; + this.Obj2Checkbox.Text = "OBJ 2"; + this.Obj2Checkbox.UseVisualStyleBackColor = true; + // + // Obj3Checkbox + // + this.Obj3Checkbox.AutoSize = true; + this.Obj3Checkbox.Location = new System.Drawing.Point(21, 75); + this.Obj3Checkbox.Name = "Obj3Checkbox"; + this.Obj3Checkbox.Size = new System.Drawing.Size(55, 17); + this.Obj3Checkbox.TabIndex = 2; + this.Obj3Checkbox.Text = "OBJ 3"; + this.Obj3Checkbox.UseVisualStyleBackColor = true; + // + // Obj4Checkbox + // + this.Obj4Checkbox.AutoSize = true; + this.Obj4Checkbox.Location = new System.Drawing.Point(21, 98); + this.Obj4Checkbox.Name = "Obj4Checkbox"; + this.Obj4Checkbox.Size = new System.Drawing.Size(55, 17); + this.Obj4Checkbox.TabIndex = 3; + this.Obj4Checkbox.Text = "OBJ 4"; + this.Obj4Checkbox.UseVisualStyleBackColor = true; + // + // Bg1Checkbox + // + this.Bg1Checkbox.AutoSize = true; + this.Bg1Checkbox.Location = new System.Drawing.Point(150, 29); + this.Bg1Checkbox.Name = "Bg1Checkbox"; + this.Bg1Checkbox.Size = new System.Drawing.Size(50, 17); + this.Bg1Checkbox.TabIndex = 4; + this.Bg1Checkbox.Text = "BG 1"; + this.Bg1Checkbox.UseVisualStyleBackColor = true; + // + // Bg2Checkbox + // + this.Bg2Checkbox.AutoSize = true; + this.Bg2Checkbox.Location = new System.Drawing.Point(150, 52); + this.Bg2Checkbox.Name = "Bg2Checkbox"; + this.Bg2Checkbox.Size = new System.Drawing.Size(50, 17); + this.Bg2Checkbox.TabIndex = 5; + this.Bg2Checkbox.Text = "BG 2"; + this.Bg2Checkbox.UseVisualStyleBackColor = true; + // + // Bg3Checkbox + // + this.Bg3Checkbox.AutoSize = true; + this.Bg3Checkbox.Location = new System.Drawing.Point(150, 75); + this.Bg3Checkbox.Name = "Bg3Checkbox"; + this.Bg3Checkbox.Size = new System.Drawing.Size(50, 17); + this.Bg3Checkbox.TabIndex = 6; + this.Bg3Checkbox.Text = "BG 3"; + this.Bg3Checkbox.UseVisualStyleBackColor = true; + // + // Bg4Checkbox + // + this.Bg4Checkbox.AutoSize = true; + this.Bg4Checkbox.Location = new System.Drawing.Point(150, 98); + this.Bg4Checkbox.Name = "Bg4Checkbox"; + this.Bg4Checkbox.Size = new System.Drawing.Size(50, 17); + this.Bg4Checkbox.TabIndex = 7; + this.Bg4Checkbox.Text = "BG 4"; + this.Bg4Checkbox.UseVisualStyleBackColor = true; + // + // SNESOptions + // + this.AcceptButton = this.btnOk; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size(304, 323); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.cbCropSGBFrame); + this.Controls.Add(this.lblDoubleSize); + this.Controls.Add(this.cbDoubleSize); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOk); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "SNESOptions"; + this.ShowIcon = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "BSNES Options"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); } @@ -220,16 +242,18 @@ private System.Windows.Forms.Button btnOk; private System.Windows.Forms.Button btnCancel; - private System.Windows.Forms.RadioButton rbCompatibility; - private System.Windows.Forms.GroupBox groupBox1; - private System.Windows.Forms.RadioButton rbPerformance; private System.Windows.Forms.CheckBox cbDoubleSize; private System.Windows.Forms.Label lblDoubleSize; - private System.Windows.Forms.RadioButton rbAccuracy; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.CheckBox cbForceDeterminism; - private System.Windows.Forms.Label label3; private System.Windows.Forms.RadioButton radioButton1; private System.Windows.Forms.CheckBox cbCropSGBFrame; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.CheckBox Bg4Checkbox; + private System.Windows.Forms.CheckBox Bg3Checkbox; + private System.Windows.Forms.CheckBox Bg2Checkbox; + private System.Windows.Forms.CheckBox Bg1Checkbox; + private System.Windows.Forms.CheckBox Obj4Checkbox; + private System.Windows.Forms.CheckBox Obj3Checkbox; + private System.Windows.Forms.CheckBox Obj2Checkbox; + private System.Windows.Forms.CheckBox Obj1Checkbox; } } \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/config/SNES/SNESOptions.cs b/BizHawk.Client.EmuHawk/config/SNES/SNESOptions.cs index a1704e0dff..f9617c753f 100644 --- a/BizHawk.Client.EmuHawk/config/SNES/SNESOptions.cs +++ b/BizHawk.Client.EmuHawk/config/SNES/SNESOptions.cs @@ -22,58 +22,36 @@ namespace BizHawk.Client.EmuHawk var dlg = new SNESOptions { AlwaysDoubleSize = s.AlwaysDoubleSize, - ForceDeterminism = s.ForceDeterminism, CropSGBFrame = s.CropSGBFrame, - Profile = ss.Profile + ShowObj1 = s.ShowOBJ_0, + ShowObj2 = s.ShowOBJ_1, + ShowObj3 = s.ShowOBJ_2, + ShowObj4 = s.ShowOBJ_3, + ShowBg1 = s.ShowBG1_0, + ShowBg2 = s.ShowBG2_0, + ShowBg3 = s.ShowBG3_0, + ShowBg4 = s.ShowBG4_0 }; var result = dlg.ShowDialog(owner); if (result == DialogResult.OK) { s.AlwaysDoubleSize = dlg.AlwaysDoubleSize; - s.ForceDeterminism = dlg.ForceDeterminism; s.CropSGBFrame = dlg.CropSGBFrame; - ss.Profile = dlg.Profile; + s.ShowOBJ_0 = dlg.ShowObj1; + s.ShowOBJ_1 = dlg.ShowObj2; + s.ShowOBJ_2 = dlg.ShowObj3; + s.ShowOBJ_3 = dlg.ShowObj4; + s.ShowBG1_0 = s.ShowBG1_1 = dlg.ShowBg1; + s.ShowBG2_0 = s.ShowBG2_1 = dlg.ShowBg2; + s.ShowBG3_0 = s.ShowBG3_1 = dlg.ShowBg3; + s.ShowBG4_0 = s.ShowBG4_1 = dlg.ShowBg4; + GlobalWin.MainForm.PutCoreSettings(s); GlobalWin.MainForm.PutCoreSyncSettings(ss); } } - private void SNESOptions_Load(object sender, EventArgs e) - { - rbAccuracy.Visible = label2.Visible = VersionInfo.DeveloperBuild; - } - - private string Profile - { - get - { - if (rbCompatibility.Checked) - { - return "Compatibility"; - } - - if (rbPerformance.Checked) - { - return "Performance"; - } - - if (rbAccuracy.Checked) - { - return "Accuracy"; - } - - throw new InvalidOperationException(); - } - - set - { - rbCompatibility.Checked = value == "Compatibility"; - rbPerformance.Checked = value == "Performance"; - rbAccuracy.Checked = value == "Accuracy"; - } - } - private bool AlwaysDoubleSize { get @@ -88,32 +66,29 @@ namespace BizHawk.Client.EmuHawk } } - private bool ForceDeterminism - { - get { return cbForceDeterminism.Checked; } - set { cbForceDeterminism.Checked = value; } - } - private bool CropSGBFrame { get { return cbCropSGBFrame.Checked; } set { cbCropSGBFrame.Checked = value; } } - void RefreshDoubleSizeOption() + private bool ShowObj1 { get { return Obj1Checkbox.Checked; } set { Obj1Checkbox.Checked = value; } } + private bool ShowObj2 { get { return Obj2Checkbox.Checked; } set { Obj2Checkbox.Checked = value; } } + private bool ShowObj3 { get { return Obj3Checkbox.Checked; } set { Obj3Checkbox.Checked = value; } } + private bool ShowObj4 { get { return Obj4Checkbox.Checked; } set { Obj4Checkbox.Checked = value; } } + + private bool ShowBg1 { get { return Bg1Checkbox.Checked; } set { Bg1Checkbox.Checked = value; } } + private bool ShowBg2 { get { return Bg2Checkbox.Checked; } set { Bg2Checkbox.Checked = value; } } + private bool ShowBg3 { get { return Bg3Checkbox.Checked; } set { Bg3Checkbox.Checked = value; } } + private bool ShowBg4 { get { return Bg4Checkbox.Checked; } set { Bg4Checkbox.Checked = value; } } + + private void RefreshDoubleSizeOption() { _suppressDoubleSize = true; cbDoubleSize.Checked = !cbDoubleSize.Enabled || _userDoubleSizeOption; _suppressDoubleSize = false; } - private void RbAccuracy_CheckedChanged(object sender, EventArgs e) - { - cbDoubleSize.Enabled = !rbAccuracy.Checked; - lblDoubleSize.ForeColor = cbDoubleSize.Enabled ? System.Drawing.SystemColors.ControlText : System.Drawing.SystemColors.GrayText; - RefreshDoubleSizeOption(); - } - private void CbDoubleSize_CheckedChanged(object sender, EventArgs e) { if (_suppressDoubleSize) @@ -124,10 +99,6 @@ namespace BizHawk.Client.EmuHawk _userDoubleSizeOption = cbDoubleSize.Checked; } - private void CbForceDeterminism_CheckedChanged(object sender, EventArgs e) - { - } - private void BtnOk_Click(object sender, EventArgs e) { DialogResult = DialogResult.OK; diff --git a/BizHawk.Client.EmuHawk/images/ControllerImages/NGPController.png b/BizHawk.Client.EmuHawk/images/ControllerImages/NGPController.png new file mode 100644 index 0000000000..9c42ef842c Binary files /dev/null and b/BizHawk.Client.EmuHawk/images/ControllerImages/NGPController.png differ diff --git a/BizHawk.Client.EmuHawk/images/ControllerImages/VBoyController.png b/BizHawk.Client.EmuHawk/images/ControllerImages/VBoyController.png new file mode 100644 index 0000000000..59bef68ff7 Binary files /dev/null and b/BizHawk.Client.EmuHawk/images/ControllerImages/VBoyController.png differ diff --git a/BizHawk.Client.EmuHawk/tools/Genesis/VDPViewer.cs b/BizHawk.Client.EmuHawk/tools/Genesis/VDPViewer.cs index 4876a5a401..35938453ba 100644 --- a/BizHawk.Client.EmuHawk/tools/Genesis/VDPViewer.cs +++ b/BizHawk.Client.EmuHawk/tools/Genesis/VDPViewer.cs @@ -7,9 +7,10 @@ using System.Linq; using System.Text; using System.Windows.Forms; using BizHawk.Client.Common; -using BizHawk.Emulation.Cores.Consoles.Sega.gpgx; using System.Drawing.Imaging; using BizHawk.Emulation.Common; +using BizHawk.Emulation.Cores.Consoles.Sega.gpgx64; +using BizHawk.Common; namespace BizHawk.Client.EmuHawk { @@ -18,7 +19,8 @@ namespace BizHawk.Client.EmuHawk [RequiredService] private GPGX Emu { get; set; } - private LibGPGX.VDPView View = new LibGPGX.VDPView(); + private GPGX.VDPView View; + int palindex = 0; protected override System.Drawing.Point ScrollToControl(System.Windows.Forms.Control activeControl) @@ -81,7 +83,7 @@ namespace BizHawk.Client.EmuHawk bv.Refresh(); } - unsafe void DrawPalettes(int *pal) + unsafe void DrawPalettes(int* pal) { var lockdata = bmpViewPal.BMP.LockBits(new Rectangle(0, 0, 16, 4), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); int pitch = lockdata.Stride / sizeof(int); @@ -121,23 +123,24 @@ namespace BizHawk.Client.EmuHawk public void NewUpdate(ToolFormUpdateType type) { } - public void UpdateValues() + public unsafe void UpdateValues() { if (Emu == null) return; - Emu.UpdateVDPViewContext(View); - unsafe + + using ((View = Emu.UpdateVDPViewContext()).EnterExit()) { int* pal = (int*)View.ColorCache; //for (int i = 0; i < 0x40; i++) // pal[i] |= unchecked((int)0xff000000); DrawPalettes(pal); DrawTiles(); - ushort *VRAMNT = (ushort*)View.VRAM; - byte *tiles = (byte*)View.PatternCache; + ushort* VRAMNT = (ushort*)View.VRAM; + byte* tiles = (byte*)View.PatternCache; DrawNameTable(View.NTA, VRAMNT, tiles, pal, bmpViewNTA); DrawNameTable(View.NTB, VRAMNT, tiles, pal, bmpViewNTB); DrawNameTable(View.NTW, VRAMNT, tiles, pal, bmpViewNTW); + View = null; } } diff --git a/BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs b/BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs index 733b40c3a5..58f4061377 100644 --- a/BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs +++ b/BizHawk.Client.EmuHawk/tools/SNES/SNESGraphicsDebugger.cs @@ -1,1471 +1,1479 @@ -//TODO - disable scanline controls if box is unchecked -//TODO - overhaul the BG display box if its mode7 or direct color (mode7 more important) -//TODO - draw `1024` label in red if your content is being scaled down. -//TODO - maybe draw a label (in lieu of above, also) showing what scale the content is at: 2x or 1x or 1/2x -//TODO - add eDisplayType for BG1-Tiles, BG2-Tiles, etc. which show the tiles available to a BG. more concise than viewing all tiles and illustrating the relevant accessible areas -// . could this apply to the palette too? -//TODO - show the priority list for the current mode. make the priority list have checkboxes, and use that to control whether that item displays (does bsnes have that granularity? maybe) -//TODO - use custom checkboxes for register-viewing checkboxes to make them green and checked -//TODO - make freeze actually save the info caches, and re-render in realtime, so that you can pick something you want to see animate without having to hover your mouse just right. also add a checkbox to do the literal freeze (stop it from updating) -//TODO - sprite wrapping is not correct -//TODO - add "scroll&screen" checkbox which changes BG1/2/3/4 display modes to render scrolled and limited to 256x224 (for matching obj screen) -// alternatively - add "BG1 Screen" as a complement to BG1 -//TODO - make Sprites mode respect priority toggles -//TODO - add "mode" display to BG info (in addition to bpp) so we can readily see if its mode7 or unavailable - -//DEFERRED: -//. 256bpp modes (difficult to use) -//. non-mode7 directcolor (no known examples, perhaps due to difficulty using the requisite 256bpp modes) - -//http://stackoverflow.com/questions/1101149/displaying-thumbnail-icons-128x128-pixels-or-larger-in-a-grid-in-listview - -//hiding the tab control headers.. once this design gets solid, ill get rid of them -//http://www.mostthingsweb.com/2011/01/hiding-tab-headers-on-a-tabcontrol-in-c/ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Drawing; -using System.Reflection; -using System.Windows.Forms; - -using BizHawk.Common.NumberExtensions; -using BizHawk.Client.Common; -using BizHawk.Emulation.Cores.Nintendo.SNES; -using BizHawk.Client.EmuHawk; //TODO: What?? -using BizHawk.Emulation.Common; - -namespace BizHawk.Client.EmuHawk -{ - public unsafe partial class SNESGraphicsDebugger : Form, IToolFormAutoConfig - { - List displayTypeItems = new List(); - - public bool UpdateBefore { get { return false; } } - public bool AskSaveChanges() { return true; } - - [RequiredService] - private LibsnesCore Emulator { get; set; } - - [ConfigPersist] - public bool UseUserBackdropColor - { - get { return checkBackdropColor.Checked; } - set { checkBackdropColor.Checked = value; } - } - [ConfigPersist] - public int UserBackdropColor { get; set; } - - - public void Restart() - { - - } - - public SNESGraphicsDebugger() - { - InitializeComponent(); - viewerTile.ScaleImage = true; - - viewer.ScaleImage = false; - - displayTypeItems.Add(new DisplayTypeItem("Sprites", eDisplayType.Sprites)); - displayTypeItems.Add(new DisplayTypeItem("OBJ", eDisplayType.OBJ)); - - displayTypeItems.Add(new DisplayTypeItem("BG1 Screen", eDisplayType.BG1)); - displayTypeItems.Add(new DisplayTypeItem("BG2 Screen", eDisplayType.BG2)); - displayTypeItems.Add(new DisplayTypeItem("BG3 Screen", eDisplayType.BG3)); - displayTypeItems.Add(new DisplayTypeItem("BG4 Screen", eDisplayType.BG4)); - - displayTypeItems.Add(new DisplayTypeItem("BG1", eDisplayType.BG1)); - displayTypeItems.Add(new DisplayTypeItem("BG2",eDisplayType.BG2)); - displayTypeItems.Add(new DisplayTypeItem("BG3",eDisplayType.BG3)); - displayTypeItems.Add(new DisplayTypeItem("BG4",eDisplayType.BG4)); - displayTypeItems.Add(new DisplayTypeItem("OBJ Tiles",eDisplayType.OBJTiles0)); - displayTypeItems.Add(new DisplayTypeItem("2bpp tiles",eDisplayType.Tiles2bpp)); - displayTypeItems.Add(new DisplayTypeItem("4bpp tiles",eDisplayType.Tiles4bpp)); - displayTypeItems.Add(new DisplayTypeItem("8bpp tiles",eDisplayType.Tiles8bpp)); - displayTypeItems.Add(new DisplayTypeItem("Mode7 tiles",eDisplayType.TilesMode7)); - displayTypeItems.Add(new DisplayTypeItem("Mode7Ext tiles",eDisplayType.TilesMode7Ext)); - displayTypeItems.Add(new DisplayTypeItem("Mode7 tiles (DC)", eDisplayType.TilesMode7DC)); - comboDisplayType.DataSource = displayTypeItems; - comboDisplayType.SelectedIndex = 2; - - var paletteTypeItems = new List(); - paletteTypeItems.Add(new PaletteTypeItem("BizHawk", SnesColors.ColorType.BizHawk)); - paletteTypeItems.Add(new PaletteTypeItem("bsnes", SnesColors.ColorType.BSNES)); - paletteTypeItems.Add(new PaletteTypeItem("Snes9X", SnesColors.ColorType.Snes9x)); - suppression = true; - comboPalette.DataSource = paletteTypeItems; - comboPalette.SelectedIndex = 0; - suppression = false; - - comboBGProps.SelectedIndex = 0; - - SyncViewerSize(); - SyncColorSelection(); - - //tabctrlDetails.SelectedIndex = 1; - SetTab(null); - - UserBackdropColor = -1; - } - - LibsnesCore currentSnesCore; - protected override void OnClosed(EventArgs e) - { - base.OnClosed(e); - if (currentSnesCore != null) - currentSnesCore.ScanlineHookManager.Unregister(this); - currentSnesCore = null; - } - - string FormatBpp(int bpp) - { - if (bpp == 0) return "---"; - else return bpp.ToString(); - } - - string FormatVramAddress(int address) - { - int excess = address & 1023; - if (excess != 0) return "@" + address.ToHexString(4); - else return string.Format("@{0} ({1}K)", address.ToHexString(4), address / 1024); - } - - public void NewUpdate(ToolFormUpdateType type) { } - - public void UpdateValues() - { - SyncCore(); - if (Visible && !checkScanlineControl.Checked) - { +//TODO - disable scanline controls if box is unchecked +//TODO - overhaul the BG display box if its mode7 or direct color (mode7 more important) +//TODO - draw `1024` label in red if your content is being scaled down. +//TODO - maybe draw a label (in lieu of above, also) showing what scale the content is at: 2x or 1x or 1/2x +//TODO - add eDisplayType for BG1-Tiles, BG2-Tiles, etc. which show the tiles available to a BG. more concise than viewing all tiles and illustrating the relevant accessible areas +// . could this apply to the palette too? +//TODO - show the priority list for the current mode. make the priority list have checkboxes, and use that to control whether that item displays (does bsnes have that granularity? maybe) +//TODO - use custom checkboxes for register-viewing checkboxes to make them green and checked +//TODO - make freeze actually save the info caches, and re-render in realtime, so that you can pick something you want to see animate without having to hover your mouse just right. also add a checkbox to do the literal freeze (stop it from updating) +//TODO - sprite wrapping is not correct +//TODO - add "scroll&screen" checkbox which changes BG1/2/3/4 display modes to render scrolled and limited to 256x224 (for matching obj screen) +// alternatively - add "BG1 Screen" as a complement to BG1 +//TODO - make Sprites mode respect priority toggles +//TODO - add "mode" display to BG info (in addition to bpp) so we can readily see if its mode7 or unavailable + +//DEFERRED: +//. 256bpp modes (difficult to use) +//. non-mode7 directcolor (no known examples, perhaps due to difficulty using the requisite 256bpp modes) + +//http://stackoverflow.com/questions/1101149/displaying-thumbnail-icons-128x128-pixels-or-larger-in-a-grid-in-listview + +//hiding the tab control headers.. once this design gets solid, ill get rid of them +//http://www.mostthingsweb.com/2011/01/hiding-tab-headers-on-a-tabcontrol-in-c/ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using System.Reflection; +using System.Windows.Forms; + +using BizHawk.Common.NumberExtensions; +using BizHawk.Client.Common; +using BizHawk.Emulation.Cores.Nintendo.SNES; +using BizHawk.Emulation.Common; +using BizHawk.Client.EmuHawk; +using BizHawk.Common; + +namespace BizHawk.Client.EmuHawk +{ + public unsafe partial class SNESGraphicsDebugger : Form, IToolFormAutoConfig + { + List displayTypeItems = new List(); + + public bool UpdateBefore { get { return false; } } + public bool AskSaveChanges() { return true; } + + [RequiredService] + private LibsnesCore Emulator { get; set; } + + [ConfigPersist] + public bool UseUserBackdropColor + { + get { return checkBackdropColor.Checked; } + set { checkBackdropColor.Checked = value; } + } + [ConfigPersist] + public int UserBackdropColor { get; set; } + + + public void Restart() + { + + } + + public SNESGraphicsDebugger() + { + InitializeComponent(); + viewerTile.ScaleImage = true; + + viewer.ScaleImage = false; + + displayTypeItems.Add(new DisplayTypeItem("Sprites", eDisplayType.Sprites)); + displayTypeItems.Add(new DisplayTypeItem("OBJ", eDisplayType.OBJ)); + + displayTypeItems.Add(new DisplayTypeItem("BG1 Screen", eDisplayType.BG1)); + displayTypeItems.Add(new DisplayTypeItem("BG2 Screen", eDisplayType.BG2)); + displayTypeItems.Add(new DisplayTypeItem("BG3 Screen", eDisplayType.BG3)); + displayTypeItems.Add(new DisplayTypeItem("BG4 Screen", eDisplayType.BG4)); + + displayTypeItems.Add(new DisplayTypeItem("BG1", eDisplayType.BG1)); + displayTypeItems.Add(new DisplayTypeItem("BG2",eDisplayType.BG2)); + displayTypeItems.Add(new DisplayTypeItem("BG3",eDisplayType.BG3)); + displayTypeItems.Add(new DisplayTypeItem("BG4",eDisplayType.BG4)); + displayTypeItems.Add(new DisplayTypeItem("OBJ Tiles",eDisplayType.OBJTiles0)); + displayTypeItems.Add(new DisplayTypeItem("2bpp tiles",eDisplayType.Tiles2bpp)); + displayTypeItems.Add(new DisplayTypeItem("4bpp tiles",eDisplayType.Tiles4bpp)); + displayTypeItems.Add(new DisplayTypeItem("8bpp tiles",eDisplayType.Tiles8bpp)); + displayTypeItems.Add(new DisplayTypeItem("Mode7 tiles",eDisplayType.TilesMode7)); + displayTypeItems.Add(new DisplayTypeItem("Mode7Ext tiles",eDisplayType.TilesMode7Ext)); + displayTypeItems.Add(new DisplayTypeItem("Mode7 tiles (DC)", eDisplayType.TilesMode7DC)); + comboDisplayType.DataSource = displayTypeItems; + comboDisplayType.SelectedIndex = 2; + + var paletteTypeItems = new List(); + paletteTypeItems.Add(new PaletteTypeItem("BizHawk", SnesColors.ColorType.BizHawk)); + paletteTypeItems.Add(new PaletteTypeItem("bsnes", SnesColors.ColorType.BSNES)); + paletteTypeItems.Add(new PaletteTypeItem("Snes9X", SnesColors.ColorType.Snes9x)); + suppression = true; + comboPalette.DataSource = paletteTypeItems; + comboPalette.SelectedIndex = 0; + suppression = false; + + comboBGProps.SelectedIndex = 0; + + SyncViewerSize(); + SyncColorSelection(); + + //tabctrlDetails.SelectedIndex = 1; + SetTab(null); + + UserBackdropColor = -1; + } + + LibsnesCore currentSnesCore; + protected override void OnClosed(EventArgs e) + { + base.OnClosed(e); + if (currentSnesCore != null) + currentSnesCore.ScanlineHookManager.Unregister(this); + currentSnesCore = null; + } + + string FormatBpp(int bpp) + { + if (bpp == 0) return "---"; + else return bpp.ToString(); + } + + string FormatVramAddress(int address) + { + int excess = address & 1023; + if (excess != 0) return "@" + address.ToHexString(4); + else return string.Format("@{0} ({1}K)", address.ToHexString(4), address / 1024); + } + + public void NewUpdate(ToolFormUpdateType type) { } + + public void UpdateValues() + { + SyncCore(); + if (Visible && !checkScanlineControl.Checked) + { + RegenerateData(); + InternalUpdateValues(); + } + } + + public void FastUpdate() + { + // To do + } + + public void UpdateToolsLoadstate() + { + SyncCore(); + if (Visible) + { RegenerateData(); InternalUpdateValues(); - } - } - - public void FastUpdate() - { - // To do - } - - public void UpdateToolsLoadstate() - { - SyncCore(); - if (Visible) - { - RegenerateData(); - InternalUpdateValues(); - } - } - - private void nudScanline_ValueChanged(object sender, EventArgs e) - { - if (suppression) return; - SyncCore(); - suppression = true; - sliderScanline.Value = 224 - (int)nudScanline.Value; - suppression = false; - } - - private void sliderScanline_ValueChanged(object sender, EventArgs e) - { - if (suppression) return; - checkScanlineControl.Checked = true; - SyncCore(); - suppression = true; - nudScanline.Value = 224 - sliderScanline.Value; - suppression = false; - } - - void SyncCore() - { - if (currentSnesCore != Emulator && currentSnesCore != null) - { - currentSnesCore.ScanlineHookManager.Unregister(this); - } - - if (currentSnesCore != Emulator && Emulator != null) - { - suppression = true; - comboPalette.SelectedValue = Emulator.CurrPalette; - RefreshBGENCheckStatesFromConfig(); - suppression = false; - } - - currentSnesCore = Emulator; - - if (currentSnesCore != null) - { - if (Visible && checkScanlineControl.Checked) - currentSnesCore.ScanlineHookManager.Register(this, ScanlineHook); - else - currentSnesCore.ScanlineHookManager.Unregister(this); - } - } - - void ScanlineHook(int line) - { - int target = (int)nudScanline.Value; - if (target == line) - { - RegenerateData(); - InternalUpdateValues(); - } - } - - SNESGraphicsDecoder gd; - SNESGraphicsDecoder.ScreenInfo si; - SNESGraphicsDecoder.TileEntry[] map; - byte[,] spriteMap = new byte[256, 224]; - SNESGraphicsDecoder.BGMode viewBgMode; - - void RegenerateData() - { - if (gd != null) gd.Dispose(); - gd = null; - if (currentSnesCore == null) return; - gd = NewDecoder(); - if(checkBackdropColor.Checked) - gd.SetBackColor(DecodeWinformsColorToSNES(pnBackdropColor.BackColor)); - gd.CacheTiles(); - si = gd.ScanScreenInfo(); - } - - private void InternalUpdateValues() - { - if (currentSnesCore == null) return; - - txtOBSELSizeBits.Text = si.OBSEL_Size.ToString(); - txtOBSELBaseBits.Text = si.OBSEL_NameBase.ToString(); - txtOBSELT1OfsBits.Text = si.OBSEL_NameSel.ToString(); - txtOBSELSizeDescr.Text = string.Format("{0}, {1}", SNESGraphicsDecoder.ObjSizes[si.OBSEL_Size, 0], SNESGraphicsDecoder.ObjSizes[si.OBSEL_Size, 1]); - txtOBSELBaseDescr.Text = FormatVramAddress(si.OBJTable0Addr); - txtOBSELT1OfsDescr.Text = FormatVramAddress(si.OBJTable1Addr); - - checkScreenExtbg.Checked = si.SETINI_Mode7ExtBG; - checkScreenHires.Checked = si.SETINI_HiRes; - checkScreenOverscan.Checked = si.SETINI_Overscan; - checkScreenObjInterlace.Checked = si.SETINI_ObjInterlace; - checkScreenInterlace.Checked = si.SETINI_ScreenInterlace; - - txtScreenCGWSEL_ColorMask.Text = si.CGWSEL_ColorMask.ToString(); - txtScreenCGWSEL_ColorSubMask.Text = si.CGWSEL_ColorSubMask.ToString(); - txtScreenCGWSEL_MathFixed.Text = si.CGWSEL_AddSubMode.ToString(); - checkScreenCGWSEL_DirectColor.Checked = si.CGWSEL_DirectColor; - txtScreenCGADSUB_AddSub.Text = si.CGWSEL_AddSubMode.ToString(); - txtScreenCGADSUB_AddSub_Descr.Text = si.CGADSUB_AddSub == 1 ? "SUB" : "ADD"; - txtScreenCGADSUB_Half.Checked = si.CGADSUB_Half; - - txtModeBits.Text = si.Mode.MODE.ToString(); - txtScreenBG1Bpp.Text = FormatBpp(si.BG.BG1.Bpp); - txtScreenBG2Bpp.Text = FormatBpp(si.BG.BG2.Bpp); - txtScreenBG3Bpp.Text = FormatBpp(si.BG.BG3.Bpp); - txtScreenBG4Bpp.Text = FormatBpp(si.BG.BG4.Bpp); - txtScreenBG1TSize.Text = FormatBpp(si.BG.BG1.TileSize); - txtScreenBG2TSize.Text = FormatBpp(si.BG.BG2.TileSize); - txtScreenBG3TSize.Text = FormatBpp(si.BG.BG3.TileSize); - txtScreenBG4TSize.Text = FormatBpp(si.BG.BG4.TileSize); - - int bgnum = comboBGProps.SelectedIndex + 1; - - var bg = si.BG[bgnum]; - txtBG1TSizeBits.Text = bg.TILESIZE.ToString(); - txtBG1TSizeDescr.Text = string.Format("{0}x{0}", bg.TileSize); - txtBG1Bpp.Text = FormatBpp(bg.Bpp); - txtBG1SizeBits.Text = bg.SCSIZE.ToString(); - txtBG1SizeInTiles.Text = bg.ScreenSizeInTiles.ToString(); - int size = bg.ScreenSizeInTiles.Width * bg.ScreenSizeInTiles.Height * 2 / 1024; - txtBG1MapSizeBytes.Text = string.Format("({0}K)", size); - txtBG1SCAddrBits.Text = bg.SCADDR.ToString(); - txtBG1SCAddrDescr.Text = FormatVramAddress(bg.ScreenAddr); - txtBG1Colors.Text = (1 << bg.Bpp).ToString(); - if (bg.Bpp == 8 && si.CGWSEL_DirectColor) txtBG1Colors.Text = "(Direct Color)"; - txtBG1TDAddrBits.Text = bg.TDADDR.ToString(); - txtBG1TDAddrDescr.Text = FormatVramAddress(bg.TiledataAddr); - - txtBG1Scroll.Text = string.Format("({0},{1})", bg.HOFS, bg.VOFS); - - if (bg.Bpp != 0) - { - var pi = bg.PaletteSelection; - txtBGPaletteInfo.Text = string.Format("{0} colors from ${1:X2} - ${2:X2}", pi.size, pi.start, pi.start + pi.size - 1); - } - else txtBGPaletteInfo.Text = ""; - - var sizeInPixels = bg.ScreenSizeInPixels; - txtBG1SizeInPixels.Text = string.Format("{0}x{1}", sizeInPixels.Width, sizeInPixels.Height); - - checkTMOBJ.Checked = si.OBJ_MainEnabled; - checkTMBG1.Checked = si.BG.BG1.MainEnabled; - checkTMBG2.Checked = si.BG.BG2.MainEnabled; - checkTMBG3.Checked = si.BG.BG3.MainEnabled; - checkTMBG4.Checked = si.BG.BG4.MainEnabled; - checkTMOBJ.Checked = si.OBJ_SubEnabled; - checkTSBG1.Checked = si.BG.BG1.SubEnabled; - checkTSBG2.Checked = si.BG.BG2.SubEnabled; - checkTSBG3.Checked = si.BG.BG3.SubEnabled; - checkTSBG4.Checked = si.BG.BG4.SubEnabled; - checkTSOBJ.Checked = si.OBJ_MainEnabled; - checkMathOBJ.Checked = si.OBJ_MathEnabled; - checkMathBK.Checked = si.BK_MathEnabled; - checkMathBG1.Checked = si.BG.BG1.MathEnabled; - checkMathBG2.Checked = si.BG.BG2.MathEnabled; - checkMathBG3.Checked = si.BG.BG3.MathEnabled; - checkMathBG4.Checked = si.BG.BG4.MathEnabled; - - if (si.Mode.MODE == 1 && si.Mode1_BG3_Priority) - { - lblBG3.ForeColor = Color.Red; - if (toolTip1.GetToolTip(lblBG3) != "Mode 1 BG3 priority toggle bit of $2105 is SET") - toolTip1.SetToolTip(lblBG3, "Mode 1 BG3 priority toggle bit of $2105 is SET"); - } - else - { - lblBG3.ForeColor = Color.Black; - if (toolTip1.GetToolTip(lblBG3) != "Mode 1 BG3 priority toggle bit of $2105 is CLEAR") - toolTip1.SetToolTip(lblBG3, "Mode 1 BG3 priority toggle bit of $2105 is CLEAR"); - } - - SyncColorSelection(); - RenderView(); - RenderPalette(); - RenderTileView(); - //these are likely to be changing all the time - UpdateColorDetails(); - UpdateOBJDetails(); - //maybe bg settings changed, or something - UpdateMapEntryDetails(); - UpdateTileDetails(); - } - - eDisplayType CurrDisplaySelection { get { return (comboDisplayType.SelectedValue as eDisplayType?).Value; } } - - //todo - something smarter to cycle through bitmaps without repeatedly trashing them (use the dispose callback on the viewer) - private void RenderView() - { - Bitmap bmp = null; - System.Drawing.Imaging.BitmapData bmpdata = null; - int* pixelptr = null; - int stride = 0; - - Action allocate = (w, h) => - { - bmp = new Bitmap(w, h); - bmpdata = bmp.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - pixelptr = (int*)bmpdata.Scan0.ToPointer(); - stride = bmpdata.Stride; - }; - - var selection = CurrDisplaySelection; - if (selection == eDisplayType.OBJ) - { - var objBounds = si.ObjSizeBounds; - int width = objBounds.Width * 8; - int height = objBounds.Height * 16; - allocate(width, height); - for (int i = 0; i < 128; i++) - { - int tx = i % 8; - int ty = i / 8; - int x = tx * objBounds.Width; - int y = ty * objBounds.Height; - gd.RenderSpriteToScreen(pixelptr, stride / 4, x,y, si, i); - } - } - if (selection == eDisplayType.Sprites) - { - //render sprites in-place - allocate(256, 224); - for (int y = 0; y < 224; y++) for (int x = 0; x < 256; x++) spriteMap[x, y] = 0xFF; - for(int i=127;i>=0;i--) - { - var oam = new SNESGraphicsDecoder.OAMInfo(gd, si, i); - gd.RenderSpriteToScreen(pixelptr, stride / 4, oam.X, oam.Y, si, i, oam, 256, 224, spriteMap); - } - } - if (selection == eDisplayType.OBJTiles0 || selection == eDisplayType.OBJTiles1) - { - allocate(128, 256); - int startTile; - startTile = si.OBJTable0Addr / 32; - gd.RenderTilesToScreen(pixelptr, 16, 16, stride / 4, 4, currPaletteSelection.start, startTile, 256, true); - startTile = si.OBJTable1Addr / 32; - gd.RenderTilesToScreen(pixelptr + (stride/4*8*16), 16, 16, stride / 4, 4, currPaletteSelection.start, startTile, 256, true); - } - if (selection == eDisplayType.Tiles2bpp) - { - allocate(512, 512); - gd.RenderTilesToScreen(pixelptr, 64, 64, stride / 4, 2, currPaletteSelection.start); - } - if (selection == eDisplayType.Tiles4bpp) - { - allocate(512, 512); - gd.RenderTilesToScreen(pixelptr, 64, 32, stride / 4, 4, currPaletteSelection.start); - } - if (selection == eDisplayType.Tiles8bpp) - { - allocate(256, 256); - gd.RenderTilesToScreen(pixelptr, 32, 32, stride / 4, 8, currPaletteSelection.start); - } - if (selection == eDisplayType.TilesMode7) - { - //256 tiles - allocate(128, 128); - gd.RenderMode7TilesToScreen(pixelptr, stride / 4, false, false); - } - if (selection == eDisplayType.TilesMode7Ext) - { - //256 tiles - allocate(128, 128); - gd.RenderMode7TilesToScreen(pixelptr, stride / 4, true, false); - } - if (selection == eDisplayType.TilesMode7DC) - { - //256 tiles - allocate(128, 128); - gd.RenderMode7TilesToScreen(pixelptr, stride / 4, false, true); - } - if (IsDisplayTypeBG(selection)) - { - int bgnum = (int)selection; - var bg = si.BG[bgnum]; - - map = new SNESGraphicsDecoder.TileEntry[0]; - viewBgMode = bg.BGMode; - - //bool handled = false; - if (bg.Enabled) - { - //TODO - directColor in normal BG renderer - bool DirectColor = si.CGWSEL_DirectColor && bg.Bpp == 8; //any exceptions? - int numPixels = 0; - //TODO - could use BGMode property on BG... too much chaos to deal with it now - if (si.Mode.MODE == 7) - { - bool mode7 = bgnum == 1; - bool mode7extbg = (bgnum == 2 && si.SETINI_Mode7ExtBG); - if (mode7 || mode7extbg) - { - //handled = true; - allocate(1024, 1024); - gd.DecodeMode7BG(pixelptr, stride / 4, mode7extbg); - numPixels = 128 * 128 * 8 * 8; - if (DirectColor) gd.DirectColorify(pixelptr, numPixels); - else gd.Paletteize(pixelptr, 0, 0, numPixels); - - //get a fake map, since mode7 doesnt really have a map - map = gd.FetchMode7Tilemap(); - } - } - else - { - //handled = true; - var dims = bg.ScreenSizeInPixels; - dims.Height = dims.Width = Math.Max(dims.Width, dims.Height); - allocate(dims.Width, dims.Height); - numPixels = dims.Width * dims.Height; - System.Diagnostics.Debug.Assert(stride / 4 == dims.Width); - - map = gd.FetchTilemap(bg.ScreenAddr, bg.ScreenSize); - int paletteStart = 0; - gd.DecodeBG(pixelptr, stride / 4, map, bg.TiledataAddr, bg.ScreenSize, bg.Bpp, bg.TileSize, paletteStart); - gd.Paletteize(pixelptr, 0, 0, numPixels); - } - - gd.Colorize(pixelptr, 0, numPixels); - } - } - - if (bmp != null) - { - bmp.UnlockBits(bmpdata); - viewer.SetBitmap(bmp); - } - } - - enum eDisplayType - { - BG1 = 1, BG2 = 2, BG3 = 3, BG4 = 4, OBJTiles0, OBJTiles1, Tiles2bpp, Tiles4bpp, Tiles8bpp, TilesMode7, TilesMode7Ext, TilesMode7DC, Sprites, OBJ, - BG1Screen = 101, BG2Screen = 102, BG3Screen = 103, BG4Screen = 104, - } - static bool IsDisplayTypeBG(eDisplayType type) { return type == eDisplayType.BG1 || type == eDisplayType.BG2 || type == eDisplayType.BG3 || type == eDisplayType.BG4; } - static bool IsDisplayTypeOBJ(eDisplayType type) { return type == eDisplayType.OBJTiles0 || type == eDisplayType.OBJTiles1; } - static int DisplayTypeBGNum(eDisplayType type) { if(IsDisplayTypeBG(type)) return (int)type; else return -1; } - static SNESGraphicsDecoder.BGMode BGModeForDisplayType(eDisplayType type) - { - switch (type) - { - case eDisplayType.Tiles2bpp: return SNESGraphicsDecoder.BGMode.Text; - case eDisplayType.Tiles4bpp: return SNESGraphicsDecoder.BGMode.Text; - case eDisplayType.Tiles8bpp: return SNESGraphicsDecoder.BGMode.Text; - case eDisplayType.TilesMode7: return SNESGraphicsDecoder.BGMode.Mode7; - case eDisplayType.TilesMode7Ext: return SNESGraphicsDecoder.BGMode.Mode7Ext; - case eDisplayType.TilesMode7DC: return SNESGraphicsDecoder.BGMode.Mode7DC; - case eDisplayType.OBJTiles0: return SNESGraphicsDecoder.BGMode.OBJ; - case eDisplayType.OBJTiles1: return SNESGraphicsDecoder.BGMode.OBJ; - default: throw new InvalidOperationException(); - } - } - - class DisplayTypeItem - { - public eDisplayType Type { get; private set; } - public string Descr { get; private set; } - public DisplayTypeItem(string descr, eDisplayType type) - { - Type = type; - Descr = descr; - } - } - - class PaletteTypeItem - { - public SnesColors.ColorType Type { get; private set; } - public string Descr { get; private set; } - public PaletteTypeItem(string descr, SnesColors.ColorType type) - { - Type = type; - Descr = descr; - } - } - - private void comboDisplayType_SelectedIndexChanged(object sender, EventArgs e) - { - InternalUpdateValues(); - - //change the bg props viewer to match - if (IsDisplayTypeBG(CurrDisplaySelection)) - comboBGProps.SelectedIndex = DisplayTypeBGNum(CurrDisplaySelection) - 1; - } - - private void exitToolStripMenuItem_Click(object sender, EventArgs e) - { - Close(); - } - - private void SNESGraphicsDebugger_Load(object sender, EventArgs e) - { - if (UserBackdropColor != -1) - { - pnBackdropColor.BackColor = Color.FromArgb(UserBackdropColor); - } - if (checkBackdropColor.Checked) - { - SyncBackdropColor(); - } - - UpdateToolsLoadstate(); - } - - bool suppression = false; - private void rbBGX_CheckedChanged(object sender, EventArgs e) - { - if (suppression) return; - //sync the comboBGProps dropdown with the result of this check - suppression = true; - if (rbBG1.Checked) comboBGProps.SelectedIndex = 0; - if (rbBG2.Checked) comboBGProps.SelectedIndex = 1; - if (rbBG3.Checked) comboBGProps.SelectedIndex = 2; - if (rbBG4.Checked) comboBGProps.SelectedIndex = 3; - suppression = false; - InternalUpdateValues(); - } - - private void comboBGProps_SelectedIndexChanged(object sender, EventArgs e) - { - if (suppression) return; - - //sync the radiobuttons with this selection - suppression = true; - if (comboBGProps.SelectedIndex == 0) rbBG1.Checked = true; - if (comboBGProps.SelectedIndex == 1) rbBG2.Checked = true; - if (comboBGProps.SelectedIndex == 2) rbBG3.Checked = true; - if (comboBGProps.SelectedIndex == 3) rbBG4.Checked = true; - suppression = false; - InternalUpdateValues(); - } - - const int paletteCellSize = 16; - const int paletteCellSpacing = 3; - - int[] lastPalette; - int lastColorNum = 0; - int selectedColorNum = 0; - SNESGraphicsDecoder.PaletteSelection currPaletteSelection; - - Rectangle GetPaletteRegion(int start, int num) - { - var ret = new Rectangle(); - ret.X = start % 16; - ret.Y = start / 16; - ret.Width = num; - ret.Height = num / 16; - if (ret.Height == 0) ret.Height = 1; - if (ret.Width > 16) ret.Width = 16; - return ret; - } - - Rectangle GetPaletteRegion(SNESGraphicsDecoder.PaletteSelection sel) - { - int start = sel.start, num = sel.size; - return GetPaletteRegion(start, num); - } - - void DrawPaletteRegion(Graphics g, Color color, Rectangle region) - { - int cellTotalSize = (paletteCellSize + paletteCellSpacing); - - int x = paletteCellSpacing + region.X * cellTotalSize - 2; - int y = paletteCellSpacing + region.Y * cellTotalSize - 2; - int width = cellTotalSize * region.Width; - int height = cellTotalSize * region.Height; - - var rect = new Rectangle(x, y, width, height); - using (var pen = new Pen(color)) - g.DrawRectangle(pen, rect); - } - - //if a tile set is being displayed, this will adapt the user's color selection into a palette to be used for rendering the tiles - SNESGraphicsDecoder.PaletteSelection GetPaletteSelectionForTileDisplay(int colorSelection) - { - int bpp = 0; - var selection = CurrDisplaySelection; - if (selection == eDisplayType.Tiles2bpp) bpp = 2; - if (selection == eDisplayType.Tiles4bpp) bpp = 4; - if (selection == eDisplayType.Tiles8bpp) bpp = 8; - if (selection == eDisplayType.TilesMode7) bpp = 8; - if (selection == eDisplayType.TilesMode7Ext) bpp = 7; - if (selection == eDisplayType.OBJTiles0) bpp = 4; - if (selection == eDisplayType.OBJTiles1) bpp = 4; - - SNESGraphicsDecoder.PaletteSelection ret = new SNESGraphicsDecoder.PaletteSelection(); - if(bpp == 0) return ret; - - //mode7 ext is fixed to use the top 128 colors - if (bpp == 7) - { - ret.size = 128; - ret.start = 0; - return ret; - } - - ret.size = 1 << bpp; - ret.start = colorSelection & (~(ret.size - 1)); - return ret; - } - - SNESGraphicsDecoder NewDecoder() - { - //wtf to do? now we need an api all the time - if (currentSnesCore != null) - return new SNESGraphicsDecoder(currentSnesCore.Api, currentSnesCore.CurrPalette); - else return new SNESGraphicsDecoder(currentSnesCore.Api, SnesColors.ColorType.BizHawk); - } - - void RenderPalette() - { - //var gd = NewDecoder(); //?? - lastPalette = gd.GetPalette(); - - int pixsize = paletteCellSize * 16 + paletteCellSpacing * 17; - int cellTotalSize = (paletteCellSize + paletteCellSpacing); - var bmp = new Bitmap(pixsize, pixsize, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - using (var g = Graphics.FromImage(bmp)) - { - for (int y = 0; y < 16; y++) - { - for (int x = 0; x < 16; x++) - { - int rgb555 = lastPalette[y * 16 + x]; - int color = gd.Colorize(rgb555); - using (var brush = new SolidBrush(Color.FromArgb(color))) - { - g.FillRectangle(brush, new Rectangle(paletteCellSpacing + x * cellTotalSize, paletteCellSpacing + y * cellTotalSize, paletteCellSize, paletteCellSize)); - } - } - } - - //draw selection boxes: - //first, draw the current selection - var region = GetPaletteRegion(selectedColorNum, 1); - DrawPaletteRegion(g, Color.Red, region); - //next, draw the rectangle that advises you which colors could possibly be used for a bg - if (IsDisplayTypeBG(CurrDisplaySelection)) - { - var ps = si.BG[DisplayTypeBGNum(CurrDisplaySelection)].PaletteSelection; - region = GetPaletteRegion(ps); - DrawPaletteRegion(g, Color.FromArgb(192, 128, 255, 255), region); - } - if (IsDisplayTypeOBJ(CurrDisplaySelection)) - { - var ps = new SNESGraphicsDecoder.PaletteSelection(128, 128); - region = GetPaletteRegion(ps); - DrawPaletteRegion(g, Color.FromArgb(192, 128, 255, 255), region); - } - //finally, draw the palette the user has chosen, in case he's viewing tiles - if (currPaletteSelection.size != 0) - { - region = GetPaletteRegion(currPaletteSelection.start, currPaletteSelection.size); - DrawPaletteRegion(g, Color.FromArgb(192,255,255,255), region); - } - } - - paletteViewer.SetBitmap(bmp); - } - - static string BGModeShortName(SNESGraphicsDecoder.BGMode mode, int bpp) - { - if (mode == SNESGraphicsDecoder.BGMode.Unavailable) return "Unavailable"; - if (mode == SNESGraphicsDecoder.BGMode.Text) return string.Format("Text{0}bpp", bpp); - if (mode == SNESGraphicsDecoder.BGMode.OBJ) return string.Format("OBJ", bpp); - if (mode == SNESGraphicsDecoder.BGMode.Mode7) return "Mode7"; - if (mode == SNESGraphicsDecoder.BGMode.Mode7Ext) return "Mode7Ext"; - if (mode == SNESGraphicsDecoder.BGMode.Mode7DC) return "Mode7DC"; - throw new InvalidOperationException(); - } - - void UpdateOBJDetails() - { - if (currObjDataState == null) return; - var oam = new SNESGraphicsDecoder.OAMInfo(gd, si, currObjDataState.Number); - txtObjNumber.Text = string.Format("#${0:X2}", currObjDataState.Number); - txtObjCoord.Text = string.Format("({0}, {1})",oam.X,oam.Y); - cbObjHFlip.Checked = oam.HFlip; - cbObjVFlip.Checked = oam.VFlip; - cbObjLarge.Checked = oam.Size == 1; - txtObjSize.Text = SNESGraphicsDecoder.ObjSizes[si.OBSEL_Size, oam.Size].ToString(); - txtObjPriority.Text = oam.Priority.ToString(); - txtObjPalette.Text = oam.Palette.ToString(); - txtObjPaletteMemo.Text = string.Format("${0:X2}", oam.Palette * 16 + 128); - txtObjName.Text = string.Format("#${0:X3}", oam.Tile); - txtObjNameAddr.Text = string.Format("@{0:X4}", oam.Address); - } - - void UpdateTileDetails() - { - if (currTileDataState == null) return; - var mode = BGModeForDisplayType(currTileDataState.Type); - int bpp = currTileDataState.Bpp; - txtTileMode.Text = BGModeShortName(mode, bpp); - txtTileBpp.Text = currTileDataState.Bpp.ToString(); - txtTileColors.Text = (1 << currTileDataState.Bpp).ToString(); - txtTileNumber.Text = string.Format("#${0:X3}", currTileDataState.Tile); - txtTileAddress.Text = string.Format("@{0:X4}", currTileDataState.Address); - txtTilePalette.Text = string.Format("#{0:X2}", currTileDataState.Palette); - } - - void UpdateMapEntryDetails() - { - if (currMapEntryState == null) return; - txtMapEntryLocation.Text = string.Format("({0},{1}), @{2:X4}", currMapEntryState.Location.X, currMapEntryState.Location.Y, currMapEntryState.entry.address); - txtMapEntryTileNum.Text = string.Format("${0:X3}", currMapEntryState.entry.tilenum); - txtMapEntryPrio.Text = string.Format("{0}", (currMapEntryState.entry.flags & SNESGraphicsDecoder.TileEntryFlags.Priority)!=0?1:0); - txtMapEntryPalette.Text = string.Format("{0}", currMapEntryState.entry.palette); - checkMapEntryHFlip.Checked = (currMapEntryState.entry.flags & SNESGraphicsDecoder.TileEntryFlags.Horz) != 0; - checkMapEntryVFlip.Checked = (currMapEntryState.entry.flags & SNESGraphicsDecoder.TileEntryFlags.Vert) != 0; - - //calculate address of tile - var bg = si.BG[currMapEntryState.bgnum]; - int bpp = bg.Bpp; - int tiledataBaseAddr = bg.TiledataAddr; - int tileSizeBytes = 8 * bpp; - int baseTileNum = tiledataBaseAddr / tileSizeBytes; - int tileNum = baseTileNum + currMapEntryState.entry.tilenum; - int addr = tileNum * tileSizeBytes; - - //mode7 takes up 128 bytes per tile because its interleaved with the screen data - if (bg.BGModeIsMode7Type) - addr *= 2; - - addr &= 0xFFFF; - txtMapEntryTileAddr.Text = "@" + addr.ToHexString(4); - } - - void UpdateColorDetails() - { - if (lastPalette == null) return; - - int rgb555 = lastPalette[lastColorNum]; - //var gd = NewDecoder(); //?? - int color = gd.Colorize(rgb555); - pnDetailsPaletteColor.BackColor = Color.FromArgb(color); - - txtDetailsPaletteColor.Text = string.Format("${0:X4}", rgb555); - txtDetailsPaletteColorHex.Text = string.Format("#{0:X6}", color & 0xFFFFFF); - txtDetailsPaletteColorRGB.Text = string.Format("({0},{1},{2})", (color >> 16) & 0xFF, (color >> 8) & 0xFF, (color & 0xFF)); - - txtPaletteDetailsIndexHex.Text = string.Format("${0:X2}", lastColorNum); - txtPaletteDetailsIndex.Text = string.Format("{0}", lastColorNum); - - //not being used anymore - //if (lastColorNum < 128) lblDetailsOBJOrBG.Text = "(BG:)"; else lblDetailsOBJOrBG.Text = "(OBJ:)"; - //txtPaletteDetailsIndexHexSpecific.Text = string.Format("${0:X2}", lastColorNum & 0x7F); - //txtPaletteDetailsIndexSpecific.Text = string.Format("{0}", lastColorNum & 0x7F); - - txtPaletteDetailsAddress.Text = string.Format("${0:X3}", lastColorNum * 2); - } - - - bool TranslatePaletteCoord(Point pt, out Point outpoint) - { - pt.X -= paletteCellSpacing; - pt.Y -= paletteCellSpacing; - int tx = pt.X / (paletteCellSize + paletteCellSpacing); - int ty = pt.Y / (paletteCellSize + paletteCellSpacing); - outpoint = new Point(tx, ty); - if (tx >= 16 || ty >= 16) return false; - return true; - } - - private void paletteViewer_MouseClick(object sender, MouseEventArgs e) - { - Point pt; - bool valid = TranslatePaletteCoord(e.Location, out pt); - if (!valid) return; - selectedColorNum = pt.Y * 16 + pt.X; - - if (currTileDataState != null) - { - currTileDataState.Palette = currPaletteSelection.start; - } - - SyncColorSelection(); - InternalUpdateValues(); - } - - void SyncColorSelection() - { - currPaletteSelection = GetPaletteSelectionForTileDisplay(selectedColorNum); - } - - private void pnDetailsPaletteColor_DoubleClick(object sender, EventArgs e) - { - //not workign real well... - //var cd = new ColorDialog(); - //cd.Color = pnDetailsPaletteColor.BackColor; - //cd.ShowDialog(this); - } - - private void rbQuad_CheckedChanged(object sender, EventArgs e) - { - SyncViewerSize(); - } - - void SyncViewerSize() - { - if (check2x.Checked) - - viewer.Size = new Size(1024, 1024); - else - viewer.Size = new Size(512, 512); - } - - private void checkScanlineControl_CheckedChanged(object sender, EventArgs e) - { - SyncCore(); - } - - private void check2x_CheckedChanged(object sender, EventArgs e) - { - SyncViewerSize(); - } - - bool viewerPan = false; - Point panStartLocation; - private void viewer_MouseDown(object sender, MouseEventArgs e) - { - viewer.Capture = true; - if ((e.Button & MouseButtons.Middle) != 0) - { - viewerPan = true; - panStartLocation = viewer.PointToScreen(e.Location); - Cursor = Cursors.SizeAll; - } - - if ((e.Button & MouseButtons.Right) != 0) - Freeze(); - } - - void Freeze() - { - groupFreeze.SuspendLayout(); - - Win32.SendMessage(groupFreeze.Handle, 11, (IntPtr)0, IntPtr.Zero); //WM_SETREDRAW false - - var tp = tabctrlDetails.SelectedTab; - - //clone the currently selected tab page into the destination - var oldControls = new ArrayList(pnGroupFreeze.Controls); - pnGroupFreeze.Controls.Clear(); - foreach (var control in tp.Controls) - pnGroupFreeze.Controls.Add((control as Control).Clone()); - foreach (var control in oldControls) - (control as Control).Dispose(); - - //set the freeze caption accordingly - if (tp == tpMapEntry) groupFreeze.Text = "Freeze - Map Entry"; - if (tp == tpPalette) groupFreeze.Text = "Freeze - Color"; - if (tp == tpTile) groupFreeze.Text = "Freeze - Tile"; - if (tp == tpOBJ) groupFreeze.Text = "Freeze - OBJ"; - - groupFreeze.ResumeLayout(); - - Win32.SendMessage(groupFreeze.Handle, 11, (IntPtr)1, IntPtr.Zero); //WM_SETREDRAW true - groupFreeze.Refresh(); - } - - enum eFreezeTarget - { - MainViewer - } - - private void viewer_MouseUp(object sender, MouseEventArgs e) - { - viewerPan = false; - viewer.Capture = false; - Cursor = Cursors.Default; - } - - private void viewer_MouseMove(object sender, MouseEventArgs e) - { - if (viewerPan) - { - var loc = viewer.PointToScreen(e.Location); - int dx = loc.X - panStartLocation.X; - int dy = loc.Y - panStartLocation.Y; - panStartLocation = loc; - - int x = viewerPanel.AutoScrollPosition.X; - int y = viewerPanel.AutoScrollPosition.Y; - x += dx; - y += dy; - viewerPanel.AutoScrollPosition = new Point(-x, -y); - } - else - { - if(si != null) - UpdateViewerMouseover(e.Location); - } - } - - class MapEntryState - { - public SNESGraphicsDecoder.TileEntry entry; - public int bgnum; - public Point Location; - } - MapEntryState currMapEntryState; - - class TileDataState - { - public eDisplayType Type; - public int Bpp; - public int Tile; - public int Address; - public int Palette; - } - TileDataState currTileDataState; - - class ObjDataState - { - public int Number; - } - ObjDataState currObjDataState; - - void RenderTileView() - { - if (currMapEntryState != null) - { - //view a BG tile - int paletteStart = 0; - var bgs = currMapEntryState; - var oneTileEntry = new SNESGraphicsDecoder.TileEntry[] { bgs.entry }; - int tileSize = si.BG[bgs.bgnum].TileSize; - int pixels = tileSize * tileSize; - - var bmp = new Bitmap(tileSize, tileSize, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - var bmpdata = bmp.LockBits(new Rectangle(0, 0, tileSize, tileSize), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - - if (viewBgMode == SNESGraphicsDecoder.BGMode.Mode7) - gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, false, false, 1, currMapEntryState.entry.tilenum, 1); - else if (viewBgMode == SNESGraphicsDecoder.BGMode.Mode7Ext) - gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, true, false, 1, currMapEntryState.entry.tilenum, 1); - else if (viewBgMode == SNESGraphicsDecoder.BGMode.Mode7DC) - gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, false, true, 1, currMapEntryState.entry.tilenum, 1); - else - { - gd.DecodeBG((int*)bmpdata.Scan0, bmpdata.Stride / 4, oneTileEntry, si.BG[bgs.bgnum].TiledataAddr, SNESGraphicsDecoder.ScreenSize.Hacky_1x1, si.BG[bgs.bgnum].Bpp, tileSize, paletteStart); - gd.Paletteize((int*)bmpdata.Scan0, 0, 0, pixels); - gd.Colorize((int*)bmpdata.Scan0, 0, pixels); - } - - bmp.UnlockBits(bmpdata); - viewerMapEntryTile.SetBitmap(bmp); - } - else if (currTileDataState != null) - { - //view a tileset tile - int bpp = currTileDataState.Bpp; - - var bmp = new Bitmap(8, 8, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - var bmpdata = bmp.LockBits(new Rectangle(0, 0, 8, 8), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - if (currTileDataState.Type == eDisplayType.TilesMode7) - gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, false, false, 1, currTileDataState.Tile, 1); - else if (currTileDataState.Type == eDisplayType.TilesMode7Ext) - gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, true, false, 1, currTileDataState.Tile, 1); - else if (currTileDataState.Type == eDisplayType.TilesMode7DC) - gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, false, true, 1, currTileDataState.Tile, 1); - else if (currTileDataState.Type == eDisplayType.OBJTiles0 || currTileDataState.Type == eDisplayType.OBJTiles1) - { - //render an obj tile - int tile = currTileDataState.Address / 32; - gd.RenderTilesToScreen((int*)bmpdata.Scan0, 1, 1, bmpdata.Stride / 4, bpp, currPaletteSelection.start, tile, 1); - } - else gd.RenderTilesToScreen((int*)bmpdata.Scan0, 1, 1, bmpdata.Stride / 4, bpp, currPaletteSelection.start, currTileDataState.Tile, 1); - - bmp.UnlockBits(bmpdata); - viewerTile.SetBitmap(bmp); - } - else if (currObjDataState != null) - { - var bounds = si.ObjSizeBoundsSquare; - int width = bounds.Width; - int height = bounds.Height; - var bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - var bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - gd.RenderSpriteToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, 0, 0, si, currObjDataState.Number); - bmp.UnlockBits(bmpdata); - viewerObj.SetBitmap(bmp); - } - else - { - var bmp = new Bitmap(8, 8, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - viewerTile.SetBitmap(bmp); - } - } - - void HandleTileViewMouseOver(int pxacross, int pxtall, int bpp, int tx, int ty) - { - int tilestride = pxacross / 8; - int tilesTall = pxtall / 8; - if (tx < 0 || ty < 0 || tx >= tilestride || ty >= tilesTall) - return; - int tilenum = ty * tilestride + tx; - currTileDataState = new TileDataState(); - currTileDataState.Bpp = bpp; - currTileDataState.Type = CurrDisplaySelection; - currTileDataState.Tile = tilenum; - currTileDataState.Address = (bpp==7?8:bpp) * 8 * currTileDataState.Tile; - currTileDataState.Palette = currPaletteSelection.start; - if (CurrDisplaySelection == eDisplayType.OBJTiles0 || CurrDisplaySelection == eDisplayType.OBJTiles1) - { - if (tilenum < 256) - currTileDataState.Address += si.OBJTable0Addr; - else - currTileDataState.Address += si.OBJTable1Addr - (256*32); - - currTileDataState.Address &= 0xFFFF; - } - else if (SNESGraphicsDecoder.BGModeIsMode7Type(BGModeForDisplayType(CurrDisplaySelection))) - { - currTileDataState.Address *= 2; - } - - SetTab(tpTile); - } - - void HandleSpriteMouseOver(int px, int py) - { - if (px < 0 || py < 0 || px >= 256 || py >= 224) return; - - int sprite = spriteMap[px,py]; - if(sprite == 0xFF) return; - - currObjDataState = new ObjDataState(); - currObjDataState.Number = sprite; - - SetTab(tpOBJ); - } - - void HandleObjMouseOver(int px, int py) - { - int ox = px / si.ObjSizeBounds.Width; - int oy = py / si.ObjSizeBounds.Height; - - if (ox < 0 || oy < 0 || ox >= 8 || oy >= 16) - return; - - int objNum = oy * 8 + ox; - - currObjDataState = new ObjDataState(); - currObjDataState.Number = objNum; - - //RenderView(); //remember, we were going to highlight the selected sprite somehow as we hover over it - SetTab(tpOBJ); - } - - void SetTab(TabPage tpSet) - { - //doesnt work well - //foreach (var tp in tabctrlDetails.TabPages) - // ((TabPage)tp).Visible = tpSet != null; - if (tpSet != null) - { - tpSet.Visible = true; - tabctrlDetails.SelectedTab = tpSet; - } - } - - void UpdateViewerMouseover(Point loc) - { - currMapEntryState = null; - currTileDataState = null; - currObjDataState = null; - - int tx = loc.X / 8; - int ty = loc.Y / 8; - - switch (CurrDisplaySelection) - { - case eDisplayType.OBJTiles0: - case eDisplayType.OBJTiles1: - HandleTileViewMouseOver(128, 256, 4, tx, ty); - break; - case eDisplayType.OBJ: - HandleObjMouseOver(loc.X, loc.Y); - break; - case eDisplayType.Sprites: - HandleSpriteMouseOver(loc.X, loc.Y); - break; - case eDisplayType.Tiles2bpp: - HandleTileViewMouseOver(512, 512, 2, tx, ty); - break; - case eDisplayType.Tiles4bpp: - HandleTileViewMouseOver(512, 256, 4, tx, ty); - break; - case eDisplayType.Tiles8bpp: - HandleTileViewMouseOver(256, 256, 8, tx, ty); - break; - case eDisplayType.TilesMode7: - case eDisplayType.TilesMode7DC: - HandleTileViewMouseOver(128, 128, 8, tx, ty); - break; - case eDisplayType.TilesMode7Ext: - HandleTileViewMouseOver(128, 128, 7, tx, ty); - break; - case eDisplayType.BG1: - case eDisplayType.BG2: - case eDisplayType.BG3: - case eDisplayType.BG4: - { - var bg = si.BG[(int)CurrDisplaySelection]; - - //unavailable BG for this mode - if (bg.Bpp == 0) - break; - - if (bg.TileSize == 16) { tx /= 2; ty /= 2; } //worry about this later. need to pass a different flag into `currViewingTile` - - int tloc = ty * bg.ScreenSizeInTiles.Width + tx; - if (tx >= bg.ScreenSizeInTiles.Width) break; - if (ty >= bg.ScreenSizeInTiles.Height) break; - if (tx < 0) break; - if (ty < 0) break; - - currMapEntryState = new MapEntryState(); - currMapEntryState.bgnum = (int)CurrDisplaySelection; - currMapEntryState.entry = map[tloc]; - currMapEntryState.Location = new Point(tx, ty); - - //public void DecodeBG(int* screen, int stride, TileEntry[] map, int tiledataBaseAddr, ScreenSize size, int bpp, int tilesize, int paletteStart) - - - //var map = gd.FetchTilemap(bg.ScreenAddr, bg.ScreenSize); - //int paletteStart = 0; - //gd.DecodeBG(pixelptr, stride / 4, map, bg.TiledataAddr, bg.ScreenSize, bg.Bpp, bg.TileSize, paletteStart); - //gd.Paletteize(pixelptr, 0, 0, numPixels); - - SetTab(tpMapEntry); - } - break; - } - - RenderTileView(); - UpdateMapEntryDetails(); - UpdateTileDetails(); - UpdateOBJDetails(); - } - - private void viewer_MouseLeave(object sender, EventArgs e) - { - SetTab(null); - } - - private void paletteViewer_MouseDown(object sender, MouseEventArgs e) - { - if ((e.Button & MouseButtons.Right) != 0) - Freeze(); - } - - private void paletteViewer_MouseEnter(object sender, EventArgs e) - { - tabctrlDetails.SelectedIndex = 0; - } - - private void paletteViewer_MouseLeave(object sender, EventArgs e) - { - SetTab(null); - } - - private void paletteViewer_MouseMove(object sender, MouseEventArgs e) - { - Point pt; - bool valid = TranslatePaletteCoord(e.Location, out pt); - if (!valid) return; - lastColorNum = pt.Y * 16 + pt.X; - UpdateColorDetails(); - SetTab(tpPalette); - } - - static int DecodeWinformsColorToSNES(Color winforms) - { - int r = winforms.R; - int g = winforms.G; - int b = winforms.B; - r >>= 3; - g >>= 3; - b >>= 3; - int col = r | (g << 5) | (b << 10); - return col; - } - - void SyncBackdropColor() - { - //TODO - //if (checkBackdropColor.Checked) - //{ - // int col = DecodeWinformsColorToSNES(pnBackdropColor.BackColor); - // LibsnesDll.snes_set_backdropColor(col); - //} - //else - //{ - // LibsnesDll.snes_set_backdropColor(-1); - //} - } - - private void checkBackdropColor_CheckedChanged(object sender, EventArgs e) - { - SyncBackdropColor(); - RegenerateData(); - } - - private void pnBackdropColor_MouseDoubleClick(object sender, MouseEventArgs e) - { - var cd = new ColorDialog(); - cd.Color = pnBackdropColor.BackColor; - if (cd.ShowDialog(this) == DialogResult.OK) - { - pnBackdropColor.BackColor = cd.Color; - UserBackdropColor = pnBackdropColor.BackColor.ToArgb(); - SyncBackdropColor(); - } - } - - protected override bool ProcessCmdKey(ref Message msg, Keys keyData) - { - if(keyData == (Keys.C | Keys.Control)) - { - // find the control under the mouse - Point m = Cursor.Position; - Control top = this; - Control found = null; - do - { - found = top.GetChildAtPoint(top.PointToClient(m), GetChildAtPointSkip.Invisible); - top = found; - } while (found != null && found.HasChildren); - - if (found != null && found is SNESGraphicsViewer) - { - var v = found as SNESGraphicsViewer; - lock (v) - { - var bmp = v.GetBitmap(); - Clipboard.SetImage(bmp); - } - string label = ""; - if (found.Name == "viewer") - label = displayTypeItems.Find((x) => x.Type == CurrDisplaySelection).Descr; - if (found.Name == "viewerTile") - label = "Tile"; - if (found.Name == "viewerMapEntryTile") - label = "Map Entry"; - if (found.Name == "paletteViewer") - label = "Palette"; - labelClipboard.Text = label + " copied to clipboard."; - messagetimer.Stop(); - messagetimer.Start(); - - return true; - } - } - - return base.ProcessCmdKey(ref msg, keyData); - } - - - private void messagetimer_Tick(object sender, EventArgs e) - { - messagetimer.Stop(); - labelClipboard.Text = "CTRL+C copies the pane under the mouse."; - } - - private void comboPalette_SelectedIndexChanged(object sender, EventArgs e) - { - if (suppression) return; - var pal = (SnesColors.ColorType)comboPalette.SelectedValue; - Console.WriteLine("set {0}", pal); - var s = Emulator.GetSettings(); - s.Palette = pal.ToString(); - if (currentSnesCore != null) - { - currentSnesCore.PutSettings(s); - } - RegenerateData(); - RenderView(); - RenderPalette(); - RenderTileView(); - } - - void RefreshBGENCheckStatesFromConfig() - { - var s = Emulator.GetSettings(); - checkEN0_BG1.Checked = s.ShowBG1_0; - checkEN0_BG2.Checked = s.ShowBG2_0; - checkEN0_BG3.Checked = s.ShowBG3_0; - checkEN0_BG4.Checked = s.ShowBG4_0; - checkEN1_BG1.Checked = s.ShowBG1_1; - checkEN1_BG2.Checked = s.ShowBG2_1; - checkEN1_BG3.Checked = s.ShowBG3_1; - checkEN1_BG4.Checked = s.ShowBG4_1; - checkEN0_OBJ.Checked = s.ShowOBJ_0; - checkEN1_OBJ.Checked = s.ShowOBJ_1; - checkEN2_OBJ.Checked = s.ShowOBJ_2; - checkEN3_OBJ.Checked = s.ShowOBJ_3; - } - - private void checkEN_CheckedChanged(object sender, EventArgs e) - { - if(suppression) return; - var snes = Emulator; - var s = snes.GetSettings(); - if (sender == checkEN0_BG1) s.ShowBG1_0 = checkEN0_BG1.Checked; - if (sender == checkEN0_BG2) s.ShowBG2_0 = checkEN0_BG2.Checked; - if (sender == checkEN0_BG3) s.ShowBG3_0 = checkEN0_BG3.Checked; - if (sender == checkEN0_BG4) s.ShowBG4_0 = checkEN0_BG4.Checked; - if (sender == checkEN1_BG1) s.ShowBG1_1 = checkEN1_BG1.Checked; - if (sender == checkEN1_BG2) s.ShowBG2_1 = checkEN1_BG2.Checked; - if (sender == checkEN1_BG3) s.ShowBG3_1 = checkEN1_BG3.Checked; - if (sender == checkEN1_BG4) s.ShowBG4_1 = checkEN1_BG4.Checked; - if (sender == checkEN0_OBJ) s.ShowOBJ_0 = checkEN0_OBJ.Checked; - if (sender == checkEN1_OBJ) s.ShowOBJ_1 = checkEN1_OBJ.Checked; - if (sender == checkEN2_OBJ) s.ShowOBJ_2 = checkEN2_OBJ.Checked; - if (sender == checkEN3_OBJ) s.ShowOBJ_3 = checkEN3_OBJ.Checked; - - if ((ModifierKeys & Keys.Shift) != 0) - { - if (sender == checkEN0_BG1) s.ShowBG1_1 = s.ShowBG1_0; - if (sender == checkEN1_BG1) s.ShowBG1_0 = s.ShowBG1_1; - if (sender == checkEN0_BG2) s.ShowBG2_1 = s.ShowBG2_0; - if (sender == checkEN1_BG2) s.ShowBG2_0 = s.ShowBG2_1; - if (sender == checkEN0_BG3) s.ShowBG3_1 = s.ShowBG3_0; - if (sender == checkEN1_BG3) s.ShowBG3_0 = s.ShowBG3_1; - if (sender == checkEN0_BG4) s.ShowBG4_1 = s.ShowBG4_0; - if (sender == checkEN1_BG4) s.ShowBG4_0 = s.ShowBG4_1; - if (sender == checkEN0_OBJ) s.ShowOBJ_1 = s.ShowOBJ_2 = s.ShowOBJ_3 = s.ShowOBJ_0; - if (sender == checkEN1_OBJ) s.ShowOBJ_0 = s.ShowOBJ_2 = s.ShowOBJ_3 = s.ShowOBJ_1; - if (sender == checkEN2_OBJ) s.ShowOBJ_0 = s.ShowOBJ_1 = s.ShowOBJ_3 = s.ShowOBJ_2; - if (sender == checkEN3_OBJ) s.ShowOBJ_0 = s.ShowOBJ_1 = s.ShowOBJ_2 = s.ShowOBJ_3; - suppression = true; - RefreshBGENCheckStatesFromConfig(); - suppression = false; - } - snes.PutSettings(s); - } - - private void lblEnPrio0_Click(object sender, EventArgs e) - { - bool any = checkEN0_OBJ.Checked || checkEN0_BG1.Checked || checkEN0_BG2.Checked || checkEN0_BG3.Checked || checkEN0_BG4.Checked; - bool all = checkEN0_OBJ.Checked && checkEN0_BG1.Checked && checkEN0_BG2.Checked && checkEN0_BG3.Checked && checkEN0_BG4.Checked; - bool newval; - if (all) newval = false; - else newval = true; - checkEN0_OBJ.Checked = checkEN0_BG1.Checked = checkEN0_BG2.Checked = checkEN0_BG3.Checked = checkEN0_BG4.Checked = newval; - - } - - private void lblEnPrio1_Click(object sender, EventArgs e) - { - bool any = checkEN1_OBJ.Checked || checkEN1_BG1.Checked || checkEN1_BG2.Checked || checkEN1_BG3.Checked || checkEN1_BG4.Checked; - bool all = checkEN1_OBJ.Checked && checkEN1_BG1.Checked && checkEN1_BG2.Checked && checkEN1_BG3.Checked && checkEN1_BG4.Checked; - bool newval; - if (all) newval = false; - else newval = true; - checkEN1_OBJ.Checked = checkEN1_BG1.Checked = checkEN1_BG2.Checked = checkEN1_BG3.Checked = checkEN1_BG4.Checked = newval; - - } - - private void lblEnPrio2_Click(object sender, EventArgs e) - { - checkEN2_OBJ.Checked ^= true; - } - - private void lblEnPrio3_Click(object sender, EventArgs e) - { - checkEN3_OBJ.Checked ^= true; - } - - } //class SNESGraphicsDebugger -} //namespace BizHawk.Client.EmuHawk - - -static class ControlExtensions -{ - static string[] secondPass = new[] { "Size" }; - public static T Clone(this T controlToClone) - where T : Control - { - PropertyInfo[] controlProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); - - Type t = controlToClone.GetType(); - T instance = Activator.CreateInstance(t) as T; - - t.GetProperty("AutoSize").SetValue(instance, false, null); - - for (int i = 0; i < 3; i++) - { - foreach (PropertyInfo propInfo in controlProperties) - { - if (!propInfo.CanWrite) - continue; - - if (propInfo.Name == "AutoSize") - { } - else if (propInfo.Name == "WindowTarget") - { } - else - propInfo.SetValue(instance, propInfo.GetValue(controlToClone, null), null); - } - } - - if (instance is RetainedViewportPanel) - { - var clonebmp = ((controlToClone) as RetainedViewportPanel).GetBitmap().Clone() as Bitmap; - ((instance) as RetainedViewportPanel).SetBitmap(clonebmp); - } - - return instance; - } -} \ No newline at end of file + } + } + + private void nudScanline_ValueChanged(object sender, EventArgs e) + { + if (suppression) return; + SyncCore(); + suppression = true; + sliderScanline.Value = 224 - (int)nudScanline.Value; + suppression = false; + } + + private void sliderScanline_ValueChanged(object sender, EventArgs e) + { + if (suppression) return; + checkScanlineControl.Checked = true; + SyncCore(); + suppression = true; + nudScanline.Value = 224 - sliderScanline.Value; + suppression = false; + } + + void SyncCore() + { + if (currentSnesCore != Emulator && currentSnesCore != null) + { + currentSnesCore.ScanlineHookManager.Unregister(this); + } + + if (currentSnesCore != Emulator && Emulator != null) + { + suppression = true; + comboPalette.SelectedValue = Emulator.CurrPalette; + RefreshBGENCheckStatesFromConfig(); + suppression = false; + } + + currentSnesCore = Emulator; + + if (currentSnesCore != null) + { + if (Visible && checkScanlineControl.Checked) + currentSnesCore.ScanlineHookManager.Register(this, ScanlineHook); + else + currentSnesCore.ScanlineHookManager.Unregister(this); + } + } + + void ScanlineHook(int line) + { + int target = (int)nudScanline.Value; + if (target == line) + { + RegenerateData(); + InternalUpdateValues(); + } + } + + SNESGraphicsDecoder gd; + SNESGraphicsDecoder.ScreenInfo si; + SNESGraphicsDecoder.TileEntry[] map; + byte[,] spriteMap = new byte[256, 224]; + SNESGraphicsDecoder.BGMode viewBgMode; + + void RegenerateData() + { + if (gd != null) gd.Dispose(); + gd = null; + if (currentSnesCore == null) return; + gd = NewDecoder(); + using (gd.EnterExit()) + { + if (checkBackdropColor.Checked) + gd.SetBackColor(DecodeWinformsColorToSNES(pnBackdropColor.BackColor)); + gd.CacheTiles(); + si = gd.ScanScreenInfo(); + } + } + + private void InternalUpdateValues() + { + if (currentSnesCore == null) return; + using (gd.EnterExit()) + { + txtOBSELSizeBits.Text = si.OBSEL_Size.ToString(); + txtOBSELBaseBits.Text = si.OBSEL_NameBase.ToString(); + txtOBSELT1OfsBits.Text = si.OBSEL_NameSel.ToString(); + txtOBSELSizeDescr.Text = string.Format("{0}, {1}", SNESGraphicsDecoder.ObjSizes[si.OBSEL_Size, 0], SNESGraphicsDecoder.ObjSizes[si.OBSEL_Size, 1]); + txtOBSELBaseDescr.Text = FormatVramAddress(si.OBJTable0Addr); + txtOBSELT1OfsDescr.Text = FormatVramAddress(si.OBJTable1Addr); + + checkScreenExtbg.Checked = si.SETINI_Mode7ExtBG; + checkScreenHires.Checked = si.SETINI_HiRes; + checkScreenOverscan.Checked = si.SETINI_Overscan; + checkScreenObjInterlace.Checked = si.SETINI_ObjInterlace; + checkScreenInterlace.Checked = si.SETINI_ScreenInterlace; + + txtScreenCGWSEL_ColorMask.Text = si.CGWSEL_ColorMask.ToString(); + txtScreenCGWSEL_ColorSubMask.Text = si.CGWSEL_ColorSubMask.ToString(); + txtScreenCGWSEL_MathFixed.Text = si.CGWSEL_AddSubMode.ToString(); + checkScreenCGWSEL_DirectColor.Checked = si.CGWSEL_DirectColor; + txtScreenCGADSUB_AddSub.Text = si.CGWSEL_AddSubMode.ToString(); + txtScreenCGADSUB_AddSub_Descr.Text = si.CGADSUB_AddSub == 1 ? "SUB" : "ADD"; + txtScreenCGADSUB_Half.Checked = si.CGADSUB_Half; + + txtModeBits.Text = si.Mode.MODE.ToString(); + txtScreenBG1Bpp.Text = FormatBpp(si.BG.BG1.Bpp); + txtScreenBG2Bpp.Text = FormatBpp(si.BG.BG2.Bpp); + txtScreenBG3Bpp.Text = FormatBpp(si.BG.BG3.Bpp); + txtScreenBG4Bpp.Text = FormatBpp(si.BG.BG4.Bpp); + txtScreenBG1TSize.Text = FormatBpp(si.BG.BG1.TileSize); + txtScreenBG2TSize.Text = FormatBpp(si.BG.BG2.TileSize); + txtScreenBG3TSize.Text = FormatBpp(si.BG.BG3.TileSize); + txtScreenBG4TSize.Text = FormatBpp(si.BG.BG4.TileSize); + + int bgnum = comboBGProps.SelectedIndex + 1; + + var bg = si.BG[bgnum]; + txtBG1TSizeBits.Text = bg.TILESIZE.ToString(); + txtBG1TSizeDescr.Text = string.Format("{0}x{0}", bg.TileSize); + txtBG1Bpp.Text = FormatBpp(bg.Bpp); + txtBG1SizeBits.Text = bg.SCSIZE.ToString(); + txtBG1SizeInTiles.Text = bg.ScreenSizeInTiles.ToString(); + int size = bg.ScreenSizeInTiles.Width * bg.ScreenSizeInTiles.Height * 2 / 1024; + txtBG1MapSizeBytes.Text = string.Format("({0}K)", size); + txtBG1SCAddrBits.Text = bg.SCADDR.ToString(); + txtBG1SCAddrDescr.Text = FormatVramAddress(bg.ScreenAddr); + txtBG1Colors.Text = (1 << bg.Bpp).ToString(); + if (bg.Bpp == 8 && si.CGWSEL_DirectColor) txtBG1Colors.Text = "(Direct Color)"; + txtBG1TDAddrBits.Text = bg.TDADDR.ToString(); + txtBG1TDAddrDescr.Text = FormatVramAddress(bg.TiledataAddr); + + txtBG1Scroll.Text = string.Format("({0},{1})", bg.HOFS, bg.VOFS); + + if (bg.Bpp != 0) + { + var pi = bg.PaletteSelection; + txtBGPaletteInfo.Text = string.Format("{0} colors from ${1:X2} - ${2:X2}", pi.size, pi.start, pi.start + pi.size - 1); + } + else txtBGPaletteInfo.Text = ""; + + var sizeInPixels = bg.ScreenSizeInPixels; + txtBG1SizeInPixels.Text = string.Format("{0}x{1}", sizeInPixels.Width, sizeInPixels.Height); + + checkTMOBJ.Checked = si.OBJ_MainEnabled; + checkTMBG1.Checked = si.BG.BG1.MainEnabled; + checkTMBG2.Checked = si.BG.BG2.MainEnabled; + checkTMBG3.Checked = si.BG.BG3.MainEnabled; + checkTMBG4.Checked = si.BG.BG4.MainEnabled; + checkTMOBJ.Checked = si.OBJ_SubEnabled; + checkTSBG1.Checked = si.BG.BG1.SubEnabled; + checkTSBG2.Checked = si.BG.BG2.SubEnabled; + checkTSBG3.Checked = si.BG.BG3.SubEnabled; + checkTSBG4.Checked = si.BG.BG4.SubEnabled; + checkTSOBJ.Checked = si.OBJ_MainEnabled; + checkMathOBJ.Checked = si.OBJ_MathEnabled; + checkMathBK.Checked = si.BK_MathEnabled; + checkMathBG1.Checked = si.BG.BG1.MathEnabled; + checkMathBG2.Checked = si.BG.BG2.MathEnabled; + checkMathBG3.Checked = si.BG.BG3.MathEnabled; + checkMathBG4.Checked = si.BG.BG4.MathEnabled; + + if (si.Mode.MODE == 1 && si.Mode1_BG3_Priority) + { + lblBG3.ForeColor = Color.Red; + if (toolTip1.GetToolTip(lblBG3) != "Mode 1 BG3 priority toggle bit of $2105 is SET") + toolTip1.SetToolTip(lblBG3, "Mode 1 BG3 priority toggle bit of $2105 is SET"); + } + else + { + lblBG3.ForeColor = Color.Black; + if (toolTip1.GetToolTip(lblBG3) != "Mode 1 BG3 priority toggle bit of $2105 is CLEAR") + toolTip1.SetToolTip(lblBG3, "Mode 1 BG3 priority toggle bit of $2105 is CLEAR"); + } + + SyncColorSelection(); + RenderView(); + RenderPalette(); + RenderTileView(); + //these are likely to be changing all the time + UpdateColorDetails(); + UpdateOBJDetails(); + //maybe bg settings changed, or something + UpdateMapEntryDetails(); + UpdateTileDetails(); + } + } + + eDisplayType CurrDisplaySelection { get { return (comboDisplayType.SelectedValue as eDisplayType?).Value; } } + + //todo - something smarter to cycle through bitmaps without repeatedly trashing them (use the dispose callback on the viewer) + private void RenderView() + { + Bitmap bmp = null; + System.Drawing.Imaging.BitmapData bmpdata = null; + int* pixelptr = null; + int stride = 0; + + Action allocate = (w, h) => + { + bmp = new Bitmap(w, h); + bmpdata = bmp.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + pixelptr = (int*)bmpdata.Scan0.ToPointer(); + stride = bmpdata.Stride; + }; + + var selection = CurrDisplaySelection; + if (selection == eDisplayType.OBJ) + { + var objBounds = si.ObjSizeBounds; + int width = objBounds.Width * 8; + int height = objBounds.Height * 16; + allocate(width, height); + for (int i = 0; i < 128; i++) + { + int tx = i % 8; + int ty = i / 8; + int x = tx * objBounds.Width; + int y = ty * objBounds.Height; + gd.RenderSpriteToScreen(pixelptr, stride / 4, x,y, si, i); + } + } + if (selection == eDisplayType.Sprites) + { + //render sprites in-place + allocate(256, 224); + for (int y = 0; y < 224; y++) for (int x = 0; x < 256; x++) spriteMap[x, y] = 0xFF; + for(int i=127;i>=0;i--) + { + var oam = new SNESGraphicsDecoder.OAMInfo(gd, si, i); + gd.RenderSpriteToScreen(pixelptr, stride / 4, oam.X, oam.Y, si, i, oam, 256, 224, spriteMap); + } + } + if (selection == eDisplayType.OBJTiles0 || selection == eDisplayType.OBJTiles1) + { + allocate(128, 256); + int startTile; + startTile = si.OBJTable0Addr / 32; + gd.RenderTilesToScreen(pixelptr, 16, 16, stride / 4, 4, currPaletteSelection.start, startTile, 256, true); + startTile = si.OBJTable1Addr / 32; + gd.RenderTilesToScreen(pixelptr + (stride/4*8*16), 16, 16, stride / 4, 4, currPaletteSelection.start, startTile, 256, true); + } + if (selection == eDisplayType.Tiles2bpp) + { + allocate(512, 512); + gd.RenderTilesToScreen(pixelptr, 64, 64, stride / 4, 2, currPaletteSelection.start); + } + if (selection == eDisplayType.Tiles4bpp) + { + allocate(512, 512); + gd.RenderTilesToScreen(pixelptr, 64, 32, stride / 4, 4, currPaletteSelection.start); + } + if (selection == eDisplayType.Tiles8bpp) + { + allocate(256, 256); + gd.RenderTilesToScreen(pixelptr, 32, 32, stride / 4, 8, currPaletteSelection.start); + } + if (selection == eDisplayType.TilesMode7) + { + //256 tiles + allocate(128, 128); + gd.RenderMode7TilesToScreen(pixelptr, stride / 4, false, false); + } + if (selection == eDisplayType.TilesMode7Ext) + { + //256 tiles + allocate(128, 128); + gd.RenderMode7TilesToScreen(pixelptr, stride / 4, true, false); + } + if (selection == eDisplayType.TilesMode7DC) + { + //256 tiles + allocate(128, 128); + gd.RenderMode7TilesToScreen(pixelptr, stride / 4, false, true); + } + if (IsDisplayTypeBG(selection)) + { + int bgnum = (int)selection; + var bg = si.BG[bgnum]; + + map = new SNESGraphicsDecoder.TileEntry[0]; + viewBgMode = bg.BGMode; + + //bool handled = false; + if (bg.Enabled) + { + //TODO - directColor in normal BG renderer + bool DirectColor = si.CGWSEL_DirectColor && bg.Bpp == 8; //any exceptions? + int numPixels = 0; + //TODO - could use BGMode property on BG... too much chaos to deal with it now + if (si.Mode.MODE == 7) + { + bool mode7 = bgnum == 1; + bool mode7extbg = (bgnum == 2 && si.SETINI_Mode7ExtBG); + if (mode7 || mode7extbg) + { + //handled = true; + allocate(1024, 1024); + gd.DecodeMode7BG(pixelptr, stride / 4, mode7extbg); + numPixels = 128 * 128 * 8 * 8; + if (DirectColor) gd.DirectColorify(pixelptr, numPixels); + else gd.Paletteize(pixelptr, 0, 0, numPixels); + + //get a fake map, since mode7 doesnt really have a map + map = gd.FetchMode7Tilemap(); + } + } + else + { + //handled = true; + var dims = bg.ScreenSizeInPixels; + dims.Height = dims.Width = Math.Max(dims.Width, dims.Height); + allocate(dims.Width, dims.Height); + numPixels = dims.Width * dims.Height; + System.Diagnostics.Debug.Assert(stride / 4 == dims.Width); + + map = gd.FetchTilemap(bg.ScreenAddr, bg.ScreenSize); + int paletteStart = 0; + gd.DecodeBG(pixelptr, stride / 4, map, bg.TiledataAddr, bg.ScreenSize, bg.Bpp, bg.TileSize, paletteStart); + gd.Paletteize(pixelptr, 0, 0, numPixels); + } + + gd.Colorize(pixelptr, 0, numPixels); + } + } + + if (bmp != null) + { + bmp.UnlockBits(bmpdata); + viewer.SetBitmap(bmp); + } + } + + enum eDisplayType + { + BG1 = 1, BG2 = 2, BG3 = 3, BG4 = 4, OBJTiles0, OBJTiles1, Tiles2bpp, Tiles4bpp, Tiles8bpp, TilesMode7, TilesMode7Ext, TilesMode7DC, Sprites, OBJ, + BG1Screen = 101, BG2Screen = 102, BG3Screen = 103, BG4Screen = 104, + } + static bool IsDisplayTypeBG(eDisplayType type) { return type == eDisplayType.BG1 || type == eDisplayType.BG2 || type == eDisplayType.BG3 || type == eDisplayType.BG4; } + static bool IsDisplayTypeOBJ(eDisplayType type) { return type == eDisplayType.OBJTiles0 || type == eDisplayType.OBJTiles1; } + static int DisplayTypeBGNum(eDisplayType type) { if(IsDisplayTypeBG(type)) return (int)type; else return -1; } + static SNESGraphicsDecoder.BGMode BGModeForDisplayType(eDisplayType type) + { + switch (type) + { + case eDisplayType.Tiles2bpp: return SNESGraphicsDecoder.BGMode.Text; + case eDisplayType.Tiles4bpp: return SNESGraphicsDecoder.BGMode.Text; + case eDisplayType.Tiles8bpp: return SNESGraphicsDecoder.BGMode.Text; + case eDisplayType.TilesMode7: return SNESGraphicsDecoder.BGMode.Mode7; + case eDisplayType.TilesMode7Ext: return SNESGraphicsDecoder.BGMode.Mode7Ext; + case eDisplayType.TilesMode7DC: return SNESGraphicsDecoder.BGMode.Mode7DC; + case eDisplayType.OBJTiles0: return SNESGraphicsDecoder.BGMode.OBJ; + case eDisplayType.OBJTiles1: return SNESGraphicsDecoder.BGMode.OBJ; + default: throw new InvalidOperationException(); + } + } + + class DisplayTypeItem + { + public eDisplayType Type { get; private set; } + public string Descr { get; private set; } + public DisplayTypeItem(string descr, eDisplayType type) + { + Type = type; + Descr = descr; + } + } + + class PaletteTypeItem + { + public SnesColors.ColorType Type { get; private set; } + public string Descr { get; private set; } + public PaletteTypeItem(string descr, SnesColors.ColorType type) + { + Type = type; + Descr = descr; + } + } + + private void comboDisplayType_SelectedIndexChanged(object sender, EventArgs e) + { + InternalUpdateValues(); + + //change the bg props viewer to match + if (IsDisplayTypeBG(CurrDisplaySelection)) + comboBGProps.SelectedIndex = DisplayTypeBGNum(CurrDisplaySelection) - 1; + } + + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + Close(); + } + + private void SNESGraphicsDebugger_Load(object sender, EventArgs e) + { + if (UserBackdropColor != -1) + { + pnBackdropColor.BackColor = Color.FromArgb(UserBackdropColor); + } + if (checkBackdropColor.Checked) + { + SyncBackdropColor(); + } + + UpdateToolsLoadstate(); + } + + bool suppression = false; + private void rbBGX_CheckedChanged(object sender, EventArgs e) + { + if (suppression) return; + //sync the comboBGProps dropdown with the result of this check + suppression = true; + if (rbBG1.Checked) comboBGProps.SelectedIndex = 0; + if (rbBG2.Checked) comboBGProps.SelectedIndex = 1; + if (rbBG3.Checked) comboBGProps.SelectedIndex = 2; + if (rbBG4.Checked) comboBGProps.SelectedIndex = 3; + suppression = false; + InternalUpdateValues(); + } + + private void comboBGProps_SelectedIndexChanged(object sender, EventArgs e) + { + if (suppression) return; + + //sync the radiobuttons with this selection + suppression = true; + if (comboBGProps.SelectedIndex == 0) rbBG1.Checked = true; + if (comboBGProps.SelectedIndex == 1) rbBG2.Checked = true; + if (comboBGProps.SelectedIndex == 2) rbBG3.Checked = true; + if (comboBGProps.SelectedIndex == 3) rbBG4.Checked = true; + suppression = false; + InternalUpdateValues(); + } + + const int paletteCellSize = 16; + const int paletteCellSpacing = 3; + + int[] lastPalette; + int lastColorNum = 0; + int selectedColorNum = 0; + SNESGraphicsDecoder.PaletteSelection currPaletteSelection; + + Rectangle GetPaletteRegion(int start, int num) + { + var ret = new Rectangle(); + ret.X = start % 16; + ret.Y = start / 16; + ret.Width = num; + ret.Height = num / 16; + if (ret.Height == 0) ret.Height = 1; + if (ret.Width > 16) ret.Width = 16; + return ret; + } + + Rectangle GetPaletteRegion(SNESGraphicsDecoder.PaletteSelection sel) + { + int start = sel.start, num = sel.size; + return GetPaletteRegion(start, num); + } + + void DrawPaletteRegion(Graphics g, Color color, Rectangle region) + { + int cellTotalSize = (paletteCellSize + paletteCellSpacing); + + int x = paletteCellSpacing + region.X * cellTotalSize - 2; + int y = paletteCellSpacing + region.Y * cellTotalSize - 2; + int width = cellTotalSize * region.Width; + int height = cellTotalSize * region.Height; + + var rect = new Rectangle(x, y, width, height); + using (var pen = new Pen(color)) + g.DrawRectangle(pen, rect); + } + + //if a tile set is being displayed, this will adapt the user's color selection into a palette to be used for rendering the tiles + SNESGraphicsDecoder.PaletteSelection GetPaletteSelectionForTileDisplay(int colorSelection) + { + int bpp = 0; + var selection = CurrDisplaySelection; + if (selection == eDisplayType.Tiles2bpp) bpp = 2; + if (selection == eDisplayType.Tiles4bpp) bpp = 4; + if (selection == eDisplayType.Tiles8bpp) bpp = 8; + if (selection == eDisplayType.TilesMode7) bpp = 8; + if (selection == eDisplayType.TilesMode7Ext) bpp = 7; + if (selection == eDisplayType.OBJTiles0) bpp = 4; + if (selection == eDisplayType.OBJTiles1) bpp = 4; + + SNESGraphicsDecoder.PaletteSelection ret = new SNESGraphicsDecoder.PaletteSelection(); + if(bpp == 0) return ret; + + //mode7 ext is fixed to use the top 128 colors + if (bpp == 7) + { + ret.size = 128; + ret.start = 0; + return ret; + } + + ret.size = 1 << bpp; + ret.start = colorSelection & (~(ret.size - 1)); + return ret; + } + + SNESGraphicsDecoder NewDecoder() + { + if (currentSnesCore != null) + return new SNESGraphicsDecoder(currentSnesCore.Api, currentSnesCore.CurrPalette); + else + return null; + } + + void RenderPalette() + { + //var gd = NewDecoder(); //?? + lastPalette = gd.GetPalette(); + + int pixsize = paletteCellSize * 16 + paletteCellSpacing * 17; + int cellTotalSize = (paletteCellSize + paletteCellSpacing); + var bmp = new Bitmap(pixsize, pixsize, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + using (var g = Graphics.FromImage(bmp)) + { + for (int y = 0; y < 16; y++) + { + for (int x = 0; x < 16; x++) + { + int rgb555 = lastPalette[y * 16 + x]; + int color = gd.Colorize(rgb555); + using (var brush = new SolidBrush(Color.FromArgb(color))) + { + g.FillRectangle(brush, new Rectangle(paletteCellSpacing + x * cellTotalSize, paletteCellSpacing + y * cellTotalSize, paletteCellSize, paletteCellSize)); + } + } + } + + //draw selection boxes: + //first, draw the current selection + var region = GetPaletteRegion(selectedColorNum, 1); + DrawPaletteRegion(g, Color.Red, region); + //next, draw the rectangle that advises you which colors could possibly be used for a bg + if (IsDisplayTypeBG(CurrDisplaySelection)) + { + var ps = si.BG[DisplayTypeBGNum(CurrDisplaySelection)].PaletteSelection; + region = GetPaletteRegion(ps); + DrawPaletteRegion(g, Color.FromArgb(192, 128, 255, 255), region); + } + if (IsDisplayTypeOBJ(CurrDisplaySelection)) + { + var ps = new SNESGraphicsDecoder.PaletteSelection(128, 128); + region = GetPaletteRegion(ps); + DrawPaletteRegion(g, Color.FromArgb(192, 128, 255, 255), region); + } + //finally, draw the palette the user has chosen, in case he's viewing tiles + if (currPaletteSelection.size != 0) + { + region = GetPaletteRegion(currPaletteSelection.start, currPaletteSelection.size); + DrawPaletteRegion(g, Color.FromArgb(192,255,255,255), region); + } + } + + paletteViewer.SetBitmap(bmp); + } + + static string BGModeShortName(SNESGraphicsDecoder.BGMode mode, int bpp) + { + if (mode == SNESGraphicsDecoder.BGMode.Unavailable) return "Unavailable"; + if (mode == SNESGraphicsDecoder.BGMode.Text) return string.Format("Text{0}bpp", bpp); + if (mode == SNESGraphicsDecoder.BGMode.OBJ) return string.Format("OBJ", bpp); + if (mode == SNESGraphicsDecoder.BGMode.Mode7) return "Mode7"; + if (mode == SNESGraphicsDecoder.BGMode.Mode7Ext) return "Mode7Ext"; + if (mode == SNESGraphicsDecoder.BGMode.Mode7DC) return "Mode7DC"; + throw new InvalidOperationException(); + } + + void UpdateOBJDetails() + { + if (currObjDataState == null) return; + var oam = new SNESGraphicsDecoder.OAMInfo(gd, si, currObjDataState.Number); + txtObjNumber.Text = string.Format("#${0:X2}", currObjDataState.Number); + txtObjCoord.Text = string.Format("({0}, {1})",oam.X,oam.Y); + cbObjHFlip.Checked = oam.HFlip; + cbObjVFlip.Checked = oam.VFlip; + cbObjLarge.Checked = oam.Size == 1; + txtObjSize.Text = SNESGraphicsDecoder.ObjSizes[si.OBSEL_Size, oam.Size].ToString(); + txtObjPriority.Text = oam.Priority.ToString(); + txtObjPalette.Text = oam.Palette.ToString(); + txtObjPaletteMemo.Text = string.Format("${0:X2}", oam.Palette * 16 + 128); + txtObjName.Text = string.Format("#${0:X3}", oam.Tile); + txtObjNameAddr.Text = string.Format("@{0:X4}", oam.Address); + } + + void UpdateTileDetails() + { + if (currTileDataState == null) return; + var mode = BGModeForDisplayType(currTileDataState.Type); + int bpp = currTileDataState.Bpp; + txtTileMode.Text = BGModeShortName(mode, bpp); + txtTileBpp.Text = currTileDataState.Bpp.ToString(); + txtTileColors.Text = (1 << currTileDataState.Bpp).ToString(); + txtTileNumber.Text = string.Format("#${0:X3}", currTileDataState.Tile); + txtTileAddress.Text = string.Format("@{0:X4}", currTileDataState.Address); + txtTilePalette.Text = string.Format("#{0:X2}", currTileDataState.Palette); + } + + void UpdateMapEntryDetails() + { + if (currMapEntryState == null) return; + txtMapEntryLocation.Text = string.Format("({0},{1}), @{2:X4}", currMapEntryState.Location.X, currMapEntryState.Location.Y, currMapEntryState.entry.address); + txtMapEntryTileNum.Text = string.Format("${0:X3}", currMapEntryState.entry.tilenum); + txtMapEntryPrio.Text = string.Format("{0}", (currMapEntryState.entry.flags & SNESGraphicsDecoder.TileEntryFlags.Priority)!=0?1:0); + txtMapEntryPalette.Text = string.Format("{0}", currMapEntryState.entry.palette); + checkMapEntryHFlip.Checked = (currMapEntryState.entry.flags & SNESGraphicsDecoder.TileEntryFlags.Horz) != 0; + checkMapEntryVFlip.Checked = (currMapEntryState.entry.flags & SNESGraphicsDecoder.TileEntryFlags.Vert) != 0; + + //calculate address of tile + var bg = si.BG[currMapEntryState.bgnum]; + int bpp = bg.Bpp; + int tiledataBaseAddr = bg.TiledataAddr; + int tileSizeBytes = 8 * bpp; + int baseTileNum = tiledataBaseAddr / tileSizeBytes; + int tileNum = baseTileNum + currMapEntryState.entry.tilenum; + int addr = tileNum * tileSizeBytes; + + //mode7 takes up 128 bytes per tile because its interleaved with the screen data + if (bg.BGModeIsMode7Type) + addr *= 2; + + addr &= 0xFFFF; + txtMapEntryTileAddr.Text = "@" + addr.ToHexString(4); + } + + void UpdateColorDetails() + { + if (lastPalette == null) return; + + int rgb555 = lastPalette[lastColorNum]; + //var gd = NewDecoder(); //?? + int color = gd.Colorize(rgb555); + pnDetailsPaletteColor.BackColor = Color.FromArgb(color); + + txtDetailsPaletteColor.Text = string.Format("${0:X4}", rgb555); + txtDetailsPaletteColorHex.Text = string.Format("#{0:X6}", color & 0xFFFFFF); + txtDetailsPaletteColorRGB.Text = string.Format("({0},{1},{2})", (color >> 16) & 0xFF, (color >> 8) & 0xFF, (color & 0xFF)); + + txtPaletteDetailsIndexHex.Text = string.Format("${0:X2}", lastColorNum); + txtPaletteDetailsIndex.Text = string.Format("{0}", lastColorNum); + + //not being used anymore + //if (lastColorNum < 128) lblDetailsOBJOrBG.Text = "(BG:)"; else lblDetailsOBJOrBG.Text = "(OBJ:)"; + //txtPaletteDetailsIndexHexSpecific.Text = string.Format("${0:X2}", lastColorNum & 0x7F); + //txtPaletteDetailsIndexSpecific.Text = string.Format("{0}", lastColorNum & 0x7F); + + txtPaletteDetailsAddress.Text = string.Format("${0:X3}", lastColorNum * 2); + } + + + bool TranslatePaletteCoord(Point pt, out Point outpoint) + { + pt.X -= paletteCellSpacing; + pt.Y -= paletteCellSpacing; + int tx = pt.X / (paletteCellSize + paletteCellSpacing); + int ty = pt.Y / (paletteCellSize + paletteCellSpacing); + outpoint = new Point(tx, ty); + if (tx >= 16 || ty >= 16) return false; + return true; + } + + private void paletteViewer_MouseClick(object sender, MouseEventArgs e) + { + Point pt; + bool valid = TranslatePaletteCoord(e.Location, out pt); + if (!valid) return; + selectedColorNum = pt.Y * 16 + pt.X; + + if (currTileDataState != null) + { + currTileDataState.Palette = currPaletteSelection.start; + } + + SyncColorSelection(); + InternalUpdateValues(); + } + + void SyncColorSelection() + { + currPaletteSelection = GetPaletteSelectionForTileDisplay(selectedColorNum); + } + + private void pnDetailsPaletteColor_DoubleClick(object sender, EventArgs e) + { + //not workign real well... + //var cd = new ColorDialog(); + //cd.Color = pnDetailsPaletteColor.BackColor; + //cd.ShowDialog(this); + } + + private void rbQuad_CheckedChanged(object sender, EventArgs e) + { + SyncViewerSize(); + } + + void SyncViewerSize() + { + if (check2x.Checked) + + viewer.Size = new Size(1024, 1024); + else + viewer.Size = new Size(512, 512); + } + + private void checkScanlineControl_CheckedChanged(object sender, EventArgs e) + { + SyncCore(); + } + + private void check2x_CheckedChanged(object sender, EventArgs e) + { + SyncViewerSize(); + } + + bool viewerPan = false; + Point panStartLocation; + private void viewer_MouseDown(object sender, MouseEventArgs e) + { + viewer.Capture = true; + if ((e.Button & MouseButtons.Middle) != 0) + { + viewerPan = true; + panStartLocation = viewer.PointToScreen(e.Location); + Cursor = Cursors.SizeAll; + } + + if ((e.Button & MouseButtons.Right) != 0) + Freeze(); + } + + void Freeze() + { + groupFreeze.SuspendLayout(); + + Win32.SendMessage(groupFreeze.Handle, 11, (IntPtr)0, IntPtr.Zero); //WM_SETREDRAW false + + var tp = tabctrlDetails.SelectedTab; + + //clone the currently selected tab page into the destination + var oldControls = new ArrayList(pnGroupFreeze.Controls); + pnGroupFreeze.Controls.Clear(); + foreach (var control in tp.Controls) + pnGroupFreeze.Controls.Add((control as Control).Clone()); + foreach (var control in oldControls) + (control as Control).Dispose(); + + //set the freeze caption accordingly + if (tp == tpMapEntry) groupFreeze.Text = "Freeze - Map Entry"; + if (tp == tpPalette) groupFreeze.Text = "Freeze - Color"; + if (tp == tpTile) groupFreeze.Text = "Freeze - Tile"; + if (tp == tpOBJ) groupFreeze.Text = "Freeze - OBJ"; + + groupFreeze.ResumeLayout(); + + Win32.SendMessage(groupFreeze.Handle, 11, (IntPtr)1, IntPtr.Zero); //WM_SETREDRAW true + groupFreeze.Refresh(); + } + + enum eFreezeTarget + { + MainViewer + } + + private void viewer_MouseUp(object sender, MouseEventArgs e) + { + viewerPan = false; + viewer.Capture = false; + Cursor = Cursors.Default; + } + + private void viewer_MouseMove(object sender, MouseEventArgs e) + { + if (viewerPan) + { + var loc = viewer.PointToScreen(e.Location); + int dx = loc.X - panStartLocation.X; + int dy = loc.Y - panStartLocation.Y; + panStartLocation = loc; + + int x = viewerPanel.AutoScrollPosition.X; + int y = viewerPanel.AutoScrollPosition.Y; + x += dx; + y += dy; + viewerPanel.AutoScrollPosition = new Point(-x, -y); + } + else + { + if(si != null) + UpdateViewerMouseover(e.Location); + } + } + + class MapEntryState + { + public SNESGraphicsDecoder.TileEntry entry; + public int bgnum; + public Point Location; + } + MapEntryState currMapEntryState; + + class TileDataState + { + public eDisplayType Type; + public int Bpp; + public int Tile; + public int Address; + public int Palette; + } + TileDataState currTileDataState; + + class ObjDataState + { + public int Number; + } + ObjDataState currObjDataState; + + void RenderTileView() + { + if (currMapEntryState != null) + { + //view a BG tile + int paletteStart = 0; + var bgs = currMapEntryState; + var oneTileEntry = new SNESGraphicsDecoder.TileEntry[] { bgs.entry }; + int tileSize = si.BG[bgs.bgnum].TileSize; + int pixels = tileSize * tileSize; + + var bmp = new Bitmap(tileSize, tileSize, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + var bmpdata = bmp.LockBits(new Rectangle(0, 0, tileSize, tileSize), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + + if (viewBgMode == SNESGraphicsDecoder.BGMode.Mode7) + gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, false, false, 1, currMapEntryState.entry.tilenum, 1); + else if (viewBgMode == SNESGraphicsDecoder.BGMode.Mode7Ext) + gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, true, false, 1, currMapEntryState.entry.tilenum, 1); + else if (viewBgMode == SNESGraphicsDecoder.BGMode.Mode7DC) + gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, false, true, 1, currMapEntryState.entry.tilenum, 1); + else + { + gd.DecodeBG((int*)bmpdata.Scan0, bmpdata.Stride / 4, oneTileEntry, si.BG[bgs.bgnum].TiledataAddr, SNESGraphicsDecoder.ScreenSize.Hacky_1x1, si.BG[bgs.bgnum].Bpp, tileSize, paletteStart); + gd.Paletteize((int*)bmpdata.Scan0, 0, 0, pixels); + gd.Colorize((int*)bmpdata.Scan0, 0, pixels); + } + + bmp.UnlockBits(bmpdata); + viewerMapEntryTile.SetBitmap(bmp); + } + else if (currTileDataState != null) + { + //view a tileset tile + int bpp = currTileDataState.Bpp; + + var bmp = new Bitmap(8, 8, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + var bmpdata = bmp.LockBits(new Rectangle(0, 0, 8, 8), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + if (currTileDataState.Type == eDisplayType.TilesMode7) + gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, false, false, 1, currTileDataState.Tile, 1); + else if (currTileDataState.Type == eDisplayType.TilesMode7Ext) + gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, true, false, 1, currTileDataState.Tile, 1); + else if (currTileDataState.Type == eDisplayType.TilesMode7DC) + gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, false, true, 1, currTileDataState.Tile, 1); + else if (currTileDataState.Type == eDisplayType.OBJTiles0 || currTileDataState.Type == eDisplayType.OBJTiles1) + { + //render an obj tile + int tile = currTileDataState.Address / 32; + gd.RenderTilesToScreen((int*)bmpdata.Scan0, 1, 1, bmpdata.Stride / 4, bpp, currPaletteSelection.start, tile, 1); + } + else gd.RenderTilesToScreen((int*)bmpdata.Scan0, 1, 1, bmpdata.Stride / 4, bpp, currPaletteSelection.start, currTileDataState.Tile, 1); + + bmp.UnlockBits(bmpdata); + viewerTile.SetBitmap(bmp); + } + else if (currObjDataState != null) + { + var bounds = si.ObjSizeBoundsSquare; + int width = bounds.Width; + int height = bounds.Height; + var bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + var bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + gd.RenderSpriteToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, 0, 0, si, currObjDataState.Number); + bmp.UnlockBits(bmpdata); + viewerObj.SetBitmap(bmp); + } + else + { + var bmp = new Bitmap(8, 8, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + viewerTile.SetBitmap(bmp); + } + } + + void HandleTileViewMouseOver(int pxacross, int pxtall, int bpp, int tx, int ty) + { + int tilestride = pxacross / 8; + int tilesTall = pxtall / 8; + if (tx < 0 || ty < 0 || tx >= tilestride || ty >= tilesTall) + return; + int tilenum = ty * tilestride + tx; + currTileDataState = new TileDataState(); + currTileDataState.Bpp = bpp; + currTileDataState.Type = CurrDisplaySelection; + currTileDataState.Tile = tilenum; + currTileDataState.Address = (bpp==7?8:bpp) * 8 * currTileDataState.Tile; + currTileDataState.Palette = currPaletteSelection.start; + if (CurrDisplaySelection == eDisplayType.OBJTiles0 || CurrDisplaySelection == eDisplayType.OBJTiles1) + { + if (tilenum < 256) + currTileDataState.Address += si.OBJTable0Addr; + else + currTileDataState.Address += si.OBJTable1Addr - (256*32); + + currTileDataState.Address &= 0xFFFF; + } + else if (SNESGraphicsDecoder.BGModeIsMode7Type(BGModeForDisplayType(CurrDisplaySelection))) + { + currTileDataState.Address *= 2; + } + + SetTab(tpTile); + } + + void HandleSpriteMouseOver(int px, int py) + { + if (px < 0 || py < 0 || px >= 256 || py >= 224) return; + + int sprite = spriteMap[px,py]; + if(sprite == 0xFF) return; + + currObjDataState = new ObjDataState(); + currObjDataState.Number = sprite; + + SetTab(tpOBJ); + } + + void HandleObjMouseOver(int px, int py) + { + int ox = px / si.ObjSizeBounds.Width; + int oy = py / si.ObjSizeBounds.Height; + + if (ox < 0 || oy < 0 || ox >= 8 || oy >= 16) + return; + + int objNum = oy * 8 + ox; + + currObjDataState = new ObjDataState(); + currObjDataState.Number = objNum; + + //RenderView(); //remember, we were going to highlight the selected sprite somehow as we hover over it + SetTab(tpOBJ); + } + + void SetTab(TabPage tpSet) + { + //doesnt work well + //foreach (var tp in tabctrlDetails.TabPages) + // ((TabPage)tp).Visible = tpSet != null; + if (tpSet != null) + { + tpSet.Visible = true; + tabctrlDetails.SelectedTab = tpSet; + } + } + + void UpdateViewerMouseover(Point loc) + { + using (gd.EnterExit()) + { + currMapEntryState = null; + currTileDataState = null; + currObjDataState = null; + + int tx = loc.X / 8; + int ty = loc.Y / 8; + + switch (CurrDisplaySelection) + { + case eDisplayType.OBJTiles0: + case eDisplayType.OBJTiles1: + HandleTileViewMouseOver(128, 256, 4, tx, ty); + break; + case eDisplayType.OBJ: + HandleObjMouseOver(loc.X, loc.Y); + break; + case eDisplayType.Sprites: + HandleSpriteMouseOver(loc.X, loc.Y); + break; + case eDisplayType.Tiles2bpp: + HandleTileViewMouseOver(512, 512, 2, tx, ty); + break; + case eDisplayType.Tiles4bpp: + HandleTileViewMouseOver(512, 256, 4, tx, ty); + break; + case eDisplayType.Tiles8bpp: + HandleTileViewMouseOver(256, 256, 8, tx, ty); + break; + case eDisplayType.TilesMode7: + case eDisplayType.TilesMode7DC: + HandleTileViewMouseOver(128, 128, 8, tx, ty); + break; + case eDisplayType.TilesMode7Ext: + HandleTileViewMouseOver(128, 128, 7, tx, ty); + break; + case eDisplayType.BG1: + case eDisplayType.BG2: + case eDisplayType.BG3: + case eDisplayType.BG4: + { + var bg = si.BG[(int)CurrDisplaySelection]; + + //unavailable BG for this mode + if (bg.Bpp == 0) + break; + + if (bg.TileSize == 16) { tx /= 2; ty /= 2; } //worry about this later. need to pass a different flag into `currViewingTile` + + int tloc = ty * bg.ScreenSizeInTiles.Width + tx; + if (tx >= bg.ScreenSizeInTiles.Width) break; + if (ty >= bg.ScreenSizeInTiles.Height) break; + if (tx < 0) break; + if (ty < 0) break; + + currMapEntryState = new MapEntryState(); + currMapEntryState.bgnum = (int)CurrDisplaySelection; + currMapEntryState.entry = map[tloc]; + currMapEntryState.Location = new Point(tx, ty); + + //public void DecodeBG(int* screen, int stride, TileEntry[] map, int tiledataBaseAddr, ScreenSize size, int bpp, int tilesize, int paletteStart) + + + //var map = gd.FetchTilemap(bg.ScreenAddr, bg.ScreenSize); + //int paletteStart = 0; + //gd.DecodeBG(pixelptr, stride / 4, map, bg.TiledataAddr, bg.ScreenSize, bg.Bpp, bg.TileSize, paletteStart); + //gd.Paletteize(pixelptr, 0, 0, numPixels); + + SetTab(tpMapEntry); + } + break; + } + + RenderTileView(); + UpdateMapEntryDetails(); + UpdateTileDetails(); + UpdateOBJDetails(); + } + } + + private void viewer_MouseLeave(object sender, EventArgs e) + { + SetTab(null); + } + + private void paletteViewer_MouseDown(object sender, MouseEventArgs e) + { + if ((e.Button & MouseButtons.Right) != 0) + Freeze(); + } + + private void paletteViewer_MouseEnter(object sender, EventArgs e) + { + tabctrlDetails.SelectedIndex = 0; + } + + private void paletteViewer_MouseLeave(object sender, EventArgs e) + { + SetTab(null); + } + + private void paletteViewer_MouseMove(object sender, MouseEventArgs e) + { + Point pt; + bool valid = TranslatePaletteCoord(e.Location, out pt); + if (!valid) return; + lastColorNum = pt.Y * 16 + pt.X; + UpdateColorDetails(); + SetTab(tpPalette); + } + + static int DecodeWinformsColorToSNES(Color winforms) + { + int r = winforms.R; + int g = winforms.G; + int b = winforms.B; + r >>= 3; + g >>= 3; + b >>= 3; + int col = r | (g << 5) | (b << 10); + return col; + } + + void SyncBackdropColor() + { + //TODO + //if (checkBackdropColor.Checked) + //{ + // int col = DecodeWinformsColorToSNES(pnBackdropColor.BackColor); + // LibsnesDll.snes_set_backdropColor(col); + //} + //else + //{ + // LibsnesDll.snes_set_backdropColor(-1); + //} + } + + private void checkBackdropColor_CheckedChanged(object sender, EventArgs e) + { + SyncBackdropColor(); + RegenerateData(); + } + + private void pnBackdropColor_MouseDoubleClick(object sender, MouseEventArgs e) + { + var cd = new ColorDialog(); + cd.Color = pnBackdropColor.BackColor; + if (cd.ShowDialog(this) == DialogResult.OK) + { + pnBackdropColor.BackColor = cd.Color; + UserBackdropColor = pnBackdropColor.BackColor.ToArgb(); + SyncBackdropColor(); + } + } + + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + if(keyData == (Keys.C | Keys.Control)) + { + // find the control under the mouse + Point m = Cursor.Position; + Control top = this; + Control found = null; + do + { + found = top.GetChildAtPoint(top.PointToClient(m), GetChildAtPointSkip.Invisible); + top = found; + } while (found != null && found.HasChildren); + + if (found != null && found is SNESGraphicsViewer) + { + var v = found as SNESGraphicsViewer; + lock (v) + { + var bmp = v.GetBitmap(); + Clipboard.SetImage(bmp); + } + string label = ""; + if (found.Name == "viewer") + label = displayTypeItems.Find((x) => x.Type == CurrDisplaySelection).Descr; + if (found.Name == "viewerTile") + label = "Tile"; + if (found.Name == "viewerMapEntryTile") + label = "Map Entry"; + if (found.Name == "paletteViewer") + label = "Palette"; + labelClipboard.Text = label + " copied to clipboard."; + messagetimer.Stop(); + messagetimer.Start(); + + return true; + } + } + + return base.ProcessCmdKey(ref msg, keyData); + } + + + private void messagetimer_Tick(object sender, EventArgs e) + { + messagetimer.Stop(); + labelClipboard.Text = "CTRL+C copies the pane under the mouse."; + } + + private void comboPalette_SelectedIndexChanged(object sender, EventArgs e) + { + if (suppression) return; + var pal = (SnesColors.ColorType)comboPalette.SelectedValue; + Console.WriteLine("set {0}", pal); + var s = Emulator.GetSettings(); + s.Palette = pal.ToString(); + if (currentSnesCore != null) + { + currentSnesCore.PutSettings(s); + } + RegenerateData(); + RenderView(); + RenderPalette(); + RenderTileView(); + } + + void RefreshBGENCheckStatesFromConfig() + { + var s = Emulator.GetSettings(); + checkEN0_BG1.Checked = s.ShowBG1_0; + checkEN0_BG2.Checked = s.ShowBG2_0; + checkEN0_BG3.Checked = s.ShowBG3_0; + checkEN0_BG4.Checked = s.ShowBG4_0; + checkEN1_BG1.Checked = s.ShowBG1_1; + checkEN1_BG2.Checked = s.ShowBG2_1; + checkEN1_BG3.Checked = s.ShowBG3_1; + checkEN1_BG4.Checked = s.ShowBG4_1; + checkEN0_OBJ.Checked = s.ShowOBJ_0; + checkEN1_OBJ.Checked = s.ShowOBJ_1; + checkEN2_OBJ.Checked = s.ShowOBJ_2; + checkEN3_OBJ.Checked = s.ShowOBJ_3; + } + + private void checkEN_CheckedChanged(object sender, EventArgs e) + { + if(suppression) return; + var snes = Emulator; + var s = snes.GetSettings(); + if (sender == checkEN0_BG1) s.ShowBG1_0 = checkEN0_BG1.Checked; + if (sender == checkEN0_BG2) s.ShowBG2_0 = checkEN0_BG2.Checked; + if (sender == checkEN0_BG3) s.ShowBG3_0 = checkEN0_BG3.Checked; + if (sender == checkEN0_BG4) s.ShowBG4_0 = checkEN0_BG4.Checked; + if (sender == checkEN1_BG1) s.ShowBG1_1 = checkEN1_BG1.Checked; + if (sender == checkEN1_BG2) s.ShowBG2_1 = checkEN1_BG2.Checked; + if (sender == checkEN1_BG3) s.ShowBG3_1 = checkEN1_BG3.Checked; + if (sender == checkEN1_BG4) s.ShowBG4_1 = checkEN1_BG4.Checked; + if (sender == checkEN0_OBJ) s.ShowOBJ_0 = checkEN0_OBJ.Checked; + if (sender == checkEN1_OBJ) s.ShowOBJ_1 = checkEN1_OBJ.Checked; + if (sender == checkEN2_OBJ) s.ShowOBJ_2 = checkEN2_OBJ.Checked; + if (sender == checkEN3_OBJ) s.ShowOBJ_3 = checkEN3_OBJ.Checked; + + if ((ModifierKeys & Keys.Shift) != 0) + { + if (sender == checkEN0_BG1) s.ShowBG1_1 = s.ShowBG1_0; + if (sender == checkEN1_BG1) s.ShowBG1_0 = s.ShowBG1_1; + if (sender == checkEN0_BG2) s.ShowBG2_1 = s.ShowBG2_0; + if (sender == checkEN1_BG2) s.ShowBG2_0 = s.ShowBG2_1; + if (sender == checkEN0_BG3) s.ShowBG3_1 = s.ShowBG3_0; + if (sender == checkEN1_BG3) s.ShowBG3_0 = s.ShowBG3_1; + if (sender == checkEN0_BG4) s.ShowBG4_1 = s.ShowBG4_0; + if (sender == checkEN1_BG4) s.ShowBG4_0 = s.ShowBG4_1; + if (sender == checkEN0_OBJ) s.ShowOBJ_1 = s.ShowOBJ_2 = s.ShowOBJ_3 = s.ShowOBJ_0; + if (sender == checkEN1_OBJ) s.ShowOBJ_0 = s.ShowOBJ_2 = s.ShowOBJ_3 = s.ShowOBJ_1; + if (sender == checkEN2_OBJ) s.ShowOBJ_0 = s.ShowOBJ_1 = s.ShowOBJ_3 = s.ShowOBJ_2; + if (sender == checkEN3_OBJ) s.ShowOBJ_0 = s.ShowOBJ_1 = s.ShowOBJ_2 = s.ShowOBJ_3; + suppression = true; + RefreshBGENCheckStatesFromConfig(); + suppression = false; + } + snes.PutSettings(s); + } + + private void lblEnPrio0_Click(object sender, EventArgs e) + { + bool any = checkEN0_OBJ.Checked || checkEN0_BG1.Checked || checkEN0_BG2.Checked || checkEN0_BG3.Checked || checkEN0_BG4.Checked; + bool all = checkEN0_OBJ.Checked && checkEN0_BG1.Checked && checkEN0_BG2.Checked && checkEN0_BG3.Checked && checkEN0_BG4.Checked; + bool newval; + if (all) newval = false; + else newval = true; + checkEN0_OBJ.Checked = checkEN0_BG1.Checked = checkEN0_BG2.Checked = checkEN0_BG3.Checked = checkEN0_BG4.Checked = newval; + + } + + private void lblEnPrio1_Click(object sender, EventArgs e) + { + bool any = checkEN1_OBJ.Checked || checkEN1_BG1.Checked || checkEN1_BG2.Checked || checkEN1_BG3.Checked || checkEN1_BG4.Checked; + bool all = checkEN1_OBJ.Checked && checkEN1_BG1.Checked && checkEN1_BG2.Checked && checkEN1_BG3.Checked && checkEN1_BG4.Checked; + bool newval; + if (all) newval = false; + else newval = true; + checkEN1_OBJ.Checked = checkEN1_BG1.Checked = checkEN1_BG2.Checked = checkEN1_BG3.Checked = checkEN1_BG4.Checked = newval; + + } + + private void lblEnPrio2_Click(object sender, EventArgs e) + { + checkEN2_OBJ.Checked ^= true; + } + + private void lblEnPrio3_Click(object sender, EventArgs e) + { + checkEN3_OBJ.Checked ^= true; + } + + } //class SNESGraphicsDebugger + + static class ControlExtensions + { + static string[] secondPass = new[] { "Size" }; + public static T Clone(this T controlToClone) + where T : Control + { + PropertyInfo[] controlProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); + + Type t = controlToClone.GetType(); + T instance = Activator.CreateInstance(t) as T; + + t.GetProperty("AutoSize").SetValue(instance, false, null); + + for (int i = 0; i < 3; i++) + { + foreach (PropertyInfo propInfo in controlProperties) + { + if (!propInfo.CanWrite) + continue; + + if (propInfo.Name == "AutoSize") + { } + else if (propInfo.Name == "WindowTarget") + { } + else + propInfo.SetValue(instance, propInfo.GetValue(controlToClone, null), null); + } + } + + if (instance is RetainedViewportPanel) + { + var clonebmp = ((controlToClone) as RetainedViewportPanel).GetBitmap().Clone() as Bitmap; + ((instance) as RetainedViewportPanel).SetBitmap(clonebmp); + } + + return instance; + } + } +} //namespace BizHawk.Client.EmuHawk diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs index 524d4df4a6..91954bf9af 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs @@ -8,7 +8,7 @@ using System.ComponentModel; using BizHawk.Emulation.Common; using BizHawk.Emulation.Common.IEmulatorExtensions; -using BizHawk.Emulation.Cores.Nintendo.SNES; +using BizHawk.Emulation.Cores.Nintendo.SNES9X; using BizHawk.Client.Common; using BizHawk.Client.Common.MovieConversionExtensions; @@ -300,39 +300,33 @@ namespace BizHawk.Client.EmuHawk Mainform.PauseOnFrame = null; Mainform.PauseEmulator(); - // Start Scenario 0: bsnes in performance mode (copied from RecordMovieMenuItem_Click()) - if (Emulator is LibsnesCore) + // Start Scenario 0: snes9x needs a nag (copied from RecordMovieMenuItem_Click()) + if (Emulator is Snes9x) { - var snes = (LibsnesCore)Emulator; - if (snes.CurrentProfile == "Performance") + var box = new CustomControls.MsgBox( + "While the Snes9x core is faster, it is not nearly as accurate as bsnes. \nIt is recommended that you switch to the bsnes core for movie recording\nSwitch to bsnes?", + "Accuracy Warning", + MessageBoxIcon.Warning); + + box.SetButtons( + new[] { "Switch", "Cancel" }, + new[] { DialogResult.Yes, DialogResult.Cancel }); + + box.MaximumSize = new Size(475, 350); + box.SetMessageToAutoSize(); + var result = box.ShowDialog(); + + if (result == DialogResult.Yes) { - var box = new CustomControls.MsgBox( - "While the performance core is faster, it is not stable enough for movie recording\n\nSwitch to Compatibility?", - "Stability Warning", - MessageBoxIcon.Warning); - - box.SetButtons( - new[] { "Switch", "Cancel" }, - new[] { DialogResult.Yes, DialogResult.Cancel }); - - box.MaximumSize = new Size(450, 350); - box.SetMessageToAutoSize(); - var result = box.ShowDialog(); - - if (result == DialogResult.Yes) - { - var ss = snes.GetSyncSettings(); - ss.Profile = "Compatibility"; - snes.PutSyncSettings(ss); - Mainform.RebootCore(); - } - else if (result == DialogResult.Cancel) - { - return false; - } + Global.Config.SNES_InSnes9x = false; + Mainform.RebootCore(); + } + else if (result == DialogResult.Cancel) + { + return false; } } - + // Start Scenario 1: A regular movie is active if (Global.MovieSession.Movie.IsActive && !(Global.MovieSession.Movie is TasMovie)) { diff --git a/BizHawk.Client.EmuHawk/tools/VirtualPads/VirtualPad.cs b/BizHawk.Client.EmuHawk/tools/VirtualPads/VirtualPad.cs index c2323cfaa8..2b00af225a 100644 --- a/BizHawk.Client.EmuHawk/tools/VirtualPads/VirtualPad.cs +++ b/BizHawk.Client.EmuHawk/tools/VirtualPads/VirtualPad.cs @@ -84,6 +84,7 @@ namespace BizHawk.Client.EmuHawk PadBox.Controls.Add(new VirtualPadAnalogStick { Name = button.Name, + SecondaryName = button.SecondaryNames.Any() ? button.SecondaryNames[0] : "", Location = UIHelper.Scale(button.Location), Size = UIHelper.Scale(new Size(180 + 79, 200 + 9)), RangeX = new float[] { button.MinValue, button.MidValue, button.MaxValue }, diff --git a/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogStick.cs b/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogStick.cs index 64330ededc..98f4e0fa53 100644 --- a/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogStick.cs +++ b/BizHawk.Client.EmuHawk/tools/VirtualPads/controls/VirtualPadAnalogStick.cs @@ -40,12 +40,16 @@ namespace BizHawk.Client.EmuHawk public float[] RangeX = new float[] { -128f, 0.0f, 127f }; public float[] RangeY = new float[] { -128f, 0.0f, 127f }; + public string SecondaryName { get; set; } + private void VirtualPadAnalogStick_Load(object sender, EventArgs e) { AnalogStick.Name = Name; AnalogStick.XName = Name; - AnalogStick.YName = Name.Replace("X", "Y"); // TODO: allow schema to dictate this but this is a convenient default + AnalogStick.YName = !string.IsNullOrEmpty(SecondaryName) + ? SecondaryName + : Name.Replace("X", "Y"); // Fallback AnalogStick.SetRangeX(RangeX); AnalogStick.SetRangeY(RangeY); @@ -228,7 +232,7 @@ namespace BizHawk.Client.EmuHawk manualR.ValueChanged -= polarNumericChangedEventHandler; manualTheta.ValueChanged -= polarNumericChangedEventHandler; - manualR.Value = (decimal)Math.Sqrt(Math.Pow(AnalogStick.X - rangeAverageX, 2) + Math.Pow(AnalogStick.Y - rangeAverageY, 2)); + manualR.Value = Math.Min(manualR.Value, (decimal)Math.Sqrt(Math.Pow(AnalogStick.X - rangeAverageX, 2) + Math.Pow(AnalogStick.Y - rangeAverageY, 2))); manualTheta.Value = (decimal)(Math.Atan2(AnalogStick.Y - rangeAverageY, AnalogStick.X - rangeAverageX) * (180 / Math.PI)); manualR.ValueChanged += polarNumericChangedEventHandler; diff --git a/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/NgpSchema.cs b/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/NgpSchema.cs new file mode 100644 index 0000000000..667ef6a28c --- /dev/null +++ b/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/NgpSchema.cs @@ -0,0 +1,102 @@ +using System.Collections.Generic; +using System.Drawing; + +using BizHawk.Emulation.Common; + +namespace BizHawk.Client.EmuHawk +{ + [SchemaAttributes("NGP")] + public class NgpSchema : IVirtualPadSchema + { + public IEnumerable GetPadSchemas(IEmulator core) + { + yield return StandardController(); + yield return ConsoleButtons(); + } + + private static PadSchema StandardController() + { + return new PadSchema + { + IsConsole = false, + DefaultSize = new Size(174, 79), + Buttons = new[] + { + new PadSchema.ButtonSchema + { + Name = "Up", + DisplayName = "", + Icon = Properties.Resources.BlueUp, + Location = new Point(14, 12), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "Down", + DisplayName = "", + Icon = Properties.Resources.BlueDown, + Location = new Point(14, 56), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "Left", + DisplayName = "", + Icon = Properties.Resources.Back, + Location = new Point(2, 34), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "Right", + DisplayName = "", + Icon = Properties.Resources.Forward, + Location = new Point(24, 34), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "B", + DisplayName = "B", + Location = new Point(74, 34), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "A", + DisplayName = "A", + Location = new Point(98, 34), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "Option", + DisplayName = "O", + Location = new Point(146, 12), + Type = PadSchema.PadInputType.Boolean + } + } + }; + } + + private static PadSchema ConsoleButtons() + { + return new PadSchema + { + DisplayName = "Console", + IsConsole = true, + DefaultSize = new Size(75, 50), + Buttons = new[] + { + new PadSchema.ButtonSchema + { + Name = "Power", + DisplayName = "Power", + Location = new Point(10, 15), + Type = PadSchema.PadInputType.Boolean + } + } + }; + } + } +} diff --git a/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/SatSchema.cs b/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/SatSchema.cs index 6263d5bb53..25e4099dfc 100644 --- a/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/SatSchema.cs +++ b/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/SatSchema.cs @@ -1,7 +1,10 @@ using System.Collections.Generic; using System.Drawing; +using System.Linq; +using System.Windows.Forms; using BizHawk.Emulation.Common; +using BizHawk.Emulation.Cores.Consoles.Sega.Saturn; namespace BizHawk.Client.EmuHawk { @@ -10,9 +13,56 @@ namespace BizHawk.Client.EmuHawk { public IEnumerable GetPadSchemas(IEmulator core) { - yield return StandardController(1); - yield return StandardController(2); - yield return ConsoleButtons(); + var ss = ((Saturnus)core).GetSyncSettings(); + + int totalPorts = (ss.Port1Multitap ? 6 : 1) + (ss.Port2Multitap ? 6 : 1); + + var padSchemas = new SaturnusControllerDeck.Device[] + { + ss.Port1, + ss.Port2, + ss.Port3, + ss.Port4, + ss.Port5, + ss.Port6, + ss.Port7, + ss.Port8, + ss.Port9, + ss.Port10, + ss.Port11, + ss.Port12 + }.Take(totalPorts) + .Where(p => p != SaturnusControllerDeck.Device.None) + .Select((p, i) => GenerateSchemaForPort(p, i + 1)) + .Where(s => s != null) + .Concat(new[] { ConsoleButtons() }); + + return padSchemas; + } + + private static PadSchema GenerateSchemaForPort(SaturnusControllerDeck.Device device, int controllerNum) + { + switch (device) + { + default: + case SaturnusControllerDeck.Device.None: + return null; + case SaturnusControllerDeck.Device.Gamepad: + return StandardController(controllerNum); + case SaturnusControllerDeck.Device.ThreeDeePad: + return ThreeDeeController(controllerNum); + case SaturnusControllerDeck.Device.Mouse: + return Mouse(controllerNum); + case SaturnusControllerDeck.Device.Wheel: + return Wheel(controllerNum); + case SaturnusControllerDeck.Device.Mission: + return MissionControl(controllerNum); + case SaturnusControllerDeck.Device.DualMission: + return DualMissionControl(controllerNum); + case SaturnusControllerDeck.Device.Keyboard: + MessageBox.Show("This peripheral is not supported yet"); + return null; + } } private static PadSchema StandardController(int controller) @@ -20,7 +70,7 @@ namespace BizHawk.Client.EmuHawk return new PadSchema { IsConsole = false, - DefaultSize = new Size(212, 90), + DefaultSize = new Size(500, 500), Buttons = new[] { new PadSchema.ButtonSchema @@ -122,6 +172,435 @@ namespace BizHawk.Client.EmuHawk }; } + private static PadSchema ThreeDeeController(int controller) + { + return new PadSchema + { + IsConsole = false, + DefaultSize = new Size(458, 285), + Buttons = new[] + { + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Up", + DisplayName = "", + Icon = Properties.Resources.BlueUp, + Location = new Point(290, 77), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Down", + DisplayName = "", + Icon = Properties.Resources.BlueDown, + Location = new Point(290, 121), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Left", + DisplayName = "", + Icon = Properties.Resources.Back, + Location = new Point(278, 99), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Right", + DisplayName = "", + Icon = Properties.Resources.Forward, + Location = new Point(300, 99), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Start", + DisplayName = "S", + Location = new Point(334, 112), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " A", + DisplayName = "A", + Location = new Point(366, 123), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " B", + DisplayName = "B", + Location = new Point(390, 113), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " C", + DisplayName = "C", + Location = new Point(414, 103), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " X", + DisplayName = "X", + Location = new Point(366, 100), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Y", + DisplayName = "Y", + Location = new Point(390, 90), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Z", + DisplayName = "Z", + Location = new Point(414, 80), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = $"P{controller} Stick Horizontal", + SecondaryNames = new[] { $"P{controller} StickVertical" }, + MinValue = 0, + MidValue = 127, + MaxValue = 255, + MinValueSec = 0, + MidValueSec = 127, + MaxValueSec = 255, + DisplayName = "", + Location = new Point(6, 74), + Type = PadSchema.PadInputType.AnalogStick + }, + new PadSchema.ButtonSchema + { + Name = $"P{controller} Left Shoulder", + DisplayName = "L", + Location = new Point(8, 12), + Type = PadSchema.PadInputType.FloatSingle, + TargetSize = new Size(128, 55), + MinValue = 0, + MaxValue = 255, + }, + new PadSchema.ButtonSchema + { + Name = $"P{controller} Right Shoulder", + DisplayName = "L", + Location = new Point(328, 12), + Type = PadSchema.PadInputType.FloatSingle, + TargetSize = new Size(128, 55), + MinValue = 0, + MaxValue = 255, + } + } + }; + } + + private static PadSchema Mouse(int controller) + { + return new PadSchema + { + DisplayName = "Mouse", + IsConsole = false, + DefaultSize = new Size(375, 320), + Buttons = new[] + { + new PadSchema.ButtonSchema + { + Name = $"P{controller} X", + SecondaryNames = new[] { $"P{controller} Y" }, + Location = new Point(14, 17), + Type = PadSchema.PadInputType.TargetedPair, + TargetSize = new Size(256, 256) + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Mouse Left", + DisplayName = "Left", + Location = new Point(300, 17), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Mouse Center", + DisplayName = "Center", + Location = new Point(300, 47), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Mouse Right", + DisplayName = "Right", + Location = new Point(300, 77), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Start", + DisplayName = "Start", + Location = new Point(300, 107), + Type = PadSchema.PadInputType.Boolean + } + }, + }; + } + + private static PadSchema Wheel(int controller) + { + return new PadSchema + { + DisplayName = "Wheel", + IsConsole = false, + DefaultSize = new Size(325, 100), + Buttons = new[] + { + new PadSchema.ButtonSchema + { + Name = $"P{controller} Wheel", + DisplayName = "Wheel", + Location = new Point(8, 12), + Type = PadSchema.PadInputType.FloatSingle, + TargetSize = new Size(128, 55), + MinValue = 0, + MaxValue = 255, + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Up", + DisplayName = "", + Icon = Properties.Resources.BlueUp, + Location = new Point(150, 20), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Down", + DisplayName = "", + Icon = Properties.Resources.BlueDown, + Location = new Point(150, 43), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " A", + DisplayName = "A", + Location = new Point(180, 63), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " B", + DisplayName = "B", + Location = new Point(204, 53), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " C", + DisplayName = "C", + Location = new Point(228, 43), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " X", + DisplayName = "X", + Location = new Point(180, 40), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Y", + DisplayName = "Y", + Location = new Point(204, 30), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Z", + DisplayName = "Z", + Location = new Point(228, 20), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Start", + DisplayName = "Start", + Location = new Point(268, 20), + Type = PadSchema.PadInputType.Boolean + }, + }, + + }; + } + + private static PadSchema MissionControl(int controller) + { + return new PadSchema + { + DisplayName = "Mission", + IsConsole = false, + DefaultSize = new Size(445, 230), + Buttons = new[] + { + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Start", + DisplayName = "Start", + Location = new Point(45, 15), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " L", + DisplayName = "L", + Location = new Point(5, 58), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " R", + DisplayName = "R", + Location = new Point(105, 58), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " X", + DisplayName = "X", + Location = new Point(30, 43), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Y", + DisplayName = "Y", + Location = new Point(55, 43), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Z", + DisplayName = "Z", + Location = new Point(80, 43), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " A", + DisplayName = "A", + Location = new Point(30, 70), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " B", + DisplayName = "B", + Location = new Point(55, 70), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " C", + DisplayName = "C", + Location = new Point(80, 70), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = $"P{controller} Stick Horizontal", + SecondaryNames = new[] { $"P{controller} Stick Vertical" }, + MinValue = 0, + MidValue = 127, + MaxValue = 255, + MinValueSec = 0, + MidValueSec = 127, + MaxValueSec = 255, + DisplayName = "", + Location = new Point(185, 13), + Type = PadSchema.PadInputType.AnalogStick + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Throttle", + DisplayName = "Throttle", + Location = new Point(135, 13), + Type = PadSchema.PadInputType.FloatSingle, + TargetSize = new Size(64, 178), + MinValue = 0, + MaxValue = 255, + Orientation = Orientation.Vertical + } + } + }; + } + + private static PadSchema DualMissionControl(int controller) + { + return new PadSchema + { + DisplayName = "Dual Mission", + IsConsole = false, + DefaultSize = new Size(680, 230), + Buttons = new[] + { + new PadSchema.ButtonSchema + { + Name = $"P{controller} Left Stick Horizontal", + SecondaryNames = new[] { $"P{controller} Left Stick Vertical" }, + MinValue = 0, + MidValue = 127, + MaxValue = 255, + MinValueSec = 0, + MidValueSec = 127, + MaxValueSec = 255, + DisplayName = "", + Location = new Point(58, 13), + Type = PadSchema.PadInputType.AnalogStick + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Left Throttle", + DisplayName = "Throttle", + Location = new Point(8, 13), + Type = PadSchema.PadInputType.FloatSingle, + TargetSize = new Size(64, 178), + MinValue = 0, + MaxValue = 255, + Orientation = Orientation.Vertical + }, + new PadSchema.ButtonSchema + { + Name = $"P{controller} Right Stick Horizontal", + SecondaryNames = new[] { $"P{controller} Right StickVertical" }, + MinValue = 0, + MidValue = 127, + MaxValue = 255, + MinValueSec = 0, + MidValueSec = 127, + MaxValueSec = 255, + DisplayName = "", + Location = new Point(400, 13), + Type = PadSchema.PadInputType.AnalogStick + }, + new PadSchema.ButtonSchema + { + Name = "P" + controller + " Right Throttle", + DisplayName = "Throttle", + Location = new Point(350, 13), + Type = PadSchema.PadInputType.FloatSingle, + TargetSize = new Size(64, 178), + MinValue = 0, + MaxValue = 255, + Orientation = Orientation.Vertical + } + } + }; + } + private static PadSchema ConsoleButtons() { return new PadSchema diff --git a/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/SnesSchema.cs b/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/SnesSchema.cs index 5f02e974e0..696466e938 100644 --- a/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/SnesSchema.cs +++ b/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/SnesSchema.cs @@ -3,6 +3,7 @@ using System.Drawing; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Nintendo.SNES; +using BizHawk.Emulation.Cores.Nintendo.SNES9X; namespace BizHawk.Client.EmuHawk { @@ -10,6 +11,49 @@ namespace BizHawk.Client.EmuHawk public class SnesSchema : IVirtualPadSchema { public IEnumerable GetPadSchemas(IEmulator core) + { + if (core is LibsnesCore) + { + return GetBsnesPadSchemas(core); + } + + return GetSnes9xPadSchemas(core); + } + private IEnumerable GetSnes9xPadSchemas(IEmulator core) + { + // Only standard controller is supported on the left port + yield return StandardController(1); + + Snes9x.SyncSettings syncSettings = ((Snes9x)core).GetSyncSettings(); + LibSnes9x.RightPortDevice rightPort = syncSettings.RightPort; + + switch (rightPort) + { + default: + case LibSnes9x.RightPortDevice.Joypad: + yield return StandardController(2); + break; + case LibSnes9x.RightPortDevice.Justifier: + yield return Justifier(2); + break; + case LibSnes9x.RightPortDevice.Mouse: + yield return Mouse(2); + break; + case LibSnes9x.RightPortDevice.Multitap: + yield return StandardController(2); + yield return StandardController(3); + yield return StandardController(4); + yield return StandardController(5); + break; + case LibSnes9x.RightPortDevice.SuperScope: + yield return SuperScope(2); + break; + } + + yield return ConsoleButtons(); + } + + private IEnumerable GetBsnesPadSchemas(IEmulator core) { var syncsettings = ((LibsnesCore)core).GetSyncSettings(); diff --git a/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/VirtualBoySchema.cs b/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/VirtualBoySchema.cs new file mode 100644 index 0000000000..e731e61e52 --- /dev/null +++ b/BizHawk.Client.EmuHawk/tools/VirtualPads/schema/VirtualBoySchema.cs @@ -0,0 +1,155 @@ +using System.Collections.Generic; +using System.Drawing; + +using BizHawk.Emulation.Common; + +namespace BizHawk.Client.EmuHawk +{ + [SchemaAttributes("VB")] + public class VirtualBoySchema : IVirtualPadSchema + { + public IEnumerable GetPadSchemas(IEmulator core) + { + yield return StandardController(); + yield return ConsoleButtons(); + } + + private static PadSchema StandardController() + { + return new PadSchema + { + IsConsole = false, + DefaultSize = new Size(222, 103), + Buttons = new[] + { + new PadSchema.ButtonSchema + { + Name = "L_Up", + DisplayName = "", + Icon = Properties.Resources.BlueUp, + Location = new Point(14, 36), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "L_Down", + DisplayName = "", + Icon = Properties.Resources.BlueDown, + Location = new Point(14, 80), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "L_Left", + DisplayName = "", + Icon = Properties.Resources.Back, + Location = new Point(2, 58), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "L_Right", + DisplayName = "", + Icon = Properties.Resources.Forward, + Location = new Point(24, 58), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "B", + DisplayName = "B", + Location = new Point(122, 58), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "A", + DisplayName = "A", + Location = new Point(146, 58), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "Select", + DisplayName = "s", + Location = new Point(52, 58), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "Start", + DisplayName = "S", + Location = new Point(74, 58), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "R_Up", + DisplayName = "", + Icon = Properties.Resources.BlueUp, + Location = new Point(188, 36), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "R_Down", + DisplayName = "", + Icon = Properties.Resources.BlueDown, + Location = new Point(188, 80), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "R_Left", + DisplayName = "", + Icon = Properties.Resources.Back, + Location = new Point(176, 58), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "R_Right", + DisplayName = "", + Icon = Properties.Resources.Forward, + Location = new Point(198, 58), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "L", + DisplayName = "L", + Location = new Point(24, 8), + Type = PadSchema.PadInputType.Boolean + }, + new PadSchema.ButtonSchema + { + Name = "R", + DisplayName = "R", + Location = new Point(176, 8), + Type = PadSchema.PadInputType.Boolean + }, + } + }; + } + + private static PadSchema ConsoleButtons() + { + return new PadSchema + { + DisplayName = "Console", + IsConsole = true, + DefaultSize = new Size(75, 50), + Buttons = new[] + { + new PadSchema.ButtonSchema + { + Name = "Power", + DisplayName = "Power", + Location = new Point(10, 15), + Type = PadSchema.PadInputType.Boolean + } + } + }; + } + } +} diff --git a/BizHawk.Client.MultiHawk/App.config b/BizHawk.Client.MultiHawk/App.config index 2c307fa314..45437954e0 100644 --- a/BizHawk.Client.MultiHawk/App.config +++ b/BizHawk.Client.MultiHawk/App.config @@ -1,6 +1,6 @@ - + diff --git a/BizHawk.Client.MultiHawk/BizHawk.Client.MultiHawk.csproj b/BizHawk.Client.MultiHawk/BizHawk.Client.MultiHawk.csproj index 64ecceeab8..b3e5ce53e7 100644 --- a/BizHawk.Client.MultiHawk/BizHawk.Client.MultiHawk.csproj +++ b/BizHawk.Client.MultiHawk/BizHawk.Client.MultiHawk.csproj @@ -1,28 +1,27 @@  - + true - ..\output64\ + ..\output\ TRACE;DEBUG;WINDOWS true full x64 - ..\output\MultiHawk.exe.CodeAnalysisLog.xml true GlobalSuppressions.cs prompt MinimumRecommendedRules.ruleset ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false - ..\output64\ + ..\output\ TRACE;WINDOWS true true pdbonly x64 - ..\output\MultiHawk.exe.CodeAnalysisLog.xml true GlobalSuppressions.cs prompt @@ -31,6 +30,7 @@ true ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules true + false @@ -41,31 +41,10 @@ Properties BizHawk.Client.MultiHawk MultiHawk - v4.0 + v4.6.1 512 - - x86 - true - full - false - ..\output\ - TRACE;DEBUG;WINDOWS - prompt - 4 - true - - - x86 - pdbonly - true - ..\output\ - TRACE;WINDOWS - prompt - 4 - true - @@ -269,11 +248,11 @@ - \ No newline at end of file diff --git a/BizHawk.Client.MultiHawk/Properties/Settings.Designer.cs b/BizHawk.Client.MultiHawk/Properties/Settings.Designer.cs index 5ac43a96ea..fb9499495c 100644 --- a/BizHawk.Client.MultiHawk/Properties/Settings.Designer.cs +++ b/BizHawk.Client.MultiHawk/Properties/Settings.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34209 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -12,7 +12,7 @@ namespace BizHawk.Client.MultiHawk.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); diff --git a/BizHawk.Common/BizHawk.Common.csproj b/BizHawk.Common/BizHawk.Common.csproj index cb5f4826e3..757e287f0e 100644 --- a/BizHawk.Common/BizHawk.Common.csproj +++ b/BizHawk.Common/BizHawk.Common.csproj @@ -1,5 +1,5 @@  - + Debug x86 @@ -10,38 +10,17 @@ Properties BizHawk.Common BizHawk.Common - v4.0 + v4.6.1 512 - - - true - full - false - ..\output\dll\ - TRACE;DEBUG;WINDOWS - prompt - 4 - x86 - true - - - pdbonly - true - ..\output\dll\ - TRACE;WINDOWS - prompt - 4 - x86 - true + true - ..\output64\dll\ + ..\output\dll\ TRACE;DEBUG;WINDOWS true full x64 - ..\output\dll\BizHawk.Common.dll.CodeAnalysisLog.xml true GlobalSuppressions.cs prompt @@ -51,15 +30,15 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules true false + false - ..\output64\dll\ + ..\output\dll\ TRACE;WINDOWS true true pdbonly x64 - ..\output\dll\BizHawk.Common.dll.CodeAnalysisLog.xml true GlobalSuppressions.cs prompt @@ -69,9 +48,11 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules true false + false + @@ -90,12 +71,18 @@ + + + + + + diff --git a/BizHawk.Common/BizInvoke/BizExvoker.cs b/BizHawk.Common/BizInvoke/BizExvoker.cs new file mode 100644 index 0000000000..120025f9cd --- /dev/null +++ b/BizHawk.Common/BizInvoke/BizExvoker.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.InteropServices; +using System.Text; + +namespace BizHawk.Common.BizInvoke +{ + public static class BizExvoker + { + /// + /// the assembly that all delegate types are placed in + /// + private static readonly AssemblyBuilder ImplAssemblyBuilder; + + /// + /// the module that all delegate types are placed in + /// + private static readonly ModuleBuilder ImplModuleBuilder; + + static BizExvoker() + { + var aname = new AssemblyName("BizExvokeProxyAssembly"); + ImplAssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(aname, AssemblyBuilderAccess.Run); + ImplModuleBuilder = ImplAssemblyBuilder.DefineDynamicModule("BizExvokerModule"); + } + + /// + /// holds the delegate types for a type + /// + private class DelegateStorage + { + /// + /// the type that this storage was made for + /// + public Type OriginalType { get; } + /// + /// the type that the delegate types reside in + /// + public Type StorageType { get; } + + public List DelegateTypes { get; } = new List(); + + public class StoredDelegateInfo + { + public MethodInfo Method { get; } + public Type DelegateType { get; } + public string EntryPointName { get; } + public StoredDelegateInfo(MethodInfo method, Type delegateType, string entryPointName) + { + Method = method; + DelegateType = delegateType; + EntryPointName = entryPointName; + } + } + + public DelegateStorage(Type type) + { + var methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public) + .Select(m => new + { + Info = m, + Attr = m.GetCustomAttributes(true).OfType().FirstOrDefault() + }) + .Where(a => a.Attr != null) + .ToList(); + + var typeBuilder = ImplModuleBuilder.DefineType( + "Bizhawk.BizExvokeHolder" + type.Name, TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed); + + foreach (var a in methods) + { + MethodBuilder unused; + var delegateType = BizInvokeUtilities.CreateDelegateType(a.Info, a.Attr.CallingConvention, typeBuilder, out unused).CreateType(); + DelegateTypes.Add(new StoredDelegateInfo(a.Info, delegateType, a.Attr.EntryPoint ?? a.Info.Name)); + } + StorageType = typeBuilder.CreateType(); + OriginalType = type; + } + } + + private class ExvokerImpl : IImportResolver + { + private readonly Dictionary EntryPoints = new Dictionary(); + + private readonly List Delegates = new List(); + + public ExvokerImpl(object o, DelegateStorage d, ICallingConventionAdapter a) + { + foreach (var sdt in d.DelegateTypes) + { + var del = Delegate.CreateDelegate(sdt.DelegateType, o, sdt.Method); + Delegates.Add(del); // prevent garbage collection of the delegate, which would invalidate the pointer + EntryPoints.Add(sdt.EntryPointName, a.GetFunctionPointerForDelegate(del)); + } + } + + public IntPtr Resolve(string entryPoint) + { + IntPtr ret; + EntryPoints.TryGetValue(entryPoint, out ret); + return ret; + } + } + + static readonly Dictionary Impls = new Dictionary(); + + + public static IImportResolver GetExvoker(object o, ICallingConventionAdapter a) + { + DelegateStorage ds; + lock (Impls) + { + var type = o.GetType(); + if (!Impls.TryGetValue(type, out ds)) + { + ds = new DelegateStorage(type); + Impls.Add(type, ds); + } + } + + return new ExvokerImpl(o, ds, a); + } + } + + /// + /// mark an instance method to be exported by BizExvoker + /// + [AttributeUsage(AttributeTargets.Method)] + public class BizExportAttribute : Attribute + { + public CallingConvention CallingConvention { get; } + + /// + /// Gets or sets the name of entry point; if not given, the method's name is used + /// + public string EntryPoint { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// unmanaged calling convention + public BizExportAttribute(CallingConvention c) + { + CallingConvention = c; + } + } +} diff --git a/BizHawk.Common/BizInvoke/BizInvokeUtilities.cs b/BizHawk.Common/BizInvoke/BizInvokeUtilities.cs new file mode 100644 index 0000000000..6bb1436d1b --- /dev/null +++ b/BizHawk.Common/BizInvoke/BizInvokeUtilities.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.InteropServices; +using System.Text; + +namespace BizHawk.Common.BizInvoke +{ + public static class BizInvokeUtilities + { + /// + /// create a delegate type to match a method type + /// + /// the method to "clone" + /// native calling convention to use + /// the type to define this delegate type as a nested type on + /// the methodBuilder for the magic Invoke method on the resulting type + /// the resulting typeBuilder + public static TypeBuilder CreateDelegateType(MethodInfo method, CallingConvention nativeCall, TypeBuilder enclosingType, + out MethodBuilder invokeMethod) + { + var paramInfos = method.GetParameters(); + var paramTypes = paramInfos.Select(p => p.ParameterType).ToArray(); + var returnType = method.ReturnType; + + // create the delegate type + var delegateType = enclosingType.DefineNestedType( + "DelegateType" + method.Name, + TypeAttributes.Class | TypeAttributes.NestedPrivate | TypeAttributes.Sealed, + typeof(MulticastDelegate)); + + var delegateCtor = delegateType.DefineConstructor( + MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Public, + CallingConventions.Standard, + new[] { typeof(object), typeof(IntPtr) }); + + delegateCtor.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed); + + var delegateInvoke = delegateType.DefineMethod( + "Invoke", + MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, + returnType, + paramTypes); + + // we have to project all of the attributes from the baseMethod to the delegateInvoke + // so for something like [Out], the interop engine will see it and use it + for (int i = 0; i < paramInfos.Length; i++) + { + var p = delegateInvoke.DefineParameter(i + 1, ParameterAttributes.None, paramInfos[i].Name); + foreach (var a in paramInfos[i].GetCustomAttributes(false)) + { + p.SetCustomAttribute(GetAttributeBuilder(a)); + } + } + + { + var p = delegateInvoke.DefineParameter(0, ParameterAttributes.Retval, method.ReturnParameter.Name); + foreach (var a in method.ReturnParameter.GetCustomAttributes(false)) + { + p.SetCustomAttribute(GetAttributeBuilder(a)); + } + } + + delegateInvoke.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed); + + // add the [UnmanagedFunctionPointer] to the delegate so interop will know how to call it + var attr = new CustomAttributeBuilder(typeof(UnmanagedFunctionPointerAttribute).GetConstructor(new[] { typeof(CallingConvention) }), new object[] { nativeCall }); + delegateType.SetCustomAttribute(attr); + + invokeMethod = delegateInvoke; + return delegateType; + } + + /// + /// get an attribute builder to clone an attribute to a delegate type + /// + private static CustomAttributeBuilder GetAttributeBuilder(object o) + { + // anything more clever we can do here? + var t = o.GetType(); + if (t == typeof(OutAttribute) || t == typeof(InAttribute)) + { + return new CustomAttributeBuilder(t.GetConstructor(Type.EmptyTypes), new object[0]); + } + + throw new InvalidOperationException("Unknown parameter attribute " + t.Name); + } + } +} diff --git a/BizHawk.Common/BizInvoke/BizInvoker.cs b/BizHawk.Common/BizInvoke/BizInvoker.cs index 5f7cfb7d1e..c00ad96da4 100644 --- a/BizHawk.Common/BizInvoke/BizInvoker.cs +++ b/BizHawk.Common/BizInvoke/BizInvoker.cs @@ -1,566 +1,561 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Reflection.Emit; -using System.Runtime.InteropServices; - -using BizHawk.Common; - -namespace BizHawk.Common.BizInvoke -{ - public static class BizInvoker - { - /// - /// holds information about a proxy implementation, including type and setup hooks - /// - private class InvokerImpl - { - public Type ImplType; - public List> Hooks; - public Action ConnectMonitor; - - public object Create(IImportResolver dll, IMonitor monitor) - { - var ret = Activator.CreateInstance(ImplType); - foreach (var f in Hooks) - { - f(ret, dll); - } - - ConnectMonitor?.Invoke(ret, monitor); - return ret; - } - } - - /// - /// dictionary of all generated proxy implementations and their base types - /// - private static readonly IDictionary Impls = new Dictionary(); - - /// - /// the assembly that all proxies are placed in - /// - private static readonly AssemblyBuilder ImplAssemblyBuilder; - - /// - /// the module that all proxies are placed in - /// - private static readonly ModuleBuilder ImplModuleBilder; - - static BizInvoker() - { - var aname = new AssemblyName("BizInvokeProxyAssembly"); - ImplAssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(aname, AssemblyBuilderAccess.Run); - ImplModuleBilder = ImplAssemblyBuilder.DefineDynamicModule("BizInvokerModule"); - } - - /// - /// get an implementation proxy for an interop class - /// - /// The class type that represents the DLL - public static T GetInvoker(IImportResolver dll) - where T : class - { - InvokerImpl impl; - lock (Impls) - { - var baseType = typeof(T); - if (!Impls.TryGetValue(baseType, out impl)) - { - impl = CreateProxy(baseType, false); - Impls.Add(baseType, impl); - } - } - - if (impl.ConnectMonitor != null) - { - throw new InvalidOperationException("Class was previously proxied with a monitor!"); - } - - return (T)impl.Create(dll, null); - } - - public static T GetInvoker(IImportResolver dll, IMonitor monitor) - where T : class - { - InvokerImpl impl; - lock (Impls) - { - var baseType = typeof(T); - if (!Impls.TryGetValue(baseType, out impl)) - { - impl = CreateProxy(baseType, true); - Impls.Add(baseType, impl); - } - } - - if (impl.ConnectMonitor == null) - { - throw new InvalidOperationException("Class was previously proxied without a monitor!"); - } - - return (T)impl.Create(dll, monitor); - } - - private static InvokerImpl CreateProxy(Type baseType, bool monitor) - { - if (baseType.IsSealed) - { - throw new InvalidOperationException("Can't proxy a sealed type"); - } - - if (!baseType.IsPublic) - { - // the proxy type will be in a new assembly, so public is required here - throw new InvalidOperationException("Type must be public"); - } - - var baseConstructor = baseType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null); - if (baseConstructor == null) - { - throw new InvalidOperationException("Base type must have a zero arg constructor"); - } - - var baseMethods = baseType.GetMethods(BindingFlags.Instance | BindingFlags.Public) - .Select(m => new - { - Info = m, - Attr = m.GetCustomAttributes(true).OfType().FirstOrDefault() - }) - .Where(a => a.Attr != null) - .ToList(); - - if (baseMethods.Count == 0) - { - throw new InvalidOperationException("Couldn't find any [BizImport] methods to proxy"); - } - - { - var uo = baseMethods.FirstOrDefault(a => !a.Info.IsVirtual || a.Info.IsFinal); - if (uo != null) - { - throw new InvalidOperationException("Method " + uo.Info.Name + " cannot be overriden!"); - } - - // there's no technical reason to disallow this, but we wouldn't be doing anything - // with the base implementation, so it's probably a user error - var na = baseMethods.FirstOrDefault(a => !a.Info.IsAbstract); - if (na != null) - { - throw new InvalidOperationException("Method " + na.Info.Name + " is not abstract!"); - } - } - - // hooks that will be run on the created proxy object - var postCreateHooks = new List>(); - - var type = ImplModuleBilder.DefineType("Bizhawk.BizInvokeProxy" + baseType.Name, TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed, baseType); - - var monitorField = monitor ? type.DefineField("MonitorField", typeof(IMonitor), FieldAttributes.Public) : null; - - foreach (var mi in baseMethods) - { - var entryPointName = mi.Attr.EntryPoint ?? mi.Info.Name; - - var hook = mi.Attr.Compatibility - ? ImplementMethodDelegate(type, mi.Info, mi.Attr.CallingConvention, entryPointName, monitorField) - : ImplementMethodCalli(type, mi.Info, mi.Attr.CallingConvention, entryPointName, monitorField); - - postCreateHooks.Add(hook); - } - - var ret = new InvokerImpl - { - Hooks = postCreateHooks, - ImplType = type.CreateType() - }; - if (monitor) - { - ret.ConnectMonitor = (o, m) => o.GetType().GetField(monitorField.Name).SetValue(o, m); - } - - return ret; - } - - /// - /// create a method implementation that uses GetDelegateForFunctionPointer internally - /// - private static Action ImplementMethodDelegate(TypeBuilder type, MethodInfo baseMethod, CallingConvention nativeCall, string entryPointName, FieldInfo monitorField) - { - var paramInfos = baseMethod.GetParameters(); - var paramTypes = paramInfos.Select(p => p.ParameterType).ToArray(); - var returnType = baseMethod.ReturnType; - - // create the delegate type - var delegateType = type.DefineNestedType( - "DelegateType" + baseMethod.Name, - TypeAttributes.Class | TypeAttributes.NestedPrivate | TypeAttributes.Sealed, - typeof(MulticastDelegate)); - - var delegateCtor = delegateType.DefineConstructor( - MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Public, - CallingConventions.Standard, - new[] { typeof(object), typeof(IntPtr) }); - - delegateCtor.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed); - - var delegateInvoke = delegateType.DefineMethod( - "Invoke", - MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, - returnType, - paramTypes); - - // we have to project all of the attributes from the baseMethod to the delegateInvoke - // so for something like [Out], the interop engine will see it and use it - for (int i = 0; i < paramInfos.Length; i++) - { - var p = delegateInvoke.DefineParameter(i + 1, ParameterAttributes.None, paramInfos[i].Name); - foreach (var a in paramInfos[i].GetCustomAttributes(false)) - { - p.SetCustomAttribute(GetAttributeBuilder(a)); - } - } - - { - var p = delegateInvoke.DefineParameter(0, ParameterAttributes.Retval, baseMethod.ReturnParameter.Name); - foreach (var a in baseMethod.ReturnParameter.GetCustomAttributes(false)) - { - p.SetCustomAttribute(GetAttributeBuilder(a)); - } - } - - delegateInvoke.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed); - - // add the [UnmanagedFunctionPointer] to the delegate so interop will know how to call it - var attr = new CustomAttributeBuilder(typeof(UnmanagedFunctionPointerAttribute).GetConstructor(new[] { typeof(CallingConvention) }), new object[] { nativeCall }); - delegateType.SetCustomAttribute(attr); - - // define a field on the class to hold the delegate - var field = type.DefineField( - "DelegateField" + baseMethod.Name, - delegateType, - FieldAttributes.Public); - - var method = type.DefineMethod( - baseMethod.Name, - MethodAttributes.Virtual | MethodAttributes.Public, - CallingConventions.HasThis, - returnType, - paramTypes); - - var il = method.GetILGenerator(); - - Label exc = new Label(); - if (monitorField != null) // monitor: enter and then begin try - { - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldfld, monitorField); - il.Emit(OpCodes.Callvirt, typeof(IMonitor).GetMethod("Enter")); - exc = il.BeginExceptionBlock(); - } - - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldfld, field); - for (int i = 0; i < paramTypes.Length; i++) - { - il.Emit(OpCodes.Ldarg, (short)(i + 1)); - } - - il.Emit(OpCodes.Callvirt, delegateInvoke); - - if (monitorField != null) // monitor: finally exit - { - LocalBuilder loc = null; - if (returnType != typeof(void)) - { - loc = il.DeclareLocal(returnType); - il.Emit(OpCodes.Stloc, loc); - } - - il.Emit(OpCodes.Leave, exc); - il.BeginFinallyBlock(); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldfld, monitorField); - il.Emit(OpCodes.Callvirt, typeof(IMonitor).GetMethod("Exit")); - il.EndExceptionBlock(); - - if (returnType != typeof(void)) - { - il.Emit(OpCodes.Ldloc, loc); - } - } - - il.Emit(OpCodes.Ret); - - type.DefineMethodOverride(method, baseMethod); - - return (o, dll) => - { - var entryPtr = dll.SafeResolve(entryPointName); - var interopDelegate = Marshal.GetDelegateForFunctionPointer(entryPtr, delegateType.CreateType()); - o.GetType().GetField(field.Name).SetValue(o, interopDelegate); - }; - } - - /// - /// create a method implementation that uses calli internally - /// - private static Action ImplementMethodCalli(TypeBuilder type, MethodInfo baseMethod, CallingConvention nativeCall, string entryPointName, FieldInfo monitorField) - { - var paramInfos = baseMethod.GetParameters(); - var paramTypes = paramInfos.Select(p => p.ParameterType).ToArray(); - var nativeParamTypes = new List(); - var returnType = baseMethod.ReturnType; - if (returnType != typeof(void) && !returnType.IsPrimitive) - { - throw new InvalidOperationException("Only primitive return types are supported"); - } - - // define a field on the type to hold the entry pointer - var field = type.DefineField( - "EntryPtrField" + baseMethod.Name, - typeof(IntPtr), - FieldAttributes.Public); - - var method = type.DefineMethod( - baseMethod.Name, - MethodAttributes.Virtual | MethodAttributes.Public, - CallingConventions.HasThis, - returnType, - paramTypes); - - var il = method.GetILGenerator(); - - Label exc = new Label(); - if (monitorField != null) // monitor: enter and then begin try - { - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldfld, monitorField); - il.Emit(OpCodes.Callvirt, typeof(IMonitor).GetMethod("Enter")); - exc = il.BeginExceptionBlock(); - } - - for (int i = 0; i < paramTypes.Length; i++) - { - // arg 0 is this, so + 1 - nativeParamTypes.Add(EmitParamterLoad(il, i + 1, paramTypes[i])); - } - - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldfld, field); - il.EmitCalli(OpCodes.Calli, nativeCall, returnType, nativeParamTypes.ToArray()); - - if (monitorField != null) // monitor: finally exit - { - LocalBuilder loc = null; - if (returnType != typeof(void)) - { - loc = il.DeclareLocal(returnType); - il.Emit(OpCodes.Stloc, loc); - } - - il.Emit(OpCodes.Leave, exc); - il.BeginFinallyBlock(); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldfld, monitorField); - il.Emit(OpCodes.Callvirt, typeof(IMonitor).GetMethod("Exit")); - il.EndExceptionBlock(); - - if (returnType != typeof(void)) - { - il.Emit(OpCodes.Ldloc, loc); - } - } - - // either there's a primitive on the stack and we're expected to return that primitive, - // or there's nothing on the stack and we're expected to return nothing - il.Emit(OpCodes.Ret); - - type.DefineMethodOverride(method, baseMethod); - - return (o, dll) => - { - var entryPtr = dll.SafeResolve(entryPointName); - o.GetType().GetField(field.Name).SetValue(o, entryPtr); - }; - } - - /// - /// load an IntPtr constant in an IL stream - /// - private static void LoadConstant(ILGenerator il, IntPtr p) - { - if (p == IntPtr.Zero) - { - il.Emit(OpCodes.Ldc_I4_0); - } - else if (IntPtr.Size == 4) - { - il.Emit(OpCodes.Ldc_I4, (int)p); - } - else - { - il.Emit(OpCodes.Ldc_I8, (long)p); - } - - il.Emit(OpCodes.Conv_I); - } - - /// - /// load a UIntPtr constant in an IL stream - /// - private static void LoadConstant(ILGenerator il, UIntPtr p) - { - if (p == UIntPtr.Zero) - { - il.Emit(OpCodes.Ldc_I4_0); - } - else if (UIntPtr.Size == 4) - { - il.Emit(OpCodes.Ldc_I4, (int)p); - } - else - { - il.Emit(OpCodes.Ldc_I8, (long)p); - } - - il.Emit(OpCodes.Conv_U); - } - - /// - /// emit a single parameter load with unmanaged conversions - /// - private static Type EmitParamterLoad(ILGenerator il, int idx, Type type) - { - if (type.IsGenericType) - { - throw new InvalidOperationException("Generic types not supported"); - } - - if (type.IsByRef) - { - var et = type.GetElementType(); - if (!et.IsPrimitive && !et.IsEnum) - { - throw new InvalidOperationException("Only refs of primitive or enum types are supported!"); - } - - var loc = il.DeclareLocal(type, true); - il.Emit(OpCodes.Ldarg, (short)idx); - il.Emit(OpCodes.Dup); - il.Emit(OpCodes.Stloc, loc); - il.Emit(OpCodes.Conv_I); - return typeof(IntPtr); - } - - if (type.IsArray) - { - var et = type.GetElementType(); - if (!et.IsPrimitive && !et.IsEnum) - { - throw new InvalidOperationException("Only arrays of primitive or enum types are supported!"); - } - - // these two cases aren't too hard to add - if (type.GetArrayRank() > 1) - { - throw new InvalidOperationException("Multidimensional arrays are not supported!"); - } - - if (type.Name.Contains('*')) - { - throw new InvalidOperationException("Only 0-based 1-dimensional arrays are supported!"); - } - - var loc = il.DeclareLocal(type, true); - var end = il.DefineLabel(); - var isNull = il.DefineLabel(); - - il.Emit(OpCodes.Ldarg, (short)idx); - il.Emit(OpCodes.Brfalse, isNull); - - il.Emit(OpCodes.Ldarg, (short)idx); - il.Emit(OpCodes.Dup); - il.Emit(OpCodes.Stloc, loc); - il.Emit(OpCodes.Ldc_I4_0); - il.Emit(OpCodes.Ldelema, et); - il.Emit(OpCodes.Conv_I); - il.Emit(OpCodes.Br, end); - - il.MarkLabel(isNull); - LoadConstant(il, IntPtr.Zero); - il.MarkLabel(end); - - return typeof(IntPtr); - } - - if (typeof(Delegate).IsAssignableFrom(type)) - { - var mi = typeof(Marshal).GetMethod("GetFunctionPointerForDelegate", new[] { typeof(Delegate) }); - var end = il.DefineLabel(); - var isNull = il.DefineLabel(); - - il.Emit(OpCodes.Ldarg, (short)idx); - il.Emit(OpCodes.Brfalse, isNull); - - il.Emit(OpCodes.Ldarg, (short)idx); - il.Emit(OpCodes.Call, mi); - il.Emit(OpCodes.Br, end); - - il.MarkLabel(isNull); - LoadConstant(il, IntPtr.Zero); - il.MarkLabel(end); - return typeof(IntPtr); - } - - if (type.IsPrimitive || type.IsEnum) - { - il.Emit(OpCodes.Ldarg, (short)idx); - return type; - } - - throw new InvalidOperationException("Unrecognized parameter type!"); - } - - private static CustomAttributeBuilder GetAttributeBuilder(object o) - { - // anything more clever we can do here? - var t = o.GetType(); - if (t == typeof(OutAttribute) || t == typeof(InAttribute)) - { - return new CustomAttributeBuilder(t.GetConstructor(Type.EmptyTypes), new object[0]); - } - - throw new InvalidOperationException("Unknown parameter attribute " + t.Name); - } - } - - /// - /// mark an abstract method to be proxied by BizInvoker - /// - [AttributeUsage(AttributeTargets.Method)] - public class BizImportAttribute : Attribute - { - public CallingConvention CallingConvention { get; } - - /// - /// Gets or sets the name of entry point; if not given, the method's name is used - /// - public string EntryPoint { get; set; } - - /// - /// Gets or sets a value indicating whether or not to use a slower interop that supports more argument types - /// - public bool Compatibility { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// unmanaged calling convention - public BizImportAttribute(CallingConvention c) - { - CallingConvention = c; - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.InteropServices; + +using BizHawk.Common; + +namespace BizHawk.Common.BizInvoke +{ + public static class BizInvoker + { + /// + /// holds information about a proxy implementation, including type and setup hooks + /// + private class InvokerImpl + { + public Type ImplType; + public List> Hooks; + public Action ConnectMonitor; + public Action ConnectCallingConventionAdapter; + + public object Create(IImportResolver dll, IMonitor monitor, ICallingConventionAdapter adapter) + { + var ret = Activator.CreateInstance(ImplType); + ConnectCallingConventionAdapter(ret, adapter); + foreach (var f in Hooks) + { + f(ret, dll, adapter); + } + ConnectMonitor?.Invoke(ret, monitor); + return ret; + } + } + + /// + /// dictionary of all generated proxy implementations and their base types + /// + private static readonly IDictionary Impls = new Dictionary(); + + /// + /// the assembly that all proxies are placed in + /// + private static readonly AssemblyBuilder ImplAssemblyBuilder; + + /// + /// the module that all proxies are placed in + /// + private static readonly ModuleBuilder ImplModuleBuilder; + + static BizInvoker() + { + var aname = new AssemblyName("BizInvokeProxyAssembly"); + ImplAssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(aname, AssemblyBuilderAccess.Run); + ImplModuleBuilder = ImplAssemblyBuilder.DefineDynamicModule("BizInvokerModule"); + } + + /// + /// get an implementation proxy for an interop class + /// + /// The class type that represents the DLL + public static T GetInvoker(IImportResolver dll, ICallingConventionAdapter adapter) + where T : class + { + InvokerImpl impl; + lock (Impls) + { + var baseType = typeof(T); + if (!Impls.TryGetValue(baseType, out impl)) + { + impl = CreateProxy(baseType, false); + Impls.Add(baseType, impl); + } + } + + if (impl.ConnectMonitor != null) + { + throw new InvalidOperationException("Class was previously proxied with a monitor!"); + } + + return (T)impl.Create(dll, null, adapter); + } + + public static T GetInvoker(IImportResolver dll, IMonitor monitor, ICallingConventionAdapter adapter) + where T : class + { + InvokerImpl impl; + lock (Impls) + { + var baseType = typeof(T); + if (!Impls.TryGetValue(baseType, out impl)) + { + impl = CreateProxy(baseType, true); + Impls.Add(baseType, impl); + } + } + + if (impl.ConnectMonitor == null) + { + throw new InvalidOperationException("Class was previously proxied without a monitor!"); + } + + return (T)impl.Create(dll, monitor, adapter); + } + + private static InvokerImpl CreateProxy(Type baseType, bool monitor) + { + if (baseType.IsSealed) + { + throw new InvalidOperationException("Can't proxy a sealed type"); + } + + if (!baseType.IsPublic) + { + // the proxy type will be in a new assembly, so public is required here + throw new InvalidOperationException("Type must be public"); + } + + var baseConstructor = baseType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null); + if (baseConstructor == null) + { + throw new InvalidOperationException("Base type must have a zero arg constructor"); + } + + var baseMethods = baseType.GetMethods(BindingFlags.Instance | BindingFlags.Public) + .Select(m => new + { + Info = m, + Attr = m.GetCustomAttributes(true).OfType().FirstOrDefault() + }) + .Where(a => a.Attr != null) + .ToList(); + + if (baseMethods.Count == 0) + { + throw new InvalidOperationException("Couldn't find any [BizImport] methods to proxy"); + } + + { + var uo = baseMethods.FirstOrDefault(a => !a.Info.IsVirtual || a.Info.IsFinal); + if (uo != null) + { + throw new InvalidOperationException("Method " + uo.Info.Name + " cannot be overriden!"); + } + + // there's no technical reason to disallow this, but we wouldn't be doing anything + // with the base implementation, so it's probably a user error + var na = baseMethods.FirstOrDefault(a => !a.Info.IsAbstract); + if (na != null) + { + throw new InvalidOperationException("Method " + na.Info.Name + " is not abstract!"); + } + } + + // hooks that will be run on the created proxy object + var postCreateHooks = new List>(); + + var type = ImplModuleBuilder.DefineType("Bizhawk.BizInvokeProxy" + baseType.Name, TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed, baseType); + + var monitorField = monitor ? type.DefineField("MonitorField", typeof(IMonitor), FieldAttributes.Public) : null; + + var adapterField = type.DefineField("CallingConvention", typeof(ICallingConventionAdapter), FieldAttributes.Public); + + foreach (var mi in baseMethods) + { + var entryPointName = mi.Attr.EntryPoint ?? mi.Info.Name; + + var hook = mi.Attr.Compatibility + ? ImplementMethodDelegate(type, mi.Info, mi.Attr.CallingConvention, entryPointName, monitorField) + : ImplementMethodCalli(type, mi.Info, mi.Attr.CallingConvention, entryPointName, monitorField, adapterField); + + postCreateHooks.Add(hook); + } + + var ret = new InvokerImpl + { + Hooks = postCreateHooks, + ImplType = type.CreateType() + }; + if (monitor) + { + ret.ConnectMonitor = (o, m) => o.GetType().GetField(monitorField.Name).SetValue(o, m); + } + ret.ConnectCallingConventionAdapter = (o, a) => o.GetType().GetField(adapterField.Name).SetValue(o, a); + + return ret; + } + + /// + /// create a method implementation that uses GetDelegateForFunctionPointer internally + /// + private static Action ImplementMethodDelegate( + TypeBuilder type, MethodInfo baseMethod, CallingConvention nativeCall, string entryPointName, FieldInfo monitorField) + { + // create the delegate type + MethodBuilder delegateInvoke; + var delegateType = BizInvokeUtilities.CreateDelegateType(baseMethod, nativeCall, type, out delegateInvoke); + + var paramInfos = baseMethod.GetParameters(); + var paramTypes = paramInfos.Select(p => p.ParameterType).ToArray(); + var returnType = baseMethod.ReturnType; + + if (paramTypes.Concat(new[] { returnType }).Any(typeof(Delegate).IsAssignableFrom)) + { + // this isn't a problem if CallingConventionAdapters.Waterbox is a no-op + if (CallingConventionAdapters.Waterbox.GetType() != CallingConventionAdapters.Native.GetType()) + throw new InvalidOperationException("Compatibility call mode cannot use ICallingConventionAdapters!"); + } + + // define a field on the class to hold the delegate + var field = type.DefineField( + "DelegateField" + baseMethod.Name, + delegateType, + FieldAttributes.Public); + + var method = type.DefineMethod( + baseMethod.Name, + MethodAttributes.Virtual | MethodAttributes.Public, + CallingConventions.HasThis, + returnType, + paramTypes); + + var il = method.GetILGenerator(); + + Label exc = new Label(); + if (monitorField != null) // monitor: enter and then begin try + { + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldfld, monitorField); + il.Emit(OpCodes.Callvirt, typeof(IMonitor).GetMethod("Enter")); + exc = il.BeginExceptionBlock(); + } + + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldfld, field); + for (int i = 0; i < paramTypes.Length; i++) + { + il.Emit(OpCodes.Ldarg, (short)(i + 1)); + } + + il.Emit(OpCodes.Callvirt, delegateInvoke); + + if (monitorField != null) // monitor: finally exit + { + LocalBuilder loc = null; + if (returnType != typeof(void)) + { + loc = il.DeclareLocal(returnType); + il.Emit(OpCodes.Stloc, loc); + } + + il.Emit(OpCodes.Leave, exc); + il.BeginFinallyBlock(); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldfld, monitorField); + il.Emit(OpCodes.Callvirt, typeof(IMonitor).GetMethod("Exit")); + il.EndExceptionBlock(); + + if (returnType != typeof(void)) + { + il.Emit(OpCodes.Ldloc, loc); + } + } + + il.Emit(OpCodes.Ret); + + type.DefineMethodOverride(method, baseMethod); + + return (o, dll, adapter) => + { + var entryPtr = dll.SafeResolve(entryPointName); + var interopDelegate = adapter.GetDelegateForFunctionPointer(entryPtr, delegateType.CreateType()); + o.GetType().GetField(field.Name).SetValue(o, interopDelegate); + }; + } + + /// + /// create a method implementation that uses calli internally + /// + private static Action ImplementMethodCalli( + TypeBuilder type, MethodInfo baseMethod, + CallingConvention nativeCall, string entryPointName, FieldInfo monitorField, FieldInfo adapterField) + { + var paramInfos = baseMethod.GetParameters(); + var paramTypes = paramInfos.Select(p => p.ParameterType).ToArray(); + var nativeParamTypes = new List(); + var returnType = baseMethod.ReturnType; + if (returnType != typeof(void) && !returnType.IsPrimitive) + { + throw new InvalidOperationException("Only primitive return types are supported"); + } + + // define a field on the type to hold the entry pointer + var field = type.DefineField( + "EntryPtrField" + baseMethod.Name, + typeof(IntPtr), + FieldAttributes.Public); + + var method = type.DefineMethod( + baseMethod.Name, + MethodAttributes.Virtual | MethodAttributes.Public, + CallingConventions.HasThis, + returnType, + paramTypes); + + var il = method.GetILGenerator(); + + Label exc = new Label(); + if (monitorField != null) // monitor: enter and then begin try + { + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldfld, monitorField); + il.Emit(OpCodes.Callvirt, typeof(IMonitor).GetMethod("Enter")); + exc = il.BeginExceptionBlock(); + } + + for (int i = 0; i < paramTypes.Length; i++) + { + // arg 0 is this, so + 1 + nativeParamTypes.Add(EmitParamterLoad(il, i + 1, paramTypes[i], adapterField)); + } + + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldfld, field); + il.EmitCalli(OpCodes.Calli, + nativeCall, + returnType == typeof(bool) ? typeof(byte) : returnType, // undo winapi style bool garbage + nativeParamTypes.ToArray()); + + if (monitorField != null) // monitor: finally exit + { + LocalBuilder loc = null; + if (returnType != typeof(void)) + { + loc = il.DeclareLocal(returnType); + il.Emit(OpCodes.Stloc, loc); + } + + il.Emit(OpCodes.Leave, exc); + il.BeginFinallyBlock(); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldfld, monitorField); + il.Emit(OpCodes.Callvirt, typeof(IMonitor).GetMethod("Exit")); + il.EndExceptionBlock(); + + if (returnType != typeof(void)) + { + il.Emit(OpCodes.Ldloc, loc); + } + } + + // either there's a primitive on the stack and we're expected to return that primitive, + // or there's nothing on the stack and we're expected to return nothing + il.Emit(OpCodes.Ret); + + type.DefineMethodOverride(method, baseMethod); + + return (o, dll, adapter) => + { + var entryPtr = dll.SafeResolve(entryPointName); + o.GetType().GetField(field.Name).SetValue( + o, adapter.GetDepartureFunctionPointer(entryPtr, new ParameterInfo(returnType, paramTypes), o)); + }; + } + + /// + /// load an IntPtr constant in an IL stream + /// + private static void LoadConstant(ILGenerator il, IntPtr p) + { + if (p == IntPtr.Zero) + { + il.Emit(OpCodes.Ldc_I4_0); + } + else if (IntPtr.Size == 4) + { + il.Emit(OpCodes.Ldc_I4, (int)p); + } + else + { + il.Emit(OpCodes.Ldc_I8, (long)p); + } + + il.Emit(OpCodes.Conv_I); + } + + /// + /// load a UIntPtr constant in an IL stream + /// + private static void LoadConstant(ILGenerator il, UIntPtr p) + { + if (p == UIntPtr.Zero) + { + il.Emit(OpCodes.Ldc_I4_0); + } + else if (UIntPtr.Size == 4) + { + il.Emit(OpCodes.Ldc_I4, (int)p); + } + else + { + il.Emit(OpCodes.Ldc_I8, (long)p); + } + + il.Emit(OpCodes.Conv_U); + } + + /// + /// emit a single parameter load with unmanaged conversions + /// + private static Type EmitParamterLoad(ILGenerator il, int idx, Type type, FieldInfo adapterField) + { + if (type.IsGenericType) + { + throw new InvalidOperationException("Generic types not supported"); + } + + if (type.IsByRef) + { + var et = type.GetElementType(); + if (!et.IsPrimitive && !et.IsEnum) + { + throw new InvalidOperationException("Only refs of primitive or enum types are supported!"); + } + + var loc = il.DeclareLocal(type, true); + il.Emit(OpCodes.Ldarg, (short)idx); + il.Emit(OpCodes.Dup); + il.Emit(OpCodes.Stloc, loc); + il.Emit(OpCodes.Conv_I); + return typeof(IntPtr); + } + + if (type.IsArray) + { + var et = type.GetElementType(); + if (!et.IsValueType) + { + throw new InvalidOperationException("Only arrays of value types are supported!"); + } + + // these two cases aren't too hard to add + if (type.GetArrayRank() > 1) + { + throw new InvalidOperationException("Multidimensional arrays are not supported!"); + } + + if (type.Name.Contains('*')) + { + throw new InvalidOperationException("Only 0-based 1-dimensional arrays are supported!"); + } + + var loc = il.DeclareLocal(type, true); + var end = il.DefineLabel(); + var isNull = il.DefineLabel(); + + il.Emit(OpCodes.Ldarg, (short)idx); + il.Emit(OpCodes.Brfalse, isNull); + + il.Emit(OpCodes.Ldarg, (short)idx); + il.Emit(OpCodes.Dup); + il.Emit(OpCodes.Stloc, loc); + il.Emit(OpCodes.Ldc_I4_0); + il.Emit(OpCodes.Ldelema, et); + il.Emit(OpCodes.Conv_I); + il.Emit(OpCodes.Br, end); + + il.MarkLabel(isNull); + LoadConstant(il, IntPtr.Zero); + il.MarkLabel(end); + + return typeof(IntPtr); + } + + if (typeof(Delegate).IsAssignableFrom(type)) + { + var mi = typeof(ICallingConventionAdapter).GetMethod("GetFunctionPointerForDelegate"); + var end = il.DefineLabel(); + var isNull = il.DefineLabel(); + + il.Emit(OpCodes.Ldarg, (short)idx); + il.Emit(OpCodes.Brfalse, isNull); + + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldfld, adapterField); + il.Emit(OpCodes.Ldarg, (short)idx); + il.Emit(OpCodes.Call, mi); + il.Emit(OpCodes.Br, end); + + il.MarkLabel(isNull); + LoadConstant(il, IntPtr.Zero); + il.MarkLabel(end); + return typeof(IntPtr); + } + + if (type.IsClass) + { + // non ref of class can just be passed as pointer + var loc = il.DeclareLocal(type, true); + var end = il.DefineLabel(); + var isNull = il.DefineLabel(); + + il.Emit(OpCodes.Ldarg, (short)idx); + il.Emit(OpCodes.Brfalse, isNull); + + il.Emit(OpCodes.Ldarg, (short)idx); + il.Emit(OpCodes.Dup); + il.Emit(OpCodes.Stloc, loc); + il.Emit(OpCodes.Conv_I); + // skip past the methodtable pointer to the first field + il.Emit(IntPtr.Size == 4 ? OpCodes.Ldc_I4_4 : OpCodes.Ldc_I4_8); + il.Emit(OpCodes.Conv_I); + il.Emit(OpCodes.Add); + il.Emit(OpCodes.Br, end); + + il.MarkLabel(isNull); + LoadConstant(il, IntPtr.Zero); + il.MarkLabel(end); + + return typeof(IntPtr); + } + + if (type.IsPrimitive || type.IsEnum) + { + il.Emit(OpCodes.Ldarg, (short)idx); + return type; + } + + throw new InvalidOperationException("Unrecognized parameter type!"); + } + } + + /// + /// mark an abstract method to be proxied by BizInvoker + /// + [AttributeUsage(AttributeTargets.Method)] + public class BizImportAttribute : Attribute + { + public CallingConvention CallingConvention { get; } + + /// + /// Gets or sets the name of entry point; if not given, the method's name is used + /// + public string EntryPoint { get; set; } + + /// + /// Gets or sets a value indicating whether or not to use a slower interop that supports more argument types + /// + public bool Compatibility { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// unmanaged calling convention + public BizImportAttribute(CallingConvention c) + { + CallingConvention = c; + } + } +} diff --git a/BizHawk.Common/BizInvoke/CallingConventionAdapter.cs b/BizHawk.Common/BizInvoke/CallingConventionAdapter.cs new file mode 100644 index 0000000000..11ab29d2d7 --- /dev/null +++ b/BizHawk.Common/BizInvoke/CallingConventionAdapter.cs @@ -0,0 +1,248 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Common.BizInvoke +{ + /// + /// create interop delegates and function pointers for a particular calling convention + /// + public interface ICallingConventionAdapter + { + IntPtr GetFunctionPointerForDelegate(Delegate d); + IntPtr GetArrivalFunctionPointer(IntPtr p, ParameterInfo pp, object lifetime); + + Delegate GetDelegateForFunctionPointer(IntPtr p, Type delegateType); + IntPtr GetDepartureFunctionPointer(IntPtr p, ParameterInfo pp, object lifetime); + } + + public static class CallingConventionAdapterExtensions + { + public static T GetDelegateForFunctionPointer(this ICallingConventionAdapter a, IntPtr p) + where T: class + { + return (T)(object)a.GetDelegateForFunctionPointer(p, typeof(T)); + } + } + + public class ParameterInfo + { + public Type ReturnType { get; } + public IReadOnlyList ParameterTypes { get; } + + public ParameterInfo(Type returnType, IEnumerable parameterTypes) + { + ReturnType = returnType; + ParameterTypes = parameterTypes.ToList().AsReadOnly(); + } + + public ParameterInfo(Type delegateType) + { + if (!typeof(Delegate).IsAssignableFrom(delegateType)) + throw new InvalidOperationException("Must be a delegate type!"); + var invoke = delegateType.GetMethod("Invoke"); + ReturnType = invoke.ReturnType; + ParameterTypes = invoke.GetParameters().Select(p => p.ParameterType).ToList().AsReadOnly(); + } + } + + public static class CallingConventionAdapters + { + private class NativeConvention : ICallingConventionAdapter + { + public IntPtr GetArrivalFunctionPointer(IntPtr p, ParameterInfo pp, object lifetime) + { + return p; + } + + public Delegate GetDelegateForFunctionPointer(IntPtr p, Type delegateType) + { + return Marshal.GetDelegateForFunctionPointer(p, delegateType); + } + + public IntPtr GetDepartureFunctionPointer(IntPtr p, ParameterInfo pp, object lifetime) + { + return p; + } + + public IntPtr GetFunctionPointerForDelegate(Delegate d) + { + return Marshal.GetFunctionPointerForDelegate(d); + } + } + + /// + /// native (pass-through) calling convention + /// + public static ICallingConventionAdapter Native { get; } = new NativeConvention(); + + /// + /// convention appropriate for waterbox guests + /// + public static ICallingConventionAdapter Waterbox { get; } = +#if true + new NativeConvention(); +#else + new SysVHostMsGuest(); +#endif + + private class SysVHostMsGuest : ICallingConventionAdapter + { + private const ulong Placeholder = 0xdeadbeeffeedface; + private const byte Padding = 0x06; + private const int BlockSize = 256; + private static readonly byte[][] Depart = + { + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x20, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x30, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x8b, 0x55, 0xf8, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x48, 0x89, 0xd1, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x30, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x40, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x89, 0x55, 0xe8, 0x48, 0x8b, 0x75, 0xe8, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x49, 0x89, 0xf0, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x40, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x89, 0x55, 0xe8, 0x48, 0x89, 0x4d, 0xe0, 0x48, 0x8b, 0x7d, 0xe0, 0x48, 0x8b, 0x75, 0xe8, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x49, 0x89, 0xf9, 0x49, 0x89, 0xf0, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x60, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x89, 0x55, 0xe8, 0x48, 0x89, 0x4d, 0xe0, 0x4c, 0x89, 0x45, 0xd8, 0x48, 0x8b, 0x7d, 0xe0, 0x48, 0x8b, 0x75, 0xe8, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0x8b, 0x45, 0xd8, 0x48, 0x89, 0x44, 0x24, 0x20, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x49, 0x89, 0xf9, 0x49, 0x89, 0xf0, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x60, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x89, 0x55, 0xe8, 0x48, 0x89, 0x4d, 0xe0, 0x4c, 0x89, 0x45, 0xd8, 0x4c, 0x89, 0x4d, 0xd0, 0x48, 0x8b, 0x7d, 0xe0, 0x48, 0x8b, 0x75, 0xe8, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0x8b, 0x45, 0xd0, 0x48, 0x89, 0x44, 0x24, 0x28, 0x48, 0x8b, 0x45, 0xd8, 0x48, 0x89, 0x44, 0x24, 0x20, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x49, 0x89, 0xf9, 0x49, 0x89, 0xf0, 0xff, 0xd0, 0xc9, 0xc3, }, + }; + private static readonly byte[][] Arrive = + { + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x20, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x30, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x8b, 0x55, 0xf8, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x48, 0x89, 0xd1, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x30, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x40, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x89, 0x55, 0xe8, 0x48, 0x8b, 0x75, 0xe8, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x49, 0x89, 0xf0, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x40, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x89, 0x55, 0xe8, 0x48, 0x89, 0x4d, 0xe0, 0x48, 0x8b, 0x7d, 0xe0, 0x48, 0x8b, 0x75, 0xe8, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x49, 0x89, 0xf9, 0x49, 0x89, 0xf0, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x60, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x89, 0x55, 0xe8, 0x48, 0x89, 0x4d, 0xe0, 0x4c, 0x89, 0x45, 0xd8, 0x48, 0x8b, 0x7d, 0xe0, 0x48, 0x8b, 0x75, 0xe8, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0x8b, 0x45, 0xd8, 0x48, 0x89, 0x44, 0x24, 0x20, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x49, 0x89, 0xf9, 0x49, 0x89, 0xf0, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x60, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x89, 0x55, 0xe8, 0x48, 0x89, 0x4d, 0xe0, 0x4c, 0x89, 0x45, 0xd8, 0x4c, 0x89, 0x4d, 0xd0, 0x48, 0x8b, 0x7d, 0xe0, 0x48, 0x8b, 0x75, 0xe8, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0x8b, 0x45, 0xd0, 0x48, 0x89, 0x44, 0x24, 0x28, 0x48, 0x8b, 0x45, 0xd8, 0x48, 0x89, 0x44, 0x24, 0x20, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x49, 0x89, 0xf9, 0x49, 0x89, 0xf0, 0xff, 0xd0, 0xc9, 0xc3, }, + }; + + private static readonly int[] DepartPlaceholderIndices; + private static readonly int[] ArrivePlaceholderIndices; + + private static int FindPlaceholderIndex(byte[] data) + { + return Enumerable.Range(0, data.Length - 7) + .Single(i => BitConverter.ToUInt64(data, i) == Placeholder); + } + + static SysVHostMsGuest() + { + DepartPlaceholderIndices = Depart.Select(FindPlaceholderIndex).ToArray(); + ArrivePlaceholderIndices = Arrive.Select(FindPlaceholderIndex).ToArray(); + if (Depart.Any(b => b.Length > BlockSize) || Arrive.Any(b => b.Length > BlockSize)) + throw new InvalidOperationException(); + } + + private readonly MemoryBlock _memory; + private readonly object _sync = new object(); + private readonly WeakReference[] _refs; + + public SysVHostMsGuest() + { + int size = 4 * 1024 * 1024; + _memory = new MemoryBlock((ulong)size); + _memory.Activate(); + _refs = new WeakReference[size / BlockSize]; + } + + private int FindFreeIndex() + { + for (int i = 0; i < _refs.Length; i++) + { + if (_refs[i] == null || !_refs[i].IsAlive) + return i; + } + throw new InvalidOperationException("Out of Thunk memory"); + } + + private static void VerifyParameter(Type type) + { + if (type == typeof(float) || type == typeof(double)) + throw new NotSupportedException("floating point not supported"); + if (type == typeof(void) || type.IsPrimitive) + return; + if (type.IsByRef || type.IsClass) + return; + throw new NotSupportedException("Unknown type. Possibly supported?"); + } + + private static int VerifyDelegateSignature(ParameterInfo pp) + { + VerifyParameter(pp.ReturnType); + foreach (var ppp in pp.ParameterTypes) + VerifyParameter(ppp); + return pp.ParameterTypes.Count; + } + + private void WriteThunk(byte[] data, int placeholderIndex, IntPtr p, int index) + { + _memory.Protect(_memory.Start, _memory.Size, MemoryBlock.Protection.RW); + var ss = _memory.GetStream(_memory.Start + (ulong)index * BlockSize, BlockSize, true); + ss.Write(data, 0, data.Length); + for (int i = data.Length; i < BlockSize; i++) + ss.WriteByte(Padding); + ss.Position = placeholderIndex; + var bw = new BinaryWriter(ss); + bw.Write((long)p); + _memory.Protect(_memory.Start, _memory.Size, MemoryBlock.Protection.RX); + } + + private IntPtr GetThunkAddress(int index) + { + return Z.US(_memory.Start + (ulong)index * BlockSize); + } + + private void SetLifetime(int index, object lifetime) + { + if (_refs[index] == null) + _refs[index] = new WeakReference(lifetime); + else + _refs[index].Target = lifetime; + } + + public IntPtr GetFunctionPointerForDelegate(Delegate d) + { + return GetArrivalFunctionPointer( + Marshal.GetFunctionPointerForDelegate(d), new ParameterInfo(d.GetType()), d); + } + + public IntPtr GetArrivalFunctionPointer(IntPtr p, ParameterInfo pp, object lifetime) + { + lock (_sync) + { + var index = FindFreeIndex(); + var count = VerifyDelegateSignature(pp); + WriteThunk(Arrive[count], ArrivePlaceholderIndices[count], p, index); + SetLifetime(index, lifetime); + return GetThunkAddress(index); + } + } + + public Delegate GetDelegateForFunctionPointer(IntPtr p, Type delegateType) + { + lock (_sync) + { + var index = FindFreeIndex(); + var count = VerifyDelegateSignature(new ParameterInfo(delegateType)); + WriteThunk(Depart[count], DepartPlaceholderIndices[count], p, index); + var ret = Marshal.GetDelegateForFunctionPointer(GetThunkAddress(index), delegateType); + SetLifetime(index, ret); + return ret; + } + } + + public IntPtr GetDepartureFunctionPointer(IntPtr p, ParameterInfo pp, object lifetime) + { + lock (_sync) + { + var index = FindFreeIndex(); + var count = VerifyDelegateSignature(pp); + WriteThunk(Depart[count], DepartPlaceholderIndices[count], p, index); + SetLifetime(index, lifetime); + return GetThunkAddress(index); + } + } + + } + } +} diff --git a/BizHawk.Emulation.Cores/MemoryBlock.cs b/BizHawk.Common/BizInvoke/MemoryBlock.cs similarity index 66% rename from BizHawk.Emulation.Cores/MemoryBlock.cs rename to BizHawk.Common/BizInvoke/MemoryBlock.cs index 5bdea3a105..3407960818 100644 --- a/BizHawk.Emulation.Cores/MemoryBlock.cs +++ b/BizHawk.Common/BizInvoke/MemoryBlock.cs @@ -5,122 +5,45 @@ using System.Text; using System.Runtime.InteropServices; using System.IO; -namespace BizHawk.Emulation.Cores +namespace BizHawk.Common.BizInvoke { - public static class Z - { - public static IntPtr US(ulong l) - { - if (IntPtr.Size == 8) - return (IntPtr)(long)l; - else - return (IntPtr)(int)l; - } - - public static UIntPtr UU(ulong l) - { - if (UIntPtr.Size == 8) - return (UIntPtr)l; - else - return (UIntPtr)(uint)l; - } - - public static IntPtr SS(long l) - { - if (IntPtr.Size == 8) - return (IntPtr)l; - else - return (IntPtr)(int)l; - } - - public static UIntPtr SU(long l) - { - if (UIntPtr.Size == 8) - return (UIntPtr)(ulong)l; - else - return (UIntPtr)(uint)l; - } - } - public sealed class MemoryBlock : IDisposable - { - /// - /// system page size - /// - public static int PageSize { get; private set;} - - /// - /// bitshift corresponding to PageSize - /// - private static readonly int PageShift; - /// - /// bitmask corresponding to PageSize - /// - private static readonly ulong PageMask; - - static MemoryBlock() - { - int p = PageSize = Environment.SystemPageSize; - while (p != 1) - { - p >>= 1; - PageShift++; - } - PageMask = (ulong)(PageSize - 1); - } - - /// - /// true if addr is aligned - /// - private static bool Aligned(ulong addr) - { - return (addr & PageMask) == 0; - } - - /// - /// align address down to previous page boundary - /// - private static ulong AlignDown(ulong addr) - { - return addr & ~PageMask; - } - - /// - /// align address up to next page boundary - /// - private static ulong AlignUp(ulong addr) - { - return ((addr - 1) | PageMask) + 1; - } - + { /// /// starting address of the memory block /// - public ulong Start { get; private set; } + public ulong Start { get; private set; } /// /// total size of the memory block /// - public ulong Size { get; private set; } + public ulong Size { get; private set; } /// /// ending address of the memory block; equal to start + size /// - public ulong End { get; private set; } - + public ulong End { get; private set; } + /// /// handle returned by CreateFileMapping /// - private IntPtr _handle; - + private IntPtr _handle; + /// /// true if this is currently swapped in /// - public bool Active { get; private set; } - + public bool Active { get; private set; } + /// /// stores last set memory protection value for each page /// - private readonly Protection[] _pageData; + private readonly Protection[] _pageData; + + /// + /// snapshot for XOR buffer + /// + private byte[] _snapshot; + public byte[] XorHash { get; private set; } + /// /// get a page index within the block /// @@ -129,17 +52,17 @@ namespace BizHawk.Emulation.Cores if (addr < Start || addr >= End) throw new ArgumentOutOfRangeException(); - return (int)((addr - Start) >> PageShift); - } - + return (int)((addr - Start) >> WaterboxUtils.PageShift); + } + /// /// get a start address for a page index within the block /// private ulong GetStartAddr(int page) { - return ((ulong)page << PageShift) + Start; - } - + return ((ulong)page << WaterboxUtils.PageShift) + Start; + } + /// /// allocate size bytes at any address /// @@ -147,8 +70,8 @@ namespace BizHawk.Emulation.Cores public MemoryBlock(ulong size) : this(0, size) { - } - + } + /// /// allocate size bytes starting at a particular address /// @@ -156,11 +79,11 @@ namespace BizHawk.Emulation.Cores /// public MemoryBlock(ulong start, ulong size) { - if (!Aligned(start)) + if (!WaterboxUtils.Aligned(start)) throw new ArgumentOutOfRangeException(); if (size == 0) throw new ArgumentOutOfRangeException(); - size = AlignUp(size); + size = WaterboxUtils.AlignUp(size); _handle = Kernel32.CreateFileMapping(Kernel32.INVALID_HANDLE_VALUE, IntPtr.Zero, Kernel32.FileMapProtection.PageExecuteReadWrite | Kernel32.FileMapProtection.SectionCommit, (uint)(size >> 32), (uint)size, null); @@ -171,8 +94,8 @@ namespace BizHawk.Emulation.Cores End = start + size; Size = size; _pageData = new Protection[GetPage(End - 1) + 1]; - } - + } + /// /// activate the memory block, swapping it in at the specified address /// @@ -187,8 +110,8 @@ namespace BizHawk.Emulation.Cores } ProtectAll(); Active = true; - } - + } + /// /// deactivate the memory block, removing it from RAM but leaving it immediately available to swap back in /// @@ -199,16 +122,16 @@ namespace BizHawk.Emulation.Cores if (!Kernel32.UnmapViewOfFile(Z.US(Start))) throw new InvalidOperationException("UnmapViewOfFile() returned NULL"); Active = false; - } - + } + /// /// Memory protection constant /// public enum Protection : byte { None, R, RW, RX - } - + } + /// /// Get a stream that can be used to read or write from part of the block. Does not check for or change Protect()! /// @@ -216,11 +139,68 @@ namespace BizHawk.Emulation.Cores { if (start < Start) throw new ArgumentOutOfRangeException(nameof(start)); - if (start + length > End) throw new ArgumentOutOfRangeException(nameof(length)); return new MemoryViewStream(!writer, writer, (long)start, (long)length, this); + } + + /// + /// get a stream that can be used to read or write from part of the block. + /// both reads and writes will be XORed against an earlier recorded snapshot + /// + public Stream GetXorStream(ulong start, ulong length, bool writer) + { + if (start < Start) + throw new ArgumentOutOfRangeException(nameof(start)); + if (start + length > End) + throw new ArgumentOutOfRangeException(nameof(length)); + if (_snapshot == null) + throw new InvalidOperationException("No snapshot taken!"); + + return new MemoryViewXorStream(!writer, writer, (long)start, (long)length, this, _snapshot, (long)(start - Start)); + } + + /// + /// take a snapshot of the entire memory block's contents, for use in GetXorStream + /// + public void SaveXorSnapshot() + { + if (_snapshot != null) + throw new InvalidOperationException("Snapshot already taken"); + if (!Active) + throw new InvalidOperationException("Not active"); + + // temporarily switch the entire block to `R`: in case some areas are unreadable, we don't want + // that to complicate things + Kernel32.MemoryProtection old; + if (!Kernel32.VirtualProtect(Z.UU(Start), Z.UU(Size), Kernel32.MemoryProtection.READONLY, out old)) + throw new InvalidOperationException("VirtualProtect() returned FALSE!"); + + _snapshot = new byte[Size]; + var ds = new MemoryStream(_snapshot, true); + var ss = GetStream(Start, Size, false); + ss.CopyTo(ds); + XorHash = WaterboxUtils.Hash(_snapshot); + + ProtectAll(); + } + + /// + /// take a hash of the current full contents of the block, including unreadable areas + /// + /// + public byte[] FullHash() + { + if (!Active) + throw new InvalidOperationException("Not active"); + // temporarily switch the entire block to `R` + Kernel32.MemoryProtection old; + if (!Kernel32.VirtualProtect(Z.UU(Start), Z.UU(Size), Kernel32.MemoryProtection.READONLY, out old)) + throw new InvalidOperationException("VirtualProtect() returned FALSE!"); + var ret = WaterboxUtils.Hash(GetStream(Start, Size, false)); + ProtectAll(); + return ret; } private static Kernel32.MemoryProtection GetKernelMemoryProtectionValue(Protection prot) @@ -235,8 +215,8 @@ namespace BizHawk.Emulation.Cores default: throw new ArgumentOutOfRangeException(nameof(prot)); } return p; - } - + } + /// /// restore all recorded protections /// @@ -256,8 +236,8 @@ namespace BizHawk.Emulation.Cores ps = i + 1; } } - } - + } + /// /// set r/w/x protection on a portion of memory. rounded to encompassing pages /// @@ -270,14 +250,17 @@ namespace BizHawk.Emulation.Cores var p = GetKernelMemoryProtectionValue(prot); for (int i = pstart; i <= pend; i++) - _pageData[i] = prot; // also store the value for later use - - if (Active) // it's legal to Protect() if we're not active; the information is just saved for the next activation + _pageData[i] = prot; // also store the value for later use + + if (Active) // it's legal to Protect() if we're not active; the information is just saved for the next activation { - // TODO: if using another OS's memory protection calls, they must give the same non-aligned behavior - // as VirtualProtect, or this must be changed + var computedStart = WaterboxUtils.AlignDown(start); + var computedEnd = WaterboxUtils.AlignUp(start + length); + var computedLength = computedEnd - computedStart; + Kernel32.MemoryProtection old; - if (!Kernel32.VirtualProtect(Z.UU(start), Z.UU(length), p, out old)) + if (!Kernel32.VirtualProtect(Z.UU(computedStart), + Z.UU(computedLength), p, out old)) throw new InvalidOperationException("VirtualProtect() returned FALSE!"); } } @@ -324,38 +307,39 @@ namespace BizHawk.Emulation.Cores private MemoryBlock _owner; - private bool _readable; - private bool _writable; + private readonly bool _readable; + private readonly bool _writable; private long _length; private long _pos; - private long _ptr; + private readonly long _ptr; - public override bool CanRead { get { return _readable; } } - public override bool CanSeek { get { return true; } } - public override bool CanWrite { get { return _writable; } } + public override bool CanRead => _readable; + public override bool CanSeek => true; + public override bool CanWrite => _writable; public override void Flush() { } - public override long Length { get { return _length; } } + public override long Length => _length; public override long Position - { - get { return _pos; } set + { + get { return _pos; } + set { if (value < 0 || value > _length) throw new ArgumentOutOfRangeException(); _pos = value; - } + } } public override int Read(byte[] buffer, int offset, int count) { if (!_readable) throw new InvalidOperationException(); - if (count < 0 || count > buffer.Length) + if (count < 0 || count + offset > buffer.Length) throw new ArgumentOutOfRangeException(); EnsureNotDisposed(); count = (int)Math.Min(count, _length - _pos); - Marshal.Copy(Z.SS(_ptr + _pos), buffer, 0, count); + Marshal.Copy(Z.SS(_ptr + _pos), buffer, offset, count); _pos += count; return count; } @@ -367,7 +351,7 @@ namespace BizHawk.Emulation.Cores { default: case SeekOrigin.Begin: - newpos = 0; + newpos = offset; break; case SeekOrigin.Current: newpos = _pos + offset; @@ -389,15 +373,73 @@ namespace BizHawk.Emulation.Cores { if (!_writable) throw new InvalidOperationException(); - if (count < 0 || count > buffer.Length) + if (count < 0 || count + offset > buffer.Length) + throw new ArgumentOutOfRangeException(); + if (count > _length - _pos) throw new ArgumentOutOfRangeException(); EnsureNotDisposed(); - count = (int)Math.Min(count, _length - _pos); - Marshal.Copy(buffer, 0, Z.SS(_ptr + _pos), count); + Marshal.Copy(buffer, offset, Z.SS(_ptr + _pos), count); _pos += count; } } + private class MemoryViewXorStream : MemoryViewStream + { + public MemoryViewXorStream(bool readable, bool writable, long ptr, long length, MemoryBlock owner, + byte[] initial, long offset) + : base(readable, writable, ptr, length, owner) + { + _initial = initial; + _offset = (int)offset; + } + + /// + /// the initial data to XOR against for both reading and writing + /// + private readonly byte[] _initial; + /// + /// offset into the XOR data that this stream is representing + /// + private readonly int _offset; + + public override int Read(byte[] buffer, int offset, int count) + { + int pos = (int)Position; + count = base.Read(buffer, offset, count); + XorTransform(_initial, _offset + pos, buffer, offset, count); + return count; + } + + public override void Write(byte[] buffer, int offset, int count) + { + int pos = (int)Position; + if (count < 0 || count + offset > buffer.Length) + throw new ArgumentOutOfRangeException(); + if (count > Length - pos) + throw new ArgumentOutOfRangeException(); + // is mutating the buffer passed to Stream.Write kosher? + XorTransform(_initial, _offset + pos, buffer, offset, count); + base.Write(buffer, offset, count); + } + + private static unsafe void XorTransform(byte[] source, int sourceOffset, byte[] dest, int destOffset, int length) + { + // we don't do any bounds check because MemoryViewStream.Read and MemoryViewXorStream.Write already did it + + // TODO: C compilers can make this pretty snappy, but can the C# jitter? Or do we need intrinsics + fixed (byte* _s = source, _d = dest) + { + byte* s = _s + sourceOffset; + byte* d = _d + destOffset; + byte* sEnd = s + length; + while (s < sEnd) + { + *d++ ^= *s++; + } + } + } + } + private static class Kernel32 { [DllImport("kernel32.dll", SetLastError = true)] diff --git a/BizHawk.Common/BizInvoke/WaterboxUtils.cs b/BizHawk.Common/BizInvoke/WaterboxUtils.cs new file mode 100644 index 0000000000..a85a437485 --- /dev/null +++ b/BizHawk.Common/BizInvoke/WaterboxUtils.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Text; + +namespace BizHawk.Common.BizInvoke +{ + public static class WaterboxUtils + { + /// + /// copy `len` bytes from `src` to `dest` + /// + /// + /// + /// + public static void CopySome(Stream src, Stream dst, long len) + { + var buff = new byte[4096]; + while (len > 0) + { + int r = src.Read(buff, 0, (int)Math.Min(len, 4096)); + dst.Write(buff, 0, r); + len -= r; + } + } + + public static byte[] Hash(byte[] data) + { + using (var h = SHA1.Create()) + { + return h.ComputeHash(data); + } + } + + public static byte[] Hash(Stream s) + { + using (var h = SHA1.Create()) + { + return h.ComputeHash(s); + } + } + + public static unsafe void ZeroMemory(IntPtr mem, long length) + { + byte* p = (byte*)mem; + byte* end = p + length; + while (p < end) + { + *p++ = 0; + } + } + + public static long Timestamp() + { + return DateTime.UtcNow.Ticks; + } + + /// + /// system page size + /// + public static int PageSize { get; private set; } + + /// + /// bitshift corresponding to PageSize + /// + public static int PageShift { get; private set; } + /// + /// bitmask corresponding to PageSize + /// + public static ulong PageMask { get; private set; } + + static WaterboxUtils() + { + int p = PageSize = Environment.SystemPageSize; + while (p != 1) + { + p >>= 1; + PageShift++; + } + PageMask = (ulong)(PageSize - 1); + } + + /// + /// true if addr is aligned + /// + public static bool Aligned(ulong addr) + { + return (addr & PageMask) == 0; + } + + /// + /// align address down to previous page boundary + /// + public static ulong AlignDown(ulong addr) + { + return addr & ~PageMask; + } + + /// + /// align address up to next page boundary + /// + public static ulong AlignUp(ulong addr) + { + return ((addr - 1) | PageMask) + 1; + } + + /// + /// return the minimum number of pages needed to hold size + /// + public static int PagesNeeded(ulong size) + { + return (int)((size + PageMask) >> PageShift); + } + } + + // C# is annoying: arithmetic operators for native ints are not exposed. + // So we store them as long/ulong instead in many places, and use these helpers + // to convert to IntPtr when needed + + public static class Z + { + public static IntPtr US(ulong l) + { + if (IntPtr.Size == 8) + return (IntPtr)(long)l; + else + return (IntPtr)(int)l; + } + + public static UIntPtr UU(ulong l) + { + if (UIntPtr.Size == 8) + return (UIntPtr)l; + else + return (UIntPtr)(uint)l; + } + + public static IntPtr SS(long l) + { + if (IntPtr.Size == 8) + return (IntPtr)l; + else + return (IntPtr)(int)l; + } + + public static UIntPtr SU(long l) + { + if (UIntPtr.Size == 8) + return (UIntPtr)(ulong)l; + else + return (UIntPtr)(uint)l; + } + } +} diff --git a/BizHawk.Common/DescribableEnumConverter.cs b/BizHawk.Common/DescribableEnumConverter.cs new file mode 100644 index 0000000000..3547d04995 --- /dev/null +++ b/BizHawk.Common/DescribableEnumConverter.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Common +{ + public class DescribableEnumConverter : EnumConverter + { + private Type enumType; + + public DescribableEnumConverter(Type type) : base(type) + { + enumType = type; + } + + public override bool CanConvertTo(ITypeDescriptorContext context, Type destType) + { + return destType == typeof(string); + } + + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, + object value, Type destType) + { + var fi = enumType.GetField(Enum.GetName(enumType, value)); + var attr = (DisplayAttribute)fi.GetCustomAttribute(typeof(DisplayAttribute)); + if (attr != null) + return attr.Name; + else + return value.ToString(); + } + + public override bool CanConvertFrom(ITypeDescriptorContext context, Type srcType) + { + return srcType == typeof(string); + } + + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, + object value) + { + foreach (var fi in enumType.GetFields(BindingFlags.Public | BindingFlags.Static)) + { + var attr = (DisplayAttribute)fi.GetCustomAttribute(typeof(DisplayAttribute)); + if (attr != null && attr.Name.Equals(value)) + return Enum.Parse(enumType, fi.Name); + } + return Enum.Parse(enumType, (string)value); + } + + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return true; + } + + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + var ret = new List(); + foreach (var fi in enumType.GetFields(BindingFlags.Public | BindingFlags.Static)) + { + ret.Add(fi.GetValue(null)); + } + return new StandardValuesCollection(ret); + } + } +} diff --git a/BizHawk.Common/Extensions/BufferExtensions.cs b/BizHawk.Common/Extensions/BufferExtensions.cs index 82f272d34a..e04788f445 100644 --- a/BizHawk.Common/Extensions/BufferExtensions.cs +++ b/BizHawk.Common/Extensions/BufferExtensions.cs @@ -8,6 +8,7 @@ namespace BizHawk.Common.BufferExtensions { public static class BufferExtensions { + [Obsolete] // do we know of any situation where SaveAsHexFast doesn't work? public static void SaveAsHex(this byte[] buffer, TextWriter writer) { foreach (var b in buffer) @@ -39,6 +40,7 @@ namespace BizHawk.Common.BufferExtensions writer.WriteLine(); } + [Obsolete] // do we know of any situation where SaveAsHexFast doesn't work? public static void SaveAsHex(this byte[] buffer, TextWriter writer, int length) { for (int i = 0; i < length; i++) diff --git a/BizHawk.Common/IImportResolver.cs b/BizHawk.Common/IImportResolver.cs index 61c7d1ddba..a6130e8c67 100644 --- a/BizHawk.Common/IImportResolver.cs +++ b/BizHawk.Common/IImportResolver.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace BizHawk.Common { @@ -12,6 +13,12 @@ namespace BizHawk.Common public static class ImportResolverExtensions { + /// + /// Resolve an entry point and throw an exception if that resolution is NULL + /// + /// + /// + /// public static IntPtr SafeResolve(this IImportResolver dll, string entryPoint) { var ret = dll.Resolve(entryPoint); @@ -23,4 +30,32 @@ namespace BizHawk.Common return ret; } } + + /// + /// compose multiple ImportResolvers, where subsequent ones takes precedence over earlier ones + /// + public class PatchImportResolver : IImportResolver + { + private readonly List _resolvers = new List(); + + public PatchImportResolver(params IImportResolver[] rr) + { + Add(rr); + } + public void Add(params IImportResolver[] rr) + { + _resolvers.AddRange(rr); + } + + public IntPtr Resolve(string entryPoint) + { + for (int i = _resolvers.Count - 1; i >= 0; i--) + { + var ret = _resolvers[i].Resolve(entryPoint); + if (ret != IntPtr.Zero) + return ret; + } + return IntPtr.Zero; + } + } } diff --git a/BizHawk.Common/IMonitor.cs b/BizHawk.Common/IMonitor.cs index a31335ef93..7b287f9ea2 100644 --- a/BizHawk.Common/IMonitor.cs +++ b/BizHawk.Common/IMonitor.cs @@ -1,8 +1,40 @@ -namespace BizHawk.Common +using System; + +namespace BizHawk.Common { public interface IMonitor { void Enter(); void Exit(); } + + public static class MonitorExtensions + { + public static IDisposable EnterExit(this IMonitor m) + { + var ret = new EnterExitWrapper(m); + m.Enter(); + return ret; + } + + private class EnterExitWrapper : IDisposable + { + private readonly IMonitor _m; + private bool _disposed = false; + + public EnterExitWrapper(IMonitor m) + { + _m = m; + } + + public void Dispose() + { + if (!_disposed) + { + _m.Exit(); + _disposed = true; + } + } + } + } } diff --git a/BizHawk.Common/Win32Hacks.cs b/BizHawk.Common/Win32Hacks.cs index 7126f0e7b2..9770518d38 100644 --- a/BizHawk.Common/Win32Hacks.cs +++ b/BizHawk.Common/Win32Hacks.cs @@ -458,6 +458,14 @@ namespace BizHawk.Common { DeleteFileW(path + ":Zone.Identifier"); } + + [DllImport("kernel32.dll")] + static extern bool IsDebuggerPresent(); + + public static bool IsDebuggerReallyPresent() + { + return IsDebuggerPresent(); + } } } \ No newline at end of file diff --git a/BizHawk.Emulation.Common/Base Implementations/ControllerDefinition.cs b/BizHawk.Emulation.Common/Base Implementations/ControllerDefinition.cs index ca7f316176..2a56072e53 100644 --- a/BizHawk.Emulation.Common/Base Implementations/ControllerDefinition.cs +++ b/BizHawk.Emulation.Common/Base Implementations/ControllerDefinition.cs @@ -165,7 +165,8 @@ namespace BizHawk.Emulation.Common List list = new List(FloatControls); list.AddRange(BoolButtons); - List[] ret = new List[9]; + // starts with console buttons, then each plasyer's buttons individually + List[] ret = new List[PlayerCount + 1]; for (int i = 0; i < ret.Length; i++) { ret[i] = new List(); @@ -182,16 +183,18 @@ namespace BizHawk.Emulation.Common public int PlayerNumber(string buttonName) { - int player = 0; - if (buttonName.Length > 3 && buttonName.StartsWith("P") && char.IsNumber(buttonName[1])) + var match = PlayerRegex.Match(buttonName); + if (match.Success) { - player = buttonName[1] - '0'; + return int.Parse(match.Groups[1].Value); + } + else + { + return 0; } - - return player; } - private static readonly Regex PlayerRegex = new Regex("^P(\\d) "); + private static readonly Regex PlayerRegex = new Regex("^P(\\d+) "); public int PlayerCount { @@ -199,9 +202,7 @@ namespace BizHawk.Emulation.Common { var allNames = FloatControls.Concat(BoolButtons).ToList(); var player = allNames - .Select(s => PlayerRegex.Match(s).Groups[1]) - .Where(group => group.Success) - .Select(group => group.Value[0] - '0') + .Select(PlayerNumber) .DefaultIfEmpty(0) .Max(); diff --git a/BizHawk.Emulation.Common/Base Implementations/MemoryDomainImpls.cs b/BizHawk.Emulation.Common/Base Implementations/MemoryDomainImpls.cs index be932755cf..6a80b62c62 100644 --- a/BizHawk.Emulation.Common/Base Implementations/MemoryDomainImpls.cs +++ b/BizHawk.Emulation.Common/Base Implementations/MemoryDomainImpls.cs @@ -1,4 +1,5 @@ -using System; +using BizHawk.Common; +using System; namespace BizHawk.Emulation.Common { @@ -9,7 +10,8 @@ namespace BizHawk.Emulation.Common public Func Peek { - get { return _peek; } set { _peek = value; } + get { return _peek; } + set { _peek = value; } } public Action Poke @@ -134,6 +136,60 @@ namespace BizHawk.Emulation.Common } } + public unsafe class MemoryDomainIntPtrMonitor : MemoryDomain + { + public IntPtr Data { get; set; } + private readonly IMonitor _monitor; + + public override byte PeekByte(long addr) + { + if ((ulong)addr < (ulong)Size) + { + using (_monitor.EnterExit()) + { + return ((byte*)Data)[addr]; + } + } + + throw new ArgumentOutOfRangeException(nameof(addr)); + } + + public override void PokeByte(long addr, byte val) + { + if (Writable) + { + if ((ulong)addr < (ulong)Size) + { + using (_monitor.EnterExit()) + { + ((byte*)Data)[addr] = val; + } + } + else + { + throw new ArgumentOutOfRangeException(nameof(addr)); + } + } + } + + public void SetSize(long size) + { + Size = size; + } + + public MemoryDomainIntPtrMonitor(string name, Endian endian, IntPtr data, long size, bool writable, int wordSize, + IMonitor monitor) + { + Name = name; + EndianType = endian; + Data = data; + Size = size; + Writable = writable; + WordSize = wordSize; + _monitor = monitor; + } + } + public unsafe class MemoryDomainIntPtrSwap16 : MemoryDomain { public IntPtr Data { get; set; } @@ -173,4 +229,53 @@ namespace BizHawk.Emulation.Common WordSize = 2; } } + + public unsafe class MemoryDomainIntPtrSwap16Monitor : MemoryDomain + { + public IntPtr Data { get; set; } + private readonly IMonitor _monitor; + + public override byte PeekByte(long addr) + { + if ((ulong)addr < (ulong)Size) + { + using (_monitor.EnterExit()) + { + return ((byte*)Data)[addr ^ 1]; + } + } + + throw new ArgumentOutOfRangeException(nameof(addr)); + } + + public override void PokeByte(long addr, byte val) + { + if (Writable) + { + if ((ulong)addr < (ulong)Size) + { + using (_monitor.EnterExit()) + { + ((byte*)Data)[addr ^ 1] = val; + } + } + else + { + throw new ArgumentOutOfRangeException(nameof(addr)); + } + } + } + + public MemoryDomainIntPtrSwap16Monitor(string name, Endian endian, IntPtr data, long size, bool writable, + IMonitor monitor) + { + Name = name; + EndianType = endian; + Data = data; + Size = size; + Writable = writable; + WordSize = 2; + _monitor = monitor; + } + } } diff --git a/BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj b/BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj index 7d96a2d9e0..76bd2ee5a3 100644 --- a/BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj +++ b/BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj @@ -1,8 +1,8 @@  - + true - ..\output64\dll\ + ..\output\dll\ DEBUG;TRACE true full @@ -17,9 +17,10 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules false false + false - ..\output64\dll\ + ..\output\dll\ TRACE true true @@ -35,6 +36,7 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules false false + false @@ -45,31 +47,10 @@ Properties BizHawk.Emulation.Common BizHawk.Emulation.Common - v4.0 + v4.6.1 512 - - true - full - false - ..\output\dll\ - DEBUG;TRACE - prompt - 4 - true - x86 - - - pdbonly - true - ..\output\dll\ - TRACE - prompt - 4 - true - x86 - False diff --git a/BizHawk.Emulation.Common/Database/Database.cs b/BizHawk.Emulation.Common/Database/Database.cs index c14f807f15..9d79a2b950 100644 --- a/BizHawk.Emulation.Common/Database/Database.cs +++ b/BizHawk.Emulation.Common/Database/Database.cs @@ -331,6 +331,19 @@ namespace BizHawk.Emulation.Common case ".DO": game.System = "AppleII"; break; + + case ".VB": + game.System = "VB"; + break; + + case ".NGP": + case ".NGC": + game.System = "NGP"; + break; + + case ".O2": + game.System = "O2"; + break; } game.Name = Path.GetFileNameWithoutExtension(fileName)?.Replace('_', ' '); diff --git a/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs b/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs index d44bfc5368..af3d781483 100644 --- a/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs +++ b/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs @@ -30,6 +30,8 @@ namespace BizHawk.Emulation.Common FirmwareAndOption("A3AF676991391A6DD716C79022D4947206B78164", 4096, "A78", "Bios_HSC", "7800highscore.bin", "Highscore Bios"); FirmwareAndOption("45BEDC4CBDEAC66C7DF59E9E599195C778D86A92", 8192, "Coleco", "Bios", "ColecoBios.bin", "Bios"); + FirmwareAndOption("079a7ce93f3fd7d35e444b2fab16b1867c95e2c1", 66084, "SGB", "SPC", "sgb.spc", "Super Gameboy SPC"); + var gbaNormal = File("300C20DF6731A33952DED8C436F7F186D25D3492", 16384, "gbabios.rom", "Bios (World)"); var gbaJDebug = File("AA98A2AD32B86106340665D1222D7D973A1361C7", 16384, "gbabios.rom", "Bios (J Debug)"); Firmware("GBA", "Bios", "Bios"); @@ -70,6 +72,8 @@ namespace BizHawk.Emulation.Common Option("SAT", "E", ss_100a_ue); Option("SAT", "E", ss_100_j); Option("SAT", "E", ss_101_j); + FirmwareAndOption("a67cd4f550751f8b91de2b8b74528ab4e0c11c77", 2 * 1024 * 1024, "SAT", "KOF95", "kof95.bin", "King of Fighters cartridge"); + Firmware("SAT", "ULTRAMAN", "Ultraman cartridge"); var ti83_102 = File("CE08F6A808701FC6672230A790167EE485157561", 262144, "ti83_102.rom", "TI-83 Rom v1.02"); // ?? is this size correct? var ti83_103 = File("8399E384804D8D29866CAA4C8763D7A61946A467", 262144, "ti83_103.rom", "TI-83 Rom v1.03"); // ?? is this size correct? @@ -198,6 +202,12 @@ namespace BizHawk.Emulation.Common Firmware("AppleII", "DiskII", "DiskII.rom"); var appleII_DiskII = File("D4181C9F046AAFC3FB326B381BAAC809D9E38D16", 256, "DiskII.rom", "Disk II"); 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"); + + FirmwareAndOption("4ED31EC6B0B175BB109C0EB5FD3D193DA823339F", 256, "GB", "World", "GB_boot_ROM.gb", "Game Boy BIOS"); + FirmwareAndOption("1293D68BF9643BC4F36954C1E80E38F39864528D", 2304, "GBC", "World", "GBC_boot_ROM.gb", "Game Boy Color BIOS"); } // adds a defined firmware ID to the database @@ -329,4 +339,4 @@ namespace BizHawk.Emulation.Common return found.FirstOrDefault(); } } // static class FirmwareDatabase -} \ No newline at end of file +} diff --git a/BizHawk.Emulation.Common/Interfaces/Services/IStatable.cs b/BizHawk.Emulation.Common/Interfaces/Services/IStatable.cs index 4c375d67b0..b2580671c9 100644 --- a/BizHawk.Emulation.Common/Interfaces/Services/IStatable.cs +++ b/BizHawk.Emulation.Common/Interfaces/Services/IStatable.cs @@ -2,13 +2,22 @@ namespace BizHawk.Emulation.Common { + /// + /// Binary save and load state only without any trappings. At the moment, an emulator core should not implement this directly + /// + public interface IBinaryStateable + { + void SaveStateBinary(BinaryWriter writer); + void LoadStateBinary(BinaryReader reader); + } + /// /// This service manages the logic of sending and receiving savestates from the core /// If this service is available, client apps will expose features for making savestates and that utilize savestates (such as rewind)) /// If unavailable these options will not be exposed /// Additionally many tools depend on savestates such as TAStudio, these will only be available if this service is implemented /// - public interface IStatable : IEmulatorService + public interface IStatable : IBinaryStateable, IEmulatorService { /// /// Gets a value indicating whether the core would rather give a binary savestate than a text one. Both must function regardless @@ -18,9 +27,6 @@ namespace BizHawk.Emulation.Common void SaveStateText(TextWriter writer); void LoadStateText(TextReader reader); - void SaveStateBinary(BinaryWriter writer); - void LoadStateBinary(BinaryReader reader); - /// /// save state binary to a byte buffer /// diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index a48dd0cc63..9a6c529b43 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -1,5 +1,5 @@  - + Debug x86 @@ -10,7 +10,7 @@ Properties BizHawk.Emulation.Cores BizHawk.Emulation.Cores - v4.0 + v4.6.1 512 @@ -33,39 +33,13 @@ true - - true - full - false - ..\output\dll\ - DEBUG;TRACE - prompt - 4 - x86 - true - false - AllRules.ruleset - - - pdbonly - true - ..\output\dll\ - TRACE;VS2010 - prompt - 4 - x86 - true - AllRules.ruleset - false - true - ..\output64\dll\ + ..\output\dll\ DEBUG;TRACE true full x64 - ..\output\dll\BizHawk.Emulation.Cores.dll.CodeAnalysisLog.xml true GlobalSuppressions.cs false @@ -76,9 +50,10 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules false false + false - ..\output64\dll\ + ..\output\dll\ TRACE;VS2010 true true @@ -95,6 +70,7 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules false false + false @@ -110,7 +86,11 @@ False ..\References\OpenTK.dll + + ..\References\PeNet.dll + + 3.5 @@ -382,7 +362,7 @@ A7800Hawk.cs - + A7800Hawk.cs @@ -495,6 +475,8 @@ + + Gambatte.cs @@ -559,7 +541,10 @@ + + + @@ -646,7 +631,6 @@ - @@ -1022,6 +1006,8 @@ + + @@ -1143,29 +1129,9 @@ - - - - Yabause.cs - - - Yabause.cs - - - Yabause.cs - - - Yabause.cs - - - Yabause.cs - - - Yabause.cs - - - Yabause.cs - + + + SMS.cs @@ -1206,6 +1172,9 @@ + + + @@ -1284,7 +1253,10 @@ - + + + + @@ -1306,7 +1278,9 @@ - + + + @@ -1318,6 +1292,11 @@ + + + + + diff --git a/BizHawk.Emulation.Cores/Consoles/Magnavox/LibO2Em.cs b/BizHawk.Emulation.Cores/Consoles/Magnavox/LibO2Em.cs new file mode 100644 index 0000000000..d4e4fdb6d9 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Magnavox/LibO2Em.cs @@ -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); + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Magnavox/O2Em.cs b/BizHawk.Emulation.Cores/Consoles/Magnavox/O2Em.cs new file mode 100644 index 0000000000..b3055049d0 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Magnavox/O2Em.cs @@ -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(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(); + } + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs index 6c4e22442c..13467e19d2 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs @@ -132,5 +132,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA [DllImport(dll, CallingConvention = cc)] public static extern void BizGetRegisters(IntPtr ctx, int[] dest); + + [DllImport(dll, CallingConvention = cc)] + public static extern void BizWriteBus(IntPtr ctx, uint addr, byte val); + + [DllImport(dll, CallingConvention = cc)] + public static extern byte BizReadBus(IntPtr ctx, uint addr); + } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IMemoryDomains.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IMemoryDomains.cs index 06083eb0da..730e339447 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IMemoryDomains.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IMemoryDomains.cs @@ -34,6 +34,28 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA mm.Add(_sram = new MemoryDomainIntPtr("SRAM", le, IntPtr.Zero, 0, true, 4)); // size will be fixed in wireup mm.Add(_cwram = new MemoryDomainDelegate("Combined WRAM", (256 + 32) * 1024, le, null, null, 4)); + mm.Add(new MemoryDomainDelegate("System Bus", 0x10000000, le, + delegate (long addr) + { + var a = (uint)addr; + if (a >= 0x10000000) + { + throw new ArgumentOutOfRangeException(); + } + + return LibmGBA.BizReadBus(_core, a); + }, + delegate (long addr, byte val) + { + var a = (uint)addr; + if (a >= 0x10000000) + { + throw new ArgumentOutOfRangeException(); + } + + LibmGBA.BizWriteBus(_core, a, val); + }, 4)); + _memoryDomains = new MemoryDomainList(mm); WireMemoryDomainPointers(); } @@ -55,7 +77,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA // special combined ram memory domain _cwram.Peek = - delegate(long addr) + delegate (long addr) { if (addr < 0 || addr >= (256 + 32) * 1024) { @@ -70,7 +92,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA return PeekWRAM(s.wram, addr); }; _cwram.Poke = - delegate(long addr, byte val) + delegate (long addr, byte val) { if (addr < 0 || addr >= (256 + 32) * 1024) { diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs index 5f3243a043..96d90306f0 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs @@ -3,7 +3,7 @@ using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.Nintendo.GBA { - [CoreAttributes("mGBA", "endrift", true, true, "0.5.0", "https://mgba.io/", false)] + [CoreAttributes("mGBA", "endrift", true, true, "0.6.0 (24ab81f8db7745586cef246be8957ad272aded9b)", "https://mgba.io/", false)] [ServiceNotApplicable(typeof(IDriveLight), typeof(IRegionable))] public partial class MGBAHawk : IEmulator, IVideoProvider, ISoundProvider, IGBAGPUViewable, ISaveRam, IStatable, IInputPollable, ISettable, diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IEmulator.cs index b13d7e4dc8..38c11b0234 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IEmulator.cs @@ -95,8 +95,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy { if (GambatteState != IntPtr.Zero) { + Console.WriteLine("disposing"); LibGambatte.gambatte_destroy(GambatteState); + Console.WriteLine("step2"); GambatteState = IntPtr.Zero; + Console.WriteLine("disposed"); } DisposeSound(); diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ISettable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ISettable.cs index f6cf22c4f1..f213b6cdb1 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ISettable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ISettable.cs @@ -80,6 +80,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy public class GambatteSyncSettings { + [DisplayName("Enable BIOS: WARNING: File must exist!")] + [Description("Boots game using system BIOS. Should be used for TASing")] + [DefaultValue(false)] + public bool EnableBIOS { get; set; } + [DisplayName("Force DMG Mode")] [Description("Force the game to run on DMG hardware, even if it's detected as a CGB game. Relevant for games that are \"CGB Enhanced\" but do not require CGB.")] [DefaultValue(false)] diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ISoundProvider.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ISoundProvider.cs index a4bd1a40c1..422a845182 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ISoundProvider.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ISoundProvider.cs @@ -1,116 +1,116 @@ -using System; -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Nintendo.Gameboy -{ - public partial class Gameboy : ISoundProvider - { - public bool CanProvideAsync => false; - - public void DiscardSamples() - { - _soundoutbuffcontains = 0; - } - - public void GetSamplesSync(out short[] samples, out int nsamp) - { - samples = _soundoutbuff; - nsamp = _soundoutbuffcontains; - } - - public void SetSyncMode(SyncSoundMode mode) - { - if (mode == SyncSoundMode.Async) - { - throw new NotSupportedException("Async mode is not supported."); - } - } - - public SyncSoundMode SyncMode => SyncSoundMode.Sync; - - public void GetSamplesAsync(short[] samples) - { - throw new InvalidOperationException("Async mode is not supported."); - } - - internal bool Muted => _settings.Muted; - - // sample pairs before resampling - private readonly short[] _soundbuff = new short[(35112 + 2064) * 2]; - - private int _soundoutbuffcontains = 0; - - private readonly short[] _soundoutbuff = new short[2048]; - - private int _latchL = 0; - private int _latchR = 0; - - private BlipBuffer _blipL, _blipR; - private uint _blipAccumulate; - - private void ProcessSound(int nsamp) - { - for (uint i = 0; i < nsamp; i++) - { - int curr = _soundbuff[i * 2]; - - if (curr != _latchL) - { - int diff = _latchL - curr; - _latchL = curr; - _blipL.AddDelta(_blipAccumulate, diff); - } - - curr = _soundbuff[(i * 2) + 1]; - - if (curr != _latchR) - { - int diff = _latchR - curr; - _latchR = curr; - _blipR.AddDelta(_blipAccumulate, diff); - } - - _blipAccumulate++; - } - } - - private void ProcessSoundEnd() - { - _blipL.EndFrame(_blipAccumulate); - _blipR.EndFrame(_blipAccumulate); - _blipAccumulate = 0; - - _soundoutbuffcontains = _blipL.SamplesAvailable(); - if (_soundoutbuffcontains != _blipR.SamplesAvailable()) - { - throw new InvalidOperationException("Audio processing error"); - } - - _blipL.ReadSamplesLeft(_soundoutbuff, _soundoutbuffcontains); - _blipR.ReadSamplesRight(_soundoutbuff, _soundoutbuffcontains); - } - - private void InitSound() - { - _blipL = new BlipBuffer(1024); - _blipL.SetRates(TICKSPERSECOND, 44100); - _blipR = new BlipBuffer(1024); - _blipR.SetRates(TICKSPERSECOND, 44100); - } - - private void DisposeSound() - { - if (_blipL != null) - { - _blipL.Dispose(); - _blipL = null; - } - - if (_blipR != null) - { - _blipR.Dispose(); - _blipR = null; - } - } - } -} +using System; +using BizHawk.Emulation.Common; + +namespace BizHawk.Emulation.Cores.Nintendo.Gameboy +{ + public partial class Gameboy : ISoundProvider + { + public bool CanProvideAsync => false; + + public void DiscardSamples() + { + _soundoutbuffcontains = 0; + } + + public void GetSamplesSync(out short[] samples, out int nsamp) + { + samples = _soundoutbuff; + nsamp = _soundoutbuffcontains; + } + + public void SetSyncMode(SyncSoundMode mode) + { + if (mode == SyncSoundMode.Async) + { + throw new NotSupportedException("Async mode is not supported."); + } + } + + public SyncSoundMode SyncMode => SyncSoundMode.Sync; + + public void GetSamplesAsync(short[] samples) + { + throw new InvalidOperationException("Async mode is not supported."); + } + + internal bool Muted => _settings.Muted; + + // sample pairs before resampling + private readonly short[] _soundbuff = new short[(35112 + 2064) * 2]; + + private int _soundoutbuffcontains = 0; + + private readonly short[] _soundoutbuff = new short[2048]; + + private int _latchL = 0; + private int _latchR = 0; + + private BlipBuffer _blipL, _blipR; + private uint _blipAccumulate; + + private void ProcessSound(int nsamp) + { + for (uint i = 0; i < nsamp; i++) + { + int curr = _soundbuff[i * 2]; + + if (curr != _latchL) + { + int diff = _latchL - curr; + _latchL = curr; + _blipL.AddDelta(_blipAccumulate, diff >> 2); + } + + curr = _soundbuff[(i * 2) + 1]; + + if (curr != _latchR) + { + int diff = _latchR - curr; + _latchR = curr; + _blipR.AddDelta(_blipAccumulate, diff >> 2); + } + + _blipAccumulate++; + } + } + + private void ProcessSoundEnd() + { + _blipL.EndFrame(_blipAccumulate); + _blipR.EndFrame(_blipAccumulate); + _blipAccumulate = 0; + + _soundoutbuffcontains = _blipL.SamplesAvailable(); + if (_soundoutbuffcontains != _blipR.SamplesAvailable()) + { + throw new InvalidOperationException("Audio processing error"); + } + + _blipL.ReadSamplesLeft(_soundoutbuff, _soundoutbuffcontains); + _blipR.ReadSamplesRight(_soundoutbuff, _soundoutbuffcontains); + } + + private void InitSound() + { + _blipL = new BlipBuffer(1024); + _blipL.SetRates(TICKSPERSECOND, 44100); + _blipR = new BlipBuffer(1024); + _blipR.SetRates(TICKSPERSECOND, 44100); + } + + private void DisposeSound() + { + if (_blipL != null) + { + _blipL.Dispose(); + _blipL = null; + } + + if (_blipR != null) + { + _blipR.Dispose(); + _blipR = null; + } + } + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs index bdc3932729..d7e3812de6 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs @@ -2,6 +2,7 @@ using BizHawk.Common.BufferExtensions; using BizHawk.Emulation.Common; +using BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy; namespace BizHawk.Emulation.Cores.Nintendo.Gameboy { @@ -17,7 +18,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy portedUrl: "http://gambatte.sourceforge.net/")] [ServiceNotApplicable(typeof(IDriveLight), typeof(IDriveLight))] public partial class Gameboy : IEmulator, IVideoProvider, ISoundProvider, ISaveRam, IStatable, IInputPollable, ICodeDataLogger, - IBoardInfo, IDebuggable, ISettable + IBoardInfo, IDebuggable, ISettable, + IGameboyCommon { [CoreConstructor("GB", "GBC")] public Gameboy(CoreComm comm, GameInfo game, byte[] file, object settings, object syncSettings, bool deterministic) @@ -50,6 +52,23 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy throw new InvalidOperationException("gambatte_create() returned null???"); } + Console.WriteLine(game.System); + + byte[] BiosRom; + + if (game.System == "GB") + { + BiosRom = new byte[256]; + BiosRom = comm.CoreFileProvider.GetFirmware("GB", "World", false); + } + else + { + BiosRom = new byte[2304]; + BiosRom = comm.CoreFileProvider.GetFirmware("GBC", "World", false); + } + + int bios_length = BiosRom == null ? 0 : BiosRom.Length; + try { _syncSettings = (GambatteSyncSettings)syncSettings ?? new GambatteSyncSettings(); @@ -64,6 +83,25 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy if (_syncSettings.ForceDMG) { flags |= LibGambatte.LoadFlags.FORCE_DMG; + + // we need to change the BIOS to GB bios + if (game.System == "GBC") + { + BiosRom = null; + BiosRom = new byte[256]; + BiosRom = comm.CoreFileProvider.GetFirmware("GB", "World", false); + } + } + + if (_syncSettings.EnableBIOS && BiosRom == null) + { + throw new MissingFirmwareException("Boot Rom not found"); + } + + // to disable BIOS loading into gambatte, just set bios_length to 0 + if (!_syncSettings.EnableBIOS) + { + bios_length = 0; } if (_syncSettings.GBACGB) @@ -76,7 +114,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy flags |= LibGambatte.LoadFlags.MULTICART_COMPAT; } - if (LibGambatte.gambatte_load(GambatteState, file, (uint)file.Length, GetCurrentTime(), flags) != 0) + if (LibGambatte.gambatte_load(GambatteState, file, (uint)file.Length, BiosRom, (uint)bios_length, GetCurrentTime(), flags) != 0) { throw new InvalidOperationException("gambatte_load() returned non-zero (is this not a gb or gbc rom?)"); } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/IGameboyCommon.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/IGameboyCommon.cs new file mode 100644 index 0000000000..fa236b8f47 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/IGameboyCommon.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy +{ + public interface IGameboyCommon + { + bool IsCGBMode(); + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs index 86b7e4fffd..06aaa58fa6 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs @@ -57,7 +57,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy /// ORed combination of LoadFlags. /// 0 on success, negative value on failure. [DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int gambatte_load(IntPtr core, byte[] romdata, uint length, long now, LoadFlags flags); + public static extern int gambatte_load(IntPtr core, byte[] romdata, uint length, byte[] biosdata, uint bioslength, long now, LoadFlags flags); /// /// Emulates until at least 'samples' stereo sound samples are produced in the supplied buffer, diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibPizza.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibPizza.cs new file mode 100644 index 0000000000..e8306aea35 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibPizza.cs @@ -0,0 +1,43 @@ +using BizHawk.Common.BizInvoke; +using BizHawk.Emulation.Cores.Waterbox; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy +{ + public abstract class LibPizza : LibWaterboxCore, ICustomSaveram + { + [Flags] + public enum Buttons : uint + { + A = 0x01, + B = 0x02, + SELECT = 0x04, + START = 0x08, + RIGHT = 0x10, + LEFT = 0x20, + UP = 0x40, + DOWN = 0x80 + } + [StructLayout(LayoutKind.Sequential)] + public new class FrameInfo : LibWaterboxCore.FrameInfo + { + public long Time; + public Buttons Keys; + } + [BizImport(CC)] + public abstract bool Init(byte[] rom, int romlen, bool sgb, byte[] spc, int spclen); + [BizImport(CC)] + public abstract bool IsCGB(); + [BizImport(CC)] + public abstract int GetSaveramSize(); + [BizImport(CC)] + public abstract void PutSaveram(byte[] data, int size); + [BizImport(CC)] + public abstract void GetSaveram(byte[] data, int size); + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Pizza.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Pizza.cs new file mode 100644 index 0000000000..836923fea3 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Pizza.cs @@ -0,0 +1,143 @@ +using BizHawk.Common; +using BizHawk.Common.BizInvoke; +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.Nintendo.Gameboy +{ + [CoreAttributes("Pizza Boy", "Davide Berra", true, false, "c7bc6ee376028b3766de8d7a02e60ab794841f45", + "https://github.com/davideberra/emu-pizza/", false)] + public class Pizza : WaterboxCore, IGameboyCommon + { + private LibPizza _pizza; + private readonly bool _sgb; + + [CoreConstructor("GB")] + public Pizza(byte[] rom, CoreComm comm) + :base(comm, new Configuration + { + DefaultWidth = 160, + DefaultHeight = 144, + MaxWidth = 256, + MaxHeight = 224, + MaxSamples = 1024, + SystemId = "SGB", + DefaultFpsNumerator = TICKSPERSECOND, + DefaultFpsDenominator = TICKSPERFRAME + }) + { + _pizza = PreInit(new PeRunnerOptions + { + Filename = "pizza.wbx", + SbrkHeapSizeKB = 128, + InvisibleHeapSizeKB = 16, + SealedHeapSizeKB = 5 * 1024, + PlainHeapSizeKB = 16, + MmapHeapSizeKB = 0 + }); + + var spc = comm.CoreFileProvider.GetFirmware("SGB", "SPC", true); + _sgb = true; + if (!_pizza.Init(rom, rom.Length, _sgb, spc, spc.Length)) + { + throw new InvalidOperationException("Core rejected the rom!"); + } + + PostInit(); + + if (_sgb) + { + VsyncNumerator = TICKSPERSECOND_SGB; + BufferWidth = 256; + BufferHeight = 224; + } + InitializeRtc(new DateTime(2010, 1, 1)); // TODO: connect to syncsettings + Console.WriteLine("Pizza Initialized: CGB {0} SGB {1}", IsCGBMode(), IsSGBMode()); + } + + /// + /// the nominal length of one frame + /// + private const int TICKSPERFRAME = 35112; + + /// + /// number of ticks per second (GB, CGB) + /// + private const int TICKSPERSECOND = 2097152; + + /// + /// number of ticks per second (SGB) + /// + private const int TICKSPERSECOND_SGB = 2147727; + + #region Controller + + private static readonly ControllerDefinition _definition; + public override ControllerDefinition ControllerDefinition => _definition; + + static Pizza() + { + _definition = new ControllerDefinition { Name = "Gameboy Controller" }; + for (int i = 0; i < 4; i++) + { + _definition.BoolButtons.AddRange( + new[] { "Up", "Down", "Left", "Right", "A", "B", "Select", "Start" } + .Select(s => $"P{i + 1} {s}")); + } + } + private static LibPizza.Buttons GetButtons(IController c) + { + LibPizza.Buttons b = 0; + for (int i = 4; i > 0; i--) + { + if (c.IsPressed($"P{i} Up")) + b |= LibPizza.Buttons.UP; + if (c.IsPressed($"P{i} Down")) + b |= LibPizza.Buttons.DOWN; + if (c.IsPressed($"P{i} Left")) + b |= LibPizza.Buttons.LEFT; + if (c.IsPressed($"P{i} Right")) + b |= LibPizza.Buttons.RIGHT; + if (c.IsPressed($"P{i} A")) + b |= LibPizza.Buttons.A; + if (c.IsPressed($"P{i} B")) + b |= LibPizza.Buttons.B; + if (c.IsPressed($"P{i} Select")) + b |= LibPizza.Buttons.SELECT; + if (c.IsPressed($"P{i} Start")) + b |= LibPizza.Buttons.START; + if (i != 1) + b = (LibPizza.Buttons)((uint)b << 8); + } + return b; + } + + #endregion + + LibPizza.FrameInfo _tmp; // TODO: clean this up so it's not so hacky + + protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound) + { + return _tmp = new LibPizza.FrameInfo + { + Time = GetRtcTime(false), + Keys = GetButtons(controller) + }; + } + + protected override void FrameAdvancePost() + { + //Console.WriteLine(_tmp.Cycles); + _tmp = null; + } + + public bool IsCGBMode() => _pizza.IsCGB(); + public bool IsSGBMode() => _sgb; + + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs index 130084f1cd..eeb6005e6f 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs @@ -118,18 +118,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 case N64SyncSettings.RspType.Rsp_Hle: rsp = "mupen64plus-rsp-hle.dll"; break; - case N64SyncSettings.RspType.Rsp_Z64_hlevideo: - rsp = "mupen64plus-rsp-z64-hlevideo.dll"; - break; - case N64SyncSettings.RspType.Rsp_cxd4: - rsp = "mupen64plus-rsp-cxd4.dll"; - break; + //case N64SyncSettings.RspType.Rsp_cxd4: + // rsp = "mupen64plus-rsp-cxd4.dll"; + // break; } api.AttachPlugin(mupen64plusApi.m64p_plugin_type.M64PLUGIN_RSP, rsp); InitMemoryDomains(); - if (_syncSettings.Core != N64SyncSettings.CoreType.Dynarec) + //if (_syncSettings.Core != N64SyncSettings.CoreType.Dynarec) { ConnectTracer(); SetBreakpointHandler(); diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64SyncSettings.Jabo.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64SyncSettings.Jabo.cs deleted file mode 100644 index 91f396c31d..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64SyncSettings.Jabo.cs +++ /dev/null @@ -1,184 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel; -using Newtonsoft.Json; - -using BizHawk.Emulation.Common; -using System.Reflection; - -namespace BizHawk.Emulation.Cores.Nintendo.N64 -{ - public partial class N64SyncSettings - { - public class N64JaboPluginSettings : IPluginSettings - { - public N64JaboPluginSettings() - { - UseDefaultHacks = true; - - anisotropic_level = ANISOTROPIC_FILTERING_LEVEL.FourTimes; - antialiasing_level = ANTIALIASING_LEVEL.Off; - brightness = 100; - super2xsal = false; - texture_filter = false; - - adjust_aspect_ratio = false; - legacy_pixel_pipeline = false; - alpha_blending = false; - //wireframe = false; - direct3d_transformation_pipeline = false; - z_compare = false; - copy_framebuffer = false; - - // Per game - resolution_width = -1; - resolution_height = -1; - clear_mode = Direct3DClearMode.Default; - } - - public PluginType GetPluginType() - { - return PluginType.Jabo; - } - - public void FillPerGameHacks(GameInfo game) - { - if (UseDefaultHacks) - { - resolution_width = game.GetInt("Jabo_Resolution_Width", -1); - resolution_height = game.GetInt("Jabo_Resolution_Height", -1); - clear_mode = (Direct3DClearMode)game.GetInt("Jabo_Clear_Frame", (int)Direct3DClearMode.Default); - } - } - - public bool UseDefaultHacks { get; set; } - - [DefaultValue(ANISOTROPIC_FILTERING_LEVEL.FourTimes)] - [DisplayName("Anisotropic filtering")] - [Description("Anisotropic filtering level")] - public ANISOTROPIC_FILTERING_LEVEL anisotropic_level { get; set; } - - [DefaultValue(ANTIALIASING_LEVEL.Off)] - [DisplayName("Full-Scene Antialiasing")] - [Description("Full-Scene Antialiasing level")] - public ANTIALIASING_LEVEL antialiasing_level { get; set; } - - // Range: 100-190 in increments of 3, TODO: would be nice to put this in the metadata - [DefaultValue(100)] - [DisplayName("Brightness")] - [Description("Brightness level, 100%-190%")] - public int brightness { get; set; } - - [DefaultValue(false)] - [DisplayName("Super2xSal textures")] - [Description("Enables Super2xSal textures")] - public bool super2xsal { get; set; } - - [DefaultValue(false)] - [DisplayName("Always use texture filter")] - [Description("Always use texture filter")] - public bool texture_filter { get; set; } - - [DefaultValue(false)] - [DisplayName("Adjust game aspect ratio to match yours")] - [Description("Adjust game aspect ratio to match yours")] - public bool adjust_aspect_ratio { get; set; } - - [DefaultValue(false)] - [DisplayName("Use legacy pixel pipeline")] - [Description("Use legacy pixel pipeline")] - public bool legacy_pixel_pipeline { get; set; } - - [DefaultValue(false)] - [DisplayName("Force alpha blending")] - [Description("Force alpha blending")] - public bool alpha_blending { get; set; } - - // As far as I can tell there is no way to apply this setting without opening the dll config window - //[DefaultValue(false)] - //[DisplayName("Wireframe rendering")] - //[Description("Wireframe rendering")] - //public bool wireframe { get; set; } - - [DefaultValue(false)] - [DisplayName("Use Direct3D trans pipeline")] - [Description("Use Direct3D transformation pipeline")] - public bool direct3d_transformation_pipeline { get; set; } - - [DefaultValue(false)] - [DisplayName("Force Z Compare")] - [Description("Force Z Compare")] - public bool z_compare { get; set; } - - [DefaultValue(false)] - [DisplayName("Copy framebuffer")] - [Description("Copy framebuffer to RDRAM")] - public bool copy_framebuffer { get; set; } - - [DefaultValue(-1)] - [DisplayName("Emulated Width")] - [Description("Emulated Width")] - public int resolution_width { get; set; } - - [DefaultValue(-1)] - [DisplayName("Emulated Height")] - [Description("Emulated Height")] - public int resolution_height { get; set; } - - [DefaultValue(Direct3DClearMode.Default)] - [DisplayName("Direct3D Clear Mode")] - [Description("Direct3D Clear Mode")] - public Direct3DClearMode clear_mode { get; set; } - - public enum ANISOTROPIC_FILTERING_LEVEL - { - [Description("Off")] - Off = 0, - - [Description("2X")] - TwoTimes = 1, - - [Description("4X")] - FourTimes = 2, - - [Description("8X")] - EightTimes = 3, - - [Description("16X")] - SixteenTimes = 4 - } - - public enum ANTIALIASING_LEVEL - { - [Description("Off")] - Off = 0, - - [Description("2X")] - TwoTimes = 1, - - [Description("4X")] - FourTimes = 2, - - [Description("8X")] - EightTimes = 3 - } - - public enum Direct3DClearMode - { - [Description("Default")] - Default = 0, - - [Description("Only Per Frame")] - PerFrame = 1, - - [Description("Always")] - Always = 2 - } - - public N64JaboPluginSettings Clone() - { - return (N64JaboPluginSettings)MemberwiseClone(); - } - } - - } -} \ No newline at end of file diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64SyncSettings.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64SyncSettings.cs index d493e06765..87bf14407a 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64SyncSettings.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64SyncSettings.cs @@ -11,8 +11,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 { public N64SyncSettings() { - VideoPlugin = PluginType.Jabo; - Core = CoreType.Dynarec; + VideoPlugin = PluginType.GLideN64; + Core = CoreType.Interpret; Rsp = RspType.Rsp_Hle; DisableExpansionSlot = true; @@ -27,7 +27,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 RicePlugin = new N64RicePluginSettings(); GlidePlugin = new N64GlidePluginSettings(); Glide64mk2Plugin = new N64Glide64mk2PluginSettings(); - JaboPlugin = new N64JaboPluginSettings(); GLideN64Plugin = new N64GLideN64PluginSettings(); } @@ -42,7 +41,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 public N64RicePluginSettings RicePlugin { get; private set; } public N64GlidePluginSettings GlidePlugin { get; private set; } public N64Glide64mk2PluginSettings Glide64mk2Plugin { get; private set; } - public N64JaboPluginSettings JaboPlugin { get; private set; } public N64GLideN64PluginSettings GLideN64Plugin { get; private set; } public N64SyncSettings Clone() @@ -56,7 +54,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 RicePlugin = RicePlugin.Clone(), GlidePlugin = GlidePlugin.Clone(), Glide64mk2Plugin = Glide64mk2Plugin.Clone(), - JaboPlugin = JaboPlugin.Clone(), GLideN64Plugin = GLideN64Plugin.Clone(), Controllers = System.Array.ConvertAll(Controllers, a => a.Clone()) }; @@ -73,7 +70,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 case PluginType.Glide: ips = GlidePlugin.Clone(); break; case PluginType.GlideMk2: ips = Glide64mk2Plugin.Clone(); break; case PluginType.Rice: ips = RicePlugin.Clone(); break; - case PluginType.Jabo: ips = JaboPlugin.Clone(); break; case PluginType.GLideN64: ips = GLideN64Plugin.Clone(); break; } @@ -90,8 +86,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 [Description("Interpreter")] Interpret = 1, - [Description("DynaRec")] - Dynarec = 2, + //[Description("DynaRec")] + //Dynarec = 2, } public enum RspType @@ -99,11 +95,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 [Description("Hle")] Rsp_Hle = 0, - [Description("Z64 Hle Video")] - Rsp_Z64_hlevideo = 1, - - [Description("cxd4 LLE")] - Rsp_cxd4 = 2 + //[Description("cxd4 LLE")] + //Rsp_cxd4 = 2 } } @@ -118,8 +111,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 [Description("Glide64 mk2")] GlideMk2, - [Description("Jabo")] - Jabo, + //this is left to keep some enums from getting mixed up + [Description("FormerlyJabo")] + FormerlyJabo, [Description("GLideN64")] GLideN64 diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeAPI/mupen64plusCoreApi.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeAPI/mupen64plusCoreApi.cs index f1229951cb..bdda7421fe 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeAPI/mupen64plusCoreApi.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeAPI/mupen64plusCoreApi.cs @@ -659,10 +659,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi { m64pConfigOpenSection("Video-Glide64mk2", ref video_plugin_section); } - else if (video_settings.Plugin == PluginType.Jabo) - { - m64pConfigOpenSection("Video-Jabo", ref video_plugin_section); - } else if (video_settings.Plugin == PluginType.GLideN64) { m64pConfigOpenSection("Video-GLideN64", ref video_plugin_section); diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeAPI/mupen64plusVideoApi.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeAPI/mupen64plusVideoApi.cs index 049cca357e..16ec0a4516 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeAPI/mupen64plusVideoApi.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeAPI/mupen64plusVideoApi.cs @@ -57,9 +57,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi case PluginType.GlideMk2: videoplugin = "mupen64plus-video-glide64mk2.dll"; break; - case PluginType.Jabo: - videoplugin = "mupen64plus-video-jabo.dll"; - break; case PluginType.GLideN64: videoplugin = "mupen64plus-video-GLideN64.dll"; break; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs index 51dedb8f61..563f46f6ea 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs @@ -22,7 +22,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES static QuickNES() { Resolver = new DynamicLibraryImportResolver(LibQuickNES.dllname); - QN = BizInvoker.GetInvoker(Resolver); + QN = BizInvoker.GetInvoker(Resolver, CallingConventionAdapters.Native); } [CoreConstructor("NES")] diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi.cs index 90e941f3d3..be07d5030c 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi.cs @@ -5,51 +5,85 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using BizHawk.Common; +using BizHawk.Emulation.Cores.Waterbox; +using BizHawk.Common.BizInvoke; +using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.Nintendo.SNES { - public unsafe partial class LibsnesApi : IDisposable + public abstract unsafe class CoreImpl { - InstanceDll instanceDll; - string InstanceName; + [BizImport(CallingConvention.Cdecl, Compatibility = true)] + public abstract IntPtr DllInit(); + [BizImport(CallingConvention.Cdecl, Compatibility = true)] + public abstract void Message(LibsnesApi.eMessage msg); + [BizImport(CallingConvention.Cdecl, Compatibility = true)] + public abstract void CopyBuffer(int id, void* ptr, int size); + [BizImport(CallingConvention.Cdecl, Compatibility = true)] + public abstract void SetBuffer(int id, void* ptr, int size); + [BizImport(CallingConvention.Cdecl)] + public abstract void PostLoadState(); + } - [DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)] - public static unsafe extern void* CopyMemory(void* dest, void* src, ulong count); + public unsafe partial class LibsnesApi : IDisposable, IMonitor, IBinaryStateable + { + static LibsnesApi() + { + if (sizeof(CommStruct) != 232) + { + throw new InvalidOperationException("sizeof(comm)"); + } + } - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate IntPtr DllInit(); + private PeRunner _exe; + private CoreImpl _core; + private bool _disposed; + private CommStruct* _comm; + private readonly Dictionary _sharedMemoryBlocks = new Dictionary(); + private bool _sealed = false; - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate void MessageApi(eMessage msg); + public void Enter() + { + _exe.Enter(); + } - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate void BufferApi(int id, void* ptr, int size); - - CommStruct* comm; - MessageApi Message; - BufferApi _copyBuffer; //TODO: consider making private and wrapping - BufferApi _setBuffer; //TODO: consider making private and wrapping + public void Exit() + { + _exe.Exit(); + } public LibsnesApi(string dllPath) { - InstanceName = "libsneshawk_" + Guid.NewGuid().ToString(); - instanceDll = new InstanceDll(dllPath); - var dllinit = (DllInit)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("DllInit"), typeof(DllInit)); - Message = (MessageApi)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("Message"), typeof(MessageApi)); - _copyBuffer = (BufferApi)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("CopyBuffer"), typeof(BufferApi)); - _setBuffer = (BufferApi)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("SetBuffer"), typeof(BufferApi)); - - comm = (CommStruct*)dllinit().ToPointer(); + _exe = new PeRunner(new PeRunnerOptions + { + Filename = "libsnes.wbx", + Path = dllPath, + SbrkHeapSizeKB = 4 * 1024, + InvisibleHeapSizeKB = 8 * 1024, + MmapHeapSizeKB = 32 * 1024, // TODO: see if we can safely make libco stacks smaller + PlainHeapSizeKB = 2 * 1024, // TODO: wasn't there more in here? + SealedHeapSizeKB = 128 * 1024 + }); + using (_exe.EnterExit()) + { + // Marshal checks that function pointers passed to GetDelegateForFunctionPointer are + // _currently_ valid when created, even though they don't need to be valid until + // the delegate is later invoked. so GetInvoker needs to be acquired within a lock. + _core = BizInvoker.GetInvoker(_exe, _exe, CallingConventionAdapters.Waterbox); + _comm = (CommStruct*)_core.DllInit().ToPointer(); + } } public void Dispose() { - instanceDll.Dispose(); - - foreach (var smb in DeallocatedMemoryBlocks.Values) smb.Dispose(); - foreach (var smb in SharedMemoryBlocks.Values) smb.Dispose(); - SharedMemoryBlocks.Clear(); - DeallocatedMemoryBlocks.Clear(); + if (!_disposed) + { + _disposed = true; + _exe.Dispose(); + _exe = null; + _core = null; + _comm = null; + } } /// @@ -57,8 +91,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES /// public void CopyAscii(int id, string str) { - fixed (byte* cp = System.Text.Encoding.ASCII.GetBytes(str+"\0")) - _copyBuffer(id, cp, str.Length + 1); + fixed (byte* cp = System.Text.Encoding.ASCII.GetBytes(str + "\0")) + { + _core.CopyBuffer(id, cp, str.Length + 1); + } } /// @@ -67,7 +103,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES public void CopyBytes(int id, byte[] bytes) { fixed (byte* bp = bytes) - _copyBuffer(id, bp, bytes.Length); + { + _core.CopyBuffer(id, bp, bytes.Length); + } } /// @@ -79,9 +117,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES /// public void SetBytes(int id, byte[] bytes, Action andThen) { + if (_sealed) + throw new InvalidOperationException("Init period is over"); fixed (byte* bp = bytes) { - _setBuffer(id, bp, bytes.Length); + _core.SetBuffer(id, bp, bytes.Length); andThen(); } } @@ -91,9 +131,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES /// public void SetAscii(int id, string str, Action andThen) { - fixed (byte* cp = System.Text.Encoding.ASCII.GetBytes(str+"\0")) + if (_sealed) + throw new InvalidOperationException("Init period is over"); + fixed (byte* cp = System.Text.Encoding.ASCII.GetBytes(str + "\0")) { - _setBuffer(id, cp, str.Length + 1); + _core.SetBuffer(id, cp, str.Length + 1); andThen(); } } @@ -109,11 +151,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES }; public enum eTRACE : uint - { - CPU = 0, - SMP = 1, + { + CPU = 0, + SMP = 1, GB = 2 - } + } public enum eCDLog_Flags { @@ -124,9 +166,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES BRR = 0x80, }; - Dictionary SharedMemoryBlocks = new Dictionary(); - Dictionary DeallocatedMemoryBlocks = new Dictionary(); - snes_video_refresh_t video_refresh; snes_input_poll_t input_poll; snes_input_state_t input_state; @@ -152,15 +191,22 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES public delegate void snes_trace_t(uint which, string msg); + [StructLayout(LayoutKind.Explicit)] public struct CPURegs { + [FieldOffset(0)] public uint pc; + [FieldOffset(4)] public ushort a, x, y, z, s, d, vector; //7x + [FieldOffset(18)] public byte p, nothing; + [FieldOffset(20)] public uint aa, rd; + [FieldOffset(28)] public byte sp, dp, db, mdr; } + [StructLayout(LayoutKind.Sequential)] public struct LayerEnables { byte _BG1_Prio0, _BG1_Prio1; @@ -177,76 +223,160 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES public bool BG3_Prio1 { get { return _BG3_Prio1 != 0; } set { _BG3_Prio1 = (byte)(value ? 1 : 0); } } public bool BG4_Prio0 { get { return _BG4_Prio0 != 0; } set { _BG4_Prio0 = (byte)(value ? 1 : 0); } } public bool BG4_Prio1 { get { return _BG4_Prio1 != 0; } set { _BG4_Prio1 = (byte)(value ? 1 : 0); } } - + public bool Obj_Prio0 { get { return _Obj_Prio0 != 0; } set { _Obj_Prio0 = (byte)(value ? 1 : 0); } } public bool Obj_Prio1 { get { return _Obj_Prio1 != 0; } set { _Obj_Prio1 = (byte)(value ? 1 : 0); } } public bool Obj_Prio2 { get { return _Obj_Prio2 != 0; } set { _Obj_Prio2 = (byte)(value ? 1 : 0); } } public bool Obj_Prio3 { get { return _Obj_Prio3 != 0; } set { _Obj_Prio3 = (byte)(value ? 1 : 0); } } } + [StructLayout(LayoutKind.Explicit)] struct CommStruct { + [FieldOffset(0)] //the cmd being executed public eMessage cmd; - + [FieldOffset(4)] //the status of the core public eStatus status; - + [FieldOffset(8)] //the SIG or BRK that the core is halted in public eMessage reason; //flexible in/out parameters //these are all "overloaded" a little so it isn't clear what's used for what in for any particular message.. //but I think it will beat having to have some kind of extremely verbose custom layouts for every message + [FieldOffset(16)] public sbyte* str; + [FieldOffset(24)] public void* ptr; - public uint id, addr, value, size; - public int port, device, index, slot; - public int width, height; + [FieldOffset(32)] + public uint id; + [FieldOffset(36)] + public uint addr; + [FieldOffset(40)] + public uint value; + [FieldOffset(44)] + public uint size; + [FieldOffset(48)] + public int port; + [FieldOffset(52)] + public int device; + [FieldOffset(56)] + public int index; + [FieldOffset(60)] + public int slot; + [FieldOffset(64)] + public int width; + [FieldOffset(68)] + public int height; + [FieldOffset(72)] public int scanline; + [FieldOffset(76)] public fixed int inports[2]; + [FieldOffset(88)] //this should always be used in pairs - public fixed uint buf[3]; //ACTUALLY A POINTER but can't marshal it :( + public fixed long buf[3]; //ACTUALLY A POINTER but can't marshal it :( + [FieldOffset(112)] public fixed int buf_size[3]; + [FieldOffset(128)] //bleck. this is a long so that it can be a 32/64bit pointer public fixed long cdl_ptr[4]; + [FieldOffset(160)] public fixed int cdl_size[4]; + [FieldOffset(176)] public CPURegs cpuregs; + [FieldOffset(208)] public LayerEnables layerEnables; + [FieldOffset(220)] //static configuration-type information which can be grabbed off the core at any time without even needing a QUERY command public SNES_REGION region; + [FieldOffset(224)] public SNES_MAPPER mapper; + [FieldOffset(228)] + public int unused; + //utilities //TODO: make internal, wrap on the API instead of the comm public unsafe string GetAscii() { return _getAscii(str); } public bool GetBool() { return value != 0; } - private unsafe string _getAscii(sbyte* ptr) { + private unsafe string _getAscii(sbyte* ptr) + { int len = 0; sbyte* junko = (sbyte*)ptr; - while(junko[len] != 0) len++; + while (junko[len] != 0) len++; return new string((sbyte*)str, 0, len, System.Text.Encoding.ASCII); } } - public SNES_REGION Region { get { return comm->region; } } - public SNES_MAPPER Mapper { get { return comm->mapper; } } + public SNES_REGION Region + { + get + { + using (_exe.EnterExit()) + { + return _comm->region; + } + } + } + public SNES_MAPPER Mapper + { + get + { + using (_exe.EnterExit()) + { + return _comm->mapper; + } + } + } + public void SetLayerEnables(ref LayerEnables enables) { - comm->layerEnables = enables; - QUERY_set_layer_enable(); + using (_exe.EnterExit()) + { + _comm->layerEnables = enables; + QUERY_set_layer_enable(); + } } public void SetInputPortBeforeInit(int port, SNES_INPUT_PORT type) { - comm->inports[port] = (int)type; + using (_exe.EnterExit()) + { + _comm->inports[port] = (int)type; + } + } + + public void Seal() + { + /* Cothreads can very easily acquire "pointer poison"; because their stack and even registers + * are part of state, any poisoned pointer that's used even temporarily might be persisted longer + * than needed. Most of the libsnes core cothreads handle internal matters only and aren't very + * vulnerable to pointer poison, but the main boss cothread is used heavily during init, when + * many syscalls happen and many kinds of poison can end up on the stack. so here, we call + * _core.DllInit() again, which recreates that cothread, zeroing out all of the memory first, + * as well as zeroing out the comm struct. */ + _core.DllInit(); + _exe.Seal(); + _sealed = true; + } + + public void SaveStateBinary(BinaryWriter writer) + { + _exe.SaveStateBinary(writer); + } + + public void LoadStateBinary(BinaryReader reader) + { + _exe.LoadStateBinary(reader); + _core.PostLoadState(); } } - } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_BRK.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_BRK.cs index 6ac0ca9ae6..ea281c0586 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_BRK.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_BRK.cs @@ -8,42 +8,38 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES { bool Handle_BRK(eMessage msg) { - switch (msg) + using (_exe.EnterExit()) { - default: - return false; + switch (msg) + { + default: + return false; - case eMessage.eMessage_BRK_hook_exec: - { - ExecHook(comm->addr); + case eMessage.eMessage_BRK_hook_exec: + ExecHook(_comm->addr); break; - } - case eMessage.eMessage_BRK_hook_read: - { - ReadHook(comm->addr); + case eMessage.eMessage_BRK_hook_read: + ReadHook(_comm->addr); break; - } - case eMessage.eMessage_BRK_hook_write: - { - WriteHook(comm->addr, (byte)comm->value); + case eMessage.eMessage_BRK_hook_write: + WriteHook(_comm->addr, (byte)_comm->value); break; - } - //not supported yet - case eMessage.eMessage_BRK_hook_nmi: - break; - case eMessage.eMessage_BRK_hook_irq: - break; + //not supported yet + case eMessage.eMessage_BRK_hook_nmi: + break; + case eMessage.eMessage_BRK_hook_irq: + break; - case eMessage.eMessage_BRK_scanlineStart: - if (scanlineStart != null) - scanlineStart(comm->scanline); - break; + case eMessage.eMessage_BRK_scanlineStart: + scanlineStart?.Invoke(_comm->scanline); + break; - } //switch(msg) + } //switch(msg) - Message(eMessage.eMessage_Resume); - return true; + _core.Message(eMessage.eMessage_Resume); + return true; + } } } -} \ No newline at end of file +} diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_CMD.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_CMD.cs index 076a4752c5..442f25f367 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_CMD.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_CMD.cs @@ -6,98 +6,75 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES { unsafe partial class LibsnesApi { - public bool CMD_serialize(IntPtr data, int size) - { - comm->buf[0] = (uint)data.ToInt32(); - comm->buf_size[0] = size; - Message(eMessage.eMessage_CMD_serialize); - WaitForCMD(); - bool ret = comm->GetBool(); - return ret; - } - void WaitForCMD() { - for (; ; ) + using (_exe.EnterExit()) { - if (comm->status == eStatus.eStatus_Idle) - break; - if (Handle_SIG(comm->reason)) continue; - if (Handle_BRK(comm->reason)) continue; + for (;;) + { + if (_comm->status == eStatus.eStatus_Idle) + break; + if (Handle_SIG(_comm->reason)) continue; + if (Handle_BRK(_comm->reason)) continue; + } } } - public bool CMD_unserialize(IntPtr data, int size) - { - comm->buf[0] = (uint)data.ToInt32(); - comm->buf_size[0] = size; - Message(eMessage.eMessage_CMD_unserialize); - WaitForCMD(); - bool ret = comm->GetBool(); - return ret; - } - public void CMD_init() { - Message(eMessage.eMessage_CMD_init); + _core.Message(eMessage.eMessage_CMD_init); WaitForCMD(); } public void CMD_power() { - Message(eMessage.eMessage_CMD_power); + _core.Message(eMessage.eMessage_CMD_power); WaitForCMD(); } public void CMD_reset() { - Message(eMessage.eMessage_CMD_reset); + _core.Message(eMessage.eMessage_CMD_reset); WaitForCMD(); } public void CMD_run() { - Message(eMessage.eMessage_CMD_run); + _core.Message(eMessage.eMessage_CMD_run); WaitForCMD(); } public bool CMD_load_cartridge_super_game_boy(string rom_xml, byte[] rom_data, uint rom_size, byte[] dmg_data) { - SetAscii(0, rom_xml ?? "", () => - SetBytes(1, rom_data, () => - SetBytes(2, dmg_data, () => - { - Message(eMessage.eMessage_CMD_load_cartridge_sgb); - WaitForCMD(); - }) - ) - ); - return comm->GetBool(); + using (_exe.EnterExit()) + { + SetAscii(0, rom_xml ?? "", () => + SetBytes(1, rom_data, () => + SetBytes(2, dmg_data, () => + { + _core.Message(eMessage.eMessage_CMD_load_cartridge_sgb); + WaitForCMD(); + }) + ) + ); + return _comm->GetBool(); + } } public bool CMD_load_cartridge_normal(byte[] rom_xml, byte[] rom_data) { - //why don't we need this for the other loads? I dont know, our XML handling is really confusing - string xml = rom_xml == null ? null : System.Text.Encoding.ASCII.GetString(rom_xml); + using (_exe.EnterExit()) + { + //why don't we need this for the other loads? I dont know, our XML handling is really confusing + string xml = rom_xml == null ? null : System.Text.Encoding.ASCII.GetString(rom_xml); - SetAscii(0, xml ?? "", () => - SetBytes(1, rom_data, () => - { - Message(eMessage.eMessage_CMD_load_cartridge_normal); - WaitForCMD(); - }) - ); - return comm->GetBool(); + SetAscii(0, xml ?? "", () => + SetBytes(1, rom_data, () => + { + _core.Message(eMessage.eMessage_CMD_load_cartridge_normal); + WaitForCMD(); + }) + ); + return _comm->GetBool(); + } } - - public void CMD_term() - { - Message(eMessage.eMessage_CMD_term); - WaitForCMD(); - } - public void CMD_unload_cartridge() - { - Message(eMessage.eMessage_CMD_unload_cartridge); - WaitForCMD(); - } - } } \ No newline at end of file diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_QUERY.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_QUERY.cs index 2917493a1c..62c963911e 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_QUERY.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_QUERY.cs @@ -10,169 +10,197 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES { public int QUERY_get_memory_size(SNES_MEMORY id) { - comm->value = (uint)id; - Message(eMessage.eMessage_QUERY_get_memory_size); - return (int)comm->value; + using (_exe.EnterExit()) + { + _comm->value = (uint)id; + _core.Message(eMessage.eMessage_QUERY_get_memory_size); + return (int)_comm->value; + } } string QUERY_MemoryNameForId(SNES_MEMORY id) { - comm->id = (uint)id; - Message(eMessage.eMessage_QUERY_GetMemoryIdName); - return comm->GetAscii(); + using (_exe.EnterExit()) + { + _comm->id = (uint)id; + _core.Message(eMessage.eMessage_QUERY_GetMemoryIdName); + return _comm->GetAscii(); + } } public byte* QUERY_get_memory_data(SNES_MEMORY id) { string name = QUERY_MemoryNameForId(id); - if (!SharedMemoryBlocks.ContainsKey(name)) return null; - var smb = SharedMemoryBlocks[name]; - return (byte*)smb.Ptr; + IntPtr ret; + _sharedMemoryBlocks.TryGetValue(name, out ret); + return (byte*)ret; } public byte QUERY_peek(SNES_MEMORY id, uint addr) { - comm->id = (uint)id; - comm->addr = addr; - Message(eMessage.eMessage_QUERY_peek); - return (byte)comm->value; + using (_exe.EnterExit()) + { + _comm->id = (uint)id; + _comm->addr = addr; + _core.Message(eMessage.eMessage_QUERY_peek); + return (byte)_comm->value; + } } public void QUERY_poke(SNES_MEMORY id, uint addr, byte val) { - comm->id = (uint)id; - comm->addr = addr; - comm->value = (byte)val; - Message(eMessage.eMessage_QUERY_poke); - } - - public int QUERY_serialize_size() - { - for (; ; ) + using (_exe.EnterExit()) { - Message(eMessage.eMessage_QUERY_serialize_size); - int ret = (int)comm->size; - if (ret > 100) - { - return ret; - } - else Console.WriteLine("WHY????????"); + _comm->id = (uint)id; + _comm->addr = addr; + _comm->value = (byte)val; + _core.Message(eMessage.eMessage_QUERY_poke); } } - - public void QUERY_set_color_lut(IntPtr colors) { - comm->ptr = colors.ToPointer(); - Message(eMessage.eMessage_QUERY_set_color_lut); + using (_exe.EnterExit()) + { + _comm->ptr = colors.ToPointer(); + _core.Message(eMessage.eMessage_QUERY_set_color_lut); + } } public void QUERY_set_state_hook_exec(bool state) { - comm->value = state ? 1u : 0u; - Message(eMessage.eMessage_QUERY_state_hook_exec); + using (_exe.EnterExit()) + { + _comm->value = state ? 1u : 0u; + _core.Message(eMessage.eMessage_QUERY_state_hook_exec); + } } public void QUERY_set_state_hook_read(bool state) { - comm->value = state ? 1u : 0u; - Message(eMessage.eMessage_QUERY_state_hook_read); + using (_exe.EnterExit()) + { + _comm->value = state ? 1u : 0u; + _core.Message(eMessage.eMessage_QUERY_state_hook_read); + } } public void QUERY_set_state_hook_write(bool state) { - comm->value = state ? 1u : 0u; - Message(eMessage.eMessage_QUERY_state_hook_write); + using (_exe.EnterExit()) + { + _comm->value = state ? 1u : 0u; + _core.Message(eMessage.eMessage_QUERY_state_hook_write); + } } public void QUERY_set_trace_callback(int mask, snes_trace_t callback) { - this.traceCallback = callback; - comm->value = (uint)mask; - Message(eMessage.eMessage_QUERY_enable_trace); + using (_exe.EnterExit()) + { + this.traceCallback = callback; + _comm->value = (uint)mask; + _core.Message(eMessage.eMessage_QUERY_enable_trace); + } } public void QUERY_set_scanlineStart(snes_scanlineStart_t scanlineStart) { - this.scanlineStart = scanlineStart; - comm->value = (scanlineStart != null) ? 1u : 0u; - Message(eMessage.eMessage_QUERY_enable_scanline); + using (_exe.EnterExit()) + { + this.scanlineStart = scanlineStart; + _comm->value = (scanlineStart != null) ? 1u : 0u; + _core.Message(eMessage.eMessage_QUERY_enable_scanline); + } } public void QUERY_set_audio_sample(snes_audio_sample_t audio_sample) { - this.audio_sample = audio_sample; - comm->value = (audio_sample!=null) ? 1u : 0u; - Message(eMessage.eMessage_QUERY_enable_audio); + using (_exe.EnterExit()) + { + this.audio_sample = audio_sample; + _comm->value = (audio_sample != null) ? 1u : 0u; + _core.Message(eMessage.eMessage_QUERY_enable_audio); + } } public void QUERY_set_layer_enable() { - Message(eMessage.eMessage_QUERY_set_layer_enable); + _core.Message(eMessage.eMessage_QUERY_set_layer_enable); } public void QUERY_set_backdropColor(int backdropColor) { - comm->value = (uint)backdropColor; - Message(eMessage.eMessage_QUERY_set_backdropColor); + using (_exe.EnterExit()) + { + _comm->value = (uint)backdropColor; + _core.Message(eMessage.eMessage_QUERY_set_backdropColor); + } } - + public int QUERY_peek_logical_register(SNES_REG reg) { - comm->id = (uint)reg; - Message(eMessage.eMessage_QUERY_peek_logical_register); - return (int)comm->value; + using (_exe.EnterExit()) + { + _comm->id = (uint)reg; + _core.Message(eMessage.eMessage_QUERY_peek_logical_register); + return (int)_comm->value; + } } public unsafe void QUERY_peek_cpu_regs(out CPURegs ret) { - Message(eMessage.eMessage_QUERY_peek_cpu_regs); - ret = comm->cpuregs; + using (_exe.EnterExit()) + { + _core.Message(eMessage.eMessage_QUERY_peek_cpu_regs); + ret = _comm->cpuregs; + } } public void QUERY_set_cdl(ICodeDataLog cdl) { - for (int i = 0; i < 8; i++) + using (_exe.EnterExit()) { - comm->cdl_ptr[i] = 0; - comm->cdl_size[i] = 0; - } - - if (cdl != null) - { - comm->cdl_ptr[0] = cdl.GetPin("CARTROM").ToInt64(); - comm->cdl_size[0] = cdl["CARTROM"].Length; - if (cdl.Has("CARTRAM")) + for (int i = 0; i < 8; i++) { - comm->cdl_ptr[1] = cdl.GetPin("CARTRAM").ToInt64(); - comm->cdl_size[1] = cdl["CARTRAM"].Length; + _comm->cdl_ptr[i] = 0; + _comm->cdl_size[i] = 0; } - comm->cdl_ptr[2] = cdl.GetPin("WRAM").ToInt64(); - comm->cdl_size[2] = cdl["WRAM"].Length; - - comm->cdl_ptr[3] = cdl.GetPin("APURAM").ToInt64(); - comm->cdl_size[3] = cdl["APURAM"].Length; - - if (cdl.Has("SGB_CARTROM")) + if (cdl != null) { - comm->cdl_ptr[4] = cdl.GetPin("SGB_CARTROM").ToInt64(); - comm->cdl_size[4] = cdl["SGB_CARTROM"].Length; - - if (cdl.Has("SGB_CARTRAM")) + _comm->cdl_ptr[0] = cdl.GetPin("CARTROM").ToInt64(); + _comm->cdl_size[0] = cdl["CARTROM"].Length; + if (cdl.Has("CARTRAM")) { - comm->cdl_ptr[5] = cdl.GetPin("SGB_CARTRAM").ToInt64(); - comm->cdl_size[5] = cdl["SGB_CARTRAM"].Length; + _comm->cdl_ptr[1] = cdl.GetPin("CARTRAM").ToInt64(); + _comm->cdl_size[1] = cdl["CARTRAM"].Length; } - comm->cdl_ptr[6] = cdl.GetPin("SGB_WRAM").ToInt64(); - comm->cdl_size[6] = cdl["SGB_WRAM"].Length; + _comm->cdl_ptr[2] = cdl.GetPin("WRAM").ToInt64(); + _comm->cdl_size[2] = cdl["WRAM"].Length; - comm->cdl_ptr[7] = cdl.GetPin("SGB_HRAM").ToInt64(); - comm->cdl_size[7] = cdl["SGB_HRAM"].Length; + _comm->cdl_ptr[3] = cdl.GetPin("APURAM").ToInt64(); + _comm->cdl_size[3] = cdl["APURAM"].Length; + + if (cdl.Has("SGB_CARTROM")) + { + _comm->cdl_ptr[4] = cdl.GetPin("SGB_CARTROM").ToInt64(); + _comm->cdl_size[4] = cdl["SGB_CARTROM"].Length; + + if (cdl.Has("SGB_CARTRAM")) + { + _comm->cdl_ptr[5] = cdl.GetPin("SGB_CARTRAM").ToInt64(); + _comm->cdl_size[5] = cdl["SGB_CARTRAM"].Length; + } + + _comm->cdl_ptr[6] = cdl.GetPin("SGB_WRAM").ToInt64(); + _comm->cdl_size[6] = cdl["SGB_WRAM"].Length; + + _comm->cdl_ptr[7] = cdl.GetPin("SGB_HRAM").ToInt64(); + _comm->cdl_size[7] = cdl["SGB_HRAM"].Length; + } } - } - Message(eMessage.eMessage_QUERY_set_cdl); + _core.Message(eMessage.eMessage_QUERY_set_cdl); + } } - } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_SIG.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_SIG.cs index 0110f65951..da1d74c111 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_SIG.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi_SIG.cs @@ -8,127 +8,89 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES { bool Handle_SIG(eMessage msg) { - switch (msg) + using (_exe.EnterExit()) { - default: - return false; + switch (msg) + { + default: + return false; - case eMessage.eMessage_SIG_video_refresh: - { - int width = comm->width; - int height = comm->height; - if (video_refresh != null) + case eMessage.eMessage_SIG_video_refresh: { - video_refresh((int*)comm->ptr, width, height); + int width = _comm->width; + int height = _comm->height; + video_refresh?.Invoke((int*)_comm->ptr, width, height); + break; } + case eMessage.eMessage_SIG_input_poll: break; - } - case eMessage.eMessage_SIG_input_poll: - break; - case eMessage.eMessage_SIG_input_state: - { - int port = comm->port; - int device = comm->device; - int index = comm->index; - int id = (int)comm->id; - if (input_state != null) - comm->value = (uint)input_state(port, device, index, id); - break; - } - case eMessage.eMessage_SIG_input_notify: - { - if (input_notify != null) - input_notify(comm->index); - break; - } - case eMessage.eMessage_SIG_audio_flush: - { - uint nsamples = comm->size; - - if (audio_sample != null) + case eMessage.eMessage_SIG_input_state: { - ushort* audiobuffer = ((ushort*)comm->ptr); - for (uint i = 0; i < nsamples; ) + int port = _comm->port; + int device = _comm->device; + int index = _comm->index; + int id = (int)_comm->id; + if (input_state != null) + _comm->value = (uint)input_state(port, device, index, id); + break; + } + case eMessage.eMessage_SIG_input_notify: + { + input_notify?.Invoke(_comm->index); + break; + } + case eMessage.eMessage_SIG_audio_flush: + { + uint nsamples = _comm->size; + + if (audio_sample != null) { - ushort left = audiobuffer[i++]; - ushort right = audiobuffer[i++]; - audio_sample(left, right); + ushort* audiobuffer = ((ushort*)_comm->ptr); + for (uint i = 0; i < nsamples;) + { + ushort left = audiobuffer[i++]; + ushort right = audiobuffer[i++]; + audio_sample(left, right); + } } + + break; } - - break; - } - case eMessage.eMessage_SIG_path_request: - { - int slot = comm->slot; - string hint = comm->GetAscii(); - string ret = hint; - if (pathRequest != null) - hint = pathRequest(slot, hint); - CopyAscii(0, hint); - break; - } - case eMessage.eMessage_SIG_trace_callback: - { - if (traceCallback != null) - traceCallback(comm->value, comm->GetAscii()); - break; - } - case eMessage.eMessage_SIG_allocSharedMemory: - { - var name = comm->GetAscii(); - var size = comm->size; - - if (SharedMemoryBlocks.ContainsKey(name)) + case eMessage.eMessage_SIG_path_request: { - throw new InvalidOperationException("Re-defined a shared memory block. Check bsnes init/shutdown code. Block name: " + name); + int slot = _comm->slot; + string hint = _comm->GetAscii(); + string ret = hint; + if (pathRequest != null) + hint = pathRequest(slot, hint); + CopyAscii(0, hint); + break; } - - //try reusing existing block; dispose it if it exists and if the size doesnt match - SharedMemoryBlock smb = null; - if (DeallocatedMemoryBlocks.ContainsKey(name)) + case eMessage.eMessage_SIG_trace_callback: { - smb = DeallocatedMemoryBlocks[name]; - DeallocatedMemoryBlocks.Remove(name); - if (smb.Size != size) - { - smb.Dispose(); - smb = null; - } + traceCallback?.Invoke(_comm->value, _comm->GetAscii()); + break; } - - //allocate a new block if we have to - if (smb == null) + case eMessage.eMessage_SIG_allocSharedMemory: { - smb = new SharedMemoryBlock(); - smb.Name = name; - smb.Size = (int)size; - smb.BlockName = InstanceName + smb.Name; - smb.Allocate(); - } + // NB: shared memory blocks are allocated on the unmanaged side + var name = _comm->GetAscii(); + var size = _comm->size; + var ptr = _comm->ptr; - comm->ptr = smb.Ptr; - SharedMemoryBlocks[smb.Name] = smb; - CopyAscii(0, smb.BlockName); - break; - } - case eMessage.eMessage_SIG_freeSharedMemory: - { - foreach (var block in SharedMemoryBlocks.Values) - { - if (block.Ptr == comm->ptr) - { - DeallocatedMemoryBlocks[block.Name] = block; - SharedMemoryBlocks.Remove(block.Name); - break; - } - } - break; - } - } //switch(msg) + if (_sharedMemoryBlocks.ContainsKey(name)) + throw new InvalidOperationException("Re-defined a shared memory block. Check bsnes init/shutdown code. Block name: " + name); - Message(eMessage.eMessage_Resume); - return true; + _sharedMemoryBlocks.Add(name, (IntPtr)ptr); + break; + } + case eMessage.eMessage_SIG_freeSharedMemory: + throw new InvalidOperationException("Unexpected call: SIG_freeSharedMemory"); + } //switch(msg) + + _core.Message(eMessage.eMessage_Resume); + return true; + } } } -} \ No newline at end of file +} diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IEmulator.cs index 9a767cee40..a245fbdbbf 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IEmulator.cs @@ -22,7 +22,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES IsLagFrame = true; - if (!_nocallbacks && _tracer.Enabled) + if (_tracer.Enabled) { //Api.QUERY_set_trace_callback(1<<(int)LibsnesApi.eTRACE.SMP, _tracecb); //TEST -- it works but theres no way to control it from the frontend now @@ -36,21 +36,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES Api.QUERY_set_trace_callback(0,null); } - // for deterministic emulation, save the state we're going to use before frame advance - // don't do this during nocallbacks though, since it's already been done - if (!_nocallbacks && DeterministicEmulation) - { - var ms = new MemoryStream(); - var bw = new BinaryWriter(ms); - bw.Write(CoreSaveState()); - bw.Write(false); // not framezero - var ssc = new SaveController(); - ssc.CopyFrom(controller); - ssc.Serialize(bw); - bw.Close(); - _savestatebuff = ms.ToArray(); - } - // speedup when sound rendering is not needed Api.QUERY_set_audio_sample(rendersound ? _soundcb : null); @@ -104,14 +89,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES } public string SystemId { get; } - - // adelikat: Nasty hack to force new business logic. Compatibility (and Accuracy when fully supported) will ALWAYS be in deterministic mode, - // a consequence is a permanent performance hit to the compatibility core - // Perormance will NEVER be in deterministic mode (and the client side logic will prohibit movie recording on it) - // feos: Nasty hack to a nasty hack. Allow user disable it with a strong warning. - public bool DeterministicEmulation => - _settings.ForceDeterminism - && (CurrentProfile == "Compatibility" || CurrentProfile == "Accuracy"); + public bool DeterministicEmulation => true; public void ResetCounters() { @@ -129,15 +107,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES return; } - _disposed = true; - - Api.CMD_unload_cartridge(); - Api.CMD_term(); - - _resampler.Dispose(); Api.Dispose(); + _resampler.Dispose(); - _currCdl?.Unpin(); + _disposed = true; } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IMemoryDomains.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IMemoryDomains.cs index b03c27c1c0..ebb2853714 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IMemoryDomains.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IMemoryDomains.cs @@ -84,8 +84,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES private unsafe void MakeMemoryDomain(string name, LibsnesApi.SNES_MEMORY id, MemoryDomain.Endian endian, int byteSize = 1) { int size = Api.QUERY_get_memory_size(id); - int mask = size - 1; - bool pow2 = Util.IsPowerOfTwo(size); // if this type of memory isnt available, dont make the memory domain (most commonly save ram) if (size == 0) @@ -95,46 +93,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES byte* blockptr = Api.QUERY_get_memory_data(id); - MemoryDomain md; - - if (id == LibsnesApi.SNES_MEMORY.OAM) - { - // OAM is actually two differently sized banks of memory which arent truly considered adjacent. - // maybe a better way to visualize it is with an empty bus and adjacent banks - // so, we just throw away everything above its size of 544 bytes - if (size != 544) - { - throw new InvalidOperationException("oam size isnt 544 bytes.. wtf?"); - } - - md = new MemoryDomainDelegate( - name, - size, - endian, - addr => addr < 544 ? blockptr[addr] : (byte)0x00, - (addr, value) => { if (addr < 544) { blockptr[addr] = value; } }, - byteSize); - } - else if (pow2) - { - md = new MemoryDomainDelegate( - name, - size, - endian, - addr => blockptr[addr & mask], - (addr, value) => blockptr[addr & mask] = value, - byteSize); - } - else - { - md = new MemoryDomainDelegate( - name, - size, - endian, - addr => blockptr[addr % size], - (addr, value) => blockptr[addr % size] = value, - byteSize); - } + var md = new MemoryDomainIntPtrMonitor(name, MemoryDomain.Endian.Little, (IntPtr)blockptr, size, + id != LibsnesApi.SNES_MEMORY.CARTRIDGE_ROM, // hack: for just this one memory area, it will be readonly + byteSize, Api); _memoryDomainList.Add(md); } @@ -152,19 +113,25 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES var md = new MemoryDomainDelegate("System Bus", 0x1000000, MemoryDomain.Endian.Little, addr => { - var a = FakeBusMap((int)addr); - if (a.HasValue) + using (Api.EnterExit()) { - return blockptr[a.Value]; - } + var a = FakeBusMap((int)addr); + if (a.HasValue) + { + return blockptr[a.Value]; + } - return FakeBusRead((int)addr); + return FakeBusRead((int)addr); + } }, (addr, val) => { - var a = FakeBusMap((int)addr); - if (a.HasValue) - blockptr[a.Value] = val; + using (Api.EnterExit()) + { + var a = FakeBusMap((int)addr); + if (a.HasValue) + blockptr[a.Value] = val; + } }, wordSize: 2); _memoryDomainList.Add(md); } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.ISaveRam.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.ISaveRam.cs index cb1ffdfb68..3f89c642f0 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.ISaveRam.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.ISaveRam.cs @@ -2,6 +2,7 @@ using System.Runtime.InteropServices; using BizHawk.Emulation.Common; +using BizHawk.Common; namespace BizHawk.Emulation.Cores.Nintendo.SNES { @@ -13,45 +14,51 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES public byte[] CloneSaveRam() { - byte* buf = Api.QUERY_get_memory_data(LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM); - var size = Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM); - - if (buf == null && Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.SGB_CARTRAM)>0) + using (Api.EnterExit()) { - buf = Api.QUERY_get_memory_data(LibsnesApi.SNES_MEMORY.SGB_CARTRAM); - size = Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.SGB_CARTRAM); - } - if (buf==null) - { - return null; - } + byte* buf = Api.QUERY_get_memory_data(LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM); + var size = Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM); + if (buf == null && Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.SGB_CARTRAM) > 0) + { + buf = Api.QUERY_get_memory_data(LibsnesApi.SNES_MEMORY.SGB_CARTRAM); + size = Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.SGB_CARTRAM); + } - var ret = new byte[size]; - Marshal.Copy((IntPtr)buf, ret, 0, size); - return ret; + if (buf == null) + { + return null; + } + + var ret = new byte[size]; + Marshal.Copy((IntPtr)buf, ret, 0, size); + return ret; + } } public void StoreSaveRam(byte[] data) { - byte* buf = Api.QUERY_get_memory_data(LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM); - var size = Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM); - if (buf == null) + using (Api.EnterExit()) { - buf = Api.QUERY_get_memory_data(LibsnesApi.SNES_MEMORY.SGB_CARTRAM); - size = Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.SGB_CARTRAM); - } + byte* buf = Api.QUERY_get_memory_data(LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM); + var size = Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM); + if (buf == null) + { + buf = Api.QUERY_get_memory_data(LibsnesApi.SNES_MEMORY.SGB_CARTRAM); + size = Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.SGB_CARTRAM); + } - if (size == 0) - { - return; - } + if (size == 0) + { + return; + } - if (size != data.Length) - { - throw new InvalidOperationException("Somehow, we got a mismatch between saveram size and what bsnes says the saveram size is"); - } + if (size != data.Length) + { + throw new InvalidOperationException("Somehow, we got a mismatch between saveram size and what bsnes says the saveram size is"); + } - Marshal.Copy(data, 0, (IntPtr)buf, size); + Marshal.Copy(data, 0, (IntPtr)buf, size); + } } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.ISettable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.ISettable.cs index 58521de3a5..f2a271904d 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.ISettable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.ISettable.cs @@ -28,8 +28,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES public bool PutSyncSettings(SnesSyncSettings o) { - bool ret = o.Profile != _syncSettings.Profile - || o.LeftPort != _syncSettings.LeftPort + bool ret = o.LeftPort != _syncSettings.LeftPort || o.RightPort != _syncSettings.RightPort || o.LimitAnalogChangeSensitivity != _syncSettings.LimitAnalogChangeSensitivity; @@ -57,7 +56,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES public bool CropSGBFrame { get; set; } = false; public bool AlwaysDoubleSize { get; set; } = false; - public bool ForceDeterminism { get; set; } = true; public string Palette { get; set; } = "BizHawk"; public SnesSettings Clone() @@ -68,8 +66,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES public class SnesSyncSettings { - public string Profile { get; set; } = "Performance"; // "Accuracy", and "Compatibility" are the other choicec, todo: make this an enum - public LibsnesControllerDeck.ControllerType LeftPort { get; set; } = LibsnesControllerDeck.ControllerType.Gamepad; public LibsnesControllerDeck.ControllerType RightPort { get; set; } = LibsnesControllerDeck.ControllerType.Gamepad; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IStatable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IStatable.cs index c90de87d53..6f6ff4298d 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IStatable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IStatable.cs @@ -14,8 +14,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES { var temp = SaveStateBinary(); temp.SaveAsHexFast(writer); - writer.WriteLine("Frame {0}", Frame); // we don't parse this, it's only for the client to use - writer.WriteLine("Profile {0}", CurrentProfile); } public void LoadStateText(TextReader reader) @@ -24,61 +22,28 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES byte[] state = new byte[hex.Length / 2]; state.ReadFromHexFast(hex); LoadStateBinary(new BinaryReader(new MemoryStream(state))); - reader.ReadLine(); // Frame # - var profile = reader.ReadLine().Split(' ')[1]; - ValidateLoadstateProfile(profile); } public void SaveStateBinary(BinaryWriter writer) { - writer.Write(DeterministicEmulation ? _savestatebuff : CoreSaveState()); - - // other variables + Api.SaveStateBinary(writer); writer.Write(IsLagFrame); writer.Write(LagCount); writer.Write(Frame); - writer.Write(CurrentProfile); - - writer.Flush(); } public void LoadStateBinary(BinaryReader reader) { - int size = Api.QUERY_serialize_size(); - byte[] buf = reader.ReadBytes(size); - CoreLoadState(buf); - - if (DeterministicEmulation) // deserialize controller and fast-foward now - { - // reconstruct savestatebuff at the same time to avoid a costly core serialize - var ms = new MemoryStream(); - var bw = new BinaryWriter(ms); - bw.Write(buf); - bool framezero = reader.ReadBoolean(); - bw.Write(framezero); - if (!framezero) - { - var ssc = new SaveController(ControllerDefinition); - ssc.DeSerialize(reader); - IController tmp = _controller; - _controller = ssc; - _nocallbacks = true; - FrameAdvance(ssc, false, false); - _nocallbacks = false; - _controller = tmp; - ssc.Serialize(bw); - } - - bw.Close(); - _savestatebuff = ms.ToArray(); - } - - // other variables + Api.LoadStateBinary(reader); IsLagFrame = reader.ReadBoolean(); LagCount = reader.ReadInt32(); Frame = reader.ReadInt32(); - var profile = reader.ReadString(); - ValidateLoadstateProfile(profile); + // refresh all callbacks now + Api.QUERY_set_video_refresh(snes_video_refresh); + Api.QUERY_set_input_poll(snes_input_poll); + Api.QUERY_set_input_state(snes_input_state); + Api.QUERY_set_input_notify(snes_input_notify); + Api.QUERY_set_audio_sample(_soundcb); } public byte[] SaveStateBinary() @@ -89,44 +54,5 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES bw.Flush(); return ms.ToArray(); } - - // handle the unmanaged part of loadstating - private void CoreLoadState(byte[] data) - { - int size = Api.QUERY_serialize_size(); - if (data.Length != size) - { - throw new Exception("Libsnes internal savestate size mismatch!"); - } - - Api.CMD_init(); - - // zero 01-sep-2014 - this approach isn't being used anymore, it's too slow! - // LoadCurrent(); //need to make sure chip roms are reloaded - fixed (byte* pbuf = &data[0]) - Api.CMD_unserialize(new IntPtr(pbuf), size); - } - - - // handle the unmanaged part of savestating - private byte[] CoreSaveState() - { - int size = Api.QUERY_serialize_size(); - byte[] buf = new byte[size]; - fixed (byte* pbuf = &buf[0]) - Api.CMD_serialize(new IntPtr(pbuf), size); - return buf; - } - - private void ValidateLoadstateProfile(string profile) - { - if (profile != CurrentProfile) - { - throw new InvalidOperationException($"You've attempted to load a savestate made using a different SNES profile ({profile}) than your current configuration ({CurrentProfile}). We COULD automatically switch for you, but we havent done that yet. This error is to make sure you know that this isnt going to work right now."); - } - } - - // most recent internal savestate, for deterministic mode ONLY - private byte[] _savestatebuff; } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IVideoProvider.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IVideoProvider.cs index 1d426410b5..67876f698b 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IVideoProvider.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.IVideoProvider.cs @@ -4,9 +4,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES { public partial class LibsnesCore : IVideoProvider { - public int VirtualWidth => (int)(_videoWidth * 1.146); + public int VirtualWidth { get; private set; } = 293; - public int VirtualHeight => _videoHeight; + public int VirtualHeight { get; private set; } = 224; public int BufferWidth => _videoWidth; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs index 7729127925..70a1f8636d 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs @@ -58,7 +58,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES _settings = (SnesSettings)settings ?? new SnesSettings(); _syncSettings = (SnesSyncSettings)syncSettings ?? new SnesSyncSettings(); - Api = new LibsnesApi(GetDllPath()) + // TODO: pass profile here + Api = new LibsnesApi(CoreComm.CoreFileProvider.DllPath()) { ReadHook = ReadHook, ExecHook = ExecHook, @@ -72,19 +73,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES Api.CMD_init(); - Api.QUERY_set_video_refresh(snes_video_refresh); - Api.QUERY_set_input_poll(snes_input_poll); - Api.QUERY_set_input_state(snes_input_state); - Api.QUERY_set_input_notify(snes_input_notify); Api.QUERY_set_path_request(snes_path_request); _scanlineStartCb = new LibsnesApi.snes_scanlineStart_t(snes_scanlineStart); _tracecb = new LibsnesApi.snes_trace_t(snes_trace); _soundcb = new LibsnesApi.snes_audio_sample_t(snes_audio_sample); - Api.QUERY_set_audio_sample(_soundcb); - - RefreshPalette(); // start up audio resampler InitAudio(); @@ -169,21 +163,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES SetupMemoryDomains(romData, sgbRomData); - // DeterministicEmulation = deterministicEmulation; // Note we don't respect the value coming in and force it instead - if (DeterministicEmulation) // save frame-0 savestate now - { - var ms = new MemoryStream(); - var bw = new BinaryWriter(ms); - bw.Write(CoreSaveState()); - bw.Write(true); // framezero, so no controller follows and don't frameadvance on load - bw.Close(); - _savestatebuff = ms.ToArray(); - } - if (CurrentProfile == "Compatibility") { ser.Register(_tracer); } + + Api.QUERY_set_path_request(null); + Api.QUERY_set_video_refresh(snes_video_refresh); + Api.QUERY_set_input_poll(snes_input_poll); + Api.QUERY_set_input_state(snes_input_state); + Api.QUERY_set_input_notify(snes_input_notify); + Api.QUERY_set_audio_sample(_soundcb); + Api.Seal(); + RefreshPalette(); } private readonly GameInfo _game; @@ -198,7 +190,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES private LoadParams _currLoadParams; private SpeexResampler _resampler; private int _timeFrameCounter; - private bool _nocallbacks; // disable all external callbacks. the front end should not even know the core is frame advancing private bool _disposed; public bool IsSGB { get; } @@ -208,19 +199,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES public string BoardName => "SGB"; } - public string CurrentProfile - { - get - { - // TODO: This logic will only work until Accuracy is ready, would we really want to override the user's choice of Accuracy with Compatibility? - if (_game.OptionValue("profile") == "Compatibility") - { - return "Compatibility"; - } - - return _syncSettings.Profile; - } - } + public string CurrentProfile => "Compatibility"; // We no longer support performance, and accuracy isn't worth the effort so we shall just hardcode this one public LibsnesApi Api { get; } @@ -374,20 +353,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES Api.QUERY_set_color_lut((IntPtr)p); } - private string GetDllPath() - { - var exename = "libsneshawk-32-" + CurrentProfile.ToLower() + ".dll"; - - string dllPath = Path.Combine(CoreComm.CoreFileProvider.DllPath(), exename); - - if (!File.Exists(dllPath)) - { - throw new InvalidOperationException("Couldn't locate the DLL for SNES emulation for profile: " + CurrentProfile + ". Please make sure you're using a fresh dearchive of a BizHawk distribution."); - } - - return dllPath; - } - private void ReadHook(uint addr) { MemoryCallbacks.CallReads(addr); @@ -573,6 +538,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES } } } + + VirtualHeight = BufferHeight; + VirtualWidth = BufferWidth; + if (VirtualHeight * 2 < VirtualWidth) + VirtualHeight *= 2; + if (VirtualHeight > 240) + VirtualWidth = 512; + VirtualWidth = (int)Math.Round(VirtualWidth * 1.146); } private void RefreshMemoryCallbacks(bool suppress) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs index 362c524900..41fbc650f4 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs @@ -8,12 +8,13 @@ //TODO //when a BG is not available, the last rendered BG still shows up. should clear it +using BizHawk.Common; using System; namespace BizHawk.Emulation.Cores.Nintendo.SNES { - public unsafe class SNESGraphicsDecoder : IDisposable + public unsafe class SNESGraphicsDecoder : IDisposable, IMonitor { public class PaletteSelection { @@ -1041,7 +1042,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES screen[i] = directColorTable[screen[i]]; } - - + + public void Enter() + { + ((IMonitor)api).Enter(); + } + + public void Exit() + { + ((IMonitor)api).Exit(); + } } //class SNESGraphicsDecoder } //namespace diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/LibSnes9x.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/LibSnes9x.cs index 6146d1e4d5..c82e32b466 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/LibSnes9x.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/LibSnes9x.cs @@ -3,18 +3,48 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; +using BizHawk.Common.BizInvoke; +using BizHawk.Emulation.Cores.Waterbox; namespace BizHawk.Emulation.Cores.Nintendo.SNES9X { - public class LibSnes9x + public abstract class LibSnes9x : LibWaterboxCore { - const string DllName = "libbizsnes.dll"; - const CallingConvention CC = CallingConvention.Cdecl; + public enum LeftPortDevice : uint + { + //None = 0, // something in the libretro spaghetti input goes wonky with None + Joypad = 1 + } - [DllImport(DllName, CallingConvention = CC)] - public static extern bool debug_init(byte[] data, int length); + public enum RightPortDevice : uint + { + //None = 0, // something in the libretro spaghetti input goes wonky with None + Joypad = 1, + Multitap = 2, + Mouse = 3, + SuperScope = 4, + Justifier = 5 + } - [DllImport(DllName, CallingConvention = CC)] - public static extern void debug_advance(int[] data); + [BizImport(CC)] + public abstract void SetButtons(short[] buttons); + [BizImport(CC)] + public abstract void biz_set_sound_channels(int channels); + [BizImport(CC)] + public abstract void biz_set_layers(int layers); + [BizImport(CC)] + public abstract void biz_soft_reset(); + [BizImport(CC)] + public abstract void biz_hard_reset(); + [BizImport(CC)] + public abstract void biz_set_port_devices(LeftPortDevice left, RightPortDevice right); + [BizImport(CC)] + public abstract bool biz_load_rom(byte[] data, int size); + [BizImport(CC)] + public abstract bool biz_init(); + [BizImport(CC)] + public abstract bool biz_is_ntsc(); + [BizImport(CC)] + public abstract void biz_post_load_state(); } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/Snes9x.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/Snes9x.cs index cee9f05fcc..ccc9492d6e 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/Snes9x.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/Snes9x.cs @@ -1,122 +1,491 @@ using System; using BizHawk.Emulation.Common; +using BizHawk.Emulation.Cores.Waterbox; +using BizHawk.Common.BizInvoke; +using System.Runtime.InteropServices; +using System.IO; +using BizHawk.Common.BufferExtensions; +using System.ComponentModel; +using BizHawk.Common; +using System.Collections.Generic; +using System.Linq; namespace BizHawk.Emulation.Cores.Nintendo.SNES9X { - [CoreAttributes("Snes9x", "FIXME", true, false, "5e0319ab3ef9611250efb18255186d0dc0d7e125", "https://github.com/snes9xgit/snes9x", true)] + [CoreAttributes("Snes9x", "", true, true, + "5e0319ab3ef9611250efb18255186d0dc0d7e125", "https://github.com/snes9xgit/snes9x", false)] [ServiceNotApplicable(typeof(IDriveLight))] - public class Snes9x : IEmulator, IVideoProvider, ISoundProvider + public class Snes9x : WaterboxCore, + ISettable, IRegionable { - [CoreConstructor("SNES")] - public Snes9x(CoreComm comm, byte[] rom) - { - if (!LibSnes9x.debug_init(rom, rom.Length)) - throw new Exception(); + private LibSnes9x _core; - ServiceProvider = new BasicServiceProvider(this); - CoreComm = comm; + [CoreConstructor("SNES")] + public Snes9x(CoreComm comm, byte[] rom, Settings settings, SyncSettings syncSettings) + :base(comm, new Configuration + { + DefaultWidth = 256, + DefaultHeight = 224, + MaxWidth = 512, + MaxHeight = 480, + MaxSamples = 8192, + SystemId = "SNES" + }) + { + settings = settings ?? new Settings(); + syncSettings = syncSettings ?? new SyncSettings(); + + _core = PreInit(new PeRunnerOptions + { + Filename = "snes9x.wbx", + SbrkHeapSizeKB = 1024, + SealedHeapSizeKB = 12 * 1024, + InvisibleHeapSizeKB = 6 * 1024, + PlainHeapSizeKB = 64 + }); + + if (!_core.biz_init()) + throw new InvalidOperationException("Init() failed"); + if (!_core.biz_load_rom(rom, rom.Length)) + throw new InvalidOperationException("LoadRom() failed"); + + PostInit(); + + if (_core.biz_is_ntsc()) + { + Console.WriteLine("NTSC rom loaded"); + VsyncNumerator = 21477272; + VsyncDenominator = 357366; + Region = DisplayType.NTSC; + } + else + { + Console.WriteLine("PAL rom loaded"); + VsyncNumerator = 21281370; + VsyncDenominator = 425568; + Region = DisplayType.PAL; + } + + _syncSettings = syncSettings; + InitControllers(); + PutSettings(settings); } #region controller - public ControllerDefinition ControllerDefinition + private readonly short[] _inputState = new short[16 * 8]; + private List _cdums; + private readonly List _controllers = new List(); + + private void InitControllers() { - get { return NullController.Instance.Definition; } + _core.biz_set_port_devices(_syncSettings.LeftPort, _syncSettings.RightPort); + + switch (_syncSettings.LeftPort) + { + case LibSnes9x.LeftPortDevice.Joypad: + _controllers.Add(new Joypad()); + break; + } + switch (_syncSettings.RightPort) + { + case LibSnes9x.RightPortDevice.Joypad: + _controllers.Add(new Joypad()); + break; + case LibSnes9x.RightPortDevice.Multitap: + _controllers.Add(new Joypad()); + _controllers.Add(new Joypad()); + _controllers.Add(new Joypad()); + _controllers.Add(new Joypad()); + break; + case LibSnes9x.RightPortDevice.Mouse: + _controllers.Add(new Mouse()); + break; + case LibSnes9x.RightPortDevice.SuperScope: + _controllers.Add(new SuperScope()); + break; + case LibSnes9x.RightPortDevice.Justifier: + _controllers.Add(new Justifier()); + break; + } + + _controllerDefinition = ControllerDefinitionMerger.GetMerged( + _controllers.Select(c => c.Definition), out _cdums); + + // add buttons that the core itself will handle + _controllerDefinition.BoolButtons.Add("Reset"); + _controllerDefinition.BoolButtons.Add("Power"); + _controllerDefinition.Name = "SNES Controller"; + } + + private void UpdateControls(IController c) + { + Array.Clear(_inputState, 0, 16 * 8); + for (int i = 0, offset = 0; i < _controllers.Count; i++, offset += 16) + { + _controllers[i].ApplyState(_cdums[i].UnMerge(c), _inputState, offset); + } + } + + private interface IControlDevice + { + ControllerDefinition Definition { get; } + void ApplyState(IController controller, short[] input, int offset); + } + + private class Joypad : IControlDevice + { + private static readonly string[] Buttons = + { + "0B", + "0Y", + "0Select", + "0Start", + "0Up", + "0Down", + "0Left", + "0Right", + "0A", + "0X", + "0L", + "0R" + }; + + private static int ButtonOrder(string btn) + { + var order = new Dictionary + { + ["0Up"] = 0, + ["0Down"] = 1, + ["0Left"] = 2, + ["0Right"] = 3, + + ["0Select"] = 4, + ["0Start"] = 5, + + ["0Y"] = 6, + ["0B"] = 7, + + ["0X"] = 8, + ["0A"] = 9, + + ["0L"] = 10, + ["0R"] = 11 + }; + + return order[btn]; + } + + private static readonly ControllerDefinition _definition = new ControllerDefinition + { + BoolButtons = Buttons.OrderBy(ButtonOrder).ToList() + }; + + public ControllerDefinition Definition { get; } = _definition; + + public void ApplyState(IController controller, short[] input, int offset) + { + for (int i = 0; i < Buttons.Length; i++) + input[offset + i] = (short)(controller.IsPressed(Buttons[i]) ? 1 : 0); + } + } + + private abstract class Analog : IControlDevice + { + public abstract ControllerDefinition Definition { get; } + + public void ApplyState(IController controller, short[] input, int offset) + { + foreach (var s in Definition.FloatControls) + input[offset++] = (short)(controller.GetFloat(s)); + foreach (var s in Definition.BoolButtons) + input[offset++] = (short)(controller.IsPressed(s) ? 1 : 0); + } + } + + private class Mouse : Analog + { + private static readonly ControllerDefinition _definition = new ControllerDefinition + { + BoolButtons = new List + { + "0Mouse Left", + "0Mouse Right" + }, + FloatControls = + { + "0Mouse X", + "0Mouse Y" + }, + FloatRanges = + { + new[] { -127f, 0f, 127f }, + new[] { -127f, 0f, 127f } + } + }; + + public override ControllerDefinition Definition => _definition; + } + + private class SuperScope : Analog + { + private static readonly ControllerDefinition _definition = new ControllerDefinition + { + BoolButtons = new List + { + "0Trigger", + "0Cursor", + "0Turbo", + "0Pause" + }, + FloatControls = + { + "0Scope X", + "0Scope Y" + }, + FloatRanges = + { + // snes9x is always in 224 mode + new[] { 0f, 128f, 256f }, + new[] { 0f, 0f, 240f } + } + }; + + public override ControllerDefinition Definition => _definition; + } + + private class Justifier : Analog + { + private static readonly ControllerDefinition _definition = new ControllerDefinition + { + BoolButtons = new List + { + "0Trigger", + "0Start", + }, + FloatControls = + { + "0Justifier X", + "0Justifier Y", + }, + FloatRanges = + { + // snes9x is always in 224 mode + new[] { 0f, 128f, 256f }, + new[] { 0f, 0f, 240f }, + } + }; + + public override ControllerDefinition Definition => _definition; + } + + private ControllerDefinition _controllerDefinition; + public override ControllerDefinition ControllerDefinition => _controllerDefinition; + + #endregion + + public DisplayType Region { get; } + + protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound) + { + if (controller.IsPressed("Power")) + _core.biz_hard_reset(); + else if (controller.IsPressed("Reset")) + _core.biz_soft_reset(); + UpdateControls(controller); + _core.SetButtons(_inputState); + + return new LibWaterboxCore.FrameInfo(); + } + protected override void FrameAdvancePost() + { + _virtualHeight = BufferHeight; + _virtualWidth = BufferWidth; + if (_virtualHeight * 2 < _virtualWidth) + _virtualHeight *= 2; + if (_virtualHeight > 240) + _virtualWidth = 512; + _virtualWidth = (int)Math.Round(_virtualWidth * 1.146); + } + + private int _virtualWidth; + private int _virtualHeight; + public override int VirtualWidth => _virtualWidth; + public override int VirtualHeight => _virtualHeight; + + #region IStatable + + protected override void LoadStateBinaryInternal(BinaryReader reader) + { + _core.biz_post_load_state(); } #endregion - public void Dispose() + #region settings + + private Settings _settings; + private SyncSettings _syncSettings; + + public Settings GetSettings() { + return _settings.Clone(); } - public IEmulatorServiceProvider ServiceProvider { get; private set; } - - public void FrameAdvance(IController controller, bool render, bool rendersound = true) + public SyncSettings GetSyncSettings() { - Frame++; - - LibSnes9x.debug_advance(_vbuff); + return _syncSettings.Clone(); } - public int Frame { get; private set; } - - public void ResetCounters() + public bool PutSettings(Settings o) { - Frame = 0; + _settings = o; + int s = 0; + if (o.PlaySound0) s |= 1; + if (o.PlaySound0) s |= 2; + if (o.PlaySound0) s |= 4; + if (o.PlaySound0) s |= 8; + if (o.PlaySound0) s |= 16; + if (o.PlaySound0) s |= 32; + if (o.PlaySound0) s |= 64; + if (o.PlaySound0) s |= 128; + _core.biz_set_sound_channels(s); + int l = 0; + if (o.ShowBg0) l |= 1; + if (o.ShowBg1) l |= 2; + if (o.ShowBg2) l |= 4; + if (o.ShowBg3) l |= 8; + if (o.ShowWindow) l |= 32; + if (o.ShowTransparency) l |= 64; + if (o.ShowSprites0) l |= 256; + if (o.ShowSprites1) l |= 512; + if (o.ShowSprites2) l |= 1024; + if (o.ShowSprites3) l |= 2048; + _core.biz_set_layers(l); + + return false; // no reboot needed } - public string SystemId { get { return "SNES"; } } - public bool DeterministicEmulation { get { return true; } } - public CoreComm CoreComm { get; private set; } - - #region IVideoProvider - - private int[] _vbuff = new int[512 * 480]; - public int[] GetVideoBuffer() { return _vbuff; } - public int VirtualWidth - { get { return (int)(BufferWidth * 1.146); ; } } - public int VirtualHeight { get { return BufferHeight; } } - public int BufferWidth { get { return 256; } } - public int BufferHeight { get { return 224; } } - public int BackgroundColor { get { return unchecked((int)0xff000000); } } - - public int VsyncNumerator + public bool PutSyncSettings(SyncSettings o) { - [FeatureNotImplemented] - get + var ret = SyncSettings.NeedsReboot(_syncSettings, o); + _syncSettings = o; + return ret; + } + + public class Settings + { + [DefaultValue(true)] + [DisplayName("Enable Sound Channel 1")] + public bool PlaySound0 { get; set; } + + [DefaultValue(true)] + [DisplayName("Enable Sound Channel 2")] + public bool PlaySound1 { get; set; } + + [DefaultValue(true)] + [DisplayName("Enable Sound Channel 3")] + public bool PlaySound2 { get; set; } + + [DefaultValue(true)] + [DisplayName("Enable Sound Channel 4")] + public bool PlaySound3 { get; set; } + + [DefaultValue(true)] + [DisplayName("Enable Sound Channel 5")] + public bool PlaySound4 { get; set; } + + [DefaultValue(true)] + [DisplayName("Enable Sound Channel 6")] + public bool PlaySound5 { get; set; } + + [DefaultValue(true)] + [DisplayName("Enable Sound Channel 7")] + public bool PlaySound6 { get; set; } + + [DefaultValue(true)] + [DisplayName("Enable Sound Channel 8")] + public bool PlaySound7 { get; set; } + + [DefaultValue(true)] + [DisplayName("Enable Background Layer 1")] + public bool ShowBg0 { get; set; } + + [DefaultValue(true)] + [DisplayName("Enable Background Layer 2")] + public bool ShowBg1 { get; set; } + + [DefaultValue(true)] + [DisplayName("Enable Background Layer 3")] + public bool ShowBg2 { get; set; } + + [DefaultValue(true)] + [DisplayName("Enable Background Layer 4")] + public bool ShowBg3 { get; set; } + + [DefaultValue(true)] + [DisplayName("Show Sprites Priority 1")] + public bool ShowSprites0 { get; set; } + + [DefaultValue(true)] + [DisplayName("Show Sprites Priority 2")] + public bool ShowSprites1 { get; set; } + + [DefaultValue(true)] + [DisplayName("Show Sprites Priority 3")] + public bool ShowSprites2 { get; set; } + + [DefaultValue(true)] + [DisplayName("Show Sprites Priority 4")] + public bool ShowSprites3 { get; set; } + + [DefaultValue(true)] + [DisplayName("Show Window")] + public bool ShowWindow { get; set; } + + [DefaultValue(true)] + [DisplayName("Show Transparency")] + public bool ShowTransparency { get; set; } + + public Settings() { - return NullVideo.DefaultVsyncNum; + SettingsUtil.SetDefaultValues(this); + } + + public Settings Clone() + { + return (Settings)MemberwiseClone(); } } - public int VsyncDenominator + public class SyncSettings { - [FeatureNotImplemented] - get + [DefaultValue(LibSnes9x.LeftPortDevice.Joypad)] + [DisplayName("Left Port")] + [Description("Specifies the controller type plugged into the left controller port on the console")] + public LibSnes9x.LeftPortDevice LeftPort { get; set; } + + [DefaultValue(LibSnes9x.RightPortDevice.Joypad)] + [DisplayName("Right Port")] + [Description("Specifies the controller type plugged into the right controller port on the console")] + public LibSnes9x.RightPortDevice RightPort { get; set; } + + public SyncSettings() { - return NullVideo.DefaultVsyncDen; + SettingsUtil.SetDefaultValues(this); } - } - #endregion - - #region ISoundProvider - - private short[] _sbuff = new short[2048]; - - public void GetSamplesSync(out short[] samples, out int nsamp) - { - samples = _sbuff; - nsamp = 735; - } - - public void DiscardSamples() - { - // Nothing to do - } - - public void SetSyncMode(SyncSoundMode mode) - { - if (mode == SyncSoundMode.Async) + public SyncSettings Clone() { - throw new NotSupportedException("Async mode is not supported."); + return (SyncSettings)MemberwiseClone(); } - } - public bool CanProvideAsync - { - get { return false; } - } - - public SyncSoundMode SyncMode - { - get { return SyncSoundMode.Sync; } - } - - public void GetSamplesAsync(short[] samples) - { - throw new InvalidOperationException("Async mode is not supported."); + public static bool NeedsReboot(SyncSettings x, SyncSettings y) + { + // the core can handle dynamic plugging and unplugging, but that changes + // the controllerdefinition, and we're not ready for that + return !DeepEquality.DeepEquals(x, y); + } } #endregion diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/VB/LibVirtualBoyee.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/VB/LibVirtualBoyee.cs new file mode 100644 index 0000000000..924fdc2816 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/VB/LibVirtualBoyee.cs @@ -0,0 +1,85 @@ +using BizHawk.Common.BizInvoke; +using BizHawk.Emulation.Cores.Waterbox; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Consoles.Nintendo.VB +{ + public abstract class LibVirtualBoyee : LibWaterboxCore + { + public enum Buttons : int + { + Up = 0x200, + Down = 0x100, + Left = 0x80, + Right = 0x40, + Select = 0x800, + Start = 0x400, + B = 0x2, + A = 0x1, + Up_R = 0x10, + Down_R = 0x200, + Left_R = 0x1000, + Right_R = 0x2000, + L = 0x8, + R = 0x4 + } + + [StructLayout(LayoutKind.Sequential)] + public new class FrameInfo : LibWaterboxCore.FrameInfo + { + public Buttons Buttons; + } + + [StructLayout(LayoutKind.Sequential)] + public class NativeSettings + { + public int InstantReadHack; + public int DisableParallax; + public int ThreeDeeMode; + public int SwapViews; + public int AnaglyphPreset; + public int AnaglyphCustomLeftColor; + public int AnaglyphCustomRightColor; + public int NonAnaglyphColor; + public int LedOnScale; + public int InterlacePrescale; + public int SideBySideSeparation; + + private static int ConvertColor(Color c) + { + return c.ToArgb(); + } + + public static NativeSettings FromFrontendSettings(VirtualBoyee.Settings s, VirtualBoyee.SyncSettings ss) + { + return new NativeSettings + { + InstantReadHack = ss.InstantReadHack ? 1 : 0, + DisableParallax = ss.DisableParallax ? 1 : 0, + ThreeDeeMode = (int)s.ThreeDeeMode, + SwapViews = s.SwapViews ? 1 : 0, + AnaglyphPreset = (int)s.AnaglyphPreset, + AnaglyphCustomLeftColor = ConvertColor(s.AnaglyphCustomLeftColor), + AnaglyphCustomRightColor = ConvertColor(s.AnaglyphCustomRightColor), + NonAnaglyphColor = ConvertColor(s.NonAnaglyphColor), + LedOnScale = s.LedOnScale, + InterlacePrescale = s.InterlacePrescale, + SideBySideSeparation = s.SideBySideSeparation + }; + } + } + + + [BizImport(CC)] + public abstract bool Load(byte[] rom, int length, [In]NativeSettings settings); + + [BizImport(CC)] + public abstract void HardReset(); + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/VB/VirtualBoyee.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/VB/VirtualBoyee.cs new file mode 100644 index 0000000000..e2321477d5 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/VB/VirtualBoyee.cs @@ -0,0 +1,253 @@ +using BizHawk.Common; +using BizHawk.Common.BizInvoke; +using BizHawk.Common.BufferExtensions; +using BizHawk.Emulation.Common; +using BizHawk.Emulation.Cores.Waterbox; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Consoles.Nintendo.VB +{ + [CoreAttributes("Virtual Boyee", "Ryphecha", true, true, "0.9.44.1", + "https://mednafen.github.io/releases/", false)] + public class VirtualBoyee : WaterboxCore, ISettable + { + private LibVirtualBoyee _boyee; + + [CoreConstructor("VB")] + public VirtualBoyee(CoreComm comm, byte[] rom, Settings settings, SyncSettings syncSettings) + :base(comm, new Configuration + { + DefaultFpsNumerator = 20000000, + DefaultFpsDenominator = 397824, + DefaultWidth = 384, + DefaultHeight = 224, + MaxWidth = 1024, + MaxHeight = 1024, + MaxSamples = 8192, + SystemId = "VB" + }) + { + _settings = settings ?? new Settings(); + _syncSettings = syncSettings ?? new SyncSettings(); + // TODO: the way settings work in this core, changing the non-sync ones will invalidate savestates + var nativeSettings = LibVirtualBoyee.NativeSettings.FromFrontendSettings(_settings, _syncSettings); + + _boyee = PreInit(new PeRunnerOptions + { + Filename = "vb.wbx", + SbrkHeapSizeKB = 256, + SealedHeapSizeKB = 4 * 1024, + InvisibleHeapSizeKB = 256, + PlainHeapSizeKB = 256 + }); + + if (!_boyee.Load(rom, rom.Length, nativeSettings)) + throw new InvalidOperationException("Core rejected the rom"); + + PostInit(); + } + + protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound) + { + if (controller.IsPressed("Power")) + _boyee.HardReset(); + + return new LibVirtualBoyee.FrameInfo { Buttons = GetButtons(controller) }; + } + + #region Controller + + private LibVirtualBoyee.Buttons GetButtons(IController c) + { + var ret = 0; + var val = 1; + foreach (var s in CoreButtons) + { + if (c.IsPressed(s)) + ret |= val; + val <<= 1; + } + return (LibVirtualBoyee.Buttons)ret; + } + + private static readonly string[] CoreButtons = + { + "A", "B", "R", "L", + "R_Up", "R_Right", + "L_Right", "L_Left", "L_Down", "L_Up", + "Start", "Select", "R_Left", "R_Down" + }; + + private static readonly Dictionary _buttonOrdinals = new Dictionary + { + ["L_Up"] = 1, + ["L_Down"] = 2, + ["L_Left"] = 3, + ["L_Right"] = 4, + ["R_Up"] = 5, + ["R_Down"] = 6, + ["R_Left"] = 7, + ["R_Right"] = 8, + ["B"] = 9, + ["A"] = 10, + ["L"] = 11, + ["R"] = 12, + ["Select"] = 13, + ["Start"] = 14 + }; + + private static readonly ControllerDefinition VirtualBoyController = new ControllerDefinition + { + Name = "VirtualBoy Controller", + BoolButtons = CoreButtons + .OrderBy(b => _buttonOrdinals[b]) + .Concat(new[] { "Power" }) + .ToList() + }; + + public override ControllerDefinition ControllerDefinition => VirtualBoyController; + + #endregion + + #region ISettable + + public class SyncSettings + { + [DefaultValue(false)] + [Description("Reduce input latency. Works with all known commercial games, may have homebrew issues.")] + public bool InstantReadHack { get; set; } + [DefaultValue(false)] + [Description("Disable parallax for rendering.")] + public bool DisableParallax { get; set; } + + public SyncSettings Clone() + { + return (SyncSettings)MemberwiseClone(); + } + + public static bool NeedsReboot(SyncSettings x, SyncSettings y) + { + return !DeepEquality.DeepEquals(x, y); + } + + public SyncSettings() + { + SettingsUtil.SetDefaultValues(this); + } + } + + public class Settings + { + public enum ThreeDeeModes : int + { + Anaglyph = 0, + CyberScope = 1, + SideBySide = 2, + //OverUnder, + VerticalInterlaced = 4, + HorizontalInterlaced = 5 + } + + [DefaultValue(ThreeDeeModes.Anaglyph)] + [Description("How to display the 3d image. Use whichever method works with your VR hardware.")] + public ThreeDeeModes ThreeDeeMode { get; set; } + + [DefaultValue(false)] + [Description("Swap the left and right views.")] + public bool SwapViews { get; set; } + + public enum AnaglyphPresets : int + { + Custom, + RedBlue, + RedCyan, + RedElectricCyan, + RedGreen, + GreenMagneto, + YellowBlue + } + + [DefaultValue(AnaglyphPresets.RedBlue)] + [Description("Color preset for Anaglyph mode.")] + public AnaglyphPresets AnaglyphPreset { get; set; } + + [DefaultValue(typeof(Color), "Green")] + [Description("Left anaglyph color. Ignored unless Preset is Custom.")] + public Color AnaglyphCustomLeftColor { get; set; } + [DefaultValue(typeof(Color), "Purple")] + [Description("Right anaglyph color. Ignored unless Preset is Custom.")] + public Color AnaglyphCustomRightColor { get; set; } + + [DefaultValue(typeof(Color), "White")] + [Description("Display color for all of the non-anaglyph modes. Real hardware was red, but other colors may be easier on your eyes.")] + public Color NonAnaglyphColor { get; set; } + + [DefaultValue(1750)] + [Range(1000, 2000)] + [Description("LED gamma ramp. Range of 1000 to 2000")] + public int LedOnScale { get; set; } + + [DefaultValue(2)] + [Range(1, 10)] + public int InterlacePrescale { get; set; } + + [DefaultValue(0)] + [Range(0, 1024)] + [Description("How many pixels to put between views in Side By Side mode")] + public int SideBySideSeparation { get; set; } + + public Settings Clone() + { + return (Settings)MemberwiseClone(); + } + + public static bool NeedsReboot(Settings x, Settings y) + { + return !DeepEquality.DeepEquals(x, y); + } + + public Settings() + { + SettingsUtil.SetDefaultValues(this); + } + } + + private Settings _settings; + private SyncSettings _syncSettings; + + public Settings GetSettings() + { + return _settings.Clone(); + } + + public SyncSettings GetSyncSettings() + { + return _syncSettings.Clone(); + } + + public bool PutSettings(Settings o) + { + var ret = Settings.NeedsReboot(_settings, o); + _settings = o; + return ret; + } + + public bool PutSyncSettings(SyncSettings o) + { + var ret = SyncSettings.NeedsReboot(_syncSettings, o); + _syncSettings = o; + return ret; + } + + #endregion + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/SNK/DualNeoGeoPort.cs b/BizHawk.Emulation.Cores/Consoles/SNK/DualNeoGeoPort.cs new file mode 100644 index 0000000000..5cf66cc8b3 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/SNK/DualNeoGeoPort.cs @@ -0,0 +1,348 @@ +using BizHawk.Common; +using BizHawk.Common.BizInvoke; +using BizHawk.Emulation.Common; +using BizHawk.Emulation.Cores.Sound; +using BizHawk.Emulation.Cores.Waterbox; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Consoles.SNK +{ + [CoreAttributes("Dual NeoPop", "Thomas Klausner and natt", true, false, "0.9.44.1", + "https://mednafen.github.io/releases/", false)] + public class DualNeoGeoPort : IEmulator + { + private NeoGeoPort _left; + private NeoGeoPort _right; + private readonly BasicServiceProvider _serviceProvider; + private bool _disposed = false; + private readonly DualSyncSound _soundProvider; + private readonly SideBySideVideo _videoProvider; + private readonly LinkInterop _leftEnd; + private readonly LinkInterop _rightEnd; + private readonly LinkCable _linkCable; + + [CoreConstructor("DNGP")] + public DualNeoGeoPort(CoreComm comm, byte[] rom, bool deterministic) + { + CoreComm = comm; + _left = new NeoGeoPort(comm, rom, new NeoGeoPort.SyncSettings { Language = LibNeoGeoPort.Language.English }, deterministic, PeRunner.CanonicalStart); + _right = new NeoGeoPort(comm, rom, new NeoGeoPort.SyncSettings { Language = LibNeoGeoPort.Language.English }, deterministic, PeRunner.AlternateStart); + _linkCable = new LinkCable(); + _leftEnd = new LinkInterop(_left, _linkCable.LeftIn, _linkCable.LeftOut); + _rightEnd = new LinkInterop(_right, _linkCable.RightIn, _linkCable.RightOut); + + + _serviceProvider = new BasicServiceProvider(this); + _soundProvider = new DualSyncSound(_left, _right); + _serviceProvider.Register(_soundProvider); + _videoProvider = new SideBySideVideo(_left, _right); + _serviceProvider.Register(_videoProvider); + } + + public void FrameAdvance(IController controller, bool render, bool rendersound = true) + { + var t1 = Task.Run(() => + { + _left.FrameAdvance(new PrefixController(controller, "P1 "), render, rendersound); + _leftEnd.SignalEndOfFrame(); + }); + var t2 = Task.Run(() => + { + _right.FrameAdvance(new PrefixController(controller, "P2 "), render, rendersound); + _rightEnd.SignalEndOfFrame(); + }); + var t3 = Task.Run(() => + { + _linkCable.RunFrame(); + }); + Task.WaitAll(t1, t2, t3); + Frame++; + _soundProvider.Fetch(); + _videoProvider.Fetch(); + } + + #region link cable + + private class LinkCable + { + public readonly BlockingCollection LeftIn = new BlockingCollection(); + public readonly BlockingCollection LeftOut = new BlockingCollection(); + public readonly BlockingCollection RightIn = new BlockingCollection(); + public readonly BlockingCollection RightOut = new BlockingCollection(); + + private readonly Queue _leftData = new Queue(); + private readonly Queue _rightData = new Queue(); + + public void RunFrame() + { + LinkRequest l = LeftIn.Take(); + LinkRequest r = RightIn.Take(); + while (true) + { + switch (l.RequestType) + { + case LinkRequest.RequestTypes.EndOfFrame: + if (r.RequestType == LinkRequest.RequestTypes.EndOfFrame) + { + Console.WriteLine("\nEnd of Frame {0} {1}", _leftData.Count, _rightData.Count); + return; + } + break; + case LinkRequest.RequestTypes.Write: + Console.Write("LW "); + _leftData.Enqueue(l.Data); + l = LeftIn.Take(); + continue; + case LinkRequest.RequestTypes.Read: + case LinkRequest.RequestTypes.Poll: + if (_rightData.Count > 0) + { + if (l.RequestType == LinkRequest.RequestTypes.Read) + Console.Write("LR "); + LeftOut.Add(new LinkResult + { + Data = l.RequestType == LinkRequest.RequestTypes.Read ? _rightData.Dequeue() : _rightData.Peek(), + Return = true + }); + l = LeftIn.Take(); + continue; + } + else if (r.RequestType != LinkRequest.RequestTypes.Write) + { + if (l.RequestType == LinkRequest.RequestTypes.Read) + Console.Write("L! "); + LeftOut.Add(new LinkResult + { + Data = l.Data, + Return = false + }); + l = LeftIn.Take(); + continue; + } + else + { + break; + } + } + switch (r.RequestType) + { + case LinkRequest.RequestTypes.Write: + Console.Write("RW "); + _rightData.Enqueue(r.Data); + r = RightIn.Take(); + continue; + case LinkRequest.RequestTypes.Read: + case LinkRequest.RequestTypes.Poll: + if (_leftData.Count > 0) + { + if (r.RequestType == LinkRequest.RequestTypes.Read) + Console.Write("RR "); + RightOut.Add(new LinkResult + { + Data = r.RequestType == LinkRequest.RequestTypes.Read ? _leftData.Dequeue() : _leftData.Peek(), + Return = true + }); + r = RightIn.Take(); + continue; + } + else if (l.RequestType != LinkRequest.RequestTypes.Write) + { + if (r.RequestType == LinkRequest.RequestTypes.Read) + Console.Write("R! "); + RightOut.Add(new LinkResult + { + Data = r.Data, + Return = false + }); + r = RightIn.Take(); + continue; + } + else + { + break; + } + } + } + } + } + + public struct LinkRequest + { + public enum RequestTypes : byte + { + Read, + Poll, + Write, + EndOfFrame + } + public RequestTypes RequestType; + public byte Data; + } + public struct LinkResult + { + public byte Data; + public bool Return; + } + + private unsafe class LinkInterop + { + private readonly BlockingCollection _push; + private readonly BlockingCollection _pull; + private NeoGeoPort _core; + private readonly IntPtr _readcb; + private readonly IntPtr _pollcb; + private readonly IntPtr _writecb; + private readonly IImportResolver _exporter; + + public LinkInterop(NeoGeoPort core, BlockingCollection push, BlockingCollection pull) + { + _core = core; + _push = push; + _pull = pull; + _exporter = BizExvoker.GetExvoker(this, CallingConventionAdapters.Waterbox); + _readcb = _exporter.SafeResolve("CommsReadCallback"); + _pollcb = _exporter.SafeResolve("CommsPollCallback"); + _writecb = _exporter.SafeResolve("CommsWriteCallback"); + ConnectPointers(); + } + + private void ConnectPointers() + { + _core._neopop.SetCommsCallbacks(_readcb, _pollcb, _writecb); + } + + private bool CommsPollNoBuffer() + { + _push.Add(new LinkRequest + { + RequestType = LinkRequest.RequestTypes.Poll + }); + return _pull.Take().Return; + } + + [BizExport(CallingConvention.Cdecl)] + public bool CommsReadCallback(byte* buffer) + { + if (buffer == null) + return CommsPollNoBuffer(); + _push.Add(new LinkRequest + { + RequestType = LinkRequest.RequestTypes.Read, + Data = *buffer + }); + var r = _pull.Take(); + *buffer = r.Data; + return r.Return; + } + [BizExport(CallingConvention.Cdecl)] + public bool CommsPollCallback(byte* buffer) + { + if (buffer == null) + return CommsPollNoBuffer(); + _push.Add(new LinkRequest + { + RequestType = LinkRequest.RequestTypes.Poll, + Data = *buffer + }); + var r = _pull.Take(); + *buffer = r.Data; + return r.Return; + } + [BizExport(CallingConvention.Cdecl)] + public void CommsWriteCallback(byte data) + { + _push.Add(new LinkRequest + { + RequestType = LinkRequest.RequestTypes.Write, + Data = data + }); + } + + public void SignalEndOfFrame() + { + _push.Add(new LinkRequest + { + RequestType = LinkRequest.RequestTypes.EndOfFrame + }); + } + + public void PostLoadState() + { + ConnectPointers(); + } + } + + #endregion + + private class PrefixController : IController + { + public PrefixController(IController controller, string prefix) + { + _controller = controller; + _prefix = prefix; + } + + private readonly IController _controller; + private readonly string _prefix; + + public ControllerDefinition Definition => null; + + public float GetFloat(string name) + { + return _controller.GetFloat(_prefix + name); + } + + public bool IsPressed(string button) + { + return _controller.IsPressed(_prefix + button); + } + } + + public ControllerDefinition ControllerDefinition => DualNeoGeoPortController; + + private static readonly ControllerDefinition DualNeoGeoPortController = new ControllerDefinition + { + BoolButtons = + { + "P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 A", "P1 B", "P1 Option", "P1 Power", + "P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 A", "P2 B", "P2 Option", "P2 Power" + }, + Name = "Dual NeoGeo Portable Controller" + }; + + public void ResetCounters() + { + Frame = 0; + } + + public int Frame { get; private set; } + + public IEmulatorServiceProvider ServiceProvider => _serviceProvider; + + public CoreComm CoreComm { get; } + + public bool DeterministicEmulation => _left.DeterministicEmulation && _right.DeterministicEmulation; + + public string SystemId => "DNGP"; + + public void Dispose() + { + if (!_disposed) + { + _left.Dispose(); + _right.Dispose(); + _left = null; + _right = null; + _disposed = true; + } + } + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/SNK/LibNeoGeoPort.cs b/BizHawk.Emulation.Cores/Consoles/SNK/LibNeoGeoPort.cs new file mode 100644 index 0000000000..5a047b3891 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/SNK/LibNeoGeoPort.cs @@ -0,0 +1,43 @@ +using BizHawk.Common.BizInvoke; +using BizHawk.Emulation.Cores.Waterbox; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Consoles.SNK +{ + public abstract class LibNeoGeoPort : LibWaterboxCore + { + [StructLayout(LayoutKind.Sequential)] + public new class FrameInfo : LibWaterboxCore.FrameInfo + { + public long FrontendTime; + public int SkipRendering; + public int Buttons; + } + public enum Language + { + Japanese, English + } + [UnmanagedFunctionPointer(CC)] + public delegate void SaveRamCallback(IntPtr data, int length); + + [BizImport(CC)] + public abstract bool LoadSystem(byte[] rom, int romlength, Language language); + [BizImport(CC)] + public abstract void SetLayers(int enable); // 1, 2, 4 bg,fg,sprites + [BizImport(CC)] + public abstract void HardReset(); + [BizImport(CC)] + public abstract void SetCommsCallbacks(IntPtr readcb, IntPtr pollcb, IntPtr writecb); + [BizImport(CC)] + public abstract bool HasSaveRam(); + [BizImport(CC)] + public abstract bool PutSaveRam(byte[] data, int length); + [BizImport(CC)] + public abstract void GetSaveRam(SaveRamCallback callback); + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/SNK/NeoGeoPort.cs b/BizHawk.Emulation.Cores/Consoles/SNK/NeoGeoPort.cs new file mode 100644 index 0000000000..cbcbadeef4 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/SNK/NeoGeoPort.cs @@ -0,0 +1,213 @@ +using BizHawk.Common; +using BizHawk.Common.BizInvoke; +using BizHawk.Common.BufferExtensions; +using BizHawk.Emulation.Common; +using BizHawk.Emulation.Cores.Waterbox; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Consoles.SNK +{ + [CoreAttributes("NeoPop", "Thomas Klausner", true, true, "0.9.44.1", + "https://mednafen.github.io/releases/", false)] + public class NeoGeoPort : WaterboxCore, + ISaveRam, // NGP provides its own saveram interface + ISettable + { + internal LibNeoGeoPort _neopop; + + [CoreConstructor("NGP")] + public NeoGeoPort(CoreComm comm, byte[] rom, SyncSettings syncSettings, bool deterministic) + : this(comm, rom, syncSettings, deterministic, PeRunner.CanonicalStart) + { + } + + internal NeoGeoPort(CoreComm comm, byte[] rom, SyncSettings syncSettings, bool deterministic, ulong startAddress) + :base(comm, new Configuration + { + DefaultFpsNumerator = 6144000, + DefaultFpsDenominator = 515 * 198, + DefaultWidth = 160, + DefaultHeight = 152, + MaxWidth = 160, + MaxHeight = 152, + MaxSamples = 8192, + SystemId = "NGP" + }) + { + if (rom.Length > 4 * 1024 * 1024) + throw new InvalidOperationException("ROM too big!"); + + _syncSettings = syncSettings ?? new SyncSettings(); + + _neopop = PreInit(new PeRunnerOptions + { + Filename = "ngp.wbx", + SbrkHeapSizeKB = 256, + SealedHeapSizeKB = 5 * 1024, // must be a bit larger than the ROM size + InvisibleHeapSizeKB = 4, + PlainHeapSizeKB = 5 * 1024, // must be a bit larger than the ROM size + StartAddress = startAddress + }); + + if (!_neopop.LoadSystem(rom, rom.Length, _syncSettings.Language)) + throw new InvalidOperationException("Core rejected the rom"); + + PostInit(); + + DeterministicEmulation = deterministic || !_syncSettings.UseRealTime; + InitializeRtc(_syncSettings.InitialTime); + } + + protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound) + { + if (controller.IsPressed("Power")) + _neopop.HardReset(); + + return new LibNeoGeoPort.FrameInfo + { + FrontendTime = GetRtcTime(!DeterministicEmulation), + Buttons = GetButtons(controller), + SkipRendering = render ? 0 : 1, + }; + } + + #region Controller + + private static int GetButtons(IController c) + { + var ret = 0; + var val = 1; + foreach (var s in CoreButtons) + { + if (c.IsPressed(s)) + ret |= val; + val <<= 1; + } + return ret; + } + + private static readonly string[] CoreButtons = + { + "Up", "Down", "Left", "Right", "A", "B", "Option" + }; + + private static readonly Dictionary ButtonOrdinals = new Dictionary + { + ["Up"] = 1, + ["Down"] = 2, + ["Left"] = 3, + ["Right"] = 4, + ["B"] = 9, + ["A"] = 10, + ["R"] = 11, + ["L"] = 12, + ["Option"] = 13 + }; + + private static readonly ControllerDefinition NeoGeoPortableController = new ControllerDefinition + { + Name = "NeoGeo Portable Controller", + BoolButtons = CoreButtons + .OrderBy(b => ButtonOrdinals[b]) + .Concat(new[] { "Power" }) + .ToList() + }; + + public override ControllerDefinition ControllerDefinition => NeoGeoPortableController; + + #endregion + + #region ISettable + + private SyncSettings _syncSettings; + + public class SyncSettings + { + [DisplayName("Language")] + [Description("Language of the system. Only affects some games.")] + [DefaultValue(LibNeoGeoPort.Language.Japanese)] + public LibNeoGeoPort.Language Language { get; set; } + + [DisplayName("Initial Time")] + [Description("Initial time of emulation. Only relevant when UseRealTime is false.")] + [DefaultValue(typeof(DateTime), "2010-01-01")] + public DateTime InitialTime { get; set; } + + [DisplayName("Use RealTime")] + [Description("If true, RTC clock will be based off of real time instead of emulated time. Ignored (set to false) when recording a movie.")] + [DefaultValue(false)] + public bool UseRealTime { get; set; } + + public SyncSettings Clone() + { + return (SyncSettings)MemberwiseClone(); + } + + public static bool NeedsReboot(SyncSettings x, SyncSettings y) + { + return !DeepEquality.DeepEquals(x, y); + } + + public SyncSettings() + { + SettingsUtil.SetDefaultValues(this); + } + } + + public object GetSettings() + { + return null; + } + + public SyncSettings GetSyncSettings() + { + return _syncSettings.Clone(); + } + + public bool PutSettings(object o) + { + return false; + } + + public bool PutSyncSettings(SyncSettings o) + { + var ret = SyncSettings.NeedsReboot(_syncSettings, o); + _syncSettings = o; + return ret; + } + + #endregion + + #region ISaveram + + public new bool SaveRamModified => _neopop.HasSaveRam(); + + public new byte[] CloneSaveRam() + { + byte[] ret = null; + _neopop.GetSaveRam((data, size) => + { + ret = new byte[size]; + Marshal.Copy(data, ret, 0, size); + }); + return ret; + } + + public new void StoreSaveRam(byte[] data) + { + if (!_neopop.PutSaveRam(data, data.Length)) + throw new InvalidOperationException("Core rejected the saveram"); + } + + #endregion + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.ISettable.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.ISettable.cs index 28167f2a02..90331a7528 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.ISettable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.ISettable.cs @@ -62,7 +62,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem { public bool EnableFM = true; public bool AllowOverlock = false; - public bool UseBIOS = false; + public bool UseBIOS = true; public string ConsoleRegion = "Export"; public string DisplayType = "NTSC"; diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs index 89c331a564..a628852be1 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs @@ -143,13 +143,20 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem else if (game.System == "SMS") { BiosRom = comm.CoreFileProvider.GetFirmware("SMS", RegionStr, false); - if (BiosRom != null && (game["RequireBios"] || SyncSettings.UseBIOS)) - Port3E = 0xF7; - if (BiosRom == null && game["RequireBios"]) - throw new MissingFirmwareException("BIOS image not available. This game requires BIOS to function."); - if (SyncSettings.UseBIOS && BiosRom == null) - CoreComm.Notify("BIOS was selected, but rom image not available. BIOS not enabled."); + if (BiosRom == null) + { + throw new MissingFirmwareException("No BIOS found"); + } + else if (!game["RequireBios"] && !SyncSettings.UseBIOS) + { + // we are skipping the BIOS + // but only if it won't break the game + } + else + { + Port3E = 0xF7; + } } if (game["SRAM"]) diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/LibSaturnus.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/LibSaturnus.cs new file mode 100644 index 0000000000..c8a788a499 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/LibSaturnus.cs @@ -0,0 +1,76 @@ +using BizHawk.Common.BizInvoke; +using BizHawk.Emulation.Cores.Waterbox; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn +{ + public abstract class LibSaturnus : LibWaterboxCore + { + // some of the internal code uses wizardry by which certain pointers in ss.wbx[.text] + // must be greater than or equal to this address, but less than 4GB bigger than it + public const ulong StartAddress = 0x36d00000000; + + [StructLayout(LayoutKind.Sequential)] + public class TOC + { + public int FirstTrack; + public int LastTrack; + public int DiskType; + + [StructLayout(LayoutKind.Sequential)] + public struct Track + { + public int Adr; + public int Control; + public int Lba; + public int Valid; + } + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 101)] + public Track[] Tracks; + } + + [StructLayout(LayoutKind.Sequential)] + public new class FrameInfo : LibWaterboxCore.FrameInfo + { + public int ResetPushed; + } + + [UnmanagedFunctionPointer(CC)] + public delegate int FirmwareSizeCallback(string filename); + [UnmanagedFunctionPointer(CC)] + public delegate void FirmwareDataCallback(string filename, IntPtr dest); + [UnmanagedFunctionPointer(CC)] + public delegate void CDTOCCallback(int disk, [In, Out]TOC toc); + [UnmanagedFunctionPointer(CC)] + public delegate void CDSectorCallback(int disk, int lba, IntPtr dest); + + [BizImport(CC)] + public abstract void SetFirmwareCallbacks(FirmwareSizeCallback sizecallback, FirmwareDataCallback datacallback); + [BizImport(CC)] + public abstract void SetCDCallbacks(CDTOCCallback toccallback, CDSectorCallback sectorcallback); + [BizImport(CC)] + public abstract bool Init( + int numDisks, + Saturnus.SyncSettings.CartType cartType, + Saturnus.SyncSettings.RegionType regionDefault, + bool regionAutodetect); + [BizImport(CC)] + public abstract void HardReset(); + [BizImport(CC)] + public abstract void SetDisk(int disk, bool open); + [BizImport(CC)] + public abstract void SetControllerData(byte[] controllerData); + [BizImport(CC)] + public abstract void SetupInput(int[] portdevices, int[] multitaps); + [BizImport(CC)] + public abstract void SetRtc(long ticks, Saturnus.SyncSettings.LanguageType language); + [BizImport(CC)] + public abstract void SetVideoParameters(bool correctAspect, bool hBlend, bool hOverscan, int sls, int sle); + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/LibYabause.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/LibYabause.cs deleted file mode 100644 index d40788220b..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/LibYabause.cs +++ /dev/null @@ -1,252 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Runtime.InteropServices; - -namespace BizHawk.Emulation.Cores.Sega.Saturn -{ - public static class LibYabause - { - /// - /// A,B,C,Start,DPad - /// - public enum Buttons1 : byte - { - B = 0x01, - C = 0x02, - A = 0x04, - S = 0x08, - U = 0x10, - D = 0x20, - L = 0x40, - R = 0x80 - } - - /// - /// X,Y,Z,Shoulders - /// - public enum Buttons2 : byte - { - L = 0x08, - Z = 0x10, - Y = 0x20, - X = 0x40, - R = 0x80 - } - - /// - /// - /// - /// player1 - /// player1 - /// player2 - /// player2 - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void libyabause_setpads(Buttons1 p11, Buttons2 p12, Buttons1 p21, Buttons2 p22); - - - /// - /// set video buffer - /// - /// 32 bit color, should persist over time. must hold at least 704*512px in software mode, or (704*n*512*n)px - /// in hardware mode with native factor size, or w*hpx in gl mode with explicit size - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void libyabause_setvidbuff(IntPtr buff); - - /// - /// - /// - /// persistent location of s16 interleaved - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void libyabause_setsndbuff(IntPtr buff); - - /// - /// soft reset, or something like that - /// - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void libyabause_softreset(); - - /// - /// hard reset, or something like that - /// - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void libyabause_hardreset(); - - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void InputCallback(); - - /// - /// set a fcn to call every time input is read - /// - /// execxutes right before the input read. null to clear - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void libyabause_setinputcallback(InputCallback cb); - - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void TraceCallback(string dis, string regs); - - /// - /// set a fcn to call every time input is read - /// - /// execxutes right before the input read. null to clear - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void libyabause_settracecallback(TraceCallback cb); - - - /// - /// - /// - /// - /// success - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern bool libyabause_loadstate(string fn); - - /// - /// - /// - /// - /// success - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern bool libyabause_savestate(string fn); - - /// - /// - /// - /// width of framebuffer - /// height of framebuffer - /// number of sample pairs produced - /// true if lagged - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern bool libyabause_frameadvance(out int w, out int h, out int nsamp); - - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void libyabause_deinit(); - - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern bool libyabause_savesaveram(string fn); - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern bool libyabause_loadsaveram(string fn); - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void libyabause_clearsaveram(); - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern bool libyabause_saveramodified(); - - public struct NativeMemoryDomain - { - public IntPtr data; - public string name; - public int length; - } - - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - static extern IntPtr libyabause_getmemoryareas(); - - public static IEnumerable libyabause_getmemoryareas_ex() - { - var ret = new List(); - IntPtr start = libyabause_getmemoryareas(); - while (true) - { - var nmd = (NativeMemoryDomain)Marshal.PtrToStructure(start, typeof(NativeMemoryDomain)); - if (nmd.data == IntPtr.Zero || nmd.name == null) - return ret.AsReadOnly(); - ret.Add(nmd); - start += Marshal.SizeOf(typeof(NativeMemoryDomain)); - } - } - - /// - /// set the overall resolution. only works in gl mode and when nativefactor = 0 - /// - /// width - /// height - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void libyabause_glresize(int w, int h); - - /// - /// cause the overall resolution to automatically switch to a multiple of the original console resolution, as the original console resolution changes. - /// only applies in gl mode. - /// - /// factor, 1-4, 0 to disable. - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void libyabause_glsetnativefactor(int n); - - - public enum CartType : int - { - NONE = 0, - DRAM8MBIT = 6, - DRAM32MBIT = 7 - } - - /// - /// - /// - /// cd interface. struct need not persist after call, but the function pointers better - /// path to bios, pass null to use built in bios emulation - /// true for opengl - /// if true, skip bios opening - /// if true, sync RTC to actual emulated time; if false, use real real time - /// if non-zero, initial emulation time in unix format - /// - [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern bool libyabause_init(ref CDInterface intf, string biosfn, bool usegl, CartType carttype, bool quickload, bool clocksync, int clockbase); - - public struct CDInterface - { - public int DontTouch; - public IntPtr DontTouch2; - /// - /// init cd functions - /// - /// - /// 0 on success, -1 on failure - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int Init(string unused); - public Init InitFunc; - /// - /// deinit cd functions - /// - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void DeInit(); - public DeInit DeInitFunc; - /// - /// 0 = cd present, spinning - /// 1 = cd present, not spinning - /// 2 = no cd - /// 3 = tray open - /// - /// - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int GetStatus(); - public GetStatus GetStatusFunc; - /// - /// read all TOC entries - /// - /// place to copy to - /// number of bytes written. should be 408 - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int ReadTOC(IntPtr dest); - public ReadTOC ReadTOCFunc; - /// - /// read a sector, should be 2352 bytes - /// - /// - /// - /// - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int ReadSectorFAD(int FAD, IntPtr dest); - public ReadSectorFAD ReadSectorFADFunc; - /// - /// hint the next sector, for async loading - /// - /// - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void ReadAheadFAD(int FAD); - public ReadAheadFAD ReadAheadFADFunc; - } - } -} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Saturnus.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Saturnus.cs new file mode 100644 index 0000000000..be7a4aa87a --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Saturnus.cs @@ -0,0 +1,568 @@ +using BizHawk.Common; +using BizHawk.Common.BizInvoke; +using BizHawk.Common.BufferExtensions; +using BizHawk.Emulation.Common; +using BizHawk.Emulation.Cores.Waterbox; +using BizHawk.Emulation.DiscSystem; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn +{ + [CoreAttributes("Saturnus", "Ryphecha", true, false, "0.9.44.1", + "https://mednafen.github.io/releases/", false)] + public class Saturnus : WaterboxCore, + IDriveLight, IRegionable, + ISettable + { + private static readonly DiscSectorReaderPolicy _diskPolicy = new DiscSectorReaderPolicy + { + DeinterleavedSubcode = false + }; + + private LibSaturnus _core; + private Disc[] _disks; + private DiscSectorReader[] _diskReaders; + private bool _isPal; + private SaturnusControllerDeck _controllerDeck; + private int _activeDisk; + private bool _prevDiskSignal; + private bool _nextDiskSignal; + + private static bool CheckDisks(IEnumerable readers) + { + var buff = new byte[2048 * 16]; + foreach (var r in readers) + { + for (int i = 0; i < 16; i++) + { + if (r.ReadLBA_2048(i, buff, 2048 * i) != 2048) + return false; + } + + if (Encoding.ASCII.GetString(buff, 0, 16) != "SEGA SEGASATURN ") + return false; + + using (var sha256 = SHA256.Create()) + { + sha256.ComputeHash(buff, 0x100, 0xd00); + if (sha256.Hash.BytesToHexString() != "96B8EA48819CFA589F24C40AA149C224C420DCCF38B730F00156EFE25C9BBC8F") + return false; + } + } + return true; + } + + public Saturnus(CoreComm comm, IEnumerable disks, bool deterministic, Settings settings, + SyncSettings syncSettings) + :base(comm, new Configuration + { + MaxSamples = 8192, + DefaultWidth = 320, + DefaultHeight = 240, + MaxWidth = 1024, + MaxHeight = 1024, + SystemId = "SAT" + }) + { + settings = settings ?? new Settings(); + syncSettings = syncSettings ?? new SyncSettings(); + + _disks = disks.ToArray(); + _diskReaders = disks.Select(d => new DiscSectorReader(d) { Policy = _diskPolicy }).ToArray(); + if (!CheckDisks(_diskReaders)) + throw new InvalidOperationException("Some disks are not valid"); + InitCallbacks(); + + _core = PreInit(new PeRunnerOptions + { + Filename = "ss.wbx", + SbrkHeapSizeKB = 128, + SealedHeapSizeKB = 4096, // 512KB of bios, 2MB of kof95/ultraman carts + InvisibleHeapSizeKB = 8 * 1024, // 4MB of framebuffer + MmapHeapSizeKB = 0, // not used? + PlainHeapSizeKB = 24 * 1024, // up to 16MB of cart ram + StartAddress = LibSaturnus.StartAddress + }); + + SetFirmwareCallbacks(); + SetCdCallbacks(); + + if (!_core.Init(_disks.Length, syncSettings.ExpansionCart, syncSettings.Region, syncSettings.RegionAutodetect)) + throw new InvalidOperationException("Core rejected the disks!"); + ClearAllCallbacks(); + + _controllerDeck = new SaturnusControllerDeck(new[] + { + syncSettings.Port1Multitap, + syncSettings.Port2Multitap + }, new[] + { + syncSettings.Port1, + syncSettings.Port2, + syncSettings.Port3, + syncSettings.Port4, + syncSettings.Port5, + syncSettings.Port6, + syncSettings.Port7, + syncSettings.Port8, + syncSettings.Port9, + syncSettings.Port10, + syncSettings.Port11, + syncSettings.Port12 + }, _core); + ControllerDefinition = _controllerDeck.Definition; + ControllerDefinition.Name = "Saturn Controller"; + ControllerDefinition.BoolButtons.AddRange(new[] + { + "Power", "Reset", "Previous Disk", "Next Disk" + }); + + _core.SetRtc((long)syncSettings.InitialTime.Subtract(new DateTime(1970, 1, 1)).TotalSeconds, + syncSettings.Language); + + PostInit(); + SetCdCallbacks(); + _core.SetDisk(0, false); + PutSettings(settings); + _syncSettings = syncSettings; + DeterministicEmulation = deterministic || !_syncSettings.UseRealTime; + } + + protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound) + { + var prevDiskSignal = controller.IsPressed("Previous Disk"); + var nextDiskSignal = controller.IsPressed("Next Disk"); + var newDisk = _activeDisk; + if (prevDiskSignal && !_prevDiskSignal) + newDisk--; + if (nextDiskSignal && !_nextDiskSignal) + newDisk++; + _prevDiskSignal = prevDiskSignal; + _nextDiskSignal = nextDiskSignal; + if (newDisk < -1) + newDisk = -1; + if (newDisk >= _disks.Length) + newDisk = _disks.Length - 1; + if (newDisk != _activeDisk) + { + _core.SetDisk(newDisk == -1 ? 0 : newDisk, newDisk == -1); + _activeDisk = newDisk; + } + + // if not reset, the core will maintain its own deterministic increasing time each frame + if (!DeterministicEmulation) + { + _core.SetRtc((long)DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds, + _syncSettings.Language); + } + + DriveLightOn = false; + if (controller.IsPressed("Power")) + _core.HardReset(); + + _core.SetControllerData(_controllerDeck.Poll(controller)); + + return new LibSaturnus.FrameInfo { ResetPushed = controller.IsPressed("Reset") ? 1 : 0 }; + } + + public DisplayType Region => _isPal ? DisplayType.PAL : DisplayType.NTSC; + + #region ISettable + + public class Settings + { + // extern bool setting_ss_correct_aspect; + [DefaultValue(true)] + public bool CorrectAspectRatio { get; set; } + + // extern bool setting_ss_h_blend; + [DisplayName("Horizontal Blend")] + [DefaultValue(false)] + [Description("Use horizontal blend filter")] + public bool HBlend { get; set; } + + // extern bool setting_ss_h_overscan; + [DisplayName("Horizontal Overscan")] + [DefaultValue(true)] + [Description("Show horiziontal overscan area")] + public bool HOverscan { get; set; } + + // extern int setting_ss_slstart; + [DefaultValue(0)] + [Description("First scanline to display in NTSC mode")] + [Range(0, 239)] + public int ScanlineStartNtsc { get; set; } + // extern int setting_ss_slend; + [DefaultValue(239)] + [Description("Last scanline to display in NTSC mode")] + [Range(0, 239)] + public int ScanlineEndNtsc { get; set; } + // extern int setting_ss_slstartp; + [DefaultValue(0)] + [Description("First scanline to display in PAL mode")] + [Range(-16, 271)] + public int ScanlineStartPal { get; set; } + // extern int setting_ss_slendp; + [DefaultValue(255)] + [Description("Last scanline to display in PAL mode")] + [Range(-16, 271)] + public int ScanlineEndPal { get; set; } + + public Settings() + { + SettingsUtil.SetDefaultValues(this); + } + + public Settings Clone() + { + return (Settings)MemberwiseClone(); + } + + public static bool NeedsReboot(Settings x, Settings y) + { + return false; + } + } + + public class SyncSettings + { + public enum CartType + { + [Display(Name = "Autodetect. Will use Backup Ram Cart if no others are appropriate")] + Autodetect = -1, + [Display(Name = "None")] + None, + [Display(Name = "Backup Ram Cart")] + Backup, + [Display(Name = "1 Meg Ram Cart")] + Ram1Meg, + [Display(Name = "4 Meg Ram Cart")] + Ram4Meg, + [Display(Name = "King of Fighters 95 Rom Cart")] + Kof95, + [Display(Name = "Ultraman Rom Cart")] + Ultraman, + [Display(Name = "CS1 16 Meg Ram Cart")] + Ram16Meg + } + + // extern int setting_ss_cart; + [DefaultValue(CartType.Autodetect)] + [Description("What to plug into the Saturn expansion slot")] + public CartType ExpansionCart { get; set; } + + [DisplayName("Port 1 Device")] + [DefaultValue(SaturnusControllerDeck.Device.Gamepad)] + [TypeConverter(typeof(DescribableEnumConverter))] + public SaturnusControllerDeck.Device Port1 { get; set; } + + [DisplayName("Port 2 Device")] + [DefaultValue(SaturnusControllerDeck.Device.Gamepad)] + [TypeConverter(typeof(DescribableEnumConverter))] + public SaturnusControllerDeck.Device Port2 { get; set; } + + [DisplayName("Port 3 Device")] + [DefaultValue(SaturnusControllerDeck.Device.None)] + [Description("Only used if one or both multitaps are set")] + [TypeConverter(typeof(DescribableEnumConverter))] + public SaturnusControllerDeck.Device Port3 { get; set; } + + [DisplayName("Port 4 Device")] + [DefaultValue(SaturnusControllerDeck.Device.None)] + [Description("Only used if one or both multitaps are set")] + [TypeConverter(typeof(DescribableEnumConverter))] + public SaturnusControllerDeck.Device Port4 { get; set; } + + [DisplayName("Port 5 Device")] + [DefaultValue(SaturnusControllerDeck.Device.None)] + [Description("Only used if one or both multitaps are set")] + [TypeConverter(typeof(DescribableEnumConverter))] + public SaturnusControllerDeck.Device Port5 { get; set; } + + [DisplayName("Port 6 Device")] + [DefaultValue(SaturnusControllerDeck.Device.None)] + [Description("Only used if one or both multitaps are set")] + [TypeConverter(typeof(DescribableEnumConverter))] + public SaturnusControllerDeck.Device Port6 { get; set; } + + [DisplayName("Port 7 Device")] + [DefaultValue(SaturnusControllerDeck.Device.None)] + [Description("Only used if one or both multitaps are set")] + [TypeConverter(typeof(DescribableEnumConverter))] + public SaturnusControllerDeck.Device Port7 { get; set; } + + [DisplayName("Port 8 Device")] + [DefaultValue(SaturnusControllerDeck.Device.None)] + [Description("Only used if both multitaps are set")] + [TypeConverter(typeof(DescribableEnumConverter))] + public SaturnusControllerDeck.Device Port8 { get; set; } + + [DisplayName("Port 9 Device")] + [DefaultValue(SaturnusControllerDeck.Device.None)] + [Description("Only used if both multitaps are set")] + [TypeConverter(typeof(DescribableEnumConverter))] + public SaturnusControllerDeck.Device Port9 { get; set; } + + [DisplayName("Port 10 Device")] + [DefaultValue(SaturnusControllerDeck.Device.None)] + [Description("Only used if both multitaps are set")] + [TypeConverter(typeof(DescribableEnumConverter))] + public SaturnusControllerDeck.Device Port10 { get; set; } + + [DisplayName("Port 11 Device")] + [DefaultValue(SaturnusControllerDeck.Device.None)] + [Description("Only used if both multitaps are set")] + [TypeConverter(typeof(DescribableEnumConverter))] + public SaturnusControllerDeck.Device Port11 { get; set; } + + [DisplayName("Port 12 Device")] + [DefaultValue(SaturnusControllerDeck.Device.None)] + [Description("Only used if both multitaps are set")] + [TypeConverter(typeof(DescribableEnumConverter))] + public SaturnusControllerDeck.Device Port12 { get; set; } + + [DisplayName("Port 1 Multitap")] + [Description("If true, Ports 1-6 will be used for multitap")] + [DefaultValue(false)] + public bool Port1Multitap { get; set; } + [DisplayName("Port 2 Multitap")] + [Description("If true, Ports 2-7 (or 7-12, depending on Port 1 Multitap) will be used for multitap")] + [DefaultValue(false)] + public bool Port2Multitap { get; set; } + + // extern bool setting_ss_region_autodetect; + [DisplayName("Region Autodetect")] + [Description("Attempt to guess the game region")] + [DefaultValue(true)] + public bool RegionAutodetect { get; set; } + + public enum RegionType + { + [Display(Name = "Japan")] + Japan = 1, + [Display(Name = "Asia NTSC (Taiwan, Phillipines)")] + Taiwan = 2, + [Display(Name = "North America")] + Murka = 4, + [Display(Name = "Latin America NTSC (Brazil)")] + Brazil = 5, + [Display(Name = "South Korea")] + Korea = 6, + [Display(Name = "Asia PAL (China, Middle East)")] + China = 10, + [Display(Name = "Europe")] + Yurop = 12, + [Display(Name = "Latin America PAL")] + SouthAmerica = 13 + } + + // extern int setting_ss_region_default; + [DisplayName("Default Region")] + [Description("Used when Region Autodetect is disabled or fails")] + [DefaultValue(RegionType.Japan)] + [TypeConverter(typeof(DescribableEnumConverter))] + public RegionType Region { get; set; } + + public enum LanguageType + { + English = 0, + German = 1, + French = 2, + Spanish = 3, + Italian = 4, + Japanese = 5, + } + + [DisplayName("Language")] + [Description("Language of the system. Only affects some games in some regions.")] + [DefaultValue(LanguageType.Japanese)] + public LanguageType Language { get; set; } + + [DisplayName("Initial Time")] + [Description("Initial time of emulation. Only relevant when UseRealTime is false.")] + [DefaultValue(typeof(DateTime), "2010-01-01")] + public DateTime InitialTime { get; set; } + + [DisplayName("Use RealTime")] + [Description("If true, RTC clock will be based off of real time instead of emulated time. Ignored (set to false) when recording a movie.")] + [DefaultValue(false)] + public bool UseRealTime { get; set; } + + public SyncSettings() + { + SettingsUtil.SetDefaultValues(this); + } + + public SyncSettings Clone() + { + return (SyncSettings)MemberwiseClone(); + } + + public static bool NeedsReboot(SyncSettings x, SyncSettings y) + { + return !DeepEquality.DeepEquals(x, y); + } + } + + private Settings _settings; + private SyncSettings _syncSettings; + + public Settings GetSettings() + { + return _settings.Clone(); + } + + public bool PutSettings(Settings s) + { + var ret = Settings.NeedsReboot(_settings, s); + _settings = s; + var sls = _isPal ? s.ScanlineStartPal + 16 : s.ScanlineStartNtsc; + var sle = _isPal ? s.ScanlineEndPal + 16 : s.ScanlineEndNtsc; + _core.SetVideoParameters(s.CorrectAspectRatio, s.HBlend, s.HOverscan, sls, sle); + return ret; + } + + public SyncSettings GetSyncSettings() + { + return _syncSettings.Clone(); + } + + public bool PutSyncSettings(SyncSettings s) + { + var ret = SyncSettings.NeedsReboot(_syncSettings, s); + _syncSettings = s; + return ret; + } + + #endregion + + #region IStatable + + protected override void SaveStateBinaryInternal(BinaryWriter writer) + { + writer.Write(_activeDisk); + writer.Write(_prevDiskSignal); + writer.Write(_nextDiskSignal); + } + + protected override void LoadStateBinaryInternal(BinaryReader reader) + { + _activeDisk = reader.ReadInt32(); + _prevDiskSignal = reader.ReadBoolean(); + _nextDiskSignal = reader.ReadBoolean(); + // any managed pointers that we sent to the core need to be resent now! + SetCdCallbacks(); + } + + #endregion + + #region Callbacks + + private LibSaturnus.FirmwareSizeCallback _firmwareSizeCallback; + private LibSaturnus.FirmwareDataCallback _firmwareDataCallback; + private LibSaturnus.CDTOCCallback _cdTocCallback; + private LibSaturnus.CDSectorCallback _cdSectorCallback; + + private void InitCallbacks() + { + _firmwareSizeCallback = FirmwareSize; + _firmwareDataCallback = FirmwareData; + _cdTocCallback = CDTOCCallback; + _cdSectorCallback = CDSectorCallback; + } + + private void SetFirmwareCallbacks() + { + _core.SetFirmwareCallbacks(_firmwareSizeCallback, _firmwareDataCallback); + } + private void SetCdCallbacks() + { + _core.SetCDCallbacks(_cdTocCallback, _cdSectorCallback); + } + private void ClearAllCallbacks() + { + _core.SetFirmwareCallbacks(null, null); + _core.SetCDCallbacks(null, null); + _core.SetInputCallback(null); + } + + private string TranslateFirmwareName(string filename) + { + switch (filename) + { + case "ss.cart.kof95_path": + return "KOF95"; + case "ss.cart.ultraman_path": + return "ULTRAMAN"; + case "BIOS_J": + case "BIOS_A": + return "J"; + case "BIOS_E": + _isPal = true; + return "E"; + case "BIOS_U": + return "U"; + default: + throw new InvalidOperationException("Unknown BIOS file"); + } + } + private byte[] GetFirmware(string filename) + { + return CoreComm.CoreFileProvider.GetFirmware("SAT", TranslateFirmwareName(filename), true); + } + + private int FirmwareSize(string filename) + { + return GetFirmware(filename).Length; + } + private void FirmwareData(string filename, IntPtr dest) + { + var data = GetFirmware(filename); + Marshal.Copy(data, 0, dest, data.Length); + } + + private void CDTOCCallback(int disk, [In, Out]LibSaturnus.TOC t) + { + // everything that's not commented, we're sure about + var tin = _disks[disk].TOC; + t.FirstTrack = tin.FirstRecordedTrackNumber; + t.LastTrack = tin.LastRecordedTrackNumber; + t.DiskType = (int)tin.Session1Format; + for (int i = 0; i < 101; i++) + { + t.Tracks[i].Adr = tin.TOCItems[i].Exists ? 1 : 0; // ???? + t.Tracks[i].Lba = tin.TOCItems[i].LBA; + t.Tracks[i].Control = (int)tin.TOCItems[i].Control; + t.Tracks[i].Valid = tin.TOCItems[i].Exists ? 1 : 0; + } + } + private void CDSectorCallback(int disk, int lba, IntPtr dest) + { + var buff = new byte[2448]; + _diskReaders[disk].ReadLBA_2448(lba, buff, 0); + Marshal.Copy(buff, 0, dest, 2448); + DriveLightOn = true; + } + + public bool DriveLightEnabled => true; + public bool DriveLightOn { get; private set; } + + #endregion + + private const int PalFpsNum = 1734687500; + private const int PalFpsDen = 61 * 455 * 1251; + private const int NtscFpsNum = 1746818182; // 1746818181.8 + private const int NtscFpsDen = 61 * 455 * 1051; + public override int VsyncNumerator => _isPal ? PalFpsNum : NtscFpsNum; + public override int VsyncDenominator => _isPal ? PalFpsDen : NtscFpsDen; + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/SaturnusControllerDeck.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/SaturnusControllerDeck.cs new file mode 100644 index 0000000000..03ddcbfefb --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/SaturnusControllerDeck.cs @@ -0,0 +1,675 @@ +using BizHawk.Emulation.Common; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static BizHawk.Emulation.Common.ControllerDefinition; + +namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn +{ + public class SaturnusControllerDeck + { + private const int DataSize = 32; + + private static readonly Type[] Implementors = + { + typeof(None), + typeof(Gamepad), + typeof(ThreeDeeGamepad), + typeof(Mouse), + typeof(Wheel), + typeof(Mission), + typeof(DualMission), + typeof(Keyboard) + }; + + private readonly IDevice[] _devices; + private readonly ControlDefUnMerger[] _unmerger; + private readonly byte[] _data; + + public ControllerDefinition Definition { get; } + + public SaturnusControllerDeck(bool[] multitap, Device[] devices, LibSaturnus core) + { + int count = 2 + multitap.Count(b => b) * 5; + + int[] dev = new int[12]; + int[] mt = new int[2]; + + for (int i = 0; i < 12; i++) + dev[i] = (int)(i < count ? devices[i] : Device.None); + for (int i = 0; i < 2; i++) + mt[i] = multitap[i] ? 1 : 0; + + core.SetupInput(dev, mt); + + _devices = dev.Take(count) + .Select(i => Activator.CreateInstance(Implementors[i])) + .Cast() + .ToArray(); + _data = new byte[count * DataSize]; + + List cdum; + Definition = ControllerDefinitionMerger.GetMerged(_devices.Select(d => d.Definition), + out cdum); + _unmerger = cdum.ToArray(); + } + + public byte[] Poll(IController controller) + { + for (int i = 0, offset = 0; i < _devices.Length; i++, offset += DataSize) + _devices[i].Update(_unmerger[i].UnMerge(controller), _data, offset); + return _data; + } + + public enum Device + { + None, + Gamepad, + [Display(Name = "3D Pad")] + ThreeDeePad, + Mouse, + [Display(Name = "Racing Controller")] + Wheel, + [Display(Name = "Mission Stick")] + Mission, + [Display(Name = "Two Mission Sticks")] + DualMission, + Keyboard + } + + private interface IDevice + { + void Update(IController controller, byte[] dest, int offset); + ControllerDefinition Definition { get; } + } + + private class None : IDevice + { + private static readonly ControllerDefinition NoneDefition = new ControllerDefinition(); + public ControllerDefinition Definition => NoneDefition; + public void Update(IController controller, byte[] dest, int offset) + { + } + + } + + private abstract class ButtonedDevice : IDevice + { + private static readonly FloatRange AnalogFloatRange = new FloatRange(0, 128, 255); + + protected ButtonedDevice() + { + _bakedButtonNames = ButtonNames.Select(s => s != null ? "0" + s : null).ToArray(); + _bakedAnalogNames = AnalogNames.Select(s => "0" + s).ToArray(); + + Definition = new ControllerDefinition + { + BoolButtons = _bakedButtonNames + .Select((s, i) => new { s, i }) + .Where(a => a.s != null) + .OrderBy(a => ButtonOrdinal(ButtonNames[a.i])) + .Select(a => a.s) + .ToList(), + }; + Definition.FloatControls.AddRange(_bakedAnalogNames + .Select((s, i) => new { s, i }) + .OrderBy(a => AnalogOrdinal(AnalogNames[a.i])) + .Select(a => a.s)); + Definition.FloatRanges.AddRange(_bakedAnalogNames.Select(s => AnalogFloatRange)); + } + + private readonly string[] _bakedButtonNames; + private readonly string[] _bakedAnalogNames; + + protected virtual string[] ButtonNames { get; } = new string[0]; + protected virtual int ButtonByteOffset { get; } = 0; + protected virtual string[] AnalogNames { get; } = new string[0]; + protected virtual int AnalogByteOffset => (ButtonNames.Length + 7) / 8; + public ControllerDefinition Definition { get; } + + protected virtual int ButtonOrdinal(string name) + { + return 0; + } + protected virtual int AnalogOrdinal(string name) + { + return 0; + } + + private void UpdateButtons(IController controller, byte[] dest, int offset) + { + int pos = offset + ButtonByteOffset; + byte data = 0; + int bit = 0; + for (int i = 0; i < _bakedButtonNames.Length; i++) + { + if (_bakedButtonNames[i] != null && controller.IsPressed(_bakedButtonNames[i])) + data |= (byte)(1 << bit); + if (++bit == 8) + { + bit = 0; + dest[pos++] = data; + data = 0; + } + } + if (bit != 0) + dest[pos] = data; + } + + private void UpdateAnalogs(IController controller, byte[] dest, int offset) + { + int pos = offset + AnalogByteOffset; + for (int i = 0; i < _bakedAnalogNames.Length; i++) + { + var data = (byte)(int)controller.GetFloat(_bakedAnalogNames[i]); + dest[pos++] = data; + } + } + + + public virtual void Update(IController controller, byte[] dest, int offset) + { + UpdateButtons(controller, dest, offset); + UpdateAnalogs(controller, dest, offset); + } + } + + private class Gamepad : ButtonedDevice + { + private static readonly string[] _buttonNames = + { + "Z", "Y", "X", "R", + "Up", "Down", "Left", "Right", + "B", "C", "A", "Start", + null, null, null, "L" + }; + + protected override string[] ButtonNames => _buttonNames; + + protected override int ButtonOrdinal(string name) + { + switch (name) + { + default: + return 0; + case "A": + return 1; + case "B": + case "C": + return 2; + case "X": + return 3; + case "Y": + return 4; + case "Z": + case "L": + return 5; + case "R": + return 6; + } + } + } + + private class ThreeDeeGamepad : ButtonedDevice + { + private static readonly string[] _buttonNames = + { + "Up", "Down", "Left", "Right", + "B", "C", "A", "Start", + "Z", "Y", "X" + }; + + protected override string[] ButtonNames => _buttonNames; + + private static readonly string[] _analogNames = + { + "Stick Horizontal", + "Stick Vertical", + "Left Shoulder", + "Right Shoulder" + }; + + protected override string[] AnalogNames => _analogNames; + + public ThreeDeeGamepad() + { + Definition.FloatRanges[2] = new FloatRange(0, 0, 255); + Definition.FloatRanges[3] = new FloatRange(0, 0, 255); + } + + public override void Update(IController controller, byte[] dest, int offset) + { + base.Update(controller, dest, offset); + // set the "Mode" button to analog at all times + dest[offset + 1] |= 0x10; + } + + protected override int ButtonOrdinal(string name) + { + switch (name) + { + default: + return 0; + case "A": + return 1; + case "B": + case "C": + return 2; + case "X": + return 3; + case "Y": + return 4; + case "Z": + return 5; + } + } + } + + private class Mouse : ButtonedDevice + { + private static readonly string[] _buttonNames = + { + "Mouse Left", "Mouse Right", "Mouse Center", "Start" + }; + + protected override string[] ButtonNames => _buttonNames; + + private static readonly string[] _analogNames = + { + "X", "Y" + }; + + protected override string[] AnalogNames => _analogNames; + + protected override int ButtonOrdinal(string name) + { + switch (name) + { + default: + case "Mouse Left": + return 0; + case "Mouse Center": + return 1; + case "Mouse Right": + return 2; + case "Start": + return 3; + } + } + } + + private class Wheel : ButtonedDevice + { + private static readonly string[] _buttonNames = + { + "Up", "Down", null, null, + "B", "C", "A", "Start", + "Z", "Y", "X" + }; + + protected override string[] ButtonNames => _buttonNames; + + private static readonly string[] _analogNames = + { + "Wheel" + }; + + protected override string[] AnalogNames => _analogNames; + + protected override int ButtonOrdinal(string name) + { + switch (name) + { + default: + return 0; + case "A": + return 1; + case "B": + case "C": + return 2; + case "X": + return 3; + case "Y": + return 4; + case "Z": + return 5; + } + } + } + + private class Mission : ButtonedDevice + { + private static readonly string[] _buttonNames = + { + "B", "C", "A", "Start", + "Z", "Y", "X", "R", + null, null, null, "L" + }; + + protected override string[] ButtonNames => _buttonNames; + + private static readonly string[] _analogNames = + { + "Stick Horizontal", + "Stick Vertical", + "Throttle" + }; + + protected override string[] AnalogNames => _analogNames; + protected override int AnalogByteOffset => 4; + + protected override int ButtonOrdinal(string name) + { + switch (name) + { + default: + return 0; + case "Start": + return 1; + case "A": + return 2; + case "B": + case "C": + return 3; + case "X": + return 4; + case "Y": + return 5; + case "Z": + case "L": + return 6; + case "R": + return 7; + } + } + } + + private class DualMission : Mission + { + private static readonly string[] _analogNames = + { + "Right Stick Horizontal", + "Right Stick Vertical", + "Right Throttle", + "Left Stick Horizontal", + "Left Stick Vertical", + "Left Throttle" + }; + + protected override string[] AnalogNames => _analogNames; + } + + private class Keyboard : ButtonedDevice + { + // TODO: LEDs, which are actually data sent back by the core + private static readonly string[] _buttonNames = + { + null, + "F9", + null, + "F5", + "F3", + "F1", + "F2", + "F12", + null, + "F10", + "F8", + "F6", + "F4", + "Tab", + "Grave`", + null, + null, + "LeftAlt", + "LeftShift", + null, + "LeftCtrl", + "Q", + "1(One)", + "RightAlt", + "RightCtrl", + "KeypadEnter", + "Z(Key)", + "S", + "A(Key)", + "W", + "2", + null, + null, + "C(Key)", + "X(Key)", + "D", + "E", + "4", + "3", + null, + null, + "Space", + "V", + "F", + "T", + "R(Key)", + "5", + null, + null, + "N", + "B(Key)", + "H", + "G", + "Y(Key)", + "6", + null, + null, + null, + "M", + "J", + "U", + "7", + "8", + null, + null, + "Comma,", + "K", + "I", + "O", + "0(Zero)", + "9", + null, + null, + "Period.", + "Slash/", + "L(Key)", + "Semicolon;", + "P", + "Minus-", + null, + null, + null, + "Quote'", + null, + "LeftBracket[", + "Equals=", + null, + null, + "CapsLock", + "RightShift", + "Enter", + "RightBracket]", + null, + "Backslash\\", + null, + null, + null, + null, + null, + null, + null, + null, + "Backspace", + null, + null, + "KeypadEnd/1", + null, + "KeypadLeft/4", + "KeypadHome/7", + null, + null, + null, + "KeypadInsert/0", + "KeypadDelete", + "KeypadDown/2", + "KeypadCenter/5", + "KeypadRight/6", + "KeypadUp/8", + "Escape", + "NumLock", + "F11", + "KeypadPlus", + "KeypadPagedown/3", + "KeypadMinus", + "KeypadAsterisk(Multiply)", + "KeypadPageup/9", + "ScrollLock", + null, + "KeypadSlash(Divide)", + "Insert", + "Pause", + "F7", + "PrintScreen", + "Delete", + "CursorLeft", + "Home", + "End", + "Up", + "Down", + "PageUp", + "PageDown", + "Right", + }; + + protected override string[] ButtonNames => _buttonNames; + + protected override int ButtonOrdinal(string name) + { + switch (name) + { + default: return 0; + case "Escape": return 1; + case "F1": return 2; + case "F2": return 3; + case "F3": return 4; + case "F4": return 5; + case "F5": return 6; + case "F6": return 7; + case "F7": return 8; + case "F8": return 9; + case "F9": return 10; + case "F10": return 11; + case "F11": return 12; + case "F12": return 13; + + case "Grave`": return 100; + case "1(One)": return 101; + case "2": return 102; + case "3": return 103; + case "4": return 104; + case "5": return 105; + case "6": return 106; + case "7": return 107; + case "8": return 108; + case "9": return 109; + case "0(Zero)": return 110; + case "Minus-": return 111; + case "Equals=": return 112; + case "Backslash\\": return 113; + case "Backspace": return 114; + + case "Tab": return 200; + case "Q": return 201; + case "W": return 202; + case "E": return 203; + case "R(Key)": return 204; + case "T": return 205; + case "Y(Key)": return 206; + case "U": return 207; + case "I": return 208; + case "O": return 209; + case "P": return 210; + case "LeftBracket[": return 211; + case "RightBracket]": return 212; + case "Enter": return 213; + + case "CapsLock": return 300; + case "A(Key)": return 301; + case "S": return 302; + case "D": return 303; + case "F": return 304; + case "G": return 305; + case "H": return 306; + case "J": return 307; + case "K": return 308; + case "L(Key)": return 309; + case "Semicolon;": return 310; + case "Quote'": return 311; + + case "LeftShift": return 400; + case "Z(Key)": return 401; + case "X(Key)": return 402; + case "C(Key)": return 403; + case "V": return 404; + case "B(Key)": return 405; + case "N": return 406; + case "M": return 407; + case "Comma,": return 408; + case "Period.": return 409; + case "Slash/": return 410; + case "RightShift": return 411; + + case "LeftCtrl": return 500; + case "LeftAlt": return 501; + case "Space": return 502; + case "RightAlt": return 503; + case "RightCtrl": return 504; + + case "PrintScreen": return 1000; + case "ScrollLock": return 1001; + case "Pause": return 1002; + + case "Insert": return 1100; + case "Delete": return 1101; + case "Home": return 1102; + case "End": return 1103; + case "PageUp": return 1104; + case "PageDown": return 1105; + + case "Up": return 1200; + case "Down": return 1201; + case "CursorLeft": return 1202; + case "Right": return 1203; + + case "NumLock": return 1300; + case "KeypadSlash(Divide)": return 1301; + case "KeypadAsterisk(Multiply)": return 1302; + case "KeypadMinus": return 1303; + case "KeypadHome/7": return 1304; + case "KeypadUp/8": return 1305; + case "KeypadPageup/9": return 1306; + case "KeypadPlus": return 1307; + case "KeypadLeft/4": return 1308; + case "KeypadCenter/5": return 1309; + case "KeypadRight/6": return 1310; + case "KeypadEnd/1": return 1311; + case "KeypadDown/2": return 1312; + case "KeypadPagedown/3": return 1313; + case "KeypadEnter": return 1314; + case "KeypadInsert/0": return 1315; + case "KeypadDelete": return 1316; + } + } + } + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.IDriveLight.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.IDriveLight.cs deleted file mode 100644 index 61a03e64cd..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.IDriveLight.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Sega.Saturn -{ - public partial class Yabause : IDriveLight - { - public bool DriveLightEnabled { get; private set; } - public bool DriveLightOn { get; private set; } - } -} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.IInputPollable.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.IInputPollable.cs deleted file mode 100644 index 76fcd17db9..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.IInputPollable.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Sega.Saturn -{ - public partial class Yabause : IInputPollable - { - public int LagCount { get; set; } - - public bool IsLagFrame { get; set; } - - // TODO: optimize managed to unmanaged using the ActiveChanged event - public IInputCallbackSystem InputCallbacks - { - [FeatureNotImplemented]get { return _inputCallbacks; } - } - - private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); - } -} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.IMemoryDomains.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.IMemoryDomains.cs deleted file mode 100644 index 137e02fbb2..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.IMemoryDomains.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Collections.Generic; -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Sega.Saturn -{ - public partial class Yabause - { - private IMemoryDomains _memoryDomains; - - private void InitMemoryDomains() - { - var ret = new List(); - var nmds = LibYabause.libyabause_getmemoryareas_ex(); - foreach (var nmd in nmds) - { - ret.Add(new MemoryDomainIntPtr(nmd.name, MemoryDomain.Endian.Little, nmd.data, nmd.length, true, 4)); - } - - // main memory is in position 2 - _memoryDomains = new MemoryDomainList(ret); - _memoryDomains.MainMemory = _memoryDomains["Work Ram Low"]; - - (ServiceProvider as BasicServiceProvider).Register(_memoryDomains); - } - } -} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.ISaveram.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.ISaveram.cs deleted file mode 100644 index 2bfa01d413..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.ISaveram.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Sega.Saturn -{ - public partial class Yabause : ISaveRam - { - public byte[] CloneSaveRam() - { - if (Disposed) - { - if (DisposedSaveRam != null) - { - return (byte[])DisposedSaveRam.Clone(); - } - else - { - return new byte[0]; - } - } - else - { - var ms = new MemoryStream(); - var fp = new FilePiping(); - fp.Get(ms); - bool success = LibYabause.libyabause_savesaveram(fp.GetPipeNameNative()); - fp.Finish(); - if (!success) - throw new Exception("libyabause_savesaveram() failed!"); - var ret = ms.ToArray(); - ms.Dispose(); - return ret; - } - - } - - public void StoreSaveRam(byte[] data) - { - if (Disposed) - { - throw new Exception("It's a bit late for that"); - } - else - { - var fp = new FilePiping(); - fp.Offer(data); - bool success = LibYabause.libyabause_loadsaveram(fp.GetPipeNameNative()); - fp.Finish(); - if (!success) - { - throw new Exception("libyabause_loadsaveram() failed!"); - } - } - } - - public bool SaveRamModified - { - get - { - if (Disposed) - { - return DisposedSaveRam != null; - } - else - { - return LibYabause.libyabause_saveramodified(); - } - } - } - } -} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.ISettable.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.ISettable.cs deleted file mode 100644 index be59406e53..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.ISettable.cs +++ /dev/null @@ -1,135 +0,0 @@ -using System; -using System.ComponentModel; -using Newtonsoft.Json; - -using BizHawk.Common; -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Sega.Saturn -{ - public partial class Yabause : ISettable - { - public object GetSettings() - { - return null; - } - - public SaturnSyncSettings GetSyncSettings() - { - return SyncSettings.Clone(); - } - - public bool PutSettings(object o) - { - return false; - } - - public bool PutSyncSettings(SaturnSyncSettings o) - { - bool ret = SaturnSyncSettings.NeedsReboot(SyncSettings, o); - - SyncSettings = o; - - if (GLMode && SyncSettings.UseGL) - { - if (SyncSettings.DispFree) - { - SetGLRes(0, SyncSettings.GLW, SyncSettings.GLH); - } - else - { - SetGLRes(SyncSettings.DispFactor, 0, 0); - } - } - - return ret; - } - - private SaturnSyncSettings SyncSettings; - - public class SaturnSyncSettings - { - [DisplayName("Open GL Mode")] - [Description("Use OpenGL mode for rendering instead of software.")] - [DefaultValue(false)] - public bool UseGL { get; set; } - - [DisplayName("Display Factor")] - [Description("In OpenGL mode, the internal resolution as a multiple of the normal internal resolution (1x, 2x, 3x, 4x). Ignored in software mode or when a custom resolution is used.")] - [DefaultValue(1)] - public int DispFactor - { - get { return _DispFactor; } - set { _DispFactor = Math.Max(1, Math.Min(value, 4)); } - } - - [JsonIgnore] - [DeepEqualsIgnore] - private int _DispFactor; - - [DisplayName("Display Free")] - [Description("In OpenGL mode, set to true to use a custom resolution and ignore DispFactor.")] - [DefaultValue(false)] - public bool DispFree { get { return _DispFree; } set { _DispFree = value; } } - [JsonIgnore] - [DeepEqualsIgnore] - private bool _DispFree; - - [DisplayName("DispFree Final Width")] - [Description("In OpenGL mode and when DispFree is true, the width of the final resolution.")] - [DefaultValue(640)] - public int GLW { get { return _GLW; } set { _GLW = Math.Max(320, Math.Min(value, 2048)); } } - [JsonIgnore] - [DeepEqualsIgnore] - private int _GLW; - - [DisplayName("DispFree Final Height")] - [Description("In OpenGL mode and when DispFree is true, the height of the final resolution.")] - [DefaultValue(480)] - public int GLH - { - get { return _GLH; } - set { _GLH = Math.Max(224, Math.Min(value, 1024)); } - } - - [JsonIgnore] - [DeepEqualsIgnore] - private int _GLH; - - [DisplayName("Ram Cart Type")] - [Description("The type of the attached RAM cart. Most games will not use this.")] - [DefaultValue(LibYabause.CartType.NONE)] - public LibYabause.CartType CartType { get; set; } - - [DisplayName("Skip BIOS")] - [Description("Skip the Bios Intro screen.")] - [DefaultValue(false)] - public bool SkipBios { get; set; } - - [DisplayName("Use RealTime RTC")] - [Description("If true, the real time clock will reflect real time, instead of emulated time. Ignored (forced to false) when a movie is recording.")] - [DefaultValue(false)] - public bool RealTimeRTC { get; set; } - - [DisplayName("RTC intiial time")] - [Description("Set the initial RTC time. Only used when RealTimeRTC is false.")] - [DefaultValue(typeof(DateTime), "2010-01-01")] - public DateTime RTCInitialTime { get; set; } - - public static bool NeedsReboot(SaturnSyncSettings x, SaturnSyncSettings y) - { - return !DeepEquality.DeepEquals(x, y); - } - - public SaturnSyncSettings Clone() - { - return (SaturnSyncSettings)MemberwiseClone(); - } - - public SaturnSyncSettings() - { - SettingsUtil.SetDefaultValues(this); - } - } - } -} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.IStatable.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.IStatable.cs deleted file mode 100644 index 8dbb3afd24..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.IStatable.cs +++ /dev/null @@ -1,125 +0,0 @@ -using System; -using System.IO; - -using BizHawk.Common.BufferExtensions; -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Sega.Saturn -{ - public partial class Yabause : IStatable - { - public bool BinarySaveStatesPreferred { get { return true; } } - - // these next 5 functions are all exact copy paste from gambatte. - // if something's wrong here, it's probably wrong there too - - public void SaveStateText(TextWriter writer) - { - var temp = SaveStateBinary(); - temp.SaveAsHexFast(writer); - // write extra copy of stuff we don't use - writer.WriteLine("Frame {0}", Frame); - } - - public void LoadStateText(TextReader reader) - { - string hex = reader.ReadLine(); - byte[] state = new byte[hex.Length / 2]; - state.ReadFromHexFast(hex); - LoadStateBinary(new BinaryReader(new MemoryStream(state))); - } - - public void SaveStateBinary(BinaryWriter writer) - { - byte[] data = SaveCoreBinary(); - - writer.Write(data.Length); - writer.Write(data); - - // other variables - writer.Write(IsLagFrame); - writer.Write(LagCount); - writer.Write(Frame); - } - - public void LoadStateBinary(BinaryReader reader) - { - int length = reader.ReadInt32(); - byte[] data = reader.ReadBytes(length); - - LoadCoreBinary(data); - - // other variables - IsLagFrame = reader.ReadBoolean(); - LagCount = reader.ReadInt32(); - Frame = reader.ReadInt32(); - } - - public byte[] SaveStateBinary() - { - MemoryStream ms = new MemoryStream(); - BinaryWriter bw = new BinaryWriter(ms); - SaveStateBinary(bw); - bw.Flush(); - return ms.ToArray(); - } - - /// - /// does a save, load, save combo, and checks the two saves for identicalness. - /// - private void CheckStates() - { - byte[] s1 = SaveStateBinary(); - LoadStateBinary(new BinaryReader(new MemoryStream(s1, false))); - byte[] s2 = SaveStateBinary(); - if (s1.Length != s2.Length) - throw new Exception(string.Format("CheckStates: Length {0} != {1}", s1.Length, s2.Length)); - unsafe - { - fixed (byte* b1 = &s1[0], b2 = &s2[0]) - { - for (int i = 0; i < s1.Length; i++) - { - if (b1[i] != b2[i]) - { - File.WriteAllBytes("save1.raw", s1); - File.WriteAllBytes("save2.raw", s2); - throw new Exception(string.Format("CheckStates s1[{0}] = {1}, s2[{0}] = {2}", i, b1[i], b2[i])); - } - } - } - } - } - - private void LoadCoreBinary(byte[] data) - { - var fp = new FilePiping(); - fp.Offer(data); - - //loadstate can trigger GL work - ActivateGL(); - - bool succeed = LibYabause.libyabause_loadstate(fp.GetPipeNameNative()); - - DeactivateGL(); - - fp.Finish(); - if (!succeed) - throw new Exception("libyabause_loadstate() failed"); - } - - private byte[] SaveCoreBinary() - { - var ms = new MemoryStream(); - var fp = new FilePiping(); - fp.Get(ms); - bool succeed = LibYabause.libyabause_savestate(fp.GetPipeNameNative()); - fp.Finish(); - var ret = ms.ToArray(); - ms.Close(); - if (!succeed) - throw new Exception("libyabause_savestate() failed"); - return ret; - } - } -} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.ITraceable.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.ITraceable.cs deleted file mode 100644 index a4107ec5f7..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.ITraceable.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Sega.Saturn -{ - public partial class Yabause - { - public TraceBuffer Tracer { get; private set; } - - public static string TraceHeader = "SH2: core, PC, machine code, mnemonic, operands, registers (GPRs, PR, SR, MAC, GBR, VBR)"; - - LibYabause.TraceCallback trace_cb; - - public void YabauseTraceCallback(string dis, string regs) - { - Tracer.Put(new TraceInfo - { - Disassembly = dis, - RegisterInfo = regs - }); - } - - private void ConnectTracer() - { - trace_cb = new LibYabause.TraceCallback(YabauseTraceCallback); - Tracer = new TraceBuffer() { Header = TraceHeader }; - ServiceProvider = new BasicServiceProvider(this); - (ServiceProvider as BasicServiceProvider).Register(Tracer); - } - } -} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs deleted file mode 100644 index 85f41f04c1..0000000000 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs +++ /dev/null @@ -1,504 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -using BizHawk.Emulation.Common; -using BizHawk.Emulation.DiscSystem; - -namespace BizHawk.Emulation.Cores.Sega.Saturn -{ - [CoreAttributes( - "Yabause", - "", - isPorted: true, - isReleased: true, - portedVersion: "9.12", - portedUrl: "http://yabause.org", - singleInstance: true)] - public partial class Yabause : IEmulator, IVideoProvider, ISoundProvider, ISaveRam, IStatable, IInputPollable, - ISettable, IDriveLight - { - public Yabause(CoreComm coreComm, Disc cd, object syncSettings) - { - ServiceProvider = new BasicServiceProvider(this); - byte[] bios = coreComm.CoreFileProvider.GetFirmware("SAT", "J", true, "Saturn BIOS is required."); - coreComm.RomStatusDetails = string.Format("Disk partial hash:{0}", new DiscHasher(cd).OldHash()); - CoreComm = coreComm; - CD = cd; - DiscSectorReader = new DiscSectorReader(cd); - - SyncSettings = (SaturnSyncSettings)syncSettings ?? new SaturnSyncSettings(); - - if (SyncSettings.UseGL && glContext == null) - { - glContext = coreComm.RequestGLContext(2,0,false); - } - - ResetCounters(); - - ActivateGL(); - Init(bios); - - InputCallbackH = new LibYabause.InputCallback(() => InputCallbacks.Call()); - LibYabause.libyabause_setinputcallback(InputCallbackH); - ConnectTracer(); - DriveLightEnabled = true; - - DeactivateGL(); - } - - public static ControllerDefinition SaturnController = new ControllerDefinition - { - Name = "Saturn Controller", - BoolButtons = - { - "Power", "Reset", - "P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 Start", "P1 A", "P1 B", "P1 C", "P1 X", "P1 Y", "P1 Z", "P1 L", "P1 R", - "P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 Start", "P2 A", "P2 B", "P2 C", "P2 X", "P2 Y", "P2 Z", "P2 L", "P2 R", - } - }; - - static Yabause AttachedCore = null; - GCHandle VideoHandle; - Disc CD; - DiscSectorReader DiscSectorReader; - GCHandle SoundHandle; - - bool Disposed = false; - byte[] DisposedSaveRam; - - LibYabause.CDInterface.Init InitH; - LibYabause.CDInterface.DeInit DeInitH; - LibYabause.CDInterface.GetStatus GetStatusH; - LibYabause.CDInterface.ReadTOC ReadTOCH; - LibYabause.CDInterface.ReadSectorFAD ReadSectorFADH; - LibYabause.CDInterface.ReadAheadFAD ReadAheadFADH; - - LibYabause.InputCallback InputCallbackH; - - public IEmulatorServiceProvider ServiceProvider { get; private set; } - - object glContext; - - void ActivateGL() - { - //if (!SyncSettings.UseGL) return; //not safe - if (glContext == null) return; - CoreComm.ActivateGLContext(glContext); - } - - void DeactivateGL() - { - //if (!SyncSettings.UseGL) return; //not safe - if (glContext == null) return; - CoreComm.DeactivateGLContext(); - } - - void Init(byte[] bios) - { - bool GL = SyncSettings.UseGL; - - if (AttachedCore != null) - { - AttachedCore.Dispose(); - AttachedCore = null; - } - VideoHandle = GCHandle.Alloc(VideoBuffer, GCHandleType.Pinned); - SoundHandle = GCHandle.Alloc(SoundBuffer, GCHandleType.Pinned); - - LibYabause.CDInterface CDInt = new LibYabause.CDInterface(); - CDInt.InitFunc = InitH = new LibYabause.CDInterface.Init(CD_Init); - CDInt.DeInitFunc = DeInitH = new LibYabause.CDInterface.DeInit(CD_DeInit); - CDInt.GetStatusFunc = GetStatusH = new LibYabause.CDInterface.GetStatus(CD_GetStatus); - CDInt.ReadTOCFunc = ReadTOCH = new LibYabause.CDInterface.ReadTOC(CD_ReadTOC); - CDInt.ReadSectorFADFunc = ReadSectorFADH = new LibYabause.CDInterface.ReadSectorFAD(CD_ReadSectorFAD); - CDInt.ReadAheadFADFunc = ReadAheadFADH = new LibYabause.CDInterface.ReadAheadFAD(CD_ReadAheadFAD); - - var fp = new FilePiping(); - string BiosPipe = fp.GetPipeNameNative(); - fp.Offer(bios); - - int basetime; - if (SyncSettings.RealTimeRTC) - basetime = 0; - else - basetime = (int)((SyncSettings.RTCInitialTime - new DateTime(1970, 1, 1).ToLocalTime()).TotalSeconds); - - if (!LibYabause.libyabause_init - ( - ref CDInt, - BiosPipe, - GL, - SyncSettings.CartType, - SyncSettings.SkipBios, - !SyncSettings.RealTimeRTC, - basetime - )) - throw new Exception("libyabause_init() failed!"); - - fp.Finish(); - - LibYabause.libyabause_setvidbuff(VideoHandle.AddrOfPinnedObject()); - LibYabause.libyabause_setsndbuff(SoundHandle.AddrOfPinnedObject()); - AttachedCore = this; - - // with or without GL, this is the guaranteed frame -1 size; (unless you do a gl resize) - BufferWidth = 320; - BufferHeight = 224; - - InitMemoryDomains(); - - GLMode = GL; - // if in GL mode, this will trigger the initial GL resize - PutSyncSettings(this.SyncSettings); - } - - public ControllerDefinition ControllerDefinition - { - get { return SaturnController; } - } - - public bool GLMode { get; private set; } - - public void SetGLRes(int factor, int width, int height) - { - if (!GLMode) - return; - - if (factor < 0) factor = 0; - if (factor > 4) factor = 4; - - int maxwidth, maxheight; - - if (factor == 0) - { - maxwidth = width; - maxheight = height; - } - else - { - maxwidth = 704 * factor; - maxheight = 512 * factor; - } - if (maxwidth * maxheight > VideoBuffer.Length) - { - VideoHandle.Free(); - VideoBuffer = new int[maxwidth * maxheight]; - VideoHandle = GCHandle.Alloc(VideoBuffer, GCHandleType.Pinned); - LibYabause.libyabause_setvidbuff(VideoHandle.AddrOfPinnedObject()); - } - LibYabause.libyabause_glsetnativefactor(factor); - if (factor == 0) - LibYabause.libyabause_glresize(width, height); - } - - public void FrameAdvance(IController controller, bool render, bool rendersound = true) - { - int w, h, nsamp; - - ActivateGL(); - - LibYabause.Buttons1 p11 = (LibYabause.Buttons1)0xff; - LibYabause.Buttons2 p12 = (LibYabause.Buttons2)0xff; - LibYabause.Buttons1 p21 = (LibYabause.Buttons1)0xff; - LibYabause.Buttons2 p22 = (LibYabause.Buttons2)0xff; - - if (controller.IsPressed("P1 A")) - p11 &= ~LibYabause.Buttons1.A; - if (controller.IsPressed("P1 B")) - p11 &= ~LibYabause.Buttons1.B; - if (controller.IsPressed("P1 C")) - p11 &= ~LibYabause.Buttons1.C; - if (controller.IsPressed("P1 Start")) - p11 &= ~LibYabause.Buttons1.S; - if (controller.IsPressed("P1 Left")) - p11 &= ~LibYabause.Buttons1.L; - if (controller.IsPressed("P1 Right")) - p11 &= ~LibYabause.Buttons1.R; - if (controller.IsPressed("P1 Up")) - p11 &= ~LibYabause.Buttons1.U; - if (controller.IsPressed("P1 Down")) - p11 &= ~LibYabause.Buttons1.D; - if (controller.IsPressed("P1 L")) - p12 &= ~LibYabause.Buttons2.L; - if (controller.IsPressed("P1 R")) - p12 &= ~LibYabause.Buttons2.R; - if (controller.IsPressed("P1 X")) - p12 &= ~LibYabause.Buttons2.X; - if (controller.IsPressed("P1 Y")) - p12 &= ~LibYabause.Buttons2.Y; - if (controller.IsPressed("P1 Z")) - p12 &= ~LibYabause.Buttons2.Z; - - if (controller.IsPressed("P2 A")) - p21 &= ~LibYabause.Buttons1.A; - if (controller.IsPressed("P2 B")) - p21 &= ~LibYabause.Buttons1.B; - if (controller.IsPressed("P2 C")) - p21 &= ~LibYabause.Buttons1.C; - if (controller.IsPressed("P2 Start")) - p21 &= ~LibYabause.Buttons1.S; - if (controller.IsPressed("P2 Left")) - p21 &= ~LibYabause.Buttons1.L; - if (controller.IsPressed("P2 Right")) - p21 &= ~LibYabause.Buttons1.R; - if (controller.IsPressed("P2 Up")) - p21 &= ~LibYabause.Buttons1.U; - if (controller.IsPressed("P2 Down")) - p21 &= ~LibYabause.Buttons1.D; - if (controller.IsPressed("P2 L")) - p22 &= ~LibYabause.Buttons2.L; - if (controller.IsPressed("P2 R")) - p22 &= ~LibYabause.Buttons2.R; - if (controller.IsPressed("P2 X")) - p22 &= ~LibYabause.Buttons2.X; - if (controller.IsPressed("P2 Y")) - p22 &= ~LibYabause.Buttons2.Y; - if (controller.IsPressed("P2 Z")) - p22 &= ~LibYabause.Buttons2.Z; - - - if (controller.IsPressed("Reset")) - LibYabause.libyabause_softreset(); - if (controller.IsPressed("Power")) - LibYabause.libyabause_hardreset(); - - LibYabause.libyabause_setpads(p11, p12, p21, p22); - - DriveLightOn = false; - - if (Tracer.Enabled) - LibYabause.libyabause_settracecallback(trace_cb); - else - LibYabause.libyabause_settracecallback(null); - - IsLagFrame = LibYabause.libyabause_frameadvance(out w, out h, out nsamp); - BufferWidth = w; - BufferHeight = h; - SoundNSamp = nsamp; - Frame++; - if (IsLagFrame) - LagCount++; - //Console.WriteLine(nsamp); - - //CheckStates(); - - DeactivateGL(); - } - - public int Frame { get; private set; } - - public string SystemId { get { return "SAT"; } } - public bool DeterministicEmulation { get { return true; } } - - public void ResetCounters() - { - Frame = 0; - LagCount = 0; - IsLagFrame = false; - } - - public CoreComm CoreComm { get; private set; } - - public void Dispose() - { - if (!Disposed) - { - ActivateGL(); - if (SaveRamModified) - DisposedSaveRam = CloneSaveRam(); - LibYabause.libyabause_setvidbuff(IntPtr.Zero); - LibYabause.libyabause_setsndbuff(IntPtr.Zero); - LibYabause.libyabause_deinit(); - VideoHandle.Free(); - SoundHandle.Free(); - CD.Dispose(); - Disposed = true; - DeactivateGL(); - if (glContext != null) - CoreComm.ReleaseGLContext(glContext); - } - } - - #region IVideoProvider - - int[] VideoBuffer = new int[704 * 512]; - int[] TextureIdBuffer = new int[1]; //todo - public int[] GetVideoBuffer() { - //doesn't work yet - //if (SyncSettings.UseGL) - // return new[] { VideoBuffer[0] }; - //else - return VideoBuffer; - } - public int VirtualWidth { get { return BufferWidth; } } - public int VirtualHeight { get { return BufferHeight; } } - public int BufferWidth { get; private set; } - public int BufferHeight { get; private set; } - public int BackgroundColor { get { return unchecked((int)0xff000000); } } - - public int VsyncNumerator - { - [FeatureNotImplemented] - get - { - return NullVideo.DefaultVsyncNum; - } - } - - public int VsyncDenominator - { - [FeatureNotImplemented] - get - { - return NullVideo.DefaultVsyncDen; - } - } - - #endregion - - #region ISyncSoundProvider - - private short[] SoundBuffer = new short[44100 * 2]; - private int SoundNSamp = 0; - - public void GetSamplesSync(out short[] samples, out int nsamp) - { - nsamp = SoundNSamp; - samples = SoundBuffer; - } - - public void DiscardSamples() { } - - public bool CanProvideAsync - { - get { return false; } - } - - public void SetSyncMode(SyncSoundMode mode) - { - if (mode == SyncSoundMode.Async) - { - throw new NotSupportedException("Async mode is not supported."); - } - } - - public SyncSoundMode SyncMode - { - get { return SyncSoundMode.Sync; } - } - - public void GetSamplesAsync(short[] samples) - { - throw new InvalidOperationException("Async mode is not supported."); - } - - #endregion - - #region CD - - /// - /// init cd functions - /// - /// - /// 0 on success, -1 on failure - int CD_Init(string unused) - { - return 0; - } - /// - /// deinit cd functions - /// - void CD_DeInit() - { - } - /// - /// 0 = cd present, spinning - /// 1 = cd present, not spinning - /// 2 = no cd - /// 3 = tray open - /// - /// - int CD_GetStatus() - { - return 0; - } - /// - /// read all TOC entries - /// - /// place to copy to - /// number of bytes written. should be 408 (99 tracks, 3 specials) - int CD_ReadTOC(IntPtr dest) - { - // this stuff from yabause's cdbase.c. don't ask me to explain it - //TODO - we could just get this out of the actual TOC, it's the same thing - - int[] rTOC = new int[102]; - var ses = CD.Session1; - int ntrk = ses.InformationTrackCount; - - for (int i = 0; i < 99; i++) - { - int tnum = i + 1; - if (tnum <= ntrk) - { - var trk = ses.Tracks[tnum]; - - uint t = (uint)trk.LBA + 150; - - if(trk.IsAudio) - t |= 0x01000000; - else - t |= 0x41000000; - - rTOC[i] = (int)t; - } - else - { - rTOC[i] = unchecked((int)0xffffffff); - } - } - - rTOC[99] = (int)(rTOC[0] & 0xff000000 | 0x010000); - rTOC[100] = (int)(rTOC[ntrk - 1] & 0xff000000 | (uint)(ntrk << 16)); - rTOC[101] = (int)(rTOC[ntrk - 1] & 0xff000000 | (uint)(CD.TOC.LeadoutLBA)); //zero 03-jul-2014 - maybe off by 150 - - - Marshal.Copy(rTOC, 0, dest, 102); - return 408; - } - - /// - /// read a sector, should be 2352 bytes - /// - /// - /// - /// - int CD_ReadSectorFAD(int FAD, IntPtr dest) - { - byte[] data = new byte[2352]; - try - { - //CD.ReadABA_2352(FAD, data, 0); - DiscSectorReader.ReadLBA_2352(FAD - 150, data, 0); //zero 21-jun-2015 - did I adapt this right? - } - catch (Exception e) - { - Console.WriteLine("CD_ReadSectorFAD: Managed Exception:\n" + e.ToString()); - return 0; // failure - } - Marshal.Copy(data, 0, dest, 2352); - DriveLightOn = true; - return 1; // success - } - /// - /// hint the next sector, for async loading - /// - /// - void CD_ReadAheadFAD(int FAD) - { - // ignored for now - } - - #endregion - } -} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IEmulator.cs index 40a945657f..8f34dbfbd9 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IEmulator.cs @@ -66,13 +66,13 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 public void Dispose() { - if (!disposed) + if (!_disposed) { - if (Elf != null) - Elf.Dispose(); + if (_elf != null) + _elf.Dispose(); if (CD != null) CD.Dispose(); - disposed = true; + _disposed = true; } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IMemoryDomains.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IMemoryDomains.cs index ee6318427e..e8375ccc50 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IMemoryDomains.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IMemoryDomains.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using BizHawk.Emulation.Common; +using BizHawk.Common; namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 { @@ -12,84 +13,88 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 private unsafe void SetMemoryDomains() { - var mm = new List(); - for (int i = LibGPGX.MIN_MEM_DOMAIN; i <= LibGPGX.MAX_MEM_DOMAIN; i++) + using (_elf.EnterExit()) { - IntPtr area = IntPtr.Zero; - int size = 0; - IntPtr pname = Core.gpgx_get_memdom(i, ref area, ref size); - if (area == IntPtr.Zero || pname == IntPtr.Zero || size == 0) - continue; - string name = Marshal.PtrToStringAnsi(pname); - if (name == "VRAM") + var mm = new List(); + for (int i = LibGPGX.MIN_MEM_DOMAIN; i <= LibGPGX.MAX_MEM_DOMAIN; i++) { - // vram pokes need to go through hook which invalidates cached tiles - byte* p = (byte*)area; - mm.Add(new MemoryDomainDelegate(name, size, MemoryDomain.Endian.Unknown, - delegate(long addr) - { - if (addr < 0 || addr >= 65536) - throw new ArgumentOutOfRangeException(); - return p[addr ^ 1]; - }, - delegate(long addr, byte val) - { - if (addr < 0 || addr >= 65536) - throw new ArgumentOutOfRangeException(); - Core.gpgx_poke_vram(((int)addr) ^ 1, val); - }, - wordSize: 2)); + IntPtr area = IntPtr.Zero; + int size = 0; + IntPtr pname = Core.gpgx_get_memdom(i, ref area, ref size); + if (area == IntPtr.Zero || pname == IntPtr.Zero || size == 0) + continue; + string name = Marshal.PtrToStringAnsi(pname); + if (name == "VRAM") + { + // vram pokes need to go through hook which invalidates cached tiles + byte* p = (byte*)area; + mm.Add(new MemoryDomainDelegate(name, size, MemoryDomain.Endian.Unknown, + delegate (long addr) + { + if (addr < 0 || addr >= 65536) + throw new ArgumentOutOfRangeException(); + using (_elf.EnterExit()) + return p[addr ^ 1]; + }, + delegate (long addr, byte val) + { + if (addr < 0 || addr >= 65536) + throw new ArgumentOutOfRangeException(); + Core.gpgx_poke_vram(((int)addr) ^ 1, val); + }, + wordSize: 2)); + } + else + { + // TODO: are the Z80 domains really Swap16 in the core? Check this + mm.Add(new MemoryDomainIntPtrSwap16Monitor(name, MemoryDomain.Endian.Big, area, size, name != "MD CART" && name != "CD BOOT ROM", _elf)); + } + } + var m68Bus = new MemoryDomainDelegate("M68K BUS", 0x1000000, MemoryDomain.Endian.Big, + delegate (long addr) + { + var a = (uint)addr; + if (a >= 0x1000000) + throw new ArgumentOutOfRangeException(); + return Core.gpgx_peek_m68k_bus(a); + }, + delegate (long addr, byte val) + { + var a = (uint)addr; + if (a >= 0x1000000) + throw new ArgumentOutOfRangeException(); + Core.gpgx_write_m68k_bus(a, val); + }, 2); + + mm.Add(m68Bus); + + if (IsMegaCD) + { + var s68Bus = new MemoryDomainDelegate("S68K BUS", 0x1000000, MemoryDomain.Endian.Big, + delegate (long addr) + { + var a = (uint)addr; + if (a >= 0x1000000) + throw new ArgumentOutOfRangeException(); + return Core.gpgx_peek_s68k_bus(a); + }, + delegate (long addr, byte val) + { + var a = (uint)addr; + if (a >= 0x1000000) + throw new ArgumentOutOfRangeException(); + Core.gpgx_write_s68k_bus(a, val); + }, 2); + + + mm.Add(s68Bus); } - else - { - // TODO: are the Z80 domains really Swap16 in the core? Check this - mm.Add(new MemoryDomainIntPtrSwap16(name, MemoryDomain.Endian.Big, area, size, name != "MD CART" && name != "CD BOOT ROM")); - } + MemoryDomains = new MemoryDomainList(mm); + MemoryDomains.SystemBus = m68Bus; + + (ServiceProvider as BasicServiceProvider).Register(MemoryDomains); } - var m68Bus = new MemoryDomainDelegate("M68K BUS", 0x1000000, MemoryDomain.Endian.Big, - delegate (long addr) - { - var a = (uint)addr; - if (a >= 0x1000000) - throw new ArgumentOutOfRangeException(); - return Core.gpgx_peek_m68k_bus(a); - }, - delegate (long addr, byte val) - { - var a = (uint)addr; - if (a >= 0x1000000) - throw new ArgumentOutOfRangeException(); - Core.gpgx_write_m68k_bus(a, val); - }, 2); - - mm.Add(m68Bus); - - var s68Bus = new MemoryDomainDelegate("S68K BUS", 0x1000000, MemoryDomain.Endian.Big, - delegate (long addr) - { - var a = (uint)addr; - if (a >= 0x1000000) - throw new ArgumentOutOfRangeException(); - return Core.gpgx_peek_s68k_bus(a); - }, - delegate (long addr, byte val) - { - var a = (uint)addr; - if (a >= 0x1000000) - throw new ArgumentOutOfRangeException(); - Core.gpgx_write_s68k_bus(a, val); - }, 2); - - if (IsSegaCD) - { - mm.Add(s68Bus); - } - - MemoryDomains = new MemoryDomainList(mm); - MemoryDomains.SystemBus = m68Bus; - - (ServiceProvider as BasicServiceProvider).Register(MemoryDomains); } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ISaveRam.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ISaveRam.cs index 2f84bf6039..7578261d9c 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ISaveRam.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ISaveRam.cs @@ -4,6 +4,7 @@ using System.IO; using BizHawk.Common.BufferExtensions; using BizHawk.Emulation.Common; using System.Runtime.InteropServices; +using BizHawk.Common; namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 { @@ -17,7 +18,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 return new byte[0]; byte[] ret = new byte[size]; - Marshal.Copy(area, ret, 0, size); + using (_elf.EnterExit()) + Marshal.Copy(area, ret, 0, size); return ret; } diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ISoundProvider.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ISoundProvider.cs index f979cd11bf..a85fc9ac06 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ISoundProvider.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ISoundProvider.cs @@ -1,6 +1,7 @@ using System; using BizHawk.Emulation.Common; using System.Runtime.InteropServices; +using BizHawk.Common; namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 { @@ -50,7 +51,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 Core.gpgx_get_audio(ref nsamp, ref src); if (src != IntPtr.Zero) { - Marshal.Copy(src, samples, 0, nsamp * 2); + using (_elf.EnterExit()) + Marshal.Copy(src, samples, 0, nsamp * 2); } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IStatable.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IStatable.cs index 24a1e1fe96..41337dfd89 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IStatable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IStatable.cs @@ -31,7 +31,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 public void LoadStateBinary(BinaryReader reader) { - Elf.LoadStateBinary(reader); + _elf.LoadStateBinary(reader); // other variables Frame = reader.ReadInt32(); LagCount = reader.ReadInt32(); @@ -46,7 +46,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 public void SaveStateBinary(BinaryWriter writer) { - Elf.SaveStateBinary(writer); + _elf.SaveStateBinary(writer); // other variables writer.Write(Frame); writer.Write(LagCount); @@ -62,9 +62,5 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 ms.Close(); return ms.ToArray(); } - - private void InitStateBuffers() - { - } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IVideoProvider.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IVideoProvider.cs index 58465b07a2..0432d4d4f5 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IVideoProvider.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.IVideoProvider.cs @@ -1,5 +1,6 @@ using System; using BizHawk.Emulation.Common; +using BizHawk.Common; namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 { @@ -41,38 +42,47 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 private unsafe void UpdateVideo() { - int gppitch, gpwidth, gpheight; - IntPtr src = IntPtr.Zero; - - Core.gpgx_get_video(out gpwidth, out gpheight, out gppitch, ref src); - - vwidth = gpwidth; - vheight = gpheight; - - if (_settings.PadScreen320 && vwidth == 256) - vwidth = 320; - - int xpad = (vwidth - gpwidth) / 2; - int xpad2 = vwidth - gpwidth - xpad; - - if (vidbuff.Length < vwidth * vheight) - vidbuff = new int[vwidth * vheight]; - - int rinc = (gppitch / 4) - gpwidth; - fixed (int* pdst_ = &vidbuff[0]) + if (Frame == 0) { - int* pdst = pdst_; - int* psrc = (int*)src; + UpdateVideoInitial(); + return; + } - for (int j = 0; j < gpheight; j++) + using (_elf.EnterExit()) + { + int gppitch, gpwidth, gpheight; + IntPtr src = IntPtr.Zero; + + Core.gpgx_get_video(out gpwidth, out gpheight, out gppitch, ref src); + + vwidth = gpwidth; + vheight = gpheight; + + if (_settings.PadScreen320 && vwidth == 256) + vwidth = 320; + + int xpad = (vwidth - gpwidth) / 2; + int xpad2 = vwidth - gpwidth - xpad; + + if (vidbuff.Length < vwidth * vheight) + vidbuff = new int[vwidth * vheight]; + + int rinc = (gppitch / 4) - gpwidth; + fixed (int* pdst_ = vidbuff) { - for (int i = 0; i < xpad; i++) - *pdst++ = unchecked((int)0xff000000); - for (int i = 0; i < gpwidth; i++) - *pdst++ = *psrc++;// | unchecked((int)0xff000000); - for (int i = 0; i < xpad2; i++) - *pdst++ = unchecked((int)0xff000000); - psrc += rinc; + int* pdst = pdst_; + int* psrc = (int*)src; + + for (int j = 0; j < gpheight; j++) + { + for (int i = 0; i < xpad; i++) + *pdst++ = unchecked((int)0xff000000); + for (int i = 0; i < gpwidth; i++) + *pdst++ = *psrc++; ; + for (int i = 0; i < xpad2; i++) + *pdst++ = unchecked((int)0xff000000); + psrc += rinc; + } } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.cs index c54a7d7892..33c3f3ddc6 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.cs @@ -4,6 +4,8 @@ using System.Runtime.InteropServices; using BizHawk.Common.BizInvoke; using BizHawk.Emulation.Common; +using BizHawk.Emulation.Cores.Waterbox; +using BizHawk.Common; namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 { @@ -39,14 +41,20 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 throw new InvalidOperationException("ROM too big! Did you try to load a CD as a ROM?"); } - try + _elf = new PeRunner(new PeRunnerOptions { - Elf = new ElfRunner(Path.Combine(comm.CoreFileProvider.DllPath(), "gpgx.elf"), 8 * 1024 * 1024, 36 * 1024 * 1024, 4 * 1024 * 1024); - if (Elf.ShouldMonitor) - Core = BizInvoker.GetInvoker(Elf, Elf); - else - Core = BizInvoker.GetInvoker(Elf); + Path = comm.CoreFileProvider.DllPath(), + Filename = "gpgx.wbx", + SbrkHeapSizeKB = 256, + SealedHeapSizeKB = 36 * 1024, + InvisibleHeapSizeKB = 4 * 1024, + PlainHeapSizeKB = 64, + MmapHeapSizeKB = 512 + }); + using (_elf.EnterExit()) + { + Core = BizInvoker.GetInvoker(_elf, _elf, CallingConventionAdapters.Waterbox); _syncSettings = (GPGXSyncSettings)syncSettings ?? new GPGXSyncSettings(); _settings = (GPGXSettings)settings ?? new GPGXSettings(); @@ -100,7 +108,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 break; } - if (!Core.gpgx_init(romextension, LoadCallback, _syncSettings.UseSixButton, system_a, system_b, _syncSettings.Region, _settings.GetNativeSettings())) throw new Exception("gpgx_init() failed"); @@ -113,13 +120,18 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 Region = VsyncNumerator / VsyncDenominator > 55 ? DisplayType.NTSC : DisplayType.PAL; } - // compute state size - InitStateBuffers(); + // when we call Seal, ANY pointer passed from managed code must be 0. + // this is so the initial state is clean + // the only two pointers set so far are LoadCallback, which the core zeroed itself, + // and CdCallback + Core.gpgx_set_cdd_callback(null); + _elf.Seal(); + Core.gpgx_set_cdd_callback(cd_callback_handle); SetControllerDefinition(); // pull the default video size from the core - UpdateVideoInitial(); + UpdateVideo(); SetMemoryDomains(); @@ -140,24 +152,17 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 Tracer = new GPGXTraceBuffer(this, MemoryDomains, this); (ServiceProvider as BasicServiceProvider).Register(Tracer); - - Elf.Seal(); - } - catch - { - Dispose(); - throw; } } - LibGPGX Core; - ElfRunner Elf; + private LibGPGX Core; + private PeRunner _elf; DiscSystem.Disc CD; DiscSystem.DiscSectorReader DiscSectorReader; byte[] romfile; - bool disposed = false; + private bool _disposed = false; LibGPGX.load_archive_cb LoadCallback = null; @@ -270,9 +275,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 } else { - throw new Exception(); - //Console.WriteLine("Couldn't satisfy firmware request {0} for unknown reasons", filename); - //return 0; + throw new InvalidOperationException("Unknown error processing firmware"); } } @@ -365,12 +368,48 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64 return (LibGPGX.INPUT_DEVICE[])input.dev.Clone(); } - public bool IsSegaCD { get { return CD != null; } } + public bool IsMegaCD { get { return CD != null; } } - public void UpdateVDPViewContext(LibGPGX.VDPView view) + public class VDPView : IMonitor { - Core.gpgx_get_vdp_view(view); + private readonly IMonitor _m; + + public VDPView(LibGPGX.VDPView v, IMonitor m) + { + _m = m; + VRAM = v.VRAM; + PatternCache = v.PatternCache; + ColorCache = v.ColorCache; + NTA = v.NTA; + NTB = v.NTB; + NTW = v.NTW; + } + + public IntPtr VRAM; + public IntPtr PatternCache; + public IntPtr ColorCache; + public LibGPGX.VDPNameTable NTA; + public LibGPGX.VDPNameTable NTB; + public LibGPGX.VDPNameTable NTW; + + + public void Enter() + { + _m.Enter(); + } + + public void Exit() + { + _m.Exit(); + } + } + + public VDPView UpdateVDPViewContext() + { + var v = new LibGPGX.VDPView(); + Core.gpgx_get_vdp_view(v); Core.gpgx_flush_vram(); // fully regenerate internal caches as needed + return new VDPView(v, _elf); } public DisplayType Region { get; private set; } diff --git a/BizHawk.Emulation.Cores/CoreInventory.cs b/BizHawk.Emulation.Cores/CoreInventory.cs index 153900a623..abf7b55dcc 100644 --- a/BizHawk.Emulation.Cores/CoreInventory.cs +++ b/BizHawk.Emulation.Cores/CoreInventory.cs @@ -174,7 +174,7 @@ namespace BizHawk.Emulation.Cores { foreach (var typ in assy.GetTypes()) { - if (typ.GetInterfaces().Contains(typeof(IEmulator))) + if (!typ.IsAbstract && typ.GetInterfaces().Contains(typeof(IEmulator))) { var coreattr = typ.GetCustomAttributes(typeof(CoreAttributes), false); if (coreattr.Length != 1) diff --git a/BizHawk.Emulation.Cores/Libretro/LibretroApi.cs b/BizHawk.Emulation.Cores/Libretro/LibretroApi.cs index 5e81a13b93..28875d5d47 100644 --- a/BizHawk.Emulation.Cores/Libretro/LibretroApi.cs +++ b/BizHawk.Emulation.Cores/Libretro/LibretroApi.cs @@ -33,7 +33,7 @@ namespace BizHawk.Emulation.Cores.Libretro delegate void MessageApi(eMessage msg); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - delegate void BufferApi(BufId id, void* ptr, int size); + delegate void BufferApi(BufId id, void* ptr, ulong size); //size_t [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void SetVariableApi(string key, string value); @@ -106,7 +106,7 @@ namespace BizHawk.Emulation.Cores.Libretro public void CopyAscii(BufId id, string str) { fixed (char* cp = str) - _copyBuffer(id, cp, str.Length + 1); + _copyBuffer(id, cp, (ulong)str.Length + 1); } /// @@ -115,7 +115,7 @@ namespace BizHawk.Emulation.Cores.Libretro public void CopyBytes(BufId id, byte[] bytes) { fixed (byte* bp = bytes) - _copyBuffer(id, bp, bytes.Length); + _copyBuffer(id, bp, (ulong)bytes.Length); } /// @@ -129,7 +129,7 @@ namespace BizHawk.Emulation.Cores.Libretro { fixed (byte* bp = bytes) { - _setBuffer(id, bp, bytes.Length); + _setBuffer(id, bp, (ulong)bytes.Length); andThen(); } } @@ -141,7 +141,7 @@ namespace BizHawk.Emulation.Cores.Libretro { fixed (byte* cp = System.Text.Encoding.ASCII.GetBytes(str+"\0")) { - _setBuffer(id, cp, str.Length + 1); + _setBuffer(id, cp, (ulong)str.Length + 1); andThen(); } } @@ -150,8 +150,10 @@ namespace BizHawk.Emulation.Cores.Libretro { public retro_system_info retro_system_info; public retro_system_av_info retro_system_av_info; + public uint retro_serialize_size_initial; //size_t :( public uint retro_serialize_size; //size_t :( + public uint retro_region; public uint retro_api_version; public retro_pixel_format pixel_format; //default is 0 -- RETRO_PIXEL_FORMAT_0RGB1555 @@ -197,8 +199,8 @@ namespace BizHawk.Emulation.Cores.Libretro public CommStructEnv env; //this should always be used in pairs - public fixed uint buf[(int)BufId.BufId_Num]; //ACTUALLY A POINTER but can't marshal it :( - public fixed int buf_size[(int)BufId.BufId_Num]; + public fixed ulong buf[(int)BufId.BufId_Num]; //actually a pointer, but can't marshal IntPtr, so dumb + public fixed ulong buf_size[(int)BufId.BufId_Num]; //actually a size_t //utilities public bool GetBoolValue() { return value != 0; } //should this be here or by the other helpers? I dont know diff --git a/BizHawk.Emulation.Cores/Libretro/LibretroApi_QUERY.cs b/BizHawk.Emulation.Cores/Libretro/LibretroApi_QUERY.cs index 56470c30c1..f0dd8d5fd8 100644 --- a/BizHawk.Emulation.Cores/Libretro/LibretroApi_QUERY.cs +++ b/BizHawk.Emulation.Cores/Libretro/LibretroApi_QUERY.cs @@ -6,11 +6,11 @@ namespace BizHawk.Emulation.Cores.Libretro { unsafe partial class LibretroApi { - public Tuple QUERY_GetMemory(RETRO_MEMORY mem) + public Tuple QUERY_GetMemory(RETRO_MEMORY mem) { comm->value = (uint)mem; Message(eMessage.QUERY_GetMemory); - return Tuple.Create(new IntPtr(comm->buf[(int)BufId.Param0]), comm->buf_size[(int)BufId.Param0]); + return Tuple.Create(new IntPtr((long)comm->buf[(int)BufId.Param0]), comm->buf_size[(int)BufId.Param0]); } } } \ No newline at end of file diff --git a/BizHawk.Emulation.Cores/Libretro/LibretroApi_SIG.cs b/BizHawk.Emulation.Cores/Libretro/LibretroApi_SIG.cs index c80abb1442..2fe71a5fb5 100644 --- a/BizHawk.Emulation.Cores/Libretro/LibretroApi_SIG.cs +++ b/BizHawk.Emulation.Cores/Libretro/LibretroApi_SIG.cs @@ -32,7 +32,7 @@ namespace BizHawk.Emulation.Cores.Libretro case eMessage.SIG_SampleBatch: { void* samples = (void*)comm->buf[(int)BufId.Param0]; - core.retro_audio_sample_batch(samples, comm->buf_size[(int)BufId.Param0]/4); + core.retro_audio_sample_batch(samples, (int)comm->buf_size[(int)BufId.Param0]/4); } break; diff --git a/BizHawk.Emulation.Cores/Libretro/LibretroCore.cs b/BizHawk.Emulation.Cores/Libretro/LibretroCore.cs index 068b6214da..d9e0648229 100644 --- a/BizHawk.Emulation.Cores/Libretro/LibretroCore.cs +++ b/BizHawk.Emulation.Cores/Libretro/LibretroCore.cs @@ -311,7 +311,7 @@ namespace BizHawk.Emulation.Cores.Libretro var mem = api.QUERY_GetMemory(LibretroApi.RETRO_MEMORY.SAVE_RAM); var buf = new byte[mem.Item2]; - Marshal.Copy(mem.Item1, buf, 0, mem.Item2); + Marshal.Copy(mem.Item1, buf, 0, (int)mem.Item2); return buf; } @@ -323,7 +323,7 @@ namespace BizHawk.Emulation.Cores.Libretro if (mem.Item2 == 0) return; - Marshal.Copy(data, 0, mem.Item1, mem.Item2); + Marshal.Copy(data, 0, mem.Item1, (int)mem.Item2); } public bool SaveRamModified diff --git a/BizHawk.Emulation.Cores/SideBySideVideo.cs b/BizHawk.Emulation.Cores/SideBySideVideo.cs new file mode 100644 index 0000000000..e624f69a41 --- /dev/null +++ b/BizHawk.Emulation.Cores/SideBySideVideo.cs @@ -0,0 +1,58 @@ +using BizHawk.Emulation.Common; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores +{ + public class SideBySideVideo : IVideoProvider + { + public SideBySideVideo(IVideoProvider l, IVideoProvider r) + { + _l = l; + _r = r; + _buff = new int[BufferWidth * BufferHeight]; + } + + private static unsafe void Blit(int* src, int srcp, int* dst, int dstp, int w, int h) + { + int* srcend = src + h * srcp; + while (src < srcend) + { + for (int j = 0; j < w; j++) + dst[j] = src[j]; + src += srcp; + dst += dstp; + } + } + + public unsafe void Fetch() + { + int h = BufferHeight; + int w = BufferWidth; + + fixed(int* _pl = _l.GetVideoBuffer(), _pr = _r.GetVideoBuffer(), _pd = _buff) + { + Blit(_pl, w / 2, _pd, w, w / 2, h); + Blit(_pr, w / 2, _pd + w / 2, w, w / 2, h); + } + } + private readonly IVideoProvider _l; + private readonly IVideoProvider _r; + private int[] _buff; + public int BackgroundColor => _l.BackgroundColor; + public int BufferHeight => _l.BufferHeight; + public int BufferWidth => _l.BufferWidth * 2; + public int VirtualHeight => _l.VirtualHeight; + public int VirtualWidth => _l.VirtualWidth * 2; + public int VsyncDenominator => _l.VsyncDenominator; + public int VsyncNumerator => _l.VsyncNumerator; + + public int[] GetVideoBuffer() + { + return _buff; + } + } +} diff --git a/BizHawk.Emulation.Cores/Sound/DualSyncSound.cs b/BizHawk.Emulation.Cores/Sound/DualSyncSound.cs new file mode 100644 index 0000000000..fd61031f22 --- /dev/null +++ b/BizHawk.Emulation.Cores/Sound/DualSyncSound.cs @@ -0,0 +1,96 @@ +using BizHawk.Emulation.Common; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Sound +{ + /// + /// this thing more or less ASSumes that the two cores input to it both provide the same number of samples in each go + /// + public class DualSyncSound : ISoundProvider + { + private ISoundProvider _left; + private ISoundProvider _right; + private int _nsamp; + private short[] _samp = new short[0]; + + private short[] _leftOverflow = new short[32]; + private int _leftOverflowCount = 0; + private short[] _rightOverflow = new short[32]; + private int _rightOverflowCount = 0; + + + public DualSyncSound(ISoundProvider left, ISoundProvider right) + { + _left = left; + _right = right; + } + + private static short Mix(short[] buff, int idx) + { + int s = buff[idx * 2] + buff[idx * 2 + 1]; + if (s > 32767) + s = 32767; + if (s < -32768) + s = -32768; + return (short)s; + } + + public void Fetch() + { + int nsampl, nsampr; + short[] sampl, sampr; + _left.GetSamplesSync(out sampl, out nsampl); + _right.GetSamplesSync(out sampr, out nsampr); + + int n = Math.Min(nsampl + _leftOverflowCount, nsampr + _rightOverflowCount); + + if (_samp.Length < n * 2) + _samp = new short[n * 2]; + + int i, j; + for (i = 0, j = 0; i < _leftOverflowCount; i++, j++) + _samp[j * 2] = Mix(_leftOverflow, i); + for (i = 0; j < n; i++, j++) + _samp[j * 2] = Mix(sampl, i); + _leftOverflowCount = Math.Min(nsampl - i, 16); + Array.Copy(sampl, i * 2, _leftOverflow, 0, _leftOverflowCount * 2); + for (i = 0, j = 0; i < _rightOverflowCount; i++, j++) + _samp[j * 2 + 1] = Mix(_rightOverflow, i); + for (i = 0; j < n; i++, j++) + _samp[j * 2 + 1] = Mix(sampr, i); + _rightOverflowCount = Math.Min(nsampr - i, 16); + Array.Copy(sampr, i * 2, _rightOverflow, 0, _rightOverflowCount * 2); + + _nsamp = n; + } + + public bool CanProvideAsync => false; + + public SyncSoundMode SyncMode => SyncSoundMode.Sync; + + public void DiscardSamples() + { + } + + public void GetSamplesAsync(short[] samples) + { + throw new InvalidOperationException(); + } + + public void GetSamplesSync(out short[] samples, out int nsamp) + { + samples = _samp; + nsamp = _nsamp; + } + + public void SetSyncMode(SyncSoundMode mode) + { + if (mode != SyncSoundMode.Sync) + throw new InvalidOperationException(); + } + } +} diff --git a/BizHawk.Emulation.Cores/Waterbox/CustomSaverammer.cs b/BizHawk.Emulation.Cores/Waterbox/CustomSaverammer.cs new file mode 100644 index 0000000000..ae1834f235 --- /dev/null +++ b/BizHawk.Emulation.Cores/Waterbox/CustomSaverammer.cs @@ -0,0 +1,38 @@ +using BizHawk.Emulation.Common; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Waterbox +{ + internal class CustomSaverammer : ISaveRam + { + private readonly ICustomSaveram _s; + private readonly int _size; + + + public CustomSaverammer(ICustomSaveram s) + { + _s = s; + _size = s.GetSaveramSize(); + } + + public bool SaveRamModified => _size > 0; + + public byte[] CloneSaveRam() + { + var ret = new byte[_size]; + _s.GetSaveram(ret, ret.Length); + return ret; + } + + public void StoreSaveRam(byte[] data) + { + if (data.Length != _size) + throw new InvalidOperationException("Wrong size saveram"); + _s.PutSaveram(data, data.Length); + } + } +} diff --git a/BizHawk.Emulation.Cores/ElfRunner.cs b/BizHawk.Emulation.Cores/Waterbox/ElfRunner.cs similarity index 66% rename from BizHawk.Emulation.Cores/ElfRunner.cs rename to BizHawk.Emulation.Cores/Waterbox/ElfRunner.cs index 0f6f1dfaa8..000d762995 100644 --- a/BizHawk.Emulation.Cores/ElfRunner.cs +++ b/BizHawk.Emulation.Cores/Waterbox/ElfRunner.cs @@ -1,722 +1,488 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Runtime.InteropServices; -using ELFSharp.ELF; -using ELFSharp.ELF.Sections; -using ELFSharp.ELF.Segments; -using System.Reflection; -using BizHawk.Common; -using System.Security.Cryptography; -using System.IO; -using System.Collections.Concurrent; -using System.Threading; - -namespace BizHawk.Emulation.Cores -{ - public sealed class ElfRunner : IImportResolver, IDisposable, IMonitor - { - // TODO: a lot of things only work with our elves and aren't fully generalized - - private ELF _elf; - private byte[] _elfhash; - - /// - /// executable is loaded here - /// - private MemoryBlock _base; - /// - /// standard malloc() heap - /// - private Heap _heap; - - /// - /// sealed heap (writable only during init) - /// - private Heap _sealedheap; - - /// - /// invisible heap (not savestated, use with care) - /// - private Heap _invisibleheap; - - /// - /// _base.Start, or 0 if we were relocated and so don't need to be swapped - /// - private ulong _lockkey; - - private long _loadoffset; - private Dictionary> _symdict; - private List> _symlist; - - /// - /// everything to clean up at dispose time - /// - private List _disposeList = new List(); - - /// - /// everything to swap in for context switches - /// - private List _memoryBlocks = new List(); - - private ulong GetHeapStart(ulong prevend) - { - // if relocatable, we won't have constant pointers, so put the heap anywhere - // otherwise, put the heap at a canonical location aligned 1MB from the end of the elf, then incremented 16MB - ulong heapstart = HasRelocations() ? 0 : ((prevend - 1) | 0xfffff) + 0x1000001; - return heapstart; - } - - public ElfRunner(string filename, long heapsize, long sealedheapsize, long invisibleheapsize) - { - using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) - { - _elfhash = Hash(fs); - } - - // todo: hack up this baby to take Streams - _elf = ELFReader.Load(filename); - - var loadsegs = _elf.Segments.Where(s => s.Type == SegmentType.Load); - - long orig_start = loadsegs.Min(s => s.Address); - orig_start &= ~(Environment.SystemPageSize - 1); - long orig_end = loadsegs.Max(s => s.Address + s.Size); - if (HasRelocations()) - { - _base = new MemoryBlock((ulong)(orig_end - orig_start)); - _loadoffset = (long)_base.Start - orig_start; - _lockkey = 0; - } - else - { - _lockkey = (ulong)orig_start; - _base = new MemoryBlock(_lockkey, (ulong)(orig_end - orig_start)); - _loadoffset = 0; - Enter(); - } - - try - { - _disposeList.Add(_base); - _memoryBlocks.Add(_base); - _base.Activate(); - _base.Protect(_base.Start, _base.Size, MemoryBlock.Protection.RW); - - foreach (var seg in loadsegs) - { - var data = seg.GetContents(); - Marshal.Copy(data, 0, Z.SS(seg.Address + _loadoffset), data.Length); - } - RegisterSymbols(); - ProcessRelocations(); - - _base.Protect(_base.Start, _base.Size, MemoryBlock.Protection.R); - - foreach (var sec in _elf.Sections.Where(s => (s.Flags & SectionFlags.Allocatable) != 0)) - { - if ((sec.Flags & SectionFlags.Executable) != 0) - _base.Protect((ulong)(sec.LoadAddress + _loadoffset), (ulong)sec.Size, MemoryBlock.Protection.RX); - else if ((sec.Flags & SectionFlags.Writable) != 0) - _base.Protect((ulong)(sec.LoadAddress + _loadoffset), (ulong)sec.Size, MemoryBlock.Protection.RW); - } - - ulong end = _base.End; - - if (heapsize > 0) - { - _heap = new Heap(GetHeapStart(end), (ulong)heapsize, "sbrk-heap"); - _heap.Memory.Activate(); - end = _heap.Memory.End; - _disposeList.Add(_heap); - _memoryBlocks.Add(_heap.Memory); - } - - if (sealedheapsize > 0) - { - _sealedheap = new Heap(GetHeapStart(end), (ulong)sealedheapsize, "sealed-heap"); - _sealedheap.Memory.Activate(); - end = _sealedheap.Memory.End; - _disposeList.Add(_sealedheap); - _memoryBlocks.Add(_sealedheap.Memory); - } - - if (invisibleheapsize > 0) - { - _invisibleheap = new Heap(GetHeapStart(end), (ulong)invisibleheapsize, "invisible-heap"); - _invisibleheap.Memory.Activate(); - end = _invisibleheap.Memory.End; - _disposeList.Add(_invisibleheap); - _memoryBlocks.Add(_invisibleheap.Memory); - } - - ConnectAllClibPatches(); - Console.WriteLine("Loaded {0}@{1:X16}", filename, _base.Start); - foreach (var sec in _elf.Sections.Where(s => s.LoadAddress != 0)) - { - Console.WriteLine(" {0}@{1:X16}, size {2}", sec.Name.PadLeft(20), sec.LoadAddress + _loadoffset, sec.Size.ToString().PadLeft(12)); - } - - PrintTopSavableSymbols(); - } - catch - { - Dispose(); - throw; - } - finally - { - Exit(); - } - } - - private void PrintTopSavableSymbols() - { - Console.WriteLine("Top savestate symbols:"); - foreach (var text in _symlist - .Where(s => s.PointedSection != null && (s.PointedSection.Flags & SectionFlags.Writable) != 0) - .OrderByDescending(s => s.Size) - .Take(30) - .Select(s => string.Format("{0} size {1}", s.Name, s.Size))) - { - Console.WriteLine(text); - } - } - - private class Elf32_Rel - { - public long Address; - public byte Type; - public int SymbolIdx; - public long Addend; - - public Elf32_Rel(byte[] data, int start, int len) - { - if (len == 8 || len == 12) - { - Address = BitConverter.ToInt32(data, start); - Type = data[start + 4]; - SymbolIdx = (int)(BitConverter.ToUInt32(data, start + 4) >> 8); - Addend = data.Length == 12 ? BitConverter.ToInt32(data, start + 8) : 0; - } - else - { - throw new InvalidOperationException(); - } - } - } - - private bool HasRelocations() - { - return _elf.Sections.Any(s => s.Name.StartsWith(".rel")); - } - - // elfsharp does not read relocation tables, so there - private void ProcessRelocations() - { - // todo: amd64 - foreach (var rel in _elf.Sections.Where(s => s.Name.StartsWith(".rel"))) - { - byte[] data = rel.GetContents(); - var symbols = Enumerable.Range(0, data.Length / 8) - .Select(i => new Elf32_Rel(data, i * 8, 8)); - foreach (var symbol in symbols) - { - ApplyRelocation(symbol); - } - } - } - private void ApplyRelocation(Elf32_Rel rel) - { - // http://flint.cs.yale.edu/cs422/doc/ELF_Format.pdf - // this is probably mostly wrong - - long val = 0; - long A = rel.Addend; - // since all symbols were moved by the same amount, just add _loadoffset here - long S = _symlist[rel.SymbolIdx].Value + _loadoffset; - long B = _loadoffset; - switch (rel.Type) - { - case 0: val = 0; break; - case 1: val = S + A; break; - case 2: throw new NotImplementedException(); - case 3: throw new NotImplementedException(); - case 4: throw new NotImplementedException(); - case 5: val = 0; break; - case 6: val = S; break; - case 7: val = S; break; - case 8: val = B + A; break; - case 9: throw new NotImplementedException(); - case 10: throw new NotImplementedException(); - default: throw new InvalidOperationException(); - } - byte[] tmp = new byte[4]; - Marshal.Copy((IntPtr)(rel.Address + _loadoffset), tmp, 0, 4); - long currentVal = BitConverter.ToUInt32(tmp, 0); - tmp = BitConverter.GetBytes((uint)(currentVal + val)); - Marshal.Copy(tmp, 0, (IntPtr)(rel.Address + _loadoffset), 4); - } - - private void RegisterSymbols() - { - var symbols = ((ISymbolTable)_elf.GetSection(".symtab")) - .Entries - .Cast>(); - - // when there are duplicate names, don't register either in the dictionary - _symdict = symbols - .GroupBy(e => e.Name) - .Where(g => g.Count() == 1) - .ToDictionary(g => g.Key, g => g.First()); - - _symlist = symbols.ToList(); - } - - public void Dispose() - { - // we don't need to activate to dispose - Dispose(true); - //GC.SuppressFinalize(this); - } - - public void Seal() - { - Enter(); - try - { - _sealedheap.Seal(); - } - finally - { - Exit(); - } - } - - //~ElfRunner() - //{ - // Dispose(false); - //} - - private void Dispose(bool disposing) - { - if (disposing) - { - foreach (var d in _disposeList) - d.Dispose(); - _disposeList.Clear(); - _memoryBlocks.Clear(); - _base = null; - _heap = null; - _sealedheap = null; - _invisibleheap = null; - } - } - - - #region clib monkeypatches - - // our clib expects a few function pointers to be defined for it - - /// - /// abort() / other abnormal situation - /// - /// desired exit code - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate void Trap_D(); - - /// - /// expand heap - /// - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate IntPtr Sbrk_D(UIntPtr n); - - /// - /// output a string - /// - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate void DebugPuts_D(string s); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate IntPtr SbrkSealed_D(UIntPtr n); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate IntPtr SbrkInvisible_D(UIntPtr n); - - [CLibPatch("_ecl_trap")] - private void Trap() - { - throw new InvalidOperationException("Waterbox code trapped!"); - } - - [CLibPatch("_ecl_sbrk")] - private IntPtr Sbrk(UIntPtr n) - { - return Z.US(_heap.Allocate((ulong)n, 1)); - } - - [CLibPatch("_ecl_debug_puts")] - private void DebugPuts(string s) - { - Console.WriteLine("Waterbox debug puts: {0}", s); - } - - [CLibPatch("_ecl_sbrk_sealed")] - private IntPtr SbrkSealed(UIntPtr n) - { - return Z.US(_sealedheap.Allocate((ulong)n, 16)); - } - - [CLibPatch("_ecl_sbrk_invisible")] - private IntPtr SbrkInvisible(UIntPtr n) - { - return Z.US(_invisibleheap.Allocate((ulong)n, 16)); - } - - /// - /// list of delegates that need to not be GCed - /// - private List _delegates = new List(); - - private void ConnectAllClibPatches() - { - _delegates.Clear(); // in case we're reconnecting - - var methods = GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) - .Where(mi => mi.GetCustomAttributes(typeof(CLibPatchAttribute), false).Length > 0); - foreach (var mi in methods) - { - var delegateType = GetType().GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic) - .Single(t => t.Name == mi.Name + "_D"); - var del = Delegate.CreateDelegate(delegateType, this, mi); - IntPtr ptr = Marshal.GetFunctionPointerForDelegate(del); - _delegates.Add(del); - var sym = _symdict[((CLibPatchAttribute)mi.GetCustomAttributes(typeof(CLibPatchAttribute), false)[0]).NativeName]; - if (sym.Size != IntPtr.Size) - throw new InvalidOperationException("Unexpected function pointer size patching clib!"); - IntPtr dest = Z.SS(sym.Value + _loadoffset); - Marshal.Copy(new[] { ptr }, 0, dest, 1); - } - } - - [AttributeUsage(AttributeTargets.Method)] - private class CLibPatchAttribute : Attribute - { - public string NativeName { get; private set; } - public CLibPatchAttribute(string nativeName) - { - NativeName = nativeName; - } - } - - #endregion - - public IntPtr Resolve(string entryPoint) - { - SymbolEntry sym; - if (_symdict.TryGetValue(entryPoint, out sym)) - { - return Z.SS(sym.Value + _loadoffset); - } - else - { - return IntPtr.Zero; - } - } - - /// - /// true if the IMonitor should be used for native calls - /// - public bool ShouldMonitor { get { return _lockkey != 0; } } - - // any ElfRunner is assumed to conflict with any other ElfRunner at the same base address, - // but not any other starting address. so don't put them too close together! - - private class LockInfo - { - public object Sync; - public ElfRunner Loaded; - } - - private static readonly ConcurrentDictionary LockInfos = new ConcurrentDictionary(); - - static ElfRunner() - { - LockInfos.GetOrAdd(0, new LockInfo()); // any errant attempt to lock when ShouldMonitor == false will result in NRE - } - - /// - /// acquire lock and swap this into memory - /// - public void Enter() - { - var li = LockInfos.GetOrAdd(_lockkey, new LockInfo { Sync = new object() }); - Monitor.Enter(li.Sync); - if (li.Loaded != this) - { - if (li.Loaded != null) - li.Loaded.DeactivateInternal(); - li.Loaded = null; - ActivateInternal(); - li.Loaded = this; - } - } - - /// - /// release lock - /// - public void Exit() - { - var li = LockInfos.GetOrAdd(_lockkey, new LockInfo { Sync = new object() }); - Monitor.Exit(li.Sync); - } - - private void DeactivateInternal() - { - Console.WriteLine("ElfRunner DeactivateInternal {0}", GetHashCode()); - foreach (var m in _memoryBlocks) - m.Deactivate(); - } - - private void ActivateInternal() - { - Console.WriteLine("ElfRunner ActivateInternal {0}", GetHashCode()); - foreach (var m in _memoryBlocks) - m.Activate(); - } - - #region state - - const ulong MAGIC = 0xb00b1e5b00b1e569; - - public void SaveStateBinary(BinaryWriter bw) - { - Enter(); - try - { - bw.Write(MAGIC); - bw.Write(_elfhash); - bw.Write(_loadoffset); - foreach (var sec in _elf.Sections.Where(s => (s.Flags & SectionFlags.Writable) != 0)) - { - var ms = _base.GetStream((ulong)(sec.LoadAddress + _loadoffset), (ulong)sec.Size, false); - bw.Write(sec.Size); - ms.CopyTo(bw.BaseStream); - } - - if (_heap != null) _heap.SaveStateBinary(bw); - if (_sealedheap != null) _sealedheap.SaveStateBinary(bw); - bw.Write(MAGIC); - } - finally - { - Exit(); - } - } - - public void LoadStateBinary(BinaryReader br) - { - Enter(); - try - { - if (br.ReadUInt64() != MAGIC) - throw new InvalidOperationException("Magic not magic enough!"); - if (!br.ReadBytes(_elfhash.Length).SequenceEqual(_elfhash)) - throw new InvalidOperationException("Elf changed disguise!"); - if (br.ReadInt64() != _loadoffset) - throw new InvalidOperationException("Trickys elves moved on you!"); - - foreach (var sec in _elf.Sections.Where(s => (s.Flags & SectionFlags.Writable) != 0)) - { - var len = br.ReadInt64(); - if (sec.Size != len) - throw new InvalidOperationException("Unexpected section size for " + sec.Name); - var ms = _base.GetStream((ulong)(sec.LoadAddress + _loadoffset), (ulong)sec.Size, true); - CopySome(br.BaseStream, ms, len); - } - - if (_heap != null) _heap.LoadStateBinary(br); - if (_sealedheap != null) _sealedheap.LoadStateBinary(br); - if (br.ReadUInt64() != MAGIC) - throw new InvalidOperationException("Magic not magic enough!"); - - // the syscall trampolines were overwritten in loadstate (they're in .bss), and if we're cross-session, - // are no longer valid. cores must similiarly resend any external pointers they gave the core. - ConnectAllClibPatches(); - } - finally - { - Exit(); - } - } - - #endregion - - #region utils - - private static void CopySome(Stream src, Stream dst, long len) - { - var buff = new byte[4096]; - while (len > 0) - { - int r = src.Read(buff, 0, (int)Math.Min(len, 4096)); - dst.Write(buff, 0, r); - len -= r; - } - } - - private static byte[] Hash(byte[] data) - { - using (var h = SHA1.Create()) - { - return h.ComputeHash(data); - } - } - - private static byte[] Hash(Stream s) - { - using (var h = SHA1.Create()) - { - return h.ComputeHash(s); - } - } - - private byte[] HashSection(ulong ptr, ulong len) - { - using (var h = SHA1.Create()) - { - var ms = _base.GetStream(ptr, len, false); - return h.ComputeHash(ms); - } - } - - /// - /// a simple grow-only fixed max size heap - /// - private sealed class Heap : IDisposable - { - public MemoryBlock Memory { get; private set; } - /// - /// name, used in identifying errors - /// - public string Name { get; private set; } - /// - /// total number of bytes used - /// - public ulong Used { get; private set; } - - /// - /// true if the heap has been sealed, preventing further changes - /// - public bool Sealed { get; private set; } - - private byte[] _hash; - - public Heap(ulong start, ulong size, string name) - { - Memory = new MemoryBlock(start, size); - Used = 0; - Name = name; - } - - private void EnsureAlignment(int align) - { - if (align > 1) - { - ulong newused = ((Used - 1) | (ulong)(align - 1)) + 1; - if (newused > Memory.Size) - { - throw new InvalidOperationException(string.Format("Failed to meet alignment {0} on heap {1}", align, Name)); - } - Used = newused; - } - } - - public ulong Allocate(ulong size, int align) - { - if (Sealed) - throw new InvalidOperationException(string.Format("Attempt made to allocate from sealed heap {0}", Name)); - - EnsureAlignment(align); - - ulong newused = Used + size; - if (newused > Memory.Size) - { - throw new InvalidOperationException(string.Format("Failed to allocate {0} bytes from heap {1}", size, Name)); - } - ulong ret = Memory.Start + Used; - Memory.Protect(ret, newused - Used, MemoryBlock.Protection.RW); - Used = newused; - Console.WriteLine("Allocated {0} bytes on {1}", size, Name); - return ret; - } - - public void Seal() - { - if (!Sealed) - { - Memory.Protect(Memory.Start, Memory.Size, MemoryBlock.Protection.R); - _hash = Hash(Memory.GetStream(Memory.Start, Used, false)); - Sealed = true; - } - else - { - throw new InvalidOperationException(string.Format("Attempt to reseal heap {0}", Name)); - } - } - - public void SaveStateBinary(BinaryWriter bw) - { - bw.Write(Name); - bw.Write(Used); - if (!Sealed) - { - var ms = Memory.GetStream(Memory.Start, Used, false); - ms.CopyTo(bw.BaseStream); - } - else - { - bw.Write(_hash); - } - } - - public void LoadStateBinary(BinaryReader br) - { - var name = br.ReadString(); - if (name != Name) - throw new InvalidOperationException(string.Format("Name did not match for heap {0}", Name)); - var used = br.ReadUInt64(); - if (used > Memory.Size) - throw new InvalidOperationException(string.Format("Heap {0} used {1} larger than available {2}", Name, used, Memory.Size)); - if (!Sealed) - { - Memory.Protect(Memory.Start, Memory.Size, MemoryBlock.Protection.None); - Memory.Protect(Memory.Start, used, MemoryBlock.Protection.RW); - var ms = Memory.GetStream(Memory.Start, used, true); - CopySome(br.BaseStream, ms, (long)used); - Used = used; - } - else - { - var hash = br.ReadBytes(_hash.Length); - if (!hash.SequenceEqual(_hash)) - { - throw new InvalidOperationException(string.Format("Hash did not match for heap {0}. Is this the same rom?")); - } - } - } - - public void Dispose() - { - if (Memory != null) - { - Memory.Dispose(); - Memory = null; - } - } - } - - #endregion - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; +using ELFSharp.ELF; +using ELFSharp.ELF.Sections; +using ELFSharp.ELF.Segments; +using System.Reflection; +using BizHawk.Common; +using System.Security.Cryptography; +using System.IO; +using System.Collections.Concurrent; +using System.Threading; +using BizHawk.Emulation.Common; +using BizHawk.Common.BizInvoke; + +namespace BizHawk.Emulation.Cores.Waterbox +{ + public sealed class ElfRunner : Swappable, IImportResolver, IBinaryStateable + { + // TODO: a lot of things only work with our elves and aren't fully generalized + + private ELF _elf; + private byte[] _elfhash; + + /// + /// executable is loaded here + /// + private MemoryBlock _base; + /// + /// standard malloc() heap + /// + private Heap _heap; + + /// + /// sealed heap (writable only during init) + /// + private Heap _sealedheap; + + /// + /// invisible heap (not savestated, use with care) + /// + private Heap _invisibleheap; + + private long _loadoffset; + private Dictionary> _symdict; + private List> _symlist; + + /// + /// everything to clean up at dispose time + /// + private List _disposeList = new List(); + + private ulong GetHeapStart(ulong prevend) + { + // if relocatable, we won't have constant pointers, so put the heap anywhere + // otherwise, put the heap at a canonical location aligned 1MB from the end of the elf, then incremented 16MB + ulong heapstart = HasRelocations() ? 0 : ((prevend - 1) | 0xfffff) + 0x1000001; + return heapstart; + } + + public ElfRunner(string filename, long heapsize, long sealedheapsize, long invisibleheapsize) + { + using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) + { + _elfhash = WaterboxUtils.Hash(fs); + } + + // todo: hack up this baby to take Streams + _elf = ELFReader.Load(filename); + + var loadsegs = _elf.Segments.Where(s => s.Type == SegmentType.Load); + + long orig_start = loadsegs.Min(s => s.Address); + orig_start &= ~(Environment.SystemPageSize - 1); + long orig_end = loadsegs.Max(s => s.Address + s.Size); + if (HasRelocations()) + { + _base = new MemoryBlock((ulong)(orig_end - orig_start)); + _loadoffset = (long)_base.Start - orig_start; + Initialize(0); + } + else + { + Initialize((ulong)orig_start); + _base = new MemoryBlock((ulong)orig_start, (ulong)(orig_end - orig_start)); + _loadoffset = 0; + Enter(); + } + + try + { + _disposeList.Add(_base); + AddMemoryBlock(_base, "elf"); + _base.Activate(); + _base.Protect(_base.Start, _base.Size, MemoryBlock.Protection.RW); + + foreach (var seg in loadsegs) + { + var data = seg.GetContents(); + Marshal.Copy(data, 0, Z.SS(seg.Address + _loadoffset), data.Length); + } + RegisterSymbols(); + ProcessRelocations(); + + _base.Protect(_base.Start, _base.Size, MemoryBlock.Protection.R); + + foreach (var sec in _elf.Sections.Where(s => (s.Flags & SectionFlags.Allocatable) != 0)) + { + if ((sec.Flags & SectionFlags.Executable) != 0) + _base.Protect((ulong)(sec.LoadAddress + _loadoffset), (ulong)sec.Size, MemoryBlock.Protection.RX); + else if ((sec.Flags & SectionFlags.Writable) != 0) + _base.Protect((ulong)(sec.LoadAddress + _loadoffset), (ulong)sec.Size, MemoryBlock.Protection.RW); + } + + ulong end = _base.End; + + if (heapsize > 0) + { + _heap = new Heap(GetHeapStart(end), (ulong)heapsize, "sbrk-heap"); + _heap.Memory.Activate(); + end = _heap.Memory.End; + _disposeList.Add(_heap); + AddMemoryBlock(_heap.Memory, "sbrk - heap"); + } + + if (sealedheapsize > 0) + { + _sealedheap = new Heap(GetHeapStart(end), (ulong)sealedheapsize, "sealed-heap"); + _sealedheap.Memory.Activate(); + end = _sealedheap.Memory.End; + _disposeList.Add(_sealedheap); + AddMemoryBlock(_sealedheap.Memory, "sealed-heap"); + } + + if (invisibleheapsize > 0) + { + _invisibleheap = new Heap(GetHeapStart(end), (ulong)invisibleheapsize, "invisible-heap"); + _invisibleheap.Memory.Activate(); + end = _invisibleheap.Memory.End; + _disposeList.Add(_invisibleheap); + AddMemoryBlock(_invisibleheap.Memory, "invisible-heap"); + } + + ConnectAllClibPatches(); + Console.WriteLine("Loaded {0}@{1:X16}", filename, _base.Start); + foreach (var sec in _elf.Sections.Where(s => s.LoadAddress != 0)) + { + Console.WriteLine(" {0}@{1:X16}, size {2}", sec.Name.PadLeft(20), sec.LoadAddress + _loadoffset, sec.Size.ToString().PadLeft(12)); + } + + PrintTopSavableSymbols(); + } + catch + { + Dispose(); + throw; + } + finally + { + Exit(); + } + } + + private void PrintTopSavableSymbols() + { + Console.WriteLine("Top savestate symbols:"); + foreach (var text in _symlist + .Where(s => s.PointedSection != null && (s.PointedSection.Flags & SectionFlags.Writable) != 0) + .OrderByDescending(s => s.Size) + .Take(30) + .Select(s => string.Format("{0} size {1}", s.Name, s.Size))) + { + Console.WriteLine(text); + } + } + + private class Elf32_Rel + { + public long Address; + public byte Type; + public int SymbolIdx; + public long Addend; + + public Elf32_Rel(byte[] data, int start, int len) + { + if (len == 8 || len == 12) + { + Address = BitConverter.ToInt32(data, start); + Type = data[start + 4]; + SymbolIdx = (int)(BitConverter.ToUInt32(data, start + 4) >> 8); + Addend = data.Length == 12 ? BitConverter.ToInt32(data, start + 8) : 0; + } + else + { + throw new InvalidOperationException(); + } + } + } + + private bool HasRelocations() + { + return _elf.Sections.Any(s => s.Name.StartsWith(".rel")); + } + + // elfsharp does not read relocation tables, so there + private void ProcessRelocations() + { + // todo: amd64 + foreach (var rel in _elf.Sections.Where(s => s.Name.StartsWith(".rel"))) + { + byte[] data = rel.GetContents(); + var symbols = Enumerable.Range(0, data.Length / 8) + .Select(i => new Elf32_Rel(data, i * 8, 8)); + foreach (var symbol in symbols) + { + ApplyRelocation(symbol); + } + } + } + private void ApplyRelocation(Elf32_Rel rel) + { + // http://flint.cs.yale.edu/cs422/doc/ELF_Format.pdf + // this is probably mostly wrong + + long val = 0; + long A = rel.Addend; + // since all symbols were moved by the same amount, just add _loadoffset here + long S = _symlist[rel.SymbolIdx].Value + _loadoffset; + long B = _loadoffset; + switch (rel.Type) + { + case 0: val = 0; break; + case 1: val = S + A; break; + case 2: throw new NotImplementedException(); + case 3: throw new NotImplementedException(); + case 4: throw new NotImplementedException(); + case 5: val = 0; break; + case 6: val = S; break; + case 7: val = S; break; + case 8: val = B + A; break; + case 9: throw new NotImplementedException(); + case 10: throw new NotImplementedException(); + default: throw new InvalidOperationException(); + } + byte[] tmp = new byte[4]; + Marshal.Copy((IntPtr)(rel.Address + _loadoffset), tmp, 0, 4); + long currentVal = BitConverter.ToUInt32(tmp, 0); + tmp = BitConverter.GetBytes((uint)(currentVal + val)); + Marshal.Copy(tmp, 0, (IntPtr)(rel.Address + _loadoffset), 4); + } + + private void RegisterSymbols() + { + var symbols = ((ISymbolTable)_elf.GetSection(".symtab")) + .Entries + .Cast>(); + + // when there are duplicate names, don't register either in the dictionary + _symdict = symbols + .GroupBy(e => e.Name) + .Where(g => g.Count() == 1) + .ToDictionary(g => g.Key, g => g.First()); + + _symlist = symbols.ToList(); + } + + public void Seal() + { + Enter(); + try + { + _sealedheap.Seal(); + } + finally + { + Exit(); + } + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (disposing) + { + foreach (var d in _disposeList) + d.Dispose(); + _disposeList.Clear(); + PurgeMemoryBlocks(); + _base = null; + _heap = null; + _sealedheap = null; + _invisibleheap = null; + } + } + + #region clib monkeypatches + + // our clib expects a few function pointers to be defined for it + + /// + /// abort() / other abnormal situation + /// + /// desired exit code + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate void Trap_D(); + + /// + /// expand heap + /// + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate IntPtr Sbrk_D(UIntPtr n); + + /// + /// output a string + /// + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate void DebugPuts_D(string s); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate IntPtr SbrkSealed_D(UIntPtr n); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate IntPtr SbrkInvisible_D(UIntPtr n); + + [CLibPatch("_ecl_trap")] + private void Trap() + { + throw new InvalidOperationException("Waterbox code trapped!"); + } + + [CLibPatch("_ecl_sbrk")] + private IntPtr Sbrk(UIntPtr n) + { + return Z.US(_heap.Allocate((ulong)n, 1)); + } + + [CLibPatch("_ecl_debug_puts")] + private void DebugPuts(string s) + { + Console.WriteLine("Waterbox debug puts: {0}", s); + } + + [CLibPatch("_ecl_sbrk_sealed")] + private IntPtr SbrkSealed(UIntPtr n) + { + return Z.US(_sealedheap.Allocate((ulong)n, 16)); + } + + [CLibPatch("_ecl_sbrk_invisible")] + private IntPtr SbrkInvisible(UIntPtr n) + { + return Z.US(_invisibleheap.Allocate((ulong)n, 16)); + } + + /// + /// list of delegates that need to not be GCed + /// + private List _delegates = new List(); + + private void ConnectAllClibPatches() + { + _delegates.Clear(); // in case we're reconnecting + + var methods = GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) + .Where(mi => mi.GetCustomAttributes(typeof(CLibPatchAttribute), false).Length > 0); + foreach (var mi in methods) + { + var delegateType = GetType().GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic) + .Single(t => t.Name == mi.Name + "_D"); + var del = Delegate.CreateDelegate(delegateType, this, mi); + IntPtr ptr = Marshal.GetFunctionPointerForDelegate(del); + _delegates.Add(del); + var sym = _symdict[((CLibPatchAttribute)mi.GetCustomAttributes(typeof(CLibPatchAttribute), false)[0]).NativeName]; + if (sym.Size != IntPtr.Size) + throw new InvalidOperationException("Unexpected function pointer size patching clib!"); + IntPtr dest = Z.SS(sym.Value + _loadoffset); + Marshal.Copy(new[] { ptr }, 0, dest, 1); + } + } + + [AttributeUsage(AttributeTargets.Method)] + private class CLibPatchAttribute : Attribute + { + public string NativeName { get; private set; } + public CLibPatchAttribute(string nativeName) + { + NativeName = nativeName; + } + } + + #endregion + + public IntPtr Resolve(string entryPoint) + { + SymbolEntry sym; + if (_symdict.TryGetValue(entryPoint, out sym)) + { + return Z.SS(sym.Value + _loadoffset); + } + else + { + return IntPtr.Zero; + } + } + + #region state + + const ulong MAGIC = 0xb00b1e5b00b1e569; + + public void SaveStateBinary(BinaryWriter bw) + { + Enter(); + try + { + bw.Write(MAGIC); + bw.Write(_elfhash); + bw.Write(_loadoffset); + foreach (var sec in _elf.Sections.Where(s => (s.Flags & SectionFlags.Writable) != 0)) + { + var ms = _base.GetStream((ulong)(sec.LoadAddress + _loadoffset), (ulong)sec.Size, false); + bw.Write(sec.Size); + ms.CopyTo(bw.BaseStream); + } + + if (_heap != null) _heap.SaveStateBinary(bw); + if (_sealedheap != null) _sealedheap.SaveStateBinary(bw); + bw.Write(MAGIC); + } + finally + { + Exit(); + } + } + + public void LoadStateBinary(BinaryReader br) + { + Enter(); + try + { + if (br.ReadUInt64() != MAGIC) + throw new InvalidOperationException("Magic not magic enough!"); + if (!br.ReadBytes(_elfhash.Length).SequenceEqual(_elfhash)) + throw new InvalidOperationException("Elf changed disguise!"); + if (br.ReadInt64() != _loadoffset) + throw new InvalidOperationException("Trickys elves moved on you!"); + + foreach (var sec in _elf.Sections.Where(s => (s.Flags & SectionFlags.Writable) != 0)) + { + var len = br.ReadInt64(); + if (sec.Size != len) + throw new InvalidOperationException("Unexpected section size for " + sec.Name); + var ms = _base.GetStream((ulong)(sec.LoadAddress + _loadoffset), (ulong)sec.Size, true); + WaterboxUtils.CopySome(br.BaseStream, ms, len); + } + + if (_heap != null) _heap.LoadStateBinary(br); + if (_sealedheap != null) _sealedheap.LoadStateBinary(br); + if (br.ReadUInt64() != MAGIC) + throw new InvalidOperationException("Magic not magic enough!"); + + // the syscall trampolines were overwritten in loadstate (they're in .bss), and if we're cross-session, + // are no longer valid. cores must similiarly resend any external pointers they gave the core. + ConnectAllClibPatches(); + } + finally + { + Exit(); + } + } + + #endregion + + #region utils + + private byte[] HashSection(ulong ptr, ulong len) + { + using (var h = SHA1.Create()) + { + var ms = _base.GetStream(ptr, len, false); + return h.ComputeHash(ms); + } + } + + #endregion + } +} diff --git a/BizHawk.Emulation.Cores/Waterbox/Heap.cs b/BizHawk.Emulation.Cores/Waterbox/Heap.cs new file mode 100644 index 0000000000..26eb952972 --- /dev/null +++ b/BizHawk.Emulation.Cores/Waterbox/Heap.cs @@ -0,0 +1,146 @@ +using BizHawk.Common.BizInvoke; +using BizHawk.Emulation.Common; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace BizHawk.Emulation.Cores.Waterbox +{ + /// + /// a simple grow-only fixed max size heap + /// + internal sealed class Heap : IBinaryStateable, IDisposable + { + public MemoryBlock Memory { get; private set; } + /// + /// name, used in identifying errors + /// + public string Name { get; private set; } + /// + /// total number of bytes used + /// + public ulong Used { get; private set; } + + /// + /// true if the heap has been sealed, preventing further changes + /// + public bool Sealed { get; private set; } + + private byte[] _hash; + + public Heap(ulong start, ulong size, string name) + { + Memory = new MemoryBlock(start, size); + Used = 0; + Name = name; + Console.WriteLine("Created heap `{1}` at {0:x16}:{2:x16}", start, name, start + size); + } + + private ulong EnsureAlignment(int align) + { + if (align > 1) + { + ulong newused = ((Used - 1) | (ulong)(align - 1)) + 1; + if (newused > Memory.Size) + { + throw new InvalidOperationException(string.Format("Failed to meet alignment {0} on heap {1}", align, Name)); + } + return newused; + } + return Used; + } + + public ulong Allocate(ulong size, int align) + { + if (Sealed) + throw new InvalidOperationException(string.Format("Attempt made to allocate from sealed heap {0}", Name)); + + ulong allocstart = EnsureAlignment(align); + ulong newused = allocstart + size; + if (newused > Memory.Size) + { + throw new InvalidOperationException(string.Format("Failed to allocate {0} bytes from heap {1}", size, Name)); + } + ulong ret = Memory.Start + allocstart; + Memory.Protect(Memory.Start + Used, newused - Used, MemoryBlock.Protection.RW); + Used = newused; + Console.WriteLine($"Allocated {size} bytes on {Name}, utilization {Used}/{Memory.Size} ({100.0 * Used / Memory.Size:0.#}%)"); + return ret; + } + + public void Seal() + { + if (!Sealed) + { + Memory.Protect(Memory.Start, Used, MemoryBlock.Protection.R); + _hash = WaterboxUtils.Hash(Memory.GetStream(Memory.Start, Used, false)); + Sealed = true; + } + else + { + throw new InvalidOperationException(string.Format("Attempt to reseal heap {0}", Name)); + } + } + + public void SaveStateBinary(BinaryWriter bw) + { + bw.Write(Name); + bw.Write(Used); + if (!Sealed) + { + bw.Write(Memory.XorHash); + var ms = Memory.GetXorStream(Memory.Start, WaterboxUtils.AlignUp(Used), false); + ms.CopyTo(bw.BaseStream); + } + else + { + bw.Write(_hash); + } + } + + public void LoadStateBinary(BinaryReader br) + { + var name = br.ReadString(); + if (name != Name) + // probable cause: internal error + throw new InvalidOperationException(string.Format("Name did not match for heap {0}", Name)); + var used = br.ReadUInt64(); + if (used > Memory.Size) + throw new InvalidOperationException(string.Format("Heap {0} used {1} larger than available {2}", Name, used, Memory.Size)); + if (!Sealed) + { + var hash = br.ReadBytes(Memory.XorHash.Length); + if (!hash.SequenceEqual(Memory.XorHash)) + { + throw new InvalidOperationException(string.Format("Hash did not match for heap {0}. Is this the same rom with the same SyncSettings?", Name)); + } + var usedAligned = WaterboxUtils.AlignUp(used); + + Memory.Protect(Memory.Start, Memory.Size, MemoryBlock.Protection.None); + Memory.Protect(Memory.Start, used, MemoryBlock.Protection.RW); + var ms = Memory.GetXorStream(Memory.Start, usedAligned, true); + WaterboxUtils.CopySome(br.BaseStream, ms, (long)usedAligned); + Used = used; + } + else + { + var hash = br.ReadBytes(_hash.Length); + if (!hash.SequenceEqual(_hash)) + { + throw new InvalidOperationException(string.Format("Hash did not match for heap {0}. Is this the same rom with the same SyncSettings?", Name)); + } + } + } + + public void Dispose() + { + if (Memory != null) + { + Memory.Dispose(); + Memory = null; + } + } + } +} diff --git a/BizHawk.Emulation.Cores/Waterbox/LibWaterboxCore.cs b/BizHawk.Emulation.Cores/Waterbox/LibWaterboxCore.cs new file mode 100644 index 0000000000..b1fd9ee0d6 --- /dev/null +++ b/BizHawk.Emulation.Cores/Waterbox/LibWaterboxCore.cs @@ -0,0 +1,208 @@ +using BizHawk.Common; +using BizHawk.Common.BizInvoke; +using BizHawk.Emulation.Common; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Waterbox +{ + public abstract class LibWaterboxCore + { + public const CallingConvention CC = CallingConvention.Cdecl; + + [StructLayout(LayoutKind.Sequential)] + public class FrameInfo + { + /// + /// pointer to the video buffer; set by frontend, filled by backend + /// + public IntPtr VideoBuffer; + /// + /// pointer to the sound buffer; set by frontend, filled by backend + /// + public IntPtr SoundBuffer; + /// + /// total number of cycles emulated this frame; set by backend + /// + public long Cycles; + /// + /// width of the output image; set by backend + /// + public int Width; + /// + /// height of the output image; set by backend + /// + public int Height; + /// + /// total number of sample pairs produced; set by backend + /// + public int Samples; + /// + /// true if controllers were not read; set by backend + /// + public int Lagged; + } + + [Flags] + public enum MemoryDomainFlags : int + { + None = 0, + /// + /// if false, the domain MUST NOT be written to. + /// in some cases, a segmentation violation might occur + /// + Writable = 1, + /// + /// if true, this memory domain should be used in saveram. + /// can be ignored if the core provides its own saveram implementation + /// + Saverammable = 2, + /// + /// if true, domain is filled with ones (FF) by default, instead of zeros. + /// used in calculating SaveRamModified + /// + OneFilled = 4, + /// + /// desginates the default memory domain + /// + Primary = 8, + /// + /// if true, the most significant bytes are first in multibyte words + /// + YugeEndian = 16, + /// + /// native wordsize. only a hint + /// + WordSize1 = 32, + /// + /// native wordsize. only a hint + /// + WordSize2 = 64, + /// + /// native wordsize. only a hint + /// + WordSize4 = 128, + /// + /// native wordsize. only a hint + /// + WordSize8 = 256, + /// + /// for a yuge endian domain, if true, bytes are stored word-swapped from their native ordering + /// + Swapped = 512, + } + + [StructLayout(LayoutKind.Sequential)] + public struct MemoryArea + { + /// + /// pointer to the data in memory + /// + public IntPtr Data; + /// + /// null terminated strnig naming the memory domain + /// + public IntPtr Name; + /// + /// size of the domain + /// + public long Size; + /// + /// + /// + public MemoryDomainFlags Flags; + } + + [UnmanagedFunctionPointer(CC)] + public delegate void EmptyCallback(); + + public unsafe class WaterboxMemoryDomain : MemoryDomain + { + private readonly IntPtr _data; + private readonly IMonitor _monitor; + private readonly long _addressMangler; + + public override byte PeekByte(long addr) + { + if ((ulong)addr < (ulong)Size) + { + using (_monitor.EnterExit()) + { + return ((byte*)_data)[addr ^ _addressMangler]; + } + } + + throw new ArgumentOutOfRangeException(nameof(addr)); + } + + public override void PokeByte(long addr, byte val) + { + if (Writable) + { + if ((ulong)addr < (ulong)Size) + { + using (_monitor.EnterExit()) + { + ((byte*)_data)[addr ^ _addressMangler] = val; + } + } + else + { + throw new ArgumentOutOfRangeException(nameof(addr)); + } + } + } + + public WaterboxMemoryDomain(MemoryArea m, IMonitor monitor) + { + Name = Marshal.PtrToStringAnsi(m.Name); + EndianType = (m.Flags & MemoryDomainFlags.YugeEndian) != 0 ? Endian.Big : Endian.Little; + _data = m.Data; + Size = m.Size; + Writable = (m.Flags & MemoryDomainFlags.Writable) != 0; + if ((m.Flags & MemoryDomainFlags.WordSize1) != 0) + WordSize = 1; + else if ((m.Flags & MemoryDomainFlags.WordSize2) != 0) + WordSize = 2; + else if ((m.Flags & MemoryDomainFlags.WordSize4) != 0) + WordSize = 4; + else if ((m.Flags & MemoryDomainFlags.WordSize8) != 0) + WordSize = 8; + else + throw new InvalidOperationException("Unknown word size for memory domain"); + _monitor = monitor; + if ((m.Flags & MemoryDomainFlags.Swapped) != 0 && EndianType == Endian.Big) + { + _addressMangler = WordSize - 1; + } + else + { + _addressMangler = 0; + } + } + } + + [BizImport(CC)] + public abstract void FrameAdvance([In, Out] FrameInfo frame); + + [BizImport(CC)] + public abstract void GetMemoryAreas([In, Out] MemoryArea[] areas); + + [BizImport(CC)] + public abstract void SetInputCallback(EmptyCallback callback); + } + + /// + /// if a core implements this, it will be used for saveramming instead of memory domains + /// + interface ICustomSaveram + { + int GetSaveramSize(); + void PutSaveram(byte[] data, int size); + void GetSaveram(byte[] data, int size); + } +} diff --git a/BizHawk.Emulation.Cores/Waterbox/MapHeap.cs b/BizHawk.Emulation.Cores/Waterbox/MapHeap.cs new file mode 100644 index 0000000000..3ae6e57a7c --- /dev/null +++ b/BizHawk.Emulation.Cores/Waterbox/MapHeap.cs @@ -0,0 +1,366 @@ +using BizHawk.Emulation.Common; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using System.Runtime.InteropServices; +using BizHawk.Common.BizInvoke; + +namespace BizHawk.Emulation.Cores.Waterbox +{ + /// + /// a heap that supports basic alloc, free, and realloc calls + /// + internal sealed class MapHeap : IBinaryStateable, IDisposable + { + public MemoryBlock Memory { get; private set; } + /// + /// name, used in identifying errors + /// + public string Name { get; private set; } + + /// + /// total number of bytes allocated + /// + public ulong Used { get; private set; } + + /// + /// get a page index within the block + /// + private int GetPage(ulong addr) + { + return (int)((addr - Memory.Start) >> WaterboxUtils.PageShift); + } + + /// + /// get a start address for a page index within the block + /// + private ulong GetStartAddr(int page) + { + return ((ulong)page << WaterboxUtils.PageShift) + Memory.Start; + } + + private const MemoryBlock.Protection FREE = (MemoryBlock.Protection)255; + + private readonly MemoryBlock.Protection[] _pages; + private readonly byte[] _pagesAsBytes; + + public MapHeap(ulong start, ulong size, string name) + { + size = WaterboxUtils.AlignUp(size); + Memory = new MemoryBlock(start, size); + Name = name; + _pagesAsBytes = new byte[size >> WaterboxUtils.PageShift]; + _pages = (MemoryBlock.Protection[])(object)_pagesAsBytes; + for (var i = 0; i < _pages.Length; i++) + _pages[i] = FREE; + Console.WriteLine("Created mapheap `{1}` at {0:x16}:{2:x16}", start, name, start + size); + } + + // find consecutive unused pages to map + private int FindConsecutiveFreePages(int count) + { + return FindConsecutiveFreePagesAssumingFreed(count, -1, -1); + } + + // find consecutive unused pages to map, pretending that [startPage..startPage + numPages) is free + // used in realloc + private int FindConsecutiveFreePagesAssumingFreed(int count, int startPage, int numPages) + { + var starts = new List(); + var sizes = new List(); + + var currStart = 0; + for (var i = 0; i <= _pages.Length; i++) + { + if (i == _pages.Length || _pages[i] != FREE && (i < startPage || i >= startPage + numPages)) + { + if (currStart < i) + { + starts.Add(currStart); + var size = i - currStart; + if (size == count) + return currStart; + sizes.Add(i - currStart); + } + currStart = i + 1; + } + } + int bestIdx = -1; + int bestSize = int.MaxValue; + for (int i = 0; i < sizes.Count; i++) + { + if (sizes[i] < bestSize && sizes[i] >= count) + { + bestSize = sizes[i]; + bestIdx = i; + } + } + if (bestIdx != -1) + return starts[bestIdx]; + else + return -1; + } + + private void ProtectInternal(int startPage, int numPages, MemoryBlock.Protection prot, bool wasUsed) + { + for (var i = startPage; i < startPage + numPages; i++) + _pages[i] = prot; + + ulong start = GetStartAddr(startPage); + ulong length = ((ulong)numPages) << WaterboxUtils.PageShift; + if (prot == FREE) + { + Memory.Protect(start, length, MemoryBlock.Protection.RW); + WaterboxUtils.ZeroMemory(Z.US(start), (long)length); + Memory.Protect(start, length, MemoryBlock.Protection.None); + Used -= length; + Console.WriteLine($"Freed {length} bytes on {Name}, utilization {Used}/{Memory.Size} ({100.0 * Used / Memory.Size:0.#}%)"); + } + else + { + Memory.Protect(start, length, prot); + if (wasUsed) + { + Console.WriteLine($"Set protection for {length} bytes on {Name} to {prot}"); + } + else + { + Used += length; + Console.WriteLine($"Allocated {length} bytes on {Name}, utilization {Used}/{Memory.Size} ({100.0 * Used / Memory.Size:0.#}%)"); + } + } + } + + private void RefreshProtections(int startPage, int pageCount) + { + int ps = startPage; + for (int i = startPage; i < startPage + pageCount; i++) + { + if (i == startPage + pageCount - 1 || _pages[i] != _pages[i + 1]) + { + var p = _pages[i]; + ulong zstart = GetStartAddr(ps); + ulong zlength = (ulong)(i - ps + 1) << WaterboxUtils.PageShift; + Memory.Protect(zstart, zlength, p == FREE ? MemoryBlock.Protection.None : p); + ps = i + 1; + } + } + } + + private void RefreshAllProtections() + { + RefreshProtections(0, _pages.Length); + } + + private bool EnsureMapped(int startPage, int pageCount) + { + for (int i = startPage; i < startPage + pageCount; i++) + if (_pages[i] == FREE) + return false; + return true; + } + + public ulong Map(ulong size, MemoryBlock.Protection prot) + { + if (size == 0) + return 0; + int numPages = WaterboxUtils.PagesNeeded(size); + int startPage = FindConsecutiveFreePages(numPages); + if (startPage == -1) + return 0; + var ret = GetStartAddr(startPage); + ProtectInternal(startPage, numPages, prot, false); + return ret; + } + + public ulong Remap(ulong start, ulong oldSize, ulong newSize, bool canMove) + { + // TODO: what is the expected behavior when everything requested for remap is allocated, + // but with different protections? + if (start < Memory.Start || start + oldSize > Memory.End || oldSize == 0 || newSize == 0) + return 0; + + var oldStartPage = GetPage(start); + var oldNumPages = WaterboxUtils.PagesNeeded(oldSize); + if (!EnsureMapped(oldStartPage, oldNumPages)) + return 0; + var oldProt = _pages[oldStartPage]; + + int newNumPages = WaterboxUtils.PagesNeeded(newSize); + + if (!canMove) + { + if (newNumPages <= oldNumPages) + { + if (newNumPages < oldNumPages) + ProtectInternal(oldStartPage + newNumPages, oldNumPages - newNumPages, FREE, true); + return start; + } + else if (newNumPages > oldNumPages) + { + for (var i = oldStartPage + oldNumPages; i < oldStartPage + newNumPages; i++) + if (_pages[i] != FREE) + return 0; + ProtectInternal(oldStartPage + oldNumPages, newNumPages - oldNumPages, oldProt, false); + return start; + } + } + + // if moving is allowed, we always move to simplify and defragment when possible + int newStartPage = FindConsecutiveFreePagesAssumingFreed(newNumPages, oldStartPage, oldNumPages); + if (newStartPage == -1) + return 0; + + var copyDataLen = Math.Min(oldSize, newSize); + var copyPageLen = Math.Min(oldNumPages, newNumPages); + + var data = new byte[copyDataLen]; + Memory.Protect(start, copyDataLen, MemoryBlock.Protection.RW); + Marshal.Copy(Z.US(start), data, 0, (int)copyDataLen); + + var pages = new MemoryBlock.Protection[copyPageLen]; + Array.Copy(_pages, oldStartPage, pages, 0, copyPageLen); + + ProtectInternal(oldStartPage, oldNumPages, FREE, true); + ProtectInternal(newStartPage, newNumPages, MemoryBlock.Protection.RW, false); + + var ret = GetStartAddr(newStartPage); + Marshal.Copy(data, 0, Z.US(ret), (int)copyDataLen); + + Array.Copy(pages, 0, _pages, newStartPage, copyPageLen); + RefreshProtections(newStartPage, copyPageLen); + if (newNumPages > oldNumPages) + ProtectInternal(newStartPage + oldNumPages, newNumPages - oldNumPages, oldProt, true); + + return ret; + } + + public bool Unmap(ulong start, ulong size) + { + return Protect(start, size, FREE); + } + + public bool Protect(ulong start, ulong size, MemoryBlock.Protection prot) + { + if (start < Memory.Start || start + size > Memory.End || size == 0) + return false; + + var startPage = GetPage(start); + var numPages = WaterboxUtils.PagesNeeded(size); + if (!EnsureMapped(startPage, numPages)) + return false; + + ProtectInternal(startPage, numPages, prot, true); + return true; + } + + public void Dispose() + { + if (Memory != null) + { + Memory.Dispose(); + Memory = null; + } + } + + private const ulong MAGIC = 0x1590abbcdeef5910; + + public void SaveStateBinary(BinaryWriter bw) + { + bw.Write(Name); + bw.Write(Memory.Size); + bw.Write(Used); + bw.Write(Memory.XorHash); + bw.Write(_pagesAsBytes); + + Memory.Protect(Memory.Start, Memory.Size, MemoryBlock.Protection.R); + var srcs = Memory.GetXorStream(Memory.Start, Memory.Size, false); + for (int i = 0, addr = 0; i < _pages.Length; i++, addr += WaterboxUtils.PageSize) + { + if (_pages[i] != FREE) + { + srcs.Seek(addr, SeekOrigin.Begin); + WaterboxUtils.CopySome(srcs, bw.BaseStream, WaterboxUtils.PageSize); + } + } + bw.Write(MAGIC); + RefreshAllProtections(); + } + + public void LoadStateBinary(BinaryReader br) + { + var name = br.ReadString(); + if (name != Name) + throw new InvalidOperationException(string.Format("Name did not match for mapheap {0}", Name)); + var size = br.ReadUInt64(); + if (size != Memory.Size) + throw new InvalidOperationException(string.Format("Size did not match for mapheap {0}", Name)); + var used = br.ReadUInt64(); + var hash = br.ReadBytes(Memory.XorHash.Length); + if (!hash.SequenceEqual(Memory.XorHash)) + throw new InvalidOperationException(string.Format("Hash did not match for mapheap {0}. Is this the same rom?", Name)); + + if (br.BaseStream.Read(_pagesAsBytes, 0, _pagesAsBytes.Length) != _pagesAsBytes.Length) + throw new InvalidOperationException("Unexpected error reading!"); + + Used = 0; + Memory.Protect(Memory.Start, Memory.Size, MemoryBlock.Protection.RW); + var dsts = Memory.GetXorStream(Memory.Start, Memory.Size, true); + for (int i = 0, addr = 0; i < _pages.Length; i++, addr += WaterboxUtils.PageSize) + { + if (_pages[i] != FREE) + { + dsts.Seek(addr, SeekOrigin.Begin); + WaterboxUtils.CopySome(br.BaseStream, dsts, WaterboxUtils.PageSize); + Used += (uint)WaterboxUtils.PageSize; + } + } + if (Used != used) + throw new InvalidOperationException("Internal savestate error"); + if (br.ReadUInt64() != MAGIC) + throw new InvalidOperationException("Savestate internal error"); + RefreshAllProtections(); + } + + public static void StressTest() + { + var allocs = new Dictionary(); + var mmo = new MapHeap(0x36a00000000, 256 * 1024 * 1024, "ballsacks"); + var rnd = new Random(12512); + + for (int i = 0; i < 40; i++) + { + ulong siz = (ulong)(rnd.Next(256 * 1024) + 384 * 1024); + siz = siz / 4096 * 4096; + var ptr = mmo.Map(siz, MemoryBlock.Protection.RW); + allocs.Add(ptr, siz); + } + + for (int i = 0; i < 20; i++) + { + int idx = rnd.Next(allocs.Count); + var elt = allocs.ElementAt(idx); + mmo.Unmap(elt.Key, elt.Value); + allocs.Remove(elt.Key); + } + + for (int i = 0; i < 40; i++) + { + ulong siz = (ulong)(rnd.Next(256 * 1024) + 384 * 1024); + siz = siz / 4096 * 4096; + var ptr = mmo.Map(siz, MemoryBlock.Protection.RW); + allocs.Add(ptr, siz); + } + + for (int i = 0; i < 20; i++) + { + int idx = rnd.Next(allocs.Count); + var elt = allocs.ElementAt(idx); + mmo.Unmap(elt.Key, elt.Value); + } + } + } +} diff --git a/BizHawk.Emulation.Cores/Waterbox/PeRunner.cs b/BizHawk.Emulation.Cores/Waterbox/PeRunner.cs new file mode 100644 index 0000000000..913312ccd3 --- /dev/null +++ b/BizHawk.Emulation.Cores/Waterbox/PeRunner.cs @@ -0,0 +1,897 @@ +using BizHawk.Common; +using BizHawk.Common.BizInvoke; +using BizHawk.Emulation.Common; +using PeNet; +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; + +namespace BizHawk.Emulation.Cores.Waterbox +{ + public class PeRunnerOptions + { + // string directory, string filename, ulong heapsize, ulong sealedheapsize, ulong invisibleheapsize + /// + /// path which the main executable and all associated libraries should be found + /// + public string Path { get; set; } + + /// + /// filename of the main executable; expected to be in Path + /// + public string Filename { get; set; } + + /// + /// how large the normal heap should be. it services sbrk calls + /// can be 0, but sbrk calls will crash. + /// + public uint SbrkHeapSizeKB { get; set; } + + /// + /// how large the sealed heap should be. it services special allocations that become readonly after init + /// Must be > 0 and at least large enough to store argv and envp, and any alloc_sealed() calls + /// + public uint SealedHeapSizeKB { get; set; } + + /// + /// how large the invisible heap should be. it services special allocations which are not savestated + /// Must be > 0 and at least large enough for the internal vtables, and any alloc_invisible() calls + /// + public uint InvisibleHeapSizeKB { get; set; } + + /// + /// how large the "plain" heap should be. it is savestated, and contains + /// Must be > 0 and at least large enough for the internal pthread structure, and any alloc_plain() calls + /// + public uint PlainHeapSizeKB { get; set; } + + /// + /// how large the mmap heap should be. it is savestated. + /// can be 0, but mmap calls will crash. + /// + public uint MmapHeapSizeKB { get; set; } + + /// + /// start address in memory + /// + public ulong StartAddress { get; set; } = PeRunner.CanonicalStart; + } + + public class PeRunner : Swappable, IImportResolver, IBinaryStateable + { + /// + /// serves as a standin for libpsxscl.so + /// + private class Psx + { + private readonly PeRunner _parent; + private readonly List _traps = new List(); + + public Psx(PeRunner parent) + { + _parent = parent; + } + + [StructLayout(LayoutKind.Sequential)] + public struct PsxContext + { + public int Size; + public int Options; + public IntPtr SyscallVtable; + public IntPtr LdsoVtable; + public IntPtr PsxVtable; + public uint SysIdx; + public uint LibcIdx; + public IntPtr PthreadSurrogate; + public IntPtr PthreadCreate; + public IntPtr DoGlobalCtors; + public IntPtr DoGlobalDtors; + } + + private void PopulateVtable(string moduleName, ICollection entries, IntPtr table) + { + var imports = _parent._exports[moduleName]; + var pointers = entries.Select(e => + { + var ptr = imports.Resolve(e); + if (ptr == IntPtr.Zero) + { + var s = string.Format("Trapped on unimplemented function {0}:{1}", moduleName, e); + Action del = () => + { + Console.WriteLine(s); + throw new InvalidOperationException(s); + }; + _traps.Add(del); + ptr = CallingConventionAdapters.Waterbox.GetFunctionPointerForDelegate(del); + } + return ptr; + }).ToArray(); + Marshal.Copy(pointers, 0, table, pointers.Length); + } + + /// + /// called by the PeRunner to reset pointers after a loadsave + /// + public void ReloadVtables() + { + _traps.Clear(); + + PopulateVtable("__syscalls", Enumerable.Range(0, 340).Select(i => "n" + i).ToList(), _syscallVtable); + PopulateVtable("__syscalls", new[] // ldso + { + "dladdr", "dlinfo", "dlsym", "dlopen", "dlclose", "dlerror", "reset_tls" + }, _ldsoVtable); + PopulateVtable("__syscalls", new[] // psx + { + "start_main", "convert_thread", "unmapself", "log_output", "pthread_self" + }, _psxVtable); + /*unsafe + { + var ptr = (IntPtr*)_psxVtable; + Console.WriteLine("AWESOMES: " + ptr[0]); + }*/ + } + + private IntPtr _syscallVtable; + private IntPtr _ldsoVtable; + private IntPtr _psxVtable; + + private IntPtr AllocVtable(int count) + { + return Z.US(_parent._invisibleheap.Allocate((ulong)(count * IntPtr.Size), 16)); + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "__psx_init")] + public int PsxInit(ref int argc, ref IntPtr argv, ref IntPtr envp, [In, Out]ref PsxContext context) + { + { + // argc = 1, argv = ["foobar, NULL], envp = [NULL] + argc = 1; + var argArea = _parent._sealedheap.Allocate(32, 16); + argv = Z.US(argArea); + envp = Z.US(argArea + (uint)IntPtr.Size * 2); + Marshal.WriteIntPtr(Z.US(argArea), Z.US(argArea + 24)); + Marshal.WriteInt64(Z.US(argArea + 24), 0x7261626f6f66); + } + + context.SyscallVtable = _syscallVtable = AllocVtable(340); + context.LdsoVtable = _ldsoVtable = AllocVtable(7); + context.PsxVtable = _psxVtable = AllocVtable(5); + // ctx comes from the native stack, where it could have any garbage in uninited fields + context.SysIdx = 0; + context.LibcIdx = 0; + context.DoGlobalCtors = IntPtr.Zero; + context.DoGlobalDtors = IntPtr.Zero; + + ReloadVtables(); + + // TODO: we can't set these pointers 4 and preserve across session + // until we find out where they get saved to and add a way to reset them + /*var extraTable = CreateVtable("__syscalls", new[] + { + "pthread_surrogate", "pthread_create", "do_global_ctors", "do_global_dtors" + }); + var tmp = new IntPtr[4]; + Marshal.Copy(extraTable, tmp, 0, 4); + context.PthreadSurrogate = tmp[0]; + context.PthreadCreate = tmp[1]; + context.DoGlobalCtors = tmp[2]; + context.DoGlobalDtors = tmp[3];*/ + + return 0; // success + } + } + + /// + /// special emulator-functions + /// + private class Emu + { + private readonly PeRunner _parent; + public Emu(PeRunner parent) + { + _parent = parent; + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "alloc_sealed")] + public IntPtr AllocSealed(UIntPtr size) + { + return Z.US(_parent._sealedheap.Allocate((ulong)size, 16)); + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "alloc_invisible")] + public IntPtr AllocInvisible(UIntPtr size) + { + return Z.US(_parent._invisibleheap.Allocate((ulong)size, 16)); + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "alloc_plain")] + public IntPtr AllocPlain(UIntPtr size) + { + return Z.US(_parent._plainheap.Allocate((ulong)size, 16)); + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "_debug_puts")] + public void DebugPuts(IntPtr s) + { + Console.WriteLine("_debug_puts:" + Marshal.PtrToStringAnsi(s)); + } + } + + /// + /// syscall emulation layer, as well as a bit of other stuff + /// + private class Syscalls + { + private readonly PeRunner _parent; + public Syscalls(PeRunner parent) + { + _parent = parent; + } + + private IntPtr _pthreadSelf; + + public void Init() + { + // as the inits are done in a defined order with a defined memory map, + // we don't need to savestate _pthreadSelf, only its contents + _pthreadSelf = Z.US(_parent._plainheap.Allocate(512, 1)); + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "log_output")] + public void DebugPuts(IntPtr s) + { + Console.WriteLine("_psx_log_output:" + Marshal.PtrToStringAnsi(s)); + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "n12")] + public UIntPtr Brk(UIntPtr _p) + { + var heap = _parent._heap; + + var start = heap.Memory.Start; + var end = start + heap.Used; + var max = heap.Memory.End; + + var p = (ulong)_p; + + if (p < start || p > max) + { + // failure: return current break + return Z.UU(end); + } + else if (p > end) + { + // increase size of heap + heap.Allocate(p - end, 1); + return Z.UU(p); + } + else if (p < end) + { + throw new InvalidOperationException("We don't support shrinking heaps"); + } + else + { + // no change + return Z.UU(end); + } + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "n16")] + public int IoCtl(int fd, ulong req) + { + return 0; // sure it worked, honest + } + + public struct Iovec + { + public IntPtr Base; + public ulong Length; + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "n0")] + public long Read(int fd, IntPtr buff, ulong count) + { + return 0; + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "n1")] + public long Write(int fd, IntPtr buff, ulong count) + { + return (long)count; + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "n19")] + public unsafe long Readv(int fd, Iovec* iov, int iovcnt) + { + return 0; + } + [BizExport(CallingConvention.Cdecl, EntryPoint = "n20")] + public unsafe long Writev(int fd, Iovec* iov, int iovcnt) + { + long ret = 0; + for (int i = 0; i < iovcnt; i++) + { + ret += (long)iov[i].Length; + } + return ret; + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "n2")] + public int Open(string path, int flags, int mode) + { + return -1; + } + [BizExport(CallingConvention.Cdecl, EntryPoint = "n3")] + public int Close(int fd) + { + return 0; + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "n4")] + public int Stat(string path, IntPtr statbuf) + { + return -1; + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "n5")] + public int Fstat(int fd, IntPtr statbuf) + { + return -1; + } + + //[UnmanagedFunctionPointer(CallingConvention.Cdecl)] + //private delegate int LibcStartMain(IntPtr main, int argc, IntPtr argv); + + //bool _firstTime = true; + + // aka __psx_init_frame (it's used elsewhere for thread setup) + // in midipix, this just sets up a SEH frame and then calls musl's start_main + [BizExport(CallingConvention.Cdecl, EntryPoint = "start_main")] + public unsafe int StartMain(IntPtr main, int argc, IntPtr argv, IntPtr libc_start_main) + { + //var del = (LibcStartMain)CallingConventionAdapters.Waterbox.GetDelegateForFunctionPointer(libc_start_main, typeof(LibcStartMain)); + // this will init, and then call user main, and then call exit() + //del(main, argc, argv); + //int* foobar = stackalloc int[128]; + + + // if we return from this, psx will then halt, so break out + //if (_firstTime) + //{ + //_firstTime = false; + throw new InvalidOperationException("This shouldn't be called"); + //} + //else + //{ + // return 0; + //} + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "pthread_self")] + public IntPtr PthreadSelf() + { + return _pthreadSelf; + } + + /*[BizExport(CallingConvention.Cdecl, EntryPoint = "convert_thread")] + public void ConvertThread() + { + + }*/ + + [BizExport(CallingConvention.Cdecl, EntryPoint = "n218")] + public long SetTidAddress(IntPtr address) + { + return 8675309; + } + + [StructLayout(LayoutKind.Sequential)] + public class TimeSpec + { + public long Seconds; + public long NanoSeconds; + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "n228")] + public int SysClockGetTime(int which, [In, Out] TimeSpec time) + { + time.Seconds = 1495889068; + time.NanoSeconds = 0; + return 0; + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "n9")] + public IntPtr MMap(IntPtr address, UIntPtr size, int prot, int flags, int fd, IntPtr offs) + { + if (address != IntPtr.Zero) + return Z.SS(-1); + MemoryBlock.Protection mprot; + switch (prot) + { + case 0: mprot = MemoryBlock.Protection.None; break; + default: + case 6: // W^X + case 7: // W^X + case 4: // exec only???? + case 2: return Z.SS(-1); // write only???? + case 3: mprot = MemoryBlock.Protection.RW; break; + case 1: mprot = MemoryBlock.Protection.R; break; + case 5: mprot = MemoryBlock.Protection.RX; break; + } + if ((flags & 0x20) == 0) + { + // MAP_ANONYMOUS is required + return Z.SS(-1); + } + if ((flags & 0xf00) != 0) + { + // various unsupported flags + return Z.SS(-1); + } + + var ret = _parent._mmapheap.Map((ulong)size, mprot); + return ret == 0 ? Z.SS(-1) : Z.US(ret); + } + [BizExport(CallingConvention.Cdecl, EntryPoint = "n25")] + public IntPtr MRemap(UIntPtr oldAddress, UIntPtr oldSize, + UIntPtr newSize, int flags) + { + if ((flags & 2) != 0) + { + // don't support MREMAP_FIXED + return Z.SS(-1); + } + var ret = _parent._mmapheap.Remap((ulong)oldAddress, (ulong)oldSize, (ulong)newSize, + (flags & 1) != 0); + return ret == 0 ? Z.SS(-1) : Z.US(ret); + } + [BizExport(CallingConvention.Cdecl, EntryPoint = "n11")] + public int MUnmap(UIntPtr address, UIntPtr size) + { + return _parent._mmapheap.Unmap((ulong)address, (ulong)size) ? 0 : -1; + } + + [BizExport(CallingConvention.Cdecl, EntryPoint = "n10")] + public int MProtect(UIntPtr address, UIntPtr size, int prot) + { + MemoryBlock.Protection mprot; + switch (prot) + { + case 0: mprot = MemoryBlock.Protection.None; break; + default: + case 6: // W^X + case 7: // W^X + case 4: // exec only???? + case 2: return -1; // write only???? + case 3: mprot = MemoryBlock.Protection.RW; break; + case 1: mprot = MemoryBlock.Protection.R; break; + case 5: mprot = MemoryBlock.Protection.RX; break; + } + return _parent._mmapheap.Protect((ulong)address, (ulong)size, mprot) ? 0 : -1; + } + } + + /// + /// libc.so functions that we want to redirect + /// + private class LibcPatch + { + private readonly PeRunner _parent; + public LibcPatch(PeRunner parent) + { + _parent = parent; + } + + + private bool _didOnce = false; + private readonly Dictionary _specificKeys = new Dictionary(); + private uint _nextSpecificKey = 401; + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void PthreadCallback(); + + // pthread stuff: + // since we don't allow multiple threads (for now), this is all pretty simple + /* + // int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); + [BizExport(CallingConvention.Cdecl, EntryPoint = "pthread_key_create")] + public int PthreadKeyCreate(ref uint key, PthreadCallback destructor) + { + key = _nextSpecificKey++; + _specificKeys.Add(key, IntPtr.Zero); + return 0; + } + // int pthread_key_delete(pthread_key_t key); + [BizExport(CallingConvention.Cdecl, EntryPoint = "pthread_key_delete")] + public int PthreadKeyDelete(uint key) + { + _specificKeys.Remove(key); + return 0; + } + // int pthread_setspecific(pthread_key_t key, const void *value); + [BizExport(CallingConvention.Cdecl, EntryPoint = "pthread_setspecific")] + public int PthreadSetSpecific(uint key, IntPtr value) + { + _specificKeys[key] = value; + return 0; + } + // void *pthread_getspecific(pthread_key_t key); + [BizExport(CallingConvention.Cdecl, EntryPoint = "pthread_getspecific")] + public IntPtr PthreadGetSpecific(uint key) + { + IntPtr ret; + _specificKeys.TryGetValue(key, out ret); + return ret; + } + + // int pthread_once(pthread_once_t* once_control, void (*init_routine)(void)); + [BizExport(CallingConvention.Cdecl, EntryPoint = "pthread_once")] + public int PthreadOnce(IntPtr control, PthreadCallback init) + { + if (!_didOnce) + { + System.Diagnostics.Debugger.Break(); + _didOnce = true; + init(); + } + return 0; + } + + // int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t* attr); + [BizExport(CallingConvention.Cdecl, EntryPoint = "pthread_mutex_init")] + public int PthreadMutexInit(IntPtr mutex, IntPtr attr) { return 0; } + // int pthread_mutex_destroy(pthread_mutex_t* mutex); + [BizExport(CallingConvention.Cdecl, EntryPoint = "pthread_mutex_destroy")] + public int PthreadMutexDestroy(IntPtr mutex) { return 0; } + + // int pthread_mutex_lock(pthread_mutex_t* mutex); + [BizExport(CallingConvention.Cdecl, EntryPoint = "pthread_mutex_lock")] + public int PthreadMutexLock(IntPtr mutex) { return 0; } + // int pthread_mutex_trylock(pthread_mutex_t* mutex); + [BizExport(CallingConvention.Cdecl, EntryPoint = "pthread_mutex_trylock")] + public int PthreadMutexTryLock(IntPtr mutex) { return 0; } + // int pthread_mutex_unlock(pthread_mutex_t* mutex); + [BizExport(CallingConvention.Cdecl, EntryPoint = "pthread_mutex_unlock")] + public int PthreadMutexUnlock(IntPtr mutex) { return 0; }*/ + + + } + + /// + /// usual starting point for the executable + /// + public const ulong CanonicalStart = 0x0000036f00000000; + + public const ulong AlternateStart = 0x0000036e00000000; + + /// + /// the next place where we can put a module or heap + /// + private ulong _nextStart = CanonicalStart; + + /// + /// increment _nextStart after adding a module + /// + private void ComputeNextStart(ulong size) + { + _nextStart += size; + // align to 1MB, then increment 16MB + _nextStart = ((_nextStart - 1) | 0xfffff) + 0x1000001; + } + + /// + /// standard malloc() heap + /// + private Heap _heap; + + /// + /// sealed heap (writable only during init) + /// + private Heap _sealedheap; + + /// + /// invisible heap (not savestated, use with care) + /// + private Heap _invisibleheap; + + /// + /// extra savestated heap + /// + private Heap _plainheap; + + /// + /// memory map emulation + /// + private MapHeap _mmapheap; + + /// + /// all loaded PE files + /// + private readonly List _modules = new List(); + + /// + /// all loaded heaps + /// + private readonly List _heaps = new List(); + + /// + /// anything at all that needs to be disposed on finish + /// + private readonly List _disposeList = new List(); + + /// + /// anything at all that needs its state saved and loaded + /// + private readonly List _savestateComponents = new List(); + + /// + /// all of the exports, including real PeWrapper ones and fake ones + /// + private readonly Dictionary _exports = new Dictionary(); + + private Psx _psx; + private Emu _emu; + private Syscalls _syscalls; + private LibcPatch _libcpatch; + + /// + /// timestamp of creation acts as a sort of "object id" in the savestate + /// + private readonly long _createstamp = WaterboxUtils.Timestamp(); + + private Heap CreateHeapHelper(uint sizeKB, string name, bool saveStated) + { + if (sizeKB != 0) + { + var heap = new Heap(_nextStart, sizeKB * 1024, name); + heap.Memory.Activate(); + ComputeNextStart(sizeKB * 1024); + AddMemoryBlock(heap.Memory, name); + if (saveStated) + _savestateComponents.Add(heap); + _disposeList.Add(heap); + _heaps.Add(heap); + return heap; + } + else + { + return null; + } + } + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate void LibcEntryRoutineD(IntPtr appMain, IntPtr psxInit, int options); + + public PeRunner(PeRunnerOptions opt) + { + _nextStart = opt.StartAddress; + Initialize(_nextStart); + using (this.EnterExit()) + { + // load any predefined exports + _psx = new Psx(this); + _exports.Add("libpsxscl.so", BizExvoker.GetExvoker(_psx, CallingConventionAdapters.Waterbox)); + _emu = new Emu(this); + _exports.Add("libemuhost.so", BizExvoker.GetExvoker(_emu, CallingConventionAdapters.Waterbox)); + _syscalls = new Syscalls(this); + _exports.Add("__syscalls", BizExvoker.GetExvoker(_syscalls, CallingConventionAdapters.Waterbox)); + + // load and connect all modules, starting with the executable + var todoModules = new Queue(); + todoModules.Enqueue(opt.Filename); + + while (todoModules.Count > 0) + { + var moduleName = todoModules.Dequeue(); + if (!_exports.ContainsKey(moduleName)) + { + var path = Path.Combine(opt.Path, moduleName); + var gzpath = path + ".gz"; + byte[] data; + if (File.Exists(gzpath)) + { + using (var fs = new FileStream(gzpath, FileMode.Open, FileAccess.Read)) + { + var tmp = new byte[4]; + fs.Seek(-4, SeekOrigin.End); + fs.Read(tmp, 0, 4); + int size = BitConverter.ToInt32(tmp, 0); + data = new byte[size]; + var ms = new MemoryStream(data); + fs.Seek(0, SeekOrigin.Begin); + using (var gs = new GZipStream(fs, CompressionMode.Decompress)) + gs.CopyTo(ms); + } + } + else + { + data = File.ReadAllBytes(path); + } + + var module = new PeWrapper(moduleName, data, _nextStart); + ComputeNextStart(module.Size); + AddMemoryBlock(module.Memory, moduleName); + _savestateComponents.Add(module); + _disposeList.Add(module); + + _exports.Add(moduleName, module); + _modules.Add(module); + foreach (var name in module.ImportsByModule.Keys) + { + todoModules.Enqueue(name); + } + } + } + + _libcpatch = new LibcPatch(this); + _exports["libc.so"] = new PatchImportResolver(_exports["libc.so"], BizExvoker.GetExvoker(_libcpatch, CallingConventionAdapters.Waterbox)); + + ConnectAllImports(); + + // load all heaps + _heap = CreateHeapHelper(opt.SbrkHeapSizeKB, "brk-heap", true); + _sealedheap = CreateHeapHelper(opt.SealedHeapSizeKB, "sealed-heap", true); + _invisibleheap = CreateHeapHelper(opt.InvisibleHeapSizeKB, "invisible-heap", false); + _plainheap = CreateHeapHelper(opt.PlainHeapSizeKB, "plain-heap", true); + + if (opt.MmapHeapSizeKB != 0) + { + _mmapheap = new MapHeap(_nextStart, opt.MmapHeapSizeKB * 1024, "mmap-heap"); + _mmapheap.Memory.Activate(); + ComputeNextStart(opt.MmapHeapSizeKB * 1024); + AddMemoryBlock(_mmapheap.Memory, "mmap-heap"); + _savestateComponents.Add(_mmapheap); + _disposeList.Add(_mmapheap); + } + + _syscalls.Init(); + + Console.WriteLine("About to enter unmanaged code"); + if (Win32Hacks.IsDebuggerReallyPresent() && !System.Diagnostics.Debugger.IsAttached) + { + // this means that GDB or another unconventional debugger is attached. + // if that's the case, and it's observing this core, it probably wants a break + System.Diagnostics.Debugger.Break(); + } + + // run unmanaged init code + var libcEnter = _exports["libc.so"].SafeResolve("__libc_entry_routine"); + var psxInit = _exports["libpsxscl.so"].SafeResolve("__psx_init"); + + var del = (LibcEntryRoutineD)CallingConventionAdapters.Waterbox.GetDelegateForFunctionPointer(libcEnter, typeof(LibcEntryRoutineD)); + // the current mmglue code doesn't use the main pointer at all, and this just returns + del(IntPtr.Zero, psxInit, 0); + + foreach (var m in _modules) + { + m.RunGlobalCtors(); + } + + /*try + { + _modules[0].RunExeEntry(); + //throw new InvalidOperationException("main() returned!"); + } + catch //(EndOfMainException) + { + } + _modules[0].RunGlobalCtors(); + foreach (var m in _modules.Skip(1)) + { + if (!m.RunDllEntry()) + throw new InvalidOperationException("DllMain() returned false"); + m.RunGlobalCtors(); + }*/ + } + } + + public IntPtr Resolve(string entryPoint) + { + // modules[0] is always the main module + return _modules[0].Resolve(entryPoint); + } + + public void Seal() + { + using (this.EnterExit()) + { + // if libco is used, the jmp_buf for the main cothread can have stack stuff in it. + // this isn't a problem, since we only savestate when the core is not running, and + // the next time it's run, that buf will be overridden again. + // but it breaks xor state verification, so when we seal, nuke it. + + // this could be the responsibility of something else other than the PeRunner; I am not sure yet... + IImportResolver libco; + if (_exports.TryGetValue("libco.so", out libco)) + { + Console.WriteLine("Calling co_clean()..."); + CallingConventionAdapters.Waterbox.GetDelegateForFunctionPointer(libco.SafeResolve("co_clean"))(); + } + + _sealedheap.Seal(); + foreach (var h in _heaps) + { + if (h != _invisibleheap) // TODO: if we have more non-savestated heaps, refine this hack + h.Memory.SaveXorSnapshot(); + } + foreach (var pe in _modules) + { + pe.SealImportsAndTakeXorSnapshot(); + } + if (_mmapheap != null) + _mmapheap.Memory.SaveXorSnapshot(); + } + } + + private void ConnectAllImports() + { + foreach (var module in _modules) + { + foreach (var name in module.ImportsByModule.Keys) + { + module.ConnectImports(name, _exports[name]); + } + } + } + + public void SaveStateBinary(BinaryWriter bw) + { + bw.Write(_createstamp); + bw.Write(_savestateComponents.Count); + using (this.EnterExit()) + { + foreach (var c in _savestateComponents) + { + c.SaveStateBinary(bw); + } + } + } + + public void LoadStateBinary(BinaryReader br) + { + var differentCore = br.ReadInt64() != _createstamp; // true if a different core instance created the state + if (br.ReadInt32() != _savestateComponents.Count) + throw new InvalidOperationException("Internal savestate error"); + using (this.EnterExit()) + { + foreach (var c in _savestateComponents) + { + c.LoadStateBinary(br); + } + if (differentCore) + { + // if a different runtime instance than this one saved the state, + // Exvoker imports need to be reconnected + Console.WriteLine("Restoring PeRunner state from a different core..."); + ConnectAllImports(); + _psx.ReloadVtables(); + } + } + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (disposing) + { + foreach (var d in _disposeList) + d.Dispose(); + _disposeList.Clear(); + PurgeMemoryBlocks(); + _modules.Clear(); + _exports.Clear(); + _heap = null; + _sealedheap = null; + _invisibleheap = null; + _plainheap = null; + _mmapheap = null; + } + } + } +} diff --git a/BizHawk.Emulation.Cores/Waterbox/PeWrapper.cs b/BizHawk.Emulation.Cores/Waterbox/PeWrapper.cs new file mode 100644 index 0000000000..bb7cb2e9fb --- /dev/null +++ b/BizHawk.Emulation.Cores/Waterbox/PeWrapper.cs @@ -0,0 +1,435 @@ +using BizHawk.Common; +using BizHawk.Common.BizInvoke; +using BizHawk.Emulation.Common; +using PeNet; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; + +namespace BizHawk.Emulation.Cores.Waterbox +{ + /// + /// represents one PE file. used in PeRunner + /// + internal class PeWrapper : IImportResolver, IBinaryStateable, IDisposable + { + public Dictionary ExportsByOrdinal { get; } = new Dictionary(); + /// + /// ordinal only exports will not show up in this list! + /// + public Dictionary ExportsByName { get; } = new Dictionary(); + + public Dictionary> ImportsByModule { get; } = + new Dictionary>(); + + private class Section + { + public string Name { get; set; } + public ulong Start { get; set; } + public ulong Size { get; set; } + public ulong SavedSize { get; set; } + public bool W { get; set; } + public bool R { get; set; } + public bool X { get; set; } + public MemoryBlock.Protection Prot { get; set; } + public ulong DiskStart { get; set; } + public ulong DiskSize { get; set; } + } + + private readonly Dictionary _sectionsByName = new Dictionary(); + private readonly List
_sections = new List
(); + private Section _imports; + + public string ModuleName { get; } + + private readonly byte[] _fileData; + private readonly PeFile _pe; + private readonly byte[] _fileHash; + + public ulong Size { get; } + public ulong Start { get; private set; } + + public long LoadOffset { get; private set; } + + public MemoryBlock Memory { get; private set; } + + public IntPtr EntryPoint { get; private set; } + + /// + /// for midipix-built PEs, pointer to the construtors to run during init + /// + public IntPtr CtorList { get; private set; } + /// + /// for midipix-build PEs, pointer to the destructors to run during fini + /// + public IntPtr DtorList { get; private set; } + + // true if the imports have been set to readonly + private bool _importsSealed = false; + + /*[UnmanagedFunctionPointer(CallingConvention.Winapi)] + private delegate bool DllEntry(IntPtr instance, int reason, IntPtr reserved); + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + private delegate void ExeEntry();*/ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate void GlobalCtor(); + + /*public bool RunDllEntry() + { + var entryThunk = (DllEntry)CallingConventionAdapters.Waterbox.GetDelegateForFunctionPointer(EntryPoint, typeof(DllEntry)); + return entryThunk(Z.US(Start), 1, IntPtr.Zero); // DLL_PROCESS_ATTACH + } + public void RunExeEntry() + { + var entryThunk = (ExeEntry)CallingConventionAdapters.Waterbox.GetDelegateForFunctionPointer(EntryPoint, typeof(ExeEntry)); + entryThunk(); + }*/ + public unsafe void RunGlobalCtors() + { + int did = 0; + if (CtorList != IntPtr.Zero) + { + IntPtr* p = (IntPtr*)CtorList; + IntPtr f; + while ((f = *++p) != IntPtr.Zero) // skip 0th dummy pointer + { + var ctorThunk = (GlobalCtor)CallingConventionAdapters.Waterbox.GetDelegateForFunctionPointer(f, typeof(GlobalCtor)); + //Console.WriteLine(f); + //System.Diagnostics.Debugger.Break(); + ctorThunk(); + did++; + } + } + + if (did > 0) + { + Console.WriteLine($"Did {did} global ctors for {ModuleName}"); + } + else + { + Console.WriteLine($"Warn: no global ctors for {ModuleName}; possibly no C++?"); + } + } + + public PeWrapper(string moduleName, byte[] fileData, ulong destAddress) + { + ModuleName = moduleName; + _fileData = fileData; + _pe = new PeFile(fileData); + Size = _pe.ImageNtHeaders.OptionalHeader.SizeOfImage; + Start = destAddress; + + if (Size < _pe.ImageSectionHeaders.Max(s => (ulong)s.VirtualSize + s.VirtualAddress)) + { + throw new InvalidOperationException("Image not Big Enough"); + } + + _fileHash = WaterboxUtils.Hash(fileData); + + foreach (var s in _pe.ImageSectionHeaders) + { + ulong start = Start + s.VirtualAddress; + ulong length = s.VirtualSize; + + MemoryBlock.Protection prot; + var r = (s.Characteristics & (uint)Constants.SectionFlags.IMAGE_SCN_MEM_READ) != 0; + var w = (s.Characteristics & (uint)Constants.SectionFlags.IMAGE_SCN_MEM_WRITE) != 0; + var x = (s.Characteristics & (uint)Constants.SectionFlags.IMAGE_SCN_MEM_EXECUTE) != 0; + if (w && x) + { + throw new InvalidOperationException("Write and Execute not allowed"); + } + + prot = x ? MemoryBlock.Protection.RX : w ? MemoryBlock.Protection.RW : MemoryBlock.Protection.R; + + var section = new Section + { + // chop off possible null padding from name + Name = Encoding.ASCII.GetString(s.Name, 0, + (s.Name.Select((v, i) => new { v, i }).FirstOrDefault(a => a.v == 0) ?? new { v = (byte)0, i = s.Name.Length }).i), + Start = start, + Size = length, + SavedSize = WaterboxUtils.AlignUp(length), + R = r, + W = w, + X = x, + Prot = prot, + DiskStart = s.PointerToRawData, + DiskSize = s.SizeOfRawData + }; + + _sections.Add(section); + _sectionsByName.Add(section.Name, section); + } + _sectionsByName.TryGetValue(".idata", out _imports); + + Mount(); + } + + /// + /// set memory protections. + /// + private void ProtectMemory() + { + Memory.Protect(Memory.Start, Memory.Size, MemoryBlock.Protection.R); + + foreach (var s in _sections) + { + Memory.Protect(s.Start, s.Size, s.Prot); + } + } + + /// + /// load the PE into memory + /// + /// start address + private void Mount() + { + LoadOffset = (long)Start - (long)_pe.ImageNtHeaders.OptionalHeader.ImageBase; + Memory = new MemoryBlock(Start, Size); + Memory.Activate(); + Memory.Protect(Start, Size, MemoryBlock.Protection.RW); + + // copy headers + Marshal.Copy(_fileData, 0, Z.US(Start), (int)_pe.ImageNtHeaders.OptionalHeader.SizeOfHeaders); + + // copy sections + foreach (var s in _sections) + { + ulong datalength = Math.Min(s.Size, s.DiskSize); + Marshal.Copy(_fileData, (int)s.DiskStart, Z.US(s.Start), (int)datalength); + WaterboxUtils.ZeroMemory(Z.US(s.Start + datalength), (long)(s.SavedSize - datalength)); + } + + // apply relocations + var n32 = 0; + var n64 = 0; + foreach (var rel in _pe.ImageRelocationDirectory) + { + foreach (var to in rel.TypeOffsets) + { + ulong address = Start + rel.VirtualAddress + to.Offset; + + switch (to.Type) + { + // there are many other types of relocation specified, + // but the only that are used is 0 (does nothing), 3 (32 bit standard), 10 (64 bit standard) + + case 3: // IMAGE_REL_BASED_HIGHLOW + { + byte[] tmp = new byte[4]; + Marshal.Copy(Z.US(address), tmp, 0, 4); + uint val = BitConverter.ToUInt32(tmp, 0); + tmp = BitConverter.GetBytes((uint)(val + LoadOffset)); + Marshal.Copy(tmp, 0, Z.US(address), 4); + n32++; + break; + } + + case 10: // IMAGE_REL_BASED_DIR64 + { + byte[] tmp = new byte[8]; + Marshal.Copy(Z.US(address), tmp, 0, 8); + long val = BitConverter.ToInt64(tmp, 0); + tmp = BitConverter.GetBytes(val + LoadOffset); + Marshal.Copy(tmp, 0, Z.US(address), 8); + n64++; + break; + } + } + } + } + if (IntPtr.Size == 8 && n32 > 0) + { + // check mcmodel, etc + throw new InvalidOperationException("32 bit relocations found in 64 bit dll! This will fail."); + } + Console.WriteLine($"Processed {n32} 32 bit and {n64} 64 bit relocations"); + + ProtectMemory(); + + // publish exports + EntryPoint = Z.US(Start + _pe.ImageNtHeaders.OptionalHeader.AddressOfEntryPoint); + foreach (var export in _pe.ExportedFunctions) + { + if (export.Name != null) + ExportsByName.Add(export.Name, Z.US(Start + export.Address)); + ExportsByOrdinal.Add(export.Ordinal, Z.US(Start + export.Address)); + } + + // collect information about imports + // NB: Hints are not the same as Ordinals + foreach (var import in _pe.ImportedFunctions) + { + Dictionary module; + if (!ImportsByModule.TryGetValue(import.DLL, out module)) + { + module = new Dictionary(); + ImportsByModule.Add(import.DLL, module); + } + var dest = Start + import.Thunk; + if (_imports == null || dest >= _imports.Start + _imports.Size || dest < _imports.Start) + throw new InvalidOperationException("Import record outside of .idata!"); + + module.Add(import.Name, Z.US(dest)); + } + + Section midipix; + if (_sectionsByName.TryGetValue(".midipix", out midipix)) + { + var dataOffset = midipix.DiskStart; + CtorList = Z.SS(BitConverter.ToInt64(_fileData, (int)(dataOffset + 0x30)) + LoadOffset); + DtorList = Z.SS(BitConverter.ToInt64(_fileData, (int)(dataOffset + 0x38)) + LoadOffset); + } + + Console.WriteLine($"Mounted `{ModuleName}` @{Start:x16}"); + foreach (var s in _sections.OrderBy(s => s.Start)) + { + Console.WriteLine(" @{0:x16} {1}{2}{3} `{4}` {5} bytes", + s.Start, + s.R ? "R" : " ", + s.W ? "W" : " ", + s.X ? "X" : " ", + s.Name, + s.Size); + } + Console.WriteLine("GDB Symbol Load:"); + var symload = $"add-sym {ModuleName} {_sectionsByName[".text"].Start}"; + if (_sectionsByName.ContainsKey(".data")) + symload += $" -s .data {_sectionsByName[".data"].Start}"; + if (_sectionsByName.ContainsKey(".bss")) + symload += $" -s .bss {_sectionsByName[".bss"].Start}"; + Console.WriteLine(symload); + } + + public IntPtr Resolve(string entryPoint) + { + IntPtr ret; + ExportsByName.TryGetValue(entryPoint, out ret); + return ret; + } + + public void ConnectImports(string moduleName, IImportResolver module) + { + // this is called once internally when bootstrapping, and externally + // when we need to restore a savestate from another run. so imports might or might not be sealed + + if (_importsSealed && _imports != null) + Memory.Protect(_imports.Start, _imports.Size, MemoryBlock.Protection.RW); + + Dictionary imports; + if (ImportsByModule.TryGetValue(moduleName, out imports)) + { + foreach (var kvp in imports) + { + var valueArray = new IntPtr[] { module.SafeResolve(kvp.Key) }; + Marshal.Copy(valueArray, 0, kvp.Value, 1); + } + } + + if (_importsSealed && _imports != null) + Memory.Protect(_imports.Start, _imports.Size, _imports.Prot); + } + + public void SealImportsAndTakeXorSnapshot() + { + if (_importsSealed) + throw new InvalidOperationException("Imports already sealed!"); + + // save import values, then zero them all (for hash purposes), then take our snapshot, then load them again, + // then set the .idata area to read only + if (_imports != null) + { + var data = new byte[_imports.Size]; + Marshal.Copy(Z.US(_imports.Start), data, 0, (int)_imports.Size); + WaterboxUtils.ZeroMemory(Z.US(_imports.Start), (long)_imports.Size); + Memory.SaveXorSnapshot(); + Marshal.Copy(data, 0, Z.US(_imports.Start), (int)_imports.Size); + _imports.W = false; + Memory.Protect(_imports.Start, _imports.Size, _imports.Prot); + } + else + { + Memory.SaveXorSnapshot(); + } + + _importsSealed = true; + } + + private bool _disposed = false; + + public void Dispose() + { + if (!_disposed) + { + Memory.Dispose(); + Memory = null; + _disposed = true; + } + } + + const ulong MAGIC = 0x420cccb1a2e17420; + + public void SaveStateBinary(BinaryWriter bw) + { + if (!_importsSealed) + throw new InvalidOperationException(".idata sections must be closed before saving state"); + + bw.Write(MAGIC); + bw.Write(_fileHash); + bw.Write(Memory.XorHash); + bw.Write(Start); + + foreach (var s in _sections) + { + if (!s.W) + continue; + + var ms = Memory.GetXorStream(s.Start, s.SavedSize, false); + bw.Write(s.SavedSize); + ms.CopyTo(bw.BaseStream); + } + } + + public void LoadStateBinary(BinaryReader br) + { + if (!_importsSealed) + // operations happening in the wrong order. probable cause: internal logic error. make sure frontend calls Seal + throw new InvalidOperationException(".idata sections must be closed before loading state"); + + if (br.ReadUInt64() != MAGIC) + // file id is missing. probable cause: garbage savestate + throw new InvalidOperationException("Savestate corrupted!"); + if (!br.ReadBytes(_fileHash.Length).SequenceEqual(_fileHash)) + // the .dll file that is loaded now has a different hash than the .dll that created the savestate + throw new InvalidOperationException("Core consistency check failed. Is this a savestate from a different version?"); + if (!br.ReadBytes(Memory.XorHash.Length).SequenceEqual(Memory.XorHash)) + // the post-Seal memory state is different. probable cause: different rom or different version of rom, + // different syncsettings + throw new InvalidOperationException("Memory consistency check failed. Is this savestate from different SyncSettings?"); + if (br.ReadUInt64() != Start) + // dll loaded somewhere else. probable cause: internal logic error. + // unlikely to get this far if the previous checks pssed + throw new InvalidOperationException("Trickys elves moved on you!"); + + Memory.Protect(Memory.Start, Memory.Size, MemoryBlock.Protection.RW); + + foreach (var s in _sections) + { + if (!s.W) + continue; + + if (br.ReadUInt64() != s.SavedSize) + throw new InvalidOperationException("Unexpected section size for " + s.Name); + + var ms = Memory.GetXorStream(s.Start, s.SavedSize, true); + WaterboxUtils.CopySome(br.BaseStream, ms, (long)s.SavedSize); + } + + ProtectMemory(); + } + } +} diff --git a/BizHawk.Emulation.Cores/Waterbox/Swappable.cs b/BizHawk.Emulation.Cores/Waterbox/Swappable.cs new file mode 100644 index 0000000000..32bc1bf0f5 --- /dev/null +++ b/BizHawk.Emulation.Cores/Waterbox/Swappable.cs @@ -0,0 +1,179 @@ +using BizHawk.Common; +using BizHawk.Common.BizInvoke; +using BizHawk.Common.BufferExtensions; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; + +namespace BizHawk.Emulation.Cores.Waterbox +{ + /// + /// represents an object that can be swapped in and out of memory to compete with other objects in the same memory + /// not suited for general purpose stuff + /// + public abstract class Swappable : IMonitor, IDisposable + { + /// + /// start address + /// + private uint _lockkey; + + /// + /// the the relevant lockinfo for this core + /// + private LockInfo _currentLockInfo; + + /// + /// everything to swap in for context switches + /// + private List _memoryBlocks = new List(); + + /// + /// an informative name for each memory block: used for debugging purposes + /// + private List _memoryBlockNames = new List(); + + protected void AddMemoryBlock(MemoryBlock block, string name) + { + _memoryBlocks.Add(block); + _memoryBlockNames.Add(name); + } + + protected void PurgeMemoryBlocks() + { + _memoryBlocks = null; + } + + protected void Initialize(ulong startAddress) + { + // any Swappables in the same 4G range are assumed to conflict + var lockkey = (uint)(startAddress >> 32); + + _lockkey = lockkey; + if (lockkey == 0) + throw new NullReferenceException(); + _currentLockInfo = LockInfos.GetOrAdd(_lockkey, new LockInfo { Sync = new object() }); + } + + private class LockInfo + { + public object Sync; + private WeakReference LoadedRef = new WeakReference(null); +#if DEBUG + /// + /// recursive lock count + /// + public int LockCount; +#endif + public Swappable Loaded + { + get + { + // if somehow an object died without being disposed, + // the MemoryBlock finalizer will have unloaded the memory + // and so we can treat it as if no Swappable was attached + return (Swappable)LoadedRef.Target; + } + set + { + LoadedRef.Target = value; + } + } + } + + private static readonly ConcurrentDictionary LockInfos = new ConcurrentDictionary(); + + /// + /// acquire lock and swap this into memory + /// + public void Enter() + { + Monitor.Enter(_currentLockInfo.Sync); +#if DEBUG + if (_currentLockInfo.LockCount++ != 0 && _currentLockInfo.Loaded != this) + throw new InvalidOperationException("Woops!"); +#endif + if (_currentLockInfo.Loaded != this) + { + if (_currentLockInfo.Loaded != null) + _currentLockInfo.Loaded.DeactivateInternal(); + _currentLockInfo.Loaded = null; + ActivateInternal(); + _currentLockInfo.Loaded = this; + } + } + + /// + /// release lock + /// + public void Exit() + { +#if DEBUG + // when debugging, if we're releasing the lock then deactivate + if (_currentLockInfo.LockCount-- == 1) + { + if (_currentLockInfo.Loaded != this) + throw new InvalidOperationException("Woops!"); + DeactivateInternal(); + _currentLockInfo.Loaded = null; + } +#endif + Monitor.Exit(_currentLockInfo.Sync); + } + + private void DeactivateInternal() + { + Console.WriteLine("Swappable DeactivateInternal {0}", GetHashCode()); + foreach (var m in _memoryBlocks) + m.Deactivate(); + } + + private void ActivateInternal() + { + Console.WriteLine("Swappable ActivateInternal {0}", GetHashCode()); + foreach (var m in _memoryBlocks) + m.Activate(); + } + + public void PrintDebuggingInfo() + { + using (this.EnterExit()) + { + foreach (var a in _memoryBlocks.Zip(_memoryBlockNames, (m, s) => new { m, s })) + { + Console.WriteLine($"{a.m.FullHash().BytesToHexString()}: {a.s}"); + } + } + } + + private bool _disposed = false; + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + lock (_currentLockInfo.Sync) + { + if (_currentLockInfo.Loaded == this) + { + DeactivateInternal(); + _currentLockInfo.Loaded = null; + } + _currentLockInfo = null; + } + } + _disposed = true; + } + } + + public void Dispose() + { + Dispose(true); + } + } +} diff --git a/BizHawk.Emulation.Cores/Waterbox/WaterboxCore.cs b/BizHawk.Emulation.Cores/Waterbox/WaterboxCore.cs new file mode 100644 index 0000000000..02824114a5 --- /dev/null +++ b/BizHawk.Emulation.Cores/Waterbox/WaterboxCore.cs @@ -0,0 +1,386 @@ +using BizHawk.Common; +using BizHawk.Common.BizInvoke; +using BizHawk.Common.BufferExtensions; +using BizHawk.Emulation.Common; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Waterbox +{ + public abstract class WaterboxCore : IEmulator, IVideoProvider, ISoundProvider, IStatable, + IInputPollable, ISaveRam + { + private LibWaterboxCore _core; + protected PeRunner _exe; + protected LibWaterboxCore.MemoryArea[] _memoryAreas; + private LibWaterboxCore.EmptyCallback _inputCallback; + + public class Configuration + { + public int MaxWidth; + public int MaxHeight; + public int DefaultWidth; + public int DefaultHeight; + public int DefaultFpsNumerator; + public int DefaultFpsDenominator; + public int MaxSamples; + public string SystemId; + } + + protected WaterboxCore(CoreComm comm, Configuration c) + { + BufferWidth = c.DefaultWidth; + BufferHeight = c.DefaultHeight; + _videoBuffer = new int[c.MaxWidth * c.MaxHeight]; + _soundBuffer = new short[c.MaxSamples * 2]; + VsyncNumerator = c.DefaultFpsNumerator; + VsyncDenominator = c.DefaultFpsDenominator; + _serviceProvider = new BasicServiceProvider(this); + SystemId = c.SystemId; + CoreComm = comm; + _inputCallback = InputCallbacks.Call; + } + + protected T PreInit(PeRunnerOptions options) + where T : LibWaterboxCore + { + if (options.Path == null) + options.Path = CoreComm.CoreFileProvider.DllPath(); + _exe = new PeRunner(options); + using (_exe.EnterExit()) + { + var ret = BizInvoker.GetInvoker(_exe, _exe, CallingConventionAdapters.Waterbox); + _core = ret; + return ret; + } + } + + protected void PostInit() + { + using (_exe.EnterExit()) + { + var areas = new LibWaterboxCore.MemoryArea[256]; + _core.GetMemoryAreas(areas); + _memoryAreas = areas.Where(a => a.Data != IntPtr.Zero && a.Size != 0) + .ToArray(); + _saveramAreas = _memoryAreas.Where(a => (a.Flags & LibWaterboxCore.MemoryDomainFlags.Saverammable) != 0) + .ToArray(); + _saveramSize = (int)_saveramAreas.Sum(a => a.Size); + + var memoryDomains = _memoryAreas.Select(a => new LibWaterboxCore.WaterboxMemoryDomain(a, _exe)); + var primaryIndex = _memoryAreas + .Select((a, i) => new { a, i }) + .Single(a => (a.a.Flags & LibWaterboxCore.MemoryDomainFlags.Primary) != 0).i; + var mdl = new MemoryDomainList(memoryDomains.Cast().ToList()); + mdl.MainMemory = mdl[primaryIndex]; + _serviceProvider.Register(mdl); + + var sr = _core as ICustomSaveram; + if (sr != null) + _serviceProvider.Register(new CustomSaverammer(sr)); // override the default implementation + + _exe.Seal(); + } + } + + #region RTC + + private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0); + private long _clockTime; + private int _clockRemainder; + + protected void InitializeRtc(DateTime start) + { + _clockTime = (long)(start - Epoch).TotalSeconds; + } + + protected long GetRtcTime(bool realTime) + { + if (realTime && DeterministicEmulation) + throw new InvalidOperationException(); + return realTime ? (long)(DateTime.Now - Epoch).TotalSeconds : _clockTime; + } + + private void AdvanceRtc() + { + _clockRemainder += VsyncDenominator; + if (_clockRemainder >= VsyncNumerator) + { + _clockRemainder -= VsyncNumerator; + _clockTime++; + } + } + + #endregion + + #region ISaveRam + + private LibWaterboxCore.MemoryArea[] _saveramAreas; + private int _saveramSize; + + public unsafe bool SaveRamModified + { + get + { + if (_saveramSize == 0) + return false; + using (_exe.EnterExit()) + { + foreach (var area in _saveramAreas) + { + int* p = (int*)area.Data; + int* pend = p + area.Size / sizeof(int); + int cmp = (area.Flags & LibWaterboxCore.MemoryDomainFlags.OneFilled) != 0 ? -1 : 0; + + while (p < pend) + { + if (*p++ != cmp) + return true; + } + } + } + return false; + } + } + + public byte[] CloneSaveRam() + { + if (_saveramSize == 0) + return null; + using (_exe.EnterExit()) + { + var ret = new byte[_saveramSize]; + var offs = 0; + foreach (var area in _saveramAreas) + { + Marshal.Copy(area.Data, ret, offs, (int)area.Size); + offs += (int)area.Size; + } + return ret; + } + } + + public void StoreSaveRam(byte[] data) + { + using (_exe.EnterExit()) + { + if (data.Length != _saveramSize) + throw new InvalidOperationException("Saveram size mismatch"); + using (_exe.EnterExit()) + { + var offs = 0; + foreach (var area in _saveramAreas) + { + Marshal.Copy(data, offs, area.Data, (int)area.Size); + offs += (int)area.Size; + } + } + } + } + + #endregion ISaveRam + + #region IEmulator + + protected abstract LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound); + protected virtual void FrameAdvancePost() + { } + + public unsafe void FrameAdvance(IController controller, bool render, bool rendersound = true) + { + using (_exe.EnterExit()) + { + _core.SetInputCallback(InputCallbacks.Count > 0 ? _inputCallback : null); + + fixed (int* vp = _videoBuffer) + fixed (short* sp = _soundBuffer) + { + var frame = FrameAdvancePrep(controller, render, rendersound); + frame.VideoBuffer = (IntPtr)vp; + frame.SoundBuffer = (IntPtr)sp; + + _core.FrameAdvance(frame); + + Frame++; + if (IsLagFrame = frame.Lagged != 0) + LagCount++; + AdvanceRtc(); + + BufferWidth = frame.Width; + BufferHeight = frame.Height; + _numSamples = frame.Samples; + + FrameAdvancePost(); + } + } + } + + private bool _disposed = false; + + public virtual void Dispose() + { + if (!_disposed) + { + _exe.Dispose(); + _disposed = true; + } + } + + public CoreComm CoreComm { get; } + public int Frame { get; private set; } + public int LagCount { get; set; } + public bool IsLagFrame { get; set; } + + public void ResetCounters() + { + Frame = 0; + } + + protected readonly BasicServiceProvider _serviceProvider; + public IEmulatorServiceProvider ServiceProvider => _serviceProvider; + public string SystemId { get; } + public bool DeterministicEmulation { get; protected set; } = true; + public IInputCallbackSystem InputCallbacks { get; } = new InputCallbackSystem(); + public virtual ControllerDefinition ControllerDefinition { get; protected set; } = NullController.Instance.Definition; + + #endregion + + #region IStatable + + public bool BinarySaveStatesPreferred => true; + + public void SaveStateText(TextWriter writer) + { + var temp = SaveStateBinary(); + temp.SaveAsHexFast(writer); + } + + public void LoadStateText(TextReader reader) + { + string hex = reader.ReadLine(); + byte[] state = new byte[hex.Length / 2]; + state.ReadFromHexFast(hex); + LoadStateBinary(new BinaryReader(new MemoryStream(state))); + } + + public void LoadStateBinary(BinaryReader reader) + { + _exe.LoadStateBinary(reader); + // other variables + Frame = reader.ReadInt32(); + LagCount = reader.ReadInt32(); + IsLagFrame = reader.ReadBoolean(); + BufferWidth = reader.ReadInt32(); + BufferHeight = reader.ReadInt32(); + _clockTime = reader.ReadInt64(); + _clockRemainder = reader.ReadInt32(); + // reset pointers here! + _core.SetInputCallback(null); + //_exe.PrintDebuggingInfo(); + LoadStateBinaryInternal(reader); + } + + public void SaveStateBinary(BinaryWriter writer) + { + _exe.SaveStateBinary(writer); + // other variables + writer.Write(Frame); + writer.Write(LagCount); + writer.Write(IsLagFrame); + writer.Write(BufferWidth); + writer.Write(BufferHeight); + writer.Write(_clockTime); + writer.Write(_clockRemainder); + SaveStateBinaryInternal(writer); + } + + public byte[] SaveStateBinary() + { + var ms = new MemoryStream(); + var bw = new BinaryWriter(ms); + SaveStateBinary(bw); + bw.Flush(); + ms.Close(); + return ms.ToArray(); + } + + /// + /// called after the base core saves state. the core must save any other + /// variables that it needs to. + /// the default implementation does nothing + /// + /// + protected virtual void SaveStateBinaryInternal(BinaryWriter writer) + { + + } + + /// + /// called after the base core loads state. the core must load any other variables + /// that were in SaveStateBinaryInternal and reset any native pointers. + /// the default implementation does nothing + /// + /// + protected virtual void LoadStateBinaryInternal(BinaryReader reader) + { + + } + + #endregion + + #region ISoundProvider + + public void SetSyncMode(SyncSoundMode mode) + { + if (mode == SyncSoundMode.Async) + { + throw new NotSupportedException("Async mode is not supported."); + } + } + + public void GetSamplesSync(out short[] samples, out int nsamp) + { + samples = _soundBuffer; + nsamp = _numSamples; + } + + public void GetSamplesAsync(short[] samples) + { + throw new InvalidOperationException("Async mode is not supported."); + } + + public void DiscardSamples() + { + } + + protected readonly short[] _soundBuffer; + protected int _numSamples; + public bool CanProvideAsync => false; + public SyncSoundMode SyncMode => SyncSoundMode.Sync; + + #endregion + + #region IVideoProvider + + public int[] GetVideoBuffer() + { + return _videoBuffer; + } + + protected readonly int[] _videoBuffer; + public virtual int VirtualWidth => BufferWidth; + public virtual int VirtualHeight => BufferWidth; + public int BufferWidth { get; protected set; } + public int BufferHeight { get; protected set; } + public virtual int VsyncNumerator { get; protected set; } + public virtual int VsyncDenominator { get; protected set; } + public int BackgroundColor => unchecked((int)0xff000000); + + #endregion + } +} diff --git a/BizHawk.Emulation.Cores/Waterbox/WaterboxUtils.cs b/BizHawk.Emulation.Cores/Waterbox/WaterboxUtils.cs new file mode 100644 index 0000000000..4477642d4b --- /dev/null +++ b/BizHawk.Emulation.Cores/Waterbox/WaterboxUtils.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Text; + +namespace BizHawk.Emulation.Cores.Waterbox +{ + public static class WaterboxUtils + { + /// + /// copy `len` bytes from `src` to `dest` + /// + /// + /// + /// + public static void CopySome(Stream src, Stream dst, long len) + { + var buff = new byte[4096]; + while (len > 0) + { + int r = src.Read(buff, 0, (int)Math.Min(len, 4096)); + dst.Write(buff, 0, r); + len -= r; + } + } + + public static byte[] Hash(byte[] data) + { + using (var h = SHA1.Create()) + { + return h.ComputeHash(data); + } + } + + public static byte[] Hash(Stream s) + { + using (var h = SHA1.Create()) + { + return h.ComputeHash(s); + } + } + + public static unsafe void ZeroMemory(IntPtr mem, long length) + { + byte* p = (byte*)mem; + byte* end = p + length; + while (p < end) + { + *p++ = 0; + } + } + + public static long Timestamp() + { + return DateTime.UtcNow.Ticks; + } + + /// + /// system page size + /// + public static int PageSize { get; private set; } + + /// + /// bitshift corresponding to PageSize + /// + public static int PageShift { get; private set; } + /// + /// bitmask corresponding to PageSize + /// + public static ulong PageMask { get; private set; } + + static WaterboxUtils() + { + int p = PageSize = Environment.SystemPageSize; + while (p != 1) + { + p >>= 1; + PageShift++; + } + PageMask = (ulong)(PageSize - 1); + } + + /// + /// true if addr is aligned + /// + public static bool Aligned(ulong addr) + { + return (addr & PageMask) == 0; + } + + /// + /// align address down to previous page boundary + /// + public static ulong AlignDown(ulong addr) + { + return addr & ~PageMask; + } + + /// + /// align address up to next page boundary + /// + public static ulong AlignUp(ulong addr) + { + return ((addr - 1) | PageMask) + 1; + } + + /// + /// return the minimum number of pages needed to hold size + /// + public static int PagesNeeded(ulong size) + { + return (int)((size + PageMask) >> PageShift); + } + } + + // C# is annoying: arithmetic operators for native ints are not exposed. + // So we store them as long/ulong instead in many places, and use these helpers + // to convert to IntPtr when needed + + public static class Z + { + public static IntPtr US(ulong l) + { + if (IntPtr.Size == 8) + return (IntPtr)(long)l; + else + return (IntPtr)(int)l; + } + + public static UIntPtr UU(ulong l) + { + if (UIntPtr.Size == 8) + return (UIntPtr)l; + else + return (UIntPtr)(uint)l; + } + + public static IntPtr SS(long l) + { + if (IntPtr.Size == 8) + return (IntPtr)l; + else + return (IntPtr)(int)l; + } + + public static UIntPtr SU(long l) + { + if (UIntPtr.Size == 8) + return (UIntPtr)(ulong)l; + else + return (UIntPtr)(uint)l; + } + } +} diff --git a/BizHawk.Emulation.DiscSystem/BizHawk.Emulation.DiscSystem.csproj b/BizHawk.Emulation.DiscSystem/BizHawk.Emulation.DiscSystem.csproj index 4b0ab9ee77..3e320bb2e1 100644 --- a/BizHawk.Emulation.DiscSystem/BizHawk.Emulation.DiscSystem.csproj +++ b/BizHawk.Emulation.DiscSystem/BizHawk.Emulation.DiscSystem.csproj @@ -1,5 +1,5 @@  - + true bin\x64\Debug\ @@ -17,6 +17,7 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules false false + false bin\x64\Release\ @@ -35,6 +36,7 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules false false + false @@ -45,31 +47,10 @@ Properties BizHawk.Emulation.DiscSystem BizHawk.Emulation.DiscSystem - v4.0 + v4.6.1 512 - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - x86 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - true - x86 - diff --git a/BizHawk.sln b/BizHawk.sln index 0d46d5e08b..03876e3909 100644 --- a/BizHawk.sln +++ b/BizHawk.sln @@ -1,7 +1,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 12.0.31101.0 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Version", "Version\Version.csproj", "{0CE8B337-08E3-4602-BF10-C4D4C75D2F13}" EndProject @@ -63,149 +63,87 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 Release|x64 = Release|x64 - Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Debug|x64.ActiveCfg = Debug|x64 {0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Debug|x64.Build.0 = Debug|x64 - {0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Debug|x86.ActiveCfg = Debug|x86 - {0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Debug|x86.Build.0 = Debug|x86 {0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Release|x64.ActiveCfg = Release|x64 {0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Release|x64.Build.0 = Release|x64 - {0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Release|x86.ActiveCfg = Release|x86 - {0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Release|x86.Build.0 = Release|x86 {24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Debug|x64.ActiveCfg = Debug|x64 {24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Debug|x64.Build.0 = Debug|x64 - {24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Debug|x86.ActiveCfg = Debug|x86 - {24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Debug|x86.Build.0 = Debug|x86 {24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Release|x64.ActiveCfg = Release|x64 {24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Release|x64.Build.0 = Release|x64 - {24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Release|x86.ActiveCfg = Release|x86 - {24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Release|x86.Build.0 = Release|x86 {866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Debug|x64.ActiveCfg = Debug|x64 {866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Debug|x64.Build.0 = Debug|x64 - {866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Debug|x86.ActiveCfg = Debug|x86 - {866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Debug|x86.Build.0 = Debug|x86 {866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Release|x64.ActiveCfg = Release|x64 {866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Release|x64.Build.0 = Release|x64 - {866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Release|x86.ActiveCfg = Release|x86 - {866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Release|x86.Build.0 = Release|x86 {DD448B37-BA3F-4544-9754-5406E8094723}.Debug|x64.ActiveCfg = Debug|x64 {DD448B37-BA3F-4544-9754-5406E8094723}.Debug|x64.Build.0 = Debug|x64 - {DD448B37-BA3F-4544-9754-5406E8094723}.Debug|x86.ActiveCfg = Debug|x86 - {DD448B37-BA3F-4544-9754-5406E8094723}.Debug|x86.Build.0 = Debug|x86 {DD448B37-BA3F-4544-9754-5406E8094723}.Release|x64.ActiveCfg = Release|x64 {DD448B37-BA3F-4544-9754-5406E8094723}.Release|x64.Build.0 = Release|x64 - {DD448B37-BA3F-4544-9754-5406E8094723}.Release|x86.ActiveCfg = Release|x86 - {DD448B37-BA3F-4544-9754-5406E8094723}.Release|x86.Build.0 = Release|x86 {C4366030-6D03-424B-AE53-F4F43BB217C3}.Debug|x64.ActiveCfg = Debug|x64 {C4366030-6D03-424B-AE53-F4F43BB217C3}.Debug|x64.Build.0 = Debug|x64 - {C4366030-6D03-424B-AE53-F4F43BB217C3}.Debug|x86.ActiveCfg = Debug|x86 - {C4366030-6D03-424B-AE53-F4F43BB217C3}.Debug|x86.Build.0 = Debug|x86 {C4366030-6D03-424B-AE53-F4F43BB217C3}.Release|x64.ActiveCfg = Release|x64 {C4366030-6D03-424B-AE53-F4F43BB217C3}.Release|x64.Build.0 = Release|x64 - {C4366030-6D03-424B-AE53-F4F43BB217C3}.Release|x86.ActiveCfg = Release|x86 - {C4366030-6D03-424B-AE53-F4F43BB217C3}.Release|x86.Build.0 = Release|x86 {F51946EA-827F-4D82-B841-1F2F6D060312}.Debug|x64.ActiveCfg = Debug|x64 {F51946EA-827F-4D82-B841-1F2F6D060312}.Debug|x64.Build.0 = Debug|x64 - {F51946EA-827F-4D82-B841-1F2F6D060312}.Debug|x86.ActiveCfg = Debug|x86 - {F51946EA-827F-4D82-B841-1F2F6D060312}.Debug|x86.Build.0 = Debug|x86 {F51946EA-827F-4D82-B841-1F2F6D060312}.Release|x64.ActiveCfg = Release|x64 {F51946EA-827F-4D82-B841-1F2F6D060312}.Release|x64.Build.0 = Release|x64 - {F51946EA-827F-4D82-B841-1F2F6D060312}.Release|x86.ActiveCfg = Release|x86 - {F51946EA-827F-4D82-B841-1F2F6D060312}.Release|x86.Build.0 = Release|x86 {E1A23168-B571-411C-B360-2229E7225E0E}.Debug|x64.ActiveCfg = Debug|x64 {E1A23168-B571-411C-B360-2229E7225E0E}.Debug|x64.Build.0 = Debug|x64 - {E1A23168-B571-411C-B360-2229E7225E0E}.Debug|x86.ActiveCfg = Debug|x86 - {E1A23168-B571-411C-B360-2229E7225E0E}.Debug|x86.Build.0 = Debug|x86 {E1A23168-B571-411C-B360-2229E7225E0E}.Release|x64.ActiveCfg = Release|x64 {E1A23168-B571-411C-B360-2229E7225E0E}.Release|x64.Build.0 = Release|x64 - {E1A23168-B571-411C-B360-2229E7225E0E}.Release|x86.ActiveCfg = Release|x86 - {E1A23168-B571-411C-B360-2229E7225E0E}.Release|x86.Build.0 = Release|x86 {197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Debug|x64.ActiveCfg = Debug|x64 {197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Debug|x64.Build.0 = Debug|x64 - {197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Debug|x86.ActiveCfg = Debug|x86 - {197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Debug|x86.Build.0 = Debug|x86 {197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Release|x64.ActiveCfg = Release|x64 {197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Release|x64.Build.0 = Release|x64 - {197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Release|x86.ActiveCfg = Release|x86 - {197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Release|x86.Build.0 = Release|x86 {9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Debug|x64.ActiveCfg = Debug|x64 {9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Debug|x64.Build.0 = Debug|x64 - {9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Debug|x86.ActiveCfg = Debug|x86 - {9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Debug|x86.Build.0 = Debug|x86 {9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Release|x64.ActiveCfg = Release|x64 {9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Release|x64.Build.0 = Release|x64 - {9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Release|x86.ActiveCfg = Release|x86 - {9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Release|x86.Build.0 = Release|x86 {5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Debug|x64.ActiveCfg = Debug|x64 {5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Debug|x64.Build.0 = Debug|x64 - {5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Debug|x86.ActiveCfg = Debug|x86 - {5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Debug|x86.Build.0 = Debug|x86 {5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Release|x64.ActiveCfg = Release|x64 {5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Release|x64.Build.0 = Release|x64 - {5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Release|x86.ActiveCfg = Release|x86 - {5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Release|x86.Build.0 = Release|x86 {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|x64.ActiveCfg = Debug|x64 {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|x64.Build.0 = Debug|x64 - {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|x86.ActiveCfg = Debug|x86 - {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|x86.Build.0 = Debug|x86 {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|x64.ActiveCfg = Release|x64 {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|x64.Build.0 = Release|x64 - {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|x86.ActiveCfg = Release|x86 - {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|x86.Build.0 = Release|x86 {337CA23E-65E7-44E1-9411-97EE08BB8116}.Debug|x64.ActiveCfg = Debug|x64 {337CA23E-65E7-44E1-9411-97EE08BB8116}.Debug|x64.Build.0 = Debug|x64 - {337CA23E-65E7-44E1-9411-97EE08BB8116}.Debug|x86.ActiveCfg = Debug|x86 - {337CA23E-65E7-44E1-9411-97EE08BB8116}.Debug|x86.Build.0 = Debug|x86 {337CA23E-65E7-44E1-9411-97EE08BB8116}.Release|x64.ActiveCfg = Release|x64 {337CA23E-65E7-44E1-9411-97EE08BB8116}.Release|x64.Build.0 = Release|x64 - {337CA23E-65E7-44E1-9411-97EE08BB8116}.Release|x86.ActiveCfg = Release|x86 - {337CA23E-65E7-44E1-9411-97EE08BB8116}.Release|x86.Build.0 = Release|x86 {E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Debug|x64.ActiveCfg = Debug|x64 {E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Debug|x64.Build.0 = Debug|x64 - {E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Debug|x86.ActiveCfg = Debug|x86 - {E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Debug|x86.Build.0 = Debug|x86 {E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Release|x64.ActiveCfg = Release|x64 {E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Release|x64.Build.0 = Release|x64 - {E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Release|x86.ActiveCfg = Release|x86 - {E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Release|x86.Build.0 = Release|x86 {B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Debug|x64.ActiveCfg = Debug|x64 {B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Debug|x64.Build.0 = Debug|x64 - {B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Debug|x86.ActiveCfg = Debug|x86 - {B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Debug|x86.Build.0 = Debug|x86 {B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Release|x64.ActiveCfg = Release|x64 {B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Release|x64.Build.0 = Release|x64 - {B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Release|x86.ActiveCfg = Release|x86 - {B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Release|x86.Build.0 = Release|x86 {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Debug|x64.ActiveCfg = Debug|x64 {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Debug|x64.Build.0 = Debug|x64 - {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Debug|x86.ActiveCfg = Debug|x86 - {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Debug|x86.Build.0 = Debug|x86 {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Release|x64.ActiveCfg = Release|x64 {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Release|x64.Build.0 = Release|x64 - {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Release|x86.ActiveCfg = Release|x86 - {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution + {24A0AA3C-B25F-4197-B23D-476D6462DBA0} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA} {DD448B37-BA3F-4544-9754-5406E8094723} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA} {C4366030-6D03-424B-AE53-F4F43BB217C3} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA} - {24A0AA3C-B25F-4197-B23D-476D6462DBA0} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA} - {2D2890A8-C338-4439-AD8B-CB9EE85A94F9} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA} - {B95649F5-A0AE-41EB-B62B-578A2AFF5E18} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA} - {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA} - {E1A23168-B571-411C-B360-2229E7225E0E} = {3627C08B-3E43-4224-9DA4-40BD69495FBC} {F51946EA-827F-4D82-B841-1F2F6D060312} = {3627C08B-3E43-4224-9DA4-40BD69495FBC} + {E1A23168-B571-411C-B360-2229E7225E0E} = {3627C08B-3E43-4224-9DA4-40BD69495FBC} {197D4314-8A9F-49BA-977D-54ACEFAEB6BA} = {3627C08B-3E43-4224-9DA4-40BD69495FBC} {9F84A0B2-861E-4EF4-B89B-5E2A3F38A465} = {0540A9A6-977E-466D-8BD3-1D8590BD5282} {5160CFB1-5389-47C1-B7F6-8A0DC97641EE} = {0540A9A6-977E-466D-8BD3-1D8590BD5282} + {2D2890A8-C338-4439-AD8B-CB9EE85A94F9} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA} {337CA23E-65E7-44E1-9411-97EE08BB8116} = {0540A9A6-977E-466D-8BD3-1D8590BD5282} {E6B436B1-A3CD-4C9A-8F76-5D7154726884} = {0540A9A6-977E-466D-8BD3-1D8590BD5282} + {B95649F5-A0AE-41EB-B62B-578A2AFF5E18} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA} + {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA} EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution StartupItem = BizHawk.Client.EmuHawk\BizHawk.Client.EmuHawk.csproj diff --git a/Bizware/BizHawk.Bizware.BizwareGL.GdiPlus/BizHawk.Bizware.BizwareGL.GdiPlus.csproj b/Bizware/BizHawk.Bizware.BizwareGL.GdiPlus/BizHawk.Bizware.BizwareGL.GdiPlus.csproj index 12a3ec16a6..e0828eeee4 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL.GdiPlus/BizHawk.Bizware.BizwareGL.GdiPlus.csproj +++ b/Bizware/BizHawk.Bizware.BizwareGL.GdiPlus/BizHawk.Bizware.BizwareGL.GdiPlus.csproj @@ -1,5 +1,5 @@  - + Debug x86 @@ -10,29 +10,9 @@ Properties BizHawk.Bizware.BizwareGL.GdiPlus BizHawk.Bizware.BizwareGL.GdiPlus - v4.0 + v4.6.1 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - x86 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - true - x86 + true @@ -49,6 +29,7 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules true + false bin\x64\Release\ @@ -64,6 +45,7 @@ MinimumRecommendedRules.ruleset ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false diff --git a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/BizHawk.Bizware.BizwareGL.OpenTK.csproj b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/BizHawk.Bizware.BizwareGL.OpenTK.csproj index acef8d082b..ecf94aff01 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/BizHawk.Bizware.BizwareGL.OpenTK.csproj +++ b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/BizHawk.Bizware.BizwareGL.OpenTK.csproj @@ -1,5 +1,5 @@  - + Debug x86 @@ -10,29 +10,9 @@ Properties BizHawk.Bizware.BizwareGL.OpenTK BizHawk.Bizware.BizwareGL.OpenTK - v4.0 + v4.6.1 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - x86 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - true - x86 + true @@ -51,6 +31,7 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules false false + false bin\x64\Release\ @@ -69,6 +50,7 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules false false + false diff --git a/Bizware/BizHawk.Bizware.BizwareGL.SlimDX/BizHawk.Bizware.BizwareGL.SlimDX.csproj b/Bizware/BizHawk.Bizware.BizwareGL.SlimDX/BizHawk.Bizware.BizwareGL.SlimDX.csproj index a7a7aa9dd4..2356fc4932 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL.SlimDX/BizHawk.Bizware.BizwareGL.SlimDX.csproj +++ b/Bizware/BizHawk.Bizware.BizwareGL.SlimDX/BizHawk.Bizware.BizwareGL.SlimDX.csproj @@ -1,5 +1,5 @@  - + Debug x86 @@ -10,29 +10,9 @@ Properties BizHawk.Bizware.BizwareGL.SlimDX BizHawk.Bizware.BizwareGL.SlimDX - v4.0 + v4.6.1 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - x86 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - true - x86 + true @@ -49,6 +29,7 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules true + false bin\x64\Release\ @@ -64,6 +45,7 @@ MinimumRecommendedRules.ruleset ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false diff --git a/Bizware/BizHawk.Bizware.BizwareGL/BitmapBuffer.cs b/Bizware/BizHawk.Bizware.BizwareGL/BitmapBuffer.cs index e31be485d0..df5fc3591a 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL/BitmapBuffer.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL/BitmapBuffer.cs @@ -367,7 +367,7 @@ namespace BizHawk.Bizware.BizwareGL int height = bmp.Height; InitSize(width, height); BitmapData bmpdata = bmp.LockBits(new sd.Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); - int* ptr = (int*)bmpdata.Scan0.ToInt32(); + int* ptr = (int*)bmpdata.Scan0; int stride = bmpdata.Stride / 4; LoadFrom(width, stride, height, (byte*)ptr, options); bmp.UnlockBits(bmpdata); diff --git a/Bizware/BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj b/Bizware/BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj index cdd918f0c8..3b52371bff 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj +++ b/Bizware/BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj @@ -1,5 +1,5 @@  - + Debug x86 @@ -10,29 +10,9 @@ Properties BizHawk.Bizware.BizwareGL BizHawk.Bizware.BizwareGL - v4.0 + v4.6.1 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - x86 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - true - x86 + true @@ -51,6 +31,7 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules false false + false bin\x64\Release\ @@ -69,6 +50,7 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules false false + false diff --git a/Dist/BuildAndPackage.bat b/Dist/BuildAndPackage.bat index f225d6fd4a..b7ec9e82af 100644 --- a/Dist/BuildAndPackage.bat +++ b/Dist/BuildAndPackage.bat @@ -17,7 +17,7 @@ for /f "skip=2 tokens=2,*" %%A in ('reg.exe query "HKLM\SOFTWARE\Microsoft\MSBui IF NOT EXIST %MSBUILDDIR%nul goto MISSINGMSBUILD IF NOT EXIST %MSBUILDDIR%msbuild.exe goto MISSINGMSBUILD -call "%MSBUILDDIR%msbuild.exe" ..\BizHawk.sln /p:Configuration=Release /p:Platform="x86" /t:rebuild +call "%MSBUILDDIR%msbuild.exe" ..\BizHawk.sln /p:Configuration=Release /p:Platform="x64" /t:rebuild @if errorlevel 1 goto MSBUILDFAILED diff --git a/Dist/RunILMerge.bat b/Dist/RunILMerge.bat index aa1d2e17d4..f388ad3edb 100644 --- a/Dist/RunILMerge.bat +++ b/Dist/RunILMerge.bat @@ -1,2 +1,2 @@ @echo please copy "C:\Windows\Microsoft.NET\Framework\v3.0\WPF\PresentationUI.dll" to this directory. Dunno why. -ilmerge /v4 /target:WinExe /out:..\output\EmuHawk.merged.exe ..\output\EmuHawk.exe ..\output\BizHawk.Client.Common.dll ..\output\BizHawk.Common.dll ..\output\BizHawk.Emulation.Common.dll ..\output\BizHawk.Emulation.Cores.dll ..\output\BizHawk.Emulation.DiscSystem.dll "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\PresentationFramework.dll" PresentationUI.dll \ No newline at end of file +ilmerge /v4 /target:WinExe /out:..\output64\EmuHawk.merged.exe ..\output64\EmuHawk.exe ..\output64\BizHawk.Client.Common.dll ..\output64\BizHawk.Common.dll ..\output64\BizHawk.Emulation.Common.dll ..\output64\BizHawk.Emulation.Cores.dll ..\output64\BizHawk.Emulation.DiscSystem.dll "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\PresentationFramework.dll" PresentationUI.dll \ No newline at end of file diff --git a/LibretroBridge/vs2015/LibretroBridge.cpp b/LibretroBridge/vs2015/LibretroBridge.cpp index addc698708..69f3047a63 100644 --- a/LibretroBridge/vs2015/LibretroBridge.cpp +++ b/LibretroBridge/vs2015/LibretroBridge.cpp @@ -172,7 +172,7 @@ struct CommStruct //always used in pairs void* buf[BufId_Num]; - s32 buf_size[BufId_Num]; + size_t buf_size[BufId_Num]; //=========================================================== //private stuff @@ -187,7 +187,7 @@ struct CommStruct size_t len = strlen(str); CopyBuffer(id, (void*)str, len+1); } - void CopyBuffer(int id, void* ptr, s32 size) + void CopyBuffer(int id, void* ptr, size_t size) { if (privbuf[id]) free(privbuf[id]); buf[id] = privbuf[id] = malloc(size); @@ -195,7 +195,7 @@ struct CommStruct buf_size[id] = size; } - void SetBuffer(int id, void* ptr, s32 size) + void SetBuffer(int id, void* ptr, size_t size) { buf[id] = ptr; buf_size[id] = size; diff --git a/LibretroBridge/vs2015/LibretroBridge.sln b/LibretroBridge/vs2015/LibretroBridge.sln index 145f7104dc..3a5c0493e9 100644 --- a/LibretroBridge/vs2015/LibretroBridge.sln +++ b/LibretroBridge/vs2015/LibretroBridge.sln @@ -7,14 +7,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibretroBridge", "LibretroB EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x86 = Debug|x86 - Release|x86 = Release|x86 + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {AEACAA89-FDA2-40C6-910C-85AEB9726452}.Debug|x86.ActiveCfg = Debug|Win32 - {AEACAA89-FDA2-40C6-910C-85AEB9726452}.Debug|x86.Build.0 = Debug|Win32 - {AEACAA89-FDA2-40C6-910C-85AEB9726452}.Release|x86.ActiveCfg = Release|Win32 - {AEACAA89-FDA2-40C6-910C-85AEB9726452}.Release|x86.Build.0 = Release|Win32 + {AEACAA89-FDA2-40C6-910C-85AEB9726452}.Debug|x64.ActiveCfg = Debug|x64 + {AEACAA89-FDA2-40C6-910C-85AEB9726452}.Debug|x64.Build.0 = Debug|x64 + {AEACAA89-FDA2-40C6-910C-85AEB9726452}.Release|x64.ActiveCfg = Release|x64 + {AEACAA89-FDA2-40C6-910C-85AEB9726452}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/LibretroBridge/vs2015/LibretroBridge.vcxproj b/LibretroBridge/vs2015/LibretroBridge.vcxproj index b04ba18ede..6aa88bd598 100644 --- a/LibretroBridge/vs2015/LibretroBridge.vcxproj +++ b/LibretroBridge/vs2015/LibretroBridge.vcxproj @@ -1,14 +1,6 @@  - - Debug - Win32 - - - Release - Win32 - Debug x64 @@ -19,14 +11,27 @@ - - - + + + + NotSet + + + NotSet + NotSet + + + NotSet + NotSet + + + + {AEACAA89-FDA2-40C6-910C-85AEB9726452} Win32Proj @@ -34,20 +39,6 @@ 8.1 - - DynamicLibrary - true - v140_xp - NotSet - false - - - DynamicLibrary - false - v140_xp - true - NotSet - DynamicLibrary true @@ -64,15 +55,10 @@ + - - - - - - @@ -80,44 +66,16 @@ - - true - ..\..\output\dll\ - .obj\$(Configuration)\ - true ..\..\output\dll\ .obj\$(Configuration)\ - - false - ..\..\output\dll\ - .obj\$(Configuration)\ - false ..\..\output\dll\ .obj\$(Configuration)\ - - - - - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBRETRO_EXPORTS;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - StreamingSIMDExtensions - Fast - false - - - Windows - true - Default - - @@ -136,27 +94,6 @@ Default - - - Level3 - - - MaxSpeed - false - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBRETRO_EXPORTS;%(PreprocessorDefinitions) - MultiThreaded - StreamingSIMDExtensions - Fast - - - Windows - true - true - true - /pdbaltpath:%_PDB% %(AdditionalOptions) - - Level3 @@ -180,6 +117,7 @@ + diff --git a/LibretroBridge/vs2015/libco/amd64.c b/LibretroBridge/vs2015/libco/amd64.c index 5f1cfca97a..ea36bbeaea 100644 --- a/LibretroBridge/vs2015/libco/amd64.c +++ b/LibretroBridge/vs2015/libco/amd64.c @@ -1,104 +1,82 @@ -/* - libco.amd64 (2009-10-12) - author: byuu - license: public domain -*/ - -#define LIBCO_C -#include "libco.h" -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -static thread_local long long co_active_buffer[64]; -static thread_local cothread_t co_active_handle = 0; -static void (*co_swap)(cothread_t, cothread_t) = 0; - -#ifdef _WIN32 - //ABI: Win64 - static unsigned char co_swap_function[] = { - 0x48, 0x89, 0x22, 0x48, 0x8B, 0x21, 0x58, 0x48, 0x89, 0x6A, 0x08, 0x48, 0x89, 0x72, 0x10, 0x48, - 0x89, 0x7A, 0x18, 0x48, 0x89, 0x5A, 0x20, 0x4C, 0x89, 0x62, 0x28, 0x4C, 0x89, 0x6A, 0x30, 0x4C, - 0x89, 0x72, 0x38, 0x4C, 0x89, 0x7A, 0x40, 0x48, 0x81, 0xC2, 0x80, 0x00, 0x00, 0x00, 0x48, 0x83, - 0xE2, 0xF0, 0x0F, 0x29, 0x32, 0x0F, 0x29, 0x7A, 0x10, 0x44, 0x0F, 0x29, 0x42, 0x20, 0x44, 0x0F, - 0x29, 0x4A, 0x30, 0x44, 0x0F, 0x29, 0x52, 0x40, 0x44, 0x0F, 0x29, 0x5A, 0x50, 0x44, 0x0F, 0x29, - 0x62, 0x60, 0x44, 0x0F, 0x29, 0x6A, 0x70, 0x44, 0x0F, 0x29, 0xB2, 0x80, 0x00, 0x00, 0x00, 0x44, - 0x0F, 0x29, 0xBA, 0x90, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x69, 0x08, 0x48, 0x8B, 0x71, 0x10, 0x48, - 0x8B, 0x79, 0x18, 0x48, 0x8B, 0x59, 0x20, 0x4C, 0x8B, 0x61, 0x28, 0x4C, 0x8B, 0x69, 0x30, 0x4C, - 0x8B, 0x71, 0x38, 0x4C, 0x8B, 0x79, 0x40, 0x48, 0x81, 0xC1, 0x80, 0x00, 0x00, 0x00, 0x48, 0x83, - 0xE1, 0xF0, 0x0F, 0x29, 0x31, 0x0F, 0x29, 0x79, 0x10, 0x44, 0x0F, 0x29, 0x41, 0x20, 0x44, 0x0F, - 0x29, 0x49, 0x30, 0x44, 0x0F, 0x29, 0x51, 0x40, 0x44, 0x0F, 0x29, 0x59, 0x50, 0x44, 0x0F, 0x29, - 0x61, 0x60, 0x44, 0x0F, 0x29, 0x69, 0x70, 0x44, 0x0F, 0x29, 0xB1, 0x80, 0x00, 0x00, 0x00, 0x44, - 0x0F, 0x29, 0xB9, 0x90, 0x00, 0x00, 0x00, 0xFF, 0xE0, - }; - - #include - - void co_init() { - DWORD old_privileges; - VirtualProtect(co_swap_function, sizeof co_swap_function, PAGE_EXECUTE_READWRITE, &old_privileges); - } -#else - //ABI: SystemV - static unsigned char co_swap_function[] = { - 0x48, 0x89, 0x26, 0x48, 0x8B, 0x27, 0x58, 0x48, 0x89, 0x6E, 0x08, 0x48, 0x89, 0x5E, 0x10, 0x4C, - 0x89, 0x66, 0x18, 0x4C, 0x89, 0x6E, 0x20, 0x4C, 0x89, 0x76, 0x28, 0x4C, 0x89, 0x7E, 0x30, 0x48, - 0x8B, 0x6F, 0x08, 0x48, 0x8B, 0x5F, 0x10, 0x4C, 0x8B, 0x67, 0x18, 0x4C, 0x8B, 0x6F, 0x20, 0x4C, - 0x8B, 0x77, 0x28, 0x4C, 0x8B, 0x7F, 0x30, 0xFF, 0xE0, - }; - - #include - #include - - void co_init() { - unsigned long long addr = (unsigned long long)co_swap_function; - unsigned long long base = addr - (addr % sysconf(_SC_PAGESIZE)); - unsigned long long size = (addr - base) + sizeof co_swap_function; - mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC); - } -#endif - -static void crash() { - assert(0); /* called only if cothread_t entrypoint returns */ -} - -cothread_t co_active() { - if(!co_active_handle) co_active_handle = &co_active_buffer; - return co_active_handle; -} - -cothread_t co_create(unsigned int size, void (*entrypoint)(void)) { - cothread_t handle; - if(!co_swap) { - co_init(); - co_swap = (void (*)(cothread_t, cothread_t))co_swap_function; - } - if(!co_active_handle) co_active_handle = &co_active_buffer; - size += 512; /* allocate additional space for storage */ - size &= ~15; /* align stack to 16-byte boundary */ - - if(handle = (cothread_t)malloc(size)) { - long long *p = (long long*)((char*)handle + size); /* seek to top of stack */ - *--p = (long long)crash; /* crash if entrypoint returns */ - *--p = (long long)entrypoint; /* start of function */ - *(long long*)handle = (long long)p; /* stack pointer */ - } - - return handle; -} - -void co_delete(cothread_t handle) { - free(handle); -} - -void co_switch(cothread_t handle) { - register cothread_t co_previous_handle = co_active_handle; - co_swap(co_active_handle = handle, co_previous_handle); -} - -#ifdef __cplusplus -} -#endif +/* +libco.amd64 (2016-09-14) +author: byuu +license: public domain +*/ + +#define LIBCO_C +#include "libco.h" + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + static long long co_active_buffer[64]; + static cothread_t co_active_handle = 0; + + static void* smalloc(size_t size) + { + char* ret = malloc(size + 16); + if (ret) + { + *(size_t*)ret = size; + return ret + 16; + } + return NULL; + } + + static void sfree(void* ptr) + { + char* original = (char*)ptr - 16; + size_t size = *(size_t*)original + 16; + memset(original, 0, size); + free(original); + } + + extern void co_swap(cothread_t, cothread_t); + + static void crash() { + assert(0); /* called only if cothread_t entrypoint returns */ + } + + void co_clean() { + memset(co_active_buffer, 0, sizeof(co_active_buffer)); + } + + cothread_t co_active() { + if (!co_active_handle) co_active_handle = &co_active_buffer; + return co_active_handle; + } + + cothread_t co_create(unsigned int size, void(*entrypoint)(void)) { + cothread_t handle; + if (!co_active_handle) co_active_handle = &co_active_buffer; + size += 512; /* allocate additional space for storage */ + size &= ~15; /* align stack to 16-byte boundary */ + + if (handle = (cothread_t)smalloc(size)) { + long long *p = (long long*)((char*)handle + size); /* seek to top of stack */ + *--p = (long long)crash; /* crash if entrypoint returns */ + *--p = (long long)entrypoint; /* start of function */ + *(long long*)handle = (long long)p; /* stack pointer */ + } + + return handle; + } + + void co_delete(cothread_t handle) { + sfree(handle); + } + + void co_switch(cothread_t handle) { + register cothread_t co_previous_handle = co_active_handle; + co_swap(co_active_handle = handle, co_previous_handle); + } + +#ifdef __cplusplus +} +#endif diff --git a/LibretroBridge/vs2015/libco/coswap.asm b/LibretroBridge/vs2015/libco/coswap.asm new file mode 100644 index 0000000000..7a43bb4350 --- /dev/null +++ b/LibretroBridge/vs2015/libco/coswap.asm @@ -0,0 +1,57 @@ +_TEXT SEGMENT + +PUBLIC co_swap +co_swap PROC + + mov [rdx],rsp + mov rsp,[rcx] + pop rax + mov [rdx+ 8],rbp + mov [rdx+16],rsi + mov [rdx+24],rdi + mov [rdx+32],rbx + mov [rdx+40],r12 + mov [rdx+48],r13 + mov [rdx+56],r14 + mov [rdx+64],r15 + + movaps [rdx+ 80],xmm6 + movaps [rdx+ 96],xmm7 + movaps [rdx+112],xmm8 + add rdx,112 + movaps [rdx+ 16],xmm9 + movaps [rdx+ 32],xmm10 + movaps [rdx+ 48],xmm11 + movaps [rdx+ 64],xmm12 + movaps [rdx+ 80],xmm13 + movaps [rdx+ 96],xmm14 + movaps [rdx+112],xmm15 + + mov rbp,[rcx+ 8] + mov rsi,[rcx+16] + mov rdi,[rcx+24] + mov rbx,[rcx+32] + mov r12,[rcx+40] + mov r13,[rcx+48] + mov r14,[rcx+56] + mov r15,[rcx+64] + + movaps xmm6, [rcx+ 80] + movaps xmm7, [rcx+ 96] + movaps xmm8, [rcx+112] + add rcx,112 + movaps xmm9, [rcx+ 16] + movaps xmm10,[rcx+ 32] + movaps xmm11,[rcx+ 48] + movaps xmm12,[rcx+ 64] + movaps xmm13,[rcx+ 80] + movaps xmm14,[rcx+ 96] + movaps xmm15,[rcx+112] + + jmp rax + +co_swap ENDP + +_TEXT ENDS + +END diff --git a/LibretroBridge/vs2015/libco/sjlj-multi.c b/LibretroBridge/vs2015/libco/sjlj-multi.c deleted file mode 100644 index 2ba14cfe84..0000000000 --- a/LibretroBridge/vs2015/libco/sjlj-multi.c +++ /dev/null @@ -1,237 +0,0 @@ -/* -original author: Nach -license: public domain - -additional work: zeromus -note: more ARM compilers are supported here (check the ifdefs in _JUMP_BUFFER) -and: work has been done to make this coexist more peaceably with .net -*/ - - - -#define LIBCO_C -#include "libco.h" -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct -{ - jmp_buf context; - coentry_t coentry; - void *stack; - unsigned long seh_frame, stack_top, stack_bottom; - cothread_t caller; - int ownstack; -} cothread_struct; - -static thread_local cothread_struct _co_primary; -static thread_local cothread_struct *co_running = 0; - -cothread_t co_primary() { return (cothread_t)&_co_primary; } - - -//------------------- -#ifdef _MSC_VER - -//links of interest -//http://connect.microsoft.com/VisualStudio/feedback/details/100319/really-wierd-behaviour-in-crt-io-coupled-with-some-inline-assembly -//http://en.wikipedia.org/wiki/Thread_Information_Block -//http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/72093e46-4524-4f54-9f36-c7e8a309d1db/ //FS warning - - -#define WINVER 0x0400 -#define _WIN32_WINNT 0x0400 -#define WIN32_LEAN_AND_MEAN -#include - -#pragma warning(disable:4733) -#pragma warning(disable:4311) - -static void capture_fs(cothread_struct* rec) -{ - int temp; - __asm mov eax, dword ptr fs:[0]; - __asm mov temp, eax; - rec->seh_frame = temp; - __asm mov eax, dword ptr fs:[4]; - __asm mov temp, eax; - rec->stack_top = temp; - __asm mov eax, dword ptr fs:[8]; - __asm mov temp, eax; - rec->stack_bottom = temp; -} - -static void restore_fs(cothread_struct* rec) -{ - int temp; - temp = rec->seh_frame; - __asm mov eax, temp; - __asm mov dword ptr fs:[0], eax - temp = rec->stack_top; - __asm mov eax, temp; - __asm mov dword ptr fs:[4], eax - temp = rec->stack_bottom; - __asm mov eax, temp; - __asm mov dword ptr fs:[8], eax -} - -static void os_co_wrapper() -{ - cothread_struct* rec = (cothread_struct*)co_active(); - __try - { - rec->coentry(); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - //unhandled win32 exception in coroutine. - //this coroutine will now be suspended permanently and control will be yielded to caller, for lack of anything better to do. - //perhaps the process should just terminate. - for(;;) - { - //dead coroutine - co_switch(rec->caller); - } - } -} - -static void os_co_create(cothread_struct* rec, unsigned int size, coentry_t coentry) -{ - _JUMP_BUFFER* jb = (_JUMP_BUFFER*)&rec->context; - cothread_struct temp; - - jb->Esp = (unsigned long)rec->stack + size - 4; - jb->Eip = (unsigned long)os_co_wrapper; - - rec->stack_top = jb->Esp + 4; - rec->stack_bottom = (unsigned long)rec->stack; - - //wild assumption about SEH frame.. seems to work - capture_fs(&temp); - rec->seh_frame = temp.seh_frame; -} - -static void os_pre_setjmp(cothread_t target) -{ - cothread_struct* rec = (cothread_struct*)target; - capture_fs(co_running); - rec->caller = co_running; -} - -static void os_pre_longjmp(cothread_struct* rec) -{ - restore_fs(rec); -} - -#elif defined(__ARM_EABI__) || defined(__ARMCC_VERSION) - -//http://sourceware.org/cgi-bin/cvsweb.cgi/src/newlib/libc/machine/arm/setjmp.S?rev=1.5&content-type=text/x-cvsweb-markup&cvsroot=src - -typedef struct -{ -#ifdef LIBCO_ARM_JUMBLED - int r8,r9,r10,r11,lr,r4,r5,r6,r7,sp; -#else - int r4,r5,r6,r7,r8,r9,r10,fp; - #ifndef LIBCO_ARM_NOIP - int ip; - #endif - int sp,lr; -#endif -} _JUMP_BUFFER; - -static void os_co_create(cothread_struct* rec, unsigned int size, coentry_t coentry) -{ - _JUMP_BUFFER* jb = (_JUMP_BUFFER*)&rec->context; - - jb->sp = (unsigned long)rec->stack + size - 4; - jb->lr = (unsigned long)coentry; -} - -static void os_pre_setjmp(cothread_t target) -{ - cothread_struct* rec = (cothread_struct*)target; - rec->caller = co_running; -} - -static void os_pre_longjmp(cothread_struct* rec) -{ -} - -#else -#error "sjlj-multi: unsupported processor, compiler or operating system" -#endif -//------------------- - -cothread_t co_active() -{ - if(!co_running) co_running = &_co_primary; - return (cothread_t)co_running; -} - -void* co_getstack(cothread_t cothread) -{ - return ((cothread_struct*)cothread)->stack; -} - -cothread_t co_create(unsigned int stacksize, coentry_t coentry) -{ - cothread_struct* ret = (cothread_struct*)co_create_withstack(malloc(stacksize), stacksize, coentry); - if(ret) - ret->ownstack = 1; - return (cothread_t)ret; -} - -cothread_t co_create_withstack(void* stack, int stacksize, coentry_t coentry) -{ - cothread_struct *thread; - - if(!co_running) co_running = &_co_primary; - - thread = (cothread_struct*)malloc(sizeof(cothread_struct)); - if(thread) - { - thread->coentry = coentry; - thread->stack = stack; - - { - setjmp(thread->context); - os_co_create(thread,stacksize,coentry); - } - thread->ownstack = 0; - } - - return (cothread_t)thread; -} - -void co_delete(cothread_t cothread) -{ - if(cothread) - { - cothread_struct* thread = (cothread_struct*)cothread; - if (thread->ownstack) - free(thread->stack); - free(cothread); - } -} - -void co_switch(cothread_t cothread) -{ - os_pre_setjmp(cothread); - if(!setjmp(co_running->context)) - { - co_running = (cothread_struct*)cothread; - os_pre_longjmp(co_running); - longjmp(co_running->context,0); - } -} - -#ifdef __cplusplus -} -#endif diff --git a/LibretroBridge/vs2015/libco/x86.c b/LibretroBridge/vs2015/libco/x86.c deleted file mode 100644 index ebfc239535..0000000000 --- a/LibretroBridge/vs2015/libco/x86.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - libco.x86 (2009-10-12) - author: byuu - license: public domain -*/ - -#define LIBCO_C -#include "libco.h" -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(_MSC_VER) - #define fastcall __fastcall -#elif defined(__GNUC__) - #define fastcall __attribute__((fastcall)) -#else - #error "libco: please define fastcall macro" -#endif - -static thread_local long co_active_buffer[64]; -static thread_local cothread_t co_active_handle = 0; -static void (fastcall *co_swap)(cothread_t, cothread_t) = 0; - -//ABI: fastcall -static unsigned char co_swap_function[] = { - 0x89, 0x22, /* mov [edx],esp */ - 0x8b, 0x21, /* mov esp,[ecx] */ - 0x58, /* pop eax */ - 0x89, 0x6a, 0x04, /* mov [edx+0x04],ebp */ - 0x89, 0x72, 0x08, /* mov [edx+0x08],esi */ - 0x89, 0x7a, 0x0c, /* mov [edx+0x0c],edi */ - 0x89, 0x5a, 0x10, /* mov [edx+0x10],ebx */ - 0x8b, 0x69, 0x04, /* mov ebp,[ecx+0x04] */ - 0x8b, 0x71, 0x08, /* mov esi,[ecx+0x08] */ - 0x8b, 0x79, 0x0c, /* mov edi,[ecx+0x0c] */ - 0x8b, 0x59, 0x10, /* mov ebx,[ecx+0x10] */ - 0xff, 0xe0, /* jmp eax */ -}; - -#ifdef _WIN32 -#include - -void co_init(void) -{ - DWORD old_privileges; - VirtualProtect(co_swap_function, - sizeof co_swap_function, PAGE_EXECUTE_READWRITE, &old_privileges); -} -#else -#include -#include - -void co_init(void) -{ - unsigned long addr = (unsigned long)co_swap_function; - unsigned long base = addr - (addr % sysconf(_SC_PAGESIZE)); - unsigned long size = (addr - base) + sizeof co_swap_function; - mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC); -} -#endif - -static void crash(void) -{ - assert(0); /* called only if cothread_t entrypoint returns */ -} - -cothread_t co_active(void) -{ - if(!co_active_handle) - co_active_handle = &co_active_buffer; - return co_active_handle; -} - -cothread_t co_create(unsigned int size, void (*entrypoint)(void)) -{ - cothread_t handle; - if(!co_swap) - { - co_init(); - co_swap = (void (fastcall*)(cothread_t, cothread_t))co_swap_function; - } - - if(!co_active_handle) - co_active_handle = &co_active_buffer; - - size += 256; /* allocate additional space for storage */ - size &= ~15; /* align stack to 16-byte boundary */ - - if((handle = (cothread_t)malloc(size))) - { - long *p = (long*)((char*)handle + size); /* seek to top of stack */ - *--p = (long)crash; /* crash if entrypoint returns */ - *--p = (long)entrypoint; /* start of function */ - *(long*)handle = (long)p; /* stack pointer */ - } - - return handle; -} - -void co_delete(cothread_t handle) -{ - free(handle); -} - -void co_switch(cothread_t handle) -{ - register cothread_t co_previous_handle = co_active_handle; - co_swap(co_active_handle = handle, co_previous_handle); -} - -#ifdef __cplusplus -} -#endif diff --git a/References/PeNet.dll b/References/PeNet.dll new file mode 100644 index 0000000000..0ba0982b04 Binary files /dev/null and b/References/PeNet.dll differ diff --git a/Version/VersionInfo.cs b/Version/VersionInfo.cs index 8db20bba6a..cbe25607eb 100644 --- a/Version/VersionInfo.cs +++ b/Version/VersionInfo.cs @@ -2,8 +2,8 @@ using System.IO; internal static class VersionInfo { - public const string Mainversion = "1.11.8"; // Use numbers only or the new version notification won't work - public static readonly string RELEASEDATE = "October 22, 2016"; + public const string Mainversion = "2.0.0"; // Use numbers only or the new version notification won't work + public static readonly string RELEASEDATE = "June 25, 2017"; public static readonly bool DeveloperBuild = true; public static readonly string HomePage = "http://tasvideos.org/BizHawk.html"; diff --git a/Version/version.csproj b/Version/version.csproj index 9fb30caa54..ad7e23f837 100644 --- a/Version/version.csproj +++ b/Version/version.csproj @@ -1,5 +1,5 @@  - + @@ -12,27 +12,9 @@ Library Version Version - v4.0 + v4.6.1 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - x86 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - x86 + true @@ -48,6 +30,7 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets false ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false bin\x64\Release\ @@ -65,6 +48,7 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules false false + false diff --git a/libgambatte/Makefile b/libgambatte/Makefile index 152f913d1d..33e7712716 100644 --- a/libgambatte/Makefile +++ b/libgambatte/Makefile @@ -4,7 +4,7 @@ CP = cp MACHINE = $(shell $(CXX) -dumpmachine) ifneq (,$(findstring i686,$(MACHINE))) - ARCH = 32 + $(error 32 bit build no longer supported) else ifneq (,$(findstring x86_64,$(MACHINE))) ARCH = 64 else @@ -18,7 +18,7 @@ LDFLAGS_64 = LDFLAGS = -shared $(LDFLAGS_$(ARCH)) $(CXXFLAGS) DEST_32 = ../output/dll -DEST_64 = ../output64/dll +DEST_64 = ../output/dll SRCS = \ src/cinterface.cpp \ diff --git a/libgambatte/include/gambatte.h b/libgambatte/include/gambatte.h index 43e56d5fb9..2265ffa6d9 100644 --- a/libgambatte/include/gambatte.h +++ b/libgambatte/include/gambatte.h @@ -60,7 +60,8 @@ public: * @param flags ORed combination of LoadFlags. * @return 0 on success, negative value on failure. */ - int load(const char *romfiledata, unsigned romfilelength, std::uint32_t now, unsigned flags = 0); + bool use_bios; + int load(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, std::uint32_t now, unsigned flags = 0); /** Emulates until at least 'samples' stereo sound samples are produced in the supplied buffer, * or until a video frame has been drawn. diff --git a/libgambatte/libgambatte.vcxproj b/libgambatte/libgambatte.vcxproj index a0a7b5eb34..4d34da2828 100644 --- a/libgambatte/libgambatte.vcxproj +++ b/libgambatte/libgambatte.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -28,23 +28,27 @@ DynamicLibrary true Unicode + v140 DynamicLibrary true Unicode + v140 DynamicLibrary false true Unicode + v140 DynamicLibrary false true Unicode + v140 @@ -107,7 +111,7 @@ true - copy /y $(TargetDir)$(TargetFileName) $(ProjectDir)..\output64\dll\$(TargetFileName) + copy /y $(TargetDir)$(TargetFileName) $(ProjectDir)..\output\dll\$(TargetFileName) @@ -151,7 +155,7 @@ true - copy /y $(TargetDir)$(TargetFileName) $(ProjectDir)..\output64\dll\$(TargetFileName) + copy /y $(TargetDir)$(TargetFileName) $(ProjectDir)..\output\dll\$(TargetFileName) diff --git a/libgambatte/src/cinterface.cpp b/libgambatte/src/cinterface.cpp index c224fdf725..6549307c85 100644 --- a/libgambatte/src/cinterface.cpp +++ b/libgambatte/src/cinterface.cpp @@ -29,9 +29,9 @@ GBEXPORT void gambatte_destroy(GB *g) delete g; } -GBEXPORT int gambatte_load(GB *g, const char *romfiledata, unsigned romfilelength, long long now, unsigned flags) +GBEXPORT int gambatte_load(GB *g, const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, long long now, unsigned flags) { - int ret = g->load(romfiledata, romfilelength, now, flags); + int ret = g->load(romfiledata, romfilelength, biosfiledata, biosfilelength, now, flags); return ret; } diff --git a/libgambatte/src/cpu.h b/libgambatte/src/cpu.h index 02fabe979e..1310257e86 100644 --- a/libgambatte/src/cpu.h +++ b/libgambatte/src/cpu.h @@ -1,132 +1,136 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef CPU_H -#define CPU_H - -#include "memory.h" +/*************************************************************************** + * Copyright (C) 2007 by Sindre Aamås * + * aamas@stud.ntnu.no * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License version 2 as * + * published by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License version 2 for more details. * + * * + * You should have received a copy of the GNU General Public License * + * version 2 along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef CPU_H +#define CPU_H + +#include "memory.h" #include "newstate.h" - -namespace gambatte { - -class CPU { - Memory memory; - - unsigned long cycleCounter_; - - unsigned short PC; - unsigned short SP; - - unsigned HF1, HF2, ZF, CF; - - unsigned char A, B, C, D, E, /*F,*/ H, L; - - bool skip; - - void process(unsigned long cycles); - - void (*tracecallback)(void *); - -public: - - CPU(); -// void halt(); - -// unsigned interrupt(unsigned address, unsigned cycleCounter); - - long runFor(unsigned long cycles); - void setStatePtrs(SaveState &state); - void loadState(const SaveState &state); - void setLayers(unsigned mask) { memory.setLayers(mask); } - - void loadSavedata(const char *data) { memory.loadSavedata(data); } - int saveSavedataLength() {return memory.saveSavedataLength(); } - void saveSavedata(char *dest) { memory.saveSavedata(dest); } - - bool getMemoryArea(int which, unsigned char **data, int *length) { return memory.getMemoryArea(which, data, length); } - - void setVideoBuffer(uint_least32_t *const videoBuf, const int pitch) { - memory.setVideoBuffer(videoBuf, pitch); - } - - void setInputGetter(unsigned (*getInput)()) { - memory.setInputGetter(getInput); - } - - void setReadCallback(void (*callback)(unsigned)) { - memory.setReadCallback(callback); - } - - void setWriteCallback(void (*callback)(unsigned)) { - memory.setWriteCallback(callback); - } - - void setExecCallback(void (*callback)(unsigned)) { - memory.setExecCallback(callback); - } - - void setCDCallback(CDCallback cdc) { - memory.setCDCallback(cdc); - } - - void setTraceCallback(void (*callback)(void *)) { - tracecallback = callback; - } - - void setScanlineCallback(void (*callback)(), int sl) { - memory.setScanlineCallback(callback, sl); - } - - void setRTCCallback(std::uint32_t (*callback)()) { - memory.setRTCCallback(callback); - } - - int load(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat) { - return memory.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat); - } - - bool loaded() const { return memory.loaded(); } - const char * romTitle() const { return memory.romTitle(); } - - void setSoundBuffer(uint_least32_t *const buf) { memory.setSoundBuffer(buf); } - unsigned fillSoundBuffer() { return memory.fillSoundBuffer(cycleCounter_); } - - bool isCgb() const { return memory.isCgb(); } - - void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32) { - memory.setDmgPaletteColor(palNum, colorNum, rgb32); - } - - void setCgbPalette(unsigned *lut) { - memory.setCgbPalette(lut); - } - - //unsigned char ExternalRead(unsigned short addr) { return memory.read(addr, cycleCounter_); } - unsigned char ExternalRead(unsigned short addr) { return memory.peek(addr); } - void ExternalWrite(unsigned short addr, unsigned char val) { memory.write_nocb(addr, val, cycleCounter_); } - - int LinkStatus(int which) { return memory.LinkStatus(which); } - - void GetRegs(int *dest); - + +namespace gambatte { + +class CPU { + Memory memory; + + unsigned long cycleCounter_; + + unsigned short PC; + unsigned short SP; + + unsigned HF1, HF2, ZF, CF; + + unsigned char A, B, C, D, E, /*F,*/ H, L; + + bool skip; + + void process(unsigned long cycles); + + void (*tracecallback)(void *); + +public: + + CPU(); +// void halt(); + +// unsigned interrupt(unsigned address, unsigned cycleCounter); + + long runFor(unsigned long cycles); + void setStatePtrs(SaveState &state); + void loadState(const SaveState &state); + void setLayers(unsigned mask) { memory.setLayers(mask); } + + void loadSavedata(const char *data) { memory.loadSavedata(data); } + int saveSavedataLength() {return memory.saveSavedataLength(); } + void saveSavedata(char *dest) { memory.saveSavedata(dest); } + + bool getMemoryArea(int which, unsigned char **data, int *length) { return memory.getMemoryArea(which, data, length); } + + void setVideoBuffer(uint_least32_t *const videoBuf, const int pitch) { + memory.setVideoBuffer(videoBuf, pitch); + } + + void setInputGetter(unsigned (*getInput)()) { + memory.setInputGetter(getInput); + } + + void setReadCallback(void (*callback)(unsigned)) { + memory.setReadCallback(callback); + } + + void setWriteCallback(void (*callback)(unsigned)) { + memory.setWriteCallback(callback); + } + + void setExecCallback(void (*callback)(unsigned)) { + memory.setExecCallback(callback); + } + + void setCDCallback(CDCallback cdc) { + memory.setCDCallback(cdc); + } + + void setTraceCallback(void (*callback)(void *)) { + tracecallback = callback; + } + + void setScanlineCallback(void (*callback)(), int sl) { + memory.setScanlineCallback(callback, sl); + } + + void setRTCCallback(std::uint32_t (*callback)()) { + memory.setRTCCallback(callback); + } + + void reset_bios(int setting) { + memory.bios_reset(setting); + } + + int load(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, bool forceDmg, bool multicartCompat) { + return memory.loadROM(romfiledata, romfilelength, biosfiledata, biosfilelength, forceDmg, multicartCompat); + } + + bool loaded() const { return memory.loaded(); } + const char * romTitle() const { return memory.romTitle(); } + + void setSoundBuffer(uint_least32_t *const buf) { memory.setSoundBuffer(buf); } + unsigned fillSoundBuffer() { return memory.fillSoundBuffer(cycleCounter_); } + + bool isCgb() const { return memory.isCgb(); } + + void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32) { + memory.setDmgPaletteColor(palNum, colorNum, rgb32); + } + + void setCgbPalette(unsigned *lut) { + memory.setCgbPalette(lut); + } + + //unsigned char ExternalRead(unsigned short addr) { return memory.read(addr, cycleCounter_); } + unsigned char ExternalRead(unsigned short addr) { return memory.peek(addr); } + void ExternalWrite(unsigned short addr, unsigned char val) { memory.write_nocb(addr, val, cycleCounter_); } + + int LinkStatus(int which) { return memory.LinkStatus(which); } + + void GetRegs(int *dest); + templatevoid SyncState(NewState *ns); -}; - -} - -#endif +}; + +} + +#endif diff --git a/libgambatte/src/gambatte.cpp b/libgambatte/src/gambatte.cpp index d56632d8f5..c3843a862c 100644 --- a/libgambatte/src/gambatte.cpp +++ b/libgambatte/src/gambatte.cpp @@ -94,7 +94,12 @@ void GB::reset(const std::uint32_t now) { SaveState state; p_->cpu.setStatePtrs(state); - setInitState(state, p_->cpu.isCgb(), p_->gbaCgbMode, now); + if (use_bios) + { + p_->cpu.reset_bios(0); + } + + setInitState(state, p_->cpu.isCgb(), p_->gbaCgbMode, now, use_bios); p_->cpu.loadState(state); if (length > 0) { @@ -136,16 +141,17 @@ void GB::setRTCCallback(std::uint32_t (*callback)()) { p_->cpu.setRTCCallback(callback); } -int GB::load(const char *romfiledata, unsigned romfilelength, const std::uint32_t now, const unsigned flags) { +int GB::load(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, const std::uint32_t now, const unsigned flags) { //if (p_->cpu.loaded()) // p_->cpu.saveSavedata(); - const int failed = p_->cpu.load(romfiledata, romfilelength, flags & FORCE_DMG, flags & MULTICART_COMPAT); + const int failed = p_->cpu.load(romfiledata, romfilelength, biosfiledata, biosfilelength, flags & FORCE_DMG, flags & MULTICART_COMPAT); + use_bios = biosfilelength > 0 ? true : false; if (!failed) { SaveState state; p_->cpu.setStatePtrs(state); - setInitState(state, p_->cpu.isCgb(), p_->gbaCgbMode = flags & GBA_CGB, now); + setInitState(state, p_->cpu.isCgb(), p_->gbaCgbMode = flags & GBA_CGB, now, use_bios); p_->cpu.loadState(state); //p_->cpu.loadSavedata(); } @@ -228,6 +234,7 @@ SYNCFUNC(GB) SSS(p_->cpu); NSS(p_->gbaCgbMode); NSS(p_->vbuff); + NSS(use_bios); } } diff --git a/libgambatte/src/initstate.cpp b/libgambatte/src/initstate.cpp index 6430061789..74bf322b4f 100644 --- a/libgambatte/src/initstate.cpp +++ b/libgambatte/src/initstate.cpp @@ -1146,7 +1146,7 @@ static void setInitialDmgIoamhram(unsigned char *const ioamhram) { } // anon namespace -void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbMode, const std::uint32_t now) { +void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbMode, const std::uint32_t now, bool boot_bios) { static const unsigned char cgbObjpDump[0x40] = { 0x00, 0x00, 0xF2, 0xAB, 0x61, 0xC2, 0xD9, 0xBA, @@ -1166,35 +1166,66 @@ void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbM 0x83, 0x40, 0x0B, 0x77 }; - state.cpu.cycleCounter = cgb ? 0x102A0 : 0x102A0 + 0x8D2C; - state.cpu.PC = 0x100; - state.cpu.SP = 0xFFFE; - state.cpu.A = cgb * 0x10 | 0x01; - state.cpu.B = cgb & gbaCgbMode; - state.cpu.C = 0x13; - state.cpu.D = 0x00; - state.cpu.E = 0xD8; - state.cpu.F = 0xB0; - state.cpu.H = 0x01; - state.cpu.L = 0x4D; - state.cpu.skip = false; + if (boot_bios) + { + state.cpu.PC = 0x00; + state.cpu.SP = 0xFFFF; + state.cpu.A = 0; + state.cpu.B = 0; + state.cpu.C = 0x0; + state.cpu.D = 0x0; + state.cpu.E = 0x0; + state.cpu.F = 0x0; + state.cpu.H = 0x0; + state.cpu.L = 0x0; + state.cpu.skip = false; + state.cpu.cycleCounter = 0; + state.mem.ioamhram.ptr[0x140] = 0x00; + state.mem.ioamhram.ptr[0x104] = 0x00; + state.mem.using_bios = true; + } + else + { + state.cpu.PC = 0x100; + state.cpu.SP = 0xFFFE; + state.cpu.A = cgb * 0x10 | 0x01; + state.cpu.B = cgb & gbaCgbMode; + state.cpu.C = 0x13; + state.cpu.D = 0x00; + state.cpu.E = 0xD8; + state.cpu.F = 0xB0; + state.cpu.H = 0x01; + state.cpu.L = 0x4D; + state.cpu.skip = false; + setInitialVram(state.mem.vram.ptr, cgb); + state.cpu.cycleCounter = cgb ? 0x102A0 : 0x102A0 + 0x8D2C; + } std::memset(state.mem.sram.ptr, 0xFF, state.mem.sram.getSz()); - setInitialVram(state.mem.vram.ptr, cgb); + if (cgb) { setInitialCgbWram(state.mem.wram.ptr); - setInitialCgbIoamhram(state.mem.ioamhram.ptr); } else { setInitialDmgWram(state.mem.wram.ptr); - setInitialDmgIoamhram(state.mem.ioamhram.ptr); } - state.mem.ioamhram.ptr[0x104] = 0x1C; - state.mem.ioamhram.ptr[0x140] = 0x91; - state.mem.ioamhram.ptr[0x144] = 0x00; - + if (!boot_bios) + { + if (cgb) { + setInitialCgbIoamhram(state.mem.ioamhram.ptr); + } + else { + setInitialDmgIoamhram(state.mem.ioamhram.ptr); + } + + + state.mem.ioamhram.ptr[0x140] = 0x91; + state.mem.ioamhram.ptr[0x104] = 0x1C; + state.mem.ioamhram.ptr[0x144] = 0x00; + } + state.mem.divLastUpdate = 0; state.mem.timaLastUpdate = 0; state.mem.tmatime = DISABLED_TIME; @@ -1258,7 +1289,6 @@ void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbM state.ppu.oldWy = state.mem.ioamhram.get()[0x14A]; state.ppu.pendingLcdstatIrq = false; - state.spu.cycleCounter = 0x1000 | (state.cpu.cycleCounter >> 1 & 0xFFF); // spu.cycleCounter >> 12 & 7 represents the frame sequencer position. state.spu.ch1.sweep.counter = SoundUnit::COUNTER_DISABLED; diff --git a/libgambatte/src/initstate.h b/libgambatte/src/initstate.h index 8d8ed5aaf6..ec56fae045 100644 --- a/libgambatte/src/initstate.h +++ b/libgambatte/src/initstate.h @@ -22,7 +22,7 @@ #include namespace gambatte { -void setInitState(struct SaveState &state, bool cgb, bool gbaCgbMode, std::uint32_t now); +void setInitState(struct SaveState &state, bool cgb, bool gbaCgbMode, std::uint32_t now, bool boot_bios); } #endif diff --git a/libgambatte/src/mem/cartridge.cpp b/libgambatte/src/mem/cartridge.cpp index b8b642f4c4..cf5c06afc1 100644 --- a/libgambatte/src/mem/cartridge.cpp +++ b/libgambatte/src/mem/cartridge.cpp @@ -1,152 +1,153 @@ -/*************************************************************************** - * Copyright (C) 2007-2010 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "cartridge.h" -#include "../savestate.h" -#include -#include -#include - -namespace gambatte { - -namespace { - -static unsigned toMulti64Rombank(const unsigned rombank) { - return (rombank >> 1 & 0x30) | (rombank & 0xF); -} - -class DefaultMbc : public Mbc { -public: - virtual bool isAddressWithinAreaRombankCanBeMappedTo(unsigned addr, unsigned bank) const { - return (addr< 0x4000) == (bank == 0); - } +/*************************************************************************** + * Copyright (C) 2007-2010 by Sindre Aamås * + * aamas@stud.ntnu.no * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License version 2 as * + * published by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License version 2 for more details. * + * * + * You should have received a copy of the GNU General Public License * + * version 2 along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "cartridge.h" +#include "../savestate.h" +#include +#include +#include +#include + +namespace gambatte { + +namespace { + +static unsigned toMulti64Rombank(const unsigned rombank) { + return (rombank >> 1 & 0x30) | (rombank & 0xF); +} + +class DefaultMbc : public Mbc { +public: + virtual bool isAddressWithinAreaRombankCanBeMappedTo(unsigned addr, unsigned bank) const { + return (addr< 0x4000) == (bank == 0); + } virtual void SyncState(NewState *ns, bool isReader) { - } -}; - -class Mbc0 : public DefaultMbc { - MemPtrs &memptrs; - bool enableRam; - -public: - explicit Mbc0(MemPtrs &memptrs) - : memptrs(memptrs), - enableRam(false) - { - } - - virtual void romWrite(const unsigned P, const unsigned data) { - if (P < 0x2000) { - enableRam = (data & 0xF) == 0xA; - memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0, 0); - } - } - - virtual void saveState(SaveState::Mem &ss) const { - ss.enableRam = enableRam; - } - - virtual void loadState(const SaveState::Mem &ss) { - enableRam = ss.enableRam; - memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0, 0); - } - + } +}; + +class Mbc0 : public DefaultMbc { + MemPtrs &memptrs; + bool enableRam; + +public: + explicit Mbc0(MemPtrs &memptrs) + : memptrs(memptrs), + enableRam(false) + { + } + + virtual void romWrite(const unsigned P, const unsigned data) { + if (P < 0x2000) { + enableRam = (data & 0xF) == 0xA; + memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0, 0); + } + } + + virtual void saveState(SaveState::Mem &ss) const { + ss.enableRam = enableRam; + } + + virtual void loadState(const SaveState::Mem &ss) { + enableRam = ss.enableRam; + memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0, 0); + } + virtual void SyncState(NewState *ns, bool isReader) { NSS(enableRam); } -}; - -static inline unsigned rambanks(const MemPtrs &memptrs) { - return static_cast(memptrs.rambankdataend() - memptrs.rambankdata()) / 0x2000; -} - -static inline unsigned rombanks(const MemPtrs &memptrs) { - return static_cast(memptrs.romdataend() - memptrs.romdata() ) / 0x4000; -} - -class Mbc1 : public DefaultMbc { - MemPtrs &memptrs; - unsigned char rombank; - unsigned char rambank; - bool enableRam; - bool rambankMode; - - static unsigned adjustedRombank(unsigned bank) { return bank & 0x1F ? bank : bank | 1; } - void setRambank() const { memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0, rambank & (rambanks(memptrs) - 1)); } - void setRombank() const { memptrs.setRombank(adjustedRombank(rombank & (rombanks(memptrs) - 1))); } - -public: - explicit Mbc1(MemPtrs &memptrs) - : memptrs(memptrs), - rombank(1), - rambank(0), - enableRam(false), - rambankMode(false) - { - } - - virtual void romWrite(const unsigned P, const unsigned data) { - switch (P >> 13 & 3) { - case 0: - enableRam = (data & 0xF) == 0xA; - setRambank(); - break; - case 1: - rombank = rambankMode ? data & 0x1F : (rombank & 0x60) | (data & 0x1F); - setRombank(); - break; - case 2: - if (rambankMode) { - rambank = data & 3; - setRambank(); - } else { - rombank = (data << 5 & 0x60) | (rombank & 0x1F); - setRombank(); - } - - break; - case 3: - // Pretty sure this should take effect immediately, but I have a policy not to change old behavior - // unless I have something (eg. a verified test or a game) that justifies it. - rambankMode = data & 1; - break; - } - } - - virtual void saveState(SaveState::Mem &ss) const { - ss.rombank = rombank; - ss.rambank = rambank; - ss.enableRam = enableRam; - ss.rambankMode = rambankMode; - } - - virtual void loadState(const SaveState::Mem &ss) { - rombank = ss.rombank; - rambank = ss.rambank; - enableRam = ss.enableRam; - rambankMode = ss.rambankMode; - setRambank(); - setRombank(); - } - +}; + +static inline unsigned rambanks(const MemPtrs &memptrs) { + return static_cast(memptrs.rambankdataend() - memptrs.rambankdata()) / 0x2000; +} + +static inline unsigned rombanks(const MemPtrs &memptrs) { + return static_cast(memptrs.romdataend() - memptrs.romdata() ) / 0x4000; +} + +class Mbc1 : public DefaultMbc { + MemPtrs &memptrs; + unsigned char rombank; + unsigned char rambank; + bool enableRam; + bool rambankMode; + + static unsigned adjustedRombank(unsigned bank) { return bank & 0x1F ? bank : bank | 1; } + void setRambank() const { memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0, rambank & (rambanks(memptrs) - 1)); } + void setRombank() const { memptrs.setRombank(adjustedRombank(rombank & (rombanks(memptrs) - 1))); } + +public: + explicit Mbc1(MemPtrs &memptrs) + : memptrs(memptrs), + rombank(1), + rambank(0), + enableRam(false), + rambankMode(false) + { + } + + virtual void romWrite(const unsigned P, const unsigned data) { + switch (P >> 13 & 3) { + case 0: + enableRam = (data & 0xF) == 0xA; + setRambank(); + break; + case 1: + rombank = rambankMode ? data & 0x1F : (rombank & 0x60) | (data & 0x1F); + setRombank(); + break; + case 2: + if (rambankMode) { + rambank = data & 3; + setRambank(); + } else { + rombank = (data << 5 & 0x60) | (rombank & 0x1F); + setRombank(); + } + + break; + case 3: + // Pretty sure this should take effect immediately, but I have a policy not to change old behavior + // unless I have something (eg. a verified test or a game) that justifies it. + rambankMode = data & 1; + break; + } + } + + virtual void saveState(SaveState::Mem &ss) const { + ss.rombank = rombank; + ss.rambank = rambank; + ss.enableRam = enableRam; + ss.rambankMode = rambankMode; + } + + virtual void loadState(const SaveState::Mem &ss) { + rombank = ss.rombank; + rambank = ss.rambank; + enableRam = ss.enableRam; + rambankMode = ss.rambankMode; + setRambank(); + setRombank(); + } + virtual void SyncState(NewState *ns, bool isReader) { NSS(rombank); @@ -154,267 +155,267 @@ public: NSS(enableRam); NSS(rambankMode); } -}; - -class Mbc1Multi64 : public Mbc { - MemPtrs &memptrs; - unsigned char rombank; - bool enableRam; - bool rombank0Mode; - - static unsigned adjustedRombank(unsigned bank) { return bank & 0x1F ? bank : bank | 1; } - - void setRombank() const { - if (rombank0Mode) { - const unsigned rb = toMulti64Rombank(rombank); - memptrs.setRombank0(rb & 0x30); - memptrs.setRombank(adjustedRombank(rb)); - } else { - memptrs.setRombank0(0); - memptrs.setRombank(adjustedRombank(rombank & (rombanks(memptrs) - 1))); - } - } - -public: - explicit Mbc1Multi64(MemPtrs &memptrs) - : memptrs(memptrs), - rombank(1), - enableRam(false), - rombank0Mode(false) - { - } - - virtual void romWrite(const unsigned P, const unsigned data) { - switch (P >> 13 & 3) { - case 0: - enableRam = (data & 0xF) == 0xA; - memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0, 0); - break; - case 1: - rombank = (rombank & 0x60) | (data & 0x1F); - memptrs.setRombank(adjustedRombank(rombank0Mode ? toMulti64Rombank(rombank) : rombank & (rombanks(memptrs) - 1))); - break; - case 2: - rombank = (data << 5 & 0x60) | (rombank & 0x1F); - setRombank(); - break; - case 3: - rombank0Mode = data & 1; - setRombank(); - break; - } - } - - virtual void saveState(SaveState::Mem &ss) const { - ss.rombank = rombank; - ss.enableRam = enableRam; - ss.rambankMode = rombank0Mode; - } - - virtual void loadState(const SaveState::Mem &ss) { - rombank = ss.rombank; - enableRam = ss.enableRam; - rombank0Mode = ss.rambankMode; - memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0, 0); - setRombank(); - } - - virtual bool isAddressWithinAreaRombankCanBeMappedTo(unsigned addr, unsigned bank) const { - return (addr < 0x4000) == ((bank & 0xF) == 0); - } - +}; + +class Mbc1Multi64 : public Mbc { + MemPtrs &memptrs; + unsigned char rombank; + bool enableRam; + bool rombank0Mode; + + static unsigned adjustedRombank(unsigned bank) { return bank & 0x1F ? bank : bank | 1; } + + void setRombank() const { + if (rombank0Mode) { + const unsigned rb = toMulti64Rombank(rombank); + memptrs.setRombank0(rb & 0x30); + memptrs.setRombank(adjustedRombank(rb)); + } else { + memptrs.setRombank0(0); + memptrs.setRombank(adjustedRombank(rombank & (rombanks(memptrs) - 1))); + } + } + +public: + explicit Mbc1Multi64(MemPtrs &memptrs) + : memptrs(memptrs), + rombank(1), + enableRam(false), + rombank0Mode(false) + { + } + + virtual void romWrite(const unsigned P, const unsigned data) { + switch (P >> 13 & 3) { + case 0: + enableRam = (data & 0xF) == 0xA; + memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0, 0); + break; + case 1: + rombank = (rombank & 0x60) | (data & 0x1F); + memptrs.setRombank(adjustedRombank(rombank0Mode ? toMulti64Rombank(rombank) : rombank & (rombanks(memptrs) - 1))); + break; + case 2: + rombank = (data << 5 & 0x60) | (rombank & 0x1F); + setRombank(); + break; + case 3: + rombank0Mode = data & 1; + setRombank(); + break; + } + } + + virtual void saveState(SaveState::Mem &ss) const { + ss.rombank = rombank; + ss.enableRam = enableRam; + ss.rambankMode = rombank0Mode; + } + + virtual void loadState(const SaveState::Mem &ss) { + rombank = ss.rombank; + enableRam = ss.enableRam; + rombank0Mode = ss.rambankMode; + memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0, 0); + setRombank(); + } + + virtual bool isAddressWithinAreaRombankCanBeMappedTo(unsigned addr, unsigned bank) const { + return (addr < 0x4000) == ((bank & 0xF) == 0); + } + virtual void SyncState(NewState *ns, bool isReader) { NSS(rombank); NSS(enableRam); NSS(rombank0Mode); } -}; - -class Mbc2 : public DefaultMbc { - MemPtrs &memptrs; - unsigned char rombank; - bool enableRam; - -public: - explicit Mbc2(MemPtrs &memptrs) - : memptrs(memptrs), - rombank(1), - enableRam(false) - { - } - - virtual void romWrite(const unsigned P, const unsigned data) { - switch (P & 0x6100) { - case 0x0000: - enableRam = (data & 0xF) == 0xA; - memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0, 0); - break; - case 0x2100: - rombank = data & 0xF; - memptrs.setRombank(rombank & (rombanks(memptrs) - 1)); - break; - } - } - - virtual void saveState(SaveState::Mem &ss) const { - ss.rombank = rombank; - ss.enableRam = enableRam; - } - - virtual void loadState(const SaveState::Mem &ss) { - rombank = ss.rombank; - enableRam = ss.enableRam; - memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0, 0); - memptrs.setRombank(rombank & (rombanks(memptrs) - 1)); - } - +}; + +class Mbc2 : public DefaultMbc { + MemPtrs &memptrs; + unsigned char rombank; + bool enableRam; + +public: + explicit Mbc2(MemPtrs &memptrs) + : memptrs(memptrs), + rombank(1), + enableRam(false) + { + } + + virtual void romWrite(const unsigned P, const unsigned data) { + switch (P & 0x6100) { + case 0x0000: + enableRam = (data & 0xF) == 0xA; + memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0, 0); + break; + case 0x2100: + rombank = data & 0xF; + memptrs.setRombank(rombank & (rombanks(memptrs) - 1)); + break; + } + } + + virtual void saveState(SaveState::Mem &ss) const { + ss.rombank = rombank; + ss.enableRam = enableRam; + } + + virtual void loadState(const SaveState::Mem &ss) { + rombank = ss.rombank; + enableRam = ss.enableRam; + memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0, 0); + memptrs.setRombank(rombank & (rombanks(memptrs) - 1)); + } + virtual void SyncState(NewState *ns, bool isReader) { NSS(rombank); NSS(enableRam); } -}; - -class Mbc3 : public DefaultMbc { - MemPtrs &memptrs; - Rtc *const rtc; - unsigned char rombank; - unsigned char rambank; - bool enableRam; - - static unsigned adjustedRombank(unsigned bank) { return bank & 0x7F ? bank : bank | 1; } - void setRambank() const { - unsigned flags = enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0; - - if (rtc) { - rtc->set(enableRam, rambank); - - if (rtc->getActive()) - flags |= MemPtrs::RTC_EN; - } - - memptrs.setRambank(flags, rambank & (rambanks(memptrs) - 1)); - } - // we adjust the rombank before masking with size? this seems correct, as how would the mbc - // know that high rom address outputs were not connected - void setRombank() const { memptrs.setRombank(adjustedRombank(rombank) & (rombanks(memptrs) - 1)); } - -public: - Mbc3(MemPtrs &memptrs, Rtc *const rtc) - : memptrs(memptrs), - rtc(rtc), - rombank(1), - rambank(0), - enableRam(false) - { - } - - virtual void romWrite(const unsigned P, const unsigned data) { - switch (P >> 13 & 3) { - case 0: - enableRam = (data & 0xF) == 0xA; - setRambank(); - break; - case 1: - rombank = data & 0x7F; - setRombank(); - break; - case 2: - rambank = data; - setRambank(); - break; - case 3: - if (rtc) - rtc->latch(data); - - break; - } - } - - virtual void saveState(SaveState::Mem &ss) const { - ss.rombank = rombank; - ss.rambank = rambank; - ss.enableRam = enableRam; - } - - virtual void loadState(const SaveState::Mem &ss) { - rombank = ss.rombank; - rambank = ss.rambank; - enableRam = ss.enableRam; - setRambank(); - setRombank(); - } - +}; + +class Mbc3 : public DefaultMbc { + MemPtrs &memptrs; + Rtc *const rtc; + unsigned char rombank; + unsigned char rambank; + bool enableRam; + + static unsigned adjustedRombank(unsigned bank) { return bank & 0x7F ? bank : bank | 1; } + void setRambank() const { + unsigned flags = enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0; + + if (rtc) { + rtc->set(enableRam, rambank); + + if (rtc->getActive()) + flags |= MemPtrs::RTC_EN; + } + + memptrs.setRambank(flags, rambank & (rambanks(memptrs) - 1)); + } + // we adjust the rombank before masking with size? this seems correct, as how would the mbc + // know that high rom address outputs were not connected + void setRombank() const { memptrs.setRombank(adjustedRombank(rombank) & (rombanks(memptrs) - 1)); } + +public: + Mbc3(MemPtrs &memptrs, Rtc *const rtc) + : memptrs(memptrs), + rtc(rtc), + rombank(1), + rambank(0), + enableRam(false) + { + } + + virtual void romWrite(const unsigned P, const unsigned data) { + switch (P >> 13 & 3) { + case 0: + enableRam = (data & 0xF) == 0xA; + setRambank(); + break; + case 1: + rombank = data & 0x7F; + setRombank(); + break; + case 2: + rambank = data; + setRambank(); + break; + case 3: + if (rtc) + rtc->latch(data); + + break; + } + } + + virtual void saveState(SaveState::Mem &ss) const { + ss.rombank = rombank; + ss.rambank = rambank; + ss.enableRam = enableRam; + } + + virtual void loadState(const SaveState::Mem &ss) { + rombank = ss.rombank; + rambank = ss.rambank; + enableRam = ss.enableRam; + setRambank(); + setRombank(); + } + virtual void SyncState(NewState *ns, bool isReader) { NSS(rombank); NSS(rambank); NSS(enableRam); } -}; - -class HuC1 : public DefaultMbc { - MemPtrs &memptrs; - unsigned char rombank; - unsigned char rambank; - bool enableRam; - bool rambankMode; - - void setRambank() const { - memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : MemPtrs::READ_EN, - rambankMode ? rambank & (rambanks(memptrs) - 1) : 0); - } - - void setRombank() const { memptrs.setRombank((rambankMode ? rombank : rambank << 6 | rombank) & (rombanks(memptrs) - 1)); } - -public: - explicit HuC1(MemPtrs &memptrs) - : memptrs(memptrs), - rombank(1), - rambank(0), - enableRam(false), - rambankMode(false) - { - } - - virtual void romWrite(const unsigned P, const unsigned data) { - switch (P >> 13 & 3) { - case 0: - enableRam = (data & 0xF) == 0xA; - setRambank(); - break; - case 1: - rombank = data & 0x3F; - setRombank(); - break; - case 2: - rambank = data & 3; - rambankMode ? setRambank() : setRombank(); - break; - case 3: - rambankMode = data & 1; - setRambank(); - setRombank(); - break; - } - } - - virtual void saveState(SaveState::Mem &ss) const { - ss.rombank = rombank; - ss.rambank = rambank; - ss.enableRam = enableRam; - ss.rambankMode = rambankMode; - } - - virtual void loadState(const SaveState::Mem &ss) { - rombank = ss.rombank; - rambank = ss.rambank; - enableRam = ss.enableRam; - rambankMode = ss.rambankMode; - setRambank(); - setRombank(); - } +}; + +class HuC1 : public DefaultMbc { + MemPtrs &memptrs; + unsigned char rombank; + unsigned char rambank; + bool enableRam; + bool rambankMode; + + void setRambank() const { + memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : MemPtrs::READ_EN, + rambankMode ? rambank & (rambanks(memptrs) - 1) : 0); + } + + void setRombank() const { memptrs.setRombank((rambankMode ? rombank : rambank << 6 | rombank) & (rombanks(memptrs) - 1)); } + +public: + explicit HuC1(MemPtrs &memptrs) + : memptrs(memptrs), + rombank(1), + rambank(0), + enableRam(false), + rambankMode(false) + { + } + + virtual void romWrite(const unsigned P, const unsigned data) { + switch (P >> 13 & 3) { + case 0: + enableRam = (data & 0xF) == 0xA; + setRambank(); + break; + case 1: + rombank = data & 0x3F; + setRombank(); + break; + case 2: + rambank = data & 3; + rambankMode ? setRambank() : setRombank(); + break; + case 3: + rambankMode = data & 1; + setRambank(); + setRombank(); + break; + } + } + + virtual void saveState(SaveState::Mem &ss) const { + ss.rombank = rombank; + ss.rambank = rambank; + ss.enableRam = enableRam; + ss.rambankMode = rambankMode; + } + + virtual void loadState(const SaveState::Mem &ss) { + rombank = ss.rombank; + rambank = ss.rambank; + enableRam = ss.enableRam; + rambankMode = ss.rambankMode; + setRambank(); + setRombank(); + } virtual void SyncState(NewState *ns, bool isReader) { @@ -423,327 +424,374 @@ public: NSS(enableRam); NSS(rambankMode); } -}; - -class Mbc5 : public DefaultMbc { - MemPtrs &memptrs; - unsigned short rombank; - unsigned char rambank; - bool enableRam; - - static unsigned adjustedRombank(const unsigned bank) { return bank; } - void setRambank() const { memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0, rambank & (rambanks(memptrs) - 1)); } - void setRombank() const { memptrs.setRombank(adjustedRombank(rombank & (rombanks(memptrs) - 1))); } - -public: - explicit Mbc5(MemPtrs &memptrs) - : memptrs(memptrs), - rombank(1), - rambank(0), - enableRam(false) - { - } - - virtual void romWrite(const unsigned P, const unsigned data) { - switch (P >> 13 & 3) { - case 0: - enableRam = (data & 0xF) == 0xA; - setRambank(); - break; - case 1: - rombank = P < 0x3000 ? (rombank & 0x100) | data - : (data << 8 & 0x100) | (rombank & 0xFF); - setRombank(); - break; - case 2: - rambank = data & 0xF; - setRambank(); - break; - case 3: - break; - } - } - - virtual void saveState(SaveState::Mem &ss) const { - ss.rombank = rombank; - ss.rambank = rambank; - ss.enableRam = enableRam; - } - - virtual void loadState(const SaveState::Mem &ss) { - rombank = ss.rombank; - rambank = ss.rambank; - enableRam = ss.enableRam; - setRambank(); - setRombank(); - } - +}; + +class Mbc5 : public DefaultMbc { + MemPtrs &memptrs; + unsigned short rombank; + unsigned char rambank; + bool enableRam; + + static unsigned adjustedRombank(const unsigned bank) { return bank; } + void setRambank() const { memptrs.setRambank(enableRam ? MemPtrs::READ_EN | MemPtrs::WRITE_EN : 0, rambank & (rambanks(memptrs) - 1)); } + void setRombank() const { memptrs.setRombank(adjustedRombank(rombank & (rombanks(memptrs) - 1))); } + +public: + explicit Mbc5(MemPtrs &memptrs) + : memptrs(memptrs), + rombank(1), + rambank(0), + enableRam(false) + { + } + + virtual void romWrite(const unsigned P, const unsigned data) { + switch (P >> 13 & 3) { + case 0: + enableRam = (data & 0xF) == 0xA; + setRambank(); + break; + case 1: + rombank = P < 0x3000 ? (rombank & 0x100) | data + : (data << 8 & 0x100) | (rombank & 0xFF); + setRombank(); + break; + case 2: + rambank = data & 0xF; + setRambank(); + break; + case 3: + break; + } + } + + virtual void saveState(SaveState::Mem &ss) const { + ss.rombank = rombank; + ss.rambank = rambank; + ss.enableRam = enableRam; + } + + virtual void loadState(const SaveState::Mem &ss) { + rombank = ss.rombank; + rambank = ss.rambank; + enableRam = ss.enableRam; + setRambank(); + setRombank(); + } + virtual void SyncState(NewState *ns, bool isReader) { NSS(rombank); NSS(rambank); NSS(enableRam); } -}; - -static bool hasRtc(const unsigned headerByte0x147) { - switch (headerByte0x147) { - case 0x0F: - case 0x10: return true; - default: return false; - } -} - -} - -void Cartridge::setStatePtrs(SaveState &state) { - state.mem.vram.set(memptrs.vramdata(), memptrs.vramdataend() - memptrs.vramdata()); - state.mem.sram.set(memptrs.rambankdata(), memptrs.rambankdataend() - memptrs.rambankdata()); - state.mem.wram.set(memptrs.wramdata(0), memptrs.wramdataend() - memptrs.wramdata(0)); -} - -void Cartridge::loadState(const SaveState &state) { - rtc.loadState(state); - mbc->loadState(state.mem); -} - -static void enforce8bit(unsigned char *data, unsigned long sz) { - if (static_cast(0x100)) - while (sz--) - *data++ &= 0xFF; -} - -static unsigned pow2ceil(unsigned n) { - --n; - n |= n >> 1; - n |= n >> 2; - n |= n >> 4; - n |= n >> 8; - ++n; - - return n; -} - -int Cartridge::loadROM(const char *romfiledata, unsigned romfilelength, const bool forceDmg, const bool multicartCompat) { - //const std::auto_ptr rom(newFileInstance(romfile)); - - //if (rom->fail()) - // return -1; - - unsigned rambanks = 1; - unsigned rombanks = 2; - bool cgb = false; - enum Cartridgetype { PLAIN, MBC1, MBC2, MBC3, MBC5, HUC1 } type = PLAIN; - - { - unsigned char header[0x150]; - //rom->read(reinterpret_cast(header), sizeof header); - if (romfilelength >= sizeof header) - std::memcpy(header, romfiledata, sizeof header); - else - return -1; - - switch (header[0x0147]) { - case 0x00: std::puts("Plain ROM loaded."); type = PLAIN; break; - case 0x01: std::puts("MBC1 ROM loaded."); type = MBC1; break; - case 0x02: std::puts("MBC1 ROM+RAM loaded."); type = MBC1; break; - case 0x03: std::puts("MBC1 ROM+RAM+BATTERY loaded."); type = MBC1; break; - case 0x05: std::puts("MBC2 ROM loaded."); type = MBC2; break; - case 0x06: std::puts("MBC2 ROM+BATTERY loaded."); type = MBC2; break; - case 0x08: std::puts("Plain ROM with additional RAM loaded."); type = PLAIN; break; - case 0x09: std::puts("Plain ROM with additional RAM and Battery loaded."); type = PLAIN; break; - case 0x0B: std::puts("MM01 ROM not supported."); return -1; - case 0x0C: std::puts("MM01 ROM not supported."); return -1; - case 0x0D: std::puts("MM01 ROM not supported."); return -1; - case 0x0F: std::puts("MBC3 ROM+TIMER+BATTERY loaded."); type = MBC3; break; - case 0x10: std::puts("MBC3 ROM+TIMER+RAM+BATTERY loaded."); type = MBC3; break; - case 0x11: std::puts("MBC3 ROM loaded."); type = MBC3; break; - case 0x12: std::puts("MBC3 ROM+RAM loaded."); type = MBC3; break; - case 0x13: std::puts("MBC3 ROM+RAM+BATTERY loaded."); type = MBC3; break; - case 0x15: std::puts("MBC4 ROM not supported."); return -1; - case 0x16: std::puts("MBC4 ROM not supported."); return -1; - case 0x17: std::puts("MBC4 ROM not supported."); return -1; - case 0x19: std::puts("MBC5 ROM loaded."); type = MBC5; break; - case 0x1A: std::puts("MBC5 ROM+RAM loaded."); type = MBC5; break; - case 0x1B: std::puts("MBC5 ROM+RAM+BATTERY loaded."); type = MBC5; break; - case 0x1C: std::puts("MBC5+RUMBLE ROM not supported."); type = MBC5; break; - case 0x1D: std::puts("MBC5+RUMBLE+RAM ROM not suported."); type = MBC5; break; - case 0x1E: std::puts("MBC5+RUMBLE+RAM+BATTERY ROM not supported."); type = MBC5; break; - case 0xFC: std::puts("Pocket Camera ROM not supported."); return -1; - case 0xFD: std::puts("Bandai TAMA5 ROM not supported."); return -1; - case 0xFE: std::puts("HuC3 ROM not supported."); return -1; - case 0xFF: std::puts("HuC1 ROM+RAM+BATTERY loaded."); type = HUC1; break; - default: std::puts("Wrong data-format, corrupt or unsupported ROM."); return -1; - } - - /*switch (header[0x0148]) { - case 0x00: rombanks = 2; break; - case 0x01: rombanks = 4; break; - case 0x02: rombanks = 8; break; - case 0x03: rombanks = 16; break; - case 0x04: rombanks = 32; break; - case 0x05: rombanks = 64; break; - case 0x06: rombanks = 128; break; - case 0x07: rombanks = 256; break; - case 0x08: rombanks = 512; break; - case 0x52: rombanks = 72; break; - case 0x53: rombanks = 80; break; - case 0x54: rombanks = 96; break; - default: return -1; - } - - std::printf("rombanks: %u\n", rombanks);*/ - - switch (header[0x0149]) { - case 0x00: /*std::puts("No RAM");*/ rambanks = type == MBC2; break; - case 0x01: /*std::puts("2kB RAM");*/ /*rambankrom=1; break;*/ - case 0x02: /*std::puts("8kB RAM");*/ - rambanks = 1; - break; - case 0x03: /*std::puts("32kB RAM");*/ - rambanks = 4; - break; - case 0x04: /*std::puts("128kB RAM");*/ - rambanks = 16; - break; - case 0x05: /*std::puts("undocumented kB RAM");*/ - rambanks = 16; - break; - default: /*std::puts("Wrong data-format, corrupt or unsupported ROM loaded.");*/ - rambanks = 16; - break; - } - - cgb = header[0x0143] >> 7 & (1 ^ forceDmg); - std::printf("cgb: %d\n", cgb); - } - - std::printf("rambanks: %u\n", rambanks); - - const std::size_t filesize = romfilelength; //rom->size(); - rombanks = std::max(pow2ceil(filesize / 0x4000), 2u); - std::printf("rombanks: %u\n", static_cast(filesize / 0x4000)); - - mbc.reset(); - memptrs.reset(rombanks, rambanks, cgb ? 8 : 2); - rtc.set(false, 0); - - //rom->rewind(); - //rom->read(reinterpret_cast(memptrs.romdata()), (filesize / 0x4000) * 0x4000ul); - std::memcpy(memptrs.romdata(), romfiledata, (filesize / 0x4000) * 0x4000ul); - std::memset(memptrs.romdata() + (filesize / 0x4000) * 0x4000ul, 0xFF, (rombanks - filesize / 0x4000) * 0x4000ul); - enforce8bit(memptrs.romdata(), rombanks * 0x4000ul); - - //if (rom->fail()) - // return -1; - - switch (type) { - case PLAIN: mbc.reset(new Mbc0(memptrs)); break; - case MBC1: - if (!rambanks && rombanks == 64 && multicartCompat) { - std::puts("Multi-ROM \"MBC1\" presumed"); - mbc.reset(new Mbc1Multi64(memptrs)); - } else - mbc.reset(new Mbc1(memptrs)); - - break; - case MBC2: mbc.reset(new Mbc2(memptrs)); break; - case MBC3: mbc.reset(new Mbc3(memptrs, hasRtc(memptrs.romdata()[0x147]) ? &rtc : 0)); break; - case MBC5: mbc.reset(new Mbc5(memptrs)); break; - case HUC1: mbc.reset(new HuC1(memptrs)); break; - } - - return 0; -} - -static bool hasBattery(const unsigned char headerByte0x147) { - switch (headerByte0x147) { - case 0x03: - case 0x06: - case 0x09: - case 0x0F: - case 0x10: - case 0x13: - case 0x1B: - case 0x1E: - case 0xFF: return true; - default: return false; - } -} - -void Cartridge::loadSavedata(const char *data) { - if (hasBattery(memptrs.romdata()[0x147])) { - int length = memptrs.rambankdataend() - memptrs.rambankdata(); - std::memcpy(memptrs.rambankdata(), data, length); - data += length; - enforce8bit(memptrs.rambankdata(), length); - } - - if (hasRtc(memptrs.romdata()[0x147])) { - unsigned long basetime; - std::memcpy(&basetime, data, 4); - rtc.setBaseTime(basetime); - } -} - -int Cartridge::saveSavedataLength() { - int ret = 0; - if (hasBattery(memptrs.romdata()[0x147])) { - ret = memptrs.rambankdataend() - memptrs.rambankdata(); - } - if (hasRtc(memptrs.romdata()[0x147])) { - ret += 4; - } - return ret; -} - -void Cartridge::saveSavedata(char *dest) { - if (hasBattery(memptrs.romdata()[0x147])) { - int length = memptrs.rambankdataend() - memptrs.rambankdata(); - std::memcpy(dest, memptrs.rambankdata(), length); - dest += length; - } - - if (hasRtc(memptrs.romdata()[0x147])) { - const unsigned long basetime = rtc.getBaseTime(); - std::memcpy(dest, &basetime, 4); - } -} - -bool Cartridge::getMemoryArea(int which, unsigned char **data, int *length) const { - if (!data || !length) - return false; - - switch (which) - { - case 0: - *data = memptrs.vramdata(); - *length = memptrs.vramdataend() - memptrs.vramdata(); - return true; - case 1: - *data = memptrs.romdata(); - *length = memptrs.romdataend() - memptrs.romdata(); - return true; - case 2: - *data = memptrs.wramdata(0); - *length = memptrs.wramdataend() - memptrs.wramdata(0); - return true; - case 3: - *data = memptrs.rambankdata(); - *length = memptrs.rambankdataend() - memptrs.rambankdata(); - return true; - - default: - return false; - } - return false; -} - +}; + +static bool hasRtc(const unsigned headerByte0x147) { + switch (headerByte0x147) { + case 0x0F: + case 0x10: return true; + default: return false; + } +} + +} + +void Cartridge::setStatePtrs(SaveState &state) { + state.mem.vram.set(memptrs.vramdata(), memptrs.vramdataend() - memptrs.vramdata()); + state.mem.sram.set(memptrs.rambankdata(), memptrs.rambankdataend() - memptrs.rambankdata()); + state.mem.wram.set(memptrs.wramdata(0), memptrs.wramdataend() - memptrs.wramdata(0)); +} + +void Cartridge::loadState(const SaveState &state) { + rtc.loadState(state); + mbc->loadState(state.mem); +} + +static void enforce8bit(unsigned char *data, unsigned long sz) { + if (static_cast(0x100)) + while (sz--) + *data++ &= 0xFF; +} + +static unsigned pow2ceil(unsigned n) { + --n; + n |= n >> 1; + n |= n >> 2; + n |= n >> 4; + n |= n >> 8; + ++n; + + return n; +} + +void Cartridge::bios_remap(int setting) { + // disable the BIOS if writing 1 or 0x22 (GBC) + if (setting == 1 || setting == 0x11) { + std::memcpy(memptrs.romdata(), memptrs.notbiosdata_, loc_bios_length); + using_bios = false; + } + + // we'll also use it to reset to BIOS on reset + if (setting == 0) { + std::memcpy(memptrs.romdata(), memptrs.biosdata_, loc_bios_length); + using_bios = true; + } +} + +int Cartridge::loadROM(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, const bool forceDmg, const bool multicartCompat) { + //const std::auto_ptr rom(newFileInstance(romfile)); + + //if (rom->fail()) + // return -1; + + unsigned rambanks = 1; + unsigned rombanks = 2; + bool cgb = false; + enum Cartridgetype { PLAIN, MBC1, MBC2, MBC3, MBC5, HUC1 } type = PLAIN; + + { + unsigned char header[0x150]; + //rom->read(reinterpret_cast(header), sizeof header); + if (romfilelength >= sizeof header) + std::memcpy(header, romfiledata, sizeof header); + else + return -1; + + switch (header[0x0147]) { + case 0x00: std::puts("Plain ROM loaded."); type = PLAIN; break; + case 0x01: std::puts("MBC1 ROM loaded."); type = MBC1; break; + case 0x02: std::puts("MBC1 ROM+RAM loaded."); type = MBC1; break; + case 0x03: std::puts("MBC1 ROM+RAM+BATTERY loaded."); type = MBC1; break; + case 0x05: std::puts("MBC2 ROM loaded."); type = MBC2; break; + case 0x06: std::puts("MBC2 ROM+BATTERY loaded."); type = MBC2; break; + case 0x08: std::puts("Plain ROM with additional RAM loaded."); type = PLAIN; break; + case 0x09: std::puts("Plain ROM with additional RAM and Battery loaded."); type = PLAIN; break; + case 0x0B: std::puts("MM01 ROM not supported."); return -1; + case 0x0C: std::puts("MM01 ROM not supported."); return -1; + case 0x0D: std::puts("MM01 ROM not supported."); return -1; + case 0x0F: std::puts("MBC3 ROM+TIMER+BATTERY loaded."); type = MBC3; break; + case 0x10: std::puts("MBC3 ROM+TIMER+RAM+BATTERY loaded."); type = MBC3; break; + case 0x11: std::puts("MBC3 ROM loaded."); type = MBC3; break; + case 0x12: std::puts("MBC3 ROM+RAM loaded."); type = MBC3; break; + case 0x13: std::puts("MBC3 ROM+RAM+BATTERY loaded."); type = MBC3; break; + case 0x15: std::puts("MBC4 ROM not supported."); return -1; + case 0x16: std::puts("MBC4 ROM not supported."); return -1; + case 0x17: std::puts("MBC4 ROM not supported."); return -1; + case 0x19: std::puts("MBC5 ROM loaded."); type = MBC5; break; + case 0x1A: std::puts("MBC5 ROM+RAM loaded."); type = MBC5; break; + case 0x1B: std::puts("MBC5 ROM+RAM+BATTERY loaded."); type = MBC5; break; + case 0x1C: std::puts("MBC5+RUMBLE ROM not supported."); type = MBC5; break; + case 0x1D: std::puts("MBC5+RUMBLE+RAM ROM not suported."); type = MBC5; break; + case 0x1E: std::puts("MBC5+RUMBLE+RAM+BATTERY ROM not supported."); type = MBC5; break; + case 0xFC: std::puts("Pocket Camera ROM not supported."); return -1; + case 0xFD: std::puts("Bandai TAMA5 ROM not supported."); return -1; + case 0xFE: std::puts("HuC3 ROM not supported."); return -1; + case 0xFF: std::puts("HuC1 ROM+RAM+BATTERY loaded."); type = HUC1; break; + default: std::puts("Wrong data-format, corrupt or unsupported ROM."); return -1; + } + + /*switch (header[0x0148]) { + case 0x00: rombanks = 2; break; + case 0x01: rombanks = 4; break; + case 0x02: rombanks = 8; break; + case 0x03: rombanks = 16; break; + case 0x04: rombanks = 32; break; + case 0x05: rombanks = 64; break; + case 0x06: rombanks = 128; break; + case 0x07: rombanks = 256; break; + case 0x08: rombanks = 512; break; + case 0x52: rombanks = 72; break; + case 0x53: rombanks = 80; break; + case 0x54: rombanks = 96; break; + default: return -1; + } + + std::printf("rombanks: %u\n", rombanks);*/ + + switch (header[0x0149]) { + case 0x00: /*std::puts("No RAM");*/ rambanks = type == MBC2; break; + case 0x01: /*std::puts("2kB RAM");*/ /*rambankrom=1; break;*/ + case 0x02: /*std::puts("8kB RAM");*/ + rambanks = 1; + break; + case 0x03: /*std::puts("32kB RAM");*/ + rambanks = 4; + break; + case 0x04: /*std::puts("128kB RAM");*/ + rambanks = 16; + break; + case 0x05: /*std::puts("undocumented kB RAM");*/ + rambanks = 16; + break; + default: /*std::puts("Wrong data-format, corrupt or unsupported ROM loaded.");*/ + rambanks = 16; + break; + } + + cgb = header[0x0143] >> 7 & (1 ^ forceDmg); + std::printf("cgb: %d\n", cgb); + } + + std::printf("rambanks: %u\n", rambanks); + + const std::size_t filesize = romfilelength; //rom->size(); + rombanks = std::max(pow2ceil(filesize / 0x4000), 2u); + std::printf("rombanks: %u\n", static_cast(filesize / 0x4000)); + + mbc.reset(); + + use_bios = biosfilelength > 0 ? true : false; + loc_bios_length = biosfilelength; + + memptrs.reset(rombanks, rambanks, cgb ? 8 : 2); + rtc.set(false, 0); + + //rom->rewind(); + //rom->read(reinterpret_cast(memptrs.romdata()), (filesize / 0x4000) * 0x4000ul); + + std::memcpy(memptrs.romdata(), romfiledata, (filesize / 0x4000) * 0x4000ul); + std::memset(memptrs.romdata() + (filesize / 0x4000) * 0x4000ul, 0xFF, (rombanks - filesize / 0x4000) * 0x4000ul); + enforce8bit(memptrs.romdata(), rombanks * 0x4000ul); + + //we want to copy in the bios data only if it exists + if (use_bios) { + using_bios = true; + memptrs.use_bios = true; + + memptrs.biosdata_ = new unsigned char[biosfilelength]; + memptrs.notbiosdata_ = new unsigned char[biosfilelength]; + + std::memcpy(memptrs.biosdata_, biosfiledata, biosfilelength); + std::memcpy(memptrs.notbiosdata_, romfiledata, biosfilelength); + + //if using GBC, the header is not overwritten by the BIOS + if (biosfilelength > 256) { + std::memcpy(memptrs.biosdata_ + 256, memptrs.notbiosdata_ + 256, 256); + } + + + std::memcpy(memptrs.romdata(), memptrs.biosdata_, biosfilelength); + } + + //if (rom->fail()) + // return -1; + + switch (type) { + case PLAIN: mbc.reset(new Mbc0(memptrs)); break; + case MBC1: + if (!rambanks && rombanks == 64 && multicartCompat) { + std::puts("Multi-ROM \"MBC1\" presumed"); + mbc.reset(new Mbc1Multi64(memptrs)); + } else + mbc.reset(new Mbc1(memptrs)); + + break; + case MBC2: mbc.reset(new Mbc2(memptrs)); break; + case MBC3: mbc.reset(new Mbc3(memptrs, hasRtc(memptrs.romdata()[0x147]) ? &rtc : 0)); break; + case MBC5: mbc.reset(new Mbc5(memptrs)); break; + case HUC1: mbc.reset(new HuC1(memptrs)); break; + } + + return 0; +} + +static bool hasBattery(const unsigned char headerByte0x147) { + switch (headerByte0x147) { + case 0x03: + case 0x06: + case 0x09: + case 0x0F: + case 0x10: + case 0x13: + case 0x1B: + case 0x1E: + case 0xFF: return true; + default: return false; + } +} + +void Cartridge::loadSavedata(const char *data) { + if (hasBattery(memptrs.romdata()[0x147])) { + int length = memptrs.rambankdataend() - memptrs.rambankdata(); + std::memcpy(memptrs.rambankdata(), data, length); + data += length; + enforce8bit(memptrs.rambankdata(), length); + } + + if (hasRtc(memptrs.romdata()[0x147])) { + unsigned long basetime; + std::memcpy(&basetime, data, 4); + rtc.setBaseTime(basetime); + } +} + +int Cartridge::saveSavedataLength() { + int ret = 0; + if (hasBattery(memptrs.romdata()[0x147])) { + ret = memptrs.rambankdataend() - memptrs.rambankdata(); + } + if (hasRtc(memptrs.romdata()[0x147])) { + ret += 4; + } + return ret; +} + +void Cartridge::saveSavedata(char *dest) { + if (hasBattery(memptrs.romdata()[0x147])) { + int length = memptrs.rambankdataend() - memptrs.rambankdata(); + std::memcpy(dest, memptrs.rambankdata(), length); + dest += length; + } + + if (hasRtc(memptrs.romdata()[0x147])) { + const unsigned long basetime = rtc.getBaseTime(); + std::memcpy(dest, &basetime, 4); + } +} + +bool Cartridge::getMemoryArea(int which, unsigned char **data, int *length) const { + if (!data || !length) + return false; + + switch (which) + { + case 0: + *data = memptrs.vramdata(); + *length = memptrs.vramdataend() - memptrs.vramdata(); + return true; + case 1: + *data = memptrs.romdata(); + *length = memptrs.romdataend() - memptrs.romdata(); + return true; + case 2: + *data = memptrs.wramdata(0); + *length = memptrs.wramdataend() - memptrs.wramdata(0); + return true; + case 3: + *data = memptrs.rambankdata(); + *length = memptrs.rambankdataend() - memptrs.rambankdata(); + return true; + + default: + return false; + } + return false; +} + SYNCFUNC(Cartridge) { SSS(memptrs); SSS(rtc); TSS(mbc); + NSS(using_bios); + + if (using_bios) { + bios_remap(0); + } + else { + bios_remap(1); + } +} + } - -} diff --git a/libgambatte/src/mem/cartridge.h b/libgambatte/src/mem/cartridge.h index 54f694df31..c3a3d7ce27 100644 --- a/libgambatte/src/mem/cartridge.h +++ b/libgambatte/src/mem/cartridge.h @@ -66,6 +66,10 @@ class Cartridge { public: void setStatePtrs(SaveState &); void loadState(const SaveState &); + + bool use_bios; + bool using_bios; + unsigned loc_bios_length; bool loaded() const { return mbc.get(); } @@ -97,13 +101,15 @@ public: bool getMemoryArea(int which, unsigned char **data, int *length) const; - int loadROM(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat); + int loadROM(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, bool forceDmg, bool multicartCompat); const char * romTitle() const { return reinterpret_cast(memptrs.romdata() + 0x134); } void setRTCCallback(std::uint32_t (*callback)()) { rtc.setRTCCallback(callback); } + void bios_remap(int setting); + templatevoid SyncState(NewState *ns); }; diff --git a/libgambatte/src/mem/memptrs.cpp b/libgambatte/src/mem/memptrs.cpp index 6e8b2fe644..4ddf5e0149 100644 --- a/libgambatte/src/mem/memptrs.cpp +++ b/libgambatte/src/mem/memptrs.cpp @@ -1,151 +1,162 @@ -/*************************************************************************** - * Copyright (C) 2007-2010 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "memptrs.h" -#include -#include - -namespace gambatte { - -MemPtrs::MemPtrs() -: rmem_(), wmem_(), romdata_(), wramdata_(), vrambankptr_(0), rsrambankptr_(0), - wsrambankptr_(0), memchunk_(0), rambankdata_(0), wramdataend_(0), oamDmaSrc_(OAM_DMA_SRC_OFF), - memchunk_len(0) -{ -} - -MemPtrs::~MemPtrs() { - delete []memchunk_; -} - -void MemPtrs::reset(const unsigned rombanks, const unsigned rambanks, const unsigned wrambanks) { - delete []memchunk_; - memchunk_len = 0x4000 + rombanks * 0x4000ul + 0x4000 + rambanks * 0x2000ul + wrambanks * 0x1000ul + 0x4000; - memchunk_ = new unsigned char[memchunk_len]; - - romdata_[0] = romdata(); - rambankdata_ = romdata_[0] + rombanks * 0x4000ul + 0x4000; - wramdata_[0] = rambankdata_ + rambanks * 0x2000ul; - wramdataend_ = wramdata_[0] + wrambanks * 0x1000ul; - - std::memset(rdisabledRamw(), 0xFF, 0x2000); - - oamDmaSrc_ = OAM_DMA_SRC_OFF; - rmem_[0x3] = rmem_[0x2] = rmem_[0x1] = rmem_[0x0] = romdata_[0]; - rmem_[0xC] = wmem_[0xC] = wramdata_[0] - 0xC000; - rmem_[0xE] = wmem_[0xE] = wramdata_[0] - 0xE000; - setRombank(1); - setRambank(0, 0); - setVrambank(0); - setWrambank(1); - - // we save only the ram areas - memchunk_saveoffs = vramdata() - memchunk_; - memchunk_savelen = wramdataend() - memchunk_ - memchunk_saveoffs; -} - -void MemPtrs::setRombank0(const unsigned bank) { - romdata_[0] = romdata() + bank * 0x4000ul; - rmem_[0x3] = rmem_[0x2] = rmem_[0x1] = rmem_[0x0] = romdata_[0]; - disconnectOamDmaAreas(); -} - -void MemPtrs::setRombank(const unsigned bank) { - romdata_[1] = romdata() + bank * 0x4000ul - 0x4000; - rmem_[0x7] = rmem_[0x6] = rmem_[0x5] = rmem_[0x4] = romdata_[1]; - disconnectOamDmaAreas(); -} - -void MemPtrs::setRambank(const unsigned flags, const unsigned rambank) { - unsigned char *const srambankptr = flags & RTC_EN - ? 0 - : (rambankdata() != rambankdataend() - ? rambankdata_ + rambank * 0x2000ul - 0xA000 : wdisabledRam() - 0xA000); - - rsrambankptr_ = (flags & READ_EN) && srambankptr != wdisabledRam() - 0xA000 ? srambankptr : rdisabledRamw() - 0xA000; - wsrambankptr_ = flags & WRITE_EN ? srambankptr : wdisabledRam() - 0xA000; - rmem_[0xB] = rmem_[0xA] = rsrambankptr_; - wmem_[0xB] = wmem_[0xA] = wsrambankptr_; - disconnectOamDmaAreas(); -} - -void MemPtrs::setWrambank(const unsigned bank) { - wramdata_[1] = wramdata_[0] + ((bank & 0x07) ? (bank & 0x07) : 1) * 0x1000; - rmem_[0xD] = wmem_[0xD] = wramdata_[1] - 0xD000; - disconnectOamDmaAreas(); -} - -void MemPtrs::setOamDmaSrc(const OamDmaSrc oamDmaSrc) { - rmem_[0x3] = rmem_[0x2] = rmem_[0x1] = rmem_[0x0] = romdata_[0]; - rmem_[0x7] = rmem_[0x6] = rmem_[0x5] = rmem_[0x4] = romdata_[1]; - rmem_[0xB] = rmem_[0xA] = rsrambankptr_; - wmem_[0xB] = wmem_[0xA] = wsrambankptr_; - rmem_[0xC] = wmem_[0xC] = wramdata_[0] - 0xC000; - rmem_[0xD] = wmem_[0xD] = wramdata_[1] - 0xD000; - rmem_[0xE] = wmem_[0xE] = wramdata_[0] - 0xE000; - - oamDmaSrc_ = oamDmaSrc; - disconnectOamDmaAreas(); -} - -void MemPtrs::disconnectOamDmaAreas() { - if (isCgb(*this)) { - switch (oamDmaSrc_) { - case OAM_DMA_SRC_ROM: // fall through - case OAM_DMA_SRC_SRAM: - case OAM_DMA_SRC_INVALID: - std::fill(rmem_, rmem_ + 8, static_cast(0)); - rmem_[0xB] = rmem_[0xA] = 0; - wmem_[0xB] = wmem_[0xA] = 0; - break; - case OAM_DMA_SRC_VRAM: - break; - case OAM_DMA_SRC_WRAM: - rmem_[0xE] = rmem_[0xD] = rmem_[0xC] = 0; - wmem_[0xE] = wmem_[0xD] = wmem_[0xC] = 0; - break; - case OAM_DMA_SRC_OFF: - break; - } - } else { - switch (oamDmaSrc_) { - case OAM_DMA_SRC_ROM: // fall through - case OAM_DMA_SRC_SRAM: - case OAM_DMA_SRC_WRAM: - case OAM_DMA_SRC_INVALID: - std::fill(rmem_, rmem_ + 8, static_cast(0)); - rmem_[0xB] = rmem_[0xA] = 0; - wmem_[0xB] = wmem_[0xA] = 0; - rmem_[0xE] = rmem_[0xD] = rmem_[0xC] = 0; - wmem_[0xE] = wmem_[0xD] = wmem_[0xC] = 0; - break; - case OAM_DMA_SRC_VRAM: - break; - case OAM_DMA_SRC_OFF: - break; - } - } -} - -// all pointers here are relative to memchunk_ -#define MSS(a) RSS(a,memchunk_) -#define MSL(a) RSL(a,memchunk_) - +/*************************************************************************** + * Copyright (C) 2007-2010 by Sindre Aamås * + * aamas@stud.ntnu.no * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License version 2 as * + * published by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License version 2 for more details. * + * * + * You should have received a copy of the GNU General Public License * + * version 2 along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "memptrs.h" +#include +#include + +namespace gambatte { + +MemPtrs::MemPtrs() +: rmem_(), wmem_(), romdata_(), wramdata_(), vrambankptr_(0), rsrambankptr_(0), + wsrambankptr_(0), memchunk_(0), rambankdata_(0), wramdataend_(0), oamDmaSrc_(OAM_DMA_SRC_OFF), + memchunk_len(0) +{ +} + +MemPtrs::~MemPtrs() { + delete []memchunk_; + if (use_bios) + { + delete[]biosdata_; + delete[]notbiosdata_; + } +} + +void MemPtrs::reset(const unsigned rombanks, const unsigned rambanks, const unsigned wrambanks) { + delete []memchunk_; + + memchunk_len = 0x4000 + rombanks * 0x4000ul + 0x4000 + rambanks * 0x2000ul + wrambanks * 0x1000ul + 0x4000; + memchunk_ = new unsigned char[memchunk_len]; + + romdata_[0] = romdata(); + + rambankdata_ = romdata_[0] + rombanks * 0x4000ul + 0x4000; + wramdata_[0] = rambankdata_ + rambanks * 0x2000ul; + wramdataend_ = wramdata_[0] + wrambanks * 0x1000ul; + + std::memset(rdisabledRamw(), 0xFF, 0x2000); + + oamDmaSrc_ = OAM_DMA_SRC_OFF; + rmem_[0x3] = rmem_[0x2] = rmem_[0x1] = rmem_[0x0] = romdata_[0]; + rmem_[0xC] = wmem_[0xC] = wramdata_[0] - 0xC000; + rmem_[0xE] = wmem_[0xE] = wramdata_[0] - 0xE000; + setRombank(1); + setRambank(0, 0); + setVrambank(0); + setWrambank(1); + + // we save only the ram areas + memchunk_saveoffs = vramdata() - memchunk_; + memchunk_savelen = wramdataend() - memchunk_ - memchunk_saveoffs; +} + +void MemPtrs::setRombank0(const unsigned bank) { + + romdata_[0] = romdata() + bank * 0x4000ul; + + rmem_[0x3] = rmem_[0x2] = rmem_[0x1] = rmem_[0x0] = romdata_[0]; + disconnectOamDmaAreas(); +} + +void MemPtrs::setRombank(const unsigned bank) { + + romdata_[1] = romdata() + bank * 0x4000ul - 0x4000; + + rmem_[0x7] = rmem_[0x6] = rmem_[0x5] = rmem_[0x4] = romdata_[1]; + disconnectOamDmaAreas(); +} + +void MemPtrs::setRambank(const unsigned flags, const unsigned rambank) { + unsigned char *const srambankptr = flags & RTC_EN + ? 0 + : (rambankdata() != rambankdataend() + ? rambankdata_ + rambank * 0x2000ul - 0xA000 : wdisabledRam() - 0xA000); + + rsrambankptr_ = (flags & READ_EN) && srambankptr != wdisabledRam() - 0xA000 ? srambankptr : rdisabledRamw() - 0xA000; + wsrambankptr_ = flags & WRITE_EN ? srambankptr : wdisabledRam() - 0xA000; + rmem_[0xB] = rmem_[0xA] = rsrambankptr_; + wmem_[0xB] = wmem_[0xA] = wsrambankptr_; + disconnectOamDmaAreas(); +} + +void MemPtrs::setWrambank(const unsigned bank) { + wramdata_[1] = wramdata_[0] + ((bank & 0x07) ? (bank & 0x07) : 1) * 0x1000; + rmem_[0xD] = wmem_[0xD] = wramdata_[1] - 0xD000; + disconnectOamDmaAreas(); +} + +void MemPtrs::setOamDmaSrc(const OamDmaSrc oamDmaSrc) { + rmem_[0x3] = rmem_[0x2] = rmem_[0x1] = rmem_[0x0] = romdata_[0]; + rmem_[0x7] = rmem_[0x6] = rmem_[0x5] = rmem_[0x4] = romdata_[1]; + rmem_[0xB] = rmem_[0xA] = rsrambankptr_; + wmem_[0xB] = wmem_[0xA] = wsrambankptr_; + rmem_[0xC] = wmem_[0xC] = wramdata_[0] - 0xC000; + rmem_[0xD] = wmem_[0xD] = wramdata_[1] - 0xD000; + rmem_[0xE] = wmem_[0xE] = wramdata_[0] - 0xE000; + + oamDmaSrc_ = oamDmaSrc; + disconnectOamDmaAreas(); +} + +void MemPtrs::disconnectOamDmaAreas() { + if (isCgb(*this)) { + switch (oamDmaSrc_) { + case OAM_DMA_SRC_ROM: // fall through + case OAM_DMA_SRC_SRAM: + case OAM_DMA_SRC_INVALID: + std::fill(rmem_, rmem_ + 8, static_cast(0)); + rmem_[0xB] = rmem_[0xA] = 0; + wmem_[0xB] = wmem_[0xA] = 0; + break; + case OAM_DMA_SRC_VRAM: + break; + case OAM_DMA_SRC_WRAM: + rmem_[0xE] = rmem_[0xD] = rmem_[0xC] = 0; + wmem_[0xE] = wmem_[0xD] = wmem_[0xC] = 0; + break; + case OAM_DMA_SRC_OFF: + break; + } + } else { + switch (oamDmaSrc_) { + case OAM_DMA_SRC_ROM: // fall through + case OAM_DMA_SRC_SRAM: + case OAM_DMA_SRC_WRAM: + case OAM_DMA_SRC_INVALID: + std::fill(rmem_, rmem_ + 8, static_cast(0)); + rmem_[0xB] = rmem_[0xA] = 0; + wmem_[0xB] = wmem_[0xA] = 0; + rmem_[0xE] = rmem_[0xD] = rmem_[0xC] = 0; + wmem_[0xE] = wmem_[0xD] = wmem_[0xC] = 0; + break; + case OAM_DMA_SRC_VRAM: + break; + case OAM_DMA_SRC_OFF: + break; + } + } +} + +// all pointers here are relative to memchunk_ +#define MSS(a) RSS(a,memchunk_) +#define MSL(a) RSL(a,memchunk_) + SYNCFUNC(MemPtrs) { /* @@ -215,6 +226,10 @@ SYNCFUNC(MemPtrs) MSS(rambankdata_); MSS(wramdataend_); NSS(oamDmaSrc_); + + NSS(biosdata_); + NSS(notbiosdata_); + NSS(use_bios); +} + } - -} diff --git a/libgambatte/src/mem/memptrs.h b/libgambatte/src/mem/memptrs.h index af21c02a15..3c63670907 100644 --- a/libgambatte/src/mem/memptrs.h +++ b/libgambatte/src/mem/memptrs.h @@ -1,93 +1,97 @@ -/*************************************************************************** - * Copyright (C) 2007-2010 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef MEMPTRS_H -#define MEMPTRS_H - +/*************************************************************************** + * Copyright (C) 2007-2010 by Sindre Aamås * + * aamas@stud.ntnu.no * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License version 2 as * + * published by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License version 2 for more details. * + * * + * You should have received a copy of the GNU General Public License * + * version 2 along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef MEMPTRS_H +#define MEMPTRS_H + #include "newstate.h" - -namespace gambatte { - -enum OamDmaSrc { OAM_DMA_SRC_ROM, OAM_DMA_SRC_SRAM, OAM_DMA_SRC_VRAM, - OAM_DMA_SRC_WRAM, OAM_DMA_SRC_INVALID, OAM_DMA_SRC_OFF }; - -class MemPtrs { - const unsigned char *rmem_[0x10]; - unsigned char *wmem_[0x10]; - - unsigned char *romdata_[2]; - unsigned char *wramdata_[2]; - unsigned char *vrambankptr_; - unsigned char *rsrambankptr_; - unsigned char *wsrambankptr_; - unsigned char *memchunk_; - unsigned char *rambankdata_; - unsigned char *wramdataend_; - - OamDmaSrc oamDmaSrc_; - - int memchunk_len; - int memchunk_saveoffs; - int memchunk_savelen; - - MemPtrs(const MemPtrs &); - MemPtrs & operator=(const MemPtrs &); - void disconnectOamDmaAreas(); - unsigned char * rdisabledRamw() const { return wramdataend_ ; } - unsigned char * wdisabledRam() const { return wramdataend_ + 0x2000; } -public: - enum RamFlag { READ_EN = 1, WRITE_EN = 2, RTC_EN = 4 }; - - MemPtrs(); - ~MemPtrs(); - void reset(unsigned rombanks, unsigned rambanks, unsigned wrambanks); - - const unsigned char * rmem(unsigned area) const { return rmem_[area]; } - unsigned char * wmem(unsigned area) const { return wmem_[area]; } - unsigned char * vramdata() const { return rambankdata_ - 0x4000; } - unsigned char * vramdataend() const { return rambankdata_; } - unsigned char * romdata() const { return memchunk_ + 0x4000; } - unsigned char * romdata(unsigned area) const { return romdata_[area]; } - unsigned char * romdataend() const { return rambankdata_ - 0x4000; } - unsigned char * wramdata(unsigned area) const { return wramdata_[area]; } - unsigned char * wramdataend() const { return wramdataend_; } - unsigned char * rambankdata() const { return rambankdata_; } - unsigned char * rambankdataend() const { return wramdata_[0]; } - const unsigned char * rdisabledRam() const { return rdisabledRamw(); } - const unsigned char * rsrambankptr() const { return rsrambankptr_; } - unsigned char * wsrambankptr() const { return wsrambankptr_; } - unsigned char * vrambankptr() const { return vrambankptr_; } - OamDmaSrc oamDmaSrc() const { return oamDmaSrc_; } - - void setRombank0(unsigned bank); - void setRombank(unsigned bank); - void setRambank(unsigned ramFlags, unsigned rambank); - void setVrambank(unsigned bank) { vrambankptr_ = vramdata() + bank * 0x2000ul - 0x8000; } - void setWrambank(unsigned bank); - void setOamDmaSrc(OamDmaSrc oamDmaSrc); - + +namespace gambatte { + +enum OamDmaSrc { OAM_DMA_SRC_ROM, OAM_DMA_SRC_SRAM, OAM_DMA_SRC_VRAM, + OAM_DMA_SRC_WRAM, OAM_DMA_SRC_INVALID, OAM_DMA_SRC_OFF }; + +class MemPtrs { + const unsigned char *rmem_[0x10]; + unsigned char *wmem_[0x10]; + + unsigned char *romdata_[2]; + unsigned char *wramdata_[2]; + unsigned char *vrambankptr_; + unsigned char *rsrambankptr_; + unsigned char *wsrambankptr_; + unsigned char *memchunk_; + unsigned char *rambankdata_; + unsigned char *wramdataend_; + + OamDmaSrc oamDmaSrc_; + + int memchunk_len; + int memchunk_saveoffs; + int memchunk_savelen; + + MemPtrs(const MemPtrs &); + MemPtrs & operator=(const MemPtrs &); + void disconnectOamDmaAreas(); + unsigned char * rdisabledRamw() const { return wramdataend_ ; } + unsigned char * wdisabledRam() const { return wramdataend_ + 0x2000; } +public: + unsigned char *biosdata_; + unsigned char *notbiosdata_; + bool use_bios; + + enum RamFlag { READ_EN = 1, WRITE_EN = 2, RTC_EN = 4 }; + + MemPtrs(); + ~MemPtrs(); + void reset(unsigned rombanks, unsigned rambanks, unsigned wrambanks); + + const unsigned char * rmem(unsigned area) const { return rmem_[area]; } + unsigned char * wmem(unsigned area) const { return wmem_[area]; } + unsigned char * vramdata() const { return rambankdata_ - 0x4000; } + unsigned char * vramdataend() const { return rambankdata_; } + unsigned char * romdata() const { return memchunk_ + 0x4000;} + unsigned char * romdata(unsigned area) const { return romdata_[area]; } + unsigned char * romdataend() const { return rambankdata_ - 0x4000; } + unsigned char * wramdata(unsigned area) const { return wramdata_[area]; } + unsigned char * wramdataend() const { return wramdataend_; } + unsigned char * rambankdata() const { return rambankdata_; } + unsigned char * rambankdataend() const { return wramdata_[0]; } + const unsigned char * rdisabledRam() const { return rdisabledRamw(); } + const unsigned char * rsrambankptr() const { return rsrambankptr_; } + unsigned char * wsrambankptr() const { return wsrambankptr_; } + unsigned char * vrambankptr() const { return vrambankptr_; } + OamDmaSrc oamDmaSrc() const { return oamDmaSrc_; } + + void setRombank0(unsigned bank); + void setRombank(unsigned bank); + void setRambank(unsigned ramFlags, unsigned rambank); + void setVrambank(unsigned bank) { vrambankptr_ = vramdata() + bank * 0x2000ul - 0x8000; } + void setWrambank(unsigned bank); + void setOamDmaSrc(OamDmaSrc oamDmaSrc); + templatevoid SyncState(NewState *ns); -}; - -inline bool isCgb(const MemPtrs &memptrs) { - return memptrs.wramdataend() - memptrs.wramdata(0) == 0x8000; -} - -} - -#endif +}; + +inline bool isCgb(const MemPtrs &memptrs) { + return memptrs.wramdataend() - memptrs.wramdata(0) == 0x8000; +} + +} + +#endif diff --git a/libgambatte/src/memory.cpp b/libgambatte/src/memory.cpp index 4bae856679..79d9820e16 100644 --- a/libgambatte/src/memory.cpp +++ b/libgambatte/src/memory.cpp @@ -1,361 +1,361 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "memory.h" -#include "video.h" -#include "sound.h" -#include "savestate.h" -#include - -namespace gambatte { - -Memory::Memory(const Interrupter &interrupter_in) -: readCallback(0), - writeCallback(0), - execCallback(0), - cdCallback(0), - getInput(0), - divLastUpdate(0), - lastOamDmaUpdate(DISABLED_TIME), - display(ioamhram, 0, VideoInterruptRequester(&intreq)), - interrupter(interrupter_in), - dmaSource(0), - dmaDestination(0), - oamDmaPos(0xFE), - serialCnt(0), - blanklcd(false), - LINKCABLE(false), - linkClockTrigger(false) -{ - intreq.setEventTime(144*456ul); - intreq.setEventTime(0); -} - -void Memory::setStatePtrs(SaveState &state) { - state.mem.ioamhram.set(ioamhram, sizeof ioamhram); - - cart.setStatePtrs(state); - display.setStatePtrs(state); - sound.setStatePtrs(state); -} - - -static inline int serialCntFrom(const unsigned long cyclesUntilDone, const bool cgbFast) { - return cgbFast ? (cyclesUntilDone + 0xF) >> 4 : (cyclesUntilDone + 0x1FF) >> 9; -} - -void Memory::loadState(const SaveState &state) { - sound.loadState(state); - display.loadState(state, state.mem.oamDmaPos < 0xA0 ? cart.rdisabledRam() : ioamhram); - tima.loadState(state, TimaInterruptRequester(intreq)); - cart.loadState(state); - intreq.loadState(state); - - divLastUpdate = state.mem.divLastUpdate; - intreq.setEventTime(state.mem.nextSerialtime > state.cpu.cycleCounter ? state.mem.nextSerialtime : state.cpu.cycleCounter); - intreq.setEventTime(state.mem.unhaltTime); - lastOamDmaUpdate = state.mem.lastOamDmaUpdate; - dmaSource = state.mem.dmaSource; - dmaDestination = state.mem.dmaDestination; - oamDmaPos = state.mem.oamDmaPos; - serialCnt = intreq.eventTime(SERIAL) != DISABLED_TIME - ? serialCntFrom(intreq.eventTime(SERIAL) - state.cpu.cycleCounter, ioamhram[0x102] & isCgb() * 2) - : 8; - - cart.setVrambank(ioamhram[0x14F] & isCgb()); - cart.setOamDmaSrc(OAM_DMA_SRC_OFF); - cart.setWrambank(isCgb() && (ioamhram[0x170] & 0x07) ? ioamhram[0x170] & 0x07 : 1); - - if (lastOamDmaUpdate != DISABLED_TIME) { - oamDmaInitSetup(); - - const unsigned oamEventPos = oamDmaPos < 0xA0 ? 0xA0 : 0x100; - - intreq.setEventTime(lastOamDmaUpdate + (oamEventPos - oamDmaPos) * 4); - } - - intreq.setEventTime((ioamhram[0x140] & 0x80) ? display.nextMode1IrqTime() : state.cpu.cycleCounter); - blanklcd = false; - - if (!isCgb()) - std::memset(cart.vramdata() + 0x2000, 0, 0x2000); -} - -void Memory::setEndtime(const unsigned long cycleCounter, const unsigned long inc) { - if (intreq.eventTime(BLIT) <= cycleCounter) - intreq.setEventTime(intreq.eventTime(BLIT) + (70224 << isDoubleSpeed())); - - intreq.setEventTime(cycleCounter + (inc << isDoubleSpeed())); -} - -void Memory::updateSerial(const unsigned long cc) { - if (!LINKCABLE) { - if (intreq.eventTime(SERIAL) != DISABLED_TIME) { - if (intreq.eventTime(SERIAL) <= cc) { - ioamhram[0x101] = (((ioamhram[0x101] + 1) << serialCnt) - 1) & 0xFF; - ioamhram[0x102] &= 0x7F; - intreq.setEventTime(DISABLED_TIME); - intreq.flagIrq(8); - } else { - const int targetCnt = serialCntFrom(intreq.eventTime(SERIAL) - cc, ioamhram[0x102] & isCgb() * 2); - ioamhram[0x101] = (((ioamhram[0x101] + 1) << (serialCnt - targetCnt)) - 1) & 0xFF; - serialCnt = targetCnt; - } - } - } - else { - if (intreq.eventTime(SERIAL) != DISABLED_TIME) { - if (intreq.eventTime(SERIAL) <= cc) { - linkClockTrigger = true; - intreq.setEventTime(DISABLED_TIME); - } - } - } -} - -void Memory::updateTimaIrq(const unsigned long cc) { - while (intreq.eventTime(TIMA) <= cc) - tima.doIrqEvent(TimaInterruptRequester(intreq)); -} - -void Memory::updateIrqs(const unsigned long cc) { - updateSerial(cc); - updateTimaIrq(cc); - display.update(cc); -} - -unsigned long Memory::event(unsigned long cycleCounter) { - if (lastOamDmaUpdate != DISABLED_TIME) - updateOamDma(cycleCounter); - - switch (intreq.minEventId()) { - case UNHALT: - intreq.unhalt(); - intreq.setEventTime(DISABLED_TIME); - break; - case END: - intreq.setEventTime(DISABLED_TIME - 1); - - while (cycleCounter >= intreq.minEventTime() && intreq.eventTime(END) != DISABLED_TIME) - cycleCounter = event(cycleCounter); - - intreq.setEventTime(DISABLED_TIME); - - break; - case BLIT: - { - const bool lcden = ioamhram[0x140] >> 7 & 1; - unsigned long blitTime = intreq.eventTime(BLIT); - - if (lcden | blanklcd) { - display.updateScreen(blanklcd, cycleCounter); - intreq.setEventTime(DISABLED_TIME); - intreq.setEventTime(DISABLED_TIME); - - while (cycleCounter >= intreq.minEventTime()) - cycleCounter = event(cycleCounter); - } else - blitTime += 70224 << isDoubleSpeed(); - - blanklcd = lcden ^ 1; - intreq.setEventTime(blitTime); - } - break; - case SERIAL: - updateSerial(cycleCounter); - break; - case OAM: - intreq.setEventTime(lastOamDmaUpdate == DISABLED_TIME ? - static_cast(DISABLED_TIME) : intreq.eventTime(OAM) + 0xA0 * 4); - break; - case DMA: - { - const bool doubleSpeed = isDoubleSpeed(); - unsigned dmaSrc = dmaSource; - unsigned dmaDest = dmaDestination; - unsigned dmaLength = ((ioamhram[0x155] & 0x7F) + 0x1) * 0x10; - unsigned length = hdmaReqFlagged(intreq) ? 0x10 : dmaLength; - - ackDmaReq(&intreq); - - if ((static_cast(dmaDest) + length) & 0x10000) { - length = 0x10000 - dmaDest; - ioamhram[0x155] |= 0x80; - } - - dmaLength -= length; - - if (!(ioamhram[0x140] & 0x80)) - dmaLength = 0; - - { - unsigned long lOamDmaUpdate = lastOamDmaUpdate; - lastOamDmaUpdate = DISABLED_TIME; - - while (length--) { - const unsigned src = dmaSrc++ & 0xFFFF; - const unsigned data = ((src & 0xE000) == 0x8000 || src > 0xFDFF) ? 0xFF : read(src, cycleCounter); - - cycleCounter += 2 << doubleSpeed; - - if (cycleCounter - 3 > lOamDmaUpdate) { - oamDmaPos = (oamDmaPos + 1) & 0xFF; - lOamDmaUpdate += 4; - - if (oamDmaPos < 0xA0) { - if (oamDmaPos == 0) - startOamDma(lOamDmaUpdate - 1); - - ioamhram[src & 0xFF] = data; - } else if (oamDmaPos == 0xA0) { - endOamDma(lOamDmaUpdate - 1); - lOamDmaUpdate = DISABLED_TIME; - } - } - - nontrivial_write(0x8000 | (dmaDest++ & 0x1FFF), data, cycleCounter); - } - - lastOamDmaUpdate = lOamDmaUpdate; - } - - cycleCounter += 4; - - dmaSource = dmaSrc; - dmaDestination = dmaDest; - ioamhram[0x155] = ((dmaLength / 0x10 - 0x1) & 0xFF) | (ioamhram[0x155] & 0x80); - - if ((ioamhram[0x155] & 0x80) && display.hdmaIsEnabled()) { - if (lastOamDmaUpdate != DISABLED_TIME) - updateOamDma(cycleCounter); - - display.disableHdma(cycleCounter); - } - } - - break; - case TIMA: - tima.doIrqEvent(TimaInterruptRequester(intreq)); - break; - case VIDEO: - display.update(cycleCounter); - break; - case INTERRUPTS: - if (halted()) { - if (isCgb()) - cycleCounter += 4; - - intreq.unhalt(); - intreq.setEventTime(DISABLED_TIME); - } - - if (ime()) { - unsigned address; - const unsigned pendingIrqs = intreq.pendingIrqs(); - const unsigned n = pendingIrqs & -pendingIrqs; - - if (n < 8) { - static const unsigned char lut[] = { 0x40, 0x48, 0x48, 0x50 }; - address = lut[n-1]; - } else - address = 0x50 + n; - - intreq.ackIrq(n); - cycleCounter = interrupter.interrupt(address, cycleCounter, *this); - } - - break; - } - - return cycleCounter; -} - -unsigned long Memory::stop(unsigned long cycleCounter) { - cycleCounter += 4 << isDoubleSpeed(); - - if (ioamhram[0x14D] & isCgb()) { - sound.generate_samples(cycleCounter, isDoubleSpeed()); - - display.speedChange(cycleCounter); - ioamhram[0x14D] ^= 0x81; - - intreq.setEventTime((ioamhram[0x140] & 0x80) ? display.nextMode1IrqTime() : cycleCounter + (70224 << isDoubleSpeed())); - - if (intreq.eventTime(END) > cycleCounter) { - intreq.setEventTime(cycleCounter + (isDoubleSpeed() ? - (intreq.eventTime(END) - cycleCounter) << 1 : (intreq.eventTime(END) - cycleCounter) >> 1)); - } - // when switching speed, it seems that the CPU spontaneously restarts soon? - // otherwise, the cpu should be allowed to stay halted as long as needed - // so only execute this line when switching speed - intreq.setEventTime(cycleCounter + 0x20000 + isDoubleSpeed() * 8); - } - - intreq.halt(); - - return cycleCounter; -} - -static void decCycles(unsigned long &counter, const unsigned long dec) { - if (counter != DISABLED_TIME) - counter -= dec; -} - -void Memory::decEventCycles(const MemEventId eventId, const unsigned long dec) { - if (intreq.eventTime(eventId) != DISABLED_TIME) - intreq.setEventTime(eventId, intreq.eventTime(eventId) - dec); -} - -unsigned long Memory::resetCounters(unsigned long cycleCounter) { - if (lastOamDmaUpdate != DISABLED_TIME) - updateOamDma(cycleCounter); - - updateIrqs(cycleCounter); - - const unsigned long oldCC = cycleCounter; - - { - const unsigned long divinc = (cycleCounter - divLastUpdate) >> 8; - ioamhram[0x104] = (ioamhram[0x104] + divinc) & 0xFF; - divLastUpdate += divinc << 8; - } - - const unsigned long dec = cycleCounter < 0x10000 ? 0 : (cycleCounter & ~0x7FFFul) - 0x8000; - - decCycles(divLastUpdate, dec); - decCycles(lastOamDmaUpdate, dec); - decEventCycles(SERIAL, dec); - decEventCycles(OAM, dec); - decEventCycles(BLIT, dec); - decEventCycles(END, dec); - decEventCycles(UNHALT, dec); - - cycleCounter -= dec; - - intreq.resetCc(oldCC, cycleCounter); - tima.resetCc(oldCC, cycleCounter, TimaInterruptRequester(intreq)); - display.resetCc(oldCC, cycleCounter); - sound.resetCounter(cycleCounter, oldCC, isDoubleSpeed()); - - return cycleCounter; -} - -void Memory::updateInput() { +/*************************************************************************** + * Copyright (C) 2007 by Sindre Aamås * + * aamas@stud.ntnu.no * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License version 2 as * + * published by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License version 2 for more details. * + * * + * You should have received a copy of the GNU General Public License * + * version 2 along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "memory.h" +#include "video.h" +#include "sound.h" +#include "savestate.h" +#include + +namespace gambatte { + +Memory::Memory(const Interrupter &interrupter_in) +: readCallback(0), + writeCallback(0), + execCallback(0), + cdCallback(0), + getInput(0), + divLastUpdate(0), + lastOamDmaUpdate(DISABLED_TIME), + display(ioamhram, 0, VideoInterruptRequester(&intreq)), + interrupter(interrupter_in), + dmaSource(0), + dmaDestination(0), + oamDmaPos(0xFE), + serialCnt(0), + blanklcd(false), + LINKCABLE(false), + linkClockTrigger(false) +{ + intreq.setEventTime(144*456ul); + intreq.setEventTime(0); +} + +void Memory::setStatePtrs(SaveState &state) { + state.mem.ioamhram.set(ioamhram, sizeof ioamhram); + + cart.setStatePtrs(state); + display.setStatePtrs(state); + sound.setStatePtrs(state); +} + + +static inline int serialCntFrom(const unsigned long cyclesUntilDone, const bool cgbFast) { + return cgbFast ? (cyclesUntilDone + 0xF) >> 4 : (cyclesUntilDone + 0x1FF) >> 9; +} + +void Memory::loadState(const SaveState &state) { + sound.loadState(state); + display.loadState(state, state.mem.oamDmaPos < 0xA0 ? cart.rdisabledRam() : ioamhram); + tima.loadState(state, TimaInterruptRequester(intreq)); + cart.loadState(state); + intreq.loadState(state); + + divLastUpdate = state.mem.divLastUpdate; + intreq.setEventTime(state.mem.nextSerialtime > state.cpu.cycleCounter ? state.mem.nextSerialtime : state.cpu.cycleCounter); + intreq.setEventTime(state.mem.unhaltTime); + lastOamDmaUpdate = state.mem.lastOamDmaUpdate; + dmaSource = state.mem.dmaSource; + dmaDestination = state.mem.dmaDestination; + oamDmaPos = state.mem.oamDmaPos; + serialCnt = intreq.eventTime(SERIAL) != DISABLED_TIME + ? serialCntFrom(intreq.eventTime(SERIAL) - state.cpu.cycleCounter, ioamhram[0x102] & isCgb() * 2) + : 8; + + cart.setVrambank(ioamhram[0x14F] & isCgb()); + cart.setOamDmaSrc(OAM_DMA_SRC_OFF); + cart.setWrambank(isCgb() && (ioamhram[0x170] & 0x07) ? ioamhram[0x170] & 0x07 : 1); + + if (lastOamDmaUpdate != DISABLED_TIME) { + oamDmaInitSetup(); + + const unsigned oamEventPos = oamDmaPos < 0xA0 ? 0xA0 : 0x100; + + intreq.setEventTime(lastOamDmaUpdate + (oamEventPos - oamDmaPos) * 4); + } + + intreq.setEventTime((ioamhram[0x140] & 0x80) ? display.nextMode1IrqTime() : state.cpu.cycleCounter); + blanklcd = false; + + if (!isCgb()) + std::memset(cart.vramdata() + 0x2000, 0, 0x2000); +} + +void Memory::setEndtime(const unsigned long cycleCounter, const unsigned long inc) { + if (intreq.eventTime(BLIT) <= cycleCounter) + intreq.setEventTime(intreq.eventTime(BLIT) + (70224 << isDoubleSpeed())); + + intreq.setEventTime(cycleCounter + (inc << isDoubleSpeed())); +} + +void Memory::updateSerial(const unsigned long cc) { + if (!LINKCABLE) { + if (intreq.eventTime(SERIAL) != DISABLED_TIME) { + if (intreq.eventTime(SERIAL) <= cc) { + ioamhram[0x101] = (((ioamhram[0x101] + 1) << serialCnt) - 1) & 0xFF; + ioamhram[0x102] &= 0x7F; + intreq.setEventTime(DISABLED_TIME); + intreq.flagIrq(8); + } else { + const int targetCnt = serialCntFrom(intreq.eventTime(SERIAL) - cc, ioamhram[0x102] & isCgb() * 2); + ioamhram[0x101] = (((ioamhram[0x101] + 1) << (serialCnt - targetCnt)) - 1) & 0xFF; + serialCnt = targetCnt; + } + } + } + else { + if (intreq.eventTime(SERIAL) != DISABLED_TIME) { + if (intreq.eventTime(SERIAL) <= cc) { + linkClockTrigger = true; + intreq.setEventTime(DISABLED_TIME); + } + } + } +} + +void Memory::updateTimaIrq(const unsigned long cc) { + while (intreq.eventTime(TIMA) <= cc) + tima.doIrqEvent(TimaInterruptRequester(intreq)); +} + +void Memory::updateIrqs(const unsigned long cc) { + updateSerial(cc); + updateTimaIrq(cc); + display.update(cc); +} + +unsigned long Memory::event(unsigned long cycleCounter) { + if (lastOamDmaUpdate != DISABLED_TIME) + updateOamDma(cycleCounter); + + switch (intreq.minEventId()) { + case UNHALT: + intreq.unhalt(); + intreq.setEventTime(DISABLED_TIME); + break; + case END: + intreq.setEventTime(DISABLED_TIME - 1); + + while (cycleCounter >= intreq.minEventTime() && intreq.eventTime(END) != DISABLED_TIME) + cycleCounter = event(cycleCounter); + + intreq.setEventTime(DISABLED_TIME); + + break; + case BLIT: + { + const bool lcden = ioamhram[0x140] >> 7 & 1; + unsigned long blitTime = intreq.eventTime(BLIT); + + if (lcden | blanklcd) { + display.updateScreen(blanklcd, cycleCounter); + intreq.setEventTime(DISABLED_TIME); + intreq.setEventTime(DISABLED_TIME); + + while (cycleCounter >= intreq.minEventTime()) + cycleCounter = event(cycleCounter); + } else + blitTime += 70224 << isDoubleSpeed(); + + blanklcd = lcden ^ 1; + intreq.setEventTime(blitTime); + } + break; + case SERIAL: + updateSerial(cycleCounter); + break; + case OAM: + intreq.setEventTime(lastOamDmaUpdate == DISABLED_TIME ? + static_cast(DISABLED_TIME) : intreq.eventTime(OAM) + 0xA0 * 4); + break; + case DMA: + { + const bool doubleSpeed = isDoubleSpeed(); + unsigned dmaSrc = dmaSource; + unsigned dmaDest = dmaDestination; + unsigned dmaLength = ((ioamhram[0x155] & 0x7F) + 0x1) * 0x10; + unsigned length = hdmaReqFlagged(intreq) ? 0x10 : dmaLength; + + ackDmaReq(&intreq); + + if ((static_cast(dmaDest) + length) & 0x10000) { + length = 0x10000 - dmaDest; + ioamhram[0x155] |= 0x80; + } + + dmaLength -= length; + + if (!(ioamhram[0x140] & 0x80)) + dmaLength = 0; + + { + unsigned long lOamDmaUpdate = lastOamDmaUpdate; + lastOamDmaUpdate = DISABLED_TIME; + + while (length--) { + const unsigned src = dmaSrc++ & 0xFFFF; + const unsigned data = ((src & 0xE000) == 0x8000 || src > 0xFDFF) ? 0xFF : read(src, cycleCounter); + + cycleCounter += 2 << doubleSpeed; + + if (cycleCounter - 3 > lOamDmaUpdate) { + oamDmaPos = (oamDmaPos + 1) & 0xFF; + lOamDmaUpdate += 4; + + if (oamDmaPos < 0xA0) { + if (oamDmaPos == 0) + startOamDma(lOamDmaUpdate - 1); + + ioamhram[src & 0xFF] = data; + } else if (oamDmaPos == 0xA0) { + endOamDma(lOamDmaUpdate - 1); + lOamDmaUpdate = DISABLED_TIME; + } + } + + nontrivial_write(0x8000 | (dmaDest++ & 0x1FFF), data, cycleCounter); + } + + lastOamDmaUpdate = lOamDmaUpdate; + } + + cycleCounter += 4; + + dmaSource = dmaSrc; + dmaDestination = dmaDest; + ioamhram[0x155] = ((dmaLength / 0x10 - 0x1) & 0xFF) | (ioamhram[0x155] & 0x80); + + if ((ioamhram[0x155] & 0x80) && display.hdmaIsEnabled()) { + if (lastOamDmaUpdate != DISABLED_TIME) + updateOamDma(cycleCounter); + + display.disableHdma(cycleCounter); + } + } + + break; + case TIMA: + tima.doIrqEvent(TimaInterruptRequester(intreq)); + break; + case VIDEO: + display.update(cycleCounter); + break; + case INTERRUPTS: + if (halted()) { + if (isCgb()) + cycleCounter += 4; + + intreq.unhalt(); + intreq.setEventTime(DISABLED_TIME); + } + + if (ime()) { + unsigned address; + const unsigned pendingIrqs = intreq.pendingIrqs(); + const unsigned n = pendingIrqs & -pendingIrqs; + + if (n < 8) { + static const unsigned char lut[] = { 0x40, 0x48, 0x48, 0x50 }; + address = lut[n-1]; + } else + address = 0x50 + n; + + intreq.ackIrq(n); + cycleCounter = interrupter.interrupt(address, cycleCounter, *this); + } + + break; + } + + return cycleCounter; +} + +unsigned long Memory::stop(unsigned long cycleCounter) { + cycleCounter += 4 << isDoubleSpeed(); + + if (ioamhram[0x14D] & isCgb()) { + sound.generate_samples(cycleCounter, isDoubleSpeed()); + + display.speedChange(cycleCounter); + ioamhram[0x14D] ^= 0x81; + + intreq.setEventTime((ioamhram[0x140] & 0x80) ? display.nextMode1IrqTime() : cycleCounter + (70224 << isDoubleSpeed())); + + if (intreq.eventTime(END) > cycleCounter) { + intreq.setEventTime(cycleCounter + (isDoubleSpeed() ? + (intreq.eventTime(END) - cycleCounter) << 1 : (intreq.eventTime(END) - cycleCounter) >> 1)); + } + // when switching speed, it seems that the CPU spontaneously restarts soon? + // otherwise, the cpu should be allowed to stay halted as long as needed + // so only execute this line when switching speed + intreq.setEventTime(cycleCounter + 0x20000 + isDoubleSpeed() * 8); + } + + intreq.halt(); + + return cycleCounter; +} + +static void decCycles(unsigned long &counter, const unsigned long dec) { + if (counter != DISABLED_TIME) + counter -= dec; +} + +void Memory::decEventCycles(const MemEventId eventId, const unsigned long dec) { + if (intreq.eventTime(eventId) != DISABLED_TIME) + intreq.setEventTime(eventId, intreq.eventTime(eventId) - dec); +} + +unsigned long Memory::resetCounters(unsigned long cycleCounter) { + if (lastOamDmaUpdate != DISABLED_TIME) + updateOamDma(cycleCounter); + + updateIrqs(cycleCounter); + + const unsigned long oldCC = cycleCounter; + + { + const unsigned long divinc = (cycleCounter - divLastUpdate) >> 8; + ioamhram[0x104] = (ioamhram[0x104] + divinc) & 0xFF; + divLastUpdate += divinc << 8; + } + + const unsigned long dec = cycleCounter < 0x10000 ? 0 : (cycleCounter & ~0x7FFFul) - 0x8000; + + decCycles(divLastUpdate, dec); + decCycles(lastOamDmaUpdate, dec); + decEventCycles(SERIAL, dec); + decEventCycles(OAM, dec); + decEventCycles(BLIT, dec); + decEventCycles(END, dec); + decEventCycles(UNHALT, dec); + + cycleCounter -= dec; + + intreq.resetCc(oldCC, cycleCounter); + tima.resetCc(oldCC, cycleCounter, TimaInterruptRequester(intreq)); + display.resetCc(oldCC, cycleCounter); + sound.resetCounter(cycleCounter, oldCC, isDoubleSpeed()); + + return cycleCounter; +} + +void Memory::updateInput() { unsigned state = 0xF; if ((ioamhram[0x100] & 0x30) != 0x30 && getInput) { @@ -371,720 +371,725 @@ void Memory::updateInput() { if (state != 0xF && (ioamhram[0x100] & 0xF) == 0xF) intreq.flagIrq(0x10); - ioamhram[0x100] = (ioamhram[0x100] & -0x10u) | state; -} - -void Memory::updateOamDma(const unsigned long cycleCounter) { - const unsigned char *const oamDmaSrc = oamDmaSrcPtr(); - unsigned cycles = (cycleCounter - lastOamDmaUpdate) >> 2; - - while (cycles--) { - oamDmaPos = (oamDmaPos + 1) & 0xFF; - lastOamDmaUpdate += 4; - - if (oamDmaPos < 0xA0) { - if (oamDmaPos == 0) - startOamDma(lastOamDmaUpdate - 1); - - ioamhram[oamDmaPos] = oamDmaSrc ? oamDmaSrc[oamDmaPos] : cart.rtcRead(); - } else if (oamDmaPos == 0xA0) { - endOamDma(lastOamDmaUpdate - 1); - lastOamDmaUpdate = DISABLED_TIME; - break; - } - } -} - -void Memory::oamDmaInitSetup() { - if (ioamhram[0x146] < 0xA0) { - cart.setOamDmaSrc(ioamhram[0x146] < 0x80 ? OAM_DMA_SRC_ROM : OAM_DMA_SRC_VRAM); - } else if (ioamhram[0x146] < 0xFE - isCgb() * 0x1E) { - cart.setOamDmaSrc(ioamhram[0x146] < 0xC0 ? OAM_DMA_SRC_SRAM : OAM_DMA_SRC_WRAM); - } else - cart.setOamDmaSrc(OAM_DMA_SRC_INVALID); -} - -static const unsigned char * oamDmaSrcZero() { - static unsigned char zeroMem[0xA0]; - return zeroMem; -} - -const unsigned char * Memory::oamDmaSrcPtr() const { - switch (cart.oamDmaSrc()) { - case OAM_DMA_SRC_ROM: return cart.romdata(ioamhram[0x146] >> 6) + (ioamhram[0x146] << 8); - case OAM_DMA_SRC_SRAM: return cart.rsrambankptr() ? cart.rsrambankptr() + (ioamhram[0x146] << 8) : 0; - case OAM_DMA_SRC_VRAM: return cart.vrambankptr() + (ioamhram[0x146] << 8); - case OAM_DMA_SRC_WRAM: return cart.wramdata(ioamhram[0x146] >> 4 & 1) + (ioamhram[0x146] << 8 & 0xFFF); - case OAM_DMA_SRC_INVALID: - case OAM_DMA_SRC_OFF: break; - } - - return ioamhram[0x146] == 0xFF && !isCgb() ? oamDmaSrcZero() : cart.rdisabledRam(); -} - -void Memory::startOamDma(const unsigned long cycleCounter) { - display.oamChange(cart.rdisabledRam(), cycleCounter); -} - -void Memory::endOamDma(const unsigned long cycleCounter) { - oamDmaPos = 0xFE; - cart.setOamDmaSrc(OAM_DMA_SRC_OFF); - display.oamChange(ioamhram, cycleCounter); -} - -unsigned Memory::nontrivial_ff_read(const unsigned P, const unsigned long cycleCounter) { - if (lastOamDmaUpdate != DISABLED_TIME) - updateOamDma(cycleCounter); - - switch (P & 0x7F) { - case 0x00: - updateInput(); - break; - case 0x01: - case 0x02: - updateSerial(cycleCounter); - break; - case 0x04: - { - const unsigned long divcycles = (cycleCounter - divLastUpdate) >> 8; - ioamhram[0x104] = (ioamhram[0x104] + divcycles) & 0xFF; - divLastUpdate += divcycles << 8; - } - - break; - case 0x05: - ioamhram[0x105] = tima.tima(cycleCounter); - break; - case 0x0F: - updateIrqs(cycleCounter); - ioamhram[0x10F] = intreq.ifreg(); - break; - case 0x26: - if (ioamhram[0x126] & 0x80) { - sound.generate_samples(cycleCounter, isDoubleSpeed()); - ioamhram[0x126] = 0xF0 | sound.getStatus(); - } else - ioamhram[0x126] = 0x70; - - break; - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - case 0x38: - case 0x39: - case 0x3A: - case 0x3B: - case 0x3C: - case 0x3D: - case 0x3E: - case 0x3F: - sound.generate_samples(cycleCounter, isDoubleSpeed()); - return sound.waveRamRead(P & 0xF); - case 0x41: - return ioamhram[0x141] | display.getStat(ioamhram[0x145], cycleCounter); - case 0x44: - return display.getLyReg(cycleCounter/*+4*/); - case 0x69: - return display.cgbBgColorRead(ioamhram[0x168] & 0x3F, cycleCounter); - case 0x6B: - return display.cgbSpColorRead(ioamhram[0x16A] & 0x3F, cycleCounter); - default: break; - } - - return ioamhram[P - 0xFE00]; -} - -static bool isInOamDmaConflictArea(const OamDmaSrc oamDmaSrc, const unsigned addr, const bool cgb) { - struct Area { unsigned short areaUpper, exceptAreaLower, exceptAreaWidth, pad; }; - - static const Area cgbAreas[] = { - { 0xC000, 0x8000, 0x2000, 0 }, - { 0xC000, 0x8000, 0x2000, 0 }, - { 0xA000, 0x0000, 0x8000, 0 }, - { 0xFE00, 0x0000, 0xC000, 0 }, - { 0xC000, 0x8000, 0x2000, 0 }, - { 0x0000, 0x0000, 0x0000, 0 } - }; - - static const Area dmgAreas[] = { - { 0xFE00, 0x8000, 0x2000, 0 }, - { 0xFE00, 0x8000, 0x2000, 0 }, - { 0xA000, 0x0000, 0x8000, 0 }, - { 0xFE00, 0x8000, 0x2000, 0 }, - { 0xFE00, 0x8000, 0x2000, 0 }, - { 0x0000, 0x0000, 0x0000, 0 } - }; - - const Area *const a = cgb ? cgbAreas : dmgAreas; - - return addr < a[oamDmaSrc].areaUpper && addr - a[oamDmaSrc].exceptAreaLower >= a[oamDmaSrc].exceptAreaWidth; -} - -unsigned Memory::nontrivial_read(const unsigned P, const unsigned long cycleCounter) { - if (P < 0xFF80) { - if (lastOamDmaUpdate != DISABLED_TIME) { - updateOamDma(cycleCounter); - - if (isInOamDmaConflictArea(cart.oamDmaSrc(), P, isCgb()) && oamDmaPos < 0xA0) - return ioamhram[oamDmaPos]; - } - - if (P < 0xC000) { - if (P < 0x8000) - return cart.romdata(P >> 14)[P]; - - if (P < 0xA000) { - if (!display.vramAccessible(cycleCounter)) - return 0xFF; - - return cart.vrambankptr()[P]; - } - - if (cart.rsrambankptr()) - return cart.rsrambankptr()[P]; - - return cart.rtcRead(); - } - - if (P < 0xFE00) - return cart.wramdata(P >> 12 & 1)[P & 0xFFF]; - - if (P >= 0xFF00) - return nontrivial_ff_read(P, cycleCounter); - - if (!display.oamReadable(cycleCounter) || oamDmaPos < 0xA0) - return 0xFF; - } - - return ioamhram[P - 0xFE00]; -} - -unsigned Memory::nontrivial_peek(const unsigned P) { - if (P < 0xC000) { - if (P < 0x8000) - return cart.romdata(P >> 14)[P]; - - if (P < 0xA000) { - return cart.vrambankptr()[P]; - } - - if (cart.rsrambankptr()) - return cart.rsrambankptr()[P]; - - return cart.rtcRead(); // verified side-effect free - } - if (P < 0xFE00) - return cart.wramdata(P >> 12 & 1)[P & 0xFFF]; - if (P >= 0xFF00 && P < 0xFF80) - return nontrivial_ff_peek(P); - return ioamhram[P - 0xFE00]; -} - -unsigned Memory::nontrivial_ff_peek(const unsigned P) { - // some regs may be somewhat wrong with this - return ioamhram[P - 0xFE00]; -} - -void Memory::nontrivial_ff_write(const unsigned P, unsigned data, const unsigned long cycleCounter) { - if (lastOamDmaUpdate != DISABLED_TIME) - updateOamDma(cycleCounter); - - switch (P & 0xFF) { + ioamhram[0x100] = (ioamhram[0x100] & -0x10u) | state; +} + +void Memory::updateOamDma(const unsigned long cycleCounter) { + const unsigned char *const oamDmaSrc = oamDmaSrcPtr(); + unsigned cycles = (cycleCounter - lastOamDmaUpdate) >> 2; + + while (cycles--) { + oamDmaPos = (oamDmaPos + 1) & 0xFF; + lastOamDmaUpdate += 4; + + if (oamDmaPos < 0xA0) { + if (oamDmaPos == 0) + startOamDma(lastOamDmaUpdate - 1); + + ioamhram[oamDmaPos] = oamDmaSrc ? oamDmaSrc[oamDmaPos] : cart.rtcRead(); + } else if (oamDmaPos == 0xA0) { + endOamDma(lastOamDmaUpdate - 1); + lastOamDmaUpdate = DISABLED_TIME; + break; + } + } +} + +void Memory::oamDmaInitSetup() { + if (ioamhram[0x146] < 0xA0) { + cart.setOamDmaSrc(ioamhram[0x146] < 0x80 ? OAM_DMA_SRC_ROM : OAM_DMA_SRC_VRAM); + } else if (ioamhram[0x146] < 0xFE - isCgb() * 0x1E) { + cart.setOamDmaSrc(ioamhram[0x146] < 0xC0 ? OAM_DMA_SRC_SRAM : OAM_DMA_SRC_WRAM); + } else + cart.setOamDmaSrc(OAM_DMA_SRC_INVALID); +} + +static const unsigned char * oamDmaSrcZero() { + static unsigned char zeroMem[0xA0]; + return zeroMem; +} + +const unsigned char * Memory::oamDmaSrcPtr() const { + switch (cart.oamDmaSrc()) { + case OAM_DMA_SRC_ROM: return cart.romdata(ioamhram[0x146] >> 6) + (ioamhram[0x146] << 8); + case OAM_DMA_SRC_SRAM: return cart.rsrambankptr() ? cart.rsrambankptr() + (ioamhram[0x146] << 8) : 0; + case OAM_DMA_SRC_VRAM: return cart.vrambankptr() + (ioamhram[0x146] << 8); + case OAM_DMA_SRC_WRAM: return cart.wramdata(ioamhram[0x146] >> 4 & 1) + (ioamhram[0x146] << 8 & 0xFFF); + case OAM_DMA_SRC_INVALID: + case OAM_DMA_SRC_OFF: break; + } + + return ioamhram[0x146] == 0xFF && !isCgb() ? oamDmaSrcZero() : cart.rdisabledRam(); +} + +void Memory::startOamDma(const unsigned long cycleCounter) { + display.oamChange(cart.rdisabledRam(), cycleCounter); +} + +void Memory::endOamDma(const unsigned long cycleCounter) { + oamDmaPos = 0xFE; + cart.setOamDmaSrc(OAM_DMA_SRC_OFF); + display.oamChange(ioamhram, cycleCounter); +} + +unsigned Memory::nontrivial_ff_read(const unsigned P, const unsigned long cycleCounter) { + if (lastOamDmaUpdate != DISABLED_TIME) + updateOamDma(cycleCounter); + + switch (P & 0x7F) { + case 0x00: + updateInput(); + break; + case 0x01: + case 0x02: + updateSerial(cycleCounter); + break; + case 0x04: + { + const unsigned long divcycles = (cycleCounter - divLastUpdate) >> 8; + ioamhram[0x104] = (ioamhram[0x104] + divcycles) & 0xFF; + divLastUpdate += divcycles << 8; + } + + break; + case 0x05: + ioamhram[0x105] = tima.tima(cycleCounter); + break; + case 0x0F: + updateIrqs(cycleCounter); + ioamhram[0x10F] = intreq.ifreg(); + break; + case 0x26: + if (ioamhram[0x126] & 0x80) { + sound.generate_samples(cycleCounter, isDoubleSpeed()); + ioamhram[0x126] = 0xF0 | sound.getStatus(); + } else + ioamhram[0x126] = 0x70; + + break; + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x3A: + case 0x3B: + case 0x3C: + case 0x3D: + case 0x3E: + case 0x3F: + sound.generate_samples(cycleCounter, isDoubleSpeed()); + return sound.waveRamRead(P & 0xF); + case 0x41: + return ioamhram[0x141] | display.getStat(ioamhram[0x145], cycleCounter); + case 0x44: + return display.getLyReg(cycleCounter/*+4*/); + case 0x69: + return display.cgbBgColorRead(ioamhram[0x168] & 0x3F, cycleCounter); + case 0x6B: + return display.cgbSpColorRead(ioamhram[0x16A] & 0x3F, cycleCounter); + default: break; + } + + return ioamhram[P - 0xFE00]; +} + +static bool isInOamDmaConflictArea(const OamDmaSrc oamDmaSrc, const unsigned addr, const bool cgb) { + struct Area { unsigned short areaUpper, exceptAreaLower, exceptAreaWidth, pad; }; + + static const Area cgbAreas[] = { + { 0xC000, 0x8000, 0x2000, 0 }, + { 0xC000, 0x8000, 0x2000, 0 }, + { 0xA000, 0x0000, 0x8000, 0 }, + { 0xFE00, 0x0000, 0xC000, 0 }, + { 0xC000, 0x8000, 0x2000, 0 }, + { 0x0000, 0x0000, 0x0000, 0 } + }; + + static const Area dmgAreas[] = { + { 0xFE00, 0x8000, 0x2000, 0 }, + { 0xFE00, 0x8000, 0x2000, 0 }, + { 0xA000, 0x0000, 0x8000, 0 }, + { 0xFE00, 0x8000, 0x2000, 0 }, + { 0xFE00, 0x8000, 0x2000, 0 }, + { 0x0000, 0x0000, 0x0000, 0 } + }; + + const Area *const a = cgb ? cgbAreas : dmgAreas; + + return addr < a[oamDmaSrc].areaUpper && addr - a[oamDmaSrc].exceptAreaLower >= a[oamDmaSrc].exceptAreaWidth; +} + +unsigned Memory::nontrivial_read(const unsigned P, const unsigned long cycleCounter) { + if (P < 0xFF80) { + if (lastOamDmaUpdate != DISABLED_TIME) { + updateOamDma(cycleCounter); + + if (isInOamDmaConflictArea(cart.oamDmaSrc(), P, isCgb()) && oamDmaPos < 0xA0) + return ioamhram[oamDmaPos]; + } + + if (P < 0xC000) { + if (P < 0x8000) + return cart.romdata(P >> 14)[P]; + + if (P < 0xA000) { + if (!display.vramAccessible(cycleCounter)) + return 0xFF; + + return cart.vrambankptr()[P]; + } + + if (cart.rsrambankptr()) + return cart.rsrambankptr()[P]; + + return cart.rtcRead(); + } + + if (P < 0xFE00) + return cart.wramdata(P >> 12 & 1)[P & 0xFFF]; + + if (P >= 0xFF00) + return nontrivial_ff_read(P, cycleCounter); + + if (!display.oamReadable(cycleCounter) || oamDmaPos < 0xA0) + return 0xFF; + } + + return ioamhram[P - 0xFE00]; +} + +unsigned Memory::nontrivial_peek(const unsigned P) { + if (P < 0xC000) { + if (P < 0x8000) + return cart.romdata(P >> 14)[P]; + + if (P < 0xA000) { + return cart.vrambankptr()[P]; + } + + if (cart.rsrambankptr()) + return cart.rsrambankptr()[P]; + + return cart.rtcRead(); // verified side-effect free + } + if (P < 0xFE00) + return cart.wramdata(P >> 12 & 1)[P & 0xFFF]; + if (P >= 0xFF00 && P < 0xFF80) + return nontrivial_ff_peek(P); + return ioamhram[P - 0xFE00]; +} + +unsigned Memory::nontrivial_ff_peek(const unsigned P) { + // some regs may be somewhat wrong with this + return ioamhram[P - 0xFE00]; +} + +void Memory::nontrivial_ff_write(const unsigned P, unsigned data, const unsigned long cycleCounter) { + if (lastOamDmaUpdate != DISABLED_TIME) + updateOamDma(cycleCounter); + + switch (P & 0xFF) { case 0x00: if ((data ^ ioamhram[0x100]) & 0x30) { ioamhram[0x100] = (ioamhram[0x100] & ~0x30u) | (data & 0x30); updateInput(); } - return; - case 0x01: - updateSerial(cycleCounter); - break; - case 0x02: - updateSerial(cycleCounter); - - serialCnt = 8; - intreq.setEventTime((data & 0x81) == 0x81 - ? (data & isCgb() * 2 ? (cycleCounter & ~0x7ul) + 0x10 * 8 : (cycleCounter & ~0xFFul) + 0x200 * 8) - : static_cast(DISABLED_TIME)); - - data |= 0x7E - isCgb() * 2; - break; - case 0x04: - ioamhram[0x104] = 0; - divLastUpdate = cycleCounter; - return; - case 0x05: - tima.setTima(data, cycleCounter, TimaInterruptRequester(intreq)); - break; - case 0x06: - tima.setTma(data, cycleCounter, TimaInterruptRequester(intreq)); - break; - case 0x07: - data |= 0xF8; - tima.setTac(data, cycleCounter, TimaInterruptRequester(intreq)); - break; - case 0x0F: - updateIrqs(cycleCounter); - intreq.setIfreg(0xE0 | data); - return; - case 0x10: - if (!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr10(data); - data |= 0x80; - break; - case 0x11: - if (!sound.isEnabled()) { - if (isCgb()) - return; - - data &= 0x3F; - } - - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr11(data); - data |= 0x3F; - break; - case 0x12: - if (!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr12(data); - break; - case 0x13: - if (!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr13(data); - return; - case 0x14: - if (!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr14(data); - data |= 0xBF; - break; - case 0x16: - if (!sound.isEnabled()) { - if (isCgb()) - return; - - data &= 0x3F; - } - - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr21(data); - data |= 0x3F; - break; - case 0x17: - if (!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr22(data); - break; - case 0x18: - if (!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr23(data); - return; - case 0x19: - if (!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr24(data); - data |= 0xBF; - break; - case 0x1A: - if (!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr30(data); - data |= 0x7F; - break; - case 0x1B: - if (!sound.isEnabled() && isCgb()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr31(data); - return; - case 0x1C: - if (!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr32(data); - data |= 0x9F; - break; - case 0x1D: - if (!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr33(data); - return; - case 0x1E: - if (!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr34(data); - data |= 0xBF; - break; - case 0x20: - if (!sound.isEnabled() && isCgb()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr41(data); - return; - case 0x21: - if (!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr42(data); - break; - case 0x22: - if (!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr43(data); - break; - case 0x23: - if (!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr44(data); - data |= 0xBF; - break; - case 0x24: - if (!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_so_volume(data); - break; - case 0x25: - if (!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.map_so(data); - break; - case 0x26: - if ((ioamhram[0x126] ^ data) & 0x80) { - sound.generate_samples(cycleCounter, isDoubleSpeed()); - - if (!(data & 0x80)) { - for (unsigned i = 0xFF10; i < 0xFF26; ++i) - ff_write(i, 0, cycleCounter); - - sound.setEnabled(false); - } else { - sound.reset(); - sound.setEnabled(true); - } - } - - data = (data & 0x80) | (ioamhram[0x126] & 0x7F); - break; - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - case 0x38: - case 0x39: - case 0x3A: - case 0x3B: - case 0x3C: - case 0x3D: - case 0x3E: - case 0x3F: - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.waveRamWrite(P & 0xF, data); - break; - case 0x40: - if (ioamhram[0x140] != data) { - if ((ioamhram[0x140] ^ data) & 0x80) { - const unsigned lyc = display.getStat(ioamhram[0x145], cycleCounter) & 4; - const bool hdmaEnabled = display.hdmaIsEnabled(); - - display.lcdcChange(data, cycleCounter); - ioamhram[0x144] = 0; - ioamhram[0x141] &= 0xF8; - - if (data & 0x80) { - intreq.setEventTime(display.nextMode1IrqTime() + (blanklcd ? 0 : 70224 << isDoubleSpeed())); - } else { - ioamhram[0x141] |= lyc; - intreq.setEventTime(cycleCounter + (456 * 4 << isDoubleSpeed())); - - if (hdmaEnabled) - flagHdmaReq(&intreq); - } - } else - display.lcdcChange(data, cycleCounter); - - ioamhram[0x140] = data; - } - - return; - case 0x41: - display.lcdstatChange(data, cycleCounter); - data = (ioamhram[0x141] & 0x87) | (data & 0x78); - break; - case 0x42: - display.scyChange(data, cycleCounter); - break; - case 0x43: - display.scxChange(data, cycleCounter); - break; - case 0x45: - display.lycRegChange(data, cycleCounter); - break; - case 0x46: - if (lastOamDmaUpdate != DISABLED_TIME) - endOamDma(cycleCounter); - - lastOamDmaUpdate = cycleCounter; - intreq.setEventTime(cycleCounter + 8); - ioamhram[0x146] = data; - oamDmaInitSetup(); - return; - case 0x47: - if (!isCgb()) - display.dmgBgPaletteChange(data, cycleCounter); - - break; - case 0x48: - if (!isCgb()) - display.dmgSpPalette1Change(data, cycleCounter); - - break; - case 0x49: - if (!isCgb()) - display.dmgSpPalette2Change(data, cycleCounter); - - break; - case 0x4A: - display.wyChange(data, cycleCounter); - break; - case 0x4B: - display.wxChange(data, cycleCounter); - break; - - case 0x4D: + return; + case 0x01: + updateSerial(cycleCounter); + break; + case 0x02: + updateSerial(cycleCounter); + + serialCnt = 8; + intreq.setEventTime((data & 0x81) == 0x81 + ? (data & isCgb() * 2 ? (cycleCounter & ~0x7ul) + 0x10 * 8 : (cycleCounter & ~0xFFul) + 0x200 * 8) + : static_cast(DISABLED_TIME)); + + data |= 0x7E - isCgb() * 2; + break; + case 0x04: + ioamhram[0x104] = 0; + divLastUpdate = cycleCounter; + return; + case 0x05: + tima.setTima(data, cycleCounter, TimaInterruptRequester(intreq)); + break; + case 0x06: + tima.setTma(data, cycleCounter, TimaInterruptRequester(intreq)); + break; + case 0x07: + data |= 0xF8; + tima.setTac(data, cycleCounter, TimaInterruptRequester(intreq)); + break; + case 0x0F: + updateIrqs(cycleCounter); + intreq.setIfreg(0xE0 | data); + return; + case 0x10: + if (!sound.isEnabled()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr10(data); + data |= 0x80; + break; + case 0x11: + if (!sound.isEnabled()) { + if (isCgb()) + return; + + data &= 0x3F; + } + + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr11(data); + data |= 0x3F; + break; + case 0x12: + if (!sound.isEnabled()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr12(data); + break; + case 0x13: + if (!sound.isEnabled()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr13(data); + return; + case 0x14: + if (!sound.isEnabled()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr14(data); + data |= 0xBF; + break; + case 0x16: + if (!sound.isEnabled()) { + if (isCgb()) + return; + + data &= 0x3F; + } + + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr21(data); + data |= 0x3F; + break; + case 0x17: + if (!sound.isEnabled()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr22(data); + break; + case 0x18: + if (!sound.isEnabled()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr23(data); + return; + case 0x19: + if (!sound.isEnabled()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr24(data); + data |= 0xBF; + break; + case 0x1A: + if (!sound.isEnabled()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr30(data); + data |= 0x7F; + break; + case 0x1B: + if (!sound.isEnabled() && isCgb()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr31(data); + return; + case 0x1C: + if (!sound.isEnabled()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr32(data); + data |= 0x9F; + break; + case 0x1D: + if (!sound.isEnabled()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr33(data); + return; + case 0x1E: + if (!sound.isEnabled()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr34(data); + data |= 0xBF; + break; + case 0x20: + if (!sound.isEnabled() && isCgb()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr41(data); + return; + case 0x21: + if (!sound.isEnabled()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr42(data); + break; + case 0x22: + if (!sound.isEnabled()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr43(data); + break; + case 0x23: + if (!sound.isEnabled()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_nr44(data); + data |= 0xBF; + break; + case 0x24: + if (!sound.isEnabled()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.set_so_volume(data); + break; + case 0x25: + if (!sound.isEnabled()) return; + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.map_so(data); + break; + case 0x26: + if ((ioamhram[0x126] ^ data) & 0x80) { + sound.generate_samples(cycleCounter, isDoubleSpeed()); + + if (!(data & 0x80)) { + for (unsigned i = 0xFF10; i < 0xFF26; ++i) + ff_write(i, 0, cycleCounter); + + sound.setEnabled(false); + } else { + sound.reset(); + sound.setEnabled(true); + } + } + + data = (data & 0x80) | (ioamhram[0x126] & 0x7F); + break; + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x3A: + case 0x3B: + case 0x3C: + case 0x3D: + case 0x3E: + case 0x3F: + sound.generate_samples(cycleCounter, isDoubleSpeed()); + sound.waveRamWrite(P & 0xF, data); + break; + case 0x40: + if (ioamhram[0x140] != data) { + if ((ioamhram[0x140] ^ data) & 0x80) { + const unsigned lyc = display.getStat(ioamhram[0x145], cycleCounter) & 4; + const bool hdmaEnabled = display.hdmaIsEnabled(); + + display.lcdcChange(data, cycleCounter); + ioamhram[0x144] = 0; + ioamhram[0x141] &= 0xF8; + + if (data & 0x80) { + intreq.setEventTime(display.nextMode1IrqTime() + (blanklcd ? 0 : 70224 << isDoubleSpeed())); + } else { + ioamhram[0x141] |= lyc; + intreq.setEventTime(cycleCounter + (456 * 4 << isDoubleSpeed())); + + if (hdmaEnabled) + flagHdmaReq(&intreq); + } + } else + display.lcdcChange(data, cycleCounter); + + ioamhram[0x140] = data; + } + + return; + case 0x41: + display.lcdstatChange(data, cycleCounter); + data = (ioamhram[0x141] & 0x87) | (data & 0x78); + break; + case 0x42: + display.scyChange(data, cycleCounter); + break; + case 0x43: + display.scxChange(data, cycleCounter); + break; + case 0x45: + display.lycRegChange(data, cycleCounter); + break; + case 0x46: + if (lastOamDmaUpdate != DISABLED_TIME) + endOamDma(cycleCounter); + + lastOamDmaUpdate = cycleCounter; + intreq.setEventTime(cycleCounter + 8); + ioamhram[0x146] = data; + oamDmaInitSetup(); + return; + case 0x47: + if (!isCgb()) + display.dmgBgPaletteChange(data, cycleCounter); + + break; + case 0x48: + if (!isCgb()) + display.dmgSpPalette1Change(data, cycleCounter); + + break; + case 0x49: + if (!isCgb()) + display.dmgSpPalette2Change(data, cycleCounter); + + break; + case 0x4A: + display.wyChange(data, cycleCounter); + break; + case 0x4B: + display.wxChange(data, cycleCounter); + break; + + case 0x4D: if (isCgb()) - ioamhram[0x14D] = (ioamhram[0x14D] & ~1u) | (data & 1); return; - case 0x4F: - if (isCgb()) { - cart.setVrambank(data & 1); - ioamhram[0x14F] = 0xFE | data; - } - - return; - case 0x51: - dmaSource = data << 8 | (dmaSource & 0xFF); - return; - case 0x52: - dmaSource = (dmaSource & 0xFF00) | (data & 0xF0); - return; - case 0x53: - dmaDestination = data << 8 | (dmaDestination & 0xFF); - return; - case 0x54: - dmaDestination = (dmaDestination & 0xFF00) | (data & 0xF0); - return; - case 0x55: - if (isCgb()) { - ioamhram[0x155] = data & 0x7F; - - if (display.hdmaIsEnabled()) { - if (!(data & 0x80)) { - ioamhram[0x155] |= 0x80; - display.disableHdma(cycleCounter); - } - } else { - if (data & 0x80) { - if (ioamhram[0x140] & 0x80) { - display.enableHdma(cycleCounter); - } else - flagHdmaReq(&intreq); - } else - flagGdmaReq(&intreq); - } - } - - return; - case 0x56: - if (isCgb()) - ioamhram[0x156] = data | 0x3E; - - return; - case 0x68: - if (isCgb()) - ioamhram[0x168] = data | 0x40; - - return; - case 0x69: - if (isCgb()) { - const unsigned index = ioamhram[0x168] & 0x3F; - - display.cgbBgColorChange(index, data, cycleCounter); - - ioamhram[0x168] = (ioamhram[0x168] & ~0x3F) | ((index + (ioamhram[0x168] >> 7)) & 0x3F); - } - - return; - case 0x6A: - if (isCgb()) - ioamhram[0x16A] = data | 0x40; - - return; - case 0x6B: - if (isCgb()) { - const unsigned index = ioamhram[0x16A] & 0x3F; - - display.cgbSpColorChange(index, data, cycleCounter); - - ioamhram[0x16A] = (ioamhram[0x16A] & ~0x3F) | ((index + (ioamhram[0x16A] >> 7)) & 0x3F); - } - - return; - case 0x6C: - if (isCgb()) - ioamhram[0x16C] = data | 0xFE; - - return; - case 0x70: - if (isCgb()) { - cart.setWrambank((data & 0x07) ? (data & 0x07) : 1); - ioamhram[0x170] = data | 0xF8; - } - - return; - case 0x72: - case 0x73: - case 0x74: - if (isCgb()) - break; - - return; - case 0x75: - if (isCgb()) - ioamhram[0x175] = data | 0x8F; - - return; - case 0xFF: - intreq.setIereg(data); - break; - default: - return; - } - - ioamhram[P - 0xFE00] = data; -} - -void Memory::nontrivial_write(const unsigned P, const unsigned data, const unsigned long cycleCounter) { - if (lastOamDmaUpdate != DISABLED_TIME) { - updateOamDma(cycleCounter); - - if (isInOamDmaConflictArea(cart.oamDmaSrc(), P, isCgb()) && oamDmaPos < 0xA0) { - ioamhram[oamDmaPos] = data; - return; - } - } - - if (P < 0xFE00) { - if (P < 0xA000) { - if (P < 0x8000) { - cart.mbcWrite(P, data); - } else if (display.vramAccessible(cycleCounter)) { - display.vramChange(cycleCounter); - cart.vrambankptr()[P] = data; - } - } else if (P < 0xC000) { - if (cart.wsrambankptr()) - cart.wsrambankptr()[P] = data; - else - cart.rtcWrite(data); - } else - cart.wramdata(P >> 12 & 1)[P & 0xFFF] = data; - } else if (P - 0xFF80u >= 0x7Fu) { - if (P < 0xFF00) { - if (display.oamWritable(cycleCounter) && oamDmaPos >= 0xA0 && (P < 0xFEA0 || isCgb())) { - display.oamChange(cycleCounter); - ioamhram[P - 0xFE00] = data; - } - } else - nontrivial_ff_write(P, data, cycleCounter); - } else - ioamhram[P - 0xFE00] = data; -} - -int Memory::loadROM(const char *romfiledata, unsigned romfilelength, const bool forceDmg, const bool multicartCompat) { - if (const int fail = cart.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat)) - return fail; - - sound.init(cart.isCgb()); - display.reset(ioamhram, cart.vramdata(), cart.isCgb()); - - return 0; -} - -unsigned Memory::fillSoundBuffer(const unsigned long cycleCounter) { - sound.generate_samples(cycleCounter, isDoubleSpeed()); - return sound.fillBuffer(); -} - -void Memory::setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32) { - display.setDmgPaletteColor(palNum, colorNum, rgb32); -} - -void Memory::setCgbPalette(unsigned *lut) { - display.setCgbPalette(lut); -} - -bool Memory::getMemoryArea(int which, unsigned char **data, int *length) { - if (!data || !length) - return false; - - switch (which) - { - case 4: // oam - *data = &ioamhram[0]; - *length = 160; - return true; - case 5: // hram - *data = &ioamhram[384]; - *length = 128; - return true; - case 6: // bgpal - *data = (unsigned char *)display.bgPalette(); - *length = 32; - return true; - case 7: // sppal - *data = (unsigned char *)display.spPalette(); - *length = 32; - return true; - default: // pass to cartridge - return cart.getMemoryArea(which, data, length); - } -} - -int Memory::LinkStatus(int which) -{ - switch (which) - { - case 256: // ClockSignaled - return linkClockTrigger; - case 257: // AckClockSignal - linkClockTrigger = false; - return 0; - case 258: // GetOut - return ioamhram[0x101] & 0xff; - case 259: // connect link cable - LINKCABLE = true; - return 0; - default: // ShiftIn - if (ioamhram[0x102] & 0x80) // was enabled - { - ioamhram[0x101] = which; - ioamhram[0x102] &= 0x7F; - intreq.flagIrq(8); - } - return 0; - } - - return -1; -} - + ioamhram[0x14D] = (ioamhram[0x14D] & ~1u) | (data & 1); return; + case 0x4F: + if (isCgb()) { + cart.setVrambank(data & 1); + ioamhram[0x14F] = 0xFE | data; + } + + return; + case 0x50: + // this is the register that turns off the bootrom + // it can only ever be written to once (with 1) once boot rom finishes + cart.bios_remap(data); + return; + case 0x51: + dmaSource = data << 8 | (dmaSource & 0xFF); + return; + case 0x52: + dmaSource = (dmaSource & 0xFF00) | (data & 0xF0); + return; + case 0x53: + dmaDestination = data << 8 | (dmaDestination & 0xFF); + return; + case 0x54: + dmaDestination = (dmaDestination & 0xFF00) | (data & 0xF0); + return; + case 0x55: + if (isCgb()) { + ioamhram[0x155] = data & 0x7F; + + if (display.hdmaIsEnabled()) { + if (!(data & 0x80)) { + ioamhram[0x155] |= 0x80; + display.disableHdma(cycleCounter); + } + } else { + if (data & 0x80) { + if (ioamhram[0x140] & 0x80) { + display.enableHdma(cycleCounter); + } else + flagHdmaReq(&intreq); + } else + flagGdmaReq(&intreq); + } + } + + return; + case 0x56: + if (isCgb()) + ioamhram[0x156] = data | 0x3E; + + return; + case 0x68: + if (isCgb()) + ioamhram[0x168] = data | 0x40; + + return; + case 0x69: + if (isCgb()) { + const unsigned index = ioamhram[0x168] & 0x3F; + + display.cgbBgColorChange(index, data, cycleCounter); + + ioamhram[0x168] = (ioamhram[0x168] & ~0x3F) | ((index + (ioamhram[0x168] >> 7)) & 0x3F); + } + + return; + case 0x6A: + if (isCgb()) + ioamhram[0x16A] = data | 0x40; + + return; + case 0x6B: + if (isCgb()) { + const unsigned index = ioamhram[0x16A] & 0x3F; + + display.cgbSpColorChange(index, data, cycleCounter); + + ioamhram[0x16A] = (ioamhram[0x16A] & ~0x3F) | ((index + (ioamhram[0x16A] >> 7)) & 0x3F); + } + + return; + case 0x6C: + if (isCgb()) + ioamhram[0x16C] = data | 0xFE; + + return; + case 0x70: + if (isCgb()) { + cart.setWrambank((data & 0x07) ? (data & 0x07) : 1); + ioamhram[0x170] = data | 0xF8; + } + + return; + case 0x72: + case 0x73: + case 0x74: + if (isCgb()) + break; + + return; + case 0x75: + if (isCgb()) + ioamhram[0x175] = data | 0x8F; + + return; + case 0xFF: + intreq.setIereg(data); + break; + default: + return; + } + + ioamhram[P - 0xFE00] = data; +} + +void Memory::nontrivial_write(const unsigned P, const unsigned data, const unsigned long cycleCounter) { + if (lastOamDmaUpdate != DISABLED_TIME) { + updateOamDma(cycleCounter); + + if (isInOamDmaConflictArea(cart.oamDmaSrc(), P, isCgb()) && oamDmaPos < 0xA0) { + ioamhram[oamDmaPos] = data; + return; + } + } + + if (P < 0xFE00) { + if (P < 0xA000) { + if (P < 0x8000) { + cart.mbcWrite(P, data); + } else if (display.vramAccessible(cycleCounter)) { + display.vramChange(cycleCounter); + cart.vrambankptr()[P] = data; + } + } else if (P < 0xC000) { + if (cart.wsrambankptr()) + cart.wsrambankptr()[P] = data; + else + cart.rtcWrite(data); + } else + cart.wramdata(P >> 12 & 1)[P & 0xFFF] = data; + } else if (P - 0xFF80u >= 0x7Fu) { + if (P < 0xFF00) { + if (display.oamWritable(cycleCounter) && oamDmaPos >= 0xA0 && (P < 0xFEA0 || isCgb())) { + display.oamChange(cycleCounter); + ioamhram[P - 0xFE00] = data; + } + } else + nontrivial_ff_write(P, data, cycleCounter); + } else + ioamhram[P - 0xFE00] = data; +} + +int Memory::loadROM(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, const bool forceDmg, const bool multicartCompat) { + if (const int fail = cart.loadROM(romfiledata, romfilelength, biosfiledata, biosfilelength, forceDmg, multicartCompat)) + return fail; + + sound.init(cart.isCgb()); + display.reset(ioamhram, cart.vramdata(), cart.isCgb()); + + return 0; +} + +unsigned Memory::fillSoundBuffer(const unsigned long cycleCounter) { + sound.generate_samples(cycleCounter, isDoubleSpeed()); + return sound.fillBuffer(); +} + +void Memory::setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32) { + display.setDmgPaletteColor(palNum, colorNum, rgb32); +} + +void Memory::setCgbPalette(unsigned *lut) { + display.setCgbPalette(lut); +} + +bool Memory::getMemoryArea(int which, unsigned char **data, int *length) { + if (!data || !length) + return false; + + switch (which) + { + case 4: // oam + *data = &ioamhram[0]; + *length = 160; + return true; + case 5: // hram + *data = &ioamhram[384]; + *length = 128; + return true; + case 6: // bgpal + *data = (unsigned char *)display.bgPalette(); + *length = 32; + return true; + case 7: // sppal + *data = (unsigned char *)display.spPalette(); + *length = 32; + return true; + default: // pass to cartridge + return cart.getMemoryArea(which, data, length); + } +} + +int Memory::LinkStatus(int which) +{ + switch (which) + { + case 256: // ClockSignaled + return linkClockTrigger; + case 257: // AckClockSignal + linkClockTrigger = false; + return 0; + case 258: // GetOut + return ioamhram[0x101] & 0xff; + case 259: // connect link cable + LINKCABLE = true; + return 0; + default: // ShiftIn + if (ioamhram[0x102] & 0x80) // was enabled + { + ioamhram[0x101] = which; + ioamhram[0x102] &= 0x7F; + intreq.flagIrq(8); + } + return 0; + } + + return -1; +} + SYNCFUNC(Memory) { SSS(cart); @@ -1107,5 +1112,5 @@ SYNCFUNC(Memory) NSS(LINKCABLE); NSS(linkClockTrigger); } - -} + +} diff --git a/libgambatte/src/memory.h b/libgambatte/src/memory.h index bbf9e89c6d..78a89a0ee4 100644 --- a/libgambatte/src/memory.h +++ b/libgambatte/src/memory.h @@ -1,293 +1,297 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef MEMORY_H -#define MEMORY_H - -#include "mem/cartridge.h" -#include "video.h" -#include "sound.h" -#include "interrupter.h" -#include "tima.h" +/*************************************************************************** + * Copyright (C) 2007 by Sindre Aamås * + * aamas@stud.ntnu.no * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License version 2 as * + * published by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License version 2 for more details. * + * * + * You should have received a copy of the GNU General Public License * + * version 2 along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef MEMORY_H +#define MEMORY_H + +#include "mem/cartridge.h" +#include "video.h" +#include "sound.h" +#include "interrupter.h" +#include "tima.h" #include "newstate.h" #include "gambatte.h" - -namespace gambatte { -class InputGetter; -class FilterInfo; - -class Memory { - Cartridge cart; - unsigned char ioamhram[0x200]; - - void (*readCallback)(unsigned); - void (*writeCallback)(unsigned); - void (*execCallback)(unsigned); - CDCallback cdCallback; - - unsigned (*getInput)(); - unsigned long divLastUpdate; - unsigned long lastOamDmaUpdate; - - InterruptRequester intreq; - Tima tima; - LCD display; - PSG sound; - Interrupter interrupter; - - unsigned short dmaSource; - unsigned short dmaDestination; - unsigned char oamDmaPos; - unsigned char serialCnt; - bool blanklcd; - - bool LINKCABLE; - bool linkClockTrigger; - - void decEventCycles(MemEventId eventId, unsigned long dec); - - void oamDmaInitSetup(); - void updateOamDma(unsigned long cycleCounter); - void startOamDma(unsigned long cycleCounter); - void endOamDma(unsigned long cycleCounter); - const unsigned char * oamDmaSrcPtr() const; - - unsigned nontrivial_ff_read(unsigned P, unsigned long cycleCounter); - unsigned nontrivial_read(unsigned P, unsigned long cycleCounter); - void nontrivial_ff_write(unsigned P, unsigned data, unsigned long cycleCounter); - void nontrivial_write(unsigned P, unsigned data, unsigned long cycleCounter); - - unsigned nontrivial_peek(unsigned P); - unsigned nontrivial_ff_peek(unsigned P); - - void updateSerial(unsigned long cc); - void updateTimaIrq(unsigned long cc); - void updateIrqs(unsigned long cc); - - bool isDoubleSpeed() const { return display.isDoubleSpeed(); } - -public: - explicit Memory(const Interrupter &interrupter); - - bool loaded() const { return cart.loaded(); } - const char * romTitle() const { return cart.romTitle(); } - - int debugGetLY() const { return display.debugGetLY(); } - - void setStatePtrs(SaveState &state); - void loadState(const SaveState &state/*, unsigned long oldCc*/); - void loadSavedata(const char *data) { cart.loadSavedata(data); } - int saveSavedataLength() {return cart.saveSavedataLength(); } - void saveSavedata(char *dest) { cart.saveSavedata(dest); } - void updateInput(); - - bool getMemoryArea(int which, unsigned char **data, int *length); // { return cart.getMemoryArea(which, data, length); } - - unsigned long stop(unsigned long cycleCounter); - bool isCgb() const { return display.isCgb(); } - bool ime() const { return intreq.ime(); } - bool halted() const { return intreq.halted(); } - unsigned long nextEventTime() const { return intreq.minEventTime(); } - - void setLayers(unsigned mask) { display.setLayers(mask); } - - bool isActive() const { return intreq.eventTime(END) != DISABLED_TIME; } - - long cyclesSinceBlit(const unsigned long cc) const { - return cc < intreq.eventTime(BLIT) ? -1 : static_cast((cc - intreq.eventTime(BLIT)) >> isDoubleSpeed()); - } - - void halt() { intreq.halt(); } - void ei(unsigned long cycleCounter) { if (!ime()) { intreq.ei(cycleCounter); } } - - void di() { intreq.di(); } - - unsigned ff_read(const unsigned P, const unsigned long cycleCounter) { - return P < 0xFF80 ? nontrivial_ff_read(P, cycleCounter) : ioamhram[P - 0xFE00]; - } - - struct CDMapResult - { - eCDLog_AddrType type; - unsigned addr; - }; - - CDMapResult CDMap(const unsigned P) const - { - if(P<0x4000) - { - CDMapResult ret = { eCDLog_AddrType_ROM, P }; - return ret; - } - else if(P<0x8000) - { - unsigned bank = cart.rmem(P>>12) - cart.rmem(0); - unsigned addr = P+bank; - CDMapResult ret = { eCDLog_AddrType_ROM, addr }; - return ret; - } - else if(P<0xA000) {} - else if(P<0xC000) - { - if(cart.wsrambankptr()) - { - //not bankable. but. we're not sure how much might be here - unsigned char *data; - int length; - bool has = cart.getMemoryArea(3,&data,&length); - unsigned addr = P&(length-1); - if(has && length!=0) - { - CDMapResult ret = { eCDLog_AddrType_CartRAM, addr }; - return ret; - } - } - } - else if(P<0xE000) - { - unsigned bank = cart.wramdata(P >> 12 & 1) - cart.wramdata(0); - unsigned addr = (P&0xFFF)+bank; - CDMapResult ret = { eCDLog_AddrType_WRAM, addr }; - return ret; - } - else if(P<0xFF80) {} - else - { - ////this is just for debugging, really, it's pretty useless - //CDMapResult ret = { eCDLog_AddrType_HRAM, (P-0xFF80) }; - //return ret; - } - - CDMapResult ret = { eCDLog_AddrType_None }; - return ret; - } - - - unsigned read(const unsigned P, const unsigned long cycleCounter) { - if (readCallback) - readCallback(P); - if(cdCallback) - { - CDMapResult map = CDMap(P); - if(map.type != eCDLog_AddrType_None) - cdCallback(map.addr,map.type,eCDLog_Flags_Data); - } - return cart.rmem(P >> 12) ? cart.rmem(P >> 12)[P] : nontrivial_read(P, cycleCounter); - } - - unsigned read_excb(const unsigned P, const unsigned long cycleCounter, bool first) { - if (execCallback) - execCallback(P); - if(cdCallback) - { - CDMapResult map = CDMap(P); - if(map.type != eCDLog_AddrType_None) - cdCallback(map.addr,map.type,first?eCDLog_Flags_ExecFirst : eCDLog_Flags_ExecOperand); - } - return cart.rmem(P >> 12) ? cart.rmem(P >> 12)[P] : nontrivial_read(P, cycleCounter); - } - - unsigned peek(const unsigned P) { - return cart.rmem(P >> 12) ? cart.rmem(P >> 12)[P] : nontrivial_peek(P); - } - - void write_nocb(const unsigned P, const unsigned data, const unsigned long cycleCounter) { - if (cart.wmem(P >> 12)) { - cart.wmem(P >> 12)[P] = data; - } else - nontrivial_write(P, data, cycleCounter); - } - - void write(const unsigned P, const unsigned data, const unsigned long cycleCounter) { - if (cart.wmem(P >> 12)) { - cart.wmem(P >> 12)[P] = data; - } else - nontrivial_write(P, data, cycleCounter); - if (writeCallback) - writeCallback(P); - if(cdCallback) - { - CDMapResult map = CDMap(P); - if(map.type != eCDLog_AddrType_None) - cdCallback(map.addr,map.type,eCDLog_Flags_Data); - } - } - - void ff_write(const unsigned P, const unsigned data, const unsigned long cycleCounter) { - if (P - 0xFF80u < 0x7Fu) { - ioamhram[P - 0xFE00] = data; - } else - nontrivial_ff_write(P, data, cycleCounter); - if(cdCallback) - { - CDMapResult map = CDMap(P); - if(map.type != eCDLog_AddrType_None) - cdCallback(map.addr,map.type,eCDLog_Flags_Data); - } - } - - unsigned long event(unsigned long cycleCounter); - unsigned long resetCounters(unsigned long cycleCounter); - - int loadROM(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat); - - void setInputGetter(unsigned (*getInput)()) { - this->getInput = getInput; - } - - void setReadCallback(void (*callback)(unsigned)) { - this->readCallback = callback; - } - void setWriteCallback(void (*callback)(unsigned)) { - this->writeCallback = callback; - } - void setExecCallback(void (*callback)(unsigned)) { - this->execCallback = callback; - } - void setCDCallback(CDCallback cdc) { - this->cdCallback = cdc; - } - - void setScanlineCallback(void (*callback)(), int sl) { - display.setScanlineCallback(callback, sl); - } - - void setRTCCallback(std::uint32_t (*callback)()) { - cart.setRTCCallback(callback); - } - - void setEndtime(unsigned long cc, unsigned long inc); - - void setSoundBuffer(uint_least32_t *const buf) { sound.setBuffer(buf); } - unsigned fillSoundBuffer(unsigned long cc); - - void setVideoBuffer(uint_least32_t *const videoBuf, const int pitch) { - display.setVideoBuffer(videoBuf, pitch); - } - - void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32); - void setCgbPalette(unsigned *lut); - - int LinkStatus(int which); - + +namespace gambatte { +class InputGetter; +class FilterInfo; + +class Memory { + Cartridge cart; + unsigned char ioamhram[0x200]; + + void (*readCallback)(unsigned); + void (*writeCallback)(unsigned); + void (*execCallback)(unsigned); + CDCallback cdCallback; + + unsigned (*getInput)(); + unsigned long divLastUpdate; + unsigned long lastOamDmaUpdate; + + InterruptRequester intreq; + Tima tima; + LCD display; + PSG sound; + Interrupter interrupter; + + unsigned short dmaSource; + unsigned short dmaDestination; + unsigned char oamDmaPos; + unsigned char serialCnt; + bool blanklcd; + + bool LINKCABLE; + bool linkClockTrigger; + + void decEventCycles(MemEventId eventId, unsigned long dec); + + void oamDmaInitSetup(); + void updateOamDma(unsigned long cycleCounter); + void startOamDma(unsigned long cycleCounter); + void endOamDma(unsigned long cycleCounter); + const unsigned char * oamDmaSrcPtr() const; + + unsigned nontrivial_ff_read(unsigned P, unsigned long cycleCounter); + unsigned nontrivial_read(unsigned P, unsigned long cycleCounter); + void nontrivial_ff_write(unsigned P, unsigned data, unsigned long cycleCounter); + void nontrivial_write(unsigned P, unsigned data, unsigned long cycleCounter); + + unsigned nontrivial_peek(unsigned P); + unsigned nontrivial_ff_peek(unsigned P); + + void updateSerial(unsigned long cc); + void updateTimaIrq(unsigned long cc); + void updateIrqs(unsigned long cc); + + bool isDoubleSpeed() const { return display.isDoubleSpeed(); } + +public: + explicit Memory(const Interrupter &interrupter); + + bool loaded() const { return cart.loaded(); } + const char * romTitle() const { return cart.romTitle(); } + + void bios_reset(int setting) { + nontrivial_ff_write(0x50, setting, 0); + } + + int debugGetLY() const { return display.debugGetLY(); } + + void setStatePtrs(SaveState &state); + void loadState(const SaveState &state/*, unsigned long oldCc*/); + void loadSavedata(const char *data) { cart.loadSavedata(data); } + int saveSavedataLength() {return cart.saveSavedataLength(); } + void saveSavedata(char *dest) { cart.saveSavedata(dest); } + void updateInput(); + + bool getMemoryArea(int which, unsigned char **data, int *length); // { return cart.getMemoryArea(which, data, length); } + + unsigned long stop(unsigned long cycleCounter); + bool isCgb() const { return display.isCgb(); } + bool ime() const { return intreq.ime(); } + bool halted() const { return intreq.halted(); } + unsigned long nextEventTime() const { return intreq.minEventTime(); } + + void setLayers(unsigned mask) { display.setLayers(mask); } + + bool isActive() const { return intreq.eventTime(END) != DISABLED_TIME; } + + long cyclesSinceBlit(const unsigned long cc) const { + return cc < intreq.eventTime(BLIT) ? -1 : static_cast((cc - intreq.eventTime(BLIT)) >> isDoubleSpeed()); + } + + void halt() { intreq.halt(); } + void ei(unsigned long cycleCounter) { if (!ime()) { intreq.ei(cycleCounter); } } + + void di() { intreq.di(); } + + unsigned ff_read(const unsigned P, const unsigned long cycleCounter) { + return P < 0xFF80 ? nontrivial_ff_read(P, cycleCounter) : ioamhram[P - 0xFE00]; + } + + struct CDMapResult + { + eCDLog_AddrType type; + unsigned addr; + }; + + CDMapResult CDMap(const unsigned P) const + { + if(P<0x4000) + { + CDMapResult ret = { eCDLog_AddrType_ROM, P }; + return ret; + } + else if(P<0x8000) + { + unsigned bank = cart.rmem(P>>12) - cart.rmem(0); + unsigned addr = P+bank; + CDMapResult ret = { eCDLog_AddrType_ROM, addr }; + return ret; + } + else if(P<0xA000) {} + else if(P<0xC000) + { + if(cart.wsrambankptr()) + { + //not bankable. but. we're not sure how much might be here + unsigned char *data; + int length; + bool has = cart.getMemoryArea(3,&data,&length); + unsigned addr = P&(length-1); + if(has && length!=0) + { + CDMapResult ret = { eCDLog_AddrType_CartRAM, addr }; + return ret; + } + } + } + else if(P<0xE000) + { + unsigned bank = cart.wramdata(P >> 12 & 1) - cart.wramdata(0); + unsigned addr = (P&0xFFF)+bank; + CDMapResult ret = { eCDLog_AddrType_WRAM, addr }; + return ret; + } + else if(P<0xFF80) {} + else + { + ////this is just for debugging, really, it's pretty useless + //CDMapResult ret = { eCDLog_AddrType_HRAM, (P-0xFF80) }; + //return ret; + } + + CDMapResult ret = { eCDLog_AddrType_None }; + return ret; + } + + + unsigned read(const unsigned P, const unsigned long cycleCounter) { + if (readCallback) + readCallback(P); + if(cdCallback) + { + CDMapResult map = CDMap(P); + if(map.type != eCDLog_AddrType_None) + cdCallback(map.addr,map.type,eCDLog_Flags_Data); + } + return cart.rmem(P >> 12) ? cart.rmem(P >> 12)[P] : nontrivial_read(P, cycleCounter); + } + + unsigned read_excb(const unsigned P, const unsigned long cycleCounter, bool first) { + if (execCallback) + execCallback(P); + if(cdCallback) + { + CDMapResult map = CDMap(P); + if(map.type != eCDLog_AddrType_None) + cdCallback(map.addr,map.type,first?eCDLog_Flags_ExecFirst : eCDLog_Flags_ExecOperand); + } + return cart.rmem(P >> 12) ? cart.rmem(P >> 12)[P] : nontrivial_read(P, cycleCounter); + } + + unsigned peek(const unsigned P) { + return cart.rmem(P >> 12) ? cart.rmem(P >> 12)[P] : nontrivial_peek(P); + } + + void write_nocb(const unsigned P, const unsigned data, const unsigned long cycleCounter) { + if (cart.wmem(P >> 12)) { + cart.wmem(P >> 12)[P] = data; + } else + nontrivial_write(P, data, cycleCounter); + } + + void write(const unsigned P, const unsigned data, const unsigned long cycleCounter) { + if (cart.wmem(P >> 12)) { + cart.wmem(P >> 12)[P] = data; + } else + nontrivial_write(P, data, cycleCounter); + if (writeCallback) + writeCallback(P); + if(cdCallback) + { + CDMapResult map = CDMap(P); + if(map.type != eCDLog_AddrType_None) + cdCallback(map.addr,map.type,eCDLog_Flags_Data); + } + } + + void ff_write(const unsigned P, const unsigned data, const unsigned long cycleCounter) { + if (P - 0xFF80u < 0x7Fu) { + ioamhram[P - 0xFE00] = data; + } else + nontrivial_ff_write(P, data, cycleCounter); + if(cdCallback) + { + CDMapResult map = CDMap(P); + if(map.type != eCDLog_AddrType_None) + cdCallback(map.addr,map.type,eCDLog_Flags_Data); + } + } + + unsigned long event(unsigned long cycleCounter); + unsigned long resetCounters(unsigned long cycleCounter); + + int loadROM(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, bool forceDmg, bool multicartCompat); + + void setInputGetter(unsigned (*getInput)()) { + this->getInput = getInput; + } + + void setReadCallback(void (*callback)(unsigned)) { + this->readCallback = callback; + } + void setWriteCallback(void (*callback)(unsigned)) { + this->writeCallback = callback; + } + void setExecCallback(void (*callback)(unsigned)) { + this->execCallback = callback; + } + void setCDCallback(CDCallback cdc) { + this->cdCallback = cdc; + } + + void setScanlineCallback(void (*callback)(), int sl) { + display.setScanlineCallback(callback, sl); + } + + void setRTCCallback(std::uint32_t (*callback)()) { + cart.setRTCCallback(callback); + } + + void setEndtime(unsigned long cc, unsigned long inc); + + void setSoundBuffer(uint_least32_t *const buf) { sound.setBuffer(buf); } + unsigned fillSoundBuffer(unsigned long cc); + + void setVideoBuffer(uint_least32_t *const videoBuf, const int pitch) { + display.setVideoBuffer(videoBuf, pitch); + } + + void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32); + void setCgbPalette(unsigned *lut); + + int LinkStatus(int which); + templatevoid SyncState(NewState *ns); -}; - -} - -#endif +}; + +} + +#endif diff --git a/libgambatte/src/savestate.h b/libgambatte/src/savestate.h index 4110161ca0..be3f21322a 100644 --- a/libgambatte/src/savestate.h +++ b/libgambatte/src/savestate.h @@ -38,7 +38,7 @@ struct SaveState { void set(T *ptr, const unsigned long sz) { this->ptr = ptr; this->sz = sz; } friend class SaverList; - friend void setInitState(SaveState &, bool, bool, std::uint32_t); + friend void setInitState(SaveState &, bool, bool, std::uint32_t, bool); }; struct CPU { @@ -78,6 +78,7 @@ struct SaveState { bool enableRam; bool rambankMode; bool hdmaTransfer; + bool using_bios; } mem; struct PPU { diff --git a/libmupen64plus/D3D8Interceptor/D3D8Interceptor/D3D8Interceptor.vcxproj b/libmupen64plus/D3D8Interceptor/D3D8Interceptor/D3D8Interceptor.vcxproj index 9680c2965d..5e0e1c357b 100644 --- a/libmupen64plus/D3D8Interceptor/D3D8Interceptor/D3D8Interceptor.vcxproj +++ b/libmupen64plus/D3D8Interceptor/D3D8Interceptor/D3D8Interceptor.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {4CC85A3A-8E85-45DB-8941-2E2E18FC9A53} @@ -22,6 +30,12 @@ v100 MultiByte + + DynamicLibrary + true + v100 + MultiByte + DynamicLibrary false @@ -30,15 +44,29 @@ MultiByte Dynamic + + DynamicLibrary + false + v100 + true + MultiByte + Dynamic + + + + + + + false @@ -46,11 +74,22 @@ true d3d8 + + false + $(SolutionDir)..\..\..\..\output\dll\ + true + d3d8 + $(SolutionDir)..\..\..\..\output\dll\ true d3d8 + + $(SolutionDir)..\..\..\..\output\dll\ + true + d3d8 + Level3 @@ -69,6 +108,24 @@ + + + Level3 + Disabled + true + false + %(AdditionalIncludeDirectories) + WIN32;DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + + + Windows + true + + + + + + Level3 @@ -93,6 +150,31 @@ + + + Level3 + MaxSpeed + + + false + %(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + + + true + + + true + true + true + %(AdditionalDependencies) + Windows + + + + + + diff --git a/libmupen64plus/GLideN64 b/libmupen64plus/GLideN64 index 90ade303dc..e944753875 160000 --- a/libmupen64plus/GLideN64 +++ b/libmupen64plus/GLideN64 @@ -1 +1 @@ -Subproject commit 90ade303dc3a398aff347fd35a81b8f6b292357e +Subproject commit e94475387505141fc8d4b4107f6db09dae9e106f diff --git a/libmupen64plus/deps/libs/libboost_filesystem-vc100-mt-1_57.lib b/libmupen64plus/deps/libs/libboost_filesystem-vc100-mt-1_57.lib new file mode 100644 index 0000000000..f1c859e89f Binary files /dev/null and b/libmupen64plus/deps/libs/libboost_filesystem-vc100-mt-1_57.lib differ diff --git a/libmupen64plus/deps/libs/libboost_filesystem-vc100-mt-gd-1_57.lib b/libmupen64plus/deps/libs/libboost_filesystem-vc100-mt-gd-1_57.lib new file mode 100644 index 0000000000..049c070fd4 Binary files /dev/null and b/libmupen64plus/deps/libs/libboost_filesystem-vc100-mt-gd-1_57.lib differ diff --git a/libmupen64plus/deps/libs/libboost_system-vc100-mt-1_57.lib b/libmupen64plus/deps/libs/libboost_system-vc100-mt-1_57.lib new file mode 100644 index 0000000000..4c2b31210c Binary files /dev/null and b/libmupen64plus/deps/libs/libboost_system-vc100-mt-1_57.lib differ diff --git a/libmupen64plus/deps/libs/libboost_system-vc100-mt-gd-1_57.lib b/libmupen64plus/deps/libs/libboost_system-vc100-mt-gd-1_57.lib new file mode 100644 index 0000000000..bff439d6e6 Binary files /dev/null and b/libmupen64plus/deps/libs/libboost_system-vc100-mt-gd-1_57.lib differ diff --git a/libmupen64plus/mupen64plus-audio-bkm/mupen64plus-audio-bkm/mupen64plus-audio-bkm.vcxproj b/libmupen64plus/mupen64plus-audio-bkm/mupen64plus-audio-bkm/mupen64plus-audio-bkm.vcxproj index 43a6b4621e..011d4cebd7 100644 --- a/libmupen64plus/mupen64plus-audio-bkm/mupen64plus-audio-bkm/mupen64plus-audio-bkm.vcxproj +++ b/libmupen64plus/mupen64plus-audio-bkm/mupen64plus-audio-bkm/mupen64plus-audio-bkm.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {B6F20769-1385-4C0F-91A9-26F47AD1E78F} @@ -20,28 +28,51 @@ true MultiByte + + DynamicLibrary + true + MultiByte + DynamicLibrary false true MultiByte + + DynamicLibrary + false + true + MultiByte + + + + + + + $(SolutionDir)..\..\..\..\output\dll\ + + $(SolutionDir)..\..\..\..\output\dll\ + $(SolutionDir)..\..\..\..\output\dll\ + + $(SolutionDir)..\..\..\..\output\dll\ + Level3 @@ -59,6 +90,23 @@ + + + Level3 + Disabled + ..\..\mupen64plus-core\src\api;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + false + + + true + + + + + + Level3 @@ -81,6 +129,29 @@ + + + Level3 + MaxSpeed + + + false + ..\..\mupen64plus-core\src\api;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + + + true + + + true + true + true + + + + + + diff --git a/libmupen64plus/mupen64plus-core/projects/msvc11/mupen64plus-core.vcxproj b/libmupen64plus/mupen64plus-core/projects/msvc11/mupen64plus-core.vcxproj index abb1572891..e433e456d7 100644 --- a/libmupen64plus/mupen64plus-core/projects/msvc11/mupen64plus-core.vcxproj +++ b/libmupen64plus/mupen64plus-core/projects/msvc11/mupen64plus-core.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {92D3FEB9-2129-41C5-8577-BCD7D961EF41} @@ -22,46 +30,81 @@ true v100 + + DynamicLibrary + MultiByte + true + v100 + DynamicLibrary MultiByte v100 + + DynamicLibrary + MultiByte + v100 + + + + + + + <_ProjectFileVersion>10.0.40219.1 $(SolutionDir)..\..\..\..\output\dll\ + $(SolutionDir)..\..\..\..\output\dll\ $(Configuration)\ + $(Configuration)\ true + true $(SolutionDir)..\..\..\..\output\dll\ + $(SolutionDir)..\..\..\..\output\dll\ $(Configuration)\ + $(Configuration)\ false + false AllRules.ruleset + AllRules.ruleset + + AllRules.ruleset + AllRules.ruleset + + mupen64plus + + mupen64plus + mupen64plus + + mupen64plus + Disabled - ..\..\src;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\include;..\..\..\mupen64plus-win32-deps\freetype-2.3.5-1\include;%(AdditionalIncludeDirectories) + ..\..\src;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\include;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\include;..\..\..\mupen64plus-win32-deps\freetype-2.6\include;%(AdditionalIncludeDirectories) DBG;WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;DYNAREC;M64P_OSD;M64P_PARALLEL;%(PreprocessorDefinitions) false EnableFastChecks @@ -74,7 +117,7 @@ true - winmm.lib;shell32.lib;opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\lib\zlib.lib;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\lib\libpng.lib;..\..\..\mupen64plus-win32-deps\freetype-2.3.5-1\lib\freetype.lib;%(AdditionalDependencies) + winmm.lib;shell32.lib;opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\SDL.lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\lib\zlib.lib;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\lib\libpng.lib;..\..\..\mupen64plus-win32-deps\freetype-2.6\lib\freetype.lib;%(AdditionalDependencies) $(OutDir)mupen64plus.dll true Windows @@ -85,10 +128,41 @@ + + + Disabled + ..\..\src;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\include;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\include;..\..\..\mupen64plus-win32-deps\freetype-2.6\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;DYNAREC;M64P_OSD;M64P_PARALLEL;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + Default + true + + + winmm.lib;shell32.lib;opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\x64\SDL.lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\lib\x64\zlib.lib;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\lib\x64\libpng16.lib;..\..\..\mupen64plus-win32-deps\freetype-2.6\lib\x64\freetype26.lib;%(AdditionalDependencies) + $(OutDir)mupen64plus.dll + true + Windows + + + + + + +<<<<<<< HEAD + ..\..\src;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\include;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\include;..\..\..\mupen64plus-win32-deps\freetype-2.6\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;DYNAREC;M64P_OSD;M64P_PARALLEL;%(PreprocessorDefinitions) +======= ..\..\src;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\include;..\..\..\mupen64plus-win32-deps\freetype-2.3.5-1\include;%(AdditionalIncludeDirectories) DBG;WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;DYNAREC;M64P_OSD;M64P_PARALLEL;%(PreprocessorDefinitions) +>>>>>>> master MultiThreadedDLL @@ -97,7 +171,7 @@ true - winmm.lib;shell32.lib;opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\lib\zlib.lib;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\lib\libpng.lib;..\..\..\mupen64plus-win32-deps\freetype-2.3.5-1\lib\freetype.lib;%(AdditionalDependencies) + winmm.lib;shell32.lib;opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\SDL.lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\lib\zlib.lib;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\lib\libpng.lib;..\..\..\mupen64plus-win32-deps\freetype-2.6\lib\freetype.lib;%(AdditionalDependencies) $(OutDir)mupen64plus.dll true Windows @@ -111,6 +185,31 @@ + + + ..\..\src;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\include;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\include;..\..\..\mupen64plus-win32-deps\freetype-2.6\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;DYNAREC;M64P_OSD;M64P_PARALLEL;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + Default + true + + + winmm.lib;shell32.lib;opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\x64\SDL.lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\lib\x64\zlib.lib;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\lib\x64\libpng16.lib;..\..\..\mupen64plus-win32-deps\freetype-2.6\lib\x64\freetype26.lib;%(AdditionalDependencies) + $(OutDir)mupen64plus.dll + true + Windows + true + true + /PDBALTPATH:%_PDB%.%_EXT% %(AdditionalOptions) + + + + + + @@ -122,9 +221,13 @@ $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.obj $(IntDir)%(Filename)1.xdc + $(IntDir)%(Filename)1.xdc $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.obj $(IntDir)%(Filename)1.xdc + $(IntDir)%(Filename)1.xdc diff --git a/libmupen64plus/mupen64plus-core/src/osal/preproc.h b/libmupen64plus/mupen64plus-core/src/osal/preproc.h index d6ad2b191d..445ab30977 100644 --- a/libmupen64plus/mupen64plus-core/src/osal/preproc.h +++ b/libmupen64plus/mupen64plus-core/src/osal/preproc.h @@ -27,7 +27,7 @@ #if defined(WIN32) && !defined(__MINGW32__) // macros - #define OSAL_BREAKPOINT_INTERRUPT __asm{ int 3 }; + #define OSAL_BREAKPOINT_INTERRUPT DebugBreak(); #define ALIGN(BYTES,DATA) __declspec(align(BYTES)) DATA; #define osal_inline __inline diff --git a/libmupen64plus/mupen64plus-core/src/r4300/fpu.h b/libmupen64plus/mupen64plus-core/src/r4300/fpu.h index e2933bd993..8f4ddce8fd 100644 --- a/libmupen64plus/mupen64plus-core/src/r4300/fpu.h +++ b/libmupen64plus/mupen64plus-core/src/r4300/fpu.h @@ -31,7 +31,8 @@ { static const unsigned int msRound[4] = { _RC_NEAR, _RC_CHOP, _RC_UP, _RC_DOWN }; unsigned int oldX87, oldSSE2; - __control87_2(msRound[RoundType], _MCW_RC, &oldX87, &oldSSE2); + //__control87_2(msRound[RoundType], _MCW_RC, &oldX87, &oldSSE2); //? ? ? ? + _control87(msRound[RoundType], _MCW_RC); } static __inline double round(double x) { return floor(x + 0.5); } static __inline float roundf(float x) { return (float) floor(x + 0.5); } diff --git a/libmupen64plus/mupen64plus-core/src/r4300/x86/rjump.c b/libmupen64plus/mupen64plus-core/src/r4300/x86/rjump.c index 5073279f13..6592621ed6 100644 --- a/libmupen64plus/mupen64plus-core/src/r4300/x86/rjump.c +++ b/libmupen64plus/mupen64plus-core/src/r4300/x86/rjump.c @@ -63,6 +63,7 @@ void dyna_jump() #pragma warning(disable:4731) /* frame pointer register 'ebp' modified by inline assembly code */ #endif +#if HAVE_DYNAREC void dyna_start(void *code) { /* save the base and stack pointers */ @@ -155,6 +156,7 @@ void dyna_start(void *code) save_eip=0; } + void dyna_stop() { if (save_eip == 0) @@ -165,3 +167,10 @@ void dyna_stop() } } + +#else //#if HAVE_DYNAREC + +void dyna_start(void *code) {} +void dyna_stop(void) {} + +#endif //#if HAVE_DYNAREC diff --git a/libmupen64plus/mupen64plus-input-bkm/mupen64plus-input-bkm/mupen64plus-input-bkm.vcxproj b/libmupen64plus/mupen64plus-input-bkm/mupen64plus-input-bkm/mupen64plus-input-bkm.vcxproj index 92b8275f3b..0950ec528e 100644 --- a/libmupen64plus/mupen64plus-input-bkm/mupen64plus-input-bkm/mupen64plus-input-bkm.vcxproj +++ b/libmupen64plus/mupen64plus-input-bkm/mupen64plus-input-bkm/mupen64plus-input-bkm.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {3D8BD211-6002-4698-B5C1-A0F3146B6ACF} @@ -21,6 +29,12 @@ v100 MultiByte + + DynamicLibrary + true + v100 + MultiByte + DynamicLibrary false @@ -28,32 +42,71 @@ true MultiByte + + DynamicLibrary + false + v100 + true + MultiByte + + + + + + + false $(SolutionDir)..\..\..\..\output\dll\ true + + false + $(SolutionDir)..\..\..\..\output\dll\ + true + $(SolutionDir)..\..\..\..\output\dll\ true + + $(SolutionDir)..\..\..\..\output\dll\ + true + Level3 Disabled true false - ..\..\mupen64plus-core\src\api;..\..\mupen64plus-win32-deps\SDL-1.2.14\include;%(AdditionalIncludeDirectories) + ..\..\mupen64plus-core\src\api;..\..\mupen64plus-win32-deps\SDL-1.2.15\include;%(AdditionalIncludeDirectories) + WIN32;DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + + + true + + + + + + + + + Level3 + Disabled + true + false + ..\..\mupen64plus-core\src\api;..\..\mupen64plus-win32-deps\SDL-1.2.15\include;%(AdditionalIncludeDirectories) WIN32;DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) @@ -71,7 +124,7 @@ false - ..\..\mupen64plus-core\src\api;..\..\mupen64plus-win32-deps\SDL-1.2.14\include;%(AdditionalIncludeDirectories) + ..\..\mupen64plus-core\src\api;..\..\mupen64plus-win32-deps\SDL-1.2.15\include;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) true @@ -80,7 +133,32 @@ true true true - ..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib;%(AdditionalDependencies) + ..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\SDL.lib;%(AdditionalDependencies) + Windows + + + + + + + + + Level3 + MaxSpeed + + + false + ..\..\mupen64plus-core\src\api;..\..\mupen64plus-win32-deps\SDL-1.2.15\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + + + true + + + true + true + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) Windows diff --git a/libmupen64plus/mupen64plus-rsp-hle/projects/msvc11/mupen64plus-rsp-hle.vcxproj b/libmupen64plus/mupen64plus-rsp-hle/projects/msvc11/mupen64plus-rsp-hle.vcxproj index 65936c50c7..f71023ea49 100644 --- a/libmupen64plus/mupen64plus-rsp-hle/projects/msvc11/mupen64plus-rsp-hle.vcxproj +++ b/libmupen64plus/mupen64plus-rsp-hle/projects/msvc11/mupen64plus-rsp-hle.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {2EC7CEE3-C7A7-4F2E-B2C8-4DF6AFEC3E9A} @@ -22,35 +30,64 @@ true v100 + + DynamicLibrary + MultiByte + true + v100 + DynamicLibrary MultiByte v100 + + DynamicLibrary + MultiByte + v100 + + + + + + + <_ProjectFileVersion>10.0.40219.1 $(SolutionDir)..\..\..\..\output\dll\ + $(SolutionDir)..\..\..\..\output\dll\ $(Configuration)\ + $(Configuration)\ true + true $(SolutionDir)..\..\..\..\output\dll\ + $(SolutionDir)..\..\..\..\output\dll\ $(Configuration)\ + $(Configuration)\ false + false AllRules.ruleset + AllRules.ruleset + + AllRules.ruleset + AllRules.ruleset + + @@ -77,6 +114,30 @@ + + + Disabled + ..\..\..\mupen64plus-core\src\api;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;inline=__inline;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + Default + true + + + true + Windows + + + + + + ..\..\..\mupen64plus-core\src\api;%(AdditionalIncludeDirectories) @@ -101,6 +162,29 @@ + + + ..\..\..\mupen64plus-core\src\api;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;inline=__inline;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + Default + true + + + true + Windows + true + true + + + + + + diff --git a/libmupen64plus/mupen64plus-sln/projects/msvc11/mupen64plus.sln b/libmupen64plus/mupen64plus-sln/projects/msvc11/mupen64plus.sln index 3f1e002945..267738a8e0 100644 --- a/libmupen64plus/mupen64plus-sln/projects/msvc11/mupen64plus.sln +++ b/libmupen64plus/mupen64plus-sln/projects/msvc11/mupen64plus.sln @@ -23,49 +23,91 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 Release|Win32 = Release|Win32 + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {92D3FEB9-2129-41C5-8577-BCD7D961EF41}.Debug|Win32.ActiveCfg = Debug|Win32 {92D3FEB9-2129-41C5-8577-BCD7D961EF41}.Debug|Win32.Build.0 = Debug|Win32 + {92D3FEB9-2129-41C5-8577-BCD7D961EF41}.Debug|x64.ActiveCfg = Debug|x64 + {92D3FEB9-2129-41C5-8577-BCD7D961EF41}.Debug|x64.Build.0 = Debug|x64 {92D3FEB9-2129-41C5-8577-BCD7D961EF41}.Release|Win32.ActiveCfg = Release|Win32 {92D3FEB9-2129-41C5-8577-BCD7D961EF41}.Release|Win32.Build.0 = Release|Win32 + {92D3FEB9-2129-41C5-8577-BCD7D961EF41}.Release|x64.ActiveCfg = Release|x64 + {92D3FEB9-2129-41C5-8577-BCD7D961EF41}.Release|x64.Build.0 = Release|x64 {2EC7CEE3-C7A7-4F2E-B2C8-4DF6AFEC3E9A}.Debug|Win32.ActiveCfg = Debug|Win32 {2EC7CEE3-C7A7-4F2E-B2C8-4DF6AFEC3E9A}.Debug|Win32.Build.0 = Debug|Win32 + {2EC7CEE3-C7A7-4F2E-B2C8-4DF6AFEC3E9A}.Debug|x64.ActiveCfg = Debug|x64 + {2EC7CEE3-C7A7-4F2E-B2C8-4DF6AFEC3E9A}.Debug|x64.Build.0 = Debug|x64 {2EC7CEE3-C7A7-4F2E-B2C8-4DF6AFEC3E9A}.Release|Win32.ActiveCfg = Release|Win32 {2EC7CEE3-C7A7-4F2E-B2C8-4DF6AFEC3E9A}.Release|Win32.Build.0 = Release|Win32 + {2EC7CEE3-C7A7-4F2E-B2C8-4DF6AFEC3E9A}.Release|x64.ActiveCfg = Release|x64 + {2EC7CEE3-C7A7-4F2E-B2C8-4DF6AFEC3E9A}.Release|x64.Build.0 = Release|x64 {7D4AFF6A-B7D9-4C25-975A-038B8079098E}.Debug|Win32.ActiveCfg = Debug|Win32 {7D4AFF6A-B7D9-4C25-975A-038B8079098E}.Debug|Win32.Build.0 = Debug|Win32 + {7D4AFF6A-B7D9-4C25-975A-038B8079098E}.Debug|x64.ActiveCfg = Debug|x64 + {7D4AFF6A-B7D9-4C25-975A-038B8079098E}.Debug|x64.Build.0 = Debug|x64 {7D4AFF6A-B7D9-4C25-975A-038B8079098E}.Release|Win32.ActiveCfg = Release|Win32 {7D4AFF6A-B7D9-4C25-975A-038B8079098E}.Release|Win32.Build.0 = Release|Win32 + {7D4AFF6A-B7D9-4C25-975A-038B8079098E}.Release|x64.ActiveCfg = Release|x64 + {7D4AFF6A-B7D9-4C25-975A-038B8079098E}.Release|x64.Build.0 = Release|x64 {A4D13408-A794-4199-8FC7-4A9A32505005}.Debug|Win32.ActiveCfg = Debug|Win32 {A4D13408-A794-4199-8FC7-4A9A32505005}.Debug|Win32.Build.0 = Debug|Win32 + {A4D13408-A794-4199-8FC7-4A9A32505005}.Debug|x64.ActiveCfg = Debug|x64 + {A4D13408-A794-4199-8FC7-4A9A32505005}.Debug|x64.Build.0 = Debug|x64 {A4D13408-A794-4199-8FC7-4A9A32505005}.Release|Win32.ActiveCfg = Release|Win32 {A4D13408-A794-4199-8FC7-4A9A32505005}.Release|Win32.Build.0 = Release|Win32 + {A4D13408-A794-4199-8FC7-4A9A32505005}.Release|x64.ActiveCfg = Release|x64 + {A4D13408-A794-4199-8FC7-4A9A32505005}.Release|x64.Build.0 = Release|x64 {B6F20769-1385-4C0F-91A9-26F47AD1E78F}.Debug|Win32.ActiveCfg = Debug|Win32 {B6F20769-1385-4C0F-91A9-26F47AD1E78F}.Debug|Win32.Build.0 = Debug|Win32 + {B6F20769-1385-4C0F-91A9-26F47AD1E78F}.Debug|x64.ActiveCfg = Debug|x64 + {B6F20769-1385-4C0F-91A9-26F47AD1E78F}.Debug|x64.Build.0 = Debug|x64 {B6F20769-1385-4C0F-91A9-26F47AD1E78F}.Release|Win32.ActiveCfg = Release|Win32 {B6F20769-1385-4C0F-91A9-26F47AD1E78F}.Release|Win32.Build.0 = Release|Win32 + {B6F20769-1385-4C0F-91A9-26F47AD1E78F}.Release|x64.ActiveCfg = Release|x64 + {B6F20769-1385-4C0F-91A9-26F47AD1E78F}.Release|x64.Build.0 = Release|x64 {3D8BD211-6002-4698-B5C1-A0F3146B6ACF}.Debug|Win32.ActiveCfg = Debug|Win32 {3D8BD211-6002-4698-B5C1-A0F3146B6ACF}.Debug|Win32.Build.0 = Debug|Win32 + {3D8BD211-6002-4698-B5C1-A0F3146B6ACF}.Debug|x64.ActiveCfg = Debug|x64 + {3D8BD211-6002-4698-B5C1-A0F3146B6ACF}.Debug|x64.Build.0 = Debug|x64 {3D8BD211-6002-4698-B5C1-A0F3146B6ACF}.Release|Win32.ActiveCfg = Release|Win32 {3D8BD211-6002-4698-B5C1-A0F3146B6ACF}.Release|Win32.Build.0 = Release|Win32 + {3D8BD211-6002-4698-B5C1-A0F3146B6ACF}.Release|x64.ActiveCfg = Release|x64 + {3D8BD211-6002-4698-B5C1-A0F3146B6ACF}.Release|x64.Build.0 = Release|x64 {7708C1D2-3303-4F90-BCE8-3BCE4046BFD7}.Debug|Win32.ActiveCfg = Debug|Win32 {7708C1D2-3303-4F90-BCE8-3BCE4046BFD7}.Debug|Win32.Build.0 = Debug|Win32 + {7708C1D2-3303-4F90-BCE8-3BCE4046BFD7}.Debug|x64.ActiveCfg = Debug|x64 + {7708C1D2-3303-4F90-BCE8-3BCE4046BFD7}.Debug|x64.Build.0 = Debug|x64 {7708C1D2-3303-4F90-BCE8-3BCE4046BFD7}.Release|Win32.ActiveCfg = Release|Win32 {7708C1D2-3303-4F90-BCE8-3BCE4046BFD7}.Release|Win32.Build.0 = Release|Win32 + {7708C1D2-3303-4F90-BCE8-3BCE4046BFD7}.Release|x64.ActiveCfg = Release|x64 + {7708C1D2-3303-4F90-BCE8-3BCE4046BFD7}.Release|x64.Build.0 = Release|x64 {0C220B26-3D4D-431D-B829-CADE6508A771}.Debug|Win32.ActiveCfg = Debug|Win32 {0C220B26-3D4D-431D-B829-CADE6508A771}.Debug|Win32.Build.0 = Debug|Win32 + {0C220B26-3D4D-431D-B829-CADE6508A771}.Debug|x64.ActiveCfg = Debug|x64 + {0C220B26-3D4D-431D-B829-CADE6508A771}.Debug|x64.Build.0 = Debug|x64 {0C220B26-3D4D-431D-B829-CADE6508A771}.Release|Win32.ActiveCfg = Release|Win32 {0C220B26-3D4D-431D-B829-CADE6508A771}.Release|Win32.Build.0 = Release|Win32 + {0C220B26-3D4D-431D-B829-CADE6508A771}.Release|x64.ActiveCfg = Release|x64 + {0C220B26-3D4D-431D-B829-CADE6508A771}.Release|x64.Build.0 = Release|x64 {F3E6138A-C318-4020-B408-A9A24D8B3DE7}.Debug|Win32.ActiveCfg = Debug|Win32 {F3E6138A-C318-4020-B408-A9A24D8B3DE7}.Debug|Win32.Build.0 = Debug|Win32 + {F3E6138A-C318-4020-B408-A9A24D8B3DE7}.Debug|x64.ActiveCfg = Debug|x64 + {F3E6138A-C318-4020-B408-A9A24D8B3DE7}.Debug|x64.Build.0 = Debug|x64 {F3E6138A-C318-4020-B408-A9A24D8B3DE7}.Release|Win32.ActiveCfg = Release|Win32 {F3E6138A-C318-4020-B408-A9A24D8B3DE7}.Release|Win32.Build.0 = Release|Win32 + {F3E6138A-C318-4020-B408-A9A24D8B3DE7}.Release|x64.ActiveCfg = Release|x64 + {F3E6138A-C318-4020-B408-A9A24D8B3DE7}.Release|x64.Build.0 = Release|x64 {4CC85A3A-8E85-45DB-8941-2E2E18FC9A53}.Debug|Win32.ActiveCfg = Debug|Win32 {4CC85A3A-8E85-45DB-8941-2E2E18FC9A53}.Debug|Win32.Build.0 = Debug|Win32 + {4CC85A3A-8E85-45DB-8941-2E2E18FC9A53}.Debug|x64.ActiveCfg = Debug|Win32 + {4CC85A3A-8E85-45DB-8941-2E2E18FC9A53}.Debug|x64.Build.0 = Debug|Win32 {4CC85A3A-8E85-45DB-8941-2E2E18FC9A53}.Release|Win32.ActiveCfg = Release|Win32 {4CC85A3A-8E85-45DB-8941-2E2E18FC9A53}.Release|Win32.Build.0 = Release|Win32 + {4CC85A3A-8E85-45DB-8941-2E2E18FC9A53}.Release|x64.ActiveCfg = Release|x64 + {4CC85A3A-8E85-45DB-8941-2E2E18FC9A53}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/libmupen64plus/mupen64plus-video-glide64/projects/msvc10/mupen64plus-video-glide64.vcxproj b/libmupen64plus/mupen64plus-video-glide64/projects/msvc10/mupen64plus-video-glide64.vcxproj index dd6ed62a22..92966133be 100644 --- a/libmupen64plus/mupen64plus-video-glide64/projects/msvc10/mupen64plus-video-glide64.vcxproj +++ b/libmupen64plus/mupen64plus-video-glide64/projects/msvc10/mupen64plus-video-glide64.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {F3E6138A-C318-4020-B408-A9A24D8B3DE7} @@ -20,31 +28,50 @@ MultiByte true + + DynamicLibrary + MultiByte + true + DynamicLibrary MultiByte + + DynamicLibrary + MultiByte + + + + + + + <_ProjectFileVersion>10.0.40219.1 $(SolutionDir)..\..\..\..\output\dll\ + $(SolutionDir)..\..\..\..\output\dll\ $(Configuration)\ + $(Configuration)\ $(SolutionDir)..\..\..\..\output\dll\ + $(SolutionDir)..\..\..\..\output\dll\ $(Configuration)\ + $(Configuration)\ Disabled - ../../src;../../src/wrapper;../../../mupen64plus-core/src/api;../../../mupen64plus-win32-deps/SDL-1.2.14/include;%(AdditionalIncludeDirectories) + ../../src;../../src/wrapper;../../../mupen64plus-core/src/api;../../../mupen64plus-win32-deps/SDL-1.2.15/include;%(AdditionalIncludeDirectories) _WIN32_WINNT=0x0400;NOMINMAX;WIN32;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) false EnableFastChecks @@ -55,7 +82,7 @@ true - opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib;%(AdditionalDependencies) + opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\SDL.lib;%(AdditionalDependencies) true Windows MachineX86 @@ -65,11 +92,34 @@ + + + Disabled + ../../src;../../src/wrapper;../../../mupen64plus-core/src/api;../../../mupen64plus-win32-deps/SDL-1.2.15/include;%(AdditionalIncludeDirectories) + NO_ASM;_WIN32_WINNT=0x0400;NOMINMAX;WIN32;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Cdecl + true + + + opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\x64\SDL.lib;%(AdditionalDependencies) + true + Windows + + + + + + MaxSpeed true - ../../src;../../src/wrapper;../../../mupen64plus-core/src/api;../../../mupen64plus-win32-deps/SDL-1.2.14/include;%(AdditionalIncludeDirectories) + ../../src;../../src/wrapper;../../../mupen64plus-core/src/api;../../../mupen64plus-win32-deps/SDL-1.2.15/include;%(AdditionalIncludeDirectories) NOMINMAX;WIN32;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -77,7 +127,7 @@ ProgramDatabase - opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib;%(AdditionalDependencies) + opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\SDL.lib;%(AdditionalDependencies) true Windows true @@ -89,6 +139,29 @@ + + + MaxSpeed + true + ../../src;../../src/wrapper;../../../mupen64plus-core/src/api;../../../mupen64plus-win32-deps/SDL-1.2.15/include;%(AdditionalIncludeDirectories) + NO_ASM;NOMINMAX;WIN32;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + Level3 + ProgramDatabase + + + opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\x64\SDL.lib;%(AdditionalDependencies) + true + Windows + true + true + + + + + + @@ -105,39 +178,57 @@ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ $(IntDir)wrapper\ + $(IntDir)wrapper\ diff --git a/libmupen64plus/mupen64plus-video-glide64mk2/projects/msvc10/mupen64plus-video-glide64mk2.vcxproj b/libmupen64plus/mupen64plus-video-glide64mk2/projects/msvc10/mupen64plus-video-glide64mk2.vcxproj index 62bc3b1acd..35d3025ae6 100644 --- a/libmupen64plus/mupen64plus-video-glide64mk2/projects/msvc10/mupen64plus-video-glide64mk2.vcxproj +++ b/libmupen64plus/mupen64plus-video-glide64mk2/projects/msvc10/mupen64plus-video-glide64mk2.vcxproj @@ -64,7 +64,7 @@ Disabled - ..\..\src\Glitch64\inc;..\..\..\mupen64plus-win32-deps\boost-1.53.0\;..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;%(AdditionalIncludeDirectories) + ..\..\src\Glitch64\inc;..\..\..\mupen64plus-win32-deps\boost-1.53.0\;..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\include;%(AdditionalIncludeDirectories) _GLIBCXX_HAVE_BROKEN_VSWPRINTF;NO_FILTER_THREAD;_VARIADIC_MAX=10;_CRT_SECURE_NO_WARNINGS;__MSC__;WIN32;%(PreprocessorDefinitions) Async EnableFastChecks @@ -83,7 +83,7 @@ 0x0409 - opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\lib\libpng.lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\lib\zlib.lib;winmm.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;msvcrtd.lib;%(AdditionalDependencies) + opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\SDL.lib;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\lib\libpng.lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\lib\zlib.lib;winmm.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;msvcrtd.lib;%(AdditionalDependencies) $(OutDir)$(TargetName)$(TargetExt) true ..\lib;..\..\..\mupen64plus-win32-deps\boost-1.53.0\boost\libs;%(AdditionalLibraryDirectories) @@ -114,7 +114,7 @@ true Speed false - ..\..\..\mupen64plus-win32-deps\boost-1.53.0\;..\..\..\mupen64plus-core\src\api;..\..\src\Glide64;..\..\src\Glide64\inc;..\..\src\GlideHQ;..\..\src\GlideHQ\tc-1.1+;..\..\src\Glitch64;..\..\src\Glitch64\inc;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\include;%(AdditionalIncludeDirectories) + ..\..\..\mupen64plus-win32-deps\boost-1.53.0\;..\..\..\mupen64plus-core\src\api;..\..\src\Glide64;..\..\src\Glide64\inc;..\..\src\GlideHQ;..\..\src\GlideHQ\tc-1.1+;..\..\src\Glitch64;..\..\src\Glitch64\inc;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\include;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\include;%(AdditionalIncludeDirectories) _GLIBCXX_HAVE_BROKEN_VSWPRINTF;NO_FILTER_THREAD;_VARIADIC_MAX=10;_CRT_SECURE_NO_WARNINGS;__MSC__;WIN32;__VISUALC__;%(PreprocessorDefinitions) true Async @@ -137,7 +137,7 @@ SDL.lib;zlib.lib;libpng.lib;opengl32.lib;winmm.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;msvcrt.lib;LIBCMT.lib;%(AdditionalDependencies) $(OutDir)$(TargetName)$(TargetExt) true - ..\..\..\mupen64plus-win32-deps\boost-1.53.0\boost\libs;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib;%(AdditionalLibraryDirectories) + ..\..\..\mupen64plus-win32-deps\boost-1.53.0\boost\libs;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib;%(AdditionalLibraryDirectories) $(TargetDir)$(TargetName).pdb diff --git a/libmupen64plus/mupen64plus-video-glide64mk2/projects/msvc11/mupen64plus-video-glide64mk2.vcxproj b/libmupen64plus/mupen64plus-video-glide64mk2/projects/msvc11/mupen64plus-video-glide64mk2.vcxproj index 137793b88d..cde45305f3 100644 --- a/libmupen64plus/mupen64plus-video-glide64mk2/projects/msvc11/mupen64plus-video-glide64mk2.vcxproj +++ b/libmupen64plus/mupen64plus-video-glide64mk2/projects/msvc11/mupen64plus-video-glide64mk2.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {A4D13408-A794-4199-8FC7-4A9A32505005} @@ -23,34 +31,64 @@ true v120 + + DynamicLibrary + false + MultiByte + true + v100 + DynamicLibrary false MultiByte v120 + + DynamicLibrary + false + MultiByte + v100 + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 $(SolutionDir)..\..\..\..\output\dll\ + $(SolutionDir)..\..\..\..\output\dll\ $(Configuration)\ + $(Configuration)\ true + true $(SolutionDir)..\..\..\..\output\dll\ + $(SolutionDir)..\..\..\..\output\dll\ $(Configuration)\ + $(Configuration)\ false + false true + true F:\Code\Third Party\boost;$(IncludePath) + F:\Code\Third Party\boost;$(IncludePath) F:\Code\Third Party\boost\stage\lib;$(LibraryPath) + F:\Code\Third Party\boost\stage\lib;$(LibraryPath) @@ -64,7 +102,7 @@ Disabled - ..\..\src\Glitch64\inc;..\..\..\mupen64plus-win32-deps\boost-1.57.0\;..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;%(AdditionalIncludeDirectories) + ..\..\src\Glitch64\inc;..\..\..\mupen64plus-win32-deps\boost-1.57.0\;..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\include;%(AdditionalIncludeDirectories) _GLIBCXX_HAVE_BROKEN_VSWPRINTF;NO_FILTER_THREAD;_VARIADIC_MAX=10;_CRT_SECURE_NO_WARNINGS;__MSC__;WIN32;%(PreprocessorDefinitions) Async EnableFastChecks @@ -83,7 +121,7 @@ 0x0409 - opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\lib\libpng.lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\lib\zlib.lib;winmm.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;msvcrtd.lib;%(AdditionalDependencies) + opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\SDL.lib;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\lib\libpng.lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\lib\zlib.lib;winmm.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;msvcrtd.lib;%(AdditionalDependencies) $(OutDir)$(TargetName)$(TargetExt) true ..\lib;..\..\..\mupen64plus-win32-deps\boost-1.57.0\boost\libs;%(AdditionalLibraryDirectories) @@ -104,6 +142,56 @@ + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/n64Glide.tlb + + + + + Disabled + ..\..\src\Glitch64\inc;..\..\..\mupen64plus-win32-deps\boost-1.57.0\;..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\include;%(AdditionalIncludeDirectories) + NO_ASM;_GLIBCXX_HAVE_BROKEN_VSWPRINTF;NO_FILTER_THREAD;_VARIADIC_MAX=10;_CRT_SECURE_NO_WARNINGS;__MSC__;WIN32;%(PreprocessorDefinitions) + Async + EnableFastChecks + MultiThreadedDebugDLL + .\Debug/n64Glide.pch + .\Debug/ + .\Debug/ + .\Debug/ + Level3 + true + ProgramDatabase + true + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\x64\SDL.lib;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\lib\x64\libpng16.lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\lib\x64\zlib.lib;winmm.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;msvcrtd.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + ..\lib;..\..\..\deps\libs;%(AdditionalLibraryDirectories) + false + true + .\Debug/Glide64.pdb + .\Debug/Glide64.lib + + + true + .\Debug/n64Glide.bsc + + + + + + + + NDEBUG;%(PreprocessorDefinitions) @@ -120,7 +208,7 @@ true Speed false - ..\..\..\mupen64plus-win32-deps\boost-1.57.0\;..\..\..\mupen64plus-core\src\api;..\..\src\Glide64;..\..\src\Glide64\inc;..\..\src\GlideHQ;..\..\src\GlideHQ\tc-1.1+;..\..\src\Glitch64;..\..\src\Glitch64\inc;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\include;%(AdditionalIncludeDirectories) + ..\..\..\mupen64plus-win32-deps\boost-1.57.0\;..\..\..\mupen64plus-core\src\api;..\..\src\Glide64;..\..\src\Glide64\inc;..\..\src\GlideHQ;..\..\src\GlideHQ\tc-1.1+;..\..\src\Glitch64;..\..\src\Glitch64\inc;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\include;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\include;%(AdditionalIncludeDirectories) _GLIBCXX_HAVE_BROKEN_VSWPRINTF;NO_FILTER_THREAD;_VARIADIC_MAX=10;_CRT_SECURE_NO_WARNINGS;__MSC__;WIN32;__VISUALC__;%(PreprocessorDefinitions) true Async @@ -143,7 +231,7 @@ SDL.lib;zlib.lib;libpng.lib;opengl32.lib;winmm.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;msvcrt.lib;LIBCMT.lib;%(AdditionalDependencies) $(OutDir)$(TargetName)$(TargetExt) true - ..\..\..\mupen64plus-win32-deps\boost-1.57.0\boost\libs;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib;%(AdditionalLibraryDirectories) + ..\..\..\mupen64plus-win32-deps\boost-1.57.0\boost\libs;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib;%(AdditionalLibraryDirectories) $(TargetDir)$(TargetName).pdb @@ -165,6 +253,66 @@ + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/n64Glide.tlb + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + false + ..\..\..\mupen64plus-win32-deps\boost-1.57.0\;..\..\..\mupen64plus-core\src\api;..\..\src\Glide64;..\..\src\Glide64\inc;..\..\src\GlideHQ;..\..\src\GlideHQ\tc-1.1+;..\..\src\Glitch64;..\..\src\Glitch64\inc;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\include;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\include;%(AdditionalIncludeDirectories) + NO_ASM;_GLIBCXX_HAVE_BROKEN_VSWPRINTF;NO_FILTER_THREAD;_VARIADIC_MAX=10;_CRT_SECURE_NO_WARNINGS;__MSC__;WIN32;__VISUALC__;%(PreprocessorDefinitions) + true + Async + MultiThreadedDLL + true + NotSet + .\Release/n64Glide.pch + .\Release/ + .\Release/ + .\Release/ + Level3 + true + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\x64\SDL.lib;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\lib\x64\libpng16.lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.8\lib\x64\zlib.lib;winmm.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;msvcrtd.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + ..\lib;..\..\..\deps\libs;%(AdditionalLibraryDirectories) + $(TargetDir)$(TargetName).pdb + + + Windows + true + false + + + true + .\Release/n64Glide.bsc + + + true + + + + + + + + @@ -204,7 +352,9 @@ .\Release/%(Filename)1.obj + .\Release/%(Filename)1.obj $(IntDir)%(Filename)1.xdc + $(IntDir)%(Filename)1.xdc diff --git a/libmupen64plus/mupen64plus-video-jabo/mupen64plus-video-jabo/mupen64plus-video-jabo.vcxproj b/libmupen64plus/mupen64plus-video-jabo/mupen64plus-video-jabo/mupen64plus-video-jabo.vcxproj index d3f9c71bad..9374e59c04 100644 --- a/libmupen64plus/mupen64plus-video-jabo/mupen64plus-video-jabo/mupen64plus-video-jabo.vcxproj +++ b/libmupen64plus/mupen64plus-video-jabo/mupen64plus-video-jabo/mupen64plus-video-jabo.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {0C220B26-3D4D-431D-B829-CADE6508A771} @@ -22,6 +30,12 @@ v100 MultiByte + + DynamicLibrary + true + v100 + MultiByte + DynamicLibrary false @@ -29,32 +43,71 @@ true MultiByte + + DynamicLibrary + false + v100 + true + MultiByte + + + + + + + false $(SolutionDir)..\..\..\..\output\dll\ true + + false + $(SolutionDir)..\..\..\..\output\dll\ + true + $(SolutionDir)..\..\..\..\output\dll\ true + + $(SolutionDir)..\..\..\..\output\dll\ + true + Level3 Disabled true false - ..\..\mupen64plus-core\src\api;..\..\mupen64plus-win32-deps\SDL-1.2.14\include;%(AdditionalIncludeDirectories) + ..\..\mupen64plus-core\src\api;..\..\mupen64plus-win32-deps\SDL-1.2.15\include;%(AdditionalIncludeDirectories) + WIN32;DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + + + true + + + + + + + + + Level3 + Disabled + true + false + ..\..\mupen64plus-core\src\api;..\..\mupen64plus-win32-deps\SDL-1.2.15\include;%(AdditionalIncludeDirectories) WIN32;DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) @@ -72,7 +125,7 @@ false - ..\..\mupen64plus-core\src\api;..\..\mupen64plus-win32-deps\SDL-1.2.14\include;%(AdditionalIncludeDirectories) + ..\..\mupen64plus-core\src\api;..\..\mupen64plus-win32-deps\SDL-1.2.15\include;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) true @@ -81,7 +134,32 @@ true true true - ..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib;%(AdditionalDependencies) + ..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\SDL.lib;%(AdditionalDependencies) + Windows + + + + + + + + + Level3 + MaxSpeed + + + false + ..\..\mupen64plus-core\src\api;..\..\mupen64plus-win32-deps\SDL-1.2.15\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + + + true + + + true + true + true + ..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\SDL.lib;%(AdditionalDependencies) Windows diff --git a/libmupen64plus/mupen64plus-video-rice/projects/msvc11/mupen64plus-video-rice.vcxproj b/libmupen64plus/mupen64plus-video-rice/projects/msvc11/mupen64plus-video-rice.vcxproj index fba3ee3eb4..53dfc72e13 100644 --- a/libmupen64plus/mupen64plus-video-rice/projects/msvc11/mupen64plus-video-rice.vcxproj +++ b/libmupen64plus/mupen64plus-video-rice/projects/msvc11/mupen64plus-video-rice.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {7D4AFF6A-B7D9-4C25-975A-038B8079098E} @@ -22,40 +30,69 @@ true v100 + + DynamicLibrary + MultiByte + true + v100 + DynamicLibrary MultiByte v100 + + DynamicLibrary + MultiByte + v100 + + + + + + + <_ProjectFileVersion>10.0.40219.1 $(SolutionDir)..\..\..\..\output\dll\ + $(SolutionDir)..\..\..\..\output\dll\ $(Configuration)\ + $(Configuration)\ true + true $(SolutionDir)..\..\..\..\output\dll\ + $(SolutionDir)..\..\..\..\output\dll\ $(Configuration)\ + $(Configuration)\ false + false AllRules.ruleset + AllRules.ruleset + + AllRules.ruleset + AllRules.ruleset + + Disabled - ..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;%(AdditionalIncludeDirectories) + ..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;%(AdditionalIncludeDirectories) WIN32;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) false EnableFastChecks @@ -67,7 +104,7 @@ true - user32.lib;gdi32.lib;opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\lib\libpng.lib;%(AdditionalDependencies) + user32.lib;gdi32.lib;opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\SDL.lib;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\lib\libpng.lib;%(AdditionalDependencies) true Windows MachineX86 @@ -77,9 +114,33 @@ + + + Disabled + ..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;%(AdditionalIncludeDirectories) + NO_ASM;WIN32;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + true + + + user32.lib;gdi32.lib;opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\x64\SDL.lib;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\lib\x64\libpng16.lib;%(AdditionalDependencies) + true + Windows + + + + + + - ..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;%(AdditionalIncludeDirectories) + ..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) MultiThreadedDLL @@ -90,7 +151,7 @@ true - user32.lib;gdi32.lib;opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\lib\libpng.lib;%(AdditionalDependencies) + user32.lib;gdi32.lib;opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\SDL.lib;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\lib\libpng.lib;%(AdditionalDependencies) true Windows true @@ -102,6 +163,30 @@ + + + ..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;%(AdditionalIncludeDirectories) + NO_ASM;WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + Default + true + + + user32.lib;gdi32.lib;opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\x64\SDL.lib;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\lib\x64\libpng16.lib;%(AdditionalDependencies) + true + Windows + true + true + + + + + + diff --git a/libmupen64plus/mupen64plus-video-z64/projects/msvc11/mupen64plus-video-z64.vcxproj b/libmupen64plus/mupen64plus-video-z64/projects/msvc11/mupen64plus-video-z64.vcxproj index ac5ed36161..1edf1a4d36 100644 --- a/libmupen64plus/mupen64plus-video-z64/projects/msvc11/mupen64plus-video-z64.vcxproj +++ b/libmupen64plus/mupen64plus-video-z64/projects/msvc11/mupen64plus-video-z64.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + @@ -46,37 +54,62 @@ true Unicode + + DynamicLibrary + true + Unicode + DynamicLibrary false true Unicode + + DynamicLibrary + false + true + Unicode + + + + + + + true $(SolutionDir)..\..\..\..\output\dll\ + + true + $(SolutionDir)..\..\..\..\output\dll\ + false $(SolutionDir)..\..\..\..\output\dll\ + + false + $(SolutionDir)..\..\..\..\output\dll\ + NotUsing Level3 Disabled WIN32;_DEBUG;_WINDOWS;_USRDLL;MUPEN64PLUSVIDEOZ64_EXPORTS;%(PreprocessorDefinitions) - ..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;..\..\..\mupen64plus-win32-deps\glew-1.10.0\include\GL + ..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;..\..\..\mupen64plus-win32-deps\glew-1.10.0\include\GL 4996;4005;4244 @@ -84,7 +117,24 @@ true - opengl32.lib;..\..\..\mupen64plus-win32-deps\glew-1.10.0\lib\Release\Win32\glew32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib + opengl32.lib;..\..\..\mupen64plus-win32-deps\glew-1.10.0\lib\Release\Win32\glew32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\SDL.lib + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MUPEN64PLUSVIDEOZ64_EXPORTS;%(PreprocessorDefinitions) + ..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;..\..\..\mupen64plus-win32-deps\glew-1.10.0\include\GL + 4996;4005;4244 + + + Windows + true + + + opengl32.lib;..\..\..\mupen64plus-win32-deps\glew-1.10.0\lib\Release\Win32\glew32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\SDL.lib @@ -95,7 +145,7 @@ true true WIN32;NDEBUG;_WINDOWS;_USRDLL;MUPEN64PLUSVIDEOZ64_EXPORTS;%(PreprocessorDefinitions) - ..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;..\..\..\mupen64plus-win32-deps\glew-1.10.0\include\GL + ..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;..\..\..\mupen64plus-win32-deps\glew-1.10.0\include\GL 4996;4005;4244 @@ -103,7 +153,28 @@ true true true - opengl32.lib;..\..\..\mupen64plus-win32-deps\glew-1.10.0\lib\Release\Win32\glew32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib + opengl32.lib;..\..\..\mupen64plus-win32-deps\glew-1.10.0\lib\Release\Win32\glew32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\SDL.lib + + + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;MUPEN64PLUSVIDEOZ64_EXPORTS;%(PreprocessorDefinitions) + ..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\include;..\..\..\mupen64plus-win32-deps\libpng-1.6.18\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;..\..\..\mupen64plus-win32-deps\glew-1.10.0\include\GL + 4996;4005;4244 + + + Windows + true + true + true + opengl32.lib;..\..\..\mupen64plus-win32-deps\glew-1.10.0\lib\Release\Win32\glew32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.15\lib\SDL.lib diff --git a/libmupen64plus/mupen64plus-win32-deps b/libmupen64plus/mupen64plus-win32-deps index 36a67e2dae..b38635b746 160000 --- a/libmupen64plus/mupen64plus-win32-deps +++ b/libmupen64plus/mupen64plus-win32-deps @@ -1 +1 @@ -Subproject commit 36a67e2dae92cb6e95f915bc76af0e0b789a0127 +Subproject commit b38635b74648dc7b84c774186fc63c75afc22d58 diff --git a/libsnes/bsnes/Makefile b/libsnes/bsnes/Makefile deleted file mode 100644 index c1b89f9102..0000000000 --- a/libsnes/bsnes/Makefile +++ /dev/null @@ -1,100 +0,0 @@ -include nall/Makefile - -nes := nes -snes := snes -gameboy := gameboy -profile := accuracy -target := ui - -# options += console - -# compiler -c := $(compiler) -std=gnu99 $(BIZWINCFLAGS) -cpp := $(subst cc,++,$(compiler)) -std=gnu++0x -flags := -I. -O3 -fomit-frame-pointer -link := -objects := libco - -ifneq ($(BIZWINCFLAGS),) - flags := $(BIZWINCFLAGS) -endif - -# profile-guided optimization mode -# pgo := instrument -# pgo := optimize - -ifeq ($(pgo),instrument) - flags += -fprofile-generate - link += -lgcov -else ifeq ($(pgo),optimize) - flags += -fprofile-use -endif - -# platform -ifeq ($(platform),x) - link += -s -ldl -lX11 -lXext -else ifeq ($(platform),osx) -else ifeq ($(platform),win) - link += $(if $(findstring console,$(options)),-mconsole,-mwindows) - link += -mthreads -s -luuid -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lshell32 -lole32 - link += -enable-auto-import -enable-runtime-pseudo-reloc -else - unknown_platform: help; -endif - -ui := target-$(target) - -# implicit rules -compile = \ - $(strip \ - $(if $(filter %.c,$<), \ - $(c) $(flags) $1 -c $< -o $@, \ - $(if $(filter %.cpp,$<), \ - $(cpp) $(flags) $1 -c $< -o $@ \ - ) \ - ) \ - ) - -%.o: $<; $(call compile) - -all: build; - -obj/libco.o: libco/libco.c libco/* - -include $(ui)/Makefile -flags := $(flags) $(foreach o,$(call strupper,$(options)),-D$o) - -# targets -clean: - -@$(call delete,obj/*.o) - -@$(call delete,obj/*.a) - -@$(call delete,obj/*.so) - -@$(call delete,obj/*.dylib) - -@$(call delete,obj/*.dll) - -@$(call delete,*.res) - -@$(call delete,*.pgd) - -@$(call delete,*.pgc) - -@$(call delete,*.ilk) - -@$(call delete,*.pdb) - -@$(call delete,*.manifest) - -sync: - if [ -d ./libco ]; then rm -r ./libco; fi - if [ -d ./nall ]; then rm -r ./nall; fi - if [ -d ./ruby ]; then rm -r ./ruby; fi - if [ -d ./phoenix ]; then rm -r ./phoenix; fi - cp -r ../libco ./libco - cp -r ../nall ./nall - cp -r ../ruby ./ruby - cp -r ../phoenix ./phoenix - rm -r libco/doc - rm -r libco/test - rm -r nall/test - rm -r ruby/_test - rm -r phoenix/nall - rm -r phoenix/test - -archive-all: - tar -cjf bsnes.tar.bz2 base data gameboy libco nall nes obj out phoenix ruby snes target-debugger target-libsnes target-ui Makefile cc.bat purge.bat - -help:; diff --git a/libsnes/bsnes/gameboy/Makefile b/libsnes/bsnes/gameboy/Makefile deleted file mode 100644 index 22a77c700c..0000000000 --- a/libsnes/bsnes/gameboy/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -options += gameboy - -gameboy_objects := gameboy-interface gameboy-system gameboy-scheduler -gameboy_objects += gameboy-memory gameboy-cartridge -gameboy_objects += gameboy-cpu gameboy-apu gameboy-lcd -gameboy_objects += gameboy-cheat gameboy-video -objects += $(gameboy_objects) - -obj/gameboy-interface.o: $(gameboy)/interface/interface.cpp $(call rwildcard,$(gameboy)/interface/) -obj/gameboy-system.o: $(gameboy)/system/system.cpp $(call rwildcard,$(gameboy)/system/) -obj/gameboy-scheduler.o: $(gameboy)/scheduler/scheduler.cpp $(call rwildcard,$(gameboy)/scheduler/) -obj/gameboy-cartridge.o: $(gameboy)/cartridge/cartridge.cpp $(call rwildcard,$(gameboy)/cartridge/) -obj/gameboy-memory.o: $(gameboy)/memory/memory.cpp $(call rwildcard,$(gameboy)/memory/) -obj/gameboy-cpu.o: $(gameboy)/cpu/cpu.cpp $(call rwildcard,$(gameboy)/cpu/) -obj/gameboy-apu.o: $(gameboy)/apu/apu.cpp $(call rwildcard,$(gameboy)/apu/) -obj/gameboy-lcd.o: $(gameboy)/lcd/lcd.cpp $(call rwildcard,$(gameboy)/lcd/) -obj/gameboy-cheat.o: $(gameboy)/cheat/cheat.cpp $(call rwildcard,$(gameboy)/cheat/) -obj/gameboy-video.o: $(gameboy)/video/video.cpp $(call rwildcard,$(gameboy)/video/) diff --git a/libsnes/bsnes/gameboy/apu/serialization.cpp b/libsnes/bsnes/gameboy/apu/serialization.cpp deleted file mode 100644 index 3468634750..0000000000 --- a/libsnes/bsnes/gameboy/apu/serialization.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#ifdef APU_CPP - -void APU::serialize(serializer &s) { - Processor::serialize(s); - - s.array(mmio_data); - s.integer(sequencer_base); - s.integer(sequencer_step); - - square1.serialize(s); - square2.serialize(s); - wave.serialize(s); - noise.serialize(s); - master.serialize(s); -} - -#endif diff --git a/libsnes/bsnes/gameboy/cartridge/serialization.cpp b/libsnes/bsnes/gameboy/cartridge/serialization.cpp deleted file mode 100644 index 2f54262a05..0000000000 --- a/libsnes/bsnes/gameboy/cartridge/serialization.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifdef CARTRIDGE_CPP - -void Cartridge::serialize(serializer &s) { - if(info.battery) s.array(ramdata, ramsize); - s.integer(bootrom_enable); - - s.integer(mbc1.ram_enable); - s.integer(mbc1.rom_select); - s.integer(mbc1.ram_select); - s.integer(mbc1.mode_select); - - s.integer(mbc2.ram_enable); - s.integer(mbc2.rom_select); - - s.integer(mbc3.ram_enable); - s.integer(mbc3.rom_select); - s.integer(mbc3.ram_select); - s.integer(mbc3.rtc_latch); - - s.integer(mbc3.rtc_halt); - s.integer(mbc3.rtc_second); - s.integer(mbc3.rtc_minute); - s.integer(mbc3.rtc_hour); - s.integer(mbc3.rtc_day); - s.integer(mbc3.rtc_day_carry); - - s.integer(mbc3.rtc_latch_second); - s.integer(mbc3.rtc_latch_minute); - s.integer(mbc3.rtc_latch_hour); - s.integer(mbc3.rtc_latch_day); - s.integer(mbc3.rtc_latch_day_carry); - - s.integer(mbc5.ram_enable); - s.integer(mbc5.rom_select); - s.integer(mbc5.ram_select); - - s.integer(mmm01.rom_mode); - s.integer(mmm01.rom_base); - - s.integer(mmm01.ram_enable); - s.integer(mmm01.rom_select); - s.integer(mmm01.ram_select); - - s.integer(huc1.ram_writable); - s.integer(huc1.rom_select); - s.integer(huc1.ram_select); - s.integer(huc1.model); - - s.integer(huc3.ram_enable); - s.integer(huc3.rom_select); - s.integer(huc3.ram_select); -} - -#endif diff --git a/libsnes/bsnes/gameboy/cheat/cheat.cpp b/libsnes/bsnes/gameboy/cheat/cheat.cpp deleted file mode 100644 index bd72ef6928..0000000000 --- a/libsnes/bsnes/gameboy/cheat/cheat.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include - -namespace GameBoy { - -Cheat cheat; - -bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned &comp) { - static bool initialize = false; - static uint8 mapProActionReplay[256], mapGameGenie[256]; - - if(initialize == false) { - initialize = true; - - for(auto &n : mapProActionReplay) n = ~0; - mapProActionReplay['0'] = 0; mapProActionReplay['1'] = 1; mapProActionReplay['2'] = 2; mapProActionReplay['3'] = 3; - mapProActionReplay['4'] = 4; mapProActionReplay['5'] = 5; mapProActionReplay['6'] = 6; mapProActionReplay['7'] = 7; - mapProActionReplay['8'] = 8; mapProActionReplay['9'] = 9; mapProActionReplay['A'] = 10; mapProActionReplay['B'] = 11; - mapProActionReplay['C'] = 12; mapProActionReplay['D'] = 13; mapProActionReplay['E'] = 14; mapProActionReplay['F'] = 15; - - for(auto &n : mapGameGenie) n = ~0; - mapGameGenie['0'] = 0; mapGameGenie['1'] = 1; mapGameGenie['2'] = 2; mapGameGenie['3'] = 3; - mapGameGenie['4'] = 4; mapGameGenie['5'] = 5; mapGameGenie['6'] = 6; mapGameGenie['7'] = 7; - mapGameGenie['8'] = 8; mapGameGenie['9'] = 9; mapGameGenie['A'] = 10; mapGameGenie['B'] = 11; - mapGameGenie['C'] = 12; mapGameGenie['D'] = 13; mapGameGenie['E'] = 14; mapGameGenie['F'] = 15; - } - - string code = code_; - code.upper(); - unsigned length = code.length(), bits = 0; - - if(code.wildcard("????:??")) { - code = { substr(code, 0, 4), substr(code, 5, 2) }; - for(unsigned n = 0; n < 6; n++) if(mapProActionReplay[code[n]] > 15) return false; - bits = hex(code); - addr = (bits >> 8) & 0xffff; - data = (bits >> 0) & 0xff; - comp = ~0; - return true; - } - - if(code.wildcard("????:??:??")) { - code = { substr(code, 0, 4), substr(code, 5, 2), substr(code, 8, 2) }; - for(unsigned n = 0; n < 8; n++) if(mapProActionReplay[code[n]] > 15) return false; - bits = hex(code); - addr = (bits >> 16) & 0xffff; - data = (bits >> 8) & 0xff; - comp = (bits >> 0) & 0xff; - return true; - } - - if(code.wildcard("???" "-" "???")) { - code = { substr(code, 0, 3), substr(code, 4, 3) }; - for(unsigned n = 0; n < 6; n++) if(mapGameGenie[code[n]] > 15) return false; - for(unsigned n = 0; n < 6; n++) bits |= mapGameGenie[code[n]] << (20 - n * 4); - - addr = (bits >> 0) & 0xffff; - data = (bits >> 16) & 0xff; - comp = ~0; - - addr = (((addr >> 4) | (addr << 12)) & 0xffff) ^ 0xf000; - - return true; - } - - if(code.wildcard("???" "-" "???" "-" "???")) { - code = { substr(code, 0, 3), substr(code, 4, 3), substr(code, 8, 1), substr(code, 10, 1) }; - for(unsigned n = 0; n < 8; n++) if(mapGameGenie[code[n]] > 15) return false; - for(unsigned n = 0; n < 8; n++) bits |= mapGameGenie[code[n]] << (28 - n * 4); - - addr = (bits >> 8) & 0xffff; - data = (bits >> 24) & 0xff; - comp = (bits >> 0) & 0xff; - - addr = (((addr >> 4) | (addr << 12)) & 0xffff) ^ 0xf000; - comp = (((comp >> 2) | (comp << 6)) & 0xff) ^ 0xba; - - return true; - } - - return false; -} - -void Cheat::synchronize() { - for(auto &n : override) n = false; - - for(unsigned n = 0; n < size(); n++) { - override[operator[](n).addr] = true; - } -} - -} diff --git a/libsnes/bsnes/gameboy/cheat/cheat.hpp b/libsnes/bsnes/gameboy/cheat/cheat.hpp deleted file mode 100644 index 4446a52b1c..0000000000 --- a/libsnes/bsnes/gameboy/cheat/cheat.hpp +++ /dev/null @@ -1,14 +0,0 @@ -struct CheatCode { - unsigned addr; - unsigned data; - unsigned comp; -}; - -struct Cheat : public linear_vector { - static bool decode(const string &code, unsigned &addr, unsigned &data, unsigned &comp); - - void synchronize(); - bool override[65536]; -}; - -extern Cheat cheat; diff --git a/libsnes/bsnes/gameboy/cpu/serialization.cpp b/libsnes/bsnes/gameboy/cpu/serialization.cpp deleted file mode 100644 index 0b4c75ba20..0000000000 --- a/libsnes/bsnes/gameboy/cpu/serialization.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#ifdef CPU_CPP - -void CPU::serialize(serializer &s) { - Processor::serialize(s); - - s.array(wram,32768); - s.array(hram,8192); - - s.integer(r.a.data); - s.integer(r.f.z); - s.integer(r.f.n); - s.integer(r.f.h); - s.integer(r.f.c); - s.integer(r.b.data); - s.integer(r.c.data); - s.integer(r.d.data); - s.integer(r.e.data); - s.integer(r.h.data); - s.integer(r.l.data); - s.integer(r.sp.data); - s.integer(r.pc.data); - - s.integer(status.clock); - s.integer(status.halt); - s.integer(status.stop); - s.integer(status.ei); - s.integer(status.ime); - - s.integer(status.p15); - s.integer(status.p14); - s.integer(status.joyp); - s.integer(status.mlt_req); - - s.integer(status.serial_data); - s.integer(status.serial_bits); - - s.integer(status.serial_transfer); - s.integer(status.serial_clock); - - s.integer(status.div); - s.integer(status.tima); - s.integer(status.tma); - s.integer(status.timer_enable); - s.integer(status.timer_clock); - - s.integer(status.interrupt_request_joypad); - s.integer(status.interrupt_request_serial); - s.integer(status.interrupt_request_timer); - s.integer(status.interrupt_request_stat); - s.integer(status.interrupt_request_vblank); - - s.integer(status.speed_double); - s.integer(status.speed_switch); - - s.integer(status.dma_source); - s.integer(status.dma_target); - s.integer(status.dma_mode); - s.integer(status.dma_length); - - s.integer(status.ff6c); - - s.integer(status.wram_bank); - - s.integer(status.ff72); - s.integer(status.ff73); - s.integer(status.ff74); - s.integer(status.ff75); - - s.integer(status.interrupt_enable_joypad); - s.integer(status.interrupt_enable_serial); - s.integer(status.interrupt_enable_timer); - s.integer(status.interrupt_enable_stat); - s.integer(status.interrupt_enable_vblank); -} - -#endif diff --git a/libsnes/bsnes/gameboy/lcd/serialization.cpp b/libsnes/bsnes/gameboy/lcd/serialization.cpp deleted file mode 100644 index df4752aab5..0000000000 --- a/libsnes/bsnes/gameboy/lcd/serialization.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#ifdef LCD_CPP - -void LCD::serialize(serializer &s) { - Processor::serialize(s); - - s.array(screen); - s.array(line); - s.array(origin); - - s.array(vram); - s.array(oam); - s.array(bgp); - s.array(obp[0]); - s.array(obp[1]); - s.array(bgpd); - s.array(obpd); - - s.integer(status.lx); - s.integer(status.wyc); - - s.integer(status.display_enable); - s.integer(status.window_tilemap_select); - s.integer(status.window_display_enable); - s.integer(status.bg_tiledata_select); - s.integer(status.bg_tilemap_select); - s.integer(status.ob_size); - s.integer(status.ob_enable); - s.integer(status.bg_enable); - - s.integer(status.interrupt_lyc); - s.integer(status.interrupt_oam); - s.integer(status.interrupt_vblank); - s.integer(status.interrupt_hblank); - - s.integer(status.scy); - s.integer(status.scx); - - s.integer(status.ly); - s.integer(status.lyc); - - s.integer(status.wy); - s.integer(status.wx); - - s.integer(status.vram_bank); - - s.integer(status.bgpi_increment); - s.integer(status.bgpi); - - s.integer(status.obpi_increment); - s.integer(status.obpi); -} - -#endif diff --git a/libsnes/bsnes/gameboy/system/serialization.cpp b/libsnes/bsnes/gameboy/system/serialization.cpp deleted file mode 100644 index c7ca0f8be3..0000000000 --- a/libsnes/bsnes/gameboy/system/serialization.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifdef SYSTEM_CPP - -serializer System::serialize() { - serializer s(serialize_size); - - unsigned signature = 0x31545342, version = Info::SerializerVersion, crc32 = 0; - char description[512]; - memset(&description, 0, sizeof description); - - s.integer(signature); - s.integer(version); - s.integer(crc32); - s.array(description); - - serialize_all(s); - return s; -} - -bool System::unserialize(serializer &s) { - unsigned signature, version, crc32; - char description[512]; - - s.integer(signature); - s.integer(version); - s.integer(crc32); - s.array(description); - - if(signature != 0x31545342) return false; - if(version != Info::SerializerVersion) return false; -//if(crc32 != 0) return false; - - power(); - serialize_all(s); - return true; -} - -void System::serialize(serializer &s) { - s.integer(clocks_executed); -} - -void System::serialize_all(serializer &s) { - cartridge.serialize(s); - system.serialize(s); - cpu.serialize(s); - apu.serialize(s); - lcd.serialize(s); -} - -void System::serialize_init() { - serializer s; - - unsigned signature = 0, version = 0, crc32 = 0; - char description[512]; - - s.integer(signature); - s.integer(version); - s.integer(crc32); - s.array(description); - - serialize_all(s); - serialize_size = s.size(); -} - -#endif diff --git a/libsnes/bsnes/libco/amd64.c b/libsnes/bsnes/libco/amd64.c deleted file mode 100644 index 5f1cfca97a..0000000000 --- a/libsnes/bsnes/libco/amd64.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - libco.amd64 (2009-10-12) - author: byuu - license: public domain -*/ - -#define LIBCO_C -#include "libco.h" -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -static thread_local long long co_active_buffer[64]; -static thread_local cothread_t co_active_handle = 0; -static void (*co_swap)(cothread_t, cothread_t) = 0; - -#ifdef _WIN32 - //ABI: Win64 - static unsigned char co_swap_function[] = { - 0x48, 0x89, 0x22, 0x48, 0x8B, 0x21, 0x58, 0x48, 0x89, 0x6A, 0x08, 0x48, 0x89, 0x72, 0x10, 0x48, - 0x89, 0x7A, 0x18, 0x48, 0x89, 0x5A, 0x20, 0x4C, 0x89, 0x62, 0x28, 0x4C, 0x89, 0x6A, 0x30, 0x4C, - 0x89, 0x72, 0x38, 0x4C, 0x89, 0x7A, 0x40, 0x48, 0x81, 0xC2, 0x80, 0x00, 0x00, 0x00, 0x48, 0x83, - 0xE2, 0xF0, 0x0F, 0x29, 0x32, 0x0F, 0x29, 0x7A, 0x10, 0x44, 0x0F, 0x29, 0x42, 0x20, 0x44, 0x0F, - 0x29, 0x4A, 0x30, 0x44, 0x0F, 0x29, 0x52, 0x40, 0x44, 0x0F, 0x29, 0x5A, 0x50, 0x44, 0x0F, 0x29, - 0x62, 0x60, 0x44, 0x0F, 0x29, 0x6A, 0x70, 0x44, 0x0F, 0x29, 0xB2, 0x80, 0x00, 0x00, 0x00, 0x44, - 0x0F, 0x29, 0xBA, 0x90, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x69, 0x08, 0x48, 0x8B, 0x71, 0x10, 0x48, - 0x8B, 0x79, 0x18, 0x48, 0x8B, 0x59, 0x20, 0x4C, 0x8B, 0x61, 0x28, 0x4C, 0x8B, 0x69, 0x30, 0x4C, - 0x8B, 0x71, 0x38, 0x4C, 0x8B, 0x79, 0x40, 0x48, 0x81, 0xC1, 0x80, 0x00, 0x00, 0x00, 0x48, 0x83, - 0xE1, 0xF0, 0x0F, 0x29, 0x31, 0x0F, 0x29, 0x79, 0x10, 0x44, 0x0F, 0x29, 0x41, 0x20, 0x44, 0x0F, - 0x29, 0x49, 0x30, 0x44, 0x0F, 0x29, 0x51, 0x40, 0x44, 0x0F, 0x29, 0x59, 0x50, 0x44, 0x0F, 0x29, - 0x61, 0x60, 0x44, 0x0F, 0x29, 0x69, 0x70, 0x44, 0x0F, 0x29, 0xB1, 0x80, 0x00, 0x00, 0x00, 0x44, - 0x0F, 0x29, 0xB9, 0x90, 0x00, 0x00, 0x00, 0xFF, 0xE0, - }; - - #include - - void co_init() { - DWORD old_privileges; - VirtualProtect(co_swap_function, sizeof co_swap_function, PAGE_EXECUTE_READWRITE, &old_privileges); - } -#else - //ABI: SystemV - static unsigned char co_swap_function[] = { - 0x48, 0x89, 0x26, 0x48, 0x8B, 0x27, 0x58, 0x48, 0x89, 0x6E, 0x08, 0x48, 0x89, 0x5E, 0x10, 0x4C, - 0x89, 0x66, 0x18, 0x4C, 0x89, 0x6E, 0x20, 0x4C, 0x89, 0x76, 0x28, 0x4C, 0x89, 0x7E, 0x30, 0x48, - 0x8B, 0x6F, 0x08, 0x48, 0x8B, 0x5F, 0x10, 0x4C, 0x8B, 0x67, 0x18, 0x4C, 0x8B, 0x6F, 0x20, 0x4C, - 0x8B, 0x77, 0x28, 0x4C, 0x8B, 0x7F, 0x30, 0xFF, 0xE0, - }; - - #include - #include - - void co_init() { - unsigned long long addr = (unsigned long long)co_swap_function; - unsigned long long base = addr - (addr % sysconf(_SC_PAGESIZE)); - unsigned long long size = (addr - base) + sizeof co_swap_function; - mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC); - } -#endif - -static void crash() { - assert(0); /* called only if cothread_t entrypoint returns */ -} - -cothread_t co_active() { - if(!co_active_handle) co_active_handle = &co_active_buffer; - return co_active_handle; -} - -cothread_t co_create(unsigned int size, void (*entrypoint)(void)) { - cothread_t handle; - if(!co_swap) { - co_init(); - co_swap = (void (*)(cothread_t, cothread_t))co_swap_function; - } - if(!co_active_handle) co_active_handle = &co_active_buffer; - size += 512; /* allocate additional space for storage */ - size &= ~15; /* align stack to 16-byte boundary */ - - if(handle = (cothread_t)malloc(size)) { - long long *p = (long long*)((char*)handle + size); /* seek to top of stack */ - *--p = (long long)crash; /* crash if entrypoint returns */ - *--p = (long long)entrypoint; /* start of function */ - *(long long*)handle = (long long)p; /* stack pointer */ - } - - return handle; -} - -void co_delete(cothread_t handle) { - free(handle); -} - -void co_switch(cothread_t handle) { - register cothread_t co_previous_handle = co_active_handle; - co_swap(co_active_handle = handle, co_previous_handle); -} - -#ifdef __cplusplus -} -#endif diff --git a/libsnes/bsnes/libco/fiber.c b/libsnes/bsnes/libco/fiber.c deleted file mode 100644 index 02ef5bc788..0000000000 --- a/libsnes/bsnes/libco/fiber.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - libco.win (2008-01-28) - authors: Nach, byuu - license: public domain -*/ - -#define LIBCO_C -#include "libco.h" -#define WINVER 0x0400 -#define _WIN32_WINNT 0x0400 -#define WIN32_LEAN_AND_MEAN -#include - -#ifdef __cplusplus -extern "C" { -#endif - -static thread_local cothread_t co_active_ = 0; - -static void __stdcall co_thunk(void *coentry) { - ((void (*)(void))coentry)(); -} - -cothread_t co_active() { - if(!co_active_) { - ConvertThreadToFiber(0); - co_active_ = GetCurrentFiber(); - } - return co_active_; -} - -cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) { - if(!co_active_) { - ConvertThreadToFiber(0); - co_active_ = GetCurrentFiber(); - } - return (cothread_t)CreateFiber(heapsize, co_thunk, (void*)coentry); -} - -void co_delete(cothread_t cothread) { - DeleteFiber(cothread); -} - -void co_switch(cothread_t cothread) { - co_active_ = cothread; - SwitchToFiber(cothread); -} - -#ifdef __cplusplus -} -#endif diff --git a/libsnes/bsnes/libco/libco.c b/libsnes/bsnes/libco/libco.c deleted file mode 100644 index 766e2b4cf8..0000000000 --- a/libsnes/bsnes/libco/libco.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - libco - auto-selection module - license: public domain -*/ - -#if (defined(__ARM_EABI__) || defined(__ARMCC_VERSION) ) - #include "sjlj-multi.c" -#elif defined(__GNUC__) && defined(__i386__) - #if !defined(LIBCO_MSVC) - #include "x86.c" - #endif -#elif defined(__GNUC__) && defined(__amd64__) - #include "amd64.c" -#elif defined(__GNUC__) && defined(_ARCH_PPC) - #include "ppc.c" -#elif defined(__GNUC__) - #include "sjlj.c" -#elif defined(_MSC_VER) && defined(_M_IX86) - #include "x86.c" -#elif defined(_MSC_VER) && defined(_M_AMD64) - #include "amd64.c" -#elif defined(_MSC_VER) - #include "fiber.c" -#else - #error "libco: unsupported processor, compiler or operating system" -#endif diff --git a/libsnes/bsnes/libco/libco.h b/libsnes/bsnes/libco/libco.h deleted file mode 100644 index a32f95fdad..0000000000 --- a/libsnes/bsnes/libco/libco.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - libco - version: 0.16 (2010-12-24) - license: public domain -*/ - -#ifndef LIBCO_H -#define LIBCO_H - -#ifdef LIBCO_C - #ifdef LIBCO_MP - #define thread_local __thread - #else - #define thread_local - #endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void* cothread_t; -typedef void (*coentry_t)(void); - -void* co_getstack(cothread_t); -cothread_t co_active(); -cothread_t co_create_withstack(void* stack, int stacksize, coentry_t); -cothread_t co_create(unsigned int, coentry_t); -void co_delete(cothread_t); -void co_switch(cothread_t); -cothread_t co_primary(); - -#ifdef __cplusplus -} -#endif - -/* ifndef LIBCO_H */ -#endif diff --git a/libsnes/bsnes/libco/ppc.c b/libsnes/bsnes/libco/ppc.c deleted file mode 100644 index a6028fdba2..0000000000 --- a/libsnes/bsnes/libco/ppc.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - libco.ppc (2010-10-17) - author: blargg - license: public domain -*/ - -/* PowerPC 32/64 using embedded or external asm, with optional -floating-point and AltiVec save/restore */ - -#define LIBCO_C -#include "libco.h" -#include -#include -#include - -#define LIBCO_MPROTECT (__unix__ && !LIBCO_PPC_ASM) - -#if LIBCO_MPROTECT - #include - #include -#endif - -/* State format (offsets in 32-bit words) - -+0 Pointer to swap code - Rest of function descriptor for entry function -+8 PC -+10 SP - Special regs - GPRs - FPRs - VRs - stack -*/ - -enum { state_size = 1024 }; -enum { above_stack = 2048 }; -enum { stack_align = 256 }; - -static thread_local cothread_t co_active_handle = 0; - -/**** Determine environment ****/ - -#define LIBCO_PPC64 (_ARCH_PPC64 || __PPC64__ || __ppc64__ || __powerpc64__) - -/* Whether function calls are indirect through a descriptor, -or are directly to function */ -#ifndef LIBCO_PPCDESC - #if !_CALL_SYSV && (_CALL_AIX || _CALL_AIXDESC || LIBCO_PPC64) - #define LIBCO_PPCDESC 1 - #endif -#endif - -#ifdef LIBCO_PPC_ASM - - #ifdef __cplusplus - extern "C" - #endif - - /* Swap code is in ppc.S */ - void co_swap_asm( cothread_t, cothread_t ); - #define CO_SWAP_ASM( x, y ) co_swap_asm( x, y ) - -#else - -/* Swap code is here in array. Please leave dieassembly comments, -as they make it easy to see what it does, and reorder instructions -if one wants to see whether that improves performance. */ -static const uint32_t libco_ppc_code [] = { -#if LIBCO_PPC64 - 0x7d000026, /* mfcr r8 */ - 0xf8240028, /* std r1,40(r4) */ - 0x7d2802a6, /* mflr r9 */ - 0xf9c40048, /* std r14,72(r4) */ - 0xf9e40050, /* std r15,80(r4) */ - 0xfa040058, /* std r16,88(r4) */ - 0xfa240060, /* std r17,96(r4) */ - 0xfa440068, /* std r18,104(r4) */ - 0xfa640070, /* std r19,112(r4) */ - 0xfa840078, /* std r20,120(r4) */ - 0xfaa40080, /* std r21,128(r4) */ - 0xfac40088, /* std r22,136(r4) */ - 0xfae40090, /* std r23,144(r4) */ - 0xfb040098, /* std r24,152(r4) */ - 0xfb2400a0, /* std r25,160(r4) */ - 0xfb4400a8, /* std r26,168(r4) */ - 0xfb6400b0, /* std r27,176(r4) */ - 0xfb8400b8, /* std r28,184(r4) */ - 0xfba400c0, /* std r29,192(r4) */ - 0xfbc400c8, /* std r30,200(r4) */ - 0xfbe400d0, /* std r31,208(r4) */ - 0xf9240020, /* std r9,32(r4) */ - 0xe8e30020, /* ld r7,32(r3) */ - 0xe8230028, /* ld r1,40(r3) */ - 0x48000009, /* bl 1 */ - 0x7fe00008, /* trap */ - 0x91040030,/*1:stw r8,48(r4) */ - 0x80c30030, /* lwz r6,48(r3) */ - 0x7ce903a6, /* mtctr r7 */ - 0xe9c30048, /* ld r14,72(r3) */ - 0xe9e30050, /* ld r15,80(r3) */ - 0xea030058, /* ld r16,88(r3) */ - 0xea230060, /* ld r17,96(r3) */ - 0xea430068, /* ld r18,104(r3) */ - 0xea630070, /* ld r19,112(r3) */ - 0xea830078, /* ld r20,120(r3) */ - 0xeaa30080, /* ld r21,128(r3) */ - 0xeac30088, /* ld r22,136(r3) */ - 0xeae30090, /* ld r23,144(r3) */ - 0xeb030098, /* ld r24,152(r3) */ - 0xeb2300a0, /* ld r25,160(r3) */ - 0xeb4300a8, /* ld r26,168(r3) */ - 0xeb6300b0, /* ld r27,176(r3) */ - 0xeb8300b8, /* ld r28,184(r3) */ - 0xeba300c0, /* ld r29,192(r3) */ - 0xebc300c8, /* ld r30,200(r3) */ - 0xebe300d0, /* ld r31,208(r3) */ - 0x7ccff120, /* mtcr r6 */ -#else - 0x7d000026, /* mfcr r8 */ - 0x90240028, /* stw r1,40(r4) */ - 0x7d2802a6, /* mflr r9 */ - 0x91a4003c, /* stw r13,60(r4) */ - 0x91c40040, /* stw r14,64(r4) */ - 0x91e40044, /* stw r15,68(r4) */ - 0x92040048, /* stw r16,72(r4) */ - 0x9224004c, /* stw r17,76(r4) */ - 0x92440050, /* stw r18,80(r4) */ - 0x92640054, /* stw r19,84(r4) */ - 0x92840058, /* stw r20,88(r4) */ - 0x92a4005c, /* stw r21,92(r4) */ - 0x92c40060, /* stw r22,96(r4) */ - 0x92e40064, /* stw r23,100(r4) */ - 0x93040068, /* stw r24,104(r4) */ - 0x9324006c, /* stw r25,108(r4) */ - 0x93440070, /* stw r26,112(r4) */ - 0x93640074, /* stw r27,116(r4) */ - 0x93840078, /* stw r28,120(r4) */ - 0x93a4007c, /* stw r29,124(r4) */ - 0x93c40080, /* stw r30,128(r4) */ - 0x93e40084, /* stw r31,132(r4) */ - 0x91240020, /* stw r9,32(r4) */ - 0x80e30020, /* lwz r7,32(r3) */ - 0x80230028, /* lwz r1,40(r3) */ - 0x48000009, /* bl 1 */ - 0x7fe00008, /* trap */ - 0x91040030,/*1:stw r8,48(r4) */ - 0x80c30030, /* lwz r6,48(r3) */ - 0x7ce903a6, /* mtctr r7 */ - 0x81a3003c, /* lwz r13,60(r3) */ - 0x81c30040, /* lwz r14,64(r3) */ - 0x81e30044, /* lwz r15,68(r3) */ - 0x82030048, /* lwz r16,72(r3) */ - 0x8223004c, /* lwz r17,76(r3) */ - 0x82430050, /* lwz r18,80(r3) */ - 0x82630054, /* lwz r19,84(r3) */ - 0x82830058, /* lwz r20,88(r3) */ - 0x82a3005c, /* lwz r21,92(r3) */ - 0x82c30060, /* lwz r22,96(r3) */ - 0x82e30064, /* lwz r23,100(r3) */ - 0x83030068, /* lwz r24,104(r3) */ - 0x8323006c, /* lwz r25,108(r3) */ - 0x83430070, /* lwz r26,112(r3) */ - 0x83630074, /* lwz r27,116(r3) */ - 0x83830078, /* lwz r28,120(r3) */ - 0x83a3007c, /* lwz r29,124(r3) */ - 0x83c30080, /* lwz r30,128(r3) */ - 0x83e30084, /* lwz r31,132(r3) */ - 0x7ccff120, /* mtcr r6 */ -#endif - -#ifndef LIBCO_PPC_NOFP - 0xd9c400e0, /* stfd f14,224(r4) */ - 0xd9e400e8, /* stfd f15,232(r4) */ - 0xda0400f0, /* stfd f16,240(r4) */ - 0xda2400f8, /* stfd f17,248(r4) */ - 0xda440100, /* stfd f18,256(r4) */ - 0xda640108, /* stfd f19,264(r4) */ - 0xda840110, /* stfd f20,272(r4) */ - 0xdaa40118, /* stfd f21,280(r4) */ - 0xdac40120, /* stfd f22,288(r4) */ - 0xdae40128, /* stfd f23,296(r4) */ - 0xdb040130, /* stfd f24,304(r4) */ - 0xdb240138, /* stfd f25,312(r4) */ - 0xdb440140, /* stfd f26,320(r4) */ - 0xdb640148, /* stfd f27,328(r4) */ - 0xdb840150, /* stfd f28,336(r4) */ - 0xdba40158, /* stfd f29,344(r4) */ - 0xdbc40160, /* stfd f30,352(r4) */ - 0xdbe40168, /* stfd f31,360(r4) */ - 0xc9c300e0, /* lfd f14,224(r3) */ - 0xc9e300e8, /* lfd f15,232(r3) */ - 0xca0300f0, /* lfd f16,240(r3) */ - 0xca2300f8, /* lfd f17,248(r3) */ - 0xca430100, /* lfd f18,256(r3) */ - 0xca630108, /* lfd f19,264(r3) */ - 0xca830110, /* lfd f20,272(r3) */ - 0xcaa30118, /* lfd f21,280(r3) */ - 0xcac30120, /* lfd f22,288(r3) */ - 0xcae30128, /* lfd f23,296(r3) */ - 0xcb030130, /* lfd f24,304(r3) */ - 0xcb230138, /* lfd f25,312(r3) */ - 0xcb430140, /* lfd f26,320(r3) */ - 0xcb630148, /* lfd f27,328(r3) */ - 0xcb830150, /* lfd f28,336(r3) */ - 0xcba30158, /* lfd f29,344(r3) */ - 0xcbc30160, /* lfd f30,352(r3) */ - 0xcbe30168, /* lfd f31,360(r3) */ -#endif - -#ifdef __ALTIVEC__ - 0x7ca042a6, /* mfvrsave r5 */ - 0x39040180, /* addi r8,r4,384 */ - 0x39240190, /* addi r9,r4,400 */ - 0x70a00fff, /* andi. r0,r5,4095 */ - 0x90a40034, /* stw r5,52(r4) */ - 0x4182005c, /* beq- 2 */ - 0x7e8041ce, /* stvx v20,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7ea049ce, /* stvx v21,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7ec041ce, /* stvx v22,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7ee049ce, /* stvx v23,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7f0041ce, /* stvx v24,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7f2049ce, /* stvx v25,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7f4041ce, /* stvx v26,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7f6049ce, /* stvx v27,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7f8041ce, /* stvx v28,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7fa049ce, /* stvx v29,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7fc041ce, /* stvx v30,r0,r8 */ - 0x7fe049ce, /* stvx v31,r0,r9 */ - 0x80a30034,/*2:lwz r5,52(r3) */ - 0x39030180, /* addi r8,r3,384 */ - 0x39230190, /* addi r9,r3,400 */ - 0x70a00fff, /* andi. r0,r5,4095 */ - 0x7ca043a6, /* mtvrsave r5 */ - 0x4d820420, /* beqctr */ - 0x7e8040ce, /* lvx v20,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7ea048ce, /* lvx v21,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7ec040ce, /* lvx v22,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7ee048ce, /* lvx v23,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7f0040ce, /* lvx v24,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7f2048ce, /* lvx v25,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7f4040ce, /* lvx v26,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7f6048ce, /* lvx v27,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7f8040ce, /* lvx v28,r0,r8 */ - 0x39080020, /* addi r8,r8,32 */ - 0x7fa048ce, /* lvx v29,r0,r9 */ - 0x39290020, /* addi r9,r9,32 */ - 0x7fc040ce, /* lvx v30,r0,r8 */ - 0x7fe048ce, /* lvx v31,r0,r9 */ -#endif - - 0x4e800420, /* bctr */ -}; - - #if LIBCO_PPCDESC - /* Function call goes through indirect descriptor */ - #define CO_SWAP_ASM( x, y ) \ - ((void (*)( cothread_t, cothread_t )) (uintptr_t) x)( x, y ) - #else - /* Function call goes directly to code */ - #define CO_SWAP_ASM( x, y ) \ - ((void (*)( cothread_t, cothread_t )) (uintptr_t) libco_ppc_code)( x, y ) - #endif - -#endif - -static uint32_t* co_create_( unsigned size, uintptr_t entry ) -{ - uint32_t* t = (uint32_t*) malloc( size ); - - (void) entry; - - #if LIBCO_PPCDESC - if ( t ) - { - /* Copy entry's descriptor */ - memcpy( t, (void*) entry, sizeof (void*) * 3 ); - - /* Set function pointer to swap routine */ - #ifdef LIBCO_PPC_ASM - *(const void**) t = *(void**) &co_swap_asm; - #else - *(const void**) t = libco_ppc_code; - #endif - } - #endif - - return t; -} - -cothread_t co_create( unsigned int size, void (*entry_)( void ) ) -{ - uintptr_t entry = (uintptr_t) entry_; - uint32_t* t = NULL; - - /* Be sure main thread was successfully allocated */ - if ( co_active() ) - { - size += state_size + above_stack + stack_align; - t = co_create_( size, entry ); - } - - if ( t ) - { - uintptr_t sp; - int shift; - - /* Save current registers into new thread, so that any special ones will - have proper values when thread is begun */ - CO_SWAP_ASM( t, t ); - - #if LIBCO_PPCDESC - /* Get real address */ - entry = (uintptr_t) *(void**) entry; - #endif - - /* Put stack near end of block, and align */ - sp = (uintptr_t) t + size - above_stack; - sp -= sp % stack_align; - - /* On PPC32, we save and restore GPRs as 32 bits. For PPC64, we - save and restore them as 64 bits, regardless of the size the ABI - uses. So, we manually write pointers at the proper size. We always - save and restore at the same address, and since PPC is big-endian, - we must put the low byte first on PPC32. */ - - /* If uintptr_t is 32 bits, >>32 is undefined behavior, so we do two shifts - and don't have to care how many bits uintptr_t is. */ - #if LIBCO_PPC64 - shift = 16; - #else - shift = 0; - #endif - - /* Set up so entry will be called on next swap */ - t [8] = (uint32_t) (entry >> shift >> shift); - t [9] = (uint32_t) entry; - - t [10] = (uint32_t) (sp >> shift >> shift); - t [11] = (uint32_t) sp; - } - - return t; -} - -void co_delete( cothread_t t ) -{ - free( t ); -} - -static void co_init_( void ) -{ - #if LIBCO_MPROTECT - /* TODO: pre- and post-pad PPC code so that this doesn't make other - data executable and writable */ - long page_size = sysconf( _SC_PAGESIZE ); - if ( page_size > 0 ) - { - uintptr_t align = page_size; - uintptr_t begin = (uintptr_t) libco_ppc_code; - uintptr_t end = begin + sizeof libco_ppc_code; - - /* Align beginning and end */ - end += align - 1; - end -= end % align; - begin -= begin % align; - - mprotect( (void*) begin, end - begin, PROT_READ | PROT_WRITE | PROT_EXEC ); - } - #endif - - co_active_handle = co_create_( state_size, (uintptr_t) &co_switch ); -} - -cothread_t co_active() -{ - if ( !co_active_handle ) - co_init_(); - - return co_active_handle; -} - -void co_switch( cothread_t t ) -{ - cothread_t old = co_active_handle; - co_active_handle = t; - - CO_SWAP_ASM( t, old ); -} diff --git a/libsnes/bsnes/libco/sjlj-multi.c b/libsnes/bsnes/libco/sjlj-multi.c deleted file mode 100644 index 2ba14cfe84..0000000000 --- a/libsnes/bsnes/libco/sjlj-multi.c +++ /dev/null @@ -1,237 +0,0 @@ -/* -original author: Nach -license: public domain - -additional work: zeromus -note: more ARM compilers are supported here (check the ifdefs in _JUMP_BUFFER) -and: work has been done to make this coexist more peaceably with .net -*/ - - - -#define LIBCO_C -#include "libco.h" -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct -{ - jmp_buf context; - coentry_t coentry; - void *stack; - unsigned long seh_frame, stack_top, stack_bottom; - cothread_t caller; - int ownstack; -} cothread_struct; - -static thread_local cothread_struct _co_primary; -static thread_local cothread_struct *co_running = 0; - -cothread_t co_primary() { return (cothread_t)&_co_primary; } - - -//------------------- -#ifdef _MSC_VER - -//links of interest -//http://connect.microsoft.com/VisualStudio/feedback/details/100319/really-wierd-behaviour-in-crt-io-coupled-with-some-inline-assembly -//http://en.wikipedia.org/wiki/Thread_Information_Block -//http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/72093e46-4524-4f54-9f36-c7e8a309d1db/ //FS warning - - -#define WINVER 0x0400 -#define _WIN32_WINNT 0x0400 -#define WIN32_LEAN_AND_MEAN -#include - -#pragma warning(disable:4733) -#pragma warning(disable:4311) - -static void capture_fs(cothread_struct* rec) -{ - int temp; - __asm mov eax, dword ptr fs:[0]; - __asm mov temp, eax; - rec->seh_frame = temp; - __asm mov eax, dword ptr fs:[4]; - __asm mov temp, eax; - rec->stack_top = temp; - __asm mov eax, dword ptr fs:[8]; - __asm mov temp, eax; - rec->stack_bottom = temp; -} - -static void restore_fs(cothread_struct* rec) -{ - int temp; - temp = rec->seh_frame; - __asm mov eax, temp; - __asm mov dword ptr fs:[0], eax - temp = rec->stack_top; - __asm mov eax, temp; - __asm mov dword ptr fs:[4], eax - temp = rec->stack_bottom; - __asm mov eax, temp; - __asm mov dword ptr fs:[8], eax -} - -static void os_co_wrapper() -{ - cothread_struct* rec = (cothread_struct*)co_active(); - __try - { - rec->coentry(); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - //unhandled win32 exception in coroutine. - //this coroutine will now be suspended permanently and control will be yielded to caller, for lack of anything better to do. - //perhaps the process should just terminate. - for(;;) - { - //dead coroutine - co_switch(rec->caller); - } - } -} - -static void os_co_create(cothread_struct* rec, unsigned int size, coentry_t coentry) -{ - _JUMP_BUFFER* jb = (_JUMP_BUFFER*)&rec->context; - cothread_struct temp; - - jb->Esp = (unsigned long)rec->stack + size - 4; - jb->Eip = (unsigned long)os_co_wrapper; - - rec->stack_top = jb->Esp + 4; - rec->stack_bottom = (unsigned long)rec->stack; - - //wild assumption about SEH frame.. seems to work - capture_fs(&temp); - rec->seh_frame = temp.seh_frame; -} - -static void os_pre_setjmp(cothread_t target) -{ - cothread_struct* rec = (cothread_struct*)target; - capture_fs(co_running); - rec->caller = co_running; -} - -static void os_pre_longjmp(cothread_struct* rec) -{ - restore_fs(rec); -} - -#elif defined(__ARM_EABI__) || defined(__ARMCC_VERSION) - -//http://sourceware.org/cgi-bin/cvsweb.cgi/src/newlib/libc/machine/arm/setjmp.S?rev=1.5&content-type=text/x-cvsweb-markup&cvsroot=src - -typedef struct -{ -#ifdef LIBCO_ARM_JUMBLED - int r8,r9,r10,r11,lr,r4,r5,r6,r7,sp; -#else - int r4,r5,r6,r7,r8,r9,r10,fp; - #ifndef LIBCO_ARM_NOIP - int ip; - #endif - int sp,lr; -#endif -} _JUMP_BUFFER; - -static void os_co_create(cothread_struct* rec, unsigned int size, coentry_t coentry) -{ - _JUMP_BUFFER* jb = (_JUMP_BUFFER*)&rec->context; - - jb->sp = (unsigned long)rec->stack + size - 4; - jb->lr = (unsigned long)coentry; -} - -static void os_pre_setjmp(cothread_t target) -{ - cothread_struct* rec = (cothread_struct*)target; - rec->caller = co_running; -} - -static void os_pre_longjmp(cothread_struct* rec) -{ -} - -#else -#error "sjlj-multi: unsupported processor, compiler or operating system" -#endif -//------------------- - -cothread_t co_active() -{ - if(!co_running) co_running = &_co_primary; - return (cothread_t)co_running; -} - -void* co_getstack(cothread_t cothread) -{ - return ((cothread_struct*)cothread)->stack; -} - -cothread_t co_create(unsigned int stacksize, coentry_t coentry) -{ - cothread_struct* ret = (cothread_struct*)co_create_withstack(malloc(stacksize), stacksize, coentry); - if(ret) - ret->ownstack = 1; - return (cothread_t)ret; -} - -cothread_t co_create_withstack(void* stack, int stacksize, coentry_t coentry) -{ - cothread_struct *thread; - - if(!co_running) co_running = &_co_primary; - - thread = (cothread_struct*)malloc(sizeof(cothread_struct)); - if(thread) - { - thread->coentry = coentry; - thread->stack = stack; - - { - setjmp(thread->context); - os_co_create(thread,stacksize,coentry); - } - thread->ownstack = 0; - } - - return (cothread_t)thread; -} - -void co_delete(cothread_t cothread) -{ - if(cothread) - { - cothread_struct* thread = (cothread_struct*)cothread; - if (thread->ownstack) - free(thread->stack); - free(cothread); - } -} - -void co_switch(cothread_t cothread) -{ - os_pre_setjmp(cothread); - if(!setjmp(co_running->context)) - { - co_running = (cothread_struct*)cothread; - os_pre_longjmp(co_running); - longjmp(co_running->context,0); - } -} - -#ifdef __cplusplus -} -#endif diff --git a/libsnes/bsnes/libco/sjlj.c b/libsnes/bsnes/libco/sjlj.c deleted file mode 100644 index 8b72b614e3..0000000000 --- a/libsnes/bsnes/libco/sjlj.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - libco.sjlj (2008-01-28) - author: Nach - license: public domain -*/ - -/* - * Note this was designed for UNIX systems. Based on ideas expressed in a paper - * by Ralf Engelschall. - * For SJLJ on other systems, one would want to rewrite springboard() and - * co_create() and hack the jmb_buf stack pointer. - */ - -#define LIBCO_C -#include "libco.h" -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - sigjmp_buf context; - void (*coentry)(void); - void *stack; -} cothread_struct; - -static thread_local cothread_struct co_primary; -static thread_local cothread_struct *creating, *co_running = 0; - -static void springboard(int ignored) { - if(sigsetjmp(creating->context, 0)) { - co_running->coentry(); - } -} - -cothread_t co_active() { - if(!co_running) co_running = &co_primary; - return (cothread_t)co_running; -} - -cothread_t co_create(unsigned int size, void (*coentry)(void)) { - if(!co_running) co_running = &co_primary; - - cothread_struct *thread = (cothread_struct*)malloc(sizeof(cothread_struct)); - if(thread) { - struct sigaction handler; - struct sigaction old_handler; - - stack_t stack; - stack_t old_stack; - - thread->coentry = thread->stack = 0; - - stack.ss_flags = 0; - stack.ss_size = size; - thread->stack = stack.ss_sp = malloc(size); - if(stack.ss_sp && !sigaltstack(&stack, &old_stack)) { - handler.sa_handler = springboard; - handler.sa_flags = SA_ONSTACK; - sigemptyset(&handler.sa_mask); - creating = thread; - - if(!sigaction(SIGUSR1, &handler, &old_handler)) { - if(!raise(SIGUSR1)) { - thread->coentry = coentry; - } - sigaltstack(&old_stack, 0); - sigaction(SIGUSR1, &old_handler, 0); - } - } - - if(thread->coentry != coentry) { - co_delete(thread); - thread = 0; - } - } - - return (cothread_t)thread; -} - -void co_delete(cothread_t cothread) { - if(cothread) { - if(((cothread_struct*)cothread)->stack) { - free(((cothread_struct*)cothread)->stack); - } - free(cothread); - } -} - -void co_switch(cothread_t cothread) { - if(!sigsetjmp(co_running->context, 0)) { - co_running = (cothread_struct*)cothread; - siglongjmp(co_running->context, 1); - } -} - -#ifdef __cplusplus -} -#endif diff --git a/libsnes/bsnes/libco/ucontext.c b/libsnes/bsnes/libco/ucontext.c deleted file mode 100644 index 17472f6bcc..0000000000 --- a/libsnes/bsnes/libco/ucontext.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - libco.ucontext (2008-01-28) - author: Nach - license: public domain -*/ - -/* - * WARNING: the overhead of POSIX ucontext is very high, - * assembly versions of libco or libco_sjlj should be much faster - * - * This library only exists for two reasons: - * 1 - as an initial test for the viability of a ucontext implementation - * 2 - to demonstrate the power and speed of libco over existing implementations, - * such as pth (which defaults to wrapping ucontext on unix targets) - * - * Use this library only as a *last resort* - */ - -#define LIBCO_C -#include "libco.h" -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -static thread_local ucontext_t co_primary; -static thread_local ucontext_t *co_running = 0; - -cothread_t co_active() { - if(!co_running) co_running = &co_primary; - return (cothread_t)co_running; -} - -cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) { - if(!co_running) co_running = &co_primary; - ucontext_t *thread = (ucontext_t*)malloc(sizeof(ucontext_t)); - if(thread) { - if((!getcontext(thread) && !(thread->uc_stack.ss_sp = 0)) && (thread->uc_stack.ss_sp = malloc(heapsize))) { - thread->uc_link = co_running; - thread->uc_stack.ss_size = heapsize; - makecontext(thread, coentry, 0); - } else { - co_delete((cothread_t)thread); - thread = 0; - } - } - return (cothread_t)thread; -} - -void co_delete(cothread_t cothread) { - if(cothread) { - if(((ucontext_t*)cothread)->uc_stack.ss_sp) { free(((ucontext_t*)cothread)->uc_stack.ss_sp); } - free(cothread); - } -} - -void co_switch(cothread_t cothread) { - ucontext_t *old_thread = co_running; - co_running = (ucontext_t*)cothread; - swapcontext(old_thread, co_running); -} - -#ifdef __cplusplus -} -#endif diff --git a/libsnes/bsnes/libco/x86.c b/libsnes/bsnes/libco/x86.c deleted file mode 100644 index ebfc239535..0000000000 --- a/libsnes/bsnes/libco/x86.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - libco.x86 (2009-10-12) - author: byuu - license: public domain -*/ - -#define LIBCO_C -#include "libco.h" -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(_MSC_VER) - #define fastcall __fastcall -#elif defined(__GNUC__) - #define fastcall __attribute__((fastcall)) -#else - #error "libco: please define fastcall macro" -#endif - -static thread_local long co_active_buffer[64]; -static thread_local cothread_t co_active_handle = 0; -static void (fastcall *co_swap)(cothread_t, cothread_t) = 0; - -//ABI: fastcall -static unsigned char co_swap_function[] = { - 0x89, 0x22, /* mov [edx],esp */ - 0x8b, 0x21, /* mov esp,[ecx] */ - 0x58, /* pop eax */ - 0x89, 0x6a, 0x04, /* mov [edx+0x04],ebp */ - 0x89, 0x72, 0x08, /* mov [edx+0x08],esi */ - 0x89, 0x7a, 0x0c, /* mov [edx+0x0c],edi */ - 0x89, 0x5a, 0x10, /* mov [edx+0x10],ebx */ - 0x8b, 0x69, 0x04, /* mov ebp,[ecx+0x04] */ - 0x8b, 0x71, 0x08, /* mov esi,[ecx+0x08] */ - 0x8b, 0x79, 0x0c, /* mov edi,[ecx+0x0c] */ - 0x8b, 0x59, 0x10, /* mov ebx,[ecx+0x10] */ - 0xff, 0xe0, /* jmp eax */ -}; - -#ifdef _WIN32 -#include - -void co_init(void) -{ - DWORD old_privileges; - VirtualProtect(co_swap_function, - sizeof co_swap_function, PAGE_EXECUTE_READWRITE, &old_privileges); -} -#else -#include -#include - -void co_init(void) -{ - unsigned long addr = (unsigned long)co_swap_function; - unsigned long base = addr - (addr % sysconf(_SC_PAGESIZE)); - unsigned long size = (addr - base) + sizeof co_swap_function; - mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC); -} -#endif - -static void crash(void) -{ - assert(0); /* called only if cothread_t entrypoint returns */ -} - -cothread_t co_active(void) -{ - if(!co_active_handle) - co_active_handle = &co_active_buffer; - return co_active_handle; -} - -cothread_t co_create(unsigned int size, void (*entrypoint)(void)) -{ - cothread_t handle; - if(!co_swap) - { - co_init(); - co_swap = (void (fastcall*)(cothread_t, cothread_t))co_swap_function; - } - - if(!co_active_handle) - co_active_handle = &co_active_buffer; - - size += 256; /* allocate additional space for storage */ - size &= ~15; /* align stack to 16-byte boundary */ - - if((handle = (cothread_t)malloc(size))) - { - long *p = (long*)((char*)handle + size); /* seek to top of stack */ - *--p = (long)crash; /* crash if entrypoint returns */ - *--p = (long)entrypoint; /* start of function */ - *(long*)handle = (long)p; /* stack pointer */ - } - - return handle; -} - -void co_delete(cothread_t handle) -{ - free(handle); -} - -void co_switch(cothread_t handle) -{ - register cothread_t co_previous_handle = co_active_handle; - co_swap(co_active_handle = handle, co_previous_handle); -} - -#ifdef __cplusplus -} -#endif diff --git a/libsnes/bsnes/nall/Makefile b/libsnes/bsnes/nall/Makefile deleted file mode 100644 index c1437d141c..0000000000 --- a/libsnes/bsnes/nall/Makefile +++ /dev/null @@ -1,115 +0,0 @@ -# Makefile -# author: byuu -# license: public domain - -[A-Z] = 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 -[a-z] = 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-9] = 0 1 2 3 4 5 6 7 8 9 -[markup] = ` ~ ! @ \# $$ % ^ & * ( ) - _ = + [ { ] } \ | ; : ' " , < . > / ? -[all] = $([A-Z]) $([a-z]) $([0-9]) $([markup]) -[space] := -[space] += - -##### -# platform detection -##### - -ifeq ($(platform),) - uname := $(shell uname -a) - ifeq ($(uname),) - platform := win - delete = del $(subst /,\,$1) - else ifneq ($(findstring CYGWIN,$(uname)),) - platform := win - delete = del $(subst /,\,$1) - else ifneq ($(findstring Darwin,$(uname)),) - platform := osx - delete = rm -f $1 - else - platform := x - delete = rm -f $1 - endif -endif - -ifeq ($(compiler),) - ifeq ($(platform),win) - compiler := gcc - else ifeq ($(platform),osx) - compiler := gcc-mp-4.6 - else - compiler := gcc-4.6 - endif -endif - -c := $(compiler) -std=gnu99 -cpp := $(subst cc,++,$(compiler)) -std=gnu++0x - -ifeq ($(prefix),) - prefix := /usr/local -endif - -##### -# function rwildcard(directory, pattern) -##### -rwildcard = \ - $(strip \ - $(filter $(if $2,$2,%), \ - $(foreach f, \ - $(wildcard $1*), \ - $(eval t = $(call rwildcard,$f/)) \ - $(if $t,$t,$f) \ - ) \ - ) \ - ) - -##### -# function strtr(source, from, to) -##### -strtr = \ - $(eval __temp := $1) \ - $(strip \ - $(foreach c, \ - $(join $(addsuffix :,$2),$3), \ - $(eval __temp := \ - $(subst $(word 1,$(subst :, ,$c)),$(word 2,$(subst :, ,$c)),$(__temp)) \ - ) \ - ) \ - $(__temp) \ - ) - -##### -# function strupper(source) -##### -strupper = $(call strtr,$1,$([a-z]),$([A-Z])) - -##### -# function strlower(source) -##### -strlower = $(call strtr,$1,$([A-Z]),$([a-z])) - -##### -# function strlen(source) -##### -strlen = \ - $(eval __temp := $(subst $([space]),_,$1)) \ - $(words \ - $(strip \ - $(foreach c, \ - $([all]), \ - $(eval __temp := \ - $(subst $c,$c ,$(__temp)) \ - ) \ - ) \ - $(__temp) \ - ) \ - ) - -##### -# function streq(source) -##### -streq = $(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),,1) - -##### -# function strne(source) -##### -strne = $(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),1,) diff --git a/libsnes/bsnes/snes/Makefile b/libsnes/bsnes/snes/Makefile deleted file mode 100644 index 7d19c4a999..0000000000 --- a/libsnes/bsnes/snes/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -snes_objects := snes-interface snes-system snes-controller -snes_objects += snes-cartridge snes-cheat -snes_objects += snes-memory snes-cpucore snes-smpcore -snes_objects += snes-cpu snes-smp snes-dsp snes-ppu -snes_objects += snes-icd2 snes-nss snes-superfx snes-sa1 -snes_objects += snes-necdsp snes-hitachidsp snes-armdsp -snes_objects += snes-bsx snes-srtc snes-sdd1 snes-spc7110 -snes_objects += snes-obc1 snes-sufamiturbo -snes_objects += snes-msu1 snes-link -objects += $(snes_objects) - -ifeq ($(profile),accuracy) - flags += -DPROFILE_ACCURACY - snescpu := $(snes)/cpu - snessmp := $(snes)/smp - snesdsp := $(snes)/dsp - snesppu := $(snes)/ppu -else ifeq ($(profile),compatibility) - flags += -DPROFILE_COMPATIBILITY - snescpu := $(snes)/cpu - snessmp := $(snes)/smp - snesdsp := $(snes)/alt/dsp - snesppu := $(snes)/alt/ppu-compatibility -else ifeq ($(profile),performance) - flags += -DPROFILE_PERFORMANCE - snescpu := $(snes)/alt/cpu - snessmp := $(snes)/alt/smp - snesdsp := $(snes)/alt/dsp - snesppu := $(snes)/alt/ppu-performance -endif - -obj/snes-interface.o : $(snes)/interface/interface.cpp $(call rwildcard,$(snes)/interface) -obj/snes-system.o : $(snes)/system/system.cpp $(call rwildcard,$(snes)/system/) -obj/snes-controller.o: $(snes)/controller/controller.cpp $(call rwildcard,$(snes)/controller/) -obj/snes-memory.o : $(snes)/memory/memory.cpp $(call rwildcard,$(snes)/memory/) -obj/snes-cpucore.o : $(snes)/cpu/core/core.cpp $(call rwildcard,$(snes)/cpu/core/) -obj/snes-smpcore.o : $(snes)/smp/core/core.cpp $(call rwildcard,$(snes)/smp/core/) -obj/snes-cpu.o : $(snescpu)/cpu.cpp $(call rwildcard,$(snescpu)/) -obj/snes-smp.o : $(snessmp)/smp.cpp $(call rwildcard,$(snessmp)/) -obj/snes-dsp.o : $(snesdsp)/dsp.cpp $(call rwildcard,$(snesdsp)/) -obj/snes-ppu.o : $(snesppu)/ppu.cpp $(call rwildcard,$(snesppu)/) -obj/snes-cartridge.o : $(snes)/cartridge/cartridge.cpp $(snes)/cartridge/* -obj/snes-cheat.o : $(snes)/cheat/cheat.cpp $(snes)/cheat/* - -obj/snes-nss.o : $(snes)/chip/nss/nss.cpp $(call rwildcard,$(snes)/chip/nss/) -obj/snes-icd2.o : $(snes)/chip/icd2/icd2.cpp $(call rwildcard,$(snes)/chip/icd2/) -obj/snes-superfx.o : $(snes)/chip/superfx/superfx.cpp $(call rwildcard,$(snes)/chip/superfx/) -obj/snes-sa1.o : $(snes)/chip/sa1/sa1.cpp $(call rwildcard,$(snes)/chip/sa1/) -obj/snes-necdsp.o : $(snes)/chip/necdsp/necdsp.cpp $(call rwildcard,$(snes)/chip/necdsp/) -obj/snes-hitachidsp.o : $(snes)/chip/hitachidsp/hitachidsp.cpp $(call rwildcard,$(snes)/chip/hitachidsp/) -obj/snes-armdsp.o : $(snes)/chip/armdsp/armdsp.cpp $(call rwildcard,$(snes)/chip/armdsp/) -obj/snes-bsx.o : $(snes)/chip/bsx/bsx.cpp $(call rwildcard,$(snes)/chip/bsx/) -obj/snes-srtc.o : $(snes)/chip/srtc/srtc.cpp $(snes)/chip/srtc/* -obj/snes-sdd1.o : $(snes)/chip/sdd1/sdd1.cpp $(snes)/chip/sdd1/* -obj/snes-spc7110.o : $(snes)/chip/spc7110/spc7110.cpp $(snes)/chip/spc7110/* -obj/snes-obc1.o : $(snes)/chip/obc1/obc1.cpp $(snes)/chip/obc1/* -obj/snes-sufamiturbo.o: $(snes)/chip/sufamiturbo/sufamiturbo.cpp $(snes)/chip/sufamiturbo/* -obj/snes-msu1.o : $(snes)/chip/msu1/msu1.cpp $(snes)/chip/msu1/* -obj/snes-link.o : $(snes)/chip/link/link.cpp $(snes)/chip/link/* diff --git a/libsnes/bsnes/snes/alt/cpu/serialization.cpp b/libsnes/bsnes/snes/alt/cpu/serialization.cpp deleted file mode 100644 index 77990c8116..0000000000 --- a/libsnes/bsnes/snes/alt/cpu/serialization.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#ifdef CPU_CPP - -void CPU::serialize(serializer &s) { - Processor::serialize(s); - CPUcore::core_serialize(s); - PPUcounter::serialize(s); - - s.array(wram, 128 * 1024); - - queue.serialize(s); - s.array(port_data); - - for(unsigned i = 0; i < 8; i++) { - s.integer(channel[i].dma_enabled); - s.integer(channel[i].hdma_enabled); - - s.integer(channel[i].direction); - s.integer(channel[i].indirect); - s.integer(channel[i].unused); - s.integer(channel[i].reverse_transfer); - s.integer(channel[i].fixed_transfer); - s.integer(channel[i].transfer_mode); - - s.integer(channel[i].dest_addr); - s.integer(channel[i].source_addr); - s.integer(channel[i].source_bank); - - s.integer(channel[i].transfer_size); - - s.integer(channel[i].indirect_bank); - s.integer(channel[i].hdma_addr); - s.integer(channel[i].line_counter); - s.integer(channel[i].unknown); - - s.integer(channel[i].hdma_completed); - s.integer(channel[i].hdma_do_transfer); - } - - s.integer(status.nmi_valid); - s.integer(status.nmi_line); - s.integer(status.nmi_transition); - s.integer(status.nmi_pending); - - s.integer(status.irq_valid); - s.integer(status.irq_line); - s.integer(status.irq_transition); - s.integer(status.irq_pending); - - s.integer(status.irq_lock); - s.integer(status.hdma_pending); - - s.integer(status.wram_addr); - - s.integer(status.joypad_strobe_latch); - - s.integer(status.nmi_enabled); - s.integer(status.virq_enabled); - s.integer(status.hirq_enabled); - s.integer(status.auto_joypad_poll_enabled); - - s.integer(status.pio); - - s.integer(status.wrmpya); - s.integer(status.wrmpyb); - s.integer(status.wrdiva); - s.integer(status.wrdivb); - - s.integer(status.htime); - s.integer(status.vtime); - - s.integer(status.rom_speed); - - s.integer(status.rddiv); - s.integer(status.rdmpy); - - s.integer(status.joy1l); - s.integer(status.joy1h); - s.integer(status.joy2l); - s.integer(status.joy2h); - s.integer(status.joy3l); - s.integer(status.joy3h); - s.integer(status.joy4l); - s.integer(status.joy4h); -} - -#endif diff --git a/libsnes/bsnes/snes/alt/dsp/serialization.cpp b/libsnes/bsnes/snes/alt/dsp/serialization.cpp deleted file mode 100644 index 0565a1b5e9..0000000000 --- a/libsnes/bsnes/snes/alt/dsp/serialization.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#ifdef DSP_CPP - -static void dsp_state_save(unsigned char **out, void *in, size_t size) { - memcpy(*out, in, size); - *out += size; -} - -static void dsp_state_load(unsigned char **in, void *out, size_t size) { - memcpy(out, *in, size); - *in += size; -} - -void DSP::serialize(serializer &s) { - Processor::serialize(s); - s.array(samplebuffer); - - unsigned char state[SPC_DSP::state_size]; - unsigned char *p = state; - memset(&state, 0, SPC_DSP::state_size); - if(s.mode() == serializer::Save) { - spc_dsp.copy_state(&p, dsp_state_save); - s.array(state); - } else if(s.mode() == serializer::Load) { - s.array(state); - spc_dsp.copy_state(&p, dsp_state_load); - } else { - s.array(state); - } -} - -#endif diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/serialization.cpp b/libsnes/bsnes/snes/alt/ppu-compatibility/serialization.cpp deleted file mode 100644 index 28df9b1e95..0000000000 --- a/libsnes/bsnes/snes/alt/ppu-compatibility/serialization.cpp +++ /dev/null @@ -1,210 +0,0 @@ -#ifdef PPU_CPP - -void PPUcounter::serialize(serializer &s) { - s.integer(status.interlace); - s.integer(status.field); - s.integer(status.vcounter); - s.integer(status.hcounter); - - s.array(history.field); - s.array(history.vcounter); - s.array(history.hcounter); - s.integer(history.index); -} - -void PPU::serialize(serializer &s) { - Processor::serialize(s); - PPUcounter::serialize(s); - - s.array(vram,128 * 1024); - s.array(oam,544); - s.array(cgram,512); - - s.integer(ppu1_version); - s.integer(ppu2_version); - - s.integer(region); - s.integer(line); - - s.integer(display.interlace); - s.integer(display.overscan); - - s.integer(cache.oam_basesize); - s.integer(cache.oam_nameselect); - s.integer(cache.oam_tdaddr); - - s.integer(regs.ppu1_mdr); - s.integer(regs.ppu2_mdr); - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_y[n]); - - s.integer(regs.ioamaddr); - s.integer(regs.icgramaddr); - - s.integer(regs.display_disabled); - s.integer(regs.display_brightness); - - s.integer(regs.oam_basesize); - s.integer(regs.oam_nameselect); - s.integer(regs.oam_tdaddr); - - s.integer(regs.oam_baseaddr); - s.integer(regs.oam_addr); - s.integer(regs.oam_priority); - s.integer(regs.oam_firstsprite); - - s.integer(regs.oam_latchdata); - - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_tilesize[n]); - s.integer(regs.bg3_priority); - s.integer(regs.bg_mode); - - s.integer(regs.mosaic_size); - for(unsigned n = 0; n < 4; n++) s.integer(regs.mosaic_enabled[n]); - s.integer(regs.mosaic_countdown); - - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_scaddr[n]); - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_scsize[n]); - - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_tdaddr[n]); - - s.integer(regs.bg_ofslatch); - s.integer(regs.m7_hofs); - s.integer(regs.m7_vofs); - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_hofs[n]); - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_vofs[n]); - - s.integer(regs.vram_incmode); - s.integer(regs.vram_mapping); - s.integer(regs.vram_incsize); - - s.integer(regs.vram_addr); - - s.integer(regs.mode7_repeat); - s.integer(regs.mode7_vflip); - s.integer(regs.mode7_hflip); - - s.integer(regs.m7_latch); - s.integer(regs.m7a); - s.integer(regs.m7b); - s.integer(regs.m7c); - s.integer(regs.m7d); - s.integer(regs.m7x); - s.integer(regs.m7y); - - s.integer(regs.cgram_addr); - - s.integer(regs.cgram_latchdata); - - for(unsigned n = 0; n < 6; n++) s.integer(regs.window1_enabled[n]); - for(unsigned n = 0; n < 6; n++) s.integer(regs.window1_invert [n]); - for(unsigned n = 0; n < 6; n++) s.integer(regs.window2_enabled[n]); - for(unsigned n = 0; n < 6; n++) s.integer(regs.window2_invert [n]); - - s.integer(regs.window1_left); - s.integer(regs.window1_right); - s.integer(regs.window2_left); - s.integer(regs.window2_right); - - for(unsigned n = 0; n < 6; n++) s.integer(regs.window_mask[n]); - for(unsigned n = 0; n < 5; n++) s.integer(regs.bg_enabled[n]); - for(unsigned n = 0; n < 5; n++) s.integer(regs.bgsub_enabled[n]); - for(unsigned n = 0; n < 5; n++) s.integer(regs.window_enabled[n]); - for(unsigned n = 0; n < 5; n++) s.integer(regs.sub_window_enabled[n]); - - s.integer(regs.color_mask); - s.integer(regs.colorsub_mask); - s.integer(regs.addsub_mode); - s.integer(regs.direct_color); - - s.integer(regs.color_mode); - s.integer(regs.color_halve); - for(unsigned n = 0; n < 6; n++) s.integer(regs.color_enabled[n]); - - s.integer(regs.color_r); - s.integer(regs.color_g); - s.integer(regs.color_b); - s.integer(regs.color_rgb); - - s.integer(regs.mode7_extbg); - s.integer(regs.pseudo_hires); - s.integer(regs.overscan); - s.integer(regs.scanlines); - s.integer(regs.oam_interlace); - s.integer(regs.interlace); - - s.integer(regs.hcounter); - s.integer(regs.vcounter); - s.integer(regs.latch_hcounter); - s.integer(regs.latch_vcounter); - s.integer(regs.counters_latched); - - s.integer(regs.vram_readbuffer); - - s.integer(regs.time_over); - s.integer(regs.range_over); - s.integer(regs.oam_itemcount); - s.integer(regs.oam_tilecount); - - for(unsigned n = 0; n < 256; n++) { - s.integer(pixel_cache[n].src_main); - s.integer(pixel_cache[n].src_sub); - s.integer(pixel_cache[n].bg_main); - s.integer(pixel_cache[n].bg_sub); - s.integer(pixel_cache[n].ce_main); - s.integer(pixel_cache[n].ce_sub); - s.integer(pixel_cache[n].pri_main); - s.integer(pixel_cache[n].pri_sub); - } - - //zero TODO - only on load - //better to just take a small speed hit than store all of bg_tiledata[3][] ... - flush_tiledata_cache(); - - for(unsigned n = 0; n < 6; n++) { - s.array(window[n].main, 256); - s.array(window[n].sub, 256); - } - - for(unsigned n = 0; n < 4; n++) { - s.integer(bg_info[n].tw); - s.integer(bg_info[n].th); - s.integer(bg_info[n].mx); - s.integer(bg_info[n].my); - s.integer(bg_info[n].scx); - s.integer(bg_info[n].scy); - } - - for(unsigned n = 0; n < 128; n++) { - s.integer(sprite_list[n].width); - s.integer(sprite_list[n].height); - s.integer(sprite_list[n].x); - s.integer(sprite_list[n].y); - s.integer(sprite_list[n].character); - s.integer(sprite_list[n].use_nameselect); - s.integer(sprite_list[n].vflip); - s.integer(sprite_list[n].hflip); - s.integer(sprite_list[n].palette); - s.integer(sprite_list[n].priority); - s.integer(sprite_list[n].size); - } - s.integer(sprite_list_valid); - s.integer(active_sprite); - - s.array(oam_itemlist, 32); - - for(unsigned n = 0; n < 34; n++) { - s.integer(oam_tilelist[n].x); - s.integer(oam_tilelist[n].y); - s.integer(oam_tilelist[n].pri); - s.integer(oam_tilelist[n].pal); - s.integer(oam_tilelist[n].tile); - s.integer(oam_tilelist[n].hflip); - } - - s.array(oam_line_pal, 256); - s.array(oam_line_pri, 256); - - s.integer(uindex); -} - -#endif diff --git a/libsnes/bsnes/snes/alt/ppu-performance/serialization.cpp b/libsnes/bsnes/snes/alt/ppu-performance/serialization.cpp deleted file mode 100644 index e928df9d38..0000000000 --- a/libsnes/bsnes/snes/alt/ppu-performance/serialization.cpp +++ /dev/null @@ -1,249 +0,0 @@ -#ifdef PPU_CPP - -void PPUcounter::serialize(serializer &s) { - s.integer(status.interlace); - s.integer(status.field); - s.integer(status.vcounter); - s.integer(status.hcounter); - - s.array(history.field); - s.array(history.vcounter); - s.array(history.hcounter); - s.integer(history.index); -} - -void PPU::serialize(serializer &s) { - Processor::serialize(s); - PPUcounter::serialize(s); - - s.array(vram, 64 * 1024); - s.array(oam, 544); - s.array(cgram, 512); - - cache.serialize(s); - bg1.serialize(s); - bg2.serialize(s); - bg3.serialize(s); - bg4.serialize(s); - sprite.serialize(s); - screen.serialize(s); - - s.integer(display.interlace); - s.integer(display.overscan); - s.integer(display.width); - s.integer(display.height); - - s.integer(regs.ppu1_mdr); - s.integer(regs.ppu2_mdr); - - s.integer(regs.vram_readbuffer); - s.integer(regs.oam_latchdata); - s.integer(regs.cgram_latchdata); - s.integer(regs.bgofs_latchdata); - s.integer(regs.mode7_latchdata); - - s.integer(regs.counters_latched); - s.integer(regs.latch_hcounter); - s.integer(regs.latch_vcounter); - - s.integer(regs.display_disable); - s.integer(regs.display_brightness); - - s.integer(regs.oam_baseaddr); - s.integer(regs.oam_addr); - s.integer(regs.oam_priority); - - s.integer(regs.bg3_priority); - s.integer(regs.bgmode); - - s.integer(regs.mode7_hoffset); - - s.integer(regs.mode7_voffset); - - s.integer(regs.vram_incmode); - s.integer(regs.vram_mapping); - s.integer(regs.vram_incsize); - - s.integer(regs.vram_addr); - - s.integer(regs.mode7_repeat); - s.integer(regs.mode7_vflip); - s.integer(regs.mode7_hflip); - - s.integer(regs.m7a); - s.integer(regs.m7b); - s.integer(regs.m7c); - s.integer(regs.m7d); - s.integer(regs.m7x); - s.integer(regs.m7y); - - s.integer(regs.cgram_addr); - - s.integer(regs.window_one_left); - s.integer(regs.window_one_right); - s.integer(regs.window_two_left); - s.integer(regs.window_two_right); - - s.integer(regs.mode7_extbg); - s.integer(regs.pseudo_hires); - s.integer(regs.overscan); - s.integer(regs.interlace); - - s.integer(regs.hcounter); - - s.integer(regs.vcounter); -} - -void PPU::Cache::serialize(serializer &s) { - //rather than save ~512KB worth of cached tiledata, invalidate it all - for(unsigned i = 0; i < 4096; i++) tilevalid[0][i] = false; - for(unsigned i = 0; i < 2048; i++) tilevalid[1][i] = false; - for(unsigned i = 0; i < 1024; i++) tilevalid[2][i] = false; -} - -void PPU::Background::serialize(serializer &s) { - s.integer(regs.mode); - s.integer(regs.priority0); - s.integer(regs.priority1); - - s.integer(regs.tile_size); - s.integer(regs.mosaic); - - s.integer(regs.screen_addr); - s.integer(regs.screen_size); - s.integer(regs.tiledata_addr); - - s.integer(regs.hoffset); - s.integer(regs.voffset); - - s.integer(regs.main_enable); - s.integer(regs.sub_enable); - - s.integer(hires); - s.integer(width); - - s.integer(tile_width); - s.integer(tile_height); - - s.integer(mask_x); - s.integer(mask_y); - - s.integer(scx); - s.integer(scy); - - s.integer(hscroll); - s.integer(vscroll); - - s.integer(mosaic_vcounter); - s.integer(mosaic_voffset); - - window.serialize(s); -} - -void PPU::Sprite::serialize(serializer &s) { - s.integer(regs.priority0); - s.integer(regs.priority1); - s.integer(regs.priority2); - s.integer(regs.priority3); - - s.integer(regs.base_size); - s.integer(regs.nameselect); - s.integer(regs.tiledata_addr); - s.integer(regs.first_sprite); - - s.integer(regs.main_enable); - s.integer(regs.sub_enable); - - s.integer(regs.interlace); - - s.integer(regs.time_over); - s.integer(regs.range_over); - - for(unsigned i = 0; i < 128; i++) { - s.integer(list[i].width); - s.integer(list[i].height); - s.integer(list[i].x); - s.integer(list[i].y); - s.integer(list[i].character); - s.integer(list[i].use_nameselect); - s.integer(list[i].vflip); - s.integer(list[i].hflip); - s.integer(list[i].palette); - s.integer(list[i].priority); - s.integer(list[i].size); - } - s.integer(list_valid); - - s.array(itemlist); - for(unsigned i = 0; i < 34; i++) { - s.integer(tilelist[i].x); - s.integer(tilelist[i].y); - s.integer(tilelist[i].priority); - s.integer(tilelist[i].palette); - s.integer(tilelist[i].tile); - s.integer(tilelist[i].hflip); - } - - s.array(output.palette); - s.array(output.priority); - - window.serialize(s); -} - -void PPU::Screen::serialize(serializer &s) { - s.integer(regs.addsub_mode); - s.integer(regs.direct_color); - - s.integer(regs.color_mode); - s.integer(regs.color_halve); - s.array(regs.color_enable); - - s.integer(regs.color_b); - s.integer(regs.color_g); - s.integer(regs.color_r); - s.integer(regs.color); - - for(unsigned i = 0; i < 256; i++) { - s.integer(output.main[i].color); - s.integer(output.main[i].priority); - s.integer(output.main[i].source); - - s.integer(output.sub[i].color); - s.integer(output.sub[i].priority); - s.integer(output.sub[i].source); - } - - window.serialize(s); -} - -void PPU::LayerWindow::serialize(serializer &s) { - s.integer(one_enable); - s.integer(one_invert); - s.integer(two_enable); - s.integer(two_invert); - - s.integer(mask); - - s.integer(main_enable); - s.integer(sub_enable); - - s.array(main); - s.array(sub); -} - -void PPU::ColorWindow::serialize(serializer &s) { - s.integer(one_enable); - s.integer(one_invert); - s.integer(two_enable); - s.integer(two_invert); - - s.integer(mask); - - s.integer(main_mask); - s.integer(sub_mask); - - s.array(main); - s.array(sub); -} - -#endif diff --git a/libsnes/bsnes/snes/cartridge/serialization.cpp b/libsnes/bsnes/snes/cartridge/serialization.cpp deleted file mode 100644 index f7e0abfa7f..0000000000 --- a/libsnes/bsnes/snes/cartridge/serialization.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#ifdef CARTRIDGE_CPP - -void Cartridge::serialize(serializer &s) { - for(auto &ram : nvram) { - if(ram.size) s.array(ram.data, ram.size); - } -} - -#endif diff --git a/libsnes/bsnes/snes/cheat/cheat.cpp b/libsnes/bsnes/snes/cheat/cheat.cpp deleted file mode 100644 index 46c42d1c9b..0000000000 --- a/libsnes/bsnes/snes/cheat/cheat.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include - -#define CHEAT_CPP -namespace SNES { - -Cheat cheat; - -bool Cheat::enabled() const { - return system_enabled; -} - -void Cheat::enable(bool state) { - system_enabled = state; - cheat_enabled = system_enabled && code_enabled; -} - -void Cheat::synchronize() { - memset(override, 0x00, 16 * 1024 * 1024); - code_enabled = size() > 0; - - for(unsigned i = 0; i < size(); i++) { - const CheatCode &code = operator[](i); - - unsigned addr = mirror(code.addr); - override[addr] = true; - if((addr & 0xffe000) == 0x7e0000) { - //mirror $7e:0000-1fff to $00-3f|80-bf:0000-1fff - unsigned mirroraddr; - for(unsigned x = 0; x <= 0x3f; x++) { - mirroraddr = ((0x00 + x) << 16) + (addr & 0x1fff); - override[mirroraddr] = true; - - mirroraddr = ((0x80 + x) << 16) + (addr & 0x1fff); - override[mirroraddr] = true; - } - } - } - - cheat_enabled = system_enabled && code_enabled; -} - -uint8 Cheat::read(unsigned addr) const { - addr = mirror(addr); - - for(unsigned i = 0; i < size(); i++) { - const CheatCode &code = operator[](i); - if(addr == mirror(code.addr)) { - return code.data; - } - } - - return 0x00; -} - -void Cheat::init() { - memset(override, 0x00, 16 * 1024 * 1024); -} - -Cheat::Cheat() { - override = new uint8[16 * 1024 * 1024]; - system_enabled = true; -} - -Cheat::~Cheat() { - delete[] override; -} - -bool Cheat::decode(const string &code, unsigned &addr, unsigned &data) { - string t = code; - t.lower(); - - #define ischr(n) ((n >= '0' && n <= '9') || (n >= 'a' && n <= 'f')) - - if(t.wildcard("??????:??")) { - //Direct - t = { substr(t, 0, 6), substr(t, 7, 2) }; - for(unsigned n = 0; n < 8; n++) if(!ischr(t[n])) return false; //validate input - unsigned r = hex(t); - - addr = r >> 8; - data = r & 0xff; - return true; - } - - if(t.wildcard("????" "-" "????")) { - //Game Genie - t = { substr(t, 0, 4), substr(t, 5, 4) }; - for(unsigned n = 0; n < 8; n++) if(!ischr(t[n])) return false; //validate input - t.transform("df4709156bc8a23e", "0123456789abcdef"); - unsigned r = hex(t); - static unsigned bits[] = { 13, 12, 11, 10, 5, 4, 3, 2, 23, 22, 21, 20, 1, 0, 15, 14, 19, 18, 17, 16, 9, 8, 7, 6 }; - - addr = 0; - for(unsigned n = 0; n < 24; n++) addr |= r & (1 << bits[n]) ? 0x800000 >> n : 0; - data = r >> 24; - return true; - } else { - return false; - } - - #undef ischr -} - -unsigned Cheat::mirror(unsigned addr) const { - //$00-3f|80-bf:0000-1fff -> $7e:0000-1fff - if((addr & 0x40e000) == 0x000000) return (0x7e0000 + (addr & 0x1fff)); - return addr; -} - -} diff --git a/libsnes/bsnes/snes/cheat/cheat.hpp b/libsnes/bsnes/snes/cheat/cheat.hpp deleted file mode 100644 index 306b99b158..0000000000 --- a/libsnes/bsnes/snes/cheat/cheat.hpp +++ /dev/null @@ -1,27 +0,0 @@ -struct CheatCode { - unsigned addr; - unsigned data; -}; - -struct Cheat : public linear_vector { - uint8 *override; - - bool enabled() const; - void enable(bool); - void synchronize(); - uint8 read(unsigned) const; - void init(); - - Cheat(); - ~Cheat(); - - static bool decode(const string&, unsigned&, unsigned&); - -private: - bool system_enabled; - bool code_enabled; - bool cheat_enabled; - unsigned mirror(unsigned) const; -}; - -extern Cheat cheat; diff --git a/libsnes/bsnes/snes/chip/armdsp/serialization.cpp b/libsnes/bsnes/snes/chip/armdsp/serialization.cpp deleted file mode 100644 index 481e4f798f..0000000000 --- a/libsnes/bsnes/snes/chip/armdsp/serialization.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifdef ARMDSP_CPP - -void ArmDSP::serialize(serializer &s) { - Processor::serialize(s); - - s.array(programRAM, 16 * 1024); - - s.integer(bridge.cputoarm.ready); - s.integer(bridge.cputoarm.data); - s.integer(bridge.armtocpu.ready); - s.integer(bridge.armtocpu.data); - s.integer(bridge.timer); - s.integer(bridge.timerlatch); - s.integer(bridge.reset); - s.integer(bridge.ready); - s.integer(bridge.busy); - - s.integer(cpsr.n); - s.integer(cpsr.z); - s.integer(cpsr.c); - s.integer(cpsr.v); - s.integer(cpsr.i); - s.integer(cpsr.f); - s.integer(cpsr.m); - - s.integer(spsr.n); - s.integer(spsr.z); - s.integer(spsr.c); - s.integer(spsr.v); - s.integer(spsr.i); - s.integer(spsr.f); - s.integer(spsr.m); - - s.integer(r[ 0].data); - s.integer(r[ 1].data); - s.integer(r[ 2].data); - s.integer(r[ 3].data); - s.integer(r[ 4].data); - s.integer(r[ 5].data); - s.integer(r[ 6].data); - s.integer(r[ 7].data); - s.integer(r[ 8].data); - s.integer(r[ 9].data); - s.integer(r[10].data); - s.integer(r[11].data); - s.integer(r[12].data); - s.integer(r[13].data); - s.integer(r[14].data); - s.integer(r[15].data); - - s.integer(shiftercarry); - s.integer(instruction); - s.integer(exception); - - s.integer(pipeline.reload); - s.integer(pipeline.instruction.opcode); - s.integer(pipeline.instruction.address); - s.integer(pipeline.prefetch.opcode); - s.integer(pipeline.prefetch.address); - s.integer(pipeline.mdr.opcode); - s.integer(pipeline.mdr.address); -} - -#endif diff --git a/libsnes/bsnes/snes/chip/hitachidsp/serialization.cpp b/libsnes/bsnes/snes/chip/hitachidsp/serialization.cpp deleted file mode 100644 index dc6d2d395d..0000000000 --- a/libsnes/bsnes/snes/chip/hitachidsp/serialization.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifdef HITACHIDSP_CPP - -void HitachiDSP::serialize(serializer &s) { - Processor::serialize(s); - - s.array(dataRAM); - for(auto &n : stack) s.integer(n); - s.integer(opcode); - s.integer((unsigned&)state); - - s.integer(regs.pc); - s.integer(regs.p); - s.integer(regs.n); - s.integer(regs.z); - s.integer(regs.c); - - s.integer(regs.a); - s.integer(regs.acch); - s.integer(regs.accl); - s.integer(regs.busdata); - s.integer(regs.romdata); - s.integer(regs.ramdata); - s.integer(regs.busaddr); - s.integer(regs.ramaddr); - for(auto &n : regs.gpr) s.integer(n); - - s.integer(regs.dma_source); - s.integer(regs.dma_length); - s.integer(regs.dma_target); - s.integer(regs.r1f48); - s.integer(regs.program_offset); - s.integer(regs.r1f4c); - s.integer(regs.page_number); - s.integer(regs.program_counter); - s.integer(regs.r1f50); - s.integer(regs.r1f51); - s.integer(regs.r1f52); - s.array(regs.vector); -} - -#endif diff --git a/libsnes/bsnes/snes/chip/icd2/serialization.cpp b/libsnes/bsnes/snes/chip/icd2/serialization.cpp deleted file mode 100644 index 5c31448ed8..0000000000 --- a/libsnes/bsnes/snes/chip/icd2/serialization.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifdef ICD2_CPP - -void ICD2::serialize(serializer &s) { - Processor::serialize(s); - GameBoy::system.serialize_all(s); - - for(unsigned n = 0; n < 64; n++) s.array(packet[n].data); - s.integer(packetsize); - - s.integer(joyp_id); - s.integer(joyp15lock); - s.integer(joyp14lock); - s.integer(pulselock); - s.integer(strobelock); - s.integer(packetlock); - s.array(joyp_packet.data); - s.integer(packetoffset); - s.integer(bitdata); - s.integer(bitoffset); - - s.integer(r6000_ly); - s.integer(r6000_row); - s.integer(r6001); - s.integer(r6003); - s.integer(r6004); - s.integer(r6005); - s.integer(r6006); - s.integer(r6007); - s.array(r7000); - s.integer(r7800); - s.integer(mlt_req); - - s.array(lcd.buffer); - s.array(lcd.output); - s.integer(lcd.row); -} - -#endif diff --git a/libsnes/bsnes/snes/chip/msu1/serialization.cpp b/libsnes/bsnes/snes/chip/msu1/serialization.cpp deleted file mode 100644 index ffe4485adf..0000000000 --- a/libsnes/bsnes/snes/chip/msu1/serialization.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifdef MSU1_CPP - -void MSU1::serialize(serializer &s) { - Processor::serialize(s); - - s.integer(mmio.data_offset); - s.integer(mmio.audio_offset); - s.integer(mmio.audio_loop_offset); - - s.integer(mmio.audio_track); - s.integer(mmio.audio_volume); - - s.integer(mmio.data_busy); - s.integer(mmio.audio_busy); - s.integer(mmio.audio_repeat); - s.integer(mmio.audio_play); - - if(datafile.open()) datafile.close(); - if(datafile.open(interface()->path(Cartridge::Slot::Base, "msu1.rom"), file::mode::read)) { - datafile.seek(mmio.data_offset); - } - - if(audiofile.open()) audiofile.close(); - if(audiofile.open(interface()->path(Cartridge::Slot::Base, { "track-", (unsigned)mmio.audio_track, ".pcm" }), file::mode::read)) { - audiofile.seek(mmio.audio_offset); - } -} - -#endif diff --git a/libsnes/bsnes/snes/chip/necdsp/serialization.cpp b/libsnes/bsnes/snes/chip/necdsp/serialization.cpp deleted file mode 100644 index a06510f833..0000000000 --- a/libsnes/bsnes/snes/chip/necdsp/serialization.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#ifdef NECDSP_CPP - -void NECDSP::serialize(serializer &s) { - Processor::serialize(s); - - s.array(dataRAM); - - s.array(regs.stack); - s.integer(regs.pc); - s.integer(regs.rp); - s.integer(regs.dp); - s.integer(regs.sp); - - s.integer(regs.k); - s.integer(regs.l); - s.integer(regs.m); - s.integer(regs.n); - s.integer(regs.a); - s.integer(regs.b); - - s.integer(regs.flaga.s1); - s.integer(regs.flaga.s0); - s.integer(regs.flaga.c); - s.integer(regs.flaga.z); - s.integer(regs.flaga.ov1); - s.integer(regs.flaga.ov0); - - s.integer(regs.flagb.s1); - s.integer(regs.flagb.s0); - s.integer(regs.flagb.c); - s.integer(regs.flagb.z); - s.integer(regs.flagb.ov1); - s.integer(regs.flagb.ov0); - - s.integer(regs.tr); - s.integer(regs.trb); - - s.integer(regs.sr.rqm); - s.integer(regs.sr.usf1); - s.integer(regs.sr.usf0); - s.integer(regs.sr.drs); - s.integer(regs.sr.dma); - s.integer(regs.sr.drc); - s.integer(regs.sr.soc); - s.integer(regs.sr.sic); - s.integer(regs.sr.ei); - s.integer(regs.sr.p1); - s.integer(regs.sr.p0); - - s.integer(regs.dr); - s.integer(regs.si); - s.integer(regs.so); -} - -#endif diff --git a/libsnes/bsnes/snes/chip/obc1/serialization.cpp b/libsnes/bsnes/snes/chip/obc1/serialization.cpp deleted file mode 100644 index 3d61aafc38..0000000000 --- a/libsnes/bsnes/snes/chip/obc1/serialization.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#ifdef OBC1_CPP - -void OBC1::serialize(serializer &s) { - s.integer(status.address); - s.integer(status.baseptr); - s.integer(status.shift); -} - -#endif diff --git a/libsnes/bsnes/snes/chip/sa1/serialization.cpp b/libsnes/bsnes/snes/chip/sa1/serialization.cpp deleted file mode 100644 index 3d755883b8..0000000000 --- a/libsnes/bsnes/snes/chip/sa1/serialization.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#ifdef SA1_CPP - -void SA1::serialize(serializer &s) { - Processor::serialize(s); - CPUcore::core_serialize(s); - - //sa1.hpp - s.integer(status.tick_counter); - - s.integer(status.interrupt_pending); - - s.integer(status.scanlines); - s.integer(status.vcounter); - s.integer(status.hcounter); - - //bus/bus.hpp - s.array(iram.data(), iram.size()); - - s.integer(cpubwram.dma); - - //dma/dma.hpp - s.integer(dma.line); - - //mmio/mmio.hpp - s.integer(mmio.sa1_irq); - s.integer(mmio.sa1_rdyb); - s.integer(mmio.sa1_resb); - s.integer(mmio.sa1_nmi); - s.integer(mmio.smeg); - - s.integer(mmio.cpu_irqen); - s.integer(mmio.chdma_irqen); - - s.integer(mmio.cpu_irqcl); - s.integer(mmio.chdma_irqcl); - - s.integer(mmio.crv); - - s.integer(mmio.cnv); - - s.integer(mmio.civ); - - s.integer(mmio.cpu_irq); - s.integer(mmio.cpu_ivsw); - s.integer(mmio.cpu_nvsw); - s.integer(mmio.cmeg); - - s.integer(mmio.sa1_irqen); - s.integer(mmio.timer_irqen); - s.integer(mmio.dma_irqen); - s.integer(mmio.sa1_nmien); - - s.integer(mmio.sa1_irqcl); - s.integer(mmio.timer_irqcl); - s.integer(mmio.dma_irqcl); - s.integer(mmio.sa1_nmicl); - - s.integer(mmio.snv); - - s.integer(mmio.siv); - - s.integer(mmio.hvselb); - s.integer(mmio.ven); - s.integer(mmio.hen); - - s.integer(mmio.hcnt); - - s.integer(mmio.vcnt); - - s.integer(mmio.cbmode); - s.integer(mmio.cb); - - s.integer(mmio.dbmode); - s.integer(mmio.db); - - s.integer(mmio.ebmode); - s.integer(mmio.eb); - - s.integer(mmio.fbmode); - s.integer(mmio.fb); - - s.integer(mmio.sbm); - - s.integer(mmio.sw46); - s.integer(mmio.cbm); - - s.integer(mmio.swen); - - s.integer(mmio.cwen); - - s.integer(mmio.bwp); - - s.integer(mmio.siwp); - - s.integer(mmio.ciwp); - - s.integer(mmio.dmaen); - s.integer(mmio.dprio); - s.integer(mmio.cden); - s.integer(mmio.cdsel); - s.integer(mmio.dd); - s.integer(mmio.sd); - - s.integer(mmio.chdend); - s.integer(mmio.dmasize); - s.integer(mmio.dmacb); - - s.integer(mmio.dsa); - - s.integer(mmio.dda); - - s.integer(mmio.dtc); - - s.integer(mmio.bbf); - - s.array(mmio.brf); - - s.integer(mmio.acm); - s.integer(mmio.md); - - s.integer(mmio.ma); - - s.integer(mmio.mb); - - s.integer(mmio.hl); - s.integer(mmio.vb); - - s.integer(mmio.va); - s.integer(mmio.vbit); - - s.integer(mmio.cpu_irqfl); - s.integer(mmio.chdma_irqfl); - - s.integer(mmio.sa1_irqfl); - s.integer(mmio.timer_irqfl); - s.integer(mmio.dma_irqfl); - s.integer(mmio.sa1_nmifl); - - s.integer(mmio.hcr); - - s.integer(mmio.vcr); - - s.integer(mmio.mr); - - s.integer(mmio.overflow); -} - -#endif diff --git a/libsnes/bsnes/snes/chip/sdd1/serialization.cpp b/libsnes/bsnes/snes/chip/sdd1/serialization.cpp deleted file mode 100644 index 1741e1a4f6..0000000000 --- a/libsnes/bsnes/snes/chip/sdd1/serialization.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef SDD1_CPP - -void SDD1::serialize(serializer &s) { - s.integer(sdd1_enable); - s.integer(xfer_enable); - s.integer(dma_ready); - s.array(mmc); - - for(unsigned n = 0; n < 8; n++) { - s.integer(dma[n].addr); - s.integer(dma[n].size); - } -} - -#endif diff --git a/libsnes/bsnes/snes/chip/spc7110/serialization.cpp b/libsnes/bsnes/snes/chip/spc7110/serialization.cpp deleted file mode 100644 index 5868206122..0000000000 --- a/libsnes/bsnes/snes/chip/spc7110/serialization.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#ifdef SPC7110_CPP - -void SPC7110::Decomp::serialize(serializer &s) { - s.integer(decomp_mode); - s.integer(decomp_offset); - - s.array(decomp_buffer, decomp_buffer_size); - s.integer(decomp_buffer_rdoffset); - s.integer(decomp_buffer_wroffset); - s.integer(decomp_buffer_length); - - for(unsigned n = 0; n < 32; n++) { - s.integer(context[n].index); - s.integer(context[n].invert); - } -} - -void SPC7110::serialize(serializer &s) { - s.integer(r4801); - s.integer(r4802); - s.integer(r4803); - s.integer(r4804); - s.integer(r4805); - s.integer(r4806); - s.integer(r4807); - s.integer(r4808); - s.integer(r4809); - s.integer(r480a); - s.integer(r480b); - s.integer(r480c); - decomp.serialize(s); - - s.integer(r4811); - s.integer(r4812); - s.integer(r4813); - s.integer(r4814); - s.integer(r4815); - s.integer(r4816); - s.integer(r4817); - s.integer(r4818); - s.integer(r481x); - s.integer(r4814_latch); - s.integer(r4815_latch); - - s.integer(r4820); - s.integer(r4821); - s.integer(r4822); - s.integer(r4823); - s.integer(r4824); - s.integer(r4825); - s.integer(r4826); - s.integer(r4827); - s.integer(r4828); - s.integer(r4829); - s.integer(r482a); - s.integer(r482b); - s.integer(r482c); - s.integer(r482d); - s.integer(r482e); - s.integer(r482f); - - s.integer(r4830); - s.integer(r4831); - s.integer(r4832); - s.integer(r4833); - s.integer(r4834); - - s.integer(dx_offset); - s.integer(ex_offset); - s.integer(fx_offset); - - s.integer(r4840); - s.integer(r4841); - s.integer(r4842); - - s.array(rtc,20); - s.integer(rtc_state); - s.integer(rtc_mode); - s.integer(rtc_index); -} - -#endif diff --git a/libsnes/bsnes/snes/chip/srtc/serialization.cpp b/libsnes/bsnes/snes/chip/srtc/serialization.cpp deleted file mode 100644 index 9850635065..0000000000 --- a/libsnes/bsnes/snes/chip/srtc/serialization.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#ifdef SRTC_CPP - -void SRTC::serialize(serializer &s) { - s.array(rtc,20); - s.integer(rtc_mode); - s.integer(rtc_index); -} - -#endif diff --git a/libsnes/bsnes/snes/chip/sufamiturbo/serialization.cpp b/libsnes/bsnes/snes/chip/sufamiturbo/serialization.cpp deleted file mode 100644 index 526c3496dc..0000000000 --- a/libsnes/bsnes/snes/chip/sufamiturbo/serialization.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifdef SUFAMITURBO_CPP - -void SufamiTurbo::serialize(serializer &s) { - if(slotA.ram.data()) s.array(slotA.ram.data(), slotA.ram.size()); - if(slotB.ram.data()) s.array(slotB.ram.data(), slotB.ram.size()); -} - -#endif diff --git a/libsnes/bsnes/snes/chip/superfx/serialization.cpp b/libsnes/bsnes/snes/chip/superfx/serialization.cpp deleted file mode 100644 index 67e5385bd5..0000000000 --- a/libsnes/bsnes/snes/chip/superfx/serialization.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#ifdef SUPERFX_CPP - -void SuperFX::serialize(serializer &s) { - Processor::serialize(s); - - //superfx.hpp - s.integer(clockmode); - s.integer(instruction_counter); - - //core/registers.hpp - s.integer(regs.pipeline); - s.integer(regs.ramaddr); - - s.integer(regs.r[ 0].data); - s.integer(regs.r[ 1].data); - s.integer(regs.r[ 2].data); - s.integer(regs.r[ 3].data); - s.integer(regs.r[ 4].data); - s.integer(regs.r[ 5].data); - s.integer(regs.r[ 6].data); - s.integer(regs.r[ 7].data); - s.integer(regs.r[ 8].data); - s.integer(regs.r[ 9].data); - s.integer(regs.r[10].data); - s.integer(regs.r[11].data); - s.integer(regs.r[12].data); - s.integer(regs.r[13].data); - s.integer(regs.r[14].data); - s.integer(regs.r[15].data); - - s.integer(regs.sfr.irq); - s.integer(regs.sfr.b); - s.integer(regs.sfr.ih); - s.integer(regs.sfr.il); - s.integer(regs.sfr.alt2); - s.integer(regs.sfr.alt1); - s.integer(regs.sfr.r); - s.integer(regs.sfr.g); - s.integer(regs.sfr.ov); - s.integer(regs.sfr.s); - s.integer(regs.sfr.cy); - s.integer(regs.sfr.z); - - s.integer(regs.pbr); - s.integer(regs.rombr); - s.integer(regs.rambr); - s.integer(regs.cbr); - s.integer(regs.scbr); - - s.integer(regs.scmr.ht); - s.integer(regs.scmr.ron); - s.integer(regs.scmr.ran); - s.integer(regs.scmr.md); - - s.integer(regs.colr); - - s.integer(regs.por.obj); - s.integer(regs.por.freezehigh); - s.integer(regs.por.highnibble); - s.integer(regs.por.dither); - s.integer(regs.por.transparent); - - s.integer(regs.bramr); - s.integer(regs.vcr); - - s.integer(regs.cfgr.irq); - s.integer(regs.cfgr.ms0); - - s.integer(regs.clsr); - - s.integer(regs.romcl); - s.integer(regs.romdr); - - s.integer(regs.ramcl); - s.integer(regs.ramar); - s.integer(regs.ramdr); - - s.integer(regs.sreg); - s.integer(regs.dreg); - - s.array(cache.buffer); - s.array(cache.valid); - - for(unsigned i = 0; i < 2; i++) { - s.integer(pixelcache[i].offset); - s.integer(pixelcache[i].bitpend); - s.array(pixelcache[i].data); - } - - //timing/timing.hpp - s.integer(cache_access_speed); - s.integer(memory_access_speed); - s.integer(r15_modified); -} - -#endif diff --git a/libsnes/bsnes/snes/cpu/core/serialization.cpp b/libsnes/bsnes/snes/cpu/core/serialization.cpp deleted file mode 100644 index 629fb6fe71..0000000000 --- a/libsnes/bsnes/snes/cpu/core/serialization.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifdef CPUCORE_CPP - -void CPUcore::core_serialize(serializer &s) { - s.integer(regs.pc.d); - - s.integer(regs.a.w); - s.integer(regs.x.w); - s.integer(regs.y.w); - s.integer(regs.z.w); - s.integer(regs.s.w); - s.integer(regs.d.w); - - s.integer(regs.p.n); - s.integer(regs.p.v); - s.integer(regs.p.m); - s.integer(regs.p.x); - s.integer(regs.p.d); - s.integer(regs.p.i); - s.integer(regs.p.z); - s.integer(regs.p.c); - - s.integer(regs.db); - s.integer(regs.e); - s.integer(regs.irq); - s.integer(regs.wai); - s.integer(regs.mdr); - s.integer(regs.vector); - - unsigned junk = (unsigned)regs.hang; - s.integer(junk); - regs.hang = (HangType)junk; - - s.integer(aa.d); - s.integer(rd.d); - s.integer(sp); - s.integer(dp); - - update_table(); -} - -#endif diff --git a/libsnes/bsnes/snes/cpu/serialization.cpp b/libsnes/bsnes/snes/cpu/serialization.cpp deleted file mode 100644 index 2cd32d12ad..0000000000 --- a/libsnes/bsnes/snes/cpu/serialization.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#ifdef CPU_CPP - -void CPU::serialize(serializer &s) { - Processor::serialize(s); - CPUcore::core_serialize(s); - PPUcounter::serialize(s); - - s.array(wram,128 * 1024); - - s.integer(cpu_version); - - s.integer(status.interrupt_pending); - - s.integer(status.clock_count); - s.integer(status.line_clocks); - - s.integer(status.irq_lock); - - s.integer(status.dram_refresh_position); - s.integer(status.dram_refreshed); - - s.integer(status.hdma_init_position); - s.integer(status.hdma_init_triggered); - - s.integer(status.hdma_position); - s.integer(status.hdma_triggered); - - s.integer(status.nmi_valid); - s.integer(status.nmi_line); - s.integer(status.nmi_transition); - s.integer(status.nmi_pending); - s.integer(status.nmi_hold); - - s.integer(status.irq_valid); - s.integer(status.irq_line); - s.integer(status.irq_transition); - s.integer(status.irq_pending); - s.integer(status.irq_hold); - - s.integer(status.reset_pending); - - s.integer(status.dma_active); - s.integer(status.dma_counter); - s.integer(status.dma_clocks); - s.integer(status.dma_pending); - s.integer(status.hdma_pending); - s.integer(status.hdma_mode); - - s.integer(status.auto_joypad_active); - s.integer(status.auto_joypad_latch); - s.integer(status.auto_joypad_counter); - s.integer(status.auto_joypad_clock); - - s.array(status.port); - - s.integer(status.wram_addr); - - s.integer(status.joypad_strobe_latch); - s.integer(status.joypad1_bits); - s.integer(status.joypad2_bits); - - s.integer(status.nmi_enabled); - s.integer(status.hirq_enabled); - s.integer(status.virq_enabled); - s.integer(status.auto_joypad_poll); - - s.integer(status.pio); - - s.integer(status.wrmpya); - s.integer(status.wrmpyb); - - s.integer(status.wrdiva); - s.integer(status.wrdivb); - - s.integer(status.hirq_pos); - s.integer(status.virq_pos); - - s.integer(status.rom_speed); - - s.integer(status.rddiv); - s.integer(status.rdmpy); - - s.integer(status.joy1); - s.integer(status.joy2); - s.integer(status.joy3); - s.integer(status.joy4); - - s.integer(alu.mpyctr); - s.integer(alu.divctr); - s.integer(alu.shift); - - for(unsigned i = 0; i < 8; i++) { - s.integer(channel[i].dma_enabled); - s.integer(channel[i].hdma_enabled); - s.integer(channel[i].direction); - s.integer(channel[i].indirect); - s.integer(channel[i].unused); - s.integer(channel[i].reverse_transfer); - s.integer(channel[i].fixed_transfer); - s.integer(channel[i].transfer_mode); - s.integer(channel[i].dest_addr); - s.integer(channel[i].source_addr); - s.integer(channel[i].source_bank); - s.integer(channel[i].transfer_size); - s.integer(channel[i].indirect_bank); - s.integer(channel[i].hdma_addr); - s.integer(channel[i].line_counter); - s.integer(channel[i].unknown); - s.integer(channel[i].hdma_completed); - s.integer(channel[i].hdma_do_transfer); - } - - s.integer(pipe.valid); - s.integer(pipe.addr); - s.integer(pipe.data); -} - -#endif diff --git a/libsnes/bsnes/snes/dsp/serialization.cpp b/libsnes/bsnes/snes/dsp/serialization.cpp deleted file mode 100644 index 0595c11e9d..0000000000 --- a/libsnes/bsnes/snes/dsp/serialization.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#ifdef DSP_CPP - -void DSP::serialize(serializer &s) { - Processor::serialize(s); - - s.array(state.regs, 128); - state.echo_hist[0].serialize(s); - state.echo_hist[1].serialize(s); - s.integer(state.echo_hist_pos); - - s.integer(state.every_other_sample); - s.integer(state.kon); - s.integer(state.noise); - s.integer(state.counter); - s.integer(state.echo_offset); - s.integer(state.echo_length); - - s.integer(state.new_kon); - s.integer(state.endx_buf); - s.integer(state.envx_buf); - s.integer(state.outx_buf); - - s.integer(state.t_pmon); - s.integer(state.t_non); - s.integer(state.t_eon); - s.integer(state.t_dir); - s.integer(state.t_koff); - - s.integer(state.t_brr_next_addr); - s.integer(state.t_adsr0); - s.integer(state.t_brr_header); - s.integer(state.t_brr_byte); - s.integer(state.t_srcn); - s.integer(state.t_esa); - s.integer(state.t_echo_disabled); - - s.integer(state.t_dir_addr); - s.integer(state.t_pitch); - s.integer(state.t_output); - s.integer(state.t_looped); - s.integer(state.t_echo_ptr); - - s.integer(state.t_main_out[0]); - s.integer(state.t_main_out[1]); - s.integer(state.t_echo_out[0]); - s.integer(state.t_echo_out[1]); - s.integer(state.t_echo_in [0]); - s.integer(state.t_echo_in [1]); - - for(unsigned n = 0; n < 8; n++) { - voice[n].buffer.serialize(s); - s.integer(voice[n].buf_pos); - s.integer(voice[n].interp_pos); - s.integer(voice[n].brr_addr); - s.integer(voice[n].brr_offset); - s.integer(voice[n].vbit); - s.integer(voice[n].vidx); - s.integer(voice[n].kon_delay); - s.integer(voice[n].env_mode); - s.integer(voice[n].env); - s.integer(voice[n].t_envx_out); - s.integer(voice[n].hidden_env); - } -} - -#endif diff --git a/libsnes/bsnes/snes/ppu/serialization.cpp b/libsnes/bsnes/snes/ppu/serialization.cpp deleted file mode 100644 index edf90f13cc..0000000000 --- a/libsnes/bsnes/snes/ppu/serialization.cpp +++ /dev/null @@ -1,284 +0,0 @@ -#ifdef PPU_CPP - -void PPUcounter::serialize(serializer &s) { - s.integer(status.interlace); - s.integer(status.field); - s.integer(status.vcounter); - s.integer(status.hcounter); - - s.array(history.field); - s.array(history.vcounter); - s.array(history.hcounter); - s.integer(history.index); -} - -void PPU::serialize(serializer &s) { - Processor::serialize(s); - PPUcounter::serialize(s); - - s.array(vram); - s.array(oam); - s.array(cgram); - - s.integer(ppu1_version); - s.integer(ppu2_version); - - s.integer(display.interlace); - s.integer(display.overscan); - - s.integer(regs.ppu1_mdr); - s.integer(regs.ppu2_mdr); - - s.integer(regs.vram_readbuffer); - s.integer(regs.oam_latchdata); - s.integer(regs.cgram_latchdata); - s.integer(regs.bgofs_latchdata); - s.integer(regs.mode7_latchdata); - s.integer(regs.counters_latched); - s.integer(regs.latch_hcounter); - s.integer(regs.latch_vcounter); - - s.integer(regs.oam_iaddr); - s.integer(regs.cgram_iaddr); - - s.integer(regs.display_disable); - s.integer(regs.display_brightness); - - s.integer(regs.oam_baseaddr); - s.integer(regs.oam_addr); - s.integer(regs.oam_priority); - - s.integer(regs.bg3_priority); - s.integer(regs.bgmode); - - s.integer(regs.mode7_hoffset); - s.integer(regs.mode7_voffset); - - s.integer(regs.vram_incmode); - s.integer(regs.vram_mapping); - s.integer(regs.vram_incsize); - - s.integer(regs.vram_addr); - - s.integer(regs.mode7_repeat); - s.integer(regs.mode7_vflip); - s.integer(regs.mode7_hflip); - - s.integer(regs.m7a); - s.integer(regs.m7b); - s.integer(regs.m7c); - s.integer(regs.m7d); - s.integer(regs.m7x); - s.integer(regs.m7y); - - s.integer(regs.cgram_addr); - - s.integer(regs.mode7_extbg); - s.integer(regs.pseudo_hires); - s.integer(regs.overscan); - s.integer(regs.interlace); - - s.integer(regs.hcounter); - s.integer(regs.vcounter); - - bg1.serialize(s); - bg2.serialize(s); - bg3.serialize(s); - bg4.serialize(s); - sprite.serialize(s); - window.serialize(s); - screen.serialize(s); -} - -void PPU::Background::serialize(serializer &s) { - s.integer(id); - - s.integer(regs.tiledata_addr); - s.integer(regs.screen_addr); - s.integer(regs.screen_size); - s.integer(regs.mosaic); - s.integer(regs.tile_size); - - s.integer(regs.mode); - s.integer(regs.priority0); - s.integer(regs.priority1); - - s.integer(regs.main_enable); - s.integer(regs.sub_enable); - - s.integer(regs.hoffset); - s.integer(regs.voffset); - - s.integer(cache.hoffset); - s.integer(cache.voffset); - - s.integer(output.main.priority); - s.integer(output.main.palette); - s.integer(output.main.tile); - - s.integer(output.sub.priority); - s.integer(output.sub.palette); - s.integer(output.sub.tile); - - s.integer(x); - s.integer(y); - - s.integer(mosaic.priority); - s.integer(mosaic.palette); - s.integer(mosaic.tile); - - s.integer(mosaic.vcounter); - s.integer(mosaic.voffset); - s.integer(mosaic.hcounter); - s.integer(mosaic.hoffset); - - s.integer(tile_counter); - s.integer(tile); - s.integer(priority); - s.integer(palette_number); - s.integer(palette_index); - s.array(data); -} - -void PPU::Sprite::serialize(serializer &s) { - for(unsigned i = 0; i < 128; i++) { - s.integer(list[i].x); - s.integer(list[i].y); - s.integer(list[i].character); - s.integer(list[i].nameselect); - s.integer(list[i].vflip); - s.integer(list[i].hflip); - s.integer(list[i].priority); - s.integer(list[i].palette); - s.integer(list[i].size); - } - - s.integer(t.x); - s.integer(t.y); - - s.integer(t.item_count); - s.integer(t.tile_count); - - s.integer(t.active); - for(unsigned n = 0; n < 2; n++) { - s.array(t.item[n]); - for(unsigned i = 0; i < 34; i++) { - s.integer(t.tile[n][i].x); - s.integer(t.tile[n][i].priority); - s.integer(t.tile[n][i].palette); - s.integer(t.tile[n][i].hflip); - s.integer(t.tile[n][i].d0); - s.integer(t.tile[n][i].d1); - s.integer(t.tile[n][i].d2); - s.integer(t.tile[n][i].d3); - } - } - - s.integer(regs.main_enable); - s.integer(regs.sub_enable); - s.integer(regs.interlace); - - s.integer(regs.base_size); - s.integer(regs.nameselect); - s.integer(regs.tiledata_addr); - s.integer(regs.first_sprite); - - s.integer(regs.priority0); - s.integer(regs.priority1); - s.integer(regs.priority2); - s.integer(regs.priority3); - - s.integer(regs.time_over); - s.integer(regs.range_over); - - s.integer(output.main.priority); - s.integer(output.main.palette); - - s.integer(output.sub.priority); - s.integer(output.sub.palette); -} - -void PPU::Window::serialize(serializer &s) { - s.integer(regs.bg1_one_enable); - s.integer(regs.bg1_one_invert); - s.integer(regs.bg1_two_enable); - s.integer(regs.bg1_two_invert); - - s.integer(regs.bg2_one_enable); - s.integer(regs.bg2_one_invert); - s.integer(regs.bg2_two_enable); - s.integer(regs.bg2_two_invert); - - s.integer(regs.bg3_one_enable); - s.integer(regs.bg3_one_invert); - s.integer(regs.bg3_two_enable); - s.integer(regs.bg3_two_invert); - - s.integer(regs.bg4_one_enable); - s.integer(regs.bg4_one_invert); - s.integer(regs.bg4_two_enable); - s.integer(regs.bg4_two_invert); - - s.integer(regs.oam_one_enable); - s.integer(regs.oam_one_invert); - s.integer(regs.oam_two_enable); - s.integer(regs.oam_two_invert); - - s.integer(regs.col_one_enable); - s.integer(regs.col_one_invert); - s.integer(regs.col_two_enable); - s.integer(regs.col_two_invert); - - s.integer(regs.one_left); - s.integer(regs.one_right); - s.integer(regs.two_left); - s.integer(regs.two_right); - - s.integer(regs.bg1_mask); - s.integer(regs.bg2_mask); - s.integer(regs.bg3_mask); - s.integer(regs.bg4_mask); - s.integer(regs.oam_mask); - s.integer(regs.col_mask); - - s.integer(regs.bg1_main_enable); - s.integer(regs.bg1_sub_enable); - s.integer(regs.bg2_main_enable); - s.integer(regs.bg2_sub_enable); - s.integer(regs.bg3_main_enable); - s.integer(regs.bg3_sub_enable); - s.integer(regs.bg4_main_enable); - s.integer(regs.bg4_sub_enable); - s.integer(regs.oam_main_enable); - s.integer(regs.oam_sub_enable); - - s.integer(regs.col_main_mask); - s.integer(regs.col_sub_mask); - - s.integer(output.main.color_enable); - s.integer(output.sub.color_enable); - - s.integer(x); - s.integer(one); - s.integer(two); -} - -void PPU::Screen::serialize(serializer &s) { - s.integer(regs.addsub_mode); - s.integer(regs.direct_color); - - s.integer(regs.color_mode); - s.integer(regs.color_halve); - s.integer(regs.bg1_color_enable); - s.integer(regs.bg2_color_enable); - s.integer(regs.bg3_color_enable); - s.integer(regs.bg4_color_enable); - s.integer(regs.oam_color_enable); - s.integer(regs.back_color_enable); - - s.integer(regs.color_b); - s.integer(regs.color_g); - s.integer(regs.color_r); -} - -#endif diff --git a/libsnes/bsnes/snes/smp/core/serialization.cpp b/libsnes/bsnes/snes/smp/core/serialization.cpp deleted file mode 100644 index 03a8d33639..0000000000 --- a/libsnes/bsnes/snes/smp/core/serialization.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifdef SMPCORE_CPP - -void SMPcore::core_serialize(serializer &s) { - s.integer(regs.pc); - s.integer(regs.a); - s.integer(regs.x); - s.integer(regs.y); - s.integer(regs.s); - s.integer(regs.p.n); - s.integer(regs.p.v); - s.integer(regs.p.p); - s.integer(regs.p.b); - s.integer(regs.p.h); - s.integer(regs.p.i); - s.integer(regs.p.z); - s.integer(regs.p.c); - - s.integer(opcode); - s.integer(dp.w); - s.integer(sp.w); - s.integer(rd.w); - s.integer(wr.w); - s.integer(bit.w); - s.integer(ya.w); - - s.integer(uindex); -} - -#endif diff --git a/libsnes/bsnes/snes/smp/core/uop.cpp b/libsnes/bsnes/snes/smp/core/uop.cpp deleted file mode 100644 index def4ca5d67..0000000000 --- a/libsnes/bsnes/snes/smp/core/uop.cpp +++ /dev/null @@ -1,3151 +0,0 @@ -const int uoptable[256][16] = { - -// case 0x00: return op_nop(); -// void SMPcore::op_nop() { -{ - 1, // op_io(); - 2, // //!!NEXT -}, -// case 0x01: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x02: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x03: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x04: return op_read_dp<&SMPcore::op_or>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x05: return op_read_addr<&SMPcore::op_or>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x06: return op_read_ix<&SMPcore::op_or>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x07: return op_read_idpx<&SMPcore::op_or>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x08: return op_read_const<&SMPcore::op_or>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x09: return op_write_dp_dp<&SMPcore::op_or>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 29, // wr = op_or(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x0a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 1, // op_io(); - 33, // regs.p.c |= (rd & (1 << bit)) ^ 0; - 2, // //!!NEXT -}, -// case 0x0b: return op_adjust_dp<&SMPcore::op_asl>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 34, // rd = op_asl(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x0c: return op_adjust_addr<&SMPcore::op_asl>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 34, // rd = op_asl(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x0d: return op_push(regs.p); -// void SMPcore::op_push(uint8 r) { -{ - 1, // op_io(); - 1, // op_io(); - 37, // op_writesp(regs.p); - 2, // //!!NEXT -}, -// case 0x0e: return op_test_addr(1); -// void SMPcore::op_test_addr(bool set) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 38, // regs.p.n = (regs.a - rd) & 0x80; - 39, // regs.p.z = (regs.a - rd) == 0; - 40, // op_read(dp); - 41, // op_write(dp, rd | regs.a); - 2, // //!!NEXT -}, -// case 0x0f: return op_brk(); -// void SMPcore::op_brk() { -{ - 42, // rd.l = op_read(0xffde); - 43, // rd.h = op_read(0xffdf); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 37, // op_writesp(regs.p); - 8, // regs.pc = rd; - 44, // regs.p.b = 1; - 45, // regs.p.i = 0; - 2, // //!!NEXT -}, -// case 0x10: return op_branch(regs.p.n == 0); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 46, // if(regs.p.n != 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x11: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x12: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x13: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x14: return op_read_dpi<&SMPcore::op_or>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x15: return op_read_addri<&SMPcore::op_or>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x16: return op_read_addri<&SMPcore::op_or>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x17: return op_read_idpy<&SMPcore::op_or>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x18: return op_write_dp_const<&SMPcore::op_or>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 29, // wr = op_or(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x19: return op_write_ix_iy<&SMPcore::op_or>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 29, // wr = op_or(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0x1a: return op_adjust_dpw(-1); -// void SMPcore::op_adjust_dpw(signed n) { -{ - 9, // dp = op_readpc(); - 54, // rd.w = op_readdp(dp) - 1; - 55, // op_writedp(dp++, rd.l); - 56, // rd.h += op_readdp(dp); - 57, // op_writedp(dp++, rd.h); - 58, // regs.p.n = rd & 0x8000; - 59, // regs.p.z = rd == 0; - 2, // //!!NEXT -}, -// case 0x1b: return op_adjust_dpx<&SMPcore::op_asl>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 34, // rd = op_asl(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x1c: return op_adjust<&SMPcore::op_asl>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 61, // regs.a = op_asl(regs.a); - 2, // //!!NEXT -}, -// case 0x1d: return op_adjust<&SMPcore::op_dec>(regs.x); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 62, // regs.x = op_dec(regs.x); - 2, // //!!NEXT -}, -// case 0x1e: return op_read_addr<&SMPcore::op_cmp>(regs.x); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 63, // regs.x = op_cmp(regs.x, rd); - 2, // //!!NEXT -}, -// case 0x1f: return op_jmp_iaddrx(); -// void SMPcore::op_jmp_iaddrx() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 64, // dp += regs.x; - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x20: return op_set_flag(regs.p.p, 0); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 65, // regs.p.p = 0; - 2, // //!!NEXT -}, -// case 0x21: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x22: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x23: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x24: return op_read_dp<&SMPcore::op_and>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x25: return op_read_addr<&SMPcore::op_and>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x26: return op_read_ix<&SMPcore::op_and>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x27: return op_read_idpx<&SMPcore::op_and>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x28: return op_read_const<&SMPcore::op_and>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x29: return op_write_dp_dp<&SMPcore::op_and>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 67, // wr = op_and(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x2a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 1, // op_io(); - 68, // regs.p.c |= (rd & (1 << bit)) ^ 1; - 2, // //!!NEXT -}, -// case 0x2b: return op_adjust_dp<&SMPcore::op_rol>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 69, // rd = op_rol(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x2c: return op_adjust_addr<&SMPcore::op_rol>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 69, // rd = op_rol(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x2d: return op_push(regs.a); -// void SMPcore::op_push(uint8 r) { -{ - 1, // op_io(); - 1, // op_io(); - 70, // op_writesp(regs.a); - 2, // //!!NEXT -}, -// case 0x2e: return op_bne_dp(); -// void SMPcore::op_bne_dp() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 71, // if(regs.a == sp) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x2f: return op_branch(true); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x30: return op_branch(regs.p.n == 1); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 72, // if(regs.p.n != 1) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x31: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x32: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x33: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x34: return op_read_dpi<&SMPcore::op_and>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x35: return op_read_addri<&SMPcore::op_and>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x36: return op_read_addri<&SMPcore::op_and>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x37: return op_read_idpy<&SMPcore::op_and>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x38: return op_write_dp_const<&SMPcore::op_and>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 67, // wr = op_and(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x39: return op_write_ix_iy<&SMPcore::op_and>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 67, // wr = op_and(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0x3a: return op_adjust_dpw(+1); -// void SMPcore::op_adjust_dpw(signed n) { -{ - 9, // dp = op_readpc(); - 73, // rd.w = op_readdp(dp) + 1; - 55, // op_writedp(dp++, rd.l); - 56, // rd.h += op_readdp(dp); - 57, // op_writedp(dp++, rd.h); - 58, // regs.p.n = rd & 0x8000; - 59, // regs.p.z = rd == 0; - 2, // //!!NEXT -}, -// case 0x3b: return op_adjust_dpx<&SMPcore::op_rol>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 69, // rd = op_rol(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x3c: return op_adjust<&SMPcore::op_rol>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 74, // regs.a = op_rol(regs.a); - 2, // //!!NEXT -}, -// case 0x3d: return op_adjust<&SMPcore::op_inc>(regs.x); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 75, // regs.x = op_inc(regs.x); - 2, // //!!NEXT -}, -// case 0x3e: return op_read_dp<&SMPcore::op_cmp>(regs.x); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 63, // regs.x = op_cmp(regs.x, rd); - 2, // //!!NEXT -}, -// case 0x3f: return op_jsr_addr(); -// void SMPcore::op_jsr_addr() { -{ - 76, // rd.l = op_readpc(); - 77, // rd.h = op_readpc(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x40: return op_set_flag(regs.p.p, 1); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 78, // regs.p.p = 1; - 2, // //!!NEXT -}, -// case 0x41: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x42: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x43: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x44: return op_read_dp<&SMPcore::op_eor>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x45: return op_read_addr<&SMPcore::op_eor>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x46: return op_read_ix<&SMPcore::op_eor>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x47: return op_read_idpx<&SMPcore::op_eor>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x48: return op_read_const<&SMPcore::op_eor>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x49: return op_write_dp_dp<&SMPcore::op_eor>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 80, // wr = op_eor(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x4a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 81, // regs.p.c &= (rd & (1 << bit)) ^ 0; - 2, // //!!NEXT -}, -// case 0x4b: return op_adjust_dp<&SMPcore::op_lsr>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 82, // rd = op_lsr(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x4c: return op_adjust_addr<&SMPcore::op_lsr>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 82, // rd = op_lsr(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x4d: return op_push(regs.x); -// void SMPcore::op_push(uint8 r) { -{ - 1, // op_io(); - 1, // op_io(); - 83, // op_writesp(regs.x); - 2, // //!!NEXT -}, -// case 0x4e: return op_test_addr(0); -// void SMPcore::op_test_addr(bool set) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 38, // regs.p.n = (regs.a - rd) & 0x80; - 39, // regs.p.z = (regs.a - rd) == 0; - 40, // op_read(dp); - 84, // op_write(dp, rd & ~regs.a); - 2, // //!!NEXT -}, -// case 0x4f: return op_jsp_dp(); -// void SMPcore::op_jsp_dp() { -{ - 13, // rd = op_readpc(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 85, // regs.pc = 0xff00 | rd; - 2, // //!!NEXT -}, -// case 0x50: return op_branch(regs.p.v == 0); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 86, // if(regs.p.v != 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x51: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x52: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x53: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x54: return op_read_dpi<&SMPcore::op_eor>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x55: return op_read_addri<&SMPcore::op_eor>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x56: return op_read_addri<&SMPcore::op_eor>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x57: return op_read_idpy<&SMPcore::op_eor>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x58: return op_write_dp_const<&SMPcore::op_eor>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 80, // wr = op_eor(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x59: return op_write_ix_iy<&SMPcore::op_eor>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 80, // wr = op_eor(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0x5a: return op_read_dpw<&SMPcore::op_cpw>(); -// void SMPcore::op_read_dpw() { -{ - 9, // dp = op_readpc(); - 87, // rd.l = op_readdp(dp++); - 88, // rd.h = op_readdp(dp++); - 89, // regs.ya = op_cpw(regs.ya, rd); - 2, // //!!NEXT -}, -// case 0x5b: return op_adjust_dpx<&SMPcore::op_lsr>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 82, // rd = op_lsr(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x5c: return op_adjust<&SMPcore::op_lsr>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 90, // regs.a = op_lsr(regs.a); - 2, // //!!NEXT -}, -// case 0x5d: return op_transfer(regs.a, regs.x); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 91, // regs.x = regs.a; - 92, // regs.p.n = (regs.x & 0x80); - 93, // regs.p.z = (regs.x == 0); - 2, // //!!NEXT -}, -// case 0x5e: return op_read_addr<&SMPcore::op_cmp>(regs.y); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 94, // regs.y = op_cmp(regs.y, rd); - 2, // //!!NEXT -}, -// case 0x5f: return op_jmp_addr(); -// void SMPcore::op_jmp_addr() { -{ - 76, // rd.l = op_readpc(); - 77, // rd.h = op_readpc(); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x60: return op_set_flag(regs.p.c, 0); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 95, // regs.p.c = 0; - 2, // //!!NEXT -}, -// case 0x61: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x62: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x63: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x64: return op_read_dp<&SMPcore::op_cmp>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x65: return op_read_addr<&SMPcore::op_cmp>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x66: return op_read_ix<&SMPcore::op_cmp>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x67: return op_read_idpx<&SMPcore::op_cmp>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x68: return op_read_const<&SMPcore::op_cmp>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x69: return op_write_dp_dp<&SMPcore::op_cmp>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 97, // wr = op_cmp(wr, rd); - 1, // op_io(); - 2, // //!!NEXT -}, -// case 0x6a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 98, // regs.p.c &= (rd & (1 << bit)) ^ 1; - 2, // //!!NEXT -}, -// case 0x6b: return op_adjust_dp<&SMPcore::op_ror>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 99, // rd = op_ror(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x6c: return op_adjust_addr<&SMPcore::op_ror>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 99, // rd = op_ror(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x6d: return op_push(regs.y); -// void SMPcore::op_push(uint8 r) { -{ - 1, // op_io(); - 1, // op_io(); - 100, // op_writesp(regs.y); - 2, // //!!NEXT -}, -// case 0x6e: return op_bne_dpdec(); -// void SMPcore::op_bne_dpdec() { -{ - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 101, // op_writedp(dp, --wr); - 13, // rd = op_readpc(); - 102, // if(wr == 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x6f: return op_rts(); -// void SMPcore::op_rts() { -{ - 103, // rd.l = op_readsp(); - 104, // rd.h = op_readsp(); - 1, // op_io(); - 1, // op_io(); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x70: return op_branch(regs.p.v == 1); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 105, // if(regs.p.v != 1) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x71: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x72: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x73: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x74: return op_read_dpi<&SMPcore::op_cmp>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x75: return op_read_addri<&SMPcore::op_cmp>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x76: return op_read_addri<&SMPcore::op_cmp>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x77: return op_read_idpy<&SMPcore::op_cmp>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x78: return op_write_dp_const<&SMPcore::op_cmp>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 97, // wr = op_cmp(wr, rd); - 1, // op_io(); - 2, // //!!NEXT -}, -// case 0x79: return op_write_ix_iy<&SMPcore::op_cmp>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 97, // wr = op_cmp(wr, rd); - 1, // op_io(); - 2, // //!!NEXT -}, -// case 0x7a: return op_read_dpw<&SMPcore::op_adw>(); -// void SMPcore::op_read_dpw() { -{ - 9, // dp = op_readpc(); - 87, // rd.l = op_readdp(dp++); - 1, // op_io(); - 88, // rd.h = op_readdp(dp++); - 106, // regs.ya = op_adw(regs.ya, rd); - 2, // //!!NEXT -}, -// case 0x7b: return op_adjust_dpx<&SMPcore::op_ror>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 99, // rd = op_ror(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x7c: return op_adjust<&SMPcore::op_ror>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 107, // regs.a = op_ror(regs.a); - 2, // //!!NEXT -}, -// case 0x7d: return op_transfer(regs.x, regs.a); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 108, // regs.a = regs.x; - 109, // regs.p.n = (regs.a & 0x80); - 110, // regs.p.z = (regs.a == 0); - 2, // //!!NEXT -}, -// case 0x7e: return op_read_dp<&SMPcore::op_cmp>(regs.y); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 94, // regs.y = op_cmp(regs.y, rd); - 2, // //!!NEXT -}, -// case 0x7f: return op_rti(); -// void SMPcore::op_rti() { -{ - 111, // regs.p = op_readsp(); - 103, // rd.l = op_readsp(); - 104, // rd.h = op_readsp(); - 1, // op_io(); - 1, // op_io(); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x80: return op_set_flag(regs.p.c, 1); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 112, // regs.p.c = 1; - 2, // //!!NEXT -}, -// case 0x81: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x82: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x83: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x84: return op_read_dp<&SMPcore::op_adc>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x85: return op_read_addr<&SMPcore::op_adc>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x86: return op_read_ix<&SMPcore::op_adc>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x87: return op_read_idpx<&SMPcore::op_adc>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x88: return op_read_const<&SMPcore::op_adc>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x89: return op_write_dp_dp<&SMPcore::op_adc>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 114, // wr = op_adc(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x8a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 1, // op_io(); - 115, // regs.p.c ^= (bool)(rd & (1 << bit)); - 2, // //!!NEXT -}, -// case 0x8b: return op_adjust_dp<&SMPcore::op_dec>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 116, // rd = op_dec(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x8c: return op_adjust_addr<&SMPcore::op_dec>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 116, // rd = op_dec(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x8d: return op_read_const<&SMPcore::op_ld>(regs.y); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 117, // regs.y = op_ld(regs.y, rd); - 2, // //!!NEXT -}, -// case 0x8e: return op_plp(); -// void SMPcore::op_plp() { -{ - 1, // op_io(); - 1, // op_io(); - 111, // regs.p = op_readsp(); - 2, // //!!NEXT -}, -// case 0x8f: return op_write_dp_const<&SMPcore::op_st>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 118, // wr = op_st(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x90: return op_branch(regs.p.c == 0); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 119, // if(regs.p.c != 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x91: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x92: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x93: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x94: return op_read_dpi<&SMPcore::op_adc>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x95: return op_read_addri<&SMPcore::op_adc>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x96: return op_read_addri<&SMPcore::op_adc>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x97: return op_read_idpy<&SMPcore::op_adc>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x98: return op_write_dp_const<&SMPcore::op_adc>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 114, // wr = op_adc(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x99: return op_write_ix_iy<&SMPcore::op_adc>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 114, // wr = op_adc(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0x9a: return op_read_dpw<&SMPcore::op_sbw>(); -// void SMPcore::op_read_dpw() { -{ - 9, // dp = op_readpc(); - 87, // rd.l = op_readdp(dp++); - 1, // op_io(); - 88, // rd.h = op_readdp(dp++); - 120, // regs.ya = op_sbw(regs.ya, rd); - 2, // //!!NEXT -}, -// case 0x9b: return op_adjust_dpx<&SMPcore::op_dec>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 116, // rd = op_dec(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x9c: return op_adjust<&SMPcore::op_dec>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 121, // regs.a = op_dec(regs.a); - 2, // //!!NEXT -}, -// case 0x9d: return op_transfer(regs.s, regs.x); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 122, // regs.x = regs.s; - 92, // regs.p.n = (regs.x & 0x80); - 93, // regs.p.z = (regs.x == 0); - 2, // //!!NEXT -}, -// case 0x9e: return op_div_ya_x(); -// void SMPcore::op_div_ya_x() { -{ - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - //ya = regs.ya; - ////overflow set if quotient >= 256 - //regs.p.v = (regs.y >= regs.x); - //regs.p.h = ((regs.y & 15) >= (regs.x & 15)); - //if(regs.y < (regs.x << 1)) { - ////if quotient is <= 511 (will fit into 9-bit result) - //regs.a = ya / regs.x; - //regs.y = ya % regs.x; - //} else { - ////otherwise, the quotient won't fit into regs.p.v + regs.a - ////this emulates the odd behavior of the S-SMP in this case - //regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x); - //regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x); - //} - ////result is set based on a (quotient) only - //regs.p.n = (regs.a & 0x80); - //regs.p.z = (regs.a == 0); - 123, // //!!MULTI0 - 2, // //!!NEXT -}, -// case 0x9f: return op_xcn(); -// void SMPcore::op_xcn() { -{ - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 124, // regs.a = (regs.a >> 4) | (regs.a << 4); - 125, // regs.p.n = regs.a & 0x80; - 126, // regs.p.z = regs.a == 0; - 2, // //!!NEXT -}, -// case 0xa0: return op_set_flag(regs.p.i, 1); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 1, // op_io(); - 127, // regs.p.i = 1; - 2, // //!!NEXT -}, -// case 0xa1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xa2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xa3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xa4: return op_read_dp<&SMPcore::op_sbc>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa5: return op_read_addr<&SMPcore::op_sbc>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa6: return op_read_ix<&SMPcore::op_sbc>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa7: return op_read_idpx<&SMPcore::op_sbc>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa8: return op_read_const<&SMPcore::op_sbc>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa9: return op_write_dp_dp<&SMPcore::op_sbc>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 129, // wr = op_sbc(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0xaa: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 130, // regs.p.c = (rd & (1 << bit)); - 2, // //!!NEXT -}, -// case 0xab: return op_adjust_dp<&SMPcore::op_inc>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 131, // rd = op_inc(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0xac: return op_adjust_addr<&SMPcore::op_inc>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 131, // rd = op_inc(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0xad: return op_read_const<&SMPcore::op_cmp>(regs.y); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 94, // regs.y = op_cmp(regs.y, rd); - 2, // //!!NEXT -}, -// case 0xae: return op_pull(regs.a); -// void SMPcore::op_pull(uint8 &r) { -{ - 1, // op_io(); - 1, // op_io(); - 132, // regs.a = op_readsp(); - 2, // //!!NEXT -}, -// case 0xaf: return op_sta_ixinc(); -// void SMPcore::op_sta_ixinc() { -{ - 1, // op_io(); - 1, // op_io(); - 133, // op_writedp(regs.x++, regs.a); - 2, // //!!NEXT -}, -// case 0xb0: return op_branch(regs.p.c == 1); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 134, // if(regs.p.c != 1) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xb1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xb2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xb3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xb4: return op_read_dpi<&SMPcore::op_sbc>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xb5: return op_read_addri<&SMPcore::op_sbc>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xb6: return op_read_addri<&SMPcore::op_sbc>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xb7: return op_read_idpy<&SMPcore::op_sbc>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xb8: return op_write_dp_const<&SMPcore::op_sbc>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 129, // wr = op_sbc(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0xb9: return op_write_ix_iy<&SMPcore::op_sbc>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 129, // wr = op_sbc(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0xba: return op_read_dpw<&SMPcore::op_ldw>(); -// void SMPcore::op_read_dpw() { -{ - 9, // dp = op_readpc(); - 87, // rd.l = op_readdp(dp++); - 1, // op_io(); - 88, // rd.h = op_readdp(dp++); - 135, // regs.ya = op_ldw(regs.ya, rd); - 2, // //!!NEXT -}, -// case 0xbb: return op_adjust_dpx<&SMPcore::op_inc>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 131, // rd = op_inc(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0xbc: return op_adjust<&SMPcore::op_inc>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 136, // regs.a = op_inc(regs.a); - 2, // //!!NEXT -}, -// case 0xbd: return op_transfer(regs.x, regs.s); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 137, // regs.s = regs.x; - 2, // //!!NEXT -}, -// case 0xbe: return op_das(); -// void SMPcore::op_das() { -{ - 1, // op_io(); - 1, // op_io(); - //if(!regs.p.c || (regs.a) > 0x99) { - //regs.a -= 0x60; - //regs.p.c = 0; - //} - //if(!regs.p.h || (regs.a & 15) > 0x09) { - //regs.a -= 0x06; - //} - //regs.p.n = (regs.a & 0x80); - //regs.p.z = (regs.a == 0); - 138, // //!!MULTI1 - 2, // //!!NEXT -}, -// case 0xbf: return op_lda_ixinc(); -// void SMPcore::op_lda_ixinc() { -{ - 1, // op_io(); - 139, // regs.a = op_readdp(regs.x++); - 1, // op_io(); - 125, // regs.p.n = regs.a & 0x80; - 126, // regs.p.z = regs.a == 0; - 2, // //!!NEXT -}, -// case 0xc0: return op_set_flag(regs.p.i, 0); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 1, // op_io(); - 45, // regs.p.i = 0; - 2, // //!!NEXT -}, -// case 0xc1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xc2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xc3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xc4: return op_write_dp(regs.a); -// void SMPcore::op_write_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 140, // op_readdp(dp); - 141, // op_writedp(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xc5: return op_write_addr(regs.a); -// void SMPcore::op_write_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xc6: return op_sta_ix(); -// void SMPcore::op_sta_ix() { -{ - 1, // op_io(); - 143, // op_readdp(regs.x); - 144, // op_writedp(regs.x, regs.a); - 2, // //!!NEXT -}, -// case 0xc7: return op_sta_idpx(); -// void SMPcore::op_sta_idpx() { -{ - 145, // sp = op_readpc() + regs.x; - 1, // op_io(); - 146, // dp.l = op_readdp(sp++); - 147, // dp.h = op_readdp(sp++); - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xc8: return op_read_const<&SMPcore::op_cmp>(regs.x); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 63, // regs.x = op_cmp(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xc9: return op_write_addr(regs.x); -// void SMPcore::op_write_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 40, // op_read(dp); - 148, // op_write(dp, regs.x); - 2, // //!!NEXT -}, -// case 0xca: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 1, // op_io(); - 149, // rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0xcb: return op_write_dp(regs.y); -// void SMPcore::op_write_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 140, // op_readdp(dp); - 150, // op_writedp(dp, regs.y); - 2, // //!!NEXT -}, -// case 0xcc: return op_write_addr(regs.y); -// void SMPcore::op_write_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 40, // op_read(dp); - 151, // op_write(dp, regs.y); - 2, // //!!NEXT -}, -// case 0xcd: return op_read_const<&SMPcore::op_ld>(regs.x); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 152, // regs.x = op_ld(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xce: return op_pull(regs.x); -// void SMPcore::op_pull(uint8 &r) { -{ - 1, // op_io(); - 1, // op_io(); - 153, // regs.x = op_readsp(); - 2, // //!!NEXT -}, -// case 0xcf: return op_mul_ya(); -// void SMPcore::op_mul_ya() { -{ - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - //ya = regs.y * regs.a; - //regs.a = ya; - //regs.y = ya >> 8; - ////result is set based on y (high-byte) only - //regs.p.n = (regs.y & 0x80); - //regs.p.z = (regs.y == 0); - 154, // //!!MULTI2 - 2, // //!!NEXT -}, -// case 0xd0: return op_branch(regs.p.z == 0); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 155, // if(regs.p.z != 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xd1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xd2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xd3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xd4: return op_write_dpi(regs.a, regs.x); -// void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 140, // op_readdp(dp); - 141, // op_writedp(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xd5: return op_write_addri(regs.x); -// void SMPcore::op_write_addri(uint8 &i) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 64, // dp += regs.x; - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xd6: return op_write_addri(regs.y); -// void SMPcore::op_write_addri(uint8 &i) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 156, // dp += regs.y; - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xd7: return op_sta_idpy(); -// void SMPcore::op_sta_idpy() { -{ - 26, // sp = op_readpc(); - 146, // dp.l = op_readdp(sp++); - 147, // dp.h = op_readdp(sp++); - 1, // op_io(); - 156, // dp += regs.y; - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xd8: return op_write_dp(regs.x); -// void SMPcore::op_write_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 140, // op_readdp(dp); - 157, // op_writedp(dp, regs.x); - 2, // //!!NEXT -}, -// case 0xd9: return op_write_dpi(regs.x, regs.y); -// void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { -{ - 158, // dp = op_readpc() + regs.y; - 1, // op_io(); - 140, // op_readdp(dp); - 157, // op_writedp(dp, regs.x); - 2, // //!!NEXT -}, -// case 0xda: return op_stw_dp(); -// void SMPcore::op_stw_dp() { -{ - 9, // dp = op_readpc(); - 140, // op_readdp(dp); - 159, // op_writedp(dp++, regs.a); - 160, // op_writedp(dp++, regs.y); - 2, // //!!NEXT -}, -// case 0xdb: return op_write_dpi(regs.y, regs.x); -// void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 140, // op_readdp(dp); - 150, // op_writedp(dp, regs.y); - 2, // //!!NEXT -}, -// case 0xdc: return op_adjust<&SMPcore::op_dec>(regs.y); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 161, // regs.y = op_dec(regs.y); - 2, // //!!NEXT -}, -// case 0xdd: return op_transfer(regs.y, regs.a); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 162, // regs.a = regs.y; - 109, // regs.p.n = (regs.a & 0x80); - 110, // regs.p.z = (regs.a == 0); - 2, // //!!NEXT -}, -// case 0xde: return op_bne_dpx(); -// void SMPcore::op_bne_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 163, // sp = op_readdp(dp + regs.x); - 13, // rd = op_readpc(); - 1, // op_io(); - 71, // if(regs.a == sp) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xdf: return op_daa(); -// void SMPcore::op_daa() { -{ - 1, // op_io(); - 1, // op_io(); - //if(regs.p.c || (regs.a) > 0x99) { - //regs.a += 0x60; - //regs.p.c = 1; - //} - //if(regs.p.h || (regs.a & 15) > 0x09) { - //regs.a += 0x06; - //} - //regs.p.n = (regs.a & 0x80); - //regs.p.z = (regs.a == 0); - 164, // //!!MULTI3 - 2, // //!!NEXT -}, -// case 0xe0: return op_clv(); -// void SMPcore::op_clv() { -{ - 1, // op_io(); - 165, // regs.p.v = 0; - 166, // regs.p.h = 0; - 2, // //!!NEXT -}, -// case 0xe1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xe2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xe3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xe4: return op_read_dp<&SMPcore::op_ld>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe5: return op_read_addr<&SMPcore::op_ld>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe6: return op_read_ix<&SMPcore::op_ld>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe7: return op_read_idpx<&SMPcore::op_ld>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe8: return op_read_const<&SMPcore::op_ld>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe9: return op_read_addr<&SMPcore::op_ld>(regs.x); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 152, // regs.x = op_ld(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xea: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 168, // rd ^= 1 << bit; - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0xeb: return op_read_dp<&SMPcore::op_ld>(regs.y); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 117, // regs.y = op_ld(regs.y, rd); - 2, // //!!NEXT -}, -// case 0xec: return op_read_addr<&SMPcore::op_ld>(regs.y); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 117, // regs.y = op_ld(regs.y, rd); - 2, // //!!NEXT -}, -// case 0xed: return op_cmc(); -// void SMPcore::op_cmc() { -{ - 1, // op_io(); - 1, // op_io(); - 169, // regs.p.c = !regs.p.c; - 2, // //!!NEXT -}, -// case 0xee: return op_pull(regs.y); -// void SMPcore::op_pull(uint8 &r) { -{ - 1, // op_io(); - 1, // op_io(); - 170, // regs.y = op_readsp(); - 2, // //!!NEXT -}, -// case 0xef: return op_wait(); -// void SMPcore::op_wait() { -{ - 1, // op_io(); - 1, // op_io(); - 171, // //!!REPEAT -}, -// case 0xf0: return op_branch(regs.p.z == 1); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 172, // if(regs.p.z != 1) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xf1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xf2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xf3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xf4: return op_read_dpi<&SMPcore::op_ld>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xf5: return op_read_addri<&SMPcore::op_ld>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xf6: return op_read_addri<&SMPcore::op_ld>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xf7: return op_read_idpy<&SMPcore::op_ld>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xf8: return op_read_dp<&SMPcore::op_ld>(regs.x); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 152, // regs.x = op_ld(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xf9: return op_read_dpi<&SMPcore::op_ld>(regs.x, regs.y); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 173, // rd = op_readdp(dp + regs.y); - 152, // regs.x = op_ld(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xfa: return op_write_dp_dp<&SMPcore::op_st>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 118, // wr = op_st(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0xfb: return op_read_dpi<&SMPcore::op_ld>(regs.y, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 117, // regs.y = op_ld(regs.y, rd); - 2, // //!!NEXT -}, -// case 0xfc: return op_adjust<&SMPcore::op_inc>(regs.y); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 174, // regs.y = op_inc(regs.y); - 2, // //!!NEXT -}, -// case 0xfd: return op_transfer(regs.a, regs.y); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 175, // regs.y = regs.a; - 176, // regs.p.n = (regs.y & 0x80); - 177, // regs.p.z = (regs.y == 0); - 2, // //!!NEXT -}, -// case 0xfe: return op_bne_ydec(); -// void SMPcore::op_bne_ydec() { -{ - 13, // rd = op_readpc(); - 1, // op_io(); - 1, // op_io(); - 178, // if(--regs.y == 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xff: return op_wait(); -// void SMPcore::op_wait() { -{ - 1, // op_io(); - 1, // op_io(); - 171, // //!!REPEAT -}, - -}; // const int uoptable[][] = { - - - - -void SMPcore::op_step() -{ - switch (uoptable[opcode][uindex]) - { - case 1: - op_io(); - break; - case 2: - op_next();//!!NEXT - break; - case 3: - dp = 0xffde - ((opcode >> 4) << 1); - break; - case 4: - rd.l = op_read(dp++); - break; - case 5: - rd.h = op_read(dp++); - break; - case 6: - op_writesp(regs.pc.h); - break; - case 7: - op_writesp(regs.pc.l); - break; - case 8: - regs.pc = rd; - break; - case 9: - dp = op_readpc(); - break; - case 10: - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - break; - case 11: - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - break; - case 12: - sp = op_readdp(dp); - break; - case 13: - rd = op_readpc(); - break; - case 14: - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) op_next(); - break; - case 15: - regs.pc += (int8)rd; - break; - case 16: - rd = op_readdp(dp); - break; - case 17: - regs.a = op_or(regs.a, rd); - break; - case 18: - dp.l = op_readpc(); - break; - case 19: - dp.h = op_readpc(); - break; - case 20: - rd = op_read(dp); - break; - case 21: - rd = op_readdp(regs.x); - break; - case 22: - dp = op_readpc() + regs.x; - break; - case 23: - sp.l = op_readdp(dp++); - break; - case 24: - sp.h = op_readdp(dp++); - break; - case 25: - rd = op_read(sp); - break; - case 26: - sp = op_readpc(); - break; - case 27: - rd = op_readdp(sp); - break; - case 28: - wr = op_readdp(dp); - break; - case 29: - wr = op_or(wr, rd); - break; - case 30: - op_writedp(dp, wr); - break; - case 31: - bit = dp >> 13; - break; - case 32: - dp &= 0x1fff; - break; - case 33: - regs.p.c |= (rd & (1 << bit)) ^ 0; - break; - case 34: - rd = op_asl(rd); - break; - case 35: - op_writedp(dp, rd); - break; - case 36: - op_write(dp, rd); - break; - case 37: - op_writesp(regs.p); - break; - case 38: - regs.p.n = (regs.a - rd) & 0x80; - break; - case 39: - regs.p.z = (regs.a - rd) == 0; - break; - case 40: - op_read(dp); - break; - case 41: - op_write(dp, rd | regs.a); - break; - case 42: - rd.l = op_read(0xffde); - break; - case 43: - rd.h = op_read(0xffdf); - break; - case 44: - regs.p.b = 1; - break; - case 45: - regs.p.i = 0; - break; - case 46: - if(regs.p.n != 0) op_next(); - break; - case 47: - rd = op_readdp(dp + regs.x); - break; - case 48: - rd = op_read(dp + regs.x); - break; - case 49: - rd = op_read(dp + regs.y); - break; - case 50: - rd = op_read(sp + regs.y); - break; - case 51: - rd = op_readdp(regs.y); - break; - case 52: - wr = op_readdp(regs.x); - break; - case 53: - op_writedp(regs.x, wr); - break; - case 54: - rd.w = op_readdp(dp) - 1; - break; - case 55: - op_writedp(dp++, rd.l); - break; - case 56: - rd.h += op_readdp(dp); - break; - case 57: - op_writedp(dp++, rd.h); - break; - case 58: - regs.p.n = rd & 0x8000; - break; - case 59: - regs.p.z = rd == 0; - break; - case 60: - op_writedp(dp + regs.x, rd); - break; - case 61: - regs.a = op_asl(regs.a); - break; - case 62: - regs.x = op_dec(regs.x); - break; - case 63: - regs.x = op_cmp(regs.x, rd); - break; - case 64: - dp += regs.x; - break; - case 65: - regs.p.p = 0; - break; - case 66: - regs.a = op_and(regs.a, rd); - break; - case 67: - wr = op_and(wr, rd); - break; - case 68: - regs.p.c |= (rd & (1 << bit)) ^ 1; - break; - case 69: - rd = op_rol(rd); - break; - case 70: - op_writesp(regs.a); - break; - case 71: - if(regs.a == sp) op_next(); - break; - case 72: - if(regs.p.n != 1) op_next(); - break; - case 73: - rd.w = op_readdp(dp) + 1; - break; - case 74: - regs.a = op_rol(regs.a); - break; - case 75: - regs.x = op_inc(regs.x); - break; - case 76: - rd.l = op_readpc(); - break; - case 77: - rd.h = op_readpc(); - break; - case 78: - regs.p.p = 1; - break; - case 79: - regs.a = op_eor(regs.a, rd); - break; - case 80: - wr = op_eor(wr, rd); - break; - case 81: - regs.p.c &= (rd & (1 << bit)) ^ 0; - break; - case 82: - rd = op_lsr(rd); - break; - case 83: - op_writesp(regs.x); - break; - case 84: - op_write(dp, rd & ~regs.a); - break; - case 85: - regs.pc = 0xff00 | rd; - break; - case 86: - if(regs.p.v != 0) op_next(); - break; - case 87: - rd.l = op_readdp(dp++); - break; - case 88: - rd.h = op_readdp(dp++); - break; - case 89: - regs.ya = op_cpw(regs.ya, rd); - break; - case 90: - regs.a = op_lsr(regs.a); - break; - case 91: - regs.x = regs.a; - break; - case 92: - regs.p.n = (regs.x & 0x80); - break; - case 93: - regs.p.z = (regs.x == 0); - break; - case 94: - regs.y = op_cmp(regs.y, rd); - break; - case 95: - regs.p.c = 0; - break; - case 96: - regs.a = op_cmp(regs.a, rd); - break; - case 97: - wr = op_cmp(wr, rd); - break; - case 98: - regs.p.c &= (rd & (1 << bit)) ^ 1; - break; - case 99: - rd = op_ror(rd); - break; - case 100: - op_writesp(regs.y); - break; - case 101: - op_writedp(dp, --wr); - break; - case 102: - if(wr == 0) op_next(); - break; - case 103: - rd.l = op_readsp(); - break; - case 104: - rd.h = op_readsp(); - break; - case 105: - if(regs.p.v != 1) op_next(); - break; - case 106: - regs.ya = op_adw(regs.ya, rd); - break; - case 107: - regs.a = op_ror(regs.a); - break; - case 108: - regs.a = regs.x; - break; - case 109: - regs.p.n = (regs.a & 0x80); - break; - case 110: - regs.p.z = (regs.a == 0); - break; - case 111: - regs.p = op_readsp(); - break; - case 112: - regs.p.c = 1; - break; - case 113: - regs.a = op_adc(regs.a, rd); - break; - case 114: - wr = op_adc(wr, rd); - break; - case 115: - regs.p.c ^= (bool)(rd & (1 << bit)); - break; - case 116: - rd = op_dec(rd); - break; - case 117: - regs.y = op_ld(regs.y, rd); - break; - case 118: - wr = op_st(wr, rd); - break; - case 119: - if(regs.p.c != 0) op_next(); - break; - case 120: - regs.ya = op_sbw(regs.ya, rd); - break; - case 121: - regs.a = op_dec(regs.a); - break; - case 122: - regs.x = regs.s; - break; - case 123: - //!!MULTI0 - ya = regs.ya; - //overflow set if quotient >= 256 - regs.p.v = (regs.y >= regs.x); - regs.p.h = ((regs.y & 15) >= (regs.x & 15)); - if(regs.y < (regs.x << 1)) { - //if quotient is <= 511 (will fit into 9-bit result) - regs.a = ya / regs.x; - regs.y = ya % regs.x; - } else { - //otherwise, the quotient won't fit into regs.p.v + regs.a - //this emulates the odd behavior of the S-SMP in this case - regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x); - regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x); - } - //result is set based on a (quotient) only - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); - break; - case 124: - regs.a = (regs.a >> 4) | (regs.a << 4); - break; - case 125: - regs.p.n = regs.a & 0x80; - break; - case 126: - regs.p.z = regs.a == 0; - break; - case 127: - regs.p.i = 1; - break; - case 128: - regs.a = op_sbc(regs.a, rd); - break; - case 129: - wr = op_sbc(wr, rd); - break; - case 130: - regs.p.c = (rd & (1 << bit)); - break; - case 131: - rd = op_inc(rd); - break; - case 132: - regs.a = op_readsp(); - break; - case 133: - op_writedp(regs.x++, regs.a); - break; - case 134: - if(regs.p.c != 1) op_next(); - break; - case 135: - regs.ya = op_ldw(regs.ya, rd); - break; - case 136: - regs.a = op_inc(regs.a); - break; - case 137: - regs.s = regs.x; - break; - case 138: - //!!MULTI1 - if(!regs.p.c || (regs.a) > 0x99) { - regs.a -= 0x60; - regs.p.c = 0; - } - if(!regs.p.h || (regs.a & 15) > 0x09) { - regs.a -= 0x06; - } - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); - break; - case 139: - regs.a = op_readdp(regs.x++); - break; - case 140: - op_readdp(dp); - break; - case 141: - op_writedp(dp, regs.a); - break; - case 142: - op_write(dp, regs.a); - break; - case 143: - op_readdp(regs.x); - break; - case 144: - op_writedp(regs.x, regs.a); - break; - case 145: - sp = op_readpc() + regs.x; - break; - case 146: - dp.l = op_readdp(sp++); - break; - case 147: - dp.h = op_readdp(sp++); - break; - case 148: - op_write(dp, regs.x); - break; - case 149: - rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - break; - case 150: - op_writedp(dp, regs.y); - break; - case 151: - op_write(dp, regs.y); - break; - case 152: - regs.x = op_ld(regs.x, rd); - break; - case 153: - regs.x = op_readsp(); - break; - case 154: - //!!MULTI2 - ya = regs.y * regs.a; - regs.a = ya; - regs.y = ya >> 8; - //result is set based on y (high-byte) only - regs.p.n = (regs.y & 0x80); - regs.p.z = (regs.y == 0); - break; - case 155: - if(regs.p.z != 0) op_next(); - break; - case 156: - dp += regs.y; - break; - case 157: - op_writedp(dp, regs.x); - break; - case 158: - dp = op_readpc() + regs.y; - break; - case 159: - op_writedp(dp++, regs.a); - break; - case 160: - op_writedp(dp++, regs.y); - break; - case 161: - regs.y = op_dec(regs.y); - break; - case 162: - regs.a = regs.y; - break; - case 163: - sp = op_readdp(dp + regs.x); - break; - case 164: - //!!MULTI3 - if(regs.p.c || (regs.a) > 0x99) { - regs.a += 0x60; - regs.p.c = 1; - } - if(regs.p.h || (regs.a & 15) > 0x09) { - regs.a += 0x06; - } - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); - break; - case 165: - regs.p.v = 0; - break; - case 166: - regs.p.h = 0; - break; - case 167: - regs.a = op_ld(regs.a, rd); - break; - case 168: - rd ^= 1 << bit; - break; - case 169: - regs.p.c = !regs.p.c; - break; - case 170: - regs.y = op_readsp(); - break; - case 171: - uindex = -1; //!!REPEAT - break; - case 172: - if(regs.p.z != 1) op_next(); - break; - case 173: - rd = op_readdp(dp + regs.y); - break; - case 174: - regs.y = op_inc(regs.y); - break; - case 175: - regs.y = regs.a; - break; - case 176: - regs.p.n = (regs.y & 0x80); - break; - case 177: - regs.p.z = (regs.y == 0); - break; - case 178: - if(--regs.y == 0) op_next(); - break; - } - uindex++; -} diff --git a/libsnes/bsnes/snes/smp/serialization.cpp b/libsnes/bsnes/snes/smp/serialization.cpp deleted file mode 100644 index 4ece40fdb0..0000000000 --- a/libsnes/bsnes/snes/smp/serialization.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#ifdef SMP_CPP - -void SMP::serialize(serializer &s) { - Processor::serialize(s); - SMPcore::core_serialize(s); - - s.array(apuram, 64 * 1024); - - s.integer(status.clock_counter); - s.integer(status.dsp_counter); - s.integer(status.timer_step); - - s.integer(status.clock_speed); - s.integer(status.timer_speed); - s.integer(status.timers_enable); - s.integer(status.ram_disable); - s.integer(status.ram_writable); - s.integer(status.timers_disable); - - s.integer(status.iplrom_enable); - - s.integer(status.dsp_addr); - - s.integer(status.ram00f8); - s.integer(status.ram00f9); - - s.integer(timer0.stage0_ticks); - s.integer(timer0.stage1_ticks); - s.integer(timer0.stage2_ticks); - s.integer(timer0.stage3_ticks); - s.integer(timer0.current_line); - s.integer(timer0.enable); - s.integer(timer0.target); - - s.integer(timer1.stage0_ticks); - s.integer(timer1.stage1_ticks); - s.integer(timer1.stage2_ticks); - s.integer(timer1.stage3_ticks); - s.integer(timer1.current_line); - s.integer(timer1.enable); - s.integer(timer1.target); - - s.integer(timer2.stage0_ticks); - s.integer(timer2.stage1_ticks); - s.integer(timer2.stage2_ticks); - s.integer(timer2.stage3_ticks); - s.integer(timer2.current_line); - s.integer(timer2.enable); - s.integer(timer2.target); -} - -#endif diff --git a/libsnes/bsnes/snes/system/serialization.cpp b/libsnes/bsnes/snes/system/serialization.cpp deleted file mode 100644 index f4e4517da7..0000000000 --- a/libsnes/bsnes/snes/system/serialization.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#ifdef SYSTEM_CPP - -serializer System::serialize() { - serializer s(serialize_size); - - unsigned signature = 0x31545342, version = Info::SerializerVersion, crc32 = cartridge.crc32(); - char description[512], profile[16]; - memset(&description, 0, sizeof description); - memset(&profile, 0, sizeof profile); - strmcpy(profile, Info::Profile, sizeof profile); - - s.integer(signature); - s.integer(version); - s.integer(crc32); - s.array(description); - s.array(profile); - - serialize_all(s); - return s; -} - -bool System::unserialize(serializer &s) { - unsigned signature, version, crc32; - char description[512], profile[16]; - - s.integer(signature); - s.integer(version); - s.integer(crc32); - s.array(description); - s.array(profile); - - if(signature != 0x31545342) return false; - if(version != Info::SerializerVersion) return false; -//if(crc32 != cartridge.crc32()) return false; - if(strcmp(profile, Info::Profile)) return false; - - power(); - serialize_all(s); - return true; -} - -//======== -//internal -//======== - -void System::serialize(serializer &s) { - s.integer((unsigned&)region); - s.integer((unsigned&)expansion); -} - -//zero 01-dec-2012 - these will embed strings in the savestates, so you can debug them more easily. but itll break the savestate format -//#define DEBUGSAVESTATE(X) s.array(#X) -#define DEBUGSAVESTATE(X) - -void System::serialize_all(serializer &s) { - DEBUGSAVESTATE(cart); - cartridge.serialize(s); - DEBUGSAVESTATE(system); - system.serialize(s); - DEBUGSAVESTATE(random); - random.serialize(s); - DEBUGSAVESTATE(cpu); - cpu.serialize(s); - DEBUGSAVESTATE(smp); - smp.serialize(s); - DEBUGSAVESTATE(ppu); - ppu.serialize(s); - DEBUGSAVESTATE(dsp); - dsp.serialize(s); - DEBUGSAVESTATE(input); - input.serialize(s); - - DEBUGSAVESTATE(sufamiturbo); - if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.serialize(s); - #if defined(GAMEBOY) - DEBUGSAVESTATE(icd2); - if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.serialize(s); - #endif - DEBUGSAVESTATE(superfx); - if(cartridge.has_superfx()) superfx.serialize(s); - DEBUGSAVESTATE(sa1); - if(cartridge.has_sa1()) sa1.serialize(s); - DEBUGSAVESTATE(necdsp); - if(cartridge.has_necdsp()) necdsp.serialize(s); - DEBUGSAVESTATE(hitachidsp); - if(cartridge.has_hitachidsp()) hitachidsp.serialize(s); - DEBUGSAVESTATE(armdsp); - if(cartridge.has_armdsp()) armdsp.serialize(s); - DEBUGSAVESTATE(srtc); - if(cartridge.has_srtc()) srtc.serialize(s); - DEBUGSAVESTATE(sdd1); - if(cartridge.has_sdd1()) sdd1.serialize(s); - DEBUGSAVESTATE(spc7110); - if(cartridge.has_spc7110()) spc7110.serialize(s); - DEBUGSAVESTATE(obc1); - if(cartridge.has_obc1()) obc1.serialize(s); - DEBUGSAVESTATE(msu1); - if(cartridge.has_msu1()) msu1.serialize(s); -} - -//perform dry-run state save: -//determines exactly how many bytes are needed to save state for this cartridge, -//as amount varies per game (eg different RAM sizes, special chips, etc.) -void System::serialize_init() { - serializer s; - - unsigned signature = 0, version = 0, crc32 = 0; - char profile[16], description[512]; - - s.integer(signature); - s.integer(version); - s.integer(crc32); - s.array(profile); - s.array(description); - - serialize_all(s); - serialize_size = s.size(); -} - -#endif diff --git a/libsnes/bsnes/target-libsnes/Makefile b/libsnes/bsnes/target-libsnes/Makefile deleted file mode 100644 index 9ebdc9bde2..0000000000 --- a/libsnes/bsnes/target-libsnes/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -include $(snes)/Makefile -include $(gameboy)/Makefile -output := libsnes - -ifeq ($(platform),x) - flags += -fPIC -else ifeq ($(platform),osx) - flags += -fPIC -else ifeq ($(platform),win) -endif - -#rules -objects := $(objects) libsnes libsnes_pwrap -objects := $(patsubst %,obj/%.o,$(objects)) - -obj/libsnes.o: $(ui)/libsnes.cpp $(ui)/* -obj/libsnes_pwrap.o: $(ui)/libsnes_pwrap.cpp $(ui)/* - -#targets -build: $(objects) -ifeq ($(platform),x) - ar rcs out/libsnes.a $(objects) - $(cpp) -o out/libsnes.so -shared -soname,libsnes.so.1 $(objects) -else ifeq ($(platform),osx) - ar rcs out/libsnes.a $(objects) - $(cpp) -o out/libsnes.dylib -install_name @executable_path/../Libraries/libsnes.dylib -shared -dynamiclib $(objects) -else ifeq ($(platform),win) - $(cpp) -o out/libsneshawk-$(bits)-$(profile).exe $(objects) $(TARGET_LIBSNES_LIBDEPS) -endif - -install: -ifeq ($(platform),x) - install -D -m 755 out/libsnes.a $(DESTDIR)$(prefix)/lib/libsnes.a - install -D -m 755 out/libsnes.so $(DESTDIR)$(prefix)/lib/libsnes.so - ldconfig -n $(DESTDIR)$(prefix)/lib -else ifeq ($(platform),osx) - cp out/libsnes.dylib /usr/local/lib/libsnes.dylib -endif - -uninstall: -ifeq ($(platform),x) - rm $(DESTDIR)$(prefix)/lib/libsnes.a - rm $(DESTDIR)$(prefix)/lib/libsnes.so -else ifeq ($(platform),osx) - rm /usr/local/lib/libsnes.dylib -endif diff --git a/libsnes/s_cpu_coregen/Generex/Decoder.cs b/libsnes/s_cpu_coregen/Generex/Decoder.cs deleted file mode 100644 index 4b14ffa14a..0000000000 --- a/libsnes/s_cpu_coregen/Generex/Decoder.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.IO; -using System.Text.RegularExpressions; - -namespace Generex -{ - public class Decoder - { - TextReader core; - - public List> impls = new List>(); - - List ops = new List(); - - public Decoder(TextReader core, TextReader ops) - { - this.core = core; - string s; - while ((s = ops.ReadLine()) != null) - { - this.ops.Add(s); - } - } - - void ProcMethod(string openline, int opsindex, string submeth) - { - List impl = new List(); - impl.Add("// " + openline); - - string replacant = null; - if (submeth != null) - { - var r = new Regex(@">\(([^\)]*)"); - var m = r.Match(openline); - if (m.Success) - { - replacant = m.Groups[1].Value; - } - else - { - throw new Exception(string.Format("no find in \"{0}\"", openline)); - } - } - - for (int i = opsindex; i < ops.Count; i++) - { - if (string.IsNullOrWhiteSpace(ops[i])) - break; - if (submeth != null && ops[i].Contains("call")) - { - var s = ops[i].Replace("call", submeth); - // also have to replace 'r' tokens - //Console.WriteLine("\"{0}\"{1}\"", s, replacant); - impl.Add(s); - } - else - impl.Add(ops[i]); - } - impls.Add(impl); - } - - public void Scan() - { - string s; - while ((s = core.ReadLine()) != null) - { - var r = new Regex(@": return ([^<\(]*)"); - - var m = r.Match(s); - - if (!m.Success) - continue; - - var methname = m.Groups[1].Value; - - r = new Regex(@"<&SMPcore::([^>]*)"); - - m = r.Match(s); - - string submeth = m.Success ? m.Groups[1].Value : null; - - // find method - - string findu = "void SMPcore::" + methname; - - int i; - for (i = 0; i < ops.Count; i++) - { - if (ops[i].Contains(findu)) - { - ProcMethod(s, i, submeth); - break; - } - - } - if (i == ops.Count) - throw new Exception(string.Format("Couldn't find! \"{0}\"", findu)); - - } - - } - - - } -} diff --git a/libsnes/s_cpu_coregen/Generex/Generex.csproj b/libsnes/s_cpu_coregen/Generex/Generex.csproj deleted file mode 100644 index 0d10a4a46e..0000000000 --- a/libsnes/s_cpu_coregen/Generex/Generex.csproj +++ /dev/null @@ -1,59 +0,0 @@ - - - - Debug - x86 - 8.0.30703 - 2.0 - {CC4ABECE-2F0B-4649-88FC-62F6B2AFBA59} - Exe - Properties - Generex - Generex - v4.0 - Client - 512 - - - x86 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - x86 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/libsnes/s_cpu_coregen/Generex/Generex.sln b/libsnes/s_cpu_coregen/Generex/Generex.sln deleted file mode 100644 index 8a08570643..0000000000 --- a/libsnes/s_cpu_coregen/Generex/Generex.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Generex", "Generex.csproj", "{CC4ABECE-2F0B-4649-88FC-62F6B2AFBA59}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x86 = Debug|x86 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {CC4ABECE-2F0B-4649-88FC-62F6B2AFBA59}.Debug|x86.ActiveCfg = Debug|x86 - {CC4ABECE-2F0B-4649-88FC-62F6B2AFBA59}.Debug|x86.Build.0 = Debug|x86 - {CC4ABECE-2F0B-4649-88FC-62F6B2AFBA59}.Release|x86.ActiveCfg = Release|x86 - {CC4ABECE-2F0B-4649-88FC-62F6B2AFBA59}.Release|x86.Build.0 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/libsnes/s_cpu_coregen/Generex/ListerTheTormentor.cs b/libsnes/s_cpu_coregen/Generex/ListerTheTormentor.cs deleted file mode 100644 index aca5ab90aa..0000000000 --- a/libsnes/s_cpu_coregen/Generex/ListerTheTormentor.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.IO; - -namespace Generex -{ - public class Lister - { - List lines = new List(); - - Dictionary uops = new Dictionary(); - int nextindex = 1; - int nextmulti = 0; - - StringWriter output = new StringWriter(); - - public Lister(TextReader src) - { - string s; - while ((s = src.ReadLine()) != null) - lines.Add(s); - } - - int GetIndex(string uop) - { - uop = uop.Trim(); - int ret; - if (uops.TryGetValue(uop, out ret)) - return ret; - else - { - uops.Add(uop, nextindex++); - return nextindex - 1; - } - } - - void ReadOpcode(ref int idx) - { - if (lines[idx] != "//##IMPL") - throw new Exception("missing IMPL tag"); - idx++; - output.WriteLine(lines[idx++]); - output.WriteLine("// " + lines[idx++]); - output.WriteLine("{"); - while (lines[idx].Length > 1) - { - var s = lines[idx].Trim(); - - if (s == "//[[") // special multiline hack - { - idx++; - while ((s = lines[idx].Trim()) != "//]]") - { - output.WriteLine(" //{0}", s); - idx++; - } - string f = string.Format("//!!MULTI{0}", nextmulti++); - int j = GetIndex(f); - output.WriteLine(" {0}, // {1}", j, f); - idx++; - } - else - { - int j = GetIndex(s); - output.WriteLine(" {0}, // {1}", j, s); - - idx++; - } - } - output.WriteLine(" {0}, // //!!NEXT", GetIndex("//!!NEXT")); - output.WriteLine("},"); - idx++; - } - - public void Scan() - { - for (int idx = 0; idx < lines.Count; ReadOpcode(ref idx)) - { - } - } - - void PrintUops() - { - Console.WriteLine("{"); - Console.WriteLine(" switch (uop)"); - Console.WriteLine(" {"); - foreach (var kv in uops) - { - Console.WriteLine(" case {0}:", kv.Value); - Console.WriteLine(" {0}", kv.Key); - Console.WriteLine(" break;"); - } - Console.WriteLine(" }"); - Console.WriteLine("}"); - - } - - public void PrintStuff() - { - Console.WriteLine(output.ToString()); - - for (int i = 0; i < 8; i++) - Console.WriteLine(); - - PrintUops(); - } - - } -} diff --git a/libsnes/s_cpu_coregen/Generex/Program.cs b/libsnes/s_cpu_coregen/Generex/Program.cs deleted file mode 100644 index 0512796415..0000000000 --- a/libsnes/s_cpu_coregen/Generex/Program.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.IO; - -namespace Generex -{ - class Program - { - // contains case list - const string corecpp = @"..\..\..\..\bsnes\snes\smp\core\core.cpp"; - - const string opcodescpp = @"..\..\..\..\bsnes\snes\smp\core\opcodes.cpp"; - - const string fixedcpp = @".\fixed.cpp"; - - static void Main(string[] args) - { - try - { - // GENEREX PHASE 1 - /* - TextReader core = new StreamReader(corecpp); - TextReader ops = new StreamReader(opcodescpp); - - Decoder d = new Decoder(core, ops); - - d.Scan(); - - foreach (var s in d.impls) - { - Console.WriteLine("//##IMPL"); - foreach (var ss in s) - Console.WriteLine(ss); - } - */ - // GENERX PHASE 2 - - TextReader fixedt = new StreamReader(fixedcpp); - Lister l = new Lister(fixedt); - l.Scan(); - l.PrintStuff(); - } - catch (Exception e) - { - Console.Error.WriteLine("EXCEPTION KILLED ME"); - Console.Error.WriteLine(e.ToString()); - - } - } - } -} diff --git a/libsnes/s_cpu_coregen/Generex/Properties/AssemblyInfo.cs b/libsnes/s_cpu_coregen/Generex/Properties/AssemblyInfo.cs deleted file mode 100644 index da7f6c1ef4..0000000000 --- a/libsnes/s_cpu_coregen/Generex/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Generex")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("Generex")] -[assembly: AssemblyCopyright("Copyright © Microsoft 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("6c415bcd-4fe8-4df8-9bfd-41f0ea31aeed")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/libsnes/s_cpu_coregen/Generex/bin/Debug/fixed.cpp b/libsnes/s_cpu_coregen/Generex/bin/Debug/fixed.cpp deleted file mode 100644 index 229e185977..0000000000 --- a/libsnes/s_cpu_coregen/Generex/bin/Debug/fixed.cpp +++ /dev/null @@ -1,2311 +0,0 @@ -//##IMPL -// case 0x00: return op_nop(); -void SMPcore::op_nop() { - op_io(); -} -//##IMPL -// case 0x01: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x02: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x03: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x04: return op_read_dp<&SMPcore::op_or>(regs.a); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - regs.a = op_or(regs.a, rd); -} -//##IMPL -// case 0x05: return op_read_addr<&SMPcore::op_or>(regs.a); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - regs.a = op_or(regs.a, rd); -} -//##IMPL -// case 0x06: return op_read_ix<&SMPcore::op_or>(); -void SMPcore::op_read_ix() { - op_io(); - rd = op_readdp(regs.x); - regs.a = op_or(regs.a, rd); -} -//##IMPL -// case 0x07: return op_read_idpx<&SMPcore::op_or>(); -void SMPcore::op_read_idpx() { - dp = op_readpc() + regs.x; - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp); - regs.a = op_or(regs.a, rd); -} -//##IMPL -// case 0x08: return op_read_const<&SMPcore::op_or>(regs.a); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - regs.a = op_or(regs.a, rd); -} -//##IMPL -// case 0x09: return op_write_dp_dp<&SMPcore::op_or>(); -void SMPcore::op_write_dp_dp() { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_or(wr, rd); - op_writedp(dp, wr); -} -//##IMPL -// case 0x0a: return op_set_addr_bit(); -void SMPcore::op_set_addr_bit() { - dp.l = op_readpc(); - dp.h = op_readpc(); - bit = dp >> 13; - dp &= 0x1fff; - rd = op_read(dp); - op_io(); - regs.p.c |= (rd & (1 << bit)) ^ 0; -} -//##IMPL -// case 0x0b: return op_adjust_dp<&SMPcore::op_asl>(); -void SMPcore::op_adjust_dp() { - dp = op_readpc(); - rd = op_readdp(dp); - rd = op_asl(rd); - op_writedp(dp, rd); -} -//##IMPL -// case 0x0c: return op_adjust_addr<&SMPcore::op_asl>(); -void SMPcore::op_adjust_addr() { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - rd = op_asl(rd); - op_write(dp, rd); -} -//##IMPL -// case 0x0d: return op_push(regs.p); -void SMPcore::op_push(uint8 r) { - op_io(); - op_io(); - op_writesp(regs.p); -} -//##IMPL -// case 0x0e: return op_test_addr(1); -void SMPcore::op_test_addr(bool set) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - regs.p.n = (regs.a - rd) & 0x80; - regs.p.z = (regs.a - rd) == 0; - op_read(dp); - op_write(dp, rd | regs.a); -} -//##IMPL -// case 0x0f: return op_brk(); -void SMPcore::op_brk() { - rd.l = op_read(0xffde); - rd.h = op_read(0xffdf); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - op_writesp(regs.p); - regs.pc = rd; - regs.p.b = 1; - regs.p.i = 0; -} -//##IMPL -// case 0x10: return op_branch(regs.p.n == 0); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(regs.p.n != 0) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x11: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x12: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x13: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x14: return op_read_dpi<&SMPcore::op_or>(regs.a, regs.x); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - regs.a = op_or(regs.a, rd); -} -//##IMPL -// case 0x15: return op_read_addri<&SMPcore::op_or>(regs.x); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + regs.x); - regs.a = op_or(regs.a, rd); -} -//##IMPL -// case 0x16: return op_read_addri<&SMPcore::op_or>(regs.y); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + regs.y); - regs.a = op_or(regs.a, rd); -} -//##IMPL -// case 0x17: return op_read_idpy<&SMPcore::op_or>(); -void SMPcore::op_read_idpy() { - dp = op_readpc(); - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp + regs.y); - regs.a = op_or(regs.a, rd); -} -//##IMPL -// case 0x18: return op_write_dp_const<&SMPcore::op_or>(); -void SMPcore::op_write_dp_const() { - rd = op_readpc(); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_or(wr, rd); - op_writedp(dp, wr); -} -//##IMPL -// case 0x19: return op_write_ix_iy<&SMPcore::op_or>(); -void SMPcore::op_write_ix_iy() { - op_io(); - rd = op_readdp(regs.y); - wr = op_readdp(regs.x); - wr = op_or(wr, rd); - op_writedp(regs.x, wr); -} -//##IMPL -// case 0x1a: return op_adjust_dpw(-1); -void SMPcore::op_adjust_dpw(signed n) { - dp = op_readpc(); - rd.w = op_readdp(dp) - 1; - op_writedp(dp++, rd.l); - rd.h += op_readdp(dp); - op_writedp(dp++, rd.h); - regs.p.n = rd & 0x8000; - regs.p.z = rd == 0; -} -//##IMPL -// case 0x1b: return op_adjust_dpx<&SMPcore::op_asl>(); -void SMPcore::op_adjust_dpx() { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - rd = op_asl(rd); - op_writedp(dp + regs.x, rd); -} -//##IMPL -// case 0x1c: return op_adjust<&SMPcore::op_asl>(regs.a); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - regs.a = op_asl(regs.a); -} -//##IMPL -// case 0x1d: return op_adjust<&SMPcore::op_dec>(regs.x); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - regs.x = op_dec(regs.x); -} -//##IMPL -// case 0x1e: return op_read_addr<&SMPcore::op_cmp>(regs.x); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - regs.x = op_cmp(regs.x, rd); -} -//##IMPL -// case 0x1f: return op_jmp_iaddrx(); -void SMPcore::op_jmp_iaddrx() { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - dp += regs.x; - rd.l = op_read(dp++); - rd.h = op_read(dp++); - regs.pc = rd; -} -//##IMPL -// case 0x20: return op_set_flag(regs.p.p, 0); -void SMPcore::op_set_flag(bool &flag, bool data) { - op_io(); - regs.p.p = 0; -} -//##IMPL -// case 0x21: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x22: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x23: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x24: return op_read_dp<&SMPcore::op_and>(regs.a); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - regs.a = op_and(regs.a, rd); -} -//##IMPL -// case 0x25: return op_read_addr<&SMPcore::op_and>(regs.a); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - regs.a = op_and(regs.a, rd); -} -//##IMPL -// case 0x26: return op_read_ix<&SMPcore::op_and>(); -void SMPcore::op_read_ix() { - op_io(); - rd = op_readdp(regs.x); - regs.a = op_and(regs.a, rd); -} -//##IMPL -// case 0x27: return op_read_idpx<&SMPcore::op_and>(); -void SMPcore::op_read_idpx() { - dp = op_readpc() + regs.x; - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp); - regs.a = op_and(regs.a, rd); -} -//##IMPL -// case 0x28: return op_read_const<&SMPcore::op_and>(regs.a); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - regs.a = op_and(regs.a, rd); -} -//##IMPL -// case 0x29: return op_write_dp_dp<&SMPcore::op_and>(); -void SMPcore::op_write_dp_dp() { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_and(wr, rd); - op_writedp(dp, wr); -} -//##IMPL -// case 0x2a: return op_set_addr_bit(); -void SMPcore::op_set_addr_bit() { - dp.l = op_readpc(); - dp.h = op_readpc(); - bit = dp >> 13; - dp &= 0x1fff; - rd = op_read(dp); - op_io(); - regs.p.c |= (rd & (1 << bit)) ^ 1; -} -//##IMPL -// case 0x2b: return op_adjust_dp<&SMPcore::op_rol>(); -void SMPcore::op_adjust_dp() { - dp = op_readpc(); - rd = op_readdp(dp); - rd = op_rol(rd); - op_writedp(dp, rd); -} -//##IMPL -// case 0x2c: return op_adjust_addr<&SMPcore::op_rol>(); -void SMPcore::op_adjust_addr() { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - rd = op_rol(rd); - op_write(dp, rd); -} -//##IMPL -// case 0x2d: return op_push(regs.a); -void SMPcore::op_push(uint8 r) { - op_io(); - op_io(); - op_writesp(regs.a); -} -//##IMPL -// case 0x2e: return op_bne_dp(); -void SMPcore::op_bne_dp() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if(regs.a == sp) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x2f: return op_branch(true); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x30: return op_branch(regs.p.n == 1); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(regs.p.n != 1) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x31: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x32: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x33: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x34: return op_read_dpi<&SMPcore::op_and>(regs.a, regs.x); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - regs.a = op_and(regs.a, rd); -} -//##IMPL -// case 0x35: return op_read_addri<&SMPcore::op_and>(regs.x); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + regs.x); - regs.a = op_and(regs.a, rd); -} -//##IMPL -// case 0x36: return op_read_addri<&SMPcore::op_and>(regs.y); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + regs.y); - regs.a = op_and(regs.a, rd); -} -//##IMPL -// case 0x37: return op_read_idpy<&SMPcore::op_and>(); -void SMPcore::op_read_idpy() { - dp = op_readpc(); - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp + regs.y); - regs.a = op_and(regs.a, rd); -} -//##IMPL -// case 0x38: return op_write_dp_const<&SMPcore::op_and>(); -void SMPcore::op_write_dp_const() { - rd = op_readpc(); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_and(wr, rd); - op_writedp(dp, wr); -} -//##IMPL -// case 0x39: return op_write_ix_iy<&SMPcore::op_and>(); -void SMPcore::op_write_ix_iy() { - op_io(); - rd = op_readdp(regs.y); - wr = op_readdp(regs.x); - wr = op_and(wr, rd); - op_writedp(regs.x, wr); -} -//##IMPL -// case 0x3a: return op_adjust_dpw(+1); -void SMPcore::op_adjust_dpw(signed n) { - dp = op_readpc(); - rd.w = op_readdp(dp) + 1; - op_writedp(dp++, rd.l); - rd.h += op_readdp(dp); - op_writedp(dp++, rd.h); - regs.p.n = rd & 0x8000; - regs.p.z = rd == 0; -} -//##IMPL -// case 0x3b: return op_adjust_dpx<&SMPcore::op_rol>(); -void SMPcore::op_adjust_dpx() { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - rd = op_rol(rd); - op_writedp(dp + regs.x, rd); -} -//##IMPL -// case 0x3c: return op_adjust<&SMPcore::op_rol>(regs.a); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - regs.a = op_rol(regs.a); -} -//##IMPL -// case 0x3d: return op_adjust<&SMPcore::op_inc>(regs.x); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - regs.x = op_inc(regs.x); -} -//##IMPL -// case 0x3e: return op_read_dp<&SMPcore::op_cmp>(regs.x); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - regs.x = op_cmp(regs.x, rd); -} -//##IMPL -// case 0x3f: return op_jsr_addr(); -void SMPcore::op_jsr_addr() { - rd.l = op_readpc(); - rd.h = op_readpc(); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x40: return op_set_flag(regs.p.p, 1); -void SMPcore::op_set_flag(bool &flag, bool data) { - op_io(); - regs.p.p = 1; -} -//##IMPL -// case 0x41: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x42: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x43: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x44: return op_read_dp<&SMPcore::op_eor>(regs.a); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - regs.a = op_eor(regs.a, rd); -} -//##IMPL -// case 0x45: return op_read_addr<&SMPcore::op_eor>(regs.a); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - regs.a = op_eor(regs.a, rd); -} -//##IMPL -// case 0x46: return op_read_ix<&SMPcore::op_eor>(); -void SMPcore::op_read_ix() { - op_io(); - rd = op_readdp(regs.x); - regs.a = op_eor(regs.a, rd); -} -//##IMPL -// case 0x47: return op_read_idpx<&SMPcore::op_eor>(); -void SMPcore::op_read_idpx() { - dp = op_readpc() + regs.x; - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp); - regs.a = op_eor(regs.a, rd); -} -//##IMPL -// case 0x48: return op_read_const<&SMPcore::op_eor>(regs.a); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - regs.a = op_eor(regs.a, rd); -} -//##IMPL -// case 0x49: return op_write_dp_dp<&SMPcore::op_eor>(); -void SMPcore::op_write_dp_dp() { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_eor(wr, rd); - op_writedp(dp, wr); -} -//##IMPL -// case 0x4a: return op_set_addr_bit(); -void SMPcore::op_set_addr_bit() { - dp.l = op_readpc(); - dp.h = op_readpc(); - bit = dp >> 13; - dp &= 0x1fff; - rd = op_read(dp); - regs.p.c &= (rd & (1 << bit)) ^ 0; -} -//##IMPL -// case 0x4b: return op_adjust_dp<&SMPcore::op_lsr>(); -void SMPcore::op_adjust_dp() { - dp = op_readpc(); - rd = op_readdp(dp); - rd = op_lsr(rd); - op_writedp(dp, rd); -} -//##IMPL -// case 0x4c: return op_adjust_addr<&SMPcore::op_lsr>(); -void SMPcore::op_adjust_addr() { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - rd = op_lsr(rd); - op_write(dp, rd); -} -//##IMPL -// case 0x4d: return op_push(regs.x); -void SMPcore::op_push(uint8 r) { - op_io(); - op_io(); - op_writesp(regs.x); -} -//##IMPL -// case 0x4e: return op_test_addr(0); -void SMPcore::op_test_addr(bool set) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - regs.p.n = (regs.a - rd) & 0x80; - regs.p.z = (regs.a - rd) == 0; - op_read(dp); - op_write(dp, rd & ~regs.a); -} -//##IMPL -// case 0x4f: return op_jsp_dp(); -void SMPcore::op_jsp_dp() { - rd = op_readpc(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = 0xff00 | rd; -} -//##IMPL -// case 0x50: return op_branch(regs.p.v == 0); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(regs.p.v != 0) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x51: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x52: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x53: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x54: return op_read_dpi<&SMPcore::op_eor>(regs.a, regs.x); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - regs.a = op_eor(regs.a, rd); -} -//##IMPL -// case 0x55: return op_read_addri<&SMPcore::op_eor>(regs.x); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + regs.x); - regs.a = op_eor(regs.a, rd); -} -//##IMPL -// case 0x56: return op_read_addri<&SMPcore::op_eor>(regs.y); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + regs.y); - regs.a = op_eor(regs.a, rd); -} -//##IMPL -// case 0x57: return op_read_idpy<&SMPcore::op_eor>(); -void SMPcore::op_read_idpy() { - dp = op_readpc(); - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp + regs.y); - regs.a = op_eor(regs.a, rd); -} -//##IMPL -// case 0x58: return op_write_dp_const<&SMPcore::op_eor>(); -void SMPcore::op_write_dp_const() { - rd = op_readpc(); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_eor(wr, rd); - op_writedp(dp, wr); -} -//##IMPL -// case 0x59: return op_write_ix_iy<&SMPcore::op_eor>(); -void SMPcore::op_write_ix_iy() { - op_io(); - rd = op_readdp(regs.y); - wr = op_readdp(regs.x); - wr = op_eor(wr, rd); - op_writedp(regs.x, wr); -} -//##IMPL -// case 0x5a: return op_read_dpw<&SMPcore::op_cpw>(); -void SMPcore::op_read_dpw() { - dp = op_readpc(); - rd.l = op_readdp(dp++); - rd.h = op_readdp(dp++); - regs.ya = op_cpw(regs.ya, rd); -} -//##IMPL -// case 0x5b: return op_adjust_dpx<&SMPcore::op_lsr>(); -void SMPcore::op_adjust_dpx() { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - rd = op_lsr(rd); - op_writedp(dp + regs.x, rd); -} -//##IMPL -// case 0x5c: return op_adjust<&SMPcore::op_lsr>(regs.a); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - regs.a = op_lsr(regs.a); -} -//##IMPL -// case 0x5d: return op_transfer(regs.a, regs.x); -void SMPcore::op_transfer(uint8 &from, uint8 &to) { - op_io(); - regs.x = regs.a; - regs.p.n = (regs.x & 0x80); - regs.p.z = (regs.x == 0); -} -//##IMPL -// case 0x5e: return op_read_addr<&SMPcore::op_cmp>(regs.y); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - regs.y = op_cmp(regs.y, rd); -} -//##IMPL -// case 0x5f: return op_jmp_addr(); -void SMPcore::op_jmp_addr() { - rd.l = op_readpc(); - rd.h = op_readpc(); - regs.pc = rd; -} -//##IMPL -// case 0x60: return op_set_flag(regs.p.c, 0); -void SMPcore::op_set_flag(bool &flag, bool data) { - op_io(); - regs.p.c = 0; -} -//##IMPL -// case 0x61: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x62: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x63: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x64: return op_read_dp<&SMPcore::op_cmp>(regs.a); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - regs.a = op_cmp(regs.a, rd); -} -//##IMPL -// case 0x65: return op_read_addr<&SMPcore::op_cmp>(regs.a); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - regs.a = op_cmp(regs.a, rd); -} -//##IMPL -// case 0x66: return op_read_ix<&SMPcore::op_cmp>(); -void SMPcore::op_read_ix() { - op_io(); - rd = op_readdp(regs.x); - regs.a = op_cmp(regs.a, rd); -} -//##IMPL -// case 0x67: return op_read_idpx<&SMPcore::op_cmp>(); -void SMPcore::op_read_idpx() { - dp = op_readpc() + regs.x; - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp); - regs.a = op_cmp(regs.a, rd); -} -//##IMPL -// case 0x68: return op_read_const<&SMPcore::op_cmp>(regs.a); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - regs.a = op_cmp(regs.a, rd); -} -//##IMPL -// case 0x69: return op_write_dp_dp<&SMPcore::op_cmp>(); -void SMPcore::op_write_dp_dp() { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_cmp(wr, rd); - op_io(); -} -//##IMPL -// case 0x6a: return op_set_addr_bit(); -void SMPcore::op_set_addr_bit() { - dp.l = op_readpc(); - dp.h = op_readpc(); - bit = dp >> 13; - dp &= 0x1fff; - rd = op_read(dp); - regs.p.c &= (rd & (1 << bit)) ^ 1; -} -//##IMPL -// case 0x6b: return op_adjust_dp<&SMPcore::op_ror>(); -void SMPcore::op_adjust_dp() { - dp = op_readpc(); - rd = op_readdp(dp); - rd = op_ror(rd); - op_writedp(dp, rd); -} -//##IMPL -// case 0x6c: return op_adjust_addr<&SMPcore::op_ror>(); -void SMPcore::op_adjust_addr() { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - rd = op_ror(rd); - op_write(dp, rd); -} -//##IMPL -// case 0x6d: return op_push(regs.y); -void SMPcore::op_push(uint8 r) { - op_io(); - op_io(); - op_writesp(regs.y); -} -//##IMPL -// case 0x6e: return op_bne_dpdec(); -void SMPcore::op_bne_dpdec() { - dp = op_readpc(); - wr = op_readdp(dp); - op_writedp(dp, --wr); - rd = op_readpc(); - if(wr == 0) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x6f: return op_rts(); -void SMPcore::op_rts() { - rd.l = op_readsp(); - rd.h = op_readsp(); - op_io(); - op_io(); - regs.pc = rd; -} -//##IMPL -// case 0x70: return op_branch(regs.p.v == 1); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(regs.p.v != 1) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x71: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x72: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x73: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x74: return op_read_dpi<&SMPcore::op_cmp>(regs.a, regs.x); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - regs.a = op_cmp(regs.a, rd); -} -//##IMPL -// case 0x75: return op_read_addri<&SMPcore::op_cmp>(regs.x); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + regs.x); - regs.a = op_cmp(regs.a, rd); -} -//##IMPL -// case 0x76: return op_read_addri<&SMPcore::op_cmp>(regs.y); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + regs.y); - regs.a = op_cmp(regs.a, rd); -} -//##IMPL -// case 0x77: return op_read_idpy<&SMPcore::op_cmp>(); -void SMPcore::op_read_idpy() { - dp = op_readpc(); - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp + regs.y); - regs.a = op_cmp(regs.a, rd); -} -//##IMPL -// case 0x78: return op_write_dp_const<&SMPcore::op_cmp>(); -void SMPcore::op_write_dp_const() { - rd = op_readpc(); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_cmp(wr, rd); - op_io(); -} -//##IMPL -// case 0x79: return op_write_ix_iy<&SMPcore::op_cmp>(); -void SMPcore::op_write_ix_iy() { - op_io(); - rd = op_readdp(regs.y); - wr = op_readdp(regs.x); - wr = op_cmp(wr, rd); - op_io(); -} -//##IMPL -// case 0x7a: return op_read_dpw<&SMPcore::op_adw>(); -void SMPcore::op_read_dpw() { - dp = op_readpc(); - rd.l = op_readdp(dp++); - op_io(); - rd.h = op_readdp(dp++); - regs.ya = op_adw(regs.ya, rd); -} -//##IMPL -// case 0x7b: return op_adjust_dpx<&SMPcore::op_ror>(); -void SMPcore::op_adjust_dpx() { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - rd = op_ror(rd); - op_writedp(dp + regs.x, rd); -} -//##IMPL -// case 0x7c: return op_adjust<&SMPcore::op_ror>(regs.a); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - regs.a = op_ror(regs.a); -} -//##IMPL -// case 0x7d: return op_transfer(regs.x, regs.a); -void SMPcore::op_transfer(uint8 &from, uint8 &to) { - op_io(); - regs.a = regs.x; - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); -} -//##IMPL -// case 0x7e: return op_read_dp<&SMPcore::op_cmp>(regs.y); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - regs.y = op_cmp(regs.y, rd); -} -//##IMPL -// case 0x7f: return op_rti(); -void SMPcore::op_rti() { - regs.p = op_readsp(); - rd.l = op_readsp(); - rd.h = op_readsp(); - op_io(); - op_io(); - regs.pc = rd; -} -//##IMPL -// case 0x80: return op_set_flag(regs.p.c, 1); -void SMPcore::op_set_flag(bool &flag, bool data) { - op_io(); - regs.p.c = 1; -} -//##IMPL -// case 0x81: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x82: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x83: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x84: return op_read_dp<&SMPcore::op_adc>(regs.a); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - regs.a = op_adc(regs.a, rd); -} -//##IMPL -// case 0x85: return op_read_addr<&SMPcore::op_adc>(regs.a); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - regs.a = op_adc(regs.a, rd); -} -//##IMPL -// case 0x86: return op_read_ix<&SMPcore::op_adc>(); -void SMPcore::op_read_ix() { - op_io(); - rd = op_readdp(regs.x); - regs.a = op_adc(regs.a, rd); -} -//##IMPL -// case 0x87: return op_read_idpx<&SMPcore::op_adc>(); -void SMPcore::op_read_idpx() { - dp = op_readpc() + regs.x; - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp); - regs.a = op_adc(regs.a, rd); -} -//##IMPL -// case 0x88: return op_read_const<&SMPcore::op_adc>(regs.a); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - regs.a = op_adc(regs.a, rd); -} -//##IMPL -// case 0x89: return op_write_dp_dp<&SMPcore::op_adc>(); -void SMPcore::op_write_dp_dp() { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_adc(wr, rd); - op_writedp(dp, wr); -} -//##IMPL -// case 0x8a: return op_set_addr_bit(); -void SMPcore::op_set_addr_bit() { - dp.l = op_readpc(); - dp.h = op_readpc(); - bit = dp >> 13; - dp &= 0x1fff; - rd = op_read(dp); - op_io(); - regs.p.c ^= (bool)(rd & (1 << bit)); -} -//##IMPL -// case 0x8b: return op_adjust_dp<&SMPcore::op_dec>(); -void SMPcore::op_adjust_dp() { - dp = op_readpc(); - rd = op_readdp(dp); - rd = op_dec(rd); - op_writedp(dp, rd); -} -//##IMPL -// case 0x8c: return op_adjust_addr<&SMPcore::op_dec>(); -void SMPcore::op_adjust_addr() { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - rd = op_dec(rd); - op_write(dp, rd); -} -//##IMPL -// case 0x8d: return op_read_const<&SMPcore::op_ld>(regs.y); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - regs.y = op_ld(regs.y, rd); -} -//##IMPL -// case 0x8e: return op_plp(); -void SMPcore::op_plp() { - op_io(); - op_io(); - regs.p = op_readsp(); -} -//##IMPL -// case 0x8f: return op_write_dp_const<&SMPcore::op_st>(); -void SMPcore::op_write_dp_const() { - rd = op_readpc(); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_st(wr, rd); - op_writedp(dp, wr); -} -//##IMPL -// case 0x90: return op_branch(regs.p.c == 0); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(regs.p.c != 0) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x91: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x92: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x93: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x94: return op_read_dpi<&SMPcore::op_adc>(regs.a, regs.x); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - regs.a = op_adc(regs.a, rd); -} -//##IMPL -// case 0x95: return op_read_addri<&SMPcore::op_adc>(regs.x); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + regs.x); - regs.a = op_adc(regs.a, rd); -} -//##IMPL -// case 0x96: return op_read_addri<&SMPcore::op_adc>(regs.y); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + regs.y); - regs.a = op_adc(regs.a, rd); -} -//##IMPL -// case 0x97: return op_read_idpy<&SMPcore::op_adc>(); -void SMPcore::op_read_idpy() { - dp = op_readpc(); - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp + regs.y); - regs.a = op_adc(regs.a, rd); -} -//##IMPL -// case 0x98: return op_write_dp_const<&SMPcore::op_adc>(); -void SMPcore::op_write_dp_const() { - rd = op_readpc(); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_adc(wr, rd); - op_writedp(dp, wr); -} -//##IMPL -// case 0x99: return op_write_ix_iy<&SMPcore::op_adc>(); -void SMPcore::op_write_ix_iy() { - op_io(); - rd = op_readdp(regs.y); - wr = op_readdp(regs.x); - wr = op_adc(wr, rd); - op_writedp(regs.x, wr); -} -//##IMPL -// case 0x9a: return op_read_dpw<&SMPcore::op_sbw>(); -void SMPcore::op_read_dpw() { - dp = op_readpc(); - rd.l = op_readdp(dp++); - op_io(); - rd.h = op_readdp(dp++); - regs.ya = op_sbw(regs.ya, rd); -} -//##IMPL -// case 0x9b: return op_adjust_dpx<&SMPcore::op_dec>(); -void SMPcore::op_adjust_dpx() { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - rd = op_dec(rd); - op_writedp(dp + regs.x, rd); -} -//##IMPL -// case 0x9c: return op_adjust<&SMPcore::op_dec>(regs.a); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - regs.a = op_dec(regs.a); -} -//##IMPL -// case 0x9d: return op_transfer(regs.s, regs.x); -void SMPcore::op_transfer(uint8 &from, uint8 &to) { - op_io(); - regs.x = regs.s; - regs.p.n = (regs.x & 0x80); - regs.p.z = (regs.x == 0); -} -//##IMPL -// case 0x9e: return op_div_ya_x(); -void SMPcore::op_div_ya_x() { - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - //[[ - ya = regs.ya; - //overflow set if quotient >= 256 - regs.p.v = (regs.y >= regs.x); - regs.p.h = ((regs.y & 15) >= (regs.x & 15)); - if(regs.y < (regs.x << 1)) { - //if quotient is <= 511 (will fit into 9-bit result) - regs.a = ya / regs.x; - regs.y = ya % regs.x; - } else { - //otherwise, the quotient won't fit into regs.p.v + regs.a - //this emulates the odd behavior of the S-SMP in this case - regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x); - regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x); - } - //result is set based on a (quotient) only - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); - //]] -} -//##IMPL -// case 0x9f: return op_xcn(); -void SMPcore::op_xcn() { - op_io(); - op_io(); - op_io(); - op_io(); - regs.a = (regs.a >> 4) | (regs.a << 4); - regs.p.n = regs.a & 0x80; - regs.p.z = regs.a == 0; -} -//##IMPL -// case 0xa0: return op_set_flag(regs.p.i, 1); -void SMPcore::op_set_flag(bool &flag, bool data) { - op_io(); - op_io(); - regs.p.i = 1; -} -//##IMPL -// case 0xa1: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0xa2: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0xa3: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xa4: return op_read_dp<&SMPcore::op_sbc>(regs.a); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - regs.a = op_sbc(regs.a, rd); -} -//##IMPL -// case 0xa5: return op_read_addr<&SMPcore::op_sbc>(regs.a); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - regs.a = op_sbc(regs.a, rd); -} -//##IMPL -// case 0xa6: return op_read_ix<&SMPcore::op_sbc>(); -void SMPcore::op_read_ix() { - op_io(); - rd = op_readdp(regs.x); - regs.a = op_sbc(regs.a, rd); -} -//##IMPL -// case 0xa7: return op_read_idpx<&SMPcore::op_sbc>(); -void SMPcore::op_read_idpx() { - dp = op_readpc() + regs.x; - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp); - regs.a = op_sbc(regs.a, rd); -} -//##IMPL -// case 0xa8: return op_read_const<&SMPcore::op_sbc>(regs.a); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - regs.a = op_sbc(regs.a, rd); -} -//##IMPL -// case 0xa9: return op_write_dp_dp<&SMPcore::op_sbc>(); -void SMPcore::op_write_dp_dp() { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_sbc(wr, rd); - op_writedp(dp, wr); -} -//##IMPL -// case 0xaa: return op_set_addr_bit(); -void SMPcore::op_set_addr_bit() { - dp.l = op_readpc(); - dp.h = op_readpc(); - bit = dp >> 13; - dp &= 0x1fff; - rd = op_read(dp); - regs.p.c = (rd & (1 << bit)); -} -//##IMPL -// case 0xab: return op_adjust_dp<&SMPcore::op_inc>(); -void SMPcore::op_adjust_dp() { - dp = op_readpc(); - rd = op_readdp(dp); - rd = op_inc(rd); - op_writedp(dp, rd); -} -//##IMPL -// case 0xac: return op_adjust_addr<&SMPcore::op_inc>(); -void SMPcore::op_adjust_addr() { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - rd = op_inc(rd); - op_write(dp, rd); -} -//##IMPL -// case 0xad: return op_read_const<&SMPcore::op_cmp>(regs.y); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - regs.y = op_cmp(regs.y, rd); -} -//##IMPL -// case 0xae: return op_pull(regs.a); -void SMPcore::op_pull(uint8 &r) { - op_io(); - op_io(); - regs.a = op_readsp(); -} -//##IMPL -// case 0xaf: return op_sta_ixinc(); -void SMPcore::op_sta_ixinc() { - op_io(); - op_io(); - op_writedp(regs.x++, regs.a); -} -//##IMPL -// case 0xb0: return op_branch(regs.p.c == 1); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(regs.p.c != 1) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xb1: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0xb2: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0xb3: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xb4: return op_read_dpi<&SMPcore::op_sbc>(regs.a, regs.x); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - regs.a = op_sbc(regs.a, rd); -} -//##IMPL -// case 0xb5: return op_read_addri<&SMPcore::op_sbc>(regs.x); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + regs.x); - regs.a = op_sbc(regs.a, rd); -} -//##IMPL -// case 0xb6: return op_read_addri<&SMPcore::op_sbc>(regs.y); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + regs.y); - regs.a = op_sbc(regs.a, rd); -} -//##IMPL -// case 0xb7: return op_read_idpy<&SMPcore::op_sbc>(); -void SMPcore::op_read_idpy() { - dp = op_readpc(); - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp + regs.y); - regs.a = op_sbc(regs.a, rd); -} -//##IMPL -// case 0xb8: return op_write_dp_const<&SMPcore::op_sbc>(); -void SMPcore::op_write_dp_const() { - rd = op_readpc(); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_sbc(wr, rd); - op_writedp(dp, wr); -} -//##IMPL -// case 0xb9: return op_write_ix_iy<&SMPcore::op_sbc>(); -void SMPcore::op_write_ix_iy() { - op_io(); - rd = op_readdp(regs.y); - wr = op_readdp(regs.x); - wr = op_sbc(wr, rd); - op_writedp(regs.x, wr); -} -//##IMPL -// case 0xba: return op_read_dpw<&SMPcore::op_ldw>(); -void SMPcore::op_read_dpw() { - dp = op_readpc(); - rd.l = op_readdp(dp++); - op_io(); - rd.h = op_readdp(dp++); - regs.ya = op_ldw(regs.ya, rd); -} -//##IMPL -// case 0xbb: return op_adjust_dpx<&SMPcore::op_inc>(); -void SMPcore::op_adjust_dpx() { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - rd = op_inc(rd); - op_writedp(dp + regs.x, rd); -} -//##IMPL -// case 0xbc: return op_adjust<&SMPcore::op_inc>(regs.a); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - regs.a = op_inc(regs.a); -} -//##IMPL -// case 0xbd: return op_transfer(regs.x, regs.s); -void SMPcore::op_transfer(uint8 &from, uint8 &to) { - op_io(); - regs.s = regs.x; -} -//##IMPL -// case 0xbe: return op_das(); -void SMPcore::op_das() { - op_io(); - op_io(); - //[[ - if(!regs.p.c || (regs.a) > 0x99) { - regs.a -= 0x60; - regs.p.c = 0; - } - if(!regs.p.h || (regs.a & 15) > 0x09) { - regs.a -= 0x06; - } - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); - //]] -} -//##IMPL -// case 0xbf: return op_lda_ixinc(); -void SMPcore::op_lda_ixinc() { - op_io(); - regs.a = op_readdp(regs.x++); - op_io(); - regs.p.n = regs.a & 0x80; - regs.p.z = regs.a == 0; -} -//##IMPL -// case 0xc0: return op_set_flag(regs.p.i, 0); -void SMPcore::op_set_flag(bool &flag, bool data) { - op_io(); - op_io(); - regs.p.i = 0; -} -//##IMPL -// case 0xc1: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0xc2: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0xc3: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xc4: return op_write_dp(regs.a); -void SMPcore::op_write_dp(uint8 &r) { - dp = op_readpc(); - op_readdp(dp); - op_writedp(dp, regs.a); -} -//##IMPL -// case 0xc5: return op_write_addr(regs.a); -void SMPcore::op_write_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_read(dp); - op_write(dp, regs.a); -} -//##IMPL -// case 0xc6: return op_sta_ix(); -void SMPcore::op_sta_ix() { - op_io(); - op_readdp(regs.x); - op_writedp(regs.x, regs.a); -} -//##IMPL -// case 0xc7: return op_sta_idpx(); -void SMPcore::op_sta_idpx() { - sp = op_readpc() + regs.x; - op_io(); - dp.l = op_readdp(sp++); - dp.h = op_readdp(sp++); - op_read(dp); - op_write(dp, regs.a); -} -//##IMPL -// case 0xc8: return op_read_const<&SMPcore::op_cmp>(regs.x); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - regs.x = op_cmp(regs.x, rd); -} -//##IMPL -// case 0xc9: return op_write_addr(regs.x); -void SMPcore::op_write_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_read(dp); - op_write(dp, regs.x); -} -//##IMPL -// case 0xca: return op_set_addr_bit(); -void SMPcore::op_set_addr_bit() { - dp.l = op_readpc(); - dp.h = op_readpc(); - bit = dp >> 13; - dp &= 0x1fff; - rd = op_read(dp); - op_io(); - rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - op_write(dp, rd); -} -//##IMPL -// case 0xcb: return op_write_dp(regs.y); -void SMPcore::op_write_dp(uint8 &r) { - dp = op_readpc(); - op_readdp(dp); - op_writedp(dp, regs.y); -} -//##IMPL -// case 0xcc: return op_write_addr(regs.y); -void SMPcore::op_write_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_read(dp); - op_write(dp, regs.y); -} -//##IMPL -// case 0xcd: return op_read_const<&SMPcore::op_ld>(regs.x); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - regs.x = op_ld(regs.x, rd); -} -//##IMPL -// case 0xce: return op_pull(regs.x); -void SMPcore::op_pull(uint8 &r) { - op_io(); - op_io(); - regs.x = op_readsp(); -} -//##IMPL -// case 0xcf: return op_mul_ya(); -void SMPcore::op_mul_ya() { - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - //[[ - ya = regs.y * regs.a; - regs.a = ya; - regs.y = ya >> 8; - //result is set based on y (high-byte) only - regs.p.n = (regs.y & 0x80); - regs.p.z = (regs.y == 0); - //]] -} -//##IMPL -// case 0xd0: return op_branch(regs.p.z == 0); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(regs.p.z != 0) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xd1: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0xd2: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0xd3: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xd4: return op_write_dpi(regs.a, regs.x); -void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { - dp = op_readpc() + regs.x; - op_io(); - op_readdp(dp); - op_writedp(dp, regs.a); -} -//##IMPL -// case 0xd5: return op_write_addri(regs.x); -void SMPcore::op_write_addri(uint8 &i) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - dp += regs.x; - op_read(dp); - op_write(dp, regs.a); -} -//##IMPL -// case 0xd6: return op_write_addri(regs.y); -void SMPcore::op_write_addri(uint8 &i) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - dp += regs.y; - op_read(dp); - op_write(dp, regs.a); -} -//##IMPL -// case 0xd7: return op_sta_idpy(); -void SMPcore::op_sta_idpy() { - sp = op_readpc(); - dp.l = op_readdp(sp++); - dp.h = op_readdp(sp++); - op_io(); - dp += regs.y; - op_read(dp); - op_write(dp, regs.a); -} -//##IMPL -// case 0xd8: return op_write_dp(regs.x); -void SMPcore::op_write_dp(uint8 &r) { - dp = op_readpc(); - op_readdp(dp); - op_writedp(dp, regs.x); -} -//##IMPL -// case 0xd9: return op_write_dpi(regs.x, regs.y); -void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { - dp = op_readpc() + regs.y; - op_io(); - op_readdp(dp); - op_writedp(dp, regs.x); -} -//##IMPL -// case 0xda: return op_stw_dp(); -void SMPcore::op_stw_dp() { - dp = op_readpc(); - op_readdp(dp); - op_writedp(dp++, regs.a); - op_writedp(dp++, regs.y); -} -//##IMPL -// case 0xdb: return op_write_dpi(regs.y, regs.x); -void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { - dp = op_readpc() + regs.x; - op_io(); - op_readdp(dp); - op_writedp(dp, regs.y); -} -//##IMPL -// case 0xdc: return op_adjust<&SMPcore::op_dec>(regs.y); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - regs.y = op_dec(regs.y); -} -//##IMPL -// case 0xdd: return op_transfer(regs.y, regs.a); -void SMPcore::op_transfer(uint8 &from, uint8 &to) { - op_io(); - regs.a = regs.y; - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); -} -//##IMPL -// case 0xde: return op_bne_dpx(); -void SMPcore::op_bne_dpx() { - dp = op_readpc(); - op_io(); - sp = op_readdp(dp + regs.x); - rd = op_readpc(); - op_io(); - if(regs.a == sp) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xdf: return op_daa(); -void SMPcore::op_daa() { - op_io(); - op_io(); - //[[ - if(regs.p.c || (regs.a) > 0x99) { - regs.a += 0x60; - regs.p.c = 1; - } - if(regs.p.h || (regs.a & 15) > 0x09) { - regs.a += 0x06; - } - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); - //]] -} -//##IMPL -// case 0xe0: return op_clv(); -void SMPcore::op_clv() { - op_io(); - regs.p.v = 0; - regs.p.h = 0; -} -//##IMPL -// case 0xe1: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0xe2: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0xe3: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xe4: return op_read_dp<&SMPcore::op_ld>(regs.a); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - regs.a = op_ld(regs.a, rd); -} -//##IMPL -// case 0xe5: return op_read_addr<&SMPcore::op_ld>(regs.a); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - regs.a = op_ld(regs.a, rd); -} -//##IMPL -// case 0xe6: return op_read_ix<&SMPcore::op_ld>(); -void SMPcore::op_read_ix() { - op_io(); - rd = op_readdp(regs.x); - regs.a = op_ld(regs.a, rd); -} -//##IMPL -// case 0xe7: return op_read_idpx<&SMPcore::op_ld>(); -void SMPcore::op_read_idpx() { - dp = op_readpc() + regs.x; - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp); - regs.a = op_ld(regs.a, rd); -} -//##IMPL -// case 0xe8: return op_read_const<&SMPcore::op_ld>(regs.a); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - regs.a = op_ld(regs.a, rd); -} -//##IMPL -// case 0xe9: return op_read_addr<&SMPcore::op_ld>(regs.x); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - regs.x = op_ld(regs.x, rd); -} -//##IMPL -// case 0xea: return op_set_addr_bit(); -void SMPcore::op_set_addr_bit() { - dp.l = op_readpc(); - dp.h = op_readpc(); - bit = dp >> 13; - dp &= 0x1fff; - rd = op_read(dp); - rd ^= 1 << bit; - op_write(dp, rd); -} -//##IMPL -// case 0xeb: return op_read_dp<&SMPcore::op_ld>(regs.y); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - regs.y = op_ld(regs.y, rd); -} -//##IMPL -// case 0xec: return op_read_addr<&SMPcore::op_ld>(regs.y); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - regs.y = op_ld(regs.y, rd); -} -//##IMPL -// case 0xed: return op_cmc(); -void SMPcore::op_cmc() { - op_io(); - op_io(); - regs.p.c = !regs.p.c; -} -//##IMPL -// case 0xee: return op_pull(regs.y); -void SMPcore::op_pull(uint8 &r) { - op_io(); - op_io(); - regs.y = op_readsp(); -} -//##IMPL -// case 0xef: return op_wait(); -void SMPcore::op_wait() { - op_io(); - op_io(); - //!!REPEAT -} -//##IMPL -// case 0xf0: return op_branch(regs.p.z == 1); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(regs.p.z != 1) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xf1: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0xf2: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0xf3: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xf4: return op_read_dpi<&SMPcore::op_ld>(regs.a, regs.x); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - regs.a = op_ld(regs.a, rd); -} -//##IMPL -// case 0xf5: return op_read_addri<&SMPcore::op_ld>(regs.x); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + regs.x); - regs.a = op_ld(regs.a, rd); -} -//##IMPL -// case 0xf6: return op_read_addri<&SMPcore::op_ld>(regs.y); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + regs.y); - regs.a = op_ld(regs.a, rd); -} -//##IMPL -// case 0xf7: return op_read_idpy<&SMPcore::op_ld>(); -void SMPcore::op_read_idpy() { - dp = op_readpc(); - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp + regs.y); - regs.a = op_ld(regs.a, rd); -} -//##IMPL -// case 0xf8: return op_read_dp<&SMPcore::op_ld>(regs.x); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - regs.x = op_ld(regs.x, rd); -} -//##IMPL -// case 0xf9: return op_read_dpi<&SMPcore::op_ld>(regs.x, regs.y); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.y); - regs.x = op_ld(regs.x, rd); -} -//##IMPL -// case 0xfa: return op_write_dp_dp<&SMPcore::op_st>(); -void SMPcore::op_write_dp_dp() { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - wr = op_st(wr, rd); - op_writedp(dp, wr); -} -//##IMPL -// case 0xfb: return op_read_dpi<&SMPcore::op_ld>(regs.y, regs.x); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - regs.y = op_ld(regs.y, rd); -} -//##IMPL -// case 0xfc: return op_adjust<&SMPcore::op_inc>(regs.y); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - regs.y = op_inc(regs.y); -} -//##IMPL -// case 0xfd: return op_transfer(regs.a, regs.y); -void SMPcore::op_transfer(uint8 &from, uint8 &to) { - op_io(); - regs.y = regs.a; - regs.p.n = (regs.y & 0x80); - regs.p.z = (regs.y == 0); -} -//##IMPL -// case 0xfe: return op_bne_ydec(); -void SMPcore::op_bne_ydec() { - rd = op_readpc(); - op_io(); - op_io(); - if(--regs.y == 0) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xff: return op_wait(); -void SMPcore::op_wait() { - op_io(); - op_io(); - //!!REPEAT -} diff --git a/libsnes/s_cpu_coregen/Generex/bin/Debug/out.cpp b/libsnes/s_cpu_coregen/Generex/bin/Debug/out.cpp deleted file mode 100644 index bda6a47603..0000000000 --- a/libsnes/s_cpu_coregen/Generex/bin/Debug/out.cpp +++ /dev/null @@ -1,2530 +0,0 @@ -//##IMPL -// case 0x00: return op_nop(); -void SMPcore::op_nop() { - op_io(); -} -//##IMPL -// case 0x01: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x02: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x03: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x04: return op_read_dp<&SMPcore::op_or>(regs.a); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - r = op_or(r, rd); -} -//##IMPL -// case 0x05: return op_read_addr<&SMPcore::op_or>(regs.a); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - r = op_or(r, rd); -} -//##IMPL -// case 0x06: return op_read_ix<&SMPcore::op_or>(); -void SMPcore::op_read_ix() { - op_io(); - rd = op_readdp(regs.x); - regs.a = op_or(regs.a, rd); -} -//##IMPL -// case 0x07: return op_read_idpx<&SMPcore::op_or>(); -void SMPcore::op_read_idpx() { - dp = op_readpc() + regs.x; - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp); - regs.a = op_or(regs.a, rd); -} -//##IMPL -// case 0x08: return op_read_const<&SMPcore::op_or>(regs.a); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - r = op_or(r, rd); -} -//##IMPL -// case 0x09: return op_write_dp_dp<&SMPcore::op_or>(); -void SMPcore::op_write_dp_dp() { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - if(op != &SMPcore::op_st) wr = op_readdp(dp); - wr = op_or(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(dp, wr) : op_io(); -} -//##IMPL -// case 0x0a: return op_set_addr_bit(); -void SMPcore::op_set_addr_bit() { - dp.l = op_readpc(); - dp.h = op_readpc(); - bit = dp >> 13; - dp &= 0x1fff; - rd = op_read(dp); - switch(opcode >> 5) { - case 0: //orc addr:bit - case 1: //orc !addr:bit - op_io(); - regs.p.c |= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); - break; - case 2: //and addr:bit - case 3: //and !addr:bit - regs.p.c &= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); - break; - case 4: //eor addr:bit - op_io(); - regs.p.c ^= (bool)(rd & (1 << bit)); - break; - case 5: //ldc addr:bit - regs.p.c = (rd & (1 << bit)); - break; - case 6: //stc addr:bit - op_io(); - rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - op_write(dp, rd); - break; - case 7: //not addr:bit - rd ^= 1 << bit; - op_write(dp, rd); - break; - } -} -//##IMPL -// case 0x0b: return op_adjust_dp<&SMPcore::op_asl>(); -void SMPcore::op_adjust_dp() { - dp = op_readpc(); - rd = op_readdp(dp); - rd = op_asl(rd); - op_writedp(dp, rd); -} -//##IMPL -// case 0x0c: return op_adjust_addr<&SMPcore::op_asl>(); -void SMPcore::op_adjust_addr() { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - rd = op_asl(rd); - op_write(dp, rd); -} -//##IMPL -// case 0x0d: return op_push(regs.p); -void SMPcore::op_push(uint8 r) { - op_io(); - op_io(); - op_writesp(r); -} -//##IMPL -// case 0x0e: return op_test_addr(1); -void SMPcore::op_test_addr(bool set) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - regs.p.n = (regs.a - rd) & 0x80; - regs.p.z = (regs.a - rd) == 0; - op_read(dp); - op_write(dp, set ? rd | regs.a : rd & ~regs.a); -} -//##IMPL -// case 0x0f: return op_brk(); -void SMPcore::op_brk() { - rd.l = op_read(0xffde); - rd.h = op_read(0xffdf); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - op_writesp(regs.p); - regs.pc = rd; - regs.p.b = 1; - regs.p.i = 0; -} -//##IMPL -// case 0x10: return op_branch(regs.p.n == 0); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(condition == false) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x11: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x12: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x13: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x14: return op_read_dpi<&SMPcore::op_or>(regs.a, regs.x); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + i); - r = op_or(r, rd); -} -//##IMPL -// case 0x15: return op_read_addri<&SMPcore::op_or>(regs.x); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + r); - regs.a = op_or(regs.a, rd); -} -//##IMPL -// case 0x16: return op_read_addri<&SMPcore::op_or>(regs.y); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + r); - regs.a = op_or(regs.a, rd); -} -//##IMPL -// case 0x17: return op_read_idpy<&SMPcore::op_or>(); -void SMPcore::op_read_idpy() { - dp = op_readpc(); - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp + regs.y); - regs.a = op_or(regs.a, rd); -} -//##IMPL -// case 0x18: return op_write_dp_const<&SMPcore::op_or>(); -void SMPcore::op_write_dp_const() { - rd = op_readpc(); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_or(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(dp, wr) : op_io(); -} -//##IMPL -// case 0x19: return op_write_ix_iy<&SMPcore::op_or>(); -void SMPcore::op_write_ix_iy() { - op_io(); - rd = op_readdp(regs.y); - wr = op_readdp(regs.x); - wr = op_or(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(regs.x, wr) : op_io(); -} -//##IMPL -// case 0x1a: return op_adjust_dpw(-1); -void SMPcore::op_adjust_dpw(signed n) { - dp = op_readpc(); - rd.w = op_readdp(dp) + n; - op_writedp(dp++, rd.l); - rd.h += op_readdp(dp); - op_writedp(dp++, rd.h); - regs.p.n = rd & 0x8000; - regs.p.z = rd == 0; -} -//##IMPL -// case 0x1b: return op_adjust_dpx<&SMPcore::op_asl>(); -void SMPcore::op_adjust_dpx() { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - rd = op_asl(rd); - op_writedp(dp + regs.x, rd); -} -//##IMPL -// case 0x1c: return op_adjust<&SMPcore::op_asl>(regs.a); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - r = op_asl(r); -} -//##IMPL -// case 0x1d: return op_adjust<&SMPcore::op_dec>(regs.x); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - r = op_dec(r); -} -//##IMPL -// case 0x1e: return op_read_addr<&SMPcore::op_cmp>(regs.x); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - r = op_cmp(r, rd); -} -//##IMPL -// case 0x1f: return op_jmp_iaddrx(); -void SMPcore::op_jmp_iaddrx() { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - dp += regs.x; - rd.l = op_read(dp++); - rd.h = op_read(dp++); - regs.pc = rd; -} -//##IMPL -// case 0x20: return op_set_flag(regs.p.p, 0); -void SMPcore::op_set_flag(bool &flag, bool data) { - op_io(); - if(&flag == ®s.p.i) op_io(); - flag = data; -} -//##IMPL -// case 0x21: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x22: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x23: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x24: return op_read_dp<&SMPcore::op_and>(regs.a); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - r = op_and(r, rd); -} -//##IMPL -// case 0x25: return op_read_addr<&SMPcore::op_and>(regs.a); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - r = op_and(r, rd); -} -//##IMPL -// case 0x26: return op_read_ix<&SMPcore::op_and>(); -void SMPcore::op_read_ix() { - op_io(); - rd = op_readdp(regs.x); - regs.a = op_and(regs.a, rd); -} -//##IMPL -// case 0x27: return op_read_idpx<&SMPcore::op_and>(); -void SMPcore::op_read_idpx() { - dp = op_readpc() + regs.x; - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp); - regs.a = op_and(regs.a, rd); -} -//##IMPL -// case 0x28: return op_read_const<&SMPcore::op_and>(regs.a); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - r = op_and(r, rd); -} -//##IMPL -// case 0x29: return op_write_dp_dp<&SMPcore::op_and>(); -void SMPcore::op_write_dp_dp() { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - if(op != &SMPcore::op_st) wr = op_readdp(dp); - wr = op_and(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(dp, wr) : op_io(); -} -//##IMPL -// case 0x2a: return op_set_addr_bit(); -void SMPcore::op_set_addr_bit() { - dp.l = op_readpc(); - dp.h = op_readpc(); - bit = dp >> 13; - dp &= 0x1fff; - rd = op_read(dp); - switch(opcode >> 5) { - case 0: //orc addr:bit - case 1: //orc !addr:bit - op_io(); - regs.p.c |= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); - break; - case 2: //and addr:bit - case 3: //and !addr:bit - regs.p.c &= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); - break; - case 4: //eor addr:bit - op_io(); - regs.p.c ^= (bool)(rd & (1 << bit)); - break; - case 5: //ldc addr:bit - regs.p.c = (rd & (1 << bit)); - break; - case 6: //stc addr:bit - op_io(); - rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - op_write(dp, rd); - break; - case 7: //not addr:bit - rd ^= 1 << bit; - op_write(dp, rd); - break; - } -} -//##IMPL -// case 0x2b: return op_adjust_dp<&SMPcore::op_rol>(); -void SMPcore::op_adjust_dp() { - dp = op_readpc(); - rd = op_readdp(dp); - rd = op_rol(rd); - op_writedp(dp, rd); -} -//##IMPL -// case 0x2c: return op_adjust_addr<&SMPcore::op_rol>(); -void SMPcore::op_adjust_addr() { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - rd = op_rol(rd); - op_write(dp, rd); -} -//##IMPL -// case 0x2d: return op_push(regs.a); -void SMPcore::op_push(uint8 r) { - op_io(); - op_io(); - op_writesp(r); -} -//##IMPL -// case 0x2e: return op_bne_dp(); -void SMPcore::op_bne_dp() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if(regs.a == sp) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x2f: return op_branch(true); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(condition == false) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x30: return op_branch(regs.p.n == 1); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(condition == false) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x31: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x32: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x33: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x34: return op_read_dpi<&SMPcore::op_and>(regs.a, regs.x); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + i); - r = op_and(r, rd); -} -//##IMPL -// case 0x35: return op_read_addri<&SMPcore::op_and>(regs.x); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + r); - regs.a = op_and(regs.a, rd); -} -//##IMPL -// case 0x36: return op_read_addri<&SMPcore::op_and>(regs.y); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + r); - regs.a = op_and(regs.a, rd); -} -//##IMPL -// case 0x37: return op_read_idpy<&SMPcore::op_and>(); -void SMPcore::op_read_idpy() { - dp = op_readpc(); - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp + regs.y); - regs.a = op_and(regs.a, rd); -} -//##IMPL -// case 0x38: return op_write_dp_const<&SMPcore::op_and>(); -void SMPcore::op_write_dp_const() { - rd = op_readpc(); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_and(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(dp, wr) : op_io(); -} -//##IMPL -// case 0x39: return op_write_ix_iy<&SMPcore::op_and>(); -void SMPcore::op_write_ix_iy() { - op_io(); - rd = op_readdp(regs.y); - wr = op_readdp(regs.x); - wr = op_and(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(regs.x, wr) : op_io(); -} -//##IMPL -// case 0x3a: return op_adjust_dpw(+1); -void SMPcore::op_adjust_dpw(signed n) { - dp = op_readpc(); - rd.w = op_readdp(dp) + n; - op_writedp(dp++, rd.l); - rd.h += op_readdp(dp); - op_writedp(dp++, rd.h); - regs.p.n = rd & 0x8000; - regs.p.z = rd == 0; -} -//##IMPL -// case 0x3b: return op_adjust_dpx<&SMPcore::op_rol>(); -void SMPcore::op_adjust_dpx() { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - rd = op_rol(rd); - op_writedp(dp + regs.x, rd); -} -//##IMPL -// case 0x3c: return op_adjust<&SMPcore::op_rol>(regs.a); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - r = op_rol(r); -} -//##IMPL -// case 0x3d: return op_adjust<&SMPcore::op_inc>(regs.x); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - r = op_inc(r); -} -//##IMPL -// case 0x3e: return op_read_dp<&SMPcore::op_cmp>(regs.x); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - r = op_cmp(r, rd); -} -//##IMPL -// case 0x3f: return op_jsr_addr(); -void SMPcore::op_jsr_addr() { - rd.l = op_readpc(); - rd.h = op_readpc(); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x40: return op_set_flag(regs.p.p, 1); -void SMPcore::op_set_flag(bool &flag, bool data) { - op_io(); - if(&flag == ®s.p.i) op_io(); - flag = data; -} -//##IMPL -// case 0x41: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x42: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x43: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x44: return op_read_dp<&SMPcore::op_eor>(regs.a); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - r = op_eor(r, rd); -} -//##IMPL -// case 0x45: return op_read_addr<&SMPcore::op_eor>(regs.a); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - r = op_eor(r, rd); -} -//##IMPL -// case 0x46: return op_read_ix<&SMPcore::op_eor>(); -void SMPcore::op_read_ix() { - op_io(); - rd = op_readdp(regs.x); - regs.a = op_eor(regs.a, rd); -} -//##IMPL -// case 0x47: return op_read_idpx<&SMPcore::op_eor>(); -void SMPcore::op_read_idpx() { - dp = op_readpc() + regs.x; - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp); - regs.a = op_eor(regs.a, rd); -} -//##IMPL -// case 0x48: return op_read_const<&SMPcore::op_eor>(regs.a); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - r = op_eor(r, rd); -} -//##IMPL -// case 0x49: return op_write_dp_dp<&SMPcore::op_eor>(); -void SMPcore::op_write_dp_dp() { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - if(op != &SMPcore::op_st) wr = op_readdp(dp); - wr = op_eor(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(dp, wr) : op_io(); -} -//##IMPL -// case 0x4a: return op_set_addr_bit(); -void SMPcore::op_set_addr_bit() { - dp.l = op_readpc(); - dp.h = op_readpc(); - bit = dp >> 13; - dp &= 0x1fff; - rd = op_read(dp); - switch(opcode >> 5) { - case 0: //orc addr:bit - case 1: //orc !addr:bit - op_io(); - regs.p.c |= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); - break; - case 2: //and addr:bit - case 3: //and !addr:bit - regs.p.c &= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); - break; - case 4: //eor addr:bit - op_io(); - regs.p.c ^= (bool)(rd & (1 << bit)); - break; - case 5: //ldc addr:bit - regs.p.c = (rd & (1 << bit)); - break; - case 6: //stc addr:bit - op_io(); - rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - op_write(dp, rd); - break; - case 7: //not addr:bit - rd ^= 1 << bit; - op_write(dp, rd); - break; - } -} -//##IMPL -// case 0x4b: return op_adjust_dp<&SMPcore::op_lsr>(); -void SMPcore::op_adjust_dp() { - dp = op_readpc(); - rd = op_readdp(dp); - rd = op_lsr(rd); - op_writedp(dp, rd); -} -//##IMPL -// case 0x4c: return op_adjust_addr<&SMPcore::op_lsr>(); -void SMPcore::op_adjust_addr() { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - rd = op_lsr(rd); - op_write(dp, rd); -} -//##IMPL -// case 0x4d: return op_push(regs.x); -void SMPcore::op_push(uint8 r) { - op_io(); - op_io(); - op_writesp(r); -} -//##IMPL -// case 0x4e: return op_test_addr(0); -void SMPcore::op_test_addr(bool set) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - regs.p.n = (regs.a - rd) & 0x80; - regs.p.z = (regs.a - rd) == 0; - op_read(dp); - op_write(dp, set ? rd | regs.a : rd & ~regs.a); -} -//##IMPL -// case 0x4f: return op_jsp_dp(); -void SMPcore::op_jsp_dp() { - rd = op_readpc(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = 0xff00 | rd; -} -//##IMPL -// case 0x50: return op_branch(regs.p.v == 0); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(condition == false) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x51: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x52: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x53: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x54: return op_read_dpi<&SMPcore::op_eor>(regs.a, regs.x); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + i); - r = op_eor(r, rd); -} -//##IMPL -// case 0x55: return op_read_addri<&SMPcore::op_eor>(regs.x); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + r); - regs.a = op_eor(regs.a, rd); -} -//##IMPL -// case 0x56: return op_read_addri<&SMPcore::op_eor>(regs.y); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + r); - regs.a = op_eor(regs.a, rd); -} -//##IMPL -// case 0x57: return op_read_idpy<&SMPcore::op_eor>(); -void SMPcore::op_read_idpy() { - dp = op_readpc(); - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp + regs.y); - regs.a = op_eor(regs.a, rd); -} -//##IMPL -// case 0x58: return op_write_dp_const<&SMPcore::op_eor>(); -void SMPcore::op_write_dp_const() { - rd = op_readpc(); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_eor(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(dp, wr) : op_io(); -} -//##IMPL -// case 0x59: return op_write_ix_iy<&SMPcore::op_eor>(); -void SMPcore::op_write_ix_iy() { - op_io(); - rd = op_readdp(regs.y); - wr = op_readdp(regs.x); - wr = op_eor(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(regs.x, wr) : op_io(); -} -//##IMPL -// case 0x5a: return op_read_dpw<&SMPcore::op_cpw>(); -void SMPcore::op_read_dpw() { - dp = op_readpc(); - rd.l = op_readdp(dp++); - if(op != &SMPcore::op_cpw) op_io(); - rd.h = op_readdp(dp++); - regs.ya = op_cpw(regs.ya, rd); -} -//##IMPL -// case 0x5b: return op_adjust_dpx<&SMPcore::op_lsr>(); -void SMPcore::op_adjust_dpx() { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - rd = op_lsr(rd); - op_writedp(dp + regs.x, rd); -} -//##IMPL -// case 0x5c: return op_adjust<&SMPcore::op_lsr>(regs.a); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - r = op_lsr(r); -} -//##IMPL -// case 0x5d: return op_transfer(regs.a, regs.x); -void SMPcore::op_transfer(uint8 &from, uint8 &to) { - op_io(); - to = from; - if(&to == ®s.s) return; - regs.p.n = (to & 0x80); - regs.p.z = (to == 0); -} -//##IMPL -// case 0x5e: return op_read_addr<&SMPcore::op_cmp>(regs.y); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - r = op_cmp(r, rd); -} -//##IMPL -// case 0x5f: return op_jmp_addr(); -void SMPcore::op_jmp_addr() { - rd.l = op_readpc(); - rd.h = op_readpc(); - regs.pc = rd; -} -//##IMPL -// case 0x60: return op_set_flag(regs.p.c, 0); -void SMPcore::op_set_flag(bool &flag, bool data) { - op_io(); - if(&flag == ®s.p.i) op_io(); - flag = data; -} -//##IMPL -// case 0x61: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x62: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x63: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x64: return op_read_dp<&SMPcore::op_cmp>(regs.a); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - r = op_cmp(r, rd); -} -//##IMPL -// case 0x65: return op_read_addr<&SMPcore::op_cmp>(regs.a); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - r = op_cmp(r, rd); -} -//##IMPL -// case 0x66: return op_read_ix<&SMPcore::op_cmp>(); -void SMPcore::op_read_ix() { - op_io(); - rd = op_readdp(regs.x); - regs.a = op_cmp(regs.a, rd); -} -//##IMPL -// case 0x67: return op_read_idpx<&SMPcore::op_cmp>(); -void SMPcore::op_read_idpx() { - dp = op_readpc() + regs.x; - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp); - regs.a = op_cmp(regs.a, rd); -} -//##IMPL -// case 0x68: return op_read_const<&SMPcore::op_cmp>(regs.a); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - r = op_cmp(r, rd); -} -//##IMPL -// case 0x69: return op_write_dp_dp<&SMPcore::op_cmp>(); -void SMPcore::op_write_dp_dp() { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - if(op != &SMPcore::op_st) wr = op_readdp(dp); - wr = op_cmp(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(dp, wr) : op_io(); -} -//##IMPL -// case 0x6a: return op_set_addr_bit(); -void SMPcore::op_set_addr_bit() { - dp.l = op_readpc(); - dp.h = op_readpc(); - bit = dp >> 13; - dp &= 0x1fff; - rd = op_read(dp); - switch(opcode >> 5) { - case 0: //orc addr:bit - case 1: //orc !addr:bit - op_io(); - regs.p.c |= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); - break; - case 2: //and addr:bit - case 3: //and !addr:bit - regs.p.c &= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); - break; - case 4: //eor addr:bit - op_io(); - regs.p.c ^= (bool)(rd & (1 << bit)); - break; - case 5: //ldc addr:bit - regs.p.c = (rd & (1 << bit)); - break; - case 6: //stc addr:bit - op_io(); - rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - op_write(dp, rd); - break; - case 7: //not addr:bit - rd ^= 1 << bit; - op_write(dp, rd); - break; - } -} -//##IMPL -// case 0x6b: return op_adjust_dp<&SMPcore::op_ror>(); -void SMPcore::op_adjust_dp() { - dp = op_readpc(); - rd = op_readdp(dp); - rd = op_ror(rd); - op_writedp(dp, rd); -} -//##IMPL -// case 0x6c: return op_adjust_addr<&SMPcore::op_ror>(); -void SMPcore::op_adjust_addr() { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - rd = op_ror(rd); - op_write(dp, rd); -} -//##IMPL -// case 0x6d: return op_push(regs.y); -void SMPcore::op_push(uint8 r) { - op_io(); - op_io(); - op_writesp(r); -} -//##IMPL -// case 0x6e: return op_bne_dpdec(); -void SMPcore::op_bne_dpdec() { - dp = op_readpc(); - wr = op_readdp(dp); - op_writedp(dp, --wr); - rd = op_readpc(); - if(wr == 0) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x6f: return op_rts(); -void SMPcore::op_rts() { - rd.l = op_readsp(); - rd.h = op_readsp(); - op_io(); - op_io(); - regs.pc = rd; -} -//##IMPL -// case 0x70: return op_branch(regs.p.v == 1); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(condition == false) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x71: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x72: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x73: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x74: return op_read_dpi<&SMPcore::op_cmp>(regs.a, regs.x); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + i); - r = op_cmp(r, rd); -} -//##IMPL -// case 0x75: return op_read_addri<&SMPcore::op_cmp>(regs.x); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + r); - regs.a = op_cmp(regs.a, rd); -} -//##IMPL -// case 0x76: return op_read_addri<&SMPcore::op_cmp>(regs.y); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + r); - regs.a = op_cmp(regs.a, rd); -} -//##IMPL -// case 0x77: return op_read_idpy<&SMPcore::op_cmp>(); -void SMPcore::op_read_idpy() { - dp = op_readpc(); - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp + regs.y); - regs.a = op_cmp(regs.a, rd); -} -//##IMPL -// case 0x78: return op_write_dp_const<&SMPcore::op_cmp>(); -void SMPcore::op_write_dp_const() { - rd = op_readpc(); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_cmp(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(dp, wr) : op_io(); -} -//##IMPL -// case 0x79: return op_write_ix_iy<&SMPcore::op_cmp>(); -void SMPcore::op_write_ix_iy() { - op_io(); - rd = op_readdp(regs.y); - wr = op_readdp(regs.x); - wr = op_cmp(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(regs.x, wr) : op_io(); -} -//##IMPL -// case 0x7a: return op_read_dpw<&SMPcore::op_adw>(); -void SMPcore::op_read_dpw() { - dp = op_readpc(); - rd.l = op_readdp(dp++); - if(op != &SMPcore::op_cpw) op_io(); - rd.h = op_readdp(dp++); - regs.ya = op_adw(regs.ya, rd); -} -//##IMPL -// case 0x7b: return op_adjust_dpx<&SMPcore::op_ror>(); -void SMPcore::op_adjust_dpx() { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - rd = op_ror(rd); - op_writedp(dp + regs.x, rd); -} -//##IMPL -// case 0x7c: return op_adjust<&SMPcore::op_ror>(regs.a); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - r = op_ror(r); -} -//##IMPL -// case 0x7d: return op_transfer(regs.x, regs.a); -void SMPcore::op_transfer(uint8 &from, uint8 &to) { - op_io(); - to = from; - if(&to == ®s.s) return; - regs.p.n = (to & 0x80); - regs.p.z = (to == 0); -} -//##IMPL -// case 0x7e: return op_read_dp<&SMPcore::op_cmp>(regs.y); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - r = op_cmp(r, rd); -} -//##IMPL -// case 0x7f: return op_rti(); -void SMPcore::op_rti() { - regs.p = op_readsp(); - rd.l = op_readsp(); - rd.h = op_readsp(); - op_io(); - op_io(); - regs.pc = rd; -} -//##IMPL -// case 0x80: return op_set_flag(regs.p.c, 1); -void SMPcore::op_set_flag(bool &flag, bool data) { - op_io(); - if(&flag == ®s.p.i) op_io(); - flag = data; -} -//##IMPL -// case 0x81: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x82: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x83: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x84: return op_read_dp<&SMPcore::op_adc>(regs.a); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - r = op_adc(r, rd); -} -//##IMPL -// case 0x85: return op_read_addr<&SMPcore::op_adc>(regs.a); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - r = op_adc(r, rd); -} -//##IMPL -// case 0x86: return op_read_ix<&SMPcore::op_adc>(); -void SMPcore::op_read_ix() { - op_io(); - rd = op_readdp(regs.x); - regs.a = op_adc(regs.a, rd); -} -//##IMPL -// case 0x87: return op_read_idpx<&SMPcore::op_adc>(); -void SMPcore::op_read_idpx() { - dp = op_readpc() + regs.x; - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp); - regs.a = op_adc(regs.a, rd); -} -//##IMPL -// case 0x88: return op_read_const<&SMPcore::op_adc>(regs.a); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - r = op_adc(r, rd); -} -//##IMPL -// case 0x89: return op_write_dp_dp<&SMPcore::op_adc>(); -void SMPcore::op_write_dp_dp() { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - if(op != &SMPcore::op_st) wr = op_readdp(dp); - wr = op_adc(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(dp, wr) : op_io(); -} -//##IMPL -// case 0x8a: return op_set_addr_bit(); -void SMPcore::op_set_addr_bit() { - dp.l = op_readpc(); - dp.h = op_readpc(); - bit = dp >> 13; - dp &= 0x1fff; - rd = op_read(dp); - switch(opcode >> 5) { - case 0: //orc addr:bit - case 1: //orc !addr:bit - op_io(); - regs.p.c |= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); - break; - case 2: //and addr:bit - case 3: //and !addr:bit - regs.p.c &= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); - break; - case 4: //eor addr:bit - op_io(); - regs.p.c ^= (bool)(rd & (1 << bit)); - break; - case 5: //ldc addr:bit - regs.p.c = (rd & (1 << bit)); - break; - case 6: //stc addr:bit - op_io(); - rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - op_write(dp, rd); - break; - case 7: //not addr:bit - rd ^= 1 << bit; - op_write(dp, rd); - break; - } -} -//##IMPL -// case 0x8b: return op_adjust_dp<&SMPcore::op_dec>(); -void SMPcore::op_adjust_dp() { - dp = op_readpc(); - rd = op_readdp(dp); - rd = op_dec(rd); - op_writedp(dp, rd); -} -//##IMPL -// case 0x8c: return op_adjust_addr<&SMPcore::op_dec>(); -void SMPcore::op_adjust_addr() { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - rd = op_dec(rd); - op_write(dp, rd); -} -//##IMPL -// case 0x8d: return op_read_const<&SMPcore::op_ld>(regs.y); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - r = op_ld(r, rd); -} -//##IMPL -// case 0x8e: return op_plp(); -void SMPcore::op_plp() { - op_io(); - op_io(); - regs.p = op_readsp(); -} -//##IMPL -// case 0x8f: return op_write_dp_const<&SMPcore::op_st>(); -void SMPcore::op_write_dp_const() { - rd = op_readpc(); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_st(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(dp, wr) : op_io(); -} -//##IMPL -// case 0x90: return op_branch(regs.p.c == 0); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(condition == false) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x91: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0x92: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0x93: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0x94: return op_read_dpi<&SMPcore::op_adc>(regs.a, regs.x); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + i); - r = op_adc(r, rd); -} -//##IMPL -// case 0x95: return op_read_addri<&SMPcore::op_adc>(regs.x); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + r); - regs.a = op_adc(regs.a, rd); -} -//##IMPL -// case 0x96: return op_read_addri<&SMPcore::op_adc>(regs.y); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + r); - regs.a = op_adc(regs.a, rd); -} -//##IMPL -// case 0x97: return op_read_idpy<&SMPcore::op_adc>(); -void SMPcore::op_read_idpy() { - dp = op_readpc(); - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp + regs.y); - regs.a = op_adc(regs.a, rd); -} -//##IMPL -// case 0x98: return op_write_dp_const<&SMPcore::op_adc>(); -void SMPcore::op_write_dp_const() { - rd = op_readpc(); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_adc(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(dp, wr) : op_io(); -} -//##IMPL -// case 0x99: return op_write_ix_iy<&SMPcore::op_adc>(); -void SMPcore::op_write_ix_iy() { - op_io(); - rd = op_readdp(regs.y); - wr = op_readdp(regs.x); - wr = op_adc(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(regs.x, wr) : op_io(); -} -//##IMPL -// case 0x9a: return op_read_dpw<&SMPcore::op_sbw>(); -void SMPcore::op_read_dpw() { - dp = op_readpc(); - rd.l = op_readdp(dp++); - if(op != &SMPcore::op_cpw) op_io(); - rd.h = op_readdp(dp++); - regs.ya = op_sbw(regs.ya, rd); -} -//##IMPL -// case 0x9b: return op_adjust_dpx<&SMPcore::op_dec>(); -void SMPcore::op_adjust_dpx() { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - rd = op_dec(rd); - op_writedp(dp + regs.x, rd); -} -//##IMPL -// case 0x9c: return op_adjust<&SMPcore::op_dec>(regs.a); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - r = op_dec(r); -} -//##IMPL -// case 0x9d: return op_transfer(regs.s, regs.x); -void SMPcore::op_transfer(uint8 &from, uint8 &to) { - op_io(); - to = from; - if(&to == ®s.s) return; - regs.p.n = (to & 0x80); - regs.p.z = (to == 0); -} -//##IMPL -// case 0x9e: return op_div_ya_x(); -void SMPcore::op_div_ya_x() { - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - ya = regs.ya; - //overflow set if quotient >= 256 - regs.p.v = (regs.y >= regs.x); - regs.p.h = ((regs.y & 15) >= (regs.x & 15)); - if(regs.y < (regs.x << 1)) { - //if quotient is <= 511 (will fit into 9-bit result) - regs.a = ya / regs.x; - regs.y = ya % regs.x; - } else { - //otherwise, the quotient won't fit into regs.p.v + regs.a - //this emulates the odd behavior of the S-SMP in this case - regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x); - regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x); - } - //result is set based on a (quotient) only - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); -} -//##IMPL -// case 0x9f: return op_xcn(); -void SMPcore::op_xcn() { - op_io(); - op_io(); - op_io(); - op_io(); - regs.a = (regs.a >> 4) | (regs.a << 4); - regs.p.n = regs.a & 0x80; - regs.p.z = regs.a == 0; -} -//##IMPL -// case 0xa0: return op_set_flag(regs.p.i, 1); -void SMPcore::op_set_flag(bool &flag, bool data) { - op_io(); - if(&flag == ®s.p.i) op_io(); - flag = data; -} -//##IMPL -// case 0xa1: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0xa2: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0xa3: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xa4: return op_read_dp<&SMPcore::op_sbc>(regs.a); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - r = op_sbc(r, rd); -} -//##IMPL -// case 0xa5: return op_read_addr<&SMPcore::op_sbc>(regs.a); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - r = op_sbc(r, rd); -} -//##IMPL -// case 0xa6: return op_read_ix<&SMPcore::op_sbc>(); -void SMPcore::op_read_ix() { - op_io(); - rd = op_readdp(regs.x); - regs.a = op_sbc(regs.a, rd); -} -//##IMPL -// case 0xa7: return op_read_idpx<&SMPcore::op_sbc>(); -void SMPcore::op_read_idpx() { - dp = op_readpc() + regs.x; - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp); - regs.a = op_sbc(regs.a, rd); -} -//##IMPL -// case 0xa8: return op_read_const<&SMPcore::op_sbc>(regs.a); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - r = op_sbc(r, rd); -} -//##IMPL -// case 0xa9: return op_write_dp_dp<&SMPcore::op_sbc>(); -void SMPcore::op_write_dp_dp() { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - if(op != &SMPcore::op_st) wr = op_readdp(dp); - wr = op_sbc(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(dp, wr) : op_io(); -} -//##IMPL -// case 0xaa: return op_set_addr_bit(); -void SMPcore::op_set_addr_bit() { - dp.l = op_readpc(); - dp.h = op_readpc(); - bit = dp >> 13; - dp &= 0x1fff; - rd = op_read(dp); - switch(opcode >> 5) { - case 0: //orc addr:bit - case 1: //orc !addr:bit - op_io(); - regs.p.c |= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); - break; - case 2: //and addr:bit - case 3: //and !addr:bit - regs.p.c &= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); - break; - case 4: //eor addr:bit - op_io(); - regs.p.c ^= (bool)(rd & (1 << bit)); - break; - case 5: //ldc addr:bit - regs.p.c = (rd & (1 << bit)); - break; - case 6: //stc addr:bit - op_io(); - rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - op_write(dp, rd); - break; - case 7: //not addr:bit - rd ^= 1 << bit; - op_write(dp, rd); - break; - } -} -//##IMPL -// case 0xab: return op_adjust_dp<&SMPcore::op_inc>(); -void SMPcore::op_adjust_dp() { - dp = op_readpc(); - rd = op_readdp(dp); - rd = op_inc(rd); - op_writedp(dp, rd); -} -//##IMPL -// case 0xac: return op_adjust_addr<&SMPcore::op_inc>(); -void SMPcore::op_adjust_addr() { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - rd = op_inc(rd); - op_write(dp, rd); -} -//##IMPL -// case 0xad: return op_read_const<&SMPcore::op_cmp>(regs.y); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - r = op_cmp(r, rd); -} -//##IMPL -// case 0xae: return op_pull(regs.a); -void SMPcore::op_pull(uint8 &r) { - op_io(); - op_io(); - r = op_readsp(); -} -//##IMPL -// case 0xaf: return op_sta_ixinc(); -void SMPcore::op_sta_ixinc() { - op_io(); - op_io(); - op_writedp(regs.x++, regs.a); -} -//##IMPL -// case 0xb0: return op_branch(regs.p.c == 1); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(condition == false) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xb1: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0xb2: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0xb3: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xb4: return op_read_dpi<&SMPcore::op_sbc>(regs.a, regs.x); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + i); - r = op_sbc(r, rd); -} -//##IMPL -// case 0xb5: return op_read_addri<&SMPcore::op_sbc>(regs.x); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + r); - regs.a = op_sbc(regs.a, rd); -} -//##IMPL -// case 0xb6: return op_read_addri<&SMPcore::op_sbc>(regs.y); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + r); - regs.a = op_sbc(regs.a, rd); -} -//##IMPL -// case 0xb7: return op_read_idpy<&SMPcore::op_sbc>(); -void SMPcore::op_read_idpy() { - dp = op_readpc(); - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp + regs.y); - regs.a = op_sbc(regs.a, rd); -} -//##IMPL -// case 0xb8: return op_write_dp_const<&SMPcore::op_sbc>(); -void SMPcore::op_write_dp_const() { - rd = op_readpc(); - dp = op_readpc(); - wr = op_readdp(dp); - wr = op_sbc(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(dp, wr) : op_io(); -} -//##IMPL -// case 0xb9: return op_write_ix_iy<&SMPcore::op_sbc>(); -void SMPcore::op_write_ix_iy() { - op_io(); - rd = op_readdp(regs.y); - wr = op_readdp(regs.x); - wr = op_sbc(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(regs.x, wr) : op_io(); -} -//##IMPL -// case 0xba: return op_read_dpw<&SMPcore::op_ldw>(); -void SMPcore::op_read_dpw() { - dp = op_readpc(); - rd.l = op_readdp(dp++); - if(op != &SMPcore::op_cpw) op_io(); - rd.h = op_readdp(dp++); - regs.ya = op_ldw(regs.ya, rd); -} -//##IMPL -// case 0xbb: return op_adjust_dpx<&SMPcore::op_inc>(); -void SMPcore::op_adjust_dpx() { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - rd = op_inc(rd); - op_writedp(dp + regs.x, rd); -} -//##IMPL -// case 0xbc: return op_adjust<&SMPcore::op_inc>(regs.a); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - r = op_inc(r); -} -//##IMPL -// case 0xbd: return op_transfer(regs.x, regs.s); -void SMPcore::op_transfer(uint8 &from, uint8 &to) { - op_io(); - to = from; - if(&to == ®s.s) return; - regs.p.n = (to & 0x80); - regs.p.z = (to == 0); -} -//##IMPL -// case 0xbe: return op_das(); -void SMPcore::op_das() { - op_io(); - op_io(); - if(!regs.p.c || (regs.a) > 0x99) { - regs.a -= 0x60; - regs.p.c = 0; - } - if(!regs.p.h || (regs.a & 15) > 0x09) { - regs.a -= 0x06; - } - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); -} -//##IMPL -// case 0xbf: return op_lda_ixinc(); -void SMPcore::op_lda_ixinc() { - op_io(); - regs.a = op_readdp(regs.x++); - op_io(); - regs.p.n = regs.a & 0x80; - regs.p.z = regs.a == 0; -} -//##IMPL -// case 0xc0: return op_set_flag(regs.p.i, 0); -void SMPcore::op_set_flag(bool &flag, bool data) { - op_io(); - if(&flag == ®s.p.i) op_io(); - flag = data; -} -//##IMPL -// case 0xc1: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0xc2: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0xc3: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xc4: return op_write_dp(regs.a); -void SMPcore::op_write_dp(uint8 &r) { - dp = op_readpc(); - op_readdp(dp); - op_writedp(dp, r); -} -//##IMPL -// case 0xc5: return op_write_addr(regs.a); -void SMPcore::op_write_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_read(dp); - op_write(dp, r); -} -//##IMPL -// case 0xc6: return op_sta_ix(); -void SMPcore::op_sta_ix() { - op_io(); - op_readdp(regs.x); - op_writedp(regs.x, regs.a); -} -//##IMPL -// case 0xc7: return op_sta_idpx(); -void SMPcore::op_sta_idpx() { - sp = op_readpc() + regs.x; - op_io(); - dp.l = op_readdp(sp++); - dp.h = op_readdp(sp++); - op_read(dp); - op_write(dp, regs.a); -} -//##IMPL -// case 0xc8: return op_read_const<&SMPcore::op_cmp>(regs.x); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - r = op_cmp(r, rd); -} -//##IMPL -// case 0xc9: return op_write_addr(regs.x); -void SMPcore::op_write_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_read(dp); - op_write(dp, r); -} -//##IMPL -// case 0xca: return op_set_addr_bit(); -void SMPcore::op_set_addr_bit() { - dp.l = op_readpc(); - dp.h = op_readpc(); - bit = dp >> 13; - dp &= 0x1fff; - rd = op_read(dp); - switch(opcode >> 5) { - case 0: //orc addr:bit - case 1: //orc !addr:bit - op_io(); - regs.p.c |= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); - break; - case 2: //and addr:bit - case 3: //and !addr:bit - regs.p.c &= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); - break; - case 4: //eor addr:bit - op_io(); - regs.p.c ^= (bool)(rd & (1 << bit)); - break; - case 5: //ldc addr:bit - regs.p.c = (rd & (1 << bit)); - break; - case 6: //stc addr:bit - op_io(); - rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - op_write(dp, rd); - break; - case 7: //not addr:bit - rd ^= 1 << bit; - op_write(dp, rd); - break; - } -} -//##IMPL -// case 0xcb: return op_write_dp(regs.y); -void SMPcore::op_write_dp(uint8 &r) { - dp = op_readpc(); - op_readdp(dp); - op_writedp(dp, r); -} -//##IMPL -// case 0xcc: return op_write_addr(regs.y); -void SMPcore::op_write_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_read(dp); - op_write(dp, r); -} -//##IMPL -// case 0xcd: return op_read_const<&SMPcore::op_ld>(regs.x); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - r = op_ld(r, rd); -} -//##IMPL -// case 0xce: return op_pull(regs.x); -void SMPcore::op_pull(uint8 &r) { - op_io(); - op_io(); - r = op_readsp(); -} -//##IMPL -// case 0xcf: return op_mul_ya(); -void SMPcore::op_mul_ya() { - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - ya = regs.y * regs.a; - regs.a = ya; - regs.y = ya >> 8; - //result is set based on y (high-byte) only - regs.p.n = (regs.y & 0x80); - regs.p.z = (regs.y == 0); -} -//##IMPL -// case 0xd0: return op_branch(regs.p.z == 0); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(condition == false) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xd1: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0xd2: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0xd3: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xd4: return op_write_dpi(regs.a, regs.x); -void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { - dp = op_readpc() + i; - op_io(); - op_readdp(dp); - op_writedp(dp, r); -} -//##IMPL -// case 0xd5: return op_write_addri(regs.x); -void SMPcore::op_write_addri(uint8 &i) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - dp += i; - op_read(dp); - op_write(dp, regs.a); -} -//##IMPL -// case 0xd6: return op_write_addri(regs.y); -void SMPcore::op_write_addri(uint8 &i) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - dp += i; - op_read(dp); - op_write(dp, regs.a); -} -//##IMPL -// case 0xd7: return op_sta_idpy(); -void SMPcore::op_sta_idpy() { - sp = op_readpc(); - dp.l = op_readdp(sp++); - dp.h = op_readdp(sp++); - op_io(); - dp += regs.y; - op_read(dp); - op_write(dp, regs.a); -} -//##IMPL -// case 0xd8: return op_write_dp(regs.x); -void SMPcore::op_write_dp(uint8 &r) { - dp = op_readpc(); - op_readdp(dp); - op_writedp(dp, r); -} -//##IMPL -// case 0xd9: return op_write_dpi(regs.x, regs.y); -void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { - dp = op_readpc() + i; - op_io(); - op_readdp(dp); - op_writedp(dp, r); -} -//##IMPL -// case 0xda: return op_stw_dp(); -void SMPcore::op_stw_dp() { - dp = op_readpc(); - op_readdp(dp); - op_writedp(dp++, regs.a); - op_writedp(dp++, regs.y); -} -//##IMPL -// case 0xdb: return op_write_dpi(regs.y, regs.x); -void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { - dp = op_readpc() + i; - op_io(); - op_readdp(dp); - op_writedp(dp, r); -} -//##IMPL -// case 0xdc: return op_adjust<&SMPcore::op_dec>(regs.y); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - r = op_dec(r); -} -//##IMPL -// case 0xdd: return op_transfer(regs.y, regs.a); -void SMPcore::op_transfer(uint8 &from, uint8 &to) { - op_io(); - to = from; - if(&to == ®s.s) return; - regs.p.n = (to & 0x80); - regs.p.z = (to == 0); -} -//##IMPL -// case 0xde: return op_bne_dpx(); -void SMPcore::op_bne_dpx() { - dp = op_readpc(); - op_io(); - sp = op_readdp(dp + regs.x); - rd = op_readpc(); - op_io(); - if(regs.a == sp) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xdf: return op_daa(); -void SMPcore::op_daa() { - op_io(); - op_io(); - if(regs.p.c || (regs.a) > 0x99) { - regs.a += 0x60; - regs.p.c = 1; - } - if(regs.p.h || (regs.a & 15) > 0x09) { - regs.a += 0x06; - } - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); -} -//##IMPL -// case 0xe0: return op_clv(); -void SMPcore::op_clv() { - op_io(); - regs.p.v = 0; - regs.p.h = 0; -} -//##IMPL -// case 0xe1: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0xe2: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0xe3: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xe4: return op_read_dp<&SMPcore::op_ld>(regs.a); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - r = op_ld(r, rd); -} -//##IMPL -// case 0xe5: return op_read_addr<&SMPcore::op_ld>(regs.a); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - r = op_ld(r, rd); -} -//##IMPL -// case 0xe6: return op_read_ix<&SMPcore::op_ld>(); -void SMPcore::op_read_ix() { - op_io(); - rd = op_readdp(regs.x); - regs.a = op_ld(regs.a, rd); -} -//##IMPL -// case 0xe7: return op_read_idpx<&SMPcore::op_ld>(); -void SMPcore::op_read_idpx() { - dp = op_readpc() + regs.x; - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp); - regs.a = op_ld(regs.a, rd); -} -//##IMPL -// case 0xe8: return op_read_const<&SMPcore::op_ld>(regs.a); -void SMPcore::op_read_const(uint8 &r) { - rd = op_readpc(); - r = op_ld(r, rd); -} -//##IMPL -// case 0xe9: return op_read_addr<&SMPcore::op_ld>(regs.x); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - r = op_ld(r, rd); -} -//##IMPL -// case 0xea: return op_set_addr_bit(); -void SMPcore::op_set_addr_bit() { - dp.l = op_readpc(); - dp.h = op_readpc(); - bit = dp >> 13; - dp &= 0x1fff; - rd = op_read(dp); - switch(opcode >> 5) { - case 0: //orc addr:bit - case 1: //orc !addr:bit - op_io(); - regs.p.c |= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); - break; - case 2: //and addr:bit - case 3: //and !addr:bit - regs.p.c &= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); - break; - case 4: //eor addr:bit - op_io(); - regs.p.c ^= (bool)(rd & (1 << bit)); - break; - case 5: //ldc addr:bit - regs.p.c = (rd & (1 << bit)); - break; - case 6: //stc addr:bit - op_io(); - rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - op_write(dp, rd); - break; - case 7: //not addr:bit - rd ^= 1 << bit; - op_write(dp, rd); - break; - } -} -//##IMPL -// case 0xeb: return op_read_dp<&SMPcore::op_ld>(regs.y); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - r = op_ld(r, rd); -} -//##IMPL -// case 0xec: return op_read_addr<&SMPcore::op_ld>(regs.y); -void SMPcore::op_read_addr(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); - r = op_ld(r, rd); -} -//##IMPL -// case 0xed: return op_cmc(); -void SMPcore::op_cmc() { - op_io(); - op_io(); - regs.p.c = !regs.p.c; -} -//##IMPL -// case 0xee: return op_pull(regs.y); -void SMPcore::op_pull(uint8 &r) { - op_io(); - op_io(); - r = op_readsp(); -} -//##IMPL -// case 0xef: return op_wait(); -void SMPcore::op_wait() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - regs.pc--; // repeat this opcode on next run - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - op_io(); - op_io(); - } -} -//##IMPL -// case 0xf0: return op_branch(regs.p.z == 1); -void SMPcore::op_branch(bool condition) { - rd = op_readpc(); - if(condition == false) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xf1: return op_jst(); -void SMPcore::op_jst() { - dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - regs.pc = rd; -} -//##IMPL -// case 0xf2: return op_set_bit(); -void SMPcore::op_set_bit() { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); -} -//##IMPL -// case 0xf3: return op_branch_bit(); -void SMPcore::op_branch_bit() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xf4: return op_read_dpi<&SMPcore::op_ld>(regs.a, regs.x); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + i); - r = op_ld(r, rd); -} -//##IMPL -// case 0xf5: return op_read_addri<&SMPcore::op_ld>(regs.x); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + r); - regs.a = op_ld(regs.a, rd); -} -//##IMPL -// case 0xf6: return op_read_addri<&SMPcore::op_ld>(regs.y); -void SMPcore::op_read_addri(uint8 &r) { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + r); - regs.a = op_ld(regs.a, rd); -} -//##IMPL -// case 0xf7: return op_read_idpy<&SMPcore::op_ld>(); -void SMPcore::op_read_idpy() { - dp = op_readpc(); - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp + regs.y); - regs.a = op_ld(regs.a, rd); -} -//##IMPL -// case 0xf8: return op_read_dp<&SMPcore::op_ld>(regs.x); -void SMPcore::op_read_dp(uint8 &r) { - dp = op_readpc(); - rd = op_readdp(dp); - r = op_ld(r, rd); -} -//##IMPL -// case 0xf9: return op_read_dpi<&SMPcore::op_ld>(regs.x, regs.y); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + i); - r = op_ld(r, rd); -} -//##IMPL -// case 0xfa: return op_write_dp_dp<&SMPcore::op_st>(); -void SMPcore::op_write_dp_dp() { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - if(op != &SMPcore::op_st) wr = op_readdp(dp); - wr = op_st(wr, rd); - op != &SMPcore::op_cmp ? op_writedp(dp, wr) : op_io(); -} -//##IMPL -// case 0xfb: return op_read_dpi<&SMPcore::op_ld>(regs.y, regs.x); -void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + i); - r = op_ld(r, rd); -} -//##IMPL -// case 0xfc: return op_adjust<&SMPcore::op_inc>(regs.y); -void SMPcore::op_adjust(uint8 &r) { - op_io(); - r = op_inc(r); -} -//##IMPL -// case 0xfd: return op_transfer(regs.a, regs.y); -void SMPcore::op_transfer(uint8 &from, uint8 &to) { - op_io(); - to = from; - if(&to == ®s.s) return; - regs.p.n = (to & 0x80); - regs.p.z = (to == 0); -} -//##IMPL -// case 0xfe: return op_bne_ydec(); -void SMPcore::op_bne_ydec() { - rd = op_readpc(); - op_io(); - op_io(); - if(--regs.y == 0) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} -//##IMPL -// case 0xff: return op_wait(); -void SMPcore::op_wait() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - regs.pc--; // repeat this opcode on next run - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - op_io(); - op_io(); - } -} diff --git a/libsnes/s_cpu_coregen/Generex/bin/Debug/uopmod.cpp b/libsnes/s_cpu_coregen/Generex/bin/Debug/uopmod.cpp deleted file mode 100644 index c3e0574eb0..0000000000 --- a/libsnes/s_cpu_coregen/Generex/bin/Debug/uopmod.cpp +++ /dev/null @@ -1,3154 +0,0 @@ -const int uoptable[][] = { - -// case 0x00: return op_nop(); -// void SMPcore::op_nop() { -{ - 1, // op_io(); - 2, // //!!NEXT -}, -// case 0x01: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x02: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x03: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x04: return op_read_dp<&SMPcore::op_or>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x05: return op_read_addr<&SMPcore::op_or>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x06: return op_read_ix<&SMPcore::op_or>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x07: return op_read_idpx<&SMPcore::op_or>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x08: return op_read_const<&SMPcore::op_or>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x09: return op_write_dp_dp<&SMPcore::op_or>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 29, // wr = op_or(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x0a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 1, // op_io(); - 33, // regs.p.c |= (rd & (1 << bit)) ^ 0; - 2, // //!!NEXT -}, -// case 0x0b: return op_adjust_dp<&SMPcore::op_asl>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 34, // rd = op_asl(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x0c: return op_adjust_addr<&SMPcore::op_asl>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 34, // rd = op_asl(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x0d: return op_push(regs.p); -// void SMPcore::op_push(uint8 r) { -{ - 1, // op_io(); - 1, // op_io(); - 37, // op_writesp(regs.p); - 2, // //!!NEXT -}, -// case 0x0e: return op_test_addr(1); -// void SMPcore::op_test_addr(bool set) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 38, // regs.p.n = (regs.a - rd) & 0x80; - 39, // regs.p.z = (regs.a - rd) == 0; - 40, // op_read(dp); - 41, // op_write(dp, rd | regs.a); - 2, // //!!NEXT -}, -// case 0x0f: return op_brk(); -// void SMPcore::op_brk() { -{ - 42, // rd.l = op_read(0xffde); - 43, // rd.h = op_read(0xffdf); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 37, // op_writesp(regs.p); - 8, // regs.pc = rd; - 44, // regs.p.b = 1; - 45, // regs.p.i = 0; - 2, // //!!NEXT -}, -// case 0x10: return op_branch(regs.p.n == 0); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 46, // if(regs.p.n != 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x11: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x12: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x13: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x14: return op_read_dpi<&SMPcore::op_or>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x15: return op_read_addri<&SMPcore::op_or>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x16: return op_read_addri<&SMPcore::op_or>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x17: return op_read_idpy<&SMPcore::op_or>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x18: return op_write_dp_const<&SMPcore::op_or>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 29, // wr = op_or(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x19: return op_write_ix_iy<&SMPcore::op_or>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 29, // wr = op_or(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0x1a: return op_adjust_dpw(-1); -// void SMPcore::op_adjust_dpw(signed n) { -{ - 9, // dp = op_readpc(); - 54, // rd.w = op_readdp(dp) - 1; - 55, // op_writedp(dp++, rd.l); - 56, // rd.h += op_readdp(dp); - 57, // op_writedp(dp++, rd.h); - 58, // regs.p.n = rd & 0x8000; - 59, // regs.p.z = rd == 0; - 2, // //!!NEXT -}, -// case 0x1b: return op_adjust_dpx<&SMPcore::op_asl>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 34, // rd = op_asl(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x1c: return op_adjust<&SMPcore::op_asl>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 61, // regs.a = op_asl(regs.a); - 2, // //!!NEXT -}, -// case 0x1d: return op_adjust<&SMPcore::op_dec>(regs.x); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 62, // regs.x = op_dec(regs.x); - 2, // //!!NEXT -}, -// case 0x1e: return op_read_addr<&SMPcore::op_cmp>(regs.x); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 63, // regs.x = op_cmp(regs.x, rd); - 2, // //!!NEXT -}, -// case 0x1f: return op_jmp_iaddrx(); -// void SMPcore::op_jmp_iaddrx() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 64, // dp += regs.x; - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x20: return op_set_flag(regs.p.p, 0); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 65, // regs.p.p = 0; - 2, // //!!NEXT -}, -// case 0x21: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x22: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x23: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x24: return op_read_dp<&SMPcore::op_and>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x25: return op_read_addr<&SMPcore::op_and>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x26: return op_read_ix<&SMPcore::op_and>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x27: return op_read_idpx<&SMPcore::op_and>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x28: return op_read_const<&SMPcore::op_and>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x29: return op_write_dp_dp<&SMPcore::op_and>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 67, // wr = op_and(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x2a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 1, // op_io(); - 68, // regs.p.c |= (rd & (1 << bit)) ^ 1; - 2, // //!!NEXT -}, -// case 0x2b: return op_adjust_dp<&SMPcore::op_rol>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 69, // rd = op_rol(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x2c: return op_adjust_addr<&SMPcore::op_rol>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 69, // rd = op_rol(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x2d: return op_push(regs.a); -// void SMPcore::op_push(uint8 r) { -{ - 1, // op_io(); - 1, // op_io(); - 70, // op_writesp(regs.a); - 2, // //!!NEXT -}, -// case 0x2e: return op_bne_dp(); -// void SMPcore::op_bne_dp() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 71, // if(regs.a == sp) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x2f: return op_branch(true); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x30: return op_branch(regs.p.n == 1); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 72, // if(regs.p.n != 1) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x31: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x32: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x33: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x34: return op_read_dpi<&SMPcore::op_and>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x35: return op_read_addri<&SMPcore::op_and>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x36: return op_read_addri<&SMPcore::op_and>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x37: return op_read_idpy<&SMPcore::op_and>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x38: return op_write_dp_const<&SMPcore::op_and>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 67, // wr = op_and(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x39: return op_write_ix_iy<&SMPcore::op_and>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 67, // wr = op_and(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0x3a: return op_adjust_dpw(+1); -// void SMPcore::op_adjust_dpw(signed n) { -{ - 9, // dp = op_readpc(); - 73, // rd.w = op_readdp(dp) + 1; - 55, // op_writedp(dp++, rd.l); - 56, // rd.h += op_readdp(dp); - 57, // op_writedp(dp++, rd.h); - 58, // regs.p.n = rd & 0x8000; - 59, // regs.p.z = rd == 0; - 2, // //!!NEXT -}, -// case 0x3b: return op_adjust_dpx<&SMPcore::op_rol>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 69, // rd = op_rol(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x3c: return op_adjust<&SMPcore::op_rol>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 74, // regs.a = op_rol(regs.a); - 2, // //!!NEXT -}, -// case 0x3d: return op_adjust<&SMPcore::op_inc>(regs.x); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 75, // regs.x = op_inc(regs.x); - 2, // //!!NEXT -}, -// case 0x3e: return op_read_dp<&SMPcore::op_cmp>(regs.x); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 63, // regs.x = op_cmp(regs.x, rd); - 2, // //!!NEXT -}, -// case 0x3f: return op_jsr_addr(); -// void SMPcore::op_jsr_addr() { -{ - 76, // rd.l = op_readpc(); - 77, // rd.h = op_readpc(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x40: return op_set_flag(regs.p.p, 1); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 78, // regs.p.p = 1; - 2, // //!!NEXT -}, -// case 0x41: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x42: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x43: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x44: return op_read_dp<&SMPcore::op_eor>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x45: return op_read_addr<&SMPcore::op_eor>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x46: return op_read_ix<&SMPcore::op_eor>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x47: return op_read_idpx<&SMPcore::op_eor>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x48: return op_read_const<&SMPcore::op_eor>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x49: return op_write_dp_dp<&SMPcore::op_eor>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 80, // wr = op_eor(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x4a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 81, // regs.p.c &= (rd & (1 << bit)) ^ 0; - 2, // //!!NEXT -}, -// case 0x4b: return op_adjust_dp<&SMPcore::op_lsr>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 82, // rd = op_lsr(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x4c: return op_adjust_addr<&SMPcore::op_lsr>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 82, // rd = op_lsr(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x4d: return op_push(regs.x); -// void SMPcore::op_push(uint8 r) { -{ - 1, // op_io(); - 1, // op_io(); - 83, // op_writesp(regs.x); - 2, // //!!NEXT -}, -// case 0x4e: return op_test_addr(0); -// void SMPcore::op_test_addr(bool set) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 38, // regs.p.n = (regs.a - rd) & 0x80; - 39, // regs.p.z = (regs.a - rd) == 0; - 40, // op_read(dp); - 84, // op_write(dp, rd & ~regs.a); - 2, // //!!NEXT -}, -// case 0x4f: return op_jsp_dp(); -// void SMPcore::op_jsp_dp() { -{ - 13, // rd = op_readpc(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 85, // regs.pc = 0xff00 | rd; - 2, // //!!NEXT -}, -// case 0x50: return op_branch(regs.p.v == 0); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 86, // if(regs.p.v != 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x51: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x52: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x53: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x54: return op_read_dpi<&SMPcore::op_eor>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x55: return op_read_addri<&SMPcore::op_eor>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x56: return op_read_addri<&SMPcore::op_eor>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x57: return op_read_idpy<&SMPcore::op_eor>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x58: return op_write_dp_const<&SMPcore::op_eor>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 80, // wr = op_eor(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x59: return op_write_ix_iy<&SMPcore::op_eor>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 80, // wr = op_eor(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0x5a: return op_read_dpw<&SMPcore::op_cpw>(); -// void SMPcore::op_read_dpw() { -{ - 9, // dp = op_readpc(); - 87, // rd.l = op_readdp(dp++); - 88, // rd.h = op_readdp(dp++); - 89, // regs.ya = op_cpw(regs.ya, rd); - 2, // //!!NEXT -}, -// case 0x5b: return op_adjust_dpx<&SMPcore::op_lsr>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 82, // rd = op_lsr(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x5c: return op_adjust<&SMPcore::op_lsr>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 90, // regs.a = op_lsr(regs.a); - 2, // //!!NEXT -}, -// case 0x5d: return op_transfer(regs.a, regs.x); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 91, // regs.x = regs.a; - 92, // regs.p.n = (regs.x & 0x80); - 93, // regs.p.z = (regs.x == 0); - 2, // //!!NEXT -}, -// case 0x5e: return op_read_addr<&SMPcore::op_cmp>(regs.y); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 94, // regs.y = op_cmp(regs.y, rd); - 2, // //!!NEXT -}, -// case 0x5f: return op_jmp_addr(); -// void SMPcore::op_jmp_addr() { -{ - 76, // rd.l = op_readpc(); - 77, // rd.h = op_readpc(); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x60: return op_set_flag(regs.p.c, 0); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 95, // regs.p.c = 0; - 2, // //!!NEXT -}, -// case 0x61: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x62: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x63: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x64: return op_read_dp<&SMPcore::op_cmp>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x65: return op_read_addr<&SMPcore::op_cmp>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x66: return op_read_ix<&SMPcore::op_cmp>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x67: return op_read_idpx<&SMPcore::op_cmp>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x68: return op_read_const<&SMPcore::op_cmp>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x69: return op_write_dp_dp<&SMPcore::op_cmp>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 97, // wr = op_cmp(wr, rd); - 1, // op_io(); - 2, // //!!NEXT -}, -// case 0x6a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 98, // regs.p.c &= (rd & (1 << bit)) ^ 1; - 2, // //!!NEXT -}, -// case 0x6b: return op_adjust_dp<&SMPcore::op_ror>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 99, // rd = op_ror(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x6c: return op_adjust_addr<&SMPcore::op_ror>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 99, // rd = op_ror(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x6d: return op_push(regs.y); -// void SMPcore::op_push(uint8 r) { -{ - 1, // op_io(); - 1, // op_io(); - 100, // op_writesp(regs.y); - 2, // //!!NEXT -}, -// case 0x6e: return op_bne_dpdec(); -// void SMPcore::op_bne_dpdec() { -{ - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 101, // op_writedp(dp, --wr); - 13, // rd = op_readpc(); - 102, // if(wr == 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x6f: return op_rts(); -// void SMPcore::op_rts() { -{ - 103, // rd.l = op_readsp(); - 104, // rd.h = op_readsp(); - 1, // op_io(); - 1, // op_io(); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x70: return op_branch(regs.p.v == 1); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 105, // if(regs.p.v != 1) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x71: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x72: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x73: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x74: return op_read_dpi<&SMPcore::op_cmp>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x75: return op_read_addri<&SMPcore::op_cmp>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x76: return op_read_addri<&SMPcore::op_cmp>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x77: return op_read_idpy<&SMPcore::op_cmp>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x78: return op_write_dp_const<&SMPcore::op_cmp>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 97, // wr = op_cmp(wr, rd); - 1, // op_io(); - 2, // //!!NEXT -}, -// case 0x79: return op_write_ix_iy<&SMPcore::op_cmp>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 97, // wr = op_cmp(wr, rd); - 1, // op_io(); - 2, // //!!NEXT -}, -// case 0x7a: return op_read_dpw<&SMPcore::op_adw>(); -// void SMPcore::op_read_dpw() { -{ - 9, // dp = op_readpc(); - 87, // rd.l = op_readdp(dp++); - 1, // op_io(); - 88, // rd.h = op_readdp(dp++); - 106, // regs.ya = op_adw(regs.ya, rd); - 2, // //!!NEXT -}, -// case 0x7b: return op_adjust_dpx<&SMPcore::op_ror>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 99, // rd = op_ror(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x7c: return op_adjust<&SMPcore::op_ror>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 107, // regs.a = op_ror(regs.a); - 2, // //!!NEXT -}, -// case 0x7d: return op_transfer(regs.x, regs.a); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 108, // regs.a = regs.x; - 109, // regs.p.n = (regs.a & 0x80); - 110, // regs.p.z = (regs.a == 0); - 2, // //!!NEXT -}, -// case 0x7e: return op_read_dp<&SMPcore::op_cmp>(regs.y); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 94, // regs.y = op_cmp(regs.y, rd); - 2, // //!!NEXT -}, -// case 0x7f: return op_rti(); -// void SMPcore::op_rti() { -{ - 111, // regs.p = op_readsp(); - 103, // rd.l = op_readsp(); - 104, // rd.h = op_readsp(); - 1, // op_io(); - 1, // op_io(); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x80: return op_set_flag(regs.p.c, 1); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 112, // regs.p.c = 1; - 2, // //!!NEXT -}, -// case 0x81: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x82: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x83: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x84: return op_read_dp<&SMPcore::op_adc>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x85: return op_read_addr<&SMPcore::op_adc>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x86: return op_read_ix<&SMPcore::op_adc>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x87: return op_read_idpx<&SMPcore::op_adc>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x88: return op_read_const<&SMPcore::op_adc>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x89: return op_write_dp_dp<&SMPcore::op_adc>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 114, // wr = op_adc(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x8a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 1, // op_io(); - 115, // regs.p.c ^= (bool)(rd & (1 << bit)); - 2, // //!!NEXT -}, -// case 0x8b: return op_adjust_dp<&SMPcore::op_dec>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 116, // rd = op_dec(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x8c: return op_adjust_addr<&SMPcore::op_dec>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 116, // rd = op_dec(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x8d: return op_read_const<&SMPcore::op_ld>(regs.y); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 117, // regs.y = op_ld(regs.y, rd); - 2, // //!!NEXT -}, -// case 0x8e: return op_plp(); -// void SMPcore::op_plp() { -{ - 1, // op_io(); - 1, // op_io(); - 111, // regs.p = op_readsp(); - 2, // //!!NEXT -}, -// case 0x8f: return op_write_dp_const<&SMPcore::op_st>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 118, // wr = op_st(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x90: return op_branch(regs.p.c == 0); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 119, // if(regs.p.c != 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x91: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x92: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x93: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x94: return op_read_dpi<&SMPcore::op_adc>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x95: return op_read_addri<&SMPcore::op_adc>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x96: return op_read_addri<&SMPcore::op_adc>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x97: return op_read_idpy<&SMPcore::op_adc>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x98: return op_write_dp_const<&SMPcore::op_adc>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 114, // wr = op_adc(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x99: return op_write_ix_iy<&SMPcore::op_adc>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 114, // wr = op_adc(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0x9a: return op_read_dpw<&SMPcore::op_sbw>(); -// void SMPcore::op_read_dpw() { -{ - 9, // dp = op_readpc(); - 87, // rd.l = op_readdp(dp++); - 1, // op_io(); - 88, // rd.h = op_readdp(dp++); - 120, // regs.ya = op_sbw(regs.ya, rd); - 2, // //!!NEXT -}, -// case 0x9b: return op_adjust_dpx<&SMPcore::op_dec>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 116, // rd = op_dec(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x9c: return op_adjust<&SMPcore::op_dec>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 121, // regs.a = op_dec(regs.a); - 2, // //!!NEXT -}, -// case 0x9d: return op_transfer(regs.s, regs.x); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 122, // regs.x = regs.s; - 92, // regs.p.n = (regs.x & 0x80); - 93, // regs.p.z = (regs.x == 0); - 2, // //!!NEXT -}, -// case 0x9e: return op_div_ya_x(); -// void SMPcore::op_div_ya_x() { -{ - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - //ya = regs.ya; - ////overflow set if quotient >= 256 - //regs.p.v = (regs.y >= regs.x); - //regs.p.h = ((regs.y & 15) >= (regs.x & 15)); - //if(regs.y < (regs.x << 1)) { - ////if quotient is <= 511 (will fit into 9-bit result) - //regs.a = ya / regs.x; - //regs.y = ya % regs.x; - //} else { - ////otherwise, the quotient won't fit into regs.p.v + regs.a - ////this emulates the odd behavior of the S-SMP in this case - //regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x); - //regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x); - //} - ////result is set based on a (quotient) only - //regs.p.n = (regs.a & 0x80); - //regs.p.z = (regs.a == 0); - 123, // //!!MULTI0 - 2, // //!!NEXT -}, -// case 0x9f: return op_xcn(); -// void SMPcore::op_xcn() { -{ - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 124, // regs.a = (regs.a >> 4) | (regs.a << 4); - 125, // regs.p.n = regs.a & 0x80; - 126, // regs.p.z = regs.a == 0; - 2, // //!!NEXT -}, -// case 0xa0: return op_set_flag(regs.p.i, 1); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 1, // op_io(); - 127, // regs.p.i = 1; - 2, // //!!NEXT -}, -// case 0xa1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xa2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xa3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xa4: return op_read_dp<&SMPcore::op_sbc>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa5: return op_read_addr<&SMPcore::op_sbc>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa6: return op_read_ix<&SMPcore::op_sbc>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa7: return op_read_idpx<&SMPcore::op_sbc>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa8: return op_read_const<&SMPcore::op_sbc>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa9: return op_write_dp_dp<&SMPcore::op_sbc>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 129, // wr = op_sbc(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0xaa: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 130, // regs.p.c = (rd & (1 << bit)); - 2, // //!!NEXT -}, -// case 0xab: return op_adjust_dp<&SMPcore::op_inc>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 131, // rd = op_inc(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0xac: return op_adjust_addr<&SMPcore::op_inc>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 131, // rd = op_inc(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0xad: return op_read_const<&SMPcore::op_cmp>(regs.y); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 94, // regs.y = op_cmp(regs.y, rd); - 2, // //!!NEXT -}, -// case 0xae: return op_pull(regs.a); -// void SMPcore::op_pull(uint8 &r) { -{ - 1, // op_io(); - 1, // op_io(); - 132, // regs.a = op_readsp(); - 2, // //!!NEXT -}, -// case 0xaf: return op_sta_ixinc(); -// void SMPcore::op_sta_ixinc() { -{ - 1, // op_io(); - 1, // op_io(); - 133, // op_writedp(regs.x++, regs.a); - 2, // //!!NEXT -}, -// case 0xb0: return op_branch(regs.p.c == 1); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 134, // if(regs.p.c != 1) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xb1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xb2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xb3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xb4: return op_read_dpi<&SMPcore::op_sbc>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xb5: return op_read_addri<&SMPcore::op_sbc>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xb6: return op_read_addri<&SMPcore::op_sbc>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xb7: return op_read_idpy<&SMPcore::op_sbc>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xb8: return op_write_dp_const<&SMPcore::op_sbc>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 129, // wr = op_sbc(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0xb9: return op_write_ix_iy<&SMPcore::op_sbc>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 129, // wr = op_sbc(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0xba: return op_read_dpw<&SMPcore::op_ldw>(); -// void SMPcore::op_read_dpw() { -{ - 9, // dp = op_readpc(); - 87, // rd.l = op_readdp(dp++); - 1, // op_io(); - 88, // rd.h = op_readdp(dp++); - 135, // regs.ya = op_ldw(regs.ya, rd); - 2, // //!!NEXT -}, -// case 0xbb: return op_adjust_dpx<&SMPcore::op_inc>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 131, // rd = op_inc(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0xbc: return op_adjust<&SMPcore::op_inc>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 136, // r = op_inc(r); - 2, // //!!NEXT -}, -// case 0xbd: return op_transfer(regs.x, regs.s); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 137, // regs.s = regs.x; - 2, // //!!NEXT -}, -// case 0xbe: return op_das(); -// void SMPcore::op_das() { -{ - 1, // op_io(); - 1, // op_io(); - //if(!regs.p.c || (regs.a) > 0x99) { - //regs.a -= 0x60; - //regs.p.c = 0; - //} - //if(!regs.p.h || (regs.a & 15) > 0x09) { - //regs.a -= 0x06; - //} - //regs.p.n = (regs.a & 0x80); - //regs.p.z = (regs.a == 0); - 138, // //!!MULTI1 - 2, // //!!NEXT -}, -// case 0xbf: return op_lda_ixinc(); -// void SMPcore::op_lda_ixinc() { -{ - 1, // op_io(); - 139, // regs.a = op_readdp(regs.x++); - 1, // op_io(); - 125, // regs.p.n = regs.a & 0x80; - 126, // regs.p.z = regs.a == 0; - 2, // //!!NEXT -}, -// case 0xc0: return op_set_flag(regs.p.i, 0); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 1, // op_io(); - 45, // regs.p.i = 0; - 2, // //!!NEXT -}, -// case 0xc1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xc2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xc3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xc4: return op_write_dp(regs.a); -// void SMPcore::op_write_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 140, // op_readdp(dp); - 141, // op_writedp(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xc5: return op_write_addr(regs.a); -// void SMPcore::op_write_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xc6: return op_sta_ix(); -// void SMPcore::op_sta_ix() { -{ - 1, // op_io(); - 143, // op_readdp(regs.x); - 144, // op_writedp(regs.x, regs.a); - 2, // //!!NEXT -}, -// case 0xc7: return op_sta_idpx(); -// void SMPcore::op_sta_idpx() { -{ - 145, // sp = op_readpc() + regs.x; - 1, // op_io(); - 146, // dp.l = op_readdp(sp++); - 147, // dp.h = op_readdp(sp++); - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xc8: return op_read_const<&SMPcore::op_cmp>(regs.x); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 63, // regs.x = op_cmp(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xc9: return op_write_addr(regs.x); -// void SMPcore::op_write_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 40, // op_read(dp); - 148, // op_write(dp, regs.x); - 2, // //!!NEXT -}, -// case 0xca: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 1, // op_io(); - 149, // rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0xcb: return op_write_dp(regs.y); -// void SMPcore::op_write_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 140, // op_readdp(dp); - 150, // op_writedp(dp, regs.y); - 2, // //!!NEXT -}, -// case 0xcc: return op_write_addr(regs.y); -// void SMPcore::op_write_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 40, // op_read(dp); - 151, // op_write(dp, regs.y); - 2, // //!!NEXT -}, -// case 0xcd: return op_read_const<&SMPcore::op_ld>(regs.x); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 152, // regs.x = op_ld(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xce: return op_pull(regs.x); -// void SMPcore::op_pull(uint8 &r) { -{ - 1, // op_io(); - 1, // op_io(); - 153, // regs.x = op_readsp(); - 2, // //!!NEXT -}, -// case 0xcf: return op_mul_ya(); -// void SMPcore::op_mul_ya() { -{ - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - //ya = regs.y * regs.a; - //regs.a = ya; - //regs.y = ya >> 8; - ////result is set based on y (high-byte) only - //regs.p.n = (regs.y & 0x80); - //regs.p.z = (regs.y == 0); - 154, // //!!MULTI2 - 2, // //!!NEXT -}, -// case 0xd0: return op_branch(regs.p.z == 0); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 155, // if(regs.p.z != 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xd1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xd2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xd3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xd4: return op_write_dpi(regs.a, regs.x); -// void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 140, // op_readdp(dp); - 141, // op_writedp(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xd5: return op_write_addri(regs.x); -// void SMPcore::op_write_addri(uint8 &i) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 64, // dp += regs.x; - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xd6: return op_write_addri(regs.y); -// void SMPcore::op_write_addri(uint8 &i) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 156, // dp += regs.y; - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xd7: return op_sta_idpy(); -// void SMPcore::op_sta_idpy() { -{ - 26, // sp = op_readpc(); - 146, // dp.l = op_readdp(sp++); - 147, // dp.h = op_readdp(sp++); - 1, // op_io(); - 156, // dp += regs.y; - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xd8: return op_write_dp(regs.x); -// void SMPcore::op_write_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 140, // op_readdp(dp); - 157, // op_writedp(dp, regs.x); - 2, // //!!NEXT -}, -// case 0xd9: return op_write_dpi(regs.x, regs.y); -// void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { -{ - 158, // dp = op_readpc() + regs.y; - 1, // op_io(); - 140, // op_readdp(dp); - 157, // op_writedp(dp, regs.x); - 2, // //!!NEXT -}, -// case 0xda: return op_stw_dp(); -// void SMPcore::op_stw_dp() { -{ - 9, // dp = op_readpc(); - 140, // op_readdp(dp); - 159, // op_writedp(dp++, regs.a); - 160, // op_writedp(dp++, regs.y); - 2, // //!!NEXT -}, -// case 0xdb: return op_write_dpi(regs.y, regs.x); -// void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 140, // op_readdp(dp); - 150, // op_writedp(dp, regs.y); - 2, // //!!NEXT -}, -// case 0xdc: return op_adjust<&SMPcore::op_dec>(regs.y); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 161, // regs.y = op_dec(regs.y); - 2, // //!!NEXT -}, -// case 0xdd: return op_transfer(regs.y, regs.a); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 162, // regs.a = regs.y; - 109, // regs.p.n = (regs.a & 0x80); - 110, // regs.p.z = (regs.a == 0); - 2, // //!!NEXT -}, -// case 0xde: return op_bne_dpx(); -// void SMPcore::op_bne_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 163, // sp = op_readdp(dp + regs.x); - 13, // rd = op_readpc(); - 1, // op_io(); - 71, // if(regs.a == sp) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xdf: return op_daa(); -// void SMPcore::op_daa() { -{ - 1, // op_io(); - 1, // op_io(); - //if(regs.p.c || (regs.a) > 0x99) { - //regs.a += 0x60; - //regs.p.c = 1; - //} - //if(regs.p.h || (regs.a & 15) > 0x09) { - //regs.a += 0x06; - //} - //regs.p.n = (regs.a & 0x80); - //regs.p.z = (regs.a == 0); - 164, // //!!MULTI3 - 2, // //!!NEXT -}, -// case 0xe0: return op_clv(); -// void SMPcore::op_clv() { -{ - 1, // op_io(); - 165, // regs.p.v = 0; - 166, // regs.p.h = 0; - 2, // //!!NEXT -}, -// case 0xe1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xe2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xe3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xe4: return op_read_dp<&SMPcore::op_ld>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe5: return op_read_addr<&SMPcore::op_ld>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe6: return op_read_ix<&SMPcore::op_ld>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe7: return op_read_idpx<&SMPcore::op_ld>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe8: return op_read_const<&SMPcore::op_ld>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe9: return op_read_addr<&SMPcore::op_ld>(regs.x); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 152, // regs.x = op_ld(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xea: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 168, // rd ^= 1 << bit; - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0xeb: return op_read_dp<&SMPcore::op_ld>(regs.y); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 117, // regs.y = op_ld(regs.y, rd); - 2, // //!!NEXT -}, -// case 0xec: return op_read_addr<&SMPcore::op_ld>(regs.y); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 117, // regs.y = op_ld(regs.y, rd); - 2, // //!!NEXT -}, -// case 0xed: return op_cmc(); -// void SMPcore::op_cmc() { -{ - 1, // op_io(); - 1, // op_io(); - 169, // regs.p.c = !regs.p.c; - 2, // //!!NEXT -}, -// case 0xee: return op_pull(regs.y); -// void SMPcore::op_pull(uint8 &r) { -{ - 1, // op_io(); - 1, // op_io(); - 170, // regs.y = op_readsp(); - 2, // //!!NEXT -}, -// case 0xef: return op_wait(); -// void SMPcore::op_wait() { -{ - 1, // op_io(); - 1, // op_io(); - 171, // //!!REPEAT -}, -// case 0xf0: return op_branch(regs.p.z == 1); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 172, // if(regs.p.z != 1) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xf1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xf2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xf3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xf4: return op_read_dpi<&SMPcore::op_ld>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xf5: return op_read_addri<&SMPcore::op_ld>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xf6: return op_read_addri<&SMPcore::op_ld>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xf7: return op_read_idpy<&SMPcore::op_ld>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xf8: return op_read_dp<&SMPcore::op_ld>(regs.x); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 152, // regs.x = op_ld(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xf9: return op_read_dpi<&SMPcore::op_ld>(regs.x, regs.y); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 173, // rd = op_readdp(dp + regs.y); - 152, // regs.x = op_ld(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xfa: return op_write_dp_dp<&SMPcore::op_st>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 118, // wr = op_st(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0xfb: return op_read_dpi<&SMPcore::op_ld>(regs.y, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 117, // regs.y = op_ld(regs.y, rd); - 2, // //!!NEXT -}, -// case 0xfc: return op_adjust<&SMPcore::op_inc>(regs.y); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 174, // regs.y = op_inc(regs.y); - 2, // //!!NEXT -}, -// case 0xfd: return op_transfer(regs.a, regs.y); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 175, // regs.y = regs.a; - 176, // regs.p.n = (regs.y & 0x80); - 177, // regs.p.z = (regs.y == 0); - 2, // //!!NEXT -}, -// case 0xfe: return op_bne_ydec(); -// void SMPcore::op_bne_ydec() { -{ - 13, // rd = op_readpc(); - 1, // op_io(); - 1, // op_io(); - 178, // if(--regs.y == 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xff: return op_wait(); -// void SMPcore::op_wait() { -{ - 1, // op_io(); - 1, // op_io(); - 171, // //!!REPEAT -}, - -}; // const int uoptable[][] = { - - - - - - -void SMPcore::op_step() -{ - switch (uoptable[opcode][uindex]) - { - case 1: - op_io(); - break; - case 2: - opcode = op_readpc(); //!!NEXT - uindex = -1; - break; - case 3: - dp = 0xffde - ((opcode >> 4) << 1); - break; - case 4: - rd.l = op_read(dp++); - break; - case 5: - rd.h = op_read(dp++); - break; - case 6: - op_writesp(regs.pc.h); - break; - case 7: - op_writesp(regs.pc.l); - break; - case 8: - regs.pc = rd; - break; - case 9: - dp = op_readpc(); - break; - case 10: - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - break; - case 11: - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - break; - case 12: - sp = op_readdp(dp); - break; - case 13: - rd = op_readpc(); - break; - case 14: - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) op_next(); - break; - case 15: - regs.pc += (int8)rd; - break; - case 16: - rd = op_readdp(dp); - break; - case 17: - regs.a = op_or(regs.a, rd); - break; - case 18: - dp.l = op_readpc(); - break; - case 19: - dp.h = op_readpc(); - break; - case 20: - rd = op_read(dp); - break; - case 21: - rd = op_readdp(regs.x); - break; - case 22: - dp = op_readpc() + regs.x; - break; - case 23: - sp.l = op_readdp(dp++); - break; - case 24: - sp.h = op_readdp(dp++); - break; - case 25: - rd = op_read(sp); - break; - case 26: - sp = op_readpc(); - break; - case 27: - rd = op_readdp(sp); - break; - case 28: - wr = op_readdp(dp); - break; - case 29: - wr = op_or(wr, rd); - break; - case 30: - op_writedp(dp, wr); - break; - case 31: - bit = dp >> 13; - break; - case 32: - dp &= 0x1fff; - break; - case 33: - regs.p.c |= (rd & (1 << bit)) ^ 0; - break; - case 34: - rd = op_asl(rd); - break; - case 35: - op_writedp(dp, rd); - break; - case 36: - op_write(dp, rd); - break; - case 37: - op_writesp(regs.p); - break; - case 38: - regs.p.n = (regs.a - rd) & 0x80; - break; - case 39: - regs.p.z = (regs.a - rd) == 0; - break; - case 40: - op_read(dp); - break; - case 41: - op_write(dp, rd | regs.a); - break; - case 42: - rd.l = op_read(0xffde); - break; - case 43: - rd.h = op_read(0xffdf); - break; - case 44: - regs.p.b = 1; - break; - case 45: - regs.p.i = 0; - break; - case 46: - if(regs.p.n != 0) op_next(); - break; - case 47: - rd = op_readdp(dp + regs.x); - break; - case 48: - rd = op_read(dp + regs.x); - break; - case 49: - rd = op_read(dp + regs.y); - break; - case 50: - rd = op_read(sp + regs.y); - break; - case 51: - rd = op_readdp(regs.y); - break; - case 52: - wr = op_readdp(regs.x); - break; - case 53: - op_writedp(regs.x, wr); - break; - case 54: - rd.w = op_readdp(dp) - 1; - break; - case 55: - op_writedp(dp++, rd.l); - break; - case 56: - rd.h += op_readdp(dp); - break; - case 57: - op_writedp(dp++, rd.h); - break; - case 58: - regs.p.n = rd & 0x8000; - break; - case 59: - regs.p.z = rd == 0; - break; - case 60: - op_writedp(dp + regs.x, rd); - break; - case 61: - regs.a = op_asl(regs.a); - break; - case 62: - regs.x = op_dec(regs.x); - break; - case 63: - regs.x = op_cmp(regs.x, rd); - break; - case 64: - dp += regs.x; - break; - case 65: - regs.p.p = 0; - break; - case 66: - regs.a = op_and(regs.a, rd); - break; - case 67: - wr = op_and(wr, rd); - break; - case 68: - regs.p.c |= (rd & (1 << bit)) ^ 1; - break; - case 69: - rd = op_rol(rd); - break; - case 70: - op_writesp(regs.a); - break; - case 71: - if(regs.a == sp) op_next(); - break; - case 72: - if(regs.p.n != 1) op_next(); - break; - case 73: - rd.w = op_readdp(dp) + 1; - break; - case 74: - regs.a = op_rol(regs.a); - break; - case 75: - regs.x = op_inc(regs.x); - break; - case 76: - rd.l = op_readpc(); - break; - case 77: - rd.h = op_readpc(); - break; - case 78: - regs.p.p = 1; - break; - case 79: - regs.a = op_eor(regs.a, rd); - break; - case 80: - wr = op_eor(wr, rd); - break; - case 81: - regs.p.c &= (rd & (1 << bit)) ^ 0; - break; - case 82: - rd = op_lsr(rd); - break; - case 83: - op_writesp(regs.x); - break; - case 84: - op_write(dp, rd & ~regs.a); - break; - case 85: - regs.pc = 0xff00 | rd; - break; - case 86: - if(regs.p.v != 0) op_next(); - break; - case 87: - rd.l = op_readdp(dp++); - break; - case 88: - rd.h = op_readdp(dp++); - break; - case 89: - regs.ya = op_cpw(regs.ya, rd); - break; - case 90: - regs.a = op_lsr(regs.a); - break; - case 91: - regs.x = regs.a; - break; - case 92: - regs.p.n = (regs.x & 0x80); - break; - case 93: - regs.p.z = (regs.x == 0); - break; - case 94: - regs.y = op_cmp(regs.y, rd); - break; - case 95: - regs.p.c = 0; - break; - case 96: - regs.a = op_cmp(regs.a, rd); - break; - case 97: - wr = op_cmp(wr, rd); - break; - case 98: - regs.p.c &= (rd & (1 << bit)) ^ 1; - break; - case 99: - rd = op_ror(rd); - break; - case 100: - op_writesp(regs.y); - break; - case 101: - op_writedp(dp, --wr); - break; - case 102: - if(wr == 0) op_next(); - break; - case 103: - rd.l = op_readsp(); - break; - case 104: - rd.h = op_readsp(); - break; - case 105: - if(regs.p.v != 1) op_next(); - break; - case 106: - regs.ya = op_adw(regs.ya, rd); - break; - case 107: - regs.a = op_ror(regs.a); - break; - case 108: - regs.a = regs.x; - break; - case 109: - regs.p.n = (regs.a & 0x80); - break; - case 110: - regs.p.z = (regs.a == 0); - break; - case 111: - regs.p = op_readsp(); - break; - case 112: - regs.p.c = 1; - break; - case 113: - regs.a = op_adc(regs.a, rd); - break; - case 114: - wr = op_adc(wr, rd); - break; - case 115: - regs.p.c ^= (bool)(rd & (1 << bit)); - break; - case 116: - rd = op_dec(rd); - break; - case 117: - regs.y = op_ld(regs.y, rd); - break; - case 118: - wr = op_st(wr, rd); - break; - case 119: - if(regs.p.c != 0) op_next(); - break; - case 120: - regs.ya = op_sbw(regs.ya, rd); - break; - case 121: - regs.a = op_dec(regs.a); - break; - case 122: - regs.x = regs.s; - break; - case 123: - //!!MULTI0 - ya = regs.ya; - //overflow set if quotient >= 256 - regs.p.v = (regs.y >= regs.x); - regs.p.h = ((regs.y & 15) >= (regs.x & 15)); - if(regs.y < (regs.x << 1)) { - //if quotient is <= 511 (will fit into 9-bit result) - regs.a = ya / regs.x; - regs.y = ya % regs.x; - } else { - //otherwise, the quotient won't fit into regs.p.v + regs.a - //this emulates the odd behavior of the S-SMP in this case - regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x); - regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x); - } - //result is set based on a (quotient) only - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); - break; - case 124: - regs.a = (regs.a >> 4) | (regs.a << 4); - break; - case 125: - regs.p.n = regs.a & 0x80; - break; - case 126: - regs.p.z = regs.a == 0; - break; - case 127: - regs.p.i = 1; - break; - case 128: - regs.a = op_sbc(regs.a, rd); - break; - case 129: - wr = op_sbc(wr, rd); - break; - case 130: - regs.p.c = (rd & (1 << bit)); - break; - case 131: - rd = op_inc(rd); - break; - case 132: - regs.a = op_readsp(); - break; - case 133: - op_writedp(regs.x++, regs.a); - break; - case 134: - if(regs.p.c != 1) op_next(); - break; - case 135: - regs.ya = op_ldw(regs.ya, rd); - break; - case 136: - r = op_inc(r); - break; - case 137: - regs.s = regs.x; - break; - case 138: - //!!MULTI1 - if(!regs.p.c || (regs.a) > 0x99) { - regs.a -= 0x60; - regs.p.c = 0; - } - if(!regs.p.h || (regs.a & 15) > 0x09) { - regs.a -= 0x06; - } - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); - break; - case 139: - regs.a = op_readdp(regs.x++); - break; - case 140: - op_readdp(dp); - break; - case 141: - op_writedp(dp, regs.a); - break; - case 142: - op_write(dp, regs.a); - break; - case 143: - op_readdp(regs.x); - break; - case 144: - op_writedp(regs.x, regs.a); - break; - case 145: - sp = op_readpc() + regs.x; - break; - case 146: - dp.l = op_readdp(sp++); - break; - case 147: - dp.h = op_readdp(sp++); - break; - case 148: - op_write(dp, regs.x); - break; - case 149: - rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - break; - case 150: - op_writedp(dp, regs.y); - break; - case 151: - op_write(dp, regs.y); - break; - case 152: - regs.x = op_ld(regs.x, rd); - break; - case 153: - regs.x = op_readsp(); - break; - case 154: - //!!MULTI2 - ya = regs.y * regs.a; - regs.a = ya; - regs.y = ya >> 8; - //result is set based on y (high-byte) only - regs.p.n = (regs.y & 0x80); - regs.p.z = (regs.y == 0); - break; - case 155: - if(regs.p.z != 0) op_next(); - break; - case 156: - dp += regs.y; - break; - case 157: - op_writedp(dp, regs.x); - break; - case 158: - dp = op_readpc() + regs.y; - break; - case 159: - op_writedp(dp++, regs.a); - break; - case 160: - op_writedp(dp++, regs.y); - break; - case 161: - regs.y = op_dec(regs.y); - break; - case 162: - regs.a = regs.y; - break; - case 163: - sp = op_readdp(dp + regs.x); - break; - case 164: - //!!MULTI3 - if(regs.p.c || (regs.a) > 0x99) { - regs.a += 0x60; - regs.p.c = 1; - } - if(regs.p.h || (regs.a & 15) > 0x09) { - regs.a += 0x06; - } - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); - break; - case 165: - regs.p.v = 0; - break; - case 166: - regs.p.h = 0; - break; - case 167: - regs.a = op_ld(regs.a, rd); - break; - case 168: - rd ^= 1 << bit; - break; - case 169: - regs.p.c = !regs.p.c; - break; - case 170: - regs.y = op_readsp(); - break; - case 171: - uindex = -1; //!!REPEAT - break; - case 172: - if(regs.p.z != 1) op_next(); - break; - case 173: - rd = op_readdp(dp + regs.y); - break; - case 174: - regs.y = op_inc(regs.y); - break; - case 175: - regs.y = regs.a; - break; - case 176: - regs.p.n = (regs.y & 0x80); - break; - case 177: - regs.p.z = (regs.y == 0); - break; - case 178: - if(--regs.y == 0) op_next(); - break; - } - uindex++; -} diff --git a/libsnes/s_cpu_coregen/Generex/bin/Debug/uops.cpp b/libsnes/s_cpu_coregen/Generex/bin/Debug/uops.cpp deleted file mode 100644 index e39e36c719..0000000000 --- a/libsnes/s_cpu_coregen/Generex/bin/Debug/uops.cpp +++ /dev/null @@ -1,3111 +0,0 @@ -// case 0x00: return op_nop(); -// void SMPcore::op_nop() { -{ - 1, // op_io(); - 2, // //!!NEXT -}, -// case 0x01: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x02: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x03: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x04: return op_read_dp<&SMPcore::op_or>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x05: return op_read_addr<&SMPcore::op_or>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x06: return op_read_ix<&SMPcore::op_or>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x07: return op_read_idpx<&SMPcore::op_or>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x08: return op_read_const<&SMPcore::op_or>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x09: return op_write_dp_dp<&SMPcore::op_or>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 29, // wr = op_or(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x0a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 1, // op_io(); - 33, // regs.p.c |= (rd & (1 << bit)) ^ 0; - 2, // //!!NEXT -}, -// case 0x0b: return op_adjust_dp<&SMPcore::op_asl>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 34, // rd = op_asl(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x0c: return op_adjust_addr<&SMPcore::op_asl>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 34, // rd = op_asl(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x0d: return op_push(regs.p); -// void SMPcore::op_push(uint8 r) { -{ - 1, // op_io(); - 1, // op_io(); - 37, // op_writesp(regs.p); - 2, // //!!NEXT -}, -// case 0x0e: return op_test_addr(1); -// void SMPcore::op_test_addr(bool set) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 38, // regs.p.n = (regs.a - rd) & 0x80; - 39, // regs.p.z = (regs.a - rd) == 0; - 40, // op_read(dp); - 41, // op_write(dp, rd | regs.a); - 2, // //!!NEXT -}, -// case 0x0f: return op_brk(); -// void SMPcore::op_brk() { -{ - 42, // rd.l = op_read(0xffde); - 43, // rd.h = op_read(0xffdf); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 37, // op_writesp(regs.p); - 8, // regs.pc = rd; - 44, // regs.p.b = 1; - 45, // regs.p.i = 0; - 2, // //!!NEXT -}, -// case 0x10: return op_branch(regs.p.n == 0); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 46, // if(regs.p.n != 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x11: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x12: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x13: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x14: return op_read_dpi<&SMPcore::op_or>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x15: return op_read_addri<&SMPcore::op_or>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x16: return op_read_addri<&SMPcore::op_or>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x17: return op_read_idpy<&SMPcore::op_or>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x18: return op_write_dp_const<&SMPcore::op_or>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 29, // wr = op_or(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x19: return op_write_ix_iy<&SMPcore::op_or>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 29, // wr = op_or(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0x1a: return op_adjust_dpw(-1); -// void SMPcore::op_adjust_dpw(signed n) { -{ - 9, // dp = op_readpc(); - 54, // rd.w = op_readdp(dp) - 1; - 55, // op_writedp(dp++, rd.l); - 56, // rd.h += op_readdp(dp); - 57, // op_writedp(dp++, rd.h); - 58, // regs.p.n = rd & 0x8000; - 59, // regs.p.z = rd == 0; - 2, // //!!NEXT -}, -// case 0x1b: return op_adjust_dpx<&SMPcore::op_asl>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 34, // rd = op_asl(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x1c: return op_adjust<&SMPcore::op_asl>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 61, // regs.a = op_asl(regs.a); - 2, // //!!NEXT -}, -// case 0x1d: return op_adjust<&SMPcore::op_dec>(regs.x); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 62, // regs.x = op_dec(regs.x); - 2, // //!!NEXT -}, -// case 0x1e: return op_read_addr<&SMPcore::op_cmp>(regs.x); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 63, // regs.x = op_cmp(regs.x, rd); - 2, // //!!NEXT -}, -// case 0x1f: return op_jmp_iaddrx(); -// void SMPcore::op_jmp_iaddrx() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 64, // dp += regs.x; - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x20: return op_set_flag(regs.p.p, 0); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 65, // regs.p.p = 0; - 2, // //!!NEXT -}, -// case 0x21: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x22: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x23: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x24: return op_read_dp<&SMPcore::op_and>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x25: return op_read_addr<&SMPcore::op_and>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x26: return op_read_ix<&SMPcore::op_and>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x27: return op_read_idpx<&SMPcore::op_and>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x28: return op_read_const<&SMPcore::op_and>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x29: return op_write_dp_dp<&SMPcore::op_and>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 67, // wr = op_and(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x2a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 1, // op_io(); - 68, // regs.p.c |= (rd & (1 << bit)) ^ 1; - 2, // //!!NEXT -}, -// case 0x2b: return op_adjust_dp<&SMPcore::op_rol>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 69, // rd = op_rol(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x2c: return op_adjust_addr<&SMPcore::op_rol>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 69, // rd = op_rol(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x2d: return op_push(regs.a); -// void SMPcore::op_push(uint8 r) { -{ - 1, // op_io(); - 1, // op_io(); - 70, // op_writesp(regs.a); - 2, // //!!NEXT -}, -// case 0x2e: return op_bne_dp(); -// void SMPcore::op_bne_dp() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 71, // if(regs.a == sp) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x2f: return op_branch(true); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x30: return op_branch(regs.p.n == 1); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 72, // if(regs.p.n != 1) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x31: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x32: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x33: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x34: return op_read_dpi<&SMPcore::op_and>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x35: return op_read_addri<&SMPcore::op_and>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x36: return op_read_addri<&SMPcore::op_and>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x37: return op_read_idpy<&SMPcore::op_and>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x38: return op_write_dp_const<&SMPcore::op_and>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 67, // wr = op_and(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x39: return op_write_ix_iy<&SMPcore::op_and>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 67, // wr = op_and(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0x3a: return op_adjust_dpw(+1); -// void SMPcore::op_adjust_dpw(signed n) { -{ - 9, // dp = op_readpc(); - 73, // rd.w = op_readdp(dp) + 1; - 55, // op_writedp(dp++, rd.l); - 56, // rd.h += op_readdp(dp); - 57, // op_writedp(dp++, rd.h); - 58, // regs.p.n = rd & 0x8000; - 59, // regs.p.z = rd == 0; - 2, // //!!NEXT -}, -// case 0x3b: return op_adjust_dpx<&SMPcore::op_rol>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 69, // rd = op_rol(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x3c: return op_adjust<&SMPcore::op_rol>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 74, // regs.a = op_rol(regs.a); - 2, // //!!NEXT -}, -// case 0x3d: return op_adjust<&SMPcore::op_inc>(regs.x); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 75, // regs.x = op_inc(regs.x); - 2, // //!!NEXT -}, -// case 0x3e: return op_read_dp<&SMPcore::op_cmp>(regs.x); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 63, // regs.x = op_cmp(regs.x, rd); - 2, // //!!NEXT -}, -// case 0x3f: return op_jsr_addr(); -// void SMPcore::op_jsr_addr() { -{ - 76, // rd.l = op_readpc(); - 77, // rd.h = op_readpc(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x40: return op_set_flag(regs.p.p, 1); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 78, // regs.p.p = 1; - 2, // //!!NEXT -}, -// case 0x41: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x42: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x43: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x44: return op_read_dp<&SMPcore::op_eor>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x45: return op_read_addr<&SMPcore::op_eor>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x46: return op_read_ix<&SMPcore::op_eor>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x47: return op_read_idpx<&SMPcore::op_eor>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x48: return op_read_const<&SMPcore::op_eor>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x49: return op_write_dp_dp<&SMPcore::op_eor>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 80, // wr = op_eor(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x4a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 81, // regs.p.c &= (rd & (1 << bit)) ^ 0; - 2, // //!!NEXT -}, -// case 0x4b: return op_adjust_dp<&SMPcore::op_lsr>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 82, // rd = op_lsr(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x4c: return op_adjust_addr<&SMPcore::op_lsr>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 82, // rd = op_lsr(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x4d: return op_push(regs.x); -// void SMPcore::op_push(uint8 r) { -{ - 1, // op_io(); - 1, // op_io(); - 83, // op_writesp(regs.x); - 2, // //!!NEXT -}, -// case 0x4e: return op_test_addr(0); -// void SMPcore::op_test_addr(bool set) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 38, // regs.p.n = (regs.a - rd) & 0x80; - 39, // regs.p.z = (regs.a - rd) == 0; - 40, // op_read(dp); - 84, // op_write(dp, rd & ~regs.a); - 2, // //!!NEXT -}, -// case 0x4f: return op_jsp_dp(); -// void SMPcore::op_jsp_dp() { -{ - 13, // rd = op_readpc(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 85, // regs.pc = 0xff00 | rd; - 2, // //!!NEXT -}, -// case 0x50: return op_branch(regs.p.v == 0); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 86, // if(regs.p.v != 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x51: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x52: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x53: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x54: return op_read_dpi<&SMPcore::op_eor>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x55: return op_read_addri<&SMPcore::op_eor>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x56: return op_read_addri<&SMPcore::op_eor>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x57: return op_read_idpy<&SMPcore::op_eor>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x58: return op_write_dp_const<&SMPcore::op_eor>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 80, // wr = op_eor(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x59: return op_write_ix_iy<&SMPcore::op_eor>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 80, // wr = op_eor(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0x5a: return op_read_dpw<&SMPcore::op_cpw>(); -// void SMPcore::op_read_dpw() { -{ - 9, // dp = op_readpc(); - 87, // rd.l = op_readdp(dp++); - 88, // rd.h = op_readdp(dp++); - 89, // regs.ya = op_cpw(regs.ya, rd); - 2, // //!!NEXT -}, -// case 0x5b: return op_adjust_dpx<&SMPcore::op_lsr>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 82, // rd = op_lsr(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x5c: return op_adjust<&SMPcore::op_lsr>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 90, // regs.a = op_lsr(regs.a); - 2, // //!!NEXT -}, -// case 0x5d: return op_transfer(regs.a, regs.x); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 91, // regs.x = regs.a; - 92, // regs.p.n = (regs.x & 0x80); - 93, // regs.p.z = (regs.x == 0); - 2, // //!!NEXT -}, -// case 0x5e: return op_read_addr<&SMPcore::op_cmp>(regs.y); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 94, // regs.y = op_cmp(regs.y, rd); - 2, // //!!NEXT -}, -// case 0x5f: return op_jmp_addr(); -// void SMPcore::op_jmp_addr() { -{ - 76, // rd.l = op_readpc(); - 77, // rd.h = op_readpc(); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x60: return op_set_flag(regs.p.c, 0); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 95, // regs.p.c = 0; - 2, // //!!NEXT -}, -// case 0x61: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x62: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x63: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x64: return op_read_dp<&SMPcore::op_cmp>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x65: return op_read_addr<&SMPcore::op_cmp>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x66: return op_read_ix<&SMPcore::op_cmp>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x67: return op_read_idpx<&SMPcore::op_cmp>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x68: return op_read_const<&SMPcore::op_cmp>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x69: return op_write_dp_dp<&SMPcore::op_cmp>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 97, // wr = op_cmp(wr, rd); - 1, // op_io(); - 2, // //!!NEXT -}, -// case 0x6a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 98, // regs.p.c &= (rd & (1 << bit)) ^ 1; - 2, // //!!NEXT -}, -// case 0x6b: return op_adjust_dp<&SMPcore::op_ror>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 99, // rd = op_ror(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x6c: return op_adjust_addr<&SMPcore::op_ror>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 99, // rd = op_ror(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x6d: return op_push(regs.y); -// void SMPcore::op_push(uint8 r) { -{ - 1, // op_io(); - 1, // op_io(); - 100, // op_writesp(regs.y); - 2, // //!!NEXT -}, -// case 0x6e: return op_bne_dpdec(); -// void SMPcore::op_bne_dpdec() { -{ - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 101, // op_writedp(dp, --wr); - 13, // rd = op_readpc(); - 102, // if(wr == 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x6f: return op_rts(); -// void SMPcore::op_rts() { -{ - 103, // rd.l = op_readsp(); - 104, // rd.h = op_readsp(); - 1, // op_io(); - 1, // op_io(); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x70: return op_branch(regs.p.v == 1); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 105, // if(regs.p.v != 1) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x71: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x72: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x73: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x74: return op_read_dpi<&SMPcore::op_cmp>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x75: return op_read_addri<&SMPcore::op_cmp>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x76: return op_read_addri<&SMPcore::op_cmp>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x77: return op_read_idpy<&SMPcore::op_cmp>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x78: return op_write_dp_const<&SMPcore::op_cmp>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 97, // wr = op_cmp(wr, rd); - 1, // op_io(); - 2, // //!!NEXT -}, -// case 0x79: return op_write_ix_iy<&SMPcore::op_cmp>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 97, // wr = op_cmp(wr, rd); - 1, // op_io(); - 2, // //!!NEXT -}, -// case 0x7a: return op_read_dpw<&SMPcore::op_adw>(); -// void SMPcore::op_read_dpw() { -{ - 9, // dp = op_readpc(); - 87, // rd.l = op_readdp(dp++); - 1, // op_io(); - 88, // rd.h = op_readdp(dp++); - 106, // regs.ya = op_adw(regs.ya, rd); - 2, // //!!NEXT -}, -// case 0x7b: return op_adjust_dpx<&SMPcore::op_ror>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 99, // rd = op_ror(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x7c: return op_adjust<&SMPcore::op_ror>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 107, // regs.a = op_ror(regs.a); - 2, // //!!NEXT -}, -// case 0x7d: return op_transfer(regs.x, regs.a); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 108, // regs.a = regs.x; - 109, // regs.p.n = (regs.a & 0x80); - 110, // regs.p.z = (regs.a == 0); - 2, // //!!NEXT -}, -// case 0x7e: return op_read_dp<&SMPcore::op_cmp>(regs.y); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 94, // regs.y = op_cmp(regs.y, rd); - 2, // //!!NEXT -}, -// case 0x7f: return op_rti(); -// void SMPcore::op_rti() { -{ - 111, // regs.p = op_readsp(); - 103, // rd.l = op_readsp(); - 104, // rd.h = op_readsp(); - 1, // op_io(); - 1, // op_io(); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x80: return op_set_flag(regs.p.c, 1); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 112, // regs.p.c = 1; - 2, // //!!NEXT -}, -// case 0x81: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x82: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x83: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x84: return op_read_dp<&SMPcore::op_adc>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x85: return op_read_addr<&SMPcore::op_adc>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x86: return op_read_ix<&SMPcore::op_adc>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x87: return op_read_idpx<&SMPcore::op_adc>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x88: return op_read_const<&SMPcore::op_adc>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x89: return op_write_dp_dp<&SMPcore::op_adc>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 114, // wr = op_adc(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x8a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 1, // op_io(); - 115, // regs.p.c ^= (bool)(rd & (1 << bit)); - 2, // //!!NEXT -}, -// case 0x8b: return op_adjust_dp<&SMPcore::op_dec>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 116, // rd = op_dec(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x8c: return op_adjust_addr<&SMPcore::op_dec>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 116, // rd = op_dec(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x8d: return op_read_const<&SMPcore::op_ld>(regs.y); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 117, // regs.y = op_ld(regs.y, rd); - 2, // //!!NEXT -}, -// case 0x8e: return op_plp(); -// void SMPcore::op_plp() { -{ - 1, // op_io(); - 1, // op_io(); - 111, // regs.p = op_readsp(); - 2, // //!!NEXT -}, -// case 0x8f: return op_write_dp_const<&SMPcore::op_st>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 118, // wr = op_st(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x90: return op_branch(regs.p.c == 0); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 119, // if(regs.p.c != 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x91: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x92: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x93: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x94: return op_read_dpi<&SMPcore::op_adc>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x95: return op_read_addri<&SMPcore::op_adc>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x96: return op_read_addri<&SMPcore::op_adc>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x97: return op_read_idpy<&SMPcore::op_adc>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x98: return op_write_dp_const<&SMPcore::op_adc>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 114, // wr = op_adc(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x99: return op_write_ix_iy<&SMPcore::op_adc>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 114, // wr = op_adc(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0x9a: return op_read_dpw<&SMPcore::op_sbw>(); -// void SMPcore::op_read_dpw() { -{ - 9, // dp = op_readpc(); - 87, // rd.l = op_readdp(dp++); - 1, // op_io(); - 88, // rd.h = op_readdp(dp++); - 120, // regs.ya = op_sbw(regs.ya, rd); - 2, // //!!NEXT -}, -// case 0x9b: return op_adjust_dpx<&SMPcore::op_dec>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 116, // rd = op_dec(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x9c: return op_adjust<&SMPcore::op_dec>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 121, // regs.a = op_dec(regs.a); - 2, // //!!NEXT -}, -// case 0x9d: return op_transfer(regs.s, regs.x); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 122, // regs.x = regs.s; - 92, // regs.p.n = (regs.x & 0x80); - 93, // regs.p.z = (regs.x == 0); - 2, // //!!NEXT -}, -// case 0x9e: return op_div_ya_x(); -// void SMPcore::op_div_ya_x() { -{ - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - //ya = regs.ya; - ////overflow set if quotient >= 256 - //regs.p.v = (regs.y >= regs.x); - //regs.p.h = ((regs.y & 15) >= (regs.x & 15)); - //if(regs.y < (regs.x << 1)) { - ////if quotient is <= 511 (will fit into 9-bit result) - //regs.a = ya / regs.x; - //regs.y = ya % regs.x; - //} else { - ////otherwise, the quotient won't fit into regs.p.v + regs.a - ////this emulates the odd behavior of the S-SMP in this case - //regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x); - //regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x); - //} - ////result is set based on a (quotient) only - //regs.p.n = (regs.a & 0x80); - //regs.p.z = (regs.a == 0); - 123, // //!!MULTI0 - 2, // //!!NEXT -}, -// case 0x9f: return op_xcn(); -// void SMPcore::op_xcn() { -{ - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 124, // regs.a = (regs.a >> 4) | (regs.a << 4); - 125, // regs.p.n = regs.a & 0x80; - 126, // regs.p.z = regs.a == 0; - 2, // //!!NEXT -}, -// case 0xa0: return op_set_flag(regs.p.i, 1); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 1, // op_io(); - 127, // regs.p.i = 1; - 2, // //!!NEXT -}, -// case 0xa1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xa2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xa3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xa4: return op_read_dp<&SMPcore::op_sbc>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa5: return op_read_addr<&SMPcore::op_sbc>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa6: return op_read_ix<&SMPcore::op_sbc>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa7: return op_read_idpx<&SMPcore::op_sbc>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa8: return op_read_const<&SMPcore::op_sbc>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa9: return op_write_dp_dp<&SMPcore::op_sbc>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 129, // wr = op_sbc(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0xaa: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 130, // regs.p.c = (rd & (1 << bit)); - 2, // //!!NEXT -}, -// case 0xab: return op_adjust_dp<&SMPcore::op_inc>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 131, // rd = op_inc(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0xac: return op_adjust_addr<&SMPcore::op_inc>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 131, // rd = op_inc(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0xad: return op_read_const<&SMPcore::op_cmp>(regs.y); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 94, // regs.y = op_cmp(regs.y, rd); - 2, // //!!NEXT -}, -// case 0xae: return op_pull(regs.a); -// void SMPcore::op_pull(uint8 &r) { -{ - 1, // op_io(); - 1, // op_io(); - 132, // regs.a = op_readsp(); - 2, // //!!NEXT -}, -// case 0xaf: return op_sta_ixinc(); -// void SMPcore::op_sta_ixinc() { -{ - 1, // op_io(); - 1, // op_io(); - 133, // op_writedp(regs.x++, regs.a); - 2, // //!!NEXT -}, -// case 0xb0: return op_branch(regs.p.c == 1); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 134, // if(regs.p.c != 1) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xb1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xb2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xb3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xb4: return op_read_dpi<&SMPcore::op_sbc>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xb5: return op_read_addri<&SMPcore::op_sbc>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xb6: return op_read_addri<&SMPcore::op_sbc>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xb7: return op_read_idpy<&SMPcore::op_sbc>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xb8: return op_write_dp_const<&SMPcore::op_sbc>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 129, // wr = op_sbc(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0xb9: return op_write_ix_iy<&SMPcore::op_sbc>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 129, // wr = op_sbc(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0xba: return op_read_dpw<&SMPcore::op_ldw>(); -// void SMPcore::op_read_dpw() { -{ - 9, // dp = op_readpc(); - 87, // rd.l = op_readdp(dp++); - 1, // op_io(); - 88, // rd.h = op_readdp(dp++); - 135, // regs.ya = op_ldw(regs.ya, rd); - 2, // //!!NEXT -}, -// case 0xbb: return op_adjust_dpx<&SMPcore::op_inc>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 131, // rd = op_inc(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0xbc: return op_adjust<&SMPcore::op_inc>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 136, // r = op_inc(r); - 2, // //!!NEXT -}, -// case 0xbd: return op_transfer(regs.x, regs.s); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 137, // regs.s = regs.x; - 2, // //!!NEXT -}, -// case 0xbe: return op_das(); -// void SMPcore::op_das() { -{ - 1, // op_io(); - 1, // op_io(); - //if(!regs.p.c || (regs.a) > 0x99) { - //regs.a -= 0x60; - //regs.p.c = 0; - //} - //if(!regs.p.h || (regs.a & 15) > 0x09) { - //regs.a -= 0x06; - //} - //regs.p.n = (regs.a & 0x80); - //regs.p.z = (regs.a == 0); - 138, // //!!MULTI1 - 2, // //!!NEXT -}, -// case 0xbf: return op_lda_ixinc(); -// void SMPcore::op_lda_ixinc() { -{ - 1, // op_io(); - 139, // regs.a = op_readdp(regs.x++); - 1, // op_io(); - 125, // regs.p.n = regs.a & 0x80; - 126, // regs.p.z = regs.a == 0; - 2, // //!!NEXT -}, -// case 0xc0: return op_set_flag(regs.p.i, 0); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 1, // op_io(); - 45, // regs.p.i = 0; - 2, // //!!NEXT -}, -// case 0xc1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xc2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xc3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xc4: return op_write_dp(regs.a); -// void SMPcore::op_write_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 140, // op_readdp(dp); - 141, // op_writedp(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xc5: return op_write_addr(regs.a); -// void SMPcore::op_write_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xc6: return op_sta_ix(); -// void SMPcore::op_sta_ix() { -{ - 1, // op_io(); - 143, // op_readdp(regs.x); - 144, // op_writedp(regs.x, regs.a); - 2, // //!!NEXT -}, -// case 0xc7: return op_sta_idpx(); -// void SMPcore::op_sta_idpx() { -{ - 145, // sp = op_readpc() + regs.x; - 1, // op_io(); - 146, // dp.l = op_readdp(sp++); - 147, // dp.h = op_readdp(sp++); - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xc8: return op_read_const<&SMPcore::op_cmp>(regs.x); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 63, // regs.x = op_cmp(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xc9: return op_write_addr(regs.x); -// void SMPcore::op_write_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 40, // op_read(dp); - 148, // op_write(dp, regs.x); - 2, // //!!NEXT -}, -// case 0xca: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 1, // op_io(); - 149, // rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0xcb: return op_write_dp(regs.y); -// void SMPcore::op_write_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 140, // op_readdp(dp); - 150, // op_writedp(dp, regs.y); - 2, // //!!NEXT -}, -// case 0xcc: return op_write_addr(regs.y); -// void SMPcore::op_write_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 40, // op_read(dp); - 151, // op_write(dp, regs.y); - 2, // //!!NEXT -}, -// case 0xcd: return op_read_const<&SMPcore::op_ld>(regs.x); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 152, // regs.x = op_ld(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xce: return op_pull(regs.x); -// void SMPcore::op_pull(uint8 &r) { -{ - 1, // op_io(); - 1, // op_io(); - 153, // regs.x = op_readsp(); - 2, // //!!NEXT -}, -// case 0xcf: return op_mul_ya(); -// void SMPcore::op_mul_ya() { -{ - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - //ya = regs.y * regs.a; - //regs.a = ya; - //regs.y = ya >> 8; - ////result is set based on y (high-byte) only - //regs.p.n = (regs.y & 0x80); - //regs.p.z = (regs.y == 0); - 154, // //!!MULTI2 - 2, // //!!NEXT -}, -// case 0xd0: return op_branch(regs.p.z == 0); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 155, // if(regs.p.z != 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xd1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xd2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xd3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xd4: return op_write_dpi(regs.a, regs.x); -// void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 140, // op_readdp(dp); - 141, // op_writedp(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xd5: return op_write_addri(regs.x); -// void SMPcore::op_write_addri(uint8 &i) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 64, // dp += regs.x; - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xd6: return op_write_addri(regs.y); -// void SMPcore::op_write_addri(uint8 &i) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 156, // dp += regs.y; - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xd7: return op_sta_idpy(); -// void SMPcore::op_sta_idpy() { -{ - 26, // sp = op_readpc(); - 146, // dp.l = op_readdp(sp++); - 147, // dp.h = op_readdp(sp++); - 1, // op_io(); - 156, // dp += regs.y; - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xd8: return op_write_dp(regs.x); -// void SMPcore::op_write_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 140, // op_readdp(dp); - 157, // op_writedp(dp, regs.x); - 2, // //!!NEXT -}, -// case 0xd9: return op_write_dpi(regs.x, regs.y); -// void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { -{ - 158, // dp = op_readpc() + regs.y; - 1, // op_io(); - 140, // op_readdp(dp); - 157, // op_writedp(dp, regs.x); - 2, // //!!NEXT -}, -// case 0xda: return op_stw_dp(); -// void SMPcore::op_stw_dp() { -{ - 9, // dp = op_readpc(); - 140, // op_readdp(dp); - 159, // op_writedp(dp++, regs.a); - 160, // op_writedp(dp++, regs.y); - 2, // //!!NEXT -}, -// case 0xdb: return op_write_dpi(regs.y, regs.x); -// void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 140, // op_readdp(dp); - 150, // op_writedp(dp, regs.y); - 2, // //!!NEXT -}, -// case 0xdc: return op_adjust<&SMPcore::op_dec>(regs.y); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 161, // regs.y = op_dec(regs.y); - 2, // //!!NEXT -}, -// case 0xdd: return op_transfer(regs.y, regs.a); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 162, // regs.a = regs.y; - 109, // regs.p.n = (regs.a & 0x80); - 110, // regs.p.z = (regs.a == 0); - 2, // //!!NEXT -}, -// case 0xde: return op_bne_dpx(); -// void SMPcore::op_bne_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 163, // sp = op_readdp(dp + regs.x); - 13, // rd = op_readpc(); - 1, // op_io(); - 71, // if(regs.a == sp) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xdf: return op_daa(); -// void SMPcore::op_daa() { -{ - 1, // op_io(); - 1, // op_io(); - //if(regs.p.c || (regs.a) > 0x99) { - //regs.a += 0x60; - //regs.p.c = 1; - //} - //if(regs.p.h || (regs.a & 15) > 0x09) { - //regs.a += 0x06; - //} - //regs.p.n = (regs.a & 0x80); - //regs.p.z = (regs.a == 0); - 164, // //!!MULTI3 - 2, // //!!NEXT -}, -// case 0xe0: return op_clv(); -// void SMPcore::op_clv() { -{ - 1, // op_io(); - 165, // regs.p.v = 0; - 166, // regs.p.h = 0; - 2, // //!!NEXT -}, -// case 0xe1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xe2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xe3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xe4: return op_read_dp<&SMPcore::op_ld>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe5: return op_read_addr<&SMPcore::op_ld>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe6: return op_read_ix<&SMPcore::op_ld>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe7: return op_read_idpx<&SMPcore::op_ld>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe8: return op_read_const<&SMPcore::op_ld>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe9: return op_read_addr<&SMPcore::op_ld>(regs.x); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 152, // regs.x = op_ld(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xea: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 168, // rd ^= 1 << bit; - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0xeb: return op_read_dp<&SMPcore::op_ld>(regs.y); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 117, // regs.y = op_ld(regs.y, rd); - 2, // //!!NEXT -}, -// case 0xec: return op_read_addr<&SMPcore::op_ld>(regs.y); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 117, // regs.y = op_ld(regs.y, rd); - 2, // //!!NEXT -}, -// case 0xed: return op_cmc(); -// void SMPcore::op_cmc() { -{ - 1, // op_io(); - 1, // op_io(); - 169, // regs.p.c = !regs.p.c; - 2, // //!!NEXT -}, -// case 0xee: return op_pull(regs.y); -// void SMPcore::op_pull(uint8 &r) { -{ - 1, // op_io(); - 1, // op_io(); - 170, // regs.y = op_readsp(); - 2, // //!!NEXT -}, -// case 0xef: return op_wait(); -// void SMPcore::op_wait() { -{ - 1, // op_io(); - 1, // op_io(); - 171, // //!!REPEAT - 2, // //!!NEXT -}, -// case 0xf0: return op_branch(regs.p.z == 1); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 172, // if(regs.p.z != 1) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xf1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xf2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xf3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xf4: return op_read_dpi<&SMPcore::op_ld>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xf5: return op_read_addri<&SMPcore::op_ld>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xf6: return op_read_addri<&SMPcore::op_ld>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xf7: return op_read_idpy<&SMPcore::op_ld>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xf8: return op_read_dp<&SMPcore::op_ld>(regs.x); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 152, // regs.x = op_ld(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xf9: return op_read_dpi<&SMPcore::op_ld>(regs.x, regs.y); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 173, // rd = op_readdp(dp + regs.y); - 152, // regs.x = op_ld(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xfa: return op_write_dp_dp<&SMPcore::op_st>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 118, // wr = op_st(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0xfb: return op_read_dpi<&SMPcore::op_ld>(regs.y, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 117, // regs.y = op_ld(regs.y, rd); - 2, // //!!NEXT -}, -// case 0xfc: return op_adjust<&SMPcore::op_inc>(regs.y); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 174, // regs.y = op_inc(regs.y); - 2, // //!!NEXT -}, -// case 0xfd: return op_transfer(regs.a, regs.y); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 175, // regs.y = regs.a; - 176, // regs.p.n = (regs.y & 0x80); - 177, // regs.p.z = (regs.y == 0); - 2, // //!!NEXT -}, -// case 0xfe: return op_bne_ydec(); -// void SMPcore::op_bne_ydec() { -{ - 13, // rd = op_readpc(); - 1, // op_io(); - 1, // op_io(); - 178, // if(--regs.y == 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xff: return op_wait(); -// void SMPcore::op_wait() { -{ - 1, // op_io(); - 1, // op_io(); - 171, // //!!REPEAT - 2, // //!!NEXT -}, - - - - - - - - - -{ - switch (uop) - { - case 1: - op_io(); - break - case 2: - //!!NEXT - break - case 3: - dp = 0xffde - ((opcode >> 4) << 1); - break - case 4: - rd.l = op_read(dp++); - break - case 5: - rd.h = op_read(dp++); - break - case 6: - op_writesp(regs.pc.h); - break - case 7: - op_writesp(regs.pc.l); - break - case 8: - regs.pc = rd; - break - case 9: - dp = op_readpc(); - break - case 10: - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - break - case 11: - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - break - case 12: - sp = op_readdp(dp); - break - case 13: - rd = op_readpc(); - break - case 14: - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - break - case 15: - regs.pc += (int8)rd; - break - case 16: - rd = op_readdp(dp); - break - case 17: - regs.a = op_or(regs.a, rd); - break - case 18: - dp.l = op_readpc(); - break - case 19: - dp.h = op_readpc(); - break - case 20: - rd = op_read(dp); - break - case 21: - rd = op_readdp(regs.x); - break - case 22: - dp = op_readpc() + regs.x; - break - case 23: - sp.l = op_readdp(dp++); - break - case 24: - sp.h = op_readdp(dp++); - break - case 25: - rd = op_read(sp); - break - case 26: - sp = op_readpc(); - break - case 27: - rd = op_readdp(sp); - break - case 28: - wr = op_readdp(dp); - break - case 29: - wr = op_or(wr, rd); - break - case 30: - op_writedp(dp, wr); - break - case 31: - bit = dp >> 13; - break - case 32: - dp &= 0x1fff; - break - case 33: - regs.p.c |= (rd & (1 << bit)) ^ 0; - break - case 34: - rd = op_asl(rd); - break - case 35: - op_writedp(dp, rd); - break - case 36: - op_write(dp, rd); - break - case 37: - op_writesp(regs.p); - break - case 38: - regs.p.n = (regs.a - rd) & 0x80; - break - case 39: - regs.p.z = (regs.a - rd) == 0; - break - case 40: - op_read(dp); - break - case 41: - op_write(dp, rd | regs.a); - break - case 42: - rd.l = op_read(0xffde); - break - case 43: - rd.h = op_read(0xffdf); - break - case 44: - regs.p.b = 1; - break - case 45: - regs.p.i = 0; - break - case 46: - if(regs.p.n != 0) return; - break - case 47: - rd = op_readdp(dp + regs.x); - break - case 48: - rd = op_read(dp + regs.x); - break - case 49: - rd = op_read(dp + regs.y); - break - case 50: - rd = op_read(sp + regs.y); - break - case 51: - rd = op_readdp(regs.y); - break - case 52: - wr = op_readdp(regs.x); - break - case 53: - op_writedp(regs.x, wr); - break - case 54: - rd.w = op_readdp(dp) - 1; - break - case 55: - op_writedp(dp++, rd.l); - break - case 56: - rd.h += op_readdp(dp); - break - case 57: - op_writedp(dp++, rd.h); - break - case 58: - regs.p.n = rd & 0x8000; - break - case 59: - regs.p.z = rd == 0; - break - case 60: - op_writedp(dp + regs.x, rd); - break - case 61: - regs.a = op_asl(regs.a); - break - case 62: - regs.x = op_dec(regs.x); - break - case 63: - regs.x = op_cmp(regs.x, rd); - break - case 64: - dp += regs.x; - break - case 65: - regs.p.p = 0; - break - case 66: - regs.a = op_and(regs.a, rd); - break - case 67: - wr = op_and(wr, rd); - break - case 68: - regs.p.c |= (rd & (1 << bit)) ^ 1; - break - case 69: - rd = op_rol(rd); - break - case 70: - op_writesp(regs.a); - break - case 71: - if(regs.a == sp) return; - break - case 72: - if(regs.p.n != 1) return; - break - case 73: - rd.w = op_readdp(dp) + 1; - break - case 74: - regs.a = op_rol(regs.a); - break - case 75: - regs.x = op_inc(regs.x); - break - case 76: - rd.l = op_readpc(); - break - case 77: - rd.h = op_readpc(); - break - case 78: - regs.p.p = 1; - break - case 79: - regs.a = op_eor(regs.a, rd); - break - case 80: - wr = op_eor(wr, rd); - break - case 81: - regs.p.c &= (rd & (1 << bit)) ^ 0; - break - case 82: - rd = op_lsr(rd); - break - case 83: - op_writesp(regs.x); - break - case 84: - op_write(dp, rd & ~regs.a); - break - case 85: - regs.pc = 0xff00 | rd; - break - case 86: - if(regs.p.v != 0) return; - break - case 87: - rd.l = op_readdp(dp++); - break - case 88: - rd.h = op_readdp(dp++); - break - case 89: - regs.ya = op_cpw(regs.ya, rd); - break - case 90: - regs.a = op_lsr(regs.a); - break - case 91: - regs.x = regs.a; - break - case 92: - regs.p.n = (regs.x & 0x80); - break - case 93: - regs.p.z = (regs.x == 0); - break - case 94: - regs.y = op_cmp(regs.y, rd); - break - case 95: - regs.p.c = 0; - break - case 96: - regs.a = op_cmp(regs.a, rd); - break - case 97: - wr = op_cmp(wr, rd); - break - case 98: - regs.p.c &= (rd & (1 << bit)) ^ 1; - break - case 99: - rd = op_ror(rd); - break - case 100: - op_writesp(regs.y); - break - case 101: - op_writedp(dp, --wr); - break - case 102: - if(wr == 0) return; - break - case 103: - rd.l = op_readsp(); - break - case 104: - rd.h = op_readsp(); - break - case 105: - if(regs.p.v != 1) return; - break - case 106: - regs.ya = op_adw(regs.ya, rd); - break - case 107: - regs.a = op_ror(regs.a); - break - case 108: - regs.a = regs.x; - break - case 109: - regs.p.n = (regs.a & 0x80); - break - case 110: - regs.p.z = (regs.a == 0); - break - case 111: - regs.p = op_readsp(); - break - case 112: - regs.p.c = 1; - break - case 113: - regs.a = op_adc(regs.a, rd); - break - case 114: - wr = op_adc(wr, rd); - break - case 115: - regs.p.c ^= (bool)(rd & (1 << bit)); - break - case 116: - rd = op_dec(rd); - break - case 117: - regs.y = op_ld(regs.y, rd); - break - case 118: - wr = op_st(wr, rd); - break - case 119: - if(regs.p.c != 0) return; - break - case 120: - regs.ya = op_sbw(regs.ya, rd); - break - case 121: - regs.a = op_dec(regs.a); - break - case 122: - regs.x = regs.s; - break - case 123: - //!!MULTI0 - break - case 124: - regs.a = (regs.a >> 4) | (regs.a << 4); - break - case 125: - regs.p.n = regs.a & 0x80; - break - case 126: - regs.p.z = regs.a == 0; - break - case 127: - regs.p.i = 1; - break - case 128: - regs.a = op_sbc(regs.a, rd); - break - case 129: - wr = op_sbc(wr, rd); - break - case 130: - regs.p.c = (rd & (1 << bit)); - break - case 131: - rd = op_inc(rd); - break - case 132: - regs.a = op_readsp(); - break - case 133: - op_writedp(regs.x++, regs.a); - break - case 134: - if(regs.p.c != 1) return; - break - case 135: - regs.ya = op_ldw(regs.ya, rd); - break - case 136: - r = op_inc(r); - break - case 137: - regs.s = regs.x; - break - case 138: - //!!MULTI1 - break - case 139: - regs.a = op_readdp(regs.x++); - break - case 140: - op_readdp(dp); - break - case 141: - op_writedp(dp, regs.a); - break - case 142: - op_write(dp, regs.a); - break - case 143: - op_readdp(regs.x); - break - case 144: - op_writedp(regs.x, regs.a); - break - case 145: - sp = op_readpc() + regs.x; - break - case 146: - dp.l = op_readdp(sp++); - break - case 147: - dp.h = op_readdp(sp++); - break - case 148: - op_write(dp, regs.x); - break - case 149: - rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - break - case 150: - op_writedp(dp, regs.y); - break - case 151: - op_write(dp, regs.y); - break - case 152: - regs.x = op_ld(regs.x, rd); - break - case 153: - regs.x = op_readsp(); - break - case 154: - //!!MULTI2 - break - case 155: - if(regs.p.z != 0) return; - break - case 156: - dp += regs.y; - break - case 157: - op_writedp(dp, regs.x); - break - case 158: - dp = op_readpc() + regs.y; - break - case 159: - op_writedp(dp++, regs.a); - break - case 160: - op_writedp(dp++, regs.y); - break - case 161: - regs.y = op_dec(regs.y); - break - case 162: - regs.a = regs.y; - break - case 163: - sp = op_readdp(dp + regs.x); - break - case 164: - //!!MULTI3 - break - case 165: - regs.p.v = 0; - break - case 166: - regs.p.h = 0; - break - case 167: - regs.a = op_ld(regs.a, rd); - break - case 168: - rd ^= 1 << bit; - break - case 169: - regs.p.c = !regs.p.c; - break - case 170: - regs.y = op_readsp(); - break - case 171: - //!!REPEAT - break - case 172: - if(regs.p.z != 1) return; - break - case 173: - rd = op_readdp(dp + regs.y); - break - case 174: - regs.y = op_inc(regs.y); - break - case 175: - regs.y = regs.a; - break - case 176: - regs.p.n = (regs.y & 0x80); - break - case 177: - regs.p.z = (regs.y == 0); - break - case 178: - if(--regs.y == 0) return; - break - } -} diff --git a/libsnes/s_cpu_coregen/readme.txt b/libsnes/s_cpu_coregen/readme.txt deleted file mode 100644 index d35e246030..0000000000 --- a/libsnes/s_cpu_coregen/readme.txt +++ /dev/null @@ -1,13 +0,0 @@ -this code was used to aid in the creation of r4203. it's not really production quality, and two generate steps are involved with manual -editing inbetween each. - -rough outline of functionality: - -1. in Program.cs, uncomment "PHASE 1" and comment "PHASE 2". - run the program and redirect stdout to "out.cpp" -2. edit "out.cpp" to produce "fixed.cpp". as fixed.cpp is included - in the svn commit, i won't provide any other details. -3. in Program.cs, uncomment "PHASE 2" and comment "PHASE 1". - run the program and redirect stdout. to "uop.cpp" -4. fix up "uop.cpp" by hand, and integrate it into the bsnes source tree. - diff --git a/libsnes/vs2015/libsnes.sln b/libsnes/vs2015/libsnes.sln deleted file mode 100644 index cdb4be35b3..0000000000 --- a/libsnes/vs2015/libsnes.sln +++ /dev/null @@ -1,28 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.22823.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsnes", "libsnes.vcxproj", "{488B77AD-58DF-4E01-9329-67B20D486860}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug-Compatibility|x86 = Debug-Compatibility|x86 - Debug-Performance|x86 = Debug-Performance|x86 - Release-Compatibility|x86 = Release-Compatibility|x86 - Release-Performance|x86 = Release-Performance|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {488B77AD-58DF-4E01-9329-67B20D486860}.Debug-Compatibility|x86.ActiveCfg = Debug-Compatibility|Win32 - {488B77AD-58DF-4E01-9329-67B20D486860}.Debug-Compatibility|x86.Build.0 = Debug-Compatibility|Win32 - {488B77AD-58DF-4E01-9329-67B20D486860}.Debug-Performance|x86.ActiveCfg = Debug-Performance|Win32 - {488B77AD-58DF-4E01-9329-67B20D486860}.Debug-Performance|x86.Build.0 = Debug-Performance|Win32 - {488B77AD-58DF-4E01-9329-67B20D486860}.Release-Compatibility|x86.ActiveCfg = Release-Compatibility|Win32 - {488B77AD-58DF-4E01-9329-67B20D486860}.Release-Compatibility|x86.Build.0 = Release-Compatibility|Win32 - {488B77AD-58DF-4E01-9329-67B20D486860}.Release-Performance|x86.ActiveCfg = Release-Performance|Win32 - {488B77AD-58DF-4E01-9329-67B20D486860}.Release-Performance|x86.Build.0 = Release-Performance|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/libsnes/vs2015/libsnes.vcxproj b/libsnes/vs2015/libsnes.vcxproj deleted file mode 100644 index 16c231b132..0000000000 --- a/libsnes/vs2015/libsnes.vcxproj +++ /dev/null @@ -1,822 +0,0 @@ - - - - - Debug-Compatibility - Win32 - - - Debug-Performance - Win32 - - - Release-Compatibility - Win32 - - - Release-Performance - Win32 - - - - {488B77AD-58DF-4E01-9329-67B20D486860} - libsnes - 8.1 - 8.1 - - - - DynamicLibrary - true - v140_xp - NotSet - - - DynamicLibrary - true - v140_xp - NotSet - - - DynamicLibrary - false - v140_xp - true - NotSet - - - DynamicLibrary - false - v140_xp - true - NotSet - - - - - - - - - - - - - - - - - - - - - ..\..\output\dll\ - libsneshawk-32-performance - .obj\$(Configuration)\ - - - ..\..\output\dll\ - libsneshawk-32-compatibility - .obj\$(Configuration)\ - - - libsneshawk-32-compatibility - ..\..\output\dll\ - .obj\$(Configuration)\ - - - libsneshawk-32-performance - ..\..\output\dll\ - .obj\$(Configuration)\ - - - - Level3 - Disabled - false - $(ProjectDir)../bsnes - HOOKS;BIZHAWK;PROFILE_PERFORMANCE;GAMEBOY;%(PreprocessorDefinitions) - true - false - /Zc:threadSafeInit- %(AdditionalOptions) - - - true - Windows - - - - - Level3 - Disabled - false - $(ProjectDir)../bsnes - HOOKS;BIZHAWK;PROFILE_COMPATIBILITY;GAMEBOY;%(PreprocessorDefinitions) - true - false - /Zc:threadSafeInit- %(AdditionalOptions) - - - true - Windows - - - - - Level3 - Full - true - false - true - $(ProjectDir)../bsnes - HOOKS;BIZHAWK;PROFILE_PERFORMANCE;GAMEBOY;%(PreprocessorDefinitions) - None - AnySuitable - Speed - true - StreamingSIMDExtensions - Fast - MultiThreaded - /Zc:threadSafeInit- %(AdditionalOptions) - - - true - true - true - Windows - - - upx -9 $(TargetPath) - - - - - Level3 - Full - true - false - true - $(ProjectDir)../bsnes - HOOKS;BIZHAWK;PROFILE_COMPATIBILITY;GAMEBOY;%(PreprocessorDefinitions) - None - MultiThreaded - Speed - true - AnySuitable - /Zc:threadSafeInit- %(AdditionalOptions) - StreamingSIMDExtensions - Fast - - - true - true - true - Windows - - - upx -9 $(TargetPath) - - - - - - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - - - - - - - - - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - true - true - true - true - - - true - true - true - true - - - true - true - - - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - - - true - true - true - true - - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - - - - - - - - - - - true - true - true - true - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - false - true - false - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - true - true - true - true - - - true - true - true - true - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - false - true - false - - - true - true - true - true - - - - - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - - - - - - - - - - (); - foreach( var item in ItemList ) - { - var filename = item.GetMetadata("Filename"); - - //assign reused filenames to increasing numbers - //assign previously unused filenames to 0 - int assignment = 0; - if(assignmentMap.TryGetValue(filename, out assignment)) - assignmentMap[filename] = ++assignment; - else - assignmentMap[filename] = 0; - - var thisFileOutdir = Path.Combine(OutputDir,assignment.ToString()) + "/"; //take care it ends in / so /Fo knows it's a directory and not a filename - item.SetMetadata( "ObjectFileName", thisFileOutdir ); - } - - OutputItemList = ItemList; - ItemList = new Microsoft.Build.Framework.ITaskItem[0]; - - ]]> - - - - - - - - - - - - - - \ No newline at end of file diff --git a/libsnes/vs2015/libsnes.vcxproj.filters b/libsnes/vs2015/libsnes.vcxproj.filters deleted file mode 100644 index 2acf8d1ca3..0000000000 --- a/libsnes/vs2015/libsnes.vcxproj.filters +++ /dev/null @@ -1,593 +0,0 @@ - - - - - {6321d017-eb1b-4c32-8ad6-2a444cd349f6} - - - {b524d91d-4f81-4c11-a85c-b3b4d12ae8cf} - - - {c08353ee-b185-43d3-bbcf-0b6ec3e90320} - - - {408560e5-f6fb-4bb3-a9d5-d4142a1320f0} - - - {a38518d2-1cce-44e8-a3a5-0f861d87493e} - - - {9f9acb28-fdaa-49d0-90be-c1420ab16873} - - - {289226f8-df84-498f-9ae4-aa56bd12b59c} - - - {55ee4b4b-d81c-44a1-9aaa-acd145d22f7a} - - - {2393d351-a00c-4786-ad11-445f1a1f41b1} - - - {7c6789fc-4c2c-4d46-9f37-f0ca1d3b1040} - - - {7f99b945-63a1-4516-8b55-97e752e836f2} - - - {b2c7c754-bd74-4418-948b-2af3c799d015} - - - {17456ecf-3890-4e53-ab34-0e2522355065} - - - {ba2a4779-7d10-43e6-bfc9-132ea211483c} - - - {118fed9b-6135-4bb5-9e24-eea11c4af00c} - - - {82b154b9-d01b-413a-8f8b-dd12999827dd} - - - {a3e5a31b-5b10-40d1-8805-abd490396997} - - - {72824eb5-fe38-4ef8-908a-58c890560e65} - - - {e219cd9c-1e92-4ab1-bf0a-ce3501000807} - - - {613fc7f9-2c45-429f-b23d-6d49079d7891} - - - {2b5e8fde-1d52-4681-a15c-f06b7926fe82} - - - {b4be7383-80a1-4237-8d43-01e15867afc2} - - - {11dfb660-4987-46c8-8972-7342e656c555} - - - {9dd57f5e-1002-48d7-81d3-529c022996bd} - - - {944e3046-20a8-4271-9974-15718a3aa3cd} - - - {b5eedfaf-3238-4e31-814b-f59d2ad6c617} - - - {bb93bc7a-e90a-4e11-a0c0-84e26dc7f42a} - - - {7887aa9a-01a4-4152-a285-bb4ecaa0b716} - - - {009324b7-7605-4e55-b73d-68131f4a8845} - - - {a9b576a3-938b-4e09-86e7-4cda6e5deba5} - - - {4c4832de-b4f0-488d-980b-a77ebce05527} - - - {fb725aa0-6ff3-4b25-bf45-ae28fc3aed4a} - - - {2a37b3c4-7b36-48e5-b201-25b1e81d8751} - - - {574e46b2-63b2-491a-8ae1-0942b01d6cd2} - - - {b4ec7434-0582-4463-8e08-c3e9eb99d005} - - - {34858db2-a967-43a1-ac48-4de7b5db5a6b} - - - {e7a4951f-47f4-44e1-a1ac-c29484c89c33} - - - {da1501bf-c0ce-4e34-a9b5-80b369db33dc} - - - {adbd7da4-de16-44d3-9ba4-15841768d4fe} - - - {9cabccb5-50ec-491e-b48f-ca8b88a546c8} - - - {f008c454-28d4-40c7-9289-b3f2dd19a762} - - - {434d7eb5-d533-4917-8b38-cca08d569ed5} - - - {a6600a1f-d587-4a88-966e-11f7a2ee2e3e} - - - {000a6753-2b90-45fa-845d-c7b364a37c35} - - - {b8ea9101-3f2f-4631-8bfe-4011bebc8e0e} - - - {1d1cf6c9-9e1b-402c-b1cc-7ed8866092e7} - - - {be676f5c-dcb3-4a39-911c-4e102dfa25d8} - - - {ebb8bc23-969e-4273-bada-413a29d6af3e} - - - {f06ef20e-c749-4f16-81d3-f88d96b659bc} - - - {abb9e273-8335-47ae-b389-76395d57844c} - - - {b17bd430-7d56-4e93-b78c-d41b2c6f3d85} - - - {1e74e41b-9992-4e18-b2a9-91827d350402} - - - {f1711f3e-853c-4ec3-bd3d-2c21d85c65bd} - - - {a2db2d0e-68ec-4fa0-91fc-2bcc8ac33d32} - - - {70659d45-e958-48ff-94a3-8a57aa76dd61} - - - - - base - - - gameboy - - - gameboy\apu - - - gameboy\cheat - - - snes - - - snes - - - snes - - - snes - - - target-libsnes - - - snes\interface - - - snes\cpu\core\disassembler - - - snes\cpu\core - - - snes\cpu\core - - - snes\cpu\core - - - snes\cpu - - - snes\cartridge - - - snes\cpu\memory - - - snes\alt\cpu - - - snes\alt\smp - - - snes\smp\core - - - snes\smp\core - - - snes\smp\core - - - snes\smp\memory - - - snes\smp\timing - - - snes\smp - - - snes\alt\dsp - - - snes\alt\dsp - - - snes\alt\dsp - - - snes\alt\dsp - - - snes\alt\dsp - - - snes\alt\dsp - - - snes\dsp - - - - - gameboy\apu - - - gameboy\cartridge - - - gameboy\cheat - - - gameboy\cpu - - - gameboy\interface - - - gameboy\lcd - - - gameboy\memory - - - gameboy\scheduler - - - gameboy\system - - - gameboy\video - - - snes\alt\dsp - - - snes\alt\cpu - - - snes\alt\ppu-performance - - - snes\alt\smp - - - snes\cartridge - - - snes\cheat - - - snes\chip\armdsp - - - snes\chip\bsx - - - snes\chip\hitachidsp - - - snes\chip\icd2 - - - snes\chip\link - - - snes\chip\msu1 - - - snes\necdsp - - - snes\chip\nss - - - snes\chip\obc1 - - - snes\chip\sa1 - - - snes\chip\sdd1 - - - snes\chip\spc7110 - - - snes\chip\srtc - - - snes\chip\sufamiturbo - - - snes\chip\superfx - - - snes\config - - - snes\controller - - - snes\cpu - - - snes\dsp - - - snes\interface - - - snes\memory - - - snes\ppu - - - snes\smp - - - snes\system - - - target-libsnes - - - target-libsnes - - - snes\cpu\core - - - snes\alt\ppu-compatibility - - - snes\smp\core - - - snes\cpu\core\disassembler - - - snes\cpu\core - - - snes\cpu\core - - - snes\cpu\core - - - snes\cpu\core - - - snes\cpu\core - - - snes\cpu\core - - - snes\cpu\core - - - snes\cpu\core - - - snes\cpu - - - snes\cartridge - - - snes\cartridge - - - base - - - snes\cpu\memory - - - snes\alt\cpu - - - snes\alt\cpu - - - snes\alt\cpu - - - snes\alt\cpu - - - snes\alt\cpu - - - snes\alt\smp - - - snes\alt\smp - - - snes\alt\smp - - - snes\alt\smp - - - snes\alt\smp - - - snes\alt\smp - - - snes\alt\smp\core - - - snes\alt\smp\core - - - snes\alt\smp\core - - - snes\alt\smp\core - - - snes\alt\smp\core - - - snes\alt\smp\core - - - snes\alt\smp\core - - - snes\alt\smp\core - - - snes\alt\smp\core - - - snes\alt\smp\core - - - snes\alt\smp\core - - - snes\smp\core - - - snes\smp\core - - - snes\smp\core - - - snes\smp\core - - - snes\smp\core - - - snes\smp\memory - - - snes\smp\timing - - - snes\smp - - - snes\smp - - - snes\alt\dsp - - - snes\alt\dsp - - - snes\dsp - - - snes\dsp - - - snes\dsp - - - snes\dsp - - - snes\dsp - - - snes\dsp - - - snes\dsp - - - snes\dsp - - - libco - - - - - snes\alt\smp\core - - - snes\alt\smp\core - - - snes\alt\smp\core - - - snes\alt\smp\core - - - snes\alt\smp\core - - - snes\alt\smp\core - - - \ No newline at end of file diff --git a/libsnes/vs2015/upx.exe b/libsnes/vs2015/upx.exe deleted file mode 100644 index 1c331c703a..0000000000 Binary files a/libsnes/vs2015/upx.exe and /dev/null differ diff --git a/lynx/mingw/Makefile b/lynx/mingw/Makefile index 1ab0e687cf..67cf91df85 100644 --- a/lynx/mingw/Makefile +++ b/lynx/mingw/Makefile @@ -4,7 +4,7 @@ CP = cp MACHINE = $(shell $(CXX) -dumpmachine) ifneq (,$(findstring i686,$(MACHINE))) - ARCH = 32 + $(error 32 bit build no longer supported) else ifneq (,$(findstring x86_64,$(MACHINE))) ARCH = 64 else @@ -19,7 +19,7 @@ LDFLAGS_64 = LDFLAGS = -shared $(LDFLAGS_$(ARCH)) $(CXXFLAGS) DEST_32 = ../../output/dll -DEST_64 = ../../output64/dll +DEST_64 = ../../output/dll SRCS = \ ../c65c02.cpp \ diff --git a/miniz/Makefile b/miniz/Makefile new file mode 100644 index 0000000000..3492702b37 --- /dev/null +++ b/miniz/Makefile @@ -0,0 +1,40 @@ +CXX = gcc +CXXFLAGS = -Wall -O3 -std=c99 -fomit-frame-pointer -Wno-attributes -s + +MACHINE = $(shell $(CXX) -dumpmachine) +ifneq (,$(findstring i686,$(MACHINE))) + ARCH = 32 +else ifneq (,$(findstring x86_64,$(MACHINE))) + ARCH = 64 +else + $(error Unknown arch) +endif + +LDFLAGS_32 = +LDFLAGS_64 = +LDFLAGS = -shared $(LDFLAGS_$(ARCH)) $(CXXFLAGS) + +TARGET = libminiz.dll +RM = rm +CP = cp + +SRCS = miniz.c + +OBJS = $(SRCS:.c=.o) +DEST_32 = ../output/dll +DEST_64 = ../output64/dll + +all: $(TARGET) + +%.o: %.c + $(CXX) -c -o $@ $< $(CXXFLAGS) + +$(TARGET) : $(OBJS) + $(CXX) -o $@ $(LDFLAGS) $(OBJS) + +clean: + $(RM) $(OBJS) + $(RM) $(TARGET) + +install: + $(CP) $(TARGET) $(DEST_$(ARCH)) diff --git a/miniz/example1.c b/miniz/example1.c new file mode 100644 index 0000000000..9b2891b0d8 --- /dev/null +++ b/miniz/example1.c @@ -0,0 +1,105 @@ +// example1.c - Demonstrates miniz.c's compress() and uncompress() functions (same as zlib's). +// Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c. +#include "miniz.c" + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint; + +// The string to compress. +static const char *s_pStr = "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ + "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ + "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ + "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ + "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ + "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ + "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."; + +int main(int argc, char *argv[]) +{ + uint step = 0; + int cmp_status; + uLong src_len = (uLong)strlen(s_pStr); + uLong cmp_len = compressBound(src_len); + uLong uncomp_len = src_len; + uint8 *pCmp, *pUncomp; + uint total_succeeded = 0; + (void)argc, (void)argv; + + printf("miniz.c version: %s\n", MZ_VERSION); + + do + { + // Allocate buffers to hold compressed and uncompressed data. + pCmp = (mz_uint8 *)malloc((size_t)cmp_len); + pUncomp = (mz_uint8 *)malloc((size_t)src_len); + if ((!pCmp) || (!pUncomp)) + { + printf("Out of memory!\n"); + return EXIT_FAILURE; + } + + // Compress the string. + cmp_status = compress(pCmp, &cmp_len, (const unsigned char *)s_pStr, src_len); + if (cmp_status != Z_OK) + { + printf("compress() failed!\n"); + free(pCmp); + free(pUncomp); + return EXIT_FAILURE; + } + + printf("Compressed from %u to %u bytes\n", (mz_uint32)src_len, (mz_uint32)cmp_len); + + if (step) + { + // Purposely corrupt the compressed data if fuzzy testing (this is a very crude fuzzy test). + uint n = 1 + (rand() % 3); + while (n--) + { + uint i = rand() % cmp_len; + pCmp[i] ^= (rand() & 0xFF); + } + } + + // Decompress. + cmp_status = uncompress(pUncomp, &uncomp_len, pCmp, cmp_len); + total_succeeded += (cmp_status == Z_OK); + + if (step) + { + printf("Simple fuzzy test: step %u total_succeeded: %u\n", step, total_succeeded); + } + else + { + if (cmp_status != Z_OK) + { + printf("uncompress failed!\n"); + free(pCmp); + free(pUncomp); + return EXIT_FAILURE; + } + + printf("Decompressed from %u to %u bytes\n", (mz_uint32)cmp_len, (mz_uint32)uncomp_len); + + // Ensure uncompress() returned the expected data. + if ((uncomp_len != src_len) || (memcmp(pUncomp, s_pStr, (size_t)src_len))) + { + printf("Decompression failed!\n"); + free(pCmp); + free(pUncomp); + return EXIT_FAILURE; + } + } + + free(pCmp); + free(pUncomp); + + step++; + + // Keep on fuzzy testing if there's a non-empty command line. + } while (argc >= 2); + + printf("Success.\n"); + return EXIT_SUCCESS; +} diff --git a/miniz/example2.c b/miniz/example2.c new file mode 100644 index 0000000000..78760c3355 --- /dev/null +++ b/miniz/example2.c @@ -0,0 +1,95 @@ +// example2.c - Simple demonstration of miniz.c's ZIP archive API's. +// Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c. +#include "miniz.c" + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint; + +// The string to compress. +static const char *s_pStr = +"MISSION CONTROL I wouldn't worry too much about the computer. First of all, there is still a chance that he is right, despite your tests, and" \ +"if it should happen again, we suggest eliminating this possibility by allowing the unit to remain in place and seeing whether or not it" \ +"actually fails. If the computer should turn out to be wrong, the situation is still not alarming. The type of obsessional error he may be" \ +"guilty of is not unknown among the latest generation of HAL 9000 computers. It has almost always revolved around a single detail, such as" \ +"the one you have described, and it has never interfered with the integrity or reliability of the computer's performance in other areas." \ +"No one is certain of the cause of this kind of malfunctioning. It may be over-programming, but it could also be any number of reasons. In any" \ +"event, it is somewhat analogous to human neurotic behavior. Does this answer your query? Zero-five-three-Zero, MC, transmission concluded."; + +static const char *s_pComment = "This is a comment"; + +int main(int argc, char *argv[]) +{ + uint i; + mz_bool status; + size_t uncomp_size; + mz_zip_archive zip_archive; + void *p; + + printf("miniz.c version: %s\n", MZ_VERSION); + + (void)argc, (void)argv; + + // Append a bunch of text files to test.zip + for (i = 0; i < 50; i++) + { + char archive_filename[64]; + sprintf(archive_filename, "%u.txt", i); + status = mz_zip_add_mem_to_archive_file_in_place("test.zip", archive_filename, s_pStr, strlen(s_pStr), s_pComment, (uint16)strlen(s_pComment), MZ_BEST_COMPRESSION); + if (!status) + { + printf("mz_zip_add_mem_to_archive_file_in_place failed!\n"); + return EXIT_FAILURE; + } + } + + // Now try to open the archive. + memset(&zip_archive, 0, sizeof(zip_archive)); + status = mz_zip_reader_init_file(&zip_archive, "test.zip", 0); + if (!status) + { + printf("mz_zip_reader_init_file() failed!\n"); + return EXIT_FAILURE; + } + + // Get and print information about each file in the archive. + for (i = 0; i < mz_zip_reader_get_num_files(&zip_archive); i++) + { + mz_zip_archive_file_stat file_stat; + if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) + { + printf("mz_zip_reader_file_stat() failed!\n"); + mz_zip_reader_end(&zip_archive); + return EXIT_FAILURE; + } + + printf("Filename: \"%s\", Comment: \"%s\", Uncompressed size: %u, Compressed size: %u\n", file_stat.m_filename, file_stat.m_comment, (uint)file_stat.m_uncomp_size, (uint)file_stat.m_comp_size); + } + + // Try to extract 0.txt to the heap. + p = mz_zip_reader_extract_file_to_heap(&zip_archive, "0.txt", &uncomp_size, 0); + if (!p) + { + printf("mz_zip_reader_extract_file_to_heap() failed!\n"); + mz_zip_reader_end(&zip_archive); + return EXIT_FAILURE; + } + + // Make sure the extraction really succeeded. + if ((uncomp_size != strlen(s_pStr)) || (memcmp(p, s_pStr, strlen(s_pStr)))) + { + printf("mz_zip_reader_extract_file_to_heap() failed to extract the proper data\n"); + free(p); + mz_zip_reader_end(&zip_archive); + return EXIT_FAILURE; + } + + printf("Successfully extracted file \"0.txt\", size %u\n", (uint)uncomp_size); + + // We're done. + free(p); + mz_zip_reader_end(&zip_archive); + + printf("Success.\n"); + return EXIT_SUCCESS; +} diff --git a/miniz/example3.c b/miniz/example3.c new file mode 100644 index 0000000000..924475a559 --- /dev/null +++ b/miniz/example3.c @@ -0,0 +1,268 @@ +// example3.c - Demonstrates how to use miniz.c's deflate() and inflate() functions for simple file compression. +// Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c. +// For simplicity, this example is limited to files smaller than 4GB, but this is not a limitation of miniz.c. +#include "miniz.c" +#include + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint; + +#define my_max(a,b) (((a) > (b)) ? (a) : (b)) +#define my_min(a,b) (((a) < (b)) ? (a) : (b)) + +#define BUF_SIZE (1024 * 1024) +static uint8 s_inbuf[BUF_SIZE]; +static uint8 s_outbuf[BUF_SIZE]; + +int main(int argc, char *argv[]) +{ + const char *pMode; + FILE *pInfile, *pOutfile; + uint infile_size; + int level = Z_BEST_COMPRESSION; + z_stream stream; + int p = 1; + const char *pSrc_filename; + const char *pDst_filename; + long file_loc; + + printf("miniz.c version: %s\n", MZ_VERSION); + + if (argc < 4) + { + printf("Usage: example3 [options] [mode:c or d] infile outfile\n"); + printf("\nModes:\n"); + printf("c - Compresses file infile to a zlib stream in file outfile\n"); + printf("d - Decompress zlib stream in file infile to file outfile\n"); + printf("\nOptions:\n"); + printf("-l[0-10] - Compression level, higher values are slower.\n"); + return EXIT_FAILURE; + } + + while ((p < argc) && (argv[p][0] == '-')) + { + switch (argv[p][1]) + { + case 'l': + { + level = atoi(&argv[1][2]); + if ((level < 0) || (level > 10)) + { + printf("Invalid level!\n"); + return EXIT_FAILURE; + } + break; + } + default: + { + printf("Invalid option: %s\n", argv[p]); + return EXIT_FAILURE; + } + } + p++; + } + + if ((argc - p) < 3) + { + printf("Must specify mode, input filename, and output filename after options!\n"); + return EXIT_FAILURE; + } + else if ((argc - p) > 3) + { + printf("Too many filenames!\n"); + return EXIT_FAILURE; + } + + pMode = argv[p++]; + if (!strchr("cCdD", pMode[0])) + { + printf("Invalid mode!\n"); + return EXIT_FAILURE; + } + + pSrc_filename = argv[p++]; + pDst_filename = argv[p++]; + + printf("Mode: %c, Level: %u\nInput File: \"%s\"\nOutput File: \"%s\"\n", pMode[0], level, pSrc_filename, pDst_filename); + + // Open input file. + pInfile = fopen(pSrc_filename, "rb"); + if (!pInfile) + { + printf("Failed opening input file!\n"); + return EXIT_FAILURE; + } + + // Determine input file's size. + fseek(pInfile, 0, SEEK_END); + file_loc = ftell(pInfile); + fseek(pInfile, 0, SEEK_SET); + + if ((file_loc < 0) || (file_loc > INT_MAX)) + { + // This is not a limitation of miniz or tinfl, but this example. + printf("File is too large to be processed by this example.\n"); + return EXIT_FAILURE; + } + + infile_size = (uint)file_loc; + + // Open output file. + pOutfile = fopen(pDst_filename, "wb"); + if (!pOutfile) + { + printf("Failed opening output file!\n"); + return EXIT_FAILURE; + } + + printf("Input file size: %u\n", infile_size); + + // Init the z_stream + memset(&stream, 0, sizeof(stream)); + stream.next_in = s_inbuf; + stream.avail_in = 0; + stream.next_out = s_outbuf; + stream.avail_out = BUF_SIZE; + + if ((pMode[0] == 'c') || (pMode[0] == 'C')) + { + // Compression. + uint infile_remaining = infile_size; + + if (deflateInit(&stream, level) != Z_OK) + { + printf("deflateInit() failed!\n"); + return EXIT_FAILURE; + } + + for ( ; ; ) + { + int status; + if (!stream.avail_in) + { + // Input buffer is empty, so read more bytes from input file. + uint n = my_min(BUF_SIZE, infile_remaining); + + if (fread(s_inbuf, 1, n, pInfile) != n) + { + printf("Failed reading from input file!\n"); + return EXIT_FAILURE; + } + + stream.next_in = s_inbuf; + stream.avail_in = n; + + infile_remaining -= n; + //printf("Input bytes remaining: %u\n", infile_remaining); + } + + status = deflate(&stream, infile_remaining ? Z_NO_FLUSH : Z_FINISH); + + if ((status == Z_STREAM_END) || (!stream.avail_out)) + { + // Output buffer is full, or compression is done, so write buffer to output file. + uint n = BUF_SIZE - stream.avail_out; + if (fwrite(s_outbuf, 1, n, pOutfile) != n) + { + printf("Failed writing to output file!\n"); + return EXIT_FAILURE; + } + stream.next_out = s_outbuf; + stream.avail_out = BUF_SIZE; + } + + if (status == Z_STREAM_END) + break; + else if (status != Z_OK) + { + printf("deflate() failed with status %i!\n", status); + return EXIT_FAILURE; + } + } + + if (deflateEnd(&stream) != Z_OK) + { + printf("deflateEnd() failed!\n"); + return EXIT_FAILURE; + } + } + else if ((pMode[0] == 'd') || (pMode[0] == 'D')) + { + // Decompression. + uint infile_remaining = infile_size; + + if (inflateInit(&stream)) + { + printf("inflateInit() failed!\n"); + return EXIT_FAILURE; + } + + for ( ; ; ) + { + int status; + if (!stream.avail_in) + { + // Input buffer is empty, so read more bytes from input file. + uint n = my_min(BUF_SIZE, infile_remaining); + + if (fread(s_inbuf, 1, n, pInfile) != n) + { + printf("Failed reading from input file!\n"); + return EXIT_FAILURE; + } + + stream.next_in = s_inbuf; + stream.avail_in = n; + + infile_remaining -= n; + } + + status = inflate(&stream, Z_SYNC_FLUSH); + + if ((status == Z_STREAM_END) || (!stream.avail_out)) + { + // Output buffer is full, or decompression is done, so write buffer to output file. + uint n = BUF_SIZE - stream.avail_out; + if (fwrite(s_outbuf, 1, n, pOutfile) != n) + { + printf("Failed writing to output file!\n"); + return EXIT_FAILURE; + } + stream.next_out = s_outbuf; + stream.avail_out = BUF_SIZE; + } + + if (status == Z_STREAM_END) + break; + else if (status != Z_OK) + { + printf("inflate() failed with status %i!\n", status); + return EXIT_FAILURE; + } + } + + if (inflateEnd(&stream) != Z_OK) + { + printf("inflateEnd() failed!\n"); + return EXIT_FAILURE; + } + } + else + { + printf("Invalid mode!\n"); + return EXIT_FAILURE; + } + + fclose(pInfile); + if (EOF == fclose(pOutfile)) + { + printf("Failed writing to output file!\n"); + return EXIT_FAILURE; + } + + printf("Total input bytes: %u\n", (mz_uint32)stream.total_in); + printf("Total output bytes: %u\n", (mz_uint32)stream.total_out); + printf("Success.\n"); + return EXIT_SUCCESS; +} diff --git a/miniz/example4.c b/miniz/example4.c new file mode 100644 index 0000000000..effa4050b6 --- /dev/null +++ b/miniz/example4.c @@ -0,0 +1,101 @@ +// example4.c - Uses tinfl.c to decompress a zlib stream in memory to an output file +// Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c. +#include "tinfl.c" +#include +#include + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint; + +#define my_max(a,b) (((a) > (b)) ? (a) : (b)) +#define my_min(a,b) (((a) < (b)) ? (a) : (b)) + +static int tinfl_put_buf_func(const void* pBuf, int len, void *pUser) +{ + return len == (int)fwrite(pBuf, 1, len, (FILE*)pUser); +} + +int main(int argc, char *argv[]) +{ + int status; + FILE *pInfile, *pOutfile; + uint infile_size, outfile_size; + size_t in_buf_size; + uint8 *pCmp_data; + long file_loc; + + if (argc != 3) + { + printf("Usage: example4 infile outfile\n"); + printf("Decompresses zlib stream in file infile to file outfile.\n"); + printf("Input file must be able to fit entirely in memory.\n"); + return EXIT_FAILURE; + } + + // Open input file. + pInfile = fopen(argv[1], "rb"); + if (!pInfile) + { + printf("Failed opening input file!\n"); + return EXIT_FAILURE; + } + + // Determine input file's size. + fseek(pInfile, 0, SEEK_END); + file_loc = ftell(pInfile); + fseek(pInfile, 0, SEEK_SET); + + if ((file_loc < 0) || (file_loc > INT_MAX)) + { + // This is not a limitation of miniz or tinfl, but this example. + printf("File is too large to be processed by this example.\n"); + return EXIT_FAILURE; + } + + infile_size = (uint)file_loc; + + pCmp_data = (uint8 *)malloc(infile_size); + if (!pCmp_data) + { + printf("Out of memory!\n"); + return EXIT_FAILURE; + } + if (fread(pCmp_data, 1, infile_size, pInfile) != infile_size) + { + printf("Failed reading input file!\n"); + return EXIT_FAILURE; + } + + // Open output file. + pOutfile = fopen(argv[2], "wb"); + if (!pOutfile) + { + printf("Failed opening output file!\n"); + return EXIT_FAILURE; + } + + printf("Input file size: %u\n", infile_size); + + in_buf_size = infile_size; + status = tinfl_decompress_mem_to_callback(pCmp_data, &in_buf_size, tinfl_put_buf_func, pOutfile, TINFL_FLAG_PARSE_ZLIB_HEADER); + if (!status) + { + printf("tinfl_decompress_mem_to_callback() failed with status %i!\n", status); + return EXIT_FAILURE; + } + + outfile_size = ftell(pOutfile); + + fclose(pInfile); + if (EOF == fclose(pOutfile)) + { + printf("Failed writing to output file!\n"); + return EXIT_FAILURE; + } + + printf("Total input bytes: %u\n", (uint)in_buf_size); + printf("Total output bytes: %u\n", outfile_size); + printf("Success.\n"); + return EXIT_SUCCESS; +} diff --git a/miniz/example5.c b/miniz/example5.c new file mode 100644 index 0000000000..ed4df739f5 --- /dev/null +++ b/miniz/example5.c @@ -0,0 +1,327 @@ +// example5.c - Demonstrates how to use miniz.c's low-level tdefl_compress() and tinfl_inflate() API's for simple file to file compression/decompression. +// The low-level API's are the fastest, make no use of dynamic memory allocation, and are the most flexible functions exposed by miniz.c. +// Public domain, April 11 2012, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c. +// For simplicity, this example is limited to files smaller than 4GB, but this is not a limitation of miniz.c. + +// Purposely disable a whole bunch of stuff this low-level example doesn't use. +#define MINIZ_NO_STDIO +#define MINIZ_NO_ARCHIVE_APIS +#define MINIZ_NO_TIME +#define MINIZ_NO_ZLIB_APIS +#define MINIZ_NO_MALLOC +#include "miniz.c" + +// Now include stdio.h because this test uses fopen(), etc. (but we still don't want miniz.c's stdio stuff, for testing). +#include +#include + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint; + +#define my_max(a,b) (((a) > (b)) ? (a) : (b)) +#define my_min(a,b) (((a) < (b)) ? (a) : (b)) + +// IN_BUF_SIZE is the size of the file read buffer. +// IN_BUF_SIZE must be >= 1 +#define IN_BUF_SIZE (1024*512) +static uint8 s_inbuf[IN_BUF_SIZE]; + +// COMP_OUT_BUF_SIZE is the size of the output buffer used during compression. +// COMP_OUT_BUF_SIZE must be >= 1 and <= OUT_BUF_SIZE +#define COMP_OUT_BUF_SIZE (1024*512) + +// OUT_BUF_SIZE is the size of the output buffer used during decompression. +// OUT_BUF_SIZE must be a power of 2 >= TINFL_LZ_DICT_SIZE (because the low-level decompressor not only writes, but reads from the output buffer as it decompresses) +//#define OUT_BUF_SIZE (TINFL_LZ_DICT_SIZE) +#define OUT_BUF_SIZE (1024*512) +static uint8 s_outbuf[OUT_BUF_SIZE]; + +// tdefl_compressor contains all the state needed by the low-level compressor so it's a pretty big struct (~300k). +// This example makes it a global vs. putting it on the stack, of course in real-world usage you'll probably malloc() or new it. +tdefl_compressor g_deflator; + +int main(int argc, char *argv[]) +{ + const char *pMode; + FILE *pInfile, *pOutfile; + uint infile_size; + int level = 9; + int p = 1; + const char *pSrc_filename; + const char *pDst_filename; + const void *next_in = s_inbuf; + size_t avail_in = 0; + void *next_out = s_outbuf; + size_t avail_out = OUT_BUF_SIZE; + size_t total_in = 0, total_out = 0; + long file_loc; + + assert(COMP_OUT_BUF_SIZE <= OUT_BUF_SIZE); + + printf("miniz.c example5 (demonstrates tinfl/tdefl)\n"); + + if (argc < 4) + { + printf("File to file compression/decompression using the low-level tinfl/tdefl API's.\n"); + printf("Usage: example5 [options] [mode:c or d] infile outfile\n"); + printf("\nModes:\n"); + printf("c - Compresses file infile to a zlib stream in file outfile\n"); + printf("d - Decompress zlib stream in file infile to file outfile\n"); + printf("\nOptions:\n"); + printf("-l[0-10] - Compression level, higher values are slower, 0 is none.\n"); + return EXIT_FAILURE; + } + + while ((p < argc) && (argv[p][0] == '-')) + { + switch (argv[p][1]) + { + case 'l': + { + level = atoi(&argv[1][2]); + if ((level < 0) || (level > 10)) + { + printf("Invalid level!\n"); + return EXIT_FAILURE; + } + break; + } + default: + { + printf("Invalid option: %s\n", argv[p]); + return EXIT_FAILURE; + } + } + p++; + } + + if ((argc - p) < 3) + { + printf("Must specify mode, input filename, and output filename after options!\n"); + return EXIT_FAILURE; + } + else if ((argc - p) > 3) + { + printf("Too many filenames!\n"); + return EXIT_FAILURE; + } + + pMode = argv[p++]; + if (!strchr("cCdD", pMode[0])) + { + printf("Invalid mode!\n"); + return EXIT_FAILURE; + } + + pSrc_filename = argv[p++]; + pDst_filename = argv[p++]; + + printf("Mode: %c, Level: %u\nInput File: \"%s\"\nOutput File: \"%s\"\n", pMode[0], level, pSrc_filename, pDst_filename); + + // Open input file. + pInfile = fopen(pSrc_filename, "rb"); + if (!pInfile) + { + printf("Failed opening input file!\n"); + return EXIT_FAILURE; + } + + // Determine input file's size. + fseek(pInfile, 0, SEEK_END); + file_loc = ftell(pInfile); + fseek(pInfile, 0, SEEK_SET); + + if ((file_loc < 0) || (file_loc > INT_MAX)) + { + // This is not a limitation of miniz or tinfl, but this example. + printf("File is too large to be processed by this example.\n"); + return EXIT_FAILURE; + } + + infile_size = (uint)file_loc; + + // Open output file. + pOutfile = fopen(pDst_filename, "wb"); + if (!pOutfile) + { + printf("Failed opening output file!\n"); + return EXIT_FAILURE; + } + + printf("Input file size: %u\n", infile_size); + + if ((pMode[0] == 'c') || (pMode[0] == 'C')) + { + // The number of dictionary probes to use at each compression level (0-10). 0=implies fastest/minimal possible probing. + static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; + + tdefl_status status; + uint infile_remaining = infile_size; + + // create tdefl() compatible flags (we have to compose the low-level flags ourselves, or use tdefl_create_comp_flags_from_zip_params() but that means MINIZ_NO_ZLIB_APIS can't be defined). + mz_uint comp_flags = TDEFL_WRITE_ZLIB_HEADER | s_tdefl_num_probes[MZ_MIN(10, level)] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); + if (!level) + comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; + + // Initialize the low-level compressor. + status = tdefl_init(&g_deflator, NULL, NULL, comp_flags); + if (status != TDEFL_STATUS_OKAY) + { + printf("tdefl_init() failed!\n"); + return EXIT_FAILURE; + } + + avail_out = COMP_OUT_BUF_SIZE; + + // Compression. + for ( ; ; ) + { + size_t in_bytes, out_bytes; + + if (!avail_in) + { + // Input buffer is empty, so read more bytes from input file. + uint n = my_min(IN_BUF_SIZE, infile_remaining); + + if (fread(s_inbuf, 1, n, pInfile) != n) + { + printf("Failed reading from input file!\n"); + return EXIT_FAILURE; + } + + next_in = s_inbuf; + avail_in = n; + + infile_remaining -= n; + //printf("Input bytes remaining: %u\n", infile_remaining); + } + + in_bytes = avail_in; + out_bytes = avail_out; + // Compress as much of the input as possible (or all of it) to the output buffer. + status = tdefl_compress(&g_deflator, next_in, &in_bytes, next_out, &out_bytes, infile_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH); + + next_in = (const char *)next_in + in_bytes; + avail_in -= in_bytes; + total_in += in_bytes; + + next_out = (char *)next_out + out_bytes; + avail_out -= out_bytes; + total_out += out_bytes; + + if ((status != TDEFL_STATUS_OKAY) || (!avail_out)) + { + // Output buffer is full, or compression is done or failed, so write buffer to output file. + uint n = COMP_OUT_BUF_SIZE - (uint)avail_out; + if (fwrite(s_outbuf, 1, n, pOutfile) != n) + { + printf("Failed writing to output file!\n"); + return EXIT_FAILURE; + } + next_out = s_outbuf; + avail_out = COMP_OUT_BUF_SIZE; + } + + if (status == TDEFL_STATUS_DONE) + { + // Compression completed successfully. + break; + } + else if (status != TDEFL_STATUS_OKAY) + { + // Compression somehow failed. + printf("tdefl_compress() failed with status %i!\n", status); + return EXIT_FAILURE; + } + } + } + else if ((pMode[0] == 'd') || (pMode[0] == 'D')) + { + // Decompression. + uint infile_remaining = infile_size; + + tinfl_decompressor inflator; + tinfl_init(&inflator); + + for ( ; ; ) + { + size_t in_bytes, out_bytes; + tinfl_status status; + if (!avail_in) + { + // Input buffer is empty, so read more bytes from input file. + uint n = my_min(IN_BUF_SIZE, infile_remaining); + + if (fread(s_inbuf, 1, n, pInfile) != n) + { + printf("Failed reading from input file!\n"); + return EXIT_FAILURE; + } + + next_in = s_inbuf; + avail_in = n; + + infile_remaining -= n; + } + + in_bytes = avail_in; + out_bytes = avail_out; + status = tinfl_decompress(&inflator, (const mz_uint8 *)next_in, &in_bytes, s_outbuf, (mz_uint8 *)next_out, &out_bytes, (infile_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0) | TINFL_FLAG_PARSE_ZLIB_HEADER); + + avail_in -= in_bytes; + next_in = (const mz_uint8 *)next_in + in_bytes; + total_in += in_bytes; + + avail_out -= out_bytes; + next_out = (mz_uint8 *)next_out + out_bytes; + total_out += out_bytes; + + if ((status <= TINFL_STATUS_DONE) || (!avail_out)) + { + // Output buffer is full, or decompression is done, so write buffer to output file. + uint n = OUT_BUF_SIZE - (uint)avail_out; + if (fwrite(s_outbuf, 1, n, pOutfile) != n) + { + printf("Failed writing to output file!\n"); + return EXIT_FAILURE; + } + next_out = s_outbuf; + avail_out = OUT_BUF_SIZE; + } + + // If status is <= TINFL_STATUS_DONE then either decompression is done or something went wrong. + if (status <= TINFL_STATUS_DONE) + { + if (status == TINFL_STATUS_DONE) + { + // Decompression completed successfully. + break; + } + else + { + // Decompression failed. + printf("tinfl_decompress() failed with status %i!\n", status); + return EXIT_FAILURE; + } + } + } + } + else + { + printf("Invalid mode!\n"); + return EXIT_FAILURE; + } + + fclose(pInfile); + if (EOF == fclose(pOutfile)) + { + printf("Failed writing to output file!\n"); + return EXIT_FAILURE; + } + + printf("Total input bytes: %u\n", (mz_uint32)total_in); + printf("Total output bytes: %u\n", (mz_uint32)total_out); + printf("Success.\n"); + return EXIT_SUCCESS; +} diff --git a/miniz/libminiz.dll b/miniz/libminiz.dll new file mode 100644 index 0000000000..8591e555e4 Binary files /dev/null and b/miniz/libminiz.dll differ diff --git a/miniz/miniz.c b/miniz/miniz.c new file mode 100644 index 0000000000..5856b7c9e5 --- /dev/null +++ b/miniz/miniz.c @@ -0,0 +1,4834 @@ +/* miniz.c v1.14 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing + See "unlicense" statement at the end of this file. + Rich Geldreich , last updated May 20, 2012 + Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt + + Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define + MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros). + + * Change History + 5/20/12 v1.14 - MinGW32/64 GCC 4.6.1 compiler fixes: added MZ_FORCEINLINE, #include (thanks fermtect). + 5/19/12 v1.13 - From jason@cornsyrup.org and kelwert@mtu.edu - Fix mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bit. + Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files. + Eliminated a bunch of warnings when compiling with GCC 32-bit/64. + Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly + "Use of the comma-operator in a tested expression.." analysis warning, which I purposely use to work around a MSVC compiler warning). + Created 32-bit and 64-bit Codeblocks projects/workspace. Built and tested Linux executables. The codeblocks workspace is compatible with Linux+Win32/x64. + Added miniz_tester solution/project, which is a useful little app derived from LZHAM's tester app that I use as part of the regression test. + Ran miniz.c and tinfl.c through another series of regression testing on ~500,000 files and archives. + Modified example5.c so it purposely disables a bunch of high-level functionality (MINIZ_NO_STDIO, etc.). (Thanks to corysama for the MINIZ_NO_STDIO bug report.) + Fix ftell() usage in examples so they exit with an error on files which are too large (a limitation of the examples, not miniz itself). + 4/12/12 v1.12 - More comments, added low-level example5.c, fixed a couple minor level_and_flags issues in the archive API's. + level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce Dawson for the feedback/bug report. + 5/28/11 v1.11 - Added statement from unlicense.org + 5/27/11 v1.10 - Substantial compressor optimizations: + Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a + Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86). + Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types. + Refactored the compression code for better readability and maintainability. + Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large + drop in throughput on some files). + 5/15/11 v1.09 - Initial stable release. + + * Low-level Deflate/Inflate implementation notes: + + Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or + greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses + approximately as well as zlib. + + Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function + coroutine: see tinfl_decompress(). It supports decompression into a 32KB (or larger power of 2) wrapping buffer, or into a memory + block large enough to hold the entire file. + + The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation. + + * zlib-style API notes: + + miniz.c implements a fairly large subset of zlib. There's enough functionality present for it to be a drop-in + zlib replacement in many apps: + The z_stream struct, optional memory allocation callbacks + deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound + inflateInit/inflateInit2/inflate/inflateEnd + compress, compress2, compressBound, uncompress + CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines. + Supports raw deflate streams or standard zlib streams with adler-32 checking. + + Limitations: + The callback API's are not implemented yet. No support for gzip headers or zlib static dictionaries. + I've tried to closely emulate zlib's various flavors of stream flushing and return status codes, but + there are no guarantees that miniz.c pulls this off perfectly. + + * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, originally written by + Alex Evans. Supports 1-4 bytes/pixel images. + + * ZIP archive API notes: + + The ZIP archive API's where designed with simplicity and efficiency in mind, with just enough abstraction to + get the job done with minimal fuss. There are simple API's to retrieve file information, read files from + existing archives, create new archives, append new files to existing archives, or clone archive data from + one archive to another. It supports archives located in memory or the heap, on disk (using stdio.h), + or you can specify custom file read/write callbacks. + + - Archive reading: Just call this function to read a single file from a disk archive: + + void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, + size_t *pSize, mz_uint zip_flags); + + For more complex cases, use the "mz_zip_reader" functions. Upon opening an archive, the entire central + directory is located and read as-is into memory, and subsequent file access only occurs when reading individual files. + + - Archives file scanning: The simple way is to use this function to scan a loaded archive for a specific file: + + int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags); + + The locate operation can optionally check file comments too, which (as one example) can be used to identify + multiple versions of the same file in an archive. This function uses a simple linear search through the central + directory, so it's not very fast. + + Alternately, you can iterate through all the files in an archive (using mz_zip_reader_get_num_files()) and + retrieve detailed info on each file by calling mz_zip_reader_file_stat(). + + - Archive creation: Use the "mz_zip_writer" functions. The ZIP writer immediately writes compressed file data + to disk and builds an exact image of the central directory in memory. The central directory image is written + all at once at the end of the archive file when the archive is finalized. + + The archive writer can optionally align each file's local header and file data to any power of 2 alignment, + which can be useful when the archive will be read from optical media. Also, the writer supports placing + arbitrary data blobs at the very beginning of ZIP archives. Archives written using either feature are still + readable by any ZIP tool. + + - Archive appending: The simple way to add a single file to an archive is to call this function: + + mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, + const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); + + The archive will be created if it doesn't already exist, otherwise it'll be appended to. + Note the appending is done in-place and is not an atomic operation, so if something goes wrong + during the operation it's possible the archive could be left without a central directory (although the local + file headers and file data will be fine, so the archive will be recoverable). + + For more complex archive modification scenarios: + 1. The safest way is to use a mz_zip_reader to read the existing archive, cloning only those bits you want to + preserve into a new archive using using the mz_zip_writer_add_from_zip_reader() function (which compiles the + compressed file data as-is). When you're done, delete the old archive and rename the newly written archive, and + you're done. This is safe but requires a bunch of temporary disk space or heap memory. + + 2. Or, you can convert an mz_zip_reader in-place to an mz_zip_writer using mz_zip_writer_init_from_reader(), + append new files as needed, then finalize the archive which will write an updated central directory to the + original archive. (This is basically what mz_zip_add_mem_to_archive_file_in_place() does.) There's a + possibility that the archive's central directory could be lost with this method if anything goes wrong, though. + + - ZIP archive support limitations: + No zip64 or spanning support. Extraction functions can only handle unencrypted, stored or deflated files. + Requires streams capable of seeking. + + * This is a header file library, like stb_image.c. To get only a header file, either cut and paste the + below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it. + + * Important: For best perf. be sure to customize the below macros for your target platform: + #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 + #define MINIZ_LITTLE_ENDIAN 1 + #define MINIZ_HAS_64BIT_REGISTERS 1 +*/ + +#ifndef MINIZ_HEADER_INCLUDED +#define MINIZ_HEADER_INCLUDED + +#include + +#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS) +#include +#endif + +// Defines to completely disable specific portions of miniz.c: +// If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl. + +// Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O. +//#define MINIZ_NO_STDIO + +// If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or +// get/set file times. +//#define MINIZ_NO_TIME + +// Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's. +//#define MINIZ_NO_ARCHIVE_APIS + +// Define MINIZ_NO_ARCHIVE_APIS to disable all writing related ZIP archive API's. +//#define MINIZ_NO_ARCHIVE_WRITING_APIS + +// Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's. +//#define MINIZ_NO_ZLIB_APIS + +// Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib. +//#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES + +// Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc. +// Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc +// callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user +// functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. +//#define MINIZ_NO_MALLOC + +#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__) +// MINIZ_X86_OR_X64_CPU is only used to help set the below macros. +#define MINIZ_X86_OR_X64_CPU 1 +#endif + +#if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU +// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. +#define MINIZ_LITTLE_ENDIAN 1 +#endif + +#if MINIZ_X86_OR_X64_CPU +// Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses. +#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 +#endif + +#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__) +// Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions). +#define MINIZ_HAS_64BIT_REGISTERS 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// ------------------- zlib-style API Definitions. + +// For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits! +typedef unsigned long mz_ulong; + +// mz_free() internally uses the MZ_FREE() macro (which by default calls free() unless you've modified the MZ_MALLOC macro) to release a block allocated from the heap. +void mz_free(void *p); + +#define MZ_ADLER32_INIT (1) +// mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL. +mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len); + +#define MZ_CRC32_INIT (0) +// mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL. +mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len); + +// Compression strategies. +enum { MZ_DEFAULT_STRATEGY = 0, MZ_FILTERED = 1, MZ_HUFFMAN_ONLY = 2, MZ_RLE = 3, MZ_FIXED = 4 }; + +// Method +#define MZ_DEFLATED 8 + +#ifndef MINIZ_NO_ZLIB_APIS + +// Heap allocation callbacks. +// Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long. +typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size); +typedef void (*mz_free_func)(void *opaque, void *address); +typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size); + +#define MZ_VERSION "9.1.14" +#define MZ_VERNUM 0x91E0 +#define MZ_VER_MAJOR 9 +#define MZ_VER_MINOR 1 +#define MZ_VER_REVISION 14 +#define MZ_VER_SUBREVISION 0 + +// Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs). +enum { MZ_NO_FLUSH = 0, MZ_PARTIAL_FLUSH = 1, MZ_SYNC_FLUSH = 2, MZ_FULL_FLUSH = 3, MZ_FINISH = 4, MZ_BLOCK = 5 }; + +// Return status codes. MZ_PARAM_ERROR is non-standard. +enum { MZ_OK = 0, MZ_STREAM_END = 1, MZ_NEED_DICT = 2, MZ_ERRNO = -1, MZ_STREAM_ERROR = -2, MZ_DATA_ERROR = -3, MZ_MEM_ERROR = -4, MZ_BUF_ERROR = -5, MZ_VERSION_ERROR = -6, MZ_PARAM_ERROR = -10000 }; + +// Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL. +enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_UBER_COMPRESSION = 10, MZ_DEFAULT_LEVEL = 6, MZ_DEFAULT_COMPRESSION = -1 }; + +// Window bits +#define MZ_DEFAULT_WINDOW_BITS 15 + +struct mz_internal_state; + +// Compression/decompression stream struct. +typedef struct mz_stream_s +{ + const unsigned char *next_in; // pointer to next byte to read + unsigned int avail_in; // number of bytes available at next_in + mz_ulong total_in; // total number of bytes consumed so far + + unsigned char *next_out; // pointer to next byte to write + unsigned int avail_out; // number of bytes that can be written to next_out + mz_ulong total_out; // total number of bytes produced so far + + char *msg; // error msg (unused) + struct mz_internal_state *state; // internal state, allocated by zalloc/zfree + + mz_alloc_func zalloc; // optional heap allocation function (defaults to malloc) + mz_free_func zfree; // optional heap free function (defaults to free) + void *opaque; // heap alloc function user pointer + + int data_type; // data_type (unused) + mz_ulong adler; // adler32 of the source or uncompressed data + mz_ulong reserved; // not used +} mz_stream; + +typedef mz_stream *mz_streamp; + +// Returns the version string of miniz.c. +const char *mz_version(void); + +// mz_deflateInit() initializes a compressor with default options: +// Parameters: +// pStream must point to an initialized mz_stream struct. +// level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION]. +// level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio. +// (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.) +// Return values: +// MZ_OK on success. +// MZ_STREAM_ERROR if the stream is bogus. +// MZ_PARAM_ERROR if the input parameters are bogus. +// MZ_MEM_ERROR on out of memory. +int mz_deflateInit(mz_streamp pStream, int level); + +// mz_deflateInit2() is like mz_deflate(), except with more control: +// Additional parameters: +// method must be MZ_DEFLATED +// window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer) +// mem_level must be between [1, 9] (it's checked but ignored by miniz.c) +int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy); + +// Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2(). +int mz_deflateReset(mz_streamp pStream); + +// mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible. +// Parameters: +// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. +// flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH. +// Return values: +// MZ_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full). +// MZ_STREAM_END if all input has been consumed and all output bytes have been written. Don't call mz_deflate() on the stream anymore. +// MZ_STREAM_ERROR if the stream is bogus. +// MZ_PARAM_ERROR if one of the parameters is invalid. +// MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.) +int mz_deflate(mz_streamp pStream, int flush); + +// mz_deflateEnd() deinitializes a compressor: +// Return values: +// MZ_OK on success. +// MZ_STREAM_ERROR if the stream is bogus. +int mz_deflateEnd(mz_streamp pStream); + +// mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH. +mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len); + +// Single-call compression functions mz_compress() and mz_compress2(): +// Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure. +int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len); +int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level); + +// mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress(). +mz_ulong mz_compressBound(mz_ulong source_len); + +// Initializes a decompressor. +int mz_inflateInit(mz_streamp pStream); + +// mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer: +// window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate). +int mz_inflateInit2(mz_streamp pStream, int window_bits); + +// Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible. +// Parameters: +// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. +// flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH. +// On the first call, if flush is MZ_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster). +// MZ_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data. +// Return values: +// MZ_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full. +// MZ_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified. +// MZ_STREAM_ERROR if the stream is bogus. +// MZ_DATA_ERROR if the deflate stream is invalid. +// MZ_PARAM_ERROR if one of the parameters is invalid. +// MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again +// with more input data, or with more room in the output buffer (except when using single call decompression, described above). +int mz_inflate(mz_streamp pStream, int flush); + +// Deinitializes a decompressor. +int mz_inflateEnd(mz_streamp pStream); + +// Single-call decompression. +// Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure. +int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len); + +// Returns a string description of the specified error code, or NULL if the error code is invalid. +const char *mz_error(int err); + +// Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports. +// Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project. +#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES + typedef unsigned char Byte; + typedef unsigned int uInt; + typedef mz_ulong uLong; + typedef Byte Bytef; + typedef uInt uIntf; + typedef char charf; + typedef int intf; + typedef void *voidpf; + typedef uLong uLongf; + typedef void *voidp; + typedef void *const voidpc; + #define Z_NULL 0 + #define Z_NO_FLUSH MZ_NO_FLUSH + #define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH + #define Z_SYNC_FLUSH MZ_SYNC_FLUSH + #define Z_FULL_FLUSH MZ_FULL_FLUSH + #define Z_FINISH MZ_FINISH + #define Z_BLOCK MZ_BLOCK + #define Z_OK MZ_OK + #define Z_STREAM_END MZ_STREAM_END + #define Z_NEED_DICT MZ_NEED_DICT + #define Z_ERRNO MZ_ERRNO + #define Z_STREAM_ERROR MZ_STREAM_ERROR + #define Z_DATA_ERROR MZ_DATA_ERROR + #define Z_MEM_ERROR MZ_MEM_ERROR + #define Z_BUF_ERROR MZ_BUF_ERROR + #define Z_VERSION_ERROR MZ_VERSION_ERROR + #define Z_PARAM_ERROR MZ_PARAM_ERROR + #define Z_NO_COMPRESSION MZ_NO_COMPRESSION + #define Z_BEST_SPEED MZ_BEST_SPEED + #define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION + #define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION + #define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY + #define Z_FILTERED MZ_FILTERED + #define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY + #define Z_RLE MZ_RLE + #define Z_FIXED MZ_FIXED + #define Z_DEFLATED MZ_DEFLATED + #define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS + #define alloc_func mz_alloc_func + #define free_func mz_free_func + #define internal_state mz_internal_state + #define z_stream mz_stream + #define deflateInit mz_deflateInit + #define deflateInit2 mz_deflateInit2 + #define deflateReset mz_deflateReset + #define deflate mz_deflate + #define deflateEnd mz_deflateEnd + #define deflateBound mz_deflateBound + #define compress mz_compress + #define compress2 mz_compress2 + #define compressBound mz_compressBound + #define inflateInit mz_inflateInit + #define inflateInit2 mz_inflateInit2 + #define inflate mz_inflate + #define inflateEnd mz_inflateEnd + #define uncompress mz_uncompress + #define crc32 mz_crc32 + #define adler32 mz_adler32 + #define MAX_WBITS 15 + #define MAX_MEM_LEVEL 9 + #define zError mz_error + #define ZLIB_VERSION MZ_VERSION + #define ZLIB_VERNUM MZ_VERNUM + #define ZLIB_VER_MAJOR MZ_VER_MAJOR + #define ZLIB_VER_MINOR MZ_VER_MINOR + #define ZLIB_VER_REVISION MZ_VER_REVISION + #define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION + #define zlibVersion mz_version + #define zlib_version mz_version() +#endif // #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES + +#endif // MINIZ_NO_ZLIB_APIS + +// ------------------- Types and macros + +typedef unsigned char mz_uint8; +typedef signed short mz_int16; +typedef unsigned short mz_uint16; +typedef unsigned int mz_uint32; +typedef unsigned int mz_uint; +typedef long long mz_int64; +typedef unsigned long long mz_uint64; +typedef int mz_bool; + +#define MZ_FALSE (0) +#define MZ_TRUE (1) + +// Works around MSVC's spammy "warning C4127: conditional expression is constant" message. +#ifdef _MSC_VER + #define MZ_MACRO_END while (0, 0) +#else + #define MZ_MACRO_END while (0) +#endif + +// ------------------- ZIP archive reading/writing + +#ifndef MINIZ_NO_ARCHIVE_APIS + +enum +{ + MZ_ZIP_MAX_IO_BUF_SIZE = 64*1024, + MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 260, + MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 256 +}; + +typedef struct +{ + mz_uint32 m_file_index; + mz_uint32 m_central_dir_ofs; + mz_uint16 m_version_made_by; + mz_uint16 m_version_needed; + mz_uint16 m_bit_flag; + mz_uint16 m_method; +#ifndef MINIZ_NO_TIME + time_t m_time; +#endif + mz_uint32 m_crc32; + mz_uint64 m_comp_size; + mz_uint64 m_uncomp_size; + mz_uint16 m_internal_attr; + mz_uint32 m_external_attr; + mz_uint64 m_local_header_ofs; + mz_uint32 m_comment_size; + char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE]; + char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE]; +} mz_zip_archive_file_stat; + +typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n); +typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n); + +struct mz_zip_internal_state_tag; +typedef struct mz_zip_internal_state_tag mz_zip_internal_state; + +typedef enum +{ + MZ_ZIP_MODE_INVALID = 0, + MZ_ZIP_MODE_READING = 1, + MZ_ZIP_MODE_WRITING = 2, + MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3 +} mz_zip_mode; + +typedef struct +{ + mz_uint64 m_archive_size; + mz_uint64 m_central_directory_file_ofs; + mz_uint m_total_files; + mz_zip_mode m_zip_mode; + + mz_uint m_file_offset_alignment; + + mz_alloc_func m_pAlloc; + mz_free_func m_pFree; + mz_realloc_func m_pRealloc; + void *m_pAlloc_opaque; + + mz_file_read_func m_pRead; + mz_file_write_func m_pWrite; + void *m_pIO_opaque; + + mz_zip_internal_state *m_pState; + +} mz_zip_archive; + +typedef enum +{ + MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100, + MZ_ZIP_FLAG_IGNORE_PATH = 0x0200, + MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400, + MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800 +} mz_zip_flags; + +// ZIP archive reading + +// Inits a ZIP archive reader. +// These functions read and validate the archive's central directory. +mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint32 flags); +mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint32 flags); + +#ifndef MINIZ_NO_STDIO +mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags); +#endif + +// Returns the total number of files in the archive. +mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip); + +// Returns detailed information about an archive file entry. +mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat); + +// Determines if an archive file entry is a directory entry. +mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index); +mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index); + +// Retrieves the filename of an archive file entry. +// Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename. +mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size); + +// Attempts to locates a file in the archive's central directory. +// Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH +// Returns -1 if the file cannot be found. +int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags); + +// Extracts a archive file to a memory buffer using no memory allocation. +mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size); +mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size); + +// Extracts a archive file to a memory buffer. +mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags); +mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags); + +// Extracts a archive file to a dynamically allocated heap buffer. +void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags); +void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags); + +// Extracts a archive file using a callback function to output the file's data. +mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags); +mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags); + +#ifndef MINIZ_NO_STDIO +// Extracts a archive file to a disk file and sets its last accessed and modified times. +// This function only extracts files, not archive directory records. +mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags); +mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags); +#endif + +// Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used. +mz_bool mz_zip_reader_end(mz_zip_archive *pZip); + +// ZIP archive writing + +#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS + +// Inits a ZIP archive writer. +mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size); +mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size); + +#ifndef MINIZ_NO_STDIO +mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning); +#endif + +// Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive. +// For archives opened using mz_zip_reader_init_file, pFilename must be the archive's filename so it can be reopened for writing. If the file can't be reopened, mz_zip_reader_end() will be called. +// For archives opened using mz_zip_reader_init_mem, the memory block must be growable using the realloc callback (which defaults to realloc unless you've overridden it). +// Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL. +// Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before +// the archive is finalized the file's central directory will be hosed. +mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename); + +// Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive. +// To add a directory entry, call this method with an archive name ending in a forwardslash with empty buffer. +// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. +mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags); +mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32); + +#ifndef MINIZ_NO_STDIO +// Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive. +// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. +mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); +#endif + +// Adds a file to an archive by fully cloning the data from another archive. +// This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data, and comment fields. +mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index); + +// Finalizes the archive by writing the central directory records followed by the end of central directory record. +// After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end(). +// An archive must be manually finalized by calling this function for it to be valid. +mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip); +mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, size_t *pSize); + +// Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used. +// Note for the archive to be valid, it must have been finalized before ending. +mz_bool mz_zip_writer_end(mz_zip_archive *pZip); + +// Misc. high-level helper functions: + +// mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive. +// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. +mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); + +// Reads a single file from an archive into a heap block. +// Returns NULL on failure. +void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint zip_flags); + +#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS + +#endif // #ifndef MINIZ_NO_ARCHIVE_APIS + +// ------------------- Low-level Decompression API Definitions + +// Decompression flags used by tinfl_decompress(). +// TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream. +// TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input. +// TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB). +// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes. +enum +{ + TINFL_FLAG_PARSE_ZLIB_HEADER = 1, + TINFL_FLAG_HAS_MORE_INPUT = 2, + TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4, + TINFL_FLAG_COMPUTE_ADLER32 = 8 +}; + +// High level decompression functions: +// tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc(). +// On entry: +// pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress. +// On return: +// Function returns a pointer to the decompressed data, or NULL on failure. +// *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data. +// The caller must call mz_free() on the returned block when it's no longer needed. +void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); + +// tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory. +// Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success. +#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1)) +size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); + +// tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer. +// Returns 1 on success or 0 on failure. +typedef int (*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser); +int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); + +struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor; + +// Max size of LZ dictionary. +#define TINFL_LZ_DICT_SIZE 32768 + +// Return status. +typedef enum +{ + TINFL_STATUS_BAD_PARAM = -3, + TINFL_STATUS_ADLER32_MISMATCH = -2, + TINFL_STATUS_FAILED = -1, + TINFL_STATUS_DONE = 0, + TINFL_STATUS_NEEDS_MORE_INPUT = 1, + TINFL_STATUS_HAS_MORE_OUTPUT = 2 +} tinfl_status; + +// Initializes the decompressor to its initial state. +#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END +#define tinfl_get_adler32(r) (r)->m_check_adler32 + +// Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. +// This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. +tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags); + +// Internal/private bits follow. +enum +{ + TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19, + TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS +}; + +typedef struct +{ + mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0]; + mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; +} tinfl_huff_table; + +#if MINIZ_HAS_64BIT_REGISTERS + #define TINFL_USE_64BIT_BITBUF 1 +#endif + +#if TINFL_USE_64BIT_BITBUF + typedef mz_uint64 tinfl_bit_buf_t; + #define TINFL_BITBUF_SIZE (64) +#else + typedef mz_uint32 tinfl_bit_buf_t; + #define TINFL_BITBUF_SIZE (32) +#endif + +struct tinfl_decompressor_tag +{ + mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES]; + tinfl_bit_buf_t m_bit_buf; + size_t m_dist_from_out_buf_start; + tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES]; + mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137]; +}; + +// ------------------- Low-level Compression API Definitions + +// Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently). +#define TDEFL_LESS_MEMORY 0 + +// tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search): +// TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression). +enum +{ + TDEFL_HUFFMAN_ONLY = 0, TDEFL_DEFAULT_MAX_PROBES = 128, TDEFL_MAX_PROBES_MASK = 0xFFF +}; + +// TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data. +// TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers). +// TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing. +// TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory). +// TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1) +// TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled. +// TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables. +// TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks. +enum +{ + TDEFL_WRITE_ZLIB_HEADER = 0x01000, + TDEFL_COMPUTE_ADLER32 = 0x02000, + TDEFL_GREEDY_PARSING_FLAG = 0x04000, + TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000, + TDEFL_RLE_MATCHES = 0x10000, + TDEFL_FILTER_MATCHES = 0x20000, + TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000, + TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000 +}; + +// High level compression functions: +// tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc(). +// On entry: +// pSrc_buf, src_buf_len: Pointer and size of source block to compress. +// flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression. +// On return: +// Function returns a pointer to the compressed data, or NULL on failure. +// *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data. +// The caller must free() the returned block when it's no longer needed. +void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); + +// tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory. +// Returns 0 on failure. +size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); + +// Compresses an image to a compressed PNG file in memory. +// On entry: +// pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4. +// The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory. +// On return: +// Function returns a pointer to the compressed data, or NULL on failure. +// *pLen_out will be set to the size of the PNG image file. +// The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed. +void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out); + +// Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. +typedef mz_bool (*tdefl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser); + +// tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally. +mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); + +enum { TDEFL_MAX_HUFF_TABLES = 3, TDEFL_MAX_HUFF_SYMBOLS_0 = 288, TDEFL_MAX_HUFF_SYMBOLS_1 = 32, TDEFL_MAX_HUFF_SYMBOLS_2 = 19, TDEFL_LZ_DICT_SIZE = 32768, TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1, TDEFL_MIN_MATCH_LEN = 3, TDEFL_MAX_MATCH_LEN = 258 }; + +// TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes). +#if TDEFL_LESS_MEMORY +enum { TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 12, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS }; +#else +enum { TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 15, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS }; +#endif + +// The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions. +typedef enum +{ + TDEFL_STATUS_BAD_PARAM = -2, + TDEFL_STATUS_PUT_BUF_FAILED = -1, + TDEFL_STATUS_OKAY = 0, + TDEFL_STATUS_DONE = 1, +} tdefl_status; + +// Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums +typedef enum +{ + TDEFL_NO_FLUSH = 0, + TDEFL_SYNC_FLUSH = 2, + TDEFL_FULL_FLUSH = 3, + TDEFL_FINISH = 4 +} tdefl_flush; + +// tdefl's compression state structure. +typedef struct +{ + tdefl_put_buf_func_ptr m_pPut_buf_func; + void *m_pPut_buf_user; + mz_uint m_flags, m_max_probes[2]; + int m_greedy_parsing; + mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size; + mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end; + mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer; + mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish; + tdefl_status m_prev_return_status; + const void *m_pIn_buf; + void *m_pOut_buf; + size_t *m_pIn_buf_size, *m_pOut_buf_size; + tdefl_flush m_flush; + const mz_uint8 *m_pSrc; + size_t m_src_buf_left, m_out_buf_ofs; + mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1]; + mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE]; + mz_uint16 m_next[TDEFL_LZ_DICT_SIZE]; + mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE]; + mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE]; +} tdefl_compressor; + +// Initializes the compressor. +// There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory. +// pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression. +// If pBut_buf_func is NULL the user should always call the tdefl_compress() API. +// flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.) +tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); + +// Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible. +tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush); + +// tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr. +// tdefl_compress_buffer() always consumes the entire input buffer. +tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush); + +tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d); +mz_uint32 tdefl_get_adler32(tdefl_compressor *d); + +// Can't use tdefl_create_comp_flags_from_zip_params if MINIZ_NO_ZLIB_APIS isn't defined, because it uses some of its macros. +#ifndef MINIZ_NO_ZLIB_APIS +// Create tdefl_compress() flags given zlib-style compression parameters. +// level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files) +// window_bits may be -15 (raw deflate) or 15 (zlib) +// strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED +mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy); +#endif // #ifndef MINIZ_NO_ZLIB_APIS + +#ifdef __cplusplus +} +#endif + +#endif // MINIZ_HEADER_INCLUDED + +// ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.) + +#ifndef MINIZ_HEADER_FILE_ONLY + +typedef unsigned char mz_validate_uint16[sizeof(mz_uint16)==2 ? 1 : -1]; +typedef unsigned char mz_validate_uint32[sizeof(mz_uint32)==4 ? 1 : -1]; +typedef unsigned char mz_validate_uint64[sizeof(mz_uint64)==8 ? 1 : -1]; + +#include +#include + +#define MZ_ASSERT(x) assert(x) + +#ifdef MINIZ_NO_MALLOC + #define MZ_MALLOC(x) NULL + #define MZ_FREE(x) (void)x, ((void)0) + #define MZ_REALLOC(p, x) NULL +#else + #define MZ_MALLOC(x) malloc(x) + #define MZ_FREE(x) free(x) + #define MZ_REALLOC(p, x) realloc(p, x) +#endif + +#define MZ_MAX(a,b) (((a)>(b))?(a):(b)) +#define MZ_MIN(a,b) (((a)<(b))?(a):(b)) +#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj)) + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + #define MZ_READ_LE16(p) *((const mz_uint16 *)(p)) + #define MZ_READ_LE32(p) *((const mz_uint32 *)(p)) +#else + #define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U)) + #define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U)) +#endif + +#ifdef _MSC_VER + #define MZ_FORCEINLINE __forceinline +#elif defined(__GNUC__) + #define MZ_FORCEINLINE __attribute__((__always_inline__)) +#else + #define MZ_FORCEINLINE +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +// ------------------- zlib-style API's + +mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len) +{ + mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16); size_t block_len = buf_len % 5552; + if (!ptr) return MZ_ADLER32_INIT; + while (buf_len) { + for (i = 0; i + 7 < block_len; i += 8, ptr += 8) { + s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1; + s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1; + } + for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1; + s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552; + } + return (s2 << 16) + s1; +} + +// Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/ +mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) +{ + static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c }; + mz_uint32 crcu32 = (mz_uint32)crc; + if (!ptr) return MZ_CRC32_INIT; + crcu32 = ~crcu32; while (buf_len--) { mz_uint8 b = *ptr++; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)]; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)]; } + return ~crcu32; +} + +void mz_free(void *p) +{ + MZ_FREE(p); +} + +#ifndef MINIZ_NO_ZLIB_APIS + +static void *def_alloc_func(void *opaque, size_t items, size_t size) { (void)opaque, (void)items, (void)size; return MZ_MALLOC(items * size); } +static void def_free_func(void *opaque, void *address) { (void)opaque, (void)address; MZ_FREE(address); } +static void *def_realloc_func(void *opaque, void *address, size_t items, size_t size) { (void)opaque, (void)address, (void)items, (void)size; return MZ_REALLOC(address, items * size); } + +const char *mz_version(void) +{ + return MZ_VERSION; +} + +int mz_deflateInit(mz_streamp pStream, int level) +{ + return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY); +} + +int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy) +{ + tdefl_compressor *pComp; + mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy); + + if (!pStream) return MZ_STREAM_ERROR; + if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))) return MZ_PARAM_ERROR; + + pStream->data_type = 0; + pStream->adler = MZ_ADLER32_INIT; + pStream->msg = NULL; + pStream->reserved = 0; + pStream->total_in = 0; + pStream->total_out = 0; + if (!pStream->zalloc) pStream->zalloc = def_alloc_func; + if (!pStream->zfree) pStream->zfree = def_free_func; + + pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor)); + if (!pComp) + return MZ_MEM_ERROR; + + pStream->state = (struct mz_internal_state *)pComp; + + if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY) + { + mz_deflateEnd(pStream); + return MZ_PARAM_ERROR; + } + + return MZ_OK; +} + +int mz_deflateReset(mz_streamp pStream) +{ + if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree)) return MZ_STREAM_ERROR; + pStream->total_in = pStream->total_out = 0; + tdefl_init((tdefl_compressor*)pStream->state, NULL, NULL, ((tdefl_compressor*)pStream->state)->m_flags); + return MZ_OK; +} + +int mz_deflate(mz_streamp pStream, int flush) +{ + size_t in_bytes, out_bytes; + mz_ulong orig_total_in, orig_total_out; + int mz_status = MZ_OK; + + if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out)) return MZ_STREAM_ERROR; + if (!pStream->avail_out) return MZ_BUF_ERROR; + + if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH; + + if (((tdefl_compressor*)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE) + return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR; + + orig_total_in = pStream->total_in; orig_total_out = pStream->total_out; + for ( ; ; ) + { + tdefl_status defl_status; + in_bytes = pStream->avail_in; out_bytes = pStream->avail_out; + + defl_status = tdefl_compress((tdefl_compressor*)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush); + pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; + pStream->total_in += (mz_uint)in_bytes; pStream->adler = tdefl_get_adler32((tdefl_compressor*)pStream->state); + + pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; + pStream->total_out += (mz_uint)out_bytes; + + if (defl_status < 0) + { + mz_status = MZ_STREAM_ERROR; + break; + } + else if (defl_status == TDEFL_STATUS_DONE) + { + mz_status = MZ_STREAM_END; + break; + } + else if (!pStream->avail_out) + break; + else if ((!pStream->avail_in) && (flush != MZ_FINISH)) + { + if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out)) + break; + return MZ_BUF_ERROR; // Can't make forward progress without some input. + } + } + return mz_status; +} + +int mz_deflateEnd(mz_streamp pStream) +{ + if (!pStream) return MZ_STREAM_ERROR; + if (pStream->state) + { + pStream->zfree(pStream->opaque, pStream->state); + pStream->state = NULL; + } + return MZ_OK; +} + +mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len) +{ + (void)pStream; + // This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.) + return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5); +} + +int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level) +{ + int status; + mz_stream stream; + memset(&stream, 0, sizeof(stream)); + + // In case mz_ulong is 64-bits (argh I hate longs). + if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; + + stream.next_in = pSource; + stream.avail_in = (mz_uint32)source_len; + stream.next_out = pDest; + stream.avail_out = (mz_uint32)*pDest_len; + + status = mz_deflateInit(&stream, level); + if (status != MZ_OK) return status; + + status = mz_deflate(&stream, MZ_FINISH); + if (status != MZ_STREAM_END) + { + mz_deflateEnd(&stream); + return (status == MZ_OK) ? MZ_BUF_ERROR : status; + } + + *pDest_len = stream.total_out; + return mz_deflateEnd(&stream); +} + +int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) +{ + return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION); +} + +mz_ulong mz_compressBound(mz_ulong source_len) +{ + return mz_deflateBound(NULL, source_len); +} + +typedef struct +{ + tinfl_decompressor m_decomp; + mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; int m_window_bits; + mz_uint8 m_dict[TINFL_LZ_DICT_SIZE]; + tinfl_status m_last_status; +} inflate_state; + +int mz_inflateInit2(mz_streamp pStream, int window_bits) +{ + inflate_state *pDecomp; + if (!pStream) return MZ_STREAM_ERROR; + if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) return MZ_PARAM_ERROR; + + pStream->data_type = 0; + pStream->adler = 0; + pStream->msg = NULL; + pStream->total_in = 0; + pStream->total_out = 0; + pStream->reserved = 0; + if (!pStream->zalloc) pStream->zalloc = def_alloc_func; + if (!pStream->zfree) pStream->zfree = def_free_func; + + pDecomp = (inflate_state*)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state)); + if (!pDecomp) return MZ_MEM_ERROR; + + pStream->state = (struct mz_internal_state *)pDecomp; + + tinfl_init(&pDecomp->m_decomp); + pDecomp->m_dict_ofs = 0; + pDecomp->m_dict_avail = 0; + pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT; + pDecomp->m_first_call = 1; + pDecomp->m_has_flushed = 0; + pDecomp->m_window_bits = window_bits; + + return MZ_OK; +} + +int mz_inflateInit(mz_streamp pStream) +{ + return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS); +} + +int mz_inflate(mz_streamp pStream, int flush) +{ + inflate_state* pState; + mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32; + size_t in_bytes, out_bytes, orig_avail_in; + tinfl_status status; + + if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR; + if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH; + if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) return MZ_STREAM_ERROR; + + pState = (inflate_state*)pStream->state; + if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER; + orig_avail_in = pStream->avail_in; + + first_call = pState->m_first_call; pState->m_first_call = 0; + if (pState->m_last_status < 0) return MZ_DATA_ERROR; + + if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR; + pState->m_has_flushed |= (flush == MZ_FINISH); + + if ((flush == MZ_FINISH) && (first_call)) + { + // MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. + decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF; + in_bytes = pStream->avail_in; out_bytes = pStream->avail_out; + status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags); + pState->m_last_status = status; + pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes; + pStream->adler = tinfl_get_adler32(&pState->m_decomp); + pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; pStream->total_out += (mz_uint)out_bytes; + + if (status < 0) + return MZ_DATA_ERROR; + else if (status != TINFL_STATUS_DONE) + { + pState->m_last_status = TINFL_STATUS_FAILED; + return MZ_BUF_ERROR; + } + return MZ_STREAM_END; + } + // flush != MZ_FINISH then we must assume there's more input. + if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT; + + if (pState->m_dict_avail) + { + n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); + memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); + pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n; + pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); + return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; + } + + for ( ; ; ) + { + in_bytes = pStream->avail_in; + out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs; + + status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags); + pState->m_last_status = status; + + pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; + pStream->total_in += (mz_uint)in_bytes; pStream->adler = tinfl_get_adler32(&pState->m_decomp); + + pState->m_dict_avail = (mz_uint)out_bytes; + + n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); + memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); + pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n; + pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); + + if (status < 0) + return MZ_DATA_ERROR; // Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). + else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in)) + return MZ_BUF_ERROR; // Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. + else if (flush == MZ_FINISH) + { + // The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. + if (status == TINFL_STATUS_DONE) + return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END; + // status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong. + else if (!pStream->avail_out) + return MZ_BUF_ERROR; + } + else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail)) + break; + } + + return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; +} + +int mz_inflateEnd(mz_streamp pStream) +{ + if (!pStream) + return MZ_STREAM_ERROR; + if (pStream->state) + { + pStream->zfree(pStream->opaque, pStream->state); + pStream->state = NULL; + } + return MZ_OK; +} + +int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) +{ + mz_stream stream; + int status; + memset(&stream, 0, sizeof(stream)); + + // In case mz_ulong is 64-bits (argh I hate longs). + if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; + + stream.next_in = pSource; + stream.avail_in = (mz_uint32)source_len; + stream.next_out = pDest; + stream.avail_out = (mz_uint32)*pDest_len; + + status = mz_inflateInit(&stream); + if (status != MZ_OK) + return status; + + status = mz_inflate(&stream, MZ_FINISH); + if (status != MZ_STREAM_END) + { + mz_inflateEnd(&stream); + return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status; + } + *pDest_len = stream.total_out; + + return mz_inflateEnd(&stream); +} + +const char *mz_error(int err) +{ + static struct { int m_err; const char *m_pDesc; } s_error_descs[] = + { + { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, + { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" } + }; + mz_uint i; for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i) if (s_error_descs[i].m_err == err) return s_error_descs[i].m_pDesc; + return NULL; +} + +#endif //MINIZ_NO_ZLIB_APIS + +// ------------------- Low-level Decompression (completely independent from all compression API's) + +#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l) +#define TINFL_MEMSET(p, c, l) memset(p, c, l) + +#define TINFL_CR_BEGIN switch(r->m_state) { case 0: +#define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END +#define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END +#define TINFL_CR_FINISH } + +// TODO: If the caller has indicated that there's no more input, and we attempt to read beyond the input buf, then something is wrong with the input because the inflator never +// reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario. +#define TINFL_GET_BYTE(state_index, c) do { \ + if (pIn_buf_cur >= pIn_buf_end) { \ + for ( ; ; ) { \ + if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \ + TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \ + if (pIn_buf_cur < pIn_buf_end) { \ + c = *pIn_buf_cur++; \ + break; \ + } \ + } else { \ + c = 0; \ + break; \ + } \ + } \ + } else c = *pIn_buf_cur++; } MZ_MACRO_END + +#define TINFL_NEED_BITS(state_index, n) do { mz_uint c; TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; } while (num_bits < (mz_uint)(n)) +#define TINFL_SKIP_BITS(state_index, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END +#define TINFL_GET_BITS(state_index, b, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } b = bit_buf & ((1 << (n)) - 1); bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END + +// TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. +// It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a +// Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the +// bit buffer contains >=15 bits (deflate's max. Huffman code size). +#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \ + do { \ + temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ + if (temp >= 0) { \ + code_len = temp >> 9; \ + if ((code_len) && (num_bits >= code_len)) \ + break; \ + } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \ + code_len = TINFL_FAST_LOOKUP_BITS; \ + do { \ + temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ + } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \ + } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \ + } while (num_bits < 15); + +// TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read +// beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully +// decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32. +// The slow path is only executed at the very end of the input buffer. +#define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \ + int temp; mz_uint code_len, c; \ + if (num_bits < 15) { \ + if ((pIn_buf_end - pIn_buf_cur) < 2) { \ + TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \ + } else { \ + bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); pIn_buf_cur += 2; num_bits += 16; \ + } \ + } \ + if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \ + code_len = temp >> 9, temp &= 511; \ + else { \ + code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \ + } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END + +tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags) +{ + static const int s_length_base[31] = { 3,4,5,6,7,8,9,10,11,13, 15,17,19,23,27,31,35,43,51,59, 67,83,99,115,131,163,195,227,258,0,0 }; + static const int s_length_extra[31]= { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; + static const int s_dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; + static const int s_dist_extra[32] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + static const mz_uint8 s_length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + static const int s_min_table_sizes[3] = { 257, 1, 4 }; + + tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf; + const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size; + mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size; + size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start; + + // Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). + if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) { *pIn_buf_size = *pOut_buf_size = 0; return TINFL_STATUS_BAD_PARAM; } + + num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; counter = r->m_counter; num_extra = r->m_num_extra; dist_from_out_buf_start = r->m_dist_from_out_buf_start; + TINFL_CR_BEGIN + + bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1; + if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) + { + TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1); + counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8)); + if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4))))); + if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); } + } + + do + { + TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1; + if (r->m_type == 0) + { + TINFL_SKIP_BITS(5, num_bits & 7); + for (counter = 0; counter < 4; ++counter) { if (num_bits) TINFL_GET_BITS(6, r->m_raw_header[counter], 8); else TINFL_GET_BYTE(7, r->m_raw_header[counter]); } + if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); } + while ((counter) && (num_bits)) + { + TINFL_GET_BITS(51, dist, 8); + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = (mz_uint8)dist; + counter--; + } + while (counter) + { + size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); } + while (pIn_buf_cur >= pIn_buf_end) + { + if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) + { + TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT); + } + else + { + TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED); + } + } + n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter); + TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n; + } + } + else if (r->m_type == 3) + { + TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED); + } + else + { + if (r->m_type == 1) + { + mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i; + r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32); + for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8; + } + else + { + for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; } + MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; } + r->m_table_sizes[2] = 19; + } + for ( ; (int)r->m_type >= 0; r->m_type--) + { + int tree_next, tree_cur; tinfl_huff_table *pTable; + mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree); + for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++; + used_syms = 0, total = 0; next_code[0] = next_code[1] = 0; + for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); } + if ((65536 != total) && (used_syms > 1)) + { + TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED); + } + for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index) + { + mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue; + cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1); + if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { pTable->m_look_up[rev_code] = k; rev_code += (1 << code_size); } continue; } + if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } + rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1); + for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) + { + tree_cur -= ((rev_code >>= 1) & 1); + if (!pTable->m_tree[-tree_cur - 1]) { pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else tree_cur = pTable->m_tree[-tree_cur - 1]; + } + tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index; + } + if (r->m_type == 2) + { + for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); ) + { + mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; } + if ((dist == 16) && (!counter)) + { + TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED); + } + num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16]; + TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s; + } + if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter) + { + TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); + } + TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); + } + } + for ( ; ; ) + { + mz_uint8 *pSrc; + for ( ; ; ) + { + if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2)) + { + TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]); + if (counter >= 256) + break; + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = (mz_uint8)counter; + } + else + { + int sym2; mz_uint code_len; +#if TINFL_USE_64BIT_BITBUF + if (num_bits < 30) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); pIn_buf_cur += 4; num_bits += 32; } +#else + if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; } +#endif + if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + code_len = sym2 >> 9; + else + { + code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); + } + counter = sym2; bit_buf >>= code_len; num_bits -= code_len; + if (counter & 256) + break; + +#if !TINFL_USE_64BIT_BITBUF + if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; } +#endif + if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + code_len = sym2 >> 9; + else + { + code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); + } + bit_buf >>= code_len; num_bits -= code_len; + + pOut_buf_cur[0] = (mz_uint8)counter; + if (sym2 & 256) + { + pOut_buf_cur++; + counter = sym2; + break; + } + pOut_buf_cur[1] = (mz_uint8)sym2; + pOut_buf_cur += 2; + } + } + if ((counter &= 511) == 256) break; + + num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257]; + if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; } + + TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]); + num_extra = s_dist_extra[dist]; dist = s_dist_base[dist]; + if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; } + + dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start; + if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) + { + TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED); + } + + pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask); + + if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end) + { + while (counter--) + { + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask]; + } + continue; + } +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES + else if ((counter >= 9) && (counter <= dist)) + { + const mz_uint8 *pSrc_end = pSrc + (counter & ~7); + do + { + ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0]; + ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1]; + pOut_buf_cur += 8; + } while ((pSrc += 8) < pSrc_end); + if ((counter &= 7) < 3) + { + if (counter) + { + pOut_buf_cur[0] = pSrc[0]; + if (counter > 1) + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur += counter; + } + continue; + } + } +#endif + do + { + pOut_buf_cur[0] = pSrc[0]; + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur[2] = pSrc[2]; + pOut_buf_cur += 3; pSrc += 3; + } while ((int)(counter -= 3) > 2); + if ((int)counter > 0) + { + pOut_buf_cur[0] = pSrc[0]; + if ((int)counter > 1) + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur += counter; + } + } + } + } while (!(r->m_final & 1)); + if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) + { + TINFL_SKIP_BITS(32, num_bits & 7); for (counter = 0; counter < 4; ++counter) { mz_uint s; if (num_bits) TINFL_GET_BITS(41, s, 8); else TINFL_GET_BYTE(42, s); r->m_z_adler32 = (r->m_z_adler32 << 8) | s; } + } + TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE); + TINFL_CR_FINISH + +common_exit: + r->m_num_bits = num_bits; r->m_bit_buf = bit_buf; r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; r->m_dist_from_out_buf_start = dist_from_out_buf_start; + *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next; + if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0)) + { + const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size; + mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552; + while (buf_len) + { + for (i = 0; i + 7 < block_len; i += 8, ptr += 8) + { + s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1; + s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1; + } + for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1; + s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552; + } + r->m_check_adler32 = (s2 << 16) + s1; if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) status = TINFL_STATUS_ADLER32_MISMATCH; + } + return status; +} + +// Higher level helper functions. +void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) +{ + tinfl_decompressor decomp; void *pBuf = NULL, *pNew_buf; size_t src_buf_ofs = 0, out_buf_capacity = 0; + *pOut_len = 0; + tinfl_init(&decomp); + for ( ; ; ) + { + size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity; + tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8*)pBuf, pBuf ? (mz_uint8*)pBuf + *pOut_len : NULL, &dst_buf_size, + (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); + if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) + { + MZ_FREE(pBuf); *pOut_len = 0; return NULL; + } + src_buf_ofs += src_buf_size; + *pOut_len += dst_buf_size; + if (status == TINFL_STATUS_DONE) break; + new_out_buf_capacity = out_buf_capacity * 2; if (new_out_buf_capacity < 128) new_out_buf_capacity = 128; + pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity); + if (!pNew_buf) + { + MZ_FREE(pBuf); *pOut_len = 0; return NULL; + } + pBuf = pNew_buf; out_buf_capacity = new_out_buf_capacity; + } + return pBuf; +} + +size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) +{ + tinfl_decompressor decomp; tinfl_status status; tinfl_init(&decomp); + status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf, &src_buf_len, (mz_uint8*)pOut_buf, (mz_uint8*)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); + return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len; +} + +int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) +{ + int result = 0; + tinfl_decompressor decomp; + mz_uint8 *pDict = (mz_uint8*)MZ_MALLOC(TINFL_LZ_DICT_SIZE); size_t in_buf_ofs = 0, dict_ofs = 0; + if (!pDict) + return TINFL_STATUS_FAILED; + tinfl_init(&decomp); + for ( ; ; ) + { + size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs; + tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size, + (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))); + in_buf_ofs += in_buf_size; + if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user))) + break; + if (status != TINFL_STATUS_HAS_MORE_OUTPUT) + { + result = (status == TINFL_STATUS_DONE); + break; + } + dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1); + } + MZ_FREE(pDict); + *pIn_buf_size = in_buf_ofs; + return result; +} + +// ------------------- Low-level Compression (independent from all decompression API's) + +// Purposely making these tables static for faster init and thread safety. +static const mz_uint16 s_tdefl_len_sym[256] = { + 257,258,259,260,261,262,263,264,265,265,266,266,267,267,268,268,269,269,269,269,270,270,270,270,271,271,271,271,272,272,272,272, + 273,273,273,273,273,273,273,273,274,274,274,274,274,274,274,274,275,275,275,275,275,275,275,275,276,276,276,276,276,276,276,276, + 277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278, + 279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280, + 281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281, + 282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282, + 283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283, + 284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,285 }; + +static const mz_uint8 s_tdefl_len_extra[256] = { + 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0 }; + +static const mz_uint8 s_tdefl_small_dist_sym[512] = { + 0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17 }; + +static const mz_uint8 s_tdefl_small_dist_extra[512] = { + 0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7 }; + +static const mz_uint8 s_tdefl_large_dist_sym[128] = { + 0,0,18,19,20,20,21,21,22,22,22,22,23,23,23,23,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, + 28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 }; + +static const mz_uint8 s_tdefl_large_dist_extra[128] = { + 0,0,8,8,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13 }; + +// Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values. +typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq; +static tdefl_sym_freq* tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq* pSyms0, tdefl_sym_freq* pSyms1) +{ + mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2]; tdefl_sym_freq* pCur_syms = pSyms0, *pNew_syms = pSyms1; MZ_CLEAR_OBJ(hist); + for (i = 0; i < num_syms; i++) { mz_uint freq = pSyms0[i].m_key; hist[freq & 0xFF]++; hist[256 + ((freq >> 8) & 0xFF)]++; } + while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) total_passes--; + for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8) + { + const mz_uint32* pHist = &hist[pass << 8]; + mz_uint offsets[256], cur_ofs = 0; + for (i = 0; i < 256; i++) { offsets[i] = cur_ofs; cur_ofs += pHist[i]; } + for (i = 0; i < num_syms; i++) pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i]; + { tdefl_sym_freq* t = pCur_syms; pCur_syms = pNew_syms; pNew_syms = t; } + } + return pCur_syms; +} + +// tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996. +static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n) +{ + int root, leaf, next, avbl, used, dpth; + if (n==0) return; else if (n==1) { A[0].m_key = 1; return; } + A[0].m_key += A[1].m_key; root = 0; leaf = 2; + for (next=1; next < n-1; next++) + { + if (leaf>=n || A[root].m_key=n || (root=0; next--) A[next].m_key = A[A[next].m_key].m_key+1; + avbl = 1; used = dpth = 0; root = n-2; next = n-1; + while (avbl>0) + { + while (root>=0 && (int)A[root].m_key==dpth) { used++; root--; } + while (avbl>used) { A[next--].m_key = (mz_uint16)(dpth); avbl--; } + avbl = 2*used; dpth++; used = 0; + } +} + +// Limits canonical Huffman code table's max code size. +enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 }; +static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size) +{ + int i; mz_uint32 total = 0; if (code_list_len <= 1) return; + for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) pNum_codes[max_code_size] += pNum_codes[i]; + for (i = max_code_size; i > 0; i--) total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i)); + while (total != (1UL << max_code_size)) + { + pNum_codes[max_code_size]--; + for (i = max_code_size - 1; i > 0; i--) if (pNum_codes[i]) { pNum_codes[i]--; pNum_codes[i + 1] += 2; break; } + total--; + } +} + +static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table) +{ + int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE]; mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1]; MZ_CLEAR_OBJ(num_codes); + if (static_table) + { + for (i = 0; i < table_len; i++) num_codes[d->m_huff_code_sizes[table_num][i]]++; + } + else + { + tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], *pSyms; + int num_used_syms = 0; + const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0]; + for (i = 0; i < table_len; i++) if (pSym_count[i]) { syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i]; syms0[num_used_syms++].m_sym_index = (mz_uint16)i; } + + pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1); tdefl_calculate_minimum_redundancy(pSyms, num_used_syms); + + for (i = 0; i < num_used_syms; i++) num_codes[pSyms[i].m_key]++; + + tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit); + + MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); MZ_CLEAR_OBJ(d->m_huff_codes[table_num]); + for (i = 1, j = num_used_syms; i <= code_size_limit; i++) + for (l = num_codes[i]; l > 0; l--) d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i); + } + + next_code[1] = 0; for (j = 0, i = 2; i <= code_size_limit; i++) next_code[i] = j = ((j + num_codes[i - 1]) << 1); + + for (i = 0; i < table_len; i++) + { + mz_uint rev_code = 0, code, code_size; if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) continue; + code = next_code[code_size]++; for (l = code_size; l > 0; l--, code >>= 1) rev_code = (rev_code << 1) | (code & 1); + d->m_huff_codes[table_num][i] = (mz_uint16)rev_code; + } +} + +#define TDEFL_PUT_BITS(b, l) do { \ + mz_uint bits = b; mz_uint len = l; MZ_ASSERT(bits <= ((1U << len) - 1U)); \ + d->m_bit_buffer |= (bits << d->m_bits_in); d->m_bits_in += len; \ + while (d->m_bits_in >= 8) { \ + if (d->m_pOutput_buf < d->m_pOutput_buf_end) \ + *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \ + d->m_bit_buffer >>= 8; \ + d->m_bits_in -= 8; \ + } \ +} MZ_MACRO_END + +#define TDEFL_RLE_PREV_CODE_SIZE() { if (rle_repeat_count) { \ + if (rle_repeat_count < 3) { \ + d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \ + while (rle_repeat_count--) packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \ + } else { \ + d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); packed_code_sizes[num_packed_code_sizes++] = 16; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \ +} rle_repeat_count = 0; } } + +#define TDEFL_RLE_ZERO_CODE_SIZE() { if (rle_z_count) { \ + if (rle_z_count < 3) { \ + d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); while (rle_z_count--) packed_code_sizes[num_packed_code_sizes++] = 0; \ + } else if (rle_z_count <= 10) { \ + d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); packed_code_sizes[num_packed_code_sizes++] = 17; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \ + } else { \ + d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); packed_code_sizes[num_packed_code_sizes++] = 18; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \ +} rle_z_count = 0; } } + +static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; + +static void tdefl_start_dynamic_block(tdefl_compressor *d) +{ + int num_lit_codes, num_dist_codes, num_bit_lengths; mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index; + mz_uint8 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], prev_code_size = 0xFF; + + d->m_huff_count[0][256] = 1; + + tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE); + tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE); + + for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) if (d->m_huff_code_sizes[0][num_lit_codes - 1]) break; + for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) if (d->m_huff_code_sizes[1][num_dist_codes - 1]) break; + + memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes); + memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes); + total_code_sizes_to_pack = num_lit_codes + num_dist_codes; num_packed_code_sizes = 0; rle_z_count = 0; rle_repeat_count = 0; + + memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2); + for (i = 0; i < total_code_sizes_to_pack; i++) + { + mz_uint8 code_size = code_sizes_to_pack[i]; + if (!code_size) + { + TDEFL_RLE_PREV_CODE_SIZE(); + if (++rle_z_count == 138) { TDEFL_RLE_ZERO_CODE_SIZE(); } + } + else + { + TDEFL_RLE_ZERO_CODE_SIZE(); + if (code_size != prev_code_size) + { + TDEFL_RLE_PREV_CODE_SIZE(); + d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1); packed_code_sizes[num_packed_code_sizes++] = code_size; + } + else if (++rle_repeat_count == 6) + { + TDEFL_RLE_PREV_CODE_SIZE(); + } + } + prev_code_size = code_size; + } + if (rle_repeat_count) { TDEFL_RLE_PREV_CODE_SIZE(); } else { TDEFL_RLE_ZERO_CODE_SIZE(); } + + tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE); + + TDEFL_PUT_BITS(2, 2); + + TDEFL_PUT_BITS(num_lit_codes - 257, 5); + TDEFL_PUT_BITS(num_dist_codes - 1, 5); + + for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--) if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]]) break; + num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1)); TDEFL_PUT_BITS(num_bit_lengths - 4, 4); + for (i = 0; (int)i < num_bit_lengths; i++) TDEFL_PUT_BITS(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3); + + for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes; ) + { + mz_uint code = packed_code_sizes[packed_code_sizes_index++]; MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2); + TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]); + if (code >= 16) TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]); + } +} + +static void tdefl_start_static_block(tdefl_compressor *d) +{ + mz_uint i; + mz_uint8 *p = &d->m_huff_code_sizes[0][0]; + + for (i = 0; i <= 143; ++i) *p++ = 8; + for ( ; i <= 255; ++i) *p++ = 9; + for ( ; i <= 279; ++i) *p++ = 7; + for ( ; i <= 287; ++i) *p++ = 8; + + memset(d->m_huff_code_sizes[1], 5, 32); + + tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE); + tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE); + + TDEFL_PUT_BITS(1, 2); +} + +static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS +static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) +{ + mz_uint flags; + mz_uint8 *pLZ_codes; + mz_uint8 *pOutput_buf = d->m_pOutput_buf; + mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf; + mz_uint64 bit_buffer = d->m_bit_buffer; + mz_uint bits_in = d->m_bits_in; + +#define TDEFL_PUT_BITS_FAST(b, l) { bit_buffer |= (((mz_uint64)(b)) << bits_in); bits_in += (l); } + + flags = 1; + for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1) + { + if (flags == 1) + flags = *pLZ_codes++ | 0x100; + + if (flags & 1) + { + mz_uint s0, s1, n0, n1, sym, num_extra_bits; + mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1); pLZ_codes += 3; + + MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]); + + // This sequence coaxes MSVC into using cmov's vs. jmp's. + s0 = s_tdefl_small_dist_sym[match_dist & 511]; + n0 = s_tdefl_small_dist_extra[match_dist & 511]; + s1 = s_tdefl_large_dist_sym[match_dist >> 8]; + n1 = s_tdefl_large_dist_extra[match_dist >> 8]; + sym = (match_dist < 512) ? s0 : s1; + num_extra_bits = (match_dist < 512) ? n0 : n1; + + MZ_ASSERT(d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); + } + else + { + mz_uint lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + + if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) + { + flags >>= 1; + lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + + if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) + { + flags >>= 1; + lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + } + } + } + + if (pOutput_buf >= d->m_pOutput_buf_end) + return MZ_FALSE; + + *(mz_uint64*)pOutput_buf = bit_buffer; + pOutput_buf += (bits_in >> 3); + bit_buffer >>= (bits_in & ~7); + bits_in &= 7; + } + +#undef TDEFL_PUT_BITS_FAST + + d->m_pOutput_buf = pOutput_buf; + d->m_bits_in = 0; + d->m_bit_buffer = 0; + + while (bits_in) + { + mz_uint32 n = MZ_MIN(bits_in, 16); + TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n); + bit_buffer >>= n; + bits_in -= n; + } + + TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); + + return (d->m_pOutput_buf < d->m_pOutput_buf_end); +} +#else +static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) +{ + mz_uint flags; + mz_uint8 *pLZ_codes; + + flags = 1; + for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1) + { + if (flags == 1) + flags = *pLZ_codes++ | 0x100; + if (flags & 1) + { + mz_uint sym, num_extra_bits; + mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); pLZ_codes += 3; + + MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]); + + if (match_dist < 512) + { + sym = s_tdefl_small_dist_sym[match_dist]; num_extra_bits = s_tdefl_small_dist_extra[match_dist]; + } + else + { + sym = s_tdefl_large_dist_sym[match_dist >> 8]; num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8]; + } + MZ_ASSERT(d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); + } + else + { + mz_uint lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + } + } + + TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); + + return (d->m_pOutput_buf < d->m_pOutput_buf_end); +} +#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS + +static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block) +{ + if (static_block) + tdefl_start_static_block(d); + else + tdefl_start_dynamic_block(d); + return tdefl_compress_lz_codes(d); +} + +static int tdefl_flush_block(tdefl_compressor *d, int flush) +{ + mz_uint saved_bit_buf, saved_bits_in; + mz_uint8 *pSaved_output_buf; + mz_bool comp_block_succeeded = MZ_FALSE; + int n, use_raw_block = ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size; + mz_uint8 *pOutput_buf_start = ((d->m_pPut_buf_func == NULL) && ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) : d->m_output_buf; + + d->m_pOutput_buf = pOutput_buf_start; + d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16; + + MZ_ASSERT(!d->m_output_flush_remaining); + d->m_output_flush_ofs = 0; + d->m_output_flush_remaining = 0; + + *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left); + d->m_pLZ_code_buf -= (d->m_num_flags_left == 8); + + if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index)) + { + TDEFL_PUT_BITS(0x78, 8); TDEFL_PUT_BITS(0x01, 8); + } + + TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1); + + pSaved_output_buf = d->m_pOutput_buf; saved_bit_buf = d->m_bit_buffer; saved_bits_in = d->m_bits_in; + + if (!use_raw_block) + comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48)); + + // If the block gets expanded, forget the current contents of the output buffer and send a raw block instead. + if ( ((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) && + ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size) ) + { + mz_uint i; d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; + TDEFL_PUT_BITS(0, 2); + if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } + for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF) + { + TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16); + } + for (i = 0; i < d->m_total_lz_bytes; ++i) + { + TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8); + } + } + // Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes. + else if (!comp_block_succeeded) + { + d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; + tdefl_compress_block(d, MZ_TRUE); + } + + if (flush) + { + if (flush == TDEFL_FINISH) + { + if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } + if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) { mz_uint i, a = d->m_adler32; for (i = 0; i < 4; i++) { TDEFL_PUT_BITS((a >> 24) & 0xFF, 8); a <<= 8; } } + } + else + { + mz_uint i, z = 0; TDEFL_PUT_BITS(0, 3); if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } for (i = 2; i; --i, z ^= 0xFFFF) { TDEFL_PUT_BITS(z & 0xFFFF, 16); } + } + } + + MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end); + + memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); + memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); + + d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8; d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes; d->m_total_lz_bytes = 0; d->m_block_index++; + + if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0) + { + if (d->m_pPut_buf_func) + { + *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; + if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user)) + return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED); + } + else if (pOutput_buf_start == d->m_output_buf) + { + int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs)); + memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy); + d->m_out_buf_ofs += bytes_to_copy; + if ((n -= bytes_to_copy) != 0) + { + d->m_output_flush_ofs = bytes_to_copy; + d->m_output_flush_remaining = n; + } + } + else + { + d->m_out_buf_ofs += n; + } + } + + return d->m_output_flush_remaining; +} + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES +#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16*)(p) +static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) +{ + mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len; + mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; + const mz_uint16 *s = (const mz_uint16*)(d->m_dict + pos), *p, *q; + mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD(s); + MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return; + for ( ; ; ) + { + for ( ; ; ) + { + if (--num_probes_left == 0) return; + #define TDEFL_PROBE \ + next_probe_pos = d->m_next[probe_pos]; \ + if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \ + probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ + if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) break; + TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE; + } + if (!dist) break; q = (const mz_uint16*)(d->m_dict + probe_pos); if (TDEFL_READ_UNALIGNED_WORD(q) != s01) continue; p = s; probe_len = 32; + do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && + (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) ); + if (!probe_len) + { + *pMatch_dist = dist; *pMatch_len = MZ_MIN(max_match_len, TDEFL_MAX_MATCH_LEN); break; + } + else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8*)p == *(const mz_uint8*)q)) > match_len) + { + *pMatch_dist = dist; if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len) break; + c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]); + } + } +} +#else +static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) +{ + mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len; + mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; + const mz_uint8 *s = d->m_dict + pos, *p, *q; + mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1]; + MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return; + for ( ; ; ) + { + for ( ; ; ) + { + if (--num_probes_left == 0) return; + #define TDEFL_PROBE \ + next_probe_pos = d->m_next[probe_pos]; \ + if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \ + probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ + if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) break; + TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE; + } + if (!dist) break; p = s; q = d->m_dict + probe_pos; for (probe_len = 0; probe_len < max_match_len; probe_len++) if (*p++ != *q++) break; + if (probe_len > match_len) + { + *pMatch_dist = dist; if ((*pMatch_len = match_len = probe_len) == max_match_len) return; + c0 = d->m_dict[pos + match_len]; c1 = d->m_dict[pos + match_len - 1]; + } + } +} +#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN +static mz_bool tdefl_compress_fast(tdefl_compressor *d) +{ + // Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio. + mz_uint lookahead_pos = d->m_lookahead_pos, lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, total_lz_bytes = d->m_total_lz_bytes, num_flags_left = d->m_num_flags_left; + mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags; + mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; + + while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size))) + { + const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096; + mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; + mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size); + d->m_src_buf_left -= num_bytes_to_process; + lookahead_size += num_bytes_to_process; + + while (num_bytes_to_process) + { + mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process); + memcpy(d->m_dict + dst_pos, d->m_pSrc, n); + if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) + memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos)); + d->m_pSrc += n; + dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK; + num_bytes_to_process -= n; + } + + dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size); + if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE)) break; + + while (lookahead_size >= 4) + { + mz_uint cur_match_dist, cur_match_len = 1; + mz_uint8 *pCur_dict = d->m_dict + cur_pos; + mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF; + mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK; + mz_uint probe_pos = d->m_hash[hash]; + d->m_hash[hash] = (mz_uint16)lookahead_pos; + + if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((*(const mz_uint32 *)(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram)) + { + const mz_uint16 *p = (const mz_uint16 *)pCur_dict; + const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos); + mz_uint32 probe_len = 32; + do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && + (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) ); + cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q); + if (!probe_len) + cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0; + + if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U))) + { + cur_match_len = 1; + *pLZ_code_buf++ = (mz_uint8)first_trigram; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + d->m_huff_count[0][(mz_uint8)first_trigram]++; + } + else + { + mz_uint32 s0, s1; + cur_match_len = MZ_MIN(cur_match_len, lookahead_size); + + MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE)); + + cur_match_dist--; + + pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN); + *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist; + pLZ_code_buf += 3; + *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80); + + s0 = s_tdefl_small_dist_sym[cur_match_dist & 511]; + s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8]; + d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++; + + d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++; + } + } + else + { + *pLZ_code_buf++ = (mz_uint8)first_trigram; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + d->m_huff_count[0][(mz_uint8)first_trigram]++; + } + + if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; } + + total_lz_bytes += cur_match_len; + lookahead_pos += cur_match_len; + dict_size = MZ_MIN(dict_size + cur_match_len, TDEFL_LZ_DICT_SIZE); + cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK; + MZ_ASSERT(lookahead_size >= cur_match_len); + lookahead_size -= cur_match_len; + + if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) + { + int n; + d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left; + } + } + + while (lookahead_size) + { + mz_uint8 lit = d->m_dict[cur_pos]; + + total_lz_bytes++; + *pLZ_code_buf++ = lit; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; } + + d->m_huff_count[0][lit]++; + + lookahead_pos++; + dict_size = MZ_MIN(dict_size + 1, TDEFL_LZ_DICT_SIZE); + cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; + lookahead_size--; + + if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) + { + int n; + d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left; + } + } + } + + d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; + return MZ_TRUE; +} +#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + +static MZ_FORCEINLINE void tdefl_record_literal(tdefl_compressor *d, mz_uint8 lit) +{ + d->m_total_lz_bytes++; + *d->m_pLZ_code_buf++ = lit; + *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; } + d->m_huff_count[0][lit]++; +} + +static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist) +{ + mz_uint32 s0, s1; + + MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE)); + + d->m_total_lz_bytes += match_len; + + d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN); + + match_dist -= 1; + d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF); + d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8); d->m_pLZ_code_buf += 3; + + *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; } + + s0 = s_tdefl_small_dist_sym[match_dist & 511]; s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127]; + d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++; + + if (match_len >= TDEFL_MIN_MATCH_LEN) d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++; +} + +static mz_bool tdefl_compress_normal(tdefl_compressor *d) +{ + const mz_uint8 *pSrc = d->m_pSrc; size_t src_buf_left = d->m_src_buf_left; + tdefl_flush flush = d->m_flush; + + while ((src_buf_left) || ((flush) && (d->m_lookahead_size))) + { + mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos; + // Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN. + if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1)) + { + mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2; + mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK]; + mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size); + const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process; + src_buf_left -= num_bytes_to_process; + d->m_lookahead_size += num_bytes_to_process; + while (pSrc != pSrc_end) + { + mz_uint8 c = *pSrc++; d->m_dict[dst_pos] = c; if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; + hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); + d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos); + dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; ins_pos++; + } + } + else + { + while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) + { + mz_uint8 c = *pSrc++; + mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; + src_buf_left--; + d->m_dict[dst_pos] = c; + if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) + d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; + if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN) + { + mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2; + mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << (TDEFL_LZ_HASH_SHIFT * 2)) ^ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); + d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos); + } + } + } + d->m_dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size); + if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) + break; + + // Simple lazy/greedy parsing state machine. + len_to_move = 1; cur_match_dist = 0; cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1); cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; + if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS)) + { + if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) + { + mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK]; + cur_match_len = 0; while (cur_match_len < d->m_lookahead_size) { if (d->m_dict[cur_pos + cur_match_len] != c) break; cur_match_len++; } + if (cur_match_len < TDEFL_MIN_MATCH_LEN) cur_match_len = 0; else cur_match_dist = 1; + } + } + else + { + tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len); + } + if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U)) || (cur_pos == cur_match_dist) || ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5))) + { + cur_match_dist = cur_match_len = 0; + } + if (d->m_saved_match_len) + { + if (cur_match_len > d->m_saved_match_len) + { + tdefl_record_literal(d, (mz_uint8)d->m_saved_lit); + if (cur_match_len >= 128) + { + tdefl_record_match(d, cur_match_len, cur_match_dist); + d->m_saved_match_len = 0; len_to_move = cur_match_len; + } + else + { + d->m_saved_lit = d->m_dict[cur_pos]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len; + } + } + else + { + tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist); + len_to_move = d->m_saved_match_len - 1; d->m_saved_match_len = 0; + } + } + else if (!cur_match_dist) + tdefl_record_literal(d, d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]); + else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128)) + { + tdefl_record_match(d, cur_match_len, cur_match_dist); + len_to_move = cur_match_len; + } + else + { + d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len; + } + // Move the lookahead forward by len_to_move bytes. + d->m_lookahead_pos += len_to_move; + MZ_ASSERT(d->m_lookahead_size >= len_to_move); + d->m_lookahead_size -= len_to_move; + d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, TDEFL_LZ_DICT_SIZE); + // Check if it's time to flush the current LZ codes to the internal output buffer. + if ( (d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) || + ( (d->m_total_lz_bytes > 31*1024) && (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= d->m_total_lz_bytes) || (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) ) + { + int n; + d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + } + } + + d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left; + return MZ_TRUE; +} + +static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d) +{ + if (d->m_pIn_buf_size) + { + *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; + } + + if (d->m_pOut_buf_size) + { + size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, d->m_output_flush_remaining); + memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n); + d->m_output_flush_ofs += (mz_uint)n; + d->m_output_flush_remaining -= (mz_uint)n; + d->m_out_buf_ofs += n; + + *d->m_pOut_buf_size = d->m_out_buf_ofs; + } + + return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE : TDEFL_STATUS_OKAY; +} + +tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush) +{ + if (!d) + { + if (pIn_buf_size) *pIn_buf_size = 0; + if (pOut_buf_size) *pOut_buf_size = 0; + return TDEFL_STATUS_BAD_PARAM; + } + + d->m_pIn_buf = pIn_buf; d->m_pIn_buf_size = pIn_buf_size; + d->m_pOut_buf = pOut_buf; d->m_pOut_buf_size = pOut_buf_size; + d->m_pSrc = (const mz_uint8 *)(pIn_buf); d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0; + d->m_out_buf_ofs = 0; + d->m_flush = flush; + + if ( ((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) || + (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf) ) + { + if (pIn_buf_size) *pIn_buf_size = 0; + if (pOut_buf_size) *pOut_buf_size = 0; + return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM); + } + d->m_wants_to_finish |= (flush == TDEFL_FINISH); + + if ((d->m_output_flush_remaining) || (d->m_finished)) + return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) && + ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) && + ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | TDEFL_RLE_MATCHES)) == 0)) + { + if (!tdefl_compress_fast(d)) + return d->m_prev_return_status; + } + else +#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + { + if (!tdefl_compress_normal(d)) + return d->m_prev_return_status; + } + + if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf)) + d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf); + + if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining)) + { + if (tdefl_flush_block(d, flush) < 0) + return d->m_prev_return_status; + d->m_finished = (flush == TDEFL_FINISH); + if (flush == TDEFL_FULL_FLUSH) { MZ_CLEAR_OBJ(d->m_hash); MZ_CLEAR_OBJ(d->m_next); d->m_dict_size = 0; } + } + + return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); +} + +tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush) +{ + MZ_ASSERT(d->m_pPut_buf_func); return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush); +} + +tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) +{ + d->m_pPut_buf_func = pPut_buf_func; d->m_pPut_buf_user = pPut_buf_user; + d->m_flags = (mz_uint)(flags); d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3; d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0; + d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3; + if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) MZ_CLEAR_OBJ(d->m_hash); + d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0; + d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0; + d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8; + d->m_pOutput_buf = d->m_output_buf; d->m_pOutput_buf_end = d->m_output_buf; d->m_prev_return_status = TDEFL_STATUS_OKAY; + d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0; d->m_adler32 = 1; + d->m_pIn_buf = NULL; d->m_pOut_buf = NULL; + d->m_pIn_buf_size = NULL; d->m_pOut_buf_size = NULL; + d->m_flush = TDEFL_NO_FLUSH; d->m_pSrc = NULL; d->m_src_buf_left = 0; d->m_out_buf_ofs = 0; + memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); + memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); + return TDEFL_STATUS_OKAY; +} + +tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d) +{ + return d->m_prev_return_status; +} + +mz_uint32 tdefl_get_adler32(tdefl_compressor *d) +{ + return d->m_adler32; +} + +mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) +{ + tdefl_compressor *pComp; mz_bool succeeded; if (((buf_len) && (!pBuf)) || (!pPut_buf_func)) return MZ_FALSE; + pComp = (tdefl_compressor*)MZ_MALLOC(sizeof(tdefl_compressor)); if (!pComp) return MZ_FALSE; + succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY); + succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE); + MZ_FREE(pComp); return succeeded; +} + +typedef struct +{ + size_t m_size, m_capacity; + mz_uint8 *m_pBuf; + mz_bool m_expandable; +} tdefl_output_buffer; + +static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser) +{ + tdefl_output_buffer *p = (tdefl_output_buffer *)pUser; + size_t new_size = p->m_size + len; + if (new_size > p->m_capacity) + { + size_t new_capacity = p->m_capacity; mz_uint8 *pNew_buf; if (!p->m_expandable) return MZ_FALSE; + do { new_capacity = MZ_MAX(128U, new_capacity << 1U); } while (new_size > new_capacity); + pNew_buf = (mz_uint8*)MZ_REALLOC(p->m_pBuf, new_capacity); if (!pNew_buf) return MZ_FALSE; + p->m_pBuf = pNew_buf; p->m_capacity = new_capacity; + } + memcpy((mz_uint8*)p->m_pBuf + p->m_size, pBuf, len); p->m_size = new_size; + return MZ_TRUE; +} + +void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) +{ + tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf); + if (!pOut_len) return MZ_FALSE; else *pOut_len = 0; + out_buf.m_expandable = MZ_TRUE; + if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return NULL; + *pOut_len = out_buf.m_size; return out_buf.m_pBuf; +} + +size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) +{ + tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf); + if (!pOut_buf) return 0; + out_buf.m_pBuf = (mz_uint8*)pOut_buf; out_buf.m_capacity = out_buf_len; + if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return 0; + return out_buf.m_size; +} + +#ifndef MINIZ_NO_ZLIB_APIS +static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; + +// level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files). +mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy) +{ + mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); + if (window_bits > 0) comp_flags |= TDEFL_WRITE_ZLIB_HEADER; + + if (!level) comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; + else if (strategy == MZ_FILTERED) comp_flags |= TDEFL_FILTER_MATCHES; + else if (strategy == MZ_HUFFMAN_ONLY) comp_flags &= ~TDEFL_MAX_PROBES_MASK; + else if (strategy == MZ_FIXED) comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS; + else if (strategy == MZ_RLE) comp_flags |= TDEFL_RLE_MATCHES; + + return comp_flags; +} +#endif //MINIZ_NO_ZLIB_APIS + +#ifdef _MSC_VER +#pragma warning (push) +#pragma warning (disable:4204) // nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal) +#endif + +// Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at +// http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/. +void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out) +{ + tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); tdefl_output_buffer out_buf; int i, bpl = w * num_chans, y, z; mz_uint32 c; *pLen_out = 0; + if (!pComp) return NULL; + MZ_CLEAR_OBJ(out_buf); out_buf.m_expandable = MZ_TRUE; out_buf.m_capacity = 57+MZ_MAX(64, (1+bpl)*h); if (NULL == (out_buf.m_pBuf = (mz_uint8*)MZ_MALLOC(out_buf.m_capacity))) { MZ_FREE(pComp); return NULL; } + // write dummy header + for (z = 41; z; --z) tdefl_output_buffer_putter(&z, 1, &out_buf); + // compress image data + tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, TDEFL_DEFAULT_MAX_PROBES | TDEFL_WRITE_ZLIB_HEADER); + for (y = 0; y < h; ++y) { tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); tdefl_compress_buffer(pComp, (mz_uint8*)pImage + y * bpl, bpl, TDEFL_NO_FLUSH); } + if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE) { MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; } + // write real header + *pLen_out = out_buf.m_size-41; + { + mz_uint8 pnghdr[41]={0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52, + 0,0,(mz_uint8)(w>>8),(mz_uint8)w,0,0,(mz_uint8)(h>>8),(mz_uint8)h,8,"\0\0\04\02\06"[num_chans],0,0,0,0,0,0,0, + (mz_uint8)(*pLen_out>>24),(mz_uint8)(*pLen_out>>16),(mz_uint8)(*pLen_out>>8),(mz_uint8)*pLen_out,0x49,0x44,0x41,0x54}; + c=(mz_uint32)mz_crc32(MZ_CRC32_INIT,pnghdr+12,17); for (i=0; i<4; ++i, c<<=8) ((mz_uint8*)(pnghdr+29))[i]=(mz_uint8)(c>>24); + memcpy(out_buf.m_pBuf, pnghdr, 41); + } + // write footer (IDAT CRC-32, followed by IEND chunk) + if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) { *pLen_out = 0; MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; } + c = (mz_uint32)mz_crc32(MZ_CRC32_INIT,out_buf.m_pBuf+41-4, *pLen_out+4); for (i=0; i<4; ++i, c<<=8) (out_buf.m_pBuf+out_buf.m_size-16)[i] = (mz_uint8)(c >> 24); + // compute final size of file, grab compressed data buffer and return + *pLen_out += 57; MZ_FREE(pComp); return out_buf.m_pBuf; +} + +#ifdef _MSC_VER +#pragma warning (pop) +#endif + +// ------------------- .ZIP archive reading + +#ifndef MINIZ_NO_ARCHIVE_APIS + +#ifdef MINIZ_NO_STDIO + #define MZ_FILE void * +#else + #include + #include + + #if defined(_MSC_VER) + static FILE *mz_fopen(const char *pFilename, const char *pMode) + { + FILE* pFile = NULL; + fopen_s(&pFile, pFilename, pMode); + return pFile; + } + static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) + { + FILE* pFile = NULL; + if (freopen_s(&pFile, pPath, pMode, pStream)) + return NULL; + return pFile; + } + #else + static FILE *mz_fopen(const char *pFilename, const char *pMode) + { + return fopen(pFilename, pMode); + } + static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) + { + return freopen(pPath, pMode, pStream); + } + #endif // #if defined(_MSC_VER) + + #if defined(_MSC_VER) || defined(__MINGW64__) + #ifndef MINIZ_NO_TIME + #include + #endif + #define MZ_FILE FILE + #define MZ_FOPEN mz_fopen + #define MZ_FCLOSE fclose + #define MZ_FREAD fread + #define MZ_FWRITE fwrite + #define MZ_FTELL64 _ftelli64 + #define MZ_FSEEK64 _fseeki64 + #define MZ_FILE_STAT_STRUCT _stat + #define MZ_FILE_STAT _stat + #define MZ_FFLUSH fflush + #define MZ_FREOPEN mz_freopen + #define MZ_DELETE_FILE remove + #elif defined(__MINGW32__) + #ifndef MINIZ_NO_TIME + #include + #endif + #define MZ_FILE FILE + #define MZ_FOPEN mz_fopen + #define MZ_FCLOSE fclose + #define MZ_FREAD fread + #define MZ_FWRITE fwrite + #define MZ_FTELL64 ftello64 + #define MZ_FSEEK64 fseeko64 + #define MZ_FILE_STAT_STRUCT _stat + #define MZ_FILE_STAT _stat + #define MZ_FFLUSH fflush + #define MZ_FREOPEN mz_freopen + #define MZ_DELETE_FILE remove + #elif defined(__TINYC__) + #ifndef MINIZ_NO_TIME + #include + #endif + #define MZ_FILE FILE + #define MZ_FOPEN mz_fopen + #define MZ_FCLOSE fclose + #define MZ_FREAD fread + #define MZ_FWRITE fwrite + #define MZ_FTELL64 ftell + #define MZ_FSEEK64 fseek + #define MZ_FILE_STAT_STRUCT stat + #define MZ_FILE_STAT stat + #define MZ_FFLUSH fflush + #define MZ_FREOPEN mz_freopen + #define MZ_DELETE_FILE remove + #else + #ifndef MINIZ_NO_TIME + #include + #endif + #define MZ_FILE FILE + #define MZ_FOPEN mz_fopen + #define MZ_FCLOSE fclose + #define MZ_FREAD fread + #define MZ_FWRITE fwrite + #define MZ_FTELL64 ftello + #define MZ_FSEEK64 fseeko + #define MZ_FILE_STAT_STRUCT stat + #define MZ_FILE_STAT stat + #define MZ_FFLUSH fflush + #define MZ_FREOPEN mz_freopen + #define MZ_DELETE_FILE remove + #endif // #ifdef _MSC_VER +#endif // #ifdef MINIZ_NO_STDIO + +#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c)) + +// Various ZIP archive enums. To completely avoid cross platform compiler alignment and platform endian issues, miniz.c doesn't use structs for any of this stuff. +enum +{ + // ZIP archive identifiers and record sizes + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06054b50, MZ_ZIP_CENTRAL_DIR_HEADER_SIG = 0x02014b50, MZ_ZIP_LOCAL_DIR_HEADER_SIG = 0x04034b50, + MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22, + // Central directory header record offsets + MZ_ZIP_CDH_SIG_OFS = 0, MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4, MZ_ZIP_CDH_VERSION_NEEDED_OFS = 6, MZ_ZIP_CDH_BIT_FLAG_OFS = 8, + MZ_ZIP_CDH_METHOD_OFS = 10, MZ_ZIP_CDH_FILE_TIME_OFS = 12, MZ_ZIP_CDH_FILE_DATE_OFS = 14, MZ_ZIP_CDH_CRC32_OFS = 16, + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS = 20, MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS = 24, MZ_ZIP_CDH_FILENAME_LEN_OFS = 28, MZ_ZIP_CDH_EXTRA_LEN_OFS = 30, + MZ_ZIP_CDH_COMMENT_LEN_OFS = 32, MZ_ZIP_CDH_DISK_START_OFS = 34, MZ_ZIP_CDH_INTERNAL_ATTR_OFS = 36, MZ_ZIP_CDH_EXTERNAL_ATTR_OFS = 38, MZ_ZIP_CDH_LOCAL_HEADER_OFS = 42, + // Local directory header offsets + MZ_ZIP_LDH_SIG_OFS = 0, MZ_ZIP_LDH_VERSION_NEEDED_OFS = 4, MZ_ZIP_LDH_BIT_FLAG_OFS = 6, MZ_ZIP_LDH_METHOD_OFS = 8, MZ_ZIP_LDH_FILE_TIME_OFS = 10, + MZ_ZIP_LDH_FILE_DATE_OFS = 12, MZ_ZIP_LDH_CRC32_OFS = 14, MZ_ZIP_LDH_COMPRESSED_SIZE_OFS = 18, MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS = 22, + MZ_ZIP_LDH_FILENAME_LEN_OFS = 26, MZ_ZIP_LDH_EXTRA_LEN_OFS = 28, + // End of central directory offsets + MZ_ZIP_ECDH_SIG_OFS = 0, MZ_ZIP_ECDH_NUM_THIS_DISK_OFS = 4, MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS = 6, MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 8, + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS = 10, MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12, MZ_ZIP_ECDH_CDIR_OFS_OFS = 16, MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20, +}; + +typedef struct +{ + void *m_p; + size_t m_size, m_capacity; + mz_uint m_element_size; +} mz_zip_array; + +struct mz_zip_internal_state_tag +{ + mz_zip_array m_central_dir; + mz_zip_array m_central_dir_offsets; + mz_zip_array m_sorted_central_dir_offsets; + MZ_FILE *m_pFile; + void *m_pMem; + size_t m_mem_size; + size_t m_mem_capacity; +}; + +#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size +#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[index] + +static MZ_FORCEINLINE void mz_zip_array_clear(mz_zip_archive *pZip, mz_zip_array *pArray) +{ + pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p); + memset(pArray, 0, sizeof(mz_zip_array)); +} + +static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, mz_zip_array *pArray, size_t min_new_capacity, mz_uint growing) +{ + void *pNew_p; size_t new_capacity = min_new_capacity; MZ_ASSERT(pArray->m_element_size); if (pArray->m_capacity >= min_new_capacity) return MZ_TRUE; + if (growing) { new_capacity = MZ_MAX(1, pArray->m_capacity); while (new_capacity < min_new_capacity) new_capacity *= 2; } + if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, pArray->m_element_size, new_capacity))) return MZ_FALSE; + pArray->m_p = pNew_p; pArray->m_capacity = new_capacity; + return MZ_TRUE; +} + +static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_capacity, mz_uint growing) +{ + if (new_capacity > pArray->m_capacity) { if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing)) return MZ_FALSE; } + return MZ_TRUE; +} + +static MZ_FORCEINLINE mz_bool mz_zip_array_resize(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_size, mz_uint growing) +{ + if (new_size > pArray->m_capacity) { if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing)) return MZ_FALSE; } + pArray->m_size = new_size; + return MZ_TRUE; +} + +static MZ_FORCEINLINE mz_bool mz_zip_array_ensure_room(mz_zip_archive *pZip, mz_zip_array *pArray, size_t n) +{ + return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE); +} + +static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(mz_zip_archive *pZip, mz_zip_array *pArray, const void *pElements, size_t n) +{ + size_t orig_size = pArray->m_size; if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE)) return MZ_FALSE; + memcpy((mz_uint8*)pArray->m_p + orig_size * pArray->m_element_size, pElements, n * pArray->m_element_size); + return MZ_TRUE; +} + +#ifndef MINIZ_NO_TIME +static time_t mz_zip_dos_to_time_t(int dos_time, int dos_date) +{ + struct tm tm; + memset(&tm, 0, sizeof(tm)); tm.tm_isdst = -1; + tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900; tm.tm_mon = ((dos_date >> 5) & 15) - 1; tm.tm_mday = dos_date & 31; + tm.tm_hour = (dos_time >> 11) & 31; tm.tm_min = (dos_time >> 5) & 63; tm.tm_sec = (dos_time << 1) & 62; + return mktime(&tm); +} + +static void mz_zip_time_to_dos_time(time_t time, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date) +{ +#ifdef _MSC_VER + struct tm tm_struct; + struct tm *tm = &tm_struct; + errno_t err = localtime_s(tm, &time); + if (err) + { + *pDOS_date = 0; *pDOS_time = 0; + return; + } +#else + struct tm *tm = localtime(&time); +#endif + *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1)); + *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday); +} +#endif + +#ifndef MINIZ_NO_STDIO +static mz_bool mz_zip_get_file_modified_time(const char *pFilename, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date) +{ +#ifdef MINIZ_NO_TIME + (void)pFilename; *pDOS_date = *pDOS_time = 0; +#else + struct MZ_FILE_STAT_STRUCT file_stat; if (MZ_FILE_STAT(pFilename, &file_stat) != 0) return MZ_FALSE; + mz_zip_time_to_dos_time(file_stat.st_mtime, pDOS_time, pDOS_date); +#endif // #ifdef MINIZ_NO_TIME + return MZ_TRUE; +} + +static mz_bool mz_zip_set_file_times(const char *pFilename, time_t access_time, time_t modified_time) +{ +#ifndef MINIZ_NO_TIME + struct utimbuf t; t.actime = access_time; t.modtime = modified_time; + return !utime(pFilename, &t); +#else + (void)pFilename, (void)access_time, (void)modified_time; + return MZ_TRUE; +#endif // #ifndef MINIZ_NO_TIME +} +#endif + +static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, mz_uint32 flags) +{ + (void)flags; + if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID)) + return MZ_FALSE; + + if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func; + if (!pZip->m_pFree) pZip->m_pFree = def_free_func; + if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func; + + pZip->m_zip_mode = MZ_ZIP_MODE_READING; + pZip->m_archive_size = 0; + pZip->m_central_directory_file_ofs = 0; + pZip->m_total_files = 0; + + if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state)))) + return MZ_FALSE; + memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32)); + return MZ_TRUE; +} + +static MZ_FORCEINLINE mz_bool mz_zip_reader_filename_less(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, mz_uint r_index) +{ + const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE; + const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index)); + mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS), r_len = MZ_READ_LE16(pR + MZ_ZIP_CDH_FILENAME_LEN_OFS); + mz_uint8 l = 0, r = 0; + pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; pR += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; + pE = pL + MZ_MIN(l_len, r_len); + while (pL < pE) + { + if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR))) + break; + pL++; pR++; + } + return (pL == pE) ? (l_len < r_len) : (l < r); +} + +#define MZ_SWAP_UINT32(a, b) do { mz_uint32 t = a; a = b; b = t; } MZ_MACRO_END + +// Heap sort of lowercased filenames, used to help accelerate plain central directory searches by mz_zip_reader_locate_file(). (Could also use qsort(), but it could allocate memory.) +static void mz_zip_reader_sort_central_dir_offsets_by_filename(mz_zip_archive *pZip) +{ + mz_zip_internal_state *pState = pZip->m_pState; + const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets; + const mz_zip_array *pCentral_dir = &pState->m_central_dir; + mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0); + const int size = pZip->m_total_files; + int start = (size - 2) >> 1, end; + while (start >= 0) + { + int child, root = start; + for ( ; ; ) + { + if ((child = (root << 1) + 1) >= size) + break; + child += (((child + 1) < size) && (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1]))); + if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child])) + break; + MZ_SWAP_UINT32(pIndices[root], pIndices[child]); root = child; + } + start--; + } + + end = size - 1; + while (end > 0) + { + int child, root = 0; + MZ_SWAP_UINT32(pIndices[end], pIndices[0]); + for ( ; ; ) + { + if ((child = (root << 1) + 1) >= end) + break; + child += (((child + 1) < end) && mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1])); + if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child])) + break; + MZ_SWAP_UINT32(pIndices[root], pIndices[child]); root = child; + } + end--; + } +} + +static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint32 flags) +{ + mz_uint cdir_size, num_this_disk, cdir_disk_index; + mz_uint64 cdir_ofs; + mz_int64 cur_file_ofs; + const mz_uint8 *p; + mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; mz_uint8 *pBuf = (mz_uint8 *)buf_u32; + // Basic sanity checks - reject files which are too small, and check the first 4 bytes of the file to make sure a local header is there. + if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) + return MZ_FALSE; + // Find the end of central directory record by scanning the file from the end towards the beginning. + cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0); + for ( ; ; ) + { + int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs); + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n) + return MZ_FALSE; + for (i = n - 4; i >= 0; --i) + if (MZ_READ_LE32(pBuf + i) == MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) + break; + if (i >= 0) + { + cur_file_ofs += i; + break; + } + if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= (0xFFFF + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE))) + return MZ_FALSE; + cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0); + } + // Read and verify the end of central directory record. + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) + return MZ_FALSE; + if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) || + ((pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) != MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS))) + return MZ_FALSE; + + num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS); + cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS); + if (((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1))) + return MZ_FALSE; + + if ((cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS)) < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) + return MZ_FALSE; + + cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS); + if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size) + return MZ_FALSE; + + pZip->m_central_directory_file_ofs = cdir_ofs; + + if (pZip->m_total_files) + { + mz_uint i, n; + // Read the entire central directory into a heap block, and allocate another heap block to hold the unsorted central dir file record offsets, and another to hold the sorted indices. + if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, MZ_FALSE)) || + (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, pZip->m_total_files, MZ_FALSE)) || + (!mz_zip_array_resize(pZip, &pZip->m_pState->m_sorted_central_dir_offsets, pZip->m_total_files, MZ_FALSE))) + return MZ_FALSE; + if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, pZip->m_pState->m_central_dir.m_p, cdir_size) != cdir_size) + return MZ_FALSE; + + // Now create an index into the central directory file records, do some basic sanity checking on each record, and check for zip64 entries (which are not yet supported). + p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p; + for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i) + { + mz_uint total_header_size, comp_size, decomp_size, disk_index; + if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) || (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG)) + return MZ_FALSE; + MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, i) = (mz_uint32)(p - (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p); + MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, mz_uint32, i) = i; + comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); + decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); + if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && (decomp_size != comp_size)) || (decomp_size && !comp_size) || (decomp_size == 0xFFFFFFFF) || (comp_size == 0xFFFFFFFF)) + return MZ_FALSE; + disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS); + if ((disk_index != num_this_disk) && (disk_index != 1)) + return MZ_FALSE; + if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size) + return MZ_FALSE; + if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) > n) + return MZ_FALSE; + n -= total_header_size; p += total_header_size; + } + } + + if ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0) + mz_zip_reader_sort_central_dir_offsets_by_filename(pZip); + + return MZ_TRUE; +} + +mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint32 flags) +{ + if ((!pZip) || (!pZip->m_pRead)) + return MZ_FALSE; + if (!mz_zip_reader_init_internal(pZip, flags)) + return MZ_FALSE; + pZip->m_archive_size = size; + if (!mz_zip_reader_read_central_dir(pZip, flags)) + { + mz_zip_reader_end(pZip); + return MZ_FALSE; + } + return MZ_TRUE; +} + +static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n) +{ + mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; + size_t s = (file_ofs >= pZip->m_archive_size) ? 0 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n); + memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s); + return s; +} + +mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint32 flags) +{ + if (!mz_zip_reader_init_internal(pZip, flags)) + return MZ_FALSE; + pZip->m_archive_size = size; + pZip->m_pRead = mz_zip_mem_read_func; + pZip->m_pIO_opaque = pZip; + pZip->m_pState->m_pMem = (void *)pMem; + pZip->m_pState->m_mem_size = size; + if (!mz_zip_reader_read_central_dir(pZip, flags)) + { + mz_zip_reader_end(pZip); + return MZ_FALSE; + } + return MZ_TRUE; +} + +#ifndef MINIZ_NO_STDIO +static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n) +{ + mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; + mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile); + if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET)))) + return 0; + return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile); +} + +mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags) +{ + mz_uint64 file_size; + MZ_FILE *pFile = MZ_FOPEN(pFilename, "rb"); + if (!pFile) + return MZ_FALSE; + if (MZ_FSEEK64(pFile, 0, SEEK_END)) + return MZ_FALSE; + file_size = MZ_FTELL64(pFile); + if (!mz_zip_reader_init_internal(pZip, flags)) + { + MZ_FCLOSE(pFile); + return MZ_FALSE; + } + pZip->m_pRead = mz_zip_file_read_func; + pZip->m_pIO_opaque = pZip; + pZip->m_pState->m_pFile = pFile; + pZip->m_archive_size = file_size; + if (!mz_zip_reader_read_central_dir(pZip, flags)) + { + mz_zip_reader_end(pZip); + return MZ_FALSE; + } + return MZ_TRUE; +} +#endif // #ifndef MINIZ_NO_STDIO + +mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip) +{ + return pZip ? pZip->m_total_files : 0; +} + +static MZ_FORCEINLINE const mz_uint8 *mz_zip_reader_get_cdh(mz_zip_archive *pZip, mz_uint file_index) +{ + if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) + return NULL; + return &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index)); +} + +mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index) +{ + mz_uint m_bit_flag; + const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); + if (!p) + return MZ_FALSE; + m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); + return (m_bit_flag & 1); +} + +mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index) +{ + mz_uint filename_len, internal_attr, external_attr; + const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); + if (!p) + return MZ_FALSE; + + internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS); + external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS); + if ((!internal_attr) && ((external_attr & 0x10) != 0)) + return MZ_TRUE; + + filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); + if (filename_len) + { + if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/') + return MZ_TRUE; + } + + return MZ_FALSE; +} + +mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat) +{ + mz_uint n; + const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); + if ((!p) || (!pStat)) + return MZ_FALSE; + + // Unpack the central directory record. + pStat->m_file_index = file_index; + pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index); + pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS); + pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS); + pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); + pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS); +#ifndef MINIZ_NO_TIME + pStat->m_time = mz_zip_dos_to_time_t(MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_TIME_OFS), MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_DATE_OFS)); +#endif + pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS); + pStat->m_comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); + pStat->m_uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); + pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS); + pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS); + pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS); + + // Copy as much of the filename and comment as possible. + n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1); + memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); pStat->m_filename[n] = '\0'; + + n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS); n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1); + pStat->m_comment_size = n; + memcpy(pStat->m_comment, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS), n); pStat->m_comment[n] = '\0'; + + return MZ_TRUE; +} + +mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size) +{ + mz_uint n; + const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); + if (!p) { if (filename_buf_size) pFilename[0] = '\0'; return 0; } + n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); + if (filename_buf_size) + { + n = MZ_MIN(n, filename_buf_size - 1); + memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); + pFilename[n] = '\0'; + } + return n + 1; +} + +static MZ_FORCEINLINE mz_bool mz_zip_reader_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags) +{ + mz_uint i; + if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE) + return 0 == memcmp(pA, pB, len); + for (i = 0; i < len; ++i) + if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i])) + return MZ_FALSE; + return MZ_TRUE; +} + +static MZ_FORCEINLINE int mz_zip_reader_filename_compare(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, const char *pR, mz_uint r_len) +{ + const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE; + mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS); + mz_uint8 l = 0, r = 0; + pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; + pE = pL + MZ_MIN(l_len, r_len); + while (pL < pE) + { + if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR))) + break; + pL++; pR++; + } + return (pL == pE) ? (int)(l_len - r_len) : (l - r); +} + +static int mz_zip_reader_locate_file_binary_search(mz_zip_archive *pZip, const char *pFilename) +{ + mz_zip_internal_state *pState = pZip->m_pState; + const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets; + const mz_zip_array *pCentral_dir = &pState->m_central_dir; + mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0); + const int size = pZip->m_total_files; + const mz_uint filename_len = (mz_uint)strlen(pFilename); + int l = 0, h = size - 1; + while (l <= h) + { + int m = (l + h) >> 1, file_index = pIndices[m], comp = mz_zip_reader_filename_compare(pCentral_dir, pCentral_dir_offsets, file_index, pFilename, filename_len); + if (!comp) + return file_index; + else if (comp < 0) + l = m + 1; + else + h = m - 1; + } + return -1; +} + +int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags) +{ + mz_uint file_index; size_t name_len, comment_len; + if ((!pZip) || (!pZip->m_pState) || (!pName) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) + return -1; + if (((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_p)) + return mz_zip_reader_locate_file_binary_search(pZip, pName); + name_len = strlen(pName); if (name_len > 0xFFFF) return -1; + comment_len = pComment ? strlen(pComment) : 0; if (comment_len > 0xFFFF) return -1; + for (file_index = 0; file_index < pZip->m_total_files; file_index++) + { + const mz_uint8 *pHeader = &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index)); + mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS); + const char *pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; + if (filename_len < name_len) + continue; + if (comment_len) + { + mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS), file_comment_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS); + const char *pFile_comment = pFilename + filename_len + file_extra_len; + if ((file_comment_len != comment_len) || (!mz_zip_reader_string_equal(pComment, pFile_comment, file_comment_len, flags))) + continue; + } + if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len)) + { + int ofs = filename_len - 1; + do + { + if ((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') || (pFilename[ofs] == ':')) + break; + } while (--ofs >= 0); + ofs++; + pFilename += ofs; filename_len -= ofs; + } + if ((filename_len == name_len) && (mz_zip_reader_string_equal(pName, pFilename, filename_len, flags))) + return file_index; + } + return -1; +} + +mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size) +{ + int status = TINFL_STATUS_DONE; + mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail; + mz_zip_archive_file_stat file_stat; + void *pRead_buf; + mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; + tinfl_decompressor inflator; + + if ((buf_size) && (!pBuf)) + return MZ_FALSE; + + if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) + return MZ_FALSE; + + if (!file_stat.m_comp_size) + return MZ_TRUE; + + // Encryption and patch files are not supported. + if (file_stat.m_bit_flag & (1 | 32)) + return MZ_FALSE; + + // This function only supports stored and deflate. + if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED)) + return MZ_FALSE; + + // Ensure supplied output buffer is large enough. + needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size; + if (buf_size < needed_size) + return MZ_FALSE; + + // Read and parse the local directory entry. + cur_file_ofs = file_stat.m_local_header_ofs; + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + return MZ_FALSE; + if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) + return MZ_FALSE; + + cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); + if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size) + return MZ_FALSE; + + if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) + { + // The file is stored or the caller has requested the compressed data. + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, (size_t)needed_size) != needed_size) + return MZ_FALSE; + return ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) != 0) || (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) == file_stat.m_crc32); + } + + // Decompress the file either directly from memory or from a file input buffer. + tinfl_init(&inflator); + + if (pZip->m_pState->m_pMem) + { + // Read directly from the archive in memory. + pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs; + read_buf_size = read_buf_avail = file_stat.m_comp_size; + comp_remaining = 0; + } + else if (pUser_read_buf) + { + // Use a user provided read buffer. + if (!user_read_buf_size) + return MZ_FALSE; + pRead_buf = (mz_uint8 *)pUser_read_buf; + read_buf_size = user_read_buf_size; + read_buf_avail = 0; + comp_remaining = file_stat.m_uncomp_size; + } + else + { + // Temporarily allocate a read buffer. + read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE); +#ifdef _MSC_VER + if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF)) +#else + if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF)) +#endif + return MZ_FALSE; + if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size))) + return MZ_FALSE; + read_buf_avail = 0; + comp_remaining = file_stat.m_comp_size; + } + + do + { + size_t in_buf_size, out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs); + if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) + { + read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) + { + status = TINFL_STATUS_FAILED; + break; + } + cur_file_ofs += read_buf_avail; + comp_remaining -= read_buf_avail; + read_buf_ofs = 0; + } + in_buf_size = (size_t)read_buf_avail; + status = tinfl_decompress(&inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0)); + read_buf_avail -= in_buf_size; + read_buf_ofs += in_buf_size; + out_buf_ofs += out_buf_size; + } while (status == TINFL_STATUS_NEEDS_MORE_INPUT); + + if (status == TINFL_STATUS_DONE) + { + // Make sure the entire file was decompressed, and check its CRC. + if ((out_buf_ofs != file_stat.m_uncomp_size) || (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)) + status = TINFL_STATUS_FAILED; + } + + if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf)) + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + + return status == TINFL_STATUS_DONE; +} + +mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size) +{ + int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags); + if (file_index < 0) + return MZ_FALSE; + return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size); +} + +mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags) +{ + return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, NULL, 0); +} + +mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags) +{ + return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf, buf_size, flags, NULL, 0); +} + +void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags) +{ + mz_uint64 comp_size, uncomp_size, alloc_size; + const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); + void *pBuf; + + if (pSize) + *pSize = 0; + if (!p) + return NULL; + + comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); + uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); + + alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size; +#ifdef _MSC_VER + if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF)) +#else + if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF)) +#endif + return NULL; + if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size))) + return NULL; + + if (!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (size_t)alloc_size, flags)) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + return NULL; + } + + if (pSize) *pSize = (size_t)alloc_size; + return pBuf; +} + +void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags) +{ + int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags); + if (file_index < 0) + { + if (pSize) *pSize = 0; + return MZ_FALSE; + } + return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags); +} + +mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags) +{ + int status = TINFL_STATUS_DONE; mz_uint file_crc32 = MZ_CRC32_INIT; + mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs; + mz_zip_archive_file_stat file_stat; + void *pRead_buf = NULL; void *pWrite_buf = NULL; + mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; + + if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) + return MZ_FALSE; + + if (!file_stat.m_comp_size) + return MZ_TRUE; + + // Encryption and patch files are not supported. + if (file_stat.m_bit_flag & (1 | 32)) + return MZ_FALSE; + + // This function only supports stored and deflate. + if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED)) + return MZ_FALSE; + + // Read and parse the local directory entry. + cur_file_ofs = file_stat.m_local_header_ofs; + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + return MZ_FALSE; + if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) + return MZ_FALSE; + + cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); + if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size) + return MZ_FALSE; + + // Decompress the file either directly from memory or from a file input buffer. + if (pZip->m_pState->m_pMem) + { + pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs; + read_buf_size = read_buf_avail = file_stat.m_comp_size; + comp_remaining = 0; + } + else + { + read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE); + if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size))) + return MZ_FALSE; + read_buf_avail = 0; + comp_remaining = file_stat.m_comp_size; + } + + if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) + { + // The file is stored or the caller has requested the compressed data. + if (pZip->m_pState->m_pMem) + { +#ifdef _MSC_VER + if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > 0xFFFFFFFF)) +#else + if (((sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > 0xFFFFFFFF)) +#endif + return MZ_FALSE; + if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)file_stat.m_comp_size) != file_stat.m_comp_size) + status = TINFL_STATUS_FAILED; + else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) + file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)file_stat.m_comp_size); + cur_file_ofs += file_stat.m_comp_size; + out_buf_ofs += file_stat.m_comp_size; + comp_remaining = 0; + } + else + { + while (comp_remaining) + { + read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) + { + status = TINFL_STATUS_FAILED; + break; + } + + if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) + file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail); + + if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) + { + status = TINFL_STATUS_FAILED; + break; + } + cur_file_ofs += read_buf_avail; + out_buf_ofs += read_buf_avail; + comp_remaining -= read_buf_avail; + } + } + } + else + { + tinfl_decompressor inflator; + tinfl_init(&inflator); + + if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE))) + status = TINFL_STATUS_FAILED; + else + { + do + { + mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); + size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); + if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) + { + read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) + { + status = TINFL_STATUS_FAILED; + break; + } + cur_file_ofs += read_buf_avail; + comp_remaining -= read_buf_avail; + read_buf_ofs = 0; + } + + in_buf_size = (size_t)read_buf_avail; + status = tinfl_decompress(&inflator, (const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size, comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0); + read_buf_avail -= in_buf_size; + read_buf_ofs += in_buf_size; + + if (out_buf_size) + { + if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != out_buf_size) + { + status = TINFL_STATUS_FAILED; + break; + } + file_crc32 = (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size); + if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size) + { + status = TINFL_STATUS_FAILED; + break; + } + } + } while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || (status == TINFL_STATUS_HAS_MORE_OUTPUT)); + } + } + + if ((status == TINFL_STATUS_DONE) && (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))) + { + // Make sure the entire file was decompressed, and check its CRC. + if ((out_buf_ofs != file_stat.m_uncomp_size) || (file_crc32 != file_stat.m_crc32)) + status = TINFL_STATUS_FAILED; + } + + if (!pZip->m_pState->m_pMem) + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + if (pWrite_buf) + pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf); + + return status == TINFL_STATUS_DONE; +} + +mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags) +{ + int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags); + if (file_index < 0) + return MZ_FALSE; + return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque, flags); +} + +#ifndef MINIZ_NO_STDIO +static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, const void *pBuf, size_t n) +{ + (void)ofs; return MZ_FWRITE(pBuf, 1, n, (MZ_FILE*)pOpaque); +} + +mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags) +{ + mz_bool status; + mz_zip_archive_file_stat file_stat; + MZ_FILE *pFile; + if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) + return MZ_FALSE; + pFile = MZ_FOPEN(pDst_filename, "wb"); + if (!pFile) + return MZ_FALSE; + status = mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags); + if (MZ_FCLOSE(pFile) == EOF) + return MZ_FALSE; +#ifndef MINIZ_NO_TIME + if (status) + mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time); +#endif + return status; +} +#endif // #ifndef MINIZ_NO_STDIO + +mz_bool mz_zip_reader_end(mz_zip_archive *pZip) +{ + if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) + return MZ_FALSE; + + if (pZip->m_pState) + { + mz_zip_internal_state *pState = pZip->m_pState; pZip->m_pState = NULL; + mz_zip_array_clear(pZip, &pState->m_central_dir); + mz_zip_array_clear(pZip, &pState->m_central_dir_offsets); + mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets); + +#ifndef MINIZ_NO_STDIO + if (pState->m_pFile) + { + MZ_FCLOSE(pState->m_pFile); + pState->m_pFile = NULL; + } +#endif // #ifndef MINIZ_NO_STDIO + + pZip->m_pFree(pZip->m_pAlloc_opaque, pState); + } + pZip->m_zip_mode = MZ_ZIP_MODE_INVALID; + + return MZ_TRUE; +} + +#ifndef MINIZ_NO_STDIO +mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags) +{ + int file_index = mz_zip_reader_locate_file(pZip, pArchive_filename, NULL, flags); + if (file_index < 0) + return MZ_FALSE; + return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags); +} +#endif + +// ------------------- .ZIP archive writing + +#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS + +static void mz_write_le16(mz_uint8 *p, mz_uint16 v) { p[0] = (mz_uint8)v; p[1] = (mz_uint8)(v >> 8); } +static void mz_write_le32(mz_uint8 *p, mz_uint32 v) { p[0] = (mz_uint8)v; p[1] = (mz_uint8)(v >> 8); p[2] = (mz_uint8)(v >> 16); p[3] = (mz_uint8)(v >> 24); } +#define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v)) +#define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v)) + +mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size) +{ + if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID)) + return MZ_FALSE; + + if (pZip->m_file_offset_alignment) + { + // Ensure user specified file offset alignment is a power of 2. + if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1)) + return MZ_FALSE; + } + + if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func; + if (!pZip->m_pFree) pZip->m_pFree = def_free_func; + if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func; + + pZip->m_zip_mode = MZ_ZIP_MODE_WRITING; + pZip->m_archive_size = existing_size; + pZip->m_central_directory_file_ofs = 0; + pZip->m_total_files = 0; + + if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state)))) + return MZ_FALSE; + memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32)); + return MZ_TRUE; +} + +static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n) +{ + mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; + mz_zip_internal_state *pState = pZip->m_pState; + mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size); +#ifdef _MSC_VER + if ((!n) || ((0, sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF))) +#else + if ((!n) || ((sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF))) +#endif + return 0; + if (new_size > pState->m_mem_capacity) + { + void *pNew_block; + size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity); while (new_capacity < new_size) new_capacity *= 2; + if (NULL == (pNew_block = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity))) + return 0; + pState->m_pMem = pNew_block; pState->m_mem_capacity = new_capacity; + } + memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n); + pState->m_mem_size = (size_t)new_size; + return n; +} + +mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size) +{ + pZip->m_pWrite = mz_zip_heap_write_func; + pZip->m_pIO_opaque = pZip; + if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning)) + return MZ_FALSE; + if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size, size_to_reserve_at_beginning))) + { + if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, initial_allocation_size))) + { + mz_zip_writer_end(pZip); + return MZ_FALSE; + } + pZip->m_pState->m_mem_capacity = initial_allocation_size; + } + return MZ_TRUE; +} + +#ifndef MINIZ_NO_STDIO +static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n) +{ + mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; + mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile); + if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET)))) + return 0; + return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile); +} + +mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning) +{ + MZ_FILE *pFile; + pZip->m_pWrite = mz_zip_file_write_func; + pZip->m_pIO_opaque = pZip; + if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning)) + return MZ_FALSE; + if (NULL == (pFile = MZ_FOPEN(pFilename, "wb"))) + { + mz_zip_writer_end(pZip); + return MZ_FALSE; + } + pZip->m_pState->m_pFile = pFile; + if (size_to_reserve_at_beginning) + { + mz_uint64 cur_ofs = 0; char buf[4096]; MZ_CLEAR_OBJ(buf); + do + { + size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning); + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n) + { + mz_zip_writer_end(pZip); + return MZ_FALSE; + } + cur_ofs += n; size_to_reserve_at_beginning -= n; + } while (size_to_reserve_at_beginning); + } + return MZ_TRUE; +} +#endif // #ifndef MINIZ_NO_STDIO + +mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename) +{ + mz_zip_internal_state *pState; + if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) + return MZ_FALSE; + // No sense in trying to write to an archive that's already at the support max size + if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > 0xFFFFFFFF)) + return MZ_FALSE; + + pState = pZip->m_pState; + + if (pState->m_pFile) + { +#ifdef MINIZ_NO_STDIO + pFilename; return MZ_FALSE; +#else + // Archive is being read from stdio - try to reopen as writable. + if (pZip->m_pIO_opaque != pZip) + return MZ_FALSE; + if (!pFilename) + return MZ_FALSE; + pZip->m_pWrite = mz_zip_file_write_func; + if (NULL == (pState->m_pFile = MZ_FREOPEN(pFilename, "r+b", pState->m_pFile))) + { + // The mz_zip_archive is now in a bogus state because pState->m_pFile is NULL, so just close it. + mz_zip_reader_end(pZip); + return MZ_FALSE; + } +#endif // #ifdef MINIZ_NO_STDIO + } + else if (pState->m_pMem) + { + // Archive lives in a memory block. Assume it's from the heap that we can resize using the realloc callback. + if (pZip->m_pIO_opaque != pZip) + return MZ_FALSE; + pState->m_mem_capacity = pState->m_mem_size; + pZip->m_pWrite = mz_zip_heap_write_func; + } + // Archive is being read via a user provided read function - make sure the user has specified a write function too. + else if (!pZip->m_pWrite) + return MZ_FALSE; + + // Start writing new files at the archive's current central directory location. + pZip->m_archive_size = pZip->m_central_directory_file_ofs; + pZip->m_zip_mode = MZ_ZIP_MODE_WRITING; + pZip->m_central_directory_file_ofs = 0; + + return MZ_TRUE; +} + +mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags) +{ + return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, level_and_flags, 0, 0); +} + +typedef struct +{ + mz_zip_archive *m_pZip; + mz_uint64 m_cur_archive_file_ofs; + mz_uint64 m_comp_size; +} mz_zip_writer_add_state; + +static mz_bool mz_zip_writer_add_put_buf_callback(const void* pBuf, int len, void *pUser) +{ + mz_zip_writer_add_state *pState = (mz_zip_writer_add_state *)pUser; + if ((int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, pState->m_cur_archive_file_ofs, pBuf, len) != len) + return MZ_FALSE; + pState->m_cur_archive_file_ofs += len; + pState->m_comp_size += len; + return MZ_TRUE; +} + +static mz_bool mz_zip_writer_create_local_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date) +{ + (void)pZip; + memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE); + MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date); + MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32); + MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, comp_size); + MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, uncomp_size); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size); + return MZ_TRUE; +} + +static mz_bool mz_zip_writer_create_central_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes) +{ + (void)pZip; + memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, comp_size); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, uncomp_size); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_header_ofs); + return MZ_TRUE; +} + +static mz_bool mz_zip_writer_add_to_central_dir(mz_zip_archive *pZip, const char *pFilename, mz_uint16 filename_size, const void *pExtra, mz_uint16 extra_size, const void *pComment, mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes) +{ + mz_zip_internal_state *pState = pZip->m_pState; + mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size; + size_t orig_central_dir_size = pState->m_central_dir.m_size; + mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE]; + + // No zip64 support yet + if ((local_header_ofs > 0xFFFFFFFF) || (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + comment_size) > 0xFFFFFFFF)) + return MZ_FALSE; + + if (!mz_zip_writer_create_central_dir_header(pZip, central_dir_header, filename_size, extra_size, comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_header_ofs, ext_attributes)) + return MZ_FALSE; + + if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) || + (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) || + (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) || + (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) || + (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, ¢ral_dir_ofs, 1))) + { + // Try to push the central directory array back into its original state. + mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); + return MZ_FALSE; + } + + return MZ_TRUE; +} + +static mz_bool mz_zip_writer_validate_archive_name(const char *pArchive_name) +{ + // Basic ZIP archive filename validity checks: Valid filenames cannot start with a forward slash, cannot contain a drive letter, and cannot use DOS-style backward slashes. + if (*pArchive_name == '/') + return MZ_FALSE; + while (*pArchive_name) + { + if ((*pArchive_name == '\\') || (*pArchive_name == ':')) + return MZ_FALSE; + pArchive_name++; + } + return MZ_TRUE; +} + +static mz_uint mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip) +{ + mz_uint32 n; + if (!pZip->m_file_offset_alignment) + return 0; + n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1)); + return (pZip->m_file_offset_alignment - n) & (pZip->m_file_offset_alignment - 1); +} + +static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, mz_uint64 cur_file_ofs, mz_uint32 n) +{ + char buf[4096]; + memset(buf, 0, MZ_MIN(sizeof(buf), n)); + while (n) + { + mz_uint32 s = MZ_MIN(sizeof(buf), n); + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s) + return MZ_FALSE; + cur_file_ofs += s; n -= s; + } + return MZ_TRUE; +} + +mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32) +{ + mz_uint16 method = 0, dos_time = 0, dos_date = 0; + mz_uint level, ext_attributes = 0, num_alignment_padding_bytes; + mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0; + size_t archive_name_size; + mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; + tdefl_compressor *pComp = NULL; + mz_bool store_data_uncompressed; + mz_zip_internal_state *pState; + + if ((int)level_and_flags < 0) + level_and_flags = MZ_DEFAULT_LEVEL; + level = level_and_flags & 0xF; + store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)); + + if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (pZip->m_total_files == 0xFFFF) || (level > MZ_UBER_COMPRESSION)) + return MZ_FALSE; + + pState = pZip->m_pState; + + if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size)) + return MZ_FALSE; + // No zip64 support yet + if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF)) + return MZ_FALSE; + if (!mz_zip_writer_validate_archive_name(pArchive_name)) + return MZ_FALSE; + +#ifndef MINIZ_NO_TIME + { + time_t cur_time; time(&cur_time); + mz_zip_time_to_dos_time(cur_time, &dos_time, &dos_date); + } +#endif // #ifndef MINIZ_NO_TIME + + archive_name_size = strlen(pArchive_name); + if (archive_name_size > 0xFFFF) + return MZ_FALSE; + + num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); + + // no zip64 support yet + if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF)) + return MZ_FALSE; + + if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/')) + { + // Set DOS Subdirectory attribute bit. + ext_attributes |= 0x10; + // Subdirectories cannot contain data. + if ((buf_size) || (uncomp_size)) + return MZ_FALSE; + } + + // Try to do any allocations before writing to the archive, so if an allocation fails the file remains unmodified. (A good idea if we're doing an in-place modification.) + if ((!mz_zip_array_ensure_room(pZip, &pState->m_central_dir, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size)) || (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1))) + return MZ_FALSE; + + if ((!store_data_uncompressed) && (buf_size)) + { + if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor)))) + return MZ_FALSE; + } + + if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header))) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return MZ_FALSE; + } + local_dir_header_ofs += num_alignment_padding_bytes; + if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); } + cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header); + + MZ_CLEAR_OBJ(local_dir_header); + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return MZ_FALSE; + } + cur_archive_file_ofs += archive_name_size; + + if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) + { + uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8*)pBuf, buf_size); + uncomp_size = buf_size; + if (uncomp_size <= 3) + { + level = 0; + store_data_uncompressed = MZ_TRUE; + } + } + + if (store_data_uncompressed) + { + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, buf_size) != buf_size) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return MZ_FALSE; + } + + cur_archive_file_ofs += buf_size; + comp_size = buf_size; + + if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA) + method = MZ_DEFLATED; + } + else if (buf_size) + { + mz_zip_writer_add_state state; + + state.m_pZip = pZip; + state.m_cur_archive_file_ofs = cur_archive_file_ofs; + state.m_comp_size = 0; + + if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) || + (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != TDEFL_STATUS_DONE)) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return MZ_FALSE; + } + + comp_size = state.m_comp_size; + cur_archive_file_ofs = state.m_cur_archive_file_ofs; + + method = MZ_DEFLATED; + } + + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + pComp = NULL; + + // no zip64 support yet + if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF)) + return MZ_FALSE; + + if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date)) + return MZ_FALSE; + + if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) + return MZ_FALSE; + + if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes)) + return MZ_FALSE; + + pZip->m_total_files++; + pZip->m_archive_size = cur_archive_file_ofs; + + return MZ_TRUE; +} + +#ifndef MINIZ_NO_STDIO +mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags) +{ + mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes; + mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0; + mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, comp_size = 0; + size_t archive_name_size; + mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; + MZ_FILE *pSrc_file = NULL; + + if ((int)level_and_flags < 0) + level_and_flags = MZ_DEFAULT_LEVEL; + level = level_and_flags & 0xF; + + if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION)) + return MZ_FALSE; + if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA) + return MZ_FALSE; + if (!mz_zip_writer_validate_archive_name(pArchive_name)) + return MZ_FALSE; + + archive_name_size = strlen(pArchive_name); + if (archive_name_size > 0xFFFF) + return MZ_FALSE; + + num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); + + // no zip64 support yet + if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF)) + return MZ_FALSE; + + if (!mz_zip_get_file_modified_time(pSrc_filename, &dos_time, &dos_date)) + return MZ_FALSE; + + pSrc_file = MZ_FOPEN(pSrc_filename, "rb"); + if (!pSrc_file) + return MZ_FALSE; + MZ_FSEEK64(pSrc_file, 0, SEEK_END); + uncomp_size = MZ_FTELL64(pSrc_file); + MZ_FSEEK64(pSrc_file, 0, SEEK_SET); + + if (uncomp_size > 0xFFFFFFFF) + { + // No zip64 support yet + MZ_FCLOSE(pSrc_file); + return MZ_FALSE; + } + if (uncomp_size <= 3) + level = 0; + + if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header))) + return MZ_FALSE; + local_dir_header_ofs += num_alignment_padding_bytes; + if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); } + cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header); + + MZ_CLEAR_OBJ(local_dir_header); + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) + { + MZ_FCLOSE(pSrc_file); + return MZ_FALSE; + } + cur_archive_file_ofs += archive_name_size; + + if (uncomp_size) + { + mz_uint64 uncomp_remaining = uncomp_size; + void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE); + if (!pRead_buf) + { + MZ_FCLOSE(pSrc_file); + return MZ_FALSE; + } + + if (!level) + { + while (uncomp_remaining) + { + mz_uint n = (mz_uint)MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, uncomp_remaining); + if ((MZ_FREAD(pRead_buf, 1, n, pSrc_file) != n) || (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n)) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + MZ_FCLOSE(pSrc_file); + return MZ_FALSE; + } + uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n); + uncomp_remaining -= n; + cur_archive_file_ofs += n; + } + comp_size = uncomp_size; + } + else + { + mz_bool result = MZ_FALSE; + mz_zip_writer_add_state state; + tdefl_compressor *pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor)); + if (!pComp) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + MZ_FCLOSE(pSrc_file); + return MZ_FALSE; + } + + state.m_pZip = pZip; + state.m_cur_archive_file_ofs = cur_archive_file_ofs; + state.m_comp_size = 0; + + if (tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + MZ_FCLOSE(pSrc_file); + return MZ_FALSE; + } + + for ( ; ; ) + { + size_t in_buf_size = (mz_uint32)MZ_MIN(uncomp_remaining, MZ_ZIP_MAX_IO_BUF_SIZE); + tdefl_status status; + + if (MZ_FREAD(pRead_buf, 1, in_buf_size, pSrc_file) != in_buf_size) + break; + + uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, in_buf_size); + uncomp_remaining -= in_buf_size; + + status = tdefl_compress_buffer(pComp, pRead_buf, in_buf_size, uncomp_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH); + if (status == TDEFL_STATUS_DONE) + { + result = MZ_TRUE; + break; + } + else if (status != TDEFL_STATUS_OKAY) + break; + } + + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + + if (!result) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + MZ_FCLOSE(pSrc_file); + return MZ_FALSE; + } + + comp_size = state.m_comp_size; + cur_archive_file_ofs = state.m_cur_archive_file_ofs; + + method = MZ_DEFLATED; + } + + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + } + + MZ_FCLOSE(pSrc_file); pSrc_file = NULL; + + // no zip64 support yet + if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF)) + return MZ_FALSE; + + if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date)) + return MZ_FALSE; + + if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) + return MZ_FALSE; + + if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes)) + return MZ_FALSE; + + pZip->m_total_files++; + pZip->m_archive_size = cur_archive_file_ofs; + + return MZ_TRUE; +} +#endif // #ifndef MINIZ_NO_STDIO + +mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index) +{ + mz_uint n, bit_flags, num_alignment_padding_bytes; + mz_uint64 comp_bytes_remaining, local_dir_header_ofs; + mz_uint64 cur_src_file_ofs, cur_dst_file_ofs; + mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; + mz_uint8 central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE]; + size_t orig_central_dir_size; + mz_zip_internal_state *pState; + void *pBuf; const mz_uint8 *pSrc_central_header; + + if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING)) + return MZ_FALSE; + if (NULL == (pSrc_central_header = mz_zip_reader_get_cdh(pSource_zip, file_index))) + return MZ_FALSE; + pState = pZip->m_pState; + + num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); + + // no zip64 support yet + if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF)) + return MZ_FALSE; + + cur_src_file_ofs = MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS); + cur_dst_file_ofs = pZip->m_archive_size; + + if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + return MZ_FALSE; + if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) + return MZ_FALSE; + cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE; + + if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs, num_alignment_padding_bytes)) + return MZ_FALSE; + cur_dst_file_ofs += num_alignment_padding_bytes; + local_dir_header_ofs = cur_dst_file_ofs; + if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); } + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + return MZ_FALSE; + cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE; + + n = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); + comp_bytes_remaining = n + MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); + + if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)MZ_MAX(sizeof(mz_uint32) * 4, MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining))))) + return MZ_FALSE; + + while (comp_bytes_remaining) + { + n = (mz_uint)MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining); + if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, n) != n) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + return MZ_FALSE; + } + cur_src_file_ofs += n; + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + return MZ_FALSE; + } + cur_dst_file_ofs += n; + + comp_bytes_remaining -= n; + } + + bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS); + if (bit_flags & 8) + { + // Copy data descriptor + if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, sizeof(mz_uint32) * 4) != sizeof(mz_uint32) * 4) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + return MZ_FALSE; + } + + n = sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == 0x08074b50) ? 4 : 3); + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + return MZ_FALSE; + } + + cur_src_file_ofs += n; + cur_dst_file_ofs += n; + } + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + + // no zip64 support yet + if (cur_dst_file_ofs > 0xFFFFFFFF) + return MZ_FALSE; + + orig_central_dir_size = pState->m_central_dir.m_size; + + memcpy(central_header, pSrc_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE); + MZ_WRITE_LE32(central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_dir_header_ofs); + if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) + return MZ_FALSE; + + n = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS); + if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n)) + { + mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); + return MZ_FALSE; + } + + if (pState->m_central_dir.m_size > 0xFFFFFFFF) + return MZ_FALSE; + n = (mz_uint32)pState->m_central_dir.m_size; + if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1)) + { + mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); + return MZ_FALSE; + } + + pZip->m_total_files++; + pZip->m_archive_size = cur_dst_file_ofs; + + return MZ_TRUE; +} + +mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip) +{ + mz_zip_internal_state *pState; + mz_uint64 central_dir_ofs, central_dir_size; + mz_uint8 hdr[MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE]; + + if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING)) + return MZ_FALSE; + + pState = pZip->m_pState; + + // no zip64 support yet + if ((pZip->m_total_files > 0xFFFF) || ((pZip->m_archive_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF)) + return MZ_FALSE; + + central_dir_ofs = 0; + central_dir_size = 0; + if (pZip->m_total_files) + { + // Write central directory + central_dir_ofs = pZip->m_archive_size; + central_dir_size = pState->m_central_dir.m_size; + pZip->m_central_directory_file_ofs = central_dir_ofs; + if (pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs, pState->m_central_dir.m_p, (size_t)central_dir_size) != central_dir_size) + return MZ_FALSE; + pZip->m_archive_size += central_dir_size; + } + + // Write end of central directory record + MZ_CLEAR_OBJ(hdr); + MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG); + MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, pZip->m_total_files); + MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, pZip->m_total_files); + MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, central_dir_size); + MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, central_dir_ofs); + + if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, sizeof(hdr)) != sizeof(hdr)) + return MZ_FALSE; +#ifndef MINIZ_NO_STDIO + if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF)) + return MZ_FALSE; +#endif // #ifndef MINIZ_NO_STDIO + + pZip->m_archive_size += sizeof(hdr); + + pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED; + return MZ_TRUE; +} + +mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, size_t *pSize) +{ + if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pSize)) + return MZ_FALSE; + if (pZip->m_pWrite != mz_zip_heap_write_func) + return MZ_FALSE; + if (!mz_zip_writer_finalize_archive(pZip)) + return MZ_FALSE; + + *pBuf = pZip->m_pState->m_pMem; + *pSize = pZip->m_pState->m_mem_size; + pZip->m_pState->m_pMem = NULL; + pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0; + return MZ_TRUE; +} + +mz_bool mz_zip_writer_end(mz_zip_archive *pZip) +{ + mz_zip_internal_state *pState; + mz_bool status = MZ_TRUE; + if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) && (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED))) + return MZ_FALSE; + + pState = pZip->m_pState; + pZip->m_pState = NULL; + mz_zip_array_clear(pZip, &pState->m_central_dir); + mz_zip_array_clear(pZip, &pState->m_central_dir_offsets); + mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets); + +#ifndef MINIZ_NO_STDIO + if (pState->m_pFile) + { + MZ_FCLOSE(pState->m_pFile); + pState->m_pFile = NULL; + } +#endif // #ifndef MINIZ_NO_STDIO + + if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem)) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem); + pState->m_pMem = NULL; + } + + pZip->m_pFree(pZip->m_pAlloc_opaque, pState); + pZip->m_zip_mode = MZ_ZIP_MODE_INVALID; + return status; +} + +#ifndef MINIZ_NO_STDIO +mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags) +{ + mz_bool status, created_new_archive = MZ_FALSE; + mz_zip_archive zip_archive; + struct MZ_FILE_STAT_STRUCT file_stat; + MZ_CLEAR_OBJ(zip_archive); + if ((int)level_and_flags < 0) + level_and_flags = MZ_DEFAULT_LEVEL; + if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION)) + return MZ_FALSE; + if (!mz_zip_writer_validate_archive_name(pArchive_name)) + return MZ_FALSE; + if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0) + { + // Create a new archive. + if (!mz_zip_writer_init_file(&zip_archive, pZip_filename, 0)) + return MZ_FALSE; + created_new_archive = MZ_TRUE; + } + else + { + // Append to an existing archive. + if (!mz_zip_reader_init_file(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) + return MZ_FALSE; + if (!mz_zip_writer_init_from_reader(&zip_archive, pZip_filename)) + { + mz_zip_reader_end(&zip_archive); + return MZ_FALSE; + } + } + status = mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0); + // Always finalize, even if adding failed for some reason, so we have a valid central directory. (This may not always succeed, but we can try.) + if (!mz_zip_writer_finalize_archive(&zip_archive)) + status = MZ_FALSE; + if (!mz_zip_writer_end(&zip_archive)) + status = MZ_FALSE; + if ((!status) && (created_new_archive)) + { + // It's a new archive and something went wrong, so just delete it. + int ignoredStatus = MZ_DELETE_FILE(pZip_filename); + (void)ignoredStatus; + } + return status; +} + +void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags) +{ + int file_index; + mz_zip_archive zip_archive; + void *p = NULL; + + if (pSize) + *pSize = 0; + + if ((!pZip_filename) || (!pArchive_name)) + return NULL; + + MZ_CLEAR_OBJ(zip_archive); + if (!mz_zip_reader_init_file(&zip_archive, pZip_filename, flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) + return NULL; + + if ((file_index = mz_zip_reader_locate_file(&zip_archive, pArchive_name, NULL, flags)) >= 0) + p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags); + + mz_zip_reader_end(&zip_archive); + return p; +} + +#endif // #ifndef MINIZ_NO_STDIO + +#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS + +#endif // #ifndef MINIZ_NO_ARCHIVE_APIS + +#ifdef __cplusplus +} +#endif + +#endif // MINIZ_HEADER_FILE_ONLY + +/* + This is free and unencumbered software released into the public domain. + + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this software, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + + In jurisdictions that recognize copyright laws, the author or authors + of this software dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + For more information, please refer to +*/ diff --git a/miniz/miniz_tester.cpp b/miniz/miniz_tester.cpp new file mode 100644 index 0000000000..b881419762 --- /dev/null +++ b/miniz/miniz_tester.cpp @@ -0,0 +1,1804 @@ +// miniz_tester.cpp +// Note: This module is not intended to make a good example, or be used for anything other than testing. +// It's something quick I put together last year to help regression test miniz/tinfl under Linux/Win32/Mac. It's derived from LZHAM's test module. +#ifdef _MSC_VER +#pragma warning (disable:4127) // warning C4127: conditional expression is constant +#endif + +#if defined(__GNUC__) +#define _FILE_OFFSET_BITS 64 +#endif + +#define MINIZ_HEADER_FILE_ONLY +#include "miniz.c" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "timer.h" + +#define my_max(a,b) (((a) > (b)) ? (a) : (b)) +#define my_min(a,b) (((a) < (b)) ? (a) : (b)) + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint; + +#define TDEFL_PRINT_OUTPUT_PROGRESS + +#if defined(WIN32) + #define WIN32_LEAN_AND_MEAN + #include + #define FILE_STAT_STRUCT _stat + #define FILE_STAT _stat +#else + #include + #define Sleep(ms) usleep(ms*1000) + #define _aligned_malloc(size, alignment) memalign(alignment, size) + #define _aligned_free free + #define fopen fopen64 + #define _fseeki64 fseeko64 + #define _ftelli64 ftello64 + #define _stricmp strcasecmp + #define FILE_STAT_STRUCT stat + #define FILE_STAT stat +#endif + +#ifdef WIN32 +#define QUAD_INT_FMT "%I64u" +#else +#define QUAD_INT_FMT "%llu" +#endif + +#ifdef _DEBUG +const bool g_is_debug = true; +#else +const bool g_is_debug = false; +#endif + +typedef unsigned char uint8; +typedef unsigned int uint; +typedef unsigned int uint32; +typedef unsigned long long uint64; +typedef long long int64; + +#define TDEFLTEST_COMP_INPUT_BUFFER_SIZE 1024*1024*2 +#define TDEFLTEST_COMP_OUTPUT_BUFFER_SIZE 1024*1024*2 +#define TDEFLTEST_DECOMP_INPUT_BUFFER_SIZE 1024*1024*2 + +static float s_max_small_comp_ratio, s_max_large_comp_ratio; + +struct comp_options +{ + comp_options() : + m_level(7), + m_unbuffered_decompression(false), + m_verify_compressed_data(false), + m_randomize_params(false), + m_randomize_buffer_sizes(false), + m_z_strat(Z_DEFAULT_STRATEGY), + m_random_z_flushing(false), + m_write_zlib_header(true), + m_archive_test(false), + m_write_archives(false) + { + } + + void print() + { + printf("Level: %u\n", m_level); + printf("Write zlib header: %u\n", (uint)m_write_zlib_header); + printf("Unbuffered decompression: %u\n", (uint)m_unbuffered_decompression); + printf("Verify compressed data: %u\n", (uint)m_verify_compressed_data); + printf("Randomize parameters: %u\n", m_randomize_params); + printf("Randomize buffer sizes: %u\n", m_randomize_buffer_sizes); + printf("Deflate strategy: %u\n", m_z_strat); + printf("Random Z stream flushing: %u\n", m_random_z_flushing); + printf("Archive test: %u\n", m_archive_test); + printf("Write archives: %u\n", m_write_archives); + } + + uint m_level; + bool m_unbuffered_decompression; + bool m_verify_compressed_data; + bool m_randomize_params; + bool m_randomize_buffer_sizes; + uint m_z_strat; + bool m_random_z_flushing; + bool m_write_zlib_header; + bool m_archive_test; + bool m_write_archives; +}; + +#define RND_SHR3(x) (x ^= (x << 17), x ^= (x >> 13), x ^= (x << 5)) + +#if 0 +static void random_fill(uint8 *pDst, size_t len, uint32 x) +{ + x ^= (x << 16); + if (!x) x++; + + while (len) + { + RND_SHR3(x); uint64 l0 = x & 0xFFF; + RND_SHR3(x); uint64 l1 = x & 0xFFF; + RND_SHR3(x); uint64 l2 = x & 0xFFF; + RND_SHR3(x); uint c = x; + + uint l = (uint)(((l0*l1*l2)/(16769025ULL) * 32) / 4095); + l = (uint)my_max(1,my_min(l, len)); + len -= l; + + while (l--) + { + *pDst++ = (uint8)c; + } + + if (((int)x < 0) && len) + { + *pDst++ = 0; + len--; + } + } +} +#endif + +static void print_usage() +{ + printf("Usage: [options] [mode] inpath/infile [outfile]\n"); + printf("\n"); + printf("Modes:\n"); + printf("c - Compress \"infile\" to \"outfile\"\n"); + printf("d - Decompress \"infile\" to \"outfile\"\n"); + printf("a - Recursively compress all files under \"inpath\"\n"); + printf("r - Archive decompression test\n"); + printf("\n"); + printf("Options:\n"); + printf("-m[0-10] - Compression level: 0=fastest (Huffman only), 9=best (10=uber)\n"); + printf("-u - Use unbuffered decompression on files that can fit into memory.\n"); + printf(" Unbuffered decompression is faster, but may have more I/O overhead.\n"); + printf("-v - Immediately decompress compressed file after compression for verification.\n"); + printf("-z - Do not write zlib header\n"); + printf("-r - Randomize parameters during recursive testing\n"); + printf("-b - Randomize input/output buffer sizes\n"); + printf("-h - Use random z_flushing\n"); + printf("-x# - Set rand() seed to value\n"); + printf("-t# - Set z_strategy to value [0-4]\n"); + printf("-a - Create single-file archives instead of files during testing\n"); + printf("-w - Test archive cloning\n"); +} + +static void print_error(const char *pMsg, ...) +{ + char buf[1024]; + + va_list args; + va_start(args, pMsg); + vsnprintf(buf, sizeof(buf), pMsg, args); + va_end(args); + + buf[sizeof(buf) - 1] = '\0'; + + fprintf(stderr, "Error: %s", buf); +} + +static FILE* open_file_with_retries(const char *pFilename, const char* pMode) +{ + const uint cNumRetries = 8; + for (uint i = 0; i < cNumRetries; i++) + { + FILE* pFile = fopen(pFilename, pMode); + if (pFile) + return pFile; + Sleep(250); + } + return NULL; +} + +static bool ensure_file_exists_and_is_readable(const char *pFilename) +{ + FILE *p = fopen(pFilename, "rb"); + if (!p) + return false; + + _fseeki64(p, 0, SEEK_END); + uint64 src_file_size = _ftelli64(p); + _fseeki64(p, 0, SEEK_SET); + + if (src_file_size) + { + char buf[1]; + if (fread(buf, 1, 1, p) != 1) + { + fclose(p); + return false; + } + } + fclose(p); + return true; +} + +static bool ensure_file_is_writable(const char *pFilename) +{ + const int cNumRetries = 8; + for (int i = 0; i < cNumRetries; i++) + { + FILE *pFile = fopen(pFilename, "wb"); + if (pFile) + { + fclose(pFile); + return true; + } + Sleep(250); + } + return false; +} + +static int simple_test1(const comp_options &options) +{ + options; + + uint8 cmp_buf[1024]; + size_t cmp_len = sizeof(cmp_buf); + + const char *p = "This is a test.This is a test.This is a test.1234567This is a test.This is a test.123456"; + size_t uncomp_len = strlen(p); + + void *pComp_data = tdefl_compress_mem_to_heap(p, uncomp_len, &cmp_len, TDEFL_WRITE_ZLIB_HEADER); + if (!pComp_data) + { + free(pComp_data); + print_error("Compression test failed!\n"); + return EXIT_FAILURE; + } + + printf("Uncompressed size: %u\nCompressed size: %u\n", (uint)uncomp_len, (uint)cmp_len); + + size_t decomp_len = 0; + void *pDecomp_data = tinfl_decompress_mem_to_heap(pComp_data, cmp_len, &decomp_len, TINFL_FLAG_PARSE_ZLIB_HEADER); + + if ((!pDecomp_data) || (decomp_len != uncomp_len) || (memcmp(pDecomp_data, p, uncomp_len))) + { + free(pComp_data); + free(pDecomp_data); + print_error("Compression test failed!\n"); + return EXIT_FAILURE; + } + + printf("Low-level API compression test succeeded.\n"); + + free(pComp_data); + free(pDecomp_data); + + return EXIT_SUCCESS; +} + +static int simple_test2(const comp_options &options) +{ + options; + + uint8 cmp_buf[1024], decomp_buf[1024]; + uLong cmp_len = sizeof(cmp_buf); + + const char *p = "This is a test.This is a test.This is a test.1234567This is a test.This is a test.123456"; + uLong uncomp_len = (uLong)strlen(p); + + int status = compress(cmp_buf, &cmp_len, (const uint8*)p, uncomp_len); + if (status != Z_OK) + { + print_error("Compression test failed!\n"); + return EXIT_FAILURE; + } + + printf("Uncompressed size: %u\nCompressed size: %u\n", (uint)uncomp_len, (uint)cmp_len); + + if (cmp_len > compressBound(uncomp_len)) + { + print_error("compressBound() returned bogus result\n"); + return EXIT_FAILURE; + } + + uLong decomp_len = sizeof(decomp_buf); + status = uncompress(decomp_buf, &decomp_len, cmp_buf, cmp_len);; + + if ((status != Z_OK) || (decomp_len != uncomp_len) || (memcmp(decomp_buf, p, uncomp_len))) + { + print_error("Compression test failed!\n"); + return EXIT_FAILURE; + } + + printf("zlib API compression test succeeded.\n"); + + return EXIT_SUCCESS; +} + +static bool compress_file_zlib(const char* pSrc_filename, const char *pDst_filename, const comp_options &options) +{ + printf("Testing: Streaming zlib compression\n"); + + FILE *pInFile = fopen(pSrc_filename, "rb"); + if (!pInFile) + { + print_error("Unable to read file: %s\n", pSrc_filename); + return false; + } + + FILE *pOutFile = fopen(pDst_filename, "wb"); + if (!pOutFile) + { + print_error("Unable to create file: %s\n", pDst_filename); + return false; + } + + _fseeki64(pInFile, 0, SEEK_END); + uint64 src_file_size = _ftelli64(pInFile); + _fseeki64(pInFile, 0, SEEK_SET); + + fputc('D', pOutFile); fputc('E', pOutFile); fputc('F', pOutFile); fputc('0', pOutFile); + fputc(options.m_write_zlib_header, pOutFile); + + for (uint i = 0; i < 8; i++) + fputc(static_cast((src_file_size >> (i * 8)) & 0xFF), pOutFile); + + uint cInBufSize = TDEFLTEST_COMP_INPUT_BUFFER_SIZE; + uint cOutBufSize = TDEFLTEST_COMP_OUTPUT_BUFFER_SIZE; + if (options.m_randomize_buffer_sizes) + { + cInBufSize = 1 + (rand() % 4096); + cOutBufSize = 1 + (rand() % 4096); + } + printf("Input buffer size: %u, Output buffer size: %u\n", cInBufSize, cOutBufSize); + + uint8 *in_file_buf = static_cast(_aligned_malloc(cInBufSize, 16)); + uint8 *out_file_buf = static_cast(_aligned_malloc(cOutBufSize, 16)); + if ((!in_file_buf) || (!out_file_buf)) + { + print_error("Out of memory!\n"); + _aligned_free(in_file_buf); + _aligned_free(out_file_buf); + fclose(pInFile); + fclose(pOutFile); + return false; + } + + uint64 src_bytes_left = src_file_size; + + uint in_file_buf_size = 0; + uint in_file_buf_ofs = 0; + + uint64 total_output_bytes = 0; + + timer_ticks start_time = timer::get_ticks(); + + z_stream zstream; + memset(&zstream, 0, sizeof(zstream)); + + timer_ticks init_start_time = timer::get_ticks(); + int status = deflateInit2(&zstream, options.m_level, Z_DEFLATED, options.m_write_zlib_header ? Z_DEFAULT_WINDOW_BITS : -Z_DEFAULT_WINDOW_BITS, 9, options.m_z_strat); + timer_ticks total_init_time = timer::get_ticks() - init_start_time; + + if (status != Z_OK) + { + print_error("Failed initializing compressor!\n"); + _aligned_free(in_file_buf); + _aligned_free(out_file_buf); + fclose(pInFile); + fclose(pOutFile); + return false; + } + + printf("deflateInit2() took %3.3fms\n", timer::ticks_to_secs(total_init_time)*1000.0f); + + uint32 x = my_max(1, (uint32)(src_file_size ^ (src_file_size >> 32))); + + for ( ; ; ) + { + if (src_file_size) + { + double total_elapsed_time = timer::ticks_to_secs(timer::get_ticks() - start_time); + double total_bytes_processed = static_cast(src_file_size - src_bytes_left); + double comp_rate = (total_elapsed_time > 0.0f) ? total_bytes_processed / total_elapsed_time : 0.0f; + +#ifdef TDEFL_PRINT_OUTPUT_PROGRESS + for (int i = 0; i < 15; i++) + printf("\b\b\b\b"); + printf("Progress: %3.1f%%, Bytes Remaining: %3.1fMB, %3.3fMB/sec", (1.0f - (static_cast(src_bytes_left) / src_file_size)) * 100.0f, src_bytes_left / 1048576.0f, comp_rate / (1024.0f * 1024.0f)); + printf(" \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); +#endif + } + + if (in_file_buf_ofs == in_file_buf_size) + { + in_file_buf_size = static_cast(my_min(cInBufSize, src_bytes_left)); + + if (fread(in_file_buf, 1, in_file_buf_size, pInFile) != in_file_buf_size) + { + printf("\n"); + print_error("Failure reading from source file!\n"); + _aligned_free(in_file_buf); + _aligned_free(out_file_buf); + fclose(pInFile); + fclose(pOutFile); + deflateEnd(&zstream); + return false; + } + + src_bytes_left -= in_file_buf_size; + + in_file_buf_ofs = 0; + } + + zstream.next_in = &in_file_buf[in_file_buf_ofs]; + zstream.avail_in = in_file_buf_size - in_file_buf_ofs; + zstream.next_out = out_file_buf; + zstream.avail_out = cOutBufSize; + + int flush = !src_bytes_left ? Z_FINISH : Z_NO_FLUSH; + if ((flush == Z_NO_FLUSH) && (options.m_random_z_flushing)) + { + RND_SHR3(x); + if ((x & 15) == 0) + { + RND_SHR3(x); + flush = (x & 31) ? Z_SYNC_FLUSH : Z_FULL_FLUSH; + } + } + status = deflate(&zstream, flush); + + uint num_in_bytes = (in_file_buf_size - in_file_buf_ofs) - zstream.avail_in; + uint num_out_bytes = cOutBufSize - zstream.avail_out; + if (num_in_bytes) + { + in_file_buf_ofs += (uint)num_in_bytes; + assert(in_file_buf_ofs <= in_file_buf_size); + } + + if (num_out_bytes) + { + if (fwrite(out_file_buf, 1, static_cast(num_out_bytes), pOutFile) != num_out_bytes) + { + printf("\n"); + print_error("Failure writing to destination file!\n"); + _aligned_free(in_file_buf); + _aligned_free(out_file_buf); + fclose(pInFile); + fclose(pOutFile); + deflateEnd(&zstream); + return false; + } + + total_output_bytes += num_out_bytes; + } + + if (status != Z_OK) + break; + } + +#ifdef TDEFL_PRINT_OUTPUT_PROGRESS + for (int i = 0; i < 15; i++) + { + printf("\b\b\b\b \b\b\b\b"); + } +#endif + + src_bytes_left += (in_file_buf_size - in_file_buf_ofs); + + uint32 adler32 = zstream.adler; + deflateEnd(&zstream); + + timer_ticks end_time = timer::get_ticks(); + double total_time = timer::ticks_to_secs(my_max(1, end_time - start_time)); + + uint64 cmp_file_size = _ftelli64(pOutFile); + + _aligned_free(in_file_buf); + in_file_buf = NULL; + _aligned_free(out_file_buf); + out_file_buf = NULL; + + fclose(pInFile); + pInFile = NULL; + fclose(pOutFile); + pOutFile = NULL; + + if (status != Z_STREAM_END) + { + print_error("Compression failed with status %i\n", status); + return false; + } + + if (src_bytes_left) + { + print_error("Compressor failed to consume entire input file!\n"); + return false; + } + + printf("Success\n"); + printf("Input file size: " QUAD_INT_FMT ", Compressed file size: " QUAD_INT_FMT ", Ratio: %3.2f%%\n", src_file_size, cmp_file_size, src_file_size ? ((1.0f - (static_cast(cmp_file_size) / src_file_size)) * 100.0f) : 0.0f); + printf("Compression time: %3.6f\nConsumption rate: %9.1f bytes/sec, Emission rate: %9.1f bytes/sec\n", total_time, src_file_size / total_time, cmp_file_size / total_time); + printf("Input file adler32: 0x%08X\n", adler32); + if (src_file_size) + { + if (src_file_size >= 256) + s_max_large_comp_ratio = my_max(s_max_large_comp_ratio, cmp_file_size / (float)src_file_size); + else + s_max_small_comp_ratio = my_max(s_max_small_comp_ratio, cmp_file_size / (float)src_file_size); + } + //printf("Max small comp ratio: %f, Max large comp ratio: %f\n", s_max_small_comp_ratio, s_max_large_comp_ratio); + + return true; +} + +static bool decompress_file_zlib(const char* pSrc_filename, const char *pDst_filename, comp_options options) +{ + FILE *pInFile = fopen(pSrc_filename, "rb"); + if (!pInFile) + { + print_error("Unable to read file: %s\n", pSrc_filename); + return false; + } + + _fseeki64(pInFile, 0, SEEK_END); + uint64 src_file_size = _ftelli64(pInFile); + _fseeki64(pInFile, 0, SEEK_SET); + if (src_file_size < (5+9)) + { + print_error("Compressed file is too small!\n"); + fclose(pInFile); + return false; + } + + int h0 = fgetc(pInFile); + int h1 = fgetc(pInFile); + int h2 = fgetc(pInFile); + int h3 = fgetc(pInFile); + int zlib_header = fgetc(pInFile); + if ((h0 != 'D') | (h1 != 'E') || (h2 != 'F') || (h3 != '0')) + { + print_error("Unrecognized/invalid header in file: %s\n", pSrc_filename); + fclose(pInFile); + return false; + } + + FILE *pOutFile = fopen(pDst_filename, "wb"); + if (!pOutFile) + { + print_error("Unable to create file: %s\n", pDst_filename); + fclose(pInFile); + return false; + } + + uint64 orig_file_size = 0; + for (uint i = 0; i < 8; i++) + orig_file_size |= (static_cast(fgetc(pInFile)) << (i * 8)); + + int total_header_bytes = ftell(pInFile); + + // Avoid running out of memory on large files when using unbuffered decompression. + if ((options.m_unbuffered_decompression) && (orig_file_size > 768*1024*1024)) + { + printf("Output file is too large for unbuffered decompression - switching to streaming decompression.\n"); + options.m_unbuffered_decompression = false; + } + + if (options.m_unbuffered_decompression) + printf("Testing: Unbuffered decompression\n"); + else + printf("Testing: Streaming decompression\n"); + + uint cInBufSize = options.m_unbuffered_decompression ? static_cast(src_file_size) : TDEFLTEST_DECOMP_INPUT_BUFFER_SIZE; + uint out_buf_size = options.m_unbuffered_decompression ? static_cast(orig_file_size) : TINFL_LZ_DICT_SIZE; + + if ((options.m_randomize_buffer_sizes) && (!options.m_unbuffered_decompression)) + { + cInBufSize = 1 + (rand() % 4096); + } + + printf("Input buffer size: %u, Output buffer size: %u\n", cInBufSize, out_buf_size); + + uint8 *in_file_buf = static_cast(_aligned_malloc(cInBufSize, 16)); + uint8 *out_file_buf = static_cast(_aligned_malloc(out_buf_size, 16)); + if ((!in_file_buf) || (!out_file_buf)) + { + print_error("Failed allocating output buffer!\n"); + _aligned_free(in_file_buf); + fclose(pInFile); + fclose(pOutFile); + return false; + } + + uint64 src_bytes_left = src_file_size - total_header_bytes; + uint64 dst_bytes_left = orig_file_size; + + uint in_file_buf_size = 0; + uint in_file_buf_ofs = 0; + uint out_file_buf_ofs = 0; + + timer_ticks start_time = timer::get_ticks(); + double decomp_only_time = 0; + + z_stream zstream; + memset(&zstream, 0, sizeof(zstream)); + + timer_ticks init_start_time = timer::get_ticks(); + int status = zlib_header ? inflateInit(&zstream) : inflateInit2(&zstream, -Z_DEFAULT_WINDOW_BITS); + timer_ticks total_init_time = timer::get_ticks() - init_start_time; + if (status != Z_OK) + { + print_error("Failed initializing decompressor!\n"); + _aligned_free(in_file_buf); + _aligned_free(out_file_buf); + fclose(pInFile); + fclose(pOutFile); + return false; + } + + printf("inflateInit() took %3.3fms\n", timer::ticks_to_secs(total_init_time)*1000.0f); + + for ( ; ; ) + { + if (in_file_buf_ofs == in_file_buf_size) + { + in_file_buf_size = static_cast(my_min(cInBufSize, src_bytes_left)); + + if (fread(in_file_buf, 1, in_file_buf_size, pInFile) != in_file_buf_size) + { + print_error("Failure reading from source file!\n"); + _aligned_free(in_file_buf); + _aligned_free(out_file_buf); + deflateEnd(&zstream); + fclose(pInFile); + fclose(pOutFile); + return false; + } + + src_bytes_left -= in_file_buf_size; + + in_file_buf_ofs = 0; + } + + uint num_in_bytes = (in_file_buf_size - in_file_buf_ofs); + uint num_out_bytes = (out_buf_size - out_file_buf_ofs); + zstream.next_in = in_file_buf + in_file_buf_ofs; + zstream.avail_in = num_in_bytes; + zstream.next_out = out_file_buf + out_file_buf_ofs; + zstream.avail_out = num_out_bytes; + + { + timer decomp_only_timer; + decomp_only_timer.start(); + status = inflate(&zstream, options.m_unbuffered_decompression ? Z_FINISH : Z_SYNC_FLUSH); + decomp_only_time += decomp_only_timer.get_elapsed_secs(); + } + num_in_bytes -= zstream.avail_in; + num_out_bytes -= zstream.avail_out; + + if (num_in_bytes) + { + in_file_buf_ofs += (uint)num_in_bytes; + assert(in_file_buf_ofs <= in_file_buf_size); + } + + out_file_buf_ofs += (uint)num_out_bytes; + + if ((out_file_buf_ofs == out_buf_size) || (status == Z_STREAM_END)) + { + if (fwrite(out_file_buf, 1, static_cast(out_file_buf_ofs), pOutFile) != out_file_buf_ofs) + { + print_error("Failure writing to destination file!\n"); + _aligned_free(in_file_buf); + _aligned_free(out_file_buf); + inflateEnd(&zstream); + fclose(pInFile); + fclose(pOutFile); + return false; + } + out_file_buf_ofs = 0; + } + + if (num_out_bytes > dst_bytes_left) + { + print_error("Decompressor wrote too many bytes to destination file!\n"); + _aligned_free(in_file_buf); + _aligned_free(out_file_buf); + inflateEnd(&zstream); + fclose(pInFile); + fclose(pOutFile); + return false; + } + dst_bytes_left -= num_out_bytes; + + if (status != Z_OK) + break; + } + _aligned_free(in_file_buf); + in_file_buf = NULL; + + _aligned_free(out_file_buf); + out_file_buf = NULL; + + src_bytes_left += (in_file_buf_size - in_file_buf_ofs); + + uint32 adler32 = zstream.adler; + inflateEnd(&zstream); + + timer_ticks end_time = timer::get_ticks(); + double total_time = timer::ticks_to_secs(my_max(1, end_time - start_time)); + + fclose(pInFile); + pInFile = NULL; + + fclose(pOutFile); + pOutFile = NULL; + + if (status != Z_STREAM_END) + { + print_error("Decompression FAILED with status %i\n", status); + return false; + } + + if ((src_file_size < UINT_MAX) && (orig_file_size < UINT_MAX)) + { + if ((((size_t)zstream.total_in + total_header_bytes) != src_file_size) || (zstream.total_out != orig_file_size)) + { + print_error("Decompression FAILED to consume all input or write all expected output!\n"); + return false; + } + } + + if (dst_bytes_left) + { + print_error("Decompressor FAILED to output the entire output file!\n"); + return false; + } + + if (src_bytes_left) + { + print_error("Decompressor FAILED to read " QUAD_INT_FMT " bytes from input buffer\n", src_bytes_left); + } + + printf("Success\n"); + printf("Source file size: " QUAD_INT_FMT ", Decompressed file size: " QUAD_INT_FMT "\n", src_file_size, orig_file_size); + if (zlib_header) printf("Decompressed adler32: 0x%08X\n", adler32); + printf("Overall decompression time (decompression init+I/O+decompression): %3.6f\n Consumption rate: %9.1f bytes/sec, Decompression rate: %9.1f bytes/sec\n", total_time, src_file_size / total_time, orig_file_size / total_time); + printf("Decompression only time (not counting decompression init or I/O): %3.6f\n Consumption rate: %9.1f bytes/sec, Decompression rate: %9.1f bytes/sec\n", decomp_only_time, src_file_size / decomp_only_time, orig_file_size / decomp_only_time); + + return true; +} + +static bool compare_files(const char *pFilename1, const char* pFilename2) +{ + FILE* pFile1 = open_file_with_retries(pFilename1, "rb"); + if (!pFile1) + { + print_error("Failed opening file: %s\n", pFilename1); + return false; + } + + FILE* pFile2 = open_file_with_retries(pFilename2, "rb"); + if (!pFile2) + { + print_error("Failed opening file: %s\n", pFilename2); + fclose(pFile1); + return false; + } + + _fseeki64(pFile1, 0, SEEK_END); + int64 fileSize1 = _ftelli64(pFile1); + _fseeki64(pFile1, 0, SEEK_SET); + + _fseeki64(pFile2, 0, SEEK_END); + int64 fileSize2 = _ftelli64(pFile2); + _fseeki64(pFile2, 0, SEEK_SET); + + if (fileSize1 != fileSize2) + { + print_error("Files to compare are not the same size: %I64i vs. %I64i.\n", fileSize1, fileSize2); + fclose(pFile1); + fclose(pFile2); + return false; + } + + const uint cBufSize = 1024 * 1024; + std::vector buf1(cBufSize); + std::vector buf2(cBufSize); + + int64 bytes_remaining = fileSize1; + while (bytes_remaining) + { + const uint bytes_to_read = static_cast(my_min(cBufSize, bytes_remaining)); + + if (fread(&buf1.front(), bytes_to_read, 1, pFile1) != 1) + { + print_error("Failed reading from file: %s\n", pFilename1); + fclose(pFile1); + fclose(pFile2); + return false; + } + + if (fread(&buf2.front(), bytes_to_read, 1, pFile2) != 1) + { + print_error("Failed reading from file: %s\n", pFilename2); + fclose(pFile1); + fclose(pFile2); + return false; + } + + if (memcmp(&buf1.front(), &buf2.front(), bytes_to_read) != 0) + { + print_error("File data comparison failed!\n"); + fclose(pFile1); + fclose(pFile2); + return false; + } + + bytes_remaining -= bytes_to_read; + } + + fclose(pFile1); + fclose(pFile2); + return true; +} + +static bool zip_create(const char *pZip_filename, const char *pSrc_filename) +{ + mz_zip_archive zip; + memset(&zip, 0, sizeof(zip)); + if ((rand() % 100) >= 10) + zip.m_file_offset_alignment = 1 << (rand() & 15); + if (!mz_zip_writer_init_file(&zip, pZip_filename, 65537)) + { + print_error("Failed creating zip archive \"%s\"!\n", pZip_filename); + return false; + } + + mz_bool success = MZ_TRUE; + + const char *pStr = "This is a test!This is a test!This is a test!\n"; + size_t comp_size; + void *pComp_data = tdefl_compress_mem_to_heap(pStr, strlen(pStr), &comp_size, 256); + success &= mz_zip_writer_add_mem_ex(&zip, "precomp.txt", pComp_data, comp_size, "Comment", (uint16)strlen("Comment"), MZ_ZIP_FLAG_COMPRESSED_DATA, strlen(pStr), mz_crc32(MZ_CRC32_INIT, (const uint8 *)pStr, strlen(pStr))); + + success &= mz_zip_writer_add_mem(&zip, "cool/", NULL, 0, 0); + + success &= mz_zip_writer_add_mem(&zip, "1.txt", pStr, strlen(pStr), 9); + int n = rand() & 4095; + for (int i = 0; i < n; i++) + { + char name[256], buf[256], comment[256]; + sprintf(name, "t%u.txt", i); + sprintf(buf, "%u\n", i*5377); + sprintf(comment, "comment: %u\n", i); + success &= mz_zip_writer_add_mem_ex(&zip, name, buf, strlen(buf), comment, (uint16)strlen(comment), i % 10, 0, 0); + } + + const char *pTestComment = "test comment"; + success &= mz_zip_writer_add_file(&zip, "test.bin", pSrc_filename, pTestComment, (uint16)strlen(pTestComment), 9); + + if (ensure_file_exists_and_is_readable("changelog.txt")) + success &= mz_zip_writer_add_file(&zip, "changelog.txt", "changelog.txt", "This is a comment", (uint16)strlen("This is a comment"), 9); + + if (!success) + { + mz_zip_writer_end(&zip); + remove(pZip_filename); + print_error("Failed creating zip archive \"%s\"!\n", pZip_filename); + return false; + } + + if (!mz_zip_writer_finalize_archive(&zip)) + { + mz_zip_writer_end(&zip); + remove(pZip_filename); + print_error("Failed creating zip archive \"%s\"!\n", pZip_filename); + return false; + } + + mz_zip_writer_end(&zip); + + struct FILE_STAT_STRUCT stat_buf; + FILE_STAT(pZip_filename, &stat_buf); + uint64 actual_file_size = stat_buf.st_size; + if (zip.m_archive_size != actual_file_size) + { + print_error("Archive's actual size and zip archive object's size differ for file \"%s\"!\n", pZip_filename); + return false; + } + + printf("Created zip file \"%s\", file size: " QUAD_INT_FMT "\n", pZip_filename, zip.m_archive_size); + return true; +} + +static size_t zip_write_callback(void *pOpaque, uint64 ofs, const void *pBuf, size_t n) +{ + pOpaque, ofs, pBuf, n; + return n; +} + +static bool zip_extract(const char *pZip_filename, const char *pDst_filename) +{ + mz_zip_archive zip; + memset(&zip, 0, sizeof(zip)); + if (!mz_zip_reader_init_file(&zip, pZip_filename, 0)) + { + print_error("Failed opening zip archive \"%s\"!\n", pZip_filename); + return false; + } + + int file_index = mz_zip_reader_locate_file(&zip, "test.bin", "test Comment", 0); + int alt_file_index = mz_zip_reader_locate_file(&zip, "test.bin", "test Comment e", 0); + if ((file_index < 0) || (alt_file_index >= 0)) + { + print_error("Archive \"%s\" is missing test.bin file!\n", pZip_filename); + mz_zip_reader_end(&zip); + return false; + } + + alt_file_index = mz_zip_reader_locate_file(&zip, "test.bin", NULL, 0); + if (alt_file_index != file_index) + { + print_error("mz_zip_reader_locate_file() failed!\n", pZip_filename); + mz_zip_reader_end(&zip); + return false; + } + + if (!mz_zip_reader_extract_to_file(&zip, file_index, pDst_filename, 0)) + { + print_error("Failed extracting test.bin from archive \"%s\"!\n", pZip_filename); + mz_zip_reader_end(&zip); + return false; + } + + for (uint i = 0; i < mz_zip_reader_get_num_files(&zip); i++) + { + mz_zip_archive_file_stat stat; + if (!mz_zip_reader_file_stat(&zip, i, &stat)) + { + print_error("Failed testing archive \"%s\"!\n", pZip_filename); + mz_zip_reader_end(&zip); + return false; + } + //printf("\"%s\" %I64u %I64u\n", stat.m_filename, stat.m_comp_size, stat.m_uncomp_size); + size_t size = 0; + + mz_bool status = mz_zip_reader_extract_to_callback(&zip, i, zip_write_callback, NULL, 0); + if (!status) + { + print_error("Failed testing archive \"%s\"!\n", pZip_filename); + mz_zip_reader_end(&zip); + return false; + } + + void *p = mz_zip_reader_extract_to_heap(&zip, i, &size, 0); + if (!p) + { + print_error("Failed testing archive \"%s\"!\n", pZip_filename); + mz_zip_reader_end(&zip); + return false; + } + free(p); + } + printf("Verified %u files\n", mz_zip_reader_get_num_files(&zip)); + + mz_zip_reader_end(&zip); + + printf("Extracted file \"%s\"\n", pDst_filename); + return true; +} + +typedef std::vector< std::string > string_array; + +#if defined(WIN32) +static bool find_files(std::string pathname, const std::string &filename, string_array &files, bool recursive, int depth = 0) +{ + if (!pathname.empty()) + { + char c = pathname[pathname.size() - 1]; + if ((c != ':') && (c != '\\') && (c != '/')) + pathname += "\\"; + } + + WIN32_FIND_DATAA find_data; + + HANDLE findHandle = FindFirstFileA((pathname + filename).c_str(), &find_data); + if (findHandle == INVALID_HANDLE_VALUE) + { + HRESULT hres = GetLastError(); + if ((!depth) && (hres != NO_ERROR) && (hres != ERROR_FILE_NOT_FOUND)) + return false; + } + else + { + do + { + const bool is_directory = (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; + const bool is_system = (find_data.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) != 0; + const bool is_hidden = false;//(find_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0; + + std::string filename(find_data.cFileName); + + if ((!is_directory) && (!is_system) && (!is_hidden)) + files.push_back(pathname + filename); + + } while (FindNextFileA(findHandle, &find_data)); + + FindClose(findHandle); + } + + if (recursive) + { + string_array paths; + + HANDLE findHandle = FindFirstFileA((pathname + "*").c_str(), &find_data); + if (findHandle != INVALID_HANDLE_VALUE) + { + do + { + const bool is_directory = (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; + const bool is_system = (find_data.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) != 0; + const bool is_hidden = false;//(find_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0; + + std::string filename(find_data.cFileName); + + if ((is_directory) && (!is_hidden) && (!is_system)) + paths.push_back(filename); + + } while (FindNextFileA(findHandle, &find_data)); + + FindClose(findHandle); + + for (uint i = 0; i < paths.size(); i++) + { + const std::string &path = paths[i]; + if (path[0] == '.') + continue; + + if (!find_files(pathname + path, filename, files, true, depth + 1)) + return false; + } + } + } + + return true; +} +#else +#include +#include +static bool find_files(std::string pathname, const std::string &pattern, string_array &files, bool recursive, int depth = 0) +{ + if (!pathname.empty()) + { + char c = pathname[pathname.size() - 1]; + if ((c != ':') && (c != '\\') && (c != '/')) + pathname += "/"; + } + + DIR *dp = opendir(pathname.c_str()); + + if (!dp) + return depth ? true : false; + + string_array paths; + + for ( ; ; ) + { + struct dirent *ep = readdir(dp); + if (!ep) + break; + + const bool is_directory = (ep->d_type & DT_DIR) != 0; + const bool is_file = (ep->d_type & DT_REG) != 0; + + if (ep->d_name[0] == '.') + continue; + + std::string filename(ep->d_name); + + if (is_directory) + { + if (recursive) + paths.push_back(filename); + } + else if (is_file) + { + if (0 == fnmatch(pattern.c_str(), filename.c_str(), 0)) + files.push_back(pathname + filename); + } + } + + closedir(dp); + dp = NULL; + + if (recursive) + { + for (uint i = 0; i < paths.size(); i++) + { + const std::string &path = paths[i]; + if (!find_files(pathname + path, pattern, files, true, depth + 1)) + return false; + } + } + + return true; +} +#endif + +static bool test_recursive(const char *pPath, comp_options options) +{ + string_array files; + if (!find_files(pPath, "*", files, true)) + { + print_error("Failed finding files under path \"%s\"!\n", pPath); + return false; + } + + uint total_files_compressed = 0; + uint64 total_source_size = 0; + uint64 total_comp_size = 0; + +#ifdef WIN32 + MEMORYSTATUS initial_mem_status; + GlobalMemoryStatus(&initial_mem_status); +#endif + + timer_ticks start_tick_count = timer::get_ticks(); + + const int first_file_index = 0; + + uint unique_id = static_cast(timer::get_init_ticks()); + char cmp_file[256], decomp_file[256]; + + sprintf(cmp_file, "__comp_temp_%u__.tmp", unique_id); + sprintf(decomp_file, "__decomp_temp_%u__.tmp", unique_id); + + for (uint file_index = first_file_index; file_index < files.size(); file_index++) + { + const std::string &src_file = files[file_index]; + + printf("***** [%u of %u] Compressing file \"%s\" to \"%s\"\n", 1 + file_index, (uint)files.size(), src_file.c_str(), cmp_file); + + if ((strstr(src_file.c_str(), "__comp_temp") != NULL) || (strstr(src_file.c_str(), "__decomp_temp") != NULL)) + { + printf("Skipping temporary file \"%s\"\n", src_file.c_str()); + continue; + } + + FILE *pFile = fopen(src_file.c_str(), "rb"); + if (!pFile) + { + printf("Skipping unreadable file \"%s\"\n", src_file.c_str()); + continue; + } + _fseeki64(pFile, 0, SEEK_END); + int64 src_file_size = _ftelli64(pFile); + + if (src_file_size) + { + _fseeki64(pFile, 0, SEEK_SET); + if (fgetc(pFile) == EOF) + { + printf("Skipping unreadable file \"%s\"\n", src_file.c_str()); + fclose(pFile); + continue; + } + } + + fclose(pFile); + + if (!ensure_file_is_writable(cmp_file)) + { + print_error("Unable to create file \"%s\"!\n", cmp_file); + return false; + } + + comp_options file_options(options); + if (options.m_randomize_params) + { + file_options.m_level = rand() % 11; + file_options.m_unbuffered_decompression = (rand() & 1) != 0; + file_options.m_z_strat = rand() % (Z_FIXED + 1); + file_options.m_write_zlib_header = (rand() & 1) != 0; + file_options.m_random_z_flushing = (rand() & 1) != 0; + file_options.print(); + } + + bool status; + if (file_options.m_archive_test) + { + if (src_file_size > 0xFFF00000) + { + printf("Skipping too big file \"%s\"\n", src_file.c_str()); + continue; + } + printf("Creating test archive with file \"%s\", size " QUAD_INT_FMT "\n", src_file.c_str(), src_file_size); + status = zip_create(cmp_file, src_file.c_str()); + } + else + status = compress_file_zlib(src_file.c_str(), cmp_file, file_options); + if (!status) + { + print_error("Failed compressing file \"%s\" to \"%s\"\n", src_file.c_str(), cmp_file); + return false; + } + + if (file_options.m_verify_compressed_data) + { + printf("Decompressing file \"%s\" to \"%s\"\n", cmp_file, decomp_file); + + if (!ensure_file_is_writable(decomp_file)) + { + print_error("Unable to create file \"%s\"!\n", decomp_file); + return false; + } + + if (file_options.m_archive_test) + status = zip_extract(cmp_file, decomp_file); + else + status = decompress_file_zlib(cmp_file, decomp_file, file_options); + + if (!status) + { + print_error("Failed decompressing file \"%s\" to \"%s\"\n", src_file.c_str(), decomp_file); + return false; + } + + printf("Comparing file \"%s\" to \"%s\"\n", decomp_file, src_file.c_str()); + + if (!compare_files(decomp_file, src_file.c_str())) + { + print_error("Failed comparing decompressed file data while compressing \"%s\" to \"%s\"\n", src_file.c_str(), cmp_file); + return false; + } + else + { + printf("Decompressed file compared OK to original file.\n"); + } + } + + int64 cmp_file_size = 0; + pFile = fopen(cmp_file, "rb"); + if (pFile) + { + _fseeki64(pFile, 0, SEEK_END); + cmp_file_size = _ftelli64(pFile); + fclose(pFile); + } + + total_files_compressed++; + total_source_size += src_file_size; + total_comp_size += cmp_file_size; + +#ifdef WIN32 + MEMORYSTATUS mem_status; + GlobalMemoryStatus(&mem_status); + + const int64 bytes_allocated = initial_mem_status.dwAvailVirtual- mem_status.dwAvailVirtual; + + printf("Memory allocated relative to first file: %I64i\n", bytes_allocated); +#endif + + printf("\n"); + } + + timer_ticks end_tick_count = timer::get_ticks(); + + double total_elapsed_time = timer::ticks_to_secs(end_tick_count - start_tick_count); + + printf("Test successful: %f secs\n", total_elapsed_time); + printf("Total files processed: %u\n", total_files_compressed); + printf("Total source size: " QUAD_INT_FMT "\n", total_source_size); + printf("Total compressed size: " QUAD_INT_FMT "\n", total_comp_size); + printf("Max small comp ratio: %f, Max large comp ratio: %f\n", s_max_small_comp_ratio, s_max_large_comp_ratio); + + remove(cmp_file); + remove(decomp_file); + + return true; +} + +static size_t dummy_zip_file_write_callback(void *pOpaque, uint64 ofs, const void *pBuf, size_t n) +{ + ofs; pBuf; + uint32 *pCRC = (uint32*)pOpaque; + *pCRC = mz_crc32(*pCRC, (const uint8*)pBuf, n); + return n; +} + +static bool test_archives(const char *pPath, comp_options options) +{ + options; + + string_array files; + if (!find_files(pPath, "*.zip", files, true)) + { + print_error("Failed finding files under path \"%s\"!\n", pPath); + return false; + } + + uint total_archives = 0; + uint64 total_bytes_processed = 0; + uint64 total_files_processed = 0; + uint total_errors = 0; + +#ifdef WIN32 + MEMORYSTATUS initial_mem_status; + GlobalMemoryStatus(&initial_mem_status); +#endif + + const int first_file_index = 0; + uint unique_id = static_cast(timer::get_init_ticks()); + char cmp_file[256], decomp_file[256]; + + sprintf(decomp_file, "__decomp_temp_%u__.tmp", unique_id); + + string_array failed_archives; + + for (uint file_index = first_file_index; file_index < files.size(); file_index++) + { + const std::string &src_file = files[file_index]; + + printf("***** [%u of %u] Testing archive file \"%s\"\n", 1 + file_index, (uint)files.size(), src_file.c_str()); + + if ((strstr(src_file.c_str(), "__comp_temp") != NULL) || (strstr(src_file.c_str(), "__decomp_temp") != NULL)) + { + printf("Skipping temporary file \"%s\"\n", src_file.c_str()); + continue; + } + + FILE *pFile = fopen(src_file.c_str(), "rb"); + if (!pFile) + { + printf("Skipping unreadable file \"%s\"\n", src_file.c_str()); + continue; + } + _fseeki64(pFile, 0, SEEK_END); + int64 src_file_size = _ftelli64(pFile); + fclose(pFile); + + src_file_size; + + sprintf(cmp_file, "__comp_temp_%u__.zip", file_index); + + mz_zip_archive src_archive; + memset(&src_archive, 0, sizeof(src_archive)); + + if (!mz_zip_reader_init_file(&src_archive, src_file.c_str(), 0)) + { + failed_archives.push_back(src_file); + + print_error("Failed opening archive \"%s\"!\n", src_file.c_str()); + total_errors++; + continue; + } + + mz_zip_archive dst_archive; + memset(&dst_archive, 0, sizeof(dst_archive)); + if (options.m_write_archives) + { + if (!ensure_file_is_writable(cmp_file)) + { + print_error("Unable to create file \"%s\"!\n", cmp_file); + return false; + } + + if (!mz_zip_writer_init_file(&dst_archive, cmp_file, 0)) + { + print_error("Failed creating archive \"%s\"!\n", cmp_file); + total_errors++; + continue; + } + } + + int i; + //for (i = 0; i < mz_zip_reader_get_num_files(&src_archive); i++) + for (i = mz_zip_reader_get_num_files(&src_archive) - 1; i >= 0; --i) + { + if (mz_zip_reader_is_file_encrypted(&src_archive, i)) + continue; + + mz_zip_archive_file_stat file_stat; + bool status = mz_zip_reader_file_stat(&src_archive, i, &file_stat) != 0; + + int locate_file_index = mz_zip_reader_locate_file(&src_archive, file_stat.m_filename, NULL, 0); + if (locate_file_index != i) + { + mz_zip_archive_file_stat locate_file_stat; + mz_zip_reader_file_stat(&src_archive, locate_file_index, &locate_file_stat); + if (_stricmp(locate_file_stat.m_filename, file_stat.m_filename) != 0) + { + print_error("mz_zip_reader_locate_file() failed!\n"); + return false; + } + else + { + printf("Warning: Duplicate filenames in archive!\n"); + } + } + + if ((file_stat.m_method) && (file_stat.m_method != MZ_DEFLATED)) + continue; + + if (status) + { + char name[260]; + mz_zip_reader_get_filename(&src_archive, i, name, sizeof(name)); + + size_t extracted_size = 0; + void *p = mz_zip_reader_extract_file_to_heap(&src_archive, name, &extracted_size, 0); + if (!p) + status = false; + + uint32 extracted_crc32 = MZ_CRC32_INIT; + if (!mz_zip_reader_extract_file_to_callback(&src_archive, name, dummy_zip_file_write_callback, &extracted_crc32, 0)) + status = false; + + if (mz_crc32(MZ_CRC32_INIT, (const uint8*)p, extracted_size) != extracted_crc32) + status = false; + + free(p); + + if (options.m_write_archives) + { + if ((status) && (!mz_zip_writer_add_from_zip_reader(&dst_archive, &src_archive, i))) + { + print_error("Failed adding new file to archive \"%s\"!\n", cmp_file); + status = false; + } + } + + total_bytes_processed += file_stat.m_uncomp_size; + total_files_processed++; + } + + if (!status) + break; + } + + mz_zip_reader_end(&src_archive); + + //if (i < mz_zip_reader_get_num_files(&src_archive)) + if (i >= 0) + { + failed_archives.push_back(src_file); + + print_error("Failed processing archive \"%s\"!\n", src_file.c_str()); + total_errors++; + } + + if (options.m_write_archives) + { + if (!mz_zip_writer_finalize_archive(&dst_archive) || !mz_zip_writer_end(&dst_archive)) + { + failed_archives.push_back(src_file); + + print_error("Failed finalizing archive \"%s\"!\n", cmp_file); + total_errors++; + } + } + + total_archives++; + +#ifdef WIN32 + MEMORYSTATUS mem_status; + GlobalMemoryStatus(&mem_status); + + const int64 bytes_allocated = initial_mem_status.dwAvailVirtual- mem_status.dwAvailVirtual; + + printf("Memory allocated relative to first file: %I64i\n", bytes_allocated); +#endif + + printf("\n"); + } + + printf("Total archives processed: %u\n", total_archives); + printf("Total errors: %u\n", total_errors); + printf("Total bytes processed: " QUAD_INT_FMT "\n", total_bytes_processed); + printf("Total archive files processed: " QUAD_INT_FMT "\n", total_files_processed); + + printf("List of failed archives:\n"); + for (uint i = 0; i < failed_archives.size(); ++i) + printf("%s\n", failed_archives[i].c_str()); + + remove(cmp_file); + remove(decomp_file); + + return true; +} + +int main_internal(string_array cmd_line) +{ + comp_options options; + + if (!cmd_line.size()) + { + print_usage(); + if (simple_test1(options) || simple_test2(options)) + return EXIT_FAILURE; + return EXIT_SUCCESS; + } + + enum op_mode_t + { + OP_MODE_INVALID = -1, + OP_MODE_COMPRESS = 0, + OP_MODE_DECOMPRESS = 1, + OP_MODE_ALL = 2, + OP_MODE_ARCHIVES = 3 + }; + + op_mode_t op_mode = OP_MODE_INVALID; + + for (int i = 0; i < (int)cmd_line.size(); i++) + { + const std::string &str = cmd_line[i]; + if (str[0] == '-') + { + if (str.size() < 2) + { + print_error("Invalid option: %s\n", str.c_str()); + return EXIT_FAILURE; + } + switch (tolower(str[1])) + { + case 'u': + { + options.m_unbuffered_decompression = true; + break; + } + case 'm': + { + int comp_level = atoi(str.c_str() + 2); + if ((comp_level < 0) || (comp_level > (int)10)) + { + print_error("Invalid compression level: %s\n", str.c_str()); + return EXIT_FAILURE; + } + + options.m_level = comp_level; + break; + } + case 'v': + { + options.m_verify_compressed_data = true; + break; + } + case 'r': + { + options.m_randomize_params = true; + break; + } + case 'b': + { + options.m_randomize_buffer_sizes = true; + break; + } + case 'h': + { + options.m_random_z_flushing = true; + break; + } + case 'x': + { + int seed = atoi(str.c_str() + 2); + srand(seed); + printf("Using random seed: %i\n", seed); + break; + } + case 't': + { + options.m_z_strat = my_min(Z_FIXED, my_max(0, atoi(str.c_str() + 2))); + break; + } + case 'z': + { + options.m_write_zlib_header = false; + break; + } + case 'a': + { + options.m_archive_test = true; + break; + } + case 'w': + { + options.m_write_archives = true; + break; + } + default: + { + print_error("Invalid option: %s\n", str.c_str()); + return EXIT_FAILURE; + } + } + + cmd_line.erase(cmd_line.begin() + i); + i--; + + continue; + } + + if (str.size() != 1) + { + print_error("Invalid mode: %s\n", str.c_str()); + return EXIT_FAILURE; + } + switch (tolower(str[0])) + { + case 'c': + { + op_mode = OP_MODE_COMPRESS; + break; + } + case 'd': + { + op_mode = OP_MODE_DECOMPRESS; + break; + } + case 'a': + { + op_mode = OP_MODE_ALL; + break; + } + case 'r': + { + op_mode = OP_MODE_ARCHIVES; + break; + } + default: + { + print_error("Invalid mode: %s\n", str.c_str()); + return EXIT_FAILURE; + } + } + cmd_line.erase(cmd_line.begin() + i); + break; + } + + if (op_mode == OP_MODE_INVALID) + { + print_error("No mode specified!\n"); + print_usage(); + return EXIT_FAILURE; + } + + printf("Using options:\n"); + options.print(); + printf("\n"); + + int exit_status = EXIT_FAILURE; + + switch (op_mode) + { + case OP_MODE_COMPRESS: + { + if (cmd_line.size() < 2) + { + print_error("Must specify input and output filenames!\n"); + return EXIT_FAILURE; + } + else if (cmd_line.size() > 2) + { + print_error("Too many filenames!\n"); + return EXIT_FAILURE; + } + + const std::string &src_file = cmd_line[0]; + const std::string &cmp_file = cmd_line[1]; + + bool comp_result = compress_file_zlib(src_file.c_str(), cmp_file.c_str(), options); + if (comp_result) + exit_status = EXIT_SUCCESS; + + if ((comp_result) && (options.m_verify_compressed_data)) + { + char decomp_file[256]; + + sprintf(decomp_file, "__decomp_temp_%u__.tmp", (uint)timer::get_ms()); + + if (!decompress_file_zlib(cmp_file.c_str(), decomp_file, options)) + { + print_error("Failed decompressing file \"%s\" to \"%s\"\n", cmp_file.c_str(), decomp_file); + return EXIT_FAILURE; + } + + printf("Comparing file \"%s\" to \"%s\"\n", decomp_file, src_file.c_str()); + + if (!compare_files(decomp_file, src_file.c_str())) + { + print_error("Failed comparing decompressed file data while compressing \"%s\" to \"%s\"\n", src_file.c_str(), cmp_file.c_str()); + return EXIT_FAILURE; + } + else + { + printf("Decompressed file compared OK to original file.\n"); + } + + remove(decomp_file); + } + + break; + } + case OP_MODE_DECOMPRESS: + { + if (cmd_line.size() < 2) + { + print_error("Must specify input and output filenames!\n"); + return EXIT_FAILURE; + } + else if (cmd_line.size() > 2) + { + print_error("Too many filenames!\n"); + return EXIT_FAILURE; + } + if (decompress_file_zlib(cmd_line[0].c_str(), cmd_line[1].c_str(), options)) + exit_status = EXIT_SUCCESS; + break; + } + case OP_MODE_ALL: + { + if (!cmd_line.size()) + { + print_error("No directory specified!\n"); + return EXIT_FAILURE; + } + else if (cmd_line.size() != 1) + { + print_error("Too many filenames!\n"); + return EXIT_FAILURE; + } + if (test_recursive(cmd_line[0].c_str(), options)) + exit_status = EXIT_SUCCESS; + break; + } + case OP_MODE_ARCHIVES: + { + if (!cmd_line.size()) + { + print_error("No directory specified!\n"); + return EXIT_FAILURE; + } + else if (cmd_line.size() != 1) + { + print_error("Too many filenames!\n"); + return EXIT_FAILURE; + } + if (test_archives(cmd_line[0].c_str(), options)) + exit_status = EXIT_SUCCESS; + break; + } + default: + { + print_error("No mode specified!\n"); + print_usage(); + return EXIT_FAILURE; + } + } + + return exit_status; +} + +int main(int argc, char *argv[]) +{ +#ifdef _WIN64 + printf("miniz.c x64 Command Line Test App - Compiled %s %s\n", __DATE__, __TIME__); +#else + printf("miniz.c x86 Command Line Test App - Compiled %s %s\n", __DATE__, __TIME__); +#endif + timer::get_ticks(); + + string_array cmd_line; + for (int i = 1; i < argc; i++) + cmd_line.push_back(std::string(argv[i])); + + int exit_status = main_internal(cmd_line); + + return exit_status; +} diff --git a/miniz/timer.cpp b/miniz/timer.cpp new file mode 100644 index 0000000000..bb35b6c2b2 --- /dev/null +++ b/miniz/timer.cpp @@ -0,0 +1,152 @@ +// File: timer.cpp - Simple high-precision timer class. Supports Win32, X360, and POSIX/Linux +#include +#include +#include +#include + +#include "timer.h" + +#if defined(WIN32) +#include +#elif defined(_XBOX) +#include +#endif + +unsigned long long timer::g_init_ticks; +unsigned long long timer::g_freq; +double timer::g_inv_freq; + +#if defined(WIN32) || defined(_XBOX) +inline void query_counter(timer_ticks *pTicks) +{ + QueryPerformanceCounter(reinterpret_cast(pTicks)); +} +inline void query_counter_frequency(timer_ticks *pTicks) +{ + QueryPerformanceFrequency(reinterpret_cast(pTicks)); +} +#elif defined(__GNUC__) +#include +inline void query_counter(timer_ticks *pTicks) +{ + struct timeval cur_time; + gettimeofday(&cur_time, NULL); + *pTicks = static_cast(cur_time.tv_sec)*1000000ULL + static_cast(cur_time.tv_usec); +} +inline void query_counter_frequency(timer_ticks *pTicks) +{ + *pTicks = 1000000; +} +#endif + +timer::timer() : + m_start_time(0), + m_stop_time(0), + m_started(false), + m_stopped(false) +{ + if (!g_inv_freq) + init(); +} + +timer::timer(timer_ticks start_ticks) +{ + if (!g_inv_freq) + init(); + + m_start_time = start_ticks; + + m_started = true; + m_stopped = false; +} + +void timer::start(timer_ticks start_ticks) +{ + m_start_time = start_ticks; + + m_started = true; + m_stopped = false; +} + +void timer::start() +{ + query_counter(&m_start_time); + + m_started = true; + m_stopped = false; +} + +void timer::stop() +{ + assert(m_started); + + query_counter(&m_stop_time); + + m_stopped = true; +} + +double timer::get_elapsed_secs() const +{ + assert(m_started); + if (!m_started) + return 0; + + timer_ticks stop_time = m_stop_time; + if (!m_stopped) + query_counter(&stop_time); + + timer_ticks delta = stop_time - m_start_time; + return delta * g_inv_freq; +} + +timer_ticks timer::get_elapsed_us() const +{ + assert(m_started); + if (!m_started) + return 0; + + timer_ticks stop_time = m_stop_time; + if (!m_stopped) + query_counter(&stop_time); + + timer_ticks delta = stop_time - m_start_time; + return (delta * 1000000ULL + (g_freq >> 1U)) / g_freq; +} + +void timer::init() +{ + if (!g_inv_freq) + { + query_counter_frequency(&g_freq); + g_inv_freq = 1.0f / g_freq; + + query_counter(&g_init_ticks); + } +} + +timer_ticks timer::get_init_ticks() +{ + if (!g_inv_freq) + init(); + + return g_init_ticks; +} + +timer_ticks timer::get_ticks() +{ + if (!g_inv_freq) + init(); + + timer_ticks ticks; + query_counter(&ticks); + return ticks - g_init_ticks; +} + +double timer::ticks_to_secs(timer_ticks ticks) +{ + if (!g_inv_freq) + init(); + + return ticks * g_inv_freq; +} + diff --git a/miniz/timer.h b/miniz/timer.h new file mode 100644 index 0000000000..df6e01f401 --- /dev/null +++ b/miniz/timer.h @@ -0,0 +1,40 @@ +// File: timer.h +#pragma once + +typedef unsigned long long timer_ticks; + +class timer +{ +public: + timer(); + timer(timer_ticks start_ticks); + + void start(); + void start(timer_ticks start_ticks); + + void stop(); + + double get_elapsed_secs() const; + inline double get_elapsed_ms() const { return get_elapsed_secs() * 1000.0f; } + timer_ticks get_elapsed_us() const; + + static void init(); + static inline timer_ticks get_ticks_per_sec() { return g_freq; } + static timer_ticks get_init_ticks(); + static timer_ticks get_ticks(); + static double ticks_to_secs(timer_ticks ticks); + static inline double ticks_to_ms(timer_ticks ticks) { return ticks_to_secs(ticks) * 1000.0f; } + static inline double get_secs() { return ticks_to_secs(get_ticks()); } + static inline double get_ms() { return ticks_to_ms(get_ticks()); } + +private: + static timer_ticks g_init_ticks; + static timer_ticks g_freq; + static double g_inv_freq; + + timer_ticks m_start_time; + timer_ticks m_stop_time; + + bool m_started : 1; + bool m_stopped : 1; +}; diff --git a/miniz/tinfl.c b/miniz/tinfl.c new file mode 100644 index 0000000000..a17a156b6c --- /dev/null +++ b/miniz/tinfl.c @@ -0,0 +1,592 @@ +/* tinfl.c v1.11 - public domain inflate with zlib header parsing/adler32 checking (inflate-only subset of miniz.c) + See "unlicense" statement at the end of this file. + Rich Geldreich , last updated May 20, 2011 + Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt + + The entire decompressor coroutine is implemented in tinfl_decompress(). The other functions are optional high-level helpers. +*/ +#ifndef TINFL_HEADER_INCLUDED +#define TINFL_HEADER_INCLUDED + +#include + +typedef unsigned char mz_uint8; +typedef signed short mz_int16; +typedef unsigned short mz_uint16; +typedef unsigned int mz_uint32; +typedef unsigned int mz_uint; +typedef unsigned long long mz_uint64; + +#if defined(_M_IX86) || defined(_M_X64) +// Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 if integer loads and stores to unaligned addresses are acceptable on the target platform (slightly faster). +#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 +// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. +#define MINIZ_LITTLE_ENDIAN 1 +#endif + +#if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) +// Set MINIZ_HAS_64BIT_REGISTERS to 1 if the processor has 64-bit general purpose registers (enables 64-bit bitbuffer in inflator) +#define MINIZ_HAS_64BIT_REGISTERS 1 +#endif + +// Works around MSVC's spammy "warning C4127: conditional expression is constant" message. +#ifdef _MSC_VER + #define MZ_MACRO_END while (0, 0) +#else + #define MZ_MACRO_END while (0) +#endif + +// Decompression flags used by tinfl_decompress(). +// TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream. +// TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input. +// TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB). +// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes. +enum +{ + TINFL_FLAG_PARSE_ZLIB_HEADER = 1, + TINFL_FLAG_HAS_MORE_INPUT = 2, + TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4, + TINFL_FLAG_COMPUTE_ADLER32 = 8 +}; + +// High level decompression functions: +// tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc(). +// On entry: +// pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress. +// On return: +// Function returns a pointer to the decompressed data, or NULL on failure. +// *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data. +// The caller must free() the returned block when it's no longer needed. +void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); + +// tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory. +// Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success. +#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1)) +size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); + +// tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer. +// Returns 1 on success or 0 on failure. +typedef int (*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser); +int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); + +struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor; + +// Max size of LZ dictionary. +#define TINFL_LZ_DICT_SIZE 32768 + +// Return status. +typedef enum +{ + TINFL_STATUS_BAD_PARAM = -3, + TINFL_STATUS_ADLER32_MISMATCH = -2, + TINFL_STATUS_FAILED = -1, + TINFL_STATUS_DONE = 0, + TINFL_STATUS_NEEDS_MORE_INPUT = 1, + TINFL_STATUS_HAS_MORE_OUTPUT = 2 +} tinfl_status; + +// Initializes the decompressor to its initial state. +#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END +#define tinfl_get_adler32(r) (r)->m_check_adler32 + +// Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. +// This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. +tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags); + +// Internal/private bits follow. +enum +{ + TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19, + TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS +}; + +typedef struct +{ + mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0]; + mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; +} tinfl_huff_table; + +#if MINIZ_HAS_64BIT_REGISTERS + #define TINFL_USE_64BIT_BITBUF 1 +#endif + +#if TINFL_USE_64BIT_BITBUF + typedef mz_uint64 tinfl_bit_buf_t; + #define TINFL_BITBUF_SIZE (64) +#else + typedef mz_uint32 tinfl_bit_buf_t; + #define TINFL_BITBUF_SIZE (32) +#endif + +struct tinfl_decompressor_tag +{ + mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES]; + tinfl_bit_buf_t m_bit_buf; + size_t m_dist_from_out_buf_start; + tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES]; + mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137]; +}; + +#endif // #ifdef TINFL_HEADER_INCLUDED + +// ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.) + +#ifndef TINFL_HEADER_FILE_ONLY + +#include + +// MZ_MALLOC, etc. are only used by the optional high-level helper functions. +#ifdef MINIZ_NO_MALLOC + #define MZ_MALLOC(x) NULL + #define MZ_FREE(x) x, ((void)0) + #define MZ_REALLOC(p, x) NULL +#else + #define MZ_MALLOC(x) malloc(x) + #define MZ_FREE(x) free(x) + #define MZ_REALLOC(p, x) realloc(p, x) +#endif + +#define MZ_MAX(a,b) (((a)>(b))?(a):(b)) +#define MZ_MIN(a,b) (((a)<(b))?(a):(b)) +#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj)) + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + #define MZ_READ_LE16(p) *((const mz_uint16 *)(p)) + #define MZ_READ_LE32(p) *((const mz_uint32 *)(p)) +#else + #define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U)) + #define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U)) +#endif + +#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l) +#define TINFL_MEMSET(p, c, l) memset(p, c, l) + +#define TINFL_CR_BEGIN switch(r->m_state) { case 0: +#define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END +#define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END +#define TINFL_CR_FINISH } + +// TODO: If the caller has indicated that there's no more input, and we attempt to read beyond the input buf, then something is wrong with the input because the inflator never +// reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario. +#define TINFL_GET_BYTE(state_index, c) do { \ + if (pIn_buf_cur >= pIn_buf_end) { \ + for ( ; ; ) { \ + if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \ + TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \ + if (pIn_buf_cur < pIn_buf_end) { \ + c = *pIn_buf_cur++; \ + break; \ + } \ + } else { \ + c = 0; \ + break; \ + } \ + } \ + } else c = *pIn_buf_cur++; } MZ_MACRO_END + +#define TINFL_NEED_BITS(state_index, n) do { mz_uint c; TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; } while (num_bits < (mz_uint)(n)) +#define TINFL_SKIP_BITS(state_index, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END +#define TINFL_GET_BITS(state_index, b, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } b = bit_buf & ((1 << (n)) - 1); bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END + +// TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. +// It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a +// Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the +// bit buffer contains >=15 bits (deflate's max. Huffman code size). +#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \ + do { \ + temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ + if (temp >= 0) { \ + code_len = temp >> 9; \ + if ((code_len) && (num_bits >= code_len)) \ + break; \ + } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \ + code_len = TINFL_FAST_LOOKUP_BITS; \ + do { \ + temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ + } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \ + } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \ + } while (num_bits < 15); + +// TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read +// beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully +// decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32. +// The slow path is only executed at the very end of the input buffer. +#define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \ + int temp; mz_uint code_len, c; \ + if (num_bits < 15) { \ + if ((pIn_buf_end - pIn_buf_cur) < 2) { \ + TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \ + } else { \ + bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); pIn_buf_cur += 2; num_bits += 16; \ + } \ + } \ + if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \ + code_len = temp >> 9, temp &= 511; \ + else { \ + code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \ + } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END + +tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags) +{ + static const int s_length_base[31] = { 3,4,5,6,7,8,9,10,11,13, 15,17,19,23,27,31,35,43,51,59, 67,83,99,115,131,163,195,227,258,0,0 }; + static const int s_length_extra[31]= { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; + static const int s_dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; + static const int s_dist_extra[32] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + static const mz_uint8 s_length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + static const int s_min_table_sizes[3] = { 257, 1, 4 }; + + tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf; + const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size; + mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size; + size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start; + + // Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). + if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) { *pIn_buf_size = *pOut_buf_size = 0; return TINFL_STATUS_BAD_PARAM; } + + num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; counter = r->m_counter; num_extra = r->m_num_extra; dist_from_out_buf_start = r->m_dist_from_out_buf_start; + TINFL_CR_BEGIN + + bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1; + if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) + { + TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1); + counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8)); + if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4))))); + if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); } + } + + do + { + TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1; + if (r->m_type == 0) + { + TINFL_SKIP_BITS(5, num_bits & 7); + for (counter = 0; counter < 4; ++counter) { if (num_bits) TINFL_GET_BITS(6, r->m_raw_header[counter], 8); else TINFL_GET_BYTE(7, r->m_raw_header[counter]); } + if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); } + while ((counter) && (num_bits)) + { + TINFL_GET_BITS(51, dist, 8); + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = (mz_uint8)dist; + counter--; + } + while (counter) + { + size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); } + while (pIn_buf_cur >= pIn_buf_end) + { + if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) + { + TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT); + } + else + { + TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED); + } + } + n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter); + TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n; + } + } + else if (r->m_type == 3) + { + TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED); + } + else + { + if (r->m_type == 1) + { + mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i; + r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32); + for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8; + } + else + { + for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; } + MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; } + r->m_table_sizes[2] = 19; + } + for ( ; (int)r->m_type >= 0; r->m_type--) + { + int tree_next, tree_cur; tinfl_huff_table *pTable; + mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree); + for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++; + used_syms = 0, total = 0; next_code[0] = next_code[1] = 0; + for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); } + if ((65536 != total) && (used_syms > 1)) + { + TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED); + } + for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index) + { + mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue; + cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1); + if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { pTable->m_look_up[rev_code] = k; rev_code += (1 << code_size); } continue; } + if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } + rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1); + for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) + { + tree_cur -= ((rev_code >>= 1) & 1); + if (!pTable->m_tree[-tree_cur - 1]) { pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else tree_cur = pTable->m_tree[-tree_cur - 1]; + } + tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index; + } + if (r->m_type == 2) + { + for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); ) + { + mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; } + if ((dist == 16) && (!counter)) + { + TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED); + } + num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16]; + TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s; + } + if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter) + { + TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); + } + TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); + } + } + for ( ; ; ) + { + mz_uint8 *pSrc; + for ( ; ; ) + { + if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2)) + { + TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]); + if (counter >= 256) + break; + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = (mz_uint8)counter; + } + else + { + int sym2; mz_uint code_len; +#if TINFL_USE_64BIT_BITBUF + if (num_bits < 30) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); pIn_buf_cur += 4; num_bits += 32; } +#else + if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; } +#endif + if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + code_len = sym2 >> 9; + else + { + code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); + } + counter = sym2; bit_buf >>= code_len; num_bits -= code_len; + if (counter & 256) + break; + +#if !TINFL_USE_64BIT_BITBUF + if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; } +#endif + if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + code_len = sym2 >> 9; + else + { + code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); + } + bit_buf >>= code_len; num_bits -= code_len; + + pOut_buf_cur[0] = (mz_uint8)counter; + if (sym2 & 256) + { + pOut_buf_cur++; + counter = sym2; + break; + } + pOut_buf_cur[1] = (mz_uint8)sym2; + pOut_buf_cur += 2; + } + } + if ((counter &= 511) == 256) break; + + num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257]; + if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; } + + TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]); + num_extra = s_dist_extra[dist]; dist = s_dist_base[dist]; + if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; } + + dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start; + if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) + { + TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED); + } + + pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask); + + if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end) + { + while (counter--) + { + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask]; + } + continue; + } +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES + else if ((counter >= 9) && (counter <= dist)) + { + const mz_uint8 *pSrc_end = pSrc + (counter & ~7); + do + { + ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0]; + ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1]; + pOut_buf_cur += 8; + } while ((pSrc += 8) < pSrc_end); + if ((counter &= 7) < 3) + { + if (counter) + { + pOut_buf_cur[0] = pSrc[0]; + if (counter > 1) + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur += counter; + } + continue; + } + } +#endif + do + { + pOut_buf_cur[0] = pSrc[0]; + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur[2] = pSrc[2]; + pOut_buf_cur += 3; pSrc += 3; + } while ((int)(counter -= 3) > 2); + if ((int)counter > 0) + { + pOut_buf_cur[0] = pSrc[0]; + if ((int)counter > 1) + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur += counter; + } + } + } + } while (!(r->m_final & 1)); + if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) + { + TINFL_SKIP_BITS(32, num_bits & 7); for (counter = 0; counter < 4; ++counter) { mz_uint s; if (num_bits) TINFL_GET_BITS(41, s, 8); else TINFL_GET_BYTE(42, s); r->m_z_adler32 = (r->m_z_adler32 << 8) | s; } + } + TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE); + TINFL_CR_FINISH + +common_exit: + r->m_num_bits = num_bits; r->m_bit_buf = bit_buf; r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; r->m_dist_from_out_buf_start = dist_from_out_buf_start; + *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next; + if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0)) + { + const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size; + mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552; + while (buf_len) + { + for (i = 0; i + 7 < block_len; i += 8, ptr += 8) + { + s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1; + s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1; + } + for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1; + s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552; + } + r->m_check_adler32 = (s2 << 16) + s1; if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) status = TINFL_STATUS_ADLER32_MISMATCH; + } + return status; +} + +// Higher level helper functions. +void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) +{ + tinfl_decompressor decomp; void *pBuf = NULL, *pNew_buf; size_t src_buf_ofs = 0, out_buf_capacity = 0; + *pOut_len = 0; + tinfl_init(&decomp); + for ( ; ; ) + { + size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity; + tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8*)pBuf, pBuf ? (mz_uint8*)pBuf + *pOut_len : NULL, &dst_buf_size, + (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); + if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) + { + MZ_FREE(pBuf); *pOut_len = 0; return NULL; + } + src_buf_ofs += src_buf_size; + *pOut_len += dst_buf_size; + if (status == TINFL_STATUS_DONE) break; + new_out_buf_capacity = out_buf_capacity * 2; if (new_out_buf_capacity < 128) new_out_buf_capacity = 128; + pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity); + if (!pNew_buf) + { + MZ_FREE(pBuf); *pOut_len = 0; return NULL; + } + pBuf = pNew_buf; out_buf_capacity = new_out_buf_capacity; + } + return pBuf; +} + +size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) +{ + tinfl_decompressor decomp; tinfl_status status; tinfl_init(&decomp); + status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf, &src_buf_len, (mz_uint8*)pOut_buf, (mz_uint8*)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); + return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len; +} + +int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) +{ + int result = 0; + tinfl_decompressor decomp; + mz_uint8 *pDict = (mz_uint8*)MZ_MALLOC(TINFL_LZ_DICT_SIZE); size_t in_buf_ofs = 0, dict_ofs = 0; + if (!pDict) + return TINFL_STATUS_FAILED; + tinfl_init(&decomp); + for ( ; ; ) + { + size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs; + tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size, + (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))); + in_buf_ofs += in_buf_size; + if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user))) + break; + if (status != TINFL_STATUS_HAS_MORE_OUTPUT) + { + result = (status == TINFL_STATUS_DONE); + break; + } + dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1); + } + MZ_FREE(pDict); + *pIn_buf_size = in_buf_ofs; + return result; +} + +#endif // #ifndef TINFL_HEADER_FILE_ONLY + +/* + This is free and unencumbered software released into the public domain. + + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this software, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + + In jurisdictions that recognize copyright laws, the author or authors + of this software dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + For more information, please refer to +*/ diff --git a/output/7z.dll b/output/7z.dll deleted file mode 100755 index f08706fef8..0000000000 Binary files a/output/7z.dll and /dev/null differ diff --git a/output/dll/7z.dll b/output/dll/7z.dll index f08706fef8..cea996e4f5 100644 Binary files a/output/dll/7z.dll and b/output/dll/7z.dll differ diff --git a/output/dll/Jabo_Direct3D8_patched.dll b/output/dll/Jabo_Direct3D8_patched.dll deleted file mode 100644 index 81e7ab64e0..0000000000 Binary files a/output/dll/Jabo_Direct3D8_patched.dll and /dev/null differ diff --git a/output/dll/LibretroBridge.dll b/output/dll/LibretroBridge.dll index 3e94b57a67..94c891c448 100644 Binary files a/output/dll/LibretroBridge.dll and b/output/dll/LibretroBridge.dll differ diff --git a/output/dll/SDL.dll b/output/dll/SDL.dll index 628cdfcf01..dee47e810f 100644 Binary files a/output/dll/SDL.dll and b/output/dll/SDL.dll differ diff --git a/output/dll/bizlynx.dll b/output/dll/bizlynx.dll index 7903f302ac..e62beb1d94 100644 Binary files a/output/dll/bizlynx.dll and b/output/dll/bizlynx.dll differ diff --git a/output/dll/bizswan.dll b/output/dll/bizswan.dll index ab5717249e..7c0542124a 100644 Binary files a/output/dll/bizswan.dll and b/output/dll/bizswan.dll differ diff --git a/output/dll/blip_buf.dll b/output/dll/blip_buf.dll index 28e3b355f2..769a2b59bf 100644 Binary files a/output/dll/blip_buf.dll and b/output/dll/blip_buf.dll differ diff --git a/output/dll/d3d8.dll b/output/dll/d3d8.dll deleted file mode 100644 index 92edd74472..0000000000 Binary files a/output/dll/d3d8.dll and /dev/null differ diff --git a/output/dll/ffmpeg.exe b/output/dll/ffmpeg.exe index e1bb9b742b..90e9fd74de 100644 Binary files a/output/dll/ffmpeg.exe and b/output/dll/ffmpeg.exe differ diff --git a/output/dll/freetype26.dll b/output/dll/freetype26.dll new file mode 100644 index 0000000000..2f6ede0fe2 Binary files /dev/null and b/output/dll/freetype26.dll differ diff --git a/output/dll/freetype6.dll b/output/dll/freetype6.dll deleted file mode 100644 index e35edc6bb0..0000000000 Binary files a/output/dll/freetype6.dll and /dev/null differ diff --git a/output/dll/gpgx.wbx.gz b/output/dll/gpgx.wbx.gz new file mode 100644 index 0000000000..3cff19446f Binary files /dev/null and b/output/dll/gpgx.wbx.gz differ diff --git a/output/dll/libbizsnes.dll b/output/dll/libbizsnes.dll deleted file mode 100644 index a32e7a07da..0000000000 Binary files a/output/dll/libbizsnes.dll and /dev/null differ diff --git a/output/dll/libc.so.gz b/output/dll/libc.so.gz new file mode 100644 index 0000000000..98c6a89836 Binary files /dev/null and b/output/dll/libc.so.gz differ diff --git a/output/dll/libco.so.gz b/output/dll/libco.so.gz new file mode 100644 index 0000000000..186f7471c6 Binary files /dev/null and b/output/dll/libco.so.gz differ diff --git a/output/dll/libco_msvc_win32.dll b/output/dll/libco_msvc_win32.dll deleted file mode 100644 index 7186aa94fe..0000000000 Binary files a/output/dll/libco_msvc_win32.dll and /dev/null differ diff --git a/output/dll/libdarm.dll b/output/dll/libdarm.dll deleted file mode 100644 index 9313414b41..0000000000 Binary files a/output/dll/libdarm.dll and /dev/null differ diff --git a/output/dll/libgambatte.dll b/output/dll/libgambatte.dll index cf461d3ed5..e10e63ff4f 100644 Binary files a/output/dll/libgambatte.dll and b/output/dll/libgambatte.dll differ diff --git a/output/dll/libgcc_s.so.gz b/output/dll/libgcc_s.so.gz new file mode 100644 index 0000000000..b5080b6353 Binary files /dev/null and b/output/dll/libgcc_s.so.gz differ diff --git a/output64/dll/libgcc_s_seh-1.dll b/output/dll/libgcc_s_seh-1.dll similarity index 100% rename from output64/dll/libgcc_s_seh-1.dll rename to output/dll/libgcc_s_seh-1.dll diff --git a/output/dll/libgenplusgx.dll b/output/dll/libgenplusgx.dll deleted file mode 100644 index 41ad039e12..0000000000 Binary files a/output/dll/libgenplusgx.dll and /dev/null differ diff --git a/output/dll/libpng12.dll b/output/dll/libpng12.dll deleted file mode 100644 index 25c0a7c8ee..0000000000 Binary files a/output/dll/libpng12.dll and /dev/null differ diff --git a/output/dll/libpng16.dll b/output/dll/libpng16.dll new file mode 100644 index 0000000000..24159dac76 Binary files /dev/null and b/output/dll/libpng16.dll differ diff --git a/output/dll/libquicknes.dll b/output/dll/libquicknes.dll index a961862827..3e35c8bc7c 100644 Binary files a/output/dll/libquicknes.dll and b/output/dll/libquicknes.dll differ diff --git a/output/dll/libsnes.wbx.gz b/output/dll/libsnes.wbx.gz new file mode 100644 index 0000000000..4877d7e2ed Binary files /dev/null and b/output/dll/libsnes.wbx.gz differ diff --git a/output/dll/libsneshawk-32-compatibility.dll b/output/dll/libsneshawk-32-compatibility.dll deleted file mode 100644 index 59493c3722..0000000000 Binary files a/output/dll/libsneshawk-32-compatibility.dll and /dev/null differ diff --git a/output/dll/libsneshawk-32-performance.dll b/output/dll/libsneshawk-32-performance.dll deleted file mode 100644 index b74645c983..0000000000 Binary files a/output/dll/libsneshawk-32-performance.dll and /dev/null differ diff --git a/output/dll/libspeexdsp.dll b/output/dll/libspeexdsp.dll index 1b5d0fd3cc..02ebc18351 100644 Binary files a/output/dll/libspeexdsp.dll and b/output/dll/libspeexdsp.dll differ diff --git a/output64/dll/libstdc++-6.dll b/output/dll/libstdc++-6.dll similarity index 100% rename from output64/dll/libstdc++-6.dll rename to output/dll/libstdc++-6.dll diff --git a/output/dll/libstdc++.so.6.gz b/output/dll/libstdc++.so.6.gz new file mode 100644 index 0000000000..d827ecc1b5 Binary files /dev/null and b/output/dll/libstdc++.so.6.gz differ diff --git a/output/dll/libvbanext.dll b/output/dll/libvbanext.dll index e7bbdf475b..3a860e5bb9 100644 Binary files a/output/dll/libvbanext.dll and b/output/dll/libvbanext.dll differ diff --git a/output64/dll/libwinpthread-1.dll b/output/dll/libwinpthread-1.dll similarity index 100% rename from output64/dll/libwinpthread-1.dll rename to output/dll/libwinpthread-1.dll diff --git a/output/dll/libyabause.dll b/output/dll/libyabause.dll deleted file mode 100644 index 0d87791963..0000000000 Binary files a/output/dll/libyabause.dll and /dev/null differ diff --git a/output/dll/mednadisc.dll b/output/dll/mednadisc.dll deleted file mode 100644 index 1360c8d5a1..0000000000 Binary files a/output/dll/mednadisc.dll and /dev/null differ diff --git a/output/dll/mgba.dll b/output/dll/mgba.dll index bb3dab4488..12a7522a86 100644 Binary files a/output/dll/mgba.dll and b/output/dll/mgba.dll differ diff --git a/output/dll/mupen64plus-audio-bkm.dll b/output/dll/mupen64plus-audio-bkm.dll index f239519c77..00d1cd6c13 100644 Binary files a/output/dll/mupen64plus-audio-bkm.dll and b/output/dll/mupen64plus-audio-bkm.dll differ diff --git a/output/dll/mupen64plus-input-bkm.dll b/output/dll/mupen64plus-input-bkm.dll index 3843c7378c..434c6d1a03 100644 Binary files a/output/dll/mupen64plus-input-bkm.dll and b/output/dll/mupen64plus-input-bkm.dll differ diff --git a/output/dll/mupen64plus-rsp-cxd4.dll b/output/dll/mupen64plus-rsp-cxd4.dll deleted file mode 100644 index 5517d8b4e4..0000000000 Binary files a/output/dll/mupen64plus-rsp-cxd4.dll and /dev/null differ diff --git a/output/dll/mupen64plus-rsp-hle.dll b/output/dll/mupen64plus-rsp-hle.dll index cb2f85ff4a..777026c971 100644 Binary files a/output/dll/mupen64plus-rsp-hle.dll and b/output/dll/mupen64plus-rsp-hle.dll differ diff --git a/output/dll/mupen64plus-rsp-z64-hlevideo.dll b/output/dll/mupen64plus-rsp-z64-hlevideo.dll deleted file mode 100644 index 3009047762..0000000000 Binary files a/output/dll/mupen64plus-rsp-z64-hlevideo.dll and /dev/null differ diff --git a/output/dll/mupen64plus-video-GLideN64.dll b/output/dll/mupen64plus-video-GLideN64.dll index c43f4f3d66..79746df3bc 100644 Binary files a/output/dll/mupen64plus-video-GLideN64.dll and b/output/dll/mupen64plus-video-GLideN64.dll differ diff --git a/output/dll/mupen64plus-video-glide64.dll b/output/dll/mupen64plus-video-glide64.dll index 2f768d095b..3ba5d4438a 100644 Binary files a/output/dll/mupen64plus-video-glide64.dll and b/output/dll/mupen64plus-video-glide64.dll differ diff --git a/output/dll/mupen64plus-video-glide64mk2.dll b/output/dll/mupen64plus-video-glide64mk2.dll index a8ce1755e2..da44f01514 100644 Binary files a/output/dll/mupen64plus-video-glide64mk2.dll and b/output/dll/mupen64plus-video-glide64mk2.dll differ diff --git a/output/dll/mupen64plus-video-jabo.dll b/output/dll/mupen64plus-video-jabo.dll deleted file mode 100644 index 88061eaf88..0000000000 Binary files a/output/dll/mupen64plus-video-jabo.dll and /dev/null differ diff --git a/output/dll/mupen64plus-video-rice.dll b/output/dll/mupen64plus-video-rice.dll index 372ee5a4c4..6db618f9f2 100644 Binary files a/output/dll/mupen64plus-video-rice.dll and b/output/dll/mupen64plus-video-rice.dll differ diff --git a/output/dll/mupen64plus.dll b/output/dll/mupen64plus.dll index 70e5c10877..6088630804 100644 Binary files a/output/dll/mupen64plus.dll and b/output/dll/mupen64plus.dll differ diff --git a/output/dll/ngp.wbx.gz b/output/dll/ngp.wbx.gz new file mode 100644 index 0000000000..9eabf028fa Binary files /dev/null and b/output/dll/ngp.wbx.gz differ diff --git a/output/dll/octoshock.dll b/output/dll/octoshock.dll index a283e0fef8..292d2536eb 100644 Binary files a/output/dll/octoshock.dll and b/output/dll/octoshock.dll differ diff --git a/output/dll/openal32.dll b/output/dll/openal32.dll deleted file mode 100644 index 71ced6a21f..0000000000 Binary files a/output/dll/openal32.dll and /dev/null differ diff --git a/output/dll/pizza.wbx.gz b/output/dll/pizza.wbx.gz new file mode 100644 index 0000000000..df14acf500 Binary files /dev/null and b/output/dll/pizza.wbx.gz differ diff --git a/output/dll/snes9x.wbx.gz b/output/dll/snes9x.wbx.gz new file mode 100644 index 0000000000..a6f6f9450e Binary files /dev/null and b/output/dll/snes9x.wbx.gz differ diff --git a/output/dll/ss.wbx.gz b/output/dll/ss.wbx.gz new file mode 100644 index 0000000000..6b6cf90539 Binary files /dev/null and b/output/dll/ss.wbx.gz differ diff --git a/output/dll/vb.wbx.gz b/output/dll/vb.wbx.gz new file mode 100644 index 0000000000..d76e6f7546 Binary files /dev/null and b/output/dll/vb.wbx.gz differ diff --git a/output/dll/zlib1.dll b/output/dll/zlib1.dll index 31996cd3e2..43fd4f6e35 100644 Binary files a/output/dll/zlib1.dll and b/output/dll/zlib1.dll differ diff --git a/output64/dll/7z.dll b/output64/dll/7z.dll deleted file mode 100644 index cea996e4f5..0000000000 Binary files a/output64/dll/7z.dll and /dev/null differ diff --git a/output64/dll/bizlynx.dll b/output64/dll/bizlynx.dll deleted file mode 100644 index e62beb1d94..0000000000 Binary files a/output64/dll/bizlynx.dll and /dev/null differ diff --git a/output64/dll/bizswan.dll b/output64/dll/bizswan.dll deleted file mode 100644 index 7c0542124a..0000000000 Binary files a/output64/dll/bizswan.dll and /dev/null differ diff --git a/output64/dll/blip_buf.dll b/output64/dll/blip_buf.dll deleted file mode 100644 index 769a2b59bf..0000000000 Binary files a/output64/dll/blip_buf.dll and /dev/null differ diff --git a/output64/dll/gpgx.elf b/output64/dll/gpgx.elf deleted file mode 100644 index ef0edb00f3..0000000000 Binary files a/output64/dll/gpgx.elf and /dev/null differ diff --git a/output64/dll/libgambatte.dll b/output64/dll/libgambatte.dll deleted file mode 100644 index 87284591fd..0000000000 Binary files a/output64/dll/libgambatte.dll and /dev/null differ diff --git a/output64/dll/libquicknes.dll b/output64/dll/libquicknes.dll deleted file mode 100644 index 3e35c8bc7c..0000000000 Binary files a/output64/dll/libquicknes.dll and /dev/null differ diff --git a/output64/dll/libspeexdsp.dll b/output64/dll/libspeexdsp.dll deleted file mode 100644 index 02ebc18351..0000000000 Binary files a/output64/dll/libspeexdsp.dll and /dev/null differ diff --git a/output64/dll/mgba.dll b/output64/dll/mgba.dll deleted file mode 100644 index 5c5bdbeb5d..0000000000 Binary files a/output64/dll/mgba.dll and /dev/null differ diff --git a/output64/dll/octoshock.dll b/output64/dll/octoshock.dll deleted file mode 100644 index 7c84af3882..0000000000 Binary files a/output64/dll/octoshock.dll and /dev/null differ diff --git a/psx/octoshock/bizhawk/octoshock.vcxproj b/psx/octoshock/bizhawk/octoshock.vcxproj index 006061d102..2d06105b9a 100644 --- a/psx/octoshock/bizhawk/octoshock.vcxproj +++ b/psx/octoshock/bizhawk/octoshock.vcxproj @@ -170,7 +170,7 @@ true - $(ProjectDir)\..\..\..\output64\dll\ + $(ProjectDir)\..\..\..\output\dll\ false @@ -179,7 +179,7 @@ false - $(ProjectDir)\..\..\..\output64\dll\ + $(ProjectDir)\..\..\..\output\dll\ diff --git a/quicknes/mingw/Makefile b/quicknes/mingw/Makefile index 97ea9797d0..109c71a97d 100644 --- a/quicknes/mingw/Makefile +++ b/quicknes/mingw/Makefile @@ -4,7 +4,7 @@ CP = cp MACHINE = $(shell $(CXX) -dumpmachine) ifneq (,$(findstring i686,$(MACHINE))) - ARCH = 32 + $(error 32 bit build no longer supported) else ifneq (,$(findstring x86_64,$(MACHINE))) ARCH = 64 else @@ -23,7 +23,7 @@ LDFLAGS_64 = LDFLAGS = -shared $(LDFLAGS_$(ARCH)) $(CXXFLAGS) DEST_32 = ../../output/dll -DEST_64 = ../../output64/dll +DEST_64 = ../../output/dll SRCS = \ ../nes_emu/abstract_file.cpp \ diff --git a/snes9xgit.txt b/snes9xgit.txt deleted file mode 100644 index 219235b3ff..0000000000 --- a/snes9xgit.txt +++ /dev/null @@ -1,8 +0,0 @@ -In order to have snes9x in the right place, clone the git repo: - -https://github.com/nattthebear/snes9x - -Into a path directly under the location of this file, called: - -snes9xgit/ - diff --git a/vbanext/mingw/Makefile b/vbanext/mingw/Makefile index 75c5f60d7d..e5556e477e 100644 --- a/vbanext/mingw/Makefile +++ b/vbanext/mingw/Makefile @@ -1,7 +1,22 @@ CXX = g++ -CXXFLAGS = -Wall -O3 -fpermissive -Wno-unused-but-set-variable -Wno-strict-aliasing -Wzero-as-null-pointer-constant -Wno-unused-variable -Wno-parentheses -Wno-sign-compare -std=gnu++11 -fomit-frame-pointer -fno-exceptions +CXXFLAGS = -Wall -O3 -fpermissive -Wno-unused-but-set-variable \ + -Wno-strict-aliasing -Wzero-as-null-pointer-constant -Wno-unused-variable \ + -Wno-parentheses -Wno-sign-compare -std=gnu++11 -fomit-frame-pointer -fno-exceptions + +MACHINE = $(shell $(CXX) -dumpmachine) +ifneq (,$(findstring i686,$(MACHINE))) + $(error 32 bit build no longer supported) +else ifneq (,$(findstring x86_64,$(MACHINE))) + ARCH = 64 +else + $(error Unknown arch) +endif + +LDFLAGS_32 = -static-libgcc -static-libstdc++ +LDFLAGS_64 = +LDFLAGS = -shared $(LDFLAGS_$(ARCH)) $(CXXFLAGS) + TARGET = libvbanext.dll -LDFLAGS = -shared -static-libgcc -static-libstdc++ $(CXXFLAGS) RM = rm CP = cp @@ -10,6 +25,8 @@ SRCS = \ ../newstate.cpp OBJS = $(SRCS:.cpp=.o) +DEST_32 = ../../output/dll +DEST_64 = ../../output/dll all: $(TARGET) @@ -24,4 +41,4 @@ clean: $(RM) $(TARGET) install: - $(CP) $(TARGET) ../../output/dll + $(CP) $(TARGET) $(DEST_$(ARCH)) diff --git a/waterbox/emulibc/Makefile b/waterbox/emulibc/Makefile new file mode 100644 index 0000000000..b8196ffcb7 --- /dev/null +++ b/waterbox/emulibc/Makefile @@ -0,0 +1,32 @@ +CC = x86_64-nt64-midipix-gcc + +CCFLAGS:= -Wall -O2# -mcmodel=large + +TARGET = libemuhost.so + +LDFLAGS = -shared + +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) : $(OBJS) + @$(CC) -o $@ $(LDFLAGS) $(CCFLAGS) $(OBJS) + +clean: + rm -rf $(OBJ_DIR) + rm -f $(TARGET) + +#install: +# $(CP) $(TARGET) $(DEST_$(ARCH)) diff --git a/waterbox/emulibc/emulibc.c b/waterbox/emulibc/emulibc.c new file mode 100644 index 0000000000..8a55a78438 --- /dev/null +++ b/waterbox/emulibc/emulibc.c @@ -0,0 +1,7 @@ +#include "emulibc.h" + +// this is just used to build a dummy .so file that isn't used +void *alloc_sealed(size_t size) { return NULL; } +void *alloc_invisible(size_t size) { return NULL; } +void *alloc_plain(size_t size) { return NULL; } +void _debug_puts(const char *s) { } diff --git a/waterbox/libc/includes/emulibc.h b/waterbox/emulibc/emulibc.h similarity index 73% rename from waterbox/libc/includes/emulibc.h rename to waterbox/emulibc/emulibc.h index 608dbea2c3..90e705a5d5 100644 --- a/waterbox/libc/includes/emulibc.h +++ b/waterbox/emulibc/emulibc.h @@ -3,8 +3,12 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + // mark an entry point or callback pointer -#define ECL_ENTRY __attribute__((ms_abi)) +#define ECL_ENTRY // mark a visible symbol #define ECL_EXPORT __attribute__((visibility("default"))) @@ -19,7 +23,16 @@ void *alloc_sealed(size_t size); // you are absolutely sure will not harm savestates void *alloc_invisible(size_t size); +// allocate memory from the "plain" pool. this memory can never be freed. +// this memory is savestated normally. +// useful to avoid malloc() overhead for things that will never be freed +void *alloc_plain(size_t size); + // send a debug string somewhere, bypassing stdio void _debug_puts(const char *); +#ifdef __cplusplus +} +#endif + #endif diff --git a/waterbox/emulibc/libemuhost.so b/waterbox/emulibc/libemuhost.so new file mode 100644 index 0000000000..ba581bfe47 Binary files /dev/null and b/waterbox/emulibc/libemuhost.so differ diff --git a/waterbox/emulibc/waterboxcore.h b/waterbox/emulibc/waterboxcore.h new file mode 100644 index 0000000000..8ac891d120 --- /dev/null +++ b/waterbox/emulibc/waterboxcore.h @@ -0,0 +1,40 @@ +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + uint32_t* VideoBuffer; + int16_t* SoundBuffer; + int64_t Cycles; + int32_t Width; + int32_t Height; + int32_t Samples; + int32_t Lagged; +} FrameInfo; + +typedef struct +{ + void* Data; + const char* Name; + int64_t Size; + int32_t Flags; +} MemoryArea; + +#define MEMORYAREA_FLAGS_WRITABLE 1 +#define MEMORYAREA_FLAGS_SAVERAMMABLE 2 +#define MEMORYAREA_FLAGS_ONEFILLED 4 +#define MEMORYAREA_FLAGS_PRIMARY 8 +#define MEMORYAREA_FLAGS_YUGEENDIAN 16 +#define MEMORYAREA_FLAGS_WORDSIZE1 32 +#define MEMORYAREA_FLAGS_WORDSIZE2 64 +#define MEMORYAREA_FLAGS_WORDSIZE4 128 +#define MEMORYAREA_FLAGS_WORDSIZE8 256 +#define MEMORYAREA_FLAGS_SWAPPED 512 + +#ifdef __cplusplus +} +#endif diff --git a/waterbox/gpgx/Makefile b/waterbox/gpgx/Makefile index 967eceed66..ba9cad8d00 100644 --- a/waterbox/gpgx/Makefile +++ b/waterbox/gpgx/Makefile @@ -1,32 +1,16 @@ -CC = gcc - -ARCH = 64 -#MACHINE = $(shell $(CC) -dumpmachine) -#ifneq (,$(findstring i686,$(MACHINE))) -# ARCH = 32 -#else ifneq (,$(findstring x86_64,$(MACHINE))) -# ARCH = 64 -#else -# $(error Unknown arch) -#endif +CC = x86_64-nt64-midipix-gcc CCFLAGS:=-Icore -Iutil -Icore/m68k -Icore/z80 -Icore/input_hw \ -Icore/cart_hw -Icore/cart_hw/svp -Icore/sound -Icore/ntsc -Icore/cd_hw \ + -I../emulibc \ -Wall -Werror=pointer-to-int-cast -Werror=int-to-pointer-cast -Werror=implicit-function-declaration \ -std=c99 -fomit-frame-pointer -fvisibility=hidden \ -DLSB_FIRST -DUSE_32BPP_RENDERING -DINLINE=static\ __inline__ \ - -ffreestanding -nostdinc -nostdlib \ - -I../libc/includes -I../libc/internals \ - -mcmodel=large -O2 + -O3 -flto -TARGET = gpgx.elf +TARGET = gpgx.wbx -LDFLAGS_32 = -LDFLAGS_64 = -static -LDFLAGS = $(LDFLAGS_$(ARCH)) $(CCFLAGS) - -#DEST_32 = ../../../../../output/dll -#DEST_64 = ../../../../../output64/dll +LDFLAGS = -Wl,--dynamicbase,--export-all-symbols ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.c') @@ -43,11 +27,15 @@ all: $(TARGET) .PHONY: clean all -$(TARGET) : $(OBJS) lscript - @$(CC) -o $@ $(LDFLAGS) -T lscript $(CCFLAGS) $(OBJS) ../libc/emulibc.a +$(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 clean: rm -rf $(OBJ_DIR) + rm -f $(TARGET).in rm -f $(TARGET) #install: diff --git a/waterbox/gpgx/cinterface/cinterface.c b/waterbox/gpgx/cinterface/cinterface.c index a1b4106915..b3456d2237 100644 --- a/waterbox/gpgx/cinterface/cinterface.c +++ b/waterbox/gpgx/cinterface/cinterface.c @@ -1,715 +1,723 @@ -#include -#include -#include -#include -#include "callbacks.h" - -#ifdef _MSC_VER -#define snprintf _snprintf -#endif - -#include "shared.h" -#include "genesis.h" -#include "md_ntsc.h" -#include "sms_ntsc.h" -#include "eeprom_i2c.h" -#include "vdp_render.h" - -char GG_ROM[256] = "GG_ROM"; // game genie rom -char AR_ROM[256] = "AR_ROM"; // actin replay rom -char SK_ROM[256] = "SK_ROM"; // sanic and knuckles -char SK_UPMEM[256] = "SK_UPMEM"; // sanic and knuckles -char GG_BIOS[256] = "GG_BIOS"; // game gear bootrom -char CD_BIOS_EU[256] = "CD_BIOS_EU"; // cd bioses -char CD_BIOS_US[256] = "CD_BIOS_US"; -char CD_BIOS_JP[256] = "CD_BIOS_JP"; -char MS_BIOS_US[256] = "MS_BIOS_US"; // master system bioses -char MS_BIOS_EU[256] = "MS_BIOS_EU"; -char MS_BIOS_JP[256] = "MS_BIOS_JP"; - -char romextension[4]; - -static int16 soundbuffer[4096]; -static int nsamples; - -int cinterface_render_bga = 1; -int cinterface_render_bgb = 1; -int cinterface_render_bgw = 1; -int cinterface_render_obj = 1; -uint8 cinterface_custom_backdrop = 0; -uint32 cinterface_custom_backdrop_color = 0xffff00ff; // pink -extern uint8 border; - -#ifdef _MSC_VER -#define GPGX_EX __declspec(dllexport) -#else -#define GPGX_EX __attribute__((visibility("default"))) ECL_ENTRY -#endif - -static int vwidth; -static int vheight; - -static uint8_t brm_format[0x40] = -{ - 0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x00,0x00,0x00,0x00,0x40, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x53,0x45,0x47,0x41,0x5f,0x43,0x44,0x5f,0x52,0x4f,0x4d,0x00,0x01,0x00,0x00,0x00, - 0x52,0x41,0x4d,0x5f,0x43,0x41,0x52,0x54,0x52,0x49,0x44,0x47,0x45,0x5f,0x5f,0x5f -}; - -ECL_ENTRY void (*biz_execcb)(unsigned addr); -ECL_ENTRY void (*biz_readcb)(unsigned addr); -ECL_ENTRY void (*biz_writecb)(unsigned addr); -CDCallback biz_cdcallback = NULL; -unsigned biz_lastpc = 0; -ECL_ENTRY void (*cdd_readcallback)(int lba, void *dest, int audio); -uint8 *tempsram; - -static void update_viewport(void) -{ - vwidth = bitmap.viewport.w + (bitmap.viewport.x * 2); - vheight = bitmap.viewport.h + (bitmap.viewport.y * 2); - - if (config.ntsc) - { - if (reg[12] & 1) - vwidth = MD_NTSC_OUT_WIDTH(vwidth); - else - vwidth = SMS_NTSC_OUT_WIDTH(vwidth); - } - - if (config.render && interlaced) - { - vheight = vheight * 2; - } -} - -GPGX_EX void gpgx_get_video(int *w, int *h, int *pitch, void **buffer) -{ - if (w) - *w = vwidth; - if (h) - *h = vheight; - if (pitch) - *pitch = bitmap.pitch; - if (buffer) - *buffer = bitmap.data; -} - -GPGX_EX void gpgx_get_audio(int *n, void **buffer) -{ - if (n) - *n = nsamples; - if (buffer) - *buffer = soundbuffer; -} - -// this is most certainly wrong for interlacing -GPGX_EX void gpgx_get_fps(int *num, int *den) -{ - if (vdp_pal) - { - if (num) - *num = 53203424; - if (den) - *den = 3420 * 313; - } - else - { - if (num) - *num = 53693175; - if (den) - *den = 3420 * 262; - } -} - -void osd_input_update(void) -{ -} - -ECL_ENTRY void (*input_callback_cb)(void); - -void real_input_callback(void) -{ - if (input_callback_cb) - input_callback_cb(); -} - -GPGX_EX void gpgx_set_input_callback(ECL_ENTRY void (*fecb)(void)) -{ - input_callback_cb = fecb; -} - -GPGX_EX void gpgx_set_cdd_callback(ECL_ENTRY void (*cddcb)(int lba, void *dest, int audio)) -{ - cdd_readcallback = cddcb; -} - -ECL_ENTRY int (*load_archive_cb)(const char *filename, unsigned char *buffer, int maxsize); - -// return 0 on failure, else actual loaded size -// extension, if not null, should be populated with the extension of the file loaded -// (up to 3 chars and null terminator, no more) -int load_archive(const char *filename, unsigned char *buffer, int maxsize, char *extension) -{ - if (extension) - memcpy(extension, romextension, 4); - - return load_archive_cb(filename, buffer, maxsize); -} - -GPGX_EX int gpgx_get_control(t_input *dest, int bytes) -{ - if (bytes != sizeof(t_input)) - return 0; - memcpy(dest, &input, sizeof(t_input)); - return 1; -} - -GPGX_EX int gpgx_put_control(t_input *src, int bytes) -{ - if (bytes != sizeof(t_input)) - return 0; - memcpy(&input, src, sizeof(t_input)); - return 1; -} - -GPGX_EX void gpgx_advance(void) -{ - if (system_hw == SYSTEM_MCD) - system_frame_scd(0); - else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) - system_frame_gen(0); - else - system_frame_sms(0); - - if (bitmap.viewport.changed & 1) - { - bitmap.viewport.changed &= ~1; - update_viewport(); - } - - nsamples = audio_update(soundbuffer); -} - -typedef struct -{ - uint32 width; // in cells - uint32 height; - uint32 baseaddr; -} nametable_t; - -typedef struct -{ - uint8 *vram; // 64K vram - uint8 *patterncache; // every pattern, first normal, then hflip, vflip, bothflip - uint32 *colorcache; // 64 colors - nametable_t nta; - nametable_t ntb; - nametable_t ntw; -} vdpview_t; - - -extern uint8 *bg_pattern_cache; -extern uint32 pixel[]; - -GPGX_EX void gpgx_get_vdp_view(vdpview_t *view) -{ - view->vram = vram; - view->patterncache = bg_pattern_cache; - view->colorcache = pixel + 0x40; - view->nta.width = 1 << (playfield_shift - 1); - view->ntb.width = 1 << (playfield_shift - 1); - view->nta.height = (playfield_row_mask + 1) >> 3; - view->ntb.height = (playfield_row_mask + 1) >> 3; - view->ntw.width = 1 << (5 + (reg[12] & 1)); - view->ntw.height = 32; - view->nta.baseaddr = ntab; - view->ntb.baseaddr = ntbb; - view->ntw.baseaddr = ntwb; -} - -// internal: computes sram size (no brams) -int saveramsize(void) -{ - return sram_get_actual_size(); -} - -GPGX_EX void gpgx_clear_sram(void) -{ - // clear sram - if (sram.on) - memset(sram.sram, 0xff, 0x10000); - - if (cdd.loaded) - { - // clear and format bram - memset(scd.bram, 0, 0x2000); - brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = 0x00; - brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (0x2000 / 64) - 3; - memcpy(scd.bram + 0x2000 - 0x40, brm_format, 0x40); - - if (scd.cartridge.id) - { - // clear and format ebram - memset(scd.cartridge.area, 0x00, scd.cartridge.mask + 1); - brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = (((scd.cartridge.mask + 1) / 64) - 3) >> 8; - brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (((scd.cartridge.mask + 1) / 64) - 3) & 0xff; - memcpy(scd.cartridge.area + scd.cartridge.mask + 1 - 0x40, brm_format, 0x40); - } - } -} - -// a bit hacky: -// in order to present a single memory block to the frontend, -// we copy the both the bram and the ebram to another area - -GPGX_EX void* gpgx_get_sram(int *size) -{ - if (sram.on) - { - *size = saveramsize(); - return sram.sram; - } - else if (cdd.loaded && scd.cartridge.id) - { - int sz = scd.cartridge.mask + 1; - memcpy(tempsram, scd.cartridge.area, sz); - memcpy(tempsram + sz, scd.bram, 0x2000); - *size = sz + 0x2000; - return tempsram; - } - else if (cdd.loaded) - { - *size = 0x2000; - return scd.bram; - } - else if (scd.cartridge.id) - { - *size = scd.cartridge.mask + 1; - return scd.cartridge.area; - } - else - { - *size = 0; - return NULL; - } -} - -GPGX_EX int gpgx_put_sram(const uint8 *data, int size) -{ - if (sram.on) - { - if (size != saveramsize()) - return 0; - memcpy(sram.sram, data, size); - return 1; - } - else if (cdd.loaded && scd.cartridge.id) - { - int sz = scd.cartridge.mask + 1; - if (size != sz + 0x2000) - return 0; - memcpy(scd.cartridge.area, data, sz); - memcpy(scd.bram, data + sz, 0x2000); - return 1; - } - else if (cdd.loaded) - { - if (size != 0x2000) - return 0; - memcpy(scd.bram, data, size); - return 1; - } - else if (scd.cartridge.id) - { - int sz = scd.cartridge.mask + 1; - if (size != sz) - return 0; - memcpy(scd.cartridge.area, data, size); - return 1; - } - else - { - if (size != 0) - return 0; - return 1; // "successful"? - } -} - -GPGX_EX void gpgx_poke_vram(int addr, uint8 val) -{ - write_vram_byte(addr, val); -} - -GPGX_EX void gpgx_flush_vram(void) -{ - flush_vram_cache(); -} - -GPGX_EX const char* gpgx_get_memdom(int which, void **area, int *size) -{ - if (!area || !size) - return NULL; - switch (which) - { - case 0: - *area = work_ram; - *size = 0x10000; - return "68K RAM"; - case 1: - *area = zram; - *size = 0x2000; - return "Z80 RAM"; - case 2: - if (!cdd.loaded) - { - *area = ext.md_cart.rom; - *size = ext.md_cart.romsize; - return "MD CART"; - } - else if (scd.cartridge.id) - { - *area = scd.cartridge.area; - *size = scd.cartridge.mask + 1; - return "EBRAM"; - } - else return NULL; - case 3: - if (cdd.loaded) - { - *area = scd.bootrom; - *size = 0x20000; - return "CD BOOT ROM"; - } - else return NULL; - case 4: - if (cdd.loaded) - { - *area = scd.prg_ram; - *size = 0x80000; - return "CD PRG RAM"; - } - else return NULL; - case 5: - if (cdd.loaded) - { - *area = scd.word_ram[0]; - *size = 0x20000; - return "CD WORD RAM[0] (1M)"; - } - else return NULL; - case 6: - if (cdd.loaded) - { - *area = scd.word_ram[1]; - *size = 0x20000; - return "CD WORD RAM[1] (1M)"; - } - else return NULL; - case 7: - if (cdd.loaded) - { - *area = scd.word_ram_2M; - *size = 0x40000; - return "CD WORD RAM (2M)"; - } - else return NULL; - case 8: - if (cdd.loaded) - { - *area = scd.bram; - *size = 0x2000; - return "CD BRAM"; - } - else return NULL; - case 9: - *area = boot_rom; - *size = 0x800; - return "BOOT ROM"; - default: - return NULL; - case 10: - if (sram.on) - { - *area = sram.sram; - *size = saveramsize(); - return "SRAM"; - } - else return NULL; - case 11: - *area = cram; - *size = 128; - return "CRAM"; - case 12: - *area = vsram; - *size = 128; - return "VSRAM"; - case 13: - *area = vram; - *size = 65536; - return "VRAM"; - } -} - -GPGX_EX void gpgx_write_m68k_bus(unsigned addr, unsigned data) -{ - unsigned char *base = m68k.memory_map[addr >> 16 & 0xff].base; - if (base) - base[addr & 0xffff ^ 1] = data; -} - -GPGX_EX void gpgx_write_s68k_bus(unsigned addr, unsigned data) -{ - unsigned char *base = s68k.memory_map[addr >> 16 & 0xff].base; - if (base) - base[addr & 0xffff ^ 1] = data; -} -GPGX_EX unsigned gpgx_peek_m68k_bus(unsigned addr) -{ - unsigned char *base = m68k.memory_map[addr >> 16 & 0xff].base; - if (base) - return base[addr & 0xffff ^ 1]; - else - return 0xff; -} -GPGX_EX unsigned gpgx_peek_s68k_bus(unsigned addr) -{ - unsigned char *base = s68k.memory_map[addr >> 16 & 0xff].base; - if (base) - return base[addr & 0xffff ^ 1]; - else - return 0xff; -} - -struct InitSettings -{ - uint8_t Filter; - uint16_t LowPassRange; - int16_t LowFreq; - int16_t HighFreq; - int16_t LowGain; - int16_t MidGain; - int16_t HighGain; - uint32_t BackdropColor; -}; - -GPGX_EX int gpgx_init(const char *feromextension, ECL_ENTRY int (*feload_archive_cb)(const char *filename, unsigned char *buffer, int maxsize), int sixbutton, char system_a, char system_b, int region, struct InitSettings *settings) -{ - _debug_puts("Initializing GPGX native..."); - memset(&bitmap, 0, sizeof(bitmap)); - - strncpy(romextension, feromextension, 3); - romextension[3] = 0; - - load_archive_cb = feload_archive_cb; - - bitmap.width = 1024; - bitmap.height = 512; - bitmap.pitch = 1024 * 4; - bitmap.data = alloc_invisible(2 * 1024 * 1024); - tempsram = alloc_invisible(24 * 1024); - bg_pattern_cache = alloc_invisible(0x80000); - - ext.md_cart.rom = alloc_sealed(32 * 1024 * 1024); - SZHVC_add = alloc_sealed(131072); - SZHVC_sub = alloc_sealed(131072); - ym2612_lfo_pm_table = alloc_sealed(131072); - vdp_bp_lut = alloc_sealed(262144); - vdp_lut = alloc_sealed(6 * sizeof(*vdp_lut)); - for (int i = 0; i < 6; i++) - vdp_lut[i] = alloc_sealed(65536); - - /* sound options */ - config.psg_preamp = 150; - config.fm_preamp= 100; - config.hq_fm = 1; /* high-quality resampling */ - config.psgBoostNoise = 1; - config.filter = settings->Filter; //0; /* no filter */ - config.lp_range = settings->LowPassRange; //0x9999; /* 0.6 in 16.16 fixed point */ - config.low_freq = settings->LowFreq; //880; - config.high_freq = settings->HighFreq; //5000; - config.lg = settings->LowGain; //1.0; - config.mg = settings->MidGain; //1.0; - config.hg = settings->HighGain; //1.0; - config.dac_bits = 14; /* MAX DEPTH */ - config.ym2413= 2; /* AUTO */ - config.mono = 0; /* STEREO output */ - - /* system options */ - config.system = 0; /* AUTO */ - config.region_detect = region; // see loadrom.c - config.vdp_mode = 0; /* AUTO */ - config.master_clock = 0; /* AUTO */ - config.force_dtack = 0; - config.addr_error = 1; - config.bios = 0; - config.lock_on = 0; - - /* video options */ - config.overscan = 0; - config.gg_extra = 0; - config.ntsc = 0; - config.render = 0; - - // set overall input system type - // usual is MD GAMEPAD or NONE - // TEAMPLAYER, WAYPLAY, ACTIVATOR, XEA1P, MOUSE need to be specified - // everything else is auto or master system only - // XEA1P is port 1 only - // WAYPLAY is both ports at same time only - input.system[0] = system_a; - input.system[1] = system_b; - - cinterface_custom_backdrop_color = settings->BackdropColor; - - // apparently, the only part of config.input used is the padtype identifier, - // and that's used only for choosing pad type when system_md - { - int i; - for (i = 0; i < MAX_INPUTS; i++) - config.input[i].padtype = sixbutton ? DEVICE_PAD6B : DEVICE_PAD3B; - } - - if (!load_rom("PRIMARY_ROM")) - return 0; - - audio_init(44100, 0); - system_init(); - system_reset(); - - update_viewport(); - gpgx_clear_sram(); - - return 1; -} - -GPGX_EX void gpgx_reset(int hard) -{ - if (hard) - system_reset(); - else - gen_reset(0); -} - -GPGX_EX void gpgx_set_mem_callback(ECL_ENTRY void (*read)(unsigned), ECL_ENTRY void (*write)(unsigned), ECL_ENTRY void (*exec)(unsigned)) -{ - biz_readcb = read; - biz_writecb = write; - biz_execcb = exec; -} - -GPGX_EX void gpgx_set_cd_callback(CDCallback cdcallback) -{ - biz_cdcallback = cdcallback; -} - -GPGX_EX void gpgx_set_draw_mask(int mask) -{ - cinterface_render_bga = !!(mask & 1); - cinterface_render_bgb = !!(mask & 2); - cinterface_render_bgw = !!(mask & 4); - cinterface_render_obj = !!(mask & 8); - cinterface_custom_backdrop = !!(mask & 16); - if (cinterface_custom_backdrop) - color_update_m5(0, 0); - else - color_update_m5(0x00, *(uint16 *)&cram[border << 1]); -} - -GPGX_EX void gpgx_invalidate_pattern_cache(void) -{ - vdp_invalidate_full_cache(); -} - -typedef struct -{ - unsigned int value; - const char *name; -} gpregister_t; - -GPGX_EX int gpgx_getmaxnumregs(void) -{ - return 57; -} - -GPGX_EX int gpgx_getregs(gpregister_t *regs) -{ - int ret = 0; - - // 22 -#define MAKEREG(x) regs->name = "M68K " #x; regs->value = m68k_get_reg(M68K_REG_##x); regs++; ret++; - MAKEREG(D0); - MAKEREG(D1); - MAKEREG(D2); - MAKEREG(D3); - MAKEREG(D4); - MAKEREG(D5); - MAKEREG(D6); - MAKEREG(D7); - MAKEREG(A0); - MAKEREG(A1); - MAKEREG(A2); - MAKEREG(A3); - MAKEREG(A4); - MAKEREG(A5); - MAKEREG(A6); - MAKEREG(A7); - MAKEREG(PC); - MAKEREG(SR); - MAKEREG(SP); - MAKEREG(USP); - MAKEREG(ISP); - MAKEREG(IR); -#undef MAKEREG - - (regs-6)->value = biz_lastpc; // during read/write callbacks, PC runs away due to prefetch. restore it. - - // 13 -#define MAKEREG(x) regs->name = "Z80 " #x; regs->value = Z80.x.d; regs++; ret++; - MAKEREG(pc); - MAKEREG(sp); - MAKEREG(af); - MAKEREG(bc); - MAKEREG(de); - MAKEREG(hl); - MAKEREG(ix); - MAKEREG(iy); - MAKEREG(wz); - MAKEREG(af2); - MAKEREG(bc2); - MAKEREG(de2); - MAKEREG(hl2); -#undef MAKEREG - - // 22 - if (system_hw == SYSTEM_MCD) - { -#define MAKEREG(x) regs->name = "S68K " #x; regs->value = s68k_get_reg(M68K_REG_##x); regs++; ret++; - MAKEREG(D0); - MAKEREG(D1); - MAKEREG(D2); - MAKEREG(D3); - MAKEREG(D4); - MAKEREG(D5); - MAKEREG(D6); - MAKEREG(D7); - MAKEREG(A0); - MAKEREG(A1); - MAKEREG(A2); - MAKEREG(A3); - MAKEREG(A4); - MAKEREG(A5); - MAKEREG(A6); - MAKEREG(A7); - MAKEREG(PC); - MAKEREG(SR); - MAKEREG(SP); - MAKEREG(USP); - MAKEREG(ISP); - MAKEREG(IR); -#undef MAKEREG - } - - return ret; -} +#include +#include +#include +#include +#include "callbacks.h" + +#ifdef _MSC_VER +#define snprintf _snprintf +#endif + +#include "shared.h" +#include "genesis.h" +#include "md_ntsc.h" +#include "sms_ntsc.h" +#include "eeprom_i2c.h" +#include "vdp_render.h" + +char GG_ROM[256] = "GG_ROM"; // game genie rom +char AR_ROM[256] = "AR_ROM"; // actin replay rom +char SK_ROM[256] = "SK_ROM"; // sanic and knuckles +char SK_UPMEM[256] = "SK_UPMEM"; // sanic and knuckles +char GG_BIOS[256] = "GG_BIOS"; // game gear bootrom +char CD_BIOS_EU[256] = "CD_BIOS_EU"; // cd bioses +char CD_BIOS_US[256] = "CD_BIOS_US"; +char CD_BIOS_JP[256] = "CD_BIOS_JP"; +char MS_BIOS_US[256] = "MS_BIOS_US"; // master system bioses +char MS_BIOS_EU[256] = "MS_BIOS_EU"; +char MS_BIOS_JP[256] = "MS_BIOS_JP"; + +char romextension[4]; + +static int16 soundbuffer[4096]; +static int nsamples; + +int cinterface_render_bga = 1; +int cinterface_render_bgb = 1; +int cinterface_render_bgw = 1; +int cinterface_render_obj = 1; +uint8 cinterface_custom_backdrop = 0; +uint32 cinterface_custom_backdrop_color = 0xffff00ff; // pink +extern uint8 border; + +#ifdef _MSC_VER +#define GPGX_EX __declspec(dllexport) +#else +#define GPGX_EX __attribute__((visibility("default"))) ECL_ENTRY +#endif + +static int vwidth; +static int vheight; + +static uint8_t brm_format[0x40] = +{ + 0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x00,0x00,0x00,0x00,0x40, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x53,0x45,0x47,0x41,0x5f,0x43,0x44,0x5f,0x52,0x4f,0x4d,0x00,0x01,0x00,0x00,0x00, + 0x52,0x41,0x4d,0x5f,0x43,0x41,0x52,0x54,0x52,0x49,0x44,0x47,0x45,0x5f,0x5f,0x5f +}; + +ECL_ENTRY void (*biz_execcb)(unsigned addr); +ECL_ENTRY void (*biz_readcb)(unsigned addr); +ECL_ENTRY void (*biz_writecb)(unsigned addr); +CDCallback biz_cdcallback = NULL; +unsigned biz_lastpc = 0; +ECL_ENTRY void (*cdd_readcallback)(int lba, void *dest, int audio); +uint8 *tempsram; + +static void update_viewport(void) +{ + vwidth = bitmap.viewport.w + (bitmap.viewport.x * 2); + vheight = bitmap.viewport.h + (bitmap.viewport.y * 2); + + if (config.ntsc) + { + if (reg[12] & 1) + vwidth = MD_NTSC_OUT_WIDTH(vwidth); + else + vwidth = SMS_NTSC_OUT_WIDTH(vwidth); + } + + if (config.render && interlaced) + { + vheight = vheight * 2; + } +} + +GPGX_EX void gpgx_get_video(int *w, int *h, int *pitch, void **buffer) +{ + if (w) + *w = vwidth; + if (h) + *h = vheight; + if (pitch) + *pitch = bitmap.pitch; + if (buffer) + *buffer = bitmap.data; +} + +GPGX_EX void gpgx_get_audio(int *n, void **buffer) +{ + if (n) + *n = nsamples; + if (buffer) + *buffer = soundbuffer; +} + +// this is most certainly wrong for interlacing +GPGX_EX void gpgx_get_fps(int *num, int *den) +{ + if (vdp_pal) + { + if (num) + *num = 53203424; + if (den) + *den = 3420 * 313; + } + else + { + if (num) + *num = 53693175; + if (den) + *den = 3420 * 262; + } +} + +void osd_input_update(void) +{ +} + +ECL_ENTRY void (*input_callback_cb)(void); + +void real_input_callback(void) +{ + if (input_callback_cb) + input_callback_cb(); +} + +GPGX_EX void gpgx_set_input_callback(ECL_ENTRY void (*fecb)(void)) +{ + input_callback_cb = fecb; +} + +GPGX_EX void gpgx_set_cdd_callback(ECL_ENTRY void (*cddcb)(int lba, void *dest, int audio)) +{ + cdd_readcallback = cddcb; +} + +ECL_ENTRY int (*load_archive_cb)(const char *filename, unsigned char *buffer, int maxsize); + +// return 0 on failure, else actual loaded size +// extension, if not null, should be populated with the extension of the file loaded +// (up to 3 chars and null terminator, no more) +int load_archive(const char *filename, unsigned char *buffer, int maxsize, char *extension) +{ + if (extension) + memcpy(extension, romextension, 4); + + return load_archive_cb(filename, buffer, maxsize); +} + +GPGX_EX int gpgx_get_control(t_input *dest, int bytes) +{ + if (bytes != sizeof(t_input)) + return 0; + memcpy(dest, &input, sizeof(t_input)); + return 1; +} + +GPGX_EX int gpgx_put_control(t_input *src, int bytes) +{ + if (bytes != sizeof(t_input)) + return 0; + memcpy(&input, src, sizeof(t_input)); + return 1; +} + +GPGX_EX void gpgx_advance(void) +{ + if (system_hw == SYSTEM_MCD) + system_frame_scd(0); + else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) + system_frame_gen(0); + else + system_frame_sms(0); + + if (bitmap.viewport.changed & 1) + { + bitmap.viewport.changed &= ~1; + update_viewport(); + } + + nsamples = audio_update(soundbuffer); +} + +typedef struct +{ + uint32 width; // in cells + uint32 height; + uint32 baseaddr; +} nametable_t; + +typedef struct +{ + uint8 *vram; // 64K vram + uint8 *patterncache; // every pattern, first normal, then hflip, vflip, bothflip + uint32 *colorcache; // 64 colors + nametable_t nta; + nametable_t ntb; + nametable_t ntw; +} vdpview_t; + + +extern uint8 *bg_pattern_cache; +extern uint32 pixel[]; + +GPGX_EX void gpgx_get_vdp_view(vdpview_t *view) +{ + view->vram = vram; + view->patterncache = bg_pattern_cache; + view->colorcache = pixel + 0x40; + view->nta.width = 1 << (playfield_shift - 1); + view->ntb.width = 1 << (playfield_shift - 1); + view->nta.height = (playfield_row_mask + 1) >> 3; + view->ntb.height = (playfield_row_mask + 1) >> 3; + view->ntw.width = 1 << (5 + (reg[12] & 1)); + view->ntw.height = 32; + view->nta.baseaddr = ntab; + view->ntb.baseaddr = ntbb; + view->ntw.baseaddr = ntwb; +} + +// internal: computes sram size (no brams) +int saveramsize(void) +{ + return sram_get_actual_size(); +} + +GPGX_EX void gpgx_clear_sram(void) +{ + // clear sram + if (sram.on) + memset(sram.sram, 0xff, 0x10000); + + if (cdd.loaded) + { + // clear and format bram + memset(scd.bram, 0, 0x2000); + brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = 0x00; + brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (0x2000 / 64) - 3; + memcpy(scd.bram + 0x2000 - 0x40, brm_format, 0x40); + + if (scd.cartridge.id) + { + // clear and format ebram + memset(scd.cartridge.area, 0x00, scd.cartridge.mask + 1); + brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = (((scd.cartridge.mask + 1) / 64) - 3) >> 8; + brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (((scd.cartridge.mask + 1) / 64) - 3) & 0xff; + memcpy(scd.cartridge.area + scd.cartridge.mask + 1 - 0x40, brm_format, 0x40); + } + } +} + +// a bit hacky: +// in order to present a single memory block to the frontend, +// we copy the both the bram and the ebram to another area + +GPGX_EX void* gpgx_get_sram(int *size) +{ + if (sram.on) + { + *size = saveramsize(); + return sram.sram; + } + else if (cdd.loaded && scd.cartridge.id) + { + int sz = scd.cartridge.mask + 1; + memcpy(tempsram, scd.cartridge.area, sz); + memcpy(tempsram + sz, scd.bram, 0x2000); + *size = sz + 0x2000; + return tempsram; + } + else if (cdd.loaded) + { + *size = 0x2000; + return scd.bram; + } + else if (scd.cartridge.id) + { + *size = scd.cartridge.mask + 1; + return scd.cartridge.area; + } + else + { + *size = 0; + return NULL; + } +} + +GPGX_EX int gpgx_put_sram(const uint8 *data, int size) +{ + if (sram.on) + { + if (size != saveramsize()) + return 0; + memcpy(sram.sram, data, size); + return 1; + } + else if (cdd.loaded && scd.cartridge.id) + { + int sz = scd.cartridge.mask + 1; + if (size != sz + 0x2000) + return 0; + memcpy(scd.cartridge.area, data, sz); + memcpy(scd.bram, data + sz, 0x2000); + return 1; + } + else if (cdd.loaded) + { + if (size != 0x2000) + return 0; + memcpy(scd.bram, data, size); + return 1; + } + else if (scd.cartridge.id) + { + int sz = scd.cartridge.mask + 1; + if (size != sz) + return 0; + memcpy(scd.cartridge.area, data, size); + return 1; + } + else + { + if (size != 0) + return 0; + return 1; // "successful"? + } +} + +GPGX_EX void gpgx_poke_vram(int addr, uint8 val) +{ + write_vram_byte(addr, val); +} + +GPGX_EX void gpgx_flush_vram(void) +{ + flush_vram_cache(); +} + +GPGX_EX const char* gpgx_get_memdom(int which, void **area, int *size) +{ + if (!area || !size) + return NULL; + switch (which) + { + case 0: + *area = work_ram; + *size = 0x10000; + return "68K RAM"; + case 1: + *area = zram; + *size = 0x2000; + return "Z80 RAM"; + case 2: + if (!cdd.loaded) + { + *area = ext.md_cart.rom; + *size = ext.md_cart.romsize; + return "MD CART"; + } + else if (scd.cartridge.id) + { + *area = scd.cartridge.area; + *size = scd.cartridge.mask + 1; + return "EBRAM"; + } + else return NULL; + case 3: + if (cdd.loaded) + { + *area = scd.bootrom; + *size = 0x20000; + return "CD BOOT ROM"; + } + else return NULL; + case 4: + if (cdd.loaded) + { + *area = scd.prg_ram; + *size = 0x80000; + return "CD PRG RAM"; + } + else return NULL; + case 5: + if (cdd.loaded) + { + *area = scd.word_ram[0]; + *size = 0x20000; + return "CD WORD RAM[0] (1M)"; + } + else return NULL; + case 6: + if (cdd.loaded) + { + *area = scd.word_ram[1]; + *size = 0x20000; + return "CD WORD RAM[1] (1M)"; + } + else return NULL; + case 7: + if (cdd.loaded) + { + *area = scd.word_ram_2M; + *size = 0x40000; + return "CD WORD RAM (2M)"; + } + else return NULL; + case 8: + if (cdd.loaded) + { + *area = scd.bram; + *size = 0x2000; + return "CD BRAM"; + } + else return NULL; + case 9: + *area = boot_rom; + *size = 0x800; + return "BOOT ROM"; + default: + return NULL; + case 10: + if (sram.on) + { + *area = sram.sram; + *size = saveramsize(); + return "SRAM"; + } + else return NULL; + case 11: + *area = cram; + *size = 128; + return "CRAM"; + case 12: + *area = vsram; + *size = 128; + return "VSRAM"; + case 13: + *area = vram; + *size = 65536; + return "VRAM"; + } +} + +GPGX_EX void gpgx_write_m68k_bus(unsigned addr, unsigned data) +{ + unsigned char *base = m68k.memory_map[addr >> 16 & 0xff].base; + if (base) + base[addr & 0xffff ^ 1] = data; +} + +GPGX_EX void gpgx_write_s68k_bus(unsigned addr, unsigned data) +{ + unsigned char *base = s68k.memory_map[addr >> 16 & 0xff].base; + if (base) + base[addr & 0xffff ^ 1] = data; +} +GPGX_EX unsigned gpgx_peek_m68k_bus(unsigned addr) +{ + unsigned char *base = m68k.memory_map[addr >> 16 & 0xff].base; + if (base) + return base[addr & 0xffff ^ 1]; + else + return 0xff; +} +GPGX_EX unsigned gpgx_peek_s68k_bus(unsigned addr) +{ + unsigned char *base = s68k.memory_map[addr >> 16 & 0xff].base; + if (base) + return base[addr & 0xffff ^ 1]; + else + return 0xff; +} + +struct InitSettings +{ + uint8_t Filter; + uint16_t LowPassRange; + int16_t LowFreq; + int16_t HighFreq; + int16_t LowGain; + int16_t MidGain; + int16_t HighGain; + uint32_t BackdropColor; +}; + +GPGX_EX int gpgx_init(const char *feromextension, ECL_ENTRY int (*feload_archive_cb)(const char *filename, unsigned char *buffer, int maxsize), int sixbutton, char system_a, char system_b, int region, struct InitSettings *settings) +{ + _debug_puts("Initializing GPGX native..."); + memset(&bitmap, 0, sizeof(bitmap)); + + strncpy(romextension, feromextension, 3); + romextension[3] = 0; + + load_archive_cb = feload_archive_cb; + + bitmap.width = 1024; + bitmap.height = 512; + bitmap.pitch = 1024 * 4; + bitmap.data = alloc_invisible(2 * 1024 * 1024); + tempsram = alloc_invisible(24 * 1024); + bg_pattern_cache = alloc_invisible(0x80000); + + ext.md_cart.rom = alloc_sealed(32 * 1024 * 1024); + SZHVC_add = alloc_sealed(131072); + SZHVC_sub = alloc_sealed(131072); + ym2612_lfo_pm_table = alloc_sealed(131072); + vdp_bp_lut = alloc_sealed(262144); + vdp_lut = alloc_sealed(6 * sizeof(*vdp_lut)); + for (int i = 0; i < 6; i++) + vdp_lut[i] = alloc_sealed(65536); + + /* sound options */ + config.psg_preamp = 150; + config.fm_preamp= 100; + config.hq_fm = 1; /* high-quality resampling */ + config.psgBoostNoise = 1; + config.filter = settings->Filter; //0; /* no filter */ + config.lp_range = settings->LowPassRange; //0x9999; /* 0.6 in 16.16 fixed point */ + config.low_freq = settings->LowFreq; //880; + config.high_freq = settings->HighFreq; //5000; + config.lg = settings->LowGain; //1.0; + config.mg = settings->MidGain; //1.0; + config.hg = settings->HighGain; //1.0; + config.dac_bits = 14; /* MAX DEPTH */ + config.ym2413= 2; /* AUTO */ + config.mono = 0; /* STEREO output */ + + /* system options */ + config.system = 0; /* AUTO */ + config.region_detect = region; // see loadrom.c + config.vdp_mode = 0; /* AUTO */ + config.master_clock = 0; /* AUTO */ + config.force_dtack = 0; + config.addr_error = 1; + config.bios = 0; + config.lock_on = 0; + + /* video options */ + config.overscan = 0; + config.gg_extra = 0; + config.ntsc = 0; + config.render = 1; + + // set overall input system type + // usual is MD GAMEPAD or NONE + // TEAMPLAYER, WAYPLAY, ACTIVATOR, XEA1P, MOUSE need to be specified + // everything else is auto or master system only + // XEA1P is port 1 only + // WAYPLAY is both ports at same time only + input.system[0] = system_a; + input.system[1] = system_b; + + cinterface_custom_backdrop_color = settings->BackdropColor; + + // apparently, the only part of config.input used is the padtype identifier, + // and that's used only for choosing pad type when system_md + { + int i; + for (i = 0; i < MAX_INPUTS; i++) + config.input[i].padtype = sixbutton ? DEVICE_PAD6B : DEVICE_PAD3B; + } + + if (!load_rom("PRIMARY_ROM")) + return 0; + + audio_init(44100, 0); + system_init(); + system_reset(); + + update_viewport(); + gpgx_clear_sram(); + + load_archive_cb = NULL; // don't hold onto load_archive_cb for longer than we need it for + + return 1; +} + +GPGX_EX void gpgx_reset(int hard) +{ + if (hard) + system_reset(); + else + gen_reset(0); +} + +GPGX_EX void gpgx_set_mem_callback(ECL_ENTRY void (*read)(unsigned), ECL_ENTRY void (*write)(unsigned), ECL_ENTRY void (*exec)(unsigned)) +{ + biz_readcb = read; + biz_writecb = write; + biz_execcb = exec; +} + +GPGX_EX void gpgx_set_cd_callback(CDCallback cdcallback) +{ + biz_cdcallback = cdcallback; +} + +GPGX_EX void gpgx_set_draw_mask(int mask) +{ + cinterface_render_bga = !!(mask & 1); + cinterface_render_bgb = !!(mask & 2); + cinterface_render_bgw = !!(mask & 4); + cinterface_render_obj = !!(mask & 8); + cinterface_custom_backdrop = !!(mask & 16); + if (cinterface_custom_backdrop) + color_update_m5(0, 0); + else + color_update_m5(0x00, *(uint16 *)&cram[border << 1]); +} + +GPGX_EX void gpgx_invalidate_pattern_cache(void) +{ + vdp_invalidate_full_cache(); +} + +typedef struct +{ + unsigned int value; + const char *name; +} gpregister_t; + +GPGX_EX int gpgx_getmaxnumregs(void) +{ + return 57; +} + +GPGX_EX int gpgx_getregs(gpregister_t *regs) +{ + int ret = 0; + + // 22 +#define MAKEREG(x) regs->name = "M68K " #x; regs->value = m68k_get_reg(M68K_REG_##x); regs++; ret++; + MAKEREG(D0); + MAKEREG(D1); + MAKEREG(D2); + MAKEREG(D3); + MAKEREG(D4); + MAKEREG(D5); + MAKEREG(D6); + MAKEREG(D7); + MAKEREG(A0); + MAKEREG(A1); + MAKEREG(A2); + MAKEREG(A3); + MAKEREG(A4); + MAKEREG(A5); + MAKEREG(A6); + MAKEREG(A7); + MAKEREG(PC); + MAKEREG(SR); + MAKEREG(SP); + MAKEREG(USP); + MAKEREG(ISP); + MAKEREG(IR); +#undef MAKEREG + + (regs-6)->value = biz_lastpc; // during read/write callbacks, PC runs away due to prefetch. restore it. + + // 13 +#define MAKEREG(x) regs->name = "Z80 " #x; regs->value = Z80.x.d; regs++; ret++; + MAKEREG(pc); + MAKEREG(sp); + MAKEREG(af); + MAKEREG(bc); + MAKEREG(de); + MAKEREG(hl); + MAKEREG(ix); + MAKEREG(iy); + MAKEREG(wz); + MAKEREG(af2); + MAKEREG(bc2); + MAKEREG(de2); + MAKEREG(hl2); +#undef MAKEREG + + // 22 + if (system_hw == SYSTEM_MCD) + { +#define MAKEREG(x) regs->name = "S68K " #x; regs->value = s68k_get_reg(M68K_REG_##x); regs++; ret++; + MAKEREG(D0); + MAKEREG(D1); + MAKEREG(D2); + MAKEREG(D3); + MAKEREG(D4); + MAKEREG(D5); + MAKEREG(D6); + MAKEREG(D7); + MAKEREG(A0); + MAKEREG(A1); + MAKEREG(A2); + MAKEREG(A3); + MAKEREG(A4); + MAKEREG(A5); + MAKEREG(A6); + MAKEREG(A7); + MAKEREG(PC); + MAKEREG(SR); + MAKEREG(SP); + MAKEREG(USP); + MAKEREG(ISP); + MAKEREG(IR); +#undef MAKEREG + } + + return ret; +} + +// at the moment, this dummy is not called +int main(void) +{ + return 0; +} diff --git a/waterbox/gpgx/core/cart_hw/md_cart.c b/waterbox/gpgx/core/cart_hw/md_cart.c index de7fc8f2a4..d51b72b319 100644 --- a/waterbox/gpgx/core/cart_hw/md_cart.c +++ b/waterbox/gpgx/core/cart_hw/md_cart.c @@ -1,1821 +1,1846 @@ -/**************************************************************************** - * Genesis Plus - * Mega Drive cartridge hardware support - * - * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) - * - * Many cartridge protections were initially documented by Haze - * (http://haze.mameworld.info/) - * - * Realtec mapper was documented by TascoDeluxe - * - * Redistribution and use of this code or any derivative works are permitted - * provided that the following conditions are met: - * - * - Redistributions may not be sold, nor may they be used in a commercial - * product or activity. - * - * - Redistributions that are modified from the original source must include the - * complete source code, including the source code for all components used by a - * binary built from the modified sources. However, as a special exception, the - * source code distributed need not include anything that is normally distributed - * (in either source or binary form) with the major components (compiler, kernel, - * and so on) of the operating system on which the executable runs, unless that - * component itself accompanies the executable. - * - * - Redistributions must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************************/ - -#include "shared.h" -#include "eeprom_i2c.h" -#include "eeprom_spi.h" -#include "gamepad.h" - -#define CART_CNT (55) - -/* Cart database entry */ -typedef struct -{ - uint16 chk_1; /* header checksum */ - uint16 chk_2; /* real checksum */ - uint8 bank_start; /* first mapped bank in $400000-$7fffff region */ - uint8 bank_end; /* last mapped bank in $400000-$7fffff region */ - cart_hw_t cart_hw; /* hardware description */ -} md_entry_t; - -/* Function prototypes */ -static void mapper_sega_w(uint32 data); -static void mapper_ssf2_w(uint32 address, uint32 data); -static void mapper_sf001_w(uint32 address, uint32 data); -static void mapper_sf002_w(uint32 address, uint32 data); -static void mapper_sf004_w(uint32 address, uint32 data); -static uint32 mapper_sf004_r(uint32 address); -static void mapper_t5740_w(uint32 address, uint32 data); -static uint32 mapper_t5740_r(uint32 address); -static uint32 mapper_smw_64_r(uint32 address); -static void mapper_smw_64_w(uint32 address, uint32 data); -static void mapper_realtec_w(uint32 address, uint32 data); -static void mapper_seganet_w(uint32 address, uint32 data); -static void mapper_32k_w(uint32 data); -static void mapper_64k_w(uint32 data); -static void mapper_64k_multi_w(uint32 address); -static uint32 mapper_radica_r(uint32 address); -static void default_time_w(uint32 address, uint32 data); -static void default_regs_w(uint32 address, uint32 data); -static uint32 default_regs_r(uint32 address); -static uint32 default_regs_r_16(uint32 address); -static uint32 custom_regs_r(uint32 address); -static void custom_regs_w(uint32 address, uint32 data); -static void custom_alt_regs_w(uint32 address, uint32 data); -static uint32 topshooter_r(uint32 address); -static void topshooter_w(uint32 address, uint32 data); -static uint32 tekken_regs_r(uint32 address); -static void tekken_regs_w(uint32 address, uint32 data); - -/* Games that need extra hardware emulation: - - copy protection device - - custom ROM banking device -*/ -static const md_entry_t rom_database[CART_CNT] = -{ -/* Funny World & Balloon Boy */ - {0x0000,0x06ab,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},1,0,NULL,NULL,NULL,mapper_realtec_w}}, -/* Whac-a-Critter */ - {0xffff,0xf863,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},1,0,NULL,NULL,NULL,mapper_realtec_w}}, -/* Earth Defense */ - {0xffff,0x44fb,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},1,0,NULL,NULL,NULL,mapper_realtec_w}}, - - -/* RADICA (Volume 1) (bad dump ?) */ - {0x0000,0x2326,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,1,mapper_radica_r,NULL,NULL,NULL}}, -/* RADICA (Volume 1) */ - {0x24f4,0xfc84,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,mapper_radica_r,NULL,NULL,NULL}}, -/* RADICA (Volume 2) */ - {0x104f,0x32e9,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,mapper_radica_r,NULL,NULL,NULL}}, - - -/* Tenchi wo Kurau III: Sangokushi Gaiden - Chinese Fighter */ - {0x9490,0x8180,0x40,0x6f,{{0x00,0x00,0x00,0x00},{0xf0000c,0xf0000c,0xf0000c,0xf0000c},{0x400000,0x400004,0x400008,0x40000c},0,1,NULL,NULL,default_regs_r,custom_alt_regs_w}}, - - -/* Top Fighter */ - {0x4eb9,0x5d8b,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, -/* Soul Edge VS Samurai Spirits */ - {0x00ff,0x5d34,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, -/* Mulan */ - {0x0404,0x1b40,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, -/* Pocket Monsters II */ - {0x47f9,0x17e5,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, -/* Lion King 3 */ - {0x0000,0x507c,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, -/* Super King Kong 99 */ - {0x0000,0x7d6e,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, -/* Gunfight 3-in-1 */ - {0x0000,0x6ff8,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, -/* Pokemon Stadium */ - {0x0000,0x843c,0x70,0x7f,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,1,NULL,NULL,NULL,custom_regs_w}}, - - -/* Tekken 3 Special (original dump) (a bootleg version also exists, with patched protection & different boot routine which reads unused !TIME mapped area) */ - {0x0000,0xc2f0,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,NULL,NULL,tekken_regs_r,tekken_regs_w}}, - - -/* Lion King 2 */ - {0xffff,0x1d9b,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, -/* Squirell King */ - {0x0000,0x8ec8,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, -/* Tiny Toon Adventures 3 */ - {0x2020,0xed9c,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, -/* Lian Huan Pao - Barver Battle Saga (registers accessed by Z80, related to sound engine ?) */ - {0x30b9,0x1c2a,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, -/* Shui Hu Zhuan (registers accessed by Z80, related to sound engine ?) */ - {0x6001,0x0211,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, -/* Feng Shen Ying Jie Chuan (registers accessed by Z80, related to sound engine ?) */ - {0xffff,0x5d98,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, -/* (*) Shui Hu - Feng Yun Zhuan (patched ROM, unused registers) */ - {0x3332,0x872b,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, - - -/* (*) Chao Ji Da Fu Weng (patched ROM, various words witten to register, long word also read from $7E0000, unknown banking hardware ?) */ - {0xa697,0xa697,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x000000,0x000000,0x000000},0,0,NULL,NULL,NULL,default_regs_w}}, - -/* (*) Aq Renkan Awa (patched ROM, ON/OFF bit sequence is written to register, unknown banking hardware ?) */ - {0x8104,0x0517,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400001,0x000000,0x000000,0x000000},0,0,NULL,NULL,NULL,default_regs_w}}, - - -/* (*) Tun Shi Tian Di III (patched ROM, unused register) */ - {0x0000,0x9c5e,0x40,0x40,{{0xab,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400046,0x000000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, - - -/* Ma Jiang Qing Ren - Ji Ma Jiang Zhi */ - {0x0000,0x7037,0x40,0x40,{{0x90,0xd3,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x401000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, -/* Super Majon Club */ - {0x0000,0x3b95,0x40,0x40,{{0x90,0xd3,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x401000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, -/* Feng Kuang Tao Hua Yuan (original version from Creaton Softec Inc) (a bootleg version also exists with patched protection and minor title screen variations) */ - {0x0000,0x9dc4,0x40,0x40,{{0x90,0xd3,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x401000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, - - -/* (*) Jiu Ji Ma Jiang II - Ye Yan Bian (patched ROM, using expected register value - $0f - crashes the game) (uses 16-bits reads) */ - {0x0c44,0xba81,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x400006},0,0,NULL,NULL,default_regs_r_16,NULL}}, -/* 16 Zhang Ma Jiang (uses 16-bits reads) */ - {0xfb40,0x4bed,0x40,0x40,{{0x00,0xaa,0x00,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x400002,0x000000,0x400006},0,0,NULL,NULL,default_regs_r_16,NULL}}, -/* 16 Tiles Mahjong II (uses 16-bits reads) */ - {0xffff,0x0903,0x40,0x40,{{0x00,0x00,0xc9,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x400004,0x000000},0,0,NULL,NULL,default_regs_r_16,NULL}}, -/* Thunderbolt II (uses 16-bits reads) */ - {0x0000,0x1585,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r_16,NULL}}, - - -/* Super Bubble Bobble */ - {0x0000,0x16cd,0x40,0x40,{{0x55,0x0f,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, -/* Tenchi wo Kurau II - The Battle of Red Cliffs (Unl) */ - {0x0000,0xed61,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, -/* Huan Le Tao Qi Shu - Smart Mouse */ - {0x0000,0x1a28,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, -/* (*) Hei Tao 2 - Super Big 2 (patched ROM, unused registers) */ - {0x0000,0x5843,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, -/* Mighty Morphin Power Rangers - The Fighting Edition */ - {0x0000,0x2288,0x40,0x40,{{0x55,0x0f,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, -/* Elf Wor */ - {0x0080,0x3dba,0x40,0x40,{{0x55,0x0f,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, -/* Ya-Se Chuanshuo */ - {0xffff,0xd472,0x40,0x40,{{0x63,0x98,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, -/* 777 Casino (For first one, 0x55 works as well. Other values are never used so they are guessed from on other unlicensed games using similar mapper) */ - {0x0000,0xf8d9,0x40,0x40,{{0x63,0x98,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, -/* Wu Kong Wai Zhuan (original) (a bootleg version also exists, with patched protection & modified SRAM test routine ?) */ - {0x0000,0x19ff,0x40,0x40,{{0x63,0x98,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, -/* Soul Blade */ - {0x0000,0x0c5b,0x40,0x40,{{0x63,0x98,0xc9,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, - - -/* King of Fighter 98 */ - {0x0000,0xd0a0,0x48,0x4f,{{0x00,0x00,0xaa,0xf0},{0xffffff,0xffffff,0xfc0000,0xfc0000},{0x000000,0x000000,0x480000,0x4c0000},0,0,NULL,NULL,default_regs_r,NULL}}, - - -/* Rockman X3 (bootleg version ? two last register returned values are ignored, note that 0xaa/0x18 would work as well) */ - {0x0000,0x9d0e,0x40,0x40,{{0x0c,0x00,0xc9,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0x000000,0x400004,0x400006},0,0,default_regs_r,NULL,default_regs_r,NULL}}, - - -/* (*) Dragon Ball Final Bout (patched ROM, in original code, different switches occurs depending on returned value $00-$0f) */ - {0xc65a,0xc65a,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, -/* (*) Yang Jia Jiang - Yang Warrior Family (patched ROM, register value unused) */ - {0x0000,0x96b0,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, -/* Super Mario 2 1998 */ - {0xffff,0x0474,0x00,0x00,{{0x0a,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, -/* Super Mario World */ - {0x2020,0xb4eb,0x00,0x00,{{0x1c,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, - - -/* King of Fighter 99 */ - {0x0000,0x021e,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,custom_regs_r,default_regs_w,NULL,NULL}}, -/* Pocket Monster */ - {0xd6fc,0x1eb1,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,custom_regs_r,default_regs_w,NULL,NULL}}, -/* Pocket Monster (bootleg version ? two last register returned values are ignored & first register test has been modified) */ - {0xd6fc,0x6319,0x00,0x00,{{0x14,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,default_regs_r,m68k_unused_8_w,NULL,NULL}}, -/* A Bug's Life (bootleg version ? two last register returned values are ignored & first register test has been modified ?) */ - {0x7f7f,0x2aad,0x00,0x00,{{0x28,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,default_regs_r,m68k_unused_8_w,NULL,NULL}}, - - -/* Game no Kanzume Otokuyou */ - {0x0000,0xf9d1,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,NULL,mapper_seganet_w,NULL,NULL}}, - - -/* Top Shooter (arcade hardware) */ - {0xffff,0x3632,0x20,0x20,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,NULL,NULL,topshooter_r,topshooter_w}} -}; - - -/************************************************************ - Cart Hardware initialization -*************************************************************/ - -void md_cart_init(void) -{ - int i; - - /*************************************************************************************************************** - CARTRIDGE ROM MIRRORING - *************************************************************************************************************** - - MD Cartridge area is mapped to $000000-$3fffff: - - -> when accessing ROM, 68k address lines A1 to A21 can be used by the internal cartridge hardware to decode - full 4MB address range. - -> depending on ROM total size and additional decoding hardware, some address lines might be ignored, - resulting in ROM mirroring. - - Cartridges can use either 8-bits (x2) or 16-bits (x1, x2) Mask ROM chips, each chip size is a factor of 2 bytes: - - -> two 8-bits chips are equivalent to one 16-bits chip, no specific address decoding is required, needed - address lines are simply connected to each chip, upper address lines are ignored and data lines are - connected appropriately to each chip (D0-D7 to one chip, D8-D15 to the other one). - ROM is generally mirrored each N bytes where N=2^(k+1) is the total ROM size (ROM1+ROM2,ROM1+ROM2,...) - - -> one single 16-bits chip do not need specific address decoding, address lines are simply connected - depending on the ROM size, upper address lines being ignored. - ROM is generally mirrored each N bytes where N=2^k is the size of the ROM chip (ROM1,ROM1,ROM1,...) - - -> two 16-bits chips of the same size are equivalent to one chip of double size, address decoding generally - is the same except that specific hardware is used (one address line is generally used for chip selection, - lower ones being used to address the chips and upper ones being ignored). - ROM is generally mirrored each N bytes where N=2^(k+1) is the total ROM size (ROM1,ROM2,ROM1,ROM2,...) - - -> two 16-bits chips with different size are mapped differently. Address decoding is done the same way as - above (one address line used for chip selection) but the ignored & required address lines differ from - one chip to another, which makes ROM mirroring different. - ROM2 size is generally half of ROM1 size and upper half ignored (ROM1,ROM2,XXXX,ROM1,ROM2,XXXX,...) - - From the emulator point of view, we only need to distinguish 2 cases: - - 1/ total ROM size is a factor of 2: ROM is mirrored each 2^k bytes. - - 2/ total ROM size is not a factor of 2: ROM is padded up to 2^k then mirrored each 2^k bytes. - - ******************************************************************************************************************/ - - /* calculate nearest size with factor of 2 */ - unsigned int size = 0x10000; - while (cart.romsize > size) - size <<= 1; - - /* Sonic & Knuckles */ - if (strstr(rominfo.international,"SONIC & KNUCKLES")) - { - /* disable ROM mirroring at $200000-$3fffff (normally mapped to external cartridge) */ - size = 0x400000; - } - - /* total ROM size is not a factor of 2 */ - /* TODO: handle all possible ROM configurations using cartridge database */ - if (cart.romsize < size) - { - if (size < MAXROMSIZE) - { - /* ROM is padded up to 2^k bytes */ - memset(cart.rom + cart.romsize, 0xff, size - cart.romsize); - } - else - { - /* ROM is padded up to max ROM size */ - memset(cart.rom + cart.romsize, 0xff, MAXROMSIZE - cart.romsize); - } - } - - /* ROM is mirrored each 2^k bytes */ - cart.mask = size - 1; - - /********************************************** - DEFAULT CARTRIDGE MAPPING - ***********************************************/ - for (i=0; i<0x40; i++) - { - /* cartridge ROM */ - m68k.memory_map[i].base = cart.rom + ((i<<16) & cart.mask); - m68k.memory_map[i].read8 = NULL; - m68k.memory_map[i].read16 = NULL; - m68k.memory_map[i].write8 = m68k_unused_8_w; - m68k.memory_map[i].write16 = m68k_unused_16_w; - zbank_memory_map[i].read = NULL; - zbank_memory_map[i].write = zbank_unused_w; - } - - for (i=0x40; i<0x80; i++) - { - /* unused area */ - m68k.memory_map[i].base = cart.rom + (i<<16); - m68k.memory_map[i].read8 = m68k_read_bus_8; - m68k.memory_map[i].read16 = m68k_read_bus_16; - m68k.memory_map[i].write8 = m68k_unused_8_w; - m68k.memory_map[i].write16 = m68k_unused_16_w; - zbank_memory_map[i].read = zbank_unused_r; - zbank_memory_map[i].write = zbank_unused_w; - } - - /* support for Quackshot REV 01 (real) dump */ - if (strstr(rominfo.product,"00004054-01") && (cart.romsize == 0x80000)) - { - /* $000000-$0fffff: first 256K mirrored (A18 not connected to ROM chip, A19 not decoded) */ - for (i=0x00; i<0x10; i++) - { - /* $200000-$3fffff: mirror of $000000-$1fffff (A21 not decoded) */ - m68k.memory_map[i].base = m68k.memory_map[i + 0x20].base = cart.rom + ((i & 0x03) << 16); - } - - /* $100000-$1fffff: second 256K mirrored (A20 connected to ROM chip A18) */ - for (i=0x10; i<0x20; i++) - { - /* $200000-$3fffff: mirror of $000000-$1fffff (A21 not decoded) */ - m68k.memory_map[i].base = m68k.memory_map[i + 0x20].base = cart.rom + 0x40000 + ((i & 0x03) << 16); - } - } - - /********************************************** - BACKUP MEMORY - ***********************************************/ - sram_init(); - eeprom_i2c_init(); - - /* external SRAM */ - if (sram.on && !sram.custom) - { - /* disabled on startup if ROM is mapped in same area */ - if (cart.romsize <= sram.start) - { - /* initialize m68k bus handlers */ - m68k.memory_map[sram.start >> 16].base = sram.sram; - m68k.memory_map[sram.start >> 16].read8 = sram_read_byte; - m68k.memory_map[sram.start >> 16].read16 = sram_read_word; - m68k.memory_map[sram.start >> 16].write8 = sram_write_byte; - m68k.memory_map[sram.start >> 16].write16 = sram_write_word; - zbank_memory_map[sram.start >> 16].read = sram_read_byte; - zbank_memory_map[sram.start >> 16].write = sram_write_byte; - } - } - - /********************************************** - SVP CHIP - ***********************************************/ - svp = NULL; - if (strstr(rominfo.international,"Virtua Racing")) - { - svp_init(); - - m68k.memory_map[0x30].base = svp->dram; - m68k.memory_map[0x30].read16 = NULL; - m68k.memory_map[0x30].write16 = svp_write_dram; - - m68k.memory_map[0x31].base = svp->dram + 0x10000; - m68k.memory_map[0x31].read16 = NULL; - m68k.memory_map[0x31].write16 = svp_write_dram; - - m68k.memory_map[0x39].read16 = svp_read_cell_1; - m68k.memory_map[0x3a].read16 = svp_read_cell_2; - } - - /********************************************** - J-CART - ***********************************************/ - cart.special = 0; - if ((strstr(rominfo.product,"00000000") && (rominfo.checksum == 0x168b)) || /* Super Skidmarks, Micro Machines Military */ - (strstr(rominfo.product,"00000000") && (rominfo.checksum == 0x165e)) || /* Pete Sampras Tennis (1991), Micro Machines 96 */ - (strstr(rominfo.product,"00000000") && (rominfo.checksum == 0xcee0)) || /* Micro Machines Military (bad) */ - (strstr(rominfo.product,"00000000") && (rominfo.checksum == 0x2c41)) || /* Micro Machines 96 (bad) */ - (strstr(rominfo.product,"XXXXXXXX") && (rominfo.checksum == 0xdf39)) || /* Sampras Tennis 96 */ - (strstr(rominfo.product,"T-123456") && (rominfo.checksum == 0x1eae)) || /* Sampras Tennis 96 */ - (strstr(rominfo.product,"T-120066") && (rominfo.checksum == 0x16a4)) || /* Pete Sampras Tennis (1994)*/ - strstr(rominfo.product,"T-120096")) /* Micro Machines 2 */ - { - if (cart.romsize <= 0x380000) /* just to be sure (checksum might not be enough) */ - { - cart.special |= HW_J_CART; - - /* force port 1 setting */ - if (input.system[1] != SYSTEM_WAYPLAY) - { - old_system[1] = input.system[1]; - input.system[1] = SYSTEM_MD_GAMEPAD; - } - - /* extra connectors mapped at $38xxxx or $3Fxxxx */ - m68k.memory_map[0x38].read16 = jcart_read; - m68k.memory_map[0x38].write16 = jcart_write; - m68k.memory_map[0x3f].read16 = jcart_read; - m68k.memory_map[0x3f].write16 = jcart_write; - } - } - - /********************************************** - LOCK-ON - ***********************************************/ - - /* clear existing patches */ - ggenie_shutdown(); - areplay_shutdown(); - - /* initialize extra hardware */ - switch (config.lock_on) - { - case TYPE_GG: - { - ggenie_init(); - break; - } - - case TYPE_AR: - { - areplay_init(); - break; - } - - case TYPE_SK: - { - FILE *f; - - /* store S&K ROM above cartridge ROM (and before backup memory) */ - if (cart.romsize > 0x600000) break; - - /* load Sonic & Knuckles ROM (2 MB) */ - f = fopen(SK_ROM,"rb"); - if (!f) break; - for (i=0; i<0x200000; i+=0x1000) - { - fread(cart.rom + 0x600000 + i, 0x1000, 1, f); - } - fclose(f); - - /* load Sonic 2 UPMEM ROM (256 KB) */ - f = fopen(SK_UPMEM,"rb"); - if (!f) break; - for (i=0; i<0x40000; i+=0x1000) - { - fread(cart.rom + 0x900000 + i, 0x1000, 1, f); - } - fclose(f); - -#ifdef LSB_FIRST - for (i=0; i<0x200000; i+=2) - { - /* Byteswap ROM */ - uint8 temp = cart.rom[i + 0x600000]; - cart.rom[i + 0x600000] = cart.rom[i + 0x600000 + 1]; - cart.rom[i + 0x600000 + 1] = temp; - } - - for (i=0; i<0x40000; i+=2) - { - /* Byteswap ROM */ - uint8 temp = cart.rom[i + 0x900000]; - cart.rom[i + 0x900000] = cart.rom[i + 0x900000 + 1]; - cart.rom[i + 0x900000 + 1] = temp; - } -#endif - - /* $000000-$1FFFFF is mapped to S&K ROM */ - for (i=0x00; i<0x20; i++) - { - m68k.memory_map[i].base = cart.rom + 0x600000 + (i << 16); - } - - cart.special |= HW_LOCK_ON; - break; - } - - default: - { - break; - } - } - - /********************************************** - CARTRIDGE EXTRA HARDWARE - ***********************************************/ - memset(&cart.hw, 0, sizeof(cart.hw)); - - /* search for game into database */ - for (i=0; i 0x400000) - { - /* assume linear ROM mapper without bankswitching (max. 10MB) */ - for (i=0x40; i<0xA0; i++) - { - m68k.memory_map[i].base = cart.rom + (i<<16); - m68k.memory_map[i].read8 = NULL; - m68k.memory_map[i].read16 = NULL; - zbank_memory_map[i].read = NULL; - } - } - - /* default write handler for !TIME range ($A130xx)*/ - if (!cart.hw.time_w) - { - cart.hw.time_w = default_time_w; - } -} - -/* hardware that need to be reseted on power on */ -void md_cart_reset(int hard_reset) -{ - int i; - - /* reset cartridge mapping */ - if (cart.hw.bankshift) - { - for (i=0x00; i<0x40; i++) - { - m68k.memory_map[i].base = cart.rom + ((i<<16) & cart.mask); - } - } - - /* SVP chip */ - if (svp) - { - svp_reset(); - } - - /* Lock-ON */ - switch (config.lock_on) - { - case TYPE_GG: - { - ggenie_reset(hard_reset); - break; - } - - case TYPE_AR: - { - areplay_reset(hard_reset); - break; - } - - case TYPE_SK: - { - if (cart.special & HW_LOCK_ON) - { - /* disable UPMEM chip at $300000-$3fffff */ - for (i=0x30; i<0x40; i++) - { - m68k.memory_map[i].base = cart.rom + ((i<<16) & cart.mask); - } - } - break; - } - - default: - { - break; - } - } -} - - -/************************************************************ - MAPPER handlers -*************************************************************/ - -/* - "official" ROM/SRAM bankswitch (Phantasy Star IV, Story of Thor/Beyond Oasis, Sonic 3 & Knuckles) -*/ -static void mapper_sega_w(uint32 data) -{ - int i; - - if (data & 1) - { - if (sram.on) - { - /* Backup RAM mapped to $200000-$20ffff (normally mirrored up to $3fffff but this breaks Sonic Megamix and no game need it) */ - m68k.memory_map[0x20].base = sram.sram; - m68k.memory_map[0x20].read8 = sram_read_byte; - m68k.memory_map[0x20].read16 = sram_read_word; - zbank_memory_map[0x20].read = sram_read_byte; - - /* Backup RAM write protection */ - if (data & 2) - { - m68k.memory_map[0x20].write8 = m68k_unused_8_w; - m68k.memory_map[0x20].write16 = m68k_unused_16_w; - zbank_memory_map[0x20].write = zbank_unused_w; - } - else - { - m68k.memory_map[0x20].write8 = sram_write_byte; - m68k.memory_map[0x20].write16 = sram_write_word; - zbank_memory_map[0x20].write = sram_write_byte; - } - } - - /* S&K lock-on chip */ - if ((cart.special & HW_LOCK_ON) && (config.lock_on == TYPE_SK)) - { - /* S2K upmem chip mapped to $300000-$3fffff (256K mirrored) */ - for (i=0x30; i<0x40; i++) - { - m68k.memory_map[i].base = (cart.rom + 0x900000) + ((i & 3) << 16); - } - } - } - else - { - /* cartridge ROM mapped to $200000-$3fffff */ - for (i=0x20; i<0x40; i++) - { - m68k.memory_map[i].base = cart.rom + ((i<<16) & cart.mask); - m68k.memory_map[i].read8 = NULL; - m68k.memory_map[i].read16 = NULL; - zbank_memory_map[i].read = NULL; - m68k.memory_map[i].write8 = m68k_unused_8_w; - m68k.memory_map[i].write16 = m68k_unused_16_w; - zbank_memory_map[i].write = zbank_unused_w; - } - } -} - -/* - Super Street Fighter 2 ROM bankswitch - documented by Bart Trzynadlowski (http://www.trzy.org/files/ssf2.txt) -*/ -static void mapper_ssf2_w(uint32 address, uint32 data) -{ - /* 8 x 512k banks */ - address = (address << 2) & 0x38; - - /* bank 0 remains unchanged */ - if (address) - { - uint32 i; - uint8 *src = cart.rom + (data << 19); - - for (i=0; i<8; i++) - { - m68k.memory_map[address++].base = src + (i<<16); - } - } -} - -/* - SF-001 mapper -*/ -static void mapper_sf001_w(uint32 address, uint32 data) -{ - switch ((address >> 8) & 0xf) - { - case 0xe: - { - int i; - - /* bit 6: enable / disable cartridge access */ - if (data & 0x40) - { - /* $000000-$3FFFFF is not mapped */ - for (i=0x00; i<0x40; i++) - { - m68k.memory_map[i].base = cart.rom + (i << 16); - m68k.memory_map[i].read8 = m68k_read_bus_8; - m68k.memory_map[i].read16 = m68k_read_bus_16; - m68k.memory_map[i].write8 = (i > 0x00) ? m68k_unused_8_w : mapper_sf001_w; - m68k.memory_map[i].write16 = (i > 0x00) ? m68k_unused_16_w : mapper_sf001_w; - zbank_memory_map[i].read = zbank_unused_r; - zbank_memory_map[i].write = (i > 0x00) ? m68k_unused_8_w : mapper_sf001_w; - } - } - - /* bit 7: enable / disable SRAM & ROM bankswitching */ - else if (data & 0x80) - { - /* 256K ROM bank #15 mapped to $000000-$03FFFF */ - for (i=0x00; i<0x04; i++) - { - m68k.memory_map[i].base = cart.rom + ((0x38 + i) << 16); - m68k.memory_map[i].read8 = NULL; - m68k.memory_map[i].read16 = NULL; - zbank_memory_map[i].read = NULL; - } - - /* 256K ROM banks #2 to #15 mapped to $040000-$3BFFFF (last revision) or $040000-$3FFFFF (older revisions) */ - for (i=0x04; i<(sram.start >> 16); i++) - { - m68k.memory_map[i].base = cart.rom + (i << 16); - m68k.memory_map[i].read8 = NULL; - m68k.memory_map[i].read16 = NULL; - zbank_memory_map[i].read = NULL; - } - - /* 32K static RAM mirrored into $3C0000-$3FFFFF (odd bytes only) (last revision only) */ - while (i<0x40) - { - m68k.memory_map[i].base = sram.sram; - m68k.memory_map[i].read8 = sram_read_byte; - m68k.memory_map[i].read16 = sram_read_word; - m68k.memory_map[i].write8 = sram_write_byte; - m68k.memory_map[i].write16 = sram_write_word; - zbank_memory_map[i].read = sram_read_byte; - zbank_memory_map[i].write = sram_write_byte; - i++; - } - } - else - { - /* 256K ROM banks #1 to #16 mapped to $000000-$3FFFFF (default) */ - for (i=0x00; i<0x40; i++) - { - m68k.memory_map[i].base = cart.rom + (i << 16); - m68k.memory_map[i].read8 = NULL; - m68k.memory_map[i].read16 = NULL; - m68k.memory_map[i].write8 = (i > 0x00) ? m68k_unused_8_w : mapper_sf001_w; - m68k.memory_map[i].write16 = (i > 0x00) ? m68k_unused_16_w : mapper_sf001_w; - zbank_memory_map[i].read = NULL; - zbank_memory_map[i].write = (i > 0x00) ? m68k_unused_8_w : mapper_sf001_w; - } - } - - /* bit 5: lock bankswitch hardware when set */ - if (data & 0x20) - { - /* disable bankswitch hardware access until hard reset */ - m68k.memory_map[0x00].write8 = m68k_unused_8_w; - m68k.memory_map[0x00].write16 = m68k_unused_16_w; - zbank_memory_map[0x00].write = m68k_unused_8_w; - } - - return; - } - - default: - { - m68k_unused_8_w(address, data); - return; - } - } -} - -/* - SF-002 mapper -*/ -static void mapper_sf002_w(uint32 address, uint32 data) -{ - int i; - if (data & 0x80) - { - /* $000000-$1BFFFF mapped to $200000-$3BFFFF */ - for (i=0x20; i<0x3C; i++) - { - m68k.memory_map[i].base = cart.rom + ((i & 0x1F) << 16); - } - } - else - { - /* $200000-$3BFFFF mapped to $200000-$3BFFFF */ - for (i=0x20; i<0x3C; i++) - { - m68k.memory_map[i].base = cart.rom + (i << 16); - } - } -} - -/* - SF-004 mapper -*/ -static void mapper_sf004_w(uint32 address, uint32 data) -{ - int i; - switch ((address >> 8) & 0xf) - { - case 0xd: - { - /* bit 7: enable/disable static RAM access */ - if (data & 0x80) - { - /* 32KB static RAM mirrored into $200000-$2FFFFF (odd bytes only) */ - for (i=0x20; i<0x30; i++) - { - m68k.memory_map[i].read8 = sram_read_byte; - m68k.memory_map[i].read16 = sram_read_word; - m68k.memory_map[i].write8 = sram_write_byte; - m68k.memory_map[i].write16 = sram_write_word; - zbank_memory_map[i].read = sram_read_byte; - zbank_memory_map[i].write = sram_write_byte; - } - } - else - { - /* 32KB static RAM disabled at $200000-$2FFFFF */ - for (i=0x20; i<0x30; i++) - { - m68k.memory_map[i].read8 = m68k_read_bus_8; - m68k.memory_map[i].read16 = m68k_read_bus_16; - m68k.memory_map[i].write8 = m68k_unused_8_w; - m68k.memory_map[i].write16 = m68k_unused_16_w; - zbank_memory_map[i].read = m68k_read_bus_8; - zbank_memory_map[i].write = m68k_unused_8_w; - } - } - - return; - } - - case 0x0e: - { - /* bit 5: enable / disable cartridge ROM access */ - if (data & 0x20) - { - /* $000000-$1FFFFF is not mapped */ - for (i=0x00; i<0x20; i++) - { - m68k.memory_map[i].read8 = m68k_read_bus_8; - m68k.memory_map[i].read16 = m68k_read_bus_16; - zbank_memory_map[i].read = m68k_read_bus_8; - } - } - - /* bit 6: enable / disable first page mirroring */ - else if (data & 0x40) - { - /* first page ROM bank */ - uint8 base = (m68k.memory_map[0x00].base - cart.rom) >> 16; - - /* 5 x 256K ROM banks mapped to $000000-$13FFFF, starting from first page ROM bank */ - for (i=0x00; i<0x14; i++) - { - m68k.memory_map[i].base = cart.rom + (((base + i) & 0x1f) << 16); - m68k.memory_map[i].read8 = NULL; - m68k.memory_map[i].read16 = NULL; - zbank_memory_map[i].read = NULL; - } - - /* $140000-$1FFFFF is not mapped */ - for (i=0x14; i<0x20; i++) - { - m68k.memory_map[i].read8 = m68k_read_bus_8; - m68k.memory_map[i].read16 = m68k_read_bus_16; - zbank_memory_map[i].read = m68k_read_bus_8; - } - } - else - { - /* first page 256K ROM bank mirrored into $000000-$1FFFFF */ - for (i=0x00; i<0x20; i++) - { - m68k.memory_map[i].base = m68k.memory_map[0].base + ((i & 0x03) << 16); - m68k.memory_map[i].read8 = NULL; - m68k.memory_map[i].read16 = NULL; - zbank_memory_map[i].read = NULL; - } - } - - /* bit 7: lock ROM bankswitching hardware when cleared */ - if (!(data & 0x80)) - { - /* disable bankswitch hardware access */ - m68k.memory_map[0x00].write8 = m68k_unused_8_w; - m68k.memory_map[0x00].write16 = m68k_unused_16_w; - zbank_memory_map[0x00].write = m68k_unused_8_w; - } - - return; - } - - case 0x0f: - { - /* bits 6-4: select first page ROM bank (8 x 256K ROM banks) */ - uint8 base = ((data >> 4) & 7) << 2; - - if (m68k.memory_map[0].base == m68k.memory_map[4].base) - { - /* selected 256K ROM bank mirrored into $000000-$1FFFFF */ - for (i=0x00; i<0x20; i++) - { - m68k.memory_map[i].base = cart.rom + ((base + (i & 0x03)) << 16); - } - } - else - { - /* 5 x 256K ROM banks mapped to $000000-$13FFFF, starting from selected bank */ - for (i=0x00; i<0x14; i++) - { - m68k.memory_map[i].base = cart.rom + (((base + i) & 0x1f) << 16); - } - } - - return; - } - - default: - { - m68k_unused_8_w(address, data); - return; - } - } -} - -static uint32 mapper_sf004_r(uint32 address) -{ - /* return first page 256K bank index ($00,$10,$20,...,$70) */ - return (((m68k.memory_map[0x00].base - cart.rom) >> 18) << 4); -} - -/* - T-5740xx-xx mapper -*/ -static void mapper_t5740_w(uint32 address, uint32 data) -{ - int i; - uint8 *base; - - switch (address & 0xff) - { - case 0x01: /* mode register */ - { - /* bits 7-4: unused ? */ - /* bit 3: enable SPI registers access ? */ - /* bit 2: not used ? */ - /* bit 1: enable bankswitch registers access ? */ - /* bit 0: always set, enable hardware access ? */ - return; - } - - case 0x03: /* page #5 register */ - { - /* map any of 16 x 512K ROM banks to $280000-$2FFFFF */ - base = cart.rom + ((data & 0x0f) << 19); - for (i=0x28; i<0x30; i++) - { - m68k.memory_map[i].base = base + ((i & 0x07) << 16); - } - return; - } - - case 0x05: /* page #6 register */ - { - /* map any of 16 x 512K ROM banks to $300000-$37FFFF */ - base = cart.rom + ((data & 0x0f) << 19); - for (i=0x30; i<0x38; i++) - { - m68k.memory_map[i].base = base + ((i & 0x07) << 16); - } - return; - } - - case 0x07: /* page #7 register */ - { - /* map any of 16 x 512K ROM banks to $380000-$3FFFFF */ - base = cart.rom + ((data & 0x0f) << 19); - for (i=0x38; i<0x40; i++) - { - m68k.memory_map[i].base = base + ((i & 0x07) << 16); - } - return; - } - - case 0x09: /* serial EEPROM SPI board support */ - { - eeprom_spi_write(data); - return; - } - - default: - { - /* unknown registers */ - m68k_unused_8_w(address, data); - return; - } - } -} - -static uint32 mapper_t5740_r(uint32 address) -{ - /* By default, first 32K of each eight 512K pages mapped in $000000-$3FFFFF are mirrored in the 512K page */ - /* mirroring is disabled/enabled when a specific number of words is being read from specific ROM addresses */ - /* Exact decoding isn't known but mirrored data is expected on startup when reading a few times from $181xx */ - /* this area doesn't seem to be accessed as byte later so it seems safe to always return mirrored data here */ - if ((address & 0xff00) == 0x8100) - { - return READ_BYTE(cart.rom , (address & 0x7fff)); - } - - return READ_BYTE(cart.rom, address); -} - -/* - Super Mario World 64 (unlicensed) mapper -*/ -static void mapper_smw_64_w(uint32 address, uint32 data) -{ - /* internal registers (saved to backup RAM) */ - switch ((address >> 16) & 0x07) - { - case 0x00: /* $60xxxx */ - { - if (address & 2) - { - /* $600003 data write mode ? */ - switch (sram.sram[0x00] & 0x07) - { - case 0x00: - { - /* update value returned at $660001-$660003 */ - sram.sram[0x06] = ((sram.sram[0x06] ^ sram.sram[0x01]) ^ data) & 0xFE; - break; - } - - case 0x01: - { - /* update value returned at $660005-$660007 */ - sram.sram[0x07] = data & 0xFE; - break; - } - - case 0x07: - { - /* update selected ROM bank (upper 512K) mapped at $610000-$61ffff */ - m68k.memory_map[0x61].base = m68k.memory_map[0x69].base = cart.rom + 0x080000 + ((data & 0x1c) << 14); - break; - } - - default: - { - /* unknown mode */ - break; - } - } - - /* $600003 data register */ - sram.sram[0x01] = data; - } - else - { - /* $600001 ctrl register */ - sram.sram[0x00] = data; - } - return; - } - - case 0x01: /* $61xxxx */ - { - if (address & 2) - { - /* $610003 ctrl register */ - sram.sram[0x02] = data; - } - return; - } - - case 0x04: /* $64xxxx */ - { - if (address & 2) - { - /* $640003 data register */ - sram.sram[0x04] = data; - } - else - { - /* $640001 data register */ - sram.sram[0x03] = data; - } - return; - } - - case 0x06: /* $66xxxx */ - { - /* unknown */ - return; - } - - case 0x07: /* $67xxxx */ - { - if (!(address & 2)) - { - /* $670001 ctrl register */ - sram.sram[0x05] = data; - - /* upper 512K ROM bank-switching enabled ? */ - if (sram.sram[0x02] & 0x80) - { - /* update selected ROM bank (upper 512K) mapped at $600000-$60ffff */ - m68k.memory_map[0x60].base = m68k.memory_map[0x68].base = cart.rom + 0x080000 + ((data & 0x1c) << 14); - } - } - return; - } - - default: /* not used */ - { - m68k_unused_8_w(address, data); - return; - } - } -} - -static uint32 mapper_smw_64_r(uint32 address) -{ - /* internal registers (saved to backup RAM) */ - switch ((address >> 16) & 0x03) - { - case 0x02: /* $66xxxx */ - { - switch ((address >> 1) & 7) - { - case 0x00: return sram.sram[0x06]; - case 0x01: return sram.sram[0x06] + 1; - case 0x02: return sram.sram[0x07]; - case 0x03: return sram.sram[0x07] + 1; - case 0x04: return sram.sram[0x08]; - case 0x05: return sram.sram[0x08] + 1; - case 0x06: return sram.sram[0x08] + 2; - case 0x07: return sram.sram[0x08] + 3; - } - } - - case 0x03: /* $67xxxx */ - { - uint8 data = (sram.sram[0x02] & 0x80) ? ((sram.sram[0x05] & 0x40) ? (sram.sram[0x03] & sram.sram[0x04]) : (sram.sram[0x03] ^ 0xFF)) : 0x00; - - if (address & 2) - { - /* $670003 */ - data &= 0x7f; - } - else - { - /* $66xxxx data registers update */ - if (sram.sram[0x05] & 0x80) - { - if (sram.sram[0x05] & 0x20) - { - /* update $660009-$66000f data register */ - sram.sram[0x08] = (sram.sram[0x04] << 2) & 0xFC; - } - else - { - /* update $660001-$660003 data register */ - sram.sram[0x06] = (sram.sram[0x01] ^ (sram.sram[0x03] << 1)) & 0xFE; - } - } - } - - return data; - } - - default: /* 64xxxx-$65xxxx */ - { - return 0x00; - } - } -} - -/* - Realtec ROM bankswitch (Earth Defend, Balloon Boy & Funny World, Whac-A-Critter) - (Note: register usage is inverted in TascoDlx documentation) -*/ -static void mapper_realtec_w(uint32 address, uint32 data) -{ - switch (address) - { - case 0x402000: - { - /* number of mapped 64k blocks (the written value is a number of 128k blocks) */ - cart.hw.regs[2] = data << 1; - return; - } - - case 0x404000: - { - /* 00000xxx */ - cart.hw.regs[0] = data & 7; - return; - } - - case 0x400000: - { - /* 00000yy1 */ - cart.hw.regs[1] = data & 6; - - /* ensure mapped size is not null */ - if (cart.hw.regs[2]) - { - /* mapped start address is 00yy xxx0 0000 0000 0000 0000 */ - uint32 base = (cart.hw.regs[0] << 1) | (cart.hw.regs[1] << 3); - - /* selected blocks are mirrored into the whole cartridge area */ - int i; - for (i=0x00; i<0x40; i++) - { - m68k.memory_map[i].base = &cart.rom[(base + (i % cart.hw.regs[2])) << 16]; - } - } - return; - } - } -} - -/* Game no Kanzume Otokuyou ROM Mapper */ -static void mapper_seganet_w(uint32 address, uint32 data) -{ - if ((address & 0xff) == 0xf1) - { - int i; - if (data & 1) - { - /* ROM Write protected */ - for (i=0; i<0x40; i++) - { - m68k.memory_map[i].write8 = m68k_unused_8_w; - m68k.memory_map[i].write16 = m68k_unused_16_w; - zbank_memory_map[i].write = zbank_unused_w; - } - } - else - { - /* ROM Write enabled */ - for (i=0; i<0x40; i++) - { - m68k.memory_map[i].write8 = NULL; - m68k.memory_map[i].write16 = NULL; - zbank_memory_map[i].write = NULL; - } - } - } -} - -/* - Custom ROM Bankswitch used in Soul Edge VS Samurai Spirits, Top Fighter, Mulan, Pocket Monsters II, Lion King 3, Super King Kong 99, Pokemon Stadium -*/ -static void mapper_32k_w(uint32 data) -{ - int i; - - /* 64 x 32k banks */ - if (data) - { - for (i=0; i<0x10; i++) - { - /* Remap to unused ROM area */ - m68k.memory_map[i].base = &cart.rom[0x400000 + (i << 16)]; - - /* address = address OR (value << 15) */ - memcpy(m68k.memory_map[i].base, cart.rom + ((i << 16) | (data & 0x3f) << 15), 0x8000); - memcpy(m68k.memory_map[i].base + 0x8000, cart.rom + ((i << 16) | ((data | 1) & 0x3f) << 15), 0x8000); - } - } - else - { - /* reset default $000000-$0FFFFF mapping */ - for (i=0; i<16; i++) - { - m68k.memory_map[i].base = &cart.rom[i << 16]; - } - } -} - -/* - Custom ROM Bankswitch used in Chinese Fighter III -*/ -static void mapper_64k_w(uint32 data) -{ - int i; - - /* 16 x 64k banks */ - if (data) - { - /* bank is mapped at $000000-$0FFFFF */ - for (i=0; i<16; i++) - { - m68k.memory_map[i].base = &cart.rom[(data & 0xf) << 16]; - } - } - else - { - /* reset default $000000-$0FFFFF mapping */ - for (i=0; i<16; i++) - { - m68k.memory_map[i].base = &cart.rom[(i & 0xf) << 16]; - } - } -} - -/* - Custom ROM Bankswitch used in pirate "Multi-in-1" cartridges, A Bug's Life, King of Fighter 99, Pocket Monster, Rockman X3 - */ -static void mapper_64k_multi_w(uint32 address) -{ - int i; - - /* 64 x 64k banks */ - for (i=0; i<64; i++) - { - m68k.memory_map[i].base = &cart.rom[((address++) & 0x3f) << 16]; - } -} - -/* - Custom ROM Bankswitch used in RADICA cartridges -*/ -static uint32 mapper_radica_r(uint32 address) -{ - int i = 0; - address = (address >> 1); - - /* 64 x 64k banks */ - for (i = 0; i < 64; i++) - { - m68k.memory_map[i].base = &cart.rom[((address++)& 0x3f)<< 16]; - } - - return 0xffff; -} - - -/************************************************************ - default !TIME signal handler -*************************************************************/ - -static void default_time_w(uint32 address, uint32 data) -{ - if (address < 0xa13040) - { - /* unlicensed cartridges mapper (default) */ - mapper_64k_multi_w(address); - return; - } - - /* official cartridges mapper (default) */ - mapper_sega_w(data); -} - - -/************************************************************ - Internal register handlers -*************************************************************/ - -static uint32 default_regs_r(uint32 address) -{ - int i; - for (i=0; i<4; i++) - { - if ((address & cart.hw.mask[i]) == cart.hw.addr[i]) - { - return cart.hw.regs[i]; - } - } - return m68k_read_bus_8(address); -} - -static uint32 default_regs_r_16(uint32 address) -{ - int i; - for (i=0; i<4; i++) - { - if ((address & cart.hw.mask[i]) == cart.hw.addr[i]) - { - return (cart.hw.regs[i] << 8); - } - } - return m68k_read_bus_16(address); -} - -static void default_regs_w(uint32 address, uint32 data) -{ - int i; - for (i=0; i<4; i++) - { - if ((address & cart.hw.mask[i]) == cart.hw.addr[i]) - { - cart.hw.regs[i] = data; - return; - } - } - m68k_unused_8_w(address, data); -} - -/* basic register shifting hardware (Bug's Life, Pocket Monster) */ -static uint32 custom_regs_r(uint32 address) -{ - int i; - for (i=0; i<4; i++) - { - if ((address & cart.hw.mask[i]) == cart.hw.addr[i]) - { - return cart.hw.regs[i] >> 1; - } - } - - return m68k_read_bus_8(address); -} - -/* custom register hardware (Top Fighter, Lion King III, Super Donkey Kong 99, Mulan, Pocket Monsters II, Pokemon Stadium) */ -static void custom_regs_w(uint32 address, uint32 data) -{ - uint8 temp; - - /* ROM bankswitch */ - if ((address >> 16) > 0x6f) - { - mapper_32k_w(data); - return; - } - - /* write register */ - default_regs_w(address, data); - - /* bitswapping */ - temp = cart.hw.regs[0]; - switch (cart.hw.regs[1] & 3) - { - case 0: - cart.hw.regs[2] = (temp << 1); - break; - - case 1: - cart.hw.regs[2] = (temp >> 1); - return; - - case 2: - cart.hw.regs[2] = ((temp >> 4) | ((temp & 0x0F) << 4)); - return; - - default: - cart.hw.regs[2] = (((temp >> 7) & 0x01) | ((temp >> 5) & 0x02) | - ((temp >> 3) & 0x04) | ((temp >> 1) & 0x08) | - ((temp << 1) & 0x10) | ((temp << 3) & 0x20) | - ((temp << 5) & 0x40) | ((temp << 7) & 0x80)); - return; - } -} - -/* alternate custom register hardware (Chinese Fighters III) */ -static void custom_alt_regs_w(uint32 address, uint32 data) -{ - /* ROM bankswitch */ - if ((address >> 16) > 0x5f) - { - mapper_64k_w(data); - return; - } - - /* write regs */ - default_regs_w(address, data); -} - - -/* "Tekken 3 Special" custom register hardware */ -static uint32 tekken_regs_r(uint32 address) -{ - /* data output */ - if ((address & 0x0e) == 0x02) - { - /* maybe depends on mode bits ? */ - return (cart.hw.regs[0] - 1); - } - - return m68k_read_bus_16(address); -} - -static void tekken_regs_w(uint32 address, uint32 data) -{ - switch (address & 0x0e) - { - case 0x00: - { - /* data output reset ? (game writes $FF before & after protection check) */ - cart.hw.regs[0]= 0x00; - break; - } - - case 0x02: - { - /* read only ? */ - break; - } - - case 0x0c: - { - /* data output mode bit 0 ? (game writes $01) */ - break; - } - - case 0x0e: - { - /* data output mode bit 1 ? (never written by game) */ - break; - } - - default: - { - /* data input (only connected to D0 ?)*/ - if (data & 1) - { - /* 4-bit hardware register ($400004 corresponds to bit0, $400006 to bit1, etc) */ - cart.hw.regs[0] |= 1 << (((address - 0x04) >> 1) & 3); - } - break; - } - } -} - -/* "Top Shooter" arcade board hardware */ -static uint32 topshooter_r(uint32 address) -{ - if (address < 0x202000) - { - uint8 temp = 0xff; - - switch (address & 0xff) - { - case 0x43: - { - if (input.pad[0] & INPUT_A) temp &= ~0x80; /* Shoot */ - if (input.pad[0] & INPUT_B) temp &= ~0x10; /* Bet */ - if (input.pad[0] & INPUT_START) temp &= ~0x20; /* Start */ - break; - } - - case 0x45: /* ??? (DOWN) & Service Mode (UP) */ - { - if (input.pad[0] & INPUT_UP) temp &= ~0x08; /* Service Mode */ - if (input.pad[0] & INPUT_DOWN) temp &= ~0x10; /* ???, used in service menu to select next option */ - break; - } - - case 0x47: - { - if (input.pad[0] & INPUT_RIGHT) temp &= ~0x03; /* Insert 10 coins */ - break; - } - - case 0x49: - { - if (input.pad[0] & INPUT_LEFT) temp &= ~0x03; /* Clear coins */ - if (input.pad[0] & INPUT_C) temp &= ~0x01; /* Insert XXX coins */ - break; - } - - case 0x51: - { - temp = 0xA5; - break; - } - - default: - { - temp = m68k_read_bus_8(address); - break; - } - } - return temp; - } - - return READ_BYTE(sram.sram , address & 0xffff); -} - -static void topshooter_w(uint32 address, uint32 data) -{ - if (address >= 0x202000) - { - WRITE_BYTE(sram.sram , address & 0xffff, data); - return; - } - - m68k_unused_8_w(address, data); -} - - -/* Sega Channel hardware (not emulated) */ -/* - -$A13004: BUSY ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? - -Unused read16 00A13004 (00005B54) -Unused read16 00A13004 (00005B70) -Unused read16 00A13006 (00005B7C) - -Unused read16 00A13004 (00005BC4) -Unused read16 00A13004 (00005BDA) - -Unused write16 00A13032 = 0004 (00005706) -Unused write16 00A130F0 = 0000 (0000570E) - -Unused write16 00A130F0 = 0000 (0000463E) -Unused write16 00A130F2 = 0001 (00004646) -Unused write16 00A130F4 = 0002 (0000464E) -Unused write16 00A130F6 = 0003 (00004656) -Unused write16 00A130F8 = 0004 (0000465E) -Unused write16 00A130FA = 0005 (00004666) - -Unused write16 00A13032 = 0004 (00005706) -Unused write16 00A13032 = 0104 (0000579E) - -Unused write16 00380000 = ACDC (00005718) -Unused write16 00380002 = 0000 (00005722) -Unused read16 00380000 (0000572C) -Unused write16 00A13032 = 0104 (0000579E) -Unused write16 00300000 = ACDC (000057B2) -Unused write16 00380000 = 0000 (000057BC) -Unused read16 00300000 (000057C6) - -static uint32 sega_channel_r(uint32 address) -{ - return m68k_read_bus_16(address);; -} - -static void sega_channel_w(uint32 address, uint32 data) -{ - m68k_unused_16_w(address, data); -} -*/ +/**************************************************************************** + * Genesis Plus + * Mega Drive cartridge hardware support + * + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Many cartridge protections were initially documented by Haze + * (http://haze.mameworld.info/) + * + * Realtec mapper was documented by TascoDeluxe + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "eeprom_i2c.h" +#include "eeprom_spi.h" +#include "gamepad.h" + +#define CART_CNT (55) + +/* Cart database entry */ +typedef struct +{ + uint16 chk_1; /* header checksum */ + uint16 chk_2; /* real checksum */ + uint8 bank_start; /* first mapped bank in $400000-$7fffff region */ + uint8 bank_end; /* last mapped bank in $400000-$7fffff region */ + cart_hw_t cart_hw; /* hardware description */ +} md_entry_t; + +/* Function prototypes */ +static void mapper_sega_w(uint32 data); +static void mapper_ssf2_w(uint32 address, uint32 data); +static void mapper_sf001_w(uint32 address, uint32 data); +static void mapper_sf002_w(uint32 address, uint32 data); +static void mapper_sf004_w(uint32 address, uint32 data); +static uint32 mapper_sf004_r(uint32 address); +static void mapper_t5740_w(uint32 address, uint32 data); +static uint32 mapper_t5740_r(uint32 address); +static uint32 mapper_smw_64_r(uint32 address); +static void mapper_smw_64_w(uint32 address, uint32 data); +static void mapper_realtec_w(uint32 address, uint32 data); +static void mapper_seganet_w(uint32 address, uint32 data); +static void mapper_32k_w(uint32 data); +static void mapper_64k_w(uint32 data); +static void mapper_64k_multi_w(uint32 address); +static uint32 mapper_radica_r(uint32 address); +static void default_time_w(uint32 address, uint32 data); +static void default_regs_w(uint32 address, uint32 data); +static uint32 default_regs_r(uint32 address); +static uint32 default_regs_r_16(uint32 address); +static uint32 custom_regs_r(uint32 address); +static void custom_regs_w(uint32 address, uint32 data); +static void custom_alt_regs_w(uint32 address, uint32 data); +static uint32 topshooter_r(uint32 address); +static void topshooter_w(uint32 address, uint32 data); +static uint32 tekken_regs_r(uint32 address); +static void tekken_regs_w(uint32 address, uint32 data); + +/* Games that need extra hardware emulation: + - copy protection device + - custom ROM banking device +*/ +static const md_entry_t rom_database[CART_CNT] = +{ +/* Funny World & Balloon Boy */ + {0x0000,0x06ab,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},1,0,NULL,NULL,NULL,mapper_realtec_w}}, +/* Whac-a-Critter */ + {0xffff,0xf863,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},1,0,NULL,NULL,NULL,mapper_realtec_w}}, +/* Earth Defense */ + {0xffff,0x44fb,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},1,0,NULL,NULL,NULL,mapper_realtec_w}}, + + +/* RADICA (Volume 1) (bad dump ?) */ + {0x0000,0x2326,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,1,mapper_radica_r,NULL,NULL,NULL}}, +/* RADICA (Volume 1) */ + {0x24f4,0xfc84,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,mapper_radica_r,NULL,NULL,NULL}}, +/* RADICA (Volume 2) */ + {0x104f,0x32e9,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,mapper_radica_r,NULL,NULL,NULL}}, + + +/* Tenchi wo Kurau III: Sangokushi Gaiden - Chinese Fighter */ + {0x9490,0x8180,0x40,0x6f,{{0x00,0x00,0x00,0x00},{0xf0000c,0xf0000c,0xf0000c,0xf0000c},{0x400000,0x400004,0x400008,0x40000c},0,1,NULL,NULL,default_regs_r,custom_alt_regs_w}}, + + +/* Top Fighter */ + {0x4eb9,0x5d8b,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, +/* Soul Edge VS Samurai Spirits */ + {0x00ff,0x5d34,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, +/* Mulan */ + {0x0404,0x1b40,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, +/* Pocket Monsters II */ + {0x47f9,0x17e5,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, +/* Lion King 3 */ + {0x0000,0x507c,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, +/* Super King Kong 99 */ + {0x0000,0x7d6e,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, +/* Gunfight 3-in-1 */ + {0x0000,0x6ff8,0x60,0x7f,{{0x00,0x00,0x00,0x00},{0xf00007,0xf00007,0xf00007,0xffffff},{0x600001,0x600003,0x600005,0x000000},0,1,NULL,NULL,default_regs_r,custom_regs_w}}, +/* Pokemon Stadium */ + {0x0000,0x843c,0x70,0x7f,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,1,NULL,NULL,NULL,custom_regs_w}}, + + +/* Tekken 3 Special (original dump) (a bootleg version also exists, with patched protection & different boot routine which reads unused !TIME mapped area) */ + {0x0000,0xc2f0,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,NULL,NULL,tekken_regs_r,tekken_regs_w}}, + + +/* Lion King 2 */ + {0xffff,0x1d9b,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, +/* Squirell King */ + {0x0000,0x8ec8,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, +/* Tiny Toon Adventures 3 */ + {0x2020,0xed9c,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, +/* Lian Huan Pao - Barver Battle Saga (registers accessed by Z80, related to sound engine ?) */ + {0x30b9,0x1c2a,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, +/* Shui Hu Zhuan (registers accessed by Z80, related to sound engine ?) */ + {0x6001,0x0211,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, +/* Feng Shen Ying Jie Chuan (registers accessed by Z80, related to sound engine ?) */ + {0xffff,0x5d98,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, +/* (*) Shui Hu - Feng Yun Zhuan (patched ROM, unused registers) */ + {0x3332,0x872b,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xfffffd,0xfffffd,0xffffff,0xffffff},{0x400000,0x400004,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,default_regs_w}}, + + +/* (*) Chao Ji Da Fu Weng (patched ROM, various words witten to register, long word also read from $7E0000, unknown banking hardware ?) */ + {0xa697,0xa697,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x000000,0x000000,0x000000},0,0,NULL,NULL,NULL,default_regs_w}}, + +/* (*) Aq Renkan Awa (patched ROM, ON/OFF bit sequence is written to register, unknown banking hardware ?) */ + {0x8104,0x0517,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400001,0x000000,0x000000,0x000000},0,0,NULL,NULL,NULL,default_regs_w}}, + + +/* (*) Tun Shi Tian Di III (patched ROM, unused register) */ + {0x0000,0x9c5e,0x40,0x40,{{0xab,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400046,0x000000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, + + +/* Ma Jiang Qing Ren - Ji Ma Jiang Zhi */ + {0x0000,0x7037,0x40,0x40,{{0x90,0xd3,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x401000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Super Majon Club */ + {0x0000,0x3b95,0x40,0x40,{{0x90,0xd3,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x401000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Feng Kuang Tao Hua Yuan (original version from Creaton Softec Inc) (a bootleg version also exists with patched protection and minor title screen variations) */ + {0x0000,0x9dc4,0x40,0x40,{{0x90,0xd3,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x401000,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, + + +/* (*) Jiu Ji Ma Jiang II - Ye Yan Bian (patched ROM, using expected register value - $0f - crashes the game) (uses 16-bits reads) */ + {0x0c44,0xba81,0x40,0x40,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x400006},0,0,NULL,NULL,default_regs_r_16,NULL}}, +/* 16 Zhang Ma Jiang (uses 16-bits reads) */ + {0xfb40,0x4bed,0x40,0x40,{{0x00,0xaa,0x00,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x400002,0x000000,0x400006},0,0,NULL,NULL,default_regs_r_16,NULL}}, +/* 16 Tiles Mahjong II (uses 16-bits reads) */ + {0xffff,0x0903,0x40,0x40,{{0x00,0x00,0xc9,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x400004,0x000000},0,0,NULL,NULL,default_regs_r_16,NULL}}, +/* Thunderbolt II (uses 16-bits reads) */ + {0x0000,0x1585,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r_16,NULL}}, + + +/* Super Bubble Bobble */ + {0x0000,0x16cd,0x40,0x40,{{0x55,0x0f,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x000000,0x000000},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Tenchi wo Kurau II - The Battle of Red Cliffs (Unl) */ + {0x0000,0xed61,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Huan Le Tao Qi Shu - Smart Mouse */ + {0x0000,0x1a28,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, +/* (*) Hei Tao 2 - Super Big 2 (patched ROM, unused registers) */ + {0x0000,0x5843,0x40,0x40,{{0x55,0x0f,0xaa,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Mighty Morphin Power Rangers - The Fighting Edition */ + {0x0000,0x2288,0x40,0x40,{{0x55,0x0f,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Elf Wor */ + {0x0080,0x3dba,0x40,0x40,{{0x55,0x0f,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Ya-Se Chuanshuo */ + {0xffff,0xd472,0x40,0x40,{{0x63,0x98,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, +/* 777 Casino (For first one, 0x55 works as well. Other values are never used so they are guessed from on other unlicensed games using similar mapper) */ + {0x0000,0xf8d9,0x40,0x40,{{0x63,0x98,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Wu Kong Wai Zhuan (original) (a bootleg version also exists, with patched protection & modified SRAM test routine ?) */ + {0x0000,0x19ff,0x40,0x40,{{0x63,0x98,0xc9,0x18},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, +/* Soul Blade */ + {0x0000,0x0c5b,0x40,0x40,{{0x63,0x98,0xc9,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0x400000,0x400002,0x400004,0x400006},0,0,NULL,NULL,default_regs_r,NULL}}, + + +/* King of Fighter 98 */ + {0x0000,0xd0a0,0x48,0x4f,{{0x00,0x00,0xaa,0xf0},{0xffffff,0xffffff,0xfc0000,0xfc0000},{0x000000,0x000000,0x480000,0x4c0000},0,0,NULL,NULL,default_regs_r,NULL}}, + + +/* Rockman X3 (bootleg version ? two last register returned values are ignored, note that 0xaa/0x18 would work as well) */ + {0x0000,0x9d0e,0x40,0x40,{{0x0c,0x00,0xc9,0xf0},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0x000000,0x400004,0x400006},0,0,default_regs_r,NULL,default_regs_r,NULL}}, + + +/* (*) Dragon Ball Final Bout (patched ROM, in original code, different switches occurs depending on returned value $00-$0f) */ + {0xc65a,0xc65a,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, +/* (*) Yang Jia Jiang - Yang Warrior Family (patched ROM, register value unused) */ + {0x0000,0x96b0,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, +/* Super Mario 2 1998 */ + {0xffff,0x0474,0x00,0x00,{{0x0a,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, +/* Super Mario World */ + {0x2020,0xb4eb,0x00,0x00,{{0x1c,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0x000000,0x000000,0x000000},0,0,default_regs_r,NULL,NULL,NULL}}, + + +/* King of Fighter 99 */ + {0x0000,0x021e,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,custom_regs_r,default_regs_w,NULL,NULL}}, +/* Pocket Monster */ + {0xd6fc,0x1eb1,0x00,0x00,{{0x00,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,custom_regs_r,default_regs_w,NULL,NULL}}, +/* Pocket Monster (bootleg version ? two last register returned values are ignored & first register test has been modified) */ + {0xd6fc,0x6319,0x00,0x00,{{0x14,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,default_regs_r,m68k_unused_8_w,NULL,NULL}}, +/* A Bug's Life (bootleg version ? two last register returned values are ignored & first register test has been modified ?) */ + {0x7f7f,0x2aad,0x00,0x00,{{0x28,0x01,0x1f,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0xa13000,0xa13002,0xa1303e,0x000000},0,0,default_regs_r,m68k_unused_8_w,NULL,NULL}}, + + +/* Game no Kanzume Otokuyou */ + {0x0000,0xf9d1,0x00,0x00,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,NULL,mapper_seganet_w,NULL,NULL}}, + + +/* Top Shooter (arcade hardware) */ + {0xffff,0x3632,0x20,0x20,{{0x00,0x00,0x00,0x00},{0xffffff,0xffffff,0xffffff,0xffffff},{0x000000,0x000000,0x000000,0x000000},0,0,NULL,NULL,topshooter_r,topshooter_w}} +}; + + +/************************************************************ + Cart Hardware initialization +*************************************************************/ + +void md_cart_init(void) +{ + int i; + + /*************************************************************************************************************** + CARTRIDGE ROM MIRRORING + *************************************************************************************************************** + + MD Cartridge area is mapped to $000000-$3fffff: + + -> when accessing ROM, 68k address lines A1 to A21 can be used by the internal cartridge hardware to decode + full 4MB address range. + -> depending on ROM total size and additional decoding hardware, some address lines might be ignored, + resulting in ROM mirroring. + + Cartridges can use either 8-bits (x2) or 16-bits (x1, x2) Mask ROM chips, each chip size is a factor of 2 bytes: + + -> two 8-bits chips are equivalent to one 16-bits chip, no specific address decoding is required, needed + address lines are simply connected to each chip, upper address lines are ignored and data lines are + connected appropriately to each chip (D0-D7 to one chip, D8-D15 to the other one). + ROM is generally mirrored each N bytes where N=2^(k+1) is the total ROM size (ROM1+ROM2,ROM1+ROM2,...) + + -> one single 16-bits chip do not need specific address decoding, address lines are simply connected + depending on the ROM size, upper address lines being ignored. + ROM is generally mirrored each N bytes where N=2^k is the size of the ROM chip (ROM1,ROM1,ROM1,...) + + -> two 16-bits chips of the same size are equivalent to one chip of double size, address decoding generally + is the same except that specific hardware is used (one address line is generally used for chip selection, + lower ones being used to address the chips and upper ones being ignored). + ROM is generally mirrored each N bytes where N=2^(k+1) is the total ROM size (ROM1,ROM2,ROM1,ROM2,...) + + -> two 16-bits chips with different size are mapped differently. Address decoding is done the same way as + above (one address line used for chip selection) but the ignored & required address lines differ from + one chip to another, which makes ROM mirroring different. + ROM2 size is generally half of ROM1 size and upper half ignored (ROM1,ROM2,XXXX,ROM1,ROM2,XXXX,...) + + From the emulator point of view, we only need to distinguish 2 cases: + + 1/ total ROM size is a factor of 2: ROM is mirrored each 2^k bytes. + + 2/ total ROM size is not a factor of 2: ROM is padded up to 2^k then mirrored each 2^k bytes. + + ******************************************************************************************************************/ + + /* calculate nearest size with factor of 2 */ + unsigned int size = 0x10000; + while (cart.romsize > size) + size <<= 1; + + /* Sonic & Knuckles */ + if (strstr(rominfo.international,"SONIC & KNUCKLES")) + { + /* disable ROM mirroring at $200000-$3fffff (normally mapped to external cartridge) */ + size = 0x400000; + } + + /* total ROM size is not a factor of 2 */ + /* TODO: handle all possible ROM configurations using cartridge database */ + if (cart.romsize < size) + { + if (size < MAXROMSIZE) + { + /* ROM is padded up to 2^k bytes */ + memset(cart.rom + cart.romsize, 0xff, size - cart.romsize); + } + else + { + /* ROM is padded up to max ROM size */ + memset(cart.rom + cart.romsize, 0xff, MAXROMSIZE - cart.romsize); + } + } + + /* ROM is mirrored each 2^k bytes */ + cart.mask = size - 1; + + /********************************************** + DEFAULT CARTRIDGE MAPPING + ***********************************************/ + for (i=0; i<0x40; i++) + { + /* cartridge ROM */ + m68k.memory_map[i].base = cart.rom + ((i<<16) & cart.mask); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + m68k.memory_map[i].write8 = m68k_unused_8_w; + m68k.memory_map[i].write16 = m68k_unused_16_w; + zbank_memory_map[i].read = NULL; + zbank_memory_map[i].write = zbank_unused_w; + } + + for (i=0x40; i<0x80; i++) + { + /* unused area */ + m68k.memory_map[i].base = cart.rom + (i<<16); + m68k.memory_map[i].read8 = m68k_read_bus_8; + m68k.memory_map[i].read16 = m68k_read_bus_16; + m68k.memory_map[i].write8 = m68k_unused_8_w; + m68k.memory_map[i].write16 = m68k_unused_16_w; + zbank_memory_map[i].read = zbank_unused_r; + zbank_memory_map[i].write = zbank_unused_w; + } + + /* support for Quackshot REV 01 (real) dump */ + if (strstr(rominfo.product,"00004054-01") && (cart.romsize == 0x80000)) + { + /* $000000-$0fffff: first 256K mirrored (A18 not connected to ROM chip, A19 not decoded) */ + for (i=0x00; i<0x10; i++) + { + /* $200000-$3fffff: mirror of $000000-$1fffff (A21 not decoded) */ + m68k.memory_map[i].base = m68k.memory_map[i + 0x20].base = cart.rom + ((i & 0x03) << 16); + } + + /* $100000-$1fffff: second 256K mirrored (A20 connected to ROM chip A18) */ + for (i=0x10; i<0x20; i++) + { + /* $200000-$3fffff: mirror of $000000-$1fffff (A21 not decoded) */ + m68k.memory_map[i].base = m68k.memory_map[i + 0x20].base = cart.rom + 0x40000 + ((i & 0x03) << 16); + } + } + + /********************************************** + BACKUP MEMORY + ***********************************************/ + sram_init(); + eeprom_i2c_init(); + + /* external SRAM */ + if (sram.on && !sram.custom) + { + /* disabled on startup if ROM is mapped in same area */ + if (cart.romsize <= sram.start) + { + /* initialize m68k bus handlers */ + m68k.memory_map[sram.start >> 16].base = sram.sram; + m68k.memory_map[sram.start >> 16].read8 = sram_read_byte; + m68k.memory_map[sram.start >> 16].read16 = sram_read_word; + m68k.memory_map[sram.start >> 16].write8 = sram_write_byte; + m68k.memory_map[sram.start >> 16].write16 = sram_write_word; + zbank_memory_map[sram.start >> 16].read = sram_read_byte; + zbank_memory_map[sram.start >> 16].write = sram_write_byte; + } + } + + /********************************************** + SVP CHIP + ***********************************************/ + svp = NULL; + if (strstr(rominfo.international,"Virtua Racing")) + { + svp_init(); + } + + /********************************************** + J-CART + ***********************************************/ + cart.special = 0; + if ((strstr(rominfo.product,"00000000") && (rominfo.checksum == 0x168b)) || /* Super Skidmarks, Micro Machines Military */ + (strstr(rominfo.product,"00000000") && (rominfo.checksum == 0x165e)) || /* Pete Sampras Tennis (1991), Micro Machines 96 */ + (strstr(rominfo.product,"00000000") && (rominfo.checksum == 0xcee0)) || /* Micro Machines Military (bad) */ + (strstr(rominfo.product,"00000000") && (rominfo.checksum == 0x2c41)) || /* Micro Machines 96 (bad) */ + (strstr(rominfo.product,"XXXXXXXX") && (rominfo.checksum == 0xdf39)) || /* Sampras Tennis 96 */ + (strstr(rominfo.product,"T-123456") && (rominfo.checksum == 0x1eae)) || /* Sampras Tennis 96 */ + (strstr(rominfo.product,"T-120066") && (rominfo.checksum == 0x16a4)) || /* Pete Sampras Tennis (1994)*/ + strstr(rominfo.product,"T-120096")) /* Micro Machines 2 */ + { + if (cart.romsize <= 0x380000) /* just to be sure (checksum might not be enough) */ + { + cart.special |= HW_J_CART; + + /* force port 1 setting */ + if (input.system[1] != SYSTEM_WAYPLAY) + { + old_system[1] = input.system[1]; + input.system[1] = SYSTEM_MD_GAMEPAD; + } + + /* extra connectors mapped at $38xxxx or $3Fxxxx */ + m68k.memory_map[0x38].read16 = jcart_read; + m68k.memory_map[0x38].write16 = jcart_write; + m68k.memory_map[0x3f].read16 = jcart_read; + m68k.memory_map[0x3f].write16 = jcart_write; + } + } + + /********************************************** + LOCK-ON + ***********************************************/ + + /* clear existing patches */ + ggenie_shutdown(); + areplay_shutdown(); + + /* initialize extra hardware */ + switch (config.lock_on) + { + case TYPE_GG: + { + ggenie_init(); + break; + } + + case TYPE_AR: + { + areplay_init(); + break; + } + + case TYPE_SK: + { + FILE *f; + + /* store S&K ROM above cartridge ROM (and before backup memory) */ + if (cart.romsize > 0x600000) break; + + /* load Sonic & Knuckles ROM (2 MB) */ + f = fopen(SK_ROM,"rb"); + if (!f) break; + for (i=0; i<0x200000; i+=0x1000) + { + fread(cart.rom + 0x600000 + i, 0x1000, 1, f); + } + fclose(f); + + /* load Sonic 2 UPMEM ROM (256 KB) */ + f = fopen(SK_UPMEM,"rb"); + if (!f) break; + for (i=0; i<0x40000; i+=0x1000) + { + fread(cart.rom + 0x900000 + i, 0x1000, 1, f); + } + fclose(f); + +#ifdef LSB_FIRST + for (i=0; i<0x200000; i+=2) + { + /* Byteswap ROM */ + uint8 temp = cart.rom[i + 0x600000]; + cart.rom[i + 0x600000] = cart.rom[i + 0x600000 + 1]; + cart.rom[i + 0x600000 + 1] = temp; + } + + for (i=0; i<0x40000; i+=2) + { + /* Byteswap ROM */ + uint8 temp = cart.rom[i + 0x900000]; + cart.rom[i + 0x900000] = cart.rom[i + 0x900000 + 1]; + cart.rom[i + 0x900000 + 1] = temp; + } +#endif + + /* $000000-$1FFFFF is mapped to S&K ROM */ + for (i=0x00; i<0x20; i++) + { + m68k.memory_map[i].base = cart.rom + 0x600000 + (i << 16); + } + + cart.special |= HW_LOCK_ON; + break; + } + + default: + { + break; + } + } + + /********************************************** + CARTRIDGE EXTRA HARDWARE + ***********************************************/ + memset(&cart.hw, 0, sizeof(cart.hw)); + + /* search for game into database */ + for (i=0; i 0x400000) + { + /* assume linear ROM mapper without bankswitching (max. 10MB) */ + for (i=0x40; i<0xA0; i++) + { + m68k.memory_map[i].base = cart.rom + (i<<16); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + zbank_memory_map[i].read = NULL; + } + } + + /* default write handler for !TIME range ($A130xx)*/ + if (!cart.hw.time_w) + { + cart.hw.time_w = default_time_w; + } +} + +/* hardware that need to be reseted on power on */ +void md_cart_reset(int hard_reset) +{ + int i; + + /* reset cartridge mapping */ + if (cart.hw.bankshift) + { + for (i=0x00; i<0x40; i++) + { + m68k.memory_map[i].base = cart.rom + ((i<<16) & cart.mask); + } + } + + /* SVP chip */ + if (svp) + { + svp_reset(); + } + + /* Lock-ON */ + switch (config.lock_on) + { + case TYPE_GG: + { + ggenie_reset(hard_reset); + break; + } + + case TYPE_AR: + { + areplay_reset(hard_reset); + break; + } + + case TYPE_SK: + { + if (cart.special & HW_LOCK_ON) + { + /* disable UPMEM chip at $300000-$3fffff */ + for (i=0x30; i<0x40; i++) + { + m68k.memory_map[i].base = cart.rom + ((i<<16) & cart.mask); + } + } + break; + } + + default: + { + break; + } + } +} + + +/************************************************************ + MAPPER handlers +*************************************************************/ + +/* + "official" ROM/SRAM bankswitch (Phantasy Star IV, Story of Thor/Beyond Oasis, Sonic 3 & Knuckles) +*/ +static void mapper_sega_w(uint32 data) +{ + int i; + + if (data & 1) + { + if (sram.on) + { + /* Backup RAM mapped to $200000-$20ffff (normally mirrored up to $3fffff but this breaks Sonic Megamix and no game need it) */ + m68k.memory_map[0x20].base = sram.sram; + m68k.memory_map[0x20].read8 = sram_read_byte; + m68k.memory_map[0x20].read16 = sram_read_word; + zbank_memory_map[0x20].read = sram_read_byte; + + /* Backup RAM write protection */ + if (data & 2) + { + m68k.memory_map[0x20].write8 = m68k_unused_8_w; + m68k.memory_map[0x20].write16 = m68k_unused_16_w; + zbank_memory_map[0x20].write = zbank_unused_w; + } + else + { + m68k.memory_map[0x20].write8 = sram_write_byte; + m68k.memory_map[0x20].write16 = sram_write_word; + zbank_memory_map[0x20].write = sram_write_byte; + } + } + + /* S&K lock-on chip */ + if ((cart.special & HW_LOCK_ON) && (config.lock_on == TYPE_SK)) + { + /* S2K upmem chip mapped to $300000-$3fffff (256K mirrored) */ + for (i=0x30; i<0x40; i++) + { + m68k.memory_map[i].base = (cart.rom + 0x900000) + ((i & 3) << 16); + } + } + } + else + { + /* cartridge ROM mapped to $200000-$3fffff */ + for (i=0x20; i<0x40; i++) + { + m68k.memory_map[i].base = cart.rom + ((i<<16) & cart.mask); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + zbank_memory_map[i].read = NULL; + m68k.memory_map[i].write8 = m68k_unused_8_w; + m68k.memory_map[i].write16 = m68k_unused_16_w; + zbank_memory_map[i].write = zbank_unused_w; + } + } +} + +/* + Super Street Fighter 2 ROM bankswitch + documented by Bart Trzynadlowski (http://www.trzy.org/files/ssf2.txt) +*/ +static void mapper_ssf2_w(uint32 address, uint32 data) +{ + /* 8 x 512k banks */ + address = (address << 2) & 0x38; + + /* bank 0 remains unchanged */ + if (address) + { + uint32 i; + uint8 *src = cart.rom + (data << 19); + + for (i=0; i<8; i++) + { + m68k.memory_map[address++].base = src + (i<<16); + } + } +} + +/* + SF-001 mapper +*/ +static void mapper_sf001_w(uint32 address, uint32 data) +{ + switch ((address >> 8) & 0xf) + { + case 0xe: + { + int i; + + /* bit 6: enable / disable cartridge access */ + if (data & 0x40) + { + /* $000000-$3FFFFF is not mapped */ + for (i=0x00; i<0x40; i++) + { + m68k.memory_map[i].base = cart.rom + (i << 16); + m68k.memory_map[i].read8 = m68k_read_bus_8; + m68k.memory_map[i].read16 = m68k_read_bus_16; + m68k.memory_map[i].write8 = (i > 0x00) ? m68k_unused_8_w : mapper_sf001_w; + m68k.memory_map[i].write16 = (i > 0x00) ? m68k_unused_16_w : mapper_sf001_w; + zbank_memory_map[i].read = zbank_unused_r; + zbank_memory_map[i].write = (i > 0x00) ? m68k_unused_8_w : mapper_sf001_w; + } + } + + /* bit 7: enable / disable SRAM & ROM bankswitching */ + else if (data & 0x80) + { + /* 256K ROM bank #15 mapped to $000000-$03FFFF */ + for (i=0x00; i<0x04; i++) + { + m68k.memory_map[i].base = cart.rom + ((0x38 + i) << 16); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + zbank_memory_map[i].read = NULL; + } + + /* 256K ROM banks #2 to #15 mapped to $040000-$3BFFFF (last revision) or $040000-$3FFFFF (older revisions) */ + for (i=0x04; i<(sram.start >> 16); i++) + { + m68k.memory_map[i].base = cart.rom + (i << 16); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + zbank_memory_map[i].read = NULL; + } + + /* 32K static RAM mirrored into $3C0000-$3FFFFF (odd bytes only) (last revision only) */ + while (i<0x40) + { + m68k.memory_map[i].base = sram.sram; + m68k.memory_map[i].read8 = sram_read_byte; + m68k.memory_map[i].read16 = sram_read_word; + m68k.memory_map[i].write8 = sram_write_byte; + m68k.memory_map[i].write16 = sram_write_word; + zbank_memory_map[i].read = sram_read_byte; + zbank_memory_map[i].write = sram_write_byte; + i++; + } + } + else + { + /* 256K ROM banks #1 to #16 mapped to $000000-$3FFFFF (default) */ + for (i=0x00; i<0x40; i++) + { + m68k.memory_map[i].base = cart.rom + (i << 16); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + m68k.memory_map[i].write8 = (i > 0x00) ? m68k_unused_8_w : mapper_sf001_w; + m68k.memory_map[i].write16 = (i > 0x00) ? m68k_unused_16_w : mapper_sf001_w; + zbank_memory_map[i].read = NULL; + zbank_memory_map[i].write = (i > 0x00) ? m68k_unused_8_w : mapper_sf001_w; + } + } + + /* bit 5: lock bankswitch hardware when set */ + if (data & 0x20) + { + /* disable bankswitch hardware access until hard reset */ + m68k.memory_map[0x00].write8 = m68k_unused_8_w; + m68k.memory_map[0x00].write16 = m68k_unused_16_w; + zbank_memory_map[0x00].write = m68k_unused_8_w; + } + + return; + } + + default: + { + m68k_unused_8_w(address, data); + return; + } + } +} + +/* + SF-002 mapper +*/ +static void mapper_sf002_w(uint32 address, uint32 data) +{ + /* 8 x 512k banks */ + address = (address << 2) & 0x38; + + /* bank 0 remains unchanged */ + if (address) + { + uint32 i; + uint8 *src = cart.rom + (data << 19); + + for (i = 0; i<8; i++) + { + m68k.memory_map[address++].base = src + (i << 16); + } + } + else // emulate turning on SRAM + { + if (data & 1) + { + if (sram.on) + { + /* Backup RAM mapped to $200000-$20ffff (normally mirrored up to $3fffff but this breaks Sonic Megamix and no game need it) */ + cart.hw.bankshift = m68k.memory_map[0x20].base; + m68k.memory_map[0x20].base = sram.sram; + m68k.memory_map[0x20].read8 = sram_read_byte; + m68k.memory_map[0x20].read16 = sram_read_word; + zbank_memory_map[0x20].read = sram_read_byte; + + /* Backup RAM write protection */ + if (data & 2) + { + m68k.memory_map[0x20].write8 = m68k_unused_8_w; + m68k.memory_map[0x20].write16 = m68k_unused_16_w; + zbank_memory_map[0x20].write = zbank_unused_w; + } + else + { + m68k.memory_map[0x20].write8 = sram_write_byte; + m68k.memory_map[0x20].write16 = sram_write_word; + zbank_memory_map[0x20].write = sram_write_byte; + } + } + } + else + { + // automatically turn off writing to SRAM if SRAM is not visible + m68k.memory_map[0x20].write8 = m68k_unused_8_w; + m68k.memory_map[0x20].write16 = m68k_unused_16_w; + zbank_memory_map[0x20].write = zbank_unused_w; + + // put the ROM data back in the memory map + m68k.memory_map[0x20].base = cart.hw.bankshift; + } + } +} + +/* + SF-004 mapper +*/ +static void mapper_sf004_w(uint32 address, uint32 data) +{ + int i; + switch ((address >> 8) & 0xf) + { + case 0xd: + { + /* bit 7: enable/disable static RAM access */ + if (data & 0x80) + { + /* 32KB static RAM mirrored into $200000-$2FFFFF (odd bytes only) */ + for (i=0x20; i<0x30; i++) + { + m68k.memory_map[i].read8 = sram_read_byte; + m68k.memory_map[i].read16 = sram_read_word; + m68k.memory_map[i].write8 = sram_write_byte; + m68k.memory_map[i].write16 = sram_write_word; + zbank_memory_map[i].read = sram_read_byte; + zbank_memory_map[i].write = sram_write_byte; + } + } + else + { + /* 32KB static RAM disabled at $200000-$2FFFFF */ + for (i=0x20; i<0x30; i++) + { + m68k.memory_map[i].read8 = m68k_read_bus_8; + m68k.memory_map[i].read16 = m68k_read_bus_16; + m68k.memory_map[i].write8 = m68k_unused_8_w; + m68k.memory_map[i].write16 = m68k_unused_16_w; + zbank_memory_map[i].read = m68k_read_bus_8; + zbank_memory_map[i].write = m68k_unused_8_w; + } + } + + return; + } + + case 0x0e: + { + /* bit 5: enable / disable cartridge ROM access */ + if (data & 0x20) + { + /* $000000-$1FFFFF is not mapped */ + for (i=0x00; i<0x20; i++) + { + m68k.memory_map[i].read8 = m68k_read_bus_8; + m68k.memory_map[i].read16 = m68k_read_bus_16; + zbank_memory_map[i].read = m68k_read_bus_8; + } + } + + /* bit 6: enable / disable first page mirroring */ + else if (data & 0x40) + { + /* first page ROM bank */ + uint8 base = (m68k.memory_map[0x00].base - cart.rom) >> 16; + + /* 5 x 256K ROM banks mapped to $000000-$13FFFF, starting from first page ROM bank */ + for (i=0x00; i<0x14; i++) + { + m68k.memory_map[i].base = cart.rom + (((base + i) & 0x1f) << 16); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + zbank_memory_map[i].read = NULL; + } + + /* $140000-$1FFFFF is not mapped */ + for (i=0x14; i<0x20; i++) + { + m68k.memory_map[i].read8 = m68k_read_bus_8; + m68k.memory_map[i].read16 = m68k_read_bus_16; + zbank_memory_map[i].read = m68k_read_bus_8; + } + } + else + { + /* first page 256K ROM bank mirrored into $000000-$1FFFFF */ + for (i=0x00; i<0x20; i++) + { + m68k.memory_map[i].base = m68k.memory_map[0].base + ((i & 0x03) << 16); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + zbank_memory_map[i].read = NULL; + } + } + + /* bit 7: lock ROM bankswitching hardware when cleared */ + if (!(data & 0x80)) + { + /* disable bankswitch hardware access */ + m68k.memory_map[0x00].write8 = m68k_unused_8_w; + m68k.memory_map[0x00].write16 = m68k_unused_16_w; + zbank_memory_map[0x00].write = m68k_unused_8_w; + } + + return; + } + + case 0x0f: + { + /* bits 6-4: select first page ROM bank (8 x 256K ROM banks) */ + uint8 base = ((data >> 4) & 7) << 2; + + if (m68k.memory_map[0].base == m68k.memory_map[4].base) + { + /* selected 256K ROM bank mirrored into $000000-$1FFFFF */ + for (i=0x00; i<0x20; i++) + { + m68k.memory_map[i].base = cart.rom + ((base + (i & 0x03)) << 16); + } + } + else + { + /* 5 x 256K ROM banks mapped to $000000-$13FFFF, starting from selected bank */ + for (i=0x00; i<0x14; i++) + { + m68k.memory_map[i].base = cart.rom + (((base + i) & 0x1f) << 16); + } + } + + return; + } + + default: + { + m68k_unused_8_w(address, data); + return; + } + } +} + +static uint32 mapper_sf004_r(uint32 address) +{ + /* return first page 256K bank index ($00,$10,$20,...,$70) */ + return (((m68k.memory_map[0x00].base - cart.rom) >> 18) << 4); +} + +/* + T-5740xx-xx mapper +*/ +static void mapper_t5740_w(uint32 address, uint32 data) +{ + int i; + uint8 *base; + + switch (address & 0xff) + { + case 0x01: /* mode register */ + { + /* bits 7-4: unused ? */ + /* bit 3: enable SPI registers access ? */ + /* bit 2: not used ? */ + /* bit 1: enable bankswitch registers access ? */ + /* bit 0: always set, enable hardware access ? */ + return; + } + + case 0x03: /* page #5 register */ + { + /* map any of 16 x 512K ROM banks to $280000-$2FFFFF */ + base = cart.rom + ((data & 0x0f) << 19); + for (i=0x28; i<0x30; i++) + { + m68k.memory_map[i].base = base + ((i & 0x07) << 16); + } + return; + } + + case 0x05: /* page #6 register */ + { + /* map any of 16 x 512K ROM banks to $300000-$37FFFF */ + base = cart.rom + ((data & 0x0f) << 19); + for (i=0x30; i<0x38; i++) + { + m68k.memory_map[i].base = base + ((i & 0x07) << 16); + } + return; + } + + case 0x07: /* page #7 register */ + { + /* map any of 16 x 512K ROM banks to $380000-$3FFFFF */ + base = cart.rom + ((data & 0x0f) << 19); + for (i=0x38; i<0x40; i++) + { + m68k.memory_map[i].base = base + ((i & 0x07) << 16); + } + return; + } + + case 0x09: /* serial EEPROM SPI board support */ + { + eeprom_spi_write(data); + return; + } + + default: + { + /* unknown registers */ + m68k_unused_8_w(address, data); + return; + } + } +} + +static uint32 mapper_t5740_r(uint32 address) +{ + /* By default, first 32K of each eight 512K pages mapped in $000000-$3FFFFF are mirrored in the 512K page */ + /* mirroring is disabled/enabled when a specific number of words is being read from specific ROM addresses */ + /* Exact decoding isn't known but mirrored data is expected on startup when reading a few times from $181xx */ + /* this area doesn't seem to be accessed as byte later so it seems safe to always return mirrored data here */ + if ((address & 0xff00) == 0x8100) + { + return READ_BYTE(cart.rom , (address & 0x7fff)); + } + + return READ_BYTE(cart.rom, address); +} + +/* + Super Mario World 64 (unlicensed) mapper +*/ +static void mapper_smw_64_w(uint32 address, uint32 data) +{ + /* internal registers (saved to backup RAM) */ + switch ((address >> 16) & 0x07) + { + case 0x00: /* $60xxxx */ + { + if (address & 2) + { + /* $600003 data write mode ? */ + switch (sram.sram[0x00] & 0x07) + { + case 0x00: + { + /* update value returned at $660001-$660003 */ + sram.sram[0x06] = ((sram.sram[0x06] ^ sram.sram[0x01]) ^ data) & 0xFE; + break; + } + + case 0x01: + { + /* update value returned at $660005-$660007 */ + sram.sram[0x07] = data & 0xFE; + break; + } + + case 0x07: + { + /* update selected ROM bank (upper 512K) mapped at $610000-$61ffff */ + m68k.memory_map[0x61].base = m68k.memory_map[0x69].base = cart.rom + 0x080000 + ((data & 0x1c) << 14); + break; + } + + default: + { + /* unknown mode */ + break; + } + } + + /* $600003 data register */ + sram.sram[0x01] = data; + } + else + { + /* $600001 ctrl register */ + sram.sram[0x00] = data; + } + return; + } + + case 0x01: /* $61xxxx */ + { + if (address & 2) + { + /* $610003 ctrl register */ + sram.sram[0x02] = data; + } + return; + } + + case 0x04: /* $64xxxx */ + { + if (address & 2) + { + /* $640003 data register */ + sram.sram[0x04] = data; + } + else + { + /* $640001 data register */ + sram.sram[0x03] = data; + } + return; + } + + case 0x06: /* $66xxxx */ + { + /* unknown */ + return; + } + + case 0x07: /* $67xxxx */ + { + if (!(address & 2)) + { + /* $670001 ctrl register */ + sram.sram[0x05] = data; + + /* upper 512K ROM bank-switching enabled ? */ + if (sram.sram[0x02] & 0x80) + { + /* update selected ROM bank (upper 512K) mapped at $600000-$60ffff */ + m68k.memory_map[0x60].base = m68k.memory_map[0x68].base = cart.rom + 0x080000 + ((data & 0x1c) << 14); + } + } + return; + } + + default: /* not used */ + { + m68k_unused_8_w(address, data); + return; + } + } +} + +static uint32 mapper_smw_64_r(uint32 address) +{ + /* internal registers (saved to backup RAM) */ + switch ((address >> 16) & 0x03) + { + case 0x02: /* $66xxxx */ + { + switch ((address >> 1) & 7) + { + case 0x00: return sram.sram[0x06]; + case 0x01: return sram.sram[0x06] + 1; + case 0x02: return sram.sram[0x07]; + case 0x03: return sram.sram[0x07] + 1; + case 0x04: return sram.sram[0x08]; + case 0x05: return sram.sram[0x08] + 1; + case 0x06: return sram.sram[0x08] + 2; + case 0x07: return sram.sram[0x08] + 3; + } + } + + case 0x03: /* $67xxxx */ + { + uint8 data = (sram.sram[0x02] & 0x80) ? ((sram.sram[0x05] & 0x40) ? (sram.sram[0x03] & sram.sram[0x04]) : (sram.sram[0x03] ^ 0xFF)) : 0x00; + + if (address & 2) + { + /* $670003 */ + data &= 0x7f; + } + else + { + /* $66xxxx data registers update */ + if (sram.sram[0x05] & 0x80) + { + if (sram.sram[0x05] & 0x20) + { + /* update $660009-$66000f data register */ + sram.sram[0x08] = (sram.sram[0x04] << 2) & 0xFC; + } + else + { + /* update $660001-$660003 data register */ + sram.sram[0x06] = (sram.sram[0x01] ^ (sram.sram[0x03] << 1)) & 0xFE; + } + } + } + + return data; + } + + default: /* 64xxxx-$65xxxx */ + { + return 0x00; + } + } +} + +/* + Realtec ROM bankswitch (Earth Defend, Balloon Boy & Funny World, Whac-A-Critter) + (Note: register usage is inverted in TascoDlx documentation) +*/ +static void mapper_realtec_w(uint32 address, uint32 data) +{ + switch (address) + { + case 0x402000: + { + /* number of mapped 64k blocks (the written value is a number of 128k blocks) */ + cart.hw.regs[2] = data << 1; + return; + } + + case 0x404000: + { + /* 00000xxx */ + cart.hw.regs[0] = data & 7; + return; + } + + case 0x400000: + { + /* 00000yy1 */ + cart.hw.regs[1] = data & 6; + + /* ensure mapped size is not null */ + if (cart.hw.regs[2]) + { + /* mapped start address is 00yy xxx0 0000 0000 0000 0000 */ + uint32 base = (cart.hw.regs[0] << 1) | (cart.hw.regs[1] << 3); + + /* selected blocks are mirrored into the whole cartridge area */ + int i; + for (i=0x00; i<0x40; i++) + { + m68k.memory_map[i].base = &cart.rom[(base + (i % cart.hw.regs[2])) << 16]; + } + } + return; + } + } +} + +/* Game no Kanzume Otokuyou ROM Mapper */ +static void mapper_seganet_w(uint32 address, uint32 data) +{ + if ((address & 0xff) == 0xf1) + { + int i; + if (data & 1) + { + /* ROM Write protected */ + for (i=0; i<0x40; i++) + { + m68k.memory_map[i].write8 = m68k_unused_8_w; + m68k.memory_map[i].write16 = m68k_unused_16_w; + zbank_memory_map[i].write = zbank_unused_w; + } + } + else + { + /* ROM Write enabled */ + for (i=0; i<0x40; i++) + { + m68k.memory_map[i].write8 = NULL; + m68k.memory_map[i].write16 = NULL; + zbank_memory_map[i].write = NULL; + } + } + } +} + +/* + Custom ROM Bankswitch used in Soul Edge VS Samurai Spirits, Top Fighter, Mulan, Pocket Monsters II, Lion King 3, Super King Kong 99, Pokemon Stadium +*/ +static void mapper_32k_w(uint32 data) +{ + int i; + + /* 64 x 32k banks */ + if (data) + { + for (i=0; i<0x10; i++) + { + /* Remap to unused ROM area */ + m68k.memory_map[i].base = &cart.rom[0x400000 + (i << 16)]; + + /* address = address OR (value << 15) */ + memcpy(m68k.memory_map[i].base, cart.rom + ((i << 16) | (data & 0x3f) << 15), 0x8000); + memcpy(m68k.memory_map[i].base + 0x8000, cart.rom + ((i << 16) | ((data | 1) & 0x3f) << 15), 0x8000); + } + } + else + { + /* reset default $000000-$0FFFFF mapping */ + for (i=0; i<16; i++) + { + m68k.memory_map[i].base = &cart.rom[i << 16]; + } + } +} + +/* + Custom ROM Bankswitch used in Chinese Fighter III +*/ +static void mapper_64k_w(uint32 data) +{ + int i; + + /* 16 x 64k banks */ + if (data) + { + /* bank is mapped at $000000-$0FFFFF */ + for (i=0; i<16; i++) + { + m68k.memory_map[i].base = &cart.rom[(data & 0xf) << 16]; + } + } + else + { + /* reset default $000000-$0FFFFF mapping */ + for (i=0; i<16; i++) + { + m68k.memory_map[i].base = &cart.rom[(i & 0xf) << 16]; + } + } +} + +/* + Custom ROM Bankswitch used in pirate "Multi-in-1" cartridges, A Bug's Life, King of Fighter 99, Pocket Monster, Rockman X3 + */ +static void mapper_64k_multi_w(uint32 address) +{ + int i; + + /* 64 x 64k banks */ + for (i=0; i<64; i++) + { + m68k.memory_map[i].base = &cart.rom[((address++) & 0x3f) << 16]; + } +} + +/* + Custom ROM Bankswitch used in RADICA cartridges +*/ +static uint32 mapper_radica_r(uint32 address) +{ + int i = 0; + address = (address >> 1); + + /* 64 x 64k banks */ + for (i = 0; i < 64; i++) + { + m68k.memory_map[i].base = &cart.rom[((address++)& 0x3f)<< 16]; + } + + return 0xffff; +} + + +/************************************************************ + default !TIME signal handler +*************************************************************/ + +static void default_time_w(uint32 address, uint32 data) +{ + if (address < 0xa13040) + { + /* unlicensed cartridges mapper (default) */ + mapper_64k_multi_w(address); + return; + } + + /* official cartridges mapper (default) */ + mapper_sega_w(data); +} + + +/************************************************************ + Internal register handlers +*************************************************************/ + +static uint32 default_regs_r(uint32 address) +{ + int i; + for (i=0; i<4; i++) + { + if ((address & cart.hw.mask[i]) == cart.hw.addr[i]) + { + return cart.hw.regs[i]; + } + } + return m68k_read_bus_8(address); +} + +static uint32 default_regs_r_16(uint32 address) +{ + int i; + for (i=0; i<4; i++) + { + if ((address & cart.hw.mask[i]) == cart.hw.addr[i]) + { + return (cart.hw.regs[i] << 8); + } + } + return m68k_read_bus_16(address); +} + +static void default_regs_w(uint32 address, uint32 data) +{ + int i; + for (i=0; i<4; i++) + { + if ((address & cart.hw.mask[i]) == cart.hw.addr[i]) + { + cart.hw.regs[i] = data; + return; + } + } + m68k_unused_8_w(address, data); +} + +/* basic register shifting hardware (Bug's Life, Pocket Monster) */ +static uint32 custom_regs_r(uint32 address) +{ + int i; + for (i=0; i<4; i++) + { + if ((address & cart.hw.mask[i]) == cart.hw.addr[i]) + { + return cart.hw.regs[i] >> 1; + } + } + + return m68k_read_bus_8(address); +} + +/* custom register hardware (Top Fighter, Lion King III, Super Donkey Kong 99, Mulan, Pocket Monsters II, Pokemon Stadium) */ +static void custom_regs_w(uint32 address, uint32 data) +{ + uint8 temp; + + /* ROM bankswitch */ + if ((address >> 16) > 0x6f) + { + mapper_32k_w(data); + return; + } + + /* write register */ + default_regs_w(address, data); + + /* bitswapping */ + temp = cart.hw.regs[0]; + switch (cart.hw.regs[1] & 3) + { + case 0: + cart.hw.regs[2] = (temp << 1); + break; + + case 1: + cart.hw.regs[2] = (temp >> 1); + return; + + case 2: + cart.hw.regs[2] = ((temp >> 4) | ((temp & 0x0F) << 4)); + return; + + default: + cart.hw.regs[2] = (((temp >> 7) & 0x01) | ((temp >> 5) & 0x02) | + ((temp >> 3) & 0x04) | ((temp >> 1) & 0x08) | + ((temp << 1) & 0x10) | ((temp << 3) & 0x20) | + ((temp << 5) & 0x40) | ((temp << 7) & 0x80)); + return; + } +} + +/* alternate custom register hardware (Chinese Fighters III) */ +static void custom_alt_regs_w(uint32 address, uint32 data) +{ + /* ROM bankswitch */ + if ((address >> 16) > 0x5f) + { + mapper_64k_w(data); + return; + } + + /* write regs */ + default_regs_w(address, data); +} + + +/* "Tekken 3 Special" custom register hardware */ +static uint32 tekken_regs_r(uint32 address) +{ + /* data output */ + if ((address & 0x0e) == 0x02) + { + /* maybe depends on mode bits ? */ + return (cart.hw.regs[0] - 1); + } + + return m68k_read_bus_16(address); +} + +static void tekken_regs_w(uint32 address, uint32 data) +{ + switch (address & 0x0e) + { + case 0x00: + { + /* data output reset ? (game writes $FF before & after protection check) */ + cart.hw.regs[0]= 0x00; + break; + } + + case 0x02: + { + /* read only ? */ + break; + } + + case 0x0c: + { + /* data output mode bit 0 ? (game writes $01) */ + break; + } + + case 0x0e: + { + /* data output mode bit 1 ? (never written by game) */ + break; + } + + default: + { + /* data input (only connected to D0 ?)*/ + if (data & 1) + { + /* 4-bit hardware register ($400004 corresponds to bit0, $400006 to bit1, etc) */ + cart.hw.regs[0] |= 1 << (((address - 0x04) >> 1) & 3); + } + break; + } + } +} + +/* "Top Shooter" arcade board hardware */ +static uint32 topshooter_r(uint32 address) +{ + if (address < 0x202000) + { + uint8 temp = 0xff; + + switch (address & 0xff) + { + case 0x43: + { + if (input.pad[0] & INPUT_A) temp &= ~0x80; /* Shoot */ + if (input.pad[0] & INPUT_B) temp &= ~0x10; /* Bet */ + if (input.pad[0] & INPUT_START) temp &= ~0x20; /* Start */ + break; + } + + case 0x45: /* ??? (DOWN) & Service Mode (UP) */ + { + if (input.pad[0] & INPUT_UP) temp &= ~0x08; /* Service Mode */ + if (input.pad[0] & INPUT_DOWN) temp &= ~0x10; /* ???, used in service menu to select next option */ + break; + } + + case 0x47: + { + if (input.pad[0] & INPUT_RIGHT) temp &= ~0x03; /* Insert 10 coins */ + break; + } + + case 0x49: + { + if (input.pad[0] & INPUT_LEFT) temp &= ~0x03; /* Clear coins */ + if (input.pad[0] & INPUT_C) temp &= ~0x01; /* Insert XXX coins */ + break; + } + + case 0x51: + { + temp = 0xA5; + break; + } + + default: + { + temp = m68k_read_bus_8(address); + break; + } + } + return temp; + } + + return READ_BYTE(sram.sram , address & 0xffff); +} + +static void topshooter_w(uint32 address, uint32 data) +{ + if (address >= 0x202000) + { + WRITE_BYTE(sram.sram , address & 0xffff, data); + return; + } + + m68k_unused_8_w(address, data); +} + + +/* Sega Channel hardware (not emulated) */ +/* + +$A13004: BUSY ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? + +Unused read16 00A13004 (00005B54) +Unused read16 00A13004 (00005B70) +Unused read16 00A13006 (00005B7C) + +Unused read16 00A13004 (00005BC4) +Unused read16 00A13004 (00005BDA) + +Unused write16 00A13032 = 0004 (00005706) +Unused write16 00A130F0 = 0000 (0000570E) + +Unused write16 00A130F0 = 0000 (0000463E) +Unused write16 00A130F2 = 0001 (00004646) +Unused write16 00A130F4 = 0002 (0000464E) +Unused write16 00A130F6 = 0003 (00004656) +Unused write16 00A130F8 = 0004 (0000465E) +Unused write16 00A130FA = 0005 (00004666) + +Unused write16 00A13032 = 0004 (00005706) +Unused write16 00A13032 = 0104 (0000579E) + +Unused write16 00380000 = ACDC (00005718) +Unused write16 00380002 = 0000 (00005722) +Unused read16 00380000 (0000572C) +Unused write16 00A13032 = 0104 (0000579E) +Unused write16 00300000 = ACDC (000057B2) +Unused write16 00380000 = 0000 (000057BC) +Unused read16 00300000 (000057C6) + +static uint32 sega_channel_r(uint32 address) +{ + return m68k_read_bus_16(address);; +} + +static void sega_channel_w(uint32 address, uint32 data) +{ + m68k_unused_16_w(address, data); +} +*/ diff --git a/waterbox/gpgx/core/cart_hw/sram.c b/waterbox/gpgx/core/cart_hw/sram.c index 70773c47b9..3389163ee3 100644 --- a/waterbox/gpgx/core/cart_hw/sram.c +++ b/waterbox/gpgx/core/cart_hw/sram.c @@ -1,255 +1,268 @@ -/*************************************************************************************** - * Genesis Plus - * Backup RAM support - * - * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) - * - * Redistribution and use of this code or any derivative works are permitted - * provided that the following conditions are met: - * - * - Redistributions may not be sold, nor may they be used in a commercial - * product or activity. - * - * - Redistributions that are modified from the original source must include the - * complete source code, including the source code for all components used by a - * binary built from the modified sources. However, as a special exception, the - * source code distributed need not include anything that is normally distributed - * (in either source or binary form) with the major components (compiler, kernel, - * and so on) of the operating system on which the executable runs, unless that - * component itself accompanies the executable. - * - * - Redistributions must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************************/ - -#include "shared.h" -#include "eeprom_i2c.h" -#include "eeprom_spi.h" -#include "eeprom_93c.h" - -T_SRAM sram; - -/**************************************************************************** - * A quick guide to external RAM on the Genesis - * - * The external RAM definition is held at offset 0x1b0 of the ROM header. - * - * 1B0h: dc.b 'RA', %1x1yz000, %abc00000 - * 1B4h: dc.l RAM start address - * 1B8h: dc.l RAM end address - * x 1 for BACKUP (not volatile), 0 for volatile RAM - * yz 10 if even address only - * 11 if odd address only - * 00 if both even and odd address - * 01 others (serial EEPROM, RAM with 4-bit data bus, etc) - * abc 001 if SRAM - * 010 if EEPROM (serial or parallel) - * other values unused - * - * Assuming max. 64k backup RAM throughout - ****************************************************************************/ -void sram_init() -{ - memset(&sram, 0, sizeof (T_SRAM)); - - /* backup RAM data is stored above cartridge ROM area, at $800000-$80FFFF (max. 64K) */ - if (cart.romsize > 0x800000) return; - sram.sram = malloc(0x10000); - - /* initialize Backup RAM */ - memset(sram.sram, 0xFF, 0x10000); - //sram.crc = crc32(0, sram.sram, 0x10000); - - /* retrieve informations from header */ - if ((READ_BYTE(cart.rom,0x1b0) == 0x52) && (READ_BYTE(cart.rom,0x1b1) == 0x41)) - { - /* backup RAM detected */ - sram.detected = 1; - - /* enable backup RAM */ - sram.on = 1; - - /* retrieve backup RAM start & end addresses */ - sram.start = READ_WORD_LONG(cart.rom, 0x1b4); - sram.end = READ_WORD_LONG(cart.rom, 0x1b8); - - /* autodetect games with wrong header infos */ - if (strstr(rominfo.product,"T-26013") != NULL) - { - /* Psy-O-Blade (wrong header) */ - sram.start = 0x200001; - sram.end = 0x203fff; - } - - /* fixe games indicating internal RAM as volatile external RAM (Feng Kuang Tao Hua Yuan) */ - else if (sram.start == 0xff0000) - { - /* backup RAM should be disabled */ - sram.on = 0; - } - - /* fixe other bad header informations */ - else if ((sram.start > sram.end) || ((sram.end - sram.start) >= 0x10000)) - { - sram.end = sram.start + 0xffff; - } - } - else - { - /* autodetect games with missing header infos */ - if (strstr(rominfo.product,"T-50086") != NULL) - { - /* PGA Tour Golf */ - sram.on = 1; - sram.start = 0x200001; - sram.end = 0x203fff; - } - else if (strstr(rominfo.product,"ACLD007") != NULL) - { - /* Winter Challenge */ - sram.on = 1; - sram.start = 0x200001; - sram.end = 0x200fff; - } - else if (strstr(rominfo.product,"T-50286") != NULL) - { - /* Buck Rogers - Countdown to Doomsday */ - sram.on = 1; - sram.start = 0x200001; - sram.end = 0x203fff; - } - else if (((rominfo.realchecksum == 0xaeaa) || (rominfo.realchecksum == 0x8dba)) && - (rominfo.checksum == 0x8104)) - { - /* Xin Qigai Wangzi (use uncommon area) */ - sram.on = 1; - sram.start = 0x400001; - sram.end = 0x40ffff; - } - else if ((strstr(rominfo.ROMType,"SF") != NULL) && (strstr(rominfo.product,"001") != NULL)) - { - /* SF-001 */ - sram.on = 1; - if (rominfo.checksum == 0x3e08) - { - /* last revision (use bankswitching) */ - sram.start = 0x3c0001; - sram.end = 0x3cffff; - } - else - { - /* older revisions (use uncommon area) */ - sram.start = 0x400001; - sram.end = 0x40ffff; - } - } - else if ((strstr(rominfo.ROMType,"SF") != NULL) && (strstr(rominfo.product,"004") != NULL)) - { - /* SF-004 (use bankswitching) */ - sram.on = 1; - sram.start = 0x200001; - sram.end = 0x203fff; - } - else if (strstr(rominfo.international,"SONIC & KNUCKLES") != NULL) - { - /* Sonic 3 & Knuckles combined ROM */ - if (cart.romsize == 0x400000) - { - /* Sonic & Knuckle does not have backup RAM but can access FRAM from Sonic 3 cartridge */ - sram.on = 1; - sram.start = 0x200001; - sram.end = 0x203fff; - } - } - - /* auto-detect games which need disabled backup RAM */ - else if (strstr(rominfo.product,"T-113016") != NULL) - { - /* Pugsy (does not have backup RAM but tries writing outside ROM area as copy protection) */ - sram.on = 0; - } - else if (strstr(rominfo.international,"SONIC THE HEDGEHOG 2") != NULL) - { - /* Sonic the Hedgehog 2 (does not have backup RAM) */ - /* this prevents backup RAM from being mapped in place of mirrored ROM when using S&K LOCK-ON feature */ - sram.on = 0; - } - - // by default, enable backup RAM for ROM smaller than 2MB - /* - else if (cart.romsize <= 0x200000) - { - // 64KB static RAM mapped to $200000-$20ffff - sram.start = 0x200000; - sram.end = 0x20ffff; - sram.on = 1; - } - */ - } -} - -unsigned int sram_read_byte(unsigned int address) -{ - return sram.sram[address & 0xffff]; -} - -unsigned int sram_read_word(unsigned int address) -{ - address &= 0xfffe; - return (sram.sram[address + 1] | (sram.sram[address] << 8)); -} - -void sram_write_byte(unsigned int address, unsigned int data) -{ - sram.sram[address & 0xffff] = data; -} - -void sram_write_word(unsigned int address, unsigned int data) -{ - address &= 0xfffe; - sram.sram[address] = data >> 8; - sram.sram[address + 1] = data & 0xff; -} - -// the variables in SRAM_T are all part of "configuration", so we don't have to save those. -// the only thing that needs to be saved is the SRAM itself and the SEEPROM struct (if applicable) - -int sram_get_actual_size() -{ - if (!sram.on) - return 0; - switch (sram.custom) - { - case 0: // plain bus access saveram - break; - case 1: // i2c - return eeprom_i2c.config.size_mask + 1; - case 2: // spi - return 0x10000; // it doesn't appear to mask anything internally - case 3: // 93c - return 0x10000; // SMS only and i don't have time to look into it - default: - return 0x10000; // who knows - } - // figure size for plain bus access saverams - { - int startaddr = sram.start / 8192; - int endaddr = sram.end / 8192 + 1; - int size = (endaddr - startaddr) * 8192; - return size; - } -} +/*************************************************************************************** + * Genesis Plus + * Backup RAM support + * + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" +#include "eeprom_i2c.h" +#include "eeprom_spi.h" +#include "eeprom_93c.h" + +T_SRAM sram; + +/**************************************************************************** + * A quick guide to external RAM on the Genesis + * + * The external RAM definition is held at offset 0x1b0 of the ROM header. + * + * 1B0h: dc.b 'RA', %1x1yz000, %abc00000 + * 1B4h: dc.l RAM start address + * 1B8h: dc.l RAM end address + * x 1 for BACKUP (not volatile), 0 for volatile RAM + * yz 10 if even address only + * 11 if odd address only + * 00 if both even and odd address + * 01 others (serial EEPROM, RAM with 4-bit data bus, etc) + * abc 001 if SRAM + * 010 if EEPROM (serial or parallel) + * other values unused + * + * Assuming max. 64k backup RAM throughout + ****************************************************************************/ +void sram_init() +{ + memset(&sram, 0, sizeof (T_SRAM)); + + /* backup RAM data is stored above cartridge ROM area, at $800000-$80FFFF (max. 64K) */ + if (cart.romsize > 0x800000) return; + sram.sram = malloc(0x10000); + + /* initialize Backup RAM */ + memset(sram.sram, 0xFF, 0x10000); + //sram.crc = crc32(0, sram.sram, 0x10000); + + /* retrieve informations from header */ + if ((READ_BYTE(cart.rom,0x1b0) == 0x52) && (READ_BYTE(cart.rom,0x1b1) == 0x41)) + { + /* backup RAM detected */ + sram.detected = 1; + + /* enable backup RAM */ + sram.on = 1; + + /* retrieve backup RAM start & end addresses */ + sram.start = READ_WORD_LONG(cart.rom, 0x1b4); + sram.end = READ_WORD_LONG(cart.rom, 0x1b8); + + /* autodetect games with wrong header infos */ + if (strstr(rominfo.product,"T-26013") != NULL) + { + /* Psy-O-Blade (wrong header) */ + sram.start = 0x200001; + sram.end = 0x203fff; + } + + /* fixe games indicating internal RAM as volatile external RAM (Feng Kuang Tao Hua Yuan) */ + else if (sram.start == 0xff0000) + { + /* backup RAM should be disabled */ + sram.on = 0; + } + + /* fixe other bad header informations */ + else if ((sram.start > sram.end) || ((sram.end - sram.start) >= 0x10000)) + { + sram.end = sram.start + 0xffff; + } + } + else + { + /* autodetect games with missing header infos */ + if (strstr(rominfo.product,"T-50086") != NULL) + { + /* PGA Tour Golf */ + sram.on = 1; + sram.start = 0x200001; + sram.end = 0x203fff; + } + else if (strstr(rominfo.product,"ACLD007") != NULL) + { + /* Winter Challenge */ + sram.on = 1; + sram.start = 0x200001; + sram.end = 0x200fff; + } + else if (strstr(rominfo.product,"T-50286") != NULL) + { + /* Buck Rogers - Countdown to Doomsday */ + sram.on = 1; + sram.start = 0x200001; + sram.end = 0x203fff; + } + else if (((rominfo.realchecksum == 0xaeaa) || (rominfo.realchecksum == 0x8dba)) && + (rominfo.checksum == 0x8104)) + { + /* Xin Qigai Wangzi (use uncommon area) */ + sram.on = 1; + sram.start = 0x400001; + sram.end = 0x40ffff; + } + else if ((strstr(rominfo.ROMType,"SF") != NULL) && (strstr(rominfo.product,"001") != NULL)) + { + /* SF-001 */ + sram.on = 1; + if (rominfo.checksum == 0x3e08) + { + /* last revision (use bankswitching) */ + sram.start = 0x3c0001; + sram.end = 0x3cffff; + } + else + { + /* older revisions (use uncommon area) */ + sram.start = 0x400001; + sram.end = 0x40ffff; + } + } + else if ((strstr(rominfo.ROMType,"SF") != NULL) && (strstr(rominfo.product,"004") != NULL)) + { + /* SF-004 (use bankswitching) */ + sram.on = 1; + sram.start = 0x200001; + sram.end = 0x203fff; + } + else if (strstr(rominfo.international,"SONIC & KNUCKLES") != NULL) + { + /* Sonic 3 & Knuckles combined ROM */ + if (cart.romsize == 0x400000) + { + /* Sonic & Knuckle does not have backup RAM but can access FRAM from Sonic 3 cartridge */ + sram.on = 1; + sram.start = 0x200001; + sram.end = 0x203fff; + } + } + else if (strstr(rominfo.product, "T-50166") != NULL) + { + /* Might and Magic Gates to Another World */ + sram.on = 1; + sram.start = 0x200001; + sram.end = 0x203fff; + } + else if (strstr(rominfo.international, "MIGHT & MAGIC III") != NULL) + { + /* Might and Magic III - Isles of Terra (USA) (Proto) */ + sram.on = 1; + sram.start = 0x200001; + sram.end = 0x203fff; + } + /* auto-detect games which need disabled backup RAM */ + else if (strstr(rominfo.product,"T-113016") != NULL) + { + /* Pugsy (does not have backup RAM but tries writing outside ROM area as copy protection) */ + sram.on = 0; + } + else if (strstr(rominfo.international,"SONIC THE HEDGEHOG 2") != NULL) + { + /* Sonic the Hedgehog 2 (does not have backup RAM) */ + /* this prevents backup RAM from being mapped in place of mirrored ROM when using S&K LOCK-ON feature */ + sram.on = 0; + } + + // by default, enable backup RAM for ROM smaller than 2MB + /* + else if (cart.romsize <= 0x200000) + { + // 64KB static RAM mapped to $200000-$20ffff + sram.start = 0x200000; + sram.end = 0x20ffff; + sram.on = 1; + } + */ + } +} + +unsigned int sram_read_byte(unsigned int address) +{ + return sram.sram[address & 0xffff]; +} + +unsigned int sram_read_word(unsigned int address) +{ + address &= 0xfffe; + return (sram.sram[address + 1] | (sram.sram[address] << 8)); +} + +void sram_write_byte(unsigned int address, unsigned int data) +{ + sram.sram[address & 0xffff] = data; +} + +void sram_write_word(unsigned int address, unsigned int data) +{ + address &= 0xfffe; + sram.sram[address] = data >> 8; + sram.sram[address + 1] = data & 0xff; +} + +// the variables in SRAM_T are all part of "configuration", so we don't have to save those. +// the only thing that needs to be saved is the SRAM itself and the SEEPROM struct (if applicable) + +int sram_get_actual_size() +{ + if (!sram.on) + return 0; + switch (sram.custom) + { + case 0: // plain bus access saveram + break; + case 1: // i2c + return eeprom_i2c.config.size_mask + 1; + case 2: // spi + return 0x10000; // it doesn't appear to mask anything internally + case 3: // 93c + return 0x10000; // SMS only and i don't have time to look into it + default: + return 0x10000; // who knows + } + // figure size for plain bus access saverams + { + int startaddr = sram.start / 8192; + int endaddr = sram.end / 8192 + 1; + int size = (endaddr - startaddr) * 8192; + return size; + } +} diff --git a/waterbox/gpgx/core/cart_hw/svp/svp.c b/waterbox/gpgx/core/cart_hw/svp/svp.c index eee72c047d..b225c04650 100644 --- a/waterbox/gpgx/core/cart_hw/svp/svp.c +++ b/waterbox/gpgx/core/cart_hw/svp/svp.c @@ -1,49 +1,83 @@ -/* - basic, incomplete SSP160x (SSP1601?) interpreter - with SVP memory controller emu - - (c) Copyright 2008, Grazvydas "notaz" Ignotas - Free for non-commercial use. - - For commercial use, separate licencing terms must be obtained. - - Modified for Genesis Plus GX (Eke-Eke): added BIG ENDIAN support, fixed addr/code inversion -*/ - -#include "shared.h" - -svp_t *svp = NULL; - -void svp_init(void) -{ - svp = malloc(sizeof(svp_t)); - memset(svp, 0, sizeof(*svp)); -} - -void svp_reset(void) -{ - memcpy(svp->iram_rom + 0x800, cart.rom + 0x800, 0x20000 - 0x800); - ssp1601_reset(&svp->ssp1601); -} - -void svp_write_dram(uint32 address, uint32 data) -{ - *(uint16 *)(svp->dram + (address & 0x1fffe)) = data; - if ((address == 0x30fe06) && data) svp->ssp1601.emu_status &= ~SSP_WAIT_30FE06; - if ((address == 0x30fe08) && data) svp->ssp1601.emu_status &= ~SSP_WAIT_30FE08; -} - -uint32 svp_read_cell_1(uint32 address) -{ - address >>= 1; - address = (address & 0x7001) | ((address & 0x3e) << 6) | ((address & 0xfc0) >> 5); - return *(uint16 *)(svp->dram + (address & 0x1fffe)); -} - -uint32 svp_read_cell_2(uint32 address) -{ - address >>= 1; - address = (address & 0x7801) | ((address & 0x1e) << 6) | ((address & 0x7e0) >> 4); - return *(uint16 *)(svp->dram + (address & 0x1fffe)); -} - +/* +basic, incomplete SSP160x (SSP1601?) interpreter +with SVP memory controller emu +(c) Copyright 2008, Grazvydas "notaz" Ignotas +Free for non-commercial use. +For commercial use, separate licencing terms must be obtained. +Modified for Genesis Plus GX (Eke-Eke): added BIG ENDIAN support, fixed addr/code inversion +*/ + +#include "shared.h" + +svp_t *svp; + +static void svp_write_dram(uint32 address, uint32 data) +{ + *(uint16 *)(svp->dram + (address & 0x1fffe)) = data; + if (data) + { + if (address == 0x30fe06) + svp->ssp1601.emu_status &= ~SSP_WAIT_30FE06; + else if (address == 0x30fe08) + svp->ssp1601.emu_status &= ~SSP_WAIT_30FE08; + } +} + +static uint32 svp_read_cell_1(uint32 address) +{ + address = (address & 0xe002) | ((address & 0x7c) << 6) | ((address & 0x1f80) >> 5); + return *(uint16 *)(svp->dram + address); +} + +static uint32 svp_read_cell_2(uint32 address) +{ + address = (address & 0xf002) | ((address & 0x3c) << 6) | ((address & 0xfc0) >> 4); + return *(uint16 *)(svp->dram + address); +} + +static uint32 svp_read_cell_byte(uint32 address) +{ + uint16 data = m68k.memory_map[address >> 16].read16(address); + + if (address & 0x01) + { + return (data & 0xff); + } + + return (data >> 8); +} + +void svp_init(void) +{ + svp = malloc(sizeof(*svp)); + memset(svp, 0, sizeof(*svp)); + + m68k.memory_map[0x30].base = svp->dram; + m68k.memory_map[0x30].read8 = NULL; + m68k.memory_map[0x30].read16 = NULL; + m68k.memory_map[0x30].write8 = NULL; + m68k.memory_map[0x30].write16 = svp_write_dram; + zbank_memory_map[0x30].read = NULL; + zbank_memory_map[0x30].write = NULL; + + m68k.memory_map[0x31].base = svp->dram + 0x10000; + m68k.memory_map[0x31].read8 = NULL; + m68k.memory_map[0x31].read16 = NULL; + m68k.memory_map[0x31].write8 = NULL; + m68k.memory_map[0x31].write16 = NULL; + zbank_memory_map[0x31].read = NULL; + zbank_memory_map[0x31].write = NULL; + + m68k.memory_map[0x39].read8 = svp_read_cell_byte; + m68k.memory_map[0x39].read16 = svp_read_cell_1; + zbank_memory_map[0x39].read = svp_read_cell_byte; + m68k.memory_map[0x3a].read8 = svp_read_cell_byte; + m68k.memory_map[0x3a].read16 = svp_read_cell_2; + zbank_memory_map[0x3a].read = svp_read_cell_byte; +} + +void svp_reset(void) +{ + memcpy(svp->iram_rom + 0x800, cart.rom + 0x800, 0x20000 - 0x800); + ssp1601_reset(&svp->ssp1601); +} diff --git a/waterbox/gpgx/core/cart_hw/svp/svp.h b/waterbox/gpgx/core/cart_hw/svp/svp.h index 845cc027aa..a20d299a83 100644 --- a/waterbox/gpgx/core/cart_hw/svp/svp.h +++ b/waterbox/gpgx/core/cart_hw/svp/svp.h @@ -1,33 +1,30 @@ -/* - basic, incomplete SSP160x (SSP1601?) interpreter - with SVP memory controller emu - - (c) Copyright 2008, Grazvydas "notaz" Ignotas - Free for non-commercial use. - - For commercial use, separate licencing terms must be obtained. - - Modified for Genesis Plus GX (Eke-Eke): added BIG ENDIAN support, fixed addr/code inversion -*/ - -#ifndef _SVP_H_ -#define _SVP_H_ - -#include "shared.h" -#include "ssp16.h" - -typedef struct { - unsigned char iram_rom[0x20000]; /* IRAM (0-0x7ff) and program ROM (0x800-0x1ffff) */ - unsigned char dram[0x20000]; - ssp1601_t ssp1601; -} svp_t; - -extern svp_t *svp; - -extern void svp_init(void); -extern void svp_reset(void); -extern void svp_write_dram(uint32 address, uint32 data); -extern uint32 svp_read_cell_1(uint32 address); -extern uint32 svp_read_cell_2(uint32 address); - -#endif +/* + basic, incomplete SSP160x (SSP1601?) interpreter + with SVP memory controller emu + + (c) Copyright 2008, Grazvydas "notaz" Ignotas + Free for non-commercial use. + + For commercial use, separate licencing terms must be obtained. + + Modified for Genesis Plus GX (Eke-Eke): added BIG ENDIAN support, fixed addr/code inversion +*/ + +#ifndef _SVP_H_ +#define _SVP_H_ + +#include "shared.h" +#include "ssp16.h" + +typedef struct { + unsigned char iram_rom[0x20000]; /* IRAM (0-0x7ff) and program ROM (0x800-0x1ffff) */ + unsigned char dram[0x20000]; + ssp1601_t ssp1601; +} svp_t; + +extern svp_t *svp; + +extern void svp_init(void); +extern void svp_reset(void); + +#endif diff --git a/waterbox/gpgx/core/m68k/m68kcpu.h b/waterbox/gpgx/core/m68k/m68kcpu.h index 3af87b6b8b..eaf747e9b2 100644 --- a/waterbox/gpgx/core/m68k/m68kcpu.h +++ b/waterbox/gpgx/core/m68k/m68kcpu.h @@ -1,1446 +1,1453 @@ -#ifndef M68KCPU__HEADER -#define M68KCPU__HEADER - -/* ======================================================================== */ -/* GENERIC 68K CORE */ -/* ======================================================================== */ - -#include -#include -#include - -#if M68K_EMULATE_ADDRESS_ERROR -#include -#endif /* M68K_EMULATE_ADDRESS_ERROR */ - -#include "m68k.h" -#include "../cinterface/callbacks.h" - -void CDLog68k(uint addr, uint flags); - -/* ======================================================================== */ -/* ============================ GENERAL DEFINES =========================== */ -/* ======================================================================== */ - -/* Exception Vectors handled by emulation */ -#define EXCEPTION_RESET 0 -#define EXCEPTION_BUS_ERROR 2 /* This one is not emulated! */ -#define EXCEPTION_ADDRESS_ERROR 3 /* This one is partially emulated (doesn't stack a proper frame yet) */ -#define EXCEPTION_ILLEGAL_INSTRUCTION 4 -#define EXCEPTION_ZERO_DIVIDE 5 -#define EXCEPTION_CHK 6 -#define EXCEPTION_TRAPV 7 -#define EXCEPTION_PRIVILEGE_VIOLATION 8 -#define EXCEPTION_TRACE 9 -#define EXCEPTION_1010 10 -#define EXCEPTION_1111 11 -#define EXCEPTION_FORMAT_ERROR 14 -#define EXCEPTION_UNINITIALIZED_INTERRUPT 15 -#define EXCEPTION_SPURIOUS_INTERRUPT 24 -#define EXCEPTION_INTERRUPT_AUTOVECTOR 24 -#define EXCEPTION_TRAP_BASE 32 - -/* Function codes set by CPU during data/address bus activity */ -#define FUNCTION_CODE_USER_DATA 1 -#define FUNCTION_CODE_USER_PROGRAM 2 -#define FUNCTION_CODE_SUPERVISOR_DATA 5 -#define FUNCTION_CODE_SUPERVISOR_PROGRAM 6 -#define FUNCTION_CODE_CPU_SPACE 7 - -/* Different ways to stop the CPU */ -#define STOP_LEVEL_STOP 1 -#define STOP_LEVEL_HALT 2 - -/* Used for 68000 address error processing */ -#if M68K_EMULATE_ADDRESS_ERROR -#define INSTRUCTION_YES 0 -#define INSTRUCTION_NO 0x08 -#define MODE_READ 0x10 -#define MODE_WRITE 0 - -#define RUN_MODE_NORMAL 0 -#define RUN_MODE_BERR_AERR_RESET 1 -#endif - -#ifndef NULL -#define NULL ((void*)0) -#endif - -/* ======================================================================== */ -/* ================================ MACROS ================================ */ -/* ======================================================================== */ - - -/* ---------------------------- General Macros ---------------------------- */ - -/* Bit Isolation Macros */ -#define BIT_0(A) ((A) & 0x00000001) -#define BIT_1(A) ((A) & 0x00000002) -#define BIT_2(A) ((A) & 0x00000004) -#define BIT_3(A) ((A) & 0x00000008) -#define BIT_4(A) ((A) & 0x00000010) -#define BIT_5(A) ((A) & 0x00000020) -#define BIT_6(A) ((A) & 0x00000040) -#define BIT_7(A) ((A) & 0x00000080) -#define BIT_8(A) ((A) & 0x00000100) -#define BIT_9(A) ((A) & 0x00000200) -#define BIT_A(A) ((A) & 0x00000400) -#define BIT_B(A) ((A) & 0x00000800) -#define BIT_C(A) ((A) & 0x00001000) -#define BIT_D(A) ((A) & 0x00002000) -#define BIT_E(A) ((A) & 0x00004000) -#define BIT_F(A) ((A) & 0x00008000) -#define BIT_10(A) ((A) & 0x00010000) -#define BIT_11(A) ((A) & 0x00020000) -#define BIT_12(A) ((A) & 0x00040000) -#define BIT_13(A) ((A) & 0x00080000) -#define BIT_14(A) ((A) & 0x00100000) -#define BIT_15(A) ((A) & 0x00200000) -#define BIT_16(A) ((A) & 0x00400000) -#define BIT_17(A) ((A) & 0x00800000) -#define BIT_18(A) ((A) & 0x01000000) -#define BIT_19(A) ((A) & 0x02000000) -#define BIT_1A(A) ((A) & 0x04000000) -#define BIT_1B(A) ((A) & 0x08000000) -#define BIT_1C(A) ((A) & 0x10000000) -#define BIT_1D(A) ((A) & 0x20000000) -#define BIT_1E(A) ((A) & 0x40000000) -#define BIT_1F(A) ((A) & 0x80000000) - -/* Get the most significant bit for specific sizes */ -#define GET_MSB_8(A) ((A) & 0x80) -#define GET_MSB_9(A) ((A) & 0x100) -#define GET_MSB_16(A) ((A) & 0x8000) -#define GET_MSB_17(A) ((A) & 0x10000) -#define GET_MSB_32(A) ((A) & 0x80000000) -#if M68K_USE_64_BIT -#define GET_MSB_33(A) ((A) & 0x100000000) -#endif /* M68K_USE_64_BIT */ - -/* Isolate nibbles */ -#define LOW_NIBBLE(A) ((A) & 0x0f) -#define HIGH_NIBBLE(A) ((A) & 0xf0) - -/* These are used to isolate 8, 16, and 32 bit sizes */ -#define MASK_OUT_ABOVE_2(A) ((A) & 3) -#define MASK_OUT_ABOVE_8(A) ((A) & 0xff) -#define MASK_OUT_ABOVE_16(A) ((A) & 0xffff) -#define MASK_OUT_BELOW_2(A) ((A) & ~3) -#define MASK_OUT_BELOW_8(A) ((A) & ~0xff) -#define MASK_OUT_BELOW_16(A) ((A) & ~0xffff) - -/* No need to mask if we are 32 bit */ -#if M68K_INT_GT_32_BIT || M68K_USE_64_BIT - #define MASK_OUT_ABOVE_32(A) ((A) & 0xffffffff) - #define MASK_OUT_BELOW_32(A) ((A) & ~0xffffffff) -#else - #define MASK_OUT_ABOVE_32(A) (A) - #define MASK_OUT_BELOW_32(A) 0 -#endif /* M68K_INT_GT_32_BIT || M68K_USE_64_BIT */ - -/* Simulate address lines of 68k family */ -#define ADDRESS_68K(A) ((A)&CPU_ADDRESS_MASK) - - -/* Shift & Rotate Macros. */ -#define LSL(A, C) ((A) << (C)) -#define LSR(A, C) ((A) >> (C)) - -/* Some > 32-bit optimizations */ -#if M68K_INT_GT_32_BIT - /* Shift left and right */ - #define LSR_32(A, C) ((A) >> (C)) - #define LSL_32(A, C) ((A) << (C)) -#else - /* We have to do this because the morons at ANSI decided that shifts - * by >= data size are undefined. - */ - #define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0) - #define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0) -#endif /* M68K_INT_GT_32_BIT */ - -#if M68K_USE_64_BIT - #define LSL_32_64(A, C) ((A) << (C)) - #define LSR_32_64(A, C) ((A) >> (C)) - #define ROL_33_64(A, C) (LSL_32_64(A, C) | LSR_32_64(A, 33-(C))) - #define ROR_33_64(A, C) (LSR_32_64(A, C) | LSL_32_64(A, 33-(C))) -#endif /* M68K_USE_64_BIT */ - -#define ROL_8(A, C) MASK_OUT_ABOVE_8(LSL(A, C) | LSR(A, 8-(C))) -#define ROL_9(A, C) (LSL(A, C) | LSR(A, 9-(C))) -#define ROL_16(A, C) MASK_OUT_ABOVE_16(LSL(A, C) | LSR(A, 16-(C))) -#define ROL_17(A, C) (LSL(A, C) | LSR(A, 17-(C))) -#define ROL_32(A, C) MASK_OUT_ABOVE_32(LSL_32(A, C) | LSR_32(A, 32-(C))) -#define ROL_33(A, C) (LSL_32(A, C) | LSR_32(A, 33-(C))) - -#define ROR_8(A, C) MASK_OUT_ABOVE_8(LSR(A, C) | LSL(A, 8-(C))) -#define ROR_9(A, C) (LSR(A, C) | LSL(A, 9-(C))) -#define ROR_16(A, C) MASK_OUT_ABOVE_16(LSR(A, C) | LSL(A, 16-(C))) -#define ROR_17(A, C) (LSR(A, C) | LSL(A, 17-(C))) -#define ROR_32(A, C) MASK_OUT_ABOVE_32(LSR_32(A, C) | LSL_32(A, 32-(C))) -#define ROR_33(A, C) (LSR_32(A, C) | LSL_32(A, 33-(C))) - - - -/* ------------------------------ CPU Access ------------------------------ */ - -/* Access the CPU registers */ -#define REG_DA m68ki_cpu.dar /* easy access to data and address regs */ -#define REG_D m68ki_cpu.dar -#define REG_A (m68ki_cpu.dar+8) -#define REG_PC m68ki_cpu.pc -#define REG_SP_BASE m68ki_cpu.sp -#define REG_USP m68ki_cpu.sp[0] -#define REG_ISP m68ki_cpu.sp[4] -#define REG_SP m68ki_cpu.dar[15] -#define REG_IR m68ki_cpu.ir - -#define FLAG_T1 m68ki_cpu.t1_flag -#define FLAG_S m68ki_cpu.s_flag -#define FLAG_X m68ki_cpu.x_flag -#define FLAG_N m68ki_cpu.n_flag -#define FLAG_Z m68ki_cpu.not_z_flag -#define FLAG_V m68ki_cpu.v_flag -#define FLAG_C m68ki_cpu.c_flag -#define FLAG_INT_MASK m68ki_cpu.int_mask - -#define CPU_INT_LEVEL m68ki_cpu.int_level /* ASG: changed from CPU_INTS_PENDING */ -#define CPU_STOPPED m68ki_cpu.stopped -#if M68K_EMULATE_PREFETCH -#define CPU_PREF_ADDR m68ki_cpu.pref_addr -#define CPU_PREF_DATA m68ki_cpu.pref_data -#endif -#define CPU_ADDRESS_MASK 0x00ffffff -#if M68K_EMULATE_ADDRESS_ERROR -#define CPU_INSTR_MODE m68ki_cpu.instr_mode -#define CPU_RUN_MODE m68ki_cpu.run_mode -#endif - -#define CYC_INSTRUCTION m68ki_cycles -#define CYC_EXCEPTION m68ki_exception_cycle_table -#define CYC_BCC_NOTAKE_B ( -2 * MUL) -#define CYC_BCC_NOTAKE_W ( 2 * MUL) -#define CYC_DBCC_F_NOEXP ( -2 * MUL) -#define CYC_DBCC_F_EXP ( 2 * MUL) -#define CYC_SCC_R_TRUE ( 2 * MUL) -#define CYC_MOVEM_W ( 4 * MUL) -#define CYC_MOVEM_L ( 8 * MUL) -#define CYC_SHIFT ( 2 * MUL) -#define CYC_RESET (132 * MUL) - -#if M68K_EMULATE_INT_ACK == OPT_ON -#define CALLBACK_INT_ACK m68ki_cpu.int_ack_callback -#endif -#if M68K_EMULATE_RESET == OPT_ON -#define CALLBACK_RESET_INSTR m68ki_cpu.reset_instr_callback -#endif -#if M68K_TAS_HAS_CALLBACK == OPT_ON -#define CALLBACK_TAS_INSTR m68ki_cpu.tas_instr_callback -#endif -#if M68K_EMULATE_FC == OPT_ON -#define CALLBACK_SET_FC m68ki_cpu.set_fc_callback -#endif - - -/* ----------------------------- Configuration ---------------------------- */ - -/* These defines are dependant on the configuration defines in m68kconf.h */ - -/* Enable or disable callback functions */ -#if M68K_EMULATE_INT_ACK - #if M68K_EMULATE_INT_ACK == OPT_SPECIFY_HANDLER - #define m68ki_int_ack(A) M68K_INT_ACK_CALLBACK(A); - #else - #define m68ki_int_ack(A) CALLBACK_INT_ACK(A); - #endif -#else - /* Default action is to used autovector mode, which is most common */ - #define m68ki_int_ack(A) M68K_INT_ACK_AUTOVECTOR -#endif /* M68K_EMULATE_INT_ACK */ - -#if M68K_EMULATE_RESET - #if M68K_EMULATE_RESET == OPT_SPECIFY_HANDLER - #define m68ki_output_reset() M68K_RESET_CALLBACK(); - #else - #define m68ki_output_reset() CALLBACK_RESET_INSTR(); - #endif -#else - #define m68ki_output_reset() -#endif /* M68K_EMULATE_RESET */ - -#if M68K_TAS_HAS_CALLBACK - #if M68K_TAS_HAS_CALLBACK == OPT_SPECIFY_HANDLER - #define m68ki_tas_callback() M68K_TAS_CALLBACK() - #else - #define m68ki_tas_callback() CALLBACK_TAS_INSTR() - #endif -#else - #define m68ki_tas_callback() 0 -#endif /* M68K_TAS_HAS_CALLBACK */ - - -/* Enable or disable function code emulation */ -#if M68K_EMULATE_FC - #if M68K_EMULATE_FC == OPT_SPECIFY_HANDLER - #define m68ki_set_fc(A) M68K_SET_FC_CALLBACK(A); - #else - #define m68ki_set_fc(A) CALLBACK_SET_FC(A); - #endif - #define m68ki_use_data_space() m68ki_cpu.address_space = FUNCTION_CODE_USER_DATA; - #define m68ki_use_program_space() m68ki_cpu.address_space = FUNCTION_CODE_USER_PROGRAM; - #define m68ki_get_address_space() m68ki_cpu.address_space -#else - #define m68ki_set_fc(A) - #define m68ki_use_data_space() - #define m68ki_use_program_space() - #define m68ki_get_address_space() FUNCTION_CODE_USER_DATA -#endif /* M68K_EMULATE_FC */ - - -/* Enable or disable trace emulation */ -#if M68K_EMULATE_TRACE - /* Initiates trace checking before each instruction (t1) */ - #define m68ki_trace_t1() m68ki_cpu.tracing = FLAG_T1; - /* Clear all tracing */ - #define m68ki_clear_trace() m68ki_cpu.tracing = 0; - /* Cause a trace exception if we are tracing */ - #define m68ki_exception_if_trace() if(m68ki_cpu.tracing) m68ki_exception_trace(); -#else - #define m68ki_trace_t1() - #define m68ki_clear_trace() - #define m68ki_exception_if_trace() -#endif /* M68K_EMULATE_TRACE */ - - -/* Enable or disable Address error emulation */ -#if M68K_EMULATE_ADDRESS_ERROR - #define m68ki_set_address_error_trap() \ - if(setjmp(m68ki_cpu.aerr_trap) != 0) \ - { \ - m68ki_exception_address_error(); \ - } - - #define m68ki_check_address_error(ADDR, WRITE_MODE, FC) \ - if((ADDR)&1) \ - { \ - if (m68ki_cpu.aerr_enabled) \ - { \ - m68ki_cpu.aerr_address = ADDR; \ - m68ki_cpu.aerr_write_mode = WRITE_MODE; \ - m68ki_cpu.aerr_fc = FC; \ - longjmp(m68ki_cpu.aerr_trap, 1); \ - } \ - } -#else - #define m68ki_set_address_error_trap() - #define m68ki_check_address_error(ADDR, WRITE_MODE, FC) -#endif /* M68K_ADDRESS_ERROR */ - - -/* -------------------------- EA / Operand Access ------------------------- */ - -/* - * The general instruction format follows this pattern: - * .... XXX. .... .YYY - * where XXX is register X and YYY is register Y - */ - -/* Data Register Isolation */ -#define DX (REG_D[(REG_IR >> 9) & 7]) -#define DY (REG_D[REG_IR & 7]) - -/* Address Register Isolation */ -#define AX (REG_A[(REG_IR >> 9) & 7]) -#define AY (REG_A[REG_IR & 7]) - -/* Effective Address Calculations */ -#define EA_AY_AI_8() AY /* address register indirect */ -#define EA_AY_AI_16() EA_AY_AI_8() -#define EA_AY_AI_32() EA_AY_AI_8() -#define EA_AY_PI_8() (AY++) /* postincrement (size = byte) */ -#define EA_AY_PI_16() ((AY+=2)-2) /* postincrement (size = word) */ -#define EA_AY_PI_32() ((AY+=4)-4) /* postincrement (size = long) */ -#define EA_AY_PD_8() (--AY) /* predecrement (size = byte) */ -#define EA_AY_PD_16() (AY-=2) /* predecrement (size = word) */ -#define EA_AY_PD_32() (AY-=4) /* predecrement (size = long) */ -#define EA_AY_DI_8() (AY+MAKE_INT_16(m68ki_read_imm_16())) /* displacement */ -#define EA_AY_DI_16() EA_AY_DI_8() -#define EA_AY_DI_32() EA_AY_DI_8() -#define EA_AY_IX_8() m68ki_get_ea_ix(AY) /* indirect + index */ -#define EA_AY_IX_16() EA_AY_IX_8() -#define EA_AY_IX_32() EA_AY_IX_8() - -#define EA_AX_AI_8() AX -#define EA_AX_AI_16() EA_AX_AI_8() -#define EA_AX_AI_32() EA_AX_AI_8() -#define EA_AX_PI_8() (AX++) -#define EA_AX_PI_16() ((AX+=2)-2) -#define EA_AX_PI_32() ((AX+=4)-4) -#define EA_AX_PD_8() (--AX) -#define EA_AX_PD_16() (AX-=2) -#define EA_AX_PD_32() (AX-=4) -#define EA_AX_DI_8() (AX+MAKE_INT_16(m68ki_read_imm_16())) -#define EA_AX_DI_16() EA_AX_DI_8() -#define EA_AX_DI_32() EA_AX_DI_8() -#define EA_AX_IX_8() m68ki_get_ea_ix(AX) -#define EA_AX_IX_16() EA_AX_IX_8() -#define EA_AX_IX_32() EA_AX_IX_8() - -#define EA_A7_PI_8() ((REG_A[7]+=2)-2) -#define EA_A7_PD_8() (REG_A[7]-=2) - -#define EA_AW_8() MAKE_INT_16(m68ki_read_imm_16()) /* absolute word */ -#define EA_AW_16() EA_AW_8() -#define EA_AW_32() EA_AW_8() -#define EA_AL_8() m68ki_read_imm_32() /* absolute long */ -#define EA_AL_16() EA_AL_8() -#define EA_AL_32() EA_AL_8() -#define EA_PCDI_8() m68ki_get_ea_pcdi() /* pc indirect + displacement */ -#define EA_PCDI_16() EA_PCDI_8() -#define EA_PCDI_32() EA_PCDI_8() -#define EA_PCIX_8() m68ki_get_ea_pcix() /* pc indirect + index */ -#define EA_PCIX_16() EA_PCIX_8() -#define EA_PCIX_32() EA_PCIX_8() - - -#define OPER_I_8() m68ki_read_imm_8() -#define OPER_I_16() m68ki_read_imm_16() -#define OPER_I_32() m68ki_read_imm_32() - - -/* --------------------------- Status Register ---------------------------- */ - -/* Flag Calculation Macros */ -#define CFLAG_8(A) (A) -#define CFLAG_16(A) ((A)>>8) - -#if M68K_INT_GT_32_BIT - #define CFLAG_ADD_32(S, D, R) ((R)>>24) - #define CFLAG_SUB_32(S, D, R) ((R)>>24) -#else - #define CFLAG_ADD_32(S, D, R) (((S & D) | (~R & (S | D)))>>23) - #define CFLAG_SUB_32(S, D, R) (((S & R) | (~D & (S | R)))>>23) -#endif /* M68K_INT_GT_32_BIT */ - -#define VFLAG_ADD_8(S, D, R) ((S^R) & (D^R)) -#define VFLAG_ADD_16(S, D, R) (((S^R) & (D^R))>>8) -#define VFLAG_ADD_32(S, D, R) (((S^R) & (D^R))>>24) - -#define VFLAG_SUB_8(S, D, R) ((S^D) & (R^D)) -#define VFLAG_SUB_16(S, D, R) (((S^D) & (R^D))>>8) -#define VFLAG_SUB_32(S, D, R) (((S^D) & (R^D))>>24) - -#define NFLAG_8(A) (A) -#define NFLAG_16(A) ((A)>>8) -#define NFLAG_32(A) ((A)>>24) -#define NFLAG_64(A) ((A)>>56) - -#define ZFLAG_8(A) MASK_OUT_ABOVE_8(A) -#define ZFLAG_16(A) MASK_OUT_ABOVE_16(A) -#define ZFLAG_32(A) MASK_OUT_ABOVE_32(A) - - -/* Flag values */ -#define NFLAG_SET 0x80 -#define NFLAG_CLEAR 0 -#define CFLAG_SET 0x100 -#define CFLAG_CLEAR 0 -#define XFLAG_SET 0x100 -#define XFLAG_CLEAR 0 -#define VFLAG_SET 0x80 -#define VFLAG_CLEAR 0 -#define ZFLAG_SET 0 -#define ZFLAG_CLEAR 0xffffffff -#define SFLAG_SET 4 -#define SFLAG_CLEAR 0 - -/* Turn flag values into 1 or 0 */ -#define XFLAG_AS_1() ((FLAG_X>>8)&1) -#define NFLAG_AS_1() ((FLAG_N>>7)&1) -#define VFLAG_AS_1() ((FLAG_V>>7)&1) -#define ZFLAG_AS_1() (!FLAG_Z) -#define CFLAG_AS_1() ((FLAG_C>>8)&1) - - -/* Conditions */ -#define COND_CS() (FLAG_C&0x100) -#define COND_CC() (!COND_CS()) -#define COND_VS() (FLAG_V&0x80) -#define COND_VC() (!COND_VS()) -#define COND_NE() FLAG_Z -#define COND_EQ() (!COND_NE()) -#define COND_MI() (FLAG_N&0x80) -#define COND_PL() (!COND_MI()) -#define COND_LT() ((FLAG_N^FLAG_V)&0x80) -#define COND_GE() (!COND_LT()) -#define COND_HI() (COND_CC() && COND_NE()) -#define COND_LS() (COND_CS() || COND_EQ()) -#define COND_GT() (COND_GE() && COND_NE()) -#define COND_LE() (COND_LT() || COND_EQ()) - -/* Reversed conditions */ -#define COND_NOT_CS() COND_CC() -#define COND_NOT_CC() COND_CS() -#define COND_NOT_VS() COND_VC() -#define COND_NOT_VC() COND_VS() -#define COND_NOT_NE() COND_EQ() -#define COND_NOT_EQ() COND_NE() -#define COND_NOT_MI() COND_PL() -#define COND_NOT_PL() COND_MI() -#define COND_NOT_LT() COND_GE() -#define COND_NOT_GE() COND_LT() -#define COND_NOT_HI() COND_LS() -#define COND_NOT_LS() COND_HI() -#define COND_NOT_GT() COND_LE() -#define COND_NOT_LE() COND_GT() - -/* Not real conditions, but here for convenience */ -#define COND_XS() (FLAG_X&0x100) -#define COND_XC() (!COND_XS) - - -/* Get the condition code register */ -#define m68ki_get_ccr() ((COND_XS() >> 4) | \ - (COND_MI() >> 4) | \ - (COND_EQ() << 2) | \ - (COND_VS() >> 6) | \ - (COND_CS() >> 8)) - -/* Get the status register */ -#define m68ki_get_sr() ( FLAG_T1 | \ - (FLAG_S << 11) | \ - FLAG_INT_MASK | \ - m68ki_get_ccr()) - - - -/* ---------------------------- Cycle Counting ---------------------------- */ - -#define USE_CYCLES(A) m68ki_cpu.cycles += (A) -#define SET_CYCLES(A) m68ki_cpu.cycles = (A) - - -/* ----------------------------- Read / Write ----------------------------- */ - -/* Read data immediately following the PC */ -#define m68k_read_immediate_16(address) *(uint16 *)(m68ki_cpu.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)) -#define m68k_read_immediate_32(address) (m68k_read_immediate_16(address) << 16) | (m68k_read_immediate_16(address+2)) - -/* Read data relative to the PC */ -#define m68k_read_pcrelative_8(address) READ_BYTE(m68ki_cpu.memory_map[((address)>>16)&0xff].base, (address) & 0xffff) -#define m68k_read_pcrelative_16(address) m68k_read_immediate_16(address) -#define m68k_read_pcrelative_32(address) m68k_read_immediate_32(address) - -/* Read from the current address space */ -#define m68ki_read_8(A) m68ki_read_8_fc (A, FLAG_S | m68ki_get_address_space()) -#define m68ki_read_16(A) m68ki_read_16_fc(A, FLAG_S | m68ki_get_address_space()) -#define m68ki_read_32(A) m68ki_read_32_fc(A, FLAG_S | m68ki_get_address_space()) - -/* Write to the current data space */ -#define m68ki_write_8(A, V) m68ki_write_8_fc (A, FLAG_S | FUNCTION_CODE_USER_DATA, V) -#define m68ki_write_16(A, V) m68ki_write_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V) -#define m68ki_write_32(A, V) m68ki_write_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V) - -/* map read immediate 8 to read immediate 16 */ -#define m68ki_read_imm_8() MASK_OUT_ABOVE_8(m68ki_read_imm_16()) - -/* Map PC-relative reads */ -#define m68ki_read_pcrel_8(A) m68k_read_pcrelative_8(A) -#define m68ki_read_pcrel_16(A) m68k_read_pcrelative_16(A) -#define m68ki_read_pcrel_32(A) m68k_read_pcrelative_32(A) - -/* Read from the program space */ -#define m68ki_read_program_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) -#define m68ki_read_program_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) -#define m68ki_read_program_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) - -/* Read from the data space */ -#define m68ki_read_data_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) -#define m68ki_read_data_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) -#define m68ki_read_data_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) - - - -/* ======================================================================== */ -/* =============================== PROTOTYPES ============================= */ -/* ======================================================================== */ - -/* Used by shift & rotate instructions */ -static const uint8 m68ki_shift_8_table[65] = -{ - 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff -}; - -static const uint16 m68ki_shift_16_table[65] = -{ - 0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, - 0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff -}; - -static const uint m68ki_shift_32_table[65] = -{ - 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000, - 0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, - 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000, - 0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, - 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8, - 0xfffffffc, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff -}; - - -/* Number of clock cycles to use for exception processing. - * I used 4 for any vectors that are undocumented for processing times. - */ -static const uint16 m68ki_exception_cycle_table[256] = -{ - 40*MUL, /* 0: Reset - Initial Stack Pointer */ - 4*MUL, /* 1: Reset - Initial Program Counter */ - 50*MUL, /* 2: Bus Error (unemulated) */ - 50*MUL, /* 3: Address Error (unemulated) */ - 34*MUL, /* 4: Illegal Instruction */ - 38*MUL, /* 5: Divide by Zero -- ASG: changed from 42 */ - 40*MUL, /* 6: CHK -- ASG: chanaged from 44 */ - 34*MUL, /* 7: TRAPV */ - 34*MUL, /* 8: Privilege Violation */ - 34*MUL, /* 9: Trace */ - 4*MUL, /* 10: 1010 */ - 4*MUL, /* 11: 1111 */ - 4*MUL, /* 12: RESERVED */ - 4*MUL, /* 13: Coprocessor Protocol Violation (unemulated) */ - 4*MUL, /* 14: Format Error */ - 44*MUL, /* 15: Uninitialized Interrupt */ - 4*MUL, /* 16: RESERVED */ - 4*MUL, /* 17: RESERVED */ - 4*MUL, /* 18: RESERVED */ - 4*MUL, /* 19: RESERVED */ - 4*MUL, /* 20: RESERVED */ - 4*MUL, /* 21: RESERVED */ - 4*MUL, /* 22: RESERVED */ - 4*MUL, /* 23: RESERVED */ - 44*MUL, /* 24: Spurious Interrupt */ - 44*MUL, /* 25: Level 1 Interrupt Autovector */ - 44*MUL, /* 26: Level 2 Interrupt Autovector */ - 44*MUL, /* 27: Level 3 Interrupt Autovector */ - 44*MUL, /* 28: Level 4 Interrupt Autovector */ - 44*MUL, /* 29: Level 5 Interrupt Autovector */ - 44*MUL, /* 30: Level 6 Interrupt Autovector */ - 44*MUL, /* 31: Level 7 Interrupt Autovector */ - 34*MUL, /* 32: TRAP #0 -- ASG: chanaged from 38 */ - 34*MUL, /* 33: TRAP #1 */ - 34*MUL, /* 34: TRAP #2 */ - 34*MUL, /* 35: TRAP #3 */ - 34*MUL, /* 36: TRAP #4 */ - 34*MUL, /* 37: TRAP #5 */ - 34*MUL, /* 38: TRAP #6 */ - 34*MUL, /* 39: TRAP #7 */ - 34*MUL, /* 40: TRAP #8 */ - 34*MUL, /* 41: TRAP #9 */ - 34*MUL, /* 42: TRAP #10 */ - 34*MUL, /* 43: TRAP #11 */ - 34*MUL, /* 44: TRAP #12 */ - 34*MUL, /* 45: TRAP #13 */ - 34*MUL, /* 46: TRAP #14 */ - 34*MUL, /* 47: TRAP #15 */ - 4*MUL, /* 48: FP Branch or Set on Unknown Condition (unemulated) */ - 4*MUL, /* 49: FP Inexact Result (unemulated) */ - 4*MUL, /* 50: FP Divide by Zero (unemulated) */ - 4*MUL, /* 51: FP Underflow (unemulated) */ - 4*MUL, /* 52: FP Operand Error (unemulated) */ - 4*MUL, /* 53: FP Overflow (unemulated) */ - 4*MUL, /* 54: FP Signaling NAN (unemulated) */ - 4*MUL, /* 55: FP Unimplemented Data Type (unemulated) */ - 4*MUL, /* 56: MMU Configuration Error (unemulated) */ - 4*MUL, /* 57: MMU Illegal Operation Error (unemulated) */ - 4*MUL, /* 58: MMU Access Level Violation Error (unemulated) */ - 4*MUL, /* 59: RESERVED */ - 4*MUL, /* 60: RESERVED */ - 4*MUL, /* 61: RESERVED */ - 4*MUL, /* 62: RESERVED */ - 4*MUL, /* 63: RESERVED */ - /* 64-255: User Defined */ - 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL, - 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL, - 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL, - 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL, - 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL, - 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL -}; - -/* Read data immediately after the program counter */ -INLINE uint m68ki_read_imm_16(void); -INLINE uint m68ki_read_imm_32(void); - -/* Read data with specific function code */ -INLINE uint m68ki_read_8_fc (uint address, uint fc); -INLINE uint m68ki_read_16_fc (uint address, uint fc); -INLINE uint m68ki_read_32_fc (uint address, uint fc); - -/* Write data with specific function code */ -INLINE void m68ki_write_8_fc (uint address, uint fc, uint value); -INLINE void m68ki_write_16_fc(uint address, uint fc, uint value); -INLINE void m68ki_write_32_fc(uint address, uint fc, uint value); - -/* Indexed and PC-relative ea fetching */ -INLINE uint m68ki_get_ea_pcdi(void); -INLINE uint m68ki_get_ea_pcix(void); -INLINE uint m68ki_get_ea_ix(uint An); - -/* Operand fetching */ -INLINE uint OPER_AY_AI_8(void); -INLINE uint OPER_AY_AI_16(void); -INLINE uint OPER_AY_AI_32(void); -INLINE uint OPER_AY_PI_8(void); -INLINE uint OPER_AY_PI_16(void); -INLINE uint OPER_AY_PI_32(void); -INLINE uint OPER_AY_PD_8(void); -INLINE uint OPER_AY_PD_16(void); -INLINE uint OPER_AY_PD_32(void); -INLINE uint OPER_AY_DI_8(void); -INLINE uint OPER_AY_DI_16(void); -INLINE uint OPER_AY_DI_32(void); -INLINE uint OPER_AY_IX_8(void); -INLINE uint OPER_AY_IX_16(void); -INLINE uint OPER_AY_IX_32(void); - -INLINE uint OPER_AX_AI_8(void); -INLINE uint OPER_AX_AI_16(void); -INLINE uint OPER_AX_AI_32(void); -INLINE uint OPER_AX_PI_8(void); -INLINE uint OPER_AX_PI_16(void); -INLINE uint OPER_AX_PI_32(void); -INLINE uint OPER_AX_PD_8(void); -INLINE uint OPER_AX_PD_16(void); -INLINE uint OPER_AX_PD_32(void); -INLINE uint OPER_AX_DI_8(void); -INLINE uint OPER_AX_DI_16(void); -INLINE uint OPER_AX_DI_32(void); -INLINE uint OPER_AX_IX_8(void); -INLINE uint OPER_AX_IX_16(void); -INLINE uint OPER_AX_IX_32(void); - -INLINE uint OPER_A7_PI_8(void); -INLINE uint OPER_A7_PD_8(void); - -INLINE uint OPER_AW_8(void); -INLINE uint OPER_AW_16(void); -INLINE uint OPER_AW_32(void); -INLINE uint OPER_AL_8(void); -INLINE uint OPER_AL_16(void); -INLINE uint OPER_AL_32(void); -INLINE uint OPER_PCDI_8(void); -INLINE uint OPER_PCDI_16(void); -INLINE uint OPER_PCDI_32(void); -INLINE uint OPER_PCIX_8(void); -INLINE uint OPER_PCIX_16(void); -INLINE uint OPER_PCIX_32(void); - -/* Stack operations */ -INLINE void m68ki_push_16(uint value); -INLINE void m68ki_push_32(uint value); -INLINE uint m68ki_pull_16(void); -INLINE uint m68ki_pull_32(void); - -/* Program flow operations */ -INLINE void m68ki_jump(uint new_pc); -INLINE void m68ki_jump_vector(uint vector); -INLINE void m68ki_branch_8(uint offset); -INLINE void m68ki_branch_16(uint offset); -INLINE void m68ki_branch_32(uint offset); - -/* Status register operations. */ -INLINE void m68ki_set_s_flag(uint value); /* Only bit 2 of value should be set (i.e. 4 or 0) */ -INLINE void m68ki_set_ccr(uint value); /* set the condition code register */ -INLINE void m68ki_set_sr(uint value); /* set the status register */ - -/* Exception processing */ -INLINE uint m68ki_init_exception(void); /* Initial exception processing */ -INLINE void m68ki_stack_frame_3word(uint pc, uint sr); /* Stack various frame types */ -#if M68K_EMULATE_ADDRESS_ERROR -INLINE void m68ki_stack_frame_buserr(uint sr); -#endif -INLINE void m68ki_exception_trap(uint vector); -INLINE void m68ki_exception_trapN(uint vector); -#if M68K_EMULATE_TRACE -INLINE void m68ki_exception_trace(void); -#endif -static void m68ki_exception_privilege_violation(void); /* do not inline in order to reduce function size and allow inlining of read/write functions by the compile */ -INLINE void m68ki_exception_1010(void); -INLINE void m68ki_exception_1111(void); -INLINE void m68ki_exception_illegal(void); -#if M68K_EMULATE_ADDRESS_ERROR -INLINE void m68ki_exception_address_error(void); -#endif -INLINE void m68ki_exception_interrupt(uint int_level); -INLINE void m68ki_check_interrupts(void); /* ASG: check for interrupts */ - -/* ======================================================================== */ -/* =========================== UTILITY FUNCTIONS ========================== */ -/* ======================================================================== */ - - -/* ---------------------------- Read Immediate ---------------------------- */ - -/* Handles all immediate reads, does address error check, function code setting, - * and prefetching if they are enabled in m68kconf.h - */ -INLINE uint m68ki_read_imm_16(void) -{ - m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ -#if M68K_CHECK_PC_ADDRESS_ERROR - m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ -#endif -#if M68K_EMULATE_PREFETCH - if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) - { - CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); - CPU_PREF_DATA = m68k_read_immediate_32(CPU_PREF_ADDR); - } - REG_PC += 2; - return MASK_OUT_ABOVE_16(CPU_PREF_DATA >> ((2-((REG_PC-2)&2))<<3)); -#else - uint pc = REG_PC; - REG_PC += 2; - return m68k_read_immediate_16(pc); -#endif /* M68K_EMULATE_PREFETCH */ -} - -INLINE uint m68ki_read_imm_32(void) -{ -#if M68K_EMULATE_PREFETCH - uint temp_val; - - m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ -#if M68K_CHECK_PC_ADDRESS_ERROR - m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ -#endif - if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) - { - CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); - CPU_PREF_DATA = m68k_read_immediate_32(CPU_PREF_ADDR); - } - temp_val = CPU_PREF_DATA; - REG_PC += 2; - if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) - { - CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); - CPU_PREF_DATA = m68k_read_immediate_32(CPU_PREF_ADDR); - temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | (CPU_PREF_DATA >> 16)); - } - REG_PC += 2; - - return temp_val; -#else - m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ -#if M68K_CHECK_PC_ADDRESS_ERROR - m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ -#endif - uint pc = REG_PC; - REG_PC += 4; - return m68k_read_immediate_32(pc); -#endif /* M68K_EMULATE_PREFETCH */ -} - - - -/* ------------------------- Top level read/write ------------------------- */ - -/* Handles all memory accesses (except for immediate reads if they are - * configured to use separate functions in m68kconf.h). - * All memory accesses must go through these top level functions. - * These functions will also check for address error and set the function - * code if they are enabled in m68kconf.h. - */ -INLINE uint m68ki_read_8_fc(uint address, uint fc) -{ - cpu_memory_map *temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];; - if (biz_readcb) - biz_readcb(address); - - if(biz_cdcallback) - CDLog68k(address,eCDLog_Flags_Data68k); - - m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ - - if (temp->read8) return (*temp->read8)(ADDRESS_68K(address)); - else return READ_BYTE(temp->base, (address) & 0xffff); -} - -INLINE uint m68ki_read_16_fc(uint address, uint fc) -{ - cpu_memory_map *temp; - if (biz_readcb) - biz_readcb(address); - - if(biz_cdcallback) - { - CDLog68k(address,eCDLog_Flags_Data68k); - CDLog68k(address+1,eCDLog_Flags_Data68k); - } - - m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ - m68ki_check_address_error(address, MODE_READ, fc) /* auto-disable (see m68kcpu.h) */ - - temp = &m68ki_cpu.memory_map[((address)>>16)&0xff]; - if (temp->read16) return (*temp->read16)(ADDRESS_68K(address)); - else return *(uint16 *)(temp->base + ((address) & 0xffff)); -} - -INLINE uint m68ki_read_32_fc(uint address, uint fc) -{ - cpu_memory_map *temp; - if (biz_readcb) - biz_readcb(address); - - if(biz_cdcallback) - { - CDLog68k(address,eCDLog_Flags_Data68k); - CDLog68k(address+1,eCDLog_Flags_Data68k); - CDLog68k(address+2,eCDLog_Flags_Data68k); - CDLog68k(address+3,eCDLog_Flags_Data68k); - } - - m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ - m68ki_check_address_error(address, MODE_READ, fc) /* auto-disable (see m68kcpu.h) */ - - temp = &m68ki_cpu.memory_map[((address)>>16)&0xff]; - if (temp->read16) return ((*temp->read16)(ADDRESS_68K(address)) << 16) | ((*temp->read16)(ADDRESS_68K(address + 2))); - else return m68k_read_immediate_32(address); -} - -INLINE void m68ki_write_8_fc(uint address, uint fc, uint value) -{ - cpu_memory_map *temp; - if (biz_writecb) - biz_writecb(address); - - m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ - - temp = &m68ki_cpu.memory_map[((address)>>16)&0xff]; - if (temp->write8) (*temp->write8)(ADDRESS_68K(address),value); - else WRITE_BYTE(temp->base, (address) & 0xffff, value); -} - -INLINE void m68ki_write_16_fc(uint address, uint fc, uint value) -{ - cpu_memory_map *temp; - if (biz_writecb) - biz_writecb(address); - - m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ - m68ki_check_address_error(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */ - - temp = &m68ki_cpu.memory_map[((address)>>16)&0xff]; - if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value); - else *(uint16 *)(temp->base + ((address) & 0xffff)) = value; -} - -INLINE void m68ki_write_32_fc(uint address, uint fc, uint value) -{ - cpu_memory_map *temp; - if (biz_writecb) - biz_writecb(address); - - m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ - m68ki_check_address_error(address, MODE_WRITE, fc) /* auto-disable (see m68kcpu.h) */ - - temp = &m68ki_cpu.memory_map[((address)>>16)&0xff]; - if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value>>16); - else *(uint16 *)(temp->base + ((address) & 0xffff)) = value >> 16; - - temp = &m68ki_cpu.memory_map[((address + 2)>>16)&0xff]; - if (temp->write16) (*temp->write16)(ADDRESS_68K(address+2),value&0xffff); - else *(uint16 *)(temp->base + ((address + 2) & 0xffff)) = value; -} - - -/* --------------------- Effective Address Calculation -------------------- */ - -/* The program counter relative addressing modes cause operands to be - * retrieved from program space, not data space. - */ -INLINE uint m68ki_get_ea_pcdi(void) -{ - uint old_pc = REG_PC; - m68ki_use_program_space() /* auto-disable */ - return old_pc + MAKE_INT_16(m68ki_read_imm_16()); -} - - -INLINE uint m68ki_get_ea_pcix(void) -{ - m68ki_use_program_space() /* auto-disable */ - return m68ki_get_ea_ix(REG_PC); -} - -/* Indexed addressing modes are encoded as follows: - * - * Base instruction format: - * F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0 - * x x x x x x x x x x | 1 1 0 | BASE REGISTER (An) - * - * Base instruction format for destination EA in move instructions: - * F E D C | B A 9 | 8 7 6 | 5 4 3 2 1 0 - * x x x x | BASE REG | 1 1 0 | X X X X X X (An) - * - * Brief extension format: - * F | E D C | B | A 9 | 8 | 7 6 5 4 3 2 1 0 - * D/A | REGISTER | W/L | SCALE | 0 | DISPLACEMENT - * - * Full extension format: - * F E D C B A 9 8 7 6 5 4 3 2 1 0 - * D/A | REGISTER | W/L | SCALE | 1 | BS | IS | BD SIZE | 0 | I/IS - * BASE DISPLACEMENT (0, 16, 32 bit) (bd) - * OUTER DISPLACEMENT (0, 16, 32 bit) (od) - * - * D/A: 0 = Dn, 1 = An (Xn) - * W/L: 0 = W (sign extend), 1 = L (.SIZE) - * SCALE: 00=1, 01=2, 10=4, 11=8 (*SCALE) - * BS: 0=add base reg, 1=suppress base reg (An suppressed) - * IS: 0=add index, 1=suppress index (Xn suppressed) - * BD SIZE: 00=reserved, 01=NULL, 10=Word, 11=Long (size of bd) - * - * IS I/IS Operation - * 0 000 No Memory Indirect - * 0 001 indir prex with null outer - * 0 010 indir prex with word outer - * 0 011 indir prex with long outer - * 0 100 reserved - * 0 101 indir postx with null outer - * 0 110 indir postx with word outer - * 0 111 indir postx with long outer - * 1 000 no memory indirect - * 1 001 mem indir with null outer - * 1 010 mem indir with word outer - * 1 011 mem indir with long outer - * 1 100-111 reserved - */ -INLINE uint m68ki_get_ea_ix(uint An) -{ - /* An = base register */ - uint extension = m68ki_read_imm_16(); - - uint Xn = 0; /* Index register */ - - /* Calculate index */ - Xn = REG_DA[extension>>12]; /* Xn */ - if(!BIT_B(extension)) /* W/L */ - Xn = MAKE_INT_16(Xn); - - /* Add base register and displacement and return */ - return An + Xn + MAKE_INT_8(extension); -} - - -/* Fetch operands */ -INLINE uint OPER_AY_AI_8(void) {uint ea = EA_AY_AI_8(); return m68ki_read_8(ea); } -INLINE uint OPER_AY_AI_16(void) {uint ea = EA_AY_AI_16(); return m68ki_read_16(ea);} -INLINE uint OPER_AY_AI_32(void) {uint ea = EA_AY_AI_32(); return m68ki_read_32(ea);} -INLINE uint OPER_AY_PI_8(void) {uint ea = EA_AY_PI_8(); return m68ki_read_8(ea); } -INLINE uint OPER_AY_PI_16(void) {uint ea = EA_AY_PI_16(); return m68ki_read_16(ea);} -INLINE uint OPER_AY_PI_32(void) {uint ea = EA_AY_PI_32(); return m68ki_read_32(ea);} -INLINE uint OPER_AY_PD_8(void) {uint ea = EA_AY_PD_8(); return m68ki_read_8(ea); } -INLINE uint OPER_AY_PD_16(void) {uint ea = EA_AY_PD_16(); return m68ki_read_16(ea);} -INLINE uint OPER_AY_PD_32(void) {uint ea = EA_AY_PD_32(); return m68ki_read_32(ea);} -INLINE uint OPER_AY_DI_8(void) {uint ea = EA_AY_DI_8(); return m68ki_read_8(ea); } -INLINE uint OPER_AY_DI_16(void) {uint ea = EA_AY_DI_16(); return m68ki_read_16(ea);} -INLINE uint OPER_AY_DI_32(void) {uint ea = EA_AY_DI_32(); return m68ki_read_32(ea);} -INLINE uint OPER_AY_IX_8(void) {uint ea = EA_AY_IX_8(); return m68ki_read_8(ea); } -INLINE uint OPER_AY_IX_16(void) {uint ea = EA_AY_IX_16(); return m68ki_read_16(ea);} -INLINE uint OPER_AY_IX_32(void) {uint ea = EA_AY_IX_32(); return m68ki_read_32(ea);} - -INLINE uint OPER_AX_AI_8(void) {uint ea = EA_AX_AI_8(); return m68ki_read_8(ea); } -INLINE uint OPER_AX_AI_16(void) {uint ea = EA_AX_AI_16(); return m68ki_read_16(ea);} -INLINE uint OPER_AX_AI_32(void) {uint ea = EA_AX_AI_32(); return m68ki_read_32(ea);} -INLINE uint OPER_AX_PI_8(void) {uint ea = EA_AX_PI_8(); return m68ki_read_8(ea); } -INLINE uint OPER_AX_PI_16(void) {uint ea = EA_AX_PI_16(); return m68ki_read_16(ea);} -INLINE uint OPER_AX_PI_32(void) {uint ea = EA_AX_PI_32(); return m68ki_read_32(ea);} -INLINE uint OPER_AX_PD_8(void) {uint ea = EA_AX_PD_8(); return m68ki_read_8(ea); } -INLINE uint OPER_AX_PD_16(void) {uint ea = EA_AX_PD_16(); return m68ki_read_16(ea);} -INLINE uint OPER_AX_PD_32(void) {uint ea = EA_AX_PD_32(); return m68ki_read_32(ea);} -INLINE uint OPER_AX_DI_8(void) {uint ea = EA_AX_DI_8(); return m68ki_read_8(ea); } -INLINE uint OPER_AX_DI_16(void) {uint ea = EA_AX_DI_16(); return m68ki_read_16(ea);} -INLINE uint OPER_AX_DI_32(void) {uint ea = EA_AX_DI_32(); return m68ki_read_32(ea);} -INLINE uint OPER_AX_IX_8(void) {uint ea = EA_AX_IX_8(); return m68ki_read_8(ea); } -INLINE uint OPER_AX_IX_16(void) {uint ea = EA_AX_IX_16(); return m68ki_read_16(ea);} -INLINE uint OPER_AX_IX_32(void) {uint ea = EA_AX_IX_32(); return m68ki_read_32(ea);} - -INLINE uint OPER_A7_PI_8(void) {uint ea = EA_A7_PI_8(); return m68ki_read_8(ea); } -INLINE uint OPER_A7_PD_8(void) {uint ea = EA_A7_PD_8(); return m68ki_read_8(ea); } - -INLINE uint OPER_AW_8(void) {uint ea = EA_AW_8(); return m68ki_read_8(ea); } -INLINE uint OPER_AW_16(void) {uint ea = EA_AW_16(); return m68ki_read_16(ea);} -INLINE uint OPER_AW_32(void) {uint ea = EA_AW_32(); return m68ki_read_32(ea);} -INLINE uint OPER_AL_8(void) {uint ea = EA_AL_8(); return m68ki_read_8(ea); } -INLINE uint OPER_AL_16(void) {uint ea = EA_AL_16(); return m68ki_read_16(ea);} -INLINE uint OPER_AL_32(void) {uint ea = EA_AL_32(); return m68ki_read_32(ea);} -INLINE uint OPER_PCDI_8(void) {uint ea = EA_PCDI_8(); return m68ki_read_pcrel_8(ea); } -INLINE uint OPER_PCDI_16(void) {uint ea = EA_PCDI_16(); return m68ki_read_pcrel_16(ea);} -INLINE uint OPER_PCDI_32(void) {uint ea = EA_PCDI_32(); return m68ki_read_pcrel_32(ea);} -INLINE uint OPER_PCIX_8(void) {uint ea = EA_PCIX_8(); return m68ki_read_pcrel_8(ea); } -INLINE uint OPER_PCIX_16(void) {uint ea = EA_PCIX_16(); return m68ki_read_pcrel_16(ea);} -INLINE uint OPER_PCIX_32(void) {uint ea = EA_PCIX_32(); return m68ki_read_pcrel_32(ea);} - - - -/* ---------------------------- Stack Functions --------------------------- */ - -/* Push/pull data from the stack */ -/* Optimized access assuming stack is always located in ROM/RAM [EkeEke] */ -INLINE void m68ki_push_16(uint value) -{ - REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2); - /*m68ki_write_16(REG_SP, value);*/ - *(uint16 *)(m68ki_cpu.memory_map[(REG_SP>>16)&0xff].base + (REG_SP & 0xffff)) = value; -} - -INLINE void m68ki_push_32(uint value) -{ - REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4); - /*m68ki_write_32(REG_SP, value);*/ - *(uint16 *)(m68ki_cpu.memory_map[(REG_SP>>16)&0xff].base + (REG_SP & 0xffff)) = value >> 16; - *(uint16 *)(m68ki_cpu.memory_map[((REG_SP + 2)>>16)&0xff].base + ((REG_SP + 2) & 0xffff)) = value & 0xffff; -} - -INLINE uint m68ki_pull_16(void) -{ - uint sp = REG_SP; - REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2); - return m68k_read_immediate_16(sp); - /*return m68ki_read_16(sp);*/ -} - -INLINE uint m68ki_pull_32(void) -{ - uint sp = REG_SP; - REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4); - return m68k_read_immediate_32(sp); - /*return m68ki_read_32(sp);*/ -} - - - -/* ----------------------------- Program Flow ----------------------------- */ - -/* Jump to a new program location or vector. - * These functions will also call the pc_changed callback if it was enabled - * in m68kconf.h. - */ -INLINE void m68ki_jump(uint new_pc) -{ - REG_PC = new_pc; -} - -INLINE void m68ki_jump_vector(uint vector) -{ - REG_PC = m68ki_read_data_32(vector<<2); -} - - -/* Branch to a new memory location. - * The 32-bit branch will call pc_changed if it was enabled in m68kconf.h. - * So far I've found no problems with not calling pc_changed for 8 or 16 - * bit branches. - */ -INLINE void m68ki_branch_8(uint offset) -{ - REG_PC += MAKE_INT_8(offset); -} - -INLINE void m68ki_branch_16(uint offset) -{ - REG_PC += MAKE_INT_16(offset); -} - -INLINE void m68ki_branch_32(uint offset) -{ - REG_PC += offset; -} - - - -/* ---------------------------- Status Register --------------------------- */ - -/* Set the S flag and change the active stack pointer. - * Note that value MUST be 4 or 0. - */ -INLINE void m68ki_set_s_flag(uint value) -{ - /* Backup the old stack pointer */ - REG_SP_BASE[FLAG_S] = REG_SP; - /* Set the S flag */ - FLAG_S = value; - /* Set the new stack pointer */ - REG_SP = REG_SP_BASE[FLAG_S]; -} - - -/* Set the condition code register */ -INLINE void m68ki_set_ccr(uint value) -{ - FLAG_X = BIT_4(value) << 4; - FLAG_N = BIT_3(value) << 4; - FLAG_Z = !BIT_2(value); - FLAG_V = BIT_1(value) << 6; - FLAG_C = BIT_0(value) << 8; -} - - -/* Set the status register and check for interrupts */ -INLINE void m68ki_set_sr(uint value) -{ - /* Set the status register */ - FLAG_T1 = BIT_F(value); - FLAG_INT_MASK = value & 0x0700; - m68ki_set_ccr(value); - m68ki_set_s_flag((value >> 11) & 4); - - /* Check current IRQ status */ - m68ki_check_interrupts(); -} - - -/* ------------------------- Exception Processing ------------------------- */ - -/* Initiate exception processing */ -INLINE uint m68ki_init_exception(void) -{ - /* Save the old status register */ - uint sr = m68ki_get_sr(); - - /* Turn off trace flag, clear pending traces */ - FLAG_T1 = 0; - m68ki_clear_trace() - - /* Enter supervisor mode */ - m68ki_set_s_flag(SFLAG_SET); - - return sr; -} - -/* 3 word stack frame (68000 only) */ -INLINE void m68ki_stack_frame_3word(uint pc, uint sr) -{ - m68ki_push_32(pc); - m68ki_push_16(sr); -} - -#if M68K_EMULATE_ADDRESS_ERROR -/* Bus error stack frame (68000 only). - */ -INLINE void m68ki_stack_frame_buserr(uint sr) -{ - m68ki_push_32(REG_PC); - m68ki_push_16(sr); - m68ki_push_16(REG_IR); - m68ki_push_32(m68ki_cpu.aerr_address); /* access address */ - /* 0 0 0 0 0 0 0 0 0 0 0 R/W I/N FC - * R/W 0 = write, 1 = read - * I/N 0 = instruction, 1 = not - * FC 3-bit function code - */ - m68ki_push_16(m68ki_cpu.aerr_write_mode | CPU_INSTR_MODE | m68ki_cpu.aerr_fc); -} -#endif - -/* Used for Group 2 exceptions. - */ -INLINE void m68ki_exception_trap(uint vector) -{ - uint sr = m68ki_init_exception(); - - m68ki_stack_frame_3word(REG_PC, sr); - - m68ki_jump_vector(vector); - - /* Use up some clock cycles */ - USE_CYCLES(CYC_EXCEPTION[vector]); -} - -/* Trap#n stacks a 0 frame but behaves like group2 otherwise */ -INLINE void m68ki_exception_trapN(uint vector) -{ - uint sr = m68ki_init_exception(); - m68ki_stack_frame_3word(REG_PC, sr); - m68ki_jump_vector(vector); - - /* Use up some clock cycles */ - USE_CYCLES(CYC_EXCEPTION[vector]); -} - -#if M68K_EMULATE_TRACE -/* Exception for trace mode */ -INLINE void m68ki_exception_trace(void) -{ - uint sr = m68ki_init_exception(); - - #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON - CPU_INSTR_MODE = INSTRUCTION_NO; - #endif /* M68K_EMULATE_ADDRESS_ERROR */ - - m68ki_stack_frame_3word(REG_PC, sr); - m68ki_jump_vector(EXCEPTION_TRACE); - - /* Trace nullifies a STOP instruction */ - CPU_STOPPED &= ~STOP_LEVEL_STOP; - - /* Use up some clock cycles */ - USE_CYCLES(CYC_EXCEPTION[EXCEPTION_TRACE]); -} -#endif - -/* Exception for privilege violation */ -static void m68ki_exception_privilege_violation(void) -{ - uint sr = m68ki_init_exception(); - - #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON - CPU_INSTR_MODE = INSTRUCTION_NO; - #endif /* M68K_EMULATE_ADDRESS_ERROR */ - - m68ki_stack_frame_3word(REG_PC-2, sr); - m68ki_jump_vector(EXCEPTION_PRIVILEGE_VIOLATION); - - /* Use up some clock cycles and undo the instruction's cycles */ - USE_CYCLES(CYC_EXCEPTION[EXCEPTION_PRIVILEGE_VIOLATION] - CYC_INSTRUCTION[REG_IR]); -} - -/* Exception for A-Line instructions */ -INLINE void m68ki_exception_1010(void) -{ - uint sr = m68ki_init_exception(); - m68ki_stack_frame_3word(REG_PC-2, sr); - m68ki_jump_vector(EXCEPTION_1010); - - /* Use up some clock cycles and undo the instruction's cycles */ - USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1010] - CYC_INSTRUCTION[REG_IR]); -} - -/* Exception for F-Line instructions */ -INLINE void m68ki_exception_1111(void) -{ - uint sr = m68ki_init_exception(); - m68ki_stack_frame_3word(REG_PC-2, sr); - m68ki_jump_vector(EXCEPTION_1111); - - /* Use up some clock cycles and undo the instruction's cycles */ - USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1111] - CYC_INSTRUCTION[REG_IR]); -} - -/* Exception for illegal instructions */ -INLINE void m68ki_exception_illegal(void) -{ - uint sr = m68ki_init_exception(); - - #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON - CPU_INSTR_MODE = INSTRUCTION_NO; - #endif /* M68K_EMULATE_ADDRESS_ERROR */ - - m68ki_stack_frame_3word(REG_PC-2, sr); - m68ki_jump_vector(EXCEPTION_ILLEGAL_INSTRUCTION); - - /* Use up some clock cycles and undo the instruction's cycles */ - USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ILLEGAL_INSTRUCTION] - CYC_INSTRUCTION[REG_IR]); -} - - -#if M68K_EMULATE_ADDRESS_ERROR -/* Exception for address error */ -INLINE void m68ki_exception_address_error(void) -{ - uint sr = m68ki_init_exception(); - - /* If we were processing a bus error, address error, or reset, - * this is a catastrophic failure. - * Halt the CPU - */ - if(CPU_RUN_MODE == RUN_MODE_BERR_AERR_RESET) - { - CPU_STOPPED = STOP_LEVEL_HALT; - SET_CYCLES(m68ki_cpu.cycle_end - CYC_INSTRUCTION[REG_IR]); - return; - } - CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET; - - /* Note: This is implemented for 68000 only! */ - m68ki_stack_frame_buserr(sr); - - m68ki_jump_vector(EXCEPTION_ADDRESS_ERROR); - - /* Use up some clock cycles and undo the instruction's cycles */ - USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ADDRESS_ERROR] - CYC_INSTRUCTION[REG_IR]); -} -#endif - -/* Service an interrupt request and start exception processing */ -INLINE void m68ki_exception_interrupt(uint int_level) -{ - uint vector, sr, new_pc; - - #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON - CPU_INSTR_MODE = INSTRUCTION_NO; - #endif /* M68K_EMULATE_ADDRESS_ERROR */ - - /* Turn off the stopped state */ - CPU_STOPPED &= STOP_LEVEL_HALT; - - /* If we are halted, don't do anything */ - if(CPU_STOPPED) - return; - - /* Always use the autovectors. */ - vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level; - - /* Start exception processing */ - sr = m68ki_init_exception(); - - /* Set the interrupt mask to the level of the one being serviced */ - FLAG_INT_MASK = int_level<<8; - - /* Acknowledge the interrupt */ - m68ki_int_ack(int_level); - - /* Get the new PC */ - new_pc = m68ki_read_data_32(vector<<2); - - /* If vector is uninitialized, call the uninitialized interrupt vector */ - if(new_pc == 0) - new_pc = m68ki_read_data_32((EXCEPTION_UNINITIALIZED_INTERRUPT<<2)); - - /* Generate a stack frame */ - m68ki_stack_frame_3word(REG_PC, sr); - - m68ki_jump(new_pc); - - /* Update cycle count now */ - USE_CYCLES(CYC_EXCEPTION[vector]); -} - -/* ASG: Check for interrupts */ -INLINE void m68ki_check_interrupts(void) -{ - if(CPU_INT_LEVEL > FLAG_INT_MASK) - m68ki_exception_interrupt(CPU_INT_LEVEL>>8); -} - - -/* ======================================================================== */ -/* ============================== END OF FILE ============================= */ -/* ======================================================================== */ - -#endif /* M68KCPU__HEADER */ +#ifndef M68KCPU__HEADER +#define M68KCPU__HEADER + +/* ======================================================================== */ +/* GENERIC 68K CORE */ +/* ======================================================================== */ + +#include +#include +#include + +#if M68K_EMULATE_ADDRESS_ERROR +#include +#endif /* M68K_EMULATE_ADDRESS_ERROR */ + +#include "m68k.h" +#include "mem68k.h" +#include "../cinterface/callbacks.h" + +void CDLog68k(uint addr, uint flags); + +/* ======================================================================== */ +/* ============================ GENERAL DEFINES =========================== */ +/* ======================================================================== */ + +/* Exception Vectors handled by emulation */ +#define EXCEPTION_RESET 0 +#define EXCEPTION_BUS_ERROR 2 /* This one is not emulated! */ +#define EXCEPTION_ADDRESS_ERROR 3 /* This one is partially emulated (doesn't stack a proper frame yet) */ +#define EXCEPTION_ILLEGAL_INSTRUCTION 4 +#define EXCEPTION_ZERO_DIVIDE 5 +#define EXCEPTION_CHK 6 +#define EXCEPTION_TRAPV 7 +#define EXCEPTION_PRIVILEGE_VIOLATION 8 +#define EXCEPTION_TRACE 9 +#define EXCEPTION_1010 10 +#define EXCEPTION_1111 11 +#define EXCEPTION_FORMAT_ERROR 14 +#define EXCEPTION_UNINITIALIZED_INTERRUPT 15 +#define EXCEPTION_SPURIOUS_INTERRUPT 24 +#define EXCEPTION_INTERRUPT_AUTOVECTOR 24 +#define EXCEPTION_TRAP_BASE 32 + +/* Function codes set by CPU during data/address bus activity */ +#define FUNCTION_CODE_USER_DATA 1 +#define FUNCTION_CODE_USER_PROGRAM 2 +#define FUNCTION_CODE_SUPERVISOR_DATA 5 +#define FUNCTION_CODE_SUPERVISOR_PROGRAM 6 +#define FUNCTION_CODE_CPU_SPACE 7 + +/* Different ways to stop the CPU */ +#define STOP_LEVEL_STOP 1 +#define STOP_LEVEL_HALT 2 + +/* Used for 68000 address error processing */ +#if M68K_EMULATE_ADDRESS_ERROR +#define INSTRUCTION_YES 0 +#define INSTRUCTION_NO 0x08 +#define MODE_READ 0x10 +#define MODE_WRITE 0 + +#define RUN_MODE_NORMAL 0 +#define RUN_MODE_BERR_AERR_RESET 1 +#endif + +#ifndef NULL +#define NULL ((void*)0) +#endif + +/* ======================================================================== */ +/* ================================ MACROS ================================ */ +/* ======================================================================== */ + + +/* ---------------------------- General Macros ---------------------------- */ + +/* Bit Isolation Macros */ +#define BIT_0(A) ((A) & 0x00000001) +#define BIT_1(A) ((A) & 0x00000002) +#define BIT_2(A) ((A) & 0x00000004) +#define BIT_3(A) ((A) & 0x00000008) +#define BIT_4(A) ((A) & 0x00000010) +#define BIT_5(A) ((A) & 0x00000020) +#define BIT_6(A) ((A) & 0x00000040) +#define BIT_7(A) ((A) & 0x00000080) +#define BIT_8(A) ((A) & 0x00000100) +#define BIT_9(A) ((A) & 0x00000200) +#define BIT_A(A) ((A) & 0x00000400) +#define BIT_B(A) ((A) & 0x00000800) +#define BIT_C(A) ((A) & 0x00001000) +#define BIT_D(A) ((A) & 0x00002000) +#define BIT_E(A) ((A) & 0x00004000) +#define BIT_F(A) ((A) & 0x00008000) +#define BIT_10(A) ((A) & 0x00010000) +#define BIT_11(A) ((A) & 0x00020000) +#define BIT_12(A) ((A) & 0x00040000) +#define BIT_13(A) ((A) & 0x00080000) +#define BIT_14(A) ((A) & 0x00100000) +#define BIT_15(A) ((A) & 0x00200000) +#define BIT_16(A) ((A) & 0x00400000) +#define BIT_17(A) ((A) & 0x00800000) +#define BIT_18(A) ((A) & 0x01000000) +#define BIT_19(A) ((A) & 0x02000000) +#define BIT_1A(A) ((A) & 0x04000000) +#define BIT_1B(A) ((A) & 0x08000000) +#define BIT_1C(A) ((A) & 0x10000000) +#define BIT_1D(A) ((A) & 0x20000000) +#define BIT_1E(A) ((A) & 0x40000000) +#define BIT_1F(A) ((A) & 0x80000000) + +/* Get the most significant bit for specific sizes */ +#define GET_MSB_8(A) ((A) & 0x80) +#define GET_MSB_9(A) ((A) & 0x100) +#define GET_MSB_16(A) ((A) & 0x8000) +#define GET_MSB_17(A) ((A) & 0x10000) +#define GET_MSB_32(A) ((A) & 0x80000000) +#if M68K_USE_64_BIT +#define GET_MSB_33(A) ((A) & 0x100000000) +#endif /* M68K_USE_64_BIT */ + +/* Isolate nibbles */ +#define LOW_NIBBLE(A) ((A) & 0x0f) +#define HIGH_NIBBLE(A) ((A) & 0xf0) + +/* These are used to isolate 8, 16, and 32 bit sizes */ +#define MASK_OUT_ABOVE_2(A) ((A) & 3) +#define MASK_OUT_ABOVE_8(A) ((A) & 0xff) +#define MASK_OUT_ABOVE_16(A) ((A) & 0xffff) +#define MASK_OUT_BELOW_2(A) ((A) & ~3) +#define MASK_OUT_BELOW_8(A) ((A) & ~0xff) +#define MASK_OUT_BELOW_16(A) ((A) & ~0xffff) + +/* No need to mask if we are 32 bit */ +#if M68K_INT_GT_32_BIT || M68K_USE_64_BIT + #define MASK_OUT_ABOVE_32(A) ((A) & 0xffffffff) + #define MASK_OUT_BELOW_32(A) ((A) & ~0xffffffff) +#else + #define MASK_OUT_ABOVE_32(A) (A) + #define MASK_OUT_BELOW_32(A) 0 +#endif /* M68K_INT_GT_32_BIT || M68K_USE_64_BIT */ + +/* Simulate address lines of 68k family */ +#define ADDRESS_68K(A) ((A)&CPU_ADDRESS_MASK) + + +/* Shift & Rotate Macros. */ +#define LSL(A, C) ((A) << (C)) +#define LSR(A, C) ((A) >> (C)) + +/* Some > 32-bit optimizations */ +#if M68K_INT_GT_32_BIT + /* Shift left and right */ + #define LSR_32(A, C) ((A) >> (C)) + #define LSL_32(A, C) ((A) << (C)) +#else + /* We have to do this because the morons at ANSI decided that shifts + * by >= data size are undefined. + */ + #define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0) + #define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0) +#endif /* M68K_INT_GT_32_BIT */ + +#if M68K_USE_64_BIT + #define LSL_32_64(A, C) ((A) << (C)) + #define LSR_32_64(A, C) ((A) >> (C)) + #define ROL_33_64(A, C) (LSL_32_64(A, C) | LSR_32_64(A, 33-(C))) + #define ROR_33_64(A, C) (LSR_32_64(A, C) | LSL_32_64(A, 33-(C))) +#endif /* M68K_USE_64_BIT */ + +#define ROL_8(A, C) MASK_OUT_ABOVE_8(LSL(A, C) | LSR(A, 8-(C))) +#define ROL_9(A, C) (LSL(A, C) | LSR(A, 9-(C))) +#define ROL_16(A, C) MASK_OUT_ABOVE_16(LSL(A, C) | LSR(A, 16-(C))) +#define ROL_17(A, C) (LSL(A, C) | LSR(A, 17-(C))) +#define ROL_32(A, C) MASK_OUT_ABOVE_32(LSL_32(A, C) | LSR_32(A, 32-(C))) +#define ROL_33(A, C) (LSL_32(A, C) | LSR_32(A, 33-(C))) + +#define ROR_8(A, C) MASK_OUT_ABOVE_8(LSR(A, C) | LSL(A, 8-(C))) +#define ROR_9(A, C) (LSR(A, C) | LSL(A, 9-(C))) +#define ROR_16(A, C) MASK_OUT_ABOVE_16(LSR(A, C) | LSL(A, 16-(C))) +#define ROR_17(A, C) (LSR(A, C) | LSL(A, 17-(C))) +#define ROR_32(A, C) MASK_OUT_ABOVE_32(LSR_32(A, C) | LSL_32(A, 32-(C))) +#define ROR_33(A, C) (LSR_32(A, C) | LSL_32(A, 33-(C))) + + + +/* ------------------------------ CPU Access ------------------------------ */ + +/* Access the CPU registers */ +#define REG_DA m68ki_cpu.dar /* easy access to data and address regs */ +#define REG_D m68ki_cpu.dar +#define REG_A (m68ki_cpu.dar+8) +#define REG_PC m68ki_cpu.pc +#define REG_SP_BASE m68ki_cpu.sp +#define REG_USP m68ki_cpu.sp[0] +#define REG_ISP m68ki_cpu.sp[4] +#define REG_SP m68ki_cpu.dar[15] +#define REG_IR m68ki_cpu.ir + +#define FLAG_T1 m68ki_cpu.t1_flag +#define FLAG_S m68ki_cpu.s_flag +#define FLAG_X m68ki_cpu.x_flag +#define FLAG_N m68ki_cpu.n_flag +#define FLAG_Z m68ki_cpu.not_z_flag +#define FLAG_V m68ki_cpu.v_flag +#define FLAG_C m68ki_cpu.c_flag +#define FLAG_INT_MASK m68ki_cpu.int_mask + +#define CPU_INT_LEVEL m68ki_cpu.int_level /* ASG: changed from CPU_INTS_PENDING */ +#define CPU_STOPPED m68ki_cpu.stopped +#if M68K_EMULATE_PREFETCH +#define CPU_PREF_ADDR m68ki_cpu.pref_addr +#define CPU_PREF_DATA m68ki_cpu.pref_data +#endif +#define CPU_ADDRESS_MASK 0x00ffffff +#if M68K_EMULATE_ADDRESS_ERROR +#define CPU_INSTR_MODE m68ki_cpu.instr_mode +#define CPU_RUN_MODE m68ki_cpu.run_mode +#endif + +#define CYC_INSTRUCTION m68ki_cycles +#define CYC_EXCEPTION m68ki_exception_cycle_table +#define CYC_BCC_NOTAKE_B ( -2 * MUL) +#define CYC_BCC_NOTAKE_W ( 2 * MUL) +#define CYC_DBCC_F_NOEXP ( -2 * MUL) +#define CYC_DBCC_F_EXP ( 2 * MUL) +#define CYC_SCC_R_TRUE ( 2 * MUL) +#define CYC_MOVEM_W ( 4 * MUL) +#define CYC_MOVEM_L ( 8 * MUL) +#define CYC_SHIFT ( 2 * MUL) +#define CYC_RESET (132 * MUL) + +#if M68K_EMULATE_INT_ACK == OPT_ON +#define CALLBACK_INT_ACK m68ki_cpu.int_ack_callback +#endif +#if M68K_EMULATE_RESET == OPT_ON +#define CALLBACK_RESET_INSTR m68ki_cpu.reset_instr_callback +#endif +#if M68K_TAS_HAS_CALLBACK == OPT_ON +#define CALLBACK_TAS_INSTR m68ki_cpu.tas_instr_callback +#endif +#if M68K_EMULATE_FC == OPT_ON +#define CALLBACK_SET_FC m68ki_cpu.set_fc_callback +#endif + + +/* ----------------------------- Configuration ---------------------------- */ + +/* These defines are dependant on the configuration defines in m68kconf.h */ + +/* Enable or disable callback functions */ +#if M68K_EMULATE_INT_ACK + #if M68K_EMULATE_INT_ACK == OPT_SPECIFY_HANDLER + #define m68ki_int_ack(A) M68K_INT_ACK_CALLBACK(A); + #else + #define m68ki_int_ack(A) CALLBACK_INT_ACK(A); + #endif +#else + /* Default action is to used autovector mode, which is most common */ + #define m68ki_int_ack(A) M68K_INT_ACK_AUTOVECTOR +#endif /* M68K_EMULATE_INT_ACK */ + +#if M68K_EMULATE_RESET + #if M68K_EMULATE_RESET == OPT_SPECIFY_HANDLER + #define m68ki_output_reset() M68K_RESET_CALLBACK(); + #else + #define m68ki_output_reset() CALLBACK_RESET_INSTR(); + #endif +#else + #define m68ki_output_reset() +#endif /* M68K_EMULATE_RESET */ + +#if M68K_TAS_HAS_CALLBACK + #if M68K_TAS_HAS_CALLBACK == OPT_SPECIFY_HANDLER + #define m68ki_tas_callback() M68K_TAS_CALLBACK() + #else + #define m68ki_tas_callback() CALLBACK_TAS_INSTR() + #endif +#else + #define m68ki_tas_callback() 0 +#endif /* M68K_TAS_HAS_CALLBACK */ + + +/* Enable or disable function code emulation */ +#if M68K_EMULATE_FC + #if M68K_EMULATE_FC == OPT_SPECIFY_HANDLER + #define m68ki_set_fc(A) M68K_SET_FC_CALLBACK(A); + #else + #define m68ki_set_fc(A) CALLBACK_SET_FC(A); + #endif + #define m68ki_use_data_space() m68ki_cpu.address_space = FUNCTION_CODE_USER_DATA; + #define m68ki_use_program_space() m68ki_cpu.address_space = FUNCTION_CODE_USER_PROGRAM; + #define m68ki_get_address_space() m68ki_cpu.address_space +#else + #define m68ki_set_fc(A) + #define m68ki_use_data_space() + #define m68ki_use_program_space() + #define m68ki_get_address_space() FUNCTION_CODE_USER_DATA +#endif /* M68K_EMULATE_FC */ + + +/* Enable or disable trace emulation */ +#if M68K_EMULATE_TRACE + /* Initiates trace checking before each instruction (t1) */ + #define m68ki_trace_t1() m68ki_cpu.tracing = FLAG_T1; + /* Clear all tracing */ + #define m68ki_clear_trace() m68ki_cpu.tracing = 0; + /* Cause a trace exception if we are tracing */ + #define m68ki_exception_if_trace() if(m68ki_cpu.tracing) m68ki_exception_trace(); +#else + #define m68ki_trace_t1() + #define m68ki_clear_trace() + #define m68ki_exception_if_trace() +#endif /* M68K_EMULATE_TRACE */ + + +/* Enable or disable Address error emulation */ +#if M68K_EMULATE_ADDRESS_ERROR + #define m68ki_set_address_error_trap() \ + if(setjmp(m68ki_cpu.aerr_trap) != 0) \ + { \ + m68ki_exception_address_error(); \ + } + + #define m68ki_check_address_error(ADDR, WRITE_MODE, FC) \ + if((ADDR)&1) \ + { \ + if (m68ki_cpu.aerr_enabled) \ + { \ + m68ki_cpu.aerr_address = ADDR; \ + m68ki_cpu.aerr_write_mode = WRITE_MODE; \ + m68ki_cpu.aerr_fc = FC; \ + longjmp(m68ki_cpu.aerr_trap, 1); \ + } \ + } +#else + #define m68ki_set_address_error_trap() + #define m68ki_check_address_error(ADDR, WRITE_MODE, FC) +#endif /* M68K_ADDRESS_ERROR */ + + +/* -------------------------- EA / Operand Access ------------------------- */ + +/* + * The general instruction format follows this pattern: + * .... XXX. .... .YYY + * where XXX is register X and YYY is register Y + */ + +/* Data Register Isolation */ +#define DX (REG_D[(REG_IR >> 9) & 7]) +#define DY (REG_D[REG_IR & 7]) + +/* Address Register Isolation */ +#define AX (REG_A[(REG_IR >> 9) & 7]) +#define AY (REG_A[REG_IR & 7]) + +/* Effective Address Calculations */ +#define EA_AY_AI_8() AY /* address register indirect */ +#define EA_AY_AI_16() EA_AY_AI_8() +#define EA_AY_AI_32() EA_AY_AI_8() +#define EA_AY_PI_8() (AY++) /* postincrement (size = byte) */ +#define EA_AY_PI_16() ((AY+=2)-2) /* postincrement (size = word) */ +#define EA_AY_PI_32() ((AY+=4)-4) /* postincrement (size = long) */ +#define EA_AY_PD_8() (--AY) /* predecrement (size = byte) */ +#define EA_AY_PD_16() (AY-=2) /* predecrement (size = word) */ +#define EA_AY_PD_32() (AY-=4) /* predecrement (size = long) */ +#define EA_AY_DI_8() (AY+MAKE_INT_16(m68ki_read_imm_16())) /* displacement */ +#define EA_AY_DI_16() EA_AY_DI_8() +#define EA_AY_DI_32() EA_AY_DI_8() +#define EA_AY_IX_8() m68ki_get_ea_ix(AY) /* indirect + index */ +#define EA_AY_IX_16() EA_AY_IX_8() +#define EA_AY_IX_32() EA_AY_IX_8() + +#define EA_AX_AI_8() AX +#define EA_AX_AI_16() EA_AX_AI_8() +#define EA_AX_AI_32() EA_AX_AI_8() +#define EA_AX_PI_8() (AX++) +#define EA_AX_PI_16() ((AX+=2)-2) +#define EA_AX_PI_32() ((AX+=4)-4) +#define EA_AX_PD_8() (--AX) +#define EA_AX_PD_16() (AX-=2) +#define EA_AX_PD_32() (AX-=4) +#define EA_AX_DI_8() (AX+MAKE_INT_16(m68ki_read_imm_16())) +#define EA_AX_DI_16() EA_AX_DI_8() +#define EA_AX_DI_32() EA_AX_DI_8() +#define EA_AX_IX_8() m68ki_get_ea_ix(AX) +#define EA_AX_IX_16() EA_AX_IX_8() +#define EA_AX_IX_32() EA_AX_IX_8() + +#define EA_A7_PI_8() ((REG_A[7]+=2)-2) +#define EA_A7_PD_8() (REG_A[7]-=2) + +#define EA_AW_8() MAKE_INT_16(m68ki_read_imm_16()) /* absolute word */ +#define EA_AW_16() EA_AW_8() +#define EA_AW_32() EA_AW_8() +#define EA_AL_8() m68ki_read_imm_32() /* absolute long */ +#define EA_AL_16() EA_AL_8() +#define EA_AL_32() EA_AL_8() +#define EA_PCDI_8() m68ki_get_ea_pcdi() /* pc indirect + displacement */ +#define EA_PCDI_16() EA_PCDI_8() +#define EA_PCDI_32() EA_PCDI_8() +#define EA_PCIX_8() m68ki_get_ea_pcix() /* pc indirect + index */ +#define EA_PCIX_16() EA_PCIX_8() +#define EA_PCIX_32() EA_PCIX_8() + + +#define OPER_I_8() m68ki_read_imm_8() +#define OPER_I_16() m68ki_read_imm_16() +#define OPER_I_32() m68ki_read_imm_32() + + +/* --------------------------- Status Register ---------------------------- */ + +/* Flag Calculation Macros */ +#define CFLAG_8(A) (A) +#define CFLAG_16(A) ((A)>>8) + +#if M68K_INT_GT_32_BIT + #define CFLAG_ADD_32(S, D, R) ((R)>>24) + #define CFLAG_SUB_32(S, D, R) ((R)>>24) +#else + #define CFLAG_ADD_32(S, D, R) (((S & D) | (~R & (S | D)))>>23) + #define CFLAG_SUB_32(S, D, R) (((S & R) | (~D & (S | R)))>>23) +#endif /* M68K_INT_GT_32_BIT */ + +#define VFLAG_ADD_8(S, D, R) ((S^R) & (D^R)) +#define VFLAG_ADD_16(S, D, R) (((S^R) & (D^R))>>8) +#define VFLAG_ADD_32(S, D, R) (((S^R) & (D^R))>>24) + +#define VFLAG_SUB_8(S, D, R) ((S^D) & (R^D)) +#define VFLAG_SUB_16(S, D, R) (((S^D) & (R^D))>>8) +#define VFLAG_SUB_32(S, D, R) (((S^D) & (R^D))>>24) + +#define NFLAG_8(A) (A) +#define NFLAG_16(A) ((A)>>8) +#define NFLAG_32(A) ((A)>>24) +#define NFLAG_64(A) ((A)>>56) + +#define ZFLAG_8(A) MASK_OUT_ABOVE_8(A) +#define ZFLAG_16(A) MASK_OUT_ABOVE_16(A) +#define ZFLAG_32(A) MASK_OUT_ABOVE_32(A) + + +/* Flag values */ +#define NFLAG_SET 0x80 +#define NFLAG_CLEAR 0 +#define CFLAG_SET 0x100 +#define CFLAG_CLEAR 0 +#define XFLAG_SET 0x100 +#define XFLAG_CLEAR 0 +#define VFLAG_SET 0x80 +#define VFLAG_CLEAR 0 +#define ZFLAG_SET 0 +#define ZFLAG_CLEAR 0xffffffff +#define SFLAG_SET 4 +#define SFLAG_CLEAR 0 + +/* Turn flag values into 1 or 0 */ +#define XFLAG_AS_1() ((FLAG_X>>8)&1) +#define NFLAG_AS_1() ((FLAG_N>>7)&1) +#define VFLAG_AS_1() ((FLAG_V>>7)&1) +#define ZFLAG_AS_1() (!FLAG_Z) +#define CFLAG_AS_1() ((FLAG_C>>8)&1) + + +/* Conditions */ +#define COND_CS() (FLAG_C&0x100) +#define COND_CC() (!COND_CS()) +#define COND_VS() (FLAG_V&0x80) +#define COND_VC() (!COND_VS()) +#define COND_NE() FLAG_Z +#define COND_EQ() (!COND_NE()) +#define COND_MI() (FLAG_N&0x80) +#define COND_PL() (!COND_MI()) +#define COND_LT() ((FLAG_N^FLAG_V)&0x80) +#define COND_GE() (!COND_LT()) +#define COND_HI() (COND_CC() && COND_NE()) +#define COND_LS() (COND_CS() || COND_EQ()) +#define COND_GT() (COND_GE() && COND_NE()) +#define COND_LE() (COND_LT() || COND_EQ()) + +/* Reversed conditions */ +#define COND_NOT_CS() COND_CC() +#define COND_NOT_CC() COND_CS() +#define COND_NOT_VS() COND_VC() +#define COND_NOT_VC() COND_VS() +#define COND_NOT_NE() COND_EQ() +#define COND_NOT_EQ() COND_NE() +#define COND_NOT_MI() COND_PL() +#define COND_NOT_PL() COND_MI() +#define COND_NOT_LT() COND_GE() +#define COND_NOT_GE() COND_LT() +#define COND_NOT_HI() COND_LS() +#define COND_NOT_LS() COND_HI() +#define COND_NOT_GT() COND_LE() +#define COND_NOT_LE() COND_GT() + +/* Not real conditions, but here for convenience */ +#define COND_XS() (FLAG_X&0x100) +#define COND_XC() (!COND_XS) + + +/* Get the condition code register */ +#define m68ki_get_ccr() ((COND_XS() >> 4) | \ + (COND_MI() >> 4) | \ + (COND_EQ() << 2) | \ + (COND_VS() >> 6) | \ + (COND_CS() >> 8)) + +/* Get the status register */ +#define m68ki_get_sr() ( FLAG_T1 | \ + (FLAG_S << 11) | \ + FLAG_INT_MASK | \ + m68ki_get_ccr()) + + + +/* ---------------------------- Cycle Counting ---------------------------- */ + +#define USE_CYCLES(A) m68ki_cpu.cycles += (A) +#define SET_CYCLES(A) m68ki_cpu.cycles = (A) + + +/* ----------------------------- Read / Write ----------------------------- */ + +/* Read data immediately following the PC */ +#define m68k_read_immediate_16(address) *(uint16 *)(m68ki_cpu.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)) +#define m68k_read_immediate_32(address) (m68k_read_immediate_16(address) << 16) | (m68k_read_immediate_16(address+2)) + +/* Read data relative to the PC */ +#define m68k_read_pcrelative_8(address) READ_BYTE(m68ki_cpu.memory_map[((address)>>16)&0xff].base, (address) & 0xffff) +#define m68k_read_pcrelative_16(address) m68k_read_immediate_16(address) +#define m68k_read_pcrelative_32(address) m68k_read_immediate_32(address) + +/* Read from the current address space */ +#define m68ki_read_8(A) m68ki_read_8_fc (A, FLAG_S | m68ki_get_address_space()) +#define m68ki_read_16(A) m68ki_read_16_fc(A, FLAG_S | m68ki_get_address_space()) +#define m68ki_read_32(A) m68ki_read_32_fc(A, FLAG_S | m68ki_get_address_space()) + +/* Write to the current data space */ +#define m68ki_write_8(A, V) m68ki_write_8_fc (A, FLAG_S | FUNCTION_CODE_USER_DATA, V) +#define m68ki_write_16(A, V) m68ki_write_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V) +#define m68ki_write_32(A, V) m68ki_write_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA, V) + +/* map read immediate 8 to read immediate 16 */ +#define m68ki_read_imm_8() MASK_OUT_ABOVE_8(m68ki_read_imm_16()) + +/* Map PC-relative reads */ +#define m68ki_read_pcrel_8(A) m68k_read_pcrelative_8(A) +#define m68ki_read_pcrel_16(A) m68k_read_pcrelative_16(A) +#define m68ki_read_pcrel_32(A) m68k_read_pcrelative_32(A) + +/* Read from the program space */ +#define m68ki_read_program_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) +#define m68ki_read_program_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) +#define m68ki_read_program_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_PROGRAM) + +/* Read from the data space */ +#define m68ki_read_data_8(A) m68ki_read_8_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) +#define m68ki_read_data_16(A) m68ki_read_16_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) +#define m68ki_read_data_32(A) m68ki_read_32_fc(A, FLAG_S | FUNCTION_CODE_USER_DATA) + + + +/* ======================================================================== */ +/* =============================== PROTOTYPES ============================= */ +/* ======================================================================== */ + +/* Used by shift & rotate instructions */ +static const uint8 m68ki_shift_8_table[65] = +{ + 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff +}; + +static const uint16 m68ki_shift_16_table[65] = +{ + 0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, + 0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff +}; + +static const uint m68ki_shift_32_table[65] = +{ + 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000, + 0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, + 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000, + 0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, + 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8, + 0xfffffffc, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff +}; + + +/* Number of clock cycles to use for exception processing. + * I used 4 for any vectors that are undocumented for processing times. + */ +static const uint16 m68ki_exception_cycle_table[256] = +{ + 40*MUL, /* 0: Reset - Initial Stack Pointer */ + 4*MUL, /* 1: Reset - Initial Program Counter */ + 50*MUL, /* 2: Bus Error (unemulated) */ + 50*MUL, /* 3: Address Error (unemulated) */ + 34*MUL, /* 4: Illegal Instruction */ + 38*MUL, /* 5: Divide by Zero -- ASG: changed from 42 */ + 40*MUL, /* 6: CHK -- ASG: chanaged from 44 */ + 34*MUL, /* 7: TRAPV */ + 34*MUL, /* 8: Privilege Violation */ + 34*MUL, /* 9: Trace */ + 4*MUL, /* 10: 1010 */ + 4*MUL, /* 11: 1111 */ + 4*MUL, /* 12: RESERVED */ + 4*MUL, /* 13: Coprocessor Protocol Violation (unemulated) */ + 4*MUL, /* 14: Format Error */ + 44*MUL, /* 15: Uninitialized Interrupt */ + 4*MUL, /* 16: RESERVED */ + 4*MUL, /* 17: RESERVED */ + 4*MUL, /* 18: RESERVED */ + 4*MUL, /* 19: RESERVED */ + 4*MUL, /* 20: RESERVED */ + 4*MUL, /* 21: RESERVED */ + 4*MUL, /* 22: RESERVED */ + 4*MUL, /* 23: RESERVED */ + 44*MUL, /* 24: Spurious Interrupt */ + 44*MUL, /* 25: Level 1 Interrupt Autovector */ + 44*MUL, /* 26: Level 2 Interrupt Autovector */ + 44*MUL, /* 27: Level 3 Interrupt Autovector */ + 44*MUL, /* 28: Level 4 Interrupt Autovector */ + 44*MUL, /* 29: Level 5 Interrupt Autovector */ + 44*MUL, /* 30: Level 6 Interrupt Autovector */ + 44*MUL, /* 31: Level 7 Interrupt Autovector */ + 34*MUL, /* 32: TRAP #0 -- ASG: chanaged from 38 */ + 34*MUL, /* 33: TRAP #1 */ + 34*MUL, /* 34: TRAP #2 */ + 34*MUL, /* 35: TRAP #3 */ + 34*MUL, /* 36: TRAP #4 */ + 34*MUL, /* 37: TRAP #5 */ + 34*MUL, /* 38: TRAP #6 */ + 34*MUL, /* 39: TRAP #7 */ + 34*MUL, /* 40: TRAP #8 */ + 34*MUL, /* 41: TRAP #9 */ + 34*MUL, /* 42: TRAP #10 */ + 34*MUL, /* 43: TRAP #11 */ + 34*MUL, /* 44: TRAP #12 */ + 34*MUL, /* 45: TRAP #13 */ + 34*MUL, /* 46: TRAP #14 */ + 34*MUL, /* 47: TRAP #15 */ + 4*MUL, /* 48: FP Branch or Set on Unknown Condition (unemulated) */ + 4*MUL, /* 49: FP Inexact Result (unemulated) */ + 4*MUL, /* 50: FP Divide by Zero (unemulated) */ + 4*MUL, /* 51: FP Underflow (unemulated) */ + 4*MUL, /* 52: FP Operand Error (unemulated) */ + 4*MUL, /* 53: FP Overflow (unemulated) */ + 4*MUL, /* 54: FP Signaling NAN (unemulated) */ + 4*MUL, /* 55: FP Unimplemented Data Type (unemulated) */ + 4*MUL, /* 56: MMU Configuration Error (unemulated) */ + 4*MUL, /* 57: MMU Illegal Operation Error (unemulated) */ + 4*MUL, /* 58: MMU Access Level Violation Error (unemulated) */ + 4*MUL, /* 59: RESERVED */ + 4*MUL, /* 60: RESERVED */ + 4*MUL, /* 61: RESERVED */ + 4*MUL, /* 62: RESERVED */ + 4*MUL, /* 63: RESERVED */ + /* 64-255: User Defined */ + 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL, + 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL, + 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL, + 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL, + 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL, + 4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL,4*MUL +}; + +/* Read data immediately after the program counter */ +INLINE uint m68ki_read_imm_16(void); +INLINE uint m68ki_read_imm_32(void); + +/* Read data with specific function code */ +INLINE uint m68ki_read_8_fc (uint address, uint fc); +INLINE uint m68ki_read_16_fc (uint address, uint fc); +INLINE uint m68ki_read_32_fc (uint address, uint fc); + +/* Write data with specific function code */ +INLINE void m68ki_write_8_fc (uint address, uint fc, uint value); +INLINE void m68ki_write_16_fc(uint address, uint fc, uint value); +INLINE void m68ki_write_32_fc(uint address, uint fc, uint value); + +/* Indexed and PC-relative ea fetching */ +INLINE uint m68ki_get_ea_pcdi(void); +INLINE uint m68ki_get_ea_pcix(void); +INLINE uint m68ki_get_ea_ix(uint An); + +/* Operand fetching */ +INLINE uint OPER_AY_AI_8(void); +INLINE uint OPER_AY_AI_16(void); +INLINE uint OPER_AY_AI_32(void); +INLINE uint OPER_AY_PI_8(void); +INLINE uint OPER_AY_PI_16(void); +INLINE uint OPER_AY_PI_32(void); +INLINE uint OPER_AY_PD_8(void); +INLINE uint OPER_AY_PD_16(void); +INLINE uint OPER_AY_PD_32(void); +INLINE uint OPER_AY_DI_8(void); +INLINE uint OPER_AY_DI_16(void); +INLINE uint OPER_AY_DI_32(void); +INLINE uint OPER_AY_IX_8(void); +INLINE uint OPER_AY_IX_16(void); +INLINE uint OPER_AY_IX_32(void); + +INLINE uint OPER_AX_AI_8(void); +INLINE uint OPER_AX_AI_16(void); +INLINE uint OPER_AX_AI_32(void); +INLINE uint OPER_AX_PI_8(void); +INLINE uint OPER_AX_PI_16(void); +INLINE uint OPER_AX_PI_32(void); +INLINE uint OPER_AX_PD_8(void); +INLINE uint OPER_AX_PD_16(void); +INLINE uint OPER_AX_PD_32(void); +INLINE uint OPER_AX_DI_8(void); +INLINE uint OPER_AX_DI_16(void); +INLINE uint OPER_AX_DI_32(void); +INLINE uint OPER_AX_IX_8(void); +INLINE uint OPER_AX_IX_16(void); +INLINE uint OPER_AX_IX_32(void); + +INLINE uint OPER_A7_PI_8(void); +INLINE uint OPER_A7_PD_8(void); + +INLINE uint OPER_AW_8(void); +INLINE uint OPER_AW_16(void); +INLINE uint OPER_AW_32(void); +INLINE uint OPER_AL_8(void); +INLINE uint OPER_AL_16(void); +INLINE uint OPER_AL_32(void); +INLINE uint OPER_PCDI_8(void); +INLINE uint OPER_PCDI_16(void); +INLINE uint OPER_PCDI_32(void); +INLINE uint OPER_PCIX_8(void); +INLINE uint OPER_PCIX_16(void); +INLINE uint OPER_PCIX_32(void); + +/* Stack operations */ +INLINE void m68ki_push_16(uint value); +INLINE void m68ki_push_32(uint value); +INLINE uint m68ki_pull_16(void); +INLINE uint m68ki_pull_32(void); + +/* Program flow operations */ +INLINE void m68ki_jump(uint new_pc); +INLINE void m68ki_jump_vector(uint vector); +INLINE void m68ki_branch_8(uint offset); +INLINE void m68ki_branch_16(uint offset); +INLINE void m68ki_branch_32(uint offset); + +/* Status register operations. */ +INLINE void m68ki_set_s_flag(uint value); /* Only bit 2 of value should be set (i.e. 4 or 0) */ +INLINE void m68ki_set_ccr(uint value); /* set the condition code register */ +INLINE void m68ki_set_sr(uint value); /* set the status register */ + +/* Exception processing */ +INLINE uint m68ki_init_exception(void); /* Initial exception processing */ +INLINE void m68ki_stack_frame_3word(uint pc, uint sr); /* Stack various frame types */ +#if M68K_EMULATE_ADDRESS_ERROR +INLINE void m68ki_stack_frame_buserr(uint sr); +#endif +INLINE void m68ki_exception_trap(uint vector); +INLINE void m68ki_exception_trapN(uint vector); +#if M68K_EMULATE_TRACE +INLINE void m68ki_exception_trace(void); +#endif +static void m68ki_exception_privilege_violation(void); /* do not inline in order to reduce function size and allow inlining of read/write functions by the compile */ +INLINE void m68ki_exception_1010(void); +INLINE void m68ki_exception_1111(void); +INLINE void m68ki_exception_illegal(void); +#if M68K_EMULATE_ADDRESS_ERROR +INLINE void m68ki_exception_address_error(void); +#endif +INLINE void m68ki_exception_interrupt(uint int_level); +INLINE void m68ki_check_interrupts(void); /* ASG: check for interrupts */ + +/* ======================================================================== */ +/* =========================== UTILITY FUNCTIONS ========================== */ +/* ======================================================================== */ + + +/* ---------------------------- Read Immediate ---------------------------- */ + +/* Handles all immediate reads, does address error check, function code setting, + * and prefetching if they are enabled in m68kconf.h + */ +INLINE uint m68ki_read_imm_16(void) +{ + m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ +#if M68K_CHECK_PC_ADDRESS_ERROR + m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ +#endif +#if M68K_EMULATE_PREFETCH + if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) + { + CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); + CPU_PREF_DATA = m68k_read_immediate_32(CPU_PREF_ADDR); + } + REG_PC += 2; + return MASK_OUT_ABOVE_16(CPU_PREF_DATA >> ((2-((REG_PC-2)&2))<<3)); +#else + uint pc = REG_PC; + REG_PC += 2; + return m68k_read_immediate_16(pc); +#endif /* M68K_EMULATE_PREFETCH */ +} + +INLINE uint m68ki_read_imm_32(void) +{ +#if M68K_EMULATE_PREFETCH + uint temp_val; + + m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ +#if M68K_CHECK_PC_ADDRESS_ERROR + m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ +#endif + if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) + { + CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); + CPU_PREF_DATA = m68k_read_immediate_32(CPU_PREF_ADDR); + } + temp_val = CPU_PREF_DATA; + REG_PC += 2; + if(MASK_OUT_BELOW_2(REG_PC) != CPU_PREF_ADDR) + { + CPU_PREF_ADDR = MASK_OUT_BELOW_2(REG_PC); + CPU_PREF_DATA = m68k_read_immediate_32(CPU_PREF_ADDR); + temp_val = MASK_OUT_ABOVE_32((temp_val << 16) | (CPU_PREF_DATA >> 16)); + } + REG_PC += 2; + + return temp_val; +#else + m68ki_set_fc(FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ +#if M68K_CHECK_PC_ADDRESS_ERROR + m68ki_check_address_error(REG_PC, MODE_READ, FLAG_S | FUNCTION_CODE_USER_PROGRAM) /* auto-disable (see m68kcpu.h) */ +#endif + uint pc = REG_PC; + REG_PC += 4; + return m68k_read_immediate_32(pc); +#endif /* M68K_EMULATE_PREFETCH */ +} + + + +/* ------------------------- Top level read/write ------------------------- */ + +/* Handles all memory accesses (except for immediate reads if they are + * configured to use separate functions in m68kconf.h). + * All memory accesses must go through these top level functions. + * These functions will also check for address error and set the function + * code if they are enabled in m68kconf.h. + */ +INLINE uint m68ki_read_8_fc(uint address, uint fc) +{ + cpu_memory_map *temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];; + if (biz_readcb) + biz_readcb(address); + + if(biz_cdcallback) + CDLog68k(address,eCDLog_Flags_Data68k); + + m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ + + if (temp->read8) return (*temp->read8)(ADDRESS_68K(address)); + else return READ_BYTE(temp->base, (address) & 0xffff); +} + +INLINE uint m68ki_read_16_fc(uint address, uint fc) +{ + cpu_memory_map *temp; + if (biz_readcb) + biz_readcb(address); + + if(biz_cdcallback) + { + CDLog68k(address,eCDLog_Flags_Data68k); + CDLog68k(address+1,eCDLog_Flags_Data68k); + } + + m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(address, MODE_READ, fc) /* auto-disable (see m68kcpu.h) */ + + temp = &m68ki_cpu.memory_map[((address)>>16)&0xff]; + if (temp->read16) return (*temp->read16)(ADDRESS_68K(address)); + else return *(uint16 *)(temp->base + ((address) & 0xffff)); +} + +INLINE uint m68ki_read_32_fc(uint address, uint fc) +{ + cpu_memory_map *temp; + if (biz_readcb) + biz_readcb(address); + + if(biz_cdcallback) + { + CDLog68k(address,eCDLog_Flags_Data68k); + CDLog68k(address+1,eCDLog_Flags_Data68k); + CDLog68k(address+2,eCDLog_Flags_Data68k); + CDLog68k(address+3,eCDLog_Flags_Data68k); + } + + m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(address, MODE_READ, fc) /* auto-disable (see m68kcpu.h) */ + + temp = &m68ki_cpu.memory_map[((address)>>16)&0xff]; + if (temp->read16) return ((*temp->read16)(ADDRESS_68K(address)) << 16) | ((*temp->read16)(ADDRESS_68K(address + 2))); + else return m68k_read_immediate_32(address); +} + +INLINE void m68ki_write_8_fc(uint address, uint fc, uint value) +{ + cpu_memory_map *temp; + if (biz_writecb) + biz_writecb(address); + + m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ + + temp = &m68ki_cpu.memory_map[((address)>>16)&0xff]; + if (temp->write8) (*temp->write8)(ADDRESS_68K(address),value); + else WRITE_BYTE(temp->base, (address) & 0xffff, value); +} + +INLINE void m68ki_write_16_fc(uint address, uint fc, uint value) +{ + cpu_memory_map *temp; + if (biz_writecb) + biz_writecb(address); + + m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */ + + temp = &m68ki_cpu.memory_map[((address)>>16)&0xff]; + if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value); + else *(uint16 *)(temp->base + ((address) & 0xffff)) = value; +} + +INLINE void m68ki_write_32_fc(uint address, uint fc, uint value) +{ + cpu_memory_map *temp; + if (biz_writecb) + biz_writecb(address); + + m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ + m68ki_check_address_error(address, MODE_WRITE, fc) /* auto-disable (see m68kcpu.h) */ + + temp = &m68ki_cpu.memory_map[((address)>>16)&0xff]; + if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value>>16); + else *(uint16 *)(temp->base + ((address) & 0xffff)) = value >> 16; + + temp = &m68ki_cpu.memory_map[((address + 2)>>16)&0xff]; + if (temp->write16) (*temp->write16)(ADDRESS_68K(address+2),value&0xffff); + else *(uint16 *)(temp->base + ((address + 2) & 0xffff)) = value; +} + + +/* --------------------- Effective Address Calculation -------------------- */ + +/* The program counter relative addressing modes cause operands to be + * retrieved from program space, not data space. + */ +INLINE uint m68ki_get_ea_pcdi(void) +{ + uint old_pc = REG_PC; + m68ki_use_program_space() /* auto-disable */ + return old_pc + MAKE_INT_16(m68ki_read_imm_16()); +} + + +INLINE uint m68ki_get_ea_pcix(void) +{ + m68ki_use_program_space() /* auto-disable */ + return m68ki_get_ea_ix(REG_PC); +} + +/* Indexed addressing modes are encoded as follows: + * + * Base instruction format: + * F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0 + * x x x x x x x x x x | 1 1 0 | BASE REGISTER (An) + * + * Base instruction format for destination EA in move instructions: + * F E D C | B A 9 | 8 7 6 | 5 4 3 2 1 0 + * x x x x | BASE REG | 1 1 0 | X X X X X X (An) + * + * Brief extension format: + * F | E D C | B | A 9 | 8 | 7 6 5 4 3 2 1 0 + * D/A | REGISTER | W/L | SCALE | 0 | DISPLACEMENT + * + * Full extension format: + * F E D C B A 9 8 7 6 5 4 3 2 1 0 + * D/A | REGISTER | W/L | SCALE | 1 | BS | IS | BD SIZE | 0 | I/IS + * BASE DISPLACEMENT (0, 16, 32 bit) (bd) + * OUTER DISPLACEMENT (0, 16, 32 bit) (od) + * + * D/A: 0 = Dn, 1 = An (Xn) + * W/L: 0 = W (sign extend), 1 = L (.SIZE) + * SCALE: 00=1, 01=2, 10=4, 11=8 (*SCALE) + * BS: 0=add base reg, 1=suppress base reg (An suppressed) + * IS: 0=add index, 1=suppress index (Xn suppressed) + * BD SIZE: 00=reserved, 01=NULL, 10=Word, 11=Long (size of bd) + * + * IS I/IS Operation + * 0 000 No Memory Indirect + * 0 001 indir prex with null outer + * 0 010 indir prex with word outer + * 0 011 indir prex with long outer + * 0 100 reserved + * 0 101 indir postx with null outer + * 0 110 indir postx with word outer + * 0 111 indir postx with long outer + * 1 000 no memory indirect + * 1 001 mem indir with null outer + * 1 010 mem indir with word outer + * 1 011 mem indir with long outer + * 1 100-111 reserved + */ +INLINE uint m68ki_get_ea_ix(uint An) +{ + /* An = base register */ + uint extension = m68ki_read_imm_16(); + + uint Xn = 0; /* Index register */ + + /* Calculate index */ + Xn = REG_DA[extension>>12]; /* Xn */ + if(!BIT_B(extension)) /* W/L */ + Xn = MAKE_INT_16(Xn); + + /* Add base register and displacement and return */ + return An + Xn + MAKE_INT_8(extension); +} + + +/* Fetch operands */ +INLINE uint OPER_AY_AI_8(void) {uint ea = EA_AY_AI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AY_AI_16(void) {uint ea = EA_AY_AI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AY_AI_32(void) {uint ea = EA_AY_AI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AY_PI_8(void) {uint ea = EA_AY_PI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AY_PI_16(void) {uint ea = EA_AY_PI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AY_PI_32(void) {uint ea = EA_AY_PI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AY_PD_8(void) {uint ea = EA_AY_PD_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AY_PD_16(void) {uint ea = EA_AY_PD_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AY_PD_32(void) {uint ea = EA_AY_PD_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AY_DI_8(void) {uint ea = EA_AY_DI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AY_DI_16(void) {uint ea = EA_AY_DI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AY_DI_32(void) {uint ea = EA_AY_DI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AY_IX_8(void) {uint ea = EA_AY_IX_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AY_IX_16(void) {uint ea = EA_AY_IX_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AY_IX_32(void) {uint ea = EA_AY_IX_32(); return m68ki_read_32(ea);} + +INLINE uint OPER_AX_AI_8(void) {uint ea = EA_AX_AI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AX_AI_16(void) {uint ea = EA_AX_AI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AX_AI_32(void) {uint ea = EA_AX_AI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AX_PI_8(void) {uint ea = EA_AX_PI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AX_PI_16(void) {uint ea = EA_AX_PI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AX_PI_32(void) {uint ea = EA_AX_PI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AX_PD_8(void) {uint ea = EA_AX_PD_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AX_PD_16(void) {uint ea = EA_AX_PD_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AX_PD_32(void) {uint ea = EA_AX_PD_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AX_DI_8(void) {uint ea = EA_AX_DI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AX_DI_16(void) {uint ea = EA_AX_DI_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AX_DI_32(void) {uint ea = EA_AX_DI_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AX_IX_8(void) {uint ea = EA_AX_IX_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AX_IX_16(void) {uint ea = EA_AX_IX_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AX_IX_32(void) {uint ea = EA_AX_IX_32(); return m68ki_read_32(ea);} + +INLINE uint OPER_A7_PI_8(void) {uint ea = EA_A7_PI_8(); return m68ki_read_8(ea); } +INLINE uint OPER_A7_PD_8(void) {uint ea = EA_A7_PD_8(); return m68ki_read_8(ea); } + +INLINE uint OPER_AW_8(void) {uint ea = EA_AW_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AW_16(void) {uint ea = EA_AW_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AW_32(void) {uint ea = EA_AW_32(); return m68ki_read_32(ea);} +INLINE uint OPER_AL_8(void) {uint ea = EA_AL_8(); return m68ki_read_8(ea); } +INLINE uint OPER_AL_16(void) {uint ea = EA_AL_16(); return m68ki_read_16(ea);} +INLINE uint OPER_AL_32(void) {uint ea = EA_AL_32(); return m68ki_read_32(ea);} +INLINE uint OPER_PCDI_8(void) {uint ea = EA_PCDI_8(); return m68ki_read_pcrel_8(ea); } +INLINE uint OPER_PCDI_16(void) {uint ea = EA_PCDI_16(); return m68ki_read_pcrel_16(ea);} +INLINE uint OPER_PCDI_32(void) {uint ea = EA_PCDI_32(); return m68ki_read_pcrel_32(ea);} +INLINE uint OPER_PCIX_8(void) {uint ea = EA_PCIX_8(); return m68ki_read_pcrel_8(ea); } +INLINE uint OPER_PCIX_16(void) {uint ea = EA_PCIX_16(); return m68ki_read_pcrel_16(ea);} +INLINE uint OPER_PCIX_32(void) {uint ea = EA_PCIX_32(); return m68ki_read_pcrel_32(ea);} + + + +/* ---------------------------- Stack Functions --------------------------- */ + +/* Push/pull data from the stack */ +/* Optimized access assuming stack is always located in ROM/RAM [EkeEke] */ +INLINE void m68ki_push_16(uint value) +{ + REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2); + /*m68ki_write_16(REG_SP, value);*/ + if (m68ki_cpu.memory_map[(REG_SP >> 16) & 0xff].write16 != m68k_unused_16_w) + { + *(uint16 *)(m68ki_cpu.memory_map[(REG_SP >> 16) & 0xff].base + (REG_SP & 0xffff)) = value; + } +} + +INLINE void m68ki_push_32(uint value) +{ + REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4); + /*m68ki_write_32(REG_SP, value);*/ + if (m68ki_cpu.memory_map[(REG_SP >> 16) & 0xff].write16 != m68k_unused_16_w) + { + *(uint16 *)(m68ki_cpu.memory_map[(REG_SP >> 16) & 0xff].base + (REG_SP & 0xffff)) = value >> 16; + *(uint16 *)(m68ki_cpu.memory_map[((REG_SP + 2) >> 16) & 0xff].base + ((REG_SP + 2) & 0xffff)) = value & 0xffff; + } +} + +INLINE uint m68ki_pull_16(void) +{ + uint sp = REG_SP; + REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2); + return m68k_read_immediate_16(sp); + /*return m68ki_read_16(sp);*/ +} + +INLINE uint m68ki_pull_32(void) +{ + uint sp = REG_SP; + REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4); + return m68k_read_immediate_32(sp); + /*return m68ki_read_32(sp);*/ +} + + + +/* ----------------------------- Program Flow ----------------------------- */ + +/* Jump to a new program location or vector. + * These functions will also call the pc_changed callback if it was enabled + * in m68kconf.h. + */ +INLINE void m68ki_jump(uint new_pc) +{ + REG_PC = new_pc; +} + +INLINE void m68ki_jump_vector(uint vector) +{ + REG_PC = m68ki_read_data_32(vector<<2); +} + + +/* Branch to a new memory location. + * The 32-bit branch will call pc_changed if it was enabled in m68kconf.h. + * So far I've found no problems with not calling pc_changed for 8 or 16 + * bit branches. + */ +INLINE void m68ki_branch_8(uint offset) +{ + REG_PC += MAKE_INT_8(offset); +} + +INLINE void m68ki_branch_16(uint offset) +{ + REG_PC += MAKE_INT_16(offset); +} + +INLINE void m68ki_branch_32(uint offset) +{ + REG_PC += offset; +} + + + +/* ---------------------------- Status Register --------------------------- */ + +/* Set the S flag and change the active stack pointer. + * Note that value MUST be 4 or 0. + */ +INLINE void m68ki_set_s_flag(uint value) +{ + /* Backup the old stack pointer */ + REG_SP_BASE[FLAG_S] = REG_SP; + /* Set the S flag */ + FLAG_S = value; + /* Set the new stack pointer */ + REG_SP = REG_SP_BASE[FLAG_S]; +} + + +/* Set the condition code register */ +INLINE void m68ki_set_ccr(uint value) +{ + FLAG_X = BIT_4(value) << 4; + FLAG_N = BIT_3(value) << 4; + FLAG_Z = !BIT_2(value); + FLAG_V = BIT_1(value) << 6; + FLAG_C = BIT_0(value) << 8; +} + + +/* Set the status register and check for interrupts */ +INLINE void m68ki_set_sr(uint value) +{ + /* Set the status register */ + FLAG_T1 = BIT_F(value); + FLAG_INT_MASK = value & 0x0700; + m68ki_set_ccr(value); + m68ki_set_s_flag((value >> 11) & 4); + + /* Check current IRQ status */ + m68ki_check_interrupts(); +} + + +/* ------------------------- Exception Processing ------------------------- */ + +/* Initiate exception processing */ +INLINE uint m68ki_init_exception(void) +{ + /* Save the old status register */ + uint sr = m68ki_get_sr(); + + /* Turn off trace flag, clear pending traces */ + FLAG_T1 = 0; + m68ki_clear_trace() + + /* Enter supervisor mode */ + m68ki_set_s_flag(SFLAG_SET); + + return sr; +} + +/* 3 word stack frame (68000 only) */ +INLINE void m68ki_stack_frame_3word(uint pc, uint sr) +{ + m68ki_push_32(pc); + m68ki_push_16(sr); +} + +#if M68K_EMULATE_ADDRESS_ERROR +/* Bus error stack frame (68000 only). + */ +INLINE void m68ki_stack_frame_buserr(uint sr) +{ + m68ki_push_32(REG_PC); + m68ki_push_16(sr); + m68ki_push_16(REG_IR); + m68ki_push_32(m68ki_cpu.aerr_address); /* access address */ + /* 0 0 0 0 0 0 0 0 0 0 0 R/W I/N FC + * R/W 0 = write, 1 = read + * I/N 0 = instruction, 1 = not + * FC 3-bit function code + */ + m68ki_push_16(m68ki_cpu.aerr_write_mode | CPU_INSTR_MODE | m68ki_cpu.aerr_fc); +} +#endif + +/* Used for Group 2 exceptions. + */ +INLINE void m68ki_exception_trap(uint vector) +{ + uint sr = m68ki_init_exception(); + + m68ki_stack_frame_3word(REG_PC, sr); + + m68ki_jump_vector(vector); + + /* Use up some clock cycles */ + USE_CYCLES(CYC_EXCEPTION[vector]); +} + +/* Trap#n stacks a 0 frame but behaves like group2 otherwise */ +INLINE void m68ki_exception_trapN(uint vector) +{ + uint sr = m68ki_init_exception(); + m68ki_stack_frame_3word(REG_PC, sr); + m68ki_jump_vector(vector); + + /* Use up some clock cycles */ + USE_CYCLES(CYC_EXCEPTION[vector]); +} + +#if M68K_EMULATE_TRACE +/* Exception for trace mode */ +INLINE void m68ki_exception_trace(void) +{ + uint sr = m68ki_init_exception(); + + #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON + CPU_INSTR_MODE = INSTRUCTION_NO; + #endif /* M68K_EMULATE_ADDRESS_ERROR */ + + m68ki_stack_frame_3word(REG_PC, sr); + m68ki_jump_vector(EXCEPTION_TRACE); + + /* Trace nullifies a STOP instruction */ + CPU_STOPPED &= ~STOP_LEVEL_STOP; + + /* Use up some clock cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_TRACE]); +} +#endif + +/* Exception for privilege violation */ +static void m68ki_exception_privilege_violation(void) +{ + uint sr = m68ki_init_exception(); + + #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON + CPU_INSTR_MODE = INSTRUCTION_NO; + #endif /* M68K_EMULATE_ADDRESS_ERROR */ + + m68ki_stack_frame_3word(REG_PC-2, sr); + m68ki_jump_vector(EXCEPTION_PRIVILEGE_VIOLATION); + + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_PRIVILEGE_VIOLATION] - CYC_INSTRUCTION[REG_IR]); +} + +/* Exception for A-Line instructions */ +INLINE void m68ki_exception_1010(void) +{ + uint sr = m68ki_init_exception(); + m68ki_stack_frame_3word(REG_PC-2, sr); + m68ki_jump_vector(EXCEPTION_1010); + + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1010] - CYC_INSTRUCTION[REG_IR]); +} + +/* Exception for F-Line instructions */ +INLINE void m68ki_exception_1111(void) +{ + uint sr = m68ki_init_exception(); + m68ki_stack_frame_3word(REG_PC-2, sr); + m68ki_jump_vector(EXCEPTION_1111); + + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_1111] - CYC_INSTRUCTION[REG_IR]); +} + +/* Exception for illegal instructions */ +INLINE void m68ki_exception_illegal(void) +{ + uint sr = m68ki_init_exception(); + + #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON + CPU_INSTR_MODE = INSTRUCTION_NO; + #endif /* M68K_EMULATE_ADDRESS_ERROR */ + + m68ki_stack_frame_3word(REG_PC-2, sr); + m68ki_jump_vector(EXCEPTION_ILLEGAL_INSTRUCTION); + + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ILLEGAL_INSTRUCTION] - CYC_INSTRUCTION[REG_IR]); +} + + +#if M68K_EMULATE_ADDRESS_ERROR +/* Exception for address error */ +INLINE void m68ki_exception_address_error(void) +{ + uint sr = m68ki_init_exception(); + + /* If we were processing a bus error, address error, or reset, + * this is a catastrophic failure. + * Halt the CPU + */ + if(CPU_RUN_MODE == RUN_MODE_BERR_AERR_RESET) + { + CPU_STOPPED = STOP_LEVEL_HALT; + SET_CYCLES(m68ki_cpu.cycle_end - CYC_INSTRUCTION[REG_IR]); + return; + } + CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET; + + /* Note: This is implemented for 68000 only! */ + m68ki_stack_frame_buserr(sr); + + m68ki_jump_vector(EXCEPTION_ADDRESS_ERROR); + + /* Use up some clock cycles and undo the instruction's cycles */ + USE_CYCLES(CYC_EXCEPTION[EXCEPTION_ADDRESS_ERROR] - CYC_INSTRUCTION[REG_IR]); +} +#endif + +/* Service an interrupt request and start exception processing */ +INLINE void m68ki_exception_interrupt(uint int_level) +{ + uint vector, sr, new_pc; + + #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON + CPU_INSTR_MODE = INSTRUCTION_NO; + #endif /* M68K_EMULATE_ADDRESS_ERROR */ + + /* Turn off the stopped state */ + CPU_STOPPED &= STOP_LEVEL_HALT; + + /* If we are halted, don't do anything */ + if(CPU_STOPPED) + return; + + /* Always use the autovectors. */ + vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level; + + /* Start exception processing */ + sr = m68ki_init_exception(); + + /* Set the interrupt mask to the level of the one being serviced */ + FLAG_INT_MASK = int_level<<8; + + /* Acknowledge the interrupt */ + m68ki_int_ack(int_level); + + /* Get the new PC */ + new_pc = m68ki_read_data_32(vector<<2); + + /* If vector is uninitialized, call the uninitialized interrupt vector */ + if(new_pc == 0) + new_pc = m68ki_read_data_32((EXCEPTION_UNINITIALIZED_INTERRUPT<<2)); + + /* Generate a stack frame */ + m68ki_stack_frame_3word(REG_PC, sr); + + m68ki_jump(new_pc); + + /* Update cycle count now */ + USE_CYCLES(CYC_EXCEPTION[vector]); +} + +/* ASG: Check for interrupts */ +INLINE void m68ki_check_interrupts(void) +{ + if(CPU_INT_LEVEL > FLAG_INT_MASK) + m68ki_exception_interrupt(CPU_INT_LEVEL>>8); +} + + +/* ======================================================================== */ +/* ============================== END OF FILE ============================= */ +/* ======================================================================== */ + +#endif /* M68KCPU__HEADER */ diff --git a/waterbox/gpgx/core/mem68k.c b/waterbox/gpgx/core/mem68k.c index ed90a0ae2c..56353cc3e8 100644 --- a/waterbox/gpgx/core/mem68k.c +++ b/waterbox/gpgx/core/mem68k.c @@ -1,1281 +1,1293 @@ -/*************************************************************************************** - * Genesis Plus - * Main 68k bus handlers - * - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) - * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) - * - * Redistribution and use of this code or any derivative works are permitted - * provided that the following conditions are met: - * - * - Redistributions may not be sold, nor may they be used in a commercial - * product or activity. - * - * - Redistributions that are modified from the original source must include the - * complete source code, including the source code for all components used by a - * binary built from the modified sources. However, as a special exception, the - * source code distributed need not include anything that is normally distributed - * (in either source or binary form) with the major components (compiler, kernel, - * and so on) of the operating system on which the executable runs, unless that - * component itself accompanies the executable. - * - * - Redistributions must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************************/ - -#include "shared.h" - -/*--------------------------------------------------------------------------*/ -/* Unused areas (return open bus data, i.e prefetched instruction word) */ -/*--------------------------------------------------------------------------*/ - -unsigned int m68k_read_bus_8(unsigned int address) -{ -#ifdef LOGERROR - error("Unused read8 %08X (%08X)\n", address, m68k_get_reg(M68K_REG_PC)); -#endif - address = m68k.pc | (address & 1); - return READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff); -} - -unsigned int m68k_read_bus_16(unsigned int address) -{ -#ifdef LOGERROR - error("Unused read16 %08X (%08X)\n", address, m68k_get_reg(M68K_REG_PC)); -#endif - address = m68k.pc; - return *(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)); -} - - -void m68k_unused_8_w(unsigned int address, unsigned int data) -{ -#ifdef LOGERROR - error("Unused write8 %08X = %02X (%08X)\n", address, data, m68k_get_reg(M68K_REG_PC)); -#endif -} - -void m68k_unused_16_w(unsigned int address, unsigned int data) -{ -#ifdef LOGERROR - error("Unused write16 %08X = %04X (%08X)\n", address, data, m68k_get_reg(M68K_REG_PC)); -#endif -} - - -/*--------------------------------------------------------------------------*/ -/* Illegal areas (cause system to lock-up since !DTACK is not returned) */ -/*--------------------------------------------------------------------------*/ - -void m68k_lockup_w_8 (unsigned int address, unsigned int data) -{ -#ifdef LOGERROR - error ("Lockup %08X = %02X (%08X)\n", address, data, m68k_get_reg(M68K_REG_PC)); -#endif - if (!config.force_dtack) - { - m68k_pulse_halt(); - m68k.cycles = m68k.cycle_end; - } -} - -void m68k_lockup_w_16 (unsigned int address, unsigned int data) -{ -#ifdef LOGERROR - error ("Lockup %08X = %04X (%08X)\n", address, data, m68k_get_reg(M68K_REG_PC)); -#endif - if (!config.force_dtack) - { - m68k_pulse_halt(); - m68k.cycles = m68k.cycle_end; - } -} - -unsigned int m68k_lockup_r_8 (unsigned int address) -{ -#ifdef LOGERROR - error ("Lockup %08X.b (%08X)\n", address, m68k_get_reg(M68K_REG_PC)); -#endif - if (!config.force_dtack) - { - m68k_pulse_halt(); - m68k.cycles = m68k.cycle_end; - } - address = m68k.pc | (address & 1); - return READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff); -} - -unsigned int m68k_lockup_r_16 (unsigned int address) -{ -#ifdef LOGERROR - error ("Lockup %08X.w (%08X)\n", address, m68k_get_reg(M68K_REG_PC)); -#endif - if (!config.force_dtack) - { - m68k_pulse_halt(); - m68k.cycles = m68k.cycle_end; - } - address = m68k.pc; - return *(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)); -} - - -/*--------------------------------------------------------------------------*/ -/* Z80 bus (accessed through I/O chip) */ -/*--------------------------------------------------------------------------*/ - -unsigned int z80_read_byte(unsigned int address) -{ - switch ((address >> 13) & 3) - { - case 2: /* YM2612 */ - { - return fm_read(m68k.cycles, address & 3); - } - - case 3: /* Misc */ - { - /* VDP (through 68k bus) */ - if ((address & 0xFF00) == 0x7F00) - { - return m68k_lockup_r_8(address); - } - return (m68k_read_bus_8(address) | 0xFF); - } - - default: /* ZRAM */ - { - return zram[address & 0x1FFF]; - } - } -} - -unsigned int z80_read_word(unsigned int address) -{ - unsigned int data = z80_read_byte(address); - return (data | (data << 8)); -} - -void z80_write_byte(unsigned int address, unsigned int data) -{ - switch ((address >> 13) & 3) - { - case 2: /* YM2612 */ - { - fm_write(m68k.cycles, address & 3, data); - return; - } - - case 3: - { - switch ((address >> 8) & 0x7F) - { - case 0x60: /* Bank register */ - { - gen_zbank_w(data & 1); - return; - } - - case 0x7F: /* VDP */ - { - m68k_lockup_w_8(address, data); - return; - } - - default: - { - m68k_unused_8_w(address, data); - return; - } - } - } - - default: /* ZRAM */ - { - zram[address & 0x1FFF] = data; - m68k.cycles += 8; /* ZRAM access latency (fixes Pacman 2: New Adventures) */ - return; - } - } -} - -void z80_write_word(unsigned int address, unsigned int data) -{ - z80_write_byte(address, data >> 8); -} - - -/*--------------------------------------------------------------------------*/ -/* I/O Control */ -/*--------------------------------------------------------------------------*/ - -static void m68k_poll_detect(unsigned int reg_mask) -{ - /* detect MAIN-CPU register polling */ - if (m68k.poll.detected & reg_mask) - { - if (m68k.cycles <= m68k.poll.cycle) - { - if (m68k.pc == m68k.poll.pc) - { - /* MAIN-CPU polling confirmed ? */ - if (m68k.poll.detected & 1) - { - /* idle MAIN-CPU until register is modified */ - m68k.cycles = m68k.cycle_end; - m68k.stopped = reg_mask; -#ifdef LOG_SCD - error("m68k stopped from %d cycles\n", m68k.cycles); -#endif - } - else - { - /* confirm MAIN-CPU polling */ - m68k.poll.detected |= 1; - m68k.poll.cycle = m68k.cycles + 840; - } - } - return; - } - } - else - { - /* set MAIN-CPU register access flag */ - m68k.poll.detected = reg_mask; - } - - /* reset MAIN-CPU polling detection */ - m68k.poll.cycle = m68k.cycles + 840; - m68k.poll.pc = m68k.pc; -} - -static void m68k_poll_sync(unsigned int reg_mask) -{ - /* relative SUB-CPU cycle counter */ - unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE; - - /* sync SUB-CPU with MAIN-CPU */ - if (!s68k.stopped) - { - s68k_run(cycles); - } - - /* SUB-CPU idle on register polling ? */ - if (s68k.stopped & reg_mask) - { - /* sync SUB-CPU with MAIN-CPU */ - s68k.cycles = cycles; - - /* restart SUB-CPU */ - s68k.stopped = 0; -#ifdef LOG_SCD - error("s68k started from %d cycles\n", cycles); -#endif - } - - /* clear CPU register access flags */ - s68k.poll.detected &= ~reg_mask; - m68k.poll.detected &= ~reg_mask; -} - -unsigned int ctrl_io_read_byte(unsigned int address) -{ - switch ((address >> 8) & 0xFF) - { - case 0x00: /* I/O chip */ - { - if (!(address & 0xE0)) - { - return io_68k_read((address >> 1) & 0x0F); - } - return m68k_read_bus_8(address); - } - - case 0x11: /* Z80 BUSACK */ - { - if (!(address & 1)) - { - /* Unused bits return prefetched bus data (Time Killers) */ - address = m68k.pc; - - /* Check if bus has been requested and is not reseted */ - if (zstate == 3) - { - /* D0 is cleared */ - return (READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff) & 0xFE); - } - - /* D0 is set */ - return (READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff) | 0x01); - } - return m68k_read_bus_8(address); - } - - case 0x20: /* MEGA-CD */ - { -#ifdef LOG_SCD - error("[%d][%d]read byte CD register %X (%X)\n", v_counter, m68k.cycles, address, m68k.pc); -#endif - if (system_hw == SYSTEM_MCD) - { - /* register index ($A12000-A1203F mirrored up to $A120FF) */ - uint8 index = address & 0x3f; - - /* Memory Mode */ - if (index == 0x03) - { - m68k_poll_detect(1<<0x03); - return scd.regs[0x03>>1].byte.l; - } - - /* SUB-CPU communication flags */ - if (index == 0x0f) - { - if (!s68k.stopped) - { - /* relative SUB-CPU cycle counter */ - unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE; - - /* sync SUB-CPU with MAIN-CPU (Dracula Unleashed w/ Sega CD Model 2 Boot ROM) */ - s68k_run(cycles); - } - - m68k_poll_detect(1<<0x0f); - return scd.regs[0x0f>>1].byte.l; - } - - /* default registers */ - if (index < 0x30) - { - /* SUB-CPU communication words */ - if (index >= 0x20) - { - m68k_poll_detect(1 << (index - 0x10)); - } - - /* register LSB */ - if (address & 1) - { - return scd.regs[index >> 1].byte.l; - } - - /* register MSB */ - return scd.regs[index >> 1].byte.h; - } - } - - return m68k_read_bus_8(address); - } - - case 0x30: /* TIME */ - { - if (cart.hw.time_r) - { - unsigned int data = cart.hw.time_r(address); - if (address & 1) - { - return (data & 0xFF); - } - return (data >> 8); - } - return m68k_read_bus_8(address); - } - - case 0x41: /* BOOT ROM */ - { - if ((config.bios & 1) && (address & 1)) - { - unsigned int data = gen_bankswitch_r() & 1; - - /* Unused bits return prefetched bus data */ - address = m68k.pc; - data |= (READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff) & 0xFE); - return data; - } - return m68k_read_bus_8(address); - } - - case 0x10: /* MEMORY MODE */ - case 0x12: /* Z80 RESET */ - case 0x13: /* unknown */ - case 0x40: /* TMSS */ - case 0x44: /* RADICA */ - case 0x50: /* SVP */ - { - return m68k_read_bus_8(address); - } - - default: /* Invalid address */ - { - return m68k_lockup_r_8(address); - } - } -} - -unsigned int ctrl_io_read_word(unsigned int address) -{ - switch ((address >> 8) & 0xFF) - { - case 0x00: /* I/O chip */ - { - if (!(address & 0xE0)) - { - unsigned int data = io_68k_read((address >> 1) & 0x0F); - return (data << 8 | data); - } - return m68k_read_bus_16(address); - } - - case 0x11: /* Z80 BUSACK */ - { - /* Unused bits return prefetched bus data (Time Killers) */ - address = m68k.pc; - - /* Check if bus has been requested and is not reseted */ - if (zstate == 3) - { - /* D8 is cleared */ - return (*(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)) & 0xFEFF); - } - - /* D8 is set */ - return (*(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)) | 0x0100); - } - - case 0x20: /* MEGA-CD */ - { -#ifdef LOG_SCD - error("[%d][%d]read word CD register %X (%X)\n", v_counter, m68k.cycles, address, m68k.pc); -#endif - if (system_hw == SYSTEM_MCD) - { - /* register index ($A12000-A1203F mirrored up to $A120FF) */ - uint8 index = address & 0x3f; - - /* Memory Mode */ - if (index == 0x02) - { - m68k_poll_detect(1<<0x03); - return scd.regs[0x03>>1].w; - } - - /* CDC host data (word access only ?) */ - if (index == 0x08) - { - return cdc_host_r(); - } - - /* H-INT vector (word access only ?) */ - if (index == 0x06) - { - return *(uint16 *)(m68k.memory_map[0].base + 0x72); - } - - /* Stopwatch counter (word read access only ?) */ - if (index == 0x0c) - { - /* relative SUB-CPU cycle counter */ - unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE; - - /* cycle-accurate counter value */ - return (scd.regs[0x0c>>1].w + ((cycles - scd.stopwatch) / TIMERS_SCYCLES_RATIO)) & 0xfff; - } - - /* default registers */ - if (index < 0x30) - { - /* SUB-CPU communication words */ - if (index >= 0x20) - { - if (!s68k.stopped) - { - /* relative SUB-CPU cycle counter */ - unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE; - - /* sync SUB-CPU with MAIN-CPU (Soul Star) */ - s68k_run(cycles); - } - - m68k_poll_detect(3 << (index - 0x10)); - } - - return scd.regs[index >> 1].w; - } - } - - /* invalid address */ - return m68k_read_bus_16(address); - } - - case 0x30: /* TIME */ - { - if (cart.hw.time_r) - { - return cart.hw.time_r(address); - } - return m68k_read_bus_16(address); - } - - case 0x50: /* SVP */ - { - if ((address & 0xFD) == 0) - { - return svp->ssp1601.gr[SSP_XST].byte.h; - } - - if ((address & 0xFF) == 4) - { - unsigned int data = svp->ssp1601.gr[SSP_PM0].byte.h; - svp->ssp1601.gr[SSP_PM0].byte.h &= ~1; - return data; - } - - return m68k_read_bus_16(address); - } - - case 0x10: /* MEMORY MODE */ - case 0x12: /* Z80 RESET */ - case 0x13: /* unknown */ - case 0x40: /* TMSS */ - case 0x41: /* BOOT ROM */ - case 0x44: /* RADICA */ - { - return m68k_read_bus_16(address); - } - - default: /* Invalid address */ - { - return m68k_lockup_r_16(address); - } - } -} - -void ctrl_io_write_byte(unsigned int address, unsigned int data) -{ - switch ((address >> 8) & 0xFF) - { - case 0x00: /* I/O chip */ - { - if ((address & 0xE1) == 0x01) - { - /* get /LWR only */ - io_68k_write((address >> 1) & 0x0F, data); - return; - } - m68k_unused_8_w(address, data); - return; - } - - case 0x11: /* Z80 BUSREQ */ - { - if (!(address & 1)) - { - gen_zbusreq_w(data & 1, m68k.cycles); - return; - } - m68k_unused_8_w(address, data); - return; - } - - case 0x12: /* Z80 RESET */ - { - if (!(address & 1)) - { - gen_zreset_w(data & 1, m68k.cycles); - return; - } - m68k_unused_8_w(address, data); - return; - } - - case 0x20: /* MEGA-CD */ - { -#ifdef LOG_SCD - error("[%d][%d]write byte CD register %X -> 0x%02X (%X)\n", v_counter, m68k.cycles, address, data, m68k.pc); -#endif - if (system_hw == SYSTEM_MCD) - { - /* register index ($A12000-A1203F mirrored up to $A120FF) */ - switch (address & 0x3f) - { - case 0x00: /* SUB-CPU interrupt */ - { - /* IFL2 bit */ - if (data & 0x01) - { - /* level 2 interrupt enabled ? */ - if (scd.regs[0x32>>1].byte.l & 0x04) - { - if (!s68k.stopped) - { - /* relative SUB-CPU cycle counter */ - unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE; - - /* sync SUB-CPU with MAIN-CPU (Earnest Evans, Fhey Area) */ - s68k_run(cycles); - } - - /* set IFL2 flag */ - scd.regs[0x00].byte.h |= 0x01; - - /* trigger level 2 interrupt */ - scd.pending |= (1 << 2); - - /* update IRQ level */ - s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); - } - } - - /* writing 0 does nothing */ - return; - } - - case 0x01: /* SUB-CPU control */ - { - /* RESET bit */ - if (data & 0x01) - { - /* trigger reset on 0->1 transition */ - if (!(scd.regs[0x00].byte.l & 0x01)) - { - /* reset SUB-CPU */ - s68k_pulse_reset(); - } - - /* BUSREQ bit */ - if (data & 0x02) - { - /* SUB-CPU bus requested */ - s68k_pulse_halt(); - } - else - { - /* SUB-CPU bus released */ - s68k_clear_halt(); - } - } - else - { - /* SUB-CPU is halted while !RESET is asserted */ - s68k_pulse_halt(); - } - - scd.regs[0x00].byte.l = data; - return; - } - - case 0x02: /* PRG-RAM Write Protection */ - { - scd.regs[0x02>>1].byte.h = data; - return; - } - - case 0x03: /* Memory mode */ - { - m68k_poll_sync(1<<0x03); - - /* PRG-RAM 128k bank mapped to $020000-$03FFFF (resp. $420000-$43FFFF) */ - m68k.memory_map[scd.cartridge.boot + 0x02].base = scd.prg_ram + ((data & 0xc0) << 11); - m68k.memory_map[scd.cartridge.boot + 0x03].base = m68k.memory_map[scd.cartridge.boot + 0x02].base + 0x10000; - - /* check current mode */ - if (scd.regs[0x03>>1].byte.l & 0x04) - { - /* DMNA bit */ - if (data & 0x02) - { - /* writing 1 to DMNA in 1M mode will return Word-RAM to SUB-CPU in 2M mode */ - scd.dmna = 1; - } - else - { - /* writing 0 to DMNA in 1M mode actually set DMNA bit */ - data |= 0x02; - - /* update BK0-1 & DMNA bits */ - scd.regs[0x03>>1].byte.l = (scd.regs[0x03>>1].byte.l & ~0xc2) | (data & 0xc2); - return; - } - } - else - { - /* writing 0 in 2M mode does nothing */ - if (data & 0x02) - { - /* Word-RAM is assigned to SUB-CPU */ - scd.dmna = 1; - - /* clear RET bit */ - scd.regs[0x03>>1].byte.l = (scd.regs[0x03>>1].byte.l & ~0xc3) | (data & 0xc2); - return; - } - } - - /* update BK0-1 bits */ - scd.regs[0x03>>1].byte.l = (scd.regs[0x02>>1].byte.l & ~0xc0) | (data & 0xc0); - return; - } - - case 0x0e: /* MAIN-CPU communication flags */ - case 0x0f: /* !LWR is ignored (Space Ace, Dragon's Lair) */ - { - m68k_poll_sync(1<<0x0e); - scd.regs[0x0e>>1].byte.h = data; - return; - } - - default: - { - /* MAIN-CPU communication words */ - if ((address & 0x30) == 0x10) - { - m68k_poll_sync(1 << (address & 0x1f)); - - /* register LSB */ - if (address & 1) - { - scd.regs[(address >> 1) & 0xff].byte.l = data; - return; - } - - /* register MSB */ - scd.regs[(address >> 1) & 0xff].byte.h = data; - return; - } - - /* invalid address */ - m68k_unused_8_w(address, data); - return; - } - } - } - - m68k_unused_8_w(address, data); - return; - } - - case 0x30: /* TIME */ - { - cart.hw.time_w(address, data); - return; - } - - case 0x41: /* BOOT ROM */ - { - if ((config.bios & 1) && (address & 1)) - { - gen_bankswitch_w(data & 1); - return; - } - m68k_unused_8_w(address, data); - return; - } - - case 0x10: /* MEMORY MODE */ - case 0x13: /* unknown */ - case 0x40: /* TMSS */ - case 0x44: /* RADICA */ - case 0x50: /* SVP */ - { - m68k_unused_8_w(address, data); - return; - } - - default: /* Invalid address */ - { - m68k_lockup_w_8(address, data); - return; - } - } -} - -void ctrl_io_write_word(unsigned int address, unsigned int data) -{ - switch ((address >> 8) & 0xFF) - { - case 0x00: /* I/O chip */ - { - if (!(address & 0xE0)) - { - io_68k_write((address >> 1) & 0x0F, data & 0xFF); - return; - } - m68k_unused_16_w(address, data); - return; - } - - case 0x11: /* Z80 BUSREQ */ - { - gen_zbusreq_w((data >> 8) & 1, m68k.cycles); - return; - } - - case 0x12: /* Z80 RESET */ - { - gen_zreset_w((data >> 8) & 1, m68k.cycles); - return; - } - - case 0x20: /* MEGA-CD */ - { -#ifdef LOG_SCD - error("[%d][%d]write word CD register %X -> 0x%04X (%X)\n", v_counter, m68k.cycles, address, data, m68k.pc); -#endif - if (system_hw == SYSTEM_MCD) - { - /* register index ($A12000-A1203F mirrored up to $A120FF) */ - switch (address & 0x3e) - { - case 0x00: /* SUB-CPU interrupt & control */ - { - /* RESET bit */ - if (data & 0x01) - { - /* trigger reset on 0->1 transition */ - if (!(scd.regs[0x00].byte.l & 0x01)) - { - /* reset SUB-CPU */ - s68k_pulse_reset(); - } - - /* BUSREQ bit */ - if (data & 0x02) - { - /* SUB-CPU bus requested */ - s68k_pulse_halt(); - } - else - { - /* SUB-CPU bus released */ - s68k_clear_halt(); - } - } - else - { - /* SUB-CPU is halted while !RESET is asserted */ - s68k_pulse_halt(); - } - - /* IFL2 bit */ - if (data & 0x100) - { - /* level 2 interrupt enabled ? */ - if (scd.regs[0x32>>1].byte.l & 0x04) - { - /* set IFL2 flag */ - scd.regs[0x00].byte.h |= 0x01; - - /* trigger level 2 interrupt */ - scd.pending |= (1 << 2); - - /* update IRQ level */ - s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); - } - } - - /* update LSB only */ - scd.regs[0x00].byte.l = data & 0xff; - return; - } - - case 0x02: /* Memory Mode */ - { - m68k_poll_sync(1<<0x03); - - /* PRG-RAM 128k bank mapped to $020000-$03FFFF (resp. $420000-$43FFFF) */ - m68k.memory_map[scd.cartridge.boot + 0x02].base = scd.prg_ram + ((data & 0xc0) << 11); - m68k.memory_map[scd.cartridge.boot + 0x03].base = m68k.memory_map[scd.cartridge.boot + 0x02].base + 0x10000; - - /* check current mode */ - if (scd.regs[0x03>>1].byte.l & 0x04) - { - /* DMNA bit */ - if (data & 0x02) - { - /* writing 1 to DMNA in 1M mode will return Word-RAM to SUB-CPU in 2M mode */ - scd.dmna = 1; - } - else - { - /* writing 0 to DMNA in 1M mode actually set DMNA bit */ - data |= 0x02; - - /* update WP0-7, BK0-1 & DMNA bits */ - scd.regs[0x02>>1].w = (scd.regs[0x02>>1].w & ~0xffc2) | (data & 0xffc2); - return; - } - } - else - { - /* writing 0 in 2M mode does nothing */ - if (data & 0x02) - { - /* Word-RAM is assigned to SUB-CPU */ - scd.dmna = 1; - - /* clear RET bit */ - scd.regs[0x02>>1].w = (scd.regs[0x02>>1].w & ~0xffc3) | (data & 0xffc2); - return; - } - } - - /* update WP0-7 & BK0-1 bits */ - scd.regs[0x02>>1].w = (scd.regs[0x02>>1].w & ~0xffc0) | (data & 0xffc0); - return; - } - - case 0x06: /* H-INT vector (word access only ?) */ - { - *(uint16 *)(m68k.memory_map[0].base + 0x72) = data; - return; - } - - case 0x0e: /* CPU communication flags */ - { - m68k_poll_sync(1<<0x0e); - - /* D8-D15 ignored -> only MAIN-CPU flags are updated (Mortal Kombat) */ - scd.regs[0x0e>>1].byte.h = data & 0xff; - return; - } - - default: - { - /* MAIN-CPU communication words */ - if ((address & 0x30) == 0x10) - { - m68k_poll_sync(3 << (address & 0x1e)); - scd.regs[(address >> 1) & 0xff].w = data; - return; - } - - /* invalid address */ - m68k_unused_16_w (address, data); - return; - } - } - } - - m68k_unused_16_w (address, data); - return; - } - - case 0x30: /* TIME */ - { - cart.hw.time_w(address, data); - return; - } - - case 0x40: /* TMSS */ - { - if (config.bios & 1) - { - gen_tmss_w(address & 3, data); - return; - } - m68k_unused_16_w(address, data); - return; - } - - case 0x50: /* SVP */ - { - if (!(address & 0xFD)) - { - svp->ssp1601.gr[SSP_XST].byte.h = data; - svp->ssp1601.gr[SSP_PM0].byte.h |= 2; - svp->ssp1601.emu_status &= ~SSP_WAIT_PM0; - return; - } - m68k_unused_16_w(address, data); - return; - } - - case 0x10: /* MEMORY MODE */ - case 0x13: /* unknown */ - case 0x41: /* BOOT ROM */ - case 0x44: /* RADICA */ - { - m68k_unused_16_w (address, data); - return; - } - - default: /* Invalid address */ - { - m68k_lockup_w_16 (address, data); - return; - } - } -} - - -/*--------------------------------------------------------------------------*/ -/* VDP */ -/*--------------------------------------------------------------------------*/ - -unsigned int vdp_read_byte(unsigned int address) -{ - switch (address & 0xFD) - { - case 0x00: /* DATA */ - { - return (vdp_68k_data_r() >> 8); - } - - case 0x01: /* DATA */ - { - return (vdp_68k_data_r() & 0xFF); - } - - case 0x04: /* CTRL */ - { - unsigned int data = (vdp_68k_ctrl_r(m68k.cycles) >> 8) & 3; - - /* Unused bits return prefetched bus data */ - address = m68k.pc; - data |= (READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff) & 0xFC); - - return data; - } - - case 0x05: /* CTRL */ - { - return (vdp_68k_ctrl_r(m68k.cycles) & 0xFF); - } - - case 0x08: /* HVC */ - case 0x0C: - { - return (vdp_hvc_r(m68k.cycles) >> 8); - } - - case 0x09: /* HVC */ - case 0x0D: - { - return (vdp_hvc_r(m68k.cycles) & 0xFF); - } - - case 0x18: /* Unused */ - case 0x19: - case 0x1C: - case 0x1D: - { - return m68k_read_bus_8(address); - } - - default: /* Invalid address */ - { - return m68k_lockup_r_8(address); - } - } -} - -unsigned int vdp_read_word(unsigned int address) -{ - switch (address & 0xFC) - { - case 0x00: /* DATA */ - { - return vdp_68k_data_r(); - } - - case 0x04: /* CTRL */ - { - unsigned int data = vdp_68k_ctrl_r(m68k.cycles) & 0x3FF; - - /* Unused bits return prefetched bus data */ - address = m68k.pc; - data |= (*(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)) & 0xFC00); - - return data; - } - - case 0x08: /* HVC */ - case 0x0C: - { - return vdp_hvc_r(m68k.cycles); - } - - case 0x18: /* Unused */ - case 0x1C: - { - return m68k_read_bus_16(address); - } - - default: /* Invalid address */ - { - return m68k_lockup_r_16(address); - } - } -} - -void vdp_write_byte(unsigned int address, unsigned int data) -{ - switch (address & 0xFC) - { - case 0x00: /* Data port */ - { - vdp_68k_data_w(data << 8 | data); - return; - } - - case 0x04: /* Control port */ - { - vdp_68k_ctrl_w(data << 8 | data); - return; - } - - case 0x10: /* PSG */ - case 0x14: - { - if (address & 1) - { - SN76489_Write(m68k.cycles, data); - return; - } - m68k_unused_8_w(address, data); - return; - } - - case 0x18: /* Unused */ - { - m68k_unused_8_w(address, data); - return; - } - - case 0x1C: /* TEST register */ - { - vdp_test_w(data << 8 | data); - return; - } - - default: /* Invalid address */ - { - m68k_lockup_w_8(address, data); - return; - } - } -} - -void vdp_write_word(unsigned int address, unsigned int data) -{ - switch (address & 0xFC) - { - case 0x00: /* DATA */ - { - vdp_68k_data_w(data); - return; - } - - case 0x04: /* CTRL */ - { - vdp_68k_ctrl_w(data); - return; - } - - case 0x10: /* PSG */ - case 0x14: - { - SN76489_Write(m68k.cycles, data & 0xFF); - return; - } - - case 0x18: /* Unused */ - { - m68k_unused_16_w(address, data); - return; - } - - case 0x1C: /* Test register */ - { - vdp_test_w(data); - return; - } - - default: /* Invalid address */ - { - m68k_lockup_w_16 (address, data); - return; - } - } -} - - -/*--------------------------------------------------------------------------*/ -/* PICO (incomplete) */ -/*--------------------------------------------------------------------------*/ - -unsigned int pico_read_byte(unsigned int address) -{ - switch (address & 0xFF) - { - case 0x01: /* VERSION register */ - { - return (region_code >> 1); - } - - case 0x03: /* IO register */ - { - return ~input.pad[0]; - } - - case 0x05: /* PEN X coordinate (MSB) */ - { - return (input.analog[0][0] >> 8); - } - - case 0x07: /* PEN X coordinate (LSB) */ - { - return (input.analog[0][0] & 0xFF); - } - - case 0x09: /* PEN Y coordinate (MSB) */ - { - return (input.analog[0][1] >> 8); - } - - case 0x0B: /* PEN Y coordinate (LSB) */ - { - return (input.analog[0][1] & 0xFF); - } - - case 0x0D: /* PAGE register */ - { - return (1 << pico_current) - 1; - } - - case 0x10: /* ADPCM data registers (TODO) */ - case 0x11: - { - return 0xff; - } - - case 0x12: /* ADPCM control registers (TODO) */ - { - return 0x80; - } - - default: - { - return m68k_read_bus_8(address); - } - } -} - -unsigned int pico_read_word(unsigned int address) -{ - return (pico_read_byte(address | 1) | (pico_read_byte(address) << 8)); -} +/*************************************************************************************** + * Genesis Plus + * Main 68k bus handlers + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +/*--------------------------------------------------------------------------*/ +/* Unused areas (return open bus data, i.e prefetched instruction word) */ +/*--------------------------------------------------------------------------*/ + +unsigned int m68k_read_bus_8(unsigned int address) +{ +#ifdef LOGERROR + error("Unused read8 %08X (%08X)\n", address, m68k_get_reg(M68K_REG_PC)); +#endif + address = m68k.pc | (address & 1); + return READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff); +} + +unsigned int m68k_read_bus_16(unsigned int address) +{ +#ifdef LOGERROR + error("Unused read16 %08X (%08X)\n", address, m68k_get_reg(M68K_REG_PC)); +#endif + address = m68k.pc; + return *(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)); +} + + +void m68k_unused_8_w(unsigned int address, unsigned int data) +{ +#ifdef LOGERROR + error("Unused write8 %08X = %02X (%08X)\n", address, data, m68k_get_reg(M68K_REG_PC)); +#endif +} + +void m68k_unused_16_w(unsigned int address, unsigned int data) +{ +#ifdef LOGERROR + error("Unused write16 %08X = %04X (%08X)\n", address, data, m68k_get_reg(M68K_REG_PC)); +#endif +} + + +/*--------------------------------------------------------------------------*/ +/* Illegal areas (cause system to lock-up since !DTACK is not returned) */ +/*--------------------------------------------------------------------------*/ + +void m68k_lockup_w_8 (unsigned int address, unsigned int data) +{ +#ifdef LOGERROR + error ("Lockup %08X = %02X (%08X)\n", address, data, m68k_get_reg(M68K_REG_PC)); +#endif + if (!config.force_dtack) + { + m68k_pulse_halt(); + m68k.cycles = m68k.cycle_end; + } +} + +void m68k_lockup_w_16 (unsigned int address, unsigned int data) +{ +#ifdef LOGERROR + error ("Lockup %08X = %04X (%08X)\n", address, data, m68k_get_reg(M68K_REG_PC)); +#endif + if (!config.force_dtack) + { + m68k_pulse_halt(); + m68k.cycles = m68k.cycle_end; + } +} + +unsigned int m68k_lockup_r_8 (unsigned int address) +{ +#ifdef LOGERROR + error ("Lockup %08X.b (%08X)\n", address, m68k_get_reg(M68K_REG_PC)); +#endif + if (!config.force_dtack) + { + m68k_pulse_halt(); + m68k.cycles = m68k.cycle_end; + } + address = m68k.pc | (address & 1); + return READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff); +} + +unsigned int m68k_lockup_r_16 (unsigned int address) +{ +#ifdef LOGERROR + error ("Lockup %08X.w (%08X)\n", address, m68k_get_reg(M68K_REG_PC)); +#endif + if (!config.force_dtack) + { + m68k_pulse_halt(); + m68k.cycles = m68k.cycle_end; + } + address = m68k.pc; + return *(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)); +} + + +/*--------------------------------------------------------------------------*/ +/* Z80 bus (accessed through I/O chip) */ +/*--------------------------------------------------------------------------*/ + +unsigned int z80_read_byte(unsigned int address) +{ + switch ((address >> 13) & 3) + { + case 2: /* YM2612 */ + { + return fm_read(m68k.cycles, address & 3); + } + + case 3: /* Misc */ + { + /* VDP (through 68k bus) */ + if ((address & 0xFF00) == 0x7F00) + { + return m68k_lockup_r_8(address); + } + return (m68k_read_bus_8(address) | 0xFF); + } + + default: /* ZRAM */ + { + return zram[address & 0x1FFF]; + } + } +} + +unsigned int z80_read_word(unsigned int address) +{ + unsigned int data = z80_read_byte(address); + return (data | (data << 8)); +} + +void z80_write_byte(unsigned int address, unsigned int data) +{ + switch ((address >> 13) & 3) + { + case 2: /* YM2612 */ + { + fm_write(m68k.cycles, address & 3, data); + return; + } + + case 3: + { + switch ((address >> 8) & 0x7F) + { + case 0x60: /* Bank register */ + { + gen_zbank_w(data & 1); + return; + } + + case 0x7F: /* VDP */ + { + m68k_lockup_w_8(address, data); + return; + } + + default: + { + m68k_unused_8_w(address, data); + return; + } + } + } + + default: /* ZRAM */ + { + zram[address & 0x1FFF] = data; + m68k.cycles += 8; /* ZRAM access latency (fixes Pacman 2: New Adventures) */ + return; + } + } +} + +void z80_write_word(unsigned int address, unsigned int data) +{ + z80_write_byte(address, data >> 8); +} + + +/*--------------------------------------------------------------------------*/ +/* I/O Control */ +/*--------------------------------------------------------------------------*/ + +static void m68k_poll_detect(unsigned int reg_mask) +{ + /* detect MAIN-CPU register polling */ + if (m68k.poll.detected & reg_mask) + { + if (m68k.cycles <= m68k.poll.cycle) + { + if (m68k.pc == m68k.poll.pc) + { + /* MAIN-CPU polling confirmed ? */ + if (m68k.poll.detected & 1) + { + /* idle MAIN-CPU until register is modified */ + m68k.cycles = m68k.cycle_end; + m68k.stopped = reg_mask; +#ifdef LOG_SCD + error("m68k stopped from %d cycles\n", m68k.cycles); +#endif + } + else + { + /* confirm MAIN-CPU polling */ + m68k.poll.detected |= 1; + m68k.poll.cycle = m68k.cycles + 840; + } + } + return; + } + } + else + { + /* set MAIN-CPU register access flag */ + m68k.poll.detected = reg_mask; + } + + /* reset MAIN-CPU polling detection */ + m68k.poll.cycle = m68k.cycles + 840; + m68k.poll.pc = m68k.pc; +} + +static void m68k_poll_sync(unsigned int reg_mask) +{ + /* relative SUB-CPU cycle counter */ + unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE; + + /* sync SUB-CPU with MAIN-CPU */ + if (!s68k.stopped) + { + s68k_run(cycles); + } + + /* SUB-CPU idle on register polling ? */ + if (s68k.stopped & reg_mask) + { + /* sync SUB-CPU with MAIN-CPU */ + s68k.cycles = cycles; + + /* restart SUB-CPU */ + s68k.stopped = 0; +#ifdef LOG_SCD + error("s68k started from %d cycles\n", cycles); +#endif + } + + /* clear CPU register access flags */ + s68k.poll.detected &= ~reg_mask; + m68k.poll.detected &= ~reg_mask; +} + +unsigned int ctrl_io_read_byte(unsigned int address) +{ + switch ((address >> 8) & 0xFF) + { + case 0x00: /* I/O chip */ + { + if (!(address & 0xE0)) + { + return io_68k_read((address >> 1) & 0x0F); + } + return m68k_read_bus_8(address); + } + + case 0x11: /* Z80 BUSACK */ + { + if (!(address & 1)) + { + /* Unused bits return prefetched bus data (Time Killers) */ + address = m68k.pc; + + /* Check if bus has been requested and is not reseted */ + if (zstate == 3) + { + /* D0 is cleared */ + return (READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff) & 0xFE); + } + + /* D0 is set */ + return (READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff) | 0x01); + } + return m68k_read_bus_8(address); + } + + case 0x20: /* MEGA-CD */ + { +#ifdef LOG_SCD + error("[%d][%d]read byte CD register %X (%X)\n", v_counter, m68k.cycles, address, m68k.pc); +#endif + if (system_hw == SYSTEM_MCD) + { + /* register index ($A12000-A1203F mirrored up to $A120FF) */ + uint8 index = address & 0x3f; + + /* Memory Mode */ + if (index == 0x03) + { + m68k_poll_detect(1<<0x03); + return scd.regs[0x03>>1].byte.l; + } + + /* SUB-CPU communication flags */ + if (index == 0x0f) + { + if (!s68k.stopped) + { + /* relative SUB-CPU cycle counter */ + unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE; + + /* sync SUB-CPU with MAIN-CPU (Dracula Unleashed w/ Sega CD Model 2 Boot ROM) */ + s68k_run(cycles); + } + + m68k_poll_detect(1<<0x0f); + return scd.regs[0x0f>>1].byte.l; + } + + /* default registers */ + if (index < 0x30) + { + /* SUB-CPU communication words */ + if (index >= 0x20) + { + m68k_poll_detect(1 << (index - 0x10)); + } + + /* register LSB */ + if (address & 1) + { + return scd.regs[index >> 1].byte.l; + } + + /* register MSB */ + return scd.regs[index >> 1].byte.h; + } + } + + return m68k_read_bus_8(address); + } + + case 0x30: /* TIME */ + { + if (cart.hw.time_r) + { + unsigned int data = cart.hw.time_r(address); + if (address & 1) + { + return (data & 0xFF); + } + return (data >> 8); + } + return m68k_read_bus_8(address); + } + + case 0x41: /* BOOT ROM */ + { + if ((config.bios & 1) && (address & 1)) + { + unsigned int data = gen_bankswitch_r() & 1; + + /* Unused bits return prefetched bus data */ + address = m68k.pc; + data |= (READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff) & 0xFE); + return data; + } + return m68k_read_bus_8(address); + } + + case 0x10: /* MEMORY MODE */ + case 0x12: /* Z80 RESET */ + case 0x13: /* unknown */ + case 0x40: /* TMSS */ + case 0x44: /* RADICA */ + case 0x50: /* SVP */ + { + if ((address & 0xFC) == 0x00) + { + unsigned int data = svp->ssp1601.gr[SSP_XST].byte.h; + return (address & 1) ? (data & 0xFF) : (data >> 8); + } + + if ((address & 0xFE) == 0x04) + { + unsigned int data = svp->ssp1601.gr[SSP_PM0].byte.h; + svp->ssp1601.gr[SSP_PM0].byte.h &= ~1; + return (address & 1) ? (data & 0xFF) : (data >> 8); + } + return m68k_read_bus_8(address); + } + + default: /* Invalid address */ + { + return m68k_lockup_r_8(address); + } + } +} + +unsigned int ctrl_io_read_word(unsigned int address) +{ + switch ((address >> 8) & 0xFF) + { + case 0x00: /* I/O chip */ + { + if (!(address & 0xE0)) + { + unsigned int data = io_68k_read((address >> 1) & 0x0F); + return (data << 8 | data); + } + return m68k_read_bus_16(address); + } + + case 0x11: /* Z80 BUSACK */ + { + /* Unused bits return prefetched bus data (Time Killers) */ + address = m68k.pc; + + /* Check if bus has been requested and is not reseted */ + if (zstate == 3) + { + /* D8 is cleared */ + return (*(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)) & 0xFEFF); + } + + /* D8 is set */ + return (*(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)) | 0x0100); + } + + case 0x20: /* MEGA-CD */ + { +#ifdef LOG_SCD + error("[%d][%d]read word CD register %X (%X)\n", v_counter, m68k.cycles, address, m68k.pc); +#endif + if (system_hw == SYSTEM_MCD) + { + /* register index ($A12000-A1203F mirrored up to $A120FF) */ + uint8 index = address & 0x3f; + + /* Memory Mode */ + if (index == 0x02) + { + m68k_poll_detect(1<<0x03); + return scd.regs[0x03>>1].w; + } + + /* CDC host data (word access only ?) */ + if (index == 0x08) + { + return cdc_host_r(); + } + + /* H-INT vector (word access only ?) */ + if (index == 0x06) + { + return *(uint16 *)(m68k.memory_map[0].base + 0x72); + } + + /* Stopwatch counter (word read access only ?) */ + if (index == 0x0c) + { + /* relative SUB-CPU cycle counter */ + unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE; + + /* cycle-accurate counter value */ + return (scd.regs[0x0c>>1].w + ((cycles - scd.stopwatch) / TIMERS_SCYCLES_RATIO)) & 0xfff; + } + + /* default registers */ + if (index < 0x30) + { + /* SUB-CPU communication words */ + if (index >= 0x20) + { + if (!s68k.stopped) + { + /* relative SUB-CPU cycle counter */ + unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE; + + /* sync SUB-CPU with MAIN-CPU (Soul Star) */ + s68k_run(cycles); + } + + m68k_poll_detect(3 << (index - 0x10)); + } + + return scd.regs[index >> 1].w; + } + } + + /* invalid address */ + return m68k_read_bus_16(address); + } + + case 0x30: /* TIME */ + { + if (cart.hw.time_r) + { + return cart.hw.time_r(address); + } + return m68k_read_bus_16(address); + } + + case 0x50: /* SVP */ + { + if ((address & 0xFC) == 0) + { + return svp->ssp1601.gr[SSP_XST].byte.h; + } + + if ((address & 0xFE) == 4) + { + unsigned int data = svp->ssp1601.gr[SSP_PM0].byte.h; + svp->ssp1601.gr[SSP_PM0].byte.h &= ~1; + return data; + } + + return m68k_read_bus_16(address); + } + + case 0x10: /* MEMORY MODE */ + case 0x12: /* Z80 RESET */ + case 0x13: /* unknown */ + case 0x40: /* TMSS */ + case 0x41: /* BOOT ROM */ + case 0x44: /* RADICA */ + { + return m68k_read_bus_16(address); + } + + default: /* Invalid address */ + { + return m68k_lockup_r_16(address); + } + } +} + +void ctrl_io_write_byte(unsigned int address, unsigned int data) +{ + switch ((address >> 8) & 0xFF) + { + case 0x00: /* I/O chip */ + { + if ((address & 0xE1) == 0x01) + { + /* get /LWR only */ + io_68k_write((address >> 1) & 0x0F, data); + return; + } + m68k_unused_8_w(address, data); + return; + } + + case 0x11: /* Z80 BUSREQ */ + { + if (!(address & 1)) + { + gen_zbusreq_w(data & 1, m68k.cycles); + return; + } + m68k_unused_8_w(address, data); + return; + } + + case 0x12: /* Z80 RESET */ + { + if (!(address & 1)) + { + gen_zreset_w(data & 1, m68k.cycles); + return; + } + m68k_unused_8_w(address, data); + return; + } + + case 0x20: /* MEGA-CD */ + { +#ifdef LOG_SCD + error("[%d][%d]write byte CD register %X -> 0x%02X (%X)\n", v_counter, m68k.cycles, address, data, m68k.pc); +#endif + if (system_hw == SYSTEM_MCD) + { + /* register index ($A12000-A1203F mirrored up to $A120FF) */ + switch (address & 0x3f) + { + case 0x00: /* SUB-CPU interrupt */ + { + /* IFL2 bit */ + if (data & 0x01) + { + /* level 2 interrupt enabled ? */ + if (scd.regs[0x32>>1].byte.l & 0x04) + { + if (!s68k.stopped) + { + /* relative SUB-CPU cycle counter */ + unsigned int cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE; + + /* sync SUB-CPU with MAIN-CPU (Earnest Evans, Fhey Area) */ + s68k_run(cycles); + } + + /* set IFL2 flag */ + scd.regs[0x00].byte.h |= 0x01; + + /* trigger level 2 interrupt */ + scd.pending |= (1 << 2); + + /* update IRQ level */ + s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); + } + } + + /* writing 0 does nothing */ + return; + } + + case 0x01: /* SUB-CPU control */ + { + /* RESET bit */ + if (data & 0x01) + { + /* trigger reset on 0->1 transition */ + if (!(scd.regs[0x00].byte.l & 0x01)) + { + /* reset SUB-CPU */ + s68k_pulse_reset(); + } + + /* BUSREQ bit */ + if (data & 0x02) + { + /* SUB-CPU bus requested */ + s68k_pulse_halt(); + } + else + { + /* SUB-CPU bus released */ + s68k_clear_halt(); + } + } + else + { + /* SUB-CPU is halted while !RESET is asserted */ + s68k_pulse_halt(); + } + + scd.regs[0x00].byte.l = data; + return; + } + + case 0x02: /* PRG-RAM Write Protection */ + { + scd.regs[0x02>>1].byte.h = data; + return; + } + + case 0x03: /* Memory mode */ + { + m68k_poll_sync(1<<0x03); + + /* PRG-RAM 128k bank mapped to $020000-$03FFFF (resp. $420000-$43FFFF) */ + m68k.memory_map[scd.cartridge.boot + 0x02].base = scd.prg_ram + ((data & 0xc0) << 11); + m68k.memory_map[scd.cartridge.boot + 0x03].base = m68k.memory_map[scd.cartridge.boot + 0x02].base + 0x10000; + + /* check current mode */ + if (scd.regs[0x03>>1].byte.l & 0x04) + { + /* DMNA bit */ + if (data & 0x02) + { + /* writing 1 to DMNA in 1M mode will return Word-RAM to SUB-CPU in 2M mode */ + scd.dmna = 1; + } + else + { + /* writing 0 to DMNA in 1M mode actually set DMNA bit */ + data |= 0x02; + + /* update BK0-1 & DMNA bits */ + scd.regs[0x03>>1].byte.l = (scd.regs[0x03>>1].byte.l & ~0xc2) | (data & 0xc2); + return; + } + } + else + { + /* writing 0 in 2M mode does nothing */ + if (data & 0x02) + { + /* Word-RAM is assigned to SUB-CPU */ + scd.dmna = 1; + + /* clear RET bit */ + scd.regs[0x03>>1].byte.l = (scd.regs[0x03>>1].byte.l & ~0xc3) | (data & 0xc2); + return; + } + } + + /* update BK0-1 bits */ + scd.regs[0x03>>1].byte.l = (scd.regs[0x02>>1].byte.l & ~0xc0) | (data & 0xc0); + return; + } + + case 0x0e: /* MAIN-CPU communication flags */ + case 0x0f: /* !LWR is ignored (Space Ace, Dragon's Lair) */ + { + m68k_poll_sync(1<<0x0e); + scd.regs[0x0e>>1].byte.h = data; + return; + } + + default: + { + /* MAIN-CPU communication words */ + if ((address & 0x30) == 0x10) + { + m68k_poll_sync(1 << (address & 0x1f)); + + /* register LSB */ + if (address & 1) + { + scd.regs[(address >> 1) & 0xff].byte.l = data; + return; + } + + /* register MSB */ + scd.regs[(address >> 1) & 0xff].byte.h = data; + return; + } + + /* invalid address */ + m68k_unused_8_w(address, data); + return; + } + } + } + + m68k_unused_8_w(address, data); + return; + } + + case 0x30: /* TIME */ + { + cart.hw.time_w(address, data); + return; + } + + case 0x41: /* BOOT ROM */ + { + if ((config.bios & 1) && (address & 1)) + { + gen_bankswitch_w(data & 1); + return; + } + m68k_unused_8_w(address, data); + return; + } + + case 0x10: /* MEMORY MODE */ + case 0x13: /* unknown */ + case 0x40: /* TMSS */ + case 0x44: /* RADICA */ + case 0x50: /* SVP */ + { + m68k_unused_8_w(address, data); + return; + } + + default: /* Invalid address */ + { + m68k_lockup_w_8(address, data); + return; + } + } +} + +void ctrl_io_write_word(unsigned int address, unsigned int data) +{ + switch ((address >> 8) & 0xFF) + { + case 0x00: /* I/O chip */ + { + if (!(address & 0xE0)) + { + io_68k_write((address >> 1) & 0x0F, data & 0xFF); + return; + } + m68k_unused_16_w(address, data); + return; + } + + case 0x11: /* Z80 BUSREQ */ + { + gen_zbusreq_w((data >> 8) & 1, m68k.cycles); + return; + } + + case 0x12: /* Z80 RESET */ + { + gen_zreset_w((data >> 8) & 1, m68k.cycles); + return; + } + + case 0x20: /* MEGA-CD */ + { +#ifdef LOG_SCD + error("[%d][%d]write word CD register %X -> 0x%04X (%X)\n", v_counter, m68k.cycles, address, data, m68k.pc); +#endif + if (system_hw == SYSTEM_MCD) + { + /* register index ($A12000-A1203F mirrored up to $A120FF) */ + switch (address & 0x3e) + { + case 0x00: /* SUB-CPU interrupt & control */ + { + /* RESET bit */ + if (data & 0x01) + { + /* trigger reset on 0->1 transition */ + if (!(scd.regs[0x00].byte.l & 0x01)) + { + /* reset SUB-CPU */ + s68k_pulse_reset(); + } + + /* BUSREQ bit */ + if (data & 0x02) + { + /* SUB-CPU bus requested */ + s68k_pulse_halt(); + } + else + { + /* SUB-CPU bus released */ + s68k_clear_halt(); + } + } + else + { + /* SUB-CPU is halted while !RESET is asserted */ + s68k_pulse_halt(); + } + + /* IFL2 bit */ + if (data & 0x100) + { + /* level 2 interrupt enabled ? */ + if (scd.regs[0x32>>1].byte.l & 0x04) + { + /* set IFL2 flag */ + scd.regs[0x00].byte.h |= 0x01; + + /* trigger level 2 interrupt */ + scd.pending |= (1 << 2); + + /* update IRQ level */ + s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1); + } + } + + /* update LSB only */ + scd.regs[0x00].byte.l = data & 0xff; + return; + } + + case 0x02: /* Memory Mode */ + { + m68k_poll_sync(1<<0x03); + + /* PRG-RAM 128k bank mapped to $020000-$03FFFF (resp. $420000-$43FFFF) */ + m68k.memory_map[scd.cartridge.boot + 0x02].base = scd.prg_ram + ((data & 0xc0) << 11); + m68k.memory_map[scd.cartridge.boot + 0x03].base = m68k.memory_map[scd.cartridge.boot + 0x02].base + 0x10000; + + /* check current mode */ + if (scd.regs[0x03>>1].byte.l & 0x04) + { + /* DMNA bit */ + if (data & 0x02) + { + /* writing 1 to DMNA in 1M mode will return Word-RAM to SUB-CPU in 2M mode */ + scd.dmna = 1; + } + else + { + /* writing 0 to DMNA in 1M mode actually set DMNA bit */ + data |= 0x02; + + /* update WP0-7, BK0-1 & DMNA bits */ + scd.regs[0x02>>1].w = (scd.regs[0x02>>1].w & ~0xffc2) | (data & 0xffc2); + return; + } + } + else + { + /* writing 0 in 2M mode does nothing */ + if (data & 0x02) + { + /* Word-RAM is assigned to SUB-CPU */ + scd.dmna = 1; + + /* clear RET bit */ + scd.regs[0x02>>1].w = (scd.regs[0x02>>1].w & ~0xffc3) | (data & 0xffc2); + return; + } + } + + /* update WP0-7 & BK0-1 bits */ + scd.regs[0x02>>1].w = (scd.regs[0x02>>1].w & ~0xffc0) | (data & 0xffc0); + return; + } + + case 0x06: /* H-INT vector (word access only ?) */ + { + *(uint16 *)(m68k.memory_map[0].base + 0x72) = data; + return; + } + + case 0x0e: /* CPU communication flags */ + { + m68k_poll_sync(1<<0x0e); + + /* D8-D15 ignored -> only MAIN-CPU flags are updated (Mortal Kombat) */ + scd.regs[0x0e>>1].byte.h = data & 0xff; + return; + } + + default: + { + /* MAIN-CPU communication words */ + if ((address & 0x30) == 0x10) + { + m68k_poll_sync(3 << (address & 0x1e)); + scd.regs[(address >> 1) & 0xff].w = data; + return; + } + + /* invalid address */ + m68k_unused_16_w (address, data); + return; + } + } + } + + m68k_unused_16_w (address, data); + return; + } + + case 0x30: /* TIME */ + { + cart.hw.time_w(address, data); + return; + } + + case 0x40: /* TMSS */ + { + if (config.bios & 1) + { + gen_tmss_w(address & 3, data); + return; + } + m68k_unused_16_w(address, data); + return; + } + + case 0x50: /* SVP */ + { + if (!(address & 0xFD)) + { + svp->ssp1601.gr[SSP_XST].byte.h = data; + svp->ssp1601.gr[SSP_PM0].byte.h |= 2; + svp->ssp1601.emu_status &= ~SSP_WAIT_PM0; + return; + } + m68k_unused_16_w(address, data); + return; + } + + case 0x10: /* MEMORY MODE */ + case 0x13: /* unknown */ + case 0x41: /* BOOT ROM */ + case 0x44: /* RADICA */ + { + m68k_unused_16_w (address, data); + return; + } + + default: /* Invalid address */ + { + m68k_lockup_w_16 (address, data); + return; + } + } +} + + +/*--------------------------------------------------------------------------*/ +/* VDP */ +/*--------------------------------------------------------------------------*/ + +unsigned int vdp_read_byte(unsigned int address) +{ + switch (address & 0xFD) + { + case 0x00: /* DATA */ + { + return (vdp_68k_data_r() >> 8); + } + + case 0x01: /* DATA */ + { + return (vdp_68k_data_r() & 0xFF); + } + + case 0x04: /* CTRL */ + { + unsigned int data = (vdp_68k_ctrl_r(m68k.cycles) >> 8) & 3; + + /* Unused bits return prefetched bus data */ + address = m68k.pc; + data |= (READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff) & 0xFC); + + return data; + } + + case 0x05: /* CTRL */ + { + return (vdp_68k_ctrl_r(m68k.cycles) & 0xFF); + } + + case 0x08: /* HVC */ + case 0x0C: + { + return (vdp_hvc_r(m68k.cycles) >> 8); + } + + case 0x09: /* HVC */ + case 0x0D: + { + return (vdp_hvc_r(m68k.cycles) & 0xFF); + } + + case 0x18: /* Unused */ + case 0x19: + case 0x1C: + case 0x1D: + { + return m68k_read_bus_8(address); + } + + default: /* Invalid address */ + { + return m68k_lockup_r_8(address); + } + } +} + +unsigned int vdp_read_word(unsigned int address) +{ + switch (address & 0xFC) + { + case 0x00: /* DATA */ + { + return vdp_68k_data_r(); + } + + case 0x04: /* CTRL */ + { + unsigned int data = vdp_68k_ctrl_r(m68k.cycles) & 0x3FF; + + /* Unused bits return prefetched bus data */ + address = m68k.pc; + data |= (*(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff)) & 0xFC00); + + return data; + } + + case 0x08: /* HVC */ + case 0x0C: + { + return vdp_hvc_r(m68k.cycles); + } + + case 0x18: /* Unused */ + case 0x1C: + { + return m68k_read_bus_16(address); + } + + default: /* Invalid address */ + { + return m68k_lockup_r_16(address); + } + } +} + +void vdp_write_byte(unsigned int address, unsigned int data) +{ + switch (address & 0xFC) + { + case 0x00: /* Data port */ + { + vdp_68k_data_w(data << 8 | data); + return; + } + + case 0x04: /* Control port */ + { + vdp_68k_ctrl_w(data << 8 | data); + return; + } + + case 0x10: /* PSG */ + case 0x14: + { + if (address & 1) + { + SN76489_Write(m68k.cycles, data); + return; + } + m68k_unused_8_w(address, data); + return; + } + + case 0x18: /* Unused */ + { + m68k_unused_8_w(address, data); + return; + } + + case 0x1C: /* TEST register */ + { + vdp_test_w(data << 8 | data); + return; + } + + default: /* Invalid address */ + { + m68k_lockup_w_8(address, data); + return; + } + } +} + +void vdp_write_word(unsigned int address, unsigned int data) +{ + switch (address & 0xFC) + { + case 0x00: /* DATA */ + { + vdp_68k_data_w(data); + return; + } + + case 0x04: /* CTRL */ + { + vdp_68k_ctrl_w(data); + return; + } + + case 0x10: /* PSG */ + case 0x14: + { + SN76489_Write(m68k.cycles, data & 0xFF); + return; + } + + case 0x18: /* Unused */ + { + m68k_unused_16_w(address, data); + return; + } + + case 0x1C: /* Test register */ + { + vdp_test_w(data); + return; + } + + default: /* Invalid address */ + { + m68k_lockup_w_16 (address, data); + return; + } + } +} + + +/*--------------------------------------------------------------------------*/ +/* PICO (incomplete) */ +/*--------------------------------------------------------------------------*/ + +unsigned int pico_read_byte(unsigned int address) +{ + switch (address & 0xFF) + { + case 0x01: /* VERSION register */ + { + return (region_code >> 1); + } + + case 0x03: /* IO register */ + { + return ~input.pad[0]; + } + + case 0x05: /* PEN X coordinate (MSB) */ + { + return (input.analog[0][0] >> 8); + } + + case 0x07: /* PEN X coordinate (LSB) */ + { + return (input.analog[0][0] & 0xFF); + } + + case 0x09: /* PEN Y coordinate (MSB) */ + { + return (input.analog[0][1] >> 8); + } + + case 0x0B: /* PEN Y coordinate (LSB) */ + { + return (input.analog[0][1] & 0xFF); + } + + case 0x0D: /* PAGE register */ + { + return (1 << pico_current) - 1; + } + + case 0x10: /* ADPCM data registers (TODO) */ + case 0x11: + { + return 0xff; + } + + case 0x12: /* ADPCM control registers (TODO) */ + { + return 0x80; + } + + default: + { + return m68k_read_bus_8(address); + } + } +} + +unsigned int pico_read_word(unsigned int address) +{ + return (pico_read_byte(address | 1) | (pico_read_byte(address) << 8)); +} diff --git a/waterbox/gpgx/lscript b/waterbox/gpgx/lscript deleted file mode 100644 index 88a2a40c1f..0000000000 --- a/waterbox/gpgx/lscript +++ /dev/null @@ -1,228 +0,0 @@ -/* dumped with -Wl,-verbose; base address moved -/* Script for -z combreloc: combine and sort reloc sections */ -/* Copyright (C) 2014 Free Software Foundation, Inc. - Copying and distribution of this script, with or without modification, - are permitted in any medium without royalty provided the copyright - notice and this notice are preserved. */ -OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", - "elf64-x86-64") -OUTPUT_ARCH(i386:x86-64) -ENTRY(_start) -SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64"); SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib/x86_64-linux-gnu"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x0000036f00000000)); . = SEGMENT_START("text-segment", 0x0000036f00000000) + SIZEOF_HEADERS; - .interp : { *(.interp) } - .note.gnu.build-id : { *(.note.gnu.build-id) } - .hash : { *(.hash) } - .gnu.hash : { *(.gnu.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - .rela.dyn : - { - *(.rela.init) - *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) - *(.rela.fini) - *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) - *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) - *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) - *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) - *(.rela.ctors) - *(.rela.dtors) - *(.rela.got) - *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) - *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*) - *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*) - *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*) - *(.rela.ifunc) - } - .rela.plt : - { - *(.rela.plt) - PROVIDE_HIDDEN (__rela_iplt_start = .); - *(.rela.iplt) - PROVIDE_HIDDEN (__rela_iplt_end = .); - } - .init : - { - KEEP (*(SORT_NONE(.init))) - } - .plt : { *(.plt) *(.iplt) } - .plt.bnd : { *(.plt.bnd) } - .text : - { - *(.text.unlikely .text.*_unlikely .text.unlikely.*) - *(.text.exit .text.exit.*) - *(.text.startup .text.startup.*) - *(.text.hot .text.hot.*) - *(.text .stub .text.* .gnu.linkonce.t.*) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - } - .fini : - { - KEEP (*(SORT_NONE(.fini))) - } - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table - .gcc_except_table.*) } - /* These sections are generated by the Sun/Oracle C++ compiler. */ - .exception_ranges : ONLY_IF_RO { *(.exception_ranges - .exception_ranges*) } - /* Adjust the address for the data segment. We want to adjust up to - the same address within the page on the next page up. */ - . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); - /* Exception handling */ - .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } - .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } - /* Thread Local Storage sections */ - .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } - .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) - KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) - PROVIDE_HIDDEN (__init_array_end = .); - } - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) - KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) - PROVIDE_HIDDEN (__fini_array_end = .); - } - .ctors : - { - /* gcc uses crtbegin.o to find the start of - the constructors, so we make sure it is - first. Because this is a wildcard, it - doesn't matter if the user does not - actually link against crtbegin.o; the - linker won't look for a file to match a - wildcard. The wildcard also means that it - doesn't matter which directory crtbegin.o - is in. */ - KEEP (*crtbegin.o(.ctors)) - KEEP (*crtbegin?.o(.ctors)) - /* We don't want to include the .ctor section from - the crtend.o file until after the sorted ctors. - The .ctor section from the crtend file contains the - end of ctors marker and it must be last */ - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - } - .dtors : - { - KEEP (*crtbegin.o(.dtors)) - KEEP (*crtbegin?.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } - .jcr : { KEEP (*(.jcr)) } - .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } - .dynamic : { *(.dynamic) } - .got : { *(.got) *(.igot) } - . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .); - .got.plt : { *(.got.plt) *(.igot.plt) } - .data : - { - *(.data .data.* .gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - } - .data1 : { *(.data1) } - _edata = .; PROVIDE (edata = .); - . = .; - __bss_start = .; - .bss : - { - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - *(COMMON) - /* Align here to ensure that the .bss section occupies space up to - _end. Align after .bss to ensure correct alignment even if the - .bss section disappears because there are no input sections. - FIXME: Why do we need it? When there is no .bss section, we don't - pad the .data section. */ - . = ALIGN(. != 0 ? 64 / 8 : 1); - } - .lbss : - { - *(.dynlbss) - *(.lbss .lbss.* .gnu.linkonce.lb.*) - *(LARGE_COMMON) - } - . = ALIGN(64 / 8); - . = SEGMENT_START("ldata-segment", .); - .lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : - { - *(.lrodata .lrodata.* .gnu.linkonce.lr.*) - } - .ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : - { - *(.ldata .ldata.* .gnu.linkonce.l.*) - . = ALIGN(. != 0 ? 64 / 8 : 1); - } - . = ALIGN(64 / 8); - _end = .; PROVIDE (end = .); - . = DATA_SEGMENT_END (.); - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* DWARF 3 */ - .debug_pubtypes 0 : { *(.debug_pubtypes) } - .debug_ranges 0 : { *(.debug_ranges) } - /* DWARF Extension. */ - .debug_macro 0 : { *(.debug_macro) } - .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } - /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } -} diff --git a/waterbox/libc/COPYING.CC0 b/waterbox/libc/COPYING.CC0 deleted file mode 100644 index 1625c17936..0000000000 --- a/waterbox/libc/COPYING.CC0 +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. \ No newline at end of file diff --git a/waterbox/libc/Makefile b/waterbox/libc/Makefile deleted file mode 100644 index 9513cf7568..0000000000 --- a/waterbox/libc/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -CC:=gcc -TARGET:=emulibc.a - -CFLAGS:=-Wall -Wextra -pedantic -Wno-unused-parameter -Wshadow \ - -Wpointer-arith -Wwrite-strings -Wmissing-declarations \ - -Wno-long-long -Wuninitialized -Wno-deprecated-declarations \ - -Wredundant-decls -Winline -Wcast-align -Wno-format \ - -Wnested-externs -Wstrict-prototypes -Wmissing-prototypes \ - -Wno-unused-but-set-variable -Wno-parentheses \ - -Iinternals -Iincludes -Icompileincludes \ - -ffreestanding -std=c11 -D_PDCLIB_BUILD -nostdinc -nostdlib \ - -mcmodel=large -O2 - -ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) -SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.c' -o -name '*.s') -OBJ_DIR:=$(ROOT_DIR)/obj - -_OBJS:=$(SRCS:.c=.o) -_OBJS:=$(_OBJS:.s=.o) -OBJS:=$(patsubst $(ROOT_DIR)%,$(OBJ_DIR)%,$(_OBJS)) - -$(OBJ_DIR)/%.o: %.c - @mkdir -p $(@D) - @$(CC) -c -o $@ $< $(CFLAGS) - -$(OBJ_DIR)/%.o: %.s - @mkdir -p $(@D) - @$(CC) -c -o $@ $< $(CFLAGS) - -$(TARGET): $(OBJS) - @ar rcs $@ $^ - -all: $(TARGET) - -.PHONY: clean all - -clean: - rm -rf $(OBJ_DIR) - rm -f $(TARGET) - -print-% : ; @echo $* = $($*) diff --git a/waterbox/libc/Notes.txt b/waterbox/libc/Notes.txt deleted file mode 100644 index ceb68b9d91..0000000000 --- a/waterbox/libc/Notes.txt +++ /dev/null @@ -1,110 +0,0 @@ -Credits -======= - -The vast majority of PDCLib is original work by me. I felt it was the only way -to ensure that the code was indeed free of third-party rights, and thus free to -be released into the Public Domain. - -Another issue was that of coding style, quality and stability of the code, and -the urge to really understand every miniscule part of the code as to be able to -maintain it well once v1.0 has been released. - -That is not to say there are no credits to be given. To the contrary: - -Paul Edwards (author of the PDPCLIB), for inspirational code fragments, thanks. - -P.J. Plauger (author of "The Standard C Library"), for a book without which I -would not have been able to create PDCLib at this quality, thanks. - -Paul Bourke (author of mathlib), for allowing me access to a complete math -library under public domain terms so I could use it as a reference, thanks. - -Peter ("Candy") Bindels (netizen of osdev.org), who located a copy of Cody -& Waite's "Software Manual for the Elementary Functions" for me and saved me -serious cash in the process, thanks. - -Michael Moody, who contributed the generic implementation for to -the Public Domain which can now be found in <_PDCLIB_config.h>, thanks. - -Rod Pemberton, for pointing out several flaws in early versions of PDCLib and -giving other valuable hints, thanks. - -Brian Damgaard, for a very friendly exchange over the fine details of the -Quicksort algorithm and its implementation in PDCLib, thanks. - -Rink Springer, for very precise bug reports including patches, and a heads-up -on the capabilities of PDCLib when I most needed it, thanks. - -Everyone involved in the first, "public" attempt at PDCLib, for bearing with me -when I restarted from scratch, thanks. - -Everyone bearing with me during the "stdio block", a period of many years in -which PDCLib received not a single update because I was stuck and could not -find the time and energy to work it out. - -Lennart Frid�n and Sammy Nordstr�m, who have been great pals even after I sunk -some other project that had eaten countless hours of work between the three of -us, thanks. - -My wife, daughter, and son for sharing husband and daddy with this strange -machine, thanks. - - -Style -===== - -I followed a set of guidelines in creating PDCLib. If you find some piece that -does not adhere to them, that's a bug worth reporting. I mean it. I am a bit -obsessive when it comes to coding style. ;-) - -- All the stuff that is not part of the standard specification is "hidden" in - the _PDCLIB_* namespace - functions, variables, macros, files, directories. - This is to make it easier to distinguish between what the standard dictates - and what I added to make PDCLib work. - -- Any internal includes (i.e. those not specified by the standard) have their - header guards defined in the *including* file, for a tiny bit of compile-time - performance. - -- I always try to minimize the use of local variables. Wherever possible I used - parameters passed by-value directly, and deferred declaration of locals to the - innermost block of statements, in hopes that it might reduce memory footprint - when the library is compiled with a compiler that is not that great at - optimization. - -- Every function, every static data item that could possibly be shared, got its - own implementation file. This means the library itself is probably larger than - strictly necessary, and might take a couple of clock cycles longer to link, - but it reduces size of object files and executables. - -- Where possible, I tried to share functionality between similar functions (as - can be seen in the atoi() and strtol() function families). This means one or - two additional function calls, but again reduces memory footprint and eases - maintenance of the library. - -- Function arguments are named exactly as in the standard document. - -- The standard is taken quite literally in places. For example, the default - implementations of memcpy() really copies char-wise. This runs contrary to - earlier claims of performance, but is consistent with the *letter* of the - standard, and you will probably use your compiler builtins (through a platform - overlay) anyhow. - -- Every file has an Id tag, so that it is on file for *every* code file. - -- PDCLib code has no bias towards POSIX; indeed the absence of POSIX tidbits is - one of its hallmarks. However, PDCLib also has no bias *against* POSIX, and - when one platform abstraction is as good as another, I chose the POSIX one for - sheer familiarity. (This is mainly referring to naming and parameter lists of - OS "glue" functions.) - -- Identifiers are tersely named, but not cryptically abbreviated, and should be - intuitive enough to allow easy understanding of PDCLib inner workings. - -- I disagree with the notion that good code needs no comments. Code tells you - *how*, but not the *why*, and you have to figure out the *what* yourself. So - I added comments to every nontrivial piece of code explaining my motives and - hopefully keeping overly ambitious editors from repeating my mistakes. The - header files especially should be self-documenting to the point of being a - suitable replacement for any library reference book you might be using. - diff --git a/waterbox/libc/UNICODE DATA LICENSE.txt b/waterbox/libc/UNICODE DATA LICENSE.txt deleted file mode 100644 index c33d814a62..0000000000 --- a/waterbox/libc/UNICODE DATA LICENSE.txt +++ /dev/null @@ -1,46 +0,0 @@ -Unicode Data Files include all data files under the directories -http://www.unicode.org/Public/, http://www.unicode.org/reports/, and -http://www.unicode.org/cldr/data/. Unicode Data Files do not include PDF online -code charts under the directory http://www.unicode.org/Public/. Software -includes any source code published in the Unicode Standard or under the -directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, and -http://www.unicode.org/cldr/data/. - -NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, -INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"), -AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND -BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO -NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWAR. - -COPYRIGHT AND PERMISSION NOTICE - -Copyright © 1991-2013 Unicode, Inc. All rights reserved. Distributed under the -Terms of Use in http://www.unicode.org/copyright.html. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -the Unicode data files and any associated documentation (the "Data Files") or -Unicode software and any associated documentation (the "Software") to deal in -the Data Files or Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, and/or sell copies of -the Data Files or Software, and to permit persons to whom the Data Files or -Software are furnished to do so, provided that (a) the above copyright notice(s) -and this permission notice appear with all copies of the Data Files or Software, -(b) both the above copyright notice(s) and this permission notice appear in -associated documentation, and (c) there is clear notice in each modified Data -File or in the Software as well as in the documentation associated with the Data -File(s) or Software that the data or software has been modified. - -THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD -PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS -NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL -DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING -OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR -SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall not be -used in advertising or otherwise to promote the sale, use or other dealings in -these Data Files or Software without prior written authorization of the -copyright holder. diff --git a/waterbox/libc/compileincludes/libm.h b/waterbox/libc/compileincludes/libm.h deleted file mode 100644 index 1f3ee7b204..0000000000 --- a/waterbox/libc/compileincludes/libm.h +++ /dev/null @@ -1,188 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/math_private.h */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#ifndef _LIBM_H -#define _LIBM_H - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include -#include -#include -#include -#include - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN -union ldshape { - long double f; - struct { - uint64_t m; - uint16_t se; - } i; -}; -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN -union ldshape { - long double f; - struct { - uint64_t lo; - uint32_t mid; - uint16_t top; - uint16_t se; - } i; - struct { - uint64_t lo; - uint64_t hi; - } i2; -}; -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN -union ldshape { - long double f; - struct { - uint16_t se; - uint16_t top; - uint32_t mid; - uint64_t lo; - } i; - struct { - uint64_t hi; - uint64_t lo; - } i2; -}; -#else -#error Unsupported long double representation -#endif - -#define FORCE_EVAL(x) do { \ - if (sizeof(x) == sizeof(float)) { \ - volatile float __x; \ - __x = (x); \ - } else if (sizeof(x) == sizeof(double)) { \ - volatile double __x; \ - __x = (x); \ - } else { \ - volatile long double __x; \ - __x = (x); \ - } \ -} while(0) - -/* Get two 32 bit ints from a double. */ -#define EXTRACT_WORDS(hi,lo,d) \ -do { \ - union {double f; uint64_t i;} __u; \ - __u.f = (d); \ - (hi) = __u.i >> 32; \ - (lo) = (uint32_t)__u.i; \ -} while (0) - -/* Get the more significant 32 bit int from a double. */ -#define GET_HIGH_WORD(hi,d) \ -do { \ - union {double f; uint64_t i;} __u; \ - __u.f = (d); \ - (hi) = __u.i >> 32; \ -} while (0) - -/* Get the less significant 32 bit int from a double. */ -#define GET_LOW_WORD(lo,d) \ -do { \ - union {double f; uint64_t i;} __u; \ - __u.f = (d); \ - (lo) = (uint32_t)__u.i; \ -} while (0) - -/* Set a double from two 32 bit ints. */ -#define INSERT_WORDS(d,hi,lo) \ -do { \ - union {double f; uint64_t i;} __u; \ - __u.i = ((uint64_t)(hi)<<32) | (uint32_t)(lo); \ - (d) = __u.f; \ -} while (0) - -/* Set the more significant 32 bits of a double from an int. */ -#define SET_HIGH_WORD(d,hi) \ -do { \ - union {double f; uint64_t i;} __u; \ - __u.f = (d); \ - __u.i &= 0xffffffff; \ - __u.i |= (uint64_t)(hi) << 32; \ - (d) = __u.f; \ -} while (0) - -/* Set the less significant 32 bits of a double from an int. */ -#define SET_LOW_WORD(d,lo) \ -do { \ - union {double f; uint64_t i;} __u; \ - __u.f = (d); \ - __u.i &= 0xffffffff00000000ull; \ - __u.i |= (uint32_t)(lo); \ - (d) = __u.f; \ -} while (0) - -/* Get a 32 bit int from a float. */ -#define GET_FLOAT_WORD(w,d) \ -do { \ - union {float f; uint32_t i;} __u; \ - __u.f = (d); \ - (w) = __u.i; \ -} while (0) - -/* Set a float from a 32 bit int. */ -#define SET_FLOAT_WORD(d,w) \ -do { \ - union {float f; uint32_t i;} __u; \ - __u.i = (w); \ - (d) = __u.f; \ -} while (0) - -#undef __CMPLX -#undef CMPLX -#undef CMPLXF -#undef CMPLXL - -#define __CMPLX(x, y, t) \ - ((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z) - -#define CMPLX(x, y) __CMPLX(x, y, double) -#define CMPLXF(x, y) __CMPLX(x, y, float) -#define CMPLXL(x, y) __CMPLX(x, y, long double) - -/* fdlibm kernel functions */ - -int __rem_pio2_large(double*,double*,int,int,int); - -int __rem_pio2(double,double*); -double __sin(double,double,int); -double __cos(double,double); -double __tan(double,double,int); -double __expo2(double); -double complex __ldexp_cexp(double complex,int); - -int __rem_pio2f(float,double*); -float __sindf(double); -float __cosdf(double); -float __tandf(double,int); -float __expo2f(float); -float complex __ldexp_cexpf(float complex,int); - -int __rem_pio2l(long double, long double *); -long double __sinl(long double, long double, int); -long double __cosl(long double, long double); -long double __tanl(long double, long double, int); - -/* polynomial evaluation */ -long double __polevll(long double, const long double *, int); -long double __p1evll(long double, const long double *, int); - -#endif diff --git a/waterbox/libc/compileincludes/readme.txt b/waterbox/libc/compileincludes/readme.txt deleted file mode 100644 index ccf1e5fe26..0000000000 --- a/waterbox/libc/compileincludes/readme.txt +++ /dev/null @@ -1 +0,0 @@ -includes for compiling the library only \ No newline at end of file diff --git a/waterbox/libc/functions/_PDCLIB/Readme.txt b/waterbox/libc/functions/_PDCLIB/Readme.txt deleted file mode 100644 index 46796879c0..0000000000 --- a/waterbox/libc/functions/_PDCLIB/Readme.txt +++ /dev/null @@ -1,11 +0,0 @@ -This directory holds various "internals" of PDCLib: - -- definitions of helper functions not specified by the standard (hidden in the - _PDCLIB_* namespace); - -- definitions of data objects, both internal (like digits.c) and specified by - the standard (errno.c); - -- test drivers for functionality that does not have its own implementation - file to put the test driver in. - diff --git a/waterbox/libc/functions/_PDCLIB/_PDCLIB_ascii.c b/waterbox/libc/functions/_PDCLIB/_PDCLIB_ascii.c deleted file mode 100644 index ac5a593d96..0000000000 --- a/waterbox/libc/functions/_PDCLIB/_PDCLIB_ascii.c +++ /dev/null @@ -1,139 +0,0 @@ -/* ASCII codec - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include -#include "_PDCLIB_encoding.h" - -static bool ascii_mbsinit( const mbstate_t *ps ) -{ return 1; } - -static bool asciitoc32( - char32_t *restrict *restrict p_outbuf, - size_t *restrict p_outsz, - const char *restrict *restrict p_inbuf, - size_t *restrict p_insz, - mbstate_t *restrict p_ps -) -{ - while(*p_outsz && *p_insz) { - unsigned char c = **p_inbuf; - if(c > 127) - return false; - - if(p_outbuf) { - **p_outbuf = c; - (*p_outbuf)++; - } - - (*p_inbuf)++; - (*p_insz)--; - (*p_outsz)--; - } - return true; -} - -static bool c32toascii( - char *restrict *restrict p_outbuf, - size_t *restrict p_outsz, - const char32_t *restrict *restrict p_inbuf, - size_t *restrict p_insz, - mbstate_t *restrict p_ps -) -{ - while(*p_outsz && *p_insz) { - char32_t c = **p_inbuf; - if(c > 127) - return false; - - if(p_outbuf) { - **p_outbuf = c; - (*p_outbuf)++; - } - - (*p_inbuf)++; - (*p_insz)--; - (*p_outsz)--; - } - return true; -} - -const struct _PDCLIB_charcodec_t _PDCLIB_ascii_codec = { - .__mbsinit = ascii_mbsinit, - .__mbstoc32s = asciitoc32, - .__c32stombs = c32toascii, - .__mb_max = 1, -}; - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ -#ifndef REGTEST - // Valid conversion & back - - char32_t c32out[5]; - - char32_t *c32ptr = &c32out[0]; - size_t c32rem = 5; - char *chrptr = (char*) &abcde[0]; - size_t chrrem = 5; - mbstate_t mbs = { 0 }; - - TESTCASE(asciitoc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == true); - TESTCASE(c32rem == 0); - TESTCASE(chrrem == 0); - TESTCASE(c32ptr == &c32out[5]); - TESTCASE(chrptr == &abcde[5]); - TESTCASE(c32out[0] == 'a' && c32out[1] == 'b' && c32out[2] == 'c' && \ - c32out[3] == 'd' && c32out[4] == 'e'); - - char chrout[5]; - c32ptr = &c32out[0]; - c32rem = 5; - chrptr = &chrout[0]; - chrrem = 5; - - - TESTCASE(c32toascii(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == true); - TESTCASE(c32rem == 0); - TESTCASE(chrrem == 0); - TESTCASE(c32ptr == &c32out[5]); - TESTCASE(chrptr == &chrout[5]); - TESTCASE(memcmp(chrout, abcde, 5) == 0); - - // Invalid conversions - char badascii = '\xC0'; - c32ptr = &c32out[0]; - c32rem = 5; - chrptr = &badascii; - chrrem = 1; - TESTCASE(asciitoc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false); - TESTCASE(c32ptr == &c32out[0]); - TESTCASE(c32rem == 5); - TESTCASE(chrptr == &badascii); - TESTCASE(chrrem == 1); - - char32_t baduni = 0xC0; - c32ptr = &baduni; - c32rem = 1; - chrptr = &chrout[0]; - chrrem = 5; - TESTCASE(c32toascii(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == false); - TESTCASE(c32ptr == &baduni); - TESTCASE(c32rem == 1); - TESTCASE(chrptr == &chrout[0]); - TESTCASE(chrrem == 5); -#endif - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/_PDCLIB/_PDCLIB_atomax.c b/waterbox/libc/functions/_PDCLIB/_PDCLIB_atomax.c deleted file mode 100644 index 053f776b0f..0000000000 --- a/waterbox/libc/functions/_PDCLIB/_PDCLIB_atomax.c +++ /dev/null @@ -1,44 +0,0 @@ -/* _PDCLIB_atomax( const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef REGTEST -#include "_PDCLIB_int.h" -#include -#include - -_PDCLIB_intmax_t _PDCLIB_atomax( const char * s ) -{ - _PDCLIB_intmax_t rc = 0; - char sign = '+'; - const char * x; - /* TODO: In other than "C" locale, additional patterns may be defined */ - while ( isspace( *s ) ) ++s; - if ( *s == '+' ) ++s; - else if ( *s == '-' ) sign = *(s++); - /* TODO: Earlier version was missing tolower() but was not caught by tests */ - while ( ( x = memchr( _PDCLIB_digits, tolower(*(s++)), 10 ) ) != NULL ) - { - rc = rc * 10 + ( x - _PDCLIB_digits ); - } - return ( sign == '+' ) ? rc : -rc; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ -#ifndef REGTEST - /* basic functionality */ - TESTCASE( _PDCLIB_atomax( "123" ) == 123 ); - /* testing skipping of leading whitespace and trailing garbage */ - TESTCASE( _PDCLIB_atomax( " \n\v\t\f123xyz" ) == 123 ); -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/_PDCLIB/_PDCLIB_closeall.c b/waterbox/libc/functions/_PDCLIB/_PDCLIB_closeall.c deleted file mode 100644 index 5f62ca183a..0000000000 --- a/waterbox/libc/functions/_PDCLIB/_PDCLIB_closeall.c +++ /dev/null @@ -1,36 +0,0 @@ -/* _PDCLIB_closeall( void ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" -extern _PDCLIB_file_t * _PDCLIB_filelist; - -void _PDCLIB_closeall( void ) -{ - _PDCLIB_file_t * stream = _PDCLIB_filelist; - _PDCLIB_file_t * next; - while ( stream != NULL ) - { - next = stream->next; - fclose( stream ); - stream = next; - } -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* No testdriver */ - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/_PDCLIB/_PDCLIB_digits.c b/waterbox/libc/functions/_PDCLIB/_PDCLIB_digits.c deleted file mode 100644 index 1e3d6ab163..0000000000 --- a/waterbox/libc/functions/_PDCLIB/_PDCLIB_digits.c +++ /dev/null @@ -1,30 +0,0 @@ -/* _PDCLIB_digits - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef REGTEST -#include "_PDCLIB_int.h" -#endif - -char _PDCLIB_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; - -/* For _PDCLIB/print.c only; obsolete with ctype.h */ -char _PDCLIB_Xdigits[] = "0123456789ABCDEF"; - -#ifdef TEST -#include "_PDCLIB_test.h" - -#include - -int main( void ) -{ -#ifndef REGTEST - TESTCASE( strcmp( _PDCLIB_digits, "0123456789abcdefghijklmnopqrstuvwxyz" ) == 0 ); - TESTCASE( strcmp( _PDCLIB_Xdigits, "0123456789ABCDEF" ) == 0 ); -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/_PDCLIB/_PDCLIB_fileops.c b/waterbox/libc/functions/_PDCLIB/_PDCLIB_fileops.c deleted file mode 100644 index bfe3d85b63..0000000000 --- a/waterbox/libc/functions/_PDCLIB/_PDCLIB_fileops.c +++ /dev/null @@ -1,56 +0,0 @@ -/* _PDCLIB_fileops - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef REGTEST -#include -#include -#include "_PDCLIB_glue.h" -#include - -static bool readf( _PDCLIB_fd_t self, void * buf, size_t length, - size_t * numBytesRead ) -{ - errno = ENOTSUP; - return false; -} - -static bool writef( _PDCLIB_fd_t self, const void * buf, size_t length, - size_t * numBytesWritten ) -{ - errno = ENOTSUP; - return false; -} -static bool seekf( _PDCLIB_fd_t self, int_fast64_t offset, int whence, - int_fast64_t* newPos ) -{ - errno = ENOTSUP; - return false; -} - -static void closef( _PDCLIB_fd_t self ) -{ - errno = ENOTSUP; -} - -const _PDCLIB_fileops_t _PDCLIB_fileops = { - .read = readf, - .write = writef, - .seek = seekf, - .close = closef, -}; - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - // Tested by stdio test cases - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/_PDCLIB/_PDCLIB_initclocale.c b/waterbox/libc/functions/_PDCLIB/_PDCLIB_initclocale.c deleted file mode 100644 index d7cf35063f..0000000000 --- a/waterbox/libc/functions/_PDCLIB/_PDCLIB_initclocale.c +++ /dev/null @@ -1,29 +0,0 @@ -/* _PDCLIB_initclocale( locale_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef REGTEST -#include "_PDCLIB_clocale.h" -#include "_PDCLIB_locale.h" - -void _PDCLIB_initclocale( locale_t l ) -{ - // TODO: There will be more added here... - - l->_WCType = _PDCLIB_wcinfo; - l->_WCTypeSize = _PDCLIB_wcinfo_size; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main() -{ - return TEST_RESULTS; -} - -#endif \ No newline at end of file diff --git a/waterbox/libc/functions/_PDCLIB/_PDCLIB_latin1.c b/waterbox/libc/functions/_PDCLIB/_PDCLIB_latin1.c deleted file mode 100644 index dba6ae9ce1..0000000000 --- a/waterbox/libc/functions/_PDCLIB/_PDCLIB_latin1.c +++ /dev/null @@ -1,126 +0,0 @@ -/* Latin-1 codec - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include -#include "_PDCLIB_encoding.h" - -static bool latin1_mbsinit( const mbstate_t *ps ) -{ return 1; } - -static bool latin1toc32( - char32_t *restrict *restrict p_outbuf, - size_t *restrict p_outsz, - const char *restrict *restrict p_inbuf, - size_t *restrict p_insz, - mbstate_t *restrict p_ps -) -{ - while(*p_outsz && *p_insz) { - unsigned char c = **p_inbuf; - - if(p_outbuf) { - **p_outbuf = c; - (*p_outbuf)++; - } - - (*p_inbuf)++; - (*p_insz)--; - (*p_outsz)--; - } - return true; -} - -static bool c32tolatin1( - char *restrict *restrict p_outbuf, - size_t *restrict p_outsz, - const char32_t *restrict *restrict p_inbuf, - size_t *restrict p_insz, - mbstate_t *restrict p_ps -) -{ - while(*p_outsz && *p_insz) { - char32_t c = **p_inbuf; - if(c > 255) - return false; - - if(p_outbuf) { - **p_outbuf = c; - (*p_outbuf)++; - } - - (*p_inbuf)++; - (*p_insz)--; - (*p_outsz)--; - } - return true; -} - -const struct _PDCLIB_charcodec_t _PDCLIB_latin1_codec = { - .__mbsinit = latin1_mbsinit, - .__mbstoc32s = latin1toc32, - .__c32stombs = c32tolatin1, - .__mb_max = 1, -}; - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ -#ifndef REGTEST - // Valid conversion & back - - char32_t c32out[5]; - - char32_t *c32ptr = &c32out[0]; - size_t c32rem = 5; - char *chrptr = (char*) &abcde[0]; - size_t chrrem = 5; - mbstate_t mbs = { 0 }; - - TESTCASE(latin1toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == true); - TESTCASE(c32rem == 0); - TESTCASE(chrrem == 0); - TESTCASE(c32ptr == &c32out[5]); - TESTCASE(chrptr == &abcde[5]); - TESTCASE(c32out[0] == 'a' && c32out[1] == 'b' && c32out[2] == 'c' && \ - c32out[3] == 'd' && c32out[4] == 'e'); - - char chrout[5]; - c32ptr = &c32out[0]; - c32rem = 5; - chrptr = &chrout[0]; - chrrem = 5; - - - TESTCASE(c32tolatin1(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == true); - TESTCASE(c32rem == 0); - TESTCASE(chrrem == 0); - TESTCASE(c32ptr == &c32out[5]); - TESTCASE(chrptr == &chrout[5]); - TESTCASE(memcmp(chrout, abcde, 5) == 0); - - // Invalid conversions - char32_t baduni = 0xFFFE; - c32ptr = &baduni; - c32rem = 1; - chrptr = &chrout[0]; - chrrem = 5; - TESTCASE(c32tolatin1(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == false); - TESTCASE(c32ptr == &baduni); - TESTCASE(c32rem == 1); - TESTCASE(chrptr == &chrout[0]); - TESTCASE(chrrem == 5); -#endif - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/_PDCLIB/_PDCLIB_open.c b/waterbox/libc/functions/_PDCLIB/_PDCLIB_open.c deleted file mode 100644 index 117d149c76..0000000000 --- a/waterbox/libc/functions/_PDCLIB/_PDCLIB_open.c +++ /dev/null @@ -1,37 +0,0 @@ -/* _PDCLIB_open( char const * const, int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -/* This is a stub implementation of open. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_glue.h" - -bool _PDCLIB_open( _PDCLIB_fd_t * pFd, const _PDCLIB_fileops_t ** pOps, - char const * const filename, unsigned int mode ) -{ - errno = ENOTSUP; - return false; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -#include -#include - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/_PDCLIB/_PDCLIB_seed.c b/waterbox/libc/functions/_PDCLIB/_PDCLIB_seed.c deleted file mode 100644 index 37c9b47988..0000000000 --- a/waterbox/libc/functions/_PDCLIB/_PDCLIB_seed.c +++ /dev/null @@ -1,18 +0,0 @@ -/* _PDCLIB_seed - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -unsigned long int _PDCLIB_seed = 1; - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* no tests for raw data */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/_PDCLIB/_PDCLIB_strtox_main.c b/waterbox/libc/functions/_PDCLIB/_PDCLIB_strtox_main.c deleted file mode 100644 index cf9ae5e3a8..0000000000 --- a/waterbox/libc/functions/_PDCLIB/_PDCLIB_strtox_main.c +++ /dev/null @@ -1,85 +0,0 @@ -/* _PDCLIB_strtox_main( const char * *, int, _PDCLIB_uintmax_t, _PDCLIB_uintmax_t, int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_int.h" -_PDCLIB_uintmax_t _PDCLIB_strtox_main( const char ** p, unsigned int base, uintmax_t error, uintmax_t limval, int limdigit, char * sign ) -{ - _PDCLIB_uintmax_t rc = 0; - int digit = -1; - const char * x; - while ( ( x = memchr( _PDCLIB_digits, tolower(**p), base ) ) != NULL ) - { - digit = x - _PDCLIB_digits; - if ( ( rc < limval ) || ( ( rc == limval ) && ( digit <= limdigit ) ) ) - { - rc = rc * base + (unsigned)digit; - ++(*p); - } - else - { - errno = ERANGE; - /* TODO: Only if endptr != NULL - but do we really want *another* parameter? */ - /* TODO: Earlier version was missing tolower() here but was not caught by tests */ - while ( memchr( _PDCLIB_digits, tolower(**p), base ) != NULL ) ++(*p); - /* TODO: This is ugly, but keeps caller from negating the error value */ - *sign = '+'; - return error; - } - } - if ( digit == -1 ) - { - *p = NULL; - return 0; - } - return rc; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -int main( void ) -{ -#ifndef REGTEST - const char * p; - char test[] = "123_"; - char fail[] = "xxx"; - char sign = '-'; - /* basic functionality */ - p = test; - errno = 0; - TESTCASE( _PDCLIB_strtox_main( &p, 10u, (uintmax_t)999, (uintmax_t)12, 3, &sign ) == 123 ); - TESTCASE( errno == 0 ); - TESTCASE( p == &test[3] ); - /* proper functioning to smaller base */ - p = test; - TESTCASE( _PDCLIB_strtox_main( &p, 8u, (uintmax_t)999, (uintmax_t)12, 3, &sign ) == 0123 ); - TESTCASE( errno == 0 ); - TESTCASE( p == &test[3] ); - /* overflowing subject sequence must still return proper endptr */ - p = test; - TESTCASE( _PDCLIB_strtox_main( &p, 4u, (uintmax_t)999, (uintmax_t)1, 2, &sign ) == 999 ); - TESTCASE( errno == ERANGE ); - TESTCASE( p == &test[3] ); - TESTCASE( sign == '+' ); - /* testing conversion failure */ - errno = 0; - p = fail; - sign = '-'; - TESTCASE( _PDCLIB_strtox_main( &p, 10u, (uintmax_t)999, (uintmax_t)99, 8, &sign ) == 0 ); - TESTCASE( p == NULL ); -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/_PDCLIB/_PDCLIB_strtox_prelim.c b/waterbox/libc/functions/_PDCLIB/_PDCLIB_strtox_prelim.c deleted file mode 100644 index 789409d2b9..0000000000 --- a/waterbox/libc/functions/_PDCLIB/_PDCLIB_strtox_prelim.c +++ /dev/null @@ -1,90 +0,0 @@ -/* _PDCLIB_strtox_prelim( const char *, char *, int * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include -#ifndef REGTEST -const char * _PDCLIB_strtox_prelim( const char * p, char * sign, int * base ) -{ - /* skipping leading whitespace */ - while ( isspace( *p ) ) ++p; - /* determining / skipping sign */ - if ( *p != '+' && *p != '-' ) *sign = '+'; - else *sign = *(p++); - /* determining base */ - if ( *p == '0' ) - { - ++p; - if ( ( *base == 0 || *base == 16 ) && ( *p == 'x' || *p == 'X' ) ) - { - *base = 16; - ++p; - /* catching a border case here: "0x" followed by a non-digit should - be parsed as the unprefixed zero. - We have to "rewind" the parsing; having the base set to 16 if it - was zero previously does not hurt, as the result is zero anyway. - */ - if ( memchr( _PDCLIB_digits, tolower(*p), *base ) == NULL ) - { - p -= 2; - } - } - else if ( *base == 0 ) - { - *base = 8; - } - else - { - --p; - } - } - else if ( ! *base ) - { - *base = 10; - } - return ( ( *base >= 2 ) && ( *base <= 36 ) ) ? p : NULL; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ -#ifndef REGTEST - int base = 0; - char sign = '\0'; - char test1[] = " 123"; - char test2[] = "\t+0123"; - char test3[] = "\v-0x123"; - TESTCASE( _PDCLIB_strtox_prelim( test1, &sign, &base ) == &test1[2] ); - TESTCASE( sign == '+' ); - TESTCASE( base == 10 ); - base = 0; - sign = '\0'; - TESTCASE( _PDCLIB_strtox_prelim( test2, &sign, &base ) == &test2[3] ); - TESTCASE( sign == '+' ); - TESTCASE( base == 8 ); - base = 0; - sign = '\0'; - TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == &test3[4] ); - TESTCASE( sign == '-' ); - TESTCASE( base == 16 ); - base = 10; - sign = '\0'; - TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == &test3[2] ); - TESTCASE( sign == '-' ); - TESTCASE( base == 10 ); - base = 1; - TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == NULL ); - base = 37; - TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == NULL ); -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/_PDCLIB/_PDCLIB_utf8.c b/waterbox/libc/functions/_PDCLIB/_PDCLIB_utf8.c deleted file mode 100644 index a4c19adb34..0000000000 --- a/waterbox/libc/functions/_PDCLIB/_PDCLIB_utf8.c +++ /dev/null @@ -1,338 +0,0 @@ -/* UTF-8 codec - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef REGTEST -#include -#include -#include -#include -#include "_PDCLIB_encoding.h" - -/* Use of the mbstate: - * - * _StUC[0] is the current decoding state - * _St32[1] is the character accumulated so far - */ - -static bool utf8_mbsinit( const mbstate_t *p_s ) -{ return p_s->_StUC[0] == 0; } - -enum { - DecStart = 0, - - Dec2B2, - - Dec3B2, - Dec3B3, - - Dec4B2, - Dec4B3, - Dec4B4 -}; - -#define state (p_s->_StUC[0]) -#define accum (p_s->_St32[1]) - -#define START_CONVERSION \ - bool result = true; \ - -#define END_CONVERSION \ -end_conversion: \ - return result - -#define FINISH(_r) do { \ - result = (_r); \ - goto end_conversion; \ -} while(0) - -#define OUT32(_c) do { \ - if(p_outbuf) \ - (*((*p_outbuf)++)) = (_c); \ - (*p_outsz)--; \ - _PDCLIB_UNDEFINED(accum); \ - state = DecStart; \ -} while(0) - -#define CHECK_CONTINUATION \ - do { if((c & 0xC0) != 0x80) return false; } while(0) - -static bool utf8toc32( - char32_t *restrict *restrict p_outbuf, - size_t *restrict p_outsz, - const char *restrict *restrict p_inbuf, - size_t *restrict p_insz, - mbstate_t *restrict p_s -) -{ - START_CONVERSION - while(*p_outsz && *p_insz) { - unsigned char c = **p_inbuf; - char32_t c32; - switch(state) { - case DecStart: - // 1 byte - if(c <= 0x7F) { - OUT32(c); - } else if(c <= 0xDF) { - accum = (c & 0x1F) << 6; - state = Dec2B2; - } else if(c <= 0xEF) { - accum = (c & 0x0F) << 12; - state = Dec3B2; - } else if(c <= 0xF4) { - accum = (c & 0x07) << 18; - state = Dec4B2; - } else { - // 5+byte sequence illegal - FINISH(false); - } - break; - - case Dec2B2: - CHECK_CONTINUATION; - - c32 = accum | (c & 0x3F); - - // Overlong sequence (e.g. NUL injection) - if(c32 <= 0x7F) - FINISH(false); - - OUT32(c32); - break; - - case Dec3B2: - CHECK_CONTINUATION; - accum |= (c & 0x3F) << 6; - state = Dec3B3; - break; - - case Dec3B3: - CHECK_CONTINUATION; - - c32 = accum | (c & 0x3F); - - // Overlong - if(c32 <= 0x07FF) - FINISH(false); - - // Surrogate - if(c32 >= 0xD800 && c32 <= 0xDFFF) - FINISH(false); - - OUT32(c32); - break; - - case Dec4B2: - CHECK_CONTINUATION; - accum |= (c & 0x3F) << 12; - state = Dec4B3; - break; - - case Dec4B3: - CHECK_CONTINUATION; - accum |= (c & 0x3F) << 6; - state = Dec4B4; - break; - - case Dec4B4: - CHECK_CONTINUATION; - - c32 = accum | (c & 0x3F); - - // Overlong - if(c32 <= 0xFFFF) FINISH(false); - - // Not in Unicode - if(c32 > 0x10FFFF) FINISH(false); - - OUT32(c32); - break; - - default: - assert(!"Invalid state"); - } - - (*p_inbuf)++; - (*p_insz)--; - } - END_CONVERSION; -} - -enum { - EncStart = 0, - Enc1R, - Enc2R, - Enc3R, -}; - -static bool c32toutf8( - char *restrict *restrict p_outbuf, - size_t *restrict p_outsz, - const char32_t *restrict *restrict p_inbuf, - size_t *restrict p_insz, - mbstate_t *restrict p_s -) -{ - START_CONVERSION - while(*p_outsz) { - unsigned char outc = 0; - switch(state) { - case Enc3R: - outc = 0x80 | ((accum >> 12) & 0x3F); - state = Enc2R; - break; - - case Enc2R: - outc = 0x80 | ((accum >> 6) & 0x3F); - state = Enc1R; - break; - - case Enc1R: - outc = 0x80 | (accum & 0x3F); - state = EncStart; - _PDCLIB_UNDEFINED(accum); - break; - - case EncStart: - if(*p_insz == 0) - FINISH(true); - - accum = **p_inbuf; - (*p_inbuf)++; - (*p_insz)--; - - if(accum <= 0x7F) { - outc = accum; - state = EncStart; - _PDCLIB_UNDEFINED(accum); - } else if(accum <= 0x7FF) { - outc = 0xC0 | (accum >> 6); - state = Enc1R; - } else if(accum <= 0xFFFF) { - outc = 0xE0 | (accum >> 12); - state = Enc2R; - } else if(accum <= 0x10FFFF) { - outc = 0xF0 | (accum >> 18); - state = Enc3R; - } else { - FINISH(false); - } - break; - } - - if(p_outbuf) { - **p_outbuf = outc; - (*p_outbuf)++; - } - (*p_outsz)--; - } - END_CONVERSION; -} - -const struct _PDCLIB_charcodec_t _PDCLIB_utf8_codec = { - .__mbsinit = utf8_mbsinit, - .__mbstoc32s = utf8toc32, - .__c32stombs = c32toutf8, - .__mb_max = 4, -}; - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ -#ifndef REGTEST - // Valid conversion & back - - static const char* input = "abcde" "\xDF\xBF" "\xEF\xBF\xBF" - "\xF4\x8F\xBF\xBF"; - - char32_t c32out[8]; - - char32_t *c32ptr = &c32out[0]; - size_t c32rem = 8; - const char *chrptr = (char*) &input[0]; - size_t chrrem = strlen(input); - mbstate_t mbs = { 0 }; - - TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs)); - TESTCASE(c32rem == 0); - TESTCASE(chrrem == 0); - TESTCASE(c32ptr == &c32out[8]); - TESTCASE(chrptr == &input[strlen(input)]); - TESTCASE(c32out[0] == 'a' && c32out[1] == 'b' && c32out[2] == 'c' && - c32out[3] == 'd' && c32out[4] == 'e' && c32out[5] == 0x7FF && - c32out[6] == 0xFFFF && c32out[7] == 0x10FFFF); - - char chrout[strlen(input)]; - c32ptr = &c32out[0]; - c32rem = 8; - chrptr = &chrout[0]; - chrrem = strlen(input); - TESTCASE(c32toutf8(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs)); - TESTCASE(c32rem == 0); - TESTCASE(chrrem == 0); - TESTCASE(c32ptr == &c32out[8]); - TESTCASE(chrptr == &chrout[strlen(input)]); - TESTCASE(memcmp(chrout, input, strlen(input)) == 0); - - // Multi-part conversion - static const char* mpinput = "\xDF\xBF"; - c32ptr = &c32out[0]; - c32rem = 8; - chrptr = &mpinput[0]; - chrrem = 1; - TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs)); - TESTCASE(c32ptr == &c32out[0]); - TESTCASE(c32rem == 8); - TESTCASE(chrptr == &mpinput[1]); - TESTCASE(chrrem == 0); - chrrem = 1; - TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs)); - TESTCASE(c32ptr == &c32out[1]); - TESTCASE(c32rem == 7); - TESTCASE(chrptr == &mpinput[2]); - TESTCASE(chrrem == 0); - - // Invalid conversions - - // Overlong nuls - const char* nul2 = "\xC0\x80"; - c32ptr = &c32out[0]; - c32rem = 8; - chrptr = &nul2[0]; - chrrem = 2; - TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false); - memset(&mbs, 0, sizeof mbs); - const char* nul3 = "\xE0\x80\x80"; - c32ptr = &c32out[0]; - c32rem = 8; - chrptr = &nul3[0]; - chrrem = 3; - TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false); - memset(&mbs, 0, sizeof mbs); - const char* nul4 = "\xF0\x80\x80\x80"; - c32ptr = &c32out[0]; - c32rem = 8; - chrptr = &nul4[0]; - chrrem = 4; - TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false); - - // Starting on a continuation - const char* cont = "\x80"; - c32ptr = &c32out[0]; - c32rem = 8; - chrptr = &cont[0]; - chrrem = 1; - TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false); -#endif - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/_PDCLIB/assert.c b/waterbox/libc/functions/_PDCLIB/assert.c deleted file mode 100644 index f4d2cbc2a0..0000000000 --- a/waterbox/libc/functions/_PDCLIB/assert.c +++ /dev/null @@ -1,67 +0,0 @@ -/* _PDCLIB_assert( char const * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include - -#ifndef REGTEST - -#include "_PDCLIB_aux.h" - -void _PDCLIB_assert99( char const * const message1, char const * const function, char const * const message2 ) -{ - fputs( message1, stderr ); - fputs( function, stderr ); - fputs( message2, stderr ); - abort(); -} - -void _PDCLIB_assert89( char const * const message ) -{ - fputs( message, stderr ); - abort(); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -static int EXPECTED_ABORT = 0; -static int UNEXPECTED_ABORT = 1; - -static void aborthandler( int sig ) -{ - TESTCASE( ! EXPECTED_ABORT ); - exit( (signed int)TEST_RESULTS ); -} - -#define NDEBUG -#include - -static int disabled_test( void ) -{ - int i = 0; - assert( i == 0 ); /* NDEBUG set, condition met */ - assert( i == 1 ); /* NDEBUG set, condition fails */ - return i; -} - -#undef NDEBUG -#include - -int main( void ) -{ - TESTCASE( signal( SIGABRT, &aborthandler ) != SIG_ERR ); - TESTCASE( disabled_test() == 0 ); - assert( UNEXPECTED_ABORT ); /* NDEBUG not set, condition met */ - assert( EXPECTED_ABORT ); /* NDEBUG not set, condition fails - should abort */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/_PDCLIB/emulibc.c b/waterbox/libc/functions/_PDCLIB/emulibc.c deleted file mode 100644 index 303b01eb6b..0000000000 --- a/waterbox/libc/functions/_PDCLIB/emulibc.c +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include -#include "_PDCLIB_glue.h" -#include -#include - -ECL_EXPORT ECL_ENTRY __attribute__((noreturn)) void (*_ecl_trap)(void); // something very unexpected happened. should not return -ECL_EXPORT ECL_ENTRY void *(*_ecl_sbrk)(size_t n); // sbrk. won't return if the request can't be satisfied -ECL_EXPORT ECL_ENTRY void (*_ecl_debug_puts)(const char *); // low level debug write, doesn't involve STDIO - -ECL_EXPORT ECL_ENTRY void *(*_ecl_sbrk_sealed)(size_t n); // allocate memory; see emulibc.h -ECL_EXPORT ECL_ENTRY void *(*_ecl_sbrk_invisible)(size_t n); // allocate memory; see emulibc.h - -void *alloc_sealed(size_t size) -{ - return _ecl_sbrk_sealed(size); -} - -void *alloc_invisible(size_t size) -{ - return _ecl_sbrk_invisible(size); -} - -void _debug_puts(const char *s) -{ - _ecl_debug_puts(s); -} - -void *_PDCLIB_sbrk(size_t n) -{ - void *ret = _ecl_sbrk(n); - return ret; -} - -void _PDCLIB_Exit( int status ) -{ - _ecl_trap(); -} - diff --git a/waterbox/libc/functions/_PDCLIB/rename.c b/waterbox/libc/functions/_PDCLIB/rename.c deleted file mode 100644 index 219ee5f218..0000000000 --- a/waterbox/libc/functions/_PDCLIB/rename.c +++ /dev/null @@ -1,31 +0,0 @@ -/* _PDCLIB_rename( const char *, const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_glue.h" -#include - -int _PDCLIB_rename( const char * old, const char * new ) -{ - errno = ENOTSUP; - return -1; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -#include - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/_PDCLIB/stdarg.c b/waterbox/libc/functions/_PDCLIB/stdarg.c deleted file mode 100644 index 9e43be6a10..0000000000 --- a/waterbox/libc/functions/_PDCLIB/stdarg.c +++ /dev/null @@ -1,113 +0,0 @@ -/* stdarg - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include -#ifdef TEST - -#include "_PDCLIB_test.h" - -typedef int (*intfunc_t)( void ); - -enum tag_t -{ - TAG_END, - TAG_INT, - TAG_LONG, - TAG_LLONG, - TAG_DBL, - TAG_LDBL, - TAG_INTPTR, - TAG_LDBLPTR, - TAG_FUNCPTR -}; - -static int dummy( void ) -{ - return INT_MAX; -} - -static int test( enum tag_t s, ... ) -{ - enum tag_t tag = s; - va_list ap; - va_start( ap, s ); - for (;;) - { - switch ( tag ) - { - case TAG_INT: - { - TESTCASE( va_arg( ap, int ) == INT_MAX ); - tag = va_arg( ap, enum tag_t ); - break; - } - case TAG_LONG: - { - TESTCASE( va_arg( ap, long ) == LONG_MAX ); - tag = va_arg( ap, enum tag_t ); - break; - } - case TAG_LLONG: - { - TESTCASE( va_arg( ap, long long ) == LLONG_MAX ); - tag = va_arg( ap, enum tag_t ); - break; - } - case TAG_DBL: - { - TESTCASE( va_arg( ap, double ) == DBL_MAX ); - tag = va_arg( ap, enum tag_t ); - break; - } - case TAG_LDBL: - { - TESTCASE( va_arg( ap, long double ) == LDBL_MAX ); - tag = va_arg( ap, enum tag_t ); - break; - } - case TAG_INTPTR: - { - TESTCASE( *( va_arg( ap, int * ) ) == INT_MAX ); - tag = va_arg( ap, enum tag_t ); - break; - } - case TAG_LDBLPTR: - { - TESTCASE( *( va_arg( ap, long double * ) ) == LDBL_MAX ); - tag = va_arg( ap, enum tag_t ); - break; - } - case TAG_FUNCPTR: - { - intfunc_t function; - TESTCASE( ( function = va_arg( ap, intfunc_t ) ) == dummy ); - TESTCASE( function() == INT_MAX ); - tag = va_arg( ap, enum tag_t ); - break; - } - case TAG_END: - { - va_end( ap ); - return 0; - } - } - } -} - -int main( void ) -{ - int x = INT_MAX; - long double d = LDBL_MAX; - test( TAG_END ); - test( TAG_INT, INT_MAX, TAG_END ); - test( TAG_LONG, LONG_MAX, TAG_LLONG, LLONG_MAX, TAG_END ); - test( TAG_DBL, DBL_MAX, TAG_LDBL, LDBL_MAX, TAG_END ); - test( TAG_INTPTR, &x, TAG_LDBLPTR, &d, TAG_FUNCPTR, dummy, TAG_END ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/_PDCLIB/stdinit.c b/waterbox/libc/functions/_PDCLIB/stdinit.c deleted file mode 100644 index b10e99a26c..0000000000 --- a/waterbox/libc/functions/_PDCLIB/stdinit.c +++ /dev/null @@ -1,522 +0,0 @@ -/* _PDCLIB_stdinit - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -/* This is an example initialization of stdin, stdout and stderr to the integer - file descriptors 0, 1, and 2, respectively. This applies for a great variety - of operating systems, including POSIX compliant ones. -*/ - -#include -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" -#include "_PDCLIB_locale.h" -#include "_PDCLIB_encoding.h" - -extern const _PDCLIB_fileops_t _PDCLIB_fileops; - -/* In a POSIX system, stdin / stdout / stderr are equivalent to the (int) file - descriptors 0, 1, and 2 respectively. -*/ -/* TODO: This is proof-of-concept, requires finetuning. */ -static char _PDCLIB_sin_buffer[BUFSIZ]; -static char _PDCLIB_sout_buffer[BUFSIZ]; -static char _PDCLIB_serr_buffer[BUFSIZ]; - -static unsigned char _PDCLIB_sin_ungetbuf[_PDCLIB_UNGETCBUFSIZE]; -static unsigned char _PDCLIB_sout_ungetbuf[_PDCLIB_UNGETCBUFSIZE]; -static unsigned char _PDCLIB_serr_ungetbuf[_PDCLIB_UNGETCBUFSIZE]; - - -static FILE _PDCLIB_serr = { - .ops = &_PDCLIB_fileops, - .buffer = _PDCLIB_serr_buffer, - .bufsize = BUFSIZ, - .bufidx = 0, - .bufend = 0, - .ungetidx = 0, - .ungetbuf = _PDCLIB_serr_ungetbuf, - .status = _IONBF | _PDCLIB_FWRITE | _PDCLIB_STATIC, - .filename = NULL, - .next = NULL, -}; -static FILE _PDCLIB_sout = { - .ops = &_PDCLIB_fileops, - .buffer = _PDCLIB_sout_buffer, - .bufsize = BUFSIZ, - .bufidx = 0, - .bufend = 0, - .ungetidx = 0, - .ungetbuf = _PDCLIB_sout_ungetbuf, - .status = _IOLBF | _PDCLIB_FWRITE | _PDCLIB_STATIC, - .filename = NULL, - .next = &_PDCLIB_serr -}; -static FILE _PDCLIB_sin = { - .ops = &_PDCLIB_fileops, - .buffer = _PDCLIB_sin_buffer, - .bufsize = BUFSIZ, - .bufidx = 0, - .bufend = 0, - .ungetidx = 0, - .ungetbuf = _PDCLIB_sin_ungetbuf, - .status = _IOLBF | _PDCLIB_FREAD | _PDCLIB_STATIC, - .filename = NULL, - .next = &_PDCLIB_sout -}; - -FILE *stdin = &_PDCLIB_sin; -FILE *stdout = &_PDCLIB_sout; -FILE *stderr = &_PDCLIB_serr; - -FILE *_PDCLIB_filelist = &_PDCLIB_sin; - -/* "C" locale - defaulting to ASCII-7. - 1 kByte (+ 4 byte) of data. - Each line: flags, lowercase, uppercase, collation. -*/ -static const _PDCLIB_ctype_t global_ctype[] = { - { /* EOF */ 0, 0, 0, 0 }, - { /* NUL */ _PDCLIB_CTYPE_CNTRL, 0x00, 0x00, 0x00 }, - { /* SOH */ _PDCLIB_CTYPE_CNTRL, 0x01, 0x01, 0x01 }, - { /* STX */ _PDCLIB_CTYPE_CNTRL, 0x02, 0x02, 0x02 }, - { /* ETX */ _PDCLIB_CTYPE_CNTRL, 0x03, 0x03, 0x03 }, - { /* EOT */ _PDCLIB_CTYPE_CNTRL, 0x04, 0x04, 0x04 }, - { /* ENQ */ _PDCLIB_CTYPE_CNTRL, 0x05, 0x05, 0x05 }, - { /* ACK */ _PDCLIB_CTYPE_CNTRL, 0x06, 0x06, 0x06 }, - { /* BEL */ _PDCLIB_CTYPE_CNTRL, 0x07, 0x07, 0x07 }, - { /* BS */ _PDCLIB_CTYPE_CNTRL, 0x08, 0x08, 0x08 }, - { /* HT */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_BLANK | _PDCLIB_CTYPE_SPACE, 0x09, 0x09, 0x09 }, - { /* LF */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0A, 0x0A, 0x0A }, - { /* VT */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0B, 0x0B, 0x0B }, - { /* FF */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0C, 0x0C, 0x0C }, - { /* CR */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0D, 0x0D, 0x0D }, - { /* SO */ _PDCLIB_CTYPE_CNTRL, 0x0E, 0x0E, 0x0E }, - { /* SI */ _PDCLIB_CTYPE_CNTRL, 0x0F, 0x0F, 0x0F }, - { /* DLE */ _PDCLIB_CTYPE_CNTRL, 0x10, 0x10, 0x10 }, - { /* DC1 */ _PDCLIB_CTYPE_CNTRL, 0x11, 0x11, 0x11 }, - { /* DC2 */ _PDCLIB_CTYPE_CNTRL, 0x12, 0x12, 0x12 }, - { /* DC3 */ _PDCLIB_CTYPE_CNTRL, 0x13, 0x13, 0x13 }, - { /* DC4 */ _PDCLIB_CTYPE_CNTRL, 0x14, 0x14, 0x14 }, - { /* NAK */ _PDCLIB_CTYPE_CNTRL, 0x15, 0x15, 0x15 }, - { /* SYN */ _PDCLIB_CTYPE_CNTRL, 0x16, 0x16, 0x16 }, - { /* ETB */ _PDCLIB_CTYPE_CNTRL, 0x17, 0x17, 0x17 }, - { /* CAN */ _PDCLIB_CTYPE_CNTRL, 0x18, 0x18, 0x18 }, - { /* EM */ _PDCLIB_CTYPE_CNTRL, 0x19, 0x19, 0x19 }, - { /* SUB */ _PDCLIB_CTYPE_CNTRL, 0x1A, 0x1A, 0x1A }, - { /* ESC */ _PDCLIB_CTYPE_CNTRL, 0x1B, 0x1B, 0x1B }, - { /* FS */ _PDCLIB_CTYPE_CNTRL, 0x1C, 0x1C, 0x1C }, - { /* GS */ _PDCLIB_CTYPE_CNTRL, 0x1D, 0x1D, 0x1D }, - { /* RS */ _PDCLIB_CTYPE_CNTRL, 0x1E, 0x1E, 0x1E }, - { /* US */ _PDCLIB_CTYPE_CNTRL, 0x1F, 0x1F, 0x1F }, - { /* SP */ _PDCLIB_CTYPE_BLANK | _PDCLIB_CTYPE_SPACE, 0x20, 0x20, 0x20 }, - { /* '!' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x21, 0x21, 0x21 }, - { /* '"' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x22, 0x22, 0x22 }, - { /* '#' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x23, 0x23, 0x23 }, - { /* '$' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x24, 0x24, 0x24 }, - { /* '%' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x25, 0x25, 0x25 }, - { /* '&' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x26, 0x26, 0x26 }, - { /* ''' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x27, 0x27, 0x27 }, - { /* '(' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x28, 0x28, 0x28 }, - { /* ')' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x29, 0x29, 0x29 }, - { /* '*' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2A, 0x2A, 0x2A }, - { /* '+' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2B, 0x2B, 0x2B }, - { /* ',' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2C, 0x2C, 0x2C }, - { /* '-' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2D, 0x2D, 0x2D }, - { /* '.' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2E, 0x2E, 0x2E }, - { /* '/' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2F, 0x2F, 0x2F }, - { /* '0' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x30, 0x30, 0x30 }, - { /* '1' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x31, 0x31, 0x31 }, - { /* '2' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x32, 0x32, 0x32 }, - { /* '3' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x33, 0x33, 0x33 }, - { /* '4' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x34, 0x34, 0x34 }, - { /* '5' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x35, 0x35, 0x35 }, - { /* '6' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x36, 0x36, 0x36 }, - { /* '7' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x37, 0x37, 0x37 }, - { /* '8' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x38, 0x38, 0x38 }, - { /* '9' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x39, 0x39, 0x39 }, - { /* ':' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3A, 0x3A, 0x3A }, - { /* ';' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3B, 0x3B, 0x3B }, - { /* '<' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3C, 0x3C, 0x3C }, - { /* '=' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3D, 0x3D, 0x3D }, - { /* '>' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3E, 0x3E, 0x3E }, - { /* '?' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3F, 0x3F, 0x3F }, - { /* '@' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x40, 0x40, 0x40 }, - { /* 'A' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x41, 0x61, 0x41 }, - { /* 'B' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x42, 0x62, 0x42 }, - { /* 'C' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x43, 0x63, 0x43 }, - { /* 'D' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x44, 0x64, 0x44 }, - { /* 'E' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x45, 0x65, 0x45 }, - { /* 'F' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x46, 0x66, 0x46 }, - { /* 'G' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x47, 0x67, 0x47 }, - { /* 'H' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x48, 0x68, 0x48 }, - { /* 'I' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x49, 0x69, 0x49 }, - { /* 'J' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4A, 0x6A, 0x4A }, - { /* 'K' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4B, 0x6B, 0x4B }, - { /* 'L' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4C, 0x6C, 0x4C }, - { /* 'M' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4D, 0x6D, 0x4D }, - { /* 'N' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4E, 0x6E, 0x4E }, - { /* 'O' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4F, 0x6F, 0x4F }, - { /* 'P' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x50, 0x70, 0x50 }, - { /* 'Q' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x51, 0x71, 0x51 }, - { /* 'R' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x52, 0x72, 0x52 }, - { /* 'S' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x53, 0x73, 0x53 }, - { /* 'T' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x54, 0x74, 0x54 }, - { /* 'U' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x55, 0x75, 0x55 }, - { /* 'V' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x56, 0x76, 0x56 }, - { /* 'W' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x57, 0x77, 0x57 }, - { /* 'X' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x58, 0x78, 0x58 }, - { /* 'Y' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x59, 0x79, 0x59 }, - { /* 'Z' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x5A, 0x7A, 0x5A }, - { /* '[' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5B, 0x5B, 0x5B }, - { /* '\' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5C, 0x5C, 0x5C }, - { /* ']' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5D, 0x5D, 0x5D }, - { /* '^' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5E, 0x5E, 0x5E }, - { /* '_' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5F, 0x5F, 0x5F }, - { /* '`' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x60, 0x60, 0x60 }, - { /* 'a' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x41, 0x61, 0x61 }, - { /* 'b' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x42, 0x62, 0x62 }, - { /* 'c' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x43, 0x63, 0x63 }, - { /* 'd' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x44, 0x64, 0x64 }, - { /* 'e' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x45, 0x65, 0x65 }, - { /* 'f' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x46, 0x66, 0x66 }, - { /* 'g' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x47, 0x67, 0x67 }, - { /* 'h' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x48, 0x68, 0x68 }, - { /* 'i' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x49, 0x69, 0x69 }, - { /* 'j' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4A, 0x6A, 0x6A }, - { /* 'k' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4B, 0x6B, 0x6B }, - { /* 'l' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4C, 0x6C, 0x6C }, - { /* 'm' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4D, 0x6D, 0x6D }, - { /* 'n' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4E, 0x6E, 0x6E }, - { /* 'o' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4F, 0x6F, 0x6F }, - { /* 'p' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x50, 0x70, 0x70 }, - { /* 'q' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x51, 0x71, 0x71 }, - { /* 'r' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x52, 0x72, 0x72 }, - { /* 's' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x53, 0x73, 0x73 }, - { /* 't' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x54, 0x74, 0x74 }, - { /* 'u' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x55, 0x75, 0x75 }, - { /* 'v' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x56, 0x76, 0x76 }, - { /* 'w' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x57, 0x77, 0x77 }, - { /* 'x' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x58, 0x78, 0x78 }, - { /* 'y' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x59, 0x79, 0x79 }, - { /* 'z' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x5A, 0x7A, 0x7A }, - { /* '{' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7B, 0x7B, 0x7B }, - { /* '|' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7C, 0x7C, 0x7C }, - { /* '}' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7D, 0x7D, 0x7D }, - { /* '~' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7E, 0x7E, 0x7E }, - { /* DEL */ _PDCLIB_CTYPE_CNTRL, 0x7F, 0x7F, 0x7F }, - { 0x00, 0x80, 0x80, 0x80 }, - { 0x00, 0x81, 0x81, 0x81 }, - { 0x00, 0x82, 0x82, 0x82 }, - { 0x00, 0x83, 0x83, 0x83 }, - { 0x00, 0x84, 0x84, 0x84 }, - { 0x00, 0x85, 0x85, 0x85 }, - { 0x00, 0x86, 0x86, 0x86 }, - { 0x00, 0x87, 0x87, 0x87 }, - { 0x00, 0x88, 0x88, 0x88 }, - { 0x00, 0x89, 0x89, 0x89 }, - { 0x00, 0x8A, 0x8A, 0x8A }, - { 0x00, 0x8B, 0x8B, 0x8B }, - { 0x00, 0x8C, 0x8C, 0x8C }, - { 0x00, 0x8D, 0x8D, 0x8D }, - { 0x00, 0x8E, 0x8E, 0x8E }, - { 0x00, 0x8F, 0x8F, 0x8F }, - { 0x00, 0x90, 0x90, 0x90 }, - { 0x00, 0x91, 0x91, 0x91 }, - { 0x00, 0x92, 0x92, 0x92 }, - { 0x00, 0x93, 0x93, 0x93 }, - { 0x00, 0x94, 0x94, 0x94 }, - { 0x00, 0x95, 0x95, 0x95 }, - { 0x00, 0x96, 0x96, 0x96 }, - { 0x00, 0x97, 0x97, 0x97 }, - { 0x00, 0x98, 0x98, 0x98 }, - { 0x00, 0x99, 0x99, 0x99 }, - { 0x00, 0x9A, 0x9A, 0x9A }, - { 0x00, 0x9B, 0x9B, 0x9B }, - { 0x00, 0x9C, 0x9C, 0x9C }, - { 0x00, 0x9D, 0x9D, 0x9D }, - { 0x00, 0x9E, 0x9E, 0x9E }, - { 0x00, 0x9F, 0x9F, 0x9F }, - { 0x00, 0xA0, 0xA0, 0xA0 }, - { 0x00, 0xA1, 0xA1, 0xA1 }, - { 0x00, 0xA2, 0xA2, 0xA2 }, - { 0x00, 0xA3, 0xA3, 0xA3 }, - { 0x00, 0xA4, 0xA4, 0xA4 }, - { 0x00, 0xA5, 0xA5, 0xA5 }, - { 0x00, 0xA6, 0xA6, 0xA6 }, - { 0x00, 0xA7, 0xA7, 0xA7 }, - { 0x00, 0xA8, 0xA8, 0xA8 }, - { 0x00, 0xA9, 0xA9, 0xA9 }, - { 0x00, 0xAA, 0xAA, 0xAA }, - { 0x00, 0xAB, 0xAB, 0xAB }, - { 0x00, 0xAC, 0xAC, 0xAC }, - { 0x00, 0xAD, 0xAD, 0xAD }, - { 0x00, 0xAE, 0xAE, 0xAE }, - { 0x00, 0xAF, 0xAF, 0xAF }, - { 0x00, 0xB0, 0xB0, 0xB0 }, - { 0x00, 0xB1, 0xB1, 0xB1 }, - { 0x00, 0xB2, 0xB2, 0xB2 }, - { 0x00, 0xB3, 0xB3, 0xB3 }, - { 0x00, 0xB4, 0xB4, 0xB4 }, - { 0x00, 0xB5, 0xB5, 0xB5 }, - { 0x00, 0xB6, 0xB6, 0xB6 }, - { 0x00, 0xB7, 0xB7, 0xB7 }, - { 0x00, 0xB8, 0xB8, 0xB8 }, - { 0x00, 0xB9, 0xB9, 0xB9 }, - { 0x00, 0xBA, 0xBA, 0xBA }, - { 0x00, 0xBB, 0xBB, 0xBB }, - { 0x00, 0xBC, 0xBC, 0xBC }, - { 0x00, 0xBD, 0xBD, 0xBD }, - { 0x00, 0xBE, 0xBE, 0xBE }, - { 0x00, 0xBF, 0xBF, 0xBF }, - { 0x00, 0xC0, 0xC0, 0xC0 }, - { 0x00, 0xC1, 0xC1, 0xC1 }, - { 0x00, 0xC2, 0xC2, 0xC2 }, - { 0x00, 0xC3, 0xC3, 0xC3 }, - { 0x00, 0xC4, 0xC4, 0xC4 }, - { 0x00, 0xC5, 0xC5, 0xC5 }, - { 0x00, 0xC6, 0xC6, 0xC6 }, - { 0x00, 0xC7, 0xC7, 0xC7 }, - { 0x00, 0xC8, 0xC8, 0xC8 }, - { 0x00, 0xC9, 0xC9, 0xC9 }, - { 0x00, 0xCA, 0xCA, 0xCA }, - { 0x00, 0xCB, 0xCB, 0xCB }, - { 0x00, 0xCC, 0xCC, 0xCC }, - { 0x00, 0xCD, 0xCD, 0xCD }, - { 0x00, 0xCE, 0xCE, 0xCE }, - { 0x00, 0xCF, 0xCF, 0xCF }, - { 0x00, 0xD0, 0xD0, 0xD0 }, - { 0x00, 0xD1, 0xD1, 0xD1 }, - { 0x00, 0xD2, 0xD2, 0xD2 }, - { 0x00, 0xD3, 0xD3, 0xD3 }, - { 0x00, 0xD4, 0xD4, 0xD4 }, - { 0x00, 0xD5, 0xD5, 0xD5 }, - { 0x00, 0xD6, 0xD6, 0xD6 }, - { 0x00, 0xD7, 0xD7, 0xD7 }, - { 0x00, 0xD8, 0xD8, 0xD8 }, - { 0x00, 0xD9, 0xD9, 0xD9 }, - { 0x00, 0xDA, 0xDA, 0xDA }, - { 0x00, 0xDB, 0xDB, 0xDB }, - { 0x00, 0xDC, 0xDC, 0xDC }, - { 0x00, 0xDD, 0xDD, 0xDD }, - { 0x00, 0xDE, 0xDE, 0xDE }, - { 0x00, 0xDF, 0xDF, 0xDF }, - { 0x00, 0xE0, 0xE0, 0xE0 }, - { 0x00, 0xE1, 0xE1, 0xE1 }, - { 0x00, 0xE2, 0xE2, 0xE2 }, - { 0x00, 0xE3, 0xE3, 0xE3 }, - { 0x00, 0xE4, 0xE4, 0xE4 }, - { 0x00, 0xE5, 0xE5, 0xE5 }, - { 0x00, 0xE6, 0xE6, 0xE6 }, - { 0x00, 0xE7, 0xE7, 0xE7 }, - { 0x00, 0xE8, 0xE8, 0xE8 }, - { 0x00, 0xE9, 0xE9, 0xE9 }, - { 0x00, 0xEA, 0xEA, 0xEA }, - { 0x00, 0xEB, 0xEB, 0xEB }, - { 0x00, 0xEC, 0xEC, 0xEC }, - { 0x00, 0xED, 0xED, 0xED }, - { 0x00, 0xEE, 0xEE, 0xEE }, - { 0x00, 0xEF, 0xEF, 0xEF }, - { 0x00, 0xF0, 0xF0, 0xF0 }, - { 0x00, 0xF1, 0xF1, 0xF1 }, - { 0x00, 0xF2, 0xF2, 0xF2 }, - { 0x00, 0xF3, 0xF3, 0xF3 }, - { 0x00, 0xF4, 0xF4, 0xF4 }, - { 0x00, 0xF5, 0xF5, 0xF5 }, - { 0x00, 0xF6, 0xF6, 0xF6 }, - { 0x00, 0xF7, 0xF7, 0xF7 }, - { 0x00, 0xF8, 0xF8, 0xF8 }, - { 0x00, 0xF9, 0xF9, 0xF9 }, - { 0x00, 0xFA, 0xFA, 0xFA }, - { 0x00, 0xFB, 0xFB, 0xFB }, - { 0x00, 0xFC, 0xFC, 0xFC }, - { 0x00, 0xFD, 0xFD, 0xFD }, - { 0x00, 0xFE, 0xFE, 0xFE }, - { 0x00, 0xFF, 0xFF, 0xFF } -}; - -extern const struct _PDCLIB_charcodec_t _PDCLIB_ascii_codec; -struct _PDCLIB_locale _PDCLIB_global_locale = { - ._Codec = &_PDCLIB_ascii_codec, - ._Conv = { - /* decimal_point */ (char *)".", - /* thousands_sep */ (char *)"", - /* grouping */ (char *)"", - /* mon_decimal_point */ (char *)"", - /* mon_thousands_sep */ (char *)"", - /* mon_grouping */ (char *)"", - /* positive_sign */ (char *)"", - /* negative_sign */ (char *)"", - /* currency_symbol */ (char *)"", - /* int_curr_symbol */ (char *)"", - /* frac_digits */ CHAR_MAX, - /* p_cs_precedes */ CHAR_MAX, - /* n_cs_precedes */ CHAR_MAX, - /* p_sep_by_space */ CHAR_MAX, - /* n_sep_by_space */ CHAR_MAX, - /* p_sign_posn */ CHAR_MAX, - /* n_sign_posn */ CHAR_MAX, - /* int_frac_digits */ CHAR_MAX, - /* int_p_cs_precedes */ CHAR_MAX, - /* int_n_cs_precedes */ CHAR_MAX, - /* int_p_sep_by_space */ CHAR_MAX, - /* int_n_sep_by_space */ CHAR_MAX, - /* int_p_sign_posn */ CHAR_MAX, - /* int_n_sign_posn */ CHAR_MAX, - }, - ._CType = &global_ctype[1], - ._ErrnoStr = { - "Success", - "EPERM (operation not permitted)", - "ENOENT (no such file or directory)", - "ESRCH (no such process)", - "EINTR (interrupted)", - "EIO (io error)", - "ENXIO (no such device or address)", - "E2BIG (argument list too long)", - "ENOEXEC (executable format error)", - "EBADF (bad file descriptor)", - "ECHILD (no child process)", - "EAGAIN (resource unavailable try again)", - "ENOMEM (not enough memory)", - "EACCES (permission denied)", - "EFAULT (bad address)", - "Unknown error", - "EBUSY (device or resource busy)", - "EEXIST (file exists)", - "EXDEV (cross device link)", - "ENODEV (no such device)", - "ENOTDIR (not a directory)", - "EISDIR (is a directory)", - "EINVAL (invalid argument)", - "ENFILE (too many files open in system)", - "EMFILE (too many files open)", - "ENOTTY (inappropriate io control operation)", - "ETXTBSY (text file busy)", - "EFBIG (file too large)", - "ENOSPC (no space on device)", - "ESPIPE (invalid seek)", - "EROFS (read only file system)", - "EMLINK (too many links)", - "EPIPE (broken pipe)", - "EDOM (argument out of domain)", - "ERANGE (result out of range)", - "EDEADLK (resource deadlock would occur)", - "ENAMETOOLONG (filename too long)", - "ENOLCK (no lock available)", - "ENOSYS (function not supported)", - "ENOTEMPTY (directory not empty)", - "ELOOP (too many symbolic link levels)", - "Unknown error", - "ENOMSG (no message)", - "EIDRM (identifier removed)", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "ENOSTR (not a stream)", - "ENODATA (no message available)", - "ETIME (stream timeout)", - "ENOSR (no stream resources)", - "Unknown error", - "Unknown error", - "Unknown error", - "ENOLINK (no link)", - "Unknown error", - "Unknown error", - "Unknown error", - "EPROTO (protocol error)", - "Unknown error", - "Unknown error", - "EBADMSG (bad message)", - "EOVERFLOW (value too large)", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "EILSEQ (illegal byte sequence)", - "Unknown error", - "Unknown error", - "Unknown error", - "ENOTSOCK (not a socket)", - "EDESTADDRREQ (destination address required)", - "EMSGSIZE (message size)", - "EPROTOTYPE (wrong protocol type)", - "ENOPROTOOPT (no protocol option)", - "EPROTONOSUPPORT (protocol not supported)", - "Unknown error", - "ENOTSUP (not supported)", - "Unknown error", - "EAFNOSUPPORT (address family not supported)", - "EADDRINUSE (address in use)", - "EADDRNOTAVAIL (address not available)", - "ENETDOWN (network down)", - "ENETUNREACH (network unreachable)", - "ENETRESET (network reset)", - "ECONNABORTED (connection aborted)", - "ECONNRESET (connection reset)", - "ENOBUFS (no buffer space)", - "EISCONN (already connected)", - "ENOTCONN (not connected)", - "Unknown error", - "Unknown error", - "ETIMEDOUT (timed out)", - "ECONNREFUSED (connection refused)", - "Unknown error", - "EHOSTUNREACH (host unreachable)", - "EALREADY (connection already in progress)", - "EINPROGRESS (operation in progress)", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "ECANCELED (operation canceled)", - "Unknown error", - "Unknown error", - "Unknown error", - "Unknown error", - "EOWNERDEAD (owner dead)", - "ENOTRECOVERABLE (state not recoverable)", - }, -}; - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by several other testdrivers using stdin / stdout / - stderr. - */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/_dlmalloc/dlmalloc.c b/waterbox/libc/functions/_dlmalloc/dlmalloc.c deleted file mode 100644 index 520be7f9d6..0000000000 --- a/waterbox/libc/functions/_dlmalloc/dlmalloc.c +++ /dev/null @@ -1,6227 +0,0 @@ -/* - This is a version (aka dlmalloc) of malloc/free/realloc written by - Doug Lea and released to the public domain, as explained at - http://creativecommons.org/publicdomain/zero/1.0/ Send questions, - comments, complaints, performance data, etc to dl@cs.oswego.edu - -* Version 2.8.5 Sun May 22 10:26:02 2011 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at - ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - -* Quickstart - - This library is all in one file to simplify the most common usage: - ftp it, compile it (-O3), and link it into another program. All of - the compile-time options default to reasonable values for use on - most platforms. You might later want to step through various - compile-time and dynamic tuning options. - - For convenience, an include file for code using this malloc is at: - ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.5.h - You don't really need this .h file unless you call functions not - defined in your system include files. The .h file contains only the - excerpts from this file needed for using this malloc on ANSI C/C++ - systems, so long as you haven't changed compile-time options about - naming and tuning parameters. If you do, then you can create your - own malloc.h that does include all settings by cutting at the point - indicated below. Note that you may already by default be using a C - library containing a malloc that is based on some version of this - malloc (for example in linux). You might still want to use the one - in this file to customize settings or to avoid overheads associated - with library versions. - -* Vital statistics: - - Supported pointer/size_t representation: 4 or 8 bytes - size_t MUST be an unsigned type of the same width as - pointers. (If you are using an ancient system that declares - size_t as a signed type, or need it to be a different width - than pointers, you can use a previous release of this malloc - (e.g. 2.7.2) supporting these.) - - Alignment: 8 bytes (default) - This suffices for nearly all current machines and C compilers. - However, you can define MALLOC_ALIGNMENT to be wider than this - if necessary (up to 128bytes), at the expense of using more space. - - Minimum overhead per allocated chunk: 4 or 8 bytes (if 4byte sizes) - 8 or 16 bytes (if 8byte sizes) - Each malloced chunk has a hidden word of overhead holding size - and status information, and additional cross-check word - if FOOTERS is defined. - - Minimum allocated size: 4-byte ptrs: 16 bytes (including overhead) - 8-byte ptrs: 32 bytes (including overhead) - - Even a request for zero bytes (i.e., malloc(0)) returns a - pointer to something of the minimum allocatable size. - The maximum overhead wastage (i.e., number of extra bytes - allocated than were requested in malloc) is less than or equal - to the minimum size, except for requests >= mmap_threshold that - are serviced via mmap(), where the worst case wastage is about - 32 bytes plus the remainder from a system page (the minimal - mmap unit); typically 4096 or 8192 bytes. - - Security: static-safe; optionally more or less - The "security" of malloc refers to the ability of malicious - code to accentuate the effects of errors (for example, freeing - space that is not currently malloc'ed or overwriting past the - ends of chunks) in code that calls malloc. This malloc - guarantees not to modify any memory locations below the base of - heap, i.e., static variables, even in the presence of usage - errors. The routines additionally detect most improper frees - and reallocs. All this holds as long as the static bookkeeping - for malloc itself is not corrupted by some other means. This - is only one aspect of security -- these checks do not, and - cannot, detect all possible programming errors. - - If FOOTERS is defined nonzero, then each allocated chunk - carries an additional check word to verify that it was malloced - from its space. These check words are the same within each - execution of a program using malloc, but differ across - executions, so externally crafted fake chunks cannot be - freed. This improves security by rejecting frees/reallocs that - could corrupt heap memory, in addition to the checks preventing - writes to statics that are always on. This may further improve - security at the expense of time and space overhead. (Note that - FOOTERS may also be worth using with MSPACES.) - - By default detected errors cause the program to abort (calling - "abort()"). You can override this to instead proceed past - errors by defining PROCEED_ON_ERROR. In this case, a bad free - has no effect, and a malloc that encounters a bad address - caused by user overwrites will ignore the bad address by - dropping pointers and indices to all known memory. This may - be appropriate for programs that should continue if at all - possible in the face of programming errors, although they may - run out of memory because dropped memory is never reclaimed. - - If you don't like either of these options, you can define - CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything - else. And if if you are sure that your program using malloc has - no errors or vulnerabilities, you can define INSECURE to 1, - which might (or might not) provide a small performance improvement. - - It is also possible to limit the maximum total allocatable - space, using malloc_set_footprint_limit. This is not - designed as a security feature in itself (calls to set limits - are not screened or privileged), but may be useful as one - aspect of a secure implementation. - - Thread-safety: NOT thread-safe unless USE_LOCKS defined non-zero - When USE_LOCKS is defined, each public call to malloc, free, - etc is surrounded with a lock. By default, this uses a plain - pthread mutex, win32 critical section, or a spin-lock if if - available for the platform and not disabled by setting - USE_SPIN_LOCKS=0. However, if USE_RECURSIVE_LOCKS is defined, - recursive versions are used instead (which are not required for - base functionality but may be needed in layered extensions). - Using a global lock is not especially fast, and can be a major - bottleneck. It is designed only to provide minimal protection - in concurrent environments, and to provide a basis for - extensions. If you are using malloc in a concurrent program, - consider instead using nedmalloc - (http://www.nedprod.com/programs/portable/nedmalloc/) or - ptmalloc (See http://www.malloc.de), which are derived from - versions of this malloc. - - System requirements: Any combination of MORECORE and/or MMAP/MUNMAP - This malloc can use unix sbrk or any emulation (invoked using - the CALL_MORECORE macro) and/or mmap/munmap or any emulation - (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system - memory. On most unix systems, it tends to work best if both - MORECORE and MMAP are enabled. On Win32, it uses emulations - based on VirtualAlloc. It also uses common C library functions - like memset. - - Compliance: I believe it is compliant with the Single Unix Specification - (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably - others as well. - -* Overview of algorithms - - This is not the fastest, most space-conserving, most portable, or - most tunable malloc ever written. However it is among the fastest - while also being among the most space-conserving, portable and - tunable. Consistent balance across these factors results in a good - general-purpose allocator for malloc-intensive programs. - - In most ways, this malloc is a best-fit allocator. Generally, it - chooses the best-fitting existing chunk for a request, with ties - broken in approximately least-recently-used order. (This strategy - normally maintains low fragmentation.) However, for requests less - than 256bytes, it deviates from best-fit when there is not an - exactly fitting available chunk by preferring to use space adjacent - to that used for the previous small request, as well as by breaking - ties in approximately most-recently-used order. (These enhance - locality of series of small allocations.) And for very large requests - (>= 256Kb by default), it relies on system memory mapping - facilities, if supported. (This helps avoid carrying around and - possibly fragmenting memory used only for large chunks.) - - All operations (except malloc_stats and mallinfo) have execution - times that are bounded by a constant factor of the number of bits in - a size_t, not counting any clearing in calloc or copying in realloc, - or actions surrounding MORECORE and MMAP that have times - proportional to the number of non-contiguous regions returned by - system allocation routines, which is often just 1. In real-time - applications, you can optionally suppress segment traversals using - NO_SEGMENT_TRAVERSAL, which assures bounded execution even when - system allocators return non-contiguous spaces, at the typical - expense of carrying around more memory and increased fragmentation. - - The implementation is not very modular and seriously overuses - macros. Perhaps someday all C compilers will do as good a job - inlining modular code as can now be done by brute-force expansion, - but now, enough of them seem not to. - - Some compilers issue a lot of warnings about code that is - dead/unreachable only on some platforms, and also about intentional - uses of negation on unsigned types. All known cases of each can be - ignored. - - For a longer but out of date high-level description, see - http://gee.cs.oswego.edu/dl/html/malloc.html - -* MSPACES - If MSPACES is defined, then in addition to malloc, free, etc., - this file also defines mspace_malloc, mspace_free, etc. These - are versions of malloc routines that take an "mspace" argument - obtained using create_mspace, to control all internal bookkeeping. - If ONLY_MSPACES is defined, only these versions are compiled. - So if you would like to use this allocator for only some allocations, - and your system malloc for others, you can compile with - ONLY_MSPACES and then do something like... - static mspace mymspace = create_mspace(0,0); // for example - #define mymalloc(bytes) mspace_malloc(mymspace, bytes) - - (Note: If you only need one instance of an mspace, you can instead - use "USE_DL_PREFIX" to relabel the global malloc.) - - You can similarly create thread-local allocators by storing - mspaces as thread-locals. For example: - static __thread mspace tlms = 0; - void* tlmalloc(size_t bytes) { - if (tlms == 0) tlms = create_mspace(0, 0); - return mspace_malloc(tlms, bytes); - } - void tlfree(void* mem) { mspace_free(tlms, mem); } - - Unless FOOTERS is defined, each mspace is completely independent. - You cannot allocate from one and free to another (although - conformance is only weakly checked, so usage errors are not always - caught). If FOOTERS is defined, then each chunk carries around a tag - indicating its originating mspace, and frees are directed to their - originating spaces. Normally, this requires use of locks. - - ------------------------- Compile-time options --------------------------- - -Be careful in setting #define values for numerical constants of type -size_t. On some systems, literal values are not automatically extended -to size_t precision unless they are explicitly casted. You can also -use the symbolic values MAX_SIZE_T, SIZE_T_ONE, etc below. - -WIN32 default: defined if _WIN32 defined - Defining WIN32 sets up defaults for MS environment and compilers. - Otherwise defaults are for unix. Beware that there seem to be some - cases where this malloc might not be a pure drop-in replacement for - Win32 malloc: Random-looking failures from Win32 GDI API's (eg; - SetDIBits()) may be due to bugs in some video driver implementations - when pixel buffers are malloc()ed, and the region spans more than - one VirtualAlloc()ed region. Because dlmalloc uses a small (64Kb) - default granularity, pixel buffers may straddle virtual allocation - regions more often than when using the Microsoft allocator. You can - avoid this by using VirtualAlloc() and VirtualFree() for all pixel - buffers rather than using malloc(). If this is not possible, - recompile this malloc with a larger DEFAULT_GRANULARITY. Note: - in cases where MSC and gcc (cygwin) are known to differ on WIN32, - conditions use _MSC_VER to distinguish them. - -DLMALLOC_EXPORT default: extern - Defines how public APIs are declared. If you want to export via a - Windows DLL, you might define this as - #define DLMALLOC_EXPORT extern __declspace(dllexport) - If you want a POSIX ELF shared object, you might use - #define DLMALLOC_EXPORT extern __attribute__((visibility("default"))) - -MALLOC_ALIGNMENT default: (size_t)8 - Controls the minimum alignment for malloc'ed chunks. It must be a - power of two and at least 8, even on machines for which smaller - alignments would suffice. It may be defined as larger than this - though. Note however that code and data structures are optimized for - the case of 8-byte alignment. - -MSPACES default: 0 (false) - If true, compile in support for independent allocation spaces. - This is only supported if HAVE_MMAP is true. - -ONLY_MSPACES default: 0 (false) - If true, only compile in mspace versions, not regular versions. - -USE_LOCKS default: 0 (false) - Causes each call to each public routine to be surrounded with - pthread or WIN32 mutex lock/unlock. (If set true, this can be - overridden on a per-mspace basis for mspace versions.) If set to a - non-zero value other than 1, locks are used, but their - implementation is left out, so lock functions must be supplied manually, - as described below. - -USE_SPIN_LOCKS default: 1 iff USE_LOCKS and spin locks available - If true, uses custom spin locks for locking. This is currently - supported only gcc >= 4.1, older gccs on x86 platforms, and recent - MS compilers. Otherwise, posix locks or win32 critical sections are - used. - -USE_RECURSIVE_LOCKS default: not defined - If defined nonzero, uses recursive (aka reentrant) locks, otherwise - uses plain mutexes. This is not required for malloc proper, but may - be needed for layered allocators such as nedmalloc. - -FOOTERS default: 0 - If true, provide extra checking and dispatching by placing - information in the footers of allocated chunks. This adds - space and time overhead. - -INSECURE default: 0 - If true, omit checks for usage errors and heap space overwrites. - -USE_DL_PREFIX default: NOT defined - Causes compiler to prefix all public routines with the string 'dl'. - This can be useful when you only want to use this malloc in one part - of a program, using your regular system malloc elsewhere. - -MALLOC_INSPECT_ALL default: NOT defined - If defined, compiles malloc_inspect_all and mspace_inspect_all, that - perform traversal of all heap space. Unless access to these - functions is otherwise restricted, you probably do not want to - include them in secure implementations. - -ABORT default: defined as abort() - Defines how to abort on failed checks. On most systems, a failed - check cannot die with an "assert" or even print an informative - message, because the underlying print routines in turn call malloc, - which will fail again. Generally, the best policy is to simply call - abort(). It's not very useful to do more than this because many - errors due to overwriting will show up as address faults (null, odd - addresses etc) rather than malloc-triggered checks, so will also - abort. Also, most compilers know that abort() does not return, so - can better optimize code conditionally calling it. - -PROCEED_ON_ERROR default: defined as 0 (false) - Controls whether detected bad addresses cause them to bypassed - rather than aborting. If set, detected bad arguments to free and - realloc are ignored. And all bookkeeping information is zeroed out - upon a detected overwrite of freed heap space, thus losing the - ability to ever return it from malloc again, but enabling the - application to proceed. If PROCEED_ON_ERROR is defined, the - static variable malloc_corruption_error_count is compiled in - and can be examined to see if errors have occurred. This option - generates slower code than the default abort policy. - -DEBUG default: NOT defined - The DEBUG setting is mainly intended for people trying to modify - this code or diagnose problems when porting to new platforms. - However, it may also be able to better isolate user errors than just - using runtime checks. The assertions in the check routines spell - out in more detail the assumptions and invariants underlying the - algorithms. The checking is fairly extensive, and will slow down - execution noticeably. Calling malloc_stats or mallinfo with DEBUG - set will attempt to check every non-mmapped allocated and free chunk - in the course of computing the summaries. - -ABORT_ON_ASSERT_FAILURE default: defined as 1 (true) - Debugging assertion failures can be nearly impossible if your - version of the assert macro causes malloc to be called, which will - lead to a cascade of further failures, blowing the runtime stack. - ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(), - which will usually make debugging easier. - -MALLOC_FAILURE_ACTION default: sets errno to ENOMEM, or no-op on win32 - The action to take before "return 0" when malloc fails to be able to - return memory because there is none available. - -HAVE_MORECORE default: 1 (true) unless win32 or ONLY_MSPACES - True if this system supports sbrk or an emulation of it. - -MORECORE default: sbrk - The name of the sbrk-style system routine to call to obtain more - memory. See below for guidance on writing custom MORECORE - functions. The type of the argument to sbrk/MORECORE varies across - systems. It cannot be size_t, because it supports negative - arguments, so it is normally the signed type of the same width as - size_t (sometimes declared as "intptr_t"). It doesn't much matter - though. Internally, we only call it with arguments less than half - the max value of a size_t, which should work across all reasonable - possibilities, although sometimes generating compiler warnings. - -MORECORE_CONTIGUOUS default: 1 (true) if HAVE_MORECORE - If true, take advantage of fact that consecutive calls to MORECORE - with positive arguments always return contiguous increasing - addresses. This is true of unix sbrk. It does not hurt too much to - set it true anyway, since malloc copes with non-contiguities. - Setting it false when definitely non-contiguous saves time - and possibly wasted space it would take to discover this though. - -MORECORE_CANNOT_TRIM default: NOT defined - True if MORECORE cannot release space back to the system when given - negative arguments. This is generally necessary only if you are - using a hand-crafted MORECORE function that cannot handle negative - arguments. - -NO_SEGMENT_TRAVERSAL default: 0 - If non-zero, suppresses traversals of memory segments - returned by either MORECORE or CALL_MMAP. This disables - merging of segments that are contiguous, and selectively - releasing them to the OS if unused, but bounds execution times. - -HAVE_MMAP default: 1 (true) - True if this system supports mmap or an emulation of it. If so, and - HAVE_MORECORE is not true, MMAP is used for all system - allocation. If set and HAVE_MORECORE is true as well, MMAP is - primarily used to directly allocate very large blocks. It is also - used as a backup strategy in cases where MORECORE fails to provide - space from system. Note: A single call to MUNMAP is assumed to be - able to unmap memory that may have be allocated using multiple calls - to MMAP, so long as they are adjacent. - -HAVE_MREMAP default: 1 on linux, else 0 - If true realloc() uses mremap() to re-allocate large blocks and - extend or shrink allocation spaces. - -MMAP_CLEARS default: 1 except on WINCE. - True if mmap clears memory so calloc doesn't need to. This is true - for standard unix mmap using /dev/zero and on WIN32 except for WINCE. - -USE_BUILTIN_FFS default: 0 (i.e., not used) - Causes malloc to use the builtin ffs() function to compute indices. - Some compilers may recognize and intrinsify ffs to be faster than the - supplied C version. Also, the case of x86 using gcc is special-cased - to an asm instruction, so is already as fast as it can be, and so - this setting has no effect. Similarly for Win32 under recent MS compilers. - (On most x86s, the asm version is only slightly faster than the C version.) - -malloc_getpagesize default: derive from system includes, or 4096. - The system page size. To the extent possible, this malloc manages - memory from the system in page-size units. This may be (and - usually is) a function rather than a constant. This is ignored - if WIN32, where page size is determined using getSystemInfo during - initialization. - -USE_DEV_RANDOM default: 0 (i.e., not used) - Causes malloc to use /dev/random to initialize secure magic seed for - stamping footers. Otherwise, the current time is used. - -NO_MALLINFO default: 0 - If defined, don't compile "mallinfo". This can be a simple way - of dealing with mismatches between system declarations and - those in this file. - -MALLINFO_FIELD_TYPE default: size_t - The type of the fields in the mallinfo struct. This was originally - defined as "int" in SVID etc, but is more usefully defined as - size_t. The value is used only if HAVE_USR_INCLUDE_MALLOC_H is not set - -NO_MALLOC_STATS default: 0 - If defined, don't compile "malloc_stats". This avoids calls to - fprintf and bringing in stdio dependencies you might not want. - -REALLOC_ZERO_BYTES_FREES default: not defined - This should be set if a call to realloc with zero bytes should - be the same as a call to free. Some people think it should. Otherwise, - since this malloc returns a unique pointer for malloc(0), so does - realloc(p, 0). - -LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H -LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H, LACKS_ERRNO_H -LACKS_STDLIB_H LACKS_SCHED_H LACKS_TIME_H default: NOT defined unless on WIN32 - Define these if your system does not have these header files. - You might need to manually insert some of the declarations they provide. - -DEFAULT_GRANULARITY default: page size if MORECORE_CONTIGUOUS, - system_info.dwAllocationGranularity in WIN32, - otherwise 64K. - Also settable using mallopt(M_GRANULARITY, x) - The unit for allocating and deallocating memory from the system. On - most systems with contiguous MORECORE, there is no reason to - make this more than a page. However, systems with MMAP tend to - either require or encourage larger granularities. You can increase - this value to prevent system allocation functions to be called so - often, especially if they are slow. The value must be at least one - page and must be a power of two. Setting to 0 causes initialization - to either page size or win32 region size. (Note: In previous - versions of malloc, the equivalent of this option was called - "TOP_PAD") - -DEFAULT_TRIM_THRESHOLD default: 2MB - Also settable using mallopt(M_TRIM_THRESHOLD, x) - The maximum amount of unused top-most memory to keep before - releasing via malloc_trim in free(). Automatic trimming is mainly - useful in long-lived programs using contiguous MORECORE. Because - trimming via sbrk can be slow on some systems, and can sometimes be - wasteful (in cases where programs immediately afterward allocate - more large chunks) the value should be high enough so that your - overall system performance would improve by releasing this much - memory. As a rough guide, you might set to a value close to the - average size of a process (program) running on your system. - Releasing this much memory would allow such a process to run in - memory. Generally, it is worth tuning trim thresholds when a - program undergoes phases where several large chunks are allocated - and released in ways that can reuse each other's storage, perhaps - mixed with phases where there are no such chunks at all. The trim - value must be greater than page size to have any useful effect. To - disable trimming completely, you can set to MAX_SIZE_T. Note that the trick - some people use of mallocing a huge space and then freeing it at - program startup, in an attempt to reserve system memory, doesn't - have the intended effect under automatic trimming, since that memory - will immediately be returned to the system. - -DEFAULT_MMAP_THRESHOLD default: 256K - Also settable using mallopt(M_MMAP_THRESHOLD, x) - The request size threshold for using MMAP to directly service a - request. Requests of at least this size that cannot be allocated - using already-existing space will be serviced via mmap. (If enough - normal freed space already exists it is used instead.) Using mmap - segregates relatively large chunks of memory so that they can be - individually obtained and released from the host system. A request - serviced through mmap is never reused by any other request (at least - not directly; the system may just so happen to remap successive - requests to the same locations). Segregating space in this way has - the benefits that: Mmapped space can always be individually released - back to the system, which helps keep the system level memory demands - of a long-lived program low. Also, mapped memory doesn't become - `locked' between other chunks, as can happen with normally allocated - chunks, which means that even trimming via malloc_trim would not - release them. However, it has the disadvantage that the space - cannot be reclaimed, consolidated, and then used to service later - requests, as happens with normal chunks. The advantages of mmap - nearly always outweigh disadvantages for "large" chunks, but the - value of "large" may vary across systems. The default is an - empirically derived value that works well in most systems. You can - disable mmap by setting to MAX_SIZE_T. - -MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP - The number of consolidated frees between checks to release - unused segments when freeing. When using non-contiguous segments, - especially with multiple mspaces, checking only for topmost space - doesn't always suffice to trigger trimming. To compensate for this, - free() will, with a period of MAX_RELEASE_CHECK_RATE (or the - current number of segments, if greater) try to release unused - segments to the OS when freeing chunks that result in - consolidation. The best value for this parameter is a compromise - between slowing down frees with relatively costly checks that - rarely trigger versus holding on to unused memory. To effectively - disable, set to MAX_SIZE_T. This may lead to a very slight speed - improvement at the expense of carrying around more memory. -*/ - -#ifndef REGTEST -#include "dlmalloc.h" - -/* Version identifier to allow people to support multiple versions */ -#ifndef DLMALLOC_VERSION -#define DLMALLOC_VERSION 20805 -#endif /* DLMALLOC_VERSION */ - -#ifndef DLMALLOC_EXPORT -#define DLMALLOC_EXPORT extern -#endif - - -#ifndef LACKS_SYS_TYPES_H -#include /* For size_t */ -#endif /* LACKS_SYS_TYPES_H */ - -/* The maximum possible size_t value has all bits set */ -#define MAX_SIZE_T (~(size_t)0) - -#ifndef USE_LOCKS /* ensure true if spin or recursive locks set */ -#define USE_LOCKS ((defined(USE_SPIN_LOCKS) && USE_SPIN_LOCKS != 0) || \ - (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0)) -#endif /* USE_LOCKS */ - -#if USE_LOCKS /* Spin locks for gcc >= 4.1, older gcc on x86, MSC >= 1310 */ -#if ((defined(__GNUC__) && \ - ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) || \ - defined(__i386__) || defined(__x86_64__))) || \ - (defined(_MSC_VER) && _MSC_VER>=1310)) -#ifndef USE_SPIN_LOCKS -#define USE_SPIN_LOCKS 1 -#endif /* USE_SPIN_LOCKS */ -#elif USE_SPIN_LOCKS -#error "USE_SPIN_LOCKS defined without implementation" -#endif /* ... locks available... */ -#elif !defined(USE_SPIN_LOCKS) -#define USE_SPIN_LOCKS 0 -#endif /* USE_LOCKS */ - -#ifndef ONLY_MSPACES -#define ONLY_MSPACES 0 -#endif /* ONLY_MSPACES */ -#ifndef MSPACES -#if ONLY_MSPACES -#define MSPACES 1 -#else /* ONLY_MSPACES */ -#define MSPACES 0 -#endif /* ONLY_MSPACES */ -#endif /* MSPACES */ -#ifndef MALLOC_ALIGNMENT -#define MALLOC_ALIGNMENT ((size_t)8U) -#endif /* MALLOC_ALIGNMENT */ -#ifndef FOOTERS -#define FOOTERS 0 -#endif /* FOOTERS */ -#ifndef ABORT -#define ABORT abort() -#endif /* ABORT */ -#ifndef ABORT_ON_ASSERT_FAILURE -#define ABORT_ON_ASSERT_FAILURE 1 -#endif /* ABORT_ON_ASSERT_FAILURE */ -#ifndef PROCEED_ON_ERROR -#define PROCEED_ON_ERROR 0 -#endif /* PROCEED_ON_ERROR */ - -#ifndef INSECURE -#define INSECURE 0 -#endif /* INSECURE */ -#ifndef MALLOC_INSPECT_ALL -#define MALLOC_INSPECT_ALL 0 -#endif /* MALLOC_INSPECT_ALL */ -#ifndef HAVE_MMAP -#define HAVE_MMAP 1 -#endif /* HAVE_MMAP */ -#ifndef MMAP_CLEARS -#define MMAP_CLEARS 1 -#endif /* MMAP_CLEARS */ -#ifndef HAVE_MREMAP -#ifdef linux -#define HAVE_MREMAP 1 -#define _GNU_SOURCE /* Turns on mremap() definition */ -#else /* linux */ -#define HAVE_MREMAP 0 -#endif /* linux */ -#endif /* HAVE_MREMAP */ -#ifndef MALLOC_FAILURE_ACTION -#define MALLOC_FAILURE_ACTION errno = ENOMEM; -#endif /* MALLOC_FAILURE_ACTION */ -#ifndef HAVE_MORECORE -#if ONLY_MSPACES -#define HAVE_MORECORE 0 -#else /* ONLY_MSPACES */ -#define HAVE_MORECORE 1 -#endif /* ONLY_MSPACES */ -#endif /* HAVE_MORECORE */ -#if !HAVE_MORECORE -#define MORECORE_CONTIGUOUS 0 -#else /* !HAVE_MORECORE */ -#define MORECORE_DEFAULT sbrk -#ifndef MORECORE_CONTIGUOUS -#define MORECORE_CONTIGUOUS 1 -#endif /* MORECORE_CONTIGUOUS */ -#endif /* HAVE_MORECORE */ -#ifndef DEFAULT_GRANULARITY -#if (MORECORE_CONTIGUOUS || defined(WIN32)) -#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */ -#else /* MORECORE_CONTIGUOUS */ -#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U) -#endif /* MORECORE_CONTIGUOUS */ -#endif /* DEFAULT_GRANULARITY */ -#ifndef DEFAULT_TRIM_THRESHOLD -#ifndef MORECORE_CANNOT_TRIM -#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U) -#else /* MORECORE_CANNOT_TRIM */ -#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T -#endif /* MORECORE_CANNOT_TRIM */ -#endif /* DEFAULT_TRIM_THRESHOLD */ -#ifndef DEFAULT_MMAP_THRESHOLD -#if HAVE_MMAP -#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U) -#else /* HAVE_MMAP */ -#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T -#endif /* HAVE_MMAP */ -#endif /* DEFAULT_MMAP_THRESHOLD */ -#ifndef MAX_RELEASE_CHECK_RATE -#if HAVE_MMAP -#define MAX_RELEASE_CHECK_RATE 4095 -#else -#define MAX_RELEASE_CHECK_RATE MAX_SIZE_T -#endif /* HAVE_MMAP */ -#endif /* MAX_RELEASE_CHECK_RATE */ -#ifndef USE_BUILTIN_FFS -#define USE_BUILTIN_FFS 0 -#endif /* USE_BUILTIN_FFS */ -#ifndef USE_DEV_RANDOM -#define USE_DEV_RANDOM 0 -#endif /* USE_DEV_RANDOM */ -#ifndef NO_MALLINFO -#define NO_MALLINFO 0 -#endif /* NO_MALLINFO */ -#ifndef MALLINFO_FIELD_TYPE -#define MALLINFO_FIELD_TYPE size_t -#endif /* MALLINFO_FIELD_TYPE */ -#ifndef NO_MALLOC_STATS -#define NO_MALLOC_STATS 0 -#endif /* NO_MALLOC_STATS */ -#ifndef NO_SEGMENT_TRAVERSAL -#define NO_SEGMENT_TRAVERSAL 0 -#endif /* NO_SEGMENT_TRAVERSAL */ - -/* - mallopt tuning options. SVID/XPG defines four standard parameter - numbers for mallopt, normally defined in malloc.h. None of these - are used in this malloc, so setting them has no effect. But this - malloc does support the following options. -*/ - -#define M_TRIM_THRESHOLD (-1) -#define M_GRANULARITY (-2) -#define M_MMAP_THRESHOLD (-3) - -/* ------------------------ Mallinfo declarations ------------------------ */ - -#if !NO_MALLINFO -/* - This version of malloc supports the standard SVID/XPG mallinfo - routine that returns a struct containing usage properties and - statistics. It should work on any system that has a - /usr/include/malloc.h defining struct mallinfo. The main - declaration needed is the mallinfo struct that is returned (by-copy) - by mallinfo(). The malloinfo struct contains a bunch of fields that - are not even meaningful in this version of malloc. These fields are - are instead filled by mallinfo() with other numbers that might be of - interest. - - HAVE_USR_INCLUDE_MALLOC_H should be set if you have a - /usr/include/malloc.h file that includes a declaration of struct - mallinfo. If so, it is included; else a compliant version is - declared below. These must be precisely the same for mallinfo() to - work. The original SVID version of this struct, defined on most - systems with mallinfo, declares all fields as ints. But some others - define as unsigned long. If your system defines the fields using a - type of different width than listed here, you MUST #include your - system version and #define HAVE_USR_INCLUDE_MALLOC_H. -*/ - -/* #define HAVE_USR_INCLUDE_MALLOC_H */ - -#ifdef HAVE_USR_INCLUDE_MALLOC_H -#include "/usr/include/malloc.h" -#else /* HAVE_USR_INCLUDE_MALLOC_H */ -#ifndef STRUCT_MALLINFO_DECLARED -/* HP-UX (and others?) redefines mallinfo unless _STRUCT_MALLINFO is defined */ -#define _STRUCT_MALLINFO -#define STRUCT_MALLINFO_DECLARED 1 -struct mallinfo { - MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ - MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ - MALLINFO_FIELD_TYPE smblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ - MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ - MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ - MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ - MALLINFO_FIELD_TYPE fordblks; /* total free space */ - MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ -}; -#endif /* STRUCT_MALLINFO_DECLARED */ -#endif /* HAVE_USR_INCLUDE_MALLOC_H */ -#endif /* NO_MALLINFO */ - -/* - Try to persuade compilers to inline. The most critical functions for - inlining are defined as macros, so these aren't used for them. -*/ - -#ifndef FORCEINLINE - #if defined(__GNUC__) -#define FORCEINLINE __inline __attribute__ ((always_inline)) - #elif defined(_MSC_VER) - #define FORCEINLINE __forceinline - #endif -#endif -#ifndef NOINLINE - #if defined(__GNUC__) - #define NOINLINE __attribute__ ((noinline)) - #elif defined(_MSC_VER) - #define NOINLINE __declspec(noinline) - #else - #define NOINLINE - #endif -#endif - -#ifdef __cplusplus -extern "C" { -#ifndef FORCEINLINE - #define FORCEINLINE inline -#endif -#endif /* __cplusplus */ -#ifndef FORCEINLINE - #define FORCEINLINE -#endif - -#if !ONLY_MSPACES - -/* ------------------- Declarations of public routines ------------------- */ - -#ifndef USE_DL_PREFIX -#define dlcalloc calloc -#define dlfree free -#define dlmalloc malloc -#define dlmemalign aligned_alloc -#define dlposix_memalign posix_memalign -#define dlrealloc realloc -#define dlrealloc_in_place realloc_in_place -#define dlvalloc valloc -#define dlpvalloc pvalloc -#define dlmallinfo mallinfo -#define dlmallopt mallopt -#define dlmalloc_trim malloc_trim -#define dlmalloc_stats malloc_stats -#define dlmalloc_usable_size malloc_usable_size -#define dlmalloc_footprint malloc_footprint -#define dlmalloc_max_footprint malloc_max_footprint -#define dlmalloc_footprint_limit malloc_footprint_limit -#define dlmalloc_set_footprint_limit malloc_set_footprint_limit -#define dlmalloc_inspect_all malloc_inspect_all -#define dlindependent_calloc independent_calloc -#define dlindependent_comalloc independent_comalloc -#define dlbulk_free bulk_free -#endif /* USE_DL_PREFIX */ - -#if 0 // Redeclaration warnings as PDCLib already declares these in - -/* - malloc(size_t n) - Returns a pointer to a newly allocated chunk of at least n bytes, or - null if no space is available, in which case errno is set to ENOMEM - on ANSI C systems. - - If n is zero, malloc returns a minimum-sized chunk. (The minimum - size is 16 bytes on most 32bit systems, and 32 bytes on 64bit - systems.) Note that size_t is an unsigned type, so calls with - arguments that would be negative if signed are interpreted as - requests for huge amounts of space, which will often fail. The - maximum supported value of n differs across systems, but is in all - cases less than the maximum representable value of a size_t. -*/ -DLMALLOC_EXPORT void* dlmalloc(size_t); - -/* - free(void* p) - Releases the chunk of memory pointed to by p, that had been previously - allocated using malloc or a related routine such as realloc. - It has no effect if p is null. If p was not malloced or already - freed, free(p) will by default cause the current program to abort. -*/ -DLMALLOC_EXPORT void dlfree(void*); - -/* - calloc(size_t n_elements, size_t element_size); - Returns a pointer to n_elements * element_size bytes, with all locations - set to zero. -*/ -DLMALLOC_EXPORT void* dlcalloc(size_t, size_t); - -/* - realloc(void* p, size_t n) - Returns a pointer to a chunk of size n that contains the same data - as does chunk p up to the minimum of (n, p's size) bytes, or null - if no space is available. - - The returned pointer may or may not be the same as p. The algorithm - prefers extending p in most cases when possible, otherwise it - employs the equivalent of a malloc-copy-free sequence. - - If p is null, realloc is equivalent to malloc. - - If space is not available, realloc returns null, errno is set (if on - ANSI) and p is NOT freed. - - if n is for fewer bytes than already held by p, the newly unused - space is lopped off and freed if possible. realloc with a size - argument of zero (re)allocates a minimum-sized chunk. - - The old unix realloc convention of allowing the last-free'd chunk - to be used as an argument to realloc is not supported. -*/ -DLMALLOC_EXPORT void* dlrealloc(void*, size_t); - -#endif - -/* - realloc_in_place(void* p, size_t n) - Resizes the space allocated for p to size n, only if this can be - done without moving p (i.e., only if there is adjacent space - available if n is greater than p's current allocated size, or n is - less than or equal to p's size). This may be used instead of plain - realloc if an alternative allocation strategy is needed upon failure - to expand space; for example, reallocation of a buffer that must be - memory-aligned or cleared. You can use realloc_in_place to trigger - these alternatives only when needed. - - Returns p if successful; otherwise null. -*/ -DLMALLOC_EXPORT void* dlrealloc_in_place(void*, size_t); - -#if 0 // Redeclaration warnings as PDCLib already declares these in - -/* - memalign(size_t alignment, size_t n); - Returns a pointer to a newly allocated chunk of n bytes, aligned - in accord with the alignment argument. - - The alignment argument should be a power of two. If the argument is - not a power of two, the nearest greater power is used. - 8-byte alignment is guaranteed by normal malloc calls, so don't - bother calling memalign with an argument of 8 or less. - - Overreliance on memalign is a sure way to fragment space. -*/ -DLMALLOC_EXPORT void* dlmemalign(size_t, size_t); - -#endif - -/* - int posix_memalign(void** pp, size_t alignment, size_t n); - Allocates a chunk of n bytes, aligned in accord with the alignment - argument. Differs from memalign only in that it (1) assigns the - allocated memory to *pp rather than returning it, (2) fails and - returns EINVAL if the alignment is not a power of two (3) fails and - returns ENOMEM if memory cannot be allocated. -*/ -DLMALLOC_EXPORT int dlposix_memalign(void**, size_t, size_t); - -/* - valloc(size_t n); - Equivalent to memalign(pagesize, n), where pagesize is the page - size of the system. If the pagesize is unknown, 4096 is used. -*/ -DLMALLOC_EXPORT void* dlvalloc(size_t); - -/* - mallopt(int parameter_number, int parameter_value) - Sets tunable parameters The format is to provide a - (parameter-number, parameter-value) pair. mallopt then sets the - corresponding parameter to the argument value if it can (i.e., so - long as the value is meaningful), and returns 1 if successful else - 0. To workaround the fact that mallopt is specified to use int, - not size_t parameters, the value -1 is specially treated as the - maximum unsigned size_t value. - - SVID/XPG/ANSI defines four standard param numbers for mallopt, - normally defined in malloc.h. None of these are use in this malloc, - so setting them has no effect. But this malloc also supports other - options in mallopt. See below for details. Briefly, supported - parameters are as follows (listed defaults are for "typical" - configurations). - - Symbol param # default allowed param values - M_TRIM_THRESHOLD -1 2*1024*1024 any (-1 disables) - M_GRANULARITY -2 page size any power of 2 >= page size - M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) -*/ -DLMALLOC_EXPORT int dlmallopt(int, int); - -/* - malloc_footprint(); - Returns the number of bytes obtained from the system. The total - number of bytes allocated by malloc, realloc etc., is less than this - value. Unlike mallinfo, this function returns only a precomputed - result, so can be called frequently to monitor memory consumption. - Even if locks are otherwise defined, this function does not use them, - so results might not be up to date. -*/ -DLMALLOC_EXPORT size_t dlmalloc_footprint(void); - -/* - malloc_max_footprint(); - Returns the maximum number of bytes obtained from the system. This - value will be greater than current footprint if deallocated space - has been reclaimed by the system. The peak number of bytes allocated - by malloc, realloc etc., is less than this value. Unlike mallinfo, - this function returns only a precomputed result, so can be called - frequently to monitor memory consumption. Even if locks are - otherwise defined, this function does not use them, so results might - not be up to date. -*/ -DLMALLOC_EXPORT size_t dlmalloc_max_footprint(void); - -/* - malloc_footprint_limit(); - Returns the number of bytes that the heap is allowed to obtain from - the system, returning the last value returned by - malloc_set_footprint_limit, or the maximum size_t value if - never set. The returned value reflects a permission. There is no - guarantee that this number of bytes can actually be obtained from - the system. -*/ -DLMALLOC_EXPORT size_t dlmalloc_footprint_limit(void); - -/* - malloc_set_footprint_limit(); - Sets the maximum number of bytes to obtain from the system, causing - failure returns from malloc and related functions upon attempts to - exceed this value. The argument value may be subject to page - rounding to an enforceable limit; this actual value is returned. - Using an argument of the maximum possible size_t effectively - disables checks. If the argument is less than or equal to the - current malloc_footprint, then all future allocations that require - additional system memory will fail. However, invocation cannot - retroactively deallocate existing used memory. -*/ -DLMALLOC_EXPORT size_t dlmalloc_set_footprint_limit(size_t bytes); - -#if MALLOC_INSPECT_ALL -/* - malloc_inspect_all(void(*handler)(void *start, - void *end, - size_t used_bytes, - void* callback_arg), - void* arg); - Traverses the heap and calls the given handler for each managed - region, skipping all bytes that are (or may be) used for bookkeeping - purposes. Traversal does not include include chunks that have been - directly memory mapped. Each reported region begins at the start - address, and continues up to but not including the end address. The - first used_bytes of the region contain allocated data. If - used_bytes is zero, the region is unallocated. The handler is - invoked with the given callback argument. If locks are defined, they - are held during the entire traversal. It is a bad idea to invoke - other malloc functions from within the handler. - - For example, to count the number of in-use chunks with size greater - than 1000, you could write: - static int count = 0; - void count_chunks(void* start, void* end, size_t used, void* arg) { - if (used >= 1000) ++count; - } - then: - malloc_inspect_all(count_chunks, NULL); - - malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined. -*/ -DLMALLOC_EXPORT void dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*), - void* arg); - -#endif /* MALLOC_INSPECT_ALL */ - -#if !NO_MALLINFO -/* - mallinfo() - Returns (by copy) a struct containing various summary statistics: - - arena: current total non-mmapped bytes allocated from system - ordblks: the number of free chunks - smblks: always zero. - hblks: current number of mmapped regions - hblkhd: total bytes held in mmapped regions - usmblks: the maximum total allocated space. This will be greater - than current total if trimming has occurred. - fsmblks: always zero - uordblks: current total allocated space (normal or mmapped) - fordblks: total free space - keepcost: the maximum number of bytes that could ideally be released - back to system via malloc_trim. ("ideally" means that - it ignores page restrictions etc.) - - Because these fields are ints, but internal bookkeeping may - be kept as longs, the reported values may wrap around zero and - thus be inaccurate. -*/ -DLMALLOC_EXPORT struct mallinfo dlmallinfo(void); -#endif /* NO_MALLINFO */ - -/* - independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); - - independent_calloc is similar to calloc, but instead of returning a - single cleared space, it returns an array of pointers to n_elements - independent elements that can hold contents of size elem_size, each - of which starts out cleared, and can be independently freed, - realloc'ed etc. The elements are guaranteed to be adjacently - allocated (this is not guaranteed to occur with multiple callocs or - mallocs), which may also improve cache locality in some - applications. - - The "chunks" argument is optional (i.e., may be null, which is - probably the most typical usage). If it is null, the returned array - is itself dynamically allocated and should also be freed when it is - no longer needed. Otherwise, the chunks array must be of at least - n_elements in length. It is filled in with the pointers to the - chunks. - - In either case, independent_calloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and "chunks" - is null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be freed when it is no longer needed. This can be - done all at once using bulk_free. - - independent_calloc simplifies and speeds up implementations of many - kinds of pools. It may also be useful when constructing large data - structures that initially have a fixed number of fixed-sized nodes, - but the number is not known at compile time, and some of the nodes - may later need to be freed. For example: - - struct Node { int item; struct Node* next; }; - - struct Node* build_list() { - struct Node** pool; - int n = read_number_of_nodes_needed(); - if (n <= 0) return 0; - pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); - if (pool == 0) die(); - // organize into a linked list... - struct Node* first = pool[0]; - for (i = 0; i < n-1; ++i) - pool[i]->next = pool[i+1]; - free(pool); // Can now free the array (or not, if it is needed later) - return first; - } -*/ -DLMALLOC_EXPORT void** dlindependent_calloc(size_t, size_t, void**); - -/* - independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); - - independent_comalloc allocates, all at once, a set of n_elements - chunks with sizes indicated in the "sizes" array. It returns - an array of pointers to these elements, each of which can be - independently freed, realloc'ed etc. The elements are guaranteed to - be adjacently allocated (this is not guaranteed to occur with - multiple callocs or mallocs), which may also improve cache locality - in some applications. - - The "chunks" argument is optional (i.e., may be null). If it is null - the returned array is itself dynamically allocated and should also - be freed when it is no longer needed. Otherwise, the chunks array - must be of at least n_elements in length. It is filled in with the - pointers to the chunks. - - In either case, independent_comalloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and chunks is - null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be freed when it is no longer needed. This can be - done all at once using bulk_free. - - independent_comallac differs from independent_calloc in that each - element may have a different size, and also that it does not - automatically clear elements. - - independent_comalloc can be used to speed up allocation in cases - where several structs or objects must always be allocated at the - same time. For example: - - struct Head { ... } - struct Foot { ... } - - void send_message(char* msg) { - int msglen = strlen(msg); - size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; - void* chunks[3]; - if (independent_comalloc(3, sizes, chunks) == 0) - die(); - struct Head* head = (struct Head*)(chunks[0]); - char* body = (char*)(chunks[1]); - struct Foot* foot = (struct Foot*)(chunks[2]); - // ... - } - - In general though, independent_comalloc is worth using only for - larger values of n_elements. For small values, you probably won't - detect enough difference from series of malloc calls to bother. - - Overuse of independent_comalloc can increase overall memory usage, - since it cannot reuse existing noncontiguous small chunks that - might be available for some of the elements. -*/ -DLMALLOC_EXPORT void** dlindependent_comalloc(size_t, size_t*, void**); - -/* - bulk_free(void* array[], size_t n_elements) - Frees and clears (sets to null) each non-null pointer in the given - array. This is likely to be faster than freeing them one-by-one. - If footers are used, pointers that have been allocated in different - mspaces are not freed or cleared, and the count of all such pointers - is returned. For large arrays of pointers with poor locality, it - may be worthwhile to sort this array before calling bulk_free. -*/ -DLMALLOC_EXPORT size_t dlbulk_free(void**, size_t n_elements); - -/* - pvalloc(size_t n); - Equivalent to valloc(minimum-page-that-holds(n)), that is, - round up n to nearest pagesize. - */ -DLMALLOC_EXPORT void* dlpvalloc(size_t); - -/* - malloc_trim(size_t pad); - - If possible, gives memory back to the system (via negative arguments - to sbrk) if there is unused memory at the `high' end of the malloc - pool or in unused MMAP segments. You can call this after freeing - large blocks of memory to potentially reduce the system-level memory - requirements of a program. However, it cannot guarantee to reduce - memory. Under some allocation patterns, some large free blocks of - memory will be locked between two used chunks, so they cannot be - given back to the system. - - The `pad' argument to malloc_trim represents the amount of free - trailing space to leave untrimmed. If this argument is zero, only - the minimum amount of memory to maintain internal data structures - will be left. Non-zero arguments can be supplied to maintain enough - trailing space to service future expected allocations without having - to re-obtain memory from the system. - - Malloc_trim returns 1 if it actually released any memory, else 0. -*/ -DLMALLOC_EXPORT int dlmalloc_trim(size_t); - -/* - malloc_stats(); - Prints on stderr the amount of space obtained from the system (both - via sbrk and mmap), the maximum amount (which may be more than - current if malloc_trim and/or munmap got called), and the current - number of bytes allocated via malloc (or realloc, etc) but not yet - freed. Note that this is the number of bytes allocated, not the - number requested. It will be larger than the number requested - because of alignment and bookkeeping overhead. Because it includes - alignment wastage as being in use, this figure may be greater than - zero even when no user-level chunks are allocated. - - The reported current and maximum system memory can be inaccurate if - a program makes other calls to system memory allocation functions - (normally sbrk) outside of malloc. - - malloc_stats prints only the most commonly interesting statistics. - More information can be obtained by calling mallinfo. -*/ -DLMALLOC_EXPORT void dlmalloc_stats(void); - -#endif /* ONLY_MSPACES */ - -/* - malloc_usable_size(void* p); - - Returns the number of bytes you can actually use in - an allocated chunk, which may be more than you requested (although - often not) due to alignment and minimum size constraints. - You can use this many bytes without worrying about - overwriting other allocated objects. This is not a particularly great - programming practice. malloc_usable_size can be more useful in - debugging and assertions, for example: - - p = malloc(n); - assert(malloc_usable_size(p) >= 256); -*/ -size_t dlmalloc_usable_size(void*); - -#if MSPACES - -/* - mspace is an opaque type representing an independent - region of space that supports mspace_malloc, etc. -*/ -typedef void* mspace; - -/* - create_mspace creates and returns a new independent space with the - given initial capacity, or, if 0, the default granularity size. It - returns null if there is no system memory available to create the - space. If argument locked is non-zero, the space uses a separate - lock to control access. The capacity of the space will grow - dynamically as needed to service mspace_malloc requests. You can - control the sizes of incremental increases of this space by - compiling with a different DEFAULT_GRANULARITY or dynamically - setting with mallopt(M_GRANULARITY, value). -*/ -DLMALLOC_EXPORT mspace create_mspace(size_t capacity, int locked); - -/* - destroy_mspace destroys the given space, and attempts to return all - of its memory back to the system, returning the total number of - bytes freed. After destruction, the results of access to all memory - used by the space become undefined. -*/ -DLMALLOC_EXPORT size_t destroy_mspace(mspace msp); - -/* - create_mspace_with_base uses the memory supplied as the initial base - of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this - space is used for bookkeeping, so the capacity must be at least this - large. (Otherwise 0 is returned.) When this initial space is - exhausted, additional memory will be obtained from the system. - Destroying this space will deallocate all additionally allocated - space (if possible) but not the initial base. -*/ -DLMALLOC_EXPORT mspace create_mspace_with_base(void* base, size_t capacity, int locked); - -/* - mspace_track_large_chunks controls whether requests for large chunks - are allocated in their own untracked mmapped regions, separate from - others in this mspace. By default large chunks are not tracked, - which reduces fragmentation. However, such chunks are not - necessarily released to the system upon destroy_mspace. Enabling - tracking by setting to true may increase fragmentation, but avoids - leakage when relying on destroy_mspace to release all memory - allocated using this space. The function returns the previous - setting. -*/ -DLMALLOC_EXPORT int mspace_track_large_chunks(mspace msp, int enable); - - -/* - mspace_malloc behaves as malloc, but operates within - the given space. -*/ -DLMALLOC_EXPORT void* mspace_malloc(mspace msp, size_t bytes); - -/* - mspace_free behaves as free, but operates within - the given space. - - If compiled with FOOTERS==1, mspace_free is not actually needed. - free may be called instead of mspace_free because freed chunks from - any space are handled by their originating spaces. -*/ -DLMALLOC_EXPORT void mspace_free(mspace msp, void* mem); - -/* - mspace_realloc behaves as realloc, but operates within - the given space. - - If compiled with FOOTERS==1, mspace_realloc is not actually - needed. realloc may be called instead of mspace_realloc because - realloced chunks from any space are handled by their originating - spaces. -*/ -DLMALLOC_EXPORT void* mspace_realloc(mspace msp, void* mem, size_t newsize); - -/* - mspace_calloc behaves as calloc, but operates within - the given space. -*/ -DLMALLOC_EXPORT void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); - -/* - mspace_memalign behaves as memalign, but operates within - the given space. -*/ -DLMALLOC_EXPORT void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); - -/* - mspace_independent_calloc behaves as independent_calloc, but - operates within the given space. -*/ -DLMALLOC_EXPORT void** mspace_independent_calloc(mspace msp, size_t n_elements, - size_t elem_size, void* chunks[]); - -/* - mspace_independent_comalloc behaves as independent_comalloc, but - operates within the given space. -*/ -DLMALLOC_EXPORT void** mspace_independent_comalloc(mspace msp, size_t n_elements, - size_t sizes[], void* chunks[]); - -/* - mspace_footprint() returns the number of bytes obtained from the - system for this space. -*/ -DLMALLOC_EXPORT size_t mspace_footprint(mspace msp); - -/* - mspace_max_footprint() returns the peak number of bytes obtained from the - system for this space. -*/ -DLMALLOC_EXPORT size_t mspace_max_footprint(mspace msp); - - -#if !NO_MALLINFO -/* - mspace_mallinfo behaves as mallinfo, but reports properties of - the given space. -*/ -DLMALLOC_EXPORT struct mallinfo mspace_mallinfo(mspace msp); -#endif /* NO_MALLINFO */ - -/* - malloc_usable_size(void* p) behaves the same as malloc_usable_size; -*/ -DLMALLOC_EXPORT size_t mspace_usable_size(void* mem); - -/* - mspace_malloc_stats behaves as malloc_stats, but reports - properties of the given space. -*/ -DLMALLOC_EXPORT void mspace_malloc_stats(mspace msp); - -/* - mspace_trim behaves as malloc_trim, but - operates within the given space. -*/ -DLMALLOC_EXPORT int mspace_trim(mspace msp, size_t pad); - -/* - An alias for mallopt. -*/ -DLMALLOC_EXPORT int mspace_mallopt(int, int); - -#endif /* MSPACES */ - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -/* - ======================================================================== - To make a fully customizable malloc.h header file, cut everything - above this line, put into file malloc.h, edit to suit, and #include it - on the next line, as well as in programs that use this malloc. - ======================================================================== -*/ - -/* #include "malloc.h" */ - -/*------------------------------ internal #includes ---------------------- */ - -#ifdef _MSC_VER -#pragma warning( disable : 4146 ) /* no "unsigned" warnings */ -#endif /* _MSC_VER */ -#if !NO_MALLOC_STATS -#include /* for printing in malloc_stats */ -#endif /* NO_MALLOC_STATS */ -#ifndef LACKS_ERRNO_H -#include /* for MALLOC_FAILURE_ACTION */ -#endif /* LACKS_ERRNO_H */ -#ifdef DEBUG -#if ABORT_ON_ASSERT_FAILURE -#undef assert -#define assert(x) if(!(x)) ABORT -#else /* ABORT_ON_ASSERT_FAILURE */ -#include -#endif /* ABORT_ON_ASSERT_FAILURE */ -#else /* DEBUG */ -#ifndef assert -#define assert(x) -#endif -#define DEBUG 0 -#endif /* DEBUG */ -#if !defined(WIN32) && !defined(LACKS_TIME_H) -#include /* for magic initialization */ -#endif /* WIN32 */ -#ifndef LACKS_STDLIB_H -#include /* for abort() */ -#endif /* LACKS_STDLIB_H */ -#ifndef LACKS_STRING_H -#include /* for memset etc */ -#endif /* LACKS_STRING_H */ -#if USE_BUILTIN_FFS -#ifndef LACKS_STRINGS_H -#include /* for ffs */ -#endif /* LACKS_STRINGS_H */ -#endif /* USE_BUILTIN_FFS */ -#if HAVE_MMAP -#ifndef LACKS_SYS_MMAN_H -/* On some versions of linux, mremap decl in mman.h needs __USE_GNU set */ -#if (defined(linux) && !defined(__USE_GNU)) -#define __USE_GNU 1 -#include /* for mmap */ -#undef __USE_GNU -#else -#include /* for mmap */ -#endif /* linux */ -#endif /* LACKS_SYS_MMAN_H */ -#ifndef LACKS_FCNTL_H -#include -#endif /* LACKS_FCNTL_H */ -#endif /* HAVE_MMAP */ -#ifndef LACKS_UNISTD_H -#include /* for sbrk, sysconf */ -#else /* LACKS_UNISTD_H */ -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) -/*extern void* sbrk(ptrdiff_t);*/ -#endif /* FreeBSD etc */ -#endif /* LACKS_UNISTD_H */ - -/* Declarations for locking */ -#if USE_LOCKS -#ifndef WIN32 -#if defined (__SVR4) && defined (__sun) /* solaris */ -#include -#elif !defined(LACKS_SCHED_H) -#include -#endif /* solaris or LACKS_SCHED_H */ -#if (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0) || !USE_SPIN_LOCKS -/*#include */ -#endif /* USE_RECURSIVE_LOCKS ... */ -#elif defined(_MSC_VER) -#ifndef _M_AMD64 -/* These are already defined on AMD64 builds */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ -LONG __cdecl _InterlockedCompareExchange(LONG volatile *Dest, LONG Exchange, LONG Comp); -LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value); -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _M_AMD64 */ -#pragma intrinsic (_InterlockedCompareExchange) -#pragma intrinsic (_InterlockedExchange) -#define interlockedcompareexchange _InterlockedCompareExchange -#define interlockedexchange _InterlockedExchange -#elif defined(WIN32) && defined(__GNUC__) -#define interlockedcompareexchange(a, b, c) __sync_val_compare_and_swap(a, c, b) -#define interlockedexchange __sync_lock_test_and_set -#endif /* Win32 */ -#endif /* USE_LOCKS */ - -/* Declarations for bit scanning on win32 */ -#if defined(_MSC_VER) && _MSC_VER>=1300 -#ifndef BitScanForward /* Try to avoid pulling in WinNT.h */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ -unsigned char _BitScanForward(unsigned long *index, unsigned long mask); -unsigned char _BitScanReverse(unsigned long *index, unsigned long mask); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#define BitScanForward _BitScanForward -#define BitScanReverse _BitScanReverse -#pragma intrinsic(_BitScanForward) -#pragma intrinsic(_BitScanReverse) -#endif /* BitScanForward */ -#endif /* defined(_MSC_VER) && _MSC_VER>=1300 */ - -#ifndef WIN32 -#ifndef malloc_getpagesize -# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ -# ifndef _SC_PAGE_SIZE -# define _SC_PAGE_SIZE _SC_PAGESIZE -# endif -# endif -# ifdef _SC_PAGE_SIZE -# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) -# else -# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) - extern size_t getpagesize(); -# define malloc_getpagesize getpagesize() -# else -# ifdef WIN32 /* use supplied emulation of getpagesize */ -# define malloc_getpagesize getpagesize() -# else -# ifndef LACKS_SYS_PARAM_H -# include -# endif -# ifdef EXEC_PAGESIZE -# define malloc_getpagesize EXEC_PAGESIZE -# else -# ifdef NBPG -# ifndef CLSIZE -# define malloc_getpagesize NBPG -# else -# define malloc_getpagesize (NBPG * CLSIZE) -# endif -# else -# ifdef NBPC -# define malloc_getpagesize NBPC -# else -# ifdef PAGESIZE -# define malloc_getpagesize PAGESIZE -# else /* just guess */ -# define malloc_getpagesize ((size_t)4096U) -# endif -# endif -# endif -# endif -# endif -# endif -# endif -#endif -#endif - -/* ------------------- size_t and alignment properties -------------------- */ - -/* The byte and bit size of a size_t */ -#define SIZE_T_SIZE (sizeof(size_t)) -#define SIZE_T_BITSIZE (sizeof(size_t) << 3) - -/* Some constants coerced to size_t */ -/* Annoying but necessary to avoid errors on some platforms */ -#define SIZE_T_ZERO ((size_t)0) -#define SIZE_T_ONE ((size_t)1) -#define SIZE_T_TWO ((size_t)2) -#define SIZE_T_FOUR ((size_t)4) -#define TWO_SIZE_T_SIZES (SIZE_T_SIZE<<1) -#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE<<2) -#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES) -#define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U) - -/* The bit mask value corresponding to MALLOC_ALIGNMENT */ -#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) - -/* True if address a has acceptable alignment */ -#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0) - -/* the number of bytes to offset an address to align it */ -#define align_offset(A)\ - ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\ - ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK)) - -/* -------------------------- MMAP preliminaries ------------------------- */ - -/* - If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and - checks to fail so compiler optimizer can delete code rather than - using so many "#if"s. -*/ - - -/* MORECORE and MMAP must return MFAIL on failure */ -#define MFAIL ((void*)(MAX_SIZE_T)) -#define CMFAIL ((char*)(MFAIL)) /* defined for convenience */ - -#if HAVE_MMAP - -#ifdef MMAP_DEFAULT -#elif !defined(WIN32) -#define MUNMAP_DEFAULT(a, s) munmap((a), (s)) -#define MMAP_PROT (PROT_READ|PROT_WRITE) -#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) -#define MAP_ANONYMOUS MAP_ANON -#endif /* MAP_ANON */ -#ifdef MAP_ANONYMOUS -#define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) -#define MMAP_DEFAULT(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) -#else /* MAP_ANONYMOUS */ -/* - Nearly all versions of mmap support MAP_ANONYMOUS, so the following - is unlikely to be needed, but is supplied just in case. -*/ -#define MMAP_FLAGS (MAP_PRIVATE) -#define MMAP_DEFAULT(s) ((dev_zero_fd < 0) ? \ - (dev_zero_fd = open("/dev/zero", O_RDWR), \ - mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \ - mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) -#endif /* MAP_ANONYMOUS */ - -#define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s) - -#else /* WIN32 */ - -/* Win32 MMAP via VirtualAlloc */ -static FORCEINLINE void* win32mmap(size_t size) { - void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); - return (ptr != 0)? ptr: MFAIL; -} - -/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ -static FORCEINLINE void* win32direct_mmap(size_t size) { - void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, - PAGE_READWRITE); - return (ptr != 0)? ptr: MFAIL; -} - -/* This function supports releasing coalesed segments */ -static FORCEINLINE int win32munmap(void* ptr, size_t size) { - MEMORY_BASIC_INFORMATION minfo; - char* cptr = (char*)ptr; - while (size) { - if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0) - return -1; - if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr || - minfo.State != MEM_COMMIT || minfo.RegionSize > size) - return -1; - if (VirtualFree(cptr, 0, MEM_RELEASE) == 0) - return -1; - cptr += minfo.RegionSize; - size -= minfo.RegionSize; - } - return 0; -} - -#define MMAP_DEFAULT(s) win32mmap(s) -#define MUNMAP_DEFAULT(a, s) win32munmap((a), (s)) -#define DIRECT_MMAP_DEFAULT(s) win32direct_mmap(s) -#endif /* WIN32 */ -#endif /* HAVE_MMAP */ - -#if HAVE_MREMAP && !defined(MREMAP_DEFAULT) -#ifndef WIN32 -#define MREMAP_DEFAULT(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv)) -#endif /* WIN32 */ -#endif /* HAVE_MREMAP */ - -/** - * Define CALL_MORECORE - */ -#if HAVE_MORECORE - #ifdef MORECORE - #define CALL_MORECORE(S) MORECORE(S) - #else /* MORECORE */ - #define CALL_MORECORE(S) MORECORE_DEFAULT(S) - #endif /* MORECORE */ -#else /* HAVE_MORECORE */ - #define CALL_MORECORE(S) MFAIL -#endif /* HAVE_MORECORE */ - -/** - * Define CALL_MMAP/CALL_MUNMAP/CALL_DIRECT_MMAP - */ -#if HAVE_MMAP - #define USE_MMAP_BIT (SIZE_T_ONE) - - #ifdef MMAP - #define CALL_MMAP(s) MMAP(s) - #else /* MMAP */ - #define CALL_MMAP(s) MMAP_DEFAULT(s) - #endif /* MMAP */ - #ifdef MUNMAP - #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) - #else /* MUNMAP */ - #define CALL_MUNMAP(a, s) MUNMAP_DEFAULT((a), (s)) - #endif /* MUNMAP */ - #ifdef DIRECT_MMAP - #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) - #else /* DIRECT_MMAP */ - #define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s) - #endif /* DIRECT_MMAP */ -#else /* HAVE_MMAP */ - #define USE_MMAP_BIT (SIZE_T_ZERO) - - #define MMAP(s) MFAIL - #define MUNMAP(a, s) (-1) - #define DIRECT_MMAP(s) MFAIL - #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) - #define CALL_MMAP(s) MMAP(s) - #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) -#endif /* HAVE_MMAP */ - -/** - * Define CALL_MREMAP - */ -#if HAVE_MMAP && HAVE_MREMAP - #ifdef MREMAP - #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv)) - #else /* MREMAP */ - #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv)) - #endif /* MREMAP */ -#else /* HAVE_MMAP && HAVE_MREMAP */ - #define CALL_MREMAP(addr, osz, nsz, mv) MFAIL -#endif /* HAVE_MMAP && HAVE_MREMAP */ - -/* mstate bit set if continguous morecore disabled or failed */ -#define USE_NONCONTIGUOUS_BIT (4U) - -/* segment bit set in create_mspace_with_base */ -#define EXTERN_BIT (8U) - - -/* --------------------------- Lock preliminaries ------------------------ */ - -/* - When locks are defined, there is one global lock, plus - one per-mspace lock. - - The global lock_ensures that mparams.magic and other unique - mparams values are initialized only once. It also protects - sequences of calls to MORECORE. In many cases sys_alloc requires - two calls, that should not be interleaved with calls by other - threads. This does not protect against direct calls to MORECORE - by other threads not using this lock, so there is still code to - cope the best we can on interference. - - Per-mspace locks surround calls to malloc, free, etc. - By default, locks are simple non-reentrant mutexes. - - Because lock-protected regions generally have bounded times, it is - OK to use the supplied simple spinlocks. Spinlocks are likely to - improve performance for lightly contended applications, but worsen - performance under heavy contention. - - If USE_LOCKS is > 1, the definitions of lock routines here are - bypassed, in which case you will need to define the type MLOCK_T, - and at least INITIAL_LOCK, DESTROY_LOCK, ACQUIRE_LOCK, RELEASE_LOCK - and TRY_LOCK. You must also declare a - static MLOCK_T malloc_global_mutex = { initialization values };. - -*/ - -#if !USE_LOCKS -#define USE_LOCK_BIT (0U) -#define INITIAL_LOCK(l) (0) -#define DESTROY_LOCK(l) (0) -#define ACQUIRE_MALLOC_GLOBAL_LOCK() -#define RELEASE_MALLOC_GLOBAL_LOCK() - -#else -#if USE_LOCKS > 1 -/* ----------------------- User-defined locks ------------------------ */ -/* Define your own lock implementation here */ -/* #define INITIAL_LOCK(lk) ... */ -/* #define DESTROY_LOCK(lk) ... */ -/* #define ACQUIRE_LOCK(lk) ... */ -/* #define RELEASE_LOCK(lk) ... */ -/* #define TRY_LOCK(lk) ... */ -/* static MLOCK_T malloc_global_mutex = ... */ - -#elif USE_SPIN_LOCKS - -/* First, define CAS_LOCK and CLEAR_LOCK on ints */ -/* Note CAS_LOCK defined to return 0 on success */ - -#if defined(__GNUC__)&& (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) -#define CAS_LOCK(sl) __sync_lock_test_and_set(sl, 1) -#define CLEAR_LOCK(sl) __sync_lock_release(sl) - -#elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) -/* Custom spin locks for older gcc on x86 */ -static FORCEINLINE int x86_cas_lock(int *sl) { - int ret; - int val = 1; - int cmp = 0; - __asm__ __volatile__ ("lock; cmpxchgl %1, %2" - : "=a" (ret) - : "r" (val), "m" (*(sl)), "0"(cmp) - : "memory", "cc"); - return ret; -} - -static FORCEINLINE void x86_clear_lock(int* sl) { - assert(*sl != 0); - int prev = 0; - int ret; - __asm__ __volatile__ ("lock; xchgl %0, %1" - : "=r" (ret) - : "m" (*(sl)), "0"(prev) - : "memory"); -} - -#define CAS_LOCK(sl) x86_cas_lock(sl) -#define CLEAR_LOCK(sl) x86_clear_lock(sl) - -#else /* Win32 MSC */ -#define CAS_LOCK(sl) interlockedexchange(sl, 1) -#define CLEAR_LOCK(sl) interlockedexchange (sl, 0) - -#endif /* ... gcc spins locks ... */ - -/* How to yield for a spin lock */ -#define SPINS_PER_YIELD 63 -#if defined(_MSC_VER) -#define SLEEP_EX_DURATION 50 /* delay for yield/sleep */ -#define SPIN_LOCK_YIELD SleepEx(SLEEP_EX_DURATION, FALSE) -#elif defined (__SVR4) && defined (__sun) /* solaris */ -#define SPIN_LOCK_YIELD thr_yield(); -#elif !defined(LACKS_SCHED_H) -#define SPIN_LOCK_YIELD sched_yield(); -#else -#define SPIN_LOCK_YIELD -#endif /* ... yield ... */ - -#if !defined(USE_RECURSIVE_LOCKS) || USE_RECURSIVE_LOCKS == 0 -/* Plain spin locks use single word (embedded in malloc_states) */ -static int spin_acquire_lock(int *sl) { - int spins = 0; - while (*(volatile int *)sl != 0 || CAS_LOCK(sl)) { - if ((++spins & SPINS_PER_YIELD) == 0) { - SPIN_LOCK_YIELD; - } - } - return 0; -} - -#define MLOCK_T int -#define TRY_LOCK(sl) !CAS_LOCK(sl) -#define RELEASE_LOCK(sl) CLEAR_LOCK(sl) -#define ACQUIRE_LOCK(sl) (CAS_LOCK(sl)? spin_acquire_lock(sl) : 0) -#define INITIAL_LOCK(sl) (*sl = 0) -#define DESTROY_LOCK(sl) (0) -static MLOCK_T malloc_global_mutex = 0; - -#else /* USE_RECURSIVE_LOCKS */ -/* types for lock owners */ -#ifdef WIN32 -#define THREAD_ID_T DWORD -#define CURRENT_THREAD GetCurrentThreadId() -#define EQ_OWNER(X,Y) ((X) == (Y)) -#else -/* - Note: the following assume that pthread_t is a type that can be - initialized to (casted) zero. If this is not the case, you will need to - somehow redefine these or not use spin locks. -*/ -#define THREAD_ID_T pthread_t -#define CURRENT_THREAD pthread_self() -#define EQ_OWNER(X,Y) pthread_equal(X, Y) -#endif - -struct malloc_recursive_lock { - int sl; - unsigned int c; - THREAD_ID_T threadid; -}; - -#define MLOCK_T struct malloc_recursive_lock -static MLOCK_T malloc_global_mutex = { 0, 0, (THREAD_ID_T)0}; - -static FORCEINLINE void recursive_release_lock(MLOCK_T *lk) { - assert(lk->sl != 0); - if (--lk->c == 0) { - CLEAR_LOCK(&lk->sl); - } -} - -static FORCEINLINE int recursive_acquire_lock(MLOCK_T *lk) { - THREAD_ID_T mythreadid = CURRENT_THREAD; - int spins = 0; - for (;;) { - if (*((volatile int *)(&lk->sl)) == 0) { - if (!CAS_LOCK(&lk->sl)) { - lk->threadid = mythreadid; - lk->c = 1; - return 0; - } - } - else if (EQ_OWNER(lk->threadid, mythreadid)) { - ++lk->c; - return 0; - } - if ((++spins & SPINS_PER_YIELD) == 0) { - SPIN_LOCK_YIELD; - } - } -} - -static FORCEINLINE int recursive_try_lock(MLOCK_T *lk) { - THREAD_ID_T mythreadid = CURRENT_THREAD; - if (*((volatile int *)(&lk->sl)) == 0) { - if (!CAS_LOCK(&lk->sl)) { - lk->threadid = mythreadid; - lk->c = 1; - return 1; - } - } - else if (EQ_OWNER(lk->threadid, mythreadid)) { - ++lk->c; - return 1; - } - return 0; -} - -#define RELEASE_LOCK(lk) recursive_release_lock(lk) -#define TRY_LOCK(lk) recursive_try_lock(lk) -#define ACQUIRE_LOCK(lk) recursive_acquire_lock(lk) -#define INITIAL_LOCK(lk) ((lk)->threadid = (THREAD_ID_T)0, (lk)->sl = 0, (lk)->c = 0) -#define DESTROY_LOCK(lk) (0) -#endif /* USE_RECURSIVE_LOCKS */ - -#elif defined(WIN32) /* Win32 critical sections */ -#define MLOCK_T CRITICAL_SECTION -#define ACQUIRE_LOCK(lk) (EnterCriticalSection(lk), 0) -#define RELEASE_LOCK(lk) LeaveCriticalSection(lk) -#define TRY_LOCK(lk) TryEnterCriticalSection(lk) -#define INITIAL_LOCK(lk) (!InitializeCriticalSectionAndSpinCount((lk), 0x80000000|4000)) -#define DESTROY_LOCK(lk) (DeleteCriticalSection(lk), 0) -#define NEED_GLOBAL_LOCK_INIT - -static MLOCK_T malloc_global_mutex; -static volatile long malloc_global_mutex_status; - -/* Use spin loop to initialize global lock */ -static void init_malloc_global_mutex() { - for (;;) { - long stat = malloc_global_mutex_status; - if (stat > 0) - return; - /* transition to < 0 while initializing, then to > 0) */ - if (stat == 0 && - interlockedcompareexchange(&malloc_global_mutex_status, -1, 0) == 0) { - InitializeCriticalSection(&malloc_global_mutex); - interlockedexchange(&malloc_global_mutex_status,1); - return; - } - SleepEx(0, FALSE); - } -} - -#else /* pthreads-based locks */ -#define MLOCK_T pthread_mutex_t -#define ACQUIRE_LOCK(lk) pthread_mutex_lock(lk) -#define RELEASE_LOCK(lk) pthread_mutex_unlock(lk) -#define TRY_LOCK(lk) (!pthread_mutex_trylock(lk)) -#define INITIAL_LOCK(lk) pthread_init_lock(lk) -#define DESTROY_LOCK(lk) pthread_mutex_destroy(lk) - -#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0 && defined(linux) && !defined(PTHREAD_MUTEX_RECURSIVE) -/* Cope with old-style linux recursive lock initialization by adding */ -/* skipped internal declaration from pthread.h */ -extern int pthread_mutexattr_setkind_np __P ((pthread_mutexattr_t *__attr, - int __kind)); -#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP -#define pthread_mutexattr_settype(x,y) pthread_mutexattr_setkind_np(x,y) -#endif /* USE_RECURSIVE_LOCKS ... */ - -static MLOCK_T malloc_global_mutex = PTHREAD_MUTEX_INITIALIZER; - -static int pthread_init_lock (MLOCK_T *lk) { - pthread_mutexattr_t attr; - if (pthread_mutexattr_init(&attr)) return 1; -#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0 - if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) return 1; -#endif - if (pthread_mutex_init(lk, &attr)) return 1; - if (pthread_mutexattr_destroy(&attr)) return 1; - return 0; -} - -#endif /* ... lock types ... */ - -/* Common code for all lock types */ -#define USE_LOCK_BIT (2U) - -#ifndef ACQUIRE_MALLOC_GLOBAL_LOCK -#define ACQUIRE_MALLOC_GLOBAL_LOCK() ACQUIRE_LOCK(&malloc_global_mutex); -#endif - -#ifndef RELEASE_MALLOC_GLOBAL_LOCK -#define RELEASE_MALLOC_GLOBAL_LOCK() RELEASE_LOCK(&malloc_global_mutex); -#endif - -#endif /* USE_LOCKS */ - -/* ----------------------- Chunk representations ------------------------ */ - -/* - (The following includes lightly edited explanations by Colin Plumb.) - - The malloc_chunk declaration below is misleading (but accurate and - necessary). It declares a "view" into memory allowing access to - necessary fields at known offsets from a given base. - - Chunks of memory are maintained using a `boundary tag' method as - originally described by Knuth. (See the paper by Paul Wilson - ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such - techniques.) Sizes of free chunks are stored both in the front of - each chunk and at the end. This makes consolidating fragmented - chunks into bigger chunks fast. The head fields also hold bits - representing whether chunks are free or in use. - - Here are some pictures to make it clearer. They are "exploded" to - show that the state of a chunk can be thought of as extending from - the high 31 bits of the head field of its header through the - prev_foot and PINUSE_BIT bit of the following chunk header. - - A chunk that's in use looks like: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk (if P = 0) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| - | Size of this chunk 1| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - +- -+ - | | - +- -+ - | : - +- size - sizeof(size_t) available payload bytes -+ - : | - chunk-> +- -+ - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1| - | Size of next chunk (may or may not be in use) | +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - And if it's free, it looks like this: - - chunk-> +- -+ - | User payload (must be in use, or we would have merged!) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| - | Size of this chunk 0| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Next pointer | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Prev pointer | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | : - +- size - sizeof(struct chunk) unused bytes -+ - : | - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of this chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0| - | Size of next chunk (must be in use, or we would have merged)| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | : - +- User payload -+ - : | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |0| - +-+ - Note that since we always merge adjacent free chunks, the chunks - adjacent to a free chunk must be in use. - - Given a pointer to a chunk (which can be derived trivially from the - payload pointer) we can, in O(1) time, find out whether the adjacent - chunks are free, and if so, unlink them from the lists that they - are on and merge them with the current chunk. - - Chunks always begin on even word boundaries, so the mem portion - (which is returned to the user) is also on an even word boundary, and - thus at least double-word aligned. - - The P (PINUSE_BIT) bit, stored in the unused low-order bit of the - chunk size (which is always a multiple of two words), is an in-use - bit for the *previous* chunk. If that bit is *clear*, then the - word before the current chunk size contains the previous chunk - size, and can be used to find the front of the previous chunk. - The very first chunk allocated always has this bit set, preventing - access to non-existent (or non-owned) memory. If pinuse is set for - any given chunk, then you CANNOT determine the size of the - previous chunk, and might even get a memory addressing fault when - trying to do so. - - The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of - the chunk size redundantly records whether the current chunk is - inuse (unless the chunk is mmapped). This redundancy enables usage - checks within free and realloc, and reduces indirection when freeing - and consolidating chunks. - - Each freshly allocated chunk must have both cinuse and pinuse set. - That is, each allocated chunk borders either a previously allocated - and still in-use chunk, or the base of its memory arena. This is - ensured by making all allocations from the `lowest' part of any - found chunk. Further, no free chunk physically borders another one, - so each free chunk is known to be preceded and followed by either - inuse chunks or the ends of memory. - - Note that the `foot' of the current chunk is actually represented - as the prev_foot of the NEXT chunk. This makes it easier to - deal with alignments etc but can be very confusing when trying - to extend or adapt this code. - - The exceptions to all this are - - 1. The special chunk `top' is the top-most available chunk (i.e., - the one bordering the end of available memory). It is treated - specially. Top is never included in any bin, is used only if - no other chunk is available, and is released back to the - system if it is very large (see M_TRIM_THRESHOLD). In effect, - the top chunk is treated as larger (and thus less well - fitting) than any other available chunk. The top chunk - doesn't update its trailing size field since there is no next - contiguous chunk that would have to index off it. However, - space is still allocated for it (TOP_FOOT_SIZE) to enable - separation or merging when space is extended. - - 3. Chunks allocated via mmap, have both cinuse and pinuse bits - cleared in their head fields. Because they are allocated - one-by-one, each must carry its own prev_foot field, which is - also used to hold the offset this chunk has within its mmapped - region, which is needed to preserve alignment. Each mmapped - chunk is trailed by the first two fields of a fake next-chunk - for sake of usage checks. - -*/ - -struct malloc_chunk { - size_t prev_foot; /* Size of previous chunk (if free). */ - size_t head; /* Size and inuse bits. */ - struct malloc_chunk* fd; /* double links -- used only if free. */ - struct malloc_chunk* bk; -}; - -typedef struct malloc_chunk mchunk; -typedef struct malloc_chunk* mchunkptr; -typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */ -typedef unsigned int bindex_t; /* Described below */ -typedef unsigned int binmap_t; /* Described below */ -typedef unsigned int flag_t; /* The type of various bit flag sets */ - -/* ------------------- Chunks sizes and alignments ----------------------- */ - -#define MCHUNK_SIZE (sizeof(mchunk)) - -#if FOOTERS -#define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) -#else /* FOOTERS */ -#define CHUNK_OVERHEAD (SIZE_T_SIZE) -#endif /* FOOTERS */ - -/* MMapped chunks need a second word of overhead ... */ -#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) -/* ... and additional padding for fake next-chunk at foot */ -#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) - -/* The smallest size we can malloc is an aligned minimal chunk */ -#define MIN_CHUNK_SIZE\ - ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) - -/* conversion from malloc headers to user pointers, and back */ -#define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES)) -#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES)) -/* chunk associated with aligned address A */ -#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) - -/* Bounds on request (not chunk) sizes. */ -#define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2) -#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE) - -/* pad request bytes into a usable size */ -#define pad_request(req) \ - (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) - -/* pad request, checking for minimum (but not maximum) */ -#define request2size(req) \ - (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req)) - - -/* ------------------ Operations on head and foot fields ----------------- */ - -/* - The head field of a chunk is or'ed with PINUSE_BIT when previous - adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in - use, unless mmapped, in which case both bits are cleared. - - FLAG4_BIT is not used by this malloc, but might be useful in extensions. -*/ - -#define PINUSE_BIT (SIZE_T_ONE) -#define CINUSE_BIT (SIZE_T_TWO) -#define FLAG4_BIT (SIZE_T_FOUR) -#define INUSE_BITS (PINUSE_BIT|CINUSE_BIT) -#define FLAG_BITS (PINUSE_BIT|CINUSE_BIT|FLAG4_BIT) - -/* Head value for fenceposts */ -#define FENCEPOST_HEAD (INUSE_BITS|SIZE_T_SIZE) - -/* extraction of fields from head words */ -#define cinuse(p) ((p)->head & CINUSE_BIT) -#define pinuse(p) ((p)->head & PINUSE_BIT) -#define flag4inuse(p) ((p)->head & FLAG4_BIT) -#define is_inuse(p) (((p)->head & INUSE_BITS) != PINUSE_BIT) -#define is_mmapped(p) (((p)->head & INUSE_BITS) == 0) - -#define chunksize(p) ((p)->head & ~(FLAG_BITS)) - -#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT) -#define set_flag4(p) ((p)->head |= FLAG4_BIT) -#define clear_flag4(p) ((p)->head &= ~FLAG4_BIT) - -/* Treat space at ptr +/- offset as a chunk */ -#define chunk_plus_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) -#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s))) - -/* Ptr to next or previous physical malloc_chunk. */ -#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~FLAG_BITS))) -#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) )) - -/* extract next chunk's pinuse bit */ -#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT) - -/* Get/set size at footer */ -#define get_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot) -#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s)) - -/* Set size, pinuse bit, and foot */ -#define set_size_and_pinuse_of_free_chunk(p, s)\ - ((p)->head = (s|PINUSE_BIT), set_foot(p, s)) - -/* Set size, pinuse bit, foot, and clear next pinuse */ -#define set_free_with_pinuse(p, s, n)\ - (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s)) - -/* Get the internal overhead associated with chunk p */ -#define overhead_for(p)\ - (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) - -/* Return true if malloced space is not necessarily cleared */ -#if MMAP_CLEARS -#define calloc_must_clear(p) (!is_mmapped(p)) -#else /* MMAP_CLEARS */ -#define calloc_must_clear(p) (1) -#endif /* MMAP_CLEARS */ - -/* ---------------------- Overlaid data structures ----------------------- */ - -/* - When chunks are not in use, they are treated as nodes of either - lists or trees. - - "Small" chunks are stored in circular doubly-linked lists, and look - like this: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `head:' | Size of chunk, in bytes |P| - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Forward pointer to next chunk in list | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Back pointer to previous chunk in list | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Unused space (may be 0 bytes long) . - . . - . | -nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `foot:' | Size of chunk, in bytes | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Larger chunks are kept in a form of bitwise digital trees (aka - tries) keyed on chunksizes. Because malloc_tree_chunks are only for - free chunks greater than 256 bytes, their size doesn't impose any - constraints on user chunk sizes. Each node looks like: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `head:' | Size of chunk, in bytes |P| - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Forward pointer to next chunk of same size | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Back pointer to previous chunk of same size | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to left child (child[0]) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to right child (child[1]) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to parent | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | bin index of this chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Unused space . - . | -nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `foot:' | Size of chunk, in bytes | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Each tree holding treenodes is a tree of unique chunk sizes. Chunks - of the same size are arranged in a circularly-linked list, with only - the oldest chunk (the next to be used, in our FIFO ordering) - actually in the tree. (Tree members are distinguished by a non-null - parent pointer.) If a chunk with the same size an an existing node - is inserted, it is linked off the existing node using pointers that - work in the same way as fd/bk pointers of small chunks. - - Each tree contains a power of 2 sized range of chunk sizes (the - smallest is 0x100 <= x < 0x180), which is is divided in half at each - tree level, with the chunks in the smaller half of the range (0x100 - <= x < 0x140 for the top nose) in the left subtree and the larger - half (0x140 <= x < 0x180) in the right subtree. This is, of course, - done by inspecting individual bits. - - Using these rules, each node's left subtree contains all smaller - sizes than its right subtree. However, the node at the root of each - subtree has no particular ordering relationship to either. (The - dividing line between the subtree sizes is based on trie relation.) - If we remove the last chunk of a given size from the interior of the - tree, we need to replace it with a leaf node. The tree ordering - rules permit a node to be replaced by any leaf below it. - - The smallest chunk in a tree (a common operation in a best-fit - allocator) can be found by walking a path to the leftmost leaf in - the tree. Unlike a usual binary tree, where we follow left child - pointers until we reach a null, here we follow the right child - pointer any time the left one is null, until we reach a leaf with - both child pointers null. The smallest chunk in the tree will be - somewhere along that path. - - The worst case number of steps to add, find, or remove a node is - bounded by the number of bits differentiating chunks within - bins. Under current bin calculations, this ranges from 6 up to 21 - (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case - is of course much better. -*/ - -struct malloc_tree_chunk { - /* The first four fields must be compatible with malloc_chunk */ - size_t prev_foot; - size_t head; - struct malloc_tree_chunk* fd; - struct malloc_tree_chunk* bk; - - struct malloc_tree_chunk* child[2]; - struct malloc_tree_chunk* parent; - bindex_t index; -}; - -typedef struct malloc_tree_chunk tchunk; -typedef struct malloc_tree_chunk* tchunkptr; -typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */ - -/* A little helper macro for trees */ -#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1]) - -/* ----------------------------- Segments -------------------------------- */ - -/* - Each malloc space may include non-contiguous segments, held in a - list headed by an embedded malloc_segment record representing the - top-most space. Segments also include flags holding properties of - the space. Large chunks that are directly allocated by mmap are not - included in this list. They are instead independently created and - destroyed without otherwise keeping track of them. - - Segment management mainly comes into play for spaces allocated by - MMAP. Any call to MMAP might or might not return memory that is - adjacent to an existing segment. MORECORE normally contiguously - extends the current space, so this space is almost always adjacent, - which is simpler and faster to deal with. (This is why MORECORE is - used preferentially to MMAP when both are available -- see - sys_alloc.) When allocating using MMAP, we don't use any of the - hinting mechanisms (inconsistently) supported in various - implementations of unix mmap, or distinguish reserving from - committing memory. Instead, we just ask for space, and exploit - contiguity when we get it. It is probably possible to do - better than this on some systems, but no general scheme seems - to be significantly better. - - Management entails a simpler variant of the consolidation scheme - used for chunks to reduce fragmentation -- new adjacent memory is - normally prepended or appended to an existing segment. However, - there are limitations compared to chunk consolidation that mostly - reflect the fact that segment processing is relatively infrequent - (occurring only when getting memory from system) and that we - don't expect to have huge numbers of segments: - - * Segments are not indexed, so traversal requires linear scans. (It - would be possible to index these, but is not worth the extra - overhead and complexity for most programs on most platforms.) - * New segments are only appended to old ones when holding top-most - memory; if they cannot be prepended to others, they are held in - different segments. - - Except for the top-most segment of an mstate, each segment record - is kept at the tail of its segment. Segments are added by pushing - segment records onto the list headed by &mstate.seg for the - containing mstate. - - Segment flags control allocation/merge/deallocation policies: - * If EXTERN_BIT set, then we did not allocate this segment, - and so should not try to deallocate or merge with others. - (This currently holds only for the initial segment passed - into create_mspace_with_base.) - * If USE_MMAP_BIT set, the segment may be merged with - other surrounding mmapped segments and trimmed/de-allocated - using munmap. - * If neither bit is set, then the segment was obtained using - MORECORE so can be merged with surrounding MORECORE'd segments - and deallocated/trimmed using MORECORE with negative arguments. -*/ - -struct malloc_segment { - char* base; /* base address */ - size_t size; /* allocated size */ - struct malloc_segment* next; /* ptr to next segment */ - flag_t sflags; /* mmap and extern flag */ -}; - -#define is_mmapped_segment(S) ((S)->sflags & USE_MMAP_BIT) -#define is_extern_segment(S) ((S)->sflags & EXTERN_BIT) - -typedef struct malloc_segment msegment; -typedef struct malloc_segment* msegmentptr; - -/* ---------------------------- malloc_state ----------------------------- */ - -/* - A malloc_state holds all of the bookkeeping for a space. - The main fields are: - - Top - The topmost chunk of the currently active segment. Its size is - cached in topsize. The actual size of topmost space is - topsize+TOP_FOOT_SIZE, which includes space reserved for adding - fenceposts and segment records if necessary when getting more - space from the system. The size at which to autotrim top is - cached from mparams in trim_check, except that it is disabled if - an autotrim fails. - - Designated victim (dv) - This is the preferred chunk for servicing small requests that - don't have exact fits. It is normally the chunk split off most - recently to service another small request. Its size is cached in - dvsize. The link fields of this chunk are not maintained since it - is not kept in a bin. - - SmallBins - An array of bin headers for free chunks. These bins hold chunks - with sizes less than MIN_LARGE_SIZE bytes. Each bin contains - chunks of all the same size, spaced 8 bytes apart. To simplify - use in double-linked lists, each bin header acts as a malloc_chunk - pointing to the real first node, if it exists (else pointing to - itself). This avoids special-casing for headers. But to avoid - waste, we allocate only the fd/bk pointers of bins, and then use - repositioning tricks to treat these as the fields of a chunk. - - TreeBins - Treebins are pointers to the roots of trees holding a range of - sizes. There are 2 equally spaced treebins for each power of two - from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything - larger. - - Bin maps - There is one bit map for small bins ("smallmap") and one for - treebins ("treemap). Each bin sets its bit when non-empty, and - clears the bit when empty. Bit operations are then used to avoid - bin-by-bin searching -- nearly all "search" is done without ever - looking at bins that won't be selected. The bit maps - conservatively use 32 bits per map word, even if on 64bit system. - For a good description of some of the bit-based techniques used - here, see Henry S. Warren Jr's book "Hacker's Delight" (and - supplement at http://hackersdelight.org/). Many of these are - intended to reduce the branchiness of paths through malloc etc, as - well as to reduce the number of memory locations read or written. - - Segments - A list of segments headed by an embedded malloc_segment record - representing the initial space. - - Address check support - The least_addr field is the least address ever obtained from - MORECORE or MMAP. Attempted frees and reallocs of any address less - than this are trapped (unless INSECURE is defined). - - Magic tag - A cross-check field that should always hold same value as mparams.magic. - - Max allowed footprint - The maximum allowed bytes to allocate from system (zero means no limit) - - Flags - Bits recording whether to use MMAP, locks, or contiguous MORECORE - - Statistics - Each space keeps track of current and maximum system memory - obtained via MORECORE or MMAP. - - Trim support - Fields holding the amount of unused topmost memory that should trigger - trimming, and a counter to force periodic scanning to release unused - non-topmost segments. - - Locking - If USE_LOCKS is defined, the "mutex" lock is acquired and released - around every public call using this mspace. - - Extension support - A void* pointer and a size_t field that can be used to help implement - extensions to this malloc. -*/ - -/* Bin types, widths and sizes */ -#define NSMALLBINS (32U) -#define NTREEBINS (32U) -#define SMALLBIN_SHIFT (3U) -#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT) -#define TREEBIN_SHIFT (8U) -#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT) -#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) -#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) - -struct malloc_state { - binmap_t smallmap; - binmap_t treemap; - size_t dvsize; - size_t topsize; - char* least_addr; - mchunkptr dv; - mchunkptr top; - size_t trim_check; - size_t release_checks; - size_t magic; - mchunkptr smallbins[(NSMALLBINS+1)*2]; - tbinptr treebins[NTREEBINS]; - size_t footprint; - size_t max_footprint; - size_t footprint_limit; /* zero means no limit */ - flag_t mflags; -#if USE_LOCKS - MLOCK_T mutex; /* locate lock among fields that rarely change */ -#endif /* USE_LOCKS */ - msegment seg; - void* extp; /* Unused but available for extensions */ - size_t exts; -}; - -typedef struct malloc_state* mstate; - -/* ------------- Global malloc_state and malloc_params ------------------- */ - -/* - malloc_params holds global properties, including those that can be - dynamically set using mallopt. There is a single instance, mparams, - initialized in init_mparams. Note that the non-zeroness of "magic" - also serves as an initialization flag. -*/ - -struct malloc_params { - size_t magic; - size_t page_size; - size_t granularity; - size_t mmap_threshold; - size_t trim_threshold; - flag_t default_mflags; -}; - -static struct malloc_params mparams; - -/* Ensure mparams initialized */ -#define ensure_initialization() (void)(mparams.magic != 0 || init_mparams()) - -#if !ONLY_MSPACES - -/* The global malloc_state used for all non-"mspace" calls */ -static struct malloc_state _gm_; -#define gm (&_gm_) -#define is_global(M) ((M) == &_gm_) - -#endif /* !ONLY_MSPACES */ - -#define is_initialized(M) ((M)->top != 0) - -/* -------------------------- system alloc setup ------------------------- */ - -/* Operations on mflags */ - -#define use_lock(M) ((M)->mflags & USE_LOCK_BIT) -#define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT) -#if USE_LOCKS -#define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT) -#else -#define disable_lock(M) -#endif - -#define use_mmap(M) ((M)->mflags & USE_MMAP_BIT) -#define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT) -#if HAVE_MMAP -#define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT) -#else -#define disable_mmap(M) -#endif - -#define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT) -#define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT) - -#define set_lock(M,L)\ - ((M)->mflags = (L)?\ - ((M)->mflags | USE_LOCK_BIT) :\ - ((M)->mflags & ~USE_LOCK_BIT)) - -/* page-align a size */ -#define page_align(S)\ - (((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE)) - -/* granularity-align a size */ -#define granularity_align(S)\ - (((S) + (mparams.granularity - SIZE_T_ONE))\ - & ~(mparams.granularity - SIZE_T_ONE)) - - -/* For mmap, use granularity alignment on windows, else page-align */ -#ifdef WIN32 -#define mmap_align(S) granularity_align(S) -#else -#define mmap_align(S) page_align(S) -#endif - -/* For sys_alloc, enough padding to ensure can malloc request on success */ -#define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT) - -#define is_page_aligned(S)\ - (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0) -#define is_granularity_aligned(S)\ - (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0) - -/* True if segment S holds address A */ -#define segment_holds(S, A)\ - ((char*)(A) >= S->base && (char*)(A) < S->base + S->size) - -/* Return segment holding given address */ -static msegmentptr segment_holding(mstate m, char* addr) { - msegmentptr sp = &m->seg; - for (;;) { - if (addr >= sp->base && addr < sp->base + sp->size) - return sp; - if ((sp = sp->next) == 0) - return 0; - } -} - -/* Return true if segment contains a segment link */ -static int has_segment_link(mstate m, msegmentptr ss) { - msegmentptr sp = &m->seg; - for (;;) { - if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size) - return 1; - if ((sp = sp->next) == 0) - return 0; - } -} - -#ifndef MORECORE_CANNOT_TRIM -#define should_trim(M,s) ((s) > (M)->trim_check) -#else /* MORECORE_CANNOT_TRIM */ -#define should_trim(M,s) (0) -#endif /* MORECORE_CANNOT_TRIM */ - -/* - TOP_FOOT_SIZE is padding at the end of a segment, including space - that may be needed to place segment records and fenceposts when new - noncontiguous segments are added. -*/ -#define TOP_FOOT_SIZE\ - (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE) - - -/* ------------------------------- Hooks -------------------------------- */ - -/* - PREACTION should be defined to return 0 on success, and nonzero on - failure. If you are not using locking, you can redefine these to do - anything you like. -*/ - -#if USE_LOCKS -#define PREACTION(M) ((use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0) -#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); } -#else /* USE_LOCKS */ - -#ifndef PREACTION -#define PREACTION(M) (0) -#endif /* PREACTION */ - -#ifndef POSTACTION -#define POSTACTION(M) -#endif /* POSTACTION */ - -#endif /* USE_LOCKS */ - -/* - CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses. - USAGE_ERROR_ACTION is triggered on detected bad frees and - reallocs. The argument p is an address that might have triggered the - fault. It is ignored by the two predefined actions, but might be - useful in custom actions that try to help diagnose errors. -*/ - -#if PROCEED_ON_ERROR - -/* A count of the number of corruption errors causing resets */ -int malloc_corruption_error_count; - -/* default corruption action */ -static void reset_on_error(mstate m); - -#define CORRUPTION_ERROR_ACTION(m) reset_on_error(m) -#define USAGE_ERROR_ACTION(m, p) - -#else /* PROCEED_ON_ERROR */ - -#ifndef CORRUPTION_ERROR_ACTION -#define CORRUPTION_ERROR_ACTION(m) ABORT -#endif /* CORRUPTION_ERROR_ACTION */ - -#ifndef USAGE_ERROR_ACTION -#define USAGE_ERROR_ACTION(m,p) ABORT -#endif /* USAGE_ERROR_ACTION */ - -#endif /* PROCEED_ON_ERROR */ - - -/* -------------------------- Debugging setup ---------------------------- */ - -#if ! DEBUG - -#define check_free_chunk(M,P) -#define check_inuse_chunk(M,P) -#define check_malloced_chunk(M,P,N) -#define check_mmapped_chunk(M,P) -#define check_malloc_state(M) -#define check_top_chunk(M,P) - -#else /* DEBUG */ -#define check_free_chunk(M,P) do_check_free_chunk(M,P) -#define check_inuse_chunk(M,P) do_check_inuse_chunk(M,P) -#define check_top_chunk(M,P) do_check_top_chunk(M,P) -#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N) -#define check_mmapped_chunk(M,P) do_check_mmapped_chunk(M,P) -#define check_malloc_state(M) do_check_malloc_state(M) - -static void do_check_any_chunk(mstate m, mchunkptr p); -static void do_check_top_chunk(mstate m, mchunkptr p); -static void do_check_mmapped_chunk(mstate m, mchunkptr p); -static void do_check_inuse_chunk(mstate m, mchunkptr p); -static void do_check_free_chunk(mstate m, mchunkptr p); -static void do_check_malloced_chunk(mstate m, void* mem, size_t s); -static void do_check_tree(mstate m, tchunkptr t); -static void do_check_treebin(mstate m, bindex_t i); -static void do_check_smallbin(mstate m, bindex_t i); -static void do_check_malloc_state(mstate m); -static int bin_find(mstate m, mchunkptr x); -static size_t traverse_and_check(mstate m); -#endif /* DEBUG */ - -/* ---------------------------- Indexing Bins ---------------------------- */ - -#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS) -#define small_index(s) (bindex_t)((s) >> SMALLBIN_SHIFT) -#define small_index2size(i) ((i) << SMALLBIN_SHIFT) -#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE)) - -/* addressing by index. See above about smallbin repositioning */ -#define smallbin_at(M, i) ((sbinptr)((char*)&((M)->smallbins[(i)<<1]))) -#define treebin_at(M,i) (&((M)->treebins[i])) - -/* assign tree index for size S to variable I. Use x86 asm if possible */ -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -#define compute_tree_index(S, I)\ -{\ - unsigned int X = S >> TREEBIN_SHIFT;\ - if (X == 0)\ - I = 0;\ - else if (X > 0xFFFF)\ - I = NTREEBINS-1;\ - else {\ - unsigned int K = (unsigned) sizeof(X)*__CHAR_BIT__ - 1 - (unsigned) __builtin_clz(X); \ - I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ - }\ -} - -#elif defined (__INTEL_COMPILER) -#define compute_tree_index(S, I)\ -{\ - size_t X = S >> TREEBIN_SHIFT;\ - if (X == 0)\ - I = 0;\ - else if (X > 0xFFFF)\ - I = NTREEBINS-1;\ - else {\ - unsigned int K = _bit_scan_reverse (X); \ - I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ - }\ -} - -#elif defined(_MSC_VER) && _MSC_VER>=1300 -#define compute_tree_index(S, I)\ -{\ - size_t X = S >> TREEBIN_SHIFT;\ - if (X == 0)\ - I = 0;\ - else if (X > 0xFFFF)\ - I = NTREEBINS-1;\ - else {\ - unsigned int K;\ - _BitScanReverse((DWORD *) &K, (DWORD) X);\ - I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ - }\ -} - -#else /* GNUC */ -#define compute_tree_index(S, I)\ -{\ - size_t X = S >> TREEBIN_SHIFT;\ - if (X == 0)\ - I = 0;\ - else if (X > 0xFFFF)\ - I = NTREEBINS-1;\ - else {\ - unsigned int Y = (unsigned int)X;\ - unsigned int N = ((Y - 0x100) >> 16) & 8;\ - unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\ - N += K;\ - N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\ - K = 14 - N + ((Y <<= K) >> 15);\ - I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\ - }\ -} -#endif /* GNUC */ - -/* Bit representing maximum resolved size in a treebin at i */ -#define bit_for_tree_index(i) \ - (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2) - -/* Shift placing maximum resolved bit in a treebin at i as sign bit */ -#define leftshift_for_tree_index(i) \ - ((i == NTREEBINS-1)? 0 : \ - ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2))) - -/* The size of the smallest chunk held in bin with index i */ -#define minsize_for_tree_index(i) \ - ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \ - (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1))) - - -/* ------------------------ Operations on bin maps ----------------------- */ - -/* bit corresponding to given index */ -#define idx2bit(i) ((binmap_t)(1) << (i)) - -/* Mark/Clear bits with given index */ -#define mark_smallmap(M,i) ((M)->smallmap |= idx2bit(i)) -#define clear_smallmap(M,i) ((M)->smallmap &= ~idx2bit(i)) -#define smallmap_is_marked(M,i) ((M)->smallmap & idx2bit(i)) - -#define mark_treemap(M,i) ((M)->treemap |= idx2bit(i)) -#define clear_treemap(M,i) ((M)->treemap &= ~idx2bit(i)) -#define treemap_is_marked(M,i) ((M)->treemap & idx2bit(i)) - -/* isolate the least set bit of a bitmap */ -#define least_bit(x) ((x) & -(x)) - -/* mask with all bits to left of least bit of x on */ -#define left_bits(x) ((x<<1) | -(x<<1)) - -/* mask with all bits to left of or equal to least bit of x on */ -#define same_or_left_bits(x) ((x) | -(x)) - -/* index corresponding to given bit. Use x86 asm if possible */ - -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -#define compute_bit2idx(X, I)\ -{\ - unsigned int J;\ - J = __builtin_ctz(X); \ - I = (bindex_t)J;\ -} - -#elif defined (__INTEL_COMPILER) -#define compute_bit2idx(X, I)\ -{\ - unsigned int J;\ - J = _bit_scan_forward (X); \ - I = (bindex_t)J;\ -} - -#elif defined(_MSC_VER) && _MSC_VER>=1300 -#define compute_bit2idx(X, I)\ -{\ - unsigned int J;\ - _BitScanForward((DWORD *) &J, X);\ - I = (bindex_t)J;\ -} - -#elif USE_BUILTIN_FFS -#define compute_bit2idx(X, I) I = ffs(X)-1 - -#else -#define compute_bit2idx(X, I)\ -{\ - unsigned int Y = X - 1;\ - unsigned int K = Y >> (16-4) & 16;\ - unsigned int N = K; Y >>= K;\ - N += K = Y >> (8-3) & 8; Y >>= K;\ - N += K = Y >> (4-2) & 4; Y >>= K;\ - N += K = Y >> (2-1) & 2; Y >>= K;\ - N += K = Y >> (1-0) & 1; Y >>= K;\ - I = (bindex_t)(N + Y);\ -} -#endif /* GNUC */ - - -/* ----------------------- Runtime Check Support ------------------------- */ - -/* - For security, the main invariant is that malloc/free/etc never - writes to a static address other than malloc_state, unless static - malloc_state itself has been corrupted, which cannot occur via - malloc (because of these checks). In essence this means that we - believe all pointers, sizes, maps etc held in malloc_state, but - check all of those linked or offsetted from other embedded data - structures. These checks are interspersed with main code in a way - that tends to minimize their run-time cost. - - When FOOTERS is defined, in addition to range checking, we also - verify footer fields of inuse chunks, which can be used guarantee - that the mstate controlling malloc/free is intact. This is a - streamlined version of the approach described by William Robertson - et al in "Run-time Detection of Heap-based Overflows" LISA'03 - http://www.usenix.org/events/lisa03/tech/robertson.html The footer - of an inuse chunk holds the xor of its mstate and a random seed, - that is checked upon calls to free() and realloc(). This is - (probabalistically) unguessable from outside the program, but can be - computed by any code successfully malloc'ing any chunk, so does not - itself provide protection against code that has already broken - security through some other means. Unlike Robertson et al, we - always dynamically check addresses of all offset chunks (previous, - next, etc). This turns out to be cheaper than relying on hashes. -*/ - -#if !INSECURE -/* Check if address a is at least as high as any from MORECORE or MMAP */ -#define ok_address(M, a) ((char*)(a) >= (M)->least_addr) -/* Check if address of next chunk n is higher than base chunk p */ -#define ok_next(p, n) ((char*)(p) < (char*)(n)) -/* Check if p has inuse status */ -#define ok_inuse(p) is_inuse(p) -/* Check if p has its pinuse bit on */ -#define ok_pinuse(p) pinuse(p) - -#else /* !INSECURE */ -#define ok_address(M, a) (1) -#define ok_next(b, n) (1) -#define ok_inuse(p) (1) -#define ok_pinuse(p) (1) -#endif /* !INSECURE */ - -#if (FOOTERS && !INSECURE) -/* Check if (alleged) mstate m has expected magic field */ -#define ok_magic(M) ((M)->magic == mparams.magic) -#else /* (FOOTERS && !INSECURE) */ -#define ok_magic(M) (1) -#endif /* (FOOTERS && !INSECURE) */ - -/* In gcc, use __builtin_expect to minimize impact of checks */ -#if !INSECURE -#if defined(__GNUC__) && __GNUC__ >= 3 -#define RTCHECK(e) __builtin_expect(e, 1) -#else /* GNUC */ -#define RTCHECK(e) (e) -#endif /* GNUC */ -#else /* !INSECURE */ -#define RTCHECK(e) (1) -#endif /* !INSECURE */ - -/* macros to set up inuse chunks with or without footers */ - -#if !FOOTERS - -#define mark_inuse_foot(M,p,s) - -/* Macros for setting head/foot of non-mmapped chunks */ - -/* Set cinuse bit and pinuse bit of next chunk */ -#define set_inuse(M,p,s)\ - ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ - ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) - -/* Set cinuse and pinuse of this chunk and pinuse of next chunk */ -#define set_inuse_and_pinuse(M,p,s)\ - ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ - ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) - -/* Set size, cinuse and pinuse bit of this chunk */ -#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ - ((p)->head = (s|PINUSE_BIT|CINUSE_BIT)) - -#else /* FOOTERS */ - -/* Set foot of inuse chunk to be xor of mstate and seed */ -#define mark_inuse_foot(M,p,s)\ - (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic)) - -#define get_mstate_for(p)\ - ((mstate)(((mchunkptr)((char*)(p) +\ - (chunksize(p))))->prev_foot ^ mparams.magic)) - -#define set_inuse(M,p,s)\ - ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ - (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \ - mark_inuse_foot(M,p,s)) - -#define set_inuse_and_pinuse(M,p,s)\ - ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ - (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\ - mark_inuse_foot(M,p,s)) - -#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ - ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ - mark_inuse_foot(M, p, s)) - -#endif /* !FOOTERS */ - -/* ---------------------------- setting mparams -------------------------- */ - -/* Initialize mparams */ -static int init_mparams(void) { -#ifdef NEED_GLOBAL_LOCK_INIT - call_once(&malloc_global_mutex_init_once, init_malloc_global_mutex); -#endif - - ACQUIRE_MALLOC_GLOBAL_LOCK(); - if (mparams.magic == 0) { - size_t magic; - size_t psize; - size_t gsize; - -#ifndef WIN32 - psize = malloc_getpagesize; - gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : psize); -#else /* WIN32 */ - { - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - psize = system_info.dwPageSize; - gsize = ((DEFAULT_GRANULARITY != 0)? - DEFAULT_GRANULARITY : system_info.dwAllocationGranularity); - } -#endif /* WIN32 */ - - /* Sanity-check configuration: - size_t must be unsigned and as wide as pointer type. - ints must be at least 4 bytes. - alignment must be at least 8. - Alignment, min chunk size, and page size must all be powers of 2. - */ - if ((sizeof(size_t) != sizeof(char*)) || - (MAX_SIZE_T < MIN_CHUNK_SIZE) || - (sizeof(int) < 4) || - (MALLOC_ALIGNMENT < (size_t)8U) || - ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) || - ((MCHUNK_SIZE & (MCHUNK_SIZE-SIZE_T_ONE)) != 0) || - ((gsize & (gsize-SIZE_T_ONE)) != 0) || - ((psize & (psize-SIZE_T_ONE)) != 0)) - ABORT; - - mparams.granularity = gsize; - mparams.page_size = psize; - mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; - mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; -#if MORECORE_CONTIGUOUS - mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT; -#else /* MORECORE_CONTIGUOUS */ - mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT; -#endif /* MORECORE_CONTIGUOUS */ - -#if !ONLY_MSPACES - /* Set up lock for main malloc area */ - gm->mflags = mparams.default_mflags; - (void)INITIAL_LOCK(&gm->mutex); -#endif - - { -#if USE_DEV_RANDOM - int fd; - unsigned char buf[sizeof(size_t)]; - /* Try to use /dev/urandom, else fall back on using time */ - if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 && - read(fd, buf, sizeof(buf)) == sizeof(buf)) { - magic = *((size_t *) buf); - close(fd); - } - else -#endif /* USE_DEV_RANDOM */ -#ifdef WIN32 - magic = (size_t)(GetTickCount() ^ (size_t)0x55555555U); -#elif defined(LACKS_TIME_H) - magic = (size_t)&magic ^ (size_t)0x55555555U; -#else - magic = (size_t)(time(0) ^ (size_t)0x55555555U); -#endif - magic |= (size_t)8U; /* ensure nonzero */ - magic &= ~(size_t)7U; /* improve chances of fault for bad values */ - /* Until memory modes commonly available, use volatile-write */ - (*(volatile size_t *)(&(mparams.magic))) = magic; - } - } - - RELEASE_MALLOC_GLOBAL_LOCK(); - return 1; -} - -/* support for mallopt */ -static int change_mparam(int param_number, int value) { - size_t val; - ensure_initialization(); - val = (value == -1)? MAX_SIZE_T : (size_t)value; - switch(param_number) { - case M_TRIM_THRESHOLD: - mparams.trim_threshold = val; - return 1; - case M_GRANULARITY: - if (val >= mparams.page_size && ((val & (val-1)) == 0)) { - mparams.granularity = val; - return 1; - } - else - return 0; - case M_MMAP_THRESHOLD: - mparams.mmap_threshold = val; - return 1; - default: - return 0; - } -} - -#if DEBUG -/* ------------------------- Debugging Support --------------------------- */ - -/* Check properties of any chunk, whether free, inuse, mmapped etc */ -static void do_check_any_chunk(mstate m, mchunkptr p) { - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); -} - -/* Check properties of top chunk */ -static void do_check_top_chunk(mstate m, mchunkptr p) { - msegmentptr sp = segment_holding(m, (char*)p); - size_t sz = p->head & ~INUSE_BITS; /* third-lowest bit can be set! */ - assert(sp != 0); - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); - assert(sz == m->topsize); - assert(sz > 0); - assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE); - assert(pinuse(p)); - assert(!pinuse(chunk_plus_offset(p, sz))); -} - -/* Check properties of (inuse) mmapped chunks */ -static void do_check_mmapped_chunk(mstate m, mchunkptr p) { - size_t sz = chunksize(p); - size_t len = (sz + (p->prev_foot) + MMAP_FOOT_PAD); - assert(is_mmapped(p)); - assert(use_mmap(m)); - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); - assert(!is_small(sz)); - assert((len & (mparams.page_size-SIZE_T_ONE)) == 0); - assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); - assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0); -} - -/* Check properties of inuse chunks */ -static void do_check_inuse_chunk(mstate m, mchunkptr p) { - do_check_any_chunk(m, p); - assert(is_inuse(p)); - assert(next_pinuse(p)); - /* If not pinuse and not mmapped, previous chunk has OK offset */ - assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); - if (is_mmapped(p)) - do_check_mmapped_chunk(m, p); -} - -/* Check properties of free chunks */ -static void do_check_free_chunk(mstate m, mchunkptr p) { - size_t sz = chunksize(p); - mchunkptr next = chunk_plus_offset(p, sz); - do_check_any_chunk(m, p); - assert(!is_inuse(p)); - assert(!next_pinuse(p)); - assert (!is_mmapped(p)); - if (p != m->dv && p != m->top) { - if (sz >= MIN_CHUNK_SIZE) { - assert((sz & CHUNK_ALIGN_MASK) == 0); - assert(is_aligned(chunk2mem(p))); - assert(next->prev_foot == sz); - assert(pinuse(p)); - assert (next == m->top || is_inuse(next)); - assert(p->fd->bk == p); - assert(p->bk->fd == p); - } - else /* markers are always of size SIZE_T_SIZE */ - assert(sz == SIZE_T_SIZE); - } -} - -/* Check properties of malloced chunks at the point they are malloced */ -static void do_check_malloced_chunk(mstate m, void* mem, size_t s) { - if (mem != 0) { - mchunkptr p = mem2chunk(mem); - size_t sz = p->head & ~INUSE_BITS; - do_check_inuse_chunk(m, p); - assert((sz & CHUNK_ALIGN_MASK) == 0); - assert(sz >= MIN_CHUNK_SIZE); - assert(sz >= s); - /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ - assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); - } -} - -/* Check a tree and its subtrees. */ -static void do_check_tree(mstate m, tchunkptr t) { - tchunkptr head = 0; - tchunkptr u = t; - bindex_t tindex = t->index; - size_t tsize = chunksize(t); - bindex_t idx; - compute_tree_index(tsize, idx); - assert(tindex == idx); - assert(tsize >= MIN_LARGE_SIZE); - assert(tsize >= minsize_for_tree_index(idx)); - assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1)))); - - do { /* traverse through chain of same-sized nodes */ - do_check_any_chunk(m, ((mchunkptr)u)); - assert(u->index == tindex); - assert(chunksize(u) == tsize); - assert(!is_inuse(u)); - assert(!next_pinuse(u)); - assert(u->fd->bk == u); - assert(u->bk->fd == u); - if (u->parent == 0) { - assert(u->child[0] == 0); - assert(u->child[1] == 0); - } - else { - assert(head == 0); /* only one node on chain has parent */ - head = u; - assert(u->parent != u); - assert (u->parent->child[0] == u || - u->parent->child[1] == u || - *((tbinptr*)(u->parent)) == u); - if (u->child[0] != 0) { - assert(u->child[0]->parent == u); - assert(u->child[0] != u); - do_check_tree(m, u->child[0]); - } - if (u->child[1] != 0) { - assert(u->child[1]->parent == u); - assert(u->child[1] != u); - do_check_tree(m, u->child[1]); - } - if (u->child[0] != 0 && u->child[1] != 0) { - assert(chunksize(u->child[0]) < chunksize(u->child[1])); - } - } - u = u->fd; - } while (u != t); - assert(head != 0); -} - -/* Check all the chunks in a treebin. */ -static void do_check_treebin(mstate m, bindex_t i) { - tbinptr* tb = treebin_at(m, i); - tchunkptr t = *tb; - int empty = (m->treemap & (1U << i)) == 0; - if (t == 0) - assert(empty); - if (!empty) - do_check_tree(m, t); -} - -/* Check all the chunks in a smallbin. */ -static void do_check_smallbin(mstate m, bindex_t i) { - sbinptr b = smallbin_at(m, i); - mchunkptr p = b->bk; - unsigned int empty = (m->smallmap & (1U << i)) == 0; - if (p == b) - assert(empty); - if (!empty) { - for (; p != b; p = p->bk) { - size_t size = chunksize(p); - mchunkptr q; - /* each chunk claims to be free */ - do_check_free_chunk(m, p); - /* chunk belongs in bin */ - assert(small_index(size) == i); - assert(p->bk == b || chunksize(p->bk) == chunksize(p)); - /* chunk is followed by an inuse chunk */ - q = next_chunk(p); - if (q->head != FENCEPOST_HEAD) - do_check_inuse_chunk(m, q); - } - } -} - -/* Find x in a bin. Used in other check functions. */ -static int bin_find(mstate m, mchunkptr x) { - size_t size = chunksize(x); - if (is_small(size)) { - bindex_t sidx = small_index(size); - sbinptr b = smallbin_at(m, sidx); - if (smallmap_is_marked(m, sidx)) { - mchunkptr p = b; - do { - if (p == x) - return 1; - } while ((p = p->fd) != b); - } - } - else { - bindex_t tidx; - compute_tree_index(size, tidx); - if (treemap_is_marked(m, tidx)) { - tchunkptr t = *treebin_at(m, tidx); - size_t sizebits = size << leftshift_for_tree_index(tidx); - while (t != 0 && chunksize(t) != size) { - t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; - sizebits <<= 1; - } - if (t != 0) { - tchunkptr u = t; - do { - if (u == (tchunkptr)x) - return 1; - } while ((u = u->fd) != t); - } - } - } - return 0; -} - -/* Traverse each chunk and check it; return total */ -static size_t traverse_and_check(mstate m) { - size_t sum = 0; - if (is_initialized(m)) { - msegmentptr s = &m->seg; - sum += m->topsize + TOP_FOOT_SIZE; - while (s != 0) { - mchunkptr q = align_as_chunk(s->base); - mchunkptr lastq = 0; - assert(pinuse(q)); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) { - sum += chunksize(q); - if (is_inuse(q)) { - assert(!bin_find(m, q)); - do_check_inuse_chunk(m, q); - } - else { - assert(q == m->dv || bin_find(m, q)); - assert(lastq == 0 || is_inuse(lastq)); /* Not 2 consecutive free */ - do_check_free_chunk(m, q); - } - lastq = q; - q = next_chunk(q); - } - s = s->next; - } - } - return sum; -} - - -/* Check all properties of malloc_state. */ -static void do_check_malloc_state(mstate m) { - bindex_t i; - size_t total; - /* check bins */ - for (i = 0; i < NSMALLBINS; ++i) - do_check_smallbin(m, i); - for (i = 0; i < NTREEBINS; ++i) - do_check_treebin(m, i); - - if (m->dvsize != 0) { /* check dv chunk */ - do_check_any_chunk(m, m->dv); - assert(m->dvsize == chunksize(m->dv)); - assert(m->dvsize >= MIN_CHUNK_SIZE); - assert(bin_find(m, m->dv) == 0); - } - - if (m->top != 0) { /* check top chunk */ - do_check_top_chunk(m, m->top); - /*assert(m->topsize == chunksize(m->top)); redundant */ - assert(m->topsize > 0); - assert(bin_find(m, m->top) == 0); - } - - total = traverse_and_check(m); - assert(total <= m->footprint); - assert(m->footprint <= m->max_footprint); -} -#endif /* DEBUG */ - -/* ----------------------------- statistics ------------------------------ */ - -#if !NO_MALLINFO -static struct mallinfo internal_mallinfo(mstate m) { - struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - ensure_initialization(); - if (!PREACTION(m)) { - check_malloc_state(m); - if (is_initialized(m)) { - size_t nfree = SIZE_T_ONE; /* top always free */ - size_t mfree = m->topsize + TOP_FOOT_SIZE; - size_t sum = mfree; - msegmentptr s = &m->seg; - while (s != 0) { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) { - size_t sz = chunksize(q); - sum += sz; - if (!is_inuse(q)) { - mfree += sz; - ++nfree; - } - q = next_chunk(q); - } - s = s->next; - } - - nm.arena = sum; - nm.ordblks = nfree; - nm.hblkhd = m->footprint - sum; - nm.usmblks = m->max_footprint; - nm.uordblks = m->footprint - mfree; - nm.fordblks = mfree; - nm.keepcost = m->topsize; - } - - POSTACTION(m); - } - return nm; -} -#endif /* !NO_MALLINFO */ - -#if !NO_MALLOC_STATS -static void internal_malloc_stats(mstate m) { - ensure_initialization(); - if (!PREACTION(m)) { - size_t maxfp = 0; - size_t fp = 0; - size_t used = 0; - check_malloc_state(m); - if (is_initialized(m)) { - msegmentptr s = &m->seg; - maxfp = m->max_footprint; - fp = m->footprint; - used = fp - (m->topsize + TOP_FOOT_SIZE); - - while (s != 0) { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) { - if (!is_inuse(q)) - used -= chunksize(q); - q = next_chunk(q); - } - s = s->next; - } - } - POSTACTION(m); /* drop lock */ - fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp)); - fprintf(stderr, "system bytes = %10lu\n", (unsigned long)(fp)); - fprintf(stderr, "in use bytes = %10lu\n", (unsigned long)(used)); - } -} -#endif /* NO_MALLOC_STATS */ - -/* ----------------------- Operations on smallbins ----------------------- */ - -/* - Various forms of linking and unlinking are defined as macros. Even - the ones for trees, which are very long but have very short typical - paths. This is ugly but reduces reliance on inlining support of - compilers. -*/ - -/* Link a free chunk into a smallbin */ -#define insert_small_chunk(M, P, S) {\ - bindex_t I = small_index(S);\ - mchunkptr B = smallbin_at(M, I);\ - mchunkptr F = B;\ - assert(S >= MIN_CHUNK_SIZE);\ - if (!smallmap_is_marked(M, I))\ - mark_smallmap(M, I);\ - else if (RTCHECK(ok_address(M, B->fd)))\ - F = B->fd;\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - B->fd = P;\ - F->bk = P;\ - P->fd = F;\ - P->bk = B;\ -} - -/* Unlink a chunk from a smallbin */ -#define unlink_small_chunk(M, P, S) {\ - mchunkptr F = P->fd;\ - mchunkptr B = P->bk;\ - bindex_t I = small_index(S);\ - assert(P != B);\ - assert(P != F);\ - assert(chunksize(P) == small_index2size(I));\ - if (RTCHECK(F == smallbin_at(M,I) || (ok_address(M, F) && F->bk == P))) { \ - if (B == F) {\ - clear_smallmap(M, I);\ - }\ - else if (RTCHECK(B == smallbin_at(M,I) ||\ - (ok_address(M, B) && B->fd == P))) {\ - F->bk = B;\ - B->fd = F;\ - }\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - }\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - }\ -} - -/* Unlink the first chunk from a smallbin */ -#define unlink_first_small_chunk(M, B, P, I) {\ - mchunkptr F = P->fd;\ - assert(P != B);\ - assert(P != F);\ - assert(chunksize(P) == small_index2size(I));\ - if (B == F) {\ - clear_smallmap(M, I);\ - }\ - else if (RTCHECK(ok_address(M, F) && F->bk == P)) {\ - F->bk = B;\ - B->fd = F;\ - }\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - }\ -} - -/* Replace dv node, binning the old one */ -/* Used only when dvsize known to be small */ -#define replace_dv(M, P, S) {\ - size_t DVS = M->dvsize;\ - assert(is_small(DVS));\ - if (DVS != 0) {\ - mchunkptr DV = M->dv;\ - insert_small_chunk(M, DV, DVS);\ - }\ - M->dvsize = S;\ - M->dv = P;\ -} - -/* ------------------------- Operations on trees ------------------------- */ - -/* Insert chunk into tree */ -#define insert_large_chunk(M, X, S) {\ - tbinptr* H;\ - bindex_t I;\ - compute_tree_index(S, I);\ - H = treebin_at(M, I);\ - X->index = I;\ - X->child[0] = X->child[1] = 0;\ - if (!treemap_is_marked(M, I)) {\ - mark_treemap(M, I);\ - *H = X;\ - X->parent = (tchunkptr)H;\ - X->fd = X->bk = X;\ - }\ - else {\ - tchunkptr T = *H;\ - size_t K = S << leftshift_for_tree_index(I);\ - for (;;) {\ - if (chunksize(T) != S) {\ - tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\ - K <<= 1;\ - if (*C != 0)\ - T = *C;\ - else if (RTCHECK(ok_address(M, C))) {\ - *C = X;\ - X->parent = T;\ - X->fd = X->bk = X;\ - break;\ - }\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - break;\ - }\ - }\ - else {\ - tchunkptr F = T->fd;\ - if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\ - T->fd = F->bk = X;\ - X->fd = F;\ - X->bk = T;\ - X->parent = 0;\ - break;\ - }\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - break;\ - }\ - }\ - }\ - }\ -} - -/* - Unlink steps: - - 1. If x is a chained node, unlink it from its same-sized fd/bk links - and choose its bk node as its replacement. - 2. If x was the last node of its size, but not a leaf node, it must - be replaced with a leaf node (not merely one with an open left or - right), to make sure that lefts and rights of descendents - correspond properly to bit masks. We use the rightmost descendent - of x. We could use any other leaf, but this is easy to locate and - tends to counteract removal of leftmosts elsewhere, and so keeps - paths shorter than minimally guaranteed. This doesn't loop much - because on average a node in a tree is near the bottom. - 3. If x is the base of a chain (i.e., has parent links) relink - x's parent and children to x's replacement (or null if none). -*/ - -#define unlink_large_chunk(M, X) {\ - tchunkptr XP = X->parent;\ - tchunkptr R;\ - if (X->bk != X) {\ - tchunkptr F = X->fd;\ - R = X->bk;\ - if (RTCHECK(ok_address(M, F) && F->bk == X && R->fd == X)) {\ - F->bk = R;\ - R->fd = F;\ - }\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - }\ - else {\ - tchunkptr* RP;\ - if (((R = *(RP = &(X->child[1]))) != 0) ||\ - ((R = *(RP = &(X->child[0]))) != 0)) {\ - tchunkptr* CP;\ - while ((*(CP = &(R->child[1])) != 0) ||\ - (*(CP = &(R->child[0])) != 0)) {\ - R = *(RP = CP);\ - }\ - if (RTCHECK(ok_address(M, RP)))\ - *RP = 0;\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - }\ - }\ - if (XP != 0) {\ - tbinptr* H = treebin_at(M, X->index);\ - if (X == *H) {\ - if ((*H = R) == 0) \ - clear_treemap(M, X->index);\ - }\ - else if (RTCHECK(ok_address(M, XP))) {\ - if (XP->child[0] == X) \ - XP->child[0] = R;\ - else \ - XP->child[1] = R;\ - }\ - else\ - CORRUPTION_ERROR_ACTION(M);\ - if (R != 0) {\ - if (RTCHECK(ok_address(M, R))) {\ - tchunkptr C0, C1;\ - R->parent = XP;\ - if ((C0 = X->child[0]) != 0) {\ - if (RTCHECK(ok_address(M, C0))) {\ - R->child[0] = C0;\ - C0->parent = R;\ - }\ - else\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - if ((C1 = X->child[1]) != 0) {\ - if (RTCHECK(ok_address(M, C1))) {\ - R->child[1] = C1;\ - C1->parent = R;\ - }\ - else\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - }\ - else\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - }\ -} - -/* Relays to large vs small bin operations */ - -#define insert_chunk(M, P, S)\ - if (is_small(S)) insert_small_chunk(M, P, S)\ - else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); } - -#define unlink_chunk(M, P, S)\ - if (is_small(S)) unlink_small_chunk(M, P, S)\ - else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); } - - -/* Relays to internal calls to malloc/free from realloc, memalign etc */ - -#if ONLY_MSPACES -#define internal_malloc(m, b) mspace_malloc(m, b) -#define internal_free(m, mem) mspace_free(m,mem); -#else /* ONLY_MSPACES */ -#if MSPACES -#define internal_malloc(m, b)\ - ((m == gm)? dlmalloc(b) : mspace_malloc(m, b)) -#define internal_free(m, mem)\ - if (m == gm) dlfree(mem); else mspace_free(m,mem); -#else /* MSPACES */ -#define internal_malloc(m, b) dlmalloc(b) -#define internal_free(m, mem) dlfree(mem) -#endif /* MSPACES */ -#endif /* ONLY_MSPACES */ - -/* ----------------------- Direct-mmapping chunks ----------------------- */ - -/* - Directly mmapped chunks are set up with an offset to the start of - the mmapped region stored in the prev_foot field of the chunk. This - allows reconstruction of the required argument to MUNMAP when freed, - and also allows adjustment of the returned chunk to meet alignment - requirements (especially in memalign). -*/ - -/* Malloc using mmap */ -static void* mmap_alloc(mstate m, size_t nb) { - size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - if (m->footprint_limit != 0) { - size_t fp = m->footprint + mmsize; - if (fp <= m->footprint || fp > m->footprint_limit) - return 0; - } - if (mmsize > nb) { /* Check for wrap around 0 */ - char* mm = (char*)(CALL_DIRECT_MMAP(mmsize)); - if (mm != CMFAIL) { - size_t offset = align_offset(chunk2mem(mm)); - size_t psize = mmsize - offset - MMAP_FOOT_PAD; - mchunkptr p = (mchunkptr)(mm + offset); - p->prev_foot = offset; - p->head = psize; - mark_inuse_foot(m, p, psize); - chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; - chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0; - - if (m->least_addr == 0 || mm < m->least_addr) - m->least_addr = mm; - if ((m->footprint += mmsize) > m->max_footprint) - m->max_footprint = m->footprint; - assert(is_aligned(chunk2mem(p))); - check_mmapped_chunk(m, p); - return chunk2mem(p); - } - } - return 0; -} - -/* Realloc using mmap */ -static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb, int flags) { - size_t oldsize = chunksize(oldp); - (void) flags; - if (is_small(nb)) /* Can't shrink mmap regions below small size */ - return 0; - /* Keep old chunk if big enough but not too big */ - if (oldsize >= nb + SIZE_T_SIZE && - (oldsize - nb) <= (mparams.granularity << 1)) - return oldp; - else { - size_t offset = oldp->prev_foot; - size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; - size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - char* cp = (char*)CALL_MREMAP((char*)oldp - offset, - oldmmsize, newmmsize, flags); - if (cp != CMFAIL) { - mchunkptr newp = (mchunkptr)(cp + offset); - size_t psize = newmmsize - offset - MMAP_FOOT_PAD; - newp->head = psize; - mark_inuse_foot(m, newp, psize); - chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; - chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0; - - if (cp < m->least_addr) - m->least_addr = cp; - if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) - m->max_footprint = m->footprint; - check_mmapped_chunk(m, newp); - return newp; - } - } - return 0; -} - - -/* -------------------------- mspace management -------------------------- */ - -/* Initialize top chunk and its size */ -static void init_top(mstate m, mchunkptr p, size_t psize) { - /* Ensure alignment */ - size_t offset = align_offset(chunk2mem(p)); - p = (mchunkptr)((char*)p + offset); - psize -= offset; - - m->top = p; - m->topsize = psize; - p->head = psize | PINUSE_BIT; - /* set size of fake trailing chunk holding overhead space only once */ - chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; - m->trim_check = mparams.trim_threshold; /* reset on each update */ -} - -/* Initialize bins for a new mstate that is otherwise zeroed out */ -static void init_bins(mstate m) { - /* Establish circular links for smallbins */ - bindex_t i; - for (i = 0; i < NSMALLBINS; ++i) { - sbinptr bin = smallbin_at(m,i); - bin->fd = bin->bk = bin; - } -} - -#if PROCEED_ON_ERROR - -/* default corruption action */ -static void reset_on_error(mstate m) { - int i; - ++malloc_corruption_error_count; - /* Reinitialize fields to forget about all memory */ - m->smallmap = m->treemap = 0; - m->dvsize = m->topsize = 0; - m->seg.base = 0; - m->seg.size = 0; - m->seg.next = 0; - m->top = m->dv = 0; - for (i = 0; i < NTREEBINS; ++i) - *treebin_at(m, i) = 0; - init_bins(m); -} -#endif /* PROCEED_ON_ERROR */ - -/* Allocate chunk and prepend remainder with chunk in successor base. */ -static void* prepend_alloc(mstate m, char* newbase, char* oldbase, - size_t nb) { - mchunkptr p = align_as_chunk(newbase); - mchunkptr oldfirst = align_as_chunk(oldbase); - size_t psize = (char*)oldfirst - (char*)p; - mchunkptr q = chunk_plus_offset(p, nb); - size_t qsize = psize - nb; - set_size_and_pinuse_of_inuse_chunk(m, p, nb); - - assert((char*)oldfirst > (char*)q); - assert(pinuse(oldfirst)); - assert(qsize >= MIN_CHUNK_SIZE); - - /* consolidate remainder with first chunk of old base */ - if (oldfirst == m->top) { - size_t tsize = m->topsize += qsize; - m->top = q; - q->head = tsize | PINUSE_BIT; - check_top_chunk(m, q); - } - else if (oldfirst == m->dv) { - size_t dsize = m->dvsize += qsize; - m->dv = q; - set_size_and_pinuse_of_free_chunk(q, dsize); - } - else { - if (!is_inuse(oldfirst)) { - size_t nsize = chunksize(oldfirst); - unlink_chunk(m, oldfirst, nsize); - oldfirst = chunk_plus_offset(oldfirst, nsize); - qsize += nsize; - } - set_free_with_pinuse(q, qsize, oldfirst); - insert_chunk(m, q, qsize); - check_free_chunk(m, q); - } - - check_malloced_chunk(m, chunk2mem(p), nb); - return chunk2mem(p); -} - -/* Add a segment to hold a new noncontiguous region */ -static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { - /* Determine locations and sizes of segment, fenceposts, old top */ - char* old_top = (char*)m->top; - msegmentptr oldsp = segment_holding(m, old_top); - char* old_end = oldsp->base + oldsp->size; - size_t ssize = pad_request(sizeof(struct malloc_segment)); - char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - size_t offset = align_offset(chunk2mem(rawsp)); - char* asp = rawsp + offset; - char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp; - mchunkptr sp = (mchunkptr)csp; - msegmentptr ss = (msegmentptr)(chunk2mem(sp)); - mchunkptr tnext = chunk_plus_offset(sp, ssize); - mchunkptr p = tnext; - int nfences = 0; - - /* reset top to new space */ - init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); - - /* Set up segment record */ - assert(is_aligned(ss)); - set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); - *ss = m->seg; /* Push current record */ - m->seg.base = tbase; - m->seg.size = tsize; - m->seg.sflags = mmapped; - m->seg.next = ss; - - /* Insert trailing fenceposts */ - for (;;) { - mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); - p->head = FENCEPOST_HEAD; - ++nfences; - if ((char*)(&(nextp->head)) < old_end) - p = nextp; - else - break; - } - assert(nfences >= 2); - - /* Insert the rest of old top into a bin as an ordinary free chunk */ - if (csp != old_top) { - mchunkptr q = (mchunkptr)old_top; - size_t psize = csp - old_top; - mchunkptr tn = chunk_plus_offset(q, psize); - set_free_with_pinuse(q, psize, tn); - insert_chunk(m, q, psize); - } - - check_top_chunk(m, m->top); -} - -/* -------------------------- System allocation -------------------------- */ - -/* Get memory from system using MORECORE or MMAP */ -static void* sys_alloc(mstate m, size_t nb) { - char* tbase = CMFAIL; - size_t tsize = 0; - flag_t mmap_flag = 0; - size_t asize; /* allocation size */ - - ensure_initialization(); - - /* Directly map large chunks, but only if already initialized */ - if (use_mmap(m) && nb >= mparams.mmap_threshold && m->topsize != 0) { - void* mem = mmap_alloc(m, nb); - if (mem != 0) - return mem; - } - - asize = granularity_align(nb + SYS_ALLOC_PADDING); - if (asize <= nb) - return 0; /* wraparound */ - if (m->footprint_limit != 0) { - size_t fp = m->footprint + asize; - if (fp <= m->footprint || fp > m->footprint_limit) - return 0; - } - - /* - Try getting memory in any of three ways (in most-preferred to - least-preferred order): - 1. A call to MORECORE that can normally contiguously extend memory. - (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or - or main space is mmapped or a previous contiguous call failed) - 2. A call to MMAP new space (disabled if not HAVE_MMAP). - Note that under the default settings, if MORECORE is unable to - fulfill a request, and HAVE_MMAP is true, then mmap is - used as a noncontiguous system allocator. This is a useful backup - strategy for systems with holes in address spaces -- in this case - sbrk cannot contiguously expand the heap, but mmap may be able to - find space. - 3. A call to MORECORE that cannot usually contiguously extend memory. - (disabled if not HAVE_MORECORE) - - In all cases, we need to request enough bytes from system to ensure - we can malloc nb bytes upon success, so pad with enough space for - top_foot, plus alignment-pad to make sure we don't lose bytes if - not on boundary, and round this up to a granularity unit. - */ - - if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) { - char* br = CMFAIL; - msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top); - ACQUIRE_MALLOC_GLOBAL_LOCK(); - - if (ss == 0) { /* First time through or recovery */ - char* base = (char*)CALL_MORECORE(0); - if (base != CMFAIL) { - size_t fp; - /* Adjust to end on a page boundary */ - if (!is_page_aligned(base)) - asize += (page_align((size_t)base) - (size_t)base); - fp = m->footprint + asize; /* recheck limits */ - if (asize > nb && asize < HALF_MAX_SIZE_T && - (m->footprint_limit == 0 || - (fp > m->footprint && fp <= m->footprint_limit)) && - (br = (char*)(CALL_MORECORE(asize))) == base) { - tbase = base; - tsize = asize; - } - } - } - else { - /* Subtract out existing available top space from MORECORE request. */ - asize = granularity_align(nb - m->topsize + SYS_ALLOC_PADDING); - /* Use mem here only if it did continuously extend old space */ - if (asize < HALF_MAX_SIZE_T && - (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) { - tbase = br; - tsize = asize; - } - } - - if (tbase == CMFAIL) { /* Cope with partial failure */ - if (br != CMFAIL) { /* Try to use/extend the space we did get */ - if (asize < HALF_MAX_SIZE_T && - asize < nb + SYS_ALLOC_PADDING) { - size_t esize = granularity_align(nb + SYS_ALLOC_PADDING - asize); - if (esize < HALF_MAX_SIZE_T) { - char* end = (char*)CALL_MORECORE(esize); - if (end != CMFAIL) - asize += esize; - else { /* Can't use; try to release */ - (void) CALL_MORECORE(-asize); - br = CMFAIL; - } - } - } - } - if (br != CMFAIL) { /* Use the space we did get */ - tbase = br; - tsize = asize; - } - else - disable_contiguous(m); /* Don't try contiguous path in the future */ - } - - RELEASE_MALLOC_GLOBAL_LOCK(); - } - - if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ - char* mp = (char*)(CALL_MMAP(asize)); - if (mp != CMFAIL) { - tbase = mp; - tsize = asize; - mmap_flag = USE_MMAP_BIT; - } - } - - if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */ - if (asize < HALF_MAX_SIZE_T) { - char* br = CMFAIL; - char* end = CMFAIL; - ACQUIRE_MALLOC_GLOBAL_LOCK(); - br = (char*)(CALL_MORECORE(asize)); - end = (char*)(CALL_MORECORE(0)); - RELEASE_MALLOC_GLOBAL_LOCK(); - if (br != CMFAIL && end != CMFAIL && br < end) { - size_t ssize = end - br; - if (ssize > nb + TOP_FOOT_SIZE) { - tbase = br; - tsize = ssize; - } - } - } - } - - if (tbase != CMFAIL) { - - if ((m->footprint += tsize) > m->max_footprint) - m->max_footprint = m->footprint; - - if (!is_initialized(m)) { /* first-time initialization */ - if (m->least_addr == 0 || tbase < m->least_addr) - m->least_addr = tbase; - m->seg.base = tbase; - m->seg.size = tsize; - m->seg.sflags = mmap_flag; - m->magic = mparams.magic; - m->release_checks = MAX_RELEASE_CHECK_RATE; - init_bins(m); -#if !ONLY_MSPACES - if (is_global(m)) - init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); - else -#endif - { - /* Offset top by embedded malloc_state */ - mchunkptr mn = next_chunk(mem2chunk(m)); - init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE); - } - } - - else { - /* Try to merge with an existing segment */ - msegmentptr sp = &m->seg; - /* Only consider most recent segment if traversal suppressed */ - while (sp != 0 && tbase != sp->base + sp->size) - sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; - if (sp != 0 && - !is_extern_segment(sp) && - (sp->sflags & USE_MMAP_BIT) == mmap_flag && - segment_holds(sp, m->top)) { /* append */ - sp->size += tsize; - init_top(m, m->top, m->topsize + tsize); - } - else { - if (tbase < m->least_addr) - m->least_addr = tbase; - sp = &m->seg; - while (sp != 0 && sp->base != tbase + tsize) - sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; - if (sp != 0 && - !is_extern_segment(sp) && - (sp->sflags & USE_MMAP_BIT) == mmap_flag) { - char* oldbase = sp->base; - sp->base = tbase; - sp->size += tsize; - return prepend_alloc(m, tbase, oldbase, nb); - } - else - add_segment(m, tbase, tsize, mmap_flag); - } - } - - if (nb < m->topsize) { /* Allocate from new or extended top space */ - size_t rsize = m->topsize -= nb; - mchunkptr p = m->top; - mchunkptr r = m->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(m, p, nb); - check_top_chunk(m, m->top); - check_malloced_chunk(m, chunk2mem(p), nb); - return chunk2mem(p); - } - } - - MALLOC_FAILURE_ACTION; - return 0; -} - -/* ----------------------- system deallocation -------------------------- */ - -/* Unmap and unlink any mmapped segments that don't contain used chunks */ -static size_t release_unused_segments(mstate m) { - size_t released = 0; - int nsegs = 0; - msegmentptr pred = &m->seg; - msegmentptr sp = pred->next; - while (sp != 0) { - char* base = sp->base; - size_t size = sp->size; - msegmentptr next = sp->next; - ++nsegs; - if (is_mmapped_segment(sp) && !is_extern_segment(sp)) { - mchunkptr p = align_as_chunk(base); - size_t psize = chunksize(p); - /* Can unmap if first chunk holds entire segment and not pinned */ - if (!is_inuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) { - tchunkptr tp = (tchunkptr)p; - assert(segment_holds(sp, (char*)sp)); - if (p == m->dv) { - m->dv = 0; - m->dvsize = 0; - } - else { - unlink_large_chunk(m, tp); - } - if (CALL_MUNMAP(base, size) == 0) { - released += size; - m->footprint -= size; - /* unlink obsoleted record */ - sp = pred; - sp->next = next; - } - else { /* back out if cannot unmap */ - insert_large_chunk(m, tp, psize); - } - } - } - if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */ - break; - pred = sp; - sp = next; - } - /* Reset check counter */ - m->release_checks = ((nsegs > MAX_RELEASE_CHECK_RATE)? - nsegs : MAX_RELEASE_CHECK_RATE); - return released; -} - -static int sys_trim(mstate m, size_t pad) { - size_t released = 0; - ensure_initialization(); - if (pad < MAX_REQUEST && is_initialized(m)) { - pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ - - if (m->topsize > pad) { - /* Shrink top space in granularity-size units, keeping at least one */ - size_t unit = mparams.granularity; - size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - - SIZE_T_ONE) * unit; - msegmentptr sp = segment_holding(m, (char*)m->top); - - if (!is_extern_segment(sp)) { - if (is_mmapped_segment(sp)) { - if (HAVE_MMAP && - sp->size >= extra && - !has_segment_link(m, sp)) { /* can't shrink if pinned */ - size_t newsize = sp->size - extra; - /* Prefer mremap, fall back to munmap */ - if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) || - (CALL_MUNMAP(sp->base + newsize, extra) == 0)) { - released = extra; - } - } - } - else if (HAVE_MORECORE) { - if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ - extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit; - ACQUIRE_MALLOC_GLOBAL_LOCK(); - { - /* Make sure end of memory is where we last set it. */ - char* old_br = (char*)(CALL_MORECORE(0)); - if (old_br == sp->base + sp->size) { - char* rel_br = (char*)(CALL_MORECORE(-extra)); - char* new_br = (char*)(CALL_MORECORE(0)); - if (rel_br != CMFAIL && new_br < old_br) - released = old_br - new_br; - } - } - RELEASE_MALLOC_GLOBAL_LOCK(); - } - } - - if (released != 0) { - sp->size -= released; - m->footprint -= released; - init_top(m, m->top, m->topsize - released); - check_top_chunk(m, m->top); - } - } - - /* Unmap any unused mmapped segments */ - if (HAVE_MMAP) - released += release_unused_segments(m); - - /* On failure, disable autotrim to avoid repeated failed future calls */ - if (released == 0 && m->topsize > m->trim_check) - m->trim_check = MAX_SIZE_T; - } - - return (released != 0)? 1 : 0; -} - -/* Consolidate and bin a chunk. Differs from exported versions - of free mainly in that the chunk need not be marked as inuse. -*/ -static void dispose_chunk(mstate m, mchunkptr p, size_t psize) { - mchunkptr next = chunk_plus_offset(p, psize); - if (!pinuse(p)) { - mchunkptr prev; - size_t prevsize = p->prev_foot; - if (is_mmapped(p)) { - psize += prevsize + MMAP_FOOT_PAD; - if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) - m->footprint -= psize; - return; - } - prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if (RTCHECK(ok_address(m, prev))) { /* consolidate backward */ - if (p != m->dv) { - unlink_chunk(m, p, prevsize); - } - else if ((next->head & INUSE_BITS) == INUSE_BITS) { - m->dvsize = psize; - set_free_with_pinuse(p, psize, next); - return; - } - } - else { - CORRUPTION_ERROR_ACTION(m); - return; - } - } - if (RTCHECK(ok_address(m, next))) { - if (!cinuse(next)) { /* consolidate forward */ - if (next == m->top) { - size_t tsize = m->topsize += psize; - m->top = p; - p->head = tsize | PINUSE_BIT; - if (p == m->dv) { - m->dv = 0; - m->dvsize = 0; - } - return; - } - else if (next == m->dv) { - size_t dsize = m->dvsize += psize; - m->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - return; - } - else { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(m, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if (p == m->dv) { - m->dvsize = psize; - return; - } - } - } - else { - set_free_with_pinuse(p, psize, next); - } - insert_chunk(m, p, psize); - } - else { - CORRUPTION_ERROR_ACTION(m); - } -} - -/* ---------------------------- malloc --------------------------- */ - -/* allocate a large request from the best fitting chunk in a treebin */ -static void* tmalloc_large(mstate m, size_t nb) { - tchunkptr v = 0; - size_t rsize = -nb; /* Unsigned negation */ - tchunkptr t; - bindex_t idx; - compute_tree_index(nb, idx); - if ((t = *treebin_at(m, idx)) != 0) { - /* Traverse tree for this bin looking for node with size == nb */ - size_t sizebits = nb << leftshift_for_tree_index(idx); - tchunkptr rst = 0; /* The deepest untaken right subtree */ - for (;;) { - tchunkptr rt; - size_t trem = chunksize(t) - nb; - if (trem < rsize) { - v = t; - if ((rsize = trem) == 0) - break; - } - rt = t->child[1]; - t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; - if (rt != 0 && rt != t) - rst = rt; - if (t == 0) { - t = rst; /* set t to least subtree holding sizes > nb */ - break; - } - sizebits <<= 1; - } - } - if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */ - binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; - if (leftbits != 0) { - bindex_t i; - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - t = *treebin_at(m, i); - } - } - - while (t != 0) { /* find smallest of tree or subtree */ - size_t trem = chunksize(t) - nb; - if (trem < rsize) { - rsize = trem; - v = t; - } - t = leftmost_child(t); - } - - /* If dv is a better fit, return 0 so malloc will use it */ - if (v != 0 && rsize < (size_t)(m->dvsize - nb)) { - if (RTCHECK(ok_address(m, v))) { /* split */ - mchunkptr r = chunk_plus_offset(v, nb); - assert(chunksize(v) == rsize + nb); - if (RTCHECK(ok_next(v, r))) { - unlink_large_chunk(m, v); - if (rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(m, v, (rsize + nb)); - else { - set_size_and_pinuse_of_inuse_chunk(m, v, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - insert_chunk(m, r, rsize); - } - return chunk2mem(v); - } - } - CORRUPTION_ERROR_ACTION(m); - } - return 0; -} - -/* allocate a small request from the best fitting chunk in a treebin */ -static void* tmalloc_small(mstate m, size_t nb) { - tchunkptr t, v; - size_t rsize; - bindex_t i; - binmap_t leastbit = least_bit(m->treemap); - compute_bit2idx(leastbit, i); - v = t = *treebin_at(m, i); - rsize = chunksize(t) - nb; - - while ((t = leftmost_child(t)) != 0) { - size_t trem = chunksize(t) - nb; - if (trem < rsize) { - rsize = trem; - v = t; - } - } - - if (RTCHECK(ok_address(m, v))) { - mchunkptr r = chunk_plus_offset(v, nb); - assert(chunksize(v) == rsize + nb); - if (RTCHECK(ok_next(v, r))) { - unlink_large_chunk(m, v); - if (rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(m, v, (rsize + nb)); - else { - set_size_and_pinuse_of_inuse_chunk(m, v, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(m, r, rsize); - } - return chunk2mem(v); - } - } - - CORRUPTION_ERROR_ACTION(m); - return 0; -} - -#if !ONLY_MSPACES - -void* dlmalloc(size_t bytes) { - /* - Basic algorithm: - If a small request (< 256 bytes minus per-chunk overhead): - 1. If one exists, use a remainderless chunk in associated smallbin. - (Remainderless means that there are too few excess bytes to - represent as a chunk.) - 2. If it is big enough, use the dv chunk, which is normally the - chunk adjacent to the one used for the most recent small request. - 3. If one exists, split the smallest available chunk in a bin, - saving remainder in dv. - 4. If it is big enough, use the top chunk. - 5. If available, get memory from system and use it - Otherwise, for a large request: - 1. Find the smallest available binned chunk that fits, and use it - if it is better fitting than dv chunk, splitting if necessary. - 2. If better fitting than any binned chunk, use the dv chunk. - 3. If it is big enough, use the top chunk. - 4. If request size >= mmap threshold, try to directly mmap this chunk. - 5. If available, get memory from system and use it - - The ugly goto's here ensure that postaction occurs along all paths. - */ - -#if USE_LOCKS - ensure_initialization(); /* initialize in sys_alloc if not using locks */ -#endif - - if (!PREACTION(gm)) { - void* mem; - size_t nb; - if (bytes <= MAX_SMALL_REQUEST) { - bindex_t idx; - binmap_t smallbits; - nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); - idx = small_index(nb); - smallbits = gm->smallmap >> idx; - - if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ - mchunkptr b, p; - idx += ~smallbits & 1; /* Uses next bin if idx empty */ - b = smallbin_at(gm, idx); - p = b->fd; - assert(chunksize(p) == small_index2size(idx)); - unlink_first_small_chunk(gm, b, p, idx); - set_inuse_and_pinuse(gm, p, small_index2size(idx)); - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (nb > gm->dvsize) { - if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ - mchunkptr b, p, r; - size_t rsize; - bindex_t i; - binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - b = smallbin_at(gm, i); - p = b->fd; - assert(chunksize(p) == small_index2size(i)); - unlink_first_small_chunk(gm, b, p, i); - rsize = small_index2size(i) - nb; - /* Fit here cannot be remainderless if 4byte sizes */ - if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(gm, p, small_index2size(i)); - else { - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - r = chunk_plus_offset(p, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(gm, r, rsize); - } - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) { - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - } - } - else if (bytes >= MAX_REQUEST) - nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ - else { - nb = pad_request(bytes); - if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) { - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - } - - if (nb <= gm->dvsize) { - size_t rsize = gm->dvsize - nb; - mchunkptr p = gm->dv; - if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ - mchunkptr r = gm->dv = chunk_plus_offset(p, nb); - gm->dvsize = rsize; - set_size_and_pinuse_of_free_chunk(r, rsize); - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - } - else { /* exhaust dv */ - size_t dvs = gm->dvsize; - gm->dvsize = 0; - gm->dv = 0; - set_inuse_and_pinuse(gm, p, dvs); - } - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (nb < gm->topsize) { /* Split top */ - size_t rsize = gm->topsize -= nb; - mchunkptr p = gm->top; - mchunkptr r = gm->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - mem = chunk2mem(p); - check_top_chunk(gm, gm->top); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - mem = sys_alloc(gm, nb); - - postaction: - POSTACTION(gm); - return mem; - } - - return 0; -} - -/* ---------------------------- free --------------------------- */ - -void dlfree(void* mem) { - /* - Consolidate freed chunks with preceeding or succeeding bordering - free chunks, if they exist, and then place in a bin. Intermixed - with special cases for top, dv, mmapped chunks, and usage errors. - */ - - if (mem != 0) { - mchunkptr p = mem2chunk(mem); -#if FOOTERS - mstate fm = get_mstate_for(p); - if (!ok_magic(fm)) { - USAGE_ERROR_ACTION(fm, p); - return; - } -#else /* FOOTERS */ -#define fm gm -#endif /* FOOTERS */ - if (!PREACTION(fm)) { - check_inuse_chunk(fm, p); - if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { - size_t psize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, psize); - if (!pinuse(p)) { - size_t prevsize = p->prev_foot; - if (is_mmapped(p)) { - psize += prevsize + MMAP_FOOT_PAD; - if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) - fm->footprint -= psize; - goto postaction; - } - else { - mchunkptr prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ - if (p != fm->dv) { - unlink_chunk(fm, p, prevsize); - } - else if ((next->head & INUSE_BITS) == INUSE_BITS) { - fm->dvsize = psize; - set_free_with_pinuse(p, psize, next); - goto postaction; - } - } - else - goto erroraction; - } - } - - if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { - if (!cinuse(next)) { /* consolidate forward */ - if (next == fm->top) { - size_t tsize = fm->topsize += psize; - fm->top = p; - p->head = tsize | PINUSE_BIT; - if (p == fm->dv) { - fm->dv = 0; - fm->dvsize = 0; - } - if (should_trim(fm, tsize)) - sys_trim(fm, 0); - goto postaction; - } - else if (next == fm->dv) { - size_t dsize = fm->dvsize += psize; - fm->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - goto postaction; - } - else { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(fm, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if (p == fm->dv) { - fm->dvsize = psize; - goto postaction; - } - } - } - else - set_free_with_pinuse(p, psize, next); - - if (is_small(psize)) { - insert_small_chunk(fm, p, psize); - check_free_chunk(fm, p); - } - else { - tchunkptr tp = (tchunkptr)p; - insert_large_chunk(fm, tp, psize); - check_free_chunk(fm, p); - if (--fm->release_checks == 0) - release_unused_segments(fm); - } - goto postaction; - } - } - erroraction: - USAGE_ERROR_ACTION(fm, p); - postaction: - POSTACTION(fm); - } - } -#if !FOOTERS -#undef fm -#endif /* FOOTERS */ -} - -void* dlcalloc(size_t n_elements, size_t elem_size) { - void* mem; - size_t req = 0; - if (n_elements != 0) { - req = n_elements * elem_size; - if (((n_elements | elem_size) & ~(size_t)0xffff) && - (req / n_elements != elem_size)) - req = MAX_SIZE_T; /* force downstream failure on overflow */ - } - mem = dlmalloc(req); - if (mem != 0 && calloc_must_clear(mem2chunk(mem))) - memset(mem, 0, req); - return mem; -} - -#endif /* !ONLY_MSPACES */ - -/* ------------ Internal support for realloc, memalign, etc -------------- */ - -/* Try to realloc; only in-place unless can_move true */ -static mchunkptr try_realloc_chunk(mstate m, mchunkptr p, size_t nb, - int can_move) { - mchunkptr newp = 0; - size_t oldsize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, oldsize); - if (RTCHECK(ok_address(m, p) && ok_inuse(p) && - ok_next(p, next) && ok_pinuse(next))) { - if (is_mmapped(p)) { - newp = mmap_resize(m, p, nb, can_move); - } - else if (oldsize >= nb) { /* already big enough */ - size_t rsize = oldsize - nb; - if (rsize >= MIN_CHUNK_SIZE) { /* split off remainder */ - mchunkptr r = chunk_plus_offset(p, nb); - set_inuse(m, p, nb); - set_inuse(m, r, rsize); - dispose_chunk(m, r, rsize); - } - newp = p; - } - else if (next == m->top) { /* extend into top */ - if (oldsize + m->topsize > nb) { - size_t newsize = oldsize + m->topsize; - size_t newtopsize = newsize - nb; - mchunkptr newtop = chunk_plus_offset(p, nb); - set_inuse(m, p, nb); - newtop->head = newtopsize |PINUSE_BIT; - m->top = newtop; - m->topsize = newtopsize; - newp = p; - } - } - else if (next == m->dv) { /* extend into dv */ - size_t dvs = m->dvsize; - if (oldsize + dvs >= nb) { - size_t dsize = oldsize + dvs - nb; - if (dsize >= MIN_CHUNK_SIZE) { - mchunkptr r = chunk_plus_offset(p, nb); - mchunkptr n = chunk_plus_offset(r, dsize); - set_inuse(m, p, nb); - set_size_and_pinuse_of_free_chunk(r, dsize); - clear_pinuse(n); - m->dvsize = dsize; - m->dv = r; - } - else { /* exhaust dv */ - size_t newsize = oldsize + dvs; - set_inuse(m, p, newsize); - m->dvsize = 0; - m->dv = 0; - } - newp = p; - } - } - else if (!cinuse(next)) { /* extend into next free chunk */ - size_t nextsize = chunksize(next); - if (oldsize + nextsize >= nb) { - size_t rsize = oldsize + nextsize - nb; - unlink_chunk(m, next, nextsize); - if (rsize < MIN_CHUNK_SIZE) { - size_t newsize = oldsize + nextsize; - set_inuse(m, p, newsize); - } - else { - mchunkptr r = chunk_plus_offset(p, nb); - set_inuse(m, p, nb); - set_inuse(m, r, rsize); - dispose_chunk(m, r, rsize); - } - newp = p; - } - } - } - else { - USAGE_ERROR_ACTION(m, oldmem); - } - return newp; -} - -static void* internal_memalign(mstate m, size_t alignment, size_t bytes) { - void* mem = 0; - if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ - alignment = MIN_CHUNK_SIZE; - if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */ - size_t a = MALLOC_ALIGNMENT << 1; - while (a < alignment) a <<= 1; - alignment = a; - } - if (bytes >= MAX_REQUEST - alignment) { - if (m != 0) { /* Test isn't needed but avoids compiler warning */ - MALLOC_FAILURE_ACTION; - } - } - else { - size_t nb = request2size(bytes); - size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; - mem = internal_malloc(m, req); - if (mem != 0) { - mchunkptr p = mem2chunk(mem); - if (PREACTION(m)) - return 0; - if ((((size_t)(mem)) & (alignment - 1)) != 0) { /* misaligned */ - /* - Find an aligned spot inside chunk. Since we need to give - back leading space in a chunk of at least MIN_CHUNK_SIZE, if - the first calculation places us at a spot with less than - MIN_CHUNK_SIZE leader, we can move to the next aligned spot. - We've allocated enough total room so that this is always - possible. - */ - char* br = (char*)mem2chunk((size_t)(((size_t)((char*)mem + alignment - - SIZE_T_ONE)) & - -alignment)); - char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)? - br : br+alignment; - mchunkptr newp = (mchunkptr)pos; - size_t leadsize = pos - (char*)(p); - size_t newsize = chunksize(p) - leadsize; - - if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ - newp->prev_foot = p->prev_foot + leadsize; - newp->head = newsize; - } - else { /* Otherwise, give back leader, use the rest */ - set_inuse(m, newp, newsize); - set_inuse(m, p, leadsize); - dispose_chunk(m, p, leadsize); - } - p = newp; - } - - /* Give back spare room at the end */ - if (!is_mmapped(p)) { - size_t size = chunksize(p); - if (size > nb + MIN_CHUNK_SIZE) { - size_t remainder_size = size - nb; - mchunkptr remainder = chunk_plus_offset(p, nb); - set_inuse(m, p, nb); - set_inuse(m, remainder, remainder_size); - dispose_chunk(m, remainder, remainder_size); - } - } - - mem = chunk2mem(p); - assert (chunksize(p) >= nb); - assert(((size_t)mem & (alignment - 1)) == 0); - check_inuse_chunk(m, p); - POSTACTION(m); - } - } - return mem; -} - -/* - Common support for independent_X routines, handling - all of the combinations that can result. - The opts arg has: - bit 0 set if all elements are same size (using sizes[0]) - bit 1 set if elements should be zeroed -*/ -static void** ialloc(mstate m, - size_t n_elements, - size_t* sizes, - int opts, - void* chunks[]) { - - size_t element_size; /* chunksize of each element, if all same */ - size_t contents_size; /* total size of elements */ - size_t array_size; /* request size of pointer array */ - void* mem; /* malloced aggregate space */ - mchunkptr p; /* corresponding chunk */ - size_t remainder_size; /* remaining bytes while splitting */ - void** marray; /* either "chunks" or malloced ptr array */ - mchunkptr array_chunk; /* chunk for malloced ptr array */ - flag_t was_enabled; /* to disable mmap */ - size_t size; - size_t i; - - ensure_initialization(); - /* compute array length, if needed */ - if (chunks != 0) { - if (n_elements == 0) - return chunks; /* nothing to do */ - marray = chunks; - array_size = 0; - } - else { - /* if empty req, must still return chunk representing empty array */ - if (n_elements == 0) - return (void**)internal_malloc(m, 0); - marray = 0; - array_size = request2size(n_elements * (sizeof(void*))); - } - - /* compute total element size */ - if (opts & 0x1) { /* all-same-size */ - element_size = request2size(*sizes); - contents_size = n_elements * element_size; - } - else { /* add up all the sizes */ - element_size = 0; - contents_size = 0; - for (i = 0; i != n_elements; ++i) - contents_size += request2size(sizes[i]); - } - - size = contents_size + array_size; - - /* - Allocate the aggregate chunk. First disable direct-mmapping so - malloc won't use it, since we would not be able to later - free/realloc space internal to a segregated mmap region. - */ - was_enabled = use_mmap(m); - disable_mmap(m); - mem = internal_malloc(m, size - CHUNK_OVERHEAD); - if (was_enabled) - enable_mmap(m); - if (mem == 0) - return 0; - - if (PREACTION(m)) return 0; - p = mem2chunk(mem); - remainder_size = chunksize(p); - - assert(!is_mmapped(p)); - - if (opts & 0x2) { /* optionally clear the elements */ - memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size); - } - - /* If not provided, allocate the pointer array as final part of chunk */ - if (marray == 0) { - size_t array_chunk_size; - array_chunk = chunk_plus_offset(p, contents_size); - array_chunk_size = remainder_size - contents_size; - marray = (void**) (chunk2mem(array_chunk)); - set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); - remainder_size = contents_size; - } - - /* split out elements */ - for (i = 0; ; ++i) { - marray[i] = chunk2mem(p); - if (i != n_elements-1) { - if (element_size != 0) - size = element_size; - else - size = request2size(sizes[i]); - remainder_size -= size; - set_size_and_pinuse_of_inuse_chunk(m, p, size); - p = chunk_plus_offset(p, size); - } - else { /* the final element absorbs any overallocation slop */ - set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); - break; - } - } - -#if DEBUG - if (marray != chunks) { - /* final element must have exactly exhausted chunk */ - if (element_size != 0) { - assert(remainder_size == element_size); - } - else { - assert(remainder_size == request2size(sizes[i])); - } - check_inuse_chunk(m, mem2chunk(marray)); - } - for (i = 0; i != n_elements; ++i) - check_inuse_chunk(m, mem2chunk(marray[i])); - -#endif /* DEBUG */ - - POSTACTION(m); - return marray; -} - -/* Try to free all pointers in the given array. - Note: this could be made faster, by delaying consolidation, - at the price of disabling some user integrity checks, We - still optimize some consolidations by combining adjacent - chunks before freeing, which will occur often if allocated - with ialloc or the array is sorted. -*/ -static size_t internal_bulk_free(mstate m, void* array[], size_t nelem) { - size_t unfreed = 0; - if (!PREACTION(m)) { - void** a; - void** fence = &(array[nelem]); - for (a = array; a != fence; ++a) { - void* mem = *a; - if (mem != 0) { - mchunkptr p = mem2chunk(mem); - size_t psize = chunksize(p); -#if FOOTERS - if (get_mstate_for(p) != m) { - ++unfreed; - continue; - } -#endif - check_inuse_chunk(m, p); - *a = 0; - if (RTCHECK(ok_address(m, p) && ok_inuse(p))) { - void ** b = a + 1; /* try to merge with next chunk */ - mchunkptr next = next_chunk(p); - if (b != fence && *b == chunk2mem(next)) { - size_t newsize = chunksize(next) + psize; - set_inuse(m, p, newsize); - *b = chunk2mem(p); - } - else - dispose_chunk(m, p, psize); - } - else { - CORRUPTION_ERROR_ACTION(m); - break; - } - } - } - if (should_trim(m, m->topsize)) - sys_trim(m, 0); - POSTACTION(m); - } - return unfreed; -} - -/* Traversal */ -#if MALLOC_INSPECT_ALL -static void internal_inspect_all(mstate m, - void(*handler)(void *start, - void *end, - size_t used_bytes, - void* callback_arg), - void* arg) { - if (is_initialized(m)) { - mchunkptr top = m->top; - msegmentptr s; - for (s = &m->seg; s != 0; s = s->next) { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && q->head != FENCEPOST_HEAD) { - mchunkptr next = next_chunk(q); - size_t sz = chunksize(q); - size_t used; - void* start; - if (is_inuse(q)) { - used = sz - CHUNK_OVERHEAD; /* must not be mmapped */ - start = chunk2mem(q); - } - else { - used = 0; - if (is_small(sz)) { /* offset by possible bookkeeping */ - start = (void*)((char*)q + sizeof(malloc_chunk)); - } - else { - start = (void*)((char*)q + sizeof(malloc_tree_chunk)); - } - } - if (start < (void*)next) /* skip if all space is bookkeeping */ - handler(start, next, used, arg); - if (q == top) - break; - q = next; - } - } - } -} -#endif /* MALLOC_INSPECT_ALL */ - -/* ------------------ Exported realloc, memalign, etc -------------------- */ - -#if !ONLY_MSPACES - -void* dlrealloc(void* oldmem, size_t bytes) { - void* mem = 0; - if (oldmem == 0) { - mem = dlmalloc(bytes); - } - else if (bytes >= MAX_REQUEST) { - MALLOC_FAILURE_ACTION; - } -#ifdef REALLOC_ZERO_BYTES_FREES - else if (bytes == 0) { - dlfree(oldmem); - } -#endif /* REALLOC_ZERO_BYTES_FREES */ - else { - size_t nb = request2size(bytes); - mchunkptr oldp = mem2chunk(oldmem); -#if ! FOOTERS - mstate m = gm; -#else /* FOOTERS */ - mstate m = get_mstate_for(oldp); - if (!ok_magic(m)) { - USAGE_ERROR_ACTION(m, oldmem); - return 0; - } -#endif /* FOOTERS */ - if (!PREACTION(m)) { - mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1); - POSTACTION(m); - if (newp != 0) { - check_inuse_chunk(m, newp); - mem = chunk2mem(newp); - } - else { - mem = internal_malloc(m, bytes); - if (mem != 0) { - size_t oc = chunksize(oldp) - overhead_for(oldp); - memcpy(mem, oldmem, (oc < bytes)? oc : bytes); - internal_free(m, oldmem); - } - } - } - } - return mem; -} - -void* dlrealloc_in_place(void* oldmem, size_t bytes) { - void* mem = 0; - if (oldmem != 0) { - if (bytes >= MAX_REQUEST) { - MALLOC_FAILURE_ACTION; - } - else { - size_t nb = request2size(bytes); - mchunkptr oldp = mem2chunk(oldmem); -#if ! FOOTERS - mstate m = gm; -#else /* FOOTERS */ - mstate m = get_mstate_for(oldp); - if (!ok_magic(m)) { - USAGE_ERROR_ACTION(m, oldmem); - return 0; - } -#endif /* FOOTERS */ - if (!PREACTION(m)) { - mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0); - POSTACTION(m); - if (newp == oldp) { - check_inuse_chunk(m, newp); - mem = oldmem; - } - } - } - } - return mem; -} - -void* dlmemalign(size_t alignment, size_t bytes) { - if (alignment <= MALLOC_ALIGNMENT) { - return dlmalloc(bytes); - } - return internal_memalign(gm, alignment, bytes); -} - -int dlposix_memalign(void** pp, size_t alignment, size_t bytes) { - void* mem = 0; - if (alignment == MALLOC_ALIGNMENT) - mem = dlmalloc(bytes); - else { - size_t d = alignment / sizeof(void*); - size_t r = alignment % sizeof(void*); - if (r != 0 || d == 0 || (d & (d-SIZE_T_ONE)) != 0) - return EINVAL; - else if (bytes >= MAX_REQUEST - alignment) { - if (alignment < MIN_CHUNK_SIZE) - alignment = MIN_CHUNK_SIZE; - mem = internal_memalign(gm, alignment, bytes); - } - } - if (mem == 0) - return ENOMEM; - else { - *pp = mem; - return 0; - } -} - -void* dlvalloc(size_t bytes) { - size_t pagesz; - ensure_initialization(); - pagesz = mparams.page_size; - return dlmemalign(pagesz, bytes); -} - -void* dlpvalloc(size_t bytes) { - size_t pagesz; - ensure_initialization(); - pagesz = mparams.page_size; - return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); -} - -void** dlindependent_calloc(size_t n_elements, size_t elem_size, - void* chunks[]) { - size_t sz = elem_size; /* serves as 1-element array */ - return ialloc(gm, n_elements, &sz, 3, chunks); -} - -void** dlindependent_comalloc(size_t n_elements, size_t sizes[], - void* chunks[]) { - return ialloc(gm, n_elements, sizes, 0, chunks); -} - -size_t dlbulk_free(void* array[], size_t nelem) { - return internal_bulk_free(gm, array, nelem); -} - -#if MALLOC_INSPECT_ALL -void dlmalloc_inspect_all(void(*handler)(void *start, - void *end, - size_t used_bytes, - void* callback_arg), - void* arg) { - ensure_initialization(); - if (!PREACTION(gm)) { - internal_inspect_all(gm, handler, arg); - POSTACTION(gm); - } -} -#endif /* MALLOC_INSPECT_ALL */ - -int dlmalloc_trim(size_t pad) { - int result = 0; - ensure_initialization(); - if (!PREACTION(gm)) { - result = sys_trim(gm, pad); - POSTACTION(gm); - } - return result; -} - -size_t dlmalloc_footprint(void) { - return gm->footprint; -} - -size_t dlmalloc_max_footprint(void) { - return gm->max_footprint; -} - -size_t dlmalloc_footprint_limit(void) { - size_t maf = gm->footprint_limit; - return maf == 0 ? MAX_SIZE_T : maf; -} - -size_t dlmalloc_set_footprint_limit(size_t bytes) { - size_t result; /* invert sense of 0 */ - if (bytes == 0) - result = granularity_align(1); /* Use minimal size */ - if (bytes == MAX_SIZE_T) - result = 0; /* disable */ - else - result = granularity_align(bytes); - return gm->footprint_limit = result; -} - -#if !NO_MALLINFO -struct mallinfo dlmallinfo(void) { - return internal_mallinfo(gm); -} -#endif /* NO_MALLINFO */ - -#if !NO_MALLOC_STATS -void dlmalloc_stats() { - internal_malloc_stats(gm); -} -#endif /* NO_MALLOC_STATS */ - -int dlmallopt(int param_number, int value) { - return change_mparam(param_number, value); -} - -size_t dlmalloc_usable_size(void* mem) { - if (mem != 0) { - mchunkptr p = mem2chunk(mem); - if (is_inuse(p)) - return chunksize(p) - overhead_for(p); - } - return 0; -} - -#endif /* !ONLY_MSPACES */ - -/* ----------------------------- user mspaces ---------------------------- */ - -#if MSPACES - -static mstate init_user_mstate(char* tbase, size_t tsize) { - size_t msize = pad_request(sizeof(struct malloc_state)); - mchunkptr mn; - mchunkptr msp = align_as_chunk(tbase); - mstate m = (mstate)(chunk2mem(msp)); - memset(m, 0, msize); - (void)INITIAL_LOCK(&m->mutex); - msp->head = (msize|INUSE_BITS); - m->seg.base = m->least_addr = tbase; - m->seg.size = m->footprint = m->max_footprint = tsize; - m->magic = mparams.magic; - m->release_checks = MAX_RELEASE_CHECK_RATE; - m->mflags = mparams.default_mflags; - m->extp = 0; - m->exts = 0; - disable_contiguous(m); - init_bins(m); - mn = next_chunk(mem2chunk(m)); - init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE); - check_top_chunk(m, m->top); - return m; -} - -mspace create_mspace(size_t capacity, int locked) { - mstate m = 0; - size_t msize; - ensure_initialization(); - msize = pad_request(sizeof(struct malloc_state)); - if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { - size_t rs = ((capacity == 0)? mparams.granularity : - (capacity + TOP_FOOT_SIZE + msize)); - size_t tsize = granularity_align(rs); - char* tbase = (char*)(CALL_MMAP(tsize)); - if (tbase != CMFAIL) { - m = init_user_mstate(tbase, tsize); - m->seg.sflags = USE_MMAP_BIT; - set_lock(m, locked); - } - } - return (mspace)m; -} - -mspace create_mspace_with_base(void* base, size_t capacity, int locked) { - mstate m = 0; - size_t msize; - ensure_initialization(); - msize = pad_request(sizeof(struct malloc_state)); - if (capacity > msize + TOP_FOOT_SIZE && - capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { - m = init_user_mstate((char*)base, capacity); - m->seg.sflags = EXTERN_BIT; - set_lock(m, locked); - } - return (mspace)m; -} - -int mspace_track_large_chunks(mspace msp, int enable) { - int ret = 0; - mstate ms = (mstate)msp; - if (!PREACTION(ms)) { - if (!use_mmap(ms)) - ret = 1; - if (!enable) - enable_mmap(ms); - else - disable_mmap(ms); - POSTACTION(ms); - } - return ret; -} - -size_t destroy_mspace(mspace msp) { - size_t freed = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - msegmentptr sp = &ms->seg; - (void)DESTROY_LOCK(&ms->mutex); /* destroy before unmapped */ - while (sp != 0) { - char* base = sp->base; - size_t size = sp->size; - flag_t flag = sp->sflags; - sp = sp->next; - if ((flag & USE_MMAP_BIT) && !(flag & EXTERN_BIT) && - CALL_MUNMAP(base, size) == 0) - freed += size; - } - } - else { - USAGE_ERROR_ACTION(ms,ms); - } - return freed; -} - -/* - mspace versions of routines are near-clones of the global - versions. This is not so nice but better than the alternatives. -*/ - -void* mspace_malloc(mspace msp, size_t bytes) { - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - if (!PREACTION(ms)) { - void* mem; - size_t nb; - if (bytes <= MAX_SMALL_REQUEST) { - bindex_t idx; - binmap_t smallbits; - nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); - idx = small_index(nb); - smallbits = ms->smallmap >> idx; - - if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ - mchunkptr b, p; - idx += ~smallbits & 1; /* Uses next bin if idx empty */ - b = smallbin_at(ms, idx); - p = b->fd; - assert(chunksize(p) == small_index2size(idx)); - unlink_first_small_chunk(ms, b, p, idx); - set_inuse_and_pinuse(ms, p, small_index2size(idx)); - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (nb > ms->dvsize) { - if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ - mchunkptr b, p, r; - size_t rsize; - bindex_t i; - binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - b = smallbin_at(ms, i); - p = b->fd; - assert(chunksize(p) == small_index2size(i)); - unlink_first_small_chunk(ms, b, p, i); - rsize = small_index2size(i) - nb; - /* Fit here cannot be remainderless if 4byte sizes */ - if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(ms, p, small_index2size(i)); - else { - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - r = chunk_plus_offset(p, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(ms, r, rsize); - } - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) { - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - } - } - else if (bytes >= MAX_REQUEST) - nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ - else { - nb = pad_request(bytes); - if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) { - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - } - - if (nb <= ms->dvsize) { - size_t rsize = ms->dvsize - nb; - mchunkptr p = ms->dv; - if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ - mchunkptr r = ms->dv = chunk_plus_offset(p, nb); - ms->dvsize = rsize; - set_size_and_pinuse_of_free_chunk(r, rsize); - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - } - else { /* exhaust dv */ - size_t dvs = ms->dvsize; - ms->dvsize = 0; - ms->dv = 0; - set_inuse_and_pinuse(ms, p, dvs); - } - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (nb < ms->topsize) { /* Split top */ - size_t rsize = ms->topsize -= nb; - mchunkptr p = ms->top; - mchunkptr r = ms->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - mem = chunk2mem(p); - check_top_chunk(ms, ms->top); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - mem = sys_alloc(ms, nb); - - postaction: - POSTACTION(ms); - return mem; - } - - return 0; -} - -void mspace_free(mspace msp, void* mem) { - if (mem != 0) { - mchunkptr p = mem2chunk(mem); -#if FOOTERS - mstate fm = get_mstate_for(p); - msp = msp; /* placate people compiling -Wunused */ -#else /* FOOTERS */ - mstate fm = (mstate)msp; -#endif /* FOOTERS */ - if (!ok_magic(fm)) { - USAGE_ERROR_ACTION(fm, p); - return; - } - if (!PREACTION(fm)) { - check_inuse_chunk(fm, p); - if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { - size_t psize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, psize); - if (!pinuse(p)) { - size_t prevsize = p->prev_foot; - if (is_mmapped(p)) { - psize += prevsize + MMAP_FOOT_PAD; - if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) - fm->footprint -= psize; - goto postaction; - } - else { - mchunkptr prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ - if (p != fm->dv) { - unlink_chunk(fm, p, prevsize); - } - else if ((next->head & INUSE_BITS) == INUSE_BITS) { - fm->dvsize = psize; - set_free_with_pinuse(p, psize, next); - goto postaction; - } - } - else - goto erroraction; - } - } - - if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { - if (!cinuse(next)) { /* consolidate forward */ - if (next == fm->top) { - size_t tsize = fm->topsize += psize; - fm->top = p; - p->head = tsize | PINUSE_BIT; - if (p == fm->dv) { - fm->dv = 0; - fm->dvsize = 0; - } - if (should_trim(fm, tsize)) - sys_trim(fm, 0); - goto postaction; - } - else if (next == fm->dv) { - size_t dsize = fm->dvsize += psize; - fm->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - goto postaction; - } - else { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(fm, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if (p == fm->dv) { - fm->dvsize = psize; - goto postaction; - } - } - } - else - set_free_with_pinuse(p, psize, next); - - if (is_small(psize)) { - insert_small_chunk(fm, p, psize); - check_free_chunk(fm, p); - } - else { - tchunkptr tp = (tchunkptr)p; - insert_large_chunk(fm, tp, psize); - check_free_chunk(fm, p); - if (--fm->release_checks == 0) - release_unused_segments(fm); - } - goto postaction; - } - } - erroraction: - USAGE_ERROR_ACTION(fm, p); - postaction: - POSTACTION(fm); - } - } -} - -void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) { - void* mem; - size_t req = 0; - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - if (n_elements != 0) { - req = n_elements * elem_size; - if (((n_elements | elem_size) & ~(size_t)0xffff) && - (req / n_elements != elem_size)) - req = MAX_SIZE_T; /* force downstream failure on overflow */ - } - mem = internal_malloc(ms, req); - if (mem != 0 && calloc_must_clear(mem2chunk(mem))) - memset(mem, 0, req); - return mem; -} - -void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) { - void* mem = 0; - if (oldmem == 0) { - mem = mspace_malloc(msp, bytes); - } - else if (bytes >= MAX_REQUEST) { - MALLOC_FAILURE_ACTION; - } -#ifdef REALLOC_ZERO_BYTES_FREES - else if (bytes == 0) { - mspace_free(msp, oldmem); - } -#endif /* REALLOC_ZERO_BYTES_FREES */ - else { - size_t nb = request2size(bytes); - mchunkptr oldp = mem2chunk(oldmem); -#if ! FOOTERS - mstate m = (mstate)msp; -#else /* FOOTERS */ - mstate m = get_mstate_for(oldp); - if (!ok_magic(m)) { - USAGE_ERROR_ACTION(m, oldmem); - return 0; - } -#endif /* FOOTERS */ - if (!PREACTION(m)) { - mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1); - POSTACTION(m); - if (newp != 0) { - check_inuse_chunk(m, newp); - mem = chunk2mem(newp); - } - else { - mem = mspace_malloc(m, bytes); - if (mem != 0) { - size_t oc = chunksize(oldp) - overhead_for(oldp); - memcpy(mem, oldmem, (oc < bytes)? oc : bytes); - mspace_free(m, oldmem); - } - } - } - } - return mem; -} - -void* mspace_realloc_in_place(mspace msp, void* oldmem, size_t bytes) { - void* mem = 0; - if (oldmem != 0) { - if (bytes >= MAX_REQUEST) { - MALLOC_FAILURE_ACTION; - } - else { - size_t nb = request2size(bytes); - mchunkptr oldp = mem2chunk(oldmem); -#if ! FOOTERS - mstate m = (mstate)msp; -#else /* FOOTERS */ - mstate m = get_mstate_for(oldp); - msp = msp; /* placate people compiling -Wunused */ - if (!ok_magic(m)) { - USAGE_ERROR_ACTION(m, oldmem); - return 0; - } -#endif /* FOOTERS */ - if (!PREACTION(m)) { - mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0); - POSTACTION(m); - if (newp == oldp) { - check_inuse_chunk(m, newp); - mem = oldmem; - } - } - } - } - return mem; -} - -void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) { - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - if (alignment <= MALLOC_ALIGNMENT) - return mspace_malloc(msp, bytes); - return internal_memalign(ms, alignment, bytes); -} - -void** mspace_independent_calloc(mspace msp, size_t n_elements, - size_t elem_size, void* chunks[]) { - size_t sz = elem_size; /* serves as 1-element array */ - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - return ialloc(ms, n_elements, &sz, 3, chunks); -} - -void** mspace_independent_comalloc(mspace msp, size_t n_elements, - size_t sizes[], void* chunks[]) { - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - return ialloc(ms, n_elements, sizes, 0, chunks); -} - -size_t mspace_bulk_free(mspace msp, void* array[], size_t nelem) { - return internal_bulk_free((mstate)msp, array, nelem); -} - -#if MALLOC_INSPECT_ALL -void mspace_inspect_all(mspace msp, - void(*handler)(void *start, - void *end, - size_t used_bytes, - void* callback_arg), - void* arg) { - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - if (!PREACTION(ms)) { - internal_inspect_all(ms, handler, arg); - POSTACTION(ms); - } - } - else { - USAGE_ERROR_ACTION(ms,ms); - } -} -#endif /* MALLOC_INSPECT_ALL */ - -int mspace_trim(mspace msp, size_t pad) { - int result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - if (!PREACTION(ms)) { - result = sys_trim(ms, pad); - POSTACTION(ms); - } - } - else { - USAGE_ERROR_ACTION(ms,ms); - } - return result; -} - -#if !NO_MALLOC_STATS -void mspace_malloc_stats(mspace msp) { - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - internal_malloc_stats(ms); - } - else { - USAGE_ERROR_ACTION(ms,ms); - } -} -#endif /* NO_MALLOC_STATS */ - -size_t mspace_footprint(mspace msp) { - size_t result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - result = ms->footprint; - } - else { - USAGE_ERROR_ACTION(ms,ms); - } - return result; -} - -size_t mspace_max_footprint(mspace msp) { - size_t result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - result = ms->max_footprint; - } - else { - USAGE_ERROR_ACTION(ms,ms); - } - return result; -} - -size_t mspace_footprint_limit(mspace msp) { - size_t result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - size_t maf = ms->footprint_limit; - result = (maf == 0) ? MAX_SIZE_T : maf; - } - else { - USAGE_ERROR_ACTION(ms,ms); - } - return result; -} - -size_t mspace_set_footprint_limit(mspace msp, size_t bytes) { - size_t result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - if (bytes == 0) - result = granularity_align(1); /* Use minimal size */ - if (bytes == MAX_SIZE_T) - result = 0; /* disable */ - else - result = granularity_align(bytes); - ms->footprint_limit = result; - } - else { - USAGE_ERROR_ACTION(ms,ms); - } - return result; -} - -#if !NO_MALLINFO -struct mallinfo mspace_mallinfo(mspace msp) { - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - } - return internal_mallinfo(ms); -} -#endif /* NO_MALLINFO */ - -size_t mspace_usable_size(void* mem) { - if (mem != 0) { - mchunkptr p = mem2chunk(mem); - if (is_inuse(p)) - return chunksize(p) - overhead_for(p); - } - return 0; -} - -int mspace_mallopt(int param_number, int value) { - return change_mparam(param_number, value); -} - -#endif /* MSPACES */ - - -/* -------------------- Alternative MORECORE functions ------------------- */ - -/* - Guidelines for creating a custom version of MORECORE: - - * For best performance, MORECORE should allocate in multiples of pagesize. - * MORECORE may allocate more memory than requested. (Or even less, - but this will usually result in a malloc failure.) - * MORECORE must not allocate memory when given argument zero, but - instead return one past the end address of memory from previous - nonzero call. - * For best performance, consecutive calls to MORECORE with positive - arguments should return increasing addresses, indicating that - space has been contiguously extended. - * Even though consecutive calls to MORECORE need not return contiguous - addresses, it must be OK for malloc'ed chunks to span multiple - regions in those cases where they do happen to be contiguous. - * MORECORE need not handle negative arguments -- it may instead - just return MFAIL when given negative arguments. - Negative arguments are always multiples of pagesize. MORECORE - must not misinterpret negative args as large positive unsigned - args. You can suppress all such calls from even occurring by defining - MORECORE_CANNOT_TRIM, - - As an example alternative MORECORE, here is a custom allocator - kindly contributed for pre-OSX macOS. It uses virtually but not - necessarily physically contiguous non-paged memory (locked in, - present and won't get swapped out). You can use it by uncommenting - this section, adding some #includes, and setting up the appropriate - defines above: - - #define MORECORE osMoreCore - - There is also a shutdown routine that should somehow be called for - cleanup upon program exit. - - #define MAX_POOL_ENTRIES 100 - #define MINIMUM_MORECORE_SIZE (64 * 1024U) - static int next_os_pool; - void *our_os_pools[MAX_POOL_ENTRIES]; - - void *osMoreCore(int size) - { - void *ptr = 0; - static void *sbrk_top = 0; - - if (size > 0) - { - if (size < MINIMUM_MORECORE_SIZE) - size = MINIMUM_MORECORE_SIZE; - if (CurrentExecutionLevel() == kTaskLevel) - ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); - if (ptr == 0) - { - return (void *) MFAIL; - } - // save ptrs so they can be freed during cleanup - our_os_pools[next_os_pool] = ptr; - next_os_pool++; - ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); - sbrk_top = (char *) ptr + size; - return ptr; - } - else if (size < 0) - { - // we don't currently support shrink behavior - return (void *) MFAIL; - } - else - { - return sbrk_top; - } - } - - // cleanup any allocated memory pools - // called as last thing before shutting down driver - - void osCleanupMem(void) - { - void **ptr; - - for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) - if (*ptr) - { - PoolDeallocate(*ptr); - *ptr = 0; - } - } - -*/ - - -/* ----------------------------------------------------------------------- -History: - v2.8.5 Sun May 22 10:26:02 2011 Doug Lea (dl at gee) - * Always perform unlink checks unless INSECURE - * Add posix_memalign. - * Improve realloc to expand in more cases; expose realloc_in_place. - Thanks to Peter Buhr for the suggestion. - * Add footprint_limit, inspect_all, bulk_free. Thanks - to Barry Hayes and others for the suggestions. - * Internal refactorings to avoid calls while holding locks - * Use non-reentrant locks by default. Thanks to Roland McGrath - for the suggestion. - * Small fixes to mspace_destroy, reset_on_error. - * Various configuration extensions/changes. Thanks - to all who contributed these. - - V2.8.4a Thu Apr 28 14:39:43 2011 (dl at gee.cs.oswego.edu) - * Update Creative Commons URL - - V2.8.4 Wed May 27 09:56:23 2009 Doug Lea (dl at gee) - * Use zeros instead of prev foot for is_mmapped - * Add mspace_track_large_chunks; thanks to Jean Brouwers - * Fix set_inuse in internal_realloc; thanks to Jean Brouwers - * Fix insufficient sys_alloc padding when using 16byte alignment - * Fix bad error check in mspace_footprint - * Adaptations for ptmalloc; thanks to Wolfram Gloger. - * Reentrant spin locks; thanks to Earl Chew and others - * Win32 improvements; thanks to Niall Douglas and Earl Chew - * Add NO_SEGMENT_TRAVERSAL and MAX_RELEASE_CHECK_RATE options - * Extension hook in malloc_state - * Various small adjustments to reduce warnings on some compilers - * Various configuration extensions/changes for more platforms. Thanks - to all who contributed these. - - V2.8.3 Thu Sep 22 11:16:32 2005 Doug Lea (dl at gee) - * Add max_footprint functions - * Ensure all appropriate literals are size_t - * Fix conditional compilation problem for some #define settings - * Avoid concatenating segments with the one provided - in create_mspace_with_base - * Rename some variables to avoid compiler shadowing warnings - * Use explicit lock initialization. - * Better handling of sbrk interference. - * Simplify and fix segment insertion, trimming and mspace_destroy - * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x - * Thanks especially to Dennis Flanagan for help on these. - - V2.8.2 Sun Jun 12 16:01:10 2005 Doug Lea (dl at gee) - * Fix memalign brace error. - - V2.8.1 Wed Jun 8 16:11:46 2005 Doug Lea (dl at gee) - * Fix improper #endif nesting in C++ - * Add explicit casts needed for C++ - - V2.8.0 Mon May 30 14:09:02 2005 Doug Lea (dl at gee) - * Use trees for large bins - * Support mspaces - * Use segments to unify sbrk-based and mmap-based system allocation, - removing need for emulation on most platforms without sbrk. - * Default safety checks - * Optional footer checks. Thanks to William Robertson for the idea. - * Internal code refactoring - * Incorporate suggestions and platform-specific changes. - Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas, - Aaron Bachmann, Emery Berger, and others. - * Speed up non-fastbin processing enough to remove fastbins. - * Remove useless cfree() to avoid conflicts with other apps. - * Remove internal memcpy, memset. Compilers handle builtins better. - * Remove some options that no one ever used and rename others. - - V2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - * Fix malloc_state bitmap array misdeclaration - - V2.7.1 Thu Jul 25 10:58:03 2002 Doug Lea (dl at gee) - * Allow tuning of FIRST_SORTED_BIN_SIZE - * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte. - * Better detection and support for non-contiguousness of MORECORE. - Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger - * Bypass most of malloc if no frees. Thanks To Emery Berger. - * Fix freeing of old top non-contiguous chunk im sysmalloc. - * Raised default trim and map thresholds to 256K. - * Fix mmap-related #defines. Thanks to Lubos Lunak. - * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield. - * Branch-free bin calculation - * Default trim and mmap thresholds now 256K. - - V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee) - * Introduce independent_comalloc and independent_calloc. - Thanks to Michael Pachos for motivation and help. - * Make optional .h file available - * Allow > 2GB requests on 32bit systems. - * new WIN32 sbrk, mmap, munmap, lock code from . - Thanks also to Andreas Mueller , - and Anonymous. - * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for - helping test this.) - * memalign: check alignment arg - * realloc: don't try to shift chunks backwards, since this - leads to more fragmentation in some programs and doesn't - seem to help in any others. - * Collect all cases in malloc requiring system memory into sysmalloc - * Use mmap as backup to sbrk - * Place all internal state in malloc_state - * Introduce fastbins (although similar to 2.5.1) - * Many minor tunings and cosmetic improvements - * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK - * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS - Thanks to Tony E. Bennett and others. - * Include errno.h to support default failure action. - - V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee) - * return null for negative arguments - * Added Several WIN32 cleanups from Martin C. Fong - * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h' - (e.g. WIN32 platforms) - * Cleanup header file inclusion for WIN32 platforms - * Cleanup code to avoid Microsoft Visual C++ compiler complaints - * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing - memory allocation routines - * Set 'malloc_getpagesize' for WIN32 platforms (needs more work) - * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to - usage of 'assert' in non-WIN32 code - * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to - avoid infinite loop - * Always call 'fREe()' rather than 'free()' - - V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee) - * Fixed ordering problem with boundary-stamping - - V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee) - * Added pvalloc, as recommended by H.J. Liu - * Added 64bit pointer support mainly from Wolfram Gloger - * Added anonymously donated WIN32 sbrk emulation - * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen - * malloc_extend_top: fix mask error that caused wastage after - foreign sbrks - * Add linux mremap support code from HJ Liu - - V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee) - * Integrated most documentation with the code. - * Add support for mmap, with help from - Wolfram Gloger (Gloger@lrz.uni-muenchen.de). - * Use last_remainder in more cases. - * Pack bins using idea from colin@nyx10.cs.du.edu - * Use ordered bins instead of best-fit threshhold - * Eliminate block-local decls to simplify tracing and debugging. - * Support another case of realloc via move into top - * Fix error occuring when initial sbrk_base not word-aligned. - * Rely on page size for units instead of SBRK_UNIT to - avoid surprises about sbrk alignment conventions. - * Add mallinfo, mallopt. Thanks to Raymond Nijssen - (raymond@es.ele.tue.nl) for the suggestion. - * Add `pad' argument to malloc_trim and top_pad mallopt parameter. - * More precautions for cases where other routines call sbrk, - courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de). - * Added macros etc., allowing use in linux libc from - H.J. Lu (hjl@gnu.ai.mit.edu) - * Inverted this history list - - V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee) - * Re-tuned and fixed to behave more nicely with V2.6.0 changes. - * Removed all preallocation code since under current scheme - the work required to undo bad preallocations exceeds - the work saved in good cases for most test programs. - * No longer use return list or unconsolidated bins since - no scheme using them consistently outperforms those that don't - given above changes. - * Use best fit for very large chunks to prevent some worst-cases. - * Added some support for debugging - - V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee) - * Removed footers when chunks are in use. Thanks to - Paul Wilson (wilson@cs.texas.edu) for the suggestion. - - V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee) - * Added malloc_trim, with help from Wolfram Gloger - (wmglo@Dent.MED.Uni-Muenchen.DE). - - V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g) - - V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g) - * realloc: try to expand in both directions - * malloc: swap order of clean-bin strategy; - * realloc: only conditionally expand backwards - * Try not to scavenge used bins - * Use bin counts as a guide to preallocation - * Occasionally bin return list chunks in first scan - * Add a few optimizations from colin@nyx10.cs.du.edu - - V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g) - * faster bin computation & slightly different binning - * merged all consolidations to one part of malloc proper - (eliminating old malloc_find_space & malloc_clean_bin) - * Scan 2 returns chunks (not just 1) - * Propagate failure in realloc if malloc returns 0 - * Add stuff to allow compilation on non-ANSI compilers - from kpv@research.att.com - - V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu) - * removed potential for odd address access in prev_chunk - * removed dependency on getpagesize.h - * misc cosmetics and a bit more internal documentation - * anticosmetics: mangled names in macros to evade debugger strangeness - * tested on sparc, hp-700, dec-mips, rs6000 - with gcc & native cc (hp, dec only) allowing - Detlefs & Zorn comparison study (in SIGPLAN Notices.) - - Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) - * Based loosely on libg++-1.2X malloc. (It retains some of the overall - structure of old version, but most details differ.) - -*/ -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -/* TODO: TEST ME */ -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/_dlmalloc/dlmalloc.h b/waterbox/libc/functions/_dlmalloc/dlmalloc.h deleted file mode 100644 index e11bf4b3ab..0000000000 --- a/waterbox/libc/functions/_dlmalloc/dlmalloc.h +++ /dev/null @@ -1,50 +0,0 @@ -#include "_PDCLIB_glue.h" -#include - - -#undef WIN32 -#undef _WIN32 -#define DLMALLOC_EXPORT _PDCLIB_API -#define MALLOC_ALIGNMENT _PDCLIB_MALLOC_ALIGN -#define MSPACES 0 -#define USE_LOCKS 0 -#define USE_SPIN_LOCKS 0 -#define USE_RECURSIVE_LOCKS 0 -#undef NEED_GLOBAL_LOCK_INIT -#define FOOTERS 0 -#undef USE_DL_PREFIX -#define MALLOC_INSPECT_ALL 0 -#define ABORT abort() -#define PROCEED_ON_ERROR 0 -#define DEBUG 0 -#define ABORT_ON_ASSERT_FAILURE 1 -#define MALLOC_FAILURE_ACTION errno = ENOMEM -#define HAVE_MORECORE 1 -#define MORECORE _PDCLIB_sbrk -#define MORECORE_CONTIGUOUS 1 -#define MORECORE_CANNOT_TRIM 1 -#define NO_SEGMENT_TRAVERSAL 0 -#define HAVE_MMAP 0 -#define HAVE_MREMAP 0 -#define USE_BUILTIN_FFS 0 -#define malloc_getpagesize _PDCLIB_MALLOC_PAGESIZE -#define USE_DEV_RANDOM 0 -#define NO_MALLINFO 1 -#define MALLINFO_FIELD_TYPE size_t -#define NO_MALLOC_STATS 1 -#define DEFAULT_GRANULARITY _PDCLIB_MALLOC_GRANULARITY -#define DEFAULT_TRIM_THRESHOLD _PDCLIB_MALLOC_TRIM_THRESHOLD -#define DEFAULT_MMAP_THREHOLD _PDCLIB_MALLOC_MMAP_THRESHOLD -#define MAX_RELEASE_CHECK_RATE _PDCLIB_MALLOC_RELEASE_CHECK_RATE - -/* C standard says this is so */ -#define REALLOC_ZERO_BYTES_FREES 1 -#define LACKS_UNISTD_H -#define LACKS_FCNTL_H -#define LACKS_SYS_PARAM_H -#define LACKS_SYS_MMAN_H -#define LACKS_STRINGS_H -#define LACKS_SYS_TYPES_H -#define LACKS_SCHED_H -#include -#include diff --git a/waterbox/libc/functions/ctype/isalnum.c b/waterbox/libc/functions/ctype/isalnum.c deleted file mode 100644 index b081e9bfb8..0000000000 --- a/waterbox/libc/functions/ctype/isalnum.c +++ /dev/null @@ -1,36 +0,0 @@ -/* isalnum( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int isalnum( int c ) -{ - return ( _PDCLIB_threadlocale()->_CType[c].flags & ( _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_DIGIT ) ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( isalnum( 'a' ) ); - TESTCASE( isalnum( 'z' ) ); - TESTCASE( isalnum( 'A' ) ); - TESTCASE( isalnum( 'Z' ) ); - TESTCASE( isalnum( '0' ) ); - TESTCASE( isalnum( '9' ) ); - TESTCASE( ! isalnum( ' ' ) ); - TESTCASE( ! isalnum( '\n' ) ); - TESTCASE( ! isalnum( '@' ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/ctype/isalpha.c b/waterbox/libc/functions/ctype/isalpha.c deleted file mode 100644 index ce05b76d87..0000000000 --- a/waterbox/libc/functions/ctype/isalpha.c +++ /dev/null @@ -1,32 +0,0 @@ -/* isalpha( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int isalpha( int c ) -{ - return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_ALPHA ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( isalpha( 'a' ) ); - TESTCASE( isalpha( 'z' ) ); - TESTCASE( ! isalpha( ' ' ) ); - TESTCASE( ! isalpha( '1' ) ); - TESTCASE( ! isalpha( '@' ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/ctype/isascii.c b/waterbox/libc/functions/ctype/isascii.c deleted file mode 100644 index 2cdfa30d95..0000000000 --- a/waterbox/libc/functions/ctype/isascii.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int isascii(int c) -{ - return (unsigned)c < 128; -} diff --git a/waterbox/libc/functions/ctype/isblank.c b/waterbox/libc/functions/ctype/isblank.c deleted file mode 100644 index 50d5663c18..0000000000 --- a/waterbox/libc/functions/ctype/isblank.c +++ /dev/null @@ -1,33 +0,0 @@ -/* isblank( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int isblank( int c ) -{ - return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_BLANK ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( isblank( ' ' ) ); - TESTCASE( isblank( '\t' ) ); - TESTCASE( ! isblank( '\v' ) ); - TESTCASE( ! isblank( '\r' ) ); - TESTCASE( ! isblank( 'x' ) ); - TESTCASE( ! isblank( '@' ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/ctype/iscntrl.c b/waterbox/libc/functions/ctype/iscntrl.c deleted file mode 100644 index 4542b6ff31..0000000000 --- a/waterbox/libc/functions/ctype/iscntrl.c +++ /dev/null @@ -1,31 +0,0 @@ -/* iscntrl( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int iscntrl( int c ) -{ - return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_CNTRL ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( iscntrl( '\a' ) ); - TESTCASE( iscntrl( '\b' ) ); - TESTCASE( iscntrl( '\n' ) ); - TESTCASE( ! iscntrl( ' ' ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/ctype/isdigit.c b/waterbox/libc/functions/ctype/isdigit.c deleted file mode 100644 index 00790677e8..0000000000 --- a/waterbox/libc/functions/ctype/isdigit.c +++ /dev/null @@ -1,32 +0,0 @@ -/* isdigit( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int isdigit( int c ) -{ - return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_DIGIT ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( isdigit( '0' ) ); - TESTCASE( isdigit( '9' ) ); - TESTCASE( ! isdigit( ' ' ) ); - TESTCASE( ! isdigit( 'a' ) ); - TESTCASE( ! isdigit( '@' ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/ctype/isgraph.c b/waterbox/libc/functions/ctype/isgraph.c deleted file mode 100644 index 1dac215545..0000000000 --- a/waterbox/libc/functions/ctype/isgraph.c +++ /dev/null @@ -1,35 +0,0 @@ -/* isgraph( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int isgraph( int c ) -{ - return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_GRAPH ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( isgraph( 'a' ) ); - TESTCASE( isgraph( 'z' ) ); - TESTCASE( isgraph( 'A' ) ); - TESTCASE( isgraph( 'Z' ) ); - TESTCASE( isgraph( '@' ) ); - TESTCASE( ! isgraph( '\t' ) ); - TESTCASE( ! isgraph( '\0' ) ); - TESTCASE( ! isgraph( ' ' ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/ctype/islower.c b/waterbox/libc/functions/ctype/islower.c deleted file mode 100644 index 435b3a993a..0000000000 --- a/waterbox/libc/functions/ctype/islower.c +++ /dev/null @@ -1,33 +0,0 @@ -/* islower( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int islower( int c ) -{ - return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_LOWER ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( islower( 'a' ) ); - TESTCASE( islower( 'z' ) ); - TESTCASE( ! islower( 'A' ) ); - TESTCASE( ! islower( 'Z' ) ); - TESTCASE( ! islower( ' ' ) ); - TESTCASE( ! islower( '@' ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/ctype/isprint.c b/waterbox/libc/functions/ctype/isprint.c deleted file mode 100644 index ca5733afbd..0000000000 --- a/waterbox/libc/functions/ctype/isprint.c +++ /dev/null @@ -1,35 +0,0 @@ -/* isprint( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int isprint( int c ) -{ - return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_GRAPH ) || ( c == ' ' ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( isprint( 'a' ) ); - TESTCASE( isprint( 'z' ) ); - TESTCASE( isprint( 'A' ) ); - TESTCASE( isprint( 'Z' ) ); - TESTCASE( isprint( '@' ) ); - TESTCASE( ! isprint( '\t' ) ); - TESTCASE( ! isprint( '\0' ) ); - TESTCASE( isprint( ' ' ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/ctype/ispunct.c b/waterbox/libc/functions/ctype/ispunct.c deleted file mode 100644 index 0fe668c373..0000000000 --- a/waterbox/libc/functions/ctype/ispunct.c +++ /dev/null @@ -1,36 +0,0 @@ -/* ispunct( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int ispunct( int c ) -{ - return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_PUNCT ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( ! ispunct( 'a' ) ); - TESTCASE( ! ispunct( 'z' ) ); - TESTCASE( ! ispunct( 'A' ) ); - TESTCASE( ! ispunct( 'Z' ) ); - TESTCASE( ispunct( '@' ) ); - TESTCASE( ispunct( '.' ) ); - TESTCASE( ! ispunct( '\t' ) ); - TESTCASE( ! ispunct( '\0' ) ); - TESTCASE( ! ispunct( ' ' ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/ctype/isspace.c b/waterbox/libc/functions/ctype/isspace.c deleted file mode 100644 index c40e89bdad..0000000000 --- a/waterbox/libc/functions/ctype/isspace.c +++ /dev/null @@ -1,34 +0,0 @@ -/* isspace( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int isspace( int c ) -{ - return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_SPACE ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( isspace( ' ' ) ); - TESTCASE( isspace( '\f' ) ); - TESTCASE( isspace( '\n' ) ); - TESTCASE( isspace( '\r' ) ); - TESTCASE( isspace( '\t' ) ); - TESTCASE( isspace( '\v' ) ); - TESTCASE( ! isspace( 'a' ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/ctype/isupper.c b/waterbox/libc/functions/ctype/isupper.c deleted file mode 100644 index 7201004d69..0000000000 --- a/waterbox/libc/functions/ctype/isupper.c +++ /dev/null @@ -1,33 +0,0 @@ -/* isupper( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int isupper( int c ) -{ - return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_UPPER ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( isupper( 'A' ) ); - TESTCASE( isupper( 'Z' ) ); - TESTCASE( ! isupper( 'a' ) ); - TESTCASE( ! isupper( 'z' ) ); - TESTCASE( ! isupper( ' ' ) ); - TESTCASE( ! isupper( '@' ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/ctype/isxdigit.c b/waterbox/libc/functions/ctype/isxdigit.c deleted file mode 100644 index 2b694d8eb7..0000000000 --- a/waterbox/libc/functions/ctype/isxdigit.c +++ /dev/null @@ -1,37 +0,0 @@ -/* isxdigit( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int isxdigit( int c ) -{ - return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_XDIGT ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( isxdigit( '0' ) ); - TESTCASE( isxdigit( '9' ) ); - TESTCASE( isxdigit( 'a' ) ); - TESTCASE( isxdigit( 'f' ) ); - TESTCASE( ! isxdigit( 'g' ) ); - TESTCASE( isxdigit( 'A' ) ); - TESTCASE( isxdigit( 'F' ) ); - TESTCASE( ! isxdigit( 'G' ) ); - TESTCASE( ! isxdigit( '@' ) ); - TESTCASE( ! isxdigit( ' ' ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/ctype/tolower.c b/waterbox/libc/functions/ctype/tolower.c deleted file mode 100644 index 779afb7290..0000000000 --- a/waterbox/libc/functions/ctype/tolower.c +++ /dev/null @@ -1,32 +0,0 @@ -/* tolower( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int tolower( int c ) -{ - return _PDCLIB_threadlocale()->_CType[c].lower; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( tolower( 'A' ) == 'a' ); - TESTCASE( tolower( 'Z' ) == 'z' ); - TESTCASE( tolower( 'a' ) == 'a' ); - TESTCASE( tolower( 'z' ) == 'z' ); - TESTCASE( tolower( '@' ) == '@' ); - TESTCASE( tolower( '[' ) == '[' ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/ctype/toupper.c b/waterbox/libc/functions/ctype/toupper.c deleted file mode 100644 index 16b981abf4..0000000000 --- a/waterbox/libc/functions/ctype/toupper.c +++ /dev/null @@ -1,32 +0,0 @@ -/* toupper( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int toupper( int c ) -{ - return _PDCLIB_threadlocale()->_CType[c].upper; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( toupper( 'a' ) == 'A' ); - TESTCASE( toupper( 'z' ) == 'Z' ); - TESTCASE( toupper( 'A' ) == 'A' ); - TESTCASE( toupper( 'Z' ) == 'Z' ); - TESTCASE( toupper( '@' ) == '@' ); - TESTCASE( toupper( '[' ) == '[' ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/errno/errno.c b/waterbox/libc/functions/errno/errno.c deleted file mode 100644 index 75a564fbfd..0000000000 --- a/waterbox/libc/functions/errno/errno.c +++ /dev/null @@ -1,37 +0,0 @@ -/* _PDCLIB_errno - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include - -/* Temporary */ - -static int _PDCLIB_errno = 0; - -int * _PDCLIB_errno_func() -{ - return &_PDCLIB_errno; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - errno = 0; - TESTCASE( errno == 0 ); - errno = EDOM; - TESTCASE( errno == EDOM ); - errno = ERANGE; - TESTCASE( errno == ERANGE ); - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/inttypes/imaxabs.c b/waterbox/libc/functions/inttypes/imaxabs.c deleted file mode 100644 index 79f3dd2ab8..0000000000 --- a/waterbox/libc/functions/inttypes/imaxabs.c +++ /dev/null @@ -1,30 +0,0 @@ -/* imaxabs( intmax_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -intmax_t imaxabs( intmax_t j ) -{ - return ( j >= 0 ) ? j : -j; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -int main( void ) -{ - TESTCASE( imaxabs( (intmax_t)0 ) == 0 ); - TESTCASE( imaxabs( INTMAX_MAX ) == INTMAX_MAX ); - TESTCASE( imaxabs( INTMAX_MIN + 1 ) == -( INTMAX_MIN + 1 ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/inttypes/imaxdiv.c b/waterbox/libc/functions/inttypes/imaxdiv.c deleted file mode 100644 index 553f22e7fa..0000000000 --- a/waterbox/libc/functions/inttypes/imaxdiv.c +++ /dev/null @@ -1,38 +0,0 @@ -/* lldiv( long long int, long long int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -imaxdiv_t imaxdiv( intmax_t numer, intmax_t denom ) -{ - imaxdiv_t rc; - rc.quot = numer / denom; - rc.rem = numer % denom; - return rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - imaxdiv_t result; - result = imaxdiv( (intmax_t)5, (intmax_t)2 ); - TESTCASE( result.quot == 2 && result.rem == 1 ); - result = imaxdiv( (intmax_t)-5, (intmax_t)2 ); - TESTCASE( result.quot == -2 && result.rem == -1 ); - result = imaxdiv( (intmax_t)5, (intmax_t)-2 ); - TESTCASE( result.quot == -2 && result.rem == 1 ); - TESTCASE( sizeof( result.quot ) == sizeof( intmax_t ) ); - TESTCASE( sizeof( result.rem ) == sizeof( intmax_t ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/inttypes/strtoimax.c b/waterbox/libc/functions/inttypes/strtoimax.c deleted file mode 100644 index f58a0be9f0..0000000000 --- a/waterbox/libc/functions/inttypes/strtoimax.c +++ /dev/null @@ -1,146 +0,0 @@ -/* strtoimax( const char *, char * *, int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST - -#include - -intmax_t strtoimax( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base ) -{ - intmax_t rc; - char sign = '+'; - const char * p = _PDCLIB_strtox_prelim( nptr, &sign, &base ); - if ( base < 2 || base > 36 ) return 0; - if ( sign == '+' ) - { - rc = (intmax_t)_PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)INTMAX_MAX, (uintmax_t)( INTMAX_MAX / base ), (int)( INTMAX_MAX % base ), &sign ); - } - else - { - rc = (intmax_t)_PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)INTMAX_MIN, (uintmax_t)( INTMAX_MIN / -base ), (int)( -( INTMAX_MIN % base ) ), &sign ); - } - if ( endptr != NULL ) *endptr = ( p != NULL ) ? (char *) p : (char *) nptr; - return ( sign == '+' ) ? rc : -rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -#include - -int main( void ) -{ - char * endptr; - /* this, to base 36, overflows even a 256 bit integer */ - char overflow[] = "-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_"; - /* tricky border case */ - char tricky[] = "+0xz"; - errno = 0; - /* basic functionality */ - TESTCASE( strtoimax( "123", NULL, 10 ) == 123 ); - /* proper detecting of default base 10 */ - TESTCASE( strtoimax( "456", NULL, 0 ) == 456 ); - /* proper functioning to smaller base */ - TESTCASE( strtoimax( "14", NULL, 8 ) == 12 ); - /* proper autodetecting of octal */ - TESTCASE( strtoimax( "016", NULL, 0 ) == 14 ); - /* proper autodetecting of hexadecimal, lowercase 'x' */ - TESTCASE( strtoimax( "0xFF", NULL, 0 ) == 255 ); - /* proper autodetecting of hexadecimal, uppercase 'X' */ - TESTCASE( strtoimax( "0Xa1", NULL, 0 ) == 161 ); - /* proper handling of border case: 0x followed by non-hexdigit */ - TESTCASE( strtoimax( tricky, &endptr, 0 ) == 0 ); - TESTCASE( endptr == tricky + 2 ); - /* proper handling of border case: 0 followed by non-octdigit */ - TESTCASE( strtoimax( tricky, &endptr, 8 ) == 0 ); - TESTCASE( endptr == tricky + 2 ); - /* errno should still be 0 */ - TESTCASE( errno == 0 ); - /* overflowing subject sequence must still return proper endptr */ - TESTCASE( strtoimax( overflow, &endptr, 36 ) == INTMAX_MIN ); - TESTCASE( errno == ERANGE ); - TESTCASE( ( endptr - overflow ) == 53 ); - /* same for positive */ - errno = 0; - TESTCASE( strtoimax( overflow + 1, &endptr, 36 ) == INTMAX_MAX ); - TESTCASE( errno == ERANGE ); - TESTCASE( ( endptr - overflow ) == 53 ); - /* testing skipping of leading whitespace */ - TESTCASE( strtoimax( " \n\v\t\f789", NULL, 0 ) == 789 ); - /* testing conversion failure */ - TESTCASE( strtoimax( overflow, &endptr, 10 ) == 0 ); - TESTCASE( endptr == overflow ); - endptr = NULL; - TESTCASE( strtoimax( overflow, &endptr, 0 ) == 0 ); - TESTCASE( endptr == overflow ); - /* These tests assume two-complement, but conversion should work for */ - /* one-complement and signed magnitude just as well. Anyone having a */ - /* platform to test this on? */ - errno = 0; -#if INTMAX_MAX >> 62 == 1 - /* testing "odd" overflow, i.e. base is not a power of two */ - TESTCASE( strtoimax( "9223372036854775807", NULL, 0 ) == INTMAX_MAX ); - TESTCASE( errno == 0 ); - TESTCASE( strtoimax( "9223372036854775808", NULL, 0 ) == INTMAX_MAX ); - TESTCASE( errno == ERANGE ); - errno = 0; - TESTCASE( strtoimax( "-9223372036854775807", NULL, 0 ) == (INTMAX_MIN + 1) ); - TESTCASE( errno == 0 ); - TESTCASE( strtoimax( "-9223372036854775808", NULL, 0 ) == INTMAX_MIN ); - TESTCASE( errno == 0 ); - TESTCASE( strtoimax( "-9223372036854775809", NULL, 0 ) == INTMAX_MIN ); - TESTCASE( errno == ERANGE ); - /* testing "even" overflow, i.e. base is power of two */ - errno = 0; - TESTCASE( strtoimax( "0x7fffffffffffffff", NULL, 0 ) == INTMAX_MAX ); - TESTCASE( errno == 0 ); - TESTCASE( strtoimax( "0x8000000000000000", NULL, 0 ) == INTMAX_MAX ); - TESTCASE( errno == ERANGE ); - errno = 0; - TESTCASE( strtoimax( "-0x7fffffffffffffff", NULL, 0 ) == (INTMAX_MIN + 1) ); - TESTCASE( errno == 0 ); - TESTCASE( strtoimax( "-0x8000000000000000", NULL, 0 ) == INTMAX_MIN ); - TESTCASE( errno == 0 ); - TESTCASE( strtoimax( "-0x8000000000000001", NULL, 0 ) == INTMAX_MIN ); - TESTCASE( errno == ERANGE ); -#elif LLONG_MAX >> 126 == 1 - /* testing "odd" overflow, i.e. base is not a power of two */ - TESTCASE( strtoimax( "170141183460469231731687303715884105728", NULL, 0 ) == INTMAX_MAX ); - TESTCASE( errno == 0 ); - TESTCASE( strtoimax( "170141183460469231731687303715884105729", NULL, 0 ) == INTMAX_MAX ); - TESTCASE( errno == ERANGE ); - errno = 0; - TESTCASE( strtoimax( "-170141183460469231731687303715884105728", NULL, 0 ) == (INTMAX_MIN + 1) ); - TESTCASE( errno == 0 ); - TESTCASE( strtoimax( "-170141183460469231731687303715884105729", NULL, 0 ) == INTMAX_MIN ); - TESTCASE( errno == 0 ); - TESTCASE( strtoimax( "-170141183460469231731687303715884105730", NULL, 0 ) == INTMAX_MIN ); - TESTCASE( errno == ERANGE ); - /* testing "even" overflow, i.e. base is power of two */ - errno = 0; - TESTCASE( strtoimax( "0x7fffffffffffffffffffffffffffffff", NULL, 0 ) == INTMAX_MAX ); - TESTCASE( errno == 0 ); - TESTCASE( strtoimax( "0x80000000000000000000000000000000", NULL, 0 ) == INTMAX_MAX ); - TESTCASE( errno == ERANGE ); - errno = 0; - TESTCASE( strtoimax( "-0x7fffffffffffffffffffffffffffffff", NULL, 0 ) == (INTMAX_MIN + 1) ); - TESTCASE( errno == 0 ); - TESTCASE( strtoimax( "-0x80000000000000000000000000000000", NULL, 0 ) == INTMAX_MIN ); - TESTCASE( errno == 0 ); - TESTCASE( strtoimax( "-0x80000000000000000000000000000001", NULL, 0 ) == INTMAX_MIN ); - TESTCASE( errno == ERANGE ); -#else -#error Unsupported width of 'intmax_t' (neither 64 nor 128 bit). -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/inttypes/strtoumax.c b/waterbox/libc/functions/inttypes/strtoumax.c deleted file mode 100644 index f998338bab..0000000000 --- a/waterbox/libc/functions/inttypes/strtoumax.c +++ /dev/null @@ -1,109 +0,0 @@ -/* strtoumax( const char *, char * *, int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST - -#include - -uintmax_t strtoumax( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base ) -{ - uintmax_t rc; - char sign = '+'; - const char * p = _PDCLIB_strtox_prelim( nptr, &sign, &base ); - if ( base < 2 || base > 36 ) return 0; - rc = _PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)UINTMAX_MAX, (uintmax_t)( UINTMAX_MAX / base ), (int)( UINTMAX_MAX % base ), &sign ); - if ( endptr != NULL ) *endptr = ( p != NULL ) ? (char *) p : (char *) nptr; - return ( sign == '+' ) ? rc : -rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -int main( void ) -{ - char * endptr; - /* this, to base 36, overflows even a 256 bit integer */ - char overflow[] = "-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_"; - /* tricky border case */ - char tricky[] = "+0xz"; - errno = 0; - /* basic functionality */ - TESTCASE( strtoumax( "123", NULL, 10 ) == 123 ); - /* proper detecting of default base 10 */ - TESTCASE( strtoumax( "456", NULL, 0 ) == 456 ); - /* proper functioning to smaller base */ - TESTCASE( strtoumax( "14", NULL, 8 ) == 12 ); - /* proper autodetecting of octal */ - TESTCASE( strtoumax( "016", NULL, 0 ) == 14 ); - /* proper autodetecting of hexadecimal, lowercase 'x' */ - TESTCASE( strtoumax( "0xFF", NULL, 0 ) == 255 ); - /* proper autodetecting of hexadecimal, uppercase 'X' */ - TESTCASE( strtoumax( "0Xa1", NULL, 0 ) == 161 ); - /* proper handling of border case: 0x followed by non-hexdigit */ - TESTCASE( strtoumax( tricky, &endptr, 0 ) == 0 ); - TESTCASE( endptr == tricky + 2 ); - /* proper handling of border case: 0 followed by non-octdigit */ - TESTCASE( strtoumax( tricky, &endptr, 8 ) == 0 ); - TESTCASE( endptr == tricky + 2 ); - /* errno should still be 0 */ - TESTCASE( errno == 0 ); - /* overflowing subject sequence must still return proper endptr */ - TESTCASE( strtoumax( overflow, &endptr, 36 ) == UINTMAX_MAX ); - TESTCASE( errno == ERANGE ); - TESTCASE( ( endptr - overflow ) == 53 ); - /* same for positive */ - errno = 0; - TESTCASE( strtoumax( overflow + 1, &endptr, 36 ) == UINTMAX_MAX ); - TESTCASE( errno == ERANGE ); - TESTCASE( ( endptr - overflow ) == 53 ); - /* testing skipping of leading whitespace */ - TESTCASE( strtoumax( " \n\v\t\f789", NULL, 0 ) == 789 ); - /* testing conversion failure */ - TESTCASE( strtoumax( overflow, &endptr, 10 ) == 0 ); - TESTCASE( endptr == overflow ); - endptr = NULL; - TESTCASE( strtoumax( overflow, &endptr, 0 ) == 0 ); - TESTCASE( endptr == overflow ); - errno = 0; -/* uintmax_t -> long long -> 64 bit */ -#if UINTMAX_MAX >> 63 == 1 - /* testing "odd" overflow, i.e. base is not power of two */ - TESTCASE( strtoumax( "18446744073709551615", NULL, 0 ) == UINTMAX_MAX ); - TESTCASE( errno == 0 ); - TESTCASE( strtoumax( "18446744073709551616", NULL, 0 ) == UINTMAX_MAX ); - TESTCASE( errno == ERANGE ); - /* testing "even" overflow, i.e. base is power of two */ - errno = 0; - TESTCASE( strtoumax( "0xFFFFFFFFFFFFFFFF", NULL, 0 ) == UINTMAX_MAX ); - TESTCASE( errno == 0 ); - TESTCASE( strtoumax( "0x10000000000000000", NULL, 0 ) == UINTMAX_MAX ); - TESTCASE( errno == ERANGE ); -/* uintmax_t -> long long -> 128 bit */ -#elif UINTMAX_MAX >> 127 == 1 - /* testing "odd" overflow, i.e. base is not power of two */ - TESTCASE( strtoumax( "340282366920938463463374607431768211455", NULL, 0 ) == UINTMAX_MAX ); - TESTCASE( errno == 0 ); - TESTCASE( strtoumax( "340282366920938463463374607431768211456", NULL, 0 ) == UINTMAX_MAX ); - TESTCASE( errno == ERANGE ); - /* testing "even" everflow, i.e. base is power of two */ - errno = 0; - TESTCASE( strtoumax( "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", NULL, 0 ) == UINTMAX_MAX ); - TESTCASE( errno == 0 ); - TESTCASE( strtoumax( "0x100000000000000000000000000000000", NULL, 0 ) == UINTMAX_MAX ); - TESTCASE( errno == ERANGE ); -#else -#error Unsupported width of 'uintmax_t' (neither 64 nor 128 bit). -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/locale/UnicodeData.py b/waterbox/libc/functions/locale/UnicodeData.py deleted file mode 100644 index e0f87e58c1..0000000000 --- a/waterbox/libc/functions/locale/UnicodeData.py +++ /dev/null @@ -1,194 +0,0 @@ -#!/usr/bin/python -# -*- coding: ascii -*- -# Unicode Data Converter -# -# This file is part of the Public Domain C Library (PDCLib). -# Permission is granted to use, modify, and / or redistribute at will. -""" -Converts the character information provdied by Unicode in the UnicodeData.txt -file from the Unicode character database into a table for use by PDCLib. - -Usage: Download the UnicodeData.txt file to the same directory as this script -and then run it. Both Python 2 and 3 are supported. - -Download the data from - ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt - -We do some simple "run" compression, because characters in the Unicode Data file -tend to come in groups with the same properties. -""" -import os - -# MUST BE KEPT SYNCHRONIZED WITH _PDCLIB_locale.h -BIT_ALPHA = 1 -BIT_BLANK = 2 -BIT_CNTRL = 4 -BIT_GRAPH = 8 -BIT_PUNCT = 16 -BIT_SPACE = 32 -BIT_LOWER = 64 -BIT_UPPER = 128 -BIT_DIGIT = 256 -BIT_XDIGT = 512 - -# Category to bitfield mapping -categories = { - 'Lu': BIT_ALPHA | BIT_GRAPH | BIT_UPPER, # Uppercase - 'Ll': BIT_ALPHA | BIT_GRAPH | BIT_LOWER, # Lowercase - 'Lt': BIT_ALPHA | BIT_GRAPH | BIT_UPPER, # Title case. Upper? - 'Lm': BIT_ALPHA | BIT_GRAPH, # Modifier. Case? - 'Lo': BIT_ALPHA | BIT_GRAPH, # "Other" letter (e.g. Ideograph) - 'Nd': BIT_DIGIT | BIT_GRAPH, # Decimal digit - 'Nl': BIT_GRAPH, # Letter-like numeric character - 'No': BIT_GRAPH, # Other numeric - 'Pc': BIT_PUNCT | BIT_GRAPH, # Connecting punctuation - 'Pd': BIT_PUNCT | BIT_GRAPH, # Dash punctuation - 'Ps': BIT_PUNCT | BIT_GRAPH, # Opening punctuation - 'Pe': BIT_PUNCT | BIT_GRAPH, # Closing punctuation - 'Pi': BIT_PUNCT | BIT_GRAPH, # Opening quote - 'Pf': BIT_PUNCT | BIT_GRAPH, # Closing quote - 'Po': BIT_PUNCT | BIT_GRAPH, # Other punctuation - 'Sm': BIT_GRAPH, # Mathematical symbol - 'Sc': BIT_GRAPH, # Currency symbol - 'Sk': BIT_GRAPH, # Non-letterlike modifier symbol - 'So': BIT_GRAPH, # Other symbol - 'Zs': BIT_SPACE, # Non-zero-width space character - 'Zl': BIT_SPACE, # Line separator - 'Zp': BIT_SPACE, # Paragraph separator - 'Cc': BIT_CNTRL, # C0/C1 control codes -} - -# Characters with special properties -special = { - # Blank characters - 0x0020: BIT_SPACE | BIT_BLANK, # space - 0x0009: BIT_SPACE | BIT_BLANK, # tab - - # Digits - 0x0030: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH, - 0x0031: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH, - 0x0032: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH, - 0x0033: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH, - 0x0034: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH, - 0x0035: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH, - 0x0036: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH, - 0x0037: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH, - 0x0038: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH, - 0x0039: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH, - - # A-F (hex uppercase) - 0x0041: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER, - 0x0042: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER, - 0x0043: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER, - 0x0044: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER, - 0x0045: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER, - 0x0046: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER, - - - # a-f (hex lowercase) - 0x0061: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER, - 0x0062: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER, - 0x0063: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER, - 0x0064: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER, - 0x0065: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER, - 0x0066: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER, -} - -class Group: - def __init__(self, start, flags, upper_delta, lower_delta): - self.start = start - self.flags = flags - self.upper_delta = upper_delta - self.lower_delta = lower_delta - self.chars = [] - - def add_char(self, num, label): - self.chars.append((num, label)) - - def write_to_file(self, f): - for char in self.chars: - f.write("// %x %s\n" % char) - f.write(" { 0x%X, \t0x%X, \t0x%X, \t%d, \t%d },\n" % - (self.start, len(self.chars), self.flags, self.lower_delta, self.upper_delta)) - - def next(self): - return self.start + len(self.chars) - -groups = [] - -def add_char(num, upper, lower, bits, label): - upper_delta = upper - num - lower_delta = lower - num - - if len(groups) != 0: - cur = groups[-1] - if num == cur.next() and cur.flags == bits and \ - cur.upper_delta == upper_delta and \ - cur.lower_delta == lower_delta: - cur.add_char(num, label) - return - - g = Group(num, bits, upper_delta, lower_delta) - g.add_char(num, label) - groups.append(g) - -in_file = open('UnicodeData.txt', 'r') -out_file = open('_PDCLIB_unicodedata.c', 'w') -try: - for line in in_file: - (num_hex, name, category, combining_class, bidi_class, decomposition, - numeric_type, numeric_digit, numeric_value, mirrored, u1name, iso_com, - upper_case_hex, lower_case_hex, title_case_hex) = line.split(";") - - num = int(num_hex, 16) - upper_case = int(upper_case_hex, 16) if len(upper_case_hex) else num - lower_case = int(lower_case_hex, 16) if len(lower_case_hex) else num - bits = special.get(num, categories.get(category, 0)) - - if upper_case == 0 and lower_case == 0 and bits == 0: - continue - - add_char(num, upper_case, lower_case, bits, name) - - out_file.write(""" -/* Unicode Character Information ** AUTOMATICALLY GENERATED FILE ** - * - * This file is part of the PDCLib public domain C Library, but is automatically - * generated from the Unicode character data information file found at - * ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt - * - * As a result, the licensing that applies to that file also applies to this - * file. The licensing which applies to the Unicode character data can be found - * in Exhibit 1 of the Unicode Terms of Use, found at - * http://www.unicode.org/copyright.html#Exhibit1 - */ - #ifndef REGTEST - #include <_PDCLIB_locale.h> - -const _PDCLIB_wcinfo_t _PDCLIB_wcinfo[] = { -// { value, \tlength, \tflags,\tlower,\tupper\t}, // name - """) - for g in groups: - g.write_to_file(out_file) - out_file.write('};\n\n') - out_file.write(""" -const size_t _PDCLIB_wcinfo_size = sizeof(_PDCLIB_wcinfo) / sizeof(_PDCLIB_wcinfo[0]); -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -int main( void ) -{ - return TEST_RESULTS; -} -#endif - -""") -except: - in_file.close() - out_file.close() - os.remove('_PDCLIB_unicodedata.c') - raise -else: - in_file.close() - out_file.close() diff --git a/waterbox/libc/functions/locale/_PDCLIB_mb_cur_max.c b/waterbox/libc/functions/locale/_PDCLIB_mb_cur_max.c deleted file mode 100644 index e241b7482c..0000000000 --- a/waterbox/libc/functions/locale/_PDCLIB_mb_cur_max.c +++ /dev/null @@ -1,27 +0,0 @@ -/* _PDCLIB_mb_cur_max( void ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" -#include "_PDCLIB_encoding.h" - -size_t _PDCLIB_mb_cur_max( void ) -{ - return _PDCLIB_threadlocale()->_Codec->__mb_max; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( NO_TESTDRIVER ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/locale/_PDCLIB_unicodedata.c b/waterbox/libc/functions/locale/_PDCLIB_unicodedata.c deleted file mode 100644 index 927fdb8f6b..0000000000 --- a/waterbox/libc/functions/locale/_PDCLIB_unicodedata.c +++ /dev/null @@ -1,29890 +0,0 @@ - -/* Unicode Character Information ** AUTOMATICALLY GENERATED FILE ** - * - * This file is part of the PDCLib public domain C Library, but is automatically - * generated from the Unicode character data information file found at - * ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt - * - * As a result, the licensing that applies to that file also applies to this - * file. The licensing which applies to the Unicode character data can be found - * in Exhibit 1 of the Unicode Terms of Use, found at - * http://www.unicode.org/copyright.html#Exhibit1 - */ - #ifndef REGTEST - #include <_PDCLIB_locale.h> - -const _PDCLIB_wcinfo_t _PDCLIB_wcinfo[] = { -// { value, length, flags, lower, upper }, // name - // 0 -// 1 -// 2 -// 3 -// 4 -// 5 -// 6 -// 7 -// 8 - { 0x0, 0x9, 0x4, 0, 0 }, -// 9 - { 0x9, 0x1, 0x22, 0, 0 }, -// a -// b -// c -// d -// e -// f -// 10 -// 11 -// 12 -// 13 -// 14 -// 15 -// 16 -// 17 -// 18 -// 19 -// 1a -// 1b -// 1c -// 1d -// 1e -// 1f - { 0xA, 0x16, 0x4, 0, 0 }, -// 20 SPACE - { 0x20, 0x1, 0x22, 0, 0 }, -// 21 EXCLAMATION MARK -// 22 QUOTATION MARK -// 23 NUMBER SIGN - { 0x21, 0x3, 0x18, 0, 0 }, -// 24 DOLLAR SIGN - { 0x24, 0x1, 0x8, 0, 0 }, -// 25 PERCENT SIGN -// 26 AMPERSAND -// 27 APOSTROPHE -// 28 LEFT PARENTHESIS -// 29 RIGHT PARENTHESIS -// 2a ASTERISK - { 0x25, 0x6, 0x18, 0, 0 }, -// 2b PLUS SIGN - { 0x2B, 0x1, 0x8, 0, 0 }, -// 2c COMMA -// 2d HYPHEN-MINUS -// 2e FULL STOP -// 2f SOLIDUS - { 0x2C, 0x4, 0x18, 0, 0 }, -// 30 DIGIT ZERO -// 31 DIGIT ONE -// 32 DIGIT TWO -// 33 DIGIT THREE -// 34 DIGIT FOUR -// 35 DIGIT FIVE -// 36 DIGIT SIX -// 37 DIGIT SEVEN -// 38 DIGIT EIGHT -// 39 DIGIT NINE - { 0x30, 0xA, 0x308, 0, 0 }, -// 3a COLON -// 3b SEMICOLON - { 0x3A, 0x2, 0x18, 0, 0 }, -// 3c LESS-THAN SIGN -// 3d EQUALS SIGN -// 3e GREATER-THAN SIGN - { 0x3C, 0x3, 0x8, 0, 0 }, -// 3f QUESTION MARK -// 40 COMMERCIAL AT - { 0x3F, 0x2, 0x18, 0, 0 }, -// 41 LATIN CAPITAL LETTER A -// 42 LATIN CAPITAL LETTER B -// 43 LATIN CAPITAL LETTER C -// 44 LATIN CAPITAL LETTER D -// 45 LATIN CAPITAL LETTER E -// 46 LATIN CAPITAL LETTER F - { 0x41, 0x6, 0x289, 32, 0 }, -// 47 LATIN CAPITAL LETTER G -// 48 LATIN CAPITAL LETTER H -// 49 LATIN CAPITAL LETTER I -// 4a LATIN CAPITAL LETTER J -// 4b LATIN CAPITAL LETTER K -// 4c LATIN CAPITAL LETTER L -// 4d LATIN CAPITAL LETTER M -// 4e LATIN CAPITAL LETTER N -// 4f LATIN CAPITAL LETTER O -// 50 LATIN CAPITAL LETTER P -// 51 LATIN CAPITAL LETTER Q -// 52 LATIN CAPITAL LETTER R -// 53 LATIN CAPITAL LETTER S -// 54 LATIN CAPITAL LETTER T -// 55 LATIN CAPITAL LETTER U -// 56 LATIN CAPITAL LETTER V -// 57 LATIN CAPITAL LETTER W -// 58 LATIN CAPITAL LETTER X -// 59 LATIN CAPITAL LETTER Y -// 5a LATIN CAPITAL LETTER Z - { 0x47, 0x14, 0x89, 32, 0 }, -// 5b LEFT SQUARE BRACKET -// 5c REVERSE SOLIDUS -// 5d RIGHT SQUARE BRACKET - { 0x5B, 0x3, 0x18, 0, 0 }, -// 5e CIRCUMFLEX ACCENT - { 0x5E, 0x1, 0x8, 0, 0 }, -// 5f LOW LINE - { 0x5F, 0x1, 0x18, 0, 0 }, -// 60 GRAVE ACCENT - { 0x60, 0x1, 0x8, 0, 0 }, -// 61 LATIN SMALL LETTER A -// 62 LATIN SMALL LETTER B -// 63 LATIN SMALL LETTER C -// 64 LATIN SMALL LETTER D -// 65 LATIN SMALL LETTER E -// 66 LATIN SMALL LETTER F - { 0x61, 0x6, 0x249, 0, -32 }, -// 67 LATIN SMALL LETTER G -// 68 LATIN SMALL LETTER H -// 69 LATIN SMALL LETTER I -// 6a LATIN SMALL LETTER J -// 6b LATIN SMALL LETTER K -// 6c LATIN SMALL LETTER L -// 6d LATIN SMALL LETTER M -// 6e LATIN SMALL LETTER N -// 6f LATIN SMALL LETTER O -// 70 LATIN SMALL LETTER P -// 71 LATIN SMALL LETTER Q -// 72 LATIN SMALL LETTER R -// 73 LATIN SMALL LETTER S -// 74 LATIN SMALL LETTER T -// 75 LATIN SMALL LETTER U -// 76 LATIN SMALL LETTER V -// 77 LATIN SMALL LETTER W -// 78 LATIN SMALL LETTER X -// 79 LATIN SMALL LETTER Y -// 7a LATIN SMALL LETTER Z - { 0x67, 0x14, 0x49, 0, -32 }, -// 7b LEFT CURLY BRACKET - { 0x7B, 0x1, 0x18, 0, 0 }, -// 7c VERTICAL LINE - { 0x7C, 0x1, 0x8, 0, 0 }, -// 7d RIGHT CURLY BRACKET - { 0x7D, 0x1, 0x18, 0, 0 }, -// 7e TILDE - { 0x7E, 0x1, 0x8, 0, 0 }, -// 7f -// 80 -// 81 -// 82 -// 83 -// 84 -// 85 -// 86 -// 87 -// 88 -// 89 -// 8a -// 8b -// 8c -// 8d -// 8e -// 8f -// 90 -// 91 -// 92 -// 93 -// 94 -// 95 -// 96 -// 97 -// 98 -// 99 -// 9a -// 9b -// 9c -// 9d -// 9e -// 9f - { 0x7F, 0x21, 0x4, 0, 0 }, -// a0 NO-BREAK SPACE - { 0xA0, 0x1, 0x20, 0, 0 }, -// a1 INVERTED EXCLAMATION MARK - { 0xA1, 0x1, 0x18, 0, 0 }, -// a2 CENT SIGN -// a3 POUND SIGN -// a4 CURRENCY SIGN -// a5 YEN SIGN -// a6 BROKEN BAR - { 0xA2, 0x5, 0x8, 0, 0 }, -// a7 SECTION SIGN - { 0xA7, 0x1, 0x18, 0, 0 }, -// a8 DIAERESIS -// a9 COPYRIGHT SIGN - { 0xA8, 0x2, 0x8, 0, 0 }, -// aa FEMININE ORDINAL INDICATOR - { 0xAA, 0x1, 0x9, 0, 0 }, -// ab LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - { 0xAB, 0x1, 0x18, 0, 0 }, -// ac NOT SIGN - { 0xAC, 0x1, 0x8, 0, 0 }, -// ad SOFT HYPHEN - { 0xAD, 0x1, 0x0, 0, 0 }, -// ae REGISTERED SIGN -// af MACRON -// b0 DEGREE SIGN -// b1 PLUS-MINUS SIGN -// b2 SUPERSCRIPT TWO -// b3 SUPERSCRIPT THREE -// b4 ACUTE ACCENT - { 0xAE, 0x7, 0x8, 0, 0 }, -// b5 MICRO SIGN - { 0xB5, 0x1, 0x49, 0, 743 }, -// b6 PILCROW SIGN -// b7 MIDDLE DOT - { 0xB6, 0x2, 0x18, 0, 0 }, -// b8 CEDILLA -// b9 SUPERSCRIPT ONE - { 0xB8, 0x2, 0x8, 0, 0 }, -// ba MASCULINE ORDINAL INDICATOR - { 0xBA, 0x1, 0x9, 0, 0 }, -// bb RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - { 0xBB, 0x1, 0x18, 0, 0 }, -// bc VULGAR FRACTION ONE QUARTER -// bd VULGAR FRACTION ONE HALF -// be VULGAR FRACTION THREE QUARTERS - { 0xBC, 0x3, 0x8, 0, 0 }, -// bf INVERTED QUESTION MARK - { 0xBF, 0x1, 0x18, 0, 0 }, -// c0 LATIN CAPITAL LETTER A WITH GRAVE -// c1 LATIN CAPITAL LETTER A WITH ACUTE -// c2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX -// c3 LATIN CAPITAL LETTER A WITH TILDE -// c4 LATIN CAPITAL LETTER A WITH DIAERESIS -// c5 LATIN CAPITAL LETTER A WITH RING ABOVE -// c6 LATIN CAPITAL LETTER AE -// c7 LATIN CAPITAL LETTER C WITH CEDILLA -// c8 LATIN CAPITAL LETTER E WITH GRAVE -// c9 LATIN CAPITAL LETTER E WITH ACUTE -// ca LATIN CAPITAL LETTER E WITH CIRCUMFLEX -// cb LATIN CAPITAL LETTER E WITH DIAERESIS -// cc LATIN CAPITAL LETTER I WITH GRAVE -// cd LATIN CAPITAL LETTER I WITH ACUTE -// ce LATIN CAPITAL LETTER I WITH CIRCUMFLEX -// cf LATIN CAPITAL LETTER I WITH DIAERESIS -// d0 LATIN CAPITAL LETTER ETH -// d1 LATIN CAPITAL LETTER N WITH TILDE -// d2 LATIN CAPITAL LETTER O WITH GRAVE -// d3 LATIN CAPITAL LETTER O WITH ACUTE -// d4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX -// d5 LATIN CAPITAL LETTER O WITH TILDE -// d6 LATIN CAPITAL LETTER O WITH DIAERESIS - { 0xC0, 0x17, 0x89, 32, 0 }, -// d7 MULTIPLICATION SIGN - { 0xD7, 0x1, 0x8, 0, 0 }, -// d8 LATIN CAPITAL LETTER O WITH STROKE -// d9 LATIN CAPITAL LETTER U WITH GRAVE -// da LATIN CAPITAL LETTER U WITH ACUTE -// db LATIN CAPITAL LETTER U WITH CIRCUMFLEX -// dc LATIN CAPITAL LETTER U WITH DIAERESIS -// dd LATIN CAPITAL LETTER Y WITH ACUTE -// de LATIN CAPITAL LETTER THORN - { 0xD8, 0x7, 0x89, 32, 0 }, -// df LATIN SMALL LETTER SHARP S - { 0xDF, 0x1, 0x49, 0, 0 }, -// e0 LATIN SMALL LETTER A WITH GRAVE -// e1 LATIN SMALL LETTER A WITH ACUTE -// e2 LATIN SMALL LETTER A WITH CIRCUMFLEX -// e3 LATIN SMALL LETTER A WITH TILDE -// e4 LATIN SMALL LETTER A WITH DIAERESIS -// e5 LATIN SMALL LETTER A WITH RING ABOVE -// e6 LATIN SMALL LETTER AE -// e7 LATIN SMALL LETTER C WITH CEDILLA -// e8 LATIN SMALL LETTER E WITH GRAVE -// e9 LATIN SMALL LETTER E WITH ACUTE -// ea LATIN SMALL LETTER E WITH CIRCUMFLEX -// eb LATIN SMALL LETTER E WITH DIAERESIS -// ec LATIN SMALL LETTER I WITH GRAVE -// ed LATIN SMALL LETTER I WITH ACUTE -// ee LATIN SMALL LETTER I WITH CIRCUMFLEX -// ef LATIN SMALL LETTER I WITH DIAERESIS -// f0 LATIN SMALL LETTER ETH -// f1 LATIN SMALL LETTER N WITH TILDE -// f2 LATIN SMALL LETTER O WITH GRAVE -// f3 LATIN SMALL LETTER O WITH ACUTE -// f4 LATIN SMALL LETTER O WITH CIRCUMFLEX -// f5 LATIN SMALL LETTER O WITH TILDE -// f6 LATIN SMALL LETTER O WITH DIAERESIS - { 0xE0, 0x17, 0x49, 0, -32 }, -// f7 DIVISION SIGN - { 0xF7, 0x1, 0x8, 0, 0 }, -// f8 LATIN SMALL LETTER O WITH STROKE -// f9 LATIN SMALL LETTER U WITH GRAVE -// fa LATIN SMALL LETTER U WITH ACUTE -// fb LATIN SMALL LETTER U WITH CIRCUMFLEX -// fc LATIN SMALL LETTER U WITH DIAERESIS -// fd LATIN SMALL LETTER Y WITH ACUTE -// fe LATIN SMALL LETTER THORN - { 0xF8, 0x7, 0x49, 0, -32 }, -// ff LATIN SMALL LETTER Y WITH DIAERESIS - { 0xFF, 0x1, 0x49, 0, 121 }, -// 100 LATIN CAPITAL LETTER A WITH MACRON - { 0x100, 0x1, 0x89, 1, 0 }, -// 101 LATIN SMALL LETTER A WITH MACRON - { 0x101, 0x1, 0x49, 0, -1 }, -// 102 LATIN CAPITAL LETTER A WITH BREVE - { 0x102, 0x1, 0x89, 1, 0 }, -// 103 LATIN SMALL LETTER A WITH BREVE - { 0x103, 0x1, 0x49, 0, -1 }, -// 104 LATIN CAPITAL LETTER A WITH OGONEK - { 0x104, 0x1, 0x89, 1, 0 }, -// 105 LATIN SMALL LETTER A WITH OGONEK - { 0x105, 0x1, 0x49, 0, -1 }, -// 106 LATIN CAPITAL LETTER C WITH ACUTE - { 0x106, 0x1, 0x89, 1, 0 }, -// 107 LATIN SMALL LETTER C WITH ACUTE - { 0x107, 0x1, 0x49, 0, -1 }, -// 108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX - { 0x108, 0x1, 0x89, 1, 0 }, -// 109 LATIN SMALL LETTER C WITH CIRCUMFLEX - { 0x109, 0x1, 0x49, 0, -1 }, -// 10a LATIN CAPITAL LETTER C WITH DOT ABOVE - { 0x10A, 0x1, 0x89, 1, 0 }, -// 10b LATIN SMALL LETTER C WITH DOT ABOVE - { 0x10B, 0x1, 0x49, 0, -1 }, -// 10c LATIN CAPITAL LETTER C WITH CARON - { 0x10C, 0x1, 0x89, 1, 0 }, -// 10d LATIN SMALL LETTER C WITH CARON - { 0x10D, 0x1, 0x49, 0, -1 }, -// 10e LATIN CAPITAL LETTER D WITH CARON - { 0x10E, 0x1, 0x89, 1, 0 }, -// 10f LATIN SMALL LETTER D WITH CARON - { 0x10F, 0x1, 0x49, 0, -1 }, -// 110 LATIN CAPITAL LETTER D WITH STROKE - { 0x110, 0x1, 0x89, 1, 0 }, -// 111 LATIN SMALL LETTER D WITH STROKE - { 0x111, 0x1, 0x49, 0, -1 }, -// 112 LATIN CAPITAL LETTER E WITH MACRON - { 0x112, 0x1, 0x89, 1, 0 }, -// 113 LATIN SMALL LETTER E WITH MACRON - { 0x113, 0x1, 0x49, 0, -1 }, -// 114 LATIN CAPITAL LETTER E WITH BREVE - { 0x114, 0x1, 0x89, 1, 0 }, -// 115 LATIN SMALL LETTER E WITH BREVE - { 0x115, 0x1, 0x49, 0, -1 }, -// 116 LATIN CAPITAL LETTER E WITH DOT ABOVE - { 0x116, 0x1, 0x89, 1, 0 }, -// 117 LATIN SMALL LETTER E WITH DOT ABOVE - { 0x117, 0x1, 0x49, 0, -1 }, -// 118 LATIN CAPITAL LETTER E WITH OGONEK - { 0x118, 0x1, 0x89, 1, 0 }, -// 119 LATIN SMALL LETTER E WITH OGONEK - { 0x119, 0x1, 0x49, 0, -1 }, -// 11a LATIN CAPITAL LETTER E WITH CARON - { 0x11A, 0x1, 0x89, 1, 0 }, -// 11b LATIN SMALL LETTER E WITH CARON - { 0x11B, 0x1, 0x49, 0, -1 }, -// 11c LATIN CAPITAL LETTER G WITH CIRCUMFLEX - { 0x11C, 0x1, 0x89, 1, 0 }, -// 11d LATIN SMALL LETTER G WITH CIRCUMFLEX - { 0x11D, 0x1, 0x49, 0, -1 }, -// 11e LATIN CAPITAL LETTER G WITH BREVE - { 0x11E, 0x1, 0x89, 1, 0 }, -// 11f LATIN SMALL LETTER G WITH BREVE - { 0x11F, 0x1, 0x49, 0, -1 }, -// 120 LATIN CAPITAL LETTER G WITH DOT ABOVE - { 0x120, 0x1, 0x89, 1, 0 }, -// 121 LATIN SMALL LETTER G WITH DOT ABOVE - { 0x121, 0x1, 0x49, 0, -1 }, -// 122 LATIN CAPITAL LETTER G WITH CEDILLA - { 0x122, 0x1, 0x89, 1, 0 }, -// 123 LATIN SMALL LETTER G WITH CEDILLA - { 0x123, 0x1, 0x49, 0, -1 }, -// 124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX - { 0x124, 0x1, 0x89, 1, 0 }, -// 125 LATIN SMALL LETTER H WITH CIRCUMFLEX - { 0x125, 0x1, 0x49, 0, -1 }, -// 126 LATIN CAPITAL LETTER H WITH STROKE - { 0x126, 0x1, 0x89, 1, 0 }, -// 127 LATIN SMALL LETTER H WITH STROKE - { 0x127, 0x1, 0x49, 0, -1 }, -// 128 LATIN CAPITAL LETTER I WITH TILDE - { 0x128, 0x1, 0x89, 1, 0 }, -// 129 LATIN SMALL LETTER I WITH TILDE - { 0x129, 0x1, 0x49, 0, -1 }, -// 12a LATIN CAPITAL LETTER I WITH MACRON - { 0x12A, 0x1, 0x89, 1, 0 }, -// 12b LATIN SMALL LETTER I WITH MACRON - { 0x12B, 0x1, 0x49, 0, -1 }, -// 12c LATIN CAPITAL LETTER I WITH BREVE - { 0x12C, 0x1, 0x89, 1, 0 }, -// 12d LATIN SMALL LETTER I WITH BREVE - { 0x12D, 0x1, 0x49, 0, -1 }, -// 12e LATIN CAPITAL LETTER I WITH OGONEK - { 0x12E, 0x1, 0x89, 1, 0 }, -// 12f LATIN SMALL LETTER I WITH OGONEK - { 0x12F, 0x1, 0x49, 0, -1 }, -// 130 LATIN CAPITAL LETTER I WITH DOT ABOVE - { 0x130, 0x1, 0x89, -199, 0 }, -// 131 LATIN SMALL LETTER DOTLESS I - { 0x131, 0x1, 0x49, 0, -232 }, -// 132 LATIN CAPITAL LIGATURE IJ - { 0x132, 0x1, 0x89, 1, 0 }, -// 133 LATIN SMALL LIGATURE IJ - { 0x133, 0x1, 0x49, 0, -1 }, -// 134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX - { 0x134, 0x1, 0x89, 1, 0 }, -// 135 LATIN SMALL LETTER J WITH CIRCUMFLEX - { 0x135, 0x1, 0x49, 0, -1 }, -// 136 LATIN CAPITAL LETTER K WITH CEDILLA - { 0x136, 0x1, 0x89, 1, 0 }, -// 137 LATIN SMALL LETTER K WITH CEDILLA - { 0x137, 0x1, 0x49, 0, -1 }, -// 138 LATIN SMALL LETTER KRA - { 0x138, 0x1, 0x49, 0, 0 }, -// 139 LATIN CAPITAL LETTER L WITH ACUTE - { 0x139, 0x1, 0x89, 1, 0 }, -// 13a LATIN SMALL LETTER L WITH ACUTE - { 0x13A, 0x1, 0x49, 0, -1 }, -// 13b LATIN CAPITAL LETTER L WITH CEDILLA - { 0x13B, 0x1, 0x89, 1, 0 }, -// 13c LATIN SMALL LETTER L WITH CEDILLA - { 0x13C, 0x1, 0x49, 0, -1 }, -// 13d LATIN CAPITAL LETTER L WITH CARON - { 0x13D, 0x1, 0x89, 1, 0 }, -// 13e LATIN SMALL LETTER L WITH CARON - { 0x13E, 0x1, 0x49, 0, -1 }, -// 13f LATIN CAPITAL LETTER L WITH MIDDLE DOT - { 0x13F, 0x1, 0x89, 1, 0 }, -// 140 LATIN SMALL LETTER L WITH MIDDLE DOT - { 0x140, 0x1, 0x49, 0, -1 }, -// 141 LATIN CAPITAL LETTER L WITH STROKE - { 0x141, 0x1, 0x89, 1, 0 }, -// 142 LATIN SMALL LETTER L WITH STROKE - { 0x142, 0x1, 0x49, 0, -1 }, -// 143 LATIN CAPITAL LETTER N WITH ACUTE - { 0x143, 0x1, 0x89, 1, 0 }, -// 144 LATIN SMALL LETTER N WITH ACUTE - { 0x144, 0x1, 0x49, 0, -1 }, -// 145 LATIN CAPITAL LETTER N WITH CEDILLA - { 0x145, 0x1, 0x89, 1, 0 }, -// 146 LATIN SMALL LETTER N WITH CEDILLA - { 0x146, 0x1, 0x49, 0, -1 }, -// 147 LATIN CAPITAL LETTER N WITH CARON - { 0x147, 0x1, 0x89, 1, 0 }, -// 148 LATIN SMALL LETTER N WITH CARON - { 0x148, 0x1, 0x49, 0, -1 }, -// 149 LATIN SMALL LETTER N PRECEDED BY APOSTROPHE - { 0x149, 0x1, 0x49, 0, 0 }, -// 14a LATIN CAPITAL LETTER ENG - { 0x14A, 0x1, 0x89, 1, 0 }, -// 14b LATIN SMALL LETTER ENG - { 0x14B, 0x1, 0x49, 0, -1 }, -// 14c LATIN CAPITAL LETTER O WITH MACRON - { 0x14C, 0x1, 0x89, 1, 0 }, -// 14d LATIN SMALL LETTER O WITH MACRON - { 0x14D, 0x1, 0x49, 0, -1 }, -// 14e LATIN CAPITAL LETTER O WITH BREVE - { 0x14E, 0x1, 0x89, 1, 0 }, -// 14f LATIN SMALL LETTER O WITH BREVE - { 0x14F, 0x1, 0x49, 0, -1 }, -// 150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE - { 0x150, 0x1, 0x89, 1, 0 }, -// 151 LATIN SMALL LETTER O WITH DOUBLE ACUTE - { 0x151, 0x1, 0x49, 0, -1 }, -// 152 LATIN CAPITAL LIGATURE OE - { 0x152, 0x1, 0x89, 1, 0 }, -// 153 LATIN SMALL LIGATURE OE - { 0x153, 0x1, 0x49, 0, -1 }, -// 154 LATIN CAPITAL LETTER R WITH ACUTE - { 0x154, 0x1, 0x89, 1, 0 }, -// 155 LATIN SMALL LETTER R WITH ACUTE - { 0x155, 0x1, 0x49, 0, -1 }, -// 156 LATIN CAPITAL LETTER R WITH CEDILLA - { 0x156, 0x1, 0x89, 1, 0 }, -// 157 LATIN SMALL LETTER R WITH CEDILLA - { 0x157, 0x1, 0x49, 0, -1 }, -// 158 LATIN CAPITAL LETTER R WITH CARON - { 0x158, 0x1, 0x89, 1, 0 }, -// 159 LATIN SMALL LETTER R WITH CARON - { 0x159, 0x1, 0x49, 0, -1 }, -// 15a LATIN CAPITAL LETTER S WITH ACUTE - { 0x15A, 0x1, 0x89, 1, 0 }, -// 15b LATIN SMALL LETTER S WITH ACUTE - { 0x15B, 0x1, 0x49, 0, -1 }, -// 15c LATIN CAPITAL LETTER S WITH CIRCUMFLEX - { 0x15C, 0x1, 0x89, 1, 0 }, -// 15d LATIN SMALL LETTER S WITH CIRCUMFLEX - { 0x15D, 0x1, 0x49, 0, -1 }, -// 15e LATIN CAPITAL LETTER S WITH CEDILLA - { 0x15E, 0x1, 0x89, 1, 0 }, -// 15f LATIN SMALL LETTER S WITH CEDILLA - { 0x15F, 0x1, 0x49, 0, -1 }, -// 160 LATIN CAPITAL LETTER S WITH CARON - { 0x160, 0x1, 0x89, 1, 0 }, -// 161 LATIN SMALL LETTER S WITH CARON - { 0x161, 0x1, 0x49, 0, -1 }, -// 162 LATIN CAPITAL LETTER T WITH CEDILLA - { 0x162, 0x1, 0x89, 1, 0 }, -// 163 LATIN SMALL LETTER T WITH CEDILLA - { 0x163, 0x1, 0x49, 0, -1 }, -// 164 LATIN CAPITAL LETTER T WITH CARON - { 0x164, 0x1, 0x89, 1, 0 }, -// 165 LATIN SMALL LETTER T WITH CARON - { 0x165, 0x1, 0x49, 0, -1 }, -// 166 LATIN CAPITAL LETTER T WITH STROKE - { 0x166, 0x1, 0x89, 1, 0 }, -// 167 LATIN SMALL LETTER T WITH STROKE - { 0x167, 0x1, 0x49, 0, -1 }, -// 168 LATIN CAPITAL LETTER U WITH TILDE - { 0x168, 0x1, 0x89, 1, 0 }, -// 169 LATIN SMALL LETTER U WITH TILDE - { 0x169, 0x1, 0x49, 0, -1 }, -// 16a LATIN CAPITAL LETTER U WITH MACRON - { 0x16A, 0x1, 0x89, 1, 0 }, -// 16b LATIN SMALL LETTER U WITH MACRON - { 0x16B, 0x1, 0x49, 0, -1 }, -// 16c LATIN CAPITAL LETTER U WITH BREVE - { 0x16C, 0x1, 0x89, 1, 0 }, -// 16d LATIN SMALL LETTER U WITH BREVE - { 0x16D, 0x1, 0x49, 0, -1 }, -// 16e LATIN CAPITAL LETTER U WITH RING ABOVE - { 0x16E, 0x1, 0x89, 1, 0 }, -// 16f LATIN SMALL LETTER U WITH RING ABOVE - { 0x16F, 0x1, 0x49, 0, -1 }, -// 170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE - { 0x170, 0x1, 0x89, 1, 0 }, -// 171 LATIN SMALL LETTER U WITH DOUBLE ACUTE - { 0x171, 0x1, 0x49, 0, -1 }, -// 172 LATIN CAPITAL LETTER U WITH OGONEK - { 0x172, 0x1, 0x89, 1, 0 }, -// 173 LATIN SMALL LETTER U WITH OGONEK - { 0x173, 0x1, 0x49, 0, -1 }, -// 174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX - { 0x174, 0x1, 0x89, 1, 0 }, -// 175 LATIN SMALL LETTER W WITH CIRCUMFLEX - { 0x175, 0x1, 0x49, 0, -1 }, -// 176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX - { 0x176, 0x1, 0x89, 1, 0 }, -// 177 LATIN SMALL LETTER Y WITH CIRCUMFLEX - { 0x177, 0x1, 0x49, 0, -1 }, -// 178 LATIN CAPITAL LETTER Y WITH DIAERESIS - { 0x178, 0x1, 0x89, -121, 0 }, -// 179 LATIN CAPITAL LETTER Z WITH ACUTE - { 0x179, 0x1, 0x89, 1, 0 }, -// 17a LATIN SMALL LETTER Z WITH ACUTE - { 0x17A, 0x1, 0x49, 0, -1 }, -// 17b LATIN CAPITAL LETTER Z WITH DOT ABOVE - { 0x17B, 0x1, 0x89, 1, 0 }, -// 17c LATIN SMALL LETTER Z WITH DOT ABOVE - { 0x17C, 0x1, 0x49, 0, -1 }, -// 17d LATIN CAPITAL LETTER Z WITH CARON - { 0x17D, 0x1, 0x89, 1, 0 }, -// 17e LATIN SMALL LETTER Z WITH CARON - { 0x17E, 0x1, 0x49, 0, -1 }, -// 17f LATIN SMALL LETTER LONG S - { 0x17F, 0x1, 0x49, 0, -300 }, -// 180 LATIN SMALL LETTER B WITH STROKE - { 0x180, 0x1, 0x49, 0, 195 }, -// 181 LATIN CAPITAL LETTER B WITH HOOK - { 0x181, 0x1, 0x89, 210, 0 }, -// 182 LATIN CAPITAL LETTER B WITH TOPBAR - { 0x182, 0x1, 0x89, 1, 0 }, -// 183 LATIN SMALL LETTER B WITH TOPBAR - { 0x183, 0x1, 0x49, 0, -1 }, -// 184 LATIN CAPITAL LETTER TONE SIX - { 0x184, 0x1, 0x89, 1, 0 }, -// 185 LATIN SMALL LETTER TONE SIX - { 0x185, 0x1, 0x49, 0, -1 }, -// 186 LATIN CAPITAL LETTER OPEN O - { 0x186, 0x1, 0x89, 206, 0 }, -// 187 LATIN CAPITAL LETTER C WITH HOOK - { 0x187, 0x1, 0x89, 1, 0 }, -// 188 LATIN SMALL LETTER C WITH HOOK - { 0x188, 0x1, 0x49, 0, -1 }, -// 189 LATIN CAPITAL LETTER AFRICAN D -// 18a LATIN CAPITAL LETTER D WITH HOOK - { 0x189, 0x2, 0x89, 205, 0 }, -// 18b LATIN CAPITAL LETTER D WITH TOPBAR - { 0x18B, 0x1, 0x89, 1, 0 }, -// 18c LATIN SMALL LETTER D WITH TOPBAR - { 0x18C, 0x1, 0x49, 0, -1 }, -// 18d LATIN SMALL LETTER TURNED DELTA - { 0x18D, 0x1, 0x49, 0, 0 }, -// 18e LATIN CAPITAL LETTER REVERSED E - { 0x18E, 0x1, 0x89, 79, 0 }, -// 18f LATIN CAPITAL LETTER SCHWA - { 0x18F, 0x1, 0x89, 202, 0 }, -// 190 LATIN CAPITAL LETTER OPEN E - { 0x190, 0x1, 0x89, 203, 0 }, -// 191 LATIN CAPITAL LETTER F WITH HOOK - { 0x191, 0x1, 0x89, 1, 0 }, -// 192 LATIN SMALL LETTER F WITH HOOK - { 0x192, 0x1, 0x49, 0, -1 }, -// 193 LATIN CAPITAL LETTER G WITH HOOK - { 0x193, 0x1, 0x89, 205, 0 }, -// 194 LATIN CAPITAL LETTER GAMMA - { 0x194, 0x1, 0x89, 207, 0 }, -// 195 LATIN SMALL LETTER HV - { 0x195, 0x1, 0x49, 0, 97 }, -// 196 LATIN CAPITAL LETTER IOTA - { 0x196, 0x1, 0x89, 211, 0 }, -// 197 LATIN CAPITAL LETTER I WITH STROKE - { 0x197, 0x1, 0x89, 209, 0 }, -// 198 LATIN CAPITAL LETTER K WITH HOOK - { 0x198, 0x1, 0x89, 1, 0 }, -// 199 LATIN SMALL LETTER K WITH HOOK - { 0x199, 0x1, 0x49, 0, -1 }, -// 19a LATIN SMALL LETTER L WITH BAR - { 0x19A, 0x1, 0x49, 0, 163 }, -// 19b LATIN SMALL LETTER LAMBDA WITH STROKE - { 0x19B, 0x1, 0x49, 0, 0 }, -// 19c LATIN CAPITAL LETTER TURNED M - { 0x19C, 0x1, 0x89, 211, 0 }, -// 19d LATIN CAPITAL LETTER N WITH LEFT HOOK - { 0x19D, 0x1, 0x89, 213, 0 }, -// 19e LATIN SMALL LETTER N WITH LONG RIGHT LEG - { 0x19E, 0x1, 0x49, 0, 130 }, -// 19f LATIN CAPITAL LETTER O WITH MIDDLE TILDE - { 0x19F, 0x1, 0x89, 214, 0 }, -// 1a0 LATIN CAPITAL LETTER O WITH HORN - { 0x1A0, 0x1, 0x89, 1, 0 }, -// 1a1 LATIN SMALL LETTER O WITH HORN - { 0x1A1, 0x1, 0x49, 0, -1 }, -// 1a2 LATIN CAPITAL LETTER OI - { 0x1A2, 0x1, 0x89, 1, 0 }, -// 1a3 LATIN SMALL LETTER OI - { 0x1A3, 0x1, 0x49, 0, -1 }, -// 1a4 LATIN CAPITAL LETTER P WITH HOOK - { 0x1A4, 0x1, 0x89, 1, 0 }, -// 1a5 LATIN SMALL LETTER P WITH HOOK - { 0x1A5, 0x1, 0x49, 0, -1 }, -// 1a6 LATIN LETTER YR - { 0x1A6, 0x1, 0x89, 218, 0 }, -// 1a7 LATIN CAPITAL LETTER TONE TWO - { 0x1A7, 0x1, 0x89, 1, 0 }, -// 1a8 LATIN SMALL LETTER TONE TWO - { 0x1A8, 0x1, 0x49, 0, -1 }, -// 1a9 LATIN CAPITAL LETTER ESH - { 0x1A9, 0x1, 0x89, 218, 0 }, -// 1aa LATIN LETTER REVERSED ESH LOOP -// 1ab LATIN SMALL LETTER T WITH PALATAL HOOK - { 0x1AA, 0x2, 0x49, 0, 0 }, -// 1ac LATIN CAPITAL LETTER T WITH HOOK - { 0x1AC, 0x1, 0x89, 1, 0 }, -// 1ad LATIN SMALL LETTER T WITH HOOK - { 0x1AD, 0x1, 0x49, 0, -1 }, -// 1ae LATIN CAPITAL LETTER T WITH RETROFLEX HOOK - { 0x1AE, 0x1, 0x89, 218, 0 }, -// 1af LATIN CAPITAL LETTER U WITH HORN - { 0x1AF, 0x1, 0x89, 1, 0 }, -// 1b0 LATIN SMALL LETTER U WITH HORN - { 0x1B0, 0x1, 0x49, 0, -1 }, -// 1b1 LATIN CAPITAL LETTER UPSILON -// 1b2 LATIN CAPITAL LETTER V WITH HOOK - { 0x1B1, 0x2, 0x89, 217, 0 }, -// 1b3 LATIN CAPITAL LETTER Y WITH HOOK - { 0x1B3, 0x1, 0x89, 1, 0 }, -// 1b4 LATIN SMALL LETTER Y WITH HOOK - { 0x1B4, 0x1, 0x49, 0, -1 }, -// 1b5 LATIN CAPITAL LETTER Z WITH STROKE - { 0x1B5, 0x1, 0x89, 1, 0 }, -// 1b6 LATIN SMALL LETTER Z WITH STROKE - { 0x1B6, 0x1, 0x49, 0, -1 }, -// 1b7 LATIN CAPITAL LETTER EZH - { 0x1B7, 0x1, 0x89, 219, 0 }, -// 1b8 LATIN CAPITAL LETTER EZH REVERSED - { 0x1B8, 0x1, 0x89, 1, 0 }, -// 1b9 LATIN SMALL LETTER EZH REVERSED - { 0x1B9, 0x1, 0x49, 0, -1 }, -// 1ba LATIN SMALL LETTER EZH WITH TAIL - { 0x1BA, 0x1, 0x49, 0, 0 }, -// 1bb LATIN LETTER TWO WITH STROKE - { 0x1BB, 0x1, 0x9, 0, 0 }, -// 1bc LATIN CAPITAL LETTER TONE FIVE - { 0x1BC, 0x1, 0x89, 1, 0 }, -// 1bd LATIN SMALL LETTER TONE FIVE - { 0x1BD, 0x1, 0x49, 0, -1 }, -// 1be LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE - { 0x1BE, 0x1, 0x49, 0, 0 }, -// 1bf LATIN LETTER WYNN - { 0x1BF, 0x1, 0x49, 0, 56 }, -// 1c0 LATIN LETTER DENTAL CLICK -// 1c1 LATIN LETTER LATERAL CLICK -// 1c2 LATIN LETTER ALVEOLAR CLICK -// 1c3 LATIN LETTER RETROFLEX CLICK - { 0x1C0, 0x4, 0x9, 0, 0 }, -// 1c4 LATIN CAPITAL LETTER DZ WITH CARON - { 0x1C4, 0x1, 0x89, 2, 0 }, -// 1c5 LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON - { 0x1C5, 0x1, 0x89, 1, -1 }, -// 1c6 LATIN SMALL LETTER DZ WITH CARON - { 0x1C6, 0x1, 0x49, 0, -2 }, -// 1c7 LATIN CAPITAL LETTER LJ - { 0x1C7, 0x1, 0x89, 2, 0 }, -// 1c8 LATIN CAPITAL LETTER L WITH SMALL LETTER J - { 0x1C8, 0x1, 0x89, 1, -1 }, -// 1c9 LATIN SMALL LETTER LJ - { 0x1C9, 0x1, 0x49, 0, -2 }, -// 1ca LATIN CAPITAL LETTER NJ - { 0x1CA, 0x1, 0x89, 2, 0 }, -// 1cb LATIN CAPITAL LETTER N WITH SMALL LETTER J - { 0x1CB, 0x1, 0x89, 1, -1 }, -// 1cc LATIN SMALL LETTER NJ - { 0x1CC, 0x1, 0x49, 0, -2 }, -// 1cd LATIN CAPITAL LETTER A WITH CARON - { 0x1CD, 0x1, 0x89, 1, 0 }, -// 1ce LATIN SMALL LETTER A WITH CARON - { 0x1CE, 0x1, 0x49, 0, -1 }, -// 1cf LATIN CAPITAL LETTER I WITH CARON - { 0x1CF, 0x1, 0x89, 1, 0 }, -// 1d0 LATIN SMALL LETTER I WITH CARON - { 0x1D0, 0x1, 0x49, 0, -1 }, -// 1d1 LATIN CAPITAL LETTER O WITH CARON - { 0x1D1, 0x1, 0x89, 1, 0 }, -// 1d2 LATIN SMALL LETTER O WITH CARON - { 0x1D2, 0x1, 0x49, 0, -1 }, -// 1d3 LATIN CAPITAL LETTER U WITH CARON - { 0x1D3, 0x1, 0x89, 1, 0 }, -// 1d4 LATIN SMALL LETTER U WITH CARON - { 0x1D4, 0x1, 0x49, 0, -1 }, -// 1d5 LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON - { 0x1D5, 0x1, 0x89, 1, 0 }, -// 1d6 LATIN SMALL LETTER U WITH DIAERESIS AND MACRON - { 0x1D6, 0x1, 0x49, 0, -1 }, -// 1d7 LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE - { 0x1D7, 0x1, 0x89, 1, 0 }, -// 1d8 LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE - { 0x1D8, 0x1, 0x49, 0, -1 }, -// 1d9 LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON - { 0x1D9, 0x1, 0x89, 1, 0 }, -// 1da LATIN SMALL LETTER U WITH DIAERESIS AND CARON - { 0x1DA, 0x1, 0x49, 0, -1 }, -// 1db LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE - { 0x1DB, 0x1, 0x89, 1, 0 }, -// 1dc LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE - { 0x1DC, 0x1, 0x49, 0, -1 }, -// 1dd LATIN SMALL LETTER TURNED E - { 0x1DD, 0x1, 0x49, 0, -79 }, -// 1de LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON - { 0x1DE, 0x1, 0x89, 1, 0 }, -// 1df LATIN SMALL LETTER A WITH DIAERESIS AND MACRON - { 0x1DF, 0x1, 0x49, 0, -1 }, -// 1e0 LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON - { 0x1E0, 0x1, 0x89, 1, 0 }, -// 1e1 LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON - { 0x1E1, 0x1, 0x49, 0, -1 }, -// 1e2 LATIN CAPITAL LETTER AE WITH MACRON - { 0x1E2, 0x1, 0x89, 1, 0 }, -// 1e3 LATIN SMALL LETTER AE WITH MACRON - { 0x1E3, 0x1, 0x49, 0, -1 }, -// 1e4 LATIN CAPITAL LETTER G WITH STROKE - { 0x1E4, 0x1, 0x89, 1, 0 }, -// 1e5 LATIN SMALL LETTER G WITH STROKE - { 0x1E5, 0x1, 0x49, 0, -1 }, -// 1e6 LATIN CAPITAL LETTER G WITH CARON - { 0x1E6, 0x1, 0x89, 1, 0 }, -// 1e7 LATIN SMALL LETTER G WITH CARON - { 0x1E7, 0x1, 0x49, 0, -1 }, -// 1e8 LATIN CAPITAL LETTER K WITH CARON - { 0x1E8, 0x1, 0x89, 1, 0 }, -// 1e9 LATIN SMALL LETTER K WITH CARON - { 0x1E9, 0x1, 0x49, 0, -1 }, -// 1ea LATIN CAPITAL LETTER O WITH OGONEK - { 0x1EA, 0x1, 0x89, 1, 0 }, -// 1eb LATIN SMALL LETTER O WITH OGONEK - { 0x1EB, 0x1, 0x49, 0, -1 }, -// 1ec LATIN CAPITAL LETTER O WITH OGONEK AND MACRON - { 0x1EC, 0x1, 0x89, 1, 0 }, -// 1ed LATIN SMALL LETTER O WITH OGONEK AND MACRON - { 0x1ED, 0x1, 0x49, 0, -1 }, -// 1ee LATIN CAPITAL LETTER EZH WITH CARON - { 0x1EE, 0x1, 0x89, 1, 0 }, -// 1ef LATIN SMALL LETTER EZH WITH CARON - { 0x1EF, 0x1, 0x49, 0, -1 }, -// 1f0 LATIN SMALL LETTER J WITH CARON - { 0x1F0, 0x1, 0x49, 0, 0 }, -// 1f1 LATIN CAPITAL LETTER DZ - { 0x1F1, 0x1, 0x89, 2, 0 }, -// 1f2 LATIN CAPITAL LETTER D WITH SMALL LETTER Z - { 0x1F2, 0x1, 0x89, 1, -1 }, -// 1f3 LATIN SMALL LETTER DZ - { 0x1F3, 0x1, 0x49, 0, -2 }, -// 1f4 LATIN CAPITAL LETTER G WITH ACUTE - { 0x1F4, 0x1, 0x89, 1, 0 }, -// 1f5 LATIN SMALL LETTER G WITH ACUTE - { 0x1F5, 0x1, 0x49, 0, -1 }, -// 1f6 LATIN CAPITAL LETTER HWAIR - { 0x1F6, 0x1, 0x89, -97, 0 }, -// 1f7 LATIN CAPITAL LETTER WYNN - { 0x1F7, 0x1, 0x89, -56, 0 }, -// 1f8 LATIN CAPITAL LETTER N WITH GRAVE - { 0x1F8, 0x1, 0x89, 1, 0 }, -// 1f9 LATIN SMALL LETTER N WITH GRAVE - { 0x1F9, 0x1, 0x49, 0, -1 }, -// 1fa LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE - { 0x1FA, 0x1, 0x89, 1, 0 }, -// 1fb LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE - { 0x1FB, 0x1, 0x49, 0, -1 }, -// 1fc LATIN CAPITAL LETTER AE WITH ACUTE - { 0x1FC, 0x1, 0x89, 1, 0 }, -// 1fd LATIN SMALL LETTER AE WITH ACUTE - { 0x1FD, 0x1, 0x49, 0, -1 }, -// 1fe LATIN CAPITAL LETTER O WITH STROKE AND ACUTE - { 0x1FE, 0x1, 0x89, 1, 0 }, -// 1ff LATIN SMALL LETTER O WITH STROKE AND ACUTE - { 0x1FF, 0x1, 0x49, 0, -1 }, -// 200 LATIN CAPITAL LETTER A WITH DOUBLE GRAVE - { 0x200, 0x1, 0x89, 1, 0 }, -// 201 LATIN SMALL LETTER A WITH DOUBLE GRAVE - { 0x201, 0x1, 0x49, 0, -1 }, -// 202 LATIN CAPITAL LETTER A WITH INVERTED BREVE - { 0x202, 0x1, 0x89, 1, 0 }, -// 203 LATIN SMALL LETTER A WITH INVERTED BREVE - { 0x203, 0x1, 0x49, 0, -1 }, -// 204 LATIN CAPITAL LETTER E WITH DOUBLE GRAVE - { 0x204, 0x1, 0x89, 1, 0 }, -// 205 LATIN SMALL LETTER E WITH DOUBLE GRAVE - { 0x205, 0x1, 0x49, 0, -1 }, -// 206 LATIN CAPITAL LETTER E WITH INVERTED BREVE - { 0x206, 0x1, 0x89, 1, 0 }, -// 207 LATIN SMALL LETTER E WITH INVERTED BREVE - { 0x207, 0x1, 0x49, 0, -1 }, -// 208 LATIN CAPITAL LETTER I WITH DOUBLE GRAVE - { 0x208, 0x1, 0x89, 1, 0 }, -// 209 LATIN SMALL LETTER I WITH DOUBLE GRAVE - { 0x209, 0x1, 0x49, 0, -1 }, -// 20a LATIN CAPITAL LETTER I WITH INVERTED BREVE - { 0x20A, 0x1, 0x89, 1, 0 }, -// 20b LATIN SMALL LETTER I WITH INVERTED BREVE - { 0x20B, 0x1, 0x49, 0, -1 }, -// 20c LATIN CAPITAL LETTER O WITH DOUBLE GRAVE - { 0x20C, 0x1, 0x89, 1, 0 }, -// 20d LATIN SMALL LETTER O WITH DOUBLE GRAVE - { 0x20D, 0x1, 0x49, 0, -1 }, -// 20e LATIN CAPITAL LETTER O WITH INVERTED BREVE - { 0x20E, 0x1, 0x89, 1, 0 }, -// 20f LATIN SMALL LETTER O WITH INVERTED BREVE - { 0x20F, 0x1, 0x49, 0, -1 }, -// 210 LATIN CAPITAL LETTER R WITH DOUBLE GRAVE - { 0x210, 0x1, 0x89, 1, 0 }, -// 211 LATIN SMALL LETTER R WITH DOUBLE GRAVE - { 0x211, 0x1, 0x49, 0, -1 }, -// 212 LATIN CAPITAL LETTER R WITH INVERTED BREVE - { 0x212, 0x1, 0x89, 1, 0 }, -// 213 LATIN SMALL LETTER R WITH INVERTED BREVE - { 0x213, 0x1, 0x49, 0, -1 }, -// 214 LATIN CAPITAL LETTER U WITH DOUBLE GRAVE - { 0x214, 0x1, 0x89, 1, 0 }, -// 215 LATIN SMALL LETTER U WITH DOUBLE GRAVE - { 0x215, 0x1, 0x49, 0, -1 }, -// 216 LATIN CAPITAL LETTER U WITH INVERTED BREVE - { 0x216, 0x1, 0x89, 1, 0 }, -// 217 LATIN SMALL LETTER U WITH INVERTED BREVE - { 0x217, 0x1, 0x49, 0, -1 }, -// 218 LATIN CAPITAL LETTER S WITH COMMA BELOW - { 0x218, 0x1, 0x89, 1, 0 }, -// 219 LATIN SMALL LETTER S WITH COMMA BELOW - { 0x219, 0x1, 0x49, 0, -1 }, -// 21a LATIN CAPITAL LETTER T WITH COMMA BELOW - { 0x21A, 0x1, 0x89, 1, 0 }, -// 21b LATIN SMALL LETTER T WITH COMMA BELOW - { 0x21B, 0x1, 0x49, 0, -1 }, -// 21c LATIN CAPITAL LETTER YOGH - { 0x21C, 0x1, 0x89, 1, 0 }, -// 21d LATIN SMALL LETTER YOGH - { 0x21D, 0x1, 0x49, 0, -1 }, -// 21e LATIN CAPITAL LETTER H WITH CARON - { 0x21E, 0x1, 0x89, 1, 0 }, -// 21f LATIN SMALL LETTER H WITH CARON - { 0x21F, 0x1, 0x49, 0, -1 }, -// 220 LATIN CAPITAL LETTER N WITH LONG RIGHT LEG - { 0x220, 0x1, 0x89, -130, 0 }, -// 221 LATIN SMALL LETTER D WITH CURL - { 0x221, 0x1, 0x49, 0, 0 }, -// 222 LATIN CAPITAL LETTER OU - { 0x222, 0x1, 0x89, 1, 0 }, -// 223 LATIN SMALL LETTER OU - { 0x223, 0x1, 0x49, 0, -1 }, -// 224 LATIN CAPITAL LETTER Z WITH HOOK - { 0x224, 0x1, 0x89, 1, 0 }, -// 225 LATIN SMALL LETTER Z WITH HOOK - { 0x225, 0x1, 0x49, 0, -1 }, -// 226 LATIN CAPITAL LETTER A WITH DOT ABOVE - { 0x226, 0x1, 0x89, 1, 0 }, -// 227 LATIN SMALL LETTER A WITH DOT ABOVE - { 0x227, 0x1, 0x49, 0, -1 }, -// 228 LATIN CAPITAL LETTER E WITH CEDILLA - { 0x228, 0x1, 0x89, 1, 0 }, -// 229 LATIN SMALL LETTER E WITH CEDILLA - { 0x229, 0x1, 0x49, 0, -1 }, -// 22a LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON - { 0x22A, 0x1, 0x89, 1, 0 }, -// 22b LATIN SMALL LETTER O WITH DIAERESIS AND MACRON - { 0x22B, 0x1, 0x49, 0, -1 }, -// 22c LATIN CAPITAL LETTER O WITH TILDE AND MACRON - { 0x22C, 0x1, 0x89, 1, 0 }, -// 22d LATIN SMALL LETTER O WITH TILDE AND MACRON - { 0x22D, 0x1, 0x49, 0, -1 }, -// 22e LATIN CAPITAL LETTER O WITH DOT ABOVE - { 0x22E, 0x1, 0x89, 1, 0 }, -// 22f LATIN SMALL LETTER O WITH DOT ABOVE - { 0x22F, 0x1, 0x49, 0, -1 }, -// 230 LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON - { 0x230, 0x1, 0x89, 1, 0 }, -// 231 LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON - { 0x231, 0x1, 0x49, 0, -1 }, -// 232 LATIN CAPITAL LETTER Y WITH MACRON - { 0x232, 0x1, 0x89, 1, 0 }, -// 233 LATIN SMALL LETTER Y WITH MACRON - { 0x233, 0x1, 0x49, 0, -1 }, -// 234 LATIN SMALL LETTER L WITH CURL -// 235 LATIN SMALL LETTER N WITH CURL -// 236 LATIN SMALL LETTER T WITH CURL -// 237 LATIN SMALL LETTER DOTLESS J -// 238 LATIN SMALL LETTER DB DIGRAPH -// 239 LATIN SMALL LETTER QP DIGRAPH - { 0x234, 0x6, 0x49, 0, 0 }, -// 23a LATIN CAPITAL LETTER A WITH STROKE - { 0x23A, 0x1, 0x89, 10795, 0 }, -// 23b LATIN CAPITAL LETTER C WITH STROKE - { 0x23B, 0x1, 0x89, 1, 0 }, -// 23c LATIN SMALL LETTER C WITH STROKE - { 0x23C, 0x1, 0x49, 0, -1 }, -// 23d LATIN CAPITAL LETTER L WITH BAR - { 0x23D, 0x1, 0x89, -163, 0 }, -// 23e LATIN CAPITAL LETTER T WITH DIAGONAL STROKE - { 0x23E, 0x1, 0x89, 10792, 0 }, -// 23f LATIN SMALL LETTER S WITH SWASH TAIL -// 240 LATIN SMALL LETTER Z WITH SWASH TAIL - { 0x23F, 0x2, 0x49, 0, 10815 }, -// 241 LATIN CAPITAL LETTER GLOTTAL STOP - { 0x241, 0x1, 0x89, 1, 0 }, -// 242 LATIN SMALL LETTER GLOTTAL STOP - { 0x242, 0x1, 0x49, 0, -1 }, -// 243 LATIN CAPITAL LETTER B WITH STROKE - { 0x243, 0x1, 0x89, -195, 0 }, -// 244 LATIN CAPITAL LETTER U BAR - { 0x244, 0x1, 0x89, 69, 0 }, -// 245 LATIN CAPITAL LETTER TURNED V - { 0x245, 0x1, 0x89, 71, 0 }, -// 246 LATIN CAPITAL LETTER E WITH STROKE - { 0x246, 0x1, 0x89, 1, 0 }, -// 247 LATIN SMALL LETTER E WITH STROKE - { 0x247, 0x1, 0x49, 0, -1 }, -// 248 LATIN CAPITAL LETTER J WITH STROKE - { 0x248, 0x1, 0x89, 1, 0 }, -// 249 LATIN SMALL LETTER J WITH STROKE - { 0x249, 0x1, 0x49, 0, -1 }, -// 24a LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL - { 0x24A, 0x1, 0x89, 1, 0 }, -// 24b LATIN SMALL LETTER Q WITH HOOK TAIL - { 0x24B, 0x1, 0x49, 0, -1 }, -// 24c LATIN CAPITAL LETTER R WITH STROKE - { 0x24C, 0x1, 0x89, 1, 0 }, -// 24d LATIN SMALL LETTER R WITH STROKE - { 0x24D, 0x1, 0x49, 0, -1 }, -// 24e LATIN CAPITAL LETTER Y WITH STROKE - { 0x24E, 0x1, 0x89, 1, 0 }, -// 24f LATIN SMALL LETTER Y WITH STROKE - { 0x24F, 0x1, 0x49, 0, -1 }, -// 250 LATIN SMALL LETTER TURNED A - { 0x250, 0x1, 0x49, 0, 10783 }, -// 251 LATIN SMALL LETTER ALPHA - { 0x251, 0x1, 0x49, 0, 10780 }, -// 252 LATIN SMALL LETTER TURNED ALPHA - { 0x252, 0x1, 0x49, 0, 10782 }, -// 253 LATIN SMALL LETTER B WITH HOOK - { 0x253, 0x1, 0x49, 0, -210 }, -// 254 LATIN SMALL LETTER OPEN O - { 0x254, 0x1, 0x49, 0, -206 }, -// 255 LATIN SMALL LETTER C WITH CURL - { 0x255, 0x1, 0x49, 0, 0 }, -// 256 LATIN SMALL LETTER D WITH TAIL -// 257 LATIN SMALL LETTER D WITH HOOK - { 0x256, 0x2, 0x49, 0, -205 }, -// 258 LATIN SMALL LETTER REVERSED E - { 0x258, 0x1, 0x49, 0, 0 }, -// 259 LATIN SMALL LETTER SCHWA - { 0x259, 0x1, 0x49, 0, -202 }, -// 25a LATIN SMALL LETTER SCHWA WITH HOOK - { 0x25A, 0x1, 0x49, 0, 0 }, -// 25b LATIN SMALL LETTER OPEN E - { 0x25B, 0x1, 0x49, 0, -203 }, -// 25c LATIN SMALL LETTER REVERSED OPEN E - { 0x25C, 0x1, 0x49, 0, 42319 }, -// 25d LATIN SMALL LETTER REVERSED OPEN E WITH HOOK -// 25e LATIN SMALL LETTER CLOSED REVERSED OPEN E -// 25f LATIN SMALL LETTER DOTLESS J WITH STROKE - { 0x25D, 0x3, 0x49, 0, 0 }, -// 260 LATIN SMALL LETTER G WITH HOOK - { 0x260, 0x1, 0x49, 0, -205 }, -// 261 LATIN SMALL LETTER SCRIPT G - { 0x261, 0x1, 0x49, 0, 42315 }, -// 262 LATIN LETTER SMALL CAPITAL G - { 0x262, 0x1, 0x49, 0, 0 }, -// 263 LATIN SMALL LETTER GAMMA - { 0x263, 0x1, 0x49, 0, -207 }, -// 264 LATIN SMALL LETTER RAMS HORN - { 0x264, 0x1, 0x49, 0, 0 }, -// 265 LATIN SMALL LETTER TURNED H - { 0x265, 0x1, 0x49, 0, 42280 }, -// 266 LATIN SMALL LETTER H WITH HOOK - { 0x266, 0x1, 0x49, 0, 42308 }, -// 267 LATIN SMALL LETTER HENG WITH HOOK - { 0x267, 0x1, 0x49, 0, 0 }, -// 268 LATIN SMALL LETTER I WITH STROKE - { 0x268, 0x1, 0x49, 0, -209 }, -// 269 LATIN SMALL LETTER IOTA - { 0x269, 0x1, 0x49, 0, -211 }, -// 26a LATIN LETTER SMALL CAPITAL I - { 0x26A, 0x1, 0x49, 0, 0 }, -// 26b LATIN SMALL LETTER L WITH MIDDLE TILDE - { 0x26B, 0x1, 0x49, 0, 10743 }, -// 26c LATIN SMALL LETTER L WITH BELT - { 0x26C, 0x1, 0x49, 0, 42305 }, -// 26d LATIN SMALL LETTER L WITH RETROFLEX HOOK -// 26e LATIN SMALL LETTER LEZH - { 0x26D, 0x2, 0x49, 0, 0 }, -// 26f LATIN SMALL LETTER TURNED M - { 0x26F, 0x1, 0x49, 0, -211 }, -// 270 LATIN SMALL LETTER TURNED M WITH LONG LEG - { 0x270, 0x1, 0x49, 0, 0 }, -// 271 LATIN SMALL LETTER M WITH HOOK - { 0x271, 0x1, 0x49, 0, 10749 }, -// 272 LATIN SMALL LETTER N WITH LEFT HOOK - { 0x272, 0x1, 0x49, 0, -213 }, -// 273 LATIN SMALL LETTER N WITH RETROFLEX HOOK -// 274 LATIN LETTER SMALL CAPITAL N - { 0x273, 0x2, 0x49, 0, 0 }, -// 275 LATIN SMALL LETTER BARRED O - { 0x275, 0x1, 0x49, 0, -214 }, -// 276 LATIN LETTER SMALL CAPITAL OE -// 277 LATIN SMALL LETTER CLOSED OMEGA -// 278 LATIN SMALL LETTER PHI -// 279 LATIN SMALL LETTER TURNED R -// 27a LATIN SMALL LETTER TURNED R WITH LONG LEG -// 27b LATIN SMALL LETTER TURNED R WITH HOOK -// 27c LATIN SMALL LETTER R WITH LONG LEG - { 0x276, 0x7, 0x49, 0, 0 }, -// 27d LATIN SMALL LETTER R WITH TAIL - { 0x27D, 0x1, 0x49, 0, 10727 }, -// 27e LATIN SMALL LETTER R WITH FISHHOOK -// 27f LATIN SMALL LETTER REVERSED R WITH FISHHOOK - { 0x27E, 0x2, 0x49, 0, 0 }, -// 280 LATIN LETTER SMALL CAPITAL R - { 0x280, 0x1, 0x49, 0, -218 }, -// 281 LATIN LETTER SMALL CAPITAL INVERTED R -// 282 LATIN SMALL LETTER S WITH HOOK - { 0x281, 0x2, 0x49, 0, 0 }, -// 283 LATIN SMALL LETTER ESH - { 0x283, 0x1, 0x49, 0, -218 }, -// 284 LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK -// 285 LATIN SMALL LETTER SQUAT REVERSED ESH -// 286 LATIN SMALL LETTER ESH WITH CURL - { 0x284, 0x3, 0x49, 0, 0 }, -// 287 LATIN SMALL LETTER TURNED T - { 0x287, 0x1, 0x49, 0, 42282 }, -// 288 LATIN SMALL LETTER T WITH RETROFLEX HOOK - { 0x288, 0x1, 0x49, 0, -218 }, -// 289 LATIN SMALL LETTER U BAR - { 0x289, 0x1, 0x49, 0, -69 }, -// 28a LATIN SMALL LETTER UPSILON -// 28b LATIN SMALL LETTER V WITH HOOK - { 0x28A, 0x2, 0x49, 0, -217 }, -// 28c LATIN SMALL LETTER TURNED V - { 0x28C, 0x1, 0x49, 0, -71 }, -// 28d LATIN SMALL LETTER TURNED W -// 28e LATIN SMALL LETTER TURNED Y -// 28f LATIN LETTER SMALL CAPITAL Y -// 290 LATIN SMALL LETTER Z WITH RETROFLEX HOOK -// 291 LATIN SMALL LETTER Z WITH CURL - { 0x28D, 0x5, 0x49, 0, 0 }, -// 292 LATIN SMALL LETTER EZH - { 0x292, 0x1, 0x49, 0, -219 }, -// 293 LATIN SMALL LETTER EZH WITH CURL - { 0x293, 0x1, 0x49, 0, 0 }, -// 294 LATIN LETTER GLOTTAL STOP - { 0x294, 0x1, 0x9, 0, 0 }, -// 295 LATIN LETTER PHARYNGEAL VOICED FRICATIVE -// 296 LATIN LETTER INVERTED GLOTTAL STOP -// 297 LATIN LETTER STRETCHED C -// 298 LATIN LETTER BILABIAL CLICK -// 299 LATIN LETTER SMALL CAPITAL B -// 29a LATIN SMALL LETTER CLOSED OPEN E -// 29b LATIN LETTER SMALL CAPITAL G WITH HOOK -// 29c LATIN LETTER SMALL CAPITAL H -// 29d LATIN SMALL LETTER J WITH CROSSED-TAIL - { 0x295, 0x9, 0x49, 0, 0 }, -// 29e LATIN SMALL LETTER TURNED K - { 0x29E, 0x1, 0x49, 0, 42258 }, -// 29f LATIN LETTER SMALL CAPITAL L -// 2a0 LATIN SMALL LETTER Q WITH HOOK -// 2a1 LATIN LETTER GLOTTAL STOP WITH STROKE -// 2a2 LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE -// 2a3 LATIN SMALL LETTER DZ DIGRAPH -// 2a4 LATIN SMALL LETTER DEZH DIGRAPH -// 2a5 LATIN SMALL LETTER DZ DIGRAPH WITH CURL -// 2a6 LATIN SMALL LETTER TS DIGRAPH -// 2a7 LATIN SMALL LETTER TESH DIGRAPH -// 2a8 LATIN SMALL LETTER TC DIGRAPH WITH CURL -// 2a9 LATIN SMALL LETTER FENG DIGRAPH -// 2aa LATIN SMALL LETTER LS DIGRAPH -// 2ab LATIN SMALL LETTER LZ DIGRAPH -// 2ac LATIN LETTER BILABIAL PERCUSSIVE -// 2ad LATIN LETTER BIDENTAL PERCUSSIVE -// 2ae LATIN SMALL LETTER TURNED H WITH FISHHOOK -// 2af LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL - { 0x29F, 0x11, 0x49, 0, 0 }, -// 2b0 MODIFIER LETTER SMALL H -// 2b1 MODIFIER LETTER SMALL H WITH HOOK -// 2b2 MODIFIER LETTER SMALL J -// 2b3 MODIFIER LETTER SMALL R -// 2b4 MODIFIER LETTER SMALL TURNED R -// 2b5 MODIFIER LETTER SMALL TURNED R WITH HOOK -// 2b6 MODIFIER LETTER SMALL CAPITAL INVERTED R -// 2b7 MODIFIER LETTER SMALL W -// 2b8 MODIFIER LETTER SMALL Y -// 2b9 MODIFIER LETTER PRIME -// 2ba MODIFIER LETTER DOUBLE PRIME -// 2bb MODIFIER LETTER TURNED COMMA -// 2bc MODIFIER LETTER APOSTROPHE -// 2bd MODIFIER LETTER REVERSED COMMA -// 2be MODIFIER LETTER RIGHT HALF RING -// 2bf MODIFIER LETTER LEFT HALF RING -// 2c0 MODIFIER LETTER GLOTTAL STOP -// 2c1 MODIFIER LETTER REVERSED GLOTTAL STOP - { 0x2B0, 0x12, 0x9, 0, 0 }, -// 2c2 MODIFIER LETTER LEFT ARROWHEAD -// 2c3 MODIFIER LETTER RIGHT ARROWHEAD -// 2c4 MODIFIER LETTER UP ARROWHEAD -// 2c5 MODIFIER LETTER DOWN ARROWHEAD - { 0x2C2, 0x4, 0x8, 0, 0 }, -// 2c6 MODIFIER LETTER CIRCUMFLEX ACCENT -// 2c7 CARON -// 2c8 MODIFIER LETTER VERTICAL LINE -// 2c9 MODIFIER LETTER MACRON -// 2ca MODIFIER LETTER ACUTE ACCENT -// 2cb MODIFIER LETTER GRAVE ACCENT -// 2cc MODIFIER LETTER LOW VERTICAL LINE -// 2cd MODIFIER LETTER LOW MACRON -// 2ce MODIFIER LETTER LOW GRAVE ACCENT -// 2cf MODIFIER LETTER LOW ACUTE ACCENT -// 2d0 MODIFIER LETTER TRIANGULAR COLON -// 2d1 MODIFIER LETTER HALF TRIANGULAR COLON - { 0x2C6, 0xC, 0x9, 0, 0 }, -// 2d2 MODIFIER LETTER CENTRED RIGHT HALF RING -// 2d3 MODIFIER LETTER CENTRED LEFT HALF RING -// 2d4 MODIFIER LETTER UP TACK -// 2d5 MODIFIER LETTER DOWN TACK -// 2d6 MODIFIER LETTER PLUS SIGN -// 2d7 MODIFIER LETTER MINUS SIGN -// 2d8 BREVE -// 2d9 DOT ABOVE -// 2da RING ABOVE -// 2db OGONEK -// 2dc SMALL TILDE -// 2dd DOUBLE ACUTE ACCENT -// 2de MODIFIER LETTER RHOTIC HOOK -// 2df MODIFIER LETTER CROSS ACCENT - { 0x2D2, 0xE, 0x8, 0, 0 }, -// 2e0 MODIFIER LETTER SMALL GAMMA -// 2e1 MODIFIER LETTER SMALL L -// 2e2 MODIFIER LETTER SMALL S -// 2e3 MODIFIER LETTER SMALL X -// 2e4 MODIFIER LETTER SMALL REVERSED GLOTTAL STOP - { 0x2E0, 0x5, 0x9, 0, 0 }, -// 2e5 MODIFIER LETTER EXTRA-HIGH TONE BAR -// 2e6 MODIFIER LETTER HIGH TONE BAR -// 2e7 MODIFIER LETTER MID TONE BAR -// 2e8 MODIFIER LETTER LOW TONE BAR -// 2e9 MODIFIER LETTER EXTRA-LOW TONE BAR -// 2ea MODIFIER LETTER YIN DEPARTING TONE MARK -// 2eb MODIFIER LETTER YANG DEPARTING TONE MARK - { 0x2E5, 0x7, 0x8, 0, 0 }, -// 2ec MODIFIER LETTER VOICING - { 0x2EC, 0x1, 0x9, 0, 0 }, -// 2ed MODIFIER LETTER UNASPIRATED - { 0x2ED, 0x1, 0x8, 0, 0 }, -// 2ee MODIFIER LETTER DOUBLE APOSTROPHE - { 0x2EE, 0x1, 0x9, 0, 0 }, -// 2ef MODIFIER LETTER LOW DOWN ARROWHEAD -// 2f0 MODIFIER LETTER LOW UP ARROWHEAD -// 2f1 MODIFIER LETTER LOW LEFT ARROWHEAD -// 2f2 MODIFIER LETTER LOW RIGHT ARROWHEAD -// 2f3 MODIFIER LETTER LOW RING -// 2f4 MODIFIER LETTER MIDDLE GRAVE ACCENT -// 2f5 MODIFIER LETTER MIDDLE DOUBLE GRAVE ACCENT -// 2f6 MODIFIER LETTER MIDDLE DOUBLE ACUTE ACCENT -// 2f7 MODIFIER LETTER LOW TILDE -// 2f8 MODIFIER LETTER RAISED COLON -// 2f9 MODIFIER LETTER BEGIN HIGH TONE -// 2fa MODIFIER LETTER END HIGH TONE -// 2fb MODIFIER LETTER BEGIN LOW TONE -// 2fc MODIFIER LETTER END LOW TONE -// 2fd MODIFIER LETTER SHELF -// 2fe MODIFIER LETTER OPEN SHELF -// 2ff MODIFIER LETTER LOW LEFT ARROW - { 0x2EF, 0x11, 0x8, 0, 0 }, -// 300 COMBINING GRAVE ACCENT -// 301 COMBINING ACUTE ACCENT -// 302 COMBINING CIRCUMFLEX ACCENT -// 303 COMBINING TILDE -// 304 COMBINING MACRON -// 305 COMBINING OVERLINE -// 306 COMBINING BREVE -// 307 COMBINING DOT ABOVE -// 308 COMBINING DIAERESIS -// 309 COMBINING HOOK ABOVE -// 30a COMBINING RING ABOVE -// 30b COMBINING DOUBLE ACUTE ACCENT -// 30c COMBINING CARON -// 30d COMBINING VERTICAL LINE ABOVE -// 30e COMBINING DOUBLE VERTICAL LINE ABOVE -// 30f COMBINING DOUBLE GRAVE ACCENT -// 310 COMBINING CANDRABINDU -// 311 COMBINING INVERTED BREVE -// 312 COMBINING TURNED COMMA ABOVE -// 313 COMBINING COMMA ABOVE -// 314 COMBINING REVERSED COMMA ABOVE -// 315 COMBINING COMMA ABOVE RIGHT -// 316 COMBINING GRAVE ACCENT BELOW -// 317 COMBINING ACUTE ACCENT BELOW -// 318 COMBINING LEFT TACK BELOW -// 319 COMBINING RIGHT TACK BELOW -// 31a COMBINING LEFT ANGLE ABOVE -// 31b COMBINING HORN -// 31c COMBINING LEFT HALF RING BELOW -// 31d COMBINING UP TACK BELOW -// 31e COMBINING DOWN TACK BELOW -// 31f COMBINING PLUS SIGN BELOW -// 320 COMBINING MINUS SIGN BELOW -// 321 COMBINING PALATALIZED HOOK BELOW -// 322 COMBINING RETROFLEX HOOK BELOW -// 323 COMBINING DOT BELOW -// 324 COMBINING DIAERESIS BELOW -// 325 COMBINING RING BELOW -// 326 COMBINING COMMA BELOW -// 327 COMBINING CEDILLA -// 328 COMBINING OGONEK -// 329 COMBINING VERTICAL LINE BELOW -// 32a COMBINING BRIDGE BELOW -// 32b COMBINING INVERTED DOUBLE ARCH BELOW -// 32c COMBINING CARON BELOW -// 32d COMBINING CIRCUMFLEX ACCENT BELOW -// 32e COMBINING BREVE BELOW -// 32f COMBINING INVERTED BREVE BELOW -// 330 COMBINING TILDE BELOW -// 331 COMBINING MACRON BELOW -// 332 COMBINING LOW LINE -// 333 COMBINING DOUBLE LOW LINE -// 334 COMBINING TILDE OVERLAY -// 335 COMBINING SHORT STROKE OVERLAY -// 336 COMBINING LONG STROKE OVERLAY -// 337 COMBINING SHORT SOLIDUS OVERLAY -// 338 COMBINING LONG SOLIDUS OVERLAY -// 339 COMBINING RIGHT HALF RING BELOW -// 33a COMBINING INVERTED BRIDGE BELOW -// 33b COMBINING SQUARE BELOW -// 33c COMBINING SEAGULL BELOW -// 33d COMBINING X ABOVE -// 33e COMBINING VERTICAL TILDE -// 33f COMBINING DOUBLE OVERLINE -// 340 COMBINING GRAVE TONE MARK -// 341 COMBINING ACUTE TONE MARK -// 342 COMBINING GREEK PERISPOMENI -// 343 COMBINING GREEK KORONIS -// 344 COMBINING GREEK DIALYTIKA TONOS - { 0x300, 0x45, 0x0, 0, 0 }, -// 345 COMBINING GREEK YPOGEGRAMMENI - { 0x345, 0x1, 0x0, 0, 84 }, -// 346 COMBINING BRIDGE ABOVE -// 347 COMBINING EQUALS SIGN BELOW -// 348 COMBINING DOUBLE VERTICAL LINE BELOW -// 349 COMBINING LEFT ANGLE BELOW -// 34a COMBINING NOT TILDE ABOVE -// 34b COMBINING HOMOTHETIC ABOVE -// 34c COMBINING ALMOST EQUAL TO ABOVE -// 34d COMBINING LEFT RIGHT ARROW BELOW -// 34e COMBINING UPWARDS ARROW BELOW -// 34f COMBINING GRAPHEME JOINER -// 350 COMBINING RIGHT ARROWHEAD ABOVE -// 351 COMBINING LEFT HALF RING ABOVE -// 352 COMBINING FERMATA -// 353 COMBINING X BELOW -// 354 COMBINING LEFT ARROWHEAD BELOW -// 355 COMBINING RIGHT ARROWHEAD BELOW -// 356 COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW -// 357 COMBINING RIGHT HALF RING ABOVE -// 358 COMBINING DOT ABOVE RIGHT -// 359 COMBINING ASTERISK BELOW -// 35a COMBINING DOUBLE RING BELOW -// 35b COMBINING ZIGZAG ABOVE -// 35c COMBINING DOUBLE BREVE BELOW -// 35d COMBINING DOUBLE BREVE -// 35e COMBINING DOUBLE MACRON -// 35f COMBINING DOUBLE MACRON BELOW -// 360 COMBINING DOUBLE TILDE -// 361 COMBINING DOUBLE INVERTED BREVE -// 362 COMBINING DOUBLE RIGHTWARDS ARROW BELOW -// 363 COMBINING LATIN SMALL LETTER A -// 364 COMBINING LATIN SMALL LETTER E -// 365 COMBINING LATIN SMALL LETTER I -// 366 COMBINING LATIN SMALL LETTER O -// 367 COMBINING LATIN SMALL LETTER U -// 368 COMBINING LATIN SMALL LETTER C -// 369 COMBINING LATIN SMALL LETTER D -// 36a COMBINING LATIN SMALL LETTER H -// 36b COMBINING LATIN SMALL LETTER M -// 36c COMBINING LATIN SMALL LETTER R -// 36d COMBINING LATIN SMALL LETTER T -// 36e COMBINING LATIN SMALL LETTER V -// 36f COMBINING LATIN SMALL LETTER X - { 0x346, 0x2A, 0x0, 0, 0 }, -// 370 GREEK CAPITAL LETTER HETA - { 0x370, 0x1, 0x89, 1, 0 }, -// 371 GREEK SMALL LETTER HETA - { 0x371, 0x1, 0x49, 0, -1 }, -// 372 GREEK CAPITAL LETTER ARCHAIC SAMPI - { 0x372, 0x1, 0x89, 1, 0 }, -// 373 GREEK SMALL LETTER ARCHAIC SAMPI - { 0x373, 0x1, 0x49, 0, -1 }, -// 374 GREEK NUMERAL SIGN - { 0x374, 0x1, 0x9, 0, 0 }, -// 375 GREEK LOWER NUMERAL SIGN - { 0x375, 0x1, 0x8, 0, 0 }, -// 376 GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA - { 0x376, 0x1, 0x89, 1, 0 }, -// 377 GREEK SMALL LETTER PAMPHYLIAN DIGAMMA - { 0x377, 0x1, 0x49, 0, -1 }, -// 37a GREEK YPOGEGRAMMENI - { 0x37A, 0x1, 0x9, 0, 0 }, -// 37b GREEK SMALL REVERSED LUNATE SIGMA SYMBOL -// 37c GREEK SMALL DOTTED LUNATE SIGMA SYMBOL -// 37d GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL - { 0x37B, 0x3, 0x49, 0, 130 }, -// 37e GREEK QUESTION MARK - { 0x37E, 0x1, 0x18, 0, 0 }, -// 37f GREEK CAPITAL LETTER YOT - { 0x37F, 0x1, 0x89, 116, 0 }, -// 384 GREEK TONOS -// 385 GREEK DIALYTIKA TONOS - { 0x384, 0x2, 0x8, 0, 0 }, -// 386 GREEK CAPITAL LETTER ALPHA WITH TONOS - { 0x386, 0x1, 0x89, 38, 0 }, -// 387 GREEK ANO TELEIA - { 0x387, 0x1, 0x18, 0, 0 }, -// 388 GREEK CAPITAL LETTER EPSILON WITH TONOS -// 389 GREEK CAPITAL LETTER ETA WITH TONOS -// 38a GREEK CAPITAL LETTER IOTA WITH TONOS - { 0x388, 0x3, 0x89, 37, 0 }, -// 38c GREEK CAPITAL LETTER OMICRON WITH TONOS - { 0x38C, 0x1, 0x89, 64, 0 }, -// 38e GREEK CAPITAL LETTER UPSILON WITH TONOS -// 38f GREEK CAPITAL LETTER OMEGA WITH TONOS - { 0x38E, 0x2, 0x89, 63, 0 }, -// 390 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS - { 0x390, 0x1, 0x49, 0, 0 }, -// 391 GREEK CAPITAL LETTER ALPHA -// 392 GREEK CAPITAL LETTER BETA -// 393 GREEK CAPITAL LETTER GAMMA -// 394 GREEK CAPITAL LETTER DELTA -// 395 GREEK CAPITAL LETTER EPSILON -// 396 GREEK CAPITAL LETTER ZETA -// 397 GREEK CAPITAL LETTER ETA -// 398 GREEK CAPITAL LETTER THETA -// 399 GREEK CAPITAL LETTER IOTA -// 39a GREEK CAPITAL LETTER KAPPA -// 39b GREEK CAPITAL LETTER LAMDA -// 39c GREEK CAPITAL LETTER MU -// 39d GREEK CAPITAL LETTER NU -// 39e GREEK CAPITAL LETTER XI -// 39f GREEK CAPITAL LETTER OMICRON -// 3a0 GREEK CAPITAL LETTER PI -// 3a1 GREEK CAPITAL LETTER RHO - { 0x391, 0x11, 0x89, 32, 0 }, -// 3a3 GREEK CAPITAL LETTER SIGMA -// 3a4 GREEK CAPITAL LETTER TAU -// 3a5 GREEK CAPITAL LETTER UPSILON -// 3a6 GREEK CAPITAL LETTER PHI -// 3a7 GREEK CAPITAL LETTER CHI -// 3a8 GREEK CAPITAL LETTER PSI -// 3a9 GREEK CAPITAL LETTER OMEGA -// 3aa GREEK CAPITAL LETTER IOTA WITH DIALYTIKA -// 3ab GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA - { 0x3A3, 0x9, 0x89, 32, 0 }, -// 3ac GREEK SMALL LETTER ALPHA WITH TONOS - { 0x3AC, 0x1, 0x49, 0, -38 }, -// 3ad GREEK SMALL LETTER EPSILON WITH TONOS -// 3ae GREEK SMALL LETTER ETA WITH TONOS -// 3af GREEK SMALL LETTER IOTA WITH TONOS - { 0x3AD, 0x3, 0x49, 0, -37 }, -// 3b0 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS - { 0x3B0, 0x1, 0x49, 0, 0 }, -// 3b1 GREEK SMALL LETTER ALPHA -// 3b2 GREEK SMALL LETTER BETA -// 3b3 GREEK SMALL LETTER GAMMA -// 3b4 GREEK SMALL LETTER DELTA -// 3b5 GREEK SMALL LETTER EPSILON -// 3b6 GREEK SMALL LETTER ZETA -// 3b7 GREEK SMALL LETTER ETA -// 3b8 GREEK SMALL LETTER THETA -// 3b9 GREEK SMALL LETTER IOTA -// 3ba GREEK SMALL LETTER KAPPA -// 3bb GREEK SMALL LETTER LAMDA -// 3bc GREEK SMALL LETTER MU -// 3bd GREEK SMALL LETTER NU -// 3be GREEK SMALL LETTER XI -// 3bf GREEK SMALL LETTER OMICRON -// 3c0 GREEK SMALL LETTER PI -// 3c1 GREEK SMALL LETTER RHO - { 0x3B1, 0x11, 0x49, 0, -32 }, -// 3c2 GREEK SMALL LETTER FINAL SIGMA - { 0x3C2, 0x1, 0x49, 0, -31 }, -// 3c3 GREEK SMALL LETTER SIGMA -// 3c4 GREEK SMALL LETTER TAU -// 3c5 GREEK SMALL LETTER UPSILON -// 3c6 GREEK SMALL LETTER PHI -// 3c7 GREEK SMALL LETTER CHI -// 3c8 GREEK SMALL LETTER PSI -// 3c9 GREEK SMALL LETTER OMEGA -// 3ca GREEK SMALL LETTER IOTA WITH DIALYTIKA -// 3cb GREEK SMALL LETTER UPSILON WITH DIALYTIKA - { 0x3C3, 0x9, 0x49, 0, -32 }, -// 3cc GREEK SMALL LETTER OMICRON WITH TONOS - { 0x3CC, 0x1, 0x49, 0, -64 }, -// 3cd GREEK SMALL LETTER UPSILON WITH TONOS -// 3ce GREEK SMALL LETTER OMEGA WITH TONOS - { 0x3CD, 0x2, 0x49, 0, -63 }, -// 3cf GREEK CAPITAL KAI SYMBOL - { 0x3CF, 0x1, 0x89, 8, 0 }, -// 3d0 GREEK BETA SYMBOL - { 0x3D0, 0x1, 0x49, 0, -62 }, -// 3d1 GREEK THETA SYMBOL - { 0x3D1, 0x1, 0x49, 0, -57 }, -// 3d2 GREEK UPSILON WITH HOOK SYMBOL -// 3d3 GREEK UPSILON WITH ACUTE AND HOOK SYMBOL -// 3d4 GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL - { 0x3D2, 0x3, 0x89, 0, 0 }, -// 3d5 GREEK PHI SYMBOL - { 0x3D5, 0x1, 0x49, 0, -47 }, -// 3d6 GREEK PI SYMBOL - { 0x3D6, 0x1, 0x49, 0, -54 }, -// 3d7 GREEK KAI SYMBOL - { 0x3D7, 0x1, 0x49, 0, -8 }, -// 3d8 GREEK LETTER ARCHAIC KOPPA - { 0x3D8, 0x1, 0x89, 1, 0 }, -// 3d9 GREEK SMALL LETTER ARCHAIC KOPPA - { 0x3D9, 0x1, 0x49, 0, -1 }, -// 3da GREEK LETTER STIGMA - { 0x3DA, 0x1, 0x89, 1, 0 }, -// 3db GREEK SMALL LETTER STIGMA - { 0x3DB, 0x1, 0x49, 0, -1 }, -// 3dc GREEK LETTER DIGAMMA - { 0x3DC, 0x1, 0x89, 1, 0 }, -// 3dd GREEK SMALL LETTER DIGAMMA - { 0x3DD, 0x1, 0x49, 0, -1 }, -// 3de GREEK LETTER KOPPA - { 0x3DE, 0x1, 0x89, 1, 0 }, -// 3df GREEK SMALL LETTER KOPPA - { 0x3DF, 0x1, 0x49, 0, -1 }, -// 3e0 GREEK LETTER SAMPI - { 0x3E0, 0x1, 0x89, 1, 0 }, -// 3e1 GREEK SMALL LETTER SAMPI - { 0x3E1, 0x1, 0x49, 0, -1 }, -// 3e2 COPTIC CAPITAL LETTER SHEI - { 0x3E2, 0x1, 0x89, 1, 0 }, -// 3e3 COPTIC SMALL LETTER SHEI - { 0x3E3, 0x1, 0x49, 0, -1 }, -// 3e4 COPTIC CAPITAL LETTER FEI - { 0x3E4, 0x1, 0x89, 1, 0 }, -// 3e5 COPTIC SMALL LETTER FEI - { 0x3E5, 0x1, 0x49, 0, -1 }, -// 3e6 COPTIC CAPITAL LETTER KHEI - { 0x3E6, 0x1, 0x89, 1, 0 }, -// 3e7 COPTIC SMALL LETTER KHEI - { 0x3E7, 0x1, 0x49, 0, -1 }, -// 3e8 COPTIC CAPITAL LETTER HORI - { 0x3E8, 0x1, 0x89, 1, 0 }, -// 3e9 COPTIC SMALL LETTER HORI - { 0x3E9, 0x1, 0x49, 0, -1 }, -// 3ea COPTIC CAPITAL LETTER GANGIA - { 0x3EA, 0x1, 0x89, 1, 0 }, -// 3eb COPTIC SMALL LETTER GANGIA - { 0x3EB, 0x1, 0x49, 0, -1 }, -// 3ec COPTIC CAPITAL LETTER SHIMA - { 0x3EC, 0x1, 0x89, 1, 0 }, -// 3ed COPTIC SMALL LETTER SHIMA - { 0x3ED, 0x1, 0x49, 0, -1 }, -// 3ee COPTIC CAPITAL LETTER DEI - { 0x3EE, 0x1, 0x89, 1, 0 }, -// 3ef COPTIC SMALL LETTER DEI - { 0x3EF, 0x1, 0x49, 0, -1 }, -// 3f0 GREEK KAPPA SYMBOL - { 0x3F0, 0x1, 0x49, 0, -86 }, -// 3f1 GREEK RHO SYMBOL - { 0x3F1, 0x1, 0x49, 0, -80 }, -// 3f2 GREEK LUNATE SIGMA SYMBOL - { 0x3F2, 0x1, 0x49, 0, 7 }, -// 3f3 GREEK LETTER YOT - { 0x3F3, 0x1, 0x49, 0, -116 }, -// 3f4 GREEK CAPITAL THETA SYMBOL - { 0x3F4, 0x1, 0x89, -60, 0 }, -// 3f5 GREEK LUNATE EPSILON SYMBOL - { 0x3F5, 0x1, 0x49, 0, -96 }, -// 3f6 GREEK REVERSED LUNATE EPSILON SYMBOL - { 0x3F6, 0x1, 0x8, 0, 0 }, -// 3f7 GREEK CAPITAL LETTER SHO - { 0x3F7, 0x1, 0x89, 1, 0 }, -// 3f8 GREEK SMALL LETTER SHO - { 0x3F8, 0x1, 0x49, 0, -1 }, -// 3f9 GREEK CAPITAL LUNATE SIGMA SYMBOL - { 0x3F9, 0x1, 0x89, -7, 0 }, -// 3fa GREEK CAPITAL LETTER SAN - { 0x3FA, 0x1, 0x89, 1, 0 }, -// 3fb GREEK SMALL LETTER SAN - { 0x3FB, 0x1, 0x49, 0, -1 }, -// 3fc GREEK RHO WITH STROKE SYMBOL - { 0x3FC, 0x1, 0x49, 0, 0 }, -// 3fd GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL -// 3fe GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL -// 3ff GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL - { 0x3FD, 0x3, 0x89, -130, 0 }, -// 400 CYRILLIC CAPITAL LETTER IE WITH GRAVE -// 401 CYRILLIC CAPITAL LETTER IO -// 402 CYRILLIC CAPITAL LETTER DJE -// 403 CYRILLIC CAPITAL LETTER GJE -// 404 CYRILLIC CAPITAL LETTER UKRAINIAN IE -// 405 CYRILLIC CAPITAL LETTER DZE -// 406 CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I -// 407 CYRILLIC CAPITAL LETTER YI -// 408 CYRILLIC CAPITAL LETTER JE -// 409 CYRILLIC CAPITAL LETTER LJE -// 40a CYRILLIC CAPITAL LETTER NJE -// 40b CYRILLIC CAPITAL LETTER TSHE -// 40c CYRILLIC CAPITAL LETTER KJE -// 40d CYRILLIC CAPITAL LETTER I WITH GRAVE -// 40e CYRILLIC CAPITAL LETTER SHORT U -// 40f CYRILLIC CAPITAL LETTER DZHE - { 0x400, 0x10, 0x89, 80, 0 }, -// 410 CYRILLIC CAPITAL LETTER A -// 411 CYRILLIC CAPITAL LETTER BE -// 412 CYRILLIC CAPITAL LETTER VE -// 413 CYRILLIC CAPITAL LETTER GHE -// 414 CYRILLIC CAPITAL LETTER DE -// 415 CYRILLIC CAPITAL LETTER IE -// 416 CYRILLIC CAPITAL LETTER ZHE -// 417 CYRILLIC CAPITAL LETTER ZE -// 418 CYRILLIC CAPITAL LETTER I -// 419 CYRILLIC CAPITAL LETTER SHORT I -// 41a CYRILLIC CAPITAL LETTER KA -// 41b CYRILLIC CAPITAL LETTER EL -// 41c CYRILLIC CAPITAL LETTER EM -// 41d CYRILLIC CAPITAL LETTER EN -// 41e CYRILLIC CAPITAL LETTER O -// 41f CYRILLIC CAPITAL LETTER PE -// 420 CYRILLIC CAPITAL LETTER ER -// 421 CYRILLIC CAPITAL LETTER ES -// 422 CYRILLIC CAPITAL LETTER TE -// 423 CYRILLIC CAPITAL LETTER U -// 424 CYRILLIC CAPITAL LETTER EF -// 425 CYRILLIC CAPITAL LETTER HA -// 426 CYRILLIC CAPITAL LETTER TSE -// 427 CYRILLIC CAPITAL LETTER CHE -// 428 CYRILLIC CAPITAL LETTER SHA -// 429 CYRILLIC CAPITAL LETTER SHCHA -// 42a CYRILLIC CAPITAL LETTER HARD SIGN -// 42b CYRILLIC CAPITAL LETTER YERU -// 42c CYRILLIC CAPITAL LETTER SOFT SIGN -// 42d CYRILLIC CAPITAL LETTER E -// 42e CYRILLIC CAPITAL LETTER YU -// 42f CYRILLIC CAPITAL LETTER YA - { 0x410, 0x20, 0x89, 32, 0 }, -// 430 CYRILLIC SMALL LETTER A -// 431 CYRILLIC SMALL LETTER BE -// 432 CYRILLIC SMALL LETTER VE -// 433 CYRILLIC SMALL LETTER GHE -// 434 CYRILLIC SMALL LETTER DE -// 435 CYRILLIC SMALL LETTER IE -// 436 CYRILLIC SMALL LETTER ZHE -// 437 CYRILLIC SMALL LETTER ZE -// 438 CYRILLIC SMALL LETTER I -// 439 CYRILLIC SMALL LETTER SHORT I -// 43a CYRILLIC SMALL LETTER KA -// 43b CYRILLIC SMALL LETTER EL -// 43c CYRILLIC SMALL LETTER EM -// 43d CYRILLIC SMALL LETTER EN -// 43e CYRILLIC SMALL LETTER O -// 43f CYRILLIC SMALL LETTER PE -// 440 CYRILLIC SMALL LETTER ER -// 441 CYRILLIC SMALL LETTER ES -// 442 CYRILLIC SMALL LETTER TE -// 443 CYRILLIC SMALL LETTER U -// 444 CYRILLIC SMALL LETTER EF -// 445 CYRILLIC SMALL LETTER HA -// 446 CYRILLIC SMALL LETTER TSE -// 447 CYRILLIC SMALL LETTER CHE -// 448 CYRILLIC SMALL LETTER SHA -// 449 CYRILLIC SMALL LETTER SHCHA -// 44a CYRILLIC SMALL LETTER HARD SIGN -// 44b CYRILLIC SMALL LETTER YERU -// 44c CYRILLIC SMALL LETTER SOFT SIGN -// 44d CYRILLIC SMALL LETTER E -// 44e CYRILLIC SMALL LETTER YU -// 44f CYRILLIC SMALL LETTER YA - { 0x430, 0x20, 0x49, 0, -32 }, -// 450 CYRILLIC SMALL LETTER IE WITH GRAVE -// 451 CYRILLIC SMALL LETTER IO -// 452 CYRILLIC SMALL LETTER DJE -// 453 CYRILLIC SMALL LETTER GJE -// 454 CYRILLIC SMALL LETTER UKRAINIAN IE -// 455 CYRILLIC SMALL LETTER DZE -// 456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I -// 457 CYRILLIC SMALL LETTER YI -// 458 CYRILLIC SMALL LETTER JE -// 459 CYRILLIC SMALL LETTER LJE -// 45a CYRILLIC SMALL LETTER NJE -// 45b CYRILLIC SMALL LETTER TSHE -// 45c CYRILLIC SMALL LETTER KJE -// 45d CYRILLIC SMALL LETTER I WITH GRAVE -// 45e CYRILLIC SMALL LETTER SHORT U -// 45f CYRILLIC SMALL LETTER DZHE - { 0x450, 0x10, 0x49, 0, -80 }, -// 460 CYRILLIC CAPITAL LETTER OMEGA - { 0x460, 0x1, 0x89, 1, 0 }, -// 461 CYRILLIC SMALL LETTER OMEGA - { 0x461, 0x1, 0x49, 0, -1 }, -// 462 CYRILLIC CAPITAL LETTER YAT - { 0x462, 0x1, 0x89, 1, 0 }, -// 463 CYRILLIC SMALL LETTER YAT - { 0x463, 0x1, 0x49, 0, -1 }, -// 464 CYRILLIC CAPITAL LETTER IOTIFIED E - { 0x464, 0x1, 0x89, 1, 0 }, -// 465 CYRILLIC SMALL LETTER IOTIFIED E - { 0x465, 0x1, 0x49, 0, -1 }, -// 466 CYRILLIC CAPITAL LETTER LITTLE YUS - { 0x466, 0x1, 0x89, 1, 0 }, -// 467 CYRILLIC SMALL LETTER LITTLE YUS - { 0x467, 0x1, 0x49, 0, -1 }, -// 468 CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS - { 0x468, 0x1, 0x89, 1, 0 }, -// 469 CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS - { 0x469, 0x1, 0x49, 0, -1 }, -// 46a CYRILLIC CAPITAL LETTER BIG YUS - { 0x46A, 0x1, 0x89, 1, 0 }, -// 46b CYRILLIC SMALL LETTER BIG YUS - { 0x46B, 0x1, 0x49, 0, -1 }, -// 46c CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS - { 0x46C, 0x1, 0x89, 1, 0 }, -// 46d CYRILLIC SMALL LETTER IOTIFIED BIG YUS - { 0x46D, 0x1, 0x49, 0, -1 }, -// 46e CYRILLIC CAPITAL LETTER KSI - { 0x46E, 0x1, 0x89, 1, 0 }, -// 46f CYRILLIC SMALL LETTER KSI - { 0x46F, 0x1, 0x49, 0, -1 }, -// 470 CYRILLIC CAPITAL LETTER PSI - { 0x470, 0x1, 0x89, 1, 0 }, -// 471 CYRILLIC SMALL LETTER PSI - { 0x471, 0x1, 0x49, 0, -1 }, -// 472 CYRILLIC CAPITAL LETTER FITA - { 0x472, 0x1, 0x89, 1, 0 }, -// 473 CYRILLIC SMALL LETTER FITA - { 0x473, 0x1, 0x49, 0, -1 }, -// 474 CYRILLIC CAPITAL LETTER IZHITSA - { 0x474, 0x1, 0x89, 1, 0 }, -// 475 CYRILLIC SMALL LETTER IZHITSA - { 0x475, 0x1, 0x49, 0, -1 }, -// 476 CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT - { 0x476, 0x1, 0x89, 1, 0 }, -// 477 CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT - { 0x477, 0x1, 0x49, 0, -1 }, -// 478 CYRILLIC CAPITAL LETTER UK - { 0x478, 0x1, 0x89, 1, 0 }, -// 479 CYRILLIC SMALL LETTER UK - { 0x479, 0x1, 0x49, 0, -1 }, -// 47a CYRILLIC CAPITAL LETTER ROUND OMEGA - { 0x47A, 0x1, 0x89, 1, 0 }, -// 47b CYRILLIC SMALL LETTER ROUND OMEGA - { 0x47B, 0x1, 0x49, 0, -1 }, -// 47c CYRILLIC CAPITAL LETTER OMEGA WITH TITLO - { 0x47C, 0x1, 0x89, 1, 0 }, -// 47d CYRILLIC SMALL LETTER OMEGA WITH TITLO - { 0x47D, 0x1, 0x49, 0, -1 }, -// 47e CYRILLIC CAPITAL LETTER OT - { 0x47E, 0x1, 0x89, 1, 0 }, -// 47f CYRILLIC SMALL LETTER OT - { 0x47F, 0x1, 0x49, 0, -1 }, -// 480 CYRILLIC CAPITAL LETTER KOPPA - { 0x480, 0x1, 0x89, 1, 0 }, -// 481 CYRILLIC SMALL LETTER KOPPA - { 0x481, 0x1, 0x49, 0, -1 }, -// 482 CYRILLIC THOUSANDS SIGN - { 0x482, 0x1, 0x8, 0, 0 }, -// 483 COMBINING CYRILLIC TITLO -// 484 COMBINING CYRILLIC PALATALIZATION -// 485 COMBINING CYRILLIC DASIA PNEUMATA -// 486 COMBINING CYRILLIC PSILI PNEUMATA -// 487 COMBINING CYRILLIC POKRYTIE -// 488 COMBINING CYRILLIC HUNDRED THOUSANDS SIGN -// 489 COMBINING CYRILLIC MILLIONS SIGN - { 0x483, 0x7, 0x0, 0, 0 }, -// 48a CYRILLIC CAPITAL LETTER SHORT I WITH TAIL - { 0x48A, 0x1, 0x89, 1, 0 }, -// 48b CYRILLIC SMALL LETTER SHORT I WITH TAIL - { 0x48B, 0x1, 0x49, 0, -1 }, -// 48c CYRILLIC CAPITAL LETTER SEMISOFT SIGN - { 0x48C, 0x1, 0x89, 1, 0 }, -// 48d CYRILLIC SMALL LETTER SEMISOFT SIGN - { 0x48D, 0x1, 0x49, 0, -1 }, -// 48e CYRILLIC CAPITAL LETTER ER WITH TICK - { 0x48E, 0x1, 0x89, 1, 0 }, -// 48f CYRILLIC SMALL LETTER ER WITH TICK - { 0x48F, 0x1, 0x49, 0, -1 }, -// 490 CYRILLIC CAPITAL LETTER GHE WITH UPTURN - { 0x490, 0x1, 0x89, 1, 0 }, -// 491 CYRILLIC SMALL LETTER GHE WITH UPTURN - { 0x491, 0x1, 0x49, 0, -1 }, -// 492 CYRILLIC CAPITAL LETTER GHE WITH STROKE - { 0x492, 0x1, 0x89, 1, 0 }, -// 493 CYRILLIC SMALL LETTER GHE WITH STROKE - { 0x493, 0x1, 0x49, 0, -1 }, -// 494 CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK - { 0x494, 0x1, 0x89, 1, 0 }, -// 495 CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK - { 0x495, 0x1, 0x49, 0, -1 }, -// 496 CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER - { 0x496, 0x1, 0x89, 1, 0 }, -// 497 CYRILLIC SMALL LETTER ZHE WITH DESCENDER - { 0x497, 0x1, 0x49, 0, -1 }, -// 498 CYRILLIC CAPITAL LETTER ZE WITH DESCENDER - { 0x498, 0x1, 0x89, 1, 0 }, -// 499 CYRILLIC SMALL LETTER ZE WITH DESCENDER - { 0x499, 0x1, 0x49, 0, -1 }, -// 49a CYRILLIC CAPITAL LETTER KA WITH DESCENDER - { 0x49A, 0x1, 0x89, 1, 0 }, -// 49b CYRILLIC SMALL LETTER KA WITH DESCENDER - { 0x49B, 0x1, 0x49, 0, -1 }, -// 49c CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE - { 0x49C, 0x1, 0x89, 1, 0 }, -// 49d CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE - { 0x49D, 0x1, 0x49, 0, -1 }, -// 49e CYRILLIC CAPITAL LETTER KA WITH STROKE - { 0x49E, 0x1, 0x89, 1, 0 }, -// 49f CYRILLIC SMALL LETTER KA WITH STROKE - { 0x49F, 0x1, 0x49, 0, -1 }, -// 4a0 CYRILLIC CAPITAL LETTER BASHKIR KA - { 0x4A0, 0x1, 0x89, 1, 0 }, -// 4a1 CYRILLIC SMALL LETTER BASHKIR KA - { 0x4A1, 0x1, 0x49, 0, -1 }, -// 4a2 CYRILLIC CAPITAL LETTER EN WITH DESCENDER - { 0x4A2, 0x1, 0x89, 1, 0 }, -// 4a3 CYRILLIC SMALL LETTER EN WITH DESCENDER - { 0x4A3, 0x1, 0x49, 0, -1 }, -// 4a4 CYRILLIC CAPITAL LIGATURE EN GHE - { 0x4A4, 0x1, 0x89, 1, 0 }, -// 4a5 CYRILLIC SMALL LIGATURE EN GHE - { 0x4A5, 0x1, 0x49, 0, -1 }, -// 4a6 CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK - { 0x4A6, 0x1, 0x89, 1, 0 }, -// 4a7 CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK - { 0x4A7, 0x1, 0x49, 0, -1 }, -// 4a8 CYRILLIC CAPITAL LETTER ABKHASIAN HA - { 0x4A8, 0x1, 0x89, 1, 0 }, -// 4a9 CYRILLIC SMALL LETTER ABKHASIAN HA - { 0x4A9, 0x1, 0x49, 0, -1 }, -// 4aa CYRILLIC CAPITAL LETTER ES WITH DESCENDER - { 0x4AA, 0x1, 0x89, 1, 0 }, -// 4ab CYRILLIC SMALL LETTER ES WITH DESCENDER - { 0x4AB, 0x1, 0x49, 0, -1 }, -// 4ac CYRILLIC CAPITAL LETTER TE WITH DESCENDER - { 0x4AC, 0x1, 0x89, 1, 0 }, -// 4ad CYRILLIC SMALL LETTER TE WITH DESCENDER - { 0x4AD, 0x1, 0x49, 0, -1 }, -// 4ae CYRILLIC CAPITAL LETTER STRAIGHT U - { 0x4AE, 0x1, 0x89, 1, 0 }, -// 4af CYRILLIC SMALL LETTER STRAIGHT U - { 0x4AF, 0x1, 0x49, 0, -1 }, -// 4b0 CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE - { 0x4B0, 0x1, 0x89, 1, 0 }, -// 4b1 CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE - { 0x4B1, 0x1, 0x49, 0, -1 }, -// 4b2 CYRILLIC CAPITAL LETTER HA WITH DESCENDER - { 0x4B2, 0x1, 0x89, 1, 0 }, -// 4b3 CYRILLIC SMALL LETTER HA WITH DESCENDER - { 0x4B3, 0x1, 0x49, 0, -1 }, -// 4b4 CYRILLIC CAPITAL LIGATURE TE TSE - { 0x4B4, 0x1, 0x89, 1, 0 }, -// 4b5 CYRILLIC SMALL LIGATURE TE TSE - { 0x4B5, 0x1, 0x49, 0, -1 }, -// 4b6 CYRILLIC CAPITAL LETTER CHE WITH DESCENDER - { 0x4B6, 0x1, 0x89, 1, 0 }, -// 4b7 CYRILLIC SMALL LETTER CHE WITH DESCENDER - { 0x4B7, 0x1, 0x49, 0, -1 }, -// 4b8 CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE - { 0x4B8, 0x1, 0x89, 1, 0 }, -// 4b9 CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE - { 0x4B9, 0x1, 0x49, 0, -1 }, -// 4ba CYRILLIC CAPITAL LETTER SHHA - { 0x4BA, 0x1, 0x89, 1, 0 }, -// 4bb CYRILLIC SMALL LETTER SHHA - { 0x4BB, 0x1, 0x49, 0, -1 }, -// 4bc CYRILLIC CAPITAL LETTER ABKHASIAN CHE - { 0x4BC, 0x1, 0x89, 1, 0 }, -// 4bd CYRILLIC SMALL LETTER ABKHASIAN CHE - { 0x4BD, 0x1, 0x49, 0, -1 }, -// 4be CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER - { 0x4BE, 0x1, 0x89, 1, 0 }, -// 4bf CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER - { 0x4BF, 0x1, 0x49, 0, -1 }, -// 4c0 CYRILLIC LETTER PALOCHKA - { 0x4C0, 0x1, 0x89, 15, 0 }, -// 4c1 CYRILLIC CAPITAL LETTER ZHE WITH BREVE - { 0x4C1, 0x1, 0x89, 1, 0 }, -// 4c2 CYRILLIC SMALL LETTER ZHE WITH BREVE - { 0x4C2, 0x1, 0x49, 0, -1 }, -// 4c3 CYRILLIC CAPITAL LETTER KA WITH HOOK - { 0x4C3, 0x1, 0x89, 1, 0 }, -// 4c4 CYRILLIC SMALL LETTER KA WITH HOOK - { 0x4C4, 0x1, 0x49, 0, -1 }, -// 4c5 CYRILLIC CAPITAL LETTER EL WITH TAIL - { 0x4C5, 0x1, 0x89, 1, 0 }, -// 4c6 CYRILLIC SMALL LETTER EL WITH TAIL - { 0x4C6, 0x1, 0x49, 0, -1 }, -// 4c7 CYRILLIC CAPITAL LETTER EN WITH HOOK - { 0x4C7, 0x1, 0x89, 1, 0 }, -// 4c8 CYRILLIC SMALL LETTER EN WITH HOOK - { 0x4C8, 0x1, 0x49, 0, -1 }, -// 4c9 CYRILLIC CAPITAL LETTER EN WITH TAIL - { 0x4C9, 0x1, 0x89, 1, 0 }, -// 4ca CYRILLIC SMALL LETTER EN WITH TAIL - { 0x4CA, 0x1, 0x49, 0, -1 }, -// 4cb CYRILLIC CAPITAL LETTER KHAKASSIAN CHE - { 0x4CB, 0x1, 0x89, 1, 0 }, -// 4cc CYRILLIC SMALL LETTER KHAKASSIAN CHE - { 0x4CC, 0x1, 0x49, 0, -1 }, -// 4cd CYRILLIC CAPITAL LETTER EM WITH TAIL - { 0x4CD, 0x1, 0x89, 1, 0 }, -// 4ce CYRILLIC SMALL LETTER EM WITH TAIL - { 0x4CE, 0x1, 0x49, 0, -1 }, -// 4cf CYRILLIC SMALL LETTER PALOCHKA - { 0x4CF, 0x1, 0x49, 0, -15 }, -// 4d0 CYRILLIC CAPITAL LETTER A WITH BREVE - { 0x4D0, 0x1, 0x89, 1, 0 }, -// 4d1 CYRILLIC SMALL LETTER A WITH BREVE - { 0x4D1, 0x1, 0x49, 0, -1 }, -// 4d2 CYRILLIC CAPITAL LETTER A WITH DIAERESIS - { 0x4D2, 0x1, 0x89, 1, 0 }, -// 4d3 CYRILLIC SMALL LETTER A WITH DIAERESIS - { 0x4D3, 0x1, 0x49, 0, -1 }, -// 4d4 CYRILLIC CAPITAL LIGATURE A IE - { 0x4D4, 0x1, 0x89, 1, 0 }, -// 4d5 CYRILLIC SMALL LIGATURE A IE - { 0x4D5, 0x1, 0x49, 0, -1 }, -// 4d6 CYRILLIC CAPITAL LETTER IE WITH BREVE - { 0x4D6, 0x1, 0x89, 1, 0 }, -// 4d7 CYRILLIC SMALL LETTER IE WITH BREVE - { 0x4D7, 0x1, 0x49, 0, -1 }, -// 4d8 CYRILLIC CAPITAL LETTER SCHWA - { 0x4D8, 0x1, 0x89, 1, 0 }, -// 4d9 CYRILLIC SMALL LETTER SCHWA - { 0x4D9, 0x1, 0x49, 0, -1 }, -// 4da CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS - { 0x4DA, 0x1, 0x89, 1, 0 }, -// 4db CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS - { 0x4DB, 0x1, 0x49, 0, -1 }, -// 4dc CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS - { 0x4DC, 0x1, 0x89, 1, 0 }, -// 4dd CYRILLIC SMALL LETTER ZHE WITH DIAERESIS - { 0x4DD, 0x1, 0x49, 0, -1 }, -// 4de CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS - { 0x4DE, 0x1, 0x89, 1, 0 }, -// 4df CYRILLIC SMALL LETTER ZE WITH DIAERESIS - { 0x4DF, 0x1, 0x49, 0, -1 }, -// 4e0 CYRILLIC CAPITAL LETTER ABKHASIAN DZE - { 0x4E0, 0x1, 0x89, 1, 0 }, -// 4e1 CYRILLIC SMALL LETTER ABKHASIAN DZE - { 0x4E1, 0x1, 0x49, 0, -1 }, -// 4e2 CYRILLIC CAPITAL LETTER I WITH MACRON - { 0x4E2, 0x1, 0x89, 1, 0 }, -// 4e3 CYRILLIC SMALL LETTER I WITH MACRON - { 0x4E3, 0x1, 0x49, 0, -1 }, -// 4e4 CYRILLIC CAPITAL LETTER I WITH DIAERESIS - { 0x4E4, 0x1, 0x89, 1, 0 }, -// 4e5 CYRILLIC SMALL LETTER I WITH DIAERESIS - { 0x4E5, 0x1, 0x49, 0, -1 }, -// 4e6 CYRILLIC CAPITAL LETTER O WITH DIAERESIS - { 0x4E6, 0x1, 0x89, 1, 0 }, -// 4e7 CYRILLIC SMALL LETTER O WITH DIAERESIS - { 0x4E7, 0x1, 0x49, 0, -1 }, -// 4e8 CYRILLIC CAPITAL LETTER BARRED O - { 0x4E8, 0x1, 0x89, 1, 0 }, -// 4e9 CYRILLIC SMALL LETTER BARRED O - { 0x4E9, 0x1, 0x49, 0, -1 }, -// 4ea CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS - { 0x4EA, 0x1, 0x89, 1, 0 }, -// 4eb CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS - { 0x4EB, 0x1, 0x49, 0, -1 }, -// 4ec CYRILLIC CAPITAL LETTER E WITH DIAERESIS - { 0x4EC, 0x1, 0x89, 1, 0 }, -// 4ed CYRILLIC SMALL LETTER E WITH DIAERESIS - { 0x4ED, 0x1, 0x49, 0, -1 }, -// 4ee CYRILLIC CAPITAL LETTER U WITH MACRON - { 0x4EE, 0x1, 0x89, 1, 0 }, -// 4ef CYRILLIC SMALL LETTER U WITH MACRON - { 0x4EF, 0x1, 0x49, 0, -1 }, -// 4f0 CYRILLIC CAPITAL LETTER U WITH DIAERESIS - { 0x4F0, 0x1, 0x89, 1, 0 }, -// 4f1 CYRILLIC SMALL LETTER U WITH DIAERESIS - { 0x4F1, 0x1, 0x49, 0, -1 }, -// 4f2 CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE - { 0x4F2, 0x1, 0x89, 1, 0 }, -// 4f3 CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE - { 0x4F3, 0x1, 0x49, 0, -1 }, -// 4f4 CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS - { 0x4F4, 0x1, 0x89, 1, 0 }, -// 4f5 CYRILLIC SMALL LETTER CHE WITH DIAERESIS - { 0x4F5, 0x1, 0x49, 0, -1 }, -// 4f6 CYRILLIC CAPITAL LETTER GHE WITH DESCENDER - { 0x4F6, 0x1, 0x89, 1, 0 }, -// 4f7 CYRILLIC SMALL LETTER GHE WITH DESCENDER - { 0x4F7, 0x1, 0x49, 0, -1 }, -// 4f8 CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS - { 0x4F8, 0x1, 0x89, 1, 0 }, -// 4f9 CYRILLIC SMALL LETTER YERU WITH DIAERESIS - { 0x4F9, 0x1, 0x49, 0, -1 }, -// 4fa CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK - { 0x4FA, 0x1, 0x89, 1, 0 }, -// 4fb CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK - { 0x4FB, 0x1, 0x49, 0, -1 }, -// 4fc CYRILLIC CAPITAL LETTER HA WITH HOOK - { 0x4FC, 0x1, 0x89, 1, 0 }, -// 4fd CYRILLIC SMALL LETTER HA WITH HOOK - { 0x4FD, 0x1, 0x49, 0, -1 }, -// 4fe CYRILLIC CAPITAL LETTER HA WITH STROKE - { 0x4FE, 0x1, 0x89, 1, 0 }, -// 4ff CYRILLIC SMALL LETTER HA WITH STROKE - { 0x4FF, 0x1, 0x49, 0, -1 }, -// 500 CYRILLIC CAPITAL LETTER KOMI DE - { 0x500, 0x1, 0x89, 1, 0 }, -// 501 CYRILLIC SMALL LETTER KOMI DE - { 0x501, 0x1, 0x49, 0, -1 }, -// 502 CYRILLIC CAPITAL LETTER KOMI DJE - { 0x502, 0x1, 0x89, 1, 0 }, -// 503 CYRILLIC SMALL LETTER KOMI DJE - { 0x503, 0x1, 0x49, 0, -1 }, -// 504 CYRILLIC CAPITAL LETTER KOMI ZJE - { 0x504, 0x1, 0x89, 1, 0 }, -// 505 CYRILLIC SMALL LETTER KOMI ZJE - { 0x505, 0x1, 0x49, 0, -1 }, -// 506 CYRILLIC CAPITAL LETTER KOMI DZJE - { 0x506, 0x1, 0x89, 1, 0 }, -// 507 CYRILLIC SMALL LETTER KOMI DZJE - { 0x507, 0x1, 0x49, 0, -1 }, -// 508 CYRILLIC CAPITAL LETTER KOMI LJE - { 0x508, 0x1, 0x89, 1, 0 }, -// 509 CYRILLIC SMALL LETTER KOMI LJE - { 0x509, 0x1, 0x49, 0, -1 }, -// 50a CYRILLIC CAPITAL LETTER KOMI NJE - { 0x50A, 0x1, 0x89, 1, 0 }, -// 50b CYRILLIC SMALL LETTER KOMI NJE - { 0x50B, 0x1, 0x49, 0, -1 }, -// 50c CYRILLIC CAPITAL LETTER KOMI SJE - { 0x50C, 0x1, 0x89, 1, 0 }, -// 50d CYRILLIC SMALL LETTER KOMI SJE - { 0x50D, 0x1, 0x49, 0, -1 }, -// 50e CYRILLIC CAPITAL LETTER KOMI TJE - { 0x50E, 0x1, 0x89, 1, 0 }, -// 50f CYRILLIC SMALL LETTER KOMI TJE - { 0x50F, 0x1, 0x49, 0, -1 }, -// 510 CYRILLIC CAPITAL LETTER REVERSED ZE - { 0x510, 0x1, 0x89, 1, 0 }, -// 511 CYRILLIC SMALL LETTER REVERSED ZE - { 0x511, 0x1, 0x49, 0, -1 }, -// 512 CYRILLIC CAPITAL LETTER EL WITH HOOK - { 0x512, 0x1, 0x89, 1, 0 }, -// 513 CYRILLIC SMALL LETTER EL WITH HOOK - { 0x513, 0x1, 0x49, 0, -1 }, -// 514 CYRILLIC CAPITAL LETTER LHA - { 0x514, 0x1, 0x89, 1, 0 }, -// 515 CYRILLIC SMALL LETTER LHA - { 0x515, 0x1, 0x49, 0, -1 }, -// 516 CYRILLIC CAPITAL LETTER RHA - { 0x516, 0x1, 0x89, 1, 0 }, -// 517 CYRILLIC SMALL LETTER RHA - { 0x517, 0x1, 0x49, 0, -1 }, -// 518 CYRILLIC CAPITAL LETTER YAE - { 0x518, 0x1, 0x89, 1, 0 }, -// 519 CYRILLIC SMALL LETTER YAE - { 0x519, 0x1, 0x49, 0, -1 }, -// 51a CYRILLIC CAPITAL LETTER QA - { 0x51A, 0x1, 0x89, 1, 0 }, -// 51b CYRILLIC SMALL LETTER QA - { 0x51B, 0x1, 0x49, 0, -1 }, -// 51c CYRILLIC CAPITAL LETTER WE - { 0x51C, 0x1, 0x89, 1, 0 }, -// 51d CYRILLIC SMALL LETTER WE - { 0x51D, 0x1, 0x49, 0, -1 }, -// 51e CYRILLIC CAPITAL LETTER ALEUT KA - { 0x51E, 0x1, 0x89, 1, 0 }, -// 51f CYRILLIC SMALL LETTER ALEUT KA - { 0x51F, 0x1, 0x49, 0, -1 }, -// 520 CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK - { 0x520, 0x1, 0x89, 1, 0 }, -// 521 CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK - { 0x521, 0x1, 0x49, 0, -1 }, -// 522 CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK - { 0x522, 0x1, 0x89, 1, 0 }, -// 523 CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK - { 0x523, 0x1, 0x49, 0, -1 }, -// 524 CYRILLIC CAPITAL LETTER PE WITH DESCENDER - { 0x524, 0x1, 0x89, 1, 0 }, -// 525 CYRILLIC SMALL LETTER PE WITH DESCENDER - { 0x525, 0x1, 0x49, 0, -1 }, -// 526 CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER - { 0x526, 0x1, 0x89, 1, 0 }, -// 527 CYRILLIC SMALL LETTER SHHA WITH DESCENDER - { 0x527, 0x1, 0x49, 0, -1 }, -// 528 CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK - { 0x528, 0x1, 0x89, 1, 0 }, -// 529 CYRILLIC SMALL LETTER EN WITH LEFT HOOK - { 0x529, 0x1, 0x49, 0, -1 }, -// 52a CYRILLIC CAPITAL LETTER DZZHE - { 0x52A, 0x1, 0x89, 1, 0 }, -// 52b CYRILLIC SMALL LETTER DZZHE - { 0x52B, 0x1, 0x49, 0, -1 }, -// 52c CYRILLIC CAPITAL LETTER DCHE - { 0x52C, 0x1, 0x89, 1, 0 }, -// 52d CYRILLIC SMALL LETTER DCHE - { 0x52D, 0x1, 0x49, 0, -1 }, -// 52e CYRILLIC CAPITAL LETTER EL WITH DESCENDER - { 0x52E, 0x1, 0x89, 1, 0 }, -// 52f CYRILLIC SMALL LETTER EL WITH DESCENDER - { 0x52F, 0x1, 0x49, 0, -1 }, -// 531 ARMENIAN CAPITAL LETTER AYB -// 532 ARMENIAN CAPITAL LETTER BEN -// 533 ARMENIAN CAPITAL LETTER GIM -// 534 ARMENIAN CAPITAL LETTER DA -// 535 ARMENIAN CAPITAL LETTER ECH -// 536 ARMENIAN CAPITAL LETTER ZA -// 537 ARMENIAN CAPITAL LETTER EH -// 538 ARMENIAN CAPITAL LETTER ET -// 539 ARMENIAN CAPITAL LETTER TO -// 53a ARMENIAN CAPITAL LETTER ZHE -// 53b ARMENIAN CAPITAL LETTER INI -// 53c ARMENIAN CAPITAL LETTER LIWN -// 53d ARMENIAN CAPITAL LETTER XEH -// 53e ARMENIAN CAPITAL LETTER CA -// 53f ARMENIAN CAPITAL LETTER KEN -// 540 ARMENIAN CAPITAL LETTER HO -// 541 ARMENIAN CAPITAL LETTER JA -// 542 ARMENIAN CAPITAL LETTER GHAD -// 543 ARMENIAN CAPITAL LETTER CHEH -// 544 ARMENIAN CAPITAL LETTER MEN -// 545 ARMENIAN CAPITAL LETTER YI -// 546 ARMENIAN CAPITAL LETTER NOW -// 547 ARMENIAN CAPITAL LETTER SHA -// 548 ARMENIAN CAPITAL LETTER VO -// 549 ARMENIAN CAPITAL LETTER CHA -// 54a ARMENIAN CAPITAL LETTER PEH -// 54b ARMENIAN CAPITAL LETTER JHEH -// 54c ARMENIAN CAPITAL LETTER RA -// 54d ARMENIAN CAPITAL LETTER SEH -// 54e ARMENIAN CAPITAL LETTER VEW -// 54f ARMENIAN CAPITAL LETTER TIWN -// 550 ARMENIAN CAPITAL LETTER REH -// 551 ARMENIAN CAPITAL LETTER CO -// 552 ARMENIAN CAPITAL LETTER YIWN -// 553 ARMENIAN CAPITAL LETTER PIWR -// 554 ARMENIAN CAPITAL LETTER KEH -// 555 ARMENIAN CAPITAL LETTER OH -// 556 ARMENIAN CAPITAL LETTER FEH - { 0x531, 0x26, 0x89, 48, 0 }, -// 559 ARMENIAN MODIFIER LETTER LEFT HALF RING - { 0x559, 0x1, 0x9, 0, 0 }, -// 55a ARMENIAN APOSTROPHE -// 55b ARMENIAN EMPHASIS MARK -// 55c ARMENIAN EXCLAMATION MARK -// 55d ARMENIAN COMMA -// 55e ARMENIAN QUESTION MARK -// 55f ARMENIAN ABBREVIATION MARK - { 0x55A, 0x6, 0x18, 0, 0 }, -// 561 ARMENIAN SMALL LETTER AYB -// 562 ARMENIAN SMALL LETTER BEN -// 563 ARMENIAN SMALL LETTER GIM -// 564 ARMENIAN SMALL LETTER DA -// 565 ARMENIAN SMALL LETTER ECH -// 566 ARMENIAN SMALL LETTER ZA -// 567 ARMENIAN SMALL LETTER EH -// 568 ARMENIAN SMALL LETTER ET -// 569 ARMENIAN SMALL LETTER TO -// 56a ARMENIAN SMALL LETTER ZHE -// 56b ARMENIAN SMALL LETTER INI -// 56c ARMENIAN SMALL LETTER LIWN -// 56d ARMENIAN SMALL LETTER XEH -// 56e ARMENIAN SMALL LETTER CA -// 56f ARMENIAN SMALL LETTER KEN -// 570 ARMENIAN SMALL LETTER HO -// 571 ARMENIAN SMALL LETTER JA -// 572 ARMENIAN SMALL LETTER GHAD -// 573 ARMENIAN SMALL LETTER CHEH -// 574 ARMENIAN SMALL LETTER MEN -// 575 ARMENIAN SMALL LETTER YI -// 576 ARMENIAN SMALL LETTER NOW -// 577 ARMENIAN SMALL LETTER SHA -// 578 ARMENIAN SMALL LETTER VO -// 579 ARMENIAN SMALL LETTER CHA -// 57a ARMENIAN SMALL LETTER PEH -// 57b ARMENIAN SMALL LETTER JHEH -// 57c ARMENIAN SMALL LETTER RA -// 57d ARMENIAN SMALL LETTER SEH -// 57e ARMENIAN SMALL LETTER VEW -// 57f ARMENIAN SMALL LETTER TIWN -// 580 ARMENIAN SMALL LETTER REH -// 581 ARMENIAN SMALL LETTER CO -// 582 ARMENIAN SMALL LETTER YIWN -// 583 ARMENIAN SMALL LETTER PIWR -// 584 ARMENIAN SMALL LETTER KEH -// 585 ARMENIAN SMALL LETTER OH -// 586 ARMENIAN SMALL LETTER FEH - { 0x561, 0x26, 0x49, 0, -48 }, -// 587 ARMENIAN SMALL LIGATURE ECH YIWN - { 0x587, 0x1, 0x49, 0, 0 }, -// 589 ARMENIAN FULL STOP -// 58a ARMENIAN HYPHEN - { 0x589, 0x2, 0x18, 0, 0 }, -// 58d RIGHT-FACING ARMENIAN ETERNITY SIGN -// 58e LEFT-FACING ARMENIAN ETERNITY SIGN -// 58f ARMENIAN DRAM SIGN - { 0x58D, 0x3, 0x8, 0, 0 }, -// 591 HEBREW ACCENT ETNAHTA -// 592 HEBREW ACCENT SEGOL -// 593 HEBREW ACCENT SHALSHELET -// 594 HEBREW ACCENT ZAQEF QATAN -// 595 HEBREW ACCENT ZAQEF GADOL -// 596 HEBREW ACCENT TIPEHA -// 597 HEBREW ACCENT REVIA -// 598 HEBREW ACCENT ZARQA -// 599 HEBREW ACCENT PASHTA -// 59a HEBREW ACCENT YETIV -// 59b HEBREW ACCENT TEVIR -// 59c HEBREW ACCENT GERESH -// 59d HEBREW ACCENT GERESH MUQDAM -// 59e HEBREW ACCENT GERSHAYIM -// 59f HEBREW ACCENT QARNEY PARA -// 5a0 HEBREW ACCENT TELISHA GEDOLA -// 5a1 HEBREW ACCENT PAZER -// 5a2 HEBREW ACCENT ATNAH HAFUKH -// 5a3 HEBREW ACCENT MUNAH -// 5a4 HEBREW ACCENT MAHAPAKH -// 5a5 HEBREW ACCENT MERKHA -// 5a6 HEBREW ACCENT MERKHA KEFULA -// 5a7 HEBREW ACCENT DARGA -// 5a8 HEBREW ACCENT QADMA -// 5a9 HEBREW ACCENT TELISHA QETANA -// 5aa HEBREW ACCENT YERAH BEN YOMO -// 5ab HEBREW ACCENT OLE -// 5ac HEBREW ACCENT ILUY -// 5ad HEBREW ACCENT DEHI -// 5ae HEBREW ACCENT ZINOR -// 5af HEBREW MARK MASORA CIRCLE -// 5b0 HEBREW POINT SHEVA -// 5b1 HEBREW POINT HATAF SEGOL -// 5b2 HEBREW POINT HATAF PATAH -// 5b3 HEBREW POINT HATAF QAMATS -// 5b4 HEBREW POINT HIRIQ -// 5b5 HEBREW POINT TSERE -// 5b6 HEBREW POINT SEGOL -// 5b7 HEBREW POINT PATAH -// 5b8 HEBREW POINT QAMATS -// 5b9 HEBREW POINT HOLAM -// 5ba HEBREW POINT HOLAM HASER FOR VAV -// 5bb HEBREW POINT QUBUTS -// 5bc HEBREW POINT DAGESH OR MAPIQ -// 5bd HEBREW POINT METEG - { 0x591, 0x2D, 0x0, 0, 0 }, -// 5be HEBREW PUNCTUATION MAQAF - { 0x5BE, 0x1, 0x18, 0, 0 }, -// 5bf HEBREW POINT RAFE - { 0x5BF, 0x1, 0x0, 0, 0 }, -// 5c0 HEBREW PUNCTUATION PASEQ - { 0x5C0, 0x1, 0x18, 0, 0 }, -// 5c1 HEBREW POINT SHIN DOT -// 5c2 HEBREW POINT SIN DOT - { 0x5C1, 0x2, 0x0, 0, 0 }, -// 5c3 HEBREW PUNCTUATION SOF PASUQ - { 0x5C3, 0x1, 0x18, 0, 0 }, -// 5c4 HEBREW MARK UPPER DOT -// 5c5 HEBREW MARK LOWER DOT - { 0x5C4, 0x2, 0x0, 0, 0 }, -// 5c6 HEBREW PUNCTUATION NUN HAFUKHA - { 0x5C6, 0x1, 0x18, 0, 0 }, -// 5c7 HEBREW POINT QAMATS QATAN - { 0x5C7, 0x1, 0x0, 0, 0 }, -// 5d0 HEBREW LETTER ALEF -// 5d1 HEBREW LETTER BET -// 5d2 HEBREW LETTER GIMEL -// 5d3 HEBREW LETTER DALET -// 5d4 HEBREW LETTER HE -// 5d5 HEBREW LETTER VAV -// 5d6 HEBREW LETTER ZAYIN -// 5d7 HEBREW LETTER HET -// 5d8 HEBREW LETTER TET -// 5d9 HEBREW LETTER YOD -// 5da HEBREW LETTER FINAL KAF -// 5db HEBREW LETTER KAF -// 5dc HEBREW LETTER LAMED -// 5dd HEBREW LETTER FINAL MEM -// 5de HEBREW LETTER MEM -// 5df HEBREW LETTER FINAL NUN -// 5e0 HEBREW LETTER NUN -// 5e1 HEBREW LETTER SAMEKH -// 5e2 HEBREW LETTER AYIN -// 5e3 HEBREW LETTER FINAL PE -// 5e4 HEBREW LETTER PE -// 5e5 HEBREW LETTER FINAL TSADI -// 5e6 HEBREW LETTER TSADI -// 5e7 HEBREW LETTER QOF -// 5e8 HEBREW LETTER RESH -// 5e9 HEBREW LETTER SHIN -// 5ea HEBREW LETTER TAV - { 0x5D0, 0x1B, 0x9, 0, 0 }, -// 5f0 HEBREW LIGATURE YIDDISH DOUBLE VAV -// 5f1 HEBREW LIGATURE YIDDISH VAV YOD -// 5f2 HEBREW LIGATURE YIDDISH DOUBLE YOD - { 0x5F0, 0x3, 0x9, 0, 0 }, -// 5f3 HEBREW PUNCTUATION GERESH -// 5f4 HEBREW PUNCTUATION GERSHAYIM - { 0x5F3, 0x2, 0x18, 0, 0 }, -// 600 ARABIC NUMBER SIGN -// 601 ARABIC SIGN SANAH -// 602 ARABIC FOOTNOTE MARKER -// 603 ARABIC SIGN SAFHA -// 604 ARABIC SIGN SAMVAT -// 605 ARABIC NUMBER MARK ABOVE - { 0x600, 0x6, 0x0, 0, 0 }, -// 606 ARABIC-INDIC CUBE ROOT -// 607 ARABIC-INDIC FOURTH ROOT -// 608 ARABIC RAY - { 0x606, 0x3, 0x8, 0, 0 }, -// 609 ARABIC-INDIC PER MILLE SIGN -// 60a ARABIC-INDIC PER TEN THOUSAND SIGN - { 0x609, 0x2, 0x18, 0, 0 }, -// 60b AFGHANI SIGN - { 0x60B, 0x1, 0x8, 0, 0 }, -// 60c ARABIC COMMA -// 60d ARABIC DATE SEPARATOR - { 0x60C, 0x2, 0x18, 0, 0 }, -// 60e ARABIC POETIC VERSE SIGN -// 60f ARABIC SIGN MISRA - { 0x60E, 0x2, 0x8, 0, 0 }, -// 610 ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM -// 611 ARABIC SIGN ALAYHE ASSALLAM -// 612 ARABIC SIGN RAHMATULLAH ALAYHE -// 613 ARABIC SIGN RADI ALLAHOU ANHU -// 614 ARABIC SIGN TAKHALLUS -// 615 ARABIC SMALL HIGH TAH -// 616 ARABIC SMALL HIGH LIGATURE ALEF WITH LAM WITH YEH -// 617 ARABIC SMALL HIGH ZAIN -// 618 ARABIC SMALL FATHA -// 619 ARABIC SMALL DAMMA -// 61a ARABIC SMALL KASRA - { 0x610, 0xB, 0x0, 0, 0 }, -// 61b ARABIC SEMICOLON - { 0x61B, 0x1, 0x18, 0, 0 }, -// 61c ARABIC LETTER MARK - { 0x61C, 0x1, 0x0, 0, 0 }, -// 61e ARABIC TRIPLE DOT PUNCTUATION MARK -// 61f ARABIC QUESTION MARK - { 0x61E, 0x2, 0x18, 0, 0 }, -// 620 ARABIC LETTER KASHMIRI YEH -// 621 ARABIC LETTER HAMZA -// 622 ARABIC LETTER ALEF WITH MADDA ABOVE -// 623 ARABIC LETTER ALEF WITH HAMZA ABOVE -// 624 ARABIC LETTER WAW WITH HAMZA ABOVE -// 625 ARABIC LETTER ALEF WITH HAMZA BELOW -// 626 ARABIC LETTER YEH WITH HAMZA ABOVE -// 627 ARABIC LETTER ALEF -// 628 ARABIC LETTER BEH -// 629 ARABIC LETTER TEH MARBUTA -// 62a ARABIC LETTER TEH -// 62b ARABIC LETTER THEH -// 62c ARABIC LETTER JEEM -// 62d ARABIC LETTER HAH -// 62e ARABIC LETTER KHAH -// 62f ARABIC LETTER DAL -// 630 ARABIC LETTER THAL -// 631 ARABIC LETTER REH -// 632 ARABIC LETTER ZAIN -// 633 ARABIC LETTER SEEN -// 634 ARABIC LETTER SHEEN -// 635 ARABIC LETTER SAD -// 636 ARABIC LETTER DAD -// 637 ARABIC LETTER TAH -// 638 ARABIC LETTER ZAH -// 639 ARABIC LETTER AIN -// 63a ARABIC LETTER GHAIN -// 63b ARABIC LETTER KEHEH WITH TWO DOTS ABOVE -// 63c ARABIC LETTER KEHEH WITH THREE DOTS BELOW -// 63d ARABIC LETTER FARSI YEH WITH INVERTED V -// 63e ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE -// 63f ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE -// 640 ARABIC TATWEEL -// 641 ARABIC LETTER FEH -// 642 ARABIC LETTER QAF -// 643 ARABIC LETTER KAF -// 644 ARABIC LETTER LAM -// 645 ARABIC LETTER MEEM -// 646 ARABIC LETTER NOON -// 647 ARABIC LETTER HEH -// 648 ARABIC LETTER WAW -// 649 ARABIC LETTER ALEF MAKSURA -// 64a ARABIC LETTER YEH - { 0x620, 0x2B, 0x9, 0, 0 }, -// 64b ARABIC FATHATAN -// 64c ARABIC DAMMATAN -// 64d ARABIC KASRATAN -// 64e ARABIC FATHA -// 64f ARABIC DAMMA -// 650 ARABIC KASRA -// 651 ARABIC SHADDA -// 652 ARABIC SUKUN -// 653 ARABIC MADDAH ABOVE -// 654 ARABIC HAMZA ABOVE -// 655 ARABIC HAMZA BELOW -// 656 ARABIC SUBSCRIPT ALEF -// 657 ARABIC INVERTED DAMMA -// 658 ARABIC MARK NOON GHUNNA -// 659 ARABIC ZWARAKAY -// 65a ARABIC VOWEL SIGN SMALL V ABOVE -// 65b ARABIC VOWEL SIGN INVERTED SMALL V ABOVE -// 65c ARABIC VOWEL SIGN DOT BELOW -// 65d ARABIC REVERSED DAMMA -// 65e ARABIC FATHA WITH TWO DOTS -// 65f ARABIC WAVY HAMZA BELOW - { 0x64B, 0x15, 0x0, 0, 0 }, -// 660 ARABIC-INDIC DIGIT ZERO -// 661 ARABIC-INDIC DIGIT ONE -// 662 ARABIC-INDIC DIGIT TWO -// 663 ARABIC-INDIC DIGIT THREE -// 664 ARABIC-INDIC DIGIT FOUR -// 665 ARABIC-INDIC DIGIT FIVE -// 666 ARABIC-INDIC DIGIT SIX -// 667 ARABIC-INDIC DIGIT SEVEN -// 668 ARABIC-INDIC DIGIT EIGHT -// 669 ARABIC-INDIC DIGIT NINE - { 0x660, 0xA, 0x108, 0, 0 }, -// 66a ARABIC PERCENT SIGN -// 66b ARABIC DECIMAL SEPARATOR -// 66c ARABIC THOUSANDS SEPARATOR -// 66d ARABIC FIVE POINTED STAR - { 0x66A, 0x4, 0x18, 0, 0 }, -// 66e ARABIC LETTER DOTLESS BEH -// 66f ARABIC LETTER DOTLESS QAF - { 0x66E, 0x2, 0x9, 0, 0 }, -// 670 ARABIC LETTER SUPERSCRIPT ALEF - { 0x670, 0x1, 0x0, 0, 0 }, -// 671 ARABIC LETTER ALEF WASLA -// 672 ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE -// 673 ARABIC LETTER ALEF WITH WAVY HAMZA BELOW -// 674 ARABIC LETTER HIGH HAMZA -// 675 ARABIC LETTER HIGH HAMZA ALEF -// 676 ARABIC LETTER HIGH HAMZA WAW -// 677 ARABIC LETTER U WITH HAMZA ABOVE -// 678 ARABIC LETTER HIGH HAMZA YEH -// 679 ARABIC LETTER TTEH -// 67a ARABIC LETTER TTEHEH -// 67b ARABIC LETTER BEEH -// 67c ARABIC LETTER TEH WITH RING -// 67d ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS -// 67e ARABIC LETTER PEH -// 67f ARABIC LETTER TEHEH -// 680 ARABIC LETTER BEHEH -// 681 ARABIC LETTER HAH WITH HAMZA ABOVE -// 682 ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE -// 683 ARABIC LETTER NYEH -// 684 ARABIC LETTER DYEH -// 685 ARABIC LETTER HAH WITH THREE DOTS ABOVE -// 686 ARABIC LETTER TCHEH -// 687 ARABIC LETTER TCHEHEH -// 688 ARABIC LETTER DDAL -// 689 ARABIC LETTER DAL WITH RING -// 68a ARABIC LETTER DAL WITH DOT BELOW -// 68b ARABIC LETTER DAL WITH DOT BELOW AND SMALL TAH -// 68c ARABIC LETTER DAHAL -// 68d ARABIC LETTER DDAHAL -// 68e ARABIC LETTER DUL -// 68f ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS -// 690 ARABIC LETTER DAL WITH FOUR DOTS ABOVE -// 691 ARABIC LETTER RREH -// 692 ARABIC LETTER REH WITH SMALL V -// 693 ARABIC LETTER REH WITH RING -// 694 ARABIC LETTER REH WITH DOT BELOW -// 695 ARABIC LETTER REH WITH SMALL V BELOW -// 696 ARABIC LETTER REH WITH DOT BELOW AND DOT ABOVE -// 697 ARABIC LETTER REH WITH TWO DOTS ABOVE -// 698 ARABIC LETTER JEH -// 699 ARABIC LETTER REH WITH FOUR DOTS ABOVE -// 69a ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE -// 69b ARABIC LETTER SEEN WITH THREE DOTS BELOW -// 69c ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE -// 69d ARABIC LETTER SAD WITH TWO DOTS BELOW -// 69e ARABIC LETTER SAD WITH THREE DOTS ABOVE -// 69f ARABIC LETTER TAH WITH THREE DOTS ABOVE -// 6a0 ARABIC LETTER AIN WITH THREE DOTS ABOVE -// 6a1 ARABIC LETTER DOTLESS FEH -// 6a2 ARABIC LETTER FEH WITH DOT MOVED BELOW -// 6a3 ARABIC LETTER FEH WITH DOT BELOW -// 6a4 ARABIC LETTER VEH -// 6a5 ARABIC LETTER FEH WITH THREE DOTS BELOW -// 6a6 ARABIC LETTER PEHEH -// 6a7 ARABIC LETTER QAF WITH DOT ABOVE -// 6a8 ARABIC LETTER QAF WITH THREE DOTS ABOVE -// 6a9 ARABIC LETTER KEHEH -// 6aa ARABIC LETTER SWASH KAF -// 6ab ARABIC LETTER KAF WITH RING -// 6ac ARABIC LETTER KAF WITH DOT ABOVE -// 6ad ARABIC LETTER NG -// 6ae ARABIC LETTER KAF WITH THREE DOTS BELOW -// 6af ARABIC LETTER GAF -// 6b0 ARABIC LETTER GAF WITH RING -// 6b1 ARABIC LETTER NGOEH -// 6b2 ARABIC LETTER GAF WITH TWO DOTS BELOW -// 6b3 ARABIC LETTER GUEH -// 6b4 ARABIC LETTER GAF WITH THREE DOTS ABOVE -// 6b5 ARABIC LETTER LAM WITH SMALL V -// 6b6 ARABIC LETTER LAM WITH DOT ABOVE -// 6b7 ARABIC LETTER LAM WITH THREE DOTS ABOVE -// 6b8 ARABIC LETTER LAM WITH THREE DOTS BELOW -// 6b9 ARABIC LETTER NOON WITH DOT BELOW -// 6ba ARABIC LETTER NOON GHUNNA -// 6bb ARABIC LETTER RNOON -// 6bc ARABIC LETTER NOON WITH RING -// 6bd ARABIC LETTER NOON WITH THREE DOTS ABOVE -// 6be ARABIC LETTER HEH DOACHASHMEE -// 6bf ARABIC LETTER TCHEH WITH DOT ABOVE -// 6c0 ARABIC LETTER HEH WITH YEH ABOVE -// 6c1 ARABIC LETTER HEH GOAL -// 6c2 ARABIC LETTER HEH GOAL WITH HAMZA ABOVE -// 6c3 ARABIC LETTER TEH MARBUTA GOAL -// 6c4 ARABIC LETTER WAW WITH RING -// 6c5 ARABIC LETTER KIRGHIZ OE -// 6c6 ARABIC LETTER OE -// 6c7 ARABIC LETTER U -// 6c8 ARABIC LETTER YU -// 6c9 ARABIC LETTER KIRGHIZ YU -// 6ca ARABIC LETTER WAW WITH TWO DOTS ABOVE -// 6cb ARABIC LETTER VE -// 6cc ARABIC LETTER FARSI YEH -// 6cd ARABIC LETTER YEH WITH TAIL -// 6ce ARABIC LETTER YEH WITH SMALL V -// 6cf ARABIC LETTER WAW WITH DOT ABOVE -// 6d0 ARABIC LETTER E -// 6d1 ARABIC LETTER YEH WITH THREE DOTS BELOW -// 6d2 ARABIC LETTER YEH BARREE -// 6d3 ARABIC LETTER YEH BARREE WITH HAMZA ABOVE - { 0x671, 0x63, 0x9, 0, 0 }, -// 6d4 ARABIC FULL STOP - { 0x6D4, 0x1, 0x18, 0, 0 }, -// 6d5 ARABIC LETTER AE - { 0x6D5, 0x1, 0x9, 0, 0 }, -// 6d6 ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA -// 6d7 ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA -// 6d8 ARABIC SMALL HIGH MEEM INITIAL FORM -// 6d9 ARABIC SMALL HIGH LAM ALEF -// 6da ARABIC SMALL HIGH JEEM -// 6db ARABIC SMALL HIGH THREE DOTS -// 6dc ARABIC SMALL HIGH SEEN -// 6dd ARABIC END OF AYAH - { 0x6D6, 0x8, 0x0, 0, 0 }, -// 6de ARABIC START OF RUB EL HIZB - { 0x6DE, 0x1, 0x8, 0, 0 }, -// 6df ARABIC SMALL HIGH ROUNDED ZERO -// 6e0 ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO -// 6e1 ARABIC SMALL HIGH DOTLESS HEAD OF KHAH -// 6e2 ARABIC SMALL HIGH MEEM ISOLATED FORM -// 6e3 ARABIC SMALL LOW SEEN -// 6e4 ARABIC SMALL HIGH MADDA - { 0x6DF, 0x6, 0x0, 0, 0 }, -// 6e5 ARABIC SMALL WAW -// 6e6 ARABIC SMALL YEH - { 0x6E5, 0x2, 0x9, 0, 0 }, -// 6e7 ARABIC SMALL HIGH YEH -// 6e8 ARABIC SMALL HIGH NOON - { 0x6E7, 0x2, 0x0, 0, 0 }, -// 6e9 ARABIC PLACE OF SAJDAH - { 0x6E9, 0x1, 0x8, 0, 0 }, -// 6ea ARABIC EMPTY CENTRE LOW STOP -// 6eb ARABIC EMPTY CENTRE HIGH STOP -// 6ec ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE -// 6ed ARABIC SMALL LOW MEEM - { 0x6EA, 0x4, 0x0, 0, 0 }, -// 6ee ARABIC LETTER DAL WITH INVERTED V -// 6ef ARABIC LETTER REH WITH INVERTED V - { 0x6EE, 0x2, 0x9, 0, 0 }, -// 6f0 EXTENDED ARABIC-INDIC DIGIT ZERO -// 6f1 EXTENDED ARABIC-INDIC DIGIT ONE -// 6f2 EXTENDED ARABIC-INDIC DIGIT TWO -// 6f3 EXTENDED ARABIC-INDIC DIGIT THREE -// 6f4 EXTENDED ARABIC-INDIC DIGIT FOUR -// 6f5 EXTENDED ARABIC-INDIC DIGIT FIVE -// 6f6 EXTENDED ARABIC-INDIC DIGIT SIX -// 6f7 EXTENDED ARABIC-INDIC DIGIT SEVEN -// 6f8 EXTENDED ARABIC-INDIC DIGIT EIGHT -// 6f9 EXTENDED ARABIC-INDIC DIGIT NINE - { 0x6F0, 0xA, 0x108, 0, 0 }, -// 6fa ARABIC LETTER SHEEN WITH DOT BELOW -// 6fb ARABIC LETTER DAD WITH DOT BELOW -// 6fc ARABIC LETTER GHAIN WITH DOT BELOW - { 0x6FA, 0x3, 0x9, 0, 0 }, -// 6fd ARABIC SIGN SINDHI AMPERSAND -// 6fe ARABIC SIGN SINDHI POSTPOSITION MEN - { 0x6FD, 0x2, 0x8, 0, 0 }, -// 6ff ARABIC LETTER HEH WITH INVERTED V - { 0x6FF, 0x1, 0x9, 0, 0 }, -// 700 SYRIAC END OF PARAGRAPH -// 701 SYRIAC SUPRALINEAR FULL STOP -// 702 SYRIAC SUBLINEAR FULL STOP -// 703 SYRIAC SUPRALINEAR COLON -// 704 SYRIAC SUBLINEAR COLON -// 705 SYRIAC HORIZONTAL COLON -// 706 SYRIAC COLON SKEWED LEFT -// 707 SYRIAC COLON SKEWED RIGHT -// 708 SYRIAC SUPRALINEAR COLON SKEWED LEFT -// 709 SYRIAC SUBLINEAR COLON SKEWED RIGHT -// 70a SYRIAC CONTRACTION -// 70b SYRIAC HARKLEAN OBELUS -// 70c SYRIAC HARKLEAN METOBELUS -// 70d SYRIAC HARKLEAN ASTERISCUS - { 0x700, 0xE, 0x18, 0, 0 }, -// 70f SYRIAC ABBREVIATION MARK - { 0x70F, 0x1, 0x0, 0, 0 }, -// 710 SYRIAC LETTER ALAPH - { 0x710, 0x1, 0x9, 0, 0 }, -// 711 SYRIAC LETTER SUPERSCRIPT ALAPH - { 0x711, 0x1, 0x0, 0, 0 }, -// 712 SYRIAC LETTER BETH -// 713 SYRIAC LETTER GAMAL -// 714 SYRIAC LETTER GAMAL GARSHUNI -// 715 SYRIAC LETTER DALATH -// 716 SYRIAC LETTER DOTLESS DALATH RISH -// 717 SYRIAC LETTER HE -// 718 SYRIAC LETTER WAW -// 719 SYRIAC LETTER ZAIN -// 71a SYRIAC LETTER HETH -// 71b SYRIAC LETTER TETH -// 71c SYRIAC LETTER TETH GARSHUNI -// 71d SYRIAC LETTER YUDH -// 71e SYRIAC LETTER YUDH HE -// 71f SYRIAC LETTER KAPH -// 720 SYRIAC LETTER LAMADH -// 721 SYRIAC LETTER MIM -// 722 SYRIAC LETTER NUN -// 723 SYRIAC LETTER SEMKATH -// 724 SYRIAC LETTER FINAL SEMKATH -// 725 SYRIAC LETTER E -// 726 SYRIAC LETTER PE -// 727 SYRIAC LETTER REVERSED PE -// 728 SYRIAC LETTER SADHE -// 729 SYRIAC LETTER QAPH -// 72a SYRIAC LETTER RISH -// 72b SYRIAC LETTER SHIN -// 72c SYRIAC LETTER TAW -// 72d SYRIAC LETTER PERSIAN BHETH -// 72e SYRIAC LETTER PERSIAN GHAMAL -// 72f SYRIAC LETTER PERSIAN DHALATH - { 0x712, 0x1E, 0x9, 0, 0 }, -// 730 SYRIAC PTHAHA ABOVE -// 731 SYRIAC PTHAHA BELOW -// 732 SYRIAC PTHAHA DOTTED -// 733 SYRIAC ZQAPHA ABOVE -// 734 SYRIAC ZQAPHA BELOW -// 735 SYRIAC ZQAPHA DOTTED -// 736 SYRIAC RBASA ABOVE -// 737 SYRIAC RBASA BELOW -// 738 SYRIAC DOTTED ZLAMA HORIZONTAL -// 739 SYRIAC DOTTED ZLAMA ANGULAR -// 73a SYRIAC HBASA ABOVE -// 73b SYRIAC HBASA BELOW -// 73c SYRIAC HBASA-ESASA DOTTED -// 73d SYRIAC ESASA ABOVE -// 73e SYRIAC ESASA BELOW -// 73f SYRIAC RWAHA -// 740 SYRIAC FEMININE DOT -// 741 SYRIAC QUSHSHAYA -// 742 SYRIAC RUKKAKHA -// 743 SYRIAC TWO VERTICAL DOTS ABOVE -// 744 SYRIAC TWO VERTICAL DOTS BELOW -// 745 SYRIAC THREE DOTS ABOVE -// 746 SYRIAC THREE DOTS BELOW -// 747 SYRIAC OBLIQUE LINE ABOVE -// 748 SYRIAC OBLIQUE LINE BELOW -// 749 SYRIAC MUSIC -// 74a SYRIAC BARREKH - { 0x730, 0x1B, 0x0, 0, 0 }, -// 74d SYRIAC LETTER SOGDIAN ZHAIN -// 74e SYRIAC LETTER SOGDIAN KHAPH -// 74f SYRIAC LETTER SOGDIAN FE -// 750 ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW -// 751 ARABIC LETTER BEH WITH DOT BELOW AND THREE DOTS ABOVE -// 752 ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW -// 753 ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW AND TWO DOTS ABOVE -// 754 ARABIC LETTER BEH WITH TWO DOTS BELOW AND DOT ABOVE -// 755 ARABIC LETTER BEH WITH INVERTED SMALL V BELOW -// 756 ARABIC LETTER BEH WITH SMALL V -// 757 ARABIC LETTER HAH WITH TWO DOTS ABOVE -// 758 ARABIC LETTER HAH WITH THREE DOTS POINTING UPWARDS BELOW -// 759 ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW AND SMALL TAH -// 75a ARABIC LETTER DAL WITH INVERTED SMALL V BELOW -// 75b ARABIC LETTER REH WITH STROKE -// 75c ARABIC LETTER SEEN WITH FOUR DOTS ABOVE -// 75d ARABIC LETTER AIN WITH TWO DOTS ABOVE -// 75e ARABIC LETTER AIN WITH THREE DOTS POINTING DOWNWARDS ABOVE -// 75f ARABIC LETTER AIN WITH TWO DOTS VERTICALLY ABOVE -// 760 ARABIC LETTER FEH WITH TWO DOTS BELOW -// 761 ARABIC LETTER FEH WITH THREE DOTS POINTING UPWARDS BELOW -// 762 ARABIC LETTER KEHEH WITH DOT ABOVE -// 763 ARABIC LETTER KEHEH WITH THREE DOTS ABOVE -// 764 ARABIC LETTER KEHEH WITH THREE DOTS POINTING UPWARDS BELOW -// 765 ARABIC LETTER MEEM WITH DOT ABOVE -// 766 ARABIC LETTER MEEM WITH DOT BELOW -// 767 ARABIC LETTER NOON WITH TWO DOTS BELOW -// 768 ARABIC LETTER NOON WITH SMALL TAH -// 769 ARABIC LETTER NOON WITH SMALL V -// 76a ARABIC LETTER LAM WITH BAR -// 76b ARABIC LETTER REH WITH TWO DOTS VERTICALLY ABOVE -// 76c ARABIC LETTER REH WITH HAMZA ABOVE -// 76d ARABIC LETTER SEEN WITH TWO DOTS VERTICALLY ABOVE -// 76e ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH BELOW -// 76f ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH AND TWO DOTS -// 770 ARABIC LETTER SEEN WITH SMALL ARABIC LETTER TAH AND TWO DOTS -// 771 ARABIC LETTER REH WITH SMALL ARABIC LETTER TAH AND TWO DOTS -// 772 ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH ABOVE -// 773 ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE -// 774 ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE -// 775 ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE -// 776 ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE -// 777 ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW -// 778 ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE -// 779 ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE -// 77a ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE -// 77b ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE -// 77c ARABIC LETTER HAH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW -// 77d ARABIC LETTER SEEN WITH EXTENDED ARABIC-INDIC DIGIT FOUR ABOVE -// 77e ARABIC LETTER SEEN WITH INVERTED V -// 77f ARABIC LETTER KAF WITH TWO DOTS ABOVE -// 780 THAANA LETTER HAA -// 781 THAANA LETTER SHAVIYANI -// 782 THAANA LETTER NOONU -// 783 THAANA LETTER RAA -// 784 THAANA LETTER BAA -// 785 THAANA LETTER LHAVIYANI -// 786 THAANA LETTER KAAFU -// 787 THAANA LETTER ALIFU -// 788 THAANA LETTER VAAVU -// 789 THAANA LETTER MEEMU -// 78a THAANA LETTER FAAFU -// 78b THAANA LETTER DHAALU -// 78c THAANA LETTER THAA -// 78d THAANA LETTER LAAMU -// 78e THAANA LETTER GAAFU -// 78f THAANA LETTER GNAVIYANI -// 790 THAANA LETTER SEENU -// 791 THAANA LETTER DAVIYANI -// 792 THAANA LETTER ZAVIYANI -// 793 THAANA LETTER TAVIYANI -// 794 THAANA LETTER YAA -// 795 THAANA LETTER PAVIYANI -// 796 THAANA LETTER JAVIYANI -// 797 THAANA LETTER CHAVIYANI -// 798 THAANA LETTER TTAA -// 799 THAANA LETTER HHAA -// 79a THAANA LETTER KHAA -// 79b THAANA LETTER THAALU -// 79c THAANA LETTER ZAA -// 79d THAANA LETTER SHEENU -// 79e THAANA LETTER SAADHU -// 79f THAANA LETTER DAADHU -// 7a0 THAANA LETTER TO -// 7a1 THAANA LETTER ZO -// 7a2 THAANA LETTER AINU -// 7a3 THAANA LETTER GHAINU -// 7a4 THAANA LETTER QAAFU -// 7a5 THAANA LETTER WAAVU - { 0x74D, 0x59, 0x9, 0, 0 }, -// 7a6 THAANA ABAFILI -// 7a7 THAANA AABAAFILI -// 7a8 THAANA IBIFILI -// 7a9 THAANA EEBEEFILI -// 7aa THAANA UBUFILI -// 7ab THAANA OOBOOFILI -// 7ac THAANA EBEFILI -// 7ad THAANA EYBEYFILI -// 7ae THAANA OBOFILI -// 7af THAANA OABOAFILI -// 7b0 THAANA SUKUN - { 0x7A6, 0xB, 0x0, 0, 0 }, -// 7b1 THAANA LETTER NAA - { 0x7B1, 0x1, 0x9, 0, 0 }, -// 7c0 NKO DIGIT ZERO -// 7c1 NKO DIGIT ONE -// 7c2 NKO DIGIT TWO -// 7c3 NKO DIGIT THREE -// 7c4 NKO DIGIT FOUR -// 7c5 NKO DIGIT FIVE -// 7c6 NKO DIGIT SIX -// 7c7 NKO DIGIT SEVEN -// 7c8 NKO DIGIT EIGHT -// 7c9 NKO DIGIT NINE - { 0x7C0, 0xA, 0x108, 0, 0 }, -// 7ca NKO LETTER A -// 7cb NKO LETTER EE -// 7cc NKO LETTER I -// 7cd NKO LETTER E -// 7ce NKO LETTER U -// 7cf NKO LETTER OO -// 7d0 NKO LETTER O -// 7d1 NKO LETTER DAGBASINNA -// 7d2 NKO LETTER N -// 7d3 NKO LETTER BA -// 7d4 NKO LETTER PA -// 7d5 NKO LETTER TA -// 7d6 NKO LETTER JA -// 7d7 NKO LETTER CHA -// 7d8 NKO LETTER DA -// 7d9 NKO LETTER RA -// 7da NKO LETTER RRA -// 7db NKO LETTER SA -// 7dc NKO LETTER GBA -// 7dd NKO LETTER FA -// 7de NKO LETTER KA -// 7df NKO LETTER LA -// 7e0 NKO LETTER NA WOLOSO -// 7e1 NKO LETTER MA -// 7e2 NKO LETTER NYA -// 7e3 NKO LETTER NA -// 7e4 NKO LETTER HA -// 7e5 NKO LETTER WA -// 7e6 NKO LETTER YA -// 7e7 NKO LETTER NYA WOLOSO -// 7e8 NKO LETTER JONA JA -// 7e9 NKO LETTER JONA CHA -// 7ea NKO LETTER JONA RA - { 0x7CA, 0x21, 0x9, 0, 0 }, -// 7eb NKO COMBINING SHORT HIGH TONE -// 7ec NKO COMBINING SHORT LOW TONE -// 7ed NKO COMBINING SHORT RISING TONE -// 7ee NKO COMBINING LONG DESCENDING TONE -// 7ef NKO COMBINING LONG HIGH TONE -// 7f0 NKO COMBINING LONG LOW TONE -// 7f1 NKO COMBINING LONG RISING TONE -// 7f2 NKO COMBINING NASALIZATION MARK -// 7f3 NKO COMBINING DOUBLE DOT ABOVE - { 0x7EB, 0x9, 0x0, 0, 0 }, -// 7f4 NKO HIGH TONE APOSTROPHE -// 7f5 NKO LOW TONE APOSTROPHE - { 0x7F4, 0x2, 0x9, 0, 0 }, -// 7f6 NKO SYMBOL OO DENNEN - { 0x7F6, 0x1, 0x8, 0, 0 }, -// 7f7 NKO SYMBOL GBAKURUNEN -// 7f8 NKO COMMA -// 7f9 NKO EXCLAMATION MARK - { 0x7F7, 0x3, 0x18, 0, 0 }, -// 7fa NKO LAJANYALAN - { 0x7FA, 0x1, 0x9, 0, 0 }, -// 800 SAMARITAN LETTER ALAF -// 801 SAMARITAN LETTER BIT -// 802 SAMARITAN LETTER GAMAN -// 803 SAMARITAN LETTER DALAT -// 804 SAMARITAN LETTER IY -// 805 SAMARITAN LETTER BAA -// 806 SAMARITAN LETTER ZEN -// 807 SAMARITAN LETTER IT -// 808 SAMARITAN LETTER TIT -// 809 SAMARITAN LETTER YUT -// 80a SAMARITAN LETTER KAAF -// 80b SAMARITAN LETTER LABAT -// 80c SAMARITAN LETTER MIM -// 80d SAMARITAN LETTER NUN -// 80e SAMARITAN LETTER SINGAAT -// 80f SAMARITAN LETTER IN -// 810 SAMARITAN LETTER FI -// 811 SAMARITAN LETTER TSAADIY -// 812 SAMARITAN LETTER QUF -// 813 SAMARITAN LETTER RISH -// 814 SAMARITAN LETTER SHAN -// 815 SAMARITAN LETTER TAAF - { 0x800, 0x16, 0x9, 0, 0 }, -// 816 SAMARITAN MARK IN -// 817 SAMARITAN MARK IN-ALAF -// 818 SAMARITAN MARK OCCLUSION -// 819 SAMARITAN MARK DAGESH - { 0x816, 0x4, 0x0, 0, 0 }, -// 81a SAMARITAN MODIFIER LETTER EPENTHETIC YUT - { 0x81A, 0x1, 0x9, 0, 0 }, -// 81b SAMARITAN MARK EPENTHETIC YUT -// 81c SAMARITAN VOWEL SIGN LONG E -// 81d SAMARITAN VOWEL SIGN E -// 81e SAMARITAN VOWEL SIGN OVERLONG AA -// 81f SAMARITAN VOWEL SIGN LONG AA -// 820 SAMARITAN VOWEL SIGN AA -// 821 SAMARITAN VOWEL SIGN OVERLONG A -// 822 SAMARITAN VOWEL SIGN LONG A -// 823 SAMARITAN VOWEL SIGN A - { 0x81B, 0x9, 0x0, 0, 0 }, -// 824 SAMARITAN MODIFIER LETTER SHORT A - { 0x824, 0x1, 0x9, 0, 0 }, -// 825 SAMARITAN VOWEL SIGN SHORT A -// 826 SAMARITAN VOWEL SIGN LONG U -// 827 SAMARITAN VOWEL SIGN U - { 0x825, 0x3, 0x0, 0, 0 }, -// 828 SAMARITAN MODIFIER LETTER I - { 0x828, 0x1, 0x9, 0, 0 }, -// 829 SAMARITAN VOWEL SIGN LONG I -// 82a SAMARITAN VOWEL SIGN I -// 82b SAMARITAN VOWEL SIGN O -// 82c SAMARITAN VOWEL SIGN SUKUN -// 82d SAMARITAN MARK NEQUDAA - { 0x829, 0x5, 0x0, 0, 0 }, -// 830 SAMARITAN PUNCTUATION NEQUDAA -// 831 SAMARITAN PUNCTUATION AFSAAQ -// 832 SAMARITAN PUNCTUATION ANGED -// 833 SAMARITAN PUNCTUATION BAU -// 834 SAMARITAN PUNCTUATION ATMAAU -// 835 SAMARITAN PUNCTUATION SHIYYAALAA -// 836 SAMARITAN ABBREVIATION MARK -// 837 SAMARITAN PUNCTUATION MELODIC QITSA -// 838 SAMARITAN PUNCTUATION ZIQAA -// 839 SAMARITAN PUNCTUATION QITSA -// 83a SAMARITAN PUNCTUATION ZAEF -// 83b SAMARITAN PUNCTUATION TURU -// 83c SAMARITAN PUNCTUATION ARKAANU -// 83d SAMARITAN PUNCTUATION SOF MASHFAAT -// 83e SAMARITAN PUNCTUATION ANNAAU - { 0x830, 0xF, 0x18, 0, 0 }, -// 840 MANDAIC LETTER HALQA -// 841 MANDAIC LETTER AB -// 842 MANDAIC LETTER AG -// 843 MANDAIC LETTER AD -// 844 MANDAIC LETTER AH -// 845 MANDAIC LETTER USHENNA -// 846 MANDAIC LETTER AZ -// 847 MANDAIC LETTER IT -// 848 MANDAIC LETTER ATT -// 849 MANDAIC LETTER AKSA -// 84a MANDAIC LETTER AK -// 84b MANDAIC LETTER AL -// 84c MANDAIC LETTER AM -// 84d MANDAIC LETTER AN -// 84e MANDAIC LETTER AS -// 84f MANDAIC LETTER IN -// 850 MANDAIC LETTER AP -// 851 MANDAIC LETTER ASZ -// 852 MANDAIC LETTER AQ -// 853 MANDAIC LETTER AR -// 854 MANDAIC LETTER ASH -// 855 MANDAIC LETTER AT -// 856 MANDAIC LETTER DUSHENNA -// 857 MANDAIC LETTER KAD -// 858 MANDAIC LETTER AIN - { 0x840, 0x19, 0x9, 0, 0 }, -// 859 MANDAIC AFFRICATION MARK -// 85a MANDAIC VOCALIZATION MARK -// 85b MANDAIC GEMINATION MARK - { 0x859, 0x3, 0x0, 0, 0 }, -// 85e MANDAIC PUNCTUATION - { 0x85E, 0x1, 0x18, 0, 0 }, -// 8a0 ARABIC LETTER BEH WITH SMALL V BELOW -// 8a1 ARABIC LETTER BEH WITH HAMZA ABOVE -// 8a2 ARABIC LETTER JEEM WITH TWO DOTS ABOVE -// 8a3 ARABIC LETTER TAH WITH TWO DOTS ABOVE -// 8a4 ARABIC LETTER FEH WITH DOT BELOW AND THREE DOTS ABOVE -// 8a5 ARABIC LETTER QAF WITH DOT BELOW -// 8a6 ARABIC LETTER LAM WITH DOUBLE BAR -// 8a7 ARABIC LETTER MEEM WITH THREE DOTS ABOVE -// 8a8 ARABIC LETTER YEH WITH TWO DOTS BELOW AND HAMZA ABOVE -// 8a9 ARABIC LETTER YEH WITH TWO DOTS BELOW AND DOT ABOVE -// 8aa ARABIC LETTER REH WITH LOOP -// 8ab ARABIC LETTER WAW WITH DOT WITHIN -// 8ac ARABIC LETTER ROHINGYA YEH -// 8ad ARABIC LETTER LOW ALEF -// 8ae ARABIC LETTER DAL WITH THREE DOTS BELOW -// 8af ARABIC LETTER SAD WITH THREE DOTS BELOW -// 8b0 ARABIC LETTER GAF WITH INVERTED STROKE -// 8b1 ARABIC LETTER STRAIGHT WAW -// 8b2 ARABIC LETTER ZAIN WITH INVERTED V ABOVE - { 0x8A0, 0x13, 0x9, 0, 0 }, -// 8e4 ARABIC CURLY FATHA -// 8e5 ARABIC CURLY DAMMA -// 8e6 ARABIC CURLY KASRA -// 8e7 ARABIC CURLY FATHATAN -// 8e8 ARABIC CURLY DAMMATAN -// 8e9 ARABIC CURLY KASRATAN -// 8ea ARABIC TONE ONE DOT ABOVE -// 8eb ARABIC TONE TWO DOTS ABOVE -// 8ec ARABIC TONE LOOP ABOVE -// 8ed ARABIC TONE ONE DOT BELOW -// 8ee ARABIC TONE TWO DOTS BELOW -// 8ef ARABIC TONE LOOP BELOW -// 8f0 ARABIC OPEN FATHATAN -// 8f1 ARABIC OPEN DAMMATAN -// 8f2 ARABIC OPEN KASRATAN -// 8f3 ARABIC SMALL HIGH WAW -// 8f4 ARABIC FATHA WITH RING -// 8f5 ARABIC FATHA WITH DOT ABOVE -// 8f6 ARABIC KASRA WITH DOT BELOW -// 8f7 ARABIC LEFT ARROWHEAD ABOVE -// 8f8 ARABIC RIGHT ARROWHEAD ABOVE -// 8f9 ARABIC LEFT ARROWHEAD BELOW -// 8fa ARABIC RIGHT ARROWHEAD BELOW -// 8fb ARABIC DOUBLE RIGHT ARROWHEAD ABOVE -// 8fc ARABIC DOUBLE RIGHT ARROWHEAD ABOVE WITH DOT -// 8fd ARABIC RIGHT ARROWHEAD ABOVE WITH DOT -// 8fe ARABIC DAMMA WITH DOT -// 8ff ARABIC MARK SIDEWAYS NOON GHUNNA -// 900 DEVANAGARI SIGN INVERTED CANDRABINDU -// 901 DEVANAGARI SIGN CANDRABINDU -// 902 DEVANAGARI SIGN ANUSVARA -// 903 DEVANAGARI SIGN VISARGA - { 0x8E4, 0x20, 0x0, 0, 0 }, -// 904 DEVANAGARI LETTER SHORT A -// 905 DEVANAGARI LETTER A -// 906 DEVANAGARI LETTER AA -// 907 DEVANAGARI LETTER I -// 908 DEVANAGARI LETTER II -// 909 DEVANAGARI LETTER U -// 90a DEVANAGARI LETTER UU -// 90b DEVANAGARI LETTER VOCALIC R -// 90c DEVANAGARI LETTER VOCALIC L -// 90d DEVANAGARI LETTER CANDRA E -// 90e DEVANAGARI LETTER SHORT E -// 90f DEVANAGARI LETTER E -// 910 DEVANAGARI LETTER AI -// 911 DEVANAGARI LETTER CANDRA O -// 912 DEVANAGARI LETTER SHORT O -// 913 DEVANAGARI LETTER O -// 914 DEVANAGARI LETTER AU -// 915 DEVANAGARI LETTER KA -// 916 DEVANAGARI LETTER KHA -// 917 DEVANAGARI LETTER GA -// 918 DEVANAGARI LETTER GHA -// 919 DEVANAGARI LETTER NGA -// 91a DEVANAGARI LETTER CA -// 91b DEVANAGARI LETTER CHA -// 91c DEVANAGARI LETTER JA -// 91d DEVANAGARI LETTER JHA -// 91e DEVANAGARI LETTER NYA -// 91f DEVANAGARI LETTER TTA -// 920 DEVANAGARI LETTER TTHA -// 921 DEVANAGARI LETTER DDA -// 922 DEVANAGARI LETTER DDHA -// 923 DEVANAGARI LETTER NNA -// 924 DEVANAGARI LETTER TA -// 925 DEVANAGARI LETTER THA -// 926 DEVANAGARI LETTER DA -// 927 DEVANAGARI LETTER DHA -// 928 DEVANAGARI LETTER NA -// 929 DEVANAGARI LETTER NNNA -// 92a DEVANAGARI LETTER PA -// 92b DEVANAGARI LETTER PHA -// 92c DEVANAGARI LETTER BA -// 92d DEVANAGARI LETTER BHA -// 92e DEVANAGARI LETTER MA -// 92f DEVANAGARI LETTER YA -// 930 DEVANAGARI LETTER RA -// 931 DEVANAGARI LETTER RRA -// 932 DEVANAGARI LETTER LA -// 933 DEVANAGARI LETTER LLA -// 934 DEVANAGARI LETTER LLLA -// 935 DEVANAGARI LETTER VA -// 936 DEVANAGARI LETTER SHA -// 937 DEVANAGARI LETTER SSA -// 938 DEVANAGARI LETTER SA -// 939 DEVANAGARI LETTER HA - { 0x904, 0x36, 0x9, 0, 0 }, -// 93a DEVANAGARI VOWEL SIGN OE -// 93b DEVANAGARI VOWEL SIGN OOE -// 93c DEVANAGARI SIGN NUKTA - { 0x93A, 0x3, 0x0, 0, 0 }, -// 93d DEVANAGARI SIGN AVAGRAHA - { 0x93D, 0x1, 0x9, 0, 0 }, -// 93e DEVANAGARI VOWEL SIGN AA -// 93f DEVANAGARI VOWEL SIGN I -// 940 DEVANAGARI VOWEL SIGN II -// 941 DEVANAGARI VOWEL SIGN U -// 942 DEVANAGARI VOWEL SIGN UU -// 943 DEVANAGARI VOWEL SIGN VOCALIC R -// 944 DEVANAGARI VOWEL SIGN VOCALIC RR -// 945 DEVANAGARI VOWEL SIGN CANDRA E -// 946 DEVANAGARI VOWEL SIGN SHORT E -// 947 DEVANAGARI VOWEL SIGN E -// 948 DEVANAGARI VOWEL SIGN AI -// 949 DEVANAGARI VOWEL SIGN CANDRA O -// 94a DEVANAGARI VOWEL SIGN SHORT O -// 94b DEVANAGARI VOWEL SIGN O -// 94c DEVANAGARI VOWEL SIGN AU -// 94d DEVANAGARI SIGN VIRAMA -// 94e DEVANAGARI VOWEL SIGN PRISHTHAMATRA E -// 94f DEVANAGARI VOWEL SIGN AW - { 0x93E, 0x12, 0x0, 0, 0 }, -// 950 DEVANAGARI OM - { 0x950, 0x1, 0x9, 0, 0 }, -// 951 DEVANAGARI STRESS SIGN UDATTA -// 952 DEVANAGARI STRESS SIGN ANUDATTA -// 953 DEVANAGARI GRAVE ACCENT -// 954 DEVANAGARI ACUTE ACCENT -// 955 DEVANAGARI VOWEL SIGN CANDRA LONG E -// 956 DEVANAGARI VOWEL SIGN UE -// 957 DEVANAGARI VOWEL SIGN UUE - { 0x951, 0x7, 0x0, 0, 0 }, -// 958 DEVANAGARI LETTER QA -// 959 DEVANAGARI LETTER KHHA -// 95a DEVANAGARI LETTER GHHA -// 95b DEVANAGARI LETTER ZA -// 95c DEVANAGARI LETTER DDDHA -// 95d DEVANAGARI LETTER RHA -// 95e DEVANAGARI LETTER FA -// 95f DEVANAGARI LETTER YYA -// 960 DEVANAGARI LETTER VOCALIC RR -// 961 DEVANAGARI LETTER VOCALIC LL - { 0x958, 0xA, 0x9, 0, 0 }, -// 962 DEVANAGARI VOWEL SIGN VOCALIC L -// 963 DEVANAGARI VOWEL SIGN VOCALIC LL - { 0x962, 0x2, 0x0, 0, 0 }, -// 964 DEVANAGARI DANDA -// 965 DEVANAGARI DOUBLE DANDA - { 0x964, 0x2, 0x18, 0, 0 }, -// 966 DEVANAGARI DIGIT ZERO -// 967 DEVANAGARI DIGIT ONE -// 968 DEVANAGARI DIGIT TWO -// 969 DEVANAGARI DIGIT THREE -// 96a DEVANAGARI DIGIT FOUR -// 96b DEVANAGARI DIGIT FIVE -// 96c DEVANAGARI DIGIT SIX -// 96d DEVANAGARI DIGIT SEVEN -// 96e DEVANAGARI DIGIT EIGHT -// 96f DEVANAGARI DIGIT NINE - { 0x966, 0xA, 0x108, 0, 0 }, -// 970 DEVANAGARI ABBREVIATION SIGN - { 0x970, 0x1, 0x18, 0, 0 }, -// 971 DEVANAGARI SIGN HIGH SPACING DOT -// 972 DEVANAGARI LETTER CANDRA A -// 973 DEVANAGARI LETTER OE -// 974 DEVANAGARI LETTER OOE -// 975 DEVANAGARI LETTER AW -// 976 DEVANAGARI LETTER UE -// 977 DEVANAGARI LETTER UUE -// 978 DEVANAGARI LETTER MARWARI DDA -// 979 DEVANAGARI LETTER ZHA -// 97a DEVANAGARI LETTER HEAVY YA -// 97b DEVANAGARI LETTER GGA -// 97c DEVANAGARI LETTER JJA -// 97d DEVANAGARI LETTER GLOTTAL STOP -// 97e DEVANAGARI LETTER DDDA -// 97f DEVANAGARI LETTER BBA -// 980 BENGALI ANJI - { 0x971, 0x10, 0x9, 0, 0 }, -// 981 BENGALI SIGN CANDRABINDU -// 982 BENGALI SIGN ANUSVARA -// 983 BENGALI SIGN VISARGA - { 0x981, 0x3, 0x0, 0, 0 }, -// 985 BENGALI LETTER A -// 986 BENGALI LETTER AA -// 987 BENGALI LETTER I -// 988 BENGALI LETTER II -// 989 BENGALI LETTER U -// 98a BENGALI LETTER UU -// 98b BENGALI LETTER VOCALIC R -// 98c BENGALI LETTER VOCALIC L - { 0x985, 0x8, 0x9, 0, 0 }, -// 98f BENGALI LETTER E -// 990 BENGALI LETTER AI - { 0x98F, 0x2, 0x9, 0, 0 }, -// 993 BENGALI LETTER O -// 994 BENGALI LETTER AU -// 995 BENGALI LETTER KA -// 996 BENGALI LETTER KHA -// 997 BENGALI LETTER GA -// 998 BENGALI LETTER GHA -// 999 BENGALI LETTER NGA -// 99a BENGALI LETTER CA -// 99b BENGALI LETTER CHA -// 99c BENGALI LETTER JA -// 99d BENGALI LETTER JHA -// 99e BENGALI LETTER NYA -// 99f BENGALI LETTER TTA -// 9a0 BENGALI LETTER TTHA -// 9a1 BENGALI LETTER DDA -// 9a2 BENGALI LETTER DDHA -// 9a3 BENGALI LETTER NNA -// 9a4 BENGALI LETTER TA -// 9a5 BENGALI LETTER THA -// 9a6 BENGALI LETTER DA -// 9a7 BENGALI LETTER DHA -// 9a8 BENGALI LETTER NA - { 0x993, 0x16, 0x9, 0, 0 }, -// 9aa BENGALI LETTER PA -// 9ab BENGALI LETTER PHA -// 9ac BENGALI LETTER BA -// 9ad BENGALI LETTER BHA -// 9ae BENGALI LETTER MA -// 9af BENGALI LETTER YA -// 9b0 BENGALI LETTER RA - { 0x9AA, 0x7, 0x9, 0, 0 }, -// 9b2 BENGALI LETTER LA - { 0x9B2, 0x1, 0x9, 0, 0 }, -// 9b6 BENGALI LETTER SHA -// 9b7 BENGALI LETTER SSA -// 9b8 BENGALI LETTER SA -// 9b9 BENGALI LETTER HA - { 0x9B6, 0x4, 0x9, 0, 0 }, -// 9bc BENGALI SIGN NUKTA - { 0x9BC, 0x1, 0x0, 0, 0 }, -// 9bd BENGALI SIGN AVAGRAHA - { 0x9BD, 0x1, 0x9, 0, 0 }, -// 9be BENGALI VOWEL SIGN AA -// 9bf BENGALI VOWEL SIGN I -// 9c0 BENGALI VOWEL SIGN II -// 9c1 BENGALI VOWEL SIGN U -// 9c2 BENGALI VOWEL SIGN UU -// 9c3 BENGALI VOWEL SIGN VOCALIC R -// 9c4 BENGALI VOWEL SIGN VOCALIC RR - { 0x9BE, 0x7, 0x0, 0, 0 }, -// 9c7 BENGALI VOWEL SIGN E -// 9c8 BENGALI VOWEL SIGN AI - { 0x9C7, 0x2, 0x0, 0, 0 }, -// 9cb BENGALI VOWEL SIGN O -// 9cc BENGALI VOWEL SIGN AU -// 9cd BENGALI SIGN VIRAMA - { 0x9CB, 0x3, 0x0, 0, 0 }, -// 9ce BENGALI LETTER KHANDA TA - { 0x9CE, 0x1, 0x9, 0, 0 }, -// 9d7 BENGALI AU LENGTH MARK - { 0x9D7, 0x1, 0x0, 0, 0 }, -// 9dc BENGALI LETTER RRA -// 9dd BENGALI LETTER RHA - { 0x9DC, 0x2, 0x9, 0, 0 }, -// 9df BENGALI LETTER YYA -// 9e0 BENGALI LETTER VOCALIC RR -// 9e1 BENGALI LETTER VOCALIC LL - { 0x9DF, 0x3, 0x9, 0, 0 }, -// 9e2 BENGALI VOWEL SIGN VOCALIC L -// 9e3 BENGALI VOWEL SIGN VOCALIC LL - { 0x9E2, 0x2, 0x0, 0, 0 }, -// 9e6 BENGALI DIGIT ZERO -// 9e7 BENGALI DIGIT ONE -// 9e8 BENGALI DIGIT TWO -// 9e9 BENGALI DIGIT THREE -// 9ea BENGALI DIGIT FOUR -// 9eb BENGALI DIGIT FIVE -// 9ec BENGALI DIGIT SIX -// 9ed BENGALI DIGIT SEVEN -// 9ee BENGALI DIGIT EIGHT -// 9ef BENGALI DIGIT NINE - { 0x9E6, 0xA, 0x108, 0, 0 }, -// 9f0 BENGALI LETTER RA WITH MIDDLE DIAGONAL -// 9f1 BENGALI LETTER RA WITH LOWER DIAGONAL - { 0x9F0, 0x2, 0x9, 0, 0 }, -// 9f2 BENGALI RUPEE MARK -// 9f3 BENGALI RUPEE SIGN -// 9f4 BENGALI CURRENCY NUMERATOR ONE -// 9f5 BENGALI CURRENCY NUMERATOR TWO -// 9f6 BENGALI CURRENCY NUMERATOR THREE -// 9f7 BENGALI CURRENCY NUMERATOR FOUR -// 9f8 BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR -// 9f9 BENGALI CURRENCY DENOMINATOR SIXTEEN -// 9fa BENGALI ISSHAR -// 9fb BENGALI GANDA MARK - { 0x9F2, 0xA, 0x8, 0, 0 }, -// a01 GURMUKHI SIGN ADAK BINDI -// a02 GURMUKHI SIGN BINDI -// a03 GURMUKHI SIGN VISARGA - { 0xA01, 0x3, 0x0, 0, 0 }, -// a05 GURMUKHI LETTER A -// a06 GURMUKHI LETTER AA -// a07 GURMUKHI LETTER I -// a08 GURMUKHI LETTER II -// a09 GURMUKHI LETTER U -// a0a GURMUKHI LETTER UU - { 0xA05, 0x6, 0x9, 0, 0 }, -// a0f GURMUKHI LETTER EE -// a10 GURMUKHI LETTER AI - { 0xA0F, 0x2, 0x9, 0, 0 }, -// a13 GURMUKHI LETTER OO -// a14 GURMUKHI LETTER AU -// a15 GURMUKHI LETTER KA -// a16 GURMUKHI LETTER KHA -// a17 GURMUKHI LETTER GA -// a18 GURMUKHI LETTER GHA -// a19 GURMUKHI LETTER NGA -// a1a GURMUKHI LETTER CA -// a1b GURMUKHI LETTER CHA -// a1c GURMUKHI LETTER JA -// a1d GURMUKHI LETTER JHA -// a1e GURMUKHI LETTER NYA -// a1f GURMUKHI LETTER TTA -// a20 GURMUKHI LETTER TTHA -// a21 GURMUKHI LETTER DDA -// a22 GURMUKHI LETTER DDHA -// a23 GURMUKHI LETTER NNA -// a24 GURMUKHI LETTER TA -// a25 GURMUKHI LETTER THA -// a26 GURMUKHI LETTER DA -// a27 GURMUKHI LETTER DHA -// a28 GURMUKHI LETTER NA - { 0xA13, 0x16, 0x9, 0, 0 }, -// a2a GURMUKHI LETTER PA -// a2b GURMUKHI LETTER PHA -// a2c GURMUKHI LETTER BA -// a2d GURMUKHI LETTER BHA -// a2e GURMUKHI LETTER MA -// a2f GURMUKHI LETTER YA -// a30 GURMUKHI LETTER RA - { 0xA2A, 0x7, 0x9, 0, 0 }, -// a32 GURMUKHI LETTER LA -// a33 GURMUKHI LETTER LLA - { 0xA32, 0x2, 0x9, 0, 0 }, -// a35 GURMUKHI LETTER VA -// a36 GURMUKHI LETTER SHA - { 0xA35, 0x2, 0x9, 0, 0 }, -// a38 GURMUKHI LETTER SA -// a39 GURMUKHI LETTER HA - { 0xA38, 0x2, 0x9, 0, 0 }, -// a3c GURMUKHI SIGN NUKTA - { 0xA3C, 0x1, 0x0, 0, 0 }, -// a3e GURMUKHI VOWEL SIGN AA -// a3f GURMUKHI VOWEL SIGN I -// a40 GURMUKHI VOWEL SIGN II -// a41 GURMUKHI VOWEL SIGN U -// a42 GURMUKHI VOWEL SIGN UU - { 0xA3E, 0x5, 0x0, 0, 0 }, -// a47 GURMUKHI VOWEL SIGN EE -// a48 GURMUKHI VOWEL SIGN AI - { 0xA47, 0x2, 0x0, 0, 0 }, -// a4b GURMUKHI VOWEL SIGN OO -// a4c GURMUKHI VOWEL SIGN AU -// a4d GURMUKHI SIGN VIRAMA - { 0xA4B, 0x3, 0x0, 0, 0 }, -// a51 GURMUKHI SIGN UDAAT - { 0xA51, 0x1, 0x0, 0, 0 }, -// a59 GURMUKHI LETTER KHHA -// a5a GURMUKHI LETTER GHHA -// a5b GURMUKHI LETTER ZA -// a5c GURMUKHI LETTER RRA - { 0xA59, 0x4, 0x9, 0, 0 }, -// a5e GURMUKHI LETTER FA - { 0xA5E, 0x1, 0x9, 0, 0 }, -// a66 GURMUKHI DIGIT ZERO -// a67 GURMUKHI DIGIT ONE -// a68 GURMUKHI DIGIT TWO -// a69 GURMUKHI DIGIT THREE -// a6a GURMUKHI DIGIT FOUR -// a6b GURMUKHI DIGIT FIVE -// a6c GURMUKHI DIGIT SIX -// a6d GURMUKHI DIGIT SEVEN -// a6e GURMUKHI DIGIT EIGHT -// a6f GURMUKHI DIGIT NINE - { 0xA66, 0xA, 0x108, 0, 0 }, -// a70 GURMUKHI TIPPI -// a71 GURMUKHI ADDAK - { 0xA70, 0x2, 0x0, 0, 0 }, -// a72 GURMUKHI IRI -// a73 GURMUKHI URA -// a74 GURMUKHI EK ONKAR - { 0xA72, 0x3, 0x9, 0, 0 }, -// a75 GURMUKHI SIGN YAKASH - { 0xA75, 0x1, 0x0, 0, 0 }, -// a81 GUJARATI SIGN CANDRABINDU -// a82 GUJARATI SIGN ANUSVARA -// a83 GUJARATI SIGN VISARGA - { 0xA81, 0x3, 0x0, 0, 0 }, -// a85 GUJARATI LETTER A -// a86 GUJARATI LETTER AA -// a87 GUJARATI LETTER I -// a88 GUJARATI LETTER II -// a89 GUJARATI LETTER U -// a8a GUJARATI LETTER UU -// a8b GUJARATI LETTER VOCALIC R -// a8c GUJARATI LETTER VOCALIC L -// a8d GUJARATI VOWEL CANDRA E - { 0xA85, 0x9, 0x9, 0, 0 }, -// a8f GUJARATI LETTER E -// a90 GUJARATI LETTER AI -// a91 GUJARATI VOWEL CANDRA O - { 0xA8F, 0x3, 0x9, 0, 0 }, -// a93 GUJARATI LETTER O -// a94 GUJARATI LETTER AU -// a95 GUJARATI LETTER KA -// a96 GUJARATI LETTER KHA -// a97 GUJARATI LETTER GA -// a98 GUJARATI LETTER GHA -// a99 GUJARATI LETTER NGA -// a9a GUJARATI LETTER CA -// a9b GUJARATI LETTER CHA -// a9c GUJARATI LETTER JA -// a9d GUJARATI LETTER JHA -// a9e GUJARATI LETTER NYA -// a9f GUJARATI LETTER TTA -// aa0 GUJARATI LETTER TTHA -// aa1 GUJARATI LETTER DDA -// aa2 GUJARATI LETTER DDHA -// aa3 GUJARATI LETTER NNA -// aa4 GUJARATI LETTER TA -// aa5 GUJARATI LETTER THA -// aa6 GUJARATI LETTER DA -// aa7 GUJARATI LETTER DHA -// aa8 GUJARATI LETTER NA - { 0xA93, 0x16, 0x9, 0, 0 }, -// aaa GUJARATI LETTER PA -// aab GUJARATI LETTER PHA -// aac GUJARATI LETTER BA -// aad GUJARATI LETTER BHA -// aae GUJARATI LETTER MA -// aaf GUJARATI LETTER YA -// ab0 GUJARATI LETTER RA - { 0xAAA, 0x7, 0x9, 0, 0 }, -// ab2 GUJARATI LETTER LA -// ab3 GUJARATI LETTER LLA - { 0xAB2, 0x2, 0x9, 0, 0 }, -// ab5 GUJARATI LETTER VA -// ab6 GUJARATI LETTER SHA -// ab7 GUJARATI LETTER SSA -// ab8 GUJARATI LETTER SA -// ab9 GUJARATI LETTER HA - { 0xAB5, 0x5, 0x9, 0, 0 }, -// abc GUJARATI SIGN NUKTA - { 0xABC, 0x1, 0x0, 0, 0 }, -// abd GUJARATI SIGN AVAGRAHA - { 0xABD, 0x1, 0x9, 0, 0 }, -// abe GUJARATI VOWEL SIGN AA -// abf GUJARATI VOWEL SIGN I -// ac0 GUJARATI VOWEL SIGN II -// ac1 GUJARATI VOWEL SIGN U -// ac2 GUJARATI VOWEL SIGN UU -// ac3 GUJARATI VOWEL SIGN VOCALIC R -// ac4 GUJARATI VOWEL SIGN VOCALIC RR -// ac5 GUJARATI VOWEL SIGN CANDRA E - { 0xABE, 0x8, 0x0, 0, 0 }, -// ac7 GUJARATI VOWEL SIGN E -// ac8 GUJARATI VOWEL SIGN AI -// ac9 GUJARATI VOWEL SIGN CANDRA O - { 0xAC7, 0x3, 0x0, 0, 0 }, -// acb GUJARATI VOWEL SIGN O -// acc GUJARATI VOWEL SIGN AU -// acd GUJARATI SIGN VIRAMA - { 0xACB, 0x3, 0x0, 0, 0 }, -// ad0 GUJARATI OM - { 0xAD0, 0x1, 0x9, 0, 0 }, -// ae0 GUJARATI LETTER VOCALIC RR -// ae1 GUJARATI LETTER VOCALIC LL - { 0xAE0, 0x2, 0x9, 0, 0 }, -// ae2 GUJARATI VOWEL SIGN VOCALIC L -// ae3 GUJARATI VOWEL SIGN VOCALIC LL - { 0xAE2, 0x2, 0x0, 0, 0 }, -// ae6 GUJARATI DIGIT ZERO -// ae7 GUJARATI DIGIT ONE -// ae8 GUJARATI DIGIT TWO -// ae9 GUJARATI DIGIT THREE -// aea GUJARATI DIGIT FOUR -// aeb GUJARATI DIGIT FIVE -// aec GUJARATI DIGIT SIX -// aed GUJARATI DIGIT SEVEN -// aee GUJARATI DIGIT EIGHT -// aef GUJARATI DIGIT NINE - { 0xAE6, 0xA, 0x108, 0, 0 }, -// af0 GUJARATI ABBREVIATION SIGN - { 0xAF0, 0x1, 0x18, 0, 0 }, -// af1 GUJARATI RUPEE SIGN - { 0xAF1, 0x1, 0x8, 0, 0 }, -// b01 ORIYA SIGN CANDRABINDU -// b02 ORIYA SIGN ANUSVARA -// b03 ORIYA SIGN VISARGA - { 0xB01, 0x3, 0x0, 0, 0 }, -// b05 ORIYA LETTER A -// b06 ORIYA LETTER AA -// b07 ORIYA LETTER I -// b08 ORIYA LETTER II -// b09 ORIYA LETTER U -// b0a ORIYA LETTER UU -// b0b ORIYA LETTER VOCALIC R -// b0c ORIYA LETTER VOCALIC L - { 0xB05, 0x8, 0x9, 0, 0 }, -// b0f ORIYA LETTER E -// b10 ORIYA LETTER AI - { 0xB0F, 0x2, 0x9, 0, 0 }, -// b13 ORIYA LETTER O -// b14 ORIYA LETTER AU -// b15 ORIYA LETTER KA -// b16 ORIYA LETTER KHA -// b17 ORIYA LETTER GA -// b18 ORIYA LETTER GHA -// b19 ORIYA LETTER NGA -// b1a ORIYA LETTER CA -// b1b ORIYA LETTER CHA -// b1c ORIYA LETTER JA -// b1d ORIYA LETTER JHA -// b1e ORIYA LETTER NYA -// b1f ORIYA LETTER TTA -// b20 ORIYA LETTER TTHA -// b21 ORIYA LETTER DDA -// b22 ORIYA LETTER DDHA -// b23 ORIYA LETTER NNA -// b24 ORIYA LETTER TA -// b25 ORIYA LETTER THA -// b26 ORIYA LETTER DA -// b27 ORIYA LETTER DHA -// b28 ORIYA LETTER NA - { 0xB13, 0x16, 0x9, 0, 0 }, -// b2a ORIYA LETTER PA -// b2b ORIYA LETTER PHA -// b2c ORIYA LETTER BA -// b2d ORIYA LETTER BHA -// b2e ORIYA LETTER MA -// b2f ORIYA LETTER YA -// b30 ORIYA LETTER RA - { 0xB2A, 0x7, 0x9, 0, 0 }, -// b32 ORIYA LETTER LA -// b33 ORIYA LETTER LLA - { 0xB32, 0x2, 0x9, 0, 0 }, -// b35 ORIYA LETTER VA -// b36 ORIYA LETTER SHA -// b37 ORIYA LETTER SSA -// b38 ORIYA LETTER SA -// b39 ORIYA LETTER HA - { 0xB35, 0x5, 0x9, 0, 0 }, -// b3c ORIYA SIGN NUKTA - { 0xB3C, 0x1, 0x0, 0, 0 }, -// b3d ORIYA SIGN AVAGRAHA - { 0xB3D, 0x1, 0x9, 0, 0 }, -// b3e ORIYA VOWEL SIGN AA -// b3f ORIYA VOWEL SIGN I -// b40 ORIYA VOWEL SIGN II -// b41 ORIYA VOWEL SIGN U -// b42 ORIYA VOWEL SIGN UU -// b43 ORIYA VOWEL SIGN VOCALIC R -// b44 ORIYA VOWEL SIGN VOCALIC RR - { 0xB3E, 0x7, 0x0, 0, 0 }, -// b47 ORIYA VOWEL SIGN E -// b48 ORIYA VOWEL SIGN AI - { 0xB47, 0x2, 0x0, 0, 0 }, -// b4b ORIYA VOWEL SIGN O -// b4c ORIYA VOWEL SIGN AU -// b4d ORIYA SIGN VIRAMA - { 0xB4B, 0x3, 0x0, 0, 0 }, -// b56 ORIYA AI LENGTH MARK -// b57 ORIYA AU LENGTH MARK - { 0xB56, 0x2, 0x0, 0, 0 }, -// b5c ORIYA LETTER RRA -// b5d ORIYA LETTER RHA - { 0xB5C, 0x2, 0x9, 0, 0 }, -// b5f ORIYA LETTER YYA -// b60 ORIYA LETTER VOCALIC RR -// b61 ORIYA LETTER VOCALIC LL - { 0xB5F, 0x3, 0x9, 0, 0 }, -// b62 ORIYA VOWEL SIGN VOCALIC L -// b63 ORIYA VOWEL SIGN VOCALIC LL - { 0xB62, 0x2, 0x0, 0, 0 }, -// b66 ORIYA DIGIT ZERO -// b67 ORIYA DIGIT ONE -// b68 ORIYA DIGIT TWO -// b69 ORIYA DIGIT THREE -// b6a ORIYA DIGIT FOUR -// b6b ORIYA DIGIT FIVE -// b6c ORIYA DIGIT SIX -// b6d ORIYA DIGIT SEVEN -// b6e ORIYA DIGIT EIGHT -// b6f ORIYA DIGIT NINE - { 0xB66, 0xA, 0x108, 0, 0 }, -// b70 ORIYA ISSHAR - { 0xB70, 0x1, 0x8, 0, 0 }, -// b71 ORIYA LETTER WA - { 0xB71, 0x1, 0x9, 0, 0 }, -// b72 ORIYA FRACTION ONE QUARTER -// b73 ORIYA FRACTION ONE HALF -// b74 ORIYA FRACTION THREE QUARTERS -// b75 ORIYA FRACTION ONE SIXTEENTH -// b76 ORIYA FRACTION ONE EIGHTH -// b77 ORIYA FRACTION THREE SIXTEENTHS - { 0xB72, 0x6, 0x8, 0, 0 }, -// b82 TAMIL SIGN ANUSVARA - { 0xB82, 0x1, 0x0, 0, 0 }, -// b83 TAMIL SIGN VISARGA - { 0xB83, 0x1, 0x9, 0, 0 }, -// b85 TAMIL LETTER A -// b86 TAMIL LETTER AA -// b87 TAMIL LETTER I -// b88 TAMIL LETTER II -// b89 TAMIL LETTER U -// b8a TAMIL LETTER UU - { 0xB85, 0x6, 0x9, 0, 0 }, -// b8e TAMIL LETTER E -// b8f TAMIL LETTER EE -// b90 TAMIL LETTER AI - { 0xB8E, 0x3, 0x9, 0, 0 }, -// b92 TAMIL LETTER O -// b93 TAMIL LETTER OO -// b94 TAMIL LETTER AU -// b95 TAMIL LETTER KA - { 0xB92, 0x4, 0x9, 0, 0 }, -// b99 TAMIL LETTER NGA -// b9a TAMIL LETTER CA - { 0xB99, 0x2, 0x9, 0, 0 }, -// b9c TAMIL LETTER JA - { 0xB9C, 0x1, 0x9, 0, 0 }, -// b9e TAMIL LETTER NYA -// b9f TAMIL LETTER TTA - { 0xB9E, 0x2, 0x9, 0, 0 }, -// ba3 TAMIL LETTER NNA -// ba4 TAMIL LETTER TA - { 0xBA3, 0x2, 0x9, 0, 0 }, -// ba8 TAMIL LETTER NA -// ba9 TAMIL LETTER NNNA -// baa TAMIL LETTER PA - { 0xBA8, 0x3, 0x9, 0, 0 }, -// bae TAMIL LETTER MA -// baf TAMIL LETTER YA -// bb0 TAMIL LETTER RA -// bb1 TAMIL LETTER RRA -// bb2 TAMIL LETTER LA -// bb3 TAMIL LETTER LLA -// bb4 TAMIL LETTER LLLA -// bb5 TAMIL LETTER VA -// bb6 TAMIL LETTER SHA -// bb7 TAMIL LETTER SSA -// bb8 TAMIL LETTER SA -// bb9 TAMIL LETTER HA - { 0xBAE, 0xC, 0x9, 0, 0 }, -// bbe TAMIL VOWEL SIGN AA -// bbf TAMIL VOWEL SIGN I -// bc0 TAMIL VOWEL SIGN II -// bc1 TAMIL VOWEL SIGN U -// bc2 TAMIL VOWEL SIGN UU - { 0xBBE, 0x5, 0x0, 0, 0 }, -// bc6 TAMIL VOWEL SIGN E -// bc7 TAMIL VOWEL SIGN EE -// bc8 TAMIL VOWEL SIGN AI - { 0xBC6, 0x3, 0x0, 0, 0 }, -// bca TAMIL VOWEL SIGN O -// bcb TAMIL VOWEL SIGN OO -// bcc TAMIL VOWEL SIGN AU -// bcd TAMIL SIGN VIRAMA - { 0xBCA, 0x4, 0x0, 0, 0 }, -// bd0 TAMIL OM - { 0xBD0, 0x1, 0x9, 0, 0 }, -// bd7 TAMIL AU LENGTH MARK - { 0xBD7, 0x1, 0x0, 0, 0 }, -// be6 TAMIL DIGIT ZERO -// be7 TAMIL DIGIT ONE -// be8 TAMIL DIGIT TWO -// be9 TAMIL DIGIT THREE -// bea TAMIL DIGIT FOUR -// beb TAMIL DIGIT FIVE -// bec TAMIL DIGIT SIX -// bed TAMIL DIGIT SEVEN -// bee TAMIL DIGIT EIGHT -// bef TAMIL DIGIT NINE - { 0xBE6, 0xA, 0x108, 0, 0 }, -// bf0 TAMIL NUMBER TEN -// bf1 TAMIL NUMBER ONE HUNDRED -// bf2 TAMIL NUMBER ONE THOUSAND -// bf3 TAMIL DAY SIGN -// bf4 TAMIL MONTH SIGN -// bf5 TAMIL YEAR SIGN -// bf6 TAMIL DEBIT SIGN -// bf7 TAMIL CREDIT SIGN -// bf8 TAMIL AS ABOVE SIGN -// bf9 TAMIL RUPEE SIGN -// bfa TAMIL NUMBER SIGN - { 0xBF0, 0xB, 0x8, 0, 0 }, -// c00 TELUGU SIGN COMBINING CANDRABINDU ABOVE -// c01 TELUGU SIGN CANDRABINDU -// c02 TELUGU SIGN ANUSVARA -// c03 TELUGU SIGN VISARGA - { 0xC00, 0x4, 0x0, 0, 0 }, -// c05 TELUGU LETTER A -// c06 TELUGU LETTER AA -// c07 TELUGU LETTER I -// c08 TELUGU LETTER II -// c09 TELUGU LETTER U -// c0a TELUGU LETTER UU -// c0b TELUGU LETTER VOCALIC R -// c0c TELUGU LETTER VOCALIC L - { 0xC05, 0x8, 0x9, 0, 0 }, -// c0e TELUGU LETTER E -// c0f TELUGU LETTER EE -// c10 TELUGU LETTER AI - { 0xC0E, 0x3, 0x9, 0, 0 }, -// c12 TELUGU LETTER O -// c13 TELUGU LETTER OO -// c14 TELUGU LETTER AU -// c15 TELUGU LETTER KA -// c16 TELUGU LETTER KHA -// c17 TELUGU LETTER GA -// c18 TELUGU LETTER GHA -// c19 TELUGU LETTER NGA -// c1a TELUGU LETTER CA -// c1b TELUGU LETTER CHA -// c1c TELUGU LETTER JA -// c1d TELUGU LETTER JHA -// c1e TELUGU LETTER NYA -// c1f TELUGU LETTER TTA -// c20 TELUGU LETTER TTHA -// c21 TELUGU LETTER DDA -// c22 TELUGU LETTER DDHA -// c23 TELUGU LETTER NNA -// c24 TELUGU LETTER TA -// c25 TELUGU LETTER THA -// c26 TELUGU LETTER DA -// c27 TELUGU LETTER DHA -// c28 TELUGU LETTER NA - { 0xC12, 0x17, 0x9, 0, 0 }, -// c2a TELUGU LETTER PA -// c2b TELUGU LETTER PHA -// c2c TELUGU LETTER BA -// c2d TELUGU LETTER BHA -// c2e TELUGU LETTER MA -// c2f TELUGU LETTER YA -// c30 TELUGU LETTER RA -// c31 TELUGU LETTER RRA -// c32 TELUGU LETTER LA -// c33 TELUGU LETTER LLA -// c34 TELUGU LETTER LLLA -// c35 TELUGU LETTER VA -// c36 TELUGU LETTER SHA -// c37 TELUGU LETTER SSA -// c38 TELUGU LETTER SA -// c39 TELUGU LETTER HA - { 0xC2A, 0x10, 0x9, 0, 0 }, -// c3d TELUGU SIGN AVAGRAHA - { 0xC3D, 0x1, 0x9, 0, 0 }, -// c3e TELUGU VOWEL SIGN AA -// c3f TELUGU VOWEL SIGN I -// c40 TELUGU VOWEL SIGN II -// c41 TELUGU VOWEL SIGN U -// c42 TELUGU VOWEL SIGN UU -// c43 TELUGU VOWEL SIGN VOCALIC R -// c44 TELUGU VOWEL SIGN VOCALIC RR - { 0xC3E, 0x7, 0x0, 0, 0 }, -// c46 TELUGU VOWEL SIGN E -// c47 TELUGU VOWEL SIGN EE -// c48 TELUGU VOWEL SIGN AI - { 0xC46, 0x3, 0x0, 0, 0 }, -// c4a TELUGU VOWEL SIGN O -// c4b TELUGU VOWEL SIGN OO -// c4c TELUGU VOWEL SIGN AU -// c4d TELUGU SIGN VIRAMA - { 0xC4A, 0x4, 0x0, 0, 0 }, -// c55 TELUGU LENGTH MARK -// c56 TELUGU AI LENGTH MARK - { 0xC55, 0x2, 0x0, 0, 0 }, -// c58 TELUGU LETTER TSA -// c59 TELUGU LETTER DZA - { 0xC58, 0x2, 0x9, 0, 0 }, -// c60 TELUGU LETTER VOCALIC RR -// c61 TELUGU LETTER VOCALIC LL - { 0xC60, 0x2, 0x9, 0, 0 }, -// c62 TELUGU VOWEL SIGN VOCALIC L -// c63 TELUGU VOWEL SIGN VOCALIC LL - { 0xC62, 0x2, 0x0, 0, 0 }, -// c66 TELUGU DIGIT ZERO -// c67 TELUGU DIGIT ONE -// c68 TELUGU DIGIT TWO -// c69 TELUGU DIGIT THREE -// c6a TELUGU DIGIT FOUR -// c6b TELUGU DIGIT FIVE -// c6c TELUGU DIGIT SIX -// c6d TELUGU DIGIT SEVEN -// c6e TELUGU DIGIT EIGHT -// c6f TELUGU DIGIT NINE - { 0xC66, 0xA, 0x108, 0, 0 }, -// c78 TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR -// c79 TELUGU FRACTION DIGIT ONE FOR ODD POWERS OF FOUR -// c7a TELUGU FRACTION DIGIT TWO FOR ODD POWERS OF FOUR -// c7b TELUGU FRACTION DIGIT THREE FOR ODD POWERS OF FOUR -// c7c TELUGU FRACTION DIGIT ONE FOR EVEN POWERS OF FOUR -// c7d TELUGU FRACTION DIGIT TWO FOR EVEN POWERS OF FOUR -// c7e TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR -// c7f TELUGU SIGN TUUMU - { 0xC78, 0x8, 0x8, 0, 0 }, -// c81 KANNADA SIGN CANDRABINDU -// c82 KANNADA SIGN ANUSVARA -// c83 KANNADA SIGN VISARGA - { 0xC81, 0x3, 0x0, 0, 0 }, -// c85 KANNADA LETTER A -// c86 KANNADA LETTER AA -// c87 KANNADA LETTER I -// c88 KANNADA LETTER II -// c89 KANNADA LETTER U -// c8a KANNADA LETTER UU -// c8b KANNADA LETTER VOCALIC R -// c8c KANNADA LETTER VOCALIC L - { 0xC85, 0x8, 0x9, 0, 0 }, -// c8e KANNADA LETTER E -// c8f KANNADA LETTER EE -// c90 KANNADA LETTER AI - { 0xC8E, 0x3, 0x9, 0, 0 }, -// c92 KANNADA LETTER O -// c93 KANNADA LETTER OO -// c94 KANNADA LETTER AU -// c95 KANNADA LETTER KA -// c96 KANNADA LETTER KHA -// c97 KANNADA LETTER GA -// c98 KANNADA LETTER GHA -// c99 KANNADA LETTER NGA -// c9a KANNADA LETTER CA -// c9b KANNADA LETTER CHA -// c9c KANNADA LETTER JA -// c9d KANNADA LETTER JHA -// c9e KANNADA LETTER NYA -// c9f KANNADA LETTER TTA -// ca0 KANNADA LETTER TTHA -// ca1 KANNADA LETTER DDA -// ca2 KANNADA LETTER DDHA -// ca3 KANNADA LETTER NNA -// ca4 KANNADA LETTER TA -// ca5 KANNADA LETTER THA -// ca6 KANNADA LETTER DA -// ca7 KANNADA LETTER DHA -// ca8 KANNADA LETTER NA - { 0xC92, 0x17, 0x9, 0, 0 }, -// caa KANNADA LETTER PA -// cab KANNADA LETTER PHA -// cac KANNADA LETTER BA -// cad KANNADA LETTER BHA -// cae KANNADA LETTER MA -// caf KANNADA LETTER YA -// cb0 KANNADA LETTER RA -// cb1 KANNADA LETTER RRA -// cb2 KANNADA LETTER LA -// cb3 KANNADA LETTER LLA - { 0xCAA, 0xA, 0x9, 0, 0 }, -// cb5 KANNADA LETTER VA -// cb6 KANNADA LETTER SHA -// cb7 KANNADA LETTER SSA -// cb8 KANNADA LETTER SA -// cb9 KANNADA LETTER HA - { 0xCB5, 0x5, 0x9, 0, 0 }, -// cbc KANNADA SIGN NUKTA - { 0xCBC, 0x1, 0x0, 0, 0 }, -// cbd KANNADA SIGN AVAGRAHA - { 0xCBD, 0x1, 0x9, 0, 0 }, -// cbe KANNADA VOWEL SIGN AA -// cbf KANNADA VOWEL SIGN I -// cc0 KANNADA VOWEL SIGN II -// cc1 KANNADA VOWEL SIGN U -// cc2 KANNADA VOWEL SIGN UU -// cc3 KANNADA VOWEL SIGN VOCALIC R -// cc4 KANNADA VOWEL SIGN VOCALIC RR - { 0xCBE, 0x7, 0x0, 0, 0 }, -// cc6 KANNADA VOWEL SIGN E -// cc7 KANNADA VOWEL SIGN EE -// cc8 KANNADA VOWEL SIGN AI - { 0xCC6, 0x3, 0x0, 0, 0 }, -// cca KANNADA VOWEL SIGN O -// ccb KANNADA VOWEL SIGN OO -// ccc KANNADA VOWEL SIGN AU -// ccd KANNADA SIGN VIRAMA - { 0xCCA, 0x4, 0x0, 0, 0 }, -// cd5 KANNADA LENGTH MARK -// cd6 KANNADA AI LENGTH MARK - { 0xCD5, 0x2, 0x0, 0, 0 }, -// cde KANNADA LETTER FA - { 0xCDE, 0x1, 0x9, 0, 0 }, -// ce0 KANNADA LETTER VOCALIC RR -// ce1 KANNADA LETTER VOCALIC LL - { 0xCE0, 0x2, 0x9, 0, 0 }, -// ce2 KANNADA VOWEL SIGN VOCALIC L -// ce3 KANNADA VOWEL SIGN VOCALIC LL - { 0xCE2, 0x2, 0x0, 0, 0 }, -// ce6 KANNADA DIGIT ZERO -// ce7 KANNADA DIGIT ONE -// ce8 KANNADA DIGIT TWO -// ce9 KANNADA DIGIT THREE -// cea KANNADA DIGIT FOUR -// ceb KANNADA DIGIT FIVE -// cec KANNADA DIGIT SIX -// ced KANNADA DIGIT SEVEN -// cee KANNADA DIGIT EIGHT -// cef KANNADA DIGIT NINE - { 0xCE6, 0xA, 0x108, 0, 0 }, -// cf1 KANNADA SIGN JIHVAMULIYA -// cf2 KANNADA SIGN UPADHMANIYA - { 0xCF1, 0x2, 0x9, 0, 0 }, -// d01 MALAYALAM SIGN CANDRABINDU -// d02 MALAYALAM SIGN ANUSVARA -// d03 MALAYALAM SIGN VISARGA - { 0xD01, 0x3, 0x0, 0, 0 }, -// d05 MALAYALAM LETTER A -// d06 MALAYALAM LETTER AA -// d07 MALAYALAM LETTER I -// d08 MALAYALAM LETTER II -// d09 MALAYALAM LETTER U -// d0a MALAYALAM LETTER UU -// d0b MALAYALAM LETTER VOCALIC R -// d0c MALAYALAM LETTER VOCALIC L - { 0xD05, 0x8, 0x9, 0, 0 }, -// d0e MALAYALAM LETTER E -// d0f MALAYALAM LETTER EE -// d10 MALAYALAM LETTER AI - { 0xD0E, 0x3, 0x9, 0, 0 }, -// d12 MALAYALAM LETTER O -// d13 MALAYALAM LETTER OO -// d14 MALAYALAM LETTER AU -// d15 MALAYALAM LETTER KA -// d16 MALAYALAM LETTER KHA -// d17 MALAYALAM LETTER GA -// d18 MALAYALAM LETTER GHA -// d19 MALAYALAM LETTER NGA -// d1a MALAYALAM LETTER CA -// d1b MALAYALAM LETTER CHA -// d1c MALAYALAM LETTER JA -// d1d MALAYALAM LETTER JHA -// d1e MALAYALAM LETTER NYA -// d1f MALAYALAM LETTER TTA -// d20 MALAYALAM LETTER TTHA -// d21 MALAYALAM LETTER DDA -// d22 MALAYALAM LETTER DDHA -// d23 MALAYALAM LETTER NNA -// d24 MALAYALAM LETTER TA -// d25 MALAYALAM LETTER THA -// d26 MALAYALAM LETTER DA -// d27 MALAYALAM LETTER DHA -// d28 MALAYALAM LETTER NA -// d29 MALAYALAM LETTER NNNA -// d2a MALAYALAM LETTER PA -// d2b MALAYALAM LETTER PHA -// d2c MALAYALAM LETTER BA -// d2d MALAYALAM LETTER BHA -// d2e MALAYALAM LETTER MA -// d2f MALAYALAM LETTER YA -// d30 MALAYALAM LETTER RA -// d31 MALAYALAM LETTER RRA -// d32 MALAYALAM LETTER LA -// d33 MALAYALAM LETTER LLA -// d34 MALAYALAM LETTER LLLA -// d35 MALAYALAM LETTER VA -// d36 MALAYALAM LETTER SHA -// d37 MALAYALAM LETTER SSA -// d38 MALAYALAM LETTER SA -// d39 MALAYALAM LETTER HA -// d3a MALAYALAM LETTER TTTA - { 0xD12, 0x29, 0x9, 0, 0 }, -// d3d MALAYALAM SIGN AVAGRAHA - { 0xD3D, 0x1, 0x9, 0, 0 }, -// d3e MALAYALAM VOWEL SIGN AA -// d3f MALAYALAM VOWEL SIGN I -// d40 MALAYALAM VOWEL SIGN II -// d41 MALAYALAM VOWEL SIGN U -// d42 MALAYALAM VOWEL SIGN UU -// d43 MALAYALAM VOWEL SIGN VOCALIC R -// d44 MALAYALAM VOWEL SIGN VOCALIC RR - { 0xD3E, 0x7, 0x0, 0, 0 }, -// d46 MALAYALAM VOWEL SIGN E -// d47 MALAYALAM VOWEL SIGN EE -// d48 MALAYALAM VOWEL SIGN AI - { 0xD46, 0x3, 0x0, 0, 0 }, -// d4a MALAYALAM VOWEL SIGN O -// d4b MALAYALAM VOWEL SIGN OO -// d4c MALAYALAM VOWEL SIGN AU -// d4d MALAYALAM SIGN VIRAMA - { 0xD4A, 0x4, 0x0, 0, 0 }, -// d4e MALAYALAM LETTER DOT REPH - { 0xD4E, 0x1, 0x9, 0, 0 }, -// d57 MALAYALAM AU LENGTH MARK - { 0xD57, 0x1, 0x0, 0, 0 }, -// d60 MALAYALAM LETTER VOCALIC RR -// d61 MALAYALAM LETTER VOCALIC LL - { 0xD60, 0x2, 0x9, 0, 0 }, -// d62 MALAYALAM VOWEL SIGN VOCALIC L -// d63 MALAYALAM VOWEL SIGN VOCALIC LL - { 0xD62, 0x2, 0x0, 0, 0 }, -// d66 MALAYALAM DIGIT ZERO -// d67 MALAYALAM DIGIT ONE -// d68 MALAYALAM DIGIT TWO -// d69 MALAYALAM DIGIT THREE -// d6a MALAYALAM DIGIT FOUR -// d6b MALAYALAM DIGIT FIVE -// d6c MALAYALAM DIGIT SIX -// d6d MALAYALAM DIGIT SEVEN -// d6e MALAYALAM DIGIT EIGHT -// d6f MALAYALAM DIGIT NINE - { 0xD66, 0xA, 0x108, 0, 0 }, -// d70 MALAYALAM NUMBER TEN -// d71 MALAYALAM NUMBER ONE HUNDRED -// d72 MALAYALAM NUMBER ONE THOUSAND -// d73 MALAYALAM FRACTION ONE QUARTER -// d74 MALAYALAM FRACTION ONE HALF -// d75 MALAYALAM FRACTION THREE QUARTERS - { 0xD70, 0x6, 0x8, 0, 0 }, -// d79 MALAYALAM DATE MARK - { 0xD79, 0x1, 0x8, 0, 0 }, -// d7a MALAYALAM LETTER CHILLU NN -// d7b MALAYALAM LETTER CHILLU N -// d7c MALAYALAM LETTER CHILLU RR -// d7d MALAYALAM LETTER CHILLU L -// d7e MALAYALAM LETTER CHILLU LL -// d7f MALAYALAM LETTER CHILLU K - { 0xD7A, 0x6, 0x9, 0, 0 }, -// d82 SINHALA SIGN ANUSVARAYA -// d83 SINHALA SIGN VISARGAYA - { 0xD82, 0x2, 0x0, 0, 0 }, -// d85 SINHALA LETTER AYANNA -// d86 SINHALA LETTER AAYANNA -// d87 SINHALA LETTER AEYANNA -// d88 SINHALA LETTER AEEYANNA -// d89 SINHALA LETTER IYANNA -// d8a SINHALA LETTER IIYANNA -// d8b SINHALA LETTER UYANNA -// d8c SINHALA LETTER UUYANNA -// d8d SINHALA LETTER IRUYANNA -// d8e SINHALA LETTER IRUUYANNA -// d8f SINHALA LETTER ILUYANNA -// d90 SINHALA LETTER ILUUYANNA -// d91 SINHALA LETTER EYANNA -// d92 SINHALA LETTER EEYANNA -// d93 SINHALA LETTER AIYANNA -// d94 SINHALA LETTER OYANNA -// d95 SINHALA LETTER OOYANNA -// d96 SINHALA LETTER AUYANNA - { 0xD85, 0x12, 0x9, 0, 0 }, -// d9a SINHALA LETTER ALPAPRAANA KAYANNA -// d9b SINHALA LETTER MAHAAPRAANA KAYANNA -// d9c SINHALA LETTER ALPAPRAANA GAYANNA -// d9d SINHALA LETTER MAHAAPRAANA GAYANNA -// d9e SINHALA LETTER KANTAJA NAASIKYAYA -// d9f SINHALA LETTER SANYAKA GAYANNA -// da0 SINHALA LETTER ALPAPRAANA CAYANNA -// da1 SINHALA LETTER MAHAAPRAANA CAYANNA -// da2 SINHALA LETTER ALPAPRAANA JAYANNA -// da3 SINHALA LETTER MAHAAPRAANA JAYANNA -// da4 SINHALA LETTER TAALUJA NAASIKYAYA -// da5 SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA -// da6 SINHALA LETTER SANYAKA JAYANNA -// da7 SINHALA LETTER ALPAPRAANA TTAYANNA -// da8 SINHALA LETTER MAHAAPRAANA TTAYANNA -// da9 SINHALA LETTER ALPAPRAANA DDAYANNA -// daa SINHALA LETTER MAHAAPRAANA DDAYANNA -// dab SINHALA LETTER MUURDHAJA NAYANNA -// dac SINHALA LETTER SANYAKA DDAYANNA -// dad SINHALA LETTER ALPAPRAANA TAYANNA -// dae SINHALA LETTER MAHAAPRAANA TAYANNA -// daf SINHALA LETTER ALPAPRAANA DAYANNA -// db0 SINHALA LETTER MAHAAPRAANA DAYANNA -// db1 SINHALA LETTER DANTAJA NAYANNA - { 0xD9A, 0x18, 0x9, 0, 0 }, -// db3 SINHALA LETTER SANYAKA DAYANNA -// db4 SINHALA LETTER ALPAPRAANA PAYANNA -// db5 SINHALA LETTER MAHAAPRAANA PAYANNA -// db6 SINHALA LETTER ALPAPRAANA BAYANNA -// db7 SINHALA LETTER MAHAAPRAANA BAYANNA -// db8 SINHALA LETTER MAYANNA -// db9 SINHALA LETTER AMBA BAYANNA -// dba SINHALA LETTER YAYANNA -// dbb SINHALA LETTER RAYANNA - { 0xDB3, 0x9, 0x9, 0, 0 }, -// dbd SINHALA LETTER DANTAJA LAYANNA - { 0xDBD, 0x1, 0x9, 0, 0 }, -// dc0 SINHALA LETTER VAYANNA -// dc1 SINHALA LETTER TAALUJA SAYANNA -// dc2 SINHALA LETTER MUURDHAJA SAYANNA -// dc3 SINHALA LETTER DANTAJA SAYANNA -// dc4 SINHALA LETTER HAYANNA -// dc5 SINHALA LETTER MUURDHAJA LAYANNA -// dc6 SINHALA LETTER FAYANNA - { 0xDC0, 0x7, 0x9, 0, 0 }, -// dca SINHALA SIGN AL-LAKUNA - { 0xDCA, 0x1, 0x0, 0, 0 }, -// dcf SINHALA VOWEL SIGN AELA-PILLA -// dd0 SINHALA VOWEL SIGN KETTI AEDA-PILLA -// dd1 SINHALA VOWEL SIGN DIGA AEDA-PILLA -// dd2 SINHALA VOWEL SIGN KETTI IS-PILLA -// dd3 SINHALA VOWEL SIGN DIGA IS-PILLA -// dd4 SINHALA VOWEL SIGN KETTI PAA-PILLA - { 0xDCF, 0x6, 0x0, 0, 0 }, -// dd6 SINHALA VOWEL SIGN DIGA PAA-PILLA - { 0xDD6, 0x1, 0x0, 0, 0 }, -// dd8 SINHALA VOWEL SIGN GAETTA-PILLA -// dd9 SINHALA VOWEL SIGN KOMBUVA -// dda SINHALA VOWEL SIGN DIGA KOMBUVA -// ddb SINHALA VOWEL SIGN KOMBU DEKA -// ddc SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA -// ddd SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA -// dde SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA -// ddf SINHALA VOWEL SIGN GAYANUKITTA - { 0xDD8, 0x8, 0x0, 0, 0 }, -// de6 SINHALA LITH DIGIT ZERO -// de7 SINHALA LITH DIGIT ONE -// de8 SINHALA LITH DIGIT TWO -// de9 SINHALA LITH DIGIT THREE -// dea SINHALA LITH DIGIT FOUR -// deb SINHALA LITH DIGIT FIVE -// dec SINHALA LITH DIGIT SIX -// ded SINHALA LITH DIGIT SEVEN -// dee SINHALA LITH DIGIT EIGHT -// def SINHALA LITH DIGIT NINE - { 0xDE6, 0xA, 0x108, 0, 0 }, -// df2 SINHALA VOWEL SIGN DIGA GAETTA-PILLA -// df3 SINHALA VOWEL SIGN DIGA GAYANUKITTA - { 0xDF2, 0x2, 0x0, 0, 0 }, -// df4 SINHALA PUNCTUATION KUNDDALIYA - { 0xDF4, 0x1, 0x18, 0, 0 }, -// e01 THAI CHARACTER KO KAI -// e02 THAI CHARACTER KHO KHAI -// e03 THAI CHARACTER KHO KHUAT -// e04 THAI CHARACTER KHO KHWAI -// e05 THAI CHARACTER KHO KHON -// e06 THAI CHARACTER KHO RAKHANG -// e07 THAI CHARACTER NGO NGU -// e08 THAI CHARACTER CHO CHAN -// e09 THAI CHARACTER CHO CHING -// e0a THAI CHARACTER CHO CHANG -// e0b THAI CHARACTER SO SO -// e0c THAI CHARACTER CHO CHOE -// e0d THAI CHARACTER YO YING -// e0e THAI CHARACTER DO CHADA -// e0f THAI CHARACTER TO PATAK -// e10 THAI CHARACTER THO THAN -// e11 THAI CHARACTER THO NANGMONTHO -// e12 THAI CHARACTER THO PHUTHAO -// e13 THAI CHARACTER NO NEN -// e14 THAI CHARACTER DO DEK -// e15 THAI CHARACTER TO TAO -// e16 THAI CHARACTER THO THUNG -// e17 THAI CHARACTER THO THAHAN -// e18 THAI CHARACTER THO THONG -// e19 THAI CHARACTER NO NU -// e1a THAI CHARACTER BO BAIMAI -// e1b THAI CHARACTER PO PLA -// e1c THAI CHARACTER PHO PHUNG -// e1d THAI CHARACTER FO FA -// e1e THAI CHARACTER PHO PHAN -// e1f THAI CHARACTER FO FAN -// e20 THAI CHARACTER PHO SAMPHAO -// e21 THAI CHARACTER MO MA -// e22 THAI CHARACTER YO YAK -// e23 THAI CHARACTER RO RUA -// e24 THAI CHARACTER RU -// e25 THAI CHARACTER LO LING -// e26 THAI CHARACTER LU -// e27 THAI CHARACTER WO WAEN -// e28 THAI CHARACTER SO SALA -// e29 THAI CHARACTER SO RUSI -// e2a THAI CHARACTER SO SUA -// e2b THAI CHARACTER HO HIP -// e2c THAI CHARACTER LO CHULA -// e2d THAI CHARACTER O ANG -// e2e THAI CHARACTER HO NOKHUK -// e2f THAI CHARACTER PAIYANNOI -// e30 THAI CHARACTER SARA A - { 0xE01, 0x30, 0x9, 0, 0 }, -// e31 THAI CHARACTER MAI HAN-AKAT - { 0xE31, 0x1, 0x0, 0, 0 }, -// e32 THAI CHARACTER SARA AA -// e33 THAI CHARACTER SARA AM - { 0xE32, 0x2, 0x9, 0, 0 }, -// e34 THAI CHARACTER SARA I -// e35 THAI CHARACTER SARA II -// e36 THAI CHARACTER SARA UE -// e37 THAI CHARACTER SARA UEE -// e38 THAI CHARACTER SARA U -// e39 THAI CHARACTER SARA UU -// e3a THAI CHARACTER PHINTHU - { 0xE34, 0x7, 0x0, 0, 0 }, -// e3f THAI CURRENCY SYMBOL BAHT - { 0xE3F, 0x1, 0x8, 0, 0 }, -// e40 THAI CHARACTER SARA E -// e41 THAI CHARACTER SARA AE -// e42 THAI CHARACTER SARA O -// e43 THAI CHARACTER SARA AI MAIMUAN -// e44 THAI CHARACTER SARA AI MAIMALAI -// e45 THAI CHARACTER LAKKHANGYAO -// e46 THAI CHARACTER MAIYAMOK - { 0xE40, 0x7, 0x9, 0, 0 }, -// e47 THAI CHARACTER MAITAIKHU -// e48 THAI CHARACTER MAI EK -// e49 THAI CHARACTER MAI THO -// e4a THAI CHARACTER MAI TRI -// e4b THAI CHARACTER MAI CHATTAWA -// e4c THAI CHARACTER THANTHAKHAT -// e4d THAI CHARACTER NIKHAHIT -// e4e THAI CHARACTER YAMAKKAN - { 0xE47, 0x8, 0x0, 0, 0 }, -// e4f THAI CHARACTER FONGMAN - { 0xE4F, 0x1, 0x18, 0, 0 }, -// e50 THAI DIGIT ZERO -// e51 THAI DIGIT ONE -// e52 THAI DIGIT TWO -// e53 THAI DIGIT THREE -// e54 THAI DIGIT FOUR -// e55 THAI DIGIT FIVE -// e56 THAI DIGIT SIX -// e57 THAI DIGIT SEVEN -// e58 THAI DIGIT EIGHT -// e59 THAI DIGIT NINE - { 0xE50, 0xA, 0x108, 0, 0 }, -// e5a THAI CHARACTER ANGKHANKHU -// e5b THAI CHARACTER KHOMUT - { 0xE5A, 0x2, 0x18, 0, 0 }, -// e81 LAO LETTER KO -// e82 LAO LETTER KHO SUNG - { 0xE81, 0x2, 0x9, 0, 0 }, -// e84 LAO LETTER KHO TAM - { 0xE84, 0x1, 0x9, 0, 0 }, -// e87 LAO LETTER NGO -// e88 LAO LETTER CO - { 0xE87, 0x2, 0x9, 0, 0 }, -// e8a LAO LETTER SO TAM - { 0xE8A, 0x1, 0x9, 0, 0 }, -// e8d LAO LETTER NYO - { 0xE8D, 0x1, 0x9, 0, 0 }, -// e94 LAO LETTER DO -// e95 LAO LETTER TO -// e96 LAO LETTER THO SUNG -// e97 LAO LETTER THO TAM - { 0xE94, 0x4, 0x9, 0, 0 }, -// e99 LAO LETTER NO -// e9a LAO LETTER BO -// e9b LAO LETTER PO -// e9c LAO LETTER PHO SUNG -// e9d LAO LETTER FO TAM -// e9e LAO LETTER PHO TAM -// e9f LAO LETTER FO SUNG - { 0xE99, 0x7, 0x9, 0, 0 }, -// ea1 LAO LETTER MO -// ea2 LAO LETTER YO -// ea3 LAO LETTER LO LING - { 0xEA1, 0x3, 0x9, 0, 0 }, -// ea5 LAO LETTER LO LOOT - { 0xEA5, 0x1, 0x9, 0, 0 }, -// ea7 LAO LETTER WO - { 0xEA7, 0x1, 0x9, 0, 0 }, -// eaa LAO LETTER SO SUNG -// eab LAO LETTER HO SUNG - { 0xEAA, 0x2, 0x9, 0, 0 }, -// ead LAO LETTER O -// eae LAO LETTER HO TAM -// eaf LAO ELLIPSIS -// eb0 LAO VOWEL SIGN A - { 0xEAD, 0x4, 0x9, 0, 0 }, -// eb1 LAO VOWEL SIGN MAI KAN - { 0xEB1, 0x1, 0x0, 0, 0 }, -// eb2 LAO VOWEL SIGN AA -// eb3 LAO VOWEL SIGN AM - { 0xEB2, 0x2, 0x9, 0, 0 }, -// eb4 LAO VOWEL SIGN I -// eb5 LAO VOWEL SIGN II -// eb6 LAO VOWEL SIGN Y -// eb7 LAO VOWEL SIGN YY -// eb8 LAO VOWEL SIGN U -// eb9 LAO VOWEL SIGN UU - { 0xEB4, 0x6, 0x0, 0, 0 }, -// ebb LAO VOWEL SIGN MAI KON -// ebc LAO SEMIVOWEL SIGN LO - { 0xEBB, 0x2, 0x0, 0, 0 }, -// ebd LAO SEMIVOWEL SIGN NYO - { 0xEBD, 0x1, 0x9, 0, 0 }, -// ec0 LAO VOWEL SIGN E -// ec1 LAO VOWEL SIGN EI -// ec2 LAO VOWEL SIGN O -// ec3 LAO VOWEL SIGN AY -// ec4 LAO VOWEL SIGN AI - { 0xEC0, 0x5, 0x9, 0, 0 }, -// ec6 LAO KO LA - { 0xEC6, 0x1, 0x9, 0, 0 }, -// ec8 LAO TONE MAI EK -// ec9 LAO TONE MAI THO -// eca LAO TONE MAI TI -// ecb LAO TONE MAI CATAWA -// ecc LAO CANCELLATION MARK -// ecd LAO NIGGAHITA - { 0xEC8, 0x6, 0x0, 0, 0 }, -// ed0 LAO DIGIT ZERO -// ed1 LAO DIGIT ONE -// ed2 LAO DIGIT TWO -// ed3 LAO DIGIT THREE -// ed4 LAO DIGIT FOUR -// ed5 LAO DIGIT FIVE -// ed6 LAO DIGIT SIX -// ed7 LAO DIGIT SEVEN -// ed8 LAO DIGIT EIGHT -// ed9 LAO DIGIT NINE - { 0xED0, 0xA, 0x108, 0, 0 }, -// edc LAO HO NO -// edd LAO HO MO -// ede LAO LETTER KHMU GO -// edf LAO LETTER KHMU NYO - { 0xEDC, 0x4, 0x9, 0, 0 }, -// f00 TIBETAN SYLLABLE OM - { 0xF00, 0x1, 0x9, 0, 0 }, -// f01 TIBETAN MARK GTER YIG MGO TRUNCATED A -// f02 TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA -// f03 TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA - { 0xF01, 0x3, 0x8, 0, 0 }, -// f04 TIBETAN MARK INITIAL YIG MGO MDUN MA -// f05 TIBETAN MARK CLOSING YIG MGO SGAB MA -// f06 TIBETAN MARK CARET YIG MGO PHUR SHAD MA -// f07 TIBETAN MARK YIG MGO TSHEG SHAD MA -// f08 TIBETAN MARK SBRUL SHAD -// f09 TIBETAN MARK BSKUR YIG MGO -// f0a TIBETAN MARK BKA- SHOG YIG MGO -// f0b TIBETAN MARK INTERSYLLABIC TSHEG -// f0c TIBETAN MARK DELIMITER TSHEG BSTAR -// f0d TIBETAN MARK SHAD -// f0e TIBETAN MARK NYIS SHAD -// f0f TIBETAN MARK TSHEG SHAD -// f10 TIBETAN MARK NYIS TSHEG SHAD -// f11 TIBETAN MARK RIN CHEN SPUNGS SHAD -// f12 TIBETAN MARK RGYA GRAM SHAD - { 0xF04, 0xF, 0x18, 0, 0 }, -// f13 TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN - { 0xF13, 0x1, 0x8, 0, 0 }, -// f14 TIBETAN MARK GTER TSHEG - { 0xF14, 0x1, 0x18, 0, 0 }, -// f15 TIBETAN LOGOTYPE SIGN CHAD RTAGS -// f16 TIBETAN LOGOTYPE SIGN LHAG RTAGS -// f17 TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS - { 0xF15, 0x3, 0x8, 0, 0 }, -// f18 TIBETAN ASTROLOGICAL SIGN -KHYUD PA -// f19 TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS - { 0xF18, 0x2, 0x0, 0, 0 }, -// f1a TIBETAN SIGN RDEL DKAR GCIG -// f1b TIBETAN SIGN RDEL DKAR GNYIS -// f1c TIBETAN SIGN RDEL DKAR GSUM -// f1d TIBETAN SIGN RDEL NAG GCIG -// f1e TIBETAN SIGN RDEL NAG GNYIS -// f1f TIBETAN SIGN RDEL DKAR RDEL NAG - { 0xF1A, 0x6, 0x8, 0, 0 }, -// f20 TIBETAN DIGIT ZERO -// f21 TIBETAN DIGIT ONE -// f22 TIBETAN DIGIT TWO -// f23 TIBETAN DIGIT THREE -// f24 TIBETAN DIGIT FOUR -// f25 TIBETAN DIGIT FIVE -// f26 TIBETAN DIGIT SIX -// f27 TIBETAN DIGIT SEVEN -// f28 TIBETAN DIGIT EIGHT -// f29 TIBETAN DIGIT NINE - { 0xF20, 0xA, 0x108, 0, 0 }, -// f2a TIBETAN DIGIT HALF ONE -// f2b TIBETAN DIGIT HALF TWO -// f2c TIBETAN DIGIT HALF THREE -// f2d TIBETAN DIGIT HALF FOUR -// f2e TIBETAN DIGIT HALF FIVE -// f2f TIBETAN DIGIT HALF SIX -// f30 TIBETAN DIGIT HALF SEVEN -// f31 TIBETAN DIGIT HALF EIGHT -// f32 TIBETAN DIGIT HALF NINE -// f33 TIBETAN DIGIT HALF ZERO -// f34 TIBETAN MARK BSDUS RTAGS - { 0xF2A, 0xB, 0x8, 0, 0 }, -// f35 TIBETAN MARK NGAS BZUNG NYI ZLA - { 0xF35, 0x1, 0x0, 0, 0 }, -// f36 TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN - { 0xF36, 0x1, 0x8, 0, 0 }, -// f37 TIBETAN MARK NGAS BZUNG SGOR RTAGS - { 0xF37, 0x1, 0x0, 0, 0 }, -// f38 TIBETAN MARK CHE MGO - { 0xF38, 0x1, 0x8, 0, 0 }, -// f39 TIBETAN MARK TSA -PHRU - { 0xF39, 0x1, 0x0, 0, 0 }, -// f3a TIBETAN MARK GUG RTAGS GYON -// f3b TIBETAN MARK GUG RTAGS GYAS -// f3c TIBETAN MARK ANG KHANG GYON -// f3d TIBETAN MARK ANG KHANG GYAS - { 0xF3A, 0x4, 0x18, 0, 0 }, -// f3e TIBETAN SIGN YAR TSHES -// f3f TIBETAN SIGN MAR TSHES - { 0xF3E, 0x2, 0x0, 0, 0 }, -// f40 TIBETAN LETTER KA -// f41 TIBETAN LETTER KHA -// f42 TIBETAN LETTER GA -// f43 TIBETAN LETTER GHA -// f44 TIBETAN LETTER NGA -// f45 TIBETAN LETTER CA -// f46 TIBETAN LETTER CHA -// f47 TIBETAN LETTER JA - { 0xF40, 0x8, 0x9, 0, 0 }, -// f49 TIBETAN LETTER NYA -// f4a TIBETAN LETTER TTA -// f4b TIBETAN LETTER TTHA -// f4c TIBETAN LETTER DDA -// f4d TIBETAN LETTER DDHA -// f4e TIBETAN LETTER NNA -// f4f TIBETAN LETTER TA -// f50 TIBETAN LETTER THA -// f51 TIBETAN LETTER DA -// f52 TIBETAN LETTER DHA -// f53 TIBETAN LETTER NA -// f54 TIBETAN LETTER PA -// f55 TIBETAN LETTER PHA -// f56 TIBETAN LETTER BA -// f57 TIBETAN LETTER BHA -// f58 TIBETAN LETTER MA -// f59 TIBETAN LETTER TSA -// f5a TIBETAN LETTER TSHA -// f5b TIBETAN LETTER DZA -// f5c TIBETAN LETTER DZHA -// f5d TIBETAN LETTER WA -// f5e TIBETAN LETTER ZHA -// f5f TIBETAN LETTER ZA -// f60 TIBETAN LETTER -A -// f61 TIBETAN LETTER YA -// f62 TIBETAN LETTER RA -// f63 TIBETAN LETTER LA -// f64 TIBETAN LETTER SHA -// f65 TIBETAN LETTER SSA -// f66 TIBETAN LETTER SA -// f67 TIBETAN LETTER HA -// f68 TIBETAN LETTER A -// f69 TIBETAN LETTER KSSA -// f6a TIBETAN LETTER FIXED-FORM RA -// f6b TIBETAN LETTER KKA -// f6c TIBETAN LETTER RRA - { 0xF49, 0x24, 0x9, 0, 0 }, -// f71 TIBETAN VOWEL SIGN AA -// f72 TIBETAN VOWEL SIGN I -// f73 TIBETAN VOWEL SIGN II -// f74 TIBETAN VOWEL SIGN U -// f75 TIBETAN VOWEL SIGN UU -// f76 TIBETAN VOWEL SIGN VOCALIC R -// f77 TIBETAN VOWEL SIGN VOCALIC RR -// f78 TIBETAN VOWEL SIGN VOCALIC L -// f79 TIBETAN VOWEL SIGN VOCALIC LL -// f7a TIBETAN VOWEL SIGN E -// f7b TIBETAN VOWEL SIGN EE -// f7c TIBETAN VOWEL SIGN O -// f7d TIBETAN VOWEL SIGN OO -// f7e TIBETAN SIGN RJES SU NGA RO -// f7f TIBETAN SIGN RNAM BCAD -// f80 TIBETAN VOWEL SIGN REVERSED I -// f81 TIBETAN VOWEL SIGN REVERSED II -// f82 TIBETAN SIGN NYI ZLA NAA DA -// f83 TIBETAN SIGN SNA LDAN -// f84 TIBETAN MARK HALANTA - { 0xF71, 0x14, 0x0, 0, 0 }, -// f85 TIBETAN MARK PALUTA - { 0xF85, 0x1, 0x18, 0, 0 }, -// f86 TIBETAN SIGN LCI RTAGS -// f87 TIBETAN SIGN YANG RTAGS - { 0xF86, 0x2, 0x0, 0, 0 }, -// f88 TIBETAN SIGN LCE TSA CAN -// f89 TIBETAN SIGN MCHU CAN -// f8a TIBETAN SIGN GRU CAN RGYINGS -// f8b TIBETAN SIGN GRU MED RGYINGS -// f8c TIBETAN SIGN INVERTED MCHU CAN - { 0xF88, 0x5, 0x9, 0, 0 }, -// f8d TIBETAN SUBJOINED SIGN LCE TSA CAN -// f8e TIBETAN SUBJOINED SIGN MCHU CAN -// f8f TIBETAN SUBJOINED SIGN INVERTED MCHU CAN -// f90 TIBETAN SUBJOINED LETTER KA -// f91 TIBETAN SUBJOINED LETTER KHA -// f92 TIBETAN SUBJOINED LETTER GA -// f93 TIBETAN SUBJOINED LETTER GHA -// f94 TIBETAN SUBJOINED LETTER NGA -// f95 TIBETAN SUBJOINED LETTER CA -// f96 TIBETAN SUBJOINED LETTER CHA -// f97 TIBETAN SUBJOINED LETTER JA - { 0xF8D, 0xB, 0x0, 0, 0 }, -// f99 TIBETAN SUBJOINED LETTER NYA -// f9a TIBETAN SUBJOINED LETTER TTA -// f9b TIBETAN SUBJOINED LETTER TTHA -// f9c TIBETAN SUBJOINED LETTER DDA -// f9d TIBETAN SUBJOINED LETTER DDHA -// f9e TIBETAN SUBJOINED LETTER NNA -// f9f TIBETAN SUBJOINED LETTER TA -// fa0 TIBETAN SUBJOINED LETTER THA -// fa1 TIBETAN SUBJOINED LETTER DA -// fa2 TIBETAN SUBJOINED LETTER DHA -// fa3 TIBETAN SUBJOINED LETTER NA -// fa4 TIBETAN SUBJOINED LETTER PA -// fa5 TIBETAN SUBJOINED LETTER PHA -// fa6 TIBETAN SUBJOINED LETTER BA -// fa7 TIBETAN SUBJOINED LETTER BHA -// fa8 TIBETAN SUBJOINED LETTER MA -// fa9 TIBETAN SUBJOINED LETTER TSA -// faa TIBETAN SUBJOINED LETTER TSHA -// fab TIBETAN SUBJOINED LETTER DZA -// fac TIBETAN SUBJOINED LETTER DZHA -// fad TIBETAN SUBJOINED LETTER WA -// fae TIBETAN SUBJOINED LETTER ZHA -// faf TIBETAN SUBJOINED LETTER ZA -// fb0 TIBETAN SUBJOINED LETTER -A -// fb1 TIBETAN SUBJOINED LETTER YA -// fb2 TIBETAN SUBJOINED LETTER RA -// fb3 TIBETAN SUBJOINED LETTER LA -// fb4 TIBETAN SUBJOINED LETTER SHA -// fb5 TIBETAN SUBJOINED LETTER SSA -// fb6 TIBETAN SUBJOINED LETTER SA -// fb7 TIBETAN SUBJOINED LETTER HA -// fb8 TIBETAN SUBJOINED LETTER A -// fb9 TIBETAN SUBJOINED LETTER KSSA -// fba TIBETAN SUBJOINED LETTER FIXED-FORM WA -// fbb TIBETAN SUBJOINED LETTER FIXED-FORM YA -// fbc TIBETAN SUBJOINED LETTER FIXED-FORM RA - { 0xF99, 0x24, 0x0, 0, 0 }, -// fbe TIBETAN KU RU KHA -// fbf TIBETAN KU RU KHA BZHI MIG CAN -// fc0 TIBETAN CANTILLATION SIGN HEAVY BEAT -// fc1 TIBETAN CANTILLATION SIGN LIGHT BEAT -// fc2 TIBETAN CANTILLATION SIGN CANG TE-U -// fc3 TIBETAN CANTILLATION SIGN SBUB -CHAL -// fc4 TIBETAN SYMBOL DRIL BU -// fc5 TIBETAN SYMBOL RDO RJE - { 0xFBE, 0x8, 0x8, 0, 0 }, -// fc6 TIBETAN SYMBOL PADMA GDAN - { 0xFC6, 0x1, 0x0, 0, 0 }, -// fc7 TIBETAN SYMBOL RDO RJE RGYA GRAM -// fc8 TIBETAN SYMBOL PHUR PA -// fc9 TIBETAN SYMBOL NOR BU -// fca TIBETAN SYMBOL NOR BU NYIS -KHYIL -// fcb TIBETAN SYMBOL NOR BU GSUM -KHYIL -// fcc TIBETAN SYMBOL NOR BU BZHI -KHYIL - { 0xFC7, 0x6, 0x8, 0, 0 }, -// fce TIBETAN SIGN RDEL NAG RDEL DKAR -// fcf TIBETAN SIGN RDEL NAG GSUM - { 0xFCE, 0x2, 0x8, 0, 0 }, -// fd0 TIBETAN MARK BSKA- SHOG GI MGO RGYAN -// fd1 TIBETAN MARK MNYAM YIG GI MGO RGYAN -// fd2 TIBETAN MARK NYIS TSHEG -// fd3 TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA -// fd4 TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA - { 0xFD0, 0x5, 0x18, 0, 0 }, -// fd5 RIGHT-FACING SVASTI SIGN -// fd6 LEFT-FACING SVASTI SIGN -// fd7 RIGHT-FACING SVASTI SIGN WITH DOTS -// fd8 LEFT-FACING SVASTI SIGN WITH DOTS - { 0xFD5, 0x4, 0x8, 0, 0 }, -// fd9 TIBETAN MARK LEADING MCHAN RTAGS -// fda TIBETAN MARK TRAILING MCHAN RTAGS - { 0xFD9, 0x2, 0x18, 0, 0 }, -// 1000 MYANMAR LETTER KA -// 1001 MYANMAR LETTER KHA -// 1002 MYANMAR LETTER GA -// 1003 MYANMAR LETTER GHA -// 1004 MYANMAR LETTER NGA -// 1005 MYANMAR LETTER CA -// 1006 MYANMAR LETTER CHA -// 1007 MYANMAR LETTER JA -// 1008 MYANMAR LETTER JHA -// 1009 MYANMAR LETTER NYA -// 100a MYANMAR LETTER NNYA -// 100b MYANMAR LETTER TTA -// 100c MYANMAR LETTER TTHA -// 100d MYANMAR LETTER DDA -// 100e MYANMAR LETTER DDHA -// 100f MYANMAR LETTER NNA -// 1010 MYANMAR LETTER TA -// 1011 MYANMAR LETTER THA -// 1012 MYANMAR LETTER DA -// 1013 MYANMAR LETTER DHA -// 1014 MYANMAR LETTER NA -// 1015 MYANMAR LETTER PA -// 1016 MYANMAR LETTER PHA -// 1017 MYANMAR LETTER BA -// 1018 MYANMAR LETTER BHA -// 1019 MYANMAR LETTER MA -// 101a MYANMAR LETTER YA -// 101b MYANMAR LETTER RA -// 101c MYANMAR LETTER LA -// 101d MYANMAR LETTER WA -// 101e MYANMAR LETTER SA -// 101f MYANMAR LETTER HA -// 1020 MYANMAR LETTER LLA -// 1021 MYANMAR LETTER A -// 1022 MYANMAR LETTER SHAN A -// 1023 MYANMAR LETTER I -// 1024 MYANMAR LETTER II -// 1025 MYANMAR LETTER U -// 1026 MYANMAR LETTER UU -// 1027 MYANMAR LETTER E -// 1028 MYANMAR LETTER MON E -// 1029 MYANMAR LETTER O -// 102a MYANMAR LETTER AU - { 0x1000, 0x2B, 0x9, 0, 0 }, -// 102b MYANMAR VOWEL SIGN TALL AA -// 102c MYANMAR VOWEL SIGN AA -// 102d MYANMAR VOWEL SIGN I -// 102e MYANMAR VOWEL SIGN II -// 102f MYANMAR VOWEL SIGN U -// 1030 MYANMAR VOWEL SIGN UU -// 1031 MYANMAR VOWEL SIGN E -// 1032 MYANMAR VOWEL SIGN AI -// 1033 MYANMAR VOWEL SIGN MON II -// 1034 MYANMAR VOWEL SIGN MON O -// 1035 MYANMAR VOWEL SIGN E ABOVE -// 1036 MYANMAR SIGN ANUSVARA -// 1037 MYANMAR SIGN DOT BELOW -// 1038 MYANMAR SIGN VISARGA -// 1039 MYANMAR SIGN VIRAMA -// 103a MYANMAR SIGN ASAT -// 103b MYANMAR CONSONANT SIGN MEDIAL YA -// 103c MYANMAR CONSONANT SIGN MEDIAL RA -// 103d MYANMAR CONSONANT SIGN MEDIAL WA -// 103e MYANMAR CONSONANT SIGN MEDIAL HA - { 0x102B, 0x14, 0x0, 0, 0 }, -// 103f MYANMAR LETTER GREAT SA - { 0x103F, 0x1, 0x9, 0, 0 }, -// 1040 MYANMAR DIGIT ZERO -// 1041 MYANMAR DIGIT ONE -// 1042 MYANMAR DIGIT TWO -// 1043 MYANMAR DIGIT THREE -// 1044 MYANMAR DIGIT FOUR -// 1045 MYANMAR DIGIT FIVE -// 1046 MYANMAR DIGIT SIX -// 1047 MYANMAR DIGIT SEVEN -// 1048 MYANMAR DIGIT EIGHT -// 1049 MYANMAR DIGIT NINE - { 0x1040, 0xA, 0x108, 0, 0 }, -// 104a MYANMAR SIGN LITTLE SECTION -// 104b MYANMAR SIGN SECTION -// 104c MYANMAR SYMBOL LOCATIVE -// 104d MYANMAR SYMBOL COMPLETED -// 104e MYANMAR SYMBOL AFOREMENTIONED -// 104f MYANMAR SYMBOL GENITIVE - { 0x104A, 0x6, 0x18, 0, 0 }, -// 1050 MYANMAR LETTER SHA -// 1051 MYANMAR LETTER SSA -// 1052 MYANMAR LETTER VOCALIC R -// 1053 MYANMAR LETTER VOCALIC RR -// 1054 MYANMAR LETTER VOCALIC L -// 1055 MYANMAR LETTER VOCALIC LL - { 0x1050, 0x6, 0x9, 0, 0 }, -// 1056 MYANMAR VOWEL SIGN VOCALIC R -// 1057 MYANMAR VOWEL SIGN VOCALIC RR -// 1058 MYANMAR VOWEL SIGN VOCALIC L -// 1059 MYANMAR VOWEL SIGN VOCALIC LL - { 0x1056, 0x4, 0x0, 0, 0 }, -// 105a MYANMAR LETTER MON NGA -// 105b MYANMAR LETTER MON JHA -// 105c MYANMAR LETTER MON BBA -// 105d MYANMAR LETTER MON BBE - { 0x105A, 0x4, 0x9, 0, 0 }, -// 105e MYANMAR CONSONANT SIGN MON MEDIAL NA -// 105f MYANMAR CONSONANT SIGN MON MEDIAL MA -// 1060 MYANMAR CONSONANT SIGN MON MEDIAL LA - { 0x105E, 0x3, 0x0, 0, 0 }, -// 1061 MYANMAR LETTER SGAW KAREN SHA - { 0x1061, 0x1, 0x9, 0, 0 }, -// 1062 MYANMAR VOWEL SIGN SGAW KAREN EU -// 1063 MYANMAR TONE MARK SGAW KAREN HATHI -// 1064 MYANMAR TONE MARK SGAW KAREN KE PHO - { 0x1062, 0x3, 0x0, 0, 0 }, -// 1065 MYANMAR LETTER WESTERN PWO KAREN THA -// 1066 MYANMAR LETTER WESTERN PWO KAREN PWA - { 0x1065, 0x2, 0x9, 0, 0 }, -// 1067 MYANMAR VOWEL SIGN WESTERN PWO KAREN EU -// 1068 MYANMAR VOWEL SIGN WESTERN PWO KAREN UE -// 1069 MYANMAR SIGN WESTERN PWO KAREN TONE-1 -// 106a MYANMAR SIGN WESTERN PWO KAREN TONE-2 -// 106b MYANMAR SIGN WESTERN PWO KAREN TONE-3 -// 106c MYANMAR SIGN WESTERN PWO KAREN TONE-4 -// 106d MYANMAR SIGN WESTERN PWO KAREN TONE-5 - { 0x1067, 0x7, 0x0, 0, 0 }, -// 106e MYANMAR LETTER EASTERN PWO KAREN NNA -// 106f MYANMAR LETTER EASTERN PWO KAREN YWA -// 1070 MYANMAR LETTER EASTERN PWO KAREN GHWA - { 0x106E, 0x3, 0x9, 0, 0 }, -// 1071 MYANMAR VOWEL SIGN GEBA KAREN I -// 1072 MYANMAR VOWEL SIGN KAYAH OE -// 1073 MYANMAR VOWEL SIGN KAYAH U -// 1074 MYANMAR VOWEL SIGN KAYAH EE - { 0x1071, 0x4, 0x0, 0, 0 }, -// 1075 MYANMAR LETTER SHAN KA -// 1076 MYANMAR LETTER SHAN KHA -// 1077 MYANMAR LETTER SHAN GA -// 1078 MYANMAR LETTER SHAN CA -// 1079 MYANMAR LETTER SHAN ZA -// 107a MYANMAR LETTER SHAN NYA -// 107b MYANMAR LETTER SHAN DA -// 107c MYANMAR LETTER SHAN NA -// 107d MYANMAR LETTER SHAN PHA -// 107e MYANMAR LETTER SHAN FA -// 107f MYANMAR LETTER SHAN BA -// 1080 MYANMAR LETTER SHAN THA -// 1081 MYANMAR LETTER SHAN HA - { 0x1075, 0xD, 0x9, 0, 0 }, -// 1082 MYANMAR CONSONANT SIGN SHAN MEDIAL WA -// 1083 MYANMAR VOWEL SIGN SHAN AA -// 1084 MYANMAR VOWEL SIGN SHAN E -// 1085 MYANMAR VOWEL SIGN SHAN E ABOVE -// 1086 MYANMAR VOWEL SIGN SHAN FINAL Y -// 1087 MYANMAR SIGN SHAN TONE-2 -// 1088 MYANMAR SIGN SHAN TONE-3 -// 1089 MYANMAR SIGN SHAN TONE-5 -// 108a MYANMAR SIGN SHAN TONE-6 -// 108b MYANMAR SIGN SHAN COUNCIL TONE-2 -// 108c MYANMAR SIGN SHAN COUNCIL TONE-3 -// 108d MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE - { 0x1082, 0xC, 0x0, 0, 0 }, -// 108e MYANMAR LETTER RUMAI PALAUNG FA - { 0x108E, 0x1, 0x9, 0, 0 }, -// 108f MYANMAR SIGN RUMAI PALAUNG TONE-5 - { 0x108F, 0x1, 0x0, 0, 0 }, -// 1090 MYANMAR SHAN DIGIT ZERO -// 1091 MYANMAR SHAN DIGIT ONE -// 1092 MYANMAR SHAN DIGIT TWO -// 1093 MYANMAR SHAN DIGIT THREE -// 1094 MYANMAR SHAN DIGIT FOUR -// 1095 MYANMAR SHAN DIGIT FIVE -// 1096 MYANMAR SHAN DIGIT SIX -// 1097 MYANMAR SHAN DIGIT SEVEN -// 1098 MYANMAR SHAN DIGIT EIGHT -// 1099 MYANMAR SHAN DIGIT NINE - { 0x1090, 0xA, 0x108, 0, 0 }, -// 109a MYANMAR SIGN KHAMTI TONE-1 -// 109b MYANMAR SIGN KHAMTI TONE-3 -// 109c MYANMAR VOWEL SIGN AITON A -// 109d MYANMAR VOWEL SIGN AITON AI - { 0x109A, 0x4, 0x0, 0, 0 }, -// 109e MYANMAR SYMBOL SHAN ONE -// 109f MYANMAR SYMBOL SHAN EXCLAMATION - { 0x109E, 0x2, 0x8, 0, 0 }, -// 10a0 GEORGIAN CAPITAL LETTER AN -// 10a1 GEORGIAN CAPITAL LETTER BAN -// 10a2 GEORGIAN CAPITAL LETTER GAN -// 10a3 GEORGIAN CAPITAL LETTER DON -// 10a4 GEORGIAN CAPITAL LETTER EN -// 10a5 GEORGIAN CAPITAL LETTER VIN -// 10a6 GEORGIAN CAPITAL LETTER ZEN -// 10a7 GEORGIAN CAPITAL LETTER TAN -// 10a8 GEORGIAN CAPITAL LETTER IN -// 10a9 GEORGIAN CAPITAL LETTER KAN -// 10aa GEORGIAN CAPITAL LETTER LAS -// 10ab GEORGIAN CAPITAL LETTER MAN -// 10ac GEORGIAN CAPITAL LETTER NAR -// 10ad GEORGIAN CAPITAL LETTER ON -// 10ae GEORGIAN CAPITAL LETTER PAR -// 10af GEORGIAN CAPITAL LETTER ZHAR -// 10b0 GEORGIAN CAPITAL LETTER RAE -// 10b1 GEORGIAN CAPITAL LETTER SAN -// 10b2 GEORGIAN CAPITAL LETTER TAR -// 10b3 GEORGIAN CAPITAL LETTER UN -// 10b4 GEORGIAN CAPITAL LETTER PHAR -// 10b5 GEORGIAN CAPITAL LETTER KHAR -// 10b6 GEORGIAN CAPITAL LETTER GHAN -// 10b7 GEORGIAN CAPITAL LETTER QAR -// 10b8 GEORGIAN CAPITAL LETTER SHIN -// 10b9 GEORGIAN CAPITAL LETTER CHIN -// 10ba GEORGIAN CAPITAL LETTER CAN -// 10bb GEORGIAN CAPITAL LETTER JIL -// 10bc GEORGIAN CAPITAL LETTER CIL -// 10bd GEORGIAN CAPITAL LETTER CHAR -// 10be GEORGIAN CAPITAL LETTER XAN -// 10bf GEORGIAN CAPITAL LETTER JHAN -// 10c0 GEORGIAN CAPITAL LETTER HAE -// 10c1 GEORGIAN CAPITAL LETTER HE -// 10c2 GEORGIAN CAPITAL LETTER HIE -// 10c3 GEORGIAN CAPITAL LETTER WE -// 10c4 GEORGIAN CAPITAL LETTER HAR -// 10c5 GEORGIAN CAPITAL LETTER HOE - { 0x10A0, 0x26, 0x89, 7264, 0 }, -// 10c7 GEORGIAN CAPITAL LETTER YN - { 0x10C7, 0x1, 0x89, 7264, 0 }, -// 10cd GEORGIAN CAPITAL LETTER AEN - { 0x10CD, 0x1, 0x89, 7264, 0 }, -// 10d0 GEORGIAN LETTER AN -// 10d1 GEORGIAN LETTER BAN -// 10d2 GEORGIAN LETTER GAN -// 10d3 GEORGIAN LETTER DON -// 10d4 GEORGIAN LETTER EN -// 10d5 GEORGIAN LETTER VIN -// 10d6 GEORGIAN LETTER ZEN -// 10d7 GEORGIAN LETTER TAN -// 10d8 GEORGIAN LETTER IN -// 10d9 GEORGIAN LETTER KAN -// 10da GEORGIAN LETTER LAS -// 10db GEORGIAN LETTER MAN -// 10dc GEORGIAN LETTER NAR -// 10dd GEORGIAN LETTER ON -// 10de GEORGIAN LETTER PAR -// 10df GEORGIAN LETTER ZHAR -// 10e0 GEORGIAN LETTER RAE -// 10e1 GEORGIAN LETTER SAN -// 10e2 GEORGIAN LETTER TAR -// 10e3 GEORGIAN LETTER UN -// 10e4 GEORGIAN LETTER PHAR -// 10e5 GEORGIAN LETTER KHAR -// 10e6 GEORGIAN LETTER GHAN -// 10e7 GEORGIAN LETTER QAR -// 10e8 GEORGIAN LETTER SHIN -// 10e9 GEORGIAN LETTER CHIN -// 10ea GEORGIAN LETTER CAN -// 10eb GEORGIAN LETTER JIL -// 10ec GEORGIAN LETTER CIL -// 10ed GEORGIAN LETTER CHAR -// 10ee GEORGIAN LETTER XAN -// 10ef GEORGIAN LETTER JHAN -// 10f0 GEORGIAN LETTER HAE -// 10f1 GEORGIAN LETTER HE -// 10f2 GEORGIAN LETTER HIE -// 10f3 GEORGIAN LETTER WE -// 10f4 GEORGIAN LETTER HAR -// 10f5 GEORGIAN LETTER HOE -// 10f6 GEORGIAN LETTER FI -// 10f7 GEORGIAN LETTER YN -// 10f8 GEORGIAN LETTER ELIFI -// 10f9 GEORGIAN LETTER TURNED GAN -// 10fa GEORGIAN LETTER AIN - { 0x10D0, 0x2B, 0x9, 0, 0 }, -// 10fb GEORGIAN PARAGRAPH SEPARATOR - { 0x10FB, 0x1, 0x18, 0, 0 }, -// 10fc MODIFIER LETTER GEORGIAN NAR -// 10fd GEORGIAN LETTER AEN -// 10fe GEORGIAN LETTER HARD SIGN -// 10ff GEORGIAN LETTER LABIAL SIGN -// 1100 HANGUL CHOSEONG KIYEOK -// 1101 HANGUL CHOSEONG SSANGKIYEOK -// 1102 HANGUL CHOSEONG NIEUN -// 1103 HANGUL CHOSEONG TIKEUT -// 1104 HANGUL CHOSEONG SSANGTIKEUT -// 1105 HANGUL CHOSEONG RIEUL -// 1106 HANGUL CHOSEONG MIEUM -// 1107 HANGUL CHOSEONG PIEUP -// 1108 HANGUL CHOSEONG SSANGPIEUP -// 1109 HANGUL CHOSEONG SIOS -// 110a HANGUL CHOSEONG SSANGSIOS -// 110b HANGUL CHOSEONG IEUNG -// 110c HANGUL CHOSEONG CIEUC -// 110d HANGUL CHOSEONG SSANGCIEUC -// 110e HANGUL CHOSEONG CHIEUCH -// 110f HANGUL CHOSEONG KHIEUKH -// 1110 HANGUL CHOSEONG THIEUTH -// 1111 HANGUL CHOSEONG PHIEUPH -// 1112 HANGUL CHOSEONG HIEUH -// 1113 HANGUL CHOSEONG NIEUN-KIYEOK -// 1114 HANGUL CHOSEONG SSANGNIEUN -// 1115 HANGUL CHOSEONG NIEUN-TIKEUT -// 1116 HANGUL CHOSEONG NIEUN-PIEUP -// 1117 HANGUL CHOSEONG TIKEUT-KIYEOK -// 1118 HANGUL CHOSEONG RIEUL-NIEUN -// 1119 HANGUL CHOSEONG SSANGRIEUL -// 111a HANGUL CHOSEONG RIEUL-HIEUH -// 111b HANGUL CHOSEONG KAPYEOUNRIEUL -// 111c HANGUL CHOSEONG MIEUM-PIEUP -// 111d HANGUL CHOSEONG KAPYEOUNMIEUM -// 111e HANGUL CHOSEONG PIEUP-KIYEOK -// 111f HANGUL CHOSEONG PIEUP-NIEUN -// 1120 HANGUL CHOSEONG PIEUP-TIKEUT -// 1121 HANGUL CHOSEONG PIEUP-SIOS -// 1122 HANGUL CHOSEONG PIEUP-SIOS-KIYEOK -// 1123 HANGUL CHOSEONG PIEUP-SIOS-TIKEUT -// 1124 HANGUL CHOSEONG PIEUP-SIOS-PIEUP -// 1125 HANGUL CHOSEONG PIEUP-SSANGSIOS -// 1126 HANGUL CHOSEONG PIEUP-SIOS-CIEUC -// 1127 HANGUL CHOSEONG PIEUP-CIEUC -// 1128 HANGUL CHOSEONG PIEUP-CHIEUCH -// 1129 HANGUL CHOSEONG PIEUP-THIEUTH -// 112a HANGUL CHOSEONG PIEUP-PHIEUPH -// 112b HANGUL CHOSEONG KAPYEOUNPIEUP -// 112c HANGUL CHOSEONG KAPYEOUNSSANGPIEUP -// 112d HANGUL CHOSEONG SIOS-KIYEOK -// 112e HANGUL CHOSEONG SIOS-NIEUN -// 112f HANGUL CHOSEONG SIOS-TIKEUT -// 1130 HANGUL CHOSEONG SIOS-RIEUL -// 1131 HANGUL CHOSEONG SIOS-MIEUM -// 1132 HANGUL CHOSEONG SIOS-PIEUP -// 1133 HANGUL CHOSEONG SIOS-PIEUP-KIYEOK -// 1134 HANGUL CHOSEONG SIOS-SSANGSIOS -// 1135 HANGUL CHOSEONG SIOS-IEUNG -// 1136 HANGUL CHOSEONG SIOS-CIEUC -// 1137 HANGUL CHOSEONG SIOS-CHIEUCH -// 1138 HANGUL CHOSEONG SIOS-KHIEUKH -// 1139 HANGUL CHOSEONG SIOS-THIEUTH -// 113a HANGUL CHOSEONG SIOS-PHIEUPH -// 113b HANGUL CHOSEONG SIOS-HIEUH -// 113c HANGUL CHOSEONG CHITUEUMSIOS -// 113d HANGUL CHOSEONG CHITUEUMSSANGSIOS -// 113e HANGUL CHOSEONG CEONGCHIEUMSIOS -// 113f HANGUL CHOSEONG CEONGCHIEUMSSANGSIOS -// 1140 HANGUL CHOSEONG PANSIOS -// 1141 HANGUL CHOSEONG IEUNG-KIYEOK -// 1142 HANGUL CHOSEONG IEUNG-TIKEUT -// 1143 HANGUL CHOSEONG IEUNG-MIEUM -// 1144 HANGUL CHOSEONG IEUNG-PIEUP -// 1145 HANGUL CHOSEONG IEUNG-SIOS -// 1146 HANGUL CHOSEONG IEUNG-PANSIOS -// 1147 HANGUL CHOSEONG SSANGIEUNG -// 1148 HANGUL CHOSEONG IEUNG-CIEUC -// 1149 HANGUL CHOSEONG IEUNG-CHIEUCH -// 114a HANGUL CHOSEONG IEUNG-THIEUTH -// 114b HANGUL CHOSEONG IEUNG-PHIEUPH -// 114c HANGUL CHOSEONG YESIEUNG -// 114d HANGUL CHOSEONG CIEUC-IEUNG -// 114e HANGUL CHOSEONG CHITUEUMCIEUC -// 114f HANGUL CHOSEONG CHITUEUMSSANGCIEUC -// 1150 HANGUL CHOSEONG CEONGCHIEUMCIEUC -// 1151 HANGUL CHOSEONG CEONGCHIEUMSSANGCIEUC -// 1152 HANGUL CHOSEONG CHIEUCH-KHIEUKH -// 1153 HANGUL CHOSEONG CHIEUCH-HIEUH -// 1154 HANGUL CHOSEONG CHITUEUMCHIEUCH -// 1155 HANGUL CHOSEONG CEONGCHIEUMCHIEUCH -// 1156 HANGUL CHOSEONG PHIEUPH-PIEUP -// 1157 HANGUL CHOSEONG KAPYEOUNPHIEUPH -// 1158 HANGUL CHOSEONG SSANGHIEUH -// 1159 HANGUL CHOSEONG YEORINHIEUH -// 115a HANGUL CHOSEONG KIYEOK-TIKEUT -// 115b HANGUL CHOSEONG NIEUN-SIOS -// 115c HANGUL CHOSEONG NIEUN-CIEUC -// 115d HANGUL CHOSEONG NIEUN-HIEUH -// 115e HANGUL CHOSEONG TIKEUT-RIEUL -// 115f HANGUL CHOSEONG FILLER -// 1160 HANGUL JUNGSEONG FILLER -// 1161 HANGUL JUNGSEONG A -// 1162 HANGUL JUNGSEONG AE -// 1163 HANGUL JUNGSEONG YA -// 1164 HANGUL JUNGSEONG YAE -// 1165 HANGUL JUNGSEONG EO -// 1166 HANGUL JUNGSEONG E -// 1167 HANGUL JUNGSEONG YEO -// 1168 HANGUL JUNGSEONG YE -// 1169 HANGUL JUNGSEONG O -// 116a HANGUL JUNGSEONG WA -// 116b HANGUL JUNGSEONG WAE -// 116c HANGUL JUNGSEONG OE -// 116d HANGUL JUNGSEONG YO -// 116e HANGUL JUNGSEONG U -// 116f HANGUL JUNGSEONG WEO -// 1170 HANGUL JUNGSEONG WE -// 1171 HANGUL JUNGSEONG WI -// 1172 HANGUL JUNGSEONG YU -// 1173 HANGUL JUNGSEONG EU -// 1174 HANGUL JUNGSEONG YI -// 1175 HANGUL JUNGSEONG I -// 1176 HANGUL JUNGSEONG A-O -// 1177 HANGUL JUNGSEONG A-U -// 1178 HANGUL JUNGSEONG YA-O -// 1179 HANGUL JUNGSEONG YA-YO -// 117a HANGUL JUNGSEONG EO-O -// 117b HANGUL JUNGSEONG EO-U -// 117c HANGUL JUNGSEONG EO-EU -// 117d HANGUL JUNGSEONG YEO-O -// 117e HANGUL JUNGSEONG YEO-U -// 117f HANGUL JUNGSEONG O-EO -// 1180 HANGUL JUNGSEONG O-E -// 1181 HANGUL JUNGSEONG O-YE -// 1182 HANGUL JUNGSEONG O-O -// 1183 HANGUL JUNGSEONG O-U -// 1184 HANGUL JUNGSEONG YO-YA -// 1185 HANGUL JUNGSEONG YO-YAE -// 1186 HANGUL JUNGSEONG YO-YEO -// 1187 HANGUL JUNGSEONG YO-O -// 1188 HANGUL JUNGSEONG YO-I -// 1189 HANGUL JUNGSEONG U-A -// 118a HANGUL JUNGSEONG U-AE -// 118b HANGUL JUNGSEONG U-EO-EU -// 118c HANGUL JUNGSEONG U-YE -// 118d HANGUL JUNGSEONG U-U -// 118e HANGUL JUNGSEONG YU-A -// 118f HANGUL JUNGSEONG YU-EO -// 1190 HANGUL JUNGSEONG YU-E -// 1191 HANGUL JUNGSEONG YU-YEO -// 1192 HANGUL JUNGSEONG YU-YE -// 1193 HANGUL JUNGSEONG YU-U -// 1194 HANGUL JUNGSEONG YU-I -// 1195 HANGUL JUNGSEONG EU-U -// 1196 HANGUL JUNGSEONG EU-EU -// 1197 HANGUL JUNGSEONG YI-U -// 1198 HANGUL JUNGSEONG I-A -// 1199 HANGUL JUNGSEONG I-YA -// 119a HANGUL JUNGSEONG I-O -// 119b HANGUL JUNGSEONG I-U -// 119c HANGUL JUNGSEONG I-EU -// 119d HANGUL JUNGSEONG I-ARAEA -// 119e HANGUL JUNGSEONG ARAEA -// 119f HANGUL JUNGSEONG ARAEA-EO -// 11a0 HANGUL JUNGSEONG ARAEA-U -// 11a1 HANGUL JUNGSEONG ARAEA-I -// 11a2 HANGUL JUNGSEONG SSANGARAEA -// 11a3 HANGUL JUNGSEONG A-EU -// 11a4 HANGUL JUNGSEONG YA-U -// 11a5 HANGUL JUNGSEONG YEO-YA -// 11a6 HANGUL JUNGSEONG O-YA -// 11a7 HANGUL JUNGSEONG O-YAE -// 11a8 HANGUL JONGSEONG KIYEOK -// 11a9 HANGUL JONGSEONG SSANGKIYEOK -// 11aa HANGUL JONGSEONG KIYEOK-SIOS -// 11ab HANGUL JONGSEONG NIEUN -// 11ac HANGUL JONGSEONG NIEUN-CIEUC -// 11ad HANGUL JONGSEONG NIEUN-HIEUH -// 11ae HANGUL JONGSEONG TIKEUT -// 11af HANGUL JONGSEONG RIEUL -// 11b0 HANGUL JONGSEONG RIEUL-KIYEOK -// 11b1 HANGUL JONGSEONG RIEUL-MIEUM -// 11b2 HANGUL JONGSEONG RIEUL-PIEUP -// 11b3 HANGUL JONGSEONG RIEUL-SIOS -// 11b4 HANGUL JONGSEONG RIEUL-THIEUTH -// 11b5 HANGUL JONGSEONG RIEUL-PHIEUPH -// 11b6 HANGUL JONGSEONG RIEUL-HIEUH -// 11b7 HANGUL JONGSEONG MIEUM -// 11b8 HANGUL JONGSEONG PIEUP -// 11b9 HANGUL JONGSEONG PIEUP-SIOS -// 11ba HANGUL JONGSEONG SIOS -// 11bb HANGUL JONGSEONG SSANGSIOS -// 11bc HANGUL JONGSEONG IEUNG -// 11bd HANGUL JONGSEONG CIEUC -// 11be HANGUL JONGSEONG CHIEUCH -// 11bf HANGUL JONGSEONG KHIEUKH -// 11c0 HANGUL JONGSEONG THIEUTH -// 11c1 HANGUL JONGSEONG PHIEUPH -// 11c2 HANGUL JONGSEONG HIEUH -// 11c3 HANGUL JONGSEONG KIYEOK-RIEUL -// 11c4 HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK -// 11c5 HANGUL JONGSEONG NIEUN-KIYEOK -// 11c6 HANGUL JONGSEONG NIEUN-TIKEUT -// 11c7 HANGUL JONGSEONG NIEUN-SIOS -// 11c8 HANGUL JONGSEONG NIEUN-PANSIOS -// 11c9 HANGUL JONGSEONG NIEUN-THIEUTH -// 11ca HANGUL JONGSEONG TIKEUT-KIYEOK -// 11cb HANGUL JONGSEONG TIKEUT-RIEUL -// 11cc HANGUL JONGSEONG RIEUL-KIYEOK-SIOS -// 11cd HANGUL JONGSEONG RIEUL-NIEUN -// 11ce HANGUL JONGSEONG RIEUL-TIKEUT -// 11cf HANGUL JONGSEONG RIEUL-TIKEUT-HIEUH -// 11d0 HANGUL JONGSEONG SSANGRIEUL -// 11d1 HANGUL JONGSEONG RIEUL-MIEUM-KIYEOK -// 11d2 HANGUL JONGSEONG RIEUL-MIEUM-SIOS -// 11d3 HANGUL JONGSEONG RIEUL-PIEUP-SIOS -// 11d4 HANGUL JONGSEONG RIEUL-PIEUP-HIEUH -// 11d5 HANGUL JONGSEONG RIEUL-KAPYEOUNPIEUP -// 11d6 HANGUL JONGSEONG RIEUL-SSANGSIOS -// 11d7 HANGUL JONGSEONG RIEUL-PANSIOS -// 11d8 HANGUL JONGSEONG RIEUL-KHIEUKH -// 11d9 HANGUL JONGSEONG RIEUL-YEORINHIEUH -// 11da HANGUL JONGSEONG MIEUM-KIYEOK -// 11db HANGUL JONGSEONG MIEUM-RIEUL -// 11dc HANGUL JONGSEONG MIEUM-PIEUP -// 11dd HANGUL JONGSEONG MIEUM-SIOS -// 11de HANGUL JONGSEONG MIEUM-SSANGSIOS -// 11df HANGUL JONGSEONG MIEUM-PANSIOS -// 11e0 HANGUL JONGSEONG MIEUM-CHIEUCH -// 11e1 HANGUL JONGSEONG MIEUM-HIEUH -// 11e2 HANGUL JONGSEONG KAPYEOUNMIEUM -// 11e3 HANGUL JONGSEONG PIEUP-RIEUL -// 11e4 HANGUL JONGSEONG PIEUP-PHIEUPH -// 11e5 HANGUL JONGSEONG PIEUP-HIEUH -// 11e6 HANGUL JONGSEONG KAPYEOUNPIEUP -// 11e7 HANGUL JONGSEONG SIOS-KIYEOK -// 11e8 HANGUL JONGSEONG SIOS-TIKEUT -// 11e9 HANGUL JONGSEONG SIOS-RIEUL -// 11ea HANGUL JONGSEONG SIOS-PIEUP -// 11eb HANGUL JONGSEONG PANSIOS -// 11ec HANGUL JONGSEONG IEUNG-KIYEOK -// 11ed HANGUL JONGSEONG IEUNG-SSANGKIYEOK -// 11ee HANGUL JONGSEONG SSANGIEUNG -// 11ef HANGUL JONGSEONG IEUNG-KHIEUKH -// 11f0 HANGUL JONGSEONG YESIEUNG -// 11f1 HANGUL JONGSEONG YESIEUNG-SIOS -// 11f2 HANGUL JONGSEONG YESIEUNG-PANSIOS -// 11f3 HANGUL JONGSEONG PHIEUPH-PIEUP -// 11f4 HANGUL JONGSEONG KAPYEOUNPHIEUPH -// 11f5 HANGUL JONGSEONG HIEUH-NIEUN -// 11f6 HANGUL JONGSEONG HIEUH-RIEUL -// 11f7 HANGUL JONGSEONG HIEUH-MIEUM -// 11f8 HANGUL JONGSEONG HIEUH-PIEUP -// 11f9 HANGUL JONGSEONG YEORINHIEUH -// 11fa HANGUL JONGSEONG KIYEOK-NIEUN -// 11fb HANGUL JONGSEONG KIYEOK-PIEUP -// 11fc HANGUL JONGSEONG KIYEOK-CHIEUCH -// 11fd HANGUL JONGSEONG KIYEOK-KHIEUKH -// 11fe HANGUL JONGSEONG KIYEOK-HIEUH -// 11ff HANGUL JONGSEONG SSANGNIEUN -// 1200 ETHIOPIC SYLLABLE HA -// 1201 ETHIOPIC SYLLABLE HU -// 1202 ETHIOPIC SYLLABLE HI -// 1203 ETHIOPIC SYLLABLE HAA -// 1204 ETHIOPIC SYLLABLE HEE -// 1205 ETHIOPIC SYLLABLE HE -// 1206 ETHIOPIC SYLLABLE HO -// 1207 ETHIOPIC SYLLABLE HOA -// 1208 ETHIOPIC SYLLABLE LA -// 1209 ETHIOPIC SYLLABLE LU -// 120a ETHIOPIC SYLLABLE LI -// 120b ETHIOPIC SYLLABLE LAA -// 120c ETHIOPIC SYLLABLE LEE -// 120d ETHIOPIC SYLLABLE LE -// 120e ETHIOPIC SYLLABLE LO -// 120f ETHIOPIC SYLLABLE LWA -// 1210 ETHIOPIC SYLLABLE HHA -// 1211 ETHIOPIC SYLLABLE HHU -// 1212 ETHIOPIC SYLLABLE HHI -// 1213 ETHIOPIC SYLLABLE HHAA -// 1214 ETHIOPIC SYLLABLE HHEE -// 1215 ETHIOPIC SYLLABLE HHE -// 1216 ETHIOPIC SYLLABLE HHO -// 1217 ETHIOPIC SYLLABLE HHWA -// 1218 ETHIOPIC SYLLABLE MA -// 1219 ETHIOPIC SYLLABLE MU -// 121a ETHIOPIC SYLLABLE MI -// 121b ETHIOPIC SYLLABLE MAA -// 121c ETHIOPIC SYLLABLE MEE -// 121d ETHIOPIC SYLLABLE ME -// 121e ETHIOPIC SYLLABLE MO -// 121f ETHIOPIC SYLLABLE MWA -// 1220 ETHIOPIC SYLLABLE SZA -// 1221 ETHIOPIC SYLLABLE SZU -// 1222 ETHIOPIC SYLLABLE SZI -// 1223 ETHIOPIC SYLLABLE SZAA -// 1224 ETHIOPIC SYLLABLE SZEE -// 1225 ETHIOPIC SYLLABLE SZE -// 1226 ETHIOPIC SYLLABLE SZO -// 1227 ETHIOPIC SYLLABLE SZWA -// 1228 ETHIOPIC SYLLABLE RA -// 1229 ETHIOPIC SYLLABLE RU -// 122a ETHIOPIC SYLLABLE RI -// 122b ETHIOPIC SYLLABLE RAA -// 122c ETHIOPIC SYLLABLE REE -// 122d ETHIOPIC SYLLABLE RE -// 122e ETHIOPIC SYLLABLE RO -// 122f ETHIOPIC SYLLABLE RWA -// 1230 ETHIOPIC SYLLABLE SA -// 1231 ETHIOPIC SYLLABLE SU -// 1232 ETHIOPIC SYLLABLE SI -// 1233 ETHIOPIC SYLLABLE SAA -// 1234 ETHIOPIC SYLLABLE SEE -// 1235 ETHIOPIC SYLLABLE SE -// 1236 ETHIOPIC SYLLABLE SO -// 1237 ETHIOPIC SYLLABLE SWA -// 1238 ETHIOPIC SYLLABLE SHA -// 1239 ETHIOPIC SYLLABLE SHU -// 123a ETHIOPIC SYLLABLE SHI -// 123b ETHIOPIC SYLLABLE SHAA -// 123c ETHIOPIC SYLLABLE SHEE -// 123d ETHIOPIC SYLLABLE SHE -// 123e ETHIOPIC SYLLABLE SHO -// 123f ETHIOPIC SYLLABLE SHWA -// 1240 ETHIOPIC SYLLABLE QA -// 1241 ETHIOPIC SYLLABLE QU -// 1242 ETHIOPIC SYLLABLE QI -// 1243 ETHIOPIC SYLLABLE QAA -// 1244 ETHIOPIC SYLLABLE QEE -// 1245 ETHIOPIC SYLLABLE QE -// 1246 ETHIOPIC SYLLABLE QO -// 1247 ETHIOPIC SYLLABLE QOA -// 1248 ETHIOPIC SYLLABLE QWA - { 0x10FC, 0x14D, 0x9, 0, 0 }, -// 124a ETHIOPIC SYLLABLE QWI -// 124b ETHIOPIC SYLLABLE QWAA -// 124c ETHIOPIC SYLLABLE QWEE -// 124d ETHIOPIC SYLLABLE QWE - { 0x124A, 0x4, 0x9, 0, 0 }, -// 1250 ETHIOPIC SYLLABLE QHA -// 1251 ETHIOPIC SYLLABLE QHU -// 1252 ETHIOPIC SYLLABLE QHI -// 1253 ETHIOPIC SYLLABLE QHAA -// 1254 ETHIOPIC SYLLABLE QHEE -// 1255 ETHIOPIC SYLLABLE QHE -// 1256 ETHIOPIC SYLLABLE QHO - { 0x1250, 0x7, 0x9, 0, 0 }, -// 1258 ETHIOPIC SYLLABLE QHWA - { 0x1258, 0x1, 0x9, 0, 0 }, -// 125a ETHIOPIC SYLLABLE QHWI -// 125b ETHIOPIC SYLLABLE QHWAA -// 125c ETHIOPIC SYLLABLE QHWEE -// 125d ETHIOPIC SYLLABLE QHWE - { 0x125A, 0x4, 0x9, 0, 0 }, -// 1260 ETHIOPIC SYLLABLE BA -// 1261 ETHIOPIC SYLLABLE BU -// 1262 ETHIOPIC SYLLABLE BI -// 1263 ETHIOPIC SYLLABLE BAA -// 1264 ETHIOPIC SYLLABLE BEE -// 1265 ETHIOPIC SYLLABLE BE -// 1266 ETHIOPIC SYLLABLE BO -// 1267 ETHIOPIC SYLLABLE BWA -// 1268 ETHIOPIC SYLLABLE VA -// 1269 ETHIOPIC SYLLABLE VU -// 126a ETHIOPIC SYLLABLE VI -// 126b ETHIOPIC SYLLABLE VAA -// 126c ETHIOPIC SYLLABLE VEE -// 126d ETHIOPIC SYLLABLE VE -// 126e ETHIOPIC SYLLABLE VO -// 126f ETHIOPIC SYLLABLE VWA -// 1270 ETHIOPIC SYLLABLE TA -// 1271 ETHIOPIC SYLLABLE TU -// 1272 ETHIOPIC SYLLABLE TI -// 1273 ETHIOPIC SYLLABLE TAA -// 1274 ETHIOPIC SYLLABLE TEE -// 1275 ETHIOPIC SYLLABLE TE -// 1276 ETHIOPIC SYLLABLE TO -// 1277 ETHIOPIC SYLLABLE TWA -// 1278 ETHIOPIC SYLLABLE CA -// 1279 ETHIOPIC SYLLABLE CU -// 127a ETHIOPIC SYLLABLE CI -// 127b ETHIOPIC SYLLABLE CAA -// 127c ETHIOPIC SYLLABLE CEE -// 127d ETHIOPIC SYLLABLE CE -// 127e ETHIOPIC SYLLABLE CO -// 127f ETHIOPIC SYLLABLE CWA -// 1280 ETHIOPIC SYLLABLE XA -// 1281 ETHIOPIC SYLLABLE XU -// 1282 ETHIOPIC SYLLABLE XI -// 1283 ETHIOPIC SYLLABLE XAA -// 1284 ETHIOPIC SYLLABLE XEE -// 1285 ETHIOPIC SYLLABLE XE -// 1286 ETHIOPIC SYLLABLE XO -// 1287 ETHIOPIC SYLLABLE XOA -// 1288 ETHIOPIC SYLLABLE XWA - { 0x1260, 0x29, 0x9, 0, 0 }, -// 128a ETHIOPIC SYLLABLE XWI -// 128b ETHIOPIC SYLLABLE XWAA -// 128c ETHIOPIC SYLLABLE XWEE -// 128d ETHIOPIC SYLLABLE XWE - { 0x128A, 0x4, 0x9, 0, 0 }, -// 1290 ETHIOPIC SYLLABLE NA -// 1291 ETHIOPIC SYLLABLE NU -// 1292 ETHIOPIC SYLLABLE NI -// 1293 ETHIOPIC SYLLABLE NAA -// 1294 ETHIOPIC SYLLABLE NEE -// 1295 ETHIOPIC SYLLABLE NE -// 1296 ETHIOPIC SYLLABLE NO -// 1297 ETHIOPIC SYLLABLE NWA -// 1298 ETHIOPIC SYLLABLE NYA -// 1299 ETHIOPIC SYLLABLE NYU -// 129a ETHIOPIC SYLLABLE NYI -// 129b ETHIOPIC SYLLABLE NYAA -// 129c ETHIOPIC SYLLABLE NYEE -// 129d ETHIOPIC SYLLABLE NYE -// 129e ETHIOPIC SYLLABLE NYO -// 129f ETHIOPIC SYLLABLE NYWA -// 12a0 ETHIOPIC SYLLABLE GLOTTAL A -// 12a1 ETHIOPIC SYLLABLE GLOTTAL U -// 12a2 ETHIOPIC SYLLABLE GLOTTAL I -// 12a3 ETHIOPIC SYLLABLE GLOTTAL AA -// 12a4 ETHIOPIC SYLLABLE GLOTTAL EE -// 12a5 ETHIOPIC SYLLABLE GLOTTAL E -// 12a6 ETHIOPIC SYLLABLE GLOTTAL O -// 12a7 ETHIOPIC SYLLABLE GLOTTAL WA -// 12a8 ETHIOPIC SYLLABLE KA -// 12a9 ETHIOPIC SYLLABLE KU -// 12aa ETHIOPIC SYLLABLE KI -// 12ab ETHIOPIC SYLLABLE KAA -// 12ac ETHIOPIC SYLLABLE KEE -// 12ad ETHIOPIC SYLLABLE KE -// 12ae ETHIOPIC SYLLABLE KO -// 12af ETHIOPIC SYLLABLE KOA -// 12b0 ETHIOPIC SYLLABLE KWA - { 0x1290, 0x21, 0x9, 0, 0 }, -// 12b2 ETHIOPIC SYLLABLE KWI -// 12b3 ETHIOPIC SYLLABLE KWAA -// 12b4 ETHIOPIC SYLLABLE KWEE -// 12b5 ETHIOPIC SYLLABLE KWE - { 0x12B2, 0x4, 0x9, 0, 0 }, -// 12b8 ETHIOPIC SYLLABLE KXA -// 12b9 ETHIOPIC SYLLABLE KXU -// 12ba ETHIOPIC SYLLABLE KXI -// 12bb ETHIOPIC SYLLABLE KXAA -// 12bc ETHIOPIC SYLLABLE KXEE -// 12bd ETHIOPIC SYLLABLE KXE -// 12be ETHIOPIC SYLLABLE KXO - { 0x12B8, 0x7, 0x9, 0, 0 }, -// 12c0 ETHIOPIC SYLLABLE KXWA - { 0x12C0, 0x1, 0x9, 0, 0 }, -// 12c2 ETHIOPIC SYLLABLE KXWI -// 12c3 ETHIOPIC SYLLABLE KXWAA -// 12c4 ETHIOPIC SYLLABLE KXWEE -// 12c5 ETHIOPIC SYLLABLE KXWE - { 0x12C2, 0x4, 0x9, 0, 0 }, -// 12c8 ETHIOPIC SYLLABLE WA -// 12c9 ETHIOPIC SYLLABLE WU -// 12ca ETHIOPIC SYLLABLE WI -// 12cb ETHIOPIC SYLLABLE WAA -// 12cc ETHIOPIC SYLLABLE WEE -// 12cd ETHIOPIC SYLLABLE WE -// 12ce ETHIOPIC SYLLABLE WO -// 12cf ETHIOPIC SYLLABLE WOA -// 12d0 ETHIOPIC SYLLABLE PHARYNGEAL A -// 12d1 ETHIOPIC SYLLABLE PHARYNGEAL U -// 12d2 ETHIOPIC SYLLABLE PHARYNGEAL I -// 12d3 ETHIOPIC SYLLABLE PHARYNGEAL AA -// 12d4 ETHIOPIC SYLLABLE PHARYNGEAL EE -// 12d5 ETHIOPIC SYLLABLE PHARYNGEAL E -// 12d6 ETHIOPIC SYLLABLE PHARYNGEAL O - { 0x12C8, 0xF, 0x9, 0, 0 }, -// 12d8 ETHIOPIC SYLLABLE ZA -// 12d9 ETHIOPIC SYLLABLE ZU -// 12da ETHIOPIC SYLLABLE ZI -// 12db ETHIOPIC SYLLABLE ZAA -// 12dc ETHIOPIC SYLLABLE ZEE -// 12dd ETHIOPIC SYLLABLE ZE -// 12de ETHIOPIC SYLLABLE ZO -// 12df ETHIOPIC SYLLABLE ZWA -// 12e0 ETHIOPIC SYLLABLE ZHA -// 12e1 ETHIOPIC SYLLABLE ZHU -// 12e2 ETHIOPIC SYLLABLE ZHI -// 12e3 ETHIOPIC SYLLABLE ZHAA -// 12e4 ETHIOPIC SYLLABLE ZHEE -// 12e5 ETHIOPIC SYLLABLE ZHE -// 12e6 ETHIOPIC SYLLABLE ZHO -// 12e7 ETHIOPIC SYLLABLE ZHWA -// 12e8 ETHIOPIC SYLLABLE YA -// 12e9 ETHIOPIC SYLLABLE YU -// 12ea ETHIOPIC SYLLABLE YI -// 12eb ETHIOPIC SYLLABLE YAA -// 12ec ETHIOPIC SYLLABLE YEE -// 12ed ETHIOPIC SYLLABLE YE -// 12ee ETHIOPIC SYLLABLE YO -// 12ef ETHIOPIC SYLLABLE YOA -// 12f0 ETHIOPIC SYLLABLE DA -// 12f1 ETHIOPIC SYLLABLE DU -// 12f2 ETHIOPIC SYLLABLE DI -// 12f3 ETHIOPIC SYLLABLE DAA -// 12f4 ETHIOPIC SYLLABLE DEE -// 12f5 ETHIOPIC SYLLABLE DE -// 12f6 ETHIOPIC SYLLABLE DO -// 12f7 ETHIOPIC SYLLABLE DWA -// 12f8 ETHIOPIC SYLLABLE DDA -// 12f9 ETHIOPIC SYLLABLE DDU -// 12fa ETHIOPIC SYLLABLE DDI -// 12fb ETHIOPIC SYLLABLE DDAA -// 12fc ETHIOPIC SYLLABLE DDEE -// 12fd ETHIOPIC SYLLABLE DDE -// 12fe ETHIOPIC SYLLABLE DDO -// 12ff ETHIOPIC SYLLABLE DDWA -// 1300 ETHIOPIC SYLLABLE JA -// 1301 ETHIOPIC SYLLABLE JU -// 1302 ETHIOPIC SYLLABLE JI -// 1303 ETHIOPIC SYLLABLE JAA -// 1304 ETHIOPIC SYLLABLE JEE -// 1305 ETHIOPIC SYLLABLE JE -// 1306 ETHIOPIC SYLLABLE JO -// 1307 ETHIOPIC SYLLABLE JWA -// 1308 ETHIOPIC SYLLABLE GA -// 1309 ETHIOPIC SYLLABLE GU -// 130a ETHIOPIC SYLLABLE GI -// 130b ETHIOPIC SYLLABLE GAA -// 130c ETHIOPIC SYLLABLE GEE -// 130d ETHIOPIC SYLLABLE GE -// 130e ETHIOPIC SYLLABLE GO -// 130f ETHIOPIC SYLLABLE GOA -// 1310 ETHIOPIC SYLLABLE GWA - { 0x12D8, 0x39, 0x9, 0, 0 }, -// 1312 ETHIOPIC SYLLABLE GWI -// 1313 ETHIOPIC SYLLABLE GWAA -// 1314 ETHIOPIC SYLLABLE GWEE -// 1315 ETHIOPIC SYLLABLE GWE - { 0x1312, 0x4, 0x9, 0, 0 }, -// 1318 ETHIOPIC SYLLABLE GGA -// 1319 ETHIOPIC SYLLABLE GGU -// 131a ETHIOPIC SYLLABLE GGI -// 131b ETHIOPIC SYLLABLE GGAA -// 131c ETHIOPIC SYLLABLE GGEE -// 131d ETHIOPIC SYLLABLE GGE -// 131e ETHIOPIC SYLLABLE GGO -// 131f ETHIOPIC SYLLABLE GGWAA -// 1320 ETHIOPIC SYLLABLE THA -// 1321 ETHIOPIC SYLLABLE THU -// 1322 ETHIOPIC SYLLABLE THI -// 1323 ETHIOPIC SYLLABLE THAA -// 1324 ETHIOPIC SYLLABLE THEE -// 1325 ETHIOPIC SYLLABLE THE -// 1326 ETHIOPIC SYLLABLE THO -// 1327 ETHIOPIC SYLLABLE THWA -// 1328 ETHIOPIC SYLLABLE CHA -// 1329 ETHIOPIC SYLLABLE CHU -// 132a ETHIOPIC SYLLABLE CHI -// 132b ETHIOPIC SYLLABLE CHAA -// 132c ETHIOPIC SYLLABLE CHEE -// 132d ETHIOPIC SYLLABLE CHE -// 132e ETHIOPIC SYLLABLE CHO -// 132f ETHIOPIC SYLLABLE CHWA -// 1330 ETHIOPIC SYLLABLE PHA -// 1331 ETHIOPIC SYLLABLE PHU -// 1332 ETHIOPIC SYLLABLE PHI -// 1333 ETHIOPIC SYLLABLE PHAA -// 1334 ETHIOPIC SYLLABLE PHEE -// 1335 ETHIOPIC SYLLABLE PHE -// 1336 ETHIOPIC SYLLABLE PHO -// 1337 ETHIOPIC SYLLABLE PHWA -// 1338 ETHIOPIC SYLLABLE TSA -// 1339 ETHIOPIC SYLLABLE TSU -// 133a ETHIOPIC SYLLABLE TSI -// 133b ETHIOPIC SYLLABLE TSAA -// 133c ETHIOPIC SYLLABLE TSEE -// 133d ETHIOPIC SYLLABLE TSE -// 133e ETHIOPIC SYLLABLE TSO -// 133f ETHIOPIC SYLLABLE TSWA -// 1340 ETHIOPIC SYLLABLE TZA -// 1341 ETHIOPIC SYLLABLE TZU -// 1342 ETHIOPIC SYLLABLE TZI -// 1343 ETHIOPIC SYLLABLE TZAA -// 1344 ETHIOPIC SYLLABLE TZEE -// 1345 ETHIOPIC SYLLABLE TZE -// 1346 ETHIOPIC SYLLABLE TZO -// 1347 ETHIOPIC SYLLABLE TZOA -// 1348 ETHIOPIC SYLLABLE FA -// 1349 ETHIOPIC SYLLABLE FU -// 134a ETHIOPIC SYLLABLE FI -// 134b ETHIOPIC SYLLABLE FAA -// 134c ETHIOPIC SYLLABLE FEE -// 134d ETHIOPIC SYLLABLE FE -// 134e ETHIOPIC SYLLABLE FO -// 134f ETHIOPIC SYLLABLE FWA -// 1350 ETHIOPIC SYLLABLE PA -// 1351 ETHIOPIC SYLLABLE PU -// 1352 ETHIOPIC SYLLABLE PI -// 1353 ETHIOPIC SYLLABLE PAA -// 1354 ETHIOPIC SYLLABLE PEE -// 1355 ETHIOPIC SYLLABLE PE -// 1356 ETHIOPIC SYLLABLE PO -// 1357 ETHIOPIC SYLLABLE PWA -// 1358 ETHIOPIC SYLLABLE RYA -// 1359 ETHIOPIC SYLLABLE MYA -// 135a ETHIOPIC SYLLABLE FYA - { 0x1318, 0x43, 0x9, 0, 0 }, -// 135d ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK -// 135e ETHIOPIC COMBINING VOWEL LENGTH MARK -// 135f ETHIOPIC COMBINING GEMINATION MARK - { 0x135D, 0x3, 0x0, 0, 0 }, -// 1360 ETHIOPIC SECTION MARK -// 1361 ETHIOPIC WORDSPACE -// 1362 ETHIOPIC FULL STOP -// 1363 ETHIOPIC COMMA -// 1364 ETHIOPIC SEMICOLON -// 1365 ETHIOPIC COLON -// 1366 ETHIOPIC PREFACE COLON -// 1367 ETHIOPIC QUESTION MARK -// 1368 ETHIOPIC PARAGRAPH SEPARATOR - { 0x1360, 0x9, 0x18, 0, 0 }, -// 1369 ETHIOPIC DIGIT ONE -// 136a ETHIOPIC DIGIT TWO -// 136b ETHIOPIC DIGIT THREE -// 136c ETHIOPIC DIGIT FOUR -// 136d ETHIOPIC DIGIT FIVE -// 136e ETHIOPIC DIGIT SIX -// 136f ETHIOPIC DIGIT SEVEN -// 1370 ETHIOPIC DIGIT EIGHT -// 1371 ETHIOPIC DIGIT NINE -// 1372 ETHIOPIC NUMBER TEN -// 1373 ETHIOPIC NUMBER TWENTY -// 1374 ETHIOPIC NUMBER THIRTY -// 1375 ETHIOPIC NUMBER FORTY -// 1376 ETHIOPIC NUMBER FIFTY -// 1377 ETHIOPIC NUMBER SIXTY -// 1378 ETHIOPIC NUMBER SEVENTY -// 1379 ETHIOPIC NUMBER EIGHTY -// 137a ETHIOPIC NUMBER NINETY -// 137b ETHIOPIC NUMBER HUNDRED -// 137c ETHIOPIC NUMBER TEN THOUSAND - { 0x1369, 0x14, 0x8, 0, 0 }, -// 1380 ETHIOPIC SYLLABLE SEBATBEIT MWA -// 1381 ETHIOPIC SYLLABLE MWI -// 1382 ETHIOPIC SYLLABLE MWEE -// 1383 ETHIOPIC SYLLABLE MWE -// 1384 ETHIOPIC SYLLABLE SEBATBEIT BWA -// 1385 ETHIOPIC SYLLABLE BWI -// 1386 ETHIOPIC SYLLABLE BWEE -// 1387 ETHIOPIC SYLLABLE BWE -// 1388 ETHIOPIC SYLLABLE SEBATBEIT FWA -// 1389 ETHIOPIC SYLLABLE FWI -// 138a ETHIOPIC SYLLABLE FWEE -// 138b ETHIOPIC SYLLABLE FWE -// 138c ETHIOPIC SYLLABLE SEBATBEIT PWA -// 138d ETHIOPIC SYLLABLE PWI -// 138e ETHIOPIC SYLLABLE PWEE -// 138f ETHIOPIC SYLLABLE PWE - { 0x1380, 0x10, 0x9, 0, 0 }, -// 1390 ETHIOPIC TONAL MARK YIZET -// 1391 ETHIOPIC TONAL MARK DERET -// 1392 ETHIOPIC TONAL MARK RIKRIK -// 1393 ETHIOPIC TONAL MARK SHORT RIKRIK -// 1394 ETHIOPIC TONAL MARK DIFAT -// 1395 ETHIOPIC TONAL MARK KENAT -// 1396 ETHIOPIC TONAL MARK CHIRET -// 1397 ETHIOPIC TONAL MARK HIDET -// 1398 ETHIOPIC TONAL MARK DERET-HIDET -// 1399 ETHIOPIC TONAL MARK KURT - { 0x1390, 0xA, 0x8, 0, 0 }, -// 13a0 CHEROKEE LETTER A -// 13a1 CHEROKEE LETTER E -// 13a2 CHEROKEE LETTER I -// 13a3 CHEROKEE LETTER O -// 13a4 CHEROKEE LETTER U -// 13a5 CHEROKEE LETTER V -// 13a6 CHEROKEE LETTER GA -// 13a7 CHEROKEE LETTER KA -// 13a8 CHEROKEE LETTER GE -// 13a9 CHEROKEE LETTER GI -// 13aa CHEROKEE LETTER GO -// 13ab CHEROKEE LETTER GU -// 13ac CHEROKEE LETTER GV -// 13ad CHEROKEE LETTER HA -// 13ae CHEROKEE LETTER HE -// 13af CHEROKEE LETTER HI -// 13b0 CHEROKEE LETTER HO -// 13b1 CHEROKEE LETTER HU -// 13b2 CHEROKEE LETTER HV -// 13b3 CHEROKEE LETTER LA -// 13b4 CHEROKEE LETTER LE -// 13b5 CHEROKEE LETTER LI -// 13b6 CHEROKEE LETTER LO -// 13b7 CHEROKEE LETTER LU -// 13b8 CHEROKEE LETTER LV -// 13b9 CHEROKEE LETTER MA -// 13ba CHEROKEE LETTER ME -// 13bb CHEROKEE LETTER MI -// 13bc CHEROKEE LETTER MO -// 13bd CHEROKEE LETTER MU -// 13be CHEROKEE LETTER NA -// 13bf CHEROKEE LETTER HNA -// 13c0 CHEROKEE LETTER NAH -// 13c1 CHEROKEE LETTER NE -// 13c2 CHEROKEE LETTER NI -// 13c3 CHEROKEE LETTER NO -// 13c4 CHEROKEE LETTER NU -// 13c5 CHEROKEE LETTER NV -// 13c6 CHEROKEE LETTER QUA -// 13c7 CHEROKEE LETTER QUE -// 13c8 CHEROKEE LETTER QUI -// 13c9 CHEROKEE LETTER QUO -// 13ca CHEROKEE LETTER QUU -// 13cb CHEROKEE LETTER QUV -// 13cc CHEROKEE LETTER SA -// 13cd CHEROKEE LETTER S -// 13ce CHEROKEE LETTER SE -// 13cf CHEROKEE LETTER SI -// 13d0 CHEROKEE LETTER SO -// 13d1 CHEROKEE LETTER SU -// 13d2 CHEROKEE LETTER SV -// 13d3 CHEROKEE LETTER DA -// 13d4 CHEROKEE LETTER TA -// 13d5 CHEROKEE LETTER DE -// 13d6 CHEROKEE LETTER TE -// 13d7 CHEROKEE LETTER DI -// 13d8 CHEROKEE LETTER TI -// 13d9 CHEROKEE LETTER DO -// 13da CHEROKEE LETTER DU -// 13db CHEROKEE LETTER DV -// 13dc CHEROKEE LETTER DLA -// 13dd CHEROKEE LETTER TLA -// 13de CHEROKEE LETTER TLE -// 13df CHEROKEE LETTER TLI -// 13e0 CHEROKEE LETTER TLO -// 13e1 CHEROKEE LETTER TLU -// 13e2 CHEROKEE LETTER TLV -// 13e3 CHEROKEE LETTER TSA -// 13e4 CHEROKEE LETTER TSE -// 13e5 CHEROKEE LETTER TSI -// 13e6 CHEROKEE LETTER TSO -// 13e7 CHEROKEE LETTER TSU -// 13e8 CHEROKEE LETTER TSV -// 13e9 CHEROKEE LETTER WA -// 13ea CHEROKEE LETTER WE -// 13eb CHEROKEE LETTER WI -// 13ec CHEROKEE LETTER WO -// 13ed CHEROKEE LETTER WU -// 13ee CHEROKEE LETTER WV -// 13ef CHEROKEE LETTER YA -// 13f0 CHEROKEE LETTER YE -// 13f1 CHEROKEE LETTER YI -// 13f2 CHEROKEE LETTER YO -// 13f3 CHEROKEE LETTER YU -// 13f4 CHEROKEE LETTER YV - { 0x13A0, 0x55, 0x9, 0, 0 }, -// 1400 CANADIAN SYLLABICS HYPHEN - { 0x1400, 0x1, 0x18, 0, 0 }, -// 1401 CANADIAN SYLLABICS E -// 1402 CANADIAN SYLLABICS AAI -// 1403 CANADIAN SYLLABICS I -// 1404 CANADIAN SYLLABICS II -// 1405 CANADIAN SYLLABICS O -// 1406 CANADIAN SYLLABICS OO -// 1407 CANADIAN SYLLABICS Y-CREE OO -// 1408 CANADIAN SYLLABICS CARRIER EE -// 1409 CANADIAN SYLLABICS CARRIER I -// 140a CANADIAN SYLLABICS A -// 140b CANADIAN SYLLABICS AA -// 140c CANADIAN SYLLABICS WE -// 140d CANADIAN SYLLABICS WEST-CREE WE -// 140e CANADIAN SYLLABICS WI -// 140f CANADIAN SYLLABICS WEST-CREE WI -// 1410 CANADIAN SYLLABICS WII -// 1411 CANADIAN SYLLABICS WEST-CREE WII -// 1412 CANADIAN SYLLABICS WO -// 1413 CANADIAN SYLLABICS WEST-CREE WO -// 1414 CANADIAN SYLLABICS WOO -// 1415 CANADIAN SYLLABICS WEST-CREE WOO -// 1416 CANADIAN SYLLABICS NASKAPI WOO -// 1417 CANADIAN SYLLABICS WA -// 1418 CANADIAN SYLLABICS WEST-CREE WA -// 1419 CANADIAN SYLLABICS WAA -// 141a CANADIAN SYLLABICS WEST-CREE WAA -// 141b CANADIAN SYLLABICS NASKAPI WAA -// 141c CANADIAN SYLLABICS AI -// 141d CANADIAN SYLLABICS Y-CREE W -// 141e CANADIAN SYLLABICS GLOTTAL STOP -// 141f CANADIAN SYLLABICS FINAL ACUTE -// 1420 CANADIAN SYLLABICS FINAL GRAVE -// 1421 CANADIAN SYLLABICS FINAL BOTTOM HALF RING -// 1422 CANADIAN SYLLABICS FINAL TOP HALF RING -// 1423 CANADIAN SYLLABICS FINAL RIGHT HALF RING -// 1424 CANADIAN SYLLABICS FINAL RING -// 1425 CANADIAN SYLLABICS FINAL DOUBLE ACUTE -// 1426 CANADIAN SYLLABICS FINAL DOUBLE SHORT VERTICAL STROKES -// 1427 CANADIAN SYLLABICS FINAL MIDDLE DOT -// 1428 CANADIAN SYLLABICS FINAL SHORT HORIZONTAL STROKE -// 1429 CANADIAN SYLLABICS FINAL PLUS -// 142a CANADIAN SYLLABICS FINAL DOWN TACK -// 142b CANADIAN SYLLABICS EN -// 142c CANADIAN SYLLABICS IN -// 142d CANADIAN SYLLABICS ON -// 142e CANADIAN SYLLABICS AN -// 142f CANADIAN SYLLABICS PE -// 1430 CANADIAN SYLLABICS PAAI -// 1431 CANADIAN SYLLABICS PI -// 1432 CANADIAN SYLLABICS PII -// 1433 CANADIAN SYLLABICS PO -// 1434 CANADIAN SYLLABICS POO -// 1435 CANADIAN SYLLABICS Y-CREE POO -// 1436 CANADIAN SYLLABICS CARRIER HEE -// 1437 CANADIAN SYLLABICS CARRIER HI -// 1438 CANADIAN SYLLABICS PA -// 1439 CANADIAN SYLLABICS PAA -// 143a CANADIAN SYLLABICS PWE -// 143b CANADIAN SYLLABICS WEST-CREE PWE -// 143c CANADIAN SYLLABICS PWI -// 143d CANADIAN SYLLABICS WEST-CREE PWI -// 143e CANADIAN SYLLABICS PWII -// 143f CANADIAN SYLLABICS WEST-CREE PWII -// 1440 CANADIAN SYLLABICS PWO -// 1441 CANADIAN SYLLABICS WEST-CREE PWO -// 1442 CANADIAN SYLLABICS PWOO -// 1443 CANADIAN SYLLABICS WEST-CREE PWOO -// 1444 CANADIAN SYLLABICS PWA -// 1445 CANADIAN SYLLABICS WEST-CREE PWA -// 1446 CANADIAN SYLLABICS PWAA -// 1447 CANADIAN SYLLABICS WEST-CREE PWAA -// 1448 CANADIAN SYLLABICS Y-CREE PWAA -// 1449 CANADIAN SYLLABICS P -// 144a CANADIAN SYLLABICS WEST-CREE P -// 144b CANADIAN SYLLABICS CARRIER H -// 144c CANADIAN SYLLABICS TE -// 144d CANADIAN SYLLABICS TAAI -// 144e CANADIAN SYLLABICS TI -// 144f CANADIAN SYLLABICS TII -// 1450 CANADIAN SYLLABICS TO -// 1451 CANADIAN SYLLABICS TOO -// 1452 CANADIAN SYLLABICS Y-CREE TOO -// 1453 CANADIAN SYLLABICS CARRIER DEE -// 1454 CANADIAN SYLLABICS CARRIER DI -// 1455 CANADIAN SYLLABICS TA -// 1456 CANADIAN SYLLABICS TAA -// 1457 CANADIAN SYLLABICS TWE -// 1458 CANADIAN SYLLABICS WEST-CREE TWE -// 1459 CANADIAN SYLLABICS TWI -// 145a CANADIAN SYLLABICS WEST-CREE TWI -// 145b CANADIAN SYLLABICS TWII -// 145c CANADIAN SYLLABICS WEST-CREE TWII -// 145d CANADIAN SYLLABICS TWO -// 145e CANADIAN SYLLABICS WEST-CREE TWO -// 145f CANADIAN SYLLABICS TWOO -// 1460 CANADIAN SYLLABICS WEST-CREE TWOO -// 1461 CANADIAN SYLLABICS TWA -// 1462 CANADIAN SYLLABICS WEST-CREE TWA -// 1463 CANADIAN SYLLABICS TWAA -// 1464 CANADIAN SYLLABICS WEST-CREE TWAA -// 1465 CANADIAN SYLLABICS NASKAPI TWAA -// 1466 CANADIAN SYLLABICS T -// 1467 CANADIAN SYLLABICS TTE -// 1468 CANADIAN SYLLABICS TTI -// 1469 CANADIAN SYLLABICS TTO -// 146a CANADIAN SYLLABICS TTA -// 146b CANADIAN SYLLABICS KE -// 146c CANADIAN SYLLABICS KAAI -// 146d CANADIAN SYLLABICS KI -// 146e CANADIAN SYLLABICS KII -// 146f CANADIAN SYLLABICS KO -// 1470 CANADIAN SYLLABICS KOO -// 1471 CANADIAN SYLLABICS Y-CREE KOO -// 1472 CANADIAN SYLLABICS KA -// 1473 CANADIAN SYLLABICS KAA -// 1474 CANADIAN SYLLABICS KWE -// 1475 CANADIAN SYLLABICS WEST-CREE KWE -// 1476 CANADIAN SYLLABICS KWI -// 1477 CANADIAN SYLLABICS WEST-CREE KWI -// 1478 CANADIAN SYLLABICS KWII -// 1479 CANADIAN SYLLABICS WEST-CREE KWII -// 147a CANADIAN SYLLABICS KWO -// 147b CANADIAN SYLLABICS WEST-CREE KWO -// 147c CANADIAN SYLLABICS KWOO -// 147d CANADIAN SYLLABICS WEST-CREE KWOO -// 147e CANADIAN SYLLABICS KWA -// 147f CANADIAN SYLLABICS WEST-CREE KWA -// 1480 CANADIAN SYLLABICS KWAA -// 1481 CANADIAN SYLLABICS WEST-CREE KWAA -// 1482 CANADIAN SYLLABICS NASKAPI KWAA -// 1483 CANADIAN SYLLABICS K -// 1484 CANADIAN SYLLABICS KW -// 1485 CANADIAN SYLLABICS SOUTH-SLAVEY KEH -// 1486 CANADIAN SYLLABICS SOUTH-SLAVEY KIH -// 1487 CANADIAN SYLLABICS SOUTH-SLAVEY KOH -// 1488 CANADIAN SYLLABICS SOUTH-SLAVEY KAH -// 1489 CANADIAN SYLLABICS CE -// 148a CANADIAN SYLLABICS CAAI -// 148b CANADIAN SYLLABICS CI -// 148c CANADIAN SYLLABICS CII -// 148d CANADIAN SYLLABICS CO -// 148e CANADIAN SYLLABICS COO -// 148f CANADIAN SYLLABICS Y-CREE COO -// 1490 CANADIAN SYLLABICS CA -// 1491 CANADIAN SYLLABICS CAA -// 1492 CANADIAN SYLLABICS CWE -// 1493 CANADIAN SYLLABICS WEST-CREE CWE -// 1494 CANADIAN SYLLABICS CWI -// 1495 CANADIAN SYLLABICS WEST-CREE CWI -// 1496 CANADIAN SYLLABICS CWII -// 1497 CANADIAN SYLLABICS WEST-CREE CWII -// 1498 CANADIAN SYLLABICS CWO -// 1499 CANADIAN SYLLABICS WEST-CREE CWO -// 149a CANADIAN SYLLABICS CWOO -// 149b CANADIAN SYLLABICS WEST-CREE CWOO -// 149c CANADIAN SYLLABICS CWA -// 149d CANADIAN SYLLABICS WEST-CREE CWA -// 149e CANADIAN SYLLABICS CWAA -// 149f CANADIAN SYLLABICS WEST-CREE CWAA -// 14a0 CANADIAN SYLLABICS NASKAPI CWAA -// 14a1 CANADIAN SYLLABICS C -// 14a2 CANADIAN SYLLABICS SAYISI TH -// 14a3 CANADIAN SYLLABICS ME -// 14a4 CANADIAN SYLLABICS MAAI -// 14a5 CANADIAN SYLLABICS MI -// 14a6 CANADIAN SYLLABICS MII -// 14a7 CANADIAN SYLLABICS MO -// 14a8 CANADIAN SYLLABICS MOO -// 14a9 CANADIAN SYLLABICS Y-CREE MOO -// 14aa CANADIAN SYLLABICS MA -// 14ab CANADIAN SYLLABICS MAA -// 14ac CANADIAN SYLLABICS MWE -// 14ad CANADIAN SYLLABICS WEST-CREE MWE -// 14ae CANADIAN SYLLABICS MWI -// 14af CANADIAN SYLLABICS WEST-CREE MWI -// 14b0 CANADIAN SYLLABICS MWII -// 14b1 CANADIAN SYLLABICS WEST-CREE MWII -// 14b2 CANADIAN SYLLABICS MWO -// 14b3 CANADIAN SYLLABICS WEST-CREE MWO -// 14b4 CANADIAN SYLLABICS MWOO -// 14b5 CANADIAN SYLLABICS WEST-CREE MWOO -// 14b6 CANADIAN SYLLABICS MWA -// 14b7 CANADIAN SYLLABICS WEST-CREE MWA -// 14b8 CANADIAN SYLLABICS MWAA -// 14b9 CANADIAN SYLLABICS WEST-CREE MWAA -// 14ba CANADIAN SYLLABICS NASKAPI MWAA -// 14bb CANADIAN SYLLABICS M -// 14bc CANADIAN SYLLABICS WEST-CREE M -// 14bd CANADIAN SYLLABICS MH -// 14be CANADIAN SYLLABICS ATHAPASCAN M -// 14bf CANADIAN SYLLABICS SAYISI M -// 14c0 CANADIAN SYLLABICS NE -// 14c1 CANADIAN SYLLABICS NAAI -// 14c2 CANADIAN SYLLABICS NI -// 14c3 CANADIAN SYLLABICS NII -// 14c4 CANADIAN SYLLABICS NO -// 14c5 CANADIAN SYLLABICS NOO -// 14c6 CANADIAN SYLLABICS Y-CREE NOO -// 14c7 CANADIAN SYLLABICS NA -// 14c8 CANADIAN SYLLABICS NAA -// 14c9 CANADIAN SYLLABICS NWE -// 14ca CANADIAN SYLLABICS WEST-CREE NWE -// 14cb CANADIAN SYLLABICS NWA -// 14cc CANADIAN SYLLABICS WEST-CREE NWA -// 14cd CANADIAN SYLLABICS NWAA -// 14ce CANADIAN SYLLABICS WEST-CREE NWAA -// 14cf CANADIAN SYLLABICS NASKAPI NWAA -// 14d0 CANADIAN SYLLABICS N -// 14d1 CANADIAN SYLLABICS CARRIER NG -// 14d2 CANADIAN SYLLABICS NH -// 14d3 CANADIAN SYLLABICS LE -// 14d4 CANADIAN SYLLABICS LAAI -// 14d5 CANADIAN SYLLABICS LI -// 14d6 CANADIAN SYLLABICS LII -// 14d7 CANADIAN SYLLABICS LO -// 14d8 CANADIAN SYLLABICS LOO -// 14d9 CANADIAN SYLLABICS Y-CREE LOO -// 14da CANADIAN SYLLABICS LA -// 14db CANADIAN SYLLABICS LAA -// 14dc CANADIAN SYLLABICS LWE -// 14dd CANADIAN SYLLABICS WEST-CREE LWE -// 14de CANADIAN SYLLABICS LWI -// 14df CANADIAN SYLLABICS WEST-CREE LWI -// 14e0 CANADIAN SYLLABICS LWII -// 14e1 CANADIAN SYLLABICS WEST-CREE LWII -// 14e2 CANADIAN SYLLABICS LWO -// 14e3 CANADIAN SYLLABICS WEST-CREE LWO -// 14e4 CANADIAN SYLLABICS LWOO -// 14e5 CANADIAN SYLLABICS WEST-CREE LWOO -// 14e6 CANADIAN SYLLABICS LWA -// 14e7 CANADIAN SYLLABICS WEST-CREE LWA -// 14e8 CANADIAN SYLLABICS LWAA -// 14e9 CANADIAN SYLLABICS WEST-CREE LWAA -// 14ea CANADIAN SYLLABICS L -// 14eb CANADIAN SYLLABICS WEST-CREE L -// 14ec CANADIAN SYLLABICS MEDIAL L -// 14ed CANADIAN SYLLABICS SE -// 14ee CANADIAN SYLLABICS SAAI -// 14ef CANADIAN SYLLABICS SI -// 14f0 CANADIAN SYLLABICS SII -// 14f1 CANADIAN SYLLABICS SO -// 14f2 CANADIAN SYLLABICS SOO -// 14f3 CANADIAN SYLLABICS Y-CREE SOO -// 14f4 CANADIAN SYLLABICS SA -// 14f5 CANADIAN SYLLABICS SAA -// 14f6 CANADIAN SYLLABICS SWE -// 14f7 CANADIAN SYLLABICS WEST-CREE SWE -// 14f8 CANADIAN SYLLABICS SWI -// 14f9 CANADIAN SYLLABICS WEST-CREE SWI -// 14fa CANADIAN SYLLABICS SWII -// 14fb CANADIAN SYLLABICS WEST-CREE SWII -// 14fc CANADIAN SYLLABICS SWO -// 14fd CANADIAN SYLLABICS WEST-CREE SWO -// 14fe CANADIAN SYLLABICS SWOO -// 14ff CANADIAN SYLLABICS WEST-CREE SWOO -// 1500 CANADIAN SYLLABICS SWA -// 1501 CANADIAN SYLLABICS WEST-CREE SWA -// 1502 CANADIAN SYLLABICS SWAA -// 1503 CANADIAN SYLLABICS WEST-CREE SWAA -// 1504 CANADIAN SYLLABICS NASKAPI SWAA -// 1505 CANADIAN SYLLABICS S -// 1506 CANADIAN SYLLABICS ATHAPASCAN S -// 1507 CANADIAN SYLLABICS SW -// 1508 CANADIAN SYLLABICS BLACKFOOT S -// 1509 CANADIAN SYLLABICS MOOSE-CREE SK -// 150a CANADIAN SYLLABICS NASKAPI SKW -// 150b CANADIAN SYLLABICS NASKAPI S-W -// 150c CANADIAN SYLLABICS NASKAPI SPWA -// 150d CANADIAN SYLLABICS NASKAPI STWA -// 150e CANADIAN SYLLABICS NASKAPI SKWA -// 150f CANADIAN SYLLABICS NASKAPI SCWA -// 1510 CANADIAN SYLLABICS SHE -// 1511 CANADIAN SYLLABICS SHI -// 1512 CANADIAN SYLLABICS SHII -// 1513 CANADIAN SYLLABICS SHO -// 1514 CANADIAN SYLLABICS SHOO -// 1515 CANADIAN SYLLABICS SHA -// 1516 CANADIAN SYLLABICS SHAA -// 1517 CANADIAN SYLLABICS SHWE -// 1518 CANADIAN SYLLABICS WEST-CREE SHWE -// 1519 CANADIAN SYLLABICS SHWI -// 151a CANADIAN SYLLABICS WEST-CREE SHWI -// 151b CANADIAN SYLLABICS SHWII -// 151c CANADIAN SYLLABICS WEST-CREE SHWII -// 151d CANADIAN SYLLABICS SHWO -// 151e CANADIAN SYLLABICS WEST-CREE SHWO -// 151f CANADIAN SYLLABICS SHWOO -// 1520 CANADIAN SYLLABICS WEST-CREE SHWOO -// 1521 CANADIAN SYLLABICS SHWA -// 1522 CANADIAN SYLLABICS WEST-CREE SHWA -// 1523 CANADIAN SYLLABICS SHWAA -// 1524 CANADIAN SYLLABICS WEST-CREE SHWAA -// 1525 CANADIAN SYLLABICS SH -// 1526 CANADIAN SYLLABICS YE -// 1527 CANADIAN SYLLABICS YAAI -// 1528 CANADIAN SYLLABICS YI -// 1529 CANADIAN SYLLABICS YII -// 152a CANADIAN SYLLABICS YO -// 152b CANADIAN SYLLABICS YOO -// 152c CANADIAN SYLLABICS Y-CREE YOO -// 152d CANADIAN SYLLABICS YA -// 152e CANADIAN SYLLABICS YAA -// 152f CANADIAN SYLLABICS YWE -// 1530 CANADIAN SYLLABICS WEST-CREE YWE -// 1531 CANADIAN SYLLABICS YWI -// 1532 CANADIAN SYLLABICS WEST-CREE YWI -// 1533 CANADIAN SYLLABICS YWII -// 1534 CANADIAN SYLLABICS WEST-CREE YWII -// 1535 CANADIAN SYLLABICS YWO -// 1536 CANADIAN SYLLABICS WEST-CREE YWO -// 1537 CANADIAN SYLLABICS YWOO -// 1538 CANADIAN SYLLABICS WEST-CREE YWOO -// 1539 CANADIAN SYLLABICS YWA -// 153a CANADIAN SYLLABICS WEST-CREE YWA -// 153b CANADIAN SYLLABICS YWAA -// 153c CANADIAN SYLLABICS WEST-CREE YWAA -// 153d CANADIAN SYLLABICS NASKAPI YWAA -// 153e CANADIAN SYLLABICS Y -// 153f CANADIAN SYLLABICS BIBLE-CREE Y -// 1540 CANADIAN SYLLABICS WEST-CREE Y -// 1541 CANADIAN SYLLABICS SAYISI YI -// 1542 CANADIAN SYLLABICS RE -// 1543 CANADIAN SYLLABICS R-CREE RE -// 1544 CANADIAN SYLLABICS WEST-CREE LE -// 1545 CANADIAN SYLLABICS RAAI -// 1546 CANADIAN SYLLABICS RI -// 1547 CANADIAN SYLLABICS RII -// 1548 CANADIAN SYLLABICS RO -// 1549 CANADIAN SYLLABICS ROO -// 154a CANADIAN SYLLABICS WEST-CREE LO -// 154b CANADIAN SYLLABICS RA -// 154c CANADIAN SYLLABICS RAA -// 154d CANADIAN SYLLABICS WEST-CREE LA -// 154e CANADIAN SYLLABICS RWAA -// 154f CANADIAN SYLLABICS WEST-CREE RWAA -// 1550 CANADIAN SYLLABICS R -// 1551 CANADIAN SYLLABICS WEST-CREE R -// 1552 CANADIAN SYLLABICS MEDIAL R -// 1553 CANADIAN SYLLABICS FE -// 1554 CANADIAN SYLLABICS FAAI -// 1555 CANADIAN SYLLABICS FI -// 1556 CANADIAN SYLLABICS FII -// 1557 CANADIAN SYLLABICS FO -// 1558 CANADIAN SYLLABICS FOO -// 1559 CANADIAN SYLLABICS FA -// 155a CANADIAN SYLLABICS FAA -// 155b CANADIAN SYLLABICS FWAA -// 155c CANADIAN SYLLABICS WEST-CREE FWAA -// 155d CANADIAN SYLLABICS F -// 155e CANADIAN SYLLABICS THE -// 155f CANADIAN SYLLABICS N-CREE THE -// 1560 CANADIAN SYLLABICS THI -// 1561 CANADIAN SYLLABICS N-CREE THI -// 1562 CANADIAN SYLLABICS THII -// 1563 CANADIAN SYLLABICS N-CREE THII -// 1564 CANADIAN SYLLABICS THO -// 1565 CANADIAN SYLLABICS THOO -// 1566 CANADIAN SYLLABICS THA -// 1567 CANADIAN SYLLABICS THAA -// 1568 CANADIAN SYLLABICS THWAA -// 1569 CANADIAN SYLLABICS WEST-CREE THWAA -// 156a CANADIAN SYLLABICS TH -// 156b CANADIAN SYLLABICS TTHE -// 156c CANADIAN SYLLABICS TTHI -// 156d CANADIAN SYLLABICS TTHO -// 156e CANADIAN SYLLABICS TTHA -// 156f CANADIAN SYLLABICS TTH -// 1570 CANADIAN SYLLABICS TYE -// 1571 CANADIAN SYLLABICS TYI -// 1572 CANADIAN SYLLABICS TYO -// 1573 CANADIAN SYLLABICS TYA -// 1574 CANADIAN SYLLABICS NUNAVIK HE -// 1575 CANADIAN SYLLABICS NUNAVIK HI -// 1576 CANADIAN SYLLABICS NUNAVIK HII -// 1577 CANADIAN SYLLABICS NUNAVIK HO -// 1578 CANADIAN SYLLABICS NUNAVIK HOO -// 1579 CANADIAN SYLLABICS NUNAVIK HA -// 157a CANADIAN SYLLABICS NUNAVIK HAA -// 157b CANADIAN SYLLABICS NUNAVIK H -// 157c CANADIAN SYLLABICS NUNAVUT H -// 157d CANADIAN SYLLABICS HK -// 157e CANADIAN SYLLABICS QAAI -// 157f CANADIAN SYLLABICS QI -// 1580 CANADIAN SYLLABICS QII -// 1581 CANADIAN SYLLABICS QO -// 1582 CANADIAN SYLLABICS QOO -// 1583 CANADIAN SYLLABICS QA -// 1584 CANADIAN SYLLABICS QAA -// 1585 CANADIAN SYLLABICS Q -// 1586 CANADIAN SYLLABICS TLHE -// 1587 CANADIAN SYLLABICS TLHI -// 1588 CANADIAN SYLLABICS TLHO -// 1589 CANADIAN SYLLABICS TLHA -// 158a CANADIAN SYLLABICS WEST-CREE RE -// 158b CANADIAN SYLLABICS WEST-CREE RI -// 158c CANADIAN SYLLABICS WEST-CREE RO -// 158d CANADIAN SYLLABICS WEST-CREE RA -// 158e CANADIAN SYLLABICS NGAAI -// 158f CANADIAN SYLLABICS NGI -// 1590 CANADIAN SYLLABICS NGII -// 1591 CANADIAN SYLLABICS NGO -// 1592 CANADIAN SYLLABICS NGOO -// 1593 CANADIAN SYLLABICS NGA -// 1594 CANADIAN SYLLABICS NGAA -// 1595 CANADIAN SYLLABICS NG -// 1596 CANADIAN SYLLABICS NNG -// 1597 CANADIAN SYLLABICS SAYISI SHE -// 1598 CANADIAN SYLLABICS SAYISI SHI -// 1599 CANADIAN SYLLABICS SAYISI SHO -// 159a CANADIAN SYLLABICS SAYISI SHA -// 159b CANADIAN SYLLABICS WOODS-CREE THE -// 159c CANADIAN SYLLABICS WOODS-CREE THI -// 159d CANADIAN SYLLABICS WOODS-CREE THO -// 159e CANADIAN SYLLABICS WOODS-CREE THA -// 159f CANADIAN SYLLABICS WOODS-CREE TH -// 15a0 CANADIAN SYLLABICS LHI -// 15a1 CANADIAN SYLLABICS LHII -// 15a2 CANADIAN SYLLABICS LHO -// 15a3 CANADIAN SYLLABICS LHOO -// 15a4 CANADIAN SYLLABICS LHA -// 15a5 CANADIAN SYLLABICS LHAA -// 15a6 CANADIAN SYLLABICS LH -// 15a7 CANADIAN SYLLABICS TH-CREE THE -// 15a8 CANADIAN SYLLABICS TH-CREE THI -// 15a9 CANADIAN SYLLABICS TH-CREE THII -// 15aa CANADIAN SYLLABICS TH-CREE THO -// 15ab CANADIAN SYLLABICS TH-CREE THOO -// 15ac CANADIAN SYLLABICS TH-CREE THA -// 15ad CANADIAN SYLLABICS TH-CREE THAA -// 15ae CANADIAN SYLLABICS TH-CREE TH -// 15af CANADIAN SYLLABICS AIVILIK B -// 15b0 CANADIAN SYLLABICS BLACKFOOT E -// 15b1 CANADIAN SYLLABICS BLACKFOOT I -// 15b2 CANADIAN SYLLABICS BLACKFOOT O -// 15b3 CANADIAN SYLLABICS BLACKFOOT A -// 15b4 CANADIAN SYLLABICS BLACKFOOT WE -// 15b5 CANADIAN SYLLABICS BLACKFOOT WI -// 15b6 CANADIAN SYLLABICS BLACKFOOT WO -// 15b7 CANADIAN SYLLABICS BLACKFOOT WA -// 15b8 CANADIAN SYLLABICS BLACKFOOT NE -// 15b9 CANADIAN SYLLABICS BLACKFOOT NI -// 15ba CANADIAN SYLLABICS BLACKFOOT NO -// 15bb CANADIAN SYLLABICS BLACKFOOT NA -// 15bc CANADIAN SYLLABICS BLACKFOOT KE -// 15bd CANADIAN SYLLABICS BLACKFOOT KI -// 15be CANADIAN SYLLABICS BLACKFOOT KO -// 15bf CANADIAN SYLLABICS BLACKFOOT KA -// 15c0 CANADIAN SYLLABICS SAYISI HE -// 15c1 CANADIAN SYLLABICS SAYISI HI -// 15c2 CANADIAN SYLLABICS SAYISI HO -// 15c3 CANADIAN SYLLABICS SAYISI HA -// 15c4 CANADIAN SYLLABICS CARRIER GHU -// 15c5 CANADIAN SYLLABICS CARRIER GHO -// 15c6 CANADIAN SYLLABICS CARRIER GHE -// 15c7 CANADIAN SYLLABICS CARRIER GHEE -// 15c8 CANADIAN SYLLABICS CARRIER GHI -// 15c9 CANADIAN SYLLABICS CARRIER GHA -// 15ca CANADIAN SYLLABICS CARRIER RU -// 15cb CANADIAN SYLLABICS CARRIER RO -// 15cc CANADIAN SYLLABICS CARRIER RE -// 15cd CANADIAN SYLLABICS CARRIER REE -// 15ce CANADIAN SYLLABICS CARRIER RI -// 15cf CANADIAN SYLLABICS CARRIER RA -// 15d0 CANADIAN SYLLABICS CARRIER WU -// 15d1 CANADIAN SYLLABICS CARRIER WO -// 15d2 CANADIAN SYLLABICS CARRIER WE -// 15d3 CANADIAN SYLLABICS CARRIER WEE -// 15d4 CANADIAN SYLLABICS CARRIER WI -// 15d5 CANADIAN SYLLABICS CARRIER WA -// 15d6 CANADIAN SYLLABICS CARRIER HWU -// 15d7 CANADIAN SYLLABICS CARRIER HWO -// 15d8 CANADIAN SYLLABICS CARRIER HWE -// 15d9 CANADIAN SYLLABICS CARRIER HWEE -// 15da CANADIAN SYLLABICS CARRIER HWI -// 15db CANADIAN SYLLABICS CARRIER HWA -// 15dc CANADIAN SYLLABICS CARRIER THU -// 15dd CANADIAN SYLLABICS CARRIER THO -// 15de CANADIAN SYLLABICS CARRIER THE -// 15df CANADIAN SYLLABICS CARRIER THEE -// 15e0 CANADIAN SYLLABICS CARRIER THI -// 15e1 CANADIAN SYLLABICS CARRIER THA -// 15e2 CANADIAN SYLLABICS CARRIER TTU -// 15e3 CANADIAN SYLLABICS CARRIER TTO -// 15e4 CANADIAN SYLLABICS CARRIER TTE -// 15e5 CANADIAN SYLLABICS CARRIER TTEE -// 15e6 CANADIAN SYLLABICS CARRIER TTI -// 15e7 CANADIAN SYLLABICS CARRIER TTA -// 15e8 CANADIAN SYLLABICS CARRIER PU -// 15e9 CANADIAN SYLLABICS CARRIER PO -// 15ea CANADIAN SYLLABICS CARRIER PE -// 15eb CANADIAN SYLLABICS CARRIER PEE -// 15ec CANADIAN SYLLABICS CARRIER PI -// 15ed CANADIAN SYLLABICS CARRIER PA -// 15ee CANADIAN SYLLABICS CARRIER P -// 15ef CANADIAN SYLLABICS CARRIER GU -// 15f0 CANADIAN SYLLABICS CARRIER GO -// 15f1 CANADIAN SYLLABICS CARRIER GE -// 15f2 CANADIAN SYLLABICS CARRIER GEE -// 15f3 CANADIAN SYLLABICS CARRIER GI -// 15f4 CANADIAN SYLLABICS CARRIER GA -// 15f5 CANADIAN SYLLABICS CARRIER KHU -// 15f6 CANADIAN SYLLABICS CARRIER KHO -// 15f7 CANADIAN SYLLABICS CARRIER KHE -// 15f8 CANADIAN SYLLABICS CARRIER KHEE -// 15f9 CANADIAN SYLLABICS CARRIER KHI -// 15fa CANADIAN SYLLABICS CARRIER KHA -// 15fb CANADIAN SYLLABICS CARRIER KKU -// 15fc CANADIAN SYLLABICS CARRIER KKO -// 15fd CANADIAN SYLLABICS CARRIER KKE -// 15fe CANADIAN SYLLABICS CARRIER KKEE -// 15ff CANADIAN SYLLABICS CARRIER KKI -// 1600 CANADIAN SYLLABICS CARRIER KKA -// 1601 CANADIAN SYLLABICS CARRIER KK -// 1602 CANADIAN SYLLABICS CARRIER NU -// 1603 CANADIAN SYLLABICS CARRIER NO -// 1604 CANADIAN SYLLABICS CARRIER NE -// 1605 CANADIAN SYLLABICS CARRIER NEE -// 1606 CANADIAN SYLLABICS CARRIER NI -// 1607 CANADIAN SYLLABICS CARRIER NA -// 1608 CANADIAN SYLLABICS CARRIER MU -// 1609 CANADIAN SYLLABICS CARRIER MO -// 160a CANADIAN SYLLABICS CARRIER ME -// 160b CANADIAN SYLLABICS CARRIER MEE -// 160c CANADIAN SYLLABICS CARRIER MI -// 160d CANADIAN SYLLABICS CARRIER MA -// 160e CANADIAN SYLLABICS CARRIER YU -// 160f CANADIAN SYLLABICS CARRIER YO -// 1610 CANADIAN SYLLABICS CARRIER YE -// 1611 CANADIAN SYLLABICS CARRIER YEE -// 1612 CANADIAN SYLLABICS CARRIER YI -// 1613 CANADIAN SYLLABICS CARRIER YA -// 1614 CANADIAN SYLLABICS CARRIER JU -// 1615 CANADIAN SYLLABICS SAYISI JU -// 1616 CANADIAN SYLLABICS CARRIER JO -// 1617 CANADIAN SYLLABICS CARRIER JE -// 1618 CANADIAN SYLLABICS CARRIER JEE -// 1619 CANADIAN SYLLABICS CARRIER JI -// 161a CANADIAN SYLLABICS SAYISI JI -// 161b CANADIAN SYLLABICS CARRIER JA -// 161c CANADIAN SYLLABICS CARRIER JJU -// 161d CANADIAN SYLLABICS CARRIER JJO -// 161e CANADIAN SYLLABICS CARRIER JJE -// 161f CANADIAN SYLLABICS CARRIER JJEE -// 1620 CANADIAN SYLLABICS CARRIER JJI -// 1621 CANADIAN SYLLABICS CARRIER JJA -// 1622 CANADIAN SYLLABICS CARRIER LU -// 1623 CANADIAN SYLLABICS CARRIER LO -// 1624 CANADIAN SYLLABICS CARRIER LE -// 1625 CANADIAN SYLLABICS CARRIER LEE -// 1626 CANADIAN SYLLABICS CARRIER LI -// 1627 CANADIAN SYLLABICS CARRIER LA -// 1628 CANADIAN SYLLABICS CARRIER DLU -// 1629 CANADIAN SYLLABICS CARRIER DLO -// 162a CANADIAN SYLLABICS CARRIER DLE -// 162b CANADIAN SYLLABICS CARRIER DLEE -// 162c CANADIAN SYLLABICS CARRIER DLI -// 162d CANADIAN SYLLABICS CARRIER DLA -// 162e CANADIAN SYLLABICS CARRIER LHU -// 162f CANADIAN SYLLABICS CARRIER LHO -// 1630 CANADIAN SYLLABICS CARRIER LHE -// 1631 CANADIAN SYLLABICS CARRIER LHEE -// 1632 CANADIAN SYLLABICS CARRIER LHI -// 1633 CANADIAN SYLLABICS CARRIER LHA -// 1634 CANADIAN SYLLABICS CARRIER TLHU -// 1635 CANADIAN SYLLABICS CARRIER TLHO -// 1636 CANADIAN SYLLABICS CARRIER TLHE -// 1637 CANADIAN SYLLABICS CARRIER TLHEE -// 1638 CANADIAN SYLLABICS CARRIER TLHI -// 1639 CANADIAN SYLLABICS CARRIER TLHA -// 163a CANADIAN SYLLABICS CARRIER TLU -// 163b CANADIAN SYLLABICS CARRIER TLO -// 163c CANADIAN SYLLABICS CARRIER TLE -// 163d CANADIAN SYLLABICS CARRIER TLEE -// 163e CANADIAN SYLLABICS CARRIER TLI -// 163f CANADIAN SYLLABICS CARRIER TLA -// 1640 CANADIAN SYLLABICS CARRIER ZU -// 1641 CANADIAN SYLLABICS CARRIER ZO -// 1642 CANADIAN SYLLABICS CARRIER ZE -// 1643 CANADIAN SYLLABICS CARRIER ZEE -// 1644 CANADIAN SYLLABICS CARRIER ZI -// 1645 CANADIAN SYLLABICS CARRIER ZA -// 1646 CANADIAN SYLLABICS CARRIER Z -// 1647 CANADIAN SYLLABICS CARRIER INITIAL Z -// 1648 CANADIAN SYLLABICS CARRIER DZU -// 1649 CANADIAN SYLLABICS CARRIER DZO -// 164a CANADIAN SYLLABICS CARRIER DZE -// 164b CANADIAN SYLLABICS CARRIER DZEE -// 164c CANADIAN SYLLABICS CARRIER DZI -// 164d CANADIAN SYLLABICS CARRIER DZA -// 164e CANADIAN SYLLABICS CARRIER SU -// 164f CANADIAN SYLLABICS CARRIER SO -// 1650 CANADIAN SYLLABICS CARRIER SE -// 1651 CANADIAN SYLLABICS CARRIER SEE -// 1652 CANADIAN SYLLABICS CARRIER SI -// 1653 CANADIAN SYLLABICS CARRIER SA -// 1654 CANADIAN SYLLABICS CARRIER SHU -// 1655 CANADIAN SYLLABICS CARRIER SHO -// 1656 CANADIAN SYLLABICS CARRIER SHE -// 1657 CANADIAN SYLLABICS CARRIER SHEE -// 1658 CANADIAN SYLLABICS CARRIER SHI -// 1659 CANADIAN SYLLABICS CARRIER SHA -// 165a CANADIAN SYLLABICS CARRIER SH -// 165b CANADIAN SYLLABICS CARRIER TSU -// 165c CANADIAN SYLLABICS CARRIER TSO -// 165d CANADIAN SYLLABICS CARRIER TSE -// 165e CANADIAN SYLLABICS CARRIER TSEE -// 165f CANADIAN SYLLABICS CARRIER TSI -// 1660 CANADIAN SYLLABICS CARRIER TSA -// 1661 CANADIAN SYLLABICS CARRIER CHU -// 1662 CANADIAN SYLLABICS CARRIER CHO -// 1663 CANADIAN SYLLABICS CARRIER CHE -// 1664 CANADIAN SYLLABICS CARRIER CHEE -// 1665 CANADIAN SYLLABICS CARRIER CHI -// 1666 CANADIAN SYLLABICS CARRIER CHA -// 1667 CANADIAN SYLLABICS CARRIER TTSU -// 1668 CANADIAN SYLLABICS CARRIER TTSO -// 1669 CANADIAN SYLLABICS CARRIER TTSE -// 166a CANADIAN SYLLABICS CARRIER TTSEE -// 166b CANADIAN SYLLABICS CARRIER TTSI -// 166c CANADIAN SYLLABICS CARRIER TTSA - { 0x1401, 0x26C, 0x9, 0, 0 }, -// 166d CANADIAN SYLLABICS CHI SIGN -// 166e CANADIAN SYLLABICS FULL STOP - { 0x166D, 0x2, 0x18, 0, 0 }, -// 166f CANADIAN SYLLABICS QAI -// 1670 CANADIAN SYLLABICS NGAI -// 1671 CANADIAN SYLLABICS NNGI -// 1672 CANADIAN SYLLABICS NNGII -// 1673 CANADIAN SYLLABICS NNGO -// 1674 CANADIAN SYLLABICS NNGOO -// 1675 CANADIAN SYLLABICS NNGA -// 1676 CANADIAN SYLLABICS NNGAA -// 1677 CANADIAN SYLLABICS WOODS-CREE THWEE -// 1678 CANADIAN SYLLABICS WOODS-CREE THWI -// 1679 CANADIAN SYLLABICS WOODS-CREE THWII -// 167a CANADIAN SYLLABICS WOODS-CREE THWO -// 167b CANADIAN SYLLABICS WOODS-CREE THWOO -// 167c CANADIAN SYLLABICS WOODS-CREE THWA -// 167d CANADIAN SYLLABICS WOODS-CREE THWAA -// 167e CANADIAN SYLLABICS WOODS-CREE FINAL TH -// 167f CANADIAN SYLLABICS BLACKFOOT W - { 0x166F, 0x11, 0x9, 0, 0 }, -// 1680 OGHAM SPACE MARK - { 0x1680, 0x1, 0x20, 0, 0 }, -// 1681 OGHAM LETTER BEITH -// 1682 OGHAM LETTER LUIS -// 1683 OGHAM LETTER FEARN -// 1684 OGHAM LETTER SAIL -// 1685 OGHAM LETTER NION -// 1686 OGHAM LETTER UATH -// 1687 OGHAM LETTER DAIR -// 1688 OGHAM LETTER TINNE -// 1689 OGHAM LETTER COLL -// 168a OGHAM LETTER CEIRT -// 168b OGHAM LETTER MUIN -// 168c OGHAM LETTER GORT -// 168d OGHAM LETTER NGEADAL -// 168e OGHAM LETTER STRAIF -// 168f OGHAM LETTER RUIS -// 1690 OGHAM LETTER AILM -// 1691 OGHAM LETTER ONN -// 1692 OGHAM LETTER UR -// 1693 OGHAM LETTER EADHADH -// 1694 OGHAM LETTER IODHADH -// 1695 OGHAM LETTER EABHADH -// 1696 OGHAM LETTER OR -// 1697 OGHAM LETTER UILLEANN -// 1698 OGHAM LETTER IFIN -// 1699 OGHAM LETTER EAMHANCHOLL -// 169a OGHAM LETTER PEITH - { 0x1681, 0x1A, 0x9, 0, 0 }, -// 169b OGHAM FEATHER MARK -// 169c OGHAM REVERSED FEATHER MARK - { 0x169B, 0x2, 0x18, 0, 0 }, -// 16a0 RUNIC LETTER FEHU FEOH FE F -// 16a1 RUNIC LETTER V -// 16a2 RUNIC LETTER URUZ UR U -// 16a3 RUNIC LETTER YR -// 16a4 RUNIC LETTER Y -// 16a5 RUNIC LETTER W -// 16a6 RUNIC LETTER THURISAZ THURS THORN -// 16a7 RUNIC LETTER ETH -// 16a8 RUNIC LETTER ANSUZ A -// 16a9 RUNIC LETTER OS O -// 16aa RUNIC LETTER AC A -// 16ab RUNIC LETTER AESC -// 16ac RUNIC LETTER LONG-BRANCH-OSS O -// 16ad RUNIC LETTER SHORT-TWIG-OSS O -// 16ae RUNIC LETTER O -// 16af RUNIC LETTER OE -// 16b0 RUNIC LETTER ON -// 16b1 RUNIC LETTER RAIDO RAD REID R -// 16b2 RUNIC LETTER KAUNA -// 16b3 RUNIC LETTER CEN -// 16b4 RUNIC LETTER KAUN K -// 16b5 RUNIC LETTER G -// 16b6 RUNIC LETTER ENG -// 16b7 RUNIC LETTER GEBO GYFU G -// 16b8 RUNIC LETTER GAR -// 16b9 RUNIC LETTER WUNJO WYNN W -// 16ba RUNIC LETTER HAGLAZ H -// 16bb RUNIC LETTER HAEGL H -// 16bc RUNIC LETTER LONG-BRANCH-HAGALL H -// 16bd RUNIC LETTER SHORT-TWIG-HAGALL H -// 16be RUNIC LETTER NAUDIZ NYD NAUD N -// 16bf RUNIC LETTER SHORT-TWIG-NAUD N -// 16c0 RUNIC LETTER DOTTED-N -// 16c1 RUNIC LETTER ISAZ IS ISS I -// 16c2 RUNIC LETTER E -// 16c3 RUNIC LETTER JERAN J -// 16c4 RUNIC LETTER GER -// 16c5 RUNIC LETTER LONG-BRANCH-AR AE -// 16c6 RUNIC LETTER SHORT-TWIG-AR A -// 16c7 RUNIC LETTER IWAZ EOH -// 16c8 RUNIC LETTER PERTHO PEORTH P -// 16c9 RUNIC LETTER ALGIZ EOLHX -// 16ca RUNIC LETTER SOWILO S -// 16cb RUNIC LETTER SIGEL LONG-BRANCH-SOL S -// 16cc RUNIC LETTER SHORT-TWIG-SOL S -// 16cd RUNIC LETTER C -// 16ce RUNIC LETTER Z -// 16cf RUNIC LETTER TIWAZ TIR TYR T -// 16d0 RUNIC LETTER SHORT-TWIG-TYR T -// 16d1 RUNIC LETTER D -// 16d2 RUNIC LETTER BERKANAN BEORC BJARKAN B -// 16d3 RUNIC LETTER SHORT-TWIG-BJARKAN B -// 16d4 RUNIC LETTER DOTTED-P -// 16d5 RUNIC LETTER OPEN-P -// 16d6 RUNIC LETTER EHWAZ EH E -// 16d7 RUNIC LETTER MANNAZ MAN M -// 16d8 RUNIC LETTER LONG-BRANCH-MADR M -// 16d9 RUNIC LETTER SHORT-TWIG-MADR M -// 16da RUNIC LETTER LAUKAZ LAGU LOGR L -// 16db RUNIC LETTER DOTTED-L -// 16dc RUNIC LETTER INGWAZ -// 16dd RUNIC LETTER ING -// 16de RUNIC LETTER DAGAZ DAEG D -// 16df RUNIC LETTER OTHALAN ETHEL O -// 16e0 RUNIC LETTER EAR -// 16e1 RUNIC LETTER IOR -// 16e2 RUNIC LETTER CWEORTH -// 16e3 RUNIC LETTER CALC -// 16e4 RUNIC LETTER CEALC -// 16e5 RUNIC LETTER STAN -// 16e6 RUNIC LETTER LONG-BRANCH-YR -// 16e7 RUNIC LETTER SHORT-TWIG-YR -// 16e8 RUNIC LETTER ICELANDIC-YR -// 16e9 RUNIC LETTER Q -// 16ea RUNIC LETTER X - { 0x16A0, 0x4B, 0x9, 0, 0 }, -// 16eb RUNIC SINGLE PUNCTUATION -// 16ec RUNIC MULTIPLE PUNCTUATION -// 16ed RUNIC CROSS PUNCTUATION - { 0x16EB, 0x3, 0x18, 0, 0 }, -// 16ee RUNIC ARLAUG SYMBOL -// 16ef RUNIC TVIMADUR SYMBOL -// 16f0 RUNIC BELGTHOR SYMBOL - { 0x16EE, 0x3, 0x8, 0, 0 }, -// 16f1 RUNIC LETTER K -// 16f2 RUNIC LETTER SH -// 16f3 RUNIC LETTER OO -// 16f4 RUNIC LETTER FRANKS CASKET OS -// 16f5 RUNIC LETTER FRANKS CASKET IS -// 16f6 RUNIC LETTER FRANKS CASKET EH -// 16f7 RUNIC LETTER FRANKS CASKET AC -// 16f8 RUNIC LETTER FRANKS CASKET AESC - { 0x16F1, 0x8, 0x9, 0, 0 }, -// 1700 TAGALOG LETTER A -// 1701 TAGALOG LETTER I -// 1702 TAGALOG LETTER U -// 1703 TAGALOG LETTER KA -// 1704 TAGALOG LETTER GA -// 1705 TAGALOG LETTER NGA -// 1706 TAGALOG LETTER TA -// 1707 TAGALOG LETTER DA -// 1708 TAGALOG LETTER NA -// 1709 TAGALOG LETTER PA -// 170a TAGALOG LETTER BA -// 170b TAGALOG LETTER MA -// 170c TAGALOG LETTER YA - { 0x1700, 0xD, 0x9, 0, 0 }, -// 170e TAGALOG LETTER LA -// 170f TAGALOG LETTER WA -// 1710 TAGALOG LETTER SA -// 1711 TAGALOG LETTER HA - { 0x170E, 0x4, 0x9, 0, 0 }, -// 1712 TAGALOG VOWEL SIGN I -// 1713 TAGALOG VOWEL SIGN U -// 1714 TAGALOG SIGN VIRAMA - { 0x1712, 0x3, 0x0, 0, 0 }, -// 1720 HANUNOO LETTER A -// 1721 HANUNOO LETTER I -// 1722 HANUNOO LETTER U -// 1723 HANUNOO LETTER KA -// 1724 HANUNOO LETTER GA -// 1725 HANUNOO LETTER NGA -// 1726 HANUNOO LETTER TA -// 1727 HANUNOO LETTER DA -// 1728 HANUNOO LETTER NA -// 1729 HANUNOO LETTER PA -// 172a HANUNOO LETTER BA -// 172b HANUNOO LETTER MA -// 172c HANUNOO LETTER YA -// 172d HANUNOO LETTER RA -// 172e HANUNOO LETTER LA -// 172f HANUNOO LETTER WA -// 1730 HANUNOO LETTER SA -// 1731 HANUNOO LETTER HA - { 0x1720, 0x12, 0x9, 0, 0 }, -// 1732 HANUNOO VOWEL SIGN I -// 1733 HANUNOO VOWEL SIGN U -// 1734 HANUNOO SIGN PAMUDPOD - { 0x1732, 0x3, 0x0, 0, 0 }, -// 1735 PHILIPPINE SINGLE PUNCTUATION -// 1736 PHILIPPINE DOUBLE PUNCTUATION - { 0x1735, 0x2, 0x18, 0, 0 }, -// 1740 BUHID LETTER A -// 1741 BUHID LETTER I -// 1742 BUHID LETTER U -// 1743 BUHID LETTER KA -// 1744 BUHID LETTER GA -// 1745 BUHID LETTER NGA -// 1746 BUHID LETTER TA -// 1747 BUHID LETTER DA -// 1748 BUHID LETTER NA -// 1749 BUHID LETTER PA -// 174a BUHID LETTER BA -// 174b BUHID LETTER MA -// 174c BUHID LETTER YA -// 174d BUHID LETTER RA -// 174e BUHID LETTER LA -// 174f BUHID LETTER WA -// 1750 BUHID LETTER SA -// 1751 BUHID LETTER HA - { 0x1740, 0x12, 0x9, 0, 0 }, -// 1752 BUHID VOWEL SIGN I -// 1753 BUHID VOWEL SIGN U - { 0x1752, 0x2, 0x0, 0, 0 }, -// 1760 TAGBANWA LETTER A -// 1761 TAGBANWA LETTER I -// 1762 TAGBANWA LETTER U -// 1763 TAGBANWA LETTER KA -// 1764 TAGBANWA LETTER GA -// 1765 TAGBANWA LETTER NGA -// 1766 TAGBANWA LETTER TA -// 1767 TAGBANWA LETTER DA -// 1768 TAGBANWA LETTER NA -// 1769 TAGBANWA LETTER PA -// 176a TAGBANWA LETTER BA -// 176b TAGBANWA LETTER MA -// 176c TAGBANWA LETTER YA - { 0x1760, 0xD, 0x9, 0, 0 }, -// 176e TAGBANWA LETTER LA -// 176f TAGBANWA LETTER WA -// 1770 TAGBANWA LETTER SA - { 0x176E, 0x3, 0x9, 0, 0 }, -// 1772 TAGBANWA VOWEL SIGN I -// 1773 TAGBANWA VOWEL SIGN U - { 0x1772, 0x2, 0x0, 0, 0 }, -// 1780 KHMER LETTER KA -// 1781 KHMER LETTER KHA -// 1782 KHMER LETTER KO -// 1783 KHMER LETTER KHO -// 1784 KHMER LETTER NGO -// 1785 KHMER LETTER CA -// 1786 KHMER LETTER CHA -// 1787 KHMER LETTER CO -// 1788 KHMER LETTER CHO -// 1789 KHMER LETTER NYO -// 178a KHMER LETTER DA -// 178b KHMER LETTER TTHA -// 178c KHMER LETTER DO -// 178d KHMER LETTER TTHO -// 178e KHMER LETTER NNO -// 178f KHMER LETTER TA -// 1790 KHMER LETTER THA -// 1791 KHMER LETTER TO -// 1792 KHMER LETTER THO -// 1793 KHMER LETTER NO -// 1794 KHMER LETTER BA -// 1795 KHMER LETTER PHA -// 1796 KHMER LETTER PO -// 1797 KHMER LETTER PHO -// 1798 KHMER LETTER MO -// 1799 KHMER LETTER YO -// 179a KHMER LETTER RO -// 179b KHMER LETTER LO -// 179c KHMER LETTER VO -// 179d KHMER LETTER SHA -// 179e KHMER LETTER SSO -// 179f KHMER LETTER SA -// 17a0 KHMER LETTER HA -// 17a1 KHMER LETTER LA -// 17a2 KHMER LETTER QA -// 17a3 KHMER INDEPENDENT VOWEL QAQ -// 17a4 KHMER INDEPENDENT VOWEL QAA -// 17a5 KHMER INDEPENDENT VOWEL QI -// 17a6 KHMER INDEPENDENT VOWEL QII -// 17a7 KHMER INDEPENDENT VOWEL QU -// 17a8 KHMER INDEPENDENT VOWEL QUK -// 17a9 KHMER INDEPENDENT VOWEL QUU -// 17aa KHMER INDEPENDENT VOWEL QUUV -// 17ab KHMER INDEPENDENT VOWEL RY -// 17ac KHMER INDEPENDENT VOWEL RYY -// 17ad KHMER INDEPENDENT VOWEL LY -// 17ae KHMER INDEPENDENT VOWEL LYY -// 17af KHMER INDEPENDENT VOWEL QE -// 17b0 KHMER INDEPENDENT VOWEL QAI -// 17b1 KHMER INDEPENDENT VOWEL QOO TYPE ONE -// 17b2 KHMER INDEPENDENT VOWEL QOO TYPE TWO -// 17b3 KHMER INDEPENDENT VOWEL QAU - { 0x1780, 0x34, 0x9, 0, 0 }, -// 17b4 KHMER VOWEL INHERENT AQ -// 17b5 KHMER VOWEL INHERENT AA -// 17b6 KHMER VOWEL SIGN AA -// 17b7 KHMER VOWEL SIGN I -// 17b8 KHMER VOWEL SIGN II -// 17b9 KHMER VOWEL SIGN Y -// 17ba KHMER VOWEL SIGN YY -// 17bb KHMER VOWEL SIGN U -// 17bc KHMER VOWEL SIGN UU -// 17bd KHMER VOWEL SIGN UA -// 17be KHMER VOWEL SIGN OE -// 17bf KHMER VOWEL SIGN YA -// 17c0 KHMER VOWEL SIGN IE -// 17c1 KHMER VOWEL SIGN E -// 17c2 KHMER VOWEL SIGN AE -// 17c3 KHMER VOWEL SIGN AI -// 17c4 KHMER VOWEL SIGN OO -// 17c5 KHMER VOWEL SIGN AU -// 17c6 KHMER SIGN NIKAHIT -// 17c7 KHMER SIGN REAHMUK -// 17c8 KHMER SIGN YUUKALEAPINTU -// 17c9 KHMER SIGN MUUSIKATOAN -// 17ca KHMER SIGN TRIISAP -// 17cb KHMER SIGN BANTOC -// 17cc KHMER SIGN ROBAT -// 17cd KHMER SIGN TOANDAKHIAT -// 17ce KHMER SIGN KAKABAT -// 17cf KHMER SIGN AHSDA -// 17d0 KHMER SIGN SAMYOK SANNYA -// 17d1 KHMER SIGN VIRIAM -// 17d2 KHMER SIGN COENG -// 17d3 KHMER SIGN BATHAMASAT - { 0x17B4, 0x20, 0x0, 0, 0 }, -// 17d4 KHMER SIGN KHAN -// 17d5 KHMER SIGN BARIYOOSAN -// 17d6 KHMER SIGN CAMNUC PII KUUH - { 0x17D4, 0x3, 0x18, 0, 0 }, -// 17d7 KHMER SIGN LEK TOO - { 0x17D7, 0x1, 0x9, 0, 0 }, -// 17d8 KHMER SIGN BEYYAL -// 17d9 KHMER SIGN PHNAEK MUAN -// 17da KHMER SIGN KOOMUUT - { 0x17D8, 0x3, 0x18, 0, 0 }, -// 17db KHMER CURRENCY SYMBOL RIEL - { 0x17DB, 0x1, 0x8, 0, 0 }, -// 17dc KHMER SIGN AVAKRAHASANYA - { 0x17DC, 0x1, 0x9, 0, 0 }, -// 17dd KHMER SIGN ATTHACAN - { 0x17DD, 0x1, 0x0, 0, 0 }, -// 17e0 KHMER DIGIT ZERO -// 17e1 KHMER DIGIT ONE -// 17e2 KHMER DIGIT TWO -// 17e3 KHMER DIGIT THREE -// 17e4 KHMER DIGIT FOUR -// 17e5 KHMER DIGIT FIVE -// 17e6 KHMER DIGIT SIX -// 17e7 KHMER DIGIT SEVEN -// 17e8 KHMER DIGIT EIGHT -// 17e9 KHMER DIGIT NINE - { 0x17E0, 0xA, 0x108, 0, 0 }, -// 17f0 KHMER SYMBOL LEK ATTAK SON -// 17f1 KHMER SYMBOL LEK ATTAK MUOY -// 17f2 KHMER SYMBOL LEK ATTAK PII -// 17f3 KHMER SYMBOL LEK ATTAK BEI -// 17f4 KHMER SYMBOL LEK ATTAK BUON -// 17f5 KHMER SYMBOL LEK ATTAK PRAM -// 17f6 KHMER SYMBOL LEK ATTAK PRAM-MUOY -// 17f7 KHMER SYMBOL LEK ATTAK PRAM-PII -// 17f8 KHMER SYMBOL LEK ATTAK PRAM-BEI -// 17f9 KHMER SYMBOL LEK ATTAK PRAM-BUON - { 0x17F0, 0xA, 0x8, 0, 0 }, -// 1800 MONGOLIAN BIRGA -// 1801 MONGOLIAN ELLIPSIS -// 1802 MONGOLIAN COMMA -// 1803 MONGOLIAN FULL STOP -// 1804 MONGOLIAN COLON -// 1805 MONGOLIAN FOUR DOTS -// 1806 MONGOLIAN TODO SOFT HYPHEN -// 1807 MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER -// 1808 MONGOLIAN MANCHU COMMA -// 1809 MONGOLIAN MANCHU FULL STOP -// 180a MONGOLIAN NIRUGU - { 0x1800, 0xB, 0x18, 0, 0 }, -// 180b MONGOLIAN FREE VARIATION SELECTOR ONE -// 180c MONGOLIAN FREE VARIATION SELECTOR TWO -// 180d MONGOLIAN FREE VARIATION SELECTOR THREE -// 180e MONGOLIAN VOWEL SEPARATOR - { 0x180B, 0x4, 0x0, 0, 0 }, -// 1810 MONGOLIAN DIGIT ZERO -// 1811 MONGOLIAN DIGIT ONE -// 1812 MONGOLIAN DIGIT TWO -// 1813 MONGOLIAN DIGIT THREE -// 1814 MONGOLIAN DIGIT FOUR -// 1815 MONGOLIAN DIGIT FIVE -// 1816 MONGOLIAN DIGIT SIX -// 1817 MONGOLIAN DIGIT SEVEN -// 1818 MONGOLIAN DIGIT EIGHT -// 1819 MONGOLIAN DIGIT NINE - { 0x1810, 0xA, 0x108, 0, 0 }, -// 1820 MONGOLIAN LETTER A -// 1821 MONGOLIAN LETTER E -// 1822 MONGOLIAN LETTER I -// 1823 MONGOLIAN LETTER O -// 1824 MONGOLIAN LETTER U -// 1825 MONGOLIAN LETTER OE -// 1826 MONGOLIAN LETTER UE -// 1827 MONGOLIAN LETTER EE -// 1828 MONGOLIAN LETTER NA -// 1829 MONGOLIAN LETTER ANG -// 182a MONGOLIAN LETTER BA -// 182b MONGOLIAN LETTER PA -// 182c MONGOLIAN LETTER QA -// 182d MONGOLIAN LETTER GA -// 182e MONGOLIAN LETTER MA -// 182f MONGOLIAN LETTER LA -// 1830 MONGOLIAN LETTER SA -// 1831 MONGOLIAN LETTER SHA -// 1832 MONGOLIAN LETTER TA -// 1833 MONGOLIAN LETTER DA -// 1834 MONGOLIAN LETTER CHA -// 1835 MONGOLIAN LETTER JA -// 1836 MONGOLIAN LETTER YA -// 1837 MONGOLIAN LETTER RA -// 1838 MONGOLIAN LETTER WA -// 1839 MONGOLIAN LETTER FA -// 183a MONGOLIAN LETTER KA -// 183b MONGOLIAN LETTER KHA -// 183c MONGOLIAN LETTER TSA -// 183d MONGOLIAN LETTER ZA -// 183e MONGOLIAN LETTER HAA -// 183f MONGOLIAN LETTER ZRA -// 1840 MONGOLIAN LETTER LHA -// 1841 MONGOLIAN LETTER ZHI -// 1842 MONGOLIAN LETTER CHI -// 1843 MONGOLIAN LETTER TODO LONG VOWEL SIGN -// 1844 MONGOLIAN LETTER TODO E -// 1845 MONGOLIAN LETTER TODO I -// 1846 MONGOLIAN LETTER TODO O -// 1847 MONGOLIAN LETTER TODO U -// 1848 MONGOLIAN LETTER TODO OE -// 1849 MONGOLIAN LETTER TODO UE -// 184a MONGOLIAN LETTER TODO ANG -// 184b MONGOLIAN LETTER TODO BA -// 184c MONGOLIAN LETTER TODO PA -// 184d MONGOLIAN LETTER TODO QA -// 184e MONGOLIAN LETTER TODO GA -// 184f MONGOLIAN LETTER TODO MA -// 1850 MONGOLIAN LETTER TODO TA -// 1851 MONGOLIAN LETTER TODO DA -// 1852 MONGOLIAN LETTER TODO CHA -// 1853 MONGOLIAN LETTER TODO JA -// 1854 MONGOLIAN LETTER TODO TSA -// 1855 MONGOLIAN LETTER TODO YA -// 1856 MONGOLIAN LETTER TODO WA -// 1857 MONGOLIAN LETTER TODO KA -// 1858 MONGOLIAN LETTER TODO GAA -// 1859 MONGOLIAN LETTER TODO HAA -// 185a MONGOLIAN LETTER TODO JIA -// 185b MONGOLIAN LETTER TODO NIA -// 185c MONGOLIAN LETTER TODO DZA -// 185d MONGOLIAN LETTER SIBE E -// 185e MONGOLIAN LETTER SIBE I -// 185f MONGOLIAN LETTER SIBE IY -// 1860 MONGOLIAN LETTER SIBE UE -// 1861 MONGOLIAN LETTER SIBE U -// 1862 MONGOLIAN LETTER SIBE ANG -// 1863 MONGOLIAN LETTER SIBE KA -// 1864 MONGOLIAN LETTER SIBE GA -// 1865 MONGOLIAN LETTER SIBE HA -// 1866 MONGOLIAN LETTER SIBE PA -// 1867 MONGOLIAN LETTER SIBE SHA -// 1868 MONGOLIAN LETTER SIBE TA -// 1869 MONGOLIAN LETTER SIBE DA -// 186a MONGOLIAN LETTER SIBE JA -// 186b MONGOLIAN LETTER SIBE FA -// 186c MONGOLIAN LETTER SIBE GAA -// 186d MONGOLIAN LETTER SIBE HAA -// 186e MONGOLIAN LETTER SIBE TSA -// 186f MONGOLIAN LETTER SIBE ZA -// 1870 MONGOLIAN LETTER SIBE RAA -// 1871 MONGOLIAN LETTER SIBE CHA -// 1872 MONGOLIAN LETTER SIBE ZHA -// 1873 MONGOLIAN LETTER MANCHU I -// 1874 MONGOLIAN LETTER MANCHU KA -// 1875 MONGOLIAN LETTER MANCHU RA -// 1876 MONGOLIAN LETTER MANCHU FA -// 1877 MONGOLIAN LETTER MANCHU ZHA - { 0x1820, 0x58, 0x9, 0, 0 }, -// 1880 MONGOLIAN LETTER ALI GALI ANUSVARA ONE -// 1881 MONGOLIAN LETTER ALI GALI VISARGA ONE -// 1882 MONGOLIAN LETTER ALI GALI DAMARU -// 1883 MONGOLIAN LETTER ALI GALI UBADAMA -// 1884 MONGOLIAN LETTER ALI GALI INVERTED UBADAMA -// 1885 MONGOLIAN LETTER ALI GALI BALUDA -// 1886 MONGOLIAN LETTER ALI GALI THREE BALUDA -// 1887 MONGOLIAN LETTER ALI GALI A -// 1888 MONGOLIAN LETTER ALI GALI I -// 1889 MONGOLIAN LETTER ALI GALI KA -// 188a MONGOLIAN LETTER ALI GALI NGA -// 188b MONGOLIAN LETTER ALI GALI CA -// 188c MONGOLIAN LETTER ALI GALI TTA -// 188d MONGOLIAN LETTER ALI GALI TTHA -// 188e MONGOLIAN LETTER ALI GALI DDA -// 188f MONGOLIAN LETTER ALI GALI NNA -// 1890 MONGOLIAN LETTER ALI GALI TA -// 1891 MONGOLIAN LETTER ALI GALI DA -// 1892 MONGOLIAN LETTER ALI GALI PA -// 1893 MONGOLIAN LETTER ALI GALI PHA -// 1894 MONGOLIAN LETTER ALI GALI SSA -// 1895 MONGOLIAN LETTER ALI GALI ZHA -// 1896 MONGOLIAN LETTER ALI GALI ZA -// 1897 MONGOLIAN LETTER ALI GALI AH -// 1898 MONGOLIAN LETTER TODO ALI GALI TA -// 1899 MONGOLIAN LETTER TODO ALI GALI ZHA -// 189a MONGOLIAN LETTER MANCHU ALI GALI GHA -// 189b MONGOLIAN LETTER MANCHU ALI GALI NGA -// 189c MONGOLIAN LETTER MANCHU ALI GALI CA -// 189d MONGOLIAN LETTER MANCHU ALI GALI JHA -// 189e MONGOLIAN LETTER MANCHU ALI GALI TTA -// 189f MONGOLIAN LETTER MANCHU ALI GALI DDHA -// 18a0 MONGOLIAN LETTER MANCHU ALI GALI TA -// 18a1 MONGOLIAN LETTER MANCHU ALI GALI DHA -// 18a2 MONGOLIAN LETTER MANCHU ALI GALI SSA -// 18a3 MONGOLIAN LETTER MANCHU ALI GALI CYA -// 18a4 MONGOLIAN LETTER MANCHU ALI GALI ZHA -// 18a5 MONGOLIAN LETTER MANCHU ALI GALI ZA -// 18a6 MONGOLIAN LETTER ALI GALI HALF U -// 18a7 MONGOLIAN LETTER ALI GALI HALF YA -// 18a8 MONGOLIAN LETTER MANCHU ALI GALI BHA - { 0x1880, 0x29, 0x9, 0, 0 }, -// 18a9 MONGOLIAN LETTER ALI GALI DAGALGA - { 0x18A9, 0x1, 0x0, 0, 0 }, -// 18aa MONGOLIAN LETTER MANCHU ALI GALI LHA - { 0x18AA, 0x1, 0x9, 0, 0 }, -// 18b0 CANADIAN SYLLABICS OY -// 18b1 CANADIAN SYLLABICS AY -// 18b2 CANADIAN SYLLABICS AAY -// 18b3 CANADIAN SYLLABICS WAY -// 18b4 CANADIAN SYLLABICS POY -// 18b5 CANADIAN SYLLABICS PAY -// 18b6 CANADIAN SYLLABICS PWOY -// 18b7 CANADIAN SYLLABICS TAY -// 18b8 CANADIAN SYLLABICS KAY -// 18b9 CANADIAN SYLLABICS KWAY -// 18ba CANADIAN SYLLABICS MAY -// 18bb CANADIAN SYLLABICS NOY -// 18bc CANADIAN SYLLABICS NAY -// 18bd CANADIAN SYLLABICS LAY -// 18be CANADIAN SYLLABICS SOY -// 18bf CANADIAN SYLLABICS SAY -// 18c0 CANADIAN SYLLABICS SHOY -// 18c1 CANADIAN SYLLABICS SHAY -// 18c2 CANADIAN SYLLABICS SHWOY -// 18c3 CANADIAN SYLLABICS YOY -// 18c4 CANADIAN SYLLABICS YAY -// 18c5 CANADIAN SYLLABICS RAY -// 18c6 CANADIAN SYLLABICS NWI -// 18c7 CANADIAN SYLLABICS OJIBWAY NWI -// 18c8 CANADIAN SYLLABICS NWII -// 18c9 CANADIAN SYLLABICS OJIBWAY NWII -// 18ca CANADIAN SYLLABICS NWO -// 18cb CANADIAN SYLLABICS OJIBWAY NWO -// 18cc CANADIAN SYLLABICS NWOO -// 18cd CANADIAN SYLLABICS OJIBWAY NWOO -// 18ce CANADIAN SYLLABICS RWEE -// 18cf CANADIAN SYLLABICS RWI -// 18d0 CANADIAN SYLLABICS RWII -// 18d1 CANADIAN SYLLABICS RWO -// 18d2 CANADIAN SYLLABICS RWOO -// 18d3 CANADIAN SYLLABICS RWA -// 18d4 CANADIAN SYLLABICS OJIBWAY P -// 18d5 CANADIAN SYLLABICS OJIBWAY T -// 18d6 CANADIAN SYLLABICS OJIBWAY K -// 18d7 CANADIAN SYLLABICS OJIBWAY C -// 18d8 CANADIAN SYLLABICS OJIBWAY M -// 18d9 CANADIAN SYLLABICS OJIBWAY N -// 18da CANADIAN SYLLABICS OJIBWAY S -// 18db CANADIAN SYLLABICS OJIBWAY SH -// 18dc CANADIAN SYLLABICS EASTERN W -// 18dd CANADIAN SYLLABICS WESTERN W -// 18de CANADIAN SYLLABICS FINAL SMALL RING -// 18df CANADIAN SYLLABICS FINAL RAISED DOT -// 18e0 CANADIAN SYLLABICS R-CREE RWE -// 18e1 CANADIAN SYLLABICS WEST-CREE LOO -// 18e2 CANADIAN SYLLABICS WEST-CREE LAA -// 18e3 CANADIAN SYLLABICS THWE -// 18e4 CANADIAN SYLLABICS THWA -// 18e5 CANADIAN SYLLABICS TTHWE -// 18e6 CANADIAN SYLLABICS TTHOO -// 18e7 CANADIAN SYLLABICS TTHAA -// 18e8 CANADIAN SYLLABICS TLHWE -// 18e9 CANADIAN SYLLABICS TLHOO -// 18ea CANADIAN SYLLABICS SAYISI SHWE -// 18eb CANADIAN SYLLABICS SAYISI SHOO -// 18ec CANADIAN SYLLABICS SAYISI HOO -// 18ed CANADIAN SYLLABICS CARRIER GWU -// 18ee CANADIAN SYLLABICS CARRIER DENE GEE -// 18ef CANADIAN SYLLABICS CARRIER GAA -// 18f0 CANADIAN SYLLABICS CARRIER GWA -// 18f1 CANADIAN SYLLABICS SAYISI JUU -// 18f2 CANADIAN SYLLABICS CARRIER JWA -// 18f3 CANADIAN SYLLABICS BEAVER DENE L -// 18f4 CANADIAN SYLLABICS BEAVER DENE R -// 18f5 CANADIAN SYLLABICS CARRIER DENTAL S - { 0x18B0, 0x46, 0x9, 0, 0 }, -// 1900 LIMBU VOWEL-CARRIER LETTER -// 1901 LIMBU LETTER KA -// 1902 LIMBU LETTER KHA -// 1903 LIMBU LETTER GA -// 1904 LIMBU LETTER GHA -// 1905 LIMBU LETTER NGA -// 1906 LIMBU LETTER CA -// 1907 LIMBU LETTER CHA -// 1908 LIMBU LETTER JA -// 1909 LIMBU LETTER JHA -// 190a LIMBU LETTER YAN -// 190b LIMBU LETTER TA -// 190c LIMBU LETTER THA -// 190d LIMBU LETTER DA -// 190e LIMBU LETTER DHA -// 190f LIMBU LETTER NA -// 1910 LIMBU LETTER PA -// 1911 LIMBU LETTER PHA -// 1912 LIMBU LETTER BA -// 1913 LIMBU LETTER BHA -// 1914 LIMBU LETTER MA -// 1915 LIMBU LETTER YA -// 1916 LIMBU LETTER RA -// 1917 LIMBU LETTER LA -// 1918 LIMBU LETTER WA -// 1919 LIMBU LETTER SHA -// 191a LIMBU LETTER SSA -// 191b LIMBU LETTER SA -// 191c LIMBU LETTER HA -// 191d LIMBU LETTER GYAN -// 191e LIMBU LETTER TRA - { 0x1900, 0x1F, 0x9, 0, 0 }, -// 1920 LIMBU VOWEL SIGN A -// 1921 LIMBU VOWEL SIGN I -// 1922 LIMBU VOWEL SIGN U -// 1923 LIMBU VOWEL SIGN EE -// 1924 LIMBU VOWEL SIGN AI -// 1925 LIMBU VOWEL SIGN OO -// 1926 LIMBU VOWEL SIGN AU -// 1927 LIMBU VOWEL SIGN E -// 1928 LIMBU VOWEL SIGN O -// 1929 LIMBU SUBJOINED LETTER YA -// 192a LIMBU SUBJOINED LETTER RA -// 192b LIMBU SUBJOINED LETTER WA - { 0x1920, 0xC, 0x0, 0, 0 }, -// 1930 LIMBU SMALL LETTER KA -// 1931 LIMBU SMALL LETTER NGA -// 1932 LIMBU SMALL LETTER ANUSVARA -// 1933 LIMBU SMALL LETTER TA -// 1934 LIMBU SMALL LETTER NA -// 1935 LIMBU SMALL LETTER PA -// 1936 LIMBU SMALL LETTER MA -// 1937 LIMBU SMALL LETTER RA -// 1938 LIMBU SMALL LETTER LA -// 1939 LIMBU SIGN MUKPHRENG -// 193a LIMBU SIGN KEMPHRENG -// 193b LIMBU SIGN SA-I - { 0x1930, 0xC, 0x0, 0, 0 }, -// 1940 LIMBU SIGN LOO - { 0x1940, 0x1, 0x8, 0, 0 }, -// 1944 LIMBU EXCLAMATION MARK -// 1945 LIMBU QUESTION MARK - { 0x1944, 0x2, 0x18, 0, 0 }, -// 1946 LIMBU DIGIT ZERO -// 1947 LIMBU DIGIT ONE -// 1948 LIMBU DIGIT TWO -// 1949 LIMBU DIGIT THREE -// 194a LIMBU DIGIT FOUR -// 194b LIMBU DIGIT FIVE -// 194c LIMBU DIGIT SIX -// 194d LIMBU DIGIT SEVEN -// 194e LIMBU DIGIT EIGHT -// 194f LIMBU DIGIT NINE - { 0x1946, 0xA, 0x108, 0, 0 }, -// 1950 TAI LE LETTER KA -// 1951 TAI LE LETTER XA -// 1952 TAI LE LETTER NGA -// 1953 TAI LE LETTER TSA -// 1954 TAI LE LETTER SA -// 1955 TAI LE LETTER YA -// 1956 TAI LE LETTER TA -// 1957 TAI LE LETTER THA -// 1958 TAI LE LETTER LA -// 1959 TAI LE LETTER PA -// 195a TAI LE LETTER PHA -// 195b TAI LE LETTER MA -// 195c TAI LE LETTER FA -// 195d TAI LE LETTER VA -// 195e TAI LE LETTER HA -// 195f TAI LE LETTER QA -// 1960 TAI LE LETTER KHA -// 1961 TAI LE LETTER TSHA -// 1962 TAI LE LETTER NA -// 1963 TAI LE LETTER A -// 1964 TAI LE LETTER I -// 1965 TAI LE LETTER EE -// 1966 TAI LE LETTER EH -// 1967 TAI LE LETTER U -// 1968 TAI LE LETTER OO -// 1969 TAI LE LETTER O -// 196a TAI LE LETTER UE -// 196b TAI LE LETTER E -// 196c TAI LE LETTER AUE -// 196d TAI LE LETTER AI - { 0x1950, 0x1E, 0x9, 0, 0 }, -// 1970 TAI LE LETTER TONE-2 -// 1971 TAI LE LETTER TONE-3 -// 1972 TAI LE LETTER TONE-4 -// 1973 TAI LE LETTER TONE-5 -// 1974 TAI LE LETTER TONE-6 - { 0x1970, 0x5, 0x9, 0, 0 }, -// 1980 NEW TAI LUE LETTER HIGH QA -// 1981 NEW TAI LUE LETTER LOW QA -// 1982 NEW TAI LUE LETTER HIGH KA -// 1983 NEW TAI LUE LETTER HIGH XA -// 1984 NEW TAI LUE LETTER HIGH NGA -// 1985 NEW TAI LUE LETTER LOW KA -// 1986 NEW TAI LUE LETTER LOW XA -// 1987 NEW TAI LUE LETTER LOW NGA -// 1988 NEW TAI LUE LETTER HIGH TSA -// 1989 NEW TAI LUE LETTER HIGH SA -// 198a NEW TAI LUE LETTER HIGH YA -// 198b NEW TAI LUE LETTER LOW TSA -// 198c NEW TAI LUE LETTER LOW SA -// 198d NEW TAI LUE LETTER LOW YA -// 198e NEW TAI LUE LETTER HIGH TA -// 198f NEW TAI LUE LETTER HIGH THA -// 1990 NEW TAI LUE LETTER HIGH NA -// 1991 NEW TAI LUE LETTER LOW TA -// 1992 NEW TAI LUE LETTER LOW THA -// 1993 NEW TAI LUE LETTER LOW NA -// 1994 NEW TAI LUE LETTER HIGH PA -// 1995 NEW TAI LUE LETTER HIGH PHA -// 1996 NEW TAI LUE LETTER HIGH MA -// 1997 NEW TAI LUE LETTER LOW PA -// 1998 NEW TAI LUE LETTER LOW PHA -// 1999 NEW TAI LUE LETTER LOW MA -// 199a NEW TAI LUE LETTER HIGH FA -// 199b NEW TAI LUE LETTER HIGH VA -// 199c NEW TAI LUE LETTER HIGH LA -// 199d NEW TAI LUE LETTER LOW FA -// 199e NEW TAI LUE LETTER LOW VA -// 199f NEW TAI LUE LETTER LOW LA -// 19a0 NEW TAI LUE LETTER HIGH HA -// 19a1 NEW TAI LUE LETTER HIGH DA -// 19a2 NEW TAI LUE LETTER HIGH BA -// 19a3 NEW TAI LUE LETTER LOW HA -// 19a4 NEW TAI LUE LETTER LOW DA -// 19a5 NEW TAI LUE LETTER LOW BA -// 19a6 NEW TAI LUE LETTER HIGH KVA -// 19a7 NEW TAI LUE LETTER HIGH XVA -// 19a8 NEW TAI LUE LETTER LOW KVA -// 19a9 NEW TAI LUE LETTER LOW XVA -// 19aa NEW TAI LUE LETTER HIGH SUA -// 19ab NEW TAI LUE LETTER LOW SUA - { 0x1980, 0x2C, 0x9, 0, 0 }, -// 19b0 NEW TAI LUE VOWEL SIGN VOWEL SHORTENER -// 19b1 NEW TAI LUE VOWEL SIGN AA -// 19b2 NEW TAI LUE VOWEL SIGN II -// 19b3 NEW TAI LUE VOWEL SIGN U -// 19b4 NEW TAI LUE VOWEL SIGN UU -// 19b5 NEW TAI LUE VOWEL SIGN E -// 19b6 NEW TAI LUE VOWEL SIGN AE -// 19b7 NEW TAI LUE VOWEL SIGN O -// 19b8 NEW TAI LUE VOWEL SIGN OA -// 19b9 NEW TAI LUE VOWEL SIGN UE -// 19ba NEW TAI LUE VOWEL SIGN AY -// 19bb NEW TAI LUE VOWEL SIGN AAY -// 19bc NEW TAI LUE VOWEL SIGN UY -// 19bd NEW TAI LUE VOWEL SIGN OY -// 19be NEW TAI LUE VOWEL SIGN OAY -// 19bf NEW TAI LUE VOWEL SIGN UEY -// 19c0 NEW TAI LUE VOWEL SIGN IY - { 0x19B0, 0x11, 0x0, 0, 0 }, -// 19c1 NEW TAI LUE LETTER FINAL V -// 19c2 NEW TAI LUE LETTER FINAL NG -// 19c3 NEW TAI LUE LETTER FINAL N -// 19c4 NEW TAI LUE LETTER FINAL M -// 19c5 NEW TAI LUE LETTER FINAL K -// 19c6 NEW TAI LUE LETTER FINAL D -// 19c7 NEW TAI LUE LETTER FINAL B - { 0x19C1, 0x7, 0x9, 0, 0 }, -// 19c8 NEW TAI LUE TONE MARK-1 -// 19c9 NEW TAI LUE TONE MARK-2 - { 0x19C8, 0x2, 0x0, 0, 0 }, -// 19d0 NEW TAI LUE DIGIT ZERO -// 19d1 NEW TAI LUE DIGIT ONE -// 19d2 NEW TAI LUE DIGIT TWO -// 19d3 NEW TAI LUE DIGIT THREE -// 19d4 NEW TAI LUE DIGIT FOUR -// 19d5 NEW TAI LUE DIGIT FIVE -// 19d6 NEW TAI LUE DIGIT SIX -// 19d7 NEW TAI LUE DIGIT SEVEN -// 19d8 NEW TAI LUE DIGIT EIGHT -// 19d9 NEW TAI LUE DIGIT NINE - { 0x19D0, 0xA, 0x108, 0, 0 }, -// 19da NEW TAI LUE THAM DIGIT ONE - { 0x19DA, 0x1, 0x8, 0, 0 }, -// 19de NEW TAI LUE SIGN LAE -// 19df NEW TAI LUE SIGN LAEV -// 19e0 KHMER SYMBOL PATHAMASAT -// 19e1 KHMER SYMBOL MUOY KOET -// 19e2 KHMER SYMBOL PII KOET -// 19e3 KHMER SYMBOL BEI KOET -// 19e4 KHMER SYMBOL BUON KOET -// 19e5 KHMER SYMBOL PRAM KOET -// 19e6 KHMER SYMBOL PRAM-MUOY KOET -// 19e7 KHMER SYMBOL PRAM-PII KOET -// 19e8 KHMER SYMBOL PRAM-BEI KOET -// 19e9 KHMER SYMBOL PRAM-BUON KOET -// 19ea KHMER SYMBOL DAP KOET -// 19eb KHMER SYMBOL DAP-MUOY KOET -// 19ec KHMER SYMBOL DAP-PII KOET -// 19ed KHMER SYMBOL DAP-BEI KOET -// 19ee KHMER SYMBOL DAP-BUON KOET -// 19ef KHMER SYMBOL DAP-PRAM KOET -// 19f0 KHMER SYMBOL TUTEYASAT -// 19f1 KHMER SYMBOL MUOY ROC -// 19f2 KHMER SYMBOL PII ROC -// 19f3 KHMER SYMBOL BEI ROC -// 19f4 KHMER SYMBOL BUON ROC -// 19f5 KHMER SYMBOL PRAM ROC -// 19f6 KHMER SYMBOL PRAM-MUOY ROC -// 19f7 KHMER SYMBOL PRAM-PII ROC -// 19f8 KHMER SYMBOL PRAM-BEI ROC -// 19f9 KHMER SYMBOL PRAM-BUON ROC -// 19fa KHMER SYMBOL DAP ROC -// 19fb KHMER SYMBOL DAP-MUOY ROC -// 19fc KHMER SYMBOL DAP-PII ROC -// 19fd KHMER SYMBOL DAP-BEI ROC -// 19fe KHMER SYMBOL DAP-BUON ROC -// 19ff KHMER SYMBOL DAP-PRAM ROC - { 0x19DE, 0x22, 0x8, 0, 0 }, -// 1a00 BUGINESE LETTER KA -// 1a01 BUGINESE LETTER GA -// 1a02 BUGINESE LETTER NGA -// 1a03 BUGINESE LETTER NGKA -// 1a04 BUGINESE LETTER PA -// 1a05 BUGINESE LETTER BA -// 1a06 BUGINESE LETTER MA -// 1a07 BUGINESE LETTER MPA -// 1a08 BUGINESE LETTER TA -// 1a09 BUGINESE LETTER DA -// 1a0a BUGINESE LETTER NA -// 1a0b BUGINESE LETTER NRA -// 1a0c BUGINESE LETTER CA -// 1a0d BUGINESE LETTER JA -// 1a0e BUGINESE LETTER NYA -// 1a0f BUGINESE LETTER NYCA -// 1a10 BUGINESE LETTER YA -// 1a11 BUGINESE LETTER RA -// 1a12 BUGINESE LETTER LA -// 1a13 BUGINESE LETTER VA -// 1a14 BUGINESE LETTER SA -// 1a15 BUGINESE LETTER A -// 1a16 BUGINESE LETTER HA - { 0x1A00, 0x17, 0x9, 0, 0 }, -// 1a17 BUGINESE VOWEL SIGN I -// 1a18 BUGINESE VOWEL SIGN U -// 1a19 BUGINESE VOWEL SIGN E -// 1a1a BUGINESE VOWEL SIGN O -// 1a1b BUGINESE VOWEL SIGN AE - { 0x1A17, 0x5, 0x0, 0, 0 }, -// 1a1e BUGINESE PALLAWA -// 1a1f BUGINESE END OF SECTION - { 0x1A1E, 0x2, 0x18, 0, 0 }, -// 1a20 TAI THAM LETTER HIGH KA -// 1a21 TAI THAM LETTER HIGH KHA -// 1a22 TAI THAM LETTER HIGH KXA -// 1a23 TAI THAM LETTER LOW KA -// 1a24 TAI THAM LETTER LOW KXA -// 1a25 TAI THAM LETTER LOW KHA -// 1a26 TAI THAM LETTER NGA -// 1a27 TAI THAM LETTER HIGH CA -// 1a28 TAI THAM LETTER HIGH CHA -// 1a29 TAI THAM LETTER LOW CA -// 1a2a TAI THAM LETTER LOW SA -// 1a2b TAI THAM LETTER LOW CHA -// 1a2c TAI THAM LETTER NYA -// 1a2d TAI THAM LETTER RATA -// 1a2e TAI THAM LETTER HIGH RATHA -// 1a2f TAI THAM LETTER DA -// 1a30 TAI THAM LETTER LOW RATHA -// 1a31 TAI THAM LETTER RANA -// 1a32 TAI THAM LETTER HIGH TA -// 1a33 TAI THAM LETTER HIGH THA -// 1a34 TAI THAM LETTER LOW TA -// 1a35 TAI THAM LETTER LOW THA -// 1a36 TAI THAM LETTER NA -// 1a37 TAI THAM LETTER BA -// 1a38 TAI THAM LETTER HIGH PA -// 1a39 TAI THAM LETTER HIGH PHA -// 1a3a TAI THAM LETTER HIGH FA -// 1a3b TAI THAM LETTER LOW PA -// 1a3c TAI THAM LETTER LOW FA -// 1a3d TAI THAM LETTER LOW PHA -// 1a3e TAI THAM LETTER MA -// 1a3f TAI THAM LETTER LOW YA -// 1a40 TAI THAM LETTER HIGH YA -// 1a41 TAI THAM LETTER RA -// 1a42 TAI THAM LETTER RUE -// 1a43 TAI THAM LETTER LA -// 1a44 TAI THAM LETTER LUE -// 1a45 TAI THAM LETTER WA -// 1a46 TAI THAM LETTER HIGH SHA -// 1a47 TAI THAM LETTER HIGH SSA -// 1a48 TAI THAM LETTER HIGH SA -// 1a49 TAI THAM LETTER HIGH HA -// 1a4a TAI THAM LETTER LLA -// 1a4b TAI THAM LETTER A -// 1a4c TAI THAM LETTER LOW HA -// 1a4d TAI THAM LETTER I -// 1a4e TAI THAM LETTER II -// 1a4f TAI THAM LETTER U -// 1a50 TAI THAM LETTER UU -// 1a51 TAI THAM LETTER EE -// 1a52 TAI THAM LETTER OO -// 1a53 TAI THAM LETTER LAE -// 1a54 TAI THAM LETTER GREAT SA - { 0x1A20, 0x35, 0x9, 0, 0 }, -// 1a55 TAI THAM CONSONANT SIGN MEDIAL RA -// 1a56 TAI THAM CONSONANT SIGN MEDIAL LA -// 1a57 TAI THAM CONSONANT SIGN LA TANG LAI -// 1a58 TAI THAM SIGN MAI KANG LAI -// 1a59 TAI THAM CONSONANT SIGN FINAL NGA -// 1a5a TAI THAM CONSONANT SIGN LOW PA -// 1a5b TAI THAM CONSONANT SIGN HIGH RATHA OR LOW PA -// 1a5c TAI THAM CONSONANT SIGN MA -// 1a5d TAI THAM CONSONANT SIGN BA -// 1a5e TAI THAM CONSONANT SIGN SA - { 0x1A55, 0xA, 0x0, 0, 0 }, -// 1a60 TAI THAM SIGN SAKOT -// 1a61 TAI THAM VOWEL SIGN A -// 1a62 TAI THAM VOWEL SIGN MAI SAT -// 1a63 TAI THAM VOWEL SIGN AA -// 1a64 TAI THAM VOWEL SIGN TALL AA -// 1a65 TAI THAM VOWEL SIGN I -// 1a66 TAI THAM VOWEL SIGN II -// 1a67 TAI THAM VOWEL SIGN UE -// 1a68 TAI THAM VOWEL SIGN UUE -// 1a69 TAI THAM VOWEL SIGN U -// 1a6a TAI THAM VOWEL SIGN UU -// 1a6b TAI THAM VOWEL SIGN O -// 1a6c TAI THAM VOWEL SIGN OA BELOW -// 1a6d TAI THAM VOWEL SIGN OY -// 1a6e TAI THAM VOWEL SIGN E -// 1a6f TAI THAM VOWEL SIGN AE -// 1a70 TAI THAM VOWEL SIGN OO -// 1a71 TAI THAM VOWEL SIGN AI -// 1a72 TAI THAM VOWEL SIGN THAM AI -// 1a73 TAI THAM VOWEL SIGN OA ABOVE -// 1a74 TAI THAM SIGN MAI KANG -// 1a75 TAI THAM SIGN TONE-1 -// 1a76 TAI THAM SIGN TONE-2 -// 1a77 TAI THAM SIGN KHUEN TONE-3 -// 1a78 TAI THAM SIGN KHUEN TONE-4 -// 1a79 TAI THAM SIGN KHUEN TONE-5 -// 1a7a TAI THAM SIGN RA HAAM -// 1a7b TAI THAM SIGN MAI SAM -// 1a7c TAI THAM SIGN KHUEN-LUE KARAN - { 0x1A60, 0x1D, 0x0, 0, 0 }, -// 1a7f TAI THAM COMBINING CRYPTOGRAMMIC DOT - { 0x1A7F, 0x1, 0x0, 0, 0 }, -// 1a80 TAI THAM HORA DIGIT ZERO -// 1a81 TAI THAM HORA DIGIT ONE -// 1a82 TAI THAM HORA DIGIT TWO -// 1a83 TAI THAM HORA DIGIT THREE -// 1a84 TAI THAM HORA DIGIT FOUR -// 1a85 TAI THAM HORA DIGIT FIVE -// 1a86 TAI THAM HORA DIGIT SIX -// 1a87 TAI THAM HORA DIGIT SEVEN -// 1a88 TAI THAM HORA DIGIT EIGHT -// 1a89 TAI THAM HORA DIGIT NINE - { 0x1A80, 0xA, 0x108, 0, 0 }, -// 1a90 TAI THAM THAM DIGIT ZERO -// 1a91 TAI THAM THAM DIGIT ONE -// 1a92 TAI THAM THAM DIGIT TWO -// 1a93 TAI THAM THAM DIGIT THREE -// 1a94 TAI THAM THAM DIGIT FOUR -// 1a95 TAI THAM THAM DIGIT FIVE -// 1a96 TAI THAM THAM DIGIT SIX -// 1a97 TAI THAM THAM DIGIT SEVEN -// 1a98 TAI THAM THAM DIGIT EIGHT -// 1a99 TAI THAM THAM DIGIT NINE - { 0x1A90, 0xA, 0x108, 0, 0 }, -// 1aa0 TAI THAM SIGN WIANG -// 1aa1 TAI THAM SIGN WIANGWAAK -// 1aa2 TAI THAM SIGN SAWAN -// 1aa3 TAI THAM SIGN KEOW -// 1aa4 TAI THAM SIGN HOY -// 1aa5 TAI THAM SIGN DOKMAI -// 1aa6 TAI THAM SIGN REVERSED ROTATED RANA - { 0x1AA0, 0x7, 0x18, 0, 0 }, -// 1aa7 TAI THAM SIGN MAI YAMOK - { 0x1AA7, 0x1, 0x9, 0, 0 }, -// 1aa8 TAI THAM SIGN KAAN -// 1aa9 TAI THAM SIGN KAANKUU -// 1aaa TAI THAM SIGN SATKAAN -// 1aab TAI THAM SIGN SATKAANKUU -// 1aac TAI THAM SIGN HANG -// 1aad TAI THAM SIGN CAANG - { 0x1AA8, 0x6, 0x18, 0, 0 }, -// 1ab0 COMBINING DOUBLED CIRCUMFLEX ACCENT -// 1ab1 COMBINING DIAERESIS-RING -// 1ab2 COMBINING INFINITY -// 1ab3 COMBINING DOWNWARDS ARROW -// 1ab4 COMBINING TRIPLE DOT -// 1ab5 COMBINING X-X BELOW -// 1ab6 COMBINING WIGGLY LINE BELOW -// 1ab7 COMBINING OPEN MARK BELOW -// 1ab8 COMBINING DOUBLE OPEN MARK BELOW -// 1ab9 COMBINING LIGHT CENTRALIZATION STROKE BELOW -// 1aba COMBINING STRONG CENTRALIZATION STROKE BELOW -// 1abb COMBINING PARENTHESES ABOVE -// 1abc COMBINING DOUBLE PARENTHESES ABOVE -// 1abd COMBINING PARENTHESES BELOW -// 1abe COMBINING PARENTHESES OVERLAY - { 0x1AB0, 0xF, 0x0, 0, 0 }, -// 1b00 BALINESE SIGN ULU RICEM -// 1b01 BALINESE SIGN ULU CANDRA -// 1b02 BALINESE SIGN CECEK -// 1b03 BALINESE SIGN SURANG -// 1b04 BALINESE SIGN BISAH - { 0x1B00, 0x5, 0x0, 0, 0 }, -// 1b05 BALINESE LETTER AKARA -// 1b06 BALINESE LETTER AKARA TEDUNG -// 1b07 BALINESE LETTER IKARA -// 1b08 BALINESE LETTER IKARA TEDUNG -// 1b09 BALINESE LETTER UKARA -// 1b0a BALINESE LETTER UKARA TEDUNG -// 1b0b BALINESE LETTER RA REPA -// 1b0c BALINESE LETTER RA REPA TEDUNG -// 1b0d BALINESE LETTER LA LENGA -// 1b0e BALINESE LETTER LA LENGA TEDUNG -// 1b0f BALINESE LETTER EKARA -// 1b10 BALINESE LETTER AIKARA -// 1b11 BALINESE LETTER OKARA -// 1b12 BALINESE LETTER OKARA TEDUNG -// 1b13 BALINESE LETTER KA -// 1b14 BALINESE LETTER KA MAHAPRANA -// 1b15 BALINESE LETTER GA -// 1b16 BALINESE LETTER GA GORA -// 1b17 BALINESE LETTER NGA -// 1b18 BALINESE LETTER CA -// 1b19 BALINESE LETTER CA LACA -// 1b1a BALINESE LETTER JA -// 1b1b BALINESE LETTER JA JERA -// 1b1c BALINESE LETTER NYA -// 1b1d BALINESE LETTER TA LATIK -// 1b1e BALINESE LETTER TA MURDA MAHAPRANA -// 1b1f BALINESE LETTER DA MURDA ALPAPRANA -// 1b20 BALINESE LETTER DA MURDA MAHAPRANA -// 1b21 BALINESE LETTER NA RAMBAT -// 1b22 BALINESE LETTER TA -// 1b23 BALINESE LETTER TA TAWA -// 1b24 BALINESE LETTER DA -// 1b25 BALINESE LETTER DA MADU -// 1b26 BALINESE LETTER NA -// 1b27 BALINESE LETTER PA -// 1b28 BALINESE LETTER PA KAPAL -// 1b29 BALINESE LETTER BA -// 1b2a BALINESE LETTER BA KEMBANG -// 1b2b BALINESE LETTER MA -// 1b2c BALINESE LETTER YA -// 1b2d BALINESE LETTER RA -// 1b2e BALINESE LETTER LA -// 1b2f BALINESE LETTER WA -// 1b30 BALINESE LETTER SA SAGA -// 1b31 BALINESE LETTER SA SAPA -// 1b32 BALINESE LETTER SA -// 1b33 BALINESE LETTER HA - { 0x1B05, 0x2F, 0x9, 0, 0 }, -// 1b34 BALINESE SIGN REREKAN -// 1b35 BALINESE VOWEL SIGN TEDUNG -// 1b36 BALINESE VOWEL SIGN ULU -// 1b37 BALINESE VOWEL SIGN ULU SARI -// 1b38 BALINESE VOWEL SIGN SUKU -// 1b39 BALINESE VOWEL SIGN SUKU ILUT -// 1b3a BALINESE VOWEL SIGN RA REPA -// 1b3b BALINESE VOWEL SIGN RA REPA TEDUNG -// 1b3c BALINESE VOWEL SIGN LA LENGA -// 1b3d BALINESE VOWEL SIGN LA LENGA TEDUNG -// 1b3e BALINESE VOWEL SIGN TALING -// 1b3f BALINESE VOWEL SIGN TALING REPA -// 1b40 BALINESE VOWEL SIGN TALING TEDUNG -// 1b41 BALINESE VOWEL SIGN TALING REPA TEDUNG -// 1b42 BALINESE VOWEL SIGN PEPET -// 1b43 BALINESE VOWEL SIGN PEPET TEDUNG -// 1b44 BALINESE ADEG ADEG - { 0x1B34, 0x11, 0x0, 0, 0 }, -// 1b45 BALINESE LETTER KAF SASAK -// 1b46 BALINESE LETTER KHOT SASAK -// 1b47 BALINESE LETTER TZIR SASAK -// 1b48 BALINESE LETTER EF SASAK -// 1b49 BALINESE LETTER VE SASAK -// 1b4a BALINESE LETTER ZAL SASAK -// 1b4b BALINESE LETTER ASYURA SASAK - { 0x1B45, 0x7, 0x9, 0, 0 }, -// 1b50 BALINESE DIGIT ZERO -// 1b51 BALINESE DIGIT ONE -// 1b52 BALINESE DIGIT TWO -// 1b53 BALINESE DIGIT THREE -// 1b54 BALINESE DIGIT FOUR -// 1b55 BALINESE DIGIT FIVE -// 1b56 BALINESE DIGIT SIX -// 1b57 BALINESE DIGIT SEVEN -// 1b58 BALINESE DIGIT EIGHT -// 1b59 BALINESE DIGIT NINE - { 0x1B50, 0xA, 0x108, 0, 0 }, -// 1b5a BALINESE PANTI -// 1b5b BALINESE PAMADA -// 1b5c BALINESE WINDU -// 1b5d BALINESE CARIK PAMUNGKAH -// 1b5e BALINESE CARIK SIKI -// 1b5f BALINESE CARIK PAREREN -// 1b60 BALINESE PAMENENG - { 0x1B5A, 0x7, 0x18, 0, 0 }, -// 1b61 BALINESE MUSICAL SYMBOL DONG -// 1b62 BALINESE MUSICAL SYMBOL DENG -// 1b63 BALINESE MUSICAL SYMBOL DUNG -// 1b64 BALINESE MUSICAL SYMBOL DANG -// 1b65 BALINESE MUSICAL SYMBOL DANG SURANG -// 1b66 BALINESE MUSICAL SYMBOL DING -// 1b67 BALINESE MUSICAL SYMBOL DAENG -// 1b68 BALINESE MUSICAL SYMBOL DEUNG -// 1b69 BALINESE MUSICAL SYMBOL DAING -// 1b6a BALINESE MUSICAL SYMBOL DANG GEDE - { 0x1B61, 0xA, 0x8, 0, 0 }, -// 1b6b BALINESE MUSICAL SYMBOL COMBINING TEGEH -// 1b6c BALINESE MUSICAL SYMBOL COMBINING ENDEP -// 1b6d BALINESE MUSICAL SYMBOL COMBINING KEMPUL -// 1b6e BALINESE MUSICAL SYMBOL COMBINING KEMPLI -// 1b6f BALINESE MUSICAL SYMBOL COMBINING JEGOGAN -// 1b70 BALINESE MUSICAL SYMBOL COMBINING KEMPUL WITH JEGOGAN -// 1b71 BALINESE MUSICAL SYMBOL COMBINING KEMPLI WITH JEGOGAN -// 1b72 BALINESE MUSICAL SYMBOL COMBINING BENDE -// 1b73 BALINESE MUSICAL SYMBOL COMBINING GONG - { 0x1B6B, 0x9, 0x0, 0, 0 }, -// 1b74 BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG -// 1b75 BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DAG -// 1b76 BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TUK -// 1b77 BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TAK -// 1b78 BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PANG -// 1b79 BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PUNG -// 1b7a BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLAK -// 1b7b BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLUK -// 1b7c BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING - { 0x1B74, 0x9, 0x8, 0, 0 }, -// 1b80 SUNDANESE SIGN PANYECEK -// 1b81 SUNDANESE SIGN PANGLAYAR -// 1b82 SUNDANESE SIGN PANGWISAD - { 0x1B80, 0x3, 0x0, 0, 0 }, -// 1b83 SUNDANESE LETTER A -// 1b84 SUNDANESE LETTER I -// 1b85 SUNDANESE LETTER U -// 1b86 SUNDANESE LETTER AE -// 1b87 SUNDANESE LETTER O -// 1b88 SUNDANESE LETTER E -// 1b89 SUNDANESE LETTER EU -// 1b8a SUNDANESE LETTER KA -// 1b8b SUNDANESE LETTER QA -// 1b8c SUNDANESE LETTER GA -// 1b8d SUNDANESE LETTER NGA -// 1b8e SUNDANESE LETTER CA -// 1b8f SUNDANESE LETTER JA -// 1b90 SUNDANESE LETTER ZA -// 1b91 SUNDANESE LETTER NYA -// 1b92 SUNDANESE LETTER TA -// 1b93 SUNDANESE LETTER DA -// 1b94 SUNDANESE LETTER NA -// 1b95 SUNDANESE LETTER PA -// 1b96 SUNDANESE LETTER FA -// 1b97 SUNDANESE LETTER VA -// 1b98 SUNDANESE LETTER BA -// 1b99 SUNDANESE LETTER MA -// 1b9a SUNDANESE LETTER YA -// 1b9b SUNDANESE LETTER RA -// 1b9c SUNDANESE LETTER LA -// 1b9d SUNDANESE LETTER WA -// 1b9e SUNDANESE LETTER SA -// 1b9f SUNDANESE LETTER XA -// 1ba0 SUNDANESE LETTER HA - { 0x1B83, 0x1E, 0x9, 0, 0 }, -// 1ba1 SUNDANESE CONSONANT SIGN PAMINGKAL -// 1ba2 SUNDANESE CONSONANT SIGN PANYAKRA -// 1ba3 SUNDANESE CONSONANT SIGN PANYIKU -// 1ba4 SUNDANESE VOWEL SIGN PANGHULU -// 1ba5 SUNDANESE VOWEL SIGN PANYUKU -// 1ba6 SUNDANESE VOWEL SIGN PANAELAENG -// 1ba7 SUNDANESE VOWEL SIGN PANOLONG -// 1ba8 SUNDANESE VOWEL SIGN PAMEPET -// 1ba9 SUNDANESE VOWEL SIGN PANEULEUNG -// 1baa SUNDANESE SIGN PAMAAEH -// 1bab SUNDANESE SIGN VIRAMA -// 1bac SUNDANESE CONSONANT SIGN PASANGAN MA -// 1bad SUNDANESE CONSONANT SIGN PASANGAN WA - { 0x1BA1, 0xD, 0x0, 0, 0 }, -// 1bae SUNDANESE LETTER KHA -// 1baf SUNDANESE LETTER SYA - { 0x1BAE, 0x2, 0x9, 0, 0 }, -// 1bb0 SUNDANESE DIGIT ZERO -// 1bb1 SUNDANESE DIGIT ONE -// 1bb2 SUNDANESE DIGIT TWO -// 1bb3 SUNDANESE DIGIT THREE -// 1bb4 SUNDANESE DIGIT FOUR -// 1bb5 SUNDANESE DIGIT FIVE -// 1bb6 SUNDANESE DIGIT SIX -// 1bb7 SUNDANESE DIGIT SEVEN -// 1bb8 SUNDANESE DIGIT EIGHT -// 1bb9 SUNDANESE DIGIT NINE - { 0x1BB0, 0xA, 0x108, 0, 0 }, -// 1bba SUNDANESE AVAGRAHA -// 1bbb SUNDANESE LETTER REU -// 1bbc SUNDANESE LETTER LEU -// 1bbd SUNDANESE LETTER BHA -// 1bbe SUNDANESE LETTER FINAL K -// 1bbf SUNDANESE LETTER FINAL M -// 1bc0 BATAK LETTER A -// 1bc1 BATAK LETTER SIMALUNGUN A -// 1bc2 BATAK LETTER HA -// 1bc3 BATAK LETTER SIMALUNGUN HA -// 1bc4 BATAK LETTER MANDAILING HA -// 1bc5 BATAK LETTER BA -// 1bc6 BATAK LETTER KARO BA -// 1bc7 BATAK LETTER PA -// 1bc8 BATAK LETTER SIMALUNGUN PA -// 1bc9 BATAK LETTER NA -// 1bca BATAK LETTER MANDAILING NA -// 1bcb BATAK LETTER WA -// 1bcc BATAK LETTER SIMALUNGUN WA -// 1bcd BATAK LETTER PAKPAK WA -// 1bce BATAK LETTER GA -// 1bcf BATAK LETTER SIMALUNGUN GA -// 1bd0 BATAK LETTER JA -// 1bd1 BATAK LETTER DA -// 1bd2 BATAK LETTER RA -// 1bd3 BATAK LETTER SIMALUNGUN RA -// 1bd4 BATAK LETTER MA -// 1bd5 BATAK LETTER SIMALUNGUN MA -// 1bd6 BATAK LETTER SOUTHERN TA -// 1bd7 BATAK LETTER NORTHERN TA -// 1bd8 BATAK LETTER SA -// 1bd9 BATAK LETTER SIMALUNGUN SA -// 1bda BATAK LETTER MANDAILING SA -// 1bdb BATAK LETTER YA -// 1bdc BATAK LETTER SIMALUNGUN YA -// 1bdd BATAK LETTER NGA -// 1bde BATAK LETTER LA -// 1bdf BATAK LETTER SIMALUNGUN LA -// 1be0 BATAK LETTER NYA -// 1be1 BATAK LETTER CA -// 1be2 BATAK LETTER NDA -// 1be3 BATAK LETTER MBA -// 1be4 BATAK LETTER I -// 1be5 BATAK LETTER U - { 0x1BBA, 0x2C, 0x9, 0, 0 }, -// 1be6 BATAK SIGN TOMPI -// 1be7 BATAK VOWEL SIGN E -// 1be8 BATAK VOWEL SIGN PAKPAK E -// 1be9 BATAK VOWEL SIGN EE -// 1bea BATAK VOWEL SIGN I -// 1beb BATAK VOWEL SIGN KARO I -// 1bec BATAK VOWEL SIGN O -// 1bed BATAK VOWEL SIGN KARO O -// 1bee BATAK VOWEL SIGN U -// 1bef BATAK VOWEL SIGN U FOR SIMALUNGUN SA -// 1bf0 BATAK CONSONANT SIGN NG -// 1bf1 BATAK CONSONANT SIGN H -// 1bf2 BATAK PANGOLAT -// 1bf3 BATAK PANONGONAN - { 0x1BE6, 0xE, 0x0, 0, 0 }, -// 1bfc BATAK SYMBOL BINDU NA METEK -// 1bfd BATAK SYMBOL BINDU PINARBORAS -// 1bfe BATAK SYMBOL BINDU JUDUL -// 1bff BATAK SYMBOL BINDU PANGOLAT - { 0x1BFC, 0x4, 0x18, 0, 0 }, -// 1c00 LEPCHA LETTER KA -// 1c01 LEPCHA LETTER KLA -// 1c02 LEPCHA LETTER KHA -// 1c03 LEPCHA LETTER GA -// 1c04 LEPCHA LETTER GLA -// 1c05 LEPCHA LETTER NGA -// 1c06 LEPCHA LETTER CA -// 1c07 LEPCHA LETTER CHA -// 1c08 LEPCHA LETTER JA -// 1c09 LEPCHA LETTER NYA -// 1c0a LEPCHA LETTER TA -// 1c0b LEPCHA LETTER THA -// 1c0c LEPCHA LETTER DA -// 1c0d LEPCHA LETTER NA -// 1c0e LEPCHA LETTER PA -// 1c0f LEPCHA LETTER PLA -// 1c10 LEPCHA LETTER PHA -// 1c11 LEPCHA LETTER FA -// 1c12 LEPCHA LETTER FLA -// 1c13 LEPCHA LETTER BA -// 1c14 LEPCHA LETTER BLA -// 1c15 LEPCHA LETTER MA -// 1c16 LEPCHA LETTER MLA -// 1c17 LEPCHA LETTER TSA -// 1c18 LEPCHA LETTER TSHA -// 1c19 LEPCHA LETTER DZA -// 1c1a LEPCHA LETTER YA -// 1c1b LEPCHA LETTER RA -// 1c1c LEPCHA LETTER LA -// 1c1d LEPCHA LETTER HA -// 1c1e LEPCHA LETTER HLA -// 1c1f LEPCHA LETTER VA -// 1c20 LEPCHA LETTER SA -// 1c21 LEPCHA LETTER SHA -// 1c22 LEPCHA LETTER WA -// 1c23 LEPCHA LETTER A - { 0x1C00, 0x24, 0x9, 0, 0 }, -// 1c24 LEPCHA SUBJOINED LETTER YA -// 1c25 LEPCHA SUBJOINED LETTER RA -// 1c26 LEPCHA VOWEL SIGN AA -// 1c27 LEPCHA VOWEL SIGN I -// 1c28 LEPCHA VOWEL SIGN O -// 1c29 LEPCHA VOWEL SIGN OO -// 1c2a LEPCHA VOWEL SIGN U -// 1c2b LEPCHA VOWEL SIGN UU -// 1c2c LEPCHA VOWEL SIGN E -// 1c2d LEPCHA CONSONANT SIGN K -// 1c2e LEPCHA CONSONANT SIGN M -// 1c2f LEPCHA CONSONANT SIGN L -// 1c30 LEPCHA CONSONANT SIGN N -// 1c31 LEPCHA CONSONANT SIGN P -// 1c32 LEPCHA CONSONANT SIGN R -// 1c33 LEPCHA CONSONANT SIGN T -// 1c34 LEPCHA CONSONANT SIGN NYIN-DO -// 1c35 LEPCHA CONSONANT SIGN KANG -// 1c36 LEPCHA SIGN RAN -// 1c37 LEPCHA SIGN NUKTA - { 0x1C24, 0x14, 0x0, 0, 0 }, -// 1c3b LEPCHA PUNCTUATION TA-ROL -// 1c3c LEPCHA PUNCTUATION NYET THYOOM TA-ROL -// 1c3d LEPCHA PUNCTUATION CER-WA -// 1c3e LEPCHA PUNCTUATION TSHOOK CER-WA -// 1c3f LEPCHA PUNCTUATION TSHOOK - { 0x1C3B, 0x5, 0x18, 0, 0 }, -// 1c40 LEPCHA DIGIT ZERO -// 1c41 LEPCHA DIGIT ONE -// 1c42 LEPCHA DIGIT TWO -// 1c43 LEPCHA DIGIT THREE -// 1c44 LEPCHA DIGIT FOUR -// 1c45 LEPCHA DIGIT FIVE -// 1c46 LEPCHA DIGIT SIX -// 1c47 LEPCHA DIGIT SEVEN -// 1c48 LEPCHA DIGIT EIGHT -// 1c49 LEPCHA DIGIT NINE - { 0x1C40, 0xA, 0x108, 0, 0 }, -// 1c4d LEPCHA LETTER TTA -// 1c4e LEPCHA LETTER TTHA -// 1c4f LEPCHA LETTER DDA - { 0x1C4D, 0x3, 0x9, 0, 0 }, -// 1c50 OL CHIKI DIGIT ZERO -// 1c51 OL CHIKI DIGIT ONE -// 1c52 OL CHIKI DIGIT TWO -// 1c53 OL CHIKI DIGIT THREE -// 1c54 OL CHIKI DIGIT FOUR -// 1c55 OL CHIKI DIGIT FIVE -// 1c56 OL CHIKI DIGIT SIX -// 1c57 OL CHIKI DIGIT SEVEN -// 1c58 OL CHIKI DIGIT EIGHT -// 1c59 OL CHIKI DIGIT NINE - { 0x1C50, 0xA, 0x108, 0, 0 }, -// 1c5a OL CHIKI LETTER LA -// 1c5b OL CHIKI LETTER AT -// 1c5c OL CHIKI LETTER AG -// 1c5d OL CHIKI LETTER ANG -// 1c5e OL CHIKI LETTER AL -// 1c5f OL CHIKI LETTER LAA -// 1c60 OL CHIKI LETTER AAK -// 1c61 OL CHIKI LETTER AAJ -// 1c62 OL CHIKI LETTER AAM -// 1c63 OL CHIKI LETTER AAW -// 1c64 OL CHIKI LETTER LI -// 1c65 OL CHIKI LETTER IS -// 1c66 OL CHIKI LETTER IH -// 1c67 OL CHIKI LETTER INY -// 1c68 OL CHIKI LETTER IR -// 1c69 OL CHIKI LETTER LU -// 1c6a OL CHIKI LETTER UC -// 1c6b OL CHIKI LETTER UD -// 1c6c OL CHIKI LETTER UNN -// 1c6d OL CHIKI LETTER UY -// 1c6e OL CHIKI LETTER LE -// 1c6f OL CHIKI LETTER EP -// 1c70 OL CHIKI LETTER EDD -// 1c71 OL CHIKI LETTER EN -// 1c72 OL CHIKI LETTER ERR -// 1c73 OL CHIKI LETTER LO -// 1c74 OL CHIKI LETTER OTT -// 1c75 OL CHIKI LETTER OB -// 1c76 OL CHIKI LETTER OV -// 1c77 OL CHIKI LETTER OH -// 1c78 OL CHIKI MU TTUDDAG -// 1c79 OL CHIKI GAAHLAA TTUDDAAG -// 1c7a OL CHIKI MU-GAAHLAA TTUDDAAG -// 1c7b OL CHIKI RELAA -// 1c7c OL CHIKI PHAARKAA -// 1c7d OL CHIKI AHAD - { 0x1C5A, 0x24, 0x9, 0, 0 }, -// 1c7e OL CHIKI PUNCTUATION MUCAAD -// 1c7f OL CHIKI PUNCTUATION DOUBLE MUCAAD - { 0x1C7E, 0x2, 0x18, 0, 0 }, -// 1cc0 SUNDANESE PUNCTUATION BINDU SURYA -// 1cc1 SUNDANESE PUNCTUATION BINDU PANGLONG -// 1cc2 SUNDANESE PUNCTUATION BINDU PURNAMA -// 1cc3 SUNDANESE PUNCTUATION BINDU CAKRA -// 1cc4 SUNDANESE PUNCTUATION BINDU LEU SATANGA -// 1cc5 SUNDANESE PUNCTUATION BINDU KA SATANGA -// 1cc6 SUNDANESE PUNCTUATION BINDU DA SATANGA -// 1cc7 SUNDANESE PUNCTUATION BINDU BA SATANGA - { 0x1CC0, 0x8, 0x18, 0, 0 }, -// 1cd0 VEDIC TONE KARSHANA -// 1cd1 VEDIC TONE SHARA -// 1cd2 VEDIC TONE PRENKHA - { 0x1CD0, 0x3, 0x0, 0, 0 }, -// 1cd3 VEDIC SIGN NIHSHVASA - { 0x1CD3, 0x1, 0x18, 0, 0 }, -// 1cd4 VEDIC SIGN YAJURVEDIC MIDLINE SVARITA -// 1cd5 VEDIC TONE YAJURVEDIC AGGRAVATED INDEPENDENT SVARITA -// 1cd6 VEDIC TONE YAJURVEDIC INDEPENDENT SVARITA -// 1cd7 VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA -// 1cd8 VEDIC TONE CANDRA BELOW -// 1cd9 VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA SCHROEDER -// 1cda VEDIC TONE DOUBLE SVARITA -// 1cdb VEDIC TONE TRIPLE SVARITA -// 1cdc VEDIC TONE KATHAKA ANUDATTA -// 1cdd VEDIC TONE DOT BELOW -// 1cde VEDIC TONE TWO DOTS BELOW -// 1cdf VEDIC TONE THREE DOTS BELOW -// 1ce0 VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA -// 1ce1 VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA -// 1ce2 VEDIC SIGN VISARGA SVARITA -// 1ce3 VEDIC SIGN VISARGA UDATTA -// 1ce4 VEDIC SIGN REVERSED VISARGA UDATTA -// 1ce5 VEDIC SIGN VISARGA ANUDATTA -// 1ce6 VEDIC SIGN REVERSED VISARGA ANUDATTA -// 1ce7 VEDIC SIGN VISARGA UDATTA WITH TAIL -// 1ce8 VEDIC SIGN VISARGA ANUDATTA WITH TAIL - { 0x1CD4, 0x15, 0x0, 0, 0 }, -// 1ce9 VEDIC SIGN ANUSVARA ANTARGOMUKHA -// 1cea VEDIC SIGN ANUSVARA BAHIRGOMUKHA -// 1ceb VEDIC SIGN ANUSVARA VAMAGOMUKHA -// 1cec VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL - { 0x1CE9, 0x4, 0x9, 0, 0 }, -// 1ced VEDIC SIGN TIRYAK - { 0x1CED, 0x1, 0x0, 0, 0 }, -// 1cee VEDIC SIGN HEXIFORM LONG ANUSVARA -// 1cef VEDIC SIGN LONG ANUSVARA -// 1cf0 VEDIC SIGN RTHANG LONG ANUSVARA -// 1cf1 VEDIC SIGN ANUSVARA UBHAYATO MUKHA - { 0x1CEE, 0x4, 0x9, 0, 0 }, -// 1cf2 VEDIC SIGN ARDHAVISARGA -// 1cf3 VEDIC SIGN ROTATED ARDHAVISARGA -// 1cf4 VEDIC TONE CANDRA ABOVE - { 0x1CF2, 0x3, 0x0, 0, 0 }, -// 1cf5 VEDIC SIGN JIHVAMULIYA -// 1cf6 VEDIC SIGN UPADHMANIYA - { 0x1CF5, 0x2, 0x9, 0, 0 }, -// 1cf8 VEDIC TONE RING ABOVE -// 1cf9 VEDIC TONE DOUBLE RING ABOVE - { 0x1CF8, 0x2, 0x0, 0, 0 }, -// 1d00 LATIN LETTER SMALL CAPITAL A -// 1d01 LATIN LETTER SMALL CAPITAL AE -// 1d02 LATIN SMALL LETTER TURNED AE -// 1d03 LATIN LETTER SMALL CAPITAL BARRED B -// 1d04 LATIN LETTER SMALL CAPITAL C -// 1d05 LATIN LETTER SMALL CAPITAL D -// 1d06 LATIN LETTER SMALL CAPITAL ETH -// 1d07 LATIN LETTER SMALL CAPITAL E -// 1d08 LATIN SMALL LETTER TURNED OPEN E -// 1d09 LATIN SMALL LETTER TURNED I -// 1d0a LATIN LETTER SMALL CAPITAL J -// 1d0b LATIN LETTER SMALL CAPITAL K -// 1d0c LATIN LETTER SMALL CAPITAL L WITH STROKE -// 1d0d LATIN LETTER SMALL CAPITAL M -// 1d0e LATIN LETTER SMALL CAPITAL REVERSED N -// 1d0f LATIN LETTER SMALL CAPITAL O -// 1d10 LATIN LETTER SMALL CAPITAL OPEN O -// 1d11 LATIN SMALL LETTER SIDEWAYS O -// 1d12 LATIN SMALL LETTER SIDEWAYS OPEN O -// 1d13 LATIN SMALL LETTER SIDEWAYS O WITH STROKE -// 1d14 LATIN SMALL LETTER TURNED OE -// 1d15 LATIN LETTER SMALL CAPITAL OU -// 1d16 LATIN SMALL LETTER TOP HALF O -// 1d17 LATIN SMALL LETTER BOTTOM HALF O -// 1d18 LATIN LETTER SMALL CAPITAL P -// 1d19 LATIN LETTER SMALL CAPITAL REVERSED R -// 1d1a LATIN LETTER SMALL CAPITAL TURNED R -// 1d1b LATIN LETTER SMALL CAPITAL T -// 1d1c LATIN LETTER SMALL CAPITAL U -// 1d1d LATIN SMALL LETTER SIDEWAYS U -// 1d1e LATIN SMALL LETTER SIDEWAYS DIAERESIZED U -// 1d1f LATIN SMALL LETTER SIDEWAYS TURNED M -// 1d20 LATIN LETTER SMALL CAPITAL V -// 1d21 LATIN LETTER SMALL CAPITAL W -// 1d22 LATIN LETTER SMALL CAPITAL Z -// 1d23 LATIN LETTER SMALL CAPITAL EZH -// 1d24 LATIN LETTER VOICED LARYNGEAL SPIRANT -// 1d25 LATIN LETTER AIN -// 1d26 GREEK LETTER SMALL CAPITAL GAMMA -// 1d27 GREEK LETTER SMALL CAPITAL LAMDA -// 1d28 GREEK LETTER SMALL CAPITAL PI -// 1d29 GREEK LETTER SMALL CAPITAL RHO -// 1d2a GREEK LETTER SMALL CAPITAL PSI -// 1d2b CYRILLIC LETTER SMALL CAPITAL EL - { 0x1D00, 0x2C, 0x49, 0, 0 }, -// 1d2c MODIFIER LETTER CAPITAL A -// 1d2d MODIFIER LETTER CAPITAL AE -// 1d2e MODIFIER LETTER CAPITAL B -// 1d2f MODIFIER LETTER CAPITAL BARRED B -// 1d30 MODIFIER LETTER CAPITAL D -// 1d31 MODIFIER LETTER CAPITAL E -// 1d32 MODIFIER LETTER CAPITAL REVERSED E -// 1d33 MODIFIER LETTER CAPITAL G -// 1d34 MODIFIER LETTER CAPITAL H -// 1d35 MODIFIER LETTER CAPITAL I -// 1d36 MODIFIER LETTER CAPITAL J -// 1d37 MODIFIER LETTER CAPITAL K -// 1d38 MODIFIER LETTER CAPITAL L -// 1d39 MODIFIER LETTER CAPITAL M -// 1d3a MODIFIER LETTER CAPITAL N -// 1d3b MODIFIER LETTER CAPITAL REVERSED N -// 1d3c MODIFIER LETTER CAPITAL O -// 1d3d MODIFIER LETTER CAPITAL OU -// 1d3e MODIFIER LETTER CAPITAL P -// 1d3f MODIFIER LETTER CAPITAL R -// 1d40 MODIFIER LETTER CAPITAL T -// 1d41 MODIFIER LETTER CAPITAL U -// 1d42 MODIFIER LETTER CAPITAL W -// 1d43 MODIFIER LETTER SMALL A -// 1d44 MODIFIER LETTER SMALL TURNED A -// 1d45 MODIFIER LETTER SMALL ALPHA -// 1d46 MODIFIER LETTER SMALL TURNED AE -// 1d47 MODIFIER LETTER SMALL B -// 1d48 MODIFIER LETTER SMALL D -// 1d49 MODIFIER LETTER SMALL E -// 1d4a MODIFIER LETTER SMALL SCHWA -// 1d4b MODIFIER LETTER SMALL OPEN E -// 1d4c MODIFIER LETTER SMALL TURNED OPEN E -// 1d4d MODIFIER LETTER SMALL G -// 1d4e MODIFIER LETTER SMALL TURNED I -// 1d4f MODIFIER LETTER SMALL K -// 1d50 MODIFIER LETTER SMALL M -// 1d51 MODIFIER LETTER SMALL ENG -// 1d52 MODIFIER LETTER SMALL O -// 1d53 MODIFIER LETTER SMALL OPEN O -// 1d54 MODIFIER LETTER SMALL TOP HALF O -// 1d55 MODIFIER LETTER SMALL BOTTOM HALF O -// 1d56 MODIFIER LETTER SMALL P -// 1d57 MODIFIER LETTER SMALL T -// 1d58 MODIFIER LETTER SMALL U -// 1d59 MODIFIER LETTER SMALL SIDEWAYS U -// 1d5a MODIFIER LETTER SMALL TURNED M -// 1d5b MODIFIER LETTER SMALL V -// 1d5c MODIFIER LETTER SMALL AIN -// 1d5d MODIFIER LETTER SMALL BETA -// 1d5e MODIFIER LETTER SMALL GREEK GAMMA -// 1d5f MODIFIER LETTER SMALL DELTA -// 1d60 MODIFIER LETTER SMALL GREEK PHI -// 1d61 MODIFIER LETTER SMALL CHI -// 1d62 LATIN SUBSCRIPT SMALL LETTER I -// 1d63 LATIN SUBSCRIPT SMALL LETTER R -// 1d64 LATIN SUBSCRIPT SMALL LETTER U -// 1d65 LATIN SUBSCRIPT SMALL LETTER V -// 1d66 GREEK SUBSCRIPT SMALL LETTER BETA -// 1d67 GREEK SUBSCRIPT SMALL LETTER GAMMA -// 1d68 GREEK SUBSCRIPT SMALL LETTER RHO -// 1d69 GREEK SUBSCRIPT SMALL LETTER PHI -// 1d6a GREEK SUBSCRIPT SMALL LETTER CHI - { 0x1D2C, 0x3F, 0x9, 0, 0 }, -// 1d6b LATIN SMALL LETTER UE -// 1d6c LATIN SMALL LETTER B WITH MIDDLE TILDE -// 1d6d LATIN SMALL LETTER D WITH MIDDLE TILDE -// 1d6e LATIN SMALL LETTER F WITH MIDDLE TILDE -// 1d6f LATIN SMALL LETTER M WITH MIDDLE TILDE -// 1d70 LATIN SMALL LETTER N WITH MIDDLE TILDE -// 1d71 LATIN SMALL LETTER P WITH MIDDLE TILDE -// 1d72 LATIN SMALL LETTER R WITH MIDDLE TILDE -// 1d73 LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE -// 1d74 LATIN SMALL LETTER S WITH MIDDLE TILDE -// 1d75 LATIN SMALL LETTER T WITH MIDDLE TILDE -// 1d76 LATIN SMALL LETTER Z WITH MIDDLE TILDE -// 1d77 LATIN SMALL LETTER TURNED G - { 0x1D6B, 0xD, 0x49, 0, 0 }, -// 1d78 MODIFIER LETTER CYRILLIC EN - { 0x1D78, 0x1, 0x9, 0, 0 }, -// 1d79 LATIN SMALL LETTER INSULAR G - { 0x1D79, 0x1, 0x49, 0, 35332 }, -// 1d7a LATIN SMALL LETTER TH WITH STRIKETHROUGH -// 1d7b LATIN SMALL CAPITAL LETTER I WITH STROKE -// 1d7c LATIN SMALL LETTER IOTA WITH STROKE - { 0x1D7A, 0x3, 0x49, 0, 0 }, -// 1d7d LATIN SMALL LETTER P WITH STROKE - { 0x1D7D, 0x1, 0x49, 0, 3814 }, -// 1d7e LATIN SMALL CAPITAL LETTER U WITH STROKE -// 1d7f LATIN SMALL LETTER UPSILON WITH STROKE -// 1d80 LATIN SMALL LETTER B WITH PALATAL HOOK -// 1d81 LATIN SMALL LETTER D WITH PALATAL HOOK -// 1d82 LATIN SMALL LETTER F WITH PALATAL HOOK -// 1d83 LATIN SMALL LETTER G WITH PALATAL HOOK -// 1d84 LATIN SMALL LETTER K WITH PALATAL HOOK -// 1d85 LATIN SMALL LETTER L WITH PALATAL HOOK -// 1d86 LATIN SMALL LETTER M WITH PALATAL HOOK -// 1d87 LATIN SMALL LETTER N WITH PALATAL HOOK -// 1d88 LATIN SMALL LETTER P WITH PALATAL HOOK -// 1d89 LATIN SMALL LETTER R WITH PALATAL HOOK -// 1d8a LATIN SMALL LETTER S WITH PALATAL HOOK -// 1d8b LATIN SMALL LETTER ESH WITH PALATAL HOOK -// 1d8c LATIN SMALL LETTER V WITH PALATAL HOOK -// 1d8d LATIN SMALL LETTER X WITH PALATAL HOOK -// 1d8e LATIN SMALL LETTER Z WITH PALATAL HOOK -// 1d8f LATIN SMALL LETTER A WITH RETROFLEX HOOK -// 1d90 LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK -// 1d91 LATIN SMALL LETTER D WITH HOOK AND TAIL -// 1d92 LATIN SMALL LETTER E WITH RETROFLEX HOOK -// 1d93 LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK -// 1d94 LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK -// 1d95 LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK -// 1d96 LATIN SMALL LETTER I WITH RETROFLEX HOOK -// 1d97 LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK -// 1d98 LATIN SMALL LETTER ESH WITH RETROFLEX HOOK -// 1d99 LATIN SMALL LETTER U WITH RETROFLEX HOOK -// 1d9a LATIN SMALL LETTER EZH WITH RETROFLEX HOOK - { 0x1D7E, 0x1D, 0x49, 0, 0 }, -// 1d9b MODIFIER LETTER SMALL TURNED ALPHA -// 1d9c MODIFIER LETTER SMALL C -// 1d9d MODIFIER LETTER SMALL C WITH CURL -// 1d9e MODIFIER LETTER SMALL ETH -// 1d9f MODIFIER LETTER SMALL REVERSED OPEN E -// 1da0 MODIFIER LETTER SMALL F -// 1da1 MODIFIER LETTER SMALL DOTLESS J WITH STROKE -// 1da2 MODIFIER LETTER SMALL SCRIPT G -// 1da3 MODIFIER LETTER SMALL TURNED H -// 1da4 MODIFIER LETTER SMALL I WITH STROKE -// 1da5 MODIFIER LETTER SMALL IOTA -// 1da6 MODIFIER LETTER SMALL CAPITAL I -// 1da7 MODIFIER LETTER SMALL CAPITAL I WITH STROKE -// 1da8 MODIFIER LETTER SMALL J WITH CROSSED-TAIL -// 1da9 MODIFIER LETTER SMALL L WITH RETROFLEX HOOK -// 1daa MODIFIER LETTER SMALL L WITH PALATAL HOOK -// 1dab MODIFIER LETTER SMALL CAPITAL L -// 1dac MODIFIER LETTER SMALL M WITH HOOK -// 1dad MODIFIER LETTER SMALL TURNED M WITH LONG LEG -// 1dae MODIFIER LETTER SMALL N WITH LEFT HOOK -// 1daf MODIFIER LETTER SMALL N WITH RETROFLEX HOOK -// 1db0 MODIFIER LETTER SMALL CAPITAL N -// 1db1 MODIFIER LETTER SMALL BARRED O -// 1db2 MODIFIER LETTER SMALL PHI -// 1db3 MODIFIER LETTER SMALL S WITH HOOK -// 1db4 MODIFIER LETTER SMALL ESH -// 1db5 MODIFIER LETTER SMALL T WITH PALATAL HOOK -// 1db6 MODIFIER LETTER SMALL U BAR -// 1db7 MODIFIER LETTER SMALL UPSILON -// 1db8 MODIFIER LETTER SMALL CAPITAL U -// 1db9 MODIFIER LETTER SMALL V WITH HOOK -// 1dba MODIFIER LETTER SMALL TURNED V -// 1dbb MODIFIER LETTER SMALL Z -// 1dbc MODIFIER LETTER SMALL Z WITH RETROFLEX HOOK -// 1dbd MODIFIER LETTER SMALL Z WITH CURL -// 1dbe MODIFIER LETTER SMALL EZH -// 1dbf MODIFIER LETTER SMALL THETA - { 0x1D9B, 0x25, 0x9, 0, 0 }, -// 1dc0 COMBINING DOTTED GRAVE ACCENT -// 1dc1 COMBINING DOTTED ACUTE ACCENT -// 1dc2 COMBINING SNAKE BELOW -// 1dc3 COMBINING SUSPENSION MARK -// 1dc4 COMBINING MACRON-ACUTE -// 1dc5 COMBINING GRAVE-MACRON -// 1dc6 COMBINING MACRON-GRAVE -// 1dc7 COMBINING ACUTE-MACRON -// 1dc8 COMBINING GRAVE-ACUTE-GRAVE -// 1dc9 COMBINING ACUTE-GRAVE-ACUTE -// 1dca COMBINING LATIN SMALL LETTER R BELOW -// 1dcb COMBINING BREVE-MACRON -// 1dcc COMBINING MACRON-BREVE -// 1dcd COMBINING DOUBLE CIRCUMFLEX ABOVE -// 1dce COMBINING OGONEK ABOVE -// 1dcf COMBINING ZIGZAG BELOW -// 1dd0 COMBINING IS BELOW -// 1dd1 COMBINING UR ABOVE -// 1dd2 COMBINING US ABOVE -// 1dd3 COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE -// 1dd4 COMBINING LATIN SMALL LETTER AE -// 1dd5 COMBINING LATIN SMALL LETTER AO -// 1dd6 COMBINING LATIN SMALL LETTER AV -// 1dd7 COMBINING LATIN SMALL LETTER C CEDILLA -// 1dd8 COMBINING LATIN SMALL LETTER INSULAR D -// 1dd9 COMBINING LATIN SMALL LETTER ETH -// 1dda COMBINING LATIN SMALL LETTER G -// 1ddb COMBINING LATIN LETTER SMALL CAPITAL G -// 1ddc COMBINING LATIN SMALL LETTER K -// 1ddd COMBINING LATIN SMALL LETTER L -// 1dde COMBINING LATIN LETTER SMALL CAPITAL L -// 1ddf COMBINING LATIN LETTER SMALL CAPITAL M -// 1de0 COMBINING LATIN SMALL LETTER N -// 1de1 COMBINING LATIN LETTER SMALL CAPITAL N -// 1de2 COMBINING LATIN LETTER SMALL CAPITAL R -// 1de3 COMBINING LATIN SMALL LETTER R ROTUNDA -// 1de4 COMBINING LATIN SMALL LETTER S -// 1de5 COMBINING LATIN SMALL LETTER LONG S -// 1de6 COMBINING LATIN SMALL LETTER Z -// 1de7 COMBINING LATIN SMALL LETTER ALPHA -// 1de8 COMBINING LATIN SMALL LETTER B -// 1de9 COMBINING LATIN SMALL LETTER BETA -// 1dea COMBINING LATIN SMALL LETTER SCHWA -// 1deb COMBINING LATIN SMALL LETTER F -// 1dec COMBINING LATIN SMALL LETTER L WITH DOUBLE MIDDLE TILDE -// 1ded COMBINING LATIN SMALL LETTER O WITH LIGHT CENTRALIZATION STROKE -// 1dee COMBINING LATIN SMALL LETTER P -// 1def COMBINING LATIN SMALL LETTER ESH -// 1df0 COMBINING LATIN SMALL LETTER U WITH LIGHT CENTRALIZATION STROKE -// 1df1 COMBINING LATIN SMALL LETTER W -// 1df2 COMBINING LATIN SMALL LETTER A WITH DIAERESIS -// 1df3 COMBINING LATIN SMALL LETTER O WITH DIAERESIS -// 1df4 COMBINING LATIN SMALL LETTER U WITH DIAERESIS -// 1df5 COMBINING UP TACK ABOVE - { 0x1DC0, 0x36, 0x0, 0, 0 }, -// 1dfc COMBINING DOUBLE INVERTED BREVE BELOW -// 1dfd COMBINING ALMOST EQUAL TO BELOW -// 1dfe COMBINING LEFT ARROWHEAD ABOVE -// 1dff COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW - { 0x1DFC, 0x4, 0x0, 0, 0 }, -// 1e00 LATIN CAPITAL LETTER A WITH RING BELOW - { 0x1E00, 0x1, 0x89, 1, 0 }, -// 1e01 LATIN SMALL LETTER A WITH RING BELOW - { 0x1E01, 0x1, 0x49, 0, -1 }, -// 1e02 LATIN CAPITAL LETTER B WITH DOT ABOVE - { 0x1E02, 0x1, 0x89, 1, 0 }, -// 1e03 LATIN SMALL LETTER B WITH DOT ABOVE - { 0x1E03, 0x1, 0x49, 0, -1 }, -// 1e04 LATIN CAPITAL LETTER B WITH DOT BELOW - { 0x1E04, 0x1, 0x89, 1, 0 }, -// 1e05 LATIN SMALL LETTER B WITH DOT BELOW - { 0x1E05, 0x1, 0x49, 0, -1 }, -// 1e06 LATIN CAPITAL LETTER B WITH LINE BELOW - { 0x1E06, 0x1, 0x89, 1, 0 }, -// 1e07 LATIN SMALL LETTER B WITH LINE BELOW - { 0x1E07, 0x1, 0x49, 0, -1 }, -// 1e08 LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE - { 0x1E08, 0x1, 0x89, 1, 0 }, -// 1e09 LATIN SMALL LETTER C WITH CEDILLA AND ACUTE - { 0x1E09, 0x1, 0x49, 0, -1 }, -// 1e0a LATIN CAPITAL LETTER D WITH DOT ABOVE - { 0x1E0A, 0x1, 0x89, 1, 0 }, -// 1e0b LATIN SMALL LETTER D WITH DOT ABOVE - { 0x1E0B, 0x1, 0x49, 0, -1 }, -// 1e0c LATIN CAPITAL LETTER D WITH DOT BELOW - { 0x1E0C, 0x1, 0x89, 1, 0 }, -// 1e0d LATIN SMALL LETTER D WITH DOT BELOW - { 0x1E0D, 0x1, 0x49, 0, -1 }, -// 1e0e LATIN CAPITAL LETTER D WITH LINE BELOW - { 0x1E0E, 0x1, 0x89, 1, 0 }, -// 1e0f LATIN SMALL LETTER D WITH LINE BELOW - { 0x1E0F, 0x1, 0x49, 0, -1 }, -// 1e10 LATIN CAPITAL LETTER D WITH CEDILLA - { 0x1E10, 0x1, 0x89, 1, 0 }, -// 1e11 LATIN SMALL LETTER D WITH CEDILLA - { 0x1E11, 0x1, 0x49, 0, -1 }, -// 1e12 LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW - { 0x1E12, 0x1, 0x89, 1, 0 }, -// 1e13 LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW - { 0x1E13, 0x1, 0x49, 0, -1 }, -// 1e14 LATIN CAPITAL LETTER E WITH MACRON AND GRAVE - { 0x1E14, 0x1, 0x89, 1, 0 }, -// 1e15 LATIN SMALL LETTER E WITH MACRON AND GRAVE - { 0x1E15, 0x1, 0x49, 0, -1 }, -// 1e16 LATIN CAPITAL LETTER E WITH MACRON AND ACUTE - { 0x1E16, 0x1, 0x89, 1, 0 }, -// 1e17 LATIN SMALL LETTER E WITH MACRON AND ACUTE - { 0x1E17, 0x1, 0x49, 0, -1 }, -// 1e18 LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW - { 0x1E18, 0x1, 0x89, 1, 0 }, -// 1e19 LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW - { 0x1E19, 0x1, 0x49, 0, -1 }, -// 1e1a LATIN CAPITAL LETTER E WITH TILDE BELOW - { 0x1E1A, 0x1, 0x89, 1, 0 }, -// 1e1b LATIN SMALL LETTER E WITH TILDE BELOW - { 0x1E1B, 0x1, 0x49, 0, -1 }, -// 1e1c LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE - { 0x1E1C, 0x1, 0x89, 1, 0 }, -// 1e1d LATIN SMALL LETTER E WITH CEDILLA AND BREVE - { 0x1E1D, 0x1, 0x49, 0, -1 }, -// 1e1e LATIN CAPITAL LETTER F WITH DOT ABOVE - { 0x1E1E, 0x1, 0x89, 1, 0 }, -// 1e1f LATIN SMALL LETTER F WITH DOT ABOVE - { 0x1E1F, 0x1, 0x49, 0, -1 }, -// 1e20 LATIN CAPITAL LETTER G WITH MACRON - { 0x1E20, 0x1, 0x89, 1, 0 }, -// 1e21 LATIN SMALL LETTER G WITH MACRON - { 0x1E21, 0x1, 0x49, 0, -1 }, -// 1e22 LATIN CAPITAL LETTER H WITH DOT ABOVE - { 0x1E22, 0x1, 0x89, 1, 0 }, -// 1e23 LATIN SMALL LETTER H WITH DOT ABOVE - { 0x1E23, 0x1, 0x49, 0, -1 }, -// 1e24 LATIN CAPITAL LETTER H WITH DOT BELOW - { 0x1E24, 0x1, 0x89, 1, 0 }, -// 1e25 LATIN SMALL LETTER H WITH DOT BELOW - { 0x1E25, 0x1, 0x49, 0, -1 }, -// 1e26 LATIN CAPITAL LETTER H WITH DIAERESIS - { 0x1E26, 0x1, 0x89, 1, 0 }, -// 1e27 LATIN SMALL LETTER H WITH DIAERESIS - { 0x1E27, 0x1, 0x49, 0, -1 }, -// 1e28 LATIN CAPITAL LETTER H WITH CEDILLA - { 0x1E28, 0x1, 0x89, 1, 0 }, -// 1e29 LATIN SMALL LETTER H WITH CEDILLA - { 0x1E29, 0x1, 0x49, 0, -1 }, -// 1e2a LATIN CAPITAL LETTER H WITH BREVE BELOW - { 0x1E2A, 0x1, 0x89, 1, 0 }, -// 1e2b LATIN SMALL LETTER H WITH BREVE BELOW - { 0x1E2B, 0x1, 0x49, 0, -1 }, -// 1e2c LATIN CAPITAL LETTER I WITH TILDE BELOW - { 0x1E2C, 0x1, 0x89, 1, 0 }, -// 1e2d LATIN SMALL LETTER I WITH TILDE BELOW - { 0x1E2D, 0x1, 0x49, 0, -1 }, -// 1e2e LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE - { 0x1E2E, 0x1, 0x89, 1, 0 }, -// 1e2f LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE - { 0x1E2F, 0x1, 0x49, 0, -1 }, -// 1e30 LATIN CAPITAL LETTER K WITH ACUTE - { 0x1E30, 0x1, 0x89, 1, 0 }, -// 1e31 LATIN SMALL LETTER K WITH ACUTE - { 0x1E31, 0x1, 0x49, 0, -1 }, -// 1e32 LATIN CAPITAL LETTER K WITH DOT BELOW - { 0x1E32, 0x1, 0x89, 1, 0 }, -// 1e33 LATIN SMALL LETTER K WITH DOT BELOW - { 0x1E33, 0x1, 0x49, 0, -1 }, -// 1e34 LATIN CAPITAL LETTER K WITH LINE BELOW - { 0x1E34, 0x1, 0x89, 1, 0 }, -// 1e35 LATIN SMALL LETTER K WITH LINE BELOW - { 0x1E35, 0x1, 0x49, 0, -1 }, -// 1e36 LATIN CAPITAL LETTER L WITH DOT BELOW - { 0x1E36, 0x1, 0x89, 1, 0 }, -// 1e37 LATIN SMALL LETTER L WITH DOT BELOW - { 0x1E37, 0x1, 0x49, 0, -1 }, -// 1e38 LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON - { 0x1E38, 0x1, 0x89, 1, 0 }, -// 1e39 LATIN SMALL LETTER L WITH DOT BELOW AND MACRON - { 0x1E39, 0x1, 0x49, 0, -1 }, -// 1e3a LATIN CAPITAL LETTER L WITH LINE BELOW - { 0x1E3A, 0x1, 0x89, 1, 0 }, -// 1e3b LATIN SMALL LETTER L WITH LINE BELOW - { 0x1E3B, 0x1, 0x49, 0, -1 }, -// 1e3c LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW - { 0x1E3C, 0x1, 0x89, 1, 0 }, -// 1e3d LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW - { 0x1E3D, 0x1, 0x49, 0, -1 }, -// 1e3e LATIN CAPITAL LETTER M WITH ACUTE - { 0x1E3E, 0x1, 0x89, 1, 0 }, -// 1e3f LATIN SMALL LETTER M WITH ACUTE - { 0x1E3F, 0x1, 0x49, 0, -1 }, -// 1e40 LATIN CAPITAL LETTER M WITH DOT ABOVE - { 0x1E40, 0x1, 0x89, 1, 0 }, -// 1e41 LATIN SMALL LETTER M WITH DOT ABOVE - { 0x1E41, 0x1, 0x49, 0, -1 }, -// 1e42 LATIN CAPITAL LETTER M WITH DOT BELOW - { 0x1E42, 0x1, 0x89, 1, 0 }, -// 1e43 LATIN SMALL LETTER M WITH DOT BELOW - { 0x1E43, 0x1, 0x49, 0, -1 }, -// 1e44 LATIN CAPITAL LETTER N WITH DOT ABOVE - { 0x1E44, 0x1, 0x89, 1, 0 }, -// 1e45 LATIN SMALL LETTER N WITH DOT ABOVE - { 0x1E45, 0x1, 0x49, 0, -1 }, -// 1e46 LATIN CAPITAL LETTER N WITH DOT BELOW - { 0x1E46, 0x1, 0x89, 1, 0 }, -// 1e47 LATIN SMALL LETTER N WITH DOT BELOW - { 0x1E47, 0x1, 0x49, 0, -1 }, -// 1e48 LATIN CAPITAL LETTER N WITH LINE BELOW - { 0x1E48, 0x1, 0x89, 1, 0 }, -// 1e49 LATIN SMALL LETTER N WITH LINE BELOW - { 0x1E49, 0x1, 0x49, 0, -1 }, -// 1e4a LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW - { 0x1E4A, 0x1, 0x89, 1, 0 }, -// 1e4b LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW - { 0x1E4B, 0x1, 0x49, 0, -1 }, -// 1e4c LATIN CAPITAL LETTER O WITH TILDE AND ACUTE - { 0x1E4C, 0x1, 0x89, 1, 0 }, -// 1e4d LATIN SMALL LETTER O WITH TILDE AND ACUTE - { 0x1E4D, 0x1, 0x49, 0, -1 }, -// 1e4e LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS - { 0x1E4E, 0x1, 0x89, 1, 0 }, -// 1e4f LATIN SMALL LETTER O WITH TILDE AND DIAERESIS - { 0x1E4F, 0x1, 0x49, 0, -1 }, -// 1e50 LATIN CAPITAL LETTER O WITH MACRON AND GRAVE - { 0x1E50, 0x1, 0x89, 1, 0 }, -// 1e51 LATIN SMALL LETTER O WITH MACRON AND GRAVE - { 0x1E51, 0x1, 0x49, 0, -1 }, -// 1e52 LATIN CAPITAL LETTER O WITH MACRON AND ACUTE - { 0x1E52, 0x1, 0x89, 1, 0 }, -// 1e53 LATIN SMALL LETTER O WITH MACRON AND ACUTE - { 0x1E53, 0x1, 0x49, 0, -1 }, -// 1e54 LATIN CAPITAL LETTER P WITH ACUTE - { 0x1E54, 0x1, 0x89, 1, 0 }, -// 1e55 LATIN SMALL LETTER P WITH ACUTE - { 0x1E55, 0x1, 0x49, 0, -1 }, -// 1e56 LATIN CAPITAL LETTER P WITH DOT ABOVE - { 0x1E56, 0x1, 0x89, 1, 0 }, -// 1e57 LATIN SMALL LETTER P WITH DOT ABOVE - { 0x1E57, 0x1, 0x49, 0, -1 }, -// 1e58 LATIN CAPITAL LETTER R WITH DOT ABOVE - { 0x1E58, 0x1, 0x89, 1, 0 }, -// 1e59 LATIN SMALL LETTER R WITH DOT ABOVE - { 0x1E59, 0x1, 0x49, 0, -1 }, -// 1e5a LATIN CAPITAL LETTER R WITH DOT BELOW - { 0x1E5A, 0x1, 0x89, 1, 0 }, -// 1e5b LATIN SMALL LETTER R WITH DOT BELOW - { 0x1E5B, 0x1, 0x49, 0, -1 }, -// 1e5c LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON - { 0x1E5C, 0x1, 0x89, 1, 0 }, -// 1e5d LATIN SMALL LETTER R WITH DOT BELOW AND MACRON - { 0x1E5D, 0x1, 0x49, 0, -1 }, -// 1e5e LATIN CAPITAL LETTER R WITH LINE BELOW - { 0x1E5E, 0x1, 0x89, 1, 0 }, -// 1e5f LATIN SMALL LETTER R WITH LINE BELOW - { 0x1E5F, 0x1, 0x49, 0, -1 }, -// 1e60 LATIN CAPITAL LETTER S WITH DOT ABOVE - { 0x1E60, 0x1, 0x89, 1, 0 }, -// 1e61 LATIN SMALL LETTER S WITH DOT ABOVE - { 0x1E61, 0x1, 0x49, 0, -1 }, -// 1e62 LATIN CAPITAL LETTER S WITH DOT BELOW - { 0x1E62, 0x1, 0x89, 1, 0 }, -// 1e63 LATIN SMALL LETTER S WITH DOT BELOW - { 0x1E63, 0x1, 0x49, 0, -1 }, -// 1e64 LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE - { 0x1E64, 0x1, 0x89, 1, 0 }, -// 1e65 LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE - { 0x1E65, 0x1, 0x49, 0, -1 }, -// 1e66 LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE - { 0x1E66, 0x1, 0x89, 1, 0 }, -// 1e67 LATIN SMALL LETTER S WITH CARON AND DOT ABOVE - { 0x1E67, 0x1, 0x49, 0, -1 }, -// 1e68 LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE - { 0x1E68, 0x1, 0x89, 1, 0 }, -// 1e69 LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE - { 0x1E69, 0x1, 0x49, 0, -1 }, -// 1e6a LATIN CAPITAL LETTER T WITH DOT ABOVE - { 0x1E6A, 0x1, 0x89, 1, 0 }, -// 1e6b LATIN SMALL LETTER T WITH DOT ABOVE - { 0x1E6B, 0x1, 0x49, 0, -1 }, -// 1e6c LATIN CAPITAL LETTER T WITH DOT BELOW - { 0x1E6C, 0x1, 0x89, 1, 0 }, -// 1e6d LATIN SMALL LETTER T WITH DOT BELOW - { 0x1E6D, 0x1, 0x49, 0, -1 }, -// 1e6e LATIN CAPITAL LETTER T WITH LINE BELOW - { 0x1E6E, 0x1, 0x89, 1, 0 }, -// 1e6f LATIN SMALL LETTER T WITH LINE BELOW - { 0x1E6F, 0x1, 0x49, 0, -1 }, -// 1e70 LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW - { 0x1E70, 0x1, 0x89, 1, 0 }, -// 1e71 LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW - { 0x1E71, 0x1, 0x49, 0, -1 }, -// 1e72 LATIN CAPITAL LETTER U WITH DIAERESIS BELOW - { 0x1E72, 0x1, 0x89, 1, 0 }, -// 1e73 LATIN SMALL LETTER U WITH DIAERESIS BELOW - { 0x1E73, 0x1, 0x49, 0, -1 }, -// 1e74 LATIN CAPITAL LETTER U WITH TILDE BELOW - { 0x1E74, 0x1, 0x89, 1, 0 }, -// 1e75 LATIN SMALL LETTER U WITH TILDE BELOW - { 0x1E75, 0x1, 0x49, 0, -1 }, -// 1e76 LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW - { 0x1E76, 0x1, 0x89, 1, 0 }, -// 1e77 LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW - { 0x1E77, 0x1, 0x49, 0, -1 }, -// 1e78 LATIN CAPITAL LETTER U WITH TILDE AND ACUTE - { 0x1E78, 0x1, 0x89, 1, 0 }, -// 1e79 LATIN SMALL LETTER U WITH TILDE AND ACUTE - { 0x1E79, 0x1, 0x49, 0, -1 }, -// 1e7a LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS - { 0x1E7A, 0x1, 0x89, 1, 0 }, -// 1e7b LATIN SMALL LETTER U WITH MACRON AND DIAERESIS - { 0x1E7B, 0x1, 0x49, 0, -1 }, -// 1e7c LATIN CAPITAL LETTER V WITH TILDE - { 0x1E7C, 0x1, 0x89, 1, 0 }, -// 1e7d LATIN SMALL LETTER V WITH TILDE - { 0x1E7D, 0x1, 0x49, 0, -1 }, -// 1e7e LATIN CAPITAL LETTER V WITH DOT BELOW - { 0x1E7E, 0x1, 0x89, 1, 0 }, -// 1e7f LATIN SMALL LETTER V WITH DOT BELOW - { 0x1E7F, 0x1, 0x49, 0, -1 }, -// 1e80 LATIN CAPITAL LETTER W WITH GRAVE - { 0x1E80, 0x1, 0x89, 1, 0 }, -// 1e81 LATIN SMALL LETTER W WITH GRAVE - { 0x1E81, 0x1, 0x49, 0, -1 }, -// 1e82 LATIN CAPITAL LETTER W WITH ACUTE - { 0x1E82, 0x1, 0x89, 1, 0 }, -// 1e83 LATIN SMALL LETTER W WITH ACUTE - { 0x1E83, 0x1, 0x49, 0, -1 }, -// 1e84 LATIN CAPITAL LETTER W WITH DIAERESIS - { 0x1E84, 0x1, 0x89, 1, 0 }, -// 1e85 LATIN SMALL LETTER W WITH DIAERESIS - { 0x1E85, 0x1, 0x49, 0, -1 }, -// 1e86 LATIN CAPITAL LETTER W WITH DOT ABOVE - { 0x1E86, 0x1, 0x89, 1, 0 }, -// 1e87 LATIN SMALL LETTER W WITH DOT ABOVE - { 0x1E87, 0x1, 0x49, 0, -1 }, -// 1e88 LATIN CAPITAL LETTER W WITH DOT BELOW - { 0x1E88, 0x1, 0x89, 1, 0 }, -// 1e89 LATIN SMALL LETTER W WITH DOT BELOW - { 0x1E89, 0x1, 0x49, 0, -1 }, -// 1e8a LATIN CAPITAL LETTER X WITH DOT ABOVE - { 0x1E8A, 0x1, 0x89, 1, 0 }, -// 1e8b LATIN SMALL LETTER X WITH DOT ABOVE - { 0x1E8B, 0x1, 0x49, 0, -1 }, -// 1e8c LATIN CAPITAL LETTER X WITH DIAERESIS - { 0x1E8C, 0x1, 0x89, 1, 0 }, -// 1e8d LATIN SMALL LETTER X WITH DIAERESIS - { 0x1E8D, 0x1, 0x49, 0, -1 }, -// 1e8e LATIN CAPITAL LETTER Y WITH DOT ABOVE - { 0x1E8E, 0x1, 0x89, 1, 0 }, -// 1e8f LATIN SMALL LETTER Y WITH DOT ABOVE - { 0x1E8F, 0x1, 0x49, 0, -1 }, -// 1e90 LATIN CAPITAL LETTER Z WITH CIRCUMFLEX - { 0x1E90, 0x1, 0x89, 1, 0 }, -// 1e91 LATIN SMALL LETTER Z WITH CIRCUMFLEX - { 0x1E91, 0x1, 0x49, 0, -1 }, -// 1e92 LATIN CAPITAL LETTER Z WITH DOT BELOW - { 0x1E92, 0x1, 0x89, 1, 0 }, -// 1e93 LATIN SMALL LETTER Z WITH DOT BELOW - { 0x1E93, 0x1, 0x49, 0, -1 }, -// 1e94 LATIN CAPITAL LETTER Z WITH LINE BELOW - { 0x1E94, 0x1, 0x89, 1, 0 }, -// 1e95 LATIN SMALL LETTER Z WITH LINE BELOW - { 0x1E95, 0x1, 0x49, 0, -1 }, -// 1e96 LATIN SMALL LETTER H WITH LINE BELOW -// 1e97 LATIN SMALL LETTER T WITH DIAERESIS -// 1e98 LATIN SMALL LETTER W WITH RING ABOVE -// 1e99 LATIN SMALL LETTER Y WITH RING ABOVE -// 1e9a LATIN SMALL LETTER A WITH RIGHT HALF RING - { 0x1E96, 0x5, 0x49, 0, 0 }, -// 1e9b LATIN SMALL LETTER LONG S WITH DOT ABOVE - { 0x1E9B, 0x1, 0x49, 0, -59 }, -// 1e9c LATIN SMALL LETTER LONG S WITH DIAGONAL STROKE -// 1e9d LATIN SMALL LETTER LONG S WITH HIGH STROKE - { 0x1E9C, 0x2, 0x49, 0, 0 }, -// 1e9e LATIN CAPITAL LETTER SHARP S - { 0x1E9E, 0x1, 0x89, -7615, 0 }, -// 1e9f LATIN SMALL LETTER DELTA - { 0x1E9F, 0x1, 0x49, 0, 0 }, -// 1ea0 LATIN CAPITAL LETTER A WITH DOT BELOW - { 0x1EA0, 0x1, 0x89, 1, 0 }, -// 1ea1 LATIN SMALL LETTER A WITH DOT BELOW - { 0x1EA1, 0x1, 0x49, 0, -1 }, -// 1ea2 LATIN CAPITAL LETTER A WITH HOOK ABOVE - { 0x1EA2, 0x1, 0x89, 1, 0 }, -// 1ea3 LATIN SMALL LETTER A WITH HOOK ABOVE - { 0x1EA3, 0x1, 0x49, 0, -1 }, -// 1ea4 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE - { 0x1EA4, 0x1, 0x89, 1, 0 }, -// 1ea5 LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE - { 0x1EA5, 0x1, 0x49, 0, -1 }, -// 1ea6 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE - { 0x1EA6, 0x1, 0x89, 1, 0 }, -// 1ea7 LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE - { 0x1EA7, 0x1, 0x49, 0, -1 }, -// 1ea8 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE - { 0x1EA8, 0x1, 0x89, 1, 0 }, -// 1ea9 LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE - { 0x1EA9, 0x1, 0x49, 0, -1 }, -// 1eaa LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE - { 0x1EAA, 0x1, 0x89, 1, 0 }, -// 1eab LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE - { 0x1EAB, 0x1, 0x49, 0, -1 }, -// 1eac LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW - { 0x1EAC, 0x1, 0x89, 1, 0 }, -// 1ead LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW - { 0x1EAD, 0x1, 0x49, 0, -1 }, -// 1eae LATIN CAPITAL LETTER A WITH BREVE AND ACUTE - { 0x1EAE, 0x1, 0x89, 1, 0 }, -// 1eaf LATIN SMALL LETTER A WITH BREVE AND ACUTE - { 0x1EAF, 0x1, 0x49, 0, -1 }, -// 1eb0 LATIN CAPITAL LETTER A WITH BREVE AND GRAVE - { 0x1EB0, 0x1, 0x89, 1, 0 }, -// 1eb1 LATIN SMALL LETTER A WITH BREVE AND GRAVE - { 0x1EB1, 0x1, 0x49, 0, -1 }, -// 1eb2 LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE - { 0x1EB2, 0x1, 0x89, 1, 0 }, -// 1eb3 LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE - { 0x1EB3, 0x1, 0x49, 0, -1 }, -// 1eb4 LATIN CAPITAL LETTER A WITH BREVE AND TILDE - { 0x1EB4, 0x1, 0x89, 1, 0 }, -// 1eb5 LATIN SMALL LETTER A WITH BREVE AND TILDE - { 0x1EB5, 0x1, 0x49, 0, -1 }, -// 1eb6 LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW - { 0x1EB6, 0x1, 0x89, 1, 0 }, -// 1eb7 LATIN SMALL LETTER A WITH BREVE AND DOT BELOW - { 0x1EB7, 0x1, 0x49, 0, -1 }, -// 1eb8 LATIN CAPITAL LETTER E WITH DOT BELOW - { 0x1EB8, 0x1, 0x89, 1, 0 }, -// 1eb9 LATIN SMALL LETTER E WITH DOT BELOW - { 0x1EB9, 0x1, 0x49, 0, -1 }, -// 1eba LATIN CAPITAL LETTER E WITH HOOK ABOVE - { 0x1EBA, 0x1, 0x89, 1, 0 }, -// 1ebb LATIN SMALL LETTER E WITH HOOK ABOVE - { 0x1EBB, 0x1, 0x49, 0, -1 }, -// 1ebc LATIN CAPITAL LETTER E WITH TILDE - { 0x1EBC, 0x1, 0x89, 1, 0 }, -// 1ebd LATIN SMALL LETTER E WITH TILDE - { 0x1EBD, 0x1, 0x49, 0, -1 }, -// 1ebe LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE - { 0x1EBE, 0x1, 0x89, 1, 0 }, -// 1ebf LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE - { 0x1EBF, 0x1, 0x49, 0, -1 }, -// 1ec0 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE - { 0x1EC0, 0x1, 0x89, 1, 0 }, -// 1ec1 LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE - { 0x1EC1, 0x1, 0x49, 0, -1 }, -// 1ec2 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE - { 0x1EC2, 0x1, 0x89, 1, 0 }, -// 1ec3 LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE - { 0x1EC3, 0x1, 0x49, 0, -1 }, -// 1ec4 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE - { 0x1EC4, 0x1, 0x89, 1, 0 }, -// 1ec5 LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE - { 0x1EC5, 0x1, 0x49, 0, -1 }, -// 1ec6 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW - { 0x1EC6, 0x1, 0x89, 1, 0 }, -// 1ec7 LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW - { 0x1EC7, 0x1, 0x49, 0, -1 }, -// 1ec8 LATIN CAPITAL LETTER I WITH HOOK ABOVE - { 0x1EC8, 0x1, 0x89, 1, 0 }, -// 1ec9 LATIN SMALL LETTER I WITH HOOK ABOVE - { 0x1EC9, 0x1, 0x49, 0, -1 }, -// 1eca LATIN CAPITAL LETTER I WITH DOT BELOW - { 0x1ECA, 0x1, 0x89, 1, 0 }, -// 1ecb LATIN SMALL LETTER I WITH DOT BELOW - { 0x1ECB, 0x1, 0x49, 0, -1 }, -// 1ecc LATIN CAPITAL LETTER O WITH DOT BELOW - { 0x1ECC, 0x1, 0x89, 1, 0 }, -// 1ecd LATIN SMALL LETTER O WITH DOT BELOW - { 0x1ECD, 0x1, 0x49, 0, -1 }, -// 1ece LATIN CAPITAL LETTER O WITH HOOK ABOVE - { 0x1ECE, 0x1, 0x89, 1, 0 }, -// 1ecf LATIN SMALL LETTER O WITH HOOK ABOVE - { 0x1ECF, 0x1, 0x49, 0, -1 }, -// 1ed0 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE - { 0x1ED0, 0x1, 0x89, 1, 0 }, -// 1ed1 LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE - { 0x1ED1, 0x1, 0x49, 0, -1 }, -// 1ed2 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE - { 0x1ED2, 0x1, 0x89, 1, 0 }, -// 1ed3 LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE - { 0x1ED3, 0x1, 0x49, 0, -1 }, -// 1ed4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE - { 0x1ED4, 0x1, 0x89, 1, 0 }, -// 1ed5 LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE - { 0x1ED5, 0x1, 0x49, 0, -1 }, -// 1ed6 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE - { 0x1ED6, 0x1, 0x89, 1, 0 }, -// 1ed7 LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE - { 0x1ED7, 0x1, 0x49, 0, -1 }, -// 1ed8 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW - { 0x1ED8, 0x1, 0x89, 1, 0 }, -// 1ed9 LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW - { 0x1ED9, 0x1, 0x49, 0, -1 }, -// 1eda LATIN CAPITAL LETTER O WITH HORN AND ACUTE - { 0x1EDA, 0x1, 0x89, 1, 0 }, -// 1edb LATIN SMALL LETTER O WITH HORN AND ACUTE - { 0x1EDB, 0x1, 0x49, 0, -1 }, -// 1edc LATIN CAPITAL LETTER O WITH HORN AND GRAVE - { 0x1EDC, 0x1, 0x89, 1, 0 }, -// 1edd LATIN SMALL LETTER O WITH HORN AND GRAVE - { 0x1EDD, 0x1, 0x49, 0, -1 }, -// 1ede LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE - { 0x1EDE, 0x1, 0x89, 1, 0 }, -// 1edf LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE - { 0x1EDF, 0x1, 0x49, 0, -1 }, -// 1ee0 LATIN CAPITAL LETTER O WITH HORN AND TILDE - { 0x1EE0, 0x1, 0x89, 1, 0 }, -// 1ee1 LATIN SMALL LETTER O WITH HORN AND TILDE - { 0x1EE1, 0x1, 0x49, 0, -1 }, -// 1ee2 LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW - { 0x1EE2, 0x1, 0x89, 1, 0 }, -// 1ee3 LATIN SMALL LETTER O WITH HORN AND DOT BELOW - { 0x1EE3, 0x1, 0x49, 0, -1 }, -// 1ee4 LATIN CAPITAL LETTER U WITH DOT BELOW - { 0x1EE4, 0x1, 0x89, 1, 0 }, -// 1ee5 LATIN SMALL LETTER U WITH DOT BELOW - { 0x1EE5, 0x1, 0x49, 0, -1 }, -// 1ee6 LATIN CAPITAL LETTER U WITH HOOK ABOVE - { 0x1EE6, 0x1, 0x89, 1, 0 }, -// 1ee7 LATIN SMALL LETTER U WITH HOOK ABOVE - { 0x1EE7, 0x1, 0x49, 0, -1 }, -// 1ee8 LATIN CAPITAL LETTER U WITH HORN AND ACUTE - { 0x1EE8, 0x1, 0x89, 1, 0 }, -// 1ee9 LATIN SMALL LETTER U WITH HORN AND ACUTE - { 0x1EE9, 0x1, 0x49, 0, -1 }, -// 1eea LATIN CAPITAL LETTER U WITH HORN AND GRAVE - { 0x1EEA, 0x1, 0x89, 1, 0 }, -// 1eeb LATIN SMALL LETTER U WITH HORN AND GRAVE - { 0x1EEB, 0x1, 0x49, 0, -1 }, -// 1eec LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE - { 0x1EEC, 0x1, 0x89, 1, 0 }, -// 1eed LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE - { 0x1EED, 0x1, 0x49, 0, -1 }, -// 1eee LATIN CAPITAL LETTER U WITH HORN AND TILDE - { 0x1EEE, 0x1, 0x89, 1, 0 }, -// 1eef LATIN SMALL LETTER U WITH HORN AND TILDE - { 0x1EEF, 0x1, 0x49, 0, -1 }, -// 1ef0 LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW - { 0x1EF0, 0x1, 0x89, 1, 0 }, -// 1ef1 LATIN SMALL LETTER U WITH HORN AND DOT BELOW - { 0x1EF1, 0x1, 0x49, 0, -1 }, -// 1ef2 LATIN CAPITAL LETTER Y WITH GRAVE - { 0x1EF2, 0x1, 0x89, 1, 0 }, -// 1ef3 LATIN SMALL LETTER Y WITH GRAVE - { 0x1EF3, 0x1, 0x49, 0, -1 }, -// 1ef4 LATIN CAPITAL LETTER Y WITH DOT BELOW - { 0x1EF4, 0x1, 0x89, 1, 0 }, -// 1ef5 LATIN SMALL LETTER Y WITH DOT BELOW - { 0x1EF5, 0x1, 0x49, 0, -1 }, -// 1ef6 LATIN CAPITAL LETTER Y WITH HOOK ABOVE - { 0x1EF6, 0x1, 0x89, 1, 0 }, -// 1ef7 LATIN SMALL LETTER Y WITH HOOK ABOVE - { 0x1EF7, 0x1, 0x49, 0, -1 }, -// 1ef8 LATIN CAPITAL LETTER Y WITH TILDE - { 0x1EF8, 0x1, 0x89, 1, 0 }, -// 1ef9 LATIN SMALL LETTER Y WITH TILDE - { 0x1EF9, 0x1, 0x49, 0, -1 }, -// 1efa LATIN CAPITAL LETTER MIDDLE-WELSH LL - { 0x1EFA, 0x1, 0x89, 1, 0 }, -// 1efb LATIN SMALL LETTER MIDDLE-WELSH LL - { 0x1EFB, 0x1, 0x49, 0, -1 }, -// 1efc LATIN CAPITAL LETTER MIDDLE-WELSH V - { 0x1EFC, 0x1, 0x89, 1, 0 }, -// 1efd LATIN SMALL LETTER MIDDLE-WELSH V - { 0x1EFD, 0x1, 0x49, 0, -1 }, -// 1efe LATIN CAPITAL LETTER Y WITH LOOP - { 0x1EFE, 0x1, 0x89, 1, 0 }, -// 1eff LATIN SMALL LETTER Y WITH LOOP - { 0x1EFF, 0x1, 0x49, 0, -1 }, -// 1f00 GREEK SMALL LETTER ALPHA WITH PSILI -// 1f01 GREEK SMALL LETTER ALPHA WITH DASIA -// 1f02 GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA -// 1f03 GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA -// 1f04 GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA -// 1f05 GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA -// 1f06 GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI -// 1f07 GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI - { 0x1F00, 0x8, 0x49, 0, 8 }, -// 1f08 GREEK CAPITAL LETTER ALPHA WITH PSILI -// 1f09 GREEK CAPITAL LETTER ALPHA WITH DASIA -// 1f0a GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA -// 1f0b GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA -// 1f0c GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA -// 1f0d GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA -// 1f0e GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI -// 1f0f GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI - { 0x1F08, 0x8, 0x89, -8, 0 }, -// 1f10 GREEK SMALL LETTER EPSILON WITH PSILI -// 1f11 GREEK SMALL LETTER EPSILON WITH DASIA -// 1f12 GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA -// 1f13 GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA -// 1f14 GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA -// 1f15 GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA - { 0x1F10, 0x6, 0x49, 0, 8 }, -// 1f18 GREEK CAPITAL LETTER EPSILON WITH PSILI -// 1f19 GREEK CAPITAL LETTER EPSILON WITH DASIA -// 1f1a GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA -// 1f1b GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA -// 1f1c GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA -// 1f1d GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA - { 0x1F18, 0x6, 0x89, -8, 0 }, -// 1f20 GREEK SMALL LETTER ETA WITH PSILI -// 1f21 GREEK SMALL LETTER ETA WITH DASIA -// 1f22 GREEK SMALL LETTER ETA WITH PSILI AND VARIA -// 1f23 GREEK SMALL LETTER ETA WITH DASIA AND VARIA -// 1f24 GREEK SMALL LETTER ETA WITH PSILI AND OXIA -// 1f25 GREEK SMALL LETTER ETA WITH DASIA AND OXIA -// 1f26 GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI -// 1f27 GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI - { 0x1F20, 0x8, 0x49, 0, 8 }, -// 1f28 GREEK CAPITAL LETTER ETA WITH PSILI -// 1f29 GREEK CAPITAL LETTER ETA WITH DASIA -// 1f2a GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA -// 1f2b GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA -// 1f2c GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA -// 1f2d GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA -// 1f2e GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI -// 1f2f GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI - { 0x1F28, 0x8, 0x89, -8, 0 }, -// 1f30 GREEK SMALL LETTER IOTA WITH PSILI -// 1f31 GREEK SMALL LETTER IOTA WITH DASIA -// 1f32 GREEK SMALL LETTER IOTA WITH PSILI AND VARIA -// 1f33 GREEK SMALL LETTER IOTA WITH DASIA AND VARIA -// 1f34 GREEK SMALL LETTER IOTA WITH PSILI AND OXIA -// 1f35 GREEK SMALL LETTER IOTA WITH DASIA AND OXIA -// 1f36 GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI -// 1f37 GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI - { 0x1F30, 0x8, 0x49, 0, 8 }, -// 1f38 GREEK CAPITAL LETTER IOTA WITH PSILI -// 1f39 GREEK CAPITAL LETTER IOTA WITH DASIA -// 1f3a GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA -// 1f3b GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA -// 1f3c GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA -// 1f3d GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA -// 1f3e GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI -// 1f3f GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI - { 0x1F38, 0x8, 0x89, -8, 0 }, -// 1f40 GREEK SMALL LETTER OMICRON WITH PSILI -// 1f41 GREEK SMALL LETTER OMICRON WITH DASIA -// 1f42 GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA -// 1f43 GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA -// 1f44 GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA -// 1f45 GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA - { 0x1F40, 0x6, 0x49, 0, 8 }, -// 1f48 GREEK CAPITAL LETTER OMICRON WITH PSILI -// 1f49 GREEK CAPITAL LETTER OMICRON WITH DASIA -// 1f4a GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA -// 1f4b GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA -// 1f4c GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA -// 1f4d GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA - { 0x1F48, 0x6, 0x89, -8, 0 }, -// 1f50 GREEK SMALL LETTER UPSILON WITH PSILI - { 0x1F50, 0x1, 0x49, 0, 0 }, -// 1f51 GREEK SMALL LETTER UPSILON WITH DASIA - { 0x1F51, 0x1, 0x49, 0, 8 }, -// 1f52 GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA - { 0x1F52, 0x1, 0x49, 0, 0 }, -// 1f53 GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA - { 0x1F53, 0x1, 0x49, 0, 8 }, -// 1f54 GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA - { 0x1F54, 0x1, 0x49, 0, 0 }, -// 1f55 GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA - { 0x1F55, 0x1, 0x49, 0, 8 }, -// 1f56 GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI - { 0x1F56, 0x1, 0x49, 0, 0 }, -// 1f57 GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI - { 0x1F57, 0x1, 0x49, 0, 8 }, -// 1f59 GREEK CAPITAL LETTER UPSILON WITH DASIA - { 0x1F59, 0x1, 0x89, -8, 0 }, -// 1f5b GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA - { 0x1F5B, 0x1, 0x89, -8, 0 }, -// 1f5d GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA - { 0x1F5D, 0x1, 0x89, -8, 0 }, -// 1f5f GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI - { 0x1F5F, 0x1, 0x89, -8, 0 }, -// 1f60 GREEK SMALL LETTER OMEGA WITH PSILI -// 1f61 GREEK SMALL LETTER OMEGA WITH DASIA -// 1f62 GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA -// 1f63 GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA -// 1f64 GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA -// 1f65 GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA -// 1f66 GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI -// 1f67 GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI - { 0x1F60, 0x8, 0x49, 0, 8 }, -// 1f68 GREEK CAPITAL LETTER OMEGA WITH PSILI -// 1f69 GREEK CAPITAL LETTER OMEGA WITH DASIA -// 1f6a GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA -// 1f6b GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA -// 1f6c GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA -// 1f6d GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA -// 1f6e GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI -// 1f6f GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI - { 0x1F68, 0x8, 0x89, -8, 0 }, -// 1f70 GREEK SMALL LETTER ALPHA WITH VARIA -// 1f71 GREEK SMALL LETTER ALPHA WITH OXIA - { 0x1F70, 0x2, 0x49, 0, 74 }, -// 1f72 GREEK SMALL LETTER EPSILON WITH VARIA -// 1f73 GREEK SMALL LETTER EPSILON WITH OXIA -// 1f74 GREEK SMALL LETTER ETA WITH VARIA -// 1f75 GREEK SMALL LETTER ETA WITH OXIA - { 0x1F72, 0x4, 0x49, 0, 86 }, -// 1f76 GREEK SMALL LETTER IOTA WITH VARIA -// 1f77 GREEK SMALL LETTER IOTA WITH OXIA - { 0x1F76, 0x2, 0x49, 0, 100 }, -// 1f78 GREEK SMALL LETTER OMICRON WITH VARIA -// 1f79 GREEK SMALL LETTER OMICRON WITH OXIA - { 0x1F78, 0x2, 0x49, 0, 128 }, -// 1f7a GREEK SMALL LETTER UPSILON WITH VARIA -// 1f7b GREEK SMALL LETTER UPSILON WITH OXIA - { 0x1F7A, 0x2, 0x49, 0, 112 }, -// 1f7c GREEK SMALL LETTER OMEGA WITH VARIA -// 1f7d GREEK SMALL LETTER OMEGA WITH OXIA - { 0x1F7C, 0x2, 0x49, 0, 126 }, -// 1f80 GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI -// 1f81 GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI -// 1f82 GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI -// 1f83 GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI -// 1f84 GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI -// 1f85 GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI -// 1f86 GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI -// 1f87 GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI - { 0x1F80, 0x8, 0x49, 0, 8 }, -// 1f88 GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI -// 1f89 GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI -// 1f8a GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI -// 1f8b GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI -// 1f8c GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI -// 1f8d GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI -// 1f8e GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI -// 1f8f GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI - { 0x1F88, 0x8, 0x89, -8, 0 }, -// 1f90 GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI -// 1f91 GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI -// 1f92 GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI -// 1f93 GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI -// 1f94 GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI -// 1f95 GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI -// 1f96 GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI -// 1f97 GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI - { 0x1F90, 0x8, 0x49, 0, 8 }, -// 1f98 GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI -// 1f99 GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI -// 1f9a GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI -// 1f9b GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI -// 1f9c GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI -// 1f9d GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI -// 1f9e GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI -// 1f9f GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI - { 0x1F98, 0x8, 0x89, -8, 0 }, -// 1fa0 GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI -// 1fa1 GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI -// 1fa2 GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI -// 1fa3 GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI -// 1fa4 GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI -// 1fa5 GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI -// 1fa6 GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI -// 1fa7 GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI - { 0x1FA0, 0x8, 0x49, 0, 8 }, -// 1fa8 GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI -// 1fa9 GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI -// 1faa GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI -// 1fab GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI -// 1fac GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI -// 1fad GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI -// 1fae GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI -// 1faf GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI - { 0x1FA8, 0x8, 0x89, -8, 0 }, -// 1fb0 GREEK SMALL LETTER ALPHA WITH VRACHY -// 1fb1 GREEK SMALL LETTER ALPHA WITH MACRON - { 0x1FB0, 0x2, 0x49, 0, 8 }, -// 1fb2 GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI - { 0x1FB2, 0x1, 0x49, 0, 0 }, -// 1fb3 GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI - { 0x1FB3, 0x1, 0x49, 0, 9 }, -// 1fb4 GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI - { 0x1FB4, 0x1, 0x49, 0, 0 }, -// 1fb6 GREEK SMALL LETTER ALPHA WITH PERISPOMENI -// 1fb7 GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI - { 0x1FB6, 0x2, 0x49, 0, 0 }, -// 1fb8 GREEK CAPITAL LETTER ALPHA WITH VRACHY -// 1fb9 GREEK CAPITAL LETTER ALPHA WITH MACRON - { 0x1FB8, 0x2, 0x89, -8, 0 }, -// 1fba GREEK CAPITAL LETTER ALPHA WITH VARIA -// 1fbb GREEK CAPITAL LETTER ALPHA WITH OXIA - { 0x1FBA, 0x2, 0x89, -74, 0 }, -// 1fbc GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI - { 0x1FBC, 0x1, 0x89, -9, 0 }, -// 1fbd GREEK KORONIS - { 0x1FBD, 0x1, 0x8, 0, 0 }, -// 1fbe GREEK PROSGEGRAMMENI - { 0x1FBE, 0x1, 0x49, 0, -7205 }, -// 1fbf GREEK PSILI -// 1fc0 GREEK PERISPOMENI -// 1fc1 GREEK DIALYTIKA AND PERISPOMENI - { 0x1FBF, 0x3, 0x8, 0, 0 }, -// 1fc2 GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI - { 0x1FC2, 0x1, 0x49, 0, 0 }, -// 1fc3 GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI - { 0x1FC3, 0x1, 0x49, 0, 9 }, -// 1fc4 GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI - { 0x1FC4, 0x1, 0x49, 0, 0 }, -// 1fc6 GREEK SMALL LETTER ETA WITH PERISPOMENI -// 1fc7 GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI - { 0x1FC6, 0x2, 0x49, 0, 0 }, -// 1fc8 GREEK CAPITAL LETTER EPSILON WITH VARIA -// 1fc9 GREEK CAPITAL LETTER EPSILON WITH OXIA -// 1fca GREEK CAPITAL LETTER ETA WITH VARIA -// 1fcb GREEK CAPITAL LETTER ETA WITH OXIA - { 0x1FC8, 0x4, 0x89, -86, 0 }, -// 1fcc GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI - { 0x1FCC, 0x1, 0x89, -9, 0 }, -// 1fcd GREEK PSILI AND VARIA -// 1fce GREEK PSILI AND OXIA -// 1fcf GREEK PSILI AND PERISPOMENI - { 0x1FCD, 0x3, 0x8, 0, 0 }, -// 1fd0 GREEK SMALL LETTER IOTA WITH VRACHY -// 1fd1 GREEK SMALL LETTER IOTA WITH MACRON - { 0x1FD0, 0x2, 0x49, 0, 8 }, -// 1fd2 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA -// 1fd3 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA - { 0x1FD2, 0x2, 0x49, 0, 0 }, -// 1fd6 GREEK SMALL LETTER IOTA WITH PERISPOMENI -// 1fd7 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI - { 0x1FD6, 0x2, 0x49, 0, 0 }, -// 1fd8 GREEK CAPITAL LETTER IOTA WITH VRACHY -// 1fd9 GREEK CAPITAL LETTER IOTA WITH MACRON - { 0x1FD8, 0x2, 0x89, -8, 0 }, -// 1fda GREEK CAPITAL LETTER IOTA WITH VARIA -// 1fdb GREEK CAPITAL LETTER IOTA WITH OXIA - { 0x1FDA, 0x2, 0x89, -100, 0 }, -// 1fdd GREEK DASIA AND VARIA -// 1fde GREEK DASIA AND OXIA -// 1fdf GREEK DASIA AND PERISPOMENI - { 0x1FDD, 0x3, 0x8, 0, 0 }, -// 1fe0 GREEK SMALL LETTER UPSILON WITH VRACHY -// 1fe1 GREEK SMALL LETTER UPSILON WITH MACRON - { 0x1FE0, 0x2, 0x49, 0, 8 }, -// 1fe2 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA -// 1fe3 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA -// 1fe4 GREEK SMALL LETTER RHO WITH PSILI - { 0x1FE2, 0x3, 0x49, 0, 0 }, -// 1fe5 GREEK SMALL LETTER RHO WITH DASIA - { 0x1FE5, 0x1, 0x49, 0, 7 }, -// 1fe6 GREEK SMALL LETTER UPSILON WITH PERISPOMENI -// 1fe7 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI - { 0x1FE6, 0x2, 0x49, 0, 0 }, -// 1fe8 GREEK CAPITAL LETTER UPSILON WITH VRACHY -// 1fe9 GREEK CAPITAL LETTER UPSILON WITH MACRON - { 0x1FE8, 0x2, 0x89, -8, 0 }, -// 1fea GREEK CAPITAL LETTER UPSILON WITH VARIA -// 1feb GREEK CAPITAL LETTER UPSILON WITH OXIA - { 0x1FEA, 0x2, 0x89, -112, 0 }, -// 1fec GREEK CAPITAL LETTER RHO WITH DASIA - { 0x1FEC, 0x1, 0x89, -7, 0 }, -// 1fed GREEK DIALYTIKA AND VARIA -// 1fee GREEK DIALYTIKA AND OXIA -// 1fef GREEK VARIA - { 0x1FED, 0x3, 0x8, 0, 0 }, -// 1ff2 GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI - { 0x1FF2, 0x1, 0x49, 0, 0 }, -// 1ff3 GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI - { 0x1FF3, 0x1, 0x49, 0, 9 }, -// 1ff4 GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI - { 0x1FF4, 0x1, 0x49, 0, 0 }, -// 1ff6 GREEK SMALL LETTER OMEGA WITH PERISPOMENI -// 1ff7 GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI - { 0x1FF6, 0x2, 0x49, 0, 0 }, -// 1ff8 GREEK CAPITAL LETTER OMICRON WITH VARIA -// 1ff9 GREEK CAPITAL LETTER OMICRON WITH OXIA - { 0x1FF8, 0x2, 0x89, -128, 0 }, -// 1ffa GREEK CAPITAL LETTER OMEGA WITH VARIA -// 1ffb GREEK CAPITAL LETTER OMEGA WITH OXIA - { 0x1FFA, 0x2, 0x89, -126, 0 }, -// 1ffc GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI - { 0x1FFC, 0x1, 0x89, -9, 0 }, -// 1ffd GREEK OXIA -// 1ffe GREEK DASIA - { 0x1FFD, 0x2, 0x8, 0, 0 }, -// 2000 EN QUAD -// 2001 EM QUAD -// 2002 EN SPACE -// 2003 EM SPACE -// 2004 THREE-PER-EM SPACE -// 2005 FOUR-PER-EM SPACE -// 2006 SIX-PER-EM SPACE -// 2007 FIGURE SPACE -// 2008 PUNCTUATION SPACE -// 2009 THIN SPACE -// 200a HAIR SPACE - { 0x2000, 0xB, 0x20, 0, 0 }, -// 200b ZERO WIDTH SPACE -// 200c ZERO WIDTH NON-JOINER -// 200d ZERO WIDTH JOINER -// 200e LEFT-TO-RIGHT MARK -// 200f RIGHT-TO-LEFT MARK - { 0x200B, 0x5, 0x0, 0, 0 }, -// 2010 HYPHEN -// 2011 NON-BREAKING HYPHEN -// 2012 FIGURE DASH -// 2013 EN DASH -// 2014 EM DASH -// 2015 HORIZONTAL BAR -// 2016 DOUBLE VERTICAL LINE -// 2017 DOUBLE LOW LINE -// 2018 LEFT SINGLE QUOTATION MARK -// 2019 RIGHT SINGLE QUOTATION MARK -// 201a SINGLE LOW-9 QUOTATION MARK -// 201b SINGLE HIGH-REVERSED-9 QUOTATION MARK -// 201c LEFT DOUBLE QUOTATION MARK -// 201d RIGHT DOUBLE QUOTATION MARK -// 201e DOUBLE LOW-9 QUOTATION MARK -// 201f DOUBLE HIGH-REVERSED-9 QUOTATION MARK -// 2020 DAGGER -// 2021 DOUBLE DAGGER -// 2022 BULLET -// 2023 TRIANGULAR BULLET -// 2024 ONE DOT LEADER -// 2025 TWO DOT LEADER -// 2026 HORIZONTAL ELLIPSIS -// 2027 HYPHENATION POINT - { 0x2010, 0x18, 0x18, 0, 0 }, -// 2028 LINE SEPARATOR -// 2029 PARAGRAPH SEPARATOR - { 0x2028, 0x2, 0x20, 0, 0 }, -// 202a LEFT-TO-RIGHT EMBEDDING -// 202b RIGHT-TO-LEFT EMBEDDING -// 202c POP DIRECTIONAL FORMATTING -// 202d LEFT-TO-RIGHT OVERRIDE -// 202e RIGHT-TO-LEFT OVERRIDE - { 0x202A, 0x5, 0x0, 0, 0 }, -// 202f NARROW NO-BREAK SPACE - { 0x202F, 0x1, 0x20, 0, 0 }, -// 2030 PER MILLE SIGN -// 2031 PER TEN THOUSAND SIGN -// 2032 PRIME -// 2033 DOUBLE PRIME -// 2034 TRIPLE PRIME -// 2035 REVERSED PRIME -// 2036 REVERSED DOUBLE PRIME -// 2037 REVERSED TRIPLE PRIME -// 2038 CARET -// 2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK -// 203a SINGLE RIGHT-POINTING ANGLE QUOTATION MARK -// 203b REFERENCE MARK -// 203c DOUBLE EXCLAMATION MARK -// 203d INTERROBANG -// 203e OVERLINE -// 203f UNDERTIE -// 2040 CHARACTER TIE -// 2041 CARET INSERTION POINT -// 2042 ASTERISM -// 2043 HYPHEN BULLET - { 0x2030, 0x14, 0x18, 0, 0 }, -// 2044 FRACTION SLASH - { 0x2044, 0x1, 0x8, 0, 0 }, -// 2045 LEFT SQUARE BRACKET WITH QUILL -// 2046 RIGHT SQUARE BRACKET WITH QUILL -// 2047 DOUBLE QUESTION MARK -// 2048 QUESTION EXCLAMATION MARK -// 2049 EXCLAMATION QUESTION MARK -// 204a TIRONIAN SIGN ET -// 204b REVERSED PILCROW SIGN -// 204c BLACK LEFTWARDS BULLET -// 204d BLACK RIGHTWARDS BULLET -// 204e LOW ASTERISK -// 204f REVERSED SEMICOLON -// 2050 CLOSE UP -// 2051 TWO ASTERISKS ALIGNED VERTICALLY - { 0x2045, 0xD, 0x18, 0, 0 }, -// 2052 COMMERCIAL MINUS SIGN - { 0x2052, 0x1, 0x8, 0, 0 }, -// 2053 SWUNG DASH -// 2054 INVERTED UNDERTIE -// 2055 FLOWER PUNCTUATION MARK -// 2056 THREE DOT PUNCTUATION -// 2057 QUADRUPLE PRIME -// 2058 FOUR DOT PUNCTUATION -// 2059 FIVE DOT PUNCTUATION -// 205a TWO DOT PUNCTUATION -// 205b FOUR DOT MARK -// 205c DOTTED CROSS -// 205d TRICOLON -// 205e VERTICAL FOUR DOTS - { 0x2053, 0xC, 0x18, 0, 0 }, -// 205f MEDIUM MATHEMATICAL SPACE - { 0x205F, 0x1, 0x20, 0, 0 }, -// 2060 WORD JOINER -// 2061 FUNCTION APPLICATION -// 2062 INVISIBLE TIMES -// 2063 INVISIBLE SEPARATOR -// 2064 INVISIBLE PLUS - { 0x2060, 0x5, 0x0, 0, 0 }, -// 2066 LEFT-TO-RIGHT ISOLATE -// 2067 RIGHT-TO-LEFT ISOLATE -// 2068 FIRST STRONG ISOLATE -// 2069 POP DIRECTIONAL ISOLATE -// 206a INHIBIT SYMMETRIC SWAPPING -// 206b ACTIVATE SYMMETRIC SWAPPING -// 206c INHIBIT ARABIC FORM SHAPING -// 206d ACTIVATE ARABIC FORM SHAPING -// 206e NATIONAL DIGIT SHAPES -// 206f NOMINAL DIGIT SHAPES - { 0x2066, 0xA, 0x0, 0, 0 }, -// 2070 SUPERSCRIPT ZERO - { 0x2070, 0x1, 0x8, 0, 0 }, -// 2071 SUPERSCRIPT LATIN SMALL LETTER I - { 0x2071, 0x1, 0x9, 0, 0 }, -// 2074 SUPERSCRIPT FOUR -// 2075 SUPERSCRIPT FIVE -// 2076 SUPERSCRIPT SIX -// 2077 SUPERSCRIPT SEVEN -// 2078 SUPERSCRIPT EIGHT -// 2079 SUPERSCRIPT NINE -// 207a SUPERSCRIPT PLUS SIGN -// 207b SUPERSCRIPT MINUS -// 207c SUPERSCRIPT EQUALS SIGN - { 0x2074, 0x9, 0x8, 0, 0 }, -// 207d SUPERSCRIPT LEFT PARENTHESIS -// 207e SUPERSCRIPT RIGHT PARENTHESIS - { 0x207D, 0x2, 0x18, 0, 0 }, -// 207f SUPERSCRIPT LATIN SMALL LETTER N - { 0x207F, 0x1, 0x9, 0, 0 }, -// 2080 SUBSCRIPT ZERO -// 2081 SUBSCRIPT ONE -// 2082 SUBSCRIPT TWO -// 2083 SUBSCRIPT THREE -// 2084 SUBSCRIPT FOUR -// 2085 SUBSCRIPT FIVE -// 2086 SUBSCRIPT SIX -// 2087 SUBSCRIPT SEVEN -// 2088 SUBSCRIPT EIGHT -// 2089 SUBSCRIPT NINE -// 208a SUBSCRIPT PLUS SIGN -// 208b SUBSCRIPT MINUS -// 208c SUBSCRIPT EQUALS SIGN - { 0x2080, 0xD, 0x8, 0, 0 }, -// 208d SUBSCRIPT LEFT PARENTHESIS -// 208e SUBSCRIPT RIGHT PARENTHESIS - { 0x208D, 0x2, 0x18, 0, 0 }, -// 2090 LATIN SUBSCRIPT SMALL LETTER A -// 2091 LATIN SUBSCRIPT SMALL LETTER E -// 2092 LATIN SUBSCRIPT SMALL LETTER O -// 2093 LATIN SUBSCRIPT SMALL LETTER X -// 2094 LATIN SUBSCRIPT SMALL LETTER SCHWA -// 2095 LATIN SUBSCRIPT SMALL LETTER H -// 2096 LATIN SUBSCRIPT SMALL LETTER K -// 2097 LATIN SUBSCRIPT SMALL LETTER L -// 2098 LATIN SUBSCRIPT SMALL LETTER M -// 2099 LATIN SUBSCRIPT SMALL LETTER N -// 209a LATIN SUBSCRIPT SMALL LETTER P -// 209b LATIN SUBSCRIPT SMALL LETTER S -// 209c LATIN SUBSCRIPT SMALL LETTER T - { 0x2090, 0xD, 0x9, 0, 0 }, -// 20a0 EURO-CURRENCY SIGN -// 20a1 COLON SIGN -// 20a2 CRUZEIRO SIGN -// 20a3 FRENCH FRANC SIGN -// 20a4 LIRA SIGN -// 20a5 MILL SIGN -// 20a6 NAIRA SIGN -// 20a7 PESETA SIGN -// 20a8 RUPEE SIGN -// 20a9 WON SIGN -// 20aa NEW SHEQEL SIGN -// 20ab DONG SIGN -// 20ac EURO SIGN -// 20ad KIP SIGN -// 20ae TUGRIK SIGN -// 20af DRACHMA SIGN -// 20b0 GERMAN PENNY SIGN -// 20b1 PESO SIGN -// 20b2 GUARANI SIGN -// 20b3 AUSTRAL SIGN -// 20b4 HRYVNIA SIGN -// 20b5 CEDI SIGN -// 20b6 LIVRE TOURNOIS SIGN -// 20b7 SPESMILO SIGN -// 20b8 TENGE SIGN -// 20b9 INDIAN RUPEE SIGN -// 20ba TURKISH LIRA SIGN -// 20bb NORDIC MARK SIGN -// 20bc MANAT SIGN -// 20bd RUBLE SIGN - { 0x20A0, 0x1E, 0x8, 0, 0 }, -// 20d0 COMBINING LEFT HARPOON ABOVE -// 20d1 COMBINING RIGHT HARPOON ABOVE -// 20d2 COMBINING LONG VERTICAL LINE OVERLAY -// 20d3 COMBINING SHORT VERTICAL LINE OVERLAY -// 20d4 COMBINING ANTICLOCKWISE ARROW ABOVE -// 20d5 COMBINING CLOCKWISE ARROW ABOVE -// 20d6 COMBINING LEFT ARROW ABOVE -// 20d7 COMBINING RIGHT ARROW ABOVE -// 20d8 COMBINING RING OVERLAY -// 20d9 COMBINING CLOCKWISE RING OVERLAY -// 20da COMBINING ANTICLOCKWISE RING OVERLAY -// 20db COMBINING THREE DOTS ABOVE -// 20dc COMBINING FOUR DOTS ABOVE -// 20dd COMBINING ENCLOSING CIRCLE -// 20de COMBINING ENCLOSING SQUARE -// 20df COMBINING ENCLOSING DIAMOND -// 20e0 COMBINING ENCLOSING CIRCLE BACKSLASH -// 20e1 COMBINING LEFT RIGHT ARROW ABOVE -// 20e2 COMBINING ENCLOSING SCREEN -// 20e3 COMBINING ENCLOSING KEYCAP -// 20e4 COMBINING ENCLOSING UPWARD POINTING TRIANGLE -// 20e5 COMBINING REVERSE SOLIDUS OVERLAY -// 20e6 COMBINING DOUBLE VERTICAL STROKE OVERLAY -// 20e7 COMBINING ANNUITY SYMBOL -// 20e8 COMBINING TRIPLE UNDERDOT -// 20e9 COMBINING WIDE BRIDGE ABOVE -// 20ea COMBINING LEFTWARDS ARROW OVERLAY -// 20eb COMBINING LONG DOUBLE SOLIDUS OVERLAY -// 20ec COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS -// 20ed COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS -// 20ee COMBINING LEFT ARROW BELOW -// 20ef COMBINING RIGHT ARROW BELOW -// 20f0 COMBINING ASTERISK ABOVE - { 0x20D0, 0x21, 0x0, 0, 0 }, -// 2100 ACCOUNT OF -// 2101 ADDRESSED TO THE SUBJECT - { 0x2100, 0x2, 0x8, 0, 0 }, -// 2102 DOUBLE-STRUCK CAPITAL C - { 0x2102, 0x1, 0x89, 0, 0 }, -// 2103 DEGREE CELSIUS -// 2104 CENTRE LINE SYMBOL -// 2105 CARE OF -// 2106 CADA UNA - { 0x2103, 0x4, 0x8, 0, 0 }, -// 2107 EULER CONSTANT - { 0x2107, 0x1, 0x89, 0, 0 }, -// 2108 SCRUPLE -// 2109 DEGREE FAHRENHEIT - { 0x2108, 0x2, 0x8, 0, 0 }, -// 210a SCRIPT SMALL G - { 0x210A, 0x1, 0x49, 0, 0 }, -// 210b SCRIPT CAPITAL H -// 210c BLACK-LETTER CAPITAL H -// 210d DOUBLE-STRUCK CAPITAL H - { 0x210B, 0x3, 0x89, 0, 0 }, -// 210e PLANCK CONSTANT -// 210f PLANCK CONSTANT OVER TWO PI - { 0x210E, 0x2, 0x49, 0, 0 }, -// 2110 SCRIPT CAPITAL I -// 2111 BLACK-LETTER CAPITAL I -// 2112 SCRIPT CAPITAL L - { 0x2110, 0x3, 0x89, 0, 0 }, -// 2113 SCRIPT SMALL L - { 0x2113, 0x1, 0x49, 0, 0 }, -// 2114 L B BAR SYMBOL - { 0x2114, 0x1, 0x8, 0, 0 }, -// 2115 DOUBLE-STRUCK CAPITAL N - { 0x2115, 0x1, 0x89, 0, 0 }, -// 2116 NUMERO SIGN -// 2117 SOUND RECORDING COPYRIGHT -// 2118 SCRIPT CAPITAL P - { 0x2116, 0x3, 0x8, 0, 0 }, -// 2119 DOUBLE-STRUCK CAPITAL P -// 211a DOUBLE-STRUCK CAPITAL Q -// 211b SCRIPT CAPITAL R -// 211c BLACK-LETTER CAPITAL R -// 211d DOUBLE-STRUCK CAPITAL R - { 0x2119, 0x5, 0x89, 0, 0 }, -// 211e PRESCRIPTION TAKE -// 211f RESPONSE -// 2120 SERVICE MARK -// 2121 TELEPHONE SIGN -// 2122 TRADE MARK SIGN -// 2123 VERSICLE - { 0x211E, 0x6, 0x8, 0, 0 }, -// 2124 DOUBLE-STRUCK CAPITAL Z - { 0x2124, 0x1, 0x89, 0, 0 }, -// 2125 OUNCE SIGN - { 0x2125, 0x1, 0x8, 0, 0 }, -// 2126 OHM SIGN - { 0x2126, 0x1, 0x89, -7517, 0 }, -// 2127 INVERTED OHM SIGN - { 0x2127, 0x1, 0x8, 0, 0 }, -// 2128 BLACK-LETTER CAPITAL Z - { 0x2128, 0x1, 0x89, 0, 0 }, -// 2129 TURNED GREEK SMALL LETTER IOTA - { 0x2129, 0x1, 0x8, 0, 0 }, -// 212a KELVIN SIGN - { 0x212A, 0x1, 0x89, -8383, 0 }, -// 212b ANGSTROM SIGN - { 0x212B, 0x1, 0x89, -8262, 0 }, -// 212c SCRIPT CAPITAL B -// 212d BLACK-LETTER CAPITAL C - { 0x212C, 0x2, 0x89, 0, 0 }, -// 212e ESTIMATED SYMBOL - { 0x212E, 0x1, 0x8, 0, 0 }, -// 212f SCRIPT SMALL E - { 0x212F, 0x1, 0x49, 0, 0 }, -// 2130 SCRIPT CAPITAL E -// 2131 SCRIPT CAPITAL F - { 0x2130, 0x2, 0x89, 0, 0 }, -// 2132 TURNED CAPITAL F - { 0x2132, 0x1, 0x89, 28, 0 }, -// 2133 SCRIPT CAPITAL M - { 0x2133, 0x1, 0x89, 0, 0 }, -// 2134 SCRIPT SMALL O - { 0x2134, 0x1, 0x49, 0, 0 }, -// 2135 ALEF SYMBOL -// 2136 BET SYMBOL -// 2137 GIMEL SYMBOL -// 2138 DALET SYMBOL - { 0x2135, 0x4, 0x9, 0, 0 }, -// 2139 INFORMATION SOURCE - { 0x2139, 0x1, 0x49, 0, 0 }, -// 213a ROTATED CAPITAL Q -// 213b FACSIMILE SIGN - { 0x213A, 0x2, 0x8, 0, 0 }, -// 213c DOUBLE-STRUCK SMALL PI -// 213d DOUBLE-STRUCK SMALL GAMMA - { 0x213C, 0x2, 0x49, 0, 0 }, -// 213e DOUBLE-STRUCK CAPITAL GAMMA -// 213f DOUBLE-STRUCK CAPITAL PI - { 0x213E, 0x2, 0x89, 0, 0 }, -// 2140 DOUBLE-STRUCK N-ARY SUMMATION -// 2141 TURNED SANS-SERIF CAPITAL G -// 2142 TURNED SANS-SERIF CAPITAL L -// 2143 REVERSED SANS-SERIF CAPITAL L -// 2144 TURNED SANS-SERIF CAPITAL Y - { 0x2140, 0x5, 0x8, 0, 0 }, -// 2145 DOUBLE-STRUCK ITALIC CAPITAL D - { 0x2145, 0x1, 0x89, 0, 0 }, -// 2146 DOUBLE-STRUCK ITALIC SMALL D -// 2147 DOUBLE-STRUCK ITALIC SMALL E -// 2148 DOUBLE-STRUCK ITALIC SMALL I -// 2149 DOUBLE-STRUCK ITALIC SMALL J - { 0x2146, 0x4, 0x49, 0, 0 }, -// 214a PROPERTY LINE -// 214b TURNED AMPERSAND -// 214c PER SIGN -// 214d AKTIESELSKAB - { 0x214A, 0x4, 0x8, 0, 0 }, -// 214e TURNED SMALL F - { 0x214E, 0x1, 0x49, 0, -28 }, -// 214f SYMBOL FOR SAMARITAN SOURCE -// 2150 VULGAR FRACTION ONE SEVENTH -// 2151 VULGAR FRACTION ONE NINTH -// 2152 VULGAR FRACTION ONE TENTH -// 2153 VULGAR FRACTION ONE THIRD -// 2154 VULGAR FRACTION TWO THIRDS -// 2155 VULGAR FRACTION ONE FIFTH -// 2156 VULGAR FRACTION TWO FIFTHS -// 2157 VULGAR FRACTION THREE FIFTHS -// 2158 VULGAR FRACTION FOUR FIFTHS -// 2159 VULGAR FRACTION ONE SIXTH -// 215a VULGAR FRACTION FIVE SIXTHS -// 215b VULGAR FRACTION ONE EIGHTH -// 215c VULGAR FRACTION THREE EIGHTHS -// 215d VULGAR FRACTION FIVE EIGHTHS -// 215e VULGAR FRACTION SEVEN EIGHTHS -// 215f FRACTION NUMERATOR ONE - { 0x214F, 0x11, 0x8, 0, 0 }, -// 2160 ROMAN NUMERAL ONE -// 2161 ROMAN NUMERAL TWO -// 2162 ROMAN NUMERAL THREE -// 2163 ROMAN NUMERAL FOUR -// 2164 ROMAN NUMERAL FIVE -// 2165 ROMAN NUMERAL SIX -// 2166 ROMAN NUMERAL SEVEN -// 2167 ROMAN NUMERAL EIGHT -// 2168 ROMAN NUMERAL NINE -// 2169 ROMAN NUMERAL TEN -// 216a ROMAN NUMERAL ELEVEN -// 216b ROMAN NUMERAL TWELVE -// 216c ROMAN NUMERAL FIFTY -// 216d ROMAN NUMERAL ONE HUNDRED -// 216e ROMAN NUMERAL FIVE HUNDRED -// 216f ROMAN NUMERAL ONE THOUSAND - { 0x2160, 0x10, 0x8, 16, 0 }, -// 2170 SMALL ROMAN NUMERAL ONE -// 2171 SMALL ROMAN NUMERAL TWO -// 2172 SMALL ROMAN NUMERAL THREE -// 2173 SMALL ROMAN NUMERAL FOUR -// 2174 SMALL ROMAN NUMERAL FIVE -// 2175 SMALL ROMAN NUMERAL SIX -// 2176 SMALL ROMAN NUMERAL SEVEN -// 2177 SMALL ROMAN NUMERAL EIGHT -// 2178 SMALL ROMAN NUMERAL NINE -// 2179 SMALL ROMAN NUMERAL TEN -// 217a SMALL ROMAN NUMERAL ELEVEN -// 217b SMALL ROMAN NUMERAL TWELVE -// 217c SMALL ROMAN NUMERAL FIFTY -// 217d SMALL ROMAN NUMERAL ONE HUNDRED -// 217e SMALL ROMAN NUMERAL FIVE HUNDRED -// 217f SMALL ROMAN NUMERAL ONE THOUSAND - { 0x2170, 0x10, 0x8, 0, -16 }, -// 2180 ROMAN NUMERAL ONE THOUSAND C D -// 2181 ROMAN NUMERAL FIVE THOUSAND -// 2182 ROMAN NUMERAL TEN THOUSAND - { 0x2180, 0x3, 0x8, 0, 0 }, -// 2183 ROMAN NUMERAL REVERSED ONE HUNDRED - { 0x2183, 0x1, 0x89, 1, 0 }, -// 2184 LATIN SMALL LETTER REVERSED C - { 0x2184, 0x1, 0x49, 0, -1 }, -// 2185 ROMAN NUMERAL SIX LATE FORM -// 2186 ROMAN NUMERAL FIFTY EARLY FORM -// 2187 ROMAN NUMERAL FIFTY THOUSAND -// 2188 ROMAN NUMERAL ONE HUNDRED THOUSAND -// 2189 VULGAR FRACTION ZERO THIRDS - { 0x2185, 0x5, 0x8, 0, 0 }, -// 2190 LEFTWARDS ARROW -// 2191 UPWARDS ARROW -// 2192 RIGHTWARDS ARROW -// 2193 DOWNWARDS ARROW -// 2194 LEFT RIGHT ARROW -// 2195 UP DOWN ARROW -// 2196 NORTH WEST ARROW -// 2197 NORTH EAST ARROW -// 2198 SOUTH EAST ARROW -// 2199 SOUTH WEST ARROW -// 219a LEFTWARDS ARROW WITH STROKE -// 219b RIGHTWARDS ARROW WITH STROKE -// 219c LEFTWARDS WAVE ARROW -// 219d RIGHTWARDS WAVE ARROW -// 219e LEFTWARDS TWO HEADED ARROW -// 219f UPWARDS TWO HEADED ARROW -// 21a0 RIGHTWARDS TWO HEADED ARROW -// 21a1 DOWNWARDS TWO HEADED ARROW -// 21a2 LEFTWARDS ARROW WITH TAIL -// 21a3 RIGHTWARDS ARROW WITH TAIL -// 21a4 LEFTWARDS ARROW FROM BAR -// 21a5 UPWARDS ARROW FROM BAR -// 21a6 RIGHTWARDS ARROW FROM BAR -// 21a7 DOWNWARDS ARROW FROM BAR -// 21a8 UP DOWN ARROW WITH BASE -// 21a9 LEFTWARDS ARROW WITH HOOK -// 21aa RIGHTWARDS ARROW WITH HOOK -// 21ab LEFTWARDS ARROW WITH LOOP -// 21ac RIGHTWARDS ARROW WITH LOOP -// 21ad LEFT RIGHT WAVE ARROW -// 21ae LEFT RIGHT ARROW WITH STROKE -// 21af DOWNWARDS ZIGZAG ARROW -// 21b0 UPWARDS ARROW WITH TIP LEFTWARDS -// 21b1 UPWARDS ARROW WITH TIP RIGHTWARDS -// 21b2 DOWNWARDS ARROW WITH TIP LEFTWARDS -// 21b3 DOWNWARDS ARROW WITH TIP RIGHTWARDS -// 21b4 RIGHTWARDS ARROW WITH CORNER DOWNWARDS -// 21b5 DOWNWARDS ARROW WITH CORNER LEFTWARDS -// 21b6 ANTICLOCKWISE TOP SEMICIRCLE ARROW -// 21b7 CLOCKWISE TOP SEMICIRCLE ARROW -// 21b8 NORTH WEST ARROW TO LONG BAR -// 21b9 LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR -// 21ba ANTICLOCKWISE OPEN CIRCLE ARROW -// 21bb CLOCKWISE OPEN CIRCLE ARROW -// 21bc LEFTWARDS HARPOON WITH BARB UPWARDS -// 21bd LEFTWARDS HARPOON WITH BARB DOWNWARDS -// 21be UPWARDS HARPOON WITH BARB RIGHTWARDS -// 21bf UPWARDS HARPOON WITH BARB LEFTWARDS -// 21c0 RIGHTWARDS HARPOON WITH BARB UPWARDS -// 21c1 RIGHTWARDS HARPOON WITH BARB DOWNWARDS -// 21c2 DOWNWARDS HARPOON WITH BARB RIGHTWARDS -// 21c3 DOWNWARDS HARPOON WITH BARB LEFTWARDS -// 21c4 RIGHTWARDS ARROW OVER LEFTWARDS ARROW -// 21c5 UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW -// 21c6 LEFTWARDS ARROW OVER RIGHTWARDS ARROW -// 21c7 LEFTWARDS PAIRED ARROWS -// 21c8 UPWARDS PAIRED ARROWS -// 21c9 RIGHTWARDS PAIRED ARROWS -// 21ca DOWNWARDS PAIRED ARROWS -// 21cb LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON -// 21cc RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON -// 21cd LEFTWARDS DOUBLE ARROW WITH STROKE -// 21ce LEFT RIGHT DOUBLE ARROW WITH STROKE -// 21cf RIGHTWARDS DOUBLE ARROW WITH STROKE -// 21d0 LEFTWARDS DOUBLE ARROW -// 21d1 UPWARDS DOUBLE ARROW -// 21d2 RIGHTWARDS DOUBLE ARROW -// 21d3 DOWNWARDS DOUBLE ARROW -// 21d4 LEFT RIGHT DOUBLE ARROW -// 21d5 UP DOWN DOUBLE ARROW -// 21d6 NORTH WEST DOUBLE ARROW -// 21d7 NORTH EAST DOUBLE ARROW -// 21d8 SOUTH EAST DOUBLE ARROW -// 21d9 SOUTH WEST DOUBLE ARROW -// 21da LEFTWARDS TRIPLE ARROW -// 21db RIGHTWARDS TRIPLE ARROW -// 21dc LEFTWARDS SQUIGGLE ARROW -// 21dd RIGHTWARDS SQUIGGLE ARROW -// 21de UPWARDS ARROW WITH DOUBLE STROKE -// 21df DOWNWARDS ARROW WITH DOUBLE STROKE -// 21e0 LEFTWARDS DASHED ARROW -// 21e1 UPWARDS DASHED ARROW -// 21e2 RIGHTWARDS DASHED ARROW -// 21e3 DOWNWARDS DASHED ARROW -// 21e4 LEFTWARDS ARROW TO BAR -// 21e5 RIGHTWARDS ARROW TO BAR -// 21e6 LEFTWARDS WHITE ARROW -// 21e7 UPWARDS WHITE ARROW -// 21e8 RIGHTWARDS WHITE ARROW -// 21e9 DOWNWARDS WHITE ARROW -// 21ea UPWARDS WHITE ARROW FROM BAR -// 21eb UPWARDS WHITE ARROW ON PEDESTAL -// 21ec UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR -// 21ed UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR -// 21ee UPWARDS WHITE DOUBLE ARROW -// 21ef UPWARDS WHITE DOUBLE ARROW ON PEDESTAL -// 21f0 RIGHTWARDS WHITE ARROW FROM WALL -// 21f1 NORTH WEST ARROW TO CORNER -// 21f2 SOUTH EAST ARROW TO CORNER -// 21f3 UP DOWN WHITE ARROW -// 21f4 RIGHT ARROW WITH SMALL CIRCLE -// 21f5 DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW -// 21f6 THREE RIGHTWARDS ARROWS -// 21f7 LEFTWARDS ARROW WITH VERTICAL STROKE -// 21f8 RIGHTWARDS ARROW WITH VERTICAL STROKE -// 21f9 LEFT RIGHT ARROW WITH VERTICAL STROKE -// 21fa LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE -// 21fb RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE -// 21fc LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE -// 21fd LEFTWARDS OPEN-HEADED ARROW -// 21fe RIGHTWARDS OPEN-HEADED ARROW -// 21ff LEFT RIGHT OPEN-HEADED ARROW -// 2200 FOR ALL -// 2201 COMPLEMENT -// 2202 PARTIAL DIFFERENTIAL -// 2203 THERE EXISTS -// 2204 THERE DOES NOT EXIST -// 2205 EMPTY SET -// 2206 INCREMENT -// 2207 NABLA -// 2208 ELEMENT OF -// 2209 NOT AN ELEMENT OF -// 220a SMALL ELEMENT OF -// 220b CONTAINS AS MEMBER -// 220c DOES NOT CONTAIN AS MEMBER -// 220d SMALL CONTAINS AS MEMBER -// 220e END OF PROOF -// 220f N-ARY PRODUCT -// 2210 N-ARY COPRODUCT -// 2211 N-ARY SUMMATION -// 2212 MINUS SIGN -// 2213 MINUS-OR-PLUS SIGN -// 2214 DOT PLUS -// 2215 DIVISION SLASH -// 2216 SET MINUS -// 2217 ASTERISK OPERATOR -// 2218 RING OPERATOR -// 2219 BULLET OPERATOR -// 221a SQUARE ROOT -// 221b CUBE ROOT -// 221c FOURTH ROOT -// 221d PROPORTIONAL TO -// 221e INFINITY -// 221f RIGHT ANGLE -// 2220 ANGLE -// 2221 MEASURED ANGLE -// 2222 SPHERICAL ANGLE -// 2223 DIVIDES -// 2224 DOES NOT DIVIDE -// 2225 PARALLEL TO -// 2226 NOT PARALLEL TO -// 2227 LOGICAL AND -// 2228 LOGICAL OR -// 2229 INTERSECTION -// 222a UNION -// 222b INTEGRAL -// 222c DOUBLE INTEGRAL -// 222d TRIPLE INTEGRAL -// 222e CONTOUR INTEGRAL -// 222f SURFACE INTEGRAL -// 2230 VOLUME INTEGRAL -// 2231 CLOCKWISE INTEGRAL -// 2232 CLOCKWISE CONTOUR INTEGRAL -// 2233 ANTICLOCKWISE CONTOUR INTEGRAL -// 2234 THEREFORE -// 2235 BECAUSE -// 2236 RATIO -// 2237 PROPORTION -// 2238 DOT MINUS -// 2239 EXCESS -// 223a GEOMETRIC PROPORTION -// 223b HOMOTHETIC -// 223c TILDE OPERATOR -// 223d REVERSED TILDE -// 223e INVERTED LAZY S -// 223f SINE WAVE -// 2240 WREATH PRODUCT -// 2241 NOT TILDE -// 2242 MINUS TILDE -// 2243 ASYMPTOTICALLY EQUAL TO -// 2244 NOT ASYMPTOTICALLY EQUAL TO -// 2245 APPROXIMATELY EQUAL TO -// 2246 APPROXIMATELY BUT NOT ACTUALLY EQUAL TO -// 2247 NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO -// 2248 ALMOST EQUAL TO -// 2249 NOT ALMOST EQUAL TO -// 224a ALMOST EQUAL OR EQUAL TO -// 224b TRIPLE TILDE -// 224c ALL EQUAL TO -// 224d EQUIVALENT TO -// 224e GEOMETRICALLY EQUIVALENT TO -// 224f DIFFERENCE BETWEEN -// 2250 APPROACHES THE LIMIT -// 2251 GEOMETRICALLY EQUAL TO -// 2252 APPROXIMATELY EQUAL TO OR THE IMAGE OF -// 2253 IMAGE OF OR APPROXIMATELY EQUAL TO -// 2254 COLON EQUALS -// 2255 EQUALS COLON -// 2256 RING IN EQUAL TO -// 2257 RING EQUAL TO -// 2258 CORRESPONDS TO -// 2259 ESTIMATES -// 225a EQUIANGULAR TO -// 225b STAR EQUALS -// 225c DELTA EQUAL TO -// 225d EQUAL TO BY DEFINITION -// 225e MEASURED BY -// 225f QUESTIONED EQUAL TO -// 2260 NOT EQUAL TO -// 2261 IDENTICAL TO -// 2262 NOT IDENTICAL TO -// 2263 STRICTLY EQUIVALENT TO -// 2264 LESS-THAN OR EQUAL TO -// 2265 GREATER-THAN OR EQUAL TO -// 2266 LESS-THAN OVER EQUAL TO -// 2267 GREATER-THAN OVER EQUAL TO -// 2268 LESS-THAN BUT NOT EQUAL TO -// 2269 GREATER-THAN BUT NOT EQUAL TO -// 226a MUCH LESS-THAN -// 226b MUCH GREATER-THAN -// 226c BETWEEN -// 226d NOT EQUIVALENT TO -// 226e NOT LESS-THAN -// 226f NOT GREATER-THAN -// 2270 NEITHER LESS-THAN NOR EQUAL TO -// 2271 NEITHER GREATER-THAN NOR EQUAL TO -// 2272 LESS-THAN OR EQUIVALENT TO -// 2273 GREATER-THAN OR EQUIVALENT TO -// 2274 NEITHER LESS-THAN NOR EQUIVALENT TO -// 2275 NEITHER GREATER-THAN NOR EQUIVALENT TO -// 2276 LESS-THAN OR GREATER-THAN -// 2277 GREATER-THAN OR LESS-THAN -// 2278 NEITHER LESS-THAN NOR GREATER-THAN -// 2279 NEITHER GREATER-THAN NOR LESS-THAN -// 227a PRECEDES -// 227b SUCCEEDS -// 227c PRECEDES OR EQUAL TO -// 227d SUCCEEDS OR EQUAL TO -// 227e PRECEDES OR EQUIVALENT TO -// 227f SUCCEEDS OR EQUIVALENT TO -// 2280 DOES NOT PRECEDE -// 2281 DOES NOT SUCCEED -// 2282 SUBSET OF -// 2283 SUPERSET OF -// 2284 NOT A SUBSET OF -// 2285 NOT A SUPERSET OF -// 2286 SUBSET OF OR EQUAL TO -// 2287 SUPERSET OF OR EQUAL TO -// 2288 NEITHER A SUBSET OF NOR EQUAL TO -// 2289 NEITHER A SUPERSET OF NOR EQUAL TO -// 228a SUBSET OF WITH NOT EQUAL TO -// 228b SUPERSET OF WITH NOT EQUAL TO -// 228c MULTISET -// 228d MULTISET MULTIPLICATION -// 228e MULTISET UNION -// 228f SQUARE IMAGE OF -// 2290 SQUARE ORIGINAL OF -// 2291 SQUARE IMAGE OF OR EQUAL TO -// 2292 SQUARE ORIGINAL OF OR EQUAL TO -// 2293 SQUARE CAP -// 2294 SQUARE CUP -// 2295 CIRCLED PLUS -// 2296 CIRCLED MINUS -// 2297 CIRCLED TIMES -// 2298 CIRCLED DIVISION SLASH -// 2299 CIRCLED DOT OPERATOR -// 229a CIRCLED RING OPERATOR -// 229b CIRCLED ASTERISK OPERATOR -// 229c CIRCLED EQUALS -// 229d CIRCLED DASH -// 229e SQUARED PLUS -// 229f SQUARED MINUS -// 22a0 SQUARED TIMES -// 22a1 SQUARED DOT OPERATOR -// 22a2 RIGHT TACK -// 22a3 LEFT TACK -// 22a4 DOWN TACK -// 22a5 UP TACK -// 22a6 ASSERTION -// 22a7 MODELS -// 22a8 TRUE -// 22a9 FORCES -// 22aa TRIPLE VERTICAL BAR RIGHT TURNSTILE -// 22ab DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE -// 22ac DOES NOT PROVE -// 22ad NOT TRUE -// 22ae DOES NOT FORCE -// 22af NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE -// 22b0 PRECEDES UNDER RELATION -// 22b1 SUCCEEDS UNDER RELATION -// 22b2 NORMAL SUBGROUP OF -// 22b3 CONTAINS AS NORMAL SUBGROUP -// 22b4 NORMAL SUBGROUP OF OR EQUAL TO -// 22b5 CONTAINS AS NORMAL SUBGROUP OR EQUAL TO -// 22b6 ORIGINAL OF -// 22b7 IMAGE OF -// 22b8 MULTIMAP -// 22b9 HERMITIAN CONJUGATE MATRIX -// 22ba INTERCALATE -// 22bb XOR -// 22bc NAND -// 22bd NOR -// 22be RIGHT ANGLE WITH ARC -// 22bf RIGHT TRIANGLE -// 22c0 N-ARY LOGICAL AND -// 22c1 N-ARY LOGICAL OR -// 22c2 N-ARY INTERSECTION -// 22c3 N-ARY UNION -// 22c4 DIAMOND OPERATOR -// 22c5 DOT OPERATOR -// 22c6 STAR OPERATOR -// 22c7 DIVISION TIMES -// 22c8 BOWTIE -// 22c9 LEFT NORMAL FACTOR SEMIDIRECT PRODUCT -// 22ca RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT -// 22cb LEFT SEMIDIRECT PRODUCT -// 22cc RIGHT SEMIDIRECT PRODUCT -// 22cd REVERSED TILDE EQUALS -// 22ce CURLY LOGICAL OR -// 22cf CURLY LOGICAL AND -// 22d0 DOUBLE SUBSET -// 22d1 DOUBLE SUPERSET -// 22d2 DOUBLE INTERSECTION -// 22d3 DOUBLE UNION -// 22d4 PITCHFORK -// 22d5 EQUAL AND PARALLEL TO -// 22d6 LESS-THAN WITH DOT -// 22d7 GREATER-THAN WITH DOT -// 22d8 VERY MUCH LESS-THAN -// 22d9 VERY MUCH GREATER-THAN -// 22da LESS-THAN EQUAL TO OR GREATER-THAN -// 22db GREATER-THAN EQUAL TO OR LESS-THAN -// 22dc EQUAL TO OR LESS-THAN -// 22dd EQUAL TO OR GREATER-THAN -// 22de EQUAL TO OR PRECEDES -// 22df EQUAL TO OR SUCCEEDS -// 22e0 DOES NOT PRECEDE OR EQUAL -// 22e1 DOES NOT SUCCEED OR EQUAL -// 22e2 NOT SQUARE IMAGE OF OR EQUAL TO -// 22e3 NOT SQUARE ORIGINAL OF OR EQUAL TO -// 22e4 SQUARE IMAGE OF OR NOT EQUAL TO -// 22e5 SQUARE ORIGINAL OF OR NOT EQUAL TO -// 22e6 LESS-THAN BUT NOT EQUIVALENT TO -// 22e7 GREATER-THAN BUT NOT EQUIVALENT TO -// 22e8 PRECEDES BUT NOT EQUIVALENT TO -// 22e9 SUCCEEDS BUT NOT EQUIVALENT TO -// 22ea NOT NORMAL SUBGROUP OF -// 22eb DOES NOT CONTAIN AS NORMAL SUBGROUP -// 22ec NOT NORMAL SUBGROUP OF OR EQUAL TO -// 22ed DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL -// 22ee VERTICAL ELLIPSIS -// 22ef MIDLINE HORIZONTAL ELLIPSIS -// 22f0 UP RIGHT DIAGONAL ELLIPSIS -// 22f1 DOWN RIGHT DIAGONAL ELLIPSIS -// 22f2 ELEMENT OF WITH LONG HORIZONTAL STROKE -// 22f3 ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE -// 22f4 SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE -// 22f5 ELEMENT OF WITH DOT ABOVE -// 22f6 ELEMENT OF WITH OVERBAR -// 22f7 SMALL ELEMENT OF WITH OVERBAR -// 22f8 ELEMENT OF WITH UNDERBAR -// 22f9 ELEMENT OF WITH TWO HORIZONTAL STROKES -// 22fa CONTAINS WITH LONG HORIZONTAL STROKE -// 22fb CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE -// 22fc SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE -// 22fd CONTAINS WITH OVERBAR -// 22fe SMALL CONTAINS WITH OVERBAR -// 22ff Z NOTATION BAG MEMBERSHIP -// 2300 DIAMETER SIGN -// 2301 ELECTRIC ARROW -// 2302 HOUSE -// 2303 UP ARROWHEAD -// 2304 DOWN ARROWHEAD -// 2305 PROJECTIVE -// 2306 PERSPECTIVE -// 2307 WAVY LINE - { 0x2190, 0x178, 0x8, 0, 0 }, -// 2308 LEFT CEILING -// 2309 RIGHT CEILING -// 230a LEFT FLOOR -// 230b RIGHT FLOOR - { 0x2308, 0x4, 0x18, 0, 0 }, -// 230c BOTTOM RIGHT CROP -// 230d BOTTOM LEFT CROP -// 230e TOP RIGHT CROP -// 230f TOP LEFT CROP -// 2310 REVERSED NOT SIGN -// 2311 SQUARE LOZENGE -// 2312 ARC -// 2313 SEGMENT -// 2314 SECTOR -// 2315 TELEPHONE RECORDER -// 2316 POSITION INDICATOR -// 2317 VIEWDATA SQUARE -// 2318 PLACE OF INTEREST SIGN -// 2319 TURNED NOT SIGN -// 231a WATCH -// 231b HOURGLASS -// 231c TOP LEFT CORNER -// 231d TOP RIGHT CORNER -// 231e BOTTOM LEFT CORNER -// 231f BOTTOM RIGHT CORNER -// 2320 TOP HALF INTEGRAL -// 2321 BOTTOM HALF INTEGRAL -// 2322 FROWN -// 2323 SMILE -// 2324 UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS -// 2325 OPTION KEY -// 2326 ERASE TO THE RIGHT -// 2327 X IN A RECTANGLE BOX -// 2328 KEYBOARD - { 0x230C, 0x1D, 0x8, 0, 0 }, -// 2329 LEFT-POINTING ANGLE BRACKET -// 232a RIGHT-POINTING ANGLE BRACKET - { 0x2329, 0x2, 0x18, 0, 0 }, -// 232b ERASE TO THE LEFT -// 232c BENZENE RING -// 232d CYLINDRICITY -// 232e ALL AROUND-PROFILE -// 232f SYMMETRY -// 2330 TOTAL RUNOUT -// 2331 DIMENSION ORIGIN -// 2332 CONICAL TAPER -// 2333 SLOPE -// 2334 COUNTERBORE -// 2335 COUNTERSINK -// 2336 APL FUNCTIONAL SYMBOL I-BEAM -// 2337 APL FUNCTIONAL SYMBOL SQUISH QUAD -// 2338 APL FUNCTIONAL SYMBOL QUAD EQUAL -// 2339 APL FUNCTIONAL SYMBOL QUAD DIVIDE -// 233a APL FUNCTIONAL SYMBOL QUAD DIAMOND -// 233b APL FUNCTIONAL SYMBOL QUAD JOT -// 233c APL FUNCTIONAL SYMBOL QUAD CIRCLE -// 233d APL FUNCTIONAL SYMBOL CIRCLE STILE -// 233e APL FUNCTIONAL SYMBOL CIRCLE JOT -// 233f APL FUNCTIONAL SYMBOL SLASH BAR -// 2340 APL FUNCTIONAL SYMBOL BACKSLASH BAR -// 2341 APL FUNCTIONAL SYMBOL QUAD SLASH -// 2342 APL FUNCTIONAL SYMBOL QUAD BACKSLASH -// 2343 APL FUNCTIONAL SYMBOL QUAD LESS-THAN -// 2344 APL FUNCTIONAL SYMBOL QUAD GREATER-THAN -// 2345 APL FUNCTIONAL SYMBOL LEFTWARDS VANE -// 2346 APL FUNCTIONAL SYMBOL RIGHTWARDS VANE -// 2347 APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW -// 2348 APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW -// 2349 APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH -// 234a APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR -// 234b APL FUNCTIONAL SYMBOL DELTA STILE -// 234c APL FUNCTIONAL SYMBOL QUAD DOWN CARET -// 234d APL FUNCTIONAL SYMBOL QUAD DELTA -// 234e APL FUNCTIONAL SYMBOL DOWN TACK JOT -// 234f APL FUNCTIONAL SYMBOL UPWARDS VANE -// 2350 APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW -// 2351 APL FUNCTIONAL SYMBOL UP TACK OVERBAR -// 2352 APL FUNCTIONAL SYMBOL DEL STILE -// 2353 APL FUNCTIONAL SYMBOL QUAD UP CARET -// 2354 APL FUNCTIONAL SYMBOL QUAD DEL -// 2355 APL FUNCTIONAL SYMBOL UP TACK JOT -// 2356 APL FUNCTIONAL SYMBOL DOWNWARDS VANE -// 2357 APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW -// 2358 APL FUNCTIONAL SYMBOL QUOTE UNDERBAR -// 2359 APL FUNCTIONAL SYMBOL DELTA UNDERBAR -// 235a APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR -// 235b APL FUNCTIONAL SYMBOL JOT UNDERBAR -// 235c APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR -// 235d APL FUNCTIONAL SYMBOL UP SHOE JOT -// 235e APL FUNCTIONAL SYMBOL QUOTE QUAD -// 235f APL FUNCTIONAL SYMBOL CIRCLE STAR -// 2360 APL FUNCTIONAL SYMBOL QUAD COLON -// 2361 APL FUNCTIONAL SYMBOL UP TACK DIAERESIS -// 2362 APL FUNCTIONAL SYMBOL DEL DIAERESIS -// 2363 APL FUNCTIONAL SYMBOL STAR DIAERESIS -// 2364 APL FUNCTIONAL SYMBOL JOT DIAERESIS -// 2365 APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS -// 2366 APL FUNCTIONAL SYMBOL DOWN SHOE STILE -// 2367 APL FUNCTIONAL SYMBOL LEFT SHOE STILE -// 2368 APL FUNCTIONAL SYMBOL TILDE DIAERESIS -// 2369 APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS -// 236a APL FUNCTIONAL SYMBOL COMMA BAR -// 236b APL FUNCTIONAL SYMBOL DEL TILDE -// 236c APL FUNCTIONAL SYMBOL ZILDE -// 236d APL FUNCTIONAL SYMBOL STILE TILDE -// 236e APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR -// 236f APL FUNCTIONAL SYMBOL QUAD NOT EQUAL -// 2370 APL FUNCTIONAL SYMBOL QUAD QUESTION -// 2371 APL FUNCTIONAL SYMBOL DOWN CARET TILDE -// 2372 APL FUNCTIONAL SYMBOL UP CARET TILDE -// 2373 APL FUNCTIONAL SYMBOL IOTA -// 2374 APL FUNCTIONAL SYMBOL RHO -// 2375 APL FUNCTIONAL SYMBOL OMEGA -// 2376 APL FUNCTIONAL SYMBOL ALPHA UNDERBAR -// 2377 APL FUNCTIONAL SYMBOL EPSILON UNDERBAR -// 2378 APL FUNCTIONAL SYMBOL IOTA UNDERBAR -// 2379 APL FUNCTIONAL SYMBOL OMEGA UNDERBAR -// 237a APL FUNCTIONAL SYMBOL ALPHA -// 237b NOT CHECK MARK -// 237c RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW -// 237d SHOULDERED OPEN BOX -// 237e BELL SYMBOL -// 237f VERTICAL LINE WITH MIDDLE DOT -// 2380 INSERTION SYMBOL -// 2381 CONTINUOUS UNDERLINE SYMBOL -// 2382 DISCONTINUOUS UNDERLINE SYMBOL -// 2383 EMPHASIS SYMBOL -// 2384 COMPOSITION SYMBOL -// 2385 WHITE SQUARE WITH CENTRE VERTICAL LINE -// 2386 ENTER SYMBOL -// 2387 ALTERNATIVE KEY SYMBOL -// 2388 HELM SYMBOL -// 2389 CIRCLED HORIZONTAL BAR WITH NOTCH -// 238a CIRCLED TRIANGLE DOWN -// 238b BROKEN CIRCLE WITH NORTHWEST ARROW -// 238c UNDO SYMBOL -// 238d MONOSTABLE SYMBOL -// 238e HYSTERESIS SYMBOL -// 238f OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL -// 2390 OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL -// 2391 PASSIVE-PULL-DOWN-OUTPUT SYMBOL -// 2392 PASSIVE-PULL-UP-OUTPUT SYMBOL -// 2393 DIRECT CURRENT SYMBOL FORM TWO -// 2394 SOFTWARE-FUNCTION SYMBOL -// 2395 APL FUNCTIONAL SYMBOL QUAD -// 2396 DECIMAL SEPARATOR KEY SYMBOL -// 2397 PREVIOUS PAGE -// 2398 NEXT PAGE -// 2399 PRINT SCREEN SYMBOL -// 239a CLEAR SCREEN SYMBOL -// 239b LEFT PARENTHESIS UPPER HOOK -// 239c LEFT PARENTHESIS EXTENSION -// 239d LEFT PARENTHESIS LOWER HOOK -// 239e RIGHT PARENTHESIS UPPER HOOK -// 239f RIGHT PARENTHESIS EXTENSION -// 23a0 RIGHT PARENTHESIS LOWER HOOK -// 23a1 LEFT SQUARE BRACKET UPPER CORNER -// 23a2 LEFT SQUARE BRACKET EXTENSION -// 23a3 LEFT SQUARE BRACKET LOWER CORNER -// 23a4 RIGHT SQUARE BRACKET UPPER CORNER -// 23a5 RIGHT SQUARE BRACKET EXTENSION -// 23a6 RIGHT SQUARE BRACKET LOWER CORNER -// 23a7 LEFT CURLY BRACKET UPPER HOOK -// 23a8 LEFT CURLY BRACKET MIDDLE PIECE -// 23a9 LEFT CURLY BRACKET LOWER HOOK -// 23aa CURLY BRACKET EXTENSION -// 23ab RIGHT CURLY BRACKET UPPER HOOK -// 23ac RIGHT CURLY BRACKET MIDDLE PIECE -// 23ad RIGHT CURLY BRACKET LOWER HOOK -// 23ae INTEGRAL EXTENSION -// 23af HORIZONTAL LINE EXTENSION -// 23b0 UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION -// 23b1 UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION -// 23b2 SUMMATION TOP -// 23b3 SUMMATION BOTTOM -// 23b4 TOP SQUARE BRACKET -// 23b5 BOTTOM SQUARE BRACKET -// 23b6 BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET -// 23b7 RADICAL SYMBOL BOTTOM -// 23b8 LEFT VERTICAL BOX LINE -// 23b9 RIGHT VERTICAL BOX LINE -// 23ba HORIZONTAL SCAN LINE-1 -// 23bb HORIZONTAL SCAN LINE-3 -// 23bc HORIZONTAL SCAN LINE-7 -// 23bd HORIZONTAL SCAN LINE-9 -// 23be DENTISTRY SYMBOL LIGHT VERTICAL AND TOP RIGHT -// 23bf DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM RIGHT -// 23c0 DENTISTRY SYMBOL LIGHT VERTICAL WITH CIRCLE -// 23c1 DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH CIRCLE -// 23c2 DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH CIRCLE -// 23c3 DENTISTRY SYMBOL LIGHT VERTICAL WITH TRIANGLE -// 23c4 DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH TRIANGLE -// 23c5 DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH TRIANGLE -// 23c6 DENTISTRY SYMBOL LIGHT VERTICAL AND WAVE -// 23c7 DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH WAVE -// 23c8 DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH WAVE -// 23c9 DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL -// 23ca DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL -// 23cb DENTISTRY SYMBOL LIGHT VERTICAL AND TOP LEFT -// 23cc DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM LEFT -// 23cd SQUARE FOOT -// 23ce RETURN SYMBOL -// 23cf EJECT SYMBOL -// 23d0 VERTICAL LINE EXTENSION -// 23d1 METRICAL BREVE -// 23d2 METRICAL LONG OVER SHORT -// 23d3 METRICAL SHORT OVER LONG -// 23d4 METRICAL LONG OVER TWO SHORTS -// 23d5 METRICAL TWO SHORTS OVER LONG -// 23d6 METRICAL TWO SHORTS JOINED -// 23d7 METRICAL TRISEME -// 23d8 METRICAL TETRASEME -// 23d9 METRICAL PENTASEME -// 23da EARTH GROUND -// 23db FUSE -// 23dc TOP PARENTHESIS -// 23dd BOTTOM PARENTHESIS -// 23de TOP CURLY BRACKET -// 23df BOTTOM CURLY BRACKET -// 23e0 TOP TORTOISE SHELL BRACKET -// 23e1 BOTTOM TORTOISE SHELL BRACKET -// 23e2 WHITE TRAPEZIUM -// 23e3 BENZENE RING WITH CIRCLE -// 23e4 STRAIGHTNESS -// 23e5 FLATNESS -// 23e6 AC CURRENT -// 23e7 ELECTRICAL INTERSECTION -// 23e8 DECIMAL EXPONENT SYMBOL -// 23e9 BLACK RIGHT-POINTING DOUBLE TRIANGLE -// 23ea BLACK LEFT-POINTING DOUBLE TRIANGLE -// 23eb BLACK UP-POINTING DOUBLE TRIANGLE -// 23ec BLACK DOWN-POINTING DOUBLE TRIANGLE -// 23ed BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR -// 23ee BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR -// 23ef BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR -// 23f0 ALARM CLOCK -// 23f1 STOPWATCH -// 23f2 TIMER CLOCK -// 23f3 HOURGLASS WITH FLOWING SAND -// 23f4 BLACK MEDIUM LEFT-POINTING TRIANGLE -// 23f5 BLACK MEDIUM RIGHT-POINTING TRIANGLE -// 23f6 BLACK MEDIUM UP-POINTING TRIANGLE -// 23f7 BLACK MEDIUM DOWN-POINTING TRIANGLE -// 23f8 DOUBLE VERTICAL BAR -// 23f9 BLACK SQUARE FOR STOP -// 23fa BLACK CIRCLE FOR RECORD - { 0x232B, 0xD0, 0x8, 0, 0 }, -// 2400 SYMBOL FOR NULL -// 2401 SYMBOL FOR START OF HEADING -// 2402 SYMBOL FOR START OF TEXT -// 2403 SYMBOL FOR END OF TEXT -// 2404 SYMBOL FOR END OF TRANSMISSION -// 2405 SYMBOL FOR ENQUIRY -// 2406 SYMBOL FOR ACKNOWLEDGE -// 2407 SYMBOL FOR BELL -// 2408 SYMBOL FOR BACKSPACE -// 2409 SYMBOL FOR HORIZONTAL TABULATION -// 240a SYMBOL FOR LINE FEED -// 240b SYMBOL FOR VERTICAL TABULATION -// 240c SYMBOL FOR FORM FEED -// 240d SYMBOL FOR CARRIAGE RETURN -// 240e SYMBOL FOR SHIFT OUT -// 240f SYMBOL FOR SHIFT IN -// 2410 SYMBOL FOR DATA LINK ESCAPE -// 2411 SYMBOL FOR DEVICE CONTROL ONE -// 2412 SYMBOL FOR DEVICE CONTROL TWO -// 2413 SYMBOL FOR DEVICE CONTROL THREE -// 2414 SYMBOL FOR DEVICE CONTROL FOUR -// 2415 SYMBOL FOR NEGATIVE ACKNOWLEDGE -// 2416 SYMBOL FOR SYNCHRONOUS IDLE -// 2417 SYMBOL FOR END OF TRANSMISSION BLOCK -// 2418 SYMBOL FOR CANCEL -// 2419 SYMBOL FOR END OF MEDIUM -// 241a SYMBOL FOR SUBSTITUTE -// 241b SYMBOL FOR ESCAPE -// 241c SYMBOL FOR FILE SEPARATOR -// 241d SYMBOL FOR GROUP SEPARATOR -// 241e SYMBOL FOR RECORD SEPARATOR -// 241f SYMBOL FOR UNIT SEPARATOR -// 2420 SYMBOL FOR SPACE -// 2421 SYMBOL FOR DELETE -// 2422 BLANK SYMBOL -// 2423 OPEN BOX -// 2424 SYMBOL FOR NEWLINE -// 2425 SYMBOL FOR DELETE FORM TWO -// 2426 SYMBOL FOR SUBSTITUTE FORM TWO - { 0x2400, 0x27, 0x8, 0, 0 }, -// 2440 OCR HOOK -// 2441 OCR CHAIR -// 2442 OCR FORK -// 2443 OCR INVERTED FORK -// 2444 OCR BELT BUCKLE -// 2445 OCR BOW TIE -// 2446 OCR BRANCH BANK IDENTIFICATION -// 2447 OCR AMOUNT OF CHECK -// 2448 OCR DASH -// 2449 OCR CUSTOMER ACCOUNT NUMBER -// 244a OCR DOUBLE BACKSLASH - { 0x2440, 0xB, 0x8, 0, 0 }, -// 2460 CIRCLED DIGIT ONE -// 2461 CIRCLED DIGIT TWO -// 2462 CIRCLED DIGIT THREE -// 2463 CIRCLED DIGIT FOUR -// 2464 CIRCLED DIGIT FIVE -// 2465 CIRCLED DIGIT SIX -// 2466 CIRCLED DIGIT SEVEN -// 2467 CIRCLED DIGIT EIGHT -// 2468 CIRCLED DIGIT NINE -// 2469 CIRCLED NUMBER TEN -// 246a CIRCLED NUMBER ELEVEN -// 246b CIRCLED NUMBER TWELVE -// 246c CIRCLED NUMBER THIRTEEN -// 246d CIRCLED NUMBER FOURTEEN -// 246e CIRCLED NUMBER FIFTEEN -// 246f CIRCLED NUMBER SIXTEEN -// 2470 CIRCLED NUMBER SEVENTEEN -// 2471 CIRCLED NUMBER EIGHTEEN -// 2472 CIRCLED NUMBER NINETEEN -// 2473 CIRCLED NUMBER TWENTY -// 2474 PARENTHESIZED DIGIT ONE -// 2475 PARENTHESIZED DIGIT TWO -// 2476 PARENTHESIZED DIGIT THREE -// 2477 PARENTHESIZED DIGIT FOUR -// 2478 PARENTHESIZED DIGIT FIVE -// 2479 PARENTHESIZED DIGIT SIX -// 247a PARENTHESIZED DIGIT SEVEN -// 247b PARENTHESIZED DIGIT EIGHT -// 247c PARENTHESIZED DIGIT NINE -// 247d PARENTHESIZED NUMBER TEN -// 247e PARENTHESIZED NUMBER ELEVEN -// 247f PARENTHESIZED NUMBER TWELVE -// 2480 PARENTHESIZED NUMBER THIRTEEN -// 2481 PARENTHESIZED NUMBER FOURTEEN -// 2482 PARENTHESIZED NUMBER FIFTEEN -// 2483 PARENTHESIZED NUMBER SIXTEEN -// 2484 PARENTHESIZED NUMBER SEVENTEEN -// 2485 PARENTHESIZED NUMBER EIGHTEEN -// 2486 PARENTHESIZED NUMBER NINETEEN -// 2487 PARENTHESIZED NUMBER TWENTY -// 2488 DIGIT ONE FULL STOP -// 2489 DIGIT TWO FULL STOP -// 248a DIGIT THREE FULL STOP -// 248b DIGIT FOUR FULL STOP -// 248c DIGIT FIVE FULL STOP -// 248d DIGIT SIX FULL STOP -// 248e DIGIT SEVEN FULL STOP -// 248f DIGIT EIGHT FULL STOP -// 2490 DIGIT NINE FULL STOP -// 2491 NUMBER TEN FULL STOP -// 2492 NUMBER ELEVEN FULL STOP -// 2493 NUMBER TWELVE FULL STOP -// 2494 NUMBER THIRTEEN FULL STOP -// 2495 NUMBER FOURTEEN FULL STOP -// 2496 NUMBER FIFTEEN FULL STOP -// 2497 NUMBER SIXTEEN FULL STOP -// 2498 NUMBER SEVENTEEN FULL STOP -// 2499 NUMBER EIGHTEEN FULL STOP -// 249a NUMBER NINETEEN FULL STOP -// 249b NUMBER TWENTY FULL STOP -// 249c PARENTHESIZED LATIN SMALL LETTER A -// 249d PARENTHESIZED LATIN SMALL LETTER B -// 249e PARENTHESIZED LATIN SMALL LETTER C -// 249f PARENTHESIZED LATIN SMALL LETTER D -// 24a0 PARENTHESIZED LATIN SMALL LETTER E -// 24a1 PARENTHESIZED LATIN SMALL LETTER F -// 24a2 PARENTHESIZED LATIN SMALL LETTER G -// 24a3 PARENTHESIZED LATIN SMALL LETTER H -// 24a4 PARENTHESIZED LATIN SMALL LETTER I -// 24a5 PARENTHESIZED LATIN SMALL LETTER J -// 24a6 PARENTHESIZED LATIN SMALL LETTER K -// 24a7 PARENTHESIZED LATIN SMALL LETTER L -// 24a8 PARENTHESIZED LATIN SMALL LETTER M -// 24a9 PARENTHESIZED LATIN SMALL LETTER N -// 24aa PARENTHESIZED LATIN SMALL LETTER O -// 24ab PARENTHESIZED LATIN SMALL LETTER P -// 24ac PARENTHESIZED LATIN SMALL LETTER Q -// 24ad PARENTHESIZED LATIN SMALL LETTER R -// 24ae PARENTHESIZED LATIN SMALL LETTER S -// 24af PARENTHESIZED LATIN SMALL LETTER T -// 24b0 PARENTHESIZED LATIN SMALL LETTER U -// 24b1 PARENTHESIZED LATIN SMALL LETTER V -// 24b2 PARENTHESIZED LATIN SMALL LETTER W -// 24b3 PARENTHESIZED LATIN SMALL LETTER X -// 24b4 PARENTHESIZED LATIN SMALL LETTER Y -// 24b5 PARENTHESIZED LATIN SMALL LETTER Z - { 0x2460, 0x56, 0x8, 0, 0 }, -// 24b6 CIRCLED LATIN CAPITAL LETTER A -// 24b7 CIRCLED LATIN CAPITAL LETTER B -// 24b8 CIRCLED LATIN CAPITAL LETTER C -// 24b9 CIRCLED LATIN CAPITAL LETTER D -// 24ba CIRCLED LATIN CAPITAL LETTER E -// 24bb CIRCLED LATIN CAPITAL LETTER F -// 24bc CIRCLED LATIN CAPITAL LETTER G -// 24bd CIRCLED LATIN CAPITAL LETTER H -// 24be CIRCLED LATIN CAPITAL LETTER I -// 24bf CIRCLED LATIN CAPITAL LETTER J -// 24c0 CIRCLED LATIN CAPITAL LETTER K -// 24c1 CIRCLED LATIN CAPITAL LETTER L -// 24c2 CIRCLED LATIN CAPITAL LETTER M -// 24c3 CIRCLED LATIN CAPITAL LETTER N -// 24c4 CIRCLED LATIN CAPITAL LETTER O -// 24c5 CIRCLED LATIN CAPITAL LETTER P -// 24c6 CIRCLED LATIN CAPITAL LETTER Q -// 24c7 CIRCLED LATIN CAPITAL LETTER R -// 24c8 CIRCLED LATIN CAPITAL LETTER S -// 24c9 CIRCLED LATIN CAPITAL LETTER T -// 24ca CIRCLED LATIN CAPITAL LETTER U -// 24cb CIRCLED LATIN CAPITAL LETTER V -// 24cc CIRCLED LATIN CAPITAL LETTER W -// 24cd CIRCLED LATIN CAPITAL LETTER X -// 24ce CIRCLED LATIN CAPITAL LETTER Y -// 24cf CIRCLED LATIN CAPITAL LETTER Z - { 0x24B6, 0x1A, 0x8, 26, 0 }, -// 24d0 CIRCLED LATIN SMALL LETTER A -// 24d1 CIRCLED LATIN SMALL LETTER B -// 24d2 CIRCLED LATIN SMALL LETTER C -// 24d3 CIRCLED LATIN SMALL LETTER D -// 24d4 CIRCLED LATIN SMALL LETTER E -// 24d5 CIRCLED LATIN SMALL LETTER F -// 24d6 CIRCLED LATIN SMALL LETTER G -// 24d7 CIRCLED LATIN SMALL LETTER H -// 24d8 CIRCLED LATIN SMALL LETTER I -// 24d9 CIRCLED LATIN SMALL LETTER J -// 24da CIRCLED LATIN SMALL LETTER K -// 24db CIRCLED LATIN SMALL LETTER L -// 24dc CIRCLED LATIN SMALL LETTER M -// 24dd CIRCLED LATIN SMALL LETTER N -// 24de CIRCLED LATIN SMALL LETTER O -// 24df CIRCLED LATIN SMALL LETTER P -// 24e0 CIRCLED LATIN SMALL LETTER Q -// 24e1 CIRCLED LATIN SMALL LETTER R -// 24e2 CIRCLED LATIN SMALL LETTER S -// 24e3 CIRCLED LATIN SMALL LETTER T -// 24e4 CIRCLED LATIN SMALL LETTER U -// 24e5 CIRCLED LATIN SMALL LETTER V -// 24e6 CIRCLED LATIN SMALL LETTER W -// 24e7 CIRCLED LATIN SMALL LETTER X -// 24e8 CIRCLED LATIN SMALL LETTER Y -// 24e9 CIRCLED LATIN SMALL LETTER Z - { 0x24D0, 0x1A, 0x8, 0, -26 }, -// 24ea CIRCLED DIGIT ZERO -// 24eb NEGATIVE CIRCLED NUMBER ELEVEN -// 24ec NEGATIVE CIRCLED NUMBER TWELVE -// 24ed NEGATIVE CIRCLED NUMBER THIRTEEN -// 24ee NEGATIVE CIRCLED NUMBER FOURTEEN -// 24ef NEGATIVE CIRCLED NUMBER FIFTEEN -// 24f0 NEGATIVE CIRCLED NUMBER SIXTEEN -// 24f1 NEGATIVE CIRCLED NUMBER SEVENTEEN -// 24f2 NEGATIVE CIRCLED NUMBER EIGHTEEN -// 24f3 NEGATIVE CIRCLED NUMBER NINETEEN -// 24f4 NEGATIVE CIRCLED NUMBER TWENTY -// 24f5 DOUBLE CIRCLED DIGIT ONE -// 24f6 DOUBLE CIRCLED DIGIT TWO -// 24f7 DOUBLE CIRCLED DIGIT THREE -// 24f8 DOUBLE CIRCLED DIGIT FOUR -// 24f9 DOUBLE CIRCLED DIGIT FIVE -// 24fa DOUBLE CIRCLED DIGIT SIX -// 24fb DOUBLE CIRCLED DIGIT SEVEN -// 24fc DOUBLE CIRCLED DIGIT EIGHT -// 24fd DOUBLE CIRCLED DIGIT NINE -// 24fe DOUBLE CIRCLED NUMBER TEN -// 24ff NEGATIVE CIRCLED DIGIT ZERO -// 2500 BOX DRAWINGS LIGHT HORIZONTAL -// 2501 BOX DRAWINGS HEAVY HORIZONTAL -// 2502 BOX DRAWINGS LIGHT VERTICAL -// 2503 BOX DRAWINGS HEAVY VERTICAL -// 2504 BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL -// 2505 BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL -// 2506 BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL -// 2507 BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL -// 2508 BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL -// 2509 BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL -// 250a BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL -// 250b BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL -// 250c BOX DRAWINGS LIGHT DOWN AND RIGHT -// 250d BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY -// 250e BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT -// 250f BOX DRAWINGS HEAVY DOWN AND RIGHT -// 2510 BOX DRAWINGS LIGHT DOWN AND LEFT -// 2511 BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY -// 2512 BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT -// 2513 BOX DRAWINGS HEAVY DOWN AND LEFT -// 2514 BOX DRAWINGS LIGHT UP AND RIGHT -// 2515 BOX DRAWINGS UP LIGHT AND RIGHT HEAVY -// 2516 BOX DRAWINGS UP HEAVY AND RIGHT LIGHT -// 2517 BOX DRAWINGS HEAVY UP AND RIGHT -// 2518 BOX DRAWINGS LIGHT UP AND LEFT -// 2519 BOX DRAWINGS UP LIGHT AND LEFT HEAVY -// 251a BOX DRAWINGS UP HEAVY AND LEFT LIGHT -// 251b BOX DRAWINGS HEAVY UP AND LEFT -// 251c BOX DRAWINGS LIGHT VERTICAL AND RIGHT -// 251d BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY -// 251e BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT -// 251f BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT -// 2520 BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT -// 2521 BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY -// 2522 BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY -// 2523 BOX DRAWINGS HEAVY VERTICAL AND RIGHT -// 2524 BOX DRAWINGS LIGHT VERTICAL AND LEFT -// 2525 BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY -// 2526 BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT -// 2527 BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT -// 2528 BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT -// 2529 BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY -// 252a BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY -// 252b BOX DRAWINGS HEAVY VERTICAL AND LEFT -// 252c BOX DRAWINGS LIGHT DOWN AND HORIZONTAL -// 252d BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT -// 252e BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT -// 252f BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY -// 2530 BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT -// 2531 BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY -// 2532 BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY -// 2533 BOX DRAWINGS HEAVY DOWN AND HORIZONTAL -// 2534 BOX DRAWINGS LIGHT UP AND HORIZONTAL -// 2535 BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT -// 2536 BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT -// 2537 BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY -// 2538 BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT -// 2539 BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY -// 253a BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY -// 253b BOX DRAWINGS HEAVY UP AND HORIZONTAL -// 253c BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL -// 253d BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT -// 253e BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT -// 253f BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY -// 2540 BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT -// 2541 BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT -// 2542 BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT -// 2543 BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT -// 2544 BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT -// 2545 BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT -// 2546 BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT -// 2547 BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY -// 2548 BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY -// 2549 BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY -// 254a BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY -// 254b BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL -// 254c BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL -// 254d BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL -// 254e BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL -// 254f BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL -// 2550 BOX DRAWINGS DOUBLE HORIZONTAL -// 2551 BOX DRAWINGS DOUBLE VERTICAL -// 2552 BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE -// 2553 BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE -// 2554 BOX DRAWINGS DOUBLE DOWN AND RIGHT -// 2555 BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE -// 2556 BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE -// 2557 BOX DRAWINGS DOUBLE DOWN AND LEFT -// 2558 BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE -// 2559 BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE -// 255a BOX DRAWINGS DOUBLE UP AND RIGHT -// 255b BOX DRAWINGS UP SINGLE AND LEFT DOUBLE -// 255c BOX DRAWINGS UP DOUBLE AND LEFT SINGLE -// 255d BOX DRAWINGS DOUBLE UP AND LEFT -// 255e BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE -// 255f BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE -// 2560 BOX DRAWINGS DOUBLE VERTICAL AND RIGHT -// 2561 BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE -// 2562 BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE -// 2563 BOX DRAWINGS DOUBLE VERTICAL AND LEFT -// 2564 BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE -// 2565 BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE -// 2566 BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL -// 2567 BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE -// 2568 BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE -// 2569 BOX DRAWINGS DOUBLE UP AND HORIZONTAL -// 256a BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE -// 256b BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE -// 256c BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL -// 256d BOX DRAWINGS LIGHT ARC DOWN AND RIGHT -// 256e BOX DRAWINGS LIGHT ARC DOWN AND LEFT -// 256f BOX DRAWINGS LIGHT ARC UP AND LEFT -// 2570 BOX DRAWINGS LIGHT ARC UP AND RIGHT -// 2571 BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT -// 2572 BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT -// 2573 BOX DRAWINGS LIGHT DIAGONAL CROSS -// 2574 BOX DRAWINGS LIGHT LEFT -// 2575 BOX DRAWINGS LIGHT UP -// 2576 BOX DRAWINGS LIGHT RIGHT -// 2577 BOX DRAWINGS LIGHT DOWN -// 2578 BOX DRAWINGS HEAVY LEFT -// 2579 BOX DRAWINGS HEAVY UP -// 257a BOX DRAWINGS HEAVY RIGHT -// 257b BOX DRAWINGS HEAVY DOWN -// 257c BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT -// 257d BOX DRAWINGS LIGHT UP AND HEAVY DOWN -// 257e BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT -// 257f BOX DRAWINGS HEAVY UP AND LIGHT DOWN -// 2580 UPPER HALF BLOCK -// 2581 LOWER ONE EIGHTH BLOCK -// 2582 LOWER ONE QUARTER BLOCK -// 2583 LOWER THREE EIGHTHS BLOCK -// 2584 LOWER HALF BLOCK -// 2585 LOWER FIVE EIGHTHS BLOCK -// 2586 LOWER THREE QUARTERS BLOCK -// 2587 LOWER SEVEN EIGHTHS BLOCK -// 2588 FULL BLOCK -// 2589 LEFT SEVEN EIGHTHS BLOCK -// 258a LEFT THREE QUARTERS BLOCK -// 258b LEFT FIVE EIGHTHS BLOCK -// 258c LEFT HALF BLOCK -// 258d LEFT THREE EIGHTHS BLOCK -// 258e LEFT ONE QUARTER BLOCK -// 258f LEFT ONE EIGHTH BLOCK -// 2590 RIGHT HALF BLOCK -// 2591 LIGHT SHADE -// 2592 MEDIUM SHADE -// 2593 DARK SHADE -// 2594 UPPER ONE EIGHTH BLOCK -// 2595 RIGHT ONE EIGHTH BLOCK -// 2596 QUADRANT LOWER LEFT -// 2597 QUADRANT LOWER RIGHT -// 2598 QUADRANT UPPER LEFT -// 2599 QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT -// 259a QUADRANT UPPER LEFT AND LOWER RIGHT -// 259b QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT -// 259c QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT -// 259d QUADRANT UPPER RIGHT -// 259e QUADRANT UPPER RIGHT AND LOWER LEFT -// 259f QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT -// 25a0 BLACK SQUARE -// 25a1 WHITE SQUARE -// 25a2 WHITE SQUARE WITH ROUNDED CORNERS -// 25a3 WHITE SQUARE CONTAINING BLACK SMALL SQUARE -// 25a4 SQUARE WITH HORIZONTAL FILL -// 25a5 SQUARE WITH VERTICAL FILL -// 25a6 SQUARE WITH ORTHOGONAL CROSSHATCH FILL -// 25a7 SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL -// 25a8 SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL -// 25a9 SQUARE WITH DIAGONAL CROSSHATCH FILL -// 25aa BLACK SMALL SQUARE -// 25ab WHITE SMALL SQUARE -// 25ac BLACK RECTANGLE -// 25ad WHITE RECTANGLE -// 25ae BLACK VERTICAL RECTANGLE -// 25af WHITE VERTICAL RECTANGLE -// 25b0 BLACK PARALLELOGRAM -// 25b1 WHITE PARALLELOGRAM -// 25b2 BLACK UP-POINTING TRIANGLE -// 25b3 WHITE UP-POINTING TRIANGLE -// 25b4 BLACK UP-POINTING SMALL TRIANGLE -// 25b5 WHITE UP-POINTING SMALL TRIANGLE -// 25b6 BLACK RIGHT-POINTING TRIANGLE -// 25b7 WHITE RIGHT-POINTING TRIANGLE -// 25b8 BLACK RIGHT-POINTING SMALL TRIANGLE -// 25b9 WHITE RIGHT-POINTING SMALL TRIANGLE -// 25ba BLACK RIGHT-POINTING POINTER -// 25bb WHITE RIGHT-POINTING POINTER -// 25bc BLACK DOWN-POINTING TRIANGLE -// 25bd WHITE DOWN-POINTING TRIANGLE -// 25be BLACK DOWN-POINTING SMALL TRIANGLE -// 25bf WHITE DOWN-POINTING SMALL TRIANGLE -// 25c0 BLACK LEFT-POINTING TRIANGLE -// 25c1 WHITE LEFT-POINTING TRIANGLE -// 25c2 BLACK LEFT-POINTING SMALL TRIANGLE -// 25c3 WHITE LEFT-POINTING SMALL TRIANGLE -// 25c4 BLACK LEFT-POINTING POINTER -// 25c5 WHITE LEFT-POINTING POINTER -// 25c6 BLACK DIAMOND -// 25c7 WHITE DIAMOND -// 25c8 WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND -// 25c9 FISHEYE -// 25ca LOZENGE -// 25cb WHITE CIRCLE -// 25cc DOTTED CIRCLE -// 25cd CIRCLE WITH VERTICAL FILL -// 25ce BULLSEYE -// 25cf BLACK CIRCLE -// 25d0 CIRCLE WITH LEFT HALF BLACK -// 25d1 CIRCLE WITH RIGHT HALF BLACK -// 25d2 CIRCLE WITH LOWER HALF BLACK -// 25d3 CIRCLE WITH UPPER HALF BLACK -// 25d4 CIRCLE WITH UPPER RIGHT QUADRANT BLACK -// 25d5 CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK -// 25d6 LEFT HALF BLACK CIRCLE -// 25d7 RIGHT HALF BLACK CIRCLE -// 25d8 INVERSE BULLET -// 25d9 INVERSE WHITE CIRCLE -// 25da UPPER HALF INVERSE WHITE CIRCLE -// 25db LOWER HALF INVERSE WHITE CIRCLE -// 25dc UPPER LEFT QUADRANT CIRCULAR ARC -// 25dd UPPER RIGHT QUADRANT CIRCULAR ARC -// 25de LOWER RIGHT QUADRANT CIRCULAR ARC -// 25df LOWER LEFT QUADRANT CIRCULAR ARC -// 25e0 UPPER HALF CIRCLE -// 25e1 LOWER HALF CIRCLE -// 25e2 BLACK LOWER RIGHT TRIANGLE -// 25e3 BLACK LOWER LEFT TRIANGLE -// 25e4 BLACK UPPER LEFT TRIANGLE -// 25e5 BLACK UPPER RIGHT TRIANGLE -// 25e6 WHITE BULLET -// 25e7 SQUARE WITH LEFT HALF BLACK -// 25e8 SQUARE WITH RIGHT HALF BLACK -// 25e9 SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK -// 25ea SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK -// 25eb WHITE SQUARE WITH VERTICAL BISECTING LINE -// 25ec WHITE UP-POINTING TRIANGLE WITH DOT -// 25ed UP-POINTING TRIANGLE WITH LEFT HALF BLACK -// 25ee UP-POINTING TRIANGLE WITH RIGHT HALF BLACK -// 25ef LARGE CIRCLE -// 25f0 WHITE SQUARE WITH UPPER LEFT QUADRANT -// 25f1 WHITE SQUARE WITH LOWER LEFT QUADRANT -// 25f2 WHITE SQUARE WITH LOWER RIGHT QUADRANT -// 25f3 WHITE SQUARE WITH UPPER RIGHT QUADRANT -// 25f4 WHITE CIRCLE WITH UPPER LEFT QUADRANT -// 25f5 WHITE CIRCLE WITH LOWER LEFT QUADRANT -// 25f6 WHITE CIRCLE WITH LOWER RIGHT QUADRANT -// 25f7 WHITE CIRCLE WITH UPPER RIGHT QUADRANT -// 25f8 UPPER LEFT TRIANGLE -// 25f9 UPPER RIGHT TRIANGLE -// 25fa LOWER LEFT TRIANGLE -// 25fb WHITE MEDIUM SQUARE -// 25fc BLACK MEDIUM SQUARE -// 25fd WHITE MEDIUM SMALL SQUARE -// 25fe BLACK MEDIUM SMALL SQUARE -// 25ff LOWER RIGHT TRIANGLE -// 2600 BLACK SUN WITH RAYS -// 2601 CLOUD -// 2602 UMBRELLA -// 2603 SNOWMAN -// 2604 COMET -// 2605 BLACK STAR -// 2606 WHITE STAR -// 2607 LIGHTNING -// 2608 THUNDERSTORM -// 2609 SUN -// 260a ASCENDING NODE -// 260b DESCENDING NODE -// 260c CONJUNCTION -// 260d OPPOSITION -// 260e BLACK TELEPHONE -// 260f WHITE TELEPHONE -// 2610 BALLOT BOX -// 2611 BALLOT BOX WITH CHECK -// 2612 BALLOT BOX WITH X -// 2613 SALTIRE -// 2614 UMBRELLA WITH RAIN DROPS -// 2615 HOT BEVERAGE -// 2616 WHITE SHOGI PIECE -// 2617 BLACK SHOGI PIECE -// 2618 SHAMROCK -// 2619 REVERSED ROTATED FLORAL HEART BULLET -// 261a BLACK LEFT POINTING INDEX -// 261b BLACK RIGHT POINTING INDEX -// 261c WHITE LEFT POINTING INDEX -// 261d WHITE UP POINTING INDEX -// 261e WHITE RIGHT POINTING INDEX -// 261f WHITE DOWN POINTING INDEX -// 2620 SKULL AND CROSSBONES -// 2621 CAUTION SIGN -// 2622 RADIOACTIVE SIGN -// 2623 BIOHAZARD SIGN -// 2624 CADUCEUS -// 2625 ANKH -// 2626 ORTHODOX CROSS -// 2627 CHI RHO -// 2628 CROSS OF LORRAINE -// 2629 CROSS OF JERUSALEM -// 262a STAR AND CRESCENT -// 262b FARSI SYMBOL -// 262c ADI SHAKTI -// 262d HAMMER AND SICKLE -// 262e PEACE SYMBOL -// 262f YIN YANG -// 2630 TRIGRAM FOR HEAVEN -// 2631 TRIGRAM FOR LAKE -// 2632 TRIGRAM FOR FIRE -// 2633 TRIGRAM FOR THUNDER -// 2634 TRIGRAM FOR WIND -// 2635 TRIGRAM FOR WATER -// 2636 TRIGRAM FOR MOUNTAIN -// 2637 TRIGRAM FOR EARTH -// 2638 WHEEL OF DHARMA -// 2639 WHITE FROWNING FACE -// 263a WHITE SMILING FACE -// 263b BLACK SMILING FACE -// 263c WHITE SUN WITH RAYS -// 263d FIRST QUARTER MOON -// 263e LAST QUARTER MOON -// 263f MERCURY -// 2640 FEMALE SIGN -// 2641 EARTH -// 2642 MALE SIGN -// 2643 JUPITER -// 2644 SATURN -// 2645 URANUS -// 2646 NEPTUNE -// 2647 PLUTO -// 2648 ARIES -// 2649 TAURUS -// 264a GEMINI -// 264b CANCER -// 264c LEO -// 264d VIRGO -// 264e LIBRA -// 264f SCORPIUS -// 2650 SAGITTARIUS -// 2651 CAPRICORN -// 2652 AQUARIUS -// 2653 PISCES -// 2654 WHITE CHESS KING -// 2655 WHITE CHESS QUEEN -// 2656 WHITE CHESS ROOK -// 2657 WHITE CHESS BISHOP -// 2658 WHITE CHESS KNIGHT -// 2659 WHITE CHESS PAWN -// 265a BLACK CHESS KING -// 265b BLACK CHESS QUEEN -// 265c BLACK CHESS ROOK -// 265d BLACK CHESS BISHOP -// 265e BLACK CHESS KNIGHT -// 265f BLACK CHESS PAWN -// 2660 BLACK SPADE SUIT -// 2661 WHITE HEART SUIT -// 2662 WHITE DIAMOND SUIT -// 2663 BLACK CLUB SUIT -// 2664 WHITE SPADE SUIT -// 2665 BLACK HEART SUIT -// 2666 BLACK DIAMOND SUIT -// 2667 WHITE CLUB SUIT -// 2668 HOT SPRINGS -// 2669 QUARTER NOTE -// 266a EIGHTH NOTE -// 266b BEAMED EIGHTH NOTES -// 266c BEAMED SIXTEENTH NOTES -// 266d MUSIC FLAT SIGN -// 266e MUSIC NATURAL SIGN -// 266f MUSIC SHARP SIGN -// 2670 WEST SYRIAC CROSS -// 2671 EAST SYRIAC CROSS -// 2672 UNIVERSAL RECYCLING SYMBOL -// 2673 RECYCLING SYMBOL FOR TYPE-1 PLASTICS -// 2674 RECYCLING SYMBOL FOR TYPE-2 PLASTICS -// 2675 RECYCLING SYMBOL FOR TYPE-3 PLASTICS -// 2676 RECYCLING SYMBOL FOR TYPE-4 PLASTICS -// 2677 RECYCLING SYMBOL FOR TYPE-5 PLASTICS -// 2678 RECYCLING SYMBOL FOR TYPE-6 PLASTICS -// 2679 RECYCLING SYMBOL FOR TYPE-7 PLASTICS -// 267a RECYCLING SYMBOL FOR GENERIC MATERIALS -// 267b BLACK UNIVERSAL RECYCLING SYMBOL -// 267c RECYCLED PAPER SYMBOL -// 267d PARTIALLY-RECYCLED PAPER SYMBOL -// 267e PERMANENT PAPER SIGN -// 267f WHEELCHAIR SYMBOL -// 2680 DIE FACE-1 -// 2681 DIE FACE-2 -// 2682 DIE FACE-3 -// 2683 DIE FACE-4 -// 2684 DIE FACE-5 -// 2685 DIE FACE-6 -// 2686 WHITE CIRCLE WITH DOT RIGHT -// 2687 WHITE CIRCLE WITH TWO DOTS -// 2688 BLACK CIRCLE WITH WHITE DOT RIGHT -// 2689 BLACK CIRCLE WITH TWO WHITE DOTS -// 268a MONOGRAM FOR YANG -// 268b MONOGRAM FOR YIN -// 268c DIGRAM FOR GREATER YANG -// 268d DIGRAM FOR LESSER YIN -// 268e DIGRAM FOR LESSER YANG -// 268f DIGRAM FOR GREATER YIN -// 2690 WHITE FLAG -// 2691 BLACK FLAG -// 2692 HAMMER AND PICK -// 2693 ANCHOR -// 2694 CROSSED SWORDS -// 2695 STAFF OF AESCULAPIUS -// 2696 SCALES -// 2697 ALEMBIC -// 2698 FLOWER -// 2699 GEAR -// 269a STAFF OF HERMES -// 269b ATOM SYMBOL -// 269c FLEUR-DE-LIS -// 269d OUTLINED WHITE STAR -// 269e THREE LINES CONVERGING RIGHT -// 269f THREE LINES CONVERGING LEFT -// 26a0 WARNING SIGN -// 26a1 HIGH VOLTAGE SIGN -// 26a2 DOUBLED FEMALE SIGN -// 26a3 DOUBLED MALE SIGN -// 26a4 INTERLOCKED FEMALE AND MALE SIGN -// 26a5 MALE AND FEMALE SIGN -// 26a6 MALE WITH STROKE SIGN -// 26a7 MALE WITH STROKE AND MALE AND FEMALE SIGN -// 26a8 VERTICAL MALE WITH STROKE SIGN -// 26a9 HORIZONTAL MALE WITH STROKE SIGN -// 26aa MEDIUM WHITE CIRCLE -// 26ab MEDIUM BLACK CIRCLE -// 26ac MEDIUM SMALL WHITE CIRCLE -// 26ad MARRIAGE SYMBOL -// 26ae DIVORCE SYMBOL -// 26af UNMARRIED PARTNERSHIP SYMBOL -// 26b0 COFFIN -// 26b1 FUNERAL URN -// 26b2 NEUTER -// 26b3 CERES -// 26b4 PALLAS -// 26b5 JUNO -// 26b6 VESTA -// 26b7 CHIRON -// 26b8 BLACK MOON LILITH -// 26b9 SEXTILE -// 26ba SEMISEXTILE -// 26bb QUINCUNX -// 26bc SESQUIQUADRATE -// 26bd SOCCER BALL -// 26be BASEBALL -// 26bf SQUARED KEY -// 26c0 WHITE DRAUGHTS MAN -// 26c1 WHITE DRAUGHTS KING -// 26c2 BLACK DRAUGHTS MAN -// 26c3 BLACK DRAUGHTS KING -// 26c4 SNOWMAN WITHOUT SNOW -// 26c5 SUN BEHIND CLOUD -// 26c6 RAIN -// 26c7 BLACK SNOWMAN -// 26c8 THUNDER CLOUD AND RAIN -// 26c9 TURNED WHITE SHOGI PIECE -// 26ca TURNED BLACK SHOGI PIECE -// 26cb WHITE DIAMOND IN SQUARE -// 26cc CROSSING LANES -// 26cd DISABLED CAR -// 26ce OPHIUCHUS -// 26cf PICK -// 26d0 CAR SLIDING -// 26d1 HELMET WITH WHITE CROSS -// 26d2 CIRCLED CROSSING LANES -// 26d3 CHAINS -// 26d4 NO ENTRY -// 26d5 ALTERNATE ONE-WAY LEFT WAY TRAFFIC -// 26d6 BLACK TWO-WAY LEFT WAY TRAFFIC -// 26d7 WHITE TWO-WAY LEFT WAY TRAFFIC -// 26d8 BLACK LEFT LANE MERGE -// 26d9 WHITE LEFT LANE MERGE -// 26da DRIVE SLOW SIGN -// 26db HEAVY WHITE DOWN-POINTING TRIANGLE -// 26dc LEFT CLOSED ENTRY -// 26dd SQUARED SALTIRE -// 26de FALLING DIAGONAL IN WHITE CIRCLE IN BLACK SQUARE -// 26df BLACK TRUCK -// 26e0 RESTRICTED LEFT ENTRY-1 -// 26e1 RESTRICTED LEFT ENTRY-2 -// 26e2 ASTRONOMICAL SYMBOL FOR URANUS -// 26e3 HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE -// 26e4 PENTAGRAM -// 26e5 RIGHT-HANDED INTERLACED PENTAGRAM -// 26e6 LEFT-HANDED INTERLACED PENTAGRAM -// 26e7 INVERTED PENTAGRAM -// 26e8 BLACK CROSS ON SHIELD -// 26e9 SHINTO SHRINE -// 26ea CHURCH -// 26eb CASTLE -// 26ec HISTORIC SITE -// 26ed GEAR WITHOUT HUB -// 26ee GEAR WITH HANDLES -// 26ef MAP SYMBOL FOR LIGHTHOUSE -// 26f0 MOUNTAIN -// 26f1 UMBRELLA ON GROUND -// 26f2 FOUNTAIN -// 26f3 FLAG IN HOLE -// 26f4 FERRY -// 26f5 SAILBOAT -// 26f6 SQUARE FOUR CORNERS -// 26f7 SKIER -// 26f8 ICE SKATE -// 26f9 PERSON WITH BALL -// 26fa TENT -// 26fb JAPANESE BANK SYMBOL -// 26fc HEADSTONE GRAVEYARD SYMBOL -// 26fd FUEL PUMP -// 26fe CUP ON BLACK SQUARE -// 26ff WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE -// 2700 BLACK SAFETY SCISSORS -// 2701 UPPER BLADE SCISSORS -// 2702 BLACK SCISSORS -// 2703 LOWER BLADE SCISSORS -// 2704 WHITE SCISSORS -// 2705 WHITE HEAVY CHECK MARK -// 2706 TELEPHONE LOCATION SIGN -// 2707 TAPE DRIVE -// 2708 AIRPLANE -// 2709 ENVELOPE -// 270a RAISED FIST -// 270b RAISED HAND -// 270c VICTORY HAND -// 270d WRITING HAND -// 270e LOWER RIGHT PENCIL -// 270f PENCIL -// 2710 UPPER RIGHT PENCIL -// 2711 WHITE NIB -// 2712 BLACK NIB -// 2713 CHECK MARK -// 2714 HEAVY CHECK MARK -// 2715 MULTIPLICATION X -// 2716 HEAVY MULTIPLICATION X -// 2717 BALLOT X -// 2718 HEAVY BALLOT X -// 2719 OUTLINED GREEK CROSS -// 271a HEAVY GREEK CROSS -// 271b OPEN CENTRE CROSS -// 271c HEAVY OPEN CENTRE CROSS -// 271d LATIN CROSS -// 271e SHADOWED WHITE LATIN CROSS -// 271f OUTLINED LATIN CROSS -// 2720 MALTESE CROSS -// 2721 STAR OF DAVID -// 2722 FOUR TEARDROP-SPOKED ASTERISK -// 2723 FOUR BALLOON-SPOKED ASTERISK -// 2724 HEAVY FOUR BALLOON-SPOKED ASTERISK -// 2725 FOUR CLUB-SPOKED ASTERISK -// 2726 BLACK FOUR POINTED STAR -// 2727 WHITE FOUR POINTED STAR -// 2728 SPARKLES -// 2729 STRESS OUTLINED WHITE STAR -// 272a CIRCLED WHITE STAR -// 272b OPEN CENTRE BLACK STAR -// 272c BLACK CENTRE WHITE STAR -// 272d OUTLINED BLACK STAR -// 272e HEAVY OUTLINED BLACK STAR -// 272f PINWHEEL STAR -// 2730 SHADOWED WHITE STAR -// 2731 HEAVY ASTERISK -// 2732 OPEN CENTRE ASTERISK -// 2733 EIGHT SPOKED ASTERISK -// 2734 EIGHT POINTED BLACK STAR -// 2735 EIGHT POINTED PINWHEEL STAR -// 2736 SIX POINTED BLACK STAR -// 2737 EIGHT POINTED RECTILINEAR BLACK STAR -// 2738 HEAVY EIGHT POINTED RECTILINEAR BLACK STAR -// 2739 TWELVE POINTED BLACK STAR -// 273a SIXTEEN POINTED ASTERISK -// 273b TEARDROP-SPOKED ASTERISK -// 273c OPEN CENTRE TEARDROP-SPOKED ASTERISK -// 273d HEAVY TEARDROP-SPOKED ASTERISK -// 273e SIX PETALLED BLACK AND WHITE FLORETTE -// 273f BLACK FLORETTE -// 2740 WHITE FLORETTE -// 2741 EIGHT PETALLED OUTLINED BLACK FLORETTE -// 2742 CIRCLED OPEN CENTRE EIGHT POINTED STAR -// 2743 HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK -// 2744 SNOWFLAKE -// 2745 TIGHT TRIFOLIATE SNOWFLAKE -// 2746 HEAVY CHEVRON SNOWFLAKE -// 2747 SPARKLE -// 2748 HEAVY SPARKLE -// 2749 BALLOON-SPOKED ASTERISK -// 274a EIGHT TEARDROP-SPOKED PROPELLER ASTERISK -// 274b HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK -// 274c CROSS MARK -// 274d SHADOWED WHITE CIRCLE -// 274e NEGATIVE SQUARED CROSS MARK -// 274f LOWER RIGHT DROP-SHADOWED WHITE SQUARE -// 2750 UPPER RIGHT DROP-SHADOWED WHITE SQUARE -// 2751 LOWER RIGHT SHADOWED WHITE SQUARE -// 2752 UPPER RIGHT SHADOWED WHITE SQUARE -// 2753 BLACK QUESTION MARK ORNAMENT -// 2754 WHITE QUESTION MARK ORNAMENT -// 2755 WHITE EXCLAMATION MARK ORNAMENT -// 2756 BLACK DIAMOND MINUS WHITE X -// 2757 HEAVY EXCLAMATION MARK SYMBOL -// 2758 LIGHT VERTICAL BAR -// 2759 MEDIUM VERTICAL BAR -// 275a HEAVY VERTICAL BAR -// 275b HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT -// 275c HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT -// 275d HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT -// 275e HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT -// 275f HEAVY LOW SINGLE COMMA QUOTATION MARK ORNAMENT -// 2760 HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT -// 2761 CURVED STEM PARAGRAPH SIGN ORNAMENT -// 2762 HEAVY EXCLAMATION MARK ORNAMENT -// 2763 HEAVY HEART EXCLAMATION MARK ORNAMENT -// 2764 HEAVY BLACK HEART -// 2765 ROTATED HEAVY BLACK HEART BULLET -// 2766 FLORAL HEART -// 2767 ROTATED FLORAL HEART BULLET - { 0x24EA, 0x27E, 0x8, 0, 0 }, -// 2768 MEDIUM LEFT PARENTHESIS ORNAMENT -// 2769 MEDIUM RIGHT PARENTHESIS ORNAMENT -// 276a MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT -// 276b MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT -// 276c MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT -// 276d MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT -// 276e HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT -// 276f HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT -// 2770 HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT -// 2771 HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT -// 2772 LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT -// 2773 LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT -// 2774 MEDIUM LEFT CURLY BRACKET ORNAMENT -// 2775 MEDIUM RIGHT CURLY BRACKET ORNAMENT - { 0x2768, 0xE, 0x18, 0, 0 }, -// 2776 DINGBAT NEGATIVE CIRCLED DIGIT ONE -// 2777 DINGBAT NEGATIVE CIRCLED DIGIT TWO -// 2778 DINGBAT NEGATIVE CIRCLED DIGIT THREE -// 2779 DINGBAT NEGATIVE CIRCLED DIGIT FOUR -// 277a DINGBAT NEGATIVE CIRCLED DIGIT FIVE -// 277b DINGBAT NEGATIVE CIRCLED DIGIT SIX -// 277c DINGBAT NEGATIVE CIRCLED DIGIT SEVEN -// 277d DINGBAT NEGATIVE CIRCLED DIGIT EIGHT -// 277e DINGBAT NEGATIVE CIRCLED DIGIT NINE -// 277f DINGBAT NEGATIVE CIRCLED NUMBER TEN -// 2780 DINGBAT CIRCLED SANS-SERIF DIGIT ONE -// 2781 DINGBAT CIRCLED SANS-SERIF DIGIT TWO -// 2782 DINGBAT CIRCLED SANS-SERIF DIGIT THREE -// 2783 DINGBAT CIRCLED SANS-SERIF DIGIT FOUR -// 2784 DINGBAT CIRCLED SANS-SERIF DIGIT FIVE -// 2785 DINGBAT CIRCLED SANS-SERIF DIGIT SIX -// 2786 DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN -// 2787 DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT -// 2788 DINGBAT CIRCLED SANS-SERIF DIGIT NINE -// 2789 DINGBAT CIRCLED SANS-SERIF NUMBER TEN -// 278a DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE -// 278b DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO -// 278c DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE -// 278d DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR -// 278e DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE -// 278f DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX -// 2790 DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN -// 2791 DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT -// 2792 DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE -// 2793 DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN -// 2794 HEAVY WIDE-HEADED RIGHTWARDS ARROW -// 2795 HEAVY PLUS SIGN -// 2796 HEAVY MINUS SIGN -// 2797 HEAVY DIVISION SIGN -// 2798 HEAVY SOUTH EAST ARROW -// 2799 HEAVY RIGHTWARDS ARROW -// 279a HEAVY NORTH EAST ARROW -// 279b DRAFTING POINT RIGHTWARDS ARROW -// 279c HEAVY ROUND-TIPPED RIGHTWARDS ARROW -// 279d TRIANGLE-HEADED RIGHTWARDS ARROW -// 279e HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW -// 279f DASHED TRIANGLE-HEADED RIGHTWARDS ARROW -// 27a0 HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW -// 27a1 BLACK RIGHTWARDS ARROW -// 27a2 THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD -// 27a3 THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD -// 27a4 BLACK RIGHTWARDS ARROWHEAD -// 27a5 HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW -// 27a6 HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW -// 27a7 SQUAT BLACK RIGHTWARDS ARROW -// 27a8 HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW -// 27a9 RIGHT-SHADED WHITE RIGHTWARDS ARROW -// 27aa LEFT-SHADED WHITE RIGHTWARDS ARROW -// 27ab BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW -// 27ac FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW -// 27ad HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW -// 27ae HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW -// 27af NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW -// 27b0 CURLY LOOP -// 27b1 NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW -// 27b2 CIRCLED HEAVY WHITE RIGHTWARDS ARROW -// 27b3 WHITE-FEATHERED RIGHTWARDS ARROW -// 27b4 BLACK-FEATHERED SOUTH EAST ARROW -// 27b5 BLACK-FEATHERED RIGHTWARDS ARROW -// 27b6 BLACK-FEATHERED NORTH EAST ARROW -// 27b7 HEAVY BLACK-FEATHERED SOUTH EAST ARROW -// 27b8 HEAVY BLACK-FEATHERED RIGHTWARDS ARROW -// 27b9 HEAVY BLACK-FEATHERED NORTH EAST ARROW -// 27ba TEARDROP-BARBED RIGHTWARDS ARROW -// 27bb HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW -// 27bc WEDGE-TAILED RIGHTWARDS ARROW -// 27bd HEAVY WEDGE-TAILED RIGHTWARDS ARROW -// 27be OPEN-OUTLINED RIGHTWARDS ARROW -// 27bf DOUBLE CURLY LOOP -// 27c0 THREE DIMENSIONAL ANGLE -// 27c1 WHITE TRIANGLE CONTAINING SMALL WHITE TRIANGLE -// 27c2 PERPENDICULAR -// 27c3 OPEN SUBSET -// 27c4 OPEN SUPERSET - { 0x2776, 0x4F, 0x8, 0, 0 }, -// 27c5 LEFT S-SHAPED BAG DELIMITER -// 27c6 RIGHT S-SHAPED BAG DELIMITER - { 0x27C5, 0x2, 0x18, 0, 0 }, -// 27c7 OR WITH DOT INSIDE -// 27c8 REVERSE SOLIDUS PRECEDING SUBSET -// 27c9 SUPERSET PRECEDING SOLIDUS -// 27ca VERTICAL BAR WITH HORIZONTAL STROKE -// 27cb MATHEMATICAL RISING DIAGONAL -// 27cc LONG DIVISION -// 27cd MATHEMATICAL FALLING DIAGONAL -// 27ce SQUARED LOGICAL AND -// 27cf SQUARED LOGICAL OR -// 27d0 WHITE DIAMOND WITH CENTRED DOT -// 27d1 AND WITH DOT -// 27d2 ELEMENT OF OPENING UPWARDS -// 27d3 LOWER RIGHT CORNER WITH DOT -// 27d4 UPPER LEFT CORNER WITH DOT -// 27d5 LEFT OUTER JOIN -// 27d6 RIGHT OUTER JOIN -// 27d7 FULL OUTER JOIN -// 27d8 LARGE UP TACK -// 27d9 LARGE DOWN TACK -// 27da LEFT AND RIGHT DOUBLE TURNSTILE -// 27db LEFT AND RIGHT TACK -// 27dc LEFT MULTIMAP -// 27dd LONG RIGHT TACK -// 27de LONG LEFT TACK -// 27df UP TACK WITH CIRCLE ABOVE -// 27e0 LOZENGE DIVIDED BY HORIZONTAL RULE -// 27e1 WHITE CONCAVE-SIDED DIAMOND -// 27e2 WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK -// 27e3 WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK -// 27e4 WHITE SQUARE WITH LEFTWARDS TICK -// 27e5 WHITE SQUARE WITH RIGHTWARDS TICK - { 0x27C7, 0x1F, 0x8, 0, 0 }, -// 27e6 MATHEMATICAL LEFT WHITE SQUARE BRACKET -// 27e7 MATHEMATICAL RIGHT WHITE SQUARE BRACKET -// 27e8 MATHEMATICAL LEFT ANGLE BRACKET -// 27e9 MATHEMATICAL RIGHT ANGLE BRACKET -// 27ea MATHEMATICAL LEFT DOUBLE ANGLE BRACKET -// 27eb MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET -// 27ec MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET -// 27ed MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET -// 27ee MATHEMATICAL LEFT FLATTENED PARENTHESIS -// 27ef MATHEMATICAL RIGHT FLATTENED PARENTHESIS - { 0x27E6, 0xA, 0x18, 0, 0 }, -// 27f0 UPWARDS QUADRUPLE ARROW -// 27f1 DOWNWARDS QUADRUPLE ARROW -// 27f2 ANTICLOCKWISE GAPPED CIRCLE ARROW -// 27f3 CLOCKWISE GAPPED CIRCLE ARROW -// 27f4 RIGHT ARROW WITH CIRCLED PLUS -// 27f5 LONG LEFTWARDS ARROW -// 27f6 LONG RIGHTWARDS ARROW -// 27f7 LONG LEFT RIGHT ARROW -// 27f8 LONG LEFTWARDS DOUBLE ARROW -// 27f9 LONG RIGHTWARDS DOUBLE ARROW -// 27fa LONG LEFT RIGHT DOUBLE ARROW -// 27fb LONG LEFTWARDS ARROW FROM BAR -// 27fc LONG RIGHTWARDS ARROW FROM BAR -// 27fd LONG LEFTWARDS DOUBLE ARROW FROM BAR -// 27fe LONG RIGHTWARDS DOUBLE ARROW FROM BAR -// 27ff LONG RIGHTWARDS SQUIGGLE ARROW -// 2800 BRAILLE PATTERN BLANK -// 2801 BRAILLE PATTERN DOTS-1 -// 2802 BRAILLE PATTERN DOTS-2 -// 2803 BRAILLE PATTERN DOTS-12 -// 2804 BRAILLE PATTERN DOTS-3 -// 2805 BRAILLE PATTERN DOTS-13 -// 2806 BRAILLE PATTERN DOTS-23 -// 2807 BRAILLE PATTERN DOTS-123 -// 2808 BRAILLE PATTERN DOTS-4 -// 2809 BRAILLE PATTERN DOTS-14 -// 280a BRAILLE PATTERN DOTS-24 -// 280b BRAILLE PATTERN DOTS-124 -// 280c BRAILLE PATTERN DOTS-34 -// 280d BRAILLE PATTERN DOTS-134 -// 280e BRAILLE PATTERN DOTS-234 -// 280f BRAILLE PATTERN DOTS-1234 -// 2810 BRAILLE PATTERN DOTS-5 -// 2811 BRAILLE PATTERN DOTS-15 -// 2812 BRAILLE PATTERN DOTS-25 -// 2813 BRAILLE PATTERN DOTS-125 -// 2814 BRAILLE PATTERN DOTS-35 -// 2815 BRAILLE PATTERN DOTS-135 -// 2816 BRAILLE PATTERN DOTS-235 -// 2817 BRAILLE PATTERN DOTS-1235 -// 2818 BRAILLE PATTERN DOTS-45 -// 2819 BRAILLE PATTERN DOTS-145 -// 281a BRAILLE PATTERN DOTS-245 -// 281b BRAILLE PATTERN DOTS-1245 -// 281c BRAILLE PATTERN DOTS-345 -// 281d BRAILLE PATTERN DOTS-1345 -// 281e BRAILLE PATTERN DOTS-2345 -// 281f BRAILLE PATTERN DOTS-12345 -// 2820 BRAILLE PATTERN DOTS-6 -// 2821 BRAILLE PATTERN DOTS-16 -// 2822 BRAILLE PATTERN DOTS-26 -// 2823 BRAILLE PATTERN DOTS-126 -// 2824 BRAILLE PATTERN DOTS-36 -// 2825 BRAILLE PATTERN DOTS-136 -// 2826 BRAILLE PATTERN DOTS-236 -// 2827 BRAILLE PATTERN DOTS-1236 -// 2828 BRAILLE PATTERN DOTS-46 -// 2829 BRAILLE PATTERN DOTS-146 -// 282a BRAILLE PATTERN DOTS-246 -// 282b BRAILLE PATTERN DOTS-1246 -// 282c BRAILLE PATTERN DOTS-346 -// 282d BRAILLE PATTERN DOTS-1346 -// 282e BRAILLE PATTERN DOTS-2346 -// 282f BRAILLE PATTERN DOTS-12346 -// 2830 BRAILLE PATTERN DOTS-56 -// 2831 BRAILLE PATTERN DOTS-156 -// 2832 BRAILLE PATTERN DOTS-256 -// 2833 BRAILLE PATTERN DOTS-1256 -// 2834 BRAILLE PATTERN DOTS-356 -// 2835 BRAILLE PATTERN DOTS-1356 -// 2836 BRAILLE PATTERN DOTS-2356 -// 2837 BRAILLE PATTERN DOTS-12356 -// 2838 BRAILLE PATTERN DOTS-456 -// 2839 BRAILLE PATTERN DOTS-1456 -// 283a BRAILLE PATTERN DOTS-2456 -// 283b BRAILLE PATTERN DOTS-12456 -// 283c BRAILLE PATTERN DOTS-3456 -// 283d BRAILLE PATTERN DOTS-13456 -// 283e BRAILLE PATTERN DOTS-23456 -// 283f BRAILLE PATTERN DOTS-123456 -// 2840 BRAILLE PATTERN DOTS-7 -// 2841 BRAILLE PATTERN DOTS-17 -// 2842 BRAILLE PATTERN DOTS-27 -// 2843 BRAILLE PATTERN DOTS-127 -// 2844 BRAILLE PATTERN DOTS-37 -// 2845 BRAILLE PATTERN DOTS-137 -// 2846 BRAILLE PATTERN DOTS-237 -// 2847 BRAILLE PATTERN DOTS-1237 -// 2848 BRAILLE PATTERN DOTS-47 -// 2849 BRAILLE PATTERN DOTS-147 -// 284a BRAILLE PATTERN DOTS-247 -// 284b BRAILLE PATTERN DOTS-1247 -// 284c BRAILLE PATTERN DOTS-347 -// 284d BRAILLE PATTERN DOTS-1347 -// 284e BRAILLE PATTERN DOTS-2347 -// 284f BRAILLE PATTERN DOTS-12347 -// 2850 BRAILLE PATTERN DOTS-57 -// 2851 BRAILLE PATTERN DOTS-157 -// 2852 BRAILLE PATTERN DOTS-257 -// 2853 BRAILLE PATTERN DOTS-1257 -// 2854 BRAILLE PATTERN DOTS-357 -// 2855 BRAILLE PATTERN DOTS-1357 -// 2856 BRAILLE PATTERN DOTS-2357 -// 2857 BRAILLE PATTERN DOTS-12357 -// 2858 BRAILLE PATTERN DOTS-457 -// 2859 BRAILLE PATTERN DOTS-1457 -// 285a BRAILLE PATTERN DOTS-2457 -// 285b BRAILLE PATTERN DOTS-12457 -// 285c BRAILLE PATTERN DOTS-3457 -// 285d BRAILLE PATTERN DOTS-13457 -// 285e BRAILLE PATTERN DOTS-23457 -// 285f BRAILLE PATTERN DOTS-123457 -// 2860 BRAILLE PATTERN DOTS-67 -// 2861 BRAILLE PATTERN DOTS-167 -// 2862 BRAILLE PATTERN DOTS-267 -// 2863 BRAILLE PATTERN DOTS-1267 -// 2864 BRAILLE PATTERN DOTS-367 -// 2865 BRAILLE PATTERN DOTS-1367 -// 2866 BRAILLE PATTERN DOTS-2367 -// 2867 BRAILLE PATTERN DOTS-12367 -// 2868 BRAILLE PATTERN DOTS-467 -// 2869 BRAILLE PATTERN DOTS-1467 -// 286a BRAILLE PATTERN DOTS-2467 -// 286b BRAILLE PATTERN DOTS-12467 -// 286c BRAILLE PATTERN DOTS-3467 -// 286d BRAILLE PATTERN DOTS-13467 -// 286e BRAILLE PATTERN DOTS-23467 -// 286f BRAILLE PATTERN DOTS-123467 -// 2870 BRAILLE PATTERN DOTS-567 -// 2871 BRAILLE PATTERN DOTS-1567 -// 2872 BRAILLE PATTERN DOTS-2567 -// 2873 BRAILLE PATTERN DOTS-12567 -// 2874 BRAILLE PATTERN DOTS-3567 -// 2875 BRAILLE PATTERN DOTS-13567 -// 2876 BRAILLE PATTERN DOTS-23567 -// 2877 BRAILLE PATTERN DOTS-123567 -// 2878 BRAILLE PATTERN DOTS-4567 -// 2879 BRAILLE PATTERN DOTS-14567 -// 287a BRAILLE PATTERN DOTS-24567 -// 287b BRAILLE PATTERN DOTS-124567 -// 287c BRAILLE PATTERN DOTS-34567 -// 287d BRAILLE PATTERN DOTS-134567 -// 287e BRAILLE PATTERN DOTS-234567 -// 287f BRAILLE PATTERN DOTS-1234567 -// 2880 BRAILLE PATTERN DOTS-8 -// 2881 BRAILLE PATTERN DOTS-18 -// 2882 BRAILLE PATTERN DOTS-28 -// 2883 BRAILLE PATTERN DOTS-128 -// 2884 BRAILLE PATTERN DOTS-38 -// 2885 BRAILLE PATTERN DOTS-138 -// 2886 BRAILLE PATTERN DOTS-238 -// 2887 BRAILLE PATTERN DOTS-1238 -// 2888 BRAILLE PATTERN DOTS-48 -// 2889 BRAILLE PATTERN DOTS-148 -// 288a BRAILLE PATTERN DOTS-248 -// 288b BRAILLE PATTERN DOTS-1248 -// 288c BRAILLE PATTERN DOTS-348 -// 288d BRAILLE PATTERN DOTS-1348 -// 288e BRAILLE PATTERN DOTS-2348 -// 288f BRAILLE PATTERN DOTS-12348 -// 2890 BRAILLE PATTERN DOTS-58 -// 2891 BRAILLE PATTERN DOTS-158 -// 2892 BRAILLE PATTERN DOTS-258 -// 2893 BRAILLE PATTERN DOTS-1258 -// 2894 BRAILLE PATTERN DOTS-358 -// 2895 BRAILLE PATTERN DOTS-1358 -// 2896 BRAILLE PATTERN DOTS-2358 -// 2897 BRAILLE PATTERN DOTS-12358 -// 2898 BRAILLE PATTERN DOTS-458 -// 2899 BRAILLE PATTERN DOTS-1458 -// 289a BRAILLE PATTERN DOTS-2458 -// 289b BRAILLE PATTERN DOTS-12458 -// 289c BRAILLE PATTERN DOTS-3458 -// 289d BRAILLE PATTERN DOTS-13458 -// 289e BRAILLE PATTERN DOTS-23458 -// 289f BRAILLE PATTERN DOTS-123458 -// 28a0 BRAILLE PATTERN DOTS-68 -// 28a1 BRAILLE PATTERN DOTS-168 -// 28a2 BRAILLE PATTERN DOTS-268 -// 28a3 BRAILLE PATTERN DOTS-1268 -// 28a4 BRAILLE PATTERN DOTS-368 -// 28a5 BRAILLE PATTERN DOTS-1368 -// 28a6 BRAILLE PATTERN DOTS-2368 -// 28a7 BRAILLE PATTERN DOTS-12368 -// 28a8 BRAILLE PATTERN DOTS-468 -// 28a9 BRAILLE PATTERN DOTS-1468 -// 28aa BRAILLE PATTERN DOTS-2468 -// 28ab BRAILLE PATTERN DOTS-12468 -// 28ac BRAILLE PATTERN DOTS-3468 -// 28ad BRAILLE PATTERN DOTS-13468 -// 28ae BRAILLE PATTERN DOTS-23468 -// 28af BRAILLE PATTERN DOTS-123468 -// 28b0 BRAILLE PATTERN DOTS-568 -// 28b1 BRAILLE PATTERN DOTS-1568 -// 28b2 BRAILLE PATTERN DOTS-2568 -// 28b3 BRAILLE PATTERN DOTS-12568 -// 28b4 BRAILLE PATTERN DOTS-3568 -// 28b5 BRAILLE PATTERN DOTS-13568 -// 28b6 BRAILLE PATTERN DOTS-23568 -// 28b7 BRAILLE PATTERN DOTS-123568 -// 28b8 BRAILLE PATTERN DOTS-4568 -// 28b9 BRAILLE PATTERN DOTS-14568 -// 28ba BRAILLE PATTERN DOTS-24568 -// 28bb BRAILLE PATTERN DOTS-124568 -// 28bc BRAILLE PATTERN DOTS-34568 -// 28bd BRAILLE PATTERN DOTS-134568 -// 28be BRAILLE PATTERN DOTS-234568 -// 28bf BRAILLE PATTERN DOTS-1234568 -// 28c0 BRAILLE PATTERN DOTS-78 -// 28c1 BRAILLE PATTERN DOTS-178 -// 28c2 BRAILLE PATTERN DOTS-278 -// 28c3 BRAILLE PATTERN DOTS-1278 -// 28c4 BRAILLE PATTERN DOTS-378 -// 28c5 BRAILLE PATTERN DOTS-1378 -// 28c6 BRAILLE PATTERN DOTS-2378 -// 28c7 BRAILLE PATTERN DOTS-12378 -// 28c8 BRAILLE PATTERN DOTS-478 -// 28c9 BRAILLE PATTERN DOTS-1478 -// 28ca BRAILLE PATTERN DOTS-2478 -// 28cb BRAILLE PATTERN DOTS-12478 -// 28cc BRAILLE PATTERN DOTS-3478 -// 28cd BRAILLE PATTERN DOTS-13478 -// 28ce BRAILLE PATTERN DOTS-23478 -// 28cf BRAILLE PATTERN DOTS-123478 -// 28d0 BRAILLE PATTERN DOTS-578 -// 28d1 BRAILLE PATTERN DOTS-1578 -// 28d2 BRAILLE PATTERN DOTS-2578 -// 28d3 BRAILLE PATTERN DOTS-12578 -// 28d4 BRAILLE PATTERN DOTS-3578 -// 28d5 BRAILLE PATTERN DOTS-13578 -// 28d6 BRAILLE PATTERN DOTS-23578 -// 28d7 BRAILLE PATTERN DOTS-123578 -// 28d8 BRAILLE PATTERN DOTS-4578 -// 28d9 BRAILLE PATTERN DOTS-14578 -// 28da BRAILLE PATTERN DOTS-24578 -// 28db BRAILLE PATTERN DOTS-124578 -// 28dc BRAILLE PATTERN DOTS-34578 -// 28dd BRAILLE PATTERN DOTS-134578 -// 28de BRAILLE PATTERN DOTS-234578 -// 28df BRAILLE PATTERN DOTS-1234578 -// 28e0 BRAILLE PATTERN DOTS-678 -// 28e1 BRAILLE PATTERN DOTS-1678 -// 28e2 BRAILLE PATTERN DOTS-2678 -// 28e3 BRAILLE PATTERN DOTS-12678 -// 28e4 BRAILLE PATTERN DOTS-3678 -// 28e5 BRAILLE PATTERN DOTS-13678 -// 28e6 BRAILLE PATTERN DOTS-23678 -// 28e7 BRAILLE PATTERN DOTS-123678 -// 28e8 BRAILLE PATTERN DOTS-4678 -// 28e9 BRAILLE PATTERN DOTS-14678 -// 28ea BRAILLE PATTERN DOTS-24678 -// 28eb BRAILLE PATTERN DOTS-124678 -// 28ec BRAILLE PATTERN DOTS-34678 -// 28ed BRAILLE PATTERN DOTS-134678 -// 28ee BRAILLE PATTERN DOTS-234678 -// 28ef BRAILLE PATTERN DOTS-1234678 -// 28f0 BRAILLE PATTERN DOTS-5678 -// 28f1 BRAILLE PATTERN DOTS-15678 -// 28f2 BRAILLE PATTERN DOTS-25678 -// 28f3 BRAILLE PATTERN DOTS-125678 -// 28f4 BRAILLE PATTERN DOTS-35678 -// 28f5 BRAILLE PATTERN DOTS-135678 -// 28f6 BRAILLE PATTERN DOTS-235678 -// 28f7 BRAILLE PATTERN DOTS-1235678 -// 28f8 BRAILLE PATTERN DOTS-45678 -// 28f9 BRAILLE PATTERN DOTS-145678 -// 28fa BRAILLE PATTERN DOTS-245678 -// 28fb BRAILLE PATTERN DOTS-1245678 -// 28fc BRAILLE PATTERN DOTS-345678 -// 28fd BRAILLE PATTERN DOTS-1345678 -// 28fe BRAILLE PATTERN DOTS-2345678 -// 28ff BRAILLE PATTERN DOTS-12345678 -// 2900 RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE -// 2901 RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE -// 2902 LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE -// 2903 RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE -// 2904 LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE -// 2905 RIGHTWARDS TWO-HEADED ARROW FROM BAR -// 2906 LEFTWARDS DOUBLE ARROW FROM BAR -// 2907 RIGHTWARDS DOUBLE ARROW FROM BAR -// 2908 DOWNWARDS ARROW WITH HORIZONTAL STROKE -// 2909 UPWARDS ARROW WITH HORIZONTAL STROKE -// 290a UPWARDS TRIPLE ARROW -// 290b DOWNWARDS TRIPLE ARROW -// 290c LEFTWARDS DOUBLE DASH ARROW -// 290d RIGHTWARDS DOUBLE DASH ARROW -// 290e LEFTWARDS TRIPLE DASH ARROW -// 290f RIGHTWARDS TRIPLE DASH ARROW -// 2910 RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW -// 2911 RIGHTWARDS ARROW WITH DOTTED STEM -// 2912 UPWARDS ARROW TO BAR -// 2913 DOWNWARDS ARROW TO BAR -// 2914 RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE -// 2915 RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE -// 2916 RIGHTWARDS TWO-HEADED ARROW WITH TAIL -// 2917 RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE -// 2918 RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE -// 2919 LEFTWARDS ARROW-TAIL -// 291a RIGHTWARDS ARROW-TAIL -// 291b LEFTWARDS DOUBLE ARROW-TAIL -// 291c RIGHTWARDS DOUBLE ARROW-TAIL -// 291d LEFTWARDS ARROW TO BLACK DIAMOND -// 291e RIGHTWARDS ARROW TO BLACK DIAMOND -// 291f LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND -// 2920 RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND -// 2921 NORTH WEST AND SOUTH EAST ARROW -// 2922 NORTH EAST AND SOUTH WEST ARROW -// 2923 NORTH WEST ARROW WITH HOOK -// 2924 NORTH EAST ARROW WITH HOOK -// 2925 SOUTH EAST ARROW WITH HOOK -// 2926 SOUTH WEST ARROW WITH HOOK -// 2927 NORTH WEST ARROW AND NORTH EAST ARROW -// 2928 NORTH EAST ARROW AND SOUTH EAST ARROW -// 2929 SOUTH EAST ARROW AND SOUTH WEST ARROW -// 292a SOUTH WEST ARROW AND NORTH WEST ARROW -// 292b RISING DIAGONAL CROSSING FALLING DIAGONAL -// 292c FALLING DIAGONAL CROSSING RISING DIAGONAL -// 292d SOUTH EAST ARROW CROSSING NORTH EAST ARROW -// 292e NORTH EAST ARROW CROSSING SOUTH EAST ARROW -// 292f FALLING DIAGONAL CROSSING NORTH EAST ARROW -// 2930 RISING DIAGONAL CROSSING SOUTH EAST ARROW -// 2931 NORTH EAST ARROW CROSSING NORTH WEST ARROW -// 2932 NORTH WEST ARROW CROSSING NORTH EAST ARROW -// 2933 WAVE ARROW POINTING DIRECTLY RIGHT -// 2934 ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS -// 2935 ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS -// 2936 ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS -// 2937 ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS -// 2938 RIGHT-SIDE ARC CLOCKWISE ARROW -// 2939 LEFT-SIDE ARC ANTICLOCKWISE ARROW -// 293a TOP ARC ANTICLOCKWISE ARROW -// 293b BOTTOM ARC ANTICLOCKWISE ARROW -// 293c TOP ARC CLOCKWISE ARROW WITH MINUS -// 293d TOP ARC ANTICLOCKWISE ARROW WITH PLUS -// 293e LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW -// 293f LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW -// 2940 ANTICLOCKWISE CLOSED CIRCLE ARROW -// 2941 CLOCKWISE CLOSED CIRCLE ARROW -// 2942 RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW -// 2943 LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW -// 2944 SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW -// 2945 RIGHTWARDS ARROW WITH PLUS BELOW -// 2946 LEFTWARDS ARROW WITH PLUS BELOW -// 2947 RIGHTWARDS ARROW THROUGH X -// 2948 LEFT RIGHT ARROW THROUGH SMALL CIRCLE -// 2949 UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE -// 294a LEFT BARB UP RIGHT BARB DOWN HARPOON -// 294b LEFT BARB DOWN RIGHT BARB UP HARPOON -// 294c UP BARB RIGHT DOWN BARB LEFT HARPOON -// 294d UP BARB LEFT DOWN BARB RIGHT HARPOON -// 294e LEFT BARB UP RIGHT BARB UP HARPOON -// 294f UP BARB RIGHT DOWN BARB RIGHT HARPOON -// 2950 LEFT BARB DOWN RIGHT BARB DOWN HARPOON -// 2951 UP BARB LEFT DOWN BARB LEFT HARPOON -// 2952 LEFTWARDS HARPOON WITH BARB UP TO BAR -// 2953 RIGHTWARDS HARPOON WITH BARB UP TO BAR -// 2954 UPWARDS HARPOON WITH BARB RIGHT TO BAR -// 2955 DOWNWARDS HARPOON WITH BARB RIGHT TO BAR -// 2956 LEFTWARDS HARPOON WITH BARB DOWN TO BAR -// 2957 RIGHTWARDS HARPOON WITH BARB DOWN TO BAR -// 2958 UPWARDS HARPOON WITH BARB LEFT TO BAR -// 2959 DOWNWARDS HARPOON WITH BARB LEFT TO BAR -// 295a LEFTWARDS HARPOON WITH BARB UP FROM BAR -// 295b RIGHTWARDS HARPOON WITH BARB UP FROM BAR -// 295c UPWARDS HARPOON WITH BARB RIGHT FROM BAR -// 295d DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR -// 295e LEFTWARDS HARPOON WITH BARB DOWN FROM BAR -// 295f RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR -// 2960 UPWARDS HARPOON WITH BARB LEFT FROM BAR -// 2961 DOWNWARDS HARPOON WITH BARB LEFT FROM BAR -// 2962 LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN -// 2963 UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT -// 2964 RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN -// 2965 DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT -// 2966 LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP -// 2967 LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN -// 2968 RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP -// 2969 RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN -// 296a LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH -// 296b LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH -// 296c RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH -// 296d RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH -// 296e UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT -// 296f DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT -// 2970 RIGHT DOUBLE ARROW WITH ROUNDED HEAD -// 2971 EQUALS SIGN ABOVE RIGHTWARDS ARROW -// 2972 TILDE OPERATOR ABOVE RIGHTWARDS ARROW -// 2973 LEFTWARDS ARROW ABOVE TILDE OPERATOR -// 2974 RIGHTWARDS ARROW ABOVE TILDE OPERATOR -// 2975 RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO -// 2976 LESS-THAN ABOVE LEFTWARDS ARROW -// 2977 LEFTWARDS ARROW THROUGH LESS-THAN -// 2978 GREATER-THAN ABOVE RIGHTWARDS ARROW -// 2979 SUBSET ABOVE RIGHTWARDS ARROW -// 297a LEFTWARDS ARROW THROUGH SUBSET -// 297b SUPERSET ABOVE LEFTWARDS ARROW -// 297c LEFT FISH TAIL -// 297d RIGHT FISH TAIL -// 297e UP FISH TAIL -// 297f DOWN FISH TAIL -// 2980 TRIPLE VERTICAL BAR DELIMITER -// 2981 Z NOTATION SPOT -// 2982 Z NOTATION TYPE COLON - { 0x27F0, 0x193, 0x8, 0, 0 }, -// 2983 LEFT WHITE CURLY BRACKET -// 2984 RIGHT WHITE CURLY BRACKET -// 2985 LEFT WHITE PARENTHESIS -// 2986 RIGHT WHITE PARENTHESIS -// 2987 Z NOTATION LEFT IMAGE BRACKET -// 2988 Z NOTATION RIGHT IMAGE BRACKET -// 2989 Z NOTATION LEFT BINDING BRACKET -// 298a Z NOTATION RIGHT BINDING BRACKET -// 298b LEFT SQUARE BRACKET WITH UNDERBAR -// 298c RIGHT SQUARE BRACKET WITH UNDERBAR -// 298d LEFT SQUARE BRACKET WITH TICK IN TOP CORNER -// 298e RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER -// 298f LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER -// 2990 RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER -// 2991 LEFT ANGLE BRACKET WITH DOT -// 2992 RIGHT ANGLE BRACKET WITH DOT -// 2993 LEFT ARC LESS-THAN BRACKET -// 2994 RIGHT ARC GREATER-THAN BRACKET -// 2995 DOUBLE LEFT ARC GREATER-THAN BRACKET -// 2996 DOUBLE RIGHT ARC LESS-THAN BRACKET -// 2997 LEFT BLACK TORTOISE SHELL BRACKET -// 2998 RIGHT BLACK TORTOISE SHELL BRACKET - { 0x2983, 0x16, 0x18, 0, 0 }, -// 2999 DOTTED FENCE -// 299a VERTICAL ZIGZAG LINE -// 299b MEASURED ANGLE OPENING LEFT -// 299c RIGHT ANGLE VARIANT WITH SQUARE -// 299d MEASURED RIGHT ANGLE WITH DOT -// 299e ANGLE WITH S INSIDE -// 299f ACUTE ANGLE -// 29a0 SPHERICAL ANGLE OPENING LEFT -// 29a1 SPHERICAL ANGLE OPENING UP -// 29a2 TURNED ANGLE -// 29a3 REVERSED ANGLE -// 29a4 ANGLE WITH UNDERBAR -// 29a5 REVERSED ANGLE WITH UNDERBAR -// 29a6 OBLIQUE ANGLE OPENING UP -// 29a7 OBLIQUE ANGLE OPENING DOWN -// 29a8 MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT -// 29a9 MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT -// 29aa MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT -// 29ab MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT -// 29ac MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP -// 29ad MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP -// 29ae MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN -// 29af MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN -// 29b0 REVERSED EMPTY SET -// 29b1 EMPTY SET WITH OVERBAR -// 29b2 EMPTY SET WITH SMALL CIRCLE ABOVE -// 29b3 EMPTY SET WITH RIGHT ARROW ABOVE -// 29b4 EMPTY SET WITH LEFT ARROW ABOVE -// 29b5 CIRCLE WITH HORIZONTAL BAR -// 29b6 CIRCLED VERTICAL BAR -// 29b7 CIRCLED PARALLEL -// 29b8 CIRCLED REVERSE SOLIDUS -// 29b9 CIRCLED PERPENDICULAR -// 29ba CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR -// 29bb CIRCLE WITH SUPERIMPOSED X -// 29bc CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN -// 29bd UP ARROW THROUGH CIRCLE -// 29be CIRCLED WHITE BULLET -// 29bf CIRCLED BULLET -// 29c0 CIRCLED LESS-THAN -// 29c1 CIRCLED GREATER-THAN -// 29c2 CIRCLE WITH SMALL CIRCLE TO THE RIGHT -// 29c3 CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT -// 29c4 SQUARED RISING DIAGONAL SLASH -// 29c5 SQUARED FALLING DIAGONAL SLASH -// 29c6 SQUARED ASTERISK -// 29c7 SQUARED SMALL CIRCLE -// 29c8 SQUARED SQUARE -// 29c9 TWO JOINED SQUARES -// 29ca TRIANGLE WITH DOT ABOVE -// 29cb TRIANGLE WITH UNDERBAR -// 29cc S IN TRIANGLE -// 29cd TRIANGLE WITH SERIFS AT BOTTOM -// 29ce RIGHT TRIANGLE ABOVE LEFT TRIANGLE -// 29cf LEFT TRIANGLE BESIDE VERTICAL BAR -// 29d0 VERTICAL BAR BESIDE RIGHT TRIANGLE -// 29d1 BOWTIE WITH LEFT HALF BLACK -// 29d2 BOWTIE WITH RIGHT HALF BLACK -// 29d3 BLACK BOWTIE -// 29d4 TIMES WITH LEFT HALF BLACK -// 29d5 TIMES WITH RIGHT HALF BLACK -// 29d6 WHITE HOURGLASS -// 29d7 BLACK HOURGLASS - { 0x2999, 0x3F, 0x8, 0, 0 }, -// 29d8 LEFT WIGGLY FENCE -// 29d9 RIGHT WIGGLY FENCE -// 29da LEFT DOUBLE WIGGLY FENCE -// 29db RIGHT DOUBLE WIGGLY FENCE - { 0x29D8, 0x4, 0x18, 0, 0 }, -// 29dc INCOMPLETE INFINITY -// 29dd TIE OVER INFINITY -// 29de INFINITY NEGATED WITH VERTICAL BAR -// 29df DOUBLE-ENDED MULTIMAP -// 29e0 SQUARE WITH CONTOURED OUTLINE -// 29e1 INCREASES AS -// 29e2 SHUFFLE PRODUCT -// 29e3 EQUALS SIGN AND SLANTED PARALLEL -// 29e4 EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE -// 29e5 IDENTICAL TO AND SLANTED PARALLEL -// 29e6 GLEICH STARK -// 29e7 THERMODYNAMIC -// 29e8 DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK -// 29e9 DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK -// 29ea BLACK DIAMOND WITH DOWN ARROW -// 29eb BLACK LOZENGE -// 29ec WHITE CIRCLE WITH DOWN ARROW -// 29ed BLACK CIRCLE WITH DOWN ARROW -// 29ee ERROR-BARRED WHITE SQUARE -// 29ef ERROR-BARRED BLACK SQUARE -// 29f0 ERROR-BARRED WHITE DIAMOND -// 29f1 ERROR-BARRED BLACK DIAMOND -// 29f2 ERROR-BARRED WHITE CIRCLE -// 29f3 ERROR-BARRED BLACK CIRCLE -// 29f4 RULE-DELAYED -// 29f5 REVERSE SOLIDUS OPERATOR -// 29f6 SOLIDUS WITH OVERBAR -// 29f7 REVERSE SOLIDUS WITH HORIZONTAL STROKE -// 29f8 BIG SOLIDUS -// 29f9 BIG REVERSE SOLIDUS -// 29fa DOUBLE PLUS -// 29fb TRIPLE PLUS - { 0x29DC, 0x20, 0x8, 0, 0 }, -// 29fc LEFT-POINTING CURVED ANGLE BRACKET -// 29fd RIGHT-POINTING CURVED ANGLE BRACKET - { 0x29FC, 0x2, 0x18, 0, 0 }, -// 29fe TINY -// 29ff MINY -// 2a00 N-ARY CIRCLED DOT OPERATOR -// 2a01 N-ARY CIRCLED PLUS OPERATOR -// 2a02 N-ARY CIRCLED TIMES OPERATOR -// 2a03 N-ARY UNION OPERATOR WITH DOT -// 2a04 N-ARY UNION OPERATOR WITH PLUS -// 2a05 N-ARY SQUARE INTERSECTION OPERATOR -// 2a06 N-ARY SQUARE UNION OPERATOR -// 2a07 TWO LOGICAL AND OPERATOR -// 2a08 TWO LOGICAL OR OPERATOR -// 2a09 N-ARY TIMES OPERATOR -// 2a0a MODULO TWO SUM -// 2a0b SUMMATION WITH INTEGRAL -// 2a0c QUADRUPLE INTEGRAL OPERATOR -// 2a0d FINITE PART INTEGRAL -// 2a0e INTEGRAL WITH DOUBLE STROKE -// 2a0f INTEGRAL AVERAGE WITH SLASH -// 2a10 CIRCULATION FUNCTION -// 2a11 ANTICLOCKWISE INTEGRATION -// 2a12 LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE -// 2a13 LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE -// 2a14 LINE INTEGRATION NOT INCLUDING THE POLE -// 2a15 INTEGRAL AROUND A POINT OPERATOR -// 2a16 QUATERNION INTEGRAL OPERATOR -// 2a17 INTEGRAL WITH LEFTWARDS ARROW WITH HOOK -// 2a18 INTEGRAL WITH TIMES SIGN -// 2a19 INTEGRAL WITH INTERSECTION -// 2a1a INTEGRAL WITH UNION -// 2a1b INTEGRAL WITH OVERBAR -// 2a1c INTEGRAL WITH UNDERBAR -// 2a1d JOIN -// 2a1e LARGE LEFT TRIANGLE OPERATOR -// 2a1f Z NOTATION SCHEMA COMPOSITION -// 2a20 Z NOTATION SCHEMA PIPING -// 2a21 Z NOTATION SCHEMA PROJECTION -// 2a22 PLUS SIGN WITH SMALL CIRCLE ABOVE -// 2a23 PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE -// 2a24 PLUS SIGN WITH TILDE ABOVE -// 2a25 PLUS SIGN WITH DOT BELOW -// 2a26 PLUS SIGN WITH TILDE BELOW -// 2a27 PLUS SIGN WITH SUBSCRIPT TWO -// 2a28 PLUS SIGN WITH BLACK TRIANGLE -// 2a29 MINUS SIGN WITH COMMA ABOVE -// 2a2a MINUS SIGN WITH DOT BELOW -// 2a2b MINUS SIGN WITH FALLING DOTS -// 2a2c MINUS SIGN WITH RISING DOTS -// 2a2d PLUS SIGN IN LEFT HALF CIRCLE -// 2a2e PLUS SIGN IN RIGHT HALF CIRCLE -// 2a2f VECTOR OR CROSS PRODUCT -// 2a30 MULTIPLICATION SIGN WITH DOT ABOVE -// 2a31 MULTIPLICATION SIGN WITH UNDERBAR -// 2a32 SEMIDIRECT PRODUCT WITH BOTTOM CLOSED -// 2a33 SMASH PRODUCT -// 2a34 MULTIPLICATION SIGN IN LEFT HALF CIRCLE -// 2a35 MULTIPLICATION SIGN IN RIGHT HALF CIRCLE -// 2a36 CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT -// 2a37 MULTIPLICATION SIGN IN DOUBLE CIRCLE -// 2a38 CIRCLED DIVISION SIGN -// 2a39 PLUS SIGN IN TRIANGLE -// 2a3a MINUS SIGN IN TRIANGLE -// 2a3b MULTIPLICATION SIGN IN TRIANGLE -// 2a3c INTERIOR PRODUCT -// 2a3d RIGHTHAND INTERIOR PRODUCT -// 2a3e Z NOTATION RELATIONAL COMPOSITION -// 2a3f AMALGAMATION OR COPRODUCT -// 2a40 INTERSECTION WITH DOT -// 2a41 UNION WITH MINUS SIGN -// 2a42 UNION WITH OVERBAR -// 2a43 INTERSECTION WITH OVERBAR -// 2a44 INTERSECTION WITH LOGICAL AND -// 2a45 UNION WITH LOGICAL OR -// 2a46 UNION ABOVE INTERSECTION -// 2a47 INTERSECTION ABOVE UNION -// 2a48 UNION ABOVE BAR ABOVE INTERSECTION -// 2a49 INTERSECTION ABOVE BAR ABOVE UNION -// 2a4a UNION BESIDE AND JOINED WITH UNION -// 2a4b INTERSECTION BESIDE AND JOINED WITH INTERSECTION -// 2a4c CLOSED UNION WITH SERIFS -// 2a4d CLOSED INTERSECTION WITH SERIFS -// 2a4e DOUBLE SQUARE INTERSECTION -// 2a4f DOUBLE SQUARE UNION -// 2a50 CLOSED UNION WITH SERIFS AND SMASH PRODUCT -// 2a51 LOGICAL AND WITH DOT ABOVE -// 2a52 LOGICAL OR WITH DOT ABOVE -// 2a53 DOUBLE LOGICAL AND -// 2a54 DOUBLE LOGICAL OR -// 2a55 TWO INTERSECTING LOGICAL AND -// 2a56 TWO INTERSECTING LOGICAL OR -// 2a57 SLOPING LARGE OR -// 2a58 SLOPING LARGE AND -// 2a59 LOGICAL OR OVERLAPPING LOGICAL AND -// 2a5a LOGICAL AND WITH MIDDLE STEM -// 2a5b LOGICAL OR WITH MIDDLE STEM -// 2a5c LOGICAL AND WITH HORIZONTAL DASH -// 2a5d LOGICAL OR WITH HORIZONTAL DASH -// 2a5e LOGICAL AND WITH DOUBLE OVERBAR -// 2a5f LOGICAL AND WITH UNDERBAR -// 2a60 LOGICAL AND WITH DOUBLE UNDERBAR -// 2a61 SMALL VEE WITH UNDERBAR -// 2a62 LOGICAL OR WITH DOUBLE OVERBAR -// 2a63 LOGICAL OR WITH DOUBLE UNDERBAR -// 2a64 Z NOTATION DOMAIN ANTIRESTRICTION -// 2a65 Z NOTATION RANGE ANTIRESTRICTION -// 2a66 EQUALS SIGN WITH DOT BELOW -// 2a67 IDENTICAL WITH DOT ABOVE -// 2a68 TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE -// 2a69 TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE -// 2a6a TILDE OPERATOR WITH DOT ABOVE -// 2a6b TILDE OPERATOR WITH RISING DOTS -// 2a6c SIMILAR MINUS SIMILAR -// 2a6d CONGRUENT WITH DOT ABOVE -// 2a6e EQUALS WITH ASTERISK -// 2a6f ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT -// 2a70 APPROXIMATELY EQUAL OR EQUAL TO -// 2a71 EQUALS SIGN ABOVE PLUS SIGN -// 2a72 PLUS SIGN ABOVE EQUALS SIGN -// 2a73 EQUALS SIGN ABOVE TILDE OPERATOR -// 2a74 DOUBLE COLON EQUAL -// 2a75 TWO CONSECUTIVE EQUALS SIGNS -// 2a76 THREE CONSECUTIVE EQUALS SIGNS -// 2a77 EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW -// 2a78 EQUIVALENT WITH FOUR DOTS ABOVE -// 2a79 LESS-THAN WITH CIRCLE INSIDE -// 2a7a GREATER-THAN WITH CIRCLE INSIDE -// 2a7b LESS-THAN WITH QUESTION MARK ABOVE -// 2a7c GREATER-THAN WITH QUESTION MARK ABOVE -// 2a7d LESS-THAN OR SLANTED EQUAL TO -// 2a7e GREATER-THAN OR SLANTED EQUAL TO -// 2a7f LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE -// 2a80 GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE -// 2a81 LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE -// 2a82 GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE -// 2a83 LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT -// 2a84 GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT -// 2a85 LESS-THAN OR APPROXIMATE -// 2a86 GREATER-THAN OR APPROXIMATE -// 2a87 LESS-THAN AND SINGLE-LINE NOT EQUAL TO -// 2a88 GREATER-THAN AND SINGLE-LINE NOT EQUAL TO -// 2a89 LESS-THAN AND NOT APPROXIMATE -// 2a8a GREATER-THAN AND NOT APPROXIMATE -// 2a8b LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN -// 2a8c GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN -// 2a8d LESS-THAN ABOVE SIMILAR OR EQUAL -// 2a8e GREATER-THAN ABOVE SIMILAR OR EQUAL -// 2a8f LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN -// 2a90 GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN -// 2a91 LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL -// 2a92 GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL -// 2a93 LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL -// 2a94 GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL -// 2a95 SLANTED EQUAL TO OR LESS-THAN -// 2a96 SLANTED EQUAL TO OR GREATER-THAN -// 2a97 SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE -// 2a98 SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE -// 2a99 DOUBLE-LINE EQUAL TO OR LESS-THAN -// 2a9a DOUBLE-LINE EQUAL TO OR GREATER-THAN -// 2a9b DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN -// 2a9c DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN -// 2a9d SIMILAR OR LESS-THAN -// 2a9e SIMILAR OR GREATER-THAN -// 2a9f SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN -// 2aa0 SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN -// 2aa1 DOUBLE NESTED LESS-THAN -// 2aa2 DOUBLE NESTED GREATER-THAN -// 2aa3 DOUBLE NESTED LESS-THAN WITH UNDERBAR -// 2aa4 GREATER-THAN OVERLAPPING LESS-THAN -// 2aa5 GREATER-THAN BESIDE LESS-THAN -// 2aa6 LESS-THAN CLOSED BY CURVE -// 2aa7 GREATER-THAN CLOSED BY CURVE -// 2aa8 LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL -// 2aa9 GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL -// 2aaa SMALLER THAN -// 2aab LARGER THAN -// 2aac SMALLER THAN OR EQUAL TO -// 2aad LARGER THAN OR EQUAL TO -// 2aae EQUALS SIGN WITH BUMPY ABOVE -// 2aaf PRECEDES ABOVE SINGLE-LINE EQUALS SIGN -// 2ab0 SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN -// 2ab1 PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO -// 2ab2 SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO -// 2ab3 PRECEDES ABOVE EQUALS SIGN -// 2ab4 SUCCEEDS ABOVE EQUALS SIGN -// 2ab5 PRECEDES ABOVE NOT EQUAL TO -// 2ab6 SUCCEEDS ABOVE NOT EQUAL TO -// 2ab7 PRECEDES ABOVE ALMOST EQUAL TO -// 2ab8 SUCCEEDS ABOVE ALMOST EQUAL TO -// 2ab9 PRECEDES ABOVE NOT ALMOST EQUAL TO -// 2aba SUCCEEDS ABOVE NOT ALMOST EQUAL TO -// 2abb DOUBLE PRECEDES -// 2abc DOUBLE SUCCEEDS -// 2abd SUBSET WITH DOT -// 2abe SUPERSET WITH DOT -// 2abf SUBSET WITH PLUS SIGN BELOW -// 2ac0 SUPERSET WITH PLUS SIGN BELOW -// 2ac1 SUBSET WITH MULTIPLICATION SIGN BELOW -// 2ac2 SUPERSET WITH MULTIPLICATION SIGN BELOW -// 2ac3 SUBSET OF OR EQUAL TO WITH DOT ABOVE -// 2ac4 SUPERSET OF OR EQUAL TO WITH DOT ABOVE -// 2ac5 SUBSET OF ABOVE EQUALS SIGN -// 2ac6 SUPERSET OF ABOVE EQUALS SIGN -// 2ac7 SUBSET OF ABOVE TILDE OPERATOR -// 2ac8 SUPERSET OF ABOVE TILDE OPERATOR -// 2ac9 SUBSET OF ABOVE ALMOST EQUAL TO -// 2aca SUPERSET OF ABOVE ALMOST EQUAL TO -// 2acb SUBSET OF ABOVE NOT EQUAL TO -// 2acc SUPERSET OF ABOVE NOT EQUAL TO -// 2acd SQUARE LEFT OPEN BOX OPERATOR -// 2ace SQUARE RIGHT OPEN BOX OPERATOR -// 2acf CLOSED SUBSET -// 2ad0 CLOSED SUPERSET -// 2ad1 CLOSED SUBSET OR EQUAL TO -// 2ad2 CLOSED SUPERSET OR EQUAL TO -// 2ad3 SUBSET ABOVE SUPERSET -// 2ad4 SUPERSET ABOVE SUBSET -// 2ad5 SUBSET ABOVE SUBSET -// 2ad6 SUPERSET ABOVE SUPERSET -// 2ad7 SUPERSET BESIDE SUBSET -// 2ad8 SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET -// 2ad9 ELEMENT OF OPENING DOWNWARDS -// 2ada PITCHFORK WITH TEE TOP -// 2adb TRANSVERSAL INTERSECTION -// 2adc FORKING -// 2add NONFORKING -// 2ade SHORT LEFT TACK -// 2adf SHORT DOWN TACK -// 2ae0 SHORT UP TACK -// 2ae1 PERPENDICULAR WITH S -// 2ae2 VERTICAL BAR TRIPLE RIGHT TURNSTILE -// 2ae3 DOUBLE VERTICAL BAR LEFT TURNSTILE -// 2ae4 VERTICAL BAR DOUBLE LEFT TURNSTILE -// 2ae5 DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE -// 2ae6 LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL -// 2ae7 SHORT DOWN TACK WITH OVERBAR -// 2ae8 SHORT UP TACK WITH UNDERBAR -// 2ae9 SHORT UP TACK ABOVE SHORT DOWN TACK -// 2aea DOUBLE DOWN TACK -// 2aeb DOUBLE UP TACK -// 2aec DOUBLE STROKE NOT SIGN -// 2aed REVERSED DOUBLE STROKE NOT SIGN -// 2aee DOES NOT DIVIDE WITH REVERSED NEGATION SLASH -// 2aef VERTICAL LINE WITH CIRCLE ABOVE -// 2af0 VERTICAL LINE WITH CIRCLE BELOW -// 2af1 DOWN TACK WITH CIRCLE BELOW -// 2af2 PARALLEL WITH HORIZONTAL STROKE -// 2af3 PARALLEL WITH TILDE OPERATOR -// 2af4 TRIPLE VERTICAL BAR BINARY RELATION -// 2af5 TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE -// 2af6 TRIPLE COLON OPERATOR -// 2af7 TRIPLE NESTED LESS-THAN -// 2af8 TRIPLE NESTED GREATER-THAN -// 2af9 DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO -// 2afa DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO -// 2afb TRIPLE SOLIDUS BINARY RELATION -// 2afc LARGE TRIPLE VERTICAL BAR OPERATOR -// 2afd DOUBLE SOLIDUS OPERATOR -// 2afe WHITE VERTICAL BAR -// 2aff N-ARY WHITE VERTICAL BAR -// 2b00 NORTH EAST WHITE ARROW -// 2b01 NORTH WEST WHITE ARROW -// 2b02 SOUTH EAST WHITE ARROW -// 2b03 SOUTH WEST WHITE ARROW -// 2b04 LEFT RIGHT WHITE ARROW -// 2b05 LEFTWARDS BLACK ARROW -// 2b06 UPWARDS BLACK ARROW -// 2b07 DOWNWARDS BLACK ARROW -// 2b08 NORTH EAST BLACK ARROW -// 2b09 NORTH WEST BLACK ARROW -// 2b0a SOUTH EAST BLACK ARROW -// 2b0b SOUTH WEST BLACK ARROW -// 2b0c LEFT RIGHT BLACK ARROW -// 2b0d UP DOWN BLACK ARROW -// 2b0e RIGHTWARDS ARROW WITH TIP DOWNWARDS -// 2b0f RIGHTWARDS ARROW WITH TIP UPWARDS -// 2b10 LEFTWARDS ARROW WITH TIP DOWNWARDS -// 2b11 LEFTWARDS ARROW WITH TIP UPWARDS -// 2b12 SQUARE WITH TOP HALF BLACK -// 2b13 SQUARE WITH BOTTOM HALF BLACK -// 2b14 SQUARE WITH UPPER RIGHT DIAGONAL HALF BLACK -// 2b15 SQUARE WITH LOWER LEFT DIAGONAL HALF BLACK -// 2b16 DIAMOND WITH LEFT HALF BLACK -// 2b17 DIAMOND WITH RIGHT HALF BLACK -// 2b18 DIAMOND WITH TOP HALF BLACK -// 2b19 DIAMOND WITH BOTTOM HALF BLACK -// 2b1a DOTTED SQUARE -// 2b1b BLACK LARGE SQUARE -// 2b1c WHITE LARGE SQUARE -// 2b1d BLACK VERY SMALL SQUARE -// 2b1e WHITE VERY SMALL SQUARE -// 2b1f BLACK PENTAGON -// 2b20 WHITE PENTAGON -// 2b21 WHITE HEXAGON -// 2b22 BLACK HEXAGON -// 2b23 HORIZONTAL BLACK HEXAGON -// 2b24 BLACK LARGE CIRCLE -// 2b25 BLACK MEDIUM DIAMOND -// 2b26 WHITE MEDIUM DIAMOND -// 2b27 BLACK MEDIUM LOZENGE -// 2b28 WHITE MEDIUM LOZENGE -// 2b29 BLACK SMALL DIAMOND -// 2b2a BLACK SMALL LOZENGE -// 2b2b WHITE SMALL LOZENGE -// 2b2c BLACK HORIZONTAL ELLIPSE -// 2b2d WHITE HORIZONTAL ELLIPSE -// 2b2e BLACK VERTICAL ELLIPSE -// 2b2f WHITE VERTICAL ELLIPSE -// 2b30 LEFT ARROW WITH SMALL CIRCLE -// 2b31 THREE LEFTWARDS ARROWS -// 2b32 LEFT ARROW WITH CIRCLED PLUS -// 2b33 LONG LEFTWARDS SQUIGGLE ARROW -// 2b34 LEFTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE -// 2b35 LEFTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE -// 2b36 LEFTWARDS TWO-HEADED ARROW FROM BAR -// 2b37 LEFTWARDS TWO-HEADED TRIPLE DASH ARROW -// 2b38 LEFTWARDS ARROW WITH DOTTED STEM -// 2b39 LEFTWARDS ARROW WITH TAIL WITH VERTICAL STROKE -// 2b3a LEFTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE -// 2b3b LEFTWARDS TWO-HEADED ARROW WITH TAIL -// 2b3c LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE -// 2b3d LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE -// 2b3e LEFTWARDS ARROW THROUGH X -// 2b3f WAVE ARROW POINTING DIRECTLY LEFT -// 2b40 EQUALS SIGN ABOVE LEFTWARDS ARROW -// 2b41 REVERSE TILDE OPERATOR ABOVE LEFTWARDS ARROW -// 2b42 LEFTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO -// 2b43 RIGHTWARDS ARROW THROUGH GREATER-THAN -// 2b44 RIGHTWARDS ARROW THROUGH SUPERSET -// 2b45 LEFTWARDS QUADRUPLE ARROW -// 2b46 RIGHTWARDS QUADRUPLE ARROW -// 2b47 REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW -// 2b48 RIGHTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO -// 2b49 TILDE OPERATOR ABOVE LEFTWARDS ARROW -// 2b4a LEFTWARDS ARROW ABOVE ALMOST EQUAL TO -// 2b4b LEFTWARDS ARROW ABOVE REVERSE TILDE OPERATOR -// 2b4c RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR -// 2b4d DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW -// 2b4e SHORT SLANTED NORTH ARROW -// 2b4f SHORT BACKSLANTED SOUTH ARROW -// 2b50 WHITE MEDIUM STAR -// 2b51 BLACK SMALL STAR -// 2b52 WHITE SMALL STAR -// 2b53 BLACK RIGHT-POINTING PENTAGON -// 2b54 WHITE RIGHT-POINTING PENTAGON -// 2b55 HEAVY LARGE CIRCLE -// 2b56 HEAVY OVAL WITH OVAL INSIDE -// 2b57 HEAVY CIRCLE WITH CIRCLE INSIDE -// 2b58 HEAVY CIRCLE -// 2b59 HEAVY CIRCLED SALTIRE -// 2b5a SLANTED NORTH ARROW WITH HOOKED HEAD -// 2b5b BACKSLANTED SOUTH ARROW WITH HOOKED TAIL -// 2b5c SLANTED NORTH ARROW WITH HORIZONTAL TAIL -// 2b5d BACKSLANTED SOUTH ARROW WITH HORIZONTAL TAIL -// 2b5e BENT ARROW POINTING DOWNWARDS THEN NORTH EAST -// 2b5f SHORT BENT ARROW POINTING DOWNWARDS THEN NORTH EAST -// 2b60 LEFTWARDS TRIANGLE-HEADED ARROW -// 2b61 UPWARDS TRIANGLE-HEADED ARROW -// 2b62 RIGHTWARDS TRIANGLE-HEADED ARROW -// 2b63 DOWNWARDS TRIANGLE-HEADED ARROW -// 2b64 LEFT RIGHT TRIANGLE-HEADED ARROW -// 2b65 UP DOWN TRIANGLE-HEADED ARROW -// 2b66 NORTH WEST TRIANGLE-HEADED ARROW -// 2b67 NORTH EAST TRIANGLE-HEADED ARROW -// 2b68 SOUTH EAST TRIANGLE-HEADED ARROW -// 2b69 SOUTH WEST TRIANGLE-HEADED ARROW -// 2b6a LEFTWARDS TRIANGLE-HEADED DASHED ARROW -// 2b6b UPWARDS TRIANGLE-HEADED DASHED ARROW -// 2b6c RIGHTWARDS TRIANGLE-HEADED DASHED ARROW -// 2b6d DOWNWARDS TRIANGLE-HEADED DASHED ARROW -// 2b6e CLOCKWISE TRIANGLE-HEADED OPEN CIRCLE ARROW -// 2b6f ANTICLOCKWISE TRIANGLE-HEADED OPEN CIRCLE ARROW -// 2b70 LEFTWARDS TRIANGLE-HEADED ARROW TO BAR -// 2b71 UPWARDS TRIANGLE-HEADED ARROW TO BAR -// 2b72 RIGHTWARDS TRIANGLE-HEADED ARROW TO BAR -// 2b73 DOWNWARDS TRIANGLE-HEADED ARROW TO BAR - { 0x29FE, 0x176, 0x8, 0, 0 }, -// 2b76 NORTH WEST TRIANGLE-HEADED ARROW TO BAR -// 2b77 NORTH EAST TRIANGLE-HEADED ARROW TO BAR -// 2b78 SOUTH EAST TRIANGLE-HEADED ARROW TO BAR -// 2b79 SOUTH WEST TRIANGLE-HEADED ARROW TO BAR -// 2b7a LEFTWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE -// 2b7b UPWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE -// 2b7c RIGHTWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE -// 2b7d DOWNWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE -// 2b7e HORIZONTAL TAB KEY -// 2b7f VERTICAL TAB KEY -// 2b80 LEFTWARDS TRIANGLE-HEADED ARROW OVER RIGHTWARDS TRIANGLE-HEADED ARROW -// 2b81 UPWARDS TRIANGLE-HEADED ARROW LEFTWARDS OF DOWNWARDS TRIANGLE-HEADED ARROW -// 2b82 RIGHTWARDS TRIANGLE-HEADED ARROW OVER LEFTWARDS TRIANGLE-HEADED ARROW -// 2b83 DOWNWARDS TRIANGLE-HEADED ARROW LEFTWARDS OF UPWARDS TRIANGLE-HEADED ARROW -// 2b84 LEFTWARDS TRIANGLE-HEADED PAIRED ARROWS -// 2b85 UPWARDS TRIANGLE-HEADED PAIRED ARROWS -// 2b86 RIGHTWARDS TRIANGLE-HEADED PAIRED ARROWS -// 2b87 DOWNWARDS TRIANGLE-HEADED PAIRED ARROWS -// 2b88 LEFTWARDS BLACK CIRCLED WHITE ARROW -// 2b89 UPWARDS BLACK CIRCLED WHITE ARROW -// 2b8a RIGHTWARDS BLACK CIRCLED WHITE ARROW -// 2b8b DOWNWARDS BLACK CIRCLED WHITE ARROW -// 2b8c ANTICLOCKWISE TRIANGLE-HEADED RIGHT U-SHAPED ARROW -// 2b8d ANTICLOCKWISE TRIANGLE-HEADED BOTTOM U-SHAPED ARROW -// 2b8e ANTICLOCKWISE TRIANGLE-HEADED LEFT U-SHAPED ARROW -// 2b8f ANTICLOCKWISE TRIANGLE-HEADED TOP U-SHAPED ARROW -// 2b90 RETURN LEFT -// 2b91 RETURN RIGHT -// 2b92 NEWLINE LEFT -// 2b93 NEWLINE RIGHT -// 2b94 FOUR CORNER ARROWS CIRCLING ANTICLOCKWISE -// 2b95 RIGHTWARDS BLACK ARROW - { 0x2B76, 0x20, 0x8, 0, 0 }, -// 2b98 THREE-D TOP-LIGHTED LEFTWARDS EQUILATERAL ARROWHEAD -// 2b99 THREE-D RIGHT-LIGHTED UPWARDS EQUILATERAL ARROWHEAD -// 2b9a THREE-D TOP-LIGHTED RIGHTWARDS EQUILATERAL ARROWHEAD -// 2b9b THREE-D LEFT-LIGHTED DOWNWARDS EQUILATERAL ARROWHEAD -// 2b9c BLACK LEFTWARDS EQUILATERAL ARROWHEAD -// 2b9d BLACK UPWARDS EQUILATERAL ARROWHEAD -// 2b9e BLACK RIGHTWARDS EQUILATERAL ARROWHEAD -// 2b9f BLACK DOWNWARDS EQUILATERAL ARROWHEAD -// 2ba0 DOWNWARDS TRIANGLE-HEADED ARROW WITH LONG TIP LEFTWARDS -// 2ba1 DOWNWARDS TRIANGLE-HEADED ARROW WITH LONG TIP RIGHTWARDS -// 2ba2 UPWARDS TRIANGLE-HEADED ARROW WITH LONG TIP LEFTWARDS -// 2ba3 UPWARDS TRIANGLE-HEADED ARROW WITH LONG TIP RIGHTWARDS -// 2ba4 LEFTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP UPWARDS -// 2ba5 RIGHTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP UPWARDS -// 2ba6 LEFTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP DOWNWARDS -// 2ba7 RIGHTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP DOWNWARDS -// 2ba8 BLACK CURVED DOWNWARDS AND LEFTWARDS ARROW -// 2ba9 BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW -// 2baa BLACK CURVED UPWARDS AND LEFTWARDS ARROW -// 2bab BLACK CURVED UPWARDS AND RIGHTWARDS ARROW -// 2bac BLACK CURVED LEFTWARDS AND UPWARDS ARROW -// 2bad BLACK CURVED RIGHTWARDS AND UPWARDS ARROW -// 2bae BLACK CURVED LEFTWARDS AND DOWNWARDS ARROW -// 2baf BLACK CURVED RIGHTWARDS AND DOWNWARDS ARROW -// 2bb0 RIBBON ARROW DOWN LEFT -// 2bb1 RIBBON ARROW DOWN RIGHT -// 2bb2 RIBBON ARROW UP LEFT -// 2bb3 RIBBON ARROW UP RIGHT -// 2bb4 RIBBON ARROW LEFT UP -// 2bb5 RIBBON ARROW RIGHT UP -// 2bb6 RIBBON ARROW LEFT DOWN -// 2bb7 RIBBON ARROW RIGHT DOWN -// 2bb8 UPWARDS WHITE ARROW FROM BAR WITH HORIZONTAL BAR -// 2bb9 UP ARROWHEAD IN A RECTANGLE BOX - { 0x2B98, 0x22, 0x8, 0, 0 }, -// 2bbd BALLOT BOX WITH LIGHT X -// 2bbe CIRCLED X -// 2bbf CIRCLED BOLD X -// 2bc0 BLACK SQUARE CENTRED -// 2bc1 BLACK DIAMOND CENTRED -// 2bc2 TURNED BLACK PENTAGON -// 2bc3 HORIZONTAL BLACK OCTAGON -// 2bc4 BLACK OCTAGON -// 2bc5 BLACK MEDIUM UP-POINTING TRIANGLE CENTRED -// 2bc6 BLACK MEDIUM DOWN-POINTING TRIANGLE CENTRED -// 2bc7 BLACK MEDIUM LEFT-POINTING TRIANGLE CENTRED -// 2bc8 BLACK MEDIUM RIGHT-POINTING TRIANGLE CENTRED - { 0x2BBD, 0xC, 0x8, 0, 0 }, -// 2bca TOP HALF BLACK CIRCLE -// 2bcb BOTTOM HALF BLACK CIRCLE -// 2bcc LIGHT FOUR POINTED BLACK CUSP -// 2bcd ROTATED LIGHT FOUR POINTED BLACK CUSP -// 2bce WHITE FOUR POINTED CUSP -// 2bcf ROTATED WHITE FOUR POINTED CUSP -// 2bd0 SQUARE POSITION INDICATOR -// 2bd1 UNCERTAINTY SIGN - { 0x2BCA, 0x8, 0x8, 0, 0 }, -// 2c00 GLAGOLITIC CAPITAL LETTER AZU -// 2c01 GLAGOLITIC CAPITAL LETTER BUKY -// 2c02 GLAGOLITIC CAPITAL LETTER VEDE -// 2c03 GLAGOLITIC CAPITAL LETTER GLAGOLI -// 2c04 GLAGOLITIC CAPITAL LETTER DOBRO -// 2c05 GLAGOLITIC CAPITAL LETTER YESTU -// 2c06 GLAGOLITIC CAPITAL LETTER ZHIVETE -// 2c07 GLAGOLITIC CAPITAL LETTER DZELO -// 2c08 GLAGOLITIC CAPITAL LETTER ZEMLJA -// 2c09 GLAGOLITIC CAPITAL LETTER IZHE -// 2c0a GLAGOLITIC CAPITAL LETTER INITIAL IZHE -// 2c0b GLAGOLITIC CAPITAL LETTER I -// 2c0c GLAGOLITIC CAPITAL LETTER DJERVI -// 2c0d GLAGOLITIC CAPITAL LETTER KAKO -// 2c0e GLAGOLITIC CAPITAL LETTER LJUDIJE -// 2c0f GLAGOLITIC CAPITAL LETTER MYSLITE -// 2c10 GLAGOLITIC CAPITAL LETTER NASHI -// 2c11 GLAGOLITIC CAPITAL LETTER ONU -// 2c12 GLAGOLITIC CAPITAL LETTER POKOJI -// 2c13 GLAGOLITIC CAPITAL LETTER RITSI -// 2c14 GLAGOLITIC CAPITAL LETTER SLOVO -// 2c15 GLAGOLITIC CAPITAL LETTER TVRIDO -// 2c16 GLAGOLITIC CAPITAL LETTER UKU -// 2c17 GLAGOLITIC CAPITAL LETTER FRITU -// 2c18 GLAGOLITIC CAPITAL LETTER HERU -// 2c19 GLAGOLITIC CAPITAL LETTER OTU -// 2c1a GLAGOLITIC CAPITAL LETTER PE -// 2c1b GLAGOLITIC CAPITAL LETTER SHTA -// 2c1c GLAGOLITIC CAPITAL LETTER TSI -// 2c1d GLAGOLITIC CAPITAL LETTER CHRIVI -// 2c1e GLAGOLITIC CAPITAL LETTER SHA -// 2c1f GLAGOLITIC CAPITAL LETTER YERU -// 2c20 GLAGOLITIC CAPITAL LETTER YERI -// 2c21 GLAGOLITIC CAPITAL LETTER YATI -// 2c22 GLAGOLITIC CAPITAL LETTER SPIDERY HA -// 2c23 GLAGOLITIC CAPITAL LETTER YU -// 2c24 GLAGOLITIC CAPITAL LETTER SMALL YUS -// 2c25 GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL -// 2c26 GLAGOLITIC CAPITAL LETTER YO -// 2c27 GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS -// 2c28 GLAGOLITIC CAPITAL LETTER BIG YUS -// 2c29 GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS -// 2c2a GLAGOLITIC CAPITAL LETTER FITA -// 2c2b GLAGOLITIC CAPITAL LETTER IZHITSA -// 2c2c GLAGOLITIC CAPITAL LETTER SHTAPIC -// 2c2d GLAGOLITIC CAPITAL LETTER TROKUTASTI A -// 2c2e GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE - { 0x2C00, 0x2F, 0x89, 48, 0 }, -// 2c30 GLAGOLITIC SMALL LETTER AZU -// 2c31 GLAGOLITIC SMALL LETTER BUKY -// 2c32 GLAGOLITIC SMALL LETTER VEDE -// 2c33 GLAGOLITIC SMALL LETTER GLAGOLI -// 2c34 GLAGOLITIC SMALL LETTER DOBRO -// 2c35 GLAGOLITIC SMALL LETTER YESTU -// 2c36 GLAGOLITIC SMALL LETTER ZHIVETE -// 2c37 GLAGOLITIC SMALL LETTER DZELO -// 2c38 GLAGOLITIC SMALL LETTER ZEMLJA -// 2c39 GLAGOLITIC SMALL LETTER IZHE -// 2c3a GLAGOLITIC SMALL LETTER INITIAL IZHE -// 2c3b GLAGOLITIC SMALL LETTER I -// 2c3c GLAGOLITIC SMALL LETTER DJERVI -// 2c3d GLAGOLITIC SMALL LETTER KAKO -// 2c3e GLAGOLITIC SMALL LETTER LJUDIJE -// 2c3f GLAGOLITIC SMALL LETTER MYSLITE -// 2c40 GLAGOLITIC SMALL LETTER NASHI -// 2c41 GLAGOLITIC SMALL LETTER ONU -// 2c42 GLAGOLITIC SMALL LETTER POKOJI -// 2c43 GLAGOLITIC SMALL LETTER RITSI -// 2c44 GLAGOLITIC SMALL LETTER SLOVO -// 2c45 GLAGOLITIC SMALL LETTER TVRIDO -// 2c46 GLAGOLITIC SMALL LETTER UKU -// 2c47 GLAGOLITIC SMALL LETTER FRITU -// 2c48 GLAGOLITIC SMALL LETTER HERU -// 2c49 GLAGOLITIC SMALL LETTER OTU -// 2c4a GLAGOLITIC SMALL LETTER PE -// 2c4b GLAGOLITIC SMALL LETTER SHTA -// 2c4c GLAGOLITIC SMALL LETTER TSI -// 2c4d GLAGOLITIC SMALL LETTER CHRIVI -// 2c4e GLAGOLITIC SMALL LETTER SHA -// 2c4f GLAGOLITIC SMALL LETTER YERU -// 2c50 GLAGOLITIC SMALL LETTER YERI -// 2c51 GLAGOLITIC SMALL LETTER YATI -// 2c52 GLAGOLITIC SMALL LETTER SPIDERY HA -// 2c53 GLAGOLITIC SMALL LETTER YU -// 2c54 GLAGOLITIC SMALL LETTER SMALL YUS -// 2c55 GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL -// 2c56 GLAGOLITIC SMALL LETTER YO -// 2c57 GLAGOLITIC SMALL LETTER IOTATED SMALL YUS -// 2c58 GLAGOLITIC SMALL LETTER BIG YUS -// 2c59 GLAGOLITIC SMALL LETTER IOTATED BIG YUS -// 2c5a GLAGOLITIC SMALL LETTER FITA -// 2c5b GLAGOLITIC SMALL LETTER IZHITSA -// 2c5c GLAGOLITIC SMALL LETTER SHTAPIC -// 2c5d GLAGOLITIC SMALL LETTER TROKUTASTI A -// 2c5e GLAGOLITIC SMALL LETTER LATINATE MYSLITE - { 0x2C30, 0x2F, 0x49, 0, -48 }, -// 2c60 LATIN CAPITAL LETTER L WITH DOUBLE BAR - { 0x2C60, 0x1, 0x89, 1, 0 }, -// 2c61 LATIN SMALL LETTER L WITH DOUBLE BAR - { 0x2C61, 0x1, 0x49, 0, -1 }, -// 2c62 LATIN CAPITAL LETTER L WITH MIDDLE TILDE - { 0x2C62, 0x1, 0x89, -10743, 0 }, -// 2c63 LATIN CAPITAL LETTER P WITH STROKE - { 0x2C63, 0x1, 0x89, -3814, 0 }, -// 2c64 LATIN CAPITAL LETTER R WITH TAIL - { 0x2C64, 0x1, 0x89, -10727, 0 }, -// 2c65 LATIN SMALL LETTER A WITH STROKE - { 0x2C65, 0x1, 0x49, 0, -10795 }, -// 2c66 LATIN SMALL LETTER T WITH DIAGONAL STROKE - { 0x2C66, 0x1, 0x49, 0, -10792 }, -// 2c67 LATIN CAPITAL LETTER H WITH DESCENDER - { 0x2C67, 0x1, 0x89, 1, 0 }, -// 2c68 LATIN SMALL LETTER H WITH DESCENDER - { 0x2C68, 0x1, 0x49, 0, -1 }, -// 2c69 LATIN CAPITAL LETTER K WITH DESCENDER - { 0x2C69, 0x1, 0x89, 1, 0 }, -// 2c6a LATIN SMALL LETTER K WITH DESCENDER - { 0x2C6A, 0x1, 0x49, 0, -1 }, -// 2c6b LATIN CAPITAL LETTER Z WITH DESCENDER - { 0x2C6B, 0x1, 0x89, 1, 0 }, -// 2c6c LATIN SMALL LETTER Z WITH DESCENDER - { 0x2C6C, 0x1, 0x49, 0, -1 }, -// 2c6d LATIN CAPITAL LETTER ALPHA - { 0x2C6D, 0x1, 0x89, -10780, 0 }, -// 2c6e LATIN CAPITAL LETTER M WITH HOOK - { 0x2C6E, 0x1, 0x89, -10749, 0 }, -// 2c6f LATIN CAPITAL LETTER TURNED A - { 0x2C6F, 0x1, 0x89, -10783, 0 }, -// 2c70 LATIN CAPITAL LETTER TURNED ALPHA - { 0x2C70, 0x1, 0x89, -10782, 0 }, -// 2c71 LATIN SMALL LETTER V WITH RIGHT HOOK - { 0x2C71, 0x1, 0x49, 0, 0 }, -// 2c72 LATIN CAPITAL LETTER W WITH HOOK - { 0x2C72, 0x1, 0x89, 1, 0 }, -// 2c73 LATIN SMALL LETTER W WITH HOOK - { 0x2C73, 0x1, 0x49, 0, -1 }, -// 2c74 LATIN SMALL LETTER V WITH CURL - { 0x2C74, 0x1, 0x49, 0, 0 }, -// 2c75 LATIN CAPITAL LETTER HALF H - { 0x2C75, 0x1, 0x89, 1, 0 }, -// 2c76 LATIN SMALL LETTER HALF H - { 0x2C76, 0x1, 0x49, 0, -1 }, -// 2c77 LATIN SMALL LETTER TAILLESS PHI -// 2c78 LATIN SMALL LETTER E WITH NOTCH -// 2c79 LATIN SMALL LETTER TURNED R WITH TAIL -// 2c7a LATIN SMALL LETTER O WITH LOW RING INSIDE -// 2c7b LATIN LETTER SMALL CAPITAL TURNED E - { 0x2C77, 0x5, 0x49, 0, 0 }, -// 2c7c LATIN SUBSCRIPT SMALL LETTER J -// 2c7d MODIFIER LETTER CAPITAL V - { 0x2C7C, 0x2, 0x9, 0, 0 }, -// 2c7e LATIN CAPITAL LETTER S WITH SWASH TAIL -// 2c7f LATIN CAPITAL LETTER Z WITH SWASH TAIL - { 0x2C7E, 0x2, 0x89, -10815, 0 }, -// 2c80 COPTIC CAPITAL LETTER ALFA - { 0x2C80, 0x1, 0x89, 1, 0 }, -// 2c81 COPTIC SMALL LETTER ALFA - { 0x2C81, 0x1, 0x49, 0, -1 }, -// 2c82 COPTIC CAPITAL LETTER VIDA - { 0x2C82, 0x1, 0x89, 1, 0 }, -// 2c83 COPTIC SMALL LETTER VIDA - { 0x2C83, 0x1, 0x49, 0, -1 }, -// 2c84 COPTIC CAPITAL LETTER GAMMA - { 0x2C84, 0x1, 0x89, 1, 0 }, -// 2c85 COPTIC SMALL LETTER GAMMA - { 0x2C85, 0x1, 0x49, 0, -1 }, -// 2c86 COPTIC CAPITAL LETTER DALDA - { 0x2C86, 0x1, 0x89, 1, 0 }, -// 2c87 COPTIC SMALL LETTER DALDA - { 0x2C87, 0x1, 0x49, 0, -1 }, -// 2c88 COPTIC CAPITAL LETTER EIE - { 0x2C88, 0x1, 0x89, 1, 0 }, -// 2c89 COPTIC SMALL LETTER EIE - { 0x2C89, 0x1, 0x49, 0, -1 }, -// 2c8a COPTIC CAPITAL LETTER SOU - { 0x2C8A, 0x1, 0x89, 1, 0 }, -// 2c8b COPTIC SMALL LETTER SOU - { 0x2C8B, 0x1, 0x49, 0, -1 }, -// 2c8c COPTIC CAPITAL LETTER ZATA - { 0x2C8C, 0x1, 0x89, 1, 0 }, -// 2c8d COPTIC SMALL LETTER ZATA - { 0x2C8D, 0x1, 0x49, 0, -1 }, -// 2c8e COPTIC CAPITAL LETTER HATE - { 0x2C8E, 0x1, 0x89, 1, 0 }, -// 2c8f COPTIC SMALL LETTER HATE - { 0x2C8F, 0x1, 0x49, 0, -1 }, -// 2c90 COPTIC CAPITAL LETTER THETHE - { 0x2C90, 0x1, 0x89, 1, 0 }, -// 2c91 COPTIC SMALL LETTER THETHE - { 0x2C91, 0x1, 0x49, 0, -1 }, -// 2c92 COPTIC CAPITAL LETTER IAUDA - { 0x2C92, 0x1, 0x89, 1, 0 }, -// 2c93 COPTIC SMALL LETTER IAUDA - { 0x2C93, 0x1, 0x49, 0, -1 }, -// 2c94 COPTIC CAPITAL LETTER KAPA - { 0x2C94, 0x1, 0x89, 1, 0 }, -// 2c95 COPTIC SMALL LETTER KAPA - { 0x2C95, 0x1, 0x49, 0, -1 }, -// 2c96 COPTIC CAPITAL LETTER LAULA - { 0x2C96, 0x1, 0x89, 1, 0 }, -// 2c97 COPTIC SMALL LETTER LAULA - { 0x2C97, 0x1, 0x49, 0, -1 }, -// 2c98 COPTIC CAPITAL LETTER MI - { 0x2C98, 0x1, 0x89, 1, 0 }, -// 2c99 COPTIC SMALL LETTER MI - { 0x2C99, 0x1, 0x49, 0, -1 }, -// 2c9a COPTIC CAPITAL LETTER NI - { 0x2C9A, 0x1, 0x89, 1, 0 }, -// 2c9b COPTIC SMALL LETTER NI - { 0x2C9B, 0x1, 0x49, 0, -1 }, -// 2c9c COPTIC CAPITAL LETTER KSI - { 0x2C9C, 0x1, 0x89, 1, 0 }, -// 2c9d COPTIC SMALL LETTER KSI - { 0x2C9D, 0x1, 0x49, 0, -1 }, -// 2c9e COPTIC CAPITAL LETTER O - { 0x2C9E, 0x1, 0x89, 1, 0 }, -// 2c9f COPTIC SMALL LETTER O - { 0x2C9F, 0x1, 0x49, 0, -1 }, -// 2ca0 COPTIC CAPITAL LETTER PI - { 0x2CA0, 0x1, 0x89, 1, 0 }, -// 2ca1 COPTIC SMALL LETTER PI - { 0x2CA1, 0x1, 0x49, 0, -1 }, -// 2ca2 COPTIC CAPITAL LETTER RO - { 0x2CA2, 0x1, 0x89, 1, 0 }, -// 2ca3 COPTIC SMALL LETTER RO - { 0x2CA3, 0x1, 0x49, 0, -1 }, -// 2ca4 COPTIC CAPITAL LETTER SIMA - { 0x2CA4, 0x1, 0x89, 1, 0 }, -// 2ca5 COPTIC SMALL LETTER SIMA - { 0x2CA5, 0x1, 0x49, 0, -1 }, -// 2ca6 COPTIC CAPITAL LETTER TAU - { 0x2CA6, 0x1, 0x89, 1, 0 }, -// 2ca7 COPTIC SMALL LETTER TAU - { 0x2CA7, 0x1, 0x49, 0, -1 }, -// 2ca8 COPTIC CAPITAL LETTER UA - { 0x2CA8, 0x1, 0x89, 1, 0 }, -// 2ca9 COPTIC SMALL LETTER UA - { 0x2CA9, 0x1, 0x49, 0, -1 }, -// 2caa COPTIC CAPITAL LETTER FI - { 0x2CAA, 0x1, 0x89, 1, 0 }, -// 2cab COPTIC SMALL LETTER FI - { 0x2CAB, 0x1, 0x49, 0, -1 }, -// 2cac COPTIC CAPITAL LETTER KHI - { 0x2CAC, 0x1, 0x89, 1, 0 }, -// 2cad COPTIC SMALL LETTER KHI - { 0x2CAD, 0x1, 0x49, 0, -1 }, -// 2cae COPTIC CAPITAL LETTER PSI - { 0x2CAE, 0x1, 0x89, 1, 0 }, -// 2caf COPTIC SMALL LETTER PSI - { 0x2CAF, 0x1, 0x49, 0, -1 }, -// 2cb0 COPTIC CAPITAL LETTER OOU - { 0x2CB0, 0x1, 0x89, 1, 0 }, -// 2cb1 COPTIC SMALL LETTER OOU - { 0x2CB1, 0x1, 0x49, 0, -1 }, -// 2cb2 COPTIC CAPITAL LETTER DIALECT-P ALEF - { 0x2CB2, 0x1, 0x89, 1, 0 }, -// 2cb3 COPTIC SMALL LETTER DIALECT-P ALEF - { 0x2CB3, 0x1, 0x49, 0, -1 }, -// 2cb4 COPTIC CAPITAL LETTER OLD COPTIC AIN - { 0x2CB4, 0x1, 0x89, 1, 0 }, -// 2cb5 COPTIC SMALL LETTER OLD COPTIC AIN - { 0x2CB5, 0x1, 0x49, 0, -1 }, -// 2cb6 COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE - { 0x2CB6, 0x1, 0x89, 1, 0 }, -// 2cb7 COPTIC SMALL LETTER CRYPTOGRAMMIC EIE - { 0x2CB7, 0x1, 0x49, 0, -1 }, -// 2cb8 COPTIC CAPITAL LETTER DIALECT-P KAPA - { 0x2CB8, 0x1, 0x89, 1, 0 }, -// 2cb9 COPTIC SMALL LETTER DIALECT-P KAPA - { 0x2CB9, 0x1, 0x49, 0, -1 }, -// 2cba COPTIC CAPITAL LETTER DIALECT-P NI - { 0x2CBA, 0x1, 0x89, 1, 0 }, -// 2cbb COPTIC SMALL LETTER DIALECT-P NI - { 0x2CBB, 0x1, 0x49, 0, -1 }, -// 2cbc COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI - { 0x2CBC, 0x1, 0x89, 1, 0 }, -// 2cbd COPTIC SMALL LETTER CRYPTOGRAMMIC NI - { 0x2CBD, 0x1, 0x49, 0, -1 }, -// 2cbe COPTIC CAPITAL LETTER OLD COPTIC OOU - { 0x2CBE, 0x1, 0x89, 1, 0 }, -// 2cbf COPTIC SMALL LETTER OLD COPTIC OOU - { 0x2CBF, 0x1, 0x49, 0, -1 }, -// 2cc0 COPTIC CAPITAL LETTER SAMPI - { 0x2CC0, 0x1, 0x89, 1, 0 }, -// 2cc1 COPTIC SMALL LETTER SAMPI - { 0x2CC1, 0x1, 0x49, 0, -1 }, -// 2cc2 COPTIC CAPITAL LETTER CROSSED SHEI - { 0x2CC2, 0x1, 0x89, 1, 0 }, -// 2cc3 COPTIC SMALL LETTER CROSSED SHEI - { 0x2CC3, 0x1, 0x49, 0, -1 }, -// 2cc4 COPTIC CAPITAL LETTER OLD COPTIC SHEI - { 0x2CC4, 0x1, 0x89, 1, 0 }, -// 2cc5 COPTIC SMALL LETTER OLD COPTIC SHEI - { 0x2CC5, 0x1, 0x49, 0, -1 }, -// 2cc6 COPTIC CAPITAL LETTER OLD COPTIC ESH - { 0x2CC6, 0x1, 0x89, 1, 0 }, -// 2cc7 COPTIC SMALL LETTER OLD COPTIC ESH - { 0x2CC7, 0x1, 0x49, 0, -1 }, -// 2cc8 COPTIC CAPITAL LETTER AKHMIMIC KHEI - { 0x2CC8, 0x1, 0x89, 1, 0 }, -// 2cc9 COPTIC SMALL LETTER AKHMIMIC KHEI - { 0x2CC9, 0x1, 0x49, 0, -1 }, -// 2cca COPTIC CAPITAL LETTER DIALECT-P HORI - { 0x2CCA, 0x1, 0x89, 1, 0 }, -// 2ccb COPTIC SMALL LETTER DIALECT-P HORI - { 0x2CCB, 0x1, 0x49, 0, -1 }, -// 2ccc COPTIC CAPITAL LETTER OLD COPTIC HORI - { 0x2CCC, 0x1, 0x89, 1, 0 }, -// 2ccd COPTIC SMALL LETTER OLD COPTIC HORI - { 0x2CCD, 0x1, 0x49, 0, -1 }, -// 2cce COPTIC CAPITAL LETTER OLD COPTIC HA - { 0x2CCE, 0x1, 0x89, 1, 0 }, -// 2ccf COPTIC SMALL LETTER OLD COPTIC HA - { 0x2CCF, 0x1, 0x49, 0, -1 }, -// 2cd0 COPTIC CAPITAL LETTER L-SHAPED HA - { 0x2CD0, 0x1, 0x89, 1, 0 }, -// 2cd1 COPTIC SMALL LETTER L-SHAPED HA - { 0x2CD1, 0x1, 0x49, 0, -1 }, -// 2cd2 COPTIC CAPITAL LETTER OLD COPTIC HEI - { 0x2CD2, 0x1, 0x89, 1, 0 }, -// 2cd3 COPTIC SMALL LETTER OLD COPTIC HEI - { 0x2CD3, 0x1, 0x49, 0, -1 }, -// 2cd4 COPTIC CAPITAL LETTER OLD COPTIC HAT - { 0x2CD4, 0x1, 0x89, 1, 0 }, -// 2cd5 COPTIC SMALL LETTER OLD COPTIC HAT - { 0x2CD5, 0x1, 0x49, 0, -1 }, -// 2cd6 COPTIC CAPITAL LETTER OLD COPTIC GANGIA - { 0x2CD6, 0x1, 0x89, 1, 0 }, -// 2cd7 COPTIC SMALL LETTER OLD COPTIC GANGIA - { 0x2CD7, 0x1, 0x49, 0, -1 }, -// 2cd8 COPTIC CAPITAL LETTER OLD COPTIC DJA - { 0x2CD8, 0x1, 0x89, 1, 0 }, -// 2cd9 COPTIC SMALL LETTER OLD COPTIC DJA - { 0x2CD9, 0x1, 0x49, 0, -1 }, -// 2cda COPTIC CAPITAL LETTER OLD COPTIC SHIMA - { 0x2CDA, 0x1, 0x89, 1, 0 }, -// 2cdb COPTIC SMALL LETTER OLD COPTIC SHIMA - { 0x2CDB, 0x1, 0x49, 0, -1 }, -// 2cdc COPTIC CAPITAL LETTER OLD NUBIAN SHIMA - { 0x2CDC, 0x1, 0x89, 1, 0 }, -// 2cdd COPTIC SMALL LETTER OLD NUBIAN SHIMA - { 0x2CDD, 0x1, 0x49, 0, -1 }, -// 2cde COPTIC CAPITAL LETTER OLD NUBIAN NGI - { 0x2CDE, 0x1, 0x89, 1, 0 }, -// 2cdf COPTIC SMALL LETTER OLD NUBIAN NGI - { 0x2CDF, 0x1, 0x49, 0, -1 }, -// 2ce0 COPTIC CAPITAL LETTER OLD NUBIAN NYI - { 0x2CE0, 0x1, 0x89, 1, 0 }, -// 2ce1 COPTIC SMALL LETTER OLD NUBIAN NYI - { 0x2CE1, 0x1, 0x49, 0, -1 }, -// 2ce2 COPTIC CAPITAL LETTER OLD NUBIAN WAU - { 0x2CE2, 0x1, 0x89, 1, 0 }, -// 2ce3 COPTIC SMALL LETTER OLD NUBIAN WAU - { 0x2CE3, 0x1, 0x49, 0, -1 }, -// 2ce4 COPTIC SYMBOL KAI - { 0x2CE4, 0x1, 0x49, 0, 0 }, -// 2ce5 COPTIC SYMBOL MI RO -// 2ce6 COPTIC SYMBOL PI RO -// 2ce7 COPTIC SYMBOL STAUROS -// 2ce8 COPTIC SYMBOL TAU RO -// 2ce9 COPTIC SYMBOL KHI RO -// 2cea COPTIC SYMBOL SHIMA SIMA - { 0x2CE5, 0x6, 0x8, 0, 0 }, -// 2ceb COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI - { 0x2CEB, 0x1, 0x89, 1, 0 }, -// 2cec COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI - { 0x2CEC, 0x1, 0x49, 0, -1 }, -// 2ced COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA - { 0x2CED, 0x1, 0x89, 1, 0 }, -// 2cee COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA - { 0x2CEE, 0x1, 0x49, 0, -1 }, -// 2cef COPTIC COMBINING NI ABOVE -// 2cf0 COPTIC COMBINING SPIRITUS ASPER -// 2cf1 COPTIC COMBINING SPIRITUS LENIS - { 0x2CEF, 0x3, 0x0, 0, 0 }, -// 2cf2 COPTIC CAPITAL LETTER BOHAIRIC KHEI - { 0x2CF2, 0x1, 0x89, 1, 0 }, -// 2cf3 COPTIC SMALL LETTER BOHAIRIC KHEI - { 0x2CF3, 0x1, 0x49, 0, -1 }, -// 2cf9 COPTIC OLD NUBIAN FULL STOP -// 2cfa COPTIC OLD NUBIAN DIRECT QUESTION MARK -// 2cfb COPTIC OLD NUBIAN INDIRECT QUESTION MARK -// 2cfc COPTIC OLD NUBIAN VERSE DIVIDER - { 0x2CF9, 0x4, 0x18, 0, 0 }, -// 2cfd COPTIC FRACTION ONE HALF - { 0x2CFD, 0x1, 0x8, 0, 0 }, -// 2cfe COPTIC FULL STOP -// 2cff COPTIC MORPHOLOGICAL DIVIDER - { 0x2CFE, 0x2, 0x18, 0, 0 }, -// 2d00 GEORGIAN SMALL LETTER AN -// 2d01 GEORGIAN SMALL LETTER BAN -// 2d02 GEORGIAN SMALL LETTER GAN -// 2d03 GEORGIAN SMALL LETTER DON -// 2d04 GEORGIAN SMALL LETTER EN -// 2d05 GEORGIAN SMALL LETTER VIN -// 2d06 GEORGIAN SMALL LETTER ZEN -// 2d07 GEORGIAN SMALL LETTER TAN -// 2d08 GEORGIAN SMALL LETTER IN -// 2d09 GEORGIAN SMALL LETTER KAN -// 2d0a GEORGIAN SMALL LETTER LAS -// 2d0b GEORGIAN SMALL LETTER MAN -// 2d0c GEORGIAN SMALL LETTER NAR -// 2d0d GEORGIAN SMALL LETTER ON -// 2d0e GEORGIAN SMALL LETTER PAR -// 2d0f GEORGIAN SMALL LETTER ZHAR -// 2d10 GEORGIAN SMALL LETTER RAE -// 2d11 GEORGIAN SMALL LETTER SAN -// 2d12 GEORGIAN SMALL LETTER TAR -// 2d13 GEORGIAN SMALL LETTER UN -// 2d14 GEORGIAN SMALL LETTER PHAR -// 2d15 GEORGIAN SMALL LETTER KHAR -// 2d16 GEORGIAN SMALL LETTER GHAN -// 2d17 GEORGIAN SMALL LETTER QAR -// 2d18 GEORGIAN SMALL LETTER SHIN -// 2d19 GEORGIAN SMALL LETTER CHIN -// 2d1a GEORGIAN SMALL LETTER CAN -// 2d1b GEORGIAN SMALL LETTER JIL -// 2d1c GEORGIAN SMALL LETTER CIL -// 2d1d GEORGIAN SMALL LETTER CHAR -// 2d1e GEORGIAN SMALL LETTER XAN -// 2d1f GEORGIAN SMALL LETTER JHAN -// 2d20 GEORGIAN SMALL LETTER HAE -// 2d21 GEORGIAN SMALL LETTER HE -// 2d22 GEORGIAN SMALL LETTER HIE -// 2d23 GEORGIAN SMALL LETTER WE -// 2d24 GEORGIAN SMALL LETTER HAR -// 2d25 GEORGIAN SMALL LETTER HOE - { 0x2D00, 0x26, 0x49, 0, -7264 }, -// 2d27 GEORGIAN SMALL LETTER YN - { 0x2D27, 0x1, 0x49, 0, -7264 }, -// 2d2d GEORGIAN SMALL LETTER AEN - { 0x2D2D, 0x1, 0x49, 0, -7264 }, -// 2d30 TIFINAGH LETTER YA -// 2d31 TIFINAGH LETTER YAB -// 2d32 TIFINAGH LETTER YABH -// 2d33 TIFINAGH LETTER YAG -// 2d34 TIFINAGH LETTER YAGHH -// 2d35 TIFINAGH LETTER BERBER ACADEMY YAJ -// 2d36 TIFINAGH LETTER YAJ -// 2d37 TIFINAGH LETTER YAD -// 2d38 TIFINAGH LETTER YADH -// 2d39 TIFINAGH LETTER YADD -// 2d3a TIFINAGH LETTER YADDH -// 2d3b TIFINAGH LETTER YEY -// 2d3c TIFINAGH LETTER YAF -// 2d3d TIFINAGH LETTER YAK -// 2d3e TIFINAGH LETTER TUAREG YAK -// 2d3f TIFINAGH LETTER YAKHH -// 2d40 TIFINAGH LETTER YAH -// 2d41 TIFINAGH LETTER BERBER ACADEMY YAH -// 2d42 TIFINAGH LETTER TUAREG YAH -// 2d43 TIFINAGH LETTER YAHH -// 2d44 TIFINAGH LETTER YAA -// 2d45 TIFINAGH LETTER YAKH -// 2d46 TIFINAGH LETTER TUAREG YAKH -// 2d47 TIFINAGH LETTER YAQ -// 2d48 TIFINAGH LETTER TUAREG YAQ -// 2d49 TIFINAGH LETTER YI -// 2d4a TIFINAGH LETTER YAZH -// 2d4b TIFINAGH LETTER AHAGGAR YAZH -// 2d4c TIFINAGH LETTER TUAREG YAZH -// 2d4d TIFINAGH LETTER YAL -// 2d4e TIFINAGH LETTER YAM -// 2d4f TIFINAGH LETTER YAN -// 2d50 TIFINAGH LETTER TUAREG YAGN -// 2d51 TIFINAGH LETTER TUAREG YANG -// 2d52 TIFINAGH LETTER YAP -// 2d53 TIFINAGH LETTER YU -// 2d54 TIFINAGH LETTER YAR -// 2d55 TIFINAGH LETTER YARR -// 2d56 TIFINAGH LETTER YAGH -// 2d57 TIFINAGH LETTER TUAREG YAGH -// 2d58 TIFINAGH LETTER AYER YAGH -// 2d59 TIFINAGH LETTER YAS -// 2d5a TIFINAGH LETTER YASS -// 2d5b TIFINAGH LETTER YASH -// 2d5c TIFINAGH LETTER YAT -// 2d5d TIFINAGH LETTER YATH -// 2d5e TIFINAGH LETTER YACH -// 2d5f TIFINAGH LETTER YATT -// 2d60 TIFINAGH LETTER YAV -// 2d61 TIFINAGH LETTER YAW -// 2d62 TIFINAGH LETTER YAY -// 2d63 TIFINAGH LETTER YAZ -// 2d64 TIFINAGH LETTER TAWELLEMET YAZ -// 2d65 TIFINAGH LETTER YAZZ -// 2d66 TIFINAGH LETTER YE -// 2d67 TIFINAGH LETTER YO - { 0x2D30, 0x38, 0x9, 0, 0 }, -// 2d6f TIFINAGH MODIFIER LETTER LABIALIZATION MARK - { 0x2D6F, 0x1, 0x9, 0, 0 }, -// 2d70 TIFINAGH SEPARATOR MARK - { 0x2D70, 0x1, 0x18, 0, 0 }, -// 2d7f TIFINAGH CONSONANT JOINER - { 0x2D7F, 0x1, 0x0, 0, 0 }, -// 2d80 ETHIOPIC SYLLABLE LOA -// 2d81 ETHIOPIC SYLLABLE MOA -// 2d82 ETHIOPIC SYLLABLE ROA -// 2d83 ETHIOPIC SYLLABLE SOA -// 2d84 ETHIOPIC SYLLABLE SHOA -// 2d85 ETHIOPIC SYLLABLE BOA -// 2d86 ETHIOPIC SYLLABLE TOA -// 2d87 ETHIOPIC SYLLABLE COA -// 2d88 ETHIOPIC SYLLABLE NOA -// 2d89 ETHIOPIC SYLLABLE NYOA -// 2d8a ETHIOPIC SYLLABLE GLOTTAL OA -// 2d8b ETHIOPIC SYLLABLE ZOA -// 2d8c ETHIOPIC SYLLABLE DOA -// 2d8d ETHIOPIC SYLLABLE DDOA -// 2d8e ETHIOPIC SYLLABLE JOA -// 2d8f ETHIOPIC SYLLABLE THOA -// 2d90 ETHIOPIC SYLLABLE CHOA -// 2d91 ETHIOPIC SYLLABLE PHOA -// 2d92 ETHIOPIC SYLLABLE POA -// 2d93 ETHIOPIC SYLLABLE GGWA -// 2d94 ETHIOPIC SYLLABLE GGWI -// 2d95 ETHIOPIC SYLLABLE GGWEE -// 2d96 ETHIOPIC SYLLABLE GGWE - { 0x2D80, 0x17, 0x9, 0, 0 }, -// 2da0 ETHIOPIC SYLLABLE SSA -// 2da1 ETHIOPIC SYLLABLE SSU -// 2da2 ETHIOPIC SYLLABLE SSI -// 2da3 ETHIOPIC SYLLABLE SSAA -// 2da4 ETHIOPIC SYLLABLE SSEE -// 2da5 ETHIOPIC SYLLABLE SSE -// 2da6 ETHIOPIC SYLLABLE SSO - { 0x2DA0, 0x7, 0x9, 0, 0 }, -// 2da8 ETHIOPIC SYLLABLE CCA -// 2da9 ETHIOPIC SYLLABLE CCU -// 2daa ETHIOPIC SYLLABLE CCI -// 2dab ETHIOPIC SYLLABLE CCAA -// 2dac ETHIOPIC SYLLABLE CCEE -// 2dad ETHIOPIC SYLLABLE CCE -// 2dae ETHIOPIC SYLLABLE CCO - { 0x2DA8, 0x7, 0x9, 0, 0 }, -// 2db0 ETHIOPIC SYLLABLE ZZA -// 2db1 ETHIOPIC SYLLABLE ZZU -// 2db2 ETHIOPIC SYLLABLE ZZI -// 2db3 ETHIOPIC SYLLABLE ZZAA -// 2db4 ETHIOPIC SYLLABLE ZZEE -// 2db5 ETHIOPIC SYLLABLE ZZE -// 2db6 ETHIOPIC SYLLABLE ZZO - { 0x2DB0, 0x7, 0x9, 0, 0 }, -// 2db8 ETHIOPIC SYLLABLE CCHA -// 2db9 ETHIOPIC SYLLABLE CCHU -// 2dba ETHIOPIC SYLLABLE CCHI -// 2dbb ETHIOPIC SYLLABLE CCHAA -// 2dbc ETHIOPIC SYLLABLE CCHEE -// 2dbd ETHIOPIC SYLLABLE CCHE -// 2dbe ETHIOPIC SYLLABLE CCHO - { 0x2DB8, 0x7, 0x9, 0, 0 }, -// 2dc0 ETHIOPIC SYLLABLE QYA -// 2dc1 ETHIOPIC SYLLABLE QYU -// 2dc2 ETHIOPIC SYLLABLE QYI -// 2dc3 ETHIOPIC SYLLABLE QYAA -// 2dc4 ETHIOPIC SYLLABLE QYEE -// 2dc5 ETHIOPIC SYLLABLE QYE -// 2dc6 ETHIOPIC SYLLABLE QYO - { 0x2DC0, 0x7, 0x9, 0, 0 }, -// 2dc8 ETHIOPIC SYLLABLE KYA -// 2dc9 ETHIOPIC SYLLABLE KYU -// 2dca ETHIOPIC SYLLABLE KYI -// 2dcb ETHIOPIC SYLLABLE KYAA -// 2dcc ETHIOPIC SYLLABLE KYEE -// 2dcd ETHIOPIC SYLLABLE KYE -// 2dce ETHIOPIC SYLLABLE KYO - { 0x2DC8, 0x7, 0x9, 0, 0 }, -// 2dd0 ETHIOPIC SYLLABLE XYA -// 2dd1 ETHIOPIC SYLLABLE XYU -// 2dd2 ETHIOPIC SYLLABLE XYI -// 2dd3 ETHIOPIC SYLLABLE XYAA -// 2dd4 ETHIOPIC SYLLABLE XYEE -// 2dd5 ETHIOPIC SYLLABLE XYE -// 2dd6 ETHIOPIC SYLLABLE XYO - { 0x2DD0, 0x7, 0x9, 0, 0 }, -// 2dd8 ETHIOPIC SYLLABLE GYA -// 2dd9 ETHIOPIC SYLLABLE GYU -// 2dda ETHIOPIC SYLLABLE GYI -// 2ddb ETHIOPIC SYLLABLE GYAA -// 2ddc ETHIOPIC SYLLABLE GYEE -// 2ddd ETHIOPIC SYLLABLE GYE -// 2dde ETHIOPIC SYLLABLE GYO - { 0x2DD8, 0x7, 0x9, 0, 0 }, -// 2de0 COMBINING CYRILLIC LETTER BE -// 2de1 COMBINING CYRILLIC LETTER VE -// 2de2 COMBINING CYRILLIC LETTER GHE -// 2de3 COMBINING CYRILLIC LETTER DE -// 2de4 COMBINING CYRILLIC LETTER ZHE -// 2de5 COMBINING CYRILLIC LETTER ZE -// 2de6 COMBINING CYRILLIC LETTER KA -// 2de7 COMBINING CYRILLIC LETTER EL -// 2de8 COMBINING CYRILLIC LETTER EM -// 2de9 COMBINING CYRILLIC LETTER EN -// 2dea COMBINING CYRILLIC LETTER O -// 2deb COMBINING CYRILLIC LETTER PE -// 2dec COMBINING CYRILLIC LETTER ER -// 2ded COMBINING CYRILLIC LETTER ES -// 2dee COMBINING CYRILLIC LETTER TE -// 2def COMBINING CYRILLIC LETTER HA -// 2df0 COMBINING CYRILLIC LETTER TSE -// 2df1 COMBINING CYRILLIC LETTER CHE -// 2df2 COMBINING CYRILLIC LETTER SHA -// 2df3 COMBINING CYRILLIC LETTER SHCHA -// 2df4 COMBINING CYRILLIC LETTER FITA -// 2df5 COMBINING CYRILLIC LETTER ES-TE -// 2df6 COMBINING CYRILLIC LETTER A -// 2df7 COMBINING CYRILLIC LETTER IE -// 2df8 COMBINING CYRILLIC LETTER DJERV -// 2df9 COMBINING CYRILLIC LETTER MONOGRAPH UK -// 2dfa COMBINING CYRILLIC LETTER YAT -// 2dfb COMBINING CYRILLIC LETTER YU -// 2dfc COMBINING CYRILLIC LETTER IOTIFIED A -// 2dfd COMBINING CYRILLIC LETTER LITTLE YUS -// 2dfe COMBINING CYRILLIC LETTER BIG YUS -// 2dff COMBINING CYRILLIC LETTER IOTIFIED BIG YUS - { 0x2DE0, 0x20, 0x0, 0, 0 }, -// 2e00 RIGHT ANGLE SUBSTITUTION MARKER -// 2e01 RIGHT ANGLE DOTTED SUBSTITUTION MARKER -// 2e02 LEFT SUBSTITUTION BRACKET -// 2e03 RIGHT SUBSTITUTION BRACKET -// 2e04 LEFT DOTTED SUBSTITUTION BRACKET -// 2e05 RIGHT DOTTED SUBSTITUTION BRACKET -// 2e06 RAISED INTERPOLATION MARKER -// 2e07 RAISED DOTTED INTERPOLATION MARKER -// 2e08 DOTTED TRANSPOSITION MARKER -// 2e09 LEFT TRANSPOSITION BRACKET -// 2e0a RIGHT TRANSPOSITION BRACKET -// 2e0b RAISED SQUARE -// 2e0c LEFT RAISED OMISSION BRACKET -// 2e0d RIGHT RAISED OMISSION BRACKET -// 2e0e EDITORIAL CORONIS -// 2e0f PARAGRAPHOS -// 2e10 FORKED PARAGRAPHOS -// 2e11 REVERSED FORKED PARAGRAPHOS -// 2e12 HYPODIASTOLE -// 2e13 DOTTED OBELOS -// 2e14 DOWNWARDS ANCORA -// 2e15 UPWARDS ANCORA -// 2e16 DOTTED RIGHT-POINTING ANGLE -// 2e17 DOUBLE OBLIQUE HYPHEN -// 2e18 INVERTED INTERROBANG -// 2e19 PALM BRANCH -// 2e1a HYPHEN WITH DIAERESIS -// 2e1b TILDE WITH RING ABOVE -// 2e1c LEFT LOW PARAPHRASE BRACKET -// 2e1d RIGHT LOW PARAPHRASE BRACKET -// 2e1e TILDE WITH DOT ABOVE -// 2e1f TILDE WITH DOT BELOW -// 2e20 LEFT VERTICAL BAR WITH QUILL -// 2e21 RIGHT VERTICAL BAR WITH QUILL -// 2e22 TOP LEFT HALF BRACKET -// 2e23 TOP RIGHT HALF BRACKET -// 2e24 BOTTOM LEFT HALF BRACKET -// 2e25 BOTTOM RIGHT HALF BRACKET -// 2e26 LEFT SIDEWAYS U BRACKET -// 2e27 RIGHT SIDEWAYS U BRACKET -// 2e28 LEFT DOUBLE PARENTHESIS -// 2e29 RIGHT DOUBLE PARENTHESIS -// 2e2a TWO DOTS OVER ONE DOT PUNCTUATION -// 2e2b ONE DOT OVER TWO DOTS PUNCTUATION -// 2e2c SQUARED FOUR DOT PUNCTUATION -// 2e2d FIVE DOT MARK -// 2e2e REVERSED QUESTION MARK - { 0x2E00, 0x2F, 0x18, 0, 0 }, -// 2e2f VERTICAL TILDE - { 0x2E2F, 0x1, 0x9, 0, 0 }, -// 2e30 RING POINT -// 2e31 WORD SEPARATOR MIDDLE DOT -// 2e32 TURNED COMMA -// 2e33 RAISED DOT -// 2e34 RAISED COMMA -// 2e35 TURNED SEMICOLON -// 2e36 DAGGER WITH LEFT GUARD -// 2e37 DAGGER WITH RIGHT GUARD -// 2e38 TURNED DAGGER -// 2e39 TOP HALF SECTION SIGN -// 2e3a TWO-EM DASH -// 2e3b THREE-EM DASH -// 2e3c STENOGRAPHIC FULL STOP -// 2e3d VERTICAL SIX DOTS -// 2e3e WIGGLY VERTICAL LINE -// 2e3f CAPITULUM -// 2e40 DOUBLE HYPHEN -// 2e41 REVERSED COMMA -// 2e42 DOUBLE LOW-REVERSED-9 QUOTATION MARK - { 0x2E30, 0x13, 0x18, 0, 0 }, -// 2e80 CJK RADICAL REPEAT -// 2e81 CJK RADICAL CLIFF -// 2e82 CJK RADICAL SECOND ONE -// 2e83 CJK RADICAL SECOND TWO -// 2e84 CJK RADICAL SECOND THREE -// 2e85 CJK RADICAL PERSON -// 2e86 CJK RADICAL BOX -// 2e87 CJK RADICAL TABLE -// 2e88 CJK RADICAL KNIFE ONE -// 2e89 CJK RADICAL KNIFE TWO -// 2e8a CJK RADICAL DIVINATION -// 2e8b CJK RADICAL SEAL -// 2e8c CJK RADICAL SMALL ONE -// 2e8d CJK RADICAL SMALL TWO -// 2e8e CJK RADICAL LAME ONE -// 2e8f CJK RADICAL LAME TWO -// 2e90 CJK RADICAL LAME THREE -// 2e91 CJK RADICAL LAME FOUR -// 2e92 CJK RADICAL SNAKE -// 2e93 CJK RADICAL THREAD -// 2e94 CJK RADICAL SNOUT ONE -// 2e95 CJK RADICAL SNOUT TWO -// 2e96 CJK RADICAL HEART ONE -// 2e97 CJK RADICAL HEART TWO -// 2e98 CJK RADICAL HAND -// 2e99 CJK RADICAL RAP - { 0x2E80, 0x1A, 0x8, 0, 0 }, -// 2e9b CJK RADICAL CHOKE -// 2e9c CJK RADICAL SUN -// 2e9d CJK RADICAL MOON -// 2e9e CJK RADICAL DEATH -// 2e9f CJK RADICAL MOTHER -// 2ea0 CJK RADICAL CIVILIAN -// 2ea1 CJK RADICAL WATER ONE -// 2ea2 CJK RADICAL WATER TWO -// 2ea3 CJK RADICAL FIRE -// 2ea4 CJK RADICAL PAW ONE -// 2ea5 CJK RADICAL PAW TWO -// 2ea6 CJK RADICAL SIMPLIFIED HALF TREE TRUNK -// 2ea7 CJK RADICAL COW -// 2ea8 CJK RADICAL DOG -// 2ea9 CJK RADICAL JADE -// 2eaa CJK RADICAL BOLT OF CLOTH -// 2eab CJK RADICAL EYE -// 2eac CJK RADICAL SPIRIT ONE -// 2ead CJK RADICAL SPIRIT TWO -// 2eae CJK RADICAL BAMBOO -// 2eaf CJK RADICAL SILK -// 2eb0 CJK RADICAL C-SIMPLIFIED SILK -// 2eb1 CJK RADICAL NET ONE -// 2eb2 CJK RADICAL NET TWO -// 2eb3 CJK RADICAL NET THREE -// 2eb4 CJK RADICAL NET FOUR -// 2eb5 CJK RADICAL MESH -// 2eb6 CJK RADICAL SHEEP -// 2eb7 CJK RADICAL RAM -// 2eb8 CJK RADICAL EWE -// 2eb9 CJK RADICAL OLD -// 2eba CJK RADICAL BRUSH ONE -// 2ebb CJK RADICAL BRUSH TWO -// 2ebc CJK RADICAL MEAT -// 2ebd CJK RADICAL MORTAR -// 2ebe CJK RADICAL GRASS ONE -// 2ebf CJK RADICAL GRASS TWO -// 2ec0 CJK RADICAL GRASS THREE -// 2ec1 CJK RADICAL TIGER -// 2ec2 CJK RADICAL CLOTHES -// 2ec3 CJK RADICAL WEST ONE -// 2ec4 CJK RADICAL WEST TWO -// 2ec5 CJK RADICAL C-SIMPLIFIED SEE -// 2ec6 CJK RADICAL SIMPLIFIED HORN -// 2ec7 CJK RADICAL HORN -// 2ec8 CJK RADICAL C-SIMPLIFIED SPEECH -// 2ec9 CJK RADICAL C-SIMPLIFIED SHELL -// 2eca CJK RADICAL FOOT -// 2ecb CJK RADICAL C-SIMPLIFIED CART -// 2ecc CJK RADICAL SIMPLIFIED WALK -// 2ecd CJK RADICAL WALK ONE -// 2ece CJK RADICAL WALK TWO -// 2ecf CJK RADICAL CITY -// 2ed0 CJK RADICAL C-SIMPLIFIED GOLD -// 2ed1 CJK RADICAL LONG ONE -// 2ed2 CJK RADICAL LONG TWO -// 2ed3 CJK RADICAL C-SIMPLIFIED LONG -// 2ed4 CJK RADICAL C-SIMPLIFIED GATE -// 2ed5 CJK RADICAL MOUND ONE -// 2ed6 CJK RADICAL MOUND TWO -// 2ed7 CJK RADICAL RAIN -// 2ed8 CJK RADICAL BLUE -// 2ed9 CJK RADICAL C-SIMPLIFIED TANNED LEATHER -// 2eda CJK RADICAL C-SIMPLIFIED LEAF -// 2edb CJK RADICAL C-SIMPLIFIED WIND -// 2edc CJK RADICAL C-SIMPLIFIED FLY -// 2edd CJK RADICAL EAT ONE -// 2ede CJK RADICAL EAT TWO -// 2edf CJK RADICAL EAT THREE -// 2ee0 CJK RADICAL C-SIMPLIFIED EAT -// 2ee1 CJK RADICAL HEAD -// 2ee2 CJK RADICAL C-SIMPLIFIED HORSE -// 2ee3 CJK RADICAL BONE -// 2ee4 CJK RADICAL GHOST -// 2ee5 CJK RADICAL C-SIMPLIFIED FISH -// 2ee6 CJK RADICAL C-SIMPLIFIED BIRD -// 2ee7 CJK RADICAL C-SIMPLIFIED SALT -// 2ee8 CJK RADICAL SIMPLIFIED WHEAT -// 2ee9 CJK RADICAL SIMPLIFIED YELLOW -// 2eea CJK RADICAL C-SIMPLIFIED FROG -// 2eeb CJK RADICAL J-SIMPLIFIED EVEN -// 2eec CJK RADICAL C-SIMPLIFIED EVEN -// 2eed CJK RADICAL J-SIMPLIFIED TOOTH -// 2eee CJK RADICAL C-SIMPLIFIED TOOTH -// 2eef CJK RADICAL J-SIMPLIFIED DRAGON -// 2ef0 CJK RADICAL C-SIMPLIFIED DRAGON -// 2ef1 CJK RADICAL TURTLE -// 2ef2 CJK RADICAL J-SIMPLIFIED TURTLE -// 2ef3 CJK RADICAL C-SIMPLIFIED TURTLE - { 0x2E9B, 0x59, 0x8, 0, 0 }, -// 2f00 KANGXI RADICAL ONE -// 2f01 KANGXI RADICAL LINE -// 2f02 KANGXI RADICAL DOT -// 2f03 KANGXI RADICAL SLASH -// 2f04 KANGXI RADICAL SECOND -// 2f05 KANGXI RADICAL HOOK -// 2f06 KANGXI RADICAL TWO -// 2f07 KANGXI RADICAL LID -// 2f08 KANGXI RADICAL MAN -// 2f09 KANGXI RADICAL LEGS -// 2f0a KANGXI RADICAL ENTER -// 2f0b KANGXI RADICAL EIGHT -// 2f0c KANGXI RADICAL DOWN BOX -// 2f0d KANGXI RADICAL COVER -// 2f0e KANGXI RADICAL ICE -// 2f0f KANGXI RADICAL TABLE -// 2f10 KANGXI RADICAL OPEN BOX -// 2f11 KANGXI RADICAL KNIFE -// 2f12 KANGXI RADICAL POWER -// 2f13 KANGXI RADICAL WRAP -// 2f14 KANGXI RADICAL SPOON -// 2f15 KANGXI RADICAL RIGHT OPEN BOX -// 2f16 KANGXI RADICAL HIDING ENCLOSURE -// 2f17 KANGXI RADICAL TEN -// 2f18 KANGXI RADICAL DIVINATION -// 2f19 KANGXI RADICAL SEAL -// 2f1a KANGXI RADICAL CLIFF -// 2f1b KANGXI RADICAL PRIVATE -// 2f1c KANGXI RADICAL AGAIN -// 2f1d KANGXI RADICAL MOUTH -// 2f1e KANGXI RADICAL ENCLOSURE -// 2f1f KANGXI RADICAL EARTH -// 2f20 KANGXI RADICAL SCHOLAR -// 2f21 KANGXI RADICAL GO -// 2f22 KANGXI RADICAL GO SLOWLY -// 2f23 KANGXI RADICAL EVENING -// 2f24 KANGXI RADICAL BIG -// 2f25 KANGXI RADICAL WOMAN -// 2f26 KANGXI RADICAL CHILD -// 2f27 KANGXI RADICAL ROOF -// 2f28 KANGXI RADICAL INCH -// 2f29 KANGXI RADICAL SMALL -// 2f2a KANGXI RADICAL LAME -// 2f2b KANGXI RADICAL CORPSE -// 2f2c KANGXI RADICAL SPROUT -// 2f2d KANGXI RADICAL MOUNTAIN -// 2f2e KANGXI RADICAL RIVER -// 2f2f KANGXI RADICAL WORK -// 2f30 KANGXI RADICAL ONESELF -// 2f31 KANGXI RADICAL TURBAN -// 2f32 KANGXI RADICAL DRY -// 2f33 KANGXI RADICAL SHORT THREAD -// 2f34 KANGXI RADICAL DOTTED CLIFF -// 2f35 KANGXI RADICAL LONG STRIDE -// 2f36 KANGXI RADICAL TWO HANDS -// 2f37 KANGXI RADICAL SHOOT -// 2f38 KANGXI RADICAL BOW -// 2f39 KANGXI RADICAL SNOUT -// 2f3a KANGXI RADICAL BRISTLE -// 2f3b KANGXI RADICAL STEP -// 2f3c KANGXI RADICAL HEART -// 2f3d KANGXI RADICAL HALBERD -// 2f3e KANGXI RADICAL DOOR -// 2f3f KANGXI RADICAL HAND -// 2f40 KANGXI RADICAL BRANCH -// 2f41 KANGXI RADICAL RAP -// 2f42 KANGXI RADICAL SCRIPT -// 2f43 KANGXI RADICAL DIPPER -// 2f44 KANGXI RADICAL AXE -// 2f45 KANGXI RADICAL SQUARE -// 2f46 KANGXI RADICAL NOT -// 2f47 KANGXI RADICAL SUN -// 2f48 KANGXI RADICAL SAY -// 2f49 KANGXI RADICAL MOON -// 2f4a KANGXI RADICAL TREE -// 2f4b KANGXI RADICAL LACK -// 2f4c KANGXI RADICAL STOP -// 2f4d KANGXI RADICAL DEATH -// 2f4e KANGXI RADICAL WEAPON -// 2f4f KANGXI RADICAL DO NOT -// 2f50 KANGXI RADICAL COMPARE -// 2f51 KANGXI RADICAL FUR -// 2f52 KANGXI RADICAL CLAN -// 2f53 KANGXI RADICAL STEAM -// 2f54 KANGXI RADICAL WATER -// 2f55 KANGXI RADICAL FIRE -// 2f56 KANGXI RADICAL CLAW -// 2f57 KANGXI RADICAL FATHER -// 2f58 KANGXI RADICAL DOUBLE X -// 2f59 KANGXI RADICAL HALF TREE TRUNK -// 2f5a KANGXI RADICAL SLICE -// 2f5b KANGXI RADICAL FANG -// 2f5c KANGXI RADICAL COW -// 2f5d KANGXI RADICAL DOG -// 2f5e KANGXI RADICAL PROFOUND -// 2f5f KANGXI RADICAL JADE -// 2f60 KANGXI RADICAL MELON -// 2f61 KANGXI RADICAL TILE -// 2f62 KANGXI RADICAL SWEET -// 2f63 KANGXI RADICAL LIFE -// 2f64 KANGXI RADICAL USE -// 2f65 KANGXI RADICAL FIELD -// 2f66 KANGXI RADICAL BOLT OF CLOTH -// 2f67 KANGXI RADICAL SICKNESS -// 2f68 KANGXI RADICAL DOTTED TENT -// 2f69 KANGXI RADICAL WHITE -// 2f6a KANGXI RADICAL SKIN -// 2f6b KANGXI RADICAL DISH -// 2f6c KANGXI RADICAL EYE -// 2f6d KANGXI RADICAL SPEAR -// 2f6e KANGXI RADICAL ARROW -// 2f6f KANGXI RADICAL STONE -// 2f70 KANGXI RADICAL SPIRIT -// 2f71 KANGXI RADICAL TRACK -// 2f72 KANGXI RADICAL GRAIN -// 2f73 KANGXI RADICAL CAVE -// 2f74 KANGXI RADICAL STAND -// 2f75 KANGXI RADICAL BAMBOO -// 2f76 KANGXI RADICAL RICE -// 2f77 KANGXI RADICAL SILK -// 2f78 KANGXI RADICAL JAR -// 2f79 KANGXI RADICAL NET -// 2f7a KANGXI RADICAL SHEEP -// 2f7b KANGXI RADICAL FEATHER -// 2f7c KANGXI RADICAL OLD -// 2f7d KANGXI RADICAL AND -// 2f7e KANGXI RADICAL PLOW -// 2f7f KANGXI RADICAL EAR -// 2f80 KANGXI RADICAL BRUSH -// 2f81 KANGXI RADICAL MEAT -// 2f82 KANGXI RADICAL MINISTER -// 2f83 KANGXI RADICAL SELF -// 2f84 KANGXI RADICAL ARRIVE -// 2f85 KANGXI RADICAL MORTAR -// 2f86 KANGXI RADICAL TONGUE -// 2f87 KANGXI RADICAL OPPOSE -// 2f88 KANGXI RADICAL BOAT -// 2f89 KANGXI RADICAL STOPPING -// 2f8a KANGXI RADICAL COLOR -// 2f8b KANGXI RADICAL GRASS -// 2f8c KANGXI RADICAL TIGER -// 2f8d KANGXI RADICAL INSECT -// 2f8e KANGXI RADICAL BLOOD -// 2f8f KANGXI RADICAL WALK ENCLOSURE -// 2f90 KANGXI RADICAL CLOTHES -// 2f91 KANGXI RADICAL WEST -// 2f92 KANGXI RADICAL SEE -// 2f93 KANGXI RADICAL HORN -// 2f94 KANGXI RADICAL SPEECH -// 2f95 KANGXI RADICAL VALLEY -// 2f96 KANGXI RADICAL BEAN -// 2f97 KANGXI RADICAL PIG -// 2f98 KANGXI RADICAL BADGER -// 2f99 KANGXI RADICAL SHELL -// 2f9a KANGXI RADICAL RED -// 2f9b KANGXI RADICAL RUN -// 2f9c KANGXI RADICAL FOOT -// 2f9d KANGXI RADICAL BODY -// 2f9e KANGXI RADICAL CART -// 2f9f KANGXI RADICAL BITTER -// 2fa0 KANGXI RADICAL MORNING -// 2fa1 KANGXI RADICAL WALK -// 2fa2 KANGXI RADICAL CITY -// 2fa3 KANGXI RADICAL WINE -// 2fa4 KANGXI RADICAL DISTINGUISH -// 2fa5 KANGXI RADICAL VILLAGE -// 2fa6 KANGXI RADICAL GOLD -// 2fa7 KANGXI RADICAL LONG -// 2fa8 KANGXI RADICAL GATE -// 2fa9 KANGXI RADICAL MOUND -// 2faa KANGXI RADICAL SLAVE -// 2fab KANGXI RADICAL SHORT TAILED BIRD -// 2fac KANGXI RADICAL RAIN -// 2fad KANGXI RADICAL BLUE -// 2fae KANGXI RADICAL WRONG -// 2faf KANGXI RADICAL FACE -// 2fb0 KANGXI RADICAL LEATHER -// 2fb1 KANGXI RADICAL TANNED LEATHER -// 2fb2 KANGXI RADICAL LEEK -// 2fb3 KANGXI RADICAL SOUND -// 2fb4 KANGXI RADICAL LEAF -// 2fb5 KANGXI RADICAL WIND -// 2fb6 KANGXI RADICAL FLY -// 2fb7 KANGXI RADICAL EAT -// 2fb8 KANGXI RADICAL HEAD -// 2fb9 KANGXI RADICAL FRAGRANT -// 2fba KANGXI RADICAL HORSE -// 2fbb KANGXI RADICAL BONE -// 2fbc KANGXI RADICAL TALL -// 2fbd KANGXI RADICAL HAIR -// 2fbe KANGXI RADICAL FIGHT -// 2fbf KANGXI RADICAL SACRIFICIAL WINE -// 2fc0 KANGXI RADICAL CAULDRON -// 2fc1 KANGXI RADICAL GHOST -// 2fc2 KANGXI RADICAL FISH -// 2fc3 KANGXI RADICAL BIRD -// 2fc4 KANGXI RADICAL SALT -// 2fc5 KANGXI RADICAL DEER -// 2fc6 KANGXI RADICAL WHEAT -// 2fc7 KANGXI RADICAL HEMP -// 2fc8 KANGXI RADICAL YELLOW -// 2fc9 KANGXI RADICAL MILLET -// 2fca KANGXI RADICAL BLACK -// 2fcb KANGXI RADICAL EMBROIDERY -// 2fcc KANGXI RADICAL FROG -// 2fcd KANGXI RADICAL TRIPOD -// 2fce KANGXI RADICAL DRUM -// 2fcf KANGXI RADICAL RAT -// 2fd0 KANGXI RADICAL NOSE -// 2fd1 KANGXI RADICAL EVEN -// 2fd2 KANGXI RADICAL TOOTH -// 2fd3 KANGXI RADICAL DRAGON -// 2fd4 KANGXI RADICAL TURTLE -// 2fd5 KANGXI RADICAL FLUTE - { 0x2F00, 0xD6, 0x8, 0, 0 }, -// 2ff0 IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT -// 2ff1 IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW -// 2ff2 IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT -// 2ff3 IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW -// 2ff4 IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND -// 2ff5 IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM ABOVE -// 2ff6 IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM BELOW -// 2ff7 IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LEFT -// 2ff8 IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER LEFT -// 2ff9 IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT -// 2ffa IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT -// 2ffb IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID - { 0x2FF0, 0xC, 0x8, 0, 0 }, -// 3000 IDEOGRAPHIC SPACE - { 0x3000, 0x1, 0x20, 0, 0 }, -// 3001 IDEOGRAPHIC COMMA -// 3002 IDEOGRAPHIC FULL STOP -// 3003 DITTO MARK - { 0x3001, 0x3, 0x18, 0, 0 }, -// 3004 JAPANESE INDUSTRIAL STANDARD SYMBOL - { 0x3004, 0x1, 0x8, 0, 0 }, -// 3005 IDEOGRAPHIC ITERATION MARK -// 3006 IDEOGRAPHIC CLOSING MARK - { 0x3005, 0x2, 0x9, 0, 0 }, -// 3007 IDEOGRAPHIC NUMBER ZERO - { 0x3007, 0x1, 0x8, 0, 0 }, -// 3008 LEFT ANGLE BRACKET -// 3009 RIGHT ANGLE BRACKET -// 300a LEFT DOUBLE ANGLE BRACKET -// 300b RIGHT DOUBLE ANGLE BRACKET -// 300c LEFT CORNER BRACKET -// 300d RIGHT CORNER BRACKET -// 300e LEFT WHITE CORNER BRACKET -// 300f RIGHT WHITE CORNER BRACKET -// 3010 LEFT BLACK LENTICULAR BRACKET -// 3011 RIGHT BLACK LENTICULAR BRACKET - { 0x3008, 0xA, 0x18, 0, 0 }, -// 3012 POSTAL MARK -// 3013 GETA MARK - { 0x3012, 0x2, 0x8, 0, 0 }, -// 3014 LEFT TORTOISE SHELL BRACKET -// 3015 RIGHT TORTOISE SHELL BRACKET -// 3016 LEFT WHITE LENTICULAR BRACKET -// 3017 RIGHT WHITE LENTICULAR BRACKET -// 3018 LEFT WHITE TORTOISE SHELL BRACKET -// 3019 RIGHT WHITE TORTOISE SHELL BRACKET -// 301a LEFT WHITE SQUARE BRACKET -// 301b RIGHT WHITE SQUARE BRACKET -// 301c WAVE DASH -// 301d REVERSED DOUBLE PRIME QUOTATION MARK -// 301e DOUBLE PRIME QUOTATION MARK -// 301f LOW DOUBLE PRIME QUOTATION MARK - { 0x3014, 0xC, 0x18, 0, 0 }, -// 3020 POSTAL MARK FACE -// 3021 HANGZHOU NUMERAL ONE -// 3022 HANGZHOU NUMERAL TWO -// 3023 HANGZHOU NUMERAL THREE -// 3024 HANGZHOU NUMERAL FOUR -// 3025 HANGZHOU NUMERAL FIVE -// 3026 HANGZHOU NUMERAL SIX -// 3027 HANGZHOU NUMERAL SEVEN -// 3028 HANGZHOU NUMERAL EIGHT -// 3029 HANGZHOU NUMERAL NINE - { 0x3020, 0xA, 0x8, 0, 0 }, -// 302a IDEOGRAPHIC LEVEL TONE MARK -// 302b IDEOGRAPHIC RISING TONE MARK -// 302c IDEOGRAPHIC DEPARTING TONE MARK -// 302d IDEOGRAPHIC ENTERING TONE MARK -// 302e HANGUL SINGLE DOT TONE MARK -// 302f HANGUL DOUBLE DOT TONE MARK - { 0x302A, 0x6, 0x0, 0, 0 }, -// 3030 WAVY DASH - { 0x3030, 0x1, 0x18, 0, 0 }, -// 3031 VERTICAL KANA REPEAT MARK -// 3032 VERTICAL KANA REPEAT WITH VOICED SOUND MARK -// 3033 VERTICAL KANA REPEAT MARK UPPER HALF -// 3034 VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF -// 3035 VERTICAL KANA REPEAT MARK LOWER HALF - { 0x3031, 0x5, 0x9, 0, 0 }, -// 3036 CIRCLED POSTAL MARK -// 3037 IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL -// 3038 HANGZHOU NUMERAL TEN -// 3039 HANGZHOU NUMERAL TWENTY -// 303a HANGZHOU NUMERAL THIRTY - { 0x3036, 0x5, 0x8, 0, 0 }, -// 303b VERTICAL IDEOGRAPHIC ITERATION MARK -// 303c MASU MARK - { 0x303B, 0x2, 0x9, 0, 0 }, -// 303d PART ALTERNATION MARK - { 0x303D, 0x1, 0x18, 0, 0 }, -// 303e IDEOGRAPHIC VARIATION INDICATOR -// 303f IDEOGRAPHIC HALF FILL SPACE - { 0x303E, 0x2, 0x8, 0, 0 }, -// 3041 HIRAGANA LETTER SMALL A -// 3042 HIRAGANA LETTER A -// 3043 HIRAGANA LETTER SMALL I -// 3044 HIRAGANA LETTER I -// 3045 HIRAGANA LETTER SMALL U -// 3046 HIRAGANA LETTER U -// 3047 HIRAGANA LETTER SMALL E -// 3048 HIRAGANA LETTER E -// 3049 HIRAGANA LETTER SMALL O -// 304a HIRAGANA LETTER O -// 304b HIRAGANA LETTER KA -// 304c HIRAGANA LETTER GA -// 304d HIRAGANA LETTER KI -// 304e HIRAGANA LETTER GI -// 304f HIRAGANA LETTER KU -// 3050 HIRAGANA LETTER GU -// 3051 HIRAGANA LETTER KE -// 3052 HIRAGANA LETTER GE -// 3053 HIRAGANA LETTER KO -// 3054 HIRAGANA LETTER GO -// 3055 HIRAGANA LETTER SA -// 3056 HIRAGANA LETTER ZA -// 3057 HIRAGANA LETTER SI -// 3058 HIRAGANA LETTER ZI -// 3059 HIRAGANA LETTER SU -// 305a HIRAGANA LETTER ZU -// 305b HIRAGANA LETTER SE -// 305c HIRAGANA LETTER ZE -// 305d HIRAGANA LETTER SO -// 305e HIRAGANA LETTER ZO -// 305f HIRAGANA LETTER TA -// 3060 HIRAGANA LETTER DA -// 3061 HIRAGANA LETTER TI -// 3062 HIRAGANA LETTER DI -// 3063 HIRAGANA LETTER SMALL TU -// 3064 HIRAGANA LETTER TU -// 3065 HIRAGANA LETTER DU -// 3066 HIRAGANA LETTER TE -// 3067 HIRAGANA LETTER DE -// 3068 HIRAGANA LETTER TO -// 3069 HIRAGANA LETTER DO -// 306a HIRAGANA LETTER NA -// 306b HIRAGANA LETTER NI -// 306c HIRAGANA LETTER NU -// 306d HIRAGANA LETTER NE -// 306e HIRAGANA LETTER NO -// 306f HIRAGANA LETTER HA -// 3070 HIRAGANA LETTER BA -// 3071 HIRAGANA LETTER PA -// 3072 HIRAGANA LETTER HI -// 3073 HIRAGANA LETTER BI -// 3074 HIRAGANA LETTER PI -// 3075 HIRAGANA LETTER HU -// 3076 HIRAGANA LETTER BU -// 3077 HIRAGANA LETTER PU -// 3078 HIRAGANA LETTER HE -// 3079 HIRAGANA LETTER BE -// 307a HIRAGANA LETTER PE -// 307b HIRAGANA LETTER HO -// 307c HIRAGANA LETTER BO -// 307d HIRAGANA LETTER PO -// 307e HIRAGANA LETTER MA -// 307f HIRAGANA LETTER MI -// 3080 HIRAGANA LETTER MU -// 3081 HIRAGANA LETTER ME -// 3082 HIRAGANA LETTER MO -// 3083 HIRAGANA LETTER SMALL YA -// 3084 HIRAGANA LETTER YA -// 3085 HIRAGANA LETTER SMALL YU -// 3086 HIRAGANA LETTER YU -// 3087 HIRAGANA LETTER SMALL YO -// 3088 HIRAGANA LETTER YO -// 3089 HIRAGANA LETTER RA -// 308a HIRAGANA LETTER RI -// 308b HIRAGANA LETTER RU -// 308c HIRAGANA LETTER RE -// 308d HIRAGANA LETTER RO -// 308e HIRAGANA LETTER SMALL WA -// 308f HIRAGANA LETTER WA -// 3090 HIRAGANA LETTER WI -// 3091 HIRAGANA LETTER WE -// 3092 HIRAGANA LETTER WO -// 3093 HIRAGANA LETTER N -// 3094 HIRAGANA LETTER VU -// 3095 HIRAGANA LETTER SMALL KA -// 3096 HIRAGANA LETTER SMALL KE - { 0x3041, 0x56, 0x9, 0, 0 }, -// 3099 COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK -// 309a COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK - { 0x3099, 0x2, 0x0, 0, 0 }, -// 309b KATAKANA-HIRAGANA VOICED SOUND MARK -// 309c KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK - { 0x309B, 0x2, 0x8, 0, 0 }, -// 309d HIRAGANA ITERATION MARK -// 309e HIRAGANA VOICED ITERATION MARK -// 309f HIRAGANA DIGRAPH YORI - { 0x309D, 0x3, 0x9, 0, 0 }, -// 30a0 KATAKANA-HIRAGANA DOUBLE HYPHEN - { 0x30A0, 0x1, 0x18, 0, 0 }, -// 30a1 KATAKANA LETTER SMALL A -// 30a2 KATAKANA LETTER A -// 30a3 KATAKANA LETTER SMALL I -// 30a4 KATAKANA LETTER I -// 30a5 KATAKANA LETTER SMALL U -// 30a6 KATAKANA LETTER U -// 30a7 KATAKANA LETTER SMALL E -// 30a8 KATAKANA LETTER E -// 30a9 KATAKANA LETTER SMALL O -// 30aa KATAKANA LETTER O -// 30ab KATAKANA LETTER KA -// 30ac KATAKANA LETTER GA -// 30ad KATAKANA LETTER KI -// 30ae KATAKANA LETTER GI -// 30af KATAKANA LETTER KU -// 30b0 KATAKANA LETTER GU -// 30b1 KATAKANA LETTER KE -// 30b2 KATAKANA LETTER GE -// 30b3 KATAKANA LETTER KO -// 30b4 KATAKANA LETTER GO -// 30b5 KATAKANA LETTER SA -// 30b6 KATAKANA LETTER ZA -// 30b7 KATAKANA LETTER SI -// 30b8 KATAKANA LETTER ZI -// 30b9 KATAKANA LETTER SU -// 30ba KATAKANA LETTER ZU -// 30bb KATAKANA LETTER SE -// 30bc KATAKANA LETTER ZE -// 30bd KATAKANA LETTER SO -// 30be KATAKANA LETTER ZO -// 30bf KATAKANA LETTER TA -// 30c0 KATAKANA LETTER DA -// 30c1 KATAKANA LETTER TI -// 30c2 KATAKANA LETTER DI -// 30c3 KATAKANA LETTER SMALL TU -// 30c4 KATAKANA LETTER TU -// 30c5 KATAKANA LETTER DU -// 30c6 KATAKANA LETTER TE -// 30c7 KATAKANA LETTER DE -// 30c8 KATAKANA LETTER TO -// 30c9 KATAKANA LETTER DO -// 30ca KATAKANA LETTER NA -// 30cb KATAKANA LETTER NI -// 30cc KATAKANA LETTER NU -// 30cd KATAKANA LETTER NE -// 30ce KATAKANA LETTER NO -// 30cf KATAKANA LETTER HA -// 30d0 KATAKANA LETTER BA -// 30d1 KATAKANA LETTER PA -// 30d2 KATAKANA LETTER HI -// 30d3 KATAKANA LETTER BI -// 30d4 KATAKANA LETTER PI -// 30d5 KATAKANA LETTER HU -// 30d6 KATAKANA LETTER BU -// 30d7 KATAKANA LETTER PU -// 30d8 KATAKANA LETTER HE -// 30d9 KATAKANA LETTER BE -// 30da KATAKANA LETTER PE -// 30db KATAKANA LETTER HO -// 30dc KATAKANA LETTER BO -// 30dd KATAKANA LETTER PO -// 30de KATAKANA LETTER MA -// 30df KATAKANA LETTER MI -// 30e0 KATAKANA LETTER MU -// 30e1 KATAKANA LETTER ME -// 30e2 KATAKANA LETTER MO -// 30e3 KATAKANA LETTER SMALL YA -// 30e4 KATAKANA LETTER YA -// 30e5 KATAKANA LETTER SMALL YU -// 30e6 KATAKANA LETTER YU -// 30e7 KATAKANA LETTER SMALL YO -// 30e8 KATAKANA LETTER YO -// 30e9 KATAKANA LETTER RA -// 30ea KATAKANA LETTER RI -// 30eb KATAKANA LETTER RU -// 30ec KATAKANA LETTER RE -// 30ed KATAKANA LETTER RO -// 30ee KATAKANA LETTER SMALL WA -// 30ef KATAKANA LETTER WA -// 30f0 KATAKANA LETTER WI -// 30f1 KATAKANA LETTER WE -// 30f2 KATAKANA LETTER WO -// 30f3 KATAKANA LETTER N -// 30f4 KATAKANA LETTER VU -// 30f5 KATAKANA LETTER SMALL KA -// 30f6 KATAKANA LETTER SMALL KE -// 30f7 KATAKANA LETTER VA -// 30f8 KATAKANA LETTER VI -// 30f9 KATAKANA LETTER VE -// 30fa KATAKANA LETTER VO - { 0x30A1, 0x5A, 0x9, 0, 0 }, -// 30fb KATAKANA MIDDLE DOT - { 0x30FB, 0x1, 0x18, 0, 0 }, -// 30fc KATAKANA-HIRAGANA PROLONGED SOUND MARK -// 30fd KATAKANA ITERATION MARK -// 30fe KATAKANA VOICED ITERATION MARK -// 30ff KATAKANA DIGRAPH KOTO - { 0x30FC, 0x4, 0x9, 0, 0 }, -// 3105 BOPOMOFO LETTER B -// 3106 BOPOMOFO LETTER P -// 3107 BOPOMOFO LETTER M -// 3108 BOPOMOFO LETTER F -// 3109 BOPOMOFO LETTER D -// 310a BOPOMOFO LETTER T -// 310b BOPOMOFO LETTER N -// 310c BOPOMOFO LETTER L -// 310d BOPOMOFO LETTER G -// 310e BOPOMOFO LETTER K -// 310f BOPOMOFO LETTER H -// 3110 BOPOMOFO LETTER J -// 3111 BOPOMOFO LETTER Q -// 3112 BOPOMOFO LETTER X -// 3113 BOPOMOFO LETTER ZH -// 3114 BOPOMOFO LETTER CH -// 3115 BOPOMOFO LETTER SH -// 3116 BOPOMOFO LETTER R -// 3117 BOPOMOFO LETTER Z -// 3118 BOPOMOFO LETTER C -// 3119 BOPOMOFO LETTER S -// 311a BOPOMOFO LETTER A -// 311b BOPOMOFO LETTER O -// 311c BOPOMOFO LETTER E -// 311d BOPOMOFO LETTER EH -// 311e BOPOMOFO LETTER AI -// 311f BOPOMOFO LETTER EI -// 3120 BOPOMOFO LETTER AU -// 3121 BOPOMOFO LETTER OU -// 3122 BOPOMOFO LETTER AN -// 3123 BOPOMOFO LETTER EN -// 3124 BOPOMOFO LETTER ANG -// 3125 BOPOMOFO LETTER ENG -// 3126 BOPOMOFO LETTER ER -// 3127 BOPOMOFO LETTER I -// 3128 BOPOMOFO LETTER U -// 3129 BOPOMOFO LETTER IU -// 312a BOPOMOFO LETTER V -// 312b BOPOMOFO LETTER NG -// 312c BOPOMOFO LETTER GN -// 312d BOPOMOFO LETTER IH - { 0x3105, 0x29, 0x9, 0, 0 }, -// 3131 HANGUL LETTER KIYEOK -// 3132 HANGUL LETTER SSANGKIYEOK -// 3133 HANGUL LETTER KIYEOK-SIOS -// 3134 HANGUL LETTER NIEUN -// 3135 HANGUL LETTER NIEUN-CIEUC -// 3136 HANGUL LETTER NIEUN-HIEUH -// 3137 HANGUL LETTER TIKEUT -// 3138 HANGUL LETTER SSANGTIKEUT -// 3139 HANGUL LETTER RIEUL -// 313a HANGUL LETTER RIEUL-KIYEOK -// 313b HANGUL LETTER RIEUL-MIEUM -// 313c HANGUL LETTER RIEUL-PIEUP -// 313d HANGUL LETTER RIEUL-SIOS -// 313e HANGUL LETTER RIEUL-THIEUTH -// 313f HANGUL LETTER RIEUL-PHIEUPH -// 3140 HANGUL LETTER RIEUL-HIEUH -// 3141 HANGUL LETTER MIEUM -// 3142 HANGUL LETTER PIEUP -// 3143 HANGUL LETTER SSANGPIEUP -// 3144 HANGUL LETTER PIEUP-SIOS -// 3145 HANGUL LETTER SIOS -// 3146 HANGUL LETTER SSANGSIOS -// 3147 HANGUL LETTER IEUNG -// 3148 HANGUL LETTER CIEUC -// 3149 HANGUL LETTER SSANGCIEUC -// 314a HANGUL LETTER CHIEUCH -// 314b HANGUL LETTER KHIEUKH -// 314c HANGUL LETTER THIEUTH -// 314d HANGUL LETTER PHIEUPH -// 314e HANGUL LETTER HIEUH -// 314f HANGUL LETTER A -// 3150 HANGUL LETTER AE -// 3151 HANGUL LETTER YA -// 3152 HANGUL LETTER YAE -// 3153 HANGUL LETTER EO -// 3154 HANGUL LETTER E -// 3155 HANGUL LETTER YEO -// 3156 HANGUL LETTER YE -// 3157 HANGUL LETTER O -// 3158 HANGUL LETTER WA -// 3159 HANGUL LETTER WAE -// 315a HANGUL LETTER OE -// 315b HANGUL LETTER YO -// 315c HANGUL LETTER U -// 315d HANGUL LETTER WEO -// 315e HANGUL LETTER WE -// 315f HANGUL LETTER WI -// 3160 HANGUL LETTER YU -// 3161 HANGUL LETTER EU -// 3162 HANGUL LETTER YI -// 3163 HANGUL LETTER I -// 3164 HANGUL FILLER -// 3165 HANGUL LETTER SSANGNIEUN -// 3166 HANGUL LETTER NIEUN-TIKEUT -// 3167 HANGUL LETTER NIEUN-SIOS -// 3168 HANGUL LETTER NIEUN-PANSIOS -// 3169 HANGUL LETTER RIEUL-KIYEOK-SIOS -// 316a HANGUL LETTER RIEUL-TIKEUT -// 316b HANGUL LETTER RIEUL-PIEUP-SIOS -// 316c HANGUL LETTER RIEUL-PANSIOS -// 316d HANGUL LETTER RIEUL-YEORINHIEUH -// 316e HANGUL LETTER MIEUM-PIEUP -// 316f HANGUL LETTER MIEUM-SIOS -// 3170 HANGUL LETTER MIEUM-PANSIOS -// 3171 HANGUL LETTER KAPYEOUNMIEUM -// 3172 HANGUL LETTER PIEUP-KIYEOK -// 3173 HANGUL LETTER PIEUP-TIKEUT -// 3174 HANGUL LETTER PIEUP-SIOS-KIYEOK -// 3175 HANGUL LETTER PIEUP-SIOS-TIKEUT -// 3176 HANGUL LETTER PIEUP-CIEUC -// 3177 HANGUL LETTER PIEUP-THIEUTH -// 3178 HANGUL LETTER KAPYEOUNPIEUP -// 3179 HANGUL LETTER KAPYEOUNSSANGPIEUP -// 317a HANGUL LETTER SIOS-KIYEOK -// 317b HANGUL LETTER SIOS-NIEUN -// 317c HANGUL LETTER SIOS-TIKEUT -// 317d HANGUL LETTER SIOS-PIEUP -// 317e HANGUL LETTER SIOS-CIEUC -// 317f HANGUL LETTER PANSIOS -// 3180 HANGUL LETTER SSANGIEUNG -// 3181 HANGUL LETTER YESIEUNG -// 3182 HANGUL LETTER YESIEUNG-SIOS -// 3183 HANGUL LETTER YESIEUNG-PANSIOS -// 3184 HANGUL LETTER KAPYEOUNPHIEUPH -// 3185 HANGUL LETTER SSANGHIEUH -// 3186 HANGUL LETTER YEORINHIEUH -// 3187 HANGUL LETTER YO-YA -// 3188 HANGUL LETTER YO-YAE -// 3189 HANGUL LETTER YO-I -// 318a HANGUL LETTER YU-YEO -// 318b HANGUL LETTER YU-YE -// 318c HANGUL LETTER YU-I -// 318d HANGUL LETTER ARAEA -// 318e HANGUL LETTER ARAEAE - { 0x3131, 0x5E, 0x9, 0, 0 }, -// 3190 IDEOGRAPHIC ANNOTATION LINKING MARK -// 3191 IDEOGRAPHIC ANNOTATION REVERSE MARK -// 3192 IDEOGRAPHIC ANNOTATION ONE MARK -// 3193 IDEOGRAPHIC ANNOTATION TWO MARK -// 3194 IDEOGRAPHIC ANNOTATION THREE MARK -// 3195 IDEOGRAPHIC ANNOTATION FOUR MARK -// 3196 IDEOGRAPHIC ANNOTATION TOP MARK -// 3197 IDEOGRAPHIC ANNOTATION MIDDLE MARK -// 3198 IDEOGRAPHIC ANNOTATION BOTTOM MARK -// 3199 IDEOGRAPHIC ANNOTATION FIRST MARK -// 319a IDEOGRAPHIC ANNOTATION SECOND MARK -// 319b IDEOGRAPHIC ANNOTATION THIRD MARK -// 319c IDEOGRAPHIC ANNOTATION FOURTH MARK -// 319d IDEOGRAPHIC ANNOTATION HEAVEN MARK -// 319e IDEOGRAPHIC ANNOTATION EARTH MARK -// 319f IDEOGRAPHIC ANNOTATION MAN MARK - { 0x3190, 0x10, 0x8, 0, 0 }, -// 31a0 BOPOMOFO LETTER BU -// 31a1 BOPOMOFO LETTER ZI -// 31a2 BOPOMOFO LETTER JI -// 31a3 BOPOMOFO LETTER GU -// 31a4 BOPOMOFO LETTER EE -// 31a5 BOPOMOFO LETTER ENN -// 31a6 BOPOMOFO LETTER OO -// 31a7 BOPOMOFO LETTER ONN -// 31a8 BOPOMOFO LETTER IR -// 31a9 BOPOMOFO LETTER ANN -// 31aa BOPOMOFO LETTER INN -// 31ab BOPOMOFO LETTER UNN -// 31ac BOPOMOFO LETTER IM -// 31ad BOPOMOFO LETTER NGG -// 31ae BOPOMOFO LETTER AINN -// 31af BOPOMOFO LETTER AUNN -// 31b0 BOPOMOFO LETTER AM -// 31b1 BOPOMOFO LETTER OM -// 31b2 BOPOMOFO LETTER ONG -// 31b3 BOPOMOFO LETTER INNN -// 31b4 BOPOMOFO FINAL LETTER P -// 31b5 BOPOMOFO FINAL LETTER T -// 31b6 BOPOMOFO FINAL LETTER K -// 31b7 BOPOMOFO FINAL LETTER H -// 31b8 BOPOMOFO LETTER GH -// 31b9 BOPOMOFO LETTER LH -// 31ba BOPOMOFO LETTER ZY - { 0x31A0, 0x1B, 0x9, 0, 0 }, -// 31c0 CJK STROKE T -// 31c1 CJK STROKE WG -// 31c2 CJK STROKE XG -// 31c3 CJK STROKE BXG -// 31c4 CJK STROKE SW -// 31c5 CJK STROKE HZZ -// 31c6 CJK STROKE HZG -// 31c7 CJK STROKE HP -// 31c8 CJK STROKE HZWG -// 31c9 CJK STROKE SZWG -// 31ca CJK STROKE HZT -// 31cb CJK STROKE HZZP -// 31cc CJK STROKE HPWG -// 31cd CJK STROKE HZW -// 31ce CJK STROKE HZZZ -// 31cf CJK STROKE N -// 31d0 CJK STROKE H -// 31d1 CJK STROKE S -// 31d2 CJK STROKE P -// 31d3 CJK STROKE SP -// 31d4 CJK STROKE D -// 31d5 CJK STROKE HZ -// 31d6 CJK STROKE HG -// 31d7 CJK STROKE SZ -// 31d8 CJK STROKE SWZ -// 31d9 CJK STROKE ST -// 31da CJK STROKE SG -// 31db CJK STROKE PD -// 31dc CJK STROKE PZ -// 31dd CJK STROKE TN -// 31de CJK STROKE SZZ -// 31df CJK STROKE SWG -// 31e0 CJK STROKE HXWG -// 31e1 CJK STROKE HZZZG -// 31e2 CJK STROKE PG -// 31e3 CJK STROKE Q - { 0x31C0, 0x24, 0x8, 0, 0 }, -// 31f0 KATAKANA LETTER SMALL KU -// 31f1 KATAKANA LETTER SMALL SI -// 31f2 KATAKANA LETTER SMALL SU -// 31f3 KATAKANA LETTER SMALL TO -// 31f4 KATAKANA LETTER SMALL NU -// 31f5 KATAKANA LETTER SMALL HA -// 31f6 KATAKANA LETTER SMALL HI -// 31f7 KATAKANA LETTER SMALL HU -// 31f8 KATAKANA LETTER SMALL HE -// 31f9 KATAKANA LETTER SMALL HO -// 31fa KATAKANA LETTER SMALL MU -// 31fb KATAKANA LETTER SMALL RA -// 31fc KATAKANA LETTER SMALL RI -// 31fd KATAKANA LETTER SMALL RU -// 31fe KATAKANA LETTER SMALL RE -// 31ff KATAKANA LETTER SMALL RO - { 0x31F0, 0x10, 0x9, 0, 0 }, -// 3200 PARENTHESIZED HANGUL KIYEOK -// 3201 PARENTHESIZED HANGUL NIEUN -// 3202 PARENTHESIZED HANGUL TIKEUT -// 3203 PARENTHESIZED HANGUL RIEUL -// 3204 PARENTHESIZED HANGUL MIEUM -// 3205 PARENTHESIZED HANGUL PIEUP -// 3206 PARENTHESIZED HANGUL SIOS -// 3207 PARENTHESIZED HANGUL IEUNG -// 3208 PARENTHESIZED HANGUL CIEUC -// 3209 PARENTHESIZED HANGUL CHIEUCH -// 320a PARENTHESIZED HANGUL KHIEUKH -// 320b PARENTHESIZED HANGUL THIEUTH -// 320c PARENTHESIZED HANGUL PHIEUPH -// 320d PARENTHESIZED HANGUL HIEUH -// 320e PARENTHESIZED HANGUL KIYEOK A -// 320f PARENTHESIZED HANGUL NIEUN A -// 3210 PARENTHESIZED HANGUL TIKEUT A -// 3211 PARENTHESIZED HANGUL RIEUL A -// 3212 PARENTHESIZED HANGUL MIEUM A -// 3213 PARENTHESIZED HANGUL PIEUP A -// 3214 PARENTHESIZED HANGUL SIOS A -// 3215 PARENTHESIZED HANGUL IEUNG A -// 3216 PARENTHESIZED HANGUL CIEUC A -// 3217 PARENTHESIZED HANGUL CHIEUCH A -// 3218 PARENTHESIZED HANGUL KHIEUKH A -// 3219 PARENTHESIZED HANGUL THIEUTH A -// 321a PARENTHESIZED HANGUL PHIEUPH A -// 321b PARENTHESIZED HANGUL HIEUH A -// 321c PARENTHESIZED HANGUL CIEUC U -// 321d PARENTHESIZED KOREAN CHARACTER OJEON -// 321e PARENTHESIZED KOREAN CHARACTER O HU - { 0x3200, 0x1F, 0x8, 0, 0 }, -// 3220 PARENTHESIZED IDEOGRAPH ONE -// 3221 PARENTHESIZED IDEOGRAPH TWO -// 3222 PARENTHESIZED IDEOGRAPH THREE -// 3223 PARENTHESIZED IDEOGRAPH FOUR -// 3224 PARENTHESIZED IDEOGRAPH FIVE -// 3225 PARENTHESIZED IDEOGRAPH SIX -// 3226 PARENTHESIZED IDEOGRAPH SEVEN -// 3227 PARENTHESIZED IDEOGRAPH EIGHT -// 3228 PARENTHESIZED IDEOGRAPH NINE -// 3229 PARENTHESIZED IDEOGRAPH TEN -// 322a PARENTHESIZED IDEOGRAPH MOON -// 322b PARENTHESIZED IDEOGRAPH FIRE -// 322c PARENTHESIZED IDEOGRAPH WATER -// 322d PARENTHESIZED IDEOGRAPH WOOD -// 322e PARENTHESIZED IDEOGRAPH METAL -// 322f PARENTHESIZED IDEOGRAPH EARTH -// 3230 PARENTHESIZED IDEOGRAPH SUN -// 3231 PARENTHESIZED IDEOGRAPH STOCK -// 3232 PARENTHESIZED IDEOGRAPH HAVE -// 3233 PARENTHESIZED IDEOGRAPH SOCIETY -// 3234 PARENTHESIZED IDEOGRAPH NAME -// 3235 PARENTHESIZED IDEOGRAPH SPECIAL -// 3236 PARENTHESIZED IDEOGRAPH FINANCIAL -// 3237 PARENTHESIZED IDEOGRAPH CONGRATULATION -// 3238 PARENTHESIZED IDEOGRAPH LABOR -// 3239 PARENTHESIZED IDEOGRAPH REPRESENT -// 323a PARENTHESIZED IDEOGRAPH CALL -// 323b PARENTHESIZED IDEOGRAPH STUDY -// 323c PARENTHESIZED IDEOGRAPH SUPERVISE -// 323d PARENTHESIZED IDEOGRAPH ENTERPRISE -// 323e PARENTHESIZED IDEOGRAPH RESOURCE -// 323f PARENTHESIZED IDEOGRAPH ALLIANCE -// 3240 PARENTHESIZED IDEOGRAPH FESTIVAL -// 3241 PARENTHESIZED IDEOGRAPH REST -// 3242 PARENTHESIZED IDEOGRAPH SELF -// 3243 PARENTHESIZED IDEOGRAPH REACH -// 3244 CIRCLED IDEOGRAPH QUESTION -// 3245 CIRCLED IDEOGRAPH KINDERGARTEN -// 3246 CIRCLED IDEOGRAPH SCHOOL -// 3247 CIRCLED IDEOGRAPH KOTO -// 3248 CIRCLED NUMBER TEN ON BLACK SQUARE -// 3249 CIRCLED NUMBER TWENTY ON BLACK SQUARE -// 324a CIRCLED NUMBER THIRTY ON BLACK SQUARE -// 324b CIRCLED NUMBER FORTY ON BLACK SQUARE -// 324c CIRCLED NUMBER FIFTY ON BLACK SQUARE -// 324d CIRCLED NUMBER SIXTY ON BLACK SQUARE -// 324e CIRCLED NUMBER SEVENTY ON BLACK SQUARE -// 324f CIRCLED NUMBER EIGHTY ON BLACK SQUARE -// 3250 PARTNERSHIP SIGN -// 3251 CIRCLED NUMBER TWENTY ONE -// 3252 CIRCLED NUMBER TWENTY TWO -// 3253 CIRCLED NUMBER TWENTY THREE -// 3254 CIRCLED NUMBER TWENTY FOUR -// 3255 CIRCLED NUMBER TWENTY FIVE -// 3256 CIRCLED NUMBER TWENTY SIX -// 3257 CIRCLED NUMBER TWENTY SEVEN -// 3258 CIRCLED NUMBER TWENTY EIGHT -// 3259 CIRCLED NUMBER TWENTY NINE -// 325a CIRCLED NUMBER THIRTY -// 325b CIRCLED NUMBER THIRTY ONE -// 325c CIRCLED NUMBER THIRTY TWO -// 325d CIRCLED NUMBER THIRTY THREE -// 325e CIRCLED NUMBER THIRTY FOUR -// 325f CIRCLED NUMBER THIRTY FIVE -// 3260 CIRCLED HANGUL KIYEOK -// 3261 CIRCLED HANGUL NIEUN -// 3262 CIRCLED HANGUL TIKEUT -// 3263 CIRCLED HANGUL RIEUL -// 3264 CIRCLED HANGUL MIEUM -// 3265 CIRCLED HANGUL PIEUP -// 3266 CIRCLED HANGUL SIOS -// 3267 CIRCLED HANGUL IEUNG -// 3268 CIRCLED HANGUL CIEUC -// 3269 CIRCLED HANGUL CHIEUCH -// 326a CIRCLED HANGUL KHIEUKH -// 326b CIRCLED HANGUL THIEUTH -// 326c CIRCLED HANGUL PHIEUPH -// 326d CIRCLED HANGUL HIEUH -// 326e CIRCLED HANGUL KIYEOK A -// 326f CIRCLED HANGUL NIEUN A -// 3270 CIRCLED HANGUL TIKEUT A -// 3271 CIRCLED HANGUL RIEUL A -// 3272 CIRCLED HANGUL MIEUM A -// 3273 CIRCLED HANGUL PIEUP A -// 3274 CIRCLED HANGUL SIOS A -// 3275 CIRCLED HANGUL IEUNG A -// 3276 CIRCLED HANGUL CIEUC A -// 3277 CIRCLED HANGUL CHIEUCH A -// 3278 CIRCLED HANGUL KHIEUKH A -// 3279 CIRCLED HANGUL THIEUTH A -// 327a CIRCLED HANGUL PHIEUPH A -// 327b CIRCLED HANGUL HIEUH A -// 327c CIRCLED KOREAN CHARACTER CHAMKO -// 327d CIRCLED KOREAN CHARACTER JUEUI -// 327e CIRCLED HANGUL IEUNG U -// 327f KOREAN STANDARD SYMBOL -// 3280 CIRCLED IDEOGRAPH ONE -// 3281 CIRCLED IDEOGRAPH TWO -// 3282 CIRCLED IDEOGRAPH THREE -// 3283 CIRCLED IDEOGRAPH FOUR -// 3284 CIRCLED IDEOGRAPH FIVE -// 3285 CIRCLED IDEOGRAPH SIX -// 3286 CIRCLED IDEOGRAPH SEVEN -// 3287 CIRCLED IDEOGRAPH EIGHT -// 3288 CIRCLED IDEOGRAPH NINE -// 3289 CIRCLED IDEOGRAPH TEN -// 328a CIRCLED IDEOGRAPH MOON -// 328b CIRCLED IDEOGRAPH FIRE -// 328c CIRCLED IDEOGRAPH WATER -// 328d CIRCLED IDEOGRAPH WOOD -// 328e CIRCLED IDEOGRAPH METAL -// 328f CIRCLED IDEOGRAPH EARTH -// 3290 CIRCLED IDEOGRAPH SUN -// 3291 CIRCLED IDEOGRAPH STOCK -// 3292 CIRCLED IDEOGRAPH HAVE -// 3293 CIRCLED IDEOGRAPH SOCIETY -// 3294 CIRCLED IDEOGRAPH NAME -// 3295 CIRCLED IDEOGRAPH SPECIAL -// 3296 CIRCLED IDEOGRAPH FINANCIAL -// 3297 CIRCLED IDEOGRAPH CONGRATULATION -// 3298 CIRCLED IDEOGRAPH LABOR -// 3299 CIRCLED IDEOGRAPH SECRET -// 329a CIRCLED IDEOGRAPH MALE -// 329b CIRCLED IDEOGRAPH FEMALE -// 329c CIRCLED IDEOGRAPH SUITABLE -// 329d CIRCLED IDEOGRAPH EXCELLENT -// 329e CIRCLED IDEOGRAPH PRINT -// 329f CIRCLED IDEOGRAPH ATTENTION -// 32a0 CIRCLED IDEOGRAPH ITEM -// 32a1 CIRCLED IDEOGRAPH REST -// 32a2 CIRCLED IDEOGRAPH COPY -// 32a3 CIRCLED IDEOGRAPH CORRECT -// 32a4 CIRCLED IDEOGRAPH HIGH -// 32a5 CIRCLED IDEOGRAPH CENTRE -// 32a6 CIRCLED IDEOGRAPH LOW -// 32a7 CIRCLED IDEOGRAPH LEFT -// 32a8 CIRCLED IDEOGRAPH RIGHT -// 32a9 CIRCLED IDEOGRAPH MEDICINE -// 32aa CIRCLED IDEOGRAPH RELIGION -// 32ab CIRCLED IDEOGRAPH STUDY -// 32ac CIRCLED IDEOGRAPH SUPERVISE -// 32ad CIRCLED IDEOGRAPH ENTERPRISE -// 32ae CIRCLED IDEOGRAPH RESOURCE -// 32af CIRCLED IDEOGRAPH ALLIANCE -// 32b0 CIRCLED IDEOGRAPH NIGHT -// 32b1 CIRCLED NUMBER THIRTY SIX -// 32b2 CIRCLED NUMBER THIRTY SEVEN -// 32b3 CIRCLED NUMBER THIRTY EIGHT -// 32b4 CIRCLED NUMBER THIRTY NINE -// 32b5 CIRCLED NUMBER FORTY -// 32b6 CIRCLED NUMBER FORTY ONE -// 32b7 CIRCLED NUMBER FORTY TWO -// 32b8 CIRCLED NUMBER FORTY THREE -// 32b9 CIRCLED NUMBER FORTY FOUR -// 32ba CIRCLED NUMBER FORTY FIVE -// 32bb CIRCLED NUMBER FORTY SIX -// 32bc CIRCLED NUMBER FORTY SEVEN -// 32bd CIRCLED NUMBER FORTY EIGHT -// 32be CIRCLED NUMBER FORTY NINE -// 32bf CIRCLED NUMBER FIFTY -// 32c0 IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY -// 32c1 IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY -// 32c2 IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH -// 32c3 IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL -// 32c4 IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY -// 32c5 IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE -// 32c6 IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY -// 32c7 IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST -// 32c8 IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER -// 32c9 IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER -// 32ca IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER -// 32cb IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER -// 32cc SQUARE HG -// 32cd SQUARE ERG -// 32ce SQUARE EV -// 32cf LIMITED LIABILITY SIGN -// 32d0 CIRCLED KATAKANA A -// 32d1 CIRCLED KATAKANA I -// 32d2 CIRCLED KATAKANA U -// 32d3 CIRCLED KATAKANA E -// 32d4 CIRCLED KATAKANA O -// 32d5 CIRCLED KATAKANA KA -// 32d6 CIRCLED KATAKANA KI -// 32d7 CIRCLED KATAKANA KU -// 32d8 CIRCLED KATAKANA KE -// 32d9 CIRCLED KATAKANA KO -// 32da CIRCLED KATAKANA SA -// 32db CIRCLED KATAKANA SI -// 32dc CIRCLED KATAKANA SU -// 32dd CIRCLED KATAKANA SE -// 32de CIRCLED KATAKANA SO -// 32df CIRCLED KATAKANA TA -// 32e0 CIRCLED KATAKANA TI -// 32e1 CIRCLED KATAKANA TU -// 32e2 CIRCLED KATAKANA TE -// 32e3 CIRCLED KATAKANA TO -// 32e4 CIRCLED KATAKANA NA -// 32e5 CIRCLED KATAKANA NI -// 32e6 CIRCLED KATAKANA NU -// 32e7 CIRCLED KATAKANA NE -// 32e8 CIRCLED KATAKANA NO -// 32e9 CIRCLED KATAKANA HA -// 32ea CIRCLED KATAKANA HI -// 32eb CIRCLED KATAKANA HU -// 32ec CIRCLED KATAKANA HE -// 32ed CIRCLED KATAKANA HO -// 32ee CIRCLED KATAKANA MA -// 32ef CIRCLED KATAKANA MI -// 32f0 CIRCLED KATAKANA MU -// 32f1 CIRCLED KATAKANA ME -// 32f2 CIRCLED KATAKANA MO -// 32f3 CIRCLED KATAKANA YA -// 32f4 CIRCLED KATAKANA YU -// 32f5 CIRCLED KATAKANA YO -// 32f6 CIRCLED KATAKANA RA -// 32f7 CIRCLED KATAKANA RI -// 32f8 CIRCLED KATAKANA RU -// 32f9 CIRCLED KATAKANA RE -// 32fa CIRCLED KATAKANA RO -// 32fb CIRCLED KATAKANA WA -// 32fc CIRCLED KATAKANA WI -// 32fd CIRCLED KATAKANA WE -// 32fe CIRCLED KATAKANA WO - { 0x3220, 0xDF, 0x8, 0, 0 }, -// 3300 SQUARE APAATO -// 3301 SQUARE ARUHUA -// 3302 SQUARE ANPEA -// 3303 SQUARE AARU -// 3304 SQUARE ININGU -// 3305 SQUARE INTI -// 3306 SQUARE UON -// 3307 SQUARE ESUKUUDO -// 3308 SQUARE EEKAA -// 3309 SQUARE ONSU -// 330a SQUARE OOMU -// 330b SQUARE KAIRI -// 330c SQUARE KARATTO -// 330d SQUARE KARORII -// 330e SQUARE GARON -// 330f SQUARE GANMA -// 3310 SQUARE GIGA -// 3311 SQUARE GINII -// 3312 SQUARE KYURII -// 3313 SQUARE GIRUDAA -// 3314 SQUARE KIRO -// 3315 SQUARE KIROGURAMU -// 3316 SQUARE KIROMEETORU -// 3317 SQUARE KIROWATTO -// 3318 SQUARE GURAMU -// 3319 SQUARE GURAMUTON -// 331a SQUARE KURUZEIRO -// 331b SQUARE KUROONE -// 331c SQUARE KEESU -// 331d SQUARE KORUNA -// 331e SQUARE KOOPO -// 331f SQUARE SAIKURU -// 3320 SQUARE SANTIIMU -// 3321 SQUARE SIRINGU -// 3322 SQUARE SENTI -// 3323 SQUARE SENTO -// 3324 SQUARE DAASU -// 3325 SQUARE DESI -// 3326 SQUARE DORU -// 3327 SQUARE TON -// 3328 SQUARE NANO -// 3329 SQUARE NOTTO -// 332a SQUARE HAITU -// 332b SQUARE PAASENTO -// 332c SQUARE PAATU -// 332d SQUARE BAARERU -// 332e SQUARE PIASUTORU -// 332f SQUARE PIKURU -// 3330 SQUARE PIKO -// 3331 SQUARE BIRU -// 3332 SQUARE HUARADDO -// 3333 SQUARE HUIITO -// 3334 SQUARE BUSSYERU -// 3335 SQUARE HURAN -// 3336 SQUARE HEKUTAARU -// 3337 SQUARE PESO -// 3338 SQUARE PENIHI -// 3339 SQUARE HERUTU -// 333a SQUARE PENSU -// 333b SQUARE PEEZI -// 333c SQUARE BEETA -// 333d SQUARE POINTO -// 333e SQUARE BORUTO -// 333f SQUARE HON -// 3340 SQUARE PONDO -// 3341 SQUARE HOORU -// 3342 SQUARE HOON -// 3343 SQUARE MAIKURO -// 3344 SQUARE MAIRU -// 3345 SQUARE MAHHA -// 3346 SQUARE MARUKU -// 3347 SQUARE MANSYON -// 3348 SQUARE MIKURON -// 3349 SQUARE MIRI -// 334a SQUARE MIRIBAARU -// 334b SQUARE MEGA -// 334c SQUARE MEGATON -// 334d SQUARE MEETORU -// 334e SQUARE YAADO -// 334f SQUARE YAARU -// 3350 SQUARE YUAN -// 3351 SQUARE RITTORU -// 3352 SQUARE RIRA -// 3353 SQUARE RUPII -// 3354 SQUARE RUUBURU -// 3355 SQUARE REMU -// 3356 SQUARE RENTOGEN -// 3357 SQUARE WATTO -// 3358 IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO -// 3359 IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE -// 335a IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO -// 335b IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE -// 335c IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR -// 335d IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE -// 335e IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX -// 335f IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN -// 3360 IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT -// 3361 IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE -// 3362 IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN -// 3363 IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN -// 3364 IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE -// 3365 IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN -// 3366 IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN -// 3367 IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN -// 3368 IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN -// 3369 IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN -// 336a IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN -// 336b IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN -// 336c IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY -// 336d IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE -// 336e IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO -// 336f IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE -// 3370 IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR -// 3371 SQUARE HPA -// 3372 SQUARE DA -// 3373 SQUARE AU -// 3374 SQUARE BAR -// 3375 SQUARE OV -// 3376 SQUARE PC -// 3377 SQUARE DM -// 3378 SQUARE DM SQUARED -// 3379 SQUARE DM CUBED -// 337a SQUARE IU -// 337b SQUARE ERA NAME HEISEI -// 337c SQUARE ERA NAME SYOUWA -// 337d SQUARE ERA NAME TAISYOU -// 337e SQUARE ERA NAME MEIZI -// 337f SQUARE CORPORATION -// 3380 SQUARE PA AMPS -// 3381 SQUARE NA -// 3382 SQUARE MU A -// 3383 SQUARE MA -// 3384 SQUARE KA -// 3385 SQUARE KB -// 3386 SQUARE MB -// 3387 SQUARE GB -// 3388 SQUARE CAL -// 3389 SQUARE KCAL -// 338a SQUARE PF -// 338b SQUARE NF -// 338c SQUARE MU F -// 338d SQUARE MU G -// 338e SQUARE MG -// 338f SQUARE KG -// 3390 SQUARE HZ -// 3391 SQUARE KHZ -// 3392 SQUARE MHZ -// 3393 SQUARE GHZ -// 3394 SQUARE THZ -// 3395 SQUARE MU L -// 3396 SQUARE ML -// 3397 SQUARE DL -// 3398 SQUARE KL -// 3399 SQUARE FM -// 339a SQUARE NM -// 339b SQUARE MU M -// 339c SQUARE MM -// 339d SQUARE CM -// 339e SQUARE KM -// 339f SQUARE MM SQUARED -// 33a0 SQUARE CM SQUARED -// 33a1 SQUARE M SQUARED -// 33a2 SQUARE KM SQUARED -// 33a3 SQUARE MM CUBED -// 33a4 SQUARE CM CUBED -// 33a5 SQUARE M CUBED -// 33a6 SQUARE KM CUBED -// 33a7 SQUARE M OVER S -// 33a8 SQUARE M OVER S SQUARED -// 33a9 SQUARE PA -// 33aa SQUARE KPA -// 33ab SQUARE MPA -// 33ac SQUARE GPA -// 33ad SQUARE RAD -// 33ae SQUARE RAD OVER S -// 33af SQUARE RAD OVER S SQUARED -// 33b0 SQUARE PS -// 33b1 SQUARE NS -// 33b2 SQUARE MU S -// 33b3 SQUARE MS -// 33b4 SQUARE PV -// 33b5 SQUARE NV -// 33b6 SQUARE MU V -// 33b7 SQUARE MV -// 33b8 SQUARE KV -// 33b9 SQUARE MV MEGA -// 33ba SQUARE PW -// 33bb SQUARE NW -// 33bc SQUARE MU W -// 33bd SQUARE MW -// 33be SQUARE KW -// 33bf SQUARE MW MEGA -// 33c0 SQUARE K OHM -// 33c1 SQUARE M OHM -// 33c2 SQUARE AM -// 33c3 SQUARE BQ -// 33c4 SQUARE CC -// 33c5 SQUARE CD -// 33c6 SQUARE C OVER KG -// 33c7 SQUARE CO -// 33c8 SQUARE DB -// 33c9 SQUARE GY -// 33ca SQUARE HA -// 33cb SQUARE HP -// 33cc SQUARE IN -// 33cd SQUARE KK -// 33ce SQUARE KM CAPITAL -// 33cf SQUARE KT -// 33d0 SQUARE LM -// 33d1 SQUARE LN -// 33d2 SQUARE LOG -// 33d3 SQUARE LX -// 33d4 SQUARE MB SMALL -// 33d5 SQUARE MIL -// 33d6 SQUARE MOL -// 33d7 SQUARE PH -// 33d8 SQUARE PM -// 33d9 SQUARE PPM -// 33da SQUARE PR -// 33db SQUARE SR -// 33dc SQUARE SV -// 33dd SQUARE WB -// 33de SQUARE V OVER M -// 33df SQUARE A OVER M -// 33e0 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE -// 33e1 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO -// 33e2 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE -// 33e3 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR -// 33e4 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE -// 33e5 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX -// 33e6 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN -// 33e7 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT -// 33e8 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE -// 33e9 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN -// 33ea IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN -// 33eb IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE -// 33ec IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN -// 33ed IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN -// 33ee IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN -// 33ef IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN -// 33f0 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN -// 33f1 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN -// 33f2 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN -// 33f3 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY -// 33f4 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE -// 33f5 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO -// 33f6 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE -// 33f7 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR -// 33f8 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE -// 33f9 IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX -// 33fa IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN -// 33fb IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT -// 33fc IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE -// 33fd IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY -// 33fe IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE -// 33ff SQUARE GAL - { 0x3300, 0x100, 0x8, 0, 0 }, -// 3400 - { 0x3400, 0x1, 0x9, 0, 0 }, -// 4db5 - { 0x4DB5, 0x1, 0x9, 0, 0 }, -// 4dc0 HEXAGRAM FOR THE CREATIVE HEAVEN -// 4dc1 HEXAGRAM FOR THE RECEPTIVE EARTH -// 4dc2 HEXAGRAM FOR DIFFICULTY AT THE BEGINNING -// 4dc3 HEXAGRAM FOR YOUTHFUL FOLLY -// 4dc4 HEXAGRAM FOR WAITING -// 4dc5 HEXAGRAM FOR CONFLICT -// 4dc6 HEXAGRAM FOR THE ARMY -// 4dc7 HEXAGRAM FOR HOLDING TOGETHER -// 4dc8 HEXAGRAM FOR SMALL TAMING -// 4dc9 HEXAGRAM FOR TREADING -// 4dca HEXAGRAM FOR PEACE -// 4dcb HEXAGRAM FOR STANDSTILL -// 4dcc HEXAGRAM FOR FELLOWSHIP -// 4dcd HEXAGRAM FOR GREAT POSSESSION -// 4dce HEXAGRAM FOR MODESTY -// 4dcf HEXAGRAM FOR ENTHUSIASM -// 4dd0 HEXAGRAM FOR FOLLOWING -// 4dd1 HEXAGRAM FOR WORK ON THE DECAYED -// 4dd2 HEXAGRAM FOR APPROACH -// 4dd3 HEXAGRAM FOR CONTEMPLATION -// 4dd4 HEXAGRAM FOR BITING THROUGH -// 4dd5 HEXAGRAM FOR GRACE -// 4dd6 HEXAGRAM FOR SPLITTING APART -// 4dd7 HEXAGRAM FOR RETURN -// 4dd8 HEXAGRAM FOR INNOCENCE -// 4dd9 HEXAGRAM FOR GREAT TAMING -// 4dda HEXAGRAM FOR MOUTH CORNERS -// 4ddb HEXAGRAM FOR GREAT PREPONDERANCE -// 4ddc HEXAGRAM FOR THE ABYSMAL WATER -// 4ddd HEXAGRAM FOR THE CLINGING FIRE -// 4dde HEXAGRAM FOR INFLUENCE -// 4ddf HEXAGRAM FOR DURATION -// 4de0 HEXAGRAM FOR RETREAT -// 4de1 HEXAGRAM FOR GREAT POWER -// 4de2 HEXAGRAM FOR PROGRESS -// 4de3 HEXAGRAM FOR DARKENING OF THE LIGHT -// 4de4 HEXAGRAM FOR THE FAMILY -// 4de5 HEXAGRAM FOR OPPOSITION -// 4de6 HEXAGRAM FOR OBSTRUCTION -// 4de7 HEXAGRAM FOR DELIVERANCE -// 4de8 HEXAGRAM FOR DECREASE -// 4de9 HEXAGRAM FOR INCREASE -// 4dea HEXAGRAM FOR BREAKTHROUGH -// 4deb HEXAGRAM FOR COMING TO MEET -// 4dec HEXAGRAM FOR GATHERING TOGETHER -// 4ded HEXAGRAM FOR PUSHING UPWARD -// 4dee HEXAGRAM FOR OPPRESSION -// 4def HEXAGRAM FOR THE WELL -// 4df0 HEXAGRAM FOR REVOLUTION -// 4df1 HEXAGRAM FOR THE CAULDRON -// 4df2 HEXAGRAM FOR THE AROUSING THUNDER -// 4df3 HEXAGRAM FOR THE KEEPING STILL MOUNTAIN -// 4df4 HEXAGRAM FOR DEVELOPMENT -// 4df5 HEXAGRAM FOR THE MARRYING MAIDEN -// 4df6 HEXAGRAM FOR ABUNDANCE -// 4df7 HEXAGRAM FOR THE WANDERER -// 4df8 HEXAGRAM FOR THE GENTLE WIND -// 4df9 HEXAGRAM FOR THE JOYOUS LAKE -// 4dfa HEXAGRAM FOR DISPERSION -// 4dfb HEXAGRAM FOR LIMITATION -// 4dfc HEXAGRAM FOR INNER TRUTH -// 4dfd HEXAGRAM FOR SMALL PREPONDERANCE -// 4dfe HEXAGRAM FOR AFTER COMPLETION -// 4dff HEXAGRAM FOR BEFORE COMPLETION - { 0x4DC0, 0x40, 0x8, 0, 0 }, -// 4e00 - { 0x4E00, 0x1, 0x9, 0, 0 }, -// 9fcc - { 0x9FCC, 0x1, 0x9, 0, 0 }, -// a000 YI SYLLABLE IT -// a001 YI SYLLABLE IX -// a002 YI SYLLABLE I -// a003 YI SYLLABLE IP -// a004 YI SYLLABLE IET -// a005 YI SYLLABLE IEX -// a006 YI SYLLABLE IE -// a007 YI SYLLABLE IEP -// a008 YI SYLLABLE AT -// a009 YI SYLLABLE AX -// a00a YI SYLLABLE A -// a00b YI SYLLABLE AP -// a00c YI SYLLABLE UOX -// a00d YI SYLLABLE UO -// a00e YI SYLLABLE UOP -// a00f YI SYLLABLE OT -// a010 YI SYLLABLE OX -// a011 YI SYLLABLE O -// a012 YI SYLLABLE OP -// a013 YI SYLLABLE EX -// a014 YI SYLLABLE E -// a015 YI SYLLABLE WU -// a016 YI SYLLABLE BIT -// a017 YI SYLLABLE BIX -// a018 YI SYLLABLE BI -// a019 YI SYLLABLE BIP -// a01a YI SYLLABLE BIET -// a01b YI SYLLABLE BIEX -// a01c YI SYLLABLE BIE -// a01d YI SYLLABLE BIEP -// a01e YI SYLLABLE BAT -// a01f YI SYLLABLE BAX -// a020 YI SYLLABLE BA -// a021 YI SYLLABLE BAP -// a022 YI SYLLABLE BUOX -// a023 YI SYLLABLE BUO -// a024 YI SYLLABLE BUOP -// a025 YI SYLLABLE BOT -// a026 YI SYLLABLE BOX -// a027 YI SYLLABLE BO -// a028 YI SYLLABLE BOP -// a029 YI SYLLABLE BEX -// a02a YI SYLLABLE BE -// a02b YI SYLLABLE BEP -// a02c YI SYLLABLE BUT -// a02d YI SYLLABLE BUX -// a02e YI SYLLABLE BU -// a02f YI SYLLABLE BUP -// a030 YI SYLLABLE BURX -// a031 YI SYLLABLE BUR -// a032 YI SYLLABLE BYT -// a033 YI SYLLABLE BYX -// a034 YI SYLLABLE BY -// a035 YI SYLLABLE BYP -// a036 YI SYLLABLE BYRX -// a037 YI SYLLABLE BYR -// a038 YI SYLLABLE PIT -// a039 YI SYLLABLE PIX -// a03a YI SYLLABLE PI -// a03b YI SYLLABLE PIP -// a03c YI SYLLABLE PIEX -// a03d YI SYLLABLE PIE -// a03e YI SYLLABLE PIEP -// a03f YI SYLLABLE PAT -// a040 YI SYLLABLE PAX -// a041 YI SYLLABLE PA -// a042 YI SYLLABLE PAP -// a043 YI SYLLABLE PUOX -// a044 YI SYLLABLE PUO -// a045 YI SYLLABLE PUOP -// a046 YI SYLLABLE POT -// a047 YI SYLLABLE POX -// a048 YI SYLLABLE PO -// a049 YI SYLLABLE POP -// a04a YI SYLLABLE PUT -// a04b YI SYLLABLE PUX -// a04c YI SYLLABLE PU -// a04d YI SYLLABLE PUP -// a04e YI SYLLABLE PURX -// a04f YI SYLLABLE PUR -// a050 YI SYLLABLE PYT -// a051 YI SYLLABLE PYX -// a052 YI SYLLABLE PY -// a053 YI SYLLABLE PYP -// a054 YI SYLLABLE PYRX -// a055 YI SYLLABLE PYR -// a056 YI SYLLABLE BBIT -// a057 YI SYLLABLE BBIX -// a058 YI SYLLABLE BBI -// a059 YI SYLLABLE BBIP -// a05a YI SYLLABLE BBIET -// a05b YI SYLLABLE BBIEX -// a05c YI SYLLABLE BBIE -// a05d YI SYLLABLE BBIEP -// a05e YI SYLLABLE BBAT -// a05f YI SYLLABLE BBAX -// a060 YI SYLLABLE BBA -// a061 YI SYLLABLE BBAP -// a062 YI SYLLABLE BBUOX -// a063 YI SYLLABLE BBUO -// a064 YI SYLLABLE BBUOP -// a065 YI SYLLABLE BBOT -// a066 YI SYLLABLE BBOX -// a067 YI SYLLABLE BBO -// a068 YI SYLLABLE BBOP -// a069 YI SYLLABLE BBEX -// a06a YI SYLLABLE BBE -// a06b YI SYLLABLE BBEP -// a06c YI SYLLABLE BBUT -// a06d YI SYLLABLE BBUX -// a06e YI SYLLABLE BBU -// a06f YI SYLLABLE BBUP -// a070 YI SYLLABLE BBURX -// a071 YI SYLLABLE BBUR -// a072 YI SYLLABLE BBYT -// a073 YI SYLLABLE BBYX -// a074 YI SYLLABLE BBY -// a075 YI SYLLABLE BBYP -// a076 YI SYLLABLE NBIT -// a077 YI SYLLABLE NBIX -// a078 YI SYLLABLE NBI -// a079 YI SYLLABLE NBIP -// a07a YI SYLLABLE NBIEX -// a07b YI SYLLABLE NBIE -// a07c YI SYLLABLE NBIEP -// a07d YI SYLLABLE NBAT -// a07e YI SYLLABLE NBAX -// a07f YI SYLLABLE NBA -// a080 YI SYLLABLE NBAP -// a081 YI SYLLABLE NBOT -// a082 YI SYLLABLE NBOX -// a083 YI SYLLABLE NBO -// a084 YI SYLLABLE NBOP -// a085 YI SYLLABLE NBUT -// a086 YI SYLLABLE NBUX -// a087 YI SYLLABLE NBU -// a088 YI SYLLABLE NBUP -// a089 YI SYLLABLE NBURX -// a08a YI SYLLABLE NBUR -// a08b YI SYLLABLE NBYT -// a08c YI SYLLABLE NBYX -// a08d YI SYLLABLE NBY -// a08e YI SYLLABLE NBYP -// a08f YI SYLLABLE NBYRX -// a090 YI SYLLABLE NBYR -// a091 YI SYLLABLE HMIT -// a092 YI SYLLABLE HMIX -// a093 YI SYLLABLE HMI -// a094 YI SYLLABLE HMIP -// a095 YI SYLLABLE HMIEX -// a096 YI SYLLABLE HMIE -// a097 YI SYLLABLE HMIEP -// a098 YI SYLLABLE HMAT -// a099 YI SYLLABLE HMAX -// a09a YI SYLLABLE HMA -// a09b YI SYLLABLE HMAP -// a09c YI SYLLABLE HMUOX -// a09d YI SYLLABLE HMUO -// a09e YI SYLLABLE HMUOP -// a09f YI SYLLABLE HMOT -// a0a0 YI SYLLABLE HMOX -// a0a1 YI SYLLABLE HMO -// a0a2 YI SYLLABLE HMOP -// a0a3 YI SYLLABLE HMUT -// a0a4 YI SYLLABLE HMUX -// a0a5 YI SYLLABLE HMU -// a0a6 YI SYLLABLE HMUP -// a0a7 YI SYLLABLE HMURX -// a0a8 YI SYLLABLE HMUR -// a0a9 YI SYLLABLE HMYX -// a0aa YI SYLLABLE HMY -// a0ab YI SYLLABLE HMYP -// a0ac YI SYLLABLE HMYRX -// a0ad YI SYLLABLE HMYR -// a0ae YI SYLLABLE MIT -// a0af YI SYLLABLE MIX -// a0b0 YI SYLLABLE MI -// a0b1 YI SYLLABLE MIP -// a0b2 YI SYLLABLE MIEX -// a0b3 YI SYLLABLE MIE -// a0b4 YI SYLLABLE MIEP -// a0b5 YI SYLLABLE MAT -// a0b6 YI SYLLABLE MAX -// a0b7 YI SYLLABLE MA -// a0b8 YI SYLLABLE MAP -// a0b9 YI SYLLABLE MUOT -// a0ba YI SYLLABLE MUOX -// a0bb YI SYLLABLE MUO -// a0bc YI SYLLABLE MUOP -// a0bd YI SYLLABLE MOT -// a0be YI SYLLABLE MOX -// a0bf YI SYLLABLE MO -// a0c0 YI SYLLABLE MOP -// a0c1 YI SYLLABLE MEX -// a0c2 YI SYLLABLE ME -// a0c3 YI SYLLABLE MUT -// a0c4 YI SYLLABLE MUX -// a0c5 YI SYLLABLE MU -// a0c6 YI SYLLABLE MUP -// a0c7 YI SYLLABLE MURX -// a0c8 YI SYLLABLE MUR -// a0c9 YI SYLLABLE MYT -// a0ca YI SYLLABLE MYX -// a0cb YI SYLLABLE MY -// a0cc YI SYLLABLE MYP -// a0cd YI SYLLABLE FIT -// a0ce YI SYLLABLE FIX -// a0cf YI SYLLABLE FI -// a0d0 YI SYLLABLE FIP -// a0d1 YI SYLLABLE FAT -// a0d2 YI SYLLABLE FAX -// a0d3 YI SYLLABLE FA -// a0d4 YI SYLLABLE FAP -// a0d5 YI SYLLABLE FOX -// a0d6 YI SYLLABLE FO -// a0d7 YI SYLLABLE FOP -// a0d8 YI SYLLABLE FUT -// a0d9 YI SYLLABLE FUX -// a0da YI SYLLABLE FU -// a0db YI SYLLABLE FUP -// a0dc YI SYLLABLE FURX -// a0dd YI SYLLABLE FUR -// a0de YI SYLLABLE FYT -// a0df YI SYLLABLE FYX -// a0e0 YI SYLLABLE FY -// a0e1 YI SYLLABLE FYP -// a0e2 YI SYLLABLE VIT -// a0e3 YI SYLLABLE VIX -// a0e4 YI SYLLABLE VI -// a0e5 YI SYLLABLE VIP -// a0e6 YI SYLLABLE VIET -// a0e7 YI SYLLABLE VIEX -// a0e8 YI SYLLABLE VIE -// a0e9 YI SYLLABLE VIEP -// a0ea YI SYLLABLE VAT -// a0eb YI SYLLABLE VAX -// a0ec YI SYLLABLE VA -// a0ed YI SYLLABLE VAP -// a0ee YI SYLLABLE VOT -// a0ef YI SYLLABLE VOX -// a0f0 YI SYLLABLE VO -// a0f1 YI SYLLABLE VOP -// a0f2 YI SYLLABLE VEX -// a0f3 YI SYLLABLE VEP -// a0f4 YI SYLLABLE VUT -// a0f5 YI SYLLABLE VUX -// a0f6 YI SYLLABLE VU -// a0f7 YI SYLLABLE VUP -// a0f8 YI SYLLABLE VURX -// a0f9 YI SYLLABLE VUR -// a0fa YI SYLLABLE VYT -// a0fb YI SYLLABLE VYX -// a0fc YI SYLLABLE VY -// a0fd YI SYLLABLE VYP -// a0fe YI SYLLABLE VYRX -// a0ff YI SYLLABLE VYR -// a100 YI SYLLABLE DIT -// a101 YI SYLLABLE DIX -// a102 YI SYLLABLE DI -// a103 YI SYLLABLE DIP -// a104 YI SYLLABLE DIEX -// a105 YI SYLLABLE DIE -// a106 YI SYLLABLE DIEP -// a107 YI SYLLABLE DAT -// a108 YI SYLLABLE DAX -// a109 YI SYLLABLE DA -// a10a YI SYLLABLE DAP -// a10b YI SYLLABLE DUOX -// a10c YI SYLLABLE DUO -// a10d YI SYLLABLE DOT -// a10e YI SYLLABLE DOX -// a10f YI SYLLABLE DO -// a110 YI SYLLABLE DOP -// a111 YI SYLLABLE DEX -// a112 YI SYLLABLE DE -// a113 YI SYLLABLE DEP -// a114 YI SYLLABLE DUT -// a115 YI SYLLABLE DUX -// a116 YI SYLLABLE DU -// a117 YI SYLLABLE DUP -// a118 YI SYLLABLE DURX -// a119 YI SYLLABLE DUR -// a11a YI SYLLABLE TIT -// a11b YI SYLLABLE TIX -// a11c YI SYLLABLE TI -// a11d YI SYLLABLE TIP -// a11e YI SYLLABLE TIEX -// a11f YI SYLLABLE TIE -// a120 YI SYLLABLE TIEP -// a121 YI SYLLABLE TAT -// a122 YI SYLLABLE TAX -// a123 YI SYLLABLE TA -// a124 YI SYLLABLE TAP -// a125 YI SYLLABLE TUOT -// a126 YI SYLLABLE TUOX -// a127 YI SYLLABLE TUO -// a128 YI SYLLABLE TUOP -// a129 YI SYLLABLE TOT -// a12a YI SYLLABLE TOX -// a12b YI SYLLABLE TO -// a12c YI SYLLABLE TOP -// a12d YI SYLLABLE TEX -// a12e YI SYLLABLE TE -// a12f YI SYLLABLE TEP -// a130 YI SYLLABLE TUT -// a131 YI SYLLABLE TUX -// a132 YI SYLLABLE TU -// a133 YI SYLLABLE TUP -// a134 YI SYLLABLE TURX -// a135 YI SYLLABLE TUR -// a136 YI SYLLABLE DDIT -// a137 YI SYLLABLE DDIX -// a138 YI SYLLABLE DDI -// a139 YI SYLLABLE DDIP -// a13a YI SYLLABLE DDIEX -// a13b YI SYLLABLE DDIE -// a13c YI SYLLABLE DDIEP -// a13d YI SYLLABLE DDAT -// a13e YI SYLLABLE DDAX -// a13f YI SYLLABLE DDA -// a140 YI SYLLABLE DDAP -// a141 YI SYLLABLE DDUOX -// a142 YI SYLLABLE DDUO -// a143 YI SYLLABLE DDUOP -// a144 YI SYLLABLE DDOT -// a145 YI SYLLABLE DDOX -// a146 YI SYLLABLE DDO -// a147 YI SYLLABLE DDOP -// a148 YI SYLLABLE DDEX -// a149 YI SYLLABLE DDE -// a14a YI SYLLABLE DDEP -// a14b YI SYLLABLE DDUT -// a14c YI SYLLABLE DDUX -// a14d YI SYLLABLE DDU -// a14e YI SYLLABLE DDUP -// a14f YI SYLLABLE DDURX -// a150 YI SYLLABLE DDUR -// a151 YI SYLLABLE NDIT -// a152 YI SYLLABLE NDIX -// a153 YI SYLLABLE NDI -// a154 YI SYLLABLE NDIP -// a155 YI SYLLABLE NDIEX -// a156 YI SYLLABLE NDIE -// a157 YI SYLLABLE NDAT -// a158 YI SYLLABLE NDAX -// a159 YI SYLLABLE NDA -// a15a YI SYLLABLE NDAP -// a15b YI SYLLABLE NDOT -// a15c YI SYLLABLE NDOX -// a15d YI SYLLABLE NDO -// a15e YI SYLLABLE NDOP -// a15f YI SYLLABLE NDEX -// a160 YI SYLLABLE NDE -// a161 YI SYLLABLE NDEP -// a162 YI SYLLABLE NDUT -// a163 YI SYLLABLE NDUX -// a164 YI SYLLABLE NDU -// a165 YI SYLLABLE NDUP -// a166 YI SYLLABLE NDURX -// a167 YI SYLLABLE NDUR -// a168 YI SYLLABLE HNIT -// a169 YI SYLLABLE HNIX -// a16a YI SYLLABLE HNI -// a16b YI SYLLABLE HNIP -// a16c YI SYLLABLE HNIET -// a16d YI SYLLABLE HNIEX -// a16e YI SYLLABLE HNIE -// a16f YI SYLLABLE HNIEP -// a170 YI SYLLABLE HNAT -// a171 YI SYLLABLE HNAX -// a172 YI SYLLABLE HNA -// a173 YI SYLLABLE HNAP -// a174 YI SYLLABLE HNUOX -// a175 YI SYLLABLE HNUO -// a176 YI SYLLABLE HNOT -// a177 YI SYLLABLE HNOX -// a178 YI SYLLABLE HNOP -// a179 YI SYLLABLE HNEX -// a17a YI SYLLABLE HNE -// a17b YI SYLLABLE HNEP -// a17c YI SYLLABLE HNUT -// a17d YI SYLLABLE NIT -// a17e YI SYLLABLE NIX -// a17f YI SYLLABLE NI -// a180 YI SYLLABLE NIP -// a181 YI SYLLABLE NIEX -// a182 YI SYLLABLE NIE -// a183 YI SYLLABLE NIEP -// a184 YI SYLLABLE NAX -// a185 YI SYLLABLE NA -// a186 YI SYLLABLE NAP -// a187 YI SYLLABLE NUOX -// a188 YI SYLLABLE NUO -// a189 YI SYLLABLE NUOP -// a18a YI SYLLABLE NOT -// a18b YI SYLLABLE NOX -// a18c YI SYLLABLE NO -// a18d YI SYLLABLE NOP -// a18e YI SYLLABLE NEX -// a18f YI SYLLABLE NE -// a190 YI SYLLABLE NEP -// a191 YI SYLLABLE NUT -// a192 YI SYLLABLE NUX -// a193 YI SYLLABLE NU -// a194 YI SYLLABLE NUP -// a195 YI SYLLABLE NURX -// a196 YI SYLLABLE NUR -// a197 YI SYLLABLE HLIT -// a198 YI SYLLABLE HLIX -// a199 YI SYLLABLE HLI -// a19a YI SYLLABLE HLIP -// a19b YI SYLLABLE HLIEX -// a19c YI SYLLABLE HLIE -// a19d YI SYLLABLE HLIEP -// a19e YI SYLLABLE HLAT -// a19f YI SYLLABLE HLAX -// a1a0 YI SYLLABLE HLA -// a1a1 YI SYLLABLE HLAP -// a1a2 YI SYLLABLE HLUOX -// a1a3 YI SYLLABLE HLUO -// a1a4 YI SYLLABLE HLUOP -// a1a5 YI SYLLABLE HLOX -// a1a6 YI SYLLABLE HLO -// a1a7 YI SYLLABLE HLOP -// a1a8 YI SYLLABLE HLEX -// a1a9 YI SYLLABLE HLE -// a1aa YI SYLLABLE HLEP -// a1ab YI SYLLABLE HLUT -// a1ac YI SYLLABLE HLUX -// a1ad YI SYLLABLE HLU -// a1ae YI SYLLABLE HLUP -// a1af YI SYLLABLE HLURX -// a1b0 YI SYLLABLE HLUR -// a1b1 YI SYLLABLE HLYT -// a1b2 YI SYLLABLE HLYX -// a1b3 YI SYLLABLE HLY -// a1b4 YI SYLLABLE HLYP -// a1b5 YI SYLLABLE HLYRX -// a1b6 YI SYLLABLE HLYR -// a1b7 YI SYLLABLE LIT -// a1b8 YI SYLLABLE LIX -// a1b9 YI SYLLABLE LI -// a1ba YI SYLLABLE LIP -// a1bb YI SYLLABLE LIET -// a1bc YI SYLLABLE LIEX -// a1bd YI SYLLABLE LIE -// a1be YI SYLLABLE LIEP -// a1bf YI SYLLABLE LAT -// a1c0 YI SYLLABLE LAX -// a1c1 YI SYLLABLE LA -// a1c2 YI SYLLABLE LAP -// a1c3 YI SYLLABLE LUOT -// a1c4 YI SYLLABLE LUOX -// a1c5 YI SYLLABLE LUO -// a1c6 YI SYLLABLE LUOP -// a1c7 YI SYLLABLE LOT -// a1c8 YI SYLLABLE LOX -// a1c9 YI SYLLABLE LO -// a1ca YI SYLLABLE LOP -// a1cb YI SYLLABLE LEX -// a1cc YI SYLLABLE LE -// a1cd YI SYLLABLE LEP -// a1ce YI SYLLABLE LUT -// a1cf YI SYLLABLE LUX -// a1d0 YI SYLLABLE LU -// a1d1 YI SYLLABLE LUP -// a1d2 YI SYLLABLE LURX -// a1d3 YI SYLLABLE LUR -// a1d4 YI SYLLABLE LYT -// a1d5 YI SYLLABLE LYX -// a1d6 YI SYLLABLE LY -// a1d7 YI SYLLABLE LYP -// a1d8 YI SYLLABLE LYRX -// a1d9 YI SYLLABLE LYR -// a1da YI SYLLABLE GIT -// a1db YI SYLLABLE GIX -// a1dc YI SYLLABLE GI -// a1dd YI SYLLABLE GIP -// a1de YI SYLLABLE GIET -// a1df YI SYLLABLE GIEX -// a1e0 YI SYLLABLE GIE -// a1e1 YI SYLLABLE GIEP -// a1e2 YI SYLLABLE GAT -// a1e3 YI SYLLABLE GAX -// a1e4 YI SYLLABLE GA -// a1e5 YI SYLLABLE GAP -// a1e6 YI SYLLABLE GUOT -// a1e7 YI SYLLABLE GUOX -// a1e8 YI SYLLABLE GUO -// a1e9 YI SYLLABLE GUOP -// a1ea YI SYLLABLE GOT -// a1eb YI SYLLABLE GOX -// a1ec YI SYLLABLE GO -// a1ed YI SYLLABLE GOP -// a1ee YI SYLLABLE GET -// a1ef YI SYLLABLE GEX -// a1f0 YI SYLLABLE GE -// a1f1 YI SYLLABLE GEP -// a1f2 YI SYLLABLE GUT -// a1f3 YI SYLLABLE GUX -// a1f4 YI SYLLABLE GU -// a1f5 YI SYLLABLE GUP -// a1f6 YI SYLLABLE GURX -// a1f7 YI SYLLABLE GUR -// a1f8 YI SYLLABLE KIT -// a1f9 YI SYLLABLE KIX -// a1fa YI SYLLABLE KI -// a1fb YI SYLLABLE KIP -// a1fc YI SYLLABLE KIEX -// a1fd YI SYLLABLE KIE -// a1fe YI SYLLABLE KIEP -// a1ff YI SYLLABLE KAT -// a200 YI SYLLABLE KAX -// a201 YI SYLLABLE KA -// a202 YI SYLLABLE KAP -// a203 YI SYLLABLE KUOX -// a204 YI SYLLABLE KUO -// a205 YI SYLLABLE KUOP -// a206 YI SYLLABLE KOT -// a207 YI SYLLABLE KOX -// a208 YI SYLLABLE KO -// a209 YI SYLLABLE KOP -// a20a YI SYLLABLE KET -// a20b YI SYLLABLE KEX -// a20c YI SYLLABLE KE -// a20d YI SYLLABLE KEP -// a20e YI SYLLABLE KUT -// a20f YI SYLLABLE KUX -// a210 YI SYLLABLE KU -// a211 YI SYLLABLE KUP -// a212 YI SYLLABLE KURX -// a213 YI SYLLABLE KUR -// a214 YI SYLLABLE GGIT -// a215 YI SYLLABLE GGIX -// a216 YI SYLLABLE GGI -// a217 YI SYLLABLE GGIEX -// a218 YI SYLLABLE GGIE -// a219 YI SYLLABLE GGIEP -// a21a YI SYLLABLE GGAT -// a21b YI SYLLABLE GGAX -// a21c YI SYLLABLE GGA -// a21d YI SYLLABLE GGAP -// a21e YI SYLLABLE GGUOT -// a21f YI SYLLABLE GGUOX -// a220 YI SYLLABLE GGUO -// a221 YI SYLLABLE GGUOP -// a222 YI SYLLABLE GGOT -// a223 YI SYLLABLE GGOX -// a224 YI SYLLABLE GGO -// a225 YI SYLLABLE GGOP -// a226 YI SYLLABLE GGET -// a227 YI SYLLABLE GGEX -// a228 YI SYLLABLE GGE -// a229 YI SYLLABLE GGEP -// a22a YI SYLLABLE GGUT -// a22b YI SYLLABLE GGUX -// a22c YI SYLLABLE GGU -// a22d YI SYLLABLE GGUP -// a22e YI SYLLABLE GGURX -// a22f YI SYLLABLE GGUR -// a230 YI SYLLABLE MGIEX -// a231 YI SYLLABLE MGIE -// a232 YI SYLLABLE MGAT -// a233 YI SYLLABLE MGAX -// a234 YI SYLLABLE MGA -// a235 YI SYLLABLE MGAP -// a236 YI SYLLABLE MGUOX -// a237 YI SYLLABLE MGUO -// a238 YI SYLLABLE MGUOP -// a239 YI SYLLABLE MGOT -// a23a YI SYLLABLE MGOX -// a23b YI SYLLABLE MGO -// a23c YI SYLLABLE MGOP -// a23d YI SYLLABLE MGEX -// a23e YI SYLLABLE MGE -// a23f YI SYLLABLE MGEP -// a240 YI SYLLABLE MGUT -// a241 YI SYLLABLE MGUX -// a242 YI SYLLABLE MGU -// a243 YI SYLLABLE MGUP -// a244 YI SYLLABLE MGURX -// a245 YI SYLLABLE MGUR -// a246 YI SYLLABLE HXIT -// a247 YI SYLLABLE HXIX -// a248 YI SYLLABLE HXI -// a249 YI SYLLABLE HXIP -// a24a YI SYLLABLE HXIET -// a24b YI SYLLABLE HXIEX -// a24c YI SYLLABLE HXIE -// a24d YI SYLLABLE HXIEP -// a24e YI SYLLABLE HXAT -// a24f YI SYLLABLE HXAX -// a250 YI SYLLABLE HXA -// a251 YI SYLLABLE HXAP -// a252 YI SYLLABLE HXUOT -// a253 YI SYLLABLE HXUOX -// a254 YI SYLLABLE HXUO -// a255 YI SYLLABLE HXUOP -// a256 YI SYLLABLE HXOT -// a257 YI SYLLABLE HXOX -// a258 YI SYLLABLE HXO -// a259 YI SYLLABLE HXOP -// a25a YI SYLLABLE HXEX -// a25b YI SYLLABLE HXE -// a25c YI SYLLABLE HXEP -// a25d YI SYLLABLE NGIEX -// a25e YI SYLLABLE NGIE -// a25f YI SYLLABLE NGIEP -// a260 YI SYLLABLE NGAT -// a261 YI SYLLABLE NGAX -// a262 YI SYLLABLE NGA -// a263 YI SYLLABLE NGAP -// a264 YI SYLLABLE NGUOT -// a265 YI SYLLABLE NGUOX -// a266 YI SYLLABLE NGUO -// a267 YI SYLLABLE NGOT -// a268 YI SYLLABLE NGOX -// a269 YI SYLLABLE NGO -// a26a YI SYLLABLE NGOP -// a26b YI SYLLABLE NGEX -// a26c YI SYLLABLE NGE -// a26d YI SYLLABLE NGEP -// a26e YI SYLLABLE HIT -// a26f YI SYLLABLE HIEX -// a270 YI SYLLABLE HIE -// a271 YI SYLLABLE HAT -// a272 YI SYLLABLE HAX -// a273 YI SYLLABLE HA -// a274 YI SYLLABLE HAP -// a275 YI SYLLABLE HUOT -// a276 YI SYLLABLE HUOX -// a277 YI SYLLABLE HUO -// a278 YI SYLLABLE HUOP -// a279 YI SYLLABLE HOT -// a27a YI SYLLABLE HOX -// a27b YI SYLLABLE HO -// a27c YI SYLLABLE HOP -// a27d YI SYLLABLE HEX -// a27e YI SYLLABLE HE -// a27f YI SYLLABLE HEP -// a280 YI SYLLABLE WAT -// a281 YI SYLLABLE WAX -// a282 YI SYLLABLE WA -// a283 YI SYLLABLE WAP -// a284 YI SYLLABLE WUOX -// a285 YI SYLLABLE WUO -// a286 YI SYLLABLE WUOP -// a287 YI SYLLABLE WOX -// a288 YI SYLLABLE WO -// a289 YI SYLLABLE WOP -// a28a YI SYLLABLE WEX -// a28b YI SYLLABLE WE -// a28c YI SYLLABLE WEP -// a28d YI SYLLABLE ZIT -// a28e YI SYLLABLE ZIX -// a28f YI SYLLABLE ZI -// a290 YI SYLLABLE ZIP -// a291 YI SYLLABLE ZIEX -// a292 YI SYLLABLE ZIE -// a293 YI SYLLABLE ZIEP -// a294 YI SYLLABLE ZAT -// a295 YI SYLLABLE ZAX -// a296 YI SYLLABLE ZA -// a297 YI SYLLABLE ZAP -// a298 YI SYLLABLE ZUOX -// a299 YI SYLLABLE ZUO -// a29a YI SYLLABLE ZUOP -// a29b YI SYLLABLE ZOT -// a29c YI SYLLABLE ZOX -// a29d YI SYLLABLE ZO -// a29e YI SYLLABLE ZOP -// a29f YI SYLLABLE ZEX -// a2a0 YI SYLLABLE ZE -// a2a1 YI SYLLABLE ZEP -// a2a2 YI SYLLABLE ZUT -// a2a3 YI SYLLABLE ZUX -// a2a4 YI SYLLABLE ZU -// a2a5 YI SYLLABLE ZUP -// a2a6 YI SYLLABLE ZURX -// a2a7 YI SYLLABLE ZUR -// a2a8 YI SYLLABLE ZYT -// a2a9 YI SYLLABLE ZYX -// a2aa YI SYLLABLE ZY -// a2ab YI SYLLABLE ZYP -// a2ac YI SYLLABLE ZYRX -// a2ad YI SYLLABLE ZYR -// a2ae YI SYLLABLE CIT -// a2af YI SYLLABLE CIX -// a2b0 YI SYLLABLE CI -// a2b1 YI SYLLABLE CIP -// a2b2 YI SYLLABLE CIET -// a2b3 YI SYLLABLE CIEX -// a2b4 YI SYLLABLE CIE -// a2b5 YI SYLLABLE CIEP -// a2b6 YI SYLLABLE CAT -// a2b7 YI SYLLABLE CAX -// a2b8 YI SYLLABLE CA -// a2b9 YI SYLLABLE CAP -// a2ba YI SYLLABLE CUOX -// a2bb YI SYLLABLE CUO -// a2bc YI SYLLABLE CUOP -// a2bd YI SYLLABLE COT -// a2be YI SYLLABLE COX -// a2bf YI SYLLABLE CO -// a2c0 YI SYLLABLE COP -// a2c1 YI SYLLABLE CEX -// a2c2 YI SYLLABLE CE -// a2c3 YI SYLLABLE CEP -// a2c4 YI SYLLABLE CUT -// a2c5 YI SYLLABLE CUX -// a2c6 YI SYLLABLE CU -// a2c7 YI SYLLABLE CUP -// a2c8 YI SYLLABLE CURX -// a2c9 YI SYLLABLE CUR -// a2ca YI SYLLABLE CYT -// a2cb YI SYLLABLE CYX -// a2cc YI SYLLABLE CY -// a2cd YI SYLLABLE CYP -// a2ce YI SYLLABLE CYRX -// a2cf YI SYLLABLE CYR -// a2d0 YI SYLLABLE ZZIT -// a2d1 YI SYLLABLE ZZIX -// a2d2 YI SYLLABLE ZZI -// a2d3 YI SYLLABLE ZZIP -// a2d4 YI SYLLABLE ZZIET -// a2d5 YI SYLLABLE ZZIEX -// a2d6 YI SYLLABLE ZZIE -// a2d7 YI SYLLABLE ZZIEP -// a2d8 YI SYLLABLE ZZAT -// a2d9 YI SYLLABLE ZZAX -// a2da YI SYLLABLE ZZA -// a2db YI SYLLABLE ZZAP -// a2dc YI SYLLABLE ZZOX -// a2dd YI SYLLABLE ZZO -// a2de YI SYLLABLE ZZOP -// a2df YI SYLLABLE ZZEX -// a2e0 YI SYLLABLE ZZE -// a2e1 YI SYLLABLE ZZEP -// a2e2 YI SYLLABLE ZZUX -// a2e3 YI SYLLABLE ZZU -// a2e4 YI SYLLABLE ZZUP -// a2e5 YI SYLLABLE ZZURX -// a2e6 YI SYLLABLE ZZUR -// a2e7 YI SYLLABLE ZZYT -// a2e8 YI SYLLABLE ZZYX -// a2e9 YI SYLLABLE ZZY -// a2ea YI SYLLABLE ZZYP -// a2eb YI SYLLABLE ZZYRX -// a2ec YI SYLLABLE ZZYR -// a2ed YI SYLLABLE NZIT -// a2ee YI SYLLABLE NZIX -// a2ef YI SYLLABLE NZI -// a2f0 YI SYLLABLE NZIP -// a2f1 YI SYLLABLE NZIEX -// a2f2 YI SYLLABLE NZIE -// a2f3 YI SYLLABLE NZIEP -// a2f4 YI SYLLABLE NZAT -// a2f5 YI SYLLABLE NZAX -// a2f6 YI SYLLABLE NZA -// a2f7 YI SYLLABLE NZAP -// a2f8 YI SYLLABLE NZUOX -// a2f9 YI SYLLABLE NZUO -// a2fa YI SYLLABLE NZOX -// a2fb YI SYLLABLE NZOP -// a2fc YI SYLLABLE NZEX -// a2fd YI SYLLABLE NZE -// a2fe YI SYLLABLE NZUX -// a2ff YI SYLLABLE NZU -// a300 YI SYLLABLE NZUP -// a301 YI SYLLABLE NZURX -// a302 YI SYLLABLE NZUR -// a303 YI SYLLABLE NZYT -// a304 YI SYLLABLE NZYX -// a305 YI SYLLABLE NZY -// a306 YI SYLLABLE NZYP -// a307 YI SYLLABLE NZYRX -// a308 YI SYLLABLE NZYR -// a309 YI SYLLABLE SIT -// a30a YI SYLLABLE SIX -// a30b YI SYLLABLE SI -// a30c YI SYLLABLE SIP -// a30d YI SYLLABLE SIEX -// a30e YI SYLLABLE SIE -// a30f YI SYLLABLE SIEP -// a310 YI SYLLABLE SAT -// a311 YI SYLLABLE SAX -// a312 YI SYLLABLE SA -// a313 YI SYLLABLE SAP -// a314 YI SYLLABLE SUOX -// a315 YI SYLLABLE SUO -// a316 YI SYLLABLE SUOP -// a317 YI SYLLABLE SOT -// a318 YI SYLLABLE SOX -// a319 YI SYLLABLE SO -// a31a YI SYLLABLE SOP -// a31b YI SYLLABLE SEX -// a31c YI SYLLABLE SE -// a31d YI SYLLABLE SEP -// a31e YI SYLLABLE SUT -// a31f YI SYLLABLE SUX -// a320 YI SYLLABLE SU -// a321 YI SYLLABLE SUP -// a322 YI SYLLABLE SURX -// a323 YI SYLLABLE SUR -// a324 YI SYLLABLE SYT -// a325 YI SYLLABLE SYX -// a326 YI SYLLABLE SY -// a327 YI SYLLABLE SYP -// a328 YI SYLLABLE SYRX -// a329 YI SYLLABLE SYR -// a32a YI SYLLABLE SSIT -// a32b YI SYLLABLE SSIX -// a32c YI SYLLABLE SSI -// a32d YI SYLLABLE SSIP -// a32e YI SYLLABLE SSIEX -// a32f YI SYLLABLE SSIE -// a330 YI SYLLABLE SSIEP -// a331 YI SYLLABLE SSAT -// a332 YI SYLLABLE SSAX -// a333 YI SYLLABLE SSA -// a334 YI SYLLABLE SSAP -// a335 YI SYLLABLE SSOT -// a336 YI SYLLABLE SSOX -// a337 YI SYLLABLE SSO -// a338 YI SYLLABLE SSOP -// a339 YI SYLLABLE SSEX -// a33a YI SYLLABLE SSE -// a33b YI SYLLABLE SSEP -// a33c YI SYLLABLE SSUT -// a33d YI SYLLABLE SSUX -// a33e YI SYLLABLE SSU -// a33f YI SYLLABLE SSUP -// a340 YI SYLLABLE SSYT -// a341 YI SYLLABLE SSYX -// a342 YI SYLLABLE SSY -// a343 YI SYLLABLE SSYP -// a344 YI SYLLABLE SSYRX -// a345 YI SYLLABLE SSYR -// a346 YI SYLLABLE ZHAT -// a347 YI SYLLABLE ZHAX -// a348 YI SYLLABLE ZHA -// a349 YI SYLLABLE ZHAP -// a34a YI SYLLABLE ZHUOX -// a34b YI SYLLABLE ZHUO -// a34c YI SYLLABLE ZHUOP -// a34d YI SYLLABLE ZHOT -// a34e YI SYLLABLE ZHOX -// a34f YI SYLLABLE ZHO -// a350 YI SYLLABLE ZHOP -// a351 YI SYLLABLE ZHET -// a352 YI SYLLABLE ZHEX -// a353 YI SYLLABLE ZHE -// a354 YI SYLLABLE ZHEP -// a355 YI SYLLABLE ZHUT -// a356 YI SYLLABLE ZHUX -// a357 YI SYLLABLE ZHU -// a358 YI SYLLABLE ZHUP -// a359 YI SYLLABLE ZHURX -// a35a YI SYLLABLE ZHUR -// a35b YI SYLLABLE ZHYT -// a35c YI SYLLABLE ZHYX -// a35d YI SYLLABLE ZHY -// a35e YI SYLLABLE ZHYP -// a35f YI SYLLABLE ZHYRX -// a360 YI SYLLABLE ZHYR -// a361 YI SYLLABLE CHAT -// a362 YI SYLLABLE CHAX -// a363 YI SYLLABLE CHA -// a364 YI SYLLABLE CHAP -// a365 YI SYLLABLE CHUOT -// a366 YI SYLLABLE CHUOX -// a367 YI SYLLABLE CHUO -// a368 YI SYLLABLE CHUOP -// a369 YI SYLLABLE CHOT -// a36a YI SYLLABLE CHOX -// a36b YI SYLLABLE CHO -// a36c YI SYLLABLE CHOP -// a36d YI SYLLABLE CHET -// a36e YI SYLLABLE CHEX -// a36f YI SYLLABLE CHE -// a370 YI SYLLABLE CHEP -// a371 YI SYLLABLE CHUX -// a372 YI SYLLABLE CHU -// a373 YI SYLLABLE CHUP -// a374 YI SYLLABLE CHURX -// a375 YI SYLLABLE CHUR -// a376 YI SYLLABLE CHYT -// a377 YI SYLLABLE CHYX -// a378 YI SYLLABLE CHY -// a379 YI SYLLABLE CHYP -// a37a YI SYLLABLE CHYRX -// a37b YI SYLLABLE CHYR -// a37c YI SYLLABLE RRAX -// a37d YI SYLLABLE RRA -// a37e YI SYLLABLE RRUOX -// a37f YI SYLLABLE RRUO -// a380 YI SYLLABLE RROT -// a381 YI SYLLABLE RROX -// a382 YI SYLLABLE RRO -// a383 YI SYLLABLE RROP -// a384 YI SYLLABLE RRET -// a385 YI SYLLABLE RREX -// a386 YI SYLLABLE RRE -// a387 YI SYLLABLE RREP -// a388 YI SYLLABLE RRUT -// a389 YI SYLLABLE RRUX -// a38a YI SYLLABLE RRU -// a38b YI SYLLABLE RRUP -// a38c YI SYLLABLE RRURX -// a38d YI SYLLABLE RRUR -// a38e YI SYLLABLE RRYT -// a38f YI SYLLABLE RRYX -// a390 YI SYLLABLE RRY -// a391 YI SYLLABLE RRYP -// a392 YI SYLLABLE RRYRX -// a393 YI SYLLABLE RRYR -// a394 YI SYLLABLE NRAT -// a395 YI SYLLABLE NRAX -// a396 YI SYLLABLE NRA -// a397 YI SYLLABLE NRAP -// a398 YI SYLLABLE NROX -// a399 YI SYLLABLE NRO -// a39a YI SYLLABLE NROP -// a39b YI SYLLABLE NRET -// a39c YI SYLLABLE NREX -// a39d YI SYLLABLE NRE -// a39e YI SYLLABLE NREP -// a39f YI SYLLABLE NRUT -// a3a0 YI SYLLABLE NRUX -// a3a1 YI SYLLABLE NRU -// a3a2 YI SYLLABLE NRUP -// a3a3 YI SYLLABLE NRURX -// a3a4 YI SYLLABLE NRUR -// a3a5 YI SYLLABLE NRYT -// a3a6 YI SYLLABLE NRYX -// a3a7 YI SYLLABLE NRY -// a3a8 YI SYLLABLE NRYP -// a3a9 YI SYLLABLE NRYRX -// a3aa YI SYLLABLE NRYR -// a3ab YI SYLLABLE SHAT -// a3ac YI SYLLABLE SHAX -// a3ad YI SYLLABLE SHA -// a3ae YI SYLLABLE SHAP -// a3af YI SYLLABLE SHUOX -// a3b0 YI SYLLABLE SHUO -// a3b1 YI SYLLABLE SHUOP -// a3b2 YI SYLLABLE SHOT -// a3b3 YI SYLLABLE SHOX -// a3b4 YI SYLLABLE SHO -// a3b5 YI SYLLABLE SHOP -// a3b6 YI SYLLABLE SHET -// a3b7 YI SYLLABLE SHEX -// a3b8 YI SYLLABLE SHE -// a3b9 YI SYLLABLE SHEP -// a3ba YI SYLLABLE SHUT -// a3bb YI SYLLABLE SHUX -// a3bc YI SYLLABLE SHU -// a3bd YI SYLLABLE SHUP -// a3be YI SYLLABLE SHURX -// a3bf YI SYLLABLE SHUR -// a3c0 YI SYLLABLE SHYT -// a3c1 YI SYLLABLE SHYX -// a3c2 YI SYLLABLE SHY -// a3c3 YI SYLLABLE SHYP -// a3c4 YI SYLLABLE SHYRX -// a3c5 YI SYLLABLE SHYR -// a3c6 YI SYLLABLE RAT -// a3c7 YI SYLLABLE RAX -// a3c8 YI SYLLABLE RA -// a3c9 YI SYLLABLE RAP -// a3ca YI SYLLABLE RUOX -// a3cb YI SYLLABLE RUO -// a3cc YI SYLLABLE RUOP -// a3cd YI SYLLABLE ROT -// a3ce YI SYLLABLE ROX -// a3cf YI SYLLABLE RO -// a3d0 YI SYLLABLE ROP -// a3d1 YI SYLLABLE REX -// a3d2 YI SYLLABLE RE -// a3d3 YI SYLLABLE REP -// a3d4 YI SYLLABLE RUT -// a3d5 YI SYLLABLE RUX -// a3d6 YI SYLLABLE RU -// a3d7 YI SYLLABLE RUP -// a3d8 YI SYLLABLE RURX -// a3d9 YI SYLLABLE RUR -// a3da YI SYLLABLE RYT -// a3db YI SYLLABLE RYX -// a3dc YI SYLLABLE RY -// a3dd YI SYLLABLE RYP -// a3de YI SYLLABLE RYRX -// a3df YI SYLLABLE RYR -// a3e0 YI SYLLABLE JIT -// a3e1 YI SYLLABLE JIX -// a3e2 YI SYLLABLE JI -// a3e3 YI SYLLABLE JIP -// a3e4 YI SYLLABLE JIET -// a3e5 YI SYLLABLE JIEX -// a3e6 YI SYLLABLE JIE -// a3e7 YI SYLLABLE JIEP -// a3e8 YI SYLLABLE JUOT -// a3e9 YI SYLLABLE JUOX -// a3ea YI SYLLABLE JUO -// a3eb YI SYLLABLE JUOP -// a3ec YI SYLLABLE JOT -// a3ed YI SYLLABLE JOX -// a3ee YI SYLLABLE JO -// a3ef YI SYLLABLE JOP -// a3f0 YI SYLLABLE JUT -// a3f1 YI SYLLABLE JUX -// a3f2 YI SYLLABLE JU -// a3f3 YI SYLLABLE JUP -// a3f4 YI SYLLABLE JURX -// a3f5 YI SYLLABLE JUR -// a3f6 YI SYLLABLE JYT -// a3f7 YI SYLLABLE JYX -// a3f8 YI SYLLABLE JY -// a3f9 YI SYLLABLE JYP -// a3fa YI SYLLABLE JYRX -// a3fb YI SYLLABLE JYR -// a3fc YI SYLLABLE QIT -// a3fd YI SYLLABLE QIX -// a3fe YI SYLLABLE QI -// a3ff YI SYLLABLE QIP -// a400 YI SYLLABLE QIET -// a401 YI SYLLABLE QIEX -// a402 YI SYLLABLE QIE -// a403 YI SYLLABLE QIEP -// a404 YI SYLLABLE QUOT -// a405 YI SYLLABLE QUOX -// a406 YI SYLLABLE QUO -// a407 YI SYLLABLE QUOP -// a408 YI SYLLABLE QOT -// a409 YI SYLLABLE QOX -// a40a YI SYLLABLE QO -// a40b YI SYLLABLE QOP -// a40c YI SYLLABLE QUT -// a40d YI SYLLABLE QUX -// a40e YI SYLLABLE QU -// a40f YI SYLLABLE QUP -// a410 YI SYLLABLE QURX -// a411 YI SYLLABLE QUR -// a412 YI SYLLABLE QYT -// a413 YI SYLLABLE QYX -// a414 YI SYLLABLE QY -// a415 YI SYLLABLE QYP -// a416 YI SYLLABLE QYRX -// a417 YI SYLLABLE QYR -// a418 YI SYLLABLE JJIT -// a419 YI SYLLABLE JJIX -// a41a YI SYLLABLE JJI -// a41b YI SYLLABLE JJIP -// a41c YI SYLLABLE JJIET -// a41d YI SYLLABLE JJIEX -// a41e YI SYLLABLE JJIE -// a41f YI SYLLABLE JJIEP -// a420 YI SYLLABLE JJUOX -// a421 YI SYLLABLE JJUO -// a422 YI SYLLABLE JJUOP -// a423 YI SYLLABLE JJOT -// a424 YI SYLLABLE JJOX -// a425 YI SYLLABLE JJO -// a426 YI SYLLABLE JJOP -// a427 YI SYLLABLE JJUT -// a428 YI SYLLABLE JJUX -// a429 YI SYLLABLE JJU -// a42a YI SYLLABLE JJUP -// a42b YI SYLLABLE JJURX -// a42c YI SYLLABLE JJUR -// a42d YI SYLLABLE JJYT -// a42e YI SYLLABLE JJYX -// a42f YI SYLLABLE JJY -// a430 YI SYLLABLE JJYP -// a431 YI SYLLABLE NJIT -// a432 YI SYLLABLE NJIX -// a433 YI SYLLABLE NJI -// a434 YI SYLLABLE NJIP -// a435 YI SYLLABLE NJIET -// a436 YI SYLLABLE NJIEX -// a437 YI SYLLABLE NJIE -// a438 YI SYLLABLE NJIEP -// a439 YI SYLLABLE NJUOX -// a43a YI SYLLABLE NJUO -// a43b YI SYLLABLE NJOT -// a43c YI SYLLABLE NJOX -// a43d YI SYLLABLE NJO -// a43e YI SYLLABLE NJOP -// a43f YI SYLLABLE NJUX -// a440 YI SYLLABLE NJU -// a441 YI SYLLABLE NJUP -// a442 YI SYLLABLE NJURX -// a443 YI SYLLABLE NJUR -// a444 YI SYLLABLE NJYT -// a445 YI SYLLABLE NJYX -// a446 YI SYLLABLE NJY -// a447 YI SYLLABLE NJYP -// a448 YI SYLLABLE NJYRX -// a449 YI SYLLABLE NJYR -// a44a YI SYLLABLE NYIT -// a44b YI SYLLABLE NYIX -// a44c YI SYLLABLE NYI -// a44d YI SYLLABLE NYIP -// a44e YI SYLLABLE NYIET -// a44f YI SYLLABLE NYIEX -// a450 YI SYLLABLE NYIE -// a451 YI SYLLABLE NYIEP -// a452 YI SYLLABLE NYUOX -// a453 YI SYLLABLE NYUO -// a454 YI SYLLABLE NYUOP -// a455 YI SYLLABLE NYOT -// a456 YI SYLLABLE NYOX -// a457 YI SYLLABLE NYO -// a458 YI SYLLABLE NYOP -// a459 YI SYLLABLE NYUT -// a45a YI SYLLABLE NYUX -// a45b YI SYLLABLE NYU -// a45c YI SYLLABLE NYUP -// a45d YI SYLLABLE XIT -// a45e YI SYLLABLE XIX -// a45f YI SYLLABLE XI -// a460 YI SYLLABLE XIP -// a461 YI SYLLABLE XIET -// a462 YI SYLLABLE XIEX -// a463 YI SYLLABLE XIE -// a464 YI SYLLABLE XIEP -// a465 YI SYLLABLE XUOX -// a466 YI SYLLABLE XUO -// a467 YI SYLLABLE XOT -// a468 YI SYLLABLE XOX -// a469 YI SYLLABLE XO -// a46a YI SYLLABLE XOP -// a46b YI SYLLABLE XYT -// a46c YI SYLLABLE XYX -// a46d YI SYLLABLE XY -// a46e YI SYLLABLE XYP -// a46f YI SYLLABLE XYRX -// a470 YI SYLLABLE XYR -// a471 YI SYLLABLE YIT -// a472 YI SYLLABLE YIX -// a473 YI SYLLABLE YI -// a474 YI SYLLABLE YIP -// a475 YI SYLLABLE YIET -// a476 YI SYLLABLE YIEX -// a477 YI SYLLABLE YIE -// a478 YI SYLLABLE YIEP -// a479 YI SYLLABLE YUOT -// a47a YI SYLLABLE YUOX -// a47b YI SYLLABLE YUO -// a47c YI SYLLABLE YUOP -// a47d YI SYLLABLE YOT -// a47e YI SYLLABLE YOX -// a47f YI SYLLABLE YO -// a480 YI SYLLABLE YOP -// a481 YI SYLLABLE YUT -// a482 YI SYLLABLE YUX -// a483 YI SYLLABLE YU -// a484 YI SYLLABLE YUP -// a485 YI SYLLABLE YURX -// a486 YI SYLLABLE YUR -// a487 YI SYLLABLE YYT -// a488 YI SYLLABLE YYX -// a489 YI SYLLABLE YY -// a48a YI SYLLABLE YYP -// a48b YI SYLLABLE YYRX -// a48c YI SYLLABLE YYR - { 0xA000, 0x48D, 0x9, 0, 0 }, -// a490 YI RADICAL QOT -// a491 YI RADICAL LI -// a492 YI RADICAL KIT -// a493 YI RADICAL NYIP -// a494 YI RADICAL CYP -// a495 YI RADICAL SSI -// a496 YI RADICAL GGOP -// a497 YI RADICAL GEP -// a498 YI RADICAL MI -// a499 YI RADICAL HXIT -// a49a YI RADICAL LYR -// a49b YI RADICAL BBUT -// a49c YI RADICAL MOP -// a49d YI RADICAL YO -// a49e YI RADICAL PUT -// a49f YI RADICAL HXUO -// a4a0 YI RADICAL TAT -// a4a1 YI RADICAL GA -// a4a2 YI RADICAL ZUP -// a4a3 YI RADICAL CYT -// a4a4 YI RADICAL DDUR -// a4a5 YI RADICAL BUR -// a4a6 YI RADICAL GGUO -// a4a7 YI RADICAL NYOP -// a4a8 YI RADICAL TU -// a4a9 YI RADICAL OP -// a4aa YI RADICAL JJUT -// a4ab YI RADICAL ZOT -// a4ac YI RADICAL PYT -// a4ad YI RADICAL HMO -// a4ae YI RADICAL YIT -// a4af YI RADICAL VUR -// a4b0 YI RADICAL SHY -// a4b1 YI RADICAL VEP -// a4b2 YI RADICAL ZA -// a4b3 YI RADICAL JO -// a4b4 YI RADICAL NZUP -// a4b5 YI RADICAL JJY -// a4b6 YI RADICAL GOT -// a4b7 YI RADICAL JJIE -// a4b8 YI RADICAL WO -// a4b9 YI RADICAL DU -// a4ba YI RADICAL SHUR -// a4bb YI RADICAL LIE -// a4bc YI RADICAL CY -// a4bd YI RADICAL CUOP -// a4be YI RADICAL CIP -// a4bf YI RADICAL HXOP -// a4c0 YI RADICAL SHAT -// a4c1 YI RADICAL ZUR -// a4c2 YI RADICAL SHOP -// a4c3 YI RADICAL CHE -// a4c4 YI RADICAL ZZIET -// a4c5 YI RADICAL NBIE -// a4c6 YI RADICAL KE - { 0xA490, 0x37, 0x8, 0, 0 }, -// a4d0 LISU LETTER BA -// a4d1 LISU LETTER PA -// a4d2 LISU LETTER PHA -// a4d3 LISU LETTER DA -// a4d4 LISU LETTER TA -// a4d5 LISU LETTER THA -// a4d6 LISU LETTER GA -// a4d7 LISU LETTER KA -// a4d8 LISU LETTER KHA -// a4d9 LISU LETTER JA -// a4da LISU LETTER CA -// a4db LISU LETTER CHA -// a4dc LISU LETTER DZA -// a4dd LISU LETTER TSA -// a4de LISU LETTER TSHA -// a4df LISU LETTER MA -// a4e0 LISU LETTER NA -// a4e1 LISU LETTER LA -// a4e2 LISU LETTER SA -// a4e3 LISU LETTER ZHA -// a4e4 LISU LETTER ZA -// a4e5 LISU LETTER NGA -// a4e6 LISU LETTER HA -// a4e7 LISU LETTER XA -// a4e8 LISU LETTER HHA -// a4e9 LISU LETTER FA -// a4ea LISU LETTER WA -// a4eb LISU LETTER SHA -// a4ec LISU LETTER YA -// a4ed LISU LETTER GHA -// a4ee LISU LETTER A -// a4ef LISU LETTER AE -// a4f0 LISU LETTER E -// a4f1 LISU LETTER EU -// a4f2 LISU LETTER I -// a4f3 LISU LETTER O -// a4f4 LISU LETTER U -// a4f5 LISU LETTER UE -// a4f6 LISU LETTER UH -// a4f7 LISU LETTER OE -// a4f8 LISU LETTER TONE MYA TI -// a4f9 LISU LETTER TONE NA PO -// a4fa LISU LETTER TONE MYA CYA -// a4fb LISU LETTER TONE MYA BO -// a4fc LISU LETTER TONE MYA NA -// a4fd LISU LETTER TONE MYA JEU - { 0xA4D0, 0x2E, 0x9, 0, 0 }, -// a4fe LISU PUNCTUATION COMMA -// a4ff LISU PUNCTUATION FULL STOP - { 0xA4FE, 0x2, 0x18, 0, 0 }, -// a500 VAI SYLLABLE EE -// a501 VAI SYLLABLE EEN -// a502 VAI SYLLABLE HEE -// a503 VAI SYLLABLE WEE -// a504 VAI SYLLABLE WEEN -// a505 VAI SYLLABLE PEE -// a506 VAI SYLLABLE BHEE -// a507 VAI SYLLABLE BEE -// a508 VAI SYLLABLE MBEE -// a509 VAI SYLLABLE KPEE -// a50a VAI SYLLABLE MGBEE -// a50b VAI SYLLABLE GBEE -// a50c VAI SYLLABLE FEE -// a50d VAI SYLLABLE VEE -// a50e VAI SYLLABLE TEE -// a50f VAI SYLLABLE THEE -// a510 VAI SYLLABLE DHEE -// a511 VAI SYLLABLE DHHEE -// a512 VAI SYLLABLE LEE -// a513 VAI SYLLABLE REE -// a514 VAI SYLLABLE DEE -// a515 VAI SYLLABLE NDEE -// a516 VAI SYLLABLE SEE -// a517 VAI SYLLABLE SHEE -// a518 VAI SYLLABLE ZEE -// a519 VAI SYLLABLE ZHEE -// a51a VAI SYLLABLE CEE -// a51b VAI SYLLABLE JEE -// a51c VAI SYLLABLE NJEE -// a51d VAI SYLLABLE YEE -// a51e VAI SYLLABLE KEE -// a51f VAI SYLLABLE NGGEE -// a520 VAI SYLLABLE GEE -// a521 VAI SYLLABLE MEE -// a522 VAI SYLLABLE NEE -// a523 VAI SYLLABLE NYEE -// a524 VAI SYLLABLE I -// a525 VAI SYLLABLE IN -// a526 VAI SYLLABLE HI -// a527 VAI SYLLABLE HIN -// a528 VAI SYLLABLE WI -// a529 VAI SYLLABLE WIN -// a52a VAI SYLLABLE PI -// a52b VAI SYLLABLE BHI -// a52c VAI SYLLABLE BI -// a52d VAI SYLLABLE MBI -// a52e VAI SYLLABLE KPI -// a52f VAI SYLLABLE MGBI -// a530 VAI SYLLABLE GBI -// a531 VAI SYLLABLE FI -// a532 VAI SYLLABLE VI -// a533 VAI SYLLABLE TI -// a534 VAI SYLLABLE THI -// a535 VAI SYLLABLE DHI -// a536 VAI SYLLABLE DHHI -// a537 VAI SYLLABLE LI -// a538 VAI SYLLABLE RI -// a539 VAI SYLLABLE DI -// a53a VAI SYLLABLE NDI -// a53b VAI SYLLABLE SI -// a53c VAI SYLLABLE SHI -// a53d VAI SYLLABLE ZI -// a53e VAI SYLLABLE ZHI -// a53f VAI SYLLABLE CI -// a540 VAI SYLLABLE JI -// a541 VAI SYLLABLE NJI -// a542 VAI SYLLABLE YI -// a543 VAI SYLLABLE KI -// a544 VAI SYLLABLE NGGI -// a545 VAI SYLLABLE GI -// a546 VAI SYLLABLE MI -// a547 VAI SYLLABLE NI -// a548 VAI SYLLABLE NYI -// a549 VAI SYLLABLE A -// a54a VAI SYLLABLE AN -// a54b VAI SYLLABLE NGAN -// a54c VAI SYLLABLE HA -// a54d VAI SYLLABLE HAN -// a54e VAI SYLLABLE WA -// a54f VAI SYLLABLE WAN -// a550 VAI SYLLABLE PA -// a551 VAI SYLLABLE BHA -// a552 VAI SYLLABLE BA -// a553 VAI SYLLABLE MBA -// a554 VAI SYLLABLE KPA -// a555 VAI SYLLABLE KPAN -// a556 VAI SYLLABLE MGBA -// a557 VAI SYLLABLE GBA -// a558 VAI SYLLABLE FA -// a559 VAI SYLLABLE VA -// a55a VAI SYLLABLE TA -// a55b VAI SYLLABLE THA -// a55c VAI SYLLABLE DHA -// a55d VAI SYLLABLE DHHA -// a55e VAI SYLLABLE LA -// a55f VAI SYLLABLE RA -// a560 VAI SYLLABLE DA -// a561 VAI SYLLABLE NDA -// a562 VAI SYLLABLE SA -// a563 VAI SYLLABLE SHA -// a564 VAI SYLLABLE ZA -// a565 VAI SYLLABLE ZHA -// a566 VAI SYLLABLE CA -// a567 VAI SYLLABLE JA -// a568 VAI SYLLABLE NJA -// a569 VAI SYLLABLE YA -// a56a VAI SYLLABLE KA -// a56b VAI SYLLABLE KAN -// a56c VAI SYLLABLE NGGA -// a56d VAI SYLLABLE GA -// a56e VAI SYLLABLE MA -// a56f VAI SYLLABLE NA -// a570 VAI SYLLABLE NYA -// a571 VAI SYLLABLE OO -// a572 VAI SYLLABLE OON -// a573 VAI SYLLABLE HOO -// a574 VAI SYLLABLE WOO -// a575 VAI SYLLABLE WOON -// a576 VAI SYLLABLE POO -// a577 VAI SYLLABLE BHOO -// a578 VAI SYLLABLE BOO -// a579 VAI SYLLABLE MBOO -// a57a VAI SYLLABLE KPOO -// a57b VAI SYLLABLE MGBOO -// a57c VAI SYLLABLE GBOO -// a57d VAI SYLLABLE FOO -// a57e VAI SYLLABLE VOO -// a57f VAI SYLLABLE TOO -// a580 VAI SYLLABLE THOO -// a581 VAI SYLLABLE DHOO -// a582 VAI SYLLABLE DHHOO -// a583 VAI SYLLABLE LOO -// a584 VAI SYLLABLE ROO -// a585 VAI SYLLABLE DOO -// a586 VAI SYLLABLE NDOO -// a587 VAI SYLLABLE SOO -// a588 VAI SYLLABLE SHOO -// a589 VAI SYLLABLE ZOO -// a58a VAI SYLLABLE ZHOO -// a58b VAI SYLLABLE COO -// a58c VAI SYLLABLE JOO -// a58d VAI SYLLABLE NJOO -// a58e VAI SYLLABLE YOO -// a58f VAI SYLLABLE KOO -// a590 VAI SYLLABLE NGGOO -// a591 VAI SYLLABLE GOO -// a592 VAI SYLLABLE MOO -// a593 VAI SYLLABLE NOO -// a594 VAI SYLLABLE NYOO -// a595 VAI SYLLABLE U -// a596 VAI SYLLABLE UN -// a597 VAI SYLLABLE HU -// a598 VAI SYLLABLE HUN -// a599 VAI SYLLABLE WU -// a59a VAI SYLLABLE WUN -// a59b VAI SYLLABLE PU -// a59c VAI SYLLABLE BHU -// a59d VAI SYLLABLE BU -// a59e VAI SYLLABLE MBU -// a59f VAI SYLLABLE KPU -// a5a0 VAI SYLLABLE MGBU -// a5a1 VAI SYLLABLE GBU -// a5a2 VAI SYLLABLE FU -// a5a3 VAI SYLLABLE VU -// a5a4 VAI SYLLABLE TU -// a5a5 VAI SYLLABLE THU -// a5a6 VAI SYLLABLE DHU -// a5a7 VAI SYLLABLE DHHU -// a5a8 VAI SYLLABLE LU -// a5a9 VAI SYLLABLE RU -// a5aa VAI SYLLABLE DU -// a5ab VAI SYLLABLE NDU -// a5ac VAI SYLLABLE SU -// a5ad VAI SYLLABLE SHU -// a5ae VAI SYLLABLE ZU -// a5af VAI SYLLABLE ZHU -// a5b0 VAI SYLLABLE CU -// a5b1 VAI SYLLABLE JU -// a5b2 VAI SYLLABLE NJU -// a5b3 VAI SYLLABLE YU -// a5b4 VAI SYLLABLE KU -// a5b5 VAI SYLLABLE NGGU -// a5b6 VAI SYLLABLE GU -// a5b7 VAI SYLLABLE MU -// a5b8 VAI SYLLABLE NU -// a5b9 VAI SYLLABLE NYU -// a5ba VAI SYLLABLE O -// a5bb VAI SYLLABLE ON -// a5bc VAI SYLLABLE NGON -// a5bd VAI SYLLABLE HO -// a5be VAI SYLLABLE HON -// a5bf VAI SYLLABLE WO -// a5c0 VAI SYLLABLE WON -// a5c1 VAI SYLLABLE PO -// a5c2 VAI SYLLABLE BHO -// a5c3 VAI SYLLABLE BO -// a5c4 VAI SYLLABLE MBO -// a5c5 VAI SYLLABLE KPO -// a5c6 VAI SYLLABLE MGBO -// a5c7 VAI SYLLABLE GBO -// a5c8 VAI SYLLABLE GBON -// a5c9 VAI SYLLABLE FO -// a5ca VAI SYLLABLE VO -// a5cb VAI SYLLABLE TO -// a5cc VAI SYLLABLE THO -// a5cd VAI SYLLABLE DHO -// a5ce VAI SYLLABLE DHHO -// a5cf VAI SYLLABLE LO -// a5d0 VAI SYLLABLE RO -// a5d1 VAI SYLLABLE DO -// a5d2 VAI SYLLABLE NDO -// a5d3 VAI SYLLABLE SO -// a5d4 VAI SYLLABLE SHO -// a5d5 VAI SYLLABLE ZO -// a5d6 VAI SYLLABLE ZHO -// a5d7 VAI SYLLABLE CO -// a5d8 VAI SYLLABLE JO -// a5d9 VAI SYLLABLE NJO -// a5da VAI SYLLABLE YO -// a5db VAI SYLLABLE KO -// a5dc VAI SYLLABLE NGGO -// a5dd VAI SYLLABLE GO -// a5de VAI SYLLABLE MO -// a5df VAI SYLLABLE NO -// a5e0 VAI SYLLABLE NYO -// a5e1 VAI SYLLABLE E -// a5e2 VAI SYLLABLE EN -// a5e3 VAI SYLLABLE NGEN -// a5e4 VAI SYLLABLE HE -// a5e5 VAI SYLLABLE HEN -// a5e6 VAI SYLLABLE WE -// a5e7 VAI SYLLABLE WEN -// a5e8 VAI SYLLABLE PE -// a5e9 VAI SYLLABLE BHE -// a5ea VAI SYLLABLE BE -// a5eb VAI SYLLABLE MBE -// a5ec VAI SYLLABLE KPE -// a5ed VAI SYLLABLE KPEN -// a5ee VAI SYLLABLE MGBE -// a5ef VAI SYLLABLE GBE -// a5f0 VAI SYLLABLE GBEN -// a5f1 VAI SYLLABLE FE -// a5f2 VAI SYLLABLE VE -// a5f3 VAI SYLLABLE TE -// a5f4 VAI SYLLABLE THE -// a5f5 VAI SYLLABLE DHE -// a5f6 VAI SYLLABLE DHHE -// a5f7 VAI SYLLABLE LE -// a5f8 VAI SYLLABLE RE -// a5f9 VAI SYLLABLE DE -// a5fa VAI SYLLABLE NDE -// a5fb VAI SYLLABLE SE -// a5fc VAI SYLLABLE SHE -// a5fd VAI SYLLABLE ZE -// a5fe VAI SYLLABLE ZHE -// a5ff VAI SYLLABLE CE -// a600 VAI SYLLABLE JE -// a601 VAI SYLLABLE NJE -// a602 VAI SYLLABLE YE -// a603 VAI SYLLABLE KE -// a604 VAI SYLLABLE NGGE -// a605 VAI SYLLABLE NGGEN -// a606 VAI SYLLABLE GE -// a607 VAI SYLLABLE GEN -// a608 VAI SYLLABLE ME -// a609 VAI SYLLABLE NE -// a60a VAI SYLLABLE NYE -// a60b VAI SYLLABLE NG -// a60c VAI SYLLABLE LENGTHENER - { 0xA500, 0x10D, 0x9, 0, 0 }, -// a60d VAI COMMA -// a60e VAI FULL STOP -// a60f VAI QUESTION MARK - { 0xA60D, 0x3, 0x18, 0, 0 }, -// a610 VAI SYLLABLE NDOLE FA -// a611 VAI SYLLABLE NDOLE KA -// a612 VAI SYLLABLE NDOLE SOO -// a613 VAI SYMBOL FEENG -// a614 VAI SYMBOL KEENG -// a615 VAI SYMBOL TING -// a616 VAI SYMBOL NII -// a617 VAI SYMBOL BANG -// a618 VAI SYMBOL FAA -// a619 VAI SYMBOL TAA -// a61a VAI SYMBOL DANG -// a61b VAI SYMBOL DOONG -// a61c VAI SYMBOL KUNG -// a61d VAI SYMBOL TONG -// a61e VAI SYMBOL DO-O -// a61f VAI SYMBOL JONG - { 0xA610, 0x10, 0x9, 0, 0 }, -// a620 VAI DIGIT ZERO -// a621 VAI DIGIT ONE -// a622 VAI DIGIT TWO -// a623 VAI DIGIT THREE -// a624 VAI DIGIT FOUR -// a625 VAI DIGIT FIVE -// a626 VAI DIGIT SIX -// a627 VAI DIGIT SEVEN -// a628 VAI DIGIT EIGHT -// a629 VAI DIGIT NINE - { 0xA620, 0xA, 0x108, 0, 0 }, -// a62a VAI SYLLABLE NDOLE MA -// a62b VAI SYLLABLE NDOLE DO - { 0xA62A, 0x2, 0x9, 0, 0 }, -// a640 CYRILLIC CAPITAL LETTER ZEMLYA - { 0xA640, 0x1, 0x89, 1, 0 }, -// a641 CYRILLIC SMALL LETTER ZEMLYA - { 0xA641, 0x1, 0x49, 0, -1 }, -// a642 CYRILLIC CAPITAL LETTER DZELO - { 0xA642, 0x1, 0x89, 1, 0 }, -// a643 CYRILLIC SMALL LETTER DZELO - { 0xA643, 0x1, 0x49, 0, -1 }, -// a644 CYRILLIC CAPITAL LETTER REVERSED DZE - { 0xA644, 0x1, 0x89, 1, 0 }, -// a645 CYRILLIC SMALL LETTER REVERSED DZE - { 0xA645, 0x1, 0x49, 0, -1 }, -// a646 CYRILLIC CAPITAL LETTER IOTA - { 0xA646, 0x1, 0x89, 1, 0 }, -// a647 CYRILLIC SMALL LETTER IOTA - { 0xA647, 0x1, 0x49, 0, -1 }, -// a648 CYRILLIC CAPITAL LETTER DJERV - { 0xA648, 0x1, 0x89, 1, 0 }, -// a649 CYRILLIC SMALL LETTER DJERV - { 0xA649, 0x1, 0x49, 0, -1 }, -// a64a CYRILLIC CAPITAL LETTER MONOGRAPH UK - { 0xA64A, 0x1, 0x89, 1, 0 }, -// a64b CYRILLIC SMALL LETTER MONOGRAPH UK - { 0xA64B, 0x1, 0x49, 0, -1 }, -// a64c CYRILLIC CAPITAL LETTER BROAD OMEGA - { 0xA64C, 0x1, 0x89, 1, 0 }, -// a64d CYRILLIC SMALL LETTER BROAD OMEGA - { 0xA64D, 0x1, 0x49, 0, -1 }, -// a64e CYRILLIC CAPITAL LETTER NEUTRAL YER - { 0xA64E, 0x1, 0x89, 1, 0 }, -// a64f CYRILLIC SMALL LETTER NEUTRAL YER - { 0xA64F, 0x1, 0x49, 0, -1 }, -// a650 CYRILLIC CAPITAL LETTER YERU WITH BACK YER - { 0xA650, 0x1, 0x89, 1, 0 }, -// a651 CYRILLIC SMALL LETTER YERU WITH BACK YER - { 0xA651, 0x1, 0x49, 0, -1 }, -// a652 CYRILLIC CAPITAL LETTER IOTIFIED YAT - { 0xA652, 0x1, 0x89, 1, 0 }, -// a653 CYRILLIC SMALL LETTER IOTIFIED YAT - { 0xA653, 0x1, 0x49, 0, -1 }, -// a654 CYRILLIC CAPITAL LETTER REVERSED YU - { 0xA654, 0x1, 0x89, 1, 0 }, -// a655 CYRILLIC SMALL LETTER REVERSED YU - { 0xA655, 0x1, 0x49, 0, -1 }, -// a656 CYRILLIC CAPITAL LETTER IOTIFIED A - { 0xA656, 0x1, 0x89, 1, 0 }, -// a657 CYRILLIC SMALL LETTER IOTIFIED A - { 0xA657, 0x1, 0x49, 0, -1 }, -// a658 CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS - { 0xA658, 0x1, 0x89, 1, 0 }, -// a659 CYRILLIC SMALL LETTER CLOSED LITTLE YUS - { 0xA659, 0x1, 0x49, 0, -1 }, -// a65a CYRILLIC CAPITAL LETTER BLENDED YUS - { 0xA65A, 0x1, 0x89, 1, 0 }, -// a65b CYRILLIC SMALL LETTER BLENDED YUS - { 0xA65B, 0x1, 0x49, 0, -1 }, -// a65c CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS - { 0xA65C, 0x1, 0x89, 1, 0 }, -// a65d CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS - { 0xA65D, 0x1, 0x49, 0, -1 }, -// a65e CYRILLIC CAPITAL LETTER YN - { 0xA65E, 0x1, 0x89, 1, 0 }, -// a65f CYRILLIC SMALL LETTER YN - { 0xA65F, 0x1, 0x49, 0, -1 }, -// a660 CYRILLIC CAPITAL LETTER REVERSED TSE - { 0xA660, 0x1, 0x89, 1, 0 }, -// a661 CYRILLIC SMALL LETTER REVERSED TSE - { 0xA661, 0x1, 0x49, 0, -1 }, -// a662 CYRILLIC CAPITAL LETTER SOFT DE - { 0xA662, 0x1, 0x89, 1, 0 }, -// a663 CYRILLIC SMALL LETTER SOFT DE - { 0xA663, 0x1, 0x49, 0, -1 }, -// a664 CYRILLIC CAPITAL LETTER SOFT EL - { 0xA664, 0x1, 0x89, 1, 0 }, -// a665 CYRILLIC SMALL LETTER SOFT EL - { 0xA665, 0x1, 0x49, 0, -1 }, -// a666 CYRILLIC CAPITAL LETTER SOFT EM - { 0xA666, 0x1, 0x89, 1, 0 }, -// a667 CYRILLIC SMALL LETTER SOFT EM - { 0xA667, 0x1, 0x49, 0, -1 }, -// a668 CYRILLIC CAPITAL LETTER MONOCULAR O - { 0xA668, 0x1, 0x89, 1, 0 }, -// a669 CYRILLIC SMALL LETTER MONOCULAR O - { 0xA669, 0x1, 0x49, 0, -1 }, -// a66a CYRILLIC CAPITAL LETTER BINOCULAR O - { 0xA66A, 0x1, 0x89, 1, 0 }, -// a66b CYRILLIC SMALL LETTER BINOCULAR O - { 0xA66B, 0x1, 0x49, 0, -1 }, -// a66c CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O - { 0xA66C, 0x1, 0x89, 1, 0 }, -// a66d CYRILLIC SMALL LETTER DOUBLE MONOCULAR O - { 0xA66D, 0x1, 0x49, 0, -1 }, -// a66e CYRILLIC LETTER MULTIOCULAR O - { 0xA66E, 0x1, 0x9, 0, 0 }, -// a66f COMBINING CYRILLIC VZMET -// a670 COMBINING CYRILLIC TEN MILLIONS SIGN -// a671 COMBINING CYRILLIC HUNDRED MILLIONS SIGN -// a672 COMBINING CYRILLIC THOUSAND MILLIONS SIGN - { 0xA66F, 0x4, 0x0, 0, 0 }, -// a673 SLAVONIC ASTERISK - { 0xA673, 0x1, 0x18, 0, 0 }, -// a674 COMBINING CYRILLIC LETTER UKRAINIAN IE -// a675 COMBINING CYRILLIC LETTER I -// a676 COMBINING CYRILLIC LETTER YI -// a677 COMBINING CYRILLIC LETTER U -// a678 COMBINING CYRILLIC LETTER HARD SIGN -// a679 COMBINING CYRILLIC LETTER YERU -// a67a COMBINING CYRILLIC LETTER SOFT SIGN -// a67b COMBINING CYRILLIC LETTER OMEGA -// a67c COMBINING CYRILLIC KAVYKA -// a67d COMBINING CYRILLIC PAYEROK - { 0xA674, 0xA, 0x0, 0, 0 }, -// a67e CYRILLIC KAVYKA - { 0xA67E, 0x1, 0x18, 0, 0 }, -// a67f CYRILLIC PAYEROK - { 0xA67F, 0x1, 0x9, 0, 0 }, -// a680 CYRILLIC CAPITAL LETTER DWE - { 0xA680, 0x1, 0x89, 1, 0 }, -// a681 CYRILLIC SMALL LETTER DWE - { 0xA681, 0x1, 0x49, 0, -1 }, -// a682 CYRILLIC CAPITAL LETTER DZWE - { 0xA682, 0x1, 0x89, 1, 0 }, -// a683 CYRILLIC SMALL LETTER DZWE - { 0xA683, 0x1, 0x49, 0, -1 }, -// a684 CYRILLIC CAPITAL LETTER ZHWE - { 0xA684, 0x1, 0x89, 1, 0 }, -// a685 CYRILLIC SMALL LETTER ZHWE - { 0xA685, 0x1, 0x49, 0, -1 }, -// a686 CYRILLIC CAPITAL LETTER CCHE - { 0xA686, 0x1, 0x89, 1, 0 }, -// a687 CYRILLIC SMALL LETTER CCHE - { 0xA687, 0x1, 0x49, 0, -1 }, -// a688 CYRILLIC CAPITAL LETTER DZZE - { 0xA688, 0x1, 0x89, 1, 0 }, -// a689 CYRILLIC SMALL LETTER DZZE - { 0xA689, 0x1, 0x49, 0, -1 }, -// a68a CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK - { 0xA68A, 0x1, 0x89, 1, 0 }, -// a68b CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK - { 0xA68B, 0x1, 0x49, 0, -1 }, -// a68c CYRILLIC CAPITAL LETTER TWE - { 0xA68C, 0x1, 0x89, 1, 0 }, -// a68d CYRILLIC SMALL LETTER TWE - { 0xA68D, 0x1, 0x49, 0, -1 }, -// a68e CYRILLIC CAPITAL LETTER TSWE - { 0xA68E, 0x1, 0x89, 1, 0 }, -// a68f CYRILLIC SMALL LETTER TSWE - { 0xA68F, 0x1, 0x49, 0, -1 }, -// a690 CYRILLIC CAPITAL LETTER TSSE - { 0xA690, 0x1, 0x89, 1, 0 }, -// a691 CYRILLIC SMALL LETTER TSSE - { 0xA691, 0x1, 0x49, 0, -1 }, -// a692 CYRILLIC CAPITAL LETTER TCHE - { 0xA692, 0x1, 0x89, 1, 0 }, -// a693 CYRILLIC SMALL LETTER TCHE - { 0xA693, 0x1, 0x49, 0, -1 }, -// a694 CYRILLIC CAPITAL LETTER HWE - { 0xA694, 0x1, 0x89, 1, 0 }, -// a695 CYRILLIC SMALL LETTER HWE - { 0xA695, 0x1, 0x49, 0, -1 }, -// a696 CYRILLIC CAPITAL LETTER SHWE - { 0xA696, 0x1, 0x89, 1, 0 }, -// a697 CYRILLIC SMALL LETTER SHWE - { 0xA697, 0x1, 0x49, 0, -1 }, -// a698 CYRILLIC CAPITAL LETTER DOUBLE O - { 0xA698, 0x1, 0x89, 1, 0 }, -// a699 CYRILLIC SMALL LETTER DOUBLE O - { 0xA699, 0x1, 0x49, 0, -1 }, -// a69a CYRILLIC CAPITAL LETTER CROSSED O - { 0xA69A, 0x1, 0x89, 1, 0 }, -// a69b CYRILLIC SMALL LETTER CROSSED O - { 0xA69B, 0x1, 0x49, 0, -1 }, -// a69c MODIFIER LETTER CYRILLIC HARD SIGN -// a69d MODIFIER LETTER CYRILLIC SOFT SIGN - { 0xA69C, 0x2, 0x9, 0, 0 }, -// a69f COMBINING CYRILLIC LETTER IOTIFIED E - { 0xA69F, 0x1, 0x0, 0, 0 }, -// a6a0 BAMUM LETTER A -// a6a1 BAMUM LETTER KA -// a6a2 BAMUM LETTER U -// a6a3 BAMUM LETTER KU -// a6a4 BAMUM LETTER EE -// a6a5 BAMUM LETTER REE -// a6a6 BAMUM LETTER TAE -// a6a7 BAMUM LETTER O -// a6a8 BAMUM LETTER NYI -// a6a9 BAMUM LETTER I -// a6aa BAMUM LETTER LA -// a6ab BAMUM LETTER PA -// a6ac BAMUM LETTER RII -// a6ad BAMUM LETTER RIEE -// a6ae BAMUM LETTER LEEEE -// a6af BAMUM LETTER MEEEE -// a6b0 BAMUM LETTER TAA -// a6b1 BAMUM LETTER NDAA -// a6b2 BAMUM LETTER NJAEM -// a6b3 BAMUM LETTER M -// a6b4 BAMUM LETTER SUU -// a6b5 BAMUM LETTER MU -// a6b6 BAMUM LETTER SHII -// a6b7 BAMUM LETTER SI -// a6b8 BAMUM LETTER SHEUX -// a6b9 BAMUM LETTER SEUX -// a6ba BAMUM LETTER KYEE -// a6bb BAMUM LETTER KET -// a6bc BAMUM LETTER NUAE -// a6bd BAMUM LETTER NU -// a6be BAMUM LETTER NJUAE -// a6bf BAMUM LETTER YOQ -// a6c0 BAMUM LETTER SHU -// a6c1 BAMUM LETTER YUQ -// a6c2 BAMUM LETTER YA -// a6c3 BAMUM LETTER NSHA -// a6c4 BAMUM LETTER KEUX -// a6c5 BAMUM LETTER PEUX -// a6c6 BAMUM LETTER NJEE -// a6c7 BAMUM LETTER NTEE -// a6c8 BAMUM LETTER PUE -// a6c9 BAMUM LETTER WUE -// a6ca BAMUM LETTER PEE -// a6cb BAMUM LETTER FEE -// a6cc BAMUM LETTER RU -// a6cd BAMUM LETTER LU -// a6ce BAMUM LETTER MI -// a6cf BAMUM LETTER NI -// a6d0 BAMUM LETTER REUX -// a6d1 BAMUM LETTER RAE -// a6d2 BAMUM LETTER KEN -// a6d3 BAMUM LETTER NGKWAEN -// a6d4 BAMUM LETTER NGGA -// a6d5 BAMUM LETTER NGA -// a6d6 BAMUM LETTER SHO -// a6d7 BAMUM LETTER PUAE -// a6d8 BAMUM LETTER FU -// a6d9 BAMUM LETTER FOM -// a6da BAMUM LETTER WA -// a6db BAMUM LETTER NA -// a6dc BAMUM LETTER LI -// a6dd BAMUM LETTER PI -// a6de BAMUM LETTER LOQ -// a6df BAMUM LETTER KO -// a6e0 BAMUM LETTER MBEN -// a6e1 BAMUM LETTER REN -// a6e2 BAMUM LETTER MEN -// a6e3 BAMUM LETTER MA -// a6e4 BAMUM LETTER TI -// a6e5 BAMUM LETTER KI - { 0xA6A0, 0x46, 0x9, 0, 0 }, -// a6e6 BAMUM LETTER MO -// a6e7 BAMUM LETTER MBAA -// a6e8 BAMUM LETTER TET -// a6e9 BAMUM LETTER KPA -// a6ea BAMUM LETTER TEN -// a6eb BAMUM LETTER NTUU -// a6ec BAMUM LETTER SAMBA -// a6ed BAMUM LETTER FAAMAE -// a6ee BAMUM LETTER KOVUU -// a6ef BAMUM LETTER KOGHOM - { 0xA6E6, 0xA, 0x8, 0, 0 }, -// a6f0 BAMUM COMBINING MARK KOQNDON -// a6f1 BAMUM COMBINING MARK TUKWENTIS - { 0xA6F0, 0x2, 0x0, 0, 0 }, -// a6f2 BAMUM NJAEMLI -// a6f3 BAMUM FULL STOP -// a6f4 BAMUM COLON -// a6f5 BAMUM COMMA -// a6f6 BAMUM SEMICOLON -// a6f7 BAMUM QUESTION MARK - { 0xA6F2, 0x6, 0x18, 0, 0 }, -// a700 MODIFIER LETTER CHINESE TONE YIN PING -// a701 MODIFIER LETTER CHINESE TONE YANG PING -// a702 MODIFIER LETTER CHINESE TONE YIN SHANG -// a703 MODIFIER LETTER CHINESE TONE YANG SHANG -// a704 MODIFIER LETTER CHINESE TONE YIN QU -// a705 MODIFIER LETTER CHINESE TONE YANG QU -// a706 MODIFIER LETTER CHINESE TONE YIN RU -// a707 MODIFIER LETTER CHINESE TONE YANG RU -// a708 MODIFIER LETTER EXTRA-HIGH DOTTED TONE BAR -// a709 MODIFIER LETTER HIGH DOTTED TONE BAR -// a70a MODIFIER LETTER MID DOTTED TONE BAR -// a70b MODIFIER LETTER LOW DOTTED TONE BAR -// a70c MODIFIER LETTER EXTRA-LOW DOTTED TONE BAR -// a70d MODIFIER LETTER EXTRA-HIGH DOTTED LEFT-STEM TONE BAR -// a70e MODIFIER LETTER HIGH DOTTED LEFT-STEM TONE BAR -// a70f MODIFIER LETTER MID DOTTED LEFT-STEM TONE BAR -// a710 MODIFIER LETTER LOW DOTTED LEFT-STEM TONE BAR -// a711 MODIFIER LETTER EXTRA-LOW DOTTED LEFT-STEM TONE BAR -// a712 MODIFIER LETTER EXTRA-HIGH LEFT-STEM TONE BAR -// a713 MODIFIER LETTER HIGH LEFT-STEM TONE BAR -// a714 MODIFIER LETTER MID LEFT-STEM TONE BAR -// a715 MODIFIER LETTER LOW LEFT-STEM TONE BAR -// a716 MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR - { 0xA700, 0x17, 0x8, 0, 0 }, -// a717 MODIFIER LETTER DOT VERTICAL BAR -// a718 MODIFIER LETTER DOT SLASH -// a719 MODIFIER LETTER DOT HORIZONTAL BAR -// a71a MODIFIER LETTER LOWER RIGHT CORNER ANGLE -// a71b MODIFIER LETTER RAISED UP ARROW -// a71c MODIFIER LETTER RAISED DOWN ARROW -// a71d MODIFIER LETTER RAISED EXCLAMATION MARK -// a71e MODIFIER LETTER RAISED INVERTED EXCLAMATION MARK -// a71f MODIFIER LETTER LOW INVERTED EXCLAMATION MARK - { 0xA717, 0x9, 0x9, 0, 0 }, -// a720 MODIFIER LETTER STRESS AND HIGH TONE -// a721 MODIFIER LETTER STRESS AND LOW TONE - { 0xA720, 0x2, 0x8, 0, 0 }, -// a722 LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF - { 0xA722, 0x1, 0x89, 1, 0 }, -// a723 LATIN SMALL LETTER EGYPTOLOGICAL ALEF - { 0xA723, 0x1, 0x49, 0, -1 }, -// a724 LATIN CAPITAL LETTER EGYPTOLOGICAL AIN - { 0xA724, 0x1, 0x89, 1, 0 }, -// a725 LATIN SMALL LETTER EGYPTOLOGICAL AIN - { 0xA725, 0x1, 0x49, 0, -1 }, -// a726 LATIN CAPITAL LETTER HENG - { 0xA726, 0x1, 0x89, 1, 0 }, -// a727 LATIN SMALL LETTER HENG - { 0xA727, 0x1, 0x49, 0, -1 }, -// a728 LATIN CAPITAL LETTER TZ - { 0xA728, 0x1, 0x89, 1, 0 }, -// a729 LATIN SMALL LETTER TZ - { 0xA729, 0x1, 0x49, 0, -1 }, -// a72a LATIN CAPITAL LETTER TRESILLO - { 0xA72A, 0x1, 0x89, 1, 0 }, -// a72b LATIN SMALL LETTER TRESILLO - { 0xA72B, 0x1, 0x49, 0, -1 }, -// a72c LATIN CAPITAL LETTER CUATRILLO - { 0xA72C, 0x1, 0x89, 1, 0 }, -// a72d LATIN SMALL LETTER CUATRILLO - { 0xA72D, 0x1, 0x49, 0, -1 }, -// a72e LATIN CAPITAL LETTER CUATRILLO WITH COMMA - { 0xA72E, 0x1, 0x89, 1, 0 }, -// a72f LATIN SMALL LETTER CUATRILLO WITH COMMA - { 0xA72F, 0x1, 0x49, 0, -1 }, -// a730 LATIN LETTER SMALL CAPITAL F -// a731 LATIN LETTER SMALL CAPITAL S - { 0xA730, 0x2, 0x49, 0, 0 }, -// a732 LATIN CAPITAL LETTER AA - { 0xA732, 0x1, 0x89, 1, 0 }, -// a733 LATIN SMALL LETTER AA - { 0xA733, 0x1, 0x49, 0, -1 }, -// a734 LATIN CAPITAL LETTER AO - { 0xA734, 0x1, 0x89, 1, 0 }, -// a735 LATIN SMALL LETTER AO - { 0xA735, 0x1, 0x49, 0, -1 }, -// a736 LATIN CAPITAL LETTER AU - { 0xA736, 0x1, 0x89, 1, 0 }, -// a737 LATIN SMALL LETTER AU - { 0xA737, 0x1, 0x49, 0, -1 }, -// a738 LATIN CAPITAL LETTER AV - { 0xA738, 0x1, 0x89, 1, 0 }, -// a739 LATIN SMALL LETTER AV - { 0xA739, 0x1, 0x49, 0, -1 }, -// a73a LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR - { 0xA73A, 0x1, 0x89, 1, 0 }, -// a73b LATIN SMALL LETTER AV WITH HORIZONTAL BAR - { 0xA73B, 0x1, 0x49, 0, -1 }, -// a73c LATIN CAPITAL LETTER AY - { 0xA73C, 0x1, 0x89, 1, 0 }, -// a73d LATIN SMALL LETTER AY - { 0xA73D, 0x1, 0x49, 0, -1 }, -// a73e LATIN CAPITAL LETTER REVERSED C WITH DOT - { 0xA73E, 0x1, 0x89, 1, 0 }, -// a73f LATIN SMALL LETTER REVERSED C WITH DOT - { 0xA73F, 0x1, 0x49, 0, -1 }, -// a740 LATIN CAPITAL LETTER K WITH STROKE - { 0xA740, 0x1, 0x89, 1, 0 }, -// a741 LATIN SMALL LETTER K WITH STROKE - { 0xA741, 0x1, 0x49, 0, -1 }, -// a742 LATIN CAPITAL LETTER K WITH DIAGONAL STROKE - { 0xA742, 0x1, 0x89, 1, 0 }, -// a743 LATIN SMALL LETTER K WITH DIAGONAL STROKE - { 0xA743, 0x1, 0x49, 0, -1 }, -// a744 LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE - { 0xA744, 0x1, 0x89, 1, 0 }, -// a745 LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE - { 0xA745, 0x1, 0x49, 0, -1 }, -// a746 LATIN CAPITAL LETTER BROKEN L - { 0xA746, 0x1, 0x89, 1, 0 }, -// a747 LATIN SMALL LETTER BROKEN L - { 0xA747, 0x1, 0x49, 0, -1 }, -// a748 LATIN CAPITAL LETTER L WITH HIGH STROKE - { 0xA748, 0x1, 0x89, 1, 0 }, -// a749 LATIN SMALL LETTER L WITH HIGH STROKE - { 0xA749, 0x1, 0x49, 0, -1 }, -// a74a LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY - { 0xA74A, 0x1, 0x89, 1, 0 }, -// a74b LATIN SMALL LETTER O WITH LONG STROKE OVERLAY - { 0xA74B, 0x1, 0x49, 0, -1 }, -// a74c LATIN CAPITAL LETTER O WITH LOOP - { 0xA74C, 0x1, 0x89, 1, 0 }, -// a74d LATIN SMALL LETTER O WITH LOOP - { 0xA74D, 0x1, 0x49, 0, -1 }, -// a74e LATIN CAPITAL LETTER OO - { 0xA74E, 0x1, 0x89, 1, 0 }, -// a74f LATIN SMALL LETTER OO - { 0xA74F, 0x1, 0x49, 0, -1 }, -// a750 LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER - { 0xA750, 0x1, 0x89, 1, 0 }, -// a751 LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER - { 0xA751, 0x1, 0x49, 0, -1 }, -// a752 LATIN CAPITAL LETTER P WITH FLOURISH - { 0xA752, 0x1, 0x89, 1, 0 }, -// a753 LATIN SMALL LETTER P WITH FLOURISH - { 0xA753, 0x1, 0x49, 0, -1 }, -// a754 LATIN CAPITAL LETTER P WITH SQUIRREL TAIL - { 0xA754, 0x1, 0x89, 1, 0 }, -// a755 LATIN SMALL LETTER P WITH SQUIRREL TAIL - { 0xA755, 0x1, 0x49, 0, -1 }, -// a756 LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER - { 0xA756, 0x1, 0x89, 1, 0 }, -// a757 LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER - { 0xA757, 0x1, 0x49, 0, -1 }, -// a758 LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE - { 0xA758, 0x1, 0x89, 1, 0 }, -// a759 LATIN SMALL LETTER Q WITH DIAGONAL STROKE - { 0xA759, 0x1, 0x49, 0, -1 }, -// a75a LATIN CAPITAL LETTER R ROTUNDA - { 0xA75A, 0x1, 0x89, 1, 0 }, -// a75b LATIN SMALL LETTER R ROTUNDA - { 0xA75B, 0x1, 0x49, 0, -1 }, -// a75c LATIN CAPITAL LETTER RUM ROTUNDA - { 0xA75C, 0x1, 0x89, 1, 0 }, -// a75d LATIN SMALL LETTER RUM ROTUNDA - { 0xA75D, 0x1, 0x49, 0, -1 }, -// a75e LATIN CAPITAL LETTER V WITH DIAGONAL STROKE - { 0xA75E, 0x1, 0x89, 1, 0 }, -// a75f LATIN SMALL LETTER V WITH DIAGONAL STROKE - { 0xA75F, 0x1, 0x49, 0, -1 }, -// a760 LATIN CAPITAL LETTER VY - { 0xA760, 0x1, 0x89, 1, 0 }, -// a761 LATIN SMALL LETTER VY - { 0xA761, 0x1, 0x49, 0, -1 }, -// a762 LATIN CAPITAL LETTER VISIGOTHIC Z - { 0xA762, 0x1, 0x89, 1, 0 }, -// a763 LATIN SMALL LETTER VISIGOTHIC Z - { 0xA763, 0x1, 0x49, 0, -1 }, -// a764 LATIN CAPITAL LETTER THORN WITH STROKE - { 0xA764, 0x1, 0x89, 1, 0 }, -// a765 LATIN SMALL LETTER THORN WITH STROKE - { 0xA765, 0x1, 0x49, 0, -1 }, -// a766 LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER - { 0xA766, 0x1, 0x89, 1, 0 }, -// a767 LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER - { 0xA767, 0x1, 0x49, 0, -1 }, -// a768 LATIN CAPITAL LETTER VEND - { 0xA768, 0x1, 0x89, 1, 0 }, -// a769 LATIN SMALL LETTER VEND - { 0xA769, 0x1, 0x49, 0, -1 }, -// a76a LATIN CAPITAL LETTER ET - { 0xA76A, 0x1, 0x89, 1, 0 }, -// a76b LATIN SMALL LETTER ET - { 0xA76B, 0x1, 0x49, 0, -1 }, -// a76c LATIN CAPITAL LETTER IS - { 0xA76C, 0x1, 0x89, 1, 0 }, -// a76d LATIN SMALL LETTER IS - { 0xA76D, 0x1, 0x49, 0, -1 }, -// a76e LATIN CAPITAL LETTER CON - { 0xA76E, 0x1, 0x89, 1, 0 }, -// a76f LATIN SMALL LETTER CON - { 0xA76F, 0x1, 0x49, 0, -1 }, -// a770 MODIFIER LETTER US - { 0xA770, 0x1, 0x9, 0, 0 }, -// a771 LATIN SMALL LETTER DUM -// a772 LATIN SMALL LETTER LUM -// a773 LATIN SMALL LETTER MUM -// a774 LATIN SMALL LETTER NUM -// a775 LATIN SMALL LETTER RUM -// a776 LATIN LETTER SMALL CAPITAL RUM -// a777 LATIN SMALL LETTER TUM -// a778 LATIN SMALL LETTER UM - { 0xA771, 0x8, 0x49, 0, 0 }, -// a779 LATIN CAPITAL LETTER INSULAR D - { 0xA779, 0x1, 0x89, 1, 0 }, -// a77a LATIN SMALL LETTER INSULAR D - { 0xA77A, 0x1, 0x49, 0, -1 }, -// a77b LATIN CAPITAL LETTER INSULAR F - { 0xA77B, 0x1, 0x89, 1, 0 }, -// a77c LATIN SMALL LETTER INSULAR F - { 0xA77C, 0x1, 0x49, 0, -1 }, -// a77d LATIN CAPITAL LETTER INSULAR G - { 0xA77D, 0x1, 0x89, -35332, 0 }, -// a77e LATIN CAPITAL LETTER TURNED INSULAR G - { 0xA77E, 0x1, 0x89, 1, 0 }, -// a77f LATIN SMALL LETTER TURNED INSULAR G - { 0xA77F, 0x1, 0x49, 0, -1 }, -// a780 LATIN CAPITAL LETTER TURNED L - { 0xA780, 0x1, 0x89, 1, 0 }, -// a781 LATIN SMALL LETTER TURNED L - { 0xA781, 0x1, 0x49, 0, -1 }, -// a782 LATIN CAPITAL LETTER INSULAR R - { 0xA782, 0x1, 0x89, 1, 0 }, -// a783 LATIN SMALL LETTER INSULAR R - { 0xA783, 0x1, 0x49, 0, -1 }, -// a784 LATIN CAPITAL LETTER INSULAR S - { 0xA784, 0x1, 0x89, 1, 0 }, -// a785 LATIN SMALL LETTER INSULAR S - { 0xA785, 0x1, 0x49, 0, -1 }, -// a786 LATIN CAPITAL LETTER INSULAR T - { 0xA786, 0x1, 0x89, 1, 0 }, -// a787 LATIN SMALL LETTER INSULAR T - { 0xA787, 0x1, 0x49, 0, -1 }, -// a788 MODIFIER LETTER LOW CIRCUMFLEX ACCENT - { 0xA788, 0x1, 0x9, 0, 0 }, -// a789 MODIFIER LETTER COLON -// a78a MODIFIER LETTER SHORT EQUALS SIGN - { 0xA789, 0x2, 0x8, 0, 0 }, -// a78b LATIN CAPITAL LETTER SALTILLO - { 0xA78B, 0x1, 0x89, 1, 0 }, -// a78c LATIN SMALL LETTER SALTILLO - { 0xA78C, 0x1, 0x49, 0, -1 }, -// a78d LATIN CAPITAL LETTER TURNED H - { 0xA78D, 0x1, 0x89, -42280, 0 }, -// a78e LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT - { 0xA78E, 0x1, 0x49, 0, 0 }, -// a790 LATIN CAPITAL LETTER N WITH DESCENDER - { 0xA790, 0x1, 0x89, 1, 0 }, -// a791 LATIN SMALL LETTER N WITH DESCENDER - { 0xA791, 0x1, 0x49, 0, -1 }, -// a792 LATIN CAPITAL LETTER C WITH BAR - { 0xA792, 0x1, 0x89, 1, 0 }, -// a793 LATIN SMALL LETTER C WITH BAR - { 0xA793, 0x1, 0x49, 0, -1 }, -// a794 LATIN SMALL LETTER C WITH PALATAL HOOK -// a795 LATIN SMALL LETTER H WITH PALATAL HOOK - { 0xA794, 0x2, 0x49, 0, 0 }, -// a796 LATIN CAPITAL LETTER B WITH FLOURISH - { 0xA796, 0x1, 0x89, 1, 0 }, -// a797 LATIN SMALL LETTER B WITH FLOURISH - { 0xA797, 0x1, 0x49, 0, -1 }, -// a798 LATIN CAPITAL LETTER F WITH STROKE - { 0xA798, 0x1, 0x89, 1, 0 }, -// a799 LATIN SMALL LETTER F WITH STROKE - { 0xA799, 0x1, 0x49, 0, -1 }, -// a79a LATIN CAPITAL LETTER VOLAPUK AE - { 0xA79A, 0x1, 0x89, 1, 0 }, -// a79b LATIN SMALL LETTER VOLAPUK AE - { 0xA79B, 0x1, 0x49, 0, -1 }, -// a79c LATIN CAPITAL LETTER VOLAPUK OE - { 0xA79C, 0x1, 0x89, 1, 0 }, -// a79d LATIN SMALL LETTER VOLAPUK OE - { 0xA79D, 0x1, 0x49, 0, -1 }, -// a79e LATIN CAPITAL LETTER VOLAPUK UE - { 0xA79E, 0x1, 0x89, 1, 0 }, -// a79f LATIN SMALL LETTER VOLAPUK UE - { 0xA79F, 0x1, 0x49, 0, -1 }, -// a7a0 LATIN CAPITAL LETTER G WITH OBLIQUE STROKE - { 0xA7A0, 0x1, 0x89, 1, 0 }, -// a7a1 LATIN SMALL LETTER G WITH OBLIQUE STROKE - { 0xA7A1, 0x1, 0x49, 0, -1 }, -// a7a2 LATIN CAPITAL LETTER K WITH OBLIQUE STROKE - { 0xA7A2, 0x1, 0x89, 1, 0 }, -// a7a3 LATIN SMALL LETTER K WITH OBLIQUE STROKE - { 0xA7A3, 0x1, 0x49, 0, -1 }, -// a7a4 LATIN CAPITAL LETTER N WITH OBLIQUE STROKE - { 0xA7A4, 0x1, 0x89, 1, 0 }, -// a7a5 LATIN SMALL LETTER N WITH OBLIQUE STROKE - { 0xA7A5, 0x1, 0x49, 0, -1 }, -// a7a6 LATIN CAPITAL LETTER R WITH OBLIQUE STROKE - { 0xA7A6, 0x1, 0x89, 1, 0 }, -// a7a7 LATIN SMALL LETTER R WITH OBLIQUE STROKE - { 0xA7A7, 0x1, 0x49, 0, -1 }, -// a7a8 LATIN CAPITAL LETTER S WITH OBLIQUE STROKE - { 0xA7A8, 0x1, 0x89, 1, 0 }, -// a7a9 LATIN SMALL LETTER S WITH OBLIQUE STROKE - { 0xA7A9, 0x1, 0x49, 0, -1 }, -// a7aa LATIN CAPITAL LETTER H WITH HOOK - { 0xA7AA, 0x1, 0x89, -42308, 0 }, -// a7ab LATIN CAPITAL LETTER REVERSED OPEN E - { 0xA7AB, 0x1, 0x89, -42319, 0 }, -// a7ac LATIN CAPITAL LETTER SCRIPT G - { 0xA7AC, 0x1, 0x89, -42315, 0 }, -// a7ad LATIN CAPITAL LETTER L WITH BELT - { 0xA7AD, 0x1, 0x89, -42305, 0 }, -// a7b0 LATIN CAPITAL LETTER TURNED K - { 0xA7B0, 0x1, 0x89, -42258, 0 }, -// a7b1 LATIN CAPITAL LETTER TURNED T - { 0xA7B1, 0x1, 0x89, -42282, 0 }, -// a7f7 LATIN EPIGRAPHIC LETTER SIDEWAYS I -// a7f8 MODIFIER LETTER CAPITAL H WITH STROKE -// a7f9 MODIFIER LETTER SMALL LIGATURE OE - { 0xA7F7, 0x3, 0x9, 0, 0 }, -// a7fa LATIN LETTER SMALL CAPITAL TURNED M - { 0xA7FA, 0x1, 0x49, 0, 0 }, -// a7fb LATIN EPIGRAPHIC LETTER REVERSED F -// a7fc LATIN EPIGRAPHIC LETTER REVERSED P -// a7fd LATIN EPIGRAPHIC LETTER INVERTED M -// a7fe LATIN EPIGRAPHIC LETTER I LONGA -// a7ff LATIN EPIGRAPHIC LETTER ARCHAIC M -// a800 SYLOTI NAGRI LETTER A -// a801 SYLOTI NAGRI LETTER I - { 0xA7FB, 0x7, 0x9, 0, 0 }, -// a802 SYLOTI NAGRI SIGN DVISVARA - { 0xA802, 0x1, 0x0, 0, 0 }, -// a803 SYLOTI NAGRI LETTER U -// a804 SYLOTI NAGRI LETTER E -// a805 SYLOTI NAGRI LETTER O - { 0xA803, 0x3, 0x9, 0, 0 }, -// a806 SYLOTI NAGRI SIGN HASANTA - { 0xA806, 0x1, 0x0, 0, 0 }, -// a807 SYLOTI NAGRI LETTER KO -// a808 SYLOTI NAGRI LETTER KHO -// a809 SYLOTI NAGRI LETTER GO -// a80a SYLOTI NAGRI LETTER GHO - { 0xA807, 0x4, 0x9, 0, 0 }, -// a80b SYLOTI NAGRI SIGN ANUSVARA - { 0xA80B, 0x1, 0x0, 0, 0 }, -// a80c SYLOTI NAGRI LETTER CO -// a80d SYLOTI NAGRI LETTER CHO -// a80e SYLOTI NAGRI LETTER JO -// a80f SYLOTI NAGRI LETTER JHO -// a810 SYLOTI NAGRI LETTER TTO -// a811 SYLOTI NAGRI LETTER TTHO -// a812 SYLOTI NAGRI LETTER DDO -// a813 SYLOTI NAGRI LETTER DDHO -// a814 SYLOTI NAGRI LETTER TO -// a815 SYLOTI NAGRI LETTER THO -// a816 SYLOTI NAGRI LETTER DO -// a817 SYLOTI NAGRI LETTER DHO -// a818 SYLOTI NAGRI LETTER NO -// a819 SYLOTI NAGRI LETTER PO -// a81a SYLOTI NAGRI LETTER PHO -// a81b SYLOTI NAGRI LETTER BO -// a81c SYLOTI NAGRI LETTER BHO -// a81d SYLOTI NAGRI LETTER MO -// a81e SYLOTI NAGRI LETTER RO -// a81f SYLOTI NAGRI LETTER LO -// a820 SYLOTI NAGRI LETTER RRO -// a821 SYLOTI NAGRI LETTER SO -// a822 SYLOTI NAGRI LETTER HO - { 0xA80C, 0x17, 0x9, 0, 0 }, -// a823 SYLOTI NAGRI VOWEL SIGN A -// a824 SYLOTI NAGRI VOWEL SIGN I -// a825 SYLOTI NAGRI VOWEL SIGN U -// a826 SYLOTI NAGRI VOWEL SIGN E -// a827 SYLOTI NAGRI VOWEL SIGN OO - { 0xA823, 0x5, 0x0, 0, 0 }, -// a828 SYLOTI NAGRI POETRY MARK-1 -// a829 SYLOTI NAGRI POETRY MARK-2 -// a82a SYLOTI NAGRI POETRY MARK-3 -// a82b SYLOTI NAGRI POETRY MARK-4 - { 0xA828, 0x4, 0x8, 0, 0 }, -// a830 NORTH INDIC FRACTION ONE QUARTER -// a831 NORTH INDIC FRACTION ONE HALF -// a832 NORTH INDIC FRACTION THREE QUARTERS -// a833 NORTH INDIC FRACTION ONE SIXTEENTH -// a834 NORTH INDIC FRACTION ONE EIGHTH -// a835 NORTH INDIC FRACTION THREE SIXTEENTHS -// a836 NORTH INDIC QUARTER MARK -// a837 NORTH INDIC PLACEHOLDER MARK -// a838 NORTH INDIC RUPEE MARK -// a839 NORTH INDIC QUANTITY MARK - { 0xA830, 0xA, 0x8, 0, 0 }, -// a840 PHAGS-PA LETTER KA -// a841 PHAGS-PA LETTER KHA -// a842 PHAGS-PA LETTER GA -// a843 PHAGS-PA LETTER NGA -// a844 PHAGS-PA LETTER CA -// a845 PHAGS-PA LETTER CHA -// a846 PHAGS-PA LETTER JA -// a847 PHAGS-PA LETTER NYA -// a848 PHAGS-PA LETTER TA -// a849 PHAGS-PA LETTER THA -// a84a PHAGS-PA LETTER DA -// a84b PHAGS-PA LETTER NA -// a84c PHAGS-PA LETTER PA -// a84d PHAGS-PA LETTER PHA -// a84e PHAGS-PA LETTER BA -// a84f PHAGS-PA LETTER MA -// a850 PHAGS-PA LETTER TSA -// a851 PHAGS-PA LETTER TSHA -// a852 PHAGS-PA LETTER DZA -// a853 PHAGS-PA LETTER WA -// a854 PHAGS-PA LETTER ZHA -// a855 PHAGS-PA LETTER ZA -// a856 PHAGS-PA LETTER SMALL A -// a857 PHAGS-PA LETTER YA -// a858 PHAGS-PA LETTER RA -// a859 PHAGS-PA LETTER LA -// a85a PHAGS-PA LETTER SHA -// a85b PHAGS-PA LETTER SA -// a85c PHAGS-PA LETTER HA -// a85d PHAGS-PA LETTER A -// a85e PHAGS-PA LETTER I -// a85f PHAGS-PA LETTER U -// a860 PHAGS-PA LETTER E -// a861 PHAGS-PA LETTER O -// a862 PHAGS-PA LETTER QA -// a863 PHAGS-PA LETTER XA -// a864 PHAGS-PA LETTER FA -// a865 PHAGS-PA LETTER GGA -// a866 PHAGS-PA LETTER EE -// a867 PHAGS-PA SUBJOINED LETTER WA -// a868 PHAGS-PA SUBJOINED LETTER YA -// a869 PHAGS-PA LETTER TTA -// a86a PHAGS-PA LETTER TTHA -// a86b PHAGS-PA LETTER DDA -// a86c PHAGS-PA LETTER NNA -// a86d PHAGS-PA LETTER ALTERNATE YA -// a86e PHAGS-PA LETTER VOICELESS SHA -// a86f PHAGS-PA LETTER VOICED HA -// a870 PHAGS-PA LETTER ASPIRATED FA -// a871 PHAGS-PA SUBJOINED LETTER RA -// a872 PHAGS-PA SUPERFIXED LETTER RA -// a873 PHAGS-PA LETTER CANDRABINDU - { 0xA840, 0x34, 0x9, 0, 0 }, -// a874 PHAGS-PA SINGLE HEAD MARK -// a875 PHAGS-PA DOUBLE HEAD MARK -// a876 PHAGS-PA MARK SHAD -// a877 PHAGS-PA MARK DOUBLE SHAD - { 0xA874, 0x4, 0x18, 0, 0 }, -// a880 SAURASHTRA SIGN ANUSVARA -// a881 SAURASHTRA SIGN VISARGA - { 0xA880, 0x2, 0x0, 0, 0 }, -// a882 SAURASHTRA LETTER A -// a883 SAURASHTRA LETTER AA -// a884 SAURASHTRA LETTER I -// a885 SAURASHTRA LETTER II -// a886 SAURASHTRA LETTER U -// a887 SAURASHTRA LETTER UU -// a888 SAURASHTRA LETTER VOCALIC R -// a889 SAURASHTRA LETTER VOCALIC RR -// a88a SAURASHTRA LETTER VOCALIC L -// a88b SAURASHTRA LETTER VOCALIC LL -// a88c SAURASHTRA LETTER E -// a88d SAURASHTRA LETTER EE -// a88e SAURASHTRA LETTER AI -// a88f SAURASHTRA LETTER O -// a890 SAURASHTRA LETTER OO -// a891 SAURASHTRA LETTER AU -// a892 SAURASHTRA LETTER KA -// a893 SAURASHTRA LETTER KHA -// a894 SAURASHTRA LETTER GA -// a895 SAURASHTRA LETTER GHA -// a896 SAURASHTRA LETTER NGA -// a897 SAURASHTRA LETTER CA -// a898 SAURASHTRA LETTER CHA -// a899 SAURASHTRA LETTER JA -// a89a SAURASHTRA LETTER JHA -// a89b SAURASHTRA LETTER NYA -// a89c SAURASHTRA LETTER TTA -// a89d SAURASHTRA LETTER TTHA -// a89e SAURASHTRA LETTER DDA -// a89f SAURASHTRA LETTER DDHA -// a8a0 SAURASHTRA LETTER NNA -// a8a1 SAURASHTRA LETTER TA -// a8a2 SAURASHTRA LETTER THA -// a8a3 SAURASHTRA LETTER DA -// a8a4 SAURASHTRA LETTER DHA -// a8a5 SAURASHTRA LETTER NA -// a8a6 SAURASHTRA LETTER PA -// a8a7 SAURASHTRA LETTER PHA -// a8a8 SAURASHTRA LETTER BA -// a8a9 SAURASHTRA LETTER BHA -// a8aa SAURASHTRA LETTER MA -// a8ab SAURASHTRA LETTER YA -// a8ac SAURASHTRA LETTER RA -// a8ad SAURASHTRA LETTER LA -// a8ae SAURASHTRA LETTER VA -// a8af SAURASHTRA LETTER SHA -// a8b0 SAURASHTRA LETTER SSA -// a8b1 SAURASHTRA LETTER SA -// a8b2 SAURASHTRA LETTER HA -// a8b3 SAURASHTRA LETTER LLA - { 0xA882, 0x32, 0x9, 0, 0 }, -// a8b4 SAURASHTRA CONSONANT SIGN HAARU -// a8b5 SAURASHTRA VOWEL SIGN AA -// a8b6 SAURASHTRA VOWEL SIGN I -// a8b7 SAURASHTRA VOWEL SIGN II -// a8b8 SAURASHTRA VOWEL SIGN U -// a8b9 SAURASHTRA VOWEL SIGN UU -// a8ba SAURASHTRA VOWEL SIGN VOCALIC R -// a8bb SAURASHTRA VOWEL SIGN VOCALIC RR -// a8bc SAURASHTRA VOWEL SIGN VOCALIC L -// a8bd SAURASHTRA VOWEL SIGN VOCALIC LL -// a8be SAURASHTRA VOWEL SIGN E -// a8bf SAURASHTRA VOWEL SIGN EE -// a8c0 SAURASHTRA VOWEL SIGN AI -// a8c1 SAURASHTRA VOWEL SIGN O -// a8c2 SAURASHTRA VOWEL SIGN OO -// a8c3 SAURASHTRA VOWEL SIGN AU -// a8c4 SAURASHTRA SIGN VIRAMA - { 0xA8B4, 0x11, 0x0, 0, 0 }, -// a8ce SAURASHTRA DANDA -// a8cf SAURASHTRA DOUBLE DANDA - { 0xA8CE, 0x2, 0x18, 0, 0 }, -// a8d0 SAURASHTRA DIGIT ZERO -// a8d1 SAURASHTRA DIGIT ONE -// a8d2 SAURASHTRA DIGIT TWO -// a8d3 SAURASHTRA DIGIT THREE -// a8d4 SAURASHTRA DIGIT FOUR -// a8d5 SAURASHTRA DIGIT FIVE -// a8d6 SAURASHTRA DIGIT SIX -// a8d7 SAURASHTRA DIGIT SEVEN -// a8d8 SAURASHTRA DIGIT EIGHT -// a8d9 SAURASHTRA DIGIT NINE - { 0xA8D0, 0xA, 0x108, 0, 0 }, -// a8e0 COMBINING DEVANAGARI DIGIT ZERO -// a8e1 COMBINING DEVANAGARI DIGIT ONE -// a8e2 COMBINING DEVANAGARI DIGIT TWO -// a8e3 COMBINING DEVANAGARI DIGIT THREE -// a8e4 COMBINING DEVANAGARI DIGIT FOUR -// a8e5 COMBINING DEVANAGARI DIGIT FIVE -// a8e6 COMBINING DEVANAGARI DIGIT SIX -// a8e7 COMBINING DEVANAGARI DIGIT SEVEN -// a8e8 COMBINING DEVANAGARI DIGIT EIGHT -// a8e9 COMBINING DEVANAGARI DIGIT NINE -// a8ea COMBINING DEVANAGARI LETTER A -// a8eb COMBINING DEVANAGARI LETTER U -// a8ec COMBINING DEVANAGARI LETTER KA -// a8ed COMBINING DEVANAGARI LETTER NA -// a8ee COMBINING DEVANAGARI LETTER PA -// a8ef COMBINING DEVANAGARI LETTER RA -// a8f0 COMBINING DEVANAGARI LETTER VI -// a8f1 COMBINING DEVANAGARI SIGN AVAGRAHA - { 0xA8E0, 0x12, 0x0, 0, 0 }, -// a8f2 DEVANAGARI SIGN SPACING CANDRABINDU -// a8f3 DEVANAGARI SIGN CANDRABINDU VIRAMA -// a8f4 DEVANAGARI SIGN DOUBLE CANDRABINDU VIRAMA -// a8f5 DEVANAGARI SIGN CANDRABINDU TWO -// a8f6 DEVANAGARI SIGN CANDRABINDU THREE -// a8f7 DEVANAGARI SIGN CANDRABINDU AVAGRAHA - { 0xA8F2, 0x6, 0x9, 0, 0 }, -// a8f8 DEVANAGARI SIGN PUSHPIKA -// a8f9 DEVANAGARI GAP FILLER -// a8fa DEVANAGARI CARET - { 0xA8F8, 0x3, 0x18, 0, 0 }, -// a8fb DEVANAGARI HEADSTROKE - { 0xA8FB, 0x1, 0x9, 0, 0 }, -// a900 KAYAH LI DIGIT ZERO -// a901 KAYAH LI DIGIT ONE -// a902 KAYAH LI DIGIT TWO -// a903 KAYAH LI DIGIT THREE -// a904 KAYAH LI DIGIT FOUR -// a905 KAYAH LI DIGIT FIVE -// a906 KAYAH LI DIGIT SIX -// a907 KAYAH LI DIGIT SEVEN -// a908 KAYAH LI DIGIT EIGHT -// a909 KAYAH LI DIGIT NINE - { 0xA900, 0xA, 0x108, 0, 0 }, -// a90a KAYAH LI LETTER KA -// a90b KAYAH LI LETTER KHA -// a90c KAYAH LI LETTER GA -// a90d KAYAH LI LETTER NGA -// a90e KAYAH LI LETTER SA -// a90f KAYAH LI LETTER SHA -// a910 KAYAH LI LETTER ZA -// a911 KAYAH LI LETTER NYA -// a912 KAYAH LI LETTER TA -// a913 KAYAH LI LETTER HTA -// a914 KAYAH LI LETTER NA -// a915 KAYAH LI LETTER PA -// a916 KAYAH LI LETTER PHA -// a917 KAYAH LI LETTER MA -// a918 KAYAH LI LETTER DA -// a919 KAYAH LI LETTER BA -// a91a KAYAH LI LETTER RA -// a91b KAYAH LI LETTER YA -// a91c KAYAH LI LETTER LA -// a91d KAYAH LI LETTER WA -// a91e KAYAH LI LETTER THA -// a91f KAYAH LI LETTER HA -// a920 KAYAH LI LETTER VA -// a921 KAYAH LI LETTER CA -// a922 KAYAH LI LETTER A -// a923 KAYAH LI LETTER OE -// a924 KAYAH LI LETTER I -// a925 KAYAH LI LETTER OO - { 0xA90A, 0x1C, 0x9, 0, 0 }, -// a926 KAYAH LI VOWEL UE -// a927 KAYAH LI VOWEL E -// a928 KAYAH LI VOWEL U -// a929 KAYAH LI VOWEL EE -// a92a KAYAH LI VOWEL O -// a92b KAYAH LI TONE PLOPHU -// a92c KAYAH LI TONE CALYA -// a92d KAYAH LI TONE CALYA PLOPHU - { 0xA926, 0x8, 0x0, 0, 0 }, -// a92e KAYAH LI SIGN CWI -// a92f KAYAH LI SIGN SHYA - { 0xA92E, 0x2, 0x18, 0, 0 }, -// a930 REJANG LETTER KA -// a931 REJANG LETTER GA -// a932 REJANG LETTER NGA -// a933 REJANG LETTER TA -// a934 REJANG LETTER DA -// a935 REJANG LETTER NA -// a936 REJANG LETTER PA -// a937 REJANG LETTER BA -// a938 REJANG LETTER MA -// a939 REJANG LETTER CA -// a93a REJANG LETTER JA -// a93b REJANG LETTER NYA -// a93c REJANG LETTER SA -// a93d REJANG LETTER RA -// a93e REJANG LETTER LA -// a93f REJANG LETTER YA -// a940 REJANG LETTER WA -// a941 REJANG LETTER HA -// a942 REJANG LETTER MBA -// a943 REJANG LETTER NGGA -// a944 REJANG LETTER NDA -// a945 REJANG LETTER NYJA -// a946 REJANG LETTER A - { 0xA930, 0x17, 0x9, 0, 0 }, -// a947 REJANG VOWEL SIGN I -// a948 REJANG VOWEL SIGN U -// a949 REJANG VOWEL SIGN E -// a94a REJANG VOWEL SIGN AI -// a94b REJANG VOWEL SIGN O -// a94c REJANG VOWEL SIGN AU -// a94d REJANG VOWEL SIGN EU -// a94e REJANG VOWEL SIGN EA -// a94f REJANG CONSONANT SIGN NG -// a950 REJANG CONSONANT SIGN N -// a951 REJANG CONSONANT SIGN R -// a952 REJANG CONSONANT SIGN H -// a953 REJANG VIRAMA - { 0xA947, 0xD, 0x0, 0, 0 }, -// a95f REJANG SECTION MARK - { 0xA95F, 0x1, 0x18, 0, 0 }, -// a960 HANGUL CHOSEONG TIKEUT-MIEUM -// a961 HANGUL CHOSEONG TIKEUT-PIEUP -// a962 HANGUL CHOSEONG TIKEUT-SIOS -// a963 HANGUL CHOSEONG TIKEUT-CIEUC -// a964 HANGUL CHOSEONG RIEUL-KIYEOK -// a965 HANGUL CHOSEONG RIEUL-SSANGKIYEOK -// a966 HANGUL CHOSEONG RIEUL-TIKEUT -// a967 HANGUL CHOSEONG RIEUL-SSANGTIKEUT -// a968 HANGUL CHOSEONG RIEUL-MIEUM -// a969 HANGUL CHOSEONG RIEUL-PIEUP -// a96a HANGUL CHOSEONG RIEUL-SSANGPIEUP -// a96b HANGUL CHOSEONG RIEUL-KAPYEOUNPIEUP -// a96c HANGUL CHOSEONG RIEUL-SIOS -// a96d HANGUL CHOSEONG RIEUL-CIEUC -// a96e HANGUL CHOSEONG RIEUL-KHIEUKH -// a96f HANGUL CHOSEONG MIEUM-KIYEOK -// a970 HANGUL CHOSEONG MIEUM-TIKEUT -// a971 HANGUL CHOSEONG MIEUM-SIOS -// a972 HANGUL CHOSEONG PIEUP-SIOS-THIEUTH -// a973 HANGUL CHOSEONG PIEUP-KHIEUKH -// a974 HANGUL CHOSEONG PIEUP-HIEUH -// a975 HANGUL CHOSEONG SSANGSIOS-PIEUP -// a976 HANGUL CHOSEONG IEUNG-RIEUL -// a977 HANGUL CHOSEONG IEUNG-HIEUH -// a978 HANGUL CHOSEONG SSANGCIEUC-HIEUH -// a979 HANGUL CHOSEONG SSANGTHIEUTH -// a97a HANGUL CHOSEONG PHIEUPH-HIEUH -// a97b HANGUL CHOSEONG HIEUH-SIOS -// a97c HANGUL CHOSEONG SSANGYEORINHIEUH - { 0xA960, 0x1D, 0x9, 0, 0 }, -// a980 JAVANESE SIGN PANYANGGA -// a981 JAVANESE SIGN CECAK -// a982 JAVANESE SIGN LAYAR -// a983 JAVANESE SIGN WIGNYAN - { 0xA980, 0x4, 0x0, 0, 0 }, -// a984 JAVANESE LETTER A -// a985 JAVANESE LETTER I KAWI -// a986 JAVANESE LETTER I -// a987 JAVANESE LETTER II -// a988 JAVANESE LETTER U -// a989 JAVANESE LETTER PA CEREK -// a98a JAVANESE LETTER NGA LELET -// a98b JAVANESE LETTER NGA LELET RASWADI -// a98c JAVANESE LETTER E -// a98d JAVANESE LETTER AI -// a98e JAVANESE LETTER O -// a98f JAVANESE LETTER KA -// a990 JAVANESE LETTER KA SASAK -// a991 JAVANESE LETTER KA MURDA -// a992 JAVANESE LETTER GA -// a993 JAVANESE LETTER GA MURDA -// a994 JAVANESE LETTER NGA -// a995 JAVANESE LETTER CA -// a996 JAVANESE LETTER CA MURDA -// a997 JAVANESE LETTER JA -// a998 JAVANESE LETTER NYA MURDA -// a999 JAVANESE LETTER JA MAHAPRANA -// a99a JAVANESE LETTER NYA -// a99b JAVANESE LETTER TTA -// a99c JAVANESE LETTER TTA MAHAPRANA -// a99d JAVANESE LETTER DDA -// a99e JAVANESE LETTER DDA MAHAPRANA -// a99f JAVANESE LETTER NA MURDA -// a9a0 JAVANESE LETTER TA -// a9a1 JAVANESE LETTER TA MURDA -// a9a2 JAVANESE LETTER DA -// a9a3 JAVANESE LETTER DA MAHAPRANA -// a9a4 JAVANESE LETTER NA -// a9a5 JAVANESE LETTER PA -// a9a6 JAVANESE LETTER PA MURDA -// a9a7 JAVANESE LETTER BA -// a9a8 JAVANESE LETTER BA MURDA -// a9a9 JAVANESE LETTER MA -// a9aa JAVANESE LETTER YA -// a9ab JAVANESE LETTER RA -// a9ac JAVANESE LETTER RA AGUNG -// a9ad JAVANESE LETTER LA -// a9ae JAVANESE LETTER WA -// a9af JAVANESE LETTER SA MURDA -// a9b0 JAVANESE LETTER SA MAHAPRANA -// a9b1 JAVANESE LETTER SA -// a9b2 JAVANESE LETTER HA - { 0xA984, 0x2F, 0x9, 0, 0 }, -// a9b3 JAVANESE SIGN CECAK TELU -// a9b4 JAVANESE VOWEL SIGN TARUNG -// a9b5 JAVANESE VOWEL SIGN TOLONG -// a9b6 JAVANESE VOWEL SIGN WULU -// a9b7 JAVANESE VOWEL SIGN WULU MELIK -// a9b8 JAVANESE VOWEL SIGN SUKU -// a9b9 JAVANESE VOWEL SIGN SUKU MENDUT -// a9ba JAVANESE VOWEL SIGN TALING -// a9bb JAVANESE VOWEL SIGN DIRGA MURE -// a9bc JAVANESE VOWEL SIGN PEPET -// a9bd JAVANESE CONSONANT SIGN KERET -// a9be JAVANESE CONSONANT SIGN PENGKAL -// a9bf JAVANESE CONSONANT SIGN CAKRA -// a9c0 JAVANESE PANGKON - { 0xA9B3, 0xE, 0x0, 0, 0 }, -// a9c1 JAVANESE LEFT RERENGGAN -// a9c2 JAVANESE RIGHT RERENGGAN -// a9c3 JAVANESE PADA ANDAP -// a9c4 JAVANESE PADA MADYA -// a9c5 JAVANESE PADA LUHUR -// a9c6 JAVANESE PADA WINDU -// a9c7 JAVANESE PADA PANGKAT -// a9c8 JAVANESE PADA LINGSA -// a9c9 JAVANESE PADA LUNGSI -// a9ca JAVANESE PADA ADEG -// a9cb JAVANESE PADA ADEG ADEG -// a9cc JAVANESE PADA PISELEH -// a9cd JAVANESE TURNED PADA PISELEH - { 0xA9C1, 0xD, 0x18, 0, 0 }, -// a9cf JAVANESE PANGRANGKEP - { 0xA9CF, 0x1, 0x9, 0, 0 }, -// a9d0 JAVANESE DIGIT ZERO -// a9d1 JAVANESE DIGIT ONE -// a9d2 JAVANESE DIGIT TWO -// a9d3 JAVANESE DIGIT THREE -// a9d4 JAVANESE DIGIT FOUR -// a9d5 JAVANESE DIGIT FIVE -// a9d6 JAVANESE DIGIT SIX -// a9d7 JAVANESE DIGIT SEVEN -// a9d8 JAVANESE DIGIT EIGHT -// a9d9 JAVANESE DIGIT NINE - { 0xA9D0, 0xA, 0x108, 0, 0 }, -// a9de JAVANESE PADA TIRTA TUMETES -// a9df JAVANESE PADA ISEN-ISEN - { 0xA9DE, 0x2, 0x18, 0, 0 }, -// a9e0 MYANMAR LETTER SHAN GHA -// a9e1 MYANMAR LETTER SHAN CHA -// a9e2 MYANMAR LETTER SHAN JHA -// a9e3 MYANMAR LETTER SHAN NNA -// a9e4 MYANMAR LETTER SHAN BHA - { 0xA9E0, 0x5, 0x9, 0, 0 }, -// a9e5 MYANMAR SIGN SHAN SAW - { 0xA9E5, 0x1, 0x0, 0, 0 }, -// a9e6 MYANMAR MODIFIER LETTER SHAN REDUPLICATION -// a9e7 MYANMAR LETTER TAI LAING NYA -// a9e8 MYANMAR LETTER TAI LAING FA -// a9e9 MYANMAR LETTER TAI LAING GA -// a9ea MYANMAR LETTER TAI LAING GHA -// a9eb MYANMAR LETTER TAI LAING JA -// a9ec MYANMAR LETTER TAI LAING JHA -// a9ed MYANMAR LETTER TAI LAING DDA -// a9ee MYANMAR LETTER TAI LAING DDHA -// a9ef MYANMAR LETTER TAI LAING NNA - { 0xA9E6, 0xA, 0x9, 0, 0 }, -// a9f0 MYANMAR TAI LAING DIGIT ZERO -// a9f1 MYANMAR TAI LAING DIGIT ONE -// a9f2 MYANMAR TAI LAING DIGIT TWO -// a9f3 MYANMAR TAI LAING DIGIT THREE -// a9f4 MYANMAR TAI LAING DIGIT FOUR -// a9f5 MYANMAR TAI LAING DIGIT FIVE -// a9f6 MYANMAR TAI LAING DIGIT SIX -// a9f7 MYANMAR TAI LAING DIGIT SEVEN -// a9f8 MYANMAR TAI LAING DIGIT EIGHT -// a9f9 MYANMAR TAI LAING DIGIT NINE - { 0xA9F0, 0xA, 0x108, 0, 0 }, -// a9fa MYANMAR LETTER TAI LAING LLA -// a9fb MYANMAR LETTER TAI LAING DA -// a9fc MYANMAR LETTER TAI LAING DHA -// a9fd MYANMAR LETTER TAI LAING BA -// a9fe MYANMAR LETTER TAI LAING BHA - { 0xA9FA, 0x5, 0x9, 0, 0 }, -// aa00 CHAM LETTER A -// aa01 CHAM LETTER I -// aa02 CHAM LETTER U -// aa03 CHAM LETTER E -// aa04 CHAM LETTER AI -// aa05 CHAM LETTER O -// aa06 CHAM LETTER KA -// aa07 CHAM LETTER KHA -// aa08 CHAM LETTER GA -// aa09 CHAM LETTER GHA -// aa0a CHAM LETTER NGUE -// aa0b CHAM LETTER NGA -// aa0c CHAM LETTER CHA -// aa0d CHAM LETTER CHHA -// aa0e CHAM LETTER JA -// aa0f CHAM LETTER JHA -// aa10 CHAM LETTER NHUE -// aa11 CHAM LETTER NHA -// aa12 CHAM LETTER NHJA -// aa13 CHAM LETTER TA -// aa14 CHAM LETTER THA -// aa15 CHAM LETTER DA -// aa16 CHAM LETTER DHA -// aa17 CHAM LETTER NUE -// aa18 CHAM LETTER NA -// aa19 CHAM LETTER DDA -// aa1a CHAM LETTER PA -// aa1b CHAM LETTER PPA -// aa1c CHAM LETTER PHA -// aa1d CHAM LETTER BA -// aa1e CHAM LETTER BHA -// aa1f CHAM LETTER MUE -// aa20 CHAM LETTER MA -// aa21 CHAM LETTER BBA -// aa22 CHAM LETTER YA -// aa23 CHAM LETTER RA -// aa24 CHAM LETTER LA -// aa25 CHAM LETTER VA -// aa26 CHAM LETTER SSA -// aa27 CHAM LETTER SA -// aa28 CHAM LETTER HA - { 0xAA00, 0x29, 0x9, 0, 0 }, -// aa29 CHAM VOWEL SIGN AA -// aa2a CHAM VOWEL SIGN I -// aa2b CHAM VOWEL SIGN II -// aa2c CHAM VOWEL SIGN EI -// aa2d CHAM VOWEL SIGN U -// aa2e CHAM VOWEL SIGN OE -// aa2f CHAM VOWEL SIGN O -// aa30 CHAM VOWEL SIGN AI -// aa31 CHAM VOWEL SIGN AU -// aa32 CHAM VOWEL SIGN UE -// aa33 CHAM CONSONANT SIGN YA -// aa34 CHAM CONSONANT SIGN RA -// aa35 CHAM CONSONANT SIGN LA -// aa36 CHAM CONSONANT SIGN WA - { 0xAA29, 0xE, 0x0, 0, 0 }, -// aa40 CHAM LETTER FINAL K -// aa41 CHAM LETTER FINAL G -// aa42 CHAM LETTER FINAL NG - { 0xAA40, 0x3, 0x9, 0, 0 }, -// aa43 CHAM CONSONANT SIGN FINAL NG - { 0xAA43, 0x1, 0x0, 0, 0 }, -// aa44 CHAM LETTER FINAL CH -// aa45 CHAM LETTER FINAL T -// aa46 CHAM LETTER FINAL N -// aa47 CHAM LETTER FINAL P -// aa48 CHAM LETTER FINAL Y -// aa49 CHAM LETTER FINAL R -// aa4a CHAM LETTER FINAL L -// aa4b CHAM LETTER FINAL SS - { 0xAA44, 0x8, 0x9, 0, 0 }, -// aa4c CHAM CONSONANT SIGN FINAL M -// aa4d CHAM CONSONANT SIGN FINAL H - { 0xAA4C, 0x2, 0x0, 0, 0 }, -// aa50 CHAM DIGIT ZERO -// aa51 CHAM DIGIT ONE -// aa52 CHAM DIGIT TWO -// aa53 CHAM DIGIT THREE -// aa54 CHAM DIGIT FOUR -// aa55 CHAM DIGIT FIVE -// aa56 CHAM DIGIT SIX -// aa57 CHAM DIGIT SEVEN -// aa58 CHAM DIGIT EIGHT -// aa59 CHAM DIGIT NINE - { 0xAA50, 0xA, 0x108, 0, 0 }, -// aa5c CHAM PUNCTUATION SPIRAL -// aa5d CHAM PUNCTUATION DANDA -// aa5e CHAM PUNCTUATION DOUBLE DANDA -// aa5f CHAM PUNCTUATION TRIPLE DANDA - { 0xAA5C, 0x4, 0x18, 0, 0 }, -// aa60 MYANMAR LETTER KHAMTI GA -// aa61 MYANMAR LETTER KHAMTI CA -// aa62 MYANMAR LETTER KHAMTI CHA -// aa63 MYANMAR LETTER KHAMTI JA -// aa64 MYANMAR LETTER KHAMTI JHA -// aa65 MYANMAR LETTER KHAMTI NYA -// aa66 MYANMAR LETTER KHAMTI TTA -// aa67 MYANMAR LETTER KHAMTI TTHA -// aa68 MYANMAR LETTER KHAMTI DDA -// aa69 MYANMAR LETTER KHAMTI DDHA -// aa6a MYANMAR LETTER KHAMTI DHA -// aa6b MYANMAR LETTER KHAMTI NA -// aa6c MYANMAR LETTER KHAMTI SA -// aa6d MYANMAR LETTER KHAMTI HA -// aa6e MYANMAR LETTER KHAMTI HHA -// aa6f MYANMAR LETTER KHAMTI FA -// aa70 MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION -// aa71 MYANMAR LETTER KHAMTI XA -// aa72 MYANMAR LETTER KHAMTI ZA -// aa73 MYANMAR LETTER KHAMTI RA -// aa74 MYANMAR LOGOGRAM KHAMTI OAY -// aa75 MYANMAR LOGOGRAM KHAMTI QN -// aa76 MYANMAR LOGOGRAM KHAMTI HM - { 0xAA60, 0x17, 0x9, 0, 0 }, -// aa77 MYANMAR SYMBOL AITON EXCLAMATION -// aa78 MYANMAR SYMBOL AITON ONE -// aa79 MYANMAR SYMBOL AITON TWO - { 0xAA77, 0x3, 0x8, 0, 0 }, -// aa7a MYANMAR LETTER AITON RA - { 0xAA7A, 0x1, 0x9, 0, 0 }, -// aa7b MYANMAR SIGN PAO KAREN TONE -// aa7c MYANMAR SIGN TAI LAING TONE-2 -// aa7d MYANMAR SIGN TAI LAING TONE-5 - { 0xAA7B, 0x3, 0x0, 0, 0 }, -// aa7e MYANMAR LETTER SHWE PALAUNG CHA -// aa7f MYANMAR LETTER SHWE PALAUNG SHA -// aa80 TAI VIET LETTER LOW KO -// aa81 TAI VIET LETTER HIGH KO -// aa82 TAI VIET LETTER LOW KHO -// aa83 TAI VIET LETTER HIGH KHO -// aa84 TAI VIET LETTER LOW KHHO -// aa85 TAI VIET LETTER HIGH KHHO -// aa86 TAI VIET LETTER LOW GO -// aa87 TAI VIET LETTER HIGH GO -// aa88 TAI VIET LETTER LOW NGO -// aa89 TAI VIET LETTER HIGH NGO -// aa8a TAI VIET LETTER LOW CO -// aa8b TAI VIET LETTER HIGH CO -// aa8c TAI VIET LETTER LOW CHO -// aa8d TAI VIET LETTER HIGH CHO -// aa8e TAI VIET LETTER LOW SO -// aa8f TAI VIET LETTER HIGH SO -// aa90 TAI VIET LETTER LOW NYO -// aa91 TAI VIET LETTER HIGH NYO -// aa92 TAI VIET LETTER LOW DO -// aa93 TAI VIET LETTER HIGH DO -// aa94 TAI VIET LETTER LOW TO -// aa95 TAI VIET LETTER HIGH TO -// aa96 TAI VIET LETTER LOW THO -// aa97 TAI VIET LETTER HIGH THO -// aa98 TAI VIET LETTER LOW NO -// aa99 TAI VIET LETTER HIGH NO -// aa9a TAI VIET LETTER LOW BO -// aa9b TAI VIET LETTER HIGH BO -// aa9c TAI VIET LETTER LOW PO -// aa9d TAI VIET LETTER HIGH PO -// aa9e TAI VIET LETTER LOW PHO -// aa9f TAI VIET LETTER HIGH PHO -// aaa0 TAI VIET LETTER LOW FO -// aaa1 TAI VIET LETTER HIGH FO -// aaa2 TAI VIET LETTER LOW MO -// aaa3 TAI VIET LETTER HIGH MO -// aaa4 TAI VIET LETTER LOW YO -// aaa5 TAI VIET LETTER HIGH YO -// aaa6 TAI VIET LETTER LOW RO -// aaa7 TAI VIET LETTER HIGH RO -// aaa8 TAI VIET LETTER LOW LO -// aaa9 TAI VIET LETTER HIGH LO -// aaaa TAI VIET LETTER LOW VO -// aaab TAI VIET LETTER HIGH VO -// aaac TAI VIET LETTER LOW HO -// aaad TAI VIET LETTER HIGH HO -// aaae TAI VIET LETTER LOW O -// aaaf TAI VIET LETTER HIGH O - { 0xAA7E, 0x32, 0x9, 0, 0 }, -// aab0 TAI VIET MAI KANG - { 0xAAB0, 0x1, 0x0, 0, 0 }, -// aab1 TAI VIET VOWEL AA - { 0xAAB1, 0x1, 0x9, 0, 0 }, -// aab2 TAI VIET VOWEL I -// aab3 TAI VIET VOWEL UE -// aab4 TAI VIET VOWEL U - { 0xAAB2, 0x3, 0x0, 0, 0 }, -// aab5 TAI VIET VOWEL E -// aab6 TAI VIET VOWEL O - { 0xAAB5, 0x2, 0x9, 0, 0 }, -// aab7 TAI VIET MAI KHIT -// aab8 TAI VIET VOWEL IA - { 0xAAB7, 0x2, 0x0, 0, 0 }, -// aab9 TAI VIET VOWEL UEA -// aaba TAI VIET VOWEL UA -// aabb TAI VIET VOWEL AUE -// aabc TAI VIET VOWEL AY -// aabd TAI VIET VOWEL AN - { 0xAAB9, 0x5, 0x9, 0, 0 }, -// aabe TAI VIET VOWEL AM -// aabf TAI VIET TONE MAI EK - { 0xAABE, 0x2, 0x0, 0, 0 }, -// aac0 TAI VIET TONE MAI NUENG - { 0xAAC0, 0x1, 0x9, 0, 0 }, -// aac1 TAI VIET TONE MAI THO - { 0xAAC1, 0x1, 0x0, 0, 0 }, -// aac2 TAI VIET TONE MAI SONG - { 0xAAC2, 0x1, 0x9, 0, 0 }, -// aadb TAI VIET SYMBOL KON -// aadc TAI VIET SYMBOL NUENG -// aadd TAI VIET SYMBOL SAM - { 0xAADB, 0x3, 0x9, 0, 0 }, -// aade TAI VIET SYMBOL HO HOI -// aadf TAI VIET SYMBOL KOI KOI - { 0xAADE, 0x2, 0x18, 0, 0 }, -// aae0 MEETEI MAYEK LETTER E -// aae1 MEETEI MAYEK LETTER O -// aae2 MEETEI MAYEK LETTER CHA -// aae3 MEETEI MAYEK LETTER NYA -// aae4 MEETEI MAYEK LETTER TTA -// aae5 MEETEI MAYEK LETTER TTHA -// aae6 MEETEI MAYEK LETTER DDA -// aae7 MEETEI MAYEK LETTER DDHA -// aae8 MEETEI MAYEK LETTER NNA -// aae9 MEETEI MAYEK LETTER SHA -// aaea MEETEI MAYEK LETTER SSA - { 0xAAE0, 0xB, 0x9, 0, 0 }, -// aaeb MEETEI MAYEK VOWEL SIGN II -// aaec MEETEI MAYEK VOWEL SIGN UU -// aaed MEETEI MAYEK VOWEL SIGN AAI -// aaee MEETEI MAYEK VOWEL SIGN AU -// aaef MEETEI MAYEK VOWEL SIGN AAU - { 0xAAEB, 0x5, 0x0, 0, 0 }, -// aaf0 MEETEI MAYEK CHEIKHAN -// aaf1 MEETEI MAYEK AHANG KHUDAM - { 0xAAF0, 0x2, 0x18, 0, 0 }, -// aaf2 MEETEI MAYEK ANJI -// aaf3 MEETEI MAYEK SYLLABLE REPETITION MARK -// aaf4 MEETEI MAYEK WORD REPETITION MARK - { 0xAAF2, 0x3, 0x9, 0, 0 }, -// aaf5 MEETEI MAYEK VOWEL SIGN VISARGA -// aaf6 MEETEI MAYEK VIRAMA - { 0xAAF5, 0x2, 0x0, 0, 0 }, -// ab01 ETHIOPIC SYLLABLE TTHU -// ab02 ETHIOPIC SYLLABLE TTHI -// ab03 ETHIOPIC SYLLABLE TTHAA -// ab04 ETHIOPIC SYLLABLE TTHEE -// ab05 ETHIOPIC SYLLABLE TTHE -// ab06 ETHIOPIC SYLLABLE TTHO - { 0xAB01, 0x6, 0x9, 0, 0 }, -// ab09 ETHIOPIC SYLLABLE DDHU -// ab0a ETHIOPIC SYLLABLE DDHI -// ab0b ETHIOPIC SYLLABLE DDHAA -// ab0c ETHIOPIC SYLLABLE DDHEE -// ab0d ETHIOPIC SYLLABLE DDHE -// ab0e ETHIOPIC SYLLABLE DDHO - { 0xAB09, 0x6, 0x9, 0, 0 }, -// ab11 ETHIOPIC SYLLABLE DZU -// ab12 ETHIOPIC SYLLABLE DZI -// ab13 ETHIOPIC SYLLABLE DZAA -// ab14 ETHIOPIC SYLLABLE DZEE -// ab15 ETHIOPIC SYLLABLE DZE -// ab16 ETHIOPIC SYLLABLE DZO - { 0xAB11, 0x6, 0x9, 0, 0 }, -// ab20 ETHIOPIC SYLLABLE CCHHA -// ab21 ETHIOPIC SYLLABLE CCHHU -// ab22 ETHIOPIC SYLLABLE CCHHI -// ab23 ETHIOPIC SYLLABLE CCHHAA -// ab24 ETHIOPIC SYLLABLE CCHHEE -// ab25 ETHIOPIC SYLLABLE CCHHE -// ab26 ETHIOPIC SYLLABLE CCHHO - { 0xAB20, 0x7, 0x9, 0, 0 }, -// ab28 ETHIOPIC SYLLABLE BBA -// ab29 ETHIOPIC SYLLABLE BBU -// ab2a ETHIOPIC SYLLABLE BBI -// ab2b ETHIOPIC SYLLABLE BBAA -// ab2c ETHIOPIC SYLLABLE BBEE -// ab2d ETHIOPIC SYLLABLE BBE -// ab2e ETHIOPIC SYLLABLE BBO - { 0xAB28, 0x7, 0x9, 0, 0 }, -// ab30 LATIN SMALL LETTER BARRED ALPHA -// ab31 LATIN SMALL LETTER A REVERSED-SCHWA -// ab32 LATIN SMALL LETTER BLACKLETTER E -// ab33 LATIN SMALL LETTER BARRED E -// ab34 LATIN SMALL LETTER E WITH FLOURISH -// ab35 LATIN SMALL LETTER LENIS F -// ab36 LATIN SMALL LETTER SCRIPT G WITH CROSSED-TAIL -// ab37 LATIN SMALL LETTER L WITH INVERTED LAZY S -// ab38 LATIN SMALL LETTER L WITH DOUBLE MIDDLE TILDE -// ab39 LATIN SMALL LETTER L WITH MIDDLE RING -// ab3a LATIN SMALL LETTER M WITH CROSSED-TAIL -// ab3b LATIN SMALL LETTER N WITH CROSSED-TAIL -// ab3c LATIN SMALL LETTER ENG WITH CROSSED-TAIL -// ab3d LATIN SMALL LETTER BLACKLETTER O -// ab3e LATIN SMALL LETTER BLACKLETTER O WITH STROKE -// ab3f LATIN SMALL LETTER OPEN O WITH STROKE -// ab40 LATIN SMALL LETTER INVERTED OE -// ab41 LATIN SMALL LETTER TURNED OE WITH STROKE -// ab42 LATIN SMALL LETTER TURNED OE WITH HORIZONTAL STROKE -// ab43 LATIN SMALL LETTER TURNED O OPEN-O -// ab44 LATIN SMALL LETTER TURNED O OPEN-O WITH STROKE -// ab45 LATIN SMALL LETTER STIRRUP R -// ab46 LATIN LETTER SMALL CAPITAL R WITH RIGHT LEG -// ab47 LATIN SMALL LETTER R WITHOUT HANDLE -// ab48 LATIN SMALL LETTER DOUBLE R -// ab49 LATIN SMALL LETTER R WITH CROSSED-TAIL -// ab4a LATIN SMALL LETTER DOUBLE R WITH CROSSED-TAIL -// ab4b LATIN SMALL LETTER SCRIPT R -// ab4c LATIN SMALL LETTER SCRIPT R WITH RING -// ab4d LATIN SMALL LETTER BASELINE ESH -// ab4e LATIN SMALL LETTER U WITH SHORT RIGHT LEG -// ab4f LATIN SMALL LETTER U BAR WITH SHORT RIGHT LEG -// ab50 LATIN SMALL LETTER UI -// ab51 LATIN SMALL LETTER TURNED UI -// ab52 LATIN SMALL LETTER U WITH LEFT HOOK -// ab53 LATIN SMALL LETTER CHI -// ab54 LATIN SMALL LETTER CHI WITH LOW RIGHT RING -// ab55 LATIN SMALL LETTER CHI WITH LOW LEFT SERIF -// ab56 LATIN SMALL LETTER X WITH LOW RIGHT RING -// ab57 LATIN SMALL LETTER X WITH LONG LEFT LEG -// ab58 LATIN SMALL LETTER X WITH LONG LEFT LEG AND LOW RIGHT RING -// ab59 LATIN SMALL LETTER X WITH LONG LEFT LEG WITH SERIF -// ab5a LATIN SMALL LETTER Y WITH SHORT RIGHT LEG - { 0xAB30, 0x2B, 0x49, 0, 0 }, -// ab5b MODIFIER BREVE WITH INVERTED BREVE - { 0xAB5B, 0x1, 0x8, 0, 0 }, -// ab5c MODIFIER LETTER SMALL HENG -// ab5d MODIFIER LETTER SMALL L WITH INVERTED LAZY S -// ab5e MODIFIER LETTER SMALL L WITH MIDDLE TILDE -// ab5f MODIFIER LETTER SMALL U WITH LEFT HOOK - { 0xAB5C, 0x4, 0x9, 0, 0 }, -// ab64 LATIN SMALL LETTER INVERTED ALPHA -// ab65 GREEK LETTER SMALL CAPITAL OMEGA - { 0xAB64, 0x2, 0x49, 0, 0 }, -// abc0 MEETEI MAYEK LETTER KOK -// abc1 MEETEI MAYEK LETTER SAM -// abc2 MEETEI MAYEK LETTER LAI -// abc3 MEETEI MAYEK LETTER MIT -// abc4 MEETEI MAYEK LETTER PA -// abc5 MEETEI MAYEK LETTER NA -// abc6 MEETEI MAYEK LETTER CHIL -// abc7 MEETEI MAYEK LETTER TIL -// abc8 MEETEI MAYEK LETTER KHOU -// abc9 MEETEI MAYEK LETTER NGOU -// abca MEETEI MAYEK LETTER THOU -// abcb MEETEI MAYEK LETTER WAI -// abcc MEETEI MAYEK LETTER YANG -// abcd MEETEI MAYEK LETTER HUK -// abce MEETEI MAYEK LETTER UN -// abcf MEETEI MAYEK LETTER I -// abd0 MEETEI MAYEK LETTER PHAM -// abd1 MEETEI MAYEK LETTER ATIYA -// abd2 MEETEI MAYEK LETTER GOK -// abd3 MEETEI MAYEK LETTER JHAM -// abd4 MEETEI MAYEK LETTER RAI -// abd5 MEETEI MAYEK LETTER BA -// abd6 MEETEI MAYEK LETTER JIL -// abd7 MEETEI MAYEK LETTER DIL -// abd8 MEETEI MAYEK LETTER GHOU -// abd9 MEETEI MAYEK LETTER DHOU -// abda MEETEI MAYEK LETTER BHAM -// abdb MEETEI MAYEK LETTER KOK LONSUM -// abdc MEETEI MAYEK LETTER LAI LONSUM -// abdd MEETEI MAYEK LETTER MIT LONSUM -// abde MEETEI MAYEK LETTER PA LONSUM -// abdf MEETEI MAYEK LETTER NA LONSUM -// abe0 MEETEI MAYEK LETTER TIL LONSUM -// abe1 MEETEI MAYEK LETTER NGOU LONSUM -// abe2 MEETEI MAYEK LETTER I LONSUM - { 0xABC0, 0x23, 0x9, 0, 0 }, -// abe3 MEETEI MAYEK VOWEL SIGN ONAP -// abe4 MEETEI MAYEK VOWEL SIGN INAP -// abe5 MEETEI MAYEK VOWEL SIGN ANAP -// abe6 MEETEI MAYEK VOWEL SIGN YENAP -// abe7 MEETEI MAYEK VOWEL SIGN SOUNAP -// abe8 MEETEI MAYEK VOWEL SIGN UNAP -// abe9 MEETEI MAYEK VOWEL SIGN CHEINAP -// abea MEETEI MAYEK VOWEL SIGN NUNG - { 0xABE3, 0x8, 0x0, 0, 0 }, -// abeb MEETEI MAYEK CHEIKHEI - { 0xABEB, 0x1, 0x18, 0, 0 }, -// abec MEETEI MAYEK LUM IYEK -// abed MEETEI MAYEK APUN IYEK - { 0xABEC, 0x2, 0x0, 0, 0 }, -// abf0 MEETEI MAYEK DIGIT ZERO -// abf1 MEETEI MAYEK DIGIT ONE -// abf2 MEETEI MAYEK DIGIT TWO -// abf3 MEETEI MAYEK DIGIT THREE -// abf4 MEETEI MAYEK DIGIT FOUR -// abf5 MEETEI MAYEK DIGIT FIVE -// abf6 MEETEI MAYEK DIGIT SIX -// abf7 MEETEI MAYEK DIGIT SEVEN -// abf8 MEETEI MAYEK DIGIT EIGHT -// abf9 MEETEI MAYEK DIGIT NINE - { 0xABF0, 0xA, 0x108, 0, 0 }, -// ac00 - { 0xAC00, 0x1, 0x9, 0, 0 }, -// d7a3 - { 0xD7A3, 0x1, 0x9, 0, 0 }, -// d7b0 HANGUL JUNGSEONG O-YEO -// d7b1 HANGUL JUNGSEONG O-O-I -// d7b2 HANGUL JUNGSEONG YO-A -// d7b3 HANGUL JUNGSEONG YO-AE -// d7b4 HANGUL JUNGSEONG YO-EO -// d7b5 HANGUL JUNGSEONG U-YEO -// d7b6 HANGUL JUNGSEONG U-I-I -// d7b7 HANGUL JUNGSEONG YU-AE -// d7b8 HANGUL JUNGSEONG YU-O -// d7b9 HANGUL JUNGSEONG EU-A -// d7ba HANGUL JUNGSEONG EU-EO -// d7bb HANGUL JUNGSEONG EU-E -// d7bc HANGUL JUNGSEONG EU-O -// d7bd HANGUL JUNGSEONG I-YA-O -// d7be HANGUL JUNGSEONG I-YAE -// d7bf HANGUL JUNGSEONG I-YEO -// d7c0 HANGUL JUNGSEONG I-YE -// d7c1 HANGUL JUNGSEONG I-O-I -// d7c2 HANGUL JUNGSEONG I-YO -// d7c3 HANGUL JUNGSEONG I-YU -// d7c4 HANGUL JUNGSEONG I-I -// d7c5 HANGUL JUNGSEONG ARAEA-A -// d7c6 HANGUL JUNGSEONG ARAEA-E - { 0xD7B0, 0x17, 0x9, 0, 0 }, -// d7cb HANGUL JONGSEONG NIEUN-RIEUL -// d7cc HANGUL JONGSEONG NIEUN-CHIEUCH -// d7cd HANGUL JONGSEONG SSANGTIKEUT -// d7ce HANGUL JONGSEONG SSANGTIKEUT-PIEUP -// d7cf HANGUL JONGSEONG TIKEUT-PIEUP -// d7d0 HANGUL JONGSEONG TIKEUT-SIOS -// d7d1 HANGUL JONGSEONG TIKEUT-SIOS-KIYEOK -// d7d2 HANGUL JONGSEONG TIKEUT-CIEUC -// d7d3 HANGUL JONGSEONG TIKEUT-CHIEUCH -// d7d4 HANGUL JONGSEONG TIKEUT-THIEUTH -// d7d5 HANGUL JONGSEONG RIEUL-SSANGKIYEOK -// d7d6 HANGUL JONGSEONG RIEUL-KIYEOK-HIEUH -// d7d7 HANGUL JONGSEONG SSANGRIEUL-KHIEUKH -// d7d8 HANGUL JONGSEONG RIEUL-MIEUM-HIEUH -// d7d9 HANGUL JONGSEONG RIEUL-PIEUP-TIKEUT -// d7da HANGUL JONGSEONG RIEUL-PIEUP-PHIEUPH -// d7db HANGUL JONGSEONG RIEUL-YESIEUNG -// d7dc HANGUL JONGSEONG RIEUL-YEORINHIEUH-HIEUH -// d7dd HANGUL JONGSEONG KAPYEOUNRIEUL -// d7de HANGUL JONGSEONG MIEUM-NIEUN -// d7df HANGUL JONGSEONG MIEUM-SSANGNIEUN -// d7e0 HANGUL JONGSEONG SSANGMIEUM -// d7e1 HANGUL JONGSEONG MIEUM-PIEUP-SIOS -// d7e2 HANGUL JONGSEONG MIEUM-CIEUC -// d7e3 HANGUL JONGSEONG PIEUP-TIKEUT -// d7e4 HANGUL JONGSEONG PIEUP-RIEUL-PHIEUPH -// d7e5 HANGUL JONGSEONG PIEUP-MIEUM -// d7e6 HANGUL JONGSEONG SSANGPIEUP -// d7e7 HANGUL JONGSEONG PIEUP-SIOS-TIKEUT -// d7e8 HANGUL JONGSEONG PIEUP-CIEUC -// d7e9 HANGUL JONGSEONG PIEUP-CHIEUCH -// d7ea HANGUL JONGSEONG SIOS-MIEUM -// d7eb HANGUL JONGSEONG SIOS-KAPYEOUNPIEUP -// d7ec HANGUL JONGSEONG SSANGSIOS-KIYEOK -// d7ed HANGUL JONGSEONG SSANGSIOS-TIKEUT -// d7ee HANGUL JONGSEONG SIOS-PANSIOS -// d7ef HANGUL JONGSEONG SIOS-CIEUC -// d7f0 HANGUL JONGSEONG SIOS-CHIEUCH -// d7f1 HANGUL JONGSEONG SIOS-THIEUTH -// d7f2 HANGUL JONGSEONG SIOS-HIEUH -// d7f3 HANGUL JONGSEONG PANSIOS-PIEUP -// d7f4 HANGUL JONGSEONG PANSIOS-KAPYEOUNPIEUP -// d7f5 HANGUL JONGSEONG YESIEUNG-MIEUM -// d7f6 HANGUL JONGSEONG YESIEUNG-HIEUH -// d7f7 HANGUL JONGSEONG CIEUC-PIEUP -// d7f8 HANGUL JONGSEONG CIEUC-SSANGPIEUP -// d7f9 HANGUL JONGSEONG SSANGCIEUC -// d7fa HANGUL JONGSEONG PHIEUPH-SIOS -// d7fb HANGUL JONGSEONG PHIEUPH-THIEUTH - { 0xD7CB, 0x31, 0x9, 0, 0 }, -// d800 - { 0xD800, 0x1, 0x0, 0, 0 }, -// db7f -// db80 - { 0xDB7F, 0x2, 0x0, 0, 0 }, -// dbff -// dc00 - { 0xDBFF, 0x2, 0x0, 0, 0 }, -// dfff -// e000 - { 0xDFFF, 0x2, 0x0, 0, 0 }, -// f8ff - { 0xF8FF, 0x1, 0x0, 0, 0 }, -// f900 CJK COMPATIBILITY IDEOGRAPH-F900 -// f901 CJK COMPATIBILITY IDEOGRAPH-F901 -// f902 CJK COMPATIBILITY IDEOGRAPH-F902 -// f903 CJK COMPATIBILITY IDEOGRAPH-F903 -// f904 CJK COMPATIBILITY IDEOGRAPH-F904 -// f905 CJK COMPATIBILITY IDEOGRAPH-F905 -// f906 CJK COMPATIBILITY IDEOGRAPH-F906 -// f907 CJK COMPATIBILITY IDEOGRAPH-F907 -// f908 CJK COMPATIBILITY IDEOGRAPH-F908 -// f909 CJK COMPATIBILITY IDEOGRAPH-F909 -// f90a CJK COMPATIBILITY IDEOGRAPH-F90A -// f90b CJK COMPATIBILITY IDEOGRAPH-F90B -// f90c CJK COMPATIBILITY IDEOGRAPH-F90C -// f90d CJK COMPATIBILITY IDEOGRAPH-F90D -// f90e CJK COMPATIBILITY IDEOGRAPH-F90E -// f90f CJK COMPATIBILITY IDEOGRAPH-F90F -// f910 CJK COMPATIBILITY IDEOGRAPH-F910 -// f911 CJK COMPATIBILITY IDEOGRAPH-F911 -// f912 CJK COMPATIBILITY IDEOGRAPH-F912 -// f913 CJK COMPATIBILITY IDEOGRAPH-F913 -// f914 CJK COMPATIBILITY IDEOGRAPH-F914 -// f915 CJK COMPATIBILITY IDEOGRAPH-F915 -// f916 CJK COMPATIBILITY IDEOGRAPH-F916 -// f917 CJK COMPATIBILITY IDEOGRAPH-F917 -// f918 CJK COMPATIBILITY IDEOGRAPH-F918 -// f919 CJK COMPATIBILITY IDEOGRAPH-F919 -// f91a CJK COMPATIBILITY IDEOGRAPH-F91A -// f91b CJK COMPATIBILITY IDEOGRAPH-F91B -// f91c CJK COMPATIBILITY IDEOGRAPH-F91C -// f91d CJK COMPATIBILITY IDEOGRAPH-F91D -// f91e CJK COMPATIBILITY IDEOGRAPH-F91E -// f91f CJK COMPATIBILITY IDEOGRAPH-F91F -// f920 CJK COMPATIBILITY IDEOGRAPH-F920 -// f921 CJK COMPATIBILITY IDEOGRAPH-F921 -// f922 CJK COMPATIBILITY IDEOGRAPH-F922 -// f923 CJK COMPATIBILITY IDEOGRAPH-F923 -// f924 CJK COMPATIBILITY IDEOGRAPH-F924 -// f925 CJK COMPATIBILITY IDEOGRAPH-F925 -// f926 CJK COMPATIBILITY IDEOGRAPH-F926 -// f927 CJK COMPATIBILITY IDEOGRAPH-F927 -// f928 CJK COMPATIBILITY IDEOGRAPH-F928 -// f929 CJK COMPATIBILITY IDEOGRAPH-F929 -// f92a CJK COMPATIBILITY IDEOGRAPH-F92A -// f92b CJK COMPATIBILITY IDEOGRAPH-F92B -// f92c CJK COMPATIBILITY IDEOGRAPH-F92C -// f92d CJK COMPATIBILITY IDEOGRAPH-F92D -// f92e CJK COMPATIBILITY IDEOGRAPH-F92E -// f92f CJK COMPATIBILITY IDEOGRAPH-F92F -// f930 CJK COMPATIBILITY IDEOGRAPH-F930 -// f931 CJK COMPATIBILITY IDEOGRAPH-F931 -// f932 CJK COMPATIBILITY IDEOGRAPH-F932 -// f933 CJK COMPATIBILITY IDEOGRAPH-F933 -// f934 CJK COMPATIBILITY IDEOGRAPH-F934 -// f935 CJK COMPATIBILITY IDEOGRAPH-F935 -// f936 CJK COMPATIBILITY IDEOGRAPH-F936 -// f937 CJK COMPATIBILITY IDEOGRAPH-F937 -// f938 CJK COMPATIBILITY IDEOGRAPH-F938 -// f939 CJK COMPATIBILITY IDEOGRAPH-F939 -// f93a CJK COMPATIBILITY IDEOGRAPH-F93A -// f93b CJK COMPATIBILITY IDEOGRAPH-F93B -// f93c CJK COMPATIBILITY IDEOGRAPH-F93C -// f93d CJK COMPATIBILITY IDEOGRAPH-F93D -// f93e CJK COMPATIBILITY IDEOGRAPH-F93E -// f93f CJK COMPATIBILITY IDEOGRAPH-F93F -// f940 CJK COMPATIBILITY IDEOGRAPH-F940 -// f941 CJK COMPATIBILITY IDEOGRAPH-F941 -// f942 CJK COMPATIBILITY IDEOGRAPH-F942 -// f943 CJK COMPATIBILITY IDEOGRAPH-F943 -// f944 CJK COMPATIBILITY IDEOGRAPH-F944 -// f945 CJK COMPATIBILITY IDEOGRAPH-F945 -// f946 CJK COMPATIBILITY IDEOGRAPH-F946 -// f947 CJK COMPATIBILITY IDEOGRAPH-F947 -// f948 CJK COMPATIBILITY IDEOGRAPH-F948 -// f949 CJK COMPATIBILITY IDEOGRAPH-F949 -// f94a CJK COMPATIBILITY IDEOGRAPH-F94A -// f94b CJK COMPATIBILITY IDEOGRAPH-F94B -// f94c CJK COMPATIBILITY IDEOGRAPH-F94C -// f94d CJK COMPATIBILITY IDEOGRAPH-F94D -// f94e CJK COMPATIBILITY IDEOGRAPH-F94E -// f94f CJK COMPATIBILITY IDEOGRAPH-F94F -// f950 CJK COMPATIBILITY IDEOGRAPH-F950 -// f951 CJK COMPATIBILITY IDEOGRAPH-F951 -// f952 CJK COMPATIBILITY IDEOGRAPH-F952 -// f953 CJK COMPATIBILITY IDEOGRAPH-F953 -// f954 CJK COMPATIBILITY IDEOGRAPH-F954 -// f955 CJK COMPATIBILITY IDEOGRAPH-F955 -// f956 CJK COMPATIBILITY IDEOGRAPH-F956 -// f957 CJK COMPATIBILITY IDEOGRAPH-F957 -// f958 CJK COMPATIBILITY IDEOGRAPH-F958 -// f959 CJK COMPATIBILITY IDEOGRAPH-F959 -// f95a CJK COMPATIBILITY IDEOGRAPH-F95A -// f95b CJK COMPATIBILITY IDEOGRAPH-F95B -// f95c CJK COMPATIBILITY IDEOGRAPH-F95C -// f95d CJK COMPATIBILITY IDEOGRAPH-F95D -// f95e CJK COMPATIBILITY IDEOGRAPH-F95E -// f95f CJK COMPATIBILITY IDEOGRAPH-F95F -// f960 CJK COMPATIBILITY IDEOGRAPH-F960 -// f961 CJK COMPATIBILITY IDEOGRAPH-F961 -// f962 CJK COMPATIBILITY IDEOGRAPH-F962 -// f963 CJK COMPATIBILITY IDEOGRAPH-F963 -// f964 CJK COMPATIBILITY IDEOGRAPH-F964 -// f965 CJK COMPATIBILITY IDEOGRAPH-F965 -// f966 CJK COMPATIBILITY IDEOGRAPH-F966 -// f967 CJK COMPATIBILITY IDEOGRAPH-F967 -// f968 CJK COMPATIBILITY IDEOGRAPH-F968 -// f969 CJK COMPATIBILITY IDEOGRAPH-F969 -// f96a CJK COMPATIBILITY IDEOGRAPH-F96A -// f96b CJK COMPATIBILITY IDEOGRAPH-F96B -// f96c CJK COMPATIBILITY IDEOGRAPH-F96C -// f96d CJK COMPATIBILITY IDEOGRAPH-F96D -// f96e CJK COMPATIBILITY IDEOGRAPH-F96E -// f96f CJK COMPATIBILITY IDEOGRAPH-F96F -// f970 CJK COMPATIBILITY IDEOGRAPH-F970 -// f971 CJK COMPATIBILITY IDEOGRAPH-F971 -// f972 CJK COMPATIBILITY IDEOGRAPH-F972 -// f973 CJK COMPATIBILITY IDEOGRAPH-F973 -// f974 CJK COMPATIBILITY IDEOGRAPH-F974 -// f975 CJK COMPATIBILITY IDEOGRAPH-F975 -// f976 CJK COMPATIBILITY IDEOGRAPH-F976 -// f977 CJK COMPATIBILITY IDEOGRAPH-F977 -// f978 CJK COMPATIBILITY IDEOGRAPH-F978 -// f979 CJK COMPATIBILITY IDEOGRAPH-F979 -// f97a CJK COMPATIBILITY IDEOGRAPH-F97A -// f97b CJK COMPATIBILITY IDEOGRAPH-F97B -// f97c CJK COMPATIBILITY IDEOGRAPH-F97C -// f97d CJK COMPATIBILITY IDEOGRAPH-F97D -// f97e CJK COMPATIBILITY IDEOGRAPH-F97E -// f97f CJK COMPATIBILITY IDEOGRAPH-F97F -// f980 CJK COMPATIBILITY IDEOGRAPH-F980 -// f981 CJK COMPATIBILITY IDEOGRAPH-F981 -// f982 CJK COMPATIBILITY IDEOGRAPH-F982 -// f983 CJK COMPATIBILITY IDEOGRAPH-F983 -// f984 CJK COMPATIBILITY IDEOGRAPH-F984 -// f985 CJK COMPATIBILITY IDEOGRAPH-F985 -// f986 CJK COMPATIBILITY IDEOGRAPH-F986 -// f987 CJK COMPATIBILITY IDEOGRAPH-F987 -// f988 CJK COMPATIBILITY IDEOGRAPH-F988 -// f989 CJK COMPATIBILITY IDEOGRAPH-F989 -// f98a CJK COMPATIBILITY IDEOGRAPH-F98A -// f98b CJK COMPATIBILITY IDEOGRAPH-F98B -// f98c CJK COMPATIBILITY IDEOGRAPH-F98C -// f98d CJK COMPATIBILITY IDEOGRAPH-F98D -// f98e CJK COMPATIBILITY IDEOGRAPH-F98E -// f98f CJK COMPATIBILITY IDEOGRAPH-F98F -// f990 CJK COMPATIBILITY IDEOGRAPH-F990 -// f991 CJK COMPATIBILITY IDEOGRAPH-F991 -// f992 CJK COMPATIBILITY IDEOGRAPH-F992 -// f993 CJK COMPATIBILITY IDEOGRAPH-F993 -// f994 CJK COMPATIBILITY IDEOGRAPH-F994 -// f995 CJK COMPATIBILITY IDEOGRAPH-F995 -// f996 CJK COMPATIBILITY IDEOGRAPH-F996 -// f997 CJK COMPATIBILITY IDEOGRAPH-F997 -// f998 CJK COMPATIBILITY IDEOGRAPH-F998 -// f999 CJK COMPATIBILITY IDEOGRAPH-F999 -// f99a CJK COMPATIBILITY IDEOGRAPH-F99A -// f99b CJK COMPATIBILITY IDEOGRAPH-F99B -// f99c CJK COMPATIBILITY IDEOGRAPH-F99C -// f99d CJK COMPATIBILITY IDEOGRAPH-F99D -// f99e CJK COMPATIBILITY IDEOGRAPH-F99E -// f99f CJK COMPATIBILITY IDEOGRAPH-F99F -// f9a0 CJK COMPATIBILITY IDEOGRAPH-F9A0 -// f9a1 CJK COMPATIBILITY IDEOGRAPH-F9A1 -// f9a2 CJK COMPATIBILITY IDEOGRAPH-F9A2 -// f9a3 CJK COMPATIBILITY IDEOGRAPH-F9A3 -// f9a4 CJK COMPATIBILITY IDEOGRAPH-F9A4 -// f9a5 CJK COMPATIBILITY IDEOGRAPH-F9A5 -// f9a6 CJK COMPATIBILITY IDEOGRAPH-F9A6 -// f9a7 CJK COMPATIBILITY IDEOGRAPH-F9A7 -// f9a8 CJK COMPATIBILITY IDEOGRAPH-F9A8 -// f9a9 CJK COMPATIBILITY IDEOGRAPH-F9A9 -// f9aa CJK COMPATIBILITY IDEOGRAPH-F9AA -// f9ab CJK COMPATIBILITY IDEOGRAPH-F9AB -// f9ac CJK COMPATIBILITY IDEOGRAPH-F9AC -// f9ad CJK COMPATIBILITY IDEOGRAPH-F9AD -// f9ae CJK COMPATIBILITY IDEOGRAPH-F9AE -// f9af CJK COMPATIBILITY IDEOGRAPH-F9AF -// f9b0 CJK COMPATIBILITY IDEOGRAPH-F9B0 -// f9b1 CJK COMPATIBILITY IDEOGRAPH-F9B1 -// f9b2 CJK COMPATIBILITY IDEOGRAPH-F9B2 -// f9b3 CJK COMPATIBILITY IDEOGRAPH-F9B3 -// f9b4 CJK COMPATIBILITY IDEOGRAPH-F9B4 -// f9b5 CJK COMPATIBILITY IDEOGRAPH-F9B5 -// f9b6 CJK COMPATIBILITY IDEOGRAPH-F9B6 -// f9b7 CJK COMPATIBILITY IDEOGRAPH-F9B7 -// f9b8 CJK COMPATIBILITY IDEOGRAPH-F9B8 -// f9b9 CJK COMPATIBILITY IDEOGRAPH-F9B9 -// f9ba CJK COMPATIBILITY IDEOGRAPH-F9BA -// f9bb CJK COMPATIBILITY IDEOGRAPH-F9BB -// f9bc CJK COMPATIBILITY IDEOGRAPH-F9BC -// f9bd CJK COMPATIBILITY IDEOGRAPH-F9BD -// f9be CJK COMPATIBILITY IDEOGRAPH-F9BE -// f9bf CJK COMPATIBILITY IDEOGRAPH-F9BF -// f9c0 CJK COMPATIBILITY IDEOGRAPH-F9C0 -// f9c1 CJK COMPATIBILITY IDEOGRAPH-F9C1 -// f9c2 CJK COMPATIBILITY IDEOGRAPH-F9C2 -// f9c3 CJK COMPATIBILITY IDEOGRAPH-F9C3 -// f9c4 CJK COMPATIBILITY IDEOGRAPH-F9C4 -// f9c5 CJK COMPATIBILITY IDEOGRAPH-F9C5 -// f9c6 CJK COMPATIBILITY IDEOGRAPH-F9C6 -// f9c7 CJK COMPATIBILITY IDEOGRAPH-F9C7 -// f9c8 CJK COMPATIBILITY IDEOGRAPH-F9C8 -// f9c9 CJK COMPATIBILITY IDEOGRAPH-F9C9 -// f9ca CJK COMPATIBILITY IDEOGRAPH-F9CA -// f9cb CJK COMPATIBILITY IDEOGRAPH-F9CB -// f9cc CJK COMPATIBILITY IDEOGRAPH-F9CC -// f9cd CJK COMPATIBILITY IDEOGRAPH-F9CD -// f9ce CJK COMPATIBILITY IDEOGRAPH-F9CE -// f9cf CJK COMPATIBILITY IDEOGRAPH-F9CF -// f9d0 CJK COMPATIBILITY IDEOGRAPH-F9D0 -// f9d1 CJK COMPATIBILITY IDEOGRAPH-F9D1 -// f9d2 CJK COMPATIBILITY IDEOGRAPH-F9D2 -// f9d3 CJK COMPATIBILITY IDEOGRAPH-F9D3 -// f9d4 CJK COMPATIBILITY IDEOGRAPH-F9D4 -// f9d5 CJK COMPATIBILITY IDEOGRAPH-F9D5 -// f9d6 CJK COMPATIBILITY IDEOGRAPH-F9D6 -// f9d7 CJK COMPATIBILITY IDEOGRAPH-F9D7 -// f9d8 CJK COMPATIBILITY IDEOGRAPH-F9D8 -// f9d9 CJK COMPATIBILITY IDEOGRAPH-F9D9 -// f9da CJK COMPATIBILITY IDEOGRAPH-F9DA -// f9db CJK COMPATIBILITY IDEOGRAPH-F9DB -// f9dc CJK COMPATIBILITY IDEOGRAPH-F9DC -// f9dd CJK COMPATIBILITY IDEOGRAPH-F9DD -// f9de CJK COMPATIBILITY IDEOGRAPH-F9DE -// f9df CJK COMPATIBILITY IDEOGRAPH-F9DF -// f9e0 CJK COMPATIBILITY IDEOGRAPH-F9E0 -// f9e1 CJK COMPATIBILITY IDEOGRAPH-F9E1 -// f9e2 CJK COMPATIBILITY IDEOGRAPH-F9E2 -// f9e3 CJK COMPATIBILITY IDEOGRAPH-F9E3 -// f9e4 CJK COMPATIBILITY IDEOGRAPH-F9E4 -// f9e5 CJK COMPATIBILITY IDEOGRAPH-F9E5 -// f9e6 CJK COMPATIBILITY IDEOGRAPH-F9E6 -// f9e7 CJK COMPATIBILITY IDEOGRAPH-F9E7 -// f9e8 CJK COMPATIBILITY IDEOGRAPH-F9E8 -// f9e9 CJK COMPATIBILITY IDEOGRAPH-F9E9 -// f9ea CJK COMPATIBILITY IDEOGRAPH-F9EA -// f9eb CJK COMPATIBILITY IDEOGRAPH-F9EB -// f9ec CJK COMPATIBILITY IDEOGRAPH-F9EC -// f9ed CJK COMPATIBILITY IDEOGRAPH-F9ED -// f9ee CJK COMPATIBILITY IDEOGRAPH-F9EE -// f9ef CJK COMPATIBILITY IDEOGRAPH-F9EF -// f9f0 CJK COMPATIBILITY IDEOGRAPH-F9F0 -// f9f1 CJK COMPATIBILITY IDEOGRAPH-F9F1 -// f9f2 CJK COMPATIBILITY IDEOGRAPH-F9F2 -// f9f3 CJK COMPATIBILITY IDEOGRAPH-F9F3 -// f9f4 CJK COMPATIBILITY IDEOGRAPH-F9F4 -// f9f5 CJK COMPATIBILITY IDEOGRAPH-F9F5 -// f9f6 CJK COMPATIBILITY IDEOGRAPH-F9F6 -// f9f7 CJK COMPATIBILITY IDEOGRAPH-F9F7 -// f9f8 CJK COMPATIBILITY IDEOGRAPH-F9F8 -// f9f9 CJK COMPATIBILITY IDEOGRAPH-F9F9 -// f9fa CJK COMPATIBILITY IDEOGRAPH-F9FA -// f9fb CJK COMPATIBILITY IDEOGRAPH-F9FB -// f9fc CJK COMPATIBILITY IDEOGRAPH-F9FC -// f9fd CJK COMPATIBILITY IDEOGRAPH-F9FD -// f9fe CJK COMPATIBILITY IDEOGRAPH-F9FE -// f9ff CJK COMPATIBILITY IDEOGRAPH-F9FF -// fa00 CJK COMPATIBILITY IDEOGRAPH-FA00 -// fa01 CJK COMPATIBILITY IDEOGRAPH-FA01 -// fa02 CJK COMPATIBILITY IDEOGRAPH-FA02 -// fa03 CJK COMPATIBILITY IDEOGRAPH-FA03 -// fa04 CJK COMPATIBILITY IDEOGRAPH-FA04 -// fa05 CJK COMPATIBILITY IDEOGRAPH-FA05 -// fa06 CJK COMPATIBILITY IDEOGRAPH-FA06 -// fa07 CJK COMPATIBILITY IDEOGRAPH-FA07 -// fa08 CJK COMPATIBILITY IDEOGRAPH-FA08 -// fa09 CJK COMPATIBILITY IDEOGRAPH-FA09 -// fa0a CJK COMPATIBILITY IDEOGRAPH-FA0A -// fa0b CJK COMPATIBILITY IDEOGRAPH-FA0B -// fa0c CJK COMPATIBILITY IDEOGRAPH-FA0C -// fa0d CJK COMPATIBILITY IDEOGRAPH-FA0D -// fa0e CJK COMPATIBILITY IDEOGRAPH-FA0E -// fa0f CJK COMPATIBILITY IDEOGRAPH-FA0F -// fa10 CJK COMPATIBILITY IDEOGRAPH-FA10 -// fa11 CJK COMPATIBILITY IDEOGRAPH-FA11 -// fa12 CJK COMPATIBILITY IDEOGRAPH-FA12 -// fa13 CJK COMPATIBILITY IDEOGRAPH-FA13 -// fa14 CJK COMPATIBILITY IDEOGRAPH-FA14 -// fa15 CJK COMPATIBILITY IDEOGRAPH-FA15 -// fa16 CJK COMPATIBILITY IDEOGRAPH-FA16 -// fa17 CJK COMPATIBILITY IDEOGRAPH-FA17 -// fa18 CJK COMPATIBILITY IDEOGRAPH-FA18 -// fa19 CJK COMPATIBILITY IDEOGRAPH-FA19 -// fa1a CJK COMPATIBILITY IDEOGRAPH-FA1A -// fa1b CJK COMPATIBILITY IDEOGRAPH-FA1B -// fa1c CJK COMPATIBILITY IDEOGRAPH-FA1C -// fa1d CJK COMPATIBILITY IDEOGRAPH-FA1D -// fa1e CJK COMPATIBILITY IDEOGRAPH-FA1E -// fa1f CJK COMPATIBILITY IDEOGRAPH-FA1F -// fa20 CJK COMPATIBILITY IDEOGRAPH-FA20 -// fa21 CJK COMPATIBILITY IDEOGRAPH-FA21 -// fa22 CJK COMPATIBILITY IDEOGRAPH-FA22 -// fa23 CJK COMPATIBILITY IDEOGRAPH-FA23 -// fa24 CJK COMPATIBILITY IDEOGRAPH-FA24 -// fa25 CJK COMPATIBILITY IDEOGRAPH-FA25 -// fa26 CJK COMPATIBILITY IDEOGRAPH-FA26 -// fa27 CJK COMPATIBILITY IDEOGRAPH-FA27 -// fa28 CJK COMPATIBILITY IDEOGRAPH-FA28 -// fa29 CJK COMPATIBILITY IDEOGRAPH-FA29 -// fa2a CJK COMPATIBILITY IDEOGRAPH-FA2A -// fa2b CJK COMPATIBILITY IDEOGRAPH-FA2B -// fa2c CJK COMPATIBILITY IDEOGRAPH-FA2C -// fa2d CJK COMPATIBILITY IDEOGRAPH-FA2D -// fa2e CJK COMPATIBILITY IDEOGRAPH-FA2E -// fa2f CJK COMPATIBILITY IDEOGRAPH-FA2F -// fa30 CJK COMPATIBILITY IDEOGRAPH-FA30 -// fa31 CJK COMPATIBILITY IDEOGRAPH-FA31 -// fa32 CJK COMPATIBILITY IDEOGRAPH-FA32 -// fa33 CJK COMPATIBILITY IDEOGRAPH-FA33 -// fa34 CJK COMPATIBILITY IDEOGRAPH-FA34 -// fa35 CJK COMPATIBILITY IDEOGRAPH-FA35 -// fa36 CJK COMPATIBILITY IDEOGRAPH-FA36 -// fa37 CJK COMPATIBILITY IDEOGRAPH-FA37 -// fa38 CJK COMPATIBILITY IDEOGRAPH-FA38 -// fa39 CJK COMPATIBILITY IDEOGRAPH-FA39 -// fa3a CJK COMPATIBILITY IDEOGRAPH-FA3A -// fa3b CJK COMPATIBILITY IDEOGRAPH-FA3B -// fa3c CJK COMPATIBILITY IDEOGRAPH-FA3C -// fa3d CJK COMPATIBILITY IDEOGRAPH-FA3D -// fa3e CJK COMPATIBILITY IDEOGRAPH-FA3E -// fa3f CJK COMPATIBILITY IDEOGRAPH-FA3F -// fa40 CJK COMPATIBILITY IDEOGRAPH-FA40 -// fa41 CJK COMPATIBILITY IDEOGRAPH-FA41 -// fa42 CJK COMPATIBILITY IDEOGRAPH-FA42 -// fa43 CJK COMPATIBILITY IDEOGRAPH-FA43 -// fa44 CJK COMPATIBILITY IDEOGRAPH-FA44 -// fa45 CJK COMPATIBILITY IDEOGRAPH-FA45 -// fa46 CJK COMPATIBILITY IDEOGRAPH-FA46 -// fa47 CJK COMPATIBILITY IDEOGRAPH-FA47 -// fa48 CJK COMPATIBILITY IDEOGRAPH-FA48 -// fa49 CJK COMPATIBILITY IDEOGRAPH-FA49 -// fa4a CJK COMPATIBILITY IDEOGRAPH-FA4A -// fa4b CJK COMPATIBILITY IDEOGRAPH-FA4B -// fa4c CJK COMPATIBILITY IDEOGRAPH-FA4C -// fa4d CJK COMPATIBILITY IDEOGRAPH-FA4D -// fa4e CJK COMPATIBILITY IDEOGRAPH-FA4E -// fa4f CJK COMPATIBILITY IDEOGRAPH-FA4F -// fa50 CJK COMPATIBILITY IDEOGRAPH-FA50 -// fa51 CJK COMPATIBILITY IDEOGRAPH-FA51 -// fa52 CJK COMPATIBILITY IDEOGRAPH-FA52 -// fa53 CJK COMPATIBILITY IDEOGRAPH-FA53 -// fa54 CJK COMPATIBILITY IDEOGRAPH-FA54 -// fa55 CJK COMPATIBILITY IDEOGRAPH-FA55 -// fa56 CJK COMPATIBILITY IDEOGRAPH-FA56 -// fa57 CJK COMPATIBILITY IDEOGRAPH-FA57 -// fa58 CJK COMPATIBILITY IDEOGRAPH-FA58 -// fa59 CJK COMPATIBILITY IDEOGRAPH-FA59 -// fa5a CJK COMPATIBILITY IDEOGRAPH-FA5A -// fa5b CJK COMPATIBILITY IDEOGRAPH-FA5B -// fa5c CJK COMPATIBILITY IDEOGRAPH-FA5C -// fa5d CJK COMPATIBILITY IDEOGRAPH-FA5D -// fa5e CJK COMPATIBILITY IDEOGRAPH-FA5E -// fa5f CJK COMPATIBILITY IDEOGRAPH-FA5F -// fa60 CJK COMPATIBILITY IDEOGRAPH-FA60 -// fa61 CJK COMPATIBILITY IDEOGRAPH-FA61 -// fa62 CJK COMPATIBILITY IDEOGRAPH-FA62 -// fa63 CJK COMPATIBILITY IDEOGRAPH-FA63 -// fa64 CJK COMPATIBILITY IDEOGRAPH-FA64 -// fa65 CJK COMPATIBILITY IDEOGRAPH-FA65 -// fa66 CJK COMPATIBILITY IDEOGRAPH-FA66 -// fa67 CJK COMPATIBILITY IDEOGRAPH-FA67 -// fa68 CJK COMPATIBILITY IDEOGRAPH-FA68 -// fa69 CJK COMPATIBILITY IDEOGRAPH-FA69 -// fa6a CJK COMPATIBILITY IDEOGRAPH-FA6A -// fa6b CJK COMPATIBILITY IDEOGRAPH-FA6B -// fa6c CJK COMPATIBILITY IDEOGRAPH-FA6C -// fa6d CJK COMPATIBILITY IDEOGRAPH-FA6D - { 0xF900, 0x16E, 0x9, 0, 0 }, -// fa70 CJK COMPATIBILITY IDEOGRAPH-FA70 -// fa71 CJK COMPATIBILITY IDEOGRAPH-FA71 -// fa72 CJK COMPATIBILITY IDEOGRAPH-FA72 -// fa73 CJK COMPATIBILITY IDEOGRAPH-FA73 -// fa74 CJK COMPATIBILITY IDEOGRAPH-FA74 -// fa75 CJK COMPATIBILITY IDEOGRAPH-FA75 -// fa76 CJK COMPATIBILITY IDEOGRAPH-FA76 -// fa77 CJK COMPATIBILITY IDEOGRAPH-FA77 -// fa78 CJK COMPATIBILITY IDEOGRAPH-FA78 -// fa79 CJK COMPATIBILITY IDEOGRAPH-FA79 -// fa7a CJK COMPATIBILITY IDEOGRAPH-FA7A -// fa7b CJK COMPATIBILITY IDEOGRAPH-FA7B -// fa7c CJK COMPATIBILITY IDEOGRAPH-FA7C -// fa7d CJK COMPATIBILITY IDEOGRAPH-FA7D -// fa7e CJK COMPATIBILITY IDEOGRAPH-FA7E -// fa7f CJK COMPATIBILITY IDEOGRAPH-FA7F -// fa80 CJK COMPATIBILITY IDEOGRAPH-FA80 -// fa81 CJK COMPATIBILITY IDEOGRAPH-FA81 -// fa82 CJK COMPATIBILITY IDEOGRAPH-FA82 -// fa83 CJK COMPATIBILITY IDEOGRAPH-FA83 -// fa84 CJK COMPATIBILITY IDEOGRAPH-FA84 -// fa85 CJK COMPATIBILITY IDEOGRAPH-FA85 -// fa86 CJK COMPATIBILITY IDEOGRAPH-FA86 -// fa87 CJK COMPATIBILITY IDEOGRAPH-FA87 -// fa88 CJK COMPATIBILITY IDEOGRAPH-FA88 -// fa89 CJK COMPATIBILITY IDEOGRAPH-FA89 -// fa8a CJK COMPATIBILITY IDEOGRAPH-FA8A -// fa8b CJK COMPATIBILITY IDEOGRAPH-FA8B -// fa8c CJK COMPATIBILITY IDEOGRAPH-FA8C -// fa8d CJK COMPATIBILITY IDEOGRAPH-FA8D -// fa8e CJK COMPATIBILITY IDEOGRAPH-FA8E -// fa8f CJK COMPATIBILITY IDEOGRAPH-FA8F -// fa90 CJK COMPATIBILITY IDEOGRAPH-FA90 -// fa91 CJK COMPATIBILITY IDEOGRAPH-FA91 -// fa92 CJK COMPATIBILITY IDEOGRAPH-FA92 -// fa93 CJK COMPATIBILITY IDEOGRAPH-FA93 -// fa94 CJK COMPATIBILITY IDEOGRAPH-FA94 -// fa95 CJK COMPATIBILITY IDEOGRAPH-FA95 -// fa96 CJK COMPATIBILITY IDEOGRAPH-FA96 -// fa97 CJK COMPATIBILITY IDEOGRAPH-FA97 -// fa98 CJK COMPATIBILITY IDEOGRAPH-FA98 -// fa99 CJK COMPATIBILITY IDEOGRAPH-FA99 -// fa9a CJK COMPATIBILITY IDEOGRAPH-FA9A -// fa9b CJK COMPATIBILITY IDEOGRAPH-FA9B -// fa9c CJK COMPATIBILITY IDEOGRAPH-FA9C -// fa9d CJK COMPATIBILITY IDEOGRAPH-FA9D -// fa9e CJK COMPATIBILITY IDEOGRAPH-FA9E -// fa9f CJK COMPATIBILITY IDEOGRAPH-FA9F -// faa0 CJK COMPATIBILITY IDEOGRAPH-FAA0 -// faa1 CJK COMPATIBILITY IDEOGRAPH-FAA1 -// faa2 CJK COMPATIBILITY IDEOGRAPH-FAA2 -// faa3 CJK COMPATIBILITY IDEOGRAPH-FAA3 -// faa4 CJK COMPATIBILITY IDEOGRAPH-FAA4 -// faa5 CJK COMPATIBILITY IDEOGRAPH-FAA5 -// faa6 CJK COMPATIBILITY IDEOGRAPH-FAA6 -// faa7 CJK COMPATIBILITY IDEOGRAPH-FAA7 -// faa8 CJK COMPATIBILITY IDEOGRAPH-FAA8 -// faa9 CJK COMPATIBILITY IDEOGRAPH-FAA9 -// faaa CJK COMPATIBILITY IDEOGRAPH-FAAA -// faab CJK COMPATIBILITY IDEOGRAPH-FAAB -// faac CJK COMPATIBILITY IDEOGRAPH-FAAC -// faad CJK COMPATIBILITY IDEOGRAPH-FAAD -// faae CJK COMPATIBILITY IDEOGRAPH-FAAE -// faaf CJK COMPATIBILITY IDEOGRAPH-FAAF -// fab0 CJK COMPATIBILITY IDEOGRAPH-FAB0 -// fab1 CJK COMPATIBILITY IDEOGRAPH-FAB1 -// fab2 CJK COMPATIBILITY IDEOGRAPH-FAB2 -// fab3 CJK COMPATIBILITY IDEOGRAPH-FAB3 -// fab4 CJK COMPATIBILITY IDEOGRAPH-FAB4 -// fab5 CJK COMPATIBILITY IDEOGRAPH-FAB5 -// fab6 CJK COMPATIBILITY IDEOGRAPH-FAB6 -// fab7 CJK COMPATIBILITY IDEOGRAPH-FAB7 -// fab8 CJK COMPATIBILITY IDEOGRAPH-FAB8 -// fab9 CJK COMPATIBILITY IDEOGRAPH-FAB9 -// faba CJK COMPATIBILITY IDEOGRAPH-FABA -// fabb CJK COMPATIBILITY IDEOGRAPH-FABB -// fabc CJK COMPATIBILITY IDEOGRAPH-FABC -// fabd CJK COMPATIBILITY IDEOGRAPH-FABD -// fabe CJK COMPATIBILITY IDEOGRAPH-FABE -// fabf CJK COMPATIBILITY IDEOGRAPH-FABF -// fac0 CJK COMPATIBILITY IDEOGRAPH-FAC0 -// fac1 CJK COMPATIBILITY IDEOGRAPH-FAC1 -// fac2 CJK COMPATIBILITY IDEOGRAPH-FAC2 -// fac3 CJK COMPATIBILITY IDEOGRAPH-FAC3 -// fac4 CJK COMPATIBILITY IDEOGRAPH-FAC4 -// fac5 CJK COMPATIBILITY IDEOGRAPH-FAC5 -// fac6 CJK COMPATIBILITY IDEOGRAPH-FAC6 -// fac7 CJK COMPATIBILITY IDEOGRAPH-FAC7 -// fac8 CJK COMPATIBILITY IDEOGRAPH-FAC8 -// fac9 CJK COMPATIBILITY IDEOGRAPH-FAC9 -// faca CJK COMPATIBILITY IDEOGRAPH-FACA -// facb CJK COMPATIBILITY IDEOGRAPH-FACB -// facc CJK COMPATIBILITY IDEOGRAPH-FACC -// facd CJK COMPATIBILITY IDEOGRAPH-FACD -// face CJK COMPATIBILITY IDEOGRAPH-FACE -// facf CJK COMPATIBILITY IDEOGRAPH-FACF -// fad0 CJK COMPATIBILITY IDEOGRAPH-FAD0 -// fad1 CJK COMPATIBILITY IDEOGRAPH-FAD1 -// fad2 CJK COMPATIBILITY IDEOGRAPH-FAD2 -// fad3 CJK COMPATIBILITY IDEOGRAPH-FAD3 -// fad4 CJK COMPATIBILITY IDEOGRAPH-FAD4 -// fad5 CJK COMPATIBILITY IDEOGRAPH-FAD5 -// fad6 CJK COMPATIBILITY IDEOGRAPH-FAD6 -// fad7 CJK COMPATIBILITY IDEOGRAPH-FAD7 -// fad8 CJK COMPATIBILITY IDEOGRAPH-FAD8 -// fad9 CJK COMPATIBILITY IDEOGRAPH-FAD9 - { 0xFA70, 0x6A, 0x9, 0, 0 }, -// fb00 LATIN SMALL LIGATURE FF -// fb01 LATIN SMALL LIGATURE FI -// fb02 LATIN SMALL LIGATURE FL -// fb03 LATIN SMALL LIGATURE FFI -// fb04 LATIN SMALL LIGATURE FFL -// fb05 LATIN SMALL LIGATURE LONG S T -// fb06 LATIN SMALL LIGATURE ST - { 0xFB00, 0x7, 0x49, 0, 0 }, -// fb13 ARMENIAN SMALL LIGATURE MEN NOW -// fb14 ARMENIAN SMALL LIGATURE MEN ECH -// fb15 ARMENIAN SMALL LIGATURE MEN INI -// fb16 ARMENIAN SMALL LIGATURE VEW NOW -// fb17 ARMENIAN SMALL LIGATURE MEN XEH - { 0xFB13, 0x5, 0x49, 0, 0 }, -// fb1d HEBREW LETTER YOD WITH HIRIQ - { 0xFB1D, 0x1, 0x9, 0, 0 }, -// fb1e HEBREW POINT JUDEO-SPANISH VARIKA - { 0xFB1E, 0x1, 0x0, 0, 0 }, -// fb1f HEBREW LIGATURE YIDDISH YOD YOD PATAH -// fb20 HEBREW LETTER ALTERNATIVE AYIN -// fb21 HEBREW LETTER WIDE ALEF -// fb22 HEBREW LETTER WIDE DALET -// fb23 HEBREW LETTER WIDE HE -// fb24 HEBREW LETTER WIDE KAF -// fb25 HEBREW LETTER WIDE LAMED -// fb26 HEBREW LETTER WIDE FINAL MEM -// fb27 HEBREW LETTER WIDE RESH -// fb28 HEBREW LETTER WIDE TAV - { 0xFB1F, 0xA, 0x9, 0, 0 }, -// fb29 HEBREW LETTER ALTERNATIVE PLUS SIGN - { 0xFB29, 0x1, 0x8, 0, 0 }, -// fb2a HEBREW LETTER SHIN WITH SHIN DOT -// fb2b HEBREW LETTER SHIN WITH SIN DOT -// fb2c HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT -// fb2d HEBREW LETTER SHIN WITH DAGESH AND SIN DOT -// fb2e HEBREW LETTER ALEF WITH PATAH -// fb2f HEBREW LETTER ALEF WITH QAMATS -// fb30 HEBREW LETTER ALEF WITH MAPIQ -// fb31 HEBREW LETTER BET WITH DAGESH -// fb32 HEBREW LETTER GIMEL WITH DAGESH -// fb33 HEBREW LETTER DALET WITH DAGESH -// fb34 HEBREW LETTER HE WITH MAPIQ -// fb35 HEBREW LETTER VAV WITH DAGESH -// fb36 HEBREW LETTER ZAYIN WITH DAGESH - { 0xFB2A, 0xD, 0x9, 0, 0 }, -// fb38 HEBREW LETTER TET WITH DAGESH -// fb39 HEBREW LETTER YOD WITH DAGESH -// fb3a HEBREW LETTER FINAL KAF WITH DAGESH -// fb3b HEBREW LETTER KAF WITH DAGESH -// fb3c HEBREW LETTER LAMED WITH DAGESH - { 0xFB38, 0x5, 0x9, 0, 0 }, -// fb3e HEBREW LETTER MEM WITH DAGESH - { 0xFB3E, 0x1, 0x9, 0, 0 }, -// fb40 HEBREW LETTER NUN WITH DAGESH -// fb41 HEBREW LETTER SAMEKH WITH DAGESH - { 0xFB40, 0x2, 0x9, 0, 0 }, -// fb43 HEBREW LETTER FINAL PE WITH DAGESH -// fb44 HEBREW LETTER PE WITH DAGESH - { 0xFB43, 0x2, 0x9, 0, 0 }, -// fb46 HEBREW LETTER TSADI WITH DAGESH -// fb47 HEBREW LETTER QOF WITH DAGESH -// fb48 HEBREW LETTER RESH WITH DAGESH -// fb49 HEBREW LETTER SHIN WITH DAGESH -// fb4a HEBREW LETTER TAV WITH DAGESH -// fb4b HEBREW LETTER VAV WITH HOLAM -// fb4c HEBREW LETTER BET WITH RAFE -// fb4d HEBREW LETTER KAF WITH RAFE -// fb4e HEBREW LETTER PE WITH RAFE -// fb4f HEBREW LIGATURE ALEF LAMED -// fb50 ARABIC LETTER ALEF WASLA ISOLATED FORM -// fb51 ARABIC LETTER ALEF WASLA FINAL FORM -// fb52 ARABIC LETTER BEEH ISOLATED FORM -// fb53 ARABIC LETTER BEEH FINAL FORM -// fb54 ARABIC LETTER BEEH INITIAL FORM -// fb55 ARABIC LETTER BEEH MEDIAL FORM -// fb56 ARABIC LETTER PEH ISOLATED FORM -// fb57 ARABIC LETTER PEH FINAL FORM -// fb58 ARABIC LETTER PEH INITIAL FORM -// fb59 ARABIC LETTER PEH MEDIAL FORM -// fb5a ARABIC LETTER BEHEH ISOLATED FORM -// fb5b ARABIC LETTER BEHEH FINAL FORM -// fb5c ARABIC LETTER BEHEH INITIAL FORM -// fb5d ARABIC LETTER BEHEH MEDIAL FORM -// fb5e ARABIC LETTER TTEHEH ISOLATED FORM -// fb5f ARABIC LETTER TTEHEH FINAL FORM -// fb60 ARABIC LETTER TTEHEH INITIAL FORM -// fb61 ARABIC LETTER TTEHEH MEDIAL FORM -// fb62 ARABIC LETTER TEHEH ISOLATED FORM -// fb63 ARABIC LETTER TEHEH FINAL FORM -// fb64 ARABIC LETTER TEHEH INITIAL FORM -// fb65 ARABIC LETTER TEHEH MEDIAL FORM -// fb66 ARABIC LETTER TTEH ISOLATED FORM -// fb67 ARABIC LETTER TTEH FINAL FORM -// fb68 ARABIC LETTER TTEH INITIAL FORM -// fb69 ARABIC LETTER TTEH MEDIAL FORM -// fb6a ARABIC LETTER VEH ISOLATED FORM -// fb6b ARABIC LETTER VEH FINAL FORM -// fb6c ARABIC LETTER VEH INITIAL FORM -// fb6d ARABIC LETTER VEH MEDIAL FORM -// fb6e ARABIC LETTER PEHEH ISOLATED FORM -// fb6f ARABIC LETTER PEHEH FINAL FORM -// fb70 ARABIC LETTER PEHEH INITIAL FORM -// fb71 ARABIC LETTER PEHEH MEDIAL FORM -// fb72 ARABIC LETTER DYEH ISOLATED FORM -// fb73 ARABIC LETTER DYEH FINAL FORM -// fb74 ARABIC LETTER DYEH INITIAL FORM -// fb75 ARABIC LETTER DYEH MEDIAL FORM -// fb76 ARABIC LETTER NYEH ISOLATED FORM -// fb77 ARABIC LETTER NYEH FINAL FORM -// fb78 ARABIC LETTER NYEH INITIAL FORM -// fb79 ARABIC LETTER NYEH MEDIAL FORM -// fb7a ARABIC LETTER TCHEH ISOLATED FORM -// fb7b ARABIC LETTER TCHEH FINAL FORM -// fb7c ARABIC LETTER TCHEH INITIAL FORM -// fb7d ARABIC LETTER TCHEH MEDIAL FORM -// fb7e ARABIC LETTER TCHEHEH ISOLATED FORM -// fb7f ARABIC LETTER TCHEHEH FINAL FORM -// fb80 ARABIC LETTER TCHEHEH INITIAL FORM -// fb81 ARABIC LETTER TCHEHEH MEDIAL FORM -// fb82 ARABIC LETTER DDAHAL ISOLATED FORM -// fb83 ARABIC LETTER DDAHAL FINAL FORM -// fb84 ARABIC LETTER DAHAL ISOLATED FORM -// fb85 ARABIC LETTER DAHAL FINAL FORM -// fb86 ARABIC LETTER DUL ISOLATED FORM -// fb87 ARABIC LETTER DUL FINAL FORM -// fb88 ARABIC LETTER DDAL ISOLATED FORM -// fb89 ARABIC LETTER DDAL FINAL FORM -// fb8a ARABIC LETTER JEH ISOLATED FORM -// fb8b ARABIC LETTER JEH FINAL FORM -// fb8c ARABIC LETTER RREH ISOLATED FORM -// fb8d ARABIC LETTER RREH FINAL FORM -// fb8e ARABIC LETTER KEHEH ISOLATED FORM -// fb8f ARABIC LETTER KEHEH FINAL FORM -// fb90 ARABIC LETTER KEHEH INITIAL FORM -// fb91 ARABIC LETTER KEHEH MEDIAL FORM -// fb92 ARABIC LETTER GAF ISOLATED FORM -// fb93 ARABIC LETTER GAF FINAL FORM -// fb94 ARABIC LETTER GAF INITIAL FORM -// fb95 ARABIC LETTER GAF MEDIAL FORM -// fb96 ARABIC LETTER GUEH ISOLATED FORM -// fb97 ARABIC LETTER GUEH FINAL FORM -// fb98 ARABIC LETTER GUEH INITIAL FORM -// fb99 ARABIC LETTER GUEH MEDIAL FORM -// fb9a ARABIC LETTER NGOEH ISOLATED FORM -// fb9b ARABIC LETTER NGOEH FINAL FORM -// fb9c ARABIC LETTER NGOEH INITIAL FORM -// fb9d ARABIC LETTER NGOEH MEDIAL FORM -// fb9e ARABIC LETTER NOON GHUNNA ISOLATED FORM -// fb9f ARABIC LETTER NOON GHUNNA FINAL FORM -// fba0 ARABIC LETTER RNOON ISOLATED FORM -// fba1 ARABIC LETTER RNOON FINAL FORM -// fba2 ARABIC LETTER RNOON INITIAL FORM -// fba3 ARABIC LETTER RNOON MEDIAL FORM -// fba4 ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM -// fba5 ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM -// fba6 ARABIC LETTER HEH GOAL ISOLATED FORM -// fba7 ARABIC LETTER HEH GOAL FINAL FORM -// fba8 ARABIC LETTER HEH GOAL INITIAL FORM -// fba9 ARABIC LETTER HEH GOAL MEDIAL FORM -// fbaa ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM -// fbab ARABIC LETTER HEH DOACHASHMEE FINAL FORM -// fbac ARABIC LETTER HEH DOACHASHMEE INITIAL FORM -// fbad ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM -// fbae ARABIC LETTER YEH BARREE ISOLATED FORM -// fbaf ARABIC LETTER YEH BARREE FINAL FORM -// fbb0 ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM -// fbb1 ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM - { 0xFB46, 0x6C, 0x9, 0, 0 }, -// fbb2 ARABIC SYMBOL DOT ABOVE -// fbb3 ARABIC SYMBOL DOT BELOW -// fbb4 ARABIC SYMBOL TWO DOTS ABOVE -// fbb5 ARABIC SYMBOL TWO DOTS BELOW -// fbb6 ARABIC SYMBOL THREE DOTS ABOVE -// fbb7 ARABIC SYMBOL THREE DOTS BELOW -// fbb8 ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS ABOVE -// fbb9 ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS BELOW -// fbba ARABIC SYMBOL FOUR DOTS ABOVE -// fbbb ARABIC SYMBOL FOUR DOTS BELOW -// fbbc ARABIC SYMBOL DOUBLE VERTICAL BAR BELOW -// fbbd ARABIC SYMBOL TWO DOTS VERTICALLY ABOVE -// fbbe ARABIC SYMBOL TWO DOTS VERTICALLY BELOW -// fbbf ARABIC SYMBOL RING -// fbc0 ARABIC SYMBOL SMALL TAH ABOVE -// fbc1 ARABIC SYMBOL SMALL TAH BELOW - { 0xFBB2, 0x10, 0x8, 0, 0 }, -// fbd3 ARABIC LETTER NG ISOLATED FORM -// fbd4 ARABIC LETTER NG FINAL FORM -// fbd5 ARABIC LETTER NG INITIAL FORM -// fbd6 ARABIC LETTER NG MEDIAL FORM -// fbd7 ARABIC LETTER U ISOLATED FORM -// fbd8 ARABIC LETTER U FINAL FORM -// fbd9 ARABIC LETTER OE ISOLATED FORM -// fbda ARABIC LETTER OE FINAL FORM -// fbdb ARABIC LETTER YU ISOLATED FORM -// fbdc ARABIC LETTER YU FINAL FORM -// fbdd ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM -// fbde ARABIC LETTER VE ISOLATED FORM -// fbdf ARABIC LETTER VE FINAL FORM -// fbe0 ARABIC LETTER KIRGHIZ OE ISOLATED FORM -// fbe1 ARABIC LETTER KIRGHIZ OE FINAL FORM -// fbe2 ARABIC LETTER KIRGHIZ YU ISOLATED FORM -// fbe3 ARABIC LETTER KIRGHIZ YU FINAL FORM -// fbe4 ARABIC LETTER E ISOLATED FORM -// fbe5 ARABIC LETTER E FINAL FORM -// fbe6 ARABIC LETTER E INITIAL FORM -// fbe7 ARABIC LETTER E MEDIAL FORM -// fbe8 ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM -// fbe9 ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM -// fbea ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM -// fbeb ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM -// fbec ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM -// fbed ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM -// fbee ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM -// fbef ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM -// fbf0 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM -// fbf1 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM -// fbf2 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM -// fbf3 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM -// fbf4 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM -// fbf5 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM -// fbf6 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM -// fbf7 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM -// fbf8 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM -// fbf9 ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM -// fbfa ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM -// fbfb ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM -// fbfc ARABIC LETTER FARSI YEH ISOLATED FORM -// fbfd ARABIC LETTER FARSI YEH FINAL FORM -// fbfe ARABIC LETTER FARSI YEH INITIAL FORM -// fbff ARABIC LETTER FARSI YEH MEDIAL FORM -// fc00 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM -// fc01 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM -// fc02 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM -// fc03 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM -// fc04 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM -// fc05 ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM -// fc06 ARABIC LIGATURE BEH WITH HAH ISOLATED FORM -// fc07 ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM -// fc08 ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM -// fc09 ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM -// fc0a ARABIC LIGATURE BEH WITH YEH ISOLATED FORM -// fc0b ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM -// fc0c ARABIC LIGATURE TEH WITH HAH ISOLATED FORM -// fc0d ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM -// fc0e ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM -// fc0f ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM -// fc10 ARABIC LIGATURE TEH WITH YEH ISOLATED FORM -// fc11 ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM -// fc12 ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM -// fc13 ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM -// fc14 ARABIC LIGATURE THEH WITH YEH ISOLATED FORM -// fc15 ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM -// fc16 ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM -// fc17 ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM -// fc18 ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM -// fc19 ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM -// fc1a ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM -// fc1b ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM -// fc1c ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM -// fc1d ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM -// fc1e ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM -// fc1f ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM -// fc20 ARABIC LIGATURE SAD WITH HAH ISOLATED FORM -// fc21 ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM -// fc22 ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM -// fc23 ARABIC LIGATURE DAD WITH HAH ISOLATED FORM -// fc24 ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM -// fc25 ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM -// fc26 ARABIC LIGATURE TAH WITH HAH ISOLATED FORM -// fc27 ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM -// fc28 ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM -// fc29 ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM -// fc2a ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM -// fc2b ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM -// fc2c ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM -// fc2d ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM -// fc2e ARABIC LIGATURE FEH WITH HAH ISOLATED FORM -// fc2f ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM -// fc30 ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM -// fc31 ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM -// fc32 ARABIC LIGATURE FEH WITH YEH ISOLATED FORM -// fc33 ARABIC LIGATURE QAF WITH HAH ISOLATED FORM -// fc34 ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM -// fc35 ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM -// fc36 ARABIC LIGATURE QAF WITH YEH ISOLATED FORM -// fc37 ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM -// fc38 ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM -// fc39 ARABIC LIGATURE KAF WITH HAH ISOLATED FORM -// fc3a ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM -// fc3b ARABIC LIGATURE KAF WITH LAM ISOLATED FORM -// fc3c ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM -// fc3d ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM -// fc3e ARABIC LIGATURE KAF WITH YEH ISOLATED FORM -// fc3f ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM -// fc40 ARABIC LIGATURE LAM WITH HAH ISOLATED FORM -// fc41 ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM -// fc42 ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM -// fc43 ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM -// fc44 ARABIC LIGATURE LAM WITH YEH ISOLATED FORM -// fc45 ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM -// fc46 ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM -// fc47 ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM -// fc48 ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM -// fc49 ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM -// fc4a ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM -// fc4b ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM -// fc4c ARABIC LIGATURE NOON WITH HAH ISOLATED FORM -// fc4d ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM -// fc4e ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM -// fc4f ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM -// fc50 ARABIC LIGATURE NOON WITH YEH ISOLATED FORM -// fc51 ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM -// fc52 ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM -// fc53 ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM -// fc54 ARABIC LIGATURE HEH WITH YEH ISOLATED FORM -// fc55 ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM -// fc56 ARABIC LIGATURE YEH WITH HAH ISOLATED FORM -// fc57 ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM -// fc58 ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM -// fc59 ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM -// fc5a ARABIC LIGATURE YEH WITH YEH ISOLATED FORM -// fc5b ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM -// fc5c ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM -// fc5d ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM -// fc5e ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM -// fc5f ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM -// fc60 ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM -// fc61 ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM -// fc62 ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM -// fc63 ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM -// fc64 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM -// fc65 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM -// fc66 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM -// fc67 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM -// fc68 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM -// fc69 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM -// fc6a ARABIC LIGATURE BEH WITH REH FINAL FORM -// fc6b ARABIC LIGATURE BEH WITH ZAIN FINAL FORM -// fc6c ARABIC LIGATURE BEH WITH MEEM FINAL FORM -// fc6d ARABIC LIGATURE BEH WITH NOON FINAL FORM -// fc6e ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM -// fc6f ARABIC LIGATURE BEH WITH YEH FINAL FORM -// fc70 ARABIC LIGATURE TEH WITH REH FINAL FORM -// fc71 ARABIC LIGATURE TEH WITH ZAIN FINAL FORM -// fc72 ARABIC LIGATURE TEH WITH MEEM FINAL FORM -// fc73 ARABIC LIGATURE TEH WITH NOON FINAL FORM -// fc74 ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM -// fc75 ARABIC LIGATURE TEH WITH YEH FINAL FORM -// fc76 ARABIC LIGATURE THEH WITH REH FINAL FORM -// fc77 ARABIC LIGATURE THEH WITH ZAIN FINAL FORM -// fc78 ARABIC LIGATURE THEH WITH MEEM FINAL FORM -// fc79 ARABIC LIGATURE THEH WITH NOON FINAL FORM -// fc7a ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM -// fc7b ARABIC LIGATURE THEH WITH YEH FINAL FORM -// fc7c ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM -// fc7d ARABIC LIGATURE FEH WITH YEH FINAL FORM -// fc7e ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM -// fc7f ARABIC LIGATURE QAF WITH YEH FINAL FORM -// fc80 ARABIC LIGATURE KAF WITH ALEF FINAL FORM -// fc81 ARABIC LIGATURE KAF WITH LAM FINAL FORM -// fc82 ARABIC LIGATURE KAF WITH MEEM FINAL FORM -// fc83 ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM -// fc84 ARABIC LIGATURE KAF WITH YEH FINAL FORM -// fc85 ARABIC LIGATURE LAM WITH MEEM FINAL FORM -// fc86 ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM -// fc87 ARABIC LIGATURE LAM WITH YEH FINAL FORM -// fc88 ARABIC LIGATURE MEEM WITH ALEF FINAL FORM -// fc89 ARABIC LIGATURE MEEM WITH MEEM FINAL FORM -// fc8a ARABIC LIGATURE NOON WITH REH FINAL FORM -// fc8b ARABIC LIGATURE NOON WITH ZAIN FINAL FORM -// fc8c ARABIC LIGATURE NOON WITH MEEM FINAL FORM -// fc8d ARABIC LIGATURE NOON WITH NOON FINAL FORM -// fc8e ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM -// fc8f ARABIC LIGATURE NOON WITH YEH FINAL FORM -// fc90 ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM -// fc91 ARABIC LIGATURE YEH WITH REH FINAL FORM -// fc92 ARABIC LIGATURE YEH WITH ZAIN FINAL FORM -// fc93 ARABIC LIGATURE YEH WITH MEEM FINAL FORM -// fc94 ARABIC LIGATURE YEH WITH NOON FINAL FORM -// fc95 ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM -// fc96 ARABIC LIGATURE YEH WITH YEH FINAL FORM -// fc97 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM -// fc98 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM -// fc99 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM -// fc9a ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM -// fc9b ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM -// fc9c ARABIC LIGATURE BEH WITH JEEM INITIAL FORM -// fc9d ARABIC LIGATURE BEH WITH HAH INITIAL FORM -// fc9e ARABIC LIGATURE BEH WITH KHAH INITIAL FORM -// fc9f ARABIC LIGATURE BEH WITH MEEM INITIAL FORM -// fca0 ARABIC LIGATURE BEH WITH HEH INITIAL FORM -// fca1 ARABIC LIGATURE TEH WITH JEEM INITIAL FORM -// fca2 ARABIC LIGATURE TEH WITH HAH INITIAL FORM -// fca3 ARABIC LIGATURE TEH WITH KHAH INITIAL FORM -// fca4 ARABIC LIGATURE TEH WITH MEEM INITIAL FORM -// fca5 ARABIC LIGATURE TEH WITH HEH INITIAL FORM -// fca6 ARABIC LIGATURE THEH WITH MEEM INITIAL FORM -// fca7 ARABIC LIGATURE JEEM WITH HAH INITIAL FORM -// fca8 ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM -// fca9 ARABIC LIGATURE HAH WITH JEEM INITIAL FORM -// fcaa ARABIC LIGATURE HAH WITH MEEM INITIAL FORM -// fcab ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM -// fcac ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM -// fcad ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM -// fcae ARABIC LIGATURE SEEN WITH HAH INITIAL FORM -// fcaf ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM -// fcb0 ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM -// fcb1 ARABIC LIGATURE SAD WITH HAH INITIAL FORM -// fcb2 ARABIC LIGATURE SAD WITH KHAH INITIAL FORM -// fcb3 ARABIC LIGATURE SAD WITH MEEM INITIAL FORM -// fcb4 ARABIC LIGATURE DAD WITH JEEM INITIAL FORM -// fcb5 ARABIC LIGATURE DAD WITH HAH INITIAL FORM -// fcb6 ARABIC LIGATURE DAD WITH KHAH INITIAL FORM -// fcb7 ARABIC LIGATURE DAD WITH MEEM INITIAL FORM -// fcb8 ARABIC LIGATURE TAH WITH HAH INITIAL FORM -// fcb9 ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM -// fcba ARABIC LIGATURE AIN WITH JEEM INITIAL FORM -// fcbb ARABIC LIGATURE AIN WITH MEEM INITIAL FORM -// fcbc ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM -// fcbd ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM -// fcbe ARABIC LIGATURE FEH WITH JEEM INITIAL FORM -// fcbf ARABIC LIGATURE FEH WITH HAH INITIAL FORM -// fcc0 ARABIC LIGATURE FEH WITH KHAH INITIAL FORM -// fcc1 ARABIC LIGATURE FEH WITH MEEM INITIAL FORM -// fcc2 ARABIC LIGATURE QAF WITH HAH INITIAL FORM -// fcc3 ARABIC LIGATURE QAF WITH MEEM INITIAL FORM -// fcc4 ARABIC LIGATURE KAF WITH JEEM INITIAL FORM -// fcc5 ARABIC LIGATURE KAF WITH HAH INITIAL FORM -// fcc6 ARABIC LIGATURE KAF WITH KHAH INITIAL FORM -// fcc7 ARABIC LIGATURE KAF WITH LAM INITIAL FORM -// fcc8 ARABIC LIGATURE KAF WITH MEEM INITIAL FORM -// fcc9 ARABIC LIGATURE LAM WITH JEEM INITIAL FORM -// fcca ARABIC LIGATURE LAM WITH HAH INITIAL FORM -// fccb ARABIC LIGATURE LAM WITH KHAH INITIAL FORM -// fccc ARABIC LIGATURE LAM WITH MEEM INITIAL FORM -// fccd ARABIC LIGATURE LAM WITH HEH INITIAL FORM -// fcce ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM -// fccf ARABIC LIGATURE MEEM WITH HAH INITIAL FORM -// fcd0 ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM -// fcd1 ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM -// fcd2 ARABIC LIGATURE NOON WITH JEEM INITIAL FORM -// fcd3 ARABIC LIGATURE NOON WITH HAH INITIAL FORM -// fcd4 ARABIC LIGATURE NOON WITH KHAH INITIAL FORM -// fcd5 ARABIC LIGATURE NOON WITH MEEM INITIAL FORM -// fcd6 ARABIC LIGATURE NOON WITH HEH INITIAL FORM -// fcd7 ARABIC LIGATURE HEH WITH JEEM INITIAL FORM -// fcd8 ARABIC LIGATURE HEH WITH MEEM INITIAL FORM -// fcd9 ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM -// fcda ARABIC LIGATURE YEH WITH JEEM INITIAL FORM -// fcdb ARABIC LIGATURE YEH WITH HAH INITIAL FORM -// fcdc ARABIC LIGATURE YEH WITH KHAH INITIAL FORM -// fcdd ARABIC LIGATURE YEH WITH MEEM INITIAL FORM -// fcde ARABIC LIGATURE YEH WITH HEH INITIAL FORM -// fcdf ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM -// fce0 ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM -// fce1 ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM -// fce2 ARABIC LIGATURE BEH WITH HEH MEDIAL FORM -// fce3 ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM -// fce4 ARABIC LIGATURE TEH WITH HEH MEDIAL FORM -// fce5 ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM -// fce6 ARABIC LIGATURE THEH WITH HEH MEDIAL FORM -// fce7 ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM -// fce8 ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM -// fce9 ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM -// fcea ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM -// fceb ARABIC LIGATURE KAF WITH LAM MEDIAL FORM -// fcec ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM -// fced ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM -// fcee ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM -// fcef ARABIC LIGATURE NOON WITH HEH MEDIAL FORM -// fcf0 ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM -// fcf1 ARABIC LIGATURE YEH WITH HEH MEDIAL FORM -// fcf2 ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM -// fcf3 ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM -// fcf4 ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM -// fcf5 ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM -// fcf6 ARABIC LIGATURE TAH WITH YEH ISOLATED FORM -// fcf7 ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM -// fcf8 ARABIC LIGATURE AIN WITH YEH ISOLATED FORM -// fcf9 ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM -// fcfa ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM -// fcfb ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM -// fcfc ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM -// fcfd ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM -// fcfe ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM -// fcff ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM -// fd00 ARABIC LIGATURE HAH WITH YEH ISOLATED FORM -// fd01 ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM -// fd02 ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM -// fd03 ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM -// fd04 ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM -// fd05 ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM -// fd06 ARABIC LIGATURE SAD WITH YEH ISOLATED FORM -// fd07 ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM -// fd08 ARABIC LIGATURE DAD WITH YEH ISOLATED FORM -// fd09 ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM -// fd0a ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM -// fd0b ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM -// fd0c ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM -// fd0d ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM -// fd0e ARABIC LIGATURE SEEN WITH REH ISOLATED FORM -// fd0f ARABIC LIGATURE SAD WITH REH ISOLATED FORM -// fd10 ARABIC LIGATURE DAD WITH REH ISOLATED FORM -// fd11 ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM -// fd12 ARABIC LIGATURE TAH WITH YEH FINAL FORM -// fd13 ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM -// fd14 ARABIC LIGATURE AIN WITH YEH FINAL FORM -// fd15 ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM -// fd16 ARABIC LIGATURE GHAIN WITH YEH FINAL FORM -// fd17 ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM -// fd18 ARABIC LIGATURE SEEN WITH YEH FINAL FORM -// fd19 ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM -// fd1a ARABIC LIGATURE SHEEN WITH YEH FINAL FORM -// fd1b ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM -// fd1c ARABIC LIGATURE HAH WITH YEH FINAL FORM -// fd1d ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM -// fd1e ARABIC LIGATURE JEEM WITH YEH FINAL FORM -// fd1f ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM -// fd20 ARABIC LIGATURE KHAH WITH YEH FINAL FORM -// fd21 ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM -// fd22 ARABIC LIGATURE SAD WITH YEH FINAL FORM -// fd23 ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM -// fd24 ARABIC LIGATURE DAD WITH YEH FINAL FORM -// fd25 ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM -// fd26 ARABIC LIGATURE SHEEN WITH HAH FINAL FORM -// fd27 ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM -// fd28 ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM -// fd29 ARABIC LIGATURE SHEEN WITH REH FINAL FORM -// fd2a ARABIC LIGATURE SEEN WITH REH FINAL FORM -// fd2b ARABIC LIGATURE SAD WITH REH FINAL FORM -// fd2c ARABIC LIGATURE DAD WITH REH FINAL FORM -// fd2d ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM -// fd2e ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM -// fd2f ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM -// fd30 ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM -// fd31 ARABIC LIGATURE SEEN WITH HEH INITIAL FORM -// fd32 ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM -// fd33 ARABIC LIGATURE TAH WITH MEEM INITIAL FORM -// fd34 ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM -// fd35 ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM -// fd36 ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM -// fd37 ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM -// fd38 ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM -// fd39 ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM -// fd3a ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM -// fd3b ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM -// fd3c ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM -// fd3d ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM - { 0xFBD3, 0x16B, 0x9, 0, 0 }, -// fd3e ORNATE LEFT PARENTHESIS -// fd3f ORNATE RIGHT PARENTHESIS - { 0xFD3E, 0x2, 0x18, 0, 0 }, -// fd50 ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM -// fd51 ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM -// fd52 ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM -// fd53 ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM -// fd54 ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM -// fd55 ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM -// fd56 ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM -// fd57 ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM -// fd58 ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM -// fd59 ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM -// fd5a ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM -// fd5b ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM -// fd5c ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM -// fd5d ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM -// fd5e ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM -// fd5f ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM -// fd60 ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM -// fd61 ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM -// fd62 ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM -// fd63 ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM -// fd64 ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM -// fd65 ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM -// fd66 ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM -// fd67 ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM -// fd68 ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM -// fd69 ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM -// fd6a ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM -// fd6b ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM -// fd6c ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM -// fd6d ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM -// fd6e ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM -// fd6f ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM -// fd70 ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM -// fd71 ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM -// fd72 ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM -// fd73 ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM -// fd74 ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM -// fd75 ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM -// fd76 ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM -// fd77 ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM -// fd78 ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM -// fd79 ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM -// fd7a ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM -// fd7b ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM -// fd7c ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM -// fd7d ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM -// fd7e ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM -// fd7f ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM -// fd80 ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM -// fd81 ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM -// fd82 ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM -// fd83 ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM -// fd84 ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM -// fd85 ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM -// fd86 ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM -// fd87 ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM -// fd88 ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM -// fd89 ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM -// fd8a ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM -// fd8b ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM -// fd8c ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM -// fd8d ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM -// fd8e ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM -// fd8f ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM - { 0xFD50, 0x40, 0x9, 0, 0 }, -// fd92 ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM -// fd93 ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM -// fd94 ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM -// fd95 ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM -// fd96 ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM -// fd97 ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM -// fd98 ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM -// fd99 ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM -// fd9a ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM -// fd9b ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM -// fd9c ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM -// fd9d ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM -// fd9e ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM -// fd9f ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM -// fda0 ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM -// fda1 ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM -// fda2 ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM -// fda3 ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM -// fda4 ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM -// fda5 ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM -// fda6 ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM -// fda7 ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM -// fda8 ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM -// fda9 ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM -// fdaa ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM -// fdab ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM -// fdac ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM -// fdad ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM -// fdae ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM -// fdaf ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM -// fdb0 ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM -// fdb1 ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM -// fdb2 ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM -// fdb3 ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM -// fdb4 ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM -// fdb5 ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM -// fdb6 ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM -// fdb7 ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM -// fdb8 ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM -// fdb9 ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM -// fdba ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM -// fdbb ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM -// fdbc ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM -// fdbd ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM -// fdbe ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM -// fdbf ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM -// fdc0 ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM -// fdc1 ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM -// fdc2 ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM -// fdc3 ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM -// fdc4 ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM -// fdc5 ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM -// fdc6 ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM -// fdc7 ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM - { 0xFD92, 0x36, 0x9, 0, 0 }, -// fdf0 ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM -// fdf1 ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM -// fdf2 ARABIC LIGATURE ALLAH ISOLATED FORM -// fdf3 ARABIC LIGATURE AKBAR ISOLATED FORM -// fdf4 ARABIC LIGATURE MOHAMMAD ISOLATED FORM -// fdf5 ARABIC LIGATURE SALAM ISOLATED FORM -// fdf6 ARABIC LIGATURE RASOUL ISOLATED FORM -// fdf7 ARABIC LIGATURE ALAYHE ISOLATED FORM -// fdf8 ARABIC LIGATURE WASALLAM ISOLATED FORM -// fdf9 ARABIC LIGATURE SALLA ISOLATED FORM -// fdfa ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM -// fdfb ARABIC LIGATURE JALLAJALALOUHOU - { 0xFDF0, 0xC, 0x9, 0, 0 }, -// fdfc RIAL SIGN -// fdfd ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM - { 0xFDFC, 0x2, 0x8, 0, 0 }, -// fe00 VARIATION SELECTOR-1 -// fe01 VARIATION SELECTOR-2 -// fe02 VARIATION SELECTOR-3 -// fe03 VARIATION SELECTOR-4 -// fe04 VARIATION SELECTOR-5 -// fe05 VARIATION SELECTOR-6 -// fe06 VARIATION SELECTOR-7 -// fe07 VARIATION SELECTOR-8 -// fe08 VARIATION SELECTOR-9 -// fe09 VARIATION SELECTOR-10 -// fe0a VARIATION SELECTOR-11 -// fe0b VARIATION SELECTOR-12 -// fe0c VARIATION SELECTOR-13 -// fe0d VARIATION SELECTOR-14 -// fe0e VARIATION SELECTOR-15 -// fe0f VARIATION SELECTOR-16 - { 0xFE00, 0x10, 0x0, 0, 0 }, -// fe10 PRESENTATION FORM FOR VERTICAL COMMA -// fe11 PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA -// fe12 PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP -// fe13 PRESENTATION FORM FOR VERTICAL COLON -// fe14 PRESENTATION FORM FOR VERTICAL SEMICOLON -// fe15 PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK -// fe16 PRESENTATION FORM FOR VERTICAL QUESTION MARK -// fe17 PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET -// fe18 PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET -// fe19 PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS - { 0xFE10, 0xA, 0x18, 0, 0 }, -// fe20 COMBINING LIGATURE LEFT HALF -// fe21 COMBINING LIGATURE RIGHT HALF -// fe22 COMBINING DOUBLE TILDE LEFT HALF -// fe23 COMBINING DOUBLE TILDE RIGHT HALF -// fe24 COMBINING MACRON LEFT HALF -// fe25 COMBINING MACRON RIGHT HALF -// fe26 COMBINING CONJOINING MACRON -// fe27 COMBINING LIGATURE LEFT HALF BELOW -// fe28 COMBINING LIGATURE RIGHT HALF BELOW -// fe29 COMBINING TILDE LEFT HALF BELOW -// fe2a COMBINING TILDE RIGHT HALF BELOW -// fe2b COMBINING MACRON LEFT HALF BELOW -// fe2c COMBINING MACRON RIGHT HALF BELOW -// fe2d COMBINING CONJOINING MACRON BELOW - { 0xFE20, 0xE, 0x0, 0, 0 }, -// fe30 PRESENTATION FORM FOR VERTICAL TWO DOT LEADER -// fe31 PRESENTATION FORM FOR VERTICAL EM DASH -// fe32 PRESENTATION FORM FOR VERTICAL EN DASH -// fe33 PRESENTATION FORM FOR VERTICAL LOW LINE -// fe34 PRESENTATION FORM FOR VERTICAL WAVY LOW LINE -// fe35 PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS -// fe36 PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS -// fe37 PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET -// fe38 PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET -// fe39 PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET -// fe3a PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET -// fe3b PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET -// fe3c PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET -// fe3d PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET -// fe3e PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET -// fe3f PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET -// fe40 PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET -// fe41 PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET -// fe42 PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET -// fe43 PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET -// fe44 PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET -// fe45 SESAME DOT -// fe46 WHITE SESAME DOT -// fe47 PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET -// fe48 PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET -// fe49 DASHED OVERLINE -// fe4a CENTRELINE OVERLINE -// fe4b WAVY OVERLINE -// fe4c DOUBLE WAVY OVERLINE -// fe4d DASHED LOW LINE -// fe4e CENTRELINE LOW LINE -// fe4f WAVY LOW LINE -// fe50 SMALL COMMA -// fe51 SMALL IDEOGRAPHIC COMMA -// fe52 SMALL FULL STOP - { 0xFE30, 0x23, 0x18, 0, 0 }, -// fe54 SMALL SEMICOLON -// fe55 SMALL COLON -// fe56 SMALL QUESTION MARK -// fe57 SMALL EXCLAMATION MARK -// fe58 SMALL EM DASH -// fe59 SMALL LEFT PARENTHESIS -// fe5a SMALL RIGHT PARENTHESIS -// fe5b SMALL LEFT CURLY BRACKET -// fe5c SMALL RIGHT CURLY BRACKET -// fe5d SMALL LEFT TORTOISE SHELL BRACKET -// fe5e SMALL RIGHT TORTOISE SHELL BRACKET -// fe5f SMALL NUMBER SIGN -// fe60 SMALL AMPERSAND -// fe61 SMALL ASTERISK - { 0xFE54, 0xE, 0x18, 0, 0 }, -// fe62 SMALL PLUS SIGN - { 0xFE62, 0x1, 0x8, 0, 0 }, -// fe63 SMALL HYPHEN-MINUS - { 0xFE63, 0x1, 0x18, 0, 0 }, -// fe64 SMALL LESS-THAN SIGN -// fe65 SMALL GREATER-THAN SIGN -// fe66 SMALL EQUALS SIGN - { 0xFE64, 0x3, 0x8, 0, 0 }, -// fe68 SMALL REVERSE SOLIDUS - { 0xFE68, 0x1, 0x18, 0, 0 }, -// fe69 SMALL DOLLAR SIGN - { 0xFE69, 0x1, 0x8, 0, 0 }, -// fe6a SMALL PERCENT SIGN -// fe6b SMALL COMMERCIAL AT - { 0xFE6A, 0x2, 0x18, 0, 0 }, -// fe70 ARABIC FATHATAN ISOLATED FORM -// fe71 ARABIC TATWEEL WITH FATHATAN ABOVE -// fe72 ARABIC DAMMATAN ISOLATED FORM -// fe73 ARABIC TAIL FRAGMENT -// fe74 ARABIC KASRATAN ISOLATED FORM - { 0xFE70, 0x5, 0x9, 0, 0 }, -// fe76 ARABIC FATHA ISOLATED FORM -// fe77 ARABIC FATHA MEDIAL FORM -// fe78 ARABIC DAMMA ISOLATED FORM -// fe79 ARABIC DAMMA MEDIAL FORM -// fe7a ARABIC KASRA ISOLATED FORM -// fe7b ARABIC KASRA MEDIAL FORM -// fe7c ARABIC SHADDA ISOLATED FORM -// fe7d ARABIC SHADDA MEDIAL FORM -// fe7e ARABIC SUKUN ISOLATED FORM -// fe7f ARABIC SUKUN MEDIAL FORM -// fe80 ARABIC LETTER HAMZA ISOLATED FORM -// fe81 ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM -// fe82 ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM -// fe83 ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM -// fe84 ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM -// fe85 ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM -// fe86 ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM -// fe87 ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM -// fe88 ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM -// fe89 ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM -// fe8a ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM -// fe8b ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM -// fe8c ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM -// fe8d ARABIC LETTER ALEF ISOLATED FORM -// fe8e ARABIC LETTER ALEF FINAL FORM -// fe8f ARABIC LETTER BEH ISOLATED FORM -// fe90 ARABIC LETTER BEH FINAL FORM -// fe91 ARABIC LETTER BEH INITIAL FORM -// fe92 ARABIC LETTER BEH MEDIAL FORM -// fe93 ARABIC LETTER TEH MARBUTA ISOLATED FORM -// fe94 ARABIC LETTER TEH MARBUTA FINAL FORM -// fe95 ARABIC LETTER TEH ISOLATED FORM -// fe96 ARABIC LETTER TEH FINAL FORM -// fe97 ARABIC LETTER TEH INITIAL FORM -// fe98 ARABIC LETTER TEH MEDIAL FORM -// fe99 ARABIC LETTER THEH ISOLATED FORM -// fe9a ARABIC LETTER THEH FINAL FORM -// fe9b ARABIC LETTER THEH INITIAL FORM -// fe9c ARABIC LETTER THEH MEDIAL FORM -// fe9d ARABIC LETTER JEEM ISOLATED FORM -// fe9e ARABIC LETTER JEEM FINAL FORM -// fe9f ARABIC LETTER JEEM INITIAL FORM -// fea0 ARABIC LETTER JEEM MEDIAL FORM -// fea1 ARABIC LETTER HAH ISOLATED FORM -// fea2 ARABIC LETTER HAH FINAL FORM -// fea3 ARABIC LETTER HAH INITIAL FORM -// fea4 ARABIC LETTER HAH MEDIAL FORM -// fea5 ARABIC LETTER KHAH ISOLATED FORM -// fea6 ARABIC LETTER KHAH FINAL FORM -// fea7 ARABIC LETTER KHAH INITIAL FORM -// fea8 ARABIC LETTER KHAH MEDIAL FORM -// fea9 ARABIC LETTER DAL ISOLATED FORM -// feaa ARABIC LETTER DAL FINAL FORM -// feab ARABIC LETTER THAL ISOLATED FORM -// feac ARABIC LETTER THAL FINAL FORM -// fead ARABIC LETTER REH ISOLATED FORM -// feae ARABIC LETTER REH FINAL FORM -// feaf ARABIC LETTER ZAIN ISOLATED FORM -// feb0 ARABIC LETTER ZAIN FINAL FORM -// feb1 ARABIC LETTER SEEN ISOLATED FORM -// feb2 ARABIC LETTER SEEN FINAL FORM -// feb3 ARABIC LETTER SEEN INITIAL FORM -// feb4 ARABIC LETTER SEEN MEDIAL FORM -// feb5 ARABIC LETTER SHEEN ISOLATED FORM -// feb6 ARABIC LETTER SHEEN FINAL FORM -// feb7 ARABIC LETTER SHEEN INITIAL FORM -// feb8 ARABIC LETTER SHEEN MEDIAL FORM -// feb9 ARABIC LETTER SAD ISOLATED FORM -// feba ARABIC LETTER SAD FINAL FORM -// febb ARABIC LETTER SAD INITIAL FORM -// febc ARABIC LETTER SAD MEDIAL FORM -// febd ARABIC LETTER DAD ISOLATED FORM -// febe ARABIC LETTER DAD FINAL FORM -// febf ARABIC LETTER DAD INITIAL FORM -// fec0 ARABIC LETTER DAD MEDIAL FORM -// fec1 ARABIC LETTER TAH ISOLATED FORM -// fec2 ARABIC LETTER TAH FINAL FORM -// fec3 ARABIC LETTER TAH INITIAL FORM -// fec4 ARABIC LETTER TAH MEDIAL FORM -// fec5 ARABIC LETTER ZAH ISOLATED FORM -// fec6 ARABIC LETTER ZAH FINAL FORM -// fec7 ARABIC LETTER ZAH INITIAL FORM -// fec8 ARABIC LETTER ZAH MEDIAL FORM -// fec9 ARABIC LETTER AIN ISOLATED FORM -// feca ARABIC LETTER AIN FINAL FORM -// fecb ARABIC LETTER AIN INITIAL FORM -// fecc ARABIC LETTER AIN MEDIAL FORM -// fecd ARABIC LETTER GHAIN ISOLATED FORM -// fece ARABIC LETTER GHAIN FINAL FORM -// fecf ARABIC LETTER GHAIN INITIAL FORM -// fed0 ARABIC LETTER GHAIN MEDIAL FORM -// fed1 ARABIC LETTER FEH ISOLATED FORM -// fed2 ARABIC LETTER FEH FINAL FORM -// fed3 ARABIC LETTER FEH INITIAL FORM -// fed4 ARABIC LETTER FEH MEDIAL FORM -// fed5 ARABIC LETTER QAF ISOLATED FORM -// fed6 ARABIC LETTER QAF FINAL FORM -// fed7 ARABIC LETTER QAF INITIAL FORM -// fed8 ARABIC LETTER QAF MEDIAL FORM -// fed9 ARABIC LETTER KAF ISOLATED FORM -// feda ARABIC LETTER KAF FINAL FORM -// fedb ARABIC LETTER KAF INITIAL FORM -// fedc ARABIC LETTER KAF MEDIAL FORM -// fedd ARABIC LETTER LAM ISOLATED FORM -// fede ARABIC LETTER LAM FINAL FORM -// fedf ARABIC LETTER LAM INITIAL FORM -// fee0 ARABIC LETTER LAM MEDIAL FORM -// fee1 ARABIC LETTER MEEM ISOLATED FORM -// fee2 ARABIC LETTER MEEM FINAL FORM -// fee3 ARABIC LETTER MEEM INITIAL FORM -// fee4 ARABIC LETTER MEEM MEDIAL FORM -// fee5 ARABIC LETTER NOON ISOLATED FORM -// fee6 ARABIC LETTER NOON FINAL FORM -// fee7 ARABIC LETTER NOON INITIAL FORM -// fee8 ARABIC LETTER NOON MEDIAL FORM -// fee9 ARABIC LETTER HEH ISOLATED FORM -// feea ARABIC LETTER HEH FINAL FORM -// feeb ARABIC LETTER HEH INITIAL FORM -// feec ARABIC LETTER HEH MEDIAL FORM -// feed ARABIC LETTER WAW ISOLATED FORM -// feee ARABIC LETTER WAW FINAL FORM -// feef ARABIC LETTER ALEF MAKSURA ISOLATED FORM -// fef0 ARABIC LETTER ALEF MAKSURA FINAL FORM -// fef1 ARABIC LETTER YEH ISOLATED FORM -// fef2 ARABIC LETTER YEH FINAL FORM -// fef3 ARABIC LETTER YEH INITIAL FORM -// fef4 ARABIC LETTER YEH MEDIAL FORM -// fef5 ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM -// fef6 ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM -// fef7 ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM -// fef8 ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM -// fef9 ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM -// fefa ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM -// fefb ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM -// fefc ARABIC LIGATURE LAM WITH ALEF FINAL FORM - { 0xFE76, 0x87, 0x9, 0, 0 }, -// feff ZERO WIDTH NO-BREAK SPACE - { 0xFEFF, 0x1, 0x0, 0, 0 }, -// ff01 FULLWIDTH EXCLAMATION MARK -// ff02 FULLWIDTH QUOTATION MARK -// ff03 FULLWIDTH NUMBER SIGN - { 0xFF01, 0x3, 0x18, 0, 0 }, -// ff04 FULLWIDTH DOLLAR SIGN - { 0xFF04, 0x1, 0x8, 0, 0 }, -// ff05 FULLWIDTH PERCENT SIGN -// ff06 FULLWIDTH AMPERSAND -// ff07 FULLWIDTH APOSTROPHE -// ff08 FULLWIDTH LEFT PARENTHESIS -// ff09 FULLWIDTH RIGHT PARENTHESIS -// ff0a FULLWIDTH ASTERISK - { 0xFF05, 0x6, 0x18, 0, 0 }, -// ff0b FULLWIDTH PLUS SIGN - { 0xFF0B, 0x1, 0x8, 0, 0 }, -// ff0c FULLWIDTH COMMA -// ff0d FULLWIDTH HYPHEN-MINUS -// ff0e FULLWIDTH FULL STOP -// ff0f FULLWIDTH SOLIDUS - { 0xFF0C, 0x4, 0x18, 0, 0 }, -// ff10 FULLWIDTH DIGIT ZERO -// ff11 FULLWIDTH DIGIT ONE -// ff12 FULLWIDTH DIGIT TWO -// ff13 FULLWIDTH DIGIT THREE -// ff14 FULLWIDTH DIGIT FOUR -// ff15 FULLWIDTH DIGIT FIVE -// ff16 FULLWIDTH DIGIT SIX -// ff17 FULLWIDTH DIGIT SEVEN -// ff18 FULLWIDTH DIGIT EIGHT -// ff19 FULLWIDTH DIGIT NINE - { 0xFF10, 0xA, 0x108, 0, 0 }, -// ff1a FULLWIDTH COLON -// ff1b FULLWIDTH SEMICOLON - { 0xFF1A, 0x2, 0x18, 0, 0 }, -// ff1c FULLWIDTH LESS-THAN SIGN -// ff1d FULLWIDTH EQUALS SIGN -// ff1e FULLWIDTH GREATER-THAN SIGN - { 0xFF1C, 0x3, 0x8, 0, 0 }, -// ff1f FULLWIDTH QUESTION MARK -// ff20 FULLWIDTH COMMERCIAL AT - { 0xFF1F, 0x2, 0x18, 0, 0 }, -// ff21 FULLWIDTH LATIN CAPITAL LETTER A -// ff22 FULLWIDTH LATIN CAPITAL LETTER B -// ff23 FULLWIDTH LATIN CAPITAL LETTER C -// ff24 FULLWIDTH LATIN CAPITAL LETTER D -// ff25 FULLWIDTH LATIN CAPITAL LETTER E -// ff26 FULLWIDTH LATIN CAPITAL LETTER F -// ff27 FULLWIDTH LATIN CAPITAL LETTER G -// ff28 FULLWIDTH LATIN CAPITAL LETTER H -// ff29 FULLWIDTH LATIN CAPITAL LETTER I -// ff2a FULLWIDTH LATIN CAPITAL LETTER J -// ff2b FULLWIDTH LATIN CAPITAL LETTER K -// ff2c FULLWIDTH LATIN CAPITAL LETTER L -// ff2d FULLWIDTH LATIN CAPITAL LETTER M -// ff2e FULLWIDTH LATIN CAPITAL LETTER N -// ff2f FULLWIDTH LATIN CAPITAL LETTER O -// ff30 FULLWIDTH LATIN CAPITAL LETTER P -// ff31 FULLWIDTH LATIN CAPITAL LETTER Q -// ff32 FULLWIDTH LATIN CAPITAL LETTER R -// ff33 FULLWIDTH LATIN CAPITAL LETTER S -// ff34 FULLWIDTH LATIN CAPITAL LETTER T -// ff35 FULLWIDTH LATIN CAPITAL LETTER U -// ff36 FULLWIDTH LATIN CAPITAL LETTER V -// ff37 FULLWIDTH LATIN CAPITAL LETTER W -// ff38 FULLWIDTH LATIN CAPITAL LETTER X -// ff39 FULLWIDTH LATIN CAPITAL LETTER Y -// ff3a FULLWIDTH LATIN CAPITAL LETTER Z - { 0xFF21, 0x1A, 0x89, 32, 0 }, -// ff3b FULLWIDTH LEFT SQUARE BRACKET -// ff3c FULLWIDTH REVERSE SOLIDUS -// ff3d FULLWIDTH RIGHT SQUARE BRACKET - { 0xFF3B, 0x3, 0x18, 0, 0 }, -// ff3e FULLWIDTH CIRCUMFLEX ACCENT - { 0xFF3E, 0x1, 0x8, 0, 0 }, -// ff3f FULLWIDTH LOW LINE - { 0xFF3F, 0x1, 0x18, 0, 0 }, -// ff40 FULLWIDTH GRAVE ACCENT - { 0xFF40, 0x1, 0x8, 0, 0 }, -// ff41 FULLWIDTH LATIN SMALL LETTER A -// ff42 FULLWIDTH LATIN SMALL LETTER B -// ff43 FULLWIDTH LATIN SMALL LETTER C -// ff44 FULLWIDTH LATIN SMALL LETTER D -// ff45 FULLWIDTH LATIN SMALL LETTER E -// ff46 FULLWIDTH LATIN SMALL LETTER F -// ff47 FULLWIDTH LATIN SMALL LETTER G -// ff48 FULLWIDTH LATIN SMALL LETTER H -// ff49 FULLWIDTH LATIN SMALL LETTER I -// ff4a FULLWIDTH LATIN SMALL LETTER J -// ff4b FULLWIDTH LATIN SMALL LETTER K -// ff4c FULLWIDTH LATIN SMALL LETTER L -// ff4d FULLWIDTH LATIN SMALL LETTER M -// ff4e FULLWIDTH LATIN SMALL LETTER N -// ff4f FULLWIDTH LATIN SMALL LETTER O -// ff50 FULLWIDTH LATIN SMALL LETTER P -// ff51 FULLWIDTH LATIN SMALL LETTER Q -// ff52 FULLWIDTH LATIN SMALL LETTER R -// ff53 FULLWIDTH LATIN SMALL LETTER S -// ff54 FULLWIDTH LATIN SMALL LETTER T -// ff55 FULLWIDTH LATIN SMALL LETTER U -// ff56 FULLWIDTH LATIN SMALL LETTER V -// ff57 FULLWIDTH LATIN SMALL LETTER W -// ff58 FULLWIDTH LATIN SMALL LETTER X -// ff59 FULLWIDTH LATIN SMALL LETTER Y -// ff5a FULLWIDTH LATIN SMALL LETTER Z - { 0xFF41, 0x1A, 0x49, 0, -32 }, -// ff5b FULLWIDTH LEFT CURLY BRACKET - { 0xFF5B, 0x1, 0x18, 0, 0 }, -// ff5c FULLWIDTH VERTICAL LINE - { 0xFF5C, 0x1, 0x8, 0, 0 }, -// ff5d FULLWIDTH RIGHT CURLY BRACKET - { 0xFF5D, 0x1, 0x18, 0, 0 }, -// ff5e FULLWIDTH TILDE - { 0xFF5E, 0x1, 0x8, 0, 0 }, -// ff5f FULLWIDTH LEFT WHITE PARENTHESIS -// ff60 FULLWIDTH RIGHT WHITE PARENTHESIS -// ff61 HALFWIDTH IDEOGRAPHIC FULL STOP -// ff62 HALFWIDTH LEFT CORNER BRACKET -// ff63 HALFWIDTH RIGHT CORNER BRACKET -// ff64 HALFWIDTH IDEOGRAPHIC COMMA -// ff65 HALFWIDTH KATAKANA MIDDLE DOT - { 0xFF5F, 0x7, 0x18, 0, 0 }, -// ff66 HALFWIDTH KATAKANA LETTER WO -// ff67 HALFWIDTH KATAKANA LETTER SMALL A -// ff68 HALFWIDTH KATAKANA LETTER SMALL I -// ff69 HALFWIDTH KATAKANA LETTER SMALL U -// ff6a HALFWIDTH KATAKANA LETTER SMALL E -// ff6b HALFWIDTH KATAKANA LETTER SMALL O -// ff6c HALFWIDTH KATAKANA LETTER SMALL YA -// ff6d HALFWIDTH KATAKANA LETTER SMALL YU -// ff6e HALFWIDTH KATAKANA LETTER SMALL YO -// ff6f HALFWIDTH KATAKANA LETTER SMALL TU -// ff70 HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK -// ff71 HALFWIDTH KATAKANA LETTER A -// ff72 HALFWIDTH KATAKANA LETTER I -// ff73 HALFWIDTH KATAKANA LETTER U -// ff74 HALFWIDTH KATAKANA LETTER E -// ff75 HALFWIDTH KATAKANA LETTER O -// ff76 HALFWIDTH KATAKANA LETTER KA -// ff77 HALFWIDTH KATAKANA LETTER KI -// ff78 HALFWIDTH KATAKANA LETTER KU -// ff79 HALFWIDTH KATAKANA LETTER KE -// ff7a HALFWIDTH KATAKANA LETTER KO -// ff7b HALFWIDTH KATAKANA LETTER SA -// ff7c HALFWIDTH KATAKANA LETTER SI -// ff7d HALFWIDTH KATAKANA LETTER SU -// ff7e HALFWIDTH KATAKANA LETTER SE -// ff7f HALFWIDTH KATAKANA LETTER SO -// ff80 HALFWIDTH KATAKANA LETTER TA -// ff81 HALFWIDTH KATAKANA LETTER TI -// ff82 HALFWIDTH KATAKANA LETTER TU -// ff83 HALFWIDTH KATAKANA LETTER TE -// ff84 HALFWIDTH KATAKANA LETTER TO -// ff85 HALFWIDTH KATAKANA LETTER NA -// ff86 HALFWIDTH KATAKANA LETTER NI -// ff87 HALFWIDTH KATAKANA LETTER NU -// ff88 HALFWIDTH KATAKANA LETTER NE -// ff89 HALFWIDTH KATAKANA LETTER NO -// ff8a HALFWIDTH KATAKANA LETTER HA -// ff8b HALFWIDTH KATAKANA LETTER HI -// ff8c HALFWIDTH KATAKANA LETTER HU -// ff8d HALFWIDTH KATAKANA LETTER HE -// ff8e HALFWIDTH KATAKANA LETTER HO -// ff8f HALFWIDTH KATAKANA LETTER MA -// ff90 HALFWIDTH KATAKANA LETTER MI -// ff91 HALFWIDTH KATAKANA LETTER MU -// ff92 HALFWIDTH KATAKANA LETTER ME -// ff93 HALFWIDTH KATAKANA LETTER MO -// ff94 HALFWIDTH KATAKANA LETTER YA -// ff95 HALFWIDTH KATAKANA LETTER YU -// ff96 HALFWIDTH KATAKANA LETTER YO -// ff97 HALFWIDTH KATAKANA LETTER RA -// ff98 HALFWIDTH KATAKANA LETTER RI -// ff99 HALFWIDTH KATAKANA LETTER RU -// ff9a HALFWIDTH KATAKANA LETTER RE -// ff9b HALFWIDTH KATAKANA LETTER RO -// ff9c HALFWIDTH KATAKANA LETTER WA -// ff9d HALFWIDTH KATAKANA LETTER N -// ff9e HALFWIDTH KATAKANA VOICED SOUND MARK -// ff9f HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK -// ffa0 HALFWIDTH HANGUL FILLER -// ffa1 HALFWIDTH HANGUL LETTER KIYEOK -// ffa2 HALFWIDTH HANGUL LETTER SSANGKIYEOK -// ffa3 HALFWIDTH HANGUL LETTER KIYEOK-SIOS -// ffa4 HALFWIDTH HANGUL LETTER NIEUN -// ffa5 HALFWIDTH HANGUL LETTER NIEUN-CIEUC -// ffa6 HALFWIDTH HANGUL LETTER NIEUN-HIEUH -// ffa7 HALFWIDTH HANGUL LETTER TIKEUT -// ffa8 HALFWIDTH HANGUL LETTER SSANGTIKEUT -// ffa9 HALFWIDTH HANGUL LETTER RIEUL -// ffaa HALFWIDTH HANGUL LETTER RIEUL-KIYEOK -// ffab HALFWIDTH HANGUL LETTER RIEUL-MIEUM -// ffac HALFWIDTH HANGUL LETTER RIEUL-PIEUP -// ffad HALFWIDTH HANGUL LETTER RIEUL-SIOS -// ffae HALFWIDTH HANGUL LETTER RIEUL-THIEUTH -// ffaf HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH -// ffb0 HALFWIDTH HANGUL LETTER RIEUL-HIEUH -// ffb1 HALFWIDTH HANGUL LETTER MIEUM -// ffb2 HALFWIDTH HANGUL LETTER PIEUP -// ffb3 HALFWIDTH HANGUL LETTER SSANGPIEUP -// ffb4 HALFWIDTH HANGUL LETTER PIEUP-SIOS -// ffb5 HALFWIDTH HANGUL LETTER SIOS -// ffb6 HALFWIDTH HANGUL LETTER SSANGSIOS -// ffb7 HALFWIDTH HANGUL LETTER IEUNG -// ffb8 HALFWIDTH HANGUL LETTER CIEUC -// ffb9 HALFWIDTH HANGUL LETTER SSANGCIEUC -// ffba HALFWIDTH HANGUL LETTER CHIEUCH -// ffbb HALFWIDTH HANGUL LETTER KHIEUKH -// ffbc HALFWIDTH HANGUL LETTER THIEUTH -// ffbd HALFWIDTH HANGUL LETTER PHIEUPH -// ffbe HALFWIDTH HANGUL LETTER HIEUH - { 0xFF66, 0x59, 0x9, 0, 0 }, -// ffc2 HALFWIDTH HANGUL LETTER A -// ffc3 HALFWIDTH HANGUL LETTER AE -// ffc4 HALFWIDTH HANGUL LETTER YA -// ffc5 HALFWIDTH HANGUL LETTER YAE -// ffc6 HALFWIDTH HANGUL LETTER EO -// ffc7 HALFWIDTH HANGUL LETTER E - { 0xFFC2, 0x6, 0x9, 0, 0 }, -// ffca HALFWIDTH HANGUL LETTER YEO -// ffcb HALFWIDTH HANGUL LETTER YE -// ffcc HALFWIDTH HANGUL LETTER O -// ffcd HALFWIDTH HANGUL LETTER WA -// ffce HALFWIDTH HANGUL LETTER WAE -// ffcf HALFWIDTH HANGUL LETTER OE - { 0xFFCA, 0x6, 0x9, 0, 0 }, -// ffd2 HALFWIDTH HANGUL LETTER YO -// ffd3 HALFWIDTH HANGUL LETTER U -// ffd4 HALFWIDTH HANGUL LETTER WEO -// ffd5 HALFWIDTH HANGUL LETTER WE -// ffd6 HALFWIDTH HANGUL LETTER WI -// ffd7 HALFWIDTH HANGUL LETTER YU - { 0xFFD2, 0x6, 0x9, 0, 0 }, -// ffda HALFWIDTH HANGUL LETTER EU -// ffdb HALFWIDTH HANGUL LETTER YI -// ffdc HALFWIDTH HANGUL LETTER I - { 0xFFDA, 0x3, 0x9, 0, 0 }, -// ffe0 FULLWIDTH CENT SIGN -// ffe1 FULLWIDTH POUND SIGN -// ffe2 FULLWIDTH NOT SIGN -// ffe3 FULLWIDTH MACRON -// ffe4 FULLWIDTH BROKEN BAR -// ffe5 FULLWIDTH YEN SIGN -// ffe6 FULLWIDTH WON SIGN - { 0xFFE0, 0x7, 0x8, 0, 0 }, -// ffe8 HALFWIDTH FORMS LIGHT VERTICAL -// ffe9 HALFWIDTH LEFTWARDS ARROW -// ffea HALFWIDTH UPWARDS ARROW -// ffeb HALFWIDTH RIGHTWARDS ARROW -// ffec HALFWIDTH DOWNWARDS ARROW -// ffed HALFWIDTH BLACK SQUARE -// ffee HALFWIDTH WHITE CIRCLE - { 0xFFE8, 0x7, 0x8, 0, 0 }, -// fff9 INTERLINEAR ANNOTATION ANCHOR -// fffa INTERLINEAR ANNOTATION SEPARATOR -// fffb INTERLINEAR ANNOTATION TERMINATOR - { 0xFFF9, 0x3, 0x0, 0, 0 }, -// fffc OBJECT REPLACEMENT CHARACTER -// fffd REPLACEMENT CHARACTER - { 0xFFFC, 0x2, 0x8, 0, 0 }, -// 10000 LINEAR B SYLLABLE B008 A -// 10001 LINEAR B SYLLABLE B038 E -// 10002 LINEAR B SYLLABLE B028 I -// 10003 LINEAR B SYLLABLE B061 O -// 10004 LINEAR B SYLLABLE B010 U -// 10005 LINEAR B SYLLABLE B001 DA -// 10006 LINEAR B SYLLABLE B045 DE -// 10007 LINEAR B SYLLABLE B007 DI -// 10008 LINEAR B SYLLABLE B014 DO -// 10009 LINEAR B SYLLABLE B051 DU -// 1000a LINEAR B SYLLABLE B057 JA -// 1000b LINEAR B SYLLABLE B046 JE - { 0x10000, 0xC, 0x9, 0, 0 }, -// 1000d LINEAR B SYLLABLE B036 JO -// 1000e LINEAR B SYLLABLE B065 JU -// 1000f LINEAR B SYLLABLE B077 KA -// 10010 LINEAR B SYLLABLE B044 KE -// 10011 LINEAR B SYLLABLE B067 KI -// 10012 LINEAR B SYLLABLE B070 KO -// 10013 LINEAR B SYLLABLE B081 KU -// 10014 LINEAR B SYLLABLE B080 MA -// 10015 LINEAR B SYLLABLE B013 ME -// 10016 LINEAR B SYLLABLE B073 MI -// 10017 LINEAR B SYLLABLE B015 MO -// 10018 LINEAR B SYLLABLE B023 MU -// 10019 LINEAR B SYLLABLE B006 NA -// 1001a LINEAR B SYLLABLE B024 NE -// 1001b LINEAR B SYLLABLE B030 NI -// 1001c LINEAR B SYLLABLE B052 NO -// 1001d LINEAR B SYLLABLE B055 NU -// 1001e LINEAR B SYLLABLE B003 PA -// 1001f LINEAR B SYLLABLE B072 PE -// 10020 LINEAR B SYLLABLE B039 PI -// 10021 LINEAR B SYLLABLE B011 PO -// 10022 LINEAR B SYLLABLE B050 PU -// 10023 LINEAR B SYLLABLE B016 QA -// 10024 LINEAR B SYLLABLE B078 QE -// 10025 LINEAR B SYLLABLE B021 QI -// 10026 LINEAR B SYLLABLE B032 QO - { 0x1000D, 0x1A, 0x9, 0, 0 }, -// 10028 LINEAR B SYLLABLE B060 RA -// 10029 LINEAR B SYLLABLE B027 RE -// 1002a LINEAR B SYLLABLE B053 RI -// 1002b LINEAR B SYLLABLE B002 RO -// 1002c LINEAR B SYLLABLE B026 RU -// 1002d LINEAR B SYLLABLE B031 SA -// 1002e LINEAR B SYLLABLE B009 SE -// 1002f LINEAR B SYLLABLE B041 SI -// 10030 LINEAR B SYLLABLE B012 SO -// 10031 LINEAR B SYLLABLE B058 SU -// 10032 LINEAR B SYLLABLE B059 TA -// 10033 LINEAR B SYLLABLE B004 TE -// 10034 LINEAR B SYLLABLE B037 TI -// 10035 LINEAR B SYLLABLE B005 TO -// 10036 LINEAR B SYLLABLE B069 TU -// 10037 LINEAR B SYLLABLE B054 WA -// 10038 LINEAR B SYLLABLE B075 WE -// 10039 LINEAR B SYLLABLE B040 WI -// 1003a LINEAR B SYLLABLE B042 WO - { 0x10028, 0x13, 0x9, 0, 0 }, -// 1003c LINEAR B SYLLABLE B017 ZA -// 1003d LINEAR B SYLLABLE B074 ZE - { 0x1003C, 0x2, 0x9, 0, 0 }, -// 1003f LINEAR B SYLLABLE B020 ZO -// 10040 LINEAR B SYLLABLE B025 A2 -// 10041 LINEAR B SYLLABLE B043 A3 -// 10042 LINEAR B SYLLABLE B085 AU -// 10043 LINEAR B SYLLABLE B071 DWE -// 10044 LINEAR B SYLLABLE B090 DWO -// 10045 LINEAR B SYLLABLE B048 NWA -// 10046 LINEAR B SYLLABLE B029 PU2 -// 10047 LINEAR B SYLLABLE B062 PTE -// 10048 LINEAR B SYLLABLE B076 RA2 -// 10049 LINEAR B SYLLABLE B033 RA3 -// 1004a LINEAR B SYLLABLE B068 RO2 -// 1004b LINEAR B SYLLABLE B066 TA2 -// 1004c LINEAR B SYLLABLE B087 TWE -// 1004d LINEAR B SYLLABLE B091 TWO - { 0x1003F, 0xF, 0x9, 0, 0 }, -// 10050 LINEAR B SYMBOL B018 -// 10051 LINEAR B SYMBOL B019 -// 10052 LINEAR B SYMBOL B022 -// 10053 LINEAR B SYMBOL B034 -// 10054 LINEAR B SYMBOL B047 -// 10055 LINEAR B SYMBOL B049 -// 10056 LINEAR B SYMBOL B056 -// 10057 LINEAR B SYMBOL B063 -// 10058 LINEAR B SYMBOL B064 -// 10059 LINEAR B SYMBOL B079 -// 1005a LINEAR B SYMBOL B082 -// 1005b LINEAR B SYMBOL B083 -// 1005c LINEAR B SYMBOL B086 -// 1005d LINEAR B SYMBOL B089 - { 0x10050, 0xE, 0x9, 0, 0 }, -// 10080 LINEAR B IDEOGRAM B100 MAN -// 10081 LINEAR B IDEOGRAM B102 WOMAN -// 10082 LINEAR B IDEOGRAM B104 DEER -// 10083 LINEAR B IDEOGRAM B105 EQUID -// 10084 LINEAR B IDEOGRAM B105F MARE -// 10085 LINEAR B IDEOGRAM B105M STALLION -// 10086 LINEAR B IDEOGRAM B106F EWE -// 10087 LINEAR B IDEOGRAM B106M RAM -// 10088 LINEAR B IDEOGRAM B107F SHE-GOAT -// 10089 LINEAR B IDEOGRAM B107M HE-GOAT -// 1008a LINEAR B IDEOGRAM B108F SOW -// 1008b LINEAR B IDEOGRAM B108M BOAR -// 1008c LINEAR B IDEOGRAM B109F COW -// 1008d LINEAR B IDEOGRAM B109M BULL -// 1008e LINEAR B IDEOGRAM B120 WHEAT -// 1008f LINEAR B IDEOGRAM B121 BARLEY -// 10090 LINEAR B IDEOGRAM B122 OLIVE -// 10091 LINEAR B IDEOGRAM B123 SPICE -// 10092 LINEAR B IDEOGRAM B125 CYPERUS -// 10093 LINEAR B MONOGRAM B127 KAPO -// 10094 LINEAR B MONOGRAM B128 KANAKO -// 10095 LINEAR B IDEOGRAM B130 OIL -// 10096 LINEAR B IDEOGRAM B131 WINE -// 10097 LINEAR B IDEOGRAM B132 -// 10098 LINEAR B MONOGRAM B133 AREPA -// 10099 LINEAR B MONOGRAM B135 MERI -// 1009a LINEAR B IDEOGRAM B140 BRONZE -// 1009b LINEAR B IDEOGRAM B141 GOLD -// 1009c LINEAR B IDEOGRAM B142 -// 1009d LINEAR B IDEOGRAM B145 WOOL -// 1009e LINEAR B IDEOGRAM B146 -// 1009f LINEAR B IDEOGRAM B150 -// 100a0 LINEAR B IDEOGRAM B151 HORN -// 100a1 LINEAR B IDEOGRAM B152 -// 100a2 LINEAR B IDEOGRAM B153 -// 100a3 LINEAR B IDEOGRAM B154 -// 100a4 LINEAR B MONOGRAM B156 TURO2 -// 100a5 LINEAR B IDEOGRAM B157 -// 100a6 LINEAR B IDEOGRAM B158 -// 100a7 LINEAR B IDEOGRAM B159 CLOTH -// 100a8 LINEAR B IDEOGRAM B160 -// 100a9 LINEAR B IDEOGRAM B161 -// 100aa LINEAR B IDEOGRAM B162 GARMENT -// 100ab LINEAR B IDEOGRAM B163 ARMOUR -// 100ac LINEAR B IDEOGRAM B164 -// 100ad LINEAR B IDEOGRAM B165 -// 100ae LINEAR B IDEOGRAM B166 -// 100af LINEAR B IDEOGRAM B167 -// 100b0 LINEAR B IDEOGRAM B168 -// 100b1 LINEAR B IDEOGRAM B169 -// 100b2 LINEAR B IDEOGRAM B170 -// 100b3 LINEAR B IDEOGRAM B171 -// 100b4 LINEAR B IDEOGRAM B172 -// 100b5 LINEAR B IDEOGRAM B173 MONTH -// 100b6 LINEAR B IDEOGRAM B174 -// 100b7 LINEAR B IDEOGRAM B176 TREE -// 100b8 LINEAR B IDEOGRAM B177 -// 100b9 LINEAR B IDEOGRAM B178 -// 100ba LINEAR B IDEOGRAM B179 -// 100bb LINEAR B IDEOGRAM B180 -// 100bc LINEAR B IDEOGRAM B181 -// 100bd LINEAR B IDEOGRAM B182 -// 100be LINEAR B IDEOGRAM B183 -// 100bf LINEAR B IDEOGRAM B184 -// 100c0 LINEAR B IDEOGRAM B185 -// 100c1 LINEAR B IDEOGRAM B189 -// 100c2 LINEAR B IDEOGRAM B190 -// 100c3 LINEAR B IDEOGRAM B191 HELMET -// 100c4 LINEAR B IDEOGRAM B220 FOOTSTOOL -// 100c5 LINEAR B IDEOGRAM B225 BATHTUB -// 100c6 LINEAR B IDEOGRAM B230 SPEAR -// 100c7 LINEAR B IDEOGRAM B231 ARROW -// 100c8 LINEAR B IDEOGRAM B232 -// 100c9 LINEAR B IDEOGRAM B233 SWORD -// 100ca LINEAR B IDEOGRAM B234 -// 100cb LINEAR B IDEOGRAM B236 -// 100cc LINEAR B IDEOGRAM B240 WHEELED CHARIOT -// 100cd LINEAR B IDEOGRAM B241 CHARIOT -// 100ce LINEAR B IDEOGRAM B242 CHARIOT FRAME -// 100cf LINEAR B IDEOGRAM B243 WHEEL -// 100d0 LINEAR B IDEOGRAM B245 -// 100d1 LINEAR B IDEOGRAM B246 -// 100d2 LINEAR B MONOGRAM B247 DIPTE -// 100d3 LINEAR B IDEOGRAM B248 -// 100d4 LINEAR B IDEOGRAM B249 -// 100d5 LINEAR B IDEOGRAM B251 -// 100d6 LINEAR B IDEOGRAM B252 -// 100d7 LINEAR B IDEOGRAM B253 -// 100d8 LINEAR B IDEOGRAM B254 DART -// 100d9 LINEAR B IDEOGRAM B255 -// 100da LINEAR B IDEOGRAM B256 -// 100db LINEAR B IDEOGRAM B257 -// 100dc LINEAR B IDEOGRAM B258 -// 100dd LINEAR B IDEOGRAM B259 -// 100de LINEAR B IDEOGRAM VESSEL B155 -// 100df LINEAR B IDEOGRAM VESSEL B200 -// 100e0 LINEAR B IDEOGRAM VESSEL B201 -// 100e1 LINEAR B IDEOGRAM VESSEL B202 -// 100e2 LINEAR B IDEOGRAM VESSEL B203 -// 100e3 LINEAR B IDEOGRAM VESSEL B204 -// 100e4 LINEAR B IDEOGRAM VESSEL B205 -// 100e5 LINEAR B IDEOGRAM VESSEL B206 -// 100e6 LINEAR B IDEOGRAM VESSEL B207 -// 100e7 LINEAR B IDEOGRAM VESSEL B208 -// 100e8 LINEAR B IDEOGRAM VESSEL B209 -// 100e9 LINEAR B IDEOGRAM VESSEL B210 -// 100ea LINEAR B IDEOGRAM VESSEL B211 -// 100eb LINEAR B IDEOGRAM VESSEL B212 -// 100ec LINEAR B IDEOGRAM VESSEL B213 -// 100ed LINEAR B IDEOGRAM VESSEL B214 -// 100ee LINEAR B IDEOGRAM VESSEL B215 -// 100ef LINEAR B IDEOGRAM VESSEL B216 -// 100f0 LINEAR B IDEOGRAM VESSEL B217 -// 100f1 LINEAR B IDEOGRAM VESSEL B218 -// 100f2 LINEAR B IDEOGRAM VESSEL B219 -// 100f3 LINEAR B IDEOGRAM VESSEL B221 -// 100f4 LINEAR B IDEOGRAM VESSEL B222 -// 100f5 LINEAR B IDEOGRAM VESSEL B226 -// 100f6 LINEAR B IDEOGRAM VESSEL B227 -// 100f7 LINEAR B IDEOGRAM VESSEL B228 -// 100f8 LINEAR B IDEOGRAM VESSEL B229 -// 100f9 LINEAR B IDEOGRAM VESSEL B250 -// 100fa LINEAR B IDEOGRAM VESSEL B305 - { 0x10080, 0x7B, 0x9, 0, 0 }, -// 10100 AEGEAN WORD SEPARATOR LINE -// 10101 AEGEAN WORD SEPARATOR DOT -// 10102 AEGEAN CHECK MARK - { 0x10100, 0x3, 0x18, 0, 0 }, -// 10107 AEGEAN NUMBER ONE -// 10108 AEGEAN NUMBER TWO -// 10109 AEGEAN NUMBER THREE -// 1010a AEGEAN NUMBER FOUR -// 1010b AEGEAN NUMBER FIVE -// 1010c AEGEAN NUMBER SIX -// 1010d AEGEAN NUMBER SEVEN -// 1010e AEGEAN NUMBER EIGHT -// 1010f AEGEAN NUMBER NINE -// 10110 AEGEAN NUMBER TEN -// 10111 AEGEAN NUMBER TWENTY -// 10112 AEGEAN NUMBER THIRTY -// 10113 AEGEAN NUMBER FORTY -// 10114 AEGEAN NUMBER FIFTY -// 10115 AEGEAN NUMBER SIXTY -// 10116 AEGEAN NUMBER SEVENTY -// 10117 AEGEAN NUMBER EIGHTY -// 10118 AEGEAN NUMBER NINETY -// 10119 AEGEAN NUMBER ONE HUNDRED -// 1011a AEGEAN NUMBER TWO HUNDRED -// 1011b AEGEAN NUMBER THREE HUNDRED -// 1011c AEGEAN NUMBER FOUR HUNDRED -// 1011d AEGEAN NUMBER FIVE HUNDRED -// 1011e AEGEAN NUMBER SIX HUNDRED -// 1011f AEGEAN NUMBER SEVEN HUNDRED -// 10120 AEGEAN NUMBER EIGHT HUNDRED -// 10121 AEGEAN NUMBER NINE HUNDRED -// 10122 AEGEAN NUMBER ONE THOUSAND -// 10123 AEGEAN NUMBER TWO THOUSAND -// 10124 AEGEAN NUMBER THREE THOUSAND -// 10125 AEGEAN NUMBER FOUR THOUSAND -// 10126 AEGEAN NUMBER FIVE THOUSAND -// 10127 AEGEAN NUMBER SIX THOUSAND -// 10128 AEGEAN NUMBER SEVEN THOUSAND -// 10129 AEGEAN NUMBER EIGHT THOUSAND -// 1012a AEGEAN NUMBER NINE THOUSAND -// 1012b AEGEAN NUMBER TEN THOUSAND -// 1012c AEGEAN NUMBER TWENTY THOUSAND -// 1012d AEGEAN NUMBER THIRTY THOUSAND -// 1012e AEGEAN NUMBER FORTY THOUSAND -// 1012f AEGEAN NUMBER FIFTY THOUSAND -// 10130 AEGEAN NUMBER SIXTY THOUSAND -// 10131 AEGEAN NUMBER SEVENTY THOUSAND -// 10132 AEGEAN NUMBER EIGHTY THOUSAND -// 10133 AEGEAN NUMBER NINETY THOUSAND - { 0x10107, 0x2D, 0x8, 0, 0 }, -// 10137 AEGEAN WEIGHT BASE UNIT -// 10138 AEGEAN WEIGHT FIRST SUBUNIT -// 10139 AEGEAN WEIGHT SECOND SUBUNIT -// 1013a AEGEAN WEIGHT THIRD SUBUNIT -// 1013b AEGEAN WEIGHT FOURTH SUBUNIT -// 1013c AEGEAN DRY MEASURE FIRST SUBUNIT -// 1013d AEGEAN LIQUID MEASURE FIRST SUBUNIT -// 1013e AEGEAN MEASURE SECOND SUBUNIT -// 1013f AEGEAN MEASURE THIRD SUBUNIT -// 10140 GREEK ACROPHONIC ATTIC ONE QUARTER -// 10141 GREEK ACROPHONIC ATTIC ONE HALF -// 10142 GREEK ACROPHONIC ATTIC ONE DRACHMA -// 10143 GREEK ACROPHONIC ATTIC FIVE -// 10144 GREEK ACROPHONIC ATTIC FIFTY -// 10145 GREEK ACROPHONIC ATTIC FIVE HUNDRED -// 10146 GREEK ACROPHONIC ATTIC FIVE THOUSAND -// 10147 GREEK ACROPHONIC ATTIC FIFTY THOUSAND -// 10148 GREEK ACROPHONIC ATTIC FIVE TALENTS -// 10149 GREEK ACROPHONIC ATTIC TEN TALENTS -// 1014a GREEK ACROPHONIC ATTIC FIFTY TALENTS -// 1014b GREEK ACROPHONIC ATTIC ONE HUNDRED TALENTS -// 1014c GREEK ACROPHONIC ATTIC FIVE HUNDRED TALENTS -// 1014d GREEK ACROPHONIC ATTIC ONE THOUSAND TALENTS -// 1014e GREEK ACROPHONIC ATTIC FIVE THOUSAND TALENTS -// 1014f GREEK ACROPHONIC ATTIC FIVE STATERS -// 10150 GREEK ACROPHONIC ATTIC TEN STATERS -// 10151 GREEK ACROPHONIC ATTIC FIFTY STATERS -// 10152 GREEK ACROPHONIC ATTIC ONE HUNDRED STATERS -// 10153 GREEK ACROPHONIC ATTIC FIVE HUNDRED STATERS -// 10154 GREEK ACROPHONIC ATTIC ONE THOUSAND STATERS -// 10155 GREEK ACROPHONIC ATTIC TEN THOUSAND STATERS -// 10156 GREEK ACROPHONIC ATTIC FIFTY THOUSAND STATERS -// 10157 GREEK ACROPHONIC ATTIC TEN MNAS -// 10158 GREEK ACROPHONIC HERAEUM ONE PLETHRON -// 10159 GREEK ACROPHONIC THESPIAN ONE -// 1015a GREEK ACROPHONIC HERMIONIAN ONE -// 1015b GREEK ACROPHONIC EPIDAUREAN TWO -// 1015c GREEK ACROPHONIC THESPIAN TWO -// 1015d GREEK ACROPHONIC CYRENAIC TWO DRACHMAS -// 1015e GREEK ACROPHONIC EPIDAUREAN TWO DRACHMAS -// 1015f GREEK ACROPHONIC TROEZENIAN FIVE -// 10160 GREEK ACROPHONIC TROEZENIAN TEN -// 10161 GREEK ACROPHONIC TROEZENIAN TEN ALTERNATE FORM -// 10162 GREEK ACROPHONIC HERMIONIAN TEN -// 10163 GREEK ACROPHONIC MESSENIAN TEN -// 10164 GREEK ACROPHONIC THESPIAN TEN -// 10165 GREEK ACROPHONIC THESPIAN THIRTY -// 10166 GREEK ACROPHONIC TROEZENIAN FIFTY -// 10167 GREEK ACROPHONIC TROEZENIAN FIFTY ALTERNATE FORM -// 10168 GREEK ACROPHONIC HERMIONIAN FIFTY -// 10169 GREEK ACROPHONIC THESPIAN FIFTY -// 1016a GREEK ACROPHONIC THESPIAN ONE HUNDRED -// 1016b GREEK ACROPHONIC THESPIAN THREE HUNDRED -// 1016c GREEK ACROPHONIC EPIDAUREAN FIVE HUNDRED -// 1016d GREEK ACROPHONIC TROEZENIAN FIVE HUNDRED -// 1016e GREEK ACROPHONIC THESPIAN FIVE HUNDRED -// 1016f GREEK ACROPHONIC CARYSTIAN FIVE HUNDRED -// 10170 GREEK ACROPHONIC NAXIAN FIVE HUNDRED -// 10171 GREEK ACROPHONIC THESPIAN ONE THOUSAND -// 10172 GREEK ACROPHONIC THESPIAN FIVE THOUSAND -// 10173 GREEK ACROPHONIC DELPHIC FIVE MNAS -// 10174 GREEK ACROPHONIC STRATIAN FIFTY MNAS -// 10175 GREEK ONE HALF SIGN -// 10176 GREEK ONE HALF SIGN ALTERNATE FORM -// 10177 GREEK TWO THIRDS SIGN -// 10178 GREEK THREE QUARTERS SIGN -// 10179 GREEK YEAR SIGN -// 1017a GREEK TALENT SIGN -// 1017b GREEK DRACHMA SIGN -// 1017c GREEK OBOL SIGN -// 1017d GREEK TWO OBOLS SIGN -// 1017e GREEK THREE OBOLS SIGN -// 1017f GREEK FOUR OBOLS SIGN -// 10180 GREEK FIVE OBOLS SIGN -// 10181 GREEK METRETES SIGN -// 10182 GREEK KYATHOS BASE SIGN -// 10183 GREEK LITRA SIGN -// 10184 GREEK OUNKIA SIGN -// 10185 GREEK XESTES SIGN -// 10186 GREEK ARTABE SIGN -// 10187 GREEK AROURA SIGN -// 10188 GREEK GRAMMA SIGN -// 10189 GREEK TRYBLION BASE SIGN -// 1018a GREEK ZERO SIGN -// 1018b GREEK ONE QUARTER SIGN -// 1018c GREEK SINUSOID SIGN - { 0x10137, 0x56, 0x8, 0, 0 }, -// 10190 ROMAN SEXTANS SIGN -// 10191 ROMAN UNCIA SIGN -// 10192 ROMAN SEMUNCIA SIGN -// 10193 ROMAN SEXTULA SIGN -// 10194 ROMAN DIMIDIA SEXTULA SIGN -// 10195 ROMAN SILIQUA SIGN -// 10196 ROMAN DENARIUS SIGN -// 10197 ROMAN QUINARIUS SIGN -// 10198 ROMAN SESTERTIUS SIGN -// 10199 ROMAN DUPONDIUS SIGN -// 1019a ROMAN AS SIGN -// 1019b ROMAN CENTURIAL SIGN - { 0x10190, 0xC, 0x8, 0, 0 }, -// 101a0 GREEK SYMBOL TAU RHO - { 0x101A0, 0x1, 0x8, 0, 0 }, -// 101d0 PHAISTOS DISC SIGN PEDESTRIAN -// 101d1 PHAISTOS DISC SIGN PLUMED HEAD -// 101d2 PHAISTOS DISC SIGN TATTOOED HEAD -// 101d3 PHAISTOS DISC SIGN CAPTIVE -// 101d4 PHAISTOS DISC SIGN CHILD -// 101d5 PHAISTOS DISC SIGN WOMAN -// 101d6 PHAISTOS DISC SIGN HELMET -// 101d7 PHAISTOS DISC SIGN GAUNTLET -// 101d8 PHAISTOS DISC SIGN TIARA -// 101d9 PHAISTOS DISC SIGN ARROW -// 101da PHAISTOS DISC SIGN BOW -// 101db PHAISTOS DISC SIGN SHIELD -// 101dc PHAISTOS DISC SIGN CLUB -// 101dd PHAISTOS DISC SIGN MANACLES -// 101de PHAISTOS DISC SIGN MATTOCK -// 101df PHAISTOS DISC SIGN SAW -// 101e0 PHAISTOS DISC SIGN LID -// 101e1 PHAISTOS DISC SIGN BOOMERANG -// 101e2 PHAISTOS DISC SIGN CARPENTRY PLANE -// 101e3 PHAISTOS DISC SIGN DOLIUM -// 101e4 PHAISTOS DISC SIGN COMB -// 101e5 PHAISTOS DISC SIGN SLING -// 101e6 PHAISTOS DISC SIGN COLUMN -// 101e7 PHAISTOS DISC SIGN BEEHIVE -// 101e8 PHAISTOS DISC SIGN SHIP -// 101e9 PHAISTOS DISC SIGN HORN -// 101ea PHAISTOS DISC SIGN HIDE -// 101eb PHAISTOS DISC SIGN BULLS LEG -// 101ec PHAISTOS DISC SIGN CAT -// 101ed PHAISTOS DISC SIGN RAM -// 101ee PHAISTOS DISC SIGN EAGLE -// 101ef PHAISTOS DISC SIGN DOVE -// 101f0 PHAISTOS DISC SIGN TUNNY -// 101f1 PHAISTOS DISC SIGN BEE -// 101f2 PHAISTOS DISC SIGN PLANE TREE -// 101f3 PHAISTOS DISC SIGN VINE -// 101f4 PHAISTOS DISC SIGN PAPYRUS -// 101f5 PHAISTOS DISC SIGN ROSETTE -// 101f6 PHAISTOS DISC SIGN LILY -// 101f7 PHAISTOS DISC SIGN OX BACK -// 101f8 PHAISTOS DISC SIGN FLUTE -// 101f9 PHAISTOS DISC SIGN GRATER -// 101fa PHAISTOS DISC SIGN STRAINER -// 101fb PHAISTOS DISC SIGN SMALL AXE -// 101fc PHAISTOS DISC SIGN WAVY BAND - { 0x101D0, 0x2D, 0x8, 0, 0 }, -// 101fd PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE - { 0x101FD, 0x1, 0x0, 0, 0 }, -// 10280 LYCIAN LETTER A -// 10281 LYCIAN LETTER E -// 10282 LYCIAN LETTER B -// 10283 LYCIAN LETTER BH -// 10284 LYCIAN LETTER G -// 10285 LYCIAN LETTER D -// 10286 LYCIAN LETTER I -// 10287 LYCIAN LETTER W -// 10288 LYCIAN LETTER Z -// 10289 LYCIAN LETTER TH -// 1028a LYCIAN LETTER J -// 1028b LYCIAN LETTER K -// 1028c LYCIAN LETTER Q -// 1028d LYCIAN LETTER L -// 1028e LYCIAN LETTER M -// 1028f LYCIAN LETTER N -// 10290 LYCIAN LETTER MM -// 10291 LYCIAN LETTER NN -// 10292 LYCIAN LETTER U -// 10293 LYCIAN LETTER P -// 10294 LYCIAN LETTER KK -// 10295 LYCIAN LETTER R -// 10296 LYCIAN LETTER S -// 10297 LYCIAN LETTER T -// 10298 LYCIAN LETTER TT -// 10299 LYCIAN LETTER AN -// 1029a LYCIAN LETTER EN -// 1029b LYCIAN LETTER H -// 1029c LYCIAN LETTER X - { 0x10280, 0x1D, 0x9, 0, 0 }, -// 102a0 CARIAN LETTER A -// 102a1 CARIAN LETTER P2 -// 102a2 CARIAN LETTER D -// 102a3 CARIAN LETTER L -// 102a4 CARIAN LETTER UUU -// 102a5 CARIAN LETTER R -// 102a6 CARIAN LETTER LD -// 102a7 CARIAN LETTER A2 -// 102a8 CARIAN LETTER Q -// 102a9 CARIAN LETTER B -// 102aa CARIAN LETTER M -// 102ab CARIAN LETTER O -// 102ac CARIAN LETTER D2 -// 102ad CARIAN LETTER T -// 102ae CARIAN LETTER SH -// 102af CARIAN LETTER SH2 -// 102b0 CARIAN LETTER S -// 102b1 CARIAN LETTER C-18 -// 102b2 CARIAN LETTER U -// 102b3 CARIAN LETTER NN -// 102b4 CARIAN LETTER X -// 102b5 CARIAN LETTER N -// 102b6 CARIAN LETTER TT2 -// 102b7 CARIAN LETTER P -// 102b8 CARIAN LETTER SS -// 102b9 CARIAN LETTER I -// 102ba CARIAN LETTER E -// 102bb CARIAN LETTER UUUU -// 102bc CARIAN LETTER K -// 102bd CARIAN LETTER K2 -// 102be CARIAN LETTER ND -// 102bf CARIAN LETTER UU -// 102c0 CARIAN LETTER G -// 102c1 CARIAN LETTER G2 -// 102c2 CARIAN LETTER ST -// 102c3 CARIAN LETTER ST2 -// 102c4 CARIAN LETTER NG -// 102c5 CARIAN LETTER II -// 102c6 CARIAN LETTER C-39 -// 102c7 CARIAN LETTER TT -// 102c8 CARIAN LETTER UUU2 -// 102c9 CARIAN LETTER RR -// 102ca CARIAN LETTER MB -// 102cb CARIAN LETTER MB2 -// 102cc CARIAN LETTER MB3 -// 102cd CARIAN LETTER MB4 -// 102ce CARIAN LETTER LD2 -// 102cf CARIAN LETTER E2 -// 102d0 CARIAN LETTER UUU3 - { 0x102A0, 0x31, 0x9, 0, 0 }, -// 102e0 COPTIC EPACT THOUSANDS MARK - { 0x102E0, 0x1, 0x0, 0, 0 }, -// 102e1 COPTIC EPACT DIGIT ONE -// 102e2 COPTIC EPACT DIGIT TWO -// 102e3 COPTIC EPACT DIGIT THREE -// 102e4 COPTIC EPACT DIGIT FOUR -// 102e5 COPTIC EPACT DIGIT FIVE -// 102e6 COPTIC EPACT DIGIT SIX -// 102e7 COPTIC EPACT DIGIT SEVEN -// 102e8 COPTIC EPACT DIGIT EIGHT -// 102e9 COPTIC EPACT DIGIT NINE -// 102ea COPTIC EPACT NUMBER TEN -// 102eb COPTIC EPACT NUMBER TWENTY -// 102ec COPTIC EPACT NUMBER THIRTY -// 102ed COPTIC EPACT NUMBER FORTY -// 102ee COPTIC EPACT NUMBER FIFTY -// 102ef COPTIC EPACT NUMBER SIXTY -// 102f0 COPTIC EPACT NUMBER SEVENTY -// 102f1 COPTIC EPACT NUMBER EIGHTY -// 102f2 COPTIC EPACT NUMBER NINETY -// 102f3 COPTIC EPACT NUMBER ONE HUNDRED -// 102f4 COPTIC EPACT NUMBER TWO HUNDRED -// 102f5 COPTIC EPACT NUMBER THREE HUNDRED -// 102f6 COPTIC EPACT NUMBER FOUR HUNDRED -// 102f7 COPTIC EPACT NUMBER FIVE HUNDRED -// 102f8 COPTIC EPACT NUMBER SIX HUNDRED -// 102f9 COPTIC EPACT NUMBER SEVEN HUNDRED -// 102fa COPTIC EPACT NUMBER EIGHT HUNDRED -// 102fb COPTIC EPACT NUMBER NINE HUNDRED - { 0x102E1, 0x1B, 0x8, 0, 0 }, -// 10300 OLD ITALIC LETTER A -// 10301 OLD ITALIC LETTER BE -// 10302 OLD ITALIC LETTER KE -// 10303 OLD ITALIC LETTER DE -// 10304 OLD ITALIC LETTER E -// 10305 OLD ITALIC LETTER VE -// 10306 OLD ITALIC LETTER ZE -// 10307 OLD ITALIC LETTER HE -// 10308 OLD ITALIC LETTER THE -// 10309 OLD ITALIC LETTER I -// 1030a OLD ITALIC LETTER KA -// 1030b OLD ITALIC LETTER EL -// 1030c OLD ITALIC LETTER EM -// 1030d OLD ITALIC LETTER EN -// 1030e OLD ITALIC LETTER ESH -// 1030f OLD ITALIC LETTER O -// 10310 OLD ITALIC LETTER PE -// 10311 OLD ITALIC LETTER SHE -// 10312 OLD ITALIC LETTER KU -// 10313 OLD ITALIC LETTER ER -// 10314 OLD ITALIC LETTER ES -// 10315 OLD ITALIC LETTER TE -// 10316 OLD ITALIC LETTER U -// 10317 OLD ITALIC LETTER EKS -// 10318 OLD ITALIC LETTER PHE -// 10319 OLD ITALIC LETTER KHE -// 1031a OLD ITALIC LETTER EF -// 1031b OLD ITALIC LETTER ERS -// 1031c OLD ITALIC LETTER CHE -// 1031d OLD ITALIC LETTER II -// 1031e OLD ITALIC LETTER UU -// 1031f OLD ITALIC LETTER ESS - { 0x10300, 0x20, 0x9, 0, 0 }, -// 10320 OLD ITALIC NUMERAL ONE -// 10321 OLD ITALIC NUMERAL FIVE -// 10322 OLD ITALIC NUMERAL TEN -// 10323 OLD ITALIC NUMERAL FIFTY - { 0x10320, 0x4, 0x8, 0, 0 }, -// 10330 GOTHIC LETTER AHSA -// 10331 GOTHIC LETTER BAIRKAN -// 10332 GOTHIC LETTER GIBA -// 10333 GOTHIC LETTER DAGS -// 10334 GOTHIC LETTER AIHVUS -// 10335 GOTHIC LETTER QAIRTHRA -// 10336 GOTHIC LETTER IUJA -// 10337 GOTHIC LETTER HAGL -// 10338 GOTHIC LETTER THIUTH -// 10339 GOTHIC LETTER EIS -// 1033a GOTHIC LETTER KUSMA -// 1033b GOTHIC LETTER LAGUS -// 1033c GOTHIC LETTER MANNA -// 1033d GOTHIC LETTER NAUTHS -// 1033e GOTHIC LETTER JER -// 1033f GOTHIC LETTER URUS -// 10340 GOTHIC LETTER PAIRTHRA - { 0x10330, 0x11, 0x9, 0, 0 }, -// 10341 GOTHIC LETTER NINETY - { 0x10341, 0x1, 0x8, 0, 0 }, -// 10342 GOTHIC LETTER RAIDA -// 10343 GOTHIC LETTER SAUIL -// 10344 GOTHIC LETTER TEIWS -// 10345 GOTHIC LETTER WINJA -// 10346 GOTHIC LETTER FAIHU -// 10347 GOTHIC LETTER IGGWS -// 10348 GOTHIC LETTER HWAIR -// 10349 GOTHIC LETTER OTHAL - { 0x10342, 0x8, 0x9, 0, 0 }, -// 1034a GOTHIC LETTER NINE HUNDRED - { 0x1034A, 0x1, 0x8, 0, 0 }, -// 10350 OLD PERMIC LETTER AN -// 10351 OLD PERMIC LETTER BUR -// 10352 OLD PERMIC LETTER GAI -// 10353 OLD PERMIC LETTER DOI -// 10354 OLD PERMIC LETTER E -// 10355 OLD PERMIC LETTER ZHOI -// 10356 OLD PERMIC LETTER DZHOI -// 10357 OLD PERMIC LETTER ZATA -// 10358 OLD PERMIC LETTER DZITA -// 10359 OLD PERMIC LETTER I -// 1035a OLD PERMIC LETTER KOKE -// 1035b OLD PERMIC LETTER LEI -// 1035c OLD PERMIC LETTER MENOE -// 1035d OLD PERMIC LETTER NENOE -// 1035e OLD PERMIC LETTER VOOI -// 1035f OLD PERMIC LETTER PEEI -// 10360 OLD PERMIC LETTER REI -// 10361 OLD PERMIC LETTER SII -// 10362 OLD PERMIC LETTER TAI -// 10363 OLD PERMIC LETTER U -// 10364 OLD PERMIC LETTER CHERY -// 10365 OLD PERMIC LETTER SHOOI -// 10366 OLD PERMIC LETTER SHCHOOI -// 10367 OLD PERMIC LETTER YRY -// 10368 OLD PERMIC LETTER YERU -// 10369 OLD PERMIC LETTER O -// 1036a OLD PERMIC LETTER OO -// 1036b OLD PERMIC LETTER EF -// 1036c OLD PERMIC LETTER HA -// 1036d OLD PERMIC LETTER TSIU -// 1036e OLD PERMIC LETTER VER -// 1036f OLD PERMIC LETTER YER -// 10370 OLD PERMIC LETTER YERI -// 10371 OLD PERMIC LETTER YAT -// 10372 OLD PERMIC LETTER IE -// 10373 OLD PERMIC LETTER YU -// 10374 OLD PERMIC LETTER YA -// 10375 OLD PERMIC LETTER IA - { 0x10350, 0x26, 0x9, 0, 0 }, -// 10376 COMBINING OLD PERMIC LETTER AN -// 10377 COMBINING OLD PERMIC LETTER DOI -// 10378 COMBINING OLD PERMIC LETTER ZATA -// 10379 COMBINING OLD PERMIC LETTER NENOE -// 1037a COMBINING OLD PERMIC LETTER SII - { 0x10376, 0x5, 0x0, 0, 0 }, -// 10380 UGARITIC LETTER ALPA -// 10381 UGARITIC LETTER BETA -// 10382 UGARITIC LETTER GAMLA -// 10383 UGARITIC LETTER KHA -// 10384 UGARITIC LETTER DELTA -// 10385 UGARITIC LETTER HO -// 10386 UGARITIC LETTER WO -// 10387 UGARITIC LETTER ZETA -// 10388 UGARITIC LETTER HOTA -// 10389 UGARITIC LETTER TET -// 1038a UGARITIC LETTER YOD -// 1038b UGARITIC LETTER KAF -// 1038c UGARITIC LETTER SHIN -// 1038d UGARITIC LETTER LAMDA -// 1038e UGARITIC LETTER MEM -// 1038f UGARITIC LETTER DHAL -// 10390 UGARITIC LETTER NUN -// 10391 UGARITIC LETTER ZU -// 10392 UGARITIC LETTER SAMKA -// 10393 UGARITIC LETTER AIN -// 10394 UGARITIC LETTER PU -// 10395 UGARITIC LETTER SADE -// 10396 UGARITIC LETTER QOPA -// 10397 UGARITIC LETTER RASHA -// 10398 UGARITIC LETTER THANNA -// 10399 UGARITIC LETTER GHAIN -// 1039a UGARITIC LETTER TO -// 1039b UGARITIC LETTER I -// 1039c UGARITIC LETTER U -// 1039d UGARITIC LETTER SSU - { 0x10380, 0x1E, 0x9, 0, 0 }, -// 1039f UGARITIC WORD DIVIDER - { 0x1039F, 0x1, 0x18, 0, 0 }, -// 103a0 OLD PERSIAN SIGN A -// 103a1 OLD PERSIAN SIGN I -// 103a2 OLD PERSIAN SIGN U -// 103a3 OLD PERSIAN SIGN KA -// 103a4 OLD PERSIAN SIGN KU -// 103a5 OLD PERSIAN SIGN GA -// 103a6 OLD PERSIAN SIGN GU -// 103a7 OLD PERSIAN SIGN XA -// 103a8 OLD PERSIAN SIGN CA -// 103a9 OLD PERSIAN SIGN JA -// 103aa OLD PERSIAN SIGN JI -// 103ab OLD PERSIAN SIGN TA -// 103ac OLD PERSIAN SIGN TU -// 103ad OLD PERSIAN SIGN DA -// 103ae OLD PERSIAN SIGN DI -// 103af OLD PERSIAN SIGN DU -// 103b0 OLD PERSIAN SIGN THA -// 103b1 OLD PERSIAN SIGN PA -// 103b2 OLD PERSIAN SIGN BA -// 103b3 OLD PERSIAN SIGN FA -// 103b4 OLD PERSIAN SIGN NA -// 103b5 OLD PERSIAN SIGN NU -// 103b6 OLD PERSIAN SIGN MA -// 103b7 OLD PERSIAN SIGN MI -// 103b8 OLD PERSIAN SIGN MU -// 103b9 OLD PERSIAN SIGN YA -// 103ba OLD PERSIAN SIGN VA -// 103bb OLD PERSIAN SIGN VI -// 103bc OLD PERSIAN SIGN RA -// 103bd OLD PERSIAN SIGN RU -// 103be OLD PERSIAN SIGN LA -// 103bf OLD PERSIAN SIGN SA -// 103c0 OLD PERSIAN SIGN ZA -// 103c1 OLD PERSIAN SIGN SHA -// 103c2 OLD PERSIAN SIGN SSA -// 103c3 OLD PERSIAN SIGN HA - { 0x103A0, 0x24, 0x9, 0, 0 }, -// 103c8 OLD PERSIAN SIGN AURAMAZDAA -// 103c9 OLD PERSIAN SIGN AURAMAZDAA-2 -// 103ca OLD PERSIAN SIGN AURAMAZDAAHA -// 103cb OLD PERSIAN SIGN XSHAAYATHIYA -// 103cc OLD PERSIAN SIGN DAHYAAUSH -// 103cd OLD PERSIAN SIGN DAHYAAUSH-2 -// 103ce OLD PERSIAN SIGN BAGA -// 103cf OLD PERSIAN SIGN BUUMISH - { 0x103C8, 0x8, 0x9, 0, 0 }, -// 103d0 OLD PERSIAN WORD DIVIDER - { 0x103D0, 0x1, 0x18, 0, 0 }, -// 103d1 OLD PERSIAN NUMBER ONE -// 103d2 OLD PERSIAN NUMBER TWO -// 103d3 OLD PERSIAN NUMBER TEN -// 103d4 OLD PERSIAN NUMBER TWENTY -// 103d5 OLD PERSIAN NUMBER HUNDRED - { 0x103D1, 0x5, 0x8, 0, 0 }, -// 10400 DESERET CAPITAL LETTER LONG I -// 10401 DESERET CAPITAL LETTER LONG E -// 10402 DESERET CAPITAL LETTER LONG A -// 10403 DESERET CAPITAL LETTER LONG AH -// 10404 DESERET CAPITAL LETTER LONG O -// 10405 DESERET CAPITAL LETTER LONG OO -// 10406 DESERET CAPITAL LETTER SHORT I -// 10407 DESERET CAPITAL LETTER SHORT E -// 10408 DESERET CAPITAL LETTER SHORT A -// 10409 DESERET CAPITAL LETTER SHORT AH -// 1040a DESERET CAPITAL LETTER SHORT O -// 1040b DESERET CAPITAL LETTER SHORT OO -// 1040c DESERET CAPITAL LETTER AY -// 1040d DESERET CAPITAL LETTER OW -// 1040e DESERET CAPITAL LETTER WU -// 1040f DESERET CAPITAL LETTER YEE -// 10410 DESERET CAPITAL LETTER H -// 10411 DESERET CAPITAL LETTER PEE -// 10412 DESERET CAPITAL LETTER BEE -// 10413 DESERET CAPITAL LETTER TEE -// 10414 DESERET CAPITAL LETTER DEE -// 10415 DESERET CAPITAL LETTER CHEE -// 10416 DESERET CAPITAL LETTER JEE -// 10417 DESERET CAPITAL LETTER KAY -// 10418 DESERET CAPITAL LETTER GAY -// 10419 DESERET CAPITAL LETTER EF -// 1041a DESERET CAPITAL LETTER VEE -// 1041b DESERET CAPITAL LETTER ETH -// 1041c DESERET CAPITAL LETTER THEE -// 1041d DESERET CAPITAL LETTER ES -// 1041e DESERET CAPITAL LETTER ZEE -// 1041f DESERET CAPITAL LETTER ESH -// 10420 DESERET CAPITAL LETTER ZHEE -// 10421 DESERET CAPITAL LETTER ER -// 10422 DESERET CAPITAL LETTER EL -// 10423 DESERET CAPITAL LETTER EM -// 10424 DESERET CAPITAL LETTER EN -// 10425 DESERET CAPITAL LETTER ENG -// 10426 DESERET CAPITAL LETTER OI -// 10427 DESERET CAPITAL LETTER EW - { 0x10400, 0x28, 0x89, 40, 0 }, -// 10428 DESERET SMALL LETTER LONG I -// 10429 DESERET SMALL LETTER LONG E -// 1042a DESERET SMALL LETTER LONG A -// 1042b DESERET SMALL LETTER LONG AH -// 1042c DESERET SMALL LETTER LONG O -// 1042d DESERET SMALL LETTER LONG OO -// 1042e DESERET SMALL LETTER SHORT I -// 1042f DESERET SMALL LETTER SHORT E -// 10430 DESERET SMALL LETTER SHORT A -// 10431 DESERET SMALL LETTER SHORT AH -// 10432 DESERET SMALL LETTER SHORT O -// 10433 DESERET SMALL LETTER SHORT OO -// 10434 DESERET SMALL LETTER AY -// 10435 DESERET SMALL LETTER OW -// 10436 DESERET SMALL LETTER WU -// 10437 DESERET SMALL LETTER YEE -// 10438 DESERET SMALL LETTER H -// 10439 DESERET SMALL LETTER PEE -// 1043a DESERET SMALL LETTER BEE -// 1043b DESERET SMALL LETTER TEE -// 1043c DESERET SMALL LETTER DEE -// 1043d DESERET SMALL LETTER CHEE -// 1043e DESERET SMALL LETTER JEE -// 1043f DESERET SMALL LETTER KAY -// 10440 DESERET SMALL LETTER GAY -// 10441 DESERET SMALL LETTER EF -// 10442 DESERET SMALL LETTER VEE -// 10443 DESERET SMALL LETTER ETH -// 10444 DESERET SMALL LETTER THEE -// 10445 DESERET SMALL LETTER ES -// 10446 DESERET SMALL LETTER ZEE -// 10447 DESERET SMALL LETTER ESH -// 10448 DESERET SMALL LETTER ZHEE -// 10449 DESERET SMALL LETTER ER -// 1044a DESERET SMALL LETTER EL -// 1044b DESERET SMALL LETTER EM -// 1044c DESERET SMALL LETTER EN -// 1044d DESERET SMALL LETTER ENG -// 1044e DESERET SMALL LETTER OI -// 1044f DESERET SMALL LETTER EW - { 0x10428, 0x28, 0x49, 0, -40 }, -// 10450 SHAVIAN LETTER PEEP -// 10451 SHAVIAN LETTER TOT -// 10452 SHAVIAN LETTER KICK -// 10453 SHAVIAN LETTER FEE -// 10454 SHAVIAN LETTER THIGH -// 10455 SHAVIAN LETTER SO -// 10456 SHAVIAN LETTER SURE -// 10457 SHAVIAN LETTER CHURCH -// 10458 SHAVIAN LETTER YEA -// 10459 SHAVIAN LETTER HUNG -// 1045a SHAVIAN LETTER BIB -// 1045b SHAVIAN LETTER DEAD -// 1045c SHAVIAN LETTER GAG -// 1045d SHAVIAN LETTER VOW -// 1045e SHAVIAN LETTER THEY -// 1045f SHAVIAN LETTER ZOO -// 10460 SHAVIAN LETTER MEASURE -// 10461 SHAVIAN LETTER JUDGE -// 10462 SHAVIAN LETTER WOE -// 10463 SHAVIAN LETTER HA-HA -// 10464 SHAVIAN LETTER LOLL -// 10465 SHAVIAN LETTER MIME -// 10466 SHAVIAN LETTER IF -// 10467 SHAVIAN LETTER EGG -// 10468 SHAVIAN LETTER ASH -// 10469 SHAVIAN LETTER ADO -// 1046a SHAVIAN LETTER ON -// 1046b SHAVIAN LETTER WOOL -// 1046c SHAVIAN LETTER OUT -// 1046d SHAVIAN LETTER AH -// 1046e SHAVIAN LETTER ROAR -// 1046f SHAVIAN LETTER NUN -// 10470 SHAVIAN LETTER EAT -// 10471 SHAVIAN LETTER AGE -// 10472 SHAVIAN LETTER ICE -// 10473 SHAVIAN LETTER UP -// 10474 SHAVIAN LETTER OAK -// 10475 SHAVIAN LETTER OOZE -// 10476 SHAVIAN LETTER OIL -// 10477 SHAVIAN LETTER AWE -// 10478 SHAVIAN LETTER ARE -// 10479 SHAVIAN LETTER OR -// 1047a SHAVIAN LETTER AIR -// 1047b SHAVIAN LETTER ERR -// 1047c SHAVIAN LETTER ARRAY -// 1047d SHAVIAN LETTER EAR -// 1047e SHAVIAN LETTER IAN -// 1047f SHAVIAN LETTER YEW -// 10480 OSMANYA LETTER ALEF -// 10481 OSMANYA LETTER BA -// 10482 OSMANYA LETTER TA -// 10483 OSMANYA LETTER JA -// 10484 OSMANYA LETTER XA -// 10485 OSMANYA LETTER KHA -// 10486 OSMANYA LETTER DEEL -// 10487 OSMANYA LETTER RA -// 10488 OSMANYA LETTER SA -// 10489 OSMANYA LETTER SHIIN -// 1048a OSMANYA LETTER DHA -// 1048b OSMANYA LETTER CAYN -// 1048c OSMANYA LETTER GA -// 1048d OSMANYA LETTER FA -// 1048e OSMANYA LETTER QAAF -// 1048f OSMANYA LETTER KAAF -// 10490 OSMANYA LETTER LAAN -// 10491 OSMANYA LETTER MIIN -// 10492 OSMANYA LETTER NUUN -// 10493 OSMANYA LETTER WAW -// 10494 OSMANYA LETTER HA -// 10495 OSMANYA LETTER YA -// 10496 OSMANYA LETTER A -// 10497 OSMANYA LETTER E -// 10498 OSMANYA LETTER I -// 10499 OSMANYA LETTER O -// 1049a OSMANYA LETTER U -// 1049b OSMANYA LETTER AA -// 1049c OSMANYA LETTER EE -// 1049d OSMANYA LETTER OO - { 0x10450, 0x4E, 0x9, 0, 0 }, -// 104a0 OSMANYA DIGIT ZERO -// 104a1 OSMANYA DIGIT ONE -// 104a2 OSMANYA DIGIT TWO -// 104a3 OSMANYA DIGIT THREE -// 104a4 OSMANYA DIGIT FOUR -// 104a5 OSMANYA DIGIT FIVE -// 104a6 OSMANYA DIGIT SIX -// 104a7 OSMANYA DIGIT SEVEN -// 104a8 OSMANYA DIGIT EIGHT -// 104a9 OSMANYA DIGIT NINE - { 0x104A0, 0xA, 0x108, 0, 0 }, -// 10500 ELBASAN LETTER A -// 10501 ELBASAN LETTER BE -// 10502 ELBASAN LETTER CE -// 10503 ELBASAN LETTER CHE -// 10504 ELBASAN LETTER DE -// 10505 ELBASAN LETTER NDE -// 10506 ELBASAN LETTER DHE -// 10507 ELBASAN LETTER EI -// 10508 ELBASAN LETTER E -// 10509 ELBASAN LETTER FE -// 1050a ELBASAN LETTER GE -// 1050b ELBASAN LETTER GJE -// 1050c ELBASAN LETTER HE -// 1050d ELBASAN LETTER I -// 1050e ELBASAN LETTER JE -// 1050f ELBASAN LETTER KE -// 10510 ELBASAN LETTER LE -// 10511 ELBASAN LETTER LLE -// 10512 ELBASAN LETTER ME -// 10513 ELBASAN LETTER NE -// 10514 ELBASAN LETTER NA -// 10515 ELBASAN LETTER NJE -// 10516 ELBASAN LETTER O -// 10517 ELBASAN LETTER PE -// 10518 ELBASAN LETTER QE -// 10519 ELBASAN LETTER RE -// 1051a ELBASAN LETTER RRE -// 1051b ELBASAN LETTER SE -// 1051c ELBASAN LETTER SHE -// 1051d ELBASAN LETTER TE -// 1051e ELBASAN LETTER THE -// 1051f ELBASAN LETTER U -// 10520 ELBASAN LETTER VE -// 10521 ELBASAN LETTER XE -// 10522 ELBASAN LETTER Y -// 10523 ELBASAN LETTER ZE -// 10524 ELBASAN LETTER ZHE -// 10525 ELBASAN LETTER GHE -// 10526 ELBASAN LETTER GHAMMA -// 10527 ELBASAN LETTER KHE - { 0x10500, 0x28, 0x9, 0, 0 }, -// 10530 CAUCASIAN ALBANIAN LETTER ALT -// 10531 CAUCASIAN ALBANIAN LETTER BET -// 10532 CAUCASIAN ALBANIAN LETTER GIM -// 10533 CAUCASIAN ALBANIAN LETTER DAT -// 10534 CAUCASIAN ALBANIAN LETTER EB -// 10535 CAUCASIAN ALBANIAN LETTER ZARL -// 10536 CAUCASIAN ALBANIAN LETTER EYN -// 10537 CAUCASIAN ALBANIAN LETTER ZHIL -// 10538 CAUCASIAN ALBANIAN LETTER TAS -// 10539 CAUCASIAN ALBANIAN LETTER CHA -// 1053a CAUCASIAN ALBANIAN LETTER YOWD -// 1053b CAUCASIAN ALBANIAN LETTER ZHA -// 1053c CAUCASIAN ALBANIAN LETTER IRB -// 1053d CAUCASIAN ALBANIAN LETTER SHA -// 1053e CAUCASIAN ALBANIAN LETTER LAN -// 1053f CAUCASIAN ALBANIAN LETTER INYA -// 10540 CAUCASIAN ALBANIAN LETTER XEYN -// 10541 CAUCASIAN ALBANIAN LETTER DYAN -// 10542 CAUCASIAN ALBANIAN LETTER CAR -// 10543 CAUCASIAN ALBANIAN LETTER JHOX -// 10544 CAUCASIAN ALBANIAN LETTER KAR -// 10545 CAUCASIAN ALBANIAN LETTER LYIT -// 10546 CAUCASIAN ALBANIAN LETTER HEYT -// 10547 CAUCASIAN ALBANIAN LETTER QAY -// 10548 CAUCASIAN ALBANIAN LETTER AOR -// 10549 CAUCASIAN ALBANIAN LETTER CHOY -// 1054a CAUCASIAN ALBANIAN LETTER CHI -// 1054b CAUCASIAN ALBANIAN LETTER CYAY -// 1054c CAUCASIAN ALBANIAN LETTER MAQ -// 1054d CAUCASIAN ALBANIAN LETTER QAR -// 1054e CAUCASIAN ALBANIAN LETTER NOWC -// 1054f CAUCASIAN ALBANIAN LETTER DZYAY -// 10550 CAUCASIAN ALBANIAN LETTER SHAK -// 10551 CAUCASIAN ALBANIAN LETTER JAYN -// 10552 CAUCASIAN ALBANIAN LETTER ON -// 10553 CAUCASIAN ALBANIAN LETTER TYAY -// 10554 CAUCASIAN ALBANIAN LETTER FAM -// 10555 CAUCASIAN ALBANIAN LETTER DZAY -// 10556 CAUCASIAN ALBANIAN LETTER CHAT -// 10557 CAUCASIAN ALBANIAN LETTER PEN -// 10558 CAUCASIAN ALBANIAN LETTER GHEYS -// 10559 CAUCASIAN ALBANIAN LETTER RAT -// 1055a CAUCASIAN ALBANIAN LETTER SEYK -// 1055b CAUCASIAN ALBANIAN LETTER VEYZ -// 1055c CAUCASIAN ALBANIAN LETTER TIWR -// 1055d CAUCASIAN ALBANIAN LETTER SHOY -// 1055e CAUCASIAN ALBANIAN LETTER IWN -// 1055f CAUCASIAN ALBANIAN LETTER CYAW -// 10560 CAUCASIAN ALBANIAN LETTER CAYN -// 10561 CAUCASIAN ALBANIAN LETTER YAYD -// 10562 CAUCASIAN ALBANIAN LETTER PIWR -// 10563 CAUCASIAN ALBANIAN LETTER KIW - { 0x10530, 0x34, 0x9, 0, 0 }, -// 1056f CAUCASIAN ALBANIAN CITATION MARK - { 0x1056F, 0x1, 0x18, 0, 0 }, -// 10600 LINEAR A SIGN AB001 -// 10601 LINEAR A SIGN AB002 -// 10602 LINEAR A SIGN AB003 -// 10603 LINEAR A SIGN AB004 -// 10604 LINEAR A SIGN AB005 -// 10605 LINEAR A SIGN AB006 -// 10606 LINEAR A SIGN AB007 -// 10607 LINEAR A SIGN AB008 -// 10608 LINEAR A SIGN AB009 -// 10609 LINEAR A SIGN AB010 -// 1060a LINEAR A SIGN AB011 -// 1060b LINEAR A SIGN AB013 -// 1060c LINEAR A SIGN AB016 -// 1060d LINEAR A SIGN AB017 -// 1060e LINEAR A SIGN AB020 -// 1060f LINEAR A SIGN AB021 -// 10610 LINEAR A SIGN AB021F -// 10611 LINEAR A SIGN AB021M -// 10612 LINEAR A SIGN AB022 -// 10613 LINEAR A SIGN AB022F -// 10614 LINEAR A SIGN AB022M -// 10615 LINEAR A SIGN AB023 -// 10616 LINEAR A SIGN AB023M -// 10617 LINEAR A SIGN AB024 -// 10618 LINEAR A SIGN AB026 -// 10619 LINEAR A SIGN AB027 -// 1061a LINEAR A SIGN AB028 -// 1061b LINEAR A SIGN A028B -// 1061c LINEAR A SIGN AB029 -// 1061d LINEAR A SIGN AB030 -// 1061e LINEAR A SIGN AB031 -// 1061f LINEAR A SIGN AB034 -// 10620 LINEAR A SIGN AB037 -// 10621 LINEAR A SIGN AB038 -// 10622 LINEAR A SIGN AB039 -// 10623 LINEAR A SIGN AB040 -// 10624 LINEAR A SIGN AB041 -// 10625 LINEAR A SIGN AB044 -// 10626 LINEAR A SIGN AB045 -// 10627 LINEAR A SIGN AB046 -// 10628 LINEAR A SIGN AB047 -// 10629 LINEAR A SIGN AB048 -// 1062a LINEAR A SIGN AB049 -// 1062b LINEAR A SIGN AB050 -// 1062c LINEAR A SIGN AB051 -// 1062d LINEAR A SIGN AB053 -// 1062e LINEAR A SIGN AB054 -// 1062f LINEAR A SIGN AB055 -// 10630 LINEAR A SIGN AB056 -// 10631 LINEAR A SIGN AB057 -// 10632 LINEAR A SIGN AB058 -// 10633 LINEAR A SIGN AB059 -// 10634 LINEAR A SIGN AB060 -// 10635 LINEAR A SIGN AB061 -// 10636 LINEAR A SIGN AB065 -// 10637 LINEAR A SIGN AB066 -// 10638 LINEAR A SIGN AB067 -// 10639 LINEAR A SIGN AB069 -// 1063a LINEAR A SIGN AB070 -// 1063b LINEAR A SIGN AB073 -// 1063c LINEAR A SIGN AB074 -// 1063d LINEAR A SIGN AB076 -// 1063e LINEAR A SIGN AB077 -// 1063f LINEAR A SIGN AB078 -// 10640 LINEAR A SIGN AB079 -// 10641 LINEAR A SIGN AB080 -// 10642 LINEAR A SIGN AB081 -// 10643 LINEAR A SIGN AB082 -// 10644 LINEAR A SIGN AB085 -// 10645 LINEAR A SIGN AB086 -// 10646 LINEAR A SIGN AB087 -// 10647 LINEAR A SIGN A100-102 -// 10648 LINEAR A SIGN AB118 -// 10649 LINEAR A SIGN AB120 -// 1064a LINEAR A SIGN A120B -// 1064b LINEAR A SIGN AB122 -// 1064c LINEAR A SIGN AB123 -// 1064d LINEAR A SIGN AB131A -// 1064e LINEAR A SIGN AB131B -// 1064f LINEAR A SIGN A131C -// 10650 LINEAR A SIGN AB164 -// 10651 LINEAR A SIGN AB171 -// 10652 LINEAR A SIGN AB180 -// 10653 LINEAR A SIGN AB188 -// 10654 LINEAR A SIGN AB191 -// 10655 LINEAR A SIGN A301 -// 10656 LINEAR A SIGN A302 -// 10657 LINEAR A SIGN A303 -// 10658 LINEAR A SIGN A304 -// 10659 LINEAR A SIGN A305 -// 1065a LINEAR A SIGN A306 -// 1065b LINEAR A SIGN A307 -// 1065c LINEAR A SIGN A308 -// 1065d LINEAR A SIGN A309A -// 1065e LINEAR A SIGN A309B -// 1065f LINEAR A SIGN A309C -// 10660 LINEAR A SIGN A310 -// 10661 LINEAR A SIGN A311 -// 10662 LINEAR A SIGN A312 -// 10663 LINEAR A SIGN A313A -// 10664 LINEAR A SIGN A313B -// 10665 LINEAR A SIGN A313C -// 10666 LINEAR A SIGN A314 -// 10667 LINEAR A SIGN A315 -// 10668 LINEAR A SIGN A316 -// 10669 LINEAR A SIGN A317 -// 1066a LINEAR A SIGN A318 -// 1066b LINEAR A SIGN A319 -// 1066c LINEAR A SIGN A320 -// 1066d LINEAR A SIGN A321 -// 1066e LINEAR A SIGN A322 -// 1066f LINEAR A SIGN A323 -// 10670 LINEAR A SIGN A324 -// 10671 LINEAR A SIGN A325 -// 10672 LINEAR A SIGN A326 -// 10673 LINEAR A SIGN A327 -// 10674 LINEAR A SIGN A328 -// 10675 LINEAR A SIGN A329 -// 10676 LINEAR A SIGN A330 -// 10677 LINEAR A SIGN A331 -// 10678 LINEAR A SIGN A332 -// 10679 LINEAR A SIGN A333 -// 1067a LINEAR A SIGN A334 -// 1067b LINEAR A SIGN A335 -// 1067c LINEAR A SIGN A336 -// 1067d LINEAR A SIGN A337 -// 1067e LINEAR A SIGN A338 -// 1067f LINEAR A SIGN A339 -// 10680 LINEAR A SIGN A340 -// 10681 LINEAR A SIGN A341 -// 10682 LINEAR A SIGN A342 -// 10683 LINEAR A SIGN A343 -// 10684 LINEAR A SIGN A344 -// 10685 LINEAR A SIGN A345 -// 10686 LINEAR A SIGN A346 -// 10687 LINEAR A SIGN A347 -// 10688 LINEAR A SIGN A348 -// 10689 LINEAR A SIGN A349 -// 1068a LINEAR A SIGN A350 -// 1068b LINEAR A SIGN A351 -// 1068c LINEAR A SIGN A352 -// 1068d LINEAR A SIGN A353 -// 1068e LINEAR A SIGN A354 -// 1068f LINEAR A SIGN A355 -// 10690 LINEAR A SIGN A356 -// 10691 LINEAR A SIGN A357 -// 10692 LINEAR A SIGN A358 -// 10693 LINEAR A SIGN A359 -// 10694 LINEAR A SIGN A360 -// 10695 LINEAR A SIGN A361 -// 10696 LINEAR A SIGN A362 -// 10697 LINEAR A SIGN A363 -// 10698 LINEAR A SIGN A364 -// 10699 LINEAR A SIGN A365 -// 1069a LINEAR A SIGN A366 -// 1069b LINEAR A SIGN A367 -// 1069c LINEAR A SIGN A368 -// 1069d LINEAR A SIGN A369 -// 1069e LINEAR A SIGN A370 -// 1069f LINEAR A SIGN A371 -// 106a0 LINEAR A SIGN A400-VAS -// 106a1 LINEAR A SIGN A401-VAS -// 106a2 LINEAR A SIGN A402-VAS -// 106a3 LINEAR A SIGN A403-VAS -// 106a4 LINEAR A SIGN A404-VAS -// 106a5 LINEAR A SIGN A405-VAS -// 106a6 LINEAR A SIGN A406-VAS -// 106a7 LINEAR A SIGN A407-VAS -// 106a8 LINEAR A SIGN A408-VAS -// 106a9 LINEAR A SIGN A409-VAS -// 106aa LINEAR A SIGN A410-VAS -// 106ab LINEAR A SIGN A411-VAS -// 106ac LINEAR A SIGN A412-VAS -// 106ad LINEAR A SIGN A413-VAS -// 106ae LINEAR A SIGN A414-VAS -// 106af LINEAR A SIGN A415-VAS -// 106b0 LINEAR A SIGN A416-VAS -// 106b1 LINEAR A SIGN A417-VAS -// 106b2 LINEAR A SIGN A418-VAS -// 106b3 LINEAR A SIGN A501 -// 106b4 LINEAR A SIGN A502 -// 106b5 LINEAR A SIGN A503 -// 106b6 LINEAR A SIGN A504 -// 106b7 LINEAR A SIGN A505 -// 106b8 LINEAR A SIGN A506 -// 106b9 LINEAR A SIGN A508 -// 106ba LINEAR A SIGN A509 -// 106bb LINEAR A SIGN A510 -// 106bc LINEAR A SIGN A511 -// 106bd LINEAR A SIGN A512 -// 106be LINEAR A SIGN A513 -// 106bf LINEAR A SIGN A515 -// 106c0 LINEAR A SIGN A516 -// 106c1 LINEAR A SIGN A520 -// 106c2 LINEAR A SIGN A521 -// 106c3 LINEAR A SIGN A523 -// 106c4 LINEAR A SIGN A524 -// 106c5 LINEAR A SIGN A525 -// 106c6 LINEAR A SIGN A526 -// 106c7 LINEAR A SIGN A527 -// 106c8 LINEAR A SIGN A528 -// 106c9 LINEAR A SIGN A529 -// 106ca LINEAR A SIGN A530 -// 106cb LINEAR A SIGN A531 -// 106cc LINEAR A SIGN A532 -// 106cd LINEAR A SIGN A534 -// 106ce LINEAR A SIGN A535 -// 106cf LINEAR A SIGN A536 -// 106d0 LINEAR A SIGN A537 -// 106d1 LINEAR A SIGN A538 -// 106d2 LINEAR A SIGN A539 -// 106d3 LINEAR A SIGN A540 -// 106d4 LINEAR A SIGN A541 -// 106d5 LINEAR A SIGN A542 -// 106d6 LINEAR A SIGN A545 -// 106d7 LINEAR A SIGN A547 -// 106d8 LINEAR A SIGN A548 -// 106d9 LINEAR A SIGN A549 -// 106da LINEAR A SIGN A550 -// 106db LINEAR A SIGN A551 -// 106dc LINEAR A SIGN A552 -// 106dd LINEAR A SIGN A553 -// 106de LINEAR A SIGN A554 -// 106df LINEAR A SIGN A555 -// 106e0 LINEAR A SIGN A556 -// 106e1 LINEAR A SIGN A557 -// 106e2 LINEAR A SIGN A559 -// 106e3 LINEAR A SIGN A563 -// 106e4 LINEAR A SIGN A564 -// 106e5 LINEAR A SIGN A565 -// 106e6 LINEAR A SIGN A566 -// 106e7 LINEAR A SIGN A568 -// 106e8 LINEAR A SIGN A569 -// 106e9 LINEAR A SIGN A570 -// 106ea LINEAR A SIGN A571 -// 106eb LINEAR A SIGN A572 -// 106ec LINEAR A SIGN A573 -// 106ed LINEAR A SIGN A574 -// 106ee LINEAR A SIGN A575 -// 106ef LINEAR A SIGN A576 -// 106f0 LINEAR A SIGN A577 -// 106f1 LINEAR A SIGN A578 -// 106f2 LINEAR A SIGN A579 -// 106f3 LINEAR A SIGN A580 -// 106f4 LINEAR A SIGN A581 -// 106f5 LINEAR A SIGN A582 -// 106f6 LINEAR A SIGN A583 -// 106f7 LINEAR A SIGN A584 -// 106f8 LINEAR A SIGN A585 -// 106f9 LINEAR A SIGN A586 -// 106fa LINEAR A SIGN A587 -// 106fb LINEAR A SIGN A588 -// 106fc LINEAR A SIGN A589 -// 106fd LINEAR A SIGN A591 -// 106fe LINEAR A SIGN A592 -// 106ff LINEAR A SIGN A594 -// 10700 LINEAR A SIGN A595 -// 10701 LINEAR A SIGN A596 -// 10702 LINEAR A SIGN A598 -// 10703 LINEAR A SIGN A600 -// 10704 LINEAR A SIGN A601 -// 10705 LINEAR A SIGN A602 -// 10706 LINEAR A SIGN A603 -// 10707 LINEAR A SIGN A604 -// 10708 LINEAR A SIGN A606 -// 10709 LINEAR A SIGN A608 -// 1070a LINEAR A SIGN A609 -// 1070b LINEAR A SIGN A610 -// 1070c LINEAR A SIGN A611 -// 1070d LINEAR A SIGN A612 -// 1070e LINEAR A SIGN A613 -// 1070f LINEAR A SIGN A614 -// 10710 LINEAR A SIGN A615 -// 10711 LINEAR A SIGN A616 -// 10712 LINEAR A SIGN A617 -// 10713 LINEAR A SIGN A618 -// 10714 LINEAR A SIGN A619 -// 10715 LINEAR A SIGN A620 -// 10716 LINEAR A SIGN A621 -// 10717 LINEAR A SIGN A622 -// 10718 LINEAR A SIGN A623 -// 10719 LINEAR A SIGN A624 -// 1071a LINEAR A SIGN A626 -// 1071b LINEAR A SIGN A627 -// 1071c LINEAR A SIGN A628 -// 1071d LINEAR A SIGN A629 -// 1071e LINEAR A SIGN A634 -// 1071f LINEAR A SIGN A637 -// 10720 LINEAR A SIGN A638 -// 10721 LINEAR A SIGN A640 -// 10722 LINEAR A SIGN A642 -// 10723 LINEAR A SIGN A643 -// 10724 LINEAR A SIGN A644 -// 10725 LINEAR A SIGN A645 -// 10726 LINEAR A SIGN A646 -// 10727 LINEAR A SIGN A648 -// 10728 LINEAR A SIGN A649 -// 10729 LINEAR A SIGN A651 -// 1072a LINEAR A SIGN A652 -// 1072b LINEAR A SIGN A653 -// 1072c LINEAR A SIGN A654 -// 1072d LINEAR A SIGN A655 -// 1072e LINEAR A SIGN A656 -// 1072f LINEAR A SIGN A657 -// 10730 LINEAR A SIGN A658 -// 10731 LINEAR A SIGN A659 -// 10732 LINEAR A SIGN A660 -// 10733 LINEAR A SIGN A661 -// 10734 LINEAR A SIGN A662 -// 10735 LINEAR A SIGN A663 -// 10736 LINEAR A SIGN A664 - { 0x10600, 0x137, 0x9, 0, 0 }, -// 10740 LINEAR A SIGN A701 A -// 10741 LINEAR A SIGN A702 B -// 10742 LINEAR A SIGN A703 D -// 10743 LINEAR A SIGN A704 E -// 10744 LINEAR A SIGN A705 F -// 10745 LINEAR A SIGN A706 H -// 10746 LINEAR A SIGN A707 J -// 10747 LINEAR A SIGN A708 K -// 10748 LINEAR A SIGN A709 L -// 10749 LINEAR A SIGN A709-2 L2 -// 1074a LINEAR A SIGN A709-3 L3 -// 1074b LINEAR A SIGN A709-4 L4 -// 1074c LINEAR A SIGN A709-6 L6 -// 1074d LINEAR A SIGN A710 W -// 1074e LINEAR A SIGN A711 X -// 1074f LINEAR A SIGN A712 Y -// 10750 LINEAR A SIGN A713 OMEGA -// 10751 LINEAR A SIGN A714 ABB -// 10752 LINEAR A SIGN A715 BB -// 10753 LINEAR A SIGN A717 DD -// 10754 LINEAR A SIGN A726 EYYY -// 10755 LINEAR A SIGN A732 JE - { 0x10740, 0x16, 0x9, 0, 0 }, -// 10760 LINEAR A SIGN A800 -// 10761 LINEAR A SIGN A801 -// 10762 LINEAR A SIGN A802 -// 10763 LINEAR A SIGN A803 -// 10764 LINEAR A SIGN A804 -// 10765 LINEAR A SIGN A805 -// 10766 LINEAR A SIGN A806 -// 10767 LINEAR A SIGN A807 - { 0x10760, 0x8, 0x9, 0, 0 }, -// 10800 CYPRIOT SYLLABLE A -// 10801 CYPRIOT SYLLABLE E -// 10802 CYPRIOT SYLLABLE I -// 10803 CYPRIOT SYLLABLE O -// 10804 CYPRIOT SYLLABLE U -// 10805 CYPRIOT SYLLABLE JA - { 0x10800, 0x6, 0x9, 0, 0 }, -// 10808 CYPRIOT SYLLABLE JO - { 0x10808, 0x1, 0x9, 0, 0 }, -// 1080a CYPRIOT SYLLABLE KA -// 1080b CYPRIOT SYLLABLE KE -// 1080c CYPRIOT SYLLABLE KI -// 1080d CYPRIOT SYLLABLE KO -// 1080e CYPRIOT SYLLABLE KU -// 1080f CYPRIOT SYLLABLE LA -// 10810 CYPRIOT SYLLABLE LE -// 10811 CYPRIOT SYLLABLE LI -// 10812 CYPRIOT SYLLABLE LO -// 10813 CYPRIOT SYLLABLE LU -// 10814 CYPRIOT SYLLABLE MA -// 10815 CYPRIOT SYLLABLE ME -// 10816 CYPRIOT SYLLABLE MI -// 10817 CYPRIOT SYLLABLE MO -// 10818 CYPRIOT SYLLABLE MU -// 10819 CYPRIOT SYLLABLE NA -// 1081a CYPRIOT SYLLABLE NE -// 1081b CYPRIOT SYLLABLE NI -// 1081c CYPRIOT SYLLABLE NO -// 1081d CYPRIOT SYLLABLE NU -// 1081e CYPRIOT SYLLABLE PA -// 1081f CYPRIOT SYLLABLE PE -// 10820 CYPRIOT SYLLABLE PI -// 10821 CYPRIOT SYLLABLE PO -// 10822 CYPRIOT SYLLABLE PU -// 10823 CYPRIOT SYLLABLE RA -// 10824 CYPRIOT SYLLABLE RE -// 10825 CYPRIOT SYLLABLE RI -// 10826 CYPRIOT SYLLABLE RO -// 10827 CYPRIOT SYLLABLE RU -// 10828 CYPRIOT SYLLABLE SA -// 10829 CYPRIOT SYLLABLE SE -// 1082a CYPRIOT SYLLABLE SI -// 1082b CYPRIOT SYLLABLE SO -// 1082c CYPRIOT SYLLABLE SU -// 1082d CYPRIOT SYLLABLE TA -// 1082e CYPRIOT SYLLABLE TE -// 1082f CYPRIOT SYLLABLE TI -// 10830 CYPRIOT SYLLABLE TO -// 10831 CYPRIOT SYLLABLE TU -// 10832 CYPRIOT SYLLABLE WA -// 10833 CYPRIOT SYLLABLE WE -// 10834 CYPRIOT SYLLABLE WI -// 10835 CYPRIOT SYLLABLE WO - { 0x1080A, 0x2C, 0x9, 0, 0 }, -// 10837 CYPRIOT SYLLABLE XA -// 10838 CYPRIOT SYLLABLE XE - { 0x10837, 0x2, 0x9, 0, 0 }, -// 1083c CYPRIOT SYLLABLE ZA - { 0x1083C, 0x1, 0x9, 0, 0 }, -// 1083f CYPRIOT SYLLABLE ZO -// 10840 IMPERIAL ARAMAIC LETTER ALEPH -// 10841 IMPERIAL ARAMAIC LETTER BETH -// 10842 IMPERIAL ARAMAIC LETTER GIMEL -// 10843 IMPERIAL ARAMAIC LETTER DALETH -// 10844 IMPERIAL ARAMAIC LETTER HE -// 10845 IMPERIAL ARAMAIC LETTER WAW -// 10846 IMPERIAL ARAMAIC LETTER ZAYIN -// 10847 IMPERIAL ARAMAIC LETTER HETH -// 10848 IMPERIAL ARAMAIC LETTER TETH -// 10849 IMPERIAL ARAMAIC LETTER YODH -// 1084a IMPERIAL ARAMAIC LETTER KAPH -// 1084b IMPERIAL ARAMAIC LETTER LAMEDH -// 1084c IMPERIAL ARAMAIC LETTER MEM -// 1084d IMPERIAL ARAMAIC LETTER NUN -// 1084e IMPERIAL ARAMAIC LETTER SAMEKH -// 1084f IMPERIAL ARAMAIC LETTER AYIN -// 10850 IMPERIAL ARAMAIC LETTER PE -// 10851 IMPERIAL ARAMAIC LETTER SADHE -// 10852 IMPERIAL ARAMAIC LETTER QOPH -// 10853 IMPERIAL ARAMAIC LETTER RESH -// 10854 IMPERIAL ARAMAIC LETTER SHIN -// 10855 IMPERIAL ARAMAIC LETTER TAW - { 0x1083F, 0x17, 0x9, 0, 0 }, -// 10857 IMPERIAL ARAMAIC SECTION SIGN - { 0x10857, 0x1, 0x18, 0, 0 }, -// 10858 IMPERIAL ARAMAIC NUMBER ONE -// 10859 IMPERIAL ARAMAIC NUMBER TWO -// 1085a IMPERIAL ARAMAIC NUMBER THREE -// 1085b IMPERIAL ARAMAIC NUMBER TEN -// 1085c IMPERIAL ARAMAIC NUMBER TWENTY -// 1085d IMPERIAL ARAMAIC NUMBER ONE HUNDRED -// 1085e IMPERIAL ARAMAIC NUMBER ONE THOUSAND -// 1085f IMPERIAL ARAMAIC NUMBER TEN THOUSAND - { 0x10858, 0x8, 0x8, 0, 0 }, -// 10860 PALMYRENE LETTER ALEPH -// 10861 PALMYRENE LETTER BETH -// 10862 PALMYRENE LETTER GIMEL -// 10863 PALMYRENE LETTER DALETH -// 10864 PALMYRENE LETTER HE -// 10865 PALMYRENE LETTER WAW -// 10866 PALMYRENE LETTER ZAYIN -// 10867 PALMYRENE LETTER HETH -// 10868 PALMYRENE LETTER TETH -// 10869 PALMYRENE LETTER YODH -// 1086a PALMYRENE LETTER KAPH -// 1086b PALMYRENE LETTER LAMEDH -// 1086c PALMYRENE LETTER MEM -// 1086d PALMYRENE LETTER FINAL NUN -// 1086e PALMYRENE LETTER NUN -// 1086f PALMYRENE LETTER SAMEKH -// 10870 PALMYRENE LETTER AYIN -// 10871 PALMYRENE LETTER PE -// 10872 PALMYRENE LETTER SADHE -// 10873 PALMYRENE LETTER QOPH -// 10874 PALMYRENE LETTER RESH -// 10875 PALMYRENE LETTER SHIN -// 10876 PALMYRENE LETTER TAW - { 0x10860, 0x17, 0x9, 0, 0 }, -// 10877 PALMYRENE LEFT-POINTING FLEURON -// 10878 PALMYRENE RIGHT-POINTING FLEURON -// 10879 PALMYRENE NUMBER ONE -// 1087a PALMYRENE NUMBER TWO -// 1087b PALMYRENE NUMBER THREE -// 1087c PALMYRENE NUMBER FOUR -// 1087d PALMYRENE NUMBER FIVE -// 1087e PALMYRENE NUMBER TEN -// 1087f PALMYRENE NUMBER TWENTY - { 0x10877, 0x9, 0x8, 0, 0 }, -// 10880 NABATAEAN LETTER FINAL ALEPH -// 10881 NABATAEAN LETTER ALEPH -// 10882 NABATAEAN LETTER FINAL BETH -// 10883 NABATAEAN LETTER BETH -// 10884 NABATAEAN LETTER GIMEL -// 10885 NABATAEAN LETTER DALETH -// 10886 NABATAEAN LETTER FINAL HE -// 10887 NABATAEAN LETTER HE -// 10888 NABATAEAN LETTER WAW -// 10889 NABATAEAN LETTER ZAYIN -// 1088a NABATAEAN LETTER HETH -// 1088b NABATAEAN LETTER TETH -// 1088c NABATAEAN LETTER FINAL YODH -// 1088d NABATAEAN LETTER YODH -// 1088e NABATAEAN LETTER FINAL KAPH -// 1088f NABATAEAN LETTER KAPH -// 10890 NABATAEAN LETTER FINAL LAMEDH -// 10891 NABATAEAN LETTER LAMEDH -// 10892 NABATAEAN LETTER FINAL MEM -// 10893 NABATAEAN LETTER MEM -// 10894 NABATAEAN LETTER FINAL NUN -// 10895 NABATAEAN LETTER NUN -// 10896 NABATAEAN LETTER SAMEKH -// 10897 NABATAEAN LETTER AYIN -// 10898 NABATAEAN LETTER PE -// 10899 NABATAEAN LETTER SADHE -// 1089a NABATAEAN LETTER QOPH -// 1089b NABATAEAN LETTER RESH -// 1089c NABATAEAN LETTER FINAL SHIN -// 1089d NABATAEAN LETTER SHIN -// 1089e NABATAEAN LETTER TAW - { 0x10880, 0x1F, 0x9, 0, 0 }, -// 108a7 NABATAEAN NUMBER ONE -// 108a8 NABATAEAN NUMBER TWO -// 108a9 NABATAEAN NUMBER THREE -// 108aa NABATAEAN NUMBER FOUR -// 108ab NABATAEAN CRUCIFORM NUMBER FOUR -// 108ac NABATAEAN NUMBER FIVE -// 108ad NABATAEAN NUMBER TEN -// 108ae NABATAEAN NUMBER TWENTY -// 108af NABATAEAN NUMBER ONE HUNDRED - { 0x108A7, 0x9, 0x8, 0, 0 }, -// 10900 PHOENICIAN LETTER ALF -// 10901 PHOENICIAN LETTER BET -// 10902 PHOENICIAN LETTER GAML -// 10903 PHOENICIAN LETTER DELT -// 10904 PHOENICIAN LETTER HE -// 10905 PHOENICIAN LETTER WAU -// 10906 PHOENICIAN LETTER ZAI -// 10907 PHOENICIAN LETTER HET -// 10908 PHOENICIAN LETTER TET -// 10909 PHOENICIAN LETTER YOD -// 1090a PHOENICIAN LETTER KAF -// 1090b PHOENICIAN LETTER LAMD -// 1090c PHOENICIAN LETTER MEM -// 1090d PHOENICIAN LETTER NUN -// 1090e PHOENICIAN LETTER SEMK -// 1090f PHOENICIAN LETTER AIN -// 10910 PHOENICIAN LETTER PE -// 10911 PHOENICIAN LETTER SADE -// 10912 PHOENICIAN LETTER QOF -// 10913 PHOENICIAN LETTER ROSH -// 10914 PHOENICIAN LETTER SHIN -// 10915 PHOENICIAN LETTER TAU - { 0x10900, 0x16, 0x9, 0, 0 }, -// 10916 PHOENICIAN NUMBER ONE -// 10917 PHOENICIAN NUMBER TEN -// 10918 PHOENICIAN NUMBER TWENTY -// 10919 PHOENICIAN NUMBER ONE HUNDRED -// 1091a PHOENICIAN NUMBER TWO -// 1091b PHOENICIAN NUMBER THREE - { 0x10916, 0x6, 0x8, 0, 0 }, -// 1091f PHOENICIAN WORD SEPARATOR - { 0x1091F, 0x1, 0x18, 0, 0 }, -// 10920 LYDIAN LETTER A -// 10921 LYDIAN LETTER B -// 10922 LYDIAN LETTER G -// 10923 LYDIAN LETTER D -// 10924 LYDIAN LETTER E -// 10925 LYDIAN LETTER V -// 10926 LYDIAN LETTER I -// 10927 LYDIAN LETTER Y -// 10928 LYDIAN LETTER K -// 10929 LYDIAN LETTER L -// 1092a LYDIAN LETTER M -// 1092b LYDIAN LETTER N -// 1092c LYDIAN LETTER O -// 1092d LYDIAN LETTER R -// 1092e LYDIAN LETTER SS -// 1092f LYDIAN LETTER T -// 10930 LYDIAN LETTER U -// 10931 LYDIAN LETTER F -// 10932 LYDIAN LETTER Q -// 10933 LYDIAN LETTER S -// 10934 LYDIAN LETTER TT -// 10935 LYDIAN LETTER AN -// 10936 LYDIAN LETTER EN -// 10937 LYDIAN LETTER LY -// 10938 LYDIAN LETTER NN -// 10939 LYDIAN LETTER C - { 0x10920, 0x1A, 0x9, 0, 0 }, -// 1093f LYDIAN TRIANGULAR MARK - { 0x1093F, 0x1, 0x18, 0, 0 }, -// 10980 MEROITIC HIEROGLYPHIC LETTER A -// 10981 MEROITIC HIEROGLYPHIC LETTER E -// 10982 MEROITIC HIEROGLYPHIC LETTER I -// 10983 MEROITIC HIEROGLYPHIC LETTER O -// 10984 MEROITIC HIEROGLYPHIC LETTER YA -// 10985 MEROITIC HIEROGLYPHIC LETTER WA -// 10986 MEROITIC HIEROGLYPHIC LETTER BA -// 10987 MEROITIC HIEROGLYPHIC LETTER BA-2 -// 10988 MEROITIC HIEROGLYPHIC LETTER PA -// 10989 MEROITIC HIEROGLYPHIC LETTER MA -// 1098a MEROITIC HIEROGLYPHIC LETTER NA -// 1098b MEROITIC HIEROGLYPHIC LETTER NA-2 -// 1098c MEROITIC HIEROGLYPHIC LETTER NE -// 1098d MEROITIC HIEROGLYPHIC LETTER NE-2 -// 1098e MEROITIC HIEROGLYPHIC LETTER RA -// 1098f MEROITIC HIEROGLYPHIC LETTER RA-2 -// 10990 MEROITIC HIEROGLYPHIC LETTER LA -// 10991 MEROITIC HIEROGLYPHIC LETTER KHA -// 10992 MEROITIC HIEROGLYPHIC LETTER HHA -// 10993 MEROITIC HIEROGLYPHIC LETTER SA -// 10994 MEROITIC HIEROGLYPHIC LETTER SA-2 -// 10995 MEROITIC HIEROGLYPHIC LETTER SE -// 10996 MEROITIC HIEROGLYPHIC LETTER KA -// 10997 MEROITIC HIEROGLYPHIC LETTER QA -// 10998 MEROITIC HIEROGLYPHIC LETTER TA -// 10999 MEROITIC HIEROGLYPHIC LETTER TA-2 -// 1099a MEROITIC HIEROGLYPHIC LETTER TE -// 1099b MEROITIC HIEROGLYPHIC LETTER TE-2 -// 1099c MEROITIC HIEROGLYPHIC LETTER TO -// 1099d MEROITIC HIEROGLYPHIC LETTER DA -// 1099e MEROITIC HIEROGLYPHIC SYMBOL VIDJ -// 1099f MEROITIC HIEROGLYPHIC SYMBOL VIDJ-2 -// 109a0 MEROITIC CURSIVE LETTER A -// 109a1 MEROITIC CURSIVE LETTER E -// 109a2 MEROITIC CURSIVE LETTER I -// 109a3 MEROITIC CURSIVE LETTER O -// 109a4 MEROITIC CURSIVE LETTER YA -// 109a5 MEROITIC CURSIVE LETTER WA -// 109a6 MEROITIC CURSIVE LETTER BA -// 109a7 MEROITIC CURSIVE LETTER PA -// 109a8 MEROITIC CURSIVE LETTER MA -// 109a9 MEROITIC CURSIVE LETTER NA -// 109aa MEROITIC CURSIVE LETTER NE -// 109ab MEROITIC CURSIVE LETTER RA -// 109ac MEROITIC CURSIVE LETTER LA -// 109ad MEROITIC CURSIVE LETTER KHA -// 109ae MEROITIC CURSIVE LETTER HHA -// 109af MEROITIC CURSIVE LETTER SA -// 109b0 MEROITIC CURSIVE LETTER ARCHAIC SA -// 109b1 MEROITIC CURSIVE LETTER SE -// 109b2 MEROITIC CURSIVE LETTER KA -// 109b3 MEROITIC CURSIVE LETTER QA -// 109b4 MEROITIC CURSIVE LETTER TA -// 109b5 MEROITIC CURSIVE LETTER TE -// 109b6 MEROITIC CURSIVE LETTER TO -// 109b7 MEROITIC CURSIVE LETTER DA - { 0x10980, 0x38, 0x9, 0, 0 }, -// 109be MEROITIC CURSIVE LOGOGRAM RMT -// 109bf MEROITIC CURSIVE LOGOGRAM IMN - { 0x109BE, 0x2, 0x9, 0, 0 }, -// 10a00 KHAROSHTHI LETTER A - { 0x10A00, 0x1, 0x9, 0, 0 }, -// 10a01 KHAROSHTHI VOWEL SIGN I -// 10a02 KHAROSHTHI VOWEL SIGN U -// 10a03 KHAROSHTHI VOWEL SIGN VOCALIC R - { 0x10A01, 0x3, 0x0, 0, 0 }, -// 10a05 KHAROSHTHI VOWEL SIGN E -// 10a06 KHAROSHTHI VOWEL SIGN O - { 0x10A05, 0x2, 0x0, 0, 0 }, -// 10a0c KHAROSHTHI VOWEL LENGTH MARK -// 10a0d KHAROSHTHI SIGN DOUBLE RING BELOW -// 10a0e KHAROSHTHI SIGN ANUSVARA -// 10a0f KHAROSHTHI SIGN VISARGA - { 0x10A0C, 0x4, 0x0, 0, 0 }, -// 10a10 KHAROSHTHI LETTER KA -// 10a11 KHAROSHTHI LETTER KHA -// 10a12 KHAROSHTHI LETTER GA -// 10a13 KHAROSHTHI LETTER GHA - { 0x10A10, 0x4, 0x9, 0, 0 }, -// 10a15 KHAROSHTHI LETTER CA -// 10a16 KHAROSHTHI LETTER CHA -// 10a17 KHAROSHTHI LETTER JA - { 0x10A15, 0x3, 0x9, 0, 0 }, -// 10a19 KHAROSHTHI LETTER NYA -// 10a1a KHAROSHTHI LETTER TTA -// 10a1b KHAROSHTHI LETTER TTHA -// 10a1c KHAROSHTHI LETTER DDA -// 10a1d KHAROSHTHI LETTER DDHA -// 10a1e KHAROSHTHI LETTER NNA -// 10a1f KHAROSHTHI LETTER TA -// 10a20 KHAROSHTHI LETTER THA -// 10a21 KHAROSHTHI LETTER DA -// 10a22 KHAROSHTHI LETTER DHA -// 10a23 KHAROSHTHI LETTER NA -// 10a24 KHAROSHTHI LETTER PA -// 10a25 KHAROSHTHI LETTER PHA -// 10a26 KHAROSHTHI LETTER BA -// 10a27 KHAROSHTHI LETTER BHA -// 10a28 KHAROSHTHI LETTER MA -// 10a29 KHAROSHTHI LETTER YA -// 10a2a KHAROSHTHI LETTER RA -// 10a2b KHAROSHTHI LETTER LA -// 10a2c KHAROSHTHI LETTER VA -// 10a2d KHAROSHTHI LETTER SHA -// 10a2e KHAROSHTHI LETTER SSA -// 10a2f KHAROSHTHI LETTER SA -// 10a30 KHAROSHTHI LETTER ZA -// 10a31 KHAROSHTHI LETTER HA -// 10a32 KHAROSHTHI LETTER KKA -// 10a33 KHAROSHTHI LETTER TTTHA - { 0x10A19, 0x1B, 0x9, 0, 0 }, -// 10a38 KHAROSHTHI SIGN BAR ABOVE -// 10a39 KHAROSHTHI SIGN CAUDA -// 10a3a KHAROSHTHI SIGN DOT BELOW - { 0x10A38, 0x3, 0x0, 0, 0 }, -// 10a3f KHAROSHTHI VIRAMA - { 0x10A3F, 0x1, 0x0, 0, 0 }, -// 10a40 KHAROSHTHI DIGIT ONE -// 10a41 KHAROSHTHI DIGIT TWO -// 10a42 KHAROSHTHI DIGIT THREE -// 10a43 KHAROSHTHI DIGIT FOUR -// 10a44 KHAROSHTHI NUMBER TEN -// 10a45 KHAROSHTHI NUMBER TWENTY -// 10a46 KHAROSHTHI NUMBER ONE HUNDRED -// 10a47 KHAROSHTHI NUMBER ONE THOUSAND - { 0x10A40, 0x8, 0x8, 0, 0 }, -// 10a50 KHAROSHTHI PUNCTUATION DOT -// 10a51 KHAROSHTHI PUNCTUATION SMALL CIRCLE -// 10a52 KHAROSHTHI PUNCTUATION CIRCLE -// 10a53 KHAROSHTHI PUNCTUATION CRESCENT BAR -// 10a54 KHAROSHTHI PUNCTUATION MANGALAM -// 10a55 KHAROSHTHI PUNCTUATION LOTUS -// 10a56 KHAROSHTHI PUNCTUATION DANDA -// 10a57 KHAROSHTHI PUNCTUATION DOUBLE DANDA -// 10a58 KHAROSHTHI PUNCTUATION LINES - { 0x10A50, 0x9, 0x18, 0, 0 }, -// 10a60 OLD SOUTH ARABIAN LETTER HE -// 10a61 OLD SOUTH ARABIAN LETTER LAMEDH -// 10a62 OLD SOUTH ARABIAN LETTER HETH -// 10a63 OLD SOUTH ARABIAN LETTER MEM -// 10a64 OLD SOUTH ARABIAN LETTER QOPH -// 10a65 OLD SOUTH ARABIAN LETTER WAW -// 10a66 OLD SOUTH ARABIAN LETTER SHIN -// 10a67 OLD SOUTH ARABIAN LETTER RESH -// 10a68 OLD SOUTH ARABIAN LETTER BETH -// 10a69 OLD SOUTH ARABIAN LETTER TAW -// 10a6a OLD SOUTH ARABIAN LETTER SAT -// 10a6b OLD SOUTH ARABIAN LETTER KAPH -// 10a6c OLD SOUTH ARABIAN LETTER NUN -// 10a6d OLD SOUTH ARABIAN LETTER KHETH -// 10a6e OLD SOUTH ARABIAN LETTER SADHE -// 10a6f OLD SOUTH ARABIAN LETTER SAMEKH -// 10a70 OLD SOUTH ARABIAN LETTER FE -// 10a71 OLD SOUTH ARABIAN LETTER ALEF -// 10a72 OLD SOUTH ARABIAN LETTER AYN -// 10a73 OLD SOUTH ARABIAN LETTER DHADHE -// 10a74 OLD SOUTH ARABIAN LETTER GIMEL -// 10a75 OLD SOUTH ARABIAN LETTER DALETH -// 10a76 OLD SOUTH ARABIAN LETTER GHAYN -// 10a77 OLD SOUTH ARABIAN LETTER TETH -// 10a78 OLD SOUTH ARABIAN LETTER ZAYN -// 10a79 OLD SOUTH ARABIAN LETTER DHALETH -// 10a7a OLD SOUTH ARABIAN LETTER YODH -// 10a7b OLD SOUTH ARABIAN LETTER THAW -// 10a7c OLD SOUTH ARABIAN LETTER THETH - { 0x10A60, 0x1D, 0x9, 0, 0 }, -// 10a7d OLD SOUTH ARABIAN NUMBER ONE -// 10a7e OLD SOUTH ARABIAN NUMBER FIFTY - { 0x10A7D, 0x2, 0x8, 0, 0 }, -// 10a7f OLD SOUTH ARABIAN NUMERIC INDICATOR - { 0x10A7F, 0x1, 0x18, 0, 0 }, -// 10a80 OLD NORTH ARABIAN LETTER HEH -// 10a81 OLD NORTH ARABIAN LETTER LAM -// 10a82 OLD NORTH ARABIAN LETTER HAH -// 10a83 OLD NORTH ARABIAN LETTER MEEM -// 10a84 OLD NORTH ARABIAN LETTER QAF -// 10a85 OLD NORTH ARABIAN LETTER WAW -// 10a86 OLD NORTH ARABIAN LETTER ES-2 -// 10a87 OLD NORTH ARABIAN LETTER REH -// 10a88 OLD NORTH ARABIAN LETTER BEH -// 10a89 OLD NORTH ARABIAN LETTER TEH -// 10a8a OLD NORTH ARABIAN LETTER ES-1 -// 10a8b OLD NORTH ARABIAN LETTER KAF -// 10a8c OLD NORTH ARABIAN LETTER NOON -// 10a8d OLD NORTH ARABIAN LETTER KHAH -// 10a8e OLD NORTH ARABIAN LETTER SAD -// 10a8f OLD NORTH ARABIAN LETTER ES-3 -// 10a90 OLD NORTH ARABIAN LETTER FEH -// 10a91 OLD NORTH ARABIAN LETTER ALEF -// 10a92 OLD NORTH ARABIAN LETTER AIN -// 10a93 OLD NORTH ARABIAN LETTER DAD -// 10a94 OLD NORTH ARABIAN LETTER GEEM -// 10a95 OLD NORTH ARABIAN LETTER DAL -// 10a96 OLD NORTH ARABIAN LETTER GHAIN -// 10a97 OLD NORTH ARABIAN LETTER TAH -// 10a98 OLD NORTH ARABIAN LETTER ZAIN -// 10a99 OLD NORTH ARABIAN LETTER THAL -// 10a9a OLD NORTH ARABIAN LETTER YEH -// 10a9b OLD NORTH ARABIAN LETTER THEH -// 10a9c OLD NORTH ARABIAN LETTER ZAH - { 0x10A80, 0x1D, 0x9, 0, 0 }, -// 10a9d OLD NORTH ARABIAN NUMBER ONE -// 10a9e OLD NORTH ARABIAN NUMBER TEN -// 10a9f OLD NORTH ARABIAN NUMBER TWENTY - { 0x10A9D, 0x3, 0x8, 0, 0 }, -// 10ac0 MANICHAEAN LETTER ALEPH -// 10ac1 MANICHAEAN LETTER BETH -// 10ac2 MANICHAEAN LETTER BHETH -// 10ac3 MANICHAEAN LETTER GIMEL -// 10ac4 MANICHAEAN LETTER GHIMEL -// 10ac5 MANICHAEAN LETTER DALETH -// 10ac6 MANICHAEAN LETTER HE -// 10ac7 MANICHAEAN LETTER WAW - { 0x10AC0, 0x8, 0x9, 0, 0 }, -// 10ac8 MANICHAEAN SIGN UD - { 0x10AC8, 0x1, 0x8, 0, 0 }, -// 10ac9 MANICHAEAN LETTER ZAYIN -// 10aca MANICHAEAN LETTER ZHAYIN -// 10acb MANICHAEAN LETTER JAYIN -// 10acc MANICHAEAN LETTER JHAYIN -// 10acd MANICHAEAN LETTER HETH -// 10ace MANICHAEAN LETTER TETH -// 10acf MANICHAEAN LETTER YODH -// 10ad0 MANICHAEAN LETTER KAPH -// 10ad1 MANICHAEAN LETTER XAPH -// 10ad2 MANICHAEAN LETTER KHAPH -// 10ad3 MANICHAEAN LETTER LAMEDH -// 10ad4 MANICHAEAN LETTER DHAMEDH -// 10ad5 MANICHAEAN LETTER THAMEDH -// 10ad6 MANICHAEAN LETTER MEM -// 10ad7 MANICHAEAN LETTER NUN -// 10ad8 MANICHAEAN LETTER SAMEKH -// 10ad9 MANICHAEAN LETTER AYIN -// 10ada MANICHAEAN LETTER AAYIN -// 10adb MANICHAEAN LETTER PE -// 10adc MANICHAEAN LETTER FE -// 10add MANICHAEAN LETTER SADHE -// 10ade MANICHAEAN LETTER QOPH -// 10adf MANICHAEAN LETTER XOPH -// 10ae0 MANICHAEAN LETTER QHOPH -// 10ae1 MANICHAEAN LETTER RESH -// 10ae2 MANICHAEAN LETTER SHIN -// 10ae3 MANICHAEAN LETTER SSHIN -// 10ae4 MANICHAEAN LETTER TAW - { 0x10AC9, 0x1C, 0x9, 0, 0 }, -// 10ae5 MANICHAEAN ABBREVIATION MARK ABOVE -// 10ae6 MANICHAEAN ABBREVIATION MARK BELOW - { 0x10AE5, 0x2, 0x0, 0, 0 }, -// 10aeb MANICHAEAN NUMBER ONE -// 10aec MANICHAEAN NUMBER FIVE -// 10aed MANICHAEAN NUMBER TEN -// 10aee MANICHAEAN NUMBER TWENTY -// 10aef MANICHAEAN NUMBER ONE HUNDRED - { 0x10AEB, 0x5, 0x8, 0, 0 }, -// 10af0 MANICHAEAN PUNCTUATION STAR -// 10af1 MANICHAEAN PUNCTUATION FLEURON -// 10af2 MANICHAEAN PUNCTUATION DOUBLE DOT WITHIN DOT -// 10af3 MANICHAEAN PUNCTUATION DOT WITHIN DOT -// 10af4 MANICHAEAN PUNCTUATION DOT -// 10af5 MANICHAEAN PUNCTUATION TWO DOTS -// 10af6 MANICHAEAN PUNCTUATION LINE FILLER - { 0x10AF0, 0x7, 0x18, 0, 0 }, -// 10b00 AVESTAN LETTER A -// 10b01 AVESTAN LETTER AA -// 10b02 AVESTAN LETTER AO -// 10b03 AVESTAN LETTER AAO -// 10b04 AVESTAN LETTER AN -// 10b05 AVESTAN LETTER AAN -// 10b06 AVESTAN LETTER AE -// 10b07 AVESTAN LETTER AEE -// 10b08 AVESTAN LETTER E -// 10b09 AVESTAN LETTER EE -// 10b0a AVESTAN LETTER O -// 10b0b AVESTAN LETTER OO -// 10b0c AVESTAN LETTER I -// 10b0d AVESTAN LETTER II -// 10b0e AVESTAN LETTER U -// 10b0f AVESTAN LETTER UU -// 10b10 AVESTAN LETTER KE -// 10b11 AVESTAN LETTER XE -// 10b12 AVESTAN LETTER XYE -// 10b13 AVESTAN LETTER XVE -// 10b14 AVESTAN LETTER GE -// 10b15 AVESTAN LETTER GGE -// 10b16 AVESTAN LETTER GHE -// 10b17 AVESTAN LETTER CE -// 10b18 AVESTAN LETTER JE -// 10b19 AVESTAN LETTER TE -// 10b1a AVESTAN LETTER THE -// 10b1b AVESTAN LETTER DE -// 10b1c AVESTAN LETTER DHE -// 10b1d AVESTAN LETTER TTE -// 10b1e AVESTAN LETTER PE -// 10b1f AVESTAN LETTER FE -// 10b20 AVESTAN LETTER BE -// 10b21 AVESTAN LETTER BHE -// 10b22 AVESTAN LETTER NGE -// 10b23 AVESTAN LETTER NGYE -// 10b24 AVESTAN LETTER NGVE -// 10b25 AVESTAN LETTER NE -// 10b26 AVESTAN LETTER NYE -// 10b27 AVESTAN LETTER NNE -// 10b28 AVESTAN LETTER ME -// 10b29 AVESTAN LETTER HME -// 10b2a AVESTAN LETTER YYE -// 10b2b AVESTAN LETTER YE -// 10b2c AVESTAN LETTER VE -// 10b2d AVESTAN LETTER RE -// 10b2e AVESTAN LETTER LE -// 10b2f AVESTAN LETTER SE -// 10b30 AVESTAN LETTER ZE -// 10b31 AVESTAN LETTER SHE -// 10b32 AVESTAN LETTER ZHE -// 10b33 AVESTAN LETTER SHYE -// 10b34 AVESTAN LETTER SSHE -// 10b35 AVESTAN LETTER HE - { 0x10B00, 0x36, 0x9, 0, 0 }, -// 10b39 AVESTAN ABBREVIATION MARK -// 10b3a TINY TWO DOTS OVER ONE DOT PUNCTUATION -// 10b3b SMALL TWO DOTS OVER ONE DOT PUNCTUATION -// 10b3c LARGE TWO DOTS OVER ONE DOT PUNCTUATION -// 10b3d LARGE ONE DOT OVER TWO DOTS PUNCTUATION -// 10b3e LARGE TWO RINGS OVER ONE RING PUNCTUATION -// 10b3f LARGE ONE RING OVER TWO RINGS PUNCTUATION - { 0x10B39, 0x7, 0x18, 0, 0 }, -// 10b40 INSCRIPTIONAL PARTHIAN LETTER ALEPH -// 10b41 INSCRIPTIONAL PARTHIAN LETTER BETH -// 10b42 INSCRIPTIONAL PARTHIAN LETTER GIMEL -// 10b43 INSCRIPTIONAL PARTHIAN LETTER DALETH -// 10b44 INSCRIPTIONAL PARTHIAN LETTER HE -// 10b45 INSCRIPTIONAL PARTHIAN LETTER WAW -// 10b46 INSCRIPTIONAL PARTHIAN LETTER ZAYIN -// 10b47 INSCRIPTIONAL PARTHIAN LETTER HETH -// 10b48 INSCRIPTIONAL PARTHIAN LETTER TETH -// 10b49 INSCRIPTIONAL PARTHIAN LETTER YODH -// 10b4a INSCRIPTIONAL PARTHIAN LETTER KAPH -// 10b4b INSCRIPTIONAL PARTHIAN LETTER LAMEDH -// 10b4c INSCRIPTIONAL PARTHIAN LETTER MEM -// 10b4d INSCRIPTIONAL PARTHIAN LETTER NUN -// 10b4e INSCRIPTIONAL PARTHIAN LETTER SAMEKH -// 10b4f INSCRIPTIONAL PARTHIAN LETTER AYIN -// 10b50 INSCRIPTIONAL PARTHIAN LETTER PE -// 10b51 INSCRIPTIONAL PARTHIAN LETTER SADHE -// 10b52 INSCRIPTIONAL PARTHIAN LETTER QOPH -// 10b53 INSCRIPTIONAL PARTHIAN LETTER RESH -// 10b54 INSCRIPTIONAL PARTHIAN LETTER SHIN -// 10b55 INSCRIPTIONAL PARTHIAN LETTER TAW - { 0x10B40, 0x16, 0x9, 0, 0 }, -// 10b58 INSCRIPTIONAL PARTHIAN NUMBER ONE -// 10b59 INSCRIPTIONAL PARTHIAN NUMBER TWO -// 10b5a INSCRIPTIONAL PARTHIAN NUMBER THREE -// 10b5b INSCRIPTIONAL PARTHIAN NUMBER FOUR -// 10b5c INSCRIPTIONAL PARTHIAN NUMBER TEN -// 10b5d INSCRIPTIONAL PARTHIAN NUMBER TWENTY -// 10b5e INSCRIPTIONAL PARTHIAN NUMBER ONE HUNDRED -// 10b5f INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND - { 0x10B58, 0x8, 0x8, 0, 0 }, -// 10b60 INSCRIPTIONAL PAHLAVI LETTER ALEPH -// 10b61 INSCRIPTIONAL PAHLAVI LETTER BETH -// 10b62 INSCRIPTIONAL PAHLAVI LETTER GIMEL -// 10b63 INSCRIPTIONAL PAHLAVI LETTER DALETH -// 10b64 INSCRIPTIONAL PAHLAVI LETTER HE -// 10b65 INSCRIPTIONAL PAHLAVI LETTER WAW-AYIN-RESH -// 10b66 INSCRIPTIONAL PAHLAVI LETTER ZAYIN -// 10b67 INSCRIPTIONAL PAHLAVI LETTER HETH -// 10b68 INSCRIPTIONAL PAHLAVI LETTER TETH -// 10b69 INSCRIPTIONAL PAHLAVI LETTER YODH -// 10b6a INSCRIPTIONAL PAHLAVI LETTER KAPH -// 10b6b INSCRIPTIONAL PAHLAVI LETTER LAMEDH -// 10b6c INSCRIPTIONAL PAHLAVI LETTER MEM-QOPH -// 10b6d INSCRIPTIONAL PAHLAVI LETTER NUN -// 10b6e INSCRIPTIONAL PAHLAVI LETTER SAMEKH -// 10b6f INSCRIPTIONAL PAHLAVI LETTER PE -// 10b70 INSCRIPTIONAL PAHLAVI LETTER SADHE -// 10b71 INSCRIPTIONAL PAHLAVI LETTER SHIN -// 10b72 INSCRIPTIONAL PAHLAVI LETTER TAW - { 0x10B60, 0x13, 0x9, 0, 0 }, -// 10b78 INSCRIPTIONAL PAHLAVI NUMBER ONE -// 10b79 INSCRIPTIONAL PAHLAVI NUMBER TWO -// 10b7a INSCRIPTIONAL PAHLAVI NUMBER THREE -// 10b7b INSCRIPTIONAL PAHLAVI NUMBER FOUR -// 10b7c INSCRIPTIONAL PAHLAVI NUMBER TEN -// 10b7d INSCRIPTIONAL PAHLAVI NUMBER TWENTY -// 10b7e INSCRIPTIONAL PAHLAVI NUMBER ONE HUNDRED -// 10b7f INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND - { 0x10B78, 0x8, 0x8, 0, 0 }, -// 10b80 PSALTER PAHLAVI LETTER ALEPH -// 10b81 PSALTER PAHLAVI LETTER BETH -// 10b82 PSALTER PAHLAVI LETTER GIMEL -// 10b83 PSALTER PAHLAVI LETTER DALETH -// 10b84 PSALTER PAHLAVI LETTER HE -// 10b85 PSALTER PAHLAVI LETTER WAW-AYIN-RESH -// 10b86 PSALTER PAHLAVI LETTER ZAYIN -// 10b87 PSALTER PAHLAVI LETTER HETH -// 10b88 PSALTER PAHLAVI LETTER YODH -// 10b89 PSALTER PAHLAVI LETTER KAPH -// 10b8a PSALTER PAHLAVI LETTER LAMEDH -// 10b8b PSALTER PAHLAVI LETTER MEM-QOPH -// 10b8c PSALTER PAHLAVI LETTER NUN -// 10b8d PSALTER PAHLAVI LETTER SAMEKH -// 10b8e PSALTER PAHLAVI LETTER PE -// 10b8f PSALTER PAHLAVI LETTER SADHE -// 10b90 PSALTER PAHLAVI LETTER SHIN -// 10b91 PSALTER PAHLAVI LETTER TAW - { 0x10B80, 0x12, 0x9, 0, 0 }, -// 10b99 PSALTER PAHLAVI SECTION MARK -// 10b9a PSALTER PAHLAVI TURNED SECTION MARK -// 10b9b PSALTER PAHLAVI FOUR DOTS WITH CROSS -// 10b9c PSALTER PAHLAVI FOUR DOTS WITH DOT - { 0x10B99, 0x4, 0x18, 0, 0 }, -// 10ba9 PSALTER PAHLAVI NUMBER ONE -// 10baa PSALTER PAHLAVI NUMBER TWO -// 10bab PSALTER PAHLAVI NUMBER THREE -// 10bac PSALTER PAHLAVI NUMBER FOUR -// 10bad PSALTER PAHLAVI NUMBER TEN -// 10bae PSALTER PAHLAVI NUMBER TWENTY -// 10baf PSALTER PAHLAVI NUMBER ONE HUNDRED - { 0x10BA9, 0x7, 0x8, 0, 0 }, -// 10c00 OLD TURKIC LETTER ORKHON A -// 10c01 OLD TURKIC LETTER YENISEI A -// 10c02 OLD TURKIC LETTER YENISEI AE -// 10c03 OLD TURKIC LETTER ORKHON I -// 10c04 OLD TURKIC LETTER YENISEI I -// 10c05 OLD TURKIC LETTER YENISEI E -// 10c06 OLD TURKIC LETTER ORKHON O -// 10c07 OLD TURKIC LETTER ORKHON OE -// 10c08 OLD TURKIC LETTER YENISEI OE -// 10c09 OLD TURKIC LETTER ORKHON AB -// 10c0a OLD TURKIC LETTER YENISEI AB -// 10c0b OLD TURKIC LETTER ORKHON AEB -// 10c0c OLD TURKIC LETTER YENISEI AEB -// 10c0d OLD TURKIC LETTER ORKHON AG -// 10c0e OLD TURKIC LETTER YENISEI AG -// 10c0f OLD TURKIC LETTER ORKHON AEG -// 10c10 OLD TURKIC LETTER YENISEI AEG -// 10c11 OLD TURKIC LETTER ORKHON AD -// 10c12 OLD TURKIC LETTER YENISEI AD -// 10c13 OLD TURKIC LETTER ORKHON AED -// 10c14 OLD TURKIC LETTER ORKHON EZ -// 10c15 OLD TURKIC LETTER YENISEI EZ -// 10c16 OLD TURKIC LETTER ORKHON AY -// 10c17 OLD TURKIC LETTER YENISEI AY -// 10c18 OLD TURKIC LETTER ORKHON AEY -// 10c19 OLD TURKIC LETTER YENISEI AEY -// 10c1a OLD TURKIC LETTER ORKHON AEK -// 10c1b OLD TURKIC LETTER YENISEI AEK -// 10c1c OLD TURKIC LETTER ORKHON OEK -// 10c1d OLD TURKIC LETTER YENISEI OEK -// 10c1e OLD TURKIC LETTER ORKHON AL -// 10c1f OLD TURKIC LETTER YENISEI AL -// 10c20 OLD TURKIC LETTER ORKHON AEL -// 10c21 OLD TURKIC LETTER ORKHON ELT -// 10c22 OLD TURKIC LETTER ORKHON EM -// 10c23 OLD TURKIC LETTER ORKHON AN -// 10c24 OLD TURKIC LETTER ORKHON AEN -// 10c25 OLD TURKIC LETTER YENISEI AEN -// 10c26 OLD TURKIC LETTER ORKHON ENT -// 10c27 OLD TURKIC LETTER YENISEI ENT -// 10c28 OLD TURKIC LETTER ORKHON ENC -// 10c29 OLD TURKIC LETTER YENISEI ENC -// 10c2a OLD TURKIC LETTER ORKHON ENY -// 10c2b OLD TURKIC LETTER YENISEI ENY -// 10c2c OLD TURKIC LETTER YENISEI ANG -// 10c2d OLD TURKIC LETTER ORKHON ENG -// 10c2e OLD TURKIC LETTER YENISEI AENG -// 10c2f OLD TURKIC LETTER ORKHON EP -// 10c30 OLD TURKIC LETTER ORKHON OP -// 10c31 OLD TURKIC LETTER ORKHON IC -// 10c32 OLD TURKIC LETTER ORKHON EC -// 10c33 OLD TURKIC LETTER YENISEI EC -// 10c34 OLD TURKIC LETTER ORKHON AQ -// 10c35 OLD TURKIC LETTER YENISEI AQ -// 10c36 OLD TURKIC LETTER ORKHON IQ -// 10c37 OLD TURKIC LETTER YENISEI IQ -// 10c38 OLD TURKIC LETTER ORKHON OQ -// 10c39 OLD TURKIC LETTER YENISEI OQ -// 10c3a OLD TURKIC LETTER ORKHON AR -// 10c3b OLD TURKIC LETTER YENISEI AR -// 10c3c OLD TURKIC LETTER ORKHON AER -// 10c3d OLD TURKIC LETTER ORKHON AS -// 10c3e OLD TURKIC LETTER ORKHON AES -// 10c3f OLD TURKIC LETTER ORKHON ASH -// 10c40 OLD TURKIC LETTER YENISEI ASH -// 10c41 OLD TURKIC LETTER ORKHON ESH -// 10c42 OLD TURKIC LETTER YENISEI ESH -// 10c43 OLD TURKIC LETTER ORKHON AT -// 10c44 OLD TURKIC LETTER YENISEI AT -// 10c45 OLD TURKIC LETTER ORKHON AET -// 10c46 OLD TURKIC LETTER YENISEI AET -// 10c47 OLD TURKIC LETTER ORKHON OT -// 10c48 OLD TURKIC LETTER ORKHON BASH - { 0x10C00, 0x49, 0x9, 0, 0 }, -// 10e60 RUMI DIGIT ONE -// 10e61 RUMI DIGIT TWO -// 10e62 RUMI DIGIT THREE -// 10e63 RUMI DIGIT FOUR -// 10e64 RUMI DIGIT FIVE -// 10e65 RUMI DIGIT SIX -// 10e66 RUMI DIGIT SEVEN -// 10e67 RUMI DIGIT EIGHT -// 10e68 RUMI DIGIT NINE -// 10e69 RUMI NUMBER TEN -// 10e6a RUMI NUMBER TWENTY -// 10e6b RUMI NUMBER THIRTY -// 10e6c RUMI NUMBER FORTY -// 10e6d RUMI NUMBER FIFTY -// 10e6e RUMI NUMBER SIXTY -// 10e6f RUMI NUMBER SEVENTY -// 10e70 RUMI NUMBER EIGHTY -// 10e71 RUMI NUMBER NINETY -// 10e72 RUMI NUMBER ONE HUNDRED -// 10e73 RUMI NUMBER TWO HUNDRED -// 10e74 RUMI NUMBER THREE HUNDRED -// 10e75 RUMI NUMBER FOUR HUNDRED -// 10e76 RUMI NUMBER FIVE HUNDRED -// 10e77 RUMI NUMBER SIX HUNDRED -// 10e78 RUMI NUMBER SEVEN HUNDRED -// 10e79 RUMI NUMBER EIGHT HUNDRED -// 10e7a RUMI NUMBER NINE HUNDRED -// 10e7b RUMI FRACTION ONE HALF -// 10e7c RUMI FRACTION ONE QUARTER -// 10e7d RUMI FRACTION ONE THIRD -// 10e7e RUMI FRACTION TWO THIRDS - { 0x10E60, 0x1F, 0x8, 0, 0 }, -// 11000 BRAHMI SIGN CANDRABINDU -// 11001 BRAHMI SIGN ANUSVARA -// 11002 BRAHMI SIGN VISARGA - { 0x11000, 0x3, 0x0, 0, 0 }, -// 11003 BRAHMI SIGN JIHVAMULIYA -// 11004 BRAHMI SIGN UPADHMANIYA -// 11005 BRAHMI LETTER A -// 11006 BRAHMI LETTER AA -// 11007 BRAHMI LETTER I -// 11008 BRAHMI LETTER II -// 11009 BRAHMI LETTER U -// 1100a BRAHMI LETTER UU -// 1100b BRAHMI LETTER VOCALIC R -// 1100c BRAHMI LETTER VOCALIC RR -// 1100d BRAHMI LETTER VOCALIC L -// 1100e BRAHMI LETTER VOCALIC LL -// 1100f BRAHMI LETTER E -// 11010 BRAHMI LETTER AI -// 11011 BRAHMI LETTER O -// 11012 BRAHMI LETTER AU -// 11013 BRAHMI LETTER KA -// 11014 BRAHMI LETTER KHA -// 11015 BRAHMI LETTER GA -// 11016 BRAHMI LETTER GHA -// 11017 BRAHMI LETTER NGA -// 11018 BRAHMI LETTER CA -// 11019 BRAHMI LETTER CHA -// 1101a BRAHMI LETTER JA -// 1101b BRAHMI LETTER JHA -// 1101c BRAHMI LETTER NYA -// 1101d BRAHMI LETTER TTA -// 1101e BRAHMI LETTER TTHA -// 1101f BRAHMI LETTER DDA -// 11020 BRAHMI LETTER DDHA -// 11021 BRAHMI LETTER NNA -// 11022 BRAHMI LETTER TA -// 11023 BRAHMI LETTER THA -// 11024 BRAHMI LETTER DA -// 11025 BRAHMI LETTER DHA -// 11026 BRAHMI LETTER NA -// 11027 BRAHMI LETTER PA -// 11028 BRAHMI LETTER PHA -// 11029 BRAHMI LETTER BA -// 1102a BRAHMI LETTER BHA -// 1102b BRAHMI LETTER MA -// 1102c BRAHMI LETTER YA -// 1102d BRAHMI LETTER RA -// 1102e BRAHMI LETTER LA -// 1102f BRAHMI LETTER VA -// 11030 BRAHMI LETTER SHA -// 11031 BRAHMI LETTER SSA -// 11032 BRAHMI LETTER SA -// 11033 BRAHMI LETTER HA -// 11034 BRAHMI LETTER LLA -// 11035 BRAHMI LETTER OLD TAMIL LLLA -// 11036 BRAHMI LETTER OLD TAMIL RRA -// 11037 BRAHMI LETTER OLD TAMIL NNNA - { 0x11003, 0x35, 0x9, 0, 0 }, -// 11038 BRAHMI VOWEL SIGN AA -// 11039 BRAHMI VOWEL SIGN BHATTIPROLU AA -// 1103a BRAHMI VOWEL SIGN I -// 1103b BRAHMI VOWEL SIGN II -// 1103c BRAHMI VOWEL SIGN U -// 1103d BRAHMI VOWEL SIGN UU -// 1103e BRAHMI VOWEL SIGN VOCALIC R -// 1103f BRAHMI VOWEL SIGN VOCALIC RR -// 11040 BRAHMI VOWEL SIGN VOCALIC L -// 11041 BRAHMI VOWEL SIGN VOCALIC LL -// 11042 BRAHMI VOWEL SIGN E -// 11043 BRAHMI VOWEL SIGN AI -// 11044 BRAHMI VOWEL SIGN O -// 11045 BRAHMI VOWEL SIGN AU -// 11046 BRAHMI VIRAMA - { 0x11038, 0xF, 0x0, 0, 0 }, -// 11047 BRAHMI DANDA -// 11048 BRAHMI DOUBLE DANDA -// 11049 BRAHMI PUNCTUATION DOT -// 1104a BRAHMI PUNCTUATION DOUBLE DOT -// 1104b BRAHMI PUNCTUATION LINE -// 1104c BRAHMI PUNCTUATION CRESCENT BAR -// 1104d BRAHMI PUNCTUATION LOTUS - { 0x11047, 0x7, 0x18, 0, 0 }, -// 11052 BRAHMI NUMBER ONE -// 11053 BRAHMI NUMBER TWO -// 11054 BRAHMI NUMBER THREE -// 11055 BRAHMI NUMBER FOUR -// 11056 BRAHMI NUMBER FIVE -// 11057 BRAHMI NUMBER SIX -// 11058 BRAHMI NUMBER SEVEN -// 11059 BRAHMI NUMBER EIGHT -// 1105a BRAHMI NUMBER NINE -// 1105b BRAHMI NUMBER TEN -// 1105c BRAHMI NUMBER TWENTY -// 1105d BRAHMI NUMBER THIRTY -// 1105e BRAHMI NUMBER FORTY -// 1105f BRAHMI NUMBER FIFTY -// 11060 BRAHMI NUMBER SIXTY -// 11061 BRAHMI NUMBER SEVENTY -// 11062 BRAHMI NUMBER EIGHTY -// 11063 BRAHMI NUMBER NINETY -// 11064 BRAHMI NUMBER ONE HUNDRED -// 11065 BRAHMI NUMBER ONE THOUSAND - { 0x11052, 0x14, 0x8, 0, 0 }, -// 11066 BRAHMI DIGIT ZERO -// 11067 BRAHMI DIGIT ONE -// 11068 BRAHMI DIGIT TWO -// 11069 BRAHMI DIGIT THREE -// 1106a BRAHMI DIGIT FOUR -// 1106b BRAHMI DIGIT FIVE -// 1106c BRAHMI DIGIT SIX -// 1106d BRAHMI DIGIT SEVEN -// 1106e BRAHMI DIGIT EIGHT -// 1106f BRAHMI DIGIT NINE - { 0x11066, 0xA, 0x108, 0, 0 }, -// 1107f BRAHMI NUMBER JOINER -// 11080 KAITHI SIGN CANDRABINDU -// 11081 KAITHI SIGN ANUSVARA -// 11082 KAITHI SIGN VISARGA - { 0x1107F, 0x4, 0x0, 0, 0 }, -// 11083 KAITHI LETTER A -// 11084 KAITHI LETTER AA -// 11085 KAITHI LETTER I -// 11086 KAITHI LETTER II -// 11087 KAITHI LETTER U -// 11088 KAITHI LETTER UU -// 11089 KAITHI LETTER E -// 1108a KAITHI LETTER AI -// 1108b KAITHI LETTER O -// 1108c KAITHI LETTER AU -// 1108d KAITHI LETTER KA -// 1108e KAITHI LETTER KHA -// 1108f KAITHI LETTER GA -// 11090 KAITHI LETTER GHA -// 11091 KAITHI LETTER NGA -// 11092 KAITHI LETTER CA -// 11093 KAITHI LETTER CHA -// 11094 KAITHI LETTER JA -// 11095 KAITHI LETTER JHA -// 11096 KAITHI LETTER NYA -// 11097 KAITHI LETTER TTA -// 11098 KAITHI LETTER TTHA -// 11099 KAITHI LETTER DDA -// 1109a KAITHI LETTER DDDHA -// 1109b KAITHI LETTER DDHA -// 1109c KAITHI LETTER RHA -// 1109d KAITHI LETTER NNA -// 1109e KAITHI LETTER TA -// 1109f KAITHI LETTER THA -// 110a0 KAITHI LETTER DA -// 110a1 KAITHI LETTER DHA -// 110a2 KAITHI LETTER NA -// 110a3 KAITHI LETTER PA -// 110a4 KAITHI LETTER PHA -// 110a5 KAITHI LETTER BA -// 110a6 KAITHI LETTER BHA -// 110a7 KAITHI LETTER MA -// 110a8 KAITHI LETTER YA -// 110a9 KAITHI LETTER RA -// 110aa KAITHI LETTER LA -// 110ab KAITHI LETTER VA -// 110ac KAITHI LETTER SHA -// 110ad KAITHI LETTER SSA -// 110ae KAITHI LETTER SA -// 110af KAITHI LETTER HA - { 0x11083, 0x2D, 0x9, 0, 0 }, -// 110b0 KAITHI VOWEL SIGN AA -// 110b1 KAITHI VOWEL SIGN I -// 110b2 KAITHI VOWEL SIGN II -// 110b3 KAITHI VOWEL SIGN U -// 110b4 KAITHI VOWEL SIGN UU -// 110b5 KAITHI VOWEL SIGN E -// 110b6 KAITHI VOWEL SIGN AI -// 110b7 KAITHI VOWEL SIGN O -// 110b8 KAITHI VOWEL SIGN AU -// 110b9 KAITHI SIGN VIRAMA -// 110ba KAITHI SIGN NUKTA - { 0x110B0, 0xB, 0x0, 0, 0 }, -// 110bb KAITHI ABBREVIATION SIGN -// 110bc KAITHI ENUMERATION SIGN - { 0x110BB, 0x2, 0x18, 0, 0 }, -// 110bd KAITHI NUMBER SIGN - { 0x110BD, 0x1, 0x0, 0, 0 }, -// 110be KAITHI SECTION MARK -// 110bf KAITHI DOUBLE SECTION MARK -// 110c0 KAITHI DANDA -// 110c1 KAITHI DOUBLE DANDA - { 0x110BE, 0x4, 0x18, 0, 0 }, -// 110d0 SORA SOMPENG LETTER SAH -// 110d1 SORA SOMPENG LETTER TAH -// 110d2 SORA SOMPENG LETTER BAH -// 110d3 SORA SOMPENG LETTER CAH -// 110d4 SORA SOMPENG LETTER DAH -// 110d5 SORA SOMPENG LETTER GAH -// 110d6 SORA SOMPENG LETTER MAH -// 110d7 SORA SOMPENG LETTER NGAH -// 110d8 SORA SOMPENG LETTER LAH -// 110d9 SORA SOMPENG LETTER NAH -// 110da SORA SOMPENG LETTER VAH -// 110db SORA SOMPENG LETTER PAH -// 110dc SORA SOMPENG LETTER YAH -// 110dd SORA SOMPENG LETTER RAH -// 110de SORA SOMPENG LETTER HAH -// 110df SORA SOMPENG LETTER KAH -// 110e0 SORA SOMPENG LETTER JAH -// 110e1 SORA SOMPENG LETTER NYAH -// 110e2 SORA SOMPENG LETTER AH -// 110e3 SORA SOMPENG LETTER EEH -// 110e4 SORA SOMPENG LETTER IH -// 110e5 SORA SOMPENG LETTER UH -// 110e6 SORA SOMPENG LETTER OH -// 110e7 SORA SOMPENG LETTER EH -// 110e8 SORA SOMPENG LETTER MAE - { 0x110D0, 0x19, 0x9, 0, 0 }, -// 110f0 SORA SOMPENG DIGIT ZERO -// 110f1 SORA SOMPENG DIGIT ONE -// 110f2 SORA SOMPENG DIGIT TWO -// 110f3 SORA SOMPENG DIGIT THREE -// 110f4 SORA SOMPENG DIGIT FOUR -// 110f5 SORA SOMPENG DIGIT FIVE -// 110f6 SORA SOMPENG DIGIT SIX -// 110f7 SORA SOMPENG DIGIT SEVEN -// 110f8 SORA SOMPENG DIGIT EIGHT -// 110f9 SORA SOMPENG DIGIT NINE - { 0x110F0, 0xA, 0x108, 0, 0 }, -// 11100 CHAKMA SIGN CANDRABINDU -// 11101 CHAKMA SIGN ANUSVARA -// 11102 CHAKMA SIGN VISARGA - { 0x11100, 0x3, 0x0, 0, 0 }, -// 11103 CHAKMA LETTER AA -// 11104 CHAKMA LETTER I -// 11105 CHAKMA LETTER U -// 11106 CHAKMA LETTER E -// 11107 CHAKMA LETTER KAA -// 11108 CHAKMA LETTER KHAA -// 11109 CHAKMA LETTER GAA -// 1110a CHAKMA LETTER GHAA -// 1110b CHAKMA LETTER NGAA -// 1110c CHAKMA LETTER CAA -// 1110d CHAKMA LETTER CHAA -// 1110e CHAKMA LETTER JAA -// 1110f CHAKMA LETTER JHAA -// 11110 CHAKMA LETTER NYAA -// 11111 CHAKMA LETTER TTAA -// 11112 CHAKMA LETTER TTHAA -// 11113 CHAKMA LETTER DDAA -// 11114 CHAKMA LETTER DDHAA -// 11115 CHAKMA LETTER NNAA -// 11116 CHAKMA LETTER TAA -// 11117 CHAKMA LETTER THAA -// 11118 CHAKMA LETTER DAA -// 11119 CHAKMA LETTER DHAA -// 1111a CHAKMA LETTER NAA -// 1111b CHAKMA LETTER PAA -// 1111c CHAKMA LETTER PHAA -// 1111d CHAKMA LETTER BAA -// 1111e CHAKMA LETTER BHAA -// 1111f CHAKMA LETTER MAA -// 11120 CHAKMA LETTER YYAA -// 11121 CHAKMA LETTER YAA -// 11122 CHAKMA LETTER RAA -// 11123 CHAKMA LETTER LAA -// 11124 CHAKMA LETTER WAA -// 11125 CHAKMA LETTER SAA -// 11126 CHAKMA LETTER HAA - { 0x11103, 0x24, 0x9, 0, 0 }, -// 11127 CHAKMA VOWEL SIGN A -// 11128 CHAKMA VOWEL SIGN I -// 11129 CHAKMA VOWEL SIGN II -// 1112a CHAKMA VOWEL SIGN U -// 1112b CHAKMA VOWEL SIGN UU -// 1112c CHAKMA VOWEL SIGN E -// 1112d CHAKMA VOWEL SIGN AI -// 1112e CHAKMA VOWEL SIGN O -// 1112f CHAKMA VOWEL SIGN AU -// 11130 CHAKMA VOWEL SIGN OI -// 11131 CHAKMA O MARK -// 11132 CHAKMA AU MARK -// 11133 CHAKMA VIRAMA -// 11134 CHAKMA MAAYYAA - { 0x11127, 0xE, 0x0, 0, 0 }, -// 11136 CHAKMA DIGIT ZERO -// 11137 CHAKMA DIGIT ONE -// 11138 CHAKMA DIGIT TWO -// 11139 CHAKMA DIGIT THREE -// 1113a CHAKMA DIGIT FOUR -// 1113b CHAKMA DIGIT FIVE -// 1113c CHAKMA DIGIT SIX -// 1113d CHAKMA DIGIT SEVEN -// 1113e CHAKMA DIGIT EIGHT -// 1113f CHAKMA DIGIT NINE - { 0x11136, 0xA, 0x108, 0, 0 }, -// 11140 CHAKMA SECTION MARK -// 11141 CHAKMA DANDA -// 11142 CHAKMA DOUBLE DANDA -// 11143 CHAKMA QUESTION MARK - { 0x11140, 0x4, 0x18, 0, 0 }, -// 11150 MAHAJANI LETTER A -// 11151 MAHAJANI LETTER I -// 11152 MAHAJANI LETTER U -// 11153 MAHAJANI LETTER E -// 11154 MAHAJANI LETTER O -// 11155 MAHAJANI LETTER KA -// 11156 MAHAJANI LETTER KHA -// 11157 MAHAJANI LETTER GA -// 11158 MAHAJANI LETTER GHA -// 11159 MAHAJANI LETTER CA -// 1115a MAHAJANI LETTER CHA -// 1115b MAHAJANI LETTER JA -// 1115c MAHAJANI LETTER JHA -// 1115d MAHAJANI LETTER NYA -// 1115e MAHAJANI LETTER TTA -// 1115f MAHAJANI LETTER TTHA -// 11160 MAHAJANI LETTER DDA -// 11161 MAHAJANI LETTER DDHA -// 11162 MAHAJANI LETTER NNA -// 11163 MAHAJANI LETTER TA -// 11164 MAHAJANI LETTER THA -// 11165 MAHAJANI LETTER DA -// 11166 MAHAJANI LETTER DHA -// 11167 MAHAJANI LETTER NA -// 11168 MAHAJANI LETTER PA -// 11169 MAHAJANI LETTER PHA -// 1116a MAHAJANI LETTER BA -// 1116b MAHAJANI LETTER BHA -// 1116c MAHAJANI LETTER MA -// 1116d MAHAJANI LETTER RA -// 1116e MAHAJANI LETTER LA -// 1116f MAHAJANI LETTER VA -// 11170 MAHAJANI LETTER SA -// 11171 MAHAJANI LETTER HA -// 11172 MAHAJANI LETTER RRA - { 0x11150, 0x23, 0x9, 0, 0 }, -// 11173 MAHAJANI SIGN NUKTA - { 0x11173, 0x1, 0x0, 0, 0 }, -// 11174 MAHAJANI ABBREVIATION SIGN -// 11175 MAHAJANI SECTION MARK - { 0x11174, 0x2, 0x18, 0, 0 }, -// 11176 MAHAJANI LIGATURE SHRI - { 0x11176, 0x1, 0x9, 0, 0 }, -// 11180 SHARADA SIGN CANDRABINDU -// 11181 SHARADA SIGN ANUSVARA -// 11182 SHARADA SIGN VISARGA - { 0x11180, 0x3, 0x0, 0, 0 }, -// 11183 SHARADA LETTER A -// 11184 SHARADA LETTER AA -// 11185 SHARADA LETTER I -// 11186 SHARADA LETTER II -// 11187 SHARADA LETTER U -// 11188 SHARADA LETTER UU -// 11189 SHARADA LETTER VOCALIC R -// 1118a SHARADA LETTER VOCALIC RR -// 1118b SHARADA LETTER VOCALIC L -// 1118c SHARADA LETTER VOCALIC LL -// 1118d SHARADA LETTER E -// 1118e SHARADA LETTER AI -// 1118f SHARADA LETTER O -// 11190 SHARADA LETTER AU -// 11191 SHARADA LETTER KA -// 11192 SHARADA LETTER KHA -// 11193 SHARADA LETTER GA -// 11194 SHARADA LETTER GHA -// 11195 SHARADA LETTER NGA -// 11196 SHARADA LETTER CA -// 11197 SHARADA LETTER CHA -// 11198 SHARADA LETTER JA -// 11199 SHARADA LETTER JHA -// 1119a SHARADA LETTER NYA -// 1119b SHARADA LETTER TTA -// 1119c SHARADA LETTER TTHA -// 1119d SHARADA LETTER DDA -// 1119e SHARADA LETTER DDHA -// 1119f SHARADA LETTER NNA -// 111a0 SHARADA LETTER TA -// 111a1 SHARADA LETTER THA -// 111a2 SHARADA LETTER DA -// 111a3 SHARADA LETTER DHA -// 111a4 SHARADA LETTER NA -// 111a5 SHARADA LETTER PA -// 111a6 SHARADA LETTER PHA -// 111a7 SHARADA LETTER BA -// 111a8 SHARADA LETTER BHA -// 111a9 SHARADA LETTER MA -// 111aa SHARADA LETTER YA -// 111ab SHARADA LETTER RA -// 111ac SHARADA LETTER LA -// 111ad SHARADA LETTER LLA -// 111ae SHARADA LETTER VA -// 111af SHARADA LETTER SHA -// 111b0 SHARADA LETTER SSA -// 111b1 SHARADA LETTER SA -// 111b2 SHARADA LETTER HA - { 0x11183, 0x30, 0x9, 0, 0 }, -// 111b3 SHARADA VOWEL SIGN AA -// 111b4 SHARADA VOWEL SIGN I -// 111b5 SHARADA VOWEL SIGN II -// 111b6 SHARADA VOWEL SIGN U -// 111b7 SHARADA VOWEL SIGN UU -// 111b8 SHARADA VOWEL SIGN VOCALIC R -// 111b9 SHARADA VOWEL SIGN VOCALIC RR -// 111ba SHARADA VOWEL SIGN VOCALIC L -// 111bb SHARADA VOWEL SIGN VOCALIC LL -// 111bc SHARADA VOWEL SIGN E -// 111bd SHARADA VOWEL SIGN AI -// 111be SHARADA VOWEL SIGN O -// 111bf SHARADA VOWEL SIGN AU -// 111c0 SHARADA SIGN VIRAMA - { 0x111B3, 0xE, 0x0, 0, 0 }, -// 111c1 SHARADA SIGN AVAGRAHA -// 111c2 SHARADA SIGN JIHVAMULIYA -// 111c3 SHARADA SIGN UPADHMANIYA -// 111c4 SHARADA OM - { 0x111C1, 0x4, 0x9, 0, 0 }, -// 111c5 SHARADA DANDA -// 111c6 SHARADA DOUBLE DANDA -// 111c7 SHARADA ABBREVIATION SIGN -// 111c8 SHARADA SEPARATOR - { 0x111C5, 0x4, 0x18, 0, 0 }, -// 111cd SHARADA SUTRA MARK - { 0x111CD, 0x1, 0x18, 0, 0 }, -// 111d0 SHARADA DIGIT ZERO -// 111d1 SHARADA DIGIT ONE -// 111d2 SHARADA DIGIT TWO -// 111d3 SHARADA DIGIT THREE -// 111d4 SHARADA DIGIT FOUR -// 111d5 SHARADA DIGIT FIVE -// 111d6 SHARADA DIGIT SIX -// 111d7 SHARADA DIGIT SEVEN -// 111d8 SHARADA DIGIT EIGHT -// 111d9 SHARADA DIGIT NINE - { 0x111D0, 0xA, 0x108, 0, 0 }, -// 111da SHARADA EKAM - { 0x111DA, 0x1, 0x9, 0, 0 }, -// 111e1 SINHALA ARCHAIC DIGIT ONE -// 111e2 SINHALA ARCHAIC DIGIT TWO -// 111e3 SINHALA ARCHAIC DIGIT THREE -// 111e4 SINHALA ARCHAIC DIGIT FOUR -// 111e5 SINHALA ARCHAIC DIGIT FIVE -// 111e6 SINHALA ARCHAIC DIGIT SIX -// 111e7 SINHALA ARCHAIC DIGIT SEVEN -// 111e8 SINHALA ARCHAIC DIGIT EIGHT -// 111e9 SINHALA ARCHAIC DIGIT NINE -// 111ea SINHALA ARCHAIC NUMBER TEN -// 111eb SINHALA ARCHAIC NUMBER TWENTY -// 111ec SINHALA ARCHAIC NUMBER THIRTY -// 111ed SINHALA ARCHAIC NUMBER FORTY -// 111ee SINHALA ARCHAIC NUMBER FIFTY -// 111ef SINHALA ARCHAIC NUMBER SIXTY -// 111f0 SINHALA ARCHAIC NUMBER SEVENTY -// 111f1 SINHALA ARCHAIC NUMBER EIGHTY -// 111f2 SINHALA ARCHAIC NUMBER NINETY -// 111f3 SINHALA ARCHAIC NUMBER ONE HUNDRED -// 111f4 SINHALA ARCHAIC NUMBER ONE THOUSAND - { 0x111E1, 0x14, 0x8, 0, 0 }, -// 11200 KHOJKI LETTER A -// 11201 KHOJKI LETTER AA -// 11202 KHOJKI LETTER I -// 11203 KHOJKI LETTER U -// 11204 KHOJKI LETTER E -// 11205 KHOJKI LETTER AI -// 11206 KHOJKI LETTER O -// 11207 KHOJKI LETTER AU -// 11208 KHOJKI LETTER KA -// 11209 KHOJKI LETTER KHA -// 1120a KHOJKI LETTER GA -// 1120b KHOJKI LETTER GGA -// 1120c KHOJKI LETTER GHA -// 1120d KHOJKI LETTER NGA -// 1120e KHOJKI LETTER CA -// 1120f KHOJKI LETTER CHA -// 11210 KHOJKI LETTER JA -// 11211 KHOJKI LETTER JJA - { 0x11200, 0x12, 0x9, 0, 0 }, -// 11213 KHOJKI LETTER NYA -// 11214 KHOJKI LETTER TTA -// 11215 KHOJKI LETTER TTHA -// 11216 KHOJKI LETTER DDA -// 11217 KHOJKI LETTER DDHA -// 11218 KHOJKI LETTER NNA -// 11219 KHOJKI LETTER TA -// 1121a KHOJKI LETTER THA -// 1121b KHOJKI LETTER DA -// 1121c KHOJKI LETTER DDDA -// 1121d KHOJKI LETTER DHA -// 1121e KHOJKI LETTER NA -// 1121f KHOJKI LETTER PA -// 11220 KHOJKI LETTER PHA -// 11221 KHOJKI LETTER BA -// 11222 KHOJKI LETTER BBA -// 11223 KHOJKI LETTER BHA -// 11224 KHOJKI LETTER MA -// 11225 KHOJKI LETTER YA -// 11226 KHOJKI LETTER RA -// 11227 KHOJKI LETTER LA -// 11228 KHOJKI LETTER VA -// 11229 KHOJKI LETTER SA -// 1122a KHOJKI LETTER HA -// 1122b KHOJKI LETTER LLA - { 0x11213, 0x19, 0x9, 0, 0 }, -// 1122c KHOJKI VOWEL SIGN AA -// 1122d KHOJKI VOWEL SIGN I -// 1122e KHOJKI VOWEL SIGN II -// 1122f KHOJKI VOWEL SIGN U -// 11230 KHOJKI VOWEL SIGN E -// 11231 KHOJKI VOWEL SIGN AI -// 11232 KHOJKI VOWEL SIGN O -// 11233 KHOJKI VOWEL SIGN AU -// 11234 KHOJKI SIGN ANUSVARA -// 11235 KHOJKI SIGN VIRAMA -// 11236 KHOJKI SIGN NUKTA -// 11237 KHOJKI SIGN SHADDA - { 0x1122C, 0xC, 0x0, 0, 0 }, -// 11238 KHOJKI DANDA -// 11239 KHOJKI DOUBLE DANDA -// 1123a KHOJKI WORD SEPARATOR -// 1123b KHOJKI SECTION MARK -// 1123c KHOJKI DOUBLE SECTION MARK -// 1123d KHOJKI ABBREVIATION SIGN - { 0x11238, 0x6, 0x18, 0, 0 }, -// 112b0 KHUDAWADI LETTER A -// 112b1 KHUDAWADI LETTER AA -// 112b2 KHUDAWADI LETTER I -// 112b3 KHUDAWADI LETTER II -// 112b4 KHUDAWADI LETTER U -// 112b5 KHUDAWADI LETTER UU -// 112b6 KHUDAWADI LETTER E -// 112b7 KHUDAWADI LETTER AI -// 112b8 KHUDAWADI LETTER O -// 112b9 KHUDAWADI LETTER AU -// 112ba KHUDAWADI LETTER KA -// 112bb KHUDAWADI LETTER KHA -// 112bc KHUDAWADI LETTER GA -// 112bd KHUDAWADI LETTER GGA -// 112be KHUDAWADI LETTER GHA -// 112bf KHUDAWADI LETTER NGA -// 112c0 KHUDAWADI LETTER CA -// 112c1 KHUDAWADI LETTER CHA -// 112c2 KHUDAWADI LETTER JA -// 112c3 KHUDAWADI LETTER JJA -// 112c4 KHUDAWADI LETTER JHA -// 112c5 KHUDAWADI LETTER NYA -// 112c6 KHUDAWADI LETTER TTA -// 112c7 KHUDAWADI LETTER TTHA -// 112c8 KHUDAWADI LETTER DDA -// 112c9 KHUDAWADI LETTER DDDA -// 112ca KHUDAWADI LETTER RRA -// 112cb KHUDAWADI LETTER DDHA -// 112cc KHUDAWADI LETTER NNA -// 112cd KHUDAWADI LETTER TA -// 112ce KHUDAWADI LETTER THA -// 112cf KHUDAWADI LETTER DA -// 112d0 KHUDAWADI LETTER DHA -// 112d1 KHUDAWADI LETTER NA -// 112d2 KHUDAWADI LETTER PA -// 112d3 KHUDAWADI LETTER PHA -// 112d4 KHUDAWADI LETTER BA -// 112d5 KHUDAWADI LETTER BBA -// 112d6 KHUDAWADI LETTER BHA -// 112d7 KHUDAWADI LETTER MA -// 112d8 KHUDAWADI LETTER YA -// 112d9 KHUDAWADI LETTER RA -// 112da KHUDAWADI LETTER LA -// 112db KHUDAWADI LETTER VA -// 112dc KHUDAWADI LETTER SHA -// 112dd KHUDAWADI LETTER SA -// 112de KHUDAWADI LETTER HA - { 0x112B0, 0x2F, 0x9, 0, 0 }, -// 112df KHUDAWADI SIGN ANUSVARA -// 112e0 KHUDAWADI VOWEL SIGN AA -// 112e1 KHUDAWADI VOWEL SIGN I -// 112e2 KHUDAWADI VOWEL SIGN II -// 112e3 KHUDAWADI VOWEL SIGN U -// 112e4 KHUDAWADI VOWEL SIGN UU -// 112e5 KHUDAWADI VOWEL SIGN E -// 112e6 KHUDAWADI VOWEL SIGN AI -// 112e7 KHUDAWADI VOWEL SIGN O -// 112e8 KHUDAWADI VOWEL SIGN AU -// 112e9 KHUDAWADI SIGN NUKTA -// 112ea KHUDAWADI SIGN VIRAMA - { 0x112DF, 0xC, 0x0, 0, 0 }, -// 112f0 KHUDAWADI DIGIT ZERO -// 112f1 KHUDAWADI DIGIT ONE -// 112f2 KHUDAWADI DIGIT TWO -// 112f3 KHUDAWADI DIGIT THREE -// 112f4 KHUDAWADI DIGIT FOUR -// 112f5 KHUDAWADI DIGIT FIVE -// 112f6 KHUDAWADI DIGIT SIX -// 112f7 KHUDAWADI DIGIT SEVEN -// 112f8 KHUDAWADI DIGIT EIGHT -// 112f9 KHUDAWADI DIGIT NINE - { 0x112F0, 0xA, 0x108, 0, 0 }, -// 11301 GRANTHA SIGN CANDRABINDU -// 11302 GRANTHA SIGN ANUSVARA -// 11303 GRANTHA SIGN VISARGA - { 0x11301, 0x3, 0x0, 0, 0 }, -// 11305 GRANTHA LETTER A -// 11306 GRANTHA LETTER AA -// 11307 GRANTHA LETTER I -// 11308 GRANTHA LETTER II -// 11309 GRANTHA LETTER U -// 1130a GRANTHA LETTER UU -// 1130b GRANTHA LETTER VOCALIC R -// 1130c GRANTHA LETTER VOCALIC L - { 0x11305, 0x8, 0x9, 0, 0 }, -// 1130f GRANTHA LETTER EE -// 11310 GRANTHA LETTER AI - { 0x1130F, 0x2, 0x9, 0, 0 }, -// 11313 GRANTHA LETTER OO -// 11314 GRANTHA LETTER AU -// 11315 GRANTHA LETTER KA -// 11316 GRANTHA LETTER KHA -// 11317 GRANTHA LETTER GA -// 11318 GRANTHA LETTER GHA -// 11319 GRANTHA LETTER NGA -// 1131a GRANTHA LETTER CA -// 1131b GRANTHA LETTER CHA -// 1131c GRANTHA LETTER JA -// 1131d GRANTHA LETTER JHA -// 1131e GRANTHA LETTER NYA -// 1131f GRANTHA LETTER TTA -// 11320 GRANTHA LETTER TTHA -// 11321 GRANTHA LETTER DDA -// 11322 GRANTHA LETTER DDHA -// 11323 GRANTHA LETTER NNA -// 11324 GRANTHA LETTER TA -// 11325 GRANTHA LETTER THA -// 11326 GRANTHA LETTER DA -// 11327 GRANTHA LETTER DHA -// 11328 GRANTHA LETTER NA - { 0x11313, 0x16, 0x9, 0, 0 }, -// 1132a GRANTHA LETTER PA -// 1132b GRANTHA LETTER PHA -// 1132c GRANTHA LETTER BA -// 1132d GRANTHA LETTER BHA -// 1132e GRANTHA LETTER MA -// 1132f GRANTHA LETTER YA -// 11330 GRANTHA LETTER RA - { 0x1132A, 0x7, 0x9, 0, 0 }, -// 11332 GRANTHA LETTER LA -// 11333 GRANTHA LETTER LLA - { 0x11332, 0x2, 0x9, 0, 0 }, -// 11335 GRANTHA LETTER VA -// 11336 GRANTHA LETTER SHA -// 11337 GRANTHA LETTER SSA -// 11338 GRANTHA LETTER SA -// 11339 GRANTHA LETTER HA - { 0x11335, 0x5, 0x9, 0, 0 }, -// 1133c GRANTHA SIGN NUKTA - { 0x1133C, 0x1, 0x0, 0, 0 }, -// 1133d GRANTHA SIGN AVAGRAHA - { 0x1133D, 0x1, 0x9, 0, 0 }, -// 1133e GRANTHA VOWEL SIGN AA -// 1133f GRANTHA VOWEL SIGN I -// 11340 GRANTHA VOWEL SIGN II -// 11341 GRANTHA VOWEL SIGN U -// 11342 GRANTHA VOWEL SIGN UU -// 11343 GRANTHA VOWEL SIGN VOCALIC R -// 11344 GRANTHA VOWEL SIGN VOCALIC RR - { 0x1133E, 0x7, 0x0, 0, 0 }, -// 11347 GRANTHA VOWEL SIGN EE -// 11348 GRANTHA VOWEL SIGN AI - { 0x11347, 0x2, 0x0, 0, 0 }, -// 1134b GRANTHA VOWEL SIGN OO -// 1134c GRANTHA VOWEL SIGN AU -// 1134d GRANTHA SIGN VIRAMA - { 0x1134B, 0x3, 0x0, 0, 0 }, -// 11357 GRANTHA AU LENGTH MARK - { 0x11357, 0x1, 0x0, 0, 0 }, -// 1135d GRANTHA SIGN PLUTA -// 1135e GRANTHA LETTER VEDIC ANUSVARA -// 1135f GRANTHA LETTER VEDIC DOUBLE ANUSVARA -// 11360 GRANTHA LETTER VOCALIC RR -// 11361 GRANTHA LETTER VOCALIC LL - { 0x1135D, 0x5, 0x9, 0, 0 }, -// 11362 GRANTHA VOWEL SIGN VOCALIC L -// 11363 GRANTHA VOWEL SIGN VOCALIC LL - { 0x11362, 0x2, 0x0, 0, 0 }, -// 11366 COMBINING GRANTHA DIGIT ZERO -// 11367 COMBINING GRANTHA DIGIT ONE -// 11368 COMBINING GRANTHA DIGIT TWO -// 11369 COMBINING GRANTHA DIGIT THREE -// 1136a COMBINING GRANTHA DIGIT FOUR -// 1136b COMBINING GRANTHA DIGIT FIVE -// 1136c COMBINING GRANTHA DIGIT SIX - { 0x11366, 0x7, 0x0, 0, 0 }, -// 11370 COMBINING GRANTHA LETTER A -// 11371 COMBINING GRANTHA LETTER KA -// 11372 COMBINING GRANTHA LETTER NA -// 11373 COMBINING GRANTHA LETTER VI -// 11374 COMBINING GRANTHA LETTER PA - { 0x11370, 0x5, 0x0, 0, 0 }, -// 11480 TIRHUTA ANJI -// 11481 TIRHUTA LETTER A -// 11482 TIRHUTA LETTER AA -// 11483 TIRHUTA LETTER I -// 11484 TIRHUTA LETTER II -// 11485 TIRHUTA LETTER U -// 11486 TIRHUTA LETTER UU -// 11487 TIRHUTA LETTER VOCALIC R -// 11488 TIRHUTA LETTER VOCALIC RR -// 11489 TIRHUTA LETTER VOCALIC L -// 1148a TIRHUTA LETTER VOCALIC LL -// 1148b TIRHUTA LETTER E -// 1148c TIRHUTA LETTER AI -// 1148d TIRHUTA LETTER O -// 1148e TIRHUTA LETTER AU -// 1148f TIRHUTA LETTER KA -// 11490 TIRHUTA LETTER KHA -// 11491 TIRHUTA LETTER GA -// 11492 TIRHUTA LETTER GHA -// 11493 TIRHUTA LETTER NGA -// 11494 TIRHUTA LETTER CA -// 11495 TIRHUTA LETTER CHA -// 11496 TIRHUTA LETTER JA -// 11497 TIRHUTA LETTER JHA -// 11498 TIRHUTA LETTER NYA -// 11499 TIRHUTA LETTER TTA -// 1149a TIRHUTA LETTER TTHA -// 1149b TIRHUTA LETTER DDA -// 1149c TIRHUTA LETTER DDHA -// 1149d TIRHUTA LETTER NNA -// 1149e TIRHUTA LETTER TA -// 1149f TIRHUTA LETTER THA -// 114a0 TIRHUTA LETTER DA -// 114a1 TIRHUTA LETTER DHA -// 114a2 TIRHUTA LETTER NA -// 114a3 TIRHUTA LETTER PA -// 114a4 TIRHUTA LETTER PHA -// 114a5 TIRHUTA LETTER BA -// 114a6 TIRHUTA LETTER BHA -// 114a7 TIRHUTA LETTER MA -// 114a8 TIRHUTA LETTER YA -// 114a9 TIRHUTA LETTER RA -// 114aa TIRHUTA LETTER LA -// 114ab TIRHUTA LETTER VA -// 114ac TIRHUTA LETTER SHA -// 114ad TIRHUTA LETTER SSA -// 114ae TIRHUTA LETTER SA -// 114af TIRHUTA LETTER HA - { 0x11480, 0x30, 0x9, 0, 0 }, -// 114b0 TIRHUTA VOWEL SIGN AA -// 114b1 TIRHUTA VOWEL SIGN I -// 114b2 TIRHUTA VOWEL SIGN II -// 114b3 TIRHUTA VOWEL SIGN U -// 114b4 TIRHUTA VOWEL SIGN UU -// 114b5 TIRHUTA VOWEL SIGN VOCALIC R -// 114b6 TIRHUTA VOWEL SIGN VOCALIC RR -// 114b7 TIRHUTA VOWEL SIGN VOCALIC L -// 114b8 TIRHUTA VOWEL SIGN VOCALIC LL -// 114b9 TIRHUTA VOWEL SIGN E -// 114ba TIRHUTA VOWEL SIGN SHORT E -// 114bb TIRHUTA VOWEL SIGN AI -// 114bc TIRHUTA VOWEL SIGN O -// 114bd TIRHUTA VOWEL SIGN SHORT O -// 114be TIRHUTA VOWEL SIGN AU -// 114bf TIRHUTA SIGN CANDRABINDU -// 114c0 TIRHUTA SIGN ANUSVARA -// 114c1 TIRHUTA SIGN VISARGA -// 114c2 TIRHUTA SIGN VIRAMA -// 114c3 TIRHUTA SIGN NUKTA - { 0x114B0, 0x14, 0x0, 0, 0 }, -// 114c4 TIRHUTA SIGN AVAGRAHA -// 114c5 TIRHUTA GVANG - { 0x114C4, 0x2, 0x9, 0, 0 }, -// 114c6 TIRHUTA ABBREVIATION SIGN - { 0x114C6, 0x1, 0x18, 0, 0 }, -// 114c7 TIRHUTA OM - { 0x114C7, 0x1, 0x9, 0, 0 }, -// 114d0 TIRHUTA DIGIT ZERO -// 114d1 TIRHUTA DIGIT ONE -// 114d2 TIRHUTA DIGIT TWO -// 114d3 TIRHUTA DIGIT THREE -// 114d4 TIRHUTA DIGIT FOUR -// 114d5 TIRHUTA DIGIT FIVE -// 114d6 TIRHUTA DIGIT SIX -// 114d7 TIRHUTA DIGIT SEVEN -// 114d8 TIRHUTA DIGIT EIGHT -// 114d9 TIRHUTA DIGIT NINE - { 0x114D0, 0xA, 0x108, 0, 0 }, -// 11580 SIDDHAM LETTER A -// 11581 SIDDHAM LETTER AA -// 11582 SIDDHAM LETTER I -// 11583 SIDDHAM LETTER II -// 11584 SIDDHAM LETTER U -// 11585 SIDDHAM LETTER UU -// 11586 SIDDHAM LETTER VOCALIC R -// 11587 SIDDHAM LETTER VOCALIC RR -// 11588 SIDDHAM LETTER VOCALIC L -// 11589 SIDDHAM LETTER VOCALIC LL -// 1158a SIDDHAM LETTER E -// 1158b SIDDHAM LETTER AI -// 1158c SIDDHAM LETTER O -// 1158d SIDDHAM LETTER AU -// 1158e SIDDHAM LETTER KA -// 1158f SIDDHAM LETTER KHA -// 11590 SIDDHAM LETTER GA -// 11591 SIDDHAM LETTER GHA -// 11592 SIDDHAM LETTER NGA -// 11593 SIDDHAM LETTER CA -// 11594 SIDDHAM LETTER CHA -// 11595 SIDDHAM LETTER JA -// 11596 SIDDHAM LETTER JHA -// 11597 SIDDHAM LETTER NYA -// 11598 SIDDHAM LETTER TTA -// 11599 SIDDHAM LETTER TTHA -// 1159a SIDDHAM LETTER DDA -// 1159b SIDDHAM LETTER DDHA -// 1159c SIDDHAM LETTER NNA -// 1159d SIDDHAM LETTER TA -// 1159e SIDDHAM LETTER THA -// 1159f SIDDHAM LETTER DA -// 115a0 SIDDHAM LETTER DHA -// 115a1 SIDDHAM LETTER NA -// 115a2 SIDDHAM LETTER PA -// 115a3 SIDDHAM LETTER PHA -// 115a4 SIDDHAM LETTER BA -// 115a5 SIDDHAM LETTER BHA -// 115a6 SIDDHAM LETTER MA -// 115a7 SIDDHAM LETTER YA -// 115a8 SIDDHAM LETTER RA -// 115a9 SIDDHAM LETTER LA -// 115aa SIDDHAM LETTER VA -// 115ab SIDDHAM LETTER SHA -// 115ac SIDDHAM LETTER SSA -// 115ad SIDDHAM LETTER SA -// 115ae SIDDHAM LETTER HA - { 0x11580, 0x2F, 0x9, 0, 0 }, -// 115af SIDDHAM VOWEL SIGN AA -// 115b0 SIDDHAM VOWEL SIGN I -// 115b1 SIDDHAM VOWEL SIGN II -// 115b2 SIDDHAM VOWEL SIGN U -// 115b3 SIDDHAM VOWEL SIGN UU -// 115b4 SIDDHAM VOWEL SIGN VOCALIC R -// 115b5 SIDDHAM VOWEL SIGN VOCALIC RR - { 0x115AF, 0x7, 0x0, 0, 0 }, -// 115b8 SIDDHAM VOWEL SIGN E -// 115b9 SIDDHAM VOWEL SIGN AI -// 115ba SIDDHAM VOWEL SIGN O -// 115bb SIDDHAM VOWEL SIGN AU -// 115bc SIDDHAM SIGN CANDRABINDU -// 115bd SIDDHAM SIGN ANUSVARA -// 115be SIDDHAM SIGN VISARGA -// 115bf SIDDHAM SIGN VIRAMA -// 115c0 SIDDHAM SIGN NUKTA - { 0x115B8, 0x9, 0x0, 0, 0 }, -// 115c1 SIDDHAM SIGN SIDDHAM -// 115c2 SIDDHAM DANDA -// 115c3 SIDDHAM DOUBLE DANDA -// 115c4 SIDDHAM SEPARATOR DOT -// 115c5 SIDDHAM SEPARATOR BAR -// 115c6 SIDDHAM REPETITION MARK-1 -// 115c7 SIDDHAM REPETITION MARK-2 -// 115c8 SIDDHAM REPETITION MARK-3 -// 115c9 SIDDHAM END OF TEXT MARK - { 0x115C1, 0x9, 0x18, 0, 0 }, -// 11600 MODI LETTER A -// 11601 MODI LETTER AA -// 11602 MODI LETTER I -// 11603 MODI LETTER II -// 11604 MODI LETTER U -// 11605 MODI LETTER UU -// 11606 MODI LETTER VOCALIC R -// 11607 MODI LETTER VOCALIC RR -// 11608 MODI LETTER VOCALIC L -// 11609 MODI LETTER VOCALIC LL -// 1160a MODI LETTER E -// 1160b MODI LETTER AI -// 1160c MODI LETTER O -// 1160d MODI LETTER AU -// 1160e MODI LETTER KA -// 1160f MODI LETTER KHA -// 11610 MODI LETTER GA -// 11611 MODI LETTER GHA -// 11612 MODI LETTER NGA -// 11613 MODI LETTER CA -// 11614 MODI LETTER CHA -// 11615 MODI LETTER JA -// 11616 MODI LETTER JHA -// 11617 MODI LETTER NYA -// 11618 MODI LETTER TTA -// 11619 MODI LETTER TTHA -// 1161a MODI LETTER DDA -// 1161b MODI LETTER DDHA -// 1161c MODI LETTER NNA -// 1161d MODI LETTER TA -// 1161e MODI LETTER THA -// 1161f MODI LETTER DA -// 11620 MODI LETTER DHA -// 11621 MODI LETTER NA -// 11622 MODI LETTER PA -// 11623 MODI LETTER PHA -// 11624 MODI LETTER BA -// 11625 MODI LETTER BHA -// 11626 MODI LETTER MA -// 11627 MODI LETTER YA -// 11628 MODI LETTER RA -// 11629 MODI LETTER LA -// 1162a MODI LETTER VA -// 1162b MODI LETTER SHA -// 1162c MODI LETTER SSA -// 1162d MODI LETTER SA -// 1162e MODI LETTER HA -// 1162f MODI LETTER LLA - { 0x11600, 0x30, 0x9, 0, 0 }, -// 11630 MODI VOWEL SIGN AA -// 11631 MODI VOWEL SIGN I -// 11632 MODI VOWEL SIGN II -// 11633 MODI VOWEL SIGN U -// 11634 MODI VOWEL SIGN UU -// 11635 MODI VOWEL SIGN VOCALIC R -// 11636 MODI VOWEL SIGN VOCALIC RR -// 11637 MODI VOWEL SIGN VOCALIC L -// 11638 MODI VOWEL SIGN VOCALIC LL -// 11639 MODI VOWEL SIGN E -// 1163a MODI VOWEL SIGN AI -// 1163b MODI VOWEL SIGN O -// 1163c MODI VOWEL SIGN AU -// 1163d MODI SIGN ANUSVARA -// 1163e MODI SIGN VISARGA -// 1163f MODI SIGN VIRAMA -// 11640 MODI SIGN ARDHACANDRA - { 0x11630, 0x11, 0x0, 0, 0 }, -// 11641 MODI DANDA -// 11642 MODI DOUBLE DANDA -// 11643 MODI ABBREVIATION SIGN - { 0x11641, 0x3, 0x18, 0, 0 }, -// 11644 MODI SIGN HUVA - { 0x11644, 0x1, 0x9, 0, 0 }, -// 11650 MODI DIGIT ZERO -// 11651 MODI DIGIT ONE -// 11652 MODI DIGIT TWO -// 11653 MODI DIGIT THREE -// 11654 MODI DIGIT FOUR -// 11655 MODI DIGIT FIVE -// 11656 MODI DIGIT SIX -// 11657 MODI DIGIT SEVEN -// 11658 MODI DIGIT EIGHT -// 11659 MODI DIGIT NINE - { 0x11650, 0xA, 0x108, 0, 0 }, -// 11680 TAKRI LETTER A -// 11681 TAKRI LETTER AA -// 11682 TAKRI LETTER I -// 11683 TAKRI LETTER II -// 11684 TAKRI LETTER U -// 11685 TAKRI LETTER UU -// 11686 TAKRI LETTER E -// 11687 TAKRI LETTER AI -// 11688 TAKRI LETTER O -// 11689 TAKRI LETTER AU -// 1168a TAKRI LETTER KA -// 1168b TAKRI LETTER KHA -// 1168c TAKRI LETTER GA -// 1168d TAKRI LETTER GHA -// 1168e TAKRI LETTER NGA -// 1168f TAKRI LETTER CA -// 11690 TAKRI LETTER CHA -// 11691 TAKRI LETTER JA -// 11692 TAKRI LETTER JHA -// 11693 TAKRI LETTER NYA -// 11694 TAKRI LETTER TTA -// 11695 TAKRI LETTER TTHA -// 11696 TAKRI LETTER DDA -// 11697 TAKRI LETTER DDHA -// 11698 TAKRI LETTER NNA -// 11699 TAKRI LETTER TA -// 1169a TAKRI LETTER THA -// 1169b TAKRI LETTER DA -// 1169c TAKRI LETTER DHA -// 1169d TAKRI LETTER NA -// 1169e TAKRI LETTER PA -// 1169f TAKRI LETTER PHA -// 116a0 TAKRI LETTER BA -// 116a1 TAKRI LETTER BHA -// 116a2 TAKRI LETTER MA -// 116a3 TAKRI LETTER YA -// 116a4 TAKRI LETTER RA -// 116a5 TAKRI LETTER LA -// 116a6 TAKRI LETTER VA -// 116a7 TAKRI LETTER SHA -// 116a8 TAKRI LETTER SA -// 116a9 TAKRI LETTER HA -// 116aa TAKRI LETTER RRA - { 0x11680, 0x2B, 0x9, 0, 0 }, -// 116ab TAKRI SIGN ANUSVARA -// 116ac TAKRI SIGN VISARGA -// 116ad TAKRI VOWEL SIGN AA -// 116ae TAKRI VOWEL SIGN I -// 116af TAKRI VOWEL SIGN II -// 116b0 TAKRI VOWEL SIGN U -// 116b1 TAKRI VOWEL SIGN UU -// 116b2 TAKRI VOWEL SIGN E -// 116b3 TAKRI VOWEL SIGN AI -// 116b4 TAKRI VOWEL SIGN O -// 116b5 TAKRI VOWEL SIGN AU -// 116b6 TAKRI SIGN VIRAMA -// 116b7 TAKRI SIGN NUKTA - { 0x116AB, 0xD, 0x0, 0, 0 }, -// 116c0 TAKRI DIGIT ZERO -// 116c1 TAKRI DIGIT ONE -// 116c2 TAKRI DIGIT TWO -// 116c3 TAKRI DIGIT THREE -// 116c4 TAKRI DIGIT FOUR -// 116c5 TAKRI DIGIT FIVE -// 116c6 TAKRI DIGIT SIX -// 116c7 TAKRI DIGIT SEVEN -// 116c8 TAKRI DIGIT EIGHT -// 116c9 TAKRI DIGIT NINE - { 0x116C0, 0xA, 0x108, 0, 0 }, -// 118a0 WARANG CITI CAPITAL LETTER NGAA -// 118a1 WARANG CITI CAPITAL LETTER A -// 118a2 WARANG CITI CAPITAL LETTER WI -// 118a3 WARANG CITI CAPITAL LETTER YU -// 118a4 WARANG CITI CAPITAL LETTER YA -// 118a5 WARANG CITI CAPITAL LETTER YO -// 118a6 WARANG CITI CAPITAL LETTER II -// 118a7 WARANG CITI CAPITAL LETTER UU -// 118a8 WARANG CITI CAPITAL LETTER E -// 118a9 WARANG CITI CAPITAL LETTER O -// 118aa WARANG CITI CAPITAL LETTER ANG -// 118ab WARANG CITI CAPITAL LETTER GA -// 118ac WARANG CITI CAPITAL LETTER KO -// 118ad WARANG CITI CAPITAL LETTER ENY -// 118ae WARANG CITI CAPITAL LETTER YUJ -// 118af WARANG CITI CAPITAL LETTER UC -// 118b0 WARANG CITI CAPITAL LETTER ENN -// 118b1 WARANG CITI CAPITAL LETTER ODD -// 118b2 WARANG CITI CAPITAL LETTER TTE -// 118b3 WARANG CITI CAPITAL LETTER NUNG -// 118b4 WARANG CITI CAPITAL LETTER DA -// 118b5 WARANG CITI CAPITAL LETTER AT -// 118b6 WARANG CITI CAPITAL LETTER AM -// 118b7 WARANG CITI CAPITAL LETTER BU -// 118b8 WARANG CITI CAPITAL LETTER PU -// 118b9 WARANG CITI CAPITAL LETTER HIYO -// 118ba WARANG CITI CAPITAL LETTER HOLO -// 118bb WARANG CITI CAPITAL LETTER HORR -// 118bc WARANG CITI CAPITAL LETTER HAR -// 118bd WARANG CITI CAPITAL LETTER SSUU -// 118be WARANG CITI CAPITAL LETTER SII -// 118bf WARANG CITI CAPITAL LETTER VIYO - { 0x118A0, 0x20, 0x89, 32, 0 }, -// 118c0 WARANG CITI SMALL LETTER NGAA -// 118c1 WARANG CITI SMALL LETTER A -// 118c2 WARANG CITI SMALL LETTER WI -// 118c3 WARANG CITI SMALL LETTER YU -// 118c4 WARANG CITI SMALL LETTER YA -// 118c5 WARANG CITI SMALL LETTER YO -// 118c6 WARANG CITI SMALL LETTER II -// 118c7 WARANG CITI SMALL LETTER UU -// 118c8 WARANG CITI SMALL LETTER E -// 118c9 WARANG CITI SMALL LETTER O -// 118ca WARANG CITI SMALL LETTER ANG -// 118cb WARANG CITI SMALL LETTER GA -// 118cc WARANG CITI SMALL LETTER KO -// 118cd WARANG CITI SMALL LETTER ENY -// 118ce WARANG CITI SMALL LETTER YUJ -// 118cf WARANG CITI SMALL LETTER UC -// 118d0 WARANG CITI SMALL LETTER ENN -// 118d1 WARANG CITI SMALL LETTER ODD -// 118d2 WARANG CITI SMALL LETTER TTE -// 118d3 WARANG CITI SMALL LETTER NUNG -// 118d4 WARANG CITI SMALL LETTER DA -// 118d5 WARANG CITI SMALL LETTER AT -// 118d6 WARANG CITI SMALL LETTER AM -// 118d7 WARANG CITI SMALL LETTER BU -// 118d8 WARANG CITI SMALL LETTER PU -// 118d9 WARANG CITI SMALL LETTER HIYO -// 118da WARANG CITI SMALL LETTER HOLO -// 118db WARANG CITI SMALL LETTER HORR -// 118dc WARANG CITI SMALL LETTER HAR -// 118dd WARANG CITI SMALL LETTER SSUU -// 118de WARANG CITI SMALL LETTER SII -// 118df WARANG CITI SMALL LETTER VIYO - { 0x118C0, 0x20, 0x49, 0, -32 }, -// 118e0 WARANG CITI DIGIT ZERO -// 118e1 WARANG CITI DIGIT ONE -// 118e2 WARANG CITI DIGIT TWO -// 118e3 WARANG CITI DIGIT THREE -// 118e4 WARANG CITI DIGIT FOUR -// 118e5 WARANG CITI DIGIT FIVE -// 118e6 WARANG CITI DIGIT SIX -// 118e7 WARANG CITI DIGIT SEVEN -// 118e8 WARANG CITI DIGIT EIGHT -// 118e9 WARANG CITI DIGIT NINE - { 0x118E0, 0xA, 0x108, 0, 0 }, -// 118ea WARANG CITI NUMBER TEN -// 118eb WARANG CITI NUMBER TWENTY -// 118ec WARANG CITI NUMBER THIRTY -// 118ed WARANG CITI NUMBER FORTY -// 118ee WARANG CITI NUMBER FIFTY -// 118ef WARANG CITI NUMBER SIXTY -// 118f0 WARANG CITI NUMBER SEVENTY -// 118f1 WARANG CITI NUMBER EIGHTY -// 118f2 WARANG CITI NUMBER NINETY - { 0x118EA, 0x9, 0x8, 0, 0 }, -// 118ff WARANG CITI OM - { 0x118FF, 0x1, 0x9, 0, 0 }, -// 11ac0 PAU CIN HAU LETTER PA -// 11ac1 PAU CIN HAU LETTER KA -// 11ac2 PAU CIN HAU LETTER LA -// 11ac3 PAU CIN HAU LETTER MA -// 11ac4 PAU CIN HAU LETTER DA -// 11ac5 PAU CIN HAU LETTER ZA -// 11ac6 PAU CIN HAU LETTER VA -// 11ac7 PAU CIN HAU LETTER NGA -// 11ac8 PAU CIN HAU LETTER HA -// 11ac9 PAU CIN HAU LETTER GA -// 11aca PAU CIN HAU LETTER KHA -// 11acb PAU CIN HAU LETTER SA -// 11acc PAU CIN HAU LETTER BA -// 11acd PAU CIN HAU LETTER CA -// 11ace PAU CIN HAU LETTER TA -// 11acf PAU CIN HAU LETTER THA -// 11ad0 PAU CIN HAU LETTER NA -// 11ad1 PAU CIN HAU LETTER PHA -// 11ad2 PAU CIN HAU LETTER RA -// 11ad3 PAU CIN HAU LETTER FA -// 11ad4 PAU CIN HAU LETTER CHA -// 11ad5 PAU CIN HAU LETTER A -// 11ad6 PAU CIN HAU LETTER E -// 11ad7 PAU CIN HAU LETTER I -// 11ad8 PAU CIN HAU LETTER O -// 11ad9 PAU CIN HAU LETTER U -// 11ada PAU CIN HAU LETTER UA -// 11adb PAU CIN HAU LETTER IA -// 11adc PAU CIN HAU LETTER FINAL P -// 11add PAU CIN HAU LETTER FINAL K -// 11ade PAU CIN HAU LETTER FINAL T -// 11adf PAU CIN HAU LETTER FINAL M -// 11ae0 PAU CIN HAU LETTER FINAL N -// 11ae1 PAU CIN HAU LETTER FINAL L -// 11ae2 PAU CIN HAU LETTER FINAL W -// 11ae3 PAU CIN HAU LETTER FINAL NG -// 11ae4 PAU CIN HAU LETTER FINAL Y -// 11ae5 PAU CIN HAU RISING TONE LONG -// 11ae6 PAU CIN HAU RISING TONE -// 11ae7 PAU CIN HAU SANDHI GLOTTAL STOP -// 11ae8 PAU CIN HAU RISING TONE LONG FINAL -// 11ae9 PAU CIN HAU RISING TONE FINAL -// 11aea PAU CIN HAU SANDHI GLOTTAL STOP FINAL -// 11aeb PAU CIN HAU SANDHI TONE LONG -// 11aec PAU CIN HAU SANDHI TONE -// 11aed PAU CIN HAU SANDHI TONE LONG FINAL -// 11aee PAU CIN HAU SANDHI TONE FINAL -// 11aef PAU CIN HAU MID-LEVEL TONE -// 11af0 PAU CIN HAU GLOTTAL STOP VARIANT -// 11af1 PAU CIN HAU MID-LEVEL TONE LONG FINAL -// 11af2 PAU CIN HAU MID-LEVEL TONE FINAL -// 11af3 PAU CIN HAU LOW-FALLING TONE LONG -// 11af4 PAU CIN HAU LOW-FALLING TONE -// 11af5 PAU CIN HAU GLOTTAL STOP -// 11af6 PAU CIN HAU LOW-FALLING TONE LONG FINAL -// 11af7 PAU CIN HAU LOW-FALLING TONE FINAL -// 11af8 PAU CIN HAU GLOTTAL STOP FINAL - { 0x11AC0, 0x39, 0x9, 0, 0 }, -// 12000 CUNEIFORM SIGN A -// 12001 CUNEIFORM SIGN A TIMES A -// 12002 CUNEIFORM SIGN A TIMES BAD -// 12003 CUNEIFORM SIGN A TIMES GAN2 TENU -// 12004 CUNEIFORM SIGN A TIMES HA -// 12005 CUNEIFORM SIGN A TIMES IGI -// 12006 CUNEIFORM SIGN A TIMES LAGAR GUNU -// 12007 CUNEIFORM SIGN A TIMES MUSH -// 12008 CUNEIFORM SIGN A TIMES SAG -// 12009 CUNEIFORM SIGN A2 -// 1200a CUNEIFORM SIGN AB -// 1200b CUNEIFORM SIGN AB TIMES ASH2 -// 1200c CUNEIFORM SIGN AB TIMES DUN3 GUNU -// 1200d CUNEIFORM SIGN AB TIMES GAL -// 1200e CUNEIFORM SIGN AB TIMES GAN2 TENU -// 1200f CUNEIFORM SIGN AB TIMES HA -// 12010 CUNEIFORM SIGN AB TIMES IGI GUNU -// 12011 CUNEIFORM SIGN AB TIMES IMIN -// 12012 CUNEIFORM SIGN AB TIMES LAGAB -// 12013 CUNEIFORM SIGN AB TIMES SHESH -// 12014 CUNEIFORM SIGN AB TIMES U PLUS U PLUS U -// 12015 CUNEIFORM SIGN AB GUNU -// 12016 CUNEIFORM SIGN AB2 -// 12017 CUNEIFORM SIGN AB2 TIMES BALAG -// 12018 CUNEIFORM SIGN AB2 TIMES GAN2 TENU -// 12019 CUNEIFORM SIGN AB2 TIMES ME PLUS EN -// 1201a CUNEIFORM SIGN AB2 TIMES SHA3 -// 1201b CUNEIFORM SIGN AB2 TIMES TAK4 -// 1201c CUNEIFORM SIGN AD -// 1201d CUNEIFORM SIGN AK -// 1201e CUNEIFORM SIGN AK TIMES ERIN2 -// 1201f CUNEIFORM SIGN AK TIMES SHITA PLUS GISH -// 12020 CUNEIFORM SIGN AL -// 12021 CUNEIFORM SIGN AL TIMES AL -// 12022 CUNEIFORM SIGN AL TIMES DIM2 -// 12023 CUNEIFORM SIGN AL TIMES GISH -// 12024 CUNEIFORM SIGN AL TIMES HA -// 12025 CUNEIFORM SIGN AL TIMES KAD3 -// 12026 CUNEIFORM SIGN AL TIMES KI -// 12027 CUNEIFORM SIGN AL TIMES SHE -// 12028 CUNEIFORM SIGN AL TIMES USH -// 12029 CUNEIFORM SIGN ALAN -// 1202a CUNEIFORM SIGN ALEPH -// 1202b CUNEIFORM SIGN AMAR -// 1202c CUNEIFORM SIGN AMAR TIMES SHE -// 1202d CUNEIFORM SIGN AN -// 1202e CUNEIFORM SIGN AN OVER AN -// 1202f CUNEIFORM SIGN AN THREE TIMES -// 12030 CUNEIFORM SIGN AN PLUS NAGA OPPOSING AN PLUS NAGA -// 12031 CUNEIFORM SIGN AN PLUS NAGA SQUARED -// 12032 CUNEIFORM SIGN ANSHE -// 12033 CUNEIFORM SIGN APIN -// 12034 CUNEIFORM SIGN ARAD -// 12035 CUNEIFORM SIGN ARAD TIMES KUR -// 12036 CUNEIFORM SIGN ARKAB -// 12037 CUNEIFORM SIGN ASAL2 -// 12038 CUNEIFORM SIGN ASH -// 12039 CUNEIFORM SIGN ASH ZIDA TENU -// 1203a CUNEIFORM SIGN ASH KABA TENU -// 1203b CUNEIFORM SIGN ASH OVER ASH TUG2 OVER TUG2 TUG2 OVER TUG2 PAP -// 1203c CUNEIFORM SIGN ASH OVER ASH OVER ASH -// 1203d CUNEIFORM SIGN ASH OVER ASH OVER ASH CROSSING ASH OVER ASH OVER ASH -// 1203e CUNEIFORM SIGN ASH2 -// 1203f CUNEIFORM SIGN ASHGAB -// 12040 CUNEIFORM SIGN BA -// 12041 CUNEIFORM SIGN BAD -// 12042 CUNEIFORM SIGN BAG3 -// 12043 CUNEIFORM SIGN BAHAR2 -// 12044 CUNEIFORM SIGN BAL -// 12045 CUNEIFORM SIGN BAL OVER BAL -// 12046 CUNEIFORM SIGN BALAG -// 12047 CUNEIFORM SIGN BAR -// 12048 CUNEIFORM SIGN BARA2 -// 12049 CUNEIFORM SIGN BI -// 1204a CUNEIFORM SIGN BI TIMES A -// 1204b CUNEIFORM SIGN BI TIMES GAR -// 1204c CUNEIFORM SIGN BI TIMES IGI GUNU -// 1204d CUNEIFORM SIGN BU -// 1204e CUNEIFORM SIGN BU OVER BU AB -// 1204f CUNEIFORM SIGN BU OVER BU UN -// 12050 CUNEIFORM SIGN BU CROSSING BU -// 12051 CUNEIFORM SIGN BULUG -// 12052 CUNEIFORM SIGN BULUG OVER BULUG -// 12053 CUNEIFORM SIGN BUR -// 12054 CUNEIFORM SIGN BUR2 -// 12055 CUNEIFORM SIGN DA -// 12056 CUNEIFORM SIGN DAG -// 12057 CUNEIFORM SIGN DAG KISIM5 TIMES A PLUS MASH -// 12058 CUNEIFORM SIGN DAG KISIM5 TIMES AMAR -// 12059 CUNEIFORM SIGN DAG KISIM5 TIMES BALAG -// 1205a CUNEIFORM SIGN DAG KISIM5 TIMES BI -// 1205b CUNEIFORM SIGN DAG KISIM5 TIMES GA -// 1205c CUNEIFORM SIGN DAG KISIM5 TIMES GA PLUS MASH -// 1205d CUNEIFORM SIGN DAG KISIM5 TIMES GI -// 1205e CUNEIFORM SIGN DAG KISIM5 TIMES GIR2 -// 1205f CUNEIFORM SIGN DAG KISIM5 TIMES GUD -// 12060 CUNEIFORM SIGN DAG KISIM5 TIMES HA -// 12061 CUNEIFORM SIGN DAG KISIM5 TIMES IR -// 12062 CUNEIFORM SIGN DAG KISIM5 TIMES IR PLUS LU -// 12063 CUNEIFORM SIGN DAG KISIM5 TIMES KAK -// 12064 CUNEIFORM SIGN DAG KISIM5 TIMES LA -// 12065 CUNEIFORM SIGN DAG KISIM5 TIMES LU -// 12066 CUNEIFORM SIGN DAG KISIM5 TIMES LU PLUS MASH2 -// 12067 CUNEIFORM SIGN DAG KISIM5 TIMES LUM -// 12068 CUNEIFORM SIGN DAG KISIM5 TIMES NE -// 12069 CUNEIFORM SIGN DAG KISIM5 TIMES PAP PLUS PAP -// 1206a CUNEIFORM SIGN DAG KISIM5 TIMES SI -// 1206b CUNEIFORM SIGN DAG KISIM5 TIMES TAK4 -// 1206c CUNEIFORM SIGN DAG KISIM5 TIMES U2 PLUS GIR2 -// 1206d CUNEIFORM SIGN DAG KISIM5 TIMES USH -// 1206e CUNEIFORM SIGN DAM -// 1206f CUNEIFORM SIGN DAR -// 12070 CUNEIFORM SIGN DARA3 -// 12071 CUNEIFORM SIGN DARA4 -// 12072 CUNEIFORM SIGN DI -// 12073 CUNEIFORM SIGN DIB -// 12074 CUNEIFORM SIGN DIM -// 12075 CUNEIFORM SIGN DIM TIMES SHE -// 12076 CUNEIFORM SIGN DIM2 -// 12077 CUNEIFORM SIGN DIN -// 12078 CUNEIFORM SIGN DIN KASKAL U GUNU DISH -// 12079 CUNEIFORM SIGN DISH -// 1207a CUNEIFORM SIGN DU -// 1207b CUNEIFORM SIGN DU OVER DU -// 1207c CUNEIFORM SIGN DU GUNU -// 1207d CUNEIFORM SIGN DU SHESHIG -// 1207e CUNEIFORM SIGN DUB -// 1207f CUNEIFORM SIGN DUB TIMES ESH2 -// 12080 CUNEIFORM SIGN DUB2 -// 12081 CUNEIFORM SIGN DUG -// 12082 CUNEIFORM SIGN DUGUD -// 12083 CUNEIFORM SIGN DUH -// 12084 CUNEIFORM SIGN DUN -// 12085 CUNEIFORM SIGN DUN3 -// 12086 CUNEIFORM SIGN DUN3 GUNU -// 12087 CUNEIFORM SIGN DUN3 GUNU GUNU -// 12088 CUNEIFORM SIGN DUN4 -// 12089 CUNEIFORM SIGN DUR2 -// 1208a CUNEIFORM SIGN E -// 1208b CUNEIFORM SIGN E TIMES PAP -// 1208c CUNEIFORM SIGN E OVER E NUN OVER NUN -// 1208d CUNEIFORM SIGN E2 -// 1208e CUNEIFORM SIGN E2 TIMES A PLUS HA PLUS DA -// 1208f CUNEIFORM SIGN E2 TIMES GAR -// 12090 CUNEIFORM SIGN E2 TIMES MI -// 12091 CUNEIFORM SIGN E2 TIMES SAL -// 12092 CUNEIFORM SIGN E2 TIMES SHE -// 12093 CUNEIFORM SIGN E2 TIMES U -// 12094 CUNEIFORM SIGN EDIN -// 12095 CUNEIFORM SIGN EGIR -// 12096 CUNEIFORM SIGN EL -// 12097 CUNEIFORM SIGN EN -// 12098 CUNEIFORM SIGN EN TIMES GAN2 -// 12099 CUNEIFORM SIGN EN TIMES GAN2 TENU -// 1209a CUNEIFORM SIGN EN TIMES ME -// 1209b CUNEIFORM SIGN EN CROSSING EN -// 1209c CUNEIFORM SIGN EN OPPOSING EN -// 1209d CUNEIFORM SIGN EN SQUARED -// 1209e CUNEIFORM SIGN EREN -// 1209f CUNEIFORM SIGN ERIN2 -// 120a0 CUNEIFORM SIGN ESH2 -// 120a1 CUNEIFORM SIGN EZEN -// 120a2 CUNEIFORM SIGN EZEN TIMES A -// 120a3 CUNEIFORM SIGN EZEN TIMES A PLUS LAL -// 120a4 CUNEIFORM SIGN EZEN TIMES A PLUS LAL TIMES LAL -// 120a5 CUNEIFORM SIGN EZEN TIMES AN -// 120a6 CUNEIFORM SIGN EZEN TIMES BAD -// 120a7 CUNEIFORM SIGN EZEN TIMES DUN3 GUNU -// 120a8 CUNEIFORM SIGN EZEN TIMES DUN3 GUNU GUNU -// 120a9 CUNEIFORM SIGN EZEN TIMES HA -// 120aa CUNEIFORM SIGN EZEN TIMES HA GUNU -// 120ab CUNEIFORM SIGN EZEN TIMES IGI GUNU -// 120ac CUNEIFORM SIGN EZEN TIMES KASKAL -// 120ad CUNEIFORM SIGN EZEN TIMES KASKAL SQUARED -// 120ae CUNEIFORM SIGN EZEN TIMES KU3 -// 120af CUNEIFORM SIGN EZEN TIMES LA -// 120b0 CUNEIFORM SIGN EZEN TIMES LAL TIMES LAL -// 120b1 CUNEIFORM SIGN EZEN TIMES LI -// 120b2 CUNEIFORM SIGN EZEN TIMES LU -// 120b3 CUNEIFORM SIGN EZEN TIMES U2 -// 120b4 CUNEIFORM SIGN EZEN TIMES UD -// 120b5 CUNEIFORM SIGN GA -// 120b6 CUNEIFORM SIGN GA GUNU -// 120b7 CUNEIFORM SIGN GA2 -// 120b8 CUNEIFORM SIGN GA2 TIMES A PLUS DA PLUS HA -// 120b9 CUNEIFORM SIGN GA2 TIMES A PLUS HA -// 120ba CUNEIFORM SIGN GA2 TIMES A PLUS IGI -// 120bb CUNEIFORM SIGN GA2 TIMES AB2 TENU PLUS TAB -// 120bc CUNEIFORM SIGN GA2 TIMES AN -// 120bd CUNEIFORM SIGN GA2 TIMES ASH -// 120be CUNEIFORM SIGN GA2 TIMES ASH2 PLUS GAL -// 120bf CUNEIFORM SIGN GA2 TIMES BAD -// 120c0 CUNEIFORM SIGN GA2 TIMES BAR PLUS RA -// 120c1 CUNEIFORM SIGN GA2 TIMES BUR -// 120c2 CUNEIFORM SIGN GA2 TIMES BUR PLUS RA -// 120c3 CUNEIFORM SIGN GA2 TIMES DA -// 120c4 CUNEIFORM SIGN GA2 TIMES DI -// 120c5 CUNEIFORM SIGN GA2 TIMES DIM TIMES SHE -// 120c6 CUNEIFORM SIGN GA2 TIMES DUB -// 120c7 CUNEIFORM SIGN GA2 TIMES EL -// 120c8 CUNEIFORM SIGN GA2 TIMES EL PLUS LA -// 120c9 CUNEIFORM SIGN GA2 TIMES EN -// 120ca CUNEIFORM SIGN GA2 TIMES EN TIMES GAN2 TENU -// 120cb CUNEIFORM SIGN GA2 TIMES GAN2 TENU -// 120cc CUNEIFORM SIGN GA2 TIMES GAR -// 120cd CUNEIFORM SIGN GA2 TIMES GI -// 120ce CUNEIFORM SIGN GA2 TIMES GI4 -// 120cf CUNEIFORM SIGN GA2 TIMES GI4 PLUS A -// 120d0 CUNEIFORM SIGN GA2 TIMES GIR2 PLUS SU -// 120d1 CUNEIFORM SIGN GA2 TIMES HA PLUS LU PLUS ESH2 -// 120d2 CUNEIFORM SIGN GA2 TIMES HAL -// 120d3 CUNEIFORM SIGN GA2 TIMES HAL PLUS LA -// 120d4 CUNEIFORM SIGN GA2 TIMES HI PLUS LI -// 120d5 CUNEIFORM SIGN GA2 TIMES HUB2 -// 120d6 CUNEIFORM SIGN GA2 TIMES IGI GUNU -// 120d7 CUNEIFORM SIGN GA2 TIMES ISH PLUS HU PLUS ASH -// 120d8 CUNEIFORM SIGN GA2 TIMES KAK -// 120d9 CUNEIFORM SIGN GA2 TIMES KASKAL -// 120da CUNEIFORM SIGN GA2 TIMES KID -// 120db CUNEIFORM SIGN GA2 TIMES KID PLUS LAL -// 120dc CUNEIFORM SIGN GA2 TIMES KU3 PLUS AN -// 120dd CUNEIFORM SIGN GA2 TIMES LA -// 120de CUNEIFORM SIGN GA2 TIMES ME PLUS EN -// 120df CUNEIFORM SIGN GA2 TIMES MI -// 120e0 CUNEIFORM SIGN GA2 TIMES NUN -// 120e1 CUNEIFORM SIGN GA2 TIMES NUN OVER NUN -// 120e2 CUNEIFORM SIGN GA2 TIMES PA -// 120e3 CUNEIFORM SIGN GA2 TIMES SAL -// 120e4 CUNEIFORM SIGN GA2 TIMES SAR -// 120e5 CUNEIFORM SIGN GA2 TIMES SHE -// 120e6 CUNEIFORM SIGN GA2 TIMES SHE PLUS TUR -// 120e7 CUNEIFORM SIGN GA2 TIMES SHID -// 120e8 CUNEIFORM SIGN GA2 TIMES SUM -// 120e9 CUNEIFORM SIGN GA2 TIMES TAK4 -// 120ea CUNEIFORM SIGN GA2 TIMES U -// 120eb CUNEIFORM SIGN GA2 TIMES UD -// 120ec CUNEIFORM SIGN GA2 TIMES UD PLUS DU -// 120ed CUNEIFORM SIGN GA2 OVER GA2 -// 120ee CUNEIFORM SIGN GABA -// 120ef CUNEIFORM SIGN GABA CROSSING GABA -// 120f0 CUNEIFORM SIGN GAD -// 120f1 CUNEIFORM SIGN GAD OVER GAD GAR OVER GAR -// 120f2 CUNEIFORM SIGN GAL -// 120f3 CUNEIFORM SIGN GAL GAD OVER GAD GAR OVER GAR -// 120f4 CUNEIFORM SIGN GALAM -// 120f5 CUNEIFORM SIGN GAM -// 120f6 CUNEIFORM SIGN GAN -// 120f7 CUNEIFORM SIGN GAN2 -// 120f8 CUNEIFORM SIGN GAN2 TENU -// 120f9 CUNEIFORM SIGN GAN2 OVER GAN2 -// 120fa CUNEIFORM SIGN GAN2 CROSSING GAN2 -// 120fb CUNEIFORM SIGN GAR -// 120fc CUNEIFORM SIGN GAR3 -// 120fd CUNEIFORM SIGN GASHAN -// 120fe CUNEIFORM SIGN GESHTIN -// 120ff CUNEIFORM SIGN GESHTIN TIMES KUR -// 12100 CUNEIFORM SIGN GI -// 12101 CUNEIFORM SIGN GI TIMES E -// 12102 CUNEIFORM SIGN GI TIMES U -// 12103 CUNEIFORM SIGN GI CROSSING GI -// 12104 CUNEIFORM SIGN GI4 -// 12105 CUNEIFORM SIGN GI4 OVER GI4 -// 12106 CUNEIFORM SIGN GI4 CROSSING GI4 -// 12107 CUNEIFORM SIGN GIDIM -// 12108 CUNEIFORM SIGN GIR2 -// 12109 CUNEIFORM SIGN GIR2 GUNU -// 1210a CUNEIFORM SIGN GIR3 -// 1210b CUNEIFORM SIGN GIR3 TIMES A PLUS IGI -// 1210c CUNEIFORM SIGN GIR3 TIMES GAN2 TENU -// 1210d CUNEIFORM SIGN GIR3 TIMES IGI -// 1210e CUNEIFORM SIGN GIR3 TIMES LU PLUS IGI -// 1210f CUNEIFORM SIGN GIR3 TIMES PA -// 12110 CUNEIFORM SIGN GISAL -// 12111 CUNEIFORM SIGN GISH -// 12112 CUNEIFORM SIGN GISH CROSSING GISH -// 12113 CUNEIFORM SIGN GISH TIMES BAD -// 12114 CUNEIFORM SIGN GISH TIMES TAK4 -// 12115 CUNEIFORM SIGN GISH TENU -// 12116 CUNEIFORM SIGN GU -// 12117 CUNEIFORM SIGN GU CROSSING GU -// 12118 CUNEIFORM SIGN GU2 -// 12119 CUNEIFORM SIGN GU2 TIMES KAK -// 1211a CUNEIFORM SIGN GU2 TIMES KAK TIMES IGI GUNU -// 1211b CUNEIFORM SIGN GU2 TIMES NUN -// 1211c CUNEIFORM SIGN GU2 TIMES SAL PLUS TUG2 -// 1211d CUNEIFORM SIGN GU2 GUNU -// 1211e CUNEIFORM SIGN GUD -// 1211f CUNEIFORM SIGN GUD TIMES A PLUS KUR -// 12120 CUNEIFORM SIGN GUD TIMES KUR -// 12121 CUNEIFORM SIGN GUD OVER GUD LUGAL -// 12122 CUNEIFORM SIGN GUL -// 12123 CUNEIFORM SIGN GUM -// 12124 CUNEIFORM SIGN GUM TIMES SHE -// 12125 CUNEIFORM SIGN GUR -// 12126 CUNEIFORM SIGN GUR7 -// 12127 CUNEIFORM SIGN GURUN -// 12128 CUNEIFORM SIGN GURUSH -// 12129 CUNEIFORM SIGN HA -// 1212a CUNEIFORM SIGN HA TENU -// 1212b CUNEIFORM SIGN HA GUNU -// 1212c CUNEIFORM SIGN HAL -// 1212d CUNEIFORM SIGN HI -// 1212e CUNEIFORM SIGN HI TIMES ASH -// 1212f CUNEIFORM SIGN HI TIMES ASH2 -// 12130 CUNEIFORM SIGN HI TIMES BAD -// 12131 CUNEIFORM SIGN HI TIMES DISH -// 12132 CUNEIFORM SIGN HI TIMES GAD -// 12133 CUNEIFORM SIGN HI TIMES KIN -// 12134 CUNEIFORM SIGN HI TIMES NUN -// 12135 CUNEIFORM SIGN HI TIMES SHE -// 12136 CUNEIFORM SIGN HI TIMES U -// 12137 CUNEIFORM SIGN HU -// 12138 CUNEIFORM SIGN HUB2 -// 12139 CUNEIFORM SIGN HUB2 TIMES AN -// 1213a CUNEIFORM SIGN HUB2 TIMES HAL -// 1213b CUNEIFORM SIGN HUB2 TIMES KASKAL -// 1213c CUNEIFORM SIGN HUB2 TIMES LISH -// 1213d CUNEIFORM SIGN HUB2 TIMES UD -// 1213e CUNEIFORM SIGN HUL2 -// 1213f CUNEIFORM SIGN I -// 12140 CUNEIFORM SIGN I A -// 12141 CUNEIFORM SIGN IB -// 12142 CUNEIFORM SIGN IDIM -// 12143 CUNEIFORM SIGN IDIM OVER IDIM BUR -// 12144 CUNEIFORM SIGN IDIM OVER IDIM SQUARED -// 12145 CUNEIFORM SIGN IG -// 12146 CUNEIFORM SIGN IGI -// 12147 CUNEIFORM SIGN IGI DIB -// 12148 CUNEIFORM SIGN IGI RI -// 12149 CUNEIFORM SIGN IGI OVER IGI SHIR OVER SHIR UD OVER UD -// 1214a CUNEIFORM SIGN IGI GUNU -// 1214b CUNEIFORM SIGN IL -// 1214c CUNEIFORM SIGN IL TIMES GAN2 TENU -// 1214d CUNEIFORM SIGN IL2 -// 1214e CUNEIFORM SIGN IM -// 1214f CUNEIFORM SIGN IM TIMES TAK4 -// 12150 CUNEIFORM SIGN IM CROSSING IM -// 12151 CUNEIFORM SIGN IM OPPOSING IM -// 12152 CUNEIFORM SIGN IM SQUARED -// 12153 CUNEIFORM SIGN IMIN -// 12154 CUNEIFORM SIGN IN -// 12155 CUNEIFORM SIGN IR -// 12156 CUNEIFORM SIGN ISH -// 12157 CUNEIFORM SIGN KA -// 12158 CUNEIFORM SIGN KA TIMES A -// 12159 CUNEIFORM SIGN KA TIMES AD -// 1215a CUNEIFORM SIGN KA TIMES AD PLUS KU3 -// 1215b CUNEIFORM SIGN KA TIMES ASH2 -// 1215c CUNEIFORM SIGN KA TIMES BAD -// 1215d CUNEIFORM SIGN KA TIMES BALAG -// 1215e CUNEIFORM SIGN KA TIMES BAR -// 1215f CUNEIFORM SIGN KA TIMES BI -// 12160 CUNEIFORM SIGN KA TIMES ERIN2 -// 12161 CUNEIFORM SIGN KA TIMES ESH2 -// 12162 CUNEIFORM SIGN KA TIMES GA -// 12163 CUNEIFORM SIGN KA TIMES GAL -// 12164 CUNEIFORM SIGN KA TIMES GAN2 TENU -// 12165 CUNEIFORM SIGN KA TIMES GAR -// 12166 CUNEIFORM SIGN KA TIMES GAR PLUS SHA3 PLUS A -// 12167 CUNEIFORM SIGN KA TIMES GI -// 12168 CUNEIFORM SIGN KA TIMES GIR2 -// 12169 CUNEIFORM SIGN KA TIMES GISH PLUS SAR -// 1216a CUNEIFORM SIGN KA TIMES GISH CROSSING GISH -// 1216b CUNEIFORM SIGN KA TIMES GU -// 1216c CUNEIFORM SIGN KA TIMES GUR7 -// 1216d CUNEIFORM SIGN KA TIMES IGI -// 1216e CUNEIFORM SIGN KA TIMES IM -// 1216f CUNEIFORM SIGN KA TIMES KAK -// 12170 CUNEIFORM SIGN KA TIMES KI -// 12171 CUNEIFORM SIGN KA TIMES KID -// 12172 CUNEIFORM SIGN KA TIMES LI -// 12173 CUNEIFORM SIGN KA TIMES LU -// 12174 CUNEIFORM SIGN KA TIMES ME -// 12175 CUNEIFORM SIGN KA TIMES ME PLUS DU -// 12176 CUNEIFORM SIGN KA TIMES ME PLUS GI -// 12177 CUNEIFORM SIGN KA TIMES ME PLUS TE -// 12178 CUNEIFORM SIGN KA TIMES MI -// 12179 CUNEIFORM SIGN KA TIMES MI PLUS NUNUZ -// 1217a CUNEIFORM SIGN KA TIMES NE -// 1217b CUNEIFORM SIGN KA TIMES NUN -// 1217c CUNEIFORM SIGN KA TIMES PI -// 1217d CUNEIFORM SIGN KA TIMES RU -// 1217e CUNEIFORM SIGN KA TIMES SA -// 1217f CUNEIFORM SIGN KA TIMES SAR -// 12180 CUNEIFORM SIGN KA TIMES SHA -// 12181 CUNEIFORM SIGN KA TIMES SHE -// 12182 CUNEIFORM SIGN KA TIMES SHID -// 12183 CUNEIFORM SIGN KA TIMES SHU -// 12184 CUNEIFORM SIGN KA TIMES SIG -// 12185 CUNEIFORM SIGN KA TIMES SUHUR -// 12186 CUNEIFORM SIGN KA TIMES TAR -// 12187 CUNEIFORM SIGN KA TIMES U -// 12188 CUNEIFORM SIGN KA TIMES U2 -// 12189 CUNEIFORM SIGN KA TIMES UD -// 1218a CUNEIFORM SIGN KA TIMES UMUM TIMES PA -// 1218b CUNEIFORM SIGN KA TIMES USH -// 1218c CUNEIFORM SIGN KA TIMES ZI -// 1218d CUNEIFORM SIGN KA2 -// 1218e CUNEIFORM SIGN KA2 CROSSING KA2 -// 1218f CUNEIFORM SIGN KAB -// 12190 CUNEIFORM SIGN KAD2 -// 12191 CUNEIFORM SIGN KAD3 -// 12192 CUNEIFORM SIGN KAD4 -// 12193 CUNEIFORM SIGN KAD5 -// 12194 CUNEIFORM SIGN KAD5 OVER KAD5 -// 12195 CUNEIFORM SIGN KAK -// 12196 CUNEIFORM SIGN KAK TIMES IGI GUNU -// 12197 CUNEIFORM SIGN KAL -// 12198 CUNEIFORM SIGN KAL TIMES BAD -// 12199 CUNEIFORM SIGN KAL CROSSING KAL -// 1219a CUNEIFORM SIGN KAM2 -// 1219b CUNEIFORM SIGN KAM4 -// 1219c CUNEIFORM SIGN KASKAL -// 1219d CUNEIFORM SIGN KASKAL LAGAB TIMES U OVER LAGAB TIMES U -// 1219e CUNEIFORM SIGN KASKAL OVER KASKAL LAGAB TIMES U OVER LAGAB TIMES U -// 1219f CUNEIFORM SIGN KESH2 -// 121a0 CUNEIFORM SIGN KI -// 121a1 CUNEIFORM SIGN KI TIMES BAD -// 121a2 CUNEIFORM SIGN KI TIMES U -// 121a3 CUNEIFORM SIGN KI TIMES UD -// 121a4 CUNEIFORM SIGN KID -// 121a5 CUNEIFORM SIGN KIN -// 121a6 CUNEIFORM SIGN KISAL -// 121a7 CUNEIFORM SIGN KISH -// 121a8 CUNEIFORM SIGN KISIM5 -// 121a9 CUNEIFORM SIGN KISIM5 OVER KISIM5 -// 121aa CUNEIFORM SIGN KU -// 121ab CUNEIFORM SIGN KU OVER HI TIMES ASH2 KU OVER HI TIMES ASH2 -// 121ac CUNEIFORM SIGN KU3 -// 121ad CUNEIFORM SIGN KU4 -// 121ae CUNEIFORM SIGN KU4 VARIANT FORM -// 121af CUNEIFORM SIGN KU7 -// 121b0 CUNEIFORM SIGN KUL -// 121b1 CUNEIFORM SIGN KUL GUNU -// 121b2 CUNEIFORM SIGN KUN -// 121b3 CUNEIFORM SIGN KUR -// 121b4 CUNEIFORM SIGN KUR OPPOSING KUR -// 121b5 CUNEIFORM SIGN KUSHU2 -// 121b6 CUNEIFORM SIGN KWU318 -// 121b7 CUNEIFORM SIGN LA -// 121b8 CUNEIFORM SIGN LAGAB -// 121b9 CUNEIFORM SIGN LAGAB TIMES A -// 121ba CUNEIFORM SIGN LAGAB TIMES A PLUS DA PLUS HA -// 121bb CUNEIFORM SIGN LAGAB TIMES A PLUS GAR -// 121bc CUNEIFORM SIGN LAGAB TIMES A PLUS LAL -// 121bd CUNEIFORM SIGN LAGAB TIMES AL -// 121be CUNEIFORM SIGN LAGAB TIMES AN -// 121bf CUNEIFORM SIGN LAGAB TIMES ASH ZIDA TENU -// 121c0 CUNEIFORM SIGN LAGAB TIMES BAD -// 121c1 CUNEIFORM SIGN LAGAB TIMES BI -// 121c2 CUNEIFORM SIGN LAGAB TIMES DAR -// 121c3 CUNEIFORM SIGN LAGAB TIMES EN -// 121c4 CUNEIFORM SIGN LAGAB TIMES GA -// 121c5 CUNEIFORM SIGN LAGAB TIMES GAR -// 121c6 CUNEIFORM SIGN LAGAB TIMES GUD -// 121c7 CUNEIFORM SIGN LAGAB TIMES GUD PLUS GUD -// 121c8 CUNEIFORM SIGN LAGAB TIMES HA -// 121c9 CUNEIFORM SIGN LAGAB TIMES HAL -// 121ca CUNEIFORM SIGN LAGAB TIMES HI TIMES NUN -// 121cb CUNEIFORM SIGN LAGAB TIMES IGI GUNU -// 121cc CUNEIFORM SIGN LAGAB TIMES IM -// 121cd CUNEIFORM SIGN LAGAB TIMES IM PLUS HA -// 121ce CUNEIFORM SIGN LAGAB TIMES IM PLUS LU -// 121cf CUNEIFORM SIGN LAGAB TIMES KI -// 121d0 CUNEIFORM SIGN LAGAB TIMES KIN -// 121d1 CUNEIFORM SIGN LAGAB TIMES KU3 -// 121d2 CUNEIFORM SIGN LAGAB TIMES KUL -// 121d3 CUNEIFORM SIGN LAGAB TIMES KUL PLUS HI PLUS A -// 121d4 CUNEIFORM SIGN LAGAB TIMES LAGAB -// 121d5 CUNEIFORM SIGN LAGAB TIMES LISH -// 121d6 CUNEIFORM SIGN LAGAB TIMES LU -// 121d7 CUNEIFORM SIGN LAGAB TIMES LUL -// 121d8 CUNEIFORM SIGN LAGAB TIMES ME -// 121d9 CUNEIFORM SIGN LAGAB TIMES ME PLUS EN -// 121da CUNEIFORM SIGN LAGAB TIMES MUSH -// 121db CUNEIFORM SIGN LAGAB TIMES NE -// 121dc CUNEIFORM SIGN LAGAB TIMES SHE PLUS SUM -// 121dd CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH PLUS ERIN2 -// 121de CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH TENU -// 121df CUNEIFORM SIGN LAGAB TIMES SHU2 -// 121e0 CUNEIFORM SIGN LAGAB TIMES SHU2 PLUS SHU2 -// 121e1 CUNEIFORM SIGN LAGAB TIMES SUM -// 121e2 CUNEIFORM SIGN LAGAB TIMES TAG -// 121e3 CUNEIFORM SIGN LAGAB TIMES TAK4 -// 121e4 CUNEIFORM SIGN LAGAB TIMES TE PLUS A PLUS SU PLUS NA -// 121e5 CUNEIFORM SIGN LAGAB TIMES U -// 121e6 CUNEIFORM SIGN LAGAB TIMES U PLUS A -// 121e7 CUNEIFORM SIGN LAGAB TIMES U PLUS U PLUS U -// 121e8 CUNEIFORM SIGN LAGAB TIMES U2 PLUS ASH -// 121e9 CUNEIFORM SIGN LAGAB TIMES UD -// 121ea CUNEIFORM SIGN LAGAB TIMES USH -// 121eb CUNEIFORM SIGN LAGAB SQUARED -// 121ec CUNEIFORM SIGN LAGAR -// 121ed CUNEIFORM SIGN LAGAR TIMES SHE -// 121ee CUNEIFORM SIGN LAGAR TIMES SHE PLUS SUM -// 121ef CUNEIFORM SIGN LAGAR GUNU -// 121f0 CUNEIFORM SIGN LAGAR GUNU OVER LAGAR GUNU SHE -// 121f1 CUNEIFORM SIGN LAHSHU -// 121f2 CUNEIFORM SIGN LAL -// 121f3 CUNEIFORM SIGN LAL TIMES LAL -// 121f4 CUNEIFORM SIGN LAM -// 121f5 CUNEIFORM SIGN LAM TIMES KUR -// 121f6 CUNEIFORM SIGN LAM TIMES KUR PLUS RU -// 121f7 CUNEIFORM SIGN LI -// 121f8 CUNEIFORM SIGN LIL -// 121f9 CUNEIFORM SIGN LIMMU2 -// 121fa CUNEIFORM SIGN LISH -// 121fb CUNEIFORM SIGN LU -// 121fc CUNEIFORM SIGN LU TIMES BAD -// 121fd CUNEIFORM SIGN LU2 -// 121fe CUNEIFORM SIGN LU2 TIMES AL -// 121ff CUNEIFORM SIGN LU2 TIMES BAD -// 12200 CUNEIFORM SIGN LU2 TIMES ESH2 -// 12201 CUNEIFORM SIGN LU2 TIMES ESH2 TENU -// 12202 CUNEIFORM SIGN LU2 TIMES GAN2 TENU -// 12203 CUNEIFORM SIGN LU2 TIMES HI TIMES BAD -// 12204 CUNEIFORM SIGN LU2 TIMES IM -// 12205 CUNEIFORM SIGN LU2 TIMES KAD2 -// 12206 CUNEIFORM SIGN LU2 TIMES KAD3 -// 12207 CUNEIFORM SIGN LU2 TIMES KAD3 PLUS ASH -// 12208 CUNEIFORM SIGN LU2 TIMES KI -// 12209 CUNEIFORM SIGN LU2 TIMES LA PLUS ASH -// 1220a CUNEIFORM SIGN LU2 TIMES LAGAB -// 1220b CUNEIFORM SIGN LU2 TIMES ME PLUS EN -// 1220c CUNEIFORM SIGN LU2 TIMES NE -// 1220d CUNEIFORM SIGN LU2 TIMES NU -// 1220e CUNEIFORM SIGN LU2 TIMES SI PLUS ASH -// 1220f CUNEIFORM SIGN LU2 TIMES SIK2 PLUS BU -// 12210 CUNEIFORM SIGN LU2 TIMES TUG2 -// 12211 CUNEIFORM SIGN LU2 TENU -// 12212 CUNEIFORM SIGN LU2 CROSSING LU2 -// 12213 CUNEIFORM SIGN LU2 OPPOSING LU2 -// 12214 CUNEIFORM SIGN LU2 SQUARED -// 12215 CUNEIFORM SIGN LU2 SHESHIG -// 12216 CUNEIFORM SIGN LU3 -// 12217 CUNEIFORM SIGN LUGAL -// 12218 CUNEIFORM SIGN LUGAL OVER LUGAL -// 12219 CUNEIFORM SIGN LUGAL OPPOSING LUGAL -// 1221a CUNEIFORM SIGN LUGAL SHESHIG -// 1221b CUNEIFORM SIGN LUH -// 1221c CUNEIFORM SIGN LUL -// 1221d CUNEIFORM SIGN LUM -// 1221e CUNEIFORM SIGN LUM OVER LUM -// 1221f CUNEIFORM SIGN LUM OVER LUM GAR OVER GAR -// 12220 CUNEIFORM SIGN MA -// 12221 CUNEIFORM SIGN MA TIMES TAK4 -// 12222 CUNEIFORM SIGN MA GUNU -// 12223 CUNEIFORM SIGN MA2 -// 12224 CUNEIFORM SIGN MAH -// 12225 CUNEIFORM SIGN MAR -// 12226 CUNEIFORM SIGN MASH -// 12227 CUNEIFORM SIGN MASH2 -// 12228 CUNEIFORM SIGN ME -// 12229 CUNEIFORM SIGN MES -// 1222a CUNEIFORM SIGN MI -// 1222b CUNEIFORM SIGN MIN -// 1222c CUNEIFORM SIGN MU -// 1222d CUNEIFORM SIGN MU OVER MU -// 1222e CUNEIFORM SIGN MUG -// 1222f CUNEIFORM SIGN MUG GUNU -// 12230 CUNEIFORM SIGN MUNSUB -// 12231 CUNEIFORM SIGN MURGU2 -// 12232 CUNEIFORM SIGN MUSH -// 12233 CUNEIFORM SIGN MUSH TIMES A -// 12234 CUNEIFORM SIGN MUSH TIMES KUR -// 12235 CUNEIFORM SIGN MUSH TIMES ZA -// 12236 CUNEIFORM SIGN MUSH OVER MUSH -// 12237 CUNEIFORM SIGN MUSH OVER MUSH TIMES A PLUS NA -// 12238 CUNEIFORM SIGN MUSH CROSSING MUSH -// 12239 CUNEIFORM SIGN MUSH3 -// 1223a CUNEIFORM SIGN MUSH3 TIMES A -// 1223b CUNEIFORM SIGN MUSH3 TIMES A PLUS DI -// 1223c CUNEIFORM SIGN MUSH3 TIMES DI -// 1223d CUNEIFORM SIGN MUSH3 GUNU -// 1223e CUNEIFORM SIGN NA -// 1223f CUNEIFORM SIGN NA2 -// 12240 CUNEIFORM SIGN NAGA -// 12241 CUNEIFORM SIGN NAGA INVERTED -// 12242 CUNEIFORM SIGN NAGA TIMES SHU TENU -// 12243 CUNEIFORM SIGN NAGA OPPOSING NAGA -// 12244 CUNEIFORM SIGN NAGAR -// 12245 CUNEIFORM SIGN NAM NUTILLU -// 12246 CUNEIFORM SIGN NAM -// 12247 CUNEIFORM SIGN NAM2 -// 12248 CUNEIFORM SIGN NE -// 12249 CUNEIFORM SIGN NE TIMES A -// 1224a CUNEIFORM SIGN NE TIMES UD -// 1224b CUNEIFORM SIGN NE SHESHIG -// 1224c CUNEIFORM SIGN NI -// 1224d CUNEIFORM SIGN NI TIMES E -// 1224e CUNEIFORM SIGN NI2 -// 1224f CUNEIFORM SIGN NIM -// 12250 CUNEIFORM SIGN NIM TIMES GAN2 TENU -// 12251 CUNEIFORM SIGN NIM TIMES GAR PLUS GAN2 TENU -// 12252 CUNEIFORM SIGN NINDA2 -// 12253 CUNEIFORM SIGN NINDA2 TIMES AN -// 12254 CUNEIFORM SIGN NINDA2 TIMES ASH -// 12255 CUNEIFORM SIGN NINDA2 TIMES ASH PLUS ASH -// 12256 CUNEIFORM SIGN NINDA2 TIMES GUD -// 12257 CUNEIFORM SIGN NINDA2 TIMES ME PLUS GAN2 TENU -// 12258 CUNEIFORM SIGN NINDA2 TIMES NE -// 12259 CUNEIFORM SIGN NINDA2 TIMES NUN -// 1225a CUNEIFORM SIGN NINDA2 TIMES SHE -// 1225b CUNEIFORM SIGN NINDA2 TIMES SHE PLUS A AN -// 1225c CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH -// 1225d CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH PLUS ASH -// 1225e CUNEIFORM SIGN NINDA2 TIMES U2 PLUS ASH -// 1225f CUNEIFORM SIGN NINDA2 TIMES USH -// 12260 CUNEIFORM SIGN NISAG -// 12261 CUNEIFORM SIGN NU -// 12262 CUNEIFORM SIGN NU11 -// 12263 CUNEIFORM SIGN NUN -// 12264 CUNEIFORM SIGN NUN LAGAR TIMES GAR -// 12265 CUNEIFORM SIGN NUN LAGAR TIMES MASH -// 12266 CUNEIFORM SIGN NUN LAGAR TIMES SAL -// 12267 CUNEIFORM SIGN NUN LAGAR TIMES SAL OVER NUN LAGAR TIMES SAL -// 12268 CUNEIFORM SIGN NUN LAGAR TIMES USH -// 12269 CUNEIFORM SIGN NUN TENU -// 1226a CUNEIFORM SIGN NUN OVER NUN -// 1226b CUNEIFORM SIGN NUN CROSSING NUN -// 1226c CUNEIFORM SIGN NUN CROSSING NUN LAGAR OVER LAGAR -// 1226d CUNEIFORM SIGN NUNUZ -// 1226e CUNEIFORM SIGN NUNUZ AB2 TIMES ASHGAB -// 1226f CUNEIFORM SIGN NUNUZ AB2 TIMES BI -// 12270 CUNEIFORM SIGN NUNUZ AB2 TIMES DUG -// 12271 CUNEIFORM SIGN NUNUZ AB2 TIMES GUD -// 12272 CUNEIFORM SIGN NUNUZ AB2 TIMES IGI GUNU -// 12273 CUNEIFORM SIGN NUNUZ AB2 TIMES KAD3 -// 12274 CUNEIFORM SIGN NUNUZ AB2 TIMES LA -// 12275 CUNEIFORM SIGN NUNUZ AB2 TIMES NE -// 12276 CUNEIFORM SIGN NUNUZ AB2 TIMES SILA3 -// 12277 CUNEIFORM SIGN NUNUZ AB2 TIMES U2 -// 12278 CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI -// 12279 CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI U -// 1227a CUNEIFORM SIGN PA -// 1227b CUNEIFORM SIGN PAD -// 1227c CUNEIFORM SIGN PAN -// 1227d CUNEIFORM SIGN PAP -// 1227e CUNEIFORM SIGN PESH2 -// 1227f CUNEIFORM SIGN PI -// 12280 CUNEIFORM SIGN PI TIMES A -// 12281 CUNEIFORM SIGN PI TIMES AB -// 12282 CUNEIFORM SIGN PI TIMES BI -// 12283 CUNEIFORM SIGN PI TIMES BU -// 12284 CUNEIFORM SIGN PI TIMES E -// 12285 CUNEIFORM SIGN PI TIMES I -// 12286 CUNEIFORM SIGN PI TIMES IB -// 12287 CUNEIFORM SIGN PI TIMES U -// 12288 CUNEIFORM SIGN PI TIMES U2 -// 12289 CUNEIFORM SIGN PI CROSSING PI -// 1228a CUNEIFORM SIGN PIRIG -// 1228b CUNEIFORM SIGN PIRIG TIMES KAL -// 1228c CUNEIFORM SIGN PIRIG TIMES UD -// 1228d CUNEIFORM SIGN PIRIG TIMES ZA -// 1228e CUNEIFORM SIGN PIRIG OPPOSING PIRIG -// 1228f CUNEIFORM SIGN RA -// 12290 CUNEIFORM SIGN RAB -// 12291 CUNEIFORM SIGN RI -// 12292 CUNEIFORM SIGN RU -// 12293 CUNEIFORM SIGN SA -// 12294 CUNEIFORM SIGN SAG NUTILLU -// 12295 CUNEIFORM SIGN SAG -// 12296 CUNEIFORM SIGN SAG TIMES A -// 12297 CUNEIFORM SIGN SAG TIMES DU -// 12298 CUNEIFORM SIGN SAG TIMES DUB -// 12299 CUNEIFORM SIGN SAG TIMES HA -// 1229a CUNEIFORM SIGN SAG TIMES KAK -// 1229b CUNEIFORM SIGN SAG TIMES KUR -// 1229c CUNEIFORM SIGN SAG TIMES LUM -// 1229d CUNEIFORM SIGN SAG TIMES MI -// 1229e CUNEIFORM SIGN SAG TIMES NUN -// 1229f CUNEIFORM SIGN SAG TIMES SAL -// 122a0 CUNEIFORM SIGN SAG TIMES SHID -// 122a1 CUNEIFORM SIGN SAG TIMES TAB -// 122a2 CUNEIFORM SIGN SAG TIMES U2 -// 122a3 CUNEIFORM SIGN SAG TIMES UB -// 122a4 CUNEIFORM SIGN SAG TIMES UM -// 122a5 CUNEIFORM SIGN SAG TIMES UR -// 122a6 CUNEIFORM SIGN SAG TIMES USH -// 122a7 CUNEIFORM SIGN SAG OVER SAG -// 122a8 CUNEIFORM SIGN SAG GUNU -// 122a9 CUNEIFORM SIGN SAL -// 122aa CUNEIFORM SIGN SAL LAGAB TIMES ASH2 -// 122ab CUNEIFORM SIGN SANGA2 -// 122ac CUNEIFORM SIGN SAR -// 122ad CUNEIFORM SIGN SHA -// 122ae CUNEIFORM SIGN SHA3 -// 122af CUNEIFORM SIGN SHA3 TIMES A -// 122b0 CUNEIFORM SIGN SHA3 TIMES BAD -// 122b1 CUNEIFORM SIGN SHA3 TIMES GISH -// 122b2 CUNEIFORM SIGN SHA3 TIMES NE -// 122b3 CUNEIFORM SIGN SHA3 TIMES SHU2 -// 122b4 CUNEIFORM SIGN SHA3 TIMES TUR -// 122b5 CUNEIFORM SIGN SHA3 TIMES U -// 122b6 CUNEIFORM SIGN SHA3 TIMES U PLUS A -// 122b7 CUNEIFORM SIGN SHA6 -// 122b8 CUNEIFORM SIGN SHAB6 -// 122b9 CUNEIFORM SIGN SHAR2 -// 122ba CUNEIFORM SIGN SHE -// 122bb CUNEIFORM SIGN SHE HU -// 122bc CUNEIFORM SIGN SHE OVER SHE GAD OVER GAD GAR OVER GAR -// 122bd CUNEIFORM SIGN SHE OVER SHE TAB OVER TAB GAR OVER GAR -// 122be CUNEIFORM SIGN SHEG9 -// 122bf CUNEIFORM SIGN SHEN -// 122c0 CUNEIFORM SIGN SHESH -// 122c1 CUNEIFORM SIGN SHESH2 -// 122c2 CUNEIFORM SIGN SHESHLAM -// 122c3 CUNEIFORM SIGN SHID -// 122c4 CUNEIFORM SIGN SHID TIMES A -// 122c5 CUNEIFORM SIGN SHID TIMES IM -// 122c6 CUNEIFORM SIGN SHIM -// 122c7 CUNEIFORM SIGN SHIM TIMES A -// 122c8 CUNEIFORM SIGN SHIM TIMES BAL -// 122c9 CUNEIFORM SIGN SHIM TIMES BULUG -// 122ca CUNEIFORM SIGN SHIM TIMES DIN -// 122cb CUNEIFORM SIGN SHIM TIMES GAR -// 122cc CUNEIFORM SIGN SHIM TIMES IGI -// 122cd CUNEIFORM SIGN SHIM TIMES IGI GUNU -// 122ce CUNEIFORM SIGN SHIM TIMES KUSHU2 -// 122cf CUNEIFORM SIGN SHIM TIMES LUL -// 122d0 CUNEIFORM SIGN SHIM TIMES MUG -// 122d1 CUNEIFORM SIGN SHIM TIMES SAL -// 122d2 CUNEIFORM SIGN SHINIG -// 122d3 CUNEIFORM SIGN SHIR -// 122d4 CUNEIFORM SIGN SHIR TENU -// 122d5 CUNEIFORM SIGN SHIR OVER SHIR BUR OVER BUR -// 122d6 CUNEIFORM SIGN SHITA -// 122d7 CUNEIFORM SIGN SHU -// 122d8 CUNEIFORM SIGN SHU OVER INVERTED SHU -// 122d9 CUNEIFORM SIGN SHU2 -// 122da CUNEIFORM SIGN SHUBUR -// 122db CUNEIFORM SIGN SI -// 122dc CUNEIFORM SIGN SI GUNU -// 122dd CUNEIFORM SIGN SIG -// 122de CUNEIFORM SIGN SIG4 -// 122df CUNEIFORM SIGN SIG4 OVER SIG4 SHU2 -// 122e0 CUNEIFORM SIGN SIK2 -// 122e1 CUNEIFORM SIGN SILA3 -// 122e2 CUNEIFORM SIGN SU -// 122e3 CUNEIFORM SIGN SU OVER SU -// 122e4 CUNEIFORM SIGN SUD -// 122e5 CUNEIFORM SIGN SUD2 -// 122e6 CUNEIFORM SIGN SUHUR -// 122e7 CUNEIFORM SIGN SUM -// 122e8 CUNEIFORM SIGN SUMASH -// 122e9 CUNEIFORM SIGN SUR -// 122ea CUNEIFORM SIGN SUR9 -// 122eb CUNEIFORM SIGN TA -// 122ec CUNEIFORM SIGN TA ASTERISK -// 122ed CUNEIFORM SIGN TA TIMES HI -// 122ee CUNEIFORM SIGN TA TIMES MI -// 122ef CUNEIFORM SIGN TA GUNU -// 122f0 CUNEIFORM SIGN TAB -// 122f1 CUNEIFORM SIGN TAB OVER TAB NI OVER NI DISH OVER DISH -// 122f2 CUNEIFORM SIGN TAB SQUARED -// 122f3 CUNEIFORM SIGN TAG -// 122f4 CUNEIFORM SIGN TAG TIMES BI -// 122f5 CUNEIFORM SIGN TAG TIMES GUD -// 122f6 CUNEIFORM SIGN TAG TIMES SHE -// 122f7 CUNEIFORM SIGN TAG TIMES SHU -// 122f8 CUNEIFORM SIGN TAG TIMES TUG2 -// 122f9 CUNEIFORM SIGN TAG TIMES UD -// 122fa CUNEIFORM SIGN TAK4 -// 122fb CUNEIFORM SIGN TAR -// 122fc CUNEIFORM SIGN TE -// 122fd CUNEIFORM SIGN TE GUNU -// 122fe CUNEIFORM SIGN TI -// 122ff CUNEIFORM SIGN TI TENU -// 12300 CUNEIFORM SIGN TIL -// 12301 CUNEIFORM SIGN TIR -// 12302 CUNEIFORM SIGN TIR TIMES TAK4 -// 12303 CUNEIFORM SIGN TIR OVER TIR -// 12304 CUNEIFORM SIGN TIR OVER TIR GAD OVER GAD GAR OVER GAR -// 12305 CUNEIFORM SIGN TU -// 12306 CUNEIFORM SIGN TUG2 -// 12307 CUNEIFORM SIGN TUK -// 12308 CUNEIFORM SIGN TUM -// 12309 CUNEIFORM SIGN TUR -// 1230a CUNEIFORM SIGN TUR OVER TUR ZA OVER ZA -// 1230b CUNEIFORM SIGN U -// 1230c CUNEIFORM SIGN U GUD -// 1230d CUNEIFORM SIGN U U U -// 1230e CUNEIFORM SIGN U OVER U PA OVER PA GAR OVER GAR -// 1230f CUNEIFORM SIGN U OVER U SUR OVER SUR -// 12310 CUNEIFORM SIGN U OVER U U REVERSED OVER U REVERSED -// 12311 CUNEIFORM SIGN U2 -// 12312 CUNEIFORM SIGN UB -// 12313 CUNEIFORM SIGN UD -// 12314 CUNEIFORM SIGN UD KUSHU2 -// 12315 CUNEIFORM SIGN UD TIMES BAD -// 12316 CUNEIFORM SIGN UD TIMES MI -// 12317 CUNEIFORM SIGN UD TIMES U PLUS U PLUS U -// 12318 CUNEIFORM SIGN UD TIMES U PLUS U PLUS U GUNU -// 12319 CUNEIFORM SIGN UD GUNU -// 1231a CUNEIFORM SIGN UD SHESHIG -// 1231b CUNEIFORM SIGN UD SHESHIG TIMES BAD -// 1231c CUNEIFORM SIGN UDUG -// 1231d CUNEIFORM SIGN UM -// 1231e CUNEIFORM SIGN UM TIMES LAGAB -// 1231f CUNEIFORM SIGN UM TIMES ME PLUS DA -// 12320 CUNEIFORM SIGN UM TIMES SHA3 -// 12321 CUNEIFORM SIGN UM TIMES U -// 12322 CUNEIFORM SIGN UMBIN -// 12323 CUNEIFORM SIGN UMUM -// 12324 CUNEIFORM SIGN UMUM TIMES KASKAL -// 12325 CUNEIFORM SIGN UMUM TIMES PA -// 12326 CUNEIFORM SIGN UN -// 12327 CUNEIFORM SIGN UN GUNU -// 12328 CUNEIFORM SIGN UR -// 12329 CUNEIFORM SIGN UR CROSSING UR -// 1232a CUNEIFORM SIGN UR SHESHIG -// 1232b CUNEIFORM SIGN UR2 -// 1232c CUNEIFORM SIGN UR2 TIMES A PLUS HA -// 1232d CUNEIFORM SIGN UR2 TIMES A PLUS NA -// 1232e CUNEIFORM SIGN UR2 TIMES AL -// 1232f CUNEIFORM SIGN UR2 TIMES HA -// 12330 CUNEIFORM SIGN UR2 TIMES NUN -// 12331 CUNEIFORM SIGN UR2 TIMES U2 -// 12332 CUNEIFORM SIGN UR2 TIMES U2 PLUS ASH -// 12333 CUNEIFORM SIGN UR2 TIMES U2 PLUS BI -// 12334 CUNEIFORM SIGN UR4 -// 12335 CUNEIFORM SIGN URI -// 12336 CUNEIFORM SIGN URI3 -// 12337 CUNEIFORM SIGN URU -// 12338 CUNEIFORM SIGN URU TIMES A -// 12339 CUNEIFORM SIGN URU TIMES ASHGAB -// 1233a CUNEIFORM SIGN URU TIMES BAR -// 1233b CUNEIFORM SIGN URU TIMES DUN -// 1233c CUNEIFORM SIGN URU TIMES GA -// 1233d CUNEIFORM SIGN URU TIMES GAL -// 1233e CUNEIFORM SIGN URU TIMES GAN2 TENU -// 1233f CUNEIFORM SIGN URU TIMES GAR -// 12340 CUNEIFORM SIGN URU TIMES GU -// 12341 CUNEIFORM SIGN URU TIMES HA -// 12342 CUNEIFORM SIGN URU TIMES IGI -// 12343 CUNEIFORM SIGN URU TIMES IM -// 12344 CUNEIFORM SIGN URU TIMES ISH -// 12345 CUNEIFORM SIGN URU TIMES KI -// 12346 CUNEIFORM SIGN URU TIMES LUM -// 12347 CUNEIFORM SIGN URU TIMES MIN -// 12348 CUNEIFORM SIGN URU TIMES PA -// 12349 CUNEIFORM SIGN URU TIMES SHE -// 1234a CUNEIFORM SIGN URU TIMES SIG4 -// 1234b CUNEIFORM SIGN URU TIMES TU -// 1234c CUNEIFORM SIGN URU TIMES U PLUS GUD -// 1234d CUNEIFORM SIGN URU TIMES UD -// 1234e CUNEIFORM SIGN URU TIMES URUDA -// 1234f CUNEIFORM SIGN URUDA -// 12350 CUNEIFORM SIGN URUDA TIMES U -// 12351 CUNEIFORM SIGN USH -// 12352 CUNEIFORM SIGN USH TIMES A -// 12353 CUNEIFORM SIGN USH TIMES KU -// 12354 CUNEIFORM SIGN USH TIMES KUR -// 12355 CUNEIFORM SIGN USH TIMES TAK4 -// 12356 CUNEIFORM SIGN USHX -// 12357 CUNEIFORM SIGN USH2 -// 12358 CUNEIFORM SIGN USHUMX -// 12359 CUNEIFORM SIGN UTUKI -// 1235a CUNEIFORM SIGN UZ3 -// 1235b CUNEIFORM SIGN UZ3 TIMES KASKAL -// 1235c CUNEIFORM SIGN UZU -// 1235d CUNEIFORM SIGN ZA -// 1235e CUNEIFORM SIGN ZA TENU -// 1235f CUNEIFORM SIGN ZA SQUARED TIMES KUR -// 12360 CUNEIFORM SIGN ZAG -// 12361 CUNEIFORM SIGN ZAMX -// 12362 CUNEIFORM SIGN ZE2 -// 12363 CUNEIFORM SIGN ZI -// 12364 CUNEIFORM SIGN ZI OVER ZI -// 12365 CUNEIFORM SIGN ZI3 -// 12366 CUNEIFORM SIGN ZIB -// 12367 CUNEIFORM SIGN ZIB KABA TENU -// 12368 CUNEIFORM SIGN ZIG -// 12369 CUNEIFORM SIGN ZIZ2 -// 1236a CUNEIFORM SIGN ZU -// 1236b CUNEIFORM SIGN ZU5 -// 1236c CUNEIFORM SIGN ZU5 TIMES A -// 1236d CUNEIFORM SIGN ZUBUR -// 1236e CUNEIFORM SIGN ZUM -// 1236f CUNEIFORM SIGN KAP ELAMITE -// 12370 CUNEIFORM SIGN AB TIMES NUN -// 12371 CUNEIFORM SIGN AB2 TIMES A -// 12372 CUNEIFORM SIGN AMAR TIMES KUG -// 12373 CUNEIFORM SIGN DAG KISIM5 TIMES U2 PLUS MASH -// 12374 CUNEIFORM SIGN DAG3 -// 12375 CUNEIFORM SIGN DISH PLUS SHU -// 12376 CUNEIFORM SIGN DUB TIMES SHE -// 12377 CUNEIFORM SIGN EZEN TIMES GUD -// 12378 CUNEIFORM SIGN EZEN TIMES SHE -// 12379 CUNEIFORM SIGN GA2 TIMES AN PLUS KAK PLUS A -// 1237a CUNEIFORM SIGN GA2 TIMES ASH2 -// 1237b CUNEIFORM SIGN GE22 -// 1237c CUNEIFORM SIGN GIG -// 1237d CUNEIFORM SIGN HUSH -// 1237e CUNEIFORM SIGN KA TIMES ANSHE -// 1237f CUNEIFORM SIGN KA TIMES ASH3 -// 12380 CUNEIFORM SIGN KA TIMES GISH -// 12381 CUNEIFORM SIGN KA TIMES GUD -// 12382 CUNEIFORM SIGN KA TIMES HI TIMES ASH2 -// 12383 CUNEIFORM SIGN KA TIMES LUM -// 12384 CUNEIFORM SIGN KA TIMES PA -// 12385 CUNEIFORM SIGN KA TIMES SHUL -// 12386 CUNEIFORM SIGN KA TIMES TU -// 12387 CUNEIFORM SIGN KA TIMES UR2 -// 12388 CUNEIFORM SIGN LAGAB TIMES GI -// 12389 CUNEIFORM SIGN LU2 SHESHIG TIMES BAD -// 1238a CUNEIFORM SIGN LU2 TIMES ESH2 PLUS LAL -// 1238b CUNEIFORM SIGN LU2 TIMES SHU -// 1238c CUNEIFORM SIGN MESH -// 1238d CUNEIFORM SIGN MUSH3 TIMES ZA -// 1238e CUNEIFORM SIGN NA4 -// 1238f CUNEIFORM SIGN NIN -// 12390 CUNEIFORM SIGN NIN9 -// 12391 CUNEIFORM SIGN NINDA2 TIMES BAL -// 12392 CUNEIFORM SIGN NINDA2 TIMES GI -// 12393 CUNEIFORM SIGN NU11 ROTATED NINETY DEGREES -// 12394 CUNEIFORM SIGN PESH2 ASTERISK -// 12395 CUNEIFORM SIGN PIR2 -// 12396 CUNEIFORM SIGN SAG TIMES IGI GUNU -// 12397 CUNEIFORM SIGN TI2 -// 12398 CUNEIFORM SIGN UM TIMES ME - { 0x12000, 0x399, 0x9, 0, 0 }, -// 12400 CUNEIFORM NUMERIC SIGN TWO ASH -// 12401 CUNEIFORM NUMERIC SIGN THREE ASH -// 12402 CUNEIFORM NUMERIC SIGN FOUR ASH -// 12403 CUNEIFORM NUMERIC SIGN FIVE ASH -// 12404 CUNEIFORM NUMERIC SIGN SIX ASH -// 12405 CUNEIFORM NUMERIC SIGN SEVEN ASH -// 12406 CUNEIFORM NUMERIC SIGN EIGHT ASH -// 12407 CUNEIFORM NUMERIC SIGN NINE ASH -// 12408 CUNEIFORM NUMERIC SIGN THREE DISH -// 12409 CUNEIFORM NUMERIC SIGN FOUR DISH -// 1240a CUNEIFORM NUMERIC SIGN FIVE DISH -// 1240b CUNEIFORM NUMERIC SIGN SIX DISH -// 1240c CUNEIFORM NUMERIC SIGN SEVEN DISH -// 1240d CUNEIFORM NUMERIC SIGN EIGHT DISH -// 1240e CUNEIFORM NUMERIC SIGN NINE DISH -// 1240f CUNEIFORM NUMERIC SIGN FOUR U -// 12410 CUNEIFORM NUMERIC SIGN FIVE U -// 12411 CUNEIFORM NUMERIC SIGN SIX U -// 12412 CUNEIFORM NUMERIC SIGN SEVEN U -// 12413 CUNEIFORM NUMERIC SIGN EIGHT U -// 12414 CUNEIFORM NUMERIC SIGN NINE U -// 12415 CUNEIFORM NUMERIC SIGN ONE GESH2 -// 12416 CUNEIFORM NUMERIC SIGN TWO GESH2 -// 12417 CUNEIFORM NUMERIC SIGN THREE GESH2 -// 12418 CUNEIFORM NUMERIC SIGN FOUR GESH2 -// 12419 CUNEIFORM NUMERIC SIGN FIVE GESH2 -// 1241a CUNEIFORM NUMERIC SIGN SIX GESH2 -// 1241b CUNEIFORM NUMERIC SIGN SEVEN GESH2 -// 1241c CUNEIFORM NUMERIC SIGN EIGHT GESH2 -// 1241d CUNEIFORM NUMERIC SIGN NINE GESH2 -// 1241e CUNEIFORM NUMERIC SIGN ONE GESHU -// 1241f CUNEIFORM NUMERIC SIGN TWO GESHU -// 12420 CUNEIFORM NUMERIC SIGN THREE GESHU -// 12421 CUNEIFORM NUMERIC SIGN FOUR GESHU -// 12422 CUNEIFORM NUMERIC SIGN FIVE GESHU -// 12423 CUNEIFORM NUMERIC SIGN TWO SHAR2 -// 12424 CUNEIFORM NUMERIC SIGN THREE SHAR2 -// 12425 CUNEIFORM NUMERIC SIGN THREE SHAR2 VARIANT FORM -// 12426 CUNEIFORM NUMERIC SIGN FOUR SHAR2 -// 12427 CUNEIFORM NUMERIC SIGN FIVE SHAR2 -// 12428 CUNEIFORM NUMERIC SIGN SIX SHAR2 -// 12429 CUNEIFORM NUMERIC SIGN SEVEN SHAR2 -// 1242a CUNEIFORM NUMERIC SIGN EIGHT SHAR2 -// 1242b CUNEIFORM NUMERIC SIGN NINE SHAR2 -// 1242c CUNEIFORM NUMERIC SIGN ONE SHARU -// 1242d CUNEIFORM NUMERIC SIGN TWO SHARU -// 1242e CUNEIFORM NUMERIC SIGN THREE SHARU -// 1242f CUNEIFORM NUMERIC SIGN THREE SHARU VARIANT FORM -// 12430 CUNEIFORM NUMERIC SIGN FOUR SHARU -// 12431 CUNEIFORM NUMERIC SIGN FIVE SHARU -// 12432 CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS DISH -// 12433 CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS MIN -// 12434 CUNEIFORM NUMERIC SIGN ONE BURU -// 12435 CUNEIFORM NUMERIC SIGN TWO BURU -// 12436 CUNEIFORM NUMERIC SIGN THREE BURU -// 12437 CUNEIFORM NUMERIC SIGN THREE BURU VARIANT FORM -// 12438 CUNEIFORM NUMERIC SIGN FOUR BURU -// 12439 CUNEIFORM NUMERIC SIGN FIVE BURU -// 1243a CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH16 -// 1243b CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH21 -// 1243c CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU -// 1243d CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU4 -// 1243e CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU A -// 1243f CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU B -// 12440 CUNEIFORM NUMERIC SIGN SIX VARIANT FORM ASH9 -// 12441 CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN3 -// 12442 CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN A -// 12443 CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN B -// 12444 CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU -// 12445 CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU3 -// 12446 CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU -// 12447 CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU3 -// 12448 CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU4 -// 12449 CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU A -// 1244a CUNEIFORM NUMERIC SIGN TWO ASH TENU -// 1244b CUNEIFORM NUMERIC SIGN THREE ASH TENU -// 1244c CUNEIFORM NUMERIC SIGN FOUR ASH TENU -// 1244d CUNEIFORM NUMERIC SIGN FIVE ASH TENU -// 1244e CUNEIFORM NUMERIC SIGN SIX ASH TENU -// 1244f CUNEIFORM NUMERIC SIGN ONE BAN2 -// 12450 CUNEIFORM NUMERIC SIGN TWO BAN2 -// 12451 CUNEIFORM NUMERIC SIGN THREE BAN2 -// 12452 CUNEIFORM NUMERIC SIGN FOUR BAN2 -// 12453 CUNEIFORM NUMERIC SIGN FOUR BAN2 VARIANT FORM -// 12454 CUNEIFORM NUMERIC SIGN FIVE BAN2 -// 12455 CUNEIFORM NUMERIC SIGN FIVE BAN2 VARIANT FORM -// 12456 CUNEIFORM NUMERIC SIGN NIGIDAMIN -// 12457 CUNEIFORM NUMERIC SIGN NIGIDAESH -// 12458 CUNEIFORM NUMERIC SIGN ONE ESHE3 -// 12459 CUNEIFORM NUMERIC SIGN TWO ESHE3 -// 1245a CUNEIFORM NUMERIC SIGN ONE THIRD DISH -// 1245b CUNEIFORM NUMERIC SIGN TWO THIRDS DISH -// 1245c CUNEIFORM NUMERIC SIGN FIVE SIXTHS DISH -// 1245d CUNEIFORM NUMERIC SIGN ONE THIRD VARIANT FORM A -// 1245e CUNEIFORM NUMERIC SIGN TWO THIRDS VARIANT FORM A -// 1245f CUNEIFORM NUMERIC SIGN ONE EIGHTH ASH -// 12460 CUNEIFORM NUMERIC SIGN ONE QUARTER ASH -// 12461 CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE SIXTH -// 12462 CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER -// 12463 CUNEIFORM NUMERIC SIGN ONE QUARTER GUR -// 12464 CUNEIFORM NUMERIC SIGN ONE HALF GUR -// 12465 CUNEIFORM NUMERIC SIGN ELAMITE ONE THIRD -// 12466 CUNEIFORM NUMERIC SIGN ELAMITE TWO THIRDS -// 12467 CUNEIFORM NUMERIC SIGN ELAMITE FORTY -// 12468 CUNEIFORM NUMERIC SIGN ELAMITE FIFTY -// 12469 CUNEIFORM NUMERIC SIGN FOUR U VARIANT FORM -// 1246a CUNEIFORM NUMERIC SIGN FIVE U VARIANT FORM -// 1246b CUNEIFORM NUMERIC SIGN SIX U VARIANT FORM -// 1246c CUNEIFORM NUMERIC SIGN SEVEN U VARIANT FORM -// 1246d CUNEIFORM NUMERIC SIGN EIGHT U VARIANT FORM -// 1246e CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM - { 0x12400, 0x6F, 0x8, 0, 0 }, -// 12470 CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER -// 12471 CUNEIFORM PUNCTUATION SIGN VERTICAL COLON -// 12472 CUNEIFORM PUNCTUATION SIGN DIAGONAL COLON -// 12473 CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON -// 12474 CUNEIFORM PUNCTUATION SIGN DIAGONAL QUADCOLON - { 0x12470, 0x5, 0x18, 0, 0 }, -// 13000 EGYPTIAN HIEROGLYPH A001 -// 13001 EGYPTIAN HIEROGLYPH A002 -// 13002 EGYPTIAN HIEROGLYPH A003 -// 13003 EGYPTIAN HIEROGLYPH A004 -// 13004 EGYPTIAN HIEROGLYPH A005 -// 13005 EGYPTIAN HIEROGLYPH A005A -// 13006 EGYPTIAN HIEROGLYPH A006 -// 13007 EGYPTIAN HIEROGLYPH A006A -// 13008 EGYPTIAN HIEROGLYPH A006B -// 13009 EGYPTIAN HIEROGLYPH A007 -// 1300a EGYPTIAN HIEROGLYPH A008 -// 1300b EGYPTIAN HIEROGLYPH A009 -// 1300c EGYPTIAN HIEROGLYPH A010 -// 1300d EGYPTIAN HIEROGLYPH A011 -// 1300e EGYPTIAN HIEROGLYPH A012 -// 1300f EGYPTIAN HIEROGLYPH A013 -// 13010 EGYPTIAN HIEROGLYPH A014 -// 13011 EGYPTIAN HIEROGLYPH A014A -// 13012 EGYPTIAN HIEROGLYPH A015 -// 13013 EGYPTIAN HIEROGLYPH A016 -// 13014 EGYPTIAN HIEROGLYPH A017 -// 13015 EGYPTIAN HIEROGLYPH A017A -// 13016 EGYPTIAN HIEROGLYPH A018 -// 13017 EGYPTIAN HIEROGLYPH A019 -// 13018 EGYPTIAN HIEROGLYPH A020 -// 13019 EGYPTIAN HIEROGLYPH A021 -// 1301a EGYPTIAN HIEROGLYPH A022 -// 1301b EGYPTIAN HIEROGLYPH A023 -// 1301c EGYPTIAN HIEROGLYPH A024 -// 1301d EGYPTIAN HIEROGLYPH A025 -// 1301e EGYPTIAN HIEROGLYPH A026 -// 1301f EGYPTIAN HIEROGLYPH A027 -// 13020 EGYPTIAN HIEROGLYPH A028 -// 13021 EGYPTIAN HIEROGLYPH A029 -// 13022 EGYPTIAN HIEROGLYPH A030 -// 13023 EGYPTIAN HIEROGLYPH A031 -// 13024 EGYPTIAN HIEROGLYPH A032 -// 13025 EGYPTIAN HIEROGLYPH A032A -// 13026 EGYPTIAN HIEROGLYPH A033 -// 13027 EGYPTIAN HIEROGLYPH A034 -// 13028 EGYPTIAN HIEROGLYPH A035 -// 13029 EGYPTIAN HIEROGLYPH A036 -// 1302a EGYPTIAN HIEROGLYPH A037 -// 1302b EGYPTIAN HIEROGLYPH A038 -// 1302c EGYPTIAN HIEROGLYPH A039 -// 1302d EGYPTIAN HIEROGLYPH A040 -// 1302e EGYPTIAN HIEROGLYPH A040A -// 1302f EGYPTIAN HIEROGLYPH A041 -// 13030 EGYPTIAN HIEROGLYPH A042 -// 13031 EGYPTIAN HIEROGLYPH A042A -// 13032 EGYPTIAN HIEROGLYPH A043 -// 13033 EGYPTIAN HIEROGLYPH A043A -// 13034 EGYPTIAN HIEROGLYPH A044 -// 13035 EGYPTIAN HIEROGLYPH A045 -// 13036 EGYPTIAN HIEROGLYPH A045A -// 13037 EGYPTIAN HIEROGLYPH A046 -// 13038 EGYPTIAN HIEROGLYPH A047 -// 13039 EGYPTIAN HIEROGLYPH A048 -// 1303a EGYPTIAN HIEROGLYPH A049 -// 1303b EGYPTIAN HIEROGLYPH A050 -// 1303c EGYPTIAN HIEROGLYPH A051 -// 1303d EGYPTIAN HIEROGLYPH A052 -// 1303e EGYPTIAN HIEROGLYPH A053 -// 1303f EGYPTIAN HIEROGLYPH A054 -// 13040 EGYPTIAN HIEROGLYPH A055 -// 13041 EGYPTIAN HIEROGLYPH A056 -// 13042 EGYPTIAN HIEROGLYPH A057 -// 13043 EGYPTIAN HIEROGLYPH A058 -// 13044 EGYPTIAN HIEROGLYPH A059 -// 13045 EGYPTIAN HIEROGLYPH A060 -// 13046 EGYPTIAN HIEROGLYPH A061 -// 13047 EGYPTIAN HIEROGLYPH A062 -// 13048 EGYPTIAN HIEROGLYPH A063 -// 13049 EGYPTIAN HIEROGLYPH A064 -// 1304a EGYPTIAN HIEROGLYPH A065 -// 1304b EGYPTIAN HIEROGLYPH A066 -// 1304c EGYPTIAN HIEROGLYPH A067 -// 1304d EGYPTIAN HIEROGLYPH A068 -// 1304e EGYPTIAN HIEROGLYPH A069 -// 1304f EGYPTIAN HIEROGLYPH A070 -// 13050 EGYPTIAN HIEROGLYPH B001 -// 13051 EGYPTIAN HIEROGLYPH B002 -// 13052 EGYPTIAN HIEROGLYPH B003 -// 13053 EGYPTIAN HIEROGLYPH B004 -// 13054 EGYPTIAN HIEROGLYPH B005 -// 13055 EGYPTIAN HIEROGLYPH B005A -// 13056 EGYPTIAN HIEROGLYPH B006 -// 13057 EGYPTIAN HIEROGLYPH B007 -// 13058 EGYPTIAN HIEROGLYPH B008 -// 13059 EGYPTIAN HIEROGLYPH B009 -// 1305a EGYPTIAN HIEROGLYPH C001 -// 1305b EGYPTIAN HIEROGLYPH C002 -// 1305c EGYPTIAN HIEROGLYPH C002A -// 1305d EGYPTIAN HIEROGLYPH C002B -// 1305e EGYPTIAN HIEROGLYPH C002C -// 1305f EGYPTIAN HIEROGLYPH C003 -// 13060 EGYPTIAN HIEROGLYPH C004 -// 13061 EGYPTIAN HIEROGLYPH C005 -// 13062 EGYPTIAN HIEROGLYPH C006 -// 13063 EGYPTIAN HIEROGLYPH C007 -// 13064 EGYPTIAN HIEROGLYPH C008 -// 13065 EGYPTIAN HIEROGLYPH C009 -// 13066 EGYPTIAN HIEROGLYPH C010 -// 13067 EGYPTIAN HIEROGLYPH C010A -// 13068 EGYPTIAN HIEROGLYPH C011 -// 13069 EGYPTIAN HIEROGLYPH C012 -// 1306a EGYPTIAN HIEROGLYPH C013 -// 1306b EGYPTIAN HIEROGLYPH C014 -// 1306c EGYPTIAN HIEROGLYPH C015 -// 1306d EGYPTIAN HIEROGLYPH C016 -// 1306e EGYPTIAN HIEROGLYPH C017 -// 1306f EGYPTIAN HIEROGLYPH C018 -// 13070 EGYPTIAN HIEROGLYPH C019 -// 13071 EGYPTIAN HIEROGLYPH C020 -// 13072 EGYPTIAN HIEROGLYPH C021 -// 13073 EGYPTIAN HIEROGLYPH C022 -// 13074 EGYPTIAN HIEROGLYPH C023 -// 13075 EGYPTIAN HIEROGLYPH C024 -// 13076 EGYPTIAN HIEROGLYPH D001 -// 13077 EGYPTIAN HIEROGLYPH D002 -// 13078 EGYPTIAN HIEROGLYPH D003 -// 13079 EGYPTIAN HIEROGLYPH D004 -// 1307a EGYPTIAN HIEROGLYPH D005 -// 1307b EGYPTIAN HIEROGLYPH D006 -// 1307c EGYPTIAN HIEROGLYPH D007 -// 1307d EGYPTIAN HIEROGLYPH D008 -// 1307e EGYPTIAN HIEROGLYPH D008A -// 1307f EGYPTIAN HIEROGLYPH D009 -// 13080 EGYPTIAN HIEROGLYPH D010 -// 13081 EGYPTIAN HIEROGLYPH D011 -// 13082 EGYPTIAN HIEROGLYPH D012 -// 13083 EGYPTIAN HIEROGLYPH D013 -// 13084 EGYPTIAN HIEROGLYPH D014 -// 13085 EGYPTIAN HIEROGLYPH D015 -// 13086 EGYPTIAN HIEROGLYPH D016 -// 13087 EGYPTIAN HIEROGLYPH D017 -// 13088 EGYPTIAN HIEROGLYPH D018 -// 13089 EGYPTIAN HIEROGLYPH D019 -// 1308a EGYPTIAN HIEROGLYPH D020 -// 1308b EGYPTIAN HIEROGLYPH D021 -// 1308c EGYPTIAN HIEROGLYPH D022 -// 1308d EGYPTIAN HIEROGLYPH D023 -// 1308e EGYPTIAN HIEROGLYPH D024 -// 1308f EGYPTIAN HIEROGLYPH D025 -// 13090 EGYPTIAN HIEROGLYPH D026 -// 13091 EGYPTIAN HIEROGLYPH D027 -// 13092 EGYPTIAN HIEROGLYPH D027A -// 13093 EGYPTIAN HIEROGLYPH D028 -// 13094 EGYPTIAN HIEROGLYPH D029 -// 13095 EGYPTIAN HIEROGLYPH D030 -// 13096 EGYPTIAN HIEROGLYPH D031 -// 13097 EGYPTIAN HIEROGLYPH D031A -// 13098 EGYPTIAN HIEROGLYPH D032 -// 13099 EGYPTIAN HIEROGLYPH D033 -// 1309a EGYPTIAN HIEROGLYPH D034 -// 1309b EGYPTIAN HIEROGLYPH D034A -// 1309c EGYPTIAN HIEROGLYPH D035 -// 1309d EGYPTIAN HIEROGLYPH D036 -// 1309e EGYPTIAN HIEROGLYPH D037 -// 1309f EGYPTIAN HIEROGLYPH D038 -// 130a0 EGYPTIAN HIEROGLYPH D039 -// 130a1 EGYPTIAN HIEROGLYPH D040 -// 130a2 EGYPTIAN HIEROGLYPH D041 -// 130a3 EGYPTIAN HIEROGLYPH D042 -// 130a4 EGYPTIAN HIEROGLYPH D043 -// 130a5 EGYPTIAN HIEROGLYPH D044 -// 130a6 EGYPTIAN HIEROGLYPH D045 -// 130a7 EGYPTIAN HIEROGLYPH D046 -// 130a8 EGYPTIAN HIEROGLYPH D046A -// 130a9 EGYPTIAN HIEROGLYPH D047 -// 130aa EGYPTIAN HIEROGLYPH D048 -// 130ab EGYPTIAN HIEROGLYPH D048A -// 130ac EGYPTIAN HIEROGLYPH D049 -// 130ad EGYPTIAN HIEROGLYPH D050 -// 130ae EGYPTIAN HIEROGLYPH D050A -// 130af EGYPTIAN HIEROGLYPH D050B -// 130b0 EGYPTIAN HIEROGLYPH D050C -// 130b1 EGYPTIAN HIEROGLYPH D050D -// 130b2 EGYPTIAN HIEROGLYPH D050E -// 130b3 EGYPTIAN HIEROGLYPH D050F -// 130b4 EGYPTIAN HIEROGLYPH D050G -// 130b5 EGYPTIAN HIEROGLYPH D050H -// 130b6 EGYPTIAN HIEROGLYPH D050I -// 130b7 EGYPTIAN HIEROGLYPH D051 -// 130b8 EGYPTIAN HIEROGLYPH D052 -// 130b9 EGYPTIAN HIEROGLYPH D052A -// 130ba EGYPTIAN HIEROGLYPH D053 -// 130bb EGYPTIAN HIEROGLYPH D054 -// 130bc EGYPTIAN HIEROGLYPH D054A -// 130bd EGYPTIAN HIEROGLYPH D055 -// 130be EGYPTIAN HIEROGLYPH D056 -// 130bf EGYPTIAN HIEROGLYPH D057 -// 130c0 EGYPTIAN HIEROGLYPH D058 -// 130c1 EGYPTIAN HIEROGLYPH D059 -// 130c2 EGYPTIAN HIEROGLYPH D060 -// 130c3 EGYPTIAN HIEROGLYPH D061 -// 130c4 EGYPTIAN HIEROGLYPH D062 -// 130c5 EGYPTIAN HIEROGLYPH D063 -// 130c6 EGYPTIAN HIEROGLYPH D064 -// 130c7 EGYPTIAN HIEROGLYPH D065 -// 130c8 EGYPTIAN HIEROGLYPH D066 -// 130c9 EGYPTIAN HIEROGLYPH D067 -// 130ca EGYPTIAN HIEROGLYPH D067A -// 130cb EGYPTIAN HIEROGLYPH D067B -// 130cc EGYPTIAN HIEROGLYPH D067C -// 130cd EGYPTIAN HIEROGLYPH D067D -// 130ce EGYPTIAN HIEROGLYPH D067E -// 130cf EGYPTIAN HIEROGLYPH D067F -// 130d0 EGYPTIAN HIEROGLYPH D067G -// 130d1 EGYPTIAN HIEROGLYPH D067H -// 130d2 EGYPTIAN HIEROGLYPH E001 -// 130d3 EGYPTIAN HIEROGLYPH E002 -// 130d4 EGYPTIAN HIEROGLYPH E003 -// 130d5 EGYPTIAN HIEROGLYPH E004 -// 130d6 EGYPTIAN HIEROGLYPH E005 -// 130d7 EGYPTIAN HIEROGLYPH E006 -// 130d8 EGYPTIAN HIEROGLYPH E007 -// 130d9 EGYPTIAN HIEROGLYPH E008 -// 130da EGYPTIAN HIEROGLYPH E008A -// 130db EGYPTIAN HIEROGLYPH E009 -// 130dc EGYPTIAN HIEROGLYPH E009A -// 130dd EGYPTIAN HIEROGLYPH E010 -// 130de EGYPTIAN HIEROGLYPH E011 -// 130df EGYPTIAN HIEROGLYPH E012 -// 130e0 EGYPTIAN HIEROGLYPH E013 -// 130e1 EGYPTIAN HIEROGLYPH E014 -// 130e2 EGYPTIAN HIEROGLYPH E015 -// 130e3 EGYPTIAN HIEROGLYPH E016 -// 130e4 EGYPTIAN HIEROGLYPH E016A -// 130e5 EGYPTIAN HIEROGLYPH E017 -// 130e6 EGYPTIAN HIEROGLYPH E017A -// 130e7 EGYPTIAN HIEROGLYPH E018 -// 130e8 EGYPTIAN HIEROGLYPH E019 -// 130e9 EGYPTIAN HIEROGLYPH E020 -// 130ea EGYPTIAN HIEROGLYPH E020A -// 130eb EGYPTIAN HIEROGLYPH E021 -// 130ec EGYPTIAN HIEROGLYPH E022 -// 130ed EGYPTIAN HIEROGLYPH E023 -// 130ee EGYPTIAN HIEROGLYPH E024 -// 130ef EGYPTIAN HIEROGLYPH E025 -// 130f0 EGYPTIAN HIEROGLYPH E026 -// 130f1 EGYPTIAN HIEROGLYPH E027 -// 130f2 EGYPTIAN HIEROGLYPH E028 -// 130f3 EGYPTIAN HIEROGLYPH E028A -// 130f4 EGYPTIAN HIEROGLYPH E029 -// 130f5 EGYPTIAN HIEROGLYPH E030 -// 130f6 EGYPTIAN HIEROGLYPH E031 -// 130f7 EGYPTIAN HIEROGLYPH E032 -// 130f8 EGYPTIAN HIEROGLYPH E033 -// 130f9 EGYPTIAN HIEROGLYPH E034 -// 130fa EGYPTIAN HIEROGLYPH E034A -// 130fb EGYPTIAN HIEROGLYPH E036 -// 130fc EGYPTIAN HIEROGLYPH E037 -// 130fd EGYPTIAN HIEROGLYPH E038 -// 130fe EGYPTIAN HIEROGLYPH F001 -// 130ff EGYPTIAN HIEROGLYPH F001A -// 13100 EGYPTIAN HIEROGLYPH F002 -// 13101 EGYPTIAN HIEROGLYPH F003 -// 13102 EGYPTIAN HIEROGLYPH F004 -// 13103 EGYPTIAN HIEROGLYPH F005 -// 13104 EGYPTIAN HIEROGLYPH F006 -// 13105 EGYPTIAN HIEROGLYPH F007 -// 13106 EGYPTIAN HIEROGLYPH F008 -// 13107 EGYPTIAN HIEROGLYPH F009 -// 13108 EGYPTIAN HIEROGLYPH F010 -// 13109 EGYPTIAN HIEROGLYPH F011 -// 1310a EGYPTIAN HIEROGLYPH F012 -// 1310b EGYPTIAN HIEROGLYPH F013 -// 1310c EGYPTIAN HIEROGLYPH F013A -// 1310d EGYPTIAN HIEROGLYPH F014 -// 1310e EGYPTIAN HIEROGLYPH F015 -// 1310f EGYPTIAN HIEROGLYPH F016 -// 13110 EGYPTIAN HIEROGLYPH F017 -// 13111 EGYPTIAN HIEROGLYPH F018 -// 13112 EGYPTIAN HIEROGLYPH F019 -// 13113 EGYPTIAN HIEROGLYPH F020 -// 13114 EGYPTIAN HIEROGLYPH F021 -// 13115 EGYPTIAN HIEROGLYPH F021A -// 13116 EGYPTIAN HIEROGLYPH F022 -// 13117 EGYPTIAN HIEROGLYPH F023 -// 13118 EGYPTIAN HIEROGLYPH F024 -// 13119 EGYPTIAN HIEROGLYPH F025 -// 1311a EGYPTIAN HIEROGLYPH F026 -// 1311b EGYPTIAN HIEROGLYPH F027 -// 1311c EGYPTIAN HIEROGLYPH F028 -// 1311d EGYPTIAN HIEROGLYPH F029 -// 1311e EGYPTIAN HIEROGLYPH F030 -// 1311f EGYPTIAN HIEROGLYPH F031 -// 13120 EGYPTIAN HIEROGLYPH F031A -// 13121 EGYPTIAN HIEROGLYPH F032 -// 13122 EGYPTIAN HIEROGLYPH F033 -// 13123 EGYPTIAN HIEROGLYPH F034 -// 13124 EGYPTIAN HIEROGLYPH F035 -// 13125 EGYPTIAN HIEROGLYPH F036 -// 13126 EGYPTIAN HIEROGLYPH F037 -// 13127 EGYPTIAN HIEROGLYPH F037A -// 13128 EGYPTIAN HIEROGLYPH F038 -// 13129 EGYPTIAN HIEROGLYPH F038A -// 1312a EGYPTIAN HIEROGLYPH F039 -// 1312b EGYPTIAN HIEROGLYPH F040 -// 1312c EGYPTIAN HIEROGLYPH F041 -// 1312d EGYPTIAN HIEROGLYPH F042 -// 1312e EGYPTIAN HIEROGLYPH F043 -// 1312f EGYPTIAN HIEROGLYPH F044 -// 13130 EGYPTIAN HIEROGLYPH F045 -// 13131 EGYPTIAN HIEROGLYPH F045A -// 13132 EGYPTIAN HIEROGLYPH F046 -// 13133 EGYPTIAN HIEROGLYPH F046A -// 13134 EGYPTIAN HIEROGLYPH F047 -// 13135 EGYPTIAN HIEROGLYPH F047A -// 13136 EGYPTIAN HIEROGLYPH F048 -// 13137 EGYPTIAN HIEROGLYPH F049 -// 13138 EGYPTIAN HIEROGLYPH F050 -// 13139 EGYPTIAN HIEROGLYPH F051 -// 1313a EGYPTIAN HIEROGLYPH F051A -// 1313b EGYPTIAN HIEROGLYPH F051B -// 1313c EGYPTIAN HIEROGLYPH F051C -// 1313d EGYPTIAN HIEROGLYPH F052 -// 1313e EGYPTIAN HIEROGLYPH F053 -// 1313f EGYPTIAN HIEROGLYPH G001 -// 13140 EGYPTIAN HIEROGLYPH G002 -// 13141 EGYPTIAN HIEROGLYPH G003 -// 13142 EGYPTIAN HIEROGLYPH G004 -// 13143 EGYPTIAN HIEROGLYPH G005 -// 13144 EGYPTIAN HIEROGLYPH G006 -// 13145 EGYPTIAN HIEROGLYPH G006A -// 13146 EGYPTIAN HIEROGLYPH G007 -// 13147 EGYPTIAN HIEROGLYPH G007A -// 13148 EGYPTIAN HIEROGLYPH G007B -// 13149 EGYPTIAN HIEROGLYPH G008 -// 1314a EGYPTIAN HIEROGLYPH G009 -// 1314b EGYPTIAN HIEROGLYPH G010 -// 1314c EGYPTIAN HIEROGLYPH G011 -// 1314d EGYPTIAN HIEROGLYPH G011A -// 1314e EGYPTIAN HIEROGLYPH G012 -// 1314f EGYPTIAN HIEROGLYPH G013 -// 13150 EGYPTIAN HIEROGLYPH G014 -// 13151 EGYPTIAN HIEROGLYPH G015 -// 13152 EGYPTIAN HIEROGLYPH G016 -// 13153 EGYPTIAN HIEROGLYPH G017 -// 13154 EGYPTIAN HIEROGLYPH G018 -// 13155 EGYPTIAN HIEROGLYPH G019 -// 13156 EGYPTIAN HIEROGLYPH G020 -// 13157 EGYPTIAN HIEROGLYPH G020A -// 13158 EGYPTIAN HIEROGLYPH G021 -// 13159 EGYPTIAN HIEROGLYPH G022 -// 1315a EGYPTIAN HIEROGLYPH G023 -// 1315b EGYPTIAN HIEROGLYPH G024 -// 1315c EGYPTIAN HIEROGLYPH G025 -// 1315d EGYPTIAN HIEROGLYPH G026 -// 1315e EGYPTIAN HIEROGLYPH G026A -// 1315f EGYPTIAN HIEROGLYPH G027 -// 13160 EGYPTIAN HIEROGLYPH G028 -// 13161 EGYPTIAN HIEROGLYPH G029 -// 13162 EGYPTIAN HIEROGLYPH G030 -// 13163 EGYPTIAN HIEROGLYPH G031 -// 13164 EGYPTIAN HIEROGLYPH G032 -// 13165 EGYPTIAN HIEROGLYPH G033 -// 13166 EGYPTIAN HIEROGLYPH G034 -// 13167 EGYPTIAN HIEROGLYPH G035 -// 13168 EGYPTIAN HIEROGLYPH G036 -// 13169 EGYPTIAN HIEROGLYPH G036A -// 1316a EGYPTIAN HIEROGLYPH G037 -// 1316b EGYPTIAN HIEROGLYPH G037A -// 1316c EGYPTIAN HIEROGLYPH G038 -// 1316d EGYPTIAN HIEROGLYPH G039 -// 1316e EGYPTIAN HIEROGLYPH G040 -// 1316f EGYPTIAN HIEROGLYPH G041 -// 13170 EGYPTIAN HIEROGLYPH G042 -// 13171 EGYPTIAN HIEROGLYPH G043 -// 13172 EGYPTIAN HIEROGLYPH G043A -// 13173 EGYPTIAN HIEROGLYPH G044 -// 13174 EGYPTIAN HIEROGLYPH G045 -// 13175 EGYPTIAN HIEROGLYPH G045A -// 13176 EGYPTIAN HIEROGLYPH G046 -// 13177 EGYPTIAN HIEROGLYPH G047 -// 13178 EGYPTIAN HIEROGLYPH G048 -// 13179 EGYPTIAN HIEROGLYPH G049 -// 1317a EGYPTIAN HIEROGLYPH G050 -// 1317b EGYPTIAN HIEROGLYPH G051 -// 1317c EGYPTIAN HIEROGLYPH G052 -// 1317d EGYPTIAN HIEROGLYPH G053 -// 1317e EGYPTIAN HIEROGLYPH G054 -// 1317f EGYPTIAN HIEROGLYPH H001 -// 13180 EGYPTIAN HIEROGLYPH H002 -// 13181 EGYPTIAN HIEROGLYPH H003 -// 13182 EGYPTIAN HIEROGLYPH H004 -// 13183 EGYPTIAN HIEROGLYPH H005 -// 13184 EGYPTIAN HIEROGLYPH H006 -// 13185 EGYPTIAN HIEROGLYPH H006A -// 13186 EGYPTIAN HIEROGLYPH H007 -// 13187 EGYPTIAN HIEROGLYPH H008 -// 13188 EGYPTIAN HIEROGLYPH I001 -// 13189 EGYPTIAN HIEROGLYPH I002 -// 1318a EGYPTIAN HIEROGLYPH I003 -// 1318b EGYPTIAN HIEROGLYPH I004 -// 1318c EGYPTIAN HIEROGLYPH I005 -// 1318d EGYPTIAN HIEROGLYPH I005A -// 1318e EGYPTIAN HIEROGLYPH I006 -// 1318f EGYPTIAN HIEROGLYPH I007 -// 13190 EGYPTIAN HIEROGLYPH I008 -// 13191 EGYPTIAN HIEROGLYPH I009 -// 13192 EGYPTIAN HIEROGLYPH I009A -// 13193 EGYPTIAN HIEROGLYPH I010 -// 13194 EGYPTIAN HIEROGLYPH I010A -// 13195 EGYPTIAN HIEROGLYPH I011 -// 13196 EGYPTIAN HIEROGLYPH I011A -// 13197 EGYPTIAN HIEROGLYPH I012 -// 13198 EGYPTIAN HIEROGLYPH I013 -// 13199 EGYPTIAN HIEROGLYPH I014 -// 1319a EGYPTIAN HIEROGLYPH I015 -// 1319b EGYPTIAN HIEROGLYPH K001 -// 1319c EGYPTIAN HIEROGLYPH K002 -// 1319d EGYPTIAN HIEROGLYPH K003 -// 1319e EGYPTIAN HIEROGLYPH K004 -// 1319f EGYPTIAN HIEROGLYPH K005 -// 131a0 EGYPTIAN HIEROGLYPH K006 -// 131a1 EGYPTIAN HIEROGLYPH K007 -// 131a2 EGYPTIAN HIEROGLYPH K008 -// 131a3 EGYPTIAN HIEROGLYPH L001 -// 131a4 EGYPTIAN HIEROGLYPH L002 -// 131a5 EGYPTIAN HIEROGLYPH L002A -// 131a6 EGYPTIAN HIEROGLYPH L003 -// 131a7 EGYPTIAN HIEROGLYPH L004 -// 131a8 EGYPTIAN HIEROGLYPH L005 -// 131a9 EGYPTIAN HIEROGLYPH L006 -// 131aa EGYPTIAN HIEROGLYPH L006A -// 131ab EGYPTIAN HIEROGLYPH L007 -// 131ac EGYPTIAN HIEROGLYPH L008 -// 131ad EGYPTIAN HIEROGLYPH M001 -// 131ae EGYPTIAN HIEROGLYPH M001A -// 131af EGYPTIAN HIEROGLYPH M001B -// 131b0 EGYPTIAN HIEROGLYPH M002 -// 131b1 EGYPTIAN HIEROGLYPH M003 -// 131b2 EGYPTIAN HIEROGLYPH M003A -// 131b3 EGYPTIAN HIEROGLYPH M004 -// 131b4 EGYPTIAN HIEROGLYPH M005 -// 131b5 EGYPTIAN HIEROGLYPH M006 -// 131b6 EGYPTIAN HIEROGLYPH M007 -// 131b7 EGYPTIAN HIEROGLYPH M008 -// 131b8 EGYPTIAN HIEROGLYPH M009 -// 131b9 EGYPTIAN HIEROGLYPH M010 -// 131ba EGYPTIAN HIEROGLYPH M010A -// 131bb EGYPTIAN HIEROGLYPH M011 -// 131bc EGYPTIAN HIEROGLYPH M012 -// 131bd EGYPTIAN HIEROGLYPH M012A -// 131be EGYPTIAN HIEROGLYPH M012B -// 131bf EGYPTIAN HIEROGLYPH M012C -// 131c0 EGYPTIAN HIEROGLYPH M012D -// 131c1 EGYPTIAN HIEROGLYPH M012E -// 131c2 EGYPTIAN HIEROGLYPH M012F -// 131c3 EGYPTIAN HIEROGLYPH M012G -// 131c4 EGYPTIAN HIEROGLYPH M012H -// 131c5 EGYPTIAN HIEROGLYPH M013 -// 131c6 EGYPTIAN HIEROGLYPH M014 -// 131c7 EGYPTIAN HIEROGLYPH M015 -// 131c8 EGYPTIAN HIEROGLYPH M015A -// 131c9 EGYPTIAN HIEROGLYPH M016 -// 131ca EGYPTIAN HIEROGLYPH M016A -// 131cb EGYPTIAN HIEROGLYPH M017 -// 131cc EGYPTIAN HIEROGLYPH M017A -// 131cd EGYPTIAN HIEROGLYPH M018 -// 131ce EGYPTIAN HIEROGLYPH M019 -// 131cf EGYPTIAN HIEROGLYPH M020 -// 131d0 EGYPTIAN HIEROGLYPH M021 -// 131d1 EGYPTIAN HIEROGLYPH M022 -// 131d2 EGYPTIAN HIEROGLYPH M022A -// 131d3 EGYPTIAN HIEROGLYPH M023 -// 131d4 EGYPTIAN HIEROGLYPH M024 -// 131d5 EGYPTIAN HIEROGLYPH M024A -// 131d6 EGYPTIAN HIEROGLYPH M025 -// 131d7 EGYPTIAN HIEROGLYPH M026 -// 131d8 EGYPTIAN HIEROGLYPH M027 -// 131d9 EGYPTIAN HIEROGLYPH M028 -// 131da EGYPTIAN HIEROGLYPH M028A -// 131db EGYPTIAN HIEROGLYPH M029 -// 131dc EGYPTIAN HIEROGLYPH M030 -// 131dd EGYPTIAN HIEROGLYPH M031 -// 131de EGYPTIAN HIEROGLYPH M031A -// 131df EGYPTIAN HIEROGLYPH M032 -// 131e0 EGYPTIAN HIEROGLYPH M033 -// 131e1 EGYPTIAN HIEROGLYPH M033A -// 131e2 EGYPTIAN HIEROGLYPH M033B -// 131e3 EGYPTIAN HIEROGLYPH M034 -// 131e4 EGYPTIAN HIEROGLYPH M035 -// 131e5 EGYPTIAN HIEROGLYPH M036 -// 131e6 EGYPTIAN HIEROGLYPH M037 -// 131e7 EGYPTIAN HIEROGLYPH M038 -// 131e8 EGYPTIAN HIEROGLYPH M039 -// 131e9 EGYPTIAN HIEROGLYPH M040 -// 131ea EGYPTIAN HIEROGLYPH M040A -// 131eb EGYPTIAN HIEROGLYPH M041 -// 131ec EGYPTIAN HIEROGLYPH M042 -// 131ed EGYPTIAN HIEROGLYPH M043 -// 131ee EGYPTIAN HIEROGLYPH M044 -// 131ef EGYPTIAN HIEROGLYPH N001 -// 131f0 EGYPTIAN HIEROGLYPH N002 -// 131f1 EGYPTIAN HIEROGLYPH N003 -// 131f2 EGYPTIAN HIEROGLYPH N004 -// 131f3 EGYPTIAN HIEROGLYPH N005 -// 131f4 EGYPTIAN HIEROGLYPH N006 -// 131f5 EGYPTIAN HIEROGLYPH N007 -// 131f6 EGYPTIAN HIEROGLYPH N008 -// 131f7 EGYPTIAN HIEROGLYPH N009 -// 131f8 EGYPTIAN HIEROGLYPH N010 -// 131f9 EGYPTIAN HIEROGLYPH N011 -// 131fa EGYPTIAN HIEROGLYPH N012 -// 131fb EGYPTIAN HIEROGLYPH N013 -// 131fc EGYPTIAN HIEROGLYPH N014 -// 131fd EGYPTIAN HIEROGLYPH N015 -// 131fe EGYPTIAN HIEROGLYPH N016 -// 131ff EGYPTIAN HIEROGLYPH N017 -// 13200 EGYPTIAN HIEROGLYPH N018 -// 13201 EGYPTIAN HIEROGLYPH N018A -// 13202 EGYPTIAN HIEROGLYPH N018B -// 13203 EGYPTIAN HIEROGLYPH N019 -// 13204 EGYPTIAN HIEROGLYPH N020 -// 13205 EGYPTIAN HIEROGLYPH N021 -// 13206 EGYPTIAN HIEROGLYPH N022 -// 13207 EGYPTIAN HIEROGLYPH N023 -// 13208 EGYPTIAN HIEROGLYPH N024 -// 13209 EGYPTIAN HIEROGLYPH N025 -// 1320a EGYPTIAN HIEROGLYPH N025A -// 1320b EGYPTIAN HIEROGLYPH N026 -// 1320c EGYPTIAN HIEROGLYPH N027 -// 1320d EGYPTIAN HIEROGLYPH N028 -// 1320e EGYPTIAN HIEROGLYPH N029 -// 1320f EGYPTIAN HIEROGLYPH N030 -// 13210 EGYPTIAN HIEROGLYPH N031 -// 13211 EGYPTIAN HIEROGLYPH N032 -// 13212 EGYPTIAN HIEROGLYPH N033 -// 13213 EGYPTIAN HIEROGLYPH N033A -// 13214 EGYPTIAN HIEROGLYPH N034 -// 13215 EGYPTIAN HIEROGLYPH N034A -// 13216 EGYPTIAN HIEROGLYPH N035 -// 13217 EGYPTIAN HIEROGLYPH N035A -// 13218 EGYPTIAN HIEROGLYPH N036 -// 13219 EGYPTIAN HIEROGLYPH N037 -// 1321a EGYPTIAN HIEROGLYPH N037A -// 1321b EGYPTIAN HIEROGLYPH N038 -// 1321c EGYPTIAN HIEROGLYPH N039 -// 1321d EGYPTIAN HIEROGLYPH N040 -// 1321e EGYPTIAN HIEROGLYPH N041 -// 1321f EGYPTIAN HIEROGLYPH N042 -// 13220 EGYPTIAN HIEROGLYPH NL001 -// 13221 EGYPTIAN HIEROGLYPH NL002 -// 13222 EGYPTIAN HIEROGLYPH NL003 -// 13223 EGYPTIAN HIEROGLYPH NL004 -// 13224 EGYPTIAN HIEROGLYPH NL005 -// 13225 EGYPTIAN HIEROGLYPH NL005A -// 13226 EGYPTIAN HIEROGLYPH NL006 -// 13227 EGYPTIAN HIEROGLYPH NL007 -// 13228 EGYPTIAN HIEROGLYPH NL008 -// 13229 EGYPTIAN HIEROGLYPH NL009 -// 1322a EGYPTIAN HIEROGLYPH NL010 -// 1322b EGYPTIAN HIEROGLYPH NL011 -// 1322c EGYPTIAN HIEROGLYPH NL012 -// 1322d EGYPTIAN HIEROGLYPH NL013 -// 1322e EGYPTIAN HIEROGLYPH NL014 -// 1322f EGYPTIAN HIEROGLYPH NL015 -// 13230 EGYPTIAN HIEROGLYPH NL016 -// 13231 EGYPTIAN HIEROGLYPH NL017 -// 13232 EGYPTIAN HIEROGLYPH NL017A -// 13233 EGYPTIAN HIEROGLYPH NL018 -// 13234 EGYPTIAN HIEROGLYPH NL019 -// 13235 EGYPTIAN HIEROGLYPH NL020 -// 13236 EGYPTIAN HIEROGLYPH NU001 -// 13237 EGYPTIAN HIEROGLYPH NU002 -// 13238 EGYPTIAN HIEROGLYPH NU003 -// 13239 EGYPTIAN HIEROGLYPH NU004 -// 1323a EGYPTIAN HIEROGLYPH NU005 -// 1323b EGYPTIAN HIEROGLYPH NU006 -// 1323c EGYPTIAN HIEROGLYPH NU007 -// 1323d EGYPTIAN HIEROGLYPH NU008 -// 1323e EGYPTIAN HIEROGLYPH NU009 -// 1323f EGYPTIAN HIEROGLYPH NU010 -// 13240 EGYPTIAN HIEROGLYPH NU010A -// 13241 EGYPTIAN HIEROGLYPH NU011 -// 13242 EGYPTIAN HIEROGLYPH NU011A -// 13243 EGYPTIAN HIEROGLYPH NU012 -// 13244 EGYPTIAN HIEROGLYPH NU013 -// 13245 EGYPTIAN HIEROGLYPH NU014 -// 13246 EGYPTIAN HIEROGLYPH NU015 -// 13247 EGYPTIAN HIEROGLYPH NU016 -// 13248 EGYPTIAN HIEROGLYPH NU017 -// 13249 EGYPTIAN HIEROGLYPH NU018 -// 1324a EGYPTIAN HIEROGLYPH NU018A -// 1324b EGYPTIAN HIEROGLYPH NU019 -// 1324c EGYPTIAN HIEROGLYPH NU020 -// 1324d EGYPTIAN HIEROGLYPH NU021 -// 1324e EGYPTIAN HIEROGLYPH NU022 -// 1324f EGYPTIAN HIEROGLYPH NU022A -// 13250 EGYPTIAN HIEROGLYPH O001 -// 13251 EGYPTIAN HIEROGLYPH O001A -// 13252 EGYPTIAN HIEROGLYPH O002 -// 13253 EGYPTIAN HIEROGLYPH O003 -// 13254 EGYPTIAN HIEROGLYPH O004 -// 13255 EGYPTIAN HIEROGLYPH O005 -// 13256 EGYPTIAN HIEROGLYPH O005A -// 13257 EGYPTIAN HIEROGLYPH O006 -// 13258 EGYPTIAN HIEROGLYPH O006A -// 13259 EGYPTIAN HIEROGLYPH O006B -// 1325a EGYPTIAN HIEROGLYPH O006C -// 1325b EGYPTIAN HIEROGLYPH O006D -// 1325c EGYPTIAN HIEROGLYPH O006E -// 1325d EGYPTIAN HIEROGLYPH O006F -// 1325e EGYPTIAN HIEROGLYPH O007 -// 1325f EGYPTIAN HIEROGLYPH O008 -// 13260 EGYPTIAN HIEROGLYPH O009 -// 13261 EGYPTIAN HIEROGLYPH O010 -// 13262 EGYPTIAN HIEROGLYPH O010A -// 13263 EGYPTIAN HIEROGLYPH O010B -// 13264 EGYPTIAN HIEROGLYPH O010C -// 13265 EGYPTIAN HIEROGLYPH O011 -// 13266 EGYPTIAN HIEROGLYPH O012 -// 13267 EGYPTIAN HIEROGLYPH O013 -// 13268 EGYPTIAN HIEROGLYPH O014 -// 13269 EGYPTIAN HIEROGLYPH O015 -// 1326a EGYPTIAN HIEROGLYPH O016 -// 1326b EGYPTIAN HIEROGLYPH O017 -// 1326c EGYPTIAN HIEROGLYPH O018 -// 1326d EGYPTIAN HIEROGLYPH O019 -// 1326e EGYPTIAN HIEROGLYPH O019A -// 1326f EGYPTIAN HIEROGLYPH O020 -// 13270 EGYPTIAN HIEROGLYPH O020A -// 13271 EGYPTIAN HIEROGLYPH O021 -// 13272 EGYPTIAN HIEROGLYPH O022 -// 13273 EGYPTIAN HIEROGLYPH O023 -// 13274 EGYPTIAN HIEROGLYPH O024 -// 13275 EGYPTIAN HIEROGLYPH O024A -// 13276 EGYPTIAN HIEROGLYPH O025 -// 13277 EGYPTIAN HIEROGLYPH O025A -// 13278 EGYPTIAN HIEROGLYPH O026 -// 13279 EGYPTIAN HIEROGLYPH O027 -// 1327a EGYPTIAN HIEROGLYPH O028 -// 1327b EGYPTIAN HIEROGLYPH O029 -// 1327c EGYPTIAN HIEROGLYPH O029A -// 1327d EGYPTIAN HIEROGLYPH O030 -// 1327e EGYPTIAN HIEROGLYPH O030A -// 1327f EGYPTIAN HIEROGLYPH O031 -// 13280 EGYPTIAN HIEROGLYPH O032 -// 13281 EGYPTIAN HIEROGLYPH O033 -// 13282 EGYPTIAN HIEROGLYPH O033A -// 13283 EGYPTIAN HIEROGLYPH O034 -// 13284 EGYPTIAN HIEROGLYPH O035 -// 13285 EGYPTIAN HIEROGLYPH O036 -// 13286 EGYPTIAN HIEROGLYPH O036A -// 13287 EGYPTIAN HIEROGLYPH O036B -// 13288 EGYPTIAN HIEROGLYPH O036C -// 13289 EGYPTIAN HIEROGLYPH O036D -// 1328a EGYPTIAN HIEROGLYPH O037 -// 1328b EGYPTIAN HIEROGLYPH O038 -// 1328c EGYPTIAN HIEROGLYPH O039 -// 1328d EGYPTIAN HIEROGLYPH O040 -// 1328e EGYPTIAN HIEROGLYPH O041 -// 1328f EGYPTIAN HIEROGLYPH O042 -// 13290 EGYPTIAN HIEROGLYPH O043 -// 13291 EGYPTIAN HIEROGLYPH O044 -// 13292 EGYPTIAN HIEROGLYPH O045 -// 13293 EGYPTIAN HIEROGLYPH O046 -// 13294 EGYPTIAN HIEROGLYPH O047 -// 13295 EGYPTIAN HIEROGLYPH O048 -// 13296 EGYPTIAN HIEROGLYPH O049 -// 13297 EGYPTIAN HIEROGLYPH O050 -// 13298 EGYPTIAN HIEROGLYPH O050A -// 13299 EGYPTIAN HIEROGLYPH O050B -// 1329a EGYPTIAN HIEROGLYPH O051 -// 1329b EGYPTIAN HIEROGLYPH P001 -// 1329c EGYPTIAN HIEROGLYPH P001A -// 1329d EGYPTIAN HIEROGLYPH P002 -// 1329e EGYPTIAN HIEROGLYPH P003 -// 1329f EGYPTIAN HIEROGLYPH P003A -// 132a0 EGYPTIAN HIEROGLYPH P004 -// 132a1 EGYPTIAN HIEROGLYPH P005 -// 132a2 EGYPTIAN HIEROGLYPH P006 -// 132a3 EGYPTIAN HIEROGLYPH P007 -// 132a4 EGYPTIAN HIEROGLYPH P008 -// 132a5 EGYPTIAN HIEROGLYPH P009 -// 132a6 EGYPTIAN HIEROGLYPH P010 -// 132a7 EGYPTIAN HIEROGLYPH P011 -// 132a8 EGYPTIAN HIEROGLYPH Q001 -// 132a9 EGYPTIAN HIEROGLYPH Q002 -// 132aa EGYPTIAN HIEROGLYPH Q003 -// 132ab EGYPTIAN HIEROGLYPH Q004 -// 132ac EGYPTIAN HIEROGLYPH Q005 -// 132ad EGYPTIAN HIEROGLYPH Q006 -// 132ae EGYPTIAN HIEROGLYPH Q007 -// 132af EGYPTIAN HIEROGLYPH R001 -// 132b0 EGYPTIAN HIEROGLYPH R002 -// 132b1 EGYPTIAN HIEROGLYPH R002A -// 132b2 EGYPTIAN HIEROGLYPH R003 -// 132b3 EGYPTIAN HIEROGLYPH R003A -// 132b4 EGYPTIAN HIEROGLYPH R003B -// 132b5 EGYPTIAN HIEROGLYPH R004 -// 132b6 EGYPTIAN HIEROGLYPH R005 -// 132b7 EGYPTIAN HIEROGLYPH R006 -// 132b8 EGYPTIAN HIEROGLYPH R007 -// 132b9 EGYPTIAN HIEROGLYPH R008 -// 132ba EGYPTIAN HIEROGLYPH R009 -// 132bb EGYPTIAN HIEROGLYPH R010 -// 132bc EGYPTIAN HIEROGLYPH R010A -// 132bd EGYPTIAN HIEROGLYPH R011 -// 132be EGYPTIAN HIEROGLYPH R012 -// 132bf EGYPTIAN HIEROGLYPH R013 -// 132c0 EGYPTIAN HIEROGLYPH R014 -// 132c1 EGYPTIAN HIEROGLYPH R015 -// 132c2 EGYPTIAN HIEROGLYPH R016 -// 132c3 EGYPTIAN HIEROGLYPH R016A -// 132c4 EGYPTIAN HIEROGLYPH R017 -// 132c5 EGYPTIAN HIEROGLYPH R018 -// 132c6 EGYPTIAN HIEROGLYPH R019 -// 132c7 EGYPTIAN HIEROGLYPH R020 -// 132c8 EGYPTIAN HIEROGLYPH R021 -// 132c9 EGYPTIAN HIEROGLYPH R022 -// 132ca EGYPTIAN HIEROGLYPH R023 -// 132cb EGYPTIAN HIEROGLYPH R024 -// 132cc EGYPTIAN HIEROGLYPH R025 -// 132cd EGYPTIAN HIEROGLYPH R026 -// 132ce EGYPTIAN HIEROGLYPH R027 -// 132cf EGYPTIAN HIEROGLYPH R028 -// 132d0 EGYPTIAN HIEROGLYPH R029 -// 132d1 EGYPTIAN HIEROGLYPH S001 -// 132d2 EGYPTIAN HIEROGLYPH S002 -// 132d3 EGYPTIAN HIEROGLYPH S002A -// 132d4 EGYPTIAN HIEROGLYPH S003 -// 132d5 EGYPTIAN HIEROGLYPH S004 -// 132d6 EGYPTIAN HIEROGLYPH S005 -// 132d7 EGYPTIAN HIEROGLYPH S006 -// 132d8 EGYPTIAN HIEROGLYPH S006A -// 132d9 EGYPTIAN HIEROGLYPH S007 -// 132da EGYPTIAN HIEROGLYPH S008 -// 132db EGYPTIAN HIEROGLYPH S009 -// 132dc EGYPTIAN HIEROGLYPH S010 -// 132dd EGYPTIAN HIEROGLYPH S011 -// 132de EGYPTIAN HIEROGLYPH S012 -// 132df EGYPTIAN HIEROGLYPH S013 -// 132e0 EGYPTIAN HIEROGLYPH S014 -// 132e1 EGYPTIAN HIEROGLYPH S014A -// 132e2 EGYPTIAN HIEROGLYPH S014B -// 132e3 EGYPTIAN HIEROGLYPH S015 -// 132e4 EGYPTIAN HIEROGLYPH S016 -// 132e5 EGYPTIAN HIEROGLYPH S017 -// 132e6 EGYPTIAN HIEROGLYPH S017A -// 132e7 EGYPTIAN HIEROGLYPH S018 -// 132e8 EGYPTIAN HIEROGLYPH S019 -// 132e9 EGYPTIAN HIEROGLYPH S020 -// 132ea EGYPTIAN HIEROGLYPH S021 -// 132eb EGYPTIAN HIEROGLYPH S022 -// 132ec EGYPTIAN HIEROGLYPH S023 -// 132ed EGYPTIAN HIEROGLYPH S024 -// 132ee EGYPTIAN HIEROGLYPH S025 -// 132ef EGYPTIAN HIEROGLYPH S026 -// 132f0 EGYPTIAN HIEROGLYPH S026A -// 132f1 EGYPTIAN HIEROGLYPH S026B -// 132f2 EGYPTIAN HIEROGLYPH S027 -// 132f3 EGYPTIAN HIEROGLYPH S028 -// 132f4 EGYPTIAN HIEROGLYPH S029 -// 132f5 EGYPTIAN HIEROGLYPH S030 -// 132f6 EGYPTIAN HIEROGLYPH S031 -// 132f7 EGYPTIAN HIEROGLYPH S032 -// 132f8 EGYPTIAN HIEROGLYPH S033 -// 132f9 EGYPTIAN HIEROGLYPH S034 -// 132fa EGYPTIAN HIEROGLYPH S035 -// 132fb EGYPTIAN HIEROGLYPH S035A -// 132fc EGYPTIAN HIEROGLYPH S036 -// 132fd EGYPTIAN HIEROGLYPH S037 -// 132fe EGYPTIAN HIEROGLYPH S038 -// 132ff EGYPTIAN HIEROGLYPH S039 -// 13300 EGYPTIAN HIEROGLYPH S040 -// 13301 EGYPTIAN HIEROGLYPH S041 -// 13302 EGYPTIAN HIEROGLYPH S042 -// 13303 EGYPTIAN HIEROGLYPH S043 -// 13304 EGYPTIAN HIEROGLYPH S044 -// 13305 EGYPTIAN HIEROGLYPH S045 -// 13306 EGYPTIAN HIEROGLYPH S046 -// 13307 EGYPTIAN HIEROGLYPH T001 -// 13308 EGYPTIAN HIEROGLYPH T002 -// 13309 EGYPTIAN HIEROGLYPH T003 -// 1330a EGYPTIAN HIEROGLYPH T003A -// 1330b EGYPTIAN HIEROGLYPH T004 -// 1330c EGYPTIAN HIEROGLYPH T005 -// 1330d EGYPTIAN HIEROGLYPH T006 -// 1330e EGYPTIAN HIEROGLYPH T007 -// 1330f EGYPTIAN HIEROGLYPH T007A -// 13310 EGYPTIAN HIEROGLYPH T008 -// 13311 EGYPTIAN HIEROGLYPH T008A -// 13312 EGYPTIAN HIEROGLYPH T009 -// 13313 EGYPTIAN HIEROGLYPH T009A -// 13314 EGYPTIAN HIEROGLYPH T010 -// 13315 EGYPTIAN HIEROGLYPH T011 -// 13316 EGYPTIAN HIEROGLYPH T011A -// 13317 EGYPTIAN HIEROGLYPH T012 -// 13318 EGYPTIAN HIEROGLYPH T013 -// 13319 EGYPTIAN HIEROGLYPH T014 -// 1331a EGYPTIAN HIEROGLYPH T015 -// 1331b EGYPTIAN HIEROGLYPH T016 -// 1331c EGYPTIAN HIEROGLYPH T016A -// 1331d EGYPTIAN HIEROGLYPH T017 -// 1331e EGYPTIAN HIEROGLYPH T018 -// 1331f EGYPTIAN HIEROGLYPH T019 -// 13320 EGYPTIAN HIEROGLYPH T020 -// 13321 EGYPTIAN HIEROGLYPH T021 -// 13322 EGYPTIAN HIEROGLYPH T022 -// 13323 EGYPTIAN HIEROGLYPH T023 -// 13324 EGYPTIAN HIEROGLYPH T024 -// 13325 EGYPTIAN HIEROGLYPH T025 -// 13326 EGYPTIAN HIEROGLYPH T026 -// 13327 EGYPTIAN HIEROGLYPH T027 -// 13328 EGYPTIAN HIEROGLYPH T028 -// 13329 EGYPTIAN HIEROGLYPH T029 -// 1332a EGYPTIAN HIEROGLYPH T030 -// 1332b EGYPTIAN HIEROGLYPH T031 -// 1332c EGYPTIAN HIEROGLYPH T032 -// 1332d EGYPTIAN HIEROGLYPH T032A -// 1332e EGYPTIAN HIEROGLYPH T033 -// 1332f EGYPTIAN HIEROGLYPH T033A -// 13330 EGYPTIAN HIEROGLYPH T034 -// 13331 EGYPTIAN HIEROGLYPH T035 -// 13332 EGYPTIAN HIEROGLYPH T036 -// 13333 EGYPTIAN HIEROGLYPH U001 -// 13334 EGYPTIAN HIEROGLYPH U002 -// 13335 EGYPTIAN HIEROGLYPH U003 -// 13336 EGYPTIAN HIEROGLYPH U004 -// 13337 EGYPTIAN HIEROGLYPH U005 -// 13338 EGYPTIAN HIEROGLYPH U006 -// 13339 EGYPTIAN HIEROGLYPH U006A -// 1333a EGYPTIAN HIEROGLYPH U006B -// 1333b EGYPTIAN HIEROGLYPH U007 -// 1333c EGYPTIAN HIEROGLYPH U008 -// 1333d EGYPTIAN HIEROGLYPH U009 -// 1333e EGYPTIAN HIEROGLYPH U010 -// 1333f EGYPTIAN HIEROGLYPH U011 -// 13340 EGYPTIAN HIEROGLYPH U012 -// 13341 EGYPTIAN HIEROGLYPH U013 -// 13342 EGYPTIAN HIEROGLYPH U014 -// 13343 EGYPTIAN HIEROGLYPH U015 -// 13344 EGYPTIAN HIEROGLYPH U016 -// 13345 EGYPTIAN HIEROGLYPH U017 -// 13346 EGYPTIAN HIEROGLYPH U018 -// 13347 EGYPTIAN HIEROGLYPH U019 -// 13348 EGYPTIAN HIEROGLYPH U020 -// 13349 EGYPTIAN HIEROGLYPH U021 -// 1334a EGYPTIAN HIEROGLYPH U022 -// 1334b EGYPTIAN HIEROGLYPH U023 -// 1334c EGYPTIAN HIEROGLYPH U023A -// 1334d EGYPTIAN HIEROGLYPH U024 -// 1334e EGYPTIAN HIEROGLYPH U025 -// 1334f EGYPTIAN HIEROGLYPH U026 -// 13350 EGYPTIAN HIEROGLYPH U027 -// 13351 EGYPTIAN HIEROGLYPH U028 -// 13352 EGYPTIAN HIEROGLYPH U029 -// 13353 EGYPTIAN HIEROGLYPH U029A -// 13354 EGYPTIAN HIEROGLYPH U030 -// 13355 EGYPTIAN HIEROGLYPH U031 -// 13356 EGYPTIAN HIEROGLYPH U032 -// 13357 EGYPTIAN HIEROGLYPH U032A -// 13358 EGYPTIAN HIEROGLYPH U033 -// 13359 EGYPTIAN HIEROGLYPH U034 -// 1335a EGYPTIAN HIEROGLYPH U035 -// 1335b EGYPTIAN HIEROGLYPH U036 -// 1335c EGYPTIAN HIEROGLYPH U037 -// 1335d EGYPTIAN HIEROGLYPH U038 -// 1335e EGYPTIAN HIEROGLYPH U039 -// 1335f EGYPTIAN HIEROGLYPH U040 -// 13360 EGYPTIAN HIEROGLYPH U041 -// 13361 EGYPTIAN HIEROGLYPH U042 -// 13362 EGYPTIAN HIEROGLYPH V001 -// 13363 EGYPTIAN HIEROGLYPH V001A -// 13364 EGYPTIAN HIEROGLYPH V001B -// 13365 EGYPTIAN HIEROGLYPH V001C -// 13366 EGYPTIAN HIEROGLYPH V001D -// 13367 EGYPTIAN HIEROGLYPH V001E -// 13368 EGYPTIAN HIEROGLYPH V001F -// 13369 EGYPTIAN HIEROGLYPH V001G -// 1336a EGYPTIAN HIEROGLYPH V001H -// 1336b EGYPTIAN HIEROGLYPH V001I -// 1336c EGYPTIAN HIEROGLYPH V002 -// 1336d EGYPTIAN HIEROGLYPH V002A -// 1336e EGYPTIAN HIEROGLYPH V003 -// 1336f EGYPTIAN HIEROGLYPH V004 -// 13370 EGYPTIAN HIEROGLYPH V005 -// 13371 EGYPTIAN HIEROGLYPH V006 -// 13372 EGYPTIAN HIEROGLYPH V007 -// 13373 EGYPTIAN HIEROGLYPH V007A -// 13374 EGYPTIAN HIEROGLYPH V007B -// 13375 EGYPTIAN HIEROGLYPH V008 -// 13376 EGYPTIAN HIEROGLYPH V009 -// 13377 EGYPTIAN HIEROGLYPH V010 -// 13378 EGYPTIAN HIEROGLYPH V011 -// 13379 EGYPTIAN HIEROGLYPH V011A -// 1337a EGYPTIAN HIEROGLYPH V011B -// 1337b EGYPTIAN HIEROGLYPH V011C -// 1337c EGYPTIAN HIEROGLYPH V012 -// 1337d EGYPTIAN HIEROGLYPH V012A -// 1337e EGYPTIAN HIEROGLYPH V012B -// 1337f EGYPTIAN HIEROGLYPH V013 -// 13380 EGYPTIAN HIEROGLYPH V014 -// 13381 EGYPTIAN HIEROGLYPH V015 -// 13382 EGYPTIAN HIEROGLYPH V016 -// 13383 EGYPTIAN HIEROGLYPH V017 -// 13384 EGYPTIAN HIEROGLYPH V018 -// 13385 EGYPTIAN HIEROGLYPH V019 -// 13386 EGYPTIAN HIEROGLYPH V020 -// 13387 EGYPTIAN HIEROGLYPH V020A -// 13388 EGYPTIAN HIEROGLYPH V020B -// 13389 EGYPTIAN HIEROGLYPH V020C -// 1338a EGYPTIAN HIEROGLYPH V020D -// 1338b EGYPTIAN HIEROGLYPH V020E -// 1338c EGYPTIAN HIEROGLYPH V020F -// 1338d EGYPTIAN HIEROGLYPH V020G -// 1338e EGYPTIAN HIEROGLYPH V020H -// 1338f EGYPTIAN HIEROGLYPH V020I -// 13390 EGYPTIAN HIEROGLYPH V020J -// 13391 EGYPTIAN HIEROGLYPH V020K -// 13392 EGYPTIAN HIEROGLYPH V020L -// 13393 EGYPTIAN HIEROGLYPH V021 -// 13394 EGYPTIAN HIEROGLYPH V022 -// 13395 EGYPTIAN HIEROGLYPH V023 -// 13396 EGYPTIAN HIEROGLYPH V023A -// 13397 EGYPTIAN HIEROGLYPH V024 -// 13398 EGYPTIAN HIEROGLYPH V025 -// 13399 EGYPTIAN HIEROGLYPH V026 -// 1339a EGYPTIAN HIEROGLYPH V027 -// 1339b EGYPTIAN HIEROGLYPH V028 -// 1339c EGYPTIAN HIEROGLYPH V028A -// 1339d EGYPTIAN HIEROGLYPH V029 -// 1339e EGYPTIAN HIEROGLYPH V029A -// 1339f EGYPTIAN HIEROGLYPH V030 -// 133a0 EGYPTIAN HIEROGLYPH V030A -// 133a1 EGYPTIAN HIEROGLYPH V031 -// 133a2 EGYPTIAN HIEROGLYPH V031A -// 133a3 EGYPTIAN HIEROGLYPH V032 -// 133a4 EGYPTIAN HIEROGLYPH V033 -// 133a5 EGYPTIAN HIEROGLYPH V033A -// 133a6 EGYPTIAN HIEROGLYPH V034 -// 133a7 EGYPTIAN HIEROGLYPH V035 -// 133a8 EGYPTIAN HIEROGLYPH V036 -// 133a9 EGYPTIAN HIEROGLYPH V037 -// 133aa EGYPTIAN HIEROGLYPH V037A -// 133ab EGYPTIAN HIEROGLYPH V038 -// 133ac EGYPTIAN HIEROGLYPH V039 -// 133ad EGYPTIAN HIEROGLYPH V040 -// 133ae EGYPTIAN HIEROGLYPH V040A -// 133af EGYPTIAN HIEROGLYPH W001 -// 133b0 EGYPTIAN HIEROGLYPH W002 -// 133b1 EGYPTIAN HIEROGLYPH W003 -// 133b2 EGYPTIAN HIEROGLYPH W003A -// 133b3 EGYPTIAN HIEROGLYPH W004 -// 133b4 EGYPTIAN HIEROGLYPH W005 -// 133b5 EGYPTIAN HIEROGLYPH W006 -// 133b6 EGYPTIAN HIEROGLYPH W007 -// 133b7 EGYPTIAN HIEROGLYPH W008 -// 133b8 EGYPTIAN HIEROGLYPH W009 -// 133b9 EGYPTIAN HIEROGLYPH W009A -// 133ba EGYPTIAN HIEROGLYPH W010 -// 133bb EGYPTIAN HIEROGLYPH W010A -// 133bc EGYPTIAN HIEROGLYPH W011 -// 133bd EGYPTIAN HIEROGLYPH W012 -// 133be EGYPTIAN HIEROGLYPH W013 -// 133bf EGYPTIAN HIEROGLYPH W014 -// 133c0 EGYPTIAN HIEROGLYPH W014A -// 133c1 EGYPTIAN HIEROGLYPH W015 -// 133c2 EGYPTIAN HIEROGLYPH W016 -// 133c3 EGYPTIAN HIEROGLYPH W017 -// 133c4 EGYPTIAN HIEROGLYPH W017A -// 133c5 EGYPTIAN HIEROGLYPH W018 -// 133c6 EGYPTIAN HIEROGLYPH W018A -// 133c7 EGYPTIAN HIEROGLYPH W019 -// 133c8 EGYPTIAN HIEROGLYPH W020 -// 133c9 EGYPTIAN HIEROGLYPH W021 -// 133ca EGYPTIAN HIEROGLYPH W022 -// 133cb EGYPTIAN HIEROGLYPH W023 -// 133cc EGYPTIAN HIEROGLYPH W024 -// 133cd EGYPTIAN HIEROGLYPH W024A -// 133ce EGYPTIAN HIEROGLYPH W025 -// 133cf EGYPTIAN HIEROGLYPH X001 -// 133d0 EGYPTIAN HIEROGLYPH X002 -// 133d1 EGYPTIAN HIEROGLYPH X003 -// 133d2 EGYPTIAN HIEROGLYPH X004 -// 133d3 EGYPTIAN HIEROGLYPH X004A -// 133d4 EGYPTIAN HIEROGLYPH X004B -// 133d5 EGYPTIAN HIEROGLYPH X005 -// 133d6 EGYPTIAN HIEROGLYPH X006 -// 133d7 EGYPTIAN HIEROGLYPH X006A -// 133d8 EGYPTIAN HIEROGLYPH X007 -// 133d9 EGYPTIAN HIEROGLYPH X008 -// 133da EGYPTIAN HIEROGLYPH X008A -// 133db EGYPTIAN HIEROGLYPH Y001 -// 133dc EGYPTIAN HIEROGLYPH Y001A -// 133dd EGYPTIAN HIEROGLYPH Y002 -// 133de EGYPTIAN HIEROGLYPH Y003 -// 133df EGYPTIAN HIEROGLYPH Y004 -// 133e0 EGYPTIAN HIEROGLYPH Y005 -// 133e1 EGYPTIAN HIEROGLYPH Y006 -// 133e2 EGYPTIAN HIEROGLYPH Y007 -// 133e3 EGYPTIAN HIEROGLYPH Y008 -// 133e4 EGYPTIAN HIEROGLYPH Z001 -// 133e5 EGYPTIAN HIEROGLYPH Z002 -// 133e6 EGYPTIAN HIEROGLYPH Z002A -// 133e7 EGYPTIAN HIEROGLYPH Z002B -// 133e8 EGYPTIAN HIEROGLYPH Z002C -// 133e9 EGYPTIAN HIEROGLYPH Z002D -// 133ea EGYPTIAN HIEROGLYPH Z003 -// 133eb EGYPTIAN HIEROGLYPH Z003A -// 133ec EGYPTIAN HIEROGLYPH Z003B -// 133ed EGYPTIAN HIEROGLYPH Z004 -// 133ee EGYPTIAN HIEROGLYPH Z004A -// 133ef EGYPTIAN HIEROGLYPH Z005 -// 133f0 EGYPTIAN HIEROGLYPH Z005A -// 133f1 EGYPTIAN HIEROGLYPH Z006 -// 133f2 EGYPTIAN HIEROGLYPH Z007 -// 133f3 EGYPTIAN HIEROGLYPH Z008 -// 133f4 EGYPTIAN HIEROGLYPH Z009 -// 133f5 EGYPTIAN HIEROGLYPH Z010 -// 133f6 EGYPTIAN HIEROGLYPH Z011 -// 133f7 EGYPTIAN HIEROGLYPH Z012 -// 133f8 EGYPTIAN HIEROGLYPH Z013 -// 133f9 EGYPTIAN HIEROGLYPH Z014 -// 133fa EGYPTIAN HIEROGLYPH Z015 -// 133fb EGYPTIAN HIEROGLYPH Z015A -// 133fc EGYPTIAN HIEROGLYPH Z015B -// 133fd EGYPTIAN HIEROGLYPH Z015C -// 133fe EGYPTIAN HIEROGLYPH Z015D -// 133ff EGYPTIAN HIEROGLYPH Z015E -// 13400 EGYPTIAN HIEROGLYPH Z015F -// 13401 EGYPTIAN HIEROGLYPH Z015G -// 13402 EGYPTIAN HIEROGLYPH Z015H -// 13403 EGYPTIAN HIEROGLYPH Z015I -// 13404 EGYPTIAN HIEROGLYPH Z016 -// 13405 EGYPTIAN HIEROGLYPH Z016A -// 13406 EGYPTIAN HIEROGLYPH Z016B -// 13407 EGYPTIAN HIEROGLYPH Z016C -// 13408 EGYPTIAN HIEROGLYPH Z016D -// 13409 EGYPTIAN HIEROGLYPH Z016E -// 1340a EGYPTIAN HIEROGLYPH Z016F -// 1340b EGYPTIAN HIEROGLYPH Z016G -// 1340c EGYPTIAN HIEROGLYPH Z016H -// 1340d EGYPTIAN HIEROGLYPH AA001 -// 1340e EGYPTIAN HIEROGLYPH AA002 -// 1340f EGYPTIAN HIEROGLYPH AA003 -// 13410 EGYPTIAN HIEROGLYPH AA004 -// 13411 EGYPTIAN HIEROGLYPH AA005 -// 13412 EGYPTIAN HIEROGLYPH AA006 -// 13413 EGYPTIAN HIEROGLYPH AA007 -// 13414 EGYPTIAN HIEROGLYPH AA007A -// 13415 EGYPTIAN HIEROGLYPH AA007B -// 13416 EGYPTIAN HIEROGLYPH AA008 -// 13417 EGYPTIAN HIEROGLYPH AA009 -// 13418 EGYPTIAN HIEROGLYPH AA010 -// 13419 EGYPTIAN HIEROGLYPH AA011 -// 1341a EGYPTIAN HIEROGLYPH AA012 -// 1341b EGYPTIAN HIEROGLYPH AA013 -// 1341c EGYPTIAN HIEROGLYPH AA014 -// 1341d EGYPTIAN HIEROGLYPH AA015 -// 1341e EGYPTIAN HIEROGLYPH AA016 -// 1341f EGYPTIAN HIEROGLYPH AA017 -// 13420 EGYPTIAN HIEROGLYPH AA018 -// 13421 EGYPTIAN HIEROGLYPH AA019 -// 13422 EGYPTIAN HIEROGLYPH AA020 -// 13423 EGYPTIAN HIEROGLYPH AA021 -// 13424 EGYPTIAN HIEROGLYPH AA022 -// 13425 EGYPTIAN HIEROGLYPH AA023 -// 13426 EGYPTIAN HIEROGLYPH AA024 -// 13427 EGYPTIAN HIEROGLYPH AA025 -// 13428 EGYPTIAN HIEROGLYPH AA026 -// 13429 EGYPTIAN HIEROGLYPH AA027 -// 1342a EGYPTIAN HIEROGLYPH AA028 -// 1342b EGYPTIAN HIEROGLYPH AA029 -// 1342c EGYPTIAN HIEROGLYPH AA030 -// 1342d EGYPTIAN HIEROGLYPH AA031 -// 1342e EGYPTIAN HIEROGLYPH AA032 - { 0x13000, 0x42F, 0x9, 0, 0 }, -// 16800 BAMUM LETTER PHASE-A NGKUE MFON -// 16801 BAMUM LETTER PHASE-A GBIEE FON -// 16802 BAMUM LETTER PHASE-A PON MFON PIPAEMGBIEE -// 16803 BAMUM LETTER PHASE-A PON MFON PIPAEMBA -// 16804 BAMUM LETTER PHASE-A NAA MFON -// 16805 BAMUM LETTER PHASE-A SHUENSHUET -// 16806 BAMUM LETTER PHASE-A TITA MFON -// 16807 BAMUM LETTER PHASE-A NZA MFON -// 16808 BAMUM LETTER PHASE-A SHINDA PA NJI -// 16809 BAMUM LETTER PHASE-A PON PA NJI PIPAEMGBIEE -// 1680a BAMUM LETTER PHASE-A PON PA NJI PIPAEMBA -// 1680b BAMUM LETTER PHASE-A MAEMBGBIEE -// 1680c BAMUM LETTER PHASE-A TU MAEMBA -// 1680d BAMUM LETTER PHASE-A NGANGU -// 1680e BAMUM LETTER PHASE-A MAEMVEUX -// 1680f BAMUM LETTER PHASE-A MANSUAE -// 16810 BAMUM LETTER PHASE-A MVEUAENGAM -// 16811 BAMUM LETTER PHASE-A SEUNYAM -// 16812 BAMUM LETTER PHASE-A NTOQPEN -// 16813 BAMUM LETTER PHASE-A KEUKEUTNDA -// 16814 BAMUM LETTER PHASE-A NKINDI -// 16815 BAMUM LETTER PHASE-A SUU -// 16816 BAMUM LETTER PHASE-A NGKUENZEUM -// 16817 BAMUM LETTER PHASE-A LAPAQ -// 16818 BAMUM LETTER PHASE-A LET KUT -// 16819 BAMUM LETTER PHASE-A NTAP MFAA -// 1681a BAMUM LETTER PHASE-A MAEKEUP -// 1681b BAMUM LETTER PHASE-A PASHAE -// 1681c BAMUM LETTER PHASE-A GHEUAERAE -// 1681d BAMUM LETTER PHASE-A PAMSHAE -// 1681e BAMUM LETTER PHASE-A MON NGGEUAET -// 1681f BAMUM LETTER PHASE-A NZUN MEUT -// 16820 BAMUM LETTER PHASE-A U YUQ NAE -// 16821 BAMUM LETTER PHASE-A GHEUAEGHEUAE -// 16822 BAMUM LETTER PHASE-A NTAP NTAA -// 16823 BAMUM LETTER PHASE-A SISA -// 16824 BAMUM LETTER PHASE-A MGBASA -// 16825 BAMUM LETTER PHASE-A MEUNJOMNDEUQ -// 16826 BAMUM LETTER PHASE-A MOOMPUQ -// 16827 BAMUM LETTER PHASE-A KAFA -// 16828 BAMUM LETTER PHASE-A PA LEERAEWA -// 16829 BAMUM LETTER PHASE-A NDA LEERAEWA -// 1682a BAMUM LETTER PHASE-A PET -// 1682b BAMUM LETTER PHASE-A MAEMKPEN -// 1682c BAMUM LETTER PHASE-A NIKA -// 1682d BAMUM LETTER PHASE-A PUP -// 1682e BAMUM LETTER PHASE-A TUAEP -// 1682f BAMUM LETTER PHASE-A LUAEP -// 16830 BAMUM LETTER PHASE-A SONJAM -// 16831 BAMUM LETTER PHASE-A TEUTEUWEN -// 16832 BAMUM LETTER PHASE-A MAENYI -// 16833 BAMUM LETTER PHASE-A KET -// 16834 BAMUM LETTER PHASE-A NDAANGGEUAET -// 16835 BAMUM LETTER PHASE-A KUOQ -// 16836 BAMUM LETTER PHASE-A MOOMEUT -// 16837 BAMUM LETTER PHASE-A SHUM -// 16838 BAMUM LETTER PHASE-A LOMMAE -// 16839 BAMUM LETTER PHASE-A FIRI -// 1683a BAMUM LETTER PHASE-A ROM -// 1683b BAMUM LETTER PHASE-A KPOQ -// 1683c BAMUM LETTER PHASE-A SOQ -// 1683d BAMUM LETTER PHASE-A MAP PIEET -// 1683e BAMUM LETTER PHASE-A SHIRAE -// 1683f BAMUM LETTER PHASE-A NTAP -// 16840 BAMUM LETTER PHASE-A SHOQ NSHUT YUM -// 16841 BAMUM LETTER PHASE-A NYIT MONGKEUAEQ -// 16842 BAMUM LETTER PHASE-A PAARAE -// 16843 BAMUM LETTER PHASE-A NKAARAE -// 16844 BAMUM LETTER PHASE-A UNKNOWN -// 16845 BAMUM LETTER PHASE-A NGGEN -// 16846 BAMUM LETTER PHASE-A MAESI -// 16847 BAMUM LETTER PHASE-A NJAM -// 16848 BAMUM LETTER PHASE-A MBANYI -// 16849 BAMUM LETTER PHASE-A NYET -// 1684a BAMUM LETTER PHASE-A TEUAEN -// 1684b BAMUM LETTER PHASE-A SOT -// 1684c BAMUM LETTER PHASE-A PAAM -// 1684d BAMUM LETTER PHASE-A NSHIEE -// 1684e BAMUM LETTER PHASE-A MAEM -// 1684f BAMUM LETTER PHASE-A NYI -// 16850 BAMUM LETTER PHASE-A KAQ -// 16851 BAMUM LETTER PHASE-A NSHA -// 16852 BAMUM LETTER PHASE-A VEE -// 16853 BAMUM LETTER PHASE-A LU -// 16854 BAMUM LETTER PHASE-A NEN -// 16855 BAMUM LETTER PHASE-A NAQ -// 16856 BAMUM LETTER PHASE-A MBAQ -// 16857 BAMUM LETTER PHASE-B NSHUET -// 16858 BAMUM LETTER PHASE-B TU MAEMGBIEE -// 16859 BAMUM LETTER PHASE-B SIEE -// 1685a BAMUM LETTER PHASE-B SET TU -// 1685b BAMUM LETTER PHASE-B LOM NTEUM -// 1685c BAMUM LETTER PHASE-B MBA MAELEE -// 1685d BAMUM LETTER PHASE-B KIEEM -// 1685e BAMUM LETTER PHASE-B YEURAE -// 1685f BAMUM LETTER PHASE-B MBAARAE -// 16860 BAMUM LETTER PHASE-B KAM -// 16861 BAMUM LETTER PHASE-B PEESHI -// 16862 BAMUM LETTER PHASE-B YAFU LEERAEWA -// 16863 BAMUM LETTER PHASE-B LAM NSHUT NYAM -// 16864 BAMUM LETTER PHASE-B NTIEE SHEUOQ -// 16865 BAMUM LETTER PHASE-B NDU NJAA -// 16866 BAMUM LETTER PHASE-B GHEUGHEUAEM -// 16867 BAMUM LETTER PHASE-B PIT -// 16868 BAMUM LETTER PHASE-B TU NSIEE -// 16869 BAMUM LETTER PHASE-B SHET NJAQ -// 1686a BAMUM LETTER PHASE-B SHEUAEQTU -// 1686b BAMUM LETTER PHASE-B MFON TEUAEQ -// 1686c BAMUM LETTER PHASE-B MBIT MBAAKET -// 1686d BAMUM LETTER PHASE-B NYI NTEUM -// 1686e BAMUM LETTER PHASE-B KEUPUQ -// 1686f BAMUM LETTER PHASE-B GHEUGHEN -// 16870 BAMUM LETTER PHASE-B KEUYEUX -// 16871 BAMUM LETTER PHASE-B LAANAE -// 16872 BAMUM LETTER PHASE-B PARUM -// 16873 BAMUM LETTER PHASE-B VEUM -// 16874 BAMUM LETTER PHASE-B NGKINDI MVOP -// 16875 BAMUM LETTER PHASE-B NGGEU MBU -// 16876 BAMUM LETTER PHASE-B WUAET -// 16877 BAMUM LETTER PHASE-B SAKEUAE -// 16878 BAMUM LETTER PHASE-B TAAM -// 16879 BAMUM LETTER PHASE-B MEUQ -// 1687a BAMUM LETTER PHASE-B NGGUOQ -// 1687b BAMUM LETTER PHASE-B NGGUOQ LARGE -// 1687c BAMUM LETTER PHASE-B MFIYAQ -// 1687d BAMUM LETTER PHASE-B SUE -// 1687e BAMUM LETTER PHASE-B MBEURI -// 1687f BAMUM LETTER PHASE-B MONTIEEN -// 16880 BAMUM LETTER PHASE-B NYAEMAE -// 16881 BAMUM LETTER PHASE-B PUNGAAM -// 16882 BAMUM LETTER PHASE-B MEUT NGGEET -// 16883 BAMUM LETTER PHASE-B FEUX -// 16884 BAMUM LETTER PHASE-B MBUOQ -// 16885 BAMUM LETTER PHASE-B FEE -// 16886 BAMUM LETTER PHASE-B KEUAEM -// 16887 BAMUM LETTER PHASE-B MA NJEUAENA -// 16888 BAMUM LETTER PHASE-B MA NJUQA -// 16889 BAMUM LETTER PHASE-B LET -// 1688a BAMUM LETTER PHASE-B NGGAAM -// 1688b BAMUM LETTER PHASE-B NSEN -// 1688c BAMUM LETTER PHASE-B MA -// 1688d BAMUM LETTER PHASE-B KIQ -// 1688e BAMUM LETTER PHASE-B NGOM -// 1688f BAMUM LETTER PHASE-C NGKUE MAEMBA -// 16890 BAMUM LETTER PHASE-C NZA -// 16891 BAMUM LETTER PHASE-C YUM -// 16892 BAMUM LETTER PHASE-C WANGKUOQ -// 16893 BAMUM LETTER PHASE-C NGGEN -// 16894 BAMUM LETTER PHASE-C NDEUAEREE -// 16895 BAMUM LETTER PHASE-C NGKAQ -// 16896 BAMUM LETTER PHASE-C GHARAE -// 16897 BAMUM LETTER PHASE-C MBEEKEET -// 16898 BAMUM LETTER PHASE-C GBAYI -// 16899 BAMUM LETTER PHASE-C NYIR MKPARAQ MEUN -// 1689a BAMUM LETTER PHASE-C NTU MBIT -// 1689b BAMUM LETTER PHASE-C MBEUM -// 1689c BAMUM LETTER PHASE-C PIRIEEN -// 1689d BAMUM LETTER PHASE-C NDOMBU -// 1689e BAMUM LETTER PHASE-C MBAA CABBAGE-TREE -// 1689f BAMUM LETTER PHASE-C KEUSHEUAEP -// 168a0 BAMUM LETTER PHASE-C GHAP -// 168a1 BAMUM LETTER PHASE-C KEUKAQ -// 168a2 BAMUM LETTER PHASE-C YU MUOMAE -// 168a3 BAMUM LETTER PHASE-C NZEUM -// 168a4 BAMUM LETTER PHASE-C MBUE -// 168a5 BAMUM LETTER PHASE-C NSEUAEN -// 168a6 BAMUM LETTER PHASE-C MBIT -// 168a7 BAMUM LETTER PHASE-C YEUQ -// 168a8 BAMUM LETTER PHASE-C KPARAQ -// 168a9 BAMUM LETTER PHASE-C KAA -// 168aa BAMUM LETTER PHASE-C SEUX -// 168ab BAMUM LETTER PHASE-C NDIDA -// 168ac BAMUM LETTER PHASE-C TAASHAE -// 168ad BAMUM LETTER PHASE-C NJUEQ -// 168ae BAMUM LETTER PHASE-C TITA YUE -// 168af BAMUM LETTER PHASE-C SUAET -// 168b0 BAMUM LETTER PHASE-C NGGUAEN NYAM -// 168b1 BAMUM LETTER PHASE-C VEUX -// 168b2 BAMUM LETTER PHASE-C NANSANAQ -// 168b3 BAMUM LETTER PHASE-C MA KEUAERI -// 168b4 BAMUM LETTER PHASE-C NTAA -// 168b5 BAMUM LETTER PHASE-C NGGUON -// 168b6 BAMUM LETTER PHASE-C LAP -// 168b7 BAMUM LETTER PHASE-C MBIRIEEN -// 168b8 BAMUM LETTER PHASE-C MGBASAQ -// 168b9 BAMUM LETTER PHASE-C NTEUNGBA -// 168ba BAMUM LETTER PHASE-C TEUTEUX -// 168bb BAMUM LETTER PHASE-C NGGUM -// 168bc BAMUM LETTER PHASE-C FUE -// 168bd BAMUM LETTER PHASE-C NDEUT -// 168be BAMUM LETTER PHASE-C NSA -// 168bf BAMUM LETTER PHASE-C NSHAQ -// 168c0 BAMUM LETTER PHASE-C BUNG -// 168c1 BAMUM LETTER PHASE-C VEUAEPEN -// 168c2 BAMUM LETTER PHASE-C MBERAE -// 168c3 BAMUM LETTER PHASE-C RU -// 168c4 BAMUM LETTER PHASE-C NJAEM -// 168c5 BAMUM LETTER PHASE-C LAM -// 168c6 BAMUM LETTER PHASE-C TITUAEP -// 168c7 BAMUM LETTER PHASE-C NSUOT NGOM -// 168c8 BAMUM LETTER PHASE-C NJEEEE -// 168c9 BAMUM LETTER PHASE-C KET -// 168ca BAMUM LETTER PHASE-C NGGU -// 168cb BAMUM LETTER PHASE-C MAESI -// 168cc BAMUM LETTER PHASE-C MBUAEM -// 168cd BAMUM LETTER PHASE-C LU -// 168ce BAMUM LETTER PHASE-C KUT -// 168cf BAMUM LETTER PHASE-C NJAM -// 168d0 BAMUM LETTER PHASE-C NGOM -// 168d1 BAMUM LETTER PHASE-C WUP -// 168d2 BAMUM LETTER PHASE-C NGGUEET -// 168d3 BAMUM LETTER PHASE-C NSOM -// 168d4 BAMUM LETTER PHASE-C NTEN -// 168d5 BAMUM LETTER PHASE-C KUOP NKAARAE -// 168d6 BAMUM LETTER PHASE-C NSUN -// 168d7 BAMUM LETTER PHASE-C NDAM -// 168d8 BAMUM LETTER PHASE-C MA NSIEE -// 168d9 BAMUM LETTER PHASE-C YAA -// 168da BAMUM LETTER PHASE-C NDAP -// 168db BAMUM LETTER PHASE-C SHUEQ -// 168dc BAMUM LETTER PHASE-C SETFON -// 168dd BAMUM LETTER PHASE-C MBI -// 168de BAMUM LETTER PHASE-C MAEMBA -// 168df BAMUM LETTER PHASE-C MBANYI -// 168e0 BAMUM LETTER PHASE-C KEUSEUX -// 168e1 BAMUM LETTER PHASE-C MBEUX -// 168e2 BAMUM LETTER PHASE-C KEUM -// 168e3 BAMUM LETTER PHASE-C MBAA PICKET -// 168e4 BAMUM LETTER PHASE-C YUWOQ -// 168e5 BAMUM LETTER PHASE-C NJEUX -// 168e6 BAMUM LETTER PHASE-C MIEE -// 168e7 BAMUM LETTER PHASE-C MUAE -// 168e8 BAMUM LETTER PHASE-C SHIQ -// 168e9 BAMUM LETTER PHASE-C KEN LAW -// 168ea BAMUM LETTER PHASE-C KEN FATIGUE -// 168eb BAMUM LETTER PHASE-C NGAQ -// 168ec BAMUM LETTER PHASE-C NAQ -// 168ed BAMUM LETTER PHASE-C LIQ -// 168ee BAMUM LETTER PHASE-C PIN -// 168ef BAMUM LETTER PHASE-C PEN -// 168f0 BAMUM LETTER PHASE-C TET -// 168f1 BAMUM LETTER PHASE-D MBUO -// 168f2 BAMUM LETTER PHASE-D WAP -// 168f3 BAMUM LETTER PHASE-D NJI -// 168f4 BAMUM LETTER PHASE-D MFON -// 168f5 BAMUM LETTER PHASE-D NJIEE -// 168f6 BAMUM LETTER PHASE-D LIEE -// 168f7 BAMUM LETTER PHASE-D NJEUT -// 168f8 BAMUM LETTER PHASE-D NSHEE -// 168f9 BAMUM LETTER PHASE-D NGGAAMAE -// 168fa BAMUM LETTER PHASE-D NYAM -// 168fb BAMUM LETTER PHASE-D WUAEN -// 168fc BAMUM LETTER PHASE-D NGKUN -// 168fd BAMUM LETTER PHASE-D SHEE -// 168fe BAMUM LETTER PHASE-D NGKAP -// 168ff BAMUM LETTER PHASE-D KEUAETMEUN -// 16900 BAMUM LETTER PHASE-D TEUT -// 16901 BAMUM LETTER PHASE-D SHEUAE -// 16902 BAMUM LETTER PHASE-D NJAP -// 16903 BAMUM LETTER PHASE-D SUE -// 16904 BAMUM LETTER PHASE-D KET -// 16905 BAMUM LETTER PHASE-D YAEMMAE -// 16906 BAMUM LETTER PHASE-D KUOM -// 16907 BAMUM LETTER PHASE-D SAP -// 16908 BAMUM LETTER PHASE-D MFEUT -// 16909 BAMUM LETTER PHASE-D NDEUX -// 1690a BAMUM LETTER PHASE-D MALEERI -// 1690b BAMUM LETTER PHASE-D MEUT -// 1690c BAMUM LETTER PHASE-D SEUAEQ -// 1690d BAMUM LETTER PHASE-D YEN -// 1690e BAMUM LETTER PHASE-D NJEUAEM -// 1690f BAMUM LETTER PHASE-D KEUOT MBUAE -// 16910 BAMUM LETTER PHASE-D NGKEURI -// 16911 BAMUM LETTER PHASE-D TU -// 16912 BAMUM LETTER PHASE-D GHAA -// 16913 BAMUM LETTER PHASE-D NGKYEE -// 16914 BAMUM LETTER PHASE-D FEUFEUAET -// 16915 BAMUM LETTER PHASE-D NDEE -// 16916 BAMUM LETTER PHASE-D MGBOFUM -// 16917 BAMUM LETTER PHASE-D LEUAEP -// 16918 BAMUM LETTER PHASE-D NDON -// 16919 BAMUM LETTER PHASE-D MONI -// 1691a BAMUM LETTER PHASE-D MGBEUN -// 1691b BAMUM LETTER PHASE-D PUUT -// 1691c BAMUM LETTER PHASE-D MGBIEE -// 1691d BAMUM LETTER PHASE-D MFO -// 1691e BAMUM LETTER PHASE-D LUM -// 1691f BAMUM LETTER PHASE-D NSIEEP -// 16920 BAMUM LETTER PHASE-D MBAA -// 16921 BAMUM LETTER PHASE-D KWAET -// 16922 BAMUM LETTER PHASE-D NYET -// 16923 BAMUM LETTER PHASE-D TEUAEN -// 16924 BAMUM LETTER PHASE-D SOT -// 16925 BAMUM LETTER PHASE-D YUWOQ -// 16926 BAMUM LETTER PHASE-D KEUM -// 16927 BAMUM LETTER PHASE-D RAEM -// 16928 BAMUM LETTER PHASE-D TEEEE -// 16929 BAMUM LETTER PHASE-D NGKEUAEQ -// 1692a BAMUM LETTER PHASE-D MFEUAE -// 1692b BAMUM LETTER PHASE-D NSIEET -// 1692c BAMUM LETTER PHASE-D KEUP -// 1692d BAMUM LETTER PHASE-D PIP -// 1692e BAMUM LETTER PHASE-D PEUTAE -// 1692f BAMUM LETTER PHASE-D NYUE -// 16930 BAMUM LETTER PHASE-D LET -// 16931 BAMUM LETTER PHASE-D NGGAAM -// 16932 BAMUM LETTER PHASE-D MFIEE -// 16933 BAMUM LETTER PHASE-D NGGWAEN -// 16934 BAMUM LETTER PHASE-D YUOM -// 16935 BAMUM LETTER PHASE-D PAP -// 16936 BAMUM LETTER PHASE-D YUOP -// 16937 BAMUM LETTER PHASE-D NDAM -// 16938 BAMUM LETTER PHASE-D NTEUM -// 16939 BAMUM LETTER PHASE-D SUAE -// 1693a BAMUM LETTER PHASE-D KUN -// 1693b BAMUM LETTER PHASE-D NGGEUX -// 1693c BAMUM LETTER PHASE-D NGKIEE -// 1693d BAMUM LETTER PHASE-D TUOT -// 1693e BAMUM LETTER PHASE-D MEUN -// 1693f BAMUM LETTER PHASE-D KUQ -// 16940 BAMUM LETTER PHASE-D NSUM -// 16941 BAMUM LETTER PHASE-D TEUN -// 16942 BAMUM LETTER PHASE-D MAENJET -// 16943 BAMUM LETTER PHASE-D NGGAP -// 16944 BAMUM LETTER PHASE-D LEUM -// 16945 BAMUM LETTER PHASE-D NGGUOM -// 16946 BAMUM LETTER PHASE-D NSHUT -// 16947 BAMUM LETTER PHASE-D NJUEQ -// 16948 BAMUM LETTER PHASE-D GHEUAE -// 16949 BAMUM LETTER PHASE-D KU -// 1694a BAMUM LETTER PHASE-D REN OLD -// 1694b BAMUM LETTER PHASE-D TAE -// 1694c BAMUM LETTER PHASE-D TOQ -// 1694d BAMUM LETTER PHASE-D NYI -// 1694e BAMUM LETTER PHASE-D RII -// 1694f BAMUM LETTER PHASE-D LEEEE -// 16950 BAMUM LETTER PHASE-D MEEEE -// 16951 BAMUM LETTER PHASE-D M -// 16952 BAMUM LETTER PHASE-D SUU -// 16953 BAMUM LETTER PHASE-D MU -// 16954 BAMUM LETTER PHASE-D SHII -// 16955 BAMUM LETTER PHASE-D SHEUX -// 16956 BAMUM LETTER PHASE-D KYEE -// 16957 BAMUM LETTER PHASE-D NU -// 16958 BAMUM LETTER PHASE-D SHU -// 16959 BAMUM LETTER PHASE-D NTEE -// 1695a BAMUM LETTER PHASE-D PEE -// 1695b BAMUM LETTER PHASE-D NI -// 1695c BAMUM LETTER PHASE-D SHOQ -// 1695d BAMUM LETTER PHASE-D PUQ -// 1695e BAMUM LETTER PHASE-D MVOP -// 1695f BAMUM LETTER PHASE-D LOQ -// 16960 BAMUM LETTER PHASE-D REN MUCH -// 16961 BAMUM LETTER PHASE-D TI -// 16962 BAMUM LETTER PHASE-D NTUU -// 16963 BAMUM LETTER PHASE-D MBAA SEVEN -// 16964 BAMUM LETTER PHASE-D SAQ -// 16965 BAMUM LETTER PHASE-D FAA -// 16966 BAMUM LETTER PHASE-E NDAP -// 16967 BAMUM LETTER PHASE-E TOON -// 16968 BAMUM LETTER PHASE-E MBEUM -// 16969 BAMUM LETTER PHASE-E LAP -// 1696a BAMUM LETTER PHASE-E VOM -// 1696b BAMUM LETTER PHASE-E LOON -// 1696c BAMUM LETTER PHASE-E PAA -// 1696d BAMUM LETTER PHASE-E SOM -// 1696e BAMUM LETTER PHASE-E RAQ -// 1696f BAMUM LETTER PHASE-E NSHUOP -// 16970 BAMUM LETTER PHASE-E NDUN -// 16971 BAMUM LETTER PHASE-E PUAE -// 16972 BAMUM LETTER PHASE-E TAM -// 16973 BAMUM LETTER PHASE-E NGKA -// 16974 BAMUM LETTER PHASE-E KPEUX -// 16975 BAMUM LETTER PHASE-E WUO -// 16976 BAMUM LETTER PHASE-E SEE -// 16977 BAMUM LETTER PHASE-E NGGEUAET -// 16978 BAMUM LETTER PHASE-E PAAM -// 16979 BAMUM LETTER PHASE-E TOO -// 1697a BAMUM LETTER PHASE-E KUOP -// 1697b BAMUM LETTER PHASE-E LOM -// 1697c BAMUM LETTER PHASE-E NSHIEE -// 1697d BAMUM LETTER PHASE-E NGOP -// 1697e BAMUM LETTER PHASE-E MAEM -// 1697f BAMUM LETTER PHASE-E NGKEUX -// 16980 BAMUM LETTER PHASE-E NGOQ -// 16981 BAMUM LETTER PHASE-E NSHUE -// 16982 BAMUM LETTER PHASE-E RIMGBA -// 16983 BAMUM LETTER PHASE-E NJEUX -// 16984 BAMUM LETTER PHASE-E PEEM -// 16985 BAMUM LETTER PHASE-E SAA -// 16986 BAMUM LETTER PHASE-E NGGURAE -// 16987 BAMUM LETTER PHASE-E MGBA -// 16988 BAMUM LETTER PHASE-E GHEUX -// 16989 BAMUM LETTER PHASE-E NGKEUAEM -// 1698a BAMUM LETTER PHASE-E NJAEMLI -// 1698b BAMUM LETTER PHASE-E MAP -// 1698c BAMUM LETTER PHASE-E LOOT -// 1698d BAMUM LETTER PHASE-E NGGEEEE -// 1698e BAMUM LETTER PHASE-E NDIQ -// 1698f BAMUM LETTER PHASE-E TAEN NTEUM -// 16990 BAMUM LETTER PHASE-E SET -// 16991 BAMUM LETTER PHASE-E PUM -// 16992 BAMUM LETTER PHASE-E NDAA SOFTNESS -// 16993 BAMUM LETTER PHASE-E NGGUAESHAE NYAM -// 16994 BAMUM LETTER PHASE-E YIEE -// 16995 BAMUM LETTER PHASE-E GHEUN -// 16996 BAMUM LETTER PHASE-E TUAE -// 16997 BAMUM LETTER PHASE-E YEUAE -// 16998 BAMUM LETTER PHASE-E PO -// 16999 BAMUM LETTER PHASE-E TUMAE -// 1699a BAMUM LETTER PHASE-E KEUAE -// 1699b BAMUM LETTER PHASE-E SUAEN -// 1699c BAMUM LETTER PHASE-E TEUAEQ -// 1699d BAMUM LETTER PHASE-E VEUAE -// 1699e BAMUM LETTER PHASE-E WEUX -// 1699f BAMUM LETTER PHASE-E LAAM -// 169a0 BAMUM LETTER PHASE-E PU -// 169a1 BAMUM LETTER PHASE-E TAAQ -// 169a2 BAMUM LETTER PHASE-E GHAAMAE -// 169a3 BAMUM LETTER PHASE-E NGEUREUT -// 169a4 BAMUM LETTER PHASE-E SHEUAEQ -// 169a5 BAMUM LETTER PHASE-E MGBEN -// 169a6 BAMUM LETTER PHASE-E MBEE -// 169a7 BAMUM LETTER PHASE-E NZAQ -// 169a8 BAMUM LETTER PHASE-E NKOM -// 169a9 BAMUM LETTER PHASE-E GBET -// 169aa BAMUM LETTER PHASE-E TUM -// 169ab BAMUM LETTER PHASE-E KUET -// 169ac BAMUM LETTER PHASE-E YAP -// 169ad BAMUM LETTER PHASE-E NYI CLEAVER -// 169ae BAMUM LETTER PHASE-E YIT -// 169af BAMUM LETTER PHASE-E MFEUQ -// 169b0 BAMUM LETTER PHASE-E NDIAQ -// 169b1 BAMUM LETTER PHASE-E PIEEQ -// 169b2 BAMUM LETTER PHASE-E YUEQ -// 169b3 BAMUM LETTER PHASE-E LEUAEM -// 169b4 BAMUM LETTER PHASE-E FUE -// 169b5 BAMUM LETTER PHASE-E GBEUX -// 169b6 BAMUM LETTER PHASE-E NGKUP -// 169b7 BAMUM LETTER PHASE-E KET -// 169b8 BAMUM LETTER PHASE-E MAE -// 169b9 BAMUM LETTER PHASE-E NGKAAMI -// 169ba BAMUM LETTER PHASE-E GHET -// 169bb BAMUM LETTER PHASE-E FA -// 169bc BAMUM LETTER PHASE-E NTUM -// 169bd BAMUM LETTER PHASE-E PEUT -// 169be BAMUM LETTER PHASE-E YEUM -// 169bf BAMUM LETTER PHASE-E NGGEUAE -// 169c0 BAMUM LETTER PHASE-E NYI BETWEEN -// 169c1 BAMUM LETTER PHASE-E NZUQ -// 169c2 BAMUM LETTER PHASE-E POON -// 169c3 BAMUM LETTER PHASE-E MIEE -// 169c4 BAMUM LETTER PHASE-E FUET -// 169c5 BAMUM LETTER PHASE-E NAE -// 169c6 BAMUM LETTER PHASE-E MUAE -// 169c7 BAMUM LETTER PHASE-E GHEUAE -// 169c8 BAMUM LETTER PHASE-E FU I -// 169c9 BAMUM LETTER PHASE-E MVI -// 169ca BAMUM LETTER PHASE-E PUAQ -// 169cb BAMUM LETTER PHASE-E NGKUM -// 169cc BAMUM LETTER PHASE-E KUT -// 169cd BAMUM LETTER PHASE-E PIET -// 169ce BAMUM LETTER PHASE-E NTAP -// 169cf BAMUM LETTER PHASE-E YEUAET -// 169d0 BAMUM LETTER PHASE-E NGGUP -// 169d1 BAMUM LETTER PHASE-E PA PEOPLE -// 169d2 BAMUM LETTER PHASE-E FU CALL -// 169d3 BAMUM LETTER PHASE-E FOM -// 169d4 BAMUM LETTER PHASE-E NJEE -// 169d5 BAMUM LETTER PHASE-E A -// 169d6 BAMUM LETTER PHASE-E TOQ -// 169d7 BAMUM LETTER PHASE-E O -// 169d8 BAMUM LETTER PHASE-E I -// 169d9 BAMUM LETTER PHASE-E LAQ -// 169da BAMUM LETTER PHASE-E PA PLURAL -// 169db BAMUM LETTER PHASE-E TAA -// 169dc BAMUM LETTER PHASE-E TAQ -// 169dd BAMUM LETTER PHASE-E NDAA MY HOUSE -// 169de BAMUM LETTER PHASE-E SHIQ -// 169df BAMUM LETTER PHASE-E YEUX -// 169e0 BAMUM LETTER PHASE-E NGUAE -// 169e1 BAMUM LETTER PHASE-E YUAEN -// 169e2 BAMUM LETTER PHASE-E YOQ SWIMMING -// 169e3 BAMUM LETTER PHASE-E YOQ COVER -// 169e4 BAMUM LETTER PHASE-E YUQ -// 169e5 BAMUM LETTER PHASE-E YUN -// 169e6 BAMUM LETTER PHASE-E KEUX -// 169e7 BAMUM LETTER PHASE-E PEUX -// 169e8 BAMUM LETTER PHASE-E NJEE EPOCH -// 169e9 BAMUM LETTER PHASE-E PUE -// 169ea BAMUM LETTER PHASE-E WUE -// 169eb BAMUM LETTER PHASE-E FEE -// 169ec BAMUM LETTER PHASE-E VEE -// 169ed BAMUM LETTER PHASE-E LU -// 169ee BAMUM LETTER PHASE-E MI -// 169ef BAMUM LETTER PHASE-E REUX -// 169f0 BAMUM LETTER PHASE-E RAE -// 169f1 BAMUM LETTER PHASE-E NGUAET -// 169f2 BAMUM LETTER PHASE-E NGA -// 169f3 BAMUM LETTER PHASE-E SHO -// 169f4 BAMUM LETTER PHASE-E SHOQ -// 169f5 BAMUM LETTER PHASE-E FU REMEDY -// 169f6 BAMUM LETTER PHASE-E NA -// 169f7 BAMUM LETTER PHASE-E PI -// 169f8 BAMUM LETTER PHASE-E LOQ -// 169f9 BAMUM LETTER PHASE-E KO -// 169fa BAMUM LETTER PHASE-E MEN -// 169fb BAMUM LETTER PHASE-E MA -// 169fc BAMUM LETTER PHASE-E MAQ -// 169fd BAMUM LETTER PHASE-E TEU -// 169fe BAMUM LETTER PHASE-E KI -// 169ff BAMUM LETTER PHASE-E MON -// 16a00 BAMUM LETTER PHASE-E TEN -// 16a01 BAMUM LETTER PHASE-E FAQ -// 16a02 BAMUM LETTER PHASE-E GHOM -// 16a03 BAMUM LETTER PHASE-F KA -// 16a04 BAMUM LETTER PHASE-F U -// 16a05 BAMUM LETTER PHASE-F KU -// 16a06 BAMUM LETTER PHASE-F EE -// 16a07 BAMUM LETTER PHASE-F REE -// 16a08 BAMUM LETTER PHASE-F TAE -// 16a09 BAMUM LETTER PHASE-F NYI -// 16a0a BAMUM LETTER PHASE-F LA -// 16a0b BAMUM LETTER PHASE-F RII -// 16a0c BAMUM LETTER PHASE-F RIEE -// 16a0d BAMUM LETTER PHASE-F MEEEE -// 16a0e BAMUM LETTER PHASE-F TAA -// 16a0f BAMUM LETTER PHASE-F NDAA -// 16a10 BAMUM LETTER PHASE-F NJAEM -// 16a11 BAMUM LETTER PHASE-F M -// 16a12 BAMUM LETTER PHASE-F SUU -// 16a13 BAMUM LETTER PHASE-F SHII -// 16a14 BAMUM LETTER PHASE-F SI -// 16a15 BAMUM LETTER PHASE-F SEUX -// 16a16 BAMUM LETTER PHASE-F KYEE -// 16a17 BAMUM LETTER PHASE-F KET -// 16a18 BAMUM LETTER PHASE-F NUAE -// 16a19 BAMUM LETTER PHASE-F NU -// 16a1a BAMUM LETTER PHASE-F NJUAE -// 16a1b BAMUM LETTER PHASE-F YOQ -// 16a1c BAMUM LETTER PHASE-F SHU -// 16a1d BAMUM LETTER PHASE-F YA -// 16a1e BAMUM LETTER PHASE-F NSHA -// 16a1f BAMUM LETTER PHASE-F PEUX -// 16a20 BAMUM LETTER PHASE-F NTEE -// 16a21 BAMUM LETTER PHASE-F WUE -// 16a22 BAMUM LETTER PHASE-F PEE -// 16a23 BAMUM LETTER PHASE-F RU -// 16a24 BAMUM LETTER PHASE-F NI -// 16a25 BAMUM LETTER PHASE-F REUX -// 16a26 BAMUM LETTER PHASE-F KEN -// 16a27 BAMUM LETTER PHASE-F NGKWAEN -// 16a28 BAMUM LETTER PHASE-F NGGA -// 16a29 BAMUM LETTER PHASE-F SHO -// 16a2a BAMUM LETTER PHASE-F PUAE -// 16a2b BAMUM LETTER PHASE-F FOM -// 16a2c BAMUM LETTER PHASE-F WA -// 16a2d BAMUM LETTER PHASE-F LI -// 16a2e BAMUM LETTER PHASE-F LOQ -// 16a2f BAMUM LETTER PHASE-F KO -// 16a30 BAMUM LETTER PHASE-F MBEN -// 16a31 BAMUM LETTER PHASE-F REN -// 16a32 BAMUM LETTER PHASE-F MA -// 16a33 BAMUM LETTER PHASE-F MO -// 16a34 BAMUM LETTER PHASE-F MBAA -// 16a35 BAMUM LETTER PHASE-F TET -// 16a36 BAMUM LETTER PHASE-F KPA -// 16a37 BAMUM LETTER PHASE-F SAMBA -// 16a38 BAMUM LETTER PHASE-F VUEQ - { 0x16800, 0x239, 0x9, 0, 0 }, -// 16a40 MRO LETTER TA -// 16a41 MRO LETTER NGI -// 16a42 MRO LETTER YO -// 16a43 MRO LETTER MIM -// 16a44 MRO LETTER BA -// 16a45 MRO LETTER DA -// 16a46 MRO LETTER A -// 16a47 MRO LETTER PHI -// 16a48 MRO LETTER KHAI -// 16a49 MRO LETTER HAO -// 16a4a MRO LETTER DAI -// 16a4b MRO LETTER CHU -// 16a4c MRO LETTER KEAAE -// 16a4d MRO LETTER OL -// 16a4e MRO LETTER MAEM -// 16a4f MRO LETTER NIN -// 16a50 MRO LETTER PA -// 16a51 MRO LETTER OO -// 16a52 MRO LETTER O -// 16a53 MRO LETTER RO -// 16a54 MRO LETTER SHI -// 16a55 MRO LETTER THEA -// 16a56 MRO LETTER EA -// 16a57 MRO LETTER WA -// 16a58 MRO LETTER E -// 16a59 MRO LETTER KO -// 16a5a MRO LETTER LAN -// 16a5b MRO LETTER LA -// 16a5c MRO LETTER HAI -// 16a5d MRO LETTER RI -// 16a5e MRO LETTER TEK - { 0x16A40, 0x1F, 0x9, 0, 0 }, -// 16a60 MRO DIGIT ZERO -// 16a61 MRO DIGIT ONE -// 16a62 MRO DIGIT TWO -// 16a63 MRO DIGIT THREE -// 16a64 MRO DIGIT FOUR -// 16a65 MRO DIGIT FIVE -// 16a66 MRO DIGIT SIX -// 16a67 MRO DIGIT SEVEN -// 16a68 MRO DIGIT EIGHT -// 16a69 MRO DIGIT NINE - { 0x16A60, 0xA, 0x108, 0, 0 }, -// 16a6e MRO DANDA -// 16a6f MRO DOUBLE DANDA - { 0x16A6E, 0x2, 0x18, 0, 0 }, -// 16ad0 BASSA VAH LETTER ENNI -// 16ad1 BASSA VAH LETTER KA -// 16ad2 BASSA VAH LETTER SE -// 16ad3 BASSA VAH LETTER FA -// 16ad4 BASSA VAH LETTER MBE -// 16ad5 BASSA VAH LETTER YIE -// 16ad6 BASSA VAH LETTER GAH -// 16ad7 BASSA VAH LETTER DHII -// 16ad8 BASSA VAH LETTER KPAH -// 16ad9 BASSA VAH LETTER JO -// 16ada BASSA VAH LETTER HWAH -// 16adb BASSA VAH LETTER WA -// 16adc BASSA VAH LETTER ZO -// 16add BASSA VAH LETTER GBU -// 16ade BASSA VAH LETTER DO -// 16adf BASSA VAH LETTER CE -// 16ae0 BASSA VAH LETTER UWU -// 16ae1 BASSA VAH LETTER TO -// 16ae2 BASSA VAH LETTER BA -// 16ae3 BASSA VAH LETTER VU -// 16ae4 BASSA VAH LETTER YEIN -// 16ae5 BASSA VAH LETTER PA -// 16ae6 BASSA VAH LETTER WADDA -// 16ae7 BASSA VAH LETTER A -// 16ae8 BASSA VAH LETTER O -// 16ae9 BASSA VAH LETTER OO -// 16aea BASSA VAH LETTER U -// 16aeb BASSA VAH LETTER EE -// 16aec BASSA VAH LETTER E -// 16aed BASSA VAH LETTER I - { 0x16AD0, 0x1E, 0x9, 0, 0 }, -// 16af0 BASSA VAH COMBINING HIGH TONE -// 16af1 BASSA VAH COMBINING LOW TONE -// 16af2 BASSA VAH COMBINING MID TONE -// 16af3 BASSA VAH COMBINING LOW-MID TONE -// 16af4 BASSA VAH COMBINING HIGH-LOW TONE - { 0x16AF0, 0x5, 0x0, 0, 0 }, -// 16af5 BASSA VAH FULL STOP - { 0x16AF5, 0x1, 0x18, 0, 0 }, -// 16b00 PAHAWH HMONG VOWEL KEEB -// 16b01 PAHAWH HMONG VOWEL KEEV -// 16b02 PAHAWH HMONG VOWEL KIB -// 16b03 PAHAWH HMONG VOWEL KIV -// 16b04 PAHAWH HMONG VOWEL KAUB -// 16b05 PAHAWH HMONG VOWEL KAUV -// 16b06 PAHAWH HMONG VOWEL KUB -// 16b07 PAHAWH HMONG VOWEL KUV -// 16b08 PAHAWH HMONG VOWEL KEB -// 16b09 PAHAWH HMONG VOWEL KEV -// 16b0a PAHAWH HMONG VOWEL KAIB -// 16b0b PAHAWH HMONG VOWEL KAIV -// 16b0c PAHAWH HMONG VOWEL KOOB -// 16b0d PAHAWH HMONG VOWEL KOOV -// 16b0e PAHAWH HMONG VOWEL KAWB -// 16b0f PAHAWH HMONG VOWEL KAWV -// 16b10 PAHAWH HMONG VOWEL KUAB -// 16b11 PAHAWH HMONG VOWEL KUAV -// 16b12 PAHAWH HMONG VOWEL KOB -// 16b13 PAHAWH HMONG VOWEL KOV -// 16b14 PAHAWH HMONG VOWEL KIAB -// 16b15 PAHAWH HMONG VOWEL KIAV -// 16b16 PAHAWH HMONG VOWEL KAB -// 16b17 PAHAWH HMONG VOWEL KAV -// 16b18 PAHAWH HMONG VOWEL KWB -// 16b19 PAHAWH HMONG VOWEL KWV -// 16b1a PAHAWH HMONG VOWEL KAAB -// 16b1b PAHAWH HMONG VOWEL KAAV -// 16b1c PAHAWH HMONG CONSONANT VAU -// 16b1d PAHAWH HMONG CONSONANT NTSAU -// 16b1e PAHAWH HMONG CONSONANT LAU -// 16b1f PAHAWH HMONG CONSONANT HAU -// 16b20 PAHAWH HMONG CONSONANT NLAU -// 16b21 PAHAWH HMONG CONSONANT RAU -// 16b22 PAHAWH HMONG CONSONANT NKAU -// 16b23 PAHAWH HMONG CONSONANT QHAU -// 16b24 PAHAWH HMONG CONSONANT YAU -// 16b25 PAHAWH HMONG CONSONANT HLAU -// 16b26 PAHAWH HMONG CONSONANT MAU -// 16b27 PAHAWH HMONG CONSONANT CHAU -// 16b28 PAHAWH HMONG CONSONANT NCHAU -// 16b29 PAHAWH HMONG CONSONANT HNAU -// 16b2a PAHAWH HMONG CONSONANT PLHAU -// 16b2b PAHAWH HMONG CONSONANT NTHAU -// 16b2c PAHAWH HMONG CONSONANT NAU -// 16b2d PAHAWH HMONG CONSONANT AU -// 16b2e PAHAWH HMONG CONSONANT XAU -// 16b2f PAHAWH HMONG CONSONANT CAU - { 0x16B00, 0x30, 0x9, 0, 0 }, -// 16b30 PAHAWH HMONG MARK CIM TUB -// 16b31 PAHAWH HMONG MARK CIM SO -// 16b32 PAHAWH HMONG MARK CIM KES -// 16b33 PAHAWH HMONG MARK CIM KHAV -// 16b34 PAHAWH HMONG MARK CIM SUAM -// 16b35 PAHAWH HMONG MARK CIM HOM -// 16b36 PAHAWH HMONG MARK CIM TAUM - { 0x16B30, 0x7, 0x0, 0, 0 }, -// 16b37 PAHAWH HMONG SIGN VOS THOM -// 16b38 PAHAWH HMONG SIGN VOS TSHAB CEEB -// 16b39 PAHAWH HMONG SIGN CIM CHEEM -// 16b3a PAHAWH HMONG SIGN VOS THIAB -// 16b3b PAHAWH HMONG SIGN VOS FEEM - { 0x16B37, 0x5, 0x18, 0, 0 }, -// 16b3c PAHAWH HMONG SIGN XYEEM NTXIV -// 16b3d PAHAWH HMONG SIGN XYEEM RHO -// 16b3e PAHAWH HMONG SIGN XYEEM TOV -// 16b3f PAHAWH HMONG SIGN XYEEM FAIB - { 0x16B3C, 0x4, 0x8, 0, 0 }, -// 16b40 PAHAWH HMONG SIGN VOS SEEV -// 16b41 PAHAWH HMONG SIGN MEEJ SUAB -// 16b42 PAHAWH HMONG SIGN VOS NRUA -// 16b43 PAHAWH HMONG SIGN IB YAM - { 0x16B40, 0x4, 0x9, 0, 0 }, -// 16b44 PAHAWH HMONG SIGN XAUS - { 0x16B44, 0x1, 0x18, 0, 0 }, -// 16b45 PAHAWH HMONG SIGN CIM TSOV ROG - { 0x16B45, 0x1, 0x8, 0, 0 }, -// 16b50 PAHAWH HMONG DIGIT ZERO -// 16b51 PAHAWH HMONG DIGIT ONE -// 16b52 PAHAWH HMONG DIGIT TWO -// 16b53 PAHAWH HMONG DIGIT THREE -// 16b54 PAHAWH HMONG DIGIT FOUR -// 16b55 PAHAWH HMONG DIGIT FIVE -// 16b56 PAHAWH HMONG DIGIT SIX -// 16b57 PAHAWH HMONG DIGIT SEVEN -// 16b58 PAHAWH HMONG DIGIT EIGHT -// 16b59 PAHAWH HMONG DIGIT NINE - { 0x16B50, 0xA, 0x108, 0, 0 }, -// 16b5b PAHAWH HMONG NUMBER TENS -// 16b5c PAHAWH HMONG NUMBER HUNDREDS -// 16b5d PAHAWH HMONG NUMBER TEN THOUSANDS -// 16b5e PAHAWH HMONG NUMBER MILLIONS -// 16b5f PAHAWH HMONG NUMBER HUNDRED MILLIONS -// 16b60 PAHAWH HMONG NUMBER TEN BILLIONS -// 16b61 PAHAWH HMONG NUMBER TRILLIONS - { 0x16B5B, 0x7, 0x8, 0, 0 }, -// 16b63 PAHAWH HMONG SIGN VOS LUB -// 16b64 PAHAWH HMONG SIGN XYOO -// 16b65 PAHAWH HMONG SIGN HLI -// 16b66 PAHAWH HMONG SIGN THIRD-STAGE HLI -// 16b67 PAHAWH HMONG SIGN ZWJ THAJ -// 16b68 PAHAWH HMONG SIGN HNUB -// 16b69 PAHAWH HMONG SIGN NQIG -// 16b6a PAHAWH HMONG SIGN XIAB -// 16b6b PAHAWH HMONG SIGN NTUJ -// 16b6c PAHAWH HMONG SIGN AV -// 16b6d PAHAWH HMONG SIGN TXHEEJ CEEV -// 16b6e PAHAWH HMONG SIGN MEEJ TSEEB -// 16b6f PAHAWH HMONG SIGN TAU -// 16b70 PAHAWH HMONG SIGN LOS -// 16b71 PAHAWH HMONG SIGN MUS -// 16b72 PAHAWH HMONG SIGN CIM HAIS LUS NTOG NTOG -// 16b73 PAHAWH HMONG SIGN CIM CUAM TSHOOJ -// 16b74 PAHAWH HMONG SIGN CIM TXWV -// 16b75 PAHAWH HMONG SIGN CIM TXWV CHWV -// 16b76 PAHAWH HMONG SIGN CIM PUB DAWB -// 16b77 PAHAWH HMONG SIGN CIM NRES TOS - { 0x16B63, 0x15, 0x9, 0, 0 }, -// 16b7d PAHAWH HMONG CLAN SIGN TSHEEJ -// 16b7e PAHAWH HMONG CLAN SIGN YEEG -// 16b7f PAHAWH HMONG CLAN SIGN LIS -// 16b80 PAHAWH HMONG CLAN SIGN LAUJ -// 16b81 PAHAWH HMONG CLAN SIGN XYOOJ -// 16b82 PAHAWH HMONG CLAN SIGN KOO -// 16b83 PAHAWH HMONG CLAN SIGN HAWJ -// 16b84 PAHAWH HMONG CLAN SIGN MUAS -// 16b85 PAHAWH HMONG CLAN SIGN THOJ -// 16b86 PAHAWH HMONG CLAN SIGN TSAB -// 16b87 PAHAWH HMONG CLAN SIGN PHAB -// 16b88 PAHAWH HMONG CLAN SIGN KHAB -// 16b89 PAHAWH HMONG CLAN SIGN HAM -// 16b8a PAHAWH HMONG CLAN SIGN VAJ -// 16b8b PAHAWH HMONG CLAN SIGN FAJ -// 16b8c PAHAWH HMONG CLAN SIGN YAJ -// 16b8d PAHAWH HMONG CLAN SIGN TSWB -// 16b8e PAHAWH HMONG CLAN SIGN KWM -// 16b8f PAHAWH HMONG CLAN SIGN VWJ - { 0x16B7D, 0x13, 0x9, 0, 0 }, -// 16f00 MIAO LETTER PA -// 16f01 MIAO LETTER BA -// 16f02 MIAO LETTER YI PA -// 16f03 MIAO LETTER PLA -// 16f04 MIAO LETTER MA -// 16f05 MIAO LETTER MHA -// 16f06 MIAO LETTER ARCHAIC MA -// 16f07 MIAO LETTER FA -// 16f08 MIAO LETTER VA -// 16f09 MIAO LETTER VFA -// 16f0a MIAO LETTER TA -// 16f0b MIAO LETTER DA -// 16f0c MIAO LETTER YI TTA -// 16f0d MIAO LETTER YI TA -// 16f0e MIAO LETTER TTA -// 16f0f MIAO LETTER DDA -// 16f10 MIAO LETTER NA -// 16f11 MIAO LETTER NHA -// 16f12 MIAO LETTER YI NNA -// 16f13 MIAO LETTER ARCHAIC NA -// 16f14 MIAO LETTER NNA -// 16f15 MIAO LETTER NNHA -// 16f16 MIAO LETTER LA -// 16f17 MIAO LETTER LYA -// 16f18 MIAO LETTER LHA -// 16f19 MIAO LETTER LHYA -// 16f1a MIAO LETTER TLHA -// 16f1b MIAO LETTER DLHA -// 16f1c MIAO LETTER TLHYA -// 16f1d MIAO LETTER DLHYA -// 16f1e MIAO LETTER KA -// 16f1f MIAO LETTER GA -// 16f20 MIAO LETTER YI KA -// 16f21 MIAO LETTER QA -// 16f22 MIAO LETTER QGA -// 16f23 MIAO LETTER NGA -// 16f24 MIAO LETTER NGHA -// 16f25 MIAO LETTER ARCHAIC NGA -// 16f26 MIAO LETTER HA -// 16f27 MIAO LETTER XA -// 16f28 MIAO LETTER GHA -// 16f29 MIAO LETTER GHHA -// 16f2a MIAO LETTER TSSA -// 16f2b MIAO LETTER DZZA -// 16f2c MIAO LETTER NYA -// 16f2d MIAO LETTER NYHA -// 16f2e MIAO LETTER TSHA -// 16f2f MIAO LETTER DZHA -// 16f30 MIAO LETTER YI TSHA -// 16f31 MIAO LETTER YI DZHA -// 16f32 MIAO LETTER REFORMED TSHA -// 16f33 MIAO LETTER SHA -// 16f34 MIAO LETTER SSA -// 16f35 MIAO LETTER ZHA -// 16f36 MIAO LETTER ZSHA -// 16f37 MIAO LETTER TSA -// 16f38 MIAO LETTER DZA -// 16f39 MIAO LETTER YI TSA -// 16f3a MIAO LETTER SA -// 16f3b MIAO LETTER ZA -// 16f3c MIAO LETTER ZSA -// 16f3d MIAO LETTER ZZA -// 16f3e MIAO LETTER ZZSA -// 16f3f MIAO LETTER ARCHAIC ZZA -// 16f40 MIAO LETTER ZZYA -// 16f41 MIAO LETTER ZZSYA -// 16f42 MIAO LETTER WA -// 16f43 MIAO LETTER AH -// 16f44 MIAO LETTER HHA - { 0x16F00, 0x45, 0x9, 0, 0 }, -// 16f50 MIAO LETTER NASALIZATION - { 0x16F50, 0x1, 0x9, 0, 0 }, -// 16f51 MIAO SIGN ASPIRATION -// 16f52 MIAO SIGN REFORMED VOICING -// 16f53 MIAO SIGN REFORMED ASPIRATION -// 16f54 MIAO VOWEL SIGN A -// 16f55 MIAO VOWEL SIGN AA -// 16f56 MIAO VOWEL SIGN AHH -// 16f57 MIAO VOWEL SIGN AN -// 16f58 MIAO VOWEL SIGN ANG -// 16f59 MIAO VOWEL SIGN O -// 16f5a MIAO VOWEL SIGN OO -// 16f5b MIAO VOWEL SIGN WO -// 16f5c MIAO VOWEL SIGN W -// 16f5d MIAO VOWEL SIGN E -// 16f5e MIAO VOWEL SIGN EN -// 16f5f MIAO VOWEL SIGN ENG -// 16f60 MIAO VOWEL SIGN OEY -// 16f61 MIAO VOWEL SIGN I -// 16f62 MIAO VOWEL SIGN IA -// 16f63 MIAO VOWEL SIGN IAN -// 16f64 MIAO VOWEL SIGN IANG -// 16f65 MIAO VOWEL SIGN IO -// 16f66 MIAO VOWEL SIGN IE -// 16f67 MIAO VOWEL SIGN II -// 16f68 MIAO VOWEL SIGN IU -// 16f69 MIAO VOWEL SIGN ING -// 16f6a MIAO VOWEL SIGN U -// 16f6b MIAO VOWEL SIGN UA -// 16f6c MIAO VOWEL SIGN UAN -// 16f6d MIAO VOWEL SIGN UANG -// 16f6e MIAO VOWEL SIGN UU -// 16f6f MIAO VOWEL SIGN UEI -// 16f70 MIAO VOWEL SIGN UNG -// 16f71 MIAO VOWEL SIGN Y -// 16f72 MIAO VOWEL SIGN YI -// 16f73 MIAO VOWEL SIGN AE -// 16f74 MIAO VOWEL SIGN AEE -// 16f75 MIAO VOWEL SIGN ERR -// 16f76 MIAO VOWEL SIGN ROUNDED ERR -// 16f77 MIAO VOWEL SIGN ER -// 16f78 MIAO VOWEL SIGN ROUNDED ER -// 16f79 MIAO VOWEL SIGN AI -// 16f7a MIAO VOWEL SIGN EI -// 16f7b MIAO VOWEL SIGN AU -// 16f7c MIAO VOWEL SIGN OU -// 16f7d MIAO VOWEL SIGN N -// 16f7e MIAO VOWEL SIGN NG - { 0x16F51, 0x2E, 0x0, 0, 0 }, -// 16f8f MIAO TONE RIGHT -// 16f90 MIAO TONE TOP RIGHT -// 16f91 MIAO TONE ABOVE -// 16f92 MIAO TONE BELOW - { 0x16F8F, 0x4, 0x0, 0, 0 }, -// 16f93 MIAO LETTER TONE-2 -// 16f94 MIAO LETTER TONE-3 -// 16f95 MIAO LETTER TONE-4 -// 16f96 MIAO LETTER TONE-5 -// 16f97 MIAO LETTER TONE-6 -// 16f98 MIAO LETTER TONE-7 -// 16f99 MIAO LETTER TONE-8 -// 16f9a MIAO LETTER REFORMED TONE-1 -// 16f9b MIAO LETTER REFORMED TONE-2 -// 16f9c MIAO LETTER REFORMED TONE-4 -// 16f9d MIAO LETTER REFORMED TONE-5 -// 16f9e MIAO LETTER REFORMED TONE-6 -// 16f9f MIAO LETTER REFORMED TONE-8 - { 0x16F93, 0xD, 0x9, 0, 0 }, -// 1b000 KATAKANA LETTER ARCHAIC E -// 1b001 HIRAGANA LETTER ARCHAIC YE - { 0x1B000, 0x2, 0x9, 0, 0 }, -// 1bc00 DUPLOYAN LETTER H -// 1bc01 DUPLOYAN LETTER X -// 1bc02 DUPLOYAN LETTER P -// 1bc03 DUPLOYAN LETTER T -// 1bc04 DUPLOYAN LETTER F -// 1bc05 DUPLOYAN LETTER K -// 1bc06 DUPLOYAN LETTER L -// 1bc07 DUPLOYAN LETTER B -// 1bc08 DUPLOYAN LETTER D -// 1bc09 DUPLOYAN LETTER V -// 1bc0a DUPLOYAN LETTER G -// 1bc0b DUPLOYAN LETTER R -// 1bc0c DUPLOYAN LETTER P N -// 1bc0d DUPLOYAN LETTER D S -// 1bc0e DUPLOYAN LETTER F N -// 1bc0f DUPLOYAN LETTER K M -// 1bc10 DUPLOYAN LETTER R S -// 1bc11 DUPLOYAN LETTER TH -// 1bc12 DUPLOYAN LETTER SLOAN DH -// 1bc13 DUPLOYAN LETTER DH -// 1bc14 DUPLOYAN LETTER KK -// 1bc15 DUPLOYAN LETTER SLOAN J -// 1bc16 DUPLOYAN LETTER HL -// 1bc17 DUPLOYAN LETTER LH -// 1bc18 DUPLOYAN LETTER RH -// 1bc19 DUPLOYAN LETTER M -// 1bc1a DUPLOYAN LETTER N -// 1bc1b DUPLOYAN LETTER J -// 1bc1c DUPLOYAN LETTER S -// 1bc1d DUPLOYAN LETTER M N -// 1bc1e DUPLOYAN LETTER N M -// 1bc1f DUPLOYAN LETTER J M -// 1bc20 DUPLOYAN LETTER S J -// 1bc21 DUPLOYAN LETTER M WITH DOT -// 1bc22 DUPLOYAN LETTER N WITH DOT -// 1bc23 DUPLOYAN LETTER J WITH DOT -// 1bc24 DUPLOYAN LETTER J WITH DOTS INSIDE AND ABOVE -// 1bc25 DUPLOYAN LETTER S WITH DOT -// 1bc26 DUPLOYAN LETTER S WITH DOT BELOW -// 1bc27 DUPLOYAN LETTER M S -// 1bc28 DUPLOYAN LETTER N S -// 1bc29 DUPLOYAN LETTER J S -// 1bc2a DUPLOYAN LETTER S S -// 1bc2b DUPLOYAN LETTER M N S -// 1bc2c DUPLOYAN LETTER N M S -// 1bc2d DUPLOYAN LETTER J M S -// 1bc2e DUPLOYAN LETTER S J S -// 1bc2f DUPLOYAN LETTER J S WITH DOT -// 1bc30 DUPLOYAN LETTER J N -// 1bc31 DUPLOYAN LETTER J N S -// 1bc32 DUPLOYAN LETTER S T -// 1bc33 DUPLOYAN LETTER S T R -// 1bc34 DUPLOYAN LETTER S P -// 1bc35 DUPLOYAN LETTER S P R -// 1bc36 DUPLOYAN LETTER T S -// 1bc37 DUPLOYAN LETTER T R S -// 1bc38 DUPLOYAN LETTER W -// 1bc39 DUPLOYAN LETTER WH -// 1bc3a DUPLOYAN LETTER W R -// 1bc3b DUPLOYAN LETTER S N -// 1bc3c DUPLOYAN LETTER S M -// 1bc3d DUPLOYAN LETTER K R S -// 1bc3e DUPLOYAN LETTER G R S -// 1bc3f DUPLOYAN LETTER S K -// 1bc40 DUPLOYAN LETTER S K R -// 1bc41 DUPLOYAN LETTER A -// 1bc42 DUPLOYAN LETTER SLOAN OW -// 1bc43 DUPLOYAN LETTER OA -// 1bc44 DUPLOYAN LETTER O -// 1bc45 DUPLOYAN LETTER AOU -// 1bc46 DUPLOYAN LETTER I -// 1bc47 DUPLOYAN LETTER E -// 1bc48 DUPLOYAN LETTER IE -// 1bc49 DUPLOYAN LETTER SHORT I -// 1bc4a DUPLOYAN LETTER UI -// 1bc4b DUPLOYAN LETTER EE -// 1bc4c DUPLOYAN LETTER SLOAN EH -// 1bc4d DUPLOYAN LETTER ROMANIAN I -// 1bc4e DUPLOYAN LETTER SLOAN EE -// 1bc4f DUPLOYAN LETTER LONG I -// 1bc50 DUPLOYAN LETTER YE -// 1bc51 DUPLOYAN LETTER U -// 1bc52 DUPLOYAN LETTER EU -// 1bc53 DUPLOYAN LETTER XW -// 1bc54 DUPLOYAN LETTER U N -// 1bc55 DUPLOYAN LETTER LONG U -// 1bc56 DUPLOYAN LETTER ROMANIAN U -// 1bc57 DUPLOYAN LETTER UH -// 1bc58 DUPLOYAN LETTER SLOAN U -// 1bc59 DUPLOYAN LETTER OOH -// 1bc5a DUPLOYAN LETTER OW -// 1bc5b DUPLOYAN LETTER OU -// 1bc5c DUPLOYAN LETTER WA -// 1bc5d DUPLOYAN LETTER WO -// 1bc5e DUPLOYAN LETTER WI -// 1bc5f DUPLOYAN LETTER WEI -// 1bc60 DUPLOYAN LETTER WOW -// 1bc61 DUPLOYAN LETTER NASAL U -// 1bc62 DUPLOYAN LETTER NASAL O -// 1bc63 DUPLOYAN LETTER NASAL I -// 1bc64 DUPLOYAN LETTER NASAL A -// 1bc65 DUPLOYAN LETTER PERNIN AN -// 1bc66 DUPLOYAN LETTER PERNIN AM -// 1bc67 DUPLOYAN LETTER SLOAN EN -// 1bc68 DUPLOYAN LETTER SLOAN AN -// 1bc69 DUPLOYAN LETTER SLOAN ON -// 1bc6a DUPLOYAN LETTER VOCALIC M - { 0x1BC00, 0x6B, 0x9, 0, 0 }, -// 1bc70 DUPLOYAN AFFIX LEFT HORIZONTAL SECANT -// 1bc71 DUPLOYAN AFFIX MID HORIZONTAL SECANT -// 1bc72 DUPLOYAN AFFIX RIGHT HORIZONTAL SECANT -// 1bc73 DUPLOYAN AFFIX LOW VERTICAL SECANT -// 1bc74 DUPLOYAN AFFIX MID VERTICAL SECANT -// 1bc75 DUPLOYAN AFFIX HIGH VERTICAL SECANT -// 1bc76 DUPLOYAN AFFIX ATTACHED SECANT -// 1bc77 DUPLOYAN AFFIX ATTACHED LEFT-TO-RIGHT SECANT -// 1bc78 DUPLOYAN AFFIX ATTACHED TANGENT -// 1bc79 DUPLOYAN AFFIX ATTACHED TAIL -// 1bc7a DUPLOYAN AFFIX ATTACHED E HOOK -// 1bc7b DUPLOYAN AFFIX ATTACHED I HOOK -// 1bc7c DUPLOYAN AFFIX ATTACHED TANGENT HOOK - { 0x1BC70, 0xD, 0x9, 0, 0 }, -// 1bc80 DUPLOYAN AFFIX HIGH ACUTE -// 1bc81 DUPLOYAN AFFIX HIGH TIGHT ACUTE -// 1bc82 DUPLOYAN AFFIX HIGH GRAVE -// 1bc83 DUPLOYAN AFFIX HIGH LONG GRAVE -// 1bc84 DUPLOYAN AFFIX HIGH DOT -// 1bc85 DUPLOYAN AFFIX HIGH CIRCLE -// 1bc86 DUPLOYAN AFFIX HIGH LINE -// 1bc87 DUPLOYAN AFFIX HIGH WAVE -// 1bc88 DUPLOYAN AFFIX HIGH VERTICAL - { 0x1BC80, 0x9, 0x9, 0, 0 }, -// 1bc90 DUPLOYAN AFFIX LOW ACUTE -// 1bc91 DUPLOYAN AFFIX LOW TIGHT ACUTE -// 1bc92 DUPLOYAN AFFIX LOW GRAVE -// 1bc93 DUPLOYAN AFFIX LOW LONG GRAVE -// 1bc94 DUPLOYAN AFFIX LOW DOT -// 1bc95 DUPLOYAN AFFIX LOW CIRCLE -// 1bc96 DUPLOYAN AFFIX LOW LINE -// 1bc97 DUPLOYAN AFFIX LOW WAVE -// 1bc98 DUPLOYAN AFFIX LOW VERTICAL -// 1bc99 DUPLOYAN AFFIX LOW ARROW - { 0x1BC90, 0xA, 0x9, 0, 0 }, -// 1bc9c DUPLOYAN SIGN O WITH CROSS - { 0x1BC9C, 0x1, 0x8, 0, 0 }, -// 1bc9d DUPLOYAN THICK LETTER SELECTOR -// 1bc9e DUPLOYAN DOUBLE MARK - { 0x1BC9D, 0x2, 0x0, 0, 0 }, -// 1bc9f DUPLOYAN PUNCTUATION CHINOOK FULL STOP - { 0x1BC9F, 0x1, 0x18, 0, 0 }, -// 1bca0 SHORTHAND FORMAT LETTER OVERLAP -// 1bca1 SHORTHAND FORMAT CONTINUING OVERLAP -// 1bca2 SHORTHAND FORMAT DOWN STEP -// 1bca3 SHORTHAND FORMAT UP STEP - { 0x1BCA0, 0x4, 0x0, 0, 0 }, -// 1d000 BYZANTINE MUSICAL SYMBOL PSILI -// 1d001 BYZANTINE MUSICAL SYMBOL DASEIA -// 1d002 BYZANTINE MUSICAL SYMBOL PERISPOMENI -// 1d003 BYZANTINE MUSICAL SYMBOL OXEIA EKFONITIKON -// 1d004 BYZANTINE MUSICAL SYMBOL OXEIA DIPLI -// 1d005 BYZANTINE MUSICAL SYMBOL VAREIA EKFONITIKON -// 1d006 BYZANTINE MUSICAL SYMBOL VAREIA DIPLI -// 1d007 BYZANTINE MUSICAL SYMBOL KATHISTI -// 1d008 BYZANTINE MUSICAL SYMBOL SYRMATIKI -// 1d009 BYZANTINE MUSICAL SYMBOL PARAKLITIKI -// 1d00a BYZANTINE MUSICAL SYMBOL YPOKRISIS -// 1d00b BYZANTINE MUSICAL SYMBOL YPOKRISIS DIPLI -// 1d00c BYZANTINE MUSICAL SYMBOL KREMASTI -// 1d00d BYZANTINE MUSICAL SYMBOL APESO EKFONITIKON -// 1d00e BYZANTINE MUSICAL SYMBOL EXO EKFONITIKON -// 1d00f BYZANTINE MUSICAL SYMBOL TELEIA -// 1d010 BYZANTINE MUSICAL SYMBOL KENTIMATA -// 1d011 BYZANTINE MUSICAL SYMBOL APOSTROFOS -// 1d012 BYZANTINE MUSICAL SYMBOL APOSTROFOS DIPLI -// 1d013 BYZANTINE MUSICAL SYMBOL SYNEVMA -// 1d014 BYZANTINE MUSICAL SYMBOL THITA -// 1d015 BYZANTINE MUSICAL SYMBOL OLIGON ARCHAION -// 1d016 BYZANTINE MUSICAL SYMBOL GORGON ARCHAION -// 1d017 BYZANTINE MUSICAL SYMBOL PSILON -// 1d018 BYZANTINE MUSICAL SYMBOL CHAMILON -// 1d019 BYZANTINE MUSICAL SYMBOL VATHY -// 1d01a BYZANTINE MUSICAL SYMBOL ISON ARCHAION -// 1d01b BYZANTINE MUSICAL SYMBOL KENTIMA ARCHAION -// 1d01c BYZANTINE MUSICAL SYMBOL KENTIMATA ARCHAION -// 1d01d BYZANTINE MUSICAL SYMBOL SAXIMATA -// 1d01e BYZANTINE MUSICAL SYMBOL PARICHON -// 1d01f BYZANTINE MUSICAL SYMBOL STAVROS APODEXIA -// 1d020 BYZANTINE MUSICAL SYMBOL OXEIAI ARCHAION -// 1d021 BYZANTINE MUSICAL SYMBOL VAREIAI ARCHAION -// 1d022 BYZANTINE MUSICAL SYMBOL APODERMA ARCHAION -// 1d023 BYZANTINE MUSICAL SYMBOL APOTHEMA -// 1d024 BYZANTINE MUSICAL SYMBOL KLASMA -// 1d025 BYZANTINE MUSICAL SYMBOL REVMA -// 1d026 BYZANTINE MUSICAL SYMBOL PIASMA ARCHAION -// 1d027 BYZANTINE MUSICAL SYMBOL TINAGMA -// 1d028 BYZANTINE MUSICAL SYMBOL ANATRICHISMA -// 1d029 BYZANTINE MUSICAL SYMBOL SEISMA -// 1d02a BYZANTINE MUSICAL SYMBOL SYNAGMA ARCHAION -// 1d02b BYZANTINE MUSICAL SYMBOL SYNAGMA META STAVROU -// 1d02c BYZANTINE MUSICAL SYMBOL OYRANISMA ARCHAION -// 1d02d BYZANTINE MUSICAL SYMBOL THEMA -// 1d02e BYZANTINE MUSICAL SYMBOL LEMOI -// 1d02f BYZANTINE MUSICAL SYMBOL DYO -// 1d030 BYZANTINE MUSICAL SYMBOL TRIA -// 1d031 BYZANTINE MUSICAL SYMBOL TESSERA -// 1d032 BYZANTINE MUSICAL SYMBOL KRATIMATA -// 1d033 BYZANTINE MUSICAL SYMBOL APESO EXO NEO -// 1d034 BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION -// 1d035 BYZANTINE MUSICAL SYMBOL IMIFTHORA -// 1d036 BYZANTINE MUSICAL SYMBOL TROMIKON ARCHAION -// 1d037 BYZANTINE MUSICAL SYMBOL KATAVA TROMIKON -// 1d038 BYZANTINE MUSICAL SYMBOL PELASTON -// 1d039 BYZANTINE MUSICAL SYMBOL PSIFISTON -// 1d03a BYZANTINE MUSICAL SYMBOL KONTEVMA -// 1d03b BYZANTINE MUSICAL SYMBOL CHOREVMA ARCHAION -// 1d03c BYZANTINE MUSICAL SYMBOL RAPISMA -// 1d03d BYZANTINE MUSICAL SYMBOL PARAKALESMA ARCHAION -// 1d03e BYZANTINE MUSICAL SYMBOL PARAKLITIKI ARCHAION -// 1d03f BYZANTINE MUSICAL SYMBOL ICHADIN -// 1d040 BYZANTINE MUSICAL SYMBOL NANA -// 1d041 BYZANTINE MUSICAL SYMBOL PETASMA -// 1d042 BYZANTINE MUSICAL SYMBOL KONTEVMA ALLO -// 1d043 BYZANTINE MUSICAL SYMBOL TROMIKON ALLO -// 1d044 BYZANTINE MUSICAL SYMBOL STRAGGISMATA -// 1d045 BYZANTINE MUSICAL SYMBOL GRONTHISMATA -// 1d046 BYZANTINE MUSICAL SYMBOL ISON NEO -// 1d047 BYZANTINE MUSICAL SYMBOL OLIGON NEO -// 1d048 BYZANTINE MUSICAL SYMBOL OXEIA NEO -// 1d049 BYZANTINE MUSICAL SYMBOL PETASTI -// 1d04a BYZANTINE MUSICAL SYMBOL KOUFISMA -// 1d04b BYZANTINE MUSICAL SYMBOL PETASTOKOUFISMA -// 1d04c BYZANTINE MUSICAL SYMBOL KRATIMOKOUFISMA -// 1d04d BYZANTINE MUSICAL SYMBOL PELASTON NEO -// 1d04e BYZANTINE MUSICAL SYMBOL KENTIMATA NEO ANO -// 1d04f BYZANTINE MUSICAL SYMBOL KENTIMA NEO ANO -// 1d050 BYZANTINE MUSICAL SYMBOL YPSILI -// 1d051 BYZANTINE MUSICAL SYMBOL APOSTROFOS NEO -// 1d052 BYZANTINE MUSICAL SYMBOL APOSTROFOI SYNDESMOS NEO -// 1d053 BYZANTINE MUSICAL SYMBOL YPORROI -// 1d054 BYZANTINE MUSICAL SYMBOL KRATIMOYPORROON -// 1d055 BYZANTINE MUSICAL SYMBOL ELAFRON -// 1d056 BYZANTINE MUSICAL SYMBOL CHAMILI -// 1d057 BYZANTINE MUSICAL SYMBOL MIKRON ISON -// 1d058 BYZANTINE MUSICAL SYMBOL VAREIA NEO -// 1d059 BYZANTINE MUSICAL SYMBOL PIASMA NEO -// 1d05a BYZANTINE MUSICAL SYMBOL PSIFISTON NEO -// 1d05b BYZANTINE MUSICAL SYMBOL OMALON -// 1d05c BYZANTINE MUSICAL SYMBOL ANTIKENOMA -// 1d05d BYZANTINE MUSICAL SYMBOL LYGISMA -// 1d05e BYZANTINE MUSICAL SYMBOL PARAKLITIKI NEO -// 1d05f BYZANTINE MUSICAL SYMBOL PARAKALESMA NEO -// 1d060 BYZANTINE MUSICAL SYMBOL ETERON PARAKALESMA -// 1d061 BYZANTINE MUSICAL SYMBOL KYLISMA -// 1d062 BYZANTINE MUSICAL SYMBOL ANTIKENOKYLISMA -// 1d063 BYZANTINE MUSICAL SYMBOL TROMIKON NEO -// 1d064 BYZANTINE MUSICAL SYMBOL EKSTREPTON -// 1d065 BYZANTINE MUSICAL SYMBOL SYNAGMA NEO -// 1d066 BYZANTINE MUSICAL SYMBOL SYRMA -// 1d067 BYZANTINE MUSICAL SYMBOL CHOREVMA NEO -// 1d068 BYZANTINE MUSICAL SYMBOL EPEGERMA -// 1d069 BYZANTINE MUSICAL SYMBOL SEISMA NEO -// 1d06a BYZANTINE MUSICAL SYMBOL XIRON KLASMA -// 1d06b BYZANTINE MUSICAL SYMBOL TROMIKOPSIFISTON -// 1d06c BYZANTINE MUSICAL SYMBOL PSIFISTOLYGISMA -// 1d06d BYZANTINE MUSICAL SYMBOL TROMIKOLYGISMA -// 1d06e BYZANTINE MUSICAL SYMBOL TROMIKOPARAKALESMA -// 1d06f BYZANTINE MUSICAL SYMBOL PSIFISTOPARAKALESMA -// 1d070 BYZANTINE MUSICAL SYMBOL TROMIKOSYNAGMA -// 1d071 BYZANTINE MUSICAL SYMBOL PSIFISTOSYNAGMA -// 1d072 BYZANTINE MUSICAL SYMBOL GORGOSYNTHETON -// 1d073 BYZANTINE MUSICAL SYMBOL ARGOSYNTHETON -// 1d074 BYZANTINE MUSICAL SYMBOL ETERON ARGOSYNTHETON -// 1d075 BYZANTINE MUSICAL SYMBOL OYRANISMA NEO -// 1d076 BYZANTINE MUSICAL SYMBOL THEMATISMOS ESO -// 1d077 BYZANTINE MUSICAL SYMBOL THEMATISMOS EXO -// 1d078 BYZANTINE MUSICAL SYMBOL THEMA APLOUN -// 1d079 BYZANTINE MUSICAL SYMBOL THES KAI APOTHES -// 1d07a BYZANTINE MUSICAL SYMBOL KATAVASMA -// 1d07b BYZANTINE MUSICAL SYMBOL ENDOFONON -// 1d07c BYZANTINE MUSICAL SYMBOL YFEN KATO -// 1d07d BYZANTINE MUSICAL SYMBOL YFEN ANO -// 1d07e BYZANTINE MUSICAL SYMBOL STAVROS -// 1d07f BYZANTINE MUSICAL SYMBOL KLASMA ANO -// 1d080 BYZANTINE MUSICAL SYMBOL DIPLI ARCHAION -// 1d081 BYZANTINE MUSICAL SYMBOL KRATIMA ARCHAION -// 1d082 BYZANTINE MUSICAL SYMBOL KRATIMA ALLO -// 1d083 BYZANTINE MUSICAL SYMBOL KRATIMA NEO -// 1d084 BYZANTINE MUSICAL SYMBOL APODERMA NEO -// 1d085 BYZANTINE MUSICAL SYMBOL APLI -// 1d086 BYZANTINE MUSICAL SYMBOL DIPLI -// 1d087 BYZANTINE MUSICAL SYMBOL TRIPLI -// 1d088 BYZANTINE MUSICAL SYMBOL TETRAPLI -// 1d089 BYZANTINE MUSICAL SYMBOL KORONIS -// 1d08a BYZANTINE MUSICAL SYMBOL LEIMMA ENOS CHRONOU -// 1d08b BYZANTINE MUSICAL SYMBOL LEIMMA DYO CHRONON -// 1d08c BYZANTINE MUSICAL SYMBOL LEIMMA TRION CHRONON -// 1d08d BYZANTINE MUSICAL SYMBOL LEIMMA TESSARON CHRONON -// 1d08e BYZANTINE MUSICAL SYMBOL LEIMMA IMISEOS CHRONOU -// 1d08f BYZANTINE MUSICAL SYMBOL GORGON NEO ANO -// 1d090 BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON ARISTERA -// 1d091 BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON DEXIA -// 1d092 BYZANTINE MUSICAL SYMBOL DIGORGON -// 1d093 BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA KATO -// 1d094 BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA ANO -// 1d095 BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON DEXIA -// 1d096 BYZANTINE MUSICAL SYMBOL TRIGORGON -// 1d097 BYZANTINE MUSICAL SYMBOL ARGON -// 1d098 BYZANTINE MUSICAL SYMBOL IMIDIARGON -// 1d099 BYZANTINE MUSICAL SYMBOL DIARGON -// 1d09a BYZANTINE MUSICAL SYMBOL AGOGI POLI ARGI -// 1d09b BYZANTINE MUSICAL SYMBOL AGOGI ARGOTERI -// 1d09c BYZANTINE MUSICAL SYMBOL AGOGI ARGI -// 1d09d BYZANTINE MUSICAL SYMBOL AGOGI METRIA -// 1d09e BYZANTINE MUSICAL SYMBOL AGOGI MESI -// 1d09f BYZANTINE MUSICAL SYMBOL AGOGI GORGI -// 1d0a0 BYZANTINE MUSICAL SYMBOL AGOGI GORGOTERI -// 1d0a1 BYZANTINE MUSICAL SYMBOL AGOGI POLI GORGI -// 1d0a2 BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOS ICHOS -// 1d0a3 BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI PROTOS ICHOS -// 1d0a4 BYZANTINE MUSICAL SYMBOL MARTYRIA DEYTEROS ICHOS -// 1d0a5 BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI DEYTEROS ICHOS -// 1d0a6 BYZANTINE MUSICAL SYMBOL MARTYRIA TRITOS ICHOS -// 1d0a7 BYZANTINE MUSICAL SYMBOL MARTYRIA TRIFONIAS -// 1d0a8 BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS ICHOS -// 1d0a9 BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS LEGETOS ICHOS -// 1d0aa BYZANTINE MUSICAL SYMBOL MARTYRIA LEGETOS ICHOS -// 1d0ab BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS ICHOS -// 1d0ac BYZANTINE MUSICAL SYMBOL ISAKIA TELOUS ICHIMATOS -// 1d0ad BYZANTINE MUSICAL SYMBOL APOSTROFOI TELOUS ICHIMATOS -// 1d0ae BYZANTINE MUSICAL SYMBOL FANEROSIS TETRAFONIAS -// 1d0af BYZANTINE MUSICAL SYMBOL FANEROSIS MONOFONIAS -// 1d0b0 BYZANTINE MUSICAL SYMBOL FANEROSIS DIFONIAS -// 1d0b1 BYZANTINE MUSICAL SYMBOL MARTYRIA VARYS ICHOS -// 1d0b2 BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOVARYS ICHOS -// 1d0b3 BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS TETARTOS ICHOS -// 1d0b4 BYZANTINE MUSICAL SYMBOL GORTHMIKON N APLOUN -// 1d0b5 BYZANTINE MUSICAL SYMBOL GORTHMIKON N DIPLOUN -// 1d0b6 BYZANTINE MUSICAL SYMBOL ENARXIS KAI FTHORA VOU -// 1d0b7 BYZANTINE MUSICAL SYMBOL IMIFONON -// 1d0b8 BYZANTINE MUSICAL SYMBOL IMIFTHORON -// 1d0b9 BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION DEYTEROU ICHOU -// 1d0ba BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI PA -// 1d0bb BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NANA -// 1d0bc BYZANTINE MUSICAL SYMBOL FTHORA NAOS ICHOS -// 1d0bd BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI DI -// 1d0be BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON DIATONON DI -// 1d0bf BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI KE -// 1d0c0 BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI ZO -// 1d0c1 BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI KATO -// 1d0c2 BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI ANO -// 1d0c3 BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA DIFONIAS -// 1d0c4 BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA MONOFONIAS -// 1d0c5 BYZANTINE MUSICAL SYMBOL FHTORA SKLIRON CHROMA VASIS -// 1d0c6 BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON CHROMA SYNAFI -// 1d0c7 BYZANTINE MUSICAL SYMBOL FTHORA NENANO -// 1d0c8 BYZANTINE MUSICAL SYMBOL CHROA ZYGOS -// 1d0c9 BYZANTINE MUSICAL SYMBOL CHROA KLITON -// 1d0ca BYZANTINE MUSICAL SYMBOL CHROA SPATHI -// 1d0cb BYZANTINE MUSICAL SYMBOL FTHORA I YFESIS TETARTIMORION -// 1d0cc BYZANTINE MUSICAL SYMBOL FTHORA ENARMONIOS ANTIFONIA -// 1d0cd BYZANTINE MUSICAL SYMBOL YFESIS TRITIMORION -// 1d0ce BYZANTINE MUSICAL SYMBOL DIESIS TRITIMORION -// 1d0cf BYZANTINE MUSICAL SYMBOL DIESIS TETARTIMORION -// 1d0d0 BYZANTINE MUSICAL SYMBOL DIESIS APLI DYO DODEKATA -// 1d0d1 BYZANTINE MUSICAL SYMBOL DIESIS MONOGRAMMOS TESSERA DODEKATA -// 1d0d2 BYZANTINE MUSICAL SYMBOL DIESIS DIGRAMMOS EX DODEKATA -// 1d0d3 BYZANTINE MUSICAL SYMBOL DIESIS TRIGRAMMOS OKTO DODEKATA -// 1d0d4 BYZANTINE MUSICAL SYMBOL YFESIS APLI DYO DODEKATA -// 1d0d5 BYZANTINE MUSICAL SYMBOL YFESIS MONOGRAMMOS TESSERA DODEKATA -// 1d0d6 BYZANTINE MUSICAL SYMBOL YFESIS DIGRAMMOS EX DODEKATA -// 1d0d7 BYZANTINE MUSICAL SYMBOL YFESIS TRIGRAMMOS OKTO DODEKATA -// 1d0d8 BYZANTINE MUSICAL SYMBOL GENIKI DIESIS -// 1d0d9 BYZANTINE MUSICAL SYMBOL GENIKI YFESIS -// 1d0da BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MIKRI -// 1d0db BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MEGALI -// 1d0dc BYZANTINE MUSICAL SYMBOL DIASTOLI DIPLI -// 1d0dd BYZANTINE MUSICAL SYMBOL DIASTOLI THESEOS -// 1d0de BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS -// 1d0df BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS DISIMOU -// 1d0e0 BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TRISIMOU -// 1d0e1 BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TETRASIMOU -// 1d0e2 BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS -// 1d0e3 BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS DISIMOU -// 1d0e4 BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TRISIMOU -// 1d0e5 BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TETRASIMOU -// 1d0e6 BYZANTINE MUSICAL SYMBOL DIGRAMMA GG -// 1d0e7 BYZANTINE MUSICAL SYMBOL DIFTOGGOS OU -// 1d0e8 BYZANTINE MUSICAL SYMBOL STIGMA -// 1d0e9 BYZANTINE MUSICAL SYMBOL ARKTIKO PA -// 1d0ea BYZANTINE MUSICAL SYMBOL ARKTIKO VOU -// 1d0eb BYZANTINE MUSICAL SYMBOL ARKTIKO GA -// 1d0ec BYZANTINE MUSICAL SYMBOL ARKTIKO DI -// 1d0ed BYZANTINE MUSICAL SYMBOL ARKTIKO KE -// 1d0ee BYZANTINE MUSICAL SYMBOL ARKTIKO ZO -// 1d0ef BYZANTINE MUSICAL SYMBOL ARKTIKO NI -// 1d0f0 BYZANTINE MUSICAL SYMBOL KENTIMATA NEO MESO -// 1d0f1 BYZANTINE MUSICAL SYMBOL KENTIMA NEO MESO -// 1d0f2 BYZANTINE MUSICAL SYMBOL KENTIMATA NEO KATO -// 1d0f3 BYZANTINE MUSICAL SYMBOL KENTIMA NEO KATO -// 1d0f4 BYZANTINE MUSICAL SYMBOL KLASMA KATO -// 1d0f5 BYZANTINE MUSICAL SYMBOL GORGON NEO KATO - { 0x1D000, 0xF6, 0x8, 0, 0 }, -// 1d100 MUSICAL SYMBOL SINGLE BARLINE -// 1d101 MUSICAL SYMBOL DOUBLE BARLINE -// 1d102 MUSICAL SYMBOL FINAL BARLINE -// 1d103 MUSICAL SYMBOL REVERSE FINAL BARLINE -// 1d104 MUSICAL SYMBOL DASHED BARLINE -// 1d105 MUSICAL SYMBOL SHORT BARLINE -// 1d106 MUSICAL SYMBOL LEFT REPEAT SIGN -// 1d107 MUSICAL SYMBOL RIGHT REPEAT SIGN -// 1d108 MUSICAL SYMBOL REPEAT DOTS -// 1d109 MUSICAL SYMBOL DAL SEGNO -// 1d10a MUSICAL SYMBOL DA CAPO -// 1d10b MUSICAL SYMBOL SEGNO -// 1d10c MUSICAL SYMBOL CODA -// 1d10d MUSICAL SYMBOL REPEATED FIGURE-1 -// 1d10e MUSICAL SYMBOL REPEATED FIGURE-2 -// 1d10f MUSICAL SYMBOL REPEATED FIGURE-3 -// 1d110 MUSICAL SYMBOL FERMATA -// 1d111 MUSICAL SYMBOL FERMATA BELOW -// 1d112 MUSICAL SYMBOL BREATH MARK -// 1d113 MUSICAL SYMBOL CAESURA -// 1d114 MUSICAL SYMBOL BRACE -// 1d115 MUSICAL SYMBOL BRACKET -// 1d116 MUSICAL SYMBOL ONE-LINE STAFF -// 1d117 MUSICAL SYMBOL TWO-LINE STAFF -// 1d118 MUSICAL SYMBOL THREE-LINE STAFF -// 1d119 MUSICAL SYMBOL FOUR-LINE STAFF -// 1d11a MUSICAL SYMBOL FIVE-LINE STAFF -// 1d11b MUSICAL SYMBOL SIX-LINE STAFF -// 1d11c MUSICAL SYMBOL SIX-STRING FRETBOARD -// 1d11d MUSICAL SYMBOL FOUR-STRING FRETBOARD -// 1d11e MUSICAL SYMBOL G CLEF -// 1d11f MUSICAL SYMBOL G CLEF OTTAVA ALTA -// 1d120 MUSICAL SYMBOL G CLEF OTTAVA BASSA -// 1d121 MUSICAL SYMBOL C CLEF -// 1d122 MUSICAL SYMBOL F CLEF -// 1d123 MUSICAL SYMBOL F CLEF OTTAVA ALTA -// 1d124 MUSICAL SYMBOL F CLEF OTTAVA BASSA -// 1d125 MUSICAL SYMBOL DRUM CLEF-1 -// 1d126 MUSICAL SYMBOL DRUM CLEF-2 - { 0x1D100, 0x27, 0x8, 0, 0 }, -// 1d129 MUSICAL SYMBOL MULTIPLE MEASURE REST -// 1d12a MUSICAL SYMBOL DOUBLE SHARP -// 1d12b MUSICAL SYMBOL DOUBLE FLAT -// 1d12c MUSICAL SYMBOL FLAT UP -// 1d12d MUSICAL SYMBOL FLAT DOWN -// 1d12e MUSICAL SYMBOL NATURAL UP -// 1d12f MUSICAL SYMBOL NATURAL DOWN -// 1d130 MUSICAL SYMBOL SHARP UP -// 1d131 MUSICAL SYMBOL SHARP DOWN -// 1d132 MUSICAL SYMBOL QUARTER TONE SHARP -// 1d133 MUSICAL SYMBOL QUARTER TONE FLAT -// 1d134 MUSICAL SYMBOL COMMON TIME -// 1d135 MUSICAL SYMBOL CUT TIME -// 1d136 MUSICAL SYMBOL OTTAVA ALTA -// 1d137 MUSICAL SYMBOL OTTAVA BASSA -// 1d138 MUSICAL SYMBOL QUINDICESIMA ALTA -// 1d139 MUSICAL SYMBOL QUINDICESIMA BASSA -// 1d13a MUSICAL SYMBOL MULTI REST -// 1d13b MUSICAL SYMBOL WHOLE REST -// 1d13c MUSICAL SYMBOL HALF REST -// 1d13d MUSICAL SYMBOL QUARTER REST -// 1d13e MUSICAL SYMBOL EIGHTH REST -// 1d13f MUSICAL SYMBOL SIXTEENTH REST -// 1d140 MUSICAL SYMBOL THIRTY-SECOND REST -// 1d141 MUSICAL SYMBOL SIXTY-FOURTH REST -// 1d142 MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH REST -// 1d143 MUSICAL SYMBOL X NOTEHEAD -// 1d144 MUSICAL SYMBOL PLUS NOTEHEAD -// 1d145 MUSICAL SYMBOL CIRCLE X NOTEHEAD -// 1d146 MUSICAL SYMBOL SQUARE NOTEHEAD WHITE -// 1d147 MUSICAL SYMBOL SQUARE NOTEHEAD BLACK -// 1d148 MUSICAL SYMBOL TRIANGLE NOTEHEAD UP WHITE -// 1d149 MUSICAL SYMBOL TRIANGLE NOTEHEAD UP BLACK -// 1d14a MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT WHITE -// 1d14b MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT BLACK -// 1d14c MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT WHITE -// 1d14d MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT BLACK -// 1d14e MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN WHITE -// 1d14f MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN BLACK -// 1d150 MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT WHITE -// 1d151 MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT BLACK -// 1d152 MUSICAL SYMBOL MOON NOTEHEAD WHITE -// 1d153 MUSICAL SYMBOL MOON NOTEHEAD BLACK -// 1d154 MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN WHITE -// 1d155 MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN BLACK -// 1d156 MUSICAL SYMBOL PARENTHESIS NOTEHEAD -// 1d157 MUSICAL SYMBOL VOID NOTEHEAD -// 1d158 MUSICAL SYMBOL NOTEHEAD BLACK -// 1d159 MUSICAL SYMBOL NULL NOTEHEAD -// 1d15a MUSICAL SYMBOL CLUSTER NOTEHEAD WHITE -// 1d15b MUSICAL SYMBOL CLUSTER NOTEHEAD BLACK -// 1d15c MUSICAL SYMBOL BREVE -// 1d15d MUSICAL SYMBOL WHOLE NOTE -// 1d15e MUSICAL SYMBOL HALF NOTE -// 1d15f MUSICAL SYMBOL QUARTER NOTE -// 1d160 MUSICAL SYMBOL EIGHTH NOTE -// 1d161 MUSICAL SYMBOL SIXTEENTH NOTE -// 1d162 MUSICAL SYMBOL THIRTY-SECOND NOTE -// 1d163 MUSICAL SYMBOL SIXTY-FOURTH NOTE -// 1d164 MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE - { 0x1D129, 0x3C, 0x8, 0, 0 }, -// 1d165 MUSICAL SYMBOL COMBINING STEM -// 1d166 MUSICAL SYMBOL COMBINING SPRECHGESANG STEM -// 1d167 MUSICAL SYMBOL COMBINING TREMOLO-1 -// 1d168 MUSICAL SYMBOL COMBINING TREMOLO-2 -// 1d169 MUSICAL SYMBOL COMBINING TREMOLO-3 - { 0x1D165, 0x5, 0x0, 0, 0 }, -// 1d16a MUSICAL SYMBOL FINGERED TREMOLO-1 -// 1d16b MUSICAL SYMBOL FINGERED TREMOLO-2 -// 1d16c MUSICAL SYMBOL FINGERED TREMOLO-3 - { 0x1D16A, 0x3, 0x8, 0, 0 }, -// 1d16d MUSICAL SYMBOL COMBINING AUGMENTATION DOT -// 1d16e MUSICAL SYMBOL COMBINING FLAG-1 -// 1d16f MUSICAL SYMBOL COMBINING FLAG-2 -// 1d170 MUSICAL SYMBOL COMBINING FLAG-3 -// 1d171 MUSICAL SYMBOL COMBINING FLAG-4 -// 1d172 MUSICAL SYMBOL COMBINING FLAG-5 -// 1d173 MUSICAL SYMBOL BEGIN BEAM -// 1d174 MUSICAL SYMBOL END BEAM -// 1d175 MUSICAL SYMBOL BEGIN TIE -// 1d176 MUSICAL SYMBOL END TIE -// 1d177 MUSICAL SYMBOL BEGIN SLUR -// 1d178 MUSICAL SYMBOL END SLUR -// 1d179 MUSICAL SYMBOL BEGIN PHRASE -// 1d17a MUSICAL SYMBOL END PHRASE -// 1d17b MUSICAL SYMBOL COMBINING ACCENT -// 1d17c MUSICAL SYMBOL COMBINING STACCATO -// 1d17d MUSICAL SYMBOL COMBINING TENUTO -// 1d17e MUSICAL SYMBOL COMBINING STACCATISSIMO -// 1d17f MUSICAL SYMBOL COMBINING MARCATO -// 1d180 MUSICAL SYMBOL COMBINING MARCATO-STACCATO -// 1d181 MUSICAL SYMBOL COMBINING ACCENT-STACCATO -// 1d182 MUSICAL SYMBOL COMBINING LOURE - { 0x1D16D, 0x16, 0x0, 0, 0 }, -// 1d183 MUSICAL SYMBOL ARPEGGIATO UP -// 1d184 MUSICAL SYMBOL ARPEGGIATO DOWN - { 0x1D183, 0x2, 0x8, 0, 0 }, -// 1d185 MUSICAL SYMBOL COMBINING DOIT -// 1d186 MUSICAL SYMBOL COMBINING RIP -// 1d187 MUSICAL SYMBOL COMBINING FLIP -// 1d188 MUSICAL SYMBOL COMBINING SMEAR -// 1d189 MUSICAL SYMBOL COMBINING BEND -// 1d18a MUSICAL SYMBOL COMBINING DOUBLE TONGUE -// 1d18b MUSICAL SYMBOL COMBINING TRIPLE TONGUE - { 0x1D185, 0x7, 0x0, 0, 0 }, -// 1d18c MUSICAL SYMBOL RINFORZANDO -// 1d18d MUSICAL SYMBOL SUBITO -// 1d18e MUSICAL SYMBOL Z -// 1d18f MUSICAL SYMBOL PIANO -// 1d190 MUSICAL SYMBOL MEZZO -// 1d191 MUSICAL SYMBOL FORTE -// 1d192 MUSICAL SYMBOL CRESCENDO -// 1d193 MUSICAL SYMBOL DECRESCENDO -// 1d194 MUSICAL SYMBOL GRACE NOTE SLASH -// 1d195 MUSICAL SYMBOL GRACE NOTE NO SLASH -// 1d196 MUSICAL SYMBOL TR -// 1d197 MUSICAL SYMBOL TURN -// 1d198 MUSICAL SYMBOL INVERTED TURN -// 1d199 MUSICAL SYMBOL TURN SLASH -// 1d19a MUSICAL SYMBOL TURN UP -// 1d19b MUSICAL SYMBOL ORNAMENT STROKE-1 -// 1d19c MUSICAL SYMBOL ORNAMENT STROKE-2 -// 1d19d MUSICAL SYMBOL ORNAMENT STROKE-3 -// 1d19e MUSICAL SYMBOL ORNAMENT STROKE-4 -// 1d19f MUSICAL SYMBOL ORNAMENT STROKE-5 -// 1d1a0 MUSICAL SYMBOL ORNAMENT STROKE-6 -// 1d1a1 MUSICAL SYMBOL ORNAMENT STROKE-7 -// 1d1a2 MUSICAL SYMBOL ORNAMENT STROKE-8 -// 1d1a3 MUSICAL SYMBOL ORNAMENT STROKE-9 -// 1d1a4 MUSICAL SYMBOL ORNAMENT STROKE-10 -// 1d1a5 MUSICAL SYMBOL ORNAMENT STROKE-11 -// 1d1a6 MUSICAL SYMBOL HAUPTSTIMME -// 1d1a7 MUSICAL SYMBOL NEBENSTIMME -// 1d1a8 MUSICAL SYMBOL END OF STIMME -// 1d1a9 MUSICAL SYMBOL DEGREE SLASH - { 0x1D18C, 0x1E, 0x8, 0, 0 }, -// 1d1aa MUSICAL SYMBOL COMBINING DOWN BOW -// 1d1ab MUSICAL SYMBOL COMBINING UP BOW -// 1d1ac MUSICAL SYMBOL COMBINING HARMONIC -// 1d1ad MUSICAL SYMBOL COMBINING SNAP PIZZICATO - { 0x1D1AA, 0x4, 0x0, 0, 0 }, -// 1d1ae MUSICAL SYMBOL PEDAL MARK -// 1d1af MUSICAL SYMBOL PEDAL UP MARK -// 1d1b0 MUSICAL SYMBOL HALF PEDAL MARK -// 1d1b1 MUSICAL SYMBOL GLISSANDO UP -// 1d1b2 MUSICAL SYMBOL GLISSANDO DOWN -// 1d1b3 MUSICAL SYMBOL WITH FINGERNAILS -// 1d1b4 MUSICAL SYMBOL DAMP -// 1d1b5 MUSICAL SYMBOL DAMP ALL -// 1d1b6 MUSICAL SYMBOL MAXIMA -// 1d1b7 MUSICAL SYMBOL LONGA -// 1d1b8 MUSICAL SYMBOL BREVIS -// 1d1b9 MUSICAL SYMBOL SEMIBREVIS WHITE -// 1d1ba MUSICAL SYMBOL SEMIBREVIS BLACK -// 1d1bb MUSICAL SYMBOL MINIMA -// 1d1bc MUSICAL SYMBOL MINIMA BLACK -// 1d1bd MUSICAL SYMBOL SEMIMINIMA WHITE -// 1d1be MUSICAL SYMBOL SEMIMINIMA BLACK -// 1d1bf MUSICAL SYMBOL FUSA WHITE -// 1d1c0 MUSICAL SYMBOL FUSA BLACK -// 1d1c1 MUSICAL SYMBOL LONGA PERFECTA REST -// 1d1c2 MUSICAL SYMBOL LONGA IMPERFECTA REST -// 1d1c3 MUSICAL SYMBOL BREVIS REST -// 1d1c4 MUSICAL SYMBOL SEMIBREVIS REST -// 1d1c5 MUSICAL SYMBOL MINIMA REST -// 1d1c6 MUSICAL SYMBOL SEMIMINIMA REST -// 1d1c7 MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA -// 1d1c8 MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE IMPERFECTA -// 1d1c9 MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA DIMINUTION-1 -// 1d1ca MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE PERFECTA -// 1d1cb MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA -// 1d1cc MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-1 -// 1d1cd MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-2 -// 1d1ce MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-3 -// 1d1cf MUSICAL SYMBOL CROIX -// 1d1d0 MUSICAL SYMBOL GREGORIAN C CLEF -// 1d1d1 MUSICAL SYMBOL GREGORIAN F CLEF -// 1d1d2 MUSICAL SYMBOL SQUARE B -// 1d1d3 MUSICAL SYMBOL VIRGA -// 1d1d4 MUSICAL SYMBOL PODATUS -// 1d1d5 MUSICAL SYMBOL CLIVIS -// 1d1d6 MUSICAL SYMBOL SCANDICUS -// 1d1d7 MUSICAL SYMBOL CLIMACUS -// 1d1d8 MUSICAL SYMBOL TORCULUS -// 1d1d9 MUSICAL SYMBOL PORRECTUS -// 1d1da MUSICAL SYMBOL PORRECTUS FLEXUS -// 1d1db MUSICAL SYMBOL SCANDICUS FLEXUS -// 1d1dc MUSICAL SYMBOL TORCULUS RESUPINUS -// 1d1dd MUSICAL SYMBOL PES SUBPUNCTIS - { 0x1D1AE, 0x30, 0x8, 0, 0 }, -// 1d200 GREEK VOCAL NOTATION SYMBOL-1 -// 1d201 GREEK VOCAL NOTATION SYMBOL-2 -// 1d202 GREEK VOCAL NOTATION SYMBOL-3 -// 1d203 GREEK VOCAL NOTATION SYMBOL-4 -// 1d204 GREEK VOCAL NOTATION SYMBOL-5 -// 1d205 GREEK VOCAL NOTATION SYMBOL-6 -// 1d206 GREEK VOCAL NOTATION SYMBOL-7 -// 1d207 GREEK VOCAL NOTATION SYMBOL-8 -// 1d208 GREEK VOCAL NOTATION SYMBOL-9 -// 1d209 GREEK VOCAL NOTATION SYMBOL-10 -// 1d20a GREEK VOCAL NOTATION SYMBOL-11 -// 1d20b GREEK VOCAL NOTATION SYMBOL-12 -// 1d20c GREEK VOCAL NOTATION SYMBOL-13 -// 1d20d GREEK VOCAL NOTATION SYMBOL-14 -// 1d20e GREEK VOCAL NOTATION SYMBOL-15 -// 1d20f GREEK VOCAL NOTATION SYMBOL-16 -// 1d210 GREEK VOCAL NOTATION SYMBOL-17 -// 1d211 GREEK VOCAL NOTATION SYMBOL-18 -// 1d212 GREEK VOCAL NOTATION SYMBOL-19 -// 1d213 GREEK VOCAL NOTATION SYMBOL-20 -// 1d214 GREEK VOCAL NOTATION SYMBOL-21 -// 1d215 GREEK VOCAL NOTATION SYMBOL-22 -// 1d216 GREEK VOCAL NOTATION SYMBOL-23 -// 1d217 GREEK VOCAL NOTATION SYMBOL-24 -// 1d218 GREEK VOCAL NOTATION SYMBOL-50 -// 1d219 GREEK VOCAL NOTATION SYMBOL-51 -// 1d21a GREEK VOCAL NOTATION SYMBOL-52 -// 1d21b GREEK VOCAL NOTATION SYMBOL-53 -// 1d21c GREEK VOCAL NOTATION SYMBOL-54 -// 1d21d GREEK INSTRUMENTAL NOTATION SYMBOL-1 -// 1d21e GREEK INSTRUMENTAL NOTATION SYMBOL-2 -// 1d21f GREEK INSTRUMENTAL NOTATION SYMBOL-4 -// 1d220 GREEK INSTRUMENTAL NOTATION SYMBOL-5 -// 1d221 GREEK INSTRUMENTAL NOTATION SYMBOL-7 -// 1d222 GREEK INSTRUMENTAL NOTATION SYMBOL-8 -// 1d223 GREEK INSTRUMENTAL NOTATION SYMBOL-11 -// 1d224 GREEK INSTRUMENTAL NOTATION SYMBOL-12 -// 1d225 GREEK INSTRUMENTAL NOTATION SYMBOL-13 -// 1d226 GREEK INSTRUMENTAL NOTATION SYMBOL-14 -// 1d227 GREEK INSTRUMENTAL NOTATION SYMBOL-17 -// 1d228 GREEK INSTRUMENTAL NOTATION SYMBOL-18 -// 1d229 GREEK INSTRUMENTAL NOTATION SYMBOL-19 -// 1d22a GREEK INSTRUMENTAL NOTATION SYMBOL-23 -// 1d22b GREEK INSTRUMENTAL NOTATION SYMBOL-24 -// 1d22c GREEK INSTRUMENTAL NOTATION SYMBOL-25 -// 1d22d GREEK INSTRUMENTAL NOTATION SYMBOL-26 -// 1d22e GREEK INSTRUMENTAL NOTATION SYMBOL-27 -// 1d22f GREEK INSTRUMENTAL NOTATION SYMBOL-29 -// 1d230 GREEK INSTRUMENTAL NOTATION SYMBOL-30 -// 1d231 GREEK INSTRUMENTAL NOTATION SYMBOL-32 -// 1d232 GREEK INSTRUMENTAL NOTATION SYMBOL-36 -// 1d233 GREEK INSTRUMENTAL NOTATION SYMBOL-37 -// 1d234 GREEK INSTRUMENTAL NOTATION SYMBOL-38 -// 1d235 GREEK INSTRUMENTAL NOTATION SYMBOL-39 -// 1d236 GREEK INSTRUMENTAL NOTATION SYMBOL-40 -// 1d237 GREEK INSTRUMENTAL NOTATION SYMBOL-42 -// 1d238 GREEK INSTRUMENTAL NOTATION SYMBOL-43 -// 1d239 GREEK INSTRUMENTAL NOTATION SYMBOL-45 -// 1d23a GREEK INSTRUMENTAL NOTATION SYMBOL-47 -// 1d23b GREEK INSTRUMENTAL NOTATION SYMBOL-48 -// 1d23c GREEK INSTRUMENTAL NOTATION SYMBOL-49 -// 1d23d GREEK INSTRUMENTAL NOTATION SYMBOL-50 -// 1d23e GREEK INSTRUMENTAL NOTATION SYMBOL-51 -// 1d23f GREEK INSTRUMENTAL NOTATION SYMBOL-52 -// 1d240 GREEK INSTRUMENTAL NOTATION SYMBOL-53 -// 1d241 GREEK INSTRUMENTAL NOTATION SYMBOL-54 - { 0x1D200, 0x42, 0x8, 0, 0 }, -// 1d242 COMBINING GREEK MUSICAL TRISEME -// 1d243 COMBINING GREEK MUSICAL TETRASEME -// 1d244 COMBINING GREEK MUSICAL PENTASEME - { 0x1D242, 0x3, 0x0, 0, 0 }, -// 1d245 GREEK MUSICAL LEIMMA - { 0x1D245, 0x1, 0x8, 0, 0 }, -// 1d300 MONOGRAM FOR EARTH -// 1d301 DIGRAM FOR HEAVENLY EARTH -// 1d302 DIGRAM FOR HUMAN EARTH -// 1d303 DIGRAM FOR EARTHLY HEAVEN -// 1d304 DIGRAM FOR EARTHLY HUMAN -// 1d305 DIGRAM FOR EARTH -// 1d306 TETRAGRAM FOR CENTRE -// 1d307 TETRAGRAM FOR FULL CIRCLE -// 1d308 TETRAGRAM FOR MIRED -// 1d309 TETRAGRAM FOR BARRIER -// 1d30a TETRAGRAM FOR KEEPING SMALL -// 1d30b TETRAGRAM FOR CONTRARIETY -// 1d30c TETRAGRAM FOR ASCENT -// 1d30d TETRAGRAM FOR OPPOSITION -// 1d30e TETRAGRAM FOR BRANCHING OUT -// 1d30f TETRAGRAM FOR DEFECTIVENESS OR DISTORTION -// 1d310 TETRAGRAM FOR DIVERGENCE -// 1d311 TETRAGRAM FOR YOUTHFULNESS -// 1d312 TETRAGRAM FOR INCREASE -// 1d313 TETRAGRAM FOR PENETRATION -// 1d314 TETRAGRAM FOR REACH -// 1d315 TETRAGRAM FOR CONTACT -// 1d316 TETRAGRAM FOR HOLDING BACK -// 1d317 TETRAGRAM FOR WAITING -// 1d318 TETRAGRAM FOR FOLLOWING -// 1d319 TETRAGRAM FOR ADVANCE -// 1d31a TETRAGRAM FOR RELEASE -// 1d31b TETRAGRAM FOR RESISTANCE -// 1d31c TETRAGRAM FOR EASE -// 1d31d TETRAGRAM FOR JOY -// 1d31e TETRAGRAM FOR CONTENTION -// 1d31f TETRAGRAM FOR ENDEAVOUR -// 1d320 TETRAGRAM FOR DUTIES -// 1d321 TETRAGRAM FOR CHANGE -// 1d322 TETRAGRAM FOR DECISIVENESS -// 1d323 TETRAGRAM FOR BOLD RESOLUTION -// 1d324 TETRAGRAM FOR PACKING -// 1d325 TETRAGRAM FOR LEGION -// 1d326 TETRAGRAM FOR CLOSENESS -// 1d327 TETRAGRAM FOR KINSHIP -// 1d328 TETRAGRAM FOR GATHERING -// 1d329 TETRAGRAM FOR STRENGTH -// 1d32a TETRAGRAM FOR PURITY -// 1d32b TETRAGRAM FOR FULLNESS -// 1d32c TETRAGRAM FOR RESIDENCE -// 1d32d TETRAGRAM FOR LAW OR MODEL -// 1d32e TETRAGRAM FOR RESPONSE -// 1d32f TETRAGRAM FOR GOING TO MEET -// 1d330 TETRAGRAM FOR ENCOUNTERS -// 1d331 TETRAGRAM FOR STOVE -// 1d332 TETRAGRAM FOR GREATNESS -// 1d333 TETRAGRAM FOR ENLARGEMENT -// 1d334 TETRAGRAM FOR PATTERN -// 1d335 TETRAGRAM FOR RITUAL -// 1d336 TETRAGRAM FOR FLIGHT -// 1d337 TETRAGRAM FOR VASTNESS OR WASTING -// 1d338 TETRAGRAM FOR CONSTANCY -// 1d339 TETRAGRAM FOR MEASURE -// 1d33a TETRAGRAM FOR ETERNITY -// 1d33b TETRAGRAM FOR UNITY -// 1d33c TETRAGRAM FOR DIMINISHMENT -// 1d33d TETRAGRAM FOR CLOSED MOUTH -// 1d33e TETRAGRAM FOR GUARDEDNESS -// 1d33f TETRAGRAM FOR GATHERING IN -// 1d340 TETRAGRAM FOR MASSING -// 1d341 TETRAGRAM FOR ACCUMULATION -// 1d342 TETRAGRAM FOR EMBELLISHMENT -// 1d343 TETRAGRAM FOR DOUBT -// 1d344 TETRAGRAM FOR WATCH -// 1d345 TETRAGRAM FOR SINKING -// 1d346 TETRAGRAM FOR INNER -// 1d347 TETRAGRAM FOR DEPARTURE -// 1d348 TETRAGRAM FOR DARKENING -// 1d349 TETRAGRAM FOR DIMMING -// 1d34a TETRAGRAM FOR EXHAUSTION -// 1d34b TETRAGRAM FOR SEVERANCE -// 1d34c TETRAGRAM FOR STOPPAGE -// 1d34d TETRAGRAM FOR HARDNESS -// 1d34e TETRAGRAM FOR COMPLETION -// 1d34f TETRAGRAM FOR CLOSURE -// 1d350 TETRAGRAM FOR FAILURE -// 1d351 TETRAGRAM FOR AGGRAVATION -// 1d352 TETRAGRAM FOR COMPLIANCE -// 1d353 TETRAGRAM FOR ON THE VERGE -// 1d354 TETRAGRAM FOR DIFFICULTIES -// 1d355 TETRAGRAM FOR LABOURING -// 1d356 TETRAGRAM FOR FOSTERING - { 0x1D300, 0x57, 0x8, 0, 0 }, -// 1d360 COUNTING ROD UNIT DIGIT ONE -// 1d361 COUNTING ROD UNIT DIGIT TWO -// 1d362 COUNTING ROD UNIT DIGIT THREE -// 1d363 COUNTING ROD UNIT DIGIT FOUR -// 1d364 COUNTING ROD UNIT DIGIT FIVE -// 1d365 COUNTING ROD UNIT DIGIT SIX -// 1d366 COUNTING ROD UNIT DIGIT SEVEN -// 1d367 COUNTING ROD UNIT DIGIT EIGHT -// 1d368 COUNTING ROD UNIT DIGIT NINE -// 1d369 COUNTING ROD TENS DIGIT ONE -// 1d36a COUNTING ROD TENS DIGIT TWO -// 1d36b COUNTING ROD TENS DIGIT THREE -// 1d36c COUNTING ROD TENS DIGIT FOUR -// 1d36d COUNTING ROD TENS DIGIT FIVE -// 1d36e COUNTING ROD TENS DIGIT SIX -// 1d36f COUNTING ROD TENS DIGIT SEVEN -// 1d370 COUNTING ROD TENS DIGIT EIGHT -// 1d371 COUNTING ROD TENS DIGIT NINE - { 0x1D360, 0x12, 0x8, 0, 0 }, -// 1d400 MATHEMATICAL BOLD CAPITAL A -// 1d401 MATHEMATICAL BOLD CAPITAL B -// 1d402 MATHEMATICAL BOLD CAPITAL C -// 1d403 MATHEMATICAL BOLD CAPITAL D -// 1d404 MATHEMATICAL BOLD CAPITAL E -// 1d405 MATHEMATICAL BOLD CAPITAL F -// 1d406 MATHEMATICAL BOLD CAPITAL G -// 1d407 MATHEMATICAL BOLD CAPITAL H -// 1d408 MATHEMATICAL BOLD CAPITAL I -// 1d409 MATHEMATICAL BOLD CAPITAL J -// 1d40a MATHEMATICAL BOLD CAPITAL K -// 1d40b MATHEMATICAL BOLD CAPITAL L -// 1d40c MATHEMATICAL BOLD CAPITAL M -// 1d40d MATHEMATICAL BOLD CAPITAL N -// 1d40e MATHEMATICAL BOLD CAPITAL O -// 1d40f MATHEMATICAL BOLD CAPITAL P -// 1d410 MATHEMATICAL BOLD CAPITAL Q -// 1d411 MATHEMATICAL BOLD CAPITAL R -// 1d412 MATHEMATICAL BOLD CAPITAL S -// 1d413 MATHEMATICAL BOLD CAPITAL T -// 1d414 MATHEMATICAL BOLD CAPITAL U -// 1d415 MATHEMATICAL BOLD CAPITAL V -// 1d416 MATHEMATICAL BOLD CAPITAL W -// 1d417 MATHEMATICAL BOLD CAPITAL X -// 1d418 MATHEMATICAL BOLD CAPITAL Y -// 1d419 MATHEMATICAL BOLD CAPITAL Z - { 0x1D400, 0x1A, 0x89, 0, 0 }, -// 1d41a MATHEMATICAL BOLD SMALL A -// 1d41b MATHEMATICAL BOLD SMALL B -// 1d41c MATHEMATICAL BOLD SMALL C -// 1d41d MATHEMATICAL BOLD SMALL D -// 1d41e MATHEMATICAL BOLD SMALL E -// 1d41f MATHEMATICAL BOLD SMALL F -// 1d420 MATHEMATICAL BOLD SMALL G -// 1d421 MATHEMATICAL BOLD SMALL H -// 1d422 MATHEMATICAL BOLD SMALL I -// 1d423 MATHEMATICAL BOLD SMALL J -// 1d424 MATHEMATICAL BOLD SMALL K -// 1d425 MATHEMATICAL BOLD SMALL L -// 1d426 MATHEMATICAL BOLD SMALL M -// 1d427 MATHEMATICAL BOLD SMALL N -// 1d428 MATHEMATICAL BOLD SMALL O -// 1d429 MATHEMATICAL BOLD SMALL P -// 1d42a MATHEMATICAL BOLD SMALL Q -// 1d42b MATHEMATICAL BOLD SMALL R -// 1d42c MATHEMATICAL BOLD SMALL S -// 1d42d MATHEMATICAL BOLD SMALL T -// 1d42e MATHEMATICAL BOLD SMALL U -// 1d42f MATHEMATICAL BOLD SMALL V -// 1d430 MATHEMATICAL BOLD SMALL W -// 1d431 MATHEMATICAL BOLD SMALL X -// 1d432 MATHEMATICAL BOLD SMALL Y -// 1d433 MATHEMATICAL BOLD SMALL Z - { 0x1D41A, 0x1A, 0x49, 0, 0 }, -// 1d434 MATHEMATICAL ITALIC CAPITAL A -// 1d435 MATHEMATICAL ITALIC CAPITAL B -// 1d436 MATHEMATICAL ITALIC CAPITAL C -// 1d437 MATHEMATICAL ITALIC CAPITAL D -// 1d438 MATHEMATICAL ITALIC CAPITAL E -// 1d439 MATHEMATICAL ITALIC CAPITAL F -// 1d43a MATHEMATICAL ITALIC CAPITAL G -// 1d43b MATHEMATICAL ITALIC CAPITAL H -// 1d43c MATHEMATICAL ITALIC CAPITAL I -// 1d43d MATHEMATICAL ITALIC CAPITAL J -// 1d43e MATHEMATICAL ITALIC CAPITAL K -// 1d43f MATHEMATICAL ITALIC CAPITAL L -// 1d440 MATHEMATICAL ITALIC CAPITAL M -// 1d441 MATHEMATICAL ITALIC CAPITAL N -// 1d442 MATHEMATICAL ITALIC CAPITAL O -// 1d443 MATHEMATICAL ITALIC CAPITAL P -// 1d444 MATHEMATICAL ITALIC CAPITAL Q -// 1d445 MATHEMATICAL ITALIC CAPITAL R -// 1d446 MATHEMATICAL ITALIC CAPITAL S -// 1d447 MATHEMATICAL ITALIC CAPITAL T -// 1d448 MATHEMATICAL ITALIC CAPITAL U -// 1d449 MATHEMATICAL ITALIC CAPITAL V -// 1d44a MATHEMATICAL ITALIC CAPITAL W -// 1d44b MATHEMATICAL ITALIC CAPITAL X -// 1d44c MATHEMATICAL ITALIC CAPITAL Y -// 1d44d MATHEMATICAL ITALIC CAPITAL Z - { 0x1D434, 0x1A, 0x89, 0, 0 }, -// 1d44e MATHEMATICAL ITALIC SMALL A -// 1d44f MATHEMATICAL ITALIC SMALL B -// 1d450 MATHEMATICAL ITALIC SMALL C -// 1d451 MATHEMATICAL ITALIC SMALL D -// 1d452 MATHEMATICAL ITALIC SMALL E -// 1d453 MATHEMATICAL ITALIC SMALL F -// 1d454 MATHEMATICAL ITALIC SMALL G - { 0x1D44E, 0x7, 0x49, 0, 0 }, -// 1d456 MATHEMATICAL ITALIC SMALL I -// 1d457 MATHEMATICAL ITALIC SMALL J -// 1d458 MATHEMATICAL ITALIC SMALL K -// 1d459 MATHEMATICAL ITALIC SMALL L -// 1d45a MATHEMATICAL ITALIC SMALL M -// 1d45b MATHEMATICAL ITALIC SMALL N -// 1d45c MATHEMATICAL ITALIC SMALL O -// 1d45d MATHEMATICAL ITALIC SMALL P -// 1d45e MATHEMATICAL ITALIC SMALL Q -// 1d45f MATHEMATICAL ITALIC SMALL R -// 1d460 MATHEMATICAL ITALIC SMALL S -// 1d461 MATHEMATICAL ITALIC SMALL T -// 1d462 MATHEMATICAL ITALIC SMALL U -// 1d463 MATHEMATICAL ITALIC SMALL V -// 1d464 MATHEMATICAL ITALIC SMALL W -// 1d465 MATHEMATICAL ITALIC SMALL X -// 1d466 MATHEMATICAL ITALIC SMALL Y -// 1d467 MATHEMATICAL ITALIC SMALL Z - { 0x1D456, 0x12, 0x49, 0, 0 }, -// 1d468 MATHEMATICAL BOLD ITALIC CAPITAL A -// 1d469 MATHEMATICAL BOLD ITALIC CAPITAL B -// 1d46a MATHEMATICAL BOLD ITALIC CAPITAL C -// 1d46b MATHEMATICAL BOLD ITALIC CAPITAL D -// 1d46c MATHEMATICAL BOLD ITALIC CAPITAL E -// 1d46d MATHEMATICAL BOLD ITALIC CAPITAL F -// 1d46e MATHEMATICAL BOLD ITALIC CAPITAL G -// 1d46f MATHEMATICAL BOLD ITALIC CAPITAL H -// 1d470 MATHEMATICAL BOLD ITALIC CAPITAL I -// 1d471 MATHEMATICAL BOLD ITALIC CAPITAL J -// 1d472 MATHEMATICAL BOLD ITALIC CAPITAL K -// 1d473 MATHEMATICAL BOLD ITALIC CAPITAL L -// 1d474 MATHEMATICAL BOLD ITALIC CAPITAL M -// 1d475 MATHEMATICAL BOLD ITALIC CAPITAL N -// 1d476 MATHEMATICAL BOLD ITALIC CAPITAL O -// 1d477 MATHEMATICAL BOLD ITALIC CAPITAL P -// 1d478 MATHEMATICAL BOLD ITALIC CAPITAL Q -// 1d479 MATHEMATICAL BOLD ITALIC CAPITAL R -// 1d47a MATHEMATICAL BOLD ITALIC CAPITAL S -// 1d47b MATHEMATICAL BOLD ITALIC CAPITAL T -// 1d47c MATHEMATICAL BOLD ITALIC CAPITAL U -// 1d47d MATHEMATICAL BOLD ITALIC CAPITAL V -// 1d47e MATHEMATICAL BOLD ITALIC CAPITAL W -// 1d47f MATHEMATICAL BOLD ITALIC CAPITAL X -// 1d480 MATHEMATICAL BOLD ITALIC CAPITAL Y -// 1d481 MATHEMATICAL BOLD ITALIC CAPITAL Z - { 0x1D468, 0x1A, 0x89, 0, 0 }, -// 1d482 MATHEMATICAL BOLD ITALIC SMALL A -// 1d483 MATHEMATICAL BOLD ITALIC SMALL B -// 1d484 MATHEMATICAL BOLD ITALIC SMALL C -// 1d485 MATHEMATICAL BOLD ITALIC SMALL D -// 1d486 MATHEMATICAL BOLD ITALIC SMALL E -// 1d487 MATHEMATICAL BOLD ITALIC SMALL F -// 1d488 MATHEMATICAL BOLD ITALIC SMALL G -// 1d489 MATHEMATICAL BOLD ITALIC SMALL H -// 1d48a MATHEMATICAL BOLD ITALIC SMALL I -// 1d48b MATHEMATICAL BOLD ITALIC SMALL J -// 1d48c MATHEMATICAL BOLD ITALIC SMALL K -// 1d48d MATHEMATICAL BOLD ITALIC SMALL L -// 1d48e MATHEMATICAL BOLD ITALIC SMALL M -// 1d48f MATHEMATICAL BOLD ITALIC SMALL N -// 1d490 MATHEMATICAL BOLD ITALIC SMALL O -// 1d491 MATHEMATICAL BOLD ITALIC SMALL P -// 1d492 MATHEMATICAL BOLD ITALIC SMALL Q -// 1d493 MATHEMATICAL BOLD ITALIC SMALL R -// 1d494 MATHEMATICAL BOLD ITALIC SMALL S -// 1d495 MATHEMATICAL BOLD ITALIC SMALL T -// 1d496 MATHEMATICAL BOLD ITALIC SMALL U -// 1d497 MATHEMATICAL BOLD ITALIC SMALL V -// 1d498 MATHEMATICAL BOLD ITALIC SMALL W -// 1d499 MATHEMATICAL BOLD ITALIC SMALL X -// 1d49a MATHEMATICAL BOLD ITALIC SMALL Y -// 1d49b MATHEMATICAL BOLD ITALIC SMALL Z - { 0x1D482, 0x1A, 0x49, 0, 0 }, -// 1d49c MATHEMATICAL SCRIPT CAPITAL A - { 0x1D49C, 0x1, 0x89, 0, 0 }, -// 1d49e MATHEMATICAL SCRIPT CAPITAL C -// 1d49f MATHEMATICAL SCRIPT CAPITAL D - { 0x1D49E, 0x2, 0x89, 0, 0 }, -// 1d4a2 MATHEMATICAL SCRIPT CAPITAL G - { 0x1D4A2, 0x1, 0x89, 0, 0 }, -// 1d4a5 MATHEMATICAL SCRIPT CAPITAL J -// 1d4a6 MATHEMATICAL SCRIPT CAPITAL K - { 0x1D4A5, 0x2, 0x89, 0, 0 }, -// 1d4a9 MATHEMATICAL SCRIPT CAPITAL N -// 1d4aa MATHEMATICAL SCRIPT CAPITAL O -// 1d4ab MATHEMATICAL SCRIPT CAPITAL P -// 1d4ac MATHEMATICAL SCRIPT CAPITAL Q - { 0x1D4A9, 0x4, 0x89, 0, 0 }, -// 1d4ae MATHEMATICAL SCRIPT CAPITAL S -// 1d4af MATHEMATICAL SCRIPT CAPITAL T -// 1d4b0 MATHEMATICAL SCRIPT CAPITAL U -// 1d4b1 MATHEMATICAL SCRIPT CAPITAL V -// 1d4b2 MATHEMATICAL SCRIPT CAPITAL W -// 1d4b3 MATHEMATICAL SCRIPT CAPITAL X -// 1d4b4 MATHEMATICAL SCRIPT CAPITAL Y -// 1d4b5 MATHEMATICAL SCRIPT CAPITAL Z - { 0x1D4AE, 0x8, 0x89, 0, 0 }, -// 1d4b6 MATHEMATICAL SCRIPT SMALL A -// 1d4b7 MATHEMATICAL SCRIPT SMALL B -// 1d4b8 MATHEMATICAL SCRIPT SMALL C -// 1d4b9 MATHEMATICAL SCRIPT SMALL D - { 0x1D4B6, 0x4, 0x49, 0, 0 }, -// 1d4bb MATHEMATICAL SCRIPT SMALL F - { 0x1D4BB, 0x1, 0x49, 0, 0 }, -// 1d4bd MATHEMATICAL SCRIPT SMALL H -// 1d4be MATHEMATICAL SCRIPT SMALL I -// 1d4bf MATHEMATICAL SCRIPT SMALL J -// 1d4c0 MATHEMATICAL SCRIPT SMALL K -// 1d4c1 MATHEMATICAL SCRIPT SMALL L -// 1d4c2 MATHEMATICAL SCRIPT SMALL M -// 1d4c3 MATHEMATICAL SCRIPT SMALL N - { 0x1D4BD, 0x7, 0x49, 0, 0 }, -// 1d4c5 MATHEMATICAL SCRIPT SMALL P -// 1d4c6 MATHEMATICAL SCRIPT SMALL Q -// 1d4c7 MATHEMATICAL SCRIPT SMALL R -// 1d4c8 MATHEMATICAL SCRIPT SMALL S -// 1d4c9 MATHEMATICAL SCRIPT SMALL T -// 1d4ca MATHEMATICAL SCRIPT SMALL U -// 1d4cb MATHEMATICAL SCRIPT SMALL V -// 1d4cc MATHEMATICAL SCRIPT SMALL W -// 1d4cd MATHEMATICAL SCRIPT SMALL X -// 1d4ce MATHEMATICAL SCRIPT SMALL Y -// 1d4cf MATHEMATICAL SCRIPT SMALL Z - { 0x1D4C5, 0xB, 0x49, 0, 0 }, -// 1d4d0 MATHEMATICAL BOLD SCRIPT CAPITAL A -// 1d4d1 MATHEMATICAL BOLD SCRIPT CAPITAL B -// 1d4d2 MATHEMATICAL BOLD SCRIPT CAPITAL C -// 1d4d3 MATHEMATICAL BOLD SCRIPT CAPITAL D -// 1d4d4 MATHEMATICAL BOLD SCRIPT CAPITAL E -// 1d4d5 MATHEMATICAL BOLD SCRIPT CAPITAL F -// 1d4d6 MATHEMATICAL BOLD SCRIPT CAPITAL G -// 1d4d7 MATHEMATICAL BOLD SCRIPT CAPITAL H -// 1d4d8 MATHEMATICAL BOLD SCRIPT CAPITAL I -// 1d4d9 MATHEMATICAL BOLD SCRIPT CAPITAL J -// 1d4da MATHEMATICAL BOLD SCRIPT CAPITAL K -// 1d4db MATHEMATICAL BOLD SCRIPT CAPITAL L -// 1d4dc MATHEMATICAL BOLD SCRIPT CAPITAL M -// 1d4dd MATHEMATICAL BOLD SCRIPT CAPITAL N -// 1d4de MATHEMATICAL BOLD SCRIPT CAPITAL O -// 1d4df MATHEMATICAL BOLD SCRIPT CAPITAL P -// 1d4e0 MATHEMATICAL BOLD SCRIPT CAPITAL Q -// 1d4e1 MATHEMATICAL BOLD SCRIPT CAPITAL R -// 1d4e2 MATHEMATICAL BOLD SCRIPT CAPITAL S -// 1d4e3 MATHEMATICAL BOLD SCRIPT CAPITAL T -// 1d4e4 MATHEMATICAL BOLD SCRIPT CAPITAL U -// 1d4e5 MATHEMATICAL BOLD SCRIPT CAPITAL V -// 1d4e6 MATHEMATICAL BOLD SCRIPT CAPITAL W -// 1d4e7 MATHEMATICAL BOLD SCRIPT CAPITAL X -// 1d4e8 MATHEMATICAL BOLD SCRIPT CAPITAL Y -// 1d4e9 MATHEMATICAL BOLD SCRIPT CAPITAL Z - { 0x1D4D0, 0x1A, 0x89, 0, 0 }, -// 1d4ea MATHEMATICAL BOLD SCRIPT SMALL A -// 1d4eb MATHEMATICAL BOLD SCRIPT SMALL B -// 1d4ec MATHEMATICAL BOLD SCRIPT SMALL C -// 1d4ed MATHEMATICAL BOLD SCRIPT SMALL D -// 1d4ee MATHEMATICAL BOLD SCRIPT SMALL E -// 1d4ef MATHEMATICAL BOLD SCRIPT SMALL F -// 1d4f0 MATHEMATICAL BOLD SCRIPT SMALL G -// 1d4f1 MATHEMATICAL BOLD SCRIPT SMALL H -// 1d4f2 MATHEMATICAL BOLD SCRIPT SMALL I -// 1d4f3 MATHEMATICAL BOLD SCRIPT SMALL J -// 1d4f4 MATHEMATICAL BOLD SCRIPT SMALL K -// 1d4f5 MATHEMATICAL BOLD SCRIPT SMALL L -// 1d4f6 MATHEMATICAL BOLD SCRIPT SMALL M -// 1d4f7 MATHEMATICAL BOLD SCRIPT SMALL N -// 1d4f8 MATHEMATICAL BOLD SCRIPT SMALL O -// 1d4f9 MATHEMATICAL BOLD SCRIPT SMALL P -// 1d4fa MATHEMATICAL BOLD SCRIPT SMALL Q -// 1d4fb MATHEMATICAL BOLD SCRIPT SMALL R -// 1d4fc MATHEMATICAL BOLD SCRIPT SMALL S -// 1d4fd MATHEMATICAL BOLD SCRIPT SMALL T -// 1d4fe MATHEMATICAL BOLD SCRIPT SMALL U -// 1d4ff MATHEMATICAL BOLD SCRIPT SMALL V -// 1d500 MATHEMATICAL BOLD SCRIPT SMALL W -// 1d501 MATHEMATICAL BOLD SCRIPT SMALL X -// 1d502 MATHEMATICAL BOLD SCRIPT SMALL Y -// 1d503 MATHEMATICAL BOLD SCRIPT SMALL Z - { 0x1D4EA, 0x1A, 0x49, 0, 0 }, -// 1d504 MATHEMATICAL FRAKTUR CAPITAL A -// 1d505 MATHEMATICAL FRAKTUR CAPITAL B - { 0x1D504, 0x2, 0x89, 0, 0 }, -// 1d507 MATHEMATICAL FRAKTUR CAPITAL D -// 1d508 MATHEMATICAL FRAKTUR CAPITAL E -// 1d509 MATHEMATICAL FRAKTUR CAPITAL F -// 1d50a MATHEMATICAL FRAKTUR CAPITAL G - { 0x1D507, 0x4, 0x89, 0, 0 }, -// 1d50d MATHEMATICAL FRAKTUR CAPITAL J -// 1d50e MATHEMATICAL FRAKTUR CAPITAL K -// 1d50f MATHEMATICAL FRAKTUR CAPITAL L -// 1d510 MATHEMATICAL FRAKTUR CAPITAL M -// 1d511 MATHEMATICAL FRAKTUR CAPITAL N -// 1d512 MATHEMATICAL FRAKTUR CAPITAL O -// 1d513 MATHEMATICAL FRAKTUR CAPITAL P -// 1d514 MATHEMATICAL FRAKTUR CAPITAL Q - { 0x1D50D, 0x8, 0x89, 0, 0 }, -// 1d516 MATHEMATICAL FRAKTUR CAPITAL S -// 1d517 MATHEMATICAL FRAKTUR CAPITAL T -// 1d518 MATHEMATICAL FRAKTUR CAPITAL U -// 1d519 MATHEMATICAL FRAKTUR CAPITAL V -// 1d51a MATHEMATICAL FRAKTUR CAPITAL W -// 1d51b MATHEMATICAL FRAKTUR CAPITAL X -// 1d51c MATHEMATICAL FRAKTUR CAPITAL Y - { 0x1D516, 0x7, 0x89, 0, 0 }, -// 1d51e MATHEMATICAL FRAKTUR SMALL A -// 1d51f MATHEMATICAL FRAKTUR SMALL B -// 1d520 MATHEMATICAL FRAKTUR SMALL C -// 1d521 MATHEMATICAL FRAKTUR SMALL D -// 1d522 MATHEMATICAL FRAKTUR SMALL E -// 1d523 MATHEMATICAL FRAKTUR SMALL F -// 1d524 MATHEMATICAL FRAKTUR SMALL G -// 1d525 MATHEMATICAL FRAKTUR SMALL H -// 1d526 MATHEMATICAL FRAKTUR SMALL I -// 1d527 MATHEMATICAL FRAKTUR SMALL J -// 1d528 MATHEMATICAL FRAKTUR SMALL K -// 1d529 MATHEMATICAL FRAKTUR SMALL L -// 1d52a MATHEMATICAL FRAKTUR SMALL M -// 1d52b MATHEMATICAL FRAKTUR SMALL N -// 1d52c MATHEMATICAL FRAKTUR SMALL O -// 1d52d MATHEMATICAL FRAKTUR SMALL P -// 1d52e MATHEMATICAL FRAKTUR SMALL Q -// 1d52f MATHEMATICAL FRAKTUR SMALL R -// 1d530 MATHEMATICAL FRAKTUR SMALL S -// 1d531 MATHEMATICAL FRAKTUR SMALL T -// 1d532 MATHEMATICAL FRAKTUR SMALL U -// 1d533 MATHEMATICAL FRAKTUR SMALL V -// 1d534 MATHEMATICAL FRAKTUR SMALL W -// 1d535 MATHEMATICAL FRAKTUR SMALL X -// 1d536 MATHEMATICAL FRAKTUR SMALL Y -// 1d537 MATHEMATICAL FRAKTUR SMALL Z - { 0x1D51E, 0x1A, 0x49, 0, 0 }, -// 1d538 MATHEMATICAL DOUBLE-STRUCK CAPITAL A -// 1d539 MATHEMATICAL DOUBLE-STRUCK CAPITAL B - { 0x1D538, 0x2, 0x89, 0, 0 }, -// 1d53b MATHEMATICAL DOUBLE-STRUCK CAPITAL D -// 1d53c MATHEMATICAL DOUBLE-STRUCK CAPITAL E -// 1d53d MATHEMATICAL DOUBLE-STRUCK CAPITAL F -// 1d53e MATHEMATICAL DOUBLE-STRUCK CAPITAL G - { 0x1D53B, 0x4, 0x89, 0, 0 }, -// 1d540 MATHEMATICAL DOUBLE-STRUCK CAPITAL I -// 1d541 MATHEMATICAL DOUBLE-STRUCK CAPITAL J -// 1d542 MATHEMATICAL DOUBLE-STRUCK CAPITAL K -// 1d543 MATHEMATICAL DOUBLE-STRUCK CAPITAL L -// 1d544 MATHEMATICAL DOUBLE-STRUCK CAPITAL M - { 0x1D540, 0x5, 0x89, 0, 0 }, -// 1d546 MATHEMATICAL DOUBLE-STRUCK CAPITAL O - { 0x1D546, 0x1, 0x89, 0, 0 }, -// 1d54a MATHEMATICAL DOUBLE-STRUCK CAPITAL S -// 1d54b MATHEMATICAL DOUBLE-STRUCK CAPITAL T -// 1d54c MATHEMATICAL DOUBLE-STRUCK CAPITAL U -// 1d54d MATHEMATICAL DOUBLE-STRUCK CAPITAL V -// 1d54e MATHEMATICAL DOUBLE-STRUCK CAPITAL W -// 1d54f MATHEMATICAL DOUBLE-STRUCK CAPITAL X -// 1d550 MATHEMATICAL DOUBLE-STRUCK CAPITAL Y - { 0x1D54A, 0x7, 0x89, 0, 0 }, -// 1d552 MATHEMATICAL DOUBLE-STRUCK SMALL A -// 1d553 MATHEMATICAL DOUBLE-STRUCK SMALL B -// 1d554 MATHEMATICAL DOUBLE-STRUCK SMALL C -// 1d555 MATHEMATICAL DOUBLE-STRUCK SMALL D -// 1d556 MATHEMATICAL DOUBLE-STRUCK SMALL E -// 1d557 MATHEMATICAL DOUBLE-STRUCK SMALL F -// 1d558 MATHEMATICAL DOUBLE-STRUCK SMALL G -// 1d559 MATHEMATICAL DOUBLE-STRUCK SMALL H -// 1d55a MATHEMATICAL DOUBLE-STRUCK SMALL I -// 1d55b MATHEMATICAL DOUBLE-STRUCK SMALL J -// 1d55c MATHEMATICAL DOUBLE-STRUCK SMALL K -// 1d55d MATHEMATICAL DOUBLE-STRUCK SMALL L -// 1d55e MATHEMATICAL DOUBLE-STRUCK SMALL M -// 1d55f MATHEMATICAL DOUBLE-STRUCK SMALL N -// 1d560 MATHEMATICAL DOUBLE-STRUCK SMALL O -// 1d561 MATHEMATICAL DOUBLE-STRUCK SMALL P -// 1d562 MATHEMATICAL DOUBLE-STRUCK SMALL Q -// 1d563 MATHEMATICAL DOUBLE-STRUCK SMALL R -// 1d564 MATHEMATICAL DOUBLE-STRUCK SMALL S -// 1d565 MATHEMATICAL DOUBLE-STRUCK SMALL T -// 1d566 MATHEMATICAL DOUBLE-STRUCK SMALL U -// 1d567 MATHEMATICAL DOUBLE-STRUCK SMALL V -// 1d568 MATHEMATICAL DOUBLE-STRUCK SMALL W -// 1d569 MATHEMATICAL DOUBLE-STRUCK SMALL X -// 1d56a MATHEMATICAL DOUBLE-STRUCK SMALL Y -// 1d56b MATHEMATICAL DOUBLE-STRUCK SMALL Z - { 0x1D552, 0x1A, 0x49, 0, 0 }, -// 1d56c MATHEMATICAL BOLD FRAKTUR CAPITAL A -// 1d56d MATHEMATICAL BOLD FRAKTUR CAPITAL B -// 1d56e MATHEMATICAL BOLD FRAKTUR CAPITAL C -// 1d56f MATHEMATICAL BOLD FRAKTUR CAPITAL D -// 1d570 MATHEMATICAL BOLD FRAKTUR CAPITAL E -// 1d571 MATHEMATICAL BOLD FRAKTUR CAPITAL F -// 1d572 MATHEMATICAL BOLD FRAKTUR CAPITAL G -// 1d573 MATHEMATICAL BOLD FRAKTUR CAPITAL H -// 1d574 MATHEMATICAL BOLD FRAKTUR CAPITAL I -// 1d575 MATHEMATICAL BOLD FRAKTUR CAPITAL J -// 1d576 MATHEMATICAL BOLD FRAKTUR CAPITAL K -// 1d577 MATHEMATICAL BOLD FRAKTUR CAPITAL L -// 1d578 MATHEMATICAL BOLD FRAKTUR CAPITAL M -// 1d579 MATHEMATICAL BOLD FRAKTUR CAPITAL N -// 1d57a MATHEMATICAL BOLD FRAKTUR CAPITAL O -// 1d57b MATHEMATICAL BOLD FRAKTUR CAPITAL P -// 1d57c MATHEMATICAL BOLD FRAKTUR CAPITAL Q -// 1d57d MATHEMATICAL BOLD FRAKTUR CAPITAL R -// 1d57e MATHEMATICAL BOLD FRAKTUR CAPITAL S -// 1d57f MATHEMATICAL BOLD FRAKTUR CAPITAL T -// 1d580 MATHEMATICAL BOLD FRAKTUR CAPITAL U -// 1d581 MATHEMATICAL BOLD FRAKTUR CAPITAL V -// 1d582 MATHEMATICAL BOLD FRAKTUR CAPITAL W -// 1d583 MATHEMATICAL BOLD FRAKTUR CAPITAL X -// 1d584 MATHEMATICAL BOLD FRAKTUR CAPITAL Y -// 1d585 MATHEMATICAL BOLD FRAKTUR CAPITAL Z - { 0x1D56C, 0x1A, 0x89, 0, 0 }, -// 1d586 MATHEMATICAL BOLD FRAKTUR SMALL A -// 1d587 MATHEMATICAL BOLD FRAKTUR SMALL B -// 1d588 MATHEMATICAL BOLD FRAKTUR SMALL C -// 1d589 MATHEMATICAL BOLD FRAKTUR SMALL D -// 1d58a MATHEMATICAL BOLD FRAKTUR SMALL E -// 1d58b MATHEMATICAL BOLD FRAKTUR SMALL F -// 1d58c MATHEMATICAL BOLD FRAKTUR SMALL G -// 1d58d MATHEMATICAL BOLD FRAKTUR SMALL H -// 1d58e MATHEMATICAL BOLD FRAKTUR SMALL I -// 1d58f MATHEMATICAL BOLD FRAKTUR SMALL J -// 1d590 MATHEMATICAL BOLD FRAKTUR SMALL K -// 1d591 MATHEMATICAL BOLD FRAKTUR SMALL L -// 1d592 MATHEMATICAL BOLD FRAKTUR SMALL M -// 1d593 MATHEMATICAL BOLD FRAKTUR SMALL N -// 1d594 MATHEMATICAL BOLD FRAKTUR SMALL O -// 1d595 MATHEMATICAL BOLD FRAKTUR SMALL P -// 1d596 MATHEMATICAL BOLD FRAKTUR SMALL Q -// 1d597 MATHEMATICAL BOLD FRAKTUR SMALL R -// 1d598 MATHEMATICAL BOLD FRAKTUR SMALL S -// 1d599 MATHEMATICAL BOLD FRAKTUR SMALL T -// 1d59a MATHEMATICAL BOLD FRAKTUR SMALL U -// 1d59b MATHEMATICAL BOLD FRAKTUR SMALL V -// 1d59c MATHEMATICAL BOLD FRAKTUR SMALL W -// 1d59d MATHEMATICAL BOLD FRAKTUR SMALL X -// 1d59e MATHEMATICAL BOLD FRAKTUR SMALL Y -// 1d59f MATHEMATICAL BOLD FRAKTUR SMALL Z - { 0x1D586, 0x1A, 0x49, 0, 0 }, -// 1d5a0 MATHEMATICAL SANS-SERIF CAPITAL A -// 1d5a1 MATHEMATICAL SANS-SERIF CAPITAL B -// 1d5a2 MATHEMATICAL SANS-SERIF CAPITAL C -// 1d5a3 MATHEMATICAL SANS-SERIF CAPITAL D -// 1d5a4 MATHEMATICAL SANS-SERIF CAPITAL E -// 1d5a5 MATHEMATICAL SANS-SERIF CAPITAL F -// 1d5a6 MATHEMATICAL SANS-SERIF CAPITAL G -// 1d5a7 MATHEMATICAL SANS-SERIF CAPITAL H -// 1d5a8 MATHEMATICAL SANS-SERIF CAPITAL I -// 1d5a9 MATHEMATICAL SANS-SERIF CAPITAL J -// 1d5aa MATHEMATICAL SANS-SERIF CAPITAL K -// 1d5ab MATHEMATICAL SANS-SERIF CAPITAL L -// 1d5ac MATHEMATICAL SANS-SERIF CAPITAL M -// 1d5ad MATHEMATICAL SANS-SERIF CAPITAL N -// 1d5ae MATHEMATICAL SANS-SERIF CAPITAL O -// 1d5af MATHEMATICAL SANS-SERIF CAPITAL P -// 1d5b0 MATHEMATICAL SANS-SERIF CAPITAL Q -// 1d5b1 MATHEMATICAL SANS-SERIF CAPITAL R -// 1d5b2 MATHEMATICAL SANS-SERIF CAPITAL S -// 1d5b3 MATHEMATICAL SANS-SERIF CAPITAL T -// 1d5b4 MATHEMATICAL SANS-SERIF CAPITAL U -// 1d5b5 MATHEMATICAL SANS-SERIF CAPITAL V -// 1d5b6 MATHEMATICAL SANS-SERIF CAPITAL W -// 1d5b7 MATHEMATICAL SANS-SERIF CAPITAL X -// 1d5b8 MATHEMATICAL SANS-SERIF CAPITAL Y -// 1d5b9 MATHEMATICAL SANS-SERIF CAPITAL Z - { 0x1D5A0, 0x1A, 0x89, 0, 0 }, -// 1d5ba MATHEMATICAL SANS-SERIF SMALL A -// 1d5bb MATHEMATICAL SANS-SERIF SMALL B -// 1d5bc MATHEMATICAL SANS-SERIF SMALL C -// 1d5bd MATHEMATICAL SANS-SERIF SMALL D -// 1d5be MATHEMATICAL SANS-SERIF SMALL E -// 1d5bf MATHEMATICAL SANS-SERIF SMALL F -// 1d5c0 MATHEMATICAL SANS-SERIF SMALL G -// 1d5c1 MATHEMATICAL SANS-SERIF SMALL H -// 1d5c2 MATHEMATICAL SANS-SERIF SMALL I -// 1d5c3 MATHEMATICAL SANS-SERIF SMALL J -// 1d5c4 MATHEMATICAL SANS-SERIF SMALL K -// 1d5c5 MATHEMATICAL SANS-SERIF SMALL L -// 1d5c6 MATHEMATICAL SANS-SERIF SMALL M -// 1d5c7 MATHEMATICAL SANS-SERIF SMALL N -// 1d5c8 MATHEMATICAL SANS-SERIF SMALL O -// 1d5c9 MATHEMATICAL SANS-SERIF SMALL P -// 1d5ca MATHEMATICAL SANS-SERIF SMALL Q -// 1d5cb MATHEMATICAL SANS-SERIF SMALL R -// 1d5cc MATHEMATICAL SANS-SERIF SMALL S -// 1d5cd MATHEMATICAL SANS-SERIF SMALL T -// 1d5ce MATHEMATICAL SANS-SERIF SMALL U -// 1d5cf MATHEMATICAL SANS-SERIF SMALL V -// 1d5d0 MATHEMATICAL SANS-SERIF SMALL W -// 1d5d1 MATHEMATICAL SANS-SERIF SMALL X -// 1d5d2 MATHEMATICAL SANS-SERIF SMALL Y -// 1d5d3 MATHEMATICAL SANS-SERIF SMALL Z - { 0x1D5BA, 0x1A, 0x49, 0, 0 }, -// 1d5d4 MATHEMATICAL SANS-SERIF BOLD CAPITAL A -// 1d5d5 MATHEMATICAL SANS-SERIF BOLD CAPITAL B -// 1d5d6 MATHEMATICAL SANS-SERIF BOLD CAPITAL C -// 1d5d7 MATHEMATICAL SANS-SERIF BOLD CAPITAL D -// 1d5d8 MATHEMATICAL SANS-SERIF BOLD CAPITAL E -// 1d5d9 MATHEMATICAL SANS-SERIF BOLD CAPITAL F -// 1d5da MATHEMATICAL SANS-SERIF BOLD CAPITAL G -// 1d5db MATHEMATICAL SANS-SERIF BOLD CAPITAL H -// 1d5dc MATHEMATICAL SANS-SERIF BOLD CAPITAL I -// 1d5dd MATHEMATICAL SANS-SERIF BOLD CAPITAL J -// 1d5de MATHEMATICAL SANS-SERIF BOLD CAPITAL K -// 1d5df MATHEMATICAL SANS-SERIF BOLD CAPITAL L -// 1d5e0 MATHEMATICAL SANS-SERIF BOLD CAPITAL M -// 1d5e1 MATHEMATICAL SANS-SERIF BOLD CAPITAL N -// 1d5e2 MATHEMATICAL SANS-SERIF BOLD CAPITAL O -// 1d5e3 MATHEMATICAL SANS-SERIF BOLD CAPITAL P -// 1d5e4 MATHEMATICAL SANS-SERIF BOLD CAPITAL Q -// 1d5e5 MATHEMATICAL SANS-SERIF BOLD CAPITAL R -// 1d5e6 MATHEMATICAL SANS-SERIF BOLD CAPITAL S -// 1d5e7 MATHEMATICAL SANS-SERIF BOLD CAPITAL T -// 1d5e8 MATHEMATICAL SANS-SERIF BOLD CAPITAL U -// 1d5e9 MATHEMATICAL SANS-SERIF BOLD CAPITAL V -// 1d5ea MATHEMATICAL SANS-SERIF BOLD CAPITAL W -// 1d5eb MATHEMATICAL SANS-SERIF BOLD CAPITAL X -// 1d5ec MATHEMATICAL SANS-SERIF BOLD CAPITAL Y -// 1d5ed MATHEMATICAL SANS-SERIF BOLD CAPITAL Z - { 0x1D5D4, 0x1A, 0x89, 0, 0 }, -// 1d5ee MATHEMATICAL SANS-SERIF BOLD SMALL A -// 1d5ef MATHEMATICAL SANS-SERIF BOLD SMALL B -// 1d5f0 MATHEMATICAL SANS-SERIF BOLD SMALL C -// 1d5f1 MATHEMATICAL SANS-SERIF BOLD SMALL D -// 1d5f2 MATHEMATICAL SANS-SERIF BOLD SMALL E -// 1d5f3 MATHEMATICAL SANS-SERIF BOLD SMALL F -// 1d5f4 MATHEMATICAL SANS-SERIF BOLD SMALL G -// 1d5f5 MATHEMATICAL SANS-SERIF BOLD SMALL H -// 1d5f6 MATHEMATICAL SANS-SERIF BOLD SMALL I -// 1d5f7 MATHEMATICAL SANS-SERIF BOLD SMALL J -// 1d5f8 MATHEMATICAL SANS-SERIF BOLD SMALL K -// 1d5f9 MATHEMATICAL SANS-SERIF BOLD SMALL L -// 1d5fa MATHEMATICAL SANS-SERIF BOLD SMALL M -// 1d5fb MATHEMATICAL SANS-SERIF BOLD SMALL N -// 1d5fc MATHEMATICAL SANS-SERIF BOLD SMALL O -// 1d5fd MATHEMATICAL SANS-SERIF BOLD SMALL P -// 1d5fe MATHEMATICAL SANS-SERIF BOLD SMALL Q -// 1d5ff MATHEMATICAL SANS-SERIF BOLD SMALL R -// 1d600 MATHEMATICAL SANS-SERIF BOLD SMALL S -// 1d601 MATHEMATICAL SANS-SERIF BOLD SMALL T -// 1d602 MATHEMATICAL SANS-SERIF BOLD SMALL U -// 1d603 MATHEMATICAL SANS-SERIF BOLD SMALL V -// 1d604 MATHEMATICAL SANS-SERIF BOLD SMALL W -// 1d605 MATHEMATICAL SANS-SERIF BOLD SMALL X -// 1d606 MATHEMATICAL SANS-SERIF BOLD SMALL Y -// 1d607 MATHEMATICAL SANS-SERIF BOLD SMALL Z - { 0x1D5EE, 0x1A, 0x49, 0, 0 }, -// 1d608 MATHEMATICAL SANS-SERIF ITALIC CAPITAL A -// 1d609 MATHEMATICAL SANS-SERIF ITALIC CAPITAL B -// 1d60a MATHEMATICAL SANS-SERIF ITALIC CAPITAL C -// 1d60b MATHEMATICAL SANS-SERIF ITALIC CAPITAL D -// 1d60c MATHEMATICAL SANS-SERIF ITALIC CAPITAL E -// 1d60d MATHEMATICAL SANS-SERIF ITALIC CAPITAL F -// 1d60e MATHEMATICAL SANS-SERIF ITALIC CAPITAL G -// 1d60f MATHEMATICAL SANS-SERIF ITALIC CAPITAL H -// 1d610 MATHEMATICAL SANS-SERIF ITALIC CAPITAL I -// 1d611 MATHEMATICAL SANS-SERIF ITALIC CAPITAL J -// 1d612 MATHEMATICAL SANS-SERIF ITALIC CAPITAL K -// 1d613 MATHEMATICAL SANS-SERIF ITALIC CAPITAL L -// 1d614 MATHEMATICAL SANS-SERIF ITALIC CAPITAL M -// 1d615 MATHEMATICAL SANS-SERIF ITALIC CAPITAL N -// 1d616 MATHEMATICAL SANS-SERIF ITALIC CAPITAL O -// 1d617 MATHEMATICAL SANS-SERIF ITALIC CAPITAL P -// 1d618 MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q -// 1d619 MATHEMATICAL SANS-SERIF ITALIC CAPITAL R -// 1d61a MATHEMATICAL SANS-SERIF ITALIC CAPITAL S -// 1d61b MATHEMATICAL SANS-SERIF ITALIC CAPITAL T -// 1d61c MATHEMATICAL SANS-SERIF ITALIC CAPITAL U -// 1d61d MATHEMATICAL SANS-SERIF ITALIC CAPITAL V -// 1d61e MATHEMATICAL SANS-SERIF ITALIC CAPITAL W -// 1d61f MATHEMATICAL SANS-SERIF ITALIC CAPITAL X -// 1d620 MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y -// 1d621 MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z - { 0x1D608, 0x1A, 0x89, 0, 0 }, -// 1d622 MATHEMATICAL SANS-SERIF ITALIC SMALL A -// 1d623 MATHEMATICAL SANS-SERIF ITALIC SMALL B -// 1d624 MATHEMATICAL SANS-SERIF ITALIC SMALL C -// 1d625 MATHEMATICAL SANS-SERIF ITALIC SMALL D -// 1d626 MATHEMATICAL SANS-SERIF ITALIC SMALL E -// 1d627 MATHEMATICAL SANS-SERIF ITALIC SMALL F -// 1d628 MATHEMATICAL SANS-SERIF ITALIC SMALL G -// 1d629 MATHEMATICAL SANS-SERIF ITALIC SMALL H -// 1d62a MATHEMATICAL SANS-SERIF ITALIC SMALL I -// 1d62b MATHEMATICAL SANS-SERIF ITALIC SMALL J -// 1d62c MATHEMATICAL SANS-SERIF ITALIC SMALL K -// 1d62d MATHEMATICAL SANS-SERIF ITALIC SMALL L -// 1d62e MATHEMATICAL SANS-SERIF ITALIC SMALL M -// 1d62f MATHEMATICAL SANS-SERIF ITALIC SMALL N -// 1d630 MATHEMATICAL SANS-SERIF ITALIC SMALL O -// 1d631 MATHEMATICAL SANS-SERIF ITALIC SMALL P -// 1d632 MATHEMATICAL SANS-SERIF ITALIC SMALL Q -// 1d633 MATHEMATICAL SANS-SERIF ITALIC SMALL R -// 1d634 MATHEMATICAL SANS-SERIF ITALIC SMALL S -// 1d635 MATHEMATICAL SANS-SERIF ITALIC SMALL T -// 1d636 MATHEMATICAL SANS-SERIF ITALIC SMALL U -// 1d637 MATHEMATICAL SANS-SERIF ITALIC SMALL V -// 1d638 MATHEMATICAL SANS-SERIF ITALIC SMALL W -// 1d639 MATHEMATICAL SANS-SERIF ITALIC SMALL X -// 1d63a MATHEMATICAL SANS-SERIF ITALIC SMALL Y -// 1d63b MATHEMATICAL SANS-SERIF ITALIC SMALL Z - { 0x1D622, 0x1A, 0x49, 0, 0 }, -// 1d63c MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A -// 1d63d MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B -// 1d63e MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C -// 1d63f MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D -// 1d640 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E -// 1d641 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F -// 1d642 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G -// 1d643 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H -// 1d644 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I -// 1d645 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J -// 1d646 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K -// 1d647 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L -// 1d648 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M -// 1d649 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N -// 1d64a MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O -// 1d64b MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P -// 1d64c MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q -// 1d64d MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R -// 1d64e MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S -// 1d64f MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T -// 1d650 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U -// 1d651 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V -// 1d652 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W -// 1d653 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X -// 1d654 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y -// 1d655 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z - { 0x1D63C, 0x1A, 0x89, 0, 0 }, -// 1d656 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A -// 1d657 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B -// 1d658 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C -// 1d659 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D -// 1d65a MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E -// 1d65b MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F -// 1d65c MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G -// 1d65d MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H -// 1d65e MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I -// 1d65f MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J -// 1d660 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K -// 1d661 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L -// 1d662 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M -// 1d663 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N -// 1d664 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O -// 1d665 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P -// 1d666 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q -// 1d667 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R -// 1d668 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S -// 1d669 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T -// 1d66a MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U -// 1d66b MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V -// 1d66c MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W -// 1d66d MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X -// 1d66e MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y -// 1d66f MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z - { 0x1D656, 0x1A, 0x49, 0, 0 }, -// 1d670 MATHEMATICAL MONOSPACE CAPITAL A -// 1d671 MATHEMATICAL MONOSPACE CAPITAL B -// 1d672 MATHEMATICAL MONOSPACE CAPITAL C -// 1d673 MATHEMATICAL MONOSPACE CAPITAL D -// 1d674 MATHEMATICAL MONOSPACE CAPITAL E -// 1d675 MATHEMATICAL MONOSPACE CAPITAL F -// 1d676 MATHEMATICAL MONOSPACE CAPITAL G -// 1d677 MATHEMATICAL MONOSPACE CAPITAL H -// 1d678 MATHEMATICAL MONOSPACE CAPITAL I -// 1d679 MATHEMATICAL MONOSPACE CAPITAL J -// 1d67a MATHEMATICAL MONOSPACE CAPITAL K -// 1d67b MATHEMATICAL MONOSPACE CAPITAL L -// 1d67c MATHEMATICAL MONOSPACE CAPITAL M -// 1d67d MATHEMATICAL MONOSPACE CAPITAL N -// 1d67e MATHEMATICAL MONOSPACE CAPITAL O -// 1d67f MATHEMATICAL MONOSPACE CAPITAL P -// 1d680 MATHEMATICAL MONOSPACE CAPITAL Q -// 1d681 MATHEMATICAL MONOSPACE CAPITAL R -// 1d682 MATHEMATICAL MONOSPACE CAPITAL S -// 1d683 MATHEMATICAL MONOSPACE CAPITAL T -// 1d684 MATHEMATICAL MONOSPACE CAPITAL U -// 1d685 MATHEMATICAL MONOSPACE CAPITAL V -// 1d686 MATHEMATICAL MONOSPACE CAPITAL W -// 1d687 MATHEMATICAL MONOSPACE CAPITAL X -// 1d688 MATHEMATICAL MONOSPACE CAPITAL Y -// 1d689 MATHEMATICAL MONOSPACE CAPITAL Z - { 0x1D670, 0x1A, 0x89, 0, 0 }, -// 1d68a MATHEMATICAL MONOSPACE SMALL A -// 1d68b MATHEMATICAL MONOSPACE SMALL B -// 1d68c MATHEMATICAL MONOSPACE SMALL C -// 1d68d MATHEMATICAL MONOSPACE SMALL D -// 1d68e MATHEMATICAL MONOSPACE SMALL E -// 1d68f MATHEMATICAL MONOSPACE SMALL F -// 1d690 MATHEMATICAL MONOSPACE SMALL G -// 1d691 MATHEMATICAL MONOSPACE SMALL H -// 1d692 MATHEMATICAL MONOSPACE SMALL I -// 1d693 MATHEMATICAL MONOSPACE SMALL J -// 1d694 MATHEMATICAL MONOSPACE SMALL K -// 1d695 MATHEMATICAL MONOSPACE SMALL L -// 1d696 MATHEMATICAL MONOSPACE SMALL M -// 1d697 MATHEMATICAL MONOSPACE SMALL N -// 1d698 MATHEMATICAL MONOSPACE SMALL O -// 1d699 MATHEMATICAL MONOSPACE SMALL P -// 1d69a MATHEMATICAL MONOSPACE SMALL Q -// 1d69b MATHEMATICAL MONOSPACE SMALL R -// 1d69c MATHEMATICAL MONOSPACE SMALL S -// 1d69d MATHEMATICAL MONOSPACE SMALL T -// 1d69e MATHEMATICAL MONOSPACE SMALL U -// 1d69f MATHEMATICAL MONOSPACE SMALL V -// 1d6a0 MATHEMATICAL MONOSPACE SMALL W -// 1d6a1 MATHEMATICAL MONOSPACE SMALL X -// 1d6a2 MATHEMATICAL MONOSPACE SMALL Y -// 1d6a3 MATHEMATICAL MONOSPACE SMALL Z -// 1d6a4 MATHEMATICAL ITALIC SMALL DOTLESS I -// 1d6a5 MATHEMATICAL ITALIC SMALL DOTLESS J - { 0x1D68A, 0x1C, 0x49, 0, 0 }, -// 1d6a8 MATHEMATICAL BOLD CAPITAL ALPHA -// 1d6a9 MATHEMATICAL BOLD CAPITAL BETA -// 1d6aa MATHEMATICAL BOLD CAPITAL GAMMA -// 1d6ab MATHEMATICAL BOLD CAPITAL DELTA -// 1d6ac MATHEMATICAL BOLD CAPITAL EPSILON -// 1d6ad MATHEMATICAL BOLD CAPITAL ZETA -// 1d6ae MATHEMATICAL BOLD CAPITAL ETA -// 1d6af MATHEMATICAL BOLD CAPITAL THETA -// 1d6b0 MATHEMATICAL BOLD CAPITAL IOTA -// 1d6b1 MATHEMATICAL BOLD CAPITAL KAPPA -// 1d6b2 MATHEMATICAL BOLD CAPITAL LAMDA -// 1d6b3 MATHEMATICAL BOLD CAPITAL MU -// 1d6b4 MATHEMATICAL BOLD CAPITAL NU -// 1d6b5 MATHEMATICAL BOLD CAPITAL XI -// 1d6b6 MATHEMATICAL BOLD CAPITAL OMICRON -// 1d6b7 MATHEMATICAL BOLD CAPITAL PI -// 1d6b8 MATHEMATICAL BOLD CAPITAL RHO -// 1d6b9 MATHEMATICAL BOLD CAPITAL THETA SYMBOL -// 1d6ba MATHEMATICAL BOLD CAPITAL SIGMA -// 1d6bb MATHEMATICAL BOLD CAPITAL TAU -// 1d6bc MATHEMATICAL BOLD CAPITAL UPSILON -// 1d6bd MATHEMATICAL BOLD CAPITAL PHI -// 1d6be MATHEMATICAL BOLD CAPITAL CHI -// 1d6bf MATHEMATICAL BOLD CAPITAL PSI -// 1d6c0 MATHEMATICAL BOLD CAPITAL OMEGA - { 0x1D6A8, 0x19, 0x89, 0, 0 }, -// 1d6c1 MATHEMATICAL BOLD NABLA - { 0x1D6C1, 0x1, 0x8, 0, 0 }, -// 1d6c2 MATHEMATICAL BOLD SMALL ALPHA -// 1d6c3 MATHEMATICAL BOLD SMALL BETA -// 1d6c4 MATHEMATICAL BOLD SMALL GAMMA -// 1d6c5 MATHEMATICAL BOLD SMALL DELTA -// 1d6c6 MATHEMATICAL BOLD SMALL EPSILON -// 1d6c7 MATHEMATICAL BOLD SMALL ZETA -// 1d6c8 MATHEMATICAL BOLD SMALL ETA -// 1d6c9 MATHEMATICAL BOLD SMALL THETA -// 1d6ca MATHEMATICAL BOLD SMALL IOTA -// 1d6cb MATHEMATICAL BOLD SMALL KAPPA -// 1d6cc MATHEMATICAL BOLD SMALL LAMDA -// 1d6cd MATHEMATICAL BOLD SMALL MU -// 1d6ce MATHEMATICAL BOLD SMALL NU -// 1d6cf MATHEMATICAL BOLD SMALL XI -// 1d6d0 MATHEMATICAL BOLD SMALL OMICRON -// 1d6d1 MATHEMATICAL BOLD SMALL PI -// 1d6d2 MATHEMATICAL BOLD SMALL RHO -// 1d6d3 MATHEMATICAL BOLD SMALL FINAL SIGMA -// 1d6d4 MATHEMATICAL BOLD SMALL SIGMA -// 1d6d5 MATHEMATICAL BOLD SMALL TAU -// 1d6d6 MATHEMATICAL BOLD SMALL UPSILON -// 1d6d7 MATHEMATICAL BOLD SMALL PHI -// 1d6d8 MATHEMATICAL BOLD SMALL CHI -// 1d6d9 MATHEMATICAL BOLD SMALL PSI -// 1d6da MATHEMATICAL BOLD SMALL OMEGA - { 0x1D6C2, 0x19, 0x49, 0, 0 }, -// 1d6db MATHEMATICAL BOLD PARTIAL DIFFERENTIAL - { 0x1D6DB, 0x1, 0x8, 0, 0 }, -// 1d6dc MATHEMATICAL BOLD EPSILON SYMBOL -// 1d6dd MATHEMATICAL BOLD THETA SYMBOL -// 1d6de MATHEMATICAL BOLD KAPPA SYMBOL -// 1d6df MATHEMATICAL BOLD PHI SYMBOL -// 1d6e0 MATHEMATICAL BOLD RHO SYMBOL -// 1d6e1 MATHEMATICAL BOLD PI SYMBOL - { 0x1D6DC, 0x6, 0x49, 0, 0 }, -// 1d6e2 MATHEMATICAL ITALIC CAPITAL ALPHA -// 1d6e3 MATHEMATICAL ITALIC CAPITAL BETA -// 1d6e4 MATHEMATICAL ITALIC CAPITAL GAMMA -// 1d6e5 MATHEMATICAL ITALIC CAPITAL DELTA -// 1d6e6 MATHEMATICAL ITALIC CAPITAL EPSILON -// 1d6e7 MATHEMATICAL ITALIC CAPITAL ZETA -// 1d6e8 MATHEMATICAL ITALIC CAPITAL ETA -// 1d6e9 MATHEMATICAL ITALIC CAPITAL THETA -// 1d6ea MATHEMATICAL ITALIC CAPITAL IOTA -// 1d6eb MATHEMATICAL ITALIC CAPITAL KAPPA -// 1d6ec MATHEMATICAL ITALIC CAPITAL LAMDA -// 1d6ed MATHEMATICAL ITALIC CAPITAL MU -// 1d6ee MATHEMATICAL ITALIC CAPITAL NU -// 1d6ef MATHEMATICAL ITALIC CAPITAL XI -// 1d6f0 MATHEMATICAL ITALIC CAPITAL OMICRON -// 1d6f1 MATHEMATICAL ITALIC CAPITAL PI -// 1d6f2 MATHEMATICAL ITALIC CAPITAL RHO -// 1d6f3 MATHEMATICAL ITALIC CAPITAL THETA SYMBOL -// 1d6f4 MATHEMATICAL ITALIC CAPITAL SIGMA -// 1d6f5 MATHEMATICAL ITALIC CAPITAL TAU -// 1d6f6 MATHEMATICAL ITALIC CAPITAL UPSILON -// 1d6f7 MATHEMATICAL ITALIC CAPITAL PHI -// 1d6f8 MATHEMATICAL ITALIC CAPITAL CHI -// 1d6f9 MATHEMATICAL ITALIC CAPITAL PSI -// 1d6fa MATHEMATICAL ITALIC CAPITAL OMEGA - { 0x1D6E2, 0x19, 0x89, 0, 0 }, -// 1d6fb MATHEMATICAL ITALIC NABLA - { 0x1D6FB, 0x1, 0x8, 0, 0 }, -// 1d6fc MATHEMATICAL ITALIC SMALL ALPHA -// 1d6fd MATHEMATICAL ITALIC SMALL BETA -// 1d6fe MATHEMATICAL ITALIC SMALL GAMMA -// 1d6ff MATHEMATICAL ITALIC SMALL DELTA -// 1d700 MATHEMATICAL ITALIC SMALL EPSILON -// 1d701 MATHEMATICAL ITALIC SMALL ZETA -// 1d702 MATHEMATICAL ITALIC SMALL ETA -// 1d703 MATHEMATICAL ITALIC SMALL THETA -// 1d704 MATHEMATICAL ITALIC SMALL IOTA -// 1d705 MATHEMATICAL ITALIC SMALL KAPPA -// 1d706 MATHEMATICAL ITALIC SMALL LAMDA -// 1d707 MATHEMATICAL ITALIC SMALL MU -// 1d708 MATHEMATICAL ITALIC SMALL NU -// 1d709 MATHEMATICAL ITALIC SMALL XI -// 1d70a MATHEMATICAL ITALIC SMALL OMICRON -// 1d70b MATHEMATICAL ITALIC SMALL PI -// 1d70c MATHEMATICAL ITALIC SMALL RHO -// 1d70d MATHEMATICAL ITALIC SMALL FINAL SIGMA -// 1d70e MATHEMATICAL ITALIC SMALL SIGMA -// 1d70f MATHEMATICAL ITALIC SMALL TAU -// 1d710 MATHEMATICAL ITALIC SMALL UPSILON -// 1d711 MATHEMATICAL ITALIC SMALL PHI -// 1d712 MATHEMATICAL ITALIC SMALL CHI -// 1d713 MATHEMATICAL ITALIC SMALL PSI -// 1d714 MATHEMATICAL ITALIC SMALL OMEGA - { 0x1D6FC, 0x19, 0x49, 0, 0 }, -// 1d715 MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL - { 0x1D715, 0x1, 0x8, 0, 0 }, -// 1d716 MATHEMATICAL ITALIC EPSILON SYMBOL -// 1d717 MATHEMATICAL ITALIC THETA SYMBOL -// 1d718 MATHEMATICAL ITALIC KAPPA SYMBOL -// 1d719 MATHEMATICAL ITALIC PHI SYMBOL -// 1d71a MATHEMATICAL ITALIC RHO SYMBOL -// 1d71b MATHEMATICAL ITALIC PI SYMBOL - { 0x1D716, 0x6, 0x49, 0, 0 }, -// 1d71c MATHEMATICAL BOLD ITALIC CAPITAL ALPHA -// 1d71d MATHEMATICAL BOLD ITALIC CAPITAL BETA -// 1d71e MATHEMATICAL BOLD ITALIC CAPITAL GAMMA -// 1d71f MATHEMATICAL BOLD ITALIC CAPITAL DELTA -// 1d720 MATHEMATICAL BOLD ITALIC CAPITAL EPSILON -// 1d721 MATHEMATICAL BOLD ITALIC CAPITAL ZETA -// 1d722 MATHEMATICAL BOLD ITALIC CAPITAL ETA -// 1d723 MATHEMATICAL BOLD ITALIC CAPITAL THETA -// 1d724 MATHEMATICAL BOLD ITALIC CAPITAL IOTA -// 1d725 MATHEMATICAL BOLD ITALIC CAPITAL KAPPA -// 1d726 MATHEMATICAL BOLD ITALIC CAPITAL LAMDA -// 1d727 MATHEMATICAL BOLD ITALIC CAPITAL MU -// 1d728 MATHEMATICAL BOLD ITALIC CAPITAL NU -// 1d729 MATHEMATICAL BOLD ITALIC CAPITAL XI -// 1d72a MATHEMATICAL BOLD ITALIC CAPITAL OMICRON -// 1d72b MATHEMATICAL BOLD ITALIC CAPITAL PI -// 1d72c MATHEMATICAL BOLD ITALIC CAPITAL RHO -// 1d72d MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL -// 1d72e MATHEMATICAL BOLD ITALIC CAPITAL SIGMA -// 1d72f MATHEMATICAL BOLD ITALIC CAPITAL TAU -// 1d730 MATHEMATICAL BOLD ITALIC CAPITAL UPSILON -// 1d731 MATHEMATICAL BOLD ITALIC CAPITAL PHI -// 1d732 MATHEMATICAL BOLD ITALIC CAPITAL CHI -// 1d733 MATHEMATICAL BOLD ITALIC CAPITAL PSI -// 1d734 MATHEMATICAL BOLD ITALIC CAPITAL OMEGA - { 0x1D71C, 0x19, 0x89, 0, 0 }, -// 1d735 MATHEMATICAL BOLD ITALIC NABLA - { 0x1D735, 0x1, 0x8, 0, 0 }, -// 1d736 MATHEMATICAL BOLD ITALIC SMALL ALPHA -// 1d737 MATHEMATICAL BOLD ITALIC SMALL BETA -// 1d738 MATHEMATICAL BOLD ITALIC SMALL GAMMA -// 1d739 MATHEMATICAL BOLD ITALIC SMALL DELTA -// 1d73a MATHEMATICAL BOLD ITALIC SMALL EPSILON -// 1d73b MATHEMATICAL BOLD ITALIC SMALL ZETA -// 1d73c MATHEMATICAL BOLD ITALIC SMALL ETA -// 1d73d MATHEMATICAL BOLD ITALIC SMALL THETA -// 1d73e MATHEMATICAL BOLD ITALIC SMALL IOTA -// 1d73f MATHEMATICAL BOLD ITALIC SMALL KAPPA -// 1d740 MATHEMATICAL BOLD ITALIC SMALL LAMDA -// 1d741 MATHEMATICAL BOLD ITALIC SMALL MU -// 1d742 MATHEMATICAL BOLD ITALIC SMALL NU -// 1d743 MATHEMATICAL BOLD ITALIC SMALL XI -// 1d744 MATHEMATICAL BOLD ITALIC SMALL OMICRON -// 1d745 MATHEMATICAL BOLD ITALIC SMALL PI -// 1d746 MATHEMATICAL BOLD ITALIC SMALL RHO -// 1d747 MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA -// 1d748 MATHEMATICAL BOLD ITALIC SMALL SIGMA -// 1d749 MATHEMATICAL BOLD ITALIC SMALL TAU -// 1d74a MATHEMATICAL BOLD ITALIC SMALL UPSILON -// 1d74b MATHEMATICAL BOLD ITALIC SMALL PHI -// 1d74c MATHEMATICAL BOLD ITALIC SMALL CHI -// 1d74d MATHEMATICAL BOLD ITALIC SMALL PSI -// 1d74e MATHEMATICAL BOLD ITALIC SMALL OMEGA - { 0x1D736, 0x19, 0x49, 0, 0 }, -// 1d74f MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL - { 0x1D74F, 0x1, 0x8, 0, 0 }, -// 1d750 MATHEMATICAL BOLD ITALIC EPSILON SYMBOL -// 1d751 MATHEMATICAL BOLD ITALIC THETA SYMBOL -// 1d752 MATHEMATICAL BOLD ITALIC KAPPA SYMBOL -// 1d753 MATHEMATICAL BOLD ITALIC PHI SYMBOL -// 1d754 MATHEMATICAL BOLD ITALIC RHO SYMBOL -// 1d755 MATHEMATICAL BOLD ITALIC PI SYMBOL - { 0x1D750, 0x6, 0x49, 0, 0 }, -// 1d756 MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA -// 1d757 MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA -// 1d758 MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA -// 1d759 MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA -// 1d75a MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON -// 1d75b MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA -// 1d75c MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA -// 1d75d MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA -// 1d75e MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA -// 1d75f MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA -// 1d760 MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA -// 1d761 MATHEMATICAL SANS-SERIF BOLD CAPITAL MU -// 1d762 MATHEMATICAL SANS-SERIF BOLD CAPITAL NU -// 1d763 MATHEMATICAL SANS-SERIF BOLD CAPITAL XI -// 1d764 MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON -// 1d765 MATHEMATICAL SANS-SERIF BOLD CAPITAL PI -// 1d766 MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO -// 1d767 MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL -// 1d768 MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA -// 1d769 MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU -// 1d76a MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON -// 1d76b MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI -// 1d76c MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI -// 1d76d MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI -// 1d76e MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA - { 0x1D756, 0x19, 0x89, 0, 0 }, -// 1d76f MATHEMATICAL SANS-SERIF BOLD NABLA - { 0x1D76F, 0x1, 0x8, 0, 0 }, -// 1d770 MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA -// 1d771 MATHEMATICAL SANS-SERIF BOLD SMALL BETA -// 1d772 MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA -// 1d773 MATHEMATICAL SANS-SERIF BOLD SMALL DELTA -// 1d774 MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON -// 1d775 MATHEMATICAL SANS-SERIF BOLD SMALL ZETA -// 1d776 MATHEMATICAL SANS-SERIF BOLD SMALL ETA -// 1d777 MATHEMATICAL SANS-SERIF BOLD SMALL THETA -// 1d778 MATHEMATICAL SANS-SERIF BOLD SMALL IOTA -// 1d779 MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA -// 1d77a MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA -// 1d77b MATHEMATICAL SANS-SERIF BOLD SMALL MU -// 1d77c MATHEMATICAL SANS-SERIF BOLD SMALL NU -// 1d77d MATHEMATICAL SANS-SERIF BOLD SMALL XI -// 1d77e MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON -// 1d77f MATHEMATICAL SANS-SERIF BOLD SMALL PI -// 1d780 MATHEMATICAL SANS-SERIF BOLD SMALL RHO -// 1d781 MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA -// 1d782 MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA -// 1d783 MATHEMATICAL SANS-SERIF BOLD SMALL TAU -// 1d784 MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON -// 1d785 MATHEMATICAL SANS-SERIF BOLD SMALL PHI -// 1d786 MATHEMATICAL SANS-SERIF BOLD SMALL CHI -// 1d787 MATHEMATICAL SANS-SERIF BOLD SMALL PSI -// 1d788 MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA - { 0x1D770, 0x19, 0x49, 0, 0 }, -// 1d789 MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL - { 0x1D789, 0x1, 0x8, 0, 0 }, -// 1d78a MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL -// 1d78b MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL -// 1d78c MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL -// 1d78d MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL -// 1d78e MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL -// 1d78f MATHEMATICAL SANS-SERIF BOLD PI SYMBOL - { 0x1D78A, 0x6, 0x49, 0, 0 }, -// 1d790 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA -// 1d791 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA -// 1d792 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA -// 1d793 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA -// 1d794 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON -// 1d795 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA -// 1d796 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA -// 1d797 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA -// 1d798 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA -// 1d799 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA -// 1d79a MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA -// 1d79b MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU -// 1d79c MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU -// 1d79d MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI -// 1d79e MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON -// 1d79f MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI -// 1d7a0 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO -// 1d7a1 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL -// 1d7a2 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA -// 1d7a3 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU -// 1d7a4 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON -// 1d7a5 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI -// 1d7a6 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI -// 1d7a7 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI -// 1d7a8 MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA - { 0x1D790, 0x19, 0x89, 0, 0 }, -// 1d7a9 MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA - { 0x1D7A9, 0x1, 0x8, 0, 0 }, -// 1d7aa MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA -// 1d7ab MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA -// 1d7ac MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA -// 1d7ad MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA -// 1d7ae MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON -// 1d7af MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA -// 1d7b0 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA -// 1d7b1 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA -// 1d7b2 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA -// 1d7b3 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA -// 1d7b4 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA -// 1d7b5 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU -// 1d7b6 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU -// 1d7b7 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI -// 1d7b8 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON -// 1d7b9 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI -// 1d7ba MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO -// 1d7bb MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA -// 1d7bc MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA -// 1d7bd MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU -// 1d7be MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON -// 1d7bf MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI -// 1d7c0 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI -// 1d7c1 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI -// 1d7c2 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA - { 0x1D7AA, 0x19, 0x49, 0, 0 }, -// 1d7c3 MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL - { 0x1D7C3, 0x1, 0x8, 0, 0 }, -// 1d7c4 MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL -// 1d7c5 MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL -// 1d7c6 MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL -// 1d7c7 MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL -// 1d7c8 MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL -// 1d7c9 MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL - { 0x1D7C4, 0x6, 0x49, 0, 0 }, -// 1d7ca MATHEMATICAL BOLD CAPITAL DIGAMMA - { 0x1D7CA, 0x1, 0x89, 0, 0 }, -// 1d7cb MATHEMATICAL BOLD SMALL DIGAMMA - { 0x1D7CB, 0x1, 0x49, 0, 0 }, -// 1d7ce MATHEMATICAL BOLD DIGIT ZERO -// 1d7cf MATHEMATICAL BOLD DIGIT ONE -// 1d7d0 MATHEMATICAL BOLD DIGIT TWO -// 1d7d1 MATHEMATICAL BOLD DIGIT THREE -// 1d7d2 MATHEMATICAL BOLD DIGIT FOUR -// 1d7d3 MATHEMATICAL BOLD DIGIT FIVE -// 1d7d4 MATHEMATICAL BOLD DIGIT SIX -// 1d7d5 MATHEMATICAL BOLD DIGIT SEVEN -// 1d7d6 MATHEMATICAL BOLD DIGIT EIGHT -// 1d7d7 MATHEMATICAL BOLD DIGIT NINE -// 1d7d8 MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO -// 1d7d9 MATHEMATICAL DOUBLE-STRUCK DIGIT ONE -// 1d7da MATHEMATICAL DOUBLE-STRUCK DIGIT TWO -// 1d7db MATHEMATICAL DOUBLE-STRUCK DIGIT THREE -// 1d7dc MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR -// 1d7dd MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE -// 1d7de MATHEMATICAL DOUBLE-STRUCK DIGIT SIX -// 1d7df MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN -// 1d7e0 MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT -// 1d7e1 MATHEMATICAL DOUBLE-STRUCK DIGIT NINE -// 1d7e2 MATHEMATICAL SANS-SERIF DIGIT ZERO -// 1d7e3 MATHEMATICAL SANS-SERIF DIGIT ONE -// 1d7e4 MATHEMATICAL SANS-SERIF DIGIT TWO -// 1d7e5 MATHEMATICAL SANS-SERIF DIGIT THREE -// 1d7e6 MATHEMATICAL SANS-SERIF DIGIT FOUR -// 1d7e7 MATHEMATICAL SANS-SERIF DIGIT FIVE -// 1d7e8 MATHEMATICAL SANS-SERIF DIGIT SIX -// 1d7e9 MATHEMATICAL SANS-SERIF DIGIT SEVEN -// 1d7ea MATHEMATICAL SANS-SERIF DIGIT EIGHT -// 1d7eb MATHEMATICAL SANS-SERIF DIGIT NINE -// 1d7ec MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO -// 1d7ed MATHEMATICAL SANS-SERIF BOLD DIGIT ONE -// 1d7ee MATHEMATICAL SANS-SERIF BOLD DIGIT TWO -// 1d7ef MATHEMATICAL SANS-SERIF BOLD DIGIT THREE -// 1d7f0 MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR -// 1d7f1 MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE -// 1d7f2 MATHEMATICAL SANS-SERIF BOLD DIGIT SIX -// 1d7f3 MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN -// 1d7f4 MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT -// 1d7f5 MATHEMATICAL SANS-SERIF BOLD DIGIT NINE -// 1d7f6 MATHEMATICAL MONOSPACE DIGIT ZERO -// 1d7f7 MATHEMATICAL MONOSPACE DIGIT ONE -// 1d7f8 MATHEMATICAL MONOSPACE DIGIT TWO -// 1d7f9 MATHEMATICAL MONOSPACE DIGIT THREE -// 1d7fa MATHEMATICAL MONOSPACE DIGIT FOUR -// 1d7fb MATHEMATICAL MONOSPACE DIGIT FIVE -// 1d7fc MATHEMATICAL MONOSPACE DIGIT SIX -// 1d7fd MATHEMATICAL MONOSPACE DIGIT SEVEN -// 1d7fe MATHEMATICAL MONOSPACE DIGIT EIGHT -// 1d7ff MATHEMATICAL MONOSPACE DIGIT NINE - { 0x1D7CE, 0x32, 0x108, 0, 0 }, -// 1e800 MENDE KIKAKUI SYLLABLE M001 KI -// 1e801 MENDE KIKAKUI SYLLABLE M002 KA -// 1e802 MENDE KIKAKUI SYLLABLE M003 KU -// 1e803 MENDE KIKAKUI SYLLABLE M065 KEE -// 1e804 MENDE KIKAKUI SYLLABLE M095 KE -// 1e805 MENDE KIKAKUI SYLLABLE M076 KOO -// 1e806 MENDE KIKAKUI SYLLABLE M048 KO -// 1e807 MENDE KIKAKUI SYLLABLE M179 KUA -// 1e808 MENDE KIKAKUI SYLLABLE M004 WI -// 1e809 MENDE KIKAKUI SYLLABLE M005 WA -// 1e80a MENDE KIKAKUI SYLLABLE M006 WU -// 1e80b MENDE KIKAKUI SYLLABLE M126 WEE -// 1e80c MENDE KIKAKUI SYLLABLE M118 WE -// 1e80d MENDE KIKAKUI SYLLABLE M114 WOO -// 1e80e MENDE KIKAKUI SYLLABLE M045 WO -// 1e80f MENDE KIKAKUI SYLLABLE M194 WUI -// 1e810 MENDE KIKAKUI SYLLABLE M143 WEI -// 1e811 MENDE KIKAKUI SYLLABLE M061 WVI -// 1e812 MENDE KIKAKUI SYLLABLE M049 WVA -// 1e813 MENDE KIKAKUI SYLLABLE M139 WVE -// 1e814 MENDE KIKAKUI SYLLABLE M007 MIN -// 1e815 MENDE KIKAKUI SYLLABLE M008 MAN -// 1e816 MENDE KIKAKUI SYLLABLE M009 MUN -// 1e817 MENDE KIKAKUI SYLLABLE M059 MEN -// 1e818 MENDE KIKAKUI SYLLABLE M094 MON -// 1e819 MENDE KIKAKUI SYLLABLE M154 MUAN -// 1e81a MENDE KIKAKUI SYLLABLE M189 MUEN -// 1e81b MENDE KIKAKUI SYLLABLE M010 BI -// 1e81c MENDE KIKAKUI SYLLABLE M011 BA -// 1e81d MENDE KIKAKUI SYLLABLE M012 BU -// 1e81e MENDE KIKAKUI SYLLABLE M150 BEE -// 1e81f MENDE KIKAKUI SYLLABLE M097 BE -// 1e820 MENDE KIKAKUI SYLLABLE M103 BOO -// 1e821 MENDE KIKAKUI SYLLABLE M138 BO -// 1e822 MENDE KIKAKUI SYLLABLE M013 I -// 1e823 MENDE KIKAKUI SYLLABLE M014 A -// 1e824 MENDE KIKAKUI SYLLABLE M015 U -// 1e825 MENDE KIKAKUI SYLLABLE M163 EE -// 1e826 MENDE KIKAKUI SYLLABLE M100 E -// 1e827 MENDE KIKAKUI SYLLABLE M165 OO -// 1e828 MENDE KIKAKUI SYLLABLE M147 O -// 1e829 MENDE KIKAKUI SYLLABLE M137 EI -// 1e82a MENDE KIKAKUI SYLLABLE M131 IN -// 1e82b MENDE KIKAKUI SYLLABLE M135 IN -// 1e82c MENDE KIKAKUI SYLLABLE M195 AN -// 1e82d MENDE KIKAKUI SYLLABLE M178 EN -// 1e82e MENDE KIKAKUI SYLLABLE M019 SI -// 1e82f MENDE KIKAKUI SYLLABLE M020 SA -// 1e830 MENDE KIKAKUI SYLLABLE M021 SU -// 1e831 MENDE KIKAKUI SYLLABLE M162 SEE -// 1e832 MENDE KIKAKUI SYLLABLE M116 SE -// 1e833 MENDE KIKAKUI SYLLABLE M136 SOO -// 1e834 MENDE KIKAKUI SYLLABLE M079 SO -// 1e835 MENDE KIKAKUI SYLLABLE M196 SIA -// 1e836 MENDE KIKAKUI SYLLABLE M025 LI -// 1e837 MENDE KIKAKUI SYLLABLE M026 LA -// 1e838 MENDE KIKAKUI SYLLABLE M027 LU -// 1e839 MENDE KIKAKUI SYLLABLE M084 LEE -// 1e83a MENDE KIKAKUI SYLLABLE M073 LE -// 1e83b MENDE KIKAKUI SYLLABLE M054 LOO -// 1e83c MENDE KIKAKUI SYLLABLE M153 LO -// 1e83d MENDE KIKAKUI SYLLABLE M110 LONG LE -// 1e83e MENDE KIKAKUI SYLLABLE M016 DI -// 1e83f MENDE KIKAKUI SYLLABLE M017 DA -// 1e840 MENDE KIKAKUI SYLLABLE M018 DU -// 1e841 MENDE KIKAKUI SYLLABLE M089 DEE -// 1e842 MENDE KIKAKUI SYLLABLE M180 DOO -// 1e843 MENDE KIKAKUI SYLLABLE M181 DO -// 1e844 MENDE KIKAKUI SYLLABLE M022 TI -// 1e845 MENDE KIKAKUI SYLLABLE M023 TA -// 1e846 MENDE KIKAKUI SYLLABLE M024 TU -// 1e847 MENDE KIKAKUI SYLLABLE M091 TEE -// 1e848 MENDE KIKAKUI SYLLABLE M055 TE -// 1e849 MENDE KIKAKUI SYLLABLE M104 TOO -// 1e84a MENDE KIKAKUI SYLLABLE M069 TO -// 1e84b MENDE KIKAKUI SYLLABLE M028 JI -// 1e84c MENDE KIKAKUI SYLLABLE M029 JA -// 1e84d MENDE KIKAKUI SYLLABLE M030 JU -// 1e84e MENDE KIKAKUI SYLLABLE M157 JEE -// 1e84f MENDE KIKAKUI SYLLABLE M113 JE -// 1e850 MENDE KIKAKUI SYLLABLE M160 JOO -// 1e851 MENDE KIKAKUI SYLLABLE M063 JO -// 1e852 MENDE KIKAKUI SYLLABLE M175 LONG JO -// 1e853 MENDE KIKAKUI SYLLABLE M031 YI -// 1e854 MENDE KIKAKUI SYLLABLE M032 YA -// 1e855 MENDE KIKAKUI SYLLABLE M033 YU -// 1e856 MENDE KIKAKUI SYLLABLE M109 YEE -// 1e857 MENDE KIKAKUI SYLLABLE M080 YE -// 1e858 MENDE KIKAKUI SYLLABLE M141 YOO -// 1e859 MENDE KIKAKUI SYLLABLE M121 YO -// 1e85a MENDE KIKAKUI SYLLABLE M034 FI -// 1e85b MENDE KIKAKUI SYLLABLE M035 FA -// 1e85c MENDE KIKAKUI SYLLABLE M036 FU -// 1e85d MENDE KIKAKUI SYLLABLE M078 FEE -// 1e85e MENDE KIKAKUI SYLLABLE M075 FE -// 1e85f MENDE KIKAKUI SYLLABLE M133 FOO -// 1e860 MENDE KIKAKUI SYLLABLE M088 FO -// 1e861 MENDE KIKAKUI SYLLABLE M197 FUA -// 1e862 MENDE KIKAKUI SYLLABLE M101 FAN -// 1e863 MENDE KIKAKUI SYLLABLE M037 NIN -// 1e864 MENDE KIKAKUI SYLLABLE M038 NAN -// 1e865 MENDE KIKAKUI SYLLABLE M039 NUN -// 1e866 MENDE KIKAKUI SYLLABLE M117 NEN -// 1e867 MENDE KIKAKUI SYLLABLE M169 NON -// 1e868 MENDE KIKAKUI SYLLABLE M176 HI -// 1e869 MENDE KIKAKUI SYLLABLE M041 HA -// 1e86a MENDE KIKAKUI SYLLABLE M186 HU -// 1e86b MENDE KIKAKUI SYLLABLE M040 HEE -// 1e86c MENDE KIKAKUI SYLLABLE M096 HE -// 1e86d MENDE KIKAKUI SYLLABLE M042 HOO -// 1e86e MENDE KIKAKUI SYLLABLE M140 HO -// 1e86f MENDE KIKAKUI SYLLABLE M083 HEEI -// 1e870 MENDE KIKAKUI SYLLABLE M128 HOOU -// 1e871 MENDE KIKAKUI SYLLABLE M053 HIN -// 1e872 MENDE KIKAKUI SYLLABLE M130 HAN -// 1e873 MENDE KIKAKUI SYLLABLE M087 HUN -// 1e874 MENDE KIKAKUI SYLLABLE M052 HEN -// 1e875 MENDE KIKAKUI SYLLABLE M193 HON -// 1e876 MENDE KIKAKUI SYLLABLE M046 HUAN -// 1e877 MENDE KIKAKUI SYLLABLE M090 NGGI -// 1e878 MENDE KIKAKUI SYLLABLE M043 NGGA -// 1e879 MENDE KIKAKUI SYLLABLE M082 NGGU -// 1e87a MENDE KIKAKUI SYLLABLE M115 NGGEE -// 1e87b MENDE KIKAKUI SYLLABLE M146 NGGE -// 1e87c MENDE KIKAKUI SYLLABLE M156 NGGOO -// 1e87d MENDE KIKAKUI SYLLABLE M120 NGGO -// 1e87e MENDE KIKAKUI SYLLABLE M159 NGGAA -// 1e87f MENDE KIKAKUI SYLLABLE M127 NGGUA -// 1e880 MENDE KIKAKUI SYLLABLE M086 LONG NGGE -// 1e881 MENDE KIKAKUI SYLLABLE M106 LONG NGGOO -// 1e882 MENDE KIKAKUI SYLLABLE M183 LONG NGGO -// 1e883 MENDE KIKAKUI SYLLABLE M155 GI -// 1e884 MENDE KIKAKUI SYLLABLE M111 GA -// 1e885 MENDE KIKAKUI SYLLABLE M168 GU -// 1e886 MENDE KIKAKUI SYLLABLE M190 GEE -// 1e887 MENDE KIKAKUI SYLLABLE M166 GUEI -// 1e888 MENDE KIKAKUI SYLLABLE M167 GUAN -// 1e889 MENDE KIKAKUI SYLLABLE M184 NGEN -// 1e88a MENDE KIKAKUI SYLLABLE M057 NGON -// 1e88b MENDE KIKAKUI SYLLABLE M177 NGUAN -// 1e88c MENDE KIKAKUI SYLLABLE M068 PI -// 1e88d MENDE KIKAKUI SYLLABLE M099 PA -// 1e88e MENDE KIKAKUI SYLLABLE M050 PU -// 1e88f MENDE KIKAKUI SYLLABLE M081 PEE -// 1e890 MENDE KIKAKUI SYLLABLE M051 PE -// 1e891 MENDE KIKAKUI SYLLABLE M102 POO -// 1e892 MENDE KIKAKUI SYLLABLE M066 PO -// 1e893 MENDE KIKAKUI SYLLABLE M145 MBI -// 1e894 MENDE KIKAKUI SYLLABLE M062 MBA -// 1e895 MENDE KIKAKUI SYLLABLE M122 MBU -// 1e896 MENDE KIKAKUI SYLLABLE M047 MBEE -// 1e897 MENDE KIKAKUI SYLLABLE M188 MBEE -// 1e898 MENDE KIKAKUI SYLLABLE M072 MBE -// 1e899 MENDE KIKAKUI SYLLABLE M172 MBOO -// 1e89a MENDE KIKAKUI SYLLABLE M174 MBO -// 1e89b MENDE KIKAKUI SYLLABLE M187 MBUU -// 1e89c MENDE KIKAKUI SYLLABLE M161 LONG MBE -// 1e89d MENDE KIKAKUI SYLLABLE M105 LONG MBOO -// 1e89e MENDE KIKAKUI SYLLABLE M142 LONG MBO -// 1e89f MENDE KIKAKUI SYLLABLE M132 KPI -// 1e8a0 MENDE KIKAKUI SYLLABLE M092 KPA -// 1e8a1 MENDE KIKAKUI SYLLABLE M074 KPU -// 1e8a2 MENDE KIKAKUI SYLLABLE M044 KPEE -// 1e8a3 MENDE KIKAKUI SYLLABLE M108 KPE -// 1e8a4 MENDE KIKAKUI SYLLABLE M112 KPOO -// 1e8a5 MENDE KIKAKUI SYLLABLE M158 KPO -// 1e8a6 MENDE KIKAKUI SYLLABLE M124 GBI -// 1e8a7 MENDE KIKAKUI SYLLABLE M056 GBA -// 1e8a8 MENDE KIKAKUI SYLLABLE M148 GBU -// 1e8a9 MENDE KIKAKUI SYLLABLE M093 GBEE -// 1e8aa MENDE KIKAKUI SYLLABLE M107 GBE -// 1e8ab MENDE KIKAKUI SYLLABLE M071 GBOO -// 1e8ac MENDE KIKAKUI SYLLABLE M070 GBO -// 1e8ad MENDE KIKAKUI SYLLABLE M171 RA -// 1e8ae MENDE KIKAKUI SYLLABLE M123 NDI -// 1e8af MENDE KIKAKUI SYLLABLE M129 NDA -// 1e8b0 MENDE KIKAKUI SYLLABLE M125 NDU -// 1e8b1 MENDE KIKAKUI SYLLABLE M191 NDEE -// 1e8b2 MENDE KIKAKUI SYLLABLE M119 NDE -// 1e8b3 MENDE KIKAKUI SYLLABLE M067 NDOO -// 1e8b4 MENDE KIKAKUI SYLLABLE M064 NDO -// 1e8b5 MENDE KIKAKUI SYLLABLE M152 NJA -// 1e8b6 MENDE KIKAKUI SYLLABLE M192 NJU -// 1e8b7 MENDE KIKAKUI SYLLABLE M149 NJEE -// 1e8b8 MENDE KIKAKUI SYLLABLE M134 NJOO -// 1e8b9 MENDE KIKAKUI SYLLABLE M182 VI -// 1e8ba MENDE KIKAKUI SYLLABLE M185 VA -// 1e8bb MENDE KIKAKUI SYLLABLE M151 VU -// 1e8bc MENDE KIKAKUI SYLLABLE M173 VEE -// 1e8bd MENDE KIKAKUI SYLLABLE M085 VE -// 1e8be MENDE KIKAKUI SYLLABLE M144 VOO -// 1e8bf MENDE KIKAKUI SYLLABLE M077 VO -// 1e8c0 MENDE KIKAKUI SYLLABLE M164 NYIN -// 1e8c1 MENDE KIKAKUI SYLLABLE M058 NYAN -// 1e8c2 MENDE KIKAKUI SYLLABLE M170 NYUN -// 1e8c3 MENDE KIKAKUI SYLLABLE M098 NYEN -// 1e8c4 MENDE KIKAKUI SYLLABLE M060 NYON - { 0x1E800, 0xC5, 0x9, 0, 0 }, -// 1e8c7 MENDE KIKAKUI DIGIT ONE -// 1e8c8 MENDE KIKAKUI DIGIT TWO -// 1e8c9 MENDE KIKAKUI DIGIT THREE -// 1e8ca MENDE KIKAKUI DIGIT FOUR -// 1e8cb MENDE KIKAKUI DIGIT FIVE -// 1e8cc MENDE KIKAKUI DIGIT SIX -// 1e8cd MENDE KIKAKUI DIGIT SEVEN -// 1e8ce MENDE KIKAKUI DIGIT EIGHT -// 1e8cf MENDE KIKAKUI DIGIT NINE - { 0x1E8C7, 0x9, 0x8, 0, 0 }, -// 1e8d0 MENDE KIKAKUI COMBINING NUMBER TEENS -// 1e8d1 MENDE KIKAKUI COMBINING NUMBER TENS -// 1e8d2 MENDE KIKAKUI COMBINING NUMBER HUNDREDS -// 1e8d3 MENDE KIKAKUI COMBINING NUMBER THOUSANDS -// 1e8d4 MENDE KIKAKUI COMBINING NUMBER TEN THOUSANDS -// 1e8d5 MENDE KIKAKUI COMBINING NUMBER HUNDRED THOUSANDS -// 1e8d6 MENDE KIKAKUI COMBINING NUMBER MILLIONS - { 0x1E8D0, 0x7, 0x0, 0, 0 }, -// 1ee00 ARABIC MATHEMATICAL ALEF -// 1ee01 ARABIC MATHEMATICAL BEH -// 1ee02 ARABIC MATHEMATICAL JEEM -// 1ee03 ARABIC MATHEMATICAL DAL - { 0x1EE00, 0x4, 0x9, 0, 0 }, -// 1ee05 ARABIC MATHEMATICAL WAW -// 1ee06 ARABIC MATHEMATICAL ZAIN -// 1ee07 ARABIC MATHEMATICAL HAH -// 1ee08 ARABIC MATHEMATICAL TAH -// 1ee09 ARABIC MATHEMATICAL YEH -// 1ee0a ARABIC MATHEMATICAL KAF -// 1ee0b ARABIC MATHEMATICAL LAM -// 1ee0c ARABIC MATHEMATICAL MEEM -// 1ee0d ARABIC MATHEMATICAL NOON -// 1ee0e ARABIC MATHEMATICAL SEEN -// 1ee0f ARABIC MATHEMATICAL AIN -// 1ee10 ARABIC MATHEMATICAL FEH -// 1ee11 ARABIC MATHEMATICAL SAD -// 1ee12 ARABIC MATHEMATICAL QAF -// 1ee13 ARABIC MATHEMATICAL REH -// 1ee14 ARABIC MATHEMATICAL SHEEN -// 1ee15 ARABIC MATHEMATICAL TEH -// 1ee16 ARABIC MATHEMATICAL THEH -// 1ee17 ARABIC MATHEMATICAL KHAH -// 1ee18 ARABIC MATHEMATICAL THAL -// 1ee19 ARABIC MATHEMATICAL DAD -// 1ee1a ARABIC MATHEMATICAL ZAH -// 1ee1b ARABIC MATHEMATICAL GHAIN -// 1ee1c ARABIC MATHEMATICAL DOTLESS BEH -// 1ee1d ARABIC MATHEMATICAL DOTLESS NOON -// 1ee1e ARABIC MATHEMATICAL DOTLESS FEH -// 1ee1f ARABIC MATHEMATICAL DOTLESS QAF - { 0x1EE05, 0x1B, 0x9, 0, 0 }, -// 1ee21 ARABIC MATHEMATICAL INITIAL BEH -// 1ee22 ARABIC MATHEMATICAL INITIAL JEEM - { 0x1EE21, 0x2, 0x9, 0, 0 }, -// 1ee24 ARABIC MATHEMATICAL INITIAL HEH - { 0x1EE24, 0x1, 0x9, 0, 0 }, -// 1ee27 ARABIC MATHEMATICAL INITIAL HAH - { 0x1EE27, 0x1, 0x9, 0, 0 }, -// 1ee29 ARABIC MATHEMATICAL INITIAL YEH -// 1ee2a ARABIC MATHEMATICAL INITIAL KAF -// 1ee2b ARABIC MATHEMATICAL INITIAL LAM -// 1ee2c ARABIC MATHEMATICAL INITIAL MEEM -// 1ee2d ARABIC MATHEMATICAL INITIAL NOON -// 1ee2e ARABIC MATHEMATICAL INITIAL SEEN -// 1ee2f ARABIC MATHEMATICAL INITIAL AIN -// 1ee30 ARABIC MATHEMATICAL INITIAL FEH -// 1ee31 ARABIC MATHEMATICAL INITIAL SAD -// 1ee32 ARABIC MATHEMATICAL INITIAL QAF - { 0x1EE29, 0xA, 0x9, 0, 0 }, -// 1ee34 ARABIC MATHEMATICAL INITIAL SHEEN -// 1ee35 ARABIC MATHEMATICAL INITIAL TEH -// 1ee36 ARABIC MATHEMATICAL INITIAL THEH -// 1ee37 ARABIC MATHEMATICAL INITIAL KHAH - { 0x1EE34, 0x4, 0x9, 0, 0 }, -// 1ee39 ARABIC MATHEMATICAL INITIAL DAD - { 0x1EE39, 0x1, 0x9, 0, 0 }, -// 1ee3b ARABIC MATHEMATICAL INITIAL GHAIN - { 0x1EE3B, 0x1, 0x9, 0, 0 }, -// 1ee42 ARABIC MATHEMATICAL TAILED JEEM - { 0x1EE42, 0x1, 0x9, 0, 0 }, -// 1ee47 ARABIC MATHEMATICAL TAILED HAH - { 0x1EE47, 0x1, 0x9, 0, 0 }, -// 1ee49 ARABIC MATHEMATICAL TAILED YEH - { 0x1EE49, 0x1, 0x9, 0, 0 }, -// 1ee4b ARABIC MATHEMATICAL TAILED LAM - { 0x1EE4B, 0x1, 0x9, 0, 0 }, -// 1ee4d ARABIC MATHEMATICAL TAILED NOON -// 1ee4e ARABIC MATHEMATICAL TAILED SEEN -// 1ee4f ARABIC MATHEMATICAL TAILED AIN - { 0x1EE4D, 0x3, 0x9, 0, 0 }, -// 1ee51 ARABIC MATHEMATICAL TAILED SAD -// 1ee52 ARABIC MATHEMATICAL TAILED QAF - { 0x1EE51, 0x2, 0x9, 0, 0 }, -// 1ee54 ARABIC MATHEMATICAL TAILED SHEEN - { 0x1EE54, 0x1, 0x9, 0, 0 }, -// 1ee57 ARABIC MATHEMATICAL TAILED KHAH - { 0x1EE57, 0x1, 0x9, 0, 0 }, -// 1ee59 ARABIC MATHEMATICAL TAILED DAD - { 0x1EE59, 0x1, 0x9, 0, 0 }, -// 1ee5b ARABIC MATHEMATICAL TAILED GHAIN - { 0x1EE5B, 0x1, 0x9, 0, 0 }, -// 1ee5d ARABIC MATHEMATICAL TAILED DOTLESS NOON - { 0x1EE5D, 0x1, 0x9, 0, 0 }, -// 1ee5f ARABIC MATHEMATICAL TAILED DOTLESS QAF - { 0x1EE5F, 0x1, 0x9, 0, 0 }, -// 1ee61 ARABIC MATHEMATICAL STRETCHED BEH -// 1ee62 ARABIC MATHEMATICAL STRETCHED JEEM - { 0x1EE61, 0x2, 0x9, 0, 0 }, -// 1ee64 ARABIC MATHEMATICAL STRETCHED HEH - { 0x1EE64, 0x1, 0x9, 0, 0 }, -// 1ee67 ARABIC MATHEMATICAL STRETCHED HAH -// 1ee68 ARABIC MATHEMATICAL STRETCHED TAH -// 1ee69 ARABIC MATHEMATICAL STRETCHED YEH -// 1ee6a ARABIC MATHEMATICAL STRETCHED KAF - { 0x1EE67, 0x4, 0x9, 0, 0 }, -// 1ee6c ARABIC MATHEMATICAL STRETCHED MEEM -// 1ee6d ARABIC MATHEMATICAL STRETCHED NOON -// 1ee6e ARABIC MATHEMATICAL STRETCHED SEEN -// 1ee6f ARABIC MATHEMATICAL STRETCHED AIN -// 1ee70 ARABIC MATHEMATICAL STRETCHED FEH -// 1ee71 ARABIC MATHEMATICAL STRETCHED SAD -// 1ee72 ARABIC MATHEMATICAL STRETCHED QAF - { 0x1EE6C, 0x7, 0x9, 0, 0 }, -// 1ee74 ARABIC MATHEMATICAL STRETCHED SHEEN -// 1ee75 ARABIC MATHEMATICAL STRETCHED TEH -// 1ee76 ARABIC MATHEMATICAL STRETCHED THEH -// 1ee77 ARABIC MATHEMATICAL STRETCHED KHAH - { 0x1EE74, 0x4, 0x9, 0, 0 }, -// 1ee79 ARABIC MATHEMATICAL STRETCHED DAD -// 1ee7a ARABIC MATHEMATICAL STRETCHED ZAH -// 1ee7b ARABIC MATHEMATICAL STRETCHED GHAIN -// 1ee7c ARABIC MATHEMATICAL STRETCHED DOTLESS BEH - { 0x1EE79, 0x4, 0x9, 0, 0 }, -// 1ee7e ARABIC MATHEMATICAL STRETCHED DOTLESS FEH - { 0x1EE7E, 0x1, 0x9, 0, 0 }, -// 1ee80 ARABIC MATHEMATICAL LOOPED ALEF -// 1ee81 ARABIC MATHEMATICAL LOOPED BEH -// 1ee82 ARABIC MATHEMATICAL LOOPED JEEM -// 1ee83 ARABIC MATHEMATICAL LOOPED DAL -// 1ee84 ARABIC MATHEMATICAL LOOPED HEH -// 1ee85 ARABIC MATHEMATICAL LOOPED WAW -// 1ee86 ARABIC MATHEMATICAL LOOPED ZAIN -// 1ee87 ARABIC MATHEMATICAL LOOPED HAH -// 1ee88 ARABIC MATHEMATICAL LOOPED TAH -// 1ee89 ARABIC MATHEMATICAL LOOPED YEH - { 0x1EE80, 0xA, 0x9, 0, 0 }, -// 1ee8b ARABIC MATHEMATICAL LOOPED LAM -// 1ee8c ARABIC MATHEMATICAL LOOPED MEEM -// 1ee8d ARABIC MATHEMATICAL LOOPED NOON -// 1ee8e ARABIC MATHEMATICAL LOOPED SEEN -// 1ee8f ARABIC MATHEMATICAL LOOPED AIN -// 1ee90 ARABIC MATHEMATICAL LOOPED FEH -// 1ee91 ARABIC MATHEMATICAL LOOPED SAD -// 1ee92 ARABIC MATHEMATICAL LOOPED QAF -// 1ee93 ARABIC MATHEMATICAL LOOPED REH -// 1ee94 ARABIC MATHEMATICAL LOOPED SHEEN -// 1ee95 ARABIC MATHEMATICAL LOOPED TEH -// 1ee96 ARABIC MATHEMATICAL LOOPED THEH -// 1ee97 ARABIC MATHEMATICAL LOOPED KHAH -// 1ee98 ARABIC MATHEMATICAL LOOPED THAL -// 1ee99 ARABIC MATHEMATICAL LOOPED DAD -// 1ee9a ARABIC MATHEMATICAL LOOPED ZAH -// 1ee9b ARABIC MATHEMATICAL LOOPED GHAIN - { 0x1EE8B, 0x11, 0x9, 0, 0 }, -// 1eea1 ARABIC MATHEMATICAL DOUBLE-STRUCK BEH -// 1eea2 ARABIC MATHEMATICAL DOUBLE-STRUCK JEEM -// 1eea3 ARABIC MATHEMATICAL DOUBLE-STRUCK DAL - { 0x1EEA1, 0x3, 0x9, 0, 0 }, -// 1eea5 ARABIC MATHEMATICAL DOUBLE-STRUCK WAW -// 1eea6 ARABIC MATHEMATICAL DOUBLE-STRUCK ZAIN -// 1eea7 ARABIC MATHEMATICAL DOUBLE-STRUCK HAH -// 1eea8 ARABIC MATHEMATICAL DOUBLE-STRUCK TAH -// 1eea9 ARABIC MATHEMATICAL DOUBLE-STRUCK YEH - { 0x1EEA5, 0x5, 0x9, 0, 0 }, -// 1eeab ARABIC MATHEMATICAL DOUBLE-STRUCK LAM -// 1eeac ARABIC MATHEMATICAL DOUBLE-STRUCK MEEM -// 1eead ARABIC MATHEMATICAL DOUBLE-STRUCK NOON -// 1eeae ARABIC MATHEMATICAL DOUBLE-STRUCK SEEN -// 1eeaf ARABIC MATHEMATICAL DOUBLE-STRUCK AIN -// 1eeb0 ARABIC MATHEMATICAL DOUBLE-STRUCK FEH -// 1eeb1 ARABIC MATHEMATICAL DOUBLE-STRUCK SAD -// 1eeb2 ARABIC MATHEMATICAL DOUBLE-STRUCK QAF -// 1eeb3 ARABIC MATHEMATICAL DOUBLE-STRUCK REH -// 1eeb4 ARABIC MATHEMATICAL DOUBLE-STRUCK SHEEN -// 1eeb5 ARABIC MATHEMATICAL DOUBLE-STRUCK TEH -// 1eeb6 ARABIC MATHEMATICAL DOUBLE-STRUCK THEH -// 1eeb7 ARABIC MATHEMATICAL DOUBLE-STRUCK KHAH -// 1eeb8 ARABIC MATHEMATICAL DOUBLE-STRUCK THAL -// 1eeb9 ARABIC MATHEMATICAL DOUBLE-STRUCK DAD -// 1eeba ARABIC MATHEMATICAL DOUBLE-STRUCK ZAH -// 1eebb ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN - { 0x1EEAB, 0x11, 0x9, 0, 0 }, -// 1eef0 ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL -// 1eef1 ARABIC MATHEMATICAL OPERATOR HAH WITH DAL - { 0x1EEF0, 0x2, 0x8, 0, 0 }, -// 1f000 MAHJONG TILE EAST WIND -// 1f001 MAHJONG TILE SOUTH WIND -// 1f002 MAHJONG TILE WEST WIND -// 1f003 MAHJONG TILE NORTH WIND -// 1f004 MAHJONG TILE RED DRAGON -// 1f005 MAHJONG TILE GREEN DRAGON -// 1f006 MAHJONG TILE WHITE DRAGON -// 1f007 MAHJONG TILE ONE OF CHARACTERS -// 1f008 MAHJONG TILE TWO OF CHARACTERS -// 1f009 MAHJONG TILE THREE OF CHARACTERS -// 1f00a MAHJONG TILE FOUR OF CHARACTERS -// 1f00b MAHJONG TILE FIVE OF CHARACTERS -// 1f00c MAHJONG TILE SIX OF CHARACTERS -// 1f00d MAHJONG TILE SEVEN OF CHARACTERS -// 1f00e MAHJONG TILE EIGHT OF CHARACTERS -// 1f00f MAHJONG TILE NINE OF CHARACTERS -// 1f010 MAHJONG TILE ONE OF BAMBOOS -// 1f011 MAHJONG TILE TWO OF BAMBOOS -// 1f012 MAHJONG TILE THREE OF BAMBOOS -// 1f013 MAHJONG TILE FOUR OF BAMBOOS -// 1f014 MAHJONG TILE FIVE OF BAMBOOS -// 1f015 MAHJONG TILE SIX OF BAMBOOS -// 1f016 MAHJONG TILE SEVEN OF BAMBOOS -// 1f017 MAHJONG TILE EIGHT OF BAMBOOS -// 1f018 MAHJONG TILE NINE OF BAMBOOS -// 1f019 MAHJONG TILE ONE OF CIRCLES -// 1f01a MAHJONG TILE TWO OF CIRCLES -// 1f01b MAHJONG TILE THREE OF CIRCLES -// 1f01c MAHJONG TILE FOUR OF CIRCLES -// 1f01d MAHJONG TILE FIVE OF CIRCLES -// 1f01e MAHJONG TILE SIX OF CIRCLES -// 1f01f MAHJONG TILE SEVEN OF CIRCLES -// 1f020 MAHJONG TILE EIGHT OF CIRCLES -// 1f021 MAHJONG TILE NINE OF CIRCLES -// 1f022 MAHJONG TILE PLUM -// 1f023 MAHJONG TILE ORCHID -// 1f024 MAHJONG TILE BAMBOO -// 1f025 MAHJONG TILE CHRYSANTHEMUM -// 1f026 MAHJONG TILE SPRING -// 1f027 MAHJONG TILE SUMMER -// 1f028 MAHJONG TILE AUTUMN -// 1f029 MAHJONG TILE WINTER -// 1f02a MAHJONG TILE JOKER -// 1f02b MAHJONG TILE BACK - { 0x1F000, 0x2C, 0x8, 0, 0 }, -// 1f030 DOMINO TILE HORIZONTAL BACK -// 1f031 DOMINO TILE HORIZONTAL-00-00 -// 1f032 DOMINO TILE HORIZONTAL-00-01 -// 1f033 DOMINO TILE HORIZONTAL-00-02 -// 1f034 DOMINO TILE HORIZONTAL-00-03 -// 1f035 DOMINO TILE HORIZONTAL-00-04 -// 1f036 DOMINO TILE HORIZONTAL-00-05 -// 1f037 DOMINO TILE HORIZONTAL-00-06 -// 1f038 DOMINO TILE HORIZONTAL-01-00 -// 1f039 DOMINO TILE HORIZONTAL-01-01 -// 1f03a DOMINO TILE HORIZONTAL-01-02 -// 1f03b DOMINO TILE HORIZONTAL-01-03 -// 1f03c DOMINO TILE HORIZONTAL-01-04 -// 1f03d DOMINO TILE HORIZONTAL-01-05 -// 1f03e DOMINO TILE HORIZONTAL-01-06 -// 1f03f DOMINO TILE HORIZONTAL-02-00 -// 1f040 DOMINO TILE HORIZONTAL-02-01 -// 1f041 DOMINO TILE HORIZONTAL-02-02 -// 1f042 DOMINO TILE HORIZONTAL-02-03 -// 1f043 DOMINO TILE HORIZONTAL-02-04 -// 1f044 DOMINO TILE HORIZONTAL-02-05 -// 1f045 DOMINO TILE HORIZONTAL-02-06 -// 1f046 DOMINO TILE HORIZONTAL-03-00 -// 1f047 DOMINO TILE HORIZONTAL-03-01 -// 1f048 DOMINO TILE HORIZONTAL-03-02 -// 1f049 DOMINO TILE HORIZONTAL-03-03 -// 1f04a DOMINO TILE HORIZONTAL-03-04 -// 1f04b DOMINO TILE HORIZONTAL-03-05 -// 1f04c DOMINO TILE HORIZONTAL-03-06 -// 1f04d DOMINO TILE HORIZONTAL-04-00 -// 1f04e DOMINO TILE HORIZONTAL-04-01 -// 1f04f DOMINO TILE HORIZONTAL-04-02 -// 1f050 DOMINO TILE HORIZONTAL-04-03 -// 1f051 DOMINO TILE HORIZONTAL-04-04 -// 1f052 DOMINO TILE HORIZONTAL-04-05 -// 1f053 DOMINO TILE HORIZONTAL-04-06 -// 1f054 DOMINO TILE HORIZONTAL-05-00 -// 1f055 DOMINO TILE HORIZONTAL-05-01 -// 1f056 DOMINO TILE HORIZONTAL-05-02 -// 1f057 DOMINO TILE HORIZONTAL-05-03 -// 1f058 DOMINO TILE HORIZONTAL-05-04 -// 1f059 DOMINO TILE HORIZONTAL-05-05 -// 1f05a DOMINO TILE HORIZONTAL-05-06 -// 1f05b DOMINO TILE HORIZONTAL-06-00 -// 1f05c DOMINO TILE HORIZONTAL-06-01 -// 1f05d DOMINO TILE HORIZONTAL-06-02 -// 1f05e DOMINO TILE HORIZONTAL-06-03 -// 1f05f DOMINO TILE HORIZONTAL-06-04 -// 1f060 DOMINO TILE HORIZONTAL-06-05 -// 1f061 DOMINO TILE HORIZONTAL-06-06 -// 1f062 DOMINO TILE VERTICAL BACK -// 1f063 DOMINO TILE VERTICAL-00-00 -// 1f064 DOMINO TILE VERTICAL-00-01 -// 1f065 DOMINO TILE VERTICAL-00-02 -// 1f066 DOMINO TILE VERTICAL-00-03 -// 1f067 DOMINO TILE VERTICAL-00-04 -// 1f068 DOMINO TILE VERTICAL-00-05 -// 1f069 DOMINO TILE VERTICAL-00-06 -// 1f06a DOMINO TILE VERTICAL-01-00 -// 1f06b DOMINO TILE VERTICAL-01-01 -// 1f06c DOMINO TILE VERTICAL-01-02 -// 1f06d DOMINO TILE VERTICAL-01-03 -// 1f06e DOMINO TILE VERTICAL-01-04 -// 1f06f DOMINO TILE VERTICAL-01-05 -// 1f070 DOMINO TILE VERTICAL-01-06 -// 1f071 DOMINO TILE VERTICAL-02-00 -// 1f072 DOMINO TILE VERTICAL-02-01 -// 1f073 DOMINO TILE VERTICAL-02-02 -// 1f074 DOMINO TILE VERTICAL-02-03 -// 1f075 DOMINO TILE VERTICAL-02-04 -// 1f076 DOMINO TILE VERTICAL-02-05 -// 1f077 DOMINO TILE VERTICAL-02-06 -// 1f078 DOMINO TILE VERTICAL-03-00 -// 1f079 DOMINO TILE VERTICAL-03-01 -// 1f07a DOMINO TILE VERTICAL-03-02 -// 1f07b DOMINO TILE VERTICAL-03-03 -// 1f07c DOMINO TILE VERTICAL-03-04 -// 1f07d DOMINO TILE VERTICAL-03-05 -// 1f07e DOMINO TILE VERTICAL-03-06 -// 1f07f DOMINO TILE VERTICAL-04-00 -// 1f080 DOMINO TILE VERTICAL-04-01 -// 1f081 DOMINO TILE VERTICAL-04-02 -// 1f082 DOMINO TILE VERTICAL-04-03 -// 1f083 DOMINO TILE VERTICAL-04-04 -// 1f084 DOMINO TILE VERTICAL-04-05 -// 1f085 DOMINO TILE VERTICAL-04-06 -// 1f086 DOMINO TILE VERTICAL-05-00 -// 1f087 DOMINO TILE VERTICAL-05-01 -// 1f088 DOMINO TILE VERTICAL-05-02 -// 1f089 DOMINO TILE VERTICAL-05-03 -// 1f08a DOMINO TILE VERTICAL-05-04 -// 1f08b DOMINO TILE VERTICAL-05-05 -// 1f08c DOMINO TILE VERTICAL-05-06 -// 1f08d DOMINO TILE VERTICAL-06-00 -// 1f08e DOMINO TILE VERTICAL-06-01 -// 1f08f DOMINO TILE VERTICAL-06-02 -// 1f090 DOMINO TILE VERTICAL-06-03 -// 1f091 DOMINO TILE VERTICAL-06-04 -// 1f092 DOMINO TILE VERTICAL-06-05 -// 1f093 DOMINO TILE VERTICAL-06-06 - { 0x1F030, 0x64, 0x8, 0, 0 }, -// 1f0a0 PLAYING CARD BACK -// 1f0a1 PLAYING CARD ACE OF SPADES -// 1f0a2 PLAYING CARD TWO OF SPADES -// 1f0a3 PLAYING CARD THREE OF SPADES -// 1f0a4 PLAYING CARD FOUR OF SPADES -// 1f0a5 PLAYING CARD FIVE OF SPADES -// 1f0a6 PLAYING CARD SIX OF SPADES -// 1f0a7 PLAYING CARD SEVEN OF SPADES -// 1f0a8 PLAYING CARD EIGHT OF SPADES -// 1f0a9 PLAYING CARD NINE OF SPADES -// 1f0aa PLAYING CARD TEN OF SPADES -// 1f0ab PLAYING CARD JACK OF SPADES -// 1f0ac PLAYING CARD KNIGHT OF SPADES -// 1f0ad PLAYING CARD QUEEN OF SPADES -// 1f0ae PLAYING CARD KING OF SPADES - { 0x1F0A0, 0xF, 0x8, 0, 0 }, -// 1f0b1 PLAYING CARD ACE OF HEARTS -// 1f0b2 PLAYING CARD TWO OF HEARTS -// 1f0b3 PLAYING CARD THREE OF HEARTS -// 1f0b4 PLAYING CARD FOUR OF HEARTS -// 1f0b5 PLAYING CARD FIVE OF HEARTS -// 1f0b6 PLAYING CARD SIX OF HEARTS -// 1f0b7 PLAYING CARD SEVEN OF HEARTS -// 1f0b8 PLAYING CARD EIGHT OF HEARTS -// 1f0b9 PLAYING CARD NINE OF HEARTS -// 1f0ba PLAYING CARD TEN OF HEARTS -// 1f0bb PLAYING CARD JACK OF HEARTS -// 1f0bc PLAYING CARD KNIGHT OF HEARTS -// 1f0bd PLAYING CARD QUEEN OF HEARTS -// 1f0be PLAYING CARD KING OF HEARTS -// 1f0bf PLAYING CARD RED JOKER - { 0x1F0B1, 0xF, 0x8, 0, 0 }, -// 1f0c1 PLAYING CARD ACE OF DIAMONDS -// 1f0c2 PLAYING CARD TWO OF DIAMONDS -// 1f0c3 PLAYING CARD THREE OF DIAMONDS -// 1f0c4 PLAYING CARD FOUR OF DIAMONDS -// 1f0c5 PLAYING CARD FIVE OF DIAMONDS -// 1f0c6 PLAYING CARD SIX OF DIAMONDS -// 1f0c7 PLAYING CARD SEVEN OF DIAMONDS -// 1f0c8 PLAYING CARD EIGHT OF DIAMONDS -// 1f0c9 PLAYING CARD NINE OF DIAMONDS -// 1f0ca PLAYING CARD TEN OF DIAMONDS -// 1f0cb PLAYING CARD JACK OF DIAMONDS -// 1f0cc PLAYING CARD KNIGHT OF DIAMONDS -// 1f0cd PLAYING CARD QUEEN OF DIAMONDS -// 1f0ce PLAYING CARD KING OF DIAMONDS -// 1f0cf PLAYING CARD BLACK JOKER - { 0x1F0C1, 0xF, 0x8, 0, 0 }, -// 1f0d1 PLAYING CARD ACE OF CLUBS -// 1f0d2 PLAYING CARD TWO OF CLUBS -// 1f0d3 PLAYING CARD THREE OF CLUBS -// 1f0d4 PLAYING CARD FOUR OF CLUBS -// 1f0d5 PLAYING CARD FIVE OF CLUBS -// 1f0d6 PLAYING CARD SIX OF CLUBS -// 1f0d7 PLAYING CARD SEVEN OF CLUBS -// 1f0d8 PLAYING CARD EIGHT OF CLUBS -// 1f0d9 PLAYING CARD NINE OF CLUBS -// 1f0da PLAYING CARD TEN OF CLUBS -// 1f0db PLAYING CARD JACK OF CLUBS -// 1f0dc PLAYING CARD KNIGHT OF CLUBS -// 1f0dd PLAYING CARD QUEEN OF CLUBS -// 1f0de PLAYING CARD KING OF CLUBS -// 1f0df PLAYING CARD WHITE JOKER -// 1f0e0 PLAYING CARD FOOL -// 1f0e1 PLAYING CARD TRUMP-1 -// 1f0e2 PLAYING CARD TRUMP-2 -// 1f0e3 PLAYING CARD TRUMP-3 -// 1f0e4 PLAYING CARD TRUMP-4 -// 1f0e5 PLAYING CARD TRUMP-5 -// 1f0e6 PLAYING CARD TRUMP-6 -// 1f0e7 PLAYING CARD TRUMP-7 -// 1f0e8 PLAYING CARD TRUMP-8 -// 1f0e9 PLAYING CARD TRUMP-9 -// 1f0ea PLAYING CARD TRUMP-10 -// 1f0eb PLAYING CARD TRUMP-11 -// 1f0ec PLAYING CARD TRUMP-12 -// 1f0ed PLAYING CARD TRUMP-13 -// 1f0ee PLAYING CARD TRUMP-14 -// 1f0ef PLAYING CARD TRUMP-15 -// 1f0f0 PLAYING CARD TRUMP-16 -// 1f0f1 PLAYING CARD TRUMP-17 -// 1f0f2 PLAYING CARD TRUMP-18 -// 1f0f3 PLAYING CARD TRUMP-19 -// 1f0f4 PLAYING CARD TRUMP-20 -// 1f0f5 PLAYING CARD TRUMP-21 - { 0x1F0D1, 0x25, 0x8, 0, 0 }, -// 1f100 DIGIT ZERO FULL STOP -// 1f101 DIGIT ZERO COMMA -// 1f102 DIGIT ONE COMMA -// 1f103 DIGIT TWO COMMA -// 1f104 DIGIT THREE COMMA -// 1f105 DIGIT FOUR COMMA -// 1f106 DIGIT FIVE COMMA -// 1f107 DIGIT SIX COMMA -// 1f108 DIGIT SEVEN COMMA -// 1f109 DIGIT EIGHT COMMA -// 1f10a DIGIT NINE COMMA -// 1f10b DINGBAT CIRCLED SANS-SERIF DIGIT ZERO -// 1f10c DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO - { 0x1F100, 0xD, 0x8, 0, 0 }, -// 1f110 PARENTHESIZED LATIN CAPITAL LETTER A -// 1f111 PARENTHESIZED LATIN CAPITAL LETTER B -// 1f112 PARENTHESIZED LATIN CAPITAL LETTER C -// 1f113 PARENTHESIZED LATIN CAPITAL LETTER D -// 1f114 PARENTHESIZED LATIN CAPITAL LETTER E -// 1f115 PARENTHESIZED LATIN CAPITAL LETTER F -// 1f116 PARENTHESIZED LATIN CAPITAL LETTER G -// 1f117 PARENTHESIZED LATIN CAPITAL LETTER H -// 1f118 PARENTHESIZED LATIN CAPITAL LETTER I -// 1f119 PARENTHESIZED LATIN CAPITAL LETTER J -// 1f11a PARENTHESIZED LATIN CAPITAL LETTER K -// 1f11b PARENTHESIZED LATIN CAPITAL LETTER L -// 1f11c PARENTHESIZED LATIN CAPITAL LETTER M -// 1f11d PARENTHESIZED LATIN CAPITAL LETTER N -// 1f11e PARENTHESIZED LATIN CAPITAL LETTER O -// 1f11f PARENTHESIZED LATIN CAPITAL LETTER P -// 1f120 PARENTHESIZED LATIN CAPITAL LETTER Q -// 1f121 PARENTHESIZED LATIN CAPITAL LETTER R -// 1f122 PARENTHESIZED LATIN CAPITAL LETTER S -// 1f123 PARENTHESIZED LATIN CAPITAL LETTER T -// 1f124 PARENTHESIZED LATIN CAPITAL LETTER U -// 1f125 PARENTHESIZED LATIN CAPITAL LETTER V -// 1f126 PARENTHESIZED LATIN CAPITAL LETTER W -// 1f127 PARENTHESIZED LATIN CAPITAL LETTER X -// 1f128 PARENTHESIZED LATIN CAPITAL LETTER Y -// 1f129 PARENTHESIZED LATIN CAPITAL LETTER Z -// 1f12a TORTOISE SHELL BRACKETED LATIN CAPITAL LETTER S -// 1f12b CIRCLED ITALIC LATIN CAPITAL LETTER C -// 1f12c CIRCLED ITALIC LATIN CAPITAL LETTER R -// 1f12d CIRCLED CD -// 1f12e CIRCLED WZ - { 0x1F110, 0x1F, 0x8, 0, 0 }, -// 1f130 SQUARED LATIN CAPITAL LETTER A -// 1f131 SQUARED LATIN CAPITAL LETTER B -// 1f132 SQUARED LATIN CAPITAL LETTER C -// 1f133 SQUARED LATIN CAPITAL LETTER D -// 1f134 SQUARED LATIN CAPITAL LETTER E -// 1f135 SQUARED LATIN CAPITAL LETTER F -// 1f136 SQUARED LATIN CAPITAL LETTER G -// 1f137 SQUARED LATIN CAPITAL LETTER H -// 1f138 SQUARED LATIN CAPITAL LETTER I -// 1f139 SQUARED LATIN CAPITAL LETTER J -// 1f13a SQUARED LATIN CAPITAL LETTER K -// 1f13b SQUARED LATIN CAPITAL LETTER L -// 1f13c SQUARED LATIN CAPITAL LETTER M -// 1f13d SQUARED LATIN CAPITAL LETTER N -// 1f13e SQUARED LATIN CAPITAL LETTER O -// 1f13f SQUARED LATIN CAPITAL LETTER P -// 1f140 SQUARED LATIN CAPITAL LETTER Q -// 1f141 SQUARED LATIN CAPITAL LETTER R -// 1f142 SQUARED LATIN CAPITAL LETTER S -// 1f143 SQUARED LATIN CAPITAL LETTER T -// 1f144 SQUARED LATIN CAPITAL LETTER U -// 1f145 SQUARED LATIN CAPITAL LETTER V -// 1f146 SQUARED LATIN CAPITAL LETTER W -// 1f147 SQUARED LATIN CAPITAL LETTER X -// 1f148 SQUARED LATIN CAPITAL LETTER Y -// 1f149 SQUARED LATIN CAPITAL LETTER Z -// 1f14a SQUARED HV -// 1f14b SQUARED MV -// 1f14c SQUARED SD -// 1f14d SQUARED SS -// 1f14e SQUARED PPV -// 1f14f SQUARED WC -// 1f150 NEGATIVE CIRCLED LATIN CAPITAL LETTER A -// 1f151 NEGATIVE CIRCLED LATIN CAPITAL LETTER B -// 1f152 NEGATIVE CIRCLED LATIN CAPITAL LETTER C -// 1f153 NEGATIVE CIRCLED LATIN CAPITAL LETTER D -// 1f154 NEGATIVE CIRCLED LATIN CAPITAL LETTER E -// 1f155 NEGATIVE CIRCLED LATIN CAPITAL LETTER F -// 1f156 NEGATIVE CIRCLED LATIN CAPITAL LETTER G -// 1f157 NEGATIVE CIRCLED LATIN CAPITAL LETTER H -// 1f158 NEGATIVE CIRCLED LATIN CAPITAL LETTER I -// 1f159 NEGATIVE CIRCLED LATIN CAPITAL LETTER J -// 1f15a NEGATIVE CIRCLED LATIN CAPITAL LETTER K -// 1f15b NEGATIVE CIRCLED LATIN CAPITAL LETTER L -// 1f15c NEGATIVE CIRCLED LATIN CAPITAL LETTER M -// 1f15d NEGATIVE CIRCLED LATIN CAPITAL LETTER N -// 1f15e NEGATIVE CIRCLED LATIN CAPITAL LETTER O -// 1f15f NEGATIVE CIRCLED LATIN CAPITAL LETTER P -// 1f160 NEGATIVE CIRCLED LATIN CAPITAL LETTER Q -// 1f161 NEGATIVE CIRCLED LATIN CAPITAL LETTER R -// 1f162 NEGATIVE CIRCLED LATIN CAPITAL LETTER S -// 1f163 NEGATIVE CIRCLED LATIN CAPITAL LETTER T -// 1f164 NEGATIVE CIRCLED LATIN CAPITAL LETTER U -// 1f165 NEGATIVE CIRCLED LATIN CAPITAL LETTER V -// 1f166 NEGATIVE CIRCLED LATIN CAPITAL LETTER W -// 1f167 NEGATIVE CIRCLED LATIN CAPITAL LETTER X -// 1f168 NEGATIVE CIRCLED LATIN CAPITAL LETTER Y -// 1f169 NEGATIVE CIRCLED LATIN CAPITAL LETTER Z -// 1f16a RAISED MC SIGN -// 1f16b RAISED MD SIGN - { 0x1F130, 0x3C, 0x8, 0, 0 }, -// 1f170 NEGATIVE SQUARED LATIN CAPITAL LETTER A -// 1f171 NEGATIVE SQUARED LATIN CAPITAL LETTER B -// 1f172 NEGATIVE SQUARED LATIN CAPITAL LETTER C -// 1f173 NEGATIVE SQUARED LATIN CAPITAL LETTER D -// 1f174 NEGATIVE SQUARED LATIN CAPITAL LETTER E -// 1f175 NEGATIVE SQUARED LATIN CAPITAL LETTER F -// 1f176 NEGATIVE SQUARED LATIN CAPITAL LETTER G -// 1f177 NEGATIVE SQUARED LATIN CAPITAL LETTER H -// 1f178 NEGATIVE SQUARED LATIN CAPITAL LETTER I -// 1f179 NEGATIVE SQUARED LATIN CAPITAL LETTER J -// 1f17a NEGATIVE SQUARED LATIN CAPITAL LETTER K -// 1f17b NEGATIVE SQUARED LATIN CAPITAL LETTER L -// 1f17c NEGATIVE SQUARED LATIN CAPITAL LETTER M -// 1f17d NEGATIVE SQUARED LATIN CAPITAL LETTER N -// 1f17e NEGATIVE SQUARED LATIN CAPITAL LETTER O -// 1f17f NEGATIVE SQUARED LATIN CAPITAL LETTER P -// 1f180 NEGATIVE SQUARED LATIN CAPITAL LETTER Q -// 1f181 NEGATIVE SQUARED LATIN CAPITAL LETTER R -// 1f182 NEGATIVE SQUARED LATIN CAPITAL LETTER S -// 1f183 NEGATIVE SQUARED LATIN CAPITAL LETTER T -// 1f184 NEGATIVE SQUARED LATIN CAPITAL LETTER U -// 1f185 NEGATIVE SQUARED LATIN CAPITAL LETTER V -// 1f186 NEGATIVE SQUARED LATIN CAPITAL LETTER W -// 1f187 NEGATIVE SQUARED LATIN CAPITAL LETTER X -// 1f188 NEGATIVE SQUARED LATIN CAPITAL LETTER Y -// 1f189 NEGATIVE SQUARED LATIN CAPITAL LETTER Z -// 1f18a CROSSED NEGATIVE SQUARED LATIN CAPITAL LETTER P -// 1f18b NEGATIVE SQUARED IC -// 1f18c NEGATIVE SQUARED PA -// 1f18d NEGATIVE SQUARED SA -// 1f18e NEGATIVE SQUARED AB -// 1f18f NEGATIVE SQUARED WC -// 1f190 SQUARE DJ -// 1f191 SQUARED CL -// 1f192 SQUARED COOL -// 1f193 SQUARED FREE -// 1f194 SQUARED ID -// 1f195 SQUARED NEW -// 1f196 SQUARED NG -// 1f197 SQUARED OK -// 1f198 SQUARED SOS -// 1f199 SQUARED UP WITH EXCLAMATION MARK -// 1f19a SQUARED VS - { 0x1F170, 0x2B, 0x8, 0, 0 }, -// 1f1e6 REGIONAL INDICATOR SYMBOL LETTER A -// 1f1e7 REGIONAL INDICATOR SYMBOL LETTER B -// 1f1e8 REGIONAL INDICATOR SYMBOL LETTER C -// 1f1e9 REGIONAL INDICATOR SYMBOL LETTER D -// 1f1ea REGIONAL INDICATOR SYMBOL LETTER E -// 1f1eb REGIONAL INDICATOR SYMBOL LETTER F -// 1f1ec REGIONAL INDICATOR SYMBOL LETTER G -// 1f1ed REGIONAL INDICATOR SYMBOL LETTER H -// 1f1ee REGIONAL INDICATOR SYMBOL LETTER I -// 1f1ef REGIONAL INDICATOR SYMBOL LETTER J -// 1f1f0 REGIONAL INDICATOR SYMBOL LETTER K -// 1f1f1 REGIONAL INDICATOR SYMBOL LETTER L -// 1f1f2 REGIONAL INDICATOR SYMBOL LETTER M -// 1f1f3 REGIONAL INDICATOR SYMBOL LETTER N -// 1f1f4 REGIONAL INDICATOR SYMBOL LETTER O -// 1f1f5 REGIONAL INDICATOR SYMBOL LETTER P -// 1f1f6 REGIONAL INDICATOR SYMBOL LETTER Q -// 1f1f7 REGIONAL INDICATOR SYMBOL LETTER R -// 1f1f8 REGIONAL INDICATOR SYMBOL LETTER S -// 1f1f9 REGIONAL INDICATOR SYMBOL LETTER T -// 1f1fa REGIONAL INDICATOR SYMBOL LETTER U -// 1f1fb REGIONAL INDICATOR SYMBOL LETTER V -// 1f1fc REGIONAL INDICATOR SYMBOL LETTER W -// 1f1fd REGIONAL INDICATOR SYMBOL LETTER X -// 1f1fe REGIONAL INDICATOR SYMBOL LETTER Y -// 1f1ff REGIONAL INDICATOR SYMBOL LETTER Z -// 1f200 SQUARE HIRAGANA HOKA -// 1f201 SQUARED KATAKANA KOKO -// 1f202 SQUARED KATAKANA SA - { 0x1F1E6, 0x1D, 0x8, 0, 0 }, -// 1f210 SQUARED CJK UNIFIED IDEOGRAPH-624B -// 1f211 SQUARED CJK UNIFIED IDEOGRAPH-5B57 -// 1f212 SQUARED CJK UNIFIED IDEOGRAPH-53CC -// 1f213 SQUARED KATAKANA DE -// 1f214 SQUARED CJK UNIFIED IDEOGRAPH-4E8C -// 1f215 SQUARED CJK UNIFIED IDEOGRAPH-591A -// 1f216 SQUARED CJK UNIFIED IDEOGRAPH-89E3 -// 1f217 SQUARED CJK UNIFIED IDEOGRAPH-5929 -// 1f218 SQUARED CJK UNIFIED IDEOGRAPH-4EA4 -// 1f219 SQUARED CJK UNIFIED IDEOGRAPH-6620 -// 1f21a SQUARED CJK UNIFIED IDEOGRAPH-7121 -// 1f21b SQUARED CJK UNIFIED IDEOGRAPH-6599 -// 1f21c SQUARED CJK UNIFIED IDEOGRAPH-524D -// 1f21d SQUARED CJK UNIFIED IDEOGRAPH-5F8C -// 1f21e SQUARED CJK UNIFIED IDEOGRAPH-518D -// 1f21f SQUARED CJK UNIFIED IDEOGRAPH-65B0 -// 1f220 SQUARED CJK UNIFIED IDEOGRAPH-521D -// 1f221 SQUARED CJK UNIFIED IDEOGRAPH-7D42 -// 1f222 SQUARED CJK UNIFIED IDEOGRAPH-751F -// 1f223 SQUARED CJK UNIFIED IDEOGRAPH-8CA9 -// 1f224 SQUARED CJK UNIFIED IDEOGRAPH-58F0 -// 1f225 SQUARED CJK UNIFIED IDEOGRAPH-5439 -// 1f226 SQUARED CJK UNIFIED IDEOGRAPH-6F14 -// 1f227 SQUARED CJK UNIFIED IDEOGRAPH-6295 -// 1f228 SQUARED CJK UNIFIED IDEOGRAPH-6355 -// 1f229 SQUARED CJK UNIFIED IDEOGRAPH-4E00 -// 1f22a SQUARED CJK UNIFIED IDEOGRAPH-4E09 -// 1f22b SQUARED CJK UNIFIED IDEOGRAPH-904A -// 1f22c SQUARED CJK UNIFIED IDEOGRAPH-5DE6 -// 1f22d SQUARED CJK UNIFIED IDEOGRAPH-4E2D -// 1f22e SQUARED CJK UNIFIED IDEOGRAPH-53F3 -// 1f22f SQUARED CJK UNIFIED IDEOGRAPH-6307 -// 1f230 SQUARED CJK UNIFIED IDEOGRAPH-8D70 -// 1f231 SQUARED CJK UNIFIED IDEOGRAPH-6253 -// 1f232 SQUARED CJK UNIFIED IDEOGRAPH-7981 -// 1f233 SQUARED CJK UNIFIED IDEOGRAPH-7A7A -// 1f234 SQUARED CJK UNIFIED IDEOGRAPH-5408 -// 1f235 SQUARED CJK UNIFIED IDEOGRAPH-6E80 -// 1f236 SQUARED CJK UNIFIED IDEOGRAPH-6709 -// 1f237 SQUARED CJK UNIFIED IDEOGRAPH-6708 -// 1f238 SQUARED CJK UNIFIED IDEOGRAPH-7533 -// 1f239 SQUARED CJK UNIFIED IDEOGRAPH-5272 -// 1f23a SQUARED CJK UNIFIED IDEOGRAPH-55B6 - { 0x1F210, 0x2B, 0x8, 0, 0 }, -// 1f240 TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C -// 1f241 TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E09 -// 1f242 TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E8C -// 1f243 TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-5B89 -// 1f244 TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-70B9 -// 1f245 TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6253 -// 1f246 TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-76D7 -// 1f247 TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-52DD -// 1f248 TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557 - { 0x1F240, 0x9, 0x8, 0, 0 }, -// 1f250 CIRCLED IDEOGRAPH ADVANTAGE -// 1f251 CIRCLED IDEOGRAPH ACCEPT - { 0x1F250, 0x2, 0x8, 0, 0 }, -// 1f300 CYCLONE -// 1f301 FOGGY -// 1f302 CLOSED UMBRELLA -// 1f303 NIGHT WITH STARS -// 1f304 SUNRISE OVER MOUNTAINS -// 1f305 SUNRISE -// 1f306 CITYSCAPE AT DUSK -// 1f307 SUNSET OVER BUILDINGS -// 1f308 RAINBOW -// 1f309 BRIDGE AT NIGHT -// 1f30a WATER WAVE -// 1f30b VOLCANO -// 1f30c MILKY WAY -// 1f30d EARTH GLOBE EUROPE-AFRICA -// 1f30e EARTH GLOBE AMERICAS -// 1f30f EARTH GLOBE ASIA-AUSTRALIA -// 1f310 GLOBE WITH MERIDIANS -// 1f311 NEW MOON SYMBOL -// 1f312 WAXING CRESCENT MOON SYMBOL -// 1f313 FIRST QUARTER MOON SYMBOL -// 1f314 WAXING GIBBOUS MOON SYMBOL -// 1f315 FULL MOON SYMBOL -// 1f316 WANING GIBBOUS MOON SYMBOL -// 1f317 LAST QUARTER MOON SYMBOL -// 1f318 WANING CRESCENT MOON SYMBOL -// 1f319 CRESCENT MOON -// 1f31a NEW MOON WITH FACE -// 1f31b FIRST QUARTER MOON WITH FACE -// 1f31c LAST QUARTER MOON WITH FACE -// 1f31d FULL MOON WITH FACE -// 1f31e SUN WITH FACE -// 1f31f GLOWING STAR -// 1f320 SHOOTING STAR -// 1f321 THERMOMETER -// 1f322 BLACK DROPLET -// 1f323 WHITE SUN -// 1f324 WHITE SUN WITH SMALL CLOUD -// 1f325 WHITE SUN BEHIND CLOUD -// 1f326 WHITE SUN BEHIND CLOUD WITH RAIN -// 1f327 CLOUD WITH RAIN -// 1f328 CLOUD WITH SNOW -// 1f329 CLOUD WITH LIGHTNING -// 1f32a CLOUD WITH TORNADO -// 1f32b FOG -// 1f32c WIND BLOWING FACE - { 0x1F300, 0x2D, 0x8, 0, 0 }, -// 1f330 CHESTNUT -// 1f331 SEEDLING -// 1f332 EVERGREEN TREE -// 1f333 DECIDUOUS TREE -// 1f334 PALM TREE -// 1f335 CACTUS -// 1f336 HOT PEPPER -// 1f337 TULIP -// 1f338 CHERRY BLOSSOM -// 1f339 ROSE -// 1f33a HIBISCUS -// 1f33b SUNFLOWER -// 1f33c BLOSSOM -// 1f33d EAR OF MAIZE -// 1f33e EAR OF RICE -// 1f33f HERB -// 1f340 FOUR LEAF CLOVER -// 1f341 MAPLE LEAF -// 1f342 FALLEN LEAF -// 1f343 LEAF FLUTTERING IN WIND -// 1f344 MUSHROOM -// 1f345 TOMATO -// 1f346 AUBERGINE -// 1f347 GRAPES -// 1f348 MELON -// 1f349 WATERMELON -// 1f34a TANGERINE -// 1f34b LEMON -// 1f34c BANANA -// 1f34d PINEAPPLE -// 1f34e RED APPLE -// 1f34f GREEN APPLE -// 1f350 PEAR -// 1f351 PEACH -// 1f352 CHERRIES -// 1f353 STRAWBERRY -// 1f354 HAMBURGER -// 1f355 SLICE OF PIZZA -// 1f356 MEAT ON BONE -// 1f357 POULTRY LEG -// 1f358 RICE CRACKER -// 1f359 RICE BALL -// 1f35a COOKED RICE -// 1f35b CURRY AND RICE -// 1f35c STEAMING BOWL -// 1f35d SPAGHETTI -// 1f35e BREAD -// 1f35f FRENCH FRIES -// 1f360 ROASTED SWEET POTATO -// 1f361 DANGO -// 1f362 ODEN -// 1f363 SUSHI -// 1f364 FRIED SHRIMP -// 1f365 FISH CAKE WITH SWIRL DESIGN -// 1f366 SOFT ICE CREAM -// 1f367 SHAVED ICE -// 1f368 ICE CREAM -// 1f369 DOUGHNUT -// 1f36a COOKIE -// 1f36b CHOCOLATE BAR -// 1f36c CANDY -// 1f36d LOLLIPOP -// 1f36e CUSTARD -// 1f36f HONEY POT -// 1f370 SHORTCAKE -// 1f371 BENTO BOX -// 1f372 POT OF FOOD -// 1f373 COOKING -// 1f374 FORK AND KNIFE -// 1f375 TEACUP WITHOUT HANDLE -// 1f376 SAKE BOTTLE AND CUP -// 1f377 WINE GLASS -// 1f378 COCKTAIL GLASS -// 1f379 TROPICAL DRINK -// 1f37a BEER MUG -// 1f37b CLINKING BEER MUGS -// 1f37c BABY BOTTLE -// 1f37d FORK AND KNIFE WITH PLATE - { 0x1F330, 0x4E, 0x8, 0, 0 }, -// 1f380 RIBBON -// 1f381 WRAPPED PRESENT -// 1f382 BIRTHDAY CAKE -// 1f383 JACK-O-LANTERN -// 1f384 CHRISTMAS TREE -// 1f385 FATHER CHRISTMAS -// 1f386 FIREWORKS -// 1f387 FIREWORK SPARKLER -// 1f388 BALLOON -// 1f389 PARTY POPPER -// 1f38a CONFETTI BALL -// 1f38b TANABATA TREE -// 1f38c CROSSED FLAGS -// 1f38d PINE DECORATION -// 1f38e JAPANESE DOLLS -// 1f38f CARP STREAMER -// 1f390 WIND CHIME -// 1f391 MOON VIEWING CEREMONY -// 1f392 SCHOOL SATCHEL -// 1f393 GRADUATION CAP -// 1f394 HEART WITH TIP ON THE LEFT -// 1f395 BOUQUET OF FLOWERS -// 1f396 MILITARY MEDAL -// 1f397 REMINDER RIBBON -// 1f398 MUSICAL KEYBOARD WITH JACKS -// 1f399 STUDIO MICROPHONE -// 1f39a LEVEL SLIDER -// 1f39b CONTROL KNOBS -// 1f39c BEAMED ASCENDING MUSICAL NOTES -// 1f39d BEAMED DESCENDING MUSICAL NOTES -// 1f39e FILM FRAMES -// 1f39f ADMISSION TICKETS -// 1f3a0 CAROUSEL HORSE -// 1f3a1 FERRIS WHEEL -// 1f3a2 ROLLER COASTER -// 1f3a3 FISHING POLE AND FISH -// 1f3a4 MICROPHONE -// 1f3a5 MOVIE CAMERA -// 1f3a6 CINEMA -// 1f3a7 HEADPHONE -// 1f3a8 ARTIST PALETTE -// 1f3a9 TOP HAT -// 1f3aa CIRCUS TENT -// 1f3ab TICKET -// 1f3ac CLAPPER BOARD -// 1f3ad PERFORMING ARTS -// 1f3ae VIDEO GAME -// 1f3af DIRECT HIT -// 1f3b0 SLOT MACHINE -// 1f3b1 BILLIARDS -// 1f3b2 GAME DIE -// 1f3b3 BOWLING -// 1f3b4 FLOWER PLAYING CARDS -// 1f3b5 MUSICAL NOTE -// 1f3b6 MULTIPLE MUSICAL NOTES -// 1f3b7 SAXOPHONE -// 1f3b8 GUITAR -// 1f3b9 MUSICAL KEYBOARD -// 1f3ba TRUMPET -// 1f3bb VIOLIN -// 1f3bc MUSICAL SCORE -// 1f3bd RUNNING SHIRT WITH SASH -// 1f3be TENNIS RACQUET AND BALL -// 1f3bf SKI AND SKI BOOT -// 1f3c0 BASKETBALL AND HOOP -// 1f3c1 CHEQUERED FLAG -// 1f3c2 SNOWBOARDER -// 1f3c3 RUNNER -// 1f3c4 SURFER -// 1f3c5 SPORTS MEDAL -// 1f3c6 TROPHY -// 1f3c7 HORSE RACING -// 1f3c8 AMERICAN FOOTBALL -// 1f3c9 RUGBY FOOTBALL -// 1f3ca SWIMMER -// 1f3cb WEIGHT LIFTER -// 1f3cc GOLFER -// 1f3cd RACING MOTORCYCLE -// 1f3ce RACING CAR - { 0x1F380, 0x4F, 0x8, 0, 0 }, -// 1f3d4 SNOW CAPPED MOUNTAIN -// 1f3d5 CAMPING -// 1f3d6 BEACH WITH UMBRELLA -// 1f3d7 BUILDING CONSTRUCTION -// 1f3d8 HOUSE BUILDINGS -// 1f3d9 CITYSCAPE -// 1f3da DERELICT HOUSE BUILDING -// 1f3db CLASSICAL BUILDING -// 1f3dc DESERT -// 1f3dd DESERT ISLAND -// 1f3de NATIONAL PARK -// 1f3df STADIUM -// 1f3e0 HOUSE BUILDING -// 1f3e1 HOUSE WITH GARDEN -// 1f3e2 OFFICE BUILDING -// 1f3e3 JAPANESE POST OFFICE -// 1f3e4 EUROPEAN POST OFFICE -// 1f3e5 HOSPITAL -// 1f3e6 BANK -// 1f3e7 AUTOMATED TELLER MACHINE -// 1f3e8 HOTEL -// 1f3e9 LOVE HOTEL -// 1f3ea CONVENIENCE STORE -// 1f3eb SCHOOL -// 1f3ec DEPARTMENT STORE -// 1f3ed FACTORY -// 1f3ee IZAKAYA LANTERN -// 1f3ef JAPANESE CASTLE -// 1f3f0 EUROPEAN CASTLE -// 1f3f1 WHITE PENNANT -// 1f3f2 BLACK PENNANT -// 1f3f3 WAVING WHITE FLAG -// 1f3f4 WAVING BLACK FLAG -// 1f3f5 ROSETTE -// 1f3f6 BLACK ROSETTE -// 1f3f7 LABEL - { 0x1F3D4, 0x24, 0x8, 0, 0 }, -// 1f400 RAT -// 1f401 MOUSE -// 1f402 OX -// 1f403 WATER BUFFALO -// 1f404 COW -// 1f405 TIGER -// 1f406 LEOPARD -// 1f407 RABBIT -// 1f408 CAT -// 1f409 DRAGON -// 1f40a CROCODILE -// 1f40b WHALE -// 1f40c SNAIL -// 1f40d SNAKE -// 1f40e HORSE -// 1f40f RAM -// 1f410 GOAT -// 1f411 SHEEP -// 1f412 MONKEY -// 1f413 ROOSTER -// 1f414 CHICKEN -// 1f415 DOG -// 1f416 PIG -// 1f417 BOAR -// 1f418 ELEPHANT -// 1f419 OCTOPUS -// 1f41a SPIRAL SHELL -// 1f41b BUG -// 1f41c ANT -// 1f41d HONEYBEE -// 1f41e LADY BEETLE -// 1f41f FISH -// 1f420 TROPICAL FISH -// 1f421 BLOWFISH -// 1f422 TURTLE -// 1f423 HATCHING CHICK -// 1f424 BABY CHICK -// 1f425 FRONT-FACING BABY CHICK -// 1f426 BIRD -// 1f427 PENGUIN -// 1f428 KOALA -// 1f429 POODLE -// 1f42a DROMEDARY CAMEL -// 1f42b BACTRIAN CAMEL -// 1f42c DOLPHIN -// 1f42d MOUSE FACE -// 1f42e COW FACE -// 1f42f TIGER FACE -// 1f430 RABBIT FACE -// 1f431 CAT FACE -// 1f432 DRAGON FACE -// 1f433 SPOUTING WHALE -// 1f434 HORSE FACE -// 1f435 MONKEY FACE -// 1f436 DOG FACE -// 1f437 PIG FACE -// 1f438 FROG FACE -// 1f439 HAMSTER FACE -// 1f43a WOLF FACE -// 1f43b BEAR FACE -// 1f43c PANDA FACE -// 1f43d PIG NOSE -// 1f43e PAW PRINTS -// 1f43f CHIPMUNK -// 1f440 EYES -// 1f441 EYE -// 1f442 EAR -// 1f443 NOSE -// 1f444 MOUTH -// 1f445 TONGUE -// 1f446 WHITE UP POINTING BACKHAND INDEX -// 1f447 WHITE DOWN POINTING BACKHAND INDEX -// 1f448 WHITE LEFT POINTING BACKHAND INDEX -// 1f449 WHITE RIGHT POINTING BACKHAND INDEX -// 1f44a FISTED HAND SIGN -// 1f44b WAVING HAND SIGN -// 1f44c OK HAND SIGN -// 1f44d THUMBS UP SIGN -// 1f44e THUMBS DOWN SIGN -// 1f44f CLAPPING HANDS SIGN -// 1f450 OPEN HANDS SIGN -// 1f451 CROWN -// 1f452 WOMANS HAT -// 1f453 EYEGLASSES -// 1f454 NECKTIE -// 1f455 T-SHIRT -// 1f456 JEANS -// 1f457 DRESS -// 1f458 KIMONO -// 1f459 BIKINI -// 1f45a WOMANS CLOTHES -// 1f45b PURSE -// 1f45c HANDBAG -// 1f45d POUCH -// 1f45e MANS SHOE -// 1f45f ATHLETIC SHOE -// 1f460 HIGH-HEELED SHOE -// 1f461 WOMANS SANDAL -// 1f462 WOMANS BOOTS -// 1f463 FOOTPRINTS -// 1f464 BUST IN SILHOUETTE -// 1f465 BUSTS IN SILHOUETTE -// 1f466 BOY -// 1f467 GIRL -// 1f468 MAN -// 1f469 WOMAN -// 1f46a FAMILY -// 1f46b MAN AND WOMAN HOLDING HANDS -// 1f46c TWO MEN HOLDING HANDS -// 1f46d TWO WOMEN HOLDING HANDS -// 1f46e POLICE OFFICER -// 1f46f WOMAN WITH BUNNY EARS -// 1f470 BRIDE WITH VEIL -// 1f471 PERSON WITH BLOND HAIR -// 1f472 MAN WITH GUA PI MAO -// 1f473 MAN WITH TURBAN -// 1f474 OLDER MAN -// 1f475 OLDER WOMAN -// 1f476 BABY -// 1f477 CONSTRUCTION WORKER -// 1f478 PRINCESS -// 1f479 JAPANESE OGRE -// 1f47a JAPANESE GOBLIN -// 1f47b GHOST -// 1f47c BABY ANGEL -// 1f47d EXTRATERRESTRIAL ALIEN -// 1f47e ALIEN MONSTER -// 1f47f IMP -// 1f480 SKULL -// 1f481 INFORMATION DESK PERSON -// 1f482 GUARDSMAN -// 1f483 DANCER -// 1f484 LIPSTICK -// 1f485 NAIL POLISH -// 1f486 FACE MASSAGE -// 1f487 HAIRCUT -// 1f488 BARBER POLE -// 1f489 SYRINGE -// 1f48a PILL -// 1f48b KISS MARK -// 1f48c LOVE LETTER -// 1f48d RING -// 1f48e GEM STONE -// 1f48f KISS -// 1f490 BOUQUET -// 1f491 COUPLE WITH HEART -// 1f492 WEDDING -// 1f493 BEATING HEART -// 1f494 BROKEN HEART -// 1f495 TWO HEARTS -// 1f496 SPARKLING HEART -// 1f497 GROWING HEART -// 1f498 HEART WITH ARROW -// 1f499 BLUE HEART -// 1f49a GREEN HEART -// 1f49b YELLOW HEART -// 1f49c PURPLE HEART -// 1f49d HEART WITH RIBBON -// 1f49e REVOLVING HEARTS -// 1f49f HEART DECORATION -// 1f4a0 DIAMOND SHAPE WITH A DOT INSIDE -// 1f4a1 ELECTRIC LIGHT BULB -// 1f4a2 ANGER SYMBOL -// 1f4a3 BOMB -// 1f4a4 SLEEPING SYMBOL -// 1f4a5 COLLISION SYMBOL -// 1f4a6 SPLASHING SWEAT SYMBOL -// 1f4a7 DROPLET -// 1f4a8 DASH SYMBOL -// 1f4a9 PILE OF POO -// 1f4aa FLEXED BICEPS -// 1f4ab DIZZY SYMBOL -// 1f4ac SPEECH BALLOON -// 1f4ad THOUGHT BALLOON -// 1f4ae WHITE FLOWER -// 1f4af HUNDRED POINTS SYMBOL -// 1f4b0 MONEY BAG -// 1f4b1 CURRENCY EXCHANGE -// 1f4b2 HEAVY DOLLAR SIGN -// 1f4b3 CREDIT CARD -// 1f4b4 BANKNOTE WITH YEN SIGN -// 1f4b5 BANKNOTE WITH DOLLAR SIGN -// 1f4b6 BANKNOTE WITH EURO SIGN -// 1f4b7 BANKNOTE WITH POUND SIGN -// 1f4b8 MONEY WITH WINGS -// 1f4b9 CHART WITH UPWARDS TREND AND YEN SIGN -// 1f4ba SEAT -// 1f4bb PERSONAL COMPUTER -// 1f4bc BRIEFCASE -// 1f4bd MINIDISC -// 1f4be FLOPPY DISK -// 1f4bf OPTICAL DISC -// 1f4c0 DVD -// 1f4c1 FILE FOLDER -// 1f4c2 OPEN FILE FOLDER -// 1f4c3 PAGE WITH CURL -// 1f4c4 PAGE FACING UP -// 1f4c5 CALENDAR -// 1f4c6 TEAR-OFF CALENDAR -// 1f4c7 CARD INDEX -// 1f4c8 CHART WITH UPWARDS TREND -// 1f4c9 CHART WITH DOWNWARDS TREND -// 1f4ca BAR CHART -// 1f4cb CLIPBOARD -// 1f4cc PUSHPIN -// 1f4cd ROUND PUSHPIN -// 1f4ce PAPERCLIP -// 1f4cf STRAIGHT RULER -// 1f4d0 TRIANGULAR RULER -// 1f4d1 BOOKMARK TABS -// 1f4d2 LEDGER -// 1f4d3 NOTEBOOK -// 1f4d4 NOTEBOOK WITH DECORATIVE COVER -// 1f4d5 CLOSED BOOK -// 1f4d6 OPEN BOOK -// 1f4d7 GREEN BOOK -// 1f4d8 BLUE BOOK -// 1f4d9 ORANGE BOOK -// 1f4da BOOKS -// 1f4db NAME BADGE -// 1f4dc SCROLL -// 1f4dd MEMO -// 1f4de TELEPHONE RECEIVER -// 1f4df PAGER -// 1f4e0 FAX MACHINE -// 1f4e1 SATELLITE ANTENNA -// 1f4e2 PUBLIC ADDRESS LOUDSPEAKER -// 1f4e3 CHEERING MEGAPHONE -// 1f4e4 OUTBOX TRAY -// 1f4e5 INBOX TRAY -// 1f4e6 PACKAGE -// 1f4e7 E-MAIL SYMBOL -// 1f4e8 INCOMING ENVELOPE -// 1f4e9 ENVELOPE WITH DOWNWARDS ARROW ABOVE -// 1f4ea CLOSED MAILBOX WITH LOWERED FLAG -// 1f4eb CLOSED MAILBOX WITH RAISED FLAG -// 1f4ec OPEN MAILBOX WITH RAISED FLAG -// 1f4ed OPEN MAILBOX WITH LOWERED FLAG -// 1f4ee POSTBOX -// 1f4ef POSTAL HORN -// 1f4f0 NEWSPAPER -// 1f4f1 MOBILE PHONE -// 1f4f2 MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT -// 1f4f3 VIBRATION MODE -// 1f4f4 MOBILE PHONE OFF -// 1f4f5 NO MOBILE PHONES -// 1f4f6 ANTENNA WITH BARS -// 1f4f7 CAMERA -// 1f4f8 CAMERA WITH FLASH -// 1f4f9 VIDEO CAMERA -// 1f4fa TELEVISION -// 1f4fb RADIO -// 1f4fc VIDEOCASSETTE -// 1f4fd FILM PROJECTOR -// 1f4fe PORTABLE STEREO - { 0x1F400, 0xFF, 0x8, 0, 0 }, -// 1f500 TWISTED RIGHTWARDS ARROWS -// 1f501 CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS -// 1f502 CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS WITH CIRCLED ONE OVERLAY -// 1f503 CLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS -// 1f504 ANTICLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS -// 1f505 LOW BRIGHTNESS SYMBOL -// 1f506 HIGH BRIGHTNESS SYMBOL -// 1f507 SPEAKER WITH CANCELLATION STROKE -// 1f508 SPEAKER -// 1f509 SPEAKER WITH ONE SOUND WAVE -// 1f50a SPEAKER WITH THREE SOUND WAVES -// 1f50b BATTERY -// 1f50c ELECTRIC PLUG -// 1f50d LEFT-POINTING MAGNIFYING GLASS -// 1f50e RIGHT-POINTING MAGNIFYING GLASS -// 1f50f LOCK WITH INK PEN -// 1f510 CLOSED LOCK WITH KEY -// 1f511 KEY -// 1f512 LOCK -// 1f513 OPEN LOCK -// 1f514 BELL -// 1f515 BELL WITH CANCELLATION STROKE -// 1f516 BOOKMARK -// 1f517 LINK SYMBOL -// 1f518 RADIO BUTTON -// 1f519 BACK WITH LEFTWARDS ARROW ABOVE -// 1f51a END WITH LEFTWARDS ARROW ABOVE -// 1f51b ON WITH EXCLAMATION MARK WITH LEFT RIGHT ARROW ABOVE -// 1f51c SOON WITH RIGHTWARDS ARROW ABOVE -// 1f51d TOP WITH UPWARDS ARROW ABOVE -// 1f51e NO ONE UNDER EIGHTEEN SYMBOL -// 1f51f KEYCAP TEN -// 1f520 INPUT SYMBOL FOR LATIN CAPITAL LETTERS -// 1f521 INPUT SYMBOL FOR LATIN SMALL LETTERS -// 1f522 INPUT SYMBOL FOR NUMBERS -// 1f523 INPUT SYMBOL FOR SYMBOLS -// 1f524 INPUT SYMBOL FOR LATIN LETTERS -// 1f525 FIRE -// 1f526 ELECTRIC TORCH -// 1f527 WRENCH -// 1f528 HAMMER -// 1f529 NUT AND BOLT -// 1f52a HOCHO -// 1f52b PISTOL -// 1f52c MICROSCOPE -// 1f52d TELESCOPE -// 1f52e CRYSTAL BALL -// 1f52f SIX POINTED STAR WITH MIDDLE DOT -// 1f530 JAPANESE SYMBOL FOR BEGINNER -// 1f531 TRIDENT EMBLEM -// 1f532 BLACK SQUARE BUTTON -// 1f533 WHITE SQUARE BUTTON -// 1f534 LARGE RED CIRCLE -// 1f535 LARGE BLUE CIRCLE -// 1f536 LARGE ORANGE DIAMOND -// 1f537 LARGE BLUE DIAMOND -// 1f538 SMALL ORANGE DIAMOND -// 1f539 SMALL BLUE DIAMOND -// 1f53a UP-POINTING RED TRIANGLE -// 1f53b DOWN-POINTING RED TRIANGLE -// 1f53c UP-POINTING SMALL RED TRIANGLE -// 1f53d DOWN-POINTING SMALL RED TRIANGLE -// 1f53e LOWER RIGHT SHADOWED WHITE CIRCLE -// 1f53f UPPER RIGHT SHADOWED WHITE CIRCLE -// 1f540 CIRCLED CROSS POMMEE -// 1f541 CROSS POMMEE WITH HALF-CIRCLE BELOW -// 1f542 CROSS POMMEE -// 1f543 NOTCHED LEFT SEMICIRCLE WITH THREE DOTS -// 1f544 NOTCHED RIGHT SEMICIRCLE WITH THREE DOTS -// 1f545 SYMBOL FOR MARKS CHAPTER -// 1f546 WHITE LATIN CROSS -// 1f547 HEAVY LATIN CROSS -// 1f548 CELTIC CROSS -// 1f549 OM SYMBOL -// 1f54a DOVE OF PEACE - { 0x1F500, 0x4B, 0x8, 0, 0 }, -// 1f550 CLOCK FACE ONE OCLOCK -// 1f551 CLOCK FACE TWO OCLOCK -// 1f552 CLOCK FACE THREE OCLOCK -// 1f553 CLOCK FACE FOUR OCLOCK -// 1f554 CLOCK FACE FIVE OCLOCK -// 1f555 CLOCK FACE SIX OCLOCK -// 1f556 CLOCK FACE SEVEN OCLOCK -// 1f557 CLOCK FACE EIGHT OCLOCK -// 1f558 CLOCK FACE NINE OCLOCK -// 1f559 CLOCK FACE TEN OCLOCK -// 1f55a CLOCK FACE ELEVEN OCLOCK -// 1f55b CLOCK FACE TWELVE OCLOCK -// 1f55c CLOCK FACE ONE-THIRTY -// 1f55d CLOCK FACE TWO-THIRTY -// 1f55e CLOCK FACE THREE-THIRTY -// 1f55f CLOCK FACE FOUR-THIRTY -// 1f560 CLOCK FACE FIVE-THIRTY -// 1f561 CLOCK FACE SIX-THIRTY -// 1f562 CLOCK FACE SEVEN-THIRTY -// 1f563 CLOCK FACE EIGHT-THIRTY -// 1f564 CLOCK FACE NINE-THIRTY -// 1f565 CLOCK FACE TEN-THIRTY -// 1f566 CLOCK FACE ELEVEN-THIRTY -// 1f567 CLOCK FACE TWELVE-THIRTY -// 1f568 RIGHT SPEAKER -// 1f569 RIGHT SPEAKER WITH ONE SOUND WAVE -// 1f56a RIGHT SPEAKER WITH THREE SOUND WAVES -// 1f56b BULLHORN -// 1f56c BULLHORN WITH SOUND WAVES -// 1f56d RINGING BELL -// 1f56e BOOK -// 1f56f CANDLE -// 1f570 MANTELPIECE CLOCK -// 1f571 BLACK SKULL AND CROSSBONES -// 1f572 NO PIRACY -// 1f573 HOLE -// 1f574 MAN IN BUSINESS SUIT LEVITATING -// 1f575 SLEUTH OR SPY -// 1f576 DARK SUNGLASSES -// 1f577 SPIDER -// 1f578 SPIDER WEB -// 1f579 JOYSTICK - { 0x1F550, 0x2A, 0x8, 0, 0 }, -// 1f57b LEFT HAND TELEPHONE RECEIVER -// 1f57c TELEPHONE RECEIVER WITH PAGE -// 1f57d RIGHT HAND TELEPHONE RECEIVER -// 1f57e WHITE TOUCHTONE TELEPHONE -// 1f57f BLACK TOUCHTONE TELEPHONE -// 1f580 TELEPHONE ON TOP OF MODEM -// 1f581 CLAMSHELL MOBILE PHONE -// 1f582 BACK OF ENVELOPE -// 1f583 STAMPED ENVELOPE -// 1f584 ENVELOPE WITH LIGHTNING -// 1f585 FLYING ENVELOPE -// 1f586 PEN OVER STAMPED ENVELOPE -// 1f587 LINKED PAPERCLIPS -// 1f588 BLACK PUSHPIN -// 1f589 LOWER LEFT PENCIL -// 1f58a LOWER LEFT BALLPOINT PEN -// 1f58b LOWER LEFT FOUNTAIN PEN -// 1f58c LOWER LEFT PAINTBRUSH -// 1f58d LOWER LEFT CRAYON -// 1f58e LEFT WRITING HAND -// 1f58f TURNED OK HAND SIGN -// 1f590 RAISED HAND WITH FINGERS SPLAYED -// 1f591 REVERSED RAISED HAND WITH FINGERS SPLAYED -// 1f592 REVERSED THUMBS UP SIGN -// 1f593 REVERSED THUMBS DOWN SIGN -// 1f594 REVERSED VICTORY HAND -// 1f595 REVERSED HAND WITH MIDDLE FINGER EXTENDED -// 1f596 RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS -// 1f597 WHITE DOWN POINTING LEFT HAND INDEX -// 1f598 SIDEWAYS WHITE LEFT POINTING INDEX -// 1f599 SIDEWAYS WHITE RIGHT POINTING INDEX -// 1f59a SIDEWAYS BLACK LEFT POINTING INDEX -// 1f59b SIDEWAYS BLACK RIGHT POINTING INDEX -// 1f59c BLACK LEFT POINTING BACKHAND INDEX -// 1f59d BLACK RIGHT POINTING BACKHAND INDEX -// 1f59e SIDEWAYS WHITE UP POINTING INDEX -// 1f59f SIDEWAYS WHITE DOWN POINTING INDEX -// 1f5a0 SIDEWAYS BLACK UP POINTING INDEX -// 1f5a1 SIDEWAYS BLACK DOWN POINTING INDEX -// 1f5a2 BLACK UP POINTING BACKHAND INDEX -// 1f5a3 BLACK DOWN POINTING BACKHAND INDEX - { 0x1F57B, 0x29, 0x8, 0, 0 }, -// 1f5a5 DESKTOP COMPUTER -// 1f5a6 KEYBOARD AND MOUSE -// 1f5a7 THREE NETWORKED COMPUTERS -// 1f5a8 PRINTER -// 1f5a9 POCKET CALCULATOR -// 1f5aa BLACK HARD SHELL FLOPPY DISK -// 1f5ab WHITE HARD SHELL FLOPPY DISK -// 1f5ac SOFT SHELL FLOPPY DISK -// 1f5ad TAPE CARTRIDGE -// 1f5ae WIRED KEYBOARD -// 1f5af ONE BUTTON MOUSE -// 1f5b0 TWO BUTTON MOUSE -// 1f5b1 THREE BUTTON MOUSE -// 1f5b2 TRACKBALL -// 1f5b3 OLD PERSONAL COMPUTER -// 1f5b4 HARD DISK -// 1f5b5 SCREEN -// 1f5b6 PRINTER ICON -// 1f5b7 FAX ICON -// 1f5b8 OPTICAL DISC ICON -// 1f5b9 DOCUMENT WITH TEXT -// 1f5ba DOCUMENT WITH TEXT AND PICTURE -// 1f5bb DOCUMENT WITH PICTURE -// 1f5bc FRAME WITH PICTURE -// 1f5bd FRAME WITH TILES -// 1f5be FRAME WITH AN X -// 1f5bf BLACK FOLDER -// 1f5c0 FOLDER -// 1f5c1 OPEN FOLDER -// 1f5c2 CARD INDEX DIVIDERS -// 1f5c3 CARD FILE BOX -// 1f5c4 FILE CABINET -// 1f5c5 EMPTY NOTE -// 1f5c6 EMPTY NOTE PAGE -// 1f5c7 EMPTY NOTE PAD -// 1f5c8 NOTE -// 1f5c9 NOTE PAGE -// 1f5ca NOTE PAD -// 1f5cb EMPTY DOCUMENT -// 1f5cc EMPTY PAGE -// 1f5cd EMPTY PAGES -// 1f5ce DOCUMENT -// 1f5cf PAGE -// 1f5d0 PAGES -// 1f5d1 WASTEBASKET -// 1f5d2 SPIRAL NOTE PAD -// 1f5d3 SPIRAL CALENDAR PAD -// 1f5d4 DESKTOP WINDOW -// 1f5d5 MINIMIZE -// 1f5d6 MAXIMIZE -// 1f5d7 OVERLAP -// 1f5d8 CLOCKWISE RIGHT AND LEFT SEMICIRCLE ARROWS -// 1f5d9 CANCELLATION X -// 1f5da INCREASE FONT SIZE SYMBOL -// 1f5db DECREASE FONT SIZE SYMBOL -// 1f5dc COMPRESSION -// 1f5dd OLD KEY -// 1f5de ROLLED-UP NEWSPAPER -// 1f5df PAGE WITH CIRCLED TEXT -// 1f5e0 STOCK CHART -// 1f5e1 DAGGER KNIFE -// 1f5e2 LIPS -// 1f5e3 SPEAKING HEAD IN SILHOUETTE -// 1f5e4 THREE RAYS ABOVE -// 1f5e5 THREE RAYS BELOW -// 1f5e6 THREE RAYS LEFT -// 1f5e7 THREE RAYS RIGHT -// 1f5e8 LEFT SPEECH BUBBLE -// 1f5e9 RIGHT SPEECH BUBBLE -// 1f5ea TWO SPEECH BUBBLES -// 1f5eb THREE SPEECH BUBBLES -// 1f5ec LEFT THOUGHT BUBBLE -// 1f5ed RIGHT THOUGHT BUBBLE -// 1f5ee LEFT ANGER BUBBLE -// 1f5ef RIGHT ANGER BUBBLE -// 1f5f0 MOOD BUBBLE -// 1f5f1 LIGHTNING MOOD BUBBLE -// 1f5f2 LIGHTNING MOOD -// 1f5f3 BALLOT BOX WITH BALLOT -// 1f5f4 BALLOT SCRIPT X -// 1f5f5 BALLOT BOX WITH SCRIPT X -// 1f5f6 BALLOT BOLD SCRIPT X -// 1f5f7 BALLOT BOX WITH BOLD SCRIPT X -// 1f5f8 LIGHT CHECK MARK -// 1f5f9 BALLOT BOX WITH BOLD CHECK -// 1f5fa WORLD MAP -// 1f5fb MOUNT FUJI -// 1f5fc TOKYO TOWER -// 1f5fd STATUE OF LIBERTY -// 1f5fe SILHOUETTE OF JAPAN -// 1f5ff MOYAI -// 1f600 GRINNING FACE -// 1f601 GRINNING FACE WITH SMILING EYES -// 1f602 FACE WITH TEARS OF JOY -// 1f603 SMILING FACE WITH OPEN MOUTH -// 1f604 SMILING FACE WITH OPEN MOUTH AND SMILING EYES -// 1f605 SMILING FACE WITH OPEN MOUTH AND COLD SWEAT -// 1f606 SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES -// 1f607 SMILING FACE WITH HALO -// 1f608 SMILING FACE WITH HORNS -// 1f609 WINKING FACE -// 1f60a SMILING FACE WITH SMILING EYES -// 1f60b FACE SAVOURING DELICIOUS FOOD -// 1f60c RELIEVED FACE -// 1f60d SMILING FACE WITH HEART-SHAPED EYES -// 1f60e SMILING FACE WITH SUNGLASSES -// 1f60f SMIRKING FACE -// 1f610 NEUTRAL FACE -// 1f611 EXPRESSIONLESS FACE -// 1f612 UNAMUSED FACE -// 1f613 FACE WITH COLD SWEAT -// 1f614 PENSIVE FACE -// 1f615 CONFUSED FACE -// 1f616 CONFOUNDED FACE -// 1f617 KISSING FACE -// 1f618 FACE THROWING A KISS -// 1f619 KISSING FACE WITH SMILING EYES -// 1f61a KISSING FACE WITH CLOSED EYES -// 1f61b FACE WITH STUCK-OUT TONGUE -// 1f61c FACE WITH STUCK-OUT TONGUE AND WINKING EYE -// 1f61d FACE WITH STUCK-OUT TONGUE AND TIGHTLY-CLOSED EYES -// 1f61e DISAPPOINTED FACE -// 1f61f WORRIED FACE -// 1f620 ANGRY FACE -// 1f621 POUTING FACE -// 1f622 CRYING FACE -// 1f623 PERSEVERING FACE -// 1f624 FACE WITH LOOK OF TRIUMPH -// 1f625 DISAPPOINTED BUT RELIEVED FACE -// 1f626 FROWNING FACE WITH OPEN MOUTH -// 1f627 ANGUISHED FACE -// 1f628 FEARFUL FACE -// 1f629 WEARY FACE -// 1f62a SLEEPY FACE -// 1f62b TIRED FACE -// 1f62c GRIMACING FACE -// 1f62d LOUDLY CRYING FACE -// 1f62e FACE WITH OPEN MOUTH -// 1f62f HUSHED FACE -// 1f630 FACE WITH OPEN MOUTH AND COLD SWEAT -// 1f631 FACE SCREAMING IN FEAR -// 1f632 ASTONISHED FACE -// 1f633 FLUSHED FACE -// 1f634 SLEEPING FACE -// 1f635 DIZZY FACE -// 1f636 FACE WITHOUT MOUTH -// 1f637 FACE WITH MEDICAL MASK -// 1f638 GRINNING CAT FACE WITH SMILING EYES -// 1f639 CAT FACE WITH TEARS OF JOY -// 1f63a SMILING CAT FACE WITH OPEN MOUTH -// 1f63b SMILING CAT FACE WITH HEART-SHAPED EYES -// 1f63c CAT FACE WITH WRY SMILE -// 1f63d KISSING CAT FACE WITH CLOSED EYES -// 1f63e POUTING CAT FACE -// 1f63f CRYING CAT FACE -// 1f640 WEARY CAT FACE -// 1f641 SLIGHTLY FROWNING FACE -// 1f642 SLIGHTLY SMILING FACE - { 0x1F5A5, 0x9E, 0x8, 0, 0 }, -// 1f645 FACE WITH NO GOOD GESTURE -// 1f646 FACE WITH OK GESTURE -// 1f647 PERSON BOWING DEEPLY -// 1f648 SEE-NO-EVIL MONKEY -// 1f649 HEAR-NO-EVIL MONKEY -// 1f64a SPEAK-NO-EVIL MONKEY -// 1f64b HAPPY PERSON RAISING ONE HAND -// 1f64c PERSON RAISING BOTH HANDS IN CELEBRATION -// 1f64d PERSON FROWNING -// 1f64e PERSON WITH POUTING FACE -// 1f64f PERSON WITH FOLDED HANDS -// 1f650 NORTH WEST POINTING LEAF -// 1f651 SOUTH WEST POINTING LEAF -// 1f652 NORTH EAST POINTING LEAF -// 1f653 SOUTH EAST POINTING LEAF -// 1f654 TURNED NORTH WEST POINTING LEAF -// 1f655 TURNED SOUTH WEST POINTING LEAF -// 1f656 TURNED NORTH EAST POINTING LEAF -// 1f657 TURNED SOUTH EAST POINTING LEAF -// 1f658 NORTH WEST POINTING VINE LEAF -// 1f659 SOUTH WEST POINTING VINE LEAF -// 1f65a NORTH EAST POINTING VINE LEAF -// 1f65b SOUTH EAST POINTING VINE LEAF -// 1f65c HEAVY NORTH WEST POINTING VINE LEAF -// 1f65d HEAVY SOUTH WEST POINTING VINE LEAF -// 1f65e HEAVY NORTH EAST POINTING VINE LEAF -// 1f65f HEAVY SOUTH EAST POINTING VINE LEAF -// 1f660 NORTH WEST POINTING BUD -// 1f661 SOUTH WEST POINTING BUD -// 1f662 NORTH EAST POINTING BUD -// 1f663 SOUTH EAST POINTING BUD -// 1f664 HEAVY NORTH WEST POINTING BUD -// 1f665 HEAVY SOUTH WEST POINTING BUD -// 1f666 HEAVY NORTH EAST POINTING BUD -// 1f667 HEAVY SOUTH EAST POINTING BUD -// 1f668 HOLLOW QUILT SQUARE ORNAMENT -// 1f669 HOLLOW QUILT SQUARE ORNAMENT IN BLACK SQUARE -// 1f66a SOLID QUILT SQUARE ORNAMENT -// 1f66b SOLID QUILT SQUARE ORNAMENT IN BLACK SQUARE -// 1f66c LEFTWARDS ROCKET -// 1f66d UPWARDS ROCKET -// 1f66e RIGHTWARDS ROCKET -// 1f66f DOWNWARDS ROCKET -// 1f670 SCRIPT LIGATURE ET ORNAMENT -// 1f671 HEAVY SCRIPT LIGATURE ET ORNAMENT -// 1f672 LIGATURE OPEN ET ORNAMENT -// 1f673 HEAVY LIGATURE OPEN ET ORNAMENT -// 1f674 HEAVY AMPERSAND ORNAMENT -// 1f675 SWASH AMPERSAND ORNAMENT -// 1f676 SANS-SERIF HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT -// 1f677 SANS-SERIF HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT -// 1f678 SANS-SERIF HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT -// 1f679 HEAVY INTERROBANG ORNAMENT -// 1f67a SANS-SERIF INTERROBANG ORNAMENT -// 1f67b HEAVY SANS-SERIF INTERROBANG ORNAMENT -// 1f67c VERY HEAVY SOLIDUS -// 1f67d VERY HEAVY REVERSE SOLIDUS -// 1f67e CHECKER BOARD -// 1f67f REVERSE CHECKER BOARD -// 1f680 ROCKET -// 1f681 HELICOPTER -// 1f682 STEAM LOCOMOTIVE -// 1f683 RAILWAY CAR -// 1f684 HIGH-SPEED TRAIN -// 1f685 HIGH-SPEED TRAIN WITH BULLET NOSE -// 1f686 TRAIN -// 1f687 METRO -// 1f688 LIGHT RAIL -// 1f689 STATION -// 1f68a TRAM -// 1f68b TRAM CAR -// 1f68c BUS -// 1f68d ONCOMING BUS -// 1f68e TROLLEYBUS -// 1f68f BUS STOP -// 1f690 MINIBUS -// 1f691 AMBULANCE -// 1f692 FIRE ENGINE -// 1f693 POLICE CAR -// 1f694 ONCOMING POLICE CAR -// 1f695 TAXI -// 1f696 ONCOMING TAXI -// 1f697 AUTOMOBILE -// 1f698 ONCOMING AUTOMOBILE -// 1f699 RECREATIONAL VEHICLE -// 1f69a DELIVERY TRUCK -// 1f69b ARTICULATED LORRY -// 1f69c TRACTOR -// 1f69d MONORAIL -// 1f69e MOUNTAIN RAILWAY -// 1f69f SUSPENSION RAILWAY -// 1f6a0 MOUNTAIN CABLEWAY -// 1f6a1 AERIAL TRAMWAY -// 1f6a2 SHIP -// 1f6a3 ROWBOAT -// 1f6a4 SPEEDBOAT -// 1f6a5 HORIZONTAL TRAFFIC LIGHT -// 1f6a6 VERTICAL TRAFFIC LIGHT -// 1f6a7 CONSTRUCTION SIGN -// 1f6a8 POLICE CARS REVOLVING LIGHT -// 1f6a9 TRIANGULAR FLAG ON POST -// 1f6aa DOOR -// 1f6ab NO ENTRY SIGN -// 1f6ac SMOKING SYMBOL -// 1f6ad NO SMOKING SYMBOL -// 1f6ae PUT LITTER IN ITS PLACE SYMBOL -// 1f6af DO NOT LITTER SYMBOL -// 1f6b0 POTABLE WATER SYMBOL -// 1f6b1 NON-POTABLE WATER SYMBOL -// 1f6b2 BICYCLE -// 1f6b3 NO BICYCLES -// 1f6b4 BICYCLIST -// 1f6b5 MOUNTAIN BICYCLIST -// 1f6b6 PEDESTRIAN -// 1f6b7 NO PEDESTRIANS -// 1f6b8 CHILDREN CROSSING -// 1f6b9 MENS SYMBOL -// 1f6ba WOMENS SYMBOL -// 1f6bb RESTROOM -// 1f6bc BABY SYMBOL -// 1f6bd TOILET -// 1f6be WATER CLOSET -// 1f6bf SHOWER -// 1f6c0 BATH -// 1f6c1 BATHTUB -// 1f6c2 PASSPORT CONTROL -// 1f6c3 CUSTOMS -// 1f6c4 BAGGAGE CLAIM -// 1f6c5 LEFT LUGGAGE -// 1f6c6 TRIANGLE WITH ROUNDED CORNERS -// 1f6c7 PROHIBITED SIGN -// 1f6c8 CIRCLED INFORMATION SOURCE -// 1f6c9 BOYS SYMBOL -// 1f6ca GIRLS SYMBOL -// 1f6cb COUCH AND LAMP -// 1f6cc SLEEPING ACCOMMODATION -// 1f6cd SHOPPING BAGS -// 1f6ce BELLHOP BELL -// 1f6cf BED - { 0x1F645, 0x8B, 0x8, 0, 0 }, -// 1f6e0 HAMMER AND WRENCH -// 1f6e1 SHIELD -// 1f6e2 OIL DRUM -// 1f6e3 MOTORWAY -// 1f6e4 RAILWAY TRACK -// 1f6e5 MOTOR BOAT -// 1f6e6 UP-POINTING MILITARY AIRPLANE -// 1f6e7 UP-POINTING AIRPLANE -// 1f6e8 UP-POINTING SMALL AIRPLANE -// 1f6e9 SMALL AIRPLANE -// 1f6ea NORTHEAST-POINTING AIRPLANE -// 1f6eb AIRPLANE DEPARTURE -// 1f6ec AIRPLANE ARRIVING - { 0x1F6E0, 0xD, 0x8, 0, 0 }, -// 1f6f0 SATELLITE -// 1f6f1 ONCOMING FIRE ENGINE -// 1f6f2 DIESEL LOCOMOTIVE -// 1f6f3 PASSENGER SHIP - { 0x1F6F0, 0x4, 0x8, 0, 0 }, -// 1f700 ALCHEMICAL SYMBOL FOR QUINTESSENCE -// 1f701 ALCHEMICAL SYMBOL FOR AIR -// 1f702 ALCHEMICAL SYMBOL FOR FIRE -// 1f703 ALCHEMICAL SYMBOL FOR EARTH -// 1f704 ALCHEMICAL SYMBOL FOR WATER -// 1f705 ALCHEMICAL SYMBOL FOR AQUAFORTIS -// 1f706 ALCHEMICAL SYMBOL FOR AQUA REGIA -// 1f707 ALCHEMICAL SYMBOL FOR AQUA REGIA-2 -// 1f708 ALCHEMICAL SYMBOL FOR AQUA VITAE -// 1f709 ALCHEMICAL SYMBOL FOR AQUA VITAE-2 -// 1f70a ALCHEMICAL SYMBOL FOR VINEGAR -// 1f70b ALCHEMICAL SYMBOL FOR VINEGAR-2 -// 1f70c ALCHEMICAL SYMBOL FOR VINEGAR-3 -// 1f70d ALCHEMICAL SYMBOL FOR SULFUR -// 1f70e ALCHEMICAL SYMBOL FOR PHILOSOPHERS SULFUR -// 1f70f ALCHEMICAL SYMBOL FOR BLACK SULFUR -// 1f710 ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE -// 1f711 ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE-2 -// 1f712 ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE-3 -// 1f713 ALCHEMICAL SYMBOL FOR CINNABAR -// 1f714 ALCHEMICAL SYMBOL FOR SALT -// 1f715 ALCHEMICAL SYMBOL FOR NITRE -// 1f716 ALCHEMICAL SYMBOL FOR VITRIOL -// 1f717 ALCHEMICAL SYMBOL FOR VITRIOL-2 -// 1f718 ALCHEMICAL SYMBOL FOR ROCK SALT -// 1f719 ALCHEMICAL SYMBOL FOR ROCK SALT-2 -// 1f71a ALCHEMICAL SYMBOL FOR GOLD -// 1f71b ALCHEMICAL SYMBOL FOR SILVER -// 1f71c ALCHEMICAL SYMBOL FOR IRON ORE -// 1f71d ALCHEMICAL SYMBOL FOR IRON ORE-2 -// 1f71e ALCHEMICAL SYMBOL FOR CROCUS OF IRON -// 1f71f ALCHEMICAL SYMBOL FOR REGULUS OF IRON -// 1f720 ALCHEMICAL SYMBOL FOR COPPER ORE -// 1f721 ALCHEMICAL SYMBOL FOR IRON-COPPER ORE -// 1f722 ALCHEMICAL SYMBOL FOR SUBLIMATE OF COPPER -// 1f723 ALCHEMICAL SYMBOL FOR CROCUS OF COPPER -// 1f724 ALCHEMICAL SYMBOL FOR CROCUS OF COPPER-2 -// 1f725 ALCHEMICAL SYMBOL FOR COPPER ANTIMONIATE -// 1f726 ALCHEMICAL SYMBOL FOR SALT OF COPPER ANTIMONIATE -// 1f727 ALCHEMICAL SYMBOL FOR SUBLIMATE OF SALT OF COPPER -// 1f728 ALCHEMICAL SYMBOL FOR VERDIGRIS -// 1f729 ALCHEMICAL SYMBOL FOR TIN ORE -// 1f72a ALCHEMICAL SYMBOL FOR LEAD ORE -// 1f72b ALCHEMICAL SYMBOL FOR ANTIMONY ORE -// 1f72c ALCHEMICAL SYMBOL FOR SUBLIMATE OF ANTIMONY -// 1f72d ALCHEMICAL SYMBOL FOR SALT OF ANTIMONY -// 1f72e ALCHEMICAL SYMBOL FOR SUBLIMATE OF SALT OF ANTIMONY -// 1f72f ALCHEMICAL SYMBOL FOR VINEGAR OF ANTIMONY -// 1f730 ALCHEMICAL SYMBOL FOR REGULUS OF ANTIMONY -// 1f731 ALCHEMICAL SYMBOL FOR REGULUS OF ANTIMONY-2 -// 1f732 ALCHEMICAL SYMBOL FOR REGULUS -// 1f733 ALCHEMICAL SYMBOL FOR REGULUS-2 -// 1f734 ALCHEMICAL SYMBOL FOR REGULUS-3 -// 1f735 ALCHEMICAL SYMBOL FOR REGULUS-4 -// 1f736 ALCHEMICAL SYMBOL FOR ALKALI -// 1f737 ALCHEMICAL SYMBOL FOR ALKALI-2 -// 1f738 ALCHEMICAL SYMBOL FOR MARCASITE -// 1f739 ALCHEMICAL SYMBOL FOR SAL-AMMONIAC -// 1f73a ALCHEMICAL SYMBOL FOR ARSENIC -// 1f73b ALCHEMICAL SYMBOL FOR REALGAR -// 1f73c ALCHEMICAL SYMBOL FOR REALGAR-2 -// 1f73d ALCHEMICAL SYMBOL FOR AURIPIGMENT -// 1f73e ALCHEMICAL SYMBOL FOR BISMUTH ORE -// 1f73f ALCHEMICAL SYMBOL FOR TARTAR -// 1f740 ALCHEMICAL SYMBOL FOR TARTAR-2 -// 1f741 ALCHEMICAL SYMBOL FOR QUICK LIME -// 1f742 ALCHEMICAL SYMBOL FOR BORAX -// 1f743 ALCHEMICAL SYMBOL FOR BORAX-2 -// 1f744 ALCHEMICAL SYMBOL FOR BORAX-3 -// 1f745 ALCHEMICAL SYMBOL FOR ALUM -// 1f746 ALCHEMICAL SYMBOL FOR OIL -// 1f747 ALCHEMICAL SYMBOL FOR SPIRIT -// 1f748 ALCHEMICAL SYMBOL FOR TINCTURE -// 1f749 ALCHEMICAL SYMBOL FOR GUM -// 1f74a ALCHEMICAL SYMBOL FOR WAX -// 1f74b ALCHEMICAL SYMBOL FOR POWDER -// 1f74c ALCHEMICAL SYMBOL FOR CALX -// 1f74d ALCHEMICAL SYMBOL FOR TUTTY -// 1f74e ALCHEMICAL SYMBOL FOR CAPUT MORTUUM -// 1f74f ALCHEMICAL SYMBOL FOR SCEPTER OF JOVE -// 1f750 ALCHEMICAL SYMBOL FOR CADUCEUS -// 1f751 ALCHEMICAL SYMBOL FOR TRIDENT -// 1f752 ALCHEMICAL SYMBOL FOR STARRED TRIDENT -// 1f753 ALCHEMICAL SYMBOL FOR LODESTONE -// 1f754 ALCHEMICAL SYMBOL FOR SOAP -// 1f755 ALCHEMICAL SYMBOL FOR URINE -// 1f756 ALCHEMICAL SYMBOL FOR HORSE DUNG -// 1f757 ALCHEMICAL SYMBOL FOR ASHES -// 1f758 ALCHEMICAL SYMBOL FOR POT ASHES -// 1f759 ALCHEMICAL SYMBOL FOR BRICK -// 1f75a ALCHEMICAL SYMBOL FOR POWDERED BRICK -// 1f75b ALCHEMICAL SYMBOL FOR AMALGAM -// 1f75c ALCHEMICAL SYMBOL FOR STRATUM SUPER STRATUM -// 1f75d ALCHEMICAL SYMBOL FOR STRATUM SUPER STRATUM-2 -// 1f75e ALCHEMICAL SYMBOL FOR SUBLIMATION -// 1f75f ALCHEMICAL SYMBOL FOR PRECIPITATE -// 1f760 ALCHEMICAL SYMBOL FOR DISTILL -// 1f761 ALCHEMICAL SYMBOL FOR DISSOLVE -// 1f762 ALCHEMICAL SYMBOL FOR DISSOLVE-2 -// 1f763 ALCHEMICAL SYMBOL FOR PURIFY -// 1f764 ALCHEMICAL SYMBOL FOR PUTREFACTION -// 1f765 ALCHEMICAL SYMBOL FOR CRUCIBLE -// 1f766 ALCHEMICAL SYMBOL FOR CRUCIBLE-2 -// 1f767 ALCHEMICAL SYMBOL FOR CRUCIBLE-3 -// 1f768 ALCHEMICAL SYMBOL FOR CRUCIBLE-4 -// 1f769 ALCHEMICAL SYMBOL FOR CRUCIBLE-5 -// 1f76a ALCHEMICAL SYMBOL FOR ALEMBIC -// 1f76b ALCHEMICAL SYMBOL FOR BATH OF MARY -// 1f76c ALCHEMICAL SYMBOL FOR BATH OF VAPOURS -// 1f76d ALCHEMICAL SYMBOL FOR RETORT -// 1f76e ALCHEMICAL SYMBOL FOR HOUR -// 1f76f ALCHEMICAL SYMBOL FOR NIGHT -// 1f770 ALCHEMICAL SYMBOL FOR DAY-NIGHT -// 1f771 ALCHEMICAL SYMBOL FOR MONTH -// 1f772 ALCHEMICAL SYMBOL FOR HALF DRAM -// 1f773 ALCHEMICAL SYMBOL FOR HALF OUNCE - { 0x1F700, 0x74, 0x8, 0, 0 }, -// 1f780 BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE -// 1f781 BLACK UP-POINTING ISOSCELES RIGHT TRIANGLE -// 1f782 BLACK RIGHT-POINTING ISOSCELES RIGHT TRIANGLE -// 1f783 BLACK DOWN-POINTING ISOSCELES RIGHT TRIANGLE -// 1f784 BLACK SLIGHTLY SMALL CIRCLE -// 1f785 MEDIUM BOLD WHITE CIRCLE -// 1f786 BOLD WHITE CIRCLE -// 1f787 HEAVY WHITE CIRCLE -// 1f788 VERY HEAVY WHITE CIRCLE -// 1f789 EXTREMELY HEAVY WHITE CIRCLE -// 1f78a WHITE CIRCLE CONTAINING BLACK SMALL CIRCLE -// 1f78b ROUND TARGET -// 1f78c BLACK TINY SQUARE -// 1f78d BLACK SLIGHTLY SMALL SQUARE -// 1f78e LIGHT WHITE SQUARE -// 1f78f MEDIUM WHITE SQUARE -// 1f790 BOLD WHITE SQUARE -// 1f791 HEAVY WHITE SQUARE -// 1f792 VERY HEAVY WHITE SQUARE -// 1f793 EXTREMELY HEAVY WHITE SQUARE -// 1f794 WHITE SQUARE CONTAINING BLACK VERY SMALL SQUARE -// 1f795 WHITE SQUARE CONTAINING BLACK MEDIUM SQUARE -// 1f796 SQUARE TARGET -// 1f797 BLACK TINY DIAMOND -// 1f798 BLACK VERY SMALL DIAMOND -// 1f799 BLACK MEDIUM SMALL DIAMOND -// 1f79a WHITE DIAMOND CONTAINING BLACK VERY SMALL DIAMOND -// 1f79b WHITE DIAMOND CONTAINING BLACK MEDIUM DIAMOND -// 1f79c DIAMOND TARGET -// 1f79d BLACK TINY LOZENGE -// 1f79e BLACK VERY SMALL LOZENGE -// 1f79f BLACK MEDIUM SMALL LOZENGE -// 1f7a0 WHITE LOZENGE CONTAINING BLACK SMALL LOZENGE -// 1f7a1 THIN GREEK CROSS -// 1f7a2 LIGHT GREEK CROSS -// 1f7a3 MEDIUM GREEK CROSS -// 1f7a4 BOLD GREEK CROSS -// 1f7a5 VERY BOLD GREEK CROSS -// 1f7a6 VERY HEAVY GREEK CROSS -// 1f7a7 EXTREMELY HEAVY GREEK CROSS -// 1f7a8 THIN SALTIRE -// 1f7a9 LIGHT SALTIRE -// 1f7aa MEDIUM SALTIRE -// 1f7ab BOLD SALTIRE -// 1f7ac HEAVY SALTIRE -// 1f7ad VERY HEAVY SALTIRE -// 1f7ae EXTREMELY HEAVY SALTIRE -// 1f7af LIGHT FIVE SPOKED ASTERISK -// 1f7b0 MEDIUM FIVE SPOKED ASTERISK -// 1f7b1 BOLD FIVE SPOKED ASTERISK -// 1f7b2 HEAVY FIVE SPOKED ASTERISK -// 1f7b3 VERY HEAVY FIVE SPOKED ASTERISK -// 1f7b4 EXTREMELY HEAVY FIVE SPOKED ASTERISK -// 1f7b5 LIGHT SIX SPOKED ASTERISK -// 1f7b6 MEDIUM SIX SPOKED ASTERISK -// 1f7b7 BOLD SIX SPOKED ASTERISK -// 1f7b8 HEAVY SIX SPOKED ASTERISK -// 1f7b9 VERY HEAVY SIX SPOKED ASTERISK -// 1f7ba EXTREMELY HEAVY SIX SPOKED ASTERISK -// 1f7bb LIGHT EIGHT SPOKED ASTERISK -// 1f7bc MEDIUM EIGHT SPOKED ASTERISK -// 1f7bd BOLD EIGHT SPOKED ASTERISK -// 1f7be HEAVY EIGHT SPOKED ASTERISK -// 1f7bf VERY HEAVY EIGHT SPOKED ASTERISK -// 1f7c0 LIGHT THREE POINTED BLACK STAR -// 1f7c1 MEDIUM THREE POINTED BLACK STAR -// 1f7c2 THREE POINTED BLACK STAR -// 1f7c3 MEDIUM THREE POINTED PINWHEEL STAR -// 1f7c4 LIGHT FOUR POINTED BLACK STAR -// 1f7c5 MEDIUM FOUR POINTED BLACK STAR -// 1f7c6 FOUR POINTED BLACK STAR -// 1f7c7 MEDIUM FOUR POINTED PINWHEEL STAR -// 1f7c8 REVERSE LIGHT FOUR POINTED PINWHEEL STAR -// 1f7c9 LIGHT FIVE POINTED BLACK STAR -// 1f7ca HEAVY FIVE POINTED BLACK STAR -// 1f7cb MEDIUM SIX POINTED BLACK STAR -// 1f7cc HEAVY SIX POINTED BLACK STAR -// 1f7cd SIX POINTED PINWHEEL STAR -// 1f7ce MEDIUM EIGHT POINTED BLACK STAR -// 1f7cf HEAVY EIGHT POINTED BLACK STAR -// 1f7d0 VERY HEAVY EIGHT POINTED BLACK STAR -// 1f7d1 HEAVY EIGHT POINTED PINWHEEL STAR -// 1f7d2 LIGHT TWELVE POINTED BLACK STAR -// 1f7d3 HEAVY TWELVE POINTED BLACK STAR -// 1f7d4 HEAVY TWELVE POINTED PINWHEEL STAR - { 0x1F780, 0x55, 0x8, 0, 0 }, -// 1f800 LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD -// 1f801 UPWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD -// 1f802 RIGHTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD -// 1f803 DOWNWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD -// 1f804 LEFTWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD -// 1f805 UPWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD -// 1f806 RIGHTWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD -// 1f807 DOWNWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD -// 1f808 LEFTWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD -// 1f809 UPWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD -// 1f80a RIGHTWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD -// 1f80b DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD - { 0x1F800, 0xC, 0x8, 0, 0 }, -// 1f810 LEFTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD -// 1f811 UPWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD -// 1f812 RIGHTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD -// 1f813 DOWNWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD -// 1f814 LEFTWARDS ARROW WITH EQUILATERAL ARROWHEAD -// 1f815 UPWARDS ARROW WITH EQUILATERAL ARROWHEAD -// 1f816 RIGHTWARDS ARROW WITH EQUILATERAL ARROWHEAD -// 1f817 DOWNWARDS ARROW WITH EQUILATERAL ARROWHEAD -// 1f818 HEAVY LEFTWARDS ARROW WITH EQUILATERAL ARROWHEAD -// 1f819 HEAVY UPWARDS ARROW WITH EQUILATERAL ARROWHEAD -// 1f81a HEAVY RIGHTWARDS ARROW WITH EQUILATERAL ARROWHEAD -// 1f81b HEAVY DOWNWARDS ARROW WITH EQUILATERAL ARROWHEAD -// 1f81c HEAVY LEFTWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD -// 1f81d HEAVY UPWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD -// 1f81e HEAVY RIGHTWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD -// 1f81f HEAVY DOWNWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD -// 1f820 LEFTWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT -// 1f821 UPWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT -// 1f822 RIGHTWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT -// 1f823 DOWNWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT -// 1f824 LEFTWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT -// 1f825 UPWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT -// 1f826 RIGHTWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT -// 1f827 DOWNWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT -// 1f828 LEFTWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT -// 1f829 UPWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT -// 1f82a RIGHTWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT -// 1f82b DOWNWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT -// 1f82c LEFTWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT -// 1f82d UPWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT -// 1f82e RIGHTWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT -// 1f82f DOWNWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT -// 1f830 LEFTWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT -// 1f831 UPWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT -// 1f832 RIGHTWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT -// 1f833 DOWNWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT -// 1f834 LEFTWARDS FINGER-POST ARROW -// 1f835 UPWARDS FINGER-POST ARROW -// 1f836 RIGHTWARDS FINGER-POST ARROW -// 1f837 DOWNWARDS FINGER-POST ARROW -// 1f838 LEFTWARDS SQUARED ARROW -// 1f839 UPWARDS SQUARED ARROW -// 1f83a RIGHTWARDS SQUARED ARROW -// 1f83b DOWNWARDS SQUARED ARROW -// 1f83c LEFTWARDS COMPRESSED ARROW -// 1f83d UPWARDS COMPRESSED ARROW -// 1f83e RIGHTWARDS COMPRESSED ARROW -// 1f83f DOWNWARDS COMPRESSED ARROW -// 1f840 LEFTWARDS HEAVY COMPRESSED ARROW -// 1f841 UPWARDS HEAVY COMPRESSED ARROW -// 1f842 RIGHTWARDS HEAVY COMPRESSED ARROW -// 1f843 DOWNWARDS HEAVY COMPRESSED ARROW -// 1f844 LEFTWARDS HEAVY ARROW -// 1f845 UPWARDS HEAVY ARROW -// 1f846 RIGHTWARDS HEAVY ARROW -// 1f847 DOWNWARDS HEAVY ARROW - { 0x1F810, 0x38, 0x8, 0, 0 }, -// 1f850 LEFTWARDS SANS-SERIF ARROW -// 1f851 UPWARDS SANS-SERIF ARROW -// 1f852 RIGHTWARDS SANS-SERIF ARROW -// 1f853 DOWNWARDS SANS-SERIF ARROW -// 1f854 NORTH WEST SANS-SERIF ARROW -// 1f855 NORTH EAST SANS-SERIF ARROW -// 1f856 SOUTH EAST SANS-SERIF ARROW -// 1f857 SOUTH WEST SANS-SERIF ARROW -// 1f858 LEFT RIGHT SANS-SERIF ARROW -// 1f859 UP DOWN SANS-SERIF ARROW - { 0x1F850, 0xA, 0x8, 0, 0 }, -// 1f860 WIDE-HEADED LEFTWARDS LIGHT BARB ARROW -// 1f861 WIDE-HEADED UPWARDS LIGHT BARB ARROW -// 1f862 WIDE-HEADED RIGHTWARDS LIGHT BARB ARROW -// 1f863 WIDE-HEADED DOWNWARDS LIGHT BARB ARROW -// 1f864 WIDE-HEADED NORTH WEST LIGHT BARB ARROW -// 1f865 WIDE-HEADED NORTH EAST LIGHT BARB ARROW -// 1f866 WIDE-HEADED SOUTH EAST LIGHT BARB ARROW -// 1f867 WIDE-HEADED SOUTH WEST LIGHT BARB ARROW -// 1f868 WIDE-HEADED LEFTWARDS BARB ARROW -// 1f869 WIDE-HEADED UPWARDS BARB ARROW -// 1f86a WIDE-HEADED RIGHTWARDS BARB ARROW -// 1f86b WIDE-HEADED DOWNWARDS BARB ARROW -// 1f86c WIDE-HEADED NORTH WEST BARB ARROW -// 1f86d WIDE-HEADED NORTH EAST BARB ARROW -// 1f86e WIDE-HEADED SOUTH EAST BARB ARROW -// 1f86f WIDE-HEADED SOUTH WEST BARB ARROW -// 1f870 WIDE-HEADED LEFTWARDS MEDIUM BARB ARROW -// 1f871 WIDE-HEADED UPWARDS MEDIUM BARB ARROW -// 1f872 WIDE-HEADED RIGHTWARDS MEDIUM BARB ARROW -// 1f873 WIDE-HEADED DOWNWARDS MEDIUM BARB ARROW -// 1f874 WIDE-HEADED NORTH WEST MEDIUM BARB ARROW -// 1f875 WIDE-HEADED NORTH EAST MEDIUM BARB ARROW -// 1f876 WIDE-HEADED SOUTH EAST MEDIUM BARB ARROW -// 1f877 WIDE-HEADED SOUTH WEST MEDIUM BARB ARROW -// 1f878 WIDE-HEADED LEFTWARDS HEAVY BARB ARROW -// 1f879 WIDE-HEADED UPWARDS HEAVY BARB ARROW -// 1f87a WIDE-HEADED RIGHTWARDS HEAVY BARB ARROW -// 1f87b WIDE-HEADED DOWNWARDS HEAVY BARB ARROW -// 1f87c WIDE-HEADED NORTH WEST HEAVY BARB ARROW -// 1f87d WIDE-HEADED NORTH EAST HEAVY BARB ARROW -// 1f87e WIDE-HEADED SOUTH EAST HEAVY BARB ARROW -// 1f87f WIDE-HEADED SOUTH WEST HEAVY BARB ARROW -// 1f880 WIDE-HEADED LEFTWARDS VERY HEAVY BARB ARROW -// 1f881 WIDE-HEADED UPWARDS VERY HEAVY BARB ARROW -// 1f882 WIDE-HEADED RIGHTWARDS VERY HEAVY BARB ARROW -// 1f883 WIDE-HEADED DOWNWARDS VERY HEAVY BARB ARROW -// 1f884 WIDE-HEADED NORTH WEST VERY HEAVY BARB ARROW -// 1f885 WIDE-HEADED NORTH EAST VERY HEAVY BARB ARROW -// 1f886 WIDE-HEADED SOUTH EAST VERY HEAVY BARB ARROW -// 1f887 WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW - { 0x1F860, 0x28, 0x8, 0, 0 }, -// 1f890 LEFTWARDS TRIANGLE ARROWHEAD -// 1f891 UPWARDS TRIANGLE ARROWHEAD -// 1f892 RIGHTWARDS TRIANGLE ARROWHEAD -// 1f893 DOWNWARDS TRIANGLE ARROWHEAD -// 1f894 LEFTWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD -// 1f895 UPWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD -// 1f896 RIGHTWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD -// 1f897 DOWNWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD -// 1f898 LEFTWARDS ARROW WITH NOTCHED TAIL -// 1f899 UPWARDS ARROW WITH NOTCHED TAIL -// 1f89a RIGHTWARDS ARROW WITH NOTCHED TAIL -// 1f89b DOWNWARDS ARROW WITH NOTCHED TAIL -// 1f89c HEAVY ARROW SHAFT WIDTH ONE -// 1f89d HEAVY ARROW SHAFT WIDTH TWO THIRDS -// 1f89e HEAVY ARROW SHAFT WIDTH ONE HALF -// 1f89f HEAVY ARROW SHAFT WIDTH ONE THIRD -// 1f8a0 LEFTWARDS BOTTOM-SHADED WHITE ARROW -// 1f8a1 RIGHTWARDS BOTTOM SHADED WHITE ARROW -// 1f8a2 LEFTWARDS TOP SHADED WHITE ARROW -// 1f8a3 RIGHTWARDS TOP SHADED WHITE ARROW -// 1f8a4 LEFTWARDS LEFT-SHADED WHITE ARROW -// 1f8a5 RIGHTWARDS RIGHT-SHADED WHITE ARROW -// 1f8a6 LEFTWARDS RIGHT-SHADED WHITE ARROW -// 1f8a7 RIGHTWARDS LEFT-SHADED WHITE ARROW -// 1f8a8 LEFTWARDS BACK-TILTED SHADOWED WHITE ARROW -// 1f8a9 RIGHTWARDS BACK-TILTED SHADOWED WHITE ARROW -// 1f8aa LEFTWARDS FRONT-TILTED SHADOWED WHITE ARROW -// 1f8ab RIGHTWARDS FRONT-TILTED SHADOWED WHITE ARROW -// 1f8ac WHITE ARROW SHAFT WIDTH ONE -// 1f8ad WHITE ARROW SHAFT WIDTH TWO THIRDS - { 0x1F890, 0x1E, 0x8, 0, 0 }, -// 20000 - { 0x20000, 0x1, 0x9, 0, 0 }, -// 2a6d6 - { 0x2A6D6, 0x1, 0x9, 0, 0 }, -// 2a700 - { 0x2A700, 0x1, 0x9, 0, 0 }, -// 2b734 - { 0x2B734, 0x1, 0x9, 0, 0 }, -// 2b740 - { 0x2B740, 0x1, 0x9, 0, 0 }, -// 2b81d - { 0x2B81D, 0x1, 0x9, 0, 0 }, -// 2f800 CJK COMPATIBILITY IDEOGRAPH-2F800 -// 2f801 CJK COMPATIBILITY IDEOGRAPH-2F801 -// 2f802 CJK COMPATIBILITY IDEOGRAPH-2F802 -// 2f803 CJK COMPATIBILITY IDEOGRAPH-2F803 -// 2f804 CJK COMPATIBILITY IDEOGRAPH-2F804 -// 2f805 CJK COMPATIBILITY IDEOGRAPH-2F805 -// 2f806 CJK COMPATIBILITY IDEOGRAPH-2F806 -// 2f807 CJK COMPATIBILITY IDEOGRAPH-2F807 -// 2f808 CJK COMPATIBILITY IDEOGRAPH-2F808 -// 2f809 CJK COMPATIBILITY IDEOGRAPH-2F809 -// 2f80a CJK COMPATIBILITY IDEOGRAPH-2F80A -// 2f80b CJK COMPATIBILITY IDEOGRAPH-2F80B -// 2f80c CJK COMPATIBILITY IDEOGRAPH-2F80C -// 2f80d CJK COMPATIBILITY IDEOGRAPH-2F80D -// 2f80e CJK COMPATIBILITY IDEOGRAPH-2F80E -// 2f80f CJK COMPATIBILITY IDEOGRAPH-2F80F -// 2f810 CJK COMPATIBILITY IDEOGRAPH-2F810 -// 2f811 CJK COMPATIBILITY IDEOGRAPH-2F811 -// 2f812 CJK COMPATIBILITY IDEOGRAPH-2F812 -// 2f813 CJK COMPATIBILITY IDEOGRAPH-2F813 -// 2f814 CJK COMPATIBILITY IDEOGRAPH-2F814 -// 2f815 CJK COMPATIBILITY IDEOGRAPH-2F815 -// 2f816 CJK COMPATIBILITY IDEOGRAPH-2F816 -// 2f817 CJK COMPATIBILITY IDEOGRAPH-2F817 -// 2f818 CJK COMPATIBILITY IDEOGRAPH-2F818 -// 2f819 CJK COMPATIBILITY IDEOGRAPH-2F819 -// 2f81a CJK COMPATIBILITY IDEOGRAPH-2F81A -// 2f81b CJK COMPATIBILITY IDEOGRAPH-2F81B -// 2f81c CJK COMPATIBILITY IDEOGRAPH-2F81C -// 2f81d CJK COMPATIBILITY IDEOGRAPH-2F81D -// 2f81e CJK COMPATIBILITY IDEOGRAPH-2F81E -// 2f81f CJK COMPATIBILITY IDEOGRAPH-2F81F -// 2f820 CJK COMPATIBILITY IDEOGRAPH-2F820 -// 2f821 CJK COMPATIBILITY IDEOGRAPH-2F821 -// 2f822 CJK COMPATIBILITY IDEOGRAPH-2F822 -// 2f823 CJK COMPATIBILITY IDEOGRAPH-2F823 -// 2f824 CJK COMPATIBILITY IDEOGRAPH-2F824 -// 2f825 CJK COMPATIBILITY IDEOGRAPH-2F825 -// 2f826 CJK COMPATIBILITY IDEOGRAPH-2F826 -// 2f827 CJK COMPATIBILITY IDEOGRAPH-2F827 -// 2f828 CJK COMPATIBILITY IDEOGRAPH-2F828 -// 2f829 CJK COMPATIBILITY IDEOGRAPH-2F829 -// 2f82a CJK COMPATIBILITY IDEOGRAPH-2F82A -// 2f82b CJK COMPATIBILITY IDEOGRAPH-2F82B -// 2f82c CJK COMPATIBILITY IDEOGRAPH-2F82C -// 2f82d CJK COMPATIBILITY IDEOGRAPH-2F82D -// 2f82e CJK COMPATIBILITY IDEOGRAPH-2F82E -// 2f82f CJK COMPATIBILITY IDEOGRAPH-2F82F -// 2f830 CJK COMPATIBILITY IDEOGRAPH-2F830 -// 2f831 CJK COMPATIBILITY IDEOGRAPH-2F831 -// 2f832 CJK COMPATIBILITY IDEOGRAPH-2F832 -// 2f833 CJK COMPATIBILITY IDEOGRAPH-2F833 -// 2f834 CJK COMPATIBILITY IDEOGRAPH-2F834 -// 2f835 CJK COMPATIBILITY IDEOGRAPH-2F835 -// 2f836 CJK COMPATIBILITY IDEOGRAPH-2F836 -// 2f837 CJK COMPATIBILITY IDEOGRAPH-2F837 -// 2f838 CJK COMPATIBILITY IDEOGRAPH-2F838 -// 2f839 CJK COMPATIBILITY IDEOGRAPH-2F839 -// 2f83a CJK COMPATIBILITY IDEOGRAPH-2F83A -// 2f83b CJK COMPATIBILITY IDEOGRAPH-2F83B -// 2f83c CJK COMPATIBILITY IDEOGRAPH-2F83C -// 2f83d CJK COMPATIBILITY IDEOGRAPH-2F83D -// 2f83e CJK COMPATIBILITY IDEOGRAPH-2F83E -// 2f83f CJK COMPATIBILITY IDEOGRAPH-2F83F -// 2f840 CJK COMPATIBILITY IDEOGRAPH-2F840 -// 2f841 CJK COMPATIBILITY IDEOGRAPH-2F841 -// 2f842 CJK COMPATIBILITY IDEOGRAPH-2F842 -// 2f843 CJK COMPATIBILITY IDEOGRAPH-2F843 -// 2f844 CJK COMPATIBILITY IDEOGRAPH-2F844 -// 2f845 CJK COMPATIBILITY IDEOGRAPH-2F845 -// 2f846 CJK COMPATIBILITY IDEOGRAPH-2F846 -// 2f847 CJK COMPATIBILITY IDEOGRAPH-2F847 -// 2f848 CJK COMPATIBILITY IDEOGRAPH-2F848 -// 2f849 CJK COMPATIBILITY IDEOGRAPH-2F849 -// 2f84a CJK COMPATIBILITY IDEOGRAPH-2F84A -// 2f84b CJK COMPATIBILITY IDEOGRAPH-2F84B -// 2f84c CJK COMPATIBILITY IDEOGRAPH-2F84C -// 2f84d CJK COMPATIBILITY IDEOGRAPH-2F84D -// 2f84e CJK COMPATIBILITY IDEOGRAPH-2F84E -// 2f84f CJK COMPATIBILITY IDEOGRAPH-2F84F -// 2f850 CJK COMPATIBILITY IDEOGRAPH-2F850 -// 2f851 CJK COMPATIBILITY IDEOGRAPH-2F851 -// 2f852 CJK COMPATIBILITY IDEOGRAPH-2F852 -// 2f853 CJK COMPATIBILITY IDEOGRAPH-2F853 -// 2f854 CJK COMPATIBILITY IDEOGRAPH-2F854 -// 2f855 CJK COMPATIBILITY IDEOGRAPH-2F855 -// 2f856 CJK COMPATIBILITY IDEOGRAPH-2F856 -// 2f857 CJK COMPATIBILITY IDEOGRAPH-2F857 -// 2f858 CJK COMPATIBILITY IDEOGRAPH-2F858 -// 2f859 CJK COMPATIBILITY IDEOGRAPH-2F859 -// 2f85a CJK COMPATIBILITY IDEOGRAPH-2F85A -// 2f85b CJK COMPATIBILITY IDEOGRAPH-2F85B -// 2f85c CJK COMPATIBILITY IDEOGRAPH-2F85C -// 2f85d CJK COMPATIBILITY IDEOGRAPH-2F85D -// 2f85e CJK COMPATIBILITY IDEOGRAPH-2F85E -// 2f85f CJK COMPATIBILITY IDEOGRAPH-2F85F -// 2f860 CJK COMPATIBILITY IDEOGRAPH-2F860 -// 2f861 CJK COMPATIBILITY IDEOGRAPH-2F861 -// 2f862 CJK COMPATIBILITY IDEOGRAPH-2F862 -// 2f863 CJK COMPATIBILITY IDEOGRAPH-2F863 -// 2f864 CJK COMPATIBILITY IDEOGRAPH-2F864 -// 2f865 CJK COMPATIBILITY IDEOGRAPH-2F865 -// 2f866 CJK COMPATIBILITY IDEOGRAPH-2F866 -// 2f867 CJK COMPATIBILITY IDEOGRAPH-2F867 -// 2f868 CJK COMPATIBILITY IDEOGRAPH-2F868 -// 2f869 CJK COMPATIBILITY IDEOGRAPH-2F869 -// 2f86a CJK COMPATIBILITY IDEOGRAPH-2F86A -// 2f86b CJK COMPATIBILITY IDEOGRAPH-2F86B -// 2f86c CJK COMPATIBILITY IDEOGRAPH-2F86C -// 2f86d CJK COMPATIBILITY IDEOGRAPH-2F86D -// 2f86e CJK COMPATIBILITY IDEOGRAPH-2F86E -// 2f86f CJK COMPATIBILITY IDEOGRAPH-2F86F -// 2f870 CJK COMPATIBILITY IDEOGRAPH-2F870 -// 2f871 CJK COMPATIBILITY IDEOGRAPH-2F871 -// 2f872 CJK COMPATIBILITY IDEOGRAPH-2F872 -// 2f873 CJK COMPATIBILITY IDEOGRAPH-2F873 -// 2f874 CJK COMPATIBILITY IDEOGRAPH-2F874 -// 2f875 CJK COMPATIBILITY IDEOGRAPH-2F875 -// 2f876 CJK COMPATIBILITY IDEOGRAPH-2F876 -// 2f877 CJK COMPATIBILITY IDEOGRAPH-2F877 -// 2f878 CJK COMPATIBILITY IDEOGRAPH-2F878 -// 2f879 CJK COMPATIBILITY IDEOGRAPH-2F879 -// 2f87a CJK COMPATIBILITY IDEOGRAPH-2F87A -// 2f87b CJK COMPATIBILITY IDEOGRAPH-2F87B -// 2f87c CJK COMPATIBILITY IDEOGRAPH-2F87C -// 2f87d CJK COMPATIBILITY IDEOGRAPH-2F87D -// 2f87e CJK COMPATIBILITY IDEOGRAPH-2F87E -// 2f87f CJK COMPATIBILITY IDEOGRAPH-2F87F -// 2f880 CJK COMPATIBILITY IDEOGRAPH-2F880 -// 2f881 CJK COMPATIBILITY IDEOGRAPH-2F881 -// 2f882 CJK COMPATIBILITY IDEOGRAPH-2F882 -// 2f883 CJK COMPATIBILITY IDEOGRAPH-2F883 -// 2f884 CJK COMPATIBILITY IDEOGRAPH-2F884 -// 2f885 CJK COMPATIBILITY IDEOGRAPH-2F885 -// 2f886 CJK COMPATIBILITY IDEOGRAPH-2F886 -// 2f887 CJK COMPATIBILITY IDEOGRAPH-2F887 -// 2f888 CJK COMPATIBILITY IDEOGRAPH-2F888 -// 2f889 CJK COMPATIBILITY IDEOGRAPH-2F889 -// 2f88a CJK COMPATIBILITY IDEOGRAPH-2F88A -// 2f88b CJK COMPATIBILITY IDEOGRAPH-2F88B -// 2f88c CJK COMPATIBILITY IDEOGRAPH-2F88C -// 2f88d CJK COMPATIBILITY IDEOGRAPH-2F88D -// 2f88e CJK COMPATIBILITY IDEOGRAPH-2F88E -// 2f88f CJK COMPATIBILITY IDEOGRAPH-2F88F -// 2f890 CJK COMPATIBILITY IDEOGRAPH-2F890 -// 2f891 CJK COMPATIBILITY IDEOGRAPH-2F891 -// 2f892 CJK COMPATIBILITY IDEOGRAPH-2F892 -// 2f893 CJK COMPATIBILITY IDEOGRAPH-2F893 -// 2f894 CJK COMPATIBILITY IDEOGRAPH-2F894 -// 2f895 CJK COMPATIBILITY IDEOGRAPH-2F895 -// 2f896 CJK COMPATIBILITY IDEOGRAPH-2F896 -// 2f897 CJK COMPATIBILITY IDEOGRAPH-2F897 -// 2f898 CJK COMPATIBILITY IDEOGRAPH-2F898 -// 2f899 CJK COMPATIBILITY IDEOGRAPH-2F899 -// 2f89a CJK COMPATIBILITY IDEOGRAPH-2F89A -// 2f89b CJK COMPATIBILITY IDEOGRAPH-2F89B -// 2f89c CJK COMPATIBILITY IDEOGRAPH-2F89C -// 2f89d CJK COMPATIBILITY IDEOGRAPH-2F89D -// 2f89e CJK COMPATIBILITY IDEOGRAPH-2F89E -// 2f89f CJK COMPATIBILITY IDEOGRAPH-2F89F -// 2f8a0 CJK COMPATIBILITY IDEOGRAPH-2F8A0 -// 2f8a1 CJK COMPATIBILITY IDEOGRAPH-2F8A1 -// 2f8a2 CJK COMPATIBILITY IDEOGRAPH-2F8A2 -// 2f8a3 CJK COMPATIBILITY IDEOGRAPH-2F8A3 -// 2f8a4 CJK COMPATIBILITY IDEOGRAPH-2F8A4 -// 2f8a5 CJK COMPATIBILITY IDEOGRAPH-2F8A5 -// 2f8a6 CJK COMPATIBILITY IDEOGRAPH-2F8A6 -// 2f8a7 CJK COMPATIBILITY IDEOGRAPH-2F8A7 -// 2f8a8 CJK COMPATIBILITY IDEOGRAPH-2F8A8 -// 2f8a9 CJK COMPATIBILITY IDEOGRAPH-2F8A9 -// 2f8aa CJK COMPATIBILITY IDEOGRAPH-2F8AA -// 2f8ab CJK COMPATIBILITY IDEOGRAPH-2F8AB -// 2f8ac CJK COMPATIBILITY IDEOGRAPH-2F8AC -// 2f8ad CJK COMPATIBILITY IDEOGRAPH-2F8AD -// 2f8ae CJK COMPATIBILITY IDEOGRAPH-2F8AE -// 2f8af CJK COMPATIBILITY IDEOGRAPH-2F8AF -// 2f8b0 CJK COMPATIBILITY IDEOGRAPH-2F8B0 -// 2f8b1 CJK COMPATIBILITY IDEOGRAPH-2F8B1 -// 2f8b2 CJK COMPATIBILITY IDEOGRAPH-2F8B2 -// 2f8b3 CJK COMPATIBILITY IDEOGRAPH-2F8B3 -// 2f8b4 CJK COMPATIBILITY IDEOGRAPH-2F8B4 -// 2f8b5 CJK COMPATIBILITY IDEOGRAPH-2F8B5 -// 2f8b6 CJK COMPATIBILITY IDEOGRAPH-2F8B6 -// 2f8b7 CJK COMPATIBILITY IDEOGRAPH-2F8B7 -// 2f8b8 CJK COMPATIBILITY IDEOGRAPH-2F8B8 -// 2f8b9 CJK COMPATIBILITY IDEOGRAPH-2F8B9 -// 2f8ba CJK COMPATIBILITY IDEOGRAPH-2F8BA -// 2f8bb CJK COMPATIBILITY IDEOGRAPH-2F8BB -// 2f8bc CJK COMPATIBILITY IDEOGRAPH-2F8BC -// 2f8bd CJK COMPATIBILITY IDEOGRAPH-2F8BD -// 2f8be CJK COMPATIBILITY IDEOGRAPH-2F8BE -// 2f8bf CJK COMPATIBILITY IDEOGRAPH-2F8BF -// 2f8c0 CJK COMPATIBILITY IDEOGRAPH-2F8C0 -// 2f8c1 CJK COMPATIBILITY IDEOGRAPH-2F8C1 -// 2f8c2 CJK COMPATIBILITY IDEOGRAPH-2F8C2 -// 2f8c3 CJK COMPATIBILITY IDEOGRAPH-2F8C3 -// 2f8c4 CJK COMPATIBILITY IDEOGRAPH-2F8C4 -// 2f8c5 CJK COMPATIBILITY IDEOGRAPH-2F8C5 -// 2f8c6 CJK COMPATIBILITY IDEOGRAPH-2F8C6 -// 2f8c7 CJK COMPATIBILITY IDEOGRAPH-2F8C7 -// 2f8c8 CJK COMPATIBILITY IDEOGRAPH-2F8C8 -// 2f8c9 CJK COMPATIBILITY IDEOGRAPH-2F8C9 -// 2f8ca CJK COMPATIBILITY IDEOGRAPH-2F8CA -// 2f8cb CJK COMPATIBILITY IDEOGRAPH-2F8CB -// 2f8cc CJK COMPATIBILITY IDEOGRAPH-2F8CC -// 2f8cd CJK COMPATIBILITY IDEOGRAPH-2F8CD -// 2f8ce CJK COMPATIBILITY IDEOGRAPH-2F8CE -// 2f8cf CJK COMPATIBILITY IDEOGRAPH-2F8CF -// 2f8d0 CJK COMPATIBILITY IDEOGRAPH-2F8D0 -// 2f8d1 CJK COMPATIBILITY IDEOGRAPH-2F8D1 -// 2f8d2 CJK COMPATIBILITY IDEOGRAPH-2F8D2 -// 2f8d3 CJK COMPATIBILITY IDEOGRAPH-2F8D3 -// 2f8d4 CJK COMPATIBILITY IDEOGRAPH-2F8D4 -// 2f8d5 CJK COMPATIBILITY IDEOGRAPH-2F8D5 -// 2f8d6 CJK COMPATIBILITY IDEOGRAPH-2F8D6 -// 2f8d7 CJK COMPATIBILITY IDEOGRAPH-2F8D7 -// 2f8d8 CJK COMPATIBILITY IDEOGRAPH-2F8D8 -// 2f8d9 CJK COMPATIBILITY IDEOGRAPH-2F8D9 -// 2f8da CJK COMPATIBILITY IDEOGRAPH-2F8DA -// 2f8db CJK COMPATIBILITY IDEOGRAPH-2F8DB -// 2f8dc CJK COMPATIBILITY IDEOGRAPH-2F8DC -// 2f8dd CJK COMPATIBILITY IDEOGRAPH-2F8DD -// 2f8de CJK COMPATIBILITY IDEOGRAPH-2F8DE -// 2f8df CJK COMPATIBILITY IDEOGRAPH-2F8DF -// 2f8e0 CJK COMPATIBILITY IDEOGRAPH-2F8E0 -// 2f8e1 CJK COMPATIBILITY IDEOGRAPH-2F8E1 -// 2f8e2 CJK COMPATIBILITY IDEOGRAPH-2F8E2 -// 2f8e3 CJK COMPATIBILITY IDEOGRAPH-2F8E3 -// 2f8e4 CJK COMPATIBILITY IDEOGRAPH-2F8E4 -// 2f8e5 CJK COMPATIBILITY IDEOGRAPH-2F8E5 -// 2f8e6 CJK COMPATIBILITY IDEOGRAPH-2F8E6 -// 2f8e7 CJK COMPATIBILITY IDEOGRAPH-2F8E7 -// 2f8e8 CJK COMPATIBILITY IDEOGRAPH-2F8E8 -// 2f8e9 CJK COMPATIBILITY IDEOGRAPH-2F8E9 -// 2f8ea CJK COMPATIBILITY IDEOGRAPH-2F8EA -// 2f8eb CJK COMPATIBILITY IDEOGRAPH-2F8EB -// 2f8ec CJK COMPATIBILITY IDEOGRAPH-2F8EC -// 2f8ed CJK COMPATIBILITY IDEOGRAPH-2F8ED -// 2f8ee CJK COMPATIBILITY IDEOGRAPH-2F8EE -// 2f8ef CJK COMPATIBILITY IDEOGRAPH-2F8EF -// 2f8f0 CJK COMPATIBILITY IDEOGRAPH-2F8F0 -// 2f8f1 CJK COMPATIBILITY IDEOGRAPH-2F8F1 -// 2f8f2 CJK COMPATIBILITY IDEOGRAPH-2F8F2 -// 2f8f3 CJK COMPATIBILITY IDEOGRAPH-2F8F3 -// 2f8f4 CJK COMPATIBILITY IDEOGRAPH-2F8F4 -// 2f8f5 CJK COMPATIBILITY IDEOGRAPH-2F8F5 -// 2f8f6 CJK COMPATIBILITY IDEOGRAPH-2F8F6 -// 2f8f7 CJK COMPATIBILITY IDEOGRAPH-2F8F7 -// 2f8f8 CJK COMPATIBILITY IDEOGRAPH-2F8F8 -// 2f8f9 CJK COMPATIBILITY IDEOGRAPH-2F8F9 -// 2f8fa CJK COMPATIBILITY IDEOGRAPH-2F8FA -// 2f8fb CJK COMPATIBILITY IDEOGRAPH-2F8FB -// 2f8fc CJK COMPATIBILITY IDEOGRAPH-2F8FC -// 2f8fd CJK COMPATIBILITY IDEOGRAPH-2F8FD -// 2f8fe CJK COMPATIBILITY IDEOGRAPH-2F8FE -// 2f8ff CJK COMPATIBILITY IDEOGRAPH-2F8FF -// 2f900 CJK COMPATIBILITY IDEOGRAPH-2F900 -// 2f901 CJK COMPATIBILITY IDEOGRAPH-2F901 -// 2f902 CJK COMPATIBILITY IDEOGRAPH-2F902 -// 2f903 CJK COMPATIBILITY IDEOGRAPH-2F903 -// 2f904 CJK COMPATIBILITY IDEOGRAPH-2F904 -// 2f905 CJK COMPATIBILITY IDEOGRAPH-2F905 -// 2f906 CJK COMPATIBILITY IDEOGRAPH-2F906 -// 2f907 CJK COMPATIBILITY IDEOGRAPH-2F907 -// 2f908 CJK COMPATIBILITY IDEOGRAPH-2F908 -// 2f909 CJK COMPATIBILITY IDEOGRAPH-2F909 -// 2f90a CJK COMPATIBILITY IDEOGRAPH-2F90A -// 2f90b CJK COMPATIBILITY IDEOGRAPH-2F90B -// 2f90c CJK COMPATIBILITY IDEOGRAPH-2F90C -// 2f90d CJK COMPATIBILITY IDEOGRAPH-2F90D -// 2f90e CJK COMPATIBILITY IDEOGRAPH-2F90E -// 2f90f CJK COMPATIBILITY IDEOGRAPH-2F90F -// 2f910 CJK COMPATIBILITY IDEOGRAPH-2F910 -// 2f911 CJK COMPATIBILITY IDEOGRAPH-2F911 -// 2f912 CJK COMPATIBILITY IDEOGRAPH-2F912 -// 2f913 CJK COMPATIBILITY IDEOGRAPH-2F913 -// 2f914 CJK COMPATIBILITY IDEOGRAPH-2F914 -// 2f915 CJK COMPATIBILITY IDEOGRAPH-2F915 -// 2f916 CJK COMPATIBILITY IDEOGRAPH-2F916 -// 2f917 CJK COMPATIBILITY IDEOGRAPH-2F917 -// 2f918 CJK COMPATIBILITY IDEOGRAPH-2F918 -// 2f919 CJK COMPATIBILITY IDEOGRAPH-2F919 -// 2f91a CJK COMPATIBILITY IDEOGRAPH-2F91A -// 2f91b CJK COMPATIBILITY IDEOGRAPH-2F91B -// 2f91c CJK COMPATIBILITY IDEOGRAPH-2F91C -// 2f91d CJK COMPATIBILITY IDEOGRAPH-2F91D -// 2f91e CJK COMPATIBILITY IDEOGRAPH-2F91E -// 2f91f CJK COMPATIBILITY IDEOGRAPH-2F91F -// 2f920 CJK COMPATIBILITY IDEOGRAPH-2F920 -// 2f921 CJK COMPATIBILITY IDEOGRAPH-2F921 -// 2f922 CJK COMPATIBILITY IDEOGRAPH-2F922 -// 2f923 CJK COMPATIBILITY IDEOGRAPH-2F923 -// 2f924 CJK COMPATIBILITY IDEOGRAPH-2F924 -// 2f925 CJK COMPATIBILITY IDEOGRAPH-2F925 -// 2f926 CJK COMPATIBILITY IDEOGRAPH-2F926 -// 2f927 CJK COMPATIBILITY IDEOGRAPH-2F927 -// 2f928 CJK COMPATIBILITY IDEOGRAPH-2F928 -// 2f929 CJK COMPATIBILITY IDEOGRAPH-2F929 -// 2f92a CJK COMPATIBILITY IDEOGRAPH-2F92A -// 2f92b CJK COMPATIBILITY IDEOGRAPH-2F92B -// 2f92c CJK COMPATIBILITY IDEOGRAPH-2F92C -// 2f92d CJK COMPATIBILITY IDEOGRAPH-2F92D -// 2f92e CJK COMPATIBILITY IDEOGRAPH-2F92E -// 2f92f CJK COMPATIBILITY IDEOGRAPH-2F92F -// 2f930 CJK COMPATIBILITY IDEOGRAPH-2F930 -// 2f931 CJK COMPATIBILITY IDEOGRAPH-2F931 -// 2f932 CJK COMPATIBILITY IDEOGRAPH-2F932 -// 2f933 CJK COMPATIBILITY IDEOGRAPH-2F933 -// 2f934 CJK COMPATIBILITY IDEOGRAPH-2F934 -// 2f935 CJK COMPATIBILITY IDEOGRAPH-2F935 -// 2f936 CJK COMPATIBILITY IDEOGRAPH-2F936 -// 2f937 CJK COMPATIBILITY IDEOGRAPH-2F937 -// 2f938 CJK COMPATIBILITY IDEOGRAPH-2F938 -// 2f939 CJK COMPATIBILITY IDEOGRAPH-2F939 -// 2f93a CJK COMPATIBILITY IDEOGRAPH-2F93A -// 2f93b CJK COMPATIBILITY IDEOGRAPH-2F93B -// 2f93c CJK COMPATIBILITY IDEOGRAPH-2F93C -// 2f93d CJK COMPATIBILITY IDEOGRAPH-2F93D -// 2f93e CJK COMPATIBILITY IDEOGRAPH-2F93E -// 2f93f CJK COMPATIBILITY IDEOGRAPH-2F93F -// 2f940 CJK COMPATIBILITY IDEOGRAPH-2F940 -// 2f941 CJK COMPATIBILITY IDEOGRAPH-2F941 -// 2f942 CJK COMPATIBILITY IDEOGRAPH-2F942 -// 2f943 CJK COMPATIBILITY IDEOGRAPH-2F943 -// 2f944 CJK COMPATIBILITY IDEOGRAPH-2F944 -// 2f945 CJK COMPATIBILITY IDEOGRAPH-2F945 -// 2f946 CJK COMPATIBILITY IDEOGRAPH-2F946 -// 2f947 CJK COMPATIBILITY IDEOGRAPH-2F947 -// 2f948 CJK COMPATIBILITY IDEOGRAPH-2F948 -// 2f949 CJK COMPATIBILITY IDEOGRAPH-2F949 -// 2f94a CJK COMPATIBILITY IDEOGRAPH-2F94A -// 2f94b CJK COMPATIBILITY IDEOGRAPH-2F94B -// 2f94c CJK COMPATIBILITY IDEOGRAPH-2F94C -// 2f94d CJK COMPATIBILITY IDEOGRAPH-2F94D -// 2f94e CJK COMPATIBILITY IDEOGRAPH-2F94E -// 2f94f CJK COMPATIBILITY IDEOGRAPH-2F94F -// 2f950 CJK COMPATIBILITY IDEOGRAPH-2F950 -// 2f951 CJK COMPATIBILITY IDEOGRAPH-2F951 -// 2f952 CJK COMPATIBILITY IDEOGRAPH-2F952 -// 2f953 CJK COMPATIBILITY IDEOGRAPH-2F953 -// 2f954 CJK COMPATIBILITY IDEOGRAPH-2F954 -// 2f955 CJK COMPATIBILITY IDEOGRAPH-2F955 -// 2f956 CJK COMPATIBILITY IDEOGRAPH-2F956 -// 2f957 CJK COMPATIBILITY IDEOGRAPH-2F957 -// 2f958 CJK COMPATIBILITY IDEOGRAPH-2F958 -// 2f959 CJK COMPATIBILITY IDEOGRAPH-2F959 -// 2f95a CJK COMPATIBILITY IDEOGRAPH-2F95A -// 2f95b CJK COMPATIBILITY IDEOGRAPH-2F95B -// 2f95c CJK COMPATIBILITY IDEOGRAPH-2F95C -// 2f95d CJK COMPATIBILITY IDEOGRAPH-2F95D -// 2f95e CJK COMPATIBILITY IDEOGRAPH-2F95E -// 2f95f CJK COMPATIBILITY IDEOGRAPH-2F95F -// 2f960 CJK COMPATIBILITY IDEOGRAPH-2F960 -// 2f961 CJK COMPATIBILITY IDEOGRAPH-2F961 -// 2f962 CJK COMPATIBILITY IDEOGRAPH-2F962 -// 2f963 CJK COMPATIBILITY IDEOGRAPH-2F963 -// 2f964 CJK COMPATIBILITY IDEOGRAPH-2F964 -// 2f965 CJK COMPATIBILITY IDEOGRAPH-2F965 -// 2f966 CJK COMPATIBILITY IDEOGRAPH-2F966 -// 2f967 CJK COMPATIBILITY IDEOGRAPH-2F967 -// 2f968 CJK COMPATIBILITY IDEOGRAPH-2F968 -// 2f969 CJK COMPATIBILITY IDEOGRAPH-2F969 -// 2f96a CJK COMPATIBILITY IDEOGRAPH-2F96A -// 2f96b CJK COMPATIBILITY IDEOGRAPH-2F96B -// 2f96c CJK COMPATIBILITY IDEOGRAPH-2F96C -// 2f96d CJK COMPATIBILITY IDEOGRAPH-2F96D -// 2f96e CJK COMPATIBILITY IDEOGRAPH-2F96E -// 2f96f CJK COMPATIBILITY IDEOGRAPH-2F96F -// 2f970 CJK COMPATIBILITY IDEOGRAPH-2F970 -// 2f971 CJK COMPATIBILITY IDEOGRAPH-2F971 -// 2f972 CJK COMPATIBILITY IDEOGRAPH-2F972 -// 2f973 CJK COMPATIBILITY IDEOGRAPH-2F973 -// 2f974 CJK COMPATIBILITY IDEOGRAPH-2F974 -// 2f975 CJK COMPATIBILITY IDEOGRAPH-2F975 -// 2f976 CJK COMPATIBILITY IDEOGRAPH-2F976 -// 2f977 CJK COMPATIBILITY IDEOGRAPH-2F977 -// 2f978 CJK COMPATIBILITY IDEOGRAPH-2F978 -// 2f979 CJK COMPATIBILITY IDEOGRAPH-2F979 -// 2f97a CJK COMPATIBILITY IDEOGRAPH-2F97A -// 2f97b CJK COMPATIBILITY IDEOGRAPH-2F97B -// 2f97c CJK COMPATIBILITY IDEOGRAPH-2F97C -// 2f97d CJK COMPATIBILITY IDEOGRAPH-2F97D -// 2f97e CJK COMPATIBILITY IDEOGRAPH-2F97E -// 2f97f CJK COMPATIBILITY IDEOGRAPH-2F97F -// 2f980 CJK COMPATIBILITY IDEOGRAPH-2F980 -// 2f981 CJK COMPATIBILITY IDEOGRAPH-2F981 -// 2f982 CJK COMPATIBILITY IDEOGRAPH-2F982 -// 2f983 CJK COMPATIBILITY IDEOGRAPH-2F983 -// 2f984 CJK COMPATIBILITY IDEOGRAPH-2F984 -// 2f985 CJK COMPATIBILITY IDEOGRAPH-2F985 -// 2f986 CJK COMPATIBILITY IDEOGRAPH-2F986 -// 2f987 CJK COMPATIBILITY IDEOGRAPH-2F987 -// 2f988 CJK COMPATIBILITY IDEOGRAPH-2F988 -// 2f989 CJK COMPATIBILITY IDEOGRAPH-2F989 -// 2f98a CJK COMPATIBILITY IDEOGRAPH-2F98A -// 2f98b CJK COMPATIBILITY IDEOGRAPH-2F98B -// 2f98c CJK COMPATIBILITY IDEOGRAPH-2F98C -// 2f98d CJK COMPATIBILITY IDEOGRAPH-2F98D -// 2f98e CJK COMPATIBILITY IDEOGRAPH-2F98E -// 2f98f CJK COMPATIBILITY IDEOGRAPH-2F98F -// 2f990 CJK COMPATIBILITY IDEOGRAPH-2F990 -// 2f991 CJK COMPATIBILITY IDEOGRAPH-2F991 -// 2f992 CJK COMPATIBILITY IDEOGRAPH-2F992 -// 2f993 CJK COMPATIBILITY IDEOGRAPH-2F993 -// 2f994 CJK COMPATIBILITY IDEOGRAPH-2F994 -// 2f995 CJK COMPATIBILITY IDEOGRAPH-2F995 -// 2f996 CJK COMPATIBILITY IDEOGRAPH-2F996 -// 2f997 CJK COMPATIBILITY IDEOGRAPH-2F997 -// 2f998 CJK COMPATIBILITY IDEOGRAPH-2F998 -// 2f999 CJK COMPATIBILITY IDEOGRAPH-2F999 -// 2f99a CJK COMPATIBILITY IDEOGRAPH-2F99A -// 2f99b CJK COMPATIBILITY IDEOGRAPH-2F99B -// 2f99c CJK COMPATIBILITY IDEOGRAPH-2F99C -// 2f99d CJK COMPATIBILITY IDEOGRAPH-2F99D -// 2f99e CJK COMPATIBILITY IDEOGRAPH-2F99E -// 2f99f CJK COMPATIBILITY IDEOGRAPH-2F99F -// 2f9a0 CJK COMPATIBILITY IDEOGRAPH-2F9A0 -// 2f9a1 CJK COMPATIBILITY IDEOGRAPH-2F9A1 -// 2f9a2 CJK COMPATIBILITY IDEOGRAPH-2F9A2 -// 2f9a3 CJK COMPATIBILITY IDEOGRAPH-2F9A3 -// 2f9a4 CJK COMPATIBILITY IDEOGRAPH-2F9A4 -// 2f9a5 CJK COMPATIBILITY IDEOGRAPH-2F9A5 -// 2f9a6 CJK COMPATIBILITY IDEOGRAPH-2F9A6 -// 2f9a7 CJK COMPATIBILITY IDEOGRAPH-2F9A7 -// 2f9a8 CJK COMPATIBILITY IDEOGRAPH-2F9A8 -// 2f9a9 CJK COMPATIBILITY IDEOGRAPH-2F9A9 -// 2f9aa CJK COMPATIBILITY IDEOGRAPH-2F9AA -// 2f9ab CJK COMPATIBILITY IDEOGRAPH-2F9AB -// 2f9ac CJK COMPATIBILITY IDEOGRAPH-2F9AC -// 2f9ad CJK COMPATIBILITY IDEOGRAPH-2F9AD -// 2f9ae CJK COMPATIBILITY IDEOGRAPH-2F9AE -// 2f9af CJK COMPATIBILITY IDEOGRAPH-2F9AF -// 2f9b0 CJK COMPATIBILITY IDEOGRAPH-2F9B0 -// 2f9b1 CJK COMPATIBILITY IDEOGRAPH-2F9B1 -// 2f9b2 CJK COMPATIBILITY IDEOGRAPH-2F9B2 -// 2f9b3 CJK COMPATIBILITY IDEOGRAPH-2F9B3 -// 2f9b4 CJK COMPATIBILITY IDEOGRAPH-2F9B4 -// 2f9b5 CJK COMPATIBILITY IDEOGRAPH-2F9B5 -// 2f9b6 CJK COMPATIBILITY IDEOGRAPH-2F9B6 -// 2f9b7 CJK COMPATIBILITY IDEOGRAPH-2F9B7 -// 2f9b8 CJK COMPATIBILITY IDEOGRAPH-2F9B8 -// 2f9b9 CJK COMPATIBILITY IDEOGRAPH-2F9B9 -// 2f9ba CJK COMPATIBILITY IDEOGRAPH-2F9BA -// 2f9bb CJK COMPATIBILITY IDEOGRAPH-2F9BB -// 2f9bc CJK COMPATIBILITY IDEOGRAPH-2F9BC -// 2f9bd CJK COMPATIBILITY IDEOGRAPH-2F9BD -// 2f9be CJK COMPATIBILITY IDEOGRAPH-2F9BE -// 2f9bf CJK COMPATIBILITY IDEOGRAPH-2F9BF -// 2f9c0 CJK COMPATIBILITY IDEOGRAPH-2F9C0 -// 2f9c1 CJK COMPATIBILITY IDEOGRAPH-2F9C1 -// 2f9c2 CJK COMPATIBILITY IDEOGRAPH-2F9C2 -// 2f9c3 CJK COMPATIBILITY IDEOGRAPH-2F9C3 -// 2f9c4 CJK COMPATIBILITY IDEOGRAPH-2F9C4 -// 2f9c5 CJK COMPATIBILITY IDEOGRAPH-2F9C5 -// 2f9c6 CJK COMPATIBILITY IDEOGRAPH-2F9C6 -// 2f9c7 CJK COMPATIBILITY IDEOGRAPH-2F9C7 -// 2f9c8 CJK COMPATIBILITY IDEOGRAPH-2F9C8 -// 2f9c9 CJK COMPATIBILITY IDEOGRAPH-2F9C9 -// 2f9ca CJK COMPATIBILITY IDEOGRAPH-2F9CA -// 2f9cb CJK COMPATIBILITY IDEOGRAPH-2F9CB -// 2f9cc CJK COMPATIBILITY IDEOGRAPH-2F9CC -// 2f9cd CJK COMPATIBILITY IDEOGRAPH-2F9CD -// 2f9ce CJK COMPATIBILITY IDEOGRAPH-2F9CE -// 2f9cf CJK COMPATIBILITY IDEOGRAPH-2F9CF -// 2f9d0 CJK COMPATIBILITY IDEOGRAPH-2F9D0 -// 2f9d1 CJK COMPATIBILITY IDEOGRAPH-2F9D1 -// 2f9d2 CJK COMPATIBILITY IDEOGRAPH-2F9D2 -// 2f9d3 CJK COMPATIBILITY IDEOGRAPH-2F9D3 -// 2f9d4 CJK COMPATIBILITY IDEOGRAPH-2F9D4 -// 2f9d5 CJK COMPATIBILITY IDEOGRAPH-2F9D5 -// 2f9d6 CJK COMPATIBILITY IDEOGRAPH-2F9D6 -// 2f9d7 CJK COMPATIBILITY IDEOGRAPH-2F9D7 -// 2f9d8 CJK COMPATIBILITY IDEOGRAPH-2F9D8 -// 2f9d9 CJK COMPATIBILITY IDEOGRAPH-2F9D9 -// 2f9da CJK COMPATIBILITY IDEOGRAPH-2F9DA -// 2f9db CJK COMPATIBILITY IDEOGRAPH-2F9DB -// 2f9dc CJK COMPATIBILITY IDEOGRAPH-2F9DC -// 2f9dd CJK COMPATIBILITY IDEOGRAPH-2F9DD -// 2f9de CJK COMPATIBILITY IDEOGRAPH-2F9DE -// 2f9df CJK COMPATIBILITY IDEOGRAPH-2F9DF -// 2f9e0 CJK COMPATIBILITY IDEOGRAPH-2F9E0 -// 2f9e1 CJK COMPATIBILITY IDEOGRAPH-2F9E1 -// 2f9e2 CJK COMPATIBILITY IDEOGRAPH-2F9E2 -// 2f9e3 CJK COMPATIBILITY IDEOGRAPH-2F9E3 -// 2f9e4 CJK COMPATIBILITY IDEOGRAPH-2F9E4 -// 2f9e5 CJK COMPATIBILITY IDEOGRAPH-2F9E5 -// 2f9e6 CJK COMPATIBILITY IDEOGRAPH-2F9E6 -// 2f9e7 CJK COMPATIBILITY IDEOGRAPH-2F9E7 -// 2f9e8 CJK COMPATIBILITY IDEOGRAPH-2F9E8 -// 2f9e9 CJK COMPATIBILITY IDEOGRAPH-2F9E9 -// 2f9ea CJK COMPATIBILITY IDEOGRAPH-2F9EA -// 2f9eb CJK COMPATIBILITY IDEOGRAPH-2F9EB -// 2f9ec CJK COMPATIBILITY IDEOGRAPH-2F9EC -// 2f9ed CJK COMPATIBILITY IDEOGRAPH-2F9ED -// 2f9ee CJK COMPATIBILITY IDEOGRAPH-2F9EE -// 2f9ef CJK COMPATIBILITY IDEOGRAPH-2F9EF -// 2f9f0 CJK COMPATIBILITY IDEOGRAPH-2F9F0 -// 2f9f1 CJK COMPATIBILITY IDEOGRAPH-2F9F1 -// 2f9f2 CJK COMPATIBILITY IDEOGRAPH-2F9F2 -// 2f9f3 CJK COMPATIBILITY IDEOGRAPH-2F9F3 -// 2f9f4 CJK COMPATIBILITY IDEOGRAPH-2F9F4 -// 2f9f5 CJK COMPATIBILITY IDEOGRAPH-2F9F5 -// 2f9f6 CJK COMPATIBILITY IDEOGRAPH-2F9F6 -// 2f9f7 CJK COMPATIBILITY IDEOGRAPH-2F9F7 -// 2f9f8 CJK COMPATIBILITY IDEOGRAPH-2F9F8 -// 2f9f9 CJK COMPATIBILITY IDEOGRAPH-2F9F9 -// 2f9fa CJK COMPATIBILITY IDEOGRAPH-2F9FA -// 2f9fb CJK COMPATIBILITY IDEOGRAPH-2F9FB -// 2f9fc CJK COMPATIBILITY IDEOGRAPH-2F9FC -// 2f9fd CJK COMPATIBILITY IDEOGRAPH-2F9FD -// 2f9fe CJK COMPATIBILITY IDEOGRAPH-2F9FE -// 2f9ff CJK COMPATIBILITY IDEOGRAPH-2F9FF -// 2fa00 CJK COMPATIBILITY IDEOGRAPH-2FA00 -// 2fa01 CJK COMPATIBILITY IDEOGRAPH-2FA01 -// 2fa02 CJK COMPATIBILITY IDEOGRAPH-2FA02 -// 2fa03 CJK COMPATIBILITY IDEOGRAPH-2FA03 -// 2fa04 CJK COMPATIBILITY IDEOGRAPH-2FA04 -// 2fa05 CJK COMPATIBILITY IDEOGRAPH-2FA05 -// 2fa06 CJK COMPATIBILITY IDEOGRAPH-2FA06 -// 2fa07 CJK COMPATIBILITY IDEOGRAPH-2FA07 -// 2fa08 CJK COMPATIBILITY IDEOGRAPH-2FA08 -// 2fa09 CJK COMPATIBILITY IDEOGRAPH-2FA09 -// 2fa0a CJK COMPATIBILITY IDEOGRAPH-2FA0A -// 2fa0b CJK COMPATIBILITY IDEOGRAPH-2FA0B -// 2fa0c CJK COMPATIBILITY IDEOGRAPH-2FA0C -// 2fa0d CJK COMPATIBILITY IDEOGRAPH-2FA0D -// 2fa0e CJK COMPATIBILITY IDEOGRAPH-2FA0E -// 2fa0f CJK COMPATIBILITY IDEOGRAPH-2FA0F -// 2fa10 CJK COMPATIBILITY IDEOGRAPH-2FA10 -// 2fa11 CJK COMPATIBILITY IDEOGRAPH-2FA11 -// 2fa12 CJK COMPATIBILITY IDEOGRAPH-2FA12 -// 2fa13 CJK COMPATIBILITY IDEOGRAPH-2FA13 -// 2fa14 CJK COMPATIBILITY IDEOGRAPH-2FA14 -// 2fa15 CJK COMPATIBILITY IDEOGRAPH-2FA15 -// 2fa16 CJK COMPATIBILITY IDEOGRAPH-2FA16 -// 2fa17 CJK COMPATIBILITY IDEOGRAPH-2FA17 -// 2fa18 CJK COMPATIBILITY IDEOGRAPH-2FA18 -// 2fa19 CJK COMPATIBILITY IDEOGRAPH-2FA19 -// 2fa1a CJK COMPATIBILITY IDEOGRAPH-2FA1A -// 2fa1b CJK COMPATIBILITY IDEOGRAPH-2FA1B -// 2fa1c CJK COMPATIBILITY IDEOGRAPH-2FA1C -// 2fa1d CJK COMPATIBILITY IDEOGRAPH-2FA1D - { 0x2F800, 0x21E, 0x9, 0, 0 }, -// e0001 LANGUAGE TAG - { 0xE0001, 0x1, 0x0, 0, 0 }, -// e0020 TAG SPACE -// e0021 TAG EXCLAMATION MARK -// e0022 TAG QUOTATION MARK -// e0023 TAG NUMBER SIGN -// e0024 TAG DOLLAR SIGN -// e0025 TAG PERCENT SIGN -// e0026 TAG AMPERSAND -// e0027 TAG APOSTROPHE -// e0028 TAG LEFT PARENTHESIS -// e0029 TAG RIGHT PARENTHESIS -// e002a TAG ASTERISK -// e002b TAG PLUS SIGN -// e002c TAG COMMA -// e002d TAG HYPHEN-MINUS -// e002e TAG FULL STOP -// e002f TAG SOLIDUS -// e0030 TAG DIGIT ZERO -// e0031 TAG DIGIT ONE -// e0032 TAG DIGIT TWO -// e0033 TAG DIGIT THREE -// e0034 TAG DIGIT FOUR -// e0035 TAG DIGIT FIVE -// e0036 TAG DIGIT SIX -// e0037 TAG DIGIT SEVEN -// e0038 TAG DIGIT EIGHT -// e0039 TAG DIGIT NINE -// e003a TAG COLON -// e003b TAG SEMICOLON -// e003c TAG LESS-THAN SIGN -// e003d TAG EQUALS SIGN -// e003e TAG GREATER-THAN SIGN -// e003f TAG QUESTION MARK -// e0040 TAG COMMERCIAL AT -// e0041 TAG LATIN CAPITAL LETTER A -// e0042 TAG LATIN CAPITAL LETTER B -// e0043 TAG LATIN CAPITAL LETTER C -// e0044 TAG LATIN CAPITAL LETTER D -// e0045 TAG LATIN CAPITAL LETTER E -// e0046 TAG LATIN CAPITAL LETTER F -// e0047 TAG LATIN CAPITAL LETTER G -// e0048 TAG LATIN CAPITAL LETTER H -// e0049 TAG LATIN CAPITAL LETTER I -// e004a TAG LATIN CAPITAL LETTER J -// e004b TAG LATIN CAPITAL LETTER K -// e004c TAG LATIN CAPITAL LETTER L -// e004d TAG LATIN CAPITAL LETTER M -// e004e TAG LATIN CAPITAL LETTER N -// e004f TAG LATIN CAPITAL LETTER O -// e0050 TAG LATIN CAPITAL LETTER P -// e0051 TAG LATIN CAPITAL LETTER Q -// e0052 TAG LATIN CAPITAL LETTER R -// e0053 TAG LATIN CAPITAL LETTER S -// e0054 TAG LATIN CAPITAL LETTER T -// e0055 TAG LATIN CAPITAL LETTER U -// e0056 TAG LATIN CAPITAL LETTER V -// e0057 TAG LATIN CAPITAL LETTER W -// e0058 TAG LATIN CAPITAL LETTER X -// e0059 TAG LATIN CAPITAL LETTER Y -// e005a TAG LATIN CAPITAL LETTER Z -// e005b TAG LEFT SQUARE BRACKET -// e005c TAG REVERSE SOLIDUS -// e005d TAG RIGHT SQUARE BRACKET -// e005e TAG CIRCUMFLEX ACCENT -// e005f TAG LOW LINE -// e0060 TAG GRAVE ACCENT -// e0061 TAG LATIN SMALL LETTER A -// e0062 TAG LATIN SMALL LETTER B -// e0063 TAG LATIN SMALL LETTER C -// e0064 TAG LATIN SMALL LETTER D -// e0065 TAG LATIN SMALL LETTER E -// e0066 TAG LATIN SMALL LETTER F -// e0067 TAG LATIN SMALL LETTER G -// e0068 TAG LATIN SMALL LETTER H -// e0069 TAG LATIN SMALL LETTER I -// e006a TAG LATIN SMALL LETTER J -// e006b TAG LATIN SMALL LETTER K -// e006c TAG LATIN SMALL LETTER L -// e006d TAG LATIN SMALL LETTER M -// e006e TAG LATIN SMALL LETTER N -// e006f TAG LATIN SMALL LETTER O -// e0070 TAG LATIN SMALL LETTER P -// e0071 TAG LATIN SMALL LETTER Q -// e0072 TAG LATIN SMALL LETTER R -// e0073 TAG LATIN SMALL LETTER S -// e0074 TAG LATIN SMALL LETTER T -// e0075 TAG LATIN SMALL LETTER U -// e0076 TAG LATIN SMALL LETTER V -// e0077 TAG LATIN SMALL LETTER W -// e0078 TAG LATIN SMALL LETTER X -// e0079 TAG LATIN SMALL LETTER Y -// e007a TAG LATIN SMALL LETTER Z -// e007b TAG LEFT CURLY BRACKET -// e007c TAG VERTICAL LINE -// e007d TAG RIGHT CURLY BRACKET -// e007e TAG TILDE -// e007f CANCEL TAG - { 0xE0020, 0x60, 0x0, 0, 0 }, -// e0100 VARIATION SELECTOR-17 -// e0101 VARIATION SELECTOR-18 -// e0102 VARIATION SELECTOR-19 -// e0103 VARIATION SELECTOR-20 -// e0104 VARIATION SELECTOR-21 -// e0105 VARIATION SELECTOR-22 -// e0106 VARIATION SELECTOR-23 -// e0107 VARIATION SELECTOR-24 -// e0108 VARIATION SELECTOR-25 -// e0109 VARIATION SELECTOR-26 -// e010a VARIATION SELECTOR-27 -// e010b VARIATION SELECTOR-28 -// e010c VARIATION SELECTOR-29 -// e010d VARIATION SELECTOR-30 -// e010e VARIATION SELECTOR-31 -// e010f VARIATION SELECTOR-32 -// e0110 VARIATION SELECTOR-33 -// e0111 VARIATION SELECTOR-34 -// e0112 VARIATION SELECTOR-35 -// e0113 VARIATION SELECTOR-36 -// e0114 VARIATION SELECTOR-37 -// e0115 VARIATION SELECTOR-38 -// e0116 VARIATION SELECTOR-39 -// e0117 VARIATION SELECTOR-40 -// e0118 VARIATION SELECTOR-41 -// e0119 VARIATION SELECTOR-42 -// e011a VARIATION SELECTOR-43 -// e011b VARIATION SELECTOR-44 -// e011c VARIATION SELECTOR-45 -// e011d VARIATION SELECTOR-46 -// e011e VARIATION SELECTOR-47 -// e011f VARIATION SELECTOR-48 -// e0120 VARIATION SELECTOR-49 -// e0121 VARIATION SELECTOR-50 -// e0122 VARIATION SELECTOR-51 -// e0123 VARIATION SELECTOR-52 -// e0124 VARIATION SELECTOR-53 -// e0125 VARIATION SELECTOR-54 -// e0126 VARIATION SELECTOR-55 -// e0127 VARIATION SELECTOR-56 -// e0128 VARIATION SELECTOR-57 -// e0129 VARIATION SELECTOR-58 -// e012a VARIATION SELECTOR-59 -// e012b VARIATION SELECTOR-60 -// e012c VARIATION SELECTOR-61 -// e012d VARIATION SELECTOR-62 -// e012e VARIATION SELECTOR-63 -// e012f VARIATION SELECTOR-64 -// e0130 VARIATION SELECTOR-65 -// e0131 VARIATION SELECTOR-66 -// e0132 VARIATION SELECTOR-67 -// e0133 VARIATION SELECTOR-68 -// e0134 VARIATION SELECTOR-69 -// e0135 VARIATION SELECTOR-70 -// e0136 VARIATION SELECTOR-71 -// e0137 VARIATION SELECTOR-72 -// e0138 VARIATION SELECTOR-73 -// e0139 VARIATION SELECTOR-74 -// e013a VARIATION SELECTOR-75 -// e013b VARIATION SELECTOR-76 -// e013c VARIATION SELECTOR-77 -// e013d VARIATION SELECTOR-78 -// e013e VARIATION SELECTOR-79 -// e013f VARIATION SELECTOR-80 -// e0140 VARIATION SELECTOR-81 -// e0141 VARIATION SELECTOR-82 -// e0142 VARIATION SELECTOR-83 -// e0143 VARIATION SELECTOR-84 -// e0144 VARIATION SELECTOR-85 -// e0145 VARIATION SELECTOR-86 -// e0146 VARIATION SELECTOR-87 -// e0147 VARIATION SELECTOR-88 -// e0148 VARIATION SELECTOR-89 -// e0149 VARIATION SELECTOR-90 -// e014a VARIATION SELECTOR-91 -// e014b VARIATION SELECTOR-92 -// e014c VARIATION SELECTOR-93 -// e014d VARIATION SELECTOR-94 -// e014e VARIATION SELECTOR-95 -// e014f VARIATION SELECTOR-96 -// e0150 VARIATION SELECTOR-97 -// e0151 VARIATION SELECTOR-98 -// e0152 VARIATION SELECTOR-99 -// e0153 VARIATION SELECTOR-100 -// e0154 VARIATION SELECTOR-101 -// e0155 VARIATION SELECTOR-102 -// e0156 VARIATION SELECTOR-103 -// e0157 VARIATION SELECTOR-104 -// e0158 VARIATION SELECTOR-105 -// e0159 VARIATION SELECTOR-106 -// e015a VARIATION SELECTOR-107 -// e015b VARIATION SELECTOR-108 -// e015c VARIATION SELECTOR-109 -// e015d VARIATION SELECTOR-110 -// e015e VARIATION SELECTOR-111 -// e015f VARIATION SELECTOR-112 -// e0160 VARIATION SELECTOR-113 -// e0161 VARIATION SELECTOR-114 -// e0162 VARIATION SELECTOR-115 -// e0163 VARIATION SELECTOR-116 -// e0164 VARIATION SELECTOR-117 -// e0165 VARIATION SELECTOR-118 -// e0166 VARIATION SELECTOR-119 -// e0167 VARIATION SELECTOR-120 -// e0168 VARIATION SELECTOR-121 -// e0169 VARIATION SELECTOR-122 -// e016a VARIATION SELECTOR-123 -// e016b VARIATION SELECTOR-124 -// e016c VARIATION SELECTOR-125 -// e016d VARIATION SELECTOR-126 -// e016e VARIATION SELECTOR-127 -// e016f VARIATION SELECTOR-128 -// e0170 VARIATION SELECTOR-129 -// e0171 VARIATION SELECTOR-130 -// e0172 VARIATION SELECTOR-131 -// e0173 VARIATION SELECTOR-132 -// e0174 VARIATION SELECTOR-133 -// e0175 VARIATION SELECTOR-134 -// e0176 VARIATION SELECTOR-135 -// e0177 VARIATION SELECTOR-136 -// e0178 VARIATION SELECTOR-137 -// e0179 VARIATION SELECTOR-138 -// e017a VARIATION SELECTOR-139 -// e017b VARIATION SELECTOR-140 -// e017c VARIATION SELECTOR-141 -// e017d VARIATION SELECTOR-142 -// e017e VARIATION SELECTOR-143 -// e017f VARIATION SELECTOR-144 -// e0180 VARIATION SELECTOR-145 -// e0181 VARIATION SELECTOR-146 -// e0182 VARIATION SELECTOR-147 -// e0183 VARIATION SELECTOR-148 -// e0184 VARIATION SELECTOR-149 -// e0185 VARIATION SELECTOR-150 -// e0186 VARIATION SELECTOR-151 -// e0187 VARIATION SELECTOR-152 -// e0188 VARIATION SELECTOR-153 -// e0189 VARIATION SELECTOR-154 -// e018a VARIATION SELECTOR-155 -// e018b VARIATION SELECTOR-156 -// e018c VARIATION SELECTOR-157 -// e018d VARIATION SELECTOR-158 -// e018e VARIATION SELECTOR-159 -// e018f VARIATION SELECTOR-160 -// e0190 VARIATION SELECTOR-161 -// e0191 VARIATION SELECTOR-162 -// e0192 VARIATION SELECTOR-163 -// e0193 VARIATION SELECTOR-164 -// e0194 VARIATION SELECTOR-165 -// e0195 VARIATION SELECTOR-166 -// e0196 VARIATION SELECTOR-167 -// e0197 VARIATION SELECTOR-168 -// e0198 VARIATION SELECTOR-169 -// e0199 VARIATION SELECTOR-170 -// e019a VARIATION SELECTOR-171 -// e019b VARIATION SELECTOR-172 -// e019c VARIATION SELECTOR-173 -// e019d VARIATION SELECTOR-174 -// e019e VARIATION SELECTOR-175 -// e019f VARIATION SELECTOR-176 -// e01a0 VARIATION SELECTOR-177 -// e01a1 VARIATION SELECTOR-178 -// e01a2 VARIATION SELECTOR-179 -// e01a3 VARIATION SELECTOR-180 -// e01a4 VARIATION SELECTOR-181 -// e01a5 VARIATION SELECTOR-182 -// e01a6 VARIATION SELECTOR-183 -// e01a7 VARIATION SELECTOR-184 -// e01a8 VARIATION SELECTOR-185 -// e01a9 VARIATION SELECTOR-186 -// e01aa VARIATION SELECTOR-187 -// e01ab VARIATION SELECTOR-188 -// e01ac VARIATION SELECTOR-189 -// e01ad VARIATION SELECTOR-190 -// e01ae VARIATION SELECTOR-191 -// e01af VARIATION SELECTOR-192 -// e01b0 VARIATION SELECTOR-193 -// e01b1 VARIATION SELECTOR-194 -// e01b2 VARIATION SELECTOR-195 -// e01b3 VARIATION SELECTOR-196 -// e01b4 VARIATION SELECTOR-197 -// e01b5 VARIATION SELECTOR-198 -// e01b6 VARIATION SELECTOR-199 -// e01b7 VARIATION SELECTOR-200 -// e01b8 VARIATION SELECTOR-201 -// e01b9 VARIATION SELECTOR-202 -// e01ba VARIATION SELECTOR-203 -// e01bb VARIATION SELECTOR-204 -// e01bc VARIATION SELECTOR-205 -// e01bd VARIATION SELECTOR-206 -// e01be VARIATION SELECTOR-207 -// e01bf VARIATION SELECTOR-208 -// e01c0 VARIATION SELECTOR-209 -// e01c1 VARIATION SELECTOR-210 -// e01c2 VARIATION SELECTOR-211 -// e01c3 VARIATION SELECTOR-212 -// e01c4 VARIATION SELECTOR-213 -// e01c5 VARIATION SELECTOR-214 -// e01c6 VARIATION SELECTOR-215 -// e01c7 VARIATION SELECTOR-216 -// e01c8 VARIATION SELECTOR-217 -// e01c9 VARIATION SELECTOR-218 -// e01ca VARIATION SELECTOR-219 -// e01cb VARIATION SELECTOR-220 -// e01cc VARIATION SELECTOR-221 -// e01cd VARIATION SELECTOR-222 -// e01ce VARIATION SELECTOR-223 -// e01cf VARIATION SELECTOR-224 -// e01d0 VARIATION SELECTOR-225 -// e01d1 VARIATION SELECTOR-226 -// e01d2 VARIATION SELECTOR-227 -// e01d3 VARIATION SELECTOR-228 -// e01d4 VARIATION SELECTOR-229 -// e01d5 VARIATION SELECTOR-230 -// e01d6 VARIATION SELECTOR-231 -// e01d7 VARIATION SELECTOR-232 -// e01d8 VARIATION SELECTOR-233 -// e01d9 VARIATION SELECTOR-234 -// e01da VARIATION SELECTOR-235 -// e01db VARIATION SELECTOR-236 -// e01dc VARIATION SELECTOR-237 -// e01dd VARIATION SELECTOR-238 -// e01de VARIATION SELECTOR-239 -// e01df VARIATION SELECTOR-240 -// e01e0 VARIATION SELECTOR-241 -// e01e1 VARIATION SELECTOR-242 -// e01e2 VARIATION SELECTOR-243 -// e01e3 VARIATION SELECTOR-244 -// e01e4 VARIATION SELECTOR-245 -// e01e5 VARIATION SELECTOR-246 -// e01e6 VARIATION SELECTOR-247 -// e01e7 VARIATION SELECTOR-248 -// e01e8 VARIATION SELECTOR-249 -// e01e9 VARIATION SELECTOR-250 -// e01ea VARIATION SELECTOR-251 -// e01eb VARIATION SELECTOR-252 -// e01ec VARIATION SELECTOR-253 -// e01ed VARIATION SELECTOR-254 -// e01ee VARIATION SELECTOR-255 -// e01ef VARIATION SELECTOR-256 - { 0xE0100, 0xF0, 0x0, 0, 0 }, -// f0000 - { 0xF0000, 0x1, 0x0, 0, 0 }, -// ffffd - { 0xFFFFD, 0x1, 0x0, 0, 0 }, -// 100000 - { 0x100000, 0x1, 0x0, 0, 0 }, -// 10fffd - { 0x10FFFD, 0x1, 0x0, 0, 0 }, -}; - - -const size_t _PDCLIB_wcinfo_size = sizeof(_PDCLIB_wcinfo) / sizeof(_PDCLIB_wcinfo[0]); -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -int main( void ) -{ - return TEST_RESULTS; -} -#endif - diff --git a/waterbox/libc/functions/locale/fakelocale.c b/waterbox/libc/functions/locale/fakelocale.c deleted file mode 100644 index 2e6e68244c..0000000000 --- a/waterbox/libc/functions/locale/fakelocale.c +++ /dev/null @@ -1,3 +0,0 @@ -#include <_PDCLIB_locale.h> - -locale_t _PDCLIB_locale_fake; diff --git a/waterbox/libc/functions/locale/freelocale.c b/waterbox/libc/functions/locale/freelocale.c deleted file mode 100644 index 6ab34e9f0b..0000000000 --- a/waterbox/libc/functions/locale/freelocale.c +++ /dev/null @@ -1,29 +0,0 @@ -/* freelocale( locale_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" -#include - -void freelocale( locale_t newloc ) -{ - if( newloc != NULL ) { - assert( ! "Not implemented" ); - } -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( NO_TESTDRIVER ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/locale/localeconv.c b/waterbox/libc/functions/locale/localeconv.c deleted file mode 100644 index c6ffcf3a41..0000000000 --- a/waterbox/libc/functions/locale/localeconv.c +++ /dev/null @@ -1,26 +0,0 @@ -/* localeconv( void ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -struct lconv * localeconv( void ) -{ - return &_PDCLIB_threadlocale()->_Conv; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( NO_TESTDRIVER ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/locale/setlocale.c b/waterbox/libc/functions/locale/setlocale.c deleted file mode 100644 index 64cf6cd58e..0000000000 --- a/waterbox/libc/functions/locale/setlocale.c +++ /dev/null @@ -1,26 +0,0 @@ -/* setlocale( int, const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -char * setlocale( int category, const char * locale ) -{ - return NULL; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( NO_TESTDRIVER ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/locale/uselocale.c b/waterbox/libc/functions/locale/uselocale.c deleted file mode 100644 index 8fded5ed62..0000000000 --- a/waterbox/libc/functions/locale/uselocale.c +++ /dev/null @@ -1,36 +0,0 @@ -/* uselocale( locale_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -#ifdef _PDCLIB_LOCALE_METHOD -locale_t uselocale( locale_t newloc ) -{ - locale_t oldloc = _PDCLIB_threadlocale(); - - if(newloc == LC_GLOBAL_LOCALE) { - _PDCLIB_setthreadlocale(NULL); - } else if(newloc != NULL) { - _PDCLIB_setthreadlocale(newloc); - } - - return oldloc; -} -#endif - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( NO_TESTDRIVER ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/math/__cos.c b/waterbox/libc/functions/math/__cos.c deleted file mode 100644 index 46cefb3813..0000000000 --- a/waterbox/libc/functions/math/__cos.c +++ /dev/null @@ -1,71 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/k_cos.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* - * __cos( x, y ) - * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 - * Input x is assumed to be bounded by ~pi/4 in magnitude. - * Input y is the tail of x. - * - * Algorithm - * 1. Since cos(-x) = cos(x), we need only to consider positive x. - * 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0. - * 3. cos(x) is approximated by a polynomial of degree 14 on - * [0,pi/4] - * 4 14 - * cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x - * where the remez error is - * - * | 2 4 6 8 10 12 14 | -58 - * |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2 - * | | - * - * 4 6 8 10 12 14 - * 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then - * cos(x) ~ 1 - x*x/2 + r - * since cos(x+y) ~ cos(x) - sin(x)*y - * ~ cos(x) - x*y, - * a correction term is necessary in cos(x) and hence - * cos(x+y) = 1 - (x*x/2 - (r - x*y)) - * For better accuracy, rearrange to - * cos(x+y) ~ w + (tmp + (r-x*y)) - * where w = 1 - x*x/2 and tmp is a tiny correction term - * (1 - x*x/2 == w + tmp exactly in infinite precision). - * The exactness of w + tmp in infinite precision depends on w - * and tmp having the same precision as x. If they have extra - * precision due to compiler bugs, then the extra precision is - * only good provided it is retained in all terms of the final - * expression for cos(). Retention happens in all cases tested - * under FreeBSD, so don't pessimize things by forcibly clipping - * any extra precision in w. - */ - -#include "libm.h" - -static const double -C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */ -C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */ -C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */ -C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */ -C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */ -C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */ - -double __cos(double x, double y) -{ - double_t hz,z,r,w; - - z = x*x; - w = z*z; - r = z*(C1+z*(C2+z*C3)) + w*w*(C4+z*(C5+z*C6)); - hz = 0.5*z; - w = 1.0-hz; - return w + (((1.0-w)-hz) + (z*r-x*y)); -} diff --git a/waterbox/libc/functions/math/__cosdf.c b/waterbox/libc/functions/math/__cosdf.c deleted file mode 100644 index 2124989b32..0000000000 --- a/waterbox/libc/functions/math/__cosdf.c +++ /dev/null @@ -1,35 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/k_cosf.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - * Debugged and optimized by Bruce D. Evans. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" - -/* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */ -static const double -C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */ -C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */ -C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */ -C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */ - -float __cosdf(double x) -{ - double_t r, w, z; - - /* Try to optimize for parallel evaluation as in __tandf.c. */ - z = x*x; - w = z*z; - r = C2+z*C3; - return ((1.0+z*C0) + w*C1) + (w*z)*r; -} diff --git a/waterbox/libc/functions/math/__cosl.c b/waterbox/libc/functions/math/__cosl.c deleted file mode 100644 index fa522ddd7a..0000000000 --- a/waterbox/libc/functions/math/__cosl.c +++ /dev/null @@ -1,96 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/ld80/k_cosl.c */ -/* origin: FreeBSD /usr/src/lib/msun/ld128/k_cosl.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - - -#include "libm.h" - -#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -#if LDBL_MANT_DIG == 64 -/* - * ld80 version of __cos.c. See __cos.c for most comments. - */ -/* - * Domain [-0.7854, 0.7854], range ~[-2.43e-23, 2.425e-23]: - * |cos(x) - c(x)| < 2**-75.1 - * - * The coefficients of c(x) were generated by a pari-gp script using - * a Remez algorithm that searches for the best higher coefficients - * after rounding leading coefficients to a specified precision. - * - * Simpler methods like Chebyshev or basic Remez barely suffice for - * cos() in 64-bit precision, because we want the coefficient of x^2 - * to be precisely -0.5 so that multiplying by it is exact, and plain - * rounding of the coefficients of a good polynomial approximation only - * gives this up to about 64-bit precision. Plain rounding also gives - * a mediocre approximation for the coefficient of x^4, but a rounding - * error of 0.5 ulps for this coefficient would only contribute ~0.01 - * ulps to the final error, so this is unimportant. Rounding errors in - * higher coefficients are even less important. - * - * In fact, coefficients above the x^4 one only need to have 53-bit - * precision, and this is more efficient. We get this optimization - * almost for free from the complications needed to search for the best - * higher coefficients. - */ -static const long double -C1 = 0.0416666666666666666136L; /* 0xaaaaaaaaaaaaaa9b.0p-68 */ -static const double -C2 = -0.0013888888888888874, /* -0x16c16c16c16c10.0p-62 */ -C3 = 0.000024801587301571716, /* 0x1a01a01a018e22.0p-68 */ -C4 = -0.00000027557319215507120, /* -0x127e4fb7602f22.0p-74 */ -C5 = 0.0000000020876754400407278, /* 0x11eed8caaeccf1.0p-81 */ -C6 = -1.1470297442401303e-11, /* -0x19393412bd1529.0p-89 */ -C7 = 4.7383039476436467e-14; /* 0x1aac9d9af5c43e.0p-97 */ -#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*C7))))))) -#elif LDBL_MANT_DIG == 113 -/* - * ld128 version of __cos.c. See __cos.c for most comments. - */ -/* - * Domain [-0.7854, 0.7854], range ~[-1.80e-37, 1.79e-37]: - * |cos(x) - c(x))| < 2**-122.0 - * - * 113-bit precision requires more care than 64-bit precision, since - * simple methods give a minimax polynomial with coefficient for x^2 - * that is 1 ulp below 0.5, but we want it to be precisely 0.5. See - * above for more details. - */ -static const long double -C1 = 0.04166666666666666666666666666666658424671L, -C2 = -0.001388888888888888888888888888863490893732L, -C3 = 0.00002480158730158730158730158600795304914210L, -C4 = -0.2755731922398589065255474947078934284324e-6L, -C5 = 0.2087675698786809897659225313136400793948e-8L, -C6 = -0.1147074559772972315817149986812031204775e-10L, -C7 = 0.4779477332386808976875457937252120293400e-13L; -static const double -C8 = -0.1561920696721507929516718307820958119868e-15, -C9 = 0.4110317413744594971475941557607804508039e-18, -C10 = -0.8896592467191938803288521958313920156409e-21, -C11 = 0.1601061435794535138244346256065192782581e-23; -#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*(C7+ \ - z*(C8+z*(C9+z*(C10+z*C11))))))))))) -#endif - -long double __cosl(long double x, long double y) -{ - long double hz,z,r,w; - - z = x*x; - r = POLY(z); - hz = 0.5*z; - w = 1.0-hz; - return w + (((1.0-w)-hz) + (z*r-x*y)); -} -#endif diff --git a/waterbox/libc/functions/math/__expo2.c b/waterbox/libc/functions/math/__expo2.c deleted file mode 100644 index 740ac680e8..0000000000 --- a/waterbox/libc/functions/math/__expo2.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "libm.h" - -/* k is such that k*ln2 has minimal relative error and x - kln2 > log(DBL_MIN) */ -static const int k = 2043; -static const double kln2 = 0x1.62066151add8bp+10; - -/* exp(x)/2 for x >= log(DBL_MAX), slightly better than 0.5*exp(x/2)*exp(x/2) */ -double __expo2(double x) -{ - double scale; - - /* note that k is odd and scale*scale overflows */ - INSERT_WORDS(scale, (uint32_t)(0x3ff + k/2) << 20, 0); - /* exp(x - k ln2) * 2**(k-1) */ - return exp(x - kln2) * scale * scale; -} diff --git a/waterbox/libc/functions/math/__expo2f.c b/waterbox/libc/functions/math/__expo2f.c deleted file mode 100644 index 5163e41800..0000000000 --- a/waterbox/libc/functions/math/__expo2f.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "libm.h" - -/* k is such that k*ln2 has minimal relative error and x - kln2 > log(FLT_MIN) */ -static const int k = 235; -static const float kln2 = 0x1.45c778p+7f; - -/* expf(x)/2 for x >= log(FLT_MAX), slightly better than 0.5f*expf(x/2)*expf(x/2) */ -float __expo2f(float x) -{ - float scale; - - /* note that k is odd and scale*scale overflows */ - SET_FLOAT_WORD(scale, (uint32_t)(0x7f + k/2) << 23); - /* exp(x - k ln2) * 2**(k-1) */ - return expf(x - kln2) * scale * scale; -} diff --git a/waterbox/libc/functions/math/__fpclassify.c b/waterbox/libc/functions/math/__fpclassify.c deleted file mode 100644 index f7c0e2dfac..0000000000 --- a/waterbox/libc/functions/math/__fpclassify.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -int __fpclassify(double x) -{ - union {double f; uint64_t i;} u = {x}; - int e = u.i>>52 & 0x7ff; - if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO; - if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE; - return FP_NORMAL; -} diff --git a/waterbox/libc/functions/math/__fpclassifyf.c b/waterbox/libc/functions/math/__fpclassifyf.c deleted file mode 100644 index fd00eb1bcd..0000000000 --- a/waterbox/libc/functions/math/__fpclassifyf.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -int __fpclassifyf(float x) -{ - union {float f; uint32_t i;} u = {x}; - int e = u.i>>23 & 0xff; - if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO; - if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE; - return FP_NORMAL; -} diff --git a/waterbox/libc/functions/math/__fpclassifyl.c b/waterbox/libc/functions/math/__fpclassifyl.c deleted file mode 100644 index 481c0b9499..0000000000 --- a/waterbox/libc/functions/math/__fpclassifyl.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -int __fpclassifyl(long double x) -{ - return __fpclassify(x); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -int __fpclassifyl(long double x) -{ - union ldshape u = {x}; - int e = u.i.se & 0x7fff; - int msb = u.i.m>>63; - if (!e && !msb) - return u.i.m ? FP_SUBNORMAL : FP_ZERO; - if (!msb) - return FP_NAN; - if (e == 0x7fff) - return u.i.m << 1 ? FP_NAN : FP_INFINITE; - return FP_NORMAL; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -int __fpclassifyl(long double x) -{ - union ldshape u = {x}; - int e = u.i.se & 0x7fff; - u.i.se = 0; - if (!e) - return u.i2.lo | u.i2.hi ? FP_SUBNORMAL : FP_ZERO; - if (e == 0x7fff) - return u.i2.lo | u.i2.hi ? FP_NAN : FP_INFINITE; - return FP_NORMAL; -} -#endif diff --git a/waterbox/libc/functions/math/__invtrigl.c b/waterbox/libc/functions/math/__invtrigl.c deleted file mode 100644 index ef7f4e1b79..0000000000 --- a/waterbox/libc/functions/math/__invtrigl.c +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include "__invtrigl.h" - -#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -static const long double -pS0 = 1.66666666666666666631e-01L, -pS1 = -4.16313987993683104320e-01L, -pS2 = 3.69068046323246813704e-01L, -pS3 = -1.36213932016738603108e-01L, -pS4 = 1.78324189708471965733e-02L, -pS5 = -2.19216428382605211588e-04L, -pS6 = -7.10526623669075243183e-06L, -qS1 = -2.94788392796209867269e+00L, -qS2 = 3.27309890266528636716e+00L, -qS3 = -1.68285799854822427013e+00L, -qS4 = 3.90699412641738801874e-01L, -qS5 = -3.14365703596053263322e-02L; - -const long double pio2_hi = 1.57079632679489661926L; -const long double pio2_lo = -2.50827880633416601173e-20L; - -/* used in asinl() and acosl() */ -/* R(x^2) is a rational approximation of (asin(x)-x)/x^3 with Remez algorithm */ -long double __invtrigl_R(long double z) -{ - long double p, q; - p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*(pS5+z*pS6)))))); - q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*(qS4+z*qS5)))); - return p/q; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -static const long double -pS0 = 1.66666666666666666666666666666700314e-01L, -pS1 = -7.32816946414566252574527475428622708e-01L, -pS2 = 1.34215708714992334609030036562143589e+00L, -pS3 = -1.32483151677116409805070261790752040e+00L, -pS4 = 7.61206183613632558824485341162121989e-01L, -pS5 = -2.56165783329023486777386833928147375e-01L, -pS6 = 4.80718586374448793411019434585413855e-02L, -pS7 = -4.42523267167024279410230886239774718e-03L, -pS8 = 1.44551535183911458253205638280410064e-04L, -pS9 = -2.10558957916600254061591040482706179e-07L, -qS1 = -4.84690167848739751544716485245697428e+00L, -qS2 = 9.96619113536172610135016921140206980e+00L, -qS3 = -1.13177895428973036660836798461641458e+01L, -qS4 = 7.74004374389488266169304117714658761e+00L, -qS5 = -3.25871986053534084709023539900339905e+00L, -qS6 = 8.27830318881232209752469022352928864e-01L, -qS7 = -1.18768052702942805423330715206348004e-01L, -qS8 = 8.32600764660522313269101537926539470e-03L, -qS9 = -1.99407384882605586705979504567947007e-04L; - -const long double pio2_hi = 1.57079632679489661923132169163975140L; -const long double pio2_lo = 4.33590506506189051239852201302167613e-35L; - -long double __invtrigl_R(long double z) -{ - long double p, q; - p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*(pS5+z*(pS6+z*(pS7+z*(pS8+z*pS9))))))))); - q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*(qS4+z*(qS5+z*(pS6+z*(pS7+z*(pS8+z*pS9)))))))); - return p/q; -} -#endif diff --git a/waterbox/libc/functions/math/__invtrigl.h b/waterbox/libc/functions/math/__invtrigl.h deleted file mode 100644 index 91a8a3b61f..0000000000 --- a/waterbox/libc/functions/math/__invtrigl.h +++ /dev/null @@ -1,6 +0,0 @@ -/* shared by acosl, asinl and atan2l */ -#define pio2_hi __pio2_hi -#define pio2_lo __pio2_lo -extern const long double pio2_hi, pio2_lo; - -long double __invtrigl_R(long double z); diff --git a/waterbox/libc/functions/math/__polevll.c b/waterbox/libc/functions/math/__polevll.c deleted file mode 100644 index ce1a84046b..0000000000 --- a/waterbox/libc/functions/math/__polevll.c +++ /dev/null @@ -1,93 +0,0 @@ -/* origin: OpenBSD /usr/src/lib/libm/src/polevll.c */ -/* - * Copyright (c) 2008 Stephen L. Moshier - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/* - * Evaluate polynomial - * - * - * SYNOPSIS: - * - * int N; - * long double x, y, coef[N+1], polevl[]; - * - * y = polevll( x, coef, N ); - * - * - * DESCRIPTION: - * - * Evaluates polynomial of degree N: - * - * 2 N - * y = C + C x + C x +...+ C x - * 0 1 2 N - * - * Coefficients are stored in reverse order: - * - * coef[0] = C , ..., coef[N] = C . - * N 0 - * - * The function p1evll() assumes that coef[N] = 1.0 and is - * omitted from the array. Its calling arguments are - * otherwise the same as polevll(). - * - * - * SPEED: - * - * In the interest of speed, there are no checks for out - * of bounds arithmetic. This routine is used by most of - * the functions in the library. Depending on available - * equipment features, the user may wish to rewrite the - * program in microcode or assembly language. - * - */ - -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -#else -/* - * Polynomial evaluator: - * P[0] x^n + P[1] x^(n-1) + ... + P[n] - */ -long double __polevll(long double x, const long double *P, int n) -{ - long double y; - - y = *P++; - do { - y = y * x + *P++; - } while (--n); - - return y; -} - -/* - * Polynomial evaluator: - * x^n + P[0] x^(n-1) + P[1] x^(n-2) + ... + P[n] - */ -long double __p1evll(long double x, const long double *P, int n) -{ - long double y; - - n -= 1; - y = x + *P++; - do { - y = y * x + *P++; - } while (--n); - - return y; -} -#endif diff --git a/waterbox/libc/functions/math/__rem_pio2.c b/waterbox/libc/functions/math/__rem_pio2.c deleted file mode 100644 index d403f81c79..0000000000 --- a/waterbox/libc/functions/math/__rem_pio2.c +++ /dev/null @@ -1,177 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - * - * Optimized by Bruce D. Evans. - */ -/* __rem_pio2(x,y) - * - * return the remainder of x rem pi/2 in y[0]+y[1] - * use __rem_pio2_large() for large x - */ - -#include "libm.h" - -#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 -#define EPS DBL_EPSILON -#elif FLT_EVAL_METHOD==2 -#define EPS LDBL_EPSILON -#endif - -/* - * invpio2: 53 bits of 2/pi - * pio2_1: first 33 bit of pi/2 - * pio2_1t: pi/2 - pio2_1 - * pio2_2: second 33 bit of pi/2 - * pio2_2t: pi/2 - (pio2_1+pio2_2) - * pio2_3: third 33 bit of pi/2 - * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) - */ -static const double -toint = 1.5/EPS, -invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ -pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ -pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ -pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ -pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ -pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ -pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ - -/* caller must handle the case when reduction is not needed: |x| ~<= pi/4 */ -int __rem_pio2(double x, double *y) -{ - union {double f; uint64_t i;} u = {x}; - double_t z,w,t,r,fn; - double tx[3],ty[2]; - uint32_t ix; - int sign, n, ex, ey, i; - - sign = u.i>>63; - ix = u.i>>32 & 0x7fffffff; - if (ix <= 0x400f6a7a) { /* |x| ~<= 5pi/4 */ - if ((ix & 0xfffff) == 0x921fb) /* |x| ~= pi/2 or 2pi/2 */ - goto medium; /* cancellation -- use medium case */ - if (ix <= 0x4002d97c) { /* |x| ~<= 3pi/4 */ - if (!sign) { - z = x - pio2_1; /* one round good to 85 bits */ - y[0] = z - pio2_1t; - y[1] = (z-y[0]) - pio2_1t; - return 1; - } else { - z = x + pio2_1; - y[0] = z + pio2_1t; - y[1] = (z-y[0]) + pio2_1t; - return -1; - } - } else { - if (!sign) { - z = x - 2*pio2_1; - y[0] = z - 2*pio2_1t; - y[1] = (z-y[0]) - 2*pio2_1t; - return 2; - } else { - z = x + 2*pio2_1; - y[0] = z + 2*pio2_1t; - y[1] = (z-y[0]) + 2*pio2_1t; - return -2; - } - } - } - if (ix <= 0x401c463b) { /* |x| ~<= 9pi/4 */ - if (ix <= 0x4015fdbc) { /* |x| ~<= 7pi/4 */ - if (ix == 0x4012d97c) /* |x| ~= 3pi/2 */ - goto medium; - if (!sign) { - z = x - 3*pio2_1; - y[0] = z - 3*pio2_1t; - y[1] = (z-y[0]) - 3*pio2_1t; - return 3; - } else { - z = x + 3*pio2_1; - y[0] = z + 3*pio2_1t; - y[1] = (z-y[0]) + 3*pio2_1t; - return -3; - } - } else { - if (ix == 0x401921fb) /* |x| ~= 4pi/2 */ - goto medium; - if (!sign) { - z = x - 4*pio2_1; - y[0] = z - 4*pio2_1t; - y[1] = (z-y[0]) - 4*pio2_1t; - return 4; - } else { - z = x + 4*pio2_1; - y[0] = z + 4*pio2_1t; - y[1] = (z-y[0]) + 4*pio2_1t; - return -4; - } - } - } - if (ix < 0x413921fb) { /* |x| ~< 2^20*(pi/2), medium size */ -medium: - /* rint(x/(pi/2)), Assume round-to-nearest. */ - fn = (double_t)x*invpio2 + toint - toint; - n = (int32_t)fn; - r = x - fn*pio2_1; - w = fn*pio2_1t; /* 1st round, good to 85 bits */ - y[0] = r - w; - u.f = y[0]; - ey = u.i>>52 & 0x7ff; - ex = ix>>20; - if (ex - ey > 16) { /* 2nd round, good to 118 bits */ - t = r; - w = fn*pio2_2; - r = t - w; - w = fn*pio2_2t - ((t-r)-w); - y[0] = r - w; - u.f = y[0]; - ey = u.i>>52 & 0x7ff; - if (ex - ey > 49) { /* 3rd round, good to 151 bits, covers all cases */ - t = r; - w = fn*pio2_3; - r = t - w; - w = fn*pio2_3t - ((t-r)-w); - y[0] = r - w; - } - } - y[1] = (r - y[0]) - w; - return n; - } - /* - * all other (large) arguments - */ - if (ix >= 0x7ff00000) { /* x is inf or NaN */ - y[0] = y[1] = x - x; - return 0; - } - /* set z = scalbn(|x|,-ilogb(x)+23) */ - u.f = x; - u.i &= (uint64_t)-1>>12; - u.i |= (uint64_t)(0x3ff + 23)<<52; - z = u.f; - for (i=0; i < 2; i++) { - tx[i] = (double)(int32_t)z; - z = (z-tx[i])*0x1p24; - } - tx[i] = z; - /* skip zero terms, first term is non-zero */ - while (tx[i] == 0.0) - i--; - n = __rem_pio2_large(tx,ty,(int)(ix>>20)-(0x3ff+23),i+1,1); - if (sign) { - y[0] = -ty[0]; - y[1] = -ty[1]; - return -n; - } - y[0] = ty[0]; - y[1] = ty[1]; - return n; -} diff --git a/waterbox/libc/functions/math/__rem_pio2_large.c b/waterbox/libc/functions/math/__rem_pio2_large.c deleted file mode 100644 index 958f28c255..0000000000 --- a/waterbox/libc/functions/math/__rem_pio2_large.c +++ /dev/null @@ -1,442 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/k_rem_pio2.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* - * __rem_pio2_large(x,y,e0,nx,prec) - * double x[],y[]; int e0,nx,prec; - * - * __rem_pio2_large return the last three digits of N with - * y = x - N*pi/2 - * so that |y| < pi/2. - * - * The method is to compute the integer (mod 8) and fraction parts of - * (2/pi)*x without doing the full multiplication. In general we - * skip the part of the product that are known to be a huge integer ( - * more accurately, = 0 mod 8 ). Thus the number of operations are - * independent of the exponent of the input. - * - * (2/pi) is represented by an array of 24-bit integers in ipio2[]. - * - * Input parameters: - * x[] The input value (must be positive) is broken into nx - * pieces of 24-bit integers in double precision format. - * x[i] will be the i-th 24 bit of x. The scaled exponent - * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0 - * match x's up to 24 bits. - * - * Example of breaking a double positive z into x[0]+x[1]+x[2]: - * e0 = ilogb(z)-23 - * z = scalbn(z,-e0) - * for i = 0,1,2 - * x[i] = floor(z) - * z = (z-x[i])*2**24 - * - * - * y[] ouput result in an array of double precision numbers. - * The dimension of y[] is: - * 24-bit precision 1 - * 53-bit precision 2 - * 64-bit precision 2 - * 113-bit precision 3 - * The actual value is the sum of them. Thus for 113-bit - * precison, one may have to do something like: - * - * long double t,w,r_head, r_tail; - * t = (long double)y[2] + (long double)y[1]; - * w = (long double)y[0]; - * r_head = t+w; - * r_tail = w - (r_head - t); - * - * e0 The exponent of x[0]. Must be <= 16360 or you need to - * expand the ipio2 table. - * - * nx dimension of x[] - * - * prec an integer indicating the precision: - * 0 24 bits (single) - * 1 53 bits (double) - * 2 64 bits (extended) - * 3 113 bits (quad) - * - * External function: - * double scalbn(), floor(); - * - * - * Here is the description of some local variables: - * - * jk jk+1 is the initial number of terms of ipio2[] needed - * in the computation. The minimum and recommended value - * for jk is 3,4,4,6 for single, double, extended, and quad. - * jk+1 must be 2 larger than you might expect so that our - * recomputation test works. (Up to 24 bits in the integer - * part (the 24 bits of it that we compute) and 23 bits in - * the fraction part may be lost to cancelation before we - * recompute.) - * - * jz local integer variable indicating the number of - * terms of ipio2[] used. - * - * jx nx - 1 - * - * jv index for pointing to the suitable ipio2[] for the - * computation. In general, we want - * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8 - * is an integer. Thus - * e0-3-24*jv >= 0 or (e0-3)/24 >= jv - * Hence jv = max(0,(e0-3)/24). - * - * jp jp+1 is the number of terms in PIo2[] needed, jp = jk. - * - * q[] double array with integral value, representing the - * 24-bits chunk of the product of x and 2/pi. - * - * q0 the corresponding exponent of q[0]. Note that the - * exponent for q[i] would be q0-24*i. - * - * PIo2[] double precision array, obtained by cutting pi/2 - * into 24 bits chunks. - * - * f[] ipio2[] in floating point - * - * iq[] integer array by breaking up q[] in 24-bits chunk. - * - * fq[] final product of x*(2/pi) in fq[0],..,fq[jk] - * - * ih integer. If >0 it indicates q[] is >= 0.5, hence - * it also indicates the *sign* of the result. - * - */ -/* - * Constants: - * The hexadecimal values are the intended ones for the following - * constants. The decimal values may be used, provided that the - * compiler will convert from decimal to binary accurately enough - * to produce the hexadecimal values shown. - */ - -#include "libm.h" - -static const int init_jk[] = {3,4,4,6}; /* initial value for jk */ - -/* - * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi - * - * integer array, contains the (24*i)-th to (24*i+23)-th - * bit of 2/pi after binary point. The corresponding - * floating value is - * - * ipio2[i] * 2^(-24(i+1)). - * - * NB: This table must have at least (e0-3)/24 + jk terms. - * For quad precision (e0 <= 16360, jk = 6), this is 686. - */ -static const int32_t ipio2[] = { -0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, -0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, -0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, -0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41, -0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, -0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF, -0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, -0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, -0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, -0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, -0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, - -#if LDBL_MAX_EXP > 1024 -0x47C419, 0xC367CD, 0xDCE809, 0x2A8359, 0xC4768B, 0x961CA6, -0xDDAF44, 0xD15719, 0x053EA5, 0xFF0705, 0x3F7E33, 0xE832C2, -0xDE4F98, 0x327DBB, 0xC33D26, 0xEF6B1E, 0x5EF89F, 0x3A1F35, -0xCAF27F, 0x1D87F1, 0x21907C, 0x7C246A, 0xFA6ED5, 0x772D30, -0x433B15, 0xC614B5, 0x9D19C3, 0xC2C4AD, 0x414D2C, 0x5D000C, -0x467D86, 0x2D71E3, 0x9AC69B, 0x006233, 0x7CD2B4, 0x97A7B4, -0xD55537, 0xF63ED7, 0x1810A3, 0xFC764D, 0x2A9D64, 0xABD770, -0xF87C63, 0x57B07A, 0xE71517, 0x5649C0, 0xD9D63B, 0x3884A7, -0xCB2324, 0x778AD6, 0x23545A, 0xB91F00, 0x1B0AF1, 0xDFCE19, -0xFF319F, 0x6A1E66, 0x615799, 0x47FBAC, 0xD87F7E, 0xB76522, -0x89E832, 0x60BFE6, 0xCDC4EF, 0x09366C, 0xD43F5D, 0xD7DE16, -0xDE3B58, 0x929BDE, 0x2822D2, 0xE88628, 0x4D58E2, 0x32CAC6, -0x16E308, 0xCB7DE0, 0x50C017, 0xA71DF3, 0x5BE018, 0x34132E, -0x621283, 0x014883, 0x5B8EF5, 0x7FB0AD, 0xF2E91E, 0x434A48, -0xD36710, 0xD8DDAA, 0x425FAE, 0xCE616A, 0xA4280A, 0xB499D3, -0xF2A606, 0x7F775C, 0x83C2A3, 0x883C61, 0x78738A, 0x5A8CAF, -0xBDD76F, 0x63A62D, 0xCBBFF4, 0xEF818D, 0x67C126, 0x45CA55, -0x36D9CA, 0xD2A828, 0x8D61C2, 0x77C912, 0x142604, 0x9B4612, -0xC459C4, 0x44C5C8, 0x91B24D, 0xF31700, 0xAD43D4, 0xE54929, -0x10D5FD, 0xFCBE00, 0xCC941E, 0xEECE70, 0xF53E13, 0x80F1EC, -0xC3E7B3, 0x28F8C7, 0x940593, 0x3E71C1, 0xB3092E, 0xF3450B, -0x9C1288, 0x7B20AB, 0x9FB52E, 0xC29247, 0x2F327B, 0x6D550C, -0x90A772, 0x1FE76B, 0x96CB31, 0x4A1679, 0xE27941, 0x89DFF4, -0x9794E8, 0x84E6E2, 0x973199, 0x6BED88, 0x365F5F, 0x0EFDBB, -0xB49A48, 0x6CA467, 0x427271, 0x325D8D, 0xB8159F, 0x09E5BC, -0x25318D, 0x3974F7, 0x1C0530, 0x010C0D, 0x68084B, 0x58EE2C, -0x90AA47, 0x02E774, 0x24D6BD, 0xA67DF7, 0x72486E, 0xEF169F, -0xA6948E, 0xF691B4, 0x5153D1, 0xF20ACF, 0x339820, 0x7E4BF5, -0x6863B2, 0x5F3EDD, 0x035D40, 0x7F8985, 0x295255, 0xC06437, -0x10D86D, 0x324832, 0x754C5B, 0xD4714E, 0x6E5445, 0xC1090B, -0x69F52A, 0xD56614, 0x9D0727, 0x50045D, 0xDB3BB4, 0xC576EA, -0x17F987, 0x7D6B49, 0xBA271D, 0x296996, 0xACCCC6, 0x5414AD, -0x6AE290, 0x89D988, 0x50722C, 0xBEA404, 0x940777, 0x7030F3, -0x27FC00, 0xA871EA, 0x49C266, 0x3DE064, 0x83DD97, 0x973FA3, -0xFD9443, 0x8C860D, 0xDE4131, 0x9D3992, 0x8C70DD, 0xE7B717, -0x3BDF08, 0x2B3715, 0xA0805C, 0x93805A, 0x921110, 0xD8E80F, -0xAF806C, 0x4BFFDB, 0x0F9038, 0x761859, 0x15A562, 0xBBCB61, -0xB989C7, 0xBD4010, 0x04F2D2, 0x277549, 0xF6B6EB, 0xBB22DB, -0xAA140A, 0x2F2689, 0x768364, 0x333B09, 0x1A940E, 0xAA3A51, -0xC2A31D, 0xAEEDAF, 0x12265C, 0x4DC26D, 0x9C7A2D, 0x9756C0, -0x833F03, 0xF6F009, 0x8C402B, 0x99316D, 0x07B439, 0x15200C, -0x5BC3D8, 0xC492F5, 0x4BADC6, 0xA5CA4E, 0xCD37A7, 0x36A9E6, -0x9492AB, 0x6842DD, 0xDE6319, 0xEF8C76, 0x528B68, 0x37DBFC, -0xABA1AE, 0x3115DF, 0xA1AE00, 0xDAFB0C, 0x664D64, 0xB705ED, -0x306529, 0xBF5657, 0x3AFF47, 0xB9F96A, 0xF3BE75, 0xDF9328, -0x3080AB, 0xF68C66, 0x15CB04, 0x0622FA, 0x1DE4D9, 0xA4B33D, -0x8F1B57, 0x09CD36, 0xE9424E, 0xA4BE13, 0xB52333, 0x1AAAF0, -0xA8654F, 0xA5C1D2, 0x0F3F0B, 0xCD785B, 0x76F923, 0x048B7B, -0x721789, 0x53A6C6, 0xE26E6F, 0x00EBEF, 0x584A9B, 0xB7DAC4, -0xBA66AA, 0xCFCF76, 0x1D02D1, 0x2DF1B1, 0xC1998C, 0x77ADC3, -0xDA4886, 0xA05DF7, 0xF480C6, 0x2FF0AC, 0x9AECDD, 0xBC5C3F, -0x6DDED0, 0x1FC790, 0xB6DB2A, 0x3A25A3, 0x9AAF00, 0x9353AD, -0x0457B6, 0xB42D29, 0x7E804B, 0xA707DA, 0x0EAA76, 0xA1597B, -0x2A1216, 0x2DB7DC, 0xFDE5FA, 0xFEDB89, 0xFDBE89, 0x6C76E4, -0xFCA906, 0x70803E, 0x156E85, 0xFF87FD, 0x073E28, 0x336761, -0x86182A, 0xEABD4D, 0xAFE7B3, 0x6E6D8F, 0x396795, 0x5BBF31, -0x48D784, 0x16DF30, 0x432DC7, 0x356125, 0xCE70C9, 0xB8CB30, -0xFD6CBF, 0xA200A4, 0xE46C05, 0xA0DD5A, 0x476F21, 0xD21262, -0x845CB9, 0x496170, 0xE0566B, 0x015299, 0x375550, 0xB7D51E, -0xC4F133, 0x5F6E13, 0xE4305D, 0xA92E85, 0xC3B21D, 0x3632A1, -0xA4B708, 0xD4B1EA, 0x21F716, 0xE4698F, 0x77FF27, 0x80030C, -0x2D408D, 0xA0CD4F, 0x99A520, 0xD3A2B3, 0x0A5D2F, 0x42F9B4, -0xCBDA11, 0xD0BE7D, 0xC1DB9B, 0xBD17AB, 0x81A2CA, 0x5C6A08, -0x17552E, 0x550027, 0xF0147F, 0x8607E1, 0x640B14, 0x8D4196, -0xDEBE87, 0x2AFDDA, 0xB6256B, 0x34897B, 0xFEF305, 0x9EBFB9, -0x4F6A68, 0xA82A4A, 0x5AC44F, 0xBCF82D, 0x985AD7, 0x95C7F4, -0x8D4D0D, 0xA63A20, 0x5F57A4, 0xB13F14, 0x953880, 0x0120CC, -0x86DD71, 0xB6DEC9, 0xF560BF, 0x11654D, 0x6B0701, 0xACB08C, -0xD0C0B2, 0x485551, 0x0EFB1E, 0xC37295, 0x3B06A3, 0x3540C0, -0x7BDC06, 0xCC45E0, 0xFA294E, 0xC8CAD6, 0x41F3E8, 0xDE647C, -0xD8649B, 0x31BED9, 0xC397A4, 0xD45877, 0xC5E369, 0x13DAF0, -0x3C3ABA, 0x461846, 0x5F7555, 0xF5BDD2, 0xC6926E, 0x5D2EAC, -0xED440E, 0x423E1C, 0x87C461, 0xE9FD29, 0xF3D6E7, 0xCA7C22, -0x35916F, 0xC5E008, 0x8DD7FF, 0xE26A6E, 0xC6FDB0, 0xC10893, -0x745D7C, 0xB2AD6B, 0x9D6ECD, 0x7B723E, 0x6A11C6, 0xA9CFF7, -0xDF7329, 0xBAC9B5, 0x5100B7, 0x0DB2E2, 0x24BA74, 0x607DE5, -0x8AD874, 0x2C150D, 0x0C1881, 0x94667E, 0x162901, 0x767A9F, -0xBEFDFD, 0xEF4556, 0x367ED9, 0x13D9EC, 0xB9BA8B, 0xFC97C4, -0x27A831, 0xC36EF1, 0x36C594, 0x56A8D8, 0xB5A8B4, 0x0ECCCF, -0x2D8912, 0x34576F, 0x89562C, 0xE3CE99, 0xB920D6, 0xAA5E6B, -0x9C2A3E, 0xCC5F11, 0x4A0BFD, 0xFBF4E1, 0x6D3B8E, 0x2C86E2, -0x84D4E9, 0xA9B4FC, 0xD1EEEF, 0xC9352E, 0x61392F, 0x442138, -0xC8D91B, 0x0AFC81, 0x6A4AFB, 0xD81C2F, 0x84B453, 0x8C994E, -0xCC2254, 0xDC552A, 0xD6C6C0, 0x96190B, 0xB8701A, 0x649569, -0x605A26, 0xEE523F, 0x0F117F, 0x11B5F4, 0xF5CBFC, 0x2DBC34, -0xEEBC34, 0xCC5DE8, 0x605EDD, 0x9B8E67, 0xEF3392, 0xB817C9, -0x9B5861, 0xBC57E1, 0xC68351, 0x103ED8, 0x4871DD, 0xDD1C2D, -0xA118AF, 0x462C21, 0xD7F359, 0x987AD9, 0xC0549E, 0xFA864F, -0xFC0656, 0xAE79E5, 0x362289, 0x22AD38, 0xDC9367, 0xAAE855, -0x382682, 0x9BE7CA, 0xA40D51, 0xB13399, 0x0ED7A9, 0x480569, -0xF0B265, 0xA7887F, 0x974C88, 0x36D1F9, 0xB39221, 0x4A827B, -0x21CF98, 0xDC9F40, 0x5547DC, 0x3A74E1, 0x42EB67, 0xDF9DFE, -0x5FD45E, 0xA4677B, 0x7AACBA, 0xA2F655, 0x23882B, 0x55BA41, -0x086E59, 0x862A21, 0x834739, 0xE6E389, 0xD49EE5, 0x40FB49, -0xE956FF, 0xCA0F1C, 0x8A59C5, 0x2BFA94, 0xC5C1D3, 0xCFC50F, -0xAE5ADB, 0x86C547, 0x624385, 0x3B8621, 0x94792C, 0x876110, -0x7B4C2A, 0x1A2C80, 0x12BF43, 0x902688, 0x893C78, 0xE4C4A8, -0x7BDBE5, 0xC23AC4, 0xEAF426, 0x8A67F7, 0xBF920D, 0x2BA365, -0xB1933D, 0x0B7CBD, 0xDC51A4, 0x63DD27, 0xDDE169, 0x19949A, -0x9529A8, 0x28CE68, 0xB4ED09, 0x209F44, 0xCA984E, 0x638270, -0x237C7E, 0x32B90F, 0x8EF5A7, 0xE75614, 0x08F121, 0x2A9DB5, -0x4D7E6F, 0x5119A5, 0xABF9B5, 0xD6DF82, 0x61DD96, 0x023616, -0x9F3AC4, 0xA1A283, 0x6DED72, 0x7A8D39, 0xA9B882, 0x5C326B, -0x5B2746, 0xED3400, 0x7700D2, 0x55F4FC, 0x4D5901, 0x8071E0, -#endif -}; - -static const double PIo2[] = { - 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */ - 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */ - 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */ - 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */ - 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */ - 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */ - 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */ - 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */ -}; - -int __rem_pio2_large(double *x, double *y, int e0, int nx, int prec) -{ - int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; - double z,fw,f[20],fq[20],q[20]; - - /* initialize jk*/ - jk = init_jk[prec]; - jp = jk; - - /* determine jx,jv,q0, note that 3>q0 */ - jx = nx-1; - jv = (e0-3)/24; if(jv<0) jv=0; - q0 = e0-24*(jv+1); - - /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ - j = jv-jx; m = jx+jk; - for (i=0; i<=m; i++,j++) - f[i] = j<0 ? 0.0 : (double)ipio2[j]; - - /* compute q[0],q[1],...q[jk] */ - for (i=0; i<=jk; i++) { - for (j=0,fw=0.0; j<=jx; j++) - fw += x[j]*f[jx+i-j]; - q[i] = fw; - } - - jz = jk; -recompute: - /* distill q[] into iq[] reversingly */ - for (i=0,j=jz,z=q[jz]; j>0; i++,j--) { - fw = (double)(int32_t)(0x1p-24*z); - iq[i] = (int32_t)(z - 0x1p24*fw); - z = q[j-1]+fw; - } - - /* compute n */ - z = scalbn(z,q0); /* actual value of z */ - z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */ - n = (int32_t)z; - z -= (double)n; - ih = 0; - if (q0 > 0) { /* need iq[jz-1] to determine n */ - i = iq[jz-1]>>(24-q0); n += i; - iq[jz-1] -= i<<(24-q0); - ih = iq[jz-1]>>(23-q0); - } - else if (q0 == 0) ih = iq[jz-1]>>23; - else if (z >= 0.5) ih = 2; - - if (ih > 0) { /* q > 0.5 */ - n += 1; carry = 0; - for (i=0; i 0) { /* rare case: chance is 1 in 12 */ - switch(q0) { - case 1: - iq[jz-1] &= 0x7fffff; break; - case 2: - iq[jz-1] &= 0x3fffff; break; - } - } - if (ih == 2) { - z = 1.0 - z; - if (carry != 0) - z -= scalbn(1.0,q0); - } - } - - /* check if recomputation is needed */ - if (z == 0.0) { - j = 0; - for (i=jz-1; i>=jk; i--) j |= iq[i]; - if (j == 0) { /* need recomputation */ - for (k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */ - - for (i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */ - f[jx+i] = (double)ipio2[jv+i]; - for (j=0,fw=0.0; j<=jx; j++) - fw += x[j]*f[jx+i-j]; - q[i] = fw; - } - jz += k; - goto recompute; - } - } - - /* chop off zero terms */ - if (z == 0.0) { - jz -= 1; - q0 -= 24; - while (iq[jz] == 0) { - jz--; - q0 -= 24; - } - } else { /* break z into 24-bit if necessary */ - z = scalbn(z,-q0); - if (z >= 0x1p24) { - fw = (double)(int32_t)(0x1p-24*z); - iq[jz] = (int32_t)(z - 0x1p24*fw); - jz += 1; - q0 += 24; - iq[jz] = (int32_t)fw; - } else - iq[jz] = (int32_t)z; - } - - /* convert integer "bit" chunk to floating-point value */ - fw = scalbn(1.0,q0); - for (i=jz; i>=0; i--) { - q[i] = fw*(double)iq[i]; - fw *= 0x1p-24; - } - - /* compute PIo2[0,...,jp]*q[jz,...,0] */ - for(i=jz; i>=0; i--) { - for (fw=0.0,k=0; k<=jp && k<=jz-i; k++) - fw += PIo2[k]*q[i+k]; - fq[jz-i] = fw; - } - - /* compress fq[] into y[] */ - switch(prec) { - case 0: - fw = 0.0; - for (i=jz; i>=0; i--) - fw += fq[i]; - y[0] = ih==0 ? fw : -fw; - break; - case 1: - case 2: - fw = 0.0; - for (i=jz; i>=0; i--) - fw += fq[i]; - // TODO: drop excess precision here once double_t is used - fw = (double)fw; - y[0] = ih==0 ? fw : -fw; - fw = fq[0]-fw; - for (i=1; i<=jz; i++) - fw += fq[i]; - y[1] = ih==0 ? fw : -fw; - break; - case 3: /* painful */ - for (i=jz; i>0; i--) { - fw = fq[i-1]+fq[i]; - fq[i] += fq[i-1]-fw; - fq[i-1] = fw; - } - for (i=jz; i>1; i--) { - fw = fq[i-1]+fq[i]; - fq[i] += fq[i-1]-fw; - fq[i-1] = fw; - } - for (fw=0.0,i=jz; i>=2; i--) - fw += fq[i]; - if (ih==0) { - y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; - } else { - y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; - } - } - return n&7; -} diff --git a/waterbox/libc/functions/math/__rem_pio2f.c b/waterbox/libc/functions/math/__rem_pio2f.c deleted file mode 100644 index 4473c1c420..0000000000 --- a/waterbox/libc/functions/math/__rem_pio2f.c +++ /dev/null @@ -1,75 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2f.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - * Debugged and optimized by Bruce D. Evans. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* __rem_pio2f(x,y) - * - * return the remainder of x rem pi/2 in *y - * use double precision for everything except passing x - * use __rem_pio2_large() for large x - */ - -#include "libm.h" - -#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 -#define EPS DBL_EPSILON -#elif FLT_EVAL_METHOD==2 -#define EPS LDBL_EPSILON -#endif - -/* - * invpio2: 53 bits of 2/pi - * pio2_1: first 25 bits of pi/2 - * pio2_1t: pi/2 - pio2_1 - */ -static const double -toint = 1.5/EPS, -invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ -pio2_1 = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */ -pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */ - -int __rem_pio2f(float x, double *y) -{ - union {float f; uint32_t i;} u = {x}; - double tx[1],ty[1]; - double_t fn; - uint32_t ix; - int n, sign, e0; - - ix = u.i & 0x7fffffff; - /* 25+53 bit pi is good enough for medium size */ - if (ix < 0x4dc90fdb) { /* |x| ~< 2^28*(pi/2), medium size */ - /* Use a specialized rint() to get fn. Assume round-to-nearest. */ - fn = (double_t)x*invpio2 + toint - toint; - n = (int32_t)fn; - *y = x - fn*pio2_1 - fn*pio2_1t; - return n; - } - if(ix>=0x7f800000) { /* x is inf or NaN */ - *y = x-x; - return 0; - } - /* scale x into [2^23, 2^24-1] */ - sign = u.i>>31; - e0 = (ix>>23) - (0x7f+23); /* e0 = ilogb(|x|)-23, positive */ - u.i = ix - (e0<<23); - tx[0] = u.f; - n = __rem_pio2_large(tx,ty,e0,1,0); - if (sign) { - *y = -ty[0]; - return -n; - } - *y = ty[0]; - return n; -} diff --git a/waterbox/libc/functions/math/__rem_pio2l.c b/waterbox/libc/functions/math/__rem_pio2l.c deleted file mode 100644 index 77255bd80a..0000000000 --- a/waterbox/libc/functions/math/__rem_pio2l.c +++ /dev/null @@ -1,141 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/ld80/e_rem_pio2.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - * - * Optimized by Bruce D. Evans. - */ -#include "libm.h" -#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -/* ld80 and ld128 version of __rem_pio2(x,y) - * - * return the remainder of x rem pi/2 in y[0]+y[1] - * use __rem_pio2_large() for large x - */ - -static const long double toint = 1.5/LDBL_EPSILON; - -#if LDBL_MANT_DIG == 64 -/* u ~< 0x1p25*pi/2 */ -#define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.m>>48) < ((0x3fff + 25)<<16 | 0x921f>>1 | 0x8000)) -#define QUOBITS(x) ((uint32_t)(int32_t)x & 0x7fffffff) -#define ROUND1 22 -#define ROUND2 61 -#define NX 3 -#define NY 2 -/* - * invpio2: 64 bits of 2/pi - * pio2_1: first 39 bits of pi/2 - * pio2_1t: pi/2 - pio2_1 - * pio2_2: second 39 bits of pi/2 - * pio2_2t: pi/2 - (pio2_1+pio2_2) - * pio2_3: third 39 bits of pi/2 - * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) - */ -static const double -pio2_1 = 1.57079632679597125389e+00, /* 0x3FF921FB, 0x54444000 */ -pio2_2 = -1.07463465549783099519e-12, /* -0x12e7b967674000.0p-92 */ -pio2_3 = 6.36831716351370313614e-25; /* 0x18a2e037074000.0p-133 */ -static const long double -invpio2 = 6.36619772367581343076e-01L, /* 0xa2f9836e4e44152a.0p-64 */ -pio2_1t = -1.07463465549719416346e-12L, /* -0x973dcb3b399d747f.0p-103 */ -pio2_2t = 6.36831716351095013979e-25L, /* 0xc51701b839a25205.0p-144 */ -pio2_3t = -2.75299651904407171810e-37L; /* -0xbb5bf6c7ddd660ce.0p-185 */ -#elif LDBL_MANT_DIG == 113 -/* u ~< 0x1p45*pi/2 */ -#define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.top) < ((0x3fff + 45)<<16 | 0x921f)) -#define QUOBITS(x) ((uint32_t)(int64_t)x & 0x7fffffff) -#define ROUND1 51 -#define ROUND2 119 -#define NX 5 -#define NY 3 -static const long double -invpio2 = 6.3661977236758134307553505349005747e-01L, /* 0x145f306dc9c882a53f84eafa3ea6a.0p-113 */ -pio2_1 = 1.5707963267948966192292994253909555e+00L, /* 0x1921fb54442d18469800000000000.0p-112 */ -pio2_1t = 2.0222662487959507323996846200947577e-21L, /* 0x13198a2e03707344a4093822299f3.0p-181 */ -pio2_2 = 2.0222662487959507323994779168837751e-21L, /* 0x13198a2e03707344a400000000000.0p-181 */ -pio2_2t = 2.0670321098263988236496903051604844e-43L, /* 0x127044533e63a0105df531d89cd91.0p-254 */ -pio2_3 = 2.0670321098263988236499468110329591e-43L, /* 0x127044533e63a0105e00000000000.0p-254 */ -pio2_3t = -2.5650587247459238361625433492959285e-65L; /* -0x159c4ec64ddaeb5f78671cbfb2210.0p-327 */ -#endif - -int __rem_pio2l(long double x, long double *y) -{ - union ldshape u,uz; - long double z,w,t,r,fn; - double tx[NX],ty[NY]; - int ex,ey,n,i; - - u.f = x; - ex = u.i.se & 0x7fff; - if (SMALL(u)) { - /* rint(x/(pi/2)), Assume round-to-nearest. */ - fn = x*invpio2 + toint - toint; - n = QUOBITS(fn); - r = x-fn*pio2_1; - w = fn*pio2_1t; /* 1st round good to 102/180 bits (ld80/ld128) */ - y[0] = r-w; - u.f = y[0]; - ey = u.i.se & 0x7fff; - if (ex - ey > ROUND1) { /* 2nd iteration needed, good to 141/248 (ld80/ld128) */ - t = r; - w = fn*pio2_2; - r = t-w; - w = fn*pio2_2t-((t-r)-w); - y[0] = r-w; - u.f = y[0]; - ey = u.i.se & 0x7fff; - if (ex - ey > ROUND2) { /* 3rd iteration, good to 180/316 bits */ - t = r; /* will cover all possible cases (not verified for ld128) */ - w = fn*pio2_3; - r = t-w; - w = fn*pio2_3t-((t-r)-w); - y[0] = r-w; - } - } - y[1] = (r - y[0]) - w; - return n; - } - /* - * all other (large) arguments - */ - if (ex == 0x7fff) { /* x is inf or NaN */ - y[0] = y[1] = x - x; - return 0; - } - /* set z = scalbn(|x|,-ilogb(x)+23) */ - uz.f = x; - uz.i.se = 0x3fff + 23; - z = uz.f; - for (i=0; i < NX - 1; i++) { - tx[i] = (double)(int32_t)z; - z = (z-tx[i])*0x1p24; - } - tx[i] = z; - while (tx[i] == 0) - i--; - n = __rem_pio2_large(tx, ty, ex-0x3fff-23, i+1, NY); - w = ty[1]; - if (NY == 3) - w += ty[2]; - r = ty[0] + w; - /* TODO: for ld128 this does not follow the recommendation of the - comments of __rem_pio2_large which seem wrong if |ty[0]| > |ty[1]+ty[2]| */ - w -= r - ty[0]; - if (u.i.se >> 15) { - y[0] = -r; - y[1] = -w; - return -n; - } - y[0] = r; - y[1] = w; - return n; -} -#endif diff --git a/waterbox/libc/functions/math/__signbit.c b/waterbox/libc/functions/math/__signbit.c deleted file mode 100644 index e700b6b75f..0000000000 --- a/waterbox/libc/functions/math/__signbit.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "libm.h" - -// FIXME: macro in math.h -int __signbit(double x) -{ - union { - double d; - uint64_t i; - } y = { x }; - return y.i>>63; -} - - diff --git a/waterbox/libc/functions/math/__signbitf.c b/waterbox/libc/functions/math/__signbitf.c deleted file mode 100644 index 40ad3cfd0c..0000000000 --- a/waterbox/libc/functions/math/__signbitf.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "libm.h" - -// FIXME: macro in math.h -int __signbitf(float x) -{ - union { - float f; - uint32_t i; - } y = { x }; - return y.i>>31; -} diff --git a/waterbox/libc/functions/math/__signbitl.c b/waterbox/libc/functions/math/__signbitl.c deleted file mode 100644 index 63b3dc5a08..0000000000 --- a/waterbox/libc/functions/math/__signbitl.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "libm.h" - -#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -int __signbitl(long double x) -{ - union ldshape u = {x}; - return u.i.se >> 15; -} -#elif LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -int __signbitl(long double x) -{ - return __signbit(x); -} -#endif diff --git a/waterbox/libc/functions/math/__sin.c b/waterbox/libc/functions/math/__sin.c deleted file mode 100644 index 4030949664..0000000000 --- a/waterbox/libc/functions/math/__sin.c +++ /dev/null @@ -1,64 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/k_sin.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* __sin( x, y, iy) - * kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854 - * Input x is assumed to be bounded by ~pi/4 in magnitude. - * Input y is the tail of x. - * Input iy indicates whether y is 0. (if iy=0, y assume to be 0). - * - * Algorithm - * 1. Since sin(-x) = -sin(x), we need only to consider positive x. - * 2. Callers must return sin(-0) = -0 without calling here since our - * odd polynomial is not evaluated in a way that preserves -0. - * Callers may do the optimization sin(x) ~ x for tiny x. - * 3. sin(x) is approximated by a polynomial of degree 13 on - * [0,pi/4] - * 3 13 - * sin(x) ~ x + S1*x + ... + S6*x - * where - * - * |sin(x) 2 4 6 8 10 12 | -58 - * |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2 - * | x | - * - * 4. sin(x+y) = sin(x) + sin'(x')*y - * ~ sin(x) + (1-x*x/2)*y - * For better accuracy, let - * 3 2 2 2 2 - * r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6)))) - * then 3 2 - * sin(x) = x + (S1*x + (x *(r-y/2)+y)) - */ - -#include "libm.h" - -static const double -S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */ -S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */ -S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */ -S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */ -S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */ -S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */ - -double __sin(double x, double y, int iy) -{ - double_t z,r,v,w; - - z = x*x; - w = z*z; - r = S2 + z*(S3 + z*S4) + z*w*(S5 + z*S6); - v = z*x; - if (iy == 0) - return x + v*(S1 + z*r); - else - return x - ((z*(0.5*y - v*r) - y) - v*S1); -} diff --git a/waterbox/libc/functions/math/__sindf.c b/waterbox/libc/functions/math/__sindf.c deleted file mode 100644 index 8fec2a3f66..0000000000 --- a/waterbox/libc/functions/math/__sindf.c +++ /dev/null @@ -1,36 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/k_sinf.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - * Optimized by Bruce D. Evans. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" - -/* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */ -static const double -S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */ -S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */ -S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */ -S4 = 0x16cd878c3b46a7.0p-71; /* 0.0000027183114939898219064 */ - -float __sindf(double x) -{ - double_t r, s, w, z; - - /* Try to optimize for parallel evaluation as in __tandf.c. */ - z = x*x; - w = z*z; - r = S3 + z*S4; - s = z*x; - return (x + s*(S1 + z*S2)) + s*w*r; -} diff --git a/waterbox/libc/functions/math/__sinl.c b/waterbox/libc/functions/math/__sinl.c deleted file mode 100644 index 2525bbe866..0000000000 --- a/waterbox/libc/functions/math/__sinl.c +++ /dev/null @@ -1,78 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/ld80/k_sinl.c */ -/* origin: FreeBSD /usr/src/lib/msun/ld128/k_sinl.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" - -#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -#if LDBL_MANT_DIG == 64 -/* - * ld80 version of __sin.c. See __sin.c for most comments. - */ -/* - * Domain [-0.7854, 0.7854], range ~[-1.89e-22, 1.915e-22] - * |sin(x)/x - s(x)| < 2**-72.1 - * - * See __cosl.c for more details about the polynomial. - */ -static const long double -S1 = -0.166666666666666666671L; /* -0xaaaaaaaaaaaaaaab.0p-66 */ -static const double -S2 = 0.0083333333333333332, /* 0x11111111111111.0p-59 */ -S3 = -0.00019841269841269427, /* -0x1a01a01a019f81.0p-65 */ -S4 = 0.0000027557319223597490, /* 0x171de3a55560f7.0p-71 */ -S5 = -0.000000025052108218074604, /* -0x1ae64564f16cad.0p-78 */ -S6 = 1.6059006598854211e-10, /* 0x161242b90243b5.0p-85 */ -S7 = -7.6429779983024564e-13, /* -0x1ae42ebd1b2e00.0p-93 */ -S8 = 2.6174587166648325e-15; /* 0x179372ea0b3f64.0p-101 */ -#define POLY(z) (S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*S8)))))) -#elif LDBL_MANT_DIG == 113 -/* - * ld128 version of __sin.c. See __sin.c for most comments. - */ -/* - * Domain [-0.7854, 0.7854], range ~[-1.53e-37, 1.659e-37] - * |sin(x)/x - s(x)| < 2**-122.1 - * - * See __cosl.c for more details about the polynomial. - */ -static const long double -S1 = -0.16666666666666666666666666666666666606732416116558L, -S2 = 0.0083333333333333333333333333333331135404851288270047L, -S3 = -0.00019841269841269841269841269839935785325638310428717L, -S4 = 0.27557319223985890652557316053039946268333231205686e-5L, -S5 = -0.25052108385441718775048214826384312253862930064745e-7L, -S6 = 0.16059043836821614596571832194524392581082444805729e-9L, -S7 = -0.76471637318198151807063387954939213287488216303768e-12L, -S8 = 0.28114572543451292625024967174638477283187397621303e-14L; -static const double -S9 = -0.82206352458348947812512122163446202498005154296863e-17, -S10 = 0.19572940011906109418080609928334380560135358385256e-19, -S11 = -0.38680813379701966970673724299207480965452616911420e-22, -S12 = 0.64038150078671872796678569586315881020659912139412e-25; -#define POLY(z) (S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*(S8+ \ - z*(S9+z*(S10+z*(S11+z*S12)))))))))) -#endif - -long double __sinl(long double x, long double y, int iy) -{ - long double z,r,v; - - z = x*x; - v = z*x; - r = POLY(z); - if (iy == 0) - return x+v*(S1+z*r); - return x-((z*(0.5*y-v*r)-y)-v*S1); -} -#endif diff --git a/waterbox/libc/functions/math/__tan.c b/waterbox/libc/functions/math/__tan.c deleted file mode 100644 index 8019844d3b..0000000000 --- a/waterbox/libc/functions/math/__tan.c +++ /dev/null @@ -1,110 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/k_tan.c */ -/* - * ==================================================== - * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. - * - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* __tan( x, y, k ) - * kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854 - * Input x is assumed to be bounded by ~pi/4 in magnitude. - * Input y is the tail of x. - * Input odd indicates whether tan (if odd = 0) or -1/tan (if odd = 1) is returned. - * - * Algorithm - * 1. Since tan(-x) = -tan(x), we need only to consider positive x. - * 2. Callers must return tan(-0) = -0 without calling here since our - * odd polynomial is not evaluated in a way that preserves -0. - * Callers may do the optimization tan(x) ~ x for tiny x. - * 3. tan(x) is approximated by a odd polynomial of degree 27 on - * [0,0.67434] - * 3 27 - * tan(x) ~ x + T1*x + ... + T13*x - * where - * - * |tan(x) 2 4 26 | -59.2 - * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2 - * | x | - * - * Note: tan(x+y) = tan(x) + tan'(x)*y - * ~ tan(x) + (1+x*x)*y - * Therefore, for better accuracy in computing tan(x+y), let - * 3 2 2 2 2 - * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13)))) - * then - * 3 2 - * tan(x+y) = x + (T1*x + (x *(r+y)+y)) - * - * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then - * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y)) - * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y))) - */ - -#include "libm.h" - -static const double T[] = { - 3.33333333333334091986e-01, /* 3FD55555, 55555563 */ - 1.33333333333201242699e-01, /* 3FC11111, 1110FE7A */ - 5.39682539762260521377e-02, /* 3FABA1BA, 1BB341FE */ - 2.18694882948595424599e-02, /* 3F9664F4, 8406D637 */ - 8.86323982359930005737e-03, /* 3F8226E3, E96E8493 */ - 3.59207910759131235356e-03, /* 3F6D6D22, C9560328 */ - 1.45620945432529025516e-03, /* 3F57DBC8, FEE08315 */ - 5.88041240820264096874e-04, /* 3F4344D8, F2F26501 */ - 2.46463134818469906812e-04, /* 3F3026F7, 1A8D1068 */ - 7.81794442939557092300e-05, /* 3F147E88, A03792A6 */ - 7.14072491382608190305e-05, /* 3F12B80F, 32F0A7E9 */ - -1.85586374855275456654e-05, /* BEF375CB, DB605373 */ - 2.59073051863633712884e-05, /* 3EFB2A70, 74BF7AD4 */ -}, -pio4 = 7.85398163397448278999e-01, /* 3FE921FB, 54442D18 */ -pio4lo = 3.06161699786838301793e-17; /* 3C81A626, 33145C07 */ - -double __tan(double x, double y, int odd) -{ - double_t z, r, v, w, s, a; - double w0, a0; - uint32_t hx; - int big, sign; - - GET_HIGH_WORD(hx,x); - big = (hx&0x7fffffff) >= 0x3FE59428; /* |x| >= 0.6744 */ - if (big) { - sign = hx>>31; - if (sign) { - x = -x; - y = -y; - } - x = (pio4 - x) + (pio4lo - y); - y = 0.0; - } - z = x * x; - w = z * z; - /* - * Break x^5*(T[1]+x^2*T[2]+...) into - * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) + - * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12])) - */ - r = T[1] + w*(T[3] + w*(T[5] + w*(T[7] + w*(T[9] + w*T[11])))); - v = z*(T[2] + w*(T[4] + w*(T[6] + w*(T[8] + w*(T[10] + w*T[12]))))); - s = z * x; - r = y + z*(s*(r + v) + y) + s*T[0]; - w = x + r; - if (big) { - s = 1 - 2*odd; - v = s - 2.0 * (x + (r - w*w/(w + s))); - return sign ? -v : v; - } - if (!odd) - return w; - /* -1.0/(x+r) has up to 2ulp error, so compute it accurately */ - w0 = w; - SET_LOW_WORD(w0, 0); - v = r - (w0 - x); /* w0+v = r+x */ - a0 = a = -1.0 / w; - SET_LOW_WORD(a0, 0); - return a0 + a*(1.0 + a0*w0 + a0*v); -} diff --git a/waterbox/libc/functions/math/__tandf.c b/waterbox/libc/functions/math/__tandf.c deleted file mode 100644 index 25047eeee9..0000000000 --- a/waterbox/libc/functions/math/__tandf.c +++ /dev/null @@ -1,54 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/k_tanf.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - * Optimized by Bruce D. Evans. - */ -/* - * ==================================================== - * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. - * - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" - -/* |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). */ -static const double T[] = { - 0x15554d3418c99f.0p-54, /* 0.333331395030791399758 */ - 0x1112fd38999f72.0p-55, /* 0.133392002712976742718 */ - 0x1b54c91d865afe.0p-57, /* 0.0533812378445670393523 */ - 0x191df3908c33ce.0p-58, /* 0.0245283181166547278873 */ - 0x185dadfcecf44e.0p-61, /* 0.00297435743359967304927 */ - 0x1362b9bf971bcd.0p-59, /* 0.00946564784943673166728 */ -}; - -float __tandf(double x, int odd) -{ - double_t z,r,w,s,t,u; - - z = x*x; - /* - * Split up the polynomial into small independent terms to give - * opportunities for parallel evaluation. The chosen splitting is - * micro-optimized for Athlons (XP, X64). It costs 2 multiplications - * relative to Horner's method on sequential machines. - * - * We add the small terms from lowest degree up for efficiency on - * non-sequential machines (the lowest degree terms tend to be ready - * earlier). Apart from this, we don't care about order of - * operations, and don't need to to care since we have precision to - * spare. However, the chosen splitting is good for accuracy too, - * and would give results as accurate as Horner's method if the - * small terms were added from highest degree down. - */ - r = T[4] + z*T[5]; - t = T[2] + z*T[3]; - w = z*z; - s = z*x; - u = T[0] + z*T[1]; - r = (x + s*u) + (s*w)*(t + w*r); - return odd ? -1.0/r : r; -} diff --git a/waterbox/libc/functions/math/__tanl.c b/waterbox/libc/functions/math/__tanl.c deleted file mode 100644 index 54abc3daf1..0000000000 --- a/waterbox/libc/functions/math/__tanl.c +++ /dev/null @@ -1,143 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/ld80/k_tanl.c */ -/* origin: FreeBSD /usr/src/lib/msun/ld128/k_tanl.c */ -/* - * ==================================================== - * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. - * - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" - -#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -#if LDBL_MANT_DIG == 64 -/* - * ld80 version of __tan.c. See __tan.c for most comments. - */ -/* - * Domain [-0.67434, 0.67434], range ~[-2.25e-22, 1.921e-22] - * |tan(x)/x - t(x)| < 2**-71.9 - * - * See __cosl.c for more details about the polynomial. - */ -static const long double -T3 = 0.333333333333333333180L, /* 0xaaaaaaaaaaaaaaa5.0p-65 */ -T5 = 0.133333333333333372290L, /* 0x88888888888893c3.0p-66 */ -T7 = 0.0539682539682504975744L, /* 0xdd0dd0dd0dc13ba2.0p-68 */ -pio4 = 0.785398163397448309628L, /* 0xc90fdaa22168c235.0p-64 */ -pio4lo = -1.25413940316708300586e-20L; /* -0xece675d1fc8f8cbb.0p-130 */ -static const double -T9 = 0.021869488536312216, /* 0x1664f4882cc1c2.0p-58 */ -T11 = 0.0088632355256619590, /* 0x1226e355c17612.0p-59 */ -T13 = 0.0035921281113786528, /* 0x1d6d3d185d7ff8.0p-61 */ -T15 = 0.0014558334756312418, /* 0x17da354aa3f96b.0p-62 */ -T17 = 0.00059003538700862256, /* 0x13559358685b83.0p-63 */ -T19 = 0.00023907843576635544, /* 0x1f56242026b5be.0p-65 */ -T21 = 0.000097154625656538905, /* 0x1977efc26806f4.0p-66 */ -T23 = 0.000038440165747303162, /* 0x14275a09b3ceac.0p-67 */ -T25 = 0.000018082171885432524, /* 0x12f5e563e5487e.0p-68 */ -T27 = 0.0000024196006108814377, /* 0x144c0d80cc6896.0p-71 */ -T29 = 0.0000078293456938132840, /* 0x106b59141a6cb3.0p-69 */ -T31 = -0.0000032609076735050182, /* -0x1b5abef3ba4b59.0p-71 */ -T33 = 0.0000023261313142559411; /* 0x13835436c0c87f.0p-71 */ -#define RPOLY(w) (T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + \ - w * (T25 + w * (T29 + w * T33))))))) -#define VPOLY(w) (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + \ - w * (T27 + w * T31)))))) -#elif LDBL_MANT_DIG == 113 -/* - * ld128 version of __tan.c. See __tan.c for most comments. - */ -/* - * Domain [-0.67434, 0.67434], range ~[-3.37e-36, 1.982e-37] - * |tan(x)/x - t(x)| < 2**-117.8 (XXX should be ~1e-37) - * - * See __cosl.c for more details about the polynomial. - */ -static const long double -T3 = 0x1.5555555555555555555555555553p-2L, -T5 = 0x1.1111111111111111111111111eb5p-3L, -T7 = 0x1.ba1ba1ba1ba1ba1ba1ba1b694cd6p-5L, -T9 = 0x1.664f4882c10f9f32d6bbe09d8bcdp-6L, -T11 = 0x1.226e355e6c23c8f5b4f5762322eep-7L, -T13 = 0x1.d6d3d0e157ddfb5fed8e84e27b37p-9L, -T15 = 0x1.7da36452b75e2b5fce9ee7c2c92ep-10L, -T17 = 0x1.355824803674477dfcf726649efep-11L, -T19 = 0x1.f57d7734d1656e0aceb716f614c2p-13L, -T21 = 0x1.967e18afcb180ed942dfdc518d6cp-14L, -T23 = 0x1.497d8eea21e95bc7e2aa79b9f2cdp-15L, -T25 = 0x1.0b132d39f055c81be49eff7afd50p-16L, -T27 = 0x1.b0f72d33eff7bfa2fbc1059d90b6p-18L, -T29 = 0x1.5ef2daf21d1113df38d0fbc00267p-19L, -T31 = 0x1.1c77d6eac0234988cdaa04c96626p-20L, -T33 = 0x1.cd2a5a292b180e0bdd701057dfe3p-22L, -T35 = 0x1.75c7357d0298c01a31d0a6f7d518p-23L, -T37 = 0x1.2f3190f4718a9a520f98f50081fcp-24L, -pio4 = 0x1.921fb54442d18469898cc51701b8p-1L, -pio4lo = 0x1.cd129024e088a67cc74020bbea60p-116L; -static const double -T39 = 0.000000028443389121318352, /* 0x1e8a7592977938.0p-78 */ -T41 = 0.000000011981013102001973, /* 0x19baa1b1223219.0p-79 */ -T43 = 0.0000000038303578044958070, /* 0x107385dfb24529.0p-80 */ -T45 = 0.0000000034664378216909893, /* 0x1dc6c702a05262.0p-81 */ -T47 = -0.0000000015090641701997785, /* -0x19ecef3569ebb6.0p-82 */ -T49 = 0.0000000029449552300483952, /* 0x194c0668da786a.0p-81 */ -T51 = -0.0000000022006995706097711, /* -0x12e763b8845268.0p-81 */ -T53 = 0.0000000015468200913196612, /* 0x1a92fc98c29554.0p-82 */ -T55 = -0.00000000061311613386849674, /* -0x151106cbc779a9.0p-83 */ -T57 = 1.4912469681508012e-10; /* 0x147edbdba6f43a.0p-85 */ -#define RPOLY(w) (T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + \ - w * (T25 + w * (T29 + w * (T33 + w * (T37 + w * (T41 + \ - w * (T45 + w * (T49 + w * (T53 + w * T57))))))))))))) -#define VPOLY(w) (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + \ - w * (T27 + w * (T31 + w * (T35 + w * (T39 + w * (T43 + \ - w * (T47 + w * (T51 + w * T55)))))))))))) -#endif - -long double __tanl(long double x, long double y, int odd) { - long double z, r, v, w, s, a, t; - int big, sign; - - big = fabsl(x) >= 0.67434; - if (big) { - sign = 0; - if (x < 0) { - sign = 1; - x = -x; - y = -y; - } - x = (pio4 - x) + (pio4lo - y); - y = 0.0; - } - z = x * x; - w = z * z; - r = RPOLY(w); - v = z * VPOLY(w); - s = z * x; - r = y + z * (s * (r + v) + y) + T3 * s; - w = x + r; - if (big) { - s = 1 - 2*odd; - v = s - 2.0 * (x + (r - w * w / (w + s))); - return sign ? -v : v; - } - if (!odd) - return w; - /* - * if allow error up to 2 ulp, simply return - * -1.0 / (x+r) here - */ - /* compute -1.0 / (x+r) accurately */ - z = w; - z = z + 0x1p32 - 0x1p32; - v = r - (z - x); /* z+v = r+x */ - t = a = -1.0 / w; /* a = -1.0/w */ - t = t + 0x1p32 - 0x1p32; - s = 1.0 + t * z; - return t + a * (s + t * v); -} -#endif diff --git a/waterbox/libc/functions/math/acos.c b/waterbox/libc/functions/math/acos.c deleted file mode 100644 index ea9c87bf08..0000000000 --- a/waterbox/libc/functions/math/acos.c +++ /dev/null @@ -1,101 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_acos.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* acos(x) - * Method : - * acos(x) = pi/2 - asin(x) - * acos(-x) = pi/2 + asin(x) - * For |x|<=0.5 - * acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c) - * For x>0.5 - * acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2))) - * = 2asin(sqrt((1-x)/2)) - * = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z) - * = 2f + (2c + 2s*z*R(z)) - * where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term - * for f so that f+c ~ sqrt(z). - * For x<-0.5 - * acos(x) = pi - 2asin(sqrt((1-|x|)/2)) - * = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z) - * - * Special cases: - * if x is NaN, return x itself; - * if |x|>1, return NaN with invalid signal. - * - * Function needed: sqrt - */ - -#include "libm.h" - -static const double -pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ -pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ -pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ -pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ -pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ -pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ -pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ -pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ -qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ -qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ -qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ -qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ - -static double R(double z) -{ - double_t p, q; - p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); - q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4))); - return p/q; -} - -double acos(double x) -{ - double z,w,s,c,df; - uint32_t hx,ix; - - GET_HIGH_WORD(hx, x); - ix = hx & 0x7fffffff; - /* |x| >= 1 or nan */ - if (ix >= 0x3ff00000) { - uint32_t lx; - - GET_LOW_WORD(lx,x); - if ((ix-0x3ff00000 | lx) == 0) { - /* acos(1)=0, acos(-1)=pi */ - if (hx >> 31) - return 2*pio2_hi + 0x1p-120f; - return 0; - } - return 0/(x-x); - } - /* |x| < 0.5 */ - if (ix < 0x3fe00000) { - if (ix <= 0x3c600000) /* |x| < 2**-57 */ - return pio2_hi + 0x1p-120f; - return pio2_hi - (x - (pio2_lo-x*R(x*x))); - } - /* x < -0.5 */ - if (hx >> 31) { - z = (1.0+x)*0.5; - s = sqrt(z); - w = R(z)*s-pio2_lo; - return 2*(pio2_hi - (s+w)); - } - /* x > 0.5 */ - z = (1.0-x)*0.5; - s = sqrt(z); - df = s; - SET_LOW_WORD(df,0); - c = (z-df*df)/(s+df); - w = R(z)*s+c; - return 2*(df+w); -} diff --git a/waterbox/libc/functions/math/acosf.c b/waterbox/libc/functions/math/acosf.c deleted file mode 100644 index 8ee1a71d0c..0000000000 --- a/waterbox/libc/functions/math/acosf.c +++ /dev/null @@ -1,71 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_acosf.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" - -static const float -pio2_hi = 1.5707962513e+00, /* 0x3fc90fda */ -pio2_lo = 7.5497894159e-08, /* 0x33a22168 */ -pS0 = 1.6666586697e-01, -pS1 = -4.2743422091e-02, -pS2 = -8.6563630030e-03, -qS1 = -7.0662963390e-01; - -static float R(float z) -{ - float_t p, q; - p = z*(pS0+z*(pS1+z*pS2)); - q = 1.0f+z*qS1; - return p/q; -} - -float acosf(float x) -{ - float z,w,s,c,df; - uint32_t hx,ix; - - GET_FLOAT_WORD(hx, x); - ix = hx & 0x7fffffff; - /* |x| >= 1 or nan */ - if (ix >= 0x3f800000) { - if (ix == 0x3f800000) { - if (hx >> 31) - return 2*pio2_hi + 0x1p-120f; - return 0; - } - return 0/(x-x); - } - /* |x| < 0.5 */ - if (ix < 0x3f000000) { - if (ix <= 0x32800000) /* |x| < 2**-26 */ - return pio2_hi + 0x1p-120f; - return pio2_hi - (x - (pio2_lo-x*R(x*x))); - } - /* x < -0.5 */ - if (hx >> 31) { - z = (1+x)*0.5f; - s = sqrtf(z); - w = R(z)*s-pio2_lo; - return 2*(pio2_hi - (s+w)); - } - /* x > 0.5 */ - z = (1-x)*0.5f; - s = sqrtf(z); - GET_FLOAT_WORD(hx,s); - SET_FLOAT_WORD(df,hx&0xfffff000); - c = (z-df*df)/(s+df); - w = R(z)*s+c; - return 2*(df+w); -} diff --git a/waterbox/libc/functions/math/acosh.c b/waterbox/libc/functions/math/acosh.c deleted file mode 100644 index badbf9081e..0000000000 --- a/waterbox/libc/functions/math/acosh.c +++ /dev/null @@ -1,24 +0,0 @@ -#include "libm.h" - -#if FLT_EVAL_METHOD==2 -#undef sqrt -#define sqrt sqrtl -#endif - -/* acosh(x) = log(x + sqrt(x*x-1)) */ -double acosh(double x) -{ - union {double f; uint64_t i;} u = {.f = x}; - unsigned e = u.i >> 52 & 0x7ff; - - /* x < 1 domain error is handled in the called functions */ - - if (e < 0x3ff + 1) - /* |x| < 2, up to 2ulp error in [1,1.125] */ - return log1p(x-1 + sqrt((x-1)*(x-1)+2*(x-1))); - if (e < 0x3ff + 26) - /* |x| < 0x1p26 */ - return log(2*x - 1/(x+sqrt(x*x-1))); - /* |x| >= 0x1p26 or nan */ - return log(x) + 0.693147180559945309417232121458176568; -} diff --git a/waterbox/libc/functions/math/acoshf.c b/waterbox/libc/functions/math/acoshf.c deleted file mode 100644 index 8a4ec4d57e..0000000000 --- a/waterbox/libc/functions/math/acoshf.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "libm.h" - -#if FLT_EVAL_METHOD==2 -#undef sqrtf -#define sqrtf sqrtl -#elif FLT_EVAL_METHOD==1 -#undef sqrtf -#define sqrtf sqrt -#endif - -/* acosh(x) = log(x + sqrt(x*x-1)) */ -float acoshf(float x) -{ - union {float f; uint32_t i;} u = {x}; - uint32_t a = u.i & 0x7fffffff; - - if (a < 0x3f800000+(1<<23)) - /* |x| < 2, invalid if x < 1 or nan */ - /* up to 2ulp error in [1,1.125] */ - return log1pf(x-1 + sqrtf((x-1)*(x-1)+2*(x-1))); - if (a < 0x3f800000+(12<<23)) - /* |x| < 0x1p12 */ - return logf(2*x - 1/(x+sqrtf(x*x-1))); - /* x >= 0x1p12 */ - return logf(x) + 0.693147180559945309417232121458176568f; -} diff --git a/waterbox/libc/functions/math/acoshl.c b/waterbox/libc/functions/math/acoshl.c deleted file mode 100644 index 8d4b43f64c..0000000000 --- a/waterbox/libc/functions/math/acoshl.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double acoshl(long double x) -{ - return acosh(x); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -/* acosh(x) = log(x + sqrt(x*x-1)) */ -long double acoshl(long double x) -{ - union ldshape u = {x}; - int e = u.i.se & 0x7fff; - - if (e < 0x3fff + 1) - /* |x| < 2, invalid if x < 1 or nan */ - return log1pl(x-1 + sqrtl((x-1)*(x-1)+2*(x-1))); - if (e < 0x3fff + 32) - /* |x| < 0x1p32 */ - return logl(2*x - 1/(x+sqrtl(x*x-1))); - return logl(x) + 0.693147180559945309417232121458176568L; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -// TODO: broken implementation to make things compile -long double acoshl(long double x) -{ - return acosh(x); -} -#endif diff --git a/waterbox/libc/functions/math/acosl.c b/waterbox/libc/functions/math/acosl.c deleted file mode 100644 index c03bdf0235..0000000000 --- a/waterbox/libc/functions/math/acosl.c +++ /dev/null @@ -1,67 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_acosl.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* - * See comments in acos.c. - * Converted to long double by David Schultz . - */ - -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double acosl(long double x) -{ - return acos(x); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -#include "__invtrigl.h" -#if LDBL_MANT_DIG == 64 -#define CLEARBOTTOM(u) (u.i.m &= -1ULL << 32) -#elif LDBL_MANT_DIG == 113 -#define CLEARBOTTOM(u) (u.i.lo = 0) -#endif - -long double acosl(long double x) -{ - union ldshape u = {x}; - long double z, s, c, f; - uint16_t e = u.i.se & 0x7fff; - - /* |x| >= 1 or nan */ - if (e >= 0x3fff) { - if (x == 1) - return 0; - if (x == -1) - return 2*pio2_hi + 0x1p-120f; - return 0/(x-x); - } - /* |x| < 0.5 */ - if (e < 0x3fff - 1) { - if (e < 0x3fff - LDBL_MANT_DIG - 1) - return pio2_hi + 0x1p-120f; - return pio2_hi - (__invtrigl_R(x*x)*x - pio2_lo + x); - } - /* x < -0.5 */ - if (u.i.se >> 15) { - z = (1 + x)*0.5; - s = sqrtl(z); - return 2*(pio2_hi - (__invtrigl_R(z)*s - pio2_lo + s)); - } - /* x > 0.5 */ - z = (1 - x)*0.5; - s = sqrtl(z); - u.f = s; - CLEARBOTTOM(u); - f = u.f; - c = (z - f*f)/(s + f); - return 2*(__invtrigl_R(z)*s + c + f); -} -#endif diff --git a/waterbox/libc/functions/math/asin.c b/waterbox/libc/functions/math/asin.c deleted file mode 100644 index c926b18855..0000000000 --- a/waterbox/libc/functions/math/asin.c +++ /dev/null @@ -1,107 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_asin.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* asin(x) - * Method : - * Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ... - * we approximate asin(x) on [0,0.5] by - * asin(x) = x + x*x^2*R(x^2) - * where - * R(x^2) is a rational approximation of (asin(x)-x)/x^3 - * and its remez error is bounded by - * |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75) - * - * For x in [0.5,1] - * asin(x) = pi/2-2*asin(sqrt((1-x)/2)) - * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2; - * then for x>0.98 - * asin(x) = pi/2 - 2*(s+s*z*R(z)) - * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo) - * For x<=0.98, let pio4_hi = pio2_hi/2, then - * f = hi part of s; - * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z) - * and - * asin(x) = pi/2 - 2*(s+s*z*R(z)) - * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo) - * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c)) - * - * Special cases: - * if x is NaN, return x itself; - * if |x|>1, return NaN with invalid signal. - * - */ - -#include "libm.h" - -static const double -pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ -pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ -/* coefficients for R(x^2) */ -pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ -pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ -pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ -pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ -pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ -pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ -qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ -qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ -qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ -qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ - -static double R(double z) -{ - double_t p, q; - p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); - q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4))); - return p/q; -} - -double asin(double x) -{ - double z,r,s; - uint32_t hx,ix; - - GET_HIGH_WORD(hx, x); - ix = hx & 0x7fffffff; - /* |x| >= 1 or nan */ - if (ix >= 0x3ff00000) { - uint32_t lx; - GET_LOW_WORD(lx, x); - if ((ix-0x3ff00000 | lx) == 0) - /* asin(1) = +-pi/2 with inexact */ - return x*pio2_hi + 0x1p-120f; - return 0/(x-x); - } - /* |x| < 0.5 */ - if (ix < 0x3fe00000) { - /* if 0x1p-1022 <= |x| < 0x1p-26, avoid raising underflow */ - if (ix < 0x3e500000 && ix >= 0x00100000) - return x; - return x + x*R(x*x); - } - /* 1 > |x| >= 0.5 */ - z = (1 - fabs(x))*0.5; - s = sqrt(z); - r = R(z); - if (ix >= 0x3fef3333) { /* if |x| > 0.975 */ - x = pio2_hi-(2*(s+s*r)-pio2_lo); - } else { - double f,c; - /* f+c = sqrt(z) */ - f = s; - SET_LOW_WORD(f,0); - c = (z-f*f)/(s+f); - x = 0.5*pio2_hi - (2*s*r - (pio2_lo-2*c) - (0.5*pio2_hi-2*f)); - } - if (hx >> 31) - return -x; - return x; -} diff --git a/waterbox/libc/functions/math/asinf.c b/waterbox/libc/functions/math/asinf.c deleted file mode 100644 index bcd304a342..0000000000 --- a/waterbox/libc/functions/math/asinf.c +++ /dev/null @@ -1,61 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_asinf.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -#include "libm.h" - -static const double -pio2 = 1.570796326794896558e+00; - -static const float -/* coefficients for R(x^2) */ -pS0 = 1.6666586697e-01, -pS1 = -4.2743422091e-02, -pS2 = -8.6563630030e-03, -qS1 = -7.0662963390e-01; - -static float R(float z) -{ - float_t p, q; - p = z*(pS0+z*(pS1+z*pS2)); - q = 1.0f+z*qS1; - return p/q; -} - -float asinf(float x) -{ - double s; - float z; - uint32_t hx,ix; - - GET_FLOAT_WORD(hx, x); - ix = hx & 0x7fffffff; - if (ix >= 0x3f800000) { /* |x| >= 1 */ - if (ix == 0x3f800000) /* |x| == 1 */ - return x*pio2 + 0x1p-120f; /* asin(+-1) = +-pi/2 with inexact */ - return 0/(x-x); /* asin(|x|>1) is NaN */ - } - if (ix < 0x3f000000) { /* |x| < 0.5 */ - /* if 0x1p-126 <= |x| < 0x1p-12, avoid raising underflow */ - if (ix < 0x39800000 && ix >= 0x00800000) - return x; - return x + x*R(x*x); - } - /* 1 > |x| >= 0.5 */ - z = (1 - fabsf(x))*0.5f; - s = sqrt(z); - x = pio2 - 2*(s+s*R(z)); - if (hx >> 31) - return -x; - return x; -} diff --git a/waterbox/libc/functions/math/asinh.c b/waterbox/libc/functions/math/asinh.c deleted file mode 100644 index 0829f228ef..0000000000 --- a/waterbox/libc/functions/math/asinh.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "libm.h" - -/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */ -double asinh(double x) -{ - union {double f; uint64_t i;} u = {.f = x}; - unsigned e = u.i >> 52 & 0x7ff; - unsigned s = u.i >> 63; - - /* |x| */ - u.i &= (uint64_t)-1/2; - x = u.f; - - if (e >= 0x3ff + 26) { - /* |x| >= 0x1p26 or inf or nan */ - x = log(x) + 0.693147180559945309417232121458176568; - } else if (e >= 0x3ff + 1) { - /* |x| >= 2 */ - x = log(2*x + 1/(sqrt(x*x+1)+x)); - } else if (e >= 0x3ff - 26) { - /* |x| >= 0x1p-26, up to 1.6ulp error in [0.125,0.5] */ - x = log1p(x + x*x/(sqrt(x*x+1)+1)); - } else { - /* |x| < 0x1p-26, raise inexact if x != 0 */ - FORCE_EVAL(x + 0x1p120f); - } - return s ? -x : x; -} diff --git a/waterbox/libc/functions/math/asinhf.c b/waterbox/libc/functions/math/asinhf.c deleted file mode 100644 index fc9f0911bf..0000000000 --- a/waterbox/libc/functions/math/asinhf.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "libm.h" - -/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */ -float asinhf(float x) -{ - union {float f; uint32_t i;} u = {.f = x}; - uint32_t i = u.i & 0x7fffffff; - unsigned s = u.i >> 31; - - /* |x| */ - u.i = i; - x = u.f; - - if (i >= 0x3f800000 + (12<<23)) { - /* |x| >= 0x1p12 or inf or nan */ - x = logf(x) + 0.693147180559945309417232121458176568f; - } else if (i >= 0x3f800000 + (1<<23)) { - /* |x| >= 2 */ - x = logf(2*x + 1/(sqrtf(x*x+1)+x)); - } else if (i >= 0x3f800000 - (12<<23)) { - /* |x| >= 0x1p-12, up to 1.6ulp error in [0.125,0.5] */ - x = log1pf(x + x*x/(sqrtf(x*x+1)+1)); - } else { - /* |x| < 0x1p-12, raise inexact if x!=0 */ - FORCE_EVAL(x + 0x1p120f); - } - return s ? -x : x; -} diff --git a/waterbox/libc/functions/math/asinhl.c b/waterbox/libc/functions/math/asinhl.c deleted file mode 100644 index 8635f52e82..0000000000 --- a/waterbox/libc/functions/math/asinhl.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double asinhl(long double x) -{ - return asinh(x); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */ -long double asinhl(long double x) -{ - union ldshape u = {x}; - unsigned e = u.i.se & 0x7fff; - unsigned s = u.i.se >> 15; - - /* |x| */ - u.i.se = e; - x = u.f; - - if (e >= 0x3fff + 32) { - /* |x| >= 0x1p32 or inf or nan */ - x = logl(x) + 0.693147180559945309417232121458176568L; - } else if (e >= 0x3fff + 1) { - /* |x| >= 2 */ - x = logl(2*x + 1/(sqrtl(x*x+1)+x)); - } else if (e >= 0x3fff - 32) { - /* |x| >= 0x1p-32 */ - x = log1pl(x + x*x/(sqrtl(x*x+1)+1)); - } else { - /* |x| < 0x1p-32, raise inexact if x!=0 */ - FORCE_EVAL(x + 0x1p120f); - } - return s ? -x : x; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -// TODO: broken implementation to make things compile -long double asinhl(long double x) -{ - return asinh(x); -} -#endif diff --git a/waterbox/libc/functions/math/asinl.c b/waterbox/libc/functions/math/asinl.c deleted file mode 100644 index 347c53568c..0000000000 --- a/waterbox/libc/functions/math/asinl.c +++ /dev/null @@ -1,71 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_asinl.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* - * See comments in asin.c. - * Converted to long double by David Schultz . - */ - -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double asinl(long double x) -{ - return asin(x); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -#include "__invtrigl.h" -#if LDBL_MANT_DIG == 64 -#define CLOSETO1(u) (u.i.m>>56 >= 0xf7) -#define CLEARBOTTOM(u) (u.i.m &= -1ULL << 32) -#elif LDBL_MANT_DIG == 113 -#define CLOSETO1(u) (u.i.top >= 0xee00) -#define CLEARBOTTOM(u) (u.i.lo = 0) -#endif - -long double asinl(long double x) -{ - union ldshape u = {x}; - long double z, r, s; - uint16_t e = u.i.se & 0x7fff; - int sign = u.i.se >> 15; - - if (e >= 0x3fff) { /* |x| >= 1 or nan */ - /* asin(+-1)=+-pi/2 with inexact */ - if (x == 1 || x == -1) - return x*pio2_hi + 0x1p-120f; - return 0/(x-x); - } - if (e < 0x3fff - 1) { /* |x| < 0.5 */ - if (e < 0x3fff - (LDBL_MANT_DIG+1)/2) { - /* return x with inexact if x!=0 */ - FORCE_EVAL(x + 0x1p120f); - return x; - } - return x + x*__invtrigl_R(x*x); - } - /* 1 > |x| >= 0.5 */ - z = (1.0 - fabsl(x))*0.5; - s = sqrtl(z); - r = __invtrigl_R(z); - if (CLOSETO1(u)) { - x = pio2_hi - (2*(s+s*r)-pio2_lo); - } else { - long double f, c; - u.f = s; - CLEARBOTTOM(u); - f = u.f; - c = (z - f*f)/(s + f); - x = 0.5*pio2_hi-(2*s*r - (pio2_lo-2*c) - (0.5*pio2_hi-2*f)); - } - return sign ? -x : x; -} -#endif diff --git a/waterbox/libc/functions/math/atan.c b/waterbox/libc/functions/math/atan.c deleted file mode 100644 index 63b0ab25e3..0000000000 --- a/waterbox/libc/functions/math/atan.c +++ /dev/null @@ -1,116 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_atan.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* atan(x) - * Method - * 1. Reduce x to positive by atan(x) = -atan(-x). - * 2. According to the integer k=4t+0.25 chopped, t=x, the argument - * is further reduced to one of the following intervals and the - * arctangent of t is evaluated by the corresponding formula: - * - * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...) - * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) ) - * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) ) - * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) ) - * [39/16,INF] atan(x) = atan(INF) + atan( -1/t ) - * - * Constants: - * The hexadecimal values are the intended ones for the following - * constants. The decimal values may be used, provided that the - * compiler will convert from decimal to binary accurately enough - * to produce the hexadecimal values shown. - */ - - -#include "libm.h" - -static const double atanhi[] = { - 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */ - 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */ - 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */ - 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */ -}; - -static const double atanlo[] = { - 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */ - 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */ - 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */ - 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */ -}; - -static const double aT[] = { - 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */ - -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */ - 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */ - -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */ - 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */ - -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */ - 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */ - -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */ - 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */ - -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */ - 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */ -}; - -double atan(double x) -{ - double_t w,s1,s2,z; - uint32_t ix,sign; - int id; - - GET_HIGH_WORD(ix, x); - sign = ix >> 31; - ix &= 0x7fffffff; - if (ix >= 0x44100000) { /* if |x| >= 2^66 */ - if (isnan(x)) - return x; - z = atanhi[3] + 0x1p-120f; - return sign ? -z : z; - } - if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ - if (ix < 0x3e400000) { /* |x| < 2^-27 */ - if (ix < 0x00100000) - /* raise underflow for subnormal x */ - FORCE_EVAL((float)x); - return x; - } - id = -1; - } else { - x = fabs(x); - if (ix < 0x3ff30000) { /* |x| < 1.1875 */ - if (ix < 0x3fe60000) { /* 7/16 <= |x| < 11/16 */ - id = 0; - x = (2.0*x-1.0)/(2.0+x); - } else { /* 11/16 <= |x| < 19/16 */ - id = 1; - x = (x-1.0)/(x+1.0); - } - } else { - if (ix < 0x40038000) { /* |x| < 2.4375 */ - id = 2; - x = (x-1.5)/(1.0+1.5*x); - } else { /* 2.4375 <= |x| < 2^66 */ - id = 3; - x = -1.0/x; - } - } - } - /* end of argument reduction */ - z = x*x; - w = z*z; - /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ - s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10]))))); - s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9])))); - if (id < 0) - return x - x*(s1+s2); - z = atanhi[id] - (x*(s1+s2) - atanlo[id] - x); - return sign ? -z : z; -} diff --git a/waterbox/libc/functions/math/atan2.c b/waterbox/libc/functions/math/atan2.c deleted file mode 100644 index 5a1903c624..0000000000 --- a/waterbox/libc/functions/math/atan2.c +++ /dev/null @@ -1,107 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - * - */ -/* atan2(y,x) - * Method : - * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x). - * 2. Reduce x to positive by (if x and y are unexceptional): - * ARG (x+iy) = arctan(y/x) ... if x > 0, - * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0, - * - * Special cases: - * - * ATAN2((anything), NaN ) is NaN; - * ATAN2(NAN , (anything) ) is NaN; - * ATAN2(+-0, +(anything but NaN)) is +-0 ; - * ATAN2(+-0, -(anything but NaN)) is +-pi ; - * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2; - * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ; - * ATAN2(+-(anything but INF and NaN), -INF) is +-pi; - * ATAN2(+-INF,+INF ) is +-pi/4 ; - * ATAN2(+-INF,-INF ) is +-3pi/4; - * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2; - * - * Constants: - * The hexadecimal values are the intended ones for the following - * constants. The decimal values may be used, provided that the - * compiler will convert from decimal to binary accurately enough - * to produce the hexadecimal values shown. - */ - -#include "libm.h" - -static const double -pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */ -pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ - -double atan2(double y, double x) -{ - double z; - uint32_t m,lx,ly,ix,iy; - - if (isnan(x) || isnan(y)) - return x+y; - EXTRACT_WORDS(ix, lx, x); - EXTRACT_WORDS(iy, ly, y); - if ((ix-0x3ff00000 | lx) == 0) /* x = 1.0 */ - return atan(y); - m = ((iy>>31)&1) | ((ix>>30)&2); /* 2*sign(x)+sign(y) */ - ix = ix & 0x7fffffff; - iy = iy & 0x7fffffff; - - /* when y = 0 */ - if ((iy|ly) == 0) { - switch(m) { - case 0: - case 1: return y; /* atan(+-0,+anything)=+-0 */ - case 2: return pi; /* atan(+0,-anything) = pi */ - case 3: return -pi; /* atan(-0,-anything) =-pi */ - } - } - /* when x = 0 */ - if ((ix|lx) == 0) - return m&1 ? -pi/2 : pi/2; - /* when x is INF */ - if (ix == 0x7ff00000) { - if (iy == 0x7ff00000) { - switch(m) { - case 0: return pi/4; /* atan(+INF,+INF) */ - case 1: return -pi/4; /* atan(-INF,+INF) */ - case 2: return 3*pi/4; /* atan(+INF,-INF) */ - case 3: return -3*pi/4; /* atan(-INF,-INF) */ - } - } else { - switch(m) { - case 0: return 0.0; /* atan(+...,+INF) */ - case 1: return -0.0; /* atan(-...,+INF) */ - case 2: return pi; /* atan(+...,-INF) */ - case 3: return -pi; /* atan(-...,-INF) */ - } - } - } - /* |y/x| > 0x1p64 */ - if (ix+(64<<20) < iy || iy == 0x7ff00000) - return m&1 ? -pi/2 : pi/2; - - /* z = atan(|y/x|) without spurious underflow */ - if ((m&2) && iy+(64<<20) < ix) /* |y/x| < 0x1p-64, x<0 */ - z = 0; - else - z = atan(fabs(y/x)); - switch (m) { - case 0: return z; /* atan(+,+) */ - case 1: return -z; /* atan(-,+) */ - case 2: return pi - (z-pi_lo); /* atan(+,-) */ - default: /* case 3 */ - return (z-pi_lo) - pi; /* atan(-,-) */ - } -} diff --git a/waterbox/libc/functions/math/atan2f.c b/waterbox/libc/functions/math/atan2f.c deleted file mode 100644 index c634d00fc9..0000000000 --- a/waterbox/libc/functions/math/atan2f.c +++ /dev/null @@ -1,83 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2f.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" - -static const float -pi = 3.1415927410e+00, /* 0x40490fdb */ -pi_lo = -8.7422776573e-08; /* 0xb3bbbd2e */ - -float atan2f(float y, float x) -{ - float z; - uint32_t m,ix,iy; - - if (isnan(x) || isnan(y)) - return x+y; - GET_FLOAT_WORD(ix, x); - GET_FLOAT_WORD(iy, y); - if (ix == 0x3f800000) /* x=1.0 */ - return atanf(y); - m = ((iy>>31)&1) | ((ix>>30)&2); /* 2*sign(x)+sign(y) */ - ix &= 0x7fffffff; - iy &= 0x7fffffff; - - /* when y = 0 */ - if (iy == 0) { - switch (m) { - case 0: - case 1: return y; /* atan(+-0,+anything)=+-0 */ - case 2: return pi; /* atan(+0,-anything) = pi */ - case 3: return -pi; /* atan(-0,-anything) =-pi */ - } - } - /* when x = 0 */ - if (ix == 0) - return m&1 ? -pi/2 : pi/2; - /* when x is INF */ - if (ix == 0x7f800000) { - if (iy == 0x7f800000) { - switch (m) { - case 0: return pi/4; /* atan(+INF,+INF) */ - case 1: return -pi/4; /* atan(-INF,+INF) */ - case 2: return 3*pi/4; /*atan(+INF,-INF)*/ - case 3: return -3*pi/4; /*atan(-INF,-INF)*/ - } - } else { - switch (m) { - case 0: return 0.0f; /* atan(+...,+INF) */ - case 1: return -0.0f; /* atan(-...,+INF) */ - case 2: return pi; /* atan(+...,-INF) */ - case 3: return -pi; /* atan(-...,-INF) */ - } - } - } - /* |y/x| > 0x1p26 */ - if (ix+(26<<23) < iy || iy == 0x7f800000) - return m&1 ? -pi/2 : pi/2; - - /* z = atan(|y/x|) with correct underflow */ - if ((m&2) && iy+(26<<23) < ix) /*|y/x| < 0x1p-26, x < 0 */ - z = 0.0; - else - z = atanf(fabsf(y/x)); - switch (m) { - case 0: return z; /* atan(+,+) */ - case 1: return -z; /* atan(-,+) */ - case 2: return pi - (z-pi_lo); /* atan(+,-) */ - default: /* case 3 */ - return (z-pi_lo) - pi; /* atan(-,-) */ - } -} diff --git a/waterbox/libc/functions/math/atan2l.c b/waterbox/libc/functions/math/atan2l.c deleted file mode 100644 index f0937a9794..0000000000 --- a/waterbox/libc/functions/math/atan2l.c +++ /dev/null @@ -1,85 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2l.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - * - */ -/* - * See comments in atan2.c. - * Converted to long double by David Schultz . - */ - -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double atan2l(long double y, long double x) -{ - return atan2(y, x); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -#include "__invtrigl.h" - -long double atan2l(long double y, long double x) -{ - union ldshape ux, uy; - long double z; - int m, ex, ey; - - if (isnan(x) || isnan(y)) - return x+y; - if (x == 1) - return atanl(y); - ux.f = x; - uy.f = y; - ex = ux.i.se & 0x7fff; - ey = uy.i.se & 0x7fff; - m = 2*(ux.i.se>>15) | uy.i.se>>15; - if (y == 0) { - switch(m) { - case 0: - case 1: return y; /* atan(+-0,+anything)=+-0 */ - case 2: return 2*pio2_hi; /* atan(+0,-anything) = pi */ - case 3: return -2*pio2_hi; /* atan(-0,-anything) =-pi */ - } - } - if (x == 0) - return m&1 ? -pio2_hi : pio2_hi; - if (ex == 0x7fff) { - if (ey == 0x7fff) { - switch(m) { - case 0: return pio2_hi/2; /* atan(+INF,+INF) */ - case 1: return -pio2_hi/2; /* atan(-INF,+INF) */ - case 2: return 1.5*pio2_hi; /* atan(+INF,-INF) */ - case 3: return -1.5*pio2_hi; /* atan(-INF,-INF) */ - } - } else { - switch(m) { - case 0: return 0.0; /* atan(+...,+INF) */ - case 1: return -0.0; /* atan(-...,+INF) */ - case 2: return 2*pio2_hi; /* atan(+...,-INF) */ - case 3: return -2*pio2_hi; /* atan(-...,-INF) */ - } - } - } - if (ex+120 < ey || ey == 0x7fff) - return m&1 ? -pio2_hi : pio2_hi; - /* z = atan(|y/x|) without spurious underflow */ - if ((m&2) && ey+120 < ex) /* |y/x| < 0x1p-120, x<0 */ - z = 0.0; - else - z = atanl(fabsl(y/x)); - switch (m) { - case 0: return z; /* atan(+,+) */ - case 1: return -z; /* atan(-,+) */ - case 2: return 2*pio2_hi-(z-2*pio2_lo); /* atan(+,-) */ - default: /* case 3 */ - return (z-2*pio2_lo)-2*pio2_hi; /* atan(-,-) */ - } -} -#endif diff --git a/waterbox/libc/functions/math/atanf.c b/waterbox/libc/functions/math/atanf.c deleted file mode 100644 index 178341b670..0000000000 --- a/waterbox/libc/functions/math/atanf.c +++ /dev/null @@ -1,94 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_atanf.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - - -#include "libm.h" - -static const float atanhi[] = { - 4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */ - 7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */ - 9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */ - 1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */ -}; - -static const float atanlo[] = { - 5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */ - 3.7748947079e-08, /* atan(1.0)lo 0x33222168 */ - 3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */ - 7.5497894159e-08, /* atan(inf)lo 0x33a22168 */ -}; - -static const float aT[] = { - 3.3333328366e-01, - -1.9999158382e-01, - 1.4253635705e-01, - -1.0648017377e-01, - 6.1687607318e-02, -}; - -float atanf(float x) -{ - float_t w,s1,s2,z; - uint32_t ix,sign; - int id; - - GET_FLOAT_WORD(ix, x); - sign = ix>>31; - ix &= 0x7fffffff; - if (ix >= 0x4c800000) { /* if |x| >= 2**26 */ - if (isnan(x)) - return x; - z = atanhi[3] + 0x1p-120f; - return sign ? -z : z; - } - if (ix < 0x3ee00000) { /* |x| < 0.4375 */ - if (ix < 0x39800000) { /* |x| < 2**-12 */ - if (ix < 0x00800000) - /* raise underflow for subnormal x */ - FORCE_EVAL(x*x); - return x; - } - id = -1; - } else { - x = fabsf(x); - if (ix < 0x3f980000) { /* |x| < 1.1875 */ - if (ix < 0x3f300000) { /* 7/16 <= |x| < 11/16 */ - id = 0; - x = (2.0f*x - 1.0f)/(2.0f + x); - } else { /* 11/16 <= |x| < 19/16 */ - id = 1; - x = (x - 1.0f)/(x + 1.0f); - } - } else { - if (ix < 0x401c0000) { /* |x| < 2.4375 */ - id = 2; - x = (x - 1.5f)/(1.0f + 1.5f*x); - } else { /* 2.4375 <= |x| < 2**26 */ - id = 3; - x = -1.0f/x; - } - } - } - /* end of argument reduction */ - z = x*x; - w = z*z; - /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ - s1 = z*(aT[0]+w*(aT[2]+w*aT[4])); - s2 = w*(aT[1]+w*aT[3]); - if (id < 0) - return x - x*(s1+s2); - z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); - return sign ? -z : z; -} diff --git a/waterbox/libc/functions/math/atanh.c b/waterbox/libc/functions/math/atanh.c deleted file mode 100644 index 63a035d706..0000000000 --- a/waterbox/libc/functions/math/atanh.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "libm.h" - -/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */ -double atanh(double x) -{ - union {double f; uint64_t i;} u = {.f = x}; - unsigned e = u.i >> 52 & 0x7ff; - unsigned s = u.i >> 63; - double_t y; - - /* |x| */ - u.i &= (uint64_t)-1/2; - y = u.f; - - if (e < 0x3ff - 1) { - if (e < 0x3ff - 32) { - /* handle underflow */ - if (e == 0) - FORCE_EVAL((float)y); - } else { - /* |x| < 0.5, up to 1.7ulp error */ - y = 0.5*log1p(2*y + 2*y*y/(1-y)); - } - } else { - /* avoid overflow */ - y = 0.5*log1p(2*(y/(1-y))); - } - return s ? -y : y; -} diff --git a/waterbox/libc/functions/math/atanhf.c b/waterbox/libc/functions/math/atanhf.c deleted file mode 100644 index 65f07c0f4f..0000000000 --- a/waterbox/libc/functions/math/atanhf.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "libm.h" - -/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */ -float atanhf(float x) -{ - union {float f; uint32_t i;} u = {.f = x}; - unsigned s = u.i >> 31; - float_t y; - - /* |x| */ - u.i &= 0x7fffffff; - y = u.f; - - if (u.i < 0x3f800000 - (1<<23)) { - if (u.i < 0x3f800000 - (32<<23)) { - /* handle underflow */ - if (u.i < (1<<23)) - FORCE_EVAL((float)(y*y)); - } else { - /* |x| < 0.5, up to 1.7ulp error */ - y = 0.5f*log1pf(2*y + 2*y*y/(1-y)); - } - } else { - /* avoid overflow */ - y = 0.5f*log1pf(2*(y/(1-y))); - } - return s ? -y : y; -} diff --git a/waterbox/libc/functions/math/atanhl.c b/waterbox/libc/functions/math/atanhl.c deleted file mode 100644 index 87cd1cdb5f..0000000000 --- a/waterbox/libc/functions/math/atanhl.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double atanhl(long double x) -{ - return atanh(x); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */ -long double atanhl(long double x) -{ - union ldshape u = {x}; - unsigned e = u.i.se & 0x7fff; - unsigned s = u.i.se >> 15; - - /* |x| */ - u.i.se = e; - x = u.f; - - if (e < 0x3ff - 1) { - if (e < 0x3ff - LDBL_MANT_DIG/2) { - /* handle underflow */ - if (e == 0) - FORCE_EVAL((float)x); - } else { - /* |x| < 0.5, up to 1.7ulp error */ - x = 0.5*log1pl(2*x + 2*x*x/(1-x)); - } - } else { - /* avoid overflow */ - x = 0.5*log1pl(2*(x/(1-x))); - } - return s ? -x : x; -} -#endif diff --git a/waterbox/libc/functions/math/atanl.c b/waterbox/libc/functions/math/atanl.c deleted file mode 100644 index 79a3edb805..0000000000 --- a/waterbox/libc/functions/math/atanl.c +++ /dev/null @@ -1,184 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_atanl.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* - * See comments in atan.c. - * Converted to long double by David Schultz . - */ - -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double atanl(long double x) -{ - return atan(x); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 - -#if LDBL_MANT_DIG == 64 -#define EXPMAN(u) ((u.i.se & 0x7fff)<<8 | (u.i.m>>55 & 0xff)) - -static const long double atanhi[] = { - 4.63647609000806116202e-01L, - 7.85398163397448309628e-01L, - 9.82793723247329067960e-01L, - 1.57079632679489661926e+00L, -}; - -static const long double atanlo[] = { - 1.18469937025062860669e-20L, - -1.25413940316708300586e-20L, - 2.55232234165405176172e-20L, - -2.50827880633416601173e-20L, -}; - -static const long double aT[] = { - 3.33333333333333333017e-01L, - -1.99999999999999632011e-01L, - 1.42857142857046531280e-01L, - -1.11111111100562372733e-01L, - 9.09090902935647302252e-02L, - -7.69230552476207730353e-02L, - 6.66661718042406260546e-02L, - -5.88158892835030888692e-02L, - 5.25499891539726639379e-02L, - -4.70119845393155721494e-02L, - 4.03539201366454414072e-02L, - -2.91303858419364158725e-02L, - 1.24822046299269234080e-02L, -}; - -static long double T_even(long double x) -{ - return aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] + - x * (aT[8] + x * (aT[10] + x * aT[12]))))); -} - -static long double T_odd(long double x) -{ - return aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] + - x * (aT[9] + x * aT[11])))); -} -#elif LDBL_MANT_DIG == 113 -#define EXPMAN(u) ((u.i.se & 0x7fff)<<8 | u.i.top>>8) - -const long double atanhi[] = { - 4.63647609000806116214256231461214397e-01L, - 7.85398163397448309615660845819875699e-01L, - 9.82793723247329067985710611014666038e-01L, - 1.57079632679489661923132169163975140e+00L, -}; - -const long double atanlo[] = { - 4.89509642257333492668618435220297706e-36L, - 2.16795253253094525619926100651083806e-35L, - -2.31288434538183565909319952098066272e-35L, - 4.33590506506189051239852201302167613e-35L, -}; - -const long double aT[] = { - 3.33333333333333333333333333333333125e-01L, - -1.99999999999999999999999999999180430e-01L, - 1.42857142857142857142857142125269827e-01L, - -1.11111111111111111111110834490810169e-01L, - 9.09090909090909090908522355708623681e-02L, - -7.69230769230769230696553844935357021e-02L, - 6.66666666666666660390096773046256096e-02L, - -5.88235294117646671706582985209643694e-02L, - 5.26315789473666478515847092020327506e-02L, - -4.76190476189855517021024424991436144e-02L, - 4.34782608678695085948531993458097026e-02L, - -3.99999999632663469330634215991142368e-02L, - 3.70370363987423702891250829918659723e-02L, - -3.44827496515048090726669907612335954e-02L, - 3.22579620681420149871973710852268528e-02L, - -3.03020767654269261041647570626778067e-02L, - 2.85641979882534783223403715930946138e-02L, - -2.69824879726738568189929461383741323e-02L, - 2.54194698498808542954187110873675769e-02L, - -2.35083879708189059926183138130183215e-02L, - 2.04832358998165364349957325067131428e-02L, - -1.54489555488544397858507248612362957e-02L, - 8.64492360989278761493037861575248038e-03L, - -2.58521121597609872727919154569765469e-03L, -}; - -static long double T_even(long double x) -{ - return (aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] + x * (aT[8] + - x * (aT[10] + x * (aT[12] + x * (aT[14] + x * (aT[16] + - x * (aT[18] + x * (aT[20] + x * aT[22]))))))))))); -} - -static long double T_odd(long double x) -{ - return (aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] + x * (aT[9] + - x * (aT[11] + x * (aT[13] + x * (aT[15] + x * (aT[17] + - x * (aT[19] + x * (aT[21] + x * aT[23]))))))))))); -} -#endif - -long double atanl(long double x) -{ - union ldshape u = {x}; - long double w, s1, s2, z; - int id; - unsigned e = u.i.se & 0x7fff; - unsigned sign = u.i.se >> 15; - unsigned expman; - - if (e >= 0x3fff + LDBL_MANT_DIG + 1) { /* if |x| is large, atan(x)~=pi/2 */ - if (isnan(x)) - return x; - return sign ? -atanhi[3] : atanhi[3]; - } - /* Extract the exponent and the first few bits of the mantissa. */ - expman = EXPMAN(u); - if (expman < ((0x3fff - 2) << 8) + 0xc0) { /* |x| < 0.4375 */ - if (e < 0x3fff - (LDBL_MANT_DIG+1)/2) { /* if |x| is small, atanl(x)~=x */ - /* raise underflow if subnormal */ - if (e == 0) - FORCE_EVAL((float)x); - return x; - } - id = -1; - } else { - x = fabsl(x); - if (expman < (0x3fff << 8) + 0x30) { /* |x| < 1.1875 */ - if (expman < ((0x3fff - 1) << 8) + 0x60) { /* 7/16 <= |x| < 11/16 */ - id = 0; - x = (2.0*x-1.0)/(2.0+x); - } else { /* 11/16 <= |x| < 19/16 */ - id = 1; - x = (x-1.0)/(x+1.0); - } - } else { - if (expman < ((0x3fff + 1) << 8) + 0x38) { /* |x| < 2.4375 */ - id = 2; - x = (x-1.5)/(1.0+1.5*x); - } else { /* 2.4375 <= |x| */ - id = 3; - x = -1.0/x; - } - } - } - /* end of argument reduction */ - z = x*x; - w = z*z; - /* break sum aT[i]z**(i+1) into odd and even poly */ - s1 = z*T_even(w); - s2 = w*T_odd(w); - if (id < 0) - return x - x*(s1+s2); - z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); - return sign ? -z : z; -} -#endif diff --git a/waterbox/libc/functions/math/cbrt.c b/waterbox/libc/functions/math/cbrt.c deleted file mode 100644 index 7599d3e37d..0000000000 --- a/waterbox/libc/functions/math/cbrt.c +++ /dev/null @@ -1,103 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrt.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - * - * Optimized by Bruce D. Evans. - */ -/* cbrt(x) - * Return cube root of x - */ - -#include -#include - -static const uint32_t -B1 = 715094163, /* B1 = (1023-1023/3-0.03306235651)*2**20 */ -B2 = 696219795; /* B2 = (1023-1023/3-54/3-0.03306235651)*2**20 */ - -/* |1/cbrt(x) - p(x)| < 2**-23.5 (~[-7.93e-8, 7.929e-8]). */ -static const double -P0 = 1.87595182427177009643, /* 0x3ffe03e6, 0x0f61e692 */ -P1 = -1.88497979543377169875, /* 0xbffe28e0, 0x92f02420 */ -P2 = 1.621429720105354466140, /* 0x3ff9f160, 0x4a49d6c2 */ -P3 = -0.758397934778766047437, /* 0xbfe844cb, 0xbee751d9 */ -P4 = 0.145996192886612446982; /* 0x3fc2b000, 0xd4e4edd7 */ - -double cbrt(double x) -{ - union {double f; uint64_t i;} u = {x}; - double_t r,s,t,w; - uint32_t hx = u.i>>32 & 0x7fffffff; - - if (hx >= 0x7ff00000) /* cbrt(NaN,INF) is itself */ - return x+x; - - /* - * Rough cbrt to 5 bits: - * cbrt(2**e*(1+m) ~= 2**(e/3)*(1+(e%3+m)/3) - * where e is integral and >= 0, m is real and in [0, 1), and "/" and - * "%" are integer division and modulus with rounding towards minus - * infinity. The RHS is always >= the LHS and has a maximum relative - * error of about 1 in 16. Adding a bias of -0.03306235651 to the - * (e%3+m)/3 term reduces the error to about 1 in 32. With the IEEE - * floating point representation, for finite positive normal values, - * ordinary integer divison of the value in bits magically gives - * almost exactly the RHS of the above provided we first subtract the - * exponent bias (1023 for doubles) and later add it back. We do the - * subtraction virtually to keep e >= 0 so that ordinary integer - * division rounds towards minus infinity; this is also efficient. - */ - if (hx < 0x00100000) { /* zero or subnormal? */ - u.f = x*0x1p54; - hx = u.i>>32 & 0x7fffffff; - if (hx == 0) - return x; /* cbrt(0) is itself */ - hx = hx/3 + B2; - } else - hx = hx/3 + B1; - u.i &= 1ULL<<63; - u.i |= (uint64_t)hx << 32; - t = u.f; - - /* - * New cbrt to 23 bits: - * cbrt(x) = t*cbrt(x/t**3) ~= t*P(t**3/x) - * where P(r) is a polynomial of degree 4 that approximates 1/cbrt(r) - * to within 2**-23.5 when |r - 1| < 1/10. The rough approximation - * has produced t such than |t/cbrt(x) - 1| ~< 1/32, and cubing this - * gives us bounds for r = t**3/x. - * - * Try to optimize for parallel evaluation as in __tanf.c. - */ - r = (t*t)*(t/x); - t = t*((P0+r*(P1+r*P2))+((r*r)*r)*(P3+r*P4)); - - /* - * Round t away from zero to 23 bits (sloppily except for ensuring that - * the result is larger in magnitude than cbrt(x) but not much more than - * 2 23-bit ulps larger). With rounding towards zero, the error bound - * would be ~5/6 instead of ~4/6. With a maximum error of 2 23-bit ulps - * in the rounded t, the infinite-precision error in the Newton - * approximation barely affects third digit in the final error - * 0.667; the error in the rounded t can be up to about 3 23-bit ulps - * before the final error is larger than 0.667 ulps. - */ - u.f = t; - u.i = (u.i + 0x80000000) & 0xffffffffc0000000ULL; - t = u.f; - - /* one step Newton iteration to 53 bits with error < 0.667 ulps */ - s = t*t; /* t*t is exact */ - r = x/s; /* error <= 0.5 ulps; |r| < |t| */ - w = t+t; /* t+t is exact */ - r = (r-t)/(w+r); /* r-t is exact; w+r ~= 3*t */ - t = t+t*r; /* error <= 0.5 + 0.5/3 + epsilon */ - return t; -} diff --git a/waterbox/libc/functions/math/cbrtf.c b/waterbox/libc/functions/math/cbrtf.c deleted file mode 100644 index 89c2c8655d..0000000000 --- a/waterbox/libc/functions/math/cbrtf.c +++ /dev/null @@ -1,66 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrtf.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - * Debugged and optimized by Bruce D. Evans. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* cbrtf(x) - * Return cube root of x - */ - -#include -#include - -static const unsigned -B1 = 709958130, /* B1 = (127-127.0/3-0.03306235651)*2**23 */ -B2 = 642849266; /* B2 = (127-127.0/3-24/3-0.03306235651)*2**23 */ - -float cbrtf(float x) -{ - double_t r,T; - union {float f; uint32_t i;} u = {x}; - uint32_t hx = u.i & 0x7fffffff; - - if (hx >= 0x7f800000) /* cbrt(NaN,INF) is itself */ - return x + x; - - /* rough cbrt to 5 bits */ - if (hx < 0x00800000) { /* zero or subnormal? */ - if (hx == 0) - return x; /* cbrt(+-0) is itself */ - u.f = x*0x1p24f; - hx = u.i & 0x7fffffff; - hx = hx/3 + B2; - } else - hx = hx/3 + B1; - u.i &= 0x80000000; - u.i |= hx; - - /* - * First step Newton iteration (solving t*t-x/t == 0) to 16 bits. In - * double precision so that its terms can be arranged for efficiency - * without causing overflow or underflow. - */ - T = u.f; - r = T*T*T; - T = T*((double_t)x+x+r)/(x+r+r); - - /* - * Second step Newton iteration to 47 bits. In double precision for - * efficiency and accuracy. - */ - r = T*T*T; - T = T*((double_t)x+x+r)/(x+r+r); - - /* rounding to 24 bits is perfect in round-to-nearest mode */ - return T; -} diff --git a/waterbox/libc/functions/math/cbrtl.c b/waterbox/libc/functions/math/cbrtl.c deleted file mode 100644 index ceff9136eb..0000000000 --- a/waterbox/libc/functions/math/cbrtl.c +++ /dev/null @@ -1,124 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrtl.c */ -/*- - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * Copyright (c) 2009-2011, Bruce D. Evans, Steven G. Kargl, David Schultz. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - * - * The argument reduction and testing for exceptional cases was - * written by Steven G. Kargl with input from Bruce D. Evans - * and David A. Schultz. - */ - -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double cbrtl(long double x) -{ - return cbrt(x); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -static const unsigned B1 = 709958130; /* B1 = (127-127.0/3-0.03306235651)*2**23 */ - -long double cbrtl(long double x) -{ - union ldshape u = {x}, v; - union {float f; uint32_t i;} uft; - long double r, s, t, w; - double_t dr, dt, dx; - float_t ft; - int e = u.i.se & 0x7fff; - int sign = u.i.se & 0x8000; - - /* - * If x = +-Inf, then cbrt(x) = +-Inf. - * If x = NaN, then cbrt(x) = NaN. - */ - if (e == 0x7fff) - return x + x; - if (e == 0) { - /* Adjust subnormal numbers. */ - u.f *= 0x1p120; - e = u.i.se & 0x7fff; - /* If x = +-0, then cbrt(x) = +-0. */ - if (e == 0) - return x; - e -= 120; - } - e -= 0x3fff; - u.i.se = 0x3fff; - x = u.f; - switch (e % 3) { - case 1: - case -2: - x *= 2; - e--; - break; - case 2: - case -1: - x *= 4; - e -= 2; - break; - } - v.f = 1.0; - v.i.se = sign | (0x3fff + e/3); - - /* - * The following is the guts of s_cbrtf, with the handling of - * special values removed and extra care for accuracy not taken, - * but with most of the extra accuracy not discarded. - */ - - /* ~5-bit estimate: */ - uft.f = x; - uft.i = (uft.i & 0x7fffffff)/3 + B1; - ft = uft.f; - - /* ~16-bit estimate: */ - dx = x; - dt = ft; - dr = dt * dt * dt; - dt = dt * (dx + dx + dr) / (dx + dr + dr); - - /* ~47-bit estimate: */ - dr = dt * dt * dt; - dt = dt * (dx + dx + dr) / (dx + dr + dr); - -#if LDBL_MANT_DIG == 64 - /* - * dt is cbrtl(x) to ~47 bits (after x has been reduced to 1 <= x < 8). - * Round it away from zero to 32 bits (32 so that t*t is exact, and - * away from zero for technical reasons). - */ - t = dt + (0x1.0p32L + 0x1.0p-31L) - 0x1.0p32; -#elif LDBL_MANT_DIG == 113 - /* - * Round dt away from zero to 47 bits. Since we don't trust the 47, - * add 2 47-bit ulps instead of 1 to round up. Rounding is slow and - * might be avoidable in this case, since on most machines dt will - * have been evaluated in 53-bit precision and the technical reasons - * for rounding up might not apply to either case in cbrtl() since - * dt is much more accurate than needed. - */ - t = dt + 0x2.0p-46 + 0x1.0p60L - 0x1.0p60; -#endif - - /* - * Final step Newton iteration to 64 or 113 bits with - * error < 0.667 ulps - */ - s = t*t; /* t*t is exact */ - r = x/s; /* error <= 0.5 ulps; |r| < |t| */ - w = t+t; /* t+t is exact */ - r = (r-t)/(w+r); /* r-t is exact; w+r ~= 3*t */ - t = t+t*r; /* error <= 0.5 + 0.5/3 + epsilon */ - - t *= v.f; - return t; -} -#endif diff --git a/waterbox/libc/functions/math/ceil.c b/waterbox/libc/functions/math/ceil.c deleted file mode 100644 index b13e6f2d63..0000000000 --- a/waterbox/libc/functions/math/ceil.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "libm.h" - -#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 -#define EPS DBL_EPSILON -#elif FLT_EVAL_METHOD==2 -#define EPS LDBL_EPSILON -#endif -static const double_t toint = 1/EPS; - -double ceil(double x) -{ - union {double f; uint64_t i;} u = {x}; - int e = u.i >> 52 & 0x7ff; - double_t y; - - if (e >= 0x3ff+52 || x == 0) - return x; - /* y = int(x) - x, where int(x) is an integer neighbor of x */ - if (u.i >> 63) - y = x - toint + toint - x; - else - y = x + toint - toint - x; - /* special case because of non-nearest rounding modes */ - if (e <= 0x3ff-1) { - FORCE_EVAL(y); - return u.i >> 63 ? -0.0 : 1; - } - if (y < 0) - return x + y + 1; - return x + y; -} diff --git a/waterbox/libc/functions/math/ceilf.c b/waterbox/libc/functions/math/ceilf.c deleted file mode 100644 index 869835f397..0000000000 --- a/waterbox/libc/functions/math/ceilf.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "libm.h" - -float ceilf(float x) -{ - union {float f; uint32_t i;} u = {x}; - int e = (int)(u.i >> 23 & 0xff) - 0x7f; - uint32_t m; - - if (e >= 23) - return x; - if (e >= 0) { - m = 0x007fffff >> e; - if ((u.i & m) == 0) - return x; - FORCE_EVAL(x + 0x1p120f); - if (u.i >> 31 == 0) - u.i += m; - u.i &= ~m; - } else { - FORCE_EVAL(x + 0x1p120f); - if (u.i >> 31) - u.f = -0.0; - else if (u.i << 1) - u.f = 1.0; - } - return u.f; -} diff --git a/waterbox/libc/functions/math/ceill.c b/waterbox/libc/functions/math/ceill.c deleted file mode 100644 index 60a83020dd..0000000000 --- a/waterbox/libc/functions/math/ceill.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double ceill(long double x) -{ - return ceil(x); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 - -static const long double toint = 1/LDBL_EPSILON; - -long double ceill(long double x) -{ - union ldshape u = {x}; - int e = u.i.se & 0x7fff; - long double y; - - if (e >= 0x3fff+LDBL_MANT_DIG-1 || x == 0) - return x; - /* y = int(x) - x, where int(x) is an integer neighbor of x */ - if (u.i.se >> 15) - y = x - toint + toint - x; - else - y = x + toint - toint - x; - /* special case because of non-nearest rounding modes */ - if (e <= 0x3fff-1) { - FORCE_EVAL(y); - return u.i.se >> 15 ? -0.0 : 1; - } - if (y < 0) - return x + y + 1; - return x + y; -} -#endif diff --git a/waterbox/libc/functions/math/copysign.c b/waterbox/libc/functions/math/copysign.c deleted file mode 100644 index b09331b687..0000000000 --- a/waterbox/libc/functions/math/copysign.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "libm.h" - -double copysign(double x, double y) { - union {double f; uint64_t i;} ux={x}, uy={y}; - ux.i &= -1ULL/2; - ux.i |= uy.i & 1ULL<<63; - return ux.f; -} diff --git a/waterbox/libc/functions/math/copysignf.c b/waterbox/libc/functions/math/copysignf.c deleted file mode 100644 index 0af6ae9b21..0000000000 --- a/waterbox/libc/functions/math/copysignf.c +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include - -float copysignf(float x, float y) -{ - union {float f; uint32_t i;} ux={x}, uy={y}; - ux.i &= 0x7fffffff; - ux.i |= uy.i & 0x80000000; - return ux.f; -} diff --git a/waterbox/libc/functions/math/copysignl.c b/waterbox/libc/functions/math/copysignl.c deleted file mode 100644 index 9dd933cfa9..0000000000 --- a/waterbox/libc/functions/math/copysignl.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double copysignl(long double x, long double y) -{ - return copysign(x, y); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -long double copysignl(long double x, long double y) -{ - union ldshape ux = {x}, uy = {y}; - ux.i.se &= 0x7fff; - ux.i.se |= uy.i.se & 0x8000; - return ux.f; -} -#endif diff --git a/waterbox/libc/functions/math/cos.c b/waterbox/libc/functions/math/cos.c deleted file mode 100644 index ee97f68bbb..0000000000 --- a/waterbox/libc/functions/math/cos.c +++ /dev/null @@ -1,77 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_cos.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* cos(x) - * Return cosine function of x. - * - * kernel function: - * __sin ... sine function on [-pi/4,pi/4] - * __cos ... cosine function on [-pi/4,pi/4] - * __rem_pio2 ... argument reduction routine - * - * Method. - * Let S,C and T denote the sin, cos and tan respectively on - * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 - * in [-pi/4 , +pi/4], and let n = k mod 4. - * We have - * - * n sin(x) cos(x) tan(x) - * ---------------------------------------------------------- - * 0 S C T - * 1 C -S -1/T - * 2 -S -C T - * 3 -C S -1/T - * ---------------------------------------------------------- - * - * Special cases: - * Let trig be any of sin, cos, or tan. - * trig(+-INF) is NaN, with signals; - * trig(NaN) is that NaN; - * - * Accuracy: - * TRIG(x) returns trig(x) nearly rounded - */ - -#include "libm.h" - -double cos(double x) -{ - double y[2]; - uint32_t ix; - unsigned n; - - GET_HIGH_WORD(ix, x); - ix &= 0x7fffffff; - - /* |x| ~< pi/4 */ - if (ix <= 0x3fe921fb) { - if (ix < 0x3e46a09e) { /* |x| < 2**-27 * sqrt(2) */ - /* raise inexact if x!=0 */ - FORCE_EVAL(x + 0x1p120f); - return 1.0; - } - return __cos(x, 0); - } - - /* cos(Inf or NaN) is NaN */ - if (ix >= 0x7ff00000) - return x-x; - - /* argument reduction */ - n = __rem_pio2(x, y); - switch (n&3) { - case 0: return __cos(y[0], y[1]); - case 1: return -__sin(y[0], y[1], 1); - case 2: return -__cos(y[0], y[1]); - default: - return __sin(y[0], y[1], 1); - } -} diff --git a/waterbox/libc/functions/math/cosf.c b/waterbox/libc/functions/math/cosf.c deleted file mode 100644 index 23f3e5bf69..0000000000 --- a/waterbox/libc/functions/math/cosf.c +++ /dev/null @@ -1,78 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_cosf.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - * Optimized by Bruce D. Evans. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" - -/* Small multiples of pi/2 rounded to double precision. */ -static const double -c1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ -c2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ -c3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ -c4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ - -float cosf(float x) -{ - double y; - uint32_t ix; - unsigned n, sign; - - GET_FLOAT_WORD(ix, x); - sign = ix >> 31; - ix &= 0x7fffffff; - - if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ - if (ix < 0x39800000) { /* |x| < 2**-12 */ - /* raise inexact if x != 0 */ - FORCE_EVAL(x + 0x1p120f); - return 1.0f; - } - return __cosdf(x); - } - if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */ - if (ix > 0x4016cbe3) /* |x| ~> 3*pi/4 */ - return -__cosdf(sign ? x+c2pio2 : x-c2pio2); - else { - if (sign) - return __sindf(x + c1pio2); - else - return __sindf(c1pio2 - x); - } - } - if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */ - if (ix > 0x40afeddf) /* |x| ~> 7*pi/4 */ - return __cosdf(sign ? x+c4pio2 : x-c4pio2); - else { - if (sign) - return __sindf(-x - c3pio2); - else - return __sindf(x - c3pio2); - } - } - - /* cos(Inf or NaN) is NaN */ - if (ix >= 0x7f800000) - return x-x; - - /* general argument reduction needed */ - n = __rem_pio2f(x,&y); - switch (n&3) { - case 0: return __cosdf(y); - case 1: return __sindf(-y); - case 2: return -__cosdf(y); - default: - return __sindf(y); - } -} diff --git a/waterbox/libc/functions/math/cosh.c b/waterbox/libc/functions/math/cosh.c deleted file mode 100644 index 100f8231d8..0000000000 --- a/waterbox/libc/functions/math/cosh.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "libm.h" - -/* cosh(x) = (exp(x) + 1/exp(x))/2 - * = 1 + 0.5*(exp(x)-1)*(exp(x)-1)/exp(x) - * = 1 + x*x/2 + o(x^4) - */ -double cosh(double x) -{ - union {double f; uint64_t i;} u = {.f = x}; - uint32_t w; - double t; - - /* |x| */ - u.i &= (uint64_t)-1/2; - x = u.f; - w = u.i >> 32; - - /* |x| < log(2) */ - if (w < 0x3fe62e42) { - if (w < 0x3ff00000 - (26<<20)) { - /* raise inexact if x!=0 */ - FORCE_EVAL(x + 0x1p120f); - return 1; - } - t = expm1(x); - return 1 + t*t/(2*(1+t)); - } - - /* |x| < log(DBL_MAX) */ - if (w < 0x40862e42) { - t = exp(x); - /* note: if x>log(0x1p26) then the 1/t is not needed */ - return 0.5*(t + 1/t); - } - - /* |x| > log(DBL_MAX) or nan */ - /* note: the result is stored to handle overflow */ - t = __expo2(x); - return t; -} diff --git a/waterbox/libc/functions/math/coshf.c b/waterbox/libc/functions/math/coshf.c deleted file mode 100644 index b09f2ee575..0000000000 --- a/waterbox/libc/functions/math/coshf.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "libm.h" - -float coshf(float x) -{ - union {float f; uint32_t i;} u = {.f = x}; - uint32_t w; - float t; - - /* |x| */ - u.i &= 0x7fffffff; - x = u.f; - w = u.i; - - /* |x| < log(2) */ - if (w < 0x3f317217) { - if (w < 0x3f800000 - (12<<23)) { - FORCE_EVAL(x + 0x1p120f); - return 1; - } - t = expm1f(x); - return 1 + t*t/(2*(1+t)); - } - - /* |x| < log(FLT_MAX) */ - if (w < 0x42b17217) { - t = expf(x); - return 0.5f*(t + 1/t); - } - - /* |x| > log(FLT_MAX) or nan */ - t = __expo2f(x); - return t; -} diff --git a/waterbox/libc/functions/math/coshl.c b/waterbox/libc/functions/math/coshl.c deleted file mode 100644 index 06a56fe3be..0000000000 --- a/waterbox/libc/functions/math/coshl.c +++ /dev/null @@ -1,47 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double coshl(long double x) -{ - return cosh(x); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -long double coshl(long double x) -{ - union ldshape u = {x}; - unsigned ex = u.i.se & 0x7fff; - uint32_t w; - long double t; - - /* |x| */ - u.i.se = ex; - x = u.f; - w = u.i.m >> 32; - - /* |x| < log(2) */ - if (ex < 0x3fff-1 || (ex == 0x3fff-1 && w < 0xb17217f7)) { - if (ex < 0x3fff-32) { - FORCE_EVAL(x + 0x1p120f); - return 1; - } - t = expm1l(x); - return 1 + t*t/(2*(1+t)); - } - - /* |x| < log(LDBL_MAX) */ - if (ex < 0x3fff+13 || (ex == 0x3fff+13 && w < 0xb17217f7)) { - t = expl(x); - return 0.5*(t + 1/t); - } - - /* |x| > log(LDBL_MAX) or nan */ - t = expl(0.5*x); - return 0.5*t*t; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -// TODO: broken implementation to make things compile -long double coshl(long double x) -{ - return cosh(x); -} -#endif diff --git a/waterbox/libc/functions/math/cosl.c b/waterbox/libc/functions/math/cosl.c deleted file mode 100644 index 79c41c77fa..0000000000 --- a/waterbox/libc/functions/math/cosl.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double cosl(long double x) { - return cos(x); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -long double cosl(long double x) -{ - union ldshape u = {x}; - unsigned n; - long double y[2], hi, lo; - - u.i.se &= 0x7fff; - if (u.i.se == 0x7fff) - return x - x; - x = u.f; - if (x < M_PI_4) { - if (u.i.se < 0x3fff - LDBL_MANT_DIG) - /* raise inexact if x!=0 */ - return 1.0 + x; - return __cosl(x, 0); - } - n = __rem_pio2l(x, y); - hi = y[0]; - lo = y[1]; - switch (n & 3) { - case 0: - return __cosl(hi, lo); - case 1: - return -__sinl(hi, lo, 1); - case 2: - return -__cosl(hi, lo); - case 3: - default: - return __sinl(hi, lo, 1); - } -} -#endif diff --git a/waterbox/libc/functions/math/erf.c b/waterbox/libc/functions/math/erf.c deleted file mode 100644 index 2f30a298f9..0000000000 --- a/waterbox/libc/functions/math/erf.c +++ /dev/null @@ -1,273 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_erf.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* double erf(double x) - * double erfc(double x) - * x - * 2 |\ - * erf(x) = --------- | exp(-t*t)dt - * sqrt(pi) \| - * 0 - * - * erfc(x) = 1-erf(x) - * Note that - * erf(-x) = -erf(x) - * erfc(-x) = 2 - erfc(x) - * - * Method: - * 1. For |x| in [0, 0.84375] - * erf(x) = x + x*R(x^2) - * erfc(x) = 1 - erf(x) if x in [-.84375,0.25] - * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375] - * where R = P/Q where P is an odd poly of degree 8 and - * Q is an odd poly of degree 10. - * -57.90 - * | R - (erf(x)-x)/x | <= 2 - * - * - * Remark. The formula is derived by noting - * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) - * and that - * 2/sqrt(pi) = 1.128379167095512573896158903121545171688 - * is close to one. The interval is chosen because the fix - * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is - * near 0.6174), and by some experiment, 0.84375 is chosen to - * guarantee the error is less than one ulp for erf. - * - * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and - * c = 0.84506291151 rounded to single (24 bits) - * erf(x) = sign(x) * (c + P1(s)/Q1(s)) - * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0 - * 1+(c+P1(s)/Q1(s)) if x < 0 - * |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06 - * Remark: here we use the taylor series expansion at x=1. - * erf(1+s) = erf(1) + s*Poly(s) - * = 0.845.. + P1(s)/Q1(s) - * That is, we use rational approximation to approximate - * erf(1+s) - (c = (single)0.84506291151) - * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] - * where - * P1(s) = degree 6 poly in s - * Q1(s) = degree 6 poly in s - * - * 3. For x in [1.25,1/0.35(~2.857143)], - * erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1) - * erf(x) = 1 - erfc(x) - * where - * R1(z) = degree 7 poly in z, (z=1/x^2) - * S1(z) = degree 8 poly in z - * - * 4. For x in [1/0.35,28] - * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0 - * = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6 x >= 28 - * erf(x) = sign(x) *(1 - tiny) (raise inexact) - * erfc(x) = tiny*tiny (raise underflow) if x > 0 - * = 2 - tiny if x<0 - * - * 7. Special case: - * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1, - * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, - * erfc/erf(NaN) is NaN - */ - -#include "libm.h" - -static const double -erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */ -/* - * Coefficients for approximation to erf on [0,0.84375] - */ -efx8 = 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */ -pp0 = 1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */ -pp1 = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */ -pp2 = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */ -pp3 = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */ -pp4 = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */ -qq1 = 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */ -qq2 = 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */ -qq3 = 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */ -qq4 = 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */ -qq5 = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */ -/* - * Coefficients for approximation to erf in [0.84375,1.25] - */ -pa0 = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */ -pa1 = 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */ -pa2 = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */ -pa3 = 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */ -pa4 = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */ -pa5 = 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */ -pa6 = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */ -qa1 = 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */ -qa2 = 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */ -qa3 = 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */ -qa4 = 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */ -qa5 = 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */ -qa6 = 1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */ -/* - * Coefficients for approximation to erfc in [1.25,1/0.35] - */ -ra0 = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */ -ra1 = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */ -ra2 = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */ -ra3 = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */ -ra4 = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */ -ra5 = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */ -ra6 = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */ -ra7 = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */ -sa1 = 1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */ -sa2 = 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */ -sa3 = 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */ -sa4 = 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */ -sa5 = 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */ -sa6 = 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */ -sa7 = 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */ -sa8 = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */ -/* - * Coefficients for approximation to erfc in [1/.35,28] - */ -rb0 = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */ -rb1 = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */ -rb2 = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */ -rb3 = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */ -rb4 = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */ -rb5 = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */ -rb6 = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */ -sb1 = 3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */ -sb2 = 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */ -sb3 = 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */ -sb4 = 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */ -sb5 = 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */ -sb6 = 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */ -sb7 = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */ - -static double erfc1(double x) -{ - double_t s,P,Q; - - s = fabs(x) - 1; - P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); - Q = 1+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); - return 1 - erx - P/Q; -} - -static double erfc2(uint32_t ix, double x) -{ - double_t s,R,S; - double z; - - if (ix < 0x3ff40000) /* |x| < 1.25 */ - return erfc1(x); - - x = fabs(x); - s = 1/(x*x); - if (ix < 0x4006db6d) { /* |x| < 1/.35 ~ 2.85714 */ - R = ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( - ra5+s*(ra6+s*ra7)))))); - S = 1.0+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( - sa5+s*(sa6+s*(sa7+s*sa8))))))); - } else { /* |x| > 1/.35 */ - R = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( - rb5+s*rb6))))); - S = 1.0+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( - sb5+s*(sb6+s*sb7)))))); - } - z = x; - SET_LOW_WORD(z,0); - return exp(-z*z-0.5625)*exp((z-x)*(z+x)+R/S)/x; -} - -double erf(double x) -{ - double r,s,z,y; - uint32_t ix; - int sign; - - GET_HIGH_WORD(ix, x); - sign = ix>>31; - ix &= 0x7fffffff; - if (ix >= 0x7ff00000) { - /* erf(nan)=nan, erf(+-inf)=+-1 */ - return 1-2*sign + 1/x; - } - if (ix < 0x3feb0000) { /* |x| < 0.84375 */ - if (ix < 0x3e300000) { /* |x| < 2**-28 */ - /* avoid underflow */ - return 0.125*(8*x + efx8*x); - } - z = x*x; - r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); - s = 1.0+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); - y = r/s; - return x + x*y; - } - if (ix < 0x40180000) /* 0.84375 <= |x| < 6 */ - y = 1 - erfc2(ix,x); - else - y = 1 - 0x1p-1022; - return sign ? -y : y; -} - -double erfc(double x) -{ - double r,s,z,y; - uint32_t ix; - int sign; - - GET_HIGH_WORD(ix, x); - sign = ix>>31; - ix &= 0x7fffffff; - if (ix >= 0x7ff00000) { - /* erfc(nan)=nan, erfc(+-inf)=0,2 */ - return 2*sign + 1/x; - } - if (ix < 0x3feb0000) { /* |x| < 0.84375 */ - if (ix < 0x3c700000) /* |x| < 2**-56 */ - return 1.0 - x; - z = x*x; - r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); - s = 1.0+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); - y = r/s; - if (sign || ix < 0x3fd00000) { /* x < 1/4 */ - return 1.0 - (x+x*y); - } - return 0.5 - (x - 0.5 + x*y); - } - if (ix < 0x403c0000) { /* 0.84375 <= |x| < 28 */ - return sign ? 2 - erfc2(ix,x) : erfc2(ix,x); - } - return sign ? 2 - 0x1p-1022 : 0x1p-1022*0x1p-1022; -} diff --git a/waterbox/libc/functions/math/erff.c b/waterbox/libc/functions/math/erff.c deleted file mode 100644 index ed5f397574..0000000000 --- a/waterbox/libc/functions/math/erff.c +++ /dev/null @@ -1,183 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_erff.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" - -static const float -erx = 8.4506291151e-01, /* 0x3f58560b */ -/* - * Coefficients for approximation to erf on [0,0.84375] - */ -efx8 = 1.0270333290e+00, /* 0x3f8375d4 */ -pp0 = 1.2837916613e-01, /* 0x3e0375d4 */ -pp1 = -3.2504209876e-01, /* 0xbea66beb */ -pp2 = -2.8481749818e-02, /* 0xbce9528f */ -pp3 = -5.7702702470e-03, /* 0xbbbd1489 */ -pp4 = -2.3763017452e-05, /* 0xb7c756b1 */ -qq1 = 3.9791721106e-01, /* 0x3ecbbbce */ -qq2 = 6.5022252500e-02, /* 0x3d852a63 */ -qq3 = 5.0813062117e-03, /* 0x3ba68116 */ -qq4 = 1.3249473704e-04, /* 0x390aee49 */ -qq5 = -3.9602282413e-06, /* 0xb684e21a */ -/* - * Coefficients for approximation to erf in [0.84375,1.25] - */ -pa0 = -2.3621185683e-03, /* 0xbb1acdc6 */ -pa1 = 4.1485610604e-01, /* 0x3ed46805 */ -pa2 = -3.7220788002e-01, /* 0xbebe9208 */ -pa3 = 3.1834661961e-01, /* 0x3ea2fe54 */ -pa4 = -1.1089469492e-01, /* 0xbde31cc2 */ -pa5 = 3.5478305072e-02, /* 0x3d1151b3 */ -pa6 = -2.1663755178e-03, /* 0xbb0df9c0 */ -qa1 = 1.0642088205e-01, /* 0x3dd9f331 */ -qa2 = 5.4039794207e-01, /* 0x3f0a5785 */ -qa3 = 7.1828655899e-02, /* 0x3d931ae7 */ -qa4 = 1.2617121637e-01, /* 0x3e013307 */ -qa5 = 1.3637083583e-02, /* 0x3c5f6e13 */ -qa6 = 1.1984500103e-02, /* 0x3c445aa3 */ -/* - * Coefficients for approximation to erfc in [1.25,1/0.35] - */ -ra0 = -9.8649440333e-03, /* 0xbc21a093 */ -ra1 = -6.9385856390e-01, /* 0xbf31a0b7 */ -ra2 = -1.0558626175e+01, /* 0xc128f022 */ -ra3 = -6.2375331879e+01, /* 0xc2798057 */ -ra4 = -1.6239666748e+02, /* 0xc322658c */ -ra5 = -1.8460508728e+02, /* 0xc3389ae7 */ -ra6 = -8.1287437439e+01, /* 0xc2a2932b */ -ra7 = -9.8143291473e+00, /* 0xc11d077e */ -sa1 = 1.9651271820e+01, /* 0x419d35ce */ -sa2 = 1.3765776062e+02, /* 0x4309a863 */ -sa3 = 4.3456588745e+02, /* 0x43d9486f */ -sa4 = 6.4538726807e+02, /* 0x442158c9 */ -sa5 = 4.2900814819e+02, /* 0x43d6810b */ -sa6 = 1.0863500214e+02, /* 0x42d9451f */ -sa7 = 6.5702495575e+00, /* 0x40d23f7c */ -sa8 = -6.0424413532e-02, /* 0xbd777f97 */ -/* - * Coefficients for approximation to erfc in [1/.35,28] - */ -rb0 = -9.8649431020e-03, /* 0xbc21a092 */ -rb1 = -7.9928326607e-01, /* 0xbf4c9dd4 */ -rb2 = -1.7757955551e+01, /* 0xc18e104b */ -rb3 = -1.6063638306e+02, /* 0xc320a2ea */ -rb4 = -6.3756646729e+02, /* 0xc41f6441 */ -rb5 = -1.0250950928e+03, /* 0xc480230b */ -rb6 = -4.8351919556e+02, /* 0xc3f1c275 */ -sb1 = 3.0338060379e+01, /* 0x41f2b459 */ -sb2 = 3.2579251099e+02, /* 0x43a2e571 */ -sb3 = 1.5367296143e+03, /* 0x44c01759 */ -sb4 = 3.1998581543e+03, /* 0x4547fdbb */ -sb5 = 2.5530502930e+03, /* 0x451f90ce */ -sb6 = 4.7452853394e+02, /* 0x43ed43a7 */ -sb7 = -2.2440952301e+01; /* 0xc1b38712 */ - -static float erfc1(float x) -{ - float_t s,P,Q; - - s = fabsf(x) - 1; - P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); - Q = 1+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); - return 1 - erx - P/Q; -} - -static float erfc2(uint32_t ix, float x) -{ - float_t s,R,S; - float z; - - if (ix < 0x3fa00000) /* |x| < 1.25 */ - return erfc1(x); - - x = fabsf(x); - s = 1/(x*x); - if (ix < 0x4036db6d) { /* |x| < 1/0.35 */ - R = ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( - ra5+s*(ra6+s*ra7)))))); - S = 1.0f+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( - sa5+s*(sa6+s*(sa7+s*sa8))))))); - } else { /* |x| >= 1/0.35 */ - R = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( - rb5+s*rb6))))); - S = 1.0f+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( - sb5+s*(sb6+s*sb7)))))); - } - GET_FLOAT_WORD(ix, x); - SET_FLOAT_WORD(z, ix&0xffffe000); - return expf(-z*z - 0.5625f) * expf((z-x)*(z+x) + R/S)/x; -} - -float erff(float x) -{ - float r,s,z,y; - uint32_t ix; - int sign; - - GET_FLOAT_WORD(ix, x); - sign = ix>>31; - ix &= 0x7fffffff; - if (ix >= 0x7f800000) { - /* erf(nan)=nan, erf(+-inf)=+-1 */ - return 1-2*sign + 1/x; - } - if (ix < 0x3f580000) { /* |x| < 0.84375 */ - if (ix < 0x31800000) { /* |x| < 2**-28 */ - /*avoid underflow */ - return 0.125f*(8*x + efx8*x); - } - z = x*x; - r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); - s = 1+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); - y = r/s; - return x + x*y; - } - if (ix < 0x40c00000) /* |x| < 6 */ - y = 1 - erfc2(ix,x); - else - y = 1 - 0x1p-120f; - return sign ? -y : y; -} - -float erfcf(float x) -{ - float r,s,z,y; - uint32_t ix; - int sign; - - GET_FLOAT_WORD(ix, x); - sign = ix>>31; - ix &= 0x7fffffff; - if (ix >= 0x7f800000) { - /* erfc(nan)=nan, erfc(+-inf)=0,2 */ - return 2*sign + 1/x; - } - - if (ix < 0x3f580000) { /* |x| < 0.84375 */ - if (ix < 0x23800000) /* |x| < 2**-56 */ - return 1.0f - x; - z = x*x; - r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); - s = 1.0f+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); - y = r/s; - if (sign || ix < 0x3e800000) /* x < 1/4 */ - return 1.0f - (x+x*y); - return 0.5f - (x - 0.5f + x*y); - } - if (ix < 0x41e00000) { /* |x| < 28 */ - return sign ? 2 - erfc2(ix,x) : erfc2(ix,x); - } - return sign ? 2 - 0x1p-120f : 0x1p-120f*0x1p-120f; -} diff --git a/waterbox/libc/functions/math/erfl.c b/waterbox/libc/functions/math/erfl.c deleted file mode 100644 index e267c23105..0000000000 --- a/waterbox/libc/functions/math/erfl.c +++ /dev/null @@ -1,353 +0,0 @@ -/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_erfl.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* - * Copyright (c) 2008 Stephen L. Moshier - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/* double erf(double x) - * double erfc(double x) - * x - * 2 |\ - * erf(x) = --------- | exp(-t*t)dt - * sqrt(pi) \| - * 0 - * - * erfc(x) = 1-erf(x) - * Note that - * erf(-x) = -erf(x) - * erfc(-x) = 2 - erfc(x) - * - * Method: - * 1. For |x| in [0, 0.84375] - * erf(x) = x + x*R(x^2) - * erfc(x) = 1 - erf(x) if x in [-.84375,0.25] - * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375] - * Remark. The formula is derived by noting - * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) - * and that - * 2/sqrt(pi) = 1.128379167095512573896158903121545171688 - * is close to one. The interval is chosen because the fix - * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is - * near 0.6174), and by some experiment, 0.84375 is chosen to - * guarantee the error is less than one ulp for erf. - * - * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and - * c = 0.84506291151 rounded to single (24 bits) - * erf(x) = sign(x) * (c + P1(s)/Q1(s)) - * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0 - * 1+(c+P1(s)/Q1(s)) if x < 0 - * Remark: here we use the taylor series expansion at x=1. - * erf(1+s) = erf(1) + s*Poly(s) - * = 0.845.. + P1(s)/Q1(s) - * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] - * - * 3. For x in [1.25,1/0.35(~2.857143)], - * erfc(x) = (1/x)*exp(-x*x-0.5625+R1(z)/S1(z)) - * z=1/x^2 - * erf(x) = 1 - erfc(x) - * - * 4. For x in [1/0.35,107] - * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0 - * = 2.0 - (1/x)*exp(-x*x-0.5625+R2(z)/S2(z)) - * if -6.666 x >= 107 - * erf(x) = sign(x) *(1 - tiny) (raise inexact) - * erfc(x) = tiny*tiny (raise underflow) if x > 0 - * = 2 - tiny if x<0 - * - * 7. Special case: - * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1, - * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, - * erfc/erf(NaN) is NaN - */ - - -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double erfl(long double x) -{ - return erf(x); -} -long double erfcl(long double x) -{ - return erfc(x); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -static const long double -erx = 0.845062911510467529296875L, - -/* - * Coefficients for approximation to erf on [0,0.84375] - */ -/* 8 * (2/sqrt(pi) - 1) */ -efx8 = 1.0270333367641005911692712249723613735048E0L, -pp[6] = { - 1.122751350964552113068262337278335028553E6L, - -2.808533301997696164408397079650699163276E6L, - -3.314325479115357458197119660818768924100E5L, - -6.848684465326256109712135497895525446398E4L, - -2.657817695110739185591505062971929859314E3L, - -1.655310302737837556654146291646499062882E2L, -}, -qq[6] = { - 8.745588372054466262548908189000448124232E6L, - 3.746038264792471129367533128637019611485E6L, - 7.066358783162407559861156173539693900031E5L, - 7.448928604824620999413120955705448117056E4L, - 4.511583986730994111992253980546131408924E3L, - 1.368902937933296323345610240009071254014E2L, - /* 1.000000000000000000000000000000000000000E0 */ -}, - -/* - * Coefficients for approximation to erf in [0.84375,1.25] - */ -/* erf(x+1) = 0.845062911510467529296875 + pa(x)/qa(x) - -0.15625 <= x <= +.25 - Peak relative error 8.5e-22 */ -pa[8] = { - -1.076952146179812072156734957705102256059E0L, - 1.884814957770385593365179835059971587220E2L, - -5.339153975012804282890066622962070115606E1L, - 4.435910679869176625928504532109635632618E1L, - 1.683219516032328828278557309642929135179E1L, - -2.360236618396952560064259585299045804293E0L, - 1.852230047861891953244413872297940938041E0L, - 9.394994446747752308256773044667843200719E-2L, -}, -qa[7] = { - 4.559263722294508998149925774781887811255E2L, - 3.289248982200800575749795055149780689738E2L, - 2.846070965875643009598627918383314457912E2L, - 1.398715859064535039433275722017479994465E2L, - 6.060190733759793706299079050985358190726E1L, - 2.078695677795422351040502569964299664233E1L, - 4.641271134150895940966798357442234498546E0L, - /* 1.000000000000000000000000000000000000000E0 */ -}, - -/* - * Coefficients for approximation to erfc in [1.25,1/0.35] - */ -/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + ra(x^2)/sa(x^2)) - 1/2.85711669921875 < 1/x < 1/1.25 - Peak relative error 3.1e-21 */ -ra[] = { - 1.363566591833846324191000679620738857234E-1L, - 1.018203167219873573808450274314658434507E1L, - 1.862359362334248675526472871224778045594E2L, - 1.411622588180721285284945138667933330348E3L, - 5.088538459741511988784440103218342840478E3L, - 8.928251553922176506858267311750789273656E3L, - 7.264436000148052545243018622742770549982E3L, - 2.387492459664548651671894725748959751119E3L, - 2.220916652813908085449221282808458466556E2L, -}, -sa[] = { - -1.382234625202480685182526402169222331847E1L, - -3.315638835627950255832519203687435946482E2L, - -2.949124863912936259747237164260785326692E3L, - -1.246622099070875940506391433635999693661E4L, - -2.673079795851665428695842853070996219632E4L, - -2.880269786660559337358397106518918220991E4L, - -1.450600228493968044773354186390390823713E4L, - -2.874539731125893533960680525192064277816E3L, - -1.402241261419067750237395034116942296027E2L, - /* 1.000000000000000000000000000000000000000E0 */ -}, - -/* - * Coefficients for approximation to erfc in [1/.35,107] - */ -/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + rb(x^2)/sb(x^2)) - 1/6.6666259765625 < 1/x < 1/2.85711669921875 - Peak relative error 4.2e-22 */ -rb[] = { - -4.869587348270494309550558460786501252369E-5L, - -4.030199390527997378549161722412466959403E-3L, - -9.434425866377037610206443566288917589122E-2L, - -9.319032754357658601200655161585539404155E-1L, - -4.273788174307459947350256581445442062291E0L, - -8.842289940696150508373541814064198259278E0L, - -7.069215249419887403187988144752613025255E0L, - -1.401228723639514787920274427443330704764E0L, -}, -sb[] = { - 4.936254964107175160157544545879293019085E-3L, - 1.583457624037795744377163924895349412015E-1L, - 1.850647991850328356622940552450636420484E0L, - 9.927611557279019463768050710008450625415E0L, - 2.531667257649436709617165336779212114570E1L, - 2.869752886406743386458304052862814690045E1L, - 1.182059497870819562441683560749192539345E1L, - /* 1.000000000000000000000000000000000000000E0 */ -}, -/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + rc(x^2)/sc(x^2)) - 1/107 <= 1/x <= 1/6.6666259765625 - Peak relative error 1.1e-21 */ -rc[] = { - -8.299617545269701963973537248996670806850E-5L, - -6.243845685115818513578933902532056244108E-3L, - -1.141667210620380223113693474478394397230E-1L, - -7.521343797212024245375240432734425789409E-1L, - -1.765321928311155824664963633786967602934E0L, - -1.029403473103215800456761180695263439188E0L, -}, -sc[] = { - 8.413244363014929493035952542677768808601E-3L, - 2.065114333816877479753334599639158060979E-1L, - 1.639064941530797583766364412782135680148E0L, - 4.936788463787115555582319302981666347450E0L, - 5.005177727208955487404729933261347679090E0L, - /* 1.000000000000000000000000000000000000000E0 */ -}; - -static long double erfc1(long double x) -{ - long double s,P,Q; - - s = fabsl(x) - 1; - P = pa[0] + s * (pa[1] + s * (pa[2] + - s * (pa[3] + s * (pa[4] + s * (pa[5] + s * (pa[6] + s * pa[7])))))); - Q = qa[0] + s * (qa[1] + s * (qa[2] + - s * (qa[3] + s * (qa[4] + s * (qa[5] + s * (qa[6] + s)))))); - return 1 - erx - P / Q; -} - -static long double erfc2(uint32_t ix, long double x) -{ - union ldshape u; - long double s,z,R,S; - - if (ix < 0x3fffa000) /* 0.84375 <= |x| < 1.25 */ - return erfc1(x); - - x = fabsl(x); - s = 1 / (x * x); - if (ix < 0x4000b6db) { /* 1.25 <= |x| < 2.857 ~ 1/.35 */ - R = ra[0] + s * (ra[1] + s * (ra[2] + s * (ra[3] + s * (ra[4] + - s * (ra[5] + s * (ra[6] + s * (ra[7] + s * ra[8]))))))); - S = sa[0] + s * (sa[1] + s * (sa[2] + s * (sa[3] + s * (sa[4] + - s * (sa[5] + s * (sa[6] + s * (sa[7] + s * (sa[8] + s)))))))); - } else if (ix < 0x4001d555) { /* 2.857 <= |x| < 6.6666259765625 */ - R = rb[0] + s * (rb[1] + s * (rb[2] + s * (rb[3] + s * (rb[4] + - s * (rb[5] + s * (rb[6] + s * rb[7])))))); - S = sb[0] + s * (sb[1] + s * (sb[2] + s * (sb[3] + s * (sb[4] + - s * (sb[5] + s * (sb[6] + s)))))); - } else { /* 6.666 <= |x| < 107 (erfc only) */ - R = rc[0] + s * (rc[1] + s * (rc[2] + s * (rc[3] + - s * (rc[4] + s * rc[5])))); - S = sc[0] + s * (sc[1] + s * (sc[2] + s * (sc[3] + - s * (sc[4] + s)))); - } - u.f = x; - u.i.m &= -1ULL << 40; - z = u.f; - return expl(-z*z - 0.5625) * expl((z - x) * (z + x) + R / S) / x; -} - -long double erfl(long double x) -{ - long double r, s, z, y; - union ldshape u = {x}; - uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48; - int sign = u.i.se >> 15; - - if (ix >= 0x7fff0000) - /* erf(nan)=nan, erf(+-inf)=+-1 */ - return 1 - 2*sign + 1/x; - if (ix < 0x3ffed800) { /* |x| < 0.84375 */ - if (ix < 0x3fde8000) { /* |x| < 2**-33 */ - return 0.125 * (8 * x + efx8 * x); /* avoid underflow */ - } - z = x * x; - r = pp[0] + z * (pp[1] + - z * (pp[2] + z * (pp[3] + z * (pp[4] + z * pp[5])))); - s = qq[0] + z * (qq[1] + - z * (qq[2] + z * (qq[3] + z * (qq[4] + z * (qq[5] + z))))); - y = r / s; - return x + x * y; - } - if (ix < 0x4001d555) /* |x| < 6.6666259765625 */ - y = 1 - erfc2(ix,x); - else - y = 1 - 0x1p-16382L; - return sign ? -y : y; -} - -long double erfcl(long double x) -{ - long double r, s, z, y; - union ldshape u = {x}; - uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48; - int sign = u.i.se >> 15; - - if (ix >= 0x7fff0000) - /* erfc(nan) = nan, erfc(+-inf) = 0,2 */ - return 2*sign + 1/x; - if (ix < 0x3ffed800) { /* |x| < 0.84375 */ - if (ix < 0x3fbe0000) /* |x| < 2**-65 */ - return 1.0 - x; - z = x * x; - r = pp[0] + z * (pp[1] + - z * (pp[2] + z * (pp[3] + z * (pp[4] + z * pp[5])))); - s = qq[0] + z * (qq[1] + - z * (qq[2] + z * (qq[3] + z * (qq[4] + z * (qq[5] + z))))); - y = r / s; - if (ix < 0x3ffd8000) /* x < 1/4 */ - return 1.0 - (x + x * y); - return 0.5 - (x - 0.5 + x * y); - } - if (ix < 0x4005d600) /* |x| < 107 */ - return sign ? 2 - erfc2(ix,x) : erfc2(ix,x); - y = 0x1p-16382L; - return sign ? 2 - y : y*y; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -// TODO: broken implementation to make things compile -long double erfl(long double x) -{ - return erf(x); -} -long double erfcl(long double x) -{ - return erfc(x); -} -#endif diff --git a/waterbox/libc/functions/math/exp.c b/waterbox/libc/functions/math/exp.c deleted file mode 100644 index 9ea672fac6..0000000000 --- a/waterbox/libc/functions/math/exp.c +++ /dev/null @@ -1,134 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_exp.c */ -/* - * ==================================================== - * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. - * - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* exp(x) - * Returns the exponential of x. - * - * Method - * 1. Argument reduction: - * Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658. - * Given x, find r and integer k such that - * - * x = k*ln2 + r, |r| <= 0.5*ln2. - * - * Here r will be represented as r = hi-lo for better - * accuracy. - * - * 2. Approximation of exp(r) by a special rational function on - * the interval [0,0.34658]: - * Write - * R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ... - * We use a special Remez algorithm on [0,0.34658] to generate - * a polynomial of degree 5 to approximate R. The maximum error - * of this polynomial approximation is bounded by 2**-59. In - * other words, - * R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5 - * (where z=r*r, and the values of P1 to P5 are listed below) - * and - * | 5 | -59 - * | 2.0+P1*z+...+P5*z - R(z) | <= 2 - * | | - * The computation of exp(r) thus becomes - * 2*r - * exp(r) = 1 + ---------- - * R(r) - r - * r*c(r) - * = 1 + r + ----------- (for better accuracy) - * 2 - c(r) - * where - * 2 4 10 - * c(r) = r - (P1*r + P2*r + ... + P5*r ). - * - * 3. Scale back to obtain exp(x): - * From step 1, we have - * exp(x) = 2^k * exp(r) - * - * Special cases: - * exp(INF) is INF, exp(NaN) is NaN; - * exp(-INF) is 0, and - * for finite argument, only exp(0)=1 is exact. - * - * Accuracy: - * according to an error analysis, the error is always less than - * 1 ulp (unit in the last place). - * - * Misc. info. - * For IEEE double - * if x > 709.782712893383973096 then exp(x) overflows - * if x < -745.133219101941108420 then exp(x) underflows - */ - -#include "libm.h" - -static const double -half[2] = {0.5,-0.5}, -ln2hi = 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */ -ln2lo = 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */ -invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */ -P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ -P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ -P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ -P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ -P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ - -double exp(double x) -{ - double_t hi, lo, c, xx, y; - int k, sign; - uint32_t hx; - - GET_HIGH_WORD(hx, x); - sign = hx>>31; - hx &= 0x7fffffff; /* high word of |x| */ - - /* special cases */ - if (hx >= 0x4086232b) { /* if |x| >= 708.39... */ - if (isnan(x)) - return x; - if (x > 709.782712893383973096) { - /* overflow if x!=inf */ - x *= 0x1p1023; - return x; - } - if (x < -708.39641853226410622) { - /* underflow if x!=-inf */ - FORCE_EVAL((float)(-0x1p-149/x)); - if (x < -745.13321910194110842) - return 0; - } - } - - /* argument reduction */ - if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ - if (hx >= 0x3ff0a2b2) /* if |x| >= 1.5 ln2 */ - k = (int)(invln2*x + half[sign]); - else - k = 1 - sign - sign; - hi = x - k*ln2hi; /* k*ln2hi is exact here */ - lo = k*ln2lo; - x = hi - lo; - } else if (hx > 0x3e300000) { /* if |x| > 2**-28 */ - k = 0; - hi = x; - lo = 0; - } else { - /* inexact if x!=0 */ - FORCE_EVAL(0x1p1023 + x); - return 1 + x; - } - - /* x is now in primary range */ - xx = x*x; - c = x - xx*(P1+xx*(P2+xx*(P3+xx*(P4+xx*P5)))); - y = 1 + (x*c/(2-c) - lo + hi); - if (k == 0) - return y; - return scalbn(y, k); -} diff --git a/waterbox/libc/functions/math/exp10.c b/waterbox/libc/functions/math/exp10.c deleted file mode 100644 index 0634a75169..0000000000 --- a/waterbox/libc/functions/math/exp10.c +++ /dev/null @@ -1,25 +0,0 @@ -#define _GNU_SOURCE -#include -#include -#include "_alias.h" - -double exp10(double x) -{ - static const double p10[] = { - 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, - 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, - 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15 - }; - double n, y = modf(x, &n); - union {double f; uint64_t i;} u = {n}; - /* fabs(n) < 16 without raising invalid on nan */ - if ((u.i>>52 & 0x7ff) < 0x3ff+4) { - if (!y) return p10[(int)n+15]; - y = exp2(3.32192809488736234787031942948939 * y); - return y * p10[(int)n+15]; - } - return pow(10.0, x); -} - -weak_alias(exp10, pow10); diff --git a/waterbox/libc/functions/math/exp10f.c b/waterbox/libc/functions/math/exp10f.c deleted file mode 100644 index 23abd90599..0000000000 --- a/waterbox/libc/functions/math/exp10f.c +++ /dev/null @@ -1,23 +0,0 @@ -#define _GNU_SOURCE -#include -#include -#include "_alias.h" - -float exp10f(float x) -{ - static const float p10[] = { - 1e-7f, 1e-6f, 1e-5f, 1e-4f, 1e-3f, 1e-2f, 1e-1f, - 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7 - }; - float n, y = modff(x, &n); - union {float f; uint32_t i;} u = {n}; - /* fabsf(n) < 8 without raising invalid on nan */ - if ((u.i>>23 & 0xff) < 0x7f+3) { - if (!y) return p10[(int)n+7]; - y = exp2f(3.32192809488736234787031942948939f * y); - return y * p10[(int)n+7]; - } - return exp2(3.32192809488736234787031942948939 * x); -} - -weak_alias(exp10f, pow10f); diff --git a/waterbox/libc/functions/math/exp10l.c b/waterbox/libc/functions/math/exp10l.c deleted file mode 100644 index 125c5bb13b..0000000000 --- a/waterbox/libc/functions/math/exp10l.c +++ /dev/null @@ -1,33 +0,0 @@ -#define _GNU_SOURCE -#include -#include -#include "_alias.h" -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double exp10l(long double x) -{ - return exp10(x); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -long double exp10l(long double x) -{ - static const long double p10[] = { - 1e-15L, 1e-14L, 1e-13L, 1e-12L, 1e-11L, 1e-10L, - 1e-9L, 1e-8L, 1e-7L, 1e-6L, 1e-5L, 1e-4L, 1e-3L, 1e-2L, 1e-1L, - 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15 - }; - long double n, y = modfl(x, &n); - union ldshape u = {n}; - /* fabsl(n) < 16 without raising invalid on nan */ - if ((u.i.se & 0x7fff) < 0x3fff+4) { - if (!y) return p10[(int)n+15]; - y = exp2l(3.32192809488736234787031942948939L * y); - return y * p10[(int)n+15]; - } - return powl(10.0, x); -} -#endif - -weak_alias(exp10l, pow10l); diff --git a/waterbox/libc/functions/math/exp2.c b/waterbox/libc/functions/math/exp2.c deleted file mode 100644 index e14adba530..0000000000 --- a/waterbox/libc/functions/math/exp2.c +++ /dev/null @@ -1,375 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_exp2.c */ -/*- - * Copyright (c) 2005 David Schultz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "libm.h" - -#define TBLSIZE 256 - -static const double -redux = 0x1.8p52 / TBLSIZE, -P1 = 0x1.62e42fefa39efp-1, -P2 = 0x1.ebfbdff82c575p-3, -P3 = 0x1.c6b08d704a0a6p-5, -P4 = 0x1.3b2ab88f70400p-7, -P5 = 0x1.5d88003875c74p-10; - -static const double tbl[TBLSIZE * 2] = { -/* exp2(z + eps) eps */ - 0x1.6a09e667f3d5dp-1, 0x1.9880p-44, - 0x1.6b052fa751744p-1, 0x1.8000p-50, - 0x1.6c012750bd9fep-1, -0x1.8780p-45, - 0x1.6cfdcddd476bfp-1, 0x1.ec00p-46, - 0x1.6dfb23c651a29p-1, -0x1.8000p-50, - 0x1.6ef9298593ae3p-1, -0x1.c000p-52, - 0x1.6ff7df9519386p-1, -0x1.fd80p-45, - 0x1.70f7466f42da3p-1, -0x1.c880p-45, - 0x1.71f75e8ec5fc3p-1, 0x1.3c00p-46, - 0x1.72f8286eacf05p-1, -0x1.8300p-44, - 0x1.73f9a48a58152p-1, -0x1.0c00p-47, - 0x1.74fbd35d7ccfcp-1, 0x1.f880p-45, - 0x1.75feb564267f1p-1, 0x1.3e00p-47, - 0x1.77024b1ab6d48p-1, -0x1.7d00p-45, - 0x1.780694fde5d38p-1, -0x1.d000p-50, - 0x1.790b938ac1d00p-1, 0x1.3000p-49, - 0x1.7a11473eb0178p-1, -0x1.d000p-49, - 0x1.7b17b0976d060p-1, 0x1.0400p-45, - 0x1.7c1ed0130c133p-1, 0x1.0000p-53, - 0x1.7d26a62ff8636p-1, -0x1.6900p-45, - 0x1.7e2f336cf4e3bp-1, -0x1.2e00p-47, - 0x1.7f3878491c3e8p-1, -0x1.4580p-45, - 0x1.80427543e1b4ep-1, 0x1.3000p-44, - 0x1.814d2add1071ap-1, 0x1.f000p-47, - 0x1.82589994ccd7ep-1, -0x1.1c00p-45, - 0x1.8364c1eb942d0p-1, 0x1.9d00p-45, - 0x1.8471a4623cab5p-1, 0x1.7100p-43, - 0x1.857f4179f5bbcp-1, 0x1.2600p-45, - 0x1.868d99b4491afp-1, -0x1.2c40p-44, - 0x1.879cad931a395p-1, -0x1.3000p-45, - 0x1.88ac7d98a65b8p-1, -0x1.a800p-45, - 0x1.89bd0a4785800p-1, -0x1.d000p-49, - 0x1.8ace5422aa223p-1, 0x1.3280p-44, - 0x1.8be05bad619fap-1, 0x1.2b40p-43, - 0x1.8cf3216b54383p-1, -0x1.ed00p-45, - 0x1.8e06a5e08664cp-1, -0x1.0500p-45, - 0x1.8f1ae99157807p-1, 0x1.8280p-45, - 0x1.902fed0282c0ep-1, -0x1.cb00p-46, - 0x1.9145b0b91ff96p-1, -0x1.5e00p-47, - 0x1.925c353aa2ff9p-1, 0x1.5400p-48, - 0x1.93737b0cdc64ap-1, 0x1.7200p-46, - 0x1.948b82b5f98aep-1, -0x1.9000p-47, - 0x1.95a44cbc852cbp-1, 0x1.5680p-45, - 0x1.96bdd9a766f21p-1, -0x1.6d00p-44, - 0x1.97d829fde4e2ap-1, -0x1.1000p-47, - 0x1.98f33e47a23a3p-1, 0x1.d000p-45, - 0x1.9a0f170ca0604p-1, -0x1.8a40p-44, - 0x1.9b2bb4d53ff89p-1, 0x1.55c0p-44, - 0x1.9c49182a3f15bp-1, 0x1.6b80p-45, - 0x1.9d674194bb8c5p-1, -0x1.c000p-49, - 0x1.9e86319e3238ep-1, 0x1.7d00p-46, - 0x1.9fa5e8d07f302p-1, 0x1.6400p-46, - 0x1.a0c667b5de54dp-1, -0x1.5000p-48, - 0x1.a1e7aed8eb8f6p-1, 0x1.9e00p-47, - 0x1.a309bec4a2e27p-1, 0x1.ad80p-45, - 0x1.a42c980460a5dp-1, -0x1.af00p-46, - 0x1.a5503b23e259bp-1, 0x1.b600p-47, - 0x1.a674a8af46213p-1, 0x1.8880p-44, - 0x1.a799e1330b3a7p-1, 0x1.1200p-46, - 0x1.a8bfe53c12e8dp-1, 0x1.6c00p-47, - 0x1.a9e6b5579fcd2p-1, -0x1.9b80p-45, - 0x1.ab0e521356fb8p-1, 0x1.b700p-45, - 0x1.ac36bbfd3f381p-1, 0x1.9000p-50, - 0x1.ad5ff3a3c2780p-1, 0x1.4000p-49, - 0x1.ae89f995ad2a3p-1, -0x1.c900p-45, - 0x1.afb4ce622f367p-1, 0x1.6500p-46, - 0x1.b0e07298db790p-1, 0x1.fd40p-45, - 0x1.b20ce6c9a89a9p-1, 0x1.2700p-46, - 0x1.b33a2b84f1a4bp-1, 0x1.d470p-43, - 0x1.b468415b747e7p-1, -0x1.8380p-44, - 0x1.b59728de5593ap-1, 0x1.8000p-54, - 0x1.b6c6e29f1c56ap-1, 0x1.ad00p-47, - 0x1.b7f76f2fb5e50p-1, 0x1.e800p-50, - 0x1.b928cf22749b2p-1, -0x1.4c00p-47, - 0x1.ba5b030a10603p-1, -0x1.d700p-47, - 0x1.bb8e0b79a6f66p-1, 0x1.d900p-47, - 0x1.bcc1e904bc1ffp-1, 0x1.2a00p-47, - 0x1.bdf69c3f3a16fp-1, -0x1.f780p-46, - 0x1.bf2c25bd71db8p-1, -0x1.0a00p-46, - 0x1.c06286141b2e9p-1, -0x1.1400p-46, - 0x1.c199bdd8552e0p-1, 0x1.be00p-47, - 0x1.c2d1cd9fa64eep-1, -0x1.9400p-47, - 0x1.c40ab5fffd02fp-1, -0x1.ed00p-47, - 0x1.c544778fafd15p-1, 0x1.9660p-44, - 0x1.c67f12e57d0cbp-1, -0x1.a100p-46, - 0x1.c7ba88988c1b6p-1, -0x1.8458p-42, - 0x1.c8f6d9406e733p-1, -0x1.a480p-46, - 0x1.ca3405751c4dfp-1, 0x1.b000p-51, - 0x1.cb720dcef9094p-1, 0x1.1400p-47, - 0x1.ccb0f2e6d1689p-1, 0x1.0200p-48, - 0x1.cdf0b555dc412p-1, 0x1.3600p-48, - 0x1.cf3155b5bab3bp-1, -0x1.6900p-47, - 0x1.d072d4a0789bcp-1, 0x1.9a00p-47, - 0x1.d1b532b08c8fap-1, -0x1.5e00p-46, - 0x1.d2f87080d8a85p-1, 0x1.d280p-46, - 0x1.d43c8eacaa203p-1, 0x1.1a00p-47, - 0x1.d5818dcfba491p-1, 0x1.f000p-50, - 0x1.d6c76e862e6a1p-1, -0x1.3a00p-47, - 0x1.d80e316c9834ep-1, -0x1.cd80p-47, - 0x1.d955d71ff6090p-1, 0x1.4c00p-48, - 0x1.da9e603db32aep-1, 0x1.f900p-48, - 0x1.dbe7cd63a8325p-1, 0x1.9800p-49, - 0x1.dd321f301b445p-1, -0x1.5200p-48, - 0x1.de7d5641c05bfp-1, -0x1.d700p-46, - 0x1.dfc97337b9aecp-1, -0x1.6140p-46, - 0x1.e11676b197d5ep-1, 0x1.b480p-47, - 0x1.e264614f5a3e7p-1, 0x1.0ce0p-43, - 0x1.e3b333b16ee5cp-1, 0x1.c680p-47, - 0x1.e502ee78b3fb4p-1, -0x1.9300p-47, - 0x1.e653924676d68p-1, -0x1.5000p-49, - 0x1.e7a51fbc74c44p-1, -0x1.7f80p-47, - 0x1.e8f7977cdb726p-1, -0x1.3700p-48, - 0x1.ea4afa2a490e8p-1, 0x1.5d00p-49, - 0x1.eb9f4867ccae4p-1, 0x1.61a0p-46, - 0x1.ecf482d8e680dp-1, 0x1.5500p-48, - 0x1.ee4aaa2188514p-1, 0x1.6400p-51, - 0x1.efa1bee615a13p-1, -0x1.e800p-49, - 0x1.f0f9c1cb64106p-1, -0x1.a880p-48, - 0x1.f252b376bb963p-1, -0x1.c900p-45, - 0x1.f3ac948dd7275p-1, 0x1.a000p-53, - 0x1.f50765b6e4524p-1, -0x1.4f00p-48, - 0x1.f6632798844fdp-1, 0x1.a800p-51, - 0x1.f7bfdad9cbe38p-1, 0x1.abc0p-48, - 0x1.f91d802243c82p-1, -0x1.4600p-50, - 0x1.fa7c1819e908ep-1, -0x1.b0c0p-47, - 0x1.fbdba3692d511p-1, -0x1.0e00p-51, - 0x1.fd3c22b8f7194p-1, -0x1.0de8p-46, - 0x1.fe9d96b2a23eep-1, 0x1.e430p-49, - 0x1.0000000000000p+0, 0x0.0000p+0, - 0x1.00b1afa5abcbep+0, -0x1.3400p-52, - 0x1.0163da9fb3303p+0, -0x1.2170p-46, - 0x1.02168143b0282p+0, 0x1.a400p-52, - 0x1.02c9a3e77806cp+0, 0x1.f980p-49, - 0x1.037d42e11bbcap+0, -0x1.7400p-51, - 0x1.04315e86e7f89p+0, 0x1.8300p-50, - 0x1.04e5f72f65467p+0, -0x1.a3f0p-46, - 0x1.059b0d315855ap+0, -0x1.2840p-47, - 0x1.0650a0e3c1f95p+0, 0x1.1600p-48, - 0x1.0706b29ddf71ap+0, 0x1.5240p-46, - 0x1.07bd42b72a82dp+0, -0x1.9a00p-49, - 0x1.0874518759bd0p+0, 0x1.6400p-49, - 0x1.092bdf66607c8p+0, -0x1.0780p-47, - 0x1.09e3ecac6f383p+0, -0x1.8000p-54, - 0x1.0a9c79b1f3930p+0, 0x1.fa00p-48, - 0x1.0b5586cf988fcp+0, -0x1.ac80p-48, - 0x1.0c0f145e46c8ap+0, 0x1.9c00p-50, - 0x1.0cc922b724816p+0, 0x1.5200p-47, - 0x1.0d83b23395dd8p+0, -0x1.ad00p-48, - 0x1.0e3ec32d3d1f3p+0, 0x1.bac0p-46, - 0x1.0efa55fdfa9a6p+0, -0x1.4e80p-47, - 0x1.0fb66affed2f0p+0, -0x1.d300p-47, - 0x1.1073028d7234bp+0, 0x1.1500p-48, - 0x1.11301d0125b5bp+0, 0x1.c000p-49, - 0x1.11edbab5e2af9p+0, 0x1.6bc0p-46, - 0x1.12abdc06c31d5p+0, 0x1.8400p-49, - 0x1.136a814f2047dp+0, -0x1.ed00p-47, - 0x1.1429aaea92de9p+0, 0x1.8e00p-49, - 0x1.14e95934f3138p+0, 0x1.b400p-49, - 0x1.15a98c8a58e71p+0, 0x1.5300p-47, - 0x1.166a45471c3dfp+0, 0x1.3380p-47, - 0x1.172b83c7d5211p+0, 0x1.8d40p-45, - 0x1.17ed48695bb9fp+0, -0x1.5d00p-47, - 0x1.18af9388c8d93p+0, -0x1.c880p-46, - 0x1.1972658375d66p+0, 0x1.1f00p-46, - 0x1.1a35beb6fcba7p+0, 0x1.0480p-46, - 0x1.1af99f81387e3p+0, -0x1.7390p-43, - 0x1.1bbe084045d54p+0, 0x1.4e40p-45, - 0x1.1c82f95281c43p+0, -0x1.a200p-47, - 0x1.1d4873168b9b2p+0, 0x1.3800p-49, - 0x1.1e0e75eb44031p+0, 0x1.ac00p-49, - 0x1.1ed5022fcd938p+0, 0x1.1900p-47, - 0x1.1f9c18438cdf7p+0, -0x1.b780p-46, - 0x1.2063b88628d8fp+0, 0x1.d940p-45, - 0x1.212be3578a81ep+0, 0x1.8000p-50, - 0x1.21f49917ddd41p+0, 0x1.b340p-45, - 0x1.22bdda2791323p+0, 0x1.9f80p-46, - 0x1.2387a6e7561e7p+0, -0x1.9c80p-46, - 0x1.2451ffb821427p+0, 0x1.2300p-47, - 0x1.251ce4fb2a602p+0, -0x1.3480p-46, - 0x1.25e85711eceb0p+0, 0x1.2700p-46, - 0x1.26b4565e27d16p+0, 0x1.1d00p-46, - 0x1.2780e341de00fp+0, 0x1.1ee0p-44, - 0x1.284dfe1f5633ep+0, -0x1.4c00p-46, - 0x1.291ba7591bb30p+0, -0x1.3d80p-46, - 0x1.29e9df51fdf09p+0, 0x1.8b00p-47, - 0x1.2ab8a66d10e9bp+0, -0x1.27c0p-45, - 0x1.2b87fd0dada3ap+0, 0x1.a340p-45, - 0x1.2c57e39771af9p+0, -0x1.0800p-46, - 0x1.2d285a6e402d9p+0, -0x1.ed00p-47, - 0x1.2df961f641579p+0, -0x1.4200p-48, - 0x1.2ecafa93e2ecfp+0, -0x1.4980p-45, - 0x1.2f9d24abd8822p+0, -0x1.6300p-46, - 0x1.306fe0a31b625p+0, -0x1.2360p-44, - 0x1.31432edeea50bp+0, -0x1.0df8p-40, - 0x1.32170fc4cd7b8p+0, -0x1.2480p-45, - 0x1.32eb83ba8e9a2p+0, -0x1.5980p-45, - 0x1.33c08b2641766p+0, 0x1.ed00p-46, - 0x1.3496266e3fa27p+0, -0x1.c000p-50, - 0x1.356c55f929f0fp+0, -0x1.0d80p-44, - 0x1.36431a2de88b9p+0, 0x1.2c80p-45, - 0x1.371a7373aaa39p+0, 0x1.0600p-45, - 0x1.37f26231e74fep+0, -0x1.6600p-46, - 0x1.38cae6d05d838p+0, -0x1.ae00p-47, - 0x1.39a401b713ec3p+0, -0x1.4720p-43, - 0x1.3a7db34e5a020p+0, 0x1.8200p-47, - 0x1.3b57fbfec6e95p+0, 0x1.e800p-44, - 0x1.3c32dc313a8f2p+0, 0x1.f800p-49, - 0x1.3d0e544ede122p+0, -0x1.7a00p-46, - 0x1.3dea64c1234bbp+0, 0x1.6300p-45, - 0x1.3ec70df1c4eccp+0, -0x1.8a60p-43, - 0x1.3fa4504ac7e8cp+0, -0x1.cdc0p-44, - 0x1.40822c367a0bbp+0, 0x1.5b80p-45, - 0x1.4160a21f72e95p+0, 0x1.ec00p-46, - 0x1.423fb27094646p+0, -0x1.3600p-46, - 0x1.431f5d950a920p+0, 0x1.3980p-45, - 0x1.43ffa3f84b9ebp+0, 0x1.a000p-48, - 0x1.44e0860618919p+0, -0x1.6c00p-48, - 0x1.45c2042a7d201p+0, -0x1.bc00p-47, - 0x1.46a41ed1d0016p+0, -0x1.2800p-46, - 0x1.4786d668b3326p+0, 0x1.0e00p-44, - 0x1.486a2b5c13c00p+0, -0x1.d400p-45, - 0x1.494e1e192af04p+0, 0x1.c200p-47, - 0x1.4a32af0d7d372p+0, -0x1.e500p-46, - 0x1.4b17dea6db801p+0, 0x1.7800p-47, - 0x1.4bfdad53629e1p+0, -0x1.3800p-46, - 0x1.4ce41b817c132p+0, 0x1.0800p-47, - 0x1.4dcb299fddddbp+0, 0x1.c700p-45, - 0x1.4eb2d81d8ab96p+0, -0x1.ce00p-46, - 0x1.4f9b2769d2d02p+0, 0x1.9200p-46, - 0x1.508417f4531c1p+0, -0x1.8c00p-47, - 0x1.516daa2cf662ap+0, -0x1.a000p-48, - 0x1.5257de83f51eap+0, 0x1.a080p-43, - 0x1.5342b569d4edap+0, -0x1.6d80p-45, - 0x1.542e2f4f6ac1ap+0, -0x1.2440p-44, - 0x1.551a4ca5d94dbp+0, 0x1.83c0p-43, - 0x1.56070dde9116bp+0, 0x1.4b00p-45, - 0x1.56f4736b529dep+0, 0x1.15a0p-43, - 0x1.57e27dbe2c40ep+0, -0x1.9e00p-45, - 0x1.58d12d497c76fp+0, -0x1.3080p-45, - 0x1.59c0827ff0b4cp+0, 0x1.dec0p-43, - 0x1.5ab07dd485427p+0, -0x1.4000p-51, - 0x1.5ba11fba87af4p+0, 0x1.0080p-44, - 0x1.5c9268a59460bp+0, -0x1.6c80p-45, - 0x1.5d84590998e3fp+0, 0x1.69a0p-43, - 0x1.5e76f15ad20e1p+0, -0x1.b400p-46, - 0x1.5f6a320dcebcap+0, 0x1.7700p-46, - 0x1.605e1b976dcb8p+0, 0x1.6f80p-45, - 0x1.6152ae6cdf715p+0, 0x1.1000p-47, - 0x1.6247eb03a5531p+0, -0x1.5d00p-46, - 0x1.633dd1d1929b5p+0, -0x1.2d00p-46, - 0x1.6434634ccc313p+0, -0x1.a800p-49, - 0x1.652b9febc8efap+0, -0x1.8600p-45, - 0x1.6623882553397p+0, 0x1.1fe0p-40, - 0x1.671c1c708328ep+0, -0x1.7200p-44, - 0x1.68155d44ca97ep+0, 0x1.6800p-49, - 0x1.690f4b19e9471p+0, -0x1.9780p-45, -}; - -/* - * exp2(x): compute the base 2 exponential of x - * - * Accuracy: Peak error < 0.503 ulp for normalized results. - * - * Method: (accurate tables) - * - * Reduce x: - * x = k + y, for integer k and |y| <= 1/2. - * Thus we have exp2(x) = 2**k * exp2(y). - * - * Reduce y: - * y = i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE. - * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z - eps[i]), - * with |z - eps[i]| <= 2**-9 + 2**-39 for the table used. - * - * We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) via - * a degree-5 minimax polynomial with maximum error under 1.3 * 2**-61. - * The values in exp2t[] and eps[] are chosen such that - * exp2t[i] = exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset such - * that exp2t[i] is accurate to 2**-64. - * - * Note that the range of i is +-TBLSIZE/2, so we actually index the tables - * by i0 = i + TBLSIZE/2. For cache efficiency, exp2t[] and eps[] are - * virtual tables, interleaved in the real table tbl[]. - * - * This method is due to Gal, with many details due to Gal and Bachelis: - * - * Gal, S. and Bachelis, B. An Accurate Elementary Mathematical Library - * for the IEEE Floating Point Standard. TOMS 17(1), 26-46 (1991). - */ -double exp2(double x) -{ - double_t r, t, z; - uint32_t ix, i0; - union {double f; uint64_t i;} u = {x}; - union {uint32_t u; int32_t i;} k; - - /* Filter out exceptional cases. */ - ix = u.i>>32 & 0x7fffffff; - if (ix >= 0x408ff000) { /* |x| >= 1022 or nan */ - if (ix >= 0x40900000 && u.i>>63 == 0) { /* x >= 1024 or nan */ - /* overflow */ - x *= 0x1p1023; - return x; - } - if (ix >= 0x7ff00000) /* -inf or -nan */ - return -1/x; - if (u.i>>63) { /* x <= -1022 */ - /* underflow */ - if (x <= -1075 || x - 0x1p52 + 0x1p52 != x) - FORCE_EVAL((float)(-0x1p-149/x)); - if (x <= -1075) - return 0; - } - } else if (ix < 0x3c900000) { /* |x| < 0x1p-54 */ - return 1.0 + x; - } - - /* Reduce x, computing z, i0, and k. */ - u.f = x + redux; - i0 = u.i; - i0 += TBLSIZE / 2; - k.u = i0 / TBLSIZE * TBLSIZE; - k.i /= TBLSIZE; - i0 %= TBLSIZE; - u.f -= redux; - z = x - u.f; - - /* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */ - t = tbl[2*i0]; /* exp2t[i0] */ - z -= tbl[2*i0 + 1]; /* eps[i0] */ - r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5)))); - - return scalbn(r, k.i); -} diff --git a/waterbox/libc/functions/math/exp2f.c b/waterbox/libc/functions/math/exp2f.c deleted file mode 100644 index 296b63436f..0000000000 --- a/waterbox/libc/functions/math/exp2f.c +++ /dev/null @@ -1,126 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_exp2f.c */ -/*- - * Copyright (c) 2005 David Schultz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "libm.h" - -#define TBLSIZE 16 - -static const float -redux = 0x1.8p23f / TBLSIZE, -P1 = 0x1.62e430p-1f, -P2 = 0x1.ebfbe0p-3f, -P3 = 0x1.c6b348p-5f, -P4 = 0x1.3b2c9cp-7f; - -static const double exp2ft[TBLSIZE] = { - 0x1.6a09e667f3bcdp-1, - 0x1.7a11473eb0187p-1, - 0x1.8ace5422aa0dbp-1, - 0x1.9c49182a3f090p-1, - 0x1.ae89f995ad3adp-1, - 0x1.c199bdd85529cp-1, - 0x1.d5818dcfba487p-1, - 0x1.ea4afa2a490dap-1, - 0x1.0000000000000p+0, - 0x1.0b5586cf9890fp+0, - 0x1.172b83c7d517bp+0, - 0x1.2387a6e756238p+0, - 0x1.306fe0a31b715p+0, - 0x1.3dea64c123422p+0, - 0x1.4bfdad5362a27p+0, - 0x1.5ab07dd485429p+0, -}; - -/* - * exp2f(x): compute the base 2 exponential of x - * - * Accuracy: Peak error < 0.501 ulp; location of peak: -0.030110927. - * - * Method: (equally-spaced tables) - * - * Reduce x: - * x = k + y, for integer k and |y| <= 1/2. - * Thus we have exp2f(x) = 2**k * exp2(y). - * - * Reduce y: - * y = i/TBLSIZE + z for integer i near y * TBLSIZE. - * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z), - * with |z| <= 2**-(TBLSIZE+1). - * - * We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a - * degree-4 minimax polynomial with maximum error under 1.4 * 2**-33. - * Using double precision for everything except the reduction makes - * roundoff error insignificant and simplifies the scaling step. - * - * This method is due to Tang, but I do not use his suggested parameters: - * - * Tang, P. Table-driven Implementation of the Exponential Function - * in IEEE Floating-Point Arithmetic. TOMS 15(2), 144-157 (1989). - */ -float exp2f(float x) -{ - double_t t, r, z; - union {float f; uint32_t i;} u = {x}; - union {double f; uint64_t i;} uk; - uint32_t ix, i0, k; - - /* Filter out exceptional cases. */ - ix = u.i & 0x7fffffff; - if (ix > 0x42fc0000) { /* |x| > 126 */ - if (ix > 0x7f800000) /* NaN */ - return x; - if (u.i >= 0x43000000 && u.i < 0x80000000) { /* x >= 128 */ - x *= 0x1p127f; - return x; - } - if (u.i >= 0x80000000) { /* x < -126 */ - if (u.i >= 0xc3160000 || (u.i & 0x0000ffff)) - FORCE_EVAL(-0x1p-149f/x); - if (u.i >= 0xc3160000) /* x <= -150 */ - return 0; - } - } else if (ix <= 0x33000000) { /* |x| <= 0x1p-25 */ - return 1.0f + x; - } - - /* Reduce x, computing z, i0, and k. */ - u.f = x + redux; - i0 = u.i; - i0 += TBLSIZE / 2; - k = i0 / TBLSIZE; - uk.i = (uint64_t)(0x3ff + k)<<52; - i0 &= TBLSIZE - 1; - u.f -= redux; - z = x - u.f; - /* Compute r = exp2(y) = exp2ft[i0] * p(z). */ - r = exp2ft[i0]; - t = r * z; - r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4); - - /* Scale by 2**k */ - return r * uk.f; -} diff --git a/waterbox/libc/functions/math/exp2l.c b/waterbox/libc/functions/math/exp2l.c deleted file mode 100644 index 3565c1e67d..0000000000 --- a/waterbox/libc/functions/math/exp2l.c +++ /dev/null @@ -1,619 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/ld80/s_exp2l.c and /usr/src/lib/msun/ld128/s_exp2l.c */ -/*- - * Copyright (c) 2005-2008 David Schultz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double exp2l(long double x) -{ - return exp2(x); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -#define TBLBITS 7 -#define TBLSIZE (1 << TBLBITS) - -static const double -redux = 0x1.8p63 / TBLSIZE, -P1 = 0x1.62e42fefa39efp-1, -P2 = 0x1.ebfbdff82c58fp-3, -P3 = 0x1.c6b08d7049fap-5, -P4 = 0x1.3b2ab6fba4da5p-7, -P5 = 0x1.5d8804780a736p-10, -P6 = 0x1.430918835e33dp-13; - -static const double tbl[TBLSIZE * 2] = { - 0x1.6a09e667f3bcdp-1, -0x1.bdd3413b2648p-55, - 0x1.6c012750bdabfp-1, -0x1.2895667ff0cp-57, - 0x1.6dfb23c651a2fp-1, -0x1.bbe3a683c88p-58, - 0x1.6ff7df9519484p-1, -0x1.83c0f25860fp-56, - 0x1.71f75e8ec5f74p-1, -0x1.16e4786887bp-56, - 0x1.73f9a48a58174p-1, -0x1.0a8d96c65d5p-55, - 0x1.75feb564267c9p-1, -0x1.0245957316ep-55, - 0x1.780694fde5d3fp-1, 0x1.866b80a0216p-55, - 0x1.7a11473eb0187p-1, -0x1.41577ee0499p-56, - 0x1.7c1ed0130c132p-1, 0x1.f124cd1164ep-55, - 0x1.7e2f336cf4e62p-1, 0x1.05d02ba157ap-57, - 0x1.80427543e1a12p-1, -0x1.27c86626d97p-55, - 0x1.82589994cce13p-1, -0x1.d4c1dd41533p-55, - 0x1.8471a4623c7adp-1, -0x1.8d684a341cep-56, - 0x1.868d99b4492edp-1, -0x1.fc6f89bd4f68p-55, - 0x1.88ac7d98a6699p-1, 0x1.994c2f37cb5p-55, - 0x1.8ace5422aa0dbp-1, 0x1.6e9f156864bp-55, - 0x1.8cf3216b5448cp-1, -0x1.0d55e32e9e4p-57, - 0x1.8f1ae99157736p-1, 0x1.5cc13a2e397p-56, - 0x1.9145b0b91ffc6p-1, -0x1.dd6792e5825p-55, - 0x1.93737b0cdc5e5p-1, -0x1.75fc781b58p-58, - 0x1.95a44cbc8520fp-1, -0x1.64b7c96a5fp-57, - 0x1.97d829fde4e5p-1, -0x1.d185b7c1b86p-55, - 0x1.9a0f170ca07bap-1, -0x1.173bd91cee6p-55, - 0x1.9c49182a3f09p-1, 0x1.c7c46b071f2p-57, - 0x1.9e86319e32323p-1, 0x1.824ca78e64cp-57, - 0x1.a0c667b5de565p-1, -0x1.359495d1cd5p-55, - 0x1.a309bec4a2d33p-1, 0x1.6305c7ddc368p-55, - 0x1.a5503b23e255dp-1, -0x1.d2f6edb8d42p-55, - 0x1.a799e1330b358p-1, 0x1.bcb7ecac564p-55, - 0x1.a9e6b5579fdbfp-1, 0x1.0fac90ef7fdp-55, - 0x1.ac36bbfd3f37ap-1, -0x1.f9234cae76dp-56, - 0x1.ae89f995ad3adp-1, 0x1.7a1cd345dcc8p-55, - 0x1.b0e07298db666p-1, -0x1.bdef54c80e4p-55, - 0x1.b33a2b84f15fbp-1, -0x1.2805e3084d8p-58, - 0x1.b59728de5593ap-1, -0x1.c71dfbbba6ep-55, - 0x1.b7f76f2fb5e47p-1, -0x1.5584f7e54acp-57, - 0x1.ba5b030a1064ap-1, -0x1.efcd30e5429p-55, - 0x1.bcc1e904bc1d2p-1, 0x1.23dd07a2d9fp-56, - 0x1.bf2c25bd71e09p-1, -0x1.efdca3f6b9c8p-55, - 0x1.c199bdd85529cp-1, 0x1.11065895049p-56, - 0x1.c40ab5fffd07ap-1, 0x1.b4537e083c6p-55, - 0x1.c67f12e57d14bp-1, 0x1.2884dff483c8p-55, - 0x1.c8f6d9406e7b5p-1, 0x1.1acbc48805cp-57, - 0x1.cb720dcef9069p-1, 0x1.503cbd1e94ap-57, - 0x1.cdf0b555dc3fap-1, -0x1.dd83b53829dp-56, - 0x1.d072d4a07897cp-1, -0x1.cbc3743797a8p-55, - 0x1.d2f87080d89f2p-1, -0x1.d487b719d858p-55, - 0x1.d5818dcfba487p-1, 0x1.2ed02d75b37p-56, - 0x1.d80e316c98398p-1, -0x1.11ec18bedep-55, - 0x1.da9e603db3285p-1, 0x1.c2300696db5p-55, - 0x1.dd321f301b46p-1, 0x1.2da5778f019p-55, - 0x1.dfc97337b9b5fp-1, -0x1.1a5cd4f184b8p-55, - 0x1.e264614f5a129p-1, -0x1.7b627817a148p-55, - 0x1.e502ee78b3ff6p-1, 0x1.39e8980a9cdp-56, - 0x1.e7a51fbc74c83p-1, 0x1.2d522ca0c8ep-55, - 0x1.ea4afa2a490dap-1, -0x1.e9c23179c288p-55, - 0x1.ecf482d8e67f1p-1, -0x1.c93f3b411ad8p-55, - 0x1.efa1bee615a27p-1, 0x1.dc7f486a4b68p-55, - 0x1.f252b376bba97p-1, 0x1.3a1a5bf0d8e8p-55, - 0x1.f50765b6e454p-1, 0x1.9d3e12dd8a18p-55, - 0x1.f7bfdad9cbe14p-1, -0x1.dbb12d00635p-55, - 0x1.fa7c1819e90d8p-1, 0x1.74853f3a593p-56, - 0x1.fd3c22b8f71f1p-1, 0x1.2eb74966578p-58, - 0x1p+0, 0x0p+0, - 0x1.0163da9fb3335p+0, 0x1.b61299ab8cd8p-54, - 0x1.02c9a3e778061p+0, -0x1.19083535b08p-56, - 0x1.04315e86e7f85p+0, -0x1.0a31c1977c98p-54, - 0x1.059b0d3158574p+0, 0x1.d73e2a475b4p-55, - 0x1.0706b29ddf6dep+0, -0x1.c91dfe2b13cp-55, - 0x1.0874518759bc8p+0, 0x1.186be4bb284p-57, - 0x1.09e3ecac6f383p+0, 0x1.14878183161p-54, - 0x1.0b5586cf9890fp+0, 0x1.8a62e4adc61p-54, - 0x1.0cc922b7247f7p+0, 0x1.01edc16e24f8p-54, - 0x1.0e3ec32d3d1a2p+0, 0x1.03a1727c58p-59, - 0x1.0fb66affed31bp+0, -0x1.b9bedc44ebcp-57, - 0x1.11301d0125b51p+0, -0x1.6c51039449bp-54, - 0x1.12abdc06c31ccp+0, -0x1.1b514b36ca8p-58, - 0x1.1429aaea92dep+0, -0x1.32fbf9af1368p-54, - 0x1.15a98c8a58e51p+0, 0x1.2406ab9eeabp-55, - 0x1.172b83c7d517bp+0, -0x1.19041b9d78ap-55, - 0x1.18af9388c8deap+0, -0x1.11023d1970f8p-54, - 0x1.1a35beb6fcb75p+0, 0x1.e5b4c7b4969p-55, - 0x1.1bbe084045cd4p+0, -0x1.95386352ef6p-54, - 0x1.1d4873168b9aap+0, 0x1.e016e00a264p-54, - 0x1.1ed5022fcd91dp+0, -0x1.1df98027bb78p-54, - 0x1.2063b88628cd6p+0, 0x1.dc775814a85p-55, - 0x1.21f49917ddc96p+0, 0x1.2a97e9494a6p-55, - 0x1.2387a6e756238p+0, 0x1.9b07eb6c7058p-54, - 0x1.251ce4fb2a63fp+0, 0x1.ac155bef4f5p-55, - 0x1.26b4565e27cddp+0, 0x1.2bd339940eap-55, - 0x1.284dfe1f56381p+0, -0x1.a4c3a8c3f0d8p-54, - 0x1.29e9df51fdee1p+0, 0x1.612e8afad12p-55, - 0x1.2b87fd0dad99p+0, -0x1.10adcd6382p-59, - 0x1.2d285a6e4030bp+0, 0x1.0024754db42p-54, - 0x1.2ecafa93e2f56p+0, 0x1.1ca0f45d524p-56, - 0x1.306fe0a31b715p+0, 0x1.6f46ad23183p-55, - 0x1.32170fc4cd831p+0, 0x1.a9ce78e1804p-55, - 0x1.33c08b26416ffp+0, 0x1.327218436598p-54, - 0x1.356c55f929ff1p+0, -0x1.b5cee5c4e46p-55, - 0x1.371a7373aa9cbp+0, -0x1.63aeabf42ebp-54, - 0x1.38cae6d05d866p+0, -0x1.e958d3c99048p-54, - 0x1.3a7db34e59ff7p+0, -0x1.5e436d661f6p-56, - 0x1.3c32dc313a8e5p+0, -0x1.efff8375d2ap-54, - 0x1.3dea64c123422p+0, 0x1.ada0911f09fp-55, - 0x1.3fa4504ac801cp+0, -0x1.7d023f956fap-54, - 0x1.4160a21f72e2ap+0, -0x1.ef3691c309p-58, - 0x1.431f5d950a897p+0, -0x1.1c7dde35f7ap-55, - 0x1.44e086061892dp+0, 0x1.89b7a04ef8p-59, - 0x1.46a41ed1d0057p+0, 0x1.c944bd1648a8p-54, - 0x1.486a2b5c13cdp+0, 0x1.3c1a3b69062p-56, - 0x1.4a32af0d7d3dep+0, 0x1.9cb62f3d1be8p-54, - 0x1.4bfdad5362a27p+0, 0x1.d4397afec42p-56, - 0x1.4dcb299fddd0dp+0, 0x1.8ecdbbc6a78p-54, - 0x1.4f9b2769d2ca7p+0, -0x1.4b309d25958p-54, - 0x1.516daa2cf6642p+0, -0x1.f768569bd94p-55, - 0x1.5342b569d4f82p+0, -0x1.07abe1db13dp-55, - 0x1.551a4ca5d920fp+0, -0x1.d689cefede6p-55, - 0x1.56f4736b527dap+0, 0x1.9bb2c011d938p-54, - 0x1.58d12d497c7fdp+0, 0x1.295e15b9a1ep-55, - 0x1.5ab07dd485429p+0, 0x1.6324c0546478p-54, - 0x1.5c9268a5946b7p+0, 0x1.c4b1b81698p-60, - 0x1.5e76f15ad2148p+0, 0x1.ba6f93080e68p-54, - 0x1.605e1b976dc09p+0, -0x1.3e2429b56de8p-54, - 0x1.6247eb03a5585p+0, -0x1.383c17e40b48p-54, - 0x1.6434634ccc32p+0, -0x1.c483c759d89p-55, - 0x1.6623882552225p+0, -0x1.bb60987591cp-54, - 0x1.68155d44ca973p+0, 0x1.038ae44f74p-57, -}; - -/* - * exp2l(x): compute the base 2 exponential of x - * - * Accuracy: Peak error < 0.511 ulp. - * - * Method: (equally-spaced tables) - * - * Reduce x: - * x = 2**k + y, for integer k and |y| <= 1/2. - * Thus we have exp2l(x) = 2**k * exp2(y). - * - * Reduce y: - * y = i/TBLSIZE + z for integer i near y * TBLSIZE. - * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z), - * with |z| <= 2**-(TBLBITS+1). - * - * We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a - * degree-6 minimax polynomial with maximum error under 2**-69. - * The table entries each have 104 bits of accuracy, encoded as - * a pair of double precision values. - */ -long double exp2l(long double x) -{ - union ldshape u = {x}; - int e = u.i.se & 0x7fff; - long double r, z; - uint32_t i0; - union {uint32_t u; int32_t i;} k; - - /* Filter out exceptional cases. */ - if (e >= 0x3fff + 13) { /* |x| >= 8192 or x is NaN */ - if (u.i.se >= 0x3fff + 14 && u.i.se >> 15 == 0) - /* overflow */ - return x * 0x1p16383L; - if (e == 0x7fff) /* -inf or -nan */ - return -1/x; - if (x < -16382) { - if (x <= -16446 || x - 0x1p63 + 0x1p63 != x) - /* underflow */ - FORCE_EVAL((float)(-0x1p-149/x)); - if (x <= -16446) - return 0; - } - } else if (e < 0x3fff - 64) { - return 1 + x; - } - - /* - * Reduce x, computing z, i0, and k. The low bits of x + redux - * contain the 16-bit integer part of the exponent (k) followed by - * TBLBITS fractional bits (i0). We use bit tricks to extract these - * as integers, then set z to the remainder. - * - * Example: Suppose x is 0xabc.123456p0 and TBLBITS is 8. - * Then the low-order word of x + redux is 0x000abc12, - * We split this into k = 0xabc and i0 = 0x12 (adjusted to - * index into the table), then we compute z = 0x0.003456p0. - */ - u.f = x + redux; - i0 = u.i.m + TBLSIZE / 2; - k.u = i0 / TBLSIZE * TBLSIZE; - k.i /= TBLSIZE; - i0 %= TBLSIZE; - u.f -= redux; - z = x - u.f; - - /* Compute r = exp2l(y) = exp2lt[i0] * p(z). */ - long double t_hi = tbl[2*i0]; - long double t_lo = tbl[2*i0 + 1]; - /* XXX This gives > 1 ulp errors outside of FE_TONEAREST mode */ - r = t_lo + (t_hi + t_lo) * z * (P1 + z * (P2 + z * (P3 + z * (P4 - + z * (P5 + z * P6))))) + t_hi; - - return scalbnl(r, k.i); -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -#define TBLBITS 7 -#define TBLSIZE (1 << TBLBITS) - -static const long double - P1 = 0x1.62e42fefa39ef35793c7673007e6p-1L, - P2 = 0x1.ebfbdff82c58ea86f16b06ec9736p-3L, - P3 = 0x1.c6b08d704a0bf8b33a762bad3459p-5L, - P4 = 0x1.3b2ab6fba4e7729ccbbe0b4f3fc2p-7L, - P5 = 0x1.5d87fe78a67311071dee13fd11d9p-10L, - P6 = 0x1.430912f86c7876f4b663b23c5fe5p-13L; - -static const double - P7 = 0x1.ffcbfc588b041p-17, - P8 = 0x1.62c0223a5c7c7p-20, - P9 = 0x1.b52541ff59713p-24, - P10 = 0x1.e4cf56a391e22p-28, - redux = 0x1.8p112 / TBLSIZE; - -static const long double tbl[TBLSIZE] = { - 0x1.6a09e667f3bcc908b2fb1366dfeap-1L, - 0x1.6c012750bdabeed76a99800f4edep-1L, - 0x1.6dfb23c651a2ef220e2cbe1bc0d4p-1L, - 0x1.6ff7df9519483cf87e1b4f3e1e98p-1L, - 0x1.71f75e8ec5f73dd2370f2ef0b148p-1L, - 0x1.73f9a48a58173bd5c9a4e68ab074p-1L, - 0x1.75feb564267c8bf6e9aa33a489a8p-1L, - 0x1.780694fde5d3f619ae02808592a4p-1L, - 0x1.7a11473eb0186d7d51023f6ccb1ap-1L, - 0x1.7c1ed0130c1327c49334459378dep-1L, - 0x1.7e2f336cf4e62105d02ba1579756p-1L, - 0x1.80427543e1a11b60de67649a3842p-1L, - 0x1.82589994cce128acf88afab34928p-1L, - 0x1.8471a4623c7acce52f6b97c6444cp-1L, - 0x1.868d99b4492ec80e41d90ac2556ap-1L, - 0x1.88ac7d98a669966530bcdf2d4cc0p-1L, - 0x1.8ace5422aa0db5ba7c55a192c648p-1L, - 0x1.8cf3216b5448bef2aa1cd161c57ap-1L, - 0x1.8f1ae991577362b982745c72eddap-1L, - 0x1.9145b0b91ffc588a61b469f6b6a0p-1L, - 0x1.93737b0cdc5e4f4501c3f2540ae8p-1L, - 0x1.95a44cbc8520ee9b483695a0e7fep-1L, - 0x1.97d829fde4e4f8b9e920f91e8eb6p-1L, - 0x1.9a0f170ca07b9ba3109b8c467844p-1L, - 0x1.9c49182a3f0901c7c46b071f28dep-1L, - 0x1.9e86319e323231824ca78e64c462p-1L, - 0x1.a0c667b5de564b29ada8b8cabbacp-1L, - 0x1.a309bec4a2d3358c171f770db1f4p-1L, - 0x1.a5503b23e255c8b424491caf88ccp-1L, - 0x1.a799e1330b3586f2dfb2b158f31ep-1L, - 0x1.a9e6b5579fdbf43eb243bdff53a2p-1L, - 0x1.ac36bbfd3f379c0db966a3126988p-1L, - 0x1.ae89f995ad3ad5e8734d17731c80p-1L, - 0x1.b0e07298db66590842acdfc6fb4ep-1L, - 0x1.b33a2b84f15faf6bfd0e7bd941b0p-1L, - 0x1.b59728de559398e3881111648738p-1L, - 0x1.b7f76f2fb5e46eaa7b081ab53ff6p-1L, - 0x1.ba5b030a10649840cb3c6af5b74cp-1L, - 0x1.bcc1e904bc1d2247ba0f45b3d06cp-1L, - 0x1.bf2c25bd71e088408d7025190cd0p-1L, - 0x1.c199bdd85529c2220cb12a0916bap-1L, - 0x1.c40ab5fffd07a6d14df820f17deap-1L, - 0x1.c67f12e57d14b4a2137fd20f2a26p-1L, - 0x1.c8f6d9406e7b511acbc48805c3f6p-1L, - 0x1.cb720dcef90691503cbd1e949d0ap-1L, - 0x1.cdf0b555dc3f9c44f8958fac4f12p-1L, - 0x1.d072d4a07897b8d0f22f21a13792p-1L, - 0x1.d2f87080d89f18ade123989ea50ep-1L, - 0x1.d5818dcfba48725da05aeb66dff8p-1L, - 0x1.d80e316c98397bb84f9d048807a0p-1L, - 0x1.da9e603db3285708c01a5b6d480cp-1L, - 0x1.dd321f301b4604b695de3c0630c0p-1L, - 0x1.dfc97337b9b5eb968cac39ed284cp-1L, - 0x1.e264614f5a128a12761fa17adc74p-1L, - 0x1.e502ee78b3ff6273d130153992d0p-1L, - 0x1.e7a51fbc74c834b548b2832378a4p-1L, - 0x1.ea4afa2a490d9858f73a18f5dab4p-1L, - 0x1.ecf482d8e67f08db0312fb949d50p-1L, - 0x1.efa1bee615a27771fd21a92dabb6p-1L, - 0x1.f252b376bba974e8696fc3638f24p-1L, - 0x1.f50765b6e4540674f84b762861a6p-1L, - 0x1.f7bfdad9cbe138913b4bfe72bd78p-1L, - 0x1.fa7c1819e90d82e90a7e74b26360p-1L, - 0x1.fd3c22b8f71f10975ba4b32bd006p-1L, - 0x1.0000000000000000000000000000p+0L, - 0x1.0163da9fb33356d84a66ae336e98p+0L, - 0x1.02c9a3e778060ee6f7caca4f7a18p+0L, - 0x1.04315e86e7f84bd738f9a20da442p+0L, - 0x1.059b0d31585743ae7c548eb68c6ap+0L, - 0x1.0706b29ddf6ddc6dc403a9d87b1ep+0L, - 0x1.0874518759bc808c35f25d942856p+0L, - 0x1.09e3ecac6f3834521e060c584d5cp+0L, - 0x1.0b5586cf9890f6298b92b7184200p+0L, - 0x1.0cc922b7247f7407b705b893dbdep+0L, - 0x1.0e3ec32d3d1a2020742e4f8af794p+0L, - 0x1.0fb66affed31af232091dd8a169ep+0L, - 0x1.11301d0125b50a4ebbf1aed9321cp+0L, - 0x1.12abdc06c31cbfb92bad324d6f84p+0L, - 0x1.1429aaea92ddfb34101943b2588ep+0L, - 0x1.15a98c8a58e512480d573dd562aep+0L, - 0x1.172b83c7d517adcdf7c8c50eb162p+0L, - 0x1.18af9388c8de9bbbf70b9a3c269cp+0L, - 0x1.1a35beb6fcb753cb698f692d2038p+0L, - 0x1.1bbe084045cd39ab1e72b442810ep+0L, - 0x1.1d4873168b9aa7805b8028990be8p+0L, - 0x1.1ed5022fcd91cb8819ff61121fbep+0L, - 0x1.2063b88628cd63b8eeb0295093f6p+0L, - 0x1.21f49917ddc962552fd29294bc20p+0L, - 0x1.2387a6e75623866c1fadb1c159c0p+0L, - 0x1.251ce4fb2a63f3582ab7de9e9562p+0L, - 0x1.26b4565e27cdd257a673281d3068p+0L, - 0x1.284dfe1f5638096cf15cf03c9fa0p+0L, - 0x1.29e9df51fdee12c25d15f5a25022p+0L, - 0x1.2b87fd0dad98ffddea46538fca24p+0L, - 0x1.2d285a6e4030b40091d536d0733ep+0L, - 0x1.2ecafa93e2f5611ca0f45d5239a4p+0L, - 0x1.306fe0a31b7152de8d5a463063bep+0L, - 0x1.32170fc4cd8313539cf1c3009330p+0L, - 0x1.33c08b26416ff4c9c8610d96680ep+0L, - 0x1.356c55f929ff0c94623476373be4p+0L, - 0x1.371a7373aa9caa7145502f45452ap+0L, - 0x1.38cae6d05d86585a9cb0d9bed530p+0L, - 0x1.3a7db34e59ff6ea1bc9299e0a1fep+0L, - 0x1.3c32dc313a8e484001f228b58cf0p+0L, - 0x1.3dea64c12342235b41223e13d7eep+0L, - 0x1.3fa4504ac801ba0bf701aa417b9cp+0L, - 0x1.4160a21f72e29f84325b8f3dbacap+0L, - 0x1.431f5d950a896dc704439410b628p+0L, - 0x1.44e086061892d03136f409df0724p+0L, - 0x1.46a41ed1d005772512f459229f0ap+0L, - 0x1.486a2b5c13cd013c1a3b69062f26p+0L, - 0x1.4a32af0d7d3de672d8bcf46f99b4p+0L, - 0x1.4bfdad5362a271d4397afec42e36p+0L, - 0x1.4dcb299fddd0d63b36ef1a9e19dep+0L, - 0x1.4f9b2769d2ca6ad33d8b69aa0b8cp+0L, - 0x1.516daa2cf6641c112f52c84d6066p+0L, - 0x1.5342b569d4f81df0a83c49d86bf4p+0L, - 0x1.551a4ca5d920ec52ec620243540cp+0L, - 0x1.56f4736b527da66ecb004764e61ep+0L, - 0x1.58d12d497c7fd252bc2b7343d554p+0L, - 0x1.5ab07dd48542958c93015191e9a8p+0L, - 0x1.5c9268a5946b701c4b1b81697ed4p+0L, - 0x1.5e76f15ad21486e9be4c20399d12p+0L, - 0x1.605e1b976dc08b076f592a487066p+0L, - 0x1.6247eb03a5584b1f0fa06fd2d9eap+0L, - 0x1.6434634ccc31fc76f8714c4ee122p+0L, - 0x1.66238825522249127d9e29b92ea2p+0L, - 0x1.68155d44ca973081c57227b9f69ep+0L, -}; - -static const float eps[TBLSIZE] = { - -0x1.5c50p-101, - -0x1.5d00p-106, - 0x1.8e90p-102, - -0x1.5340p-103, - 0x1.1bd0p-102, - -0x1.4600p-105, - -0x1.7a40p-104, - 0x1.d590p-102, - -0x1.d590p-101, - 0x1.b100p-103, - -0x1.0d80p-105, - 0x1.6b00p-103, - -0x1.9f00p-105, - 0x1.c400p-103, - 0x1.e120p-103, - -0x1.c100p-104, - -0x1.9d20p-103, - 0x1.a800p-108, - 0x1.4c00p-106, - -0x1.9500p-106, - 0x1.6900p-105, - -0x1.29d0p-100, - 0x1.4c60p-103, - 0x1.13a0p-102, - -0x1.5b60p-103, - -0x1.1c40p-103, - 0x1.db80p-102, - 0x1.91a0p-102, - 0x1.dc00p-105, - 0x1.44c0p-104, - 0x1.9710p-102, - 0x1.8760p-103, - -0x1.a720p-103, - 0x1.ed20p-103, - -0x1.49c0p-102, - -0x1.e000p-111, - 0x1.86a0p-103, - 0x1.2b40p-103, - -0x1.b400p-108, - 0x1.1280p-99, - -0x1.02d8p-102, - -0x1.e3d0p-103, - -0x1.b080p-105, - -0x1.f100p-107, - -0x1.16c0p-105, - -0x1.1190p-103, - -0x1.a7d2p-100, - 0x1.3450p-103, - -0x1.67c0p-105, - 0x1.4b80p-104, - -0x1.c4e0p-103, - 0x1.6000p-108, - -0x1.3f60p-105, - 0x1.93f0p-104, - 0x1.5fe0p-105, - 0x1.6f80p-107, - -0x1.7600p-106, - 0x1.21e0p-106, - -0x1.3a40p-106, - -0x1.40c0p-104, - -0x1.9860p-105, - -0x1.5d40p-108, - -0x1.1d70p-106, - 0x1.2760p-105, - 0x0.0000p+0, - 0x1.21e2p-104, - -0x1.9520p-108, - -0x1.5720p-106, - -0x1.4810p-106, - -0x1.be00p-109, - 0x1.0080p-105, - -0x1.5780p-108, - -0x1.d460p-105, - -0x1.6140p-105, - 0x1.4630p-104, - 0x1.ad50p-103, - 0x1.82e0p-105, - 0x1.1d3cp-101, - 0x1.6100p-107, - 0x1.ec30p-104, - 0x1.f200p-108, - 0x1.0b40p-103, - 0x1.3660p-102, - 0x1.d9d0p-103, - -0x1.02d0p-102, - 0x1.b070p-103, - 0x1.b9c0p-104, - -0x1.01c0p-103, - -0x1.dfe0p-103, - 0x1.1b60p-104, - -0x1.ae94p-101, - -0x1.3340p-104, - 0x1.b3d8p-102, - -0x1.6e40p-105, - -0x1.3670p-103, - 0x1.c140p-104, - 0x1.1840p-101, - 0x1.1ab0p-102, - -0x1.a400p-104, - 0x1.1f00p-104, - -0x1.7180p-103, - 0x1.4ce0p-102, - 0x1.9200p-107, - -0x1.54c0p-103, - 0x1.1b80p-105, - -0x1.1828p-101, - 0x1.5720p-102, - -0x1.a060p-100, - 0x1.9160p-102, - 0x1.a280p-104, - 0x1.3400p-107, - 0x1.2b20p-102, - 0x1.7800p-108, - 0x1.cfd0p-101, - 0x1.2ef0p-102, - -0x1.2760p-99, - 0x1.b380p-104, - 0x1.0048p-101, - -0x1.60b0p-102, - 0x1.a1ccp-100, - -0x1.a640p-104, - -0x1.08a0p-101, - 0x1.7e60p-102, - 0x1.22c0p-103, - -0x1.7200p-106, - 0x1.f0f0p-102, - 0x1.eb4ep-99, - 0x1.c6e0p-103, -}; - -/* - * exp2l(x): compute the base 2 exponential of x - * - * Accuracy: Peak error < 0.502 ulp. - * - * Method: (accurate tables) - * - * Reduce x: - * x = 2**k + y, for integer k and |y| <= 1/2. - * Thus we have exp2(x) = 2**k * exp2(y). - * - * Reduce y: - * y = i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE. - * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z - eps[i]), - * with |z - eps[i]| <= 2**-8 + 2**-98 for the table used. - * - * We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) via - * a degree-10 minimax polynomial with maximum error under 2**-120. - * The values in exp2t[] and eps[] are chosen such that - * exp2t[i] = exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset such - * that exp2t[i] is accurate to 2**-122. - * - * Note that the range of i is +-TBLSIZE/2, so we actually index the tables - * by i0 = i + TBLSIZE/2. - * - * This method is due to Gal, with many details due to Gal and Bachelis: - * - * Gal, S. and Bachelis, B. An Accurate Elementary Mathematical Library - * for the IEEE Floating Point Standard. TOMS 17(1), 26-46 (1991). - */ -long double -exp2l(long double x) -{ - union ldshape u = {x}; - int e = u.i.se & 0x7fff; - long double r, z, t; - uint32_t i0; - union {uint32_t u; int32_t i;} k; - - /* Filter out exceptional cases. */ - if (e >= 0x3fff + 14) { /* |x| >= 16384 or x is NaN */ - if (u.i.se >= 0x3fff + 15 && u.i.se >> 15 == 0) - /* overflow */ - return x * 0x1p16383L; - if (e == 0x7fff) /* -inf or -nan */ - return -1/x; - if (x < -16382) { - if (x <= -16495 || x - 0x1p112 + 0x1p112 != x) - /* underflow */ - FORCE_EVAL((float)(-0x1p-149/x)); - if (x <= -16446) - return 0; - } - } else if (e < 0x3fff - 114) { - return 1 + x; - } - - /* - * Reduce x, computing z, i0, and k. The low bits of x + redux - * contain the 16-bit integer part of the exponent (k) followed by - * TBLBITS fractional bits (i0). We use bit tricks to extract these - * as integers, then set z to the remainder. - * - * Example: Suppose x is 0xabc.123456p0 and TBLBITS is 8. - * Then the low-order word of x + redux is 0x000abc12, - * We split this into k = 0xabc and i0 = 0x12 (adjusted to - * index into the table), then we compute z = 0x0.003456p0. - */ - u.f = x + redux; - i0 = u.i2.lo + TBLSIZE / 2; - k.u = i0 / TBLSIZE * TBLSIZE; - k.i /= TBLSIZE; - i0 %= TBLSIZE; - u.f -= redux; - z = x - u.f; - - /* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */ - t = tbl[i0]; - z -= eps[i0]; - r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * (P5 + z * (P6 - + z * (P7 + z * (P8 + z * (P9 + z * P10))))))))); - - return scalbnl(r, k.i); -} -#endif diff --git a/waterbox/libc/functions/math/expf.c b/waterbox/libc/functions/math/expf.c deleted file mode 100644 index feee2b0ed2..0000000000 --- a/waterbox/libc/functions/math/expf.c +++ /dev/null @@ -1,83 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_expf.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" - -static const float -half[2] = {0.5,-0.5}, -ln2hi = 6.9314575195e-1f, /* 0x3f317200 */ -ln2lo = 1.4286067653e-6f, /* 0x35bfbe8e */ -invln2 = 1.4426950216e+0f, /* 0x3fb8aa3b */ -/* - * Domain [-0.34568, 0.34568], range ~[-4.278e-9, 4.447e-9]: - * |x*(exp(x)+1)/(exp(x)-1) - p(x)| < 2**-27.74 - */ -P1 = 1.6666625440e-1f, /* 0xaaaa8f.0p-26 */ -P2 = -2.7667332906e-3f; /* -0xb55215.0p-32 */ - -float expf(float x) -{ - float_t hi, lo, c, xx, y; - int k, sign; - uint32_t hx; - - GET_FLOAT_WORD(hx, x); - sign = hx >> 31; /* sign bit of x */ - hx &= 0x7fffffff; /* high word of |x| */ - - /* special cases */ - if (hx >= 0x42aeac50) { /* if |x| >= -87.33655f or NaN */ - if (hx > 0x7f800000) /* NaN */ - return x; - if (hx >= 0x42b17218 && !sign) { /* x >= 88.722839f */ - /* overflow */ - x *= 0x1p127f; - return x; - } - if (sign) { - /* underflow */ - FORCE_EVAL(-0x1p-149f/x); - if (hx >= 0x42cff1b5) /* x <= -103.972084f */ - return 0; - } - } - - /* argument reduction */ - if (hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */ - if (hx > 0x3f851592) /* if |x| > 1.5 ln2 */ - k = invln2*x + half[sign]; - else - k = 1 - sign - sign; - hi = x - k*ln2hi; /* k*ln2hi is exact here */ - lo = k*ln2lo; - x = hi - lo; - } else if (hx > 0x39000000) { /* |x| > 2**-14 */ - k = 0; - hi = x; - lo = 0; - } else { - /* raise inexact */ - FORCE_EVAL(0x1p127f + x); - return 1 + x; - } - - /* x is now in primary range */ - xx = x*x; - c = x - xx*(P1+xx*P2); - y = 1 + (x*c/(2-c) - lo + hi); - if (k == 0) - return y; - return scalbnf(y, k); -} diff --git a/waterbox/libc/functions/math/expl.c b/waterbox/libc/functions/math/expl.c deleted file mode 100644 index 0a7f44f685..0000000000 --- a/waterbox/libc/functions/math/expl.c +++ /dev/null @@ -1,128 +0,0 @@ -/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_expl.c */ -/* - * Copyright (c) 2008 Stephen L. Moshier - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/* - * Exponential function, long double precision - * - * - * SYNOPSIS: - * - * long double x, y, expl(); - * - * y = expl( x ); - * - * - * DESCRIPTION: - * - * Returns e (2.71828...) raised to the x power. - * - * Range reduction is accomplished by separating the argument - * into an integer k and fraction f such that - * - * x k f - * e = 2 e. - * - * A Pade' form of degree 5/6 is used to approximate exp(f) - 1 - * in the basic range [-0.5 ln 2, 0.5 ln 2]. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-10000 50000 1.12e-19 2.81e-20 - * - * - * Error amplification in the exponential function can be - * a serious matter. The error propagation involves - * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ), - * which shows that a 1 lsb error in representing X produces - * a relative error of X times 1 lsb in the function. - * While the routine gives an accurate result for arguments - * that are exactly represented by a long double precision - * computer number, the result contains amplified roundoff - * error for large arguments not exactly represented. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * exp underflow x < MINLOG 0.0 - * exp overflow x > MAXLOG MAXNUM - * - */ - -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double expl(long double x) -{ - return exp(x); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 - -static const long double P[3] = { - 1.2617719307481059087798E-4L, - 3.0299440770744196129956E-2L, - 9.9999999999999999991025E-1L, -}; -static const long double Q[4] = { - 3.0019850513866445504159E-6L, - 2.5244834034968410419224E-3L, - 2.2726554820815502876593E-1L, - 2.0000000000000000000897E0L, -}; -static const long double -LN2HI = 6.9314575195312500000000E-1L, -LN2LO = 1.4286068203094172321215E-6L, -LOG2E = 1.4426950408889634073599E0L; - -long double expl(long double x) -{ - long double px, xx; - int k; - - if (isnan(x)) - return x; - if (x > 11356.5234062941439488L) /* x > ln(2^16384 - 0.5) */ - return x * 0x1p16383L; - if (x < -11399.4985314888605581L) /* x < ln(2^-16446) */ - return -0x1p-16445L/x; - - /* Express e**x = e**f 2**k - * = e**(f + k ln(2)) - */ - px = floorl(LOG2E * x + 0.5); - k = px; - x -= px * LN2HI; - x -= px * LN2LO; - - /* rational approximation of the fractional part: - * e**x = 1 + 2x P(x**2)/(Q(x**2) - x P(x**2)) - */ - xx = x * x; - px = x * __polevll(xx, P, 2); - x = px/(__polevll(xx, Q, 3) - px); - x = 1.0 + 2.0 * x; - return scalbnl(x, k); -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -// TODO: broken implementation to make things compile -long double expl(long double x) -{ - return exp(x); -} -#endif diff --git a/waterbox/libc/functions/math/expm1.c b/waterbox/libc/functions/math/expm1.c deleted file mode 100644 index ac1e61e4f7..0000000000 --- a/waterbox/libc/functions/math/expm1.c +++ /dev/null @@ -1,201 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_expm1.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* expm1(x) - * Returns exp(x)-1, the exponential of x minus 1. - * - * Method - * 1. Argument reduction: - * Given x, find r and integer k such that - * - * x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658 - * - * Here a correction term c will be computed to compensate - * the error in r when rounded to a floating-point number. - * - * 2. Approximating expm1(r) by a special rational function on - * the interval [0,0.34658]: - * Since - * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ... - * we define R1(r*r) by - * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r) - * That is, - * R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r) - * = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r)) - * = 1 - r^2/60 + r^4/2520 - r^6/100800 + ... - * We use a special Remez algorithm on [0,0.347] to generate - * a polynomial of degree 5 in r*r to approximate R1. The - * maximum error of this polynomial approximation is bounded - * by 2**-61. In other words, - * R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5 - * where Q1 = -1.6666666666666567384E-2, - * Q2 = 3.9682539681370365873E-4, - * Q3 = -9.9206344733435987357E-6, - * Q4 = 2.5051361420808517002E-7, - * Q5 = -6.2843505682382617102E-9; - * z = r*r, - * with error bounded by - * | 5 | -61 - * | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2 - * | | - * - * expm1(r) = exp(r)-1 is then computed by the following - * specific way which minimize the accumulation rounding error: - * 2 3 - * r r [ 3 - (R1 + R1*r/2) ] - * expm1(r) = r + --- + --- * [--------------------] - * 2 2 [ 6 - r*(3 - R1*r/2) ] - * - * To compensate the error in the argument reduction, we use - * expm1(r+c) = expm1(r) + c + expm1(r)*c - * ~ expm1(r) + c + r*c - * Thus c+r*c will be added in as the correction terms for - * expm1(r+c). Now rearrange the term to avoid optimization - * screw up: - * ( 2 2 ) - * ({ ( r [ R1 - (3 - R1*r/2) ] ) } r ) - * expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- ) - * ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 ) - * ( ) - * - * = r - E - * 3. Scale back to obtain expm1(x): - * From step 1, we have - * expm1(x) = either 2^k*[expm1(r)+1] - 1 - * = or 2^k*[expm1(r) + (1-2^-k)] - * 4. Implementation notes: - * (A). To save one multiplication, we scale the coefficient Qi - * to Qi*2^i, and replace z by (x^2)/2. - * (B). To achieve maximum accuracy, we compute expm1(x) by - * (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf) - * (ii) if k=0, return r-E - * (iii) if k=-1, return 0.5*(r-E)-0.5 - * (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E) - * else return 1.0+2.0*(r-E); - * (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1) - * (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else - * (vii) return 2^k(1-((E+2^-k)-r)) - * - * Special cases: - * expm1(INF) is INF, expm1(NaN) is NaN; - * expm1(-INF) is -1, and - * for finite argument, only expm1(0)=0 is exact. - * - * Accuracy: - * according to an error analysis, the error is always less than - * 1 ulp (unit in the last place). - * - * Misc. info. - * For IEEE double - * if x > 7.09782712893383973096e+02 then expm1(x) overflow - * - * Constants: - * The hexadecimal values are the intended ones for the following - * constants. The decimal values may be used, provided that the - * compiler will convert from decimal to binary accurately enough - * to produce the hexadecimal values shown. - */ - -#include "libm.h" - -static const double -o_threshold = 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */ -ln2_hi = 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */ -ln2_lo = 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */ -invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */ -/* Scaled Q's: Qn_here = 2**n * Qn_above, for R(2*z) where z = hxs = x*x/2: */ -Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */ -Q2 = 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */ -Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */ -Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */ -Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */ - -double expm1(double x) -{ - double_t y,hi,lo,c,t,e,hxs,hfx,r1,twopk; - union {double f; uint64_t i;} u = {x}; - uint32_t hx = u.i>>32 & 0x7fffffff; - int k, sign = u.i>>63; - - /* filter out huge and non-finite argument */ - if (hx >= 0x4043687A) { /* if |x|>=56*ln2 */ - if (isnan(x)) - return x; - if (sign) - return -1; - if (x > o_threshold) { - x *= 0x1p1023; - return x; - } - } - - /* argument reduction */ - if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ - if (hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ - if (!sign) { - hi = x - ln2_hi; - lo = ln2_lo; - k = 1; - } else { - hi = x + ln2_hi; - lo = -ln2_lo; - k = -1; - } - } else { - k = invln2*x + (sign ? -0.5 : 0.5); - t = k; - hi = x - t*ln2_hi; /* t*ln2_hi is exact here */ - lo = t*ln2_lo; - } - x = hi-lo; - c = (hi-x)-lo; - } else if (hx < 0x3c900000) { /* |x| < 2**-54, return x */ - if (hx < 0x00100000) - FORCE_EVAL((float)x); - return x; - } else - k = 0; - - /* x is now in primary range */ - hfx = 0.5*x; - hxs = x*hfx; - r1 = 1.0+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5)))); - t = 3.0-r1*hfx; - e = hxs*((r1-t)/(6.0 - x*t)); - if (k == 0) /* c is 0 */ - return x - (x*e-hxs); - e = x*(e-c) - c; - e -= hxs; - /* exp(x) ~ 2^k (x_reduced - e + 1) */ - if (k == -1) - return 0.5*(x-e) - 0.5; - if (k == 1) { - if (x < -0.25) - return -2.0*(e-(x+0.5)); - return 1.0+2.0*(x-e); - } - u.i = (uint64_t)(0x3ff + k)<<52; /* 2^k */ - twopk = u.f; - if (k < 0 || k > 56) { /* suffice to return exp(x)-1 */ - y = x - e + 1.0; - if (k == 1024) - y = y*2.0*0x1p1023; - else - y = y*twopk; - return y - 1.0; - } - u.i = (uint64_t)(0x3ff - k)<<52; /* 2^-k */ - if (k < 20) - y = (x-e+(1-u.f))*twopk; - else - y = (x-(e+u.f)+1)*twopk; - return y; -} diff --git a/waterbox/libc/functions/math/expm1f.c b/waterbox/libc/functions/math/expm1f.c deleted file mode 100644 index 297e0b44a2..0000000000 --- a/waterbox/libc/functions/math/expm1f.c +++ /dev/null @@ -1,111 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_expm1f.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" - -static const float -o_threshold = 8.8721679688e+01, /* 0x42b17180 */ -ln2_hi = 6.9313812256e-01, /* 0x3f317180 */ -ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */ -invln2 = 1.4426950216e+00, /* 0x3fb8aa3b */ -/* - * Domain [-0.34568, 0.34568], range ~[-6.694e-10, 6.696e-10]: - * |6 / x * (1 + 2 * (1 / (exp(x) - 1) - 1 / x)) - q(x)| < 2**-30.04 - * Scaled coefficients: Qn_here = 2**n * Qn_for_q (see s_expm1.c): - */ -Q1 = -3.3333212137e-2, /* -0x888868.0p-28 */ -Q2 = 1.5807170421e-3; /* 0xcf3010.0p-33 */ - -float expm1f(float x) -{ - float_t y,hi,lo,c,t,e,hxs,hfx,r1,twopk; - union {float f; uint32_t i;} u = {x}; - uint32_t hx = u.i & 0x7fffffff; - int k, sign = u.i >> 31; - - /* filter out huge and non-finite argument */ - if (hx >= 0x4195b844) { /* if |x|>=27*ln2 */ - if (hx > 0x7f800000) /* NaN */ - return x; - if (sign) - return -1; - if (x > o_threshold) { - x *= 0x1p127f; - return x; - } - } - - /* argument reduction */ - if (hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */ - if (hx < 0x3F851592) { /* and |x| < 1.5 ln2 */ - if (!sign) { - hi = x - ln2_hi; - lo = ln2_lo; - k = 1; - } else { - hi = x + ln2_hi; - lo = -ln2_lo; - k = -1; - } - } else { - k = invln2*x + (sign ? -0.5f : 0.5f); - t = k; - hi = x - t*ln2_hi; /* t*ln2_hi is exact here */ - lo = t*ln2_lo; - } - x = hi-lo; - c = (hi-x)-lo; - } else if (hx < 0x33000000) { /* when |x|<2**-25, return x */ - if (hx < 0x00800000) - FORCE_EVAL(x*x); - return x; - } else - k = 0; - - /* x is now in primary range */ - hfx = 0.5f*x; - hxs = x*hfx; - r1 = 1.0f+hxs*(Q1+hxs*Q2); - t = 3.0f - r1*hfx; - e = hxs*((r1-t)/(6.0f - x*t)); - if (k == 0) /* c is 0 */ - return x - (x*e-hxs); - e = x*(e-c) - c; - e -= hxs; - /* exp(x) ~ 2^k (x_reduced - e + 1) */ - if (k == -1) - return 0.5f*(x-e) - 0.5f; - if (k == 1) { - if (x < -0.25f) - return -2.0f*(e-(x+0.5f)); - return 1.0f + 2.0f*(x-e); - } - u.i = (0x7f+k)<<23; /* 2^k */ - twopk = u.f; - if (k < 0 || k > 56) { /* suffice to return exp(x)-1 */ - y = x - e + 1.0f; - if (k == 128) - y = y*2.0f*0x1p127f; - else - y = y*twopk; - return y - 1.0f; - } - u.i = (0x7f-k)<<23; /* 2^-k */ - if (k < 23) - y = (x-e+(1-u.f))*twopk; - else - y = (x-(e+u.f)+1)*twopk; - return y; -} diff --git a/waterbox/libc/functions/math/expm1l.c b/waterbox/libc/functions/math/expm1l.c deleted file mode 100644 index d171507852..0000000000 --- a/waterbox/libc/functions/math/expm1l.c +++ /dev/null @@ -1,123 +0,0 @@ -/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_expm1l.c */ -/* - * Copyright (c) 2008 Stephen L. Moshier - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/* - * Exponential function, minus 1 - * Long double precision - * - * - * SYNOPSIS: - * - * long double x, y, expm1l(); - * - * y = expm1l( x ); - * - * - * DESCRIPTION: - * - * Returns e (2.71828...) raised to the x power, minus 1. - * - * Range reduction is accomplished by separating the argument - * into an integer k and fraction f such that - * - * x k f - * e = 2 e. - * - * An expansion x + .5 x^2 + x^3 R(x) approximates exp(f) - 1 - * in the basic range [-0.5 ln 2, 0.5 ln 2]. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -45,+maxarg 200,000 1.2e-19 2.5e-20 - */ - -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double expm1l(long double x) -{ - return expm1(x); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 - -/* exp(x) - 1 = x + 0.5 x^2 + x^3 P(x)/Q(x) - -.5 ln 2 < x < .5 ln 2 - Theoretical peak relative error = 3.4e-22 */ -static const long double -P0 = -1.586135578666346600772998894928250240826E4L, -P1 = 2.642771505685952966904660652518429479531E3L, -P2 = -3.423199068835684263987132888286791620673E2L, -P3 = 1.800826371455042224581246202420972737840E1L, -P4 = -5.238523121205561042771939008061958820811E-1L, -Q0 = -9.516813471998079611319047060563358064497E4L, -Q1 = 3.964866271411091674556850458227710004570E4L, -Q2 = -7.207678383830091850230366618190187434796E3L, -Q3 = 7.206038318724600171970199625081491823079E2L, -Q4 = -4.002027679107076077238836622982900945173E1L, -/* Q5 = 1.000000000000000000000000000000000000000E0 */ -/* C1 + C2 = ln 2 */ -C1 = 6.93145751953125E-1L, -C2 = 1.428606820309417232121458176568075500134E-6L, -/* ln 2^-65 */ -minarg = -4.5054566736396445112120088E1L, -/* ln 2^16384 */ -maxarg = 1.1356523406294143949492E4L; - -long double expm1l(long double x) -{ - long double px, qx, xx; - int k; - - if (isnan(x)) - return x; - if (x > maxarg) - return x*0x1p16383L; /* overflow, unless x==inf */ - if (x == 0.0) - return x; - if (x < minarg) - return -1.0; - - xx = C1 + C2; - /* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */ - px = floorl(0.5 + x / xx); - k = px; - /* remainder times ln 2 */ - x -= px * C1; - x -= px * C2; - - /* Approximate exp(remainder ln 2).*/ - px = (((( P4 * x + P3) * x + P2) * x + P1) * x + P0) * x; - qx = (((( x + Q4) * x + Q3) * x + Q2) * x + Q1) * x + Q0; - xx = x * x; - qx = x + (0.5 * xx + xx * px / qx); - - /* exp(x) = exp(k ln 2) exp(remainder ln 2) = 2^k exp(remainder ln 2). - We have qx = exp(remainder ln 2) - 1, so - exp(x) - 1 = 2^k (qx + 1) - 1 = 2^k qx + 2^k - 1. */ - px = scalbnl(1.0, k); - x = px * qx + (px - 1.0); - return x; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -// TODO: broken implementation to make things compile -long double expm1l(long double x) -{ - return expm1(x); -} -#endif diff --git a/waterbox/libc/functions/math/fabs.c b/waterbox/libc/functions/math/fabs.c deleted file mode 100644 index e8258cfdbc..0000000000 --- a/waterbox/libc/functions/math/fabs.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -double fabs(double x) -{ - union {double f; uint64_t i;} u = {x}; - u.i &= -1ULL/2; - return u.f; -} diff --git a/waterbox/libc/functions/math/fabsf.c b/waterbox/libc/functions/math/fabsf.c deleted file mode 100644 index 4efc8d686d..0000000000 --- a/waterbox/libc/functions/math/fabsf.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -float fabsf(float x) -{ - union {float f; uint32_t i;} u = {x}; - u.i &= 0x7fffffff; - return u.f; -} diff --git a/waterbox/libc/functions/math/fabsl.c b/waterbox/libc/functions/math/fabsl.c deleted file mode 100644 index c4f36ec281..0000000000 --- a/waterbox/libc/functions/math/fabsl.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "libm.h" -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double fabsl(long double x) -{ - return fabs(x); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -long double fabsl(long double x) -{ - union ldshape u = {x}; - - u.i.se &= 0x7fff; - return u.f; -} -#endif diff --git a/waterbox/libc/functions/math/fdim.c b/waterbox/libc/functions/math/fdim.c deleted file mode 100644 index 9585460643..0000000000 --- a/waterbox/libc/functions/math/fdim.c +++ /dev/null @@ -1,10 +0,0 @@ -#include - -double fdim(double x, double y) -{ - if (isnan(x)) - return x; - if (isnan(y)) - return y; - return x > y ? x - y : 0; -} diff --git a/waterbox/libc/functions/math/fdimf.c b/waterbox/libc/functions/math/fdimf.c deleted file mode 100644 index 543c3648e3..0000000000 --- a/waterbox/libc/functions/math/fdimf.c +++ /dev/null @@ -1,10 +0,0 @@ -#include - -float fdimf(float x, float y) -{ - if (isnan(x)) - return x; - if (isnan(y)) - return y; - return x > y ? x - y : 0; -} diff --git a/waterbox/libc/functions/math/fdiml.c b/waterbox/libc/functions/math/fdiml.c deleted file mode 100644 index 62e29b7df3..0000000000 --- a/waterbox/libc/functions/math/fdiml.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double fdiml(long double x, long double y) -{ - return fdim(x, y); -} -#else -long double fdiml(long double x, long double y) -{ - if (isnan(x)) - return x; - if (isnan(y)) - return y; - return x > y ? x - y : 0; -} -#endif diff --git a/waterbox/libc/functions/math/finite.c b/waterbox/libc/functions/math/finite.c deleted file mode 100644 index 25a0575fb9..0000000000 --- a/waterbox/libc/functions/math/finite.c +++ /dev/null @@ -1,7 +0,0 @@ -#define _GNU_SOURCE -#include - -int finite(double x) -{ - return isfinite(x); -} diff --git a/waterbox/libc/functions/math/finitef.c b/waterbox/libc/functions/math/finitef.c deleted file mode 100644 index 2c4c771463..0000000000 --- a/waterbox/libc/functions/math/finitef.c +++ /dev/null @@ -1,7 +0,0 @@ -#define _GNU_SOURCE -#include - -int finitef(float x) -{ - return isfinite(x); -} diff --git a/waterbox/libc/functions/math/floor.c b/waterbox/libc/functions/math/floor.c deleted file mode 100644 index 14a31cd8c4..0000000000 --- a/waterbox/libc/functions/math/floor.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "libm.h" - -#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 -#define EPS DBL_EPSILON -#elif FLT_EVAL_METHOD==2 -#define EPS LDBL_EPSILON -#endif -static const double_t toint = 1/EPS; - -double floor(double x) -{ - union {double f; uint64_t i;} u = {x}; - int e = u.i >> 52 & 0x7ff; - double_t y; - - if (e >= 0x3ff+52 || x == 0) - return x; - /* y = int(x) - x, where int(x) is an integer neighbor of x */ - if (u.i >> 63) - y = x - toint + toint - x; - else - y = x + toint - toint - x; - /* special case because of non-nearest rounding modes */ - if (e <= 0x3ff-1) { - FORCE_EVAL(y); - return u.i >> 63 ? -1 : 0; - } - if (y > 0) - return x + y - 1; - return x + y; -} diff --git a/waterbox/libc/functions/math/floorf.c b/waterbox/libc/functions/math/floorf.c deleted file mode 100644 index dceec739db..0000000000 --- a/waterbox/libc/functions/math/floorf.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "libm.h" - -float floorf(float x) -{ - union {float f; uint32_t i;} u = {x}; - int e = (int)(u.i >> 23 & 0xff) - 0x7f; - uint32_t m; - - if (e >= 23) - return x; - if (e >= 0) { - m = 0x007fffff >> e; - if ((u.i & m) == 0) - return x; - FORCE_EVAL(x + 0x1p120f); - if (u.i >> 31) - u.i += m; - u.i &= ~m; - } else { - FORCE_EVAL(x + 0x1p120f); - if (u.i >> 31 == 0) - u.i = 0; - else if (u.i << 1) - u.f = -1.0; - } - return u.f; -} diff --git a/waterbox/libc/functions/math/floorl.c b/waterbox/libc/functions/math/floorl.c deleted file mode 100644 index 16aaec48ee..0000000000 --- a/waterbox/libc/functions/math/floorl.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double floorl(long double x) -{ - return floor(x); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 - -static const long double toint = 1/LDBL_EPSILON; - -long double floorl(long double x) -{ - union ldshape u = {x}; - int e = u.i.se & 0x7fff; - long double y; - - if (e >= 0x3fff+LDBL_MANT_DIG-1 || x == 0) - return x; - /* y = int(x) - x, where int(x) is an integer neighbor of x */ - if (u.i.se >> 15) - y = x - toint + toint - x; - else - y = x + toint - toint - x; - /* special case because of non-nearest rounding modes */ - if (e <= 0x3fff-1) { - FORCE_EVAL(y); - return u.i.se >> 15 ? -1 : 0; - } - if (y > 0) - return x + y - 1; - return x + y; -} -#endif diff --git a/waterbox/libc/functions/math/fma.c b/waterbox/libc/functions/math/fma.c deleted file mode 100644 index 741ccd757a..0000000000 --- a/waterbox/libc/functions/math/fma.c +++ /dev/null @@ -1,460 +0,0 @@ -#include -#include "libm.h" - -#if LDBL_MANT_DIG==64 && LDBL_MAX_EXP==16384 -/* exact add, assumes exponent_x >= exponent_y */ -static void add(long double *hi, long double *lo, long double x, long double y) -{ - long double r; - - r = x + y; - *hi = r; - r -= x; - *lo = y - r; -} - -/* exact mul, assumes no over/underflow */ -static void mul(long double *hi, long double *lo, long double x, long double y) -{ - static const long double c = 1.0 + 0x1p32L; - long double cx, xh, xl, cy, yh, yl; - - cx = c*x; - xh = (x - cx) + cx; - xl = x - xh; - cy = c*y; - yh = (y - cy) + cy; - yl = y - yh; - *hi = x*y; - *lo = (xh*yh - *hi) + xh*yl + xl*yh + xl*yl; -} - -/* -assume (long double)(hi+lo) == hi -return an adjusted hi so that rounding it to double (or less) precision is correct -*/ -static long double adjust(long double hi, long double lo) -{ - union ldshape uhi, ulo; - - if (lo == 0) - return hi; - uhi.f = hi; - if (uhi.i.m & 0x3ff) - return hi; - ulo.f = lo; - if ((uhi.i.se & 0x8000) == (ulo.i.se & 0x8000)) - uhi.i.m++; - else { - /* handle underflow and take care of ld80 implicit msb */ - if (uhi.i.m << 1 == 0) { - uhi.i.m = 0; - uhi.i.se--; - } - uhi.i.m--; - } - return uhi.f; -} - -/* adjusted add so the result is correct when rounded to double (or less) precision */ -static long double dadd(long double x, long double y) -{ - add(&x, &y, x, y); - return adjust(x, y); -} - -/* adjusted mul so the result is correct when rounded to double (or less) precision */ -static long double dmul(long double x, long double y) -{ - mul(&x, &y, x, y); - return adjust(x, y); -} - -static int getexp(long double x) -{ - union ldshape u; - u.f = x; - return u.i.se & 0x7fff; -} - -double fma(double x, double y, double z) -{ - #pragma STDC FENV_ACCESS ON - long double hi, lo1, lo2, xy; - int round, ez, exy; - - /* handle +-inf,nan */ - if (!isfinite(x) || !isfinite(y)) - return x*y + z; - if (!isfinite(z)) - return z; - /* handle +-0 */ - if (x == 0.0 || y == 0.0) - return x*y + z; - round = fegetround(); - if (z == 0.0) { - if (round == FE_TONEAREST) - return dmul(x, y); - return x*y; - } - - /* exact mul and add require nearest rounding */ - /* spurious inexact exceptions may be raised */ - fesetround(FE_TONEAREST); - mul(&xy, &lo1, x, y); - exy = getexp(xy); - ez = getexp(z); - if (ez > exy) { - add(&hi, &lo2, z, xy); - } else if (ez > exy - 12) { - add(&hi, &lo2, xy, z); - if (hi == 0) { - /* - xy + z is 0, but it should be calculated with the - original rounding mode so the sign is correct, if the - compiler does not support FENV_ACCESS ON it does not - know about the changed rounding mode and eliminates - the xy + z below without the volatile memory access - */ - volatile double z_; - fesetround(round); - z_ = z; - return (xy + z_) + lo1; - } - } else { - /* - ez <= exy - 12 - the 12 extra bits (1guard, 11round+sticky) are needed so with - lo = dadd(lo1, lo2) - elo <= ehi - 11, and we use the last 10 bits in adjust so - dadd(hi, lo) - gives correct result when rounded to double - */ - hi = xy; - lo2 = z; - } - /* - the result is stored before return for correct precision and exceptions - - one corner case is when the underflow flag should be raised because - the precise result is an inexact subnormal double, but the calculated - long double result is an exact subnormal double - (so rounding to double does not raise exceptions) - - in nearest rounding mode dadd takes care of this: the last bit of the - result is adjusted so rounding sees an inexact value when it should - - in non-nearest rounding mode fenv is used for the workaround - */ - fesetround(round); - if (round == FE_TONEAREST) - z = dadd(hi, dadd(lo1, lo2)); - else { -#if defined(FE_INEXACT) && defined(FE_UNDERFLOW) - int e = fetestexcept(FE_INEXACT); - feclearexcept(FE_INEXACT); -#endif - z = hi + (lo1 + lo2); -#if defined(FE_INEXACT) && defined(FE_UNDERFLOW) - if (getexp(z) < 0x3fff-1022 && fetestexcept(FE_INEXACT)) - feraiseexcept(FE_UNDERFLOW); - else if (e) - feraiseexcept(FE_INEXACT); -#endif - } - return z; -} -#else -/* origin: FreeBSD /usr/src/lib/msun/src/s_fma.c */ -/*- - * Copyright (c) 2005-2011 David Schultz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * A struct dd represents a floating-point number with twice the precision - * of a double. We maintain the invariant that "hi" stores the 53 high-order - * bits of the result. - */ -struct dd { - double hi; - double lo; -}; - -/* - * Compute a+b exactly, returning the exact result in a struct dd. We assume - * that both a and b are finite, but make no assumptions about their relative - * magnitudes. - */ -static inline struct dd dd_add(double a, double b) -{ - struct dd ret; - double s; - - ret.hi = a + b; - s = ret.hi - a; - ret.lo = (a - (ret.hi - s)) + (b - s); - return (ret); -} - -/* - * Compute a+b, with a small tweak: The least significant bit of the - * result is adjusted into a sticky bit summarizing all the bits that - * were lost to rounding. This adjustment negates the effects of double - * rounding when the result is added to another number with a higher - * exponent. For an explanation of round and sticky bits, see any reference - * on FPU design, e.g., - * - * J. Coonen. An Implementation Guide to a Proposed Standard for - * Floating-Point Arithmetic. Computer, vol. 13, no. 1, Jan 1980. - */ -static inline double add_adjusted(double a, double b) -{ - struct dd sum; - union {double f; uint64_t i;} uhi, ulo; - - sum = dd_add(a, b); - if (sum.lo != 0) { - uhi.f = sum.hi; - if ((uhi.i & 1) == 0) { - /* hibits += (int)copysign(1.0, sum.hi * sum.lo) */ - ulo.f = sum.lo; - uhi.i += 1 - ((uhi.i ^ ulo.i) >> 62); - sum.hi = uhi.f; - } - } - return (sum.hi); -} - -/* - * Compute ldexp(a+b, scale) with a single rounding error. It is assumed - * that the result will be subnormal, and care is taken to ensure that - * double rounding does not occur. - */ -static inline double add_and_denormalize(double a, double b, int scale) -{ - struct dd sum; - union {double f; uint64_t i;} uhi, ulo; - int bits_lost; - - sum = dd_add(a, b); - - /* - * If we are losing at least two bits of accuracy to denormalization, - * then the first lost bit becomes a round bit, and we adjust the - * lowest bit of sum.hi to make it a sticky bit summarizing all the - * bits in sum.lo. With the sticky bit adjusted, the hardware will - * break any ties in the correct direction. - * - * If we are losing only one bit to denormalization, however, we must - * break the ties manually. - */ - if (sum.lo != 0) { - uhi.f = sum.hi; - bits_lost = -((int)(uhi.i >> 52) & 0x7ff) - scale + 1; - if ((bits_lost != 1) ^ (int)(uhi.i & 1)) { - /* hibits += (int)copysign(1.0, sum.hi * sum.lo) */ - ulo.f = sum.lo; - uhi.i += 1 - (((uhi.i ^ ulo.i) >> 62) & 2); - sum.hi = uhi.f; - } - } - return scalbn(sum.hi, scale); -} - -/* - * Compute a*b exactly, returning the exact result in a struct dd. We assume - * that both a and b are normalized, so no underflow or overflow will occur. - * The current rounding mode must be round-to-nearest. - */ -static inline struct dd dd_mul(double a, double b) -{ - static const double split = 0x1p27 + 1.0; - struct dd ret; - double ha, hb, la, lb, p, q; - - p = a * split; - ha = a - p; - ha += p; - la = a - ha; - - p = b * split; - hb = b - p; - hb += p; - lb = b - hb; - - p = ha * hb; - q = ha * lb + la * hb; - - ret.hi = p + q; - ret.lo = p - ret.hi + q + la * lb; - return (ret); -} - -/* - * Fused multiply-add: Compute x * y + z with a single rounding error. - * - * We use scaling to avoid overflow/underflow, along with the - * canonical precision-doubling technique adapted from: - * - * Dekker, T. A Floating-Point Technique for Extending the - * Available Precision. Numer. Math. 18, 224-242 (1971). - * - * This algorithm is sensitive to the rounding precision. FPUs such - * as the i387 must be set in double-precision mode if variables are - * to be stored in FP registers in order to avoid incorrect results. - * This is the default on FreeBSD, but not on many other systems. - * - * Hardware instructions should be used on architectures that support it, - * since this implementation will likely be several times slower. - */ -double fma(double x, double y, double z) -{ - #pragma STDC FENV_ACCESS ON - double xs, ys, zs, adj; - struct dd xy, r; - int oround; - int ex, ey, ez; - int spread; - - /* - * Handle special cases. The order of operations and the particular - * return values here are crucial in handling special cases involving - * infinities, NaNs, overflows, and signed zeroes correctly. - */ - if (!isfinite(x) || !isfinite(y)) - return (x * y + z); - if (!isfinite(z)) - return (z); - if (x == 0.0 || y == 0.0) - return (x * y + z); - if (z == 0.0) - return (x * y); - - xs = frexp(x, &ex); - ys = frexp(y, &ey); - zs = frexp(z, &ez); - oround = fegetround(); - spread = ex + ey - ez; - - /* - * If x * y and z are many orders of magnitude apart, the scaling - * will overflow, so we handle these cases specially. Rounding - * modes other than FE_TONEAREST are painful. - */ - if (spread < -DBL_MANT_DIG) { -#ifdef FE_INEXACT - feraiseexcept(FE_INEXACT); -#endif -#ifdef FE_UNDERFLOW - if (!isnormal(z)) - feraiseexcept(FE_UNDERFLOW); -#endif - switch (oround) { - default: /* FE_TONEAREST */ - return (z); -#ifdef FE_TOWARDZERO - case FE_TOWARDZERO: - if (x > 0.0 ^ y < 0.0 ^ z < 0.0) - return (z); - else - return (nextafter(z, 0)); -#endif -#ifdef FE_DOWNWARD - case FE_DOWNWARD: - if (x > 0.0 ^ y < 0.0) - return (z); - else - return (nextafter(z, -INFINITY)); -#endif -#ifdef FE_UPWARD - case FE_UPWARD: - if (x > 0.0 ^ y < 0.0) - return (nextafter(z, INFINITY)); - else - return (z); -#endif - } - } - if (spread <= DBL_MANT_DIG * 2) - zs = scalbn(zs, -spread); - else - zs = copysign(DBL_MIN, zs); - - fesetround(FE_TONEAREST); - - /* - * Basic approach for round-to-nearest: - * - * (xy.hi, xy.lo) = x * y (exact) - * (r.hi, r.lo) = xy.hi + z (exact) - * adj = xy.lo + r.lo (inexact; low bit is sticky) - * result = r.hi + adj (correctly rounded) - */ - xy = dd_mul(xs, ys); - r = dd_add(xy.hi, zs); - - spread = ex + ey; - - if (r.hi == 0.0) { - /* - * When the addends cancel to 0, ensure that the result has - * the correct sign. - */ - fesetround(oround); - volatile double vzs = zs; /* XXX gcc CSE bug workaround */ - return xy.hi + vzs + scalbn(xy.lo, spread); - } - - if (oround != FE_TONEAREST) { - /* - * There is no need to worry about double rounding in directed - * rounding modes. - * But underflow may not be raised properly, example in downward rounding: - * fma(0x1.000000001p-1000, 0x1.000000001p-30, -0x1p-1066) - */ - double ret; -#if defined(FE_INEXACT) && defined(FE_UNDERFLOW) - int e = fetestexcept(FE_INEXACT); - feclearexcept(FE_INEXACT); -#endif - fesetround(oround); - adj = r.lo + xy.lo; - ret = scalbn(r.hi + adj, spread); -#if defined(FE_INEXACT) && defined(FE_UNDERFLOW) - if (ilogb(ret) < -1022 && fetestexcept(FE_INEXACT)) - feraiseexcept(FE_UNDERFLOW); - else if (e) - feraiseexcept(FE_INEXACT); -#endif - return ret; - } - - adj = add_adjusted(r.lo, xy.lo); - if (spread + ilogb(r.hi) > -1023) - return scalbn(r.hi + adj, spread); - else - return add_and_denormalize(r.hi, adj, spread); -} -#endif diff --git a/waterbox/libc/functions/math/fmaf.c b/waterbox/libc/functions/math/fmaf.c deleted file mode 100644 index aa57feb695..0000000000 --- a/waterbox/libc/functions/math/fmaf.c +++ /dev/null @@ -1,93 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_fmaf.c */ -/*- - * Copyright (c) 2005-2011 David Schultz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include - -/* - * Fused multiply-add: Compute x * y + z with a single rounding error. - * - * A double has more than twice as much precision than a float, so - * direct double-precision arithmetic suffices, except where double - * rounding occurs. - */ -float fmaf(float x, float y, float z) -{ - #pragma STDC FENV_ACCESS ON - double xy, result; - union {double f; uint64_t i;} u; - int e; - - xy = (double)x * y; - result = xy + z; - u.f = result; - e = u.i>>52 & 0x7ff; - /* Common case: The double precision result is fine. */ - if ((u.i & 0x1fffffff) != 0x10000000 || /* not a halfway case */ - e == 0x7ff || /* NaN */ - result - xy == z || /* exact */ - fegetround() != FE_TONEAREST) /* not round-to-nearest */ - { - /* - underflow may not be raised correctly, example: - fmaf(0x1p-120f, 0x1p-120f, 0x1p-149f) - */ -#if defined(FE_INEXACT) && defined(FE_UNDERFLOW) - if (e < 0x3ff-126 && e >= 0x3ff-149 && fetestexcept(FE_INEXACT)) { - feclearexcept(FE_INEXACT); - /* TODO: gcc and clang bug workaround */ - volatile float vz = z; - result = xy + vz; - if (fetestexcept(FE_INEXACT)) - feraiseexcept(FE_UNDERFLOW); - else - feraiseexcept(FE_INEXACT); - } -#endif - z = result; - return z; - } - - /* - * If result is inexact, and exactly halfway between two float values, - * we need to adjust the low-order bit in the direction of the error. - */ -#ifdef FE_TOWARDZERO - fesetround(FE_TOWARDZERO); -#endif - volatile double vxy = xy; /* XXX work around gcc CSE bug */ - double adjusted_result = vxy + z; - fesetround(FE_TONEAREST); - if (result == adjusted_result) { - u.f = adjusted_result; - u.i++; - adjusted_result = u.f; - } - z = adjusted_result; - return z; -} diff --git a/waterbox/libc/functions/math/fmal.c b/waterbox/libc/functions/math/fmal.c deleted file mode 100644 index 4506aac6f6..0000000000 --- a/waterbox/libc/functions/math/fmal.c +++ /dev/null @@ -1,293 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_fmal.c */ -/*- - * Copyright (c) 2005-2011 David Schultz - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include "libm.h" -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double fmal(long double x, long double y, long double z) -{ - return fma(x, y, z); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -#include -#if LDBL_MANT_DIG == 64 -#define LASTBIT(u) (u.i.m & 1) -#define SPLIT (0x1p32L + 1) -#elif LDBL_MANT_DIG == 113 -#define LASTBIT(u) (u.i.lo & 1) -#define SPLIT (0x1p57L + 1) -#endif - -/* - * A struct dd represents a floating-point number with twice the precision - * of a long double. We maintain the invariant that "hi" stores the high-order - * bits of the result. - */ -struct dd { - long double hi; - long double lo; -}; - -/* - * Compute a+b exactly, returning the exact result in a struct dd. We assume - * that both a and b are finite, but make no assumptions about their relative - * magnitudes. - */ -static inline struct dd dd_add(long double a, long double b) -{ - struct dd ret; - long double s; - - ret.hi = a + b; - s = ret.hi - a; - ret.lo = (a - (ret.hi - s)) + (b - s); - return (ret); -} - -/* - * Compute a+b, with a small tweak: The least significant bit of the - * result is adjusted into a sticky bit summarizing all the bits that - * were lost to rounding. This adjustment negates the effects of double - * rounding when the result is added to another number with a higher - * exponent. For an explanation of round and sticky bits, see any reference - * on FPU design, e.g., - * - * J. Coonen. An Implementation Guide to a Proposed Standard for - * Floating-Point Arithmetic. Computer, vol. 13, no. 1, Jan 1980. - */ -static inline long double add_adjusted(long double a, long double b) -{ - struct dd sum; - union ldshape u; - - sum = dd_add(a, b); - if (sum.lo != 0) { - u.f = sum.hi; - if (!LASTBIT(u)) - sum.hi = nextafterl(sum.hi, INFINITY * sum.lo); - } - return (sum.hi); -} - -/* - * Compute ldexp(a+b, scale) with a single rounding error. It is assumed - * that the result will be subnormal, and care is taken to ensure that - * double rounding does not occur. - */ -static inline long double add_and_denormalize(long double a, long double b, int scale) -{ - struct dd sum; - int bits_lost; - union ldshape u; - - sum = dd_add(a, b); - - /* - * If we are losing at least two bits of accuracy to denormalization, - * then the first lost bit becomes a round bit, and we adjust the - * lowest bit of sum.hi to make it a sticky bit summarizing all the - * bits in sum.lo. With the sticky bit adjusted, the hardware will - * break any ties in the correct direction. - * - * If we are losing only one bit to denormalization, however, we must - * break the ties manually. - */ - if (sum.lo != 0) { - u.f = sum.hi; - bits_lost = -u.i.se - scale + 1; - if ((bits_lost != 1) ^ LASTBIT(u)) - sum.hi = nextafterl(sum.hi, INFINITY * sum.lo); - } - return scalbnl(sum.hi, scale); -} - -/* - * Compute a*b exactly, returning the exact result in a struct dd. We assume - * that both a and b are normalized, so no underflow or overflow will occur. - * The current rounding mode must be round-to-nearest. - */ -static inline struct dd dd_mul(long double a, long double b) -{ - struct dd ret; - long double ha, hb, la, lb, p, q; - - p = a * SPLIT; - ha = a - p; - ha += p; - la = a - ha; - - p = b * SPLIT; - hb = b - p; - hb += p; - lb = b - hb; - - p = ha * hb; - q = ha * lb + la * hb; - - ret.hi = p + q; - ret.lo = p - ret.hi + q + la * lb; - return (ret); -} - -/* - * Fused multiply-add: Compute x * y + z with a single rounding error. - * - * We use scaling to avoid overflow/underflow, along with the - * canonical precision-doubling technique adapted from: - * - * Dekker, T. A Floating-Point Technique for Extending the - * Available Precision. Numer. Math. 18, 224-242 (1971). - */ -long double fmal(long double x, long double y, long double z) -{ - #pragma STDC FENV_ACCESS ON - long double xs, ys, zs, adj; - struct dd xy, r; - int oround; - int ex, ey, ez; - int spread; - - /* - * Handle special cases. The order of operations and the particular - * return values here are crucial in handling special cases involving - * infinities, NaNs, overflows, and signed zeroes correctly. - */ - if (!isfinite(x) || !isfinite(y)) - return (x * y + z); - if (!isfinite(z)) - return (z); - if (x == 0.0 || y == 0.0) - return (x * y + z); - if (z == 0.0) - return (x * y); - - xs = frexpl(x, &ex); - ys = frexpl(y, &ey); - zs = frexpl(z, &ez); - oround = fegetround(); - spread = ex + ey - ez; - - /* - * If x * y and z are many orders of magnitude apart, the scaling - * will overflow, so we handle these cases specially. Rounding - * modes other than FE_TONEAREST are painful. - */ - if (spread < -LDBL_MANT_DIG) { -#ifdef FE_INEXACT - feraiseexcept(FE_INEXACT); -#endif -#ifdef FE_UNDERFLOW - if (!isnormal(z)) - feraiseexcept(FE_UNDERFLOW); -#endif - switch (oround) { - default: /* FE_TONEAREST */ - return (z); -#ifdef FE_TOWARDZERO - case FE_TOWARDZERO: - if (x > 0.0 ^ y < 0.0 ^ z < 0.0) - return (z); - else - return (nextafterl(z, 0)); -#endif -#ifdef FE_DOWNWARD - case FE_DOWNWARD: - if (x > 0.0 ^ y < 0.0) - return (z); - else - return (nextafterl(z, -INFINITY)); -#endif -#ifdef FE_UPWARD - case FE_UPWARD: - if (x > 0.0 ^ y < 0.0) - return (nextafterl(z, INFINITY)); - else - return (z); -#endif - } - } - if (spread <= LDBL_MANT_DIG * 2) - zs = scalbnl(zs, -spread); - else - zs = copysignl(LDBL_MIN, zs); - - fesetround(FE_TONEAREST); - - /* - * Basic approach for round-to-nearest: - * - * (xy.hi, xy.lo) = x * y (exact) - * (r.hi, r.lo) = xy.hi + z (exact) - * adj = xy.lo + r.lo (inexact; low bit is sticky) - * result = r.hi + adj (correctly rounded) - */ - xy = dd_mul(xs, ys); - r = dd_add(xy.hi, zs); - - spread = ex + ey; - - if (r.hi == 0.0) { - /* - * When the addends cancel to 0, ensure that the result has - * the correct sign. - */ - fesetround(oround); - volatile long double vzs = zs; /* XXX gcc CSE bug workaround */ - return xy.hi + vzs + scalbnl(xy.lo, spread); - } - - if (oround != FE_TONEAREST) { - /* - * There is no need to worry about double rounding in directed - * rounding modes. - * But underflow may not be raised correctly, example in downward rounding: - * fmal(0x1.0000000001p-16000L, 0x1.0000000001p-400L, -0x1p-16440L) - */ - long double ret; -#if defined(FE_INEXACT) && defined(FE_UNDERFLOW) - int e = fetestexcept(FE_INEXACT); - feclearexcept(FE_INEXACT); -#endif - fesetround(oround); - adj = r.lo + xy.lo; - ret = scalbnl(r.hi + adj, spread); -#if defined(FE_INEXACT) && defined(FE_UNDERFLOW) - if (ilogbl(ret) < -16382 && fetestexcept(FE_INEXACT)) - feraiseexcept(FE_UNDERFLOW); - else if (e) - feraiseexcept(FE_INEXACT); -#endif - return ret; - } - - adj = add_adjusted(r.lo, xy.lo); - if (spread + ilogbl(r.hi) > -16383) - return scalbnl(r.hi + adj, spread); - else - return add_and_denormalize(r.hi, adj, spread); -} -#endif diff --git a/waterbox/libc/functions/math/fmax.c b/waterbox/libc/functions/math/fmax.c deleted file mode 100644 index 94f0caa177..0000000000 --- a/waterbox/libc/functions/math/fmax.c +++ /dev/null @@ -1,13 +0,0 @@ -#include - -double fmax(double x, double y) -{ - if (isnan(x)) - return y; - if (isnan(y)) - return x; - /* handle signed zeros, see C99 Annex F.9.9.2 */ - if (signbit(x) != signbit(y)) - return signbit(x) ? y : x; - return x < y ? y : x; -} diff --git a/waterbox/libc/functions/math/fmaxf.c b/waterbox/libc/functions/math/fmaxf.c deleted file mode 100644 index 695d8179c6..0000000000 --- a/waterbox/libc/functions/math/fmaxf.c +++ /dev/null @@ -1,13 +0,0 @@ -#include - -float fmaxf(float x, float y) -{ - if (isnan(x)) - return y; - if (isnan(y)) - return x; - /* handle signed zeroes, see C99 Annex F.9.9.2 */ - if (signbit(x) != signbit(y)) - return signbit(x) ? y : x; - return x < y ? y : x; -} diff --git a/waterbox/libc/functions/math/fmaxl.c b/waterbox/libc/functions/math/fmaxl.c deleted file mode 100644 index 4b03158e06..0000000000 --- a/waterbox/libc/functions/math/fmaxl.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double fmaxl(long double x, long double y) -{ - return fmax(x, y); -} -#else -long double fmaxl(long double x, long double y) -{ - if (isnan(x)) - return y; - if (isnan(y)) - return x; - /* handle signed zeros, see C99 Annex F.9.9.2 */ - if (signbit(x) != signbit(y)) - return signbit(x) ? y : x; - return x < y ? y : x; -} -#endif diff --git a/waterbox/libc/functions/math/fmin.c b/waterbox/libc/functions/math/fmin.c deleted file mode 100644 index 08a8fd17f2..0000000000 --- a/waterbox/libc/functions/math/fmin.c +++ /dev/null @@ -1,13 +0,0 @@ -#include - -double fmin(double x, double y) -{ - if (isnan(x)) - return y; - if (isnan(y)) - return x; - /* handle signed zeros, see C99 Annex F.9.9.2 */ - if (signbit(x) != signbit(y)) - return signbit(x) ? x : y; - return x < y ? x : y; -} diff --git a/waterbox/libc/functions/math/fminf.c b/waterbox/libc/functions/math/fminf.c deleted file mode 100644 index 3573c7de74..0000000000 --- a/waterbox/libc/functions/math/fminf.c +++ /dev/null @@ -1,13 +0,0 @@ -#include - -float fminf(float x, float y) -{ - if (isnan(x)) - return y; - if (isnan(y)) - return x; - /* handle signed zeros, see C99 Annex F.9.9.2 */ - if (signbit(x) != signbit(y)) - return signbit(x) ? x : y; - return x < y ? x : y; -} diff --git a/waterbox/libc/functions/math/fminl.c b/waterbox/libc/functions/math/fminl.c deleted file mode 100644 index 69bc24a79b..0000000000 --- a/waterbox/libc/functions/math/fminl.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double fminl(long double x, long double y) -{ - return fmin(x, y); -} -#else -long double fminl(long double x, long double y) -{ - if (isnan(x)) - return y; - if (isnan(y)) - return x; - /* handle signed zeros, see C99 Annex F.9.9.2 */ - if (signbit(x) != signbit(y)) - return signbit(x) ? x : y; - return x < y ? x : y; -} -#endif diff --git a/waterbox/libc/functions/math/fmod.c b/waterbox/libc/functions/math/fmod.c deleted file mode 100644 index 6849722bac..0000000000 --- a/waterbox/libc/functions/math/fmod.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include - -double fmod(double x, double y) -{ - union {double f; uint64_t i;} ux = {x}, uy = {y}; - int ex = ux.i>>52 & 0x7ff; - int ey = uy.i>>52 & 0x7ff; - int sx = ux.i>>63; - uint64_t i; - - /* in the followings uxi should be ux.i, but then gcc wrongly adds */ - /* float load/store to inner loops ruining performance and code size */ - uint64_t uxi = ux.i; - - if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff) - return (x*y)/(x*y); - if (uxi<<1 <= uy.i<<1) { - if (uxi<<1 == uy.i<<1) - return 0*x; - return x; - } - - /* normalize x and y */ - if (!ex) { - for (i = uxi<<12; i>>63 == 0; ex--, i <<= 1); - uxi <<= -ex + 1; - } else { - uxi &= -1ULL >> 12; - uxi |= 1ULL << 52; - } - if (!ey) { - for (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1); - uy.i <<= -ey + 1; - } else { - uy.i &= -1ULL >> 12; - uy.i |= 1ULL << 52; - } - - /* x mod y */ - for (; ex > ey; ex--) { - i = uxi - uy.i; - if (i >> 63 == 0) { - if (i == 0) - return 0*x; - uxi = i; - } - uxi <<= 1; - } - i = uxi - uy.i; - if (i >> 63 == 0) { - if (i == 0) - return 0*x; - uxi = i; - } - for (; uxi>>52 == 0; uxi <<= 1, ex--); - - /* scale result */ - if (ex > 0) { - uxi -= 1ULL << 52; - uxi |= (uint64_t)ex << 52; - } else { - uxi >>= -ex + 1; - } - uxi |= (uint64_t)sx << 63; - ux.i = uxi; - return ux.f; -} diff --git a/waterbox/libc/functions/math/fmodf.c b/waterbox/libc/functions/math/fmodf.c deleted file mode 100644 index ff58f93365..0000000000 --- a/waterbox/libc/functions/math/fmodf.c +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include - -float fmodf(float x, float y) -{ - union {float f; uint32_t i;} ux = {x}, uy = {y}; - int ex = ux.i>>23 & 0xff; - int ey = uy.i>>23 & 0xff; - uint32_t sx = ux.i & 0x80000000; - uint32_t i; - uint32_t uxi = ux.i; - - if (uy.i<<1 == 0 || isnan(y) || ex == 0xff) - return (x*y)/(x*y); - if (uxi<<1 <= uy.i<<1) { - if (uxi<<1 == uy.i<<1) - return 0*x; - return x; - } - - /* normalize x and y */ - if (!ex) { - for (i = uxi<<9; i>>31 == 0; ex--, i <<= 1); - uxi <<= -ex + 1; - } else { - uxi &= -1U >> 9; - uxi |= 1U << 23; - } - if (!ey) { - for (i = uy.i<<9; i>>31 == 0; ey--, i <<= 1); - uy.i <<= -ey + 1; - } else { - uy.i &= -1U >> 9; - uy.i |= 1U << 23; - } - - /* x mod y */ - for (; ex > ey; ex--) { - i = uxi - uy.i; - if (i >> 31 == 0) { - if (i == 0) - return 0*x; - uxi = i; - } - uxi <<= 1; - } - i = uxi - uy.i; - if (i >> 31 == 0) { - if (i == 0) - return 0*x; - uxi = i; - } - for (; uxi>>23 == 0; uxi <<= 1, ex--); - - /* scale result up */ - if (ex > 0) { - uxi -= 1U << 23; - uxi |= (uint32_t)ex << 23; - } else { - uxi >>= -ex + 1; - } - uxi |= sx; - ux.i = uxi; - return ux.f; -} diff --git a/waterbox/libc/functions/math/fmodl.c b/waterbox/libc/functions/math/fmodl.c deleted file mode 100644 index 9f5b87393d..0000000000 --- a/waterbox/libc/functions/math/fmodl.c +++ /dev/null @@ -1,105 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double fmodl(long double x, long double y) -{ - return fmod(x, y); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -long double fmodl(long double x, long double y) -{ - union ldshape ux = {x}, uy = {y}; - int ex = ux.i.se & 0x7fff; - int ey = uy.i.se & 0x7fff; - int sx = ux.i.se & 0x8000; - - if (y == 0 || isnan(y) || ex == 0x7fff) - return (x*y)/(x*y); - ux.i.se = ex; - uy.i.se = ey; - if (ux.f <= uy.f) { - if (ux.f == uy.f) - return 0*x; - return x; - } - - /* normalize x and y */ - if (!ex) { - ux.f *= 0x1p120f; - ex = ux.i.se - 120; - } - if (!ey) { - uy.f *= 0x1p120f; - ey = uy.i.se - 120; - } - - /* x mod y */ -#if LDBL_MANT_DIG == 64 - uint64_t i, mx, my; - mx = ux.i.m; - my = uy.i.m; - for (; ex > ey; ex--) { - i = mx - my; - if (mx >= my) { - if (i == 0) - return 0*x; - mx = 2*i; - } else if (2*mx < mx) { - mx = 2*mx - my; - } else { - mx = 2*mx; - } - } - i = mx - my; - if (mx >= my) { - if (i == 0) - return 0*x; - mx = i; - } - for (; mx >> 63 == 0; mx *= 2, ex--); - ux.i.m = mx; -#elif LDBL_MANT_DIG == 113 - uint64_t hi, lo, xhi, xlo, yhi, ylo; - xhi = (ux.i2.hi & -1ULL>>16) | 1ULL<<48; - yhi = (uy.i2.hi & -1ULL>>16) | 1ULL<<48; - xlo = ux.i2.lo; - ylo = uy.i2.lo; - for (; ex > ey; ex--) { - hi = xhi - yhi; - lo = xlo - ylo; - if (xlo < ylo) - hi -= 1; - if (hi >> 63 == 0) { - if ((hi|lo) == 0) - return 0*x; - xhi = 2*hi + (lo>>63); - xlo = 2*lo; - } else { - xhi = 2*xhi + (xlo>>63); - xlo = 2*xlo; - } - } - hi = xhi - yhi; - lo = xlo - ylo; - if (xlo < ylo) - hi -= 1; - if (hi >> 63 == 0) { - if ((hi|lo) == 0) - return 0*x; - xhi = hi; - xlo = lo; - } - for (; xhi >> 48 == 0; xhi = 2*xhi + (xlo>>63), xlo = 2*xlo, ex--); - ux.i2.hi = xhi; - ux.i2.lo = xlo; -#endif - - /* scale result */ - if (ex <= 0) { - ux.i.se = (ex+120)|sx; - ux.f *= 0x1p-120f; - } else - ux.i.se = ex|sx; - return ux.f; -} -#endif diff --git a/waterbox/libc/functions/math/frexp.c b/waterbox/libc/functions/math/frexp.c deleted file mode 100644 index 27b6266ed0..0000000000 --- a/waterbox/libc/functions/math/frexp.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include - -double frexp(double x, int *e) -{ - union { double d; uint64_t i; } y = { x }; - int ee = y.i>>52 & 0x7ff; - - if (!ee) { - if (x) { - x = frexp(x*0x1p64, e); - *e -= 64; - } else *e = 0; - return x; - } else if (ee == 0x7ff) { - return x; - } - - *e = ee - 0x3fe; - y.i &= 0x800fffffffffffffull; - y.i |= 0x3fe0000000000000ull; - return y.d; -} diff --git a/waterbox/libc/functions/math/frexpf.c b/waterbox/libc/functions/math/frexpf.c deleted file mode 100644 index 0787097527..0000000000 --- a/waterbox/libc/functions/math/frexpf.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include - -float frexpf(float x, int *e) -{ - union { float f; uint32_t i; } y = { x }; - int ee = y.i>>23 & 0xff; - - if (!ee) { - if (x) { - x = frexpf(x*0x1p64, e); - *e -= 64; - } else *e = 0; - return x; - } else if (ee == 0xff) { - return x; - } - - *e = ee - 0x7e; - y.i &= 0x807ffffful; - y.i |= 0x3f000000ul; - return y.f; -} diff --git a/waterbox/libc/functions/math/frexpl.c b/waterbox/libc/functions/math/frexpl.c deleted file mode 100644 index 3c1b553748..0000000000 --- a/waterbox/libc/functions/math/frexpl.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double frexpl(long double x, int *e) -{ - return frexp(x, e); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -long double frexpl(long double x, int *e) -{ - union ldshape u = {x}; - int ee = u.i.se & 0x7fff; - - if (!ee) { - if (x) { - x = frexpl(x*0x1p120, e); - *e -= 120; - } else *e = 0; - return x; - } else if (ee == 0x7fff) { - return x; - } - - *e = ee - 0x3ffe; - u.i.se &= 0x8000; - u.i.se |= 0x3ffe; - return u.f; -} -#endif diff --git a/waterbox/libc/functions/math/hypot.c b/waterbox/libc/functions/math/hypot.c deleted file mode 100644 index 6071bf1e28..0000000000 --- a/waterbox/libc/functions/math/hypot.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include - -#if FLT_EVAL_METHOD > 1U && LDBL_MANT_DIG == 64 -#define SPLIT (0x1p32 + 1) -#else -#define SPLIT (0x1p27 + 1) -#endif - -static void sq(double_t *hi, double_t *lo, double x) -{ - double_t xh, xl, xc; - - xc = (double_t)x*SPLIT; - xh = x - xc + xc; - xl = x - xh; - *hi = (double_t)x*x; - *lo = xh*xh - *hi + 2*xh*xl + xl*xl; -} - -double hypot(double x, double y) -{ - union {double f; uint64_t i;} ux = {x}, uy = {y}, ut; - int ex, ey; - double_t hx, lx, hy, ly, z; - - /* arrange |x| >= |y| */ - ux.i &= -1ULL>>1; - uy.i &= -1ULL>>1; - if (ux.i < uy.i) { - ut = ux; - ux = uy; - uy = ut; - } - - /* special cases */ - ex = ux.i>>52; - ey = uy.i>>52; - x = ux.f; - y = uy.f; - /* note: hypot(inf,nan) == inf */ - if (ey == 0x7ff) - return y; - if (ex == 0x7ff || uy.i == 0) - return x; - /* note: hypot(x,y) ~= x + y*y/x/2 with inexact for small y/x */ - /* 64 difference is enough for ld80 double_t */ - if (ex - ey > 64) - return x + y; - - /* precise sqrt argument in nearest rounding mode without overflow */ - /* xh*xh must not overflow and xl*xl must not underflow in sq */ - z = 1; - if (ex > 0x3ff+510) { - z = 0x1p700; - x *= 0x1p-700; - y *= 0x1p-700; - } else if (ey < 0x3ff-450) { - z = 0x1p-700; - x *= 0x1p700; - y *= 0x1p700; - } - sq(&hx, &lx, x); - sq(&hy, &ly, y); - return z*sqrt(ly+lx+hy+hx); -} diff --git a/waterbox/libc/functions/math/hypotf.c b/waterbox/libc/functions/math/hypotf.c deleted file mode 100644 index 2fc214b723..0000000000 --- a/waterbox/libc/functions/math/hypotf.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include - -float hypotf(float x, float y) -{ - union {float f; uint32_t i;} ux = {x}, uy = {y}, ut; - float_t z; - - ux.i &= -1U>>1; - uy.i &= -1U>>1; - if (ux.i < uy.i) { - ut = ux; - ux = uy; - uy = ut; - } - - x = ux.f; - y = uy.f; - if (uy.i == 0xff<<23) - return y; - if (ux.i >= 0xff<<23 || uy.i == 0 || ux.i - uy.i >= 25<<23) - return x + y; - - z = 1; - if (ux.i >= (0x7f+60)<<23) { - z = 0x1p90f; - x *= 0x1p-90f; - y *= 0x1p-90f; - } else if (uy.i < (0x7f-60)<<23) { - z = 0x1p-90f; - x *= 0x1p90f; - y *= 0x1p90f; - } - return z*sqrtf((double)x*x + (double)y*y); -} diff --git a/waterbox/libc/functions/math/hypotl.c b/waterbox/libc/functions/math/hypotl.c deleted file mode 100644 index 479aa92c3d..0000000000 --- a/waterbox/libc/functions/math/hypotl.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double hypotl(long double x, long double y) -{ - return hypot(x, y); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -#if LDBL_MANT_DIG == 64 -#define SPLIT (0x1p32L+1) -#elif LDBL_MANT_DIG == 113 -#define SPLIT (0x1p57L+1) -#endif - -static void sq(long double *hi, long double *lo, long double x) -{ - long double xh, xl, xc; - xc = x*SPLIT; - xh = x - xc + xc; - xl = x - xh; - *hi = x*x; - *lo = xh*xh - *hi + 2*xh*xl + xl*xl; -} - -long double hypotl(long double x, long double y) -{ - union ldshape ux = {x}, uy = {y}; - int ex, ey; - long double hx, lx, hy, ly, z; - - ux.i.se &= 0x7fff; - uy.i.se &= 0x7fff; - if (ux.i.se < uy.i.se) { - ex = uy.i.se; - ey = ux.i.se; - x = uy.f; - y = ux.f; - } else { - ex = ux.i.se; - ey = uy.i.se; - x = ux.f; - y = uy.f; - } - - if (ex == 0x7fff && isinf(y)) - return y; - if (ex == 0x7fff || y == 0) - return x; - if (ex - ey > LDBL_MANT_DIG) - return x + y; - - z = 1; - if (ex > 0x3fff+8000) { - z = 0x1p10000L; - x *= 0x1p-10000L; - y *= 0x1p-10000L; - } else if (ey < 0x3fff-8000) { - z = 0x1p-10000L; - x *= 0x1p10000L; - y *= 0x1p10000L; - } - sq(&hx, &lx, x); - sq(&hy, &ly, y); - return z*sqrtl(ly+lx+hy+hx); -} -#endif diff --git a/waterbox/libc/functions/math/ilogb.c b/waterbox/libc/functions/math/ilogb.c deleted file mode 100644 index 64d40154d6..0000000000 --- a/waterbox/libc/functions/math/ilogb.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include "libm.h" - -int ilogb(double x) -{ - #pragma STDC FENV_ACCESS ON - union {double f; uint64_t i;} u = {x}; - uint64_t i = u.i; - int e = i>>52 & 0x7ff; - - if (!e) { - i <<= 12; - if (i == 0) { - FORCE_EVAL(0/0.0f); - return FP_ILOGB0; - } - /* subnormal x */ - for (e = -0x3ff; i>>63 == 0; e--, i<<=1); - return e; - } - if (e == 0x7ff) { - FORCE_EVAL(0/0.0f); - return i<<12 ? FP_ILOGBNAN : INT_MAX; - } - return e - 0x3ff; -} diff --git a/waterbox/libc/functions/math/ilogbf.c b/waterbox/libc/functions/math/ilogbf.c deleted file mode 100644 index e23ba209ec..0000000000 --- a/waterbox/libc/functions/math/ilogbf.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include "libm.h" - -int ilogbf(float x) -{ - #pragma STDC FENV_ACCESS ON - union {float f; uint32_t i;} u = {x}; - uint32_t i = u.i; - int e = i>>23 & 0xff; - - if (!e) { - i <<= 9; - if (i == 0) { - FORCE_EVAL(0/0.0f); - return FP_ILOGB0; - } - /* subnormal x */ - for (e = -0x7f; i>>31 == 0; e--, i<<=1); - return e; - } - if (e == 0xff) { - FORCE_EVAL(0/0.0f); - return i<<9 ? FP_ILOGBNAN : INT_MAX; - } - return e - 0x7f; -} diff --git a/waterbox/libc/functions/math/ilogbl.c b/waterbox/libc/functions/math/ilogbl.c deleted file mode 100644 index 7b1a9cf8d0..0000000000 --- a/waterbox/libc/functions/math/ilogbl.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -int ilogbl(long double x) -{ - return ilogb(x); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -int ilogbl(long double x) -{ - #pragma STDC FENV_ACCESS ON - union ldshape u = {x}; - uint64_t m = u.i.m; - int e = u.i.se & 0x7fff; - - if (!e) { - if (m == 0) { - FORCE_EVAL(0/0.0f); - return FP_ILOGB0; - } - /* subnormal x */ - for (e = -0x3fff+1; m>>63 == 0; e--, m<<=1); - return e; - } - if (e == 0x7fff) { - FORCE_EVAL(0/0.0f); - return m<<1 ? FP_ILOGBNAN : INT_MAX; - } - return e - 0x3fff; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -int ilogbl(long double x) -{ - #pragma STDC FENV_ACCESS ON - union ldshape u = {x}; - int e = u.i.se & 0x7fff; - - if (!e) { - if (x == 0) { - FORCE_EVAL(0/0.0f); - return FP_ILOGB0; - } - /* subnormal x */ - x *= 0x1p120; - return ilogbl(x) - 120; - } - if (e == 0x7fff) { - FORCE_EVAL(0/0.0f); - u.i.se = 0; - return u.f ? FP_ILOGBNAN : INT_MAX; - } - return e - 0x3fff; -} -#endif diff --git a/waterbox/libc/functions/math/j0.c b/waterbox/libc/functions/math/j0.c deleted file mode 100644 index d722d94280..0000000000 --- a/waterbox/libc/functions/math/j0.c +++ /dev/null @@ -1,375 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_j0.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* j0(x), y0(x) - * Bessel function of the first and second kinds of order zero. - * Method -- j0(x): - * 1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ... - * 2. Reduce x to |x| since j0(x)=j0(-x), and - * for x in (0,2) - * j0(x) = 1-z/4+ z^2*R0/S0, where z = x*x; - * (precision: |j0-1+z/4-z^2R0/S0 |<2**-63.67 ) - * for x in (2,inf) - * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0)) - * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) - * as follow: - * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) - * = 1/sqrt(2) * (cos(x) + sin(x)) - * sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4) - * = 1/sqrt(2) * (sin(x) - cos(x)) - * (To avoid cancellation, use - * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) - * to compute the worse one.) - * - * 3 Special cases - * j0(nan)= nan - * j0(0) = 1 - * j0(inf) = 0 - * - * Method -- y0(x): - * 1. For x<2. - * Since - * y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...) - * therefore y0(x)-2/pi*j0(x)*ln(x) is an even function. - * We use the following function to approximate y0, - * y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2 - * where - * U(z) = u00 + u01*z + ... + u06*z^6 - * V(z) = 1 + v01*z + ... + v04*z^4 - * with absolute approximation error bounded by 2**-72. - * Note: For tiny x, U/V = u0 and j0(x)~1, hence - * y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27) - * 2. For x>=2. - * y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0)) - * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) - * by the method mentioned above. - * 3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0. - */ - -#include "libm.h" - -static double pzero(double), qzero(double); - -static const double -invsqrtpi = 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ -tpi = 6.36619772367581382433e-01; /* 0x3FE45F30, 0x6DC9C883 */ - -/* common method when |x|>=2 */ -static double common(uint32_t ix, double x, int y0) -{ - double s,c,ss,cc,z; - - /* - * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x-pi/4)-q0(x)*sin(x-pi/4)) - * y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x-pi/4)+q0(x)*cos(x-pi/4)) - * - * sin(x-pi/4) = (sin(x) - cos(x))/sqrt(2) - * cos(x-pi/4) = (sin(x) + cos(x))/sqrt(2) - * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) - */ - s = sin(x); - c = cos(x); - if (y0) - c = -c; - cc = s+c; - /* avoid overflow in 2*x, big ulp error when x>=0x1p1023 */ - if (ix < 0x7fe00000) { - ss = s-c; - z = -cos(2*x); - if (s*c < 0) - cc = z/ss; - else - ss = z/cc; - if (ix < 0x48000000) { - if (y0) - ss = -ss; - cc = pzero(x)*cc-qzero(x)*ss; - } - } - return invsqrtpi*cc/sqrt(x); -} - -/* R0/S0 on [0, 2.00] */ -static const double -R02 = 1.56249999999999947958e-02, /* 0x3F8FFFFF, 0xFFFFFFFD */ -R03 = -1.89979294238854721751e-04, /* 0xBF28E6A5, 0xB61AC6E9 */ -R04 = 1.82954049532700665670e-06, /* 0x3EBEB1D1, 0x0C503919 */ -R05 = -4.61832688532103189199e-09, /* 0xBE33D5E7, 0x73D63FCE */ -S01 = 1.56191029464890010492e-02, /* 0x3F8FFCE8, 0x82C8C2A4 */ -S02 = 1.16926784663337450260e-04, /* 0x3F1EA6D2, 0xDD57DBF4 */ -S03 = 5.13546550207318111446e-07, /* 0x3EA13B54, 0xCE84D5A9 */ -S04 = 1.16614003333790000205e-09; /* 0x3E1408BC, 0xF4745D8F */ - -double j0(double x) -{ - double z,r,s; - uint32_t ix; - - GET_HIGH_WORD(ix, x); - ix &= 0x7fffffff; - - /* j0(+-inf)=0, j0(nan)=nan */ - if (ix >= 0x7ff00000) - return 1/(x*x); - x = fabs(x); - - if (ix >= 0x40000000) { /* |x| >= 2 */ - /* large ulp error near zeros: 2.4, 5.52, 8.6537,.. */ - return common(ix,x,0); - } - - /* 1 - x*x/4 + x*x*R(x^2)/S(x^2) */ - if (ix >= 0x3f200000) { /* |x| >= 2**-13 */ - /* up to 4ulp error close to 2 */ - z = x*x; - r = z*(R02+z*(R03+z*(R04+z*R05))); - s = 1+z*(S01+z*(S02+z*(S03+z*S04))); - return (1+x/2)*(1-x/2) + z*(r/s); - } - - /* 1 - x*x/4 */ - /* prevent underflow */ - /* inexact should be raised when x!=0, this is not done correctly */ - if (ix >= 0x38000000) /* |x| >= 2**-127 */ - x = 0.25*x*x; - return 1 - x; -} - -static const double -u00 = -7.38042951086872317523e-02, /* 0xBFB2E4D6, 0x99CBD01F */ -u01 = 1.76666452509181115538e-01, /* 0x3FC69D01, 0x9DE9E3FC */ -u02 = -1.38185671945596898896e-02, /* 0xBF8C4CE8, 0xB16CFA97 */ -u03 = 3.47453432093683650238e-04, /* 0x3F36C54D, 0x20B29B6B */ -u04 = -3.81407053724364161125e-06, /* 0xBECFFEA7, 0x73D25CAD */ -u05 = 1.95590137035022920206e-08, /* 0x3E550057, 0x3B4EABD4 */ -u06 = -3.98205194132103398453e-11, /* 0xBDC5E43D, 0x693FB3C8 */ -v01 = 1.27304834834123699328e-02, /* 0x3F8A1270, 0x91C9C71A */ -v02 = 7.60068627350353253702e-05, /* 0x3F13ECBB, 0xF578C6C1 */ -v03 = 2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */ -v04 = 4.41110311332675467403e-10; /* 0x3DFE5018, 0x3BD6D9EF */ - -double y0(double x) -{ - double z,u,v; - uint32_t ix,lx; - - EXTRACT_WORDS(ix, lx, x); - - /* y0(nan)=nan, y0(<0)=nan, y0(0)=-inf, y0(inf)=0 */ - if ((ix<<1 | lx) == 0) - return -1/0.0; - if (ix>>31) - return 0/0.0; - if (ix >= 0x7ff00000) - return 1/x; - - if (ix >= 0x40000000) { /* x >= 2 */ - /* large ulp errors near zeros: 3.958, 7.086,.. */ - return common(ix,x,1); - } - - /* U(x^2)/V(x^2) + (2/pi)*j0(x)*log(x) */ - if (ix >= 0x3e400000) { /* x >= 2**-27 */ - /* large ulp error near the first zero, x ~= 0.89 */ - z = x*x; - u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06))))); - v = 1.0+z*(v01+z*(v02+z*(v03+z*v04))); - return u/v + tpi*(j0(x)*log(x)); - } - return u00 + tpi*log(x); -} - -/* The asymptotic expansions of pzero is - * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x. - * For x >= 2, We approximate pzero by - * pzero(x) = 1 + (R/S) - * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10 - * S = 1 + pS0*s^2 + ... + pS4*s^10 - * and - * | pzero(x)-1-R/S | <= 2 ** ( -60.26) - */ -static const double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ - 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ - -7.03124999999900357484e-02, /* 0xBFB1FFFF, 0xFFFFFD32 */ - -8.08167041275349795626e+00, /* 0xC02029D0, 0xB44FA779 */ - -2.57063105679704847262e+02, /* 0xC0701102, 0x7B19E863 */ - -2.48521641009428822144e+03, /* 0xC0A36A6E, 0xCD4DCAFC */ - -5.25304380490729545272e+03, /* 0xC0B4850B, 0x36CC643D */ -}; -static const double pS8[5] = { - 1.16534364619668181717e+02, /* 0x405D2233, 0x07A96751 */ - 3.83374475364121826715e+03, /* 0x40ADF37D, 0x50596938 */ - 4.05978572648472545552e+04, /* 0x40E3D2BB, 0x6EB6B05F */ - 1.16752972564375915681e+05, /* 0x40FC810F, 0x8F9FA9BD */ - 4.76277284146730962675e+04, /* 0x40E74177, 0x4F2C49DC */ -}; - -static const double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ - -1.14125464691894502584e-11, /* 0xBDA918B1, 0x47E495CC */ - -7.03124940873599280078e-02, /* 0xBFB1FFFF, 0xE69AFBC6 */ - -4.15961064470587782438e+00, /* 0xC010A370, 0xF90C6BBF */ - -6.76747652265167261021e+01, /* 0xC050EB2F, 0x5A7D1783 */ - -3.31231299649172967747e+02, /* 0xC074B3B3, 0x6742CC63 */ - -3.46433388365604912451e+02, /* 0xC075A6EF, 0x28A38BD7 */ -}; -static const double pS5[5] = { - 6.07539382692300335975e+01, /* 0x404E6081, 0x0C98C5DE */ - 1.05125230595704579173e+03, /* 0x40906D02, 0x5C7E2864 */ - 5.97897094333855784498e+03, /* 0x40B75AF8, 0x8FBE1D60 */ - 9.62544514357774460223e+03, /* 0x40C2CCB8, 0xFA76FA38 */ - 2.40605815922939109441e+03, /* 0x40A2CC1D, 0xC70BE864 */ -}; - -static const double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ - -2.54704601771951915620e-09, /* 0xBE25E103, 0x6FE1AA86 */ - -7.03119616381481654654e-02, /* 0xBFB1FFF6, 0xF7C0E24B */ - -2.40903221549529611423e+00, /* 0xC00345B2, 0xAEA48074 */ - -2.19659774734883086467e+01, /* 0xC035F74A, 0x4CB94E14 */ - -5.80791704701737572236e+01, /* 0xC04D0A22, 0x420A1A45 */ - -3.14479470594888503854e+01, /* 0xC03F72AC, 0xA892D80F */ -}; -static const double pS3[5] = { - 3.58560338055209726349e+01, /* 0x4041ED92, 0x84077DD3 */ - 3.61513983050303863820e+02, /* 0x40769839, 0x464A7C0E */ - 1.19360783792111533330e+03, /* 0x4092A66E, 0x6D1061D6 */ - 1.12799679856907414432e+03, /* 0x40919FFC, 0xB8C39B7E */ - 1.73580930813335754692e+02, /* 0x4065B296, 0xFC379081 */ -}; - -static const double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ - -8.87534333032526411254e-08, /* 0xBE77D316, 0xE927026D */ - -7.03030995483624743247e-02, /* 0xBFB1FF62, 0x495E1E42 */ - -1.45073846780952986357e+00, /* 0xBFF73639, 0x8A24A843 */ - -7.63569613823527770791e+00, /* 0xC01E8AF3, 0xEDAFA7F3 */ - -1.11931668860356747786e+01, /* 0xC02662E6, 0xC5246303 */ - -3.23364579351335335033e+00, /* 0xC009DE81, 0xAF8FE70F */ -}; -static const double pS2[5] = { - 2.22202997532088808441e+01, /* 0x40363865, 0x908B5959 */ - 1.36206794218215208048e+02, /* 0x4061069E, 0x0EE8878F */ - 2.70470278658083486789e+02, /* 0x4070E786, 0x42EA079B */ - 1.53875394208320329881e+02, /* 0x40633C03, 0x3AB6FAFF */ - 1.46576176948256193810e+01, /* 0x402D50B3, 0x44391809 */ -}; - -static double pzero(double x) -{ - const double *p,*q; - double_t z,r,s; - uint32_t ix; - - GET_HIGH_WORD(ix, x); - ix &= 0x7fffffff; - if (ix >= 0x40200000){p = pR8; q = pS8;} - else if (ix >= 0x40122E8B){p = pR5; q = pS5;} - else if (ix >= 0x4006DB6D){p = pR3; q = pS3;} - else /*ix >= 0x40000000*/ {p = pR2; q = pS2;} - z = 1.0/(x*x); - r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); - s = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); - return 1.0 + r/s; -} - - -/* For x >= 8, the asymptotic expansions of qzero is - * -1/8 s + 75/1024 s^3 - ..., where s = 1/x. - * We approximate pzero by - * qzero(x) = s*(-1.25 + (R/S)) - * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10 - * S = 1 + qS0*s^2 + ... + qS5*s^12 - * and - * | qzero(x)/s +1.25-R/S | <= 2 ** ( -61.22) - */ -static const double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ - 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ - 7.32421874999935051953e-02, /* 0x3FB2BFFF, 0xFFFFFE2C */ - 1.17682064682252693899e+01, /* 0x40278952, 0x5BB334D6 */ - 5.57673380256401856059e+02, /* 0x40816D63, 0x15301825 */ - 8.85919720756468632317e+03, /* 0x40C14D99, 0x3E18F46D */ - 3.70146267776887834771e+04, /* 0x40E212D4, 0x0E901566 */ -}; -static const double qS8[6] = { - 1.63776026895689824414e+02, /* 0x406478D5, 0x365B39BC */ - 8.09834494656449805916e+03, /* 0x40BFA258, 0x4E6B0563 */ - 1.42538291419120476348e+05, /* 0x41016652, 0x54D38C3F */ - 8.03309257119514397345e+05, /* 0x412883DA, 0x83A52B43 */ - 8.40501579819060512818e+05, /* 0x4129A66B, 0x28DE0B3D */ - -3.43899293537866615225e+05, /* 0xC114FD6D, 0x2C9530C5 */ -}; - -static const double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ - 1.84085963594515531381e-11, /* 0x3DB43D8F, 0x29CC8CD9 */ - 7.32421766612684765896e-02, /* 0x3FB2BFFF, 0xD172B04C */ - 5.83563508962056953777e+00, /* 0x401757B0, 0xB9953DD3 */ - 1.35111577286449829671e+02, /* 0x4060E392, 0x0A8788E9 */ - 1.02724376596164097464e+03, /* 0x40900CF9, 0x9DC8C481 */ - 1.98997785864605384631e+03, /* 0x409F17E9, 0x53C6E3A6 */ -}; -static const double qS5[6] = { - 8.27766102236537761883e+01, /* 0x4054B1B3, 0xFB5E1543 */ - 2.07781416421392987104e+03, /* 0x40A03BA0, 0xDA21C0CE */ - 1.88472887785718085070e+04, /* 0x40D267D2, 0x7B591E6D */ - 5.67511122894947329769e+04, /* 0x40EBB5E3, 0x97E02372 */ - 3.59767538425114471465e+04, /* 0x40E19118, 0x1F7A54A0 */ - -5.35434275601944773371e+03, /* 0xC0B4EA57, 0xBEDBC609 */ -}; - -static const double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ - 4.37741014089738620906e-09, /* 0x3E32CD03, 0x6ADECB82 */ - 7.32411180042911447163e-02, /* 0x3FB2BFEE, 0x0E8D0842 */ - 3.34423137516170720929e+00, /* 0x400AC0FC, 0x61149CF5 */ - 4.26218440745412650017e+01, /* 0x40454F98, 0x962DAEDD */ - 1.70808091340565596283e+02, /* 0x406559DB, 0xE25EFD1F */ - 1.66733948696651168575e+02, /* 0x4064D77C, 0x81FA21E0 */ -}; -static const double qS3[6] = { - 4.87588729724587182091e+01, /* 0x40486122, 0xBFE343A6 */ - 7.09689221056606015736e+02, /* 0x40862D83, 0x86544EB3 */ - 3.70414822620111362994e+03, /* 0x40ACF04B, 0xE44DFC63 */ - 6.46042516752568917582e+03, /* 0x40B93C6C, 0xD7C76A28 */ - 2.51633368920368957333e+03, /* 0x40A3A8AA, 0xD94FB1C0 */ - -1.49247451836156386662e+02, /* 0xC062A7EB, 0x201CF40F */ -}; - -static const double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ - 1.50444444886983272379e-07, /* 0x3E84313B, 0x54F76BDB */ - 7.32234265963079278272e-02, /* 0x3FB2BEC5, 0x3E883E34 */ - 1.99819174093815998816e+00, /* 0x3FFFF897, 0xE727779C */ - 1.44956029347885735348e+01, /* 0x402CFDBF, 0xAAF96FE5 */ - 3.16662317504781540833e+01, /* 0x403FAA8E, 0x29FBDC4A */ - 1.62527075710929267416e+01, /* 0x403040B1, 0x71814BB4 */ -}; -static const double qS2[6] = { - 3.03655848355219184498e+01, /* 0x403E5D96, 0xF7C07AED */ - 2.69348118608049844624e+02, /* 0x4070D591, 0xE4D14B40 */ - 8.44783757595320139444e+02, /* 0x408A6645, 0x22B3BF22 */ - 8.82935845112488550512e+02, /* 0x408B977C, 0x9C5CC214 */ - 2.12666388511798828631e+02, /* 0x406A9553, 0x0E001365 */ - -5.31095493882666946917e+00, /* 0xC0153E6A, 0xF8B32931 */ -}; - -static double qzero(double x) -{ - const double *p,*q; - double_t s,r,z; - uint32_t ix; - - GET_HIGH_WORD(ix, x); - ix &= 0x7fffffff; - if (ix >= 0x40200000){p = qR8; q = qS8;} - else if (ix >= 0x40122E8B){p = qR5; q = qS5;} - else if (ix >= 0x4006DB6D){p = qR3; q = qS3;} - else /*ix >= 0x40000000*/ {p = qR2; q = qS2;} - z = 1.0/(x*x); - r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); - s = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); - return (-.125 + r/s)/x; -} diff --git a/waterbox/libc/functions/math/j0f.c b/waterbox/libc/functions/math/j0f.c deleted file mode 100644 index 45883dc419..0000000000 --- a/waterbox/libc/functions/math/j0f.c +++ /dev/null @@ -1,314 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_j0f.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#define _GNU_SOURCE -#include "libm.h" - -static float pzerof(float), qzerof(float); - -static const float -invsqrtpi = 5.6418961287e-01, /* 0x3f106ebb */ -tpi = 6.3661974669e-01; /* 0x3f22f983 */ - -static float common(uint32_t ix, float x, int y0) -{ - float z,s,c,ss,cc; - /* - * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) - * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) - */ - s = sinf(x); - c = cosf(x); - if (y0) - c = -c; - cc = s+c; - if (ix < 0x7f000000) { - ss = s-c; - z = -cosf(2*x); - if (s*c < 0) - cc = z/ss; - else - ss = z/cc; - if (ix < 0x58800000) { - if (y0) - ss = -ss; - cc = pzerof(x)*cc-qzerof(x)*ss; - } - } - return invsqrtpi*cc/sqrtf(x); -} - -/* R0/S0 on [0, 2.00] */ -static const float -R02 = 1.5625000000e-02, /* 0x3c800000 */ -R03 = -1.8997929874e-04, /* 0xb947352e */ -R04 = 1.8295404516e-06, /* 0x35f58e88 */ -R05 = -4.6183270541e-09, /* 0xb19eaf3c */ -S01 = 1.5619102865e-02, /* 0x3c7fe744 */ -S02 = 1.1692678527e-04, /* 0x38f53697 */ -S03 = 5.1354652442e-07, /* 0x3509daa6 */ -S04 = 1.1661400734e-09; /* 0x30a045e8 */ - -float j0f(float x) -{ - float z,r,s; - uint32_t ix; - - GET_FLOAT_WORD(ix, x); - ix &= 0x7fffffff; - if (ix >= 0x7f800000) - return 1/(x*x); - x = fabsf(x); - - if (ix >= 0x40000000) { /* |x| >= 2 */ - /* large ulp error near zeros */ - return common(ix, x, 0); - } - if (ix >= 0x3a000000) { /* |x| >= 2**-11 */ - /* up to 4ulp error near 2 */ - z = x*x; - r = z*(R02+z*(R03+z*(R04+z*R05))); - s = 1+z*(S01+z*(S02+z*(S03+z*S04))); - return (1+x/2)*(1-x/2) + z*(r/s); - } - if (ix >= 0x21800000) /* |x| >= 2**-60 */ - x = 0.25f*x*x; - return 1 - x; -} - -static const float -u00 = -7.3804296553e-02, /* 0xbd9726b5 */ -u01 = 1.7666645348e-01, /* 0x3e34e80d */ -u02 = -1.3818567619e-02, /* 0xbc626746 */ -u03 = 3.4745343146e-04, /* 0x39b62a69 */ -u04 = -3.8140706238e-06, /* 0xb67ff53c */ -u05 = 1.9559013964e-08, /* 0x32a802ba */ -u06 = -3.9820518410e-11, /* 0xae2f21eb */ -v01 = 1.2730483897e-02, /* 0x3c509385 */ -v02 = 7.6006865129e-05, /* 0x389f65e0 */ -v03 = 2.5915085189e-07, /* 0x348b216c */ -v04 = 4.4111031494e-10; /* 0x2ff280c2 */ - -float y0f(float x) -{ - float z,u,v; - uint32_t ix; - - GET_FLOAT_WORD(ix, x); - if ((ix & 0x7fffffff) == 0) - return -1/0.0f; - if (ix>>31) - return 0/0.0f; - if (ix >= 0x7f800000) - return 1/x; - if (ix >= 0x40000000) { /* |x| >= 2.0 */ - /* large ulp error near zeros */ - return common(ix,x,1); - } - if (ix >= 0x39000000) { /* x >= 2**-13 */ - /* large ulp error at x ~= 0.89 */ - z = x*x; - u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06))))); - v = 1+z*(v01+z*(v02+z*(v03+z*v04))); - return u/v + tpi*(j0f(x)*logf(x)); - } - return u00 + tpi*logf(x); -} - -/* The asymptotic expansions of pzero is - * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x. - * For x >= 2, We approximate pzero by - * pzero(x) = 1 + (R/S) - * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10 - * S = 1 + pS0*s^2 + ... + pS4*s^10 - * and - * | pzero(x)-1-R/S | <= 2 ** ( -60.26) - */ -static const float pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ - 0.0000000000e+00, /* 0x00000000 */ - -7.0312500000e-02, /* 0xbd900000 */ - -8.0816707611e+00, /* 0xc1014e86 */ - -2.5706311035e+02, /* 0xc3808814 */ - -2.4852163086e+03, /* 0xc51b5376 */ - -5.2530439453e+03, /* 0xc5a4285a */ -}; -static const float pS8[5] = { - 1.1653436279e+02, /* 0x42e91198 */ - 3.8337448730e+03, /* 0x456f9beb */ - 4.0597855469e+04, /* 0x471e95db */ - 1.1675296875e+05, /* 0x47e4087c */ - 4.7627726562e+04, /* 0x473a0bba */ -}; -static const float pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ - -1.1412546255e-11, /* 0xad48c58a */ - -7.0312492549e-02, /* 0xbd8fffff */ - -4.1596107483e+00, /* 0xc0851b88 */ - -6.7674766541e+01, /* 0xc287597b */ - -3.3123129272e+02, /* 0xc3a59d9b */ - -3.4643338013e+02, /* 0xc3ad3779 */ -}; -static const float pS5[5] = { - 6.0753936768e+01, /* 0x42730408 */ - 1.0512523193e+03, /* 0x44836813 */ - 5.9789707031e+03, /* 0x45bad7c4 */ - 9.6254453125e+03, /* 0x461665c8 */ - 2.4060581055e+03, /* 0x451660ee */ -}; - -static const float pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ - -2.5470459075e-09, /* 0xb12f081b */ - -7.0311963558e-02, /* 0xbd8fffb8 */ - -2.4090321064e+00, /* 0xc01a2d95 */ - -2.1965976715e+01, /* 0xc1afba52 */ - -5.8079170227e+01, /* 0xc2685112 */ - -3.1447946548e+01, /* 0xc1fb9565 */ -}; -static const float pS3[5] = { - 3.5856033325e+01, /* 0x420f6c94 */ - 3.6151397705e+02, /* 0x43b4c1ca */ - 1.1936077881e+03, /* 0x44953373 */ - 1.1279968262e+03, /* 0x448cffe6 */ - 1.7358093262e+02, /* 0x432d94b8 */ -}; - -static const float pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ - -8.8753431271e-08, /* 0xb3be98b7 */ - -7.0303097367e-02, /* 0xbd8ffb12 */ - -1.4507384300e+00, /* 0xbfb9b1cc */ - -7.6356959343e+00, /* 0xc0f4579f */ - -1.1193166733e+01, /* 0xc1331736 */ - -3.2336456776e+00, /* 0xc04ef40d */ -}; -static const float pS2[5] = { - 2.2220300674e+01, /* 0x41b1c32d */ - 1.3620678711e+02, /* 0x430834f0 */ - 2.7047027588e+02, /* 0x43873c32 */ - 1.5387539673e+02, /* 0x4319e01a */ - 1.4657617569e+01, /* 0x416a859a */ -}; - -static float pzerof(float x) -{ - const float *p,*q; - float_t z,r,s; - uint32_t ix; - - GET_FLOAT_WORD(ix, x); - ix &= 0x7fffffff; - if (ix >= 0x41000000){p = pR8; q = pS8;} - else if (ix >= 0x40f71c58){p = pR5; q = pS5;} - else if (ix >= 0x4036db68){p = pR3; q = pS3;} - else /*ix >= 0x40000000*/ {p = pR2; q = pS2;} - z = 1.0f/(x*x); - r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); - s = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); - return 1.0f + r/s; -} - - -/* For x >= 8, the asymptotic expansions of qzero is - * -1/8 s + 75/1024 s^3 - ..., where s = 1/x. - * We approximate pzero by - * qzero(x) = s*(-1.25 + (R/S)) - * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10 - * S = 1 + qS0*s^2 + ... + qS5*s^12 - * and - * | qzero(x)/s +1.25-R/S | <= 2 ** ( -61.22) - */ -static const float qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ - 0.0000000000e+00, /* 0x00000000 */ - 7.3242187500e-02, /* 0x3d960000 */ - 1.1768206596e+01, /* 0x413c4a93 */ - 5.5767340088e+02, /* 0x440b6b19 */ - 8.8591972656e+03, /* 0x460a6cca */ - 3.7014625000e+04, /* 0x471096a0 */ -}; -static const float qS8[6] = { - 1.6377603149e+02, /* 0x4323c6aa */ - 8.0983447266e+03, /* 0x45fd12c2 */ - 1.4253829688e+05, /* 0x480b3293 */ - 8.0330925000e+05, /* 0x49441ed4 */ - 8.4050156250e+05, /* 0x494d3359 */ - -3.4389928125e+05, /* 0xc8a7eb69 */ -}; - -static const float qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ - 1.8408595828e-11, /* 0x2da1ec79 */ - 7.3242180049e-02, /* 0x3d95ffff */ - 5.8356351852e+00, /* 0x40babd86 */ - 1.3511157227e+02, /* 0x43071c90 */ - 1.0272437744e+03, /* 0x448067cd */ - 1.9899779053e+03, /* 0x44f8bf4b */ -}; -static const float qS5[6] = { - 8.2776611328e+01, /* 0x42a58da0 */ - 2.0778142090e+03, /* 0x4501dd07 */ - 1.8847289062e+04, /* 0x46933e94 */ - 5.6751113281e+04, /* 0x475daf1d */ - 3.5976753906e+04, /* 0x470c88c1 */ - -5.3543427734e+03, /* 0xc5a752be */ -}; - -static const float qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ - 4.3774099900e-09, /* 0x3196681b */ - 7.3241114616e-02, /* 0x3d95ff70 */ - 3.3442313671e+00, /* 0x405607e3 */ - 4.2621845245e+01, /* 0x422a7cc5 */ - 1.7080809021e+02, /* 0x432acedf */ - 1.6673394775e+02, /* 0x4326bbe4 */ -}; -static const float qS3[6] = { - 4.8758872986e+01, /* 0x42430916 */ - 7.0968920898e+02, /* 0x44316c1c */ - 3.7041481934e+03, /* 0x4567825f */ - 6.4604252930e+03, /* 0x45c9e367 */ - 2.5163337402e+03, /* 0x451d4557 */ - -1.4924745178e+02, /* 0xc3153f59 */ -}; - -static const float qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ - 1.5044444979e-07, /* 0x342189db */ - 7.3223426938e-02, /* 0x3d95f62a */ - 1.9981917143e+00, /* 0x3fffc4bf */ - 1.4495602608e+01, /* 0x4167edfd */ - 3.1666231155e+01, /* 0x41fd5471 */ - 1.6252708435e+01, /* 0x4182058c */ -}; -static const float qS2[6] = { - 3.0365585327e+01, /* 0x41f2ecb8 */ - 2.6934811401e+02, /* 0x4386ac8f */ - 8.4478375244e+02, /* 0x44533229 */ - 8.8293585205e+02, /* 0x445cbbe5 */ - 2.1266638184e+02, /* 0x4354aa98 */ - -5.3109550476e+00, /* 0xc0a9f358 */ -}; - -static float qzerof(float x) -{ - const float *p,*q; - float_t s,r,z; - uint32_t ix; - - GET_FLOAT_WORD(ix, x); - ix &= 0x7fffffff; - if (ix >= 0x41000000){p = qR8; q = qS8;} - else if (ix >= 0x40f71c58){p = qR5; q = qS5;} - else if (ix >= 0x4036db68){p = qR3; q = qS3;} - else /*ix >= 0x40000000*/ {p = qR2; q = qS2;} - z = 1.0f/(x*x); - r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); - s = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); - return (-.125f + r/s)/x; -} diff --git a/waterbox/libc/functions/math/j1.c b/waterbox/libc/functions/math/j1.c deleted file mode 100644 index df724d172e..0000000000 --- a/waterbox/libc/functions/math/j1.c +++ /dev/null @@ -1,362 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_j1.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* j1(x), y1(x) - * Bessel function of the first and second kinds of order zero. - * Method -- j1(x): - * 1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ... - * 2. Reduce x to |x| since j1(x)=-j1(-x), and - * for x in (0,2) - * j1(x) = x/2 + x*z*R0/S0, where z = x*x; - * (precision: |j1/x - 1/2 - R0/S0 |<2**-61.51 ) - * for x in (2,inf) - * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1)) - * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1)) - * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1) - * as follow: - * cos(x1) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) - * = 1/sqrt(2) * (sin(x) - cos(x)) - * sin(x1) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) - * = -1/sqrt(2) * (sin(x) + cos(x)) - * (To avoid cancellation, use - * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) - * to compute the worse one.) - * - * 3 Special cases - * j1(nan)= nan - * j1(0) = 0 - * j1(inf) = 0 - * - * Method -- y1(x): - * 1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN - * 2. For x<2. - * Since - * y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x^3-...) - * therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function. - * We use the following function to approximate y1, - * y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x^2 - * where for x in [0,2] (abs err less than 2**-65.89) - * U(z) = U0[0] + U0[1]*z + ... + U0[4]*z^4 - * V(z) = 1 + v0[0]*z + ... + v0[4]*z^5 - * Note: For tiny x, 1/x dominate y1 and hence - * y1(tiny) = -2/pi/tiny, (choose tiny<2**-54) - * 3. For x>=2. - * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1)) - * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1) - * by method mentioned above. - */ - -#include "libm.h" - -static double pone(double), qone(double); - -static const double -invsqrtpi = 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ -tpi = 6.36619772367581382433e-01; /* 0x3FE45F30, 0x6DC9C883 */ - -static double common(uint32_t ix, double x, int y1, int sign) -{ - double z,s,c,ss,cc; - - /* - * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x-3pi/4)-q1(x)*sin(x-3pi/4)) - * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x-3pi/4)+q1(x)*cos(x-3pi/4)) - * - * sin(x-3pi/4) = -(sin(x) + cos(x))/sqrt(2) - * cos(x-3pi/4) = (sin(x) - cos(x))/sqrt(2) - * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) - */ - s = sin(x); - if (y1) - s = -s; - c = cos(x); - cc = s-c; - if (ix < 0x7fe00000) { - /* avoid overflow in 2*x */ - ss = -s-c; - z = cos(2*x); - if (s*c > 0) - cc = z/ss; - else - ss = z/cc; - if (ix < 0x48000000) { - if (y1) - ss = -ss; - cc = pone(x)*cc-qone(x)*ss; - } - } - if (sign) - cc = -cc; - return invsqrtpi*cc/sqrt(x); -} - -/* R0/S0 on [0,2] */ -static const double -r00 = -6.25000000000000000000e-02, /* 0xBFB00000, 0x00000000 */ -r01 = 1.40705666955189706048e-03, /* 0x3F570D9F, 0x98472C61 */ -r02 = -1.59955631084035597520e-05, /* 0xBEF0C5C6, 0xBA169668 */ -r03 = 4.96727999609584448412e-08, /* 0x3E6AAAFA, 0x46CA0BD9 */ -s01 = 1.91537599538363460805e-02, /* 0x3F939D0B, 0x12637E53 */ -s02 = 1.85946785588630915560e-04, /* 0x3F285F56, 0xB9CDF664 */ -s03 = 1.17718464042623683263e-06, /* 0x3EB3BFF8, 0x333F8498 */ -s04 = 5.04636257076217042715e-09, /* 0x3E35AC88, 0xC97DFF2C */ -s05 = 1.23542274426137913908e-11; /* 0x3DAB2ACF, 0xCFB97ED8 */ - -double j1(double x) -{ - double z,r,s; - uint32_t ix; - int sign; - - GET_HIGH_WORD(ix, x); - sign = ix>>31; - ix &= 0x7fffffff; - if (ix >= 0x7ff00000) - return 1/(x*x); - if (ix >= 0x40000000) /* |x| >= 2 */ - return common(ix, fabs(x), 0, sign); - if (ix >= 0x38000000) { /* |x| >= 2**-127 */ - z = x*x; - r = z*(r00+z*(r01+z*(r02+z*r03))); - s = 1+z*(s01+z*(s02+z*(s03+z*(s04+z*s05)))); - z = r/s; - } else - /* avoid underflow, raise inexact if x!=0 */ - z = x; - return (0.5 + z)*x; -} - -static const double U0[5] = { - -1.96057090646238940668e-01, /* 0xBFC91866, 0x143CBC8A */ - 5.04438716639811282616e-02, /* 0x3FA9D3C7, 0x76292CD1 */ - -1.91256895875763547298e-03, /* 0xBF5F55E5, 0x4844F50F */ - 2.35252600561610495928e-05, /* 0x3EF8AB03, 0x8FA6B88E */ - -9.19099158039878874504e-08, /* 0xBE78AC00, 0x569105B8 */ -}; -static const double V0[5] = { - 1.99167318236649903973e-02, /* 0x3F94650D, 0x3F4DA9F0 */ - 2.02552581025135171496e-04, /* 0x3F2A8C89, 0x6C257764 */ - 1.35608801097516229404e-06, /* 0x3EB6C05A, 0x894E8CA6 */ - 6.22741452364621501295e-09, /* 0x3E3ABF1D, 0x5BA69A86 */ - 1.66559246207992079114e-11, /* 0x3DB25039, 0xDACA772A */ -}; - -double y1(double x) -{ - double z,u,v; - uint32_t ix,lx; - - EXTRACT_WORDS(ix, lx, x); - /* y1(nan)=nan, y1(<0)=nan, y1(0)=-inf, y1(inf)=0 */ - if ((ix<<1 | lx) == 0) - return -1/0.0; - if (ix>>31) - return 0/0.0; - if (ix >= 0x7ff00000) - return 1/x; - - if (ix >= 0x40000000) /* x >= 2 */ - return common(ix, x, 1, 0); - if (ix < 0x3c900000) /* x < 2**-54 */ - return -tpi/x; - z = x*x; - u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4]))); - v = 1+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4])))); - return x*(u/v) + tpi*(j1(x)*log(x)-1/x); -} - -/* For x >= 8, the asymptotic expansions of pone is - * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x. - * We approximate pone by - * pone(x) = 1 + (R/S) - * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10 - * S = 1 + ps0*s^2 + ... + ps4*s^10 - * and - * | pone(x)-1-R/S | <= 2 ** ( -60.06) - */ - -static const double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ - 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ - 1.17187499999988647970e-01, /* 0x3FBDFFFF, 0xFFFFFCCE */ - 1.32394806593073575129e+01, /* 0x402A7A9D, 0x357F7FCE */ - 4.12051854307378562225e+02, /* 0x4079C0D4, 0x652EA590 */ - 3.87474538913960532227e+03, /* 0x40AE457D, 0xA3A532CC */ - 7.91447954031891731574e+03, /* 0x40BEEA7A, 0xC32782DD */ -}; -static const double ps8[5] = { - 1.14207370375678408436e+02, /* 0x405C8D45, 0x8E656CAC */ - 3.65093083420853463394e+03, /* 0x40AC85DC, 0x964D274F */ - 3.69562060269033463555e+04, /* 0x40E20B86, 0x97C5BB7F */ - 9.76027935934950801311e+04, /* 0x40F7D42C, 0xB28F17BB */ - 3.08042720627888811578e+04, /* 0x40DE1511, 0x697A0B2D */ -}; - -static const double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ - 1.31990519556243522749e-11, /* 0x3DAD0667, 0xDAE1CA7D */ - 1.17187493190614097638e-01, /* 0x3FBDFFFF, 0xE2C10043 */ - 6.80275127868432871736e+00, /* 0x401B3604, 0x6E6315E3 */ - 1.08308182990189109773e+02, /* 0x405B13B9, 0x452602ED */ - 5.17636139533199752805e+02, /* 0x40802D16, 0xD052D649 */ - 5.28715201363337541807e+02, /* 0x408085B8, 0xBB7E0CB7 */ -}; -static const double ps5[5] = { - 5.92805987221131331921e+01, /* 0x404DA3EA, 0xA8AF633D */ - 9.91401418733614377743e+02, /* 0x408EFB36, 0x1B066701 */ - 5.35326695291487976647e+03, /* 0x40B4E944, 0x5706B6FB */ - 7.84469031749551231769e+03, /* 0x40BEA4B0, 0xB8A5BB15 */ - 1.50404688810361062679e+03, /* 0x40978030, 0x036F5E51 */ -}; - -static const double pr3[6] = { - 3.02503916137373618024e-09, /* 0x3E29FC21, 0xA7AD9EDD */ - 1.17186865567253592491e-01, /* 0x3FBDFFF5, 0x5B21D17B */ - 3.93297750033315640650e+00, /* 0x400F76BC, 0xE85EAD8A */ - 3.51194035591636932736e+01, /* 0x40418F48, 0x9DA6D129 */ - 9.10550110750781271918e+01, /* 0x4056C385, 0x4D2C1837 */ - 4.85590685197364919645e+01, /* 0x4048478F, 0x8EA83EE5 */ -}; -static const double ps3[5] = { - 3.47913095001251519989e+01, /* 0x40416549, 0xA134069C */ - 3.36762458747825746741e+02, /* 0x40750C33, 0x07F1A75F */ - 1.04687139975775130551e+03, /* 0x40905B7C, 0x5037D523 */ - 8.90811346398256432622e+02, /* 0x408BD67D, 0xA32E31E9 */ - 1.03787932439639277504e+02, /* 0x4059F26D, 0x7C2EED53 */ -}; - -static const double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ - 1.07710830106873743082e-07, /* 0x3E7CE9D4, 0xF65544F4 */ - 1.17176219462683348094e-01, /* 0x3FBDFF42, 0xBE760D83 */ - 2.36851496667608785174e+00, /* 0x4002F2B7, 0xF98FAEC0 */ - 1.22426109148261232917e+01, /* 0x40287C37, 0x7F71A964 */ - 1.76939711271687727390e+01, /* 0x4031B1A8, 0x177F8EE2 */ - 5.07352312588818499250e+00, /* 0x40144B49, 0xA574C1FE */ -}; -static const double ps2[5] = { - 2.14364859363821409488e+01, /* 0x40356FBD, 0x8AD5ECDC */ - 1.25290227168402751090e+02, /* 0x405F5293, 0x14F92CD5 */ - 2.32276469057162813669e+02, /* 0x406D08D8, 0xD5A2DBD9 */ - 1.17679373287147100768e+02, /* 0x405D6B7A, 0xDA1884A9 */ - 8.36463893371618283368e+00, /* 0x4020BAB1, 0xF44E5192 */ -}; - -static double pone(double x) -{ - const double *p,*q; - double_t z,r,s; - uint32_t ix; - - GET_HIGH_WORD(ix, x); - ix &= 0x7fffffff; - if (ix >= 0x40200000){p = pr8; q = ps8;} - else if (ix >= 0x40122E8B){p = pr5; q = ps5;} - else if (ix >= 0x4006DB6D){p = pr3; q = ps3;} - else /*ix >= 0x40000000*/ {p = pr2; q = ps2;} - z = 1.0/(x*x); - r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); - s = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); - return 1.0+ r/s; -} - -/* For x >= 8, the asymptotic expansions of qone is - * 3/8 s - 105/1024 s^3 - ..., where s = 1/x. - * We approximate pone by - * qone(x) = s*(0.375 + (R/S)) - * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10 - * S = 1 + qs1*s^2 + ... + qs6*s^12 - * and - * | qone(x)/s -0.375-R/S | <= 2 ** ( -61.13) - */ - -static const double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ - 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ - -1.02539062499992714161e-01, /* 0xBFBA3FFF, 0xFFFFFDF3 */ - -1.62717534544589987888e+01, /* 0xC0304591, 0xA26779F7 */ - -7.59601722513950107896e+02, /* 0xC087BCD0, 0x53E4B576 */ - -1.18498066702429587167e+04, /* 0xC0C724E7, 0x40F87415 */ - -4.84385124285750353010e+04, /* 0xC0E7A6D0, 0x65D09C6A */ -}; -static const double qs8[6] = { - 1.61395369700722909556e+02, /* 0x40642CA6, 0xDE5BCDE5 */ - 7.82538599923348465381e+03, /* 0x40BE9162, 0xD0D88419 */ - 1.33875336287249578163e+05, /* 0x4100579A, 0xB0B75E98 */ - 7.19657723683240939863e+05, /* 0x4125F653, 0x72869C19 */ - 6.66601232617776375264e+05, /* 0x412457D2, 0x7719AD5C */ - -2.94490264303834643215e+05, /* 0xC111F969, 0x0EA5AA18 */ -}; - -static const double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ - -2.08979931141764104297e-11, /* 0xBDB6FA43, 0x1AA1A098 */ - -1.02539050241375426231e-01, /* 0xBFBA3FFF, 0xCB597FEF */ - -8.05644828123936029840e+00, /* 0xC0201CE6, 0xCA03AD4B */ - -1.83669607474888380239e+02, /* 0xC066F56D, 0x6CA7B9B0 */ - -1.37319376065508163265e+03, /* 0xC09574C6, 0x6931734F */ - -2.61244440453215656817e+03, /* 0xC0A468E3, 0x88FDA79D */ -}; -static const double qs5[6] = { - 8.12765501384335777857e+01, /* 0x405451B2, 0xFF5A11B2 */ - 1.99179873460485964642e+03, /* 0x409F1F31, 0xE77BF839 */ - 1.74684851924908907677e+04, /* 0x40D10F1F, 0x0D64CE29 */ - 4.98514270910352279316e+04, /* 0x40E8576D, 0xAABAD197 */ - 2.79480751638918118260e+04, /* 0x40DB4B04, 0xCF7C364B */ - -4.71918354795128470869e+03, /* 0xC0B26F2E, 0xFCFFA004 */ -}; - -static const double qr3[6] = { - -5.07831226461766561369e-09, /* 0xBE35CFA9, 0xD38FC84F */ - -1.02537829820837089745e-01, /* 0xBFBA3FEB, 0x51AEED54 */ - -4.61011581139473403113e+00, /* 0xC01270C2, 0x3302D9FF */ - -5.78472216562783643212e+01, /* 0xC04CEC71, 0xC25D16DA */ - -2.28244540737631695038e+02, /* 0xC06C87D3, 0x4718D55F */ - -2.19210128478909325622e+02, /* 0xC06B66B9, 0x5F5C1BF6 */ -}; -static const double qs3[6] = { - 4.76651550323729509273e+01, /* 0x4047D523, 0xCCD367E4 */ - 6.73865112676699709482e+02, /* 0x40850EEB, 0xC031EE3E */ - 3.38015286679526343505e+03, /* 0x40AA684E, 0x448E7C9A */ - 5.54772909720722782367e+03, /* 0x40B5ABBA, 0xA61D54A6 */ - 1.90311919338810798763e+03, /* 0x409DBC7A, 0x0DD4DF4B */ - -1.35201191444307340817e+02, /* 0xC060E670, 0x290A311F */ -}; - -static const double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ - -1.78381727510958865572e-07, /* 0xBE87F126, 0x44C626D2 */ - -1.02517042607985553460e-01, /* 0xBFBA3E8E, 0x9148B010 */ - -2.75220568278187460720e+00, /* 0xC0060484, 0x69BB4EDA */ - -1.96636162643703720221e+01, /* 0xC033A9E2, 0xC168907F */ - -4.23253133372830490089e+01, /* 0xC04529A3, 0xDE104AAA */ - -2.13719211703704061733e+01, /* 0xC0355F36, 0x39CF6E52 */ -}; -static const double qs2[6] = { - 2.95333629060523854548e+01, /* 0x403D888A, 0x78AE64FF */ - 2.52981549982190529136e+02, /* 0x406F9F68, 0xDB821CBA */ - 7.57502834868645436472e+02, /* 0x4087AC05, 0xCE49A0F7 */ - 7.39393205320467245656e+02, /* 0x40871B25, 0x48D4C029 */ - 1.55949003336666123687e+02, /* 0x40637E5E, 0x3C3ED8D4 */ - -4.95949898822628210127e+00, /* 0xC013D686, 0xE71BE86B */ -}; - -static double qone(double x) -{ - const double *p,*q; - double_t s,r,z; - uint32_t ix; - - GET_HIGH_WORD(ix, x); - ix &= 0x7fffffff; - if (ix >= 0x40200000){p = qr8; q = qs8;} - else if (ix >= 0x40122E8B){p = qr5; q = qs5;} - else if (ix >= 0x4006DB6D){p = qr3; q = qs3;} - else /*ix >= 0x40000000*/ {p = qr2; q = qs2;} - z = 1.0/(x*x); - r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); - s = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); - return (.375 + r/s)/x; -} diff --git a/waterbox/libc/functions/math/j1f.c b/waterbox/libc/functions/math/j1f.c deleted file mode 100644 index 58875af9fc..0000000000 --- a/waterbox/libc/functions/math/j1f.c +++ /dev/null @@ -1,311 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_j1f.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#define _GNU_SOURCE -#include "libm.h" - -static float ponef(float), qonef(float); - -static const float -invsqrtpi = 5.6418961287e-01, /* 0x3f106ebb */ -tpi = 6.3661974669e-01; /* 0x3f22f983 */ - -static float common(uint32_t ix, float x, int y1, int sign) -{ - double z,s,c,ss,cc; - - s = sinf(x); - if (y1) - s = -s; - c = cosf(x); - cc = s-c; - if (ix < 0x7f000000) { - ss = -s-c; - z = cosf(2*x); - if (s*c > 0) - cc = z/ss; - else - ss = z/cc; - if (ix < 0x58800000) { - if (y1) - ss = -ss; - cc = ponef(x)*cc-qonef(x)*ss; - } - } - if (sign) - cc = -cc; - return invsqrtpi*cc/sqrtf(x); -} - -/* R0/S0 on [0,2] */ -static const float -r00 = -6.2500000000e-02, /* 0xbd800000 */ -r01 = 1.4070566976e-03, /* 0x3ab86cfd */ -r02 = -1.5995563444e-05, /* 0xb7862e36 */ -r03 = 4.9672799207e-08, /* 0x335557d2 */ -s01 = 1.9153760746e-02, /* 0x3c9ce859 */ -s02 = 1.8594678841e-04, /* 0x3942fab6 */ -s03 = 1.1771846857e-06, /* 0x359dffc2 */ -s04 = 5.0463624390e-09, /* 0x31ad6446 */ -s05 = 1.2354227016e-11; /* 0x2d59567e */ - -float j1f(float x) -{ - float z,r,s; - uint32_t ix; - int sign; - - GET_FLOAT_WORD(ix, x); - sign = ix>>31; - ix &= 0x7fffffff; - if (ix >= 0x7f800000) - return 1/(x*x); - if (ix >= 0x40000000) /* |x| >= 2 */ - return common(ix, fabsf(x), 0, sign); - if (ix >= 0x32000000) { /* |x| >= 2**-27 */ - z = x*x; - r = z*(r00+z*(r01+z*(r02+z*r03))); - s = 1+z*(s01+z*(s02+z*(s03+z*(s04+z*s05)))); - z = 0.5f + r/s; - } else - /* raise inexact if x!=0 */ - z = 0.5f + x; - return z*x; -} - -static const float U0[5] = { - -1.9605709612e-01, /* 0xbe48c331 */ - 5.0443872809e-02, /* 0x3d4e9e3c */ - -1.9125689287e-03, /* 0xbafaaf2a */ - 2.3525259166e-05, /* 0x37c5581c */ - -9.1909917899e-08, /* 0xb3c56003 */ -}; -static const float V0[5] = { - 1.9916731864e-02, /* 0x3ca3286a */ - 2.0255257550e-04, /* 0x3954644b */ - 1.3560879779e-06, /* 0x35b602d4 */ - 6.2274145840e-09, /* 0x31d5f8eb */ - 1.6655924903e-11, /* 0x2d9281cf */ -}; - -float y1f(float x) -{ - float z,u,v; - uint32_t ix; - - GET_FLOAT_WORD(ix, x); - if ((ix & 0x7fffffff) == 0) - return -1/0.0f; - if (ix>>31) - return 0/0.0f; - if (ix >= 0x7f800000) - return 1/x; - if (ix >= 0x40000000) /* |x| >= 2.0 */ - return common(ix,x,1,0); - if (ix < 0x32000000) /* x < 2**-27 */ - return -tpi/x; - z = x*x; - u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4]))); - v = 1.0f+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4])))); - return x*(u/v) + tpi*(j1f(x)*logf(x)-1.0f/x); -} - -/* For x >= 8, the asymptotic expansions of pone is - * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x. - * We approximate pone by - * pone(x) = 1 + (R/S) - * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10 - * S = 1 + ps0*s^2 + ... + ps4*s^10 - * and - * | pone(x)-1-R/S | <= 2 ** ( -60.06) - */ - -static const float pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ - 0.0000000000e+00, /* 0x00000000 */ - 1.1718750000e-01, /* 0x3df00000 */ - 1.3239480972e+01, /* 0x4153d4ea */ - 4.1205184937e+02, /* 0x43ce06a3 */ - 3.8747453613e+03, /* 0x45722bed */ - 7.9144794922e+03, /* 0x45f753d6 */ -}; -static const float ps8[5] = { - 1.1420736694e+02, /* 0x42e46a2c */ - 3.6509309082e+03, /* 0x45642ee5 */ - 3.6956207031e+04, /* 0x47105c35 */ - 9.7602796875e+04, /* 0x47bea166 */ - 3.0804271484e+04, /* 0x46f0a88b */ -}; - -static const float pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ - 1.3199052094e-11, /* 0x2d68333f */ - 1.1718749255e-01, /* 0x3defffff */ - 6.8027510643e+00, /* 0x40d9b023 */ - 1.0830818176e+02, /* 0x42d89dca */ - 5.1763616943e+02, /* 0x440168b7 */ - 5.2871520996e+02, /* 0x44042dc6 */ -}; -static const float ps5[5] = { - 5.9280597687e+01, /* 0x426d1f55 */ - 9.9140142822e+02, /* 0x4477d9b1 */ - 5.3532670898e+03, /* 0x45a74a23 */ - 7.8446904297e+03, /* 0x45f52586 */ - 1.5040468750e+03, /* 0x44bc0180 */ -}; - -static const float pr3[6] = { - 3.0250391081e-09, /* 0x314fe10d */ - 1.1718686670e-01, /* 0x3defffab */ - 3.9329774380e+00, /* 0x407bb5e7 */ - 3.5119403839e+01, /* 0x420c7a45 */ - 9.1055007935e+01, /* 0x42b61c2a */ - 4.8559066772e+01, /* 0x42423c7c */ -}; -static const float ps3[5] = { - 3.4791309357e+01, /* 0x420b2a4d */ - 3.3676245117e+02, /* 0x43a86198 */ - 1.0468714600e+03, /* 0x4482dbe3 */ - 8.9081134033e+02, /* 0x445eb3ed */ - 1.0378793335e+02, /* 0x42cf936c */ -}; - -static const float pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ - 1.0771083225e-07, /* 0x33e74ea8 */ - 1.1717621982e-01, /* 0x3deffa16 */ - 2.3685150146e+00, /* 0x401795c0 */ - 1.2242610931e+01, /* 0x4143e1bc */ - 1.7693971634e+01, /* 0x418d8d41 */ - 5.0735230446e+00, /* 0x40a25a4d */ -}; -static const float ps2[5] = { - 2.1436485291e+01, /* 0x41ab7dec */ - 1.2529022980e+02, /* 0x42fa9499 */ - 2.3227647400e+02, /* 0x436846c7 */ - 1.1767937469e+02, /* 0x42eb5bd7 */ - 8.3646392822e+00, /* 0x4105d590 */ -}; - -static float ponef(float x) -{ - const float *p,*q; - float_t z,r,s; - uint32_t ix; - - GET_FLOAT_WORD(ix, x); - ix &= 0x7fffffff; - if (ix >= 0x41000000){p = pr8; q = ps8;} - else if (ix >= 0x40f71c58){p = pr5; q = ps5;} - else if (ix >= 0x4036db68){p = pr3; q = ps3;} - else /*ix >= 0x40000000*/ {p = pr2; q = ps2;} - z = 1.0f/(x*x); - r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); - s = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); - return 1.0f + r/s; -} - -/* For x >= 8, the asymptotic expansions of qone is - * 3/8 s - 105/1024 s^3 - ..., where s = 1/x. - * We approximate pone by - * qone(x) = s*(0.375 + (R/S)) - * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10 - * S = 1 + qs1*s^2 + ... + qs6*s^12 - * and - * | qone(x)/s -0.375-R/S | <= 2 ** ( -61.13) - */ - -static const float qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ - 0.0000000000e+00, /* 0x00000000 */ - -1.0253906250e-01, /* 0xbdd20000 */ - -1.6271753311e+01, /* 0xc1822c8d */ - -7.5960174561e+02, /* 0xc43de683 */ - -1.1849806641e+04, /* 0xc639273a */ - -4.8438511719e+04, /* 0xc73d3683 */ -}; -static const float qs8[6] = { - 1.6139537048e+02, /* 0x43216537 */ - 7.8253862305e+03, /* 0x45f48b17 */ - 1.3387534375e+05, /* 0x4802bcd6 */ - 7.1965775000e+05, /* 0x492fb29c */ - 6.6660125000e+05, /* 0x4922be94 */ - -2.9449025000e+05, /* 0xc88fcb48 */ -}; - -static const float qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ - -2.0897993405e-11, /* 0xadb7d219 */ - -1.0253904760e-01, /* 0xbdd1fffe */ - -8.0564479828e+00, /* 0xc100e736 */ - -1.8366960144e+02, /* 0xc337ab6b */ - -1.3731937256e+03, /* 0xc4aba633 */ - -2.6124443359e+03, /* 0xc523471c */ -}; -static const float qs5[6] = { - 8.1276550293e+01, /* 0x42a28d98 */ - 1.9917987061e+03, /* 0x44f8f98f */ - 1.7468484375e+04, /* 0x468878f8 */ - 4.9851425781e+04, /* 0x4742bb6d */ - 2.7948074219e+04, /* 0x46da5826 */ - -4.7191835938e+03, /* 0xc5937978 */ -}; - -static const float qr3[6] = { - -5.0783124372e-09, /* 0xb1ae7d4f */ - -1.0253783315e-01, /* 0xbdd1ff5b */ - -4.6101160049e+00, /* 0xc0938612 */ - -5.7847221375e+01, /* 0xc267638e */ - -2.2824453735e+02, /* 0xc3643e9a */ - -2.1921012878e+02, /* 0xc35b35cb */ -}; -static const float qs3[6] = { - 4.7665153503e+01, /* 0x423ea91e */ - 6.7386511230e+02, /* 0x4428775e */ - 3.3801528320e+03, /* 0x45534272 */ - 5.5477290039e+03, /* 0x45ad5dd5 */ - 1.9031191406e+03, /* 0x44ede3d0 */ - -1.3520118713e+02, /* 0xc3073381 */ -}; - -static const float qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ - -1.7838172539e-07, /* 0xb43f8932 */ - -1.0251704603e-01, /* 0xbdd1f475 */ - -2.7522056103e+00, /* 0xc0302423 */ - -1.9663616180e+01, /* 0xc19d4f16 */ - -4.2325313568e+01, /* 0xc2294d1f */ - -2.1371921539e+01, /* 0xc1aaf9b2 */ -}; -static const float qs2[6] = { - 2.9533363342e+01, /* 0x41ec4454 */ - 2.5298155212e+02, /* 0x437cfb47 */ - 7.5750280762e+02, /* 0x443d602e */ - 7.3939318848e+02, /* 0x4438d92a */ - 1.5594900513e+02, /* 0x431bf2f2 */ - -4.9594988823e+00, /* 0xc09eb437 */ -}; - -static float qonef(float x) -{ - const float *p,*q; - float_t s,r,z; - uint32_t ix; - - GET_FLOAT_WORD(ix, x); - ix &= 0x7fffffff; - if (ix >= 0x40200000){p = qr8; q = qs8;} - else if (ix >= 0x40f71c58){p = qr5; q = qs5;} - else if (ix >= 0x4036db68){p = qr3; q = qs3;} - else /*ix >= 0x40000000*/ {p = qr2; q = qs2;} - z = 1.0f/(x*x); - r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); - s = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); - return (.375f + r/s)/x; -} diff --git a/waterbox/libc/functions/math/jn.c b/waterbox/libc/functions/math/jn.c deleted file mode 100644 index 4878a54fed..0000000000 --- a/waterbox/libc/functions/math/jn.c +++ /dev/null @@ -1,280 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_jn.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* - * jn(n, x), yn(n, x) - * floating point Bessel's function of the 1st and 2nd kind - * of order n - * - * Special cases: - * y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal; - * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal. - * Note 2. About jn(n,x), yn(n,x) - * For n=0, j0(x) is called, - * for n=1, j1(x) is called, - * for n<=x, forward recursion is used starting - * from values of j0(x) and j1(x). - * for n>x, a continued fraction approximation to - * j(n,x)/j(n-1,x) is evaluated and then backward - * recursion is used starting from a supposed value - * for j(n,x). The resulting value of j(0,x) is - * compared with the actual value to correct the - * supposed value of j(n,x). - * - * yn(n,x) is similar in all respects, except - * that forward recursion is used for all - * values of n>1. - */ - -#include "libm.h" - -static const double invsqrtpi = 5.64189583547756279280e-01; /* 0x3FE20DD7, 0x50429B6D */ - -double jn(int n, double x) -{ - uint32_t ix, lx; - int nm1, i, sign; - double a, b, temp; - - EXTRACT_WORDS(ix, lx, x); - sign = ix>>31; - ix &= 0x7fffffff; - - if ((ix | (lx|-lx)>>31) > 0x7ff00000) /* nan */ - return x; - - /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x) - * Thus, J(-n,x) = J(n,-x) - */ - /* nm1 = |n|-1 is used instead of |n| to handle n==INT_MIN */ - if (n == 0) - return j0(x); - if (n < 0) { - nm1 = -(n+1); - x = -x; - sign ^= 1; - } else - nm1 = n-1; - if (nm1 == 0) - return j1(x); - - sign &= n; /* even n: 0, odd n: signbit(x) */ - x = fabs(x); - if ((ix|lx) == 0 || ix == 0x7ff00000) /* if x is 0 or inf */ - b = 0.0; - else if (nm1 < x) { - /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */ - if (ix >= 0x52d00000) { /* x > 2**302 */ - /* (x >> n**2) - * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) - * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) - * Let s=sin(x), c=cos(x), - * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then - * - * n sin(xn)*sqt2 cos(xn)*sqt2 - * ---------------------------------- - * 0 s-c c+s - * 1 -s-c -c+s - * 2 -s+c -c-s - * 3 s+c c-s - */ - switch(nm1&3) { - case 0: temp = -cos(x)+sin(x); break; - case 1: temp = -cos(x)-sin(x); break; - case 2: temp = cos(x)-sin(x); break; - default: - case 3: temp = cos(x)+sin(x); break; - } - b = invsqrtpi*temp/sqrt(x); - } else { - a = j0(x); - b = j1(x); - for (i=0; i 32) /* underflow */ - b = 0.0; - else { - temp = x*0.5; - b = temp; - a = 1.0; - for (i=2; i<=nm1+1; i++) { - a *= (double)i; /* a = n! */ - b *= temp; /* b = (x/2)^n */ - } - b = b/a; - } - } else { - /* use backward recurrence */ - /* x x^2 x^2 - * J(n,x)/J(n-1,x) = ---- ------ ------ ..... - * 2n - 2(n+1) - 2(n+2) - * - * 1 1 1 - * (for large x) = ---- ------ ------ ..... - * 2n 2(n+1) 2(n+2) - * -- - ------ - ------ - - * x x x - * - * Let w = 2n/x and h=2/x, then the above quotient - * is equal to the continued fraction: - * 1 - * = ----------------------- - * 1 - * w - ----------------- - * 1 - * w+h - --------- - * w+2h - ... - * - * To determine how many terms needed, let - * Q(0) = w, Q(1) = w(w+h) - 1, - * Q(k) = (w+k*h)*Q(k-1) - Q(k-2), - * When Q(k) > 1e4 good for single - * When Q(k) > 1e9 good for double - * When Q(k) > 1e17 good for quadruple - */ - /* determine k */ - double t,q0,q1,w,h,z,tmp,nf; - int k; - - nf = nm1 + 1.0; - w = 2*nf/x; - h = 2/x; - z = w+h; - q0 = w; - q1 = w*z - 1.0; - k = 1; - while (q1 < 1.0e9) { - k += 1; - z += h; - tmp = z*q1 - q0; - q0 = q1; - q1 = tmp; - } - for (t=0.0, i=k; i>=0; i--) - t = 1/(2*(i+nf)/x - t); - a = t; - b = 1.0; - /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n) - * Hence, if n*(log(2n/x)) > ... - * single 8.8722839355e+01 - * double 7.09782712893383973096e+02 - * long double 1.1356523406294143949491931077970765006170e+04 - * then recurrent value may overflow and the result is - * likely underflow to zero - */ - tmp = nf*log(fabs(w)); - if (tmp < 7.09782712893383973096e+02) { - for (i=nm1; i>0; i--) { - temp = b; - b = b*(2.0*i)/x - a; - a = temp; - } - } else { - for (i=nm1; i>0; i--) { - temp = b; - b = b*(2.0*i)/x - a; - a = temp; - /* scale b to avoid spurious overflow */ - if (b > 0x1p500) { - a /= b; - t /= b; - b = 1.0; - } - } - } - z = j0(x); - w = j1(x); - if (fabs(z) >= fabs(w)) - b = t*z/b; - else - b = t*w/a; - } - } - return sign ? -b : b; -} - - -double yn(int n, double x) -{ - uint32_t ix, lx, ib; - int nm1, sign, i; - double a, b, temp; - - EXTRACT_WORDS(ix, lx, x); - sign = ix>>31; - ix &= 0x7fffffff; - - if ((ix | (lx|-lx)>>31) > 0x7ff00000) /* nan */ - return x; - if (sign && (ix|lx)!=0) /* x < 0 */ - return 0/0.0; - if (ix == 0x7ff00000) - return 0.0; - - if (n == 0) - return y0(x); - if (n < 0) { - nm1 = -(n+1); - sign = n&1; - } else { - nm1 = n-1; - sign = 0; - } - if (nm1 == 0) - return sign ? -y1(x) : y1(x); - - if (ix >= 0x52d00000) { /* x > 2**302 */ - /* (x >> n**2) - * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) - * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) - * Let s=sin(x), c=cos(x), - * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then - * - * n sin(xn)*sqt2 cos(xn)*sqt2 - * ---------------------------------- - * 0 s-c c+s - * 1 -s-c -c+s - * 2 -s+c -c-s - * 3 s+c c-s - */ - switch(nm1&3) { - case 0: temp = -sin(x)-cos(x); break; - case 1: temp = -sin(x)+cos(x); break; - case 2: temp = sin(x)+cos(x); break; - default: - case 3: temp = sin(x)-cos(x); break; - } - b = invsqrtpi*temp/sqrt(x); - } else { - a = y0(x); - b = y1(x); - /* quit if b is -inf */ - GET_HIGH_WORD(ib, b); - for (i=0; i>31; - ix &= 0x7fffffff; - if (ix > 0x7f800000) /* nan */ - return x; - - /* J(-n,x) = J(n,-x), use |n|-1 to avoid overflow in -n */ - if (n == 0) - return j0f(x); - if (n < 0) { - nm1 = -(n+1); - x = -x; - sign ^= 1; - } else - nm1 = n-1; - if (nm1 == 0) - return j1f(x); - - sign &= n; /* even n: 0, odd n: signbit(x) */ - x = fabsf(x); - if (ix == 0 || ix == 0x7f800000) /* if x is 0 or inf */ - b = 0.0f; - else if (nm1 < x) { - /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */ - a = j0f(x); - b = j1f(x); - for (i=0; i 8) /* underflow */ - nm1 = 8; - temp = 0.5f * x; - b = temp; - a = 1.0f; - for (i=2; i<=nm1+1; i++) { - a *= (float)i; /* a = n! */ - b *= temp; /* b = (x/2)^n */ - } - b = b/a; - } else { - /* use backward recurrence */ - /* x x^2 x^2 - * J(n,x)/J(n-1,x) = ---- ------ ------ ..... - * 2n - 2(n+1) - 2(n+2) - * - * 1 1 1 - * (for large x) = ---- ------ ------ ..... - * 2n 2(n+1) 2(n+2) - * -- - ------ - ------ - - * x x x - * - * Let w = 2n/x and h=2/x, then the above quotient - * is equal to the continued fraction: - * 1 - * = ----------------------- - * 1 - * w - ----------------- - * 1 - * w+h - --------- - * w+2h - ... - * - * To determine how many terms needed, let - * Q(0) = w, Q(1) = w(w+h) - 1, - * Q(k) = (w+k*h)*Q(k-1) - Q(k-2), - * When Q(k) > 1e4 good for single - * When Q(k) > 1e9 good for double - * When Q(k) > 1e17 good for quadruple - */ - /* determine k */ - float t,q0,q1,w,h,z,tmp,nf; - int k; - - nf = nm1+1.0f; - w = 2*nf/x; - h = 2/x; - z = w+h; - q0 = w; - q1 = w*z - 1.0f; - k = 1; - while (q1 < 1.0e4f) { - k += 1; - z += h; - tmp = z*q1 - q0; - q0 = q1; - q1 = tmp; - } - for (t=0.0f, i=k; i>=0; i--) - t = 1.0f/(2*(i+nf)/x-t); - a = t; - b = 1.0f; - /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n) - * Hence, if n*(log(2n/x)) > ... - * single 8.8722839355e+01 - * double 7.09782712893383973096e+02 - * long double 1.1356523406294143949491931077970765006170e+04 - * then recurrent value may overflow and the result is - * likely underflow to zero - */ - tmp = nf*logf(fabsf(w)); - if (tmp < 88.721679688f) { - for (i=nm1; i>0; i--) { - temp = b; - b = 2.0f*i*b/x - a; - a = temp; - } - } else { - for (i=nm1; i>0; i--){ - temp = b; - b = 2.0f*i*b/x - a; - a = temp; - /* scale b to avoid spurious overflow */ - if (b > 0x1p60f) { - a /= b; - t /= b; - b = 1.0f; - } - } - } - z = j0f(x); - w = j1f(x); - if (fabsf(z) >= fabsf(w)) - b = t*z/b; - else - b = t*w/a; - } - } - return sign ? -b : b; -} - -float ynf(int n, float x) -{ - uint32_t ix, ib; - int nm1, sign, i; - float a, b, temp; - - GET_FLOAT_WORD(ix, x); - sign = ix>>31; - ix &= 0x7fffffff; - if (ix > 0x7f800000) /* nan */ - return x; - if (sign && ix != 0) /* x < 0 */ - return 0/0.0f; - if (ix == 0x7f800000) - return 0.0f; - - if (n == 0) - return y0f(x); - if (n < 0) { - nm1 = -(n+1); - sign = n&1; - } else { - nm1 = n-1; - sign = 0; - } - if (nm1 == 0) - return sign ? -y1f(x) : y1f(x); - - a = y0f(x); - b = y1f(x); - /* quit if b is -inf */ - GET_FLOAT_WORD(ib,b); - for (i = 0; i < nm1 && ib != 0xff800000; ) { - i++; - temp = b; - b = (2.0f*i/x)*b - a; - GET_FLOAT_WORD(ib, b); - a = temp; - } - return sign ? -b : b; -} diff --git a/waterbox/libc/functions/math/ldexp.c b/waterbox/libc/functions/math/ldexp.c deleted file mode 100644 index f4d1cd6af5..0000000000 --- a/waterbox/libc/functions/math/ldexp.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -double ldexp(double x, int n) -{ - return scalbn(x, n); -} diff --git a/waterbox/libc/functions/math/ldexpf.c b/waterbox/libc/functions/math/ldexpf.c deleted file mode 100644 index 3bad5f393f..0000000000 --- a/waterbox/libc/functions/math/ldexpf.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -float ldexpf(float x, int n) -{ - return scalbnf(x, n); -} diff --git a/waterbox/libc/functions/math/ldexpl.c b/waterbox/libc/functions/math/ldexpl.c deleted file mode 100644 index fd145ccc56..0000000000 --- a/waterbox/libc/functions/math/ldexpl.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -long double ldexpl(long double x, int n) -{ - return scalbnl(x, n); -} diff --git a/waterbox/libc/functions/math/lgamma.c b/waterbox/libc/functions/math/lgamma.c deleted file mode 100644 index e25ec8e600..0000000000 --- a/waterbox/libc/functions/math/lgamma.c +++ /dev/null @@ -1,9 +0,0 @@ -#include - -extern int __signgam; -double __lgamma_r(double, int *); - -double lgamma(double x) -{ - return __lgamma_r(x, &__signgam); -} diff --git a/waterbox/libc/functions/math/lgamma_r.c b/waterbox/libc/functions/math/lgamma_r.c deleted file mode 100644 index 947afa27a8..0000000000 --- a/waterbox/libc/functions/math/lgamma_r.c +++ /dev/null @@ -1,284 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_lgamma_r.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - * - */ -/* lgamma_r(x, signgamp) - * Reentrant version of the logarithm of the Gamma function - * with user provide pointer for the sign of Gamma(x). - * - * Method: - * 1. Argument Reduction for 0 < x <= 8 - * Since gamma(1+s)=s*gamma(s), for x in [0,8], we may - * reduce x to a number in [1.5,2.5] by - * lgamma(1+s) = log(s) + lgamma(s) - * for example, - * lgamma(7.3) = log(6.3) + lgamma(6.3) - * = log(6.3*5.3) + lgamma(5.3) - * = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3) - * 2. Polynomial approximation of lgamma around its - * minimun ymin=1.461632144968362245 to maintain monotonicity. - * On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use - * Let z = x-ymin; - * lgamma(x) = -1.214862905358496078218 + z^2*poly(z) - * where - * poly(z) is a 14 degree polynomial. - * 2. Rational approximation in the primary interval [2,3] - * We use the following approximation: - * s = x-2.0; - * lgamma(x) = 0.5*s + s*P(s)/Q(s) - * with accuracy - * |P/Q - (lgamma(x)-0.5s)| < 2**-61.71 - * Our algorithms are based on the following observation - * - * zeta(2)-1 2 zeta(3)-1 3 - * lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ... - * 2 3 - * - * where Euler = 0.5771... is the Euler constant, which is very - * close to 0.5. - * - * 3. For x>=8, we have - * lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+.... - * (better formula: - * lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...) - * Let z = 1/x, then we approximation - * f(z) = lgamma(x) - (x-0.5)(log(x)-1) - * by - * 3 5 11 - * w = w0 + w1*z + w2*z + w3*z + ... + w6*z - * where - * |w - f(z)| < 2**-58.74 - * - * 4. For negative x, since (G is gamma function) - * -x*G(-x)*G(x) = pi/sin(pi*x), - * we have - * G(x) = pi/(sin(pi*x)*(-x)*G(-x)) - * since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0 - * Hence, for x<0, signgam = sign(sin(pi*x)) and - * lgamma(x) = log(|Gamma(x)|) - * = log(pi/(|x*sin(pi*x)|)) - lgamma(-x); - * Note: one should avoid compute pi*(-x) directly in the - * computation of sin(pi*(-x)). - * - * 5. Special Cases - * lgamma(2+s) ~ s*(1-Euler) for tiny s - * lgamma(1) = lgamma(2) = 0 - * lgamma(x) ~ -log(|x|) for tiny x - * lgamma(0) = lgamma(neg.integer) = inf and raise divide-by-zero - * lgamma(inf) = inf - * lgamma(-inf) = inf (bug for bug compatible with C99!?) - * - */ - -#include "libm.h" -#include "_alias.h" - -static const double -pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */ -a0 = 7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */ -a1 = 3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */ -a2 = 6.73523010531292681824e-02, /* 0x3FB13E00, 0x1A5562A7 */ -a3 = 2.05808084325167332806e-02, /* 0x3F951322, 0xAC92547B */ -a4 = 7.38555086081402883957e-03, /* 0x3F7E404F, 0xB68FEFE8 */ -a5 = 2.89051383673415629091e-03, /* 0x3F67ADD8, 0xCCB7926B */ -a6 = 1.19270763183362067845e-03, /* 0x3F538A94, 0x116F3F5D */ -a7 = 5.10069792153511336608e-04, /* 0x3F40B6C6, 0x89B99C00 */ -a8 = 2.20862790713908385557e-04, /* 0x3F2CF2EC, 0xED10E54D */ -a9 = 1.08011567247583939954e-04, /* 0x3F1C5088, 0x987DFB07 */ -a10 = 2.52144565451257326939e-05, /* 0x3EFA7074, 0x428CFA52 */ -a11 = 4.48640949618915160150e-05, /* 0x3F07858E, 0x90A45837 */ -tc = 1.46163214496836224576e+00, /* 0x3FF762D8, 0x6356BE3F */ -tf = -1.21486290535849611461e-01, /* 0xBFBF19B9, 0xBCC38A42 */ -/* tt = -(tail of tf) */ -tt = -3.63867699703950536541e-18, /* 0xBC50C7CA, 0xA48A971F */ -t0 = 4.83836122723810047042e-01, /* 0x3FDEF72B, 0xC8EE38A2 */ -t1 = -1.47587722994593911752e-01, /* 0xBFC2E427, 0x8DC6C509 */ -t2 = 6.46249402391333854778e-02, /* 0x3FB08B42, 0x94D5419B */ -t3 = -3.27885410759859649565e-02, /* 0xBFA0C9A8, 0xDF35B713 */ -t4 = 1.79706750811820387126e-02, /* 0x3F9266E7, 0x970AF9EC */ -t5 = -1.03142241298341437450e-02, /* 0xBF851F9F, 0xBA91EC6A */ -t6 = 6.10053870246291332635e-03, /* 0x3F78FCE0, 0xE370E344 */ -t7 = -3.68452016781138256760e-03, /* 0xBF6E2EFF, 0xB3E914D7 */ -t8 = 2.25964780900612472250e-03, /* 0x3F6282D3, 0x2E15C915 */ -t9 = -1.40346469989232843813e-03, /* 0xBF56FE8E, 0xBF2D1AF1 */ -t10 = 8.81081882437654011382e-04, /* 0x3F4CDF0C, 0xEF61A8E9 */ -t11 = -5.38595305356740546715e-04, /* 0xBF41A610, 0x9C73E0EC */ -t12 = 3.15632070903625950361e-04, /* 0x3F34AF6D, 0x6C0EBBF7 */ -t13 = -3.12754168375120860518e-04, /* 0xBF347F24, 0xECC38C38 */ -t14 = 3.35529192635519073543e-04, /* 0x3F35FD3E, 0xE8C2D3F4 */ -u0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */ -u1 = 6.32827064025093366517e-01, /* 0x3FE4401E, 0x8B005DFF */ -u2 = 1.45492250137234768737e+00, /* 0x3FF7475C, 0xD119BD6F */ -u3 = 9.77717527963372745603e-01, /* 0x3FEF4976, 0x44EA8450 */ -u4 = 2.28963728064692451092e-01, /* 0x3FCD4EAE, 0xF6010924 */ -u5 = 1.33810918536787660377e-02, /* 0x3F8B678B, 0xBF2BAB09 */ -v1 = 2.45597793713041134822e+00, /* 0x4003A5D7, 0xC2BD619C */ -v2 = 2.12848976379893395361e+00, /* 0x40010725, 0xA42B18F5 */ -v3 = 7.69285150456672783825e-01, /* 0x3FE89DFB, 0xE45050AF */ -v4 = 1.04222645593369134254e-01, /* 0x3FBAAE55, 0xD6537C88 */ -v5 = 3.21709242282423911810e-03, /* 0x3F6A5ABB, 0x57D0CF61 */ -s0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */ -s1 = 2.14982415960608852501e-01, /* 0x3FCB848B, 0x36E20878 */ -s2 = 3.25778796408930981787e-01, /* 0x3FD4D98F, 0x4F139F59 */ -s3 = 1.46350472652464452805e-01, /* 0x3FC2BB9C, 0xBEE5F2F7 */ -s4 = 2.66422703033638609560e-02, /* 0x3F9B481C, 0x7E939961 */ -s5 = 1.84028451407337715652e-03, /* 0x3F5E26B6, 0x7368F239 */ -s6 = 3.19475326584100867617e-05, /* 0x3F00BFEC, 0xDD17E945 */ -r1 = 1.39200533467621045958e+00, /* 0x3FF645A7, 0x62C4AB74 */ -r2 = 7.21935547567138069525e-01, /* 0x3FE71A18, 0x93D3DCDC */ -r3 = 1.71933865632803078993e-01, /* 0x3FC601ED, 0xCCFBDF27 */ -r4 = 1.86459191715652901344e-02, /* 0x3F9317EA, 0x742ED475 */ -r5 = 7.77942496381893596434e-04, /* 0x3F497DDA, 0xCA41A95B */ -r6 = 7.32668430744625636189e-06, /* 0x3EDEBAF7, 0xA5B38140 */ -w0 = 4.18938533204672725052e-01, /* 0x3FDACFE3, 0x90C97D69 */ -w1 = 8.33333333333329678849e-02, /* 0x3FB55555, 0x5555553B */ -w2 = -2.77777777728775536470e-03, /* 0xBF66C16C, 0x16B02E5C */ -w3 = 7.93650558643019558500e-04, /* 0x3F4A019F, 0x98CF38B6 */ -w4 = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */ -w5 = 8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */ -w6 = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */ - -/* sin(pi*x) assuming x > 2^-100, if sin(pi*x)==0 the sign is arbitrary */ -static double sin_pi(double x) -{ - int n; - - /* spurious inexact if odd int */ - x = 2.0*(x*0.5 - floor(x*0.5)); /* x mod 2.0 */ - - n = (int)(x*4.0); - n = (n+1)/2; - x -= n*0.5f; - x *= pi; - - switch (n) { - default: /* case 4: */ - case 0: return __sin(x, 0.0, 0); - case 1: return __cos(x, 0.0); - case 2: return __sin(-x, 0.0, 0); - case 3: return -__cos(x, 0.0); - } -} - -double __lgamma_r(double x, int *signgamp) -{ - union {double f; uint64_t i;} u = {x}; - double_t t,y,z,nadj,p,p1,p2,p3,q,r,w; - uint32_t ix; - int sign,i; - - /* purge off +-inf, NaN, +-0, tiny and negative arguments */ - *signgamp = 1; - sign = u.i>>63; - ix = u.i>>32 & 0x7fffffff; - if (ix >= 0x7ff00000) - return x*x; - if (ix < (0x3ff-70)<<20) { /* |x|<2**-70, return -log(|x|) */ - if(sign) { - x = -x; - *signgamp = -1; - } - return -log(x); - } - if (sign) { - x = -x; - t = sin_pi(x); - if (t == 0.0) /* -integer */ - return 1.0/(x-x); - if (t > 0.0) - *signgamp = -1; - else - t = -t; - nadj = log(pi/(t*x)); - } - - /* purge off 1 and 2 */ - if ((ix == 0x3ff00000 || ix == 0x40000000) && (uint32_t)u.i == 0) - r = 0; - /* for x < 2.0 */ - else if (ix < 0x40000000) { - if (ix <= 0x3feccccc) { /* lgamma(x) = lgamma(x+1)-log(x) */ - r = -log(x); - if (ix >= 0x3FE76944) { - y = 1.0 - x; - i = 0; - } else if (ix >= 0x3FCDA661) { - y = x - (tc-1.0); - i = 1; - } else { - y = x; - i = 2; - } - } else { - r = 0.0; - if (ix >= 0x3FFBB4C3) { /* [1.7316,2] */ - y = 2.0 - x; - i = 0; - } else if(ix >= 0x3FF3B4C4) { /* [1.23,1.73] */ - y = x - tc; - i = 1; - } else { - y = x - 1.0; - i = 2; - } - } - switch (i) { - case 0: - z = y*y; - p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10)))); - p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11))))); - p = y*p1+p2; - r += (p-0.5*y); - break; - case 1: - z = y*y; - w = z*y; - p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */ - p2 = t1+w*(t4+w*(t7+w*(t10+w*t13))); - p3 = t2+w*(t5+w*(t8+w*(t11+w*t14))); - p = z*p1-(tt-w*(p2+y*p3)); - r += tf + p; - break; - case 2: - p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5))))); - p2 = 1.0+y*(v1+y*(v2+y*(v3+y*(v4+y*v5)))); - r += -0.5*y + p1/p2; - } - } else if (ix < 0x40200000) { /* x < 8.0 */ - i = (int)x; - y = x - (double)i; - p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6)))))); - q = 1.0+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6))))); - r = 0.5*y+p/q; - z = 1.0; /* lgamma(1+s) = log(s) + lgamma(s) */ - switch (i) { - case 7: z *= y + 6.0; /* FALLTHRU */ - case 6: z *= y + 5.0; /* FALLTHRU */ - case 5: z *= y + 4.0; /* FALLTHRU */ - case 4: z *= y + 3.0; /* FALLTHRU */ - case 3: z *= y + 2.0; /* FALLTHRU */ - r += log(z); - break; - } - } else if (ix < 0x43900000) { /* 8.0 <= x < 2**58 */ - t = log(x); - z = 1.0/x; - y = z*z; - w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6))))); - r = (x-0.5)*(t-1.0)+w; - } else /* 2**58 <= x <= inf */ - r = x*(log(x)-1.0); - if (sign) - r = nadj - r; - return r; -} - -weak_alias(__lgamma_r, lgamma_r); diff --git a/waterbox/libc/functions/math/lgammaf.c b/waterbox/libc/functions/math/lgammaf.c deleted file mode 100644 index badb6dfec9..0000000000 --- a/waterbox/libc/functions/math/lgammaf.c +++ /dev/null @@ -1,9 +0,0 @@ -#include - -extern int __signgam; -float __lgammaf_r(float, int *); - -float lgammaf(float x) -{ - return __lgammaf_r(x, &__signgam); -} diff --git a/waterbox/libc/functions/math/lgammaf_r.c b/waterbox/libc/functions/math/lgammaf_r.c deleted file mode 100644 index 43a39cccbc..0000000000 --- a/waterbox/libc/functions/math/lgammaf_r.c +++ /dev/null @@ -1,219 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_lgammaf_r.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" -#include "_alias.h" - -static const float -pi = 3.1415927410e+00, /* 0x40490fdb */ -a0 = 7.7215664089e-02, /* 0x3d9e233f */ -a1 = 3.2246702909e-01, /* 0x3ea51a66 */ -a2 = 6.7352302372e-02, /* 0x3d89f001 */ -a3 = 2.0580807701e-02, /* 0x3ca89915 */ -a4 = 7.3855509982e-03, /* 0x3bf2027e */ -a5 = 2.8905137442e-03, /* 0x3b3d6ec6 */ -a6 = 1.1927076848e-03, /* 0x3a9c54a1 */ -a7 = 5.1006977446e-04, /* 0x3a05b634 */ -a8 = 2.2086278477e-04, /* 0x39679767 */ -a9 = 1.0801156895e-04, /* 0x38e28445 */ -a10 = 2.5214456400e-05, /* 0x37d383a2 */ -a11 = 4.4864096708e-05, /* 0x383c2c75 */ -tc = 1.4616321325e+00, /* 0x3fbb16c3 */ -tf = -1.2148628384e-01, /* 0xbdf8cdcd */ -/* tt = -(tail of tf) */ -tt = 6.6971006518e-09, /* 0x31e61c52 */ -t0 = 4.8383611441e-01, /* 0x3ef7b95e */ -t1 = -1.4758771658e-01, /* 0xbe17213c */ -t2 = 6.4624942839e-02, /* 0x3d845a15 */ -t3 = -3.2788541168e-02, /* 0xbd064d47 */ -t4 = 1.7970675603e-02, /* 0x3c93373d */ -t5 = -1.0314224288e-02, /* 0xbc28fcfe */ -t6 = 6.1005386524e-03, /* 0x3bc7e707 */ -t7 = -3.6845202558e-03, /* 0xbb7177fe */ -t8 = 2.2596477065e-03, /* 0x3b141699 */ -t9 = -1.4034647029e-03, /* 0xbab7f476 */ -t10 = 8.8108185446e-04, /* 0x3a66f867 */ -t11 = -5.3859531181e-04, /* 0xba0d3085 */ -t12 = 3.1563205994e-04, /* 0x39a57b6b */ -t13 = -3.1275415677e-04, /* 0xb9a3f927 */ -t14 = 3.3552918467e-04, /* 0x39afe9f7 */ -u0 = -7.7215664089e-02, /* 0xbd9e233f */ -u1 = 6.3282704353e-01, /* 0x3f2200f4 */ -u2 = 1.4549225569e+00, /* 0x3fba3ae7 */ -u3 = 9.7771751881e-01, /* 0x3f7a4bb2 */ -u4 = 2.2896373272e-01, /* 0x3e6a7578 */ -u5 = 1.3381091878e-02, /* 0x3c5b3c5e */ -v1 = 2.4559779167e+00, /* 0x401d2ebe */ -v2 = 2.1284897327e+00, /* 0x4008392d */ -v3 = 7.6928514242e-01, /* 0x3f44efdf */ -v4 = 1.0422264785e-01, /* 0x3dd572af */ -v5 = 3.2170924824e-03, /* 0x3b52d5db */ -s0 = -7.7215664089e-02, /* 0xbd9e233f */ -s1 = 2.1498242021e-01, /* 0x3e5c245a */ -s2 = 3.2577878237e-01, /* 0x3ea6cc7a */ -s3 = 1.4635047317e-01, /* 0x3e15dce6 */ -s4 = 2.6642270386e-02, /* 0x3cda40e4 */ -s5 = 1.8402845599e-03, /* 0x3af135b4 */ -s6 = 3.1947532989e-05, /* 0x3805ff67 */ -r1 = 1.3920053244e+00, /* 0x3fb22d3b */ -r2 = 7.2193557024e-01, /* 0x3f38d0c5 */ -r3 = 1.7193385959e-01, /* 0x3e300f6e */ -r4 = 1.8645919859e-02, /* 0x3c98bf54 */ -r5 = 7.7794247773e-04, /* 0x3a4beed6 */ -r6 = 7.3266842264e-06, /* 0x36f5d7bd */ -w0 = 4.1893854737e-01, /* 0x3ed67f1d */ -w1 = 8.3333335817e-02, /* 0x3daaaaab */ -w2 = -2.7777778450e-03, /* 0xbb360b61 */ -w3 = 7.9365057172e-04, /* 0x3a500cfd */ -w4 = -5.9518753551e-04, /* 0xba1c065c */ -w5 = 8.3633989561e-04, /* 0x3a5b3dd2 */ -w6 = -1.6309292987e-03; /* 0xbad5c4e8 */ - -/* sin(pi*x) assuming x > 2^-100, if sin(pi*x)==0 the sign is arbitrary */ -static float sin_pi(float x) -{ - double_t y; - int n; - - /* spurious inexact if odd int */ - x = 2*(x*0.5f - floorf(x*0.5f)); /* x mod 2.0 */ - - n = (int)(x*4); - n = (n+1)/2; - y = x - n*0.5f; - y *= 3.14159265358979323846; - switch (n) { - default: /* case 4: */ - case 0: return __sindf(y); - case 1: return __cosdf(y); - case 2: return __sindf(-y); - case 3: return -__cosdf(y); - } -} - -float __lgammaf_r(float x, int *signgamp) -{ - union {float f; uint32_t i;} u = {x}; - float t,y,z,nadj,p,p1,p2,p3,q,r,w; - uint32_t ix; - int i,sign; - - /* purge off +-inf, NaN, +-0, tiny and negative arguments */ - *signgamp = 1; - sign = u.i>>31; - ix = u.i & 0x7fffffff; - if (ix >= 0x7f800000) - return x*x; - if (ix < 0x35000000) { /* |x| < 2**-21, return -log(|x|) */ - if (sign) { - *signgamp = -1; - x = -x; - } - return -logf(x); - } - if (sign) { - x = -x; - t = sin_pi(x); - if (t == 0.0f) /* -integer */ - return 1.0f/(x-x); - if (t > 0.0f) - *signgamp = -1; - else - t = -t; - nadj = logf(pi/(t*x)); - } - - /* purge off 1 and 2 */ - if (ix == 0x3f800000 || ix == 0x40000000) - r = 0; - /* for x < 2.0 */ - else if (ix < 0x40000000) { - if (ix <= 0x3f666666) { /* lgamma(x) = lgamma(x+1)-log(x) */ - r = -logf(x); - if (ix >= 0x3f3b4a20) { - y = 1.0f - x; - i = 0; - } else if (ix >= 0x3e6d3308) { - y = x - (tc-1.0f); - i = 1; - } else { - y = x; - i = 2; - } - } else { - r = 0.0f; - if (ix >= 0x3fdda618) { /* [1.7316,2] */ - y = 2.0f - x; - i = 0; - } else if (ix >= 0x3F9da620) { /* [1.23,1.73] */ - y = x - tc; - i = 1; - } else { - y = x - 1.0f; - i = 2; - } - } - switch(i) { - case 0: - z = y*y; - p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10)))); - p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11))))); - p = y*p1+p2; - r += p - 0.5f*y; - break; - case 1: - z = y*y; - w = z*y; - p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */ - p2 = t1+w*(t4+w*(t7+w*(t10+w*t13))); - p3 = t2+w*(t5+w*(t8+w*(t11+w*t14))); - p = z*p1-(tt-w*(p2+y*p3)); - r += (tf + p); - break; - case 2: - p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5))))); - p2 = 1.0f+y*(v1+y*(v2+y*(v3+y*(v4+y*v5)))); - r += -0.5f*y + p1/p2; - } - } else if (ix < 0x41000000) { /* x < 8.0 */ - i = (int)x; - y = x - (float)i; - p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6)))))); - q = 1.0f+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6))))); - r = 0.5f*y+p/q; - z = 1.0f; /* lgamma(1+s) = log(s) + lgamma(s) */ - switch (i) { - case 7: z *= y + 6.0f; /* FALLTHRU */ - case 6: z *= y + 5.0f; /* FALLTHRU */ - case 5: z *= y + 4.0f; /* FALLTHRU */ - case 4: z *= y + 3.0f; /* FALLTHRU */ - case 3: z *= y + 2.0f; /* FALLTHRU */ - r += logf(z); - break; - } - } else if (ix < 0x5c800000) { /* 8.0 <= x < 2**58 */ - t = logf(x); - z = 1.0f/x; - y = z*z; - w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6))))); - r = (x-0.5f)*(t-1.0f)+w; - } else /* 2**58 <= x <= inf */ - r = x*(logf(x)-1.0f); - if (sign) - r = nadj - r; - return r; -} - -weak_alias(__lgammaf_r, lgammaf_r); diff --git a/waterbox/libc/functions/math/lgammal.c b/waterbox/libc/functions/math/lgammal.c deleted file mode 100644 index e9e6da63f4..0000000000 --- a/waterbox/libc/functions/math/lgammal.c +++ /dev/null @@ -1,360 +0,0 @@ -/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_lgammal.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* - * Copyright (c) 2008 Stephen L. Moshier - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/* lgammal(x) - * Reentrant version of the logarithm of the Gamma function - * with user provide pointer for the sign of Gamma(x). - * - * Method: - * 1. Argument Reduction for 0 < x <= 8 - * Since gamma(1+s)=s*gamma(s), for x in [0,8], we may - * reduce x to a number in [1.5,2.5] by - * lgamma(1+s) = log(s) + lgamma(s) - * for example, - * lgamma(7.3) = log(6.3) + lgamma(6.3) - * = log(6.3*5.3) + lgamma(5.3) - * = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3) - * 2. Polynomial approximation of lgamma around its - * minimun ymin=1.461632144968362245 to maintain monotonicity. - * On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use - * Let z = x-ymin; - * lgamma(x) = -1.214862905358496078218 + z^2*poly(z) - * 2. Rational approximation in the primary interval [2,3] - * We use the following approximation: - * s = x-2.0; - * lgamma(x) = 0.5*s + s*P(s)/Q(s) - * Our algorithms are based on the following observation - * - * zeta(2)-1 2 zeta(3)-1 3 - * lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ... - * 2 3 - * - * where Euler = 0.5771... is the Euler constant, which is very - * close to 0.5. - * - * 3. For x>=8, we have - * lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+.... - * (better formula: - * lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...) - * Let z = 1/x, then we approximation - * f(z) = lgamma(x) - (x-0.5)(log(x)-1) - * by - * 3 5 11 - * w = w0 + w1*z + w2*z + w3*z + ... + w6*z - * - * 4. For negative x, since (G is gamma function) - * -x*G(-x)*G(x) = pi/sin(pi*x), - * we have - * G(x) = pi/(sin(pi*x)*(-x)*G(-x)) - * since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0 - * Hence, for x<0, signgam = sign(sin(pi*x)) and - * lgamma(x) = log(|Gamma(x)|) - * = log(pi/(|x*sin(pi*x)|)) - lgamma(-x); - * Note: one should avoid compute pi*(-x) directly in the - * computation of sin(pi*(-x)). - * - * 5. Special Cases - * lgamma(2+s) ~ s*(1-Euler) for tiny s - * lgamma(1)=lgamma(2)=0 - * lgamma(x) ~ -log(x) for tiny x - * lgamma(0) = lgamma(inf) = inf - * lgamma(-integer) = +-inf - * - */ - -#define _GNU_SOURCE -#include "libm.h" -#include "_alias.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -double __lgamma_r(double x, int *sg); - -long double __lgammal_r(long double x, int *sg) -{ - return __lgamma_r(x, sg); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -static const long double -pi = 3.14159265358979323846264L, - -/* lgam(1+x) = 0.5 x + x a(x)/b(x) - -0.268402099609375 <= x <= 0 - peak relative error 6.6e-22 */ -a0 = -6.343246574721079391729402781192128239938E2L, -a1 = 1.856560238672465796768677717168371401378E3L, -a2 = 2.404733102163746263689288466865843408429E3L, -a3 = 8.804188795790383497379532868917517596322E2L, -a4 = 1.135361354097447729740103745999661157426E2L, -a5 = 3.766956539107615557608581581190400021285E0L, - -b0 = 8.214973713960928795704317259806842490498E3L, -b1 = 1.026343508841367384879065363925870888012E4L, -b2 = 4.553337477045763320522762343132210919277E3L, -b3 = 8.506975785032585797446253359230031874803E2L, -b4 = 6.042447899703295436820744186992189445813E1L, -/* b5 = 1.000000000000000000000000000000000000000E0 */ - - -tc = 1.4616321449683623412626595423257213284682E0L, -tf = -1.2148629053584961146050602565082954242826E-1, /* double precision */ -/* tt = (tail of tf), i.e. tf + tt has extended precision. */ -tt = 3.3649914684731379602768989080467587736363E-18L, -/* lgam ( 1.4616321449683623412626595423257213284682E0 ) = --1.2148629053584960809551455717769158215135617312999903886372437313313530E-1 */ - -/* lgam (x + tc) = tf + tt + x g(x)/h(x) - -0.230003726999612341262659542325721328468 <= x - <= 0.2699962730003876587373404576742786715318 - peak relative error 2.1e-21 */ -g0 = 3.645529916721223331888305293534095553827E-18L, -g1 = 5.126654642791082497002594216163574795690E3L, -g2 = 8.828603575854624811911631336122070070327E3L, -g3 = 5.464186426932117031234820886525701595203E3L, -g4 = 1.455427403530884193180776558102868592293E3L, -g5 = 1.541735456969245924860307497029155838446E2L, -g6 = 4.335498275274822298341872707453445815118E0L, - -h0 = 1.059584930106085509696730443974495979641E4L, -h1 = 2.147921653490043010629481226937850618860E4L, -h2 = 1.643014770044524804175197151958100656728E4L, -h3 = 5.869021995186925517228323497501767586078E3L, -h4 = 9.764244777714344488787381271643502742293E2L, -h5 = 6.442485441570592541741092969581997002349E1L, -/* h6 = 1.000000000000000000000000000000000000000E0 */ - - -/* lgam (x+1) = -0.5 x + x u(x)/v(x) - -0.100006103515625 <= x <= 0.231639862060546875 - peak relative error 1.3e-21 */ -u0 = -8.886217500092090678492242071879342025627E1L, -u1 = 6.840109978129177639438792958320783599310E2L, -u2 = 2.042626104514127267855588786511809932433E3L, -u3 = 1.911723903442667422201651063009856064275E3L, -u4 = 7.447065275665887457628865263491667767695E2L, -u5 = 1.132256494121790736268471016493103952637E2L, -u6 = 4.484398885516614191003094714505960972894E0L, - -v0 = 1.150830924194461522996462401210374632929E3L, -v1 = 3.399692260848747447377972081399737098610E3L, -v2 = 3.786631705644460255229513563657226008015E3L, -v3 = 1.966450123004478374557778781564114347876E3L, -v4 = 4.741359068914069299837355438370682773122E2L, -v5 = 4.508989649747184050907206782117647852364E1L, -/* v6 = 1.000000000000000000000000000000000000000E0 */ - - -/* lgam (x+2) = .5 x + x s(x)/r(x) - 0 <= x <= 1 - peak relative error 7.2e-22 */ -s0 = 1.454726263410661942989109455292824853344E6L, -s1 = -3.901428390086348447890408306153378922752E6L, -s2 = -6.573568698209374121847873064292963089438E6L, -s3 = -3.319055881485044417245964508099095984643E6L, -s4 = -7.094891568758439227560184618114707107977E5L, -s5 = -6.263426646464505837422314539808112478303E4L, -s6 = -1.684926520999477529949915657519454051529E3L, - -r0 = -1.883978160734303518163008696712983134698E7L, -r1 = -2.815206082812062064902202753264922306830E7L, -r2 = -1.600245495251915899081846093343626358398E7L, -r3 = -4.310526301881305003489257052083370058799E6L, -r4 = -5.563807682263923279438235987186184968542E5L, -r5 = -3.027734654434169996032905158145259713083E4L, -r6 = -4.501995652861105629217250715790764371267E2L, -/* r6 = 1.000000000000000000000000000000000000000E0 */ - - -/* lgam(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x w(1/x^2) - x >= 8 - Peak relative error 1.51e-21 -w0 = LS2PI - 0.5 */ -w0 = 4.189385332046727417803e-1L, -w1 = 8.333333333333331447505E-2L, -w2 = -2.777777777750349603440E-3L, -w3 = 7.936507795855070755671E-4L, -w4 = -5.952345851765688514613E-4L, -w5 = 8.412723297322498080632E-4L, -w6 = -1.880801938119376907179E-3L, -w7 = 4.885026142432270781165E-3L; - -/* sin(pi*x) assuming x > 2^-1000, if sin(pi*x)==0 the sign is arbitrary */ -static long double sin_pi(long double x) -{ - int n; - - /* spurious inexact if odd int */ - x *= 0.5; - x = 2.0*(x - floorl(x)); /* x mod 2.0 */ - - n = (int)(x*4.0); - n = (n+1)/2; - x -= n*0.5f; - x *= pi; - - switch (n) { - default: /* case 4: */ - case 0: return __sinl(x, 0.0, 0); - case 1: return __cosl(x, 0.0); - case 2: return __sinl(-x, 0.0, 0); - case 3: return -__cosl(x, 0.0); - } -} - -long double __lgammal_r(long double x, int *sg) { - long double t, y, z, nadj, p, p1, p2, q, r, w; - union ldshape u = {x}; - uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48; - int sign = u.i.se >> 15; - int i; - - *sg = 1; - - /* purge off +-inf, NaN, +-0, tiny and negative arguments */ - if (ix >= 0x7fff0000) - return x * x; - if (ix < 0x3fc08000) { /* |x|<2**-63, return -log(|x|) */ - if (sign) { - *sg = -1; - x = -x; - } - return -logl(x); - } - if (sign) { - x = -x; - t = sin_pi(x); - if (t == 0.0) - return 1.0 / (x-x); /* -integer */ - if (t > 0.0) - *sg = -1; - else - t = -t; - nadj = logl(pi / (t * x)); - } - - /* purge off 1 and 2 (so the sign is ok with downward rounding) */ - if ((ix == 0x3fff8000 || ix == 0x40008000) && u.i.m == 0) { - r = 0; - } else if (ix < 0x40008000) { /* x < 2.0 */ - if (ix <= 0x3ffee666) { /* 8.99993896484375e-1 */ - /* lgamma(x) = lgamma(x+1) - log(x) */ - r = -logl(x); - if (ix >= 0x3ffebb4a) { /* 7.31597900390625e-1 */ - y = x - 1.0; - i = 0; - } else if (ix >= 0x3ffced33) { /* 2.31639862060546875e-1 */ - y = x - (tc - 1.0); - i = 1; - } else { /* x < 0.23 */ - y = x; - i = 2; - } - } else { - r = 0.0; - if (ix >= 0x3fffdda6) { /* 1.73162841796875 */ - /* [1.7316,2] */ - y = x - 2.0; - i = 0; - } else if (ix >= 0x3fff9da6) { /* 1.23162841796875 */ - /* [1.23,1.73] */ - y = x - tc; - i = 1; - } else { - /* [0.9, 1.23] */ - y = x - 1.0; - i = 2; - } - } - switch (i) { - case 0: - p1 = a0 + y * (a1 + y * (a2 + y * (a3 + y * (a4 + y * a5)))); - p2 = b0 + y * (b1 + y * (b2 + y * (b3 + y * (b4 + y)))); - r += 0.5 * y + y * p1/p2; - break; - case 1: - p1 = g0 + y * (g1 + y * (g2 + y * (g3 + y * (g4 + y * (g5 + y * g6))))); - p2 = h0 + y * (h1 + y * (h2 + y * (h3 + y * (h4 + y * (h5 + y))))); - p = tt + y * p1/p2; - r += (tf + p); - break; - case 2: - p1 = y * (u0 + y * (u1 + y * (u2 + y * (u3 + y * (u4 + y * (u5 + y * u6)))))); - p2 = v0 + y * (v1 + y * (v2 + y * (v3 + y * (v4 + y * (v5 + y))))); - r += (-0.5 * y + p1 / p2); - } - } else if (ix < 0x40028000) { /* 8.0 */ - /* x < 8.0 */ - i = (int)x; - y = x - (double)i; - p = y * (s0 + y * (s1 + y * (s2 + y * (s3 + y * (s4 + y * (s5 + y * s6)))))); - q = r0 + y * (r1 + y * (r2 + y * (r3 + y * (r4 + y * (r5 + y * (r6 + y)))))); - r = 0.5 * y + p / q; - z = 1.0; - /* lgamma(1+s) = log(s) + lgamma(s) */ - switch (i) { - case 7: - z *= (y + 6.0); /* FALLTHRU */ - case 6: - z *= (y + 5.0); /* FALLTHRU */ - case 5: - z *= (y + 4.0); /* FALLTHRU */ - case 4: - z *= (y + 3.0); /* FALLTHRU */ - case 3: - z *= (y + 2.0); /* FALLTHRU */ - r += logl(z); - break; - } - } else if (ix < 0x40418000) { /* 2^66 */ - /* 8.0 <= x < 2**66 */ - t = logl(x); - z = 1.0 / x; - y = z * z; - w = w0 + z * (w1 + y * (w2 + y * (w3 + y * (w4 + y * (w5 + y * (w6 + y * w7)))))); - r = (x - 0.5) * (t - 1.0) + w; - } else /* 2**66 <= x <= inf */ - r = x * (logl(x) - 1.0); - if (sign) - r = nadj - r; - return r; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -// TODO: broken implementation to make things compile -double __lgamma_r(double x, int *sg); - -long double __lgammal_r(long double x, int *sg) -{ - return __lgamma_r(x, sg); -} -#endif - -extern int __signgam; - -long double lgammal(long double x) -{ - return __lgammal_r(x, &__signgam); -} - -weak_alias(__lgammal_r, lgammal_r); diff --git a/waterbox/libc/functions/math/llrint.c b/waterbox/libc/functions/math/llrint.c deleted file mode 100644 index 4f583ae553..0000000000 --- a/waterbox/libc/functions/math/llrint.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -/* uses LLONG_MAX > 2^53, see comments in lrint.c */ - -long long llrint(double x) -{ - return rint(x); -} diff --git a/waterbox/libc/functions/math/llrintf.c b/waterbox/libc/functions/math/llrintf.c deleted file mode 100644 index 96949a006e..0000000000 --- a/waterbox/libc/functions/math/llrintf.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -/* uses LLONG_MAX > 2^24, see comments in lrint.c */ - -long long llrintf(float x) -{ - return rintf(x); -} diff --git a/waterbox/libc/functions/math/llrintl.c b/waterbox/libc/functions/math/llrintl.c deleted file mode 100644 index 3449f6f2b4..0000000000 --- a/waterbox/libc/functions/math/llrintl.c +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include -#include "libm.h" - - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long long llrintl(long double x) -{ - return llrint(x); -} -#elif defined(FE_INEXACT) -/* -see comments in lrint.c - -Note that if LLONG_MAX == 0x7fffffffffffffff && LDBL_MANT_DIG == 64 -then x == 2**63 - 0.5 is the only input that overflows and -raises inexact (with tonearest or upward rounding mode) -*/ -long long llrintl(long double x) -{ - #pragma STDC FENV_ACCESS ON - int e; - - e = fetestexcept(FE_INEXACT); - x = rintl(x); - if (!e && (x > LLONG_MAX || x < LLONG_MIN)) - feclearexcept(FE_INEXACT); - /* conversion */ - return x; -} -#else -long long llrintl(long double x) -{ - return rintl(x); -} -#endif diff --git a/waterbox/libc/functions/math/llround.c b/waterbox/libc/functions/math/llround.c deleted file mode 100644 index 4d94787d62..0000000000 --- a/waterbox/libc/functions/math/llround.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -long long llround(double x) -{ - return round(x); -} diff --git a/waterbox/libc/functions/math/llroundf.c b/waterbox/libc/functions/math/llroundf.c deleted file mode 100644 index 19eb77ee3d..0000000000 --- a/waterbox/libc/functions/math/llroundf.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -long long llroundf(float x) -{ - return roundf(x); -} diff --git a/waterbox/libc/functions/math/llroundl.c b/waterbox/libc/functions/math/llroundl.c deleted file mode 100644 index 2c2ee5ecd6..0000000000 --- a/waterbox/libc/functions/math/llroundl.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -long long llroundl(long double x) -{ - return roundl(x); -} diff --git a/waterbox/libc/functions/math/log.c b/waterbox/libc/functions/math/log.c deleted file mode 100644 index e61e113d41..0000000000 --- a/waterbox/libc/functions/math/log.c +++ /dev/null @@ -1,118 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_log.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* log(x) - * Return the logarithm of x - * - * Method : - * 1. Argument Reduction: find k and f such that - * x = 2^k * (1+f), - * where sqrt(2)/2 < 1+f < sqrt(2) . - * - * 2. Approximation of log(1+f). - * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) - * = 2s + 2/3 s**3 + 2/5 s**5 + ....., - * = 2s + s*R - * We use a special Remez algorithm on [0,0.1716] to generate - * a polynomial of degree 14 to approximate R The maximum error - * of this polynomial approximation is bounded by 2**-58.45. In - * other words, - * 2 4 6 8 10 12 14 - * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s - * (the values of Lg1 to Lg7 are listed in the program) - * and - * | 2 14 | -58.45 - * | Lg1*s +...+Lg7*s - R(z) | <= 2 - * | | - * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. - * In order to guarantee error in log below 1ulp, we compute log - * by - * log(1+f) = f - s*(f - R) (if f is not too large) - * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy) - * - * 3. Finally, log(x) = k*ln2 + log(1+f). - * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) - * Here ln2 is split into two floating point number: - * ln2_hi + ln2_lo, - * where n*ln2_hi is always exact for |n| < 2000. - * - * Special cases: - * log(x) is NaN with signal if x < 0 (including -INF) ; - * log(+INF) is +INF; log(0) is -INF with signal; - * log(NaN) is that NaN with no signal. - * - * Accuracy: - * according to an error analysis, the error is always less than - * 1 ulp (unit in the last place). - * - * Constants: - * The hexadecimal values are the intended ones for the following - * constants. The decimal values may be used, provided that the - * compiler will convert from decimal to binary accurately enough - * to produce the hexadecimal values shown. - */ - -#include -#include - -static const double -ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ -ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ -Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ -Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ -Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ -Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ -Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ -Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ -Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ - -double log(double x) -{ - union {double f; uint64_t i;} u = {x}; - double_t hfsq,f,s,z,R,w,t1,t2,dk; - uint32_t hx; - int k; - - hx = u.i>>32; - k = 0; - if (hx < 0x00100000 || hx>>31) { - if (u.i<<1 == 0) - return -1/(x*x); /* log(+-0)=-inf */ - if (hx>>31) - return (x-x)/0.0; /* log(-#) = NaN */ - /* subnormal number, scale x up */ - k -= 54; - x *= 0x1p54; - u.f = x; - hx = u.i>>32; - } else if (hx >= 0x7ff00000) { - return x; - } else if (hx == 0x3ff00000 && u.i<<32 == 0) - return 0; - - /* reduce x into [sqrt(2)/2, sqrt(2)] */ - hx += 0x3ff00000 - 0x3fe6a09e; - k += (int)(hx>>20) - 0x3ff; - hx = (hx&0x000fffff) + 0x3fe6a09e; - u.i = (uint64_t)hx<<32 | (u.i&0xffffffff); - x = u.f; - - f = x - 1.0; - hfsq = 0.5*f*f; - s = f/(2.0+f); - z = s*s; - w = z*z; - t1 = w*(Lg2+w*(Lg4+w*Lg6)); - t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); - R = t2 + t1; - dk = k; - return s*(hfsq+R) + dk*ln2_lo - hfsq + f + dk*ln2_hi; -} diff --git a/waterbox/libc/functions/math/log10.c b/waterbox/libc/functions/math/log10.c deleted file mode 100644 index 81026876b2..0000000000 --- a/waterbox/libc/functions/math/log10.c +++ /dev/null @@ -1,101 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_log10.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* - * Return the base 10 logarithm of x. See log.c for most comments. - * - * Reduce x to 2^k (1+f) and calculate r = log(1+f) - f + f*f/2 - * as in log.c, then combine and scale in extra precision: - * log10(x) = (f - f*f/2 + r)/log(10) + k*log10(2) - */ - -#include -#include - -static const double -ivln10hi = 4.34294481878168880939e-01, /* 0x3fdbcb7b, 0x15200000 */ -ivln10lo = 2.50829467116452752298e-11, /* 0x3dbb9438, 0xca9aadd5 */ -log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */ -log10_2lo = 3.69423907715893078616e-13, /* 0x3D59FEF3, 0x11F12B36 */ -Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ -Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ -Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ -Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ -Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ -Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ -Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ - -double log10(double x) -{ - union {double f; uint64_t i;} u = {x}; - double_t hfsq,f,s,z,R,w,t1,t2,dk,y,hi,lo,val_hi,val_lo; - uint32_t hx; - int k; - - hx = u.i>>32; - k = 0; - if (hx < 0x00100000 || hx>>31) { - if (u.i<<1 == 0) - return -1/(x*x); /* log(+-0)=-inf */ - if (hx>>31) - return (x-x)/0.0; /* log(-#) = NaN */ - /* subnormal number, scale x up */ - k -= 54; - x *= 0x1p54; - u.f = x; - hx = u.i>>32; - } else if (hx >= 0x7ff00000) { - return x; - } else if (hx == 0x3ff00000 && u.i<<32 == 0) - return 0; - - /* reduce x into [sqrt(2)/2, sqrt(2)] */ - hx += 0x3ff00000 - 0x3fe6a09e; - k += (int)(hx>>20) - 0x3ff; - hx = (hx&0x000fffff) + 0x3fe6a09e; - u.i = (uint64_t)hx<<32 | (u.i&0xffffffff); - x = u.f; - - f = x - 1.0; - hfsq = 0.5*f*f; - s = f/(2.0+f); - z = s*s; - w = z*z; - t1 = w*(Lg2+w*(Lg4+w*Lg6)); - t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); - R = t2 + t1; - - /* See log2.c for details. */ - /* hi+lo = f - hfsq + s*(hfsq+R) ~ log(1+f) */ - hi = f - hfsq; - u.f = hi; - u.i &= (uint64_t)-1<<32; - hi = u.f; - lo = f - hi - hfsq + s*(hfsq+R); - - /* val_hi+val_lo ~ log10(1+f) + k*log10(2) */ - val_hi = hi*ivln10hi; - dk = k; - y = dk*log10_2hi; - val_lo = dk*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi; - - /* - * Extra precision in for adding y is not strictly needed - * since there is no very large cancellation near x = sqrt(2) or - * x = 1/sqrt(2), but we do it anyway since it costs little on CPUs - * with some parallelism and it reduces the error for many args. - */ - w = y + val_hi; - val_lo += (y - w) + val_hi; - val_hi = w; - - return val_lo + val_hi; -} diff --git a/waterbox/libc/functions/math/log10f.c b/waterbox/libc/functions/math/log10f.c deleted file mode 100644 index 9ca2f017da..0000000000 --- a/waterbox/libc/functions/math/log10f.c +++ /dev/null @@ -1,77 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_log10f.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* - * See comments in log10.c. - */ - -#include -#include - -static const float -ivln10hi = 4.3432617188e-01, /* 0x3ede6000 */ -ivln10lo = -3.1689971365e-05, /* 0xb804ead9 */ -log10_2hi = 3.0102920532e-01, /* 0x3e9a2080 */ -log10_2lo = 7.9034151668e-07, /* 0x355427db */ -/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ -Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */ -Lg2 = 0xccce13.0p-25, /* 0.40000972152 */ -Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */ -Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */ - -float log10f(float x) -{ - union {float f; uint32_t i;} u = {x}; - float_t hfsq,f,s,z,R,w,t1,t2,dk,hi,lo; - uint32_t ix; - int k; - - ix = u.i; - k = 0; - if (ix < 0x00800000 || ix>>31) { /* x < 2**-126 */ - if (ix<<1 == 0) - return -1/(x*x); /* log(+-0)=-inf */ - if (ix>>31) - return (x-x)/0.0f; /* log(-#) = NaN */ - /* subnormal number, scale up x */ - k -= 25; - x *= 0x1p25f; - u.f = x; - ix = u.i; - } else if (ix >= 0x7f800000) { - return x; - } else if (ix == 0x3f800000) - return 0; - - /* reduce x into [sqrt(2)/2, sqrt(2)] */ - ix += 0x3f800000 - 0x3f3504f3; - k += (int)(ix>>23) - 0x7f; - ix = (ix&0x007fffff) + 0x3f3504f3; - u.i = ix; - x = u.f; - - f = x - 1.0f; - s = f/(2.0f + f); - z = s*s; - w = z*z; - t1= w*(Lg2+w*Lg4); - t2= z*(Lg1+w*Lg3); - R = t2 + t1; - hfsq = 0.5f*f*f; - - hi = f - hfsq; - u.f = hi; - u.i &= 0xfffff000; - hi = u.f; - lo = f - hi - hfsq + s*(hfsq+R); - dk = k; - return dk*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi + hi*ivln10hi + dk*log10_2hi; -} diff --git a/waterbox/libc/functions/math/log10l.c b/waterbox/libc/functions/math/log10l.c deleted file mode 100644 index 63dcc286d6..0000000000 --- a/waterbox/libc/functions/math/log10l.c +++ /dev/null @@ -1,191 +0,0 @@ -/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_log10l.c */ -/* - * Copyright (c) 2008 Stephen L. Moshier - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/* - * Common logarithm, long double precision - * - * - * SYNOPSIS: - * - * long double x, y, log10l(); - * - * y = log10l( x ); - * - * - * DESCRIPTION: - * - * Returns the base 10 logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the logarithm - * of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * Otherwise, setting z = 2(x-1)/x+1), - * - * log(x) = z + z**3 P(z)/Q(z). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 30000 9.0e-20 2.6e-20 - * IEEE exp(+-10000) 30000 6.0e-20 2.3e-20 - * - * In the tests over the interval exp(+-10000), the logarithms - * of the random arguments were uniformly distributed over - * [-10000, +10000]. - * - * ERROR MESSAGES: - * - * log singularity: x = 0; returns MINLOG - * log domain: x < 0; returns MINLOG - */ - -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double log10l(long double x) -{ - return log10(x); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) - * 1/sqrt(2) <= x < sqrt(2) - * Theoretical peak relative error = 6.2e-22 - */ -static const long double P[] = { - 4.9962495940332550844739E-1L, - 1.0767376367209449010438E1L, - 7.7671073698359539859595E1L, - 2.5620629828144409632571E2L, - 4.2401812743503691187826E2L, - 3.4258224542413922935104E2L, - 1.0747524399916215149070E2L, -}; -static const long double Q[] = { -/* 1.0000000000000000000000E0,*/ - 2.3479774160285863271658E1L, - 1.9444210022760132894510E2L, - 7.7952888181207260646090E2L, - 1.6911722418503949084863E3L, - 2.0307734695595183428202E3L, - 1.2695660352705325274404E3L, - 3.2242573199748645407652E2L, -}; - -/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), - * where z = 2(x-1)/(x+1) - * 1/sqrt(2) <= x < sqrt(2) - * Theoretical peak relative error = 6.16e-22 - */ -static const long double R[4] = { - 1.9757429581415468984296E-3L, --7.1990767473014147232598E-1L, - 1.0777257190312272158094E1L, --3.5717684488096787370998E1L, -}; -static const long double S[4] = { -/* 1.00000000000000000000E0L,*/ --2.6201045551331104417768E1L, - 1.9361891836232102174846E2L, --4.2861221385716144629696E2L, -}; -/* log10(2) */ -#define L102A 0.3125L -#define L102B -1.1470004336018804786261e-2L -/* log10(e) */ -#define L10EA 0.5L -#define L10EB -6.5705518096748172348871e-2L - -#define SQRTH 0.70710678118654752440L - -long double log10l(long double x) -{ - long double y, z; - int e; - - if (isnan(x)) - return x; - if(x <= 0.0) { - if(x == 0.0) - return -1.0 / (x*x); - return (x - x) / 0.0; - } - if (x == INFINITY) - return INFINITY; - /* separate mantissa from exponent */ - /* Note, frexp is used so that denormal numbers - * will be handled properly. - */ - x = frexpl(x, &e); - - /* logarithm using log(x) = z + z**3 P(z)/Q(z), - * where z = 2(x-1)/x+1) - */ - if (e > 2 || e < -2) { - if (x < SQRTH) { /* 2(2x-1)/(2x+1) */ - e -= 1; - z = x - 0.5; - y = 0.5 * z + 0.5; - } else { /* 2 (x-1)/(x+1) */ - z = x - 0.5; - z -= 0.5; - y = 0.5 * x + 0.5; - } - x = z / y; - z = x*x; - y = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3)); - goto done; - } - - /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ - if (x < SQRTH) { - e -= 1; - x = 2.0*x - 1.0; - } else { - x = x - 1.0; - } - z = x*x; - y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 7)); - y = y - 0.5*z; - -done: - /* Multiply log of fraction by log10(e) - * and base 2 exponent by log10(2). - * - * ***CAUTION*** - * - * This sequence of operations is critical and it may - * be horribly defeated by some compiler optimizers. - */ - z = y * (L10EB); - z += x * (L10EB); - z += e * (L102B); - z += y * (L10EA); - z += x * (L10EA); - z += e * (L102A); - return z; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -// TODO: broken implementation to make things compile -long double log10l(long double x) -{ - return log10(x); -} -#endif diff --git a/waterbox/libc/functions/math/log1p.c b/waterbox/libc/functions/math/log1p.c deleted file mode 100644 index 0097134940..0000000000 --- a/waterbox/libc/functions/math/log1p.c +++ /dev/null @@ -1,122 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_log1p.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* double log1p(double x) - * Return the natural logarithm of 1+x. - * - * Method : - * 1. Argument Reduction: find k and f such that - * 1+x = 2^k * (1+f), - * where sqrt(2)/2 < 1+f < sqrt(2) . - * - * Note. If k=0, then f=x is exact. However, if k!=0, then f - * may not be representable exactly. In that case, a correction - * term is need. Let u=1+x rounded. Let c = (1+x)-u, then - * log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u), - * and add back the correction term c/u. - * (Note: when x > 2**53, one can simply return log(x)) - * - * 2. Approximation of log(1+f): See log.c - * - * 3. Finally, log1p(x) = k*ln2 + log(1+f) + c/u. See log.c - * - * Special cases: - * log1p(x) is NaN with signal if x < -1 (including -INF) ; - * log1p(+INF) is +INF; log1p(-1) is -INF with signal; - * log1p(NaN) is that NaN with no signal. - * - * Accuracy: - * according to an error analysis, the error is always less than - * 1 ulp (unit in the last place). - * - * Constants: - * The hexadecimal values are the intended ones for the following - * constants. The decimal values may be used, provided that the - * compiler will convert from decimal to binary accurately enough - * to produce the hexadecimal values shown. - * - * Note: Assuming log() return accurate answer, the following - * algorithm can be used to compute log1p(x) to within a few ULP: - * - * u = 1+x; - * if(u==1.0) return x ; else - * return log(u)*(x/(u-1.0)); - * - * See HP-15C Advanced Functions Handbook, p.193. - */ - -#include "libm.h" - -static const double -ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ -ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ -Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ -Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ -Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ -Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ -Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ -Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ -Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ - -double log1p(double x) -{ - union {double f; uint64_t i;} u = {x}; - double_t hfsq,f,c,s,z,R,w,t1,t2,dk; - uint32_t hx,hu; - int k; - - hx = u.i>>32; - k = 1; - if (hx < 0x3fda827a || hx>>31) { /* 1+x < sqrt(2)+ */ - if (hx >= 0xbff00000) { /* x <= -1.0 */ - if (x == -1) - return x/0.0; /* log1p(-1) = -inf */ - return (x-x)/0.0; /* log1p(x<-1) = NaN */ - } - if (hx<<1 < 0x3ca00000<<1) { /* |x| < 2**-53 */ - /* underflow if subnormal */ - if ((hx&0x7ff00000) == 0) - FORCE_EVAL((float)x); - return x; - } - if (hx <= 0xbfd2bec4) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */ - k = 0; - c = 0; - f = x; - } - } else if (hx >= 0x7ff00000) - return x; - if (k) { - u.f = 1 + x; - hu = u.i>>32; - hu += 0x3ff00000 - 0x3fe6a09e; - k = (int)(hu>>20) - 0x3ff; - /* correction term ~ log(1+x)-log(u), avoid underflow in c/u */ - if (k < 54) { - c = k >= 2 ? 1-(u.f-x) : x-(u.f-1); - c /= u.f; - } else - c = 0; - /* reduce u into [sqrt(2)/2, sqrt(2)] */ - hu = (hu&0x000fffff) + 0x3fe6a09e; - u.i = (uint64_t)hu<<32 | (u.i&0xffffffff); - f = u.f - 1; - } - hfsq = 0.5*f*f; - s = f/(2.0+f); - z = s*s; - w = z*z; - t1 = w*(Lg2+w*(Lg4+w*Lg6)); - t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); - R = t2 + t1; - dk = k; - return s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi; -} diff --git a/waterbox/libc/functions/math/log1pf.c b/waterbox/libc/functions/math/log1pf.c deleted file mode 100644 index 23985c3567..0000000000 --- a/waterbox/libc/functions/math/log1pf.c +++ /dev/null @@ -1,77 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_log1pf.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" - -static const float -ln2_hi = 6.9313812256e-01, /* 0x3f317180 */ -ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */ -/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ -Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */ -Lg2 = 0xccce13.0p-25, /* 0.40000972152 */ -Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */ -Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */ - -float log1pf(float x) -{ - union {float f; uint32_t i;} u = {x}; - float_t hfsq,f,c,s,z,R,w,t1,t2,dk; - uint32_t ix,iu; - int k; - - ix = u.i; - k = 1; - if (ix < 0x3ed413d0 || ix>>31) { /* 1+x < sqrt(2)+ */ - if (ix >= 0xbf800000) { /* x <= -1.0 */ - if (x == -1) - return x/0.0f; /* log1p(-1)=+inf */ - return (x-x)/0.0f; /* log1p(x<-1)=NaN */ - } - if (ix<<1 < 0x33800000<<1) { /* |x| < 2**-24 */ - /* underflow if subnormal */ - if ((ix&0x7f800000) == 0) - FORCE_EVAL(x*x); - return x; - } - if (ix <= 0xbe95f619) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */ - k = 0; - c = 0; - f = x; - } - } else if (ix >= 0x7f800000) - return x; - if (k) { - u.f = 1 + x; - iu = u.i; - iu += 0x3f800000 - 0x3f3504f3; - k = (int)(iu>>23) - 0x7f; - /* correction term ~ log(1+x)-log(u), avoid underflow in c/u */ - if (k < 25) { - c = k >= 2 ? 1-(u.f-x) : x-(u.f-1); - c /= u.f; - } else - c = 0; - /* reduce u into [sqrt(2)/2, sqrt(2)] */ - iu = (iu&0x007fffff) + 0x3f3504f3; - u.i = iu; - f = u.f - 1; - } - s = f/(2.0f + f); - z = s*s; - w = z*z; - t1= w*(Lg2+w*Lg4); - t2= z*(Lg1+w*Lg3); - R = t2 + t1; - hfsq = 0.5f*f*f; - dk = k; - return s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi; -} diff --git a/waterbox/libc/functions/math/log1pl.c b/waterbox/libc/functions/math/log1pl.c deleted file mode 100644 index 141b5f0b0c..0000000000 --- a/waterbox/libc/functions/math/log1pl.c +++ /dev/null @@ -1,177 +0,0 @@ -/* origin: OpenBSD /usr/src/lib/libm/src/ld80/s_log1pl.c */ -/* - * Copyright (c) 2008 Stephen L. Moshier - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/* - * Relative error logarithm - * Natural logarithm of 1+x, long double precision - * - * - * SYNOPSIS: - * - * long double x, y, log1pl(); - * - * y = log1pl( x ); - * - * - * DESCRIPTION: - * - * Returns the base e (2.718...) logarithm of 1+x. - * - * The argument 1+x is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the logarithm - * of the fraction is approximated by - * - * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x). - * - * Otherwise, setting z = 2(x-1)/x+1), - * - * log(x) = z + z^3 P(z)/Q(z). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1.0, 9.0 100000 8.2e-20 2.5e-20 - */ - -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double log1pl(long double x) -{ - return log1p(x); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -/* Coefficients for log(1+x) = x - x^2 / 2 + x^3 P(x)/Q(x) - * 1/sqrt(2) <= x < sqrt(2) - * Theoretical peak relative error = 2.32e-20 - */ -static const long double P[] = { - 4.5270000862445199635215E-5L, - 4.9854102823193375972212E-1L, - 6.5787325942061044846969E0L, - 2.9911919328553073277375E1L, - 6.0949667980987787057556E1L, - 5.7112963590585538103336E1L, - 2.0039553499201281259648E1L, -}; -static const long double Q[] = { -/* 1.0000000000000000000000E0,*/ - 1.5062909083469192043167E1L, - 8.3047565967967209469434E1L, - 2.2176239823732856465394E2L, - 3.0909872225312059774938E2L, - 2.1642788614495947685003E2L, - 6.0118660497603843919306E1L, -}; - -/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), - * where z = 2(x-1)/(x+1) - * 1/sqrt(2) <= x < sqrt(2) - * Theoretical peak relative error = 6.16e-22 - */ -static const long double R[4] = { - 1.9757429581415468984296E-3L, --7.1990767473014147232598E-1L, - 1.0777257190312272158094E1L, --3.5717684488096787370998E1L, -}; -static const long double S[4] = { -/* 1.00000000000000000000E0L,*/ --2.6201045551331104417768E1L, - 1.9361891836232102174846E2L, --4.2861221385716144629696E2L, -}; -static const long double C1 = 6.9314575195312500000000E-1L; -static const long double C2 = 1.4286068203094172321215E-6L; - -#define SQRTH 0.70710678118654752440L - -long double log1pl(long double xm1) -{ - long double x, y, z; - int e; - - if (isnan(xm1)) - return xm1; - if (xm1 == INFINITY) - return xm1; - if (xm1 == 0.0) - return xm1; - - x = xm1 + 1.0; - - /* Test for domain errors. */ - if (x <= 0.0) { - if (x == 0.0) - return -1/(x*x); /* -inf with divbyzero */ - return 0/0.0f; /* nan with invalid */ - } - - /* Separate mantissa from exponent. - Use frexp so that denormal numbers will be handled properly. */ - x = frexpl(x, &e); - - /* logarithm using log(x) = z + z^3 P(z)/Q(z), - where z = 2(x-1)/x+1) */ - if (e > 2 || e < -2) { - if (x < SQRTH) { /* 2(2x-1)/(2x+1) */ - e -= 1; - z = x - 0.5; - y = 0.5 * z + 0.5; - } else { /* 2 (x-1)/(x+1) */ - z = x - 0.5; - z -= 0.5; - y = 0.5 * x + 0.5; - } - x = z / y; - z = x*x; - z = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3)); - z = z + e * C2; - z = z + x; - z = z + e * C1; - return z; - } - - /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ - if (x < SQRTH) { - e -= 1; - if (e != 0) - x = 2.0 * x - 1.0; - else - x = xm1; - } else { - if (e != 0) - x = x - 1.0; - else - x = xm1; - } - z = x*x; - y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 6)); - y = y + e * C2; - z = y - 0.5 * z; - z = z + x; - z = z + e * C1; - return z; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -// TODO: broken implementation to make things compile -long double log1pl(long double x) -{ - return log1p(x); -} -#endif diff --git a/waterbox/libc/functions/math/log2.c b/waterbox/libc/functions/math/log2.c deleted file mode 100644 index 0aafad4b86..0000000000 --- a/waterbox/libc/functions/math/log2.c +++ /dev/null @@ -1,122 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_log2.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* - * Return the base 2 logarithm of x. See log.c for most comments. - * - * Reduce x to 2^k (1+f) and calculate r = log(1+f) - f + f*f/2 - * as in log.c, then combine and scale in extra precision: - * log2(x) = (f - f*f/2 + r)/log(2) + k - */ - -#include -#include - -static const double -ivln2hi = 1.44269504072144627571e+00, /* 0x3ff71547, 0x65200000 */ -ivln2lo = 1.67517131648865118353e-10, /* 0x3de705fc, 0x2eefa200 */ -Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ -Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ -Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ -Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ -Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ -Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ -Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ - -double log2(double x) -{ - union {double f; uint64_t i;} u = {x}; - double_t hfsq,f,s,z,R,w,t1,t2,y,hi,lo,val_hi,val_lo; - uint32_t hx; - int k; - - hx = u.i>>32; - k = 0; - if (hx < 0x00100000 || hx>>31) { - if (u.i<<1 == 0) - return -1/(x*x); /* log(+-0)=-inf */ - if (hx>>31) - return (x-x)/0.0; /* log(-#) = NaN */ - /* subnormal number, scale x up */ - k -= 54; - x *= 0x1p54; - u.f = x; - hx = u.i>>32; - } else if (hx >= 0x7ff00000) { - return x; - } else if (hx == 0x3ff00000 && u.i<<32 == 0) - return 0; - - /* reduce x into [sqrt(2)/2, sqrt(2)] */ - hx += 0x3ff00000 - 0x3fe6a09e; - k += (int)(hx>>20) - 0x3ff; - hx = (hx&0x000fffff) + 0x3fe6a09e; - u.i = (uint64_t)hx<<32 | (u.i&0xffffffff); - x = u.f; - - f = x - 1.0; - hfsq = 0.5*f*f; - s = f/(2.0+f); - z = s*s; - w = z*z; - t1 = w*(Lg2+w*(Lg4+w*Lg6)); - t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); - R = t2 + t1; - - /* - * f-hfsq must (for args near 1) be evaluated in extra precision - * to avoid a large cancellation when x is near sqrt(2) or 1/sqrt(2). - * This is fairly efficient since f-hfsq only depends on f, so can - * be evaluated in parallel with R. Not combining hfsq with R also - * keeps R small (though not as small as a true `lo' term would be), - * so that extra precision is not needed for terms involving R. - * - * Compiler bugs involving extra precision used to break Dekker's - * theorem for spitting f-hfsq as hi+lo, unless double_t was used - * or the multi-precision calculations were avoided when double_t - * has extra precision. These problems are now automatically - * avoided as a side effect of the optimization of combining the - * Dekker splitting step with the clear-low-bits step. - * - * y must (for args near sqrt(2) and 1/sqrt(2)) be added in extra - * precision to avoid a very large cancellation when x is very near - * these values. Unlike the above cancellations, this problem is - * specific to base 2. It is strange that adding +-1 is so much - * harder than adding +-ln2 or +-log10_2. - * - * This uses Dekker's theorem to normalize y+val_hi, so the - * compiler bugs are back in some configurations, sigh. And I - * don't want to used double_t to avoid them, since that gives a - * pessimization and the support for avoiding the pessimization - * is not yet available. - * - * The multi-precision calculations for the multiplications are - * routine. - */ - - /* hi+lo = f - hfsq + s*(hfsq+R) ~ log(1+f) */ - hi = f - hfsq; - u.f = hi; - u.i &= (uint64_t)-1<<32; - hi = u.f; - lo = f - hi - hfsq + s*(hfsq+R); - - val_hi = hi*ivln2hi; - val_lo = (lo+hi)*ivln2lo + lo*ivln2hi; - - /* spadd(val_hi, val_lo, y), except for not using double_t: */ - y = k; - w = y + val_hi; - val_lo += (y - w) + val_hi; - val_hi = w; - - return val_lo + val_hi; -} diff --git a/waterbox/libc/functions/math/log2f.c b/waterbox/libc/functions/math/log2f.c deleted file mode 100644 index b3e305fe2a..0000000000 --- a/waterbox/libc/functions/math/log2f.c +++ /dev/null @@ -1,74 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_log2f.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* - * See comments in log2.c. - */ - -#include -#include - -static const float -ivln2hi = 1.4428710938e+00, /* 0x3fb8b000 */ -ivln2lo = -1.7605285393e-04, /* 0xb9389ad4 */ -/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ -Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */ -Lg2 = 0xccce13.0p-25, /* 0.40000972152 */ -Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */ -Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */ - -float log2f(float x) -{ - union {float f; uint32_t i;} u = {x}; - float_t hfsq,f,s,z,R,w,t1,t2,hi,lo; - uint32_t ix; - int k; - - ix = u.i; - k = 0; - if (ix < 0x00800000 || ix>>31) { /* x < 2**-126 */ - if (ix<<1 == 0) - return -1/(x*x); /* log(+-0)=-inf */ - if (ix>>31) - return (x-x)/0.0f; /* log(-#) = NaN */ - /* subnormal number, scale up x */ - k -= 25; - x *= 0x1p25f; - u.f = x; - ix = u.i; - } else if (ix >= 0x7f800000) { - return x; - } else if (ix == 0x3f800000) - return 0; - - /* reduce x into [sqrt(2)/2, sqrt(2)] */ - ix += 0x3f800000 - 0x3f3504f3; - k += (int)(ix>>23) - 0x7f; - ix = (ix&0x007fffff) + 0x3f3504f3; - u.i = ix; - x = u.f; - - f = x - 1.0f; - s = f/(2.0f + f); - z = s*s; - w = z*z; - t1= w*(Lg2+w*Lg4); - t2= z*(Lg1+w*Lg3); - R = t2 + t1; - hfsq = 0.5f*f*f; - - hi = f - hfsq; - u.f = hi; - u.i &= 0xfffff000; - hi = u.f; - lo = f - hi - hfsq + s*(hfsq+R); - return (lo+hi)*ivln2lo + lo*ivln2hi + hi*ivln2hi + k; -} diff --git a/waterbox/libc/functions/math/log2l.c b/waterbox/libc/functions/math/log2l.c deleted file mode 100644 index 722b451a02..0000000000 --- a/waterbox/libc/functions/math/log2l.c +++ /dev/null @@ -1,182 +0,0 @@ -/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_log2l.c */ -/* - * Copyright (c) 2008 Stephen L. Moshier - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/* - * Base 2 logarithm, long double precision - * - * - * SYNOPSIS: - * - * long double x, y, log2l(); - * - * y = log2l( x ); - * - * - * DESCRIPTION: - * - * Returns the base 2 logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the (natural) - * logarithm of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * Otherwise, setting z = 2(x-1)/x+1), - * - * log(x) = z + z**3 P(z)/Q(z). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 30000 9.8e-20 2.7e-20 - * IEEE exp(+-10000) 70000 5.4e-20 2.3e-20 - * - * In the tests over the interval exp(+-10000), the logarithms - * of the random arguments were uniformly distributed over - * [-10000, +10000]. - */ - -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double log2l(long double x) -{ - return log2(x); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -/* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x) - * 1/sqrt(2) <= x < sqrt(2) - * Theoretical peak relative error = 6.2e-22 - */ -static const long double P[] = { - 4.9962495940332550844739E-1L, - 1.0767376367209449010438E1L, - 7.7671073698359539859595E1L, - 2.5620629828144409632571E2L, - 4.2401812743503691187826E2L, - 3.4258224542413922935104E2L, - 1.0747524399916215149070E2L, -}; -static const long double Q[] = { -/* 1.0000000000000000000000E0,*/ - 2.3479774160285863271658E1L, - 1.9444210022760132894510E2L, - 7.7952888181207260646090E2L, - 1.6911722418503949084863E3L, - 2.0307734695595183428202E3L, - 1.2695660352705325274404E3L, - 3.2242573199748645407652E2L, -}; - -/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), - * where z = 2(x-1)/(x+1) - * 1/sqrt(2) <= x < sqrt(2) - * Theoretical peak relative error = 6.16e-22 - */ -static const long double R[4] = { - 1.9757429581415468984296E-3L, --7.1990767473014147232598E-1L, - 1.0777257190312272158094E1L, --3.5717684488096787370998E1L, -}; -static const long double S[4] = { -/* 1.00000000000000000000E0L,*/ --2.6201045551331104417768E1L, - 1.9361891836232102174846E2L, --4.2861221385716144629696E2L, -}; -/* log2(e) - 1 */ -#define LOG2EA 4.4269504088896340735992e-1L - -#define SQRTH 0.70710678118654752440L - -long double log2l(long double x) -{ - long double y, z; - int e; - - if (isnan(x)) - return x; - if (x == INFINITY) - return x; - if (x <= 0.0) { - if (x == 0.0) - return -1/(x*x); /* -inf with divbyzero */ - return 0/0.0f; /* nan with invalid */ - } - - /* separate mantissa from exponent */ - /* Note, frexp is used so that denormal numbers - * will be handled properly. - */ - x = frexpl(x, &e); - - /* logarithm using log(x) = z + z**3 P(z)/Q(z), - * where z = 2(x-1)/x+1) - */ - if (e > 2 || e < -2) { - if (x < SQRTH) { /* 2(2x-1)/(2x+1) */ - e -= 1; - z = x - 0.5; - y = 0.5 * z + 0.5; - } else { /* 2 (x-1)/(x+1) */ - z = x - 0.5; - z -= 0.5; - y = 0.5 * x + 0.5; - } - x = z / y; - z = x*x; - y = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3)); - goto done; - } - - /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ - if (x < SQRTH) { - e -= 1; - x = 2.0*x - 1.0; - } else { - x = x - 1.0; - } - z = x*x; - y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 7)); - y = y - 0.5*z; - -done: - /* Multiply log of fraction by log2(e) - * and base 2 exponent by 1 - * - * ***CAUTION*** - * - * This sequence of operations is critical and it may - * be horribly defeated by some compiler optimizers. - */ - z = y * LOG2EA; - z += x * LOG2EA; - z += y; - z += x; - z += e; - return z; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -// TODO: broken implementation to make things compile -long double log2l(long double x) -{ - return log2(x); -} -#endif diff --git a/waterbox/libc/functions/math/logb.c b/waterbox/libc/functions/math/logb.c deleted file mode 100644 index 7f8bdfae19..0000000000 --- a/waterbox/libc/functions/math/logb.c +++ /dev/null @@ -1,17 +0,0 @@ -#include - -/* -special cases: - logb(+-0) = -inf, and raise divbyzero - logb(+-inf) = +inf - logb(nan) = nan -*/ - -double logb(double x) -{ - if (!isfinite(x)) - return x * x; - if (x == 0) - return -1/(x*x); - return ilogb(x); -} diff --git a/waterbox/libc/functions/math/logbf.c b/waterbox/libc/functions/math/logbf.c deleted file mode 100644 index a0a0b5ed5b..0000000000 --- a/waterbox/libc/functions/math/logbf.c +++ /dev/null @@ -1,10 +0,0 @@ -#include - -float logbf(float x) -{ - if (!isfinite(x)) - return x * x; - if (x == 0) - return -1/(x*x); - return ilogbf(x); -} diff --git a/waterbox/libc/functions/math/logbl.c b/waterbox/libc/functions/math/logbl.c deleted file mode 100644 index 962973a7b9..0000000000 --- a/waterbox/libc/functions/math/logbl.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double logbl(long double x) -{ - return logb(x); -} -#else -long double logbl(long double x) -{ - if (!isfinite(x)) - return x * x; - if (x == 0) - return -1/(x*x); - return ilogbl(x); -} -#endif diff --git a/waterbox/libc/functions/math/logf.c b/waterbox/libc/functions/math/logf.c deleted file mode 100644 index 52230a1bd4..0000000000 --- a/waterbox/libc/functions/math/logf.c +++ /dev/null @@ -1,69 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_logf.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include -#include - -static const float -ln2_hi = 6.9313812256e-01, /* 0x3f317180 */ -ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */ -/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ -Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */ -Lg2 = 0xccce13.0p-25, /* 0.40000972152 */ -Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */ -Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */ - -float logf(float x) -{ - union {float f; uint32_t i;} u = {x}; - float_t hfsq,f,s,z,R,w,t1,t2,dk; - uint32_t ix; - int k; - - ix = u.i; - k = 0; - if (ix < 0x00800000 || ix>>31) { /* x < 2**-126 */ - if (ix<<1 == 0) - return -1/(x*x); /* log(+-0)=-inf */ - if (ix>>31) - return (x-x)/0.0f; /* log(-#) = NaN */ - /* subnormal number, scale up x */ - k -= 25; - x *= 0x1p25f; - u.f = x; - ix = u.i; - } else if (ix >= 0x7f800000) { - return x; - } else if (ix == 0x3f800000) - return 0; - - /* reduce x into [sqrt(2)/2, sqrt(2)] */ - ix += 0x3f800000 - 0x3f3504f3; - k += (int)(ix>>23) - 0x7f; - ix = (ix&0x007fffff) + 0x3f3504f3; - u.i = ix; - x = u.f; - - f = x - 1.0f; - s = f/(2.0f + f); - z = s*s; - w = z*z; - t1= w*(Lg2+w*Lg4); - t2= z*(Lg1+w*Lg3); - R = t2 + t1; - hfsq = 0.5f*f*f; - dk = k; - return s*(hfsq+R) + dk*ln2_lo - hfsq + f + dk*ln2_hi; -} diff --git a/waterbox/libc/functions/math/logl.c b/waterbox/libc/functions/math/logl.c deleted file mode 100644 index 5d5365929e..0000000000 --- a/waterbox/libc/functions/math/logl.c +++ /dev/null @@ -1,175 +0,0 @@ -/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_logl.c */ -/* - * Copyright (c) 2008 Stephen L. Moshier - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/* - * Natural logarithm, long double precision - * - * - * SYNOPSIS: - * - * long double x, y, logl(); - * - * y = logl( x ); - * - * - * DESCRIPTION: - * - * Returns the base e (2.718...) logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the logarithm - * of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * Otherwise, setting z = 2(x-1)/(x+1), - * - * log(x) = log(1+z/2) - log(1-z/2) = z + z**3 P(z)/Q(z). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 150000 8.71e-20 2.75e-20 - * IEEE exp(+-10000) 100000 5.39e-20 2.34e-20 - * - * In the tests over the interval exp(+-10000), the logarithms - * of the random arguments were uniformly distributed over - * [-10000, +10000]. - */ - -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double logl(long double x) -{ - return log(x); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) - * 1/sqrt(2) <= x < sqrt(2) - * Theoretical peak relative error = 2.32e-20 - */ -static const long double P[] = { - 4.5270000862445199635215E-5L, - 4.9854102823193375972212E-1L, - 6.5787325942061044846969E0L, - 2.9911919328553073277375E1L, - 6.0949667980987787057556E1L, - 5.7112963590585538103336E1L, - 2.0039553499201281259648E1L, -}; -static const long double Q[] = { -/* 1.0000000000000000000000E0,*/ - 1.5062909083469192043167E1L, - 8.3047565967967209469434E1L, - 2.2176239823732856465394E2L, - 3.0909872225312059774938E2L, - 2.1642788614495947685003E2L, - 6.0118660497603843919306E1L, -}; - -/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), - * where z = 2(x-1)/(x+1) - * 1/sqrt(2) <= x < sqrt(2) - * Theoretical peak relative error = 6.16e-22 - */ -static const long double R[4] = { - 1.9757429581415468984296E-3L, --7.1990767473014147232598E-1L, - 1.0777257190312272158094E1L, --3.5717684488096787370998E1L, -}; -static const long double S[4] = { -/* 1.00000000000000000000E0L,*/ --2.6201045551331104417768E1L, - 1.9361891836232102174846E2L, --4.2861221385716144629696E2L, -}; -static const long double C1 = 6.9314575195312500000000E-1L; -static const long double C2 = 1.4286068203094172321215E-6L; - -#define SQRTH 0.70710678118654752440L - -long double logl(long double x) -{ - long double y, z; - int e; - - if (isnan(x)) - return x; - if (x == INFINITY) - return x; - if (x <= 0.0) { - if (x == 0.0) - return -1/(x*x); /* -inf with divbyzero */ - return 0/0.0f; /* nan with invalid */ - } - - /* separate mantissa from exponent */ - /* Note, frexp is used so that denormal numbers - * will be handled properly. - */ - x = frexpl(x, &e); - - /* logarithm using log(x) = z + z**3 P(z)/Q(z), - * where z = 2(x-1)/(x+1) - */ - if (e > 2 || e < -2) { - if (x < SQRTH) { /* 2(2x-1)/(2x+1) */ - e -= 1; - z = x - 0.5; - y = 0.5 * z + 0.5; - } else { /* 2 (x-1)/(x+1) */ - z = x - 0.5; - z -= 0.5; - y = 0.5 * x + 0.5; - } - x = z / y; - z = x*x; - z = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3)); - z = z + e * C2; - z = z + x; - z = z + e * C1; - return z; - } - - /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ - if (x < SQRTH) { - e -= 1; - x = 2.0*x - 1.0; - } else { - x = x - 1.0; - } - z = x*x; - y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 6)); - y = y + e * C2; - z = y - 0.5*z; - /* Note, the sum of above terms does not exceed x/4, - * so it contributes at most about 1/4 lsb to the error. - */ - z = z + x; - z = z + e * C1; /* This sum has an error of 1/2 lsb. */ - return z; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -// TODO: broken implementation to make things compile -long double logl(long double x) -{ - return log(x); -} -#endif diff --git a/waterbox/libc/functions/math/lrint.c b/waterbox/libc/functions/math/lrint.c deleted file mode 100644 index bdca8b7cb8..0000000000 --- a/waterbox/libc/functions/math/lrint.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include "libm.h" - -/* -If the result cannot be represented (overflow, nan), then -lrint raises the invalid exception. - -Otherwise if the input was not an integer then the inexact -exception is raised. - -C99 is a bit vague about whether inexact exception is -allowed to be raised when invalid is raised. -(F.9 explicitly allows spurious inexact exceptions, F.9.6.5 -does not make it clear if that rule applies to lrint, but -IEEE 754r 7.8 seems to forbid spurious inexact exception in -the ineger conversion functions) - -So we try to make sure that no spurious inexact exception is -raised in case of an overflow. - -If the bit size of long > precision of double, then there -cannot be inexact rounding in case the result overflows, -otherwise LONG_MAX and LONG_MIN can be represented exactly -as a double. -*/ - -#if LONG_MAX < 1U<<53 && defined(FE_INEXACT) -long lrint(double x) -{ - #pragma STDC FENV_ACCESS ON - int e; - - e = fetestexcept(FE_INEXACT); - x = rint(x); - if (!e && (x > LONG_MAX || x < LONG_MIN)) - feclearexcept(FE_INEXACT); - /* conversion */ - return x; -} -#else -long lrint(double x) -{ - return rint(x); -} -#endif diff --git a/waterbox/libc/functions/math/lrintf.c b/waterbox/libc/functions/math/lrintf.c deleted file mode 100644 index ca0b6a46aa..0000000000 --- a/waterbox/libc/functions/math/lrintf.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -/* uses LONG_MAX > 2^24, see comments in lrint.c */ - -long lrintf(float x) -{ - return rintf(x); -} diff --git a/waterbox/libc/functions/math/lrintl.c b/waterbox/libc/functions/math/lrintl.c deleted file mode 100644 index b2a8106d7c..0000000000 --- a/waterbox/libc/functions/math/lrintl.c +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include -#include "libm.h" - - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long lrintl(long double x) -{ - return lrint(x); -} -#elif defined(FE_INEXACT) -/* -see comments in lrint.c - -Note that if LONG_MAX == 0x7fffffffffffffff && LDBL_MANT_DIG == 64 -then x == 2**63 - 0.5 is the only input that overflows and -raises inexact (with tonearest or upward rounding mode) -*/ -long lrintl(long double x) -{ - #pragma STDC FENV_ACCESS ON - int e; - - e = fetestexcept(FE_INEXACT); - x = rintl(x); - if (!e && (x > LONG_MAX || x < LONG_MIN)) - feclearexcept(FE_INEXACT); - /* conversion */ - return x; -} -#else -long lrintl(long double x) -{ - return rintl(x); -} -#endif diff --git a/waterbox/libc/functions/math/lround.c b/waterbox/libc/functions/math/lround.c deleted file mode 100644 index b8b795470f..0000000000 --- a/waterbox/libc/functions/math/lround.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -long lround(double x) -{ - return round(x); -} diff --git a/waterbox/libc/functions/math/lroundf.c b/waterbox/libc/functions/math/lroundf.c deleted file mode 100644 index c4707e7db7..0000000000 --- a/waterbox/libc/functions/math/lroundf.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -long lroundf(float x) -{ - return roundf(x); -} diff --git a/waterbox/libc/functions/math/lroundl.c b/waterbox/libc/functions/math/lroundl.c deleted file mode 100644 index 094fdf6483..0000000000 --- a/waterbox/libc/functions/math/lroundl.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -long lroundl(long double x) -{ - return roundl(x); -} diff --git a/waterbox/libc/functions/math/modf.c b/waterbox/libc/functions/math/modf.c deleted file mode 100644 index 1c8a1db90d..0000000000 --- a/waterbox/libc/functions/math/modf.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "libm.h" - -double modf(double x, double *iptr) -{ - union {double f; uint64_t i;} u = {x}; - uint64_t mask; - int e = (int)(u.i>>52 & 0x7ff) - 0x3ff; - - /* no fractional part */ - if (e >= 52) { - *iptr = x; - if (e == 0x400 && u.i<<12 != 0) /* nan */ - return x; - u.i &= 1ULL<<63; - return u.f; - } - - /* no integral part*/ - if (e < 0) { - u.i &= 1ULL<<63; - *iptr = u.f; - return x; - } - - mask = -1ULL>>12>>e; - if ((u.i & mask) == 0) { - *iptr = x; - u.i &= 1ULL<<63; - return u.f; - } - u.i &= ~mask; - *iptr = u.f; - return x - u.f; -} diff --git a/waterbox/libc/functions/math/modff.c b/waterbox/libc/functions/math/modff.c deleted file mode 100644 index 639514effa..0000000000 --- a/waterbox/libc/functions/math/modff.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "libm.h" - -float modff(float x, float *iptr) -{ - union {float f; uint32_t i;} u = {x}; - uint32_t mask; - int e = (int)(u.i>>23 & 0xff) - 0x7f; - - /* no fractional part */ - if (e >= 23) { - *iptr = x; - if (e == 0x80 && u.i<<9 != 0) { /* nan */ - return x; - } - u.i &= 0x80000000; - return u.f; - } - /* no integral part */ - if (e < 0) { - u.i &= 0x80000000; - *iptr = u.f; - return x; - } - - mask = 0x007fffff>>e; - if ((u.i & mask) == 0) { - *iptr = x; - u.i &= 0x80000000; - return u.f; - } - u.i &= ~mask; - *iptr = u.f; - return x - u.f; -} diff --git a/waterbox/libc/functions/math/modfl.c b/waterbox/libc/functions/math/modfl.c deleted file mode 100644 index a47b1924f7..0000000000 --- a/waterbox/libc/functions/math/modfl.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double modfl(long double x, long double *iptr) -{ - double d; - long double r; - - r = modf(x, &d); - *iptr = d; - return r; -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 - -static const long double toint = 1/LDBL_EPSILON; - -long double modfl(long double x, long double *iptr) -{ - union ldshape u = {x}; - int e = (u.i.se & 0x7fff) - 0x3fff; - int s = u.i.se >> 15; - long double absx; - long double y; - - /* no fractional part */ - if (e >= LDBL_MANT_DIG-1) { - *iptr = x; - if (isnan(x)) - return x; - return s ? -0.0 : 0.0; - } - - /* no integral part*/ - if (e < 0) { - *iptr = s ? -0.0 : 0.0; - return x; - } - - /* raises spurious inexact */ - absx = s ? -x : x; - y = absx + toint - toint - absx; - if (y == 0) { - *iptr = x; - return s ? -0.0 : 0.0; - } - if (y > 0) - y -= 1; - if (s) - y = -y; - *iptr = x + y; - return -y; -} -#endif diff --git a/waterbox/libc/functions/math/nan.c b/waterbox/libc/functions/math/nan.c deleted file mode 100644 index 9e0826c778..0000000000 --- a/waterbox/libc/functions/math/nan.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -double nan(const char *s) -{ - return NAN; -} diff --git a/waterbox/libc/functions/math/nanf.c b/waterbox/libc/functions/math/nanf.c deleted file mode 100644 index 752ce54634..0000000000 --- a/waterbox/libc/functions/math/nanf.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -float nanf(const char *s) -{ - return NAN; -} diff --git a/waterbox/libc/functions/math/nanl.c b/waterbox/libc/functions/math/nanl.c deleted file mode 100644 index 969af5641f..0000000000 --- a/waterbox/libc/functions/math/nanl.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -long double nanl(const char *s) -{ - return NAN; -} diff --git a/waterbox/libc/functions/math/nearbyint.c b/waterbox/libc/functions/math/nearbyint.c deleted file mode 100644 index f4e8aac4f0..0000000000 --- a/waterbox/libc/functions/math/nearbyint.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - -/* nearbyint is the same as rint, but it must not raise the inexact exception */ - -double nearbyint(double x) -{ -#ifdef FE_INEXACT - #pragma STDC FENV_ACCESS ON - int e; - - e = fetestexcept(FE_INEXACT); -#endif - x = rint(x); -#ifdef FE_INEXACT - if (!e) - feclearexcept(FE_INEXACT); -#endif - return x; -} diff --git a/waterbox/libc/functions/math/nearbyintf.c b/waterbox/libc/functions/math/nearbyintf.c deleted file mode 100644 index 092e9ffae5..0000000000 --- a/waterbox/libc/functions/math/nearbyintf.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include - -float nearbyintf(float x) -{ -#ifdef FE_INEXACT - #pragma STDC FENV_ACCESS ON - int e; - - e = fetestexcept(FE_INEXACT); -#endif - x = rintf(x); -#ifdef FE_INEXACT - if (!e) - feclearexcept(FE_INEXACT); -#endif - return x; -} diff --git a/waterbox/libc/functions/math/nearbyintl.c b/waterbox/libc/functions/math/nearbyintl.c deleted file mode 100644 index 82852492f8..0000000000 --- a/waterbox/libc/functions/math/nearbyintl.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double nearbyintl(long double x) -{ - return nearbyint(x); -} -#else -#include -long double nearbyintl(long double x) -{ -#ifdef FE_INEXACT - #pragma STDC FENV_ACCESS ON - int e; - - e = fetestexcept(FE_INEXACT); -#endif - x = rintl(x); -#ifdef FE_INEXACT - if (!e) - feclearexcept(FE_INEXACT); -#endif - return x; -} -#endif diff --git a/waterbox/libc/functions/math/nextafter.c b/waterbox/libc/functions/math/nextafter.c deleted file mode 100644 index ab5795a47a..0000000000 --- a/waterbox/libc/functions/math/nextafter.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "libm.h" - -double nextafter(double x, double y) -{ - union {double f; uint64_t i;} ux={x}, uy={y}; - uint64_t ax, ay; - int e; - - if (isnan(x) || isnan(y)) - return x + y; - if (ux.i == uy.i) - return y; - ax = ux.i & -1ULL/2; - ay = uy.i & -1ULL/2; - if (ax == 0) { - if (ay == 0) - return y; - ux.i = (uy.i & 1ULL<<63) | 1; - } else if (ax > ay || ((ux.i ^ uy.i) & 1ULL<<63)) - ux.i--; - else - ux.i++; - e = ux.i >> 52 & 0x7ff; - /* raise overflow if ux.f is infinite and x is finite */ - if (e == 0x7ff) - FORCE_EVAL(x+x); - /* raise underflow if ux.f is subnormal or zero */ - if (e == 0) - FORCE_EVAL(x*x + ux.f*ux.f); - return ux.f; -} diff --git a/waterbox/libc/functions/math/nextafterf.c b/waterbox/libc/functions/math/nextafterf.c deleted file mode 100644 index 75a09f7d1c..0000000000 --- a/waterbox/libc/functions/math/nextafterf.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "libm.h" - -float nextafterf(float x, float y) -{ - union {float f; uint32_t i;} ux={x}, uy={y}; - uint32_t ax, ay, e; - - if (isnan(x) || isnan(y)) - return x + y; - if (ux.i == uy.i) - return y; - ax = ux.i & 0x7fffffff; - ay = uy.i & 0x7fffffff; - if (ax == 0) { - if (ay == 0) - return y; - ux.i = (uy.i & 0x80000000) | 1; - } else if (ax > ay || ((ux.i ^ uy.i) & 0x80000000)) - ux.i--; - else - ux.i++; - e = ux.i & 0x7f800000; - /* raise overflow if ux.f is infinite and x is finite */ - if (e == 0x7f800000) - FORCE_EVAL(x+x); - /* raise underflow if ux.f is subnormal or zero */ - if (e == 0) - FORCE_EVAL(x*x + ux.f*ux.f); - return ux.f; -} diff --git a/waterbox/libc/functions/math/nextafterl.c b/waterbox/libc/functions/math/nextafterl.c deleted file mode 100644 index 37e858fb49..0000000000 --- a/waterbox/libc/functions/math/nextafterl.c +++ /dev/null @@ -1,75 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double nextafterl(long double x, long double y) -{ - return nextafter(x, y); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -long double nextafterl(long double x, long double y) -{ - union ldshape ux, uy; - - if (isnan(x) || isnan(y)) - return x + y; - if (x == y) - return y; - ux.f = x; - if (x == 0) { - uy.f = y; - ux.i.m = 1; - ux.i.se = uy.i.se & 0x8000; - } else if ((x < y) == !(ux.i.se & 0x8000)) { - ux.i.m++; - if (ux.i.m << 1 == 0) { - ux.i.m = 1ULL << 63; - ux.i.se++; - } - } else { - if (ux.i.m << 1 == 0) { - ux.i.se--; - if (ux.i.se) - ux.i.m = 0; - } - ux.i.m--; - } - /* raise overflow if ux is infinite and x is finite */ - if ((ux.i.se & 0x7fff) == 0x7fff) - return x + x; - /* raise underflow if ux is subnormal or zero */ - if ((ux.i.se & 0x7fff) == 0) - FORCE_EVAL(x*x + ux.f*ux.f); - return ux.f; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -long double nextafterl(long double x, long double y) -{ - union ldshape ux, uy; - - if (isnan(x) || isnan(y)) - return x + y; - if (x == y) - return y; - ux.f = x; - if (x == 0) { - uy.f = y; - ux.i.lo = 1; - ux.i.se = uy.i.se & 0x8000; - } else if ((x < y) == !(ux.i.se & 0x8000)) { - ux.i2.lo++; - if (ux.i2.lo == 0) - ux.i2.hi++; - } else { - if (ux.i2.lo == 0) - ux.i2.hi--; - ux.i2.lo--; - } - /* raise overflow if ux is infinite and x is finite */ - if ((ux.i.se & 0x7fff) == 0x7fff) - return x + x; - /* raise underflow if ux is subnormal or zero */ - if ((ux.i.se & 0x7fff) == 0) - FORCE_EVAL(x*x + ux.f*ux.f); - return ux.f; -} -#endif diff --git a/waterbox/libc/functions/math/nexttoward.c b/waterbox/libc/functions/math/nexttoward.c deleted file mode 100644 index 827ee5c3c2..0000000000 --- a/waterbox/libc/functions/math/nexttoward.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -double nexttoward(double x, long double y) -{ - return nextafter(x, y); -} -#else -double nexttoward(double x, long double y) -{ - union {double f; uint64_t i;} ux = {x}; - int e; - - if (isnan(x) || isnan(y)) - return x + y; - if (x == y) - return y; - if (x == 0) { - ux.i = 1; - if (signbit(y)) - ux.i |= 1ULL<<63; - } else if (x < y) { - if (signbit(x)) - ux.i--; - else - ux.i++; - } else { - if (signbit(x)) - ux.i++; - else - ux.i--; - } - e = ux.i>>52 & 0x7ff; - /* raise overflow if ux.f is infinite and x is finite */ - if (e == 0x7ff) - FORCE_EVAL(x+x); - /* raise underflow if ux.f is subnormal or zero */ - if (e == 0) - FORCE_EVAL(x*x + ux.f*ux.f); - return ux.f; -} -#endif diff --git a/waterbox/libc/functions/math/nexttowardf.c b/waterbox/libc/functions/math/nexttowardf.c deleted file mode 100644 index bbf172f9e6..0000000000 --- a/waterbox/libc/functions/math/nexttowardf.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "libm.h" - -float nexttowardf(float x, long double y) -{ - union {float f; uint32_t i;} ux = {x}; - uint32_t e; - - if (isnan(x) || isnan(y)) - return x + y; - if (x == y) - return y; - if (x == 0) { - ux.i = 1; - if (signbit(y)) - ux.i |= 0x80000000; - } else if (x < y) { - if (signbit(x)) - ux.i--; - else - ux.i++; - } else { - if (signbit(x)) - ux.i++; - else - ux.i--; - } - e = ux.i & 0x7f800000; - /* raise overflow if ux.f is infinite and x is finite */ - if (e == 0x7f800000) - FORCE_EVAL(x+x); - /* raise underflow if ux.f is subnormal or zero */ - if (e == 0) - FORCE_EVAL(x*x + ux.f*ux.f); - return ux.f; -} diff --git a/waterbox/libc/functions/math/nexttowardl.c b/waterbox/libc/functions/math/nexttowardl.c deleted file mode 100644 index 67a634039f..0000000000 --- a/waterbox/libc/functions/math/nexttowardl.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -long double nexttowardl(long double x, long double y) -{ - return nextafterl(x, y); -} diff --git a/waterbox/libc/functions/math/pow.c b/waterbox/libc/functions/math/pow.c deleted file mode 100644 index b66f632d8e..0000000000 --- a/waterbox/libc/functions/math/pow.c +++ /dev/null @@ -1,328 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_pow.c */ -/* - * ==================================================== - * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. - * - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* pow(x,y) return x**y - * - * n - * Method: Let x = 2 * (1+f) - * 1. Compute and return log2(x) in two pieces: - * log2(x) = w1 + w2, - * where w1 has 53-24 = 29 bit trailing zeros. - * 2. Perform y*log2(x) = n+y' by simulating muti-precision - * arithmetic, where |y'|<=0.5. - * 3. Return x**y = 2**n*exp(y'*log2) - * - * Special cases: - * 1. (anything) ** 0 is 1 - * 2. 1 ** (anything) is 1 - * 3. (anything except 1) ** NAN is NAN - * 4. NAN ** (anything except 0) is NAN - * 5. +-(|x| > 1) ** +INF is +INF - * 6. +-(|x| > 1) ** -INF is +0 - * 7. +-(|x| < 1) ** +INF is +0 - * 8. +-(|x| < 1) ** -INF is +INF - * 9. -1 ** +-INF is 1 - * 10. +0 ** (+anything except 0, NAN) is +0 - * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 - * 12. +0 ** (-anything except 0, NAN) is +INF, raise divbyzero - * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF, raise divbyzero - * 14. -0 ** (+odd integer) is -0 - * 15. -0 ** (-odd integer) is -INF, raise divbyzero - * 16. +INF ** (+anything except 0,NAN) is +INF - * 17. +INF ** (-anything except 0,NAN) is +0 - * 18. -INF ** (+odd integer) is -INF - * 19. -INF ** (anything) = -0 ** (-anything), (anything except odd integer) - * 20. (anything) ** 1 is (anything) - * 21. (anything) ** -1 is 1/(anything) - * 22. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer) - * 23. (-anything except 0 and inf) ** (non-integer) is NAN - * - * Accuracy: - * pow(x,y) returns x**y nearly rounded. In particular - * pow(integer,integer) - * always returns the correct integer provided it is - * representable. - * - * Constants : - * The hexadecimal values are the intended ones for the following - * constants. The decimal values may be used, provided that the - * compiler will convert from decimal to binary accurately enough - * to produce the hexadecimal values shown. - */ - -#include "libm.h" - -static const double -bp[] = {1.0, 1.5,}, -dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */ -dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */ -two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */ -huge = 1.0e300, -tiny = 1.0e-300, -/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ -L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */ -L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */ -L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */ -L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */ -L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */ -L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */ -P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ -P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ -P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ -P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ -P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */ -lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ -lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */ -lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */ -ovt = 8.0085662595372944372e-017, /* -(1024-log2(ovfl+.5ulp)) */ -cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */ -cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */ -cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/ -ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */ -ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ -ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ - -double pow(double x, double y) -{ - double z,ax,z_h,z_l,p_h,p_l; - double y1,t1,t2,r,s,t,u,v,w; - int32_t i,j,k,yisint,n; - int32_t hx,hy,ix,iy; - uint32_t lx,ly; - - EXTRACT_WORDS(hx, lx, x); - EXTRACT_WORDS(hy, ly, y); - ix = hx & 0x7fffffff; - iy = hy & 0x7fffffff; - - /* x**0 = 1, even if x is NaN */ - if ((iy|ly) == 0) - return 1.0; - /* 1**y = 1, even if y is NaN */ - if (hx == 0x3ff00000 && lx == 0) - return 1.0; - /* NaN if either arg is NaN */ - if (ix > 0x7ff00000 || (ix == 0x7ff00000 && lx != 0) || - iy > 0x7ff00000 || (iy == 0x7ff00000 && ly != 0)) - return x + y; - - /* determine if y is an odd int when x < 0 - * yisint = 0 ... y is not an integer - * yisint = 1 ... y is an odd int - * yisint = 2 ... y is an even int - */ - yisint = 0; - if (hx < 0) { - if (iy >= 0x43400000) - yisint = 2; /* even integer y */ - else if (iy >= 0x3ff00000) { - k = (iy>>20) - 0x3ff; /* exponent */ - if (k > 20) { - j = ly>>(52-k); - if ((j<<(52-k)) == ly) - yisint = 2 - (j&1); - } else if (ly == 0) { - j = iy>>(20-k); - if ((j<<(20-k)) == iy) - yisint = 2 - (j&1); - } - } - } - - /* special value of y */ - if (ly == 0) { - if (iy == 0x7ff00000) { /* y is +-inf */ - if (((ix-0x3ff00000)|lx) == 0) /* (-1)**+-inf is 1 */ - return 1.0; - else if (ix >= 0x3ff00000) /* (|x|>1)**+-inf = inf,0 */ - return hy >= 0 ? y : 0.0; - else /* (|x|<1)**+-inf = 0,inf */ - return hy >= 0 ? 0.0 : -y; - } - if (iy == 0x3ff00000) { /* y is +-1 */ - if (hy >= 0) - return x; - y = 1/x; -#if FLT_EVAL_METHOD!=0 - { - union {double f; uint64_t i;} u = {y}; - uint64_t i = u.i & -1ULL/2; - if (i>>52 == 0 && (i&(i-1))) - FORCE_EVAL((float)y); - } -#endif - return y; - } - if (hy == 0x40000000) /* y is 2 */ - return x*x; - if (hy == 0x3fe00000) { /* y is 0.5 */ - if (hx >= 0) /* x >= +0 */ - return sqrt(x); - } - } - - ax = fabs(x); - /* special value of x */ - if (lx == 0) { - if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000) { /* x is +-0,+-inf,+-1 */ - z = ax; - if (hy < 0) /* z = (1/|x|) */ - z = 1.0/z; - if (hx < 0) { - if (((ix-0x3ff00000)|yisint) == 0) { - z = (z-z)/(z-z); /* (-1)**non-int is NaN */ - } else if (yisint == 1) - z = -z; /* (x<0)**odd = -(|x|**odd) */ - } - return z; - } - } - - s = 1.0; /* sign of result */ - if (hx < 0) { - if (yisint == 0) /* (x<0)**(non-int) is NaN */ - return (x-x)/(x-x); - if (yisint == 1) /* (x<0)**(odd int) */ - s = -1.0; - } - - /* |y| is huge */ - if (iy > 0x41e00000) { /* if |y| > 2**31 */ - if (iy > 0x43f00000) { /* if |y| > 2**64, must o/uflow */ - if (ix <= 0x3fefffff) - return hy < 0 ? huge*huge : tiny*tiny; - if (ix >= 0x3ff00000) - return hy > 0 ? huge*huge : tiny*tiny; - } - /* over/underflow if x is not close to one */ - if (ix < 0x3fefffff) - return hy < 0 ? s*huge*huge : s*tiny*tiny; - if (ix > 0x3ff00000) - return hy > 0 ? s*huge*huge : s*tiny*tiny; - /* now |1-x| is tiny <= 2**-20, suffice to compute - log(x) by x-x^2/2+x^3/3-x^4/4 */ - t = ax - 1.0; /* t has 20 trailing zeros */ - w = (t*t)*(0.5 - t*(0.3333333333333333333333-t*0.25)); - u = ivln2_h*t; /* ivln2_h has 21 sig. bits */ - v = t*ivln2_l - w*ivln2; - t1 = u + v; - SET_LOW_WORD(t1, 0); - t2 = v - (t1-u); - } else { - double ss,s2,s_h,s_l,t_h,t_l; - n = 0; - /* take care subnormal number */ - if (ix < 0x00100000) { - ax *= two53; - n -= 53; - GET_HIGH_WORD(ix,ax); - } - n += ((ix)>>20) - 0x3ff; - j = ix & 0x000fffff; - /* determine interval */ - ix = j | 0x3ff00000; /* normalize ix */ - if (j <= 0x3988E) /* |x|>1)|0x20000000) + 0x00080000 + (k<<18)); - t_l = ax - (t_h-bp[k]); - s_l = v*((u-s_h*t_h)-s_h*t_l); - /* compute log(ax) */ - s2 = ss*ss; - r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); - r += s_l*(s_h+ss); - s2 = s_h*s_h; - t_h = 3.0 + s2 + r; - SET_LOW_WORD(t_h, 0); - t_l = r - ((t_h-3.0)-s2); - /* u+v = ss*(1+...) */ - u = s_h*t_h; - v = s_l*t_h + t_l*ss; - /* 2/(3log2)*(ss+...) */ - p_h = u + v; - SET_LOW_WORD(p_h, 0); - p_l = v - (p_h-u); - z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ - z_l = cp_l*p_h+p_l*cp + dp_l[k]; - /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */ - t = (double)n; - t1 = ((z_h + z_l) + dp_h[k]) + t; - SET_LOW_WORD(t1, 0); - t2 = z_l - (((t1 - t) - dp_h[k]) - z_h); - } - - /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ - y1 = y; - SET_LOW_WORD(y1, 0); - p_l = (y-y1)*t1 + y*t2; - p_h = y1*t1; - z = p_l + p_h; - EXTRACT_WORDS(j, i, z); - if (j >= 0x40900000) { /* z >= 1024 */ - if (((j-0x40900000)|i) != 0) /* if z > 1024 */ - return s*huge*huge; /* overflow */ - if (p_l + ovt > z - p_h) - return s*huge*huge; /* overflow */ - } else if ((j&0x7fffffff) >= 0x4090cc00) { /* z <= -1075 */ // FIXME: instead of abs(j) use unsigned j - if (((j-0xc090cc00)|i) != 0) /* z < -1075 */ - return s*tiny*tiny; /* underflow */ - if (p_l <= z - p_h) - return s*tiny*tiny; /* underflow */ - } - /* - * compute 2**(p_h+p_l) - */ - i = j & 0x7fffffff; - k = (i>>20) - 0x3ff; - n = 0; - if (i > 0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */ - n = j + (0x00100000>>(k+1)); - k = ((n&0x7fffffff)>>20) - 0x3ff; /* new k for n */ - t = 0.0; - SET_HIGH_WORD(t, n & ~(0x000fffff>>k)); - n = ((n&0x000fffff)|0x00100000)>>(20-k); - if (j < 0) - n = -n; - p_h -= t; - } - t = p_l + p_h; - SET_LOW_WORD(t, 0); - u = t*lg2_h; - v = (p_l-(t-p_h))*lg2 + t*lg2_l; - z = u + v; - w = v - (z-u); - t = z*z; - t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); - r = (z*t1)/(t1-2.0) - (w + z*w); - z = 1.0 - (r-z); - GET_HIGH_WORD(j, z); - j += n<<20; - if ((j>>20) <= 0) /* subnormal output */ - z = scalbn(z,n); - else - SET_HIGH_WORD(z, j); - return s*z; -} diff --git a/waterbox/libc/functions/math/powf.c b/waterbox/libc/functions/math/powf.c deleted file mode 100644 index 427c8965b9..0000000000 --- a/waterbox/libc/functions/math/powf.c +++ /dev/null @@ -1,259 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_powf.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" - -static const float -bp[] = {1.0, 1.5,}, -dp_h[] = { 0.0, 5.84960938e-01,}, /* 0x3f15c000 */ -dp_l[] = { 0.0, 1.56322085e-06,}, /* 0x35d1cfdc */ -two24 = 16777216.0, /* 0x4b800000 */ -huge = 1.0e30, -tiny = 1.0e-30, -/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ -L1 = 6.0000002384e-01, /* 0x3f19999a */ -L2 = 4.2857143283e-01, /* 0x3edb6db7 */ -L3 = 3.3333334327e-01, /* 0x3eaaaaab */ -L4 = 2.7272811532e-01, /* 0x3e8ba305 */ -L5 = 2.3066075146e-01, /* 0x3e6c3255 */ -L6 = 2.0697501302e-01, /* 0x3e53f142 */ -P1 = 1.6666667163e-01, /* 0x3e2aaaab */ -P2 = -2.7777778450e-03, /* 0xbb360b61 */ -P3 = 6.6137559770e-05, /* 0x388ab355 */ -P4 = -1.6533901999e-06, /* 0xb5ddea0e */ -P5 = 4.1381369442e-08, /* 0x3331bb4c */ -lg2 = 6.9314718246e-01, /* 0x3f317218 */ -lg2_h = 6.93145752e-01, /* 0x3f317200 */ -lg2_l = 1.42860654e-06, /* 0x35bfbe8c */ -ovt = 4.2995665694e-08, /* -(128-log2(ovfl+.5ulp)) */ -cp = 9.6179670095e-01, /* 0x3f76384f =2/(3ln2) */ -cp_h = 9.6191406250e-01, /* 0x3f764000 =12b cp */ -cp_l = -1.1736857402e-04, /* 0xb8f623c6 =tail of cp_h */ -ivln2 = 1.4426950216e+00, /* 0x3fb8aa3b =1/ln2 */ -ivln2_h = 1.4426879883e+00, /* 0x3fb8aa00 =16b 1/ln2*/ -ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/ - -float powf(float x, float y) -{ - float z,ax,z_h,z_l,p_h,p_l; - float y1,t1,t2,r,s,sn,t,u,v,w; - int32_t i,j,k,yisint,n; - int32_t hx,hy,ix,iy,is; - - GET_FLOAT_WORD(hx, x); - GET_FLOAT_WORD(hy, y); - ix = hx & 0x7fffffff; - iy = hy & 0x7fffffff; - - /* x**0 = 1, even if x is NaN */ - if (iy == 0) - return 1.0f; - /* 1**y = 1, even if y is NaN */ - if (hx == 0x3f800000) - return 1.0f; - /* NaN if either arg is NaN */ - if (ix > 0x7f800000 || iy > 0x7f800000) - return x + y; - - /* determine if y is an odd int when x < 0 - * yisint = 0 ... y is not an integer - * yisint = 1 ... y is an odd int - * yisint = 2 ... y is an even int - */ - yisint = 0; - if (hx < 0) { - if (iy >= 0x4b800000) - yisint = 2; /* even integer y */ - else if (iy >= 0x3f800000) { - k = (iy>>23) - 0x7f; /* exponent */ - j = iy>>(23-k); - if ((j<<(23-k)) == iy) - yisint = 2 - (j & 1); - } - } - - /* special value of y */ - if (iy == 0x7f800000) { /* y is +-inf */ - if (ix == 0x3f800000) /* (-1)**+-inf is 1 */ - return 1.0f; - else if (ix > 0x3f800000) /* (|x|>1)**+-inf = inf,0 */ - return hy >= 0 ? y : 0.0f; - else /* (|x|<1)**+-inf = 0,inf */ - return hy >= 0 ? 0.0f: -y; - } - if (iy == 0x3f800000) /* y is +-1 */ - return hy >= 0 ? x : 1.0f/x; - if (hy == 0x40000000) /* y is 2 */ - return x*x; - if (hy == 0x3f000000) { /* y is 0.5 */ - if (hx >= 0) /* x >= +0 */ - return sqrtf(x); - } - - ax = fabsf(x); - /* special value of x */ - if (ix == 0x7f800000 || ix == 0 || ix == 0x3f800000) { /* x is +-0,+-inf,+-1 */ - z = ax; - if (hy < 0) /* z = (1/|x|) */ - z = 1.0f/z; - if (hx < 0) { - if (((ix-0x3f800000)|yisint) == 0) { - z = (z-z)/(z-z); /* (-1)**non-int is NaN */ - } else if (yisint == 1) - z = -z; /* (x<0)**odd = -(|x|**odd) */ - } - return z; - } - - sn = 1.0f; /* sign of result */ - if (hx < 0) { - if (yisint == 0) /* (x<0)**(non-int) is NaN */ - return (x-x)/(x-x); - if (yisint == 1) /* (x<0)**(odd int) */ - sn = -1.0f; - } - - /* |y| is huge */ - if (iy > 0x4d000000) { /* if |y| > 2**27 */ - /* over/underflow if x is not close to one */ - if (ix < 0x3f7ffff8) - return hy < 0 ? sn*huge*huge : sn*tiny*tiny; - if (ix > 0x3f800007) - return hy > 0 ? sn*huge*huge : sn*tiny*tiny; - /* now |1-x| is tiny <= 2**-20, suffice to compute - log(x) by x-x^2/2+x^3/3-x^4/4 */ - t = ax - 1; /* t has 20 trailing zeros */ - w = (t*t)*(0.5f - t*(0.333333333333f - t*0.25f)); - u = ivln2_h*t; /* ivln2_h has 16 sig. bits */ - v = t*ivln2_l - w*ivln2; - t1 = u + v; - GET_FLOAT_WORD(is, t1); - SET_FLOAT_WORD(t1, is & 0xfffff000); - t2 = v - (t1-u); - } else { - float s2,s_h,s_l,t_h,t_l; - n = 0; - /* take care subnormal number */ - if (ix < 0x00800000) { - ax *= two24; - n -= 24; - GET_FLOAT_WORD(ix, ax); - } - n += ((ix)>>23) - 0x7f; - j = ix & 0x007fffff; - /* determine interval */ - ix = j | 0x3f800000; /* normalize ix */ - if (j <= 0x1cc471) /* |x|>1) & 0xfffff000) | 0x20000000; - SET_FLOAT_WORD(t_h, is + 0x00400000 + (k<<21)); - t_l = ax - (t_h - bp[k]); - s_l = v*((u - s_h*t_h) - s_h*t_l); - /* compute log(ax) */ - s2 = s*s; - r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); - r += s_l*(s_h+s); - s2 = s_h*s_h; - t_h = 3.0f + s2 + r; - GET_FLOAT_WORD(is, t_h); - SET_FLOAT_WORD(t_h, is & 0xfffff000); - t_l = r - ((t_h - 3.0f) - s2); - /* u+v = s*(1+...) */ - u = s_h*t_h; - v = s_l*t_h + t_l*s; - /* 2/(3log2)*(s+...) */ - p_h = u + v; - GET_FLOAT_WORD(is, p_h); - SET_FLOAT_WORD(p_h, is & 0xfffff000); - p_l = v - (p_h - u); - z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ - z_l = cp_l*p_h + p_l*cp+dp_l[k]; - /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ - t = (float)n; - t1 = (((z_h + z_l) + dp_h[k]) + t); - GET_FLOAT_WORD(is, t1); - SET_FLOAT_WORD(t1, is & 0xfffff000); - t2 = z_l - (((t1 - t) - dp_h[k]) - z_h); - } - - /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ - GET_FLOAT_WORD(is, y); - SET_FLOAT_WORD(y1, is & 0xfffff000); - p_l = (y-y1)*t1 + y*t2; - p_h = y1*t1; - z = p_l + p_h; - GET_FLOAT_WORD(j, z); - if (j > 0x43000000) /* if z > 128 */ - return sn*huge*huge; /* overflow */ - else if (j == 0x43000000) { /* if z == 128 */ - if (p_l + ovt > z - p_h) - return sn*huge*huge; /* overflow */ - } else if ((j&0x7fffffff) > 0x43160000) /* z < -150 */ // FIXME: check should be (uint32_t)j > 0xc3160000 - return sn*tiny*tiny; /* underflow */ - else if (j == 0xc3160000) { /* z == -150 */ - if (p_l <= z-p_h) - return sn*tiny*tiny; /* underflow */ - } - /* - * compute 2**(p_h+p_l) - */ - i = j & 0x7fffffff; - k = (i>>23) - 0x7f; - n = 0; - if (i > 0x3f000000) { /* if |z| > 0.5, set n = [z+0.5] */ - n = j + (0x00800000>>(k+1)); - k = ((n&0x7fffffff)>>23) - 0x7f; /* new k for n */ - SET_FLOAT_WORD(t, n & ~(0x007fffff>>k)); - n = ((n&0x007fffff)|0x00800000)>>(23-k); - if (j < 0) - n = -n; - p_h -= t; - } - t = p_l + p_h; - GET_FLOAT_WORD(is, t); - SET_FLOAT_WORD(t, is & 0xffff8000); - u = t*lg2_h; - v = (p_l-(t-p_h))*lg2 + t*lg2_l; - z = u + v; - w = v - (z - u); - t = z*z; - t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); - r = (z*t1)/(t1-2.0f) - (w+z*w); - z = 1.0f - (r - z); - GET_FLOAT_WORD(j, z); - j += n<<23; - if ((j>>23) <= 0) /* subnormal output */ - z = scalbnf(z, n); - else - SET_FLOAT_WORD(z, j); - return sn*z; -} diff --git a/waterbox/libc/functions/math/powl.c b/waterbox/libc/functions/math/powl.c deleted file mode 100644 index 5b6da07b2e..0000000000 --- a/waterbox/libc/functions/math/powl.c +++ /dev/null @@ -1,522 +0,0 @@ -/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_powl.c */ -/* - * Copyright (c) 2008 Stephen L. Moshier - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/* powl.c - * - * Power function, long double precision - * - * - * SYNOPSIS: - * - * long double x, y, z, powl(); - * - * z = powl( x, y ); - * - * - * DESCRIPTION: - * - * Computes x raised to the yth power. Analytically, - * - * x**y = exp( y log(x) ). - * - * Following Cody and Waite, this program uses a lookup table - * of 2**-i/32 and pseudo extended precision arithmetic to - * obtain several extra bits of accuracy in both the logarithm - * and the exponential. - * - * - * ACCURACY: - * - * The relative error of pow(x,y) can be estimated - * by y dl ln(2), where dl is the absolute error of - * the internally computed base 2 logarithm. At the ends - * of the approximation interval the logarithm equal 1/32 - * and its relative error is about 1 lsb = 1.1e-19. Hence - * the predicted relative error in the result is 2.3e-21 y . - * - * Relative error: - * arithmetic domain # trials peak rms - * - * IEEE +-1000 40000 2.8e-18 3.7e-19 - * .001 < x < 1000, with log(x) uniformly distributed. - * -1000 < y < 1000, y uniformly distributed. - * - * IEEE 0,8700 60000 6.5e-18 1.0e-18 - * 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * pow overflow x**y > MAXNUM INFINITY - * pow underflow x**y < 1/MAXNUM 0.0 - * pow domain x<0 and y noninteger 0.0 - * - */ - -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double powl(long double x, long double y) -{ - return pow(x, y); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 - -/* Table size */ -#define NXT 32 - -/* log(1+x) = x - .5x^2 + x^3 * P(z)/Q(z) - * on the domain 2^(-1/32) - 1 <= x <= 2^(1/32) - 1 - */ -static const long double P[] = { - 8.3319510773868690346226E-4L, - 4.9000050881978028599627E-1L, - 1.7500123722550302671919E0L, - 1.4000100839971580279335E0L, -}; -static const long double Q[] = { -/* 1.0000000000000000000000E0L,*/ - 5.2500282295834889175431E0L, - 8.4000598057587009834666E0L, - 4.2000302519914740834728E0L, -}; -/* A[i] = 2^(-i/32), rounded to IEEE long double precision. - * If i is even, A[i] + B[i/2] gives additional accuracy. - */ -static const long double A[33] = { - 1.0000000000000000000000E0L, - 9.7857206208770013448287E-1L, - 9.5760328069857364691013E-1L, - 9.3708381705514995065011E-1L, - 9.1700404320467123175367E-1L, - 8.9735453750155359320742E-1L, - 8.7812608018664974155474E-1L, - 8.5930964906123895780165E-1L, - 8.4089641525371454301892E-1L, - 8.2287773907698242225554E-1L, - 8.0524516597462715409607E-1L, - 7.8799042255394324325455E-1L, - 7.7110541270397041179298E-1L, - 7.5458221379671136985669E-1L, - 7.3841307296974965571198E-1L, - 7.2259040348852331001267E-1L, - 7.0710678118654752438189E-1L, - 6.9195494098191597746178E-1L, - 6.7712777346844636413344E-1L, - 6.6261832157987064729696E-1L, - 6.4841977732550483296079E-1L, - 6.3452547859586661129850E-1L, - 6.2092890603674202431705E-1L, - 6.0762367999023443907803E-1L, - 5.9460355750136053334378E-1L, - 5.8186242938878875689693E-1L, - 5.6939431737834582684856E-1L, - 5.5719337129794626814472E-1L, - 5.4525386633262882960438E-1L, - 5.3357020033841180906486E-1L, - 5.2213689121370692017331E-1L, - 5.1094857432705833910408E-1L, - 5.0000000000000000000000E-1L, -}; -static const long double B[17] = { - 0.0000000000000000000000E0L, - 2.6176170809902549338711E-20L, --1.0126791927256478897086E-20L, - 1.3438228172316276937655E-21L, - 1.2207982955417546912101E-20L, --6.3084814358060867200133E-21L, - 1.3164426894366316434230E-20L, --1.8527916071632873716786E-20L, - 1.8950325588932570796551E-20L, - 1.5564775779538780478155E-20L, - 6.0859793637556860974380E-21L, --2.0208749253662532228949E-20L, - 1.4966292219224761844552E-20L, - 3.3540909728056476875639E-21L, --8.6987564101742849540743E-22L, --1.2327176863327626135542E-20L, - 0.0000000000000000000000E0L, -}; - -/* 2^x = 1 + x P(x), - * on the interval -1/32 <= x <= 0 - */ -static const long double R[] = { - 1.5089970579127659901157E-5L, - 1.5402715328927013076125E-4L, - 1.3333556028915671091390E-3L, - 9.6181291046036762031786E-3L, - 5.5504108664798463044015E-2L, - 2.4022650695910062854352E-1L, - 6.9314718055994530931447E-1L, -}; - -#define MEXP (NXT*16384.0L) -/* The following if denormal numbers are supported, else -MEXP: */ -#define MNEXP (-NXT*(16384.0L+64.0L)) -/* log2(e) - 1 */ -#define LOG2EA 0.44269504088896340735992L - -#define F W -#define Fa Wa -#define Fb Wb -#define G W -#define Ga Wa -#define Gb u -#define H W -#define Ha Wb -#define Hb Wb - -static const long double MAXLOGL = 1.1356523406294143949492E4L; -static const long double MINLOGL = -1.13994985314888605586758E4L; -static const long double LOGE2L = 6.9314718055994530941723E-1L; -static const long double huge = 0x1p10000L; -/* XXX Prevent gcc from erroneously constant folding this. */ -static const volatile long double twom10000 = 0x1p-10000L; - -static long double reducl(long double); -static long double powil(long double, int); - -long double powl(long double x, long double y) -{ - /* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */ - int i, nflg, iyflg, yoddint; - long e; - volatile long double z=0; - long double w=0, W=0, Wa=0, Wb=0, ya=0, yb=0, u=0; - - /* make sure no invalid exception is raised by nan comparision */ - if (isnan(x)) { - if (!isnan(y) && y == 0.0) - return 1.0; - return x; - } - if (isnan(y)) { - if (x == 1.0) - return 1.0; - return y; - } - if (x == 1.0) - return 1.0; /* 1**y = 1, even if y is nan */ - if (x == -1.0 && !isfinite(y)) - return 1.0; /* -1**inf = 1 */ - if (y == 0.0) - return 1.0; /* x**0 = 1, even if x is nan */ - if (y == 1.0) - return x; - if (y >= LDBL_MAX) { - if (x > 1.0 || x < -1.0) - return INFINITY; - if (x != 0.0) - return 0.0; - } - if (y <= -LDBL_MAX) { - if (x > 1.0 || x < -1.0) - return 0.0; - if (x != 0.0 || y == -INFINITY) - return INFINITY; - } - if (x >= LDBL_MAX) { - if (y > 0.0) - return INFINITY; - return 0.0; - } - - w = floorl(y); - - /* Set iyflg to 1 if y is an integer. */ - iyflg = 0; - if (w == y) - iyflg = 1; - - /* Test for odd integer y. */ - yoddint = 0; - if (iyflg) { - ya = fabsl(y); - ya = floorl(0.5 * ya); - yb = 0.5 * fabsl(w); - if( ya != yb ) - yoddint = 1; - } - - if (x <= -LDBL_MAX) { - if (y > 0.0) { - if (yoddint) - return -INFINITY; - return INFINITY; - } - if (y < 0.0) { - if (yoddint) - return -0.0; - return 0.0; - } - } - nflg = 0; /* (x<0)**(odd int) */ - if (x <= 0.0) { - if (x == 0.0) { - if (y < 0.0) { - if (signbit(x) && yoddint) - /* (-0.0)**(-odd int) = -inf, divbyzero */ - return -1.0/0.0; - /* (+-0.0)**(negative) = inf, divbyzero */ - return 1.0/0.0; - } - if (signbit(x) && yoddint) - return -0.0; - return 0.0; - } - if (iyflg == 0) - return (x - x) / (x - x); /* (x<0)**(non-int) is NaN */ - /* (x<0)**(integer) */ - if (yoddint) - nflg = 1; /* negate result */ - x = -x; - } - /* (+integer)**(integer) */ - if (iyflg && floorl(x) == x && fabsl(y) < 32768.0) { - w = powil(x, (int)y); - return nflg ? -w : w; - } - - /* separate significand from exponent */ - x = frexpl(x, &i); - e = i; - - /* find significand in antilog table A[] */ - i = 1; - if (x <= A[17]) - i = 17; - if (x <= A[i+8]) - i += 8; - if (x <= A[i+4]) - i += 4; - if (x <= A[i+2]) - i += 2; - if (x >= A[1]) - i = -1; - i += 1; - - /* Find (x - A[i])/A[i] - * in order to compute log(x/A[i]): - * - * log(x) = log( a x/a ) = log(a) + log(x/a) - * - * log(x/a) = log(1+v), v = x/a - 1 = (x-a)/a - */ - x -= A[i]; - x -= B[i/2]; - x /= A[i]; - - /* rational approximation for log(1+v): - * - * log(1+v) = v - v**2/2 + v**3 P(v) / Q(v) - */ - z = x*x; - w = x * (z * __polevll(x, P, 3) / __p1evll(x, Q, 3)); - w = w - 0.5*z; - - /* Convert to base 2 logarithm: - * multiply by log2(e) = 1 + LOG2EA - */ - z = LOG2EA * w; - z += w; - z += LOG2EA * x; - z += x; - - /* Compute exponent term of the base 2 logarithm. */ - w = -i; - w /= NXT; - w += e; - /* Now base 2 log of x is w + z. */ - - /* Multiply base 2 log by y, in extended precision. */ - - /* separate y into large part ya - * and small part yb less than 1/NXT - */ - ya = reducl(y); - yb = y - ya; - - /* (w+z)(ya+yb) - * = w*ya + w*yb + z*y - */ - F = z * y + w * yb; - Fa = reducl(F); - Fb = F - Fa; - - G = Fa + w * ya; - Ga = reducl(G); - Gb = G - Ga; - - H = Fb + Gb; - Ha = reducl(H); - w = (Ga + Ha) * NXT; - - /* Test the power of 2 for overflow */ - if (w > MEXP) - return huge * huge; /* overflow */ - if (w < MNEXP) - return twom10000 * twom10000; /* underflow */ - - e = w; - Hb = H - Ha; - - if (Hb > 0.0) { - e += 1; - Hb -= 1.0/NXT; /*0.0625L;*/ - } - - /* Now the product y * log2(x) = Hb + e/NXT. - * - * Compute base 2 exponential of Hb, - * where -0.0625 <= Hb <= 0. - */ - z = Hb * __polevll(Hb, R, 6); /* z = 2**Hb - 1 */ - - /* Express e/NXT as an integer plus a negative number of (1/NXT)ths. - * Find lookup table entry for the fractional power of 2. - */ - if (e < 0) - i = 0; - else - i = 1; - i = e/NXT + i; - e = NXT*i - e; - w = A[e]; - z = w * z; /* 2**-e * ( 1 + (2**Hb-1) ) */ - z = z + w; - z = scalbnl(z, i); /* multiply by integer power of 2 */ - - if (nflg) - z = -z; - return z; -} - - -/* Find a multiple of 1/NXT that is within 1/NXT of x. */ -static long double reducl(long double x) -{ - long double t; - - t = x * NXT; - t = floorl(t); - t = t / NXT; - return t; -} - -/* - * Positive real raised to integer power, long double precision - * - * - * SYNOPSIS: - * - * long double x, y, powil(); - * int n; - * - * y = powil( x, n ); - * - * - * DESCRIPTION: - * - * Returns argument x>0 raised to the nth power. - * The routine efficiently decomposes n as a sum of powers of - * two. The desired power is a product of two-to-the-kth - * powers of x. Thus to compute the 32767 power of x requires - * 28 multiplications instead of 32767 multiplications. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic x domain n domain # trials peak rms - * IEEE .001,1000 -1022,1023 50000 4.3e-17 7.8e-18 - * IEEE 1,2 -1022,1023 20000 3.9e-17 7.6e-18 - * IEEE .99,1.01 0,8700 10000 3.6e-16 7.2e-17 - * - * Returns MAXNUM on overflow, zero on underflow. - */ - -static long double powil(long double x, int nn) -{ - long double ww, y; - long double s; - int n, e, sign, lx; - - if (nn == 0) - return 1.0; - - if (nn < 0) { - sign = -1; - n = -nn; - } else { - sign = 1; - n = nn; - } - - /* Overflow detection */ - - /* Calculate approximate logarithm of answer */ - s = x; - s = frexpl( s, &lx); - e = (lx - 1)*n; - if ((e == 0) || (e > 64) || (e < -64)) { - s = (s - 7.0710678118654752e-1L) / (s + 7.0710678118654752e-1L); - s = (2.9142135623730950L * s - 0.5 + lx) * nn * LOGE2L; - } else { - s = LOGE2L * e; - } - - if (s > MAXLOGL) - return huge * huge; /* overflow */ - - if (s < MINLOGL) - return twom10000 * twom10000; /* underflow */ - /* Handle tiny denormal answer, but with less accuracy - * since roundoff error in 1.0/x will be amplified. - * The precise demarcation should be the gradual underflow threshold. - */ - if (s < -MAXLOGL+2.0) { - x = 1.0/x; - sign = -sign; - } - - /* First bit of the power */ - if (n & 1) - y = x; - else - y = 1.0; - - ww = x; - n >>= 1; - while (n) { - ww = ww * ww; /* arg to the 2-to-the-kth power */ - if (n & 1) /* if that bit is set, then include in product */ - y *= ww; - n >>= 1; - } - - if (sign < 0) - y = 1.0/y; - return y; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -// TODO: broken implementation to make things compile -long double powl(long double x, long double y) -{ - return pow(x, y); -} -#endif diff --git a/waterbox/libc/functions/math/remainder.c b/waterbox/libc/functions/math/remainder.c deleted file mode 100644 index 4521352869..0000000000 --- a/waterbox/libc/functions/math/remainder.c +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include "_alias.h" - -double remainder(double x, double y) -{ - int q; - return remquo(x, y, &q); -} - -weak_alias(remainder, drem); diff --git a/waterbox/libc/functions/math/remainderf.c b/waterbox/libc/functions/math/remainderf.c deleted file mode 100644 index e7bf3ddfc6..0000000000 --- a/waterbox/libc/functions/math/remainderf.c +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include "_alias.h" - -float remainderf(float x, float y) -{ - int q; - return remquof(x, y, &q); -} - -weak_alias(remainderf, dremf); diff --git a/waterbox/libc/functions/math/remainderl.c b/waterbox/libc/functions/math/remainderl.c deleted file mode 100644 index 2a13c1d5af..0000000000 --- a/waterbox/libc/functions/math/remainderl.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double remainderl(long double x, long double y) -{ - return remainder(x, y); -} -#else -long double remainderl(long double x, long double y) -{ - int q; - return remquol(x, y, &q); -} -#endif diff --git a/waterbox/libc/functions/math/remquo.c b/waterbox/libc/functions/math/remquo.c deleted file mode 100644 index 59d5ad57e5..0000000000 --- a/waterbox/libc/functions/math/remquo.c +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include - -double remquo(double x, double y, int *quo) -{ - union {double f; uint64_t i;} ux = {x}, uy = {y}; - int ex = ux.i>>52 & 0x7ff; - int ey = uy.i>>52 & 0x7ff; - int sx = ux.i>>63; - int sy = uy.i>>63; - uint32_t q; - uint64_t i; - uint64_t uxi = ux.i; - - *quo = 0; - if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff) - return (x*y)/(x*y); - if (ux.i<<1 == 0) - return x; - - /* normalize x and y */ - if (!ex) { - for (i = uxi<<12; i>>63 == 0; ex--, i <<= 1); - uxi <<= -ex + 1; - } else { - uxi &= -1ULL >> 12; - uxi |= 1ULL << 52; - } - if (!ey) { - for (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1); - uy.i <<= -ey + 1; - } else { - uy.i &= -1ULL >> 12; - uy.i |= 1ULL << 52; - } - - q = 0; - if (ex < ey) { - if (ex+1 == ey) - goto end; - return x; - } - - /* x mod y */ - for (; ex > ey; ex--) { - i = uxi - uy.i; - if (i >> 63 == 0) { - uxi = i; - q++; - } - uxi <<= 1; - q <<= 1; - } - i = uxi - uy.i; - if (i >> 63 == 0) { - uxi = i; - q++; - } - if (uxi == 0) - ex = -60; - else - for (; uxi>>52 == 0; uxi <<= 1, ex--); -end: - /* scale result and decide between |x| and |x|-|y| */ - if (ex > 0) { - uxi -= 1ULL << 52; - uxi |= (uint64_t)ex << 52; - } else { - uxi >>= -ex + 1; - } - ux.i = uxi; - x = ux.f; - if (sy) - y = -y; - if (ex == ey || (ex+1 == ey && (2*x > y || (2*x == y && q%2)))) { - x -= y; - q++; - } - q &= 0x7fffffff; - *quo = sx^sy ? -(int)q : (int)q; - return sx ? -x : x; -} diff --git a/waterbox/libc/functions/math/remquof.c b/waterbox/libc/functions/math/remquof.c deleted file mode 100644 index 2f41ff706d..0000000000 --- a/waterbox/libc/functions/math/remquof.c +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include - -float remquof(float x, float y, int *quo) -{ - union {float f; uint32_t i;} ux = {x}, uy = {y}; - int ex = ux.i>>23 & 0xff; - int ey = uy.i>>23 & 0xff; - int sx = ux.i>>31; - int sy = uy.i>>31; - uint32_t q; - uint32_t i; - uint32_t uxi = ux.i; - - *quo = 0; - if (uy.i<<1 == 0 || isnan(y) || ex == 0xff) - return (x*y)/(x*y); - if (ux.i<<1 == 0) - return x; - - /* normalize x and y */ - if (!ex) { - for (i = uxi<<9; i>>31 == 0; ex--, i <<= 1); - uxi <<= -ex + 1; - } else { - uxi &= -1U >> 9; - uxi |= 1U << 23; - } - if (!ey) { - for (i = uy.i<<9; i>>31 == 0; ey--, i <<= 1); - uy.i <<= -ey + 1; - } else { - uy.i &= -1U >> 9; - uy.i |= 1U << 23; - } - - q = 0; - if (ex < ey) { - if (ex+1 == ey) - goto end; - return x; - } - - /* x mod y */ - for (; ex > ey; ex--) { - i = uxi - uy.i; - if (i >> 31 == 0) { - uxi = i; - q++; - } - uxi <<= 1; - q <<= 1; - } - i = uxi - uy.i; - if (i >> 31 == 0) { - uxi = i; - q++; - } - if (uxi == 0) - ex = -30; - else - for (; uxi>>23 == 0; uxi <<= 1, ex--); -end: - /* scale result and decide between |x| and |x|-|y| */ - if (ex > 0) { - uxi -= 1U << 23; - uxi |= (uint32_t)ex << 23; - } else { - uxi >>= -ex + 1; - } - ux.i = uxi; - x = ux.f; - if (sy) - y = -y; - if (ex == ey || (ex+1 == ey && (2*x > y || (2*x == y && q%2)))) { - x -= y; - q++; - } - q &= 0x7fffffff; - *quo = sx^sy ? -(int)q : (int)q; - return sx ? -x : x; -} diff --git a/waterbox/libc/functions/math/remquol.c b/waterbox/libc/functions/math/remquol.c deleted file mode 100644 index 9b065c007f..0000000000 --- a/waterbox/libc/functions/math/remquol.c +++ /dev/null @@ -1,124 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double remquol(long double x, long double y, int *quo) -{ - return remquo(x, y, quo); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -long double remquol(long double x, long double y, int *quo) -{ - union ldshape ux = {x}, uy = {y}; - int ex = ux.i.se & 0x7fff; - int ey = uy.i.se & 0x7fff; - int sx = ux.i.se >> 15; - int sy = uy.i.se >> 15; - uint32_t q; - - *quo = 0; - if (y == 0 || isnan(y) || ex == 0x7fff) - return (x*y)/(x*y); - if (x == 0) - return x; - - /* normalize x and y */ - if (!ex) { - ux.i.se = ex; - ux.f *= 0x1p120f; - ex = ux.i.se - 120; - } - if (!ey) { - uy.i.se = ey; - uy.f *= 0x1p120f; - ey = uy.i.se - 120; - } - - q = 0; - if (ex >= ey) { - /* x mod y */ -#if LDBL_MANT_DIG == 64 - uint64_t i, mx, my; - mx = ux.i.m; - my = uy.i.m; - for (; ex > ey; ex--) { - i = mx - my; - if (mx >= my) { - mx = 2*i; - q++; - q <<= 1; - } else if (2*mx < mx) { - mx = 2*mx - my; - q <<= 1; - q++; - } else { - mx = 2*mx; - q <<= 1; - } - } - i = mx - my; - if (mx >= my) { - mx = i; - q++; - } - if (mx == 0) - ex = -120; - else - for (; mx >> 63 == 0; mx *= 2, ex--); - ux.i.m = mx; -#elif LDBL_MANT_DIG == 113 - uint64_t hi, lo, xhi, xlo, yhi, ylo; - xhi = (ux.i2.hi & -1ULL>>16) | 1ULL<<48; - yhi = (uy.i2.hi & -1ULL>>16) | 1ULL<<48; - xlo = ux.i2.lo; - ylo = ux.i2.lo; - for (; ex > ey; ex--) { - hi = xhi - yhi; - lo = xlo - ylo; - if (xlo < ylo) - hi -= 1; - if (hi >> 63 == 0) { - xhi = 2*hi + (lo>>63); - xlo = 2*lo; - q++; - } else { - xhi = 2*xhi + (xlo>>63); - xlo = 2*xlo; - } - q <<= 1; - } - hi = xhi - yhi; - lo = xlo - ylo; - if (xlo < ylo) - hi -= 1; - if (hi >> 63 == 0) { - xhi = hi; - xlo = lo; - q++; - } - if ((xhi|xlo) == 0) - ex = -120; - else - for (; xhi >> 48 == 0; xhi = 2*xhi + (xlo>>63), xlo = 2*xlo, ex--); - ux.i2.hi = xhi; - ux.i2.lo = xlo; -#endif - } - - /* scale result and decide between |x| and |x|-|y| */ - if (ex <= 0) { - ux.i.se = ex + 120; - ux.f *= 0x1p-120f; - } else - ux.i.se = ex; - x = ux.f; - if (sy) - y = -y; - if (ex == ey || (ex+1 == ey && (2*x > y || (2*x == y && q%2)))) { - x -= y; - q++; - } - q &= 0x7fffffff; - *quo = sx^sy ? -(int)q : (int)q; - return sx ? -x : x; -} -#endif diff --git a/waterbox/libc/functions/math/rint.c b/waterbox/libc/functions/math/rint.c deleted file mode 100644 index fbba390e7d..0000000000 --- a/waterbox/libc/functions/math/rint.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include - -#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 -#define EPS DBL_EPSILON -#elif FLT_EVAL_METHOD==2 -#define EPS LDBL_EPSILON -#endif -static const double_t toint = 1/EPS; - -double rint(double x) -{ - union {double f; uint64_t i;} u = {x}; - int e = u.i>>52 & 0x7ff; - int s = u.i>>63; - double_t y; - - if (e >= 0x3ff+52) - return x; - if (s) - y = x - toint + toint; - else - y = x + toint - toint; - if (y == 0) - return s ? -0.0 : 0; - return y; -} diff --git a/waterbox/libc/functions/math/rintf.c b/waterbox/libc/functions/math/rintf.c deleted file mode 100644 index 9047688d24..0000000000 --- a/waterbox/libc/functions/math/rintf.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include - -#if FLT_EVAL_METHOD==0 -#define EPS FLT_EPSILON -#elif FLT_EVAL_METHOD==1 -#define EPS DBL_EPSILON -#elif FLT_EVAL_METHOD==2 -#define EPS LDBL_EPSILON -#endif -static const float_t toint = 1/EPS; - -float rintf(float x) -{ - union {float f; uint32_t i;} u = {x}; - int e = u.i>>23 & 0xff; - int s = u.i>>31; - float_t y; - - if (e >= 0x7f+23) - return x; - if (s) - y = x - toint + toint; - else - y = x + toint - toint; - if (y == 0) - return s ? -0.0f : 0.0f; - return y; -} diff --git a/waterbox/libc/functions/math/rintl.c b/waterbox/libc/functions/math/rintl.c deleted file mode 100644 index 374327db22..0000000000 --- a/waterbox/libc/functions/math/rintl.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double rintl(long double x) -{ - return rint(x); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 - -static const long double toint = 1/LDBL_EPSILON; - -long double rintl(long double x) -{ - union ldshape u = {x}; - int e = u.i.se & 0x7fff; - int s = u.i.se >> 15; - long double y; - - if (e >= 0x3fff+LDBL_MANT_DIG-1) - return x; - if (s) - y = x - toint + toint; - else - y = x + toint - toint; - if (y == 0) - return 0*x; - return y; -} -#endif diff --git a/waterbox/libc/functions/math/round.c b/waterbox/libc/functions/math/round.c deleted file mode 100644 index 130d58d257..0000000000 --- a/waterbox/libc/functions/math/round.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "libm.h" - -#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 -#define EPS DBL_EPSILON -#elif FLT_EVAL_METHOD==2 -#define EPS LDBL_EPSILON -#endif -static const double_t toint = 1/EPS; - -double round(double x) -{ - union {double f; uint64_t i;} u = {x}; - int e = u.i >> 52 & 0x7ff; - double_t y; - - if (e >= 0x3ff+52) - return x; - if (u.i >> 63) - x = -x; - if (e < 0x3ff-1) { - /* raise inexact if x!=0 */ - FORCE_EVAL(x + toint); - return 0*u.f; - } - y = x + toint - toint - x; - if (y > 0.5) - y = y + x - 1; - else if (y <= -0.5) - y = y + x + 1; - else - y = y + x; - if (u.i >> 63) - y = -y; - return y; -} diff --git a/waterbox/libc/functions/math/roundf.c b/waterbox/libc/functions/math/roundf.c deleted file mode 100644 index e8210af562..0000000000 --- a/waterbox/libc/functions/math/roundf.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "libm.h" - -#if FLT_EVAL_METHOD==0 -#define EPS FLT_EPSILON -#elif FLT_EVAL_METHOD==1 -#define EPS DBL_EPSILON -#elif FLT_EVAL_METHOD==2 -#define EPS LDBL_EPSILON -#endif -static const float_t toint = 1/EPS; - -float roundf(float x) -{ - union {float f; uint32_t i;} u = {x}; - int e = u.i >> 23 & 0xff; - float_t y; - - if (e >= 0x7f+23) - return x; - if (u.i >> 31) - x = -x; - if (e < 0x7f-1) { - FORCE_EVAL(x + toint); - return 0*u.f; - } - y = x + toint - toint - x; - if (y > 0.5f) - y = y + x - 1; - else if (y <= -0.5f) - y = y + x + 1; - else - y = y + x; - if (u.i >> 31) - y = -y; - return y; -} diff --git a/waterbox/libc/functions/math/roundl.c b/waterbox/libc/functions/math/roundl.c deleted file mode 100644 index f4ff6820a9..0000000000 --- a/waterbox/libc/functions/math/roundl.c +++ /dev/null @@ -1,37 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double roundl(long double x) -{ - return round(x); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 - -static const long double toint = 1/LDBL_EPSILON; - -long double roundl(long double x) -{ - union ldshape u = {x}; - int e = u.i.se & 0x7fff; - long double y; - - if (e >= 0x3fff+LDBL_MANT_DIG-1) - return x; - if (u.i.se >> 15) - x = -x; - if (e < 0x3fff-1) { - FORCE_EVAL(x + toint); - return 0*u.f; - } - y = x + toint - toint - x; - if (y > 0.5) - y = y + x - 1; - else if (y <= -0.5) - y = y + x + 1; - else - y = y + x; - if (u.i.se >> 15) - y = -y; - return y; -} -#endif diff --git a/waterbox/libc/functions/math/scalb.c b/waterbox/libc/functions/math/scalb.c deleted file mode 100644 index efe69e60cd..0000000000 --- a/waterbox/libc/functions/math/scalb.c +++ /dev/null @@ -1,35 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_scalb.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* - * scalb(x, fn) is provide for - * passing various standard test suite. One - * should use scalbn() instead. - */ - -#define _GNU_SOURCE -#include - -double scalb(double x, double fn) -{ - if (isnan(x) || isnan(fn)) - return x*fn; - if (!isfinite(fn)) { - if (fn > 0.0) - return x*fn; - else - return x/(-fn); - } - if (rint(fn) != fn) return (fn-fn)/(fn-fn); - if ( fn > 65000.0) return scalbn(x, 65000); - if (-fn > 65000.0) return scalbn(x,-65000); - return scalbn(x,(int)fn); -} diff --git a/waterbox/libc/functions/math/scalbf.c b/waterbox/libc/functions/math/scalbf.c deleted file mode 100644 index f44ed5b64a..0000000000 --- a/waterbox/libc/functions/math/scalbf.c +++ /dev/null @@ -1,32 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_scalbf.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#define _GNU_SOURCE -#include - -float scalbf(float x, float fn) -{ - if (isnan(x) || isnan(fn)) return x*fn; - if (!isfinite(fn)) { - if (fn > 0.0f) - return x*fn; - else - return x/(-fn); - } - if (rintf(fn) != fn) return (fn-fn)/(fn-fn); - if ( fn > 65000.0f) return scalbnf(x, 65000); - if (-fn > 65000.0f) return scalbnf(x,-65000); - return scalbnf(x,(int)fn); -} diff --git a/waterbox/libc/functions/math/scalbln.c b/waterbox/libc/functions/math/scalbln.c deleted file mode 100644 index e6f3f195c8..0000000000 --- a/waterbox/libc/functions/math/scalbln.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -double scalbln(double x, long n) -{ - if (n > INT_MAX) - n = INT_MAX; - else if (n < INT_MIN) - n = INT_MIN; - return scalbn(x, n); -} diff --git a/waterbox/libc/functions/math/scalblnf.c b/waterbox/libc/functions/math/scalblnf.c deleted file mode 100644 index d8e8166b10..0000000000 --- a/waterbox/libc/functions/math/scalblnf.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -float scalblnf(float x, long n) -{ - if (n > INT_MAX) - n = INT_MAX; - else if (n < INT_MIN) - n = INT_MIN; - return scalbnf(x, n); -} diff --git a/waterbox/libc/functions/math/scalblnl.c b/waterbox/libc/functions/math/scalblnl.c deleted file mode 100644 index 854c51c4cb..0000000000 --- a/waterbox/libc/functions/math/scalblnl.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include -#include - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double scalblnl(long double x, long n) -{ - return scalbln(x, n); -} -#else -long double scalblnl(long double x, long n) -{ - if (n > INT_MAX) - n = INT_MAX; - else if (n < INT_MIN) - n = INT_MIN; - return scalbnl(x, n); -} -#endif diff --git a/waterbox/libc/functions/math/scalbn.c b/waterbox/libc/functions/math/scalbn.c deleted file mode 100644 index 530e07c79f..0000000000 --- a/waterbox/libc/functions/math/scalbn.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include - -double scalbn(double x, int n) -{ - union {double f; uint64_t i;} u; - double_t y = x; - - if (n > 1023) { - y *= 0x1p1023; - n -= 1023; - if (n > 1023) { - y *= 0x1p1023; - n -= 1023; - if (n > 1023) - n = 1023; - } - } else if (n < -1022) { - y *= 0x1p-1022; - n += 1022; - if (n < -1022) { - y *= 0x1p-1022; - n += 1022; - if (n < -1022) - n = -1022; - } - } - u.i = (uint64_t)(0x3ff+n)<<52; - x = y * u.f; - return x; -} diff --git a/waterbox/libc/functions/math/scalbnf.c b/waterbox/libc/functions/math/scalbnf.c deleted file mode 100644 index 0b62c3c71f..0000000000 --- a/waterbox/libc/functions/math/scalbnf.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include - -float scalbnf(float x, int n) -{ - union {float f; uint32_t i;} u; - float_t y = x; - - if (n > 127) { - y *= 0x1p127f; - n -= 127; - if (n > 127) { - y *= 0x1p127f; - n -= 127; - if (n > 127) - n = 127; - } - } else if (n < -126) { - y *= 0x1p-126f; - n += 126; - if (n < -126) { - y *= 0x1p-126f; - n += 126; - if (n < -126) - n = -126; - } - } - u.i = (uint32_t)(0x7f+n)<<23; - x = y * u.f; - return x; -} diff --git a/waterbox/libc/functions/math/scalbnl.c b/waterbox/libc/functions/math/scalbnl.c deleted file mode 100644 index 08a4c58754..0000000000 --- a/waterbox/libc/functions/math/scalbnl.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double scalbnl(long double x, int n) -{ - return scalbn(x, n); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -long double scalbnl(long double x, int n) -{ - union ldshape u; - - if (n > 16383) { - x *= 0x1p16383L; - n -= 16383; - if (n > 16383) { - x *= 0x1p16383L; - n -= 16383; - if (n > 16383) - n = 16383; - } - } else if (n < -16382) { - x *= 0x1p-16382L; - n += 16382; - if (n < -16382) { - x *= 0x1p-16382L; - n += 16382; - if (n < -16382) - n = -16382; - } - } - u.f = 1.0; - u.i.se = 0x3fff + n; - return x * u.f; -} -#endif diff --git a/waterbox/libc/functions/math/signgam.c b/waterbox/libc/functions/math/signgam.c deleted file mode 100644 index 267a2b06c7..0000000000 --- a/waterbox/libc/functions/math/signgam.c +++ /dev/null @@ -1,6 +0,0 @@ -#include -#include "_alias.h" - -int __signgam = 0; - -weak_alias(__signgam, signgam); diff --git a/waterbox/libc/functions/math/significand.c b/waterbox/libc/functions/math/significand.c deleted file mode 100644 index 40d9aa9f49..0000000000 --- a/waterbox/libc/functions/math/significand.c +++ /dev/null @@ -1,7 +0,0 @@ -#define _GNU_SOURCE -#include - -double significand(double x) -{ - return scalbn(x, -ilogb(x)); -} diff --git a/waterbox/libc/functions/math/significandf.c b/waterbox/libc/functions/math/significandf.c deleted file mode 100644 index 8a697e1aa2..0000000000 --- a/waterbox/libc/functions/math/significandf.c +++ /dev/null @@ -1,7 +0,0 @@ -#define _GNU_SOURCE -#include - -float significandf(float x) -{ - return scalbnf(x, -ilogbf(x)); -} diff --git a/waterbox/libc/functions/math/sin.c b/waterbox/libc/functions/math/sin.c deleted file mode 100644 index 055e215bc8..0000000000 --- a/waterbox/libc/functions/math/sin.c +++ /dev/null @@ -1,78 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_sin.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* sin(x) - * Return sine function of x. - * - * kernel function: - * __sin ... sine function on [-pi/4,pi/4] - * __cos ... cose function on [-pi/4,pi/4] - * __rem_pio2 ... argument reduction routine - * - * Method. - * Let S,C and T denote the sin, cos and tan respectively on - * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 - * in [-pi/4 , +pi/4], and let n = k mod 4. - * We have - * - * n sin(x) cos(x) tan(x) - * ---------------------------------------------------------- - * 0 S C T - * 1 C -S -1/T - * 2 -S -C T - * 3 -C S -1/T - * ---------------------------------------------------------- - * - * Special cases: - * Let trig be any of sin, cos, or tan. - * trig(+-INF) is NaN, with signals; - * trig(NaN) is that NaN; - * - * Accuracy: - * TRIG(x) returns trig(x) nearly rounded - */ - -#include "libm.h" - -double sin(double x) -{ - double y[2]; - uint32_t ix; - unsigned n; - - /* High word of x. */ - GET_HIGH_WORD(ix, x); - ix &= 0x7fffffff; - - /* |x| ~< pi/4 */ - if (ix <= 0x3fe921fb) { - if (ix < 0x3e500000) { /* |x| < 2**-26 */ - /* raise inexact if x != 0 and underflow if subnormal*/ - FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f); - return x; - } - return __sin(x, 0.0, 0); - } - - /* sin(Inf or NaN) is NaN */ - if (ix >= 0x7ff00000) - return x - x; - - /* argument reduction needed */ - n = __rem_pio2(x, y); - switch (n&3) { - case 0: return __sin(y[0], y[1], 1); - case 1: return __cos(y[0], y[1]); - case 2: return -__sin(y[0], y[1], 1); - default: - return -__cos(y[0], y[1]); - } -} diff --git a/waterbox/libc/functions/math/sincos.c b/waterbox/libc/functions/math/sincos.c deleted file mode 100644 index 35b2d92396..0000000000 --- a/waterbox/libc/functions/math/sincos.c +++ /dev/null @@ -1,69 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_sin.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#define _GNU_SOURCE -#include "libm.h" - -void sincos(double x, double *sin, double *cos) -{ - double y[2], s, c; - uint32_t ix; - unsigned n; - - GET_HIGH_WORD(ix, x); - ix &= 0x7fffffff; - - /* |x| ~< pi/4 */ - if (ix <= 0x3fe921fb) { - /* if |x| < 2**-27 * sqrt(2) */ - if (ix < 0x3e46a09e) { - /* raise inexact if x!=0 and underflow if subnormal */ - FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f); - *sin = x; - *cos = 1.0; - return; - } - *sin = __sin(x, 0.0, 0); - *cos = __cos(x, 0.0); - return; - } - - /* sincos(Inf or NaN) is NaN */ - if (ix >= 0x7ff00000) { - *sin = *cos = x - x; - return; - } - - /* argument reduction needed */ - n = __rem_pio2(x, y); - s = __sin(y[0], y[1], 1); - c = __cos(y[0], y[1]); - switch (n&3) { - case 0: - *sin = s; - *cos = c; - break; - case 1: - *sin = c; - *cos = -s; - break; - case 2: - *sin = -s; - *cos = -c; - break; - case 3: - default: - *sin = -c; - *cos = s; - break; - } -} diff --git a/waterbox/libc/functions/math/sincosf.c b/waterbox/libc/functions/math/sincosf.c deleted file mode 100644 index f8ca7232cf..0000000000 --- a/waterbox/libc/functions/math/sincosf.c +++ /dev/null @@ -1,117 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_sinf.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - * Optimized by Bruce D. Evans. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#define _GNU_SOURCE -#include "libm.h" - -/* Small multiples of pi/2 rounded to double precision. */ -static const double -s1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ -s2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ -s3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ -s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ - -void sincosf(float x, float *sin, float *cos) -{ - double y; - float_t s, c; - uint32_t ix; - unsigned n, sign; - - GET_FLOAT_WORD(ix, x); - sign = ix >> 31; - ix &= 0x7fffffff; - - /* |x| ~<= pi/4 */ - if (ix <= 0x3f490fda) { - /* |x| < 2**-12 */ - if (ix < 0x39800000) { - /* raise inexact if x!=0 and underflow if subnormal */ - FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f); - *sin = x; - *cos = 1.0f; - return; - } - *sin = __sindf(x); - *cos = __cosdf(x); - return; - } - - /* |x| ~<= 5*pi/4 */ - if (ix <= 0x407b53d1) { - if (ix <= 0x4016cbe3) { /* |x| ~<= 3pi/4 */ - if (sign) { - *sin = -__cosdf(x + s1pio2); - *cos = __sindf(x + s1pio2); - } else { - *sin = __cosdf(s1pio2 - x); - *cos = __sindf(s1pio2 - x); - } - return; - } - /* -sin(x+c) is not correct if x+c could be 0: -0 vs +0 */ - *sin = -__sindf(sign ? x + s2pio2 : x - s2pio2); - *cos = -__cosdf(sign ? x + s2pio2 : x - s2pio2); - return; - } - - /* |x| ~<= 9*pi/4 */ - if (ix <= 0x40e231d5) { - if (ix <= 0x40afeddf) { /* |x| ~<= 7*pi/4 */ - if (sign) { - *sin = __cosdf(x + s3pio2); - *cos = -__sindf(x + s3pio2); - } else { - *sin = -__cosdf(x - s3pio2); - *cos = __sindf(x - s3pio2); - } - return; - } - *sin = __sindf(sign ? x + s4pio2 : x - s4pio2); - *cos = __cosdf(sign ? x + s4pio2 : x - s4pio2); - return; - } - - /* sin(Inf or NaN) is NaN */ - if (ix >= 0x7f800000) { - *sin = *cos = x - x; - return; - } - - /* general argument reduction needed */ - n = __rem_pio2f(x, &y); - s = __sindf(y); - c = __cosdf(y); - switch (n&3) { - case 0: - *sin = s; - *cos = c; - break; - case 1: - *sin = c; - *cos = -s; - break; - case 2: - *sin = -s; - *cos = -c; - break; - case 3: - default: - *sin = -c; - *cos = s; - break; - } -} diff --git a/waterbox/libc/functions/math/sincosl.c b/waterbox/libc/functions/math/sincosl.c deleted file mode 100644 index d3ac1c4c8c..0000000000 --- a/waterbox/libc/functions/math/sincosl.c +++ /dev/null @@ -1,60 +0,0 @@ -#define _GNU_SOURCE -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -void sincosl(long double x, long double *sin, long double *cos) -{ - double sind, cosd; - sincos(x, &sind, &cosd); - *sin = sind; - *cos = cosd; -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -void sincosl(long double x, long double *sin, long double *cos) -{ - union ldshape u = {x}; - unsigned n; - long double y[2], s, c; - - u.i.se &= 0x7fff; - if (u.i.se == 0x7fff) { - *sin = *cos = x - x; - return; - } - if (u.f < M_PI_4) { - if (u.i.se < 0x3fff - LDBL_MANT_DIG) { - /* raise underflow if subnormal */ - if (u.i.se == 0) FORCE_EVAL(x*0x1p-120f); - *sin = x; - /* raise inexact if x!=0 */ - *cos = 1.0 + x; - return; - } - *sin = __sinl(x, 0, 0); - *cos = __cosl(x, 0); - return; - } - n = __rem_pio2l(x, y); - s = __sinl(y[0], y[1], 1); - c = __cosl(y[0], y[1]); - switch (n & 3) { - case 0: - *sin = s; - *cos = c; - break; - case 1: - *sin = c; - *cos = -s; - break; - case 2: - *sin = -s; - *cos = -c; - break; - case 3: - default: - *sin = -c; - *cos = s; - break; - } -} -#endif diff --git a/waterbox/libc/functions/math/sinf.c b/waterbox/libc/functions/math/sinf.c deleted file mode 100644 index 64e39f5017..0000000000 --- a/waterbox/libc/functions/math/sinf.c +++ /dev/null @@ -1,76 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_sinf.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - * Optimized by Bruce D. Evans. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" - -/* Small multiples of pi/2 rounded to double precision. */ -static const double -s1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ -s2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ -s3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ -s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ - -float sinf(float x) -{ - double y; - uint32_t ix; - int n, sign; - - GET_FLOAT_WORD(ix, x); - sign = ix >> 31; - ix &= 0x7fffffff; - - if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ - if (ix < 0x39800000) { /* |x| < 2**-12 */ - /* raise inexact if x!=0 and underflow if subnormal */ - FORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f); - return x; - } - return __sindf(x); - } - if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */ - if (ix <= 0x4016cbe3) { /* |x| ~<= 3pi/4 */ - if (sign) - return -__cosdf(x + s1pio2); - else - return __cosdf(x - s1pio2); - } - return __sindf(sign ? -(x + s2pio2) : -(x - s2pio2)); - } - if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */ - if (ix <= 0x40afeddf) { /* |x| ~<= 7*pi/4 */ - if (sign) - return __cosdf(x + s3pio2); - else - return -__cosdf(x - s3pio2); - } - return __sindf(sign ? x + s4pio2 : x - s4pio2); - } - - /* sin(Inf or NaN) is NaN */ - if (ix >= 0x7f800000) - return x - x; - - /* general argument reduction needed */ - n = __rem_pio2f(x, &y); - switch (n&3) { - case 0: return __sindf(y); - case 1: return __cosdf(y); - case 2: return __sindf(-y); - default: - return -__cosdf(y); - } -} diff --git a/waterbox/libc/functions/math/sinh.c b/waterbox/libc/functions/math/sinh.c deleted file mode 100644 index 00022c4e6f..0000000000 --- a/waterbox/libc/functions/math/sinh.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "libm.h" - -/* sinh(x) = (exp(x) - 1/exp(x))/2 - * = (exp(x)-1 + (exp(x)-1)/exp(x))/2 - * = x + x^3/6 + o(x^5) - */ -double sinh(double x) -{ - union {double f; uint64_t i;} u = {.f = x}; - uint32_t w; - double t, h, absx; - - h = 0.5; - if (u.i >> 63) - h = -h; - /* |x| */ - u.i &= (uint64_t)-1/2; - absx = u.f; - w = u.i >> 32; - - /* |x| < log(DBL_MAX) */ - if (w < 0x40862e42) { - t = expm1(absx); - if (w < 0x3ff00000) { - if (w < 0x3ff00000 - (26<<20)) - /* note: inexact and underflow are raised by expm1 */ - /* note: this branch avoids spurious underflow */ - return x; - return h*(2*t - t*t/(t+1)); - } - /* note: |x|>log(0x1p26)+eps could be just h*exp(x) */ - return h*(t + t/(t+1)); - } - - /* |x| > log(DBL_MAX) or nan */ - /* note: the result is stored to handle overflow */ - t = 2*h*__expo2(absx); - return t; -} diff --git a/waterbox/libc/functions/math/sinhf.c b/waterbox/libc/functions/math/sinhf.c deleted file mode 100644 index 6ad19ea2b0..0000000000 --- a/waterbox/libc/functions/math/sinhf.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "libm.h" - -float sinhf(float x) -{ - union {float f; uint32_t i;} u = {.f = x}; - uint32_t w; - float t, h, absx; - - h = 0.5; - if (u.i >> 31) - h = -h; - /* |x| */ - u.i &= 0x7fffffff; - absx = u.f; - w = u.i; - - /* |x| < log(FLT_MAX) */ - if (w < 0x42b17217) { - t = expm1f(absx); - if (w < 0x3f800000) { - if (w < 0x3f800000 - (12<<23)) - return x; - return h*(2*t - t*t/(t+1)); - } - return h*(t + t/(t+1)); - } - - /* |x| > logf(FLT_MAX) or nan */ - t = 2*h*__expo2f(absx); - return t; -} diff --git a/waterbox/libc/functions/math/sinhl.c b/waterbox/libc/functions/math/sinhl.c deleted file mode 100644 index b305d4d2f3..0000000000 --- a/waterbox/libc/functions/math/sinhl.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double sinhl(long double x) -{ - return sinh(x); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -long double sinhl(long double x) -{ - union ldshape u = {x}; - unsigned ex = u.i.se & 0x7fff; - long double h, t, absx; - - h = 0.5; - if (u.i.se & 0x8000) - h = -h; - /* |x| */ - u.i.se = ex; - absx = u.f; - - /* |x| < log(LDBL_MAX) */ - if (ex < 0x3fff+13 || (ex == 0x3fff+13 && u.i.m>>32 < 0xb17217f7)) { - t = expm1l(absx); - if (ex < 0x3fff) { - if (ex < 0x3fff-32) - return x; - return h*(2*t - t*t/(1+t)); - } - return h*(t + t/(t+1)); - } - - /* |x| > log(LDBL_MAX) or nan */ - t = expl(0.5*absx); - return h*t*t; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -// TODO: broken implementation to make things compile -long double sinhl(long double x) -{ - return sinh(x); -} -#endif diff --git a/waterbox/libc/functions/math/sinl.c b/waterbox/libc/functions/math/sinl.c deleted file mode 100644 index 9c0b16eed3..0000000000 --- a/waterbox/libc/functions/math/sinl.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double sinl(long double x) -{ - return sin(x); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -long double sinl(long double x) -{ - union ldshape u = {x}; - unsigned n; - long double y[2], hi, lo; - - u.i.se &= 0x7fff; - if (u.i.se == 0x7fff) - return x - x; - if (u.f < M_PI_4) { - if (u.i.se < 0x3fff - LDBL_MANT_DIG/2) { - /* raise inexact if x!=0 and underflow if subnormal */ - FORCE_EVAL(u.i.se == 0 ? x*0x1p-120f : x+0x1p120f); - return x; - } - return __sinl(x, 0.0, 0); - } - n = __rem_pio2l(x, y); - hi = y[0]; - lo = y[1]; - switch (n & 3) { - case 0: - return __sinl(hi, lo, 1); - case 1: - return __cosl(hi, lo); - case 2: - return -__sinl(hi, lo, 1); - case 3: - default: - return -__cosl(hi, lo); - } -} -#endif diff --git a/waterbox/libc/functions/math/sqrt.c b/waterbox/libc/functions/math/sqrt.c deleted file mode 100644 index b277567385..0000000000 --- a/waterbox/libc/functions/math/sqrt.c +++ /dev/null @@ -1,185 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_sqrt.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* sqrt(x) - * Return correctly rounded sqrt. - * ------------------------------------------ - * | Use the hardware sqrt if you have one | - * ------------------------------------------ - * Method: - * Bit by bit method using integer arithmetic. (Slow, but portable) - * 1. Normalization - * Scale x to y in [1,4) with even powers of 2: - * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then - * sqrt(x) = 2^k * sqrt(y) - * 2. Bit by bit computation - * Let q = sqrt(y) truncated to i bit after binary point (q = 1), - * i 0 - * i+1 2 - * s = 2*q , and y = 2 * ( y - q ). (1) - * i i i i - * - * To compute q from q , one checks whether - * i+1 i - * - * -(i+1) 2 - * (q + 2 ) <= y. (2) - * i - * -(i+1) - * If (2) is false, then q = q ; otherwise q = q + 2 . - * i+1 i i+1 i - * - * With some algebric manipulation, it is not difficult to see - * that (2) is equivalent to - * -(i+1) - * s + 2 <= y (3) - * i i - * - * The advantage of (3) is that s and y can be computed by - * i i - * the following recurrence formula: - * if (3) is false - * - * s = s , y = y ; (4) - * i+1 i i+1 i - * - * otherwise, - * -i -(i+1) - * s = s + 2 , y = y - s - 2 (5) - * i+1 i i+1 i i - * - * One may easily use induction to prove (4) and (5). - * Note. Since the left hand side of (3) contain only i+2 bits, - * it does not necessary to do a full (53-bit) comparison - * in (3). - * 3. Final rounding - * After generating the 53 bits result, we compute one more bit. - * Together with the remainder, we can decide whether the - * result is exact, bigger than 1/2ulp, or less than 1/2ulp - * (it will never equal to 1/2ulp). - * The rounding mode can be detected by checking whether - * huge + tiny is equal to huge, and whether huge - tiny is - * equal to huge for some floating point number "huge" and "tiny". - * - * Special cases: - * sqrt(+-0) = +-0 ... exact - * sqrt(inf) = inf - * sqrt(-ve) = NaN ... with invalid signal - * sqrt(NaN) = NaN ... with invalid signal for signaling NaN - */ - -#include "libm.h" - -static const double tiny = 1.0e-300; - -double sqrt(double x) -{ - double z; - int32_t sign = (int)0x80000000; - int32_t ix0,s0,q,m,t,i; - uint32_t r,t1,s1,ix1,q1; - - EXTRACT_WORDS(ix0, ix1, x); - - /* take care of Inf and NaN */ - if ((ix0&0x7ff00000) == 0x7ff00000) { - return x*x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */ - } - /* take care of zero */ - if (ix0 <= 0) { - if (((ix0&~sign)|ix1) == 0) - return x; /* sqrt(+-0) = +-0 */ - if (ix0 < 0) - return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ - } - /* normalize x */ - m = ix0>>20; - if (m == 0) { /* subnormal x */ - while (ix0 == 0) { - m -= 21; - ix0 |= (ix1>>11); - ix1 <<= 21; - } - for (i=0; (ix0&0x00100000) == 0; i++) - ix0<<=1; - m -= i - 1; - ix0 |= ix1>>(32-i); - ix1 <<= i; - } - m -= 1023; /* unbias exponent */ - ix0 = (ix0&0x000fffff)|0x00100000; - if (m & 1) { /* odd m, double x to make it even */ - ix0 += ix0 + ((ix1&sign)>>31); - ix1 += ix1; - } - m >>= 1; /* m = [m/2] */ - - /* generate sqrt(x) bit by bit */ - ix0 += ix0 + ((ix1&sign)>>31); - ix1 += ix1; - q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */ - r = 0x00200000; /* r = moving bit from right to left */ - - while (r != 0) { - t = s0 + r; - if (t <= ix0) { - s0 = t + r; - ix0 -= t; - q += r; - } - ix0 += ix0 + ((ix1&sign)>>31); - ix1 += ix1; - r >>= 1; - } - - r = sign; - while (r != 0) { - t1 = s1 + r; - t = s0; - if (t < ix0 || (t == ix0 && t1 <= ix1)) { - s1 = t1 + r; - if ((t1&sign) == sign && (s1&sign) == 0) - s0++; - ix0 -= t; - if (ix1 < t1) - ix0--; - ix1 -= t1; - q1 += r; - } - ix0 += ix0 + ((ix1&sign)>>31); - ix1 += ix1; - r >>= 1; - } - - /* use floating add to find out rounding direction */ - if ((ix0|ix1) != 0) { - z = 1.0 - tiny; /* raise inexact flag */ - if (z >= 1.0) { - z = 1.0 + tiny; - if (q1 == (uint32_t)0xffffffff) { - q1 = 0; - q++; - } else if (z > 1.0) { - if (q1 == (uint32_t)0xfffffffe) - q++; - q1 += 2; - } else - q1 += q1 & 1; - } - } - ix0 = (q>>1) + 0x3fe00000; - ix1 = q1>>1; - if (q&1) - ix1 |= sign; - ix0 += m << 20; - INSERT_WORDS(z, ix0, ix1); - return z; -} diff --git a/waterbox/libc/functions/math/sqrtf.c b/waterbox/libc/functions/math/sqrtf.c deleted file mode 100644 index 28cb4ad371..0000000000 --- a/waterbox/libc/functions/math/sqrtf.c +++ /dev/null @@ -1,84 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_sqrtf.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" - -static const float tiny = 1.0e-30; - -float sqrtf(float x) -{ - float z; - int32_t sign = (int)0x80000000; - int32_t ix,s,q,m,t,i; - uint32_t r; - - GET_FLOAT_WORD(ix, x); - - /* take care of Inf and NaN */ - if ((ix&0x7f800000) == 0x7f800000) - return x*x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */ - - /* take care of zero */ - if (ix <= 0) { - if ((ix&~sign) == 0) - return x; /* sqrt(+-0) = +-0 */ - if (ix < 0) - return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ - } - /* normalize x */ - m = ix>>23; - if (m == 0) { /* subnormal x */ - for (i = 0; (ix&0x00800000) == 0; i++) - ix<<=1; - m -= i - 1; - } - m -= 127; /* unbias exponent */ - ix = (ix&0x007fffff)|0x00800000; - if (m&1) /* odd m, double x to make it even */ - ix += ix; - m >>= 1; /* m = [m/2] */ - - /* generate sqrt(x) bit by bit */ - ix += ix; - q = s = 0; /* q = sqrt(x) */ - r = 0x01000000; /* r = moving bit from right to left */ - - while (r != 0) { - t = s + r; - if (t <= ix) { - s = t+r; - ix -= t; - q += r; - } - ix += ix; - r >>= 1; - } - - /* use floating add to find out rounding direction */ - if (ix != 0) { - z = 1.0f - tiny; /* raise inexact flag */ - if (z >= 1.0f) { - z = 1.0f + tiny; - if (z > 1.0f) - q += 2; - else - q += q & 1; - } - } - ix = (q>>1) + 0x3f000000; - ix += m << 23; - SET_FLOAT_WORD(z, ix); - return z; -} diff --git a/waterbox/libc/functions/math/sqrtl.c b/waterbox/libc/functions/math/sqrtl.c deleted file mode 100644 index 83a8f80c99..0000000000 --- a/waterbox/libc/functions/math/sqrtl.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -long double sqrtl(long double x) -{ - /* FIXME: implement in C, this is for LDBL_MANT_DIG == 64 only */ - return sqrt(x); -} diff --git a/waterbox/libc/functions/math/tan.c b/waterbox/libc/functions/math/tan.c deleted file mode 100644 index 9c724a45af..0000000000 --- a/waterbox/libc/functions/math/tan.c +++ /dev/null @@ -1,70 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_tan.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* tan(x) - * Return tangent function of x. - * - * kernel function: - * __tan ... tangent function on [-pi/4,pi/4] - * __rem_pio2 ... argument reduction routine - * - * Method. - * Let S,C and T denote the sin, cos and tan respectively on - * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 - * in [-pi/4 , +pi/4], and let n = k mod 4. - * We have - * - * n sin(x) cos(x) tan(x) - * ---------------------------------------------------------- - * 0 S C T - * 1 C -S -1/T - * 2 -S -C T - * 3 -C S -1/T - * ---------------------------------------------------------- - * - * Special cases: - * Let trig be any of sin, cos, or tan. - * trig(+-INF) is NaN, with signals; - * trig(NaN) is that NaN; - * - * Accuracy: - * TRIG(x) returns trig(x) nearly rounded - */ - -#include "libm.h" - -double tan(double x) -{ - double y[2]; - uint32_t ix; - unsigned n; - - GET_HIGH_WORD(ix, x); - ix &= 0x7fffffff; - - /* |x| ~< pi/4 */ - if (ix <= 0x3fe921fb) { - if (ix < 0x3e400000) { /* |x| < 2**-27 */ - /* raise inexact if x!=0 and underflow if subnormal */ - FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f); - return x; - } - return __tan(x, 0.0, 0); - } - - /* tan(Inf or NaN) is NaN */ - if (ix >= 0x7ff00000) - return x - x; - - /* argument reduction */ - n = __rem_pio2(x, y); - return __tan(y[0], y[1], n&1); -} diff --git a/waterbox/libc/functions/math/tanf.c b/waterbox/libc/functions/math/tanf.c deleted file mode 100644 index aba197777d..0000000000 --- a/waterbox/libc/functions/math/tanf.c +++ /dev/null @@ -1,64 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_tanf.c */ -/* - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - * Optimized by Bruce D. Evans. - */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "libm.h" - -/* Small multiples of pi/2 rounded to double precision. */ -static const double -t1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ -t2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ -t3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ -t4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ - -float tanf(float x) -{ - double y; - uint32_t ix; - unsigned n, sign; - - GET_FLOAT_WORD(ix, x); - sign = ix >> 31; - ix &= 0x7fffffff; - - if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ - if (ix < 0x39800000) { /* |x| < 2**-12 */ - /* raise inexact if x!=0 and underflow if subnormal */ - FORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f); - return x; - } - return __tandf(x, 0); - } - if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */ - if (ix <= 0x4016cbe3) /* |x| ~<= 3pi/4 */ - return __tandf((sign ? x+t1pio2 : x-t1pio2), 1); - else - return __tandf((sign ? x+t2pio2 : x-t2pio2), 0); - } - if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */ - if (ix <= 0x40afeddf) /* |x| ~<= 7*pi/4 */ - return __tandf((sign ? x+t3pio2 : x-t3pio2), 1); - else - return __tandf((sign ? x+t4pio2 : x-t4pio2), 0); - } - - /* tan(Inf or NaN) is NaN */ - if (ix >= 0x7f800000) - return x - x; - - /* argument reduction */ - n = __rem_pio2f(x, &y); - return __tandf(y, n&1); -} diff --git a/waterbox/libc/functions/math/tanh.c b/waterbox/libc/functions/math/tanh.c deleted file mode 100644 index 20d6dbcf41..0000000000 --- a/waterbox/libc/functions/math/tanh.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "libm.h" - -/* tanh(x) = (exp(x) - exp(-x))/(exp(x) + exp(-x)) - * = (exp(2*x) - 1)/(exp(2*x) - 1 + 2) - * = (1 - exp(-2*x))/(exp(-2*x) - 1 + 2) - */ -double tanh(double x) -{ - union {double f; uint64_t i;} u = {.f = x}; - uint32_t w; - int sign; - double_t t; - - /* x = |x| */ - sign = u.i >> 63; - u.i &= (uint64_t)-1/2; - x = u.f; - w = u.i >> 32; - - if (w > 0x3fe193ea) { - /* |x| > log(3)/2 ~= 0.5493 or nan */ - if (w > 0x40340000) { - /* |x| > 20 or nan */ - /* note: this branch avoids raising overflow */ - t = 1 - 0/x; - } else { - t = expm1(2*x); - t = 1 - 2/(t+2); - } - } else if (w > 0x3fd058ae) { - /* |x| > log(5/3)/2 ~= 0.2554 */ - t = expm1(2*x); - t = t/(t+2); - } else if (w >= 0x00100000) { - /* |x| >= 0x1p-1022, up to 2ulp error in [0.1,0.2554] */ - t = expm1(-2*x); - t = -t/(t+2); - } else { - /* |x| is subnormal */ - /* note: the branch above would not raise underflow in [0x1p-1023,0x1p-1022) */ - FORCE_EVAL((float)x); - t = x; - } - return sign ? -t : t; -} diff --git a/waterbox/libc/functions/math/tanhf.c b/waterbox/libc/functions/math/tanhf.c deleted file mode 100644 index 10636fbd7b..0000000000 --- a/waterbox/libc/functions/math/tanhf.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "libm.h" - -float tanhf(float x) -{ - union {float f; uint32_t i;} u = {.f = x}; - uint32_t w; - int sign; - float t; - - /* x = |x| */ - sign = u.i >> 31; - u.i &= 0x7fffffff; - x = u.f; - w = u.i; - - if (w > 0x3f0c9f54) { - /* |x| > log(3)/2 ~= 0.5493 or nan */ - if (w > 0x41200000) { - /* |x| > 10 */ - t = 1 + 0/x; - } else { - t = expm1f(2*x); - t = 1 - 2/(t+2); - } - } else if (w > 0x3e82c578) { - /* |x| > log(5/3)/2 ~= 0.2554 */ - t = expm1f(2*x); - t = t/(t+2); - } else if (w >= 0x00800000) { - /* |x| >= 0x1p-126 */ - t = expm1f(-2*x); - t = -t/(t+2); - } else { - /* |x| is subnormal */ - FORCE_EVAL(x*x); - t = x; - } - return sign ? -t : t; -} diff --git a/waterbox/libc/functions/math/tanhl.c b/waterbox/libc/functions/math/tanhl.c deleted file mode 100644 index 4e1aa9f87d..0000000000 --- a/waterbox/libc/functions/math/tanhl.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double tanhl(long double x) -{ - return tanh(x); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -long double tanhl(long double x) -{ - union ldshape u = {x}; - unsigned ex = u.i.se & 0x7fff; - unsigned sign = u.i.se & 0x8000; - uint32_t w; - long double t; - - /* x = |x| */ - u.i.se = ex; - x = u.f; - w = u.i.m >> 32; - - if (ex > 0x3ffe || (ex == 0x3ffe && w > 0x8c9f53d5)) { - /* |x| > log(3)/2 ~= 0.5493 or nan */ - if (ex >= 0x3fff+5) { - /* |x| >= 32 */ - t = 1 + 0/(x + 0x1p-120f); - } else { - t = expm1l(2*x); - t = 1 - 2/(t+2); - } - } else if (ex > 0x3ffd || (ex == 0x3ffd && w > 0x82c577d4)) { - /* |x| > log(5/3)/2 ~= 0.2554 */ - t = expm1l(2*x); - t = t/(t+2); - } else { - /* |x| is small */ - t = expm1l(-2*x); - t = -t/(t+2); - } - return sign ? -t : t; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -// TODO: broken implementation to make things compile -long double tanhl(long double x) -{ - return tanh(x); -} -#endif diff --git a/waterbox/libc/functions/math/tanl.c b/waterbox/libc/functions/math/tanl.c deleted file mode 100644 index 6af067127a..0000000000 --- a/waterbox/libc/functions/math/tanl.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double tanl(long double x) -{ - return tan(x); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -long double tanl(long double x) -{ - union ldshape u = {x}; - long double y[2]; - unsigned n; - - u.i.se &= 0x7fff; - if (u.i.se == 0x7fff) - return x - x; - if (u.f < M_PI_4) { - if (u.i.se < 0x3fff - LDBL_MANT_DIG/2) { - /* raise inexact if x!=0 and underflow if subnormal */ - FORCE_EVAL(u.i.se == 0 ? x*0x1p-120f : x+0x1p120f); - return x; - } - return __tanl(x, 0, 0); - } - n = __rem_pio2l(x, y); - return __tanl(y[0], y[1], n&1); -} -#endif diff --git a/waterbox/libc/functions/math/tgamma.c b/waterbox/libc/functions/math/tgamma.c deleted file mode 100644 index 28f6e0f832..0000000000 --- a/waterbox/libc/functions/math/tgamma.c +++ /dev/null @@ -1,222 +0,0 @@ -/* -"A Precision Approximation of the Gamma Function" - Cornelius Lanczos (1964) -"Lanczos Implementation of the Gamma Function" - Paul Godfrey (2001) -"An Analysis of the Lanczos Gamma Approximation" - Glendon Ralph Pugh (2004) - -approximation method: - - (x - 0.5) S(x) -Gamma(x) = (x + g - 0.5) * ---------------- - exp(x + g - 0.5) - -with - a1 a2 a3 aN -S(x) ~= [ a0 + ----- + ----- + ----- + ... + ----- ] - x + 1 x + 2 x + 3 x + N - -with a0, a1, a2, a3,.. aN constants which depend on g. - -for x < 0 the following reflection formula is used: - -Gamma(x)*Gamma(-x) = -pi/(x sin(pi x)) - -most ideas and constants are from boost and python -*/ -#include "libm.h" - -static const double pi = 3.141592653589793238462643383279502884; - -/* sin(pi x) with x > 0x1p-100, if sin(pi*x)==0 the sign is arbitrary */ -static double sinpi(double x) -{ - int n; - - /* argument reduction: x = |x| mod 2 */ - /* spurious inexact when x is odd int */ - x = x * 0.5; - x = 2 * (x - floor(x)); - - /* reduce x into [-.25,.25] */ - n = 4 * x; - n = (n+1)/2; - x -= n * 0.5; - - x *= pi; - switch (n) { - default: /* case 4 */ - case 0: - return __sin(x, 0, 0); - case 1: - return __cos(x, 0); - case 2: - return __sin(-x, 0, 0); - case 3: - return -__cos(x, 0); - } -} - -#define N 12 -//static const double g = 6.024680040776729583740234375; -static const double gmhalf = 5.524680040776729583740234375; -static const double Snum[N+1] = { - 23531376880.410759688572007674451636754734846804940, - 42919803642.649098768957899047001988850926355848959, - 35711959237.355668049440185451547166705960488635843, - 17921034426.037209699919755754458931112671403265390, - 6039542586.3520280050642916443072979210699388420708, - 1439720407.3117216736632230727949123939715485786772, - 248874557.86205415651146038641322942321632125127801, - 31426415.585400194380614231628318205362874684987640, - 2876370.6289353724412254090516208496135991145378768, - 186056.26539522349504029498971604569928220784236328, - 8071.6720023658162106380029022722506138218516325024, - 210.82427775157934587250973392071336271166969580291, - 2.5066282746310002701649081771338373386264310793408, -}; -static const double Sden[N+1] = { - 0, 39916800, 120543840, 150917976, 105258076, 45995730, 13339535, - 2637558, 357423, 32670, 1925, 66, 1, -}; -/* n! for small integer n */ -static const double fact[] = { - 1, 1, 2, 6, 24, 120, 720, 5040.0, 40320.0, 362880.0, 3628800.0, 39916800.0, - 479001600.0, 6227020800.0, 87178291200.0, 1307674368000.0, 20922789888000.0, - 355687428096000.0, 6402373705728000.0, 121645100408832000.0, - 2432902008176640000.0, 51090942171709440000.0, 1124000727777607680000.0, -}; - -/* S(x) rational function for positive x */ -static double S(double x) -{ - double_t num = 0, den = 0; - int i; - - /* to avoid overflow handle large x differently */ - if (x < 8) - for (i = N; i >= 0; i--) { - num = num * x + Snum[i]; - den = den * x + Sden[i]; - } - else - for (i = 0; i <= N; i++) { - num = num / x + Snum[i]; - den = den / x + Sden[i]; - } - return num/den; -} - -double tgamma(double x) -{ - union {double f; uint64_t i;} u = {x}; - double absx, y; - double_t dy, z, r; - uint32_t ix = u.i>>32 & 0x7fffffff; - int sign = u.i>>63; - - /* special cases */ - if (ix >= 0x7ff00000) - /* tgamma(nan)=nan, tgamma(inf)=inf, tgamma(-inf)=nan with invalid */ - return x + INFINITY; - if (ix < (0x3ff-54)<<20) - /* |x| < 2^-54: tgamma(x) ~ 1/x, +-0 raises div-by-zero */ - return 1/x; - - /* integer arguments */ - /* raise inexact when non-integer */ - if (x == floor(x)) { - if (sign) - return 0/0.0; - if (x <= sizeof fact/sizeof *fact) - return fact[(int)x - 1]; - } - - /* x >= 172: tgamma(x)=inf with overflow */ - /* x =< -184: tgamma(x)=+-0 with underflow */ - if (ix >= 0x40670000) { /* |x| >= 184 */ - if (sign) { - FORCE_EVAL((float)(0x1p-126/x)); - if (floor(x) * 0.5 == floor(x * 0.5)) - return 0; - return -0.0; - } - x *= 0x1p1023; - return x; - } - - absx = sign ? -x : x; - - /* handle the error of x + g - 0.5 */ - y = absx + gmhalf; - if (absx > gmhalf) { - dy = y - absx; - dy -= gmhalf; - } else { - dy = y - gmhalf; - dy -= absx; - } - - z = absx - 0.5; - r = S(absx) * exp(-y); - if (x < 0) { - /* reflection formula for negative x */ - /* sinpi(absx) is not 0, integers are already handled */ - r = -pi / (sinpi(absx) * absx * r); - dy = -dy; - z = -z; - } - r += dy * (gmhalf+0.5) * r / y; - z = pow(y, 0.5*z); - y = r * z * z; - return y; -} - -#if 0 -double __lgamma_r(double x, int *sign) -{ - double r, absx; - - *sign = 1; - - /* special cases */ - if (!isfinite(x)) - /* lgamma(nan)=nan, lgamma(+-inf)=inf */ - return x*x; - - /* integer arguments */ - if (x == floor(x) && x <= 2) { - /* n <= 0: lgamma(n)=inf with divbyzero */ - /* n == 1,2: lgamma(n)=0 */ - if (x <= 0) - return 1/0.0; - return 0; - } - - absx = fabs(x); - - /* lgamma(x) ~ -log(|x|) for tiny |x| */ - if (absx < 0x1p-54) { - *sign = 1 - 2*!!signbit(x); - return -log(absx); - } - - /* use tgamma for smaller |x| */ - if (absx < 128) { - x = tgamma(x); - *sign = 1 - 2*!!signbit(x); - return log(fabs(x)); - } - - /* second term (log(S)-g) could be more precise here.. */ - /* or with stirling: (|x|-0.5)*(log(|x|)-1) + poly(1/|x|) */ - r = (absx-0.5)*(log(absx+gmhalf)-1) + (log(S(absx)) - (gmhalf+0.5)); - if (x < 0) { - /* reflection formula for negative x */ - x = sinpi(absx); - *sign = 2*!!signbit(x) - 1; - r = log(pi/(fabs(x)*absx)) - r; - } - return r; -} - -weak_alias(__lgamma_r, lgamma_r); -#endif diff --git a/waterbox/libc/functions/math/tgammaf.c b/waterbox/libc/functions/math/tgammaf.c deleted file mode 100644 index b4ca51c9f7..0000000000 --- a/waterbox/libc/functions/math/tgammaf.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -float tgammaf(float x) -{ - return tgamma(x); -} diff --git a/waterbox/libc/functions/math/tgammal.c b/waterbox/libc/functions/math/tgammal.c deleted file mode 100644 index 5336c5b194..0000000000 --- a/waterbox/libc/functions/math/tgammal.c +++ /dev/null @@ -1,281 +0,0 @@ -/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_tgammal.c */ -/* - * Copyright (c) 2008 Stephen L. Moshier - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/* - * Gamma function - * - * - * SYNOPSIS: - * - * long double x, y, tgammal(); - * - * y = tgammal( x ); - * - * - * DESCRIPTION: - * - * Returns gamma function of the argument. The result is - * correctly signed. - * - * Arguments |x| <= 13 are reduced by recurrence and the function - * approximated by a rational function of degree 7/8 in the - * interval (2,3). Large arguments are handled by Stirling's - * formula. Large negative arguments are made positive using - * a reflection formula. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -40,+40 10000 3.6e-19 7.9e-20 - * IEEE -1755,+1755 10000 4.8e-18 6.5e-19 - * - * Accuracy for large arguments is dominated by error in powl(). - * - */ - -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double tgammal(long double x) -{ - return tgamma(x); -} -#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 -/* -tgamma(x+2) = tgamma(x+2) P(x)/Q(x) -0 <= x <= 1 -Relative error -n=7, d=8 -Peak error = 1.83e-20 -Relative error spread = 8.4e-23 -*/ -static const long double P[8] = { - 4.212760487471622013093E-5L, - 4.542931960608009155600E-4L, - 4.092666828394035500949E-3L, - 2.385363243461108252554E-2L, - 1.113062816019361559013E-1L, - 3.629515436640239168939E-1L, - 8.378004301573126728826E-1L, - 1.000000000000000000009E0L, -}; -static const long double Q[9] = { --1.397148517476170440917E-5L, - 2.346584059160635244282E-4L, --1.237799246653152231188E-3L, --7.955933682494738320586E-4L, - 2.773706565840072979165E-2L, --4.633887671244534213831E-2L, --2.243510905670329164562E-1L, - 4.150160950588455434583E-1L, - 9.999999999999999999908E-1L, -}; - -/* -static const long double P[] = { --3.01525602666895735709e0L, --3.25157411956062339893e1L, --2.92929976820724030353e2L, --1.70730828800510297666e3L, --7.96667499622741999770e3L, --2.59780216007146401957e4L, --5.99650230220855581642e4L, --7.15743521530849602425e4L -}; -static const long double Q[] = { - 1.00000000000000000000e0L, --1.67955233807178858919e1L, - 8.85946791747759881659e1L, - 5.69440799097468430177e1L, --1.98526250512761318471e3L, - 3.31667508019495079814e3L, - 1.60577839621734713377e4L, --2.97045081369399940529e4L, --7.15743521530849602412e4L -}; -*/ -#define MAXGAML 1755.455L -/*static const long double LOGPI = 1.14472988584940017414L;*/ - -/* Stirling's formula for the gamma function -tgamma(x) = sqrt(2 pi) x^(x-.5) exp(-x) (1 + 1/x P(1/x)) -z(x) = x -13 <= x <= 1024 -Relative error -n=8, d=0 -Peak error = 9.44e-21 -Relative error spread = 8.8e-4 -*/ -static const long double STIR[9] = { - 7.147391378143610789273E-4L, --2.363848809501759061727E-5L, --5.950237554056330156018E-4L, - 6.989332260623193171870E-5L, - 7.840334842744753003862E-4L, --2.294719747873185405699E-4L, --2.681327161876304418288E-3L, - 3.472222222230075327854E-3L, - 8.333333333333331800504E-2L, -}; - -#define MAXSTIR 1024.0L -static const long double SQTPI = 2.50662827463100050242E0L; - -/* 1/tgamma(x) = z P(z) - * z(x) = 1/x - * 0 < x < 0.03125 - * Peak relative error 4.2e-23 - */ -static const long double S[9] = { --1.193945051381510095614E-3L, - 7.220599478036909672331E-3L, --9.622023360406271645744E-3L, --4.219773360705915470089E-2L, - 1.665386113720805206758E-1L, --4.200263503403344054473E-2L, --6.558780715202540684668E-1L, - 5.772156649015328608253E-1L, - 1.000000000000000000000E0L, -}; - -/* 1/tgamma(-x) = z P(z) - * z(x) = 1/x - * 0 < x < 0.03125 - * Peak relative error 5.16e-23 - * Relative error spread = 2.5e-24 - */ -static const long double SN[9] = { - 1.133374167243894382010E-3L, - 7.220837261893170325704E-3L, - 9.621911155035976733706E-3L, --4.219773343731191721664E-2L, --1.665386113944413519335E-1L, --4.200263503402112910504E-2L, - 6.558780715202536547116E-1L, - 5.772156649015328608727E-1L, --1.000000000000000000000E0L, -}; - -static const long double PIL = 3.1415926535897932384626L; - -/* Gamma function computed by Stirling's formula. - */ -static long double stirf(long double x) -{ - long double y, w, v; - - w = 1.0/x; - /* For large x, use rational coefficients from the analytical expansion. */ - if (x > 1024.0) - w = (((((6.97281375836585777429E-5L * w - + 7.84039221720066627474E-4L) * w - - 2.29472093621399176955E-4L) * w - - 2.68132716049382716049E-3L) * w - + 3.47222222222222222222E-3L) * w - + 8.33333333333333333333E-2L) * w - + 1.0; - else - w = 1.0 + w * __polevll(w, STIR, 8); - y = expl(x); - if (x > MAXSTIR) { /* Avoid overflow in pow() */ - v = powl(x, 0.5L * x - 0.25L); - y = v * (v / y); - } else { - y = powl(x, x - 0.5L) / y; - } - y = SQTPI * y * w; - return y; -} - -long double tgammal(long double x) -{ - long double p, q, z; - - if (!isfinite(x)) - return x + INFINITY; - - q = fabsl(x); - if (q > 13.0) { - if (x < 0.0) { - p = floorl(q); - z = q - p; - if (z == 0) - return 0 / z; - if (q > MAXGAML) { - z = 0; - } else { - if (z > 0.5) { - p += 1.0; - z = q - p; - } - z = q * sinl(PIL * z); - z = fabsl(z) * stirf(q); - z = PIL/z; - } - if (0.5 * p == floorl(q * 0.5)) - z = -z; - } else if (x > MAXGAML) { - z = x * 0x1p16383L; - } else { - z = stirf(x); - } - return z; - } - - z = 1.0; - while (x >= 3.0) { - x -= 1.0; - z *= x; - } - while (x < -0.03125L) { - z /= x; - x += 1.0; - } - if (x <= 0.03125L) - goto small; - while (x < 2.0) { - z /= x; - x += 1.0; - } - if (x == 2.0) - return z; - - x -= 2.0; - p = __polevll(x, P, 7); - q = __polevll(x, Q, 8); - z = z * p / q; - return z; - -small: - /* z==1 if x was originally +-0 */ - if (x == 0 && z != 1) - return x / x; - if (x < 0.0) { - x = -x; - q = z / (x * __polevll(x, SN, 8)); - } else - q = z / (x * __polevll(x, S, 8)); - return q; -} -#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 -// TODO: broken implementation to make things compile -long double tgammal(long double x) -{ - return tgamma(x); -} -#endif diff --git a/waterbox/libc/functions/math/trunc.c b/waterbox/libc/functions/math/trunc.c deleted file mode 100644 index d13711b501..0000000000 --- a/waterbox/libc/functions/math/trunc.c +++ /dev/null @@ -1,19 +0,0 @@ -#include "libm.h" - -double trunc(double x) -{ - union {double f; uint64_t i;} u = {x}; - int e = (int)(u.i >> 52 & 0x7ff) - 0x3ff + 12; - uint64_t m; - - if (e >= 52 + 12) - return x; - if (e < 12) - e = 1; - m = -1ULL >> e; - if ((u.i & m) == 0) - return x; - FORCE_EVAL(x + 0x1p120f); - u.i &= ~m; - return u.f; -} diff --git a/waterbox/libc/functions/math/truncf.c b/waterbox/libc/functions/math/truncf.c deleted file mode 100644 index 1a7d03c3bc..0000000000 --- a/waterbox/libc/functions/math/truncf.c +++ /dev/null @@ -1,19 +0,0 @@ -#include "libm.h" - -float truncf(float x) -{ - union {float f; uint32_t i;} u = {x}; - int e = (int)(u.i >> 23 & 0xff) - 0x7f + 9; - uint32_t m; - - if (e >= 23 + 9) - return x; - if (e < 9) - e = 1; - m = -1U >> e; - if ((u.i & m) == 0) - return x; - FORCE_EVAL(x + 0x1p120f); - u.i &= ~m; - return u.f; -} diff --git a/waterbox/libc/functions/math/truncl.c b/waterbox/libc/functions/math/truncl.c deleted file mode 100644 index f07b193409..0000000000 --- a/waterbox/libc/functions/math/truncl.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "libm.h" - -#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 -long double truncl(long double x) -{ - return trunc(x); -} -#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 - -static const long double toint = 1/LDBL_EPSILON; - -long double truncl(long double x) -{ - union ldshape u = {x}; - int e = u.i.se & 0x7fff; - int s = u.i.se >> 15; - long double y; - - if (e >= 0x3fff+LDBL_MANT_DIG-1) - return x; - if (e <= 0x3fff-1) { - FORCE_EVAL(x + 0x1p120f); - return x*0; - } - /* y = int(|x|) - |x|, where int(|x|) is an integer neighbor of |x| */ - if (s) - x = -x; - y = x + toint - toint - x; - if (y > 0) - y -= 1; - x += y; - return s ? -x : x; -} -#endif diff --git a/waterbox/libc/functions/math/x86_64/__invtrigl.s b/waterbox/libc/functions/math/x86_64/__invtrigl.s deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/waterbox/libc/functions/math/x86_64/acosl.s b/waterbox/libc/functions/math/x86_64/acosl.s deleted file mode 100644 index 88e01b49a2..0000000000 --- a/waterbox/libc/functions/math/x86_64/acosl.s +++ /dev/null @@ -1,16 +0,0 @@ -# see ../i386/acos.s - -.global acosl -.type acosl,@function -acosl: - fldt 8(%rsp) -1: fld %st(0) - fld1 - fsub %st(0),%st(1) - fadd %st(2) - fmulp - fsqrt - fabs - fxch %st(1) - fpatan - ret diff --git a/waterbox/libc/functions/math/x86_64/asinl.s b/waterbox/libc/functions/math/x86_64/asinl.s deleted file mode 100644 index ed212d9a6c..0000000000 --- a/waterbox/libc/functions/math/x86_64/asinl.s +++ /dev/null @@ -1,12 +0,0 @@ -.global asinl -.type asinl,@function -asinl: - fldt 8(%rsp) -1: fld %st(0) - fld1 - fsub %st(0),%st(1) - fadd %st(2) - fmulp - fsqrt - fpatan - ret diff --git a/waterbox/libc/functions/math/x86_64/atan2l.s b/waterbox/libc/functions/math/x86_64/atan2l.s deleted file mode 100644 index e5f0a3deb3..0000000000 --- a/waterbox/libc/functions/math/x86_64/atan2l.s +++ /dev/null @@ -1,7 +0,0 @@ -.global atan2l -.type atan2l,@function -atan2l: - fldt 8(%rsp) - fldt 24(%rsp) - fpatan - ret diff --git a/waterbox/libc/functions/math/x86_64/atanl.s b/waterbox/libc/functions/math/x86_64/atanl.s deleted file mode 100644 index df76de5de4..0000000000 --- a/waterbox/libc/functions/math/x86_64/atanl.s +++ /dev/null @@ -1,7 +0,0 @@ -.global atanl -.type atanl,@function -atanl: - fldt 8(%rsp) - fld1 - fpatan - ret diff --git a/waterbox/libc/functions/math/x86_64/ceill.s b/waterbox/libc/functions/math/x86_64/ceill.s deleted file mode 100644 index f5cfa3b307..0000000000 --- a/waterbox/libc/functions/math/x86_64/ceill.s +++ /dev/null @@ -1 +0,0 @@ -# see floorl.s diff --git a/waterbox/libc/functions/math/x86_64/exp2l.s b/waterbox/libc/functions/math/x86_64/exp2l.s deleted file mode 100644 index effab2bd4e..0000000000 --- a/waterbox/libc/functions/math/x86_64/exp2l.s +++ /dev/null @@ -1,83 +0,0 @@ -.global expm1l -.type expm1l,@function -expm1l: - fldt 8(%rsp) - fldl2e - fmulp - movl $0xc2820000,-4(%rsp) - flds -4(%rsp) - fucomip %st(1),%st - fld1 - jb 1f - # x*log2e <= -65, return -1 without underflow - fstp %st(1) - fchs - ret -1: fld %st(1) - fabs - fucomip %st(1),%st - fstp %st(0) - ja 1f - f2xm1 - ret -1: push %rax - call 1f - pop %rax - fld1 - fsubrp - ret - -.global exp2l -.type exp2l,@function -exp2l: - fldt 8(%rsp) -1: fld %st(0) - sub $16,%rsp - fstpt (%rsp) - mov 8(%rsp),%ax - and $0x7fff,%ax - cmp $0x3fff+13,%ax - jb 4f # |x| < 8192 - cmp $0x3fff+15,%ax - jae 3f # |x| >= 32768 - fsts (%rsp) - cmpl $0xc67ff800,(%rsp) - jb 2f # x > -16382 - movl $0x5f000000,(%rsp) - flds (%rsp) # 0x1p63 - fld %st(1) - fsub %st(1) - faddp - fucomip %st(1),%st - je 2f # x - 0x1p63 + 0x1p63 == x - movl $1,(%rsp) - flds (%rsp) # 0x1p-149 - fdiv %st(1) - fstps (%rsp) # raise underflow -2: fld1 - fld %st(1) - frndint - fxch %st(2) - fsub %st(2) # st(0)=x-rint(x), st(1)=1, st(2)=rint(x) - f2xm1 - faddp # 2^(x-rint(x)) -1: fscale - fstp %st(1) - add $16,%rsp - ret -3: xor %eax,%eax -4: cmp $0x3fff-64,%ax - fld1 - jb 1b # |x| < 0x1p-64 - fstpt (%rsp) - fistl 8(%rsp) - fildl 8(%rsp) - fsubrp %st(1) - addl $0x3fff,8(%rsp) - f2xm1 - fld1 - faddp # 2^(x-rint(x)) - fldt (%rsp) # 2^rint(x) - fmulp - add $16,%rsp - ret diff --git a/waterbox/libc/functions/math/x86_64/expl.s b/waterbox/libc/functions/math/x86_64/expl.s deleted file mode 100644 index 798261d283..0000000000 --- a/waterbox/libc/functions/math/x86_64/expl.s +++ /dev/null @@ -1,101 +0,0 @@ -# exp(x) = 2^hi + 2^hi (2^lo - 1) -# where hi+lo = log2e*x with 128bit precision -# exact log2e*x calculation depends on nearest rounding mode -# using the exact multiplication method of Dekker and Veltkamp - -.global expl -.type expl,@function -expl: - fldt 8(%rsp) - - # interesting case: 0x1p-32 <= |x| < 16384 - # check if (exponent|0x8000) is in [0xbfff-32, 0xbfff+13] - mov 16(%rsp), %ax - or $0x8000, %ax - sub $0xbfdf, %ax - cmp $45, %ax - jbe 2f - test %ax, %ax - fld1 - js 1f - # if |x|>=0x1p14 or nan return 2^trunc(x) - fscale - fstp %st(1) - ret - # if |x|<0x1p-32 return 1+x -1: faddp - ret - - # should be 0x1.71547652b82fe178p0L == 0x3fff b8aa3b29 5c17f0bc - # it will be wrong on non-nearest rounding mode -2: fldl2e - subq $48, %rsp - # hi = log2e_hi*x - # 2^hi = exp2l(hi) - fmul %st(1),%st - fld %st(0) - fstpt (%rsp) - fstpt 16(%rsp) - fstpt 32(%rsp) - call exp2l@PLT - # if 2^hi == inf return 2^hi - fld %st(0) - fstpt (%rsp) - cmpw $0x7fff, 8(%rsp) - je 1f - fldt 32(%rsp) - fldt 16(%rsp) - # fpu stack: 2^hi x hi - # exact mult: x*log2e - fld %st(1) - # c = 0x1p32+1 - movq $0x41f0000000100000,%rax - pushq %rax - fldl (%rsp) - # xh = x - c*x + c*x - # xl = x - xh - fmulp - fld %st(2) - fsub %st(1), %st - faddp - fld %st(2) - fsub %st(1), %st - # yh = log2e_hi - c*log2e_hi + c*log2e_hi - movq $0x3ff7154765200000,%rax - pushq %rax - fldl (%rsp) - # fpu stack: 2^hi x hi xh xl yh - # lo = hi - xh*yh + xl*yh - fld %st(2) - fmul %st(1), %st - fsubp %st, %st(4) - fmul %st(1), %st - faddp %st, %st(3) - # yl = log2e_hi - yh - movq $0x3de705fc2f000000,%rax - pushq %rax - fldl (%rsp) - # fpu stack: 2^hi x lo xh xl yl - # lo += xh*yl + xl*yl - fmul %st, %st(2) - fmulp %st, %st(1) - fxch %st(2) - faddp - faddp - # log2e_lo - movq $0xbfbe,%rax - pushq %rax - movq $0x82f0025f2dc582ee,%rax - pushq %rax - fldt (%rsp) - addq $40,%rsp - # fpu stack: 2^hi x lo log2e_lo - # lo += log2e_lo*x - # return 2^hi + 2^hi (2^lo - 1) - fmulp %st, %st(2) - faddp - f2xm1 - fmul %st(1), %st - faddp -1: addq $48, %rsp - ret diff --git a/waterbox/libc/functions/math/x86_64/expm1l.s b/waterbox/libc/functions/math/x86_64/expm1l.s deleted file mode 100644 index e773f08053..0000000000 --- a/waterbox/libc/functions/math/x86_64/expm1l.s +++ /dev/null @@ -1 +0,0 @@ -# see exp2l.s diff --git a/waterbox/libc/functions/math/x86_64/fabs.s b/waterbox/libc/functions/math/x86_64/fabs.s deleted file mode 100644 index 5715005e33..0000000000 --- a/waterbox/libc/functions/math/x86_64/fabs.s +++ /dev/null @@ -1,9 +0,0 @@ -.global fabs -.type fabs,@function -fabs: - xor %eax,%eax - dec %rax - shr %rax - movq %rax,%xmm1 - andpd %xmm1,%xmm0 - ret diff --git a/waterbox/libc/functions/math/x86_64/fabsf.s b/waterbox/libc/functions/math/x86_64/fabsf.s deleted file mode 100644 index 501a1f1755..0000000000 --- a/waterbox/libc/functions/math/x86_64/fabsf.s +++ /dev/null @@ -1,7 +0,0 @@ -.global fabsf -.type fabsf,@function -fabsf: - mov $0x7fffffff,%eax - movq %rax,%xmm1 - andps %xmm1,%xmm0 - ret diff --git a/waterbox/libc/functions/math/x86_64/fabsl.s b/waterbox/libc/functions/math/x86_64/fabsl.s deleted file mode 100644 index 4e7ab525e9..0000000000 --- a/waterbox/libc/functions/math/x86_64/fabsl.s +++ /dev/null @@ -1,6 +0,0 @@ -.global fabsl -.type fabsl,@function -fabsl: - fldt 8(%rsp) - fabs - ret diff --git a/waterbox/libc/functions/math/x86_64/floorl.s b/waterbox/libc/functions/math/x86_64/floorl.s deleted file mode 100644 index 80da466095..0000000000 --- a/waterbox/libc/functions/math/x86_64/floorl.s +++ /dev/null @@ -1,27 +0,0 @@ -.global floorl -.type floorl,@function -floorl: - fldt 8(%rsp) -1: mov $0x7,%al -1: fstcw 8(%rsp) - mov 9(%rsp),%ah - mov %al,9(%rsp) - fldcw 8(%rsp) - frndint - mov %ah,9(%rsp) - fldcw 8(%rsp) - ret - -.global ceill -.type ceill,@function -ceill: - fldt 8(%rsp) - mov $0xb,%al - jmp 1b - -.global truncl -.type truncl,@function -truncl: - fldt 8(%rsp) - mov $0xf,%al - jmp 1b diff --git a/waterbox/libc/functions/math/x86_64/fmodl.s b/waterbox/libc/functions/math/x86_64/fmodl.s deleted file mode 100644 index ea07b402fe..0000000000 --- a/waterbox/libc/functions/math/x86_64/fmodl.s +++ /dev/null @@ -1,11 +0,0 @@ -.global fmodl -.type fmodl,@function -fmodl: - fldt 24(%rsp) - fldt 8(%rsp) -1: fprem - fnstsw %ax - testb $4,%ah - jnz 1b - fstp %st(1) - ret diff --git a/waterbox/libc/functions/math/x86_64/llrint.s b/waterbox/libc/functions/math/x86_64/llrint.s deleted file mode 100644 index bf47649831..0000000000 --- a/waterbox/libc/functions/math/x86_64/llrint.s +++ /dev/null @@ -1,5 +0,0 @@ -.global llrint -.type llrint,@function -llrint: - cvtsd2si %xmm0,%rax - ret diff --git a/waterbox/libc/functions/math/x86_64/llrintf.s b/waterbox/libc/functions/math/x86_64/llrintf.s deleted file mode 100644 index d7204ac0ca..0000000000 --- a/waterbox/libc/functions/math/x86_64/llrintf.s +++ /dev/null @@ -1,5 +0,0 @@ -.global llrintf -.type llrintf,@function -llrintf: - cvtss2si %xmm0,%rax - ret diff --git a/waterbox/libc/functions/math/x86_64/llrintl.s b/waterbox/libc/functions/math/x86_64/llrintl.s deleted file mode 100644 index 1ec0817d3f..0000000000 --- a/waterbox/libc/functions/math/x86_64/llrintl.s +++ /dev/null @@ -1,7 +0,0 @@ -.global llrintl -.type llrintl,@function -llrintl: - fldt 8(%rsp) - fistpll 8(%rsp) - mov 8(%rsp),%rax - ret diff --git a/waterbox/libc/functions/math/x86_64/log10l.s b/waterbox/libc/functions/math/x86_64/log10l.s deleted file mode 100644 index 48ea4af727..0000000000 --- a/waterbox/libc/functions/math/x86_64/log10l.s +++ /dev/null @@ -1,7 +0,0 @@ -.global log10l -.type log10l,@function -log10l: - fldlg2 - fldt 8(%rsp) - fyl2x - ret diff --git a/waterbox/libc/functions/math/x86_64/log1pl.s b/waterbox/libc/functions/math/x86_64/log1pl.s deleted file mode 100644 index 955c9dbff0..0000000000 --- a/waterbox/libc/functions/math/x86_64/log1pl.s +++ /dev/null @@ -1,15 +0,0 @@ -.global log1pl -.type log1pl,@function -log1pl: - mov 14(%rsp),%eax - fldln2 - and $0x7fffffff,%eax - fldt 8(%rsp) - cmp $0x3ffd9400,%eax - ja 1f - fyl2xp1 - ret -1: fld1 - faddp - fyl2x - ret diff --git a/waterbox/libc/functions/math/x86_64/log2l.s b/waterbox/libc/functions/math/x86_64/log2l.s deleted file mode 100644 index ba08b9fb65..0000000000 --- a/waterbox/libc/functions/math/x86_64/log2l.s +++ /dev/null @@ -1,7 +0,0 @@ -.global log2l -.type log2l,@function -log2l: - fld1 - fldt 8(%rsp) - fyl2x - ret diff --git a/waterbox/libc/functions/math/x86_64/logl.s b/waterbox/libc/functions/math/x86_64/logl.s deleted file mode 100644 index 20dd1f819b..0000000000 --- a/waterbox/libc/functions/math/x86_64/logl.s +++ /dev/null @@ -1,7 +0,0 @@ -.global logl -.type logl,@function -logl: - fldln2 - fldt 8(%rsp) - fyl2x - ret diff --git a/waterbox/libc/functions/math/x86_64/lrint.s b/waterbox/libc/functions/math/x86_64/lrint.s deleted file mode 100644 index 15fc2454bc..0000000000 --- a/waterbox/libc/functions/math/x86_64/lrint.s +++ /dev/null @@ -1,5 +0,0 @@ -.global lrint -.type lrint,@function -lrint: - cvtsd2si %xmm0,%rax - ret diff --git a/waterbox/libc/functions/math/x86_64/lrintf.s b/waterbox/libc/functions/math/x86_64/lrintf.s deleted file mode 100644 index 488423d217..0000000000 --- a/waterbox/libc/functions/math/x86_64/lrintf.s +++ /dev/null @@ -1,5 +0,0 @@ -.global lrintf -.type lrintf,@function -lrintf: - cvtss2si %xmm0,%rax - ret diff --git a/waterbox/libc/functions/math/x86_64/lrintl.s b/waterbox/libc/functions/math/x86_64/lrintl.s deleted file mode 100644 index d587b12b5a..0000000000 --- a/waterbox/libc/functions/math/x86_64/lrintl.s +++ /dev/null @@ -1,7 +0,0 @@ -.global lrintl -.type lrintl,@function -lrintl: - fldt 8(%rsp) - fistpll 8(%rsp) - mov 8(%rsp),%rax - ret diff --git a/waterbox/libc/functions/math/x86_64/remainderl.s b/waterbox/libc/functions/math/x86_64/remainderl.s deleted file mode 100644 index cb3857b486..0000000000 --- a/waterbox/libc/functions/math/x86_64/remainderl.s +++ /dev/null @@ -1,11 +0,0 @@ -.global remainderl -.type remainderl,@function -remainderl: - fldt 24(%rsp) - fldt 8(%rsp) -1: fprem1 - fnstsw %ax - testb $4,%ah - jnz 1b - fstp %st(1) - ret diff --git a/waterbox/libc/functions/math/x86_64/rintl.s b/waterbox/libc/functions/math/x86_64/rintl.s deleted file mode 100644 index 64e663cd2d..0000000000 --- a/waterbox/libc/functions/math/x86_64/rintl.s +++ /dev/null @@ -1,6 +0,0 @@ -.global rintl -.type rintl,@function -rintl: - fldt 8(%rsp) - frndint - ret diff --git a/waterbox/libc/functions/math/x86_64/sqrt.s b/waterbox/libc/functions/math/x86_64/sqrt.s deleted file mode 100644 index d3c609f9f8..0000000000 --- a/waterbox/libc/functions/math/x86_64/sqrt.s +++ /dev/null @@ -1,4 +0,0 @@ -.global sqrt -.type sqrt,@function -sqrt: sqrtsd %xmm0, %xmm0 - ret diff --git a/waterbox/libc/functions/math/x86_64/sqrtf.s b/waterbox/libc/functions/math/x86_64/sqrtf.s deleted file mode 100644 index eec48c6094..0000000000 --- a/waterbox/libc/functions/math/x86_64/sqrtf.s +++ /dev/null @@ -1,4 +0,0 @@ -.global sqrtf -.type sqrtf,@function -sqrtf: sqrtss %xmm0, %xmm0 - ret diff --git a/waterbox/libc/functions/math/x86_64/sqrtl.s b/waterbox/libc/functions/math/x86_64/sqrtl.s deleted file mode 100644 index 23cd687d02..0000000000 --- a/waterbox/libc/functions/math/x86_64/sqrtl.s +++ /dev/null @@ -1,5 +0,0 @@ -.global sqrtl -.type sqrtl,@function -sqrtl: fldt 8(%rsp) - fsqrt - ret diff --git a/waterbox/libc/functions/math/x86_64/truncl.s b/waterbox/libc/functions/math/x86_64/truncl.s deleted file mode 100644 index f5cfa3b307..0000000000 --- a/waterbox/libc/functions/math/x86_64/truncl.s +++ /dev/null @@ -1 +0,0 @@ -# see floorl.s diff --git a/waterbox/libc/functions/nothread/call_once.c b/waterbox/libc/functions/nothread/call_once.c deleted file mode 100644 index 6673d611a1..0000000000 --- a/waterbox/libc/functions/nothread/call_once.c +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef REGTEST -#include - -void _PDCLIB_call_once(_PDCLIB_once_flag *flag, void (*func)(void)) -{ - if(!_PDCLIB_ONCE_FLAG_IS_DONE(flag)) { - func(); - *flag = 1; - } -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -#ifndef REGTEST -static int count = 0; -static once_flag once = ONCE_FLAG_INIT; - -static void do_once(void) -{ - count++; -} -#endif - -int main( void ) -{ -#ifndef REGTEST - TESTCASE(count == 0); - call_once(&once, do_once); - TESTCASE(count == 1); - call_once(&once, do_once); - TESTCASE(count == 1); - do_once(); - TESTCASE(count == 2); -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/nothread/cnd_init.c b/waterbox/libc/functions/nothread/cnd_init.c deleted file mode 100644 index 4e05427bd5..0000000000 --- a/waterbox/libc/functions/nothread/cnd_init.c +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef REGTEST -#include - -int cnd_init(cnd_t *cond) -{ - /* does nothing */ - return thrd_success; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/nothread/cnd_signal.c b/waterbox/libc/functions/nothread/cnd_signal.c deleted file mode 100644 index 275ba16ff8..0000000000 --- a/waterbox/libc/functions/nothread/cnd_signal.c +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef REGTEST -#include - -int cnd_signal(cnd_t *cond) -{ - return thrd_success; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/nothread/cnd_wait.c b/waterbox/libc/functions/nothread/cnd_wait.c deleted file mode 100644 index 444e1d477c..0000000000 --- a/waterbox/libc/functions/nothread/cnd_wait.c +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef REGTEST -#include - -int cnd_wait(cnd_t *cond, mtx_t *mtx) -{ - return thrd_error; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/nothread/mtx_destroy.c b/waterbox/libc/functions/nothread/mtx_destroy.c deleted file mode 100644 index 587b525cd8..0000000000 --- a/waterbox/libc/functions/nothread/mtx_destroy.c +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef REGTEST -#include - -void mtx_destroy(mtx_t *mtx) -{} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/nothread/mtx_init.c b/waterbox/libc/functions/nothread/mtx_init.c deleted file mode 100644 index e1bf08e93b..0000000000 --- a/waterbox/libc/functions/nothread/mtx_init.c +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef REGTEST -#include - -int mtx_init(mtx_t *mtx, int type) -{ - *mtx = 0; - return thrd_success; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/nothread/mtx_lock.c b/waterbox/libc/functions/nothread/mtx_lock.c deleted file mode 100644 index 2c5a26df3b..0000000000 --- a/waterbox/libc/functions/nothread/mtx_lock.c +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef REGTEST -#include - -int mtx_lock(mtx_t *mtx) -{ - (*mtx)++; - return thrd_success; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/nothread/mtx_timedlock.c b/waterbox/libc/functions/nothread/mtx_timedlock.c deleted file mode 100644 index c9d8f205a5..0000000000 --- a/waterbox/libc/functions/nothread/mtx_timedlock.c +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef REGTEST -#include - -int mtx_timedlock(mtx_t *restrict mtx, const struct timespec *restrict ts) -{ - return mtx_lock(mtx); -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/nothread/mtx_trylock.c b/waterbox/libc/functions/nothread/mtx_trylock.c deleted file mode 100644 index cd0c701c6f..0000000000 --- a/waterbox/libc/functions/nothread/mtx_trylock.c +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef REGTEST -#include - -int mtx_trylock(mtx_t *mtx) -{ - (*mtx)++; - return thrd_success; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/nothread/mtx_unlock.c b/waterbox/libc/functions/nothread/mtx_unlock.c deleted file mode 100644 index 42f696aa27..0000000000 --- a/waterbox/libc/functions/nothread/mtx_unlock.c +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef REGTEST -#include - -int mtx_unlock(mtx_t *mtx) -{ - if(--(*mtx) >= 0) - return thrd_success; - return thrd_error; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/nothread/thrd_yield.c b/waterbox/libc/functions/nothread/thrd_yield.c deleted file mode 100644 index 55ce0a2a4d..0000000000 --- a/waterbox/libc/functions/nothread/thrd_yield.c +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef REGTEST -#include - -void thrd_yield(void) -{ - /* does nothing */ -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/nothread/tss_create.c b/waterbox/libc/functions/nothread/tss_create.c deleted file mode 100644 index a778c7b438..0000000000 --- a/waterbox/libc/functions/nothread/tss_create.c +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef REGTEST -#include - -int tss_create(tss_t *key, tss_dtor_t dtor) -{ - key->self = key; - key->value = NULL; - return thrd_success; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -/* Tested in tss_get.c */ -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/nothread/tss_delete.c b/waterbox/libc/functions/nothread/tss_delete.c deleted file mode 100644 index bad8d0bf3d..0000000000 --- a/waterbox/libc/functions/nothread/tss_delete.c +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef REGTEST -#include - -void tss_delete(tss_t key) -{ - key.self->self = NULL; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -/* Tested in tss_get.c */ -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/nothread/tss_get.c b/waterbox/libc/functions/nothread/tss_get.c deleted file mode 100644 index 483088a252..0000000000 --- a/waterbox/libc/functions/nothread/tss_get.c +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef REGTEST -#include - -void *tss_get(tss_t key) -{ - return key.value; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -#ifndef REGTEST -static tss_t key; -static char v; -#endif - -int main( void ) -{ -#ifndef REGTEST - TESTCASE(tss_create(&key, NULL) == thrd_success); - TESTCASE(tss_get(key) == NULL); - TESTCASE(tss_set(key, &v) == thrd_success); - TESTCASE(tss_get(key) == &v); - tss_delete(key); -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/nothread/tss_set.c b/waterbox/libc/functions/nothread/tss_set.c deleted file mode 100644 index e66ea33894..0000000000 --- a/waterbox/libc/functions/nothread/tss_set.c +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef REGTEST -#include - -int tss_set(tss_t key, void *val) -{ - key.self->value = val; - return thrd_success; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -/* Tested in tss_get.c */ -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/setjmp/setjmp.s b/waterbox/libc/functions/setjmp/setjmp.s deleted file mode 100644 index 1c53411ed3..0000000000 --- a/waterbox/libc/functions/setjmp/setjmp.s +++ /dev/null @@ -1,53 +0,0 @@ -/* - * ==================================================== - * Copyright (C) 2007 by Ellips BV. All rights reserved. - * - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - - /* - ** jmp_buf: - ** rbx rbp r12 r13 r14 r15 rsp rip - ** 0 8 16 24 32 40 48 56 - */ -.global setjmp -.global longjmp -.type setjmp,@function -.type longjmp,@function - -setjmp: - movq %rbx, 0 (%rdi) - movq %rbp, 8 (%rdi) - movq %r12, 16 (%rdi) - movq %r13, 24 (%rdi) - movq %r14, 32 (%rdi) - movq %r15, 40 (%rdi) - leaq 8 (%rsp), %rax - movq %rax, 48 (%rdi) - movq (%rsp), %rax - movq %rax, 56 (%rdi) - movq $0, %rax - ret - -longjmp: - movq %rsi, %rax /* Return value */ - test %rax, %rax - jnz L0 - inc %rax /* if 0 was passed, send back 1 instead */ -L0: - movq 8 (%rdi), %rbp - - cli - movq 48 (%rdi), %rsp - pushq 56 (%rdi) - movq 0 (%rdi), %rbx - movq 16 (%rdi), %r12 - movq 24 (%rdi), %r13 - movq 32 (%rdi), %r14 - movq 40 (%rdi), %r15 - sti - - ret diff --git a/waterbox/libc/functions/signal/raise.c b/waterbox/libc/functions/signal/raise.c deleted file mode 100644 index 13a8b50b9f..0000000000 --- a/waterbox/libc/functions/signal/raise.c +++ /dev/null @@ -1,112 +0,0 @@ -/* raise( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -#include -#include - -extern void (*_PDCLIB_sigabrt)( int ); -extern void (*_PDCLIB_sigfpe)( int ); -extern void (*_PDCLIB_sigill)( int ); -extern void (*_PDCLIB_sigint)( int ); -extern void (*_PDCLIB_sigsegv)( int ); -extern void (*_PDCLIB_sigterm)( int ); - -int raise( int sig ) -{ - void (*sighandler)( int ); - char const * message; - switch ( sig ) - { - case SIGABRT: - sighandler = _PDCLIB_sigabrt; - message = "Abnormal termination (SIGABRT)"; - break; - case SIGFPE: - sighandler = _PDCLIB_sigfpe; - message = "Arithmetic exception (SIGFPE)"; - break; - case SIGILL: - sighandler = _PDCLIB_sigill; - message = "Illegal instruction (SIGILL)"; - break; - case SIGINT: - sighandler = _PDCLIB_sigint; - message = "Interactive attention signal (SIGINT)"; - break; - case SIGSEGV: - sighandler = _PDCLIB_sigsegv; - message = "Invalid memory access (SIGSEGV)"; - break; - case SIGTERM: - sighandler = _PDCLIB_sigterm; - message = "Termination request (SIGTERM)"; - break; - default: - fprintf( stderr, "Unknown signal #%d\n", sig ); - _Exit( EXIT_FAILURE ); - } - if ( sighandler == SIG_DFL ) - { - fputs( message, stderr ); - _Exit( EXIT_FAILURE ); - } - else if ( sighandler != SIG_IGN ) - { - sighandler = signal( sig, SIG_DFL ); - sighandler( sig ); - } - return 0; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -#include - -static volatile sig_atomic_t flag = 0; - -static int expected_signal = 0; - -static void test_handler( int sig ) -{ - TESTCASE( sig == expected_signal ); - flag = 1; -} - -int main( void ) -{ - /* Could be other than SIG_DFL if you changed the implementation. */ - TESTCASE( signal( SIGABRT, SIG_IGN ) == SIG_DFL ); - /* Should be ignored. */ - TESTCASE( raise( SIGABRT ) == 0 ); - /* Installing test handler, old handler should be returned */ - TESTCASE( signal( SIGABRT, test_handler ) == SIG_IGN ); - /* Raising and checking SIGABRT */ - expected_signal = SIGABRT; - TESTCASE( raise( SIGABRT ) == 0 ); - TESTCASE( flag == 1 ); - /* Re-installing test handler, should have been reset to default */ - /* Could be other than SIG_DFL if you changed the implementation. */ - TESTCASE( signal( SIGABRT, test_handler ) == SIG_DFL ); - /* Raising and checking SIGABRT */ - flag = 0; - TESTCASE( raise( SIGABRT ) == 0 ); - TESTCASE( flag == 1 ); - /* Installing test handler for different signal... */ - TESTCASE( signal( SIGTERM, test_handler ) == SIG_DFL ); - /* Raising and checking SIGTERM */ - expected_signal = SIGTERM; - TESTCASE( raise( SIGTERM ) == 0 ); - TESTCASE( flag == 1 ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/signal/signal.c b/waterbox/libc/functions/signal/signal.c deleted file mode 100644 index 569daf5ec9..0000000000 --- a/waterbox/libc/functions/signal/signal.c +++ /dev/null @@ -1,69 +0,0 @@ -/* signal( int sig, void (*func)( int ) ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST - -void (*_PDCLIB_sigabrt)( int ) = SIG_DFL; -void (*_PDCLIB_sigfpe)( int ) = SIG_DFL; -void (*_PDCLIB_sigill)( int ) = SIG_DFL; -void (*_PDCLIB_sigint)( int ) = SIG_DFL; -void (*_PDCLIB_sigsegv)( int ) = SIG_DFL; -void (*_PDCLIB_sigterm)( int ) = SIG_DFL; - -void (*signal( int sig, void (*func)( int ) ) )( int ) -{ - void (*oldhandler)( int ); - if ( sig <= 0 || func == SIG_ERR ) - { - return SIG_ERR; - } - switch ( sig ) - { - case SIGABRT: - oldhandler = _PDCLIB_sigabrt; - _PDCLIB_sigabrt = func; - break; - case SIGFPE: - oldhandler = _PDCLIB_sigfpe; - _PDCLIB_sigfpe = func; - break; - case SIGILL: - oldhandler = _PDCLIB_sigill; - _PDCLIB_sigill = func; - break; - case SIGINT: - oldhandler = _PDCLIB_sigint; - _PDCLIB_sigint = func; - break; - case SIGSEGV: - oldhandler = _PDCLIB_sigsegv; - _PDCLIB_sigsegv = func; - break; - case SIGTERM: - oldhandler = _PDCLIB_sigterm; - _PDCLIB_sigterm = func; - break; - default: - errno = EINVAL; - return SIG_ERR; - } - return oldhandler; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by raise.c */ - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/stdio/_PDCLIB_filemode.c b/waterbox/libc/functions/stdio/_PDCLIB_filemode.c deleted file mode 100644 index 92b7b41b65..0000000000 --- a/waterbox/libc/functions/stdio/_PDCLIB_filemode.c +++ /dev/null @@ -1,90 +0,0 @@ -/* _PDCLIB_filemode( const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" -/* Helper function that parses the C-style mode string passed to fopen() into - the PDCLib flags FREAD, FWRITE, FAPPEND, FRW (read-write) and FBIN (binary - mode). -*/ -unsigned int _PDCLIB_filemode( char const * const mode ) -{ - if(!mode) return 0; - - unsigned rc = 0; - switch ( mode[0] ) - { - case 'r': - rc |= _PDCLIB_FREAD; - break; - case 'w': - rc |= _PDCLIB_FWRITE; - break; - case 'a': - rc |= _PDCLIB_FAPPEND | _PDCLIB_FWRITE; - break; - default: - /* Other than read, write, or append - invalid */ - return 0; - } - for ( size_t i = 1; i < 4; ++i ) - { - switch ( mode[i] ) - { - case '+': - if ( rc & _PDCLIB_FRW ) return 0; /* Duplicates are invalid */ - rc |= _PDCLIB_FRW; - break; - case 'b': - if ( rc & _PDCLIB_FBIN ) return 0; /* Duplicates are invalid */ - rc |= _PDCLIB_FBIN; - break; - case '\0': - /* End of mode */ - return rc; - default: - /* Other than read/write or binary - invalid. */ - return 0; - } - } - /* Longer than three chars - invalid. */ - return 0; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ -#ifndef REGTEST - TESTCASE( _PDCLIB_filemode( "r" ) == _PDCLIB_FREAD ); - TESTCASE( _PDCLIB_filemode( "w" ) == _PDCLIB_FWRITE ); - TESTCASE( _PDCLIB_filemode( "a" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE ) ); - TESTCASE( _PDCLIB_filemode( "r+" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW ) ); - TESTCASE( _PDCLIB_filemode( "w+" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW ) ); - TESTCASE( _PDCLIB_filemode( "a+" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE | _PDCLIB_FRW ) ); - TESTCASE( _PDCLIB_filemode( "rb" ) == ( _PDCLIB_FREAD | _PDCLIB_FBIN ) ); - TESTCASE( _PDCLIB_filemode( "wb" ) == ( _PDCLIB_FWRITE | _PDCLIB_FBIN ) ); - TESTCASE( _PDCLIB_filemode( "ab" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE | _PDCLIB_FBIN ) ); - TESTCASE( _PDCLIB_filemode( "r+b" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW | _PDCLIB_FBIN ) ); - TESTCASE( _PDCLIB_filemode( "w+b" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) ); - TESTCASE( _PDCLIB_filemode( "a+b" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) ); - TESTCASE( _PDCLIB_filemode( "rb+" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW | _PDCLIB_FBIN ) ); - TESTCASE( _PDCLIB_filemode( "wb+" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) ); - TESTCASE( _PDCLIB_filemode( "ab+" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) ); - TESTCASE( _PDCLIB_filemode( "x" ) == 0 ); - TESTCASE( _PDCLIB_filemode( "r++" ) == 0 ); - TESTCASE( _PDCLIB_filemode( "wbb" ) == 0 ); - TESTCASE( _PDCLIB_filemode( "a+bx" ) == 0 ); -#endif - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/_PDCLIB_fillbuffer.c b/waterbox/libc/functions/stdio/_PDCLIB_fillbuffer.c deleted file mode 100644 index 7cfbe93553..0000000000 --- a/waterbox/libc/functions/stdio/_PDCLIB_fillbuffer.c +++ /dev/null @@ -1,46 +0,0 @@ -/* _PDCLIB_fillbuffer( FILE * stream ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_glue.h" -#include "_PDCLIB_io.h" - -int _PDCLIB_fillbuffer( FILE * stream ) -{ - size_t bytesRead; - bool ok = stream->ops->read( stream->handle, stream->buffer, stream->bufsize, - &bytesRead); - - if( ok ) { - if( bytesRead == 0 ) { - stream->status |= _PDCLIB_EOFFLAG; - return EOF; - } - stream->pos.offset += bytesRead; - stream->bufend = bytesRead; - stream->bufidx = 0; - return 0; - } else { - stream->status |= _PDCLIB_ERRORFLAG; - return EOF; - } -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by ftell.c */ - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/_PDCLIB_flushbuffer.c b/waterbox/libc/functions/stdio/_PDCLIB_flushbuffer.c deleted file mode 100644 index e7cf47c354..0000000000 --- a/waterbox/libc/functions/stdio/_PDCLIB_flushbuffer.c +++ /dev/null @@ -1,119 +0,0 @@ -/* _PDCLIB_flushbuffer( struct _PDCLIB_file_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_glue.h" -#include "_PDCLIB_io.h" - - -static int flushsubbuffer( FILE * stream, size_t length ) -{ - size_t justWrote; - size_t written = 0; - int rv = 0; - -#if 0 - // Very useful for debugging buffering issues - char l = '<', r = '>'; - stream->ops->write( stream->handle, &l, 1, &justWrote ); -#endif - - while( written != length ) - { - size_t toWrite = length - written; - - bool res = stream->ops->write( stream->handle, stream->buffer + written, - toWrite, &justWrote); - written += justWrote; - stream->pos.offset += justWrote; - - if (!res) - { - stream->status |= _PDCLIB_ERRORFLAG; - rv = EOF; - break; - } - } - -#if 0 - stream->ops->write( stream->handle, &r, 1, &justWrote ); -#endif - - stream->bufidx -= written; -#ifdef _PDCLIB_NEED_EOL_TRANSLATION - stream->bufnlexp -= written; -#endif - memmove( stream->buffer, stream->buffer + written, stream->bufidx ); - - return rv; -} - -int _PDCLIB_flushbuffer( FILE * stream ) -{ -#ifdef _PDCLIB_NEED_EOL_TRANSLATION - // if a text stream, and this platform needs EOL translation, well... - if ( ! ( stream->status & _PDCLIB_FBIN ) ) - { - // Special case: buffer is full and we start with a \n - if ( stream->bufnlexp == 0 - && stream->bufidx == stream->bufend - && stream->buffer[0] == '\n' ) - { - char cr = '\r'; - size_t written = 0; - bool res = stream->ops->write( stream->handle, &cr, 1, &written ); - - if (!res) { - stream->status |= _PDCLIB_ERRORFLAG; - return EOF; - } - - } - - for ( ; stream->bufnlexp < stream->bufidx; stream->bufnlexp++ ) - { - if (stream->buffer[stream->bufnlexp] == '\n' ) { - if ( stream->bufidx == stream->bufend ) { - // buffer is full. Need to print out everything up till now - if( flushsubbuffer( stream, stream->bufnlexp - 1 ) ) - { - return EOF; - } - } - - // we have spare space in buffer. Shift everything 1char and - // insert \r - memmove( &stream->buffer[stream->bufnlexp + 1], - &stream->buffer[stream->bufnlexp], - stream->bufidx - stream->bufnlexp ); - stream->buffer[stream->bufnlexp] = '\r'; - - stream->bufnlexp++; - stream->bufidx++; - } - } - } -#endif - return flushsubbuffer( stream, stream->bufidx ); -} - -#endif - - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by ftell.c */ - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/_PDCLIB_ftell64.c b/waterbox/libc/functions/stdio/_PDCLIB_ftell64.c deleted file mode 100644 index ea93fc69f4..0000000000 --- a/waterbox/libc/functions/stdio/_PDCLIB_ftell64.c +++ /dev/null @@ -1,62 +0,0 @@ -/* _PDCLIB_ftell64( FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -uint_fast64_t _PDCLIB_ftell64_unlocked( FILE * stream ) -{ - /* ftell() must take into account: - - the actual *physical* offset of the file, i.e. the offset as recognized - by the operating system (and stored in stream->pos.offset); and - - any buffers held by PDCLib, which - - in case of unwritten buffers, count in *addition* to the offset; or - - in case of unprocessed pre-read buffers, count in *substraction* to - the offset. (Remember to count ungetidx into this number.) - Conveniently, the calculation ( ( bufend - bufidx ) + ungetidx ) results - in just the right number in both cases: - - in case of unwritten buffers, ( ( 0 - unwritten ) + 0 ) - i.e. unwritten bytes as negative number - - in case of unprocessed pre-read, ( ( preread - processed ) + unget ) - i.e. unprocessed bytes as positive number. - That is how the somewhat obscure return-value calculation works. - */ - - /* ungetc on a stream at offset==0 will cause an overflow to UINT64_MAX. - * C99/C11 says that the return value of ftell in this case is - * "indeterminate" - */ - - return ( stream->pos.offset - ( ( (int)stream->bufend - (int)stream->bufidx ) + (int)stream->ungetidx ) ); -} - -uint_fast64_t _PDCLIB_ftell64( FILE * stream ) -{ - _PDCLIB_flockfile( stream ); - uint_fast64_t pos = _PDCLIB_ftell64_unlocked( stream ); - _PDCLIB_funlockfile( stream ); - return pos; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -#include - -int main( void ) -{ - /* Tested by ftell */ - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/_PDCLIB_fvopen.c b/waterbox/libc/functions/stdio/_PDCLIB_fvopen.c deleted file mode 100644 index 292ba3922c..0000000000 --- a/waterbox/libc/functions/stdio/_PDCLIB_fvopen.c +++ /dev/null @@ -1,105 +0,0 @@ -/* _PDCLIB_fvopen( _PDCLIB_fd_t, _PDCLIB_fileops_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_glue.h" -#include "_PDCLIB_io.h" -#include -#include - -extern FILE * _PDCLIB_filelist; - -FILE * _PDCLIB_fvopen( - _PDCLIB_fd_t fd, - const _PDCLIB_fileops_t *_PDCLIB_restrict ops, - int mode, - const char *_PDCLIB_restrict filename -) -{ - size_t filename_len; - FILE * rc; - if ( mode == NULL ) - { - /* Mode invalid */ - return NULL; - } - /* To reduce the number of malloc calls, all data fields are concatenated: - * the FILE structure itself, - * ungetc buffer, - * filename buffer, - * data buffer. - Data buffer comes last because it might change in size ( setvbuf() ). - */ - filename_len = filename ? strlen( filename ) + 1 : 1; - if ( ( rc = calloc( 1, sizeof( FILE ) + _PDCLIB_UNGETCBUFSIZE + filename_len + BUFSIZ ) ) == NULL ) - { - /* no memory */ - return NULL; - } - - if(mtx_init(&rc->lock, mtx_recursive) != thrd_success) { - free(rc); - return NULL; - } - - rc->status = mode; - rc->ops = ops; - rc->handle = fd; - /* Setting pointers into the memory block allocated above */ - rc->ungetbuf = (unsigned char *)rc + sizeof( FILE ); - rc->filename = (char *)rc->ungetbuf + _PDCLIB_UNGETCBUFSIZE; - rc->buffer = rc->filename + filename_len; - /* Copying filename to FILE structure */ - if(filename) strcpy( rc->filename, filename ); - /* Initializing the rest of the structure */ - rc->bufsize = BUFSIZ; - rc->bufidx = 0; -#ifdef _PDCLIB_NEED_EOL_TRANSLATION - rc->bufnlexp = 0; -#endif - rc->ungetidx = 0; - /* Setting buffer to _IOLBF because "when opened, a stream is fully - buffered if and only if it can be determined not to refer to an - interactive device." - */ - rc->status |= _IOLBF; - /* TODO: Setting mbstate */ - /* Adding to list of open files */ - rc->next = _PDCLIB_filelist; - _PDCLIB_filelist = rc; - return rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Some of the tests are not executed for regression tests, as the libc on - my system is at once less forgiving (segfaults on mode NULL) and more - forgiving (accepts undefined modes). - */ - FILE * fh; - remove( testfile ); - TESTCASE_NOREG( fopen( NULL, NULL ) == NULL ); - TESTCASE( fopen( NULL, "w" ) == NULL ); - TESTCASE_NOREG( fopen( "", NULL ) == NULL ); - TESTCASE( fopen( "", "w" ) == NULL ); - TESTCASE( fopen( "foo", "" ) == NULL ); - TESTCASE_NOREG( fopen( testfile, "wq" ) == NULL ); /* Undefined mode */ - TESTCASE_NOREG( fopen( testfile, "wr" ) == NULL ); /* Undefined mode */ - TESTCASE( ( fh = fopen( testfile, "w" ) ) != NULL ); - TESTCASE( fclose( fh ) == 0 ); - TESTCASE( remove( testfile ) == 0 ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/_PDCLIB_prepread.c b/waterbox/libc/functions/stdio/_PDCLIB_prepread.c deleted file mode 100644 index b0a38dbad8..0000000000 --- a/waterbox/libc/functions/stdio/_PDCLIB_prepread.c +++ /dev/null @@ -1,49 +0,0 @@ -/* _PDCLIB_prepread( FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_glue.h" - -int _PDCLIB_prepread( FILE * stream ) -{ - if ( ( stream->bufidx > stream->bufend ) || - ( stream->status & ( _PDCLIB_FWRITE | _PDCLIB_FAPPEND | _PDCLIB_ERRORFLAG | _PDCLIB_WIDESTREAM | _PDCLIB_EOFFLAG ) ) || - ! ( stream->status & ( _PDCLIB_FREAD | _PDCLIB_FRW ) ) ) - { - /* Function called on illegal (e.g. output) stream. - See comments on implementation-defined errno values in - <_PDCLIB_config.h>. - */ - errno = EINVAL; - stream->status |= _PDCLIB_ERRORFLAG; - return EOF; - } - stream->status |= _PDCLIB_FREAD | _PDCLIB_BYTESTREAM; - if ( ( stream->bufidx == stream->bufend ) && ( stream->ungetidx == 0 ) ) - { - return _PDCLIB_fillbuffer( stream ); - } - else - { - return 0; - } -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by ftell.c */ - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/_PDCLIB_prepwrite.c b/waterbox/libc/functions/stdio/_PDCLIB_prepwrite.c deleted file mode 100644 index fde9603fd1..0000000000 --- a/waterbox/libc/functions/stdio/_PDCLIB_prepwrite.c +++ /dev/null @@ -1,42 +0,0 @@ -/* _PDCLIB_prepwrite( FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_prepwrite( FILE * stream ) -{ - if ( ( stream->bufidx < stream->bufend ) || ( stream->ungetidx > 0 ) || - ( stream->status & ( _PDCLIB_FREAD | _PDCLIB_ERRORFLAG | _PDCLIB_WIDESTREAM | _PDCLIB_EOFFLAG ) ) || - ! ( stream->status & ( _PDCLIB_FWRITE | _PDCLIB_FAPPEND | _PDCLIB_FRW ) ) ) - { - /* Function called on illegal (e.g. input) stream. - See the comments on implementation-defined errno values in - <_PDCLIB_config.h>. - */ - errno = EINVAL; - stream->status |= _PDCLIB_ERRORFLAG; - return EOF; - } - stream->status |= _PDCLIB_FWRITE | _PDCLIB_BYTESTREAM; - return 0; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by ftell.c */ - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/_PDCLIB_print.c b/waterbox/libc/functions/stdio/_PDCLIB_print.c deleted file mode 100644 index c14516f691..0000000000 --- a/waterbox/libc/functions/stdio/_PDCLIB_print.c +++ /dev/null @@ -1,641 +0,0 @@ -/* _PDCLIB_print( const char *, struct _PDCLIB_status_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -/* Using an integer's bits as flags for both the conversion flags and length - modifiers. -*/ -/* FIXME: one too many flags to work on a 16-bit machine, join some (e.g. the - width flags) into a combined field. -*/ -#define E_minus (1<<0) -#define E_plus (1<<1) -#define E_alt (1<<2) -#define E_space (1<<3) -#define E_zero (1<<4) -#define E_done (1<<5) - -#define E_char (1<<6) -#define E_short (1<<7) -#define E_long (1<<8) -#define E_llong (1<<9) -#define E_intmax (1<<10) -#define E_size (1<<11) -#define E_ptrdiff (1<<12) -#define E_intptr (1<<13) - -#define E_ldouble (1<<14) - -#define E_lower (1<<15) -#define E_unsigned (1<<16) - -#define E_TYPES (E_char | E_short | E_long | E_llong | E_intmax \ - | E_size | E_ptrdiff | E_intptr) - -/* returns true if callback-based output succeeded; else false */ -static inline bool cbout( - struct _PDCLIB_status_t * status, - const void * buf, - size_t size ) -{ - size_t rv = status->write( status->ctx, buf, size ); - status->i += rv; - status->current += rv; - return rv == size; -} - -/* repeated output of a single character */ -static inline bool cbrept( - struct _PDCLIB_status_t * status, - char c, - size_t times ) -{ - if ( sizeof(size_t) == 8 && CHAR_BIT == 8) - { - uint64_t spread = UINT64_C(0x0101010101010101) * c; - while ( times ) - { - size_t n = times > 8 ? 8 : times; - if ( !cbout( status, &spread, n ) ) - return false; - times -= n; - } - return true; - } - else if ( sizeof(size_t) == 4 && CHAR_BIT == 8) - { - uint32_t spread = UINT32_C(0x01010101) * c; - while ( times ) - { - size_t n = times > 4 ? 4 : times; - if ( !cbout( status, &spread, n ) ) - return false; - times -= n; - } - return true; - } - else - { - while ( times ) - { - if ( !cbout( status, &c, 1) ) - return false; - times--; - } - return true; - } -} - - -/* Maximum number of output characters = - * number of bits in (u)intmax_t / number of bits per character in smallest - * base. Smallest base is octal, 3 bits/char. - * - * Additionally require 2 extra characters for prefixes - * - * Returns false if an I/O error occured. - */ -static const size_t maxIntLen = sizeof(intmax_t) * CHAR_BIT / 3 + 1; - -static bool int2base( uintmax_t value, struct _PDCLIB_status_t * status ) -{ - char sign = 0; - if ( ! ( status->flags & E_unsigned ) ) - { - intmax_t signval = (intmax_t) value; - bool negative = signval < 0; - value = signval < 0 ? -signval : signval; - - if ( negative ) - { - sign = '-'; - } - else if ( status->flags & E_plus ) - { - sign = '+'; - } - else if (status->flags & E_space ) - { - sign = ' '; - } - } - - // The user could theoretically ask for a silly buffer length here. - // Perhaps after a certain size we should malloc? Or do we refuse to protect - // them from their own stupidity? - size_t bufLen = (status->width > maxIntLen ? status->width : maxIntLen) + 2; - char outbuf[bufLen]; - char * outend = outbuf + bufLen; - int written = 0; - - // Build up our output string - backwards - { - const char * digits = (status->flags & E_lower) ? - _PDCLIB_digits : _PDCLIB_Xdigits; - uintmax_t remaining = value; - if(status->prec != 0 || remaining != 0) do { - uintmax_t digit = remaining % status->base; - remaining /= status->base; - - outend[-++written] = digits[digit]; - } while(remaining != 0); - } - - // Pad field out to the precision specification - while( (long) written < status->prec ) outend[-++written] = '0'; - - // If a field width specified, and zero padding was requested, then pad to - // the field width - unsigned padding = 0; - if ( ( ! ( status->flags & E_minus ) ) && ( status->flags & E_zero ) ) - { - while( written < (int) status->width ) - { - outend[-++written] = '0'; - padding++; - } - } - - // Prefixes - if ( sign != 0 ) - { - if ( padding == 0 ) written++; - outend[-written] = sign; - } - else if ( status->flags & E_alt ) - { - switch ( status->base ) - { - case 8: - if ( outend[-written] != '0' ) outend[-++written] = '0'; - break; - case 16: - // No prefix if zero - if ( value == 0 ) break; - - written += padding < 2 ? 2 - padding : 0; - outend[-written ] = '0'; - outend[-written + 1] = (status->flags & E_lower) ? 'x' : 'X'; - break; - default: - break; - } - } - - // Space padding to field width - if ( ! ( status->flags & ( E_minus | E_zero ) ) ) - { - while( written < (int) status->width ) outend[-++written] = ' '; - } - - // Write output - return cbout( status, outend - written, written ); -} - -/* print a string. returns false if an I/O error occured */ -static bool printstr( const char * str, struct _PDCLIB_status_t * status ) -{ - size_t len = status->prec >= 0 ? strnlen( str, status-> prec) - : strlen(str); - - if ( status->width == 0 || status->flags & E_minus ) - { - // Simple case or left justification - if ( status->prec > 0 ) - { - len = (unsigned) status->prec < len ? (unsigned) status->prec : len; - } - - if ( !cbout( status, str, len ) ) - return false; - - /* right padding */ - if ( status->width > status->current ) { - len = status->width - status->current; - - if ( !cbrept( status, ' ', len ) ) - return false; - } - } else { - // Right justification - - if ( status->width > len ) { - size_t padding = status->width - len; - - if ( !cbrept( status, ' ', padding )) - return false; - } - - if ( !cbout( status, str, len ) ) - return false; - } - - return true; -} - -static bool printchar( char chr, struct _PDCLIB_status_t * status ) -{ - if( ! ( status->flags & E_minus ) ) - { - // Right justification - if ( status-> width ) { - size_t justification = status->width - status->current - 1; - if ( !cbrept( status, ' ', justification )) - return false; - } - - if ( !cbout( status, &chr, 1 )) - return false; - } else { - // Left justification - - if ( !cbout( status, &chr, 1 )) - return false; - - if ( status->width > status->current ) { - if ( !cbrept( status, ' ', status->width - status->current ) ) - return false; - } - } - - return true; -} - -int _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status ) -{ - const char * orig_spec = spec; - if ( *(++spec) == '%' ) - { - /* %% -> print single '%' */ - if ( !cbout(status, spec, 1) ) - return -1; - ++spec; - return (spec - orig_spec); - } - /* Initializing status structure */ - status->flags = 0; - status->base = 0; - status->current = 0; - status->width = 0; - status->prec = EOF; - - /* First come 0..n flags */ - do - { - switch ( *spec ) - { - case '-': - /* left-aligned output */ - status->flags |= E_minus; - ++spec; - break; - case '+': - /* positive numbers prefixed with '+' */ - status->flags |= E_plus; - ++spec; - break; - case '#': - /* alternative format (leading 0x for hex, 0 for octal) */ - status->flags |= E_alt; - ++spec; - break; - case ' ': - /* positive numbers prefixed with ' ' */ - status->flags |= E_space; - ++spec; - break; - case '0': - /* right-aligned padding done with '0' instead of ' ' */ - status->flags |= E_zero; - ++spec; - break; - default: - /* not a flag, exit flag parsing */ - status->flags |= E_done; - break; - } - } while ( ! ( status->flags & E_done ) ); - - /* Optional field width */ - if ( *spec == '*' ) - { - /* Retrieve width value from argument stack */ - int width = va_arg( status->arg, int ); - if ( width < 0 ) - { - status->flags |= E_minus; - status->width = abs( width ); - } - else - { - status->width = width; - } - ++spec; - } - else - { - /* If a width is given, strtol() will return its value. If not given, - strtol() will return zero. In both cases, endptr will point to the - rest of the conversion specifier - just what we need. - */ - status->width = (int)strtol( spec, (char**)&spec, 10 ); - } - - /* Optional precision */ - if ( *spec == '.' ) - { - ++spec; - if ( *spec == '*' ) - { - /* Retrieve precision value from argument stack. A negative value - is as if no precision is given - as precision is initalized to - EOF (negative), there is no need for testing for negative here. - */ - status->prec = va_arg( status->arg, int ); - ++spec; - } - else - { - status->prec = (int)strtol( spec, (char**) &spec, 10 ); - } - /* Having a precision cancels out any zero flag. */ - status->flags &= ~E_zero; - } - - /* Optional length modifier - We step one character ahead in any case, and step back only if we find - there has been no length modifier (or step ahead another character if it - has been "hh" or "ll"). - */ - switch ( *(spec++) ) - { - case 'h': - if ( *spec == 'h' ) - { - /* hh -> char */ - status->flags |= E_char; - ++spec; - } - else - { - /* h -> short */ - status->flags |= E_short; - } - break; - case 'l': - if ( *spec == 'l' ) - { - /* ll -> long long */ - status->flags |= E_llong; - ++spec; - } - else - { - /* k -> long */ - status->flags |= E_long; - } - break; - case 'j': - /* j -> intmax_t, which might or might not be long long */ - status->flags |= E_intmax; - break; - case 'z': - /* z -> size_t, which might or might not be unsigned int */ - status->flags |= E_size; - break; - case 't': - /* t -> ptrdiff_t, which might or might not be long */ - status->flags |= E_ptrdiff; - break; - case 'L': - /* L -> long double */ - status->flags |= E_ldouble; - break; - default: - --spec; - break; - } - - /* Conversion specifier */ - switch ( *spec ) - { - case 'd': - /* FALLTHROUGH */ - case 'i': - status->base = 10; - break; - case 'o': - status->base = 8; - status->flags |= E_unsigned; - break; - case 'u': - status->base = 10; - status->flags |= E_unsigned; - break; - case 'x': - status->base = 16; - status->flags |= ( E_lower | E_unsigned ); - break; - case 'X': - status->base = 16; - status->flags |= E_unsigned; - break; - case 'f': - case 'F': - case 'e': - case 'E': - case 'g': - case 'G': - break; - case 'a': - case 'A': - break; - case 'c': - /* TODO: wide chars. */ - if ( !printchar( va_arg( status->arg, int ), status ) ) - return -1; - ++spec; - return (spec - orig_spec); - case 's': - /* TODO: wide chars. */ - { - char * s = va_arg( status->arg, char * ); - if ( !printstr( s, status ) ) - return -1; - ++spec; - return (spec - orig_spec); - } - case 'p': - status->base = 16; - status->flags |= ( E_lower | E_unsigned | E_alt | E_intptr ); - break; - case 'n': - { - int * val = va_arg( status->arg, int * ); - *val = status->i; - ++spec; - return (spec - orig_spec); - } - default: - /* No conversion specifier. Bad conversion. */ - return 0; - } - /* Do the actual output based on our findings */ - if ( status->base != 0 ) - { - /* Integer conversions */ - /* TODO: Check for invalid flag combinations. */ - if ( status->flags & E_unsigned ) - { - /* TODO: Marking the default case _PDCLIB_UNREACHABLE breaks %ju test driver? */ - uintmax_t value = 0; - switch ( status->flags & E_TYPES ) - { - case E_char: - value = (uintmax_t)(unsigned char)va_arg( status->arg, int ); - break; - case E_short: - value = (uintmax_t)(unsigned short)va_arg( status->arg, int ); - break; - case 0: - value = (uintmax_t)va_arg( status->arg, unsigned int ); - break; - case E_long: - value = (uintmax_t)va_arg( status->arg, unsigned long ); - break; - case E_llong: - value = (uintmax_t)va_arg( status->arg, unsigned long long ); - break; - case E_size: - value = (uintmax_t)va_arg( status->arg, size_t ); - break; - case E_intptr: - value = (uintmax_t)va_arg( status->arg, uintptr_t ); - break; - case E_ptrdiff: - value = (uintmax_t)va_arg( status->arg, ptrdiff_t ); - break; - case E_intmax: - value = va_arg( status->arg, uintmax_t ); - } - if ( !int2base( value, status ) ) - return -1; - } - else - { - intmax_t value = 0; - switch ( status->flags & E_TYPES ) - { - case E_char: - value = (intmax_t)(char)va_arg( status->arg, int ); - break; - case E_short: - value = (intmax_t)(short)va_arg( status->arg, int ); - break; - case 0: - value = (intmax_t)va_arg( status->arg, int ); - break; - case E_long: - value = (intmax_t)va_arg( status->arg, long ); - break; - case E_llong: - value = (intmax_t)va_arg( status->arg, long long ); - break; - case E_size: - value = (intmax_t)va_arg( status->arg, size_t ); - break; - case E_intptr: - value = (intmax_t)va_arg( status->arg, intptr_t ); - break; - case E_ptrdiff: - value = (intmax_t)va_arg( status->arg, ptrdiff_t ); - break; - case E_intmax: - value = va_arg( status->arg, intmax_t ); - break; - default: - _PDCLIB_UNREACHABLE; - } - - if (!int2base( value, status ) ) - return -1; - } - - if ( status->flags & E_minus && status->current < status->width ) - { - if (!cbrept( status, ' ', status->width - status->current )) - return -1; - } - } - ++spec; - return spec - orig_spec; -} - -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "_PDCLIB/print.c" -#define _PDCLIB_STRINGIO - -#include "_PDCLIB_test.h" - -#ifndef REGTEST -static size_t testcb( void *p, const char *buf, size_t size ) -{ - char **destbuf = p; - memcpy(*destbuf, buf, size); - *destbuf += size; - return size; -} - -static int testprintf( char * buffer, const char * format, ... ) -{ - /* Members: base, flags, n, i, current, width, prec, ctx, cb, arg */ - struct _PDCLIB_status_t status; - status.base = 0; - status.flags = 0; - status.n = 100; - status.i = 0; - status.current = 0; - status.width = 0; - status.prec = 0; - status.ctx = &buffer; - status.write = testcb; - va_start( status.arg, format ); - memset( buffer, '\0', 100 ); - if ( _PDCLIB_print( format, &status ) != (int)strlen( format ) ) - { - printf( "_PDCLIB_print() did not return end-of-specifier on '%s'.\n", format ); - ++TEST_RESULTS; - } - va_end( status.arg ); - return status.i; -} -#endif - -#define TEST_CONVERSION_ONLY - -int main( void ) -{ -#ifndef REGTEST - char target[100]; -#include "printf_testcases.h" -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/_PDCLIB_scan.c b/waterbox/libc/functions/stdio/_PDCLIB_scan.c deleted file mode 100644 index aa7be84e75..0000000000 --- a/waterbox/libc/functions/stdio/_PDCLIB_scan.c +++ /dev/null @@ -1,632 +0,0 @@ -/* _PDCLIB_scan( const char *, struct _PDCLIB_status_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef REGTEST - -#include "_PDCLIB_io.h" - -/* Using an integer's bits as flags for both the conversion flags and length - modifiers. -*/ -#define E_suppressed 1<<0 -#define E_char 1<<6 -#define E_short 1<<7 -#define E_long 1<<8 -#define E_llong 1<<9 -#define E_intmax 1<<10 -#define E_size 1<<11 -#define E_ptrdiff 1<<12 -#define E_intptr 1<<13 -#define E_ldouble 1<<14 -#define E_unsigned 1<<16 - - -/* Helper function to get a character from the string or stream, whatever is - used for input. When reading from a string, returns EOF on end-of-string - so that handling of the return value can be uniform for both streams and - strings. -*/ -static int GET( struct _PDCLIB_status_t * status ) -{ - int rc = EOF; - if ( status->stream != NULL ) - { - rc = getc( status->stream ); - } - else - { - rc = ( *status->s == '\0' ) ? EOF : (unsigned char)*((status->s)++); - } - if ( rc != EOF ) - { - ++(status->i); - ++(status->current); - } - return rc; -} - - -/* Helper function to put a read character back into the string or stream, - whatever is used for input. -*/ -static void UNGET( int c, struct _PDCLIB_status_t * status ) -{ - if ( status->stream != NULL ) - { - ungetc( c, status->stream ); /* TODO: Error? */ - } - else - { - --(status->s); - } - --(status->i); - --(status->current); -} - - -/* Helper function to check if a character is part of a given scanset */ -static bool IN_SCANSET( const char * scanlist, const char * end_scanlist, int rc ) -{ - // SOLAR - int previous = -1; - while ( scanlist != end_scanlist ) - { - if ( ( *scanlist == '-' ) && ( previous != -1 ) ) - { - /* possible scangroup ("a-z") */ - if ( ++scanlist == end_scanlist ) - { - /* '-' at end of scanlist does not describe a scangroup */ - return rc == '-'; - } - while ( ++previous <= (unsigned char)*scanlist ) - { - if ( previous == rc ) - { - return true; - } - } - previous = -1; - } - else - { - /* not a scangroup, check verbatim */ - if ( rc == (unsigned char)*scanlist ) - { - return true; - } - previous = (unsigned char)(*scanlist++); - } - } - return false; -} - - -const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) -{ - /* generic input character */ - int rc = EOF; - const char * orig_spec = spec; - if ( *(++spec) == '%' ) - { - /* %% -> match single '%' */ - rc = GET( status ); - switch ( rc ) - { - case EOF: - /* input error */ - if ( status->n == 0 ) - { - status->n = -1; - } - return NULL; - case '%': - return ++spec; - default: - UNGET( rc, status ); - break; - } - } - /* Initializing status structure */ - status->flags = 0; - status->base = -1; - status->current = 0; - status->width = 0; - status->prec = 0; - - /* '*' suppresses assigning parsed value to variable */ - if ( *spec == '*' ) - { - status->flags |= E_suppressed; - ++spec; - } - - /* If a width is given, strtol() will return its value. If not given, - strtol() will return zero. In both cases, endptr will point to the - rest of the conversion specifier - just what we need. - */ - char const * prev_spec = spec; - status->width = (int)strtol( spec, (char**)&spec, 10 ); - if ( spec == prev_spec ) - { - status->width = UINT_MAX; - } - - /* Optional length modifier - We step one character ahead in any case, and step back only if we find - there has been no length modifier (or step ahead another character if it - has been "hh" or "ll"). - */ - switch ( *(spec++) ) - { - case 'h': - if ( *spec == 'h' ) - { - /* hh -> char */ - status->flags |= E_char; - ++spec; - } - else - { - /* h -> short */ - status->flags |= E_short; - } - break; - case 'l': - if ( *spec == 'l' ) - { - /* ll -> long long */ - status->flags |= E_llong; - ++spec; - } - else - { - /* l -> long */ - status->flags |= E_long; - } - break; - case 'j': - /* j -> intmax_t, which might or might not be long long */ - status->flags |= E_intmax; - break; - case 'z': - /* z -> size_t, which might or might not be unsigned int */ - status->flags |= E_size; - break; - case 't': - /* t -> ptrdiff_t, which might or might not be long */ - status->flags |= E_ptrdiff; - break; - case 'L': - /* L -> long double */ - status->flags |= E_ldouble; - break; - default: - --spec; - break; - } - - /* Conversion specifier */ - - /* whether valid input had been parsed */ - bool value_parsed = false; - - switch ( *spec ) - { - case 'd': - status->base = 10; - break; - case 'i': - status->base = 0; - break; - case 'o': - status->base = 8; - status->flags |= E_unsigned; - break; - case 'u': - status->base = 10; - status->flags |= E_unsigned; - break; - case 'x': - status->base = 16; - status->flags |= E_unsigned; - break; - case 'f': - case 'F': - case 'e': - case 'E': - case 'g': - case 'G': - case 'a': - case 'A': - break; - case 'c': - { - char * c = va_arg( status->arg, char * ); - /* for %c, default width is one */ - if ( status->width == UINT_MAX ) - { - status->width = 1; - } - /* reading until width reached or input exhausted */ - while ( ( status->current < status->width ) && - ( ( rc = GET( status ) ) != EOF ) ) - { - *(c++) = rc; - value_parsed = true; - } - /* width or input exhausted */ - if ( value_parsed ) - { - ++status->n; - return ++spec; - } - else - { - /* input error, no character read */ - if ( status->n == 0 ) - { - status->n = -1; - } - return NULL; - } - } - case 's': - { - char * c = va_arg( status->arg, char * ); - while ( ( status->current < status->width ) && - ( ( rc = GET( status ) ) != EOF ) ) - { - if ( isspace( rc ) ) - { - UNGET( rc, status ); - if ( value_parsed ) - { - /* matching sequence terminated by whitespace */ - *c = '\0'; - ++status->n; - return ++spec; - } - else - { - /* matching error */ - return NULL; - } - } - else - { - /* match */ - value_parsed = true; - *(c++) = rc; - } - } - /* width or input exhausted */ - if ( value_parsed ) - { - *c = '\0'; - ++status->n; - return ++spec; - } - else - { - /* input error, no character read */ - if ( status->n == 0 ) - { - status->n = -1; - } - return NULL; - } - } - case '[': - { - const char * endspec = spec; - bool negative_scanlist = false; - if ( *(++endspec) == '^' ) - { - negative_scanlist = true; - ++endspec; - } - spec = endspec; - do - { - // TODO: This can run beyond a malformed format string - ++endspec; - } while ( *endspec != ']' ); - // read according to scanlist, equiv. to %s above - char * c = va_arg( status->arg, char * ); - while ( ( status->current < status->width ) && - ( ( rc = GET( status ) ) != EOF ) ) - { - if ( negative_scanlist ) - { - if ( IN_SCANSET( spec, endspec, rc ) ) - { - UNGET( rc, status ); - break; - } - } - else - { - if ( ! IN_SCANSET( spec, endspec, rc ) ) - { - UNGET( rc, status ); - break; - } - } - value_parsed = true; - *(c++) = rc; - } - if ( value_parsed ) - { - *c = '\0'; - ++status->n; - return ++endspec; - } - else - { - if ( rc == EOF ) - { - status->n = -1; - } - return NULL; - } - } - case 'p': - status->base = 16; - // TODO: Like _PDCLIB_print, E_pointer(?) - status->flags |= E_unsigned | E_long; - break; - case 'n': - { - int * val = va_arg( status->arg, int * ); - *val = status->i; - return ++spec; - } - default: - /* No conversion specifier. Bad conversion. */ - return orig_spec; - } - - if ( status->base != -1 ) - { - /* integer conversion */ - uintmax_t value = 0; /* absolute value read */ - bool prefix_parsed = false; - int sign = 0; - while ( ( status->current < status->width ) && - ( ( rc = GET( status ) ) != EOF ) ) - { - if ( isspace( rc ) ) - { - if ( sign ) - { - /* matching sequence terminated by whitespace */ - UNGET( rc, status ); - break; - } - else - { - /* leading whitespace not counted against width */ - status->current--; - } - } - else if ( ! sign ) - { - /* no sign parsed yet */ - switch ( rc ) - { - case '-': - sign = -1; - break; - case '+': - sign = 1; - break; - default: - /* not a sign; put back character */ - sign = 1; - UNGET( rc, status ); - break; - } - } - else if ( ! prefix_parsed ) - { - /* no prefix (0x... for hex, 0... for octal) parsed yet */ - prefix_parsed = true; - if ( rc != '0' ) - { - /* not a prefix; if base not yet set, set to decimal */ - if ( status->base == 0 ) - { - status->base = 10; - } - UNGET( rc, status ); - } - else - { - /* starts with zero, so it might be a prefix. */ - /* check what follows next (might be 0x...) */ - if ( ( status->current < status->width ) && - ( ( rc = GET( status ) ) != EOF ) ) - { - if ( tolower( rc ) == 'x' ) - { - /* 0x... would be prefix for hex base... */ - if ( ( status->base == 0 ) || - ( status->base == 16 ) ) - { - status->base = 16; - } - else - { - /* ...unless already set to other value */ - UNGET( rc, status ); - value_parsed = true; - } - } - else - { - /* 0... but not 0x.... would be octal prefix */ - UNGET( rc, status ); - if ( status->base == 0 ) - { - status->base = 8; - } - /* in any case we have read a zero */ - value_parsed = true; - } - } - else - { - /* failed to read beyond the initial zero */ - value_parsed = true; - break; - } - } - } - else - { - char * digitptr = memchr( _PDCLIB_digits, tolower( rc ), status->base ); - if ( digitptr == NULL ) - { - /* end of input item */ - UNGET( rc, status ); - break; - } - value *= status->base; - value += digitptr - _PDCLIB_digits; - value_parsed = true; - } - } - /* width or input exhausted, or non-matching character */ - if ( ! value_parsed ) - { - /* out of input before anything could be parsed - input error */ - /* FIXME: if first character does not match, value_parsed is not set - but it is NOT an input error */ - if ( ( status->n == 0 ) && ( rc == EOF ) ) - { - status->n = -1; - } - return NULL; - } - /* convert value to target type and assign to parameter */ - if ( ! ( status->flags & E_suppressed ) ) - { - switch ( status->flags & ( E_char | E_short | E_long | E_llong | - E_intmax | E_size | E_ptrdiff | - E_unsigned ) ) - { - case E_char: - *( va_arg( status->arg, char * ) ) = (char)( value * sign ); - break; - case E_char | E_unsigned: - *( va_arg( status->arg, unsigned char * ) ) = (unsigned char)( value * sign ); - break; - - case E_short: - *( va_arg( status->arg, short * ) ) = (short)( value * sign ); - break; - case E_short | E_unsigned: - *( va_arg( status->arg, unsigned short * ) ) = (unsigned short)( value * sign ); - break; - - case 0: - *( va_arg( status->arg, int * ) ) = (int)( value * sign ); - break; - case E_unsigned: - *( va_arg( status->arg, unsigned int * ) ) = (unsigned int)( value * sign ); - break; - - case E_long: - *( va_arg( status->arg, long * ) ) = (long)( value * sign ); - break; - case E_long | E_unsigned: - *( va_arg( status->arg, unsigned long * ) ) = (unsigned long)( value * sign ); - break; - - case E_llong: - *( va_arg( status->arg, long long * ) ) = (long long)( value * sign ); - break; - case E_llong | E_unsigned: - *( va_arg( status->arg, unsigned long long * ) ) = (unsigned long long)( value * sign ); - break; - - case E_intmax: - *( va_arg( status->arg, intmax_t * ) ) = (intmax_t)( value * sign ); - break; - case E_intmax | E_unsigned: - *( va_arg( status->arg, uintmax_t * ) ) = (uintmax_t)( value * sign ); - break; - - case E_size: - /* E_size always implies unsigned */ - *( va_arg( status->arg, size_t * ) ) = (size_t)( value * sign ); - break; - - case E_ptrdiff: - /* E_ptrdiff always implies signed */ - *( va_arg( status->arg, ptrdiff_t * ) ) = (ptrdiff_t)( value * sign ); - break; - - default: - puts( "UNSUPPORTED SCANF FLAG COMBINATION" ); - return NULL; /* behaviour unspecified */ - } - ++(status->n); - } - return ++spec; - } - /* TODO: Floats. */ - return NULL; -} -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "_PDCLIB/scan.c" -#define _PDCLIB_STRINGIO - -#include "_PDCLIB_test.h" - -#ifndef REGTEST -static int testscanf( char const * s, char const * format, ... ) -{ - struct _PDCLIB_status_t status; - status.n = 0; - status.i = 0; - status.s = (char *)s; - status.stream = NULL; - va_start( status.arg, format ); - if ( *(_PDCLIB_scan( format, &status )) != '\0' ) - { - printf( "_PDCLIB_scan() did not return end-of-specifier on '%s'.\n", format ); - ++TEST_RESULTS; - } - va_end( status.arg ); - return status.n; -} -#endif - -#define TEST_CONVERSION_ONLY - -int main( void ) -{ -#ifndef REGTEST - char source[100]; -#include "scanf_testcases.h" -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/_PDCLIB_seek.c b/waterbox/libc/functions/stdio/_PDCLIB_seek.c deleted file mode 100644 index 5d88a15cb9..0000000000 --- a/waterbox/libc/functions/stdio/_PDCLIB_seek.c +++ /dev/null @@ -1,41 +0,0 @@ -/* int64_t _PDCLIB_seek( FILE *, int64_t, int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int_fast64_t _PDCLIB_seek( FILE * stream, - int_fast64_t offset, - int whence ) -{ - int_fast64_t newPos; - if(!stream->ops->seek(stream->handle, offset, whence, &newPos)) { - return EOF; - } - - stream->ungetidx = 0; - stream->bufidx = 0; - stream->bufend = 0; - stream->pos.offset = newPos; - return newPos; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by ftell.c */ - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/_cbprintf.c b/waterbox/libc/functions/stdio/_cbprintf.c deleted file mode 100644 index 3598a5c47c..0000000000 --- a/waterbox/libc/functions/stdio/_cbprintf.c +++ /dev/null @@ -1,56 +0,0 @@ -/* _cbprintf( void *, size_t (*)( void *, const char *, size_t ), const char *, ... ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include - -#ifndef REGTEST - -int _cbprintf( - void * p, - size_t (*cb)( void*, const char*, size_t ), - const char * _PDCLIB_restrict format, - ...) -{ - int rc; - va_list ap; - va_start( ap, format ); - rc = _vcbprintf( p, cb, format, ap ); - va_end( ap ); - return rc; -} - -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "stdio/sprintf.c" -#define _PDCLIB_STRINGIO -#include - -#include "_PDCLIB_test.h" - -static char * bufptr; -static size_t testcb( void *p, const char *buf, size_t size ) -{ - memcpy(bufptr, buf, size); - bufptr += size; - *bufptr = '\0'; - return size; -} - -#define testprintf( s, ... ) _cbprintf( bufptr = s, testcb, __VA_ARGS__ ) - -int main( void ) -{ -#ifndef REGTEST - char target[100]; -#include "printf_testcases.h" -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/_vcbprintf.c b/waterbox/libc/functions/stdio/_vcbprintf.c deleted file mode 100644 index bafe6aee93..0000000000 --- a/waterbox/libc/functions/stdio/_vcbprintf.c +++ /dev/null @@ -1,124 +0,0 @@ -/* vsnprintf( char *, size_t, const char *, va_list ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -/* returns true if callback-based output succeeded; else false */ -static inline bool cbout( - struct _PDCLIB_status_t * status, - const char *buf, - size_t size ) -{ - size_t rv = status->write( status->ctx, buf, size ); - status->i += rv; - return rv == size; -} - -int _vcbprintf( - void *p, - size_t ( *cb ) ( void *p, const char *buf, size_t size ), - const char *format, - va_list arg ) -{ - struct _PDCLIB_status_t status; - status.base = 0; - status.flags = 0; - status.n = 0; - status.i = 0; - status.current = 0; - status.width = 0; - status.prec = 0; - status.ctx = p; - status.write = cb; - va_copy( status.arg, arg ); - - /* Alternate between outputing runs of verbatim text and conversions */ - while ( *format != '\0' ) - { - const char *mark = format; - while ( *format != '\0' && *format != '%') - { - format++; - } - - if ( mark != format ) - { - if ( !cbout(&status, mark, format - mark) ) - return -1; - } - - if ( *format == '%' ) { - int consumed = _PDCLIB_print( format, &status ); - if ( consumed > 0 ) - { - format += consumed; - } - else if ( consumed == 0 ) - { - /* not a conversion specifier, print verbatim */ - if ( !cbout(&status, format++, 1) ) - return -1; - } - else - { - /* I/O callback error */ - return -1; - } - } - } - - va_end( status.arg ); - return status.i; -} - -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "stdio/_vcbprintf.c" -#define _PDCLIB_STRINGIO -#include -#include -#include "_PDCLIB_test.h" - -#ifndef REGTEST - -static size_t testcb( void *p, const char *buf, size_t size ) -{ - char **destbuf = p; - memcpy(*destbuf, buf, size); - *destbuf += size; - return size; -} - -static int testprintf( char * s, const char * format, ... ) -{ - int i; - va_list arg; - va_start( arg, format ); - i = _vcbprintf( &s, testcb, format, arg ); - *s = 0; - va_end( arg ); - return i; -} - -#endif - -int main( void ) -{ -#ifndef REGTEST - char target[100]; -#include "printf_testcases.h" -#endif - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/clearerr.c b/waterbox/libc/functions/stdio/clearerr.c deleted file mode 100644 index e569fd4085..0000000000 --- a/waterbox/libc/functions/stdio/clearerr.c +++ /dev/null @@ -1,59 +0,0 @@ -/* clearerr( FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -void _PDCLIB_clearerr_unlocked( FILE * stream ) -{ - stream->status &= ~( _PDCLIB_ERRORFLAG | _PDCLIB_EOFFLAG ); -} - -void clearerr( FILE * stream ) -{ - _PDCLIB_flockfile( stream ); - _PDCLIB_clearerr_unlocked( stream ); - _PDCLIB_funlockfile( stream ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - FILE * fh; - TESTCASE( ( fh = tmpfile() ) != NULL ); - /* Flags should be clear */ - TESTCASE( ! ferror( fh ) ); - TESTCASE( ! feof( fh ) ); - /* Reading from input stream - should provoke error */ - /* FIXME: Apparently glibc disagrees on this assumption. How to provoke error on glibc? */ - TESTCASE( fgetc( fh ) == EOF ); - TESTCASE( ferror( fh ) ); - TESTCASE( ! feof( fh ) ); - /* clearerr() should clear flags */ - clearerr( fh ); - TESTCASE( ! ferror( fh ) ); - TESTCASE( ! feof( fh ) ); - /* Reading from empty stream - should provoke EOF */ - rewind( fh ); - TESTCASE( fgetc( fh ) == EOF ); - TESTCASE( ! ferror( fh ) ); - TESTCASE( feof( fh ) ); - /* clearerr() should clear flags */ - clearerr( fh ); - TESTCASE( ! ferror( fh ) ); - TESTCASE( ! feof( fh ) ); - TESTCASE( fclose( fh ) == 0 ); - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/fclose.c b/waterbox/libc/functions/stdio/fclose.c deleted file mode 100644 index c80e31d1a0..0000000000 --- a/waterbox/libc/functions/stdio/fclose.c +++ /dev/null @@ -1,110 +0,0 @@ -/* fclose( FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" -#include - -extern FILE * _PDCLIB_filelist; - -int fclose( FILE * stream ) -{ - FILE * current = _PDCLIB_filelist; - FILE * previous = NULL; - /* Checking that the FILE handle is actually one we had opened before. */ - while ( current != NULL ) - { - if ( stream == current ) - { - /* Flush buffer */ - if ( stream->status & _PDCLIB_FWRITE ) - { - if ( _PDCLIB_flushbuffer( stream ) == EOF ) - { - /* Flush failed, errno already set */ - return EOF; - } - } - - /* Release mutex*/ - mtx_destroy( &stream->lock ); - - /* Close handle */ - stream->ops->close(stream->handle); - - /* Remove stream from list */ - if ( previous != NULL ) - { - previous->next = stream->next; - } - else - { - _PDCLIB_filelist = stream->next; - } - /* Delete tmpfile() */ - if ( stream->status & _PDCLIB_DELONCLOSE ) - { - remove( stream->filename ); - } - /* Free user buffer (SetVBuf allocated) */ - if ( stream->status & _PDCLIB_FREEBUFFER ) - { - free( stream->buffer ); - } - /* Free stream */ - if ( ! ( stream->status & _PDCLIB_STATIC ) ) - { - free( stream ); - } - return 0; - } - previous = current; - current = current->next; - } - - errno = EINVAL; - return -1; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ -#ifndef REGTEST - FILE * file1; - FILE * file2; - remove( testfile1 ); - remove( testfile2 ); - TESTCASE( _PDCLIB_filelist == stdin ); - TESTCASE( ( file1 = fopen( testfile1, "w" ) ) != NULL ); - TESTCASE( _PDCLIB_filelist == file1 ); - TESTCASE( ( file2 = fopen( testfile2, "w" ) ) != NULL ); - TESTCASE( _PDCLIB_filelist == file2 ); - TESTCASE( fclose( file2 ) == 0 ); - TESTCASE( _PDCLIB_filelist == file1 ); - TESTCASE( ( file2 = fopen( testfile2, "w" ) ) != NULL ); - TESTCASE( _PDCLIB_filelist == file2 ); - TESTCASE( fclose( file1 ) == 0 ); - TESTCASE( _PDCLIB_filelist == file2 ); - TESTCASE( fclose( file2 ) == 0 ); - TESTCASE( _PDCLIB_filelist == stdin ); - TESTCASE( remove( testfile1 ) == 0 ); - TESTCASE( remove( testfile2 ) == 0 ); -#else - puts( " NOTEST fclose() test driver is PDCLib-specific." ); -#endif - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/feof.c b/waterbox/libc/functions/stdio/feof.c deleted file mode 100644 index f5d0584658..0000000000 --- a/waterbox/libc/functions/stdio/feof.c +++ /dev/null @@ -1,37 +0,0 @@ -/* feof( FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_feof_unlocked( FILE * stream ) -{ - return stream->status & _PDCLIB_EOFFLAG; -} - -int feof( FILE * stream ) -{ - _PDCLIB_flockfile( stream ); - int eof = _PDCLIB_feof_unlocked( stream ); - _PDCLIB_funlockfile( stream ); - return eof; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by clearerr(). */ - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/ferror.c b/waterbox/libc/functions/stdio/ferror.c deleted file mode 100644 index 43fad2d8f6..0000000000 --- a/waterbox/libc/functions/stdio/ferror.c +++ /dev/null @@ -1,37 +0,0 @@ -/* ferror( FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_ferror_unlocked( FILE * stream ) -{ - return stream->status & _PDCLIB_ERRORFLAG; -} - -int ferror( FILE * stream ) -{ - _PDCLIB_flockfile( stream ); - int error = _PDCLIB_ferror_unlocked( stream ); - _PDCLIB_funlockfile( stream ); - return error; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by clearerr(). */ - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/fflush.c b/waterbox/libc/functions/stdio/fflush.c deleted file mode 100644 index 28793e3492..0000000000 --- a/waterbox/libc/functions/stdio/fflush.c +++ /dev/null @@ -1,60 +0,0 @@ -/* fflush( FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -extern FILE * _PDCLIB_filelist; - -int _PDCLIB_fflush_unlocked( FILE * stream ) -{ - if ( stream == NULL ) - { - stream = _PDCLIB_filelist; - /* TODO: Check what happens when fflush( NULL ) encounters write errors, in other libs */ - int rc = 0; - while ( stream != NULL ) - { - if ( stream->status & _PDCLIB_FWRITE ) - { - if ( _PDCLIB_flushbuffer( stream ) == EOF ) - { - rc = EOF; - } - } - stream = stream->next; - } - return rc; - } - else - { - return _PDCLIB_flushbuffer( stream ); - } -} - -int fflush( FILE * stream ) -{ - _PDCLIB_flockfile( stream ); - int res = _PDCLIB_fflush_unlocked(stream); - _PDCLIB_funlockfile( stream ); - return res; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by ftell.c */ - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/fgetc.c b/waterbox/libc/functions/stdio/fgetc.c deleted file mode 100644 index 0b042c7d5b..0000000000 --- a/waterbox/libc/functions/stdio/fgetc.c +++ /dev/null @@ -1,45 +0,0 @@ -/* fgetc( FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_fgetc_unlocked( FILE * stream ) -{ - if ( _PDCLIB_prepread( stream ) == EOF ) - { - return EOF; - } - - char c; - - size_t n = _PDCLIB_getchars( &c, 1, EOF, stream ); - - return n == 0 ? EOF : (unsigned char) c; -} - -int fgetc( FILE * stream ) -{ - _PDCLIB_flockfile( stream ); - int c = _PDCLIB_fgetc_unlocked( stream ); - _PDCLIB_funlockfile( stream ); - return c; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by ftell.c */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/fgetpos.c b/waterbox/libc/functions/stdio/fgetpos.c deleted file mode 100644 index ff88fba500..0000000000 --- a/waterbox/libc/functions/stdio/fgetpos.c +++ /dev/null @@ -1,51 +0,0 @@ -/* fgetpos( FILE * , fpos_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_fgetpos_unlocked( FILE * _PDCLIB_restrict stream, _PDCLIB_fpos_t * _PDCLIB_restrict pos ) -{ - pos->offset = stream->pos.offset + stream->bufidx - stream->ungetidx; - pos->mbs = stream->pos.mbs; - /* TODO: Add mbstate. */ - return 0; -} - -int fgetpos( FILE * _PDCLIB_restrict stream, _PDCLIB_fpos_t * _PDCLIB_restrict pos ) -{ - _PDCLIB_flockfile( stream ); - int res = _PDCLIB_fgetpos_unlocked( stream, pos ); - _PDCLIB_funlockfile( stream ); - return res; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -int main( void ) -{ - FILE * fh; - fpos_t pos1, pos2; - TESTCASE( ( fh = tmpfile() ) != NULL ); - TESTCASE( fgetpos( fh, &pos1 ) == 0 ); - TESTCASE( fwrite( teststring, 1, strlen( teststring ), fh ) == strlen( teststring ) ); - TESTCASE( (size_t)ftell( fh ) == strlen( teststring ) ); - TESTCASE( fgetpos( fh, &pos2 ) == 0 ); - TESTCASE( fsetpos( fh, &pos1 ) == 0 ); - TESTCASE( ftell( fh ) == 0 ); - TESTCASE( fsetpos( fh, &pos2 ) == 0 ); - TESTCASE( (size_t)ftell( fh ) == strlen( teststring ) ); - TESTCASE( fclose( fh ) == 0 ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/fgets.c b/waterbox/libc/functions/stdio/fgets.c deleted file mode 100644 index 8752892bed..0000000000 --- a/waterbox/libc/functions/stdio/fgets.c +++ /dev/null @@ -1,84 +0,0 @@ -/* fgets( char *, int, FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -char * _PDCLIB_fgets_unlocked( char * _PDCLIB_restrict s, int size, FILE * _PDCLIB_restrict stream ) -{ - if ( size == 0 ) - { - return NULL; - } - if ( size == 1 ) - { - *s = '\0'; - return s; - } - if ( _PDCLIB_prepread( stream ) == EOF ) - { - return NULL; - } - char * dest = s; - - dest += _PDCLIB_getchars( dest, size - 1, '\n', stream ); - - *dest = '\0'; - return ( dest == s ) ? NULL : s; -} - -char * fgets( char * _PDCLIB_restrict s, int size, - FILE * _PDCLIB_restrict stream ) -{ - _PDCLIB_flockfile( stream ); - char* r = _PDCLIB_fgets_unlocked( s, size, stream ); - _PDCLIB_funlockfile( stream ); - return r; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -int main( void ) -{ - FILE * fh; - char buffer[10]; - char const * fgets_test = "foo\nbar\0baz\nweenie"; - TESTCASE( ( fh = fopen( testfile, "wb+" ) ) != NULL ); - TESTCASE( fwrite( fgets_test, 1, 18, fh ) == 18 ); - rewind( fh ); - TESTCASE( fgets( buffer, 10, fh ) == buffer ); - TESTCASE( strcmp( buffer, "foo\n" ) == 0 ); - TESTCASE( fgets( buffer, 10, fh ) == buffer ); - TESTCASE( memcmp( buffer, "bar\0baz\n", 8 ) == 0 ); - TESTCASE( fgets( buffer, 10, fh ) == buffer ); - TESTCASE( strcmp( buffer, "weenie" ) == 0 ); - TESTCASE( feof( fh ) ); - TESTCASE( fseek( fh, -1, SEEK_END ) == 0 ); - TESTCASE( fgets( buffer, 1, fh ) == buffer ); - TESTCASE( strcmp( buffer, "" ) == 0 ); - TESTCASE( fgets( buffer, 0, fh ) == NULL ); - TESTCASE( ! feof( fh ) ); - TESTCASE( fgets( buffer, 1, fh ) == buffer ); - TESTCASE( strcmp( buffer, "" ) == 0 ); - TESTCASE( ! feof( fh ) ); - TESTCASE( fgets( buffer, 2, fh ) == buffer ); - TESTCASE( strcmp( buffer, "e" ) == 0 ); - TESTCASE( fseek( fh, 0, SEEK_END ) == 0 ); - TESTCASE( fgets( buffer, 2, fh ) == NULL ); - TESTCASE( feof( fh ) ); - TESTCASE( fclose( fh ) == 0 ); - TESTCASE( remove( testfile ) == 0 ); - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/flockfile.c b/waterbox/libc/functions/stdio/flockfile.c deleted file mode 100644 index 559f46abd3..0000000000 --- a/waterbox/libc/functions/stdio/flockfile.c +++ /dev/null @@ -1,33 +0,0 @@ -/* flockfile(FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" -#include -#include - -void _PDCLIB_flockfile( FILE * file ) -{ - if( mtx_lock( &file->lock ) != thrd_success ) { - abort(); - } -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - // Not tested here - tested by other stdio test drivers - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/fopen.c b/waterbox/libc/functions/stdio/fopen.c deleted file mode 100644 index 3d9f95ab1a..0000000000 --- a/waterbox/libc/functions/stdio/fopen.c +++ /dev/null @@ -1,67 +0,0 @@ -/* fopen( const char *, const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" -#include "_PDCLIB_glue.h" -#include -#include - -extern FILE * _PDCLIB_filelist; - -FILE * fopen( const char * _PDCLIB_restrict filename, - const char * _PDCLIB_restrict mode ) -{ - int imode = _PDCLIB_filemode( mode ); - - if( imode == 0 || filename == NULL ) - return NULL; - - _PDCLIB_fd_t fd; - const _PDCLIB_fileops_t * ops; - if(!_PDCLIB_open( &fd, &ops, filename, imode )) { - return NULL; - } - - FILE * f = _PDCLIB_fvopen( fd, ops, imode, filename ); - if(!f) { - int saveErrno = errno; - ops->close(fd); - errno = saveErrno; - } - return f; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Some of the tests are not executed for regression tests, as the libc on - my system is at once less forgiving (segfaults on mode NULL) and more - forgiving (accepts undefined modes). - */ - FILE * fh; - remove( testfile ); - TESTCASE_NOREG( fopen( NULL, NULL ) == NULL ); - TESTCASE( fopen( NULL, "w" ) == NULL ); - TESTCASE_NOREG( fopen( "", NULL ) == NULL ); - TESTCASE( fopen( "", "w" ) == NULL ); - TESTCASE( fopen( "foo", "" ) == NULL ); - TESTCASE_NOREG( fopen( testfile, "wq" ) == NULL ); /* Undefined mode */ - TESTCASE_NOREG( fopen( testfile, "wr" ) == NULL ); /* Undefined mode */ - TESTCASE( ( fh = fopen( testfile, "w" ) ) != NULL ); - TESTCASE( fclose( fh ) == 0 ); - TESTCASE( remove( testfile ) == 0 ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/fprintf.c b/waterbox/libc/functions/stdio/fprintf.c deleted file mode 100644 index 13eaf6b758..0000000000 --- a/waterbox/libc/functions/stdio/fprintf.c +++ /dev/null @@ -1,59 +0,0 @@ -/* fprintf( FILE *, const char *, ... ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_fprintf_unlocked( FILE * _PDCLIB_restrict stream, - const char * _PDCLIB_restrict format, ... ) -{ - int rc; - va_list ap; - va_start( ap, format ); - rc = _PDCLIB_vfprintf_unlocked( stream, format, ap ); - va_end( ap ); - return rc; -} - -int fprintf( FILE * _PDCLIB_restrict stream, - const char * _PDCLIB_restrict format, ... ) -{ - int rc; - va_list ap; - va_start( ap, format ); - _PDCLIB_flockfile( stream ); - rc = _PDCLIB_vfprintf_unlocked( stream, format, ap ); - _PDCLIB_funlockfile( stream ); - va_end( ap ); - return rc; -} - -#endif - -#ifdef TEST -#include -#include -#define _PDCLIB_FILEID "stdio/fprintf.c" -#define _PDCLIB_FILEIO - -#include "_PDCLIB_test.h" - -#define testprintf( stream, ... ) fprintf( stream, __VA_ARGS__ ) - -int main( void ) -{ - FILE * target; - TESTCASE( ( target = tmpfile() ) != NULL ); -#include "printf_testcases.h" - TESTCASE( fclose( target ) == 0 ); - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/fputc.c b/waterbox/libc/functions/stdio/fputc.c deleted file mode 100644 index 1252e6365a..0000000000 --- a/waterbox/libc/functions/stdio/fputc.c +++ /dev/null @@ -1,53 +0,0 @@ -/* fputc( int, FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -/* Write the value c (cast to unsigned char) to the given stream. - Returns c if successful, EOF otherwise. - If a write error occurs, the error indicator of the stream is set. -*/ -int _PDCLIB_fputc_unlocked( int c, FILE * stream ) -{ - if ( _PDCLIB_prepwrite( stream ) == EOF ) - { - return EOF; - } - stream->buffer[stream->bufidx++] = (char)c; - if ( ( stream->bufidx == stream->bufsize ) /* _IOFBF */ - || ( ( stream->status & _IOLBF ) && ( (char)c == '\n' ) ) /* _IOLBF */ - || ( stream->status & _IONBF ) /* _IONBF */ - ) - { - /* buffer filled, unbuffered stream, or end-of-line. */ - return ( _PDCLIB_flushbuffer( stream ) == 0 ) ? c : EOF; - } - return c; -} - -int fputc( int c, FILE * stream ) -{ - _PDCLIB_flockfile( stream ); - int r = _PDCLIB_fputc_unlocked( c, stream ); - _PDCLIB_funlockfile( stream ); - return r; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by ftell.c */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/fputs.c b/waterbox/libc/functions/stdio/fputs.c deleted file mode 100644 index 9bd0b5c5d6..0000000000 --- a/waterbox/libc/functions/stdio/fputs.c +++ /dev/null @@ -1,76 +0,0 @@ -/* fputs( const char *, FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_fputs_unlocked( const char * _PDCLIB_restrict s, - FILE * _PDCLIB_restrict stream ) -{ - if ( _PDCLIB_prepwrite( stream ) == EOF ) - { - return EOF; - } - while ( *s != '\0' ) - { - /* Unbuffered and line buffered streams get flushed when fputs() does - write the terminating end-of-line. All streams get flushed if the - buffer runs full. - */ - stream->buffer[ stream->bufidx++ ] = *s; - if ( ( stream->bufidx == stream->bufsize ) || - ( ( stream->status & _IOLBF ) && *s == '\n' ) - ) - { - if ( _PDCLIB_flushbuffer( stream ) == EOF ) - { - return EOF; - } - } - ++s; - } - if ( stream->status & _IONBF ) - { - if ( _PDCLIB_flushbuffer( stream ) == EOF ) - { - return EOF; - } - } - return 0; -} - -int fputs( const char * _PDCLIB_restrict s, - FILE * _PDCLIB_restrict stream ) -{ - _PDCLIB_flockfile( stream ); - int r = _PDCLIB_fputs_unlocked( s, stream ); - _PDCLIB_funlockfile( stream ); - return r; -} - -#endif -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char const * const message = "SUCCESS testing fputs()"; - FILE * fh; - TESTCASE( ( fh = tmpfile() ) != NULL ); - TESTCASE( fputs( message, fh ) >= 0 ); - rewind( fh ); - for ( size_t i = 0; i < 23; ++i ) - { - TESTCASE( fgetc( fh ) == message[i] ); - } - TESTCASE( fclose( fh ) == 0 ); - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/fread.c b/waterbox/libc/functions/stdio/fread.c deleted file mode 100644 index bf3185c4cf..0000000000 --- a/waterbox/libc/functions/stdio/fread.c +++ /dev/null @@ -1,87 +0,0 @@ -/* fwrite( void *, size_t, size_t, FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -#include -#include - -size_t _PDCLIB_fread_unlocked( - void * _PDCLIB_restrict ptr, - size_t size, size_t nmemb, - FILE * _PDCLIB_restrict stream -) -{ - if ( _PDCLIB_prepread( stream ) == EOF ) - { - return 0; - } - char * dest = (char *)ptr; - size_t nmemb_i; - for ( nmemb_i = 0; nmemb_i < nmemb; ++nmemb_i ) - { - size_t numread = _PDCLIB_getchars( &dest[ nmemb_i * size ], size, EOF, - stream ); - if( numread != size ) - break; - } - return nmemb_i; -} - -size_t fread( void * _PDCLIB_restrict ptr, - size_t size, size_t nmemb, - FILE * _PDCLIB_restrict stream ) -{ - _PDCLIB_flockfile( stream ); - size_t r = _PDCLIB_fread_unlocked( ptr, size, nmemb, stream ); - _PDCLIB_funlockfile( stream ); - return r; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - FILE * fh; - char const * message = "Testing fwrite()...\n"; - char buffer[21]; - buffer[20] = 'x'; - TESTCASE( ( fh = tmpfile() ) != NULL ); - /* fwrite() / readback */ - TESTCASE( fwrite( message, 1, 20, fh ) == 20 ); - rewind( fh ); - TESTCASE( fread( buffer, 1, 20, fh ) == 20 ); - TESTCASE( memcmp( buffer, message, 20 ) == 0 ); - TESTCASE( buffer[20] == 'x' ); - /* same, different nmemb / size settings */ - rewind( fh ); - TESTCASE( memset( buffer, '\0', 20 ) == buffer ); - TESTCASE( fwrite( message, 5, 4, fh ) == 4 ); - rewind( fh ); - TESTCASE( fread( buffer, 5, 4, fh ) == 4 ); - TESTCASE( memcmp( buffer, message, 20 ) == 0 ); - TESTCASE( buffer[20] == 'x' ); - /* same... */ - rewind( fh ); - TESTCASE( memset( buffer, '\0', 20 ) == buffer ); - TESTCASE( fwrite( message, 20, 1, fh ) == 1 ); - rewind( fh ); - TESTCASE( fread( buffer, 20, 1, fh ) == 1 ); - TESTCASE( memcmp( buffer, message, 20 ) == 0 ); - TESTCASE( buffer[20] == 'x' ); - /* Done. */ - TESTCASE( fclose( fh ) == 0 ); - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/freopen.c b/waterbox/libc/functions/stdio/freopen.c deleted file mode 100644 index d647d32033..0000000000 --- a/waterbox/libc/functions/stdio/freopen.c +++ /dev/null @@ -1,120 +0,0 @@ -/* freopen( const char *, const char *, FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" -#include "_PDCLIB_glue.h" -#include -#include - -FILE * freopen( - const char * _PDCLIB_restrict filename, - const char * _PDCLIB_restrict mode, - FILE * _PDCLIB_restrict stream -) -{ - _PDCLIB_flockfile( stream ); - - unsigned int status = stream->status & - ( _IONBF | _IOLBF | _IOFBF | _PDCLIB_FREEBUFFER - | _PDCLIB_DELONCLOSE | _PDCLIB_STATIC ); - - /* TODO: This function can change wide orientation of a stream */ - if ( stream->status & _PDCLIB_FWRITE ) - { - _PDCLIB_flushbuffer( stream ); - } - if ( ( filename == NULL ) && ( stream->filename == NULL ) ) - { - /* TODO: Special handling for mode changes on std-streams */ - _PDCLIB_funlockfile( stream ); - return NULL; - } - stream->ops->close(stream->handle); - - /* TODO: It is not nice to do this on a stream we just closed. - It does not matter with the current implementation of clearerr(), - but it might start to matter if someone replaced that implementation. - */ - _PDCLIB_clearerr_unlocked( stream ); - /* The new filename might not fit the old buffer */ - if ( filename == NULL ) - { - /* Use previous filename */ - filename = stream->filename; - } - else if ( ( stream->filename != NULL ) && ( strlen( stream->filename ) >= strlen( filename ) ) ) - { - /* Copy new filename into existing buffer */ - strcpy( stream->filename, filename ); - } - else - { - /* Allocate new buffer */ - if ( ( stream->filename = (char *)malloc( strlen( filename ) ) ) == NULL ) - { - _PDCLIB_funlockfile( stream ); - return NULL; - } - strcpy( stream->filename, filename ); - } - if ( ( mode == NULL ) || ( filename[0] == '\0' ) ) - { - _PDCLIB_funlockfile( stream ); - return NULL; - } - if ( ( stream->status = _PDCLIB_filemode( mode ) ) == 0 ) - { - _PDCLIB_funlockfile( stream ); - return NULL; - } - /* Re-add the flags we saved above */ - stream->status |= status; - stream->bufidx = 0; - stream->bufend = 0; - stream->ungetidx = 0; - /* TODO: Setting mbstate */ - if ( ! _PDCLIB_open( &stream->handle, &stream->ops, filename, - stream->status ) ) - { - _PDCLIB_funlockfile( stream ); - return NULL; - } - _PDCLIB_funlockfile( stream ); - return stream; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - FILE * fin; - FILE * fout; - TESTCASE( ( fin = fopen( testfile1, "wb+" ) ) != NULL ); - TESTCASE( fputc( 'x', fin ) == 'x' ); - TESTCASE( fclose( fin ) == 0 ); - TESTCASE( ( fin = freopen( testfile1, "rb", stdin ) ) != NULL ); - TESTCASE( getchar() == 'x' ); - - TESTCASE( ( fout = freopen( testfile2, "wb+", stdout ) ) != NULL ); - TESTCASE( putchar( 'x' ) == 'x' ); - rewind( fout ); - TESTCASE( fgetc( fout ) == 'x' ); - - TESTCASE( fclose( fin ) == 0 ); - TESTCASE( fclose( fout ) == 0 ); - TESTCASE( remove( testfile1 ) == 0 ); - TESTCASE( remove( testfile2 ) == 0 ); - - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/fscanf.c b/waterbox/libc/functions/stdio/fscanf.c deleted file mode 100644 index 9bb775ffc6..0000000000 --- a/waterbox/libc/functions/stdio/fscanf.c +++ /dev/null @@ -1,54 +0,0 @@ -/* fscanf( FILE *, const char *, ... ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_fscanf_unlocked( FILE * _PDCLIB_restrict stream, - const char * _PDCLIB_restrict format, ... ) -{ - int rc; - va_list ap; - va_start( ap, format ); - rc = _PDCLIB_vfscanf_unlocked( stream, format, ap ); - va_end( ap ); - return rc; -} - -int fscanf( FILE * _PDCLIB_restrict stream, - const char * _PDCLIB_restrict format, ... ) -{ - int rc; - va_list ap; - va_start( ap, format ); - rc = vfscanf( stream, format, ap ); - va_end( ap ); - return rc; -} - -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "stdio/fscanf.c" -#define _PDCLIB_FILEIO - -#include "_PDCLIB_test.h" - -#define testscanf( stream, format, ... ) fscanf( stream, format, __VA_ARGS__ ) - -int main( void ) -{ - FILE * source; - TESTCASE( ( source = tmpfile() ) != NULL ); -#include "scanf_testcases.h" - TESTCASE( fclose( source ) == 0 ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/fseek.c b/waterbox/libc/functions/stdio/fseek.c deleted file mode 100644 index a24a608b7c..0000000000 --- a/waterbox/libc/functions/stdio/fseek.c +++ /dev/null @@ -1,109 +0,0 @@ -/* fseek( FILE *, long, int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_fseek_unlocked( FILE * stream, long loffset, int whence ) -{ - _PDCLIB_int64_t offset = loffset; - if ( stream->status & _PDCLIB_FWRITE ) - { - if ( _PDCLIB_flushbuffer( stream ) == EOF ) - { - return EOF; - } - } - stream->status &= ~ _PDCLIB_EOFFLAG; - if ( stream->status & _PDCLIB_FRW ) - { - stream->status &= ~ ( _PDCLIB_FREAD | _PDCLIB_FWRITE ); - } - - if ( whence == SEEK_CUR ) - { - whence = SEEK_SET; - offset += _PDCLIB_ftell64_unlocked( stream ); - } - - return ( _PDCLIB_seek( stream, offset, whence ) != EOF ) ? 0 : EOF; -} - -int fseek( FILE * stream, long loffset, int whence ) -{ - _PDCLIB_flockfile( stream ); - int r = _PDCLIB_fseek_unlocked( stream, loffset, whence ); - _PDCLIB_funlockfile( stream ); - return r; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -int main( void ) -{ - FILE * fh; - TESTCASE( ( fh = tmpfile() ) != NULL ); - TESTCASE( fwrite( teststring, 1, strlen( teststring ), fh ) == strlen( teststring ) ); - /* General functionality */ - TESTCASE( fseek( fh, -1, SEEK_END ) == 0 ); - TESTCASE( (size_t)ftell( fh ) == strlen( teststring ) - 1 ); - TESTCASE( fseek( fh, 0, SEEK_END ) == 0 ); - TESTCASE( (size_t)ftell( fh ) == strlen( teststring ) ); - TESTCASE( fseek( fh, 0, SEEK_SET ) == 0 ); - TESTCASE( ftell( fh ) == 0 ); - TESTCASE( fseek( fh, 5, SEEK_CUR ) == 0 ); - TESTCASE( ftell( fh ) == 5 ); - TESTCASE( fseek( fh, -3, SEEK_CUR ) == 0 ); - TESTCASE( ftell( fh ) == 2 ); - /* Checking behaviour around EOF */ - TESTCASE( fseek( fh, 0, SEEK_END ) == 0 ); - TESTCASE( ! feof( fh ) ); - TESTCASE( fgetc( fh ) == EOF ); - TESTCASE( feof( fh ) ); - TESTCASE( fseek( fh, 0, SEEK_END ) == 0 ); - TESTCASE( ! feof( fh ) ); - /* Checking undo of ungetc() */ - TESTCASE( fseek( fh, 0, SEEK_SET ) == 0 ); - TESTCASE( fgetc( fh ) == teststring[0] ); - TESTCASE( fgetc( fh ) == teststring[1] ); - TESTCASE( fgetc( fh ) == teststring[2] ); - TESTCASE( ftell( fh ) == 3 ); - TESTCASE( ungetc( teststring[2], fh ) == teststring[2] ); - TESTCASE( ftell( fh ) == 2 ); - TESTCASE( fgetc( fh ) == teststring[2] ); - TESTCASE( ftell( fh ) == 3 ); - TESTCASE( ungetc( 'x', fh ) == 'x' ); - TESTCASE( ftell( fh ) == 2 ); - TESTCASE( fgetc( fh ) == 'x' ); - TESTCASE( ungetc( 'x', fh ) == 'x' ); - TESTCASE( ftell( fh ) == 2 ); - TESTCASE( fseek( fh, 2, SEEK_SET ) == 0 ); - TESTCASE( fgetc( fh ) == teststring[2] ); - /* PDCLIB-7: Check that we handle the underlying file descriptor correctly - * in the SEEK_CUR case */ - TESTCASE( fseek( fh, 10, SEEK_SET ) == 0 ); - TESTCASE( ftell( fh ) == 10l ); - TESTCASE( fseek( fh, 0, SEEK_CUR ) == 0 ); - TESTCASE( ftell( fh ) == 10l ); - TESTCASE( fseek( fh, 2, SEEK_CUR ) == 0 ); - TESTCASE( ftell( fh ) == 12l ); - TESTCASE( fseek( fh, -1, SEEK_CUR ) == 0 ); - TESTCASE( ftell( fh ) == 11l ); - /* Checking error handling */ - TESTCASE( fseek( fh, -5, SEEK_SET ) == -1 ); - TESTCASE( fseek( fh, 0, SEEK_END ) == 0 ); - TESTCASE( fclose( fh ) == 0 ); - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/fsetpos.c b/waterbox/libc/functions/stdio/fsetpos.c deleted file mode 100644 index e28b2b1af6..0000000000 --- a/waterbox/libc/functions/stdio/fsetpos.c +++ /dev/null @@ -1,51 +0,0 @@ -/* fsetpos( FILE *, const fpos_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_fsetpos_unlocked( FILE * stream, - const _PDCLIB_fpos_t * pos ) -{ - if ( stream->status & _PDCLIB_FWRITE ) - { - if ( _PDCLIB_flushbuffer( stream ) == EOF ) - { - return EOF; - } - } - if ( _PDCLIB_seek( stream, pos->offset, SEEK_SET ) == EOF ) - { - return EOF; - } - stream->pos.mbs = pos->mbs; - - return 0; -} - -int fsetpos( FILE * stream, - const _PDCLIB_fpos_t * pos ) -{ - _PDCLIB_flockfile( stream ); - int res = _PDCLIB_fsetpos_unlocked( stream, pos ); - _PDCLIB_funlockfile( stream ); - return res; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* fsetpos() tested together with fsetpos(). */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/ftell.c b/waterbox/libc/functions/stdio/ftell.c deleted file mode 100644 index 9731e33368..0000000000 --- a/waterbox/libc/functions/stdio/ftell.c +++ /dev/null @@ -1,96 +0,0 @@ -/* ftell( FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -long int _PDCLIB_ftell_unlocked( FILE * stream ) -{ - uint_fast64_t off64 = _PDCLIB_ftell64_unlocked( stream ); - - if ( off64 > LONG_MAX ) - { - /* integer overflow */ - errno = ERANGE; - return -1; - } - return off64; -} - -long int ftell( FILE * stream ) -{ - _PDCLIB_flockfile( stream ); - long int off = _PDCLIB_ftell_unlocked( stream ); - _PDCLIB_funlockfile( stream ); - return off; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include -#ifndef REGTEST -#include "_PDCLIB_io.h" -#endif - -int main( void ) -{ - /* Testing all the basic I/O functions individually would result in lots - of duplicated code, so I took the liberty of lumping it all together - here. - */ - /* The following functions delegate their tests to here: - fgetc fflush rewind fputc ungetc fseek - flushbuffer seek fillbuffer prepread prepwrite - */ - char * buffer = (char*)malloc( 4 ); - FILE * fh; - TESTCASE( ( fh = tmpfile() ) != NULL ); - TESTCASE( setvbuf( fh, buffer, _IOLBF, 4 ) == 0 ); - /* Testing ungetc() at offset 0 */ - rewind( fh ); - TESTCASE( ungetc( 'x', fh ) == 'x' ); - TESTCASE( ftell( fh ) == -1l ); - rewind( fh ); - TESTCASE( ftell( fh ) == 0l ); - /* Commence "normal" tests */ - TESTCASE( fputc( '1', fh ) == '1' ); - TESTCASE( fputc( '2', fh ) == '2' ); - TESTCASE( fputc( '3', fh ) == '3' ); - /* Positions incrementing as expected? */ - TESTCASE( ftell( fh ) == 3l ); - TESTCASE_NOREG( fh->pos.offset == 0l ); - TESTCASE_NOREG( fh->bufidx == 3l ); - /* Buffer properly flushed when full? */ - TESTCASE( fputc( '4', fh ) == '4' ); - TESTCASE_NOREG( fh->pos.offset == 4l ); - TESTCASE_NOREG( fh->bufidx == 0 ); - /* fflush() resetting positions as expected? */ - TESTCASE( fputc( '5', fh ) == '5' ); - TESTCASE( fflush( fh ) == 0 ); - TESTCASE( ftell( fh ) == 5l ); - TESTCASE_NOREG( fh->pos.offset == 5l ); - TESTCASE_NOREG( fh->bufidx == 0l ); - /* rewind() resetting positions as expected? */ - rewind( fh ); - TESTCASE( ftell( fh ) == 0l ); - TESTCASE_NOREG( fh->pos.offset == 0 ); - TESTCASE_NOREG( fh->bufidx == 0 ); - /* Reading back first character after rewind for basic read check */ - TESTCASE( fgetc( fh ) == '1' ); - /* TODO: t.b.c. */ - TESTCASE( fclose( fh ) == 0 ); - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/ftrylockfile.c b/waterbox/libc/functions/stdio/ftrylockfile.c deleted file mode 100644 index efb67199be..0000000000 --- a/waterbox/libc/functions/stdio/ftrylockfile.c +++ /dev/null @@ -1,40 +0,0 @@ -/* ftrylockfile( FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" -#include -#include - -int _PDCLIB_ftrylockfile( FILE * file ) -{ - int res = mtx_trylock( &file->lock ); - switch(res) { - case thrd_success: - return 0; - case thrd_busy: - return 1; - - default: - abort(); - } -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - // Not tested here - tested by other stdio test drivers - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/funlockfile.c b/waterbox/libc/functions/stdio/funlockfile.c deleted file mode 100644 index 98a375c971..0000000000 --- a/waterbox/libc/functions/stdio/funlockfile.c +++ /dev/null @@ -1,38 +0,0 @@ -/* funlockfile( FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" -#include -#include - -void _PDCLIB_funlockfile( FILE * file ) -{ - int res = mtx_unlock( &file->lock ); - switch(res) { - case thrd_success: - return; - - default: - abort(); - } -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - // Not tested here - tested by other stdio test drivers - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/fwrite.c b/waterbox/libc/functions/stdio/fwrite.c deleted file mode 100644 index 47da8e25a5..0000000000 --- a/waterbox/libc/functions/stdio/fwrite.c +++ /dev/null @@ -1,78 +0,0 @@ -/* fwrite( const void *, size_t, size_t, FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" -#include "_PDCLIB_glue.h" - -#include -#include - -size_t _PDCLIB_fwrite_unlocked( const void *restrict vptr, - size_t size, size_t nmemb, - FILE * _PDCLIB_restrict stream ) -{ - if ( _PDCLIB_prepwrite( stream ) == EOF ) - { - return 0; - } - - const char *restrict ptr = vptr; - size_t nmemb_i; - for ( nmemb_i = 0; nmemb_i < nmemb; ++nmemb_i ) - { - for ( size_t size_i = 0; size_i < size; ++size_i ) - { - char c = ptr[ nmemb_i * size + size_i ]; - stream->buffer[ stream->bufidx++ ] = c; - - if ( stream->bufidx == stream->bufsize || ( c == '\n' && stream->status & _IOLBF ) ) - { - if ( _PDCLIB_flushbuffer( stream ) == EOF ) - { - /* Returning number of objects completely buffered */ - return nmemb_i; - } - } - } - - if ( stream->status & _IONBF ) - { - if ( _PDCLIB_flushbuffer( stream ) == EOF ) - { - /* Returning number of objects completely buffered */ - return nmemb_i; - } - } - } - return nmemb_i; -} - -size_t fwrite( const void * _PDCLIB_restrict ptr, - size_t size, size_t nmemb, - FILE * _PDCLIB_restrict stream ) -{ - _PDCLIB_flockfile( stream ); - size_t r = _PDCLIB_fwrite_unlocked( ptr, size, nmemb, stream ); - _PDCLIB_funlockfile( stream ); - return r; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by fread(). */ - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/getc.c b/waterbox/libc/functions/stdio/getc.c deleted file mode 100644 index 7a2a900d32..0000000000 --- a/waterbox/libc/functions/stdio/getc.c +++ /dev/null @@ -1,33 +0,0 @@ -/* getc( FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_getc_unlocked( FILE * stream ) -{ - return _PDCLIB_fgetc_unlocked( stream ); -} - -int getc( FILE * stream ) -{ - return fgetc( stream ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by ftell.c */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/getchar.c b/waterbox/libc/functions/stdio/getchar.c deleted file mode 100644 index 4a6fe4d14a..0000000000 --- a/waterbox/libc/functions/stdio/getchar.c +++ /dev/null @@ -1,34 +0,0 @@ -/* getchar( void ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_getchar_unlocked( void ) -{ - return _PDCLIB_fgetc_unlocked( stdin ); -} - - -int getchar( void ) -{ - return fgetc( stdin ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by ftell.c */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/gets.c b/waterbox/libc/functions/stdio/gets.c deleted file mode 100644 index 2fb4cad9ea..0000000000 --- a/waterbox/libc/functions/stdio/gets.c +++ /dev/null @@ -1,71 +0,0 @@ -/* gets( char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" -#include - -char * gets( char * s ) -{ - _PDCLIB_flockfile( stdin ); - if ( _PDCLIB_prepread( stdin ) == EOF ) - { - _PDCLIB_funlockfile( stdin ); - return NULL; - } - char * dest = s; - - dest += _PDCLIB_getchars( dest, SIZE_MAX, '\n', stdin ); - _PDCLIB_funlockfile( stdin ); - - if(*(dest - 1) == '\n') { - *(--dest) = '\0'; - } else { - *dest = '\0'; - } - - return ( dest == s ) ? NULL : s; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -int main( void ) -{ -#ifndef REGTEST - FILE * fh; - char buffer[10]; - char const * gets_test = "foo\nbar\0baz\nweenie"; - TESTCASE( ( fh = fopen( testfile, "wb" ) ) != NULL ); - TESTCASE( fwrite( gets_test, 1, 18, fh ) == 18 ); - TESTCASE( fclose( fh ) == 0 ); - TESTCASE( ( fh = freopen( testfile, "rb", stdin ) ) != NULL ); - TESTCASE( gets( buffer ) == buffer ); - TESTCASE( strcmp( buffer, "foo" ) == 0 ); - TESTCASE( gets( buffer ) == buffer ); - TESTCASE( memcmp( buffer, "bar\0baz\0", 8 ) == 0 ); - TESTCASE( gets( buffer ) == buffer ); - TESTCASE( strcmp( buffer, "weenie" ) == 0 ); - TESTCASE( feof( fh ) ); - TESTCASE( fseek( fh, -1, SEEK_END ) == 0 ); - TESTCASE( gets( buffer ) == buffer ); - TESTCASE( strcmp( buffer, "e" ) == 0 ); - TESTCASE( feof( fh ) ); - TESTCASE( fseek( fh, 0, SEEK_END ) == 0 ); - TESTCASE( gets( buffer ) == NULL ); - TESTCASE( fclose( fh ) == 0 ); - TESTCASE( remove( testfile ) == 0 ); -#endif - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/perror.c b/waterbox/libc/functions/stdio/perror.c deleted file mode 100644 index 97b727f253..0000000000 --- a/waterbox/libc/functions/stdio/perror.c +++ /dev/null @@ -1,56 +0,0 @@ -/* perror( const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include -#include "_PDCLIB_locale.h" - -/* TODO: Doing this via a static array is not the way to do it. */ -void perror( const char * s ) -{ - if ( ( s != NULL ) && ( s[0] != '\n' ) ) - { - fprintf( stderr, "%s: ", s ); - } - if ( errno >= _PDCLIB_ERRNO_MAX ) - { - fprintf( stderr, "Unknown error\n" ); - } - else - { - fprintf( stderr, "%s\n", _PDCLIB_threadlocale()->_ErrnoStr[errno] ); - } - return; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include -#include -#include - -int main( void ) -{ - FILE * fh; - unsigned long long max = ULLONG_MAX; - char buffer[100]; - sprintf( buffer, "%llu", max ); - TESTCASE( ( fh = freopen( testfile, "wb+", stderr ) ) != NULL ); - TESTCASE( strtol( buffer, NULL, 10 ) == LONG_MAX ); - perror( "Test" ); - rewind( fh ); - TESTCASE( fread( buffer, 1, 7, fh ) == 7 ); - TESTCASE( memcmp( buffer, "Test: ", 6 ) == 0 ); - TESTCASE( fclose( fh ) == 0 ); - TESTCASE( remove( testfile ) == 0 ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/printf.c b/waterbox/libc/functions/stdio/printf.c deleted file mode 100644 index 8e31dcdcfd..0000000000 --- a/waterbox/libc/functions/stdio/printf.c +++ /dev/null @@ -1,55 +0,0 @@ -/* printf( const char *, ... ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int printf( const char * _PDCLIB_restrict format, ... ) -{ - int rc; - va_list ap; - va_start( ap, format ); - rc = vfprintf( stdout, format, ap ); - va_end( ap ); - return rc; -} - -int _PDCLIB_printf_unlocked( const char * _PDCLIB_restrict format, ... ) -{ - int rc; - va_list ap; - va_start( ap, format ); - rc = _PDCLIB_vfprintf_unlocked( stdout, format, ap ); - va_end( ap ); - return rc; -} - -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "stdio/printf.c" -#define _PDCLIB_FILEIO -#include -#include - -#include "_PDCLIB_test.h" - -#define testprintf( stream, ... ) printf( __VA_ARGS__ ) - -int main( void ) -{ - FILE * target; - TESTCASE( ( target = freopen( testfile, "wb+", stdout ) ) != NULL ); -#include "printf_testcases.h" - TESTCASE( fclose( target ) == 0 ); - TESTCASE( remove( testfile ) == 0 ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/putc.c b/waterbox/libc/functions/stdio/putc.c deleted file mode 100644 index 4017350fa5..0000000000 --- a/waterbox/libc/functions/stdio/putc.c +++ /dev/null @@ -1,34 +0,0 @@ -/* putc( int, FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_putc_unlocked( int c, FILE * stream ) -{ - return _PDCLIB_fputc_unlocked( c, stream ); -} - - -int putc( int c, FILE * stream ) -{ - return fputc( c, stream ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by ftell.c */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/putchar.c b/waterbox/libc/functions/stdio/putchar.c deleted file mode 100644 index 4e69047ffd..0000000000 --- a/waterbox/libc/functions/stdio/putchar.c +++ /dev/null @@ -1,33 +0,0 @@ -/* putchar( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_putchar_unlocked( int c ) -{ - return _PDCLIB_fputc_unlocked( c, stdout ); -} - -int putchar( int c ) -{ - return fputc( c, stdout ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by ftell.c */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/puts.c b/waterbox/libc/functions/stdio/puts.c deleted file mode 100644 index f0c5a7bbfd..0000000000 --- a/waterbox/libc/functions/stdio/puts.c +++ /dev/null @@ -1,74 +0,0 @@ -/* puts( const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -extern char * _PDCLIB_eol; - -int _PDCLIB_puts_unlocked( const char * s ) -{ - if ( _PDCLIB_prepwrite( stdout ) == EOF ) - { - return EOF; - } - while ( *s != '\0' ) - { - stdout->buffer[ stdout->bufidx++ ] = *s++; - if ( stdout->bufidx == stdout->bufsize ) - { - if ( _PDCLIB_flushbuffer( stdout ) == EOF ) - { - return EOF; - } - } - } - stdout->buffer[ stdout->bufidx++ ] = '\n'; - if ( ( stdout->bufidx == stdout->bufsize ) || - ( stdout->status & ( _IOLBF | _IONBF ) ) ) - { - return _PDCLIB_flushbuffer( stdout ); - } - else - { - return 0; - } -} - -int puts( const char * s ) -{ - _PDCLIB_flockfile( stdout ); - int r = _PDCLIB_puts_unlocked( s ); - _PDCLIB_funlockfile( stdout ); - return r; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - FILE * fh; - char const * message = "SUCCESS testing puts()"; - char buffer[23]; - buffer[22] = 'x'; - TESTCASE( ( fh = freopen( testfile, "wb+", stdout ) ) != NULL ); - TESTCASE( puts( message ) >= 0 ); - rewind( fh ); - TESTCASE( fread( buffer, 1, 22, fh ) == 22 ); - TESTCASE( memcmp( buffer, message, 22 ) == 0 ); - TESTCASE( buffer[22] == 'x' ); - TESTCASE( fclose( fh ) == 0 ); - TESTCASE( remove( testfile ) == 0 ); - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/remove.c b/waterbox/libc/functions/stdio/remove.c deleted file mode 100644 index 831d968617..0000000000 --- a/waterbox/libc/functions/stdio/remove.c +++ /dev/null @@ -1,37 +0,0 @@ -/* remove( const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -/* This is an example implementation of remove() fit for use with POSIX kernels. -*/ - -#include - -#ifndef REGTEST - -#include -#include - -extern struct _PDCLIB_file_t * _PDCLIB_filelist; - -int remove( const char * pathname ) -{ - errno = ENOTSUP; - return 1; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by ftell.c (and several others) */ - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/rename.c b/waterbox/libc/functions/stdio/rename.c deleted file mode 100644 index 0c30b1e78c..0000000000 --- a/waterbox/libc/functions/stdio/rename.c +++ /dev/null @@ -1,83 +0,0 @@ -/* rename( const char *, const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_glue.h" - -#include - -extern _PDCLIB_file_t * _PDCLIB_filelist; - -int rename( const char * old, const char * new ) -{ - FILE * current = _PDCLIB_filelist; - while ( current != NULL ) - { - if ( ( current->filename != NULL ) && ( strcmp( current->filename, old ) == 0 ) ) - { - /* File of that name currently open. Do not rename. */ - return EOF; - } - current = current->next; - } - return _PDCLIB_rename( old, new ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -#include - -int main( void ) -{ - FILE * file; - remove( testfile1 ); - remove( testfile2 ); - /* make sure that neither file exists */ - TESTCASE( fopen( testfile1, "r" ) == NULL ); - TESTCASE( fopen( testfile2, "r" ) == NULL ); - /* rename file 1 to file 2 - expected to fail */ - TESTCASE( rename( testfile1, testfile2 ) != 0 ); - /* create file 1 */ - TESTCASE( ( file = fopen( testfile1, "w" ) ) != NULL ); - TESTCASE( fputs( "x", file ) != EOF ); - TESTCASE( fclose( file ) == 0 ); - /* check that file 1 exists */ - TESTCASE( ( file = fopen( testfile1, "r" ) ) != NULL ); - TESTCASE( fclose( file ) == 0 ); - /* rename file 1 to file 2 */ - TESTCASE( rename( testfile1, testfile2 ) == 0 ); - /* check that file 2 exists, file 1 does not */ - TESTCASE( fopen( testfile1, "r" ) == NULL ); - TESTCASE( ( file = fopen( testfile2, "r" ) ) != NULL ); - TESTCASE( fclose( file ) == 0 ); - /* create another file 1 */ - TESTCASE( ( file = fopen( testfile1, "w" ) ) != NULL ); - TESTCASE( fputs( "x", file ) != EOF ); - TESTCASE( fclose( file ) == 0 ); - /* check that file 1 exists */ - TESTCASE( ( file = fopen( testfile1, "r" ) ) != NULL ); - TESTCASE( fclose( file ) == 0 ); - /* rename file 1 to file 2 - expected to fail, see comment in - _PDCLIB_rename() itself. - */ - /* NOREG as glibc overwrites existing destination file. */ - TESTCASE_NOREG( rename( testfile1, testfile2 ) != 0 ); - /* remove both files */ - TESTCASE( remove( testfile1 ) == 0 ); - TESTCASE( remove( testfile2 ) == 0 ); - /* check that they're gone */ - TESTCASE( fopen( testfile1, "r" ) == NULL ); - TESTCASE( fopen( testfile2, "r" ) == NULL ); - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/rewind.c b/waterbox/libc/functions/stdio/rewind.c deleted file mode 100644 index f50bf025b4..0000000000 --- a/waterbox/libc/functions/stdio/rewind.c +++ /dev/null @@ -1,36 +0,0 @@ -/* rewind( FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -void _PDCLIB_rewind_unlocked( FILE * stream ) -{ - stream->status &= ~ _PDCLIB_ERRORFLAG; - _PDCLIB_fseek_unlocked( stream, 0L, SEEK_SET ); -} - -void rewind( FILE * stream ) -{ - _PDCLIB_flockfile(stream); - _PDCLIB_rewind_unlocked(stream); - _PDCLIB_funlockfile(stream); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Testing covered by ftell.c */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/scanf.c b/waterbox/libc/functions/stdio/scanf.c deleted file mode 100644 index 8d0492ba06..0000000000 --- a/waterbox/libc/functions/stdio/scanf.c +++ /dev/null @@ -1,47 +0,0 @@ -/* scanf( const char *, ... ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_scanf_unlocked( const char * _PDCLIB_restrict format, ... ) -{ - va_list ap; - va_start( ap, format ); - return _PDCLIB_vfscanf_unlocked( stdin, format, ap ); -} - -int scanf( const char * _PDCLIB_restrict format, ... ) -{ - va_list ap; - va_start( ap, format ); - return vfscanf( stdin, format, ap ); -} - -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "stdio/scanf.c" -#define _PDCLIB_FILEIO - -#include "_PDCLIB_test.h" - -#define testscanf( stream, format, ... ) scanf( format, __VA_ARGS__ ) - -int main( void ) -{ - FILE * source; - TESTCASE( ( source = freopen( testfile, "wb+", stdin ) ) != NULL ); -#include "scanf_testcases.h" - TESTCASE( fclose( source ) == 0 ); - TESTCASE( remove( testfile ) == 0 ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/setbuf.c b/waterbox/libc/functions/stdio/setbuf.c deleted file mode 100644 index 749ddc9d2a..0000000000 --- a/waterbox/libc/functions/stdio/setbuf.c +++ /dev/null @@ -1,56 +0,0 @@ -/* setbuf( FILE *, char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -void setbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf ) -{ - if ( buf == NULL ) - { - setvbuf( stream, buf, _IONBF, BUFSIZ ); - } - else - { - setvbuf( stream, buf, _IOFBF, BUFSIZ ); - } -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include -#ifndef REGTEST -#include "_PDCLIB_io.h" -#endif - -int main( void ) -{ - /* TODO: Extend testing once setvbuf() is finished. */ -#ifndef REGTEST - char buffer[ BUFSIZ + 1 ]; - FILE * fh; - /* full buffered */ - TESTCASE( ( fh = tmpfile() ) != NULL ); - setbuf( fh, buffer ); - TESTCASE( fh->buffer == buffer ); - TESTCASE( fh->bufsize == BUFSIZ ); - TESTCASE( ( fh->status & ( _IOFBF | _IONBF | _IOLBF ) ) == _IOFBF ); - TESTCASE( fclose( fh ) == 0 ); - /* not buffered */ - TESTCASE( ( fh = tmpfile() ) != NULL ); - setbuf( fh, NULL ); - TESTCASE( ( fh->status & ( _IOFBF | _IONBF | _IOLBF ) ) == _IONBF ); - TESTCASE( fclose( fh ) == 0 ); -#else - puts( " NOTEST setbuf() test driver is PDCLib-specific." ); -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/setvbuf.c b/waterbox/libc/functions/stdio/setvbuf.c deleted file mode 100644 index 288211baef..0000000000 --- a/waterbox/libc/functions/stdio/setvbuf.c +++ /dev/null @@ -1,115 +0,0 @@ -/* setvbuf( FILE *, char *, int, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int setvbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf, int mode, size_t size ) -{ - _PDCLIB_flockfile( stream ); - switch ( mode ) - { - case _IONBF: - /* When unbuffered I/O is requested, we keep the buffer anyway, as - we don't want to e.g. flush the stream for every character of a - stream being printed. - */ - break; - case _IOFBF: - case _IOLBF: - if ( size > INT_MAX || size == 0 ) - { - /* PDCLib only supports buffers up to INT_MAX in size. A size - of zero doesn't make sense. - */ - _PDCLIB_funlockfile( stream ); - return -1; - } - if ( buf == NULL ) - { - /* User requested buffer size, but leaves it to library to - allocate the buffer. - */ - /* If current buffer is big enough for requested size, but not - over twice as big (and wasting memory space), we use the - current buffer (i.e., do nothing), to save the malloc() / - free() overhead. - */ - if ( ( stream->bufsize < size ) || ( stream->bufsize > ( size << 1 ) ) ) - { - /* Buffer too small, or much too large - allocate. */ - if ( ( buf = (char *) malloc( size ) ) == NULL ) - { - /* Out of memory error. */ - _PDCLIB_funlockfile( stream ); - return -1; - } - /* This buffer must be free()d on fclose() */ - stream->status |= _PDCLIB_FREEBUFFER; - } - } - stream->buffer = buf; - stream->bufsize = size; - break; - default: - /* If mode is something else than _IOFBF, _IOLBF or _IONBF -> exit */ - _PDCLIB_funlockfile( stream ); - return -1; - } - /* Deleting current buffer mode */ - stream->status &= ~( _IOFBF | _IOLBF | _IONBF ); - /* Set user-defined mode */ - stream->status |= mode; - _PDCLIB_funlockfile( stream ); - return 0; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include -#ifndef REGTEST -#include "_PDCLIB_io.h" -#endif -#define BUFFERSIZE 500 - -int main( void ) -{ -#ifndef REGTEST - char buffer[ BUFFERSIZE ]; - FILE * fh; - /* full buffered, user-supplied buffer */ - TESTCASE( ( fh = tmpfile() ) != NULL ); - TESTCASE( setvbuf( fh, buffer, _IOFBF, BUFFERSIZE ) == 0 ); - TESTCASE( fh->buffer == buffer ); - TESTCASE( fh->bufsize == BUFFERSIZE ); - TESTCASE( ( fh->status & ( _IOFBF | _IONBF | _IOLBF ) ) == _IOFBF ); - TESTCASE( fclose( fh ) == 0 ); - /* line buffered, lib-supplied buffer */ - TESTCASE( ( fh = tmpfile() ) != NULL ); - TESTCASE( setvbuf( fh, NULL, _IOLBF, BUFFERSIZE ) == 0 ); - TESTCASE( fh->buffer != NULL ); - TESTCASE( fh->bufsize == BUFFERSIZE ); - TESTCASE( ( fh->status & ( _IOFBF | _IONBF | _IOLBF ) ) == _IOLBF ); - TESTCASE( fclose( fh ) == 0 ); - /* not buffered, user-supplied buffer */ - TESTCASE( ( fh = tmpfile() ) != NULL ); - TESTCASE( setvbuf( fh, buffer, _IONBF, BUFFERSIZE ) == 0 ); - TESTCASE( ( fh->status & ( _IOFBF | _IONBF | _IOLBF ) ) == _IONBF ); - TESTCASE( fclose( fh ) == 0 ); -#else - puts( " NOTEST setvbuf() test driver is PDCLib-specific." ); -#endif - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/snprintf.c b/waterbox/libc/functions/stdio/snprintf.c deleted file mode 100644 index f095b8cb48..0000000000 --- a/waterbox/libc/functions/stdio/snprintf.c +++ /dev/null @@ -1,43 +0,0 @@ -/* snprintf( char *, size_t, const char *, ... ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST - -int snprintf( char * _PDCLIB_restrict s, size_t n, const char * _PDCLIB_restrict format, ...) -{ - int rc; - va_list ap; - va_start( ap, format ); - rc = vsnprintf( s, n, format, ap ); - va_end( ap ); - return rc; -} - -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "stdio/snprintf.c" -#define _PDCLIB_STRINGIO -#include -#include - -#include "_PDCLIB_test.h" - -#define testprintf( s, ... ) snprintf( s, 100, __VA_ARGS__ ) - -int main( void ) -{ - char target[100]; -#include "printf_testcases.h" - TESTCASE( snprintf( NULL, 0, "foo" ) == 3 ); - TESTCASE( snprintf( NULL, 0, "%d", 100 ) == 3 ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/sprintf.c b/waterbox/libc/functions/stdio/sprintf.c deleted file mode 100644 index ce3a7ff105..0000000000 --- a/waterbox/libc/functions/stdio/sprintf.c +++ /dev/null @@ -1,41 +0,0 @@ -/* sprintf( char *, const char *, ... ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include - -#ifndef REGTEST - -int sprintf( char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ...) -{ - int rc; - va_list ap; - va_start( ap, format ); - rc = vsnprintf( s, SIZE_MAX, format, ap ); /* TODO: replace with non-checking call */ - va_end( ap ); - return rc; -} - -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "stdio/sprintf.c" -#define _PDCLIB_STRINGIO -#include - -#include "_PDCLIB_test.h" - -#define testprintf( s, ... ) sprintf( s, __VA_ARGS__ ) - -int main( void ) -{ - char target[100]; -#include "printf_testcases.h" - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/sscanf.c b/waterbox/libc/functions/stdio/sscanf.c deleted file mode 100644 index 5de77ae45c..0000000000 --- a/waterbox/libc/functions/stdio/sscanf.c +++ /dev/null @@ -1,40 +0,0 @@ -/* sscanf( const char *, const char *, ... ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST - -int sscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ... ) -{ - int rc; - va_list ap; - va_start( ap, format ); - rc = vsscanf( s, format, ap ); - va_end( ap ); - return rc; -} - -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "stdio/sscanf.c" -#define _PDCLIB_STRINGIO - -#include "_PDCLIB_test.h" - -#define testscanf( s, format, ... ) sscanf( s, format, __VA_ARGS__ ) - -int main( void ) -{ - char source[100]; -#include "scanf_testcases.h" - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/testfile.txt b/waterbox/libc/functions/stdio/testfile.txt deleted file mode 100644 index 62f1825430..0000000000 Binary files a/waterbox/libc/functions/stdio/testfile.txt and /dev/null differ diff --git a/waterbox/libc/functions/stdio/tmpfile.c b/waterbox/libc/functions/stdio/tmpfile.c deleted file mode 100644 index 78273422d5..0000000000 --- a/waterbox/libc/functions/stdio/tmpfile.c +++ /dev/null @@ -1,34 +0,0 @@ -/* tmpfile( void ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -#include -#include "_PDCLIB_glue.h" - -/* This is a stub implementation of tmpfile -*/ -FILE* tmpfile( void ) -{ - errno = ENOTSUP; - return NULL; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/tmpnam.c b/waterbox/libc/functions/stdio/tmpnam.c deleted file mode 100644 index 6e8641d380..0000000000 --- a/waterbox/libc/functions/stdio/tmpnam.c +++ /dev/null @@ -1,41 +0,0 @@ -/* tmpnam( char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -#include -#include "_PDCLIB_io.h" - -char * tmpnam( char * s ) -{ - static char filename[ L_tmpnam ]; - FILE * file = tmpfile(); - if ( s == NULL ) - { - s = filename; - } - strcpy( s, file->filename ); - fclose( file ); - return s; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -#include - -int main( void ) -{ - TESTCASE( strlen( tmpnam( NULL ) ) < L_tmpnam ); - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/ungetc.c b/waterbox/libc/functions/stdio/ungetc.c deleted file mode 100644 index 560099d4e2..0000000000 --- a/waterbox/libc/functions/stdio/ungetc.c +++ /dev/null @@ -1,67 +0,0 @@ -/* ungetc( int, FILE * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_ungetc_unlocked( int c, FILE * stream ) -{ - if ( c == EOF || stream->ungetidx == _PDCLIB_UNGETCBUFSIZE ) - { - return -1; - } - return stream->ungetbuf[stream->ungetidx++] = (unsigned char) c; -} - -int ungetc( int c, FILE * stream ) -{ - _PDCLIB_flockfile( stream ); - int r = _PDCLIB_ungetc_unlocked( c, stream ); - _PDCLIB_funlockfile( stream); - return r; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -const char* hellostr = "Hello, world!"; - -int main( void ) -{ - // Also see ftell() for some testing - - // PDCLIB-18: fread ignores ungetc - size_t bufsz = strlen( hellostr ) + 1; - char * buf = malloc( bufsz ); - FILE * fh; - - // Also fgets - TESTCASE( ( fh = tmpfile() ) != NULL ); - TESTCASE( fputs(hellostr, fh) == 0 ); - rewind(fh); - TESTCASE( fgetc( fh ) == 'H' ); - TESTCASE( ungetc( 'H', fh ) == 'H' ); - TESTCASE( fgets( buf, bufsz, fh ) != NULL ); - TESTCASE( strcmp( buf, hellostr ) == 0 ); - - // fread - rewind(fh); - TESTCASE( fgetc( fh ) == 'H' ); - TESTCASE( ungetc( 'H', fh ) == 'H' ); - TESTCASE( fread( buf, bufsz - 1, 1, fh ) == 1 ); - TESTCASE( strncmp( buf, hellostr, bufsz - 1 ) == 0 ); - - - - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/vasprintf.c b/waterbox/libc/functions/stdio/vasprintf.c deleted file mode 100644 index 96bbe17f51..0000000000 --- a/waterbox/libc/functions/stdio/vasprintf.c +++ /dev/null @@ -1,58 +0,0 @@ -#define _PDCLIB_EXTENSIONS -#include -#include -#include - -static size_t mcb(void *p, const char *buf, size_t size) -{ - *(size_t *)p += size; - return size; -} - -static size_t vprintflen(const char *restrict fmt, va_list arg) -{ - size_t ret = 0; - _vcbprintf(&ret, mcb, fmt, arg); - return ret + 1; -} - -int asprintf(char **strp, const char *restrict fmt, ...) -{ - va_list arg, arg2; - va_start(arg, fmt); - va_copy(arg2, arg); - - size_t sz = vprintflen(fmt, arg); - - *strp = malloc(sz); - if (!strp) - { - va_end(arg); - va_end(arg2); - return -1; - } - - int ret = vsnprintf(*strp, sz, fmt, arg2); - va_end(arg); - va_end(arg2); - return ret; -} - -int vasprintf(char **strp, const char *restrict fmt, va_list arg) -{ - va_list arg2; - va_copy(arg2, arg); - - size_t sz = vprintflen(fmt, arg); - - *strp = malloc(sz); - if (!strp) - { - va_end(arg2); - return -1; - } - - int ret = vsnprintf(*strp, sz, fmt, arg2); - va_end(arg2); - return ret; -} diff --git a/waterbox/libc/functions/stdio/vfprintf.c b/waterbox/libc/functions/stdio/vfprintf.c deleted file mode 100644 index 1eeaf0986f..0000000000 --- a/waterbox/libc/functions/stdio/vfprintf.c +++ /dev/null @@ -1,64 +0,0 @@ -/* vfprintf( FILE *, const char *, va_list ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -static size_t filecb(void *p, const char *buf, size_t size) -{ - return _PDCLIB_fwrite_unlocked( buf, 1, size, (FILE*) p ); -} - -int _PDCLIB_vfprintf_unlocked( FILE * _PDCLIB_restrict stream, - const char * _PDCLIB_restrict format, - va_list arg ) -{ - return _vcbprintf(stream, filecb, format, arg); -} - -int vfprintf( FILE * _PDCLIB_restrict stream, - const char * _PDCLIB_restrict format, - va_list arg ) -{ - _PDCLIB_flockfile( stream ); - int r = _PDCLIB_vfprintf_unlocked( stream, format, arg ); - _PDCLIB_funlockfile( stream ); - return r; -} - -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "stdio/vfprintf.c" -#define _PDCLIB_FILEIO -#include -#include "_PDCLIB_test.h" - -static int testprintf( FILE * stream, const char * format, ... ) -{ - int i; - va_list arg; - va_start( arg, format ); - i = vfprintf( stream, format, arg ); - va_end( arg ); - return i; -} - -int main( void ) -{ - FILE * target; - TESTCASE( ( target = tmpfile() ) != NULL ); -#include "printf_testcases.h" - TESTCASE( fclose( target ) == 0 ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/vfscanf.c b/waterbox/libc/functions/stdio/vfscanf.c deleted file mode 100644 index e9aa01002e..0000000000 --- a/waterbox/libc/functions/stdio/vfscanf.c +++ /dev/null @@ -1,126 +0,0 @@ -/* vfscanf( FILE *, const char *, va_list ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_vfscanf_unlocked( FILE * _PDCLIB_restrict stream, - const char * _PDCLIB_restrict format, - va_list arg ) -{ - /* TODO: This function should interpret format as multibyte characters. */ - struct _PDCLIB_status_t status; - status.base = 0; - status.flags = 0; - status.n = 0; - status.i = 0; - status.current = 0; - status.s = NULL; - status.width = 0; - status.prec = 0; - status.stream = stream; - va_copy( status.arg, arg ); - - while ( *format != '\0' ) - { - const char * rc; - if ( ( *format != '%' ) || ( ( rc = _PDCLIB_scan( format, &status ) ) == format ) ) - { - int c; - /* No conversion specifier, match verbatim */ - if ( isspace( *format ) ) - { - /* Whitespace char in format string: Skip all whitespaces */ - /* No whitespaces in input does not result in matching error */ - while ( isspace( c = getc( stream ) ) ) - { - ++status.i; - } - if ( ! feof( stream ) ) - { - _PDCLIB_ungetc_unlocked( c, stream ); - } - } - else - { - /* Non-whitespace char in format string: Match verbatim */ - if ( ( ( c = _PDCLIB_getc_unlocked( stream ) ) != *format ) || feof( stream ) ) - { - /* Matching error */ - if ( ! feof( stream ) && ! ferror( stream ) ) - { - _PDCLIB_ungetc_unlocked( c, stream ); - } - else if ( status.n == 0 ) - { - return EOF; - } - return status.n; - } - else - { - ++status.i; - } - } - ++format; - } - else - { - /* NULL return code indicates matching error */ - if ( rc == NULL ) - { - break; - } - /* Continue parsing after conversion specifier */ - format = rc; - } - } - va_end( status.arg ); - return status.n; -} - -int vfscanf( FILE * _PDCLIB_restrict stream, - const char * _PDCLIB_restrict format, - va_list arg ) -{ - _PDCLIB_flockfile( stream ); - int r = _PDCLIB_vfscanf_unlocked( stream, format, arg ); - _PDCLIB_funlockfile( stream ); - return r; -} - -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "stdio/vfscanf.c" -#define _PDCLIB_FILEIO - -#include "_PDCLIB_test.h" - -static int testscanf( FILE * stream, char const * format, ... ) -{ - va_list ap; - va_start( ap, format ); - int result = vfscanf( stream, format, ap ); - va_end( ap ); - return result; -} - -int main( void ) -{ - FILE * source; - TESTCASE( ( source = tmpfile() ) != NULL ); -#include "scanf_testcases.h" - TESTCASE( fclose( source ) == 0 ); - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/vprintf.c b/waterbox/libc/functions/stdio/vprintf.c deleted file mode 100644 index 151c75e43a..0000000000 --- a/waterbox/libc/functions/stdio/vprintf.c +++ /dev/null @@ -1,53 +0,0 @@ -/* vprintf( const char *, va_list ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_vprintf_unlocked( const char * _PDCLIB_restrict format, - _PDCLIB_va_list arg ) -{ - return _PDCLIB_vfprintf_unlocked( stdout, format, arg ); -} - -int vprintf( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) -{ - return vfprintf( stdout, format, arg ); -} - -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "stdio/vprintf.c" -#define _PDCLIB_FILEIO -#include -#include -#include "_PDCLIB_test.h" - -static int testprintf( FILE * stream, const char * format, ... ) -{ - int i; - va_list arg; - va_start( arg, format ); - i = vprintf( format, arg ); - va_end( arg ); - return i; -} - -int main( void ) -{ - FILE * target; - TESTCASE( ( target = freopen( testfile, "wb+", stdout ) ) != NULL ); -#include "printf_testcases.h" - TESTCASE( fclose( target ) == 0 ); - TESTCASE( remove( testfile ) == 0 ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/vscanf.c b/waterbox/libc/functions/stdio/vscanf.c deleted file mode 100644 index f9ce569ef7..0000000000 --- a/waterbox/libc/functions/stdio/vscanf.c +++ /dev/null @@ -1,52 +0,0 @@ -/* vscanf( const char *, va_list ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -int _PDCLIB_vscanf_unlocked( const char * _PDCLIB_restrict format, - _PDCLIB_va_list arg ) -{ - return _PDCLIB_vfscanf_unlocked( stdin, format, arg ); -} - -int vscanf( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) -{ - return vfscanf( stdin, format, arg ); -} - -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "stdio/vscanf.c" -#define _PDCLIB_FILEIO - -#include "_PDCLIB_test.h" - -static int testscanf( FILE * stream, const char * format, ... ) -{ - int i; - va_list arg; - va_start( arg, format ); - i = vscanf( format, arg ); - va_end( arg ); - return i; -} - -int main( void ) -{ - FILE * source; - TESTCASE( ( source = freopen( testfile, "wb+", stdin ) ) != NULL ); -#include "scanf_testcases.h" - TESTCASE( fclose( source ) == 0 ); - TESTCASE( remove( testfile ) == 0 ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/vsnprintf.c b/waterbox/libc/functions/stdio/vsnprintf.c deleted file mode 100644 index 761853ff8f..0000000000 --- a/waterbox/libc/functions/stdio/vsnprintf.c +++ /dev/null @@ -1,73 +0,0 @@ -/* vsnprintf( char *, size_t, const char *, va_list ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" -#include - -struct state { - size_t bufrem; - char *bufp; -}; - -static size_t strout( void *p, const char *buf, size_t sz ) -{ - struct state *s = p; - size_t copy = s->bufrem >= sz ? sz : s->bufrem; - memcpy( s->bufp, buf, copy ); - s->bufrem -= copy; - s->bufp += copy; - return sz; -} - -int vsnprintf( char * _PDCLIB_restrict s, - size_t n, - const char * _PDCLIB_restrict format, - _PDCLIB_va_list arg ) -{ - struct state st; - st.bufrem = n; - st.bufp = s; - int r = _vcbprintf( &st, strout, format, arg ); - if ( st.bufrem ) - { - *st.bufp = 0; - } - - return r; -} - -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "stdio/vsnprintf.c" -#define _PDCLIB_STRINGIO -#include -#include -#include "_PDCLIB_test.h" - -static int testprintf( char * s, const char * format, ... ) -{ - int i; - va_list arg; - va_start( arg, format ); - i = vsnprintf( s, 100, format, arg ); - va_end( arg ); - return i; -} - -int main( void ) -{ - char target[100]; -#include "printf_testcases.h" - return TEST_RESULTS; -} - -#endif - diff --git a/waterbox/libc/functions/stdio/vsprintf.c b/waterbox/libc/functions/stdio/vsprintf.c deleted file mode 100644 index 21aa2da1e5..0000000000 --- a/waterbox/libc/functions/stdio/vsprintf.c +++ /dev/null @@ -1,46 +0,0 @@ -/* vsprintf( char *, const char *, va_list ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include -#include - -#ifndef REGTEST - -int vsprintf( char * _PDCLIB_restrict s, - const char * _PDCLIB_restrict format, - va_list arg ) -{ - return vsnprintf( s, SIZE_MAX, format, arg ); /* TODO: Replace with a non-checking call */ -} - -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "stdio/vsprintf.c" -#define _PDCLIB_STRINGIO -#include -#include -#include "_PDCLIB_test.h" - -static int testprintf( char * s, const char * format, ... ) -{ - int i; - va_list arg; - va_start( arg, format ); - i = vsprintf( s, format, arg ); - va_end( arg ); - return i; -} - -int main( void ) -{ - char target[100]; -#include "printf_testcases.h" - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdio/vsscanf.c b/waterbox/libc/functions/stdio/vsscanf.c deleted file mode 100644 index 00210c1f3a..0000000000 --- a/waterbox/libc/functions/stdio/vsscanf.c +++ /dev/null @@ -1,111 +0,0 @@ -/* vsscanf( const char *, const char *, va_list ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include -#include "_PDCLIB_io.h" - -int vsscanf( const char * _PDCLIB_restrict s, - const char * _PDCLIB_restrict format, - va_list arg ) -{ - /* TODO: This function should interpret format as multibyte characters. */ - struct _PDCLIB_status_t status; - status.base = 0; - status.flags = 0; - status.n = 0; - status.i = 0; - status.current = 0; - status.s = (char *) s; - status.width = 0; - status.prec = 0; - status.stream = NULL; - va_copy( status.arg, arg ); - - while ( *format != '\0' ) - { - const char * rc; - if ( ( *format != '%' ) || ( ( rc = _PDCLIB_scan( format, &status ) ) == format ) ) - { - /* No conversion specifier, match verbatim */ - if ( isspace( *format ) ) - { - /* Whitespace char in format string: Skip all whitespaces */ - /* No whitespaces in input do not result in matching error */ - while ( isspace( *status.s ) ) - { - ++status.s; - ++status.i; - } - } - else - { - /* Non-whitespace char in format string: Match verbatim */ - if ( *status.s != *format ) - { - if ( *status.s == '\0' && status.n == 0 ) - { - /* Early input error */ - return EOF; - } - /* Matching error */ - return status.n; - } - else - { - ++status.s; - ++status.i; - } - } - ++format; - } - else - { - /* NULL return code indicates error */ - if ( rc == NULL ) - { - if ( ( *status.s == '\n' ) && ( status.n == 0 ) ) - { - status.n = EOF; - } - break; - } - /* Continue parsing after conversion specifier */ - format = rc; - } - } - va_end( status.arg ); - return status.n; -} - -#endif - -#ifdef TEST -#define _PDCLIB_FILEID "stdio/vsscanf.c" -#define _PDCLIB_STRINGIO - -#include "_PDCLIB_test.h" - -static int testscanf( char const * stream, char const * format, ... ) -{ - va_list ap; - va_start( ap, format ); - int result = vsscanf( stream, format, ap ); - va_end( ap ); - return result; -} - -int main( void ) -{ - char source[100]; -#include "scanf_testcases.h" - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/_Exit.c b/waterbox/libc/functions/stdlib/_Exit.c deleted file mode 100644 index 5a43ee2379..0000000000 --- a/waterbox/libc/functions/stdlib/_Exit.c +++ /dev/null @@ -1,34 +0,0 @@ -/* _Exit( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST -#include "_PDCLIB_glue.h" - -void _Exit( int status ) -{ - /* TODO: Flush and close open streams. Remove tmpfile() files. Make this - called on process termination automatically. - */ - _PDCLIB_Exit( status ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - int UNEXPECTED_RETURN = 0; - _Exit( 0 ); - TESTCASE( UNEXPECTED_RETURN ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/abort.c b/waterbox/libc/functions/stdlib/abort.c deleted file mode 100644 index 0c3428340c..0000000000 --- a/waterbox/libc/functions/stdlib/abort.c +++ /dev/null @@ -1,39 +0,0 @@ -/* abort( void ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST - -void abort( void ) -{ - raise( SIGABRT ); - exit( EXIT_FAILURE ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -#include - -static void aborthandler( int sig ) -{ - exit( 0 ); -} - -int main( void ) -{ - int UNEXPECTED_RETURN_FROM_ABORT = 0; - TESTCASE( signal( SIGABRT, &aborthandler ) != SIG_ERR ); - abort(); - TESTCASE( UNEXPECTED_RETURN_FROM_ABORT ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/abs.c b/waterbox/libc/functions/stdlib/abs.c deleted file mode 100644 index 4e8302bdb2..0000000000 --- a/waterbox/libc/functions/stdlib/abs.c +++ /dev/null @@ -1,30 +0,0 @@ -/* abs( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -int abs( int j ) -{ - return ( j >= 0 ) ? j : -j; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -int main( void ) -{ - TESTCASE( abs( 0 ) == 0 ); - TESTCASE( abs( INT_MAX ) == INT_MAX ); - TESTCASE( abs( INT_MIN + 1 ) == -( INT_MIN + 1 ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/at_quick_exit.c b/waterbox/libc/functions/stdlib/at_quick_exit.c deleted file mode 100644 index 47dc38dc8c..0000000000 --- a/waterbox/libc/functions/stdlib/at_quick_exit.c +++ /dev/null @@ -1,60 +0,0 @@ -/* atexit( void (*)( void ) ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -extern void (*_PDCLIB_quickexitstack[])( void ); -extern size_t _PDCLIB_quickexitptr; - -int at_quick_exit( void (*func)( void ) ) -{ - if ( _PDCLIB_quickexitptr == 0 ) - { - return -1; - } - else - { - _PDCLIB_quickexitstack[ --_PDCLIB_quickexitptr ] = func; - return 0; - } -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -static int flags[ 32 ]; - -static void counthandler( void ) -{ - static int count = 0; - flags[ count ] = count; - ++count; -} - -static void checkhandler( void ) -{ - for ( int i = 0; i < 31; ++i ) - { - assert( flags[ i ] == i ); - } -} - -int main( void ) -{ - TESTCASE( at_quick_exit( &checkhandler ) == 0 ); - for ( int i = 0; i < 31; ++i ) - { - TESTCASE( at_quick_exit( &counthandler ) == 0 ); - } - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/atexit.c b/waterbox/libc/functions/stdlib/atexit.c deleted file mode 100644 index 808bcb1176..0000000000 --- a/waterbox/libc/functions/stdlib/atexit.c +++ /dev/null @@ -1,60 +0,0 @@ -/* atexit( void (*)( void ) ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -extern void (*_PDCLIB_exitstack[])( void ); -extern size_t _PDCLIB_exitptr; - -int atexit( void (*func)( void ) ) -{ - if ( _PDCLIB_exitptr == 0 ) - { - return -1; - } - else - { - _PDCLIB_exitstack[ --_PDCLIB_exitptr ] = func; - return 0; - } -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -static int flags[ 32 ]; - -static void counthandler( void ) -{ - static int count = 0; - flags[ count ] = count; - ++count; -} - -static void checkhandler( void ) -{ - for ( int i = 0; i < 31; ++i ) - { - assert( flags[ i ] == i ); - } -} - -int main( void ) -{ - TESTCASE( atexit( &checkhandler ) == 0 ); - for ( int i = 0; i < 31; ++i ) - { - TESTCASE( atexit( &counthandler ) == 0 ); - } - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/atoi.c b/waterbox/libc/functions/stdlib/atoi.c deleted file mode 100644 index eac0e1652c..0000000000 --- a/waterbox/libc/functions/stdlib/atoi.c +++ /dev/null @@ -1,27 +0,0 @@ -/* atoi( const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -int atoi( const char * s ) -{ - return (int) _PDCLIB_atomax( s ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* no tests for a simple wrapper */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/atol.c b/waterbox/libc/functions/stdlib/atol.c deleted file mode 100644 index fb5e512142..0000000000 --- a/waterbox/libc/functions/stdlib/atol.c +++ /dev/null @@ -1,27 +0,0 @@ -/* atol( const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -long int atol( const char * s ) -{ - return (long int) _PDCLIB_atomax( s ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* no tests for a simple wrapper */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/atoll.c b/waterbox/libc/functions/stdlib/atoll.c deleted file mode 100644 index f7fa824402..0000000000 --- a/waterbox/libc/functions/stdlib/atoll.c +++ /dev/null @@ -1,27 +0,0 @@ -/* atoll( const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -long long int atoll( const char * s ) -{ - return (long long int) _PDCLIB_atomax( s ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* no tests for a simple wrapper */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/bsearch.c b/waterbox/libc/functions/stdlib/bsearch.c deleted file mode 100644 index 835407f5ee..0000000000 --- a/waterbox/libc/functions/stdlib/bsearch.c +++ /dev/null @@ -1,60 +0,0 @@ -/* bsearch( const void *, const void *, size_t, size_t, int(*)( const void *, const void * ) ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -void * bsearch( const void * key, const void * base, size_t nmemb, size_t size, int (*compar)( const void *, const void * ) ) -{ - const void * pivot; - int rc; - size_t corr; - while ( nmemb ) - { - /* algorithm needs -1 correction if remaining elements are an even number. */ - corr = nmemb % 2; - nmemb /= 2; - pivot = (const char *)base + (nmemb * size); - rc = compar( key, pivot ); - if ( rc > 0 ) - { - base = (const char *)pivot + size; - /* applying correction */ - nmemb -= ( 1 - corr ); - } - else if ( rc == 0 ) - { - return (void *)pivot; - } - } - return NULL; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -static int compare( const void * left, const void * right ) -{ - return *( (unsigned char *)left ) - *( (unsigned char *)right ); -} - -int main( void ) -{ - TESTCASE( bsearch( "e", abcde, 4, 1, compare ) == NULL ); - TESTCASE( bsearch( "e", abcde, 5, 1, compare ) == &abcde[4] ); - TESTCASE( bsearch( "a", abcde + 1, 4, 1, compare ) == NULL ); - TESTCASE( bsearch( "0", abcde, 1, 1, compare ) == NULL ); - TESTCASE( bsearch( "a", abcde, 1, 1, compare ) == &abcde[0] ); - TESTCASE( bsearch( "a", abcde, 0, 1, compare ) == NULL ); - TESTCASE( bsearch( "e", abcde, 3, 2, compare ) == &abcde[4] ); - TESTCASE( bsearch( "b", abcde, 3, 2, compare ) == NULL ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/div.c b/waterbox/libc/functions/stdlib/div.c deleted file mode 100644 index 8aabad6dd6..0000000000 --- a/waterbox/libc/functions/stdlib/div.c +++ /dev/null @@ -1,39 +0,0 @@ -/* div( int, int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -div_t div( int numer, int denom ) -{ - div_t rc; - rc.quot = numer / denom; - rc.rem = numer % denom; - /* TODO: pre-C99 compilers might require modulus corrections */ - return rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - div_t result; - result = div( 5, 2 ); - TESTCASE( result.quot == 2 && result.rem == 1 ); - result = div( -5, 2 ); - TESTCASE( result.quot == -2 && result.rem == -1 ); - result = div( 5, -2 ); - TESTCASE( result.quot == -2 && result.rem == 1 ); - TESTCASE( sizeof( result.quot ) == sizeof( int ) ); - TESTCASE( sizeof( result.rem ) == sizeof( int ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/exit.c b/waterbox/libc/functions/stdlib/exit.c deleted file mode 100644 index fa91ade187..0000000000 --- a/waterbox/libc/functions/stdlib/exit.c +++ /dev/null @@ -1,44 +0,0 @@ -/* exit( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -/* TODO - "except that a function is called after any previously registered - functions that had already been called at the time it was registered. -*/ - -/* TODO: 32 is guaranteed. This should be dynamic but ATM gives problems - with my malloc. -*/ -#define NUMBER_OF_SLOTS 40 - -void (*_PDCLIB_exitstack[ NUMBER_OF_SLOTS ])( void ) = { _PDCLIB_closeall }; -size_t _PDCLIB_exitptr = NUMBER_OF_SLOTS; - -void exit( int status ) -{ - while ( _PDCLIB_exitptr < NUMBER_OF_SLOTS ) - { - _PDCLIB_exitstack[ _PDCLIB_exitptr++ ](); - } - _Exit( status ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Unwinding of regstack tested in atexit(). */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/getenv.c b/waterbox/libc/functions/stdlib/getenv.c deleted file mode 100644 index f07481d3b4..0000000000 --- a/waterbox/libc/functions/stdlib/getenv.c +++ /dev/null @@ -1,30 +0,0 @@ -/* getenv( const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -/* This is a stub implementation of getenv -*/ - -#include -#include - -#ifndef REGTEST - -char * getenv( const char * name ) -{ - return NULL; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/labs.c b/waterbox/libc/functions/stdlib/labs.c deleted file mode 100644 index 2888928f8e..0000000000 --- a/waterbox/libc/functions/stdlib/labs.c +++ /dev/null @@ -1,30 +0,0 @@ -/* labs( long int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -long int labs( long int j ) -{ - return ( j >= 0 ) ? j : -j; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -int main( void ) -{ - TESTCASE( labs( 0 ) == 0 ); - TESTCASE( labs( LONG_MAX ) == LONG_MAX ); - TESTCASE( labs( LONG_MIN + 1 ) == -( LONG_MIN + 1 ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/ldiv.c b/waterbox/libc/functions/stdlib/ldiv.c deleted file mode 100644 index cf579fb383..0000000000 --- a/waterbox/libc/functions/stdlib/ldiv.c +++ /dev/null @@ -1,39 +0,0 @@ -/* ldiv( long int, long int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -ldiv_t ldiv( long int numer, long int denom ) -{ - ldiv_t rc; - rc.quot = numer / denom; - rc.rem = numer % denom; - /* TODO: pre-C99 compilers might require modulus corrections */ - return rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - ldiv_t result; - result = ldiv( 5, 2 ); - TESTCASE( result.quot == 2 && result.rem == 1 ); - result = ldiv( -5, 2 ); - TESTCASE( result.quot == -2 && result.rem == -1 ); - result = ldiv( 5, -2 ); - TESTCASE( result.quot == -2 && result.rem == 1 ); - TESTCASE( sizeof( result.quot ) == sizeof( long ) ); - TESTCASE( sizeof( result.rem ) == sizeof( long ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/llabs.c b/waterbox/libc/functions/stdlib/llabs.c deleted file mode 100644 index 78a56c3009..0000000000 --- a/waterbox/libc/functions/stdlib/llabs.c +++ /dev/null @@ -1,30 +0,0 @@ -/* llabs( long int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -long long int llabs( long long int j ) -{ - return ( j >= 0 ) ? j : -j; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -int main( void ) -{ - TESTCASE( llabs( 0ll ) == 0 ); - TESTCASE( llabs( LLONG_MAX ) == LLONG_MAX ); - TESTCASE( llabs( LLONG_MIN + 1 ) == -( LLONG_MIN + 1 ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/lldiv.c b/waterbox/libc/functions/stdlib/lldiv.c deleted file mode 100644 index e6552c3447..0000000000 --- a/waterbox/libc/functions/stdlib/lldiv.c +++ /dev/null @@ -1,39 +0,0 @@ -/* lldiv( long long int, long long int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -lldiv_t lldiv( long long int numer, long long int denom ) -{ - lldiv_t rc; - rc.quot = numer / denom; - rc.rem = numer % denom; - /* TODO: pre-C99 compilers might require modulus corrections */ - return rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - lldiv_t result; - result = lldiv( 5ll, 2ll ); - TESTCASE( result.quot == 2 && result.rem == 1 ); - result = lldiv( -5ll, 2ll ); - TESTCASE( result.quot == -2 && result.rem == -1 ); - result = lldiv( 5ll, -2ll ); - TESTCASE( result.quot == -2 && result.rem == 1 ); - TESTCASE( sizeof( result.quot ) == sizeof( long long ) ); - TESTCASE( sizeof( result.rem ) == sizeof( long long ) ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/qsort.c b/waterbox/libc/functions/stdlib/qsort.c deleted file mode 100644 index 757cae0f28..0000000000 --- a/waterbox/libc/functions/stdlib/qsort.c +++ /dev/null @@ -1,164 +0,0 @@ -/* qsort( void *, size_t, size_t, int(*)( const void *, const void * ) ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -/* This implementation is taken from Paul Edward's PDPCLIB. - - Original code is credited to Raymond Gardner, Englewood CO. - Minor mods are credited to Paul Edwards. - Some reformatting and simplification done by Martin Baute. - All code is still Public Domain. -*/ - -/* Wrapper for _PDCLIB_memswp protects against multiple argument evaluation. */ -static inline void memswp( char * i, char * j, size_t size ) -{ - _PDCLIB_memswp( i, j, size ); -} - -/* For small sets, insertion sort is faster than quicksort. - T is the threshold below which insertion sort will be used. - Must be 3 or larger. -*/ -#define T 7 - -/* Macros for handling the QSort stack */ -#define PREPARE_STACK char * stack[STACKSIZE]; char * * stackptr = stack -#define PUSH( base, limit ) stackptr[0] = base; stackptr[1] = limit; stackptr += 2 -#define POP( base, limit ) stackptr -= 2; base = stackptr[0]; limit = stackptr[1] -/* TODO: Stack usage is log2( nmemb ) (minus what T shaves off the worst case). - Worst-case nmemb is platform dependent and should probably be - configured through _PDCLIB_config.h. -*/ -#define STACKSIZE 64 - -void qsort( void * base, size_t nmemb, size_t size, int (*compar)( const void *, const void * ) ) -{ - char * i; - char * j; - _PDCLIB_size_t thresh = T * size; - char * base_ = (char *)base; - char * limit = base_ + nmemb * size; - PREPARE_STACK; - - for ( ;; ) - { - if ( (size_t)( limit - base_ ) > thresh ) /* QSort for more than T elements. */ - { - /* We work from second to last - first will be pivot element. */ - i = base_ + size; - j = limit - size; - /* We swap first with middle element, then sort that with second - and last element so that eventually first element is the median - of the three - avoiding pathological pivots. - TODO: Instead of middle element, chose one randomly. - */ - memswp( ( ( ( (size_t)( limit - base_ ) ) / size ) / 2 ) * size + base_, base_, size ); - if ( compar( i, j ) > 0 ) memswp( i, j, size ); - if ( compar( base_, j ) > 0 ) memswp( base_, j, size ); - if ( compar( i, base_ ) > 0 ) memswp( i, base_, size ); - /* Now we have the median for pivot element, entering main Quicksort. */ - for ( ;; ) - { - do - { - /* move i right until *i >= pivot */ - i += size; - } while ( compar( i, base_ ) < 0 ); - do - { - /* move j left until *j <= pivot */ - j -= size; - } while ( compar( j, base_ ) > 0 ); - if ( i > j ) - { - /* break loop if pointers crossed */ - break; - } - /* else swap elements, keep scanning */ - memswp( i, j, size ); - } - /* move pivot into correct place */ - memswp( base_, j, size ); - /* larger subfile base / limit to stack, sort smaller */ - if ( j - base_ > limit - i ) - { - /* left is larger */ - PUSH( base_, j ); - base_ = i; - } - else - { - /* right is larger */ - PUSH( i, limit ); - limit = j; - } - } - else /* insertion sort for less than T elements */ - { - for ( j = base_, i = j + size; i < limit; j = i, i += size ) - { - for ( ; compar( j, j + size ) > 0; j -= size ) - { - memswp( j, j + size, size ); - if ( j == base_ ) - { - break; - } - } - } - if ( stackptr != stack ) /* if any entries on stack */ - { - POP( base_, limit ); - } - else /* else stack empty, done */ - { - break; - } - } - } -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include -#include - -static int compare( const void * left, const void * right ) -{ - return *( (unsigned char *)left ) - *( (unsigned char *)right ); -} - -int main( void ) -{ - char presort[] = { "shreicnyjqpvozxmbt" }; - char sorted1[] = { "bcehijmnopqrstvxyz" }; - char sorted2[] = { "bticjqnyozpvreshxm" }; - char s[19]; - strcpy( s, presort ); - qsort( s, 18, 1, compare ); - TESTCASE( strcmp( s, sorted1 ) == 0 ); - strcpy( s, presort ); - qsort( s, 9, 2, compare ); - TESTCASE( strcmp( s, sorted2 ) == 0 ); - strcpy( s, presort ); - qsort( s, 1, 1, compare ); - TESTCASE( strcmp( s, presort ) == 0 ); -#if defined(REGTEST) && (__BSD_VISIBLE || __APPLE__) - puts( "qsort.c: Skipping test #4 for BSD as it goes into endless loop here." ); -#else - qsort( s, 100, 0, compare ); - TESTCASE( strcmp( s, presort ) == 0 ); -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/quick_exit.c b/waterbox/libc/functions/stdlib/quick_exit.c deleted file mode 100644 index 2420e67383..0000000000 --- a/waterbox/libc/functions/stdlib/quick_exit.c +++ /dev/null @@ -1,44 +0,0 @@ -/* quick_exit( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST -#include "_PDCLIB_io.h" - -/* TODO - "except that a function is called after any previously registered - functions that had already been called at the time it was registered. -*/ - -/* TODO: 32 is guaranteed. This should be dynamic but ATM gives problems - with my malloc. -*/ -#define NUMBER_OF_SLOTS 40 - -void (*_PDCLIB_quickexitstack[ NUMBER_OF_SLOTS ])( void ) = { 0 }; -size_t _PDCLIB_quickexitptr = NUMBER_OF_SLOTS; - -void quick_exit( int status ) -{ - while ( _PDCLIB_quickexitptr < NUMBER_OF_SLOTS ) - { - _PDCLIB_quickexitstack[ _PDCLIB_quickexitptr++ ](); - } - _Exit( status ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* Unwinding of regstack tested in at_quick_exit(). */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/rand.c b/waterbox/libc/functions/stdlib/rand.c deleted file mode 100644 index 1e8f3cd789..0000000000 --- a/waterbox/libc/functions/stdlib/rand.c +++ /dev/null @@ -1,33 +0,0 @@ -/* rand( void ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -int rand( void ) -{ - _PDCLIB_seed = _PDCLIB_seed * 1103515245 + 12345; - return (int)( _PDCLIB_seed / 65536 ) % 32768; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - int rnd1, rnd2; - TESTCASE( ( rnd1 = rand() ) < RAND_MAX ); - TESTCASE( ( rnd2 = rand() ) < RAND_MAX ); - srand( 1 ); - TESTCASE( rand() == rnd1 ); - TESTCASE( rand() == rnd2 ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/srand.c b/waterbox/libc/functions/stdlib/srand.c deleted file mode 100644 index 3478cb09df..0000000000 --- a/waterbox/libc/functions/stdlib/srand.c +++ /dev/null @@ -1,27 +0,0 @@ -/* srand( unsigned int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -void srand( unsigned int seed ) -{ - _PDCLIB_seed = seed; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - /* tested in rand.c */ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/strtol.c b/waterbox/libc/functions/stdlib/strtol.c deleted file mode 100644 index ce75539e42..0000000000 --- a/waterbox/libc/functions/stdlib/strtol.c +++ /dev/null @@ -1,128 +0,0 @@ -/* strtol( const char *, char * *, int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST - -#include - -long int strtol( const char * s, char ** endptr, int base ) -{ - long int rc; - char sign = '+'; - const char * p = _PDCLIB_strtox_prelim( s, &sign, &base ); - if ( base < 2 || base > 36 ) return 0; - if ( sign == '+' ) - { - rc = (long int)_PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)LONG_MAX, (uintmax_t)( LONG_MAX / base ), (int)( LONG_MAX % base ), &sign ); - } - else - { - rc = (long int)_PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)LONG_MIN, (uintmax_t)( LONG_MIN / -base ), (int)( -( LONG_MIN % base ) ), &sign ); - } - if ( endptr != NULL ) *endptr = ( p != NULL ) ? (char *) p : (char *) s; - return ( sign == '+' ) ? rc : -rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -#include - -int main( void ) -{ - char * endptr; - /* this, to base 36, overflows even a 256 bit integer */ - char overflow[] = "-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_"; - /* tricky border case */ - char tricky[] = "+0xz"; - errno = 0; - /* basic functionality */ - TESTCASE( strtol( "123", NULL, 10 ) == 123 ); - /* proper detecting of default base 10 */ - TESTCASE( strtol( "456", NULL, 0 ) == 456 ); - /* proper functioning to smaller base */ - TESTCASE( strtol( "14", NULL, 8 ) == 12 ); - /* proper autodetecting of octal */ - TESTCASE( strtol( "016", NULL, 0 ) == 14 ); - /* proper autodetecting of hexadecimal, lowercase 'x' */ - TESTCASE( strtol( "0xFF", NULL, 0 ) == 255 ); - /* proper autodetecting of hexadecimal, uppercase 'X' */ - TESTCASE( strtol( "0Xa1", NULL, 0 ) == 161 ); - /* proper handling of border case: 0x followed by non-hexdigit */ - TESTCASE( strtol( tricky, &endptr, 0 ) == 0 ); - TESTCASE( endptr == tricky + 2 ); - /* proper handling of border case: 0 followed by non-octdigit */ - TESTCASE( strtol( tricky, &endptr, 8 ) == 0 ); - TESTCASE( endptr == tricky + 2 ); - /* errno should still be 0 */ - TESTCASE( errno == 0 ); - /* overflowing subject sequence must still return proper endptr */ - TESTCASE( strtol( overflow, &endptr, 36 ) == LONG_MIN ); - TESTCASE( errno == ERANGE ); - TESTCASE( ( endptr - overflow ) == 53 ); - /* same for positive */ - errno = 0; - TESTCASE( strtol( overflow + 1, &endptr, 36 ) == LONG_MAX ); - TESTCASE( errno == ERANGE ); - TESTCASE( ( endptr - overflow ) == 53 ); - /* testing skipping of leading whitespace */ - TESTCASE( strtol( " \n\v\t\f789", NULL, 0 ) == 789 ); - /* testing conversion failure */ - TESTCASE( strtol( overflow, &endptr, 10 ) == 0 ); - TESTCASE( endptr == overflow ); - endptr = NULL; - TESTCASE( strtol( overflow, &endptr, 0 ) == 0 ); - TESTCASE( endptr == overflow ); - /* TODO: These tests assume two-complement, but conversion should work */ - /* for one-complement and signed magnitude just as well. Anyone having */ - /* a platform to test this on? */ - errno = 0; -#if LONG_MAX >> 30 == 1 - /* testing "even" overflow, i.e. base is power of two */ - TESTCASE( strtol( "2147483647", NULL, 0 ) == 0x7fffffff ); - TESTCASE( errno == 0 ); - errno = 0; - TESTCASE( strtol( "2147483648", NULL, 0 ) == LONG_MAX ); - TESTCASE( errno == ERANGE ); - errno = 0; - TESTCASE( strtol( "-2147483647", NULL, 0 ) == (long)0x80000001 ); - TESTCASE( errno == 0 ); - errno = 0; - TESTCASE( strtol( "-2147483648", NULL, 0 ) == LONG_MIN ); - TESTCASE( errno == 0 ); - errno = 0; - TESTCASE( strtol( "-2147483649", NULL, 0 ) == LONG_MIN ); - TESTCASE( errno == ERANGE ); - /* TODO: test "odd" overflow, i.e. base is not power of two */ -#elif LONG_MAX >> 62 == 1 - /* testing "even" overflow, i.e. base is power of two */ - TESTCASE( strtol( "9223372036854775807", NULL, 0 ) == 0x7fffffffffffffff ); - TESTCASE( errno == 0 ); - errno = 0; - TESTCASE( strtol( "9223372036854775808", NULL, 0 ) == LONG_MAX ); - TESTCASE( errno == ERANGE ); - errno = 0; - TESTCASE( strtol( "-9223372036854775807", NULL, 0 ) == (long)0x8000000000000001 ); - TESTCASE( errno == 0 ); - errno = 0; - TESTCASE( strtol( "-9223372036854775808", NULL, 0 ) == LONG_MIN ); - TESTCASE( errno == 0 ); - errno = 0; - TESTCASE( strtol( "-9223372036854775809", NULL, 0 ) == LONG_MIN ); - TESTCASE( errno == ERANGE ); - /* TODO: test "odd" overflow, i.e. base is not power of two */ -#else -#error Unsupported width of 'long' (neither 32 nor 64 bit). -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/strtoll.c b/waterbox/libc/functions/stdlib/strtoll.c deleted file mode 100644 index de71194298..0000000000 --- a/waterbox/libc/functions/stdlib/strtoll.c +++ /dev/null @@ -1,122 +0,0 @@ -/* strtoll( const char *, char * *, int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST - -#include - -long long int strtoll( const char * s, char ** endptr, int base ) -{ - long long int rc; - char sign = '+'; - const char * p = _PDCLIB_strtox_prelim( s, &sign, &base ); - if ( base < 2 || base > 36 ) return 0; - if ( sign == '+' ) - { - rc = (long long int)_PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)LLONG_MAX, (uintmax_t)( LLONG_MAX / base ), (int)( LLONG_MAX % base ), &sign ); - } - else - { - rc = (long long int)_PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)LLONG_MIN, (uintmax_t)( LLONG_MIN / -base ), (int)( -( LLONG_MIN % base ) ), &sign ); - } - if ( endptr != NULL ) *endptr = ( p != NULL ) ? (char *) p : (char *) s; - return ( sign == '+' ) ? rc : -rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -#include - -int main( void ) -{ - char * endptr; - /* this, to base 36, overflows even a 256 bit integer */ - char overflow[] = "-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_"; - /* tricky border case */ - char tricky[] = "+0xz"; - errno = 0; - /* basic functionality */ - TESTCASE( strtoll( "123", NULL, 10 ) == 123 ); - /* proper detecting of default base 10 */ - TESTCASE( strtoll( "456", NULL, 0 ) == 456 ); - /* proper functioning to smaller base */ - TESTCASE( strtoll( "14", NULL, 8 ) == 12 ); - /* proper autodetecting of octal */ - TESTCASE( strtoll( "016", NULL, 0 ) == 14 ); - /* proper autodetecting of hexadecimal, lowercase 'x' */ - TESTCASE( strtoll( "0xFF", NULL, 0 ) == 255 ); - /* proper autodetecting of hexadecimal, uppercase 'X' */ - TESTCASE( strtoll( "0Xa1", NULL, 0 ) == 161 ); - /* proper handling of border case: 0x followed by non-hexdigit */ - TESTCASE( strtoll( tricky, &endptr, 0 ) == 0 ); - TESTCASE( endptr == tricky + 2 ); - /* proper handling of border case: 0 followed by non-octdigit */ - TESTCASE( strtoll( tricky, &endptr, 8 ) == 0 ); - TESTCASE( endptr == tricky + 2 ); - /* errno should still be 0 */ - TESTCASE( errno == 0 ); - /* overflowing subject sequence must still return proper endptr */ - TESTCASE( strtoll( overflow, &endptr, 36 ) == LLONG_MIN ); - TESTCASE( errno == ERANGE ); - TESTCASE( ( endptr - overflow ) == 53 ); - /* same for positive */ - errno = 0; - TESTCASE( strtoll( overflow + 1, &endptr, 36 ) == LLONG_MAX ); - TESTCASE( errno == ERANGE ); - TESTCASE( ( endptr - overflow ) == 53 ); - /* testing skipping of leading whitespace */ - TESTCASE( strtoll( " \n\v\t\f789", NULL, 0 ) == 789 ); - /* testing conversion failure */ - TESTCASE( strtoll( overflow, &endptr, 10 ) == 0 ); - TESTCASE( endptr == overflow ); - endptr = NULL; - TESTCASE( strtoll( overflow, &endptr, 0 ) == 0 ); - TESTCASE( endptr == overflow ); - /* TODO: These tests assume two-complement, but conversion should work */ - /* for one-complement and signed magnitude just as well. Anyone having */ - /* a platform to test this on? */ - errno = 0; -#if LLONG_MAX >> 62 == 1 - /* testing "even" overflow, i.e. base is power of two */ - TESTCASE( strtoll( "9223372036854775807", NULL, 0 ) == 0x7fffffffffffffff ); - TESTCASE( errno == 0 ); - TESTCASE( strtoll( "9223372036854775808", NULL, 0 ) == LLONG_MAX ); - TESTCASE( errno == ERANGE ); - errno = 0; - TESTCASE( strtoll( "-9223372036854775807", NULL, 0 ) == (long long)0x8000000000000001 ); - TESTCASE( errno == 0 ); - TESTCASE( strtoll( "-9223372036854775808", NULL, 0 ) == LLONG_MIN ); - TESTCASE( errno == 0 ); - TESTCASE( strtoll( "-9223372036854775809", NULL, 0 ) == LLONG_MIN ); - TESTCASE( errno == ERANGE ); - /* TODO: test "odd" overflow, i.e. base is not power of two */ -#elif LLONG_MAX >> 126 == 1 - /* testing "even" overflow, i.e. base is power of two */ - TESTCASE( strtoll( "170141183460469231731687303715884105728", NULL, 0 ) == 0x7fffffffffffffffffffffffffffffff ); - TESTCASE( errno == 0 ); - TESTCASE( strtoll( "170141183460469231731687303715884105729", NULL, 0 ) == LLONG_MAX ); - TESTCASE( errno == ERANGE ); - errno = 0; - TESTCASE( strtoll( "-170141183460469231731687303715884105728", NULL, 0 ) == -0x80000000000000000000000000000001 ); - TESTCASE( errno == 0 ); - TESTCASE( strtoll( "-170141183460469231731687303715884105729", NULL, 0 ) == LLONG_MIN ); - TESTCASE( errno == 0 ); - TESTCASE( strtoll( "-170141183460469231731687303715884105730", NULL, 0 ) == LLONG_MIN ); - TESTCASE( errno == ERANGE ); - /* TODO: test "odd" overflow, i.e. base is not power of two */ -#else -#error Unsupported width of 'long long' (neither 64 nor 128 bit). -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/strtoul.c b/waterbox/libc/functions/stdlib/strtoul.c deleted file mode 100644 index 0bcb7dd2b6..0000000000 --- a/waterbox/libc/functions/stdlib/strtoul.c +++ /dev/null @@ -1,104 +0,0 @@ -/* strtoul( const char *, char * *, int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST - -#include - -unsigned long int strtoul( const char * s, char ** endptr, int base ) -{ - unsigned long int rc; - char sign = '+'; - const char * p = _PDCLIB_strtox_prelim( s, &sign, &base ); - if ( base < 2 || base > 36 ) return 0; - rc = (unsigned long int)_PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)ULONG_MAX, (uintmax_t)( ULONG_MAX / base ), (int)( ULONG_MAX % base ), &sign ); - if ( endptr != NULL ) *endptr = ( p != NULL ) ? (char *) p : (char *) s; - return ( sign == '+' ) ? rc : -rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -int main( void ) -{ - char * endptr; - /* this, to base 36, overflows even a 256 bit integer */ - char overflow[] = "-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_"; - /* tricky border case */ - char tricky[] = "+0xz"; - errno = 0; - /* basic functionality */ - TESTCASE( strtoul( "123", NULL, 10 ) == 123 ); - /* proper detecting of default base 10 */ - TESTCASE( strtoul( "456", NULL, 0 ) == 456 ); - /* proper functioning to smaller base */ - TESTCASE( strtoul( "14", NULL, 8 ) == 12 ); - /* proper autodetecting of octal */ - TESTCASE( strtoul( "016", NULL, 0 ) == 14 ); - /* proper autodetecting of hexadecimal, lowercase 'x' */ - TESTCASE( strtoul( "0xFF", NULL, 0 ) == 255 ); - /* proper autodetecting of hexadecimal, uppercase 'X' */ - TESTCASE( strtoul( "0Xa1", NULL, 0 ) == 161 ); - /* proper handling of border case: 0x followed by non-hexdigit */ - TESTCASE( strtoul( tricky, &endptr, 0 ) == 0 ); - TESTCASE( endptr == tricky + 2 ); - /* proper handling of border case: 0 followed by non-octdigit */ - TESTCASE( strtoul( tricky, &endptr, 8 ) == 0 ); - TESTCASE( endptr == tricky + 2 ); - /* errno should still be 0 */ - TESTCASE( errno == 0 ); - /* overflowing subject sequence must still return proper endptr */ - TESTCASE( strtoul( overflow, &endptr, 36 ) == ULONG_MAX ); - TESTCASE( errno == ERANGE ); - TESTCASE( ( endptr - overflow ) == 53 ); - /* same for positive */ - errno = 0; - TESTCASE( strtoul( overflow + 1, &endptr, 36 ) == ULONG_MAX ); - TESTCASE( errno == ERANGE ); - TESTCASE( ( endptr - overflow ) == 53 ); - /* testing skipping of leading whitespace */ - TESTCASE( strtoul( " \n\v\t\f789", NULL, 0 ) == 789 ); - /* testing conversion failure */ - TESTCASE( strtoul( overflow, &endptr, 10 ) == 0 ); - TESTCASE( endptr == overflow ); - endptr = NULL; - TESTCASE( strtoul( overflow, &endptr, 0 ) == 0 ); - TESTCASE( endptr == overflow ); - /* TODO: These tests assume two-complement, but conversion should work */ - /* for one-complement and signed magnitude just as well. Anyone having */ - /* a platform to test this on? */ - errno = 0; -/* long -> 32 bit */ -#if ULONG_MAX >> 31 == 1 - /* testing "even" overflow, i.e. base is power of two */ - TESTCASE( strtoul( "4294967295", NULL, 0 ) == ULONG_MAX ); - TESTCASE( errno == 0 ); - errno = 0; - TESTCASE( strtoul( "4294967296", NULL, 0 ) == ULONG_MAX ); - TESTCASE( errno == ERANGE ); - /* TODO: test "odd" overflow, i.e. base is not power of two */ -/* long -> 64 bit */ -#elif ULONG_MAX >> 63 == 1 - /* testing "even" overflow, i.e. base is power of two */ - TESTCASE( strtoul( "18446744073709551615", NULL, 0 ) == ULONG_MAX ); - TESTCASE( errno == 0 ); - errno = 0; - TESTCASE( strtoul( "18446744073709551616", NULL, 0 ) == ULONG_MAX ); - TESTCASE( errno == ERANGE ); - /* TODO: test "odd" overflow, i.e. base is not power of two */ -#else -#error Unsupported width of 'long' (neither 32 nor 64 bit). -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/strtoull.c b/waterbox/libc/functions/stdlib/strtoull.c deleted file mode 100644 index 17d283fd69..0000000000 --- a/waterbox/libc/functions/stdlib/strtoull.c +++ /dev/null @@ -1,99 +0,0 @@ -/* strtoull( const char *, char * *, int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST - -#include - -unsigned long long int strtoull( const char * s, char ** endptr, int base ) -{ - unsigned long long int rc; - char sign = '+'; - const char * p = _PDCLIB_strtox_prelim( s, &sign, &base ); - if ( base < 2 || base > 36 ) return 0; - rc = _PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)ULLONG_MAX, (uintmax_t)( ULLONG_MAX / base ), (int)( ULLONG_MAX % base ), &sign ); - if ( endptr != NULL ) *endptr = ( p != NULL ) ? (char *) p : (char *) s; - return ( sign == '+' ) ? rc : -rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" -#include - -int main( void ) -{ - char * endptr; - /* this, to base 36, overflows even a 256 bit integer */ - char overflow[] = "-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_"; - /* tricky border case */ - char tricky[] = "+0xz"; - errno = 0; - /* basic functionality */ - TESTCASE( strtoull( "123", NULL, 10 ) == 123 ); - /* proper detecting of default base 10 */ - TESTCASE( strtoull( "456", NULL, 0 ) == 456 ); - /* proper functioning to smaller base */ - TESTCASE( strtoull( "14", NULL, 8 ) == 12 ); - /* proper autodetecting of octal */ - TESTCASE( strtoull( "016", NULL, 0 ) == 14 ); - /* proper autodetecting of hexadecimal, lowercase 'x' */ - TESTCASE( strtoull( "0xFF", NULL, 0 ) == 255 ); - /* proper autodetecting of hexadecimal, uppercase 'X' */ - TESTCASE( strtoull( "0Xa1", NULL, 0 ) == 161 ); - /* proper handling of border case: 0x followed by non-hexdigit */ - TESTCASE( strtoull( tricky, &endptr, 0 ) == 0 ); - TESTCASE( endptr == tricky + 2 ); - /* proper handling of border case: 0 followed by non-octdigit */ - TESTCASE( strtoull( tricky, &endptr, 8 ) == 0 ); - TESTCASE( endptr == tricky + 2 ); - /* errno should still be 0 */ - TESTCASE( errno == 0 ); - /* overflowing subject sequence must still return proper endptr */ - TESTCASE( strtoull( overflow, &endptr, 36 ) == ULLONG_MAX ); - TESTCASE( errno == ERANGE ); - TESTCASE( ( endptr - overflow ) == 53 ); - /* same for positive */ - errno = 0; - TESTCASE( strtoull( overflow + 1, &endptr, 36 ) == ULLONG_MAX ); - TESTCASE( errno == ERANGE ); - TESTCASE( ( endptr - overflow ) == 53 ); - /* testing skipping of leading whitespace */ - TESTCASE( strtoull( " \n\v\t\f789", NULL, 0 ) == 789 ); - /* testing conversion failure */ - TESTCASE( strtoull( overflow, &endptr, 10 ) == 0 ); - TESTCASE( endptr == overflow ); - endptr = NULL; - TESTCASE( strtoull( overflow, &endptr, 0 ) == 0 ); - TESTCASE( endptr == overflow ); - errno = 0; -/* long long -> 64 bit */ -#if ULLONG_MAX >> 63 == 1 - /* testing "even" overflow, i.e. base is power of two */ - TESTCASE( strtoull( "18446744073709551615", NULL, 0 ) == ULLONG_MAX ); - TESTCASE( errno == 0 ); - TESTCASE( strtoull( "18446744073709551616", NULL, 0 ) == ULLONG_MAX ); - TESTCASE( errno == ERANGE ); - /* TODO: test "odd" overflow, i.e. base is not power of two */ -/* long long -> 128 bit */ -#elif ULLONG_MAX >> 127 == 1 - /* testing "even" overflow, i.e. base is power of two */ - TESTCASE( strtoull( "340282366920938463463374607431768211455", NULL, 0 ) == ULLONG_MAX ); - TESTCASE( errno == 0 ); - TESTCASE( strtoull( "340282366920938463463374607431768211456", NULL, 0 ) == ULLONG_MAX ); - TESTCASE( errno == ERANGE ); - /* TODO: test "odd" overflow, i.e. base is not power of two */ -#else -#error Unsupported width of 'long long' (neither 64 nor 128 bit). -#endif - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/stdlib/system.c b/waterbox/libc/functions/stdlib/system.c deleted file mode 100644 index 6c0f6a7e9b..0000000000 --- a/waterbox/libc/functions/stdlib/system.c +++ /dev/null @@ -1,25 +0,0 @@ -/* system( const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -/* This is a stub implementation of getenv -*/ - -int system( const char * string ) -{ - return -1; -} - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/string/memchr.c b/waterbox/libc/functions/string/memchr.c deleted file mode 100644 index 9701b94314..0000000000 --- a/waterbox/libc/functions/string/memchr.c +++ /dev/null @@ -1,40 +0,0 @@ -/* memchr( const void *, int, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -void * memchr( const void * s, int c, size_t n ) -{ - const unsigned char * p = (const unsigned char *) s; - while ( n-- ) - { - if ( *p == (unsigned char) c ) - { - return (void *) p; - } - ++p; - } - return NULL; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( memchr( abcde, 'c', 5 ) == &abcde[2] ); - TESTCASE( memchr( abcde, 'a', 1 ) == &abcde[0] ); - TESTCASE( memchr( abcde, 'a', 0 ) == NULL ); - TESTCASE( memchr( abcde, '\0', 5 ) == NULL ); - TESTCASE( memchr( abcde, '\0', 6 ) == &abcde[5] ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/string/memcmp.c b/waterbox/libc/functions/string/memcmp.c deleted file mode 100644 index 323c5862db..0000000000 --- a/waterbox/libc/functions/string/memcmp.c +++ /dev/null @@ -1,41 +0,0 @@ -/* memcmp( const void *, const void *, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -int memcmp( const void * s1, const void * s2, size_t n ) -{ - const unsigned char * p1 = (const unsigned char *) s1; - const unsigned char * p2 = (const unsigned char *) s2; - while ( n-- ) - { - if ( *p1 != *p2 ) - { - return *p1 - *p2; - } - ++p1; - ++p2; - } - return 0; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char const xxxxx[] = "xxxxx"; - TESTCASE( memcmp( abcde, abcdx, 5 ) < 0 ); - TESTCASE( memcmp( abcde, abcdx, 4 ) == 0 ); - TESTCASE( memcmp( abcde, xxxxx, 0 ) == 0 ); - TESTCASE( memcmp( xxxxx, abcde, 1 ) > 0 ); - return 0; -} -#endif diff --git a/waterbox/libc/functions/string/memcpy.c b/waterbox/libc/functions/string/memcpy.c deleted file mode 100644 index ded60b1901..0000000000 --- a/waterbox/libc/functions/string/memcpy.c +++ /dev/null @@ -1,38 +0,0 @@ -/* memcpy( void *, const void *, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -void * memcpy( void * _PDCLIB_restrict s1, const void * _PDCLIB_restrict s2, size_t n ) -{ - char * dest = (char *) s1; - const char * src = (const char *) s2; - while ( n-- ) - { - *dest++ = *src++; - } - return s1; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char s[] = "xxxxxxxxxxx"; - TESTCASE( memcpy( s, abcde, 6 ) == s ); - TESTCASE( s[4] == 'e' ); - TESTCASE( s[5] == '\0' ); - TESTCASE( memcpy( s + 5, abcde, 5 ) == s + 5 ); - TESTCASE( s[9] == 'e' ); - TESTCASE( s[10] == 'x' ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/memmove.c b/waterbox/libc/functions/string/memmove.c deleted file mode 100644 index f83a1abede..0000000000 --- a/waterbox/libc/functions/string/memmove.c +++ /dev/null @@ -1,50 +0,0 @@ -/* memmove( void *, const void *, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -void * memmove( void * s1, const void * s2, size_t n ) -{ - char * dest = (char *) s1; - const char * src = (const char *) s2; - if ( dest <= src ) - { - while ( n-- ) - { - *dest++ = *src++; - } - } - else - { - src += n; - dest += n; - while ( n-- ) - { - *--dest = *--src; - } - } - return s1; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char s[] = "xxxxabcde"; - TESTCASE( memmove( s, s + 4, 5 ) == s ); - TESTCASE( s[0] == 'a' ); - TESTCASE( s[4] == 'e' ); - TESTCASE( s[5] == 'b' ); - TESTCASE( memmove( s + 4, s, 5 ) == s + 4 ); - TESTCASE( s[4] == 'a' ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/memset.c b/waterbox/libc/functions/string/memset.c deleted file mode 100644 index 4946ec4878..0000000000 --- a/waterbox/libc/functions/string/memset.c +++ /dev/null @@ -1,38 +0,0 @@ -/* memset( void *, int, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -void * memset( void * s, int c, size_t n ) -{ - unsigned char * p = (unsigned char *) s; - while ( n-- ) - { - *p++ = (unsigned char) c; - } - return s; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char s[] = "xxxxxxxxx"; - TESTCASE( memset( s, 'o', 10 ) == s ); - TESTCASE( s[9] == 'o' ); - TESTCASE( memset( s, '_', 0 ) == s ); - TESTCASE( s[0] == 'o' ); - TESTCASE( memset( s, '_', 1 ) == s ); - TESTCASE( s[0] == '_' ); - TESTCASE( s[1] == 'o' ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strcat.c b/waterbox/libc/functions/string/strcat.c deleted file mode 100644 index 50d66ee089..0000000000 --- a/waterbox/libc/functions/string/strcat.c +++ /dev/null @@ -1,44 +0,0 @@ -/* strcat( char *, const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -char * strcat( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 ) -{ - char * rc = s1; - if ( *s1 ) - { - while ( *++s1 ); - } - while ( (*s1++ = *s2++) ); - return rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char s[] = "xx\0xxxxxx"; - TESTCASE( strcat( s, abcde ) == s ); - TESTCASE( s[2] == 'a' ); - TESTCASE( s[6] == 'e' ); - TESTCASE( s[7] == '\0' ); - TESTCASE( s[8] == 'x' ); - s[0] = '\0'; - TESTCASE( strcat( s, abcdx ) == s ); - TESTCASE( s[4] == 'x' ); - TESTCASE( s[5] == '\0' ); - TESTCASE( strcat( s, "\0" ) == s ); - TESTCASE( s[5] == '\0' ); - TESTCASE( s[6] == 'e' ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strchr.c b/waterbox/libc/functions/string/strchr.c deleted file mode 100644 index 8c6e8a42ff..0000000000 --- a/waterbox/libc/functions/string/strchr.c +++ /dev/null @@ -1,38 +0,0 @@ -/* strchr( const char *, int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -char * strchr( const char * s, int c ) -{ - do - { - if ( *s == (char) c ) - { - return (char *) s; - } - } while ( *s++ ); - return NULL; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char abccd[] = "abccd"; - TESTCASE( strchr( abccd, 'x' ) == NULL ); - TESTCASE( strchr( abccd, 'a' ) == &abccd[0] ); - TESTCASE( strchr( abccd, 'd' ) == &abccd[4] ); - TESTCASE( strchr( abccd, '\0' ) == &abccd[5] ); - TESTCASE( strchr( abccd, 'c' ) == &abccd[2] ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strcmp.c b/waterbox/libc/functions/string/strcmp.c deleted file mode 100644 index 483260cf39..0000000000 --- a/waterbox/libc/functions/string/strcmp.c +++ /dev/null @@ -1,39 +0,0 @@ -/* strcmp( const char *, const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -int strcmp( const char * s1, const char * s2 ) -{ - while ( ( *s1 ) && ( *s1 == *s2 ) ) - { - ++s1; - ++s2; - } - return ( *(unsigned char *)s1 - *(unsigned char *)s2 ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char cmpabcde[] = "abcde"; - char cmpabcd_[] = "abcd\xfc"; - char empty[] = ""; - TESTCASE( strcmp( abcde, cmpabcde ) == 0 ); - TESTCASE( strcmp( abcde, abcdx ) < 0 ); - TESTCASE( strcmp( abcdx, abcde ) > 0 ); - TESTCASE( strcmp( empty, abcde ) < 0 ); - TESTCASE( strcmp( abcde, empty ) > 0 ); - TESTCASE( strcmp( abcde, cmpabcd_ ) < 0 ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strcoll.c b/waterbox/libc/functions/string/strcoll.c deleted file mode 100644 index 09ada0445b..0000000000 --- a/waterbox/libc/functions/string/strcoll.c +++ /dev/null @@ -1,41 +0,0 @@ -/* strcoll( const char *, const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -#include "_PDCLIB_locale.h" - -int strcoll( const char * s1, const char * s2 ) -{ - const _PDCLIB_ctype_t * ctype = _PDCLIB_threadlocale()->_CType; - - while ( ( *s1 ) && ( ctype[(unsigned char)*s1].collation == ctype[(unsigned char)*s2].collation ) ) - { - ++s1; - ++s2; - } - return ( ctype[(unsigned char)*s1].collation == ctype[(unsigned char)*s2].collation ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char cmpabcde[] = "abcde"; - char empty[] = ""; - TESTCASE( strcmp( abcde, cmpabcde ) == 0 ); - TESTCASE( strcmp( abcde, abcdx ) < 0 ); - TESTCASE( strcmp( abcdx, abcde ) > 0 ); - TESTCASE( strcmp( empty, abcde ) < 0 ); - TESTCASE( strcmp( abcde, empty ) > 0 ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strcpy.c b/waterbox/libc/functions/string/strcpy.c deleted file mode 100644 index d66cbaba5e..0000000000 --- a/waterbox/libc/functions/string/strcpy.c +++ /dev/null @@ -1,35 +0,0 @@ -/* strcpy( char *, const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -char * strcpy( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 ) -{ - char * rc = s1; - while ( ( *s1++ = *s2++ ) ); - return rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char s[] = "xxxxx"; - TESTCASE( strcpy( s, "" ) == s ); - TESTCASE( s[0] == '\0' ); - TESTCASE( s[1] == 'x' ); - TESTCASE( strcpy( s, abcde ) == s ); - TESTCASE( s[0] == 'a' ); - TESTCASE( s[4] == 'e' ); - TESTCASE( s[5] == '\0' ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strcspn.c b/waterbox/libc/functions/string/strcspn.c deleted file mode 100644 index baf8fc799a..0000000000 --- a/waterbox/libc/functions/string/strcspn.c +++ /dev/null @@ -1,48 +0,0 @@ -/* strcspn( const char *, const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -size_t strcspn( const char * s1, const char * s2 ) -{ - size_t len = 0; - const char * p; - while ( s1[len] ) - { - p = s2; - while ( *p ) - { - if ( s1[len] == *p++ ) - { - return len; - } - } - ++len; - } - return len; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( strcspn( abcde, "x" ) == 5 ); - TESTCASE( strcspn( abcde, "xyz" ) == 5 ); - TESTCASE( strcspn( abcde, "zyx" ) == 5 ); - TESTCASE( strcspn( abcdx, "x" ) == 4 ); - TESTCASE( strcspn( abcdx, "xyz" ) == 4 ); - TESTCASE( strcspn( abcdx, "zyx" ) == 4 ); - TESTCASE( strcspn( abcde, "a" ) == 0 ); - TESTCASE( strcspn( abcde, "abc" ) == 0 ); - TESTCASE( strcspn( abcde, "cba" ) == 0 ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strdup.c b/waterbox/libc/functions/string/strdup.c deleted file mode 100644 index 78dd01d4f6..0000000000 --- a/waterbox/libc/functions/string/strdup.c +++ /dev/null @@ -1,49 +0,0 @@ -/* [XSI] char * strdup( const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifdef REGTEST -#define _POSIX_C_SOURCE 200809L -#endif - -#include -#include - -#ifndef REGTEST - -char *strdup(const char *s) -{ - char* ns = NULL; - if(s) { - size_t len = strlen(s) + 1; - ns = malloc(len); - if(ns) - strncpy(ns, s, len); - } - return ns; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - const char *teststr = "Hello, world"; - const char *teststr2 = "An alternative test string with non-7-bit characters \xFE\x8C\n"; - char *testres, *testres2; - - TESTCASE((testres = strdup(teststr)) != NULL); - TESTCASE((testres2 = strdup(teststr2)) != NULL); - TESTCASE(strcmp(testres, teststr) == 0); - TESTCASE(strcmp(testres2, teststr2) == 0); - free(testres); - free(testres2); - - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/string/strerror.c b/waterbox/libc/functions/string/strerror.c deleted file mode 100644 index 5c7bf23bb6..0000000000 --- a/waterbox/libc/functions/string/strerror.c +++ /dev/null @@ -1,39 +0,0 @@ -/* strerror( int ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -#include "_PDCLIB_locale.h" - -/* TODO: Doing this via a static array is not the way to do it. */ -char * strerror( int errnum ) -{ - if ( errnum >= _PDCLIB_ERRNO_MAX ) - { - return (char *)"Unknown error"; - } - else - { - return (char *)_PDCLIB_threadlocale()->_ErrnoStr[errnum]; - } -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -#include -#include - -int main( void ) -{ - TESTCASE( strerror( ERANGE ) != strerror( EDOM ) ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strlcat.c b/waterbox/libc/functions/string/strlcat.c deleted file mode 100644 index 7348702490..0000000000 --- a/waterbox/libc/functions/string/strlcat.c +++ /dev/null @@ -1,57 +0,0 @@ -/* strlcat( char *, const char *, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -#pragma weak strlcat = _PDCLIB_strlcat -size_t _PDCLIB_strlcat( - char *restrict dst, - const char *restrict src, - size_t dstsize); - -size_t _PDCLIB_strlcat( - char *restrict dst, - const char *restrict src, - size_t dstsize) -{ - size_t needed = 0; - size_t j = 0; - - while(dst[needed]) needed++; - - while(needed < dstsize && (dst[needed] = src[j])) - needed++, j++; - - while(src[j++]) needed++; - needed++; - - if (needed > dstsize && dstsize) - dst[dstsize - 1] = 0; - - return needed; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char dstbuf[16]; - - strcpy(dstbuf, "hi"); - TESTCASE_NOREG( strlcat(dstbuf, "", 16) == 3 ); - TESTCASE_NOREG( strlcat(dstbuf, "hi", 16) == 5 ); - TESTCASE_NOREG( strlcat(dstbuf, "hello, world", 16) == 17 ); - TESTCASE_NOREG( strlcat(dstbuf, "hi", 16) == 18 ); - TESTCASE_NOREG( strcmp(dstbuf, "hihihello, worl") == 0); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/string/strlcpy.c b/waterbox/libc/functions/string/strlcpy.c deleted file mode 100644 index bf8421a238..0000000000 --- a/waterbox/libc/functions/string/strlcpy.c +++ /dev/null @@ -1,52 +0,0 @@ -/* strlcpy( char *, const char *, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -#pragma weak strlcpy = _PDCLIB_strlcpy -size_t _PDCLIB_strlcpy( - char *restrict dst, - const char *restrict src, - size_t dstsize); - -size_t _PDCLIB_strlcpy( - char *restrict dst, - const char *restrict src, - size_t dstsize) -{ - size_t needed = 0; - while(needed < dstsize && (dst[needed] = src[needed])) - needed++; - - while(src[needed++]); - - if (needed > dstsize && dstsize) - dst[dstsize - 1] = 0; - - return needed; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ -#ifndef REGTEST - char destbuf[10]; -#endif - TESTCASE_NOREG( strlcpy(NULL, "a", 0) == 2 ); - TESTCASE_NOREG( strlcpy(destbuf, "a", 10) == 2 ); - TESTCASE_NOREG( strcmp(destbuf, "a") == 0 ); - TESTCASE_NOREG( strlcpy(destbuf, "helloworld", 10) == 11 ); - TESTCASE_NOREG( strcmp(destbuf, "helloworl") == 0 ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/string/strlen.c b/waterbox/libc/functions/string/strlen.c deleted file mode 100644 index 042582abbd..0000000000 --- a/waterbox/libc/functions/string/strlen.c +++ /dev/null @@ -1,32 +0,0 @@ -/* strlen( const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -size_t strlen( const char * s ) -{ - size_t rc = 0; - while ( s[rc] ) - { - ++rc; - } - return rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( strlen( abcde ) == 5 ); - TESTCASE( strlen( "" ) == 0 ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strncat.c b/waterbox/libc/functions/string/strncat.c deleted file mode 100644 index 18d8ed596e..0000000000 --- a/waterbox/libc/functions/string/strncat.c +++ /dev/null @@ -1,58 +0,0 @@ -/* strncat( char *, const char *, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -char * strncat( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n ) -{ - char * rc = s1; - while ( *s1 ) - { - ++s1; - } - while ( n && ( *s1++ = *s2++ ) ) - { - --n; - } - if ( n == 0 ) - { - *s1 = '\0'; - } - return rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char s[] = "xx\0xxxxxx"; - TESTCASE( strncat( s, abcde, 10 ) == s ); - TESTCASE( s[2] == 'a' ); - TESTCASE( s[6] == 'e' ); - TESTCASE( s[7] == '\0' ); - TESTCASE( s[8] == 'x' ); - s[0] = '\0'; - TESTCASE( strncat( s, abcdx, 10 ) == s ); - TESTCASE( s[4] == 'x' ); - TESTCASE( s[5] == '\0' ); - TESTCASE( strncat( s, "\0", 10 ) == s ); - TESTCASE( s[5] == '\0' ); - TESTCASE( s[6] == 'e' ); - TESTCASE( strncat( s, abcde, 0 ) == s ); - TESTCASE( s[5] == '\0' ); - TESTCASE( s[6] == 'e' ); - TESTCASE( strncat( s, abcde, 3 ) == s ); - TESTCASE( s[5] == 'a' ); - TESTCASE( s[7] == 'c' ); - TESTCASE( s[8] == '\0' ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strncmp.c b/waterbox/libc/functions/string/strncmp.c deleted file mode 100644 index e1ec0de66e..0000000000 --- a/waterbox/libc/functions/string/strncmp.c +++ /dev/null @@ -1,52 +0,0 @@ -/* strncmp( const char *, const char *, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -int strncmp( const char * s1, const char * s2, size_t n ) -{ - while ( *s1 && n && ( *s1 == *s2 ) ) - { - ++s1; - ++s2; - --n; - } - if ( n == 0 ) - { - return 0; - } - else - { - return ( *(unsigned char *)s1 - *(unsigned char *)s2 ); - } -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char cmpabcde[] = "abcde\0f"; - char cmpabcd_[] = "abcde\xfc"; - char empty[] = ""; - char x[] = "x"; - TESTCASE( strncmp( abcde, cmpabcde, 5 ) == 0 ); - TESTCASE( strncmp( abcde, cmpabcde, 10 ) == 0 ); - TESTCASE( strncmp( abcde, abcdx, 5 ) < 0 ); - TESTCASE( strncmp( abcdx, abcde, 5 ) > 0 ); - TESTCASE( strncmp( empty, abcde, 5 ) < 0 ); - TESTCASE( strncmp( abcde, empty, 5 ) > 0 ); - TESTCASE( strncmp( abcde, abcdx, 4 ) == 0 ); - TESTCASE( strncmp( abcde, x, 0 ) == 0 ); - TESTCASE( strncmp( abcde, x, 1 ) < 0 ); - TESTCASE( strncmp( abcde, cmpabcd_, 10 ) < 0 ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strncpy.c b/waterbox/libc/functions/string/strncpy.c deleted file mode 100644 index 2c58d538fb..0000000000 --- a/waterbox/libc/functions/string/strncpy.c +++ /dev/null @@ -1,54 +0,0 @@ -/* strncpy( char *, const char *, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -char * strncpy( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n ) -{ - char * rc = s1; - while ( ( n > 0 ) && ( *s1++ = *s2++ ) ) - { - /* Cannot do "n--" in the conditional as size_t is unsigned and we have - to check it again for >0 in the next loop below, so we must not risk - underflow. - */ - --n; - } - /* Checking against 1 as we missed the last --n in the loop above. */ - while ( n-- > 1 ) - { - *s1++ = '\0'; - } - return rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char s[] = "xxxxxxx"; - TESTCASE( strncpy( s, "", 1 ) == s ); - TESTCASE( s[0] == '\0' ); - TESTCASE( s[1] == 'x' ); - TESTCASE( strncpy( s, abcde, 6 ) == s ); - TESTCASE( s[0] == 'a' ); - TESTCASE( s[4] == 'e' ); - TESTCASE( s[5] == '\0' ); - TESTCASE( s[6] == 'x' ); - TESTCASE( strncpy( s, abcde, 7 ) == s ); - TESTCASE( s[6] == '\0' ); - TESTCASE( strncpy( s, "xxxx", 3 ) == s ); - TESTCASE( s[0] == 'x' ); - TESTCASE( s[2] == 'x' ); - TESTCASE( s[3] == 'd' ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strndup.c b/waterbox/libc/functions/string/strndup.c deleted file mode 100644 index b7baca2cc5..0000000000 --- a/waterbox/libc/functions/string/strndup.c +++ /dev/null @@ -1,63 +0,0 @@ -/* [XSI] char * strndup( const char *, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifdef REGTEST -#define _POSIX_C_SOURCE 200809L -#endif - -#include -#include - -#ifndef REGTEST - -char *strndup( const char * s, size_t len ) -{ - char* ns = NULL; - if(s) { - ns = malloc(len + 1); - if(ns) { - ns[len] = 0; - // strncpy to be pedantic about modification in multithreaded - // applications - return strncpy(ns, s, len); - } - } - return ns; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ -#ifndef REGTEST - /* Missing on Windows. Maybe use conditionals? */ - const char *teststr = "Hello, world"; - const char *teststr2 = "\xFE\x8C\n"; - char *testres, *testres2; - - TESTCASE((testres = strndup(teststr, 5)) != NULL); - TESTCASE((testres2 = strndup(teststr2, 1)) != NULL); - TESTCASE(strcmp(testres, teststr) != 0); - TESTCASE(strncmp(testres, teststr, 5) == 0); - TESTCASE(strcmp(testres2, teststr2) != 0); - TESTCASE(strncmp(testres2, teststr2, 1) == 0); - free(testres); - free(testres2); - TESTCASE((testres = strndup(teststr, 20)) != NULL); - TESTCASE((testres2 = strndup(teststr2, 5)) != NULL); - TESTCASE(strcmp(testres, teststr) == 0); - TESTCASE(strcmp(testres2, teststr2) == 0); - free(testres); - free(testres2); -#endif - - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/string/strnlen.c b/waterbox/libc/functions/string/strnlen.c deleted file mode 100644 index 915fa76c07..0000000000 --- a/waterbox/libc/functions/string/strnlen.c +++ /dev/null @@ -1,36 +0,0 @@ -/* strnlen( const char *, size_t len ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST - -size_t strnlen( const char * s, size_t maxlen ) -{ - for( size_t len = 0; len != maxlen; len++ ) - { - if(s[len] == '\0') - return len; - } - return maxlen; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ -#ifndef REGTEST - TESTCASE( strnlen( abcde, 5 ) == 5 ); - TESTCASE( strnlen( abcde, 3 ) == 3 ) - TESTCASE( strnlen( "", SIZE_MAX ) == 0 ); -#endif - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strpbrk.c b/waterbox/libc/functions/string/strpbrk.c deleted file mode 100644 index 1615ce3ff9..0000000000 --- a/waterbox/libc/functions/string/strpbrk.c +++ /dev/null @@ -1,47 +0,0 @@ -/* strpbrk( const char *, const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -char * strpbrk( const char * s1, const char * s2 ) -{ - const char * p1 = s1; - const char * p2; - while ( *p1 ) - { - p2 = s2; - while ( *p2 ) - { - if ( *p1 == *p2++ ) - { - return (char *) p1; - } - } - ++p1; - } - return NULL; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( strpbrk( abcde, "x" ) == NULL ); - TESTCASE( strpbrk( abcde, "xyz" ) == NULL ); - TESTCASE( strpbrk( abcdx, "x" ) == &abcdx[4] ); - TESTCASE( strpbrk( abcdx, "xyz" ) == &abcdx[4] ); - TESTCASE( strpbrk( abcdx, "zyx" ) == &abcdx[4] ); - TESTCASE( strpbrk( abcde, "a" ) == &abcde[0] ); - TESTCASE( strpbrk( abcde, "abc" ) == &abcde[0] ); - TESTCASE( strpbrk( abcde, "cba" ) == &abcde[0] ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strrchr.c b/waterbox/libc/functions/string/strrchr.c deleted file mode 100644 index 2a41874b64..0000000000 --- a/waterbox/libc/functions/string/strrchr.c +++ /dev/null @@ -1,39 +0,0 @@ -/* strrchr( const char *, int c ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -char * strrchr( const char * s, int c ) -{ - size_t i = 0; - while ( s[i++] ); - do - { - if ( s[--i] == (char) c ) - { - return (char *) s + i; - } - } while ( i ); - return NULL; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char abccd[] = "abccd"; - TESTCASE( strrchr( abcde, '\0' ) == &abcde[5] ); - TESTCASE( strrchr( abcde, 'e' ) == &abcde[4] ); - TESTCASE( strrchr( abcde, 'a' ) == &abcde[0] ); - TESTCASE( strrchr( abccd, 'c' ) == &abccd[3] ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strspn.c b/waterbox/libc/functions/string/strspn.c deleted file mode 100644 index 8869a84683..0000000000 --- a/waterbox/libc/functions/string/strspn.c +++ /dev/null @@ -1,47 +0,0 @@ -/* strspn( const char *, const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -size_t strspn( const char * s1, const char * s2 ) -{ - size_t len = 0; - const char * p; - while ( s1[ len ] ) - { - p = s2; - while ( *p ) - { - if ( s1[len] == *p ) - { - break; - } - ++p; - } - if ( ! *p ) - { - return len; - } - ++len; - } - return len; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( strspn( abcde, "abc" ) == 3 ); - TESTCASE( strspn( abcde, "b" ) == 0 ); - TESTCASE( strspn( abcde, abcde ) == 5 ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strstr.c b/waterbox/libc/functions/string/strstr.c deleted file mode 100644 index 5c97a750c0..0000000000 --- a/waterbox/libc/functions/string/strstr.c +++ /dev/null @@ -1,49 +0,0 @@ -/* strstr( const char *, const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -char * strstr( const char * s1, const char * s2 ) -{ - const char * p1 = s1; - const char * p2; - while ( *s1 ) - { - p2 = s2; - while ( *p2 && ( *p1 == *p2 ) ) - { - ++p1; - ++p2; - } - if ( ! *p2 ) - { - return (char *) s1; - } - ++s1; - p1 = s1; - } - return NULL; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char s[] = "abcabcabcdabcde"; - TESTCASE( strstr( s, "x" ) == NULL ); - TESTCASE( strstr( s, "xyz" ) == NULL ); - TESTCASE( strstr( s, "a" ) == &s[0] ); - TESTCASE( strstr( s, "abc" ) == &s[0] ); - TESTCASE( strstr( s, "abcd" ) == &s[6] ); - TESTCASE( strstr( s, "abcde" ) == &s[10] ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strtok.c b/waterbox/libc/functions/string/strtok.c deleted file mode 100644 index 3c427c549c..0000000000 --- a/waterbox/libc/functions/string/strtok.c +++ /dev/null @@ -1,105 +0,0 @@ -/* strtok( char *, const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -char * strtok( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 ) -{ - static char * tmp = NULL; - const char * p = s2; - - if ( s1 != NULL ) - { - /* new string */ - tmp = s1; - } - else - { - /* old string continued */ - if ( tmp == NULL ) - { - /* No old string, no new string, nothing to do */ - return NULL; - } - s1 = tmp; - } - - /* skipping leading s2 characters */ - while ( *p && *s1 ) - { - if ( *s1 == *p ) - { - /* found seperator; skip and start over */ - ++s1; - p = s2; - continue; - } - ++p; - } - - if ( ! *s1 ) - { - /* no more to parse */ - return ( tmp = NULL ); - } - - /* skipping non-s2 characters */ - tmp = s1; - while ( *tmp ) - { - p = s2; - while ( *p ) - { - if ( *tmp == *p++ ) - { - /* found seperator; overwrite with '\0', position tmp, return */ - *tmp++ = '\0'; - return s1; - } - } - ++tmp; - } - - /* parsed to end of string */ - tmp = NULL; - return s1; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char s[] = "_a_bc__d_"; - TESTCASE( strtok( s, "_" ) == &s[1] ); - TESTCASE( s[1] == 'a' ); - TESTCASE( s[2] == '\0' ); - TESTCASE( strtok( NULL, "_" ) == &s[3] ); - TESTCASE( s[3] == 'b' ); - TESTCASE( s[4] == 'c' ); - TESTCASE( s[5] == '\0' ); - TESTCASE( strtok( NULL, "_" ) == &s[7] ); - TESTCASE( s[6] == '_' ); - TESTCASE( s[7] == 'd' ); - TESTCASE( s[8] == '\0' ); - TESTCASE( strtok( NULL, "_" ) == NULL ); - strcpy( s, "ab_cd" ); - TESTCASE( strtok( s, "_" ) == &s[0] ); - TESTCASE( s[0] == 'a' ); - TESTCASE( s[1] == 'b' ); - TESTCASE( s[2] == '\0' ); - TESTCASE( strtok( NULL, "_" ) == &s[3] ); - TESTCASE( s[3] == 'c' ); - TESTCASE( s[4] == 'd' ); - TESTCASE( s[5] == '\0' ); - TESTCASE( strtok( NULL, "_" ) == NULL ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/string/strxfrm.c b/waterbox/libc/functions/string/strxfrm.c deleted file mode 100644 index 3692257b23..0000000000 --- a/waterbox/libc/functions/string/strxfrm.c +++ /dev/null @@ -1,48 +0,0 @@ -/* strxfrm( char *, const char *, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -#include "_PDCLIB_locale.h" - -size_t strxfrm( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n ) -{ - const _PDCLIB_ctype_t *ctype = _PDCLIB_threadlocale()->_CType; - size_t len = strlen( s2 ); - if ( len < n ) - { - /* Cannot use strncpy() here as the filling of s1 with '\0' is not part - of the spec. - */ - while ( n-- && ( *s1++ = ctype[(unsigned char)*s2++].collation ) ); - } - return len; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - char s[] = "xxxxxxxxxxx"; - TESTCASE( strxfrm( NULL, "123456789012", 0 ) == 12 ); - TESTCASE( strxfrm( s, "123456789012", 12 ) == 12 ); - /* - The following test case is true in *this* implementation, but doesn't have to. - TESTCASE( s[0] == 'x' ); - */ - TESTCASE( strxfrm( s, "1234567890", 11 ) == 10 ); - TESTCASE( s[0] == '1' ); - TESTCASE( s[9] == '0' ); - TESTCASE( s[10] == '\0' ); - return TEST_RESULTS; -} -#endif - diff --git a/waterbox/libc/functions/time/clock.c b/waterbox/libc/functions/time/clock.c deleted file mode 100644 index e3add98b53..0000000000 --- a/waterbox/libc/functions/time/clock.c +++ /dev/null @@ -1,28 +0,0 @@ -/* clock( void ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -clock_t clock( void ) -{ - /* TODO: Placeholder implementation (valid but useless) */ - return -1; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( NO_TESTDRIVER ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/time/time.c b/waterbox/libc/functions/time/time.c deleted file mode 100644 index 6bbf4c76c6..0000000000 --- a/waterbox/libc/functions/time/time.c +++ /dev/null @@ -1,19 +0,0 @@ -#include - -#ifndef REGTEST -time_t time(time_t* t) -{ - if(t) *t = -1; - return -1; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/time/timespec_get.c b/waterbox/libc/functions/time/timespec_get.c deleted file mode 100644 index 04acf61ac9..0000000000 --- a/waterbox/libc/functions/time/timespec_get.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#ifndef REGTEST - -int timespec_get( struct timespec *ts, int base ) -{ - return 0; -} -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/uchar/_PDCLIB_c16slen.c b/waterbox/libc/functions/uchar/_PDCLIB_c16slen.c deleted file mode 100644 index 1a0c3e504d..0000000000 --- a/waterbox/libc/functions/uchar/_PDCLIB_c16slen.c +++ /dev/null @@ -1,28 +0,0 @@ -/* _PDCLIB_c16slen( const char16_t * ); - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef REGTEST -#include - -size_t _PDCLIB_c16slen( const char16_t * str ) -{ - size_t n = 0; - while(*(str++)) n++; - return n; -} - - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/uchar/_PDCLIB_c32slen.c b/waterbox/libc/functions/uchar/_PDCLIB_c32slen.c deleted file mode 100644 index 4c4df058f7..0000000000 --- a/waterbox/libc/functions/uchar/_PDCLIB_c32slen.c +++ /dev/null @@ -1,28 +0,0 @@ -/* _PDCLIB_c32slen( const char32_t * ); - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef REGTEST -#include - -size_t _PDCLIB_c32slen( const char32_t * str ) -{ - size_t n = 0; - while(*(str++)) n++; - return n; -} - - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/uchar/_PDCLIB_c32srtombs.c b/waterbox/libc/functions/uchar/_PDCLIB_c32srtombs.c deleted file mode 100644 index a45ba98879..0000000000 --- a/waterbox/libc/functions/uchar/_PDCLIB_c32srtombs.c +++ /dev/null @@ -1,57 +0,0 @@ -/* _PDCLIB_c32srtombs( char *, const char32_t * *, size_t, mbstate_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef REGTEST -#include -#include -#include -#include "_PDCLIB_encoding.h" -#include "_PDCLIB_locale.h" - -static size_t _PDCLIB_c32srtombs_l( - char *restrict dst, - const char32_t **restrict src, - size_t len, - mbstate_t *restrict ps, - _PDCLIB_locale_t restrict l) -{ - char *restrict *restrict dstp = dst ? &dst : NULL; - len = dst ? len : SIZE_MAX; - - size_t srclen = _PDCLIB_c32slen(*src); - size_t dstlen = len; - - if(l->_Codec->__c32stombs(dstp, &dstlen, src, &srclen, ps)) { - // Successful conversion - return len - dstlen; - } else { - // Failed conversion - errno = EILSEQ; - return (size_t) -1; - } -} - -size_t _PDCLIB_c32srtombs( - char *restrict dst, - const char32_t **restrict src, - size_t len, - mbstate_t *restrict ps -) -{ - return _PDCLIB_c32srtombs_l(dst, src, len, ps, _PDCLIB_threadlocale()); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( NO_TESTDRIVER ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/uchar/_PDCLIB_mbsrtoc32s.c b/waterbox/libc/functions/uchar/_PDCLIB_mbsrtoc32s.c deleted file mode 100644 index 85ea099f4c..0000000000 --- a/waterbox/libc/functions/uchar/_PDCLIB_mbsrtoc32s.c +++ /dev/null @@ -1,56 +0,0 @@ -/* _PDCLIB_mbsrtoc32s( char32_t *, const char * *, size_t, mbstate_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef REGTEST -#include -#include -#include -#include -#include "_PDCLIB_encoding.h" -#include "_PDCLIB_locale.h" - -static size_t _PDCLIB_mbsrtoc32s_l -( - char32_t *restrict dst, - const char **restrict src, - size_t len, - mbstate_t *restrict ps, - locale_t restrict l -) -{ - size_t dstlen = len = dst ? len : SIZE_MAX; - char32_t *restrict *restrict dstp = dst ? &dst : NULL; - - size_t srclen = strlen(*src); - if(l->_Codec->__mbstoc32s(dstp, &dstlen, src, &srclen, ps)) { - return len - dstlen; - } else { - errno = EILSEQ; - return (size_t) -1; - } -} - -size_t _PDCLIB_mbsrtoc32s( - char32_t *restrict dst, - const char **restrict src, - size_t len, - mbstate_t *restrict ps -) -{ - return _PDCLIB_mbsrtoc32s_l(dst, src, len, ps, _PDCLIB_threadlocale()); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( NO_TESTDRIVER ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/uchar/c16rtomb.c b/waterbox/libc/functions/uchar/c16rtomb.c deleted file mode 100644 index 5070e28f86..0000000000 --- a/waterbox/libc/functions/uchar/c16rtomb.c +++ /dev/null @@ -1,104 +0,0 @@ -/* c16rtomb( char *, char16_t, mbstate_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef REGTEST -#include -#include -#include -#include -#include -#include "_PDCLIB_encoding.h" -#include "_PDCLIB_locale.h" - -size_t c16rtomb_l( - char *restrict s, - char16_t c16, - mbstate_t *restrict ps, - locale_t restrict l -) -{ - const char16_t *restrict psrc = &c16; - char buf[s ? 0 : MB_CUR_MAX]; - s = s ? s : buf; - - if(!l->_Codec->__c16stombs) { - // Codec doesn't support direct conversion - translate via UCS-4 - if(ps->_Surrogate == 0) { - // No pending surrogate - if((c16 & 0xF800) == 0xD800) { - // Surrogate range - if((c16 & 0x0400) == 0) { - // 0xD800 -> 0xDBFF leading surrogate - ps->_Surrogate = c16; - - // Need more data - // Return 0 - we haven't output anything yet - - /* STD: ISO/IEC 9899:2011 is very implcifit about this being - * the correct return value. N1040, from which the - * function was adopted, is explicit about 0 being a - * valid return. - */ - return (size_t) 0; - } else { - // 0xDC00 -> 0xDFFF trailing surrogate - errno = EILSEQ; - return (size_t) -1; - } - } else { - // BMP range - UTF16 == UCS-4, pass through to c32rtomb_l - return c32rtomb_l(s, c16, ps, l); - } - } else { - // We have a stored surrogate - if((c16 & 0xFC00) == 0xDC00) { - // Trailing surrogate - char32_t c32 = (ps->_Surrogate & 0x3FF) << 10 | (c16 & 0x3FF); - ps->_Surrogate = 0; - return c32rtomb_l(s, c32, ps, l); - } else { - // Not a trailing surrogate - encoding error - errno = EILSEQ; - return (size_t) -1; - } - - } - } else { - // Codec supports direct conversion - size_t srcsz = 1; - size_t dstsz = MB_CUR_MAX; - size_t dstrem = dstsz; - - if(l->_Codec->__c16stombs(&s, &dstrem, &psrc, &srcsz, ps)) { - // Successful conversion - return dstsz - dstrem; - } else { - errno = EILSEQ; - return (size_t) -1; - } - } -} - -size_t c16rtomb( - char *restrict s, - char16_t c16, - mbstate_t *restrict ps -) -{ - return c16rtomb_l(s, c16, ps, _PDCLIB_threadlocale()); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( NO_TESTDRIVER ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/uchar/c32rtomb.c b/waterbox/libc/functions/uchar/c32rtomb.c deleted file mode 100644 index 19f65f1094..0000000000 --- a/waterbox/libc/functions/uchar/c32rtomb.c +++ /dev/null @@ -1,59 +0,0 @@ -/* c32rtomb( char *, char32_t, mbstate_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef REGTEST -#include -#include -#include -#include -#include -#include "_PDCLIB_encoding.h" -#include "_PDCLIB_locale.h" - -size_t c32rtomb_l( - char *restrict s, - char32_t c32, - mbstate_t *restrict ps, - locale_t restrict l -) -{ - char buf[s ? 0 : MB_CUR_MAX]; - s = s ? s : buf; - - const char32_t *restrict psrc = &c32; - size_t srcsz = 1; - size_t dstsz = MB_CUR_MAX; - size_t dstrem = dstsz; - - if(l->_Codec->__c32stombs(&s, &dstrem, &psrc, &srcsz, ps)) { - // Successful conversion - return dstsz - dstrem; - } else { - errno = EILSEQ; - return (size_t) -1; - } -} - -size_t c32rtomb( - char *restrict s, - char32_t c32, - mbstate_t *restrict ps -) -{ - return c32rtomb_l(s, c32, ps, _PDCLIB_threadlocale()); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( NO_TESTDRIVER ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/uchar/mbrtoc16.c b/waterbox/libc/functions/uchar/mbrtoc16.c deleted file mode 100644 index c44c165c9f..0000000000 --- a/waterbox/libc/functions/uchar/mbrtoc16.c +++ /dev/null @@ -1,95 +0,0 @@ -/* size_t mbrtoc16( char16_t *, const char *, size_t, mbstate_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef REGTEST -#include -#include -#include -#include -#include "_PDCLIB_encoding.h" -#include "_PDCLIB_locale.h" - -size_t mbrtoc16_l( - char16_t *restrict pc16, - const char *restrict s, - size_t n, - mbstate_t *restrict ps, - locale_t restrict l -) -{ - size_t dstlen = 1; - size_t nr = n; - - if(!l->_Codec->__mbstoc16s) { - // No UTF-16 support in codec. Must synthesize on top of UCS-4 support. - - if(ps->_Surrogate) { - // If a pending surrogate is stored in the state - *pc16 = ps->_Surrogate; - ps->_Surrogate = 0; - return (size_t) -3; - } - - char32_t c32; - size_t res = mbrtoc32_l(&c32, s, n, ps, l); - if(res != (size_t) -1) { - // Conversion was successful. Check for surrogates - if(c32 <= 0xFFFF) { - // BMP char - *pc16 = c32; - } else { - // Supplementary char - *pc16 = 0xD800 | (c32 >> 10); - ps->_Surrogate = 0xDC00 | (c32 & 0x3FF); - } - } - return res; - } else if(l->_Codec->__mbstoc16s(&pc16, &dstlen, &s, &nr, ps)) { - // Successful conversion - if(dstlen == 0) { - // A character was output - if(nr == n) { - // The output character resulted entirely from stored state - return (size_t) -3; - } else if(pc16[-1] == 0) { - // Was null character - return 0; - } else { - // Count of processed characters - return n - nr; - } - } else { - assert(nr == 0 && "Must have processed whole input"); - return (size_t) -2; - } - } else { - // Failed conversion - errno = EILSEQ; - return (size_t) -1; - } -} - -size_t mbrtoc16( - char16_t *restrict pc16, - const char *restrict s, - size_t n, - mbstate_t *restrict ps -) -{ - return mbrtoc16_l(pc16, s, n, ps, _PDCLIB_threadlocale()); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( NO_TESTDRIVER ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/uchar/mbrtoc32.c b/waterbox/libc/functions/uchar/mbrtoc32.c deleted file mode 100644 index 0209b36a94..0000000000 --- a/waterbox/libc/functions/uchar/mbrtoc32.c +++ /dev/null @@ -1,72 +0,0 @@ -/* size_t mbrtoc32( char32_t *, const char *, size_t, mbstate_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef REGTEST -#include -#include -#include -#include -#include "_PDCLIB_encoding.h" -#include "_PDCLIB_locale.h" - -size_t mbrtoc32_l( - char32_t *restrict pc32, - const char *restrict s, - size_t n, - mbstate_t *restrict ps, - locale_t restrict l -) -{ - size_t dstlen = 1; - size_t nr = n; - - if(l->_Codec->__mbstoc32s(&pc32, &dstlen, &s, &nr, ps)) { - // Successful conversion - if(dstlen == 0) { - // A character was output - if(nr == n) { - // The output character resulted entirely from stored state - // With UTF-32, this shouldn't be possible? - return (size_t) -3; - } else if(pc32[-1] == 0) { - // Was null character - return 0; - } else { - // Count of processed characters - return n - nr; - } - } else { - assert(nr == 0 && "Must have processed whole input"); - return (size_t) -2; - } - } else { - // Failed conversion - errno = EILSEQ; - return (size_t) -1; - } -} - -size_t mbrtoc32( - char32_t *restrict pc32, - const char *restrict s, - size_t n, - mbstate_t *restrict ps -) -{ - return mbrtoc32_l(pc32, s, n, ps, _PDCLIB_threadlocale()); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( NO_TESTDRIVER ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wchar/mbrtowc.c b/waterbox/libc/functions/wchar/mbrtowc.c deleted file mode 100644 index 31be656a43..0000000000 --- a/waterbox/libc/functions/wchar/mbrtowc.c +++ /dev/null @@ -1,92 +0,0 @@ -/* mbrtowc( wchar_t * pwc, const char * s, size_t n, mbstate_t * ps ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include -#include -#include -#include "_PDCLIB_encoding.h" -#include "_PDCLIB_locale.h" - -static size_t mbrtowc_l( - wchar_t *restrict pwc, - const char *restrict s, - size_t n, - mbstate_t *restrict ps, - locale_t restrict l -) -{ - size_t res; - - if(s == NULL) { - s = ""; - n = 1; - } - - if(ps->_PendState == _PendPrefix) { - res = _PDCLIB_mbrtocwc_l(pwc, &ps->_PendChar, 1, ps, l); - switch(res) { - case 0: - // Converted the NUL character - ps->_PendState = _PendClear; - return 0; - - case 1: - // Successful conversion - ps->_PendChar = *s; - return 1; - - case (size_t) -1: - // Illegal sequence. mbrtocwc has already set errno. - return (size_t) -1; - - case (size_t) -3: - assert(!"Codec had buffered two characters"); - _PDCLIB_UNREACHABLE; - return 0; - - case (size_t) -2: - // Incomplete character, continue - break; - } - } - - // _PendClear state - res = _PDCLIB_mbrtocwc_l(pwc, s, n, ps, l); - switch(res) { - case (size_t) -3: - // Converted entirely from internal state - ps->_PendChar = *s; - ps->_PendState = _PendPrefix; - return 1; - default: - return res; - } -} - -size_t mbrtowc( - wchar_t *restrict pwc, - const char *restrict s, - size_t n, - mbstate_t *restrict ps -) -{ - static mbstate_t st; - return mbrtowc_l(pwc, s, n, ps ? ps : &st, _PDCLIB_threadlocale()); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( NO_TESTDRIVER ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wchar/mbsinit.c b/waterbox/libc/functions/wchar/mbsinit.c deleted file mode 100644 index 0e6d7d3264..0000000000 --- a/waterbox/libc/functions/wchar/mbsinit.c +++ /dev/null @@ -1,53 +0,0 @@ -/* mbsinit( mbstate_t * ps ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_encoding.h" -#include "_PDCLIB_locale.h" - -static int _PDCLIB_mbsinit_l( const mbstate_t *ps, locale_t l ) -{ - if( ps ) { - return ps->_Surrogate == 0 - && ps->_PendState == 0 - && l->_Codec->__mbsinit(ps); - } else return 1; -} - -int mbsinit( const mbstate_t * ps ) -{ - return _PDCLIB_mbsinit_l(ps, _PDCLIB_threadlocale()); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - mbstate_t mbs; - memset(&mbs, 0, sizeof mbs); - - TESTCASE(mbsinit(NULL) != 0); - TESTCASE(mbsinit(&mbs) != 0); - -#ifndef REGTEST - // Surrogate pending - mbs._Surrogate = 0xFEED; - TESTCASE(mbsinit(&mbs) == 0); - - mbs._Surrogate = 0; - mbs._PendState = 1; - TESTCASE(mbsinit(&mbs) == 0); -#endif - return TEST_RESULTS; -} -#endif - - - diff --git a/waterbox/libc/functions/wchar/wcrtomb.c b/waterbox/libc/functions/wchar/wcrtomb.c deleted file mode 100644 index d6ed4248a4..0000000000 --- a/waterbox/libc/functions/wchar/wcrtomb.c +++ /dev/null @@ -1,52 +0,0 @@ -/* wcrtomb( char * s, wchar_t wc, mbstate_t * ps ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef REGTEST -#include -#include -#include -#include -#include -#include "_PDCLIB_encoding.h" -#include "_PDCLIB_locale.h" - -#if 0 -/* - TODO: Other conversion functions call static ..._l helpers, but this one - does not, making this function "defined but not used". -*/ -static size_t wcrtomb_l( - char *restrict s, - wchar_t wc, - mbstate_t *restrict ps, - locale_t restrict l -) -{ - return _PDCLIB_cwcrtomb_l(s, wc, ps, l); -} -#endif - -size_t wcrtomb( - char *restrict s, - wchar_t wc, - mbstate_t *restrict ps -) -{ - static mbstate_t st; - return _PDCLIB_cwcrtomb(s, wc, ps ? ps : &st); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( NO_TESTDRIVER ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wchar/wcscat.c b/waterbox/libc/functions/wchar/wcscat.c deleted file mode 100644 index c467af0ef0..0000000000 --- a/waterbox/libc/functions/wchar/wcscat.c +++ /dev/null @@ -1,45 +0,0 @@ -/* wcscat( wchar_t *, const wchar_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -wchar_t * wcscat( wchar_t * _PDCLIB_restrict s1, - const wchar_t * _PDCLIB_restrict s2 ) -{ - wchar_t * rc = s1; - if ( *s1 ) - { - while ( *++s1 ); - } - while ( (*s1++ = *s2++) ); - return rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - wchar_t s[] = L"xx\0xxxxxx"; - TESTCASE( wcscat( s, wabcde ) == s ); - TESTCASE( s[2] == L'a' ); - TESTCASE( s[6] == L'e' ); - TESTCASE( s[7] == L'\0' ); - TESTCASE( s[8] == L'x' ); - s[0] = L'\0'; - TESTCASE( wcscat( s, wabcdx ) == s ); - TESTCASE( s[4] == L'x' ); - TESTCASE( s[5] == L'\0' ); - TESTCASE( wcscat( s, L"\0" ) == s ); - TESTCASE( s[5] == L'\0' ); - TESTCASE( s[6] == L'e' ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wchar/wcschr.c b/waterbox/libc/functions/wchar/wcschr.c deleted file mode 100644 index 5629aa6fdc..0000000000 --- a/waterbox/libc/functions/wchar/wcschr.c +++ /dev/null @@ -1,32 +0,0 @@ -/* wcschr( const wchar_t *, wchar_t ); - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST - -wchar_t *wcschr(const wchar_t * haystack, wchar_t needle) -{ - while(*haystack) { - if(*haystack == needle) return (wchar_t*) haystack; - haystack++; - } - return NULL; -} - - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/wchar/wcscmp.c b/waterbox/libc/functions/wchar/wcscmp.c deleted file mode 100644 index b338b5d30b..0000000000 --- a/waterbox/libc/functions/wchar/wcscmp.c +++ /dev/null @@ -1,39 +0,0 @@ -/* wcscmp( const wchar_t *, const wchar_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -int wcscmp( const wchar_t * s1, const wchar_t * s2 ) -{ - while ( ( *s1 ) && ( *s1 == *s2 ) ) - { - ++s1; - ++s2; - } - return ( *(wchar_t *)s1 - *(wchar_t *)s2 ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - wchar_t cmpabcde[] = L"abcde"; - wchar_t cmpabcd_[] = L"abcd\xfc"; - wchar_t empty[] = L""; - TESTCASE( wcscmp( wabcde, cmpabcde ) == 0 ); - TESTCASE( wcscmp( wabcde, wabcdx ) < 0 ); - TESTCASE( wcscmp( wabcdx, wabcde ) > 0 ); - TESTCASE( wcscmp( empty, wabcde ) < 0 ); - TESTCASE( wcscmp( wabcde, empty ) > 0 ); - TESTCASE( wcscmp( wabcde, cmpabcd_ ) < 0 ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wchar/wcscoll.c b/waterbox/libc/functions/wchar/wcscoll.c deleted file mode 100644 index 9c7c2a6035..0000000000 --- a/waterbox/libc/functions/wchar/wcscoll.c +++ /dev/null @@ -1,36 +0,0 @@ -/* wcscoll( const wchar_t *, const wchar_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -/* I did much searching as to how various people implement this. - * - * OpenBSD, NetBSD and Musl libc for Linux implement this as a call to wcscmp - * and have various "todo" notices on this function, and on the other hand - * glibc implements it as a 500 line function. FreeBSD has an implementation - * which kind of uses their single byte character strcoll data for the first - * 256 characters, but looks incredibly fragile and likely to break. - * - * TL;DR: Nobody uses this, and this will probably work perfectly fine for you. - */ - -int wcscoll( const wchar_t * s1, const wchar_t * s2 ) -{ - return wcscmp(s1, s2); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wchar/wcscpy.c b/waterbox/libc/functions/wchar/wcscpy.c deleted file mode 100644 index 62a52663a5..0000000000 --- a/waterbox/libc/functions/wchar/wcscpy.c +++ /dev/null @@ -1,33 +0,0 @@ -/* wchar_t * wcscpy( wchar_t *, const wchar_t * ); - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -wchar_t *wcscpy( wchar_t * _PDCLIB_restrict dest, - const wchar_t * _PDCLIB_restrict src) -{ - wchar_t * rv = dest; - while(*src) { - *(dest++) = *(src++); - } - - return rv; -} - - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/wchar/wcscspn.c b/waterbox/libc/functions/wchar/wcscspn.c deleted file mode 100644 index 248c20072b..0000000000 --- a/waterbox/libc/functions/wchar/wcscspn.c +++ /dev/null @@ -1,48 +0,0 @@ -/* wcscspn( const wchar_t *, const wchar_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -size_t wcscspn( const wchar_t * s1, const wchar_t * s2 ) -{ - size_t len = 0; - const wchar_t * p; - while ( s1[len] ) - { - p = s2; - while ( *p ) - { - if ( s1[len] == *p++ ) - { - return len; - } - } - ++len; - } - return len; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( wcscspn( wabcde, L"x" ) == 5 ); - TESTCASE( wcscspn( wabcde, L"xyz" ) == 5 ); - TESTCASE( wcscspn( wabcde, L"zyx" ) == 5 ); - TESTCASE( wcscspn( wabcdx, L"x" ) == 4 ); - TESTCASE( wcscspn( wabcdx, L"xyz" ) == 4 ); - TESTCASE( wcscspn( wabcdx, L"zyx" ) == 4 ); - TESTCASE( wcscspn( wabcde, L"a" ) == 0 ); - TESTCASE( wcscspn( wabcde, L"abc" ) == 0 ); - TESTCASE( wcscspn( wabcde, L"cba" ) == 0 ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wchar/wcslen.c b/waterbox/libc/functions/wchar/wcslen.c deleted file mode 100644 index 00e3ca5500..0000000000 --- a/waterbox/libc/functions/wchar/wcslen.c +++ /dev/null @@ -1,29 +0,0 @@ -/* wcslen( const wchar_t * ); - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -size_t wcslen( const wchar_t * str ) -{ - size_t n = 0; - while(*(str++)) n++; - return n; -} - - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/wchar/wcsncat.c b/waterbox/libc/functions/wchar/wcsncat.c deleted file mode 100644 index 633e54df64..0000000000 --- a/waterbox/libc/functions/wchar/wcsncat.c +++ /dev/null @@ -1,60 +0,0 @@ -/* wcsncat( wchar_t *, const wchar_t *, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -wchar_t * wcsncat( wchar_t * _PDCLIB_restrict s1, - const wchar_t * _PDCLIB_restrict s2, - size_t n ) -{ - wchar_t * rc = s1; - while ( *s1 ) - { - ++s1; - } - while ( n && ( *s1++ = *s2++ ) ) - { - --n; - } - if ( n == 0 ) - { - *s1 = '\0'; - } - return rc; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - wchar_t s[] = L"xx\0xxxxxx"; - TESTCASE( wcsncat( s, wabcde, 10 ) == s ); - TESTCASE( s[2] == L'a' ); - TESTCASE( s[6] == L'e' ); - TESTCASE( s[7] == L'\0' ); - TESTCASE( s[8] == L'x' ); - s[0] = L'\0'; - TESTCASE( wcsncat( s, wabcdx, 10 ) == s ); - TESTCASE( s[4] == L'x' ); - TESTCASE( s[5] == L'\0' ); - TESTCASE( wcsncat( s, L"\0", 10 ) == s ); - TESTCASE( s[5] == L'\0' ); - TESTCASE( s[6] == L'e' ); - TESTCASE( wcsncat( s, wabcde, 0 ) == s ); - TESTCASE( s[5] == L'\0' ); - TESTCASE( s[6] == L'e' ); - TESTCASE( wcsncat( s, wabcde, 3 ) == s ); - TESTCASE( s[5] == L'a' ); - TESTCASE( s[7] == L'c' ); - TESTCASE( s[8] == L'\0' ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wchar/wcsncmp.c b/waterbox/libc/functions/wchar/wcsncmp.c deleted file mode 100644 index d857d7c3af..0000000000 --- a/waterbox/libc/functions/wchar/wcsncmp.c +++ /dev/null @@ -1,52 +0,0 @@ -/* wcsncmp( const wchar_t *, const wchar_t *, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -int wcsncmp( const wchar_t * s1, const wchar_t * s2, size_t n ) -{ - while ( *s1 && n && ( *s1 == *s2 ) ) - { - ++s1; - ++s2; - --n; - } - if ( n == 0 ) - { - return 0; - } - else - { - return ( *(wchar_t *)s1 - *(wchar_t *)s2 ); - } -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - wchar_t cmpabcde[] = L"abcde\0f"; - wchar_t cmpabcd_[] = L"abcde\xfc"; - wchar_t empty[] = L""; - wchar_t x[] = L"x"; - TESTCASE( wcsncmp( wabcde, cmpabcde, 5 ) == 0 ); - TESTCASE( wcsncmp( wabcde, cmpabcde, 10 ) == 0 ); - TESTCASE( wcsncmp( wabcde, wabcdx, 5 ) < 0 ); - TESTCASE( wcsncmp( wabcdx, wabcde, 5 ) > 0 ); - TESTCASE( wcsncmp( empty, wabcde, 5 ) < 0 ); - TESTCASE( wcsncmp( wabcde, empty, 5 ) > 0 ); - TESTCASE( wcsncmp( wabcde, wabcdx, 4 ) == 0 ); - TESTCASE( wcsncmp( wabcde, x, 0 ) == 0 ); - TESTCASE( wcsncmp( wabcde, x, 1 ) < 0 ); - TESTCASE( wcsncmp( wabcde, cmpabcd_, 10 ) < 0 ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wchar/wcsncpy.c b/waterbox/libc/functions/wchar/wcsncpy.c deleted file mode 100644 index 2734fdd690..0000000000 --- a/waterbox/libc/functions/wchar/wcsncpy.c +++ /dev/null @@ -1,43 +0,0 @@ -/* wchar_t * wcsncpy( wchar_t *, const wchar_t * , size_t ); - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -wchar_t *wcsncpy( wchar_t * _PDCLIB_restrict s1, - const wchar_t * _PDCLIB_restrict s2, - size_t n ) -{ - wchar_t * rc = s1; - while ( ( n > 0 ) && ( *s1++ = *s2++ ) ) - { - /* Cannot do "n--" in the conditional as size_t is unsigned and we have - to check it again for >0 in the next loop below, so we must not risk - underflow. - */ - --n; - } - /* Checking against 1 as we missed the last --n in the loop above. */ - while ( n-- > 1 ) - { - *s1++ = '\0'; - } - return rc; -} - - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/wchar/wcspbrk.c b/waterbox/libc/functions/wchar/wcspbrk.c deleted file mode 100644 index 6503a85429..0000000000 --- a/waterbox/libc/functions/wchar/wcspbrk.c +++ /dev/null @@ -1,47 +0,0 @@ -/* wcspbrk( const wchar_t *, const wchar_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -wchar_t * wcspbrk( const wchar_t * s1, const wchar_t * s2 ) -{ - const wchar_t * p1 = s1; - const wchar_t * p2; - while ( *p1 ) - { - p2 = s2; - while ( *p2 ) - { - if ( *p1 == *p2++ ) - { - return (wchar_t *) p1; - } - } - ++p1; - } - return NULL; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( wcspbrk( wabcde, L"x" ) == NULL ); - TESTCASE( wcspbrk( wabcde, L"xyz" ) == NULL ); - TESTCASE( wcspbrk( wabcdx, L"x" ) == &wabcdx[4] ); - TESTCASE( wcspbrk( wabcdx, L"xyz" ) == &wabcdx[4] ); - TESTCASE( wcspbrk( wabcdx, L"zyx" ) == &wabcdx[4] ); - TESTCASE( wcspbrk( wabcde, L"a" ) == &wabcde[0] ); - TESTCASE( wcspbrk( wabcde, L"abc" ) == &wabcde[0] ); - TESTCASE( wcspbrk( wabcde, L"cba" ) == &wabcde[0] ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wchar/wcsrchr.c b/waterbox/libc/functions/wchar/wcsrchr.c deleted file mode 100644 index 5f2a66daa0..0000000000 --- a/waterbox/libc/functions/wchar/wcsrchr.c +++ /dev/null @@ -1,33 +0,0 @@ -/* wcsrchr( const wchar_t *, wchar_t ); - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#include - -#ifndef REGTEST - -wchar_t *wcsrchr(const wchar_t * haystack, wchar_t needle) -{ - wchar_t *found = NULL; - while(*haystack) { - if(*haystack == needle) found = (wchar_t*) haystack; - haystack++; - } - return found; -} - - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/wchar/wcsspn.c b/waterbox/libc/functions/wchar/wcsspn.c deleted file mode 100644 index dbdf522c71..0000000000 --- a/waterbox/libc/functions/wchar/wcsspn.c +++ /dev/null @@ -1,47 +0,0 @@ -/* wcsspn( const wchar_t *, const wchar_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -size_t wcsspn( const wchar_t * s1, const wchar_t * s2 ) -{ - size_t len = 0; - const wchar_t * p; - while ( s1[ len ] ) - { - p = s2; - while ( *p ) - { - if ( s1[len] == *p ) - { - break; - } - ++p; - } - if ( ! *p ) - { - return len; - } - ++len; - } - return len; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( wcsspn( wabcde, L"abc" ) == 3 ); - TESTCASE( wcsspn( wabcde, L"b" ) == 0 ); - TESTCASE( wcsspn( wabcde, wabcde ) == 5 ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wchar/wcsstr.c b/waterbox/libc/functions/wchar/wcsstr.c deleted file mode 100644 index 1427a8a573..0000000000 --- a/waterbox/libc/functions/wchar/wcsstr.c +++ /dev/null @@ -1,49 +0,0 @@ -/* wcsstr( const wchar_t *, const wchar_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -wchar_t * wcsstr( const wchar_t * s1, const wchar_t * s2 ) -{ - const wchar_t * p1 = s1; - const wchar_t * p2; - while ( *s1 ) - { - p2 = s2; - while ( *p2 && ( *p1 == *p2 ) ) - { - ++p1; - ++p2; - } - if ( ! *p2 ) - { - return (wchar_t *) s1; - } - ++s1; - p1 = s1; - } - return NULL; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - wchar_t s[] = L"abcabcabcdabcde"; - TESTCASE( wcsstr( s, L"x" ) == NULL ); - TESTCASE( wcsstr( s, L"xyz" ) == NULL ); - TESTCASE( wcsstr( s, L"a" ) == &s[0] ); - TESTCASE( wcsstr( s, L"abc" ) == &s[0] ); - TESTCASE( wcsstr( s, L"abcd" ) == &s[6] ); - TESTCASE( wcsstr( s, L"abcde" ) == &s[10] ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wchar/wcstok.c b/waterbox/libc/functions/wchar/wcstok.c deleted file mode 100644 index b8bcf14184..0000000000 --- a/waterbox/libc/functions/wchar/wcstok.c +++ /dev/null @@ -1,113 +0,0 @@ -/* wcstok( wchar_t *, const wchar_t * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -wchar_t * wcstok( wchar_t * _PDCLIB_restrict s1, - const wchar_t * _PDCLIB_restrict s2, - wchar_t ** _PDCLIB_restrict ptr ) -{ - const wchar_t * p = s2; - - if ( s1 != NULL ) - { - /* new string */ - *ptr = s1; - } - else - { - /* old string continued */ - if ( *ptr == NULL ) - { - /* No old string, no new string, nothing to do */ - return NULL; - } - s1 = *ptr; - } - - /* skipping leading s2 characters */ - while ( *p && *s1 ) - { - if ( *s1 == *p ) - { - /* found seperator; skip and start over */ - ++s1; - p = s2; - continue; - } - ++p; - } - - if ( ! *s1 ) - { - /* no more to parse */ - return ( *ptr = NULL ); - } - - /* skipping non-s2 characters */ - *ptr = s1; - while ( **ptr ) - { - p = s2; - while ( *p ) - { - if ( **ptr == *p++ ) - { - /* found seperator; overwrite with '\0', position *ptr, return */ - *(*ptr)++ = L'\0'; - return s1; - } - } - ++(*ptr); - } - - /* parsed to end of string */ - *ptr = NULL; - return s1; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - // MinGW at least has a very nonconforming (different signature!) variety - // of wcstok -#ifndef REGTEST - wchar_t s[] = L"_a_bc__d_"; - wchar_t* state = NULL; - wchar_t* tokres; - - TESTCASE( ( tokres = wcstok( s, L"_", &state ) ) == &s[1] ); - TESTCASE( s[1] == L'a' ); - TESTCASE( s[2] == L'\0' ); - TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == &s[3] ); - TESTCASE( s[3] == L'b' ); - TESTCASE( s[4] == L'c' ); - TESTCASE( s[5] == L'\0' ); - TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == &s[7] ); - TESTCASE( s[6] == L'_' ); - TESTCASE( s[7] == L'd' ); - TESTCASE( s[8] == L'\0' ); - TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == NULL ); - wcscpy( s, L"ab_cd" ); - TESTCASE( ( tokres = wcstok( s, L"_", &state ) ) == &s[0] ); - TESTCASE( s[0] == L'a' ); - TESTCASE( s[1] == L'b' ); - TESTCASE( s[2] == L'\0' ); - TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == &s[3] ); - TESTCASE( s[3] == L'c' ); - TESTCASE( s[4] == L'd' ); - TESTCASE( s[5] == L'\0' ); - TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == NULL ); -#endif - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wchar/wcsxfrm.c b/waterbox/libc/functions/wchar/wcsxfrm.c deleted file mode 100644 index 6d1bd37d76..0000000000 --- a/waterbox/libc/functions/wchar/wcsxfrm.c +++ /dev/null @@ -1,28 +0,0 @@ -/* wcsxfrm( char *, const char *, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -/* See notes on wcscoll. */ -size_t wcsxfrm( wchar_t * _PDCLIB_restrict s1, const wchar_t * _PDCLIB_restrict s2, size_t n ) -{ - wcsncpy(s1, s2, n); - return wcslen(s2); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - return TEST_RESULTS; -} -#endif - diff --git a/waterbox/libc/functions/wchar/wmemchr.c b/waterbox/libc/functions/wchar/wmemchr.c deleted file mode 100644 index 75b010d4c2..0000000000 --- a/waterbox/libc/functions/wchar/wmemchr.c +++ /dev/null @@ -1,39 +0,0 @@ -/* wmemchr( const void *, int, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -wchar_t * wmemchr( const wchar_t * p, wchar_t c, size_t n ) -{ - while ( n-- ) - { - if ( *p == c ) - { - return (wchar_t*) p; - } - ++p; - } - return NULL; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( wmemchr( wabcde, L'c', 5 ) == &wabcde[2] ); - TESTCASE( wmemchr( wabcde, L'a', 1 ) == &wabcde[0] ); - TESTCASE( wmemchr( wabcde, L'a', 0 ) == NULL ); - TESTCASE( wmemchr( wabcde, L'\0', 5 ) == NULL ); - TESTCASE( wmemchr( wabcde, L'\0', 6 ) == &wabcde[5] ); - return TEST_RESULTS; -} - -#endif diff --git a/waterbox/libc/functions/wchar/wmemcmp.c b/waterbox/libc/functions/wchar/wmemcmp.c deleted file mode 100644 index de5d49afd2..0000000000 --- a/waterbox/libc/functions/wchar/wmemcmp.c +++ /dev/null @@ -1,39 +0,0 @@ -/* wmemcmp( const wchar_t *, const wchar_t *, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -int wmemcmp( const wchar_t * p1, const wchar_t * p2, size_t n ) -{ - while ( n-- ) - { - if ( *p1 != *p2 ) - { - return *p1 - *p2; - } - ++p1; - ++p2; - } - return 0; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - wchar_t const xxxxx[] = L"xxxxx"; - TESTCASE( wmemcmp( wabcde, wabcdx, 5 ) < 0 ); - TESTCASE( wmemcmp( wabcde, wabcdx, 4 ) == 0 ); - TESTCASE( wmemcmp( wabcde, xxxxx, 0 ) == 0 ); - TESTCASE( wmemcmp( xxxxx, wabcde, 1 ) > 0 ); - return 0; -} -#endif diff --git a/waterbox/libc/functions/wchar/wmemcpy.c b/waterbox/libc/functions/wchar/wmemcpy.c deleted file mode 100644 index 2f3bdac335..0000000000 --- a/waterbox/libc/functions/wchar/wmemcpy.c +++ /dev/null @@ -1,39 +0,0 @@ -/* wmemcpy( wchar_t *, const wchar_t *, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -wchar_t * wmemcpy( wchar_t * _PDCLIB_restrict dest, - const wchar_t * _PDCLIB_restrict src, - size_t n ) -{ - wchar_t* rv = dest; - while ( n-- ) - { - *dest++ = *src++; - } - return rv; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - wchar_t s[] = L"xxxxxxxxxxx"; - TESTCASE( wmemcpy( s, wabcde, 6 ) == s ); - TESTCASE( s[4] == L'e' ); - TESTCASE( s[5] == L'\0' ); - TESTCASE( wmemcpy( s + 5, wabcde, 5 ) == s + 5 ); - TESTCASE( s[9] == L'e' ); - TESTCASE( s[10] == L'x' ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wchar/wmemmove.c b/waterbox/libc/functions/wchar/wmemmove.c deleted file mode 100644 index a5288f40cb..0000000000 --- a/waterbox/libc/functions/wchar/wmemmove.c +++ /dev/null @@ -1,49 +0,0 @@ -/* wmemmove( wchar_t *, const wchar_t *, size_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include - -#ifndef REGTEST - -wchar_t * wmemmove( wchar_t * dest, const wchar_t * src, size_t n ) -{ - wchar_t* rv = dest; - if ( dest <= src ) - { - while ( n-- ) - { - *dest++ = *src++; - } - } - else - { - src += n; - dest += n; - while ( n-- ) - { - *--dest = *--src; - } - } - return rv; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - wchar_t s[] = L"xxxxabcde"; - TESTCASE( wmemmove( s, s + 4, 5 ) == s ); - TESTCASE( s[0] == L'a' ); - TESTCASE( s[4] == L'e' ); - TESTCASE( s[5] == L'b' ); - TESTCASE( wmemmove( s + 4, s, 5 ) == s + 4 ); - TESTCASE( s[4] == L'a' ); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/iswalnum.c b/waterbox/libc/functions/wctype/iswalnum.c deleted file mode 100644 index df5dbb2ae9..0000000000 --- a/waterbox/libc/functions/wctype/iswalnum.c +++ /dev/null @@ -1,30 +0,0 @@ -/* iswalnum( wint_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int iswalnum( wint_t wc ) -{ - return iswctype( wc, _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_DIGIT ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE(iswalnum(L'a')); - TESTCASE(iswalnum(L'z')); - TESTCASE(iswalnum(L'E')); - TESTCASE(iswalnum(L'3')); - TESTCASE(!iswalnum(L';')); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/iswalpha.c b/waterbox/libc/functions/wctype/iswalpha.c deleted file mode 100644 index 9cf5cfaa06..0000000000 --- a/waterbox/libc/functions/wctype/iswalpha.c +++ /dev/null @@ -1,30 +0,0 @@ -/* iswalpha( wint_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int iswalpha( wint_t wc ) -{ - return iswctype( wc, _PDCLIB_CTYPE_ALPHA ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE(iswalpha(L'a')); - TESTCASE(iswalpha(L'z')); - TESTCASE(iswalpha(L'E')); - TESTCASE(!iswalpha(L'3')); - TESTCASE(!iswalpha(L';')); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/iswblank.c b/waterbox/libc/functions/wctype/iswblank.c deleted file mode 100644 index a73b9f63ce..0000000000 --- a/waterbox/libc/functions/wctype/iswblank.c +++ /dev/null @@ -1,29 +0,0 @@ -/* iswblank( wint_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int iswblank( wint_t wc ) -{ - return iswctype( wc, _PDCLIB_CTYPE_BLANK ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE(iswblank(L' ')); - TESTCASE(iswblank(L'\t')); - TESTCASE(!iswblank(L'\n')); - TESTCASE(!iswblank(L'a')); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/iswcntrl.c b/waterbox/libc/functions/wctype/iswcntrl.c deleted file mode 100644 index 1c81c54437..0000000000 --- a/waterbox/libc/functions/wctype/iswcntrl.c +++ /dev/null @@ -1,30 +0,0 @@ -/* iswcntrl( wint_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int iswcntrl( wint_t wc ) -{ - return iswctype( wc, _PDCLIB_CTYPE_CNTRL ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE(iswcntrl(L'\0')); - TESTCASE(iswcntrl(L'\n')); - TESTCASE(iswcntrl(L'\v')); - TESTCASE(!iswcntrl(L'\t')); - TESTCASE(!iswcntrl(L'a')); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/iswctype.c b/waterbox/libc/functions/wctype/iswctype.c deleted file mode 100644 index cac41150ac..0000000000 --- a/waterbox/libc/functions/wctype/iswctype.c +++ /dev/null @@ -1,135 +0,0 @@ -/* iswctype( wint_t, wctype_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int _PDCLIB_iswctype_l( wint_t wc, wctype_t desc, locale_t l ) -{ - wc = _PDCLIB_unpackwint( wc ); - - _PDCLIB_wcinfo_t *info = _PDCLIB_wcgetinfo( l, wc ); - - if(!info) return 0; - - return info->flags & desc; -} - -int iswctype( wint_t wc, wctype_t desc ) -{ - return _PDCLIB_iswctype_l( wc, desc, _PDCLIB_threadlocale() ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE( iswctype(L'a', wctype("alpha"))); - TESTCASE( iswctype(L'z', wctype("alpha"))); - TESTCASE( iswctype(L'E', wctype("alpha"))); - TESTCASE(!iswctype(L'3', wctype("alpha"))); - TESTCASE(!iswctype(L';', wctype("alpha"))); - - TESTCASE( iswctype(L'a', wctype("alnum"))); - TESTCASE( iswctype(L'3', wctype("alnum"))); - TESTCASE(!iswctype(L';', wctype("alnum"))); - - TESTCASE( iswctype(L' ', wctype("blank"))); - TESTCASE( iswctype(L'\t', wctype("blank"))); - TESTCASE(!iswctype(L'\n', wctype("blank"))); - TESTCASE(!iswctype(L';', wctype("blank"))); - - TESTCASE( iswctype(L'\0', wctype("cntrl"))); - TESTCASE( iswctype(L'\n', wctype("cntrl"))); - TESTCASE( iswctype(L'\v', wctype("cntrl"))); - TESTCASE(!iswctype(L'\t', wctype("cntrl"))); - TESTCASE(!iswctype(L'a', wctype("cntrl"))); - - TESTCASE( iswctype(L'0', wctype("digit"))); - TESTCASE( iswctype(L'1', wctype("digit"))); - TESTCASE( iswctype(L'2', wctype("digit"))); - TESTCASE( iswctype(L'3', wctype("digit"))); - TESTCASE( iswctype(L'4', wctype("digit"))); - TESTCASE( iswctype(L'5', wctype("digit"))); - TESTCASE( iswctype(L'6', wctype("digit"))); - TESTCASE( iswctype(L'7', wctype("digit"))); - TESTCASE( iswctype(L'8', wctype("digit"))); - TESTCASE( iswctype(L'9', wctype("digit"))); - TESTCASE(!iswctype(L'X', wctype("digit"))); - TESTCASE(!iswctype(L'?', wctype("digit"))); - - TESTCASE( iswctype(L'a', wctype("graph"))); - TESTCASE( iswctype(L'z', wctype("graph"))); - TESTCASE( iswctype(L'E', wctype("graph"))); - TESTCASE( iswctype(L'E', wctype("graph"))); - TESTCASE(!iswctype(L' ', wctype("graph"))); - TESTCASE(!iswctype(L'\t', wctype("graph"))); - TESTCASE(!iswctype(L'\n', wctype("graph"))); - - TESTCASE( iswctype(L'a', wctype("lower"))); - TESTCASE( iswctype(L'e', wctype("lower"))); - TESTCASE( iswctype(L'z', wctype("lower"))); - TESTCASE(!iswctype(L'A', wctype("lower"))); - TESTCASE(!iswctype(L'E', wctype("lower"))); - TESTCASE(!iswctype(L'Z', wctype("lower"))); - - TESTCASE(!iswctype(L'a', wctype("upper"))); - TESTCASE(!iswctype(L'e', wctype("upper"))); - TESTCASE(!iswctype(L'z', wctype("upper"))); - TESTCASE( iswctype(L'A', wctype("upper"))); - TESTCASE( iswctype(L'E', wctype("upper"))); - TESTCASE( iswctype(L'Z', wctype("upper"))); - - TESTCASE( iswctype(L'Z', wctype("print"))); - TESTCASE( iswctype(L'a', wctype("print"))); - TESTCASE( iswctype(L';', wctype("print"))); - TESTCASE( iswctype(L'\t', wctype("print"))); - TESTCASE(!iswctype(L'\0', wctype("print"))); - - TESTCASE( iswctype(L';', wctype("punct"))); - TESTCASE( iswctype(L'.', wctype("punct"))); - TESTCASE( iswctype(L'?', wctype("punct"))); - TESTCASE(!iswctype(L' ', wctype("punct"))); - TESTCASE(!iswctype(L'Z', wctype("punct"))); - - TESTCASE( iswctype(L' ', wctype("space"))); - TESTCASE( iswctype(L'\t', wctype("space"))); - - TESTCASE( iswctype(L'0', wctype("xdigit"))); - TESTCASE( iswctype(L'1', wctype("xdigit"))); - TESTCASE( iswctype(L'2', wctype("xdigit"))); - TESTCASE( iswctype(L'3', wctype("xdigit"))); - TESTCASE( iswctype(L'4', wctype("xdigit"))); - TESTCASE( iswctype(L'5', wctype("xdigit"))); - TESTCASE( iswctype(L'6', wctype("xdigit"))); - TESTCASE( iswctype(L'7', wctype("xdigit"))); - TESTCASE( iswctype(L'8', wctype("xdigit"))); - TESTCASE( iswctype(L'9', wctype("xdigit"))); - TESTCASE( iswctype(L'a', wctype("xdigit"))); - TESTCASE( iswctype(L'b', wctype("xdigit"))); - TESTCASE( iswctype(L'c', wctype("xdigit"))); - TESTCASE( iswctype(L'd', wctype("xdigit"))); - TESTCASE( iswctype(L'e', wctype("xdigit"))); - TESTCASE( iswctype(L'f', wctype("xdigit"))); - TESTCASE( iswctype(L'A', wctype("xdigit"))); - TESTCASE( iswctype(L'B', wctype("xdigit"))); - TESTCASE( iswctype(L'C', wctype("xdigit"))); - TESTCASE( iswctype(L'D', wctype("xdigit"))); - TESTCASE( iswctype(L'E', wctype("xdigit"))); - TESTCASE( iswctype(L'F', wctype("xdigit"))); - TESTCASE(!iswctype(L'g', wctype("xdigit"))); - TESTCASE(!iswctype(L'G', wctype("xdigit"))); - TESTCASE(!iswctype(L'x', wctype("xdigit"))); - TESTCASE(!iswctype(L'X', wctype("xdigit"))); - TESTCASE(!iswctype(L' ', wctype("xdigit"))); - - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/iswdigit.c b/waterbox/libc/functions/wctype/iswdigit.c deleted file mode 100644 index 31300cc214..0000000000 --- a/waterbox/libc/functions/wctype/iswdigit.c +++ /dev/null @@ -1,52 +0,0 @@ -/* iswdigit( wint_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int iswdigit( wint_t wc ) -{ - return iswctype( wc, _PDCLIB_CTYPE_DIGIT ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE(iswdigit(L'0')); - TESTCASE(iswdigit(L'1')); - TESTCASE(iswdigit(L'2')); - TESTCASE(iswdigit(L'3')); - TESTCASE(iswdigit(L'4')); - TESTCASE(iswdigit(L'5')); - TESTCASE(iswdigit(L'6')); - TESTCASE(iswdigit(L'7')); - TESTCASE(iswdigit(L'8')); - TESTCASE(iswdigit(L'9')); - TESTCASE(!iswdigit(L'a')); - TESTCASE(!iswdigit(L'b')); - TESTCASE(!iswdigit(L'c')); - TESTCASE(!iswdigit(L'd')); - TESTCASE(!iswdigit(L'e')); - TESTCASE(!iswdigit(L'f')); - TESTCASE(!iswdigit(L'A')); - TESTCASE(!iswdigit(L'B')); - TESTCASE(!iswdigit(L'C')); - TESTCASE(!iswdigit(L'D')); - TESTCASE(!iswdigit(L'E')); - TESTCASE(!iswdigit(L'F')); - TESTCASE(!iswdigit(L'g')); - TESTCASE(!iswdigit(L'G')); - TESTCASE(!iswdigit(L'x')); - TESTCASE(!iswdigit(L'X')); - TESTCASE(!iswdigit(L' ')); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/iswgraph.c b/waterbox/libc/functions/wctype/iswgraph.c deleted file mode 100644 index 954844a2a5..0000000000 --- a/waterbox/libc/functions/wctype/iswgraph.c +++ /dev/null @@ -1,31 +0,0 @@ -/* iswgraph( wint_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int iswgraph( wint_t wc ) -{ - return iswctype( wc, _PDCLIB_CTYPE_GRAPH ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE(iswgraph(L'a')); - TESTCASE(iswgraph(L'z')); - TESTCASE(iswgraph(L'E')); - TESTCASE(!iswgraph(L' ')); - TESTCASE(!iswgraph(L'\t')); - TESTCASE(!iswgraph(L'\n')); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/iswlower.c b/waterbox/libc/functions/wctype/iswlower.c deleted file mode 100644 index 628ae64010..0000000000 --- a/waterbox/libc/functions/wctype/iswlower.c +++ /dev/null @@ -1,31 +0,0 @@ -/* iswalnum( wint_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int iswlower( wint_t wc ) -{ - return iswctype( wc, _PDCLIB_CTYPE_LOWER ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE(iswlower(L'a')); - TESTCASE(iswlower(L'e')); - TESTCASE(iswlower(L'z')); - TESTCASE(!iswlower(L'A')); - TESTCASE(!iswlower(L'E')); - TESTCASE(!iswlower(L'Z')); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/iswprint.c b/waterbox/libc/functions/wctype/iswprint.c deleted file mode 100644 index 395eb635af..0000000000 --- a/waterbox/libc/functions/wctype/iswprint.c +++ /dev/null @@ -1,26 +0,0 @@ -/* iswprint( wint_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int iswprint( wint_t wc ) -{ - return iswctype( wc, _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_SPACE ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/iswpunct.c b/waterbox/libc/functions/wctype/iswpunct.c deleted file mode 100644 index c59672c44b..0000000000 --- a/waterbox/libc/functions/wctype/iswpunct.c +++ /dev/null @@ -1,31 +0,0 @@ -/* iswpunct( wint_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int iswpunct( wint_t wc ) -{ - return iswctype( wc, _PDCLIB_CTYPE_PUNCT ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE(iswpunct(L';')); - TESTCASE(iswpunct(L'?')); - TESTCASE(iswpunct(L'.')); - TESTCASE(!iswpunct(L' ')); - TESTCASE(!iswpunct(L'Z')); - - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/iswspace.c b/waterbox/libc/functions/wctype/iswspace.c deleted file mode 100644 index 501a30139f..0000000000 --- a/waterbox/libc/functions/wctype/iswspace.c +++ /dev/null @@ -1,28 +0,0 @@ -/* iswspace( wint_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int iswspace( wint_t wc ) -{ - return iswctype( wc, _PDCLIB_CTYPE_SPACE ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE(iswspace(L' ')); - TESTCASE(iswspace(L'\t')); - TESTCASE(!iswspace(L'a')); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/iswupper.c b/waterbox/libc/functions/wctype/iswupper.c deleted file mode 100644 index 4806a281b5..0000000000 --- a/waterbox/libc/functions/wctype/iswupper.c +++ /dev/null @@ -1,31 +0,0 @@ -/* iswupper( wint_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int iswupper( wint_t wc ) -{ - return iswctype( wc, _PDCLIB_CTYPE_UPPER ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE(!iswupper(L'a')); - TESTCASE(!iswupper(L'e')); - TESTCASE(!iswupper(L'z')); - TESTCASE(iswupper(L'A')); - TESTCASE(iswupper(L'E')); - TESTCASE(iswupper(L'Z')); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/iswxdigit.c b/waterbox/libc/functions/wctype/iswxdigit.c deleted file mode 100644 index 3f51ae81bf..0000000000 --- a/waterbox/libc/functions/wctype/iswxdigit.c +++ /dev/null @@ -1,52 +0,0 @@ -/* iswxdigit( wint_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -int iswxdigit( wint_t wc ) -{ - return iswctype( wc, _PDCLIB_CTYPE_XDIGT ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE(iswxdigit(L'0')); - TESTCASE(iswxdigit(L'1')); - TESTCASE(iswxdigit(L'2')); - TESTCASE(iswxdigit(L'3')); - TESTCASE(iswxdigit(L'4')); - TESTCASE(iswxdigit(L'5')); - TESTCASE(iswxdigit(L'6')); - TESTCASE(iswxdigit(L'7')); - TESTCASE(iswxdigit(L'8')); - TESTCASE(iswxdigit(L'9')); - TESTCASE(iswxdigit(L'a')); - TESTCASE(iswxdigit(L'b')); - TESTCASE(iswxdigit(L'c')); - TESTCASE(iswxdigit(L'd')); - TESTCASE(iswxdigit(L'e')); - TESTCASE(iswxdigit(L'f')); - TESTCASE(iswxdigit(L'A')); - TESTCASE(iswxdigit(L'B')); - TESTCASE(iswxdigit(L'C')); - TESTCASE(iswxdigit(L'D')); - TESTCASE(iswxdigit(L'E')); - TESTCASE(iswxdigit(L'F')); - TESTCASE(!iswxdigit(L'g')); - TESTCASE(!iswxdigit(L'G')); - TESTCASE(!iswxdigit(L'x')); - TESTCASE(!iswxdigit(L'X')); - TESTCASE(!iswxdigit(L' ')); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/towctrans.c b/waterbox/libc/functions/wctype/towctrans.c deleted file mode 100644 index 1ecb2ff2b7..0000000000 --- a/waterbox/libc/functions/wctype/towctrans.c +++ /dev/null @@ -1,42 +0,0 @@ -/* towctrans( wint_t, wctrans_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include -#include "_PDCLIB_locale.h" - -wint_t _PDCLIB_towctrans_l( wint_t wc, wctrans_t trans, locale_t l ) -{ - switch( trans ) { - case 0: return wc; - case _PDCLIB_WCTRANS_TOLOWER: return _PDCLIB_towlower_l( wc, l ); - case _PDCLIB_WCTRANS_TOUPPER: return _PDCLIB_towupper_l( wc, l ); - default: abort(); - } -} - -wint_t towctrans( wint_t wc, wctrans_t trans ) -{ - return _PDCLIB_towctrans_l( wc, trans, _PDCLIB_threadlocale() ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE(towctrans(L'a', wctrans("toupper")) == L'A'); - TESTCASE(towctrans(L'B', wctrans("toupper")) == L'B'); - TESTCASE(towctrans(L'a', wctrans("tolower")) == L'a'); - TESTCASE(towctrans(L'B', wctrans("tolower")) == L'b'); - TESTCASE(towctrans(L'B', wctrans("invalid")) == L'B'); - TESTCASE(towctrans(L'B', 0) == L'B'); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/towlower.c b/waterbox/libc/functions/wctype/towlower.c deleted file mode 100644 index b81e7579ca..0000000000 --- a/waterbox/libc/functions/wctype/towlower.c +++ /dev/null @@ -1,41 +0,0 @@ -/* towlower( wint_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -wint_t _PDCLIB_towlower_l( wint_t wc, locale_t l ) -{ - wint_t uwc = _PDCLIB_unpackwint( wc ); - _PDCLIB_wcinfo_t *info = _PDCLIB_wcgetinfo( l, uwc ); - if( info ) - { - uwc += info->lower_delta; - } - return uwc; -} - -wint_t towlower( wint_t wc ) -{ - return _PDCLIB_towlower_l( wc, _PDCLIB_threadlocale() ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE(towlower(0) == 0); - TESTCASE(towlower(L'a') == L'a'); - TESTCASE(towlower(L'B') == L'b'); - TESTCASE(towlower(L'0') == L'0'); - - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/towupper.c b/waterbox/libc/functions/wctype/towupper.c deleted file mode 100644 index 368ca2cdb5..0000000000 --- a/waterbox/libc/functions/wctype/towupper.c +++ /dev/null @@ -1,41 +0,0 @@ -/* towupper( wint_t ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include "_PDCLIB_locale.h" - -wint_t _PDCLIB_towupper_l( wint_t wc, locale_t l ) -{ - wint_t uwc = _PDCLIB_unpackwint( wc ); - _PDCLIB_wcinfo_t *info = _PDCLIB_wcgetinfo( l, uwc ); - if( info ) - { - uwc += info->upper_delta; - } - return uwc; -} - -wint_t towupper( wint_t wc ) -{ - return _PDCLIB_towupper_l( wc, _PDCLIB_threadlocale() ); -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE(towupper(0) == 0); - TESTCASE(towupper(L'a') == L'A'); - TESTCASE(towupper(L'B') == L'B'); - TESTCASE(towupper(L'0') == L'0'); - - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/wctrans.c b/waterbox/libc/functions/wctype/wctrans.c deleted file mode 100644 index c15bde085c..0000000000 --- a/waterbox/libc/functions/wctype/wctrans.c +++ /dev/null @@ -1,38 +0,0 @@ -/* wctrans( const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include -#include "_PDCLIB_locale.h" - -wctrans_t wctrans( const char * property ) -{ - if(!property) { - return 0; - } else if(strcmp(property, "tolower") == 0) { - return _PDCLIB_WCTRANS_TOLOWER; - } else if(strcmp(property, "toupper") == 0) { - return _PDCLIB_WCTRANS_TOUPPER; - } else { - return 0; - } -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE(wctrans("") == 0); - TESTCASE(wctrans("invalid") == 0); - TESTCASE(wctrans("toupper") != 0); - TESTCASE(wctrans("tolower") != 0); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/functions/wctype/wctype.c b/waterbox/libc/functions/wctype/wctype.c deleted file mode 100644 index 3e8aa1f123..0000000000 --- a/waterbox/libc/functions/wctype/wctype.c +++ /dev/null @@ -1,110 +0,0 @@ -/* wctype( const char * ) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include -#ifndef REGTEST -#include -#include "_PDCLIB_locale.h" - -wctype_t wctype( const char * property ) -{ - if(property) switch(property[0]) - { - case 'a': - if(strcmp(property, "alpha") == 0) { - return _PDCLIB_CTYPE_ALPHA; - } else if(strcmp(property, "alnum") == 0) { - return _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_DIGIT; - } else return 0; - - case 'b': - if(strcmp(property, "blank") == 0) { - return _PDCLIB_CTYPE_BLANK; - } else return 0; - - case 'c': - if(strcmp(property, "cntrl") == 0) { - return _PDCLIB_CTYPE_CNTRL; - } else return 0; - - case 'd': - if(strcmp(property, "digit") == 0) { - return _PDCLIB_CTYPE_DIGIT; - } else return 0; - - case 'g': - if(strcmp(property, "graph") == 0) { - return _PDCLIB_CTYPE_GRAPH; - } else return 0; - - case 'l': - if(strcmp(property, "lower") == 0) { - return _PDCLIB_CTYPE_LOWER; - } else return 0; - - case 'p': - if(strcmp(property, "print") == 0) { - return _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_SPACE; - } else if(strcmp(property, "punct") == 0) { - return _PDCLIB_CTYPE_PUNCT; - } else return 0; - - case 's': - if(strcmp(property, "space") == 0) { - return _PDCLIB_CTYPE_SPACE; - } else return 0; - - case 'u': - if(strcmp(property, "upper") == 0) { - return _PDCLIB_CTYPE_UPPER; - } else return 0; - - case 'x': - if(strcmp(property, "xdigit") == 0) { - return _PDCLIB_CTYPE_XDIGT; - } else return 0; - } - return 0; -} - -#endif - -#ifdef TEST -#include "_PDCLIB_test.h" - -int main( void ) -{ - TESTCASE(wctype("") == 0); - TESTCASE_NOREG(wctype(NULL) == 0); // mingw libc crashes on this - - TESTCASE(wctype("alpha") != 0); - TESTCASE(wctype("alnum") != 0); - TESTCASE(wctype("blank") != 0); - TESTCASE(wctype("cntrl") != 0); - TESTCASE(wctype("digit") != 0); - TESTCASE(wctype("graph") != 0); - TESTCASE(wctype("lower") != 0); - TESTCASE(wctype("print") != 0); - TESTCASE(wctype("punct") != 0); - TESTCASE(wctype("space") != 0); - TESTCASE(wctype("upper") != 0); - TESTCASE(wctype("xdigit") != 0); - - TESTCASE_NOREG(wctype("alpha") == _PDCLIB_CTYPE_ALPHA); - TESTCASE_NOREG(wctype("alnum") == (_PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_DIGIT)); - TESTCASE_NOREG(wctype("blank") == _PDCLIB_CTYPE_BLANK); - TESTCASE_NOREG(wctype("cntrl") == _PDCLIB_CTYPE_CNTRL); - TESTCASE_NOREG(wctype("digit") == _PDCLIB_CTYPE_DIGIT); - TESTCASE_NOREG(wctype("graph") == _PDCLIB_CTYPE_GRAPH); - TESTCASE_NOREG(wctype("lower") == _PDCLIB_CTYPE_LOWER); - TESTCASE_NOREG(wctype("print") == (_PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_SPACE)); - TESTCASE_NOREG(wctype("punct") == _PDCLIB_CTYPE_PUNCT); - TESTCASE_NOREG(wctype("space") == _PDCLIB_CTYPE_SPACE); - TESTCASE_NOREG(wctype("upper") == _PDCLIB_CTYPE_UPPER); - TESTCASE_NOREG(wctype("xdigit") == _PDCLIB_CTYPE_XDIGT); - return TEST_RESULTS; -} -#endif diff --git a/waterbox/libc/includes/assert.h b/waterbox/libc/includes/assert.h deleted file mode 100644 index a1af59f6aa..0000000000 --- a/waterbox/libc/includes/assert.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Diagnostics - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#include "_PDCLIB_aux.h" -#include "_PDCLIB_config.h" - -/* - Defines a macro assert() that, depending on the value of the preprocessor - symbol NDEBUG, does - * evaluate to a void expression if NDEBUG is set OR the parameter expression - evaluates to true; - * print an error message and terminates the program if NDEBUG is not set AND - the parameter expression evaluates to false. - The error message contains the parameter expression, name of the source file - (__FILE__), line number (__LINE__), and (from C99 onward) name of the function - (__func__). - The header can be included MULTIPLE times, and redefines the macro depending - on the current setting of NDEBUG. -*/ - -#ifndef _PDCLIB_ASSERT_H -#define _PDCLIB_ASSERT_H _PDCLIB_ASSERT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Functions _NOT_ tagged noreturn as this hampers debugging */ -void _PDCLIB_assert99( char const * const, char const * const, char const * const ); -void _PDCLIB_assert89( char const * const ); - -#ifdef __cplusplus -} -#endif - -#if _PDCLIB_C_VERSION >= 2011 -#define static_assert _Static_assert -#else -#define static_assert( e, m ) -#endif - -#endif - -/* If NDEBUG is set, assert() is a null operation. */ -#undef assert - -#ifdef NDEBUG -#define assert( ignore ) ( (void) 0 ) -#elif _PDCLIB_C_MIN(99) -#define assert(expression) \ - do { if(!(expression)) { \ - _PDCLIB_assert99("Assertion failed: " _PDCLIB_symbol2string(expression)\ - ", function ", __func__, \ - ", file " __FILE__ \ - ", line " _PDCLIB_symbol2string( __LINE__ ) \ - "." _PDCLIB_endl ); \ - _PDCLIB_UNREACHABLE; \ - } \ - } while(0) - -#else -#define assert(expression) \ - do { if(!(expression)) { \ - _PDCLIB_assert89("Assertion failed: " _PDCLIB_symbol2string(expression)\ - ", file " __FILE__ \ - ", line " _PDCLIB_symbol2string( __LINE__ ) \ - "." _PDCLIB_endl ); \ - _PDCLIB_UNREACHABLE; \ - } \ - } while(0) -#endif diff --git a/waterbox/libc/includes/bits/alltypes.h b/waterbox/libc/includes/bits/alltypes.h deleted file mode 100644 index b918fdefd9..0000000000 --- a/waterbox/libc/includes/bits/alltypes.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef _ALLTYPES_H -#define _ALLTYPES_H -typedef double double_t; -typedef float float_t; -#endif diff --git a/waterbox/libc/includes/bits/endian.h b/waterbox/libc/includes/bits/endian.h deleted file mode 100644 index 172c338f50..0000000000 --- a/waterbox/libc/includes/bits/endian.h +++ /dev/null @@ -1 +0,0 @@ -#define __BYTE_ORDER __LITTLE_ENDIAN diff --git a/waterbox/libc/includes/bits/fenv.h b/waterbox/libc/includes/bits/fenv.h deleted file mode 100644 index 24df0417f2..0000000000 --- a/waterbox/libc/includes/bits/fenv.h +++ /dev/null @@ -1,34 +0,0 @@ -#define FE_INVALID 1 -#define __FE_DENORM 2 -#define FE_DIVBYZERO 4 -#define FE_OVERFLOW 8 -#define FE_UNDERFLOW 16 -#define FE_INEXACT 32 - -#define FE_ALL_EXCEPT 63 - -#define FE_TONEAREST 0 -#define FE_DOWNWARD 0x400 -#define FE_UPWARD 0x800 -#define FE_TOWARDZERO 0xc00 - -typedef unsigned short fexcept_t; - -typedef struct { - unsigned short __control_word; - unsigned short __unused1; - unsigned short __status_word; - unsigned short __unused2; - unsigned short __tags; - unsigned short __unused3; - unsigned int __eip; - unsigned short __cs_selector; - unsigned int __opcode:11; - unsigned int __unused4:5; - unsigned int __data_offset; - unsigned short __data_selector; - unsigned short __unused5; - unsigned int __mxcsr; -} fenv_t; - -#define FE_DFL_ENV ((const fenv_t *) -1) diff --git a/waterbox/libc/includes/complex.h b/waterbox/libc/includes/complex.h deleted file mode 100644 index 008b3c7e3b..0000000000 --- a/waterbox/libc/includes/complex.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef _COMPLEX_H -#define _COMPLEX_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define complex _Complex -#ifdef __GNUC__ -#define _Complex_I (__extension__ (0.0f+1.0fi)) -#else -#define _Complex_I (0.0f+1.0fi) -#endif -#define I _Complex_I - -double complex cacos(double complex); -float complex cacosf(float complex); -long double complex cacosl(long double complex); - -double complex casin(double complex); -float complex casinf(float complex); -long double complex casinl(long double complex); - -double complex catan(double complex); -float complex catanf(float complex); -long double complex catanl(long double complex); - -double complex ccos(double complex); -float complex ccosf(float complex); -long double complex ccosl(long double complex); - -double complex csin(double complex); -float complex csinf(float complex); -long double complex csinl(long double complex); - -double complex ctan(double complex); -float complex ctanf(float complex); -long double complex ctanl(long double complex); - -double complex cacosh(double complex); -float complex cacoshf(float complex); -long double complex cacoshl(long double complex); - -double complex casinh(double complex); -float complex casinhf(float complex); -long double complex casinhl(long double complex); - -double complex catanh(double complex); -float complex catanhf(float complex); -long double complex catanhl(long double complex); - -double complex ccosh(double complex); -float complex ccoshf(float complex); -long double complex ccoshl(long double complex); - -double complex csinh(double complex); -float complex csinhf(float complex); -long double complex csinhl(long double complex); - -double complex ctanh(double complex); -float complex ctanhf(float complex); -long double complex ctanhl(long double complex); - -double complex cexp(double complex); -float complex cexpf(float complex); -long double complex cexpl(long double complex); - -double complex clog(double complex); -float complex clogf(float complex); -long double complex clogl(long double complex); - -double cabs(double complex); -float cabsf(float complex); -long double cabsl(long double complex); - -double complex cpow(double complex, double complex); -float complex cpowf(float complex, float complex); -long double complex cpowl(long double complex, long double complex); - -double complex csqrt(double complex); -float complex csqrtf(float complex); -long double complex csqrtl(long double complex); - -double carg(double complex); -float cargf(float complex); -long double cargl(long double complex); - -double cimag(double complex); -float cimagf(float complex); -long double cimagl(long double complex); - -double complex conj(double complex); -float complex conjf(float complex); -long double complex conjl(long double complex); - -double complex cproj(double complex); -float complex cprojf(float complex); -long double complex cprojl(long double complex); - -double creal(double complex); -float crealf(float complex); -long double creall(long double complex); - -#ifndef __cplusplus -#define __CIMAG(x, t) \ - (+(union { _Complex t __z; t __xy[2]; }){(_Complex t)(x)}.__xy[1]) - -#define creal(x) ((double)(x)) -#define crealf(x) ((float)(x)) -#define creall(x) ((long double)(x)) - -#define cimag(x) __CIMAG(x, double) -#define cimagf(x) __CIMAG(x, float) -#define cimagl(x) __CIMAG(x, long double) -#endif - -#if __STDC_VERSION__ >= 201112L -#if defined(_Imaginary_I) -#define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I*(t)(y)) -#elif defined(__clang__) -#define __CMPLX(x, y, t) (+(_Complex t){ (t)(x), (t)(y) }) -#else -#define __CMPLX(x, y, t) (__builtin_complex((t)(x), (t)(y))) -#endif -#define CMPLX(x, y) __CMPLX(x, y, double) -#define CMPLXF(x, y) __CMPLX(x, y, float) -#define CMPLXL(x, y) __CMPLX(x, y, long double) -#endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/waterbox/libc/includes/ctype.h b/waterbox/libc/includes/ctype.h deleted file mode 100644 index 57fb451fa4..0000000000 --- a/waterbox/libc/includes/ctype.h +++ /dev/null @@ -1,103 +0,0 @@ -/* Character handling - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_CTYPE_H -#define _PDCLIB_CTYPE_H _PDCLIB_CTYPE_H -#include "_PDCLIB_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Character classification functions */ - -/* Note that there is a difference between "whitespace" (any printing, non- - graph character, like horizontal and vertical tab), and "blank" (the literal - ' ' space character). - - There will be masking macros for each of these later on, but right now I - focus on the functions only. -*/ - -/* Returns isalpha( c ) || isdigit( c ) */ -int isalnum( int c ) _PDCLIB_nothrow; - -/* Returns isupper( c ) || islower( c ) in the "C" locale. - In any other locale, also returns true for a locale-specific set of - alphabetic characters which are neither control characters, digits, - punctation, or whitespace. -*/ -int isalpha( int c ) _PDCLIB_nothrow; - -/* Returns true if the character isspace() and used for seperating words within - a line of text. In the "C" locale, only ' ' and '\t' are considered blanks. -*/ -int isblank( int c ) _PDCLIB_nothrow; - -/* Returns true if the character is a control character. */ -int iscntrl( int c ) _PDCLIB_nothrow; - -/* Returns true if the character is a decimal digit. Locale-independent. */ -int isdigit( int c ) _PDCLIB_nothrow; - -/* Returns true for every printing character except space (' '). */ -int isgraph( int c ) _PDCLIB_nothrow; - -/* Returns true for lowercase letters in the "C" locale. - In any other locale, also returns true for a locale-specific set of - characters which are neither control characters, digits, punctation, or - space (' '). In a locale other than the "C" locale, a character might test - true for both islower() and isupper(). -*/ -int islower( int c ) _PDCLIB_nothrow; - -/* Returns true for every printing character including space (' '). */ -int isprint( int c ) _PDCLIB_nothrow; - -/* Returns true for every printing character that is neither whitespace - nor alphanumeric in the "C" locale. In any other locale, there might be - characters that are printing characters, but neither whitespace nor - alphanumeric. -*/ -int ispunct( int c ) _PDCLIB_nothrow; - -/* Returns true for every standard whitespace character (' ', '\f', '\n', '\r', - '\t', '\v') in the "C" locale. In any other locale, also returns true for a - locale-specific set of characters for which isalnum() is false. -*/ -int isspace( int c ) _PDCLIB_nothrow; - -/* Returns true for uppercase letters in the "C" locale. - In any other locale, also returns true for a locale-specific set of - characters which are neither control characters, digits, punctation, or - space (' '). In a locale other than the "C" locale, a character might test - true for both islower() and isupper(). -*/ -int isupper( int c ) _PDCLIB_nothrow; - -/* Returns true for any hexadecimal-digit character. Locale-independent. */ -int isxdigit( int c ) _PDCLIB_nothrow; - -/* Character case mapping functions */ - -/* Converts an uppercase letter to a corresponding lowercase letter. Input that - is not an uppercase letter remains unchanged. -*/ -int tolower( int c ) _PDCLIB_nothrow; - -/* Converts a lowercase letter to a corresponding uppercase letter. Input that - is not a lowercase letter remains unchanged. -*/ -int toupper( int c ) _PDCLIB_nothrow; - -/* returns true for c in [0, 127] */ -int isascii(int c) _PDCLIB_nothrow; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/waterbox/libc/includes/endian.h b/waterbox/libc/includes/endian.h deleted file mode 100644 index 1bd444518a..0000000000 --- a/waterbox/libc/includes/endian.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef _ENDIAN_H -#define _ENDIAN_H - -#include - -#define __LITTLE_ENDIAN 1234 -#define __BIG_ENDIAN 4321 -#define __PDP_ENDIAN 3412 - -#if defined(__GNUC__) && defined(__BYTE_ORDER__) -#define __BYTE_ORDER __BYTE_ORDER__ -#else -#include -#endif - -#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) - -#define BIG_ENDIAN __BIG_ENDIAN -#define LITTLE_ENDIAN __LITTLE_ENDIAN -#define PDP_ENDIAN __PDP_ENDIAN -#define BYTE_ORDER __BYTE_ORDER - -#include - -static __inline uint16_t __bswap16(uint16_t __x) -{ - return __x<<8 | __x>>8; -} - -static __inline uint32_t __bswap32(uint32_t __x) -{ - return __x>>24 | __x>>8&0xff00 | __x<<8&0xff0000 | __x<<24; -} - -static __inline uint64_t __bswap64(uint64_t __x) -{ - return __bswap32(__x)+0ULL<<32 | __bswap32(__x>>32); -} - -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define htobe16(x) __bswap16(x) -#define be16toh(x) __bswap16(x) -#define betoh16(x) __bswap16(x) -#define htobe32(x) __bswap32(x) -#define be32toh(x) __bswap32(x) -#define betoh32(x) __bswap32(x) -#define htobe64(x) __bswap64(x) -#define be64toh(x) __bswap64(x) -#define betoh64(x) __bswap64(x) -#define htole16(x) (uint16_t)(x) -#define le16toh(x) (uint16_t)(x) -#define letoh16(x) (uint16_t)(x) -#define htole32(x) (uint32_t)(x) -#define le32toh(x) (uint32_t)(x) -#define letoh32(x) (uint32_t)(x) -#define htole64(x) (uint64_t)(x) -#define le64toh(x) (uint64_t)(x) -#define letoh64(x) (uint64_t)(x) -#else -#define htobe16(x) (uint16_t)(x) -#define be16toh(x) (uint16_t)(x) -#define betoh16(x) (uint16_t)(x) -#define htobe32(x) (uint32_t)(x) -#define be32toh(x) (uint32_t)(x) -#define betoh32(x) (uint32_t)(x) -#define htobe64(x) (uint64_t)(x) -#define be64toh(x) (uint64_t)(x) -#define betoh64(x) (uint64_t)(x) -#define htole16(x) __bswap16(x) -#define le16toh(x) __bswap16(x) -#define letoh16(x) __bswap16(x) -#define htole32(x) __bswap32(x) -#define le32toh(x) __bswap32(x) -#define letoh32(x) __bswap32(x) -#define htole64(x) __bswap64(x) -#define le64toh(x) __bswap64(x) -#define letoh64(x) __bswap64(x) -#endif - -#endif - -#endif diff --git a/waterbox/libc/includes/errno.h b/waterbox/libc/includes/errno.h deleted file mode 100644 index 1e712136b7..0000000000 --- a/waterbox/libc/includes/errno.h +++ /dev/null @@ -1,105 +0,0 @@ -/* Errors - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_ERRNO_H -#define _PDCLIB_ERRNO_H _PDCLIB_ERRNO_H - -#include "_PDCLIB_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern int * _PDCLIB_errno_func( void ); -#define errno (*_PDCLIB_errno_func()) - -/* C only requires the following three */ -#define ERANGE _PDCLIB_ERANGE -#define EDOM _PDCLIB_EDOM -#define EILSEQ _PDCLIB_EILSEQ - -/* C++11 additionally requires the following (taken from POSIX) */ -#define E2BIG _PDCLIB_E2BIG -#define EACCES _PDCLIB_EACCES -#define EADDRINUSE _PDCLIB_EADDRINUSE -#define EADDRNOTAVAIL _PDCLIB_EADDRNOTAVAIL -#define EAFNOSUPPORT _PDCLIB_EAFNOSUPPORT -#define EAGAIN _PDCLIB_EAGAIN -#define EALREADY _PDCLIB_EALREADY -#define EBADF _PDCLIB_EBADF -#define EBADMSG _PDCLIB_EBADMSG -#define EBUSY _PDCLIB_EBUSY -#define ECANCELED _PDCLIB_ECANCELED -#define ECHILD _PDCLIB_ECHILD -#define ECONNABORTED _PDCLIB_ECONNABORTED -#define ECONNREFUSED _PDCLIB_ECONNREFUSED -#define ECONNRESET _PDCLIB_ECONNRESET -#define EDEADLK _PDCLIB_EDEADLK -#define EDESTADDRREQ _PDCLIB_EDESTADDRREQ -#define EEXIST _PDCLIB_EEXIST -#define EFAULT _PDCLIB_EFAULT -#define EFBIG _PDCLIB_EFBIG -#define EHOSTUNREACH _PDCLIB_EHOSTUNREACH -#define EIDRM _PDCLIB_EIDRM -#define EINPROGRESS _PDCLIB_EINPROGRESS -#define EINTR _PDCLIB_EINTR -#define EINVAL _PDCLIB_EINVAL -#define EIO _PDCLIB_EIO -#define EISCONN _PDCLIB_EISCONN -#define EISDIR _PDCLIB_EISDIR -#define ELOOP _PDCLIB_ELOOP -#define EMFILE _PDCLIB_EMFILE -#define EMLINK _PDCLIB_EMLINK -#define EMSGSIZE _PDCLIB_EMSGSIZE -#define ENAMETOOLONG _PDCLIB_ENAMETOOLONG -#define ENETDOWN _PDCLIB_ENETDOWN -#define ENETRESET _PDCLIB_ENETRESET -#define ENETUNREACH _PDCLIB_ENETUNREACH -#define ENFILE _PDCLIB_ENFILE -#define ENOBUFS _PDCLIB_ENOBUFS -#define ENODATA _PDCLIB_ENODATA -#define ENODEV _PDCLIB_ENODEV -#define ENOENT _PDCLIB_ENOENT -#define ENOEXEC _PDCLIB_ENOEXEC -#define ENOLCK _PDCLIB_ENOLCK -#define ENOLINK _PDCLIB_ENOLINK -#define ENOMEM _PDCLIB_ENOMEM -#define ENOMSG _PDCLIB_ENOMSG -#define ENOPROTOOPT _PDCLIB_ENOPROTOOPT -#define ENOSPC _PDCLIB_ENOSPC -#define ENOSR _PDCLIB_ENOSR -#define ENOSTR _PDCLIB_ENOSTR -#define ENOSYS _PDCLIB_ENOSYS -#define ENOTCONN _PDCLIB_ENOTCONN -#define ENOTDIR _PDCLIB_ENOTDIR -#define ENOTEMPTY _PDCLIB_ENOTEMPTY -#define ENOTRECOVERABLE _PDCLIB_ENOTRECOVERABLE -#define ENOTSOCK _PDCLIB_ENOTSOCK -#define ENOTSUP _PDCLIB_ENOTSUP -#define ENOTTY _PDCLIB_ENOTTY -#define ENXIO _PDCLIB_ENXIO -#define EOPNOTSUPP _PDCLIB_EOPNOTSUPP -#define EOVERFLOW _PDCLIB_EOVERFLOW -#define EOWNERDEAD _PDCLIB_EOWNERDEAD -#define EPERM _PDCLIB_EPERM -#define EPIPE _PDCLIB_EPIPE -#define EPROTO _PDCLIB_EPROTO -#define EPROTONOSUPPORT _PDCLIB_EPROTONOSUPPORT -#define EPROTOTYPE _PDCLIB_EPROTOTYPE -#define EROFS _PDCLIB_EROFS -#define ESPIPE _PDCLIB_ESPIPE -#define ESRCH _PDCLIB_ESRCH -#define ETIME _PDCLIB_ETIME -#define ETIMEDOUT _PDCLIB_ETIMEDOUT -#define ETXTBSY _PDCLIB_ETXTBSY -#define EWOULDBLOCK _PDCLIB_EWOULDBLOCK -#define EXDEV _PDCLIB_EXDEV - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/waterbox/libc/includes/features.h b/waterbox/libc/includes/features.h deleted file mode 100644 index 3cc3e57933..0000000000 --- a/waterbox/libc/includes/features.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef _FEATURES_H -#define _FEATURES_H - -#if defined(_ALL_SOURCE) && !defined(_GNU_SOURCE) -#define _GNU_SOURCE 1 -#endif - -#if defined(_DEFAULT_SOURCE) && !defined(_BSD_SOURCE) -#define _BSD_SOURCE 1 -#endif - -#if !defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) \ - && !defined(_XOPEN_SOURCE) && !defined(_GNU_SOURCE) \ - && !defined(_BSD_SOURCE) && !defined(__STRICT_ANSI__) -#define _BSD_SOURCE 1 -#define _XOPEN_SOURCE 700 -#endif - -#if __STDC_VERSION__ >= 199901L -#define __restrict restrict -#elif !defined(__GNUC__) -#define __restrict -#endif - -#if __STDC_VERSION__ >= 199901L || defined(__cplusplus) -#define __inline inline -#endif - -#if __STDC_VERSION__ >= 201112L -#elif defined(__GNUC__) -#define _Noreturn __attribute__((__noreturn__)) -#else -#define _Noreturn -#endif - -#endif diff --git a/waterbox/libc/includes/fenv.h b/waterbox/libc/includes/fenv.h deleted file mode 100644 index 05de990c0b..0000000000 --- a/waterbox/libc/includes/fenv.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _FENV_H -#define _FENV_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -int feclearexcept(int); -int fegetexceptflag(fexcept_t *, int); -int feraiseexcept(int); -int fesetexceptflag(const fexcept_t *, int); -int fetestexcept(int); - -int fegetround(void); -int fesetround(int); - -int fegetenv(fenv_t *); -int feholdexcept(fenv_t *); -int fesetenv(const fenv_t *); -int feupdateenv(const fenv_t *); - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/waterbox/libc/includes/float.h b/waterbox/libc/includes/float.h deleted file mode 100644 index 1d6f89dc3b..0000000000 --- a/waterbox/libc/includes/float.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Characteristics of floating types - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_FLOAT_H -#define _PDCLIB_FLOAT_H _PDCLIB_FLOAT_H -#include "_PDCLIB_float.h" - -#define FLT_ROUNDS _PDCLIB_FLT_ROUNDS -#define FLT_EVAL_METHOD _PDCLIB_FLT_EVAL_METHOD -#define DECIMAL_DIG _PDCLIB_DECIMAL_DIG - -/* Radix of exponent representation */ -#define FLT_RADIX _PDCLIB_FLT_RADIX - -/* Number of base-FLT_RADIX digits in the significand of a float */ -#define FLT_MANT_DIG _PDCLIB_FLT_MANT_DIG - -/* Number of decimal digits of precision in a float */ -#define FLT_DIG _PDCLIB_FLT_DIG - -/* Difference between 1.0 and the minimum float greater than 1.0 */ -#define FLT_EPSILON _PDCLIB_FLT_EPSILON - -/* Minimum int x such that FLT_RADIX**(x-1) is a normalised float */ -#define FLT_MIN_EXP _PDCLIB_FLT_MIN_EXP - -/* Minimum normalised float */ -#define FLT_MIN _PDCLIB_FLT_MIN - -/* Minimum int x such that 10**x is a normalised float */ -#define FLT_MIN_10_EXP _PDCLIB_FLT_MIN_10_EXP - -/* Maximum int x such that FLT_RADIX**(x-1) is a representable float */ -#define FLT_MAX_EXP _PDCLIB_FLT_MAX_EXP - -/* Maximum float */ -#define FLT_MAX _PDCLIB_FLT_MAX - -/* Maximum int x such that 10**x is a representable float */ -#define FLT_MAX_10_EXP _PDCLIB_FLT_MAX_10_EXP - - -/* Number of base-FLT_RADIX digits in the significand of a double */ -#define DBL_MANT_DIG _PDCLIB_DBL_MANT_DIG - -/* Number of decimal digits of precision in a double */ -#define DBL_DIG _PDCLIB_DBL_DIG - -/* Difference between 1.0 and the minimum double greater than 1.0 */ -#define DBL_EPSILON _PDCLIB_DBL_EPSILON - -/* Minimum int x such that FLT_RADIX**(x-1) is a normalised double */ -#define DBL_MIN_EXP _PDCLIB_DBL_MIN_EXP - -/* Minimum normalised double */ -#define DBL_MIN _PDCLIB_DBL_MIN - -/* Minimum int x such that 10**x is a normalised double */ -#define DBL_MIN_10_EXP _PDCLIB_DBL_MIN_10_EXP - -/* Maximum int x such that FLT_RADIX**(x-1) is a representable double */ -#define DBL_MAX_EXP _PDCLIB_DBL_MAX_EXP - -/* Maximum double */ -#define DBL_MAX _PDCLIB_DBL_MAX - -/* Maximum int x such that 10**x is a representable double */ -#define DBL_MAX_10_EXP _PDCLIB_DBL_MAX_10_EXP - - -/* Number of base-FLT_RADIX digits in the significand of a long double */ -#define LDBL_MANT_DIG _PDCLIB_LDBL_MANT_DIG - -/* Number of decimal digits of precision in a long double */ -#define LDBL_DIG _PDCLIB_LDBL_DIG - -/* Difference between 1.0 and the minimum long double greater than 1.0 */ -#define LDBL_EPSILON _PDCLIB_LDBL_EPSILON - -/* Minimum int x such that FLT_RADIX**(x-1) is a normalised long double */ -#define LDBL_MIN_EXP _PDCLIB_LDBL_MIN_EXP - -/* Minimum normalised long double */ -#define LDBL_MIN _PDCLIB_LDBL_MIN - -/* Minimum int x such that 10**x is a normalised long double */ -#define LDBL_MIN_10_EXP _PDCLIB_LDBL_MIN_10_EXP - -/* Maximum int x such that FLT_RADIX**(x-1) is a representable long double */ -#define LDBL_MAX_EXP _PDCLIB_LDBL_MAX_EXP - -/* Maximum long double */ -#define LDBL_MAX _PDCLIB_LDBL_MAX - -/* Maximum int x such that 10**x is a representable long double */ -#define LDBL_MAX_10_EXP _PDCLIB_LDBL_MAX_10_EXP - -#endif diff --git a/waterbox/libc/includes/inttypes.h b/waterbox/libc/includes/inttypes.h deleted file mode 100644 index f13db1bf8d..0000000000 --- a/waterbox/libc/includes/inttypes.h +++ /dev/null @@ -1,268 +0,0 @@ -/* Format conversion of integer types - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_INTTYPES_H -#define _PDCLIB_INTTYPES_H _PDCLIB_INTTYPES_H -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* This structure has a member quot and a member rem, of type intmax_t. - The order of the members is platform-defined to allow the imaxdiv() - function below to be implemented efficiently. -*/ -typedef struct _PDCLIB_imaxdiv_t imaxdiv_t; - -#define PRId8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, d ) ) -#define PRId16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, d ) ) -#define PRId32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, d ) ) -#define PRId64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, d ) ) - -#define PRIdLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, d ) ) -#define PRIdLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, d ) ) -#define PRIdLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, d ) ) -#define PRIdLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, d ) ) - -#define PRIdFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, d ) ) -#define PRIdFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, d ) ) -#define PRIdFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, d ) ) -#define PRIdFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, d ) ) - -#define PRIdMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, d ) ) -#define PRIdPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, d ) ) - -#define PRIi8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, i ) ) -#define PRIi16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, i ) ) -#define PRIi32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, i ) ) -#define PRIi64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, i ) ) - -#define PRIiLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, i ) ) -#define PRIiLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, i ) ) -#define PRIiLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, i ) ) -#define PRIiLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, i ) ) - -#define PRIiFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, i ) ) -#define PRIiFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, i ) ) -#define PRIiFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, i ) ) -#define PRIiFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, i ) ) - -#define PRIiMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, i ) ) -#define PRIiPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, i ) ) - -#define PRIo8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, o ) ) -#define PRIo16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, o ) ) -#define PRIo32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, o ) ) -#define PRIo64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, o ) ) - -#define PRIoLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, o ) ) -#define PRIoLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, o ) ) -#define PRIoLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, o ) ) -#define PRIoLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, o ) ) - -#define PRIoFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, o ) ) -#define PRIoFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, o ) ) -#define PRIoFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, o ) ) -#define PRIoFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, o ) ) - -#define PRIoMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, o ) ) -#define PRIoPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, o ) ) - -#define PRIu8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, u ) ) -#define PRIu16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, u ) ) -#define PRIu32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, u ) ) -#define PRIu64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, u ) ) - -#define PRIuLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, u ) ) -#define PRIuLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, u ) ) -#define PRIuLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, u ) ) -#define PRIuLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, u ) ) - -#define PRIuFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, u ) ) -#define PRIuFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, u ) ) -#define PRIuFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, u ) ) -#define PRIuFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, u ) ) - -#define PRIuMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, u ) ) -#define PRIuPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, u ) ) - -#define PRIx8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, x ) ) -#define PRIx16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, x ) ) -#define PRIx32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, x ) ) -#define PRIx64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, x ) ) - -#define PRIxLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, x ) ) -#define PRIxLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, x ) ) -#define PRIxLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, x ) ) -#define PRIxLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, x ) ) - -#define PRIxFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, x ) ) -#define PRIxFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, x ) ) -#define PRIxFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, x ) ) -#define PRIxFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, x ) ) - -#define PRIxMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, x ) ) -#define PRIxPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, x ) ) - -#define PRIX8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, X ) ) -#define PRIX16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, X ) ) -#define PRIX32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, X ) ) -#define PRIX64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, X ) ) - -#define PRIXLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, X ) ) -#define PRIXLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, X ) ) -#define PRIXLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, X ) ) -#define PRIXLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, X ) ) - -#define PRIXFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, X ) ) -#define PRIXFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, X ) ) -#define PRIXFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, X ) ) -#define PRIXFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, X ) ) - -#define PRIXMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, X ) ) -#define PRIXPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, X ) ) - -#define SCNd8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, d ) ) -#define SCNd16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, d ) ) -#define SCNd32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, d ) ) -#define SCNd64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, d ) ) - -#define SCNdLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, d ) ) -#define SCNdLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, d ) ) -#define SCNdLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, d ) ) -#define SCNdLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, d ) ) - -#define SCNdFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, d ) ) -#define SCNdFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, d ) ) -#define SCNdFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, d ) ) -#define SCNdFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, d ) ) - -#define SCNdMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, d ) ) -#define SCNdPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, d ) ) - -#define SCNi8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, i ) ) -#define SCNi16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, i ) ) -#define SCNi32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, i ) ) -#define SCNi64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, i ) ) - -#define SCNiLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, i ) ) -#define SCNiLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, i ) ) -#define SCNiLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, i ) ) -#define SCNiLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, i ) ) - -#define SCNiFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, i ) ) -#define SCNiFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, i ) ) -#define SCNiFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, i ) ) -#define SCNiFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, i ) ) - -#define SCNiMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, i ) ) -#define SCNiPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, i ) ) - -#define SCNo8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, o ) ) -#define SCNo16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, o ) ) -#define SCNo32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, o ) ) -#define SCNo64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, o ) ) - -#define SCNoLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, o ) ) -#define SCNoLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, o ) ) -#define SCNoLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, o ) ) -#define SCNoLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, o ) ) - -#define SCNoFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, o ) ) -#define SCNoFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, o ) ) -#define SCNoFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, o ) ) -#define SCNoFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, o ) ) - -#define SCNoMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, o ) ) -#define SCNoPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, o ) ) - -#define SCNu8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, u ) ) -#define SCNu16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, u ) ) -#define SCNu32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, u ) ) -#define SCNu64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, u ) ) - -#define SCNuLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, u ) ) -#define SCNuLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, u ) ) -#define SCNuLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, u ) ) -#define SCNuLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, u ) ) - -#define SCNuFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, u ) ) -#define SCNuFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, u ) ) -#define SCNuFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, u ) ) -#define SCNuFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, u ) ) - -#define SCNuMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, u ) ) -#define SCNuPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, u ) ) - -#define SCNx8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, x ) ) -#define SCNx16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, x ) ) -#define SCNx32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, x ) ) -#define SCNx64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, x ) ) - -#define SCNxLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, x ) ) -#define SCNxLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, x ) ) -#define SCNxLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, x ) ) -#define SCNxLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, x ) ) - -#define SCNxFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, x ) ) -#define SCNxFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, x ) ) -#define SCNxFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, x ) ) -#define SCNxFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, x ) ) - -#define SCNxMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, x ) ) -#define SCNxPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, x ) ) - -/* Functions for greatest-width integer types */ - -/* Calculate the absolute value of j */ -intmax_t imaxabs( intmax_t j ) _PDCLIB_nothrow; - -/* Return quotient (quot) and remainder (rem) of an integer division in the - imaxdiv_t struct. -*/ -imaxdiv_t imaxdiv( intmax_t numer, intmax_t denom ) _PDCLIB_nothrow; - -/* Seperate the character array nptr into three parts: A (possibly empty) - sequence of whitespace characters, a character representation of an integer - to the given base, and trailing invalid characters (including the terminating - null character). If base is 0, assume it to be 10, unless the integer - representation starts with 0x / 0X (setting base to 16) or 0 (setting base to - 8). If given, base can be anything from 0 to 36, using the 26 letters of the - base alphabet (both lowercase and uppercase) as digits 10 through 35. - The integer representation is then converted into the return type of the - function. It can start with a '+' or '-' sign. If the sign is '-', the result - of the conversion is negated. - If the conversion is successful, the converted value is returned. If endptr - is not a NULL pointer, a pointer to the first trailing invalid character is - returned in *endptr. - If no conversion could be performed, zero is returned (and nptr in *endptr, - if endptr is not a NULL pointer). If the converted value does not fit into - the return type, the functions return INTMAX_MIN, INTMAX_MAX, or UINTMAX_MAX, - respectively, depending on the sign of the integer representation and the - return type, and errno is set to ERANGE. -*/ - -/* These functions are equivalent to strtol() / strtoul() in , but on - the potentially larger type. -*/ -intmax_t strtoimax( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr, int base ) _PDCLIB_nothrow; -uintmax_t strtoumax( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr, int base ) _PDCLIB_nothrow; - -/* These functions are equivalent to wcstol() / wcstoul() in , but on - the potentially larger type. -*/ -/* TODO: Not _PDCLIB_nothrow? */ -/* -intmax_t wcstoimax( const _PDCLIB_wchar_t * _PDCLIB_restrict nptr, _PDCLIB_wchar_t * * _PDCLIB_restrict endptr, int base ); -uintmax_t wcstoumax( const _PDCLIB_wchar_t * _PDCLIB_restrict nptr, _PDCLIB_wchar_t * * _PDCLIB_restrict endptr, int base ); -*/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/waterbox/libc/includes/iso646.h b/waterbox/libc/includes/iso646.h deleted file mode 100644 index 3ad9f5ce48..0000000000 --- a/waterbox/libc/includes/iso646.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Alternative spellings - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_ISO646_H -#define _PDCLIB_ISO646_H _PDCLIB_ISO646_H - -#ifndef __cplusplus -#define and && -#define and_eq &= -#define bitand & -#define bitor | -#define compl ~ -#define not ! -#define not_eq != -#define or || -#define or_eq |= -#define xor ^ -#define xor_eq ^= -#endif - -#endif diff --git a/waterbox/libc/includes/limits.h b/waterbox/libc/includes/limits.h deleted file mode 100644 index 79fc6f607a..0000000000 --- a/waterbox/libc/includes/limits.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Sizes of integer types - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_LIMITS_H -#define _PDCLIB_LIMITS_H _PDCLIB_LIMITS_H -#include "_PDCLIB_int.h" - -/* MSVC 2010 defines this to 5, which is enough for UTF-8 but might rule out - stateful encodings (like ISO/IEC 2022). GCC 5.3 defines this to 16, which - is meant to ensure future compatibility. For the same reason, we go along - with GCC's definition. - http://lists.gnu.org/archive/html/bug-gnulib/2015-05/msg00001.html -*/ -#define MB_LEN_MAX 16 - -#define LLONG_MIN _PDCLIB_LLONG_MIN -#define LLONG_MAX _PDCLIB_LLONG_MAX -#define ULLONG_MAX _PDCLIB_ULLONG_MAX - -#define CHAR_BIT _PDCLIB_CHAR_BIT -#define CHAR_MAX _PDCLIB_CHAR_MAX -#define CHAR_MIN _PDCLIB_CHAR_MIN -#define SCHAR_MAX _PDCLIB_SCHAR_MAX -#define SCHAR_MIN _PDCLIB_SCHAR_MIN -#define UCHAR_MAX _PDCLIB_UCHAR_MAX -#define SHRT_MAX _PDCLIB_SHRT_MAX -#define SHRT_MIN _PDCLIB_SHRT_MIN -#define INT_MAX _PDCLIB_INT_MAX -#define INT_MIN _PDCLIB_INT_MIN -#define LONG_MAX _PDCLIB_LONG_MAX -#define LONG_MIN _PDCLIB_LONG_MIN -#define USHRT_MAX _PDCLIB_USHRT_MAX -#define UINT_MAX _PDCLIB_UINT_MAX -#define ULONG_MAX _PDCLIB_ULONG_MAX - -#endif diff --git a/waterbox/libc/includes/locale.h b/waterbox/libc/includes/locale.h deleted file mode 100644 index ac04cd11d1..0000000000 --- a/waterbox/libc/includes/locale.h +++ /dev/null @@ -1,147 +0,0 @@ -/* Localization - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_LOCALE_H -#define _PDCLIB_LOCALE_H _PDCLIB_LOCALE_H -#include "_PDCLIB_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _PDCLIB_NULL_DEFINED -#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED -#define NULL _PDCLIB_NULL -#endif - -/* The structure returned by localeconv(). - - The values for *_sep_by_space: - 0 - no space - 1 - if symbol and sign are adjacent, a space seperates them from the value; - otherwise a space seperates the symbol from the value - 2 - if symbol and sign are adjacent, a space seperates them; otherwise a - space seperates the sign from the value - - The values for *_sign_posn: - 0 - Parentheses surround value and symbol - 1 - sign precedes value and symbol - 2 - sign succeeds value and symbol - 3 - sign immediately precedes symbol - 4 - sign immediately succeeds symbol -*/ -struct lconv -{ - char * decimal_point; /* decimal point character */ - char * thousands_sep; /* character for seperating groups of digits */ - char * grouping; /* string indicating the size of digit groups */ - char * mon_decimal_point; /* decimal point for monetary quantities */ - char * mon_thousands_sep; /* thousands_sep for monetary quantities */ - char * mon_grouping; /* grouping for monetary quantities */ - char * positive_sign; /* string indicating nonnegative mty. qty. */ - char * negative_sign; /* string indicating negative mty. qty. */ - char * currency_symbol; /* local currency symbol (e.g. '$') */ - char * int_curr_symbol; /* international currency symbol (e.g. "USD" */ - char frac_digits; /* fractional digits in local monetary qty. */ - char p_cs_precedes; /* if currency_symbol precedes positive qty. */ - char n_cs_precedes; /* if currency_symbol precedes negative qty. */ - char p_sep_by_space; /* if it is seperated by space from pos. qty. */ - char n_sep_by_space; /* if it is seperated by space from neg. qty. */ - char p_sign_posn; /* positioning of positive_sign for mon. qty. */ - char n_sign_posn; /* positioning of negative_sign for mon. qty. */ - char int_frac_digits; /* Same as above, for international format */ - char int_p_cs_precedes; /* Same as above, for international format */ - char int_n_cs_precedes; /* Same as above, for international format */ - char int_p_sep_by_space; /* Same as above, for international format */ - char int_n_sep_by_space; /* Same as above, for international format */ - char int_p_sign_posn; /* Same as above, for international format */ - char int_n_sign_posn; /* Same as above, for international format */ -}; - -/* First arguments to setlocale(). - TODO: Beware, values might change before v0.6 is released. -*/ -/* Entire locale */ -#define LC_ALL -1 -/* Collation (strcoll(), strxfrm()) */ -#define LC_COLLATE 0 -/* Character types () */ -#define LC_CTYPE 1 -/* Monetary formatting (as returned by localeconv) */ -#define LC_MONETARY 2 -/* Decimal-point character (for printf() / scanf() functions), string - conversions, nonmonetary formatting as returned by localeconv */ -#define LC_NUMERIC 3 -/* Time formats (strftime(), wcsftime()) */ -#define LC_TIME 4 - -/* not supported! */ -#define LC_MESSAGES 5 - -/* The category parameter can be any of the LC_* macros to specify if the call - to setlocale() shall affect the entire locale or only a portion thereof. - The category locale specifies which locale should be switched to, with "C" - being the minimal default locale, and "" being the locale-specific native - environment. A NULL pointer makes setlocale() return the *current* setting. - Otherwise, returns a pointer to a string associated with the specified - category for the new locale. -*/ -char * setlocale( int category, const char * locale ) _PDCLIB_nothrow; - -/* Returns a struct lconv initialized to the values appropriate for the current - locale setting. -*/ -struct lconv * localeconv( void ) _PDCLIB_nothrow; - -#if _PDCLIB_POSIX_MIN(2008) -#define LC_COLLATE_MASK (1 << LC_COLLATE) -#define LC_CTYPE_MASK (1 << LC_CTYPE) -#define LC_MONETARY_MASK (1 << LC_MONETARY) -#define LC_NUMERIC_MASK (1 << LC_NUMERIC) -#define LC_TIME_MASK (1 << LC_TIME) -#define LC_MESSAGES_MASK (1 << LC_MESSAGES) -#define LC_ALL_MASK (LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MONETARY_MASK | \ - LC_NUMERIC_MASK | LC_TIME_MASK | LC_MESSAGES_MASK) - - -/* POSIX locale type */ -typedef _PDCLIB_locale_t locale_t; - -/* Global locale */ -extern struct _PDCLIB_locale _PDCLIB_global_locale; -#define LC_GLOBAL_LOCALE (&_PDCLIB_global_locale) - -#ifdef _PDCLIB_LOCALE_METHOD - -locale_t newlocale(int category_mask, const char *locale, locale_t base); - -/* Set the thread locale to newlocale - * - * If newlocale is (locale_t)0, then doesn't change the locale and just returns - * the existing locale. - * - * If newlocale is LC_GLOBAL_LOCALE, resets the thread's locale to use the - * global locale. - * - * Returns the previous thread locale. If the thread had no previous locale, - * returns the global locale. - */ -locale_t uselocale( locale_t newlocale ); - -/* Returns a copy of loc */ -locale_t duplocale( locale_t loc ); - -/* Frees the passed locale object */ -void freelocale( locale_t loc ); -#endif - -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/waterbox/libc/includes/math.h b/waterbox/libc/includes/math.h deleted file mode 100644 index 6ac91da24f..0000000000 --- a/waterbox/libc/includes/math.h +++ /dev/null @@ -1,430 +0,0 @@ -#ifndef _MATH_H -#define _MATH_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#define __NEED_float_t -#define __NEED_double_t -#include - -#if 100*__GNUC__+__GNUC_MINOR__ >= 303 -#define NAN __builtin_nanf("") -#define INFINITY __builtin_inff() -#else -#define NAN (0.0f/0.0f) -#define INFINITY 1e5000f -#endif - -#define HUGE_VALF INFINITY -#define HUGE_VAL ((double)INFINITY) -#define HUGE_VALL ((long double)INFINITY) - -#define MATH_ERRNO 1 -#define MATH_ERREXCEPT 2 -#define math_errhandling 2 - -#define FP_ILOGBNAN (-1-(int)(((unsigned)-1)>>1)) -#define FP_ILOGB0 FP_ILOGBNAN - -#define FP_NAN 0 -#define FP_INFINITE 1 -#define FP_ZERO 2 -#define FP_SUBNORMAL 3 -#define FP_NORMAL 4 - -int __fpclassify(double); -int __fpclassifyf(float); -int __fpclassifyl(long double); - -static __inline unsigned __FLOAT_BITS(float __f) -{ - union {float __f; unsigned __i;} __u; - __u.__f = __f; - return __u.__i; -} -static __inline unsigned long long __DOUBLE_BITS(double __f) -{ - union {double __f; unsigned long long __i;} __u; - __u.__f = __f; - return __u.__i; -} - -#define fpclassify(x) ( \ - sizeof(x) == sizeof(float) ? __fpclassifyf(x) : \ - sizeof(x) == sizeof(double) ? __fpclassify(x) : \ - __fpclassifyl(x) ) - -#define isinf(x) ( \ - sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) == 0x7f800000 : \ - sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) == 0x7ffULL<<52 : \ - __fpclassifyl(x) == FP_INFINITE) - -#define isnan(x) ( \ - sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) > 0x7f800000 : \ - sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) > 0x7ffULL<<52 : \ - __fpclassifyl(x) == FP_NAN) - -#define isnormal(x) ( \ - sizeof(x) == sizeof(float) ? ((__FLOAT_BITS(x)+0x00800000) & 0x7fffffff) >= 0x01000000 : \ - sizeof(x) == sizeof(double) ? ((__DOUBLE_BITS(x)+(1ULL<<52)) & -1ULL>>1) >= 1ULL<<53 : \ - __fpclassifyl(x) == FP_NORMAL) - -#define isfinite(x) ( \ - sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) < 0x7f800000 : \ - sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) < 0x7ffULL<<52 : \ - __fpclassifyl(x) > FP_INFINITE) - -int __signbit(double); -int __signbitf(float); -int __signbitl(long double); - -#define signbit(x) ( \ - sizeof(x) == sizeof(float) ? (int)(__FLOAT_BITS(x)>>31) : \ - sizeof(x) == sizeof(double) ? (int)(__DOUBLE_BITS(x)>>63) : \ - __signbitl(x) ) - -#define isunordered(x,y) (isnan((x)) ? ((void)(y),1) : isnan((y))) - -#define __ISREL_DEF(rel, op, type) \ -static __inline int __is##rel(type __x, type __y) \ -{ return !isunordered(__x,__y) && __x op __y; } - -__ISREL_DEF(lessf, <, float_t) -__ISREL_DEF(less, <, double_t) -__ISREL_DEF(lessl, <, long double) -__ISREL_DEF(lessequalf, <=, float_t) -__ISREL_DEF(lessequal, <=, double_t) -__ISREL_DEF(lessequall, <=, long double) -__ISREL_DEF(lessgreaterf, !=, float_t) -__ISREL_DEF(lessgreater, !=, double_t) -__ISREL_DEF(lessgreaterl, !=, long double) -__ISREL_DEF(greaterf, >, float_t) -__ISREL_DEF(greater, >, double_t) -__ISREL_DEF(greaterl, >, long double) -__ISREL_DEF(greaterequalf, >=, float_t) -__ISREL_DEF(greaterequal, >=, double_t) -__ISREL_DEF(greaterequall, >=, long double) - -#define __tg_pred_2(x, y, p) ( \ - sizeof((x)+(y)) == sizeof(float) ? p##f(x, y) : \ - sizeof((x)+(y)) == sizeof(double) ? p(x, y) : \ - p##l(x, y) ) - -#define isless(x, y) __tg_pred_2(x, y, __isless) -#define islessequal(x, y) __tg_pred_2(x, y, __islessequal) -#define islessgreater(x, y) __tg_pred_2(x, y, __islessgreater) -#define isgreater(x, y) __tg_pred_2(x, y, __isgreater) -#define isgreaterequal(x, y) __tg_pred_2(x, y, __isgreaterequal) - -double acos(double); -float acosf(float); -long double acosl(long double); - -double acosh(double); -float acoshf(float); -long double acoshl(long double); - -double asin(double); -float asinf(float); -long double asinl(long double); - -double asinh(double); -float asinhf(float); -long double asinhl(long double); - -double atan(double); -float atanf(float); -long double atanl(long double); - -double atan2(double, double); -float atan2f(float, float); -long double atan2l(long double, long double); - -double atanh(double); -float atanhf(float); -long double atanhl(long double); - -double cbrt(double); -float cbrtf(float); -long double cbrtl(long double); - -double ceil(double); -float ceilf(float); -long double ceill(long double); - -double copysign(double, double); -float copysignf(float, float); -long double copysignl(long double, long double); - -double cos(double); -float cosf(float); -long double cosl(long double); - -double cosh(double); -float coshf(float); -long double coshl(long double); - -double erf(double); -float erff(float); -long double erfl(long double); - -double erfc(double); -float erfcf(float); -long double erfcl(long double); - -double exp(double); -float expf(float); -long double expl(long double); - -double exp2(double); -float exp2f(float); -long double exp2l(long double); - -double expm1(double); -float expm1f(float); -long double expm1l(long double); - -double fabs(double); -float fabsf(float); -long double fabsl(long double); - -double fdim(double, double); -float fdimf(float, float); -long double fdiml(long double, long double); - -double floor(double); -float floorf(float); -long double floorl(long double); - -double fma(double, double, double); -float fmaf(float, float, float); -long double fmal(long double, long double, long double); - -double fmax(double, double); -float fmaxf(float, float); -long double fmaxl(long double, long double); - -double fmin(double, double); -float fminf(float, float); -long double fminl(long double, long double); - -double fmod(double, double); -float fmodf(float, float); -long double fmodl(long double, long double); - -double frexp(double, int *); -float frexpf(float, int *); -long double frexpl(long double, int *); - -double hypot(double, double); -float hypotf(float, float); -long double hypotl(long double, long double); - -int ilogb(double); -int ilogbf(float); -int ilogbl(long double); - -double ldexp(double, int); -float ldexpf(float, int); -long double ldexpl(long double, int); - -double lgamma(double); -float lgammaf(float); -long double lgammal(long double); - -long long llrint(double); -long long llrintf(float); -long long llrintl(long double); - -long long llround(double); -long long llroundf(float); -long long llroundl(long double); - -double log(double); -float logf(float); -long double logl(long double); - -double log10(double); -float log10f(float); -long double log10l(long double); - -double log1p(double); -float log1pf(float); -long double log1pl(long double); - -double log2(double); -float log2f(float); -long double log2l(long double); - -double logb(double); -float logbf(float); -long double logbl(long double); - -long lrint(double); -long lrintf(float); -long lrintl(long double); - -long lround(double); -long lroundf(float); -long lroundl(long double); - -double modf(double, double *); -float modff(float, float *); -long double modfl(long double, long double *); - -double nan(const char *); -float nanf(const char *); -long double nanl(const char *); - -double nearbyint(double); -float nearbyintf(float); -long double nearbyintl(long double); - -double nextafter(double, double); -float nextafterf(float, float); -long double nextafterl(long double, long double); - -double nexttoward(double, long double); -float nexttowardf(float, long double); -long double nexttowardl(long double, long double); - -double pow(double, double); -float powf(float, float); -long double powl(long double, long double); - -double remainder(double, double); -float remainderf(float, float); -long double remainderl(long double, long double); - -double remquo(double, double, int *); -float remquof(float, float, int *); -long double remquol(long double, long double, int *); - -double rint(double); -float rintf(float); -long double rintl(long double); - -double round(double); -float roundf(float); -long double roundl(long double); - -double scalbln(double, long); -float scalblnf(float, long); -long double scalblnl(long double, long); - -double scalbn(double, int); -float scalbnf(float, int); -long double scalbnl(long double, int); - -double sin(double); -float sinf(float); -long double sinl(long double); - -double sinh(double); -float sinhf(float); -long double sinhl(long double); - -double sqrt(double); -float sqrtf(float); -long double sqrtl(long double); - -double tan(double); -float tanf(float); -long double tanl(long double); - -double tanh(double); -float tanhf(float); -long double tanhl(long double); - -double tgamma(double); -float tgammaf(float); -long double tgammal(long double); - -double trunc(double); -float truncf(float); -long double truncl(long double); - - -#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) -#undef MAXFLOAT -#define MAXFLOAT 3.40282346638528859812e+38F -#endif - -#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -#define M_E 2.7182818284590452354 /* e */ -#define M_LOG2E 1.4426950408889634074 /* log_2 e */ -#define M_LOG10E 0.43429448190325182765 /* log_10 e */ -#define M_LN2 0.69314718055994530942 /* log_e 2 */ -#define M_LN10 2.30258509299404568402 /* log_e 10 */ -#define M_PI 3.14159265358979323846 /* pi */ -#define M_PI_2 1.57079632679489661923 /* pi/2 */ -#define M_PI_4 0.78539816339744830962 /* pi/4 */ -#define M_1_PI 0.31830988618379067154 /* 1/pi */ -#define M_2_PI 0.63661977236758134308 /* 2/pi */ -#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ -#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ -#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ - -extern int signgam; - -double j0(double); -double j1(double); -double jn(int, double); - -double y0(double); -double y1(double); -double yn(int, double); -#endif - -#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -#define HUGE 3.40282346638528859812e+38F - -double drem(double, double); -float dremf(float, float); - -int finite(double); -int finitef(float); - -double scalb(double, double); -float scalbf(float, float); - -double significand(double); -float significandf(float); - -double lgamma_r(double, int*); -float lgammaf_r(float, int*); - -float j0f(float); -float j1f(float); -float jnf(int, float); - -float y0f(float); -float y1f(float); -float ynf(int, float); -#endif - -#ifdef _GNU_SOURCE -long double lgammal_r(long double, int*); - -void sincos(double, double*, double*); -void sincosf(float, float*, float*); -void sincosl(long double, long double*, long double*); - -double exp10(double); -float exp10f(float); -long double exp10l(long double); - -double pow10(double); -float pow10f(float); -long double pow10l(long double); -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/waterbox/libc/includes/setjmp.h b/waterbox/libc/includes/setjmp.h deleted file mode 100644 index 89ea066039..0000000000 --- a/waterbox/libc/includes/setjmp.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _SETJMP_H -#define _SETJMP_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define _JBTYPE long long -#define _JBLEN 8 -typedef _JBTYPE jmp_buf[_JBLEN]; - -int setjmp (jmp_buf env); -void longjmp (jmp_buf env, int val); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/waterbox/libc/includes/signal.h b/waterbox/libc/includes/signal.h deleted file mode 100644 index dbcf28c10c..0000000000 --- a/waterbox/libc/includes/signal.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Signal handling - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_SIGNAL_H -#define _PDCLIB_SIGNAL_H _PDCLIB_SIGNAL_H -#include "_PDCLIB_config.h" - -/* Signals ------------------------------------------------------------------ */ - -/* A word on signals, to the people using PDCLib in their OS projects. - - The definitions of the C standard leave about everything that *could* be - useful to be "implementation defined". Without additional, non-standard - arrangements, it is not possible to turn them into a useful tool. - - This example implementation chose to "not generate any of these signals, - except as a result of explicit calls to the raise function", which is - allowed by the standard but of course does nothing for the usefulness of - . - - A useful signal handling would: - 1) make signal() a system call that registers the signal handler with the OS - 2) make raise() a system call triggering an OS signal to the running process - 3) make provisions that further signals of the same type are blocked until - the signal handler returns (optional for SIGILL) -*/ - -/* These are the values used by Linux. */ - -/* Abnormal termination / abort() */ -#define SIGABRT 6 -/* Arithmetic exception / division by zero / overflow */ -#define SIGFPE 8 -/* Illegal instruction */ -#define SIGILL 4 -/* Interactive attention signal */ -#define SIGINT 2 -/* Invalid memory access */ -#define SIGSEGV 11 -/* Termination request */ -#define SIGTERM 15 - -/* The following should be defined to pointer values that could NEVER point to - a valid signal handler function. (They are used as special arguments to - signal().) Again, these are the values used by Linux. -*/ -#define SIG_DFL (void (*)( int ))0 -#define SIG_ERR (void (*)( int ))-1 -#define SIG_IGN (void (*)( int ))1 - -typedef _PDCLIB_sig_atomic sig_atomic_t; - -/* Installs a signal handler "func" for the given signal. - A signal handler is a function that takes an integer as argument (the signal - number) and returns void. - - Note that a signal handler can do very little else than: - 1) assign a value to a static object of type "volatile sig_atomic_t", - 2) call signal() with the value of sig equal to the signal received, - 3) call _Exit(), - 4) call abort(). - Virtually everything else is undefind. - - The signal() function returns the previous installed signal handler, which - at program start may be SIG_DFL or SIG_ILL. (This implementation uses - SIG_DFL for all handlers.) If the request cannot be honored, SIG_ERR is - returned and errno is set to an unspecified positive value. -*/ -void (*signal( int sig, void (*func)( int ) ) )( int ); - -/* Raises the given signal (executing the registered signal handler with the - given signal number as parameter). - This implementation does not prevent further signals of the same time from - occuring, but executes signal( sig, SIG_DFL ) before entering the signal - handler (i.e., a second signal before the signal handler re-registers itself - or SIG_IGN will end the program). - Returns zero if successful, nonzero otherwise. */ -int raise( int sig ); - -#endif - diff --git a/waterbox/libc/includes/stdalign.h b/waterbox/libc/includes/stdalign.h deleted file mode 100644 index 0bc20f67cf..0000000000 --- a/waterbox/libc/includes/stdalign.h +++ /dev/null @@ -1,17 +0,0 @@ -/* Alignmend - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_STDALIGN_H -#define _PDCLIB_ALIGN_H _PDCLIB_ALIGN_H - -#define alignas _Alignas -#define alignof _Alignof - -#define __alignas_is_defined 1 -#define __alignof_is_defined 1 - -#endif - diff --git a/waterbox/libc/includes/stdarg.h b/waterbox/libc/includes/stdarg.h deleted file mode 100644 index 1ebf3fba28..0000000000 --- a/waterbox/libc/includes/stdarg.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Variable arguments - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_STDARG_H -#define _PDCLIB_STDARG_H _PDCLIB_STDARG_H -#include "_PDCLIB_aux.h" -#include "_PDCLIB_config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef _PDCLIB_va_list va_list; - -#define va_arg( ap, type ) _PDCLIB_va_arg( ap, type ) -#define va_copy( dest, src ) _PDCLIB_va_copy( dest, src ) -#define va_end( ap ) _PDCLIB_va_end( ap ) -#define va_start( ap, parmN ) _PDCLIB_va_start( ap, parmN ) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/waterbox/libc/includes/stdbool.h b/waterbox/libc/includes/stdbool.h deleted file mode 100644 index daec901e45..0000000000 --- a/waterbox/libc/includes/stdbool.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Boolean type and values - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_STDBOOL_H -#define _PDCLIB_STDBOOL_H _PDCLIB_STDBOOL_H - -#ifndef __cplusplus -#define bool _Bool -#define true 1 -#define false 0 -#endif - -#define __bool_true_false_are_defined 1 - -#endif diff --git a/waterbox/libc/includes/stddef.h b/waterbox/libc/includes/stddef.h deleted file mode 100644 index 600731bdca..0000000000 --- a/waterbox/libc/includes/stddef.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Common definitions - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_STDDEF_H -#define _PDCLIB_STDDEF_H _PDCLIB_STDDEF_H -#include "_PDCLIB_config.h" -#include "_PDCLIB_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef _PDCLIB_ptrdiff_t ptrdiff_t; - -#ifndef _PDCLIB_SIZE_T_DEFINED -#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED -typedef _PDCLIB_size_t size_t; -#endif - -#ifndef __cplusplus -#ifndef _PDCLIB_WCHAR_T_DEFINED -#define _PDCLIB_WCHAR_T_DEFINED _PDCLIB_WCHAR_T_DEFINED -typedef _PDCLIB_wchar_t wchar_t; -#endif -#endif - -#ifndef _PDCLIB_NULL_DEFINED -#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED -#define NULL _PDCLIB_NULL -#endif - -#define offsetof( type, member ) _PDCLIB_offsetof( type, member ) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/waterbox/libc/includes/stdint.h b/waterbox/libc/includes/stdint.h deleted file mode 100644 index 69a6dc5a7b..0000000000 --- a/waterbox/libc/includes/stdint.h +++ /dev/null @@ -1,209 +0,0 @@ -/* Integer types - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_STDINT_H -#define _PDCLIB_STDINT_H _PDCLIB_STDINT_H -#include "_PDCLIB_int.h" - -/* Exact-width integer types. */ - -typedef _PDCLIB_int8_t int8_t; -typedef _PDCLIB_int16_t int16_t; -typedef _PDCLIB_int32_t int32_t; -typedef _PDCLIB_int64_t int64_t; - -typedef _PDCLIB_uint8_t uint8_t; -typedef _PDCLIB_uint16_t uint16_t; -typedef _PDCLIB_uint32_t uint32_t; -typedef _PDCLIB_uint64_t uint64_t; - -/* Minimum-width integer types */ - -/* You are allowed to add more types here, e.g. int_least24_t. For the standard - types, int_leastN_t is equivalent to the corresponding exact type intN_t by - definition. -*/ - -typedef _PDCLIB_int8_t int_least8_t; -typedef _PDCLIB_int16_t int_least16_t; -typedef _PDCLIB_int32_t int_least32_t; -typedef _PDCLIB_int64_t int_least64_t; - -typedef _PDCLIB_uint8_t uint_least8_t; -typedef _PDCLIB_uint16_t uint_least16_t; -typedef _PDCLIB_uint32_t uint_least32_t; -typedef _PDCLIB_uint64_t uint_least64_t; - -/* Fastest minimum-width integer types */ - -/* You are allowed to add more types here, e.g. int_fast24_t. */ - -typedef _PDCLIB_int_fast8_t int_fast8_t; -typedef _PDCLIB_int_fast16_t int_fast16_t; -typedef _PDCLIB_int_fast32_t int_fast32_t; -typedef _PDCLIB_int_fast64_t int_fast64_t; - -typedef _PDCLIB_uint_fast8_t uint_fast8_t; -typedef _PDCLIB_uint_fast16_t uint_fast16_t; -typedef _PDCLIB_uint_fast32_t uint_fast32_t; -typedef _PDCLIB_uint_fast64_t uint_fast64_t; - -/* Integer types capable of holding object pointers */ - -typedef _PDCLIB_intptr_t intptr_t; -typedef _PDCLIB_uintptr_t uintptr_t; - -/* Greatest-width integer types */ - -typedef _PDCLIB_intmax_t intmax_t; -typedef _PDCLIB_uintmax_t uintmax_t; - -/* Limits of specified-width integer types */ - -#ifdef __cplusplus -#ifndef __STDC_LIMIT_MACROS -#define _PDCLIB_NO_LIMIT_MACROS -#endif -#endif - -#ifndef _PDCLIB_NO_LIMIT_MACROS - -/* Limits of exact-width integer types */ - -#define INT8_MIN _PDCLIB_INT8_MIN -#define INT8_MAX _PDCLIB_INT8_MAX -#define UINT8_MAX _PDCLIB_UINT8_MAX - -#define INT16_MIN _PDCLIB_INT16_MIN -#define INT16_MAX _PDCLIB_INT16_MAX -#define UINT16_MAX _PDCLIB_UINT16_MAX - -#define INT32_MIN _PDCLIB_INT32_MIN -#define INT32_MAX _PDCLIB_INT32_MAX -#define UINT32_MAX _PDCLIB_UINT32_MAX - -#define INT64_MIN _PDCLIB_INT64_MIN -#define INT64_MAX _PDCLIB_INT64_MAX -#define UINT64_MAX _PDCLIB_UINT64_MAX - -/* Limits of minimum-width integer types */ - -/* For the standard widths, least and exact types are equivalent. - You are allowed to add more types here, e.g. int_least24_t. -*/ - -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define UINT_LEAST8_MAX UINT8_MAX - -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define UINT_LEAST16_MAX UINT16_MAX - -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define UINT_LEAST32_MAX UINT32_MAX - -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -/* Limits of fastest minimum-width integer types */ - -#define INT_FAST8_MIN _PDCLIB_INT_FAST8_MIN -#define INT_FAST8_MAX _PDCLIB_INT_FAST8_MAX -#define UINT_FAST8_MAX _PDCLIB_UINT_FAST8_MAX - -#define INT_FAST16_MIN _PDCLIB_INT_FAST16_MIN -#define INT_FAST16_MAX _PDCLIB_INT_FAST16_MAX -#define UINT_FAST16_MAX _PDCLIB_UINT_FAST16_MAX - -#define INT_FAST32_MIN _PDCLIB_INT_FAST32_MIN -#define INT_FAST32_MAX _PDCLIB_INT_FAST32_MAX -#define UINT_FAST32_MAX _PDCLIB_UINT_FAST32_MAX - -#define INT_FAST64_MIN _PDCLIB_INT_FAST64_MIN -#define INT_FAST64_MAX _PDCLIB_INT_FAST64_MAX -#define UINT_FAST64_MAX _PDCLIB_UINT_FAST64_MAX - -/* Limits of integer types capable of holding object pointers */ - -#define INTPTR_MIN _PDCLIB_INTPTR_MIN -#define INTPTR_MAX _PDCLIB_INTPTR_MAX -#define UINTPTR_MAX _PDCLIB_UINTPTR_MAX - -/* Limits of greatest-width integer types */ - -#define INTMAX_MIN _PDCLIB_INTMAX_MIN -#define INTMAX_MAX _PDCLIB_INTMAX_MAX -#define UINTMAX_MAX _PDCLIB_UINTMAX_MAX - -/* Limits of other integer types */ - -#define PTRDIFF_MIN _PDCLIB_PTRDIFF_MIN -#define PTRDIFF_MAX _PDCLIB_PTRDIFF_MAX - -#define SIG_ATOMIC_MIN _PDCLIB_SIG_ATOMIC_MIN -#define SIG_ATOMIC_MAX _PDCLIB_SIG_ATOMIC_MAX - -#define SIZE_MAX _PDCLIB_SIZE_MAX - -#ifndef _PDCLIB_WCHAR_MIN_MAX_DEFINED -#define _PDCLIB_WCHAR_MIN_MAX_DEFINED -#define WCHAR_MIN _PDCLIB_WCHAR_MIN -#define WCHAR_MAX _PDCLIB_WCHAR_MAX -#endif - -#define WINT_MIN _PDCLIB_WINT_MIN -#define WINT_MAX _PDCLIB_WINT_MAX - -#endif - -/* Macros for integer constants */ - -#ifdef __cplusplus -#ifndef __STDC_CONSTANT_MACROS -#define _PDCLIB_NO_CONSTANT_MACROS -#endif -#endif - -#ifndef _PDCLIB_NO_CONSTANT_MACROS - -/* Macros for minimum-width integer constants */ - -/* As the minimum-width types - for the required widths of 8, 16, 32, and 64 - bits - are expressed in terms of the exact-width types, the mechanism for - these macros is to append the literal of that exact-width type to the macro - parameter. - This is considered a hack, as the author is not sure his understanding of - the requirements of this macro is correct. Any input appreciated. -*/ - -/* Expand to an integer constant of specified value and type int_leastN_t */ - -#define INT8_C( value ) value -#define INT16_C( value ) value -#define INT32_C( value ) _PDCLIB_concat( value, _PDCLIB_INT32_LITERAL ) -#define INT64_C( value ) _PDCLIB_concat( value, _PDCLIB_INT64_LITERAL ) - -/* Expand to an integer constant of specified value and type uint_leastN_t */ - -#define UINT8_C( value ) value -#define UINT16_C( value ) value -#define UINT32_C( value ) _PDCLIB_concat( value, _PDCLIB_UINT32_LITERAL ) -#define UINT64_C( value ) _PDCLIB_concat( value, _PDCLIB_UINT64_LITERAL ) - -/* Macros for greatest-width integer constants */ - -/* Expand to an integer constant of specified value and type intmax_t */ -#define INTMAX_C( value ) _PDCLIB_INTMAX_C( value ) - -/* Expand to an integer constant of specified value and type uintmax_t */ -#define UINTMAX_C( value ) _PDCLIB_UINTMAX_C( value ) - -#endif - -#endif diff --git a/waterbox/libc/includes/stdio.h b/waterbox/libc/includes/stdio.h deleted file mode 100644 index c70ad2f502..0000000000 --- a/waterbox/libc/includes/stdio.h +++ /dev/null @@ -1,913 +0,0 @@ -/* Input/output - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_STDIO_H -#define _PDCLIB_STDIO_H _PDCLIB_STDIO_H -#include "_PDCLIB_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _PDCLIB_SIZE_T_DEFINED -#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED -typedef _PDCLIB_size_t size_t; -#endif - -#ifndef _PDCLIB_NULL_DEFINED -#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED -#define NULL _PDCLIB_NULL -#endif - -/* See setvbuf(), third argument */ -#define _IOFBF 1 -#define _IOLBF 2 -#define _IONBF 4 - -/* The following are platform-dependant, and defined in _PDCLIB_config.h. */ -typedef _PDCLIB_fpos_t fpos_t; -typedef _PDCLIB_file_t FILE; -#define EOF -1 -#define BUFSIZ _PDCLIB_BUFSIZ -#define FOPEN_MAX _PDCLIB_FOPEN_MAX -#define FILENAME_MAX _PDCLIB_FILENAME_MAX -#define L_tmpnam _PDCLIB_L_tmpnam -#define TMP_MAX _PDCLIB_TMP_MAX - -/* See fseek(), third argument - * - * Some system headers (e.g. windows) also define the SEEK_* values. Check for - * this and validate that they're the same value - */ -#if !defined(SEEK_CUR) - #define SEEK_CUR _PDCLIB_SEEK_CUR -#elif SEEK_CUR != _PDCLIB_SEEK_CUR - #error SEEK_CUR != _PDCLIB_SEEK_CUR -#endif - -#if !defined(SEEK_END) - #define SEEK_END _PDCLIB_SEEK_END -#elif SEEK_END != _PDCLIB_SEEK_END - #error SEEK_END != _PDCLIB_SEEK_END -#endif - -#if !defined(SEEK_SET) - #define SEEK_SET _PDCLIB_SEEK_SET -#elif SEEK_SET != _PDCLIB_SEEK_SET - #error SEEK_SET != _PDCLIB_SEEK_SET -#endif - -extern FILE * stdin; -extern FILE * stdout; -extern FILE * stderr; - -/* Operations on files */ - -/* Remove the given file. - Returns zero if successful, non-zero otherwise. - This implementation does detect if a file of that name is currently open, - and fails the remove in this case. This does not detect two distinct names - that merely result in the same file (e.g. "/home/user/foo" vs. "~/foo"). -*/ -int remove( const char * filename ) _PDCLIB_nothrow; - -/* Rename the given old file to the given new name. - Returns zero if successful, non-zero otherwise. - This implementation does detect if the old filename corresponds to an open - file, and fails the rename in this case. - If there already is a file with the new filename, behaviour is defined by - the glue code (see functions/_PDCLIB/rename.c). -*/ -int rename( const char * old, const char * newn ) _PDCLIB_nothrow; - -/* Open a temporary file with mode "wb+", i.e. binary-update. Remove the file - automatically if it is closed or the program exits normally (by returning - from main() or calling exit()). - Returns a pointer to a FILE handle for this file. - This implementation does not remove temporary files if the process aborts - abnormally (e.g. abort()). -*/ -FILE * tmpfile( void ) _PDCLIB_nothrow; - -/* Generate a file name that is not equal to any existing filename AT THE TIME - OF GENERATION. Generate a different name each time it is called. - Returns a pointer to an internal static buffer containing the filename if s - is a NULL pointer. (This is not thread-safe!) - Returns s if it is not a NULL pointer (s is then assumed to point to an array - of at least L_tmpnam characters). - Returns NULL if unable to generate a suitable name (because all possible - names already exist, or the function has been called TMP_MAX times already). - Note that this implementation cannot guarantee a file of the name generated - is not generated between the call to this function and a subsequent fopen(). -*/ -char * tmpnam( char * s ) _PDCLIB_nothrow; - -/* File access functions */ - -/* Close the file associated with the given stream (after flushing its buffers). - Returns zero if successful, EOF if any errors occur. -*/ -int fclose( FILE * stream ) _PDCLIB_nothrow; - -/* Flush the buffers of the given output stream. If the stream is an input - stream, or an update stream with the last operation being an input operation, - behaviour is undefined. - If stream is a NULL pointer, perform the buffer flushing for all applicable - streams. - Returns zero if successful, EOF if a write error occurs. - Sets the error indicator of the stream if a write error occurs. -*/ -int fflush( FILE * stream ) _PDCLIB_nothrow; - -/* Open the file with the given filename in the given mode, and return a stream - handle for it in which error and end-of-file indicator are cleared. Defined - values for mode are: - - READ MODES - text files binary files - without update "r" "rb" - with update "r+" "rb+" or "r+b" - - Opening in read mode fails if no file with the given filename exists, or if - cannot be read. - - WRITE MODES - text files binary files - without update "w" "wb" - with update "w+" "wb+" or "w+b" - - With write modes, if a file with the given filename already exists, it is - truncated to zero length. - - APPEND MODES - text files binary files - without update "a" "ab" - with update "a+" "ab+" or "a+b" - - With update modes, if a file with the given filename already exists, it is - not truncated to zero length, but all writes are forced to end-of-file (this - regardless to fseek() calls). Note that binary files opened in append mode - might have their end-of-file padded with '\0' characters. - - Update modes mean that both input and output functions can be performed on - the stream, but output must be terminated with a call to either fflush(), - fseek(), fsetpos(), or rewind() before input is performed, and input must - be terminated with a call to either fseek(), fsetpos(), or rewind() before - output is performed, unless input encountered end-of-file. - - If a text file is opened with update mode, the implementation is at liberty - to open a binary stream instead. This implementation honors the exact mode - given. - - The stream is fully buffered if and only if it can be determined not to - refer to an interactive device. - - If the mode string begins with but is longer than one of the above sequences - the implementation is at liberty to ignore the additional characters, or do - implementation-defined things. This implementation only accepts the exact - modes above. - - Returns a pointer to the stream handle if successfull, NULL otherwise. -*/ -FILE * fopen( const char * _PDCLIB_restrict filename, - const char * _PDCLIB_restrict mode ) _PDCLIB_nothrow; - -/* Creates a stream connected to the file descriptor \p fd with mode \p mode. - Mode must match the mode with which the file descriptor was opened. -*/ -FILE * _PDCLIB_fvopen( _PDCLIB_fd_t fd, const _PDCLIB_fileops_t * ops, - int mode, const char * filename ) _PDCLIB_nothrow; - -/* Close any file currently associated with the given stream. Open the file - identified by the given filename with the given mode (equivalent to fopen()), - and associate it with the given stream. If filename is a NULL pointer, - attempt to change the mode of the given stream. - This implementation allows any mode changes on "real" files, and associating - of the standard streams with files. It does *not* support mode changes on - standard streams. - (Primary use of this function is to redirect stdin, stdout, and stderr.) -*/ -FILE * freopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode, FILE * _PDCLIB_restrict stream ) _PDCLIB_nothrow; - -/* If buf is a NULL pointer, call setvbuf( stream, NULL, _IONBF, BUFSIZ ). - If buf is not a NULL pointer, call setvbuf( stream, buf, _IOFBF, BUFSIZ ). -*/ -void setbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf ) _PDCLIB_nothrow; - -/* Set the given stream to the given buffering mode. If buf is not a NULL - pointer, use buf as file buffer (of given size). If buf is a NULL pointer, - use a buffer of given size allocated internally. _IONBF causes unbuffered - behaviour, _IOLBF causes line-buffered behaviour, _IOFBF causes fully - buffered behaviour. Calling this function is only valid right after a file is - opened, and before any other operation (except for any unsuccessful calls to - setvbuf()) has been performed. - Returns zero if successful, nonzero otherwise. -*/ -int setvbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf, int mode, size_t size ) _PDCLIB_nothrow; - -/* Formatted input/output functions */ - -/* - Write output to the given stream, as defined by the given format string and - 0..n subsequent arguments (the argument stack). - - The format string is written to the given stream verbatim, except for any - conversion specifiers included, which start with the letter '%' and are - documented below. If the given conversion specifiers require more arguments - from the argument stack than provided, behaviour is undefined. Additional - arguments not required by conversion specifiers are evaluated but otherwise - ignored. - - (The standard specifies the format string is allowed to contain multibyte - character sequences as long as it starts and ends in initial shift state, - but this is not yet supported by this implementation, which interprets the - format string as sequence of char.) - TODO: Add multibyte support to printf() functions. - - A conversion specifier consists of: - - Zero or more flags (one of the characters "-+ #0"). - - Optional minimum field width as decimal integer. Default is padding to the - left, using spaces. Note that 0 is taken as a flag, not the beginning of a - field width. Note also that a small field width will not result in the - truncation of a value. - - Optional precision (given as ".#" with # being a decimal integer), - specifying: - - the min. number of digits to appear (diouxX), - - the max. number of digits after the decimal point (aAeEfF), - - the max. number of significant digits (gG), - - the max. number of bytes to be written (s). - - behaviour with other conversion specifiers is undefined. - - Optional length modifier specifying the size of the argument (one of "hh", - "ll", or one of the characters "hljztL"). - - Conversion specifier character specifying the type of conversion to be - applied (and the type of the next argument from the argument stack). One - of the characters "diouxXfFeEgGaAcspn%". - - Minimum field width and/or precision may be given as asterisk ('*') instead - of a decimal integer. In this case, the next argument from the argument - stack is assumed to be an int value specifying the width / precision. A - negative field width is interpreted as flag '-' followed by a positive field - width. A negative precision is interpreted as if no precision was given. - - FLAGS - - Left-justify the conversion result within its field width. - + Prefix a '+' on positive signed conversion results. Prefix a '-' on - floating conversions resulting in negative zero, or negative values - rounding to zero. - space Prefix a space on positive signed conversion results, or if a signed - conversion results in no characters. If both '+' and ' ' are given, - ' ' is ignored. - # Use an "alternative form" for - - 'o' conversion, increasing precision until the first digit of the - result is a zero; - - 'x' or 'X' conversion, prefixing "0x" or "0X" to nonzero results; - - "aAeEfF" conversions, always printing a decimal point even if no - digits are following; - - 'g' or 'G' conversions, always printing a decimal point even if no - digits are following, and not removing trailing zeroes. - - behaviour for other conversions is unspecified. - 0 Use leading zeroes instead of spaces for field width padding. If both - '-' and '0' are given, '0' is ignored. If a precision is specified for - any of the "diouxX" conversions, '0' is ignored. Behaviour is only - defined for "diouxXaAeEfFgG". - - LENGTH MODIFIERS - hh For "diouxX" conversions, the argument from the argument stack is - assumed to be of char width. (It will have been subject to integer - promotion but will be converted back.) For 'n' conversions, the argument - is assumed to be a pointer to signed char. - h For "diouxX" conversions, the argument from the argument stack is - assumed to be of short int width. (It will have been subject to integer - promotion but will be converted back.) For 'n' conversions, the argument - is assumed to be a pointer to short int. - l For "diouxX" conversions, the argument from the argument stack is - assumed to be of long int width. For 'n' conversions, the argument is - assumed to be a pointer to short int. For 'c' conversions, the argument - is assumed to be a wint_t. For 's' conversions, the argument is assumed - to be a pointer to wchar_t. No effect on "aAeEfFgG" conversions. - ll For "diouxX" conversions, the argument from the argument stack is - assumed to be of long long int width. For 'n' conversions, the argument - is assumed to be a pointer to long long int. - j For "diouxX" conversions, the argument from the argument stack is - assumed to be of intmax_t width. For 'n' conversions, the argument is - assumed to be a pointer to intmax_t. - z For "diouxX" conversions, the argument from the argument stack is - assumed to be of size_t width. For 'n' conversions, the argument is - assumed to be a pointer to size_t. - t For "diouxX" conversions, the argument from the argument stack is - assumed to be of ptrdiff_t width. For 'n' conversions, the argument is - assumed to be a pointer to ptrdiff_t. - L For "aAeEfFgG" conversions, the argument from the argument stack is - assumed to be a long double. - Length modifiers appearing for any conversions not mentioned above will have - undefined behaviour. - If a length modifier appears with any conversion specifier other than as - specified above, the behavior is undefined. - - CONVERSION SPECIFIERS - d,i The argument from the argument stack is assumed to be of type int, and - is converted to a signed decimal value with a minimum number of digits - as specified by the precision (default 1), padded with leading zeroes. - A zero value converted with precision zero yields no output. - o The argument from the argument stack is assumed to be of type unsigned - int, and is converted to an unsigned octal value, other behaviour being - as above. - u The argument from the argument stack is assumed to be of type unsigned - int, and converted to an unsigned decimal value, other behaviour being - as above. - x,X The argument from the argument stack is assumed to be of type unsigned - int, and converted to an unsigned hexadecimal value, using lowercase - "abcdef" for 'x' and uppercase "ABCDEF" for 'X' conversion, other - behaviour being as above. - f,F The argument from the argument stack is assumed to be of type double, - and converted to a decimal floating point in decimal-point notation, - with the number of digits after the decimal point as specified by the - precision (default 6) and the value being rounded appropriately. If - precision is zero (and the '#' flag is not given), no decimal point is - printed. At least one digit is always printed before the decimal point. - For 'f' conversions, an infinity value is printed as either [-]inf or - [-]infinity (, depending on the configuration of this implementation. A - NaN value is printed as [-]nan. For 'F' conversions uppercase characters - are used for these special values. The flags '-', '+' and ' ' apply as - usual to these special values, '#' and '0' have no effect. - e,E The argument from the argument stack is assumed to be of type double, - and converted to a decimal floating point in normalized exponential - notation ([?]d.ddd edd). "Normalized" means one nonzero digit before - the decimal point, unless the value is zero. The number of digits after - the decimal point is specified by the precision (default 6), the value - being rounded appropriately. If precision is zero (and the '#' flag is - not given), no decimal point is printed. The exponent has at least two - digits, and not more than necessary to represent the exponent. If the - value is zero, the exponent is zero. The 'e' written to indicate the - exponend is uppercase for 'E' conversions. - Infinity or NaN values are represented as for 'f' and 'F' conversions, - respectively. - g,G The argument from the argument stack is assumed to be of type double, - and converted according to either 'f' or 'e' format for 'g' conversions, - or 'F' or 'E' format for 'G' conversions, respectively, with the actual - conversion chosen depending on the value. 'e' / 'E' conversion is chosen - if the resulting exponent is < -4 or >= the precision (default 1). - Trailing zeroes are removed (unless the '#' flag is given). A decimal - point appears only if followed by a digit. - Infinity or NaN values are represented as for 'f' and 'F' conversions, - respectively. - a,A The argument from the argument stack is assumed to be of type double, - and converted to a floating point hexadecimal notation ([?]0xh.hhhh pd) - with one hexadecimal digit (being nonzero if the value is normalized, - and otherwise unspecified) before the decimal point, and the number of - digits after the decimal point being specified by the precision. If no - precision is given, the default is to print as many digits as nevessary - to give an exact representation of the value (if FLT_RADIX is a power of - 2). If no precision is given and FLT_RADIX is not a power of 2, the - default is to print as many digits to distinguish values of type double - (possibly omitting trailing zeroes). (A precision p is sufficient to - distinguish values of the source type if 16^p-1 > b^n where b is - FLT_RADIX and n is the number of digits in the significand (to base b) - of the source type. A smaller p might suffice depending on the - implementation's scheme for determining the digit to the left of the - decimal point.) The error has the correct sign for the current rounding - direction. - Unless the '#' flag is given, no decimal-point is given for zero - precision. - The 'a' conversion uses lowercase "abcdef", "0x" and 'p', the 'A' - conversion uppercase "ABCDEF", "0X" and 'P'. - The exponent always has at least one digit, and not more than necessary - to represent the decimal exponent of 2. If the value is zero, the - exponent is zero. - Infinity or NaN values are represented as for 'f' and 'F' conversions, - respectively. - Binary implementations are at liberty to chose the hexadecimal digit to - the left of the decimal point so that subsequent digits align to nibble - boundaries. - c The argument from the argument stack is assumed to be of type int, and - converted to a character after the value has been cast to unsigned char. - If the 'l' length modifier is given, the argument is assumed to be of - type wint_t, and converted as by a "%ls" conversion with no precision - and a pointer to a two-element wchar_t array, with the first element - being the wint_t argument and the second a '\0' wide character. - s The argument from the argument stack is assumed to be a char array (i.e. - pointer to char). Characters from that array are printed until a zero - byte is encountered or as many bytes as specified by a given precision - have been written. - If the l length modifier is given, the argument from the argument stack - is assumed to be a wchar_t array (i.e. pointer to wchar_t). Wide - characters from that array are converted to multibyte characters as by - calls to wcrtomb() (using a mbstate_t object initialized to zero prior - to the first conversion), up to and including the terminating null wide - character. The resulting multibyte character sequence is then printed up - to but not including the terminating null character. If a precision is - given, it specifies the maximum number of bytes to be written (including - shift sequences). If the given precision would require access to a wide - character one past the end of the array, the array shall contain a '\0' - wide character. In no case is a partial multibyte character written. - Redundant shift sequences may result if the multibyte characters have a - state-dependent encoding. - TODO: Clarify these statements regarding %ls. - p The argument from the argument stack is assumed to be a void pointer, - and converted to a sequence of printing characters in an implementation- - defined manner. - This implementation casts the pointer to type intptr_t, and prints the - value as if a %#x conversion specifier was given. - n The argument from the argument stack is assumed to be a pointer to a - signed integer, into which the number of characters written so far by - this call to fprintf is stored. The behaviour, should any flags, field - widths, or precisions be given is undefined. - % A verbatim '%' character is written. No argument is taken from the - argument stack. - - Returns the number of characters written if successful, a negative value - otherwise. -*/ -int fprintf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow; - -/* TODO: fscanf() documentation */ -/* - Read input from a given stream, as defined by the given format string, and - store converted input in the objects pointed to by 0..n subsequent arguments - (the argument stack). - - The format string contains a sequence of directives that are expected to - match the input. If such a directive fails to match, the function returns - (matching error). It also returns if an input error occurs (input error). - - Directives can be: - - one or more whitespaces, matching any number of whitespaces in the input; - - printing characters, matching the input verbatim; - - conversion specifications, which convert an input sequence into a value as - defined by the individual specifier, and store that value in a memory - location pointed to by the next pointer on the argument stack. Details are - documented below. If there is an insufficient number of pointers on the - argument stack, behaviour is undefined. Additional arguments not required - by any conversion specifications are evaluated, but otherwise ignored. - - (The standard specifies the format string is allowed to contain multibyte - character sequences as long as it starts and ends in initial shift state, - but this is not yet supported by this implementation, which interprets the - format string as sequence of char.) - TODO: Add multibyte support to scanf() functions. - - A conversion specifier consists of: - - Optional assignment-suppressing character ('*') that makes the conversion - read input as usual, but does not assign the conversion result. - - Optional maximum field width as decimal integer. - - Optional length modifier specifying the size of the argument (one of "hh", - "ll", or one of the characters "hljztL"). - - Conversion specifier character specifying the type of conversion to be - applied (and the type of the next argument from the argument stack). One - of the characters "diouxXaAeEfFgGcs[pn%". - - LENGTH MODIFIERS - hh For "diouxXn" conversions, the next pointer from the argument stack is - assumed to point to a variable of of char width. - h For "diouxXn" conversions, the next pointer from the argument stack is - assumed to point to a variable of short int width. - l For "diouxXn" conversions, the next pointer from the argument stack is - assumed to point to a variable of long int width. - For "aAeEfFgG" conversions, it is assumed to point to a variable of type - double. - For "cs[" conversions, it is assumed to point to a variable of type - wchar_t. - ll For "diouxXn" conversions, the next pointer from the argument stack is - assumed to point to a variable of long long int width. - j For "diouxXn" conversions, the next pointer from the argument stack is - assumed to point to a variable of intmax_t width. - z For "diouxXn" conversions, the next pointer from the argument stack is - assumed to point to a variable of size_t width. - t For "diouxXn" conversions, the next pointer from the argument stack is - assumed to point to a variable of ptrdiff_t width. - L For "aAeEfFgG" conversions, the next pointer from the argument stack is - assumed to point to a variable of type long double. - Length modifiers appearing for any conversions not mentioned above will have - undefined behaviour. - If a length modifier appears with any conversion specifier other than as - specified above, the behavior is undefined. - - CONVERSION SPECIFIERS - d Matches an (optionally signed) decimal integer of the format expected - by strtol() with base 10. The next pointer from the argument stack is - assumed to point to a signed integer. - i Matches an (optionally signed) integer of the format expected by - strtol() with base 0. The next pointer from the argument stack is - assumed to point to a signed integer. - o Matches an (optionally signed) octal integer of the format expected by - strtoul() with base 8. The next pointer from the argument stack is - assumed to point to an unsigned integer. - u Matches an (optionally signed) decimal integer of the format expected - by strtoul() with base 10. The next pointer from the argument stack is - assumed to point to an unsigned integer. - x Matches an (optionally signed) hexadecimal integer of the format - expected by strtoul() with base 16. The next pointer from the argument - stack is assumed to point to an unsigned integer. - aefg Matches an (optionally signed) floating point number, infinity, or not- - a-number-value of the format expected by strtod(). The next pointer - from the argument stack is assumed to point to a float. - c Matches a number of characters as specified by the field width (default - 1). The next pointer from the argument stack is assumed to point to a - character array large enough to hold that many characters. - If the 'l' length modifier is given, the input is assumed to match a - sequence of multibyte characters (starting in the initial shift state), - which will be converted to a wide character sequence as by successive - calls to mbrtowc() with a mbstate_t object initialized to zero prior to - the first conversion. The next pointer from the argument stack is - assumed to point to a wchar_t array large enough to hold that many - characters. - In either case, note that no '\0' character is added to terminate the - sequence. - s Matches a sequence of non-white-space characters. The next pointer from - the argument stack is assumed to point to a character array large - enough to hold the sequence including terminating '\0' character. - If the 'l' length modifier is given, the input is assumed to match a - sequence of multibyte characters (starting in the initial shift state), - which will be converted to a wide character sequence as by a call to - mbrtowc() with a mbstate_t object initialized to zero prior to the - first conversion. The next pointer from the argument stack is assumed - to point to a wchar_t array large enough to hold the sequence including - terminating '\0' character. - [ Matches a nonempty sequence consisting of any of those characters - specified between itself and a corresponding closing bracket (']'). - If the first character in the list is a circumflex ('^'), this matches - a nonempty sequence consisting of any characters NOT specified. If the - closing bracket appears as the first character in the scanset ("[]" or - "[^]", it is assumed to belong to the scanset, which then ends with the - NEXT closing bracket. - If there is a '-' character in the scanset which is not the first after - the opening bracket (or the circumflex, see above) or the last in the - scanset, behaviour is implementation-defined. This implementation - handles this character like any other. - - The extend of the input field is determined byte-by-byte for the above - conversions ('c', 's', '['), with no special provisions being made for - multibyte characters. The resulting field is nevertheless a multibyte - sequence begining in intial shift state. - - p Matches a sequence of characters as produced by the printf() "%p" - conversion. The next pointer from the argument stack is assumed to - point to a void pointer, which will be filled with the same location - as the pointer used in the printf() statement. Note that behaviour is - undefined if the input value is not the result of an earlier printf() - call. - n Does not read input. The next pointer from the argument stack is - assumed to point to a signed integer, into which the number of - characters read from input so far by this call to fscanf() is stored. - This does not affect the return value of fscanf(). The behaviour, - should an assignment-supressing character of field width be given, - is undefined. - This can be used to test the success of literal matches and suppressed - assignments. - % Matches a single, verbatim '%' character. - - A, E, F, G and X are valid, and equivalent to their lowercase counterparts. - - All conversions except [, c, or n imply that whitespace characters from the - input stream are consumed until a non-whitespace character is encountered. - Such whitespaces do not count against a maximum field width. - - Conversions push at most one character back into the input stream. That - implies that some character sequences converted by the strtol() and strtod() - function families are not converted identically by the scnaf() function - family. - - Returns the number of input items successfully assigned. This can be zero if - an early mismatch occurs. Returns EOF if an input failure occurs before the - first conversion. -*/ -int fscanf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow; - -/* Equivalent to fprintf( stdout, format, ... ). */ -int printf( const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow; - -/* Equivalent to fscanf( stdin, format, ... ). */ -int scanf( const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow; - -/* Equivalent to fprintf( stdout, format, ... ), except that the result is - written into the buffer pointed to by s, instead of stdout, and that any - characters beyond the (n-1)th are discarded. The (n)th character is - replaced by a '\0' character in this case. - Returns the number of characters that would have been written (not counting - the terminating '\0' character) if n had been sufficiently large, if - successful, and a negative number if an encoding error ocurred. -*/ -int snprintf( char * _PDCLIB_restrict s, size_t n, const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow; - -/* Equivalent to fprintf( stdout, format, ... ), except that the result is - written into the buffer pointed to by s, instead of stdout. -*/ -int sprintf( char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow; - -/* Equivalent to fscanf( stdin, format, ... ), except that the input is read - from the buffer pointed to by s, instead of stdin. -*/ -int sscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow; - -/* Equivalent to fprintf( stream, format, ... ), except that the argument stack - is passed as va_list parameter. Note that va_list is not declared by - . -*/ -int vfprintf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow; - -/* Equivalent to fscanf( stream, format, ... ), except that the argument stack - is passed as va_list parameter. Note that va_list is not declared by - . -*/ -int vfscanf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow; - -/* Equivalent to fprintf( stdout, format, ... ), except that the argument stack - is passed as va_list parameter. Note that va_list is not declared by - . -*/ -int vprintf( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow; - -/* Equivalent to fscanf( stdin, format, ... ), except that the argument stack - is passed as va_list parameter. Note that va_list is not declared by - . -*/ -int vscanf( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow; - -/* Equivalent to snprintf( s, n, format, ... ), except that the argument stack - is passed as va_list parameter. Note that va_list is not declared by - . - */ -int vsnprintf( char * _PDCLIB_restrict s, size_t n, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow; - -/* Equivalent to fprintf( stdout, format, ... ), except that the argument stack - is passed as va_list parameter, and the result is written to the buffer - pointed to by s, instead of stdout. Note that va_list is not declared by - . -*/ -int vsprintf( char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow; - -/* Equivalent to fscanf( stdin, format, ... ), except that the argument stack - is passed as va_list parameter, and the input is read from the buffer - pointed to by s, instead of stdin. Note that va_list is not declared by - . -*/ -int vsscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow; - -int asprintf(char **strp, const char * _PDCLIB_restrict fmt, ...) _PDCLIB_nothrow; -int vasprintf(char **strp, const char * _PDCLIB_restrict fmt, _PDCLIB_va_list arg) _PDCLIB_nothrow; - -/* Character input/output functions */ - -/* Retrieve the next character from given stream. - Returns the character, EOF otherwise. - If end-of-file is reached, the EOF indicator of the stream is set. - If a read error occurs, the error indicator of the stream is set. -*/ -int fgetc( FILE * stream ) _PDCLIB_nothrow; - -/* Read at most n-1 characters from given stream into the array s, stopping at - \n or EOF. Terminate the read string with \n. If EOF is encountered before - any characters are read, leave the contents of s unchanged. - Returns s if successful, NULL otherwise. - If a read error occurs, the error indicator of the stream is set. In this - case, the contents of s are indeterminate. -*/ -char * fgets( char * _PDCLIB_restrict s, int n, FILE * _PDCLIB_restrict stream ) _PDCLIB_nothrow; - -/* Write the value c (cast to unsigned char) to the given stream. - Returns c if successful, EOF otherwise. - If a write error occurs, sets the error indicator of the stream is set. -*/ -int fputc( int c, FILE * stream ) _PDCLIB_nothrow; - -/* Write the string s (not including the terminating \0) to the given stream. - Returns a value >=0 if successful, EOF otherwise. - This implementation does set the error indicator of the stream if a write - error occurs. -*/ -int fputs( const char * _PDCLIB_restrict s, FILE * _PDCLIB_restrict stream ) _PDCLIB_nothrow; - -/* Equivalent to fgetc( stream ), but may be overloaded by a macro that - evaluates its parameter more than once. -*/ -int getc( FILE * stream ) _PDCLIB_nothrow; - -/* Equivalent to fgetc( stdin ). */ -int getchar( void ) _PDCLIB_nothrow; - -#if _PDCLIB_C_MAX(1999) -/* Read characters from given stream into the array s, stopping at \n or EOF. - The string read is terminated with \0. Returns s if successful. If EOF is - encountered before any characters are read, the contents of s are unchanged, - and NULL is returned. If a read error occurs, the contents of s are indeter- - minate, and NULL is returned. - - This function is dangerous and has been a great source of security - vulnerabilities. Do not use it. It was removed by C11. -*/ -char * gets( char * s ) _PDCLIB_DEPRECATED _PDCLIB_nothrow; -#endif - -/* Equivalent to fputc( c, stream ), but may be overloaded by a macro that - evaluates its parameter more than once. -*/ -int putc( int c, FILE * stream ) _PDCLIB_nothrow; - -/* Equivalent to fputc( c, stdout ), but may be overloaded by a macro that - evaluates its parameter more than once. -*/ -int putchar( int c ) _PDCLIB_nothrow; - -/* Write the string s (not including the terminating \0) to stdout, and append - a newline to the output. Returns a value >= 0 when successful, EOF if a - write error occurred. -*/ -int puts( const char * s ) _PDCLIB_nothrow; - -/* Push the value c (cast to unsigned char) back onto the given (input) stream. - A character pushed back in this way will be delivered by subsequent read - operations (and skipped by subsequent file positioning operations) as if it - has not been read. The external representation of the stream is unaffected - by this pushback (it is a buffer operation). One character of pushback is - guaranteed, further pushbacks may fail. EOF as value for c does not change - the input stream and results in failure of the function. - For text files, the file position indicator is indeterminate until all - pushed-back characters are read. For binary files, the file position - indicator is decremented by each successful call of ungetc(). If the file - position indicator for a binary file was zero before the call of ungetc(), - behaviour is undefined. (Older versions of the library allowed such a call.) - Returns the pushed-back character if successful, EOF if it fails. -*/ -int ungetc( int c, FILE * stream ) _PDCLIB_nothrow; - -/* Direct input/output functions */ - -/* Read up to nmemb elements of given size from given stream into the buffer - pointed to by ptr. Returns the number of elements successfully read, which - may be less than nmemb if a read error or EOF is encountered. If a read - error is encountered, the value of the file position indicator is - indeterminate. If a partial element is read, its value is indeterminate. - If size or nmemb are zero, the function does nothing and returns zero. -*/ -size_t fread( void * _PDCLIB_restrict ptr, size_t size, size_t nmemb, FILE * _PDCLIB_restrict stream ) _PDCLIB_nothrow; - -/* Write up to nmemb elements of given size from buffer pointed to by ptr to - the given stream. Returns the number of elements successfully written, which - will be less than nmemb only if a write error is encountered. If a write - error is encountered, the value of the file position indicator is - indeterminate. If size or nmemb are zero, the function does nothing and - returns zero. -*/ -size_t fwrite( const void * _PDCLIB_restrict ptr, size_t size, size_t nmemb, FILE * _PDCLIB_restrict stream ) _PDCLIB_nothrow; - -/* File positioning functions */ - -/* Store the current position indicator (and, where appropriate, the current - mbstate_t status object) for the given stream into the given pos object. The - actual contents of the object are unspecified, but it can be used as second - parameter to fsetpos() to reposition the stream to the exact position and - parse state at the time fgetpos() was called. - Returns zero if successful, nonzero otherwise. - TODO: Implementation-defined errno setting for fgetpos(). -*/ -int fgetpos( FILE * _PDCLIB_restrict stream, fpos_t * _PDCLIB_restrict pos ) _PDCLIB_nothrow; - -/* Set the position indicator for the given stream to the given offset from: - - the beginning of the file if whence is SEEK_SET, - - the current value of the position indicator if whence is SEEK_CUR, - - end-of-file if whence is SEEK_END. - On text streams, non-zero offsets are only allowed with SEEK_SET, and must - have been returned by ftell() for the same file. - Any characters buffered by ungetc() are dropped, the end-of-file indicator - for the stream is cleared. If the given stream is an update stream, the next - operation after a successful fseek() may be either input or output. - Returns zero if successful, nonzero otherwise. If a read/write error occurs, - the error indicator for the given stream is set. -*/ -int fseek( FILE * stream, long int offset, int whence ) _PDCLIB_nothrow; - -/* Set the position indicator (and, where appropriate the mbstate_t status - object) for the given stream to the given pos object (created by an earlier - call to fgetpos() on the same file). - Any characters buffered by ungetc() are dropped, the end-of-file indicator - for the stream is cleared. If the given stream is an update stream, the next - operation after a successful fsetpos() may be either input or output. - Returns zero if successful, nonzero otherwise. If a read/write error occurs, - the error indicator for the given stream is set. - TODO: Implementation-defined errno setting for fsetpos(). -*/ -int fsetpos( FILE * stream, const fpos_t * pos ) _PDCLIB_nothrow; - -/* Return the current offset of the given stream from the beginning of the - associated file. For text streams, the exact value returned is unspecified - (and may not be equal to the number of characters), but may be used in - subsequent calls to fseek(). - Returns -1L if unsuccessful. - TODO: Implementation-defined errno setting for ftell(). -*/ -long int ftell( FILE * stream ) _PDCLIB_nothrow; - -/* Equivalent to (void)fseek( stream, 0L, SEEK_SET ), except that the error - indicator for the stream is also cleared. -*/ -void rewind( FILE * stream ) _PDCLIB_nothrow; - -/* Error-handling functions */ - -/* Clear the end-of-file and error indicators for the given stream. */ -void clearerr( FILE * stream ) _PDCLIB_nothrow; - -/* Return zero if the end-of-file indicator for the given stream is not set, - nonzero otherwise. -*/ -int feof( FILE * stream ) _PDCLIB_nothrow; - -/* Return zero if the error indicator for the given stream is not set, nonzero - otherwise. -*/ -int ferror( FILE * stream ) _PDCLIB_nothrow; - -/* If s is neither a NULL pointer nor an empty string, print the string to - stderr (with appended colon (':') and a space) first. In any case, print an - error message depending on the current value of errno (being the same as if - strerror( errno ) had been called). -*/ -void perror( const char * s ) _PDCLIB_nothrow; - -/* Unlocked I/O - * - * Since threading was introduced in C11, FILE objects have had implicit locks - * to prevent data races and inconsistent output. - * - * PDCLib provides these functions from POSIX as an extension in order to enable - * users to access the underlying unlocked functions. - * - * For each function defined in C11 where an _unlocked variant is defined below, - * the behaviour of the _unlocked variant is the same except that it will not - * take the lock associated with the stream. - * - * flockfile, ftrylockfile and funlockfile can be used to manually manipulate - * the stream locks. The behaviour of the _unlocked functions if called when the - * stream isn't locked by the calling thread is implementation defined. - */ -#if _PDCLIB_POSIX_MIN(200112L) || _PDCLIB_BSD_SOURCE || _PDCLIB_SVID_SOURCE -void flockfile(FILE *file) _PDCLIB_nothrow; -int ftrylockfile(FILE *file) _PDCLIB_nothrow; -void funlockfile(FILE *file) _PDCLIB_nothrow; - -int getc_unlocked(FILE *stream) _PDCLIB_nothrow; -int getchar_unlocked(void) _PDCLIB_nothrow; -int putc_unlocked(int c, FILE *stream) _PDCLIB_nothrow; -int putchar_unlocked(int c) _PDCLIB_nothrow; -#endif - -#if _PDCLIB_BSD_SOURCE || _PDCLIB_SVID_SOURCE -void clearerr_unlocked(FILE *stream) _PDCLIB_nothrow; -int feof_unlocked(FILE *stream) _PDCLIB_nothrow; -int ferror_unlocked(FILE *stream) _PDCLIB_nothrow; -int fflush_unlocked(FILE *stream) _PDCLIB_nothrow; -int fgetc_unlocked(FILE *stream) _PDCLIB_nothrow; -int fputc_unlocked(int c, FILE *stream) _PDCLIB_nothrow; -size_t fread_unlocked(void *ptr, size_t size, size_t n, FILE *stream) _PDCLIB_nothrow; -size_t fwrite_unlocked(const void *ptr, size_t size, size_t n, FILE *stream) _PDCLIB_nothrow; -#endif - -#if _PDCLIB_GNU_SOURCE -char *fgets_unlocked(char *s, int n, FILE *stream) _PDCLIB_nothrow; -int fputs_unlocked(const char *s, FILE *stream) _PDCLIB_nothrow; -#endif - -#if _PDCLIB_EXTENSIONS -int _vcbprintf( - void *p, - _PDCLIB_size_t ( *cb ) ( void *p, const char *buf, _PDCLIB_size_t size ), - const char *format, - _PDCLIB_va_list arg ); - -int _cbprintf( - void *p, - size_t ( *cb ) ( void *p, const char *buf, size_t size ), - const char *format, - ... ); - -int fgetpos_unlocked( FILE * _PDCLIB_restrict stream, fpos_t * _PDCLIB_restrict pos ) _PDCLIB_nothrow; -int fsetpos_unlocked( FILE * stream, const fpos_t * pos ) _PDCLIB_nothrow; -long int ftell_unlocked( FILE * stream ) _PDCLIB_nothrow; -int fseek_unlocked( FILE * stream, long int offset, int whence ) _PDCLIB_nothrow; -void rewind_unlocked( FILE * stream ) _PDCLIB_nothrow; - -int puts_unlocked( const char * s ) _PDCLIB_nothrow; -int ungetc_unlocked( int c, FILE * stream ) _PDCLIB_nothrow; - -int printf_unlocked( const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow; -int vprintf_unlocked( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow; -int fprintf_unlocked( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow; -int vfprintf_unlocked( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow; -int scanf_unlocked( const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow; -int vscanf_unlocked( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow; -int fscanf_unlocked( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow; -int vfscanf_unlocked( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow; - -// Todo: remove prefix? -_PDCLIB_uint_fast64_t _PDCLIB_ftell64( FILE * stream ) _PDCLIB_nothrow; -_PDCLIB_uint_fast64_t _PDCLIB_ftell64_unlocked( FILE * stream ) _PDCLIB_nothrow; -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/waterbox/libc/includes/stdlib.h b/waterbox/libc/includes/stdlib.h deleted file mode 100644 index b3a92bd461..0000000000 --- a/waterbox/libc/includes/stdlib.h +++ /dev/null @@ -1,351 +0,0 @@ -/* General utilities - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_STDLIB_H -#define _PDCLIB_STDLIB_H _PDCLIB_STDLIB_H -#include "_PDCLIB_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _PDCLIB_SIZE_T_DEFINED -#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED -typedef _PDCLIB_size_t size_t; -#endif - -#ifndef _PDCLIB_NULL_DEFINED -#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED -#define NULL _PDCLIB_NULL -#endif - -#ifndef __cplusplus - -#ifndef _PDCLIB_WCHAR_T_DEFINED -#define _PDCLIB_WCHAR_T_DEFINED _PDCLIB_WCHAR_T_DEFINED -typedef _PDCLIB_wchar_t wchar_t; -#endif - -#endif - -#ifndef _PDCLIB_MB_CUR_MAX_DEFINED -#define _PDCLIB_MB_CUR_MAX_DEFINED -#define MB_CUR_MAX (_PDCLIB_mb_cur_max()) -#endif - -/* Numeric conversion functions */ - -/* TODO: atof(), strtof(), strtod(), strtold() */ - -double atof( const char * nptr ) _PDCLIB_nothrow; -double strtod( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr ) _PDCLIB_nothrow; -float strtof( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr ) _PDCLIB_nothrow; -long double strtold( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr ) _PDCLIB_nothrow; - -/* Seperate the character array nptr into three parts: A (possibly empty) - sequence of whitespace characters, a character representation of an integer - to the given base, and trailing invalid characters (including the terminating - null character). If base is 0, assume it to be 10, unless the integer - representation starts with 0x / 0X (setting base to 16) or 0 (setting base to - 8). If given, base can be anything from 0 to 36, using the 26 letters of the - base alphabet (both lowercase and uppercase) as digits 10 through 35. - The integer representation is then converted into the return type of the - function. It can start with a '+' or '-' sign. If the sign is '-', the result - of the conversion is negated. - If the conversion is successful, the converted value is returned. If endptr - is not a NULL pointer, a pointer to the first trailing invalid character is - returned in *endptr. - If no conversion could be performed, zero is returned (and nptr in *endptr, - if endptr is not a NULL pointer). If the converted value does not fit into - the return type, the functions return LONG_MIN, LONG_MAX, ULONG_MAX, - LLONG_MIN, LLONG_MAX, or ULLONG_MAX respectively, depending on the sign of - the integer representation and the return type, and errno is set to ERANGE. -*/ -/* There is strtoimax() and strtoumax() in operating on intmax_t / - uintmax_t, if the long long versions do not suit your needs. -*/ -long int strtol( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr, int base ) _PDCLIB_nothrow; -long long int strtoll( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr, int base ) _PDCLIB_nothrow; -unsigned long int strtoul( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr, int base ) _PDCLIB_nothrow; -unsigned long long int strtoull( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr, int base ) _PDCLIB_nothrow; - -/* These functions are the equivalent of (int)strtol( nptr, NULL, 10 ), - strtol( nptr, NULL, 10 ) and strtoll(nptr, NULL, 10 ) respectively, with the - exception that they do not have to handle overflow situations in any defined - way. - (PDCLib does not simply forward these to their strtox() equivalents, but - provides a simpler atox() function that saves a couple of tests and simply - continues with the conversion in case of overflow.) -*/ -int atoi( const char * nptr ) _PDCLIB_nothrow; -long int atol( const char * nptr ) _PDCLIB_nothrow; -long long int atoll( const char * nptr ) _PDCLIB_nothrow; - -/* Pseudo-random sequence generation functions */ - -extern unsigned long int _PDCLIB_seed; - -#define RAND_MAX 32767 - -/* Returns the next number in a pseudo-random sequence, which is between 0 and - RAND_MAX. - (PDCLib uses the implementation suggested by the standard document, which is - next = next * 1103515245 + 12345; return (unsigned int)(next/65536) % 32768;) -*/ -int rand( void ) _PDCLIB_nothrow; - -/* Initialize a new pseudo-random sequence with the starting seed. Same seeds - result in the same pseudo-random sequence. The default seed is 1. -*/ -void srand( unsigned int seed ) _PDCLIB_nothrow; - -/* Memory management functions */ - -/* Allocate a chunk of memory of given size. If request could not be - satisfied, return NULL. Otherwise, return a pointer to the allocated - memory. Memory contents are undefined. -*/ -void * malloc( size_t size ) _PDCLIB_nothrow; - -/* Allocate a chunk of memory that is large enough to hold nmemb elements of - the given size, and zero-initialize that memory. If request could not be - satisfied, return NULL. Otherwise, return a pointer to the allocated - memory. -*/ -void * calloc( size_t nmemb, size_t size ) _PDCLIB_nothrow; - -/* Allocate a chunk of memory of given size, with specified alignment (which - must be a power of two; if it is not, the next greater power of two is - used). If request could not be satisfied, return NULL. Otherwise, return - a pointer to the allocated memory. -*/ -void * aligned_alloc( size_t alignment, size_t size ) _PDCLIB_nothrow; - -/* De-allocate a chunk of heap memory previously allocated using malloc(), - calloc(), or realloc(), and pointed to by ptr. If ptr does not match a - pointer previously returned by the mentioned allocation functions, or - free() has already been called for this ptr, behaviour is undefined. -*/ -void free( void * ptr ) _PDCLIB_nothrow; - -/* Resize a chunk of memory previously allocated with malloc() and pointed to - by ptr to the given size (which might be larger or smaller than the original - size). Returns a pointer to the reallocated memory, or NULL if the request - could not be satisfied. Note that the resizing might include a memcpy() - from the original location to a different one, so the return value might or - might not equal ptr. If size is larger than the original size, the value of - memory beyond the original size is undefined. If ptr is NULL, realloc() - behaves like malloc(). -*/ -void * realloc( void * ptr, size_t size ) _PDCLIB_nothrow; - -/* Communication with the environment */ - -/* These two can be passed to exit() or _Exit() as status values, to signal - successful and unsuccessful program termination, respectively. EXIT_SUCCESS - can be replaced by 0. How successful or unsuccessful program termination are - signaled to the environment, and what happens if exit() or _Exit() are being - called with a value that is neither of the three, is defined by the hosting - OS and its glue function. -*/ -#define EXIT_SUCCESS _PDCLIB_SUCCESS -#define EXIT_FAILURE _PDCLIB_FAILURE - -/* Initiate abnormal process termination, unless programm catches SIGABRT and - does not return from the signal handler. - This implementantion flushes all streams, closes all files, and removes any - temporary files before exiting with EXIT_FAILURE. - abort() does not return. -*/ -_PDCLIB_noreturn void abort( void ) _PDCLIB_nothrow; - -/* Register a function that will be called on exit(), or when main() returns. - At least 32 functions can be registered this way, and will be called in - reverse order of registration (last-in, first-out). - Returns zero if registration is successfull, nonzero if it failed. -*/ -int atexit( void (*func)( void ) ) _PDCLIB_nothrow; - -/* Register a function that will be called on quick_exit(), or when main() returns. - At least 32 functions can be registered this way, and will be called in - reverse order of registration (last-in, first-out). - Returns zero if registration is successfull, nonzero if it failed. -*/ -int at_quick_exit( void (*func)( void ) ) _PDCLIB_nothrow; - -/* Normal process termination. Functions registered by atexit() (see above) are - called, streams flushed, files closed and temporary files removed before the - program is terminated with the given status. (See comment for EXIT_SUCCESS - and EXIT_FAILURE above.) - exit() does not return. -*/ -_PDCLIB_noreturn void exit( int status ) _PDCLIB_nothrow; - -/* Normal process termination. Functions registered by atexit() (see above) are - NOT CALLED. This implementation DOES flush streams, close files and removes - temporary files before the program is teminated with the given status. (See - comment for EXIT_SUCCESS and EXIT_FAILURE above.) - _Exit() does not return. -*/ -_PDCLIB_noreturn void _Exit( int status ) _PDCLIB_nothrow; - -/* Quick process termination. Functions registered by at_quick_exit() (see - above) are called, and the process terminated. No functions registered - with atexit() (see above) or signal handlers are called. - quick_exit() does not return. -*/ -_PDCLIB_noreturn void quick_exit( int status ); - -/* Search an environment-provided key-value map for the given key name, and - return a pointer to the associated value string (or NULL if key name cannot - be found). The value string pointed to might be overwritten by a subsequent - call to getenv(). The library never calls getenv() itself. - Details on the provided keys and how to set / change them are determined by - the hosting OS and its glue function. -*/ -char * getenv( const char * name ) _PDCLIB_nothrow; - -/* If string is a NULL pointer, system() returns nonzero if a command processor - is available, and zero otherwise. If string is not a NULL pointer, it is - passed to the command processor. If system() returns, it does so with a - value that is determined by the hosting OS and its glue function. -*/ -int system( const char * string ) _PDCLIB_nothrow; - -/* Searching and sorting */ - -/* Do a binary search for a given key in the array with a given base pointer, - which consists of nmemb elements that are of the given size each. To compare - the given key with an element from the array, the given function compar is - called (with key as first parameter and a pointer to the array member as - second parameter); the function should return a value less than, equal to, - or greater than 0 if the key is considered to be less than, equal to, or - greater than the array element, respectively. - The function returns a pointer to the first matching element found, or NULL - if no match is found. - - ** May throw ** -*/ -void * bsearch( const void * key, const void * base, size_t nmemb, size_t size, int (*compar)( const void *, const void * ) ); - -/* Do a quicksort on an array with a given base pointer, which consists of - nmemb elements that are of the given size each. To compare two elements from - the array, the given function compar is called, which should return a value - less than, equal to, or greater than 0 if the first argument is considered - to be less than, equal to, or greater than the second argument, respectively. - If two elements are compared equal, their order in the sorted array is not - specified. - - ** May throw ** -*/ -void qsort( void * base, size_t nmemb, size_t size, int (*compar)( const void *, const void * ) ); - -/* Integer arithmetic functions */ - -/* Return the absolute value of the argument. Note that on machines using two- - complement's notation (most modern CPUs), the largest negative value cannot - be represented as positive value. In this case, behaviour is unspecified. -*/ -int abs( int j ) _PDCLIB_nothrow; -long int labs( long int j ) _PDCLIB_nothrow; -long long int llabs( long long int j ) _PDCLIB_nothrow; - -/* These structures each have a member quot and a member rem, of type int (for - div_t), long int (for ldiv_t) and long long it (for lldiv_t) respectively. - The order of the members is platform-defined to allow the div() functions - below to be implemented efficiently. -*/ -typedef struct _PDCLIB_div_t div_t; -typedef struct _PDCLIB_ldiv_t ldiv_t; -typedef struct _PDCLIB_lldiv_t lldiv_t; - -/* Return quotient (quot) and remainder (rem) of an integer division in one of - the structs above. -*/ -div_t div( int numer, int denom ) _PDCLIB_nothrow; -ldiv_t ldiv( long int numer, long int denom ) _PDCLIB_nothrow; -lldiv_t lldiv( long long int numer, long long int denom ) _PDCLIB_nothrow; - -/* Multibyte / wide character conversion functions */ - -/* Affected by LC_CTYPE of the current locale. For state-dependent encoding, - each function is placed into its initial conversion state at program - startup, and can be returned to that state by a call with its character - pointer argument s being a null pointer. - Changing LC_CTYPE causes the conversion state to become indeterminate. -*/ - -/* If s is not a null pointer, returns the number of bytes contained in the - multibyte character pointed to by s (if the next n or fewer bytes form a - valid multibyte character); -1, if they don't; or 0, if s points to the - null character. - If s is a null pointer, returns nonzero if multibyte encodings in the - current locale are stateful, and zero otherwise. -*/ -int mblen( const char * s, size_t n ); - -/* If s is not a null pointer, and the next n bytes (maximum) form a valid - multibyte character sequence (possibly including shift sequences), the - corresponding wide character is stored in pwc (unless that is a null - pointer). If the wide character is the null character, the function is - left in the initial conversion state. - Returns the number of bytes in the consumed multibyte character sequence; - or 0, if the resulting wide character is the null character. If the next - n bytes do not form a valid sequence, returns -1. - In no case will the returned value be greater than n or MB_CUR_MAX. - If s is a null pointer, returns nonzero if multibyte encodings in the - current locale are stateful, and zero otherwise. -*/ -int mbtowc( wchar_t * _PDCLIB_restrict pwc, const char * _PDCLIB_restrict s, size_t n ); - -/* Converts the wide character wc into the corresponding multibyte character - sequence (including shift sequences). If s is not a null pointer, the - multibyte sequence (at most MB_CUR_MAX characters) is stored at that - location. If wc is a null character, a null byte is stored, preceded by - any shift sequence needed to restore the initial shift state, and the - function is left in the initial conversion state. - Returns the number of bytes in the generated multibyte character sequence. - If wc does not correspond to a valid multibyte character, returns -1. - In no case will the returned value be greater than MB_CUR_MAX. - If s is a null pointer, returns nonzero if multibyte encodings in the - current locale are stateful, and zero otherwise. -*/ -int wctomb( char * s, wchar_t wc ); - -/* Convert a sequence of multibyte characters beginning in the initial shift - state from the array pointed to by s into the corresponding wide character - sequence, storing no more than n wide characters into pwcs. A null - character is converted into a null wide character, and marks the end of - the multibyte character sequence. - If copying takes place between objects that overlap, behaviour is - undefined. - Returns (size_t)-1 if an invalid multibyte sequence is encountered. - Otherwise, returns the number of array elements modified, not including - a terminating null wide character, if any. (Target string will not be - null terminated if the return value equals n.) -*/ -size_t mbstowcs( wchar_t * _PDCLIB_restrict pwcs, const char * _PDCLIB_restrict s, size_t n ); - -/* Convert a sequence of wide characters from the array pointed to by pwcs - into a sequence of corresponding multibyte characters, beginning in the - initial shift state, storing them in the array pointed to by s, stopping - if the next multibyte character would exceed the limit of n total bytes - or a null character is stored. - If copying takes place between objects that overlap, behaviour is - undefined. - Returns (size_t)-1 if a wide character is encountered that does not - correspond to a valid multibyte character. Otherwise, returns the number - of array elements modified, not including a terminating null character, - if any. (Target string will not be null terminated if the return value - equals n.) -*/ -size_t wcstombs( char * _PDCLIB_restrict s, const wchar_t * _PDCLIB_restrict pwcs, size_t n ); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/waterbox/libc/includes/stdnoreturn.h b/waterbox/libc/includes/stdnoreturn.h deleted file mode 100644 index 8c1814328f..0000000000 --- a/waterbox/libc/includes/stdnoreturn.h +++ /dev/null @@ -1,12 +0,0 @@ -/* _Noreturn - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_STDNORETURN_H -#define _PDCLIB_STDNORETURN_H _PDCLIB_STDNORETURN_H - -#define noreturn _Noreturn - -#endif diff --git a/waterbox/libc/includes/string.h b/waterbox/libc/includes/string.h deleted file mode 100644 index 8e4db1e282..0000000000 --- a/waterbox/libc/includes/string.h +++ /dev/null @@ -1,216 +0,0 @@ -/* String handling - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_STRING_H -#define _PDCLIB_STRING_H _PDCLIB_STRING_H -#include "_PDCLIB_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _PDCLIB_SIZE_T_DEFINED -#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED -typedef _PDCLIB_size_t size_t; -#endif - -#ifndef _PDCLIB_NULL_DEFINED -#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED -#define NULL _PDCLIB_NULL -#endif - -/* String function conventions */ - -/* - In any of the following functions taking a size_t n to specify the length of - an array or size of a memory region, n may be 0, but the pointer arguments to - the call shall still be valid unless otherwise stated. -*/ - -/* Copying functions */ - -/* Copy a number of n characters from the memory area pointed to by s2 to the - area pointed to by s1. If the two areas overlap, behaviour is undefined. - Returns the value of s1. -*/ -void * memcpy( void * _PDCLIB_restrict s1, const void * _PDCLIB_restrict s2, size_t n ) _PDCLIB_nothrow; - -/* Copy a number of n characters from the memory area pointed to by s2 to the - area pointed to by s1. The two areas may overlap. - Returns the value of s1. -*/ -void * memmove( void * s1, const void * , size_t n ) _PDCLIB_nothrow; - -/* Copy the character array s2 (including terminating '\0' byte) into the - character array s1. - Returns the value of s1. -*/ -char * strcpy( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 ) _PDCLIB_nothrow; - -/* Copy a maximum of n characters from the character array s2 into the character - array s1. If s2 is shorter than n characters, '\0' bytes will be appended to - the copy in s1 until n characters have been written. If s2 is longer than n - characters, NO terminating '\0' will be written to s1. If the arrays overlap, - behaviour is undefined. - Returns the value of s1. -*/ -char * strncpy( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n ) _PDCLIB_nothrow; - -/* Concatenation functions */ - -/* Append the contents of the character array s2 (including terminating '\0') to - the character array s1 (first character of s2 overwriting the '\0' of s1). If - the arrays overlap, behaviour is undefined. - Returns the value of s1. -*/ -char * strcat( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 ) _PDCLIB_nothrow; - -/* Append a maximum of n characters from the character array s1 to the character - array s1 (first character of s2 overwriting the '\0' of s1). A terminating - '\0' is ALWAYS appended, even if the full n characters have already been - written. If the arrays overlap, behaviour is undefined. - Returns the value of s1. -*/ -char * strncat( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n ) _PDCLIB_nothrow; - -/* Comparison functions */ - -/* Compare the first n characters of the memory areas pointed to by s1 and s2. - Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if - s1 > s2. -*/ -int memcmp( const void * s1, const void * s2, size_t n ) _PDCLIB_nothrow; - -/* Compare the character arrays s1 and s2. - Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if - s1 > s2. -*/ -int strcmp( const char * s1, const char * s2 ) _PDCLIB_nothrow; - -/* Compare the character arrays s1 and s2, interpreted as specified by the - LC_COLLATE category of the current locale. - Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if - s1 > s2. - TODO: Currently a dummy wrapper for strcmp() as PDCLib does not yet support - locales. -*/ -int strcoll( const char * s1, const char * s2 ) _PDCLIB_nothrow; - -/* Compare no more than the first n characters of the character arrays s1 and - s2. - Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if - s1 > s2. -*/ -int strncmp( const char * s1, const char * s2, size_t n ) _PDCLIB_nothrow; - -/* Transform the character array s2 as appropriate for the LC_COLLATE setting of - the current locale. If length of resulting string is less than n, store it in - the character array pointed to by s1. Return the length of the resulting - string. -*/ -size_t strxfrm( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n ) _PDCLIB_nothrow; - -/* Search functions */ - -/* Search the first n characters in the memory area pointed to by s for the - character c (interpreted as unsigned char). - Returns a pointer to the first instance found, or NULL. -*/ -void * memchr( const void * s, int c, size_t n ) _PDCLIB_nothrow; - -/* Search the character array s (including terminating '\0') for the character c - (interpreted as char). - Returns a pointer to the first instance found, or NULL. -*/ -char * strchr( const char * s, int c ) _PDCLIB_nothrow; - -/* Determine the length of the initial substring of character array s1 which - consists only of characters not from the character array s2. - Returns the length of that substring. -*/ -size_t strcspn( const char * s1, const char * s2 ) _PDCLIB_nothrow; - -/* Search the character array s1 for any character from the character array s2. - Returns a pointer to the first occurrence, or NULL. -*/ -char * strpbrk( const char * s1, const char * s2 ) _PDCLIB_nothrow; - -/* Search the character array s (including terminating '\0') for the character c - (interpreted as char). - Returns a pointer to the last instance found, or NULL. -*/ -char * strrchr( const char * s, int c ) _PDCLIB_nothrow; - -/* Determine the length of the initial substring of character array s1 which - consists only of characters from the character array s2. - Returns the length of that substring. -*/ -size_t strspn( const char * s1, const char * s2 ) _PDCLIB_nothrow; - -/* Search the character array s1 for the substring in character array s2. - Returns a pointer to that sbstring, or NULL. If s2 is of length zero, - returns s1. -*/ -char * strstr( const char * s1, const char * s2 ) _PDCLIB_nothrow; - -/* In a series of subsequent calls, parse a C string into tokens. - On the first call to strtok(), the first argument is a pointer to the to-be- - parsed C string. On subsequent calls, the first argument is NULL unless you - want to start parsing a new string. s2 holds an array of seperator characters - which can differ from call to call. Leading seperators are skipped, the first - trailing seperator overwritten with '\0'. - Returns a pointer to the next token. - WARNING: This function uses static storage, and as such is not reentrant. -*/ -char * strtok( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 ) _PDCLIB_nothrow; - -/* Miscellaneous functions */ - -/* Write the character c (interpreted as unsigned char) to the first n - characters of the memory area pointed to by s. - Returns s. -*/ -void * memset( void * s, int c, size_t n ) _PDCLIB_nothrow; - -/* Map an error number to a (locale-specific) error message string. Error - numbers are typically errno values, but any number is mapped to a message. - TODO: PDCLib does not yet support locales. -*/ -char * strerror( int errnum ) _PDCLIB_nothrow; - -/* Returns the length of the string s (excluding terminating '\0'). -*/ -size_t strlen( const char * s ) _PDCLIB_nothrow; - -#if _PDCLIB_POSIX_MIN(2008098L) -/* Returns the length of the string s (excluding terminating '\0') or maxlen if - * no terminating '\0' is found in the first maxlen characters. - */ -size_t strnlen( const char * s, size_t maxlen ) _PDCLIB_nothrow; -#endif - -#if _PDCLIB_POSIX_MIN(2008098L) || _PDCLIB_XOPEN_MIN(0) -char * strdup( const char* src ) _PDCLIB_nothrow; -char * strndup( const char* src, size_t n ) _PDCLIB_nothrow; -#endif - -#if _PDCLIB_BSD_SOURCE -size_t strlcpy( - char *_PDCLIB_restrict _Dst, - const char *_PDCLIB_restrict _Src, - size_t _DstSize) _PDCLIB_nothrow; - -size_t strlcat( - char *_PDCLIB_restrict _Dst, - const char *_PDCLIB_restrict _Src, - size_t _DstSize) _PDCLIB_nothrow; -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/waterbox/libc/includes/threads.h b/waterbox/libc/includes/threads.h deleted file mode 100644 index d3786a2326..0000000000 --- a/waterbox/libc/includes/threads.h +++ /dev/null @@ -1,116 +0,0 @@ -/* Threads - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_THREADS_H -#define _PDCLIB_THREADS_H _PDCLIB_THREADS_H -#include "_PDCLIB_int.h" -#include "_PDCLIB_threadconfig.h" - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define thread_local _Thread_local - -typedef _PDCLIB_once_flag once_flag; - -enum -{ - mtx_plain = 0, - mtx_recursive = (1 << 0), - mtx_timed = (1 << 1), - - _PDCLIB_mtx_valid_mask = mtx_recursive | mtx_timed -}; - -enum -{ - thrd_success = 0, - thrd_timeout = 1, - thrd_busy = 2, - thrd_error = 3, - thrd_nomem = 4, -}; - -#define ONCE_FLAG_INIT _PDCLIB_ONCE_FLAG_INIT -#ifdef _PDCLIB_ONCE_FLAG_IS_DONE -static inline void call_once( once_flag * flag, void (*func)( void ) ) -{ - if ( ! _PDCLIB_ONCE_FLAG_IS_DONE( flag ) ) - { - _PDCLIB_call_once( flag, func ); - } -} -#else -void call_once( once_flag * flag, void (*func)( void ) ); -#endif - -#ifdef _PDCLIB_MTX_T -typedef _PDCLIB_MTX_T mtx_t; -void mtx_destroy( mtx_t * mtx ) _PDCLIB_nothrow; -int mtx_init( mtx_t * mtx, int type ) _PDCLIB_nothrow; -int mtx_lock( mtx_t * mtx ) _PDCLIB_nothrow; -int mtx_timedlock( mtx_t * _PDCLIB_restrict mtx, const struct timespec * _PDCLIB_restrict ts ) _PDCLIB_nothrow; -int mtx_trylock( mtx_t * mtx ) _PDCLIB_nothrow; -int mtx_unlock( mtx_t * mtx ) _PDCLIB_nothrow; -#endif - -#ifdef _PDCLIB_CND_T -typedef _PDCLIB_CND_T cnd_t; -int cnd_broadcast( cnd_t * cond ) _PDCLIB_nothrow; -void cnd_destroy( cnd_t * cond ) _PDCLIB_nothrow; -int cnd_init( cnd_t * cond ) _PDCLIB_nothrow; -int cnd_signal( cnd_t * cond ) _PDCLIB_nothrow; -int cnd_timedwait( cnd_t *_PDCLIB_restrict cond, mtx_t * _PDCLIB_restrict mtx, const struct timespec * _PDCLIB_restrict ts ) _PDCLIB_nothrow; -int cnd_wait( cnd_t * cond, mtx_t * mtx ) _PDCLIB_nothrow; -#endif - -#ifdef _PDCLIB_THRD_T -#define _PDCLIB_THRD_HAVE_MISC -typedef _PDCLIB_THRD_T thrd_t; -typedef int (*thrd_start_t)( void * ); - -int thrd_create( thrd_t * thr, thrd_start_t func, void * arg ) _PDCLIB_nothrow; -thrd_t thrd_current( void ) _PDCLIB_nothrow; -int thrd_detach( thrd_t thr ) _PDCLIB_nothrow; -int thrd_equal( thrd_t thr0, thrd_t thr1 ) _PDCLIB_nothrow; - -/* Not nothrow: systems may use exceptions at thread exit */ -_PDCLIB_noreturn void thrd_exit( int res ); -/* Not nothrow: systems may potentially propogate exceptions out of thrd_join? */ -int thrd_join( thrd_t thr, int * res ); -#endif - -#ifdef _PDCLIB_THRD_HAVE_MISC -int thrd_sleep( const struct timespec * duration, struct timespec * remaining ) _PDCLIB_nothrow; -void thrd_yield( void ) _PDCLIB_nothrow; -#endif - -/* The behaviour of tss_t is woefully underspecified in the C11 standard. In - particular, it never specifies where/when/if destructors are called. - - In lieu of any clarification, we assume the behaviour of POSIX pthread_key_t -*/ - -#ifdef _PDCLIB_TSS_T -#define TSS_DTOR_ITERATIONS _PDCLIB_TSS_DTOR_ITERATIONS - -typedef _PDCLIB_TSS_T tss_t; -typedef void (*tss_dtor_t)( void * ); - -int tss_create( tss_t * key, tss_dtor_t dtor ) _PDCLIB_nothrow; -void tss_delete( tss_t key ) _PDCLIB_nothrow; -void * tss_get( tss_t key ) _PDCLIB_nothrow; -int tss_set( tss_t key, void * val ) _PDCLIB_nothrow; -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/waterbox/libc/includes/time.h b/waterbox/libc/includes/time.h deleted file mode 100644 index a2b659688c..0000000000 --- a/waterbox/libc/includes/time.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Date and time - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_TIME_H -#define _PDCLIB_TIME_H _PDCLIB_TIME_H -#include "_PDCLIB_aux.h" -#include "_PDCLIB_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _PDCLIB_SIZE_T_DEFINED -#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED -typedef _PDCLIB_size_t size_t; -#endif - -#ifndef _PDCLIB_NULL_DEFINED -#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED -#define NULL _PDCLIB_NULL -#endif - -typedef _PDCLIB_time_t time_t; -typedef _PDCLIB_clock_t clock_t; - -#define CLOCKS_PER_SEC _PDCLIB_CLOCKS_PER_SEC -#define TIME_UTC _PDCLIB_TIME_UTC - -struct timespec -{ - time_t tv_sec; - long tv_nsec; -}; - -struct tm -{ - int tm_sec; /* 0-60 */ - int tm_min; /* 0-59 */ - int tm_hour; /* 0-23 */ - int tm_mday; /* 1-31 */ - int tm_mon; /* 0-11 */ - int tm_year; /* years since 1900 */ - int tm_wday; /* 0-6 */ - int tm_yday; /* 0-365 */ - int tm_isdst; /* >0 DST, 0 no DST, <0 information unavailable */ -}; - -/* Returns the number of "clocks" in processor time since the invocation - of the program. Divide by CLOCKS_PER_SEC to get the value in seconds. - Returns -1 if the value cannot be represented in the return type or is - not available. -*/ -clock_t clock( void ) _PDCLIB_nothrow; - -/* Returns the difference between two calendar times in seconds. */ -double difftime( time_t time1, time_t time0 ) _PDCLIB_nothrow; - -time_t mktime( struct tm * timeptr ) _PDCLIB_nothrow; - -time_t time( time_t * timer ) _PDCLIB_nothrow; - -int timespec_get( struct timespec * ts, int base ) _PDCLIB_nothrow; - -char * asctime( const struct tm * timeptr ) _PDCLIB_nothrow; - -char * ctime( const time_t * timer ) _PDCLIB_nothrow; - -struct tm * gmtime( const time_t * timer ) _PDCLIB_nothrow; - -struct tm * localtime( const time_t * timer ) _PDCLIB_nothrow; - -size_t strftime( char * _PDCLIB_restrict s, size_t maxsize, const char * _PDCLIB_restrict format, const struct tm * _PDCLIB_restrict timeptr ); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/waterbox/libc/includes/uchar.h b/waterbox/libc/includes/uchar.h deleted file mode 100644 index c061113e08..0000000000 --- a/waterbox/libc/includes/uchar.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Unicode utilities - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_UCHAR_H -#define _PDCLIB_UCHAR_H _PDCLIB_UCHAR_H -#include "_PDCLIB_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _PDCLIB_SIZE_T_DEFINED -#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED -typedef _PDCLIB_size_t size_t; -#endif - -#ifndef _PDCLIB_MBSTATE_T_DEFINED -#define _PDCLIB_MBSTATE_T_DEFINED _PDCLIB_MBSTATE_T_DEFINED -typedef _PDCLIB_mbstate_t mbstate_t; -#endif - -#ifndef __cplusplus - -/* These are built-in types in C++ */ - -#ifndef _PDCLIB_CHAR16_T_DEFINED -#define _PDCLIB_CHAR16_T_DEFINED _PDCLIB_CHAR16_T_DEFINED -typedef _PDCLIB_uint_least16_t char16_t; -#endif - -#ifndef _PDCLIB_CHAR32_T_DEFINED -#define _PDCLIB_CHAR32_T_DEFINED _PDCLIB_CHAR32_T_DEFINED -typedef _PDCLIB_uint_least32_t char32_t; -#endif - -#endif - -size_t mbrtoc16( char16_t * _PDCLIB_restrict pc16, const char * _PDCLIB_restrict s, size_t n, mbstate_t * _PDCLIB_restrict ps ); - -size_t c16rtomb( char * _PDCLIB_restrict s, char16_t c16, mbstate_t * _PDCLIB_restrict ps ); - -size_t mbrtoc32( char32_t * _PDCLIB_restrict pc32, const char * _PDCLIB_restrict s, size_t n, mbstate_t * _PDCLIB_restrict ps); - -size_t c32rtomb( char * _PDCLIB_restrict s, char32_t c32, mbstate_t * _PDCLIB_restrict ps); - -#if defined(_PDCLIB_EXTENSIONS) - -/* Analogous to strlen() / wcslen() */ - -size_t _PDCLIB_c16slen( const char16_t * str ); - -size_t _PDCLIB_c32slen( const char32_t * str ); - -/* String generalizations of the above functions */ - -size_t _PDCLIB_mbsrtoc16s( char16_t * _PDCLIB_restrict dst, const char * * _PDCLIB_restrict src, size_t len, mbstate_t * _PDCLIB_restrict ps ); - -size_t _PDCLIB_mbsrtoc32s( char32_t * _PDCLIB_restrict dst, const char * * _PDCLIB_restrict src, size_t len, mbstate_t * _PDCLIB_restrict ps ); - -size_t _PDCLIB_c16srtombs( char * _PDCLIB_restrict dst, const char16_t * * _PDCLIB_restrict src, size_t len, mbstate_t * _PDCLIB_restrict ps ); - -size_t _PDCLIB_c32srtombs( char * _PDCLIB_restrict dst, const char32_t * * _PDCLIB_restrict src, size_t len, mbstate_t * _PDCLIB_restrict ps ); -#endif - -#endif diff --git a/waterbox/libc/includes/wchar.h b/waterbox/libc/includes/wchar.h deleted file mode 100644 index ea6a34b774..0000000000 --- a/waterbox/libc/includes/wchar.h +++ /dev/null @@ -1,144 +0,0 @@ -/* Extended multibyte and wide character utilities - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_WCHAR_H -#define _PDCLIB_WCHAR_H _PDCLIB_WCHAR_H -#include "_PDCLIB_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _PDCLIB_SIZE_T_DEFINED -#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED -typedef _PDCLIB_size_t size_t; -#endif - -#ifndef __cplusplus - -#ifndef _PDCLIB_WCHAR_T_DEFINED -#define _PDCLIB_WCHAR_T_DEFINED _PDCLIB_WCHAR_T_DEFINED -typedef _PDCLIB_wchar_t wchar_t; -#endif - -#endif - -#ifndef _PDCLIB_WINT_T_DEFINED -#define _PDCLIB_WINT_T_DEFINED _PDCLIB_WINT_T_DEFINED -typedef _PDCLIB_wint_t wint_t; -#endif - -#ifndef _PDCLIB_MBSTATE_T_DEFINED -#define _PDCLIB_MBSTATE_T_DEFINED _PDCLIB_MBSTATE_T_DEFINED -typedef _PDCLIB_mbstate_t mbstate_t; -#endif - -struct tm; - -#ifndef _PDCLIB_NULL_DEFINED -#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED -#define NULL _PDCLIB_NULL -#endif - -#ifndef _PDCLIB_WCHAR_MIN_MAX_DEFINED -#define _PDCLIB_WCHAR_MIN_MAX_DEFINED _PDCLIB_WCHAR_MIN_MAX_DEFINED -#define WCHAR_MIN _PDCLIB_WCHAR_MIN -#define WCHAR_MAX _PDCLIB_WCHAR_MAX -#endif - -#ifndef _PDCLIB_WEOF_DEFINED -#define _PDCLIB_WEOF_DEFINED _PDCLIB_WEOF_DEFINED -#define WEOF _PDCLIB_WEOF -#endif - -/* Wide character string handling */ -wchar_t * wcscpy( wchar_t * _PDCLIB_restrict s1, const wchar_t * _PDCLIB_restrict s2 ); -wchar_t * wcsncpy( wchar_t * _PDCLIB_restrict s1, const wchar_t * _PDCLIB_restrict s2, size_t n ); -wchar_t * wmemcpy( wchar_t * _PDCLIB_restrict s1, const wchar_t * _PDCLIB_restrict s2, size_t n ); -wchar_t * wmemmove( wchar_t * s1, const wchar_t * s2, size_t n ); -wchar_t * wcscat( wchar_t * _PDCLIB_restrict s1, const wchar_t * _PDCLIB_restrict s2 ); -wchar_t * wcsncat( wchar_t * _PDCLIB_restrict s1, const wchar_t * _PDCLIB_restrict s2, size_t n ); -int wcscmp( const wchar_t * s1, const wchar_t * s2 ); -int wcscoll( const wchar_t * s1, const wchar_t * s2 ); -int wcsncmp( const wchar_t * s1, const wchar_t * s2, size_t n ); -size_t wcsxfrm( wchar_t * _PDCLIB_restrict s1, const wchar_t * _PDCLIB_restrict s2, size_t n ); -int wmemcmp( const wchar_t * s1, const wchar_t * s2, size_t n ); -wchar_t * wcschr( const wchar_t * s, wchar_t c ); -size_t wcscspn( const wchar_t * s1, const wchar_t * s2 ); -wchar_t * wcspbrk( const wchar_t * s1, const wchar_t * s2 ); -wchar_t * wcsrchr( const wchar_t * s, wchar_t c ); -size_t wcsspn( const wchar_t * s1, const wchar_t * s2 ); -wchar_t * wcsstr( const wchar_t * s1, const wchar_t * s2 ); -wchar_t * wcstok( wchar_t * _PDCLIB_restrict s1, const wchar_t * _PDCLIB_restrict s2, wchar_t * * _PDCLIB_restrict ptr ); -wchar_t * wmemchr( const wchar_t * s, wchar_t c, size_t n ); -size_t wcslen( const wchar_t * s ); -wchar_t * wmemset( wchar_t * s, wchar_t c, size_t n ); - -size_t wcsftime( wchar_t * _PDCLIB_restrict s, size_t maxsize, const wchar_t * _PDCLIB_restrict format, const struct tm * _PDCLIB_restrict timeptr ); - -/* Wide character I/O */ -int fwprintf( _PDCLIB_file_t * _PDCLIB_restrict stream, const wchar_t * _PDCLIB_restrict format, ... ); -int fwscanf( _PDCLIB_file_t * _PDCLIB_restrict stream, const wchar_t * _PDCLIB_restrict format, ... ); -int swprintf( wchar_t * _PDCLIB_restrict s, size_t n, const wchar_t * _PDCLIB_restrict format, ... ); -int swscanf( const wchar_t * _PDCLIB_restrict s, const wchar_t * _PDCLIB_restrict format, ... ); -int vfwprintf( _PDCLIB_file_t * _PDCLIB_restrict stream, const wchar_t * _PDCLIB_restrict format, _PDCLIB_va_list arg ); -int vfwscanf( _PDCLIB_file_t * _PDCLIB_restrict stream, const wchar_t * _PDCLIB_restrict format, _PDCLIB_va_list arg ); -int vswprintf( wchar_t * _PDCLIB_restrict s, size_t n, const wchar_t * _PDCLIB_restrict format, _PDCLIB_va_list arg ); -int vswscanf( const wchar_t * _PDCLIB_restrict s, const wchar_t * _PDCLIB_restrict format, _PDCLIB_va_list arg ); -int vwprintf( const wchar_t * _PDCLIB_restrict format, _PDCLIB_va_list arg ); -int vwscanf( const wchar_t * _PDCLIB_restrict format, _PDCLIB_va_list arg ); -int wprintf( const wchar_t * _PDCLIB_restrict format, ... ); -int wscanf( const wchar_t * _PDCLIB_restrict format, ... ); -wint_t fgetwc( _PDCLIB_file_t * stream ); -wchar_t * fgetws( wchar_t * _PDCLIB_restrict s, int n, _PDCLIB_file_t * _PDCLIB_restrict stream ); -wint_t fputwc( wchar_t c, _PDCLIB_file_t * stream ); -int fputws( const wchar_t * _PDCLIB_restrict s, _PDCLIB_file_t * _PDCLIB_restrict stream ); -int fwide( _PDCLIB_file_t * stream, int mode ); -wint_t getwc( _PDCLIB_file_t * stream ); -wint_t getwchar( void ); -wint_t putwc( wchar_t c, _PDCLIB_file_t * stream ); -wint_t putwchar( wchar_t c ); -wint_t ungetwc( wint_t c, _PDCLIB_file_t * stream ); - -#if _PDCLIB_GNU_SOURCE -wint_t getwc_unlocked( _PDCLIB_file_t * stream ); -wint_t getwchar_unlocked( void ); -wint_t fgetwc_unlocked( _PDCLIB_file_t * stream ); -wint_t fputwc_unlocked( wchar_t wc, _PDCLIB_file_t * stream ); -wint_t putwc_unlocked( wchar_t wc, _PDCLIB_file_t * stream ); -wint_t putwchar_unlocked( wchar_t wc ); -wchar_t * fgetws_unlocked( wchar_t * ws, int n, _PDCLIB_file_t * stream ); -int fputws_unlocked( const wchar_t * ws, _PDCLIB_file_t * stream ); -#endif - -/* Wide character <-> Numeric conversions */ - -double wcstod( const wchar_t * _PDCLIB_restrict nptr, wchar_t * * _PDCLIB_restrict endptr ); -float wcstof( const wchar_t * _PDCLIB_restrict nptr, wchar_t * * _PDCLIB_restrict endptr ); -long double wcstold( const wchar_t * _PDCLIB_restrict nptr, wchar_t * * _PDCLIB_restrict endptr ); - -long int wcstol( const wchar_t * _PDCLIB_restrict nptr, wchar_t * * _PDCLIB_restrict endptr, int base ); -long long int wcstoll( const wchar_t * _PDCLIB_restrict nptr, wchar_t * * _PDCLIB_restrict endptr, int base ); -unsigned long int wcstoul( const wchar_t * _PDCLIB_restrict nptr, wchar_t * * _PDCLIB_restrict endptr, int base ); -unsigned long long int wcstoull( const wchar_t * _PDCLIB_restrict nptr, wchar_t * * _PDCLIB_restrict endptr, int base ); - -/* Character set conversion */ -wint_t btowc( int c ); -int wctob( wint_t c ); -int mbsinit( const mbstate_t * ps ); -size_t mbrlen( const char * _PDCLIB_restrict s, size_t n, mbstate_t * _PDCLIB_restrict ps ); -size_t mbrtowc( wchar_t * _PDCLIB_restrict pwc, const char * _PDCLIB_restrict s, size_t n, mbstate_t * _PDCLIB_restrict ps ); -size_t wcrtomb( char * _PDCLIB_restrict s, wchar_t wc, mbstate_t * _PDCLIB_restrict ps ); -size_t mbsrtowcs( wchar_t * _PDCLIB_restrict dst, const char * * _PDCLIB_restrict src, size_t len, mbstate_t * _PDCLIB_restrict ps ); -size_t mbsnrtowcs( wchar_t * _PDCLIB_restrict dst, const char * * _PDCLIB_restrict src, size_t nms, size_t len, mbstate_t * _PDCLIB_restrict ps ); // NYI -size_t wcsrtombs( char * _PDCLIB_restrict dst, const wchar_t * * _PDCLIB_restrict src, size_t len, mbstate_t * _PDCLIB_restrict ps ); -size_t wcsnrtombs( char * _PDCLIB_restrict dst, const wchar_t * * _PDCLIB_restrict src, size_t nwc, size_t len, mbstate_t * _PDCLIB_restrict ps ); // NYI - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/waterbox/libc/includes/wctype.h b/waterbox/libc/includes/wctype.h deleted file mode 100644 index 9a71e16af9..0000000000 --- a/waterbox/libc/includes/wctype.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Wide character classification and mapping utilities - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_WCTYPE_H -#define _PDCLIB_WCTYPE_H _PDCLIB_WCTYPE_H -#include "_PDCLIB_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _PDCLIB_WINT_T_DEFINED -#define _PDCLIB_WINT_T_DEFINED _PDCLIB_WINT_T_DEFINED -typedef _PDCLIB_wint_t wint_t; -#endif - -#ifndef _PDCLIB_WEOF_DEFINED -#define _PDCLIB_WEOF_DEFINED _PDCLIB_WEOF_DEFINED -#define WEOF _PDCLIB_WEOF -#endif - -/* Scalar type representing locale-specific character mappings */ -typedef int wctrans_t; - -/* Scalar type representing locale-specific character classifications */ -typedef int wctype_t; - -/* Character classification functions */ - -int iswalnum( wint_t _Wc ); -int iswalpha( wint_t _Wc ); -int iswblank( wint_t _Wc ); -int iswcntrl( wint_t _Wc ); -int iswdigit( wint_t _Wc ); -int iswgraph( wint_t _Wc ); -int iswlower( wint_t _Wc ); -int iswprint( wint_t _Wc ); -int iswpunct( wint_t _Wc ); -int iswspace( wint_t _Wc ); -int iswupper( wint_t _Wc ); -int iswxdigit( wint_t _Wc ); - -/* Extensible character classification functions */ - -int iswctype( wint_t _Wc, wctype_t _Desc ); -wctype_t wctype( const char * _Property ); - -/* Wide character case mapping utilities */ - -wint_t towlower( wint_t _Wc ); -wint_t towupper( wint_t _Wc ); - -/* Extensible wide character case mapping functions */ - -wint_t towctrans( wint_t _Wc, wctrans_t _Desc ); -wctrans_t wctrans( const char * _Property ); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/waterbox/libc/internals/_PDCLIB_aux.h b/waterbox/libc/internals/_PDCLIB_aux.h deleted file mode 100644 index 8f1cb7fee6..0000000000 --- a/waterbox/libc/internals/_PDCLIB_aux.h +++ /dev/null @@ -1,381 +0,0 @@ -/* Auxiliary PDCLib code <_PDCLIB_aux.h> - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef __PDCLIB_AUX_H -#define __PDCLIB_AUX_H __PDCLIB_AUX_H - -/* -------------------------------------------------------------------------- */ -/* You should not have to edit anything in this file; if you DO have to, it */ -/* would be considered a bug / missing feature: notify the author(s). */ -/* -------------------------------------------------------------------------- */ - -/* -------------------------------------------------------------------------- */ -/* Standard Version */ -/* -------------------------------------------------------------------------- */ - -/* Many a compiler gets this wrong, so you might have to hardcode it instead. */ - -#if __STDC__ != 1 -#error Compiler does not define _ _STDC_ _ to 1 (not standard-compliant)! -#endif - -#if defined(_PDCLIB_C_VERSION) - /* Pass - conditional simplification case */ -#elif !defined(__STDC_VERSION__) - #define _PDCLIB_C_VERSION 1990 -#elif __STDC_VERSION__ == 199409L - #define _PDCLIB_C_VERSION 1995 -#elif __STDC_VERSION__ == 199901L - #define _PDCLIB_C_VERSION 1999 -#elif __STDC_VERSION__ == 201112L - #define _PDCLIB_C_VERSION 2011 -#else - #error Unsupported _ _STDC_VERSION_ _ (__STDC_VERSION__) (supported: ISO/IEC 9899:1990, 9899/AMD1:1995, 9899:1999, 9899:2011). -#endif - -#if !defined(__cplusplus) || defined(_PDCLIB_CXX_VERSION) - #define _PDCLIB_CXX_VERSION 0 -#elif __cplusplus == 201103L - #define _PDCLIB_CXX_VERSION 2011 - /* TODO: Do we want this? */ - #if _PDCLIB_C_VERSION < 2011 - #undef _PDCLIB_C_VERSION - #define _PDCLIB_C_VERSION 2011 - #endif -#elif __cplusplus == 199711L - #define _PDCLIB_CXX_VERSION 1997 -#else - #error Unsupported _ _cplusplus (__cplusplus) (supported: ISO/IEC 14882:1997, ISO/IEC 14882:2011). -#endif - -#ifndef __STDC_HOSTED__ - #error Compiler does not define _ _STDC_HOSTED_ _ (not standard-compliant)! -#elif __STDC_HOSTED__ == 0 - #define _PDCLIB_HOSTED 0 -#elif __STDC_HOSTED__ == 1 - #define _PDCLIB_HOSTED 1 -#else - #error Compiler does not define _ _STDC_HOSTED_ _ to 0 or 1 (not standard-compliant)! -#endif - -#ifdef __cplusplus - typedef bool _PDCLIB_bool; -#else - typedef _Bool _PDCLIB_bool; -#endif - -/* Clang style feature detection macros - * Note: It is common to #define __has_feature(0) if undefined so the presence - * of this macro does not guarantee it to be working - */ - -#ifdef __has_feature - #define _PDCLIB_HAS_FEATURE(x) __has_feature(x) -#else - #define _PDCLIB_HAS_FEATURE(x) (0) -#endif - -#ifdef __has_extension - #define _PDCLIB_HAS_EXTENSION(x) __has_extension(x) -#else - // Older versions of Clang use __has_feature instead - #define _PDCLIB_HAS_EXTENSION(x) _PDCLIB_HAS_FEATURE(x) -#endif - -#ifdef __has_builtin - #define _PDCLIB_HAS_BUILTIN(x) __has_builtin(x) -#else - #define _PDCLIB_HAS_BUILTIN(x) (0) -#endif - -#ifdef __has_attribute - #define _PDCLIB_HAS_ATTRIBUTE(x) __has_attribute(x) -#else - #define _PDCLIB_HAS_ATTRIBUTE(x) (0) -#endif - -/* GCC feature detection macros */ - -#if defined(__GNUC__) - #define _PDCLIB_GCC_MIN(maj, min) \ - ((__GNUC__ > maj) || (__GNUC__ == maj && __GNUC_MINOR__ >= min)) -#else - #define _PDCLIB_GCC_MIN(maj, min) (0) -#endif - -/* Hybrid GCC/Clang feature detection macros */ -#define _PDCLIB_GCC_FEATURE(x, gccmaj, gccmin) \ - (_PDCLIB_HAS_FEATURE(x) || _PDCLIB_GCC_MIN(gccmin, gccmaj)) - -#define _PDCLIB_GCC_EXTENSION(x, gccmaj, gccmin) \ - (_PDCLIB_HAS_EXTENSION(x) || _PDCLIB_GCC_MIN(gccmin, gccmaj)) - -#define _PDCLIB_GCC_BUILTIN(x, gccmaj, gccmin) \ - (_PDCLIB_HAS_BUILTIN(x) || _PDCLIB_GCC_MIN(gccmin, gccmaj)) - -#define _PDCLIB_GCC_ATTRIBUTE(x, gccmaj, gccmin) \ - (_PDCLIB_HAS_ATTRIBUTE(x) || _PDCLIB_GCC_MIN(gccmin, gccmaj)) - -/* Extension & Language feature detection */ - -#if _PDCLIB_C_VERSION >= 1999 || defined(__cplusplus) - #ifndef __cplusplus - #define _PDCLIB_restrict restrict - #endif - #define _PDCLIB_inline inline -#endif - -#if _PDCLIB_CXX_VERSION >= 2011 - #define _PDCLIB_nothrow noexcept - #define _PDCLIB_noexcept(x) noexcept(x) -#elif _PDCLIB_CXX_VERSION - #define _PDCLIB_nothrow throw() - #define _PDCLIB_noexcept -#endif - -#if _PDCLIB_CXX_VERSION >= 2011 && _PDCLIB_GCC_FEATURE(cxx_attributes, 4, 8) - #define _PDCLIB_noreturn [[noreturn]] -#elif _PDCLIB_C_VERSION >= 2011 && _PDCLIB_GCC_FEATURE(c_noreturn, 4, 7) - #define _PDCLIB_noreturn _Noreturn -#endif - -#ifdef _WIN32 - #define _PDCLIB_EXPORT __declspec(dllexport) - #define _PDCLIB_IMPORT __declspec(dllimport) -#endif - -#if !defined(_PDCLIB_EXPORT) && _PDCLIB_GCC_ATTRIBUTE(__visibility__, 4, 0) - #define _PDCLIB_EXPORT __attribute__((__visibility__("protected"))) -#endif - -#if !defined(_PDCLIB_HIDDEN) && _PDCLIB_GCC_ATTRIBUTE(__visibility__, 4, 0) - #define _PDCLIB_HIDDEN __attribute__((__visibility__("hidden"))) -#endif - -#if !defined(_PDCLIB_nothrow) && _PDCLIB_GCC_ATTRIBUTE(__nothrow__, 4, 0) - #define _PDCLIB_nothrow __attribute__((__nothrow__)) - #define _PDCLIB_noexcept -#endif - -#if !defined(_PDCLIB_restrict) && _PDCLIB_GCC_MIN(3, 0) - #define _PDCLIB_restrict __restrict -#endif - -#if !defined(_PDCLIB_inline) && _PDCLIB_GCC_MIN(3, 0) - #define _PDCLIB_inline __inline -#endif - -#if !defined(_PDCLIB_noreturn) && _PDCLIB_GCC_ATTRIBUTE(__noreturn__, 3, 0) - /* If you don't use __noreturn__, then stdnoreturn.h will break things! */ - #define _PDCLIB_noreturn __attribute__((__noreturn__)) -#endif - -#if !defined(_PDCLIB_DEPRECATED) && _PDCLIB_GCC_ATTRIBUTE(__deprecated__, 3, 0) - #define _PDCLIB_DEPRECATED __attribute__ ((__deprecated__)) -#endif - -#if !defined(_PDCLIB_UNREACHABLE) && _PDCLIB_GCC_BUILTIN(__builtin_unreachable, 4, 0) - #define _PDCLIB_UNREACHABLE __builtin_unreachable() -#endif - -#if !defined(_PDCLIB_UNDEFINED) && defined(__GNUC__) - #define _PDCLIB_UNDEFINED(_var) \ - do { __asm__("" : "=X"(_var)); } while(0) -#endif - -/* No-op fallbacks */ - -#ifndef _PDCLIB_nothrow - #define _PDCLIB_nothrow - #define _PDCLIB_noexcept -#endif - -#ifndef _PDCLIB_EXPORT - #define _PDCLIB_EXPORT -#endif -#ifndef _PDCLIB_IMPORT - #define _PDCLIB_IMPORT -#endif -#ifndef _PDCLIB_HIDDEN - #define _PDCLIB_HIDDEN -#endif - -#if defined(_PDCLIB_SHARED) - #if defined(_PDCLIB_BUILD) - #define _PDCLIB_API _PDCLIB_EXPORT - #else - #define _PDCLIB_API _PDCLIB_IMPORT - #endif -#else - #define _PDCLIB_API -#endif - -#ifndef _PDCLIB_restrict - #define _PDCLIB_restrict -#endif - -#ifndef _PDCLIB_inline - #define _PDCLIB_inline -#endif - -#ifndef _PDCLIB_noreturn - #define _PDCLIB_noreturn -#endif - -#ifndef _PDCLIB_DEPRECATED - #define _PDCLIB_DEPRECATED -#endif - -#ifndef _PDCLIB_UNREACHABLE - #define _PDCLIB_UNREACHABLE do {} while(0) -#endif - -#ifndef _PDCLIB_UNDEFINED - #define _PDCLIB_UNDEFINED(_var) do {} while(0) -#endif - -/*#if _PDCLIB_C_VERSION != 1999 -#error PDCLib might not be fully conforming to either C89 or C95 prior to v2.x. -#endif*/ - -/* -------------------------------------------------------------------------- */ -/* Helper macros: */ -/* _PDCLIB_cc( x, y ) concatenates two preprocessor tokens without extending */ -/* _PDCLIB_concat( x, y ) concatenates two preprocessor tokens with extending */ -/* _PDCLIB_concat3( x, y, z ) is the same for three tokens */ -/* _PDCLIB_static_assert( x ) provides a compile-time check mechanism */ -/* -------------------------------------------------------------------------- */ - -#define _PDCLIB_cc( x, y ) x ## y -#define _PDCLIB_concat( x, y ) _PDCLIB_cc( x, y ) -#define _PDCLIB_concat3( x, y, z ) _PDCLIB_concat( _PDCLIB_concat( x, y ), z ) -#if _PDCLIB_C_VERSION >= 2011 -#define _PDCLIB_static_assert _Static_assert -#else -#define _PDCLIB_static_assert( e, m ) ;enum { _PDCLIB_concat( _PDCLIB_assert_, __LINE__ ) = 1 / ( !!( e ) ) } -#endif - -#define _PDCLIB_symbol2value( x ) #x -#define _PDCLIB_symbol2string( x ) _PDCLIB_symbol2value( x ) - -/* Feature test macros - * - * All of the feature test macros come in the following forms - * _PDCLIB_*_MIN(min): Available in versions >= min - * _PDCLIB_*_MINMAX(min, max): Available in versions >= min <= max - * _PDCLIB_*_MAX(max): Availabel in versions <= max - * - * The defined tests are: - * C: C standard versions - * 1990, 1995, 1999, 2011 - * CXX: C++ standard versions - * 1997, 2011 - * POSIX: POSIX extension versions. - * 1 (POSIX.2), 2 (POSIX.2), 199309L (POSIX.1b), - * 199506L (POSIX.1c), 200112L (2001), 200809L (2008) - * XOPEN: X/Open System Interface (XSI)/Single Unix Specification - * 0 (XPG4), 500 (SUSv2/UNIX98), 600 (SUSv3/UNIX03), 700 (SUSv4) - * - * Additionally, the macros - * _BSD_SOURCE, _SVID_SOURCE and _GNU_SOURCE - * are adhered to. If _GNU_SOURCE is defined, _XOPEN_SOURCE and - * _POSIX_C_SOURCE are defined to their most recent values to match glibc - * behaviour - * - * The intention of supporting these feature test macros is to ease - * application portability from these systems to PDCLib systems; in addition, - * it eases support for these standards by systems supporting them which are - * using PDCLib as their default C library. - * - * Applications targetting purely PDClib/PDCLib based platforms may define - * just _PDCLIB_EXTENSIONS, which will enable all supported extensions, plus - * all features from all supported versions of C and C++. - * - */ -#define _PDCLIB_C_MIN(min) _PDCLIB_C_MINMAX(min, 3000) -#define _PDCLIB_CXX_MIN(min) _PDCLIB_CXX_MINMAX(min, 3000) -#define _PDCLIB_XOPEN_MIN(min) _PDCLIB_XOPEN_MINMAX(min, 30000000) -#define _PDCLIB_POSIX_MIN(min) _PDCLIB_POSIX_MINMAX(min, 30000000) -#define _PDCLIB_C_MAX(max) _PDCLIB_C_MINMAX(0, max) -#define _PDCLIB_CXX_MAX(max) _PDCLIB_CXX_MINMAX(0, max) -#define _PDCLIB_XOPEN_MAX(max) _PDCLIB_XOPEN_MINMAX(0, max) -#define _PDCLIB_POSIX_MAX(max) _PDCLIB_POSIX_MINMAX(0, max) -#if defined(_PDCLIB_EXTENSIONS) || defined(_PDCLIB_BUILD) - #define _PDCLIB_C_MINMAX(min, max) 1 - #define _PDCLIB_CXX_MINMAX(min, max) 1 - #define _PDCLIB_POSIX_MINMAX(min, max) 1 - #define _PDCLIB_XOPEN_MINMAX(min, max) 1 - - #undef _PDCLIB_EXTENSIONS - #undef _PDCLIB_BSD_SOURCE - #undef _PDCLIB_SVID_SOURCE - #undef _PDCLIB_GNU_SOURCE - - #define _PDCLIB_EXTENSIONS 1 - #define _PDCLIB_BSD_SOURCE 1 - #define _PDCLIB_SVID_SOURCE 1 - #define _PDCLIB_GNU_SOURCE 1 -#else - #define _PDCLIB_C_MINMAX(min, max) \ - (_PDCLIB_C_VERSION >= (min) && _PDCLIB_C_VERSION <= (max)) - #define _PDCLIB_CXX_MINMAX(min, max) \ - (_PDCLIB_CXX_VERSION >= (min) && _PDCLIB_CXX_VERSION <= (max)) - #define _PDCLIB_XOPEN_MINMAX(min, max) \ - (defined(_XOPEN_SOURCE) \ - && _XOPEN_SOURCE >= (min) && _XOPEN_SOURCE <= (max)) - #define _PDCLIB_POSIX_MINMAX(min, max) \ - (defined(_POSIX_C_SOURCE) \ - && _POSIX_C_SOURCE >= (min) && _POSIX_C_SOURCE <= (max)) - - #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE-1 == -1) - /* If _XOPEN_SOURCE is defined as empty, redefine here as zero */ - #undef _XOPEN_SOURCE - #define _XOPEN_SOURCE 0 - #endif - - #if defined(_GNU_SOURCE) - #define _PDCLIB_GNU_SOURCE 1 - #define _PDCLIB_SVID_SOURCE 1 - #define _PDCLIB_BSD_SOURCE 1 - #undef _XOPEN_SOURCE - #define _XOPEN_SOURCE 700 - #else - #define _PDCLIB_GNU_SOURCE 0 - #endif - - #if defined(_PDCLIB_BSD_SOURCE) - // pass - #elif defined(_BSD_SOURCE) - #define _PDCLIB_BSD_SOURCE 1 - #else - #define _PDCLIB_BSD_SOURCE 0 - #endif - - #if defined(_PDCLIB_SVID_SOURCE) - // pass - #elif defined(_SVID_SOURCE) - #define _PDCLIB_SVID_SOURCE 1 - #else - #define _PDCLIB_SVID_SOURCE 0 - #endif - - #if _PDCLIB_XOPEN_MIN(700) && !_PDCLIB_POSIX_MIN(200809L) - #undef _POSIX_C_SOURCE - #define _POSIX_C_SOURCE 2008098L - #elif _PDCLIB_XOPEN_MIN(600) && !_PDCLIB_POSIX_MIN(200112L) - #undef _POSIX_C_SOURCE - #define _POSIX_C_SOURCE 200112L - #elif _PDCLIB_XOPEN_MIN(0) && !_PDCLIB_POSIX_MIN(2) - #undef _POSIX_C_SOURCE - #define _POSIX_C_SOURCE 2 - #endif - - #if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) - #define _POSIX_C_SOURCE 1 - #endif -#endif - -#endif diff --git a/waterbox/libc/internals/_PDCLIB_clocale.h b/waterbox/libc/internals/_PDCLIB_clocale.h deleted file mode 100644 index 09ccc4d2d1..0000000000 --- a/waterbox/libc/internals/_PDCLIB_clocale.h +++ /dev/null @@ -1,19 +0,0 @@ -/* "C" Locale Support - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef _PDCLIB_CLOCALE_H -#define _PDCLIB_CLOCALE_H _PDCLIB_CLOCALE_H -#include -#ifdef __cplusplus -extern "C" { -#endif - -void _PDCLIB_initclocale( locale_t l ); - -#ifdef __cplusplus -} -#endif -#endif // _PDCLIB_CLOCALE_H diff --git a/waterbox/libc/internals/_PDCLIB_config.h b/waterbox/libc/internals/_PDCLIB_config.h deleted file mode 100644 index 5aad2c6c07..0000000000 --- a/waterbox/libc/internals/_PDCLIB_config.h +++ /dev/null @@ -1,466 +0,0 @@ -#ifndef _PDCLIB_CONFIG_H -#define _PDCLIB_CONFIG_H - -/* Internal PDCLib configuration <_PDCLIB_config.h> - (Generic Template) - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -/* -------------------------------------------------------------------------- */ -/* Misc */ -/* -------------------------------------------------------------------------- */ - -/* The character (sequence) your platform uses as newline. */ -#define _PDCLIB_endl "\n" - -/* exit() can signal success to the host environment by the value of zero or */ -/* the constant EXIT_SUCCESS. Failure is signaled by EXIT_FAILURE. Note that */ -/* any other return value is "implementation-defined", i.e. your environment */ -/* is not required to handle it gracefully. Set your definitions here. */ -#define _PDCLIB_SUCCESS 0 -#define _PDCLIB_FAILURE -1 - -/* qsort() in requires a function that swaps two memory areas. */ -/* Below is a naive implementation that can be improved significantly for */ -/* specific platforms, e.g. by swapping int instead of char. */ -#define _PDCLIB_memswp( i, j, size ) char tmp; do { tmp = *i; *i++ = *j; *j++ = tmp; } while ( --size ); - -/* -------------------------------------------------------------------------- */ -/* Integers */ -/* -------------------------------------------------------------------------- */ -/* Assuming 8-bit char, two's-complement architecture here. 'short' being */ -/* 16 bit, 'int' being either 16, 32 or 64 bit, 'long' being either 32 or 64 */ -/* bit (but 64 bit only if 'int' is 32 bit), and 'long long' being 64 bit if */ -/* 'long' is not, 64 or 128 bit otherwise. */ -/* Author is quite willing to support other systems but would like to hear of */ -/* interest in such support and details on the to-be-supported architecture */ -/* first, before going to lengths about it. */ -/* -------------------------------------------------------------------------- */ - -/* Comment out (or delete) the line below if your 'char' type is unsigned. */ -#define _PDCLIB_CHAR_SIGNED 1 - -/* Width of the integer types short, int, long, and long long, in bytes. */ -/* SHRT == 2, INT >= SHRT, LONG >= INT >= 4, LLONG >= LONG - check your */ -/* compiler manuals. */ -#define _PDCLIB_SHRT_BYTES 2 -#define _PDCLIB_INT_BYTES 4 -#if defined(__LP64__) || defined(_LP64) -# define _PDCLIB_LONG_BYTES 8 -#else -# define _PDCLIB_LONG_BYTES 4 -#endif -#define _PDCLIB_LLONG_BYTES 8 - -/* defines the div() function family that allows taking quotient */ -/* and remainder of an integer division in one operation. Many platforms */ -/* support this in hardware / opcode, and the standard permits ordering of */ -/* the return structure in any way to fit the hardware. That is why those */ -/* structs can be configured here. */ - -struct _PDCLIB_div_t -{ - int quot; - int rem; -}; - -struct _PDCLIB_ldiv_t -{ - long int quot; - long int rem; -}; - -struct _PDCLIB_lldiv_t -{ - long long int quot; - long long int rem; -}; - -/* -------------------------------------------------------------------------- */ -/* defines a set of integer types that are of a minimum width, and */ -/* "usually fastest" on the system. (If, for example, accessing a single char */ -/* requires the CPU to access a complete int and then mask out the char, the */ -/* "usually fastest" type of at least 8 bits would be int, not char.) */ -/* If you do not have information on the relative performance of the types, */ -/* the standard allows you to define any type that meets minimum width and */ -/* signedness requirements. */ -/* The defines below are just configuration for the real typedefs and limit */ -/* definitions done in <_PDCLIB_int.h>. The uppercase define shall be either */ -/* SHRT, INT, LONG, or LLONG (telling which values to use for the *_MIN and */ -/* *_MAX limits); the lowercase define either short, int, long, or long long */ -/* (telling the actual type to use). */ -/* The third define is the length modifier used for the type in printf() and */ -/* scanf() functions (used in ). */ -/* If you require a non-standard datatype to define the "usually fastest" */ -/* types, PDCLib as-is doesn't support that. Please contact the author with */ -/* details on your platform in that case, so support can be added. */ -/* -------------------------------------------------------------------------- */ - -#define _PDCLIB_FAST8 INT -#define _PDCLIB_fast8 int -#define _PDCLIB_FAST8_CONV - -#define _PDCLIB_FAST16 INT -#define _PDCLIB_fast16 int -#define _PDCLIB_FAST16_CONV - -#define _PDCLIB_FAST32 INT -#define _PDCLIB_fast32 int -#define _PDCLIB_FAST32_CONV - -#define _PDCLIB_FAST64 LLONG -#define _PDCLIB_fast64 long long -#define _PDCLIB_FAST64_CONV ll - -/* -------------------------------------------------------------------------- */ -/* What follows are a couple of "special" typedefs and their limits. Again, */ -/* the actual definition of the limits is done in <_PDCLIB_int.h>, and the */ -/* defines here are merely "configuration". See above for details. */ -/* -------------------------------------------------------------------------- */ - -/* The result type of substracting two pointers */ -#define _PDCLIB_ptrdiff long -#define _PDCLIB_PTRDIFF LONG -#define _PDCLIB_PTR_CONV - -/* An integer type that can be accessed as atomic entity (think asynchronous - interrupts). The type itself is not defined in a freestanding environment, - but its limits are. (Don't ask.) -*/ -#define _PDCLIB_sig_atomic int -#define _PDCLIB_SIG_ATOMIC INT - -/* Result type of the 'sizeof' operator (must be unsigned) */ -#define _PDCLIB_size unsigned long -#define _PDCLIB_SIZE ULONG - -/* Large enough an integer to hold all character codes of the largest supported - locale. -*/ -#define _PDCLIB_wint signed int -#define _PDCLIB_wchar unsigned int -#define _PDCLIB_WCHAR UINT - -#define _PDCLIB_intptr long -#define _PDCLIB_INTPTR LONG - -/* Largest supported integer type. Implementation note: see _PDCLIB_atomax(). */ -#define _PDCLIB_intmax long long int -#define _PDCLIB_INTMAX LLONG -#define _PDCLIB_MAX_CONV ll -/* You are also required to state the literal suffix for the intmax type */ -#define _PDCLIB_INTMAX_LITERAL ll - -/* defines imaxdiv(), which is equivalent to the div() function */ -/* family (see further above) with intmax_t as basis. */ - -struct _PDCLIB_imaxdiv_t -{ - _PDCLIB_intmax quot; - _PDCLIB_intmax rem; -}; - -/* : time_t - * The C standard doesn't define what representation of time is stored in - * time_t when returned by time() , but POSIX defines it to be seconds since the - * UNIX epoch and most appplications expect that. - * - * time_t is also used as the tv_sec member of struct timespec, which *is* - * defined as a linear count of seconds. - * - * time_t is defined as a "real type", so may be a floating point type, but with - * the presence of the nanosecond accurate struct timespec, and with the lack of - * any functions for manipulating more accurate values of time_t, this is - * probably not useful. - */ -#define _PDCLIB_time unsigned long long - -/* : clock_t - * - * A count of "clock ticks", where the length of a clock tick is unspecified by - * the standard. The implementation is required to provide a macro, - * CLOCKS_PER_SEC, which is the number of "clock ticks" which corresponds to one - * second. - * - * clock_t may be any real type (i.e. integral or floating), and its type on - * various systems differs. - * - * On XSI systems, CLOCKS_PER_SEC must be defined to 1000000 - */ -#define _PDCLIB_clock double -#define _PDCLIB_CLOCKS_PER_SEC 1000000 - -/* : TIME_UTC - * - * The TIME_UTC parameter is passed to the timespec_get function in order to get - * the system time in UTC since an implementation defined epoch (not necessarily - * the same as that used for time_t). That said, on POSIX the obvious - * implementation of timespec_get for TIME_UTC is to wrap - * clock_gettime(CLOCK_REALTIME, ...), which is defined as time in UTC since the - * same epoch. - * - * This may be any non-zero integer value. - */ -#define _PDCLIB_TIME_UTC 1 - -/* -------------------------------------------------------------------------- */ -/* Floating Point */ -/* -------------------------------------------------------------------------- */ - -/* Whether the implementation rounds toward zero (0), to nearest (1), toward - positive infinity (2), or toward negative infinity (3). (-1) signifies - indeterminable rounding, any other value implementation-specific rounding. -*/ -#define _PDCLIB_FLT_ROUNDS -1 - -/* Whether the implementation uses exact-width precision (0), promotes float - to double (1), or promotes float and double to long double (2). (-1) - signifies indeterminable behaviour, any other value implementation-specific - behaviour. -*/ -#define _PDCLIB_FLT_EVAL_METHOD 0 - -/* "Number of the decimal digits (n), such that any floating-point number in the - widest supported floating type with p(max) radix (b) digits can be rounded to - a floating-point number with (n) decimal digits and back again without change - to the value p(max) log(10)b if (b) is a power of 10, [1 + p(max) log(10)b] - otherwise." - 64bit IEC 60559 double format (53bit mantissa) is DECIMAL_DIG 17. - 80bit IEC 60559 double-extended format (64bit mantissa) is DECIMAL_DIG 21. -*/ -#define _PDCLIB_DECIMAL_DIG 17 - -/* Floating point types - * - * PDCLib (at present) assumes IEEE 754 floating point formats - * The following names are used: - * SINGLE: IEEE 754 single precision (32-bit) - * DOUBLE: IEEE 754 double precision (64-bit) - * EXTENDED: IEEE 754 extended precision (80-bit, as x87) - */ -#define _PDCLIB_FLOAT_TYPE SINGLE -#define _PDCLIB_DOUBLE_TYPE DOUBLE -#if defined(__i386__) || defined(__amd64__) - #define _PDCLIB_LDOUBLE_TYPE EXTENDED -#else - #define _PDCLIB_LDOUBLE_TYPE DOUBLE -#endif - -/* -------------------------------------------------------------------------- */ -/* Platform-dependent macros defined by the standard headers. */ -/* -------------------------------------------------------------------------- */ - -/* The offsetof macro - Contract: Expand to an integer constant expression of type size_t, which - represents the offset in bytes to the structure member from the beginning - of the structure. If the specified member is a bitfield, behaviour is - undefined. - There is no standard-compliant way to do this. - This implementation casts an integer zero to 'pointer to type', and then - takes the address of member. This is undefined behaviour but should work on - most compilers. -*/ -#define _PDCLIB_offsetof( type, member ) ( (size_t) &( ( (type *) 0 )->member ) ) - -/* Variable Length Parameter List Handling () - The macros defined by are highly dependent on the calling - conventions used, and you probably have to replace them with builtins of - your compiler. The following generic implementation works only for pure - stack-based architectures, and only if arguments are aligned to pointer - type. Credits to Michael Moody, who contributed this to the Public Domain. -*/ - -/* Internal helper macro. va_round is not part of . */ -#define _PDCLIB_va_round( type ) ( (sizeof(type) + sizeof(void *) - 1) & ~(sizeof(void *) - 1) ) - -typedef char * _PDCLIB_va_list; -#define _PDCLIB_va_arg( ap, type ) ( (ap) += (_PDCLIB_va_round(type)), ( *(type*) ( (ap) - (_PDCLIB_va_round(type)) ) ) ) -#define _PDCLIB_va_copy( dest, src ) ( (dest) = (src), (void)0 ) -#define _PDCLIB_va_end( ap ) ( (ap) = (char *)0, (void)0 ) -#define _PDCLIB_va_start( ap, parmN ) ( (ap) = (char *) &parmN + ( _PDCLIB_va_round(parmN) ), (void)0 ) - -/* -------------------------------------------------------------------------- */ -/* OS "glue", part 1 */ -/* These are values and data type definitions that you would have to adapt to */ -/* the capabilities and requirements of your OS. */ -/* The actual *functions* of the OS interface are declared in _PDCLIB_glue.h. */ -/* -------------------------------------------------------------------------- */ - -/* Memory management -------------------------------------------------------- */ - -/* Set this to the page size of your OS. If your OS does not support paging, set - to an appropriate value. (Too small, and malloc() will call the kernel too - often. Too large, and you will waste memory.) -*/ -#define _PDCLIB_MALLOC_PAGESIZE 4096 -#define _PDCLIB_MALLOC_ALIGN 16 -#define _PDCLIB_MALLOC_GRANULARITY 64*1024 -#define _PDCLIB_MALLOC_TRIM_THRESHOLD 2*1024*1024 -#define _PDCLIB_MALLOC_MMAP_THRESHOLD 256*1024 -#define _PDCLIB_MALLOC_RELEASE_CHECK_RATE 4095 - -/* TODO: Better document these */ - -/* Locale --------------------------------------------------------------------*/ - -/* Locale method. See _PDCLIB_locale.h */ -#define _PDCLIB_LOCALE_METHOD _PDCLIB_LOCALE_METHOD_FAKE - -/* wchar_t encoding */ -#define _PDCLIB_WCHAR_ENCODING _PDCLIB_WCHAR_ENCODING_UCS4 - -/* I/O ---------------------------------------------------------------------- */ - -/* The default size for file buffers. Must be at least 256. */ -#define _PDCLIB_BUFSIZ 1024 - -/* The minimum number of files the implementation can open simultaneously. Must - be at least 8. Depends largely on how the bookkeeping is done by fopen() / - freopen() / fclose(). The example implementation limits the number of open - files only by available memory. -*/ -#define _PDCLIB_FOPEN_MAX 8 - -/* Length of the longest filename the implementation guarantees to support. */ -#define _PDCLIB_FILENAME_MAX 128 - -/* Maximum length of filenames generated by tmpnam(). (See tmpfile.c.) */ -#define _PDCLIB_L_tmpnam 46 - -/* Number of distinct file names that can be generated by tmpnam(). */ -#define _PDCLIB_TMP_MAX 50 - -/* The values of SEEK_SET, SEEK_CUR and SEEK_END, used by fseek(). - Since at least one platform (POSIX) uses the same symbols for its own "seek" - function, we use whatever the host defines (if it does define them). -*/ -#define _PDCLIB_SEEK_SET 0 -#define _PDCLIB_SEEK_CUR 1 -#define _PDCLIB_SEEK_END 2 - -/* The number of characters that can be buffered with ungetc(). The standard - guarantees only one (1); anything larger would make applications relying on - this capability dependent on implementation-defined behaviour (not good). -*/ -#define _PDCLIB_UNGETCBUFSIZE 1 - -/* errno -------------------------------------------------------------------- */ - -/* These are the values that _PDCLIB_errno can be set to by the library. - - By keeping PDCLib's errno in the _PDCLIB_* namespace, the library is capable - to "translate" between errno values used by the hosting operating system and - those used and passed out by the library. - - Example: In the example platform, the remove() function uses the unlink() - system call as backend. Linux sets its errno to EISDIR if you try to unlink() - a directory, but POSIX demands EPERM. Within the remove() function, you can - catch the 'errno == EISDIR', and set '_PDCLIB_errno = _PDCLIB_EPERM'. Anyone - using PDCLib's will "see" EPERM instead of EISDIR (the _PDCLIB_* - prefix removed by mechanics). - - If you do not want that kind of translation, you might want to "match" the - values used by PDCLib with those used by the host OS, to avoid confusion. - - The C standard only defines three distinct errno values: ERANGE, EDOM, and - EILSEQ. The standard leaves it up to "the implementation" whether there are - any more beyond those three. - - However, C++11 introduced the whole list of POSIX errno values into the - standard, so PDCLib might as well define those as well. - - Sometimes the standard says to set errno to indicate an error, but does not - prescribe a value. We will use a value from the following list. If POSIX - defines a value, we use that; otherwise, we use as seems suitable. -*/ - -/* These values were taken from Linux, gcc 4.8. */ -#define _PDCLIB_E2BIG 7 -#define _PDCLIB_EACCES 13 -#define _PDCLIB_EADDRINUSE 98 -#define _PDCLIB_EADDRNOTAVAIL 99 -#define _PDCLIB_EAFNOSUPPORT 97 -#define _PDCLIB_EAGAIN 11 -#define _PDCLIB_EALREADY 114 -#define _PDCLIB_EBADF 9 -#define _PDCLIB_EBADMSG 74 -#define _PDCLIB_EBUSY 16 -#define _PDCLIB_ECANCELED 125 -#define _PDCLIB_ECHILD 10 -#define _PDCLIB_ECONNABORTED 103 -#define _PDCLIB_ECONNREFUSED 111 -#define _PDCLIB_ECONNRESET 104 -#define _PDCLIB_EDEADLK 35 -#define _PDCLIB_EDESTADDRREQ 89 -#define _PDCLIB_EDOM 33 -#define _PDCLIB_EEXIST 17 -#define _PDCLIB_EFAULT 14 -#define _PDCLIB_EFBIG 27 -#define _PDCLIB_EHOSTUNREACH 113 -#define _PDCLIB_EIDRM 43 -#define _PDCLIB_EILSEQ 84 -#define _PDCLIB_EINPROGRESS 115 -#define _PDCLIB_EINTR 4 -#define _PDCLIB_EINVAL 22 -#define _PDCLIB_EIO 5 -#define _PDCLIB_EISCONN 106 -#define _PDCLIB_EISDIR 21 -#define _PDCLIB_ELOOP 40 -#define _PDCLIB_EMFILE 24 -#define _PDCLIB_EMLINK 31 -#define _PDCLIB_EMSGSIZE 90 -#define _PDCLIB_ENAMETOOLONG 36 -#define _PDCLIB_ENETDOWN 100 -#define _PDCLIB_ENETRESET 102 -#define _PDCLIB_ENETUNREACH 101 -#define _PDCLIB_ENFILE 23 -#define _PDCLIB_ENOBUFS 105 -#define _PDCLIB_ENODATA 61 -#define _PDCLIB_ENODEV 19 -#define _PDCLIB_ENOENT 2 -#define _PDCLIB_ENOEXEC 8 -#define _PDCLIB_ENOLCK 37 -#define _PDCLIB_ENOLINK 67 -#define _PDCLIB_ENOMEM 12 -#define _PDCLIB_ENOMSG 42 -#define _PDCLIB_ENOPROTOOPT 92 -#define _PDCLIB_ENOSPC 28 -#define _PDCLIB_ENOSR 63 -#define _PDCLIB_ENOSTR 60 -#define _PDCLIB_ENOSYS 38 -#define _PDCLIB_ENOTCONN 107 -#define _PDCLIB_ENOTDIR 20 -#define _PDCLIB_ENOTEMPTY 39 -#define _PDCLIB_ENOTRECOVERABLE 131 -#define _PDCLIB_ENOTSOCK 88 -#define _PDCLIB_ENOTSUP 95 -#define _PDCLIB_ENOTTY 25 -#define _PDCLIB_ENXIO 6 -#define _PDCLIB_EOPNOTSUPP 95 -#define _PDCLIB_EOVERFLOW 75 -#define _PDCLIB_EOWNERDEAD 130 -#define _PDCLIB_EPERM 1 -#define _PDCLIB_EPIPE 32 -#define _PDCLIB_EPROTO 71 -#define _PDCLIB_EPROTONOSUPPORT 93 -#define _PDCLIB_EPROTOTYPE 91 -#define _PDCLIB_ERANGE 34 -#define _PDCLIB_EROFS 30 -#define _PDCLIB_ESPIPE 29 -#define _PDCLIB_ESRCH 3 -#define _PDCLIB_ETIME 62 -#define _PDCLIB_ETIMEDOUT 110 -#define _PDCLIB_ETXTBSY 26 -#define _PDCLIB_EWOULDBLOCK 11 -#define _PDCLIB_EXDEV 18 - -/* This is used to set the size of the array in struct lconv () */ -/* holding the error messages for the strerror() and perror() fuctions. If */ -/* you change this value because you are using additional errno values, you */ -/* *HAVE* to provide appropriate error messages for *ALL* locales. */ -/* Needs to be one higher than the highest errno value above. */ -#define _PDCLIB_ERRNO_MAX 132 - -#endif diff --git a/waterbox/libc/internals/_PDCLIB_encoding.h b/waterbox/libc/internals/_PDCLIB_encoding.h deleted file mode 100644 index 7d893c2d55..0000000000 --- a/waterbox/libc/internals/_PDCLIB_encoding.h +++ /dev/null @@ -1,209 +0,0 @@ -/* Encoding support <_PDCLIB_encoding.h> - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef __PDCLIB_ENCODING_H -#define __PDCLIB_ENCODING_H __PDCLIB_ENCODING_H - -#include - -/* Must be cauued with bufsize >= 1, in != NULL, out != NULL, ps != NULL - * - * Converts a UTF-16 (char16_t) to a UCS4 (char32_t) value. Returns - * 1, 2 : Valid character (converted to UCS-4) - * -1 : Encoding error - * -2 : Partial character (only lead surrogate in buffer) - */ -static inline int _PDCLIB_c16rtoc32( - _PDCLIB_char32_t *_PDCLIB_restrict out, - const _PDCLIB_char16_t *_PDCLIB_restrict in, - _PDCLIB_size_t bufsize, - _PDCLIB_mbstate_t *_PDCLIB_restrict ps -) -{ - if(ps->_Surrogate) { - // We already have a lead surrogate - if((*in & ~0x3FF) != 0xDC00) { - // Encoding error - return -1; - } else { - // Decode and reset state - *out = (ps->_Surrogate & 0x3FF) << 10 | (*in & 0x3FF); - ps->_Surrogate = 0; - return 1; - } - } if((*in & ~0x3FF) == 0xD800) { - // Lead surrogate - if(bufsize >= 2) { - // Buffer big enough - if((in[1] & ~0x3FF) != 0xDC00) { - // Encoding error - return -1; - } else { - *out = (in[0] & 0x3FF) << 10 | (in[1] & 0x3FF); - return 2; - } - } else { - // Buffer too small - update state - ps->_Surrogate = *in; - return -2; - } - } else { - // BMP character - *out = *in; - return 1; - } -} - -static inline _PDCLIB_size_t _PDCLIB_c32rtoc16( - _PDCLIB_wchar_t *_PDCLIB_restrict out, - const _PDCLIB_char32_t *_PDCLIB_restrict in, - _PDCLIB_size_t bufsize, - _PDCLIB_mbstate_t *_PDCLIB_restrict ps -) -{ - if(ps->_Surrogate) { - *out = ps->_Surrogate; - ps->_Surrogate = 0; - return 0; - } - - if(*in <= 0xFFFF) { - // BMP character - *out = *in; - return 1; - } else { - // Supplementary plane character - *out = 0xD800 | (*in >> 10); - if(bufsize >= 2) { - out[1] = 0xDC00 | (*in & 0x3FF); - return 2; - } else { - ps->_Surrogate = 0xDC00 | (*in & 0x3FF); - return 1; - } - } -} - -struct _PDCLIB_charcodec_t { - /* Reads at most *_P_insz code units from *_P_inbuf and writes the result - * into *_P_outbuf, writing at most *_P_outsz code units. Updates - * *_P_outbuf, *_P_outsz, *_P_inbuf, *_P_outsz with the resulting state - * - * If _P_outbuf is NULL, then the input must be processed but no output - * generated. _P_outsz may be processed as normal. - * - * Returns true if the conversion completed successfully (i.e. one of - * _P_outsize or _P_insize reached zero and no coding errors were - * encountered), else return false. - */ - - /* mbsinit. Mandatory. */ - _PDCLIB_bool (*__mbsinit)(const _PDCLIB_mbstate_t *_P_ps); - - /* UCS-4 variants. Mandatory. */ - - _PDCLIB_bool (*__mbstoc32s)( - _PDCLIB_char32_t *_PDCLIB_restrict *_PDCLIB_restrict _P_outbuf, - _PDCLIB_size_t *_PDCLIB_restrict _P_outsz, - const char *_PDCLIB_restrict *_PDCLIB_restrict _P_inbuf, - _PDCLIB_size_t *_PDCLIB_restrict _P_insz, - _PDCLIB_mbstate_t *_PDCLIB_restrict _P_ps - ); - - _PDCLIB_bool (*__c32stombs)( - char *_PDCLIB_restrict *_PDCLIB_restrict _P_outbuf, - _PDCLIB_size_t *_PDCLIB_restrict _P_outsz, - const _PDCLIB_char32_t *_PDCLIB_restrict *_PDCLIB_restrict _P_inbuf, - _PDCLIB_size_t *_PDCLIB_restrict _P_insz, - _PDCLIB_mbstate_t *_PDCLIB_restrict _P_ps - ); - - /* UTF-16 variants; same as above except optional. - * - * If not provided, _PDCLib will internally synthesize on top of the UCS-4 - * variants above, albeit at a performance cost. - */ - - _PDCLIB_bool (*__mbstoc16s)( - _PDCLIB_char16_t *_PDCLIB_restrict *_PDCLIB_restrict _P_outbuf, - _PDCLIB_size_t *_PDCLIB_restrict _P_outsz, - const char *_PDCLIB_restrict *_PDCLIB_restrict _P_inbuf, - _PDCLIB_size_t *_PDCLIB_restrict _P_insz, - _PDCLIB_mbstate_t *_PDCLIB_restrict _P_ps - ); - - _PDCLIB_bool (*__c16stombs)( - char *_PDCLIB_restrict *_PDCLIB_restrict _P_outbuf, - _PDCLIB_size_t *_PDCLIB_restrict _P_outsz, - const _PDCLIB_char16_t *_PDCLIB_restrict *_PDCLIB_restrict _P_inbuf, - _PDCLIB_size_t *_PDCLIB_restrict _P_insz, - _PDCLIB_mbstate_t *_PDCLIB_restrict _P_ps - ); - - size_t __mb_max; -}; - -/* mbstate _PendState values */ -enum { - /* Nothing pending; _PendChar ignored */ - _PendClear = 0, - - /* Process the character stored in _PendChar before reading the buffer - * passed for the conversion - */ - _PendPrefix = 1, -}; - -/* XXX Defining these here is temporary - will move to xlocale in future */ -size_t mbrtoc16_l( - char16_t *_PDCLIB_restrict pc16, - const char *_PDCLIB_restrict s, - size_t n, - mbstate_t *_PDCLIB_restrict ps, -_PDCLIB_locale_t _PDCLIB_restrict l); - -size_t c16rtomb_l( - char *_PDCLIB_restrict s, - char16_t c16, - mbstate_t *_PDCLIB_restrict ps, -_PDCLIB_locale_t _PDCLIB_restrict l); - -size_t mbrtoc32_l( - char32_t *_PDCLIB_restrict pc32, - const char *_PDCLIB_restrict s, - size_t n, - mbstate_t *_PDCLIB_restrict ps, -_PDCLIB_locale_t _PDCLIB_restrict l); - -size_t c32rtomb_l( - char *_PDCLIB_restrict s, - char32_t c32, - mbstate_t *_PDCLIB_restrict ps, -_PDCLIB_locale_t _PDCLIB_restrict l); - -#define _PDCLIB_WCHAR_ENCODING_UTF16 16 -#define _PDCLIB_WCHAR_ENCODING_UCS4 32 - -#if !defined(_PDCLIB_WCHAR_ENCODING) - #define _PDCLIB_WCHAR_ENCODING 0 -#endif - -#if _PDCLIB_WCHAR_ENCODING == _PDCLIB_WCHAR_ENCODING_UTF16 - #define _PDCLIB_mbrtocwc_l mbrtoc16_l - #define _PDCLIB_mbrtocwc mbrtoc16 - #define _PDCLIB_cwcrtomb_l c16rtomb_l - #define _PDCLIB_cwcrtomb c16rtomb -#elif _PDCLIB_WCHAR_ENCODING == _PDCLIB_WCHAR_ENCODING_UCS4 - #define _PDCLIB_mbrtocwc_l mbrtoc32_l - #define _PDCLIB_mbrtocwc mbrtoc32 - #define _PDCLIB_cwcrtomb_l c32rtomb_l - #define _PDCLIB_cwcrtomb c32rtomb -#else - #error _PDCLIB_WCHAR_ENCODING not defined correctly - #error Define to one of _PDCLIB_WCHAR_ENCODING_UCS4 or _PDCLIB_WCHAR_ENCODING_UTF16 -#endif - -#endif diff --git a/waterbox/libc/internals/_PDCLIB_float.h b/waterbox/libc/internals/_PDCLIB_float.h deleted file mode 100644 index 483b54fe4b..0000000000 --- a/waterbox/libc/internals/_PDCLIB_float.h +++ /dev/null @@ -1,95 +0,0 @@ -/* PDCLib internal floating point logic <_PDCLIB_float.h> - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef __PDCLIB_PDCLIB_FLOAT_H -#define __PDCLIB_PDCLIB_FLOAT_H __PDCLIB_PDCLIB_FLOAT_H - -#include "_PDCLIB_aux.h" - -/* IEEE 754 single precision */ -#define _PDCLIB_FP_SINGLE_MIN 1.17549435082228750797e-38 -#define _PDCLIB_FP_SINGLE_EPSILON 1.19209289550781250000e-7 -#define _PDCLIB_FP_SINGLE_HAS_DENORM 1 -#define _PDCLIB_FP_SINGLE_MIN_EXP -125 -#define _PDCLIB_FP_SINGLE_MANT_DIG 24 -#define _PDCLIB_FP_SINGLE_RADIX 2 -#define _PDCLIB_FP_SINGLE_HAS_QUIET_NAN 1 -#define _PDCLIB_FP_SINGLE_MAX_10_EXP 38 -#define _PDCLIB_FP_SINGLE_HAS_INFINITY 1 -#define _PDCLIB_FP_SINGLE_DIG 6 -#define _PDCLIB_FP_SINGLE_MAX_EXP 128 -#define _PDCLIB_FP_SINGLE_DENORM_MIN 1.40129846432481707092e-45 -#define _PDCLIB_FP_SINGLE_MAX 3.40282346638528859812e+38 -#define _PDCLIB_FP_SINGLE_MIN_10_EXP -37 - -/* IEEE 754 double precision */ -#define _PDCLIB_FP_DOUBLE_MIN_EXP -1021 -#define _PDCLIB_FP_DOUBLE_DENORM_MIN 4.94065645841246544177e-324 -#define _PDCLIB_FP_DOUBLE_MIN_10_EXP -307 -#define _PDCLIB_FP_DOUBLE_DIG 15 -#define _PDCLIB_FP_DOUBLE_MAX 1.79769313486231570815e+308 -#define _PDCLIB_FP_DOUBLE_HAS_INFINITY 1 -#define _PDCLIB_FP_DOUBLE_MAX_EXP 1024 -#define _PDCLIB_FP_DOUBLE_MIN 2.22507385850720138309e-308 -#define _PDCLIB_FP_DOUBLE_HAS_DENORM 1 -#define _PDCLIB_FP_DOUBLE_HAS_QUIET_NAN 1 -#define _PDCLIB_FP_DOUBLE_MANT_DIG 53 -#define _PDCLIB_FP_DOUBLE_EPSILON 2.22044604925031308085e-16 -#define _PDCLIB_FP_DOUBLE_MAX_10_EXP 308 - -/* IEEE 754 80-bit extended precision */ -#define _PDCLIB_FP_EXTENDED_MAX 1.18973149535723176502e+4932 -#define _PDCLIB_FP_EXTENDED_MAX_EXP 16384 -#define _PDCLIB_FP_EXTENDED_HAS_INFINITY 1 -#define _PDCLIB_FP_EXTENDED_MIN 3.36210314311209350626e-4932 -#define _PDCLIB_FP_EXTENDED_HAS_QUIET_NAN 1 -#define _PDCLIB_FP_EXTENDED_HAS_DENORM 1 -#define _PDCLIB_FP_EXTENDED_EPSILON 1.08420217248550443401e-19 -#define _PDCLIB_FP_EXTENDED_MANT_DIG 64 -#define _PDCLIB_FP_EXTENDED_MIN_EXP (-16381) -#define _PDCLIB_FP_EXTENDED_MAX_10_EXP 4932 -#define _PDCLIB_FP_EXTENDED_DENORM_MIN 3.64519953188247460253e-4951 -#define _PDCLIB_FP_EXTENDED_MIN_10_EXP (-4931) -#define _PDCLIB_FP_EXTENDED_DIG 18 - -/* TODO: IEEE754 quadruple precision (_PDCLIB_FP_QUADRUPLE_*) and - "double-double" math - */ - -#define _PDCLIB_FLT_RADIX _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _RADIX ), f ) -#define _PDCLIB_FLT_MANT_DIG _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MANT_DIG ) -#define _PDCLIB_FLT_DIG _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _DIG ) -#define _PDCLIB_FLT_EPSILON _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _EPSILON ), f ) -#define _PDCLIB_FLT_MIN_EXP _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MIN_EXP ) -#define _PDCLIB_FLT_MIN _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MIN ), f ) -#define _PDCLIB_FLT_MIN_10_EXP _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MIN_10_EXP ) -#define _PDCLIB_FLT_MAX_EXP _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MAX_EXP ) -#define _PDCLIB_FLT_MAX _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MAX ), f ) -#define _PDCLIB_FLT_MAX_10_EXP _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MAX_10_EXP ) - -#define _PDCLIB_DBL_RADIX _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _RADIX ) -#define _PDCLIB_DBL_MANT_DIG _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MANT_DIG ) -#define _PDCLIB_DBL_DIG _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _DIG ) -#define _PDCLIB_DBL_EPSILON _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _EPSILON ) -#define _PDCLIB_DBL_MIN_EXP _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MIN_EXP ) -#define _PDCLIB_DBL_MIN _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MIN ) -#define _PDCLIB_DBL_MIN_10_EXP _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MIN_10_EXP ) -#define _PDCLIB_DBL_MAX_EXP _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MAX_EXP ) -#define _PDCLIB_DBL_MAX _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MAX ) -#define _PDCLIB_DBL_MAX_10_EXP _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MAX_10_EXP ) - -#define _PDCLIB_LDBL_RADIX _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _RADIX ), l ) -#define _PDCLIB_LDBL_MANT_DIG _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MANT_DIG ) -#define _PDCLIB_LDBL_DIG _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _DIG ) -#define _PDCLIB_LDBL_EPSILON _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _EPSILON ), l ) -#define _PDCLIB_LDBL_MIN_EXP _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MIN_EXP ) -#define _PDCLIB_LDBL_MIN _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MIN ), l ) -#define _PDCLIB_LDBL_MIN_10_EXP _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MIN_10_EXP ) -#define _PDCLIB_LDBL_MAX_EXP _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MAX_EXP ) -#define _PDCLIB_LDBL_MAX _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MAX ), l ) -#define _PDCLIB_LDBL_MAX_10_EXP _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MAX_10_EXP ) - -#endif diff --git a/waterbox/libc/internals/_PDCLIB_glue.h b/waterbox/libc/internals/_PDCLIB_glue.h deleted file mode 100644 index c482ef6784..0000000000 --- a/waterbox/libc/internals/_PDCLIB_glue.h +++ /dev/null @@ -1,63 +0,0 @@ -/* OS glue functions declaration <_PDCLIB_glue.h> - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef __PDCLIB_GLUE_H -#define __PDCLIB_GLUE_H __PDCLIB_GLUE_H - -#include "_PDCLIB_int.h" -#include "_PDCLIB_io.h" - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -------------------------------------------------------------------------- */ -/* OS "glue", part 2 */ -/* These are the functions you will have to touch, as they are where PDCLib */ -/* interfaces with the operating system. */ -/* They operate on data types partially defined by _PDCLIB_config.h. */ -/* -------------------------------------------------------------------------- */ - -/* stdlib.h */ - -/* A system call that terminates the calling process, returning a given status - to the environment. -*/ -_PDCLIB_noreturn void _PDCLIB_Exit( int status ); - -void *_PDCLIB_sbrk( size_t n ); - -/* stdio.h */ - -/* Open the file with the given name and mode. Return the file descriptor in - * *fd and a pointer to the operations structure in **ops on success. - * - * Return true on success and false on failure. - */ -bool _PDCLIB_open( - _PDCLIB_fd_t* fd, const _PDCLIB_fileops_t** ops, - char const * filename, unsigned int mode ); - -/* A system call that removes a file identified by name. Return zero on success, - non-zero otherwise. -*/ -int _PDCLIB_remove( const char * filename ); - -/* A system call that renames a file from given old name to given new name. - Return zero on success, non-zero otherwise. In case of failure, the file - must still be accessible by old name. Any handling of open files etc. is - done by standard rename() already. -*/ -int _PDCLIB_rename( const char * old, const char * newn); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/waterbox/libc/internals/_PDCLIB_int.h b/waterbox/libc/internals/_PDCLIB_int.h deleted file mode 100644 index 5024afcc32..0000000000 --- a/waterbox/libc/internals/_PDCLIB_int.h +++ /dev/null @@ -1,414 +0,0 @@ -/* PDCLib internal integer logic <_PDCLIB_int.h> - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef __PDCLIB_INT_H -#define __PDCLIB_INT_H __PDCLIB_INT_H - -/* -------------------------------------------------------------------------- */ -/* You should not have to edit anything in this file; if you DO have to, it */ -/* would be considered a bug / missing feature: notify the author(s). */ -/* -------------------------------------------------------------------------- */ - -#include "_PDCLIB_config.h" -#include "_PDCLIB_aux.h" - -/* null pointer constant */ -#define _PDCLIB_NULL 0 - -/* -------------------------------------------------------------------------- */ -/* Limits of native datatypes */ -/* -------------------------------------------------------------------------- */ -/* The definition of minimum limits for unsigned datatypes is done because */ -/* later on we will "construct" limits for other abstract types: */ -/* USHRT -> _PDCLIB_ + USHRT + _MIN -> _PDCLIB_USHRT_MIN -> 0 */ -/* INT -> _PDCLIB_ + INT + _MIN -> _PDCLIB_INT_MIN -> ... you get the idea. */ -/* -------------------------------------------------------------------------- */ - -/* Setting 'char' limits */ -#define _PDCLIB_CHAR_BIT 8 -#define _PDCLIB_UCHAR_MIN 0 -#define _PDCLIB_UCHAR_MAX 0xff -#define _PDCLIB_SCHAR_MIN (-0x7f - 1) -#define _PDCLIB_SCHAR_MAX 0x7f -#ifdef _PDCLIB_CHAR_SIGNED -#define _PDCLIB_CHAR_MIN _PDCLIB_SCHAR_MIN -#define _PDCLIB_CHAR_MAX _PDCLIB_SCHAR_MAX -#else -#define _PDCLIB_CHAR_MIN 0 -#define _PDCLIB_CHAR_MAX _PDCLIB_UCHAR_MAX -#endif - -/* Setting 'short' limits */ -#if _PDCLIB_SHRT_BYTES == 2 -#define _PDCLIB_SHRT_MAX 0x7fff -#define _PDCLIB_SHRT_MIN (-0x7fff - 1) -#define _PDCLIB_USHRT_MAX 0xffff -#else -#error Unsupported width of 'short' (not 16 bit). -#endif -#define _PDCLIB_USHRT_MIN 0 - -#if _PDCLIB_INT_BYTES < _PDCLIB_SHRT_BYTES -#error Bogus setting: short > int? Check _PDCLIB_config.h. -#endif - -/* Setting 'int' limits */ -#if _PDCLIB_INT_BYTES == 2 -#define _PDCLIB_INT_MAX 0x7fff -#define _PDCLIB_INT_MIN (-0x7fff - 1) -#define _PDCLIB_UINT_MAX 0xffffU -#elif _PDCLIB_INT_BYTES == 4 -#define _PDCLIB_INT_MAX 0x7fffffff -#define _PDCLIB_INT_MIN (-0x7fffffff - 1) -#define _PDCLIB_UINT_MAX 0xffffffffU -#elif _PDCLIB_INT_BYTES == 8 -#define _PDCLIB_INT_MAX 0x7fffffffffffffff -#define _PDCLIB_INT_MIN (-0x7fffffffffffffff - 1) -#define _PDCLIB_UINT_MAX 0xffffffffffffffff -#else -#error Unsupported width of 'int' (neither 16, 32, nor 64 bit). -#endif -#define _PDCLIB_UINT_MIN 0 - -/* Setting 'long' limits */ -#if _PDCLIB_LONG_BYTES == 4 -#define _PDCLIB_LONG_MAX 0x7fffffffL -#define _PDCLIB_LONG_MIN (-0x7fffffffL - 1L) -#define _PDCLIB_ULONG_MAX 0xffffffffUL -#elif _PDCLIB_LONG_BYTES == 8 -#define _PDCLIB_LONG_MAX 0x7fffffffffffffffL -#define _PDCLIB_LONG_MIN (-0x7fffffffffffffffL - 1L) -#define _PDCLIB_ULONG_MAX 0xffffffffffffffffUL -#else -#error Unsupported width of 'long' (neither 32 nor 64 bit). -#endif -#define _PDCLIB_ULONG_MIN 0 - -/* Setting 'long long' limits */ -#if _PDCLIB_LLONG_BYTES == 8 -#define _PDCLIB_LLONG_MAX 0x7fffffffffffffffLL -#define _PDCLIB_LLONG_MIN (-0x7fffffffffffffffLL - 1LL) -#define _PDCLIB_ULLONG_MAX 0xffffffffffffffffULL -#elif _PDCLIB_LLONG_BYTES == 16 -#define _PDCLIB_LLONG_MAX 0x7fffffffffffffffffffffffffffffffLL -#define _PDCLIB_LLONG_MIN (-0x7fffffffffffffffffffffffffffffffLL - 1LL) -#define _PDCLIB_ULLONG_MAX 0xffffffffffffffffffffffffffffffffULL -#else -#error Unsupported width of 'long long' (neither 64 nor 128 bit). -#endif -#define _PDCLIB_ULLONG_MIN 0 - -/* -------------------------------------------------------------------------- */ -/* exact-width types and their limits */ -/* -------------------------------------------------------------------------- */ -/* Note that, for the "standard" widths of 8, 16, 32 and 64 bit, the "LEAST" */ -/* types are identical to the "exact-width" types, by definition. */ - -/* Setting 'int8_t', its limits, its literal, and conversion macros. */ -#if _PDCLIB_CHAR_BIT == 8 -typedef signed char _PDCLIB_int8_t; -typedef unsigned char _PDCLIB_uint8_t; -typedef signed char _PDCLIB_int_least8_t; -typedef unsigned char _PDCLIB_uint_least8_t; -#define _PDCLIB_INT8_MAX _PDCLIB_CHAR_MAX -#define _PDCLIB_INT8_MIN _PDCLIB_CHAR_MIN -#define _PDCLIB_UINT8_MAX _PDCLIB_UCHAR_MAX -#define _PDCLIB_8_CONV hh -#else -#error Unsupported width of char (not 8 bits). -#endif - -/* Setting 'int16_t', its limits, its literal, and conversion macros. */ -#if _PDCLIB_INT_BYTES == 2 -typedef signed int _PDCLIB_int16_t; -typedef unsigned int _PDCLIB_uint16_t; -typedef signed int _PDCLIB_int_least16_t; -typedef unsigned int _PDCLIB_uint_least16_t; -#define _PDCLIB_INT16_MAX _PDCLIB_INT_MAX -#define _PDCLIB_INT16_MIN _PDCLIB_INT_MIN -#define _PDCLIB_UINT16_MAX _PDCLIB_UINT_MAX -#define _PDCLIB_16_CONV -#elif _PDCLIB_SHRT_BYTES == 2 -typedef signed short _PDCLIB_int16_t; -typedef unsigned short _PDCLIB_uint16_t; -typedef signed short _PDCLIB_int_least16_t; -typedef unsigned short _PDCLIB_uint_least16_t; -#define _PDCLIB_INT16_MAX _PDCLIB_SHRT_MAX -#define _PDCLIB_INT16_MIN _PDCLIB_SHRT_MIN -#define _PDCLIB_UINT16_MAX _PDCLIB_USHRT_MAX -#define _PDCLIB_16_CONV h -#else -#error Neither 'short' nor 'int' are 16-bit. -#endif - -/* Setting 'int32_t', its limits, its literal, and conversion macros. */ -#if _PDCLIB_INT_BYTES == 4 -typedef signed int _PDCLIB_int32_t; -typedef unsigned int _PDCLIB_uint32_t; -typedef signed int _PDCLIB_int_least32_t; -typedef unsigned int _PDCLIB_uint_least32_t; -#define _PDCLIB_INT32_MAX _PDCLIB_INT_MAX -#define _PDCLIB_INT32_MIN _PDCLIB_INT_MIN -#define _PDCLIB_UINT32_MAX _PDCLIB_UINT_MAX -#define _PDCLIB_INT32_LITERAL -#define _PDCLIB_UINT32_LITERAL -#define _PDCLIB_32_CONV -#elif _PDCLIB_LONG_BYTES == 4 -typedef signed long _PDCLIB_int32_t; -typedef unsigned long _PDCLIB_uint32_t; -typedef signed long _PDCLIB_int_least32_t; -typedef unsigned long _PDCLIB_uint_least32_t; -#define _PDCLIB_INT32_MAX _PDCLIB_LONG_MAX -#define _PDCLIB_INT32_MIN _PDCLIB_LONG_MIN -#define _PDCLIB_UINT32_MAX _PDCLIB_LONG_MAX -#define _PDCLIB_INT32_LITERAL l -#define _PDCLIB_UINT32_LITERAL ul -#define _PDCLIB_32_CONV l -#else -#error Neither 'int' nor 'long' are 32-bit. -#endif - -/* Setting 'int64_t', its limits, its literal, and conversion macros. */ -#if _PDCLIB_LONG_BYTES == 8 && !defined(_PDCLIB_INT64_IS_LLONG) -typedef signed long _PDCLIB_int64_t; -typedef unsigned long _PDCLIB_uint64_t; -typedef signed long _PDCLIB_int_least64_t; -typedef unsigned long _PDCLIB_uint_least64_t; -#define _PDCLIB_INT64_MAX _PDCLIB_LONG_MAX -#define _PDCLIB_INT64_MIN _PDCLIB_LONG_MIN -#define _PDCLIB_UINT64_MAX _PDCLIB_ULONG_MAX -#define _PDCLIB_INT64_LITERAL l -#define _PDCLIB_UINT64_LITERAL ul -#define _PDCLIB_64_CONV l -#elif _PDCLIB_LLONG_BYTES == 8 -typedef signed long long _PDCLIB_int64_t; -typedef unsigned long long _PDCLIB_uint64_t; -typedef signed long long _PDCLIB_int_least64_t; -typedef unsigned long long _PDCLIB_uint_least64_t; -#define _PDCLIB_INT64_MAX _PDCLIB_LLONG_MAX -#define _PDCLIB_INT64_MIN _PDCLIB_LLONG_MIN -#define _PDCLIB_UINT64_MAX _PDCLIB_ULLONG_MAX -#define _PDCLIB_INT64_LITERAL ll -#define _PDCLIB_UINT64_LITERAL ull -#define _PDCLIB_64_CONV ll -#else -#error Neither 'long' nor 'long long' are 64-bit. -#endif - -/* -------------------------------------------------------------------------- */ -/* "fastest" types and their limits */ -/* -------------------------------------------------------------------------- */ -/* This is, admittedly, butt-ugly. But at least it's ugly where the average */ -/* user of PDCLib will never see it, and makes <_PDCLIB_config.h> much */ -/* cleaner. */ -/* -------------------------------------------------------------------------- */ - -typedef _PDCLIB_fast8 _PDCLIB_int_fast8_t; -typedef unsigned _PDCLIB_fast8 _PDCLIB_uint_fast8_t; -#define _PDCLIB_INT_FAST8_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST8 ), _MIN ) -#define _PDCLIB_INT_FAST8_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST8 ), _MAX ) -#define _PDCLIB_UINT_FAST8_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_FAST8 ), _MAX ) - -typedef _PDCLIB_fast16 _PDCLIB_int_fast16_t; -typedef unsigned _PDCLIB_fast16 _PDCLIB_uint_fast16_t; -#define _PDCLIB_INT_FAST16_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST16 ), _MIN ) -#define _PDCLIB_INT_FAST16_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST16 ), _MAX ) -#define _PDCLIB_UINT_FAST16_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_FAST16 ), _MAX ) - -typedef _PDCLIB_fast32 _PDCLIB_int_fast32_t; -typedef unsigned _PDCLIB_fast32 _PDCLIB_uint_fast32_t; -#define _PDCLIB_INT_FAST32_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST32 ), _MIN ) -#define _PDCLIB_INT_FAST32_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST32 ), _MAX ) -#define _PDCLIB_UINT_FAST32_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_FAST32 ), _MAX ) - -typedef _PDCLIB_fast64 _PDCLIB_int_fast64_t; -typedef unsigned _PDCLIB_fast64 _PDCLIB_uint_fast64_t; -#define _PDCLIB_INT_FAST64_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST64 ), _MIN ) -#define _PDCLIB_INT_FAST64_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_FAST64 ), _MAX ) -#define _PDCLIB_UINT_FAST64_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_FAST64 ), _MAX ) - -/* -------------------------------------------------------------------------- */ -/* Various typedefs and limits */ -/* -------------------------------------------------------------------------- */ - -typedef _PDCLIB_ptrdiff _PDCLIB_ptrdiff_t; -#define _PDCLIB_PTRDIFF_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_PTRDIFF ), _MIN ) -#define _PDCLIB_PTRDIFF_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_PTRDIFF ), _MAX ) - -typedef _PDCLIB_size _PDCLIB_size_t; -#define _PDCLIB_SIZE_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_SIZE ), _MAX ) - -typedef _PDCLIB_wint _PDCLIB_wint_t; - -#ifndef __cplusplus - typedef _PDCLIB_wchar _PDCLIB_wchar_t; -#else - typedef wchar_t _PDCLIB_wchar_t; -#endif -#define _PDCLIB_WCHAR_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_WCHAR ), _MIN ) -#define _PDCLIB_WCHAR_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_WCHAR ), _MAX ) - -#define _PDCLIB_SIG_ATOMIC_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_SIG_ATOMIC ), _MIN ) -#define _PDCLIB_SIG_ATOMIC_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_SIG_ATOMIC ), _MAX ) - -typedef _PDCLIB_intptr _PDCLIB_intptr_t; -typedef unsigned _PDCLIB_intptr _PDCLIB_uintptr_t; -#define _PDCLIB_INTPTR_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_INTPTR ), _MIN ) -#define _PDCLIB_INTPTR_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_INTPTR ), _MAX ) -#define _PDCLIB_UINTPTR_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_INTPTR ), _MAX ) - -typedef _PDCLIB_intmax _PDCLIB_intmax_t; -typedef unsigned _PDCLIB_intmax _PDCLIB_uintmax_t; -#define _PDCLIB_INTMAX_MIN _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_INTMAX ), _MIN ) -#define _PDCLIB_INTMAX_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_, _PDCLIB_INTMAX ), _MAX ) -#define _PDCLIB_UINTMAX_MAX _PDCLIB_concat( _PDCLIB_concat( _PDCLIB_U, _PDCLIB_INTMAX ), _MAX ) -#define _PDCLIB_INTMAX_C( value ) _PDCLIB_concat( value, _PDCLIB_INTMAX_LITERAL ) -#define _PDCLIB_UINTMAX_C( value ) _PDCLIB_concat( value, _PDCLIB_concat( u, _PDCLIB_INTMAX_LITERAL ) ) - -/* -------------------------------------------------------------------------- */ -/* Various internals */ -/* -------------------------------------------------------------------------- */ - -typedef _PDCLIB_time _PDCLIB_time_t; -typedef _PDCLIB_clock _PDCLIB_clock_t; - -/* -------------------------------------------------------------------------- */ -/* Internal data types */ -/* -------------------------------------------------------------------------- */ - -/* Structure required by both atexit() and exit() for handling atexit functions */ -struct _PDCLIB_exitfunc_t -{ - struct _PDCLIB_exitfunc_t * next; - void (*func)( void ); -}; - -/* -------------------------------------------------------------------------- */ -/* Declaration of helper functions (implemented in functions/_PDCLIB). */ -/* -------------------------------------------------------------------------- */ - -/* This is the main function called by atoi(), atol() and atoll(). */ -_PDCLIB_intmax_t _PDCLIB_atomax( const char * s ); - -/* Two helper functions used by strtol(), strtoul() and long long variants. */ -const char * _PDCLIB_strtox_prelim( const char * p, char * sign, int * base ); -_PDCLIB_uintmax_t _PDCLIB_strtox_main( const char ** p, unsigned int base, _PDCLIB_uintmax_t error, _PDCLIB_uintmax_t limval, int limdigit, char * sign ); - -/* Digits arrays used by various integer conversion functions */ -extern char _PDCLIB_digits[]; -extern char _PDCLIB_Xdigits[]; - -/* -------------------------------------------------------------------------- */ -/* Sanity checks */ -/* -------------------------------------------------------------------------- */ - -#if _PDCLIB_C_VERSION >= 2011 -#ifdef __cplusplus -#define _Static_assert static_assert -#endif -_Static_assert( sizeof( short ) == _PDCLIB_SHRT_BYTES, "_PDCLIB_SHRT_BYTES incorrectly defined, check _PDCLIB_config.h" ); -_Static_assert( sizeof( int ) == _PDCLIB_INT_BYTES, "_PDCLIB_INT_BYTES incorrectly defined, check _PDCLIB_config.h" ); -_Static_assert( sizeof( long ) == _PDCLIB_LONG_BYTES, "_PDCLIB_LONG_BYTES incorrectly defined, check _PDCLIB_config.h" ); -_Static_assert( sizeof( long long ) == _PDCLIB_LLONG_BYTES, "_PDCLIB_LLONG_BYTES incorrectly defined, check _PDCLIB_config.h" ); -_Static_assert( ( (char)-1 < 0 ) == _PDCLIB_CHAR_SIGNED, "_PDCLIB_CHAR_SIGNED incorrectly defined, check _PDCLIB_config.h" ); -_Static_assert( sizeof( _PDCLIB_wchar ) == sizeof( L'x' ), "_PDCLIB_wchar incorrectly defined, check _PDCLIB_config.h" ); -_Static_assert( sizeof( void * ) == sizeof( _PDCLIB_intptr ), "_PDCLIB_intptr incorrectly defined, check _PDCLIB_config.h" ); -_Static_assert( sizeof( sizeof( 1 ) ) == sizeof( _PDCLIB_size ), "_PDCLIB_size incorrectly defined, check _PDCLIB_config.h" ); -_Static_assert( sizeof( &_PDCLIB_digits[1] - &_PDCLIB_digits[0] ) == sizeof( _PDCLIB_ptrdiff ), "_PDCLIB_ptrdiff incorrectly defined, check _PDCLIB_config.h" ); -#endif - -/* -------------------------------------------------------------------------- */ -/* locale / wchar / uchar */ -/* -------------------------------------------------------------------------- */ - -#ifndef __cplusplus -typedef _PDCLIB_uint16_t _PDCLIB_char16_t; -typedef _PDCLIB_uint32_t _PDCLIB_char32_t; -#else -typedef char16_t _PDCLIB_char16_t; -typedef char32_t _PDCLIB_char32_t; -#endif - -typedef struct _PDCLIB_mbstate { - union { - /* Is this the best way to represent this? Is this big enough? */ - _PDCLIB_uint64_t _St64[15]; - _PDCLIB_uint32_t _St32[31]; - _PDCLIB_uint16_t _St16[62]; - unsigned char _StUC[124]; - signed char _StSC[124]; - char _StC [124]; - }; - - /* c16/related functions: Surrogate storage - * - * If zero, no surrogate pending. If nonzero, surrogate. - */ - _PDCLIB_uint16_t _Surrogate; - - /* In cases where the underlying codec is capable of regurgitating a - * character without consuming any extra input (e.g. a surrogate pair in a - * UCS-4 to UTF-16 conversion) then these fields are used to track that - * state. In particular, they are used to buffer/fake the input for mbrtowc - * and similar functions. - * - * See _PDCLIB_encoding.h for values of _PendState and the resultant value - * in _PendChar. - */ - unsigned char _PendState; - char _PendChar; -} _PDCLIB_mbstate_t; - -typedef struct _PDCLIB_locale *_PDCLIB_locale_t; -typedef struct lconv _PDCLIB_lconv_t; - -_PDCLIB_size_t _PDCLIB_mb_cur_max( void ); - -/* wide-character EOF */ -#define _PDCLIB_WEOF ((wint_t) -1) - -/* -------------------------------------------------------------------------- */ -/* stdio */ -/* -------------------------------------------------------------------------- */ - -/* Position / status structure for getpos() / fsetpos(). */ -typedef struct _PDCLIB_fpos -{ - _PDCLIB_int_fast64_t offset; /* File position offset */ - _PDCLIB_mbstate_t mbs; /* Multibyte parsing state */ -} _PDCLIB_fpos_t; - -typedef struct _PDCLIB_fileops _PDCLIB_fileops_t; -typedef union _PDCLIB_fd _PDCLIB_fd_t; -typedef struct _PDCLIB_file _PDCLIB_file_t; // Rename to _PDCLIB_FILE? - -/* Status structure required by _PDCLIB_print(). */ -struct _PDCLIB_status_t -{ - /* XXX This structure is horrible now. scanf needs its own */ - - int base; /* base to which the value shall be converted */ - _PDCLIB_int_fast32_t flags; /* flags and length modifiers */ - unsigned n; /* print: maximum characters to be written (snprintf) */ - /* scan: number matched conversion specifiers */ - unsigned i; /* number of characters read/written */ - unsigned current;/* chars read/written in the CURRENT conversion */ - unsigned width; /* specified field width */ - int prec; /* specified field precision */ - - union { - void * ctx; /* context for callback */ - const char * s; /* input string for scanf */ - }; - - union { - _PDCLIB_size_t ( *write ) ( void *p, const char *buf, _PDCLIB_size_t size ); - _PDCLIB_file_t *stream; /* for scanf */ - }; - _PDCLIB_va_list arg; /* argument stack */ -}; - -#endif diff --git a/waterbox/libc/internals/_PDCLIB_io.h b/waterbox/libc/internals/_PDCLIB_io.h deleted file mode 100644 index 11f351f797..0000000000 --- a/waterbox/libc/internals/_PDCLIB_io.h +++ /dev/null @@ -1,296 +0,0 @@ -/* PDCLib I/O support <_PDCLIB_io.h> - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef __PDCLIB_IO_H -#define __PDCLIB_IO_H __PDCLIB_IO_H - -#include "_PDCLIB_int.h" -#include "_PDCLIB_threadconfig.h" - -/* Flags for representing mode (see fopen()). Note these must fit the same - status field as the _IO?BF flags in and the internal flags below. -*/ -#define _PDCLIB_FREAD 8u -#define _PDCLIB_FWRITE 16u -#define _PDCLIB_FAPPEND 32u -#define _PDCLIB_FRW 64u -#define _PDCLIB_FBIN 128u - -/* Internal flags, made to fit the same status field as the flags above. */ -/* -------------------------------------------------------------------------- */ -/* free() the buffer memory on closing (false for user-supplied buffer) */ -#define _PDCLIB_FREEBUFFER 512u -/* stream has encountered error / EOF */ -#define _PDCLIB_ERRORFLAG 1024u -#define _PDCLIB_EOFFLAG 2048u -/* stream is wide-oriented */ -#define _PDCLIB_WIDESTREAM 4096u -/* stream is byte-oriented */ -#define _PDCLIB_BYTESTREAM 8192u -/* file associated with stream should be remove()d on closing (tmpfile()) */ -#define _PDCLIB_DELONCLOSE 16384u -/* stream handle should not be free()d on close (stdin, stdout, stderr) */ -#define _PDCLIB_STATIC 32768u - -union _PDCLIB_fd -{ -#if defined(_PDCLIB_OSFD_T) - _PDCLIB_OSFD_T osfd; -#endif - void * pointer; - _PDCLIB_uintptr_t uval; - _PDCLIB_intptr_t sval; -}; - -/******************************************************************************/ -/* Internal functions */ -/******************************************************************************/ - -/* The worker for all printf() type of functions. The pointer spec should point - to the introducing '%' of a conversion specifier. The status structure is to - be that of the current printf() function, of which the members n, s, stream - and arg will be preserved; i will be updated; and all others will be trashed - by the function. - Returns the number of characters parsed as a conversion specifier (0 if none - parsed); returns -1 if the underlying I/O callback returns failure. -*/ -int _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status ); - -/* The worker for all scanf() type of functions. The pointer spec should point - to the introducing '%' of a conversion specifier. The status structure is to - be that of the current scanf() function, of which the member stream will be - preserved; n, i, and s will be updated; and all others will be trashed by - the function. - Returns a pointer to the first character not parsed as conversion specifier, - or NULL in case of error. - FIXME: Should distinguish between matching and input error -*/ -const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ); - -/* Parsing any fopen() style filemode string into a number of flags. */ -unsigned int _PDCLIB_filemode( const char * mode ); - -/* Sanity checking and preparing of read buffer, should be called first thing - by any stdio read-data function. - Returns 0 on success, EOF on error. - On error, EOF / error flags and errno are set appropriately. -*/ -int _PDCLIB_prepread( _PDCLIB_file_t * stream ); - -/* Sanity checking, should be called first thing by any stdio write-data - function. - Returns 0 on success, EOF on error. - On error, error flags and errno are set appropriately. -*/ -int _PDCLIB_prepwrite( _PDCLIB_file_t * stream ); - -/* Closing all streams on program exit */ -void _PDCLIB_closeall( void ); - -/* Writes a stream's buffer. - Returns 0 on success, EOF on write error. - Sets stream error flags and errno appropriately on error. -*/ -int _PDCLIB_flushbuffer( _PDCLIB_file_t * stream ); - -/* Fills a stream's buffer. - Returns 0 on success, EOF on read error / EOF. - Sets stream EOF / error flags and errno appropriately on error. -*/ -int _PDCLIB_fillbuffer( _PDCLIB_file_t * stream ); - -/* Repositions within a file. Returns new offset on success, - -1 / errno on error. -*/ -_PDCLIB_int_fast64_t _PDCLIB_seek( _PDCLIB_file_t * stream, - _PDCLIB_int_fast64_t offset, int whence ); - -/* File backend I/O operations - * - * PDCLib will call through to these methods as needed to implement the stdio - * functions. - */ -struct _PDCLIB_fileops -{ - /*! Read length bytes from the file into buf; returning the number of bytes - * actually read in *numBytesRead. - * - * Returns true if bytes were read successfully; on end of file, returns - * true with *numBytesRead == 0. - * - * On error, returns false and sets errno appropriately. *numBytesRead is - * ignored in this situation. - */ - _PDCLIB_bool (*read)( _PDCLIB_fd_t self, - void * buf, - _PDCLIB_size_t length, - _PDCLIB_size_t * numBytesRead ); - - /*! Write length bytes to the file from buf; returning the number of bytes - * actually written in *numBytesWritten - * - * Returns true if bytes were written successfully. On error, returns false - * and setss errno appropriately (as with read, *numBytesWritten is - * ignored) - */ - _PDCLIB_bool (*write)( _PDCLIB_fd_t self, const void * buf, - _PDCLIB_size_t length, _PDCLIB_size_t * numBytesWritten ); - - /* Seek to the file offset specified by offset, from location whence, which - * may be one of the standard constants SEEK_SET/SEEK_CUR/SEEK_END - */ - _PDCLIB_bool (*seek)( _PDCLIB_fd_t self, _PDCLIB_int_fast64_t offset, - int whence, _PDCLIB_int_fast64_t *newPos ); - - void (*close)( _PDCLIB_fd_t self ); - - /*! Behaves as read does, except for wide characters. Both length and - * *numCharsRead represent counts of characters, not bytes. - * - * This function is optional; if missing, PDCLib will buffer the character - * data as bytes and perform translation directly into the user's buffers. - * It is useful if your backend can directly take wide characters (for - * example, the Windows console) - */ - _PDCLIB_bool (*wread)( _PDCLIB_fd_t self, _PDCLIB_wchar_t * buf, - _PDCLIB_size_t length, _PDCLIB_size_t * numCharsRead ); - - /* Behaves as write does, except for wide characters. As with wread, both - * length and *numCharsWritten are character counts. - * - * This function is also optional; if missing, PDCLib will buffer the - * character data as bytes and do translation directly from the user's - * buffers. You only need to implement this if your backend can directly - * take wide characters (for example, the Windows console) - */ - _PDCLIB_bool (*wwrite)( _PDCLIB_fd_t self, const _PDCLIB_wchar_t * buf, - _PDCLIB_size_t length, _PDCLIB_size_t * numCharsWritten ); -}; - -/* struct _PDCLIB_file structure */ -struct _PDCLIB_file -{ - const _PDCLIB_fileops_t * ops; - _PDCLIB_fd_t handle; /* OS file handle */ - _PDCLIB_MTX_T lock; /* file lock */ - char * buffer; /* Pointer to buffer memory */ - _PDCLIB_size_t bufsize; /* Size of buffer */ - _PDCLIB_size_t bufidx; /* Index of current position in buffer */ - _PDCLIB_size_t bufend; /* Index of last pre-read character in buffer */ -#ifdef _PDCLIB_NEED_EOL_TRANSLATION - _PDCLIB_size_t bufnlexp; /* Current position of buffer newline expansion */ -#endif - _PDCLIB_size_t ungetidx; /* Number of ungetc()'ed characters */ - unsigned char * ungetbuf; /* ungetc() buffer */ - unsigned int status; /* Status flags; see above */ - /* multibyte parsing status to be added later */ - _PDCLIB_fpos_t pos; /* Offset and multibyte parsing state */ - char * filename; /* Name the current stream has been opened with */ - _PDCLIB_file_t * next; /* Pointer to next struct (internal) */ -}; - -static inline _PDCLIB_size_t _PDCLIB_getchars( char * out, _PDCLIB_size_t n, - int stopchar, - _PDCLIB_file_t * stream ) -{ - _PDCLIB_size_t i = 0; - int c; - while ( stream->ungetidx > 0 && i != n ) - { - c = (unsigned char) - ( out[ i++ ] = stream->ungetbuf[ --(stream->ungetidx) ] ); - if( c == stopchar ) - return i; - } - - while ( i != n ) - { - while ( stream->bufidx != stream->bufend && i != n) - { - c = (unsigned char) stream->buffer[ stream->bufidx++ ]; -#ifdef _PDCLIB_NEED_EOL_TRANSLATION - if ( !( stream->status & _PDCLIB_FBIN ) && c == '\r' ) - { - if ( stream->bufidx == stream->bufend ) - break; - - if ( stream->buffer[ stream->bufidx ] == '\n' ) - { - c = '\n'; - stream->bufidx++; - } - } -#endif - out[ i++ ] = c; - - if( c == stopchar ) - return i; - } - - if ( i != n ) - { - if( _PDCLIB_fillbuffer( stream ) == -1 ) - { - break; - } - } - } - -#ifdef _PDCLIB_NEED_EOL_TRANSLATION - if ( i != n && stream->bufidx != stream->bufend ) - { - // we must have EOF'd immediately after a \r - out[ i++ ] = stream->buffer[ stream->bufidx++ ]; - } -#endif - - return i; -} - -/* Unlocked functions - internal names - * - * We can't use the functions using their "normal" names internally because that - * would cause namespace leakage. Therefore, we use them by prefixed internal - * names - */ -void _PDCLIB_flockfile(struct _PDCLIB_file *file) _PDCLIB_nothrow; -int _PDCLIB_ftrylockfile(struct _PDCLIB_file *file) _PDCLIB_nothrow; -void _PDCLIB_funlockfile(struct _PDCLIB_file *file) _PDCLIB_nothrow; - -int _PDCLIB_getc_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow; -int _PDCLIB_getchar_unlocked(void) _PDCLIB_nothrow; -int _PDCLIB_putc_unlocked(int c, struct _PDCLIB_file *stream) _PDCLIB_nothrow; -int _PDCLIB_putchar_unlocked(int c) _PDCLIB_nothrow; -void _PDCLIB_clearerr_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow; -int _PDCLIB_feof_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow; -int _PDCLIB_ferror_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow; -int _PDCLIB_fflush_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow; -int _PDCLIB_fgetc_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow; -int _PDCLIB_fputc_unlocked(int c, struct _PDCLIB_file *stream) _PDCLIB_nothrow; -_PDCLIB_size_t _PDCLIB_fread_unlocked(void *ptr, _PDCLIB_size_t size, _PDCLIB_size_t n, struct _PDCLIB_file *stream) _PDCLIB_nothrow; -_PDCLIB_size_t _PDCLIB_fwrite_unlocked(const void *ptr, _PDCLIB_size_t size, _PDCLIB_size_t n, struct _PDCLIB_file *stream) _PDCLIB_nothrow; -char *_PDCLIB_fgets_unlocked(char *s, int n, struct _PDCLIB_file *stream) _PDCLIB_nothrow; -int _PDCLIB_fputs_unlocked(const char *s, struct _PDCLIB_file *stream) _PDCLIB_nothrow; -int _PDCLIB_fgetpos_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, _PDCLIB_fpos_t * _PDCLIB_restrict pos ) _PDCLIB_nothrow; -int _PDCLIB_fsetpos_unlocked( struct _PDCLIB_file * stream, const _PDCLIB_fpos_t * pos ) _PDCLIB_nothrow; -long int _PDCLIB_ftell_unlocked( struct _PDCLIB_file * stream ) _PDCLIB_nothrow; -int _PDCLIB_fseek_unlocked( struct _PDCLIB_file * stream, long int offset, int whence ) _PDCLIB_nothrow; -void _PDCLIB_rewind_unlocked( struct _PDCLIB_file * stream ) _PDCLIB_nothrow; - -int _PDCLIB_puts_unlocked( const char * s ) _PDCLIB_nothrow; -int _PDCLIB_ungetc_unlocked( int c, struct _PDCLIB_file * stream ) _PDCLIB_nothrow; - - -int _PDCLIB_printf_unlocked( const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow; -int _PDCLIB_vprintf_unlocked( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow; -int _PDCLIB_fprintf_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow; -int _PDCLIB_vfprintf_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow; -int _PDCLIB_scanf_unlocked( const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow; -int _PDCLIB_vscanf_unlocked( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow; -int _PDCLIB_fscanf_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow; -int _PDCLIB_vfscanf_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow; - -#endif diff --git a/waterbox/libc/internals/_PDCLIB_locale.h b/waterbox/libc/internals/_PDCLIB_locale.h deleted file mode 100644 index 89ed011101..0000000000 --- a/waterbox/libc/internals/_PDCLIB_locale.h +++ /dev/null @@ -1,193 +0,0 @@ -/* PDCLib locale support <_PDCLIB_locale.h> - - This file is part of the Public Domain C Library (PDCLib). - Permission is granted to use, modify, and / or redistribute at will. -*/ - -#ifndef __PDCLIB_LOCALE_H -#define __PDCLIB_LOCALE_H __PDCLIB_LOCALE_H - -#include "_PDCLIB_int.h" - -#include -#include -#include -#include - -#define _PDCLIB_LOCALE_METHOD_TSS 't' -#define _PDCLIB_LOCALE_METHOD_THREAD_LOCAL 'T' -#define _PDCLIB_LOCALE_METHOD_FAKE 'F' - -#if !defined(_PDCLIB_LOCALE_METHOD) - /* If undefined, no POSIX per thread locales */ - #define _PDCLIB_threadlocale() (&_PDCLIB_global_locale) -#elif _PDCLIB_LOCALE_METHOD == _PDCLIB_LOCALE_METHOD_TSS - extern tss_t _PDCLIB_locale_tss; - static inline locale_t _PDCLIB_threadlocale( void ) - { - locale_t l = tss_get(_PDCLIB_locale_tss); - if ( l == NULL ) - l = &_PDCLIB_global_locale; - return l; - } - - static inline void _PDCLIB_setthreadlocale( locale_t l ) - { - if ( tss_set( _PDCLIB_locale_tss, l ) != thrd_success ) - abort(); - } -#elif _PDCLIB_LOCALE_METHOD == _PDCLIB_LOCALE_METHOD_THREAD_LOCAL - extern thread_local locale_t _PDCLIB_locale_tls; - #define _PDCLIB_threadlocale() ( _PDCLIB_locale_tls || &_PDCLIB_global_locale ) - static inline locale_t _PDCLIB_threadlocale( void ) - { - locale_t l = _PDCLIB_locale_tls; - if(l == NULL) - l = &_PDCLIB_global_locale; - return l; - } - - static inline void _PDCLIB_setthreadlocale( locale_t l ) - { - _PDCLIB_locale_tls = l; - } -#elif _PDCLIB_LOCALE_METHOD == _PDCLIB_LOCALE_METHOD_FAKE - extern locale_t _PDCLIB_locale_fake; - static inline locale_t _PDCLIB_threadlocale( void ) - { - locale_t l = _PDCLIB_locale_fake; - if(l == NULL) - l = &_PDCLIB_global_locale; - return l; - } - - static inline void _PDCLIB_setthreadlocale( locale_t l ) - { - _PDCLIB_locale_fake = l; - } -#else - #error Locale TSS method unspecified -#endif - -/* -------------------------------------------------------------------------- */ -/* lookup tables */ -/* -------------------------------------------------------------------------- */ - -#define _PDCLIB_CTYPE_ALPHA 1 -#define _PDCLIB_CTYPE_BLANK 2 -#define _PDCLIB_CTYPE_CNTRL 4 -#define _PDCLIB_CTYPE_GRAPH 8 -#define _PDCLIB_CTYPE_PUNCT 16 -#define _PDCLIB_CTYPE_SPACE 32 -#define _PDCLIB_CTYPE_LOWER 64 -#define _PDCLIB_CTYPE_UPPER 128 -#define _PDCLIB_CTYPE_DIGIT 256 -#define _PDCLIB_CTYPE_XDIGT 512 - -#define _PDCLIB_WCTRANS_TOLOWER 1 -#define _PDCLIB_WCTRANS_TOUPPER 2 - -typedef struct _PDCLIB_ctype -{ - _PDCLIB_uint16_t flags; - unsigned char upper; - unsigned char lower; - unsigned char collation; -} _PDCLIB_ctype_t; - -typedef struct _PDCLIB_wcinfo -{ - _PDCLIB_wint_t start; - _PDCLIB_uint16_t length; - _PDCLIB_uint16_t flags; - _PDCLIB_wint_t lower_delta; - _PDCLIB_wint_t upper_delta; -} _PDCLIB_wcinfo_t; - -struct _PDCLIB_locale { - const struct _PDCLIB_charcodec_t * _Codec; - struct lconv _Conv; - - /* ctype / wctype */ - /* XXX: Maybe re-evaluate constness of these later on? */ - const _PDCLIB_wcinfo_t *_WCType; - _PDCLIB_size_t _WCTypeSize; - const _PDCLIB_ctype_t *_CType; - - /* perror/strerror */ - const char * const _ErrnoStr[_PDCLIB_ERRNO_MAX]; -}; - -extern const _PDCLIB_wcinfo_t _PDCLIB_wcinfo[]; -extern const size_t _PDCLIB_wcinfo_size; - -static inline int _PDCLIB_wcinfo_cmp( const void * _key, const void * _obj ) -{ - _PDCLIB_int32_t * key = (_PDCLIB_int32_t *) _key; - _PDCLIB_wcinfo_t * obj = (_PDCLIB_wcinfo_t *) _obj; - if ( *key < obj->start ) - { - return -1; - } - else if ( *key >= obj->start + obj->length ) - { - return 1; - } - else - { - return 0; - } -} - -static inline _PDCLIB_wcinfo_t * _PDCLIB_wcgetinfo( locale_t l, _PDCLIB_int32_t num ) -{ - _PDCLIB_wcinfo_t *info = (_PDCLIB_wcinfo_t*) - bsearch( &num, l->_WCType, l->_WCTypeSize, - sizeof( l->_WCType[0] ), _PDCLIB_wcinfo_cmp ); - - return info; -} - -static inline wint_t _PDCLIB_unpackwint( wint_t wc ) -{ - if( sizeof(_PDCLIB_wchar_t) == 2 && sizeof(_PDCLIB_wint_t) == 4 ) { - /* On UTF-16 platforms, as an extension accept a "packed surrogate" - * encoding. We accept the surrogate pairs either way - */ - - wint_t c = (wc & 0xF800F800); - if(c == (_PDCLIB_wint_t) 0xD800DC00) { - // MSW: Lead, LSW: Trail - wint_t lead = wc >> 16 & 0x3FF; - wint_t trail = wc & 0x3FF; - wc = lead << 10 | trail; - } else if(c == (_PDCLIB_wint_t) 0xDC00D800) { - // MSW: Trail, LSW: Lead - wint_t trail = wc >> 16 & 0x3FF; - wint_t lead = wc & 0x3FF; - wc = lead << 10 | trail; - } - - } - return wc; -} - -/* Internal xlocale-style WCType API */ -int _PDCLIB_iswalnum_l( wint_t _Wc, locale_t l ); -int _PDCLIB_iswalpha_l( wint_t _Wc, locale_t l ); -int _PDCLIB_iswblank_l( wint_t _Wc, locale_t l ); -int _PDCLIB_iswcntrl_l( wint_t _Wc, locale_t l ); -int _PDCLIB_iswdigit_l( wint_t _Wc, locale_t l ); -int _PDCLIB_iswgraph_l( wint_t _Wc, locale_t l ); -int _PDCLIB_iswlower_l( wint_t _Wc, locale_t l ); -int _PDCLIB_iswprint_l( wint_t _Wc, locale_t l ); -int _PDCLIB_iswpunct_l( wint_t _Wc, locale_t l ); -int _PDCLIB_iswspace_l( wint_t _Wc, locale_t l ); -int _PDCLIB_iswupper_l( wint_t _Wc, locale_t l ); -int _PDCLIB_iswxdigit_l( wint_t _Wc, locale_t l ); -int _PDCLIB_iswctype_l( wint_t _Wc, wctype_t _Desc, locale_t l ); -wint_t _PDCLIB_towlower_l( wint_t _Wc, locale_t l ); -wint_t _PDCLIB_towupper_l( wint_t _Wc, locale_t l ); -wint_t _PDCLIB_towctrans_l( wint_t _Wc, wctrans_t _Desc, locale_t l ); - -#endif diff --git a/waterbox/libc/internals/_PDCLIB_threadconfig.h b/waterbox/libc/internals/_PDCLIB_threadconfig.h deleted file mode 100644 index fcc3d39907..0000000000 --- a/waterbox/libc/internals/_PDCLIB_threadconfig.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _PDCLIB_THREADCONFIG_H -#define _PDCLIB_THREADCONFIG_H -#include "_PDCLIB_aux.h" -#include "_PDCLIB_config.h" - -#ifdef __cplusplus -extern "C" { -#endif -#define _PDCLIB_ONCE_FLAG_INIT 0 -#define _PDCLIB_ONCE_FLAG_IS_DONE(_f) (*(_f) == 1) -typedef char _PDCLIB_once_flag; - -void _PDCLIB_call_once(_PDCLIB_once_flag *flag, void (*func)(void)); - -#define _PDCLIB_THRD_HAVE_MISC -#define _PDCLIB_CND_T char -#define _PDCLIB_MTX_T char -#define _PDCLIB_TSS_T struct _PDCLIB_tss - -struct _PDCLIB_tss { - struct _PDCLIB_tss *self; - void *value; -}; - -#ifdef __cplusplus -} -#endif -#endif diff --git a/waterbox/libc/internals/_alias.h b/waterbox/libc/internals/_alias.h deleted file mode 100644 index 76836afeb0..0000000000 --- a/waterbox/libc/internals/_alias.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __ALIAS_H -#define __ALIAS_H -#endif - -/* Define ALIASNAME as a weak alias for NAME. - If weak aliases are not available, this defines a strong alias. */ -# define weak_alias(name, aliasname) _weak_alias (name, aliasname) -# define _weak_alias(name, aliasname) \ - extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))); diff --git a/waterbox/libco/.vscode/settings.json b/waterbox/libco/.vscode/settings.json new file mode 100644 index 0000000000..9f4c0f50d9 --- /dev/null +++ b/waterbox/libco/.vscode/settings.json @@ -0,0 +1,6 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "editor.insertSpaces": false, + "editor.detectIndentation": false, + "editor.tabSize": 4 +} \ No newline at end of file diff --git a/waterbox/libco/Makefile b/waterbox/libco/Makefile new file mode 100644 index 0000000000..a20d9ee74c --- /dev/null +++ b/waterbox/libco/Makefile @@ -0,0 +1,45 @@ +CC = x86_64-nt64-midipix-gcc +AS = nasm + +CCFLAGS:= -Wall -O3 -std=c99 +ASFLAGS:= -f elf64 + +TARGET = libco.so + +LDFLAGS = -shared + +ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) +SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.c') +ASRCS:=$(shell find $(ROOT_DIR) -type f -name '*.s') + +OBJ_DIR:=$(ROOT_DIR)/obj + +_OBJS:=$(SRCS:.c=.c.o) +OBJS:=$(patsubst $(ROOT_DIR)%,$(OBJ_DIR)%,$(_OBJS)) +_AOBJS:=$(ASRCS:.s=.s.o) +AOBJS:=$(patsubst $(ROOT_DIR)%,$(OBJ_DIR)%,$(_AOBJS)) + +$(OBJ_DIR)/%.c.o: %.c + @mkdir -p $(@D) + @$(CC) -c -o $@ $< $(CCFLAGS) + +$(OBJ_DIR)/%.s.o: %.s + @mkdir -p $(@D) + @$(AS) $(ASFLAGS) -o $@ $< + +all: $(TARGET) + +.PHONY: clean all + +$(TARGET): $(OBJS) $(AOBJS) + @$(CC) -o $@ $(LDFLAGS) $(CCFLAGS) $(OBJS) $(AOBJS) + @mv $(TARGET) $(TARGET).in + @strip $(TARGET).in -o $(TARGET) -R /4 -R /14 -R /29 -R /41 -R /55 -R /67 -R /78 -R /89 -R /104 + +clean: + @rm -rf $(OBJ_DIR) + @rm -f $(TARGET).in + @rm -f $(TARGET) + +#install: +# $(CP) $(TARGET) $(DEST_$(ARCH)) diff --git a/waterbox/libco/amd64.c b/waterbox/libco/amd64.c new file mode 100644 index 0000000000..94c8e98d63 --- /dev/null +++ b/waterbox/libco/amd64.c @@ -0,0 +1,100 @@ +/* + libco.amd64 (2016-09-14) + author: byuu + license: public domain +*/ + +#define LIBCO_C +#include "libco.h" + +#include +#include +#include +#include +#include + +static long long co_active_buffer[64]; +static cothread_t co_active_handle = 0; + +// allocations are 16k larger than asked for, +// and include guard space between the stack and the storage + +static void* alloc_thread(size_t* size) +{ + // align up to 4k + *size = (*size + 16384 + 4095) & ~4095; + + uint64_t* ptr = mmap(NULL, *size, + PROT_READ | PROT_WRITE, MAP_ANONYMOUS, -1, 0); + if (ptr == (uint64_t*)(-1)) + return NULL; + + ptr[512] = *size; + for (int i = 513; i < 2048; i++) + ptr[i] = 0xdeadbeefdeadbeef; + + if (mprotect(ptr + 512, 512 * 3 * sizeof(uint64_t), PROT_NONE) != 0) + abort(); + + return ptr; +} + +static void free_thread(void* p) +{ + uint64_t* ptr = (uint64_t*)p; + if (mprotect(ptr + 512, 512 * 3 * sizeof(uint64_t), PROT_READ | PROT_WRITE) != 0) + abort(); + uint64_t size = ptr[512]; + memset(p, 0, size); + if (munmap(ptr, size) != 0) + abort(); +} + +extern void co_swap(cothread_t, cothread_t); + +static void crash() +{ + assert(0); /* called only if cothread_t entrypoint returns */ +} + +void co_clean() +{ + memset(co_active_buffer, 0, sizeof(co_active_buffer)); +} + +cothread_t co_active() +{ + if (!co_active_handle) + co_active_handle = &co_active_buffer; + return co_active_handle; +} + +cothread_t co_create(unsigned int sz, void (*entrypoint)(void)) +{ + cothread_t handle; + if (!co_active_handle) + co_active_handle = &co_active_buffer; + + uint64_t size = sz; + + if (handle = (cothread_t)alloc_thread(&size)) + { + uint64_t* p = (uint64_t*)((char*)handle + size); // seek to top of stack + *--p = (uint64_t)crash; /* crash if entrypoint returns */ + *--p = (uint64_t)entrypoint; /* start of function */ + *(uint64_t*)handle = (uint64_t)p; /* stack pointer */ + } + + return handle; +} + +void co_delete(cothread_t handle) +{ + free_thread(handle); +} + +void co_switch(cothread_t handle) +{ + register cothread_t co_previous_handle = co_active_handle; + co_swap(co_active_handle = handle, co_previous_handle); +} diff --git a/waterbox/libco/coswap.s b/waterbox/libco/coswap.s new file mode 100644 index 0000000000..e9660c462c --- /dev/null +++ b/waterbox/libco/coswap.s @@ -0,0 +1,57 @@ +section .text + global co_swap + global __imp_co_swap + +; TODO: how to tell GCC it doesn't need this? +align 16 +__imp_co_swap: + dq co_swap + +align 16 +co_swap: + mov [rdx],rsp + mov rsp,[rcx] + pop rax + mov [rdx+ 8],rbp + mov [rdx+16],rsi + mov [rdx+24],rdi + mov [rdx+32],rbx + mov [rdx+40],r12 + mov [rdx+48],r13 + mov [rdx+56],r14 + mov [rdx+64],r15 +;#if !defined(LIBCO_NO_SSE) + movaps [rdx+ 80],xmm6 + movaps [rdx+ 96],xmm7 + movaps [rdx+112],xmm8 + add rdx,112 + movaps [rdx+ 16],xmm9 + movaps [rdx+ 32],xmm10 + movaps [rdx+ 48],xmm11 + movaps [rdx+ 64],xmm12 + movaps [rdx+ 80],xmm13 + movaps [rdx+ 96],xmm14 + movaps [rdx+112],xmm15 +;#endif + mov rbp,[rcx+ 8] + mov rsi,[rcx+16] + mov rdi,[rcx+24] + mov rbx,[rcx+32] + mov r12,[rcx+40] + mov r13,[rcx+48] + mov r14,[rcx+56] + mov r15,[rcx+64] +;#if !defined(LIBCO_NO_SSE) + movaps xmm6, [rcx+ 80] + movaps xmm7, [rcx+ 96] + movaps xmm8, [rcx+112] + add rcx,112 + movaps xmm9, [rcx+ 16] + movaps xmm10,[rcx+ 32] + movaps xmm11,[rcx+ 48] + movaps xmm12,[rcx+ 64] + movaps xmm13,[rcx+ 80] + movaps xmm14,[rcx+ 96] + movaps xmm15,[rcx+112] +;#endif + jmp rax diff --git a/waterbox/libco/doc/style.css b/waterbox/libco/doc/style.css new file mode 100644 index 0000000000..5181afde6c --- /dev/null +++ b/waterbox/libco/doc/style.css @@ -0,0 +1,8 @@ +body { + background: #333; + color: #fff; +} + +code { + background: #444; +} diff --git a/waterbox/libco/doc/targets.html b/waterbox/libco/doc/targets.html new file mode 100644 index 0000000000..d6211a15d7 --- /dev/null +++ b/waterbox/libco/doc/targets.html @@ -0,0 +1,89 @@ + + + + + + + +Supported targets:

+ +Note that supported targets are only those that have been tested and confirmed +working. It is quite possible that libco will work on more processors, compilers +and operating systems than those listed below. +
+ +libco.x86
+Overhead: ~5x
+Supported processor(s): 32-bit x86
+Supported compiler(s): any
+Supported operating system(s):
    +
  • Windows
  • +
  • Mac OS X
  • +
  • Linux
  • +
  • BSD
  • +
+
+ +libco.amd64
+Overhead: ~10x (Windows), ~6x (all other platforms)
+Supported processor(s): 64-bit amd64
+Supported compiler(s): any
+Supported operating system(s):
    +
  • Windows
  • +
  • Mac OS X
  • +
  • Linux
  • +
  • BSD
  • +
+
+ +libco.ppc
+Overhead: ~20x
+Supported processor(s): 32-bit PowerPC, 64-bit PowerPC
+Supported compiler(s): GNU GCC
+Supported operating system(s):
    +
+
  • Mac OS X
  • +
  • Linux
  • +
  • BSD
  • +
  • Playstation 3
  • + +
    + +Note: this module contains compiler flags to enable/disable FPU and Altivec +support. + +
    + +libco.fiber
    +Overhead: ~15x
    +Supported processor(s): Processor independent
    +Supported compiler(s): any
    +Supported operating system(s):
      +
    • Windows
    • +
    +
    + +libco.sjlj
    +Overhead: ~30x
    +Supported processor(s): Processor independent
    +Supported compiler(s): any
    +Supported operating system(s):
      +
    • Mac OS X
    • +
    • Linux
    • +
    • BSD
    • +
    • Solaris
    • +
    +
    + +libco.ucontext
    +Overhead: ~300x
    +Supported processor(s): Processor independent
    +Supported compiler(s): any
    +Supported operating system(s):
      +
    • Linux
    • +
    • BSD
    • +
    +
    + + + diff --git a/waterbox/libco/doc/usage.html b/waterbox/libco/doc/usage.html new file mode 100644 index 0000000000..3f0d81ccd8 --- /dev/null +++ b/waterbox/libco/doc/usage.html @@ -0,0 +1,107 @@ + + + + + + + +License:

    +libco is released to the public domain. +
    + +Contact:

    +At present, you may contact me at setsunakun0 at hotmail dot com.
    +I am interested in knowing of any projects that make use of this library, +though this is only a courtesy. +
    + +Foreword:

    +libco is a cross-platform, public domain implementation of +cooperative-multithreading; a feature that is sorely lacking +from the ISO C/C++ standard.
    +The library is designed for maximum speed and portability, and +not for safety or features. If safety or extra functionality is desired, +a wrapper API can easily be written to encapsulate all library functions.
    +Behavior of executing operations that are listed as not permitted +below result in undefined behavior. They may work anyway, they +may cause undesired / unknown behavior, or they may crash the +program entirely.
    +The goal of this library was to simplify the base API as much as possible, +implementing only that which cannot be implemented using pure C. Additional +functionality after this would only complicate ports of this library to new +platforms. +
    + +Porting:

    +This document is included as a reference for porting libco. Please submit any +ports you create to me, so that libco can become more useful. Please note that +since libco is public domain, you must submit your code as a work of the +public domain in order for it to be included in the official distribution. +Full credit will be given in the source code of the official release. Please +do not bother submitting code to me under any other license -- including GPL, +LGPL, BSD or CC -- I am not interested in creating a library with multiple +different licenses depending on which targets are used. +
    + +Synopsis:

    + +typedef void* cothread_t;
    +
    +cothread_t co_active();
    +cothread_t co_create(unsigned int heapsize, void (*coentry)(void));
    +void       co_delete(cothread_t cothread);
    +void       co_switch(cothread_t cothread);
    +
    +
    + +Usage: +
    + +typedef void* cothread_t;

    +Handle to cothread.
    +Handle must be of type void*.
    +A value of null (0) indicates an uninitialized or invalid +handle, whereas a non-zero value indicates a valid handle. +
    + +cothread_t co_active();

    +Return handle to current cothread. Always returns a valid handle, even when +called from the main program thread. +
    + +cothread_t co_create(unsigned int heapsize, void (*coentry)(void));

    +Create new cothread.
    +Heapsize is the amount of memory allocated for the cothread stack, specified +in bytes. This is unfortunately impossible to make fully portable. It is +recommended to specify sizes using `n * sizeof(void*)'. It is better to err +on the side of caution and allocate more memory than will be needed to ensure +compatibility with other platforms, within reason. A typical heapsize for a +32-bit architecture is ~1MB.
    +When the new cothread is first called, program execution jumps to coentry. +This function does not take any arguments, due to portability issues with +passing function arguments. However, arguments can be simulated by the use +of global variables, which can be set before the first call to each cothread.
    +coentry() must not return, and should end with an appropriate co_switch() +statement. Behavior is undefined if entry point returns normally.
    +Library is responsible for allocating cothread stack memory, to free +the user from needing to allocate special memory capable of being used +as program stack memory on platforms where this is required.
    +User is always responsible for deleting cothreads with co_delete().
    +Return value of null (0) indicates cothread creation failed. +
    + +void co_delete(cothread_t cothread);

    +Delete specified cothread.
    +Null (0) or invalid cothread handle is not allowed.
    +Passing handle of active cothread to this function is not allowed.
    +Passing handle of primary cothread is not allowed. +
    + +void co_switch(cothread_t cothread);

    +Switch to specified cothread.
    +Null (0) or invalid cothread handle is not allowed.
    +Passing handle of active cothread to this function is not allowed. +
    + + + diff --git a/waterbox/libco/libco.h b/waterbox/libco/libco.h new file mode 100644 index 0000000000..792df0bd24 --- /dev/null +++ b/waterbox/libco/libco.h @@ -0,0 +1,26 @@ +/* + libco v18 (2016-09-14) + author: byuu + license: public domain +*/ + +#ifndef LIBCO_H +#define LIBCO_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* cothread_t; + +cothread_t co_active(); +cothread_t co_create(unsigned int, void (*)(void)); +void co_delete(cothread_t); +void co_switch(cothread_t); + +#ifdef __cplusplus +} +#endif + +/* ifndef LIBCO_H */ +#endif diff --git a/waterbox/libco/libco.so b/waterbox/libco/libco.so new file mode 100644 index 0000000000..b2055be1e7 Binary files /dev/null and b/waterbox/libco/libco.so differ diff --git a/waterbox/libsnes/.vscode/settings.json b/waterbox/libsnes/.vscode/settings.json new file mode 100644 index 0000000000..320669d7d4 --- /dev/null +++ b/waterbox/libsnes/.vscode/settings.json @@ -0,0 +1,42 @@ +{ + "files.associations": { + "ostream": "cpp", + "algorithm": "cpp", + "cmath": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "cwchar": "cpp", + "deque": "cpp", + "exception": "cpp", + "initializer_list": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "limits": "cpp", + "memory": "cpp", + "new": "cpp", + "queue": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "string": "cpp", + "system_error": "cpp", + "type_traits": "cpp", + "typeinfo": "cpp", + "utility": "cpp", + "vector": "cpp", + "xfacet": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocinfo": "cpp", + "xlocnum": "cpp", + "xmemory": "cpp", + "xmemory0": "cpp", + "xstddef": "cpp", + "xstring": "cpp", + "xtr1common": "cpp", + "xutility": "cpp" + } +} \ No newline at end of file diff --git a/libsnes/0.87 b/waterbox/libsnes/0.87 similarity index 100% rename from libsnes/0.87 rename to waterbox/libsnes/0.87 diff --git a/waterbox/libsnes/Makefile b/waterbox/libsnes/Makefile new file mode 100644 index 0000000000..ebeda7f946 --- /dev/null +++ b/waterbox/libsnes/Makefile @@ -0,0 +1,100 @@ +CC = x86_64-nt64-midipix-g++ + + # -Werror=pointer-to-int-cast -Werror=int-to-pointer-cast + #-std=c99 -fomit-frame-pointer -fvisibility=hidden + #-DPROFILE_PERFORMANCE + #-fno-exceptions -fno-rtti +CCFLAGS:= -DHOOKS -DBIZHAWK -DPROFILE_COMPATIBILITY -DGAMEBOY \ + -D_GNU_SOURCE \ + -Werror=pointer-to-int-cast -Werror=int-to-pointer-cast \ + -I../emulibc -I../libco -I./bsnes \ + -Wall -Werror=implicit-function-declaration \ + -Wno-parentheses -Wno-sign-compare \ + -Wno-unused-variable -Wno-unused-function \ + -fvisibility=hidden \ + -fno-threadsafe-statics \ + -std=c++0x \ + -O3 -flto + +TARGET = libsnes.wbx + +LDFLAGS = -Wl,--dynamicbase,--export-all-symbols + +ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) + +SRCS_PERF:= \ + $(ROOT_DIR)/bsnes/snes/alt/cpu/cpu.cpp \ + $(ROOT_DIR)/bsnes/snes/alt/ppu-performance/ppu.cpp \ + $(ROOT_DIR)/bsnes/snes/alt/smp/smp.cpp +SRCS_COMPAT:= \ + $(ROOT_DIR)/bsnes/snes/alt/ppu-compatibility/ppu.cpp \ + $(ROOT_DIR)/bsnes/snes/cpu/cpu.cpp \ + $(ROOT_DIR)/bsnes/snes/smp/smp.cpp +SRCS_ALL:= \ + $(ROOT_DIR)/bsnes/base/base.cpp \ + $(ROOT_DIR)/bsnes/gameboy/apu/apu.cpp \ + $(ROOT_DIR)/bsnes/gameboy/cartridge/cartridge.cpp \ + $(ROOT_DIR)/bsnes/gameboy/cpu/cpu.cpp \ + $(ROOT_DIR)/bsnes/snes/alt/dsp/dsp.cpp \ + $(ROOT_DIR)/bsnes/gameboy/interface/interface.cpp \ + $(ROOT_DIR)/bsnes/gameboy/lcd/lcd.cpp \ + $(ROOT_DIR)/bsnes/gameboy/memory/memory.cpp \ + $(ROOT_DIR)/bsnes/gameboy/scheduler/scheduler.cpp \ + $(ROOT_DIR)/bsnes/gameboy/system/system.cpp \ + $(ROOT_DIR)/bsnes/gameboy/video/video.cpp \ + $(ROOT_DIR)/bsnes/snes/cartridge/cartridge.cpp \ + $(ROOT_DIR)/bsnes/snes/chip/armdsp/armdsp.cpp \ + $(ROOT_DIR)/bsnes/snes/chip/bsx/bsx.cpp \ + $(ROOT_DIR)/bsnes/snes/chip/hitachidsp/hitachidsp.cpp \ + $(ROOT_DIR)/bsnes/snes/chip/icd2/icd2.cpp \ + $(ROOT_DIR)/bsnes/snes/chip/link/link.cpp \ + $(ROOT_DIR)/bsnes/snes/chip/msu1/msu1.cpp \ + $(ROOT_DIR)/bsnes/snes/chip/necdsp/necdsp.cpp \ + $(ROOT_DIR)/bsnes/snes/chip/nss/nss.cpp \ + $(ROOT_DIR)/bsnes/snes/chip/obc1/obc1.cpp \ + $(ROOT_DIR)/bsnes/snes/chip/sa1/sa1.cpp \ + $(ROOT_DIR)/bsnes/snes/chip/sdd1/sdd1.cpp \ + $(ROOT_DIR)/bsnes/snes/chip/spc7110/spc7110.cpp \ + $(ROOT_DIR)/bsnes/snes/chip/srtc/srtc.cpp \ + $(ROOT_DIR)/bsnes/snes/chip/sufamiturbo/sufamiturbo.cpp \ + $(ROOT_DIR)/bsnes/snes/chip/superfx/superfx.cpp \ + $(ROOT_DIR)/bsnes/snes/config/config.cpp \ + $(ROOT_DIR)/bsnes/snes/controller/controller.cpp \ + $(ROOT_DIR)/bsnes/snes/cpu/core/core.cpp \ + $(ROOT_DIR)/bsnes/snes/interface/interface.cpp \ + $(ROOT_DIR)/bsnes/snes/memory/memory.cpp \ + $(ROOT_DIR)/bsnes/snes/smp/core/core.cpp \ + $(ROOT_DIR)/bsnes/snes/system/system.cpp \ + $(ROOT_DIR)/bsnes/target-libsnes/libsnes.cpp \ + $(ROOT_DIR)/bsnes/target-libsnes/libsnes_pwrap.cpp +SRCS:=$(SRCS_ALL) $(SRCS_COMPAT) + +OBJ_DIR:=$(ROOT_DIR)/obj + +_OBJS:=$(SRCS:.cpp=.o) +OBJS:=$(patsubst $(ROOT_DIR)%,$(OBJ_DIR)%,$(_OBJS)) + +$(OBJ_DIR)/%.o: $(ROOT_DIR)/%.cpp + @mkdir -p $(@D) + @$(CC) -c -o $@ $< $(CCFLAGS) + +all: $(TARGET) + +.PHONY: clean all + +$(TARGET).in: $(OBJS) + @$(CC) -o $@ $(LDFLAGS) $(CCFLAGS) $(OBJS) ../emulibc/libemuhost.so ../libco/libco.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) + +print-%: + @echo $* = $($*) +#install: +# $(CP) $(TARGET) $(DEST_$(ARCH)) diff --git a/libsnes/bsnes/base/base.cpp b/waterbox/libsnes/bsnes/base/base.cpp similarity index 100% rename from libsnes/bsnes/base/base.cpp rename to waterbox/libsnes/bsnes/base/base.cpp diff --git a/libsnes/bsnes/base/base.hpp b/waterbox/libsnes/bsnes/base/base.hpp similarity index 99% rename from libsnes/bsnes/base/base.hpp rename to waterbox/libsnes/bsnes/base/base.hpp index f8faddb474..96865d5348 100644 --- a/libsnes/bsnes/base/base.hpp +++ b/waterbox/libsnes/bsnes/base/base.hpp @@ -16,7 +16,6 @@ const char Version[] = "087"; #include #include #include -#include #include #include #include diff --git a/libsnes/bsnes/gameboy/apu/apu.cpp b/waterbox/libsnes/bsnes/gameboy/apu/apu.cpp similarity index 99% rename from libsnes/bsnes/gameboy/apu/apu.cpp rename to waterbox/libsnes/bsnes/gameboy/apu/apu.cpp index be3a4e7795..25cd2bc393 100644 --- a/libsnes/bsnes/gameboy/apu/apu.cpp +++ b/waterbox/libsnes/bsnes/gameboy/apu/apu.cpp @@ -8,7 +8,6 @@ namespace GameBoy { #include "wave/wave.cpp" #include "noise/noise.cpp" #include "master/master.cpp" -#include "serialization.cpp" APU apu; void APU::Main() { diff --git a/libsnes/bsnes/gameboy/apu/apu.hpp b/waterbox/libsnes/bsnes/gameboy/apu/apu.hpp similarity index 93% rename from libsnes/bsnes/gameboy/apu/apu.hpp rename to waterbox/libsnes/bsnes/gameboy/apu/apu.hpp index 7218415c67..b33f6cf6f2 100644 --- a/libsnes/bsnes/gameboy/apu/apu.hpp +++ b/waterbox/libsnes/bsnes/gameboy/apu/apu.hpp @@ -21,8 +21,6 @@ struct APU : Processor, MMIO { uint8 mmio_read(uint16 addr); void mmio_write(uint16 addr, uint8 data); - - void serialize(serializer&); }; extern APU apu; diff --git a/libsnes/bsnes/gameboy/apu/master/master.cpp b/waterbox/libsnes/bsnes/gameboy/apu/master/master.cpp similarity index 85% rename from libsnes/bsnes/gameboy/apu/master/master.cpp rename to waterbox/libsnes/bsnes/gameboy/apu/master/master.cpp index bd0a247e18..40414a59ec 100644 --- a/libsnes/bsnes/gameboy/apu/master/master.cpp +++ b/waterbox/libsnes/bsnes/gameboy/apu/master/master.cpp @@ -96,24 +96,4 @@ void APU::Master::power() { right = 0; } -void APU::Master::serialize(serializer &s) { - s.integer(left_in_enable); - s.integer(left_volume); - s.integer(right_in_enable); - s.integer(right_volume); - s.integer(channel4_left_enable); - s.integer(channel3_left_enable); - s.integer(channel2_left_enable); - s.integer(channel1_left_enable); - s.integer(channel4_right_enable); - s.integer(channel3_right_enable); - s.integer(channel2_right_enable); - s.integer(channel1_right_enable); - s.integer(enable); - - s.integer(center); - s.integer(left); - s.integer(right); -} - #endif diff --git a/libsnes/bsnes/gameboy/apu/master/master.hpp b/waterbox/libsnes/bsnes/gameboy/apu/master/master.hpp similarity index 93% rename from libsnes/bsnes/gameboy/apu/master/master.hpp rename to waterbox/libsnes/bsnes/gameboy/apu/master/master.hpp index 31a1e9f0f7..da0212ee85 100644 --- a/libsnes/bsnes/gameboy/apu/master/master.hpp +++ b/waterbox/libsnes/bsnes/gameboy/apu/master/master.hpp @@ -20,5 +20,4 @@ struct Master { void run(); void write(unsigned r, uint8 data); void power(); - void serialize(serializer&); }; diff --git a/libsnes/bsnes/gameboy/apu/noise/noise.cpp b/waterbox/libsnes/bsnes/gameboy/apu/noise/noise.cpp similarity index 82% rename from libsnes/bsnes/gameboy/apu/noise/noise.cpp rename to waterbox/libsnes/bsnes/gameboy/apu/noise/noise.cpp index c0def117cc..e97546bf19 100644 --- a/libsnes/bsnes/gameboy/apu/noise/noise.cpp +++ b/waterbox/libsnes/bsnes/gameboy/apu/noise/noise.cpp @@ -86,23 +86,4 @@ void APU::Noise::power() { lfsr = 0; } -void APU::Noise::serialize(serializer &s) { - s.integer(enable); - - s.integer(envelope_volume); - s.integer(envelope_direction); - s.integer(envelope_frequency); - s.integer(frequency); - s.integer(narrow_lfsr); - s.integer(divisor); - s.integer(counter); - - s.integer(output); - s.integer(length); - s.integer(envelope_period); - s.integer(volume); - s.integer(period); - s.integer(lfsr); -} - #endif diff --git a/libsnes/bsnes/gameboy/apu/noise/noise.hpp b/waterbox/libsnes/bsnes/gameboy/apu/noise/noise.hpp similarity index 93% rename from libsnes/bsnes/gameboy/apu/noise/noise.hpp rename to waterbox/libsnes/bsnes/gameboy/apu/noise/noise.hpp index f92efbf3e4..822de6a80c 100644 --- a/libsnes/bsnes/gameboy/apu/noise/noise.hpp +++ b/waterbox/libsnes/bsnes/gameboy/apu/noise/noise.hpp @@ -23,5 +23,4 @@ struct Noise { void clock_envelope(); void write(unsigned r, uint8 data); void power(); - void serialize(serializer&); }; diff --git a/libsnes/bsnes/gameboy/apu/square1/square1.cpp b/waterbox/libsnes/bsnes/gameboy/apu/square1/square1.cpp similarity index 84% rename from libsnes/bsnes/gameboy/apu/square1/square1.cpp rename to waterbox/libsnes/bsnes/gameboy/apu/square1/square1.cpp index 0a9e0132eb..2b05b9c4a7 100644 --- a/libsnes/bsnes/gameboy/apu/square1/square1.cpp +++ b/waterbox/libsnes/bsnes/gameboy/apu/square1/square1.cpp @@ -131,30 +131,4 @@ void APU::Square1::power() { volume = 0; } -void APU::Square1::serialize(serializer &s) { - s.integer(enable); - - s.integer(sweep_frequency); - s.integer(sweep_direction); - s.integer(sweep_shift); - s.integer(sweep_negate); - s.integer(duty); - s.integer(length); - s.integer(envelope_volume); - s.integer(envelope_direction); - s.integer(envelope_frequency); - s.integer(frequency); - s.integer(counter); - - s.integer(output); - s.integer(duty_output); - s.integer(phase); - s.integer(period); - s.integer(envelope_period); - s.integer(sweep_period); - s.integer(frequency_shadow); - s.integer(sweep_enable); - s.integer(volume); -} - #endif diff --git a/libsnes/bsnes/gameboy/apu/square1/square1.hpp b/waterbox/libsnes/bsnes/gameboy/apu/square1/square1.hpp similarity index 95% rename from libsnes/bsnes/gameboy/apu/square1/square1.hpp rename to waterbox/libsnes/bsnes/gameboy/apu/square1/square1.hpp index 2b45676f6c..07d1ab0ac9 100644 --- a/libsnes/bsnes/gameboy/apu/square1/square1.hpp +++ b/waterbox/libsnes/bsnes/gameboy/apu/square1/square1.hpp @@ -32,5 +32,4 @@ struct Square1 { void clock_envelope(); void write(unsigned r, uint8 data); void power(); - void serialize(serializer&); }; diff --git a/libsnes/bsnes/gameboy/apu/square2/square2.cpp b/waterbox/libsnes/bsnes/gameboy/apu/square2/square2.cpp similarity index 83% rename from libsnes/bsnes/gameboy/apu/square2/square2.cpp rename to waterbox/libsnes/bsnes/gameboy/apu/square2/square2.cpp index 09e5067890..18713c51fb 100644 --- a/libsnes/bsnes/gameboy/apu/square2/square2.cpp +++ b/waterbox/libsnes/bsnes/gameboy/apu/square2/square2.cpp @@ -88,23 +88,4 @@ void APU::Square2::power() { volume = 0; } -void APU::Square2::serialize(serializer &s) { - s.integer(enable); - - s.integer(duty); - s.integer(length); - s.integer(envelope_volume); - s.integer(envelope_direction); - s.integer(envelope_frequency); - s.integer(frequency); - s.integer(counter); - - s.integer(output); - s.integer(duty_output); - s.integer(phase); - s.integer(period); - s.integer(envelope_period); - s.integer(volume); -} - #endif diff --git a/libsnes/bsnes/gameboy/apu/square2/square2.hpp b/waterbox/libsnes/bsnes/gameboy/apu/square2/square2.hpp similarity index 93% rename from libsnes/bsnes/gameboy/apu/square2/square2.hpp rename to waterbox/libsnes/bsnes/gameboy/apu/square2/square2.hpp index 0a473348ea..4d0d2b730c 100644 --- a/libsnes/bsnes/gameboy/apu/square2/square2.hpp +++ b/waterbox/libsnes/bsnes/gameboy/apu/square2/square2.hpp @@ -23,5 +23,4 @@ struct Square2 { void clock_envelope(); void write(unsigned r, uint8 data); void power(); - void serialize(serializer&); }; diff --git a/libsnes/bsnes/gameboy/apu/wave/wave.cpp b/waterbox/libsnes/bsnes/gameboy/apu/wave/wave.cpp similarity index 84% rename from libsnes/bsnes/gameboy/apu/wave/wave.cpp rename to waterbox/libsnes/bsnes/gameboy/apu/wave/wave.cpp index 498cd8f643..5ab9cb1c03 100644 --- a/libsnes/bsnes/gameboy/apu/wave/wave.cpp +++ b/waterbox/libsnes/bsnes/gameboy/apu/wave/wave.cpp @@ -80,20 +80,4 @@ void APU::Wave::power() { pattern_sample = 0; } -void APU::Wave::serialize(serializer &s) { - s.integer(enable); - - s.integer(dac_enable); - s.integer(volume_shift); - s.integer(frequency); - s.integer(counter); - s.array(pattern); - - s.integer(output); - s.integer(length); - s.integer(period); - s.integer(pattern_offset); - s.integer(pattern_sample); -} - #endif diff --git a/libsnes/bsnes/gameboy/apu/wave/wave.hpp b/waterbox/libsnes/bsnes/gameboy/apu/wave/wave.hpp similarity index 92% rename from libsnes/bsnes/gameboy/apu/wave/wave.hpp rename to waterbox/libsnes/bsnes/gameboy/apu/wave/wave.hpp index 7f8d65d337..cc70043b74 100644 --- a/libsnes/bsnes/gameboy/apu/wave/wave.hpp +++ b/waterbox/libsnes/bsnes/gameboy/apu/wave/wave.hpp @@ -18,5 +18,4 @@ struct Wave { void write(unsigned r, uint8 data); void write_pattern(unsigned p, uint8 data); void power(); - void serialize(serializer&); }; diff --git a/libsnes/bsnes/gameboy/cartridge/cartridge.cpp b/waterbox/libsnes/bsnes/gameboy/cartridge/cartridge.cpp similarity index 99% rename from libsnes/bsnes/gameboy/cartridge/cartridge.cpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/cartridge.cpp index 910d454bee..16555dafc4 100644 --- a/libsnes/bsnes/gameboy/cartridge/cartridge.cpp +++ b/waterbox/libsnes/bsnes/gameboy/cartridge/cartridge.cpp @@ -13,7 +13,6 @@ namespace GameBoy { #include "mmm01/mmm01.cpp" #include "huc1/huc1.cpp" #include "huc3/huc3.cpp" -#include "serialization.cpp" Cartridge cartridge; void Cartridge::load(System::Revision revision, const string &markup, const uint8_t *data, unsigned size) { diff --git a/libsnes/bsnes/gameboy/cartridge/cartridge.hpp b/waterbox/libsnes/bsnes/gameboy/cartridge/cartridge.hpp similarity index 97% rename from libsnes/bsnes/gameboy/cartridge/cartridge.hpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/cartridge.hpp index d7e4c2a534..568ae8307c 100644 --- a/libsnes/bsnes/gameboy/cartridge/cartridge.hpp +++ b/waterbox/libsnes/bsnes/gameboy/cartridge/cartridge.hpp @@ -58,7 +58,6 @@ struct Cartridge : MMIO, property { void power(); - void serialize(serializer&); Cartridge(); ~Cartridge(); }; diff --git a/libsnes/bsnes/gameboy/cartridge/huc1/huc1.cpp b/waterbox/libsnes/bsnes/gameboy/cartridge/huc1/huc1.cpp similarity index 100% rename from libsnes/bsnes/gameboy/cartridge/huc1/huc1.cpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/huc1/huc1.cpp diff --git a/libsnes/bsnes/gameboy/cartridge/huc1/huc1.hpp b/waterbox/libsnes/bsnes/gameboy/cartridge/huc1/huc1.hpp similarity index 100% rename from libsnes/bsnes/gameboy/cartridge/huc1/huc1.hpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/huc1/huc1.hpp diff --git a/libsnes/bsnes/gameboy/cartridge/huc3/huc3.cpp b/waterbox/libsnes/bsnes/gameboy/cartridge/huc3/huc3.cpp similarity index 100% rename from libsnes/bsnes/gameboy/cartridge/huc3/huc3.cpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/huc3/huc3.cpp diff --git a/libsnes/bsnes/gameboy/cartridge/huc3/huc3.hpp b/waterbox/libsnes/bsnes/gameboy/cartridge/huc3/huc3.hpp similarity index 100% rename from libsnes/bsnes/gameboy/cartridge/huc3/huc3.hpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/huc3/huc3.hpp diff --git a/libsnes/bsnes/gameboy/cartridge/mbc0/mbc0.cpp b/waterbox/libsnes/bsnes/gameboy/cartridge/mbc0/mbc0.cpp similarity index 100% rename from libsnes/bsnes/gameboy/cartridge/mbc0/mbc0.cpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/mbc0/mbc0.cpp diff --git a/libsnes/bsnes/gameboy/cartridge/mbc0/mbc0.hpp b/waterbox/libsnes/bsnes/gameboy/cartridge/mbc0/mbc0.hpp similarity index 100% rename from libsnes/bsnes/gameboy/cartridge/mbc0/mbc0.hpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/mbc0/mbc0.hpp diff --git a/libsnes/bsnes/gameboy/cartridge/mbc1/mbc1.cpp b/waterbox/libsnes/bsnes/gameboy/cartridge/mbc1/mbc1.cpp similarity index 100% rename from libsnes/bsnes/gameboy/cartridge/mbc1/mbc1.cpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/mbc1/mbc1.cpp diff --git a/libsnes/bsnes/gameboy/cartridge/mbc1/mbc1.hpp b/waterbox/libsnes/bsnes/gameboy/cartridge/mbc1/mbc1.hpp similarity index 100% rename from libsnes/bsnes/gameboy/cartridge/mbc1/mbc1.hpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/mbc1/mbc1.hpp diff --git a/libsnes/bsnes/gameboy/cartridge/mbc2/mbc2.cpp b/waterbox/libsnes/bsnes/gameboy/cartridge/mbc2/mbc2.cpp similarity index 100% rename from libsnes/bsnes/gameboy/cartridge/mbc2/mbc2.cpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/mbc2/mbc2.cpp diff --git a/libsnes/bsnes/gameboy/cartridge/mbc2/mbc2.hpp b/waterbox/libsnes/bsnes/gameboy/cartridge/mbc2/mbc2.hpp similarity index 100% rename from libsnes/bsnes/gameboy/cartridge/mbc2/mbc2.hpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/mbc2/mbc2.hpp diff --git a/libsnes/bsnes/gameboy/cartridge/mbc3/mbc3.cpp b/waterbox/libsnes/bsnes/gameboy/cartridge/mbc3/mbc3.cpp similarity index 100% rename from libsnes/bsnes/gameboy/cartridge/mbc3/mbc3.cpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/mbc3/mbc3.cpp diff --git a/libsnes/bsnes/gameboy/cartridge/mbc3/mbc3.hpp b/waterbox/libsnes/bsnes/gameboy/cartridge/mbc3/mbc3.hpp similarity index 100% rename from libsnes/bsnes/gameboy/cartridge/mbc3/mbc3.hpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/mbc3/mbc3.hpp diff --git a/libsnes/bsnes/gameboy/cartridge/mbc5/mbc5.cpp b/waterbox/libsnes/bsnes/gameboy/cartridge/mbc5/mbc5.cpp similarity index 100% rename from libsnes/bsnes/gameboy/cartridge/mbc5/mbc5.cpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/mbc5/mbc5.cpp diff --git a/libsnes/bsnes/gameboy/cartridge/mbc5/mbc5.hpp b/waterbox/libsnes/bsnes/gameboy/cartridge/mbc5/mbc5.hpp similarity index 100% rename from libsnes/bsnes/gameboy/cartridge/mbc5/mbc5.hpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/mbc5/mbc5.hpp diff --git a/libsnes/bsnes/gameboy/cartridge/mmm01/mmm01.cpp b/waterbox/libsnes/bsnes/gameboy/cartridge/mmm01/mmm01.cpp similarity index 100% rename from libsnes/bsnes/gameboy/cartridge/mmm01/mmm01.cpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/mmm01/mmm01.cpp diff --git a/libsnes/bsnes/gameboy/cartridge/mmm01/mmm01.hpp b/waterbox/libsnes/bsnes/gameboy/cartridge/mmm01/mmm01.hpp similarity index 100% rename from libsnes/bsnes/gameboy/cartridge/mmm01/mmm01.hpp rename to waterbox/libsnes/bsnes/gameboy/cartridge/mmm01/mmm01.hpp diff --git a/libsnes/bsnes/gameboy/cpu/core/core.cpp b/waterbox/libsnes/bsnes/gameboy/cpu/core/core.cpp similarity index 100% rename from libsnes/bsnes/gameboy/cpu/core/core.cpp rename to waterbox/libsnes/bsnes/gameboy/cpu/core/core.cpp diff --git a/libsnes/bsnes/gameboy/cpu/core/core.hpp b/waterbox/libsnes/bsnes/gameboy/cpu/core/core.hpp similarity index 95% rename from libsnes/bsnes/gameboy/cpu/core/core.hpp rename to waterbox/libsnes/bsnes/gameboy/cpu/core/core.hpp index 5d94892cb5..f239f2ff04 100644 --- a/libsnes/bsnes/gameboy/cpu/core/core.hpp +++ b/waterbox/libsnes/bsnes/gameboy/cpu/core/core.hpp @@ -1,146 +1,146 @@ -#include "registers.hpp" -void (CPU::*opcode_table[256])(); -void (CPU::*opcode_table_cb[256])(); -void initialize_opcode_table(); - -void op_xx(); -void op_cb(); -uint8 op_fetch(); - -//8-bit load commands -template void op_ld_r_r(); -template void op_ld_r_n(); -template void op_ld_r_hl(); -template void op_ld_hl_r(); -void op_ld_hl_n(); -template void op_ld_a_rr(); -void op_ld_a_nn(); -template void op_ld_rr_a(); -void op_ld_nn_a(); -void op_ld_a_ffn(); -void op_ld_ffn_a(); -void op_ld_a_ffc(); -void op_ld_ffc_a(); -void op_ldi_hl_a(); -void op_ldi_a_hl(); -void op_ldd_hl_a(); -void op_ldd_a_hl(); - -//16-bit load commands -template void op_ld_rr_nn(); -void op_ld_nn_sp(); -void op_ld_sp_hl(); -template void op_push_rr(); -template void op_pop_rr(); - -//8-bit arithmetic commands -void opi_add_a(uint8 x); -template void op_add_a_r(); -void op_add_a_n(); -void op_add_a_hl(); - -void opi_adc_a(uint8 x); -template void op_adc_a_r(); -void op_adc_a_n(); -void op_adc_a_hl(); - -void opi_sub_a(uint8 x); -template void op_sub_a_r(); -void op_sub_a_n(); -void op_sub_a_hl(); - -void opi_sbc_a(uint8 x); -template void op_sbc_a_r(); -void op_sbc_a_n(); -void op_sbc_a_hl(); - -void opi_and_a(uint8 x); -template void op_and_a_r(); -void op_and_a_n(); -void op_and_a_hl(); - -void opi_xor_a(uint8 x); -template void op_xor_a_r(); -void op_xor_a_n(); -void op_xor_a_hl(); - -void opi_or_a(uint8 x); -template void op_or_a_r(); -void op_or_a_n(); -void op_or_a_hl(); - -void opi_cp_a(uint8 x); -template void op_cp_a_r(); -void op_cp_a_n(); -void op_cp_a_hl(); - -template void op_inc_r(); -void op_inc_hl(); -template void op_dec_r(); -void op_dec_hl(); -void op_daa(); -void op_cpl(); - -//16-bit arithmetic commands -template void op_add_hl_rr(); -template void op_inc_rr(); -template void op_dec_rr(); -void op_add_sp_n(); -void op_ld_hl_sp_n(); - -//rotate/shift commands -void op_rlca(); -void op_rla(); -void op_rrca(); -void op_rra(); -template void op_rlc_r(); -void op_rlc_hl(); -template void op_rl_r(); -void op_rl_hl(); -template void op_rrc_r(); -void op_rrc_hl(); -template void op_rr_r(); -void op_rr_hl(); -template void op_sla_r(); -void op_sla_hl(); -template void op_swap_r(); -void op_swap_hl(); -template void op_sra_r(); -void op_sra_hl(); -template void op_srl_r(); -void op_srl_hl(); - -//single-bit commands -template void op_bit_n_r(); -template void op_bit_n_hl(); -template void op_set_n_r(); -template void op_set_n_hl(); -template void op_res_n_r(); -template void op_res_n_hl(); - -//control commands -void op_ccf(); -void op_scf(); -void op_nop(); -void op_halt(); -void op_stop(); -void op_di(); -void op_ei(); - -//jump commands -void op_jp_nn(); -void op_jp_hl(); -template void op_jp_f_nn(); -void op_jr_n(); -template void op_jr_f_n(); -void op_call_nn(); -template void op_call_f_nn(); -void op_ret(); -template void op_ret_f(); -void op_reti(); -template void op_rst_n(); - -//disassembler.cpp -string disassemble(uint16 pc); -string disassemble_opcode(uint16 pc); -string disassemble_opcode_cb(uint16 pc); +#include "registers.hpp" +void (CPU::*opcode_table[256])(); +void (CPU::*opcode_table_cb[256])(); +void initialize_opcode_table(); + +void op_xx(); +void op_cb(); +uint8 op_fetch(); + +//8-bit load commands +template void op_ld_r_r(); +template void op_ld_r_n(); +template void op_ld_r_hl(); +template void op_ld_hl_r(); +void op_ld_hl_n(); +template void op_ld_a_rr(); +void op_ld_a_nn(); +template void op_ld_rr_a(); +void op_ld_nn_a(); +void op_ld_a_ffn(); +void op_ld_ffn_a(); +void op_ld_a_ffc(); +void op_ld_ffc_a(); +void op_ldi_hl_a(); +void op_ldi_a_hl(); +void op_ldd_hl_a(); +void op_ldd_a_hl(); + +//16-bit load commands +template void op_ld_rr_nn(); +void op_ld_nn_sp(); +void op_ld_sp_hl(); +template void op_push_rr(); +template void op_pop_rr(); + +//8-bit arithmetic commands +void opi_add_a(uint8 x); +template void op_add_a_r(); +void op_add_a_n(); +void op_add_a_hl(); + +void opi_adc_a(uint8 x); +template void op_adc_a_r(); +void op_adc_a_n(); +void op_adc_a_hl(); + +void opi_sub_a(uint8 x); +template void op_sub_a_r(); +void op_sub_a_n(); +void op_sub_a_hl(); + +void opi_sbc_a(uint8 x); +template void op_sbc_a_r(); +void op_sbc_a_n(); +void op_sbc_a_hl(); + +void opi_and_a(uint8 x); +template void op_and_a_r(); +void op_and_a_n(); +void op_and_a_hl(); + +void opi_xor_a(uint8 x); +template void op_xor_a_r(); +void op_xor_a_n(); +void op_xor_a_hl(); + +void opi_or_a(uint8 x); +template void op_or_a_r(); +void op_or_a_n(); +void op_or_a_hl(); + +void opi_cp_a(uint8 x); +template void op_cp_a_r(); +void op_cp_a_n(); +void op_cp_a_hl(); + +template void op_inc_r(); +void op_inc_hl(); +template void op_dec_r(); +void op_dec_hl(); +void op_daa(); +void op_cpl(); + +//16-bit arithmetic commands +template void op_add_hl_rr(); +template void op_inc_rr(); +template void op_dec_rr(); +void op_add_sp_n(); +void op_ld_hl_sp_n(); + +//rotate/shift commands +void op_rlca(); +void op_rla(); +void op_rrca(); +void op_rra(); +template void op_rlc_r(); +void op_rlc_hl(); +template void op_rl_r(); +void op_rl_hl(); +template void op_rrc_r(); +void op_rrc_hl(); +template void op_rr_r(); +void op_rr_hl(); +template void op_sla_r(); +void op_sla_hl(); +template void op_swap_r(); +void op_swap_hl(); +template void op_sra_r(); +void op_sra_hl(); +template void op_srl_r(); +void op_srl_hl(); + +//single-bit commands +template void op_bit_n_r(); +template void op_bit_n_hl(); +template void op_set_n_r(); +template void op_set_n_hl(); +template void op_res_n_r(); +template void op_res_n_hl(); + +//control commands +void op_ccf(); +void op_scf(); +void op_nop(); +void op_halt(); +void op_stop(); +void op_di(); +void op_ei(); + +//jump commands +void op_jp_nn(); +void op_jp_hl(); +template void op_jp_f_nn(); +void op_jr_n(); +template void op_jr_f_n(); +void op_call_nn(); +template void op_call_f_nn(); +void op_ret(); +template void op_ret_f(); +void op_reti(); +template void op_rst_n(); + +//disassembler.cpp +string disassemble(uint16 pc); +string disassemble_opcode(uint16 pc); +string disassemble_opcode_cb(uint16 pc); diff --git a/libsnes/bsnes/gameboy/cpu/core/disassembler.cpp b/waterbox/libsnes/bsnes/gameboy/cpu/core/disassembler.cpp similarity index 100% rename from libsnes/bsnes/gameboy/cpu/core/disassembler.cpp rename to waterbox/libsnes/bsnes/gameboy/cpu/core/disassembler.cpp diff --git a/libsnes/bsnes/gameboy/cpu/core/registers.hpp b/waterbox/libsnes/bsnes/gameboy/cpu/core/registers.hpp similarity index 100% rename from libsnes/bsnes/gameboy/cpu/core/registers.hpp rename to waterbox/libsnes/bsnes/gameboy/cpu/core/registers.hpp diff --git a/libsnes/bsnes/gameboy/cpu/core/table.cpp b/waterbox/libsnes/bsnes/gameboy/cpu/core/table.cpp similarity index 100% rename from libsnes/bsnes/gameboy/cpu/core/table.cpp rename to waterbox/libsnes/bsnes/gameboy/cpu/core/table.cpp diff --git a/libsnes/bsnes/gameboy/cpu/cpu.cpp b/waterbox/libsnes/bsnes/gameboy/cpu/cpu.cpp similarity index 99% rename from libsnes/bsnes/gameboy/cpu/cpu.cpp rename to waterbox/libsnes/bsnes/gameboy/cpu/cpu.cpp index f1367423ac..4b7e95b071 100644 --- a/libsnes/bsnes/gameboy/cpu/cpu.cpp +++ b/waterbox/libsnes/bsnes/gameboy/cpu/cpu.cpp @@ -8,7 +8,6 @@ namespace GameBoy { #include "core/core.cpp" #include "mmio/mmio.cpp" #include "timing/timing.cpp" -#include "serialization.cpp" CPU cpu; void CPU::Main() { diff --git a/libsnes/bsnes/gameboy/cpu/cpu.hpp b/waterbox/libsnes/bsnes/gameboy/cpu/cpu.hpp similarity index 98% rename from libsnes/bsnes/gameboy/cpu/cpu.hpp rename to waterbox/libsnes/bsnes/gameboy/cpu/cpu.hpp index 983a3f5b43..c16ac493f9 100644 --- a/libsnes/bsnes/gameboy/cpu/cpu.hpp +++ b/waterbox/libsnes/bsnes/gameboy/cpu/cpu.hpp @@ -98,7 +98,6 @@ struct CPU : Processor, MMIO { void interrupt_exec(uint16 pc); void power(); - void serialize(serializer&); void initialize(); CPU(); ~CPU(); diff --git a/libsnes/bsnes/gameboy/cpu/mmio/mmio.cpp b/waterbox/libsnes/bsnes/gameboy/cpu/mmio/mmio.cpp similarity index 100% rename from libsnes/bsnes/gameboy/cpu/mmio/mmio.cpp rename to waterbox/libsnes/bsnes/gameboy/cpu/mmio/mmio.cpp diff --git a/libsnes/bsnes/gameboy/cpu/mmio/mmio.hpp b/waterbox/libsnes/bsnes/gameboy/cpu/mmio/mmio.hpp similarity index 100% rename from libsnes/bsnes/gameboy/cpu/mmio/mmio.hpp rename to waterbox/libsnes/bsnes/gameboy/cpu/mmio/mmio.hpp diff --git a/libsnes/bsnes/gameboy/cpu/timing/opcode.cpp b/waterbox/libsnes/bsnes/gameboy/cpu/timing/opcode.cpp similarity index 100% rename from libsnes/bsnes/gameboy/cpu/timing/opcode.cpp rename to waterbox/libsnes/bsnes/gameboy/cpu/timing/opcode.cpp diff --git a/libsnes/bsnes/gameboy/cpu/timing/timing.cpp b/waterbox/libsnes/bsnes/gameboy/cpu/timing/timing.cpp similarity index 95% rename from libsnes/bsnes/gameboy/cpu/timing/timing.cpp rename to waterbox/libsnes/bsnes/gameboy/cpu/timing/timing.cpp index fc03b16f62..2fcec3d1e4 100644 --- a/libsnes/bsnes/gameboy/cpu/timing/timing.cpp +++ b/waterbox/libsnes/bsnes/gameboy/cpu/timing/timing.cpp @@ -1,96 +1,96 @@ -//70224 clocks/frame -// 456 clocks/scanline -// 154 scanlines/frame - -#ifdef CPU_CPP - -#include "opcode.cpp" - -void CPU::add_clocks(unsigned clocks) { - system.clocks_executed += clocks; - - auto flags = cdlInfo.currFlags; - - if(system.sgb()) scheduler.exit(Scheduler::ExitReason::StepEvent); - cdlInfo.currFlags = flags; - - status.clock += clocks; - if(status.clock >= 4 * 1024 * 1024) { - status.clock -= 4 * 1024 * 1024; - cartridge.mbc3.second(); - } - - //4MHz / N(hz) - 1 = mask - if((status.clock & 15) == 0) timer_262144hz(); - if((status.clock & 63) == 0) timer_65536hz(); - if((status.clock & 255) == 0) timer_16384hz(); - if((status.clock & 511) == 0) timer_8192hz(); - if((status.clock & 1023) == 0) timer_4096hz(); - - lcd.clock -= clocks * lcd.frequency; - if(lcd.clock <= 0) co_switch(scheduler.active_thread = lcd.thread); - cdlInfo.currFlags = flags; - - apu.clock -= clocks * apu.frequency; - if(apu.clock <= 0) co_switch(scheduler.active_thread = apu.thread); - cdlInfo.currFlags = flags; -} - -void CPU::timer_262144hz() { - if(status.timer_enable && status.timer_clock == 1) { - if(++status.tima == 0) { - status.tima = status.tma; - interrupt_raise(Interrupt::Timer); - } - } -} - -void CPU::timer_65536hz() { - if(status.timer_enable && status.timer_clock == 2) { - if(++status.tima == 0) { - status.tima = status.tma; - interrupt_raise(Interrupt::Timer); - } - } -} - -void CPU::timer_16384hz() { - if(status.timer_enable && status.timer_clock == 3) { - if(++status.tima == 0) { - status.tima = status.tma; - interrupt_raise(Interrupt::Timer); - } - } - - status.div++; -} - -void CPU::timer_8192hz() { - if(status.serial_transfer && status.serial_clock) { - if(--status.serial_bits == 0) { - status.serial_transfer = 0; - interrupt_raise(Interrupt::Serial); - } - } -} - -void CPU::timer_4096hz() { - if(status.timer_enable && status.timer_clock == 0) { - if(++status.tima == 0) { - status.tima = status.tma; - interrupt_raise(Interrupt::Timer); - } - } -} - -void CPU::hblank() { - if(status.dma_mode == 1 && status.dma_length) { - for(unsigned n = 0; n < 16; n++) { - bus.write(status.dma_target++, bus.read(status.dma_source++)); - add_clocks(4); - } - status.dma_length -= 16; - } -} - -#endif +//70224 clocks/frame +// 456 clocks/scanline +// 154 scanlines/frame + +#ifdef CPU_CPP + +#include "opcode.cpp" + +void CPU::add_clocks(unsigned clocks) { + system.clocks_executed += clocks; + + auto flags = cdlInfo.currFlags; + + if(system.sgb()) scheduler.exit(Scheduler::ExitReason::StepEvent); + cdlInfo.currFlags = flags; + + status.clock += clocks; + if(status.clock >= 4 * 1024 * 1024) { + status.clock -= 4 * 1024 * 1024; + cartridge.mbc3.second(); + } + + //4MHz / N(hz) - 1 = mask + if((status.clock & 15) == 0) timer_262144hz(); + if((status.clock & 63) == 0) timer_65536hz(); + if((status.clock & 255) == 0) timer_16384hz(); + if((status.clock & 511) == 0) timer_8192hz(); + if((status.clock & 1023) == 0) timer_4096hz(); + + lcd.clock -= clocks * lcd.frequency; + if(lcd.clock <= 0) co_switch(scheduler.active_thread = lcd.thread); + cdlInfo.currFlags = flags; + + apu.clock -= clocks * apu.frequency; + if(apu.clock <= 0) co_switch(scheduler.active_thread = apu.thread); + cdlInfo.currFlags = flags; +} + +void CPU::timer_262144hz() { + if(status.timer_enable && status.timer_clock == 1) { + if(++status.tima == 0) { + status.tima = status.tma; + interrupt_raise(Interrupt::Timer); + } + } +} + +void CPU::timer_65536hz() { + if(status.timer_enable && status.timer_clock == 2) { + if(++status.tima == 0) { + status.tima = status.tma; + interrupt_raise(Interrupt::Timer); + } + } +} + +void CPU::timer_16384hz() { + if(status.timer_enable && status.timer_clock == 3) { + if(++status.tima == 0) { + status.tima = status.tma; + interrupt_raise(Interrupt::Timer); + } + } + + status.div++; +} + +void CPU::timer_8192hz() { + if(status.serial_transfer && status.serial_clock) { + if(--status.serial_bits == 0) { + status.serial_transfer = 0; + interrupt_raise(Interrupt::Serial); + } + } +} + +void CPU::timer_4096hz() { + if(status.timer_enable && status.timer_clock == 0) { + if(++status.tima == 0) { + status.tima = status.tma; + interrupt_raise(Interrupt::Timer); + } + } +} + +void CPU::hblank() { + if(status.dma_mode == 1 && status.dma_length) { + for(unsigned n = 0; n < 16; n++) { + bus.write(status.dma_target++, bus.read(status.dma_source++)); + add_clocks(4); + } + status.dma_length -= 16; + } +} + +#endif diff --git a/libsnes/bsnes/gameboy/cpu/timing/timing.hpp b/waterbox/libsnes/bsnes/gameboy/cpu/timing/timing.hpp similarity index 100% rename from libsnes/bsnes/gameboy/cpu/timing/timing.hpp rename to waterbox/libsnes/bsnes/gameboy/cpu/timing/timing.hpp diff --git a/libsnes/bsnes/gameboy/gameboy.hpp b/waterbox/libsnes/bsnes/gameboy/gameboy.hpp similarity index 76% rename from libsnes/bsnes/gameboy/gameboy.hpp rename to waterbox/libsnes/bsnes/gameboy/gameboy.hpp index 142fa036ac..e7f93281aa 100644 --- a/libsnes/bsnes/gameboy/gameboy.hpp +++ b/waterbox/libsnes/bsnes/gameboy/gameboy.hpp @@ -3,13 +3,6 @@ #include -namespace GameBoy { - namespace Info { - static const char Name[] = "bgameboy"; - static const unsigned SerializerVersion = 3; - } -} - /* bgameboy - Game Boy, Super Game Boy, and Game Boy Color emulator author: byuu @@ -17,7 +10,7 @@ namespace GameBoy { project started: 2010-12-27 */ -#include +#include #include namespace GameBoy { @@ -33,11 +26,6 @@ namespace GameBoy { clock = 0; } - inline void serialize(serializer &s) { - s.integer(frequency); - s.integer(clock); - } - inline Processor() : thread(nullptr) { } @@ -53,7 +41,6 @@ namespace GameBoy { #include #include #include - #include #include }; diff --git a/libsnes/bsnes/gameboy/interface/interface.cpp b/waterbox/libsnes/bsnes/gameboy/interface/interface.cpp similarity index 100% rename from libsnes/bsnes/gameboy/interface/interface.cpp rename to waterbox/libsnes/bsnes/gameboy/interface/interface.cpp diff --git a/libsnes/bsnes/gameboy/interface/interface.hpp b/waterbox/libsnes/bsnes/gameboy/interface/interface.hpp similarity index 100% rename from libsnes/bsnes/gameboy/interface/interface.hpp rename to waterbox/libsnes/bsnes/gameboy/interface/interface.hpp diff --git a/libsnes/bsnes/gameboy/lcd/cgb.cpp b/waterbox/libsnes/bsnes/gameboy/lcd/cgb.cpp similarity index 100% rename from libsnes/bsnes/gameboy/lcd/cgb.cpp rename to waterbox/libsnes/bsnes/gameboy/lcd/cgb.cpp diff --git a/libsnes/bsnes/gameboy/lcd/dmg.cpp b/waterbox/libsnes/bsnes/gameboy/lcd/dmg.cpp similarity index 100% rename from libsnes/bsnes/gameboy/lcd/dmg.cpp rename to waterbox/libsnes/bsnes/gameboy/lcd/dmg.cpp diff --git a/libsnes/bsnes/gameboy/lcd/lcd.cpp b/waterbox/libsnes/bsnes/gameboy/lcd/lcd.cpp similarity index 99% rename from libsnes/bsnes/gameboy/lcd/lcd.cpp rename to waterbox/libsnes/bsnes/gameboy/lcd/lcd.cpp index 7a3607c606..595c46e2e8 100644 --- a/libsnes/bsnes/gameboy/lcd/lcd.cpp +++ b/waterbox/libsnes/bsnes/gameboy/lcd/lcd.cpp @@ -12,7 +12,6 @@ namespace GameBoy { #include "dmg.cpp" #include "cgb.cpp" #include "mmio/mmio.cpp" -#include "serialization.cpp" LCD lcd; void LCD::Main() { diff --git a/libsnes/bsnes/gameboy/lcd/lcd.hpp b/waterbox/libsnes/bsnes/gameboy/lcd/lcd.hpp similarity index 98% rename from libsnes/bsnes/gameboy/lcd/lcd.hpp rename to waterbox/libsnes/bsnes/gameboy/lcd/lcd.hpp index f1b88115ae..4adec719cf 100644 --- a/libsnes/bsnes/gameboy/lcd/lcd.hpp +++ b/waterbox/libsnes/bsnes/gameboy/lcd/lcd.hpp @@ -87,7 +87,6 @@ struct LCD : Processor, MMIO { void power(); - void serialize(serializer&); LCD(); }; diff --git a/libsnes/bsnes/gameboy/lcd/mmio/mmio.cpp b/waterbox/libsnes/bsnes/gameboy/lcd/mmio/mmio.cpp similarity index 100% rename from libsnes/bsnes/gameboy/lcd/mmio/mmio.cpp rename to waterbox/libsnes/bsnes/gameboy/lcd/mmio/mmio.cpp diff --git a/libsnes/bsnes/gameboy/lcd/mmio/mmio.hpp b/waterbox/libsnes/bsnes/gameboy/lcd/mmio/mmio.hpp similarity index 100% rename from libsnes/bsnes/gameboy/lcd/mmio/mmio.hpp rename to waterbox/libsnes/bsnes/gameboy/lcd/mmio/mmio.hpp diff --git a/libsnes/bsnes/gameboy/memory/memory.cpp b/waterbox/libsnes/bsnes/gameboy/memory/memory.cpp similarity index 77% rename from libsnes/bsnes/gameboy/memory/memory.cpp rename to waterbox/libsnes/bsnes/gameboy/memory/memory.cpp index ad2818449a..bb3bb3f970 100644 --- a/libsnes/bsnes/gameboy/memory/memory.cpp +++ b/waterbox/libsnes/bsnes/gameboy/memory/memory.cpp @@ -43,18 +43,6 @@ Memory::~Memory() { uint8 Bus::read(uint16 addr) { uint8 data = mmio[addr]->mmio_read(addr); - - if(cheat.override[addr]) { - for(unsigned n = 0; n < cheat.size(); n++) { - if(cheat[n].addr == addr) { - if(cheat[n].comp > 255 || cheat[n].comp == data) { - data = cheat[n].data; - break; - } - } - } - } - return data; } diff --git a/libsnes/bsnes/gameboy/memory/memory.hpp b/waterbox/libsnes/bsnes/gameboy/memory/memory.hpp similarity index 100% rename from libsnes/bsnes/gameboy/memory/memory.hpp rename to waterbox/libsnes/bsnes/gameboy/memory/memory.hpp diff --git a/libsnes/bsnes/gameboy/scheduler/scheduler.cpp b/waterbox/libsnes/bsnes/gameboy/scheduler/scheduler.cpp similarity index 100% rename from libsnes/bsnes/gameboy/scheduler/scheduler.cpp rename to waterbox/libsnes/bsnes/gameboy/scheduler/scheduler.cpp diff --git a/libsnes/bsnes/gameboy/scheduler/scheduler.hpp b/waterbox/libsnes/bsnes/gameboy/scheduler/scheduler.hpp similarity index 100% rename from libsnes/bsnes/gameboy/scheduler/scheduler.hpp rename to waterbox/libsnes/bsnes/gameboy/scheduler/scheduler.hpp diff --git a/libsnes/bsnes/gameboy/system/bootrom-cgb.cpp b/waterbox/libsnes/bsnes/gameboy/system/bootrom-cgb.cpp similarity index 100% rename from libsnes/bsnes/gameboy/system/bootrom-cgb.cpp rename to waterbox/libsnes/bsnes/gameboy/system/bootrom-cgb.cpp diff --git a/libsnes/bsnes/gameboy/system/bootrom-dmg.cpp b/waterbox/libsnes/bsnes/gameboy/system/bootrom-dmg.cpp similarity index 100% rename from libsnes/bsnes/gameboy/system/bootrom-dmg.cpp rename to waterbox/libsnes/bsnes/gameboy/system/bootrom-dmg.cpp diff --git a/libsnes/bsnes/gameboy/system/bootrom-sgb.cpp b/waterbox/libsnes/bsnes/gameboy/system/bootrom-sgb.cpp similarity index 100% rename from libsnes/bsnes/gameboy/system/bootrom-sgb.cpp rename to waterbox/libsnes/bsnes/gameboy/system/bootrom-sgb.cpp diff --git a/libsnes/bsnes/gameboy/system/system.cpp b/waterbox/libsnes/bsnes/gameboy/system/system.cpp similarity index 95% rename from libsnes/bsnes/gameboy/system/system.cpp rename to waterbox/libsnes/bsnes/gameboy/system/system.cpp index 0d6567bd8c..37727b5778 100644 --- a/libsnes/bsnes/gameboy/system/system.cpp +++ b/waterbox/libsnes/bsnes/gameboy/system/system.cpp @@ -6,7 +6,6 @@ namespace GameBoy { #include "bootrom-dmg.cpp" #include "bootrom-sgb.cpp" #include "bootrom-cgb.cpp" -#include "serialization.cpp" System system; void System::run() { @@ -40,7 +39,6 @@ void System::init() { void System::load(Revision revision) { this->revision = revision; - serialize_init(); } void System::power() { diff --git a/libsnes/bsnes/gameboy/system/system.hpp b/waterbox/libsnes/bsnes/gameboy/system/system.hpp similarity index 80% rename from libsnes/bsnes/gameboy/system/system.hpp rename to waterbox/libsnes/bsnes/gameboy/system/system.hpp index d98a8357cf..a3be91e8e0 100644 --- a/libsnes/bsnes/gameboy/system/system.hpp +++ b/waterbox/libsnes/bsnes/gameboy/system/system.hpp @@ -31,15 +31,6 @@ struct System : property { unsigned clocks_executed; - //serialization.cpp - unsigned serialize_size; - - serializer serialize(); - bool unserialize(serializer&); - - void serialize(serializer&); - void serialize_all(serializer&); - void serialize_init(); }; #include diff --git a/libsnes/bsnes/gameboy/video/video.cpp b/waterbox/libsnes/bsnes/gameboy/video/video.cpp similarity index 100% rename from libsnes/bsnes/gameboy/video/video.cpp rename to waterbox/libsnes/bsnes/gameboy/video/video.cpp diff --git a/libsnes/bsnes/gameboy/video/video.hpp b/waterbox/libsnes/bsnes/gameboy/video/video.hpp similarity index 100% rename from libsnes/bsnes/gameboy/video/video.hpp rename to waterbox/libsnes/bsnes/gameboy/video/video.hpp diff --git a/libsnes/bsnes/nall/algorithm.hpp b/waterbox/libsnes/bsnes/nall/algorithm.hpp similarity index 100% rename from libsnes/bsnes/nall/algorithm.hpp rename to waterbox/libsnes/bsnes/nall/algorithm.hpp diff --git a/libsnes/bsnes/nall/any.hpp b/waterbox/libsnes/bsnes/nall/any.hpp similarity index 100% rename from libsnes/bsnes/nall/any.hpp rename to waterbox/libsnes/bsnes/nall/any.hpp diff --git a/libsnes/bsnes/nall/array.hpp b/waterbox/libsnes/bsnes/nall/array.hpp similarity index 100% rename from libsnes/bsnes/nall/array.hpp rename to waterbox/libsnes/bsnes/nall/array.hpp diff --git a/libsnes/bsnes/nall/atoi.hpp b/waterbox/libsnes/bsnes/nall/atoi.hpp similarity index 100% rename from libsnes/bsnes/nall/atoi.hpp rename to waterbox/libsnes/bsnes/nall/atoi.hpp diff --git a/libsnes/bsnes/nall/base64.hpp b/waterbox/libsnes/bsnes/nall/base64.hpp similarity index 100% rename from libsnes/bsnes/nall/base64.hpp rename to waterbox/libsnes/bsnes/nall/base64.hpp diff --git a/libsnes/bsnes/nall/bit.hpp b/waterbox/libsnes/bsnes/nall/bit.hpp similarity index 100% rename from libsnes/bsnes/nall/bit.hpp rename to waterbox/libsnes/bsnes/nall/bit.hpp diff --git a/libsnes/bsnes/nall/bmp.hpp b/waterbox/libsnes/bsnes/nall/bmp.hpp similarity index 100% rename from libsnes/bsnes/nall/bmp.hpp rename to waterbox/libsnes/bsnes/nall/bmp.hpp diff --git a/libsnes/bsnes/nall/bps/delta.hpp b/waterbox/libsnes/bsnes/nall/bps/delta.hpp similarity index 100% rename from libsnes/bsnes/nall/bps/delta.hpp rename to waterbox/libsnes/bsnes/nall/bps/delta.hpp diff --git a/libsnes/bsnes/nall/bps/linear.hpp b/waterbox/libsnes/bsnes/nall/bps/linear.hpp similarity index 100% rename from libsnes/bsnes/nall/bps/linear.hpp rename to waterbox/libsnes/bsnes/nall/bps/linear.hpp diff --git a/libsnes/bsnes/nall/bps/metadata.hpp b/waterbox/libsnes/bsnes/nall/bps/metadata.hpp similarity index 100% rename from libsnes/bsnes/nall/bps/metadata.hpp rename to waterbox/libsnes/bsnes/nall/bps/metadata.hpp diff --git a/libsnes/bsnes/nall/bps/patch.hpp b/waterbox/libsnes/bsnes/nall/bps/patch.hpp similarity index 100% rename from libsnes/bsnes/nall/bps/patch.hpp rename to waterbox/libsnes/bsnes/nall/bps/patch.hpp diff --git a/libsnes/bsnes/nall/compositor.hpp b/waterbox/libsnes/bsnes/nall/compositor.hpp similarity index 100% rename from libsnes/bsnes/nall/compositor.hpp rename to waterbox/libsnes/bsnes/nall/compositor.hpp diff --git a/libsnes/bsnes/nall/config.hpp b/waterbox/libsnes/bsnes/nall/config.hpp similarity index 100% rename from libsnes/bsnes/nall/config.hpp rename to waterbox/libsnes/bsnes/nall/config.hpp diff --git a/libsnes/bsnes/nall/crc32.hpp b/waterbox/libsnes/bsnes/nall/crc32.hpp similarity index 100% rename from libsnes/bsnes/nall/crc32.hpp rename to waterbox/libsnes/bsnes/nall/crc32.hpp diff --git a/libsnes/bsnes/nall/directory.hpp b/waterbox/libsnes/bsnes/nall/directory.hpp similarity index 100% rename from libsnes/bsnes/nall/directory.hpp rename to waterbox/libsnes/bsnes/nall/directory.hpp diff --git a/libsnes/bsnes/nall/dl.hpp b/waterbox/libsnes/bsnes/nall/dl.hpp similarity index 100% rename from libsnes/bsnes/nall/dl.hpp rename to waterbox/libsnes/bsnes/nall/dl.hpp diff --git a/libsnes/bsnes/nall/dsp.hpp b/waterbox/libsnes/bsnes/nall/dsp.hpp similarity index 100% rename from libsnes/bsnes/nall/dsp.hpp rename to waterbox/libsnes/bsnes/nall/dsp.hpp diff --git a/libsnes/bsnes/nall/dsp/buffer.hpp b/waterbox/libsnes/bsnes/nall/dsp/buffer.hpp similarity index 78% rename from libsnes/bsnes/nall/dsp/buffer.hpp rename to waterbox/libsnes/bsnes/nall/dsp/buffer.hpp index 4386d0e955..718ee98f76 100644 --- a/libsnes/bsnes/nall/dsp/buffer.hpp +++ b/waterbox/libsnes/bsnes/nall/dsp/buffer.hpp @@ -1,51 +1,51 @@ -#ifdef NALL_DSP_INTERNAL_HPP - -struct Buffer { - double **sample; - uint16_t rdoffset; - uint16_t wroffset; - unsigned channels; - - void setChannels(unsigned channels) { - for(unsigned c = 0; c < this->channels; c++) { - if(sample[c]) delete[] sample[c]; - } - if(sample) delete[] sample; - - this->channels = channels; - if(channels == 0) return; - - sample = new double*[channels]; - for(unsigned c = 0; c < channels; c++) { - sample[c] = new double[65536](); - } - } - - inline double& read(unsigned channel, signed offset = 0) { - return sample[channel][(uint16_t)(rdoffset + offset)]; - } - - inline double& write(unsigned channel, signed offset = 0) { - return sample[channel][(uint16_t)(wroffset + offset)]; - } - - inline void clear() { - for(unsigned c = 0; c < channels; c++) { - for(unsigned n = 0; n < 65536; n++) { - sample[c][n] = 0; - } - } - rdoffset = 0; - wroffset = 0; - } - - Buffer() { - channels = 0; - } - - ~Buffer() { - setChannels(0); - } -}; - -#endif +#ifdef NALL_DSP_INTERNAL_HPP + +struct Buffer { + double **sample; + uint16_t rdoffset; + uint16_t wroffset; + unsigned channels; + + void setChannels(unsigned channels) { + for(unsigned c = 0; c < this->channels; c++) { + if(sample[c]) abort(); + } + if(sample) abort(); + + this->channels = channels; + if(channels == 0) return; + + sample = (double**)alloc_invisible(channels * sizeof(*sample)); + for(unsigned c = 0; c < channels; c++) { + sample[c] = (double*)alloc_invisible(65536 * sizeof(**sample)); + } + } + + inline double& read(unsigned channel, signed offset = 0) { + return sample[channel][(uint16_t)(rdoffset + offset)]; + } + + inline double& write(unsigned channel, signed offset = 0) { + return sample[channel][(uint16_t)(wroffset + offset)]; + } + + inline void clear() { + for(unsigned c = 0; c < channels; c++) { + for(unsigned n = 0; n < 65536; n++) { + sample[c][n] = 0; + } + } + rdoffset = 0; + wroffset = 0; + } + + Buffer() { + channels = 0; + } + + ~Buffer() { + setChannels(0); + } +}; + +#endif diff --git a/libsnes/bsnes/nall/dsp/core.hpp b/waterbox/libsnes/bsnes/nall/dsp/core.hpp similarity index 94% rename from libsnes/bsnes/nall/dsp/core.hpp rename to waterbox/libsnes/bsnes/nall/dsp/core.hpp index a5b967b1d9..cbf9b97b25 100644 --- a/libsnes/bsnes/nall/dsp/core.hpp +++ b/waterbox/libsnes/bsnes/nall/dsp/core.hpp @@ -1,167 +1,168 @@ -#ifdef NALL_DSP_INTERNAL_HPP - -#include -#include - -namespace nall { - -//precision: can be float, double or long double -#define real float - -struct DSP; - -struct Resampler { - DSP &dsp; - real frequency; - - virtual void setFrequency() = 0; - virtual void clear() = 0; - virtual void sample() = 0; - Resampler(DSP &dsp) : dsp(dsp) {} -}; - -struct DSP { - enum class ResampleEngine : unsigned { - Nearest, - Linear, - Cosine, - Cubic, - Hermite, - Average, - Sinc, - }; - - inline void setChannels(unsigned channels); - inline void setPrecision(unsigned precision); - inline void setFrequency(real frequency); //inputFrequency - inline void setVolume(real volume); - inline void setBalance(real balance); - - inline void setResampler(ResampleEngine resamplingEngine); - inline void setResamplerFrequency(real frequency); //outputFrequency - - inline void sample(signed channel[]); - inline bool pending(); - inline void read(signed channel[]); - - inline void clear(); - inline DSP(); - inline ~DSP(); - -protected: - friend class ResampleNearest; - friend class ResampleLinear; - friend class ResampleCosine; - friend class ResampleCubic; - friend class ResampleAverage; - friend class ResampleHermite; - friend class ResampleSinc; - - struct Settings { - unsigned channels; - unsigned precision; - real frequency; - real volume; - real balance; - - //internal - real intensity; - real intensityInverse; - } settings; - - Resampler *resampler; - inline void write(real channel[]); - - #include "buffer.hpp" - Buffer buffer; - Buffer output; - - inline void adjustVolume(); - inline void adjustBalance(); - inline signed clamp(const unsigned bits, const signed x); -}; - -#include "resample/nearest.hpp" -#include "resample/linear.hpp" -#include "resample/cosine.hpp" -#include "resample/cubic.hpp" -#include "resample/hermite.hpp" -#include "resample/average.hpp" -#include "resample/sinc.hpp" -#include "settings.hpp" - -void DSP::sample(signed channel[]) { - for(unsigned c = 0; c < settings.channels; c++) { - buffer.write(c) = (real)channel[c] * settings.intensityInverse; - } - buffer.wroffset++; - resampler->sample(); -} - -bool DSP::pending() { - return output.rdoffset != output.wroffset; -} - -void DSP::read(signed channel[]) { - adjustVolume(); - adjustBalance(); - - for(unsigned c = 0; c < settings.channels; c++) { - channel[c] = clamp(settings.precision, output.read(c) * settings.intensity); - } - output.rdoffset++; -} - -void DSP::write(real channel[]) { - for(unsigned c = 0; c < settings.channels; c++) { - output.write(c) = channel[c]; - } - output.wroffset++; -} - -void DSP::adjustVolume() { - for(unsigned c = 0; c < settings.channels; c++) { - output.read(c) *= settings.volume; - } -} - -void DSP::adjustBalance() { - if(settings.channels != 2) return; //TODO: support > 2 channels - if(settings.balance < 0.0) output.read(1) *= 1.0 + settings.balance; - if(settings.balance > 0.0) output.read(0) *= 1.0 - settings.balance; -} - -signed DSP::clamp(const unsigned bits, const signed x) { - const signed b = 1U << (bits - 1); - const signed m = (1U << (bits - 1)) - 1; - return (x > m) ? m : (x < -b) ? -b : x; -} - -void DSP::clear() { - buffer.clear(); - output.clear(); - resampler->clear(); -} - -DSP::DSP() { - setResampler(ResampleEngine::Hermite); - setResamplerFrequency(44100.0); - - setChannels(2); - setPrecision(16); - setFrequency(44100.0); - setVolume(1.0); - setBalance(0.0); - - clear(); -} - -DSP::~DSP() { - if(resampler) delete resampler; -} - -#undef real - -} - -#endif +#ifdef NALL_DSP_INTERNAL_HPP + +#include +#include +#include + +namespace nall { + +//precision: can be float, double or long double +#define real float + +struct DSP; + +struct Resampler { + DSP &dsp; + real frequency; + + virtual void setFrequency() = 0; + virtual void clear() = 0; + virtual void sample() = 0; + Resampler(DSP &dsp) : dsp(dsp) {} +}; + +struct DSP { + enum class ResampleEngine : unsigned { + Nearest, + Linear, + Cosine, + Cubic, + Hermite, + Average, + Sinc, + }; + + inline void setChannels(unsigned channels); + inline void setPrecision(unsigned precision); + inline void setFrequency(real frequency); //inputFrequency + inline void setVolume(real volume); + inline void setBalance(real balance); + + inline void setResampler(ResampleEngine resamplingEngine); + inline void setResamplerFrequency(real frequency); //outputFrequency + + inline void sample(signed channel[]); + inline bool pending(); + inline void read(signed channel[]); + + inline void clear(); + inline DSP(); + inline ~DSP(); + +protected: + friend class ResampleNearest; + friend class ResampleLinear; + friend class ResampleCosine; + friend class ResampleCubic; + friend class ResampleAverage; + friend class ResampleHermite; + friend class ResampleSinc; + + struct Settings { + unsigned channels; + unsigned precision; + real frequency; + real volume; + real balance; + + //internal + real intensity; + real intensityInverse; + } settings; + + Resampler *resampler; + inline void write(real channel[]); + + #include "buffer.hpp" + Buffer buffer; + Buffer output; + + inline void adjustVolume(); + inline void adjustBalance(); + inline signed clamp(const unsigned bits, const signed x); +}; + +#include "resample/nearest.hpp" +#include "resample/linear.hpp" +#include "resample/cosine.hpp" +#include "resample/cubic.hpp" +#include "resample/hermite.hpp" +#include "resample/average.hpp" +#include "resample/sinc.hpp" +#include "settings.hpp" + +void DSP::sample(signed channel[]) { + for(unsigned c = 0; c < settings.channels; c++) { + buffer.write(c) = (real)channel[c] * settings.intensityInverse; + } + buffer.wroffset++; + resampler->sample(); +} + +bool DSP::pending() { + return output.rdoffset != output.wroffset; +} + +void DSP::read(signed channel[]) { + adjustVolume(); + adjustBalance(); + + for(unsigned c = 0; c < settings.channels; c++) { + channel[c] = clamp(settings.precision, output.read(c) * settings.intensity); + } + output.rdoffset++; +} + +void DSP::write(real channel[]) { + for(unsigned c = 0; c < settings.channels; c++) { + output.write(c) = channel[c]; + } + output.wroffset++; +} + +void DSP::adjustVolume() { + for(unsigned c = 0; c < settings.channels; c++) { + output.read(c) *= settings.volume; + } +} + +void DSP::adjustBalance() { + if(settings.channels != 2) return; //TODO: support > 2 channels + if(settings.balance < 0.0) output.read(1) *= 1.0 + settings.balance; + if(settings.balance > 0.0) output.read(0) *= 1.0 - settings.balance; +} + +signed DSP::clamp(const unsigned bits, const signed x) { + const signed b = 1U << (bits - 1); + const signed m = (1U << (bits - 1)) - 1; + return (x > m) ? m : (x < -b) ? -b : x; +} + +void DSP::clear() { + buffer.clear(); + output.clear(); + resampler->clear(); +} + +DSP::DSP() { + setResampler(ResampleEngine::Hermite); + setResamplerFrequency(44100.0); + + setChannels(2); + setPrecision(16); + setFrequency(44100.0); + setVolume(1.0); + setBalance(0.0); + + clear(); +} + +DSP::~DSP() { + if(resampler) delete resampler; +} + +#undef real + +} + +#endif diff --git a/libsnes/bsnes/nall/dsp/resample/average.hpp b/waterbox/libsnes/bsnes/nall/dsp/resample/average.hpp similarity index 93% rename from libsnes/bsnes/nall/dsp/resample/average.hpp rename to waterbox/libsnes/bsnes/nall/dsp/resample/average.hpp index 68f24f9d86..f584e3731f 100644 --- a/libsnes/bsnes/nall/dsp/resample/average.hpp +++ b/waterbox/libsnes/bsnes/nall/dsp/resample/average.hpp @@ -50,7 +50,7 @@ void ResampleAverage::sample() { void ResampleAverage::sampleLinear() { while(fraction <= 1.0) { - real *channel = (real*)alloca(dsp.settings.channels * sizeof(real)); + std::vector channel(dsp.settings.channels); for(unsigned n = 0; n < dsp.settings.channels; n++) { real a = dsp.buffer.read(n, -1); @@ -61,7 +61,7 @@ void ResampleAverage::sampleLinear() { channel[n] = a * (1.0 - mu) + b * mu; } - dsp.write(channel); + dsp.write(channel.data()); fraction += step; } diff --git a/libsnes/bsnes/nall/dsp/resample/cosine.hpp b/waterbox/libsnes/bsnes/nall/dsp/resample/cosine.hpp similarity index 89% rename from libsnes/bsnes/nall/dsp/resample/cosine.hpp rename to waterbox/libsnes/bsnes/nall/dsp/resample/cosine.hpp index 7dcb4140c7..6120a734b3 100644 --- a/libsnes/bsnes/nall/dsp/resample/cosine.hpp +++ b/waterbox/libsnes/bsnes/nall/dsp/resample/cosine.hpp @@ -21,7 +21,7 @@ void ResampleCosine::clear() { void ResampleCosine::sample() { while(fraction <= 1.0) { - real *channel = (real*)alloca(dsp.settings.channels * sizeof(real)); + std::vector channel(dsp.settings.channels); for(unsigned n = 0; n < dsp.settings.channels; n++) { @@ -34,7 +34,7 @@ void ResampleCosine::sample() { channel[n] = a * (1.0 - mu) + b * mu; } - dsp.write(channel); + dsp.write(channel.data()); fraction += step; } diff --git a/libsnes/bsnes/nall/dsp/resample/cubic.hpp b/waterbox/libsnes/bsnes/nall/dsp/resample/cubic.hpp similarity index 90% rename from libsnes/bsnes/nall/dsp/resample/cubic.hpp rename to waterbox/libsnes/bsnes/nall/dsp/resample/cubic.hpp index affee3a1ee..f7f077961c 100644 --- a/libsnes/bsnes/nall/dsp/resample/cubic.hpp +++ b/waterbox/libsnes/bsnes/nall/dsp/resample/cubic.hpp @@ -21,7 +21,7 @@ void ResampleCubic::clear() { void ResampleCubic::sample() { while(fraction <= 1.0) { - real *channel = (real*)alloca(dsp.settings.channels * sizeof(real)); + std::vector channel(dsp.settings.channels); for(unsigned n = 0; n < dsp.settings.channels; n++) { real a = dsp.buffer.read(n, -3); @@ -39,7 +39,7 @@ void ResampleCubic::sample() { channel[n] = A * (mu * 3) + B * (mu * 2) + C * mu + D; } - dsp.write(channel); + dsp.write(channel.data()); fraction += step; } diff --git a/libsnes/bsnes/nall/dsp/resample/hermite.hpp b/waterbox/libsnes/bsnes/nall/dsp/resample/hermite.hpp similarity index 93% rename from libsnes/bsnes/nall/dsp/resample/hermite.hpp rename to waterbox/libsnes/bsnes/nall/dsp/resample/hermite.hpp index ffe86e42d8..04c57b85c9 100644 --- a/libsnes/bsnes/nall/dsp/resample/hermite.hpp +++ b/waterbox/libsnes/bsnes/nall/dsp/resample/hermite.hpp @@ -21,7 +21,7 @@ void ResampleHermite::clear() { void ResampleHermite::sample() { while(fraction <= 1.0) { - real *channel = (real*)alloca(dsp.settings.channels * sizeof(real)); + std::vector channel(dsp.settings.channels); for(unsigned n = 0; n < dsp.settings.channels; n++) { real a = dsp.buffer.read(n, -3); @@ -51,7 +51,7 @@ void ResampleHermite::sample() { channel[n] = (a0 * b) + (a1 * m0) + (a2 * m1) + (a3 * c); } - dsp.write(channel); + dsp.write(channel.data()); fraction += step; } diff --git a/libsnes/bsnes/nall/dsp/resample/lib/sinc.hpp b/waterbox/libsnes/bsnes/nall/dsp/resample/lib/sinc.hpp similarity index 100% rename from libsnes/bsnes/nall/dsp/resample/lib/sinc.hpp rename to waterbox/libsnes/bsnes/nall/dsp/resample/lib/sinc.hpp diff --git a/libsnes/bsnes/nall/dsp/resample/linear.hpp b/waterbox/libsnes/bsnes/nall/dsp/resample/linear.hpp similarity index 88% rename from libsnes/bsnes/nall/dsp/resample/linear.hpp rename to waterbox/libsnes/bsnes/nall/dsp/resample/linear.hpp index 7845b73b7c..34e06ae440 100644 --- a/libsnes/bsnes/nall/dsp/resample/linear.hpp +++ b/waterbox/libsnes/bsnes/nall/dsp/resample/linear.hpp @@ -21,7 +21,7 @@ void ResampleLinear::clear() { void ResampleLinear::sample() { while(fraction <= 1.0) { - real *channel = (real*)alloca(dsp.settings.channels * sizeof(real)); + std::vector channel(dsp.settings.channels); for(unsigned n = 0; n < dsp.settings.channels; n++) { real a = dsp.buffer.read(n, -1); @@ -32,7 +32,7 @@ void ResampleLinear::sample() { channel[n] = a * (1.0 - mu) + b * mu; } - dsp.write(channel); + dsp.write(channel.data()); fraction += step; } diff --git a/libsnes/bsnes/nall/dsp/resample/nearest.hpp b/waterbox/libsnes/bsnes/nall/dsp/resample/nearest.hpp similarity index 88% rename from libsnes/bsnes/nall/dsp/resample/nearest.hpp rename to waterbox/libsnes/bsnes/nall/dsp/resample/nearest.hpp index e298d4174d..73df9f7d91 100644 --- a/libsnes/bsnes/nall/dsp/resample/nearest.hpp +++ b/waterbox/libsnes/bsnes/nall/dsp/resample/nearest.hpp @@ -21,7 +21,7 @@ void ResampleNearest::clear() { void ResampleNearest::sample() { while(fraction <= 1.0) { - real *channel = (real*)alloca(dsp.settings.channels * sizeof(real)); + std::vector channel(dsp.settings.channels); for(unsigned n = 0; n < dsp.settings.channels; n++) { real a = dsp.buffer.read(n, -1); @@ -32,7 +32,7 @@ void ResampleNearest::sample() { channel[n] = mu < 0.5 ? a : b; } - dsp.write(channel); + dsp.write(channel.data()); fraction += step; } diff --git a/libsnes/bsnes/nall/dsp/resample/sinc.hpp b/waterbox/libsnes/bsnes/nall/dsp/resample/sinc.hpp similarity index 100% rename from libsnes/bsnes/nall/dsp/resample/sinc.hpp rename to waterbox/libsnes/bsnes/nall/dsp/resample/sinc.hpp diff --git a/libsnes/bsnes/nall/dsp/settings.hpp b/waterbox/libsnes/bsnes/nall/dsp/settings.hpp similarity index 100% rename from libsnes/bsnes/nall/dsp/settings.hpp rename to waterbox/libsnes/bsnes/nall/dsp/settings.hpp diff --git a/libsnes/bsnes/nall/endian.hpp b/waterbox/libsnes/bsnes/nall/endian.hpp similarity index 100% rename from libsnes/bsnes/nall/endian.hpp rename to waterbox/libsnes/bsnes/nall/endian.hpp diff --git a/libsnes/bsnes/nall/file.hpp b/waterbox/libsnes/bsnes/nall/file.hpp similarity index 100% rename from libsnes/bsnes/nall/file.hpp rename to waterbox/libsnes/bsnes/nall/file.hpp diff --git a/libsnes/bsnes/nall/filemap.hpp b/waterbox/libsnes/bsnes/nall/filemap.hpp similarity index 100% rename from libsnes/bsnes/nall/filemap.hpp rename to waterbox/libsnes/bsnes/nall/filemap.hpp diff --git a/libsnes/bsnes/nall/function.hpp b/waterbox/libsnes/bsnes/nall/function.hpp similarity index 100% rename from libsnes/bsnes/nall/function.hpp rename to waterbox/libsnes/bsnes/nall/function.hpp diff --git a/libsnes/bsnes/nall/gameboy/cartridge.hpp b/waterbox/libsnes/bsnes/nall/gameboy/cartridge.hpp similarity index 100% rename from libsnes/bsnes/nall/gameboy/cartridge.hpp rename to waterbox/libsnes/bsnes/nall/gameboy/cartridge.hpp diff --git a/libsnes/bsnes/nall/gzip.hpp b/waterbox/libsnes/bsnes/nall/gzip.hpp similarity index 100% rename from libsnes/bsnes/nall/gzip.hpp rename to waterbox/libsnes/bsnes/nall/gzip.hpp diff --git a/libsnes/bsnes/nall/http.hpp b/waterbox/libsnes/bsnes/nall/http.hpp similarity index 100% rename from libsnes/bsnes/nall/http.hpp rename to waterbox/libsnes/bsnes/nall/http.hpp diff --git a/libsnes/bsnes/nall/image.hpp b/waterbox/libsnes/bsnes/nall/image.hpp similarity index 100% rename from libsnes/bsnes/nall/image.hpp rename to waterbox/libsnes/bsnes/nall/image.hpp diff --git a/libsnes/bsnes/nall/inflate.hpp b/waterbox/libsnes/bsnes/nall/inflate.hpp similarity index 100% rename from libsnes/bsnes/nall/inflate.hpp rename to waterbox/libsnes/bsnes/nall/inflate.hpp diff --git a/libsnes/bsnes/nall/input.hpp b/waterbox/libsnes/bsnes/nall/input.hpp similarity index 100% rename from libsnes/bsnes/nall/input.hpp rename to waterbox/libsnes/bsnes/nall/input.hpp diff --git a/libsnes/bsnes/nall/interpolation.hpp b/waterbox/libsnes/bsnes/nall/interpolation.hpp similarity index 100% rename from libsnes/bsnes/nall/interpolation.hpp rename to waterbox/libsnes/bsnes/nall/interpolation.hpp diff --git a/libsnes/bsnes/nall/intrinsics.hpp b/waterbox/libsnes/bsnes/nall/intrinsics.hpp similarity index 100% rename from libsnes/bsnes/nall/intrinsics.hpp rename to waterbox/libsnes/bsnes/nall/intrinsics.hpp diff --git a/libsnes/bsnes/nall/ips.hpp b/waterbox/libsnes/bsnes/nall/ips.hpp similarity index 100% rename from libsnes/bsnes/nall/ips.hpp rename to waterbox/libsnes/bsnes/nall/ips.hpp diff --git a/libsnes/bsnes/nall/lzss.hpp b/waterbox/libsnes/bsnes/nall/lzss.hpp similarity index 100% rename from libsnes/bsnes/nall/lzss.hpp rename to waterbox/libsnes/bsnes/nall/lzss.hpp diff --git a/libsnes/bsnes/nall/map.hpp b/waterbox/libsnes/bsnes/nall/map.hpp similarity index 100% rename from libsnes/bsnes/nall/map.hpp rename to waterbox/libsnes/bsnes/nall/map.hpp diff --git a/libsnes/bsnes/nall/moduloarray.hpp b/waterbox/libsnes/bsnes/nall/moduloarray.hpp similarity index 89% rename from libsnes/bsnes/nall/moduloarray.hpp rename to waterbox/libsnes/bsnes/nall/moduloarray.hpp index be549ae9d6..f6b28ab8b4 100644 --- a/libsnes/bsnes/nall/moduloarray.hpp +++ b/waterbox/libsnes/bsnes/nall/moduloarray.hpp @@ -20,10 +20,6 @@ namespace nall { buffer[index + size + size] = value; } - void serialize(serializer &s) { - s.array(buffer, size * 3); - } - modulo_array() { buffer = new T[size * 3](); } diff --git a/libsnes/bsnes/nall/mosaic.hpp b/waterbox/libsnes/bsnes/nall/mosaic.hpp similarity index 100% rename from libsnes/bsnes/nall/mosaic.hpp rename to waterbox/libsnes/bsnes/nall/mosaic.hpp diff --git a/libsnes/bsnes/nall/mosaic/bitstream.hpp b/waterbox/libsnes/bsnes/nall/mosaic/bitstream.hpp similarity index 100% rename from libsnes/bsnes/nall/mosaic/bitstream.hpp rename to waterbox/libsnes/bsnes/nall/mosaic/bitstream.hpp diff --git a/libsnes/bsnes/nall/mosaic/context.hpp b/waterbox/libsnes/bsnes/nall/mosaic/context.hpp similarity index 100% rename from libsnes/bsnes/nall/mosaic/context.hpp rename to waterbox/libsnes/bsnes/nall/mosaic/context.hpp diff --git a/libsnes/bsnes/nall/mosaic/parser.hpp b/waterbox/libsnes/bsnes/nall/mosaic/parser.hpp similarity index 100% rename from libsnes/bsnes/nall/mosaic/parser.hpp rename to waterbox/libsnes/bsnes/nall/mosaic/parser.hpp diff --git a/libsnes/bsnes/nall/platform.hpp b/waterbox/libsnes/bsnes/nall/platform.hpp similarity index 99% rename from libsnes/bsnes/nall/platform.hpp rename to waterbox/libsnes/bsnes/nall/platform.hpp index b918bd3cb1..7c38cb4ab5 100644 --- a/libsnes/bsnes/nall/platform.hpp +++ b/waterbox/libsnes/bsnes/nall/platform.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/libsnes/bsnes/nall/png.hpp b/waterbox/libsnes/bsnes/nall/png.hpp similarity index 100% rename from libsnes/bsnes/nall/png.hpp rename to waterbox/libsnes/bsnes/nall/png.hpp diff --git a/libsnes/bsnes/nall/priorityqueue.hpp b/waterbox/libsnes/bsnes/nall/priorityqueue.hpp similarity index 92% rename from libsnes/bsnes/nall/priorityqueue.hpp rename to waterbox/libsnes/bsnes/nall/priorityqueue.hpp index 443eac21be..390fcff586 100644 --- a/libsnes/bsnes/nall/priorityqueue.hpp +++ b/waterbox/libsnes/bsnes/nall/priorityqueue.hpp @@ -66,15 +66,6 @@ namespace nall { heapsize = 0; } - void serialize(serializer &s) { - s.integer(basecounter); - s.integer(heapsize); - for(unsigned n = 0; n < heapcapacity; n++) { - s.integer(heap[n].counter); - s.integer(heap[n].event); - } - } - priority_queue(unsigned size, function callback_ = &priority_queue_nocallback) : callback(callback_) { heap = new heap_t[size]; diff --git a/libsnes/bsnes/nall/property.hpp b/waterbox/libsnes/bsnes/nall/property.hpp similarity index 100% rename from libsnes/bsnes/nall/property.hpp rename to waterbox/libsnes/bsnes/nall/property.hpp diff --git a/libsnes/bsnes/nall/public_cast.hpp b/waterbox/libsnes/bsnes/nall/public_cast.hpp similarity index 100% rename from libsnes/bsnes/nall/public_cast.hpp rename to waterbox/libsnes/bsnes/nall/public_cast.hpp diff --git a/libsnes/bsnes/nall/random.hpp b/waterbox/libsnes/bsnes/nall/random.hpp similarity index 100% rename from libsnes/bsnes/nall/random.hpp rename to waterbox/libsnes/bsnes/nall/random.hpp diff --git a/libsnes/bsnes/nall/reference_array.hpp b/waterbox/libsnes/bsnes/nall/reference_array.hpp similarity index 100% rename from libsnes/bsnes/nall/reference_array.hpp rename to waterbox/libsnes/bsnes/nall/reference_array.hpp diff --git a/libsnes/bsnes/nall/serial.hpp b/waterbox/libsnes/bsnes/nall/serial.hpp similarity index 100% rename from libsnes/bsnes/nall/serial.hpp rename to waterbox/libsnes/bsnes/nall/serial.hpp diff --git a/libsnes/bsnes/nall/serializer.hpp b/waterbox/libsnes/bsnes/nall/serializer.hpp similarity index 100% rename from libsnes/bsnes/nall/serializer.hpp rename to waterbox/libsnes/bsnes/nall/serializer.hpp diff --git a/libsnes/bsnes/nall/sha256.hpp b/waterbox/libsnes/bsnes/nall/sha256.hpp similarity index 100% rename from libsnes/bsnes/nall/sha256.hpp rename to waterbox/libsnes/bsnes/nall/sha256.hpp diff --git a/libsnes/bsnes/nall/snes/cartridge.hpp b/waterbox/libsnes/bsnes/nall/snes/cartridge.hpp similarity index 100% rename from libsnes/bsnes/nall/snes/cartridge.hpp rename to waterbox/libsnes/bsnes/nall/snes/cartridge.hpp diff --git a/libsnes/bsnes/nall/snes/cpu.hpp b/waterbox/libsnes/bsnes/nall/snes/cpu.hpp similarity index 100% rename from libsnes/bsnes/nall/snes/cpu.hpp rename to waterbox/libsnes/bsnes/nall/snes/cpu.hpp diff --git a/libsnes/bsnes/nall/snes/smp.hpp b/waterbox/libsnes/bsnes/nall/snes/smp.hpp similarity index 100% rename from libsnes/bsnes/nall/snes/smp.hpp rename to waterbox/libsnes/bsnes/nall/snes/smp.hpp diff --git a/libsnes/bsnes/nall/snes/usart.hpp b/waterbox/libsnes/bsnes/nall/snes/usart.hpp similarity index 100% rename from libsnes/bsnes/nall/snes/usart.hpp rename to waterbox/libsnes/bsnes/nall/snes/usart.hpp diff --git a/libsnes/bsnes/nall/sort.hpp b/waterbox/libsnes/bsnes/nall/sort.hpp similarity index 100% rename from libsnes/bsnes/nall/sort.hpp rename to waterbox/libsnes/bsnes/nall/sort.hpp diff --git a/libsnes/bsnes/nall/stdint.hpp b/waterbox/libsnes/bsnes/nall/stdint.hpp similarity index 100% rename from libsnes/bsnes/nall/stdint.hpp rename to waterbox/libsnes/bsnes/nall/stdint.hpp diff --git a/libsnes/bsnes/nall/stream.hpp b/waterbox/libsnes/bsnes/nall/stream.hpp similarity index 100% rename from libsnes/bsnes/nall/stream.hpp rename to waterbox/libsnes/bsnes/nall/stream.hpp diff --git a/libsnes/bsnes/nall/stream/auto.hpp b/waterbox/libsnes/bsnes/nall/stream/auto.hpp similarity index 100% rename from libsnes/bsnes/nall/stream/auto.hpp rename to waterbox/libsnes/bsnes/nall/stream/auto.hpp diff --git a/libsnes/bsnes/nall/stream/file.hpp b/waterbox/libsnes/bsnes/nall/stream/file.hpp similarity index 100% rename from libsnes/bsnes/nall/stream/file.hpp rename to waterbox/libsnes/bsnes/nall/stream/file.hpp diff --git a/libsnes/bsnes/nall/stream/gzip.hpp b/waterbox/libsnes/bsnes/nall/stream/gzip.hpp similarity index 100% rename from libsnes/bsnes/nall/stream/gzip.hpp rename to waterbox/libsnes/bsnes/nall/stream/gzip.hpp diff --git a/libsnes/bsnes/nall/stream/http.hpp b/waterbox/libsnes/bsnes/nall/stream/http.hpp similarity index 100% rename from libsnes/bsnes/nall/stream/http.hpp rename to waterbox/libsnes/bsnes/nall/stream/http.hpp diff --git a/libsnes/bsnes/nall/stream/memory.hpp b/waterbox/libsnes/bsnes/nall/stream/memory.hpp similarity index 100% rename from libsnes/bsnes/nall/stream/memory.hpp rename to waterbox/libsnes/bsnes/nall/stream/memory.hpp diff --git a/libsnes/bsnes/nall/stream/mmap.hpp b/waterbox/libsnes/bsnes/nall/stream/mmap.hpp similarity index 100% rename from libsnes/bsnes/nall/stream/mmap.hpp rename to waterbox/libsnes/bsnes/nall/stream/mmap.hpp diff --git a/libsnes/bsnes/nall/stream/stream.hpp b/waterbox/libsnes/bsnes/nall/stream/stream.hpp similarity index 100% rename from libsnes/bsnes/nall/stream/stream.hpp rename to waterbox/libsnes/bsnes/nall/stream/stream.hpp diff --git a/libsnes/bsnes/nall/stream/zip.hpp b/waterbox/libsnes/bsnes/nall/stream/zip.hpp similarity index 100% rename from libsnes/bsnes/nall/stream/zip.hpp rename to waterbox/libsnes/bsnes/nall/stream/zip.hpp diff --git a/libsnes/bsnes/nall/string.hpp b/waterbox/libsnes/bsnes/nall/string.hpp similarity index 98% rename from libsnes/bsnes/nall/string.hpp rename to waterbox/libsnes/bsnes/nall/string.hpp index 1233dcfbbc..c29574552b 100644 --- a/libsnes/bsnes/nall/string.hpp +++ b/waterbox/libsnes/bsnes/nall/string.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include diff --git a/libsnes/bsnes/nall/string/base.hpp b/waterbox/libsnes/bsnes/nall/string/base.hpp similarity index 100% rename from libsnes/bsnes/nall/string/base.hpp rename to waterbox/libsnes/bsnes/nall/string/base.hpp diff --git a/libsnes/bsnes/nall/string/bml.hpp b/waterbox/libsnes/bsnes/nall/string/bml.hpp similarity index 100% rename from libsnes/bsnes/nall/string/bml.hpp rename to waterbox/libsnes/bsnes/nall/string/bml.hpp diff --git a/libsnes/bsnes/nall/string/bsv.hpp b/waterbox/libsnes/bsnes/nall/string/bsv.hpp similarity index 100% rename from libsnes/bsnes/nall/string/bsv.hpp rename to waterbox/libsnes/bsnes/nall/string/bsv.hpp diff --git a/libsnes/bsnes/nall/string/cast.hpp b/waterbox/libsnes/bsnes/nall/string/cast.hpp similarity index 100% rename from libsnes/bsnes/nall/string/cast.hpp rename to waterbox/libsnes/bsnes/nall/string/cast.hpp diff --git a/libsnes/bsnes/nall/string/compare.hpp b/waterbox/libsnes/bsnes/nall/string/compare.hpp similarity index 100% rename from libsnes/bsnes/nall/string/compare.hpp rename to waterbox/libsnes/bsnes/nall/string/compare.hpp diff --git a/libsnes/bsnes/nall/string/convert.hpp b/waterbox/libsnes/bsnes/nall/string/convert.hpp similarity index 100% rename from libsnes/bsnes/nall/string/convert.hpp rename to waterbox/libsnes/bsnes/nall/string/convert.hpp diff --git a/libsnes/bsnes/nall/string/core.hpp b/waterbox/libsnes/bsnes/nall/string/core.hpp similarity index 100% rename from libsnes/bsnes/nall/string/core.hpp rename to waterbox/libsnes/bsnes/nall/string/core.hpp diff --git a/libsnes/bsnes/nall/string/cstring.hpp b/waterbox/libsnes/bsnes/nall/string/cstring.hpp similarity index 100% rename from libsnes/bsnes/nall/string/cstring.hpp rename to waterbox/libsnes/bsnes/nall/string/cstring.hpp diff --git a/libsnes/bsnes/nall/string/filename.hpp b/waterbox/libsnes/bsnes/nall/string/filename.hpp similarity index 100% rename from libsnes/bsnes/nall/string/filename.hpp rename to waterbox/libsnes/bsnes/nall/string/filename.hpp diff --git a/libsnes/bsnes/nall/string/math-fixed-point.hpp b/waterbox/libsnes/bsnes/nall/string/math-fixed-point.hpp similarity index 100% rename from libsnes/bsnes/nall/string/math-fixed-point.hpp rename to waterbox/libsnes/bsnes/nall/string/math-fixed-point.hpp diff --git a/libsnes/bsnes/nall/string/math-floating-point.hpp b/waterbox/libsnes/bsnes/nall/string/math-floating-point.hpp similarity index 100% rename from libsnes/bsnes/nall/string/math-floating-point.hpp rename to waterbox/libsnes/bsnes/nall/string/math-floating-point.hpp diff --git a/libsnes/bsnes/nall/string/platform.hpp b/waterbox/libsnes/bsnes/nall/string/platform.hpp similarity index 100% rename from libsnes/bsnes/nall/string/platform.hpp rename to waterbox/libsnes/bsnes/nall/string/platform.hpp diff --git a/libsnes/bsnes/nall/string/replace.hpp b/waterbox/libsnes/bsnes/nall/string/replace.hpp similarity index 100% rename from libsnes/bsnes/nall/string/replace.hpp rename to waterbox/libsnes/bsnes/nall/string/replace.hpp diff --git a/libsnes/bsnes/nall/string/split.hpp b/waterbox/libsnes/bsnes/nall/string/split.hpp similarity index 100% rename from libsnes/bsnes/nall/string/split.hpp rename to waterbox/libsnes/bsnes/nall/string/split.hpp diff --git a/libsnes/bsnes/nall/string/strm.hpp b/waterbox/libsnes/bsnes/nall/string/strm.hpp similarity index 100% rename from libsnes/bsnes/nall/string/strm.hpp rename to waterbox/libsnes/bsnes/nall/string/strm.hpp diff --git a/libsnes/bsnes/nall/string/strpos.hpp b/waterbox/libsnes/bsnes/nall/string/strpos.hpp similarity index 100% rename from libsnes/bsnes/nall/string/strpos.hpp rename to waterbox/libsnes/bsnes/nall/string/strpos.hpp diff --git a/libsnes/bsnes/nall/string/trim.hpp b/waterbox/libsnes/bsnes/nall/string/trim.hpp similarity index 100% rename from libsnes/bsnes/nall/string/trim.hpp rename to waterbox/libsnes/bsnes/nall/string/trim.hpp diff --git a/libsnes/bsnes/nall/string/utf8.hpp b/waterbox/libsnes/bsnes/nall/string/utf8.hpp similarity index 100% rename from libsnes/bsnes/nall/string/utf8.hpp rename to waterbox/libsnes/bsnes/nall/string/utf8.hpp diff --git a/libsnes/bsnes/nall/string/utility.hpp b/waterbox/libsnes/bsnes/nall/string/utility.hpp similarity index 96% rename from libsnes/bsnes/nall/string/utility.hpp rename to waterbox/libsnes/bsnes/nall/string/utility.hpp index d78b90ce9f..945728ba23 100644 --- a/libsnes/bsnes/nall/string/utility.hpp +++ b/waterbox/libsnes/bsnes/nall/string/utility.hpp @@ -166,15 +166,15 @@ template string decimal(uintmax_t value) { buffer[size] = 0; unsigned length = (length_ == 0 ? size : length_); - char* result = (char*)alloca(length + 1); - memset(result, padding, length); + std::vector result(length + 1); + memset(result.data(), padding, length); result[length] = 0; for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) { result[x] = buffer[y]; } - return (const char*)result; + return (const char*)result.data(); } template string ldecimal(uintmax_t value) { @@ -211,15 +211,15 @@ template string hex(uintmax_t value) { } while(value); unsigned length = (length_ == 0 ? size : length_); - char *result = (char*)alloca(length + 1); - memset(result, padding, length); + std::vector result(length + 1); + memset(result.data(), padding, length); result[length] = 0; for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) { result[x] = buffer[y]; } - return (const char*)result; + return (const char*)result.data(); } template string binary(uintmax_t value) { diff --git a/libsnes/bsnes/nall/string/variadic.hpp b/waterbox/libsnes/bsnes/nall/string/variadic.hpp similarity index 100% rename from libsnes/bsnes/nall/string/variadic.hpp rename to waterbox/libsnes/bsnes/nall/string/variadic.hpp diff --git a/libsnes/bsnes/nall/string/wildcard.hpp b/waterbox/libsnes/bsnes/nall/string/wildcard.hpp similarity index 100% rename from libsnes/bsnes/nall/string/wildcard.hpp rename to waterbox/libsnes/bsnes/nall/string/wildcard.hpp diff --git a/libsnes/bsnes/nall/string/wrapper.hpp b/waterbox/libsnes/bsnes/nall/string/wrapper.hpp similarity index 100% rename from libsnes/bsnes/nall/string/wrapper.hpp rename to waterbox/libsnes/bsnes/nall/string/wrapper.hpp diff --git a/libsnes/bsnes/nall/string/xml-legacy.hpp b/waterbox/libsnes/bsnes/nall/string/xml-legacy.hpp similarity index 100% rename from libsnes/bsnes/nall/string/xml-legacy.hpp rename to waterbox/libsnes/bsnes/nall/string/xml-legacy.hpp diff --git a/libsnes/bsnes/nall/string/xml.hpp b/waterbox/libsnes/bsnes/nall/string/xml.hpp similarity index 100% rename from libsnes/bsnes/nall/string/xml.hpp rename to waterbox/libsnes/bsnes/nall/string/xml.hpp diff --git a/libsnes/bsnes/nall/type_traits.hpp b/waterbox/libsnes/bsnes/nall/type_traits.hpp similarity index 100% rename from libsnes/bsnes/nall/type_traits.hpp rename to waterbox/libsnes/bsnes/nall/type_traits.hpp diff --git a/libsnes/bsnes/nall/ups.hpp b/waterbox/libsnes/bsnes/nall/ups.hpp similarity index 100% rename from libsnes/bsnes/nall/ups.hpp rename to waterbox/libsnes/bsnes/nall/ups.hpp diff --git a/libsnes/bsnes/nall/utility.hpp b/waterbox/libsnes/bsnes/nall/utility.hpp similarity index 100% rename from libsnes/bsnes/nall/utility.hpp rename to waterbox/libsnes/bsnes/nall/utility.hpp diff --git a/libsnes/bsnes/nall/varint.hpp b/waterbox/libsnes/bsnes/nall/varint.hpp similarity index 100% rename from libsnes/bsnes/nall/varint.hpp rename to waterbox/libsnes/bsnes/nall/varint.hpp diff --git a/libsnes/bsnes/nall/vector.hpp b/waterbox/libsnes/bsnes/nall/vector.hpp similarity index 100% rename from libsnes/bsnes/nall/vector.hpp rename to waterbox/libsnes/bsnes/nall/vector.hpp diff --git a/libsnes/bsnes/nall/windows/detour.hpp b/waterbox/libsnes/bsnes/nall/windows/detour.hpp similarity index 100% rename from libsnes/bsnes/nall/windows/detour.hpp rename to waterbox/libsnes/bsnes/nall/windows/detour.hpp diff --git a/libsnes/bsnes/nall/windows/launcher.hpp b/waterbox/libsnes/bsnes/nall/windows/launcher.hpp similarity index 100% rename from libsnes/bsnes/nall/windows/launcher.hpp rename to waterbox/libsnes/bsnes/nall/windows/launcher.hpp diff --git a/libsnes/bsnes/nall/windows/utf8.hpp b/waterbox/libsnes/bsnes/nall/windows/utf8.hpp similarity index 100% rename from libsnes/bsnes/nall/windows/utf8.hpp rename to waterbox/libsnes/bsnes/nall/windows/utf8.hpp diff --git a/libsnes/bsnes/nall/xorg/guard.hpp b/waterbox/libsnes/bsnes/nall/xorg/guard.hpp similarity index 100% rename from libsnes/bsnes/nall/xorg/guard.hpp rename to waterbox/libsnes/bsnes/nall/xorg/guard.hpp diff --git a/libsnes/bsnes/nall/xorg/xorg.hpp b/waterbox/libsnes/bsnes/nall/xorg/xorg.hpp similarity index 100% rename from libsnes/bsnes/nall/xorg/xorg.hpp rename to waterbox/libsnes/bsnes/nall/xorg/xorg.hpp diff --git a/libsnes/bsnes/nall/zip.hpp b/waterbox/libsnes/bsnes/nall/zip.hpp similarity index 100% rename from libsnes/bsnes/nall/zip.hpp rename to waterbox/libsnes/bsnes/nall/zip.hpp diff --git a/libsnes/bsnes/snes/alt/cpu/cpu.cpp b/waterbox/libsnes/bsnes/snes/alt/cpu/cpu.cpp similarity index 90% rename from libsnes/bsnes/snes/alt/cpu/cpu.cpp rename to waterbox/libsnes/bsnes/snes/alt/cpu/cpu.cpp index 49958d39b0..585de807ee 100644 --- a/libsnes/bsnes/snes/alt/cpu/cpu.cpp +++ b/waterbox/libsnes/bsnes/snes/alt/cpu/cpu.cpp @@ -5,7 +5,6 @@ namespace SNES { CPU cpu; -#include "serialization.cpp" #include "dma.cpp" #include "memory.cpp" #include "mmio.cpp" @@ -60,24 +59,19 @@ void CPU::enter() { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); } - if (regs.hang == HangType::Wait) this->op_wai(); - else if (regs.hang == HangType::Stop) this->op_stp(); - else - { - if(status.nmi_pending) { - status.nmi_pending = false; - regs.vector = (regs.e == false ? 0xffea : 0xfffa); - op_irq(); - } + if(status.nmi_pending) { + status.nmi_pending = false; + regs.vector = (regs.e == false ? 0xffea : 0xfffa); + op_irq(); + } - if(status.irq_pending) { - status.irq_pending = false; - regs.vector = (regs.e == false ? 0xffee : 0xfffe); - op_irq(); - } + if(status.irq_pending) { + status.irq_pending = false; + regs.vector = (regs.e == false ? 0xffee : 0xfffe); + op_irq(); + } - op_step(); - } + op_step(); } } @@ -119,7 +113,7 @@ void CPU::power() { } void CPU::reset() { - create(Enter, system.cpu_frequency()); + create(Enter, system.cpu_frequency(), 16384); coprocessors.reset(); PPUcounter::reset(); diff --git a/libsnes/bsnes/snes/alt/cpu/cpu.hpp b/waterbox/libsnes/bsnes/snes/alt/cpu/cpu.hpp similarity index 99% rename from libsnes/bsnes/snes/alt/cpu/cpu.hpp rename to waterbox/libsnes/bsnes/snes/alt/cpu/cpu.hpp index e03d2cc358..890765ee7b 100644 --- a/libsnes/bsnes/snes/alt/cpu/cpu.hpp +++ b/waterbox/libsnes/bsnes/snes/alt/cpu/cpu.hpp @@ -27,7 +27,6 @@ public: void power(); void reset(); - void serialize(serializer&); CPU(); ~CPU(); void initialize(); diff --git a/libsnes/bsnes/snes/alt/cpu/dma.cpp b/waterbox/libsnes/bsnes/snes/alt/cpu/dma.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/cpu/dma.cpp rename to waterbox/libsnes/bsnes/snes/alt/cpu/dma.cpp diff --git a/libsnes/bsnes/snes/alt/cpu/memory.cpp b/waterbox/libsnes/bsnes/snes/alt/cpu/memory.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/cpu/memory.cpp rename to waterbox/libsnes/bsnes/snes/alt/cpu/memory.cpp diff --git a/libsnes/bsnes/snes/alt/cpu/mmio.cpp b/waterbox/libsnes/bsnes/snes/alt/cpu/mmio.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/cpu/mmio.cpp rename to waterbox/libsnes/bsnes/snes/alt/cpu/mmio.cpp diff --git a/libsnes/bsnes/snes/alt/cpu/timing.cpp b/waterbox/libsnes/bsnes/snes/alt/cpu/timing.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/cpu/timing.cpp rename to waterbox/libsnes/bsnes/snes/alt/cpu/timing.cpp diff --git a/libsnes/bsnes/snes/alt/dsp/SPC_DSP.cpp b/waterbox/libsnes/bsnes/snes/alt/dsp/SPC_DSP.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/dsp/SPC_DSP.cpp rename to waterbox/libsnes/bsnes/snes/alt/dsp/SPC_DSP.cpp diff --git a/libsnes/bsnes/snes/alt/dsp/SPC_DSP.h b/waterbox/libsnes/bsnes/snes/alt/dsp/SPC_DSP.h similarity index 100% rename from libsnes/bsnes/snes/alt/dsp/SPC_DSP.h rename to waterbox/libsnes/bsnes/snes/alt/dsp/SPC_DSP.h diff --git a/libsnes/bsnes/snes/alt/dsp/blargg_common.h b/waterbox/libsnes/bsnes/snes/alt/dsp/blargg_common.h similarity index 100% rename from libsnes/bsnes/snes/alt/dsp/blargg_common.h rename to waterbox/libsnes/bsnes/snes/alt/dsp/blargg_common.h diff --git a/libsnes/bsnes/snes/alt/dsp/blargg_config.h b/waterbox/libsnes/bsnes/snes/alt/dsp/blargg_config.h similarity index 100% rename from libsnes/bsnes/snes/alt/dsp/blargg_config.h rename to waterbox/libsnes/bsnes/snes/alt/dsp/blargg_config.h diff --git a/libsnes/bsnes/snes/alt/dsp/blargg_endian.h b/waterbox/libsnes/bsnes/snes/alt/dsp/blargg_endian.h similarity index 100% rename from libsnes/bsnes/snes/alt/dsp/blargg_endian.h rename to waterbox/libsnes/bsnes/snes/alt/dsp/blargg_endian.h diff --git a/libsnes/bsnes/snes/alt/dsp/blargg_source.h b/waterbox/libsnes/bsnes/snes/alt/dsp/blargg_source.h similarity index 100% rename from libsnes/bsnes/snes/alt/dsp/blargg_source.h rename to waterbox/libsnes/bsnes/snes/alt/dsp/blargg_source.h diff --git a/libsnes/bsnes/snes/alt/dsp/dsp.cpp b/waterbox/libsnes/bsnes/snes/alt/dsp/dsp.cpp similarity index 97% rename from libsnes/bsnes/snes/alt/dsp/dsp.cpp rename to waterbox/libsnes/bsnes/snes/alt/dsp/dsp.cpp index d0c9e077a8..c6c6c64de5 100644 --- a/libsnes/bsnes/snes/alt/dsp/dsp.cpp +++ b/waterbox/libsnes/bsnes/snes/alt/dsp/dsp.cpp @@ -5,7 +5,6 @@ namespace SNES { DSP dsp; -#include "serialization.cpp" #include "SPC_DSP.cpp" void DSP::step(unsigned clocks) { diff --git a/libsnes/bsnes/snes/alt/dsp/dsp.hpp b/waterbox/libsnes/bsnes/snes/alt/dsp/dsp.hpp similarity index 93% rename from libsnes/bsnes/snes/alt/dsp/dsp.hpp rename to waterbox/libsnes/bsnes/snes/alt/dsp/dsp.hpp index 7335953b0a..79c4e4c42c 100644 --- a/libsnes/bsnes/snes/alt/dsp/dsp.hpp +++ b/waterbox/libsnes/bsnes/snes/alt/dsp/dsp.hpp @@ -15,7 +15,6 @@ public: void channel_enable(unsigned channel, bool enable); - void serialize(serializer&); DSP(); private: diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/memory/memory.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/memory/memory.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-compatibility/memory/memory.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/memory/memory.cpp diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/memory/memory.hpp b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/memory/memory.hpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-compatibility/memory/memory.hpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/memory/memory.hpp diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/mmio/mmio.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/mmio/mmio.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-compatibility/mmio/mmio.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/mmio/mmio.cpp diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/mmio/mmio.hpp b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/mmio/mmio.hpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-compatibility/mmio/mmio.hpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/mmio/mmio.hpp diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.cpp similarity index 92% rename from libsnes/bsnes/snes/alt/ppu-compatibility/ppu.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.cpp index 3e6d2dfaa6..46b21a9d54 100644 --- a/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.cpp +++ b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.cpp @@ -8,7 +8,6 @@ PPU ppu; #include "memory/memory.cpp" #include "mmio/mmio.cpp" #include "render/render.cpp" -#include "serialization.cpp" void PPU::step(unsigned clocks) { clock += clocks; @@ -16,10 +15,7 @@ void PPU::step(unsigned clocks) { void PPU::synchronize_cpu() { if(CPU::Threaded == true) { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) - co_switch(cpu.thread); - else if(clock >= 0 && scheduler.sync == Scheduler::SynchronizeMode::All) - interface()->message("PPU had to advance nondeterministically!"); + if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); } else { while(clock >= 0) cpu.enter(); } @@ -28,33 +24,15 @@ void PPU::synchronize_cpu() { void PPU::Enter() { ppu.enter(); } void PPU::enter() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::CPU) { - synchronize_cpu(); // when in CPU sync mode, always switch back to CPU as soon as possible - } + while(true) { if(scheduler.sync == Scheduler::SynchronizeMode::All) { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - switch(uindex) - { - case 0: enter1(); break; - case 1: enter2(); break; - case 2: enter3(); break; - case 3: enter4(); break; - } - uindex++; - uindex &= 3; - } -} - -void PPU::enter1() { + } + //H = 0 (initialize) scanline(); add_clocks(10); -} - -void PPU::enter2() { + //H = 10 (cache mode7 registers + OAM address reset) cache.m7_hofs = regs.m7_hofs; cache.m7_vofs = regs.m7_vofs; @@ -71,15 +49,11 @@ void PPU::enter2() { } } add_clocks(502); -} - -void PPU::enter3() { + //H = 512 (render) render_scanline(); add_clocks(640); -} - -void PPU::enter4() { + //H = 1152 (cache OBSEL) if(cache.oam_basesize != regs.oam_basesize) { cache.oam_basesize = regs.oam_basesize; @@ -88,6 +62,8 @@ void PPU::enter4() { cache.oam_nameselect = regs.oam_nameselect; cache.oam_tdaddr = regs.oam_tdaddr; add_clocks(lineclocks() - 1152); //seek to start of next scanline + + } } void PPU::add_clocks(unsigned clocks) { @@ -369,11 +345,9 @@ void PPU::power() { } void PPU::reset() { - create(Enter, system.cpu_frequency()); + create(Enter, system.cpu_frequency(), 32768); PPUcounter::reset(); memset(surface, 0, 512 * 512 * sizeof(uint32)); - - uindex = 0; //zero 01-dec-2012 - gotta reset these sometime, somewhere memset(oam_itemlist, 0, sizeof(oam_itemlist)); @@ -445,7 +419,7 @@ void PPU::initialize() oam = (uint8*)interface()->allocSharedMemory("OAM",544); cgram = (uint8*)interface()->allocSharedMemory("CGRAM",512); - surface = new uint32[512 * 512]; + surface = (uint32_t*)alloc_invisible(512 * 512 * sizeof(uint32_t)); output = surface + 16 * 512; alloc_tiledata_cache(); @@ -473,11 +447,7 @@ void PPU::initialize() } PPU::~PPU() { - delete[] surface; - free_tiledata_cache(); - interface()->freeSharedMemory(vram); - interface()->freeSharedMemory(oam); - interface()->freeSharedMemory(cgram); + abort(); } } diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.hpp b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.hpp similarity index 93% rename from libsnes/bsnes/snes/alt/ppu-compatibility/ppu.hpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.hpp index 9036d4f5fd..2df53c1e8e 100644 --- a/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.hpp +++ b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.hpp @@ -11,8 +11,6 @@ public: #include "memory/memory.hpp" #include "mmio/mmio.hpp" #include "render/render.hpp" - - int uindex; uint32 *surface; uint32 *output; @@ -60,11 +58,7 @@ public: void scanline(); void render_scanline(); void frame(); - void enter(); - void enter1(); - void enter2(); - void enter3(); - void enter4(); + void enter(); void enable(); void power(); void reset(); @@ -75,7 +69,6 @@ public: unsigned framecounter; void set_frameskip(unsigned frameskip); - void serialize(serializer&); void initialize(); PPU(); ~PPU(); diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/render/addsub.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/addsub.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-compatibility/render/addsub.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/addsub.cpp diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/render/bg.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/bg.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-compatibility/render/bg.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/bg.cpp diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/render/cache.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/cache.cpp similarity index 87% rename from libsnes/bsnes/snes/alt/ppu-compatibility/render/cache.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/cache.cpp index 189e55a7ed..551af9104c 100644 --- a/libsnes/bsnes/snes/alt/ppu-compatibility/render/cache.cpp +++ b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/cache.cpp @@ -127,12 +127,12 @@ void PPU::flush_pixel_cache() { } void PPU::alloc_tiledata_cache() { - bg_tiledata[TILE_2BIT] = new uint8_t[262144](); - bg_tiledata[TILE_4BIT] = new uint8_t[131072](); - bg_tiledata[TILE_8BIT] = new uint8_t[ 65536](); - bg_tiledata_state[TILE_2BIT] = new uint8_t[ 4096](); - bg_tiledata_state[TILE_4BIT] = new uint8_t[ 2048](); - bg_tiledata_state[TILE_8BIT] = new uint8_t[ 1024](); + bg_tiledata[TILE_2BIT] = (uint8_t*)alloc_invisible(262144); + bg_tiledata[TILE_4BIT] = (uint8_t*)alloc_invisible(131072); + bg_tiledata[TILE_8BIT] = (uint8_t*)alloc_invisible( 65536); + bg_tiledata_state[TILE_2BIT] = (uint8_t*)alloc_invisible( 4096); + bg_tiledata_state[TILE_4BIT] = (uint8_t*)alloc_invisible( 2048); + bg_tiledata_state[TILE_8BIT] = (uint8_t*)alloc_invisible( 1024); } //marks all tiledata cache entries as dirty @@ -143,12 +143,7 @@ void PPU::flush_tiledata_cache() { } void PPU::free_tiledata_cache() { - delete[] bg_tiledata[TILE_2BIT]; - delete[] bg_tiledata[TILE_4BIT]; - delete[] bg_tiledata[TILE_8BIT]; - delete[] bg_tiledata_state[TILE_2BIT]; - delete[] bg_tiledata_state[TILE_4BIT]; - delete[] bg_tiledata_state[TILE_8BIT]; + abort(); } #endif diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/render/line.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/line.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-compatibility/render/line.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/line.cpp diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/render/mode7.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/mode7.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-compatibility/render/mode7.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/mode7.cpp diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/render/oam.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/oam.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-compatibility/render/oam.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/oam.cpp diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/render/render.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/render.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-compatibility/render/render.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/render.cpp diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/render/render.hpp b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/render.hpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-compatibility/render/render.hpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/render.hpp diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/render/windows.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/windows.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-compatibility/render/windows.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-compatibility/render/windows.cpp diff --git a/libsnes/bsnes/snes/alt/ppu-performance/background/background.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/background/background.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-performance/background/background.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-performance/background/background.cpp diff --git a/libsnes/bsnes/snes/alt/ppu-performance/background/background.hpp b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/background/background.hpp similarity index 97% rename from libsnes/bsnes/snes/alt/ppu-performance/background/background.hpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-performance/background/background.hpp index 04facf00ed..c2bd08d77e 100644 --- a/libsnes/bsnes/snes/alt/ppu-performance/background/background.hpp +++ b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/background/background.hpp @@ -57,7 +57,6 @@ class Background { void render(); void render_mode7(); - void serialize(serializer&); Background(PPU &self, unsigned id); ~Background(); diff --git a/libsnes/bsnes/snes/alt/ppu-performance/background/mode7.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/background/mode7.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-performance/background/mode7.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-performance/background/mode7.cpp diff --git a/libsnes/bsnes/snes/alt/ppu-performance/cache/cache.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/cache/cache.cpp similarity index 88% rename from libsnes/bsnes/snes/alt/ppu-performance/cache/cache.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-performance/cache/cache.cpp index 7d0fe80315..c0942b2f8f 100644 --- a/libsnes/bsnes/snes/alt/ppu-performance/cache/cache.cpp +++ b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/cache/cache.cpp @@ -112,22 +112,23 @@ uint8* PPU::Cache::tile(unsigned bpp, unsigned tile) { } PPU::Cache::Cache(PPU &self) : self(self) { - tiledata[0] = new uint8[262144](); - tiledata[1] = new uint8[131072](); - tiledata[2] = new uint8[ 65536](); - tilevalid[0] = new uint8[ 4096](); - tilevalid[1] = new uint8[ 2048](); - tilevalid[2] = new uint8[ 1024](); + tiledata[0] = (uint8*)alloc_invisible(262144); + tiledata[1] = (uint8*)alloc_invisible(131072); + tiledata[2] = (uint8*)alloc_invisible(65536); + tilevalid[0] = (uint8*)alloc_invisible(4096); + tilevalid[1] = (uint8*)alloc_invisible(2048); + tilevalid[2] = (uint8*)alloc_invisible(1024); +} + +PPU::Cache::invalidate() { + memset(tilevalid[0], 0, 4096); + memset(tilevalid[1], 0, 2048); + memset(tilevalid[2], 0, 1024); } PPU::Cache::~Cache() { - delete[] tiledata[0]; - delete[] tiledata[1]; - delete[] tiledata[2]; - delete[] tilevalid[0]; - delete[] tilevalid[1]; - delete[] tilevalid[2]; + abort(); } #endif diff --git a/libsnes/bsnes/snes/alt/ppu-performance/cache/cache.hpp b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/cache/cache.hpp similarity index 90% rename from libsnes/bsnes/snes/alt/ppu-performance/cache/cache.hpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-performance/cache/cache.hpp index 3e9ae7c610..ec4b2a543e 100644 --- a/libsnes/bsnes/snes/alt/ppu-performance/cache/cache.hpp +++ b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/cache/cache.hpp @@ -7,8 +7,8 @@ public: uint8* tile_4bpp(unsigned tile); uint8* tile_8bpp(unsigned tile); uint8* tile(unsigned bpp, unsigned tile); + void invalidate(); - void serialize(serializer&); Cache(PPU &self); ~Cache(); diff --git a/libsnes/bsnes/snes/alt/ppu-performance/mmio/mmio.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/mmio/mmio.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-performance/mmio/mmio.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-performance/mmio/mmio.cpp diff --git a/libsnes/bsnes/snes/alt/ppu-performance/mmio/mmio.hpp b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/mmio/mmio.hpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-performance/mmio/mmio.hpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-performance/mmio/mmio.hpp diff --git a/libsnes/bsnes/snes/alt/ppu-performance/ppu.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/ppu.cpp similarity index 95% rename from libsnes/bsnes/snes/alt/ppu-performance/ppu.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-performance/ppu.cpp index dacdcd8c62..a286e0b0dc 100644 --- a/libsnes/bsnes/snes/alt/ppu-performance/ppu.cpp +++ b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/ppu.cpp @@ -11,7 +11,6 @@ PPU ppu; #include "background/background.cpp" #include "sprite/sprite.cpp" #include "screen/screen.cpp" -#include "serialization.cpp" void PPU::step(unsigned clocks) { clock += clocks; @@ -139,7 +138,7 @@ vram(nullptr), oam(nullptr), cgram(nullptr) { - surface = new uint32[512 * 512]; + surface = (uint32_t*)alloc_invisible(512 * 512 * sizeof(uint32_t)); output = surface + 16 * 512; display.width = 256; display.height = 224; @@ -148,10 +147,7 @@ cgram(nullptr) } PPU::~PPU() { - delete[] surface; - interface()->freeSharedMemory(vram); - interface()->freeSharedMemory(oam); - interface()->freeSharedMemory(cgram); + abort(); } void PPU::initialize() diff --git a/libsnes/bsnes/snes/alt/ppu-performance/ppu.hpp b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/ppu.hpp similarity index 97% rename from libsnes/bsnes/snes/alt/ppu-performance/ppu.hpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-performance/ppu.hpp index dc61d566cd..a71eab44e4 100644 --- a/libsnes/bsnes/snes/alt/ppu-performance/ppu.hpp +++ b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/ppu.hpp @@ -23,7 +23,6 @@ public: void layer_enable(unsigned layer, unsigned priority, bool enable); void set_frameskip(unsigned frameskip); - void serialize(serializer&); PPU(); ~PPU(); void initialize(); diff --git a/libsnes/bsnes/snes/alt/ppu-performance/screen/screen.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/screen/screen.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-performance/screen/screen.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-performance/screen/screen.cpp diff --git a/libsnes/bsnes/snes/alt/ppu-performance/screen/screen.hpp b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/screen/screen.hpp similarity index 97% rename from libsnes/bsnes/snes/alt/ppu-performance/screen/screen.hpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-performance/screen/screen.hpp index e93d3cd495..dec3214e2e 100644 --- a/libsnes/bsnes/snes/alt/ppu-performance/screen/screen.hpp +++ b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/screen/screen.hpp @@ -35,7 +35,6 @@ class Screen { alwaysinline uint16 get_pixel_sub(unsigned x); void render(); - void serialize(serializer&); Screen(PPU &self); ~Screen(); diff --git a/libsnes/bsnes/snes/alt/ppu-performance/sprite/sprite.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/sprite/sprite.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-performance/sprite/sprite.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-performance/sprite/sprite.cpp diff --git a/libsnes/bsnes/snes/alt/ppu-performance/sprite/sprite.hpp b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/sprite/sprite.hpp similarity index 97% rename from libsnes/bsnes/snes/alt/ppu-performance/sprite/sprite.hpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-performance/sprite/sprite.hpp index 06912d7e24..062f116549 100644 --- a/libsnes/bsnes/snes/alt/ppu-performance/sprite/sprite.hpp +++ b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/sprite/sprite.hpp @@ -63,7 +63,6 @@ class Sprite { alwaysinline bool on_scanline(unsigned sprite); void render(); - void serialize(serializer&); Sprite(PPU &self); PPU &self; diff --git a/libsnes/bsnes/snes/alt/ppu-performance/window/window.cpp b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/window/window.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/ppu-performance/window/window.cpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-performance/window/window.cpp diff --git a/libsnes/bsnes/snes/alt/ppu-performance/window/window.hpp b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/window/window.hpp similarity index 88% rename from libsnes/bsnes/snes/alt/ppu-performance/window/window.hpp rename to waterbox/libsnes/bsnes/snes/alt/ppu-performance/window/window.hpp index ee67dd5e5b..96957b0073 100644 --- a/libsnes/bsnes/snes/alt/ppu-performance/window/window.hpp +++ b/waterbox/libsnes/bsnes/snes/alt/ppu-performance/window/window.hpp @@ -14,7 +14,6 @@ public: uint8 sub[256]; void render(bool screen); - void serialize(serializer&); }; class ColorWindow { @@ -33,5 +32,4 @@ public: uint8 sub[256]; void render(bool screen); - void serialize(serializer&); }; diff --git a/libsnes/bsnes/snes/alt/smp/algorithms.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/algorithms.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/algorithms.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/algorithms.cpp diff --git a/libsnes/bsnes/snes/alt/smp/core.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/core.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/core.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/core.cpp diff --git a/libsnes/bsnes/snes/alt/smp/core/cc.sh b/waterbox/libsnes/bsnes/snes/alt/smp/core/cc.sh similarity index 100% rename from libsnes/bsnes/snes/alt/smp/core/cc.sh rename to waterbox/libsnes/bsnes/snes/alt/smp/core/cc.sh diff --git a/libsnes/bsnes/snes/alt/smp/core/generate.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/core/generate.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/core/generate.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/core/generate.cpp diff --git a/libsnes/bsnes/snes/alt/smp/core/op_misc.b b/waterbox/libsnes/bsnes/snes/alt/smp/core/op_misc.b similarity index 94% rename from libsnes/bsnes/snes/alt/smp/core/op_misc.b rename to waterbox/libsnes/bsnes/snes/alt/smp/core/op_misc.b index fb25865000..d38086fdd2 100644 --- a/libsnes/bsnes/snes/alt/smp/core/op_misc.b +++ b/waterbox/libsnes/bsnes/snes/alt/smp/core/op_misc.b @@ -1,163 +1,163 @@ -nop(0x00) { -1:op_io(); -} - -sleep(0xef), -stop(0xff) { -1:op_io(); -2:op_io(); - regs.pc--; -} - -xcn(0x9f) { -1:op_io(); -2:op_io(); -3:op_io(); -4:op_io(); - regs.a = (regs.a >> 4) | (regs.a << 4); - regs.p.n = !!(regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -daa(0xdf) { -1:op_io(); -2:op_io(); - if(regs.p.c || (regs.a) > 0x99) { - regs.a += 0x60; - regs.p.c = 1; - } - if(regs.p.h || (regs.a & 15) > 0x09) { - regs.a += 0x06; - } - regs.p.n = !!(regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -das(0xbe) { -1:op_io(); -2:op_io(); - if(!regs.p.c || (regs.a) > 0x99) { - regs.a -= 0x60; - regs.p.c = 0; - } - if(!regs.p.h || (regs.a & 15) > 0x09) { - regs.a -= 0x06; - } - regs.p.n = !!(regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -clrc(0x60, regs.p.c = 0), -clrp(0x20, regs.p.p = 0), -setc(0x80, regs.p.c = 1), -setp(0x40, regs.p.p = 1) { -1:op_io(); - $1; -} - -clrv(0xe0) { -1:op_io(); - regs.p.v = 0; - regs.p.h = 0; -} - -notc(0xed) { -1:op_io(); -2:op_io(); - regs.p.c = !regs.p.c; -} - -ei(0xa0, 1), -di(0xc0, 0) { -1:op_io(); -2:op_io(); - regs.p.i = $1; -} - -set0_dp(0x02, rd |= 0x01), -clr0_dp(0x12, rd &= ~0x01), -set1_dp(0x22, rd |= 0x02), -clr1_dp(0x32, rd &= ~0x02), -set2_dp(0x42, rd |= 0x04), -clr2_dp(0x52, rd &= ~0x04), -set3_dp(0x62, rd |= 0x08), -clr3_dp(0x72, rd &= ~0x08), -set4_dp(0x82, rd |= 0x10), -clr4_dp(0x92, rd &= ~0x10), -set5_dp(0xa2, rd |= 0x20), -clr5_dp(0xb2, rd &= ~0x20), -set6_dp(0xc2, rd |= 0x40), -clr6_dp(0xd2, rd &= ~0x40), -set7_dp(0xe2, rd |= 0x80), -clr7_dp(0xf2, rd &= ~0x80) { -1:dp = op_readpc(); -2:rd = op_readdp(dp); -3:$1; - op_writedp(dp, rd); -} - -push_a(0x2d, a), -push_x(0x4d, x), -push_y(0x6d, y), -push_p(0x0d, p) { -1:op_io(); -2:op_io(); -3:op_writestack(regs.$1); -} - -pop_a(0xae, a), -pop_x(0xce, x), -pop_y(0xee, y), -pop_p(0x8e, p) { -1:op_io(); -2:op_io(); -3:regs.$1 = op_readstack(); -} - -mul_ya(0xcf) { -1:op_io(); -2:op_io(); -3:op_io(); -4:op_io(); -5:op_io(); -6:op_io(); -7:op_io(); -8:op_io(); - ya = regs.y * regs.a; - regs.a = ya; - regs.y = ya >> 8; - //result is set based on y (high-byte) only - regs.p.n = !!(regs.y & 0x80); - regs.p.z = (regs.y == 0); -} - -div_ya_x(0x9e) { -1:op_io(); -2:op_io(); -3:op_io(); -4:op_io(); -5:op_io(); -6:op_io(); -7:op_io(); -8:op_io(); -9:op_io(); -10:op_io(); -11:op_io(); - ya = regs.ya; - //overflow set if quotient >= 256 - regs.p.v = !!(regs.y >= regs.x); - regs.p.h = !!((regs.y & 15) >= (regs.x & 15)); - if(regs.y < (regs.x << 1)) { - //if quotient is <= 511 (will fit into 9-bit result) - regs.a = ya / regs.x; - regs.y = ya % regs.x; - } else { - //otherwise, the quotient won't fit into regs.p.v + regs.a - //this emulates the odd behavior of the S-SMP in this case - regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x); - regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x); - } - //result is set based on a (quotient) only - regs.p.n = !!(regs.a & 0x80); - regs.p.z = (regs.a == 0); -} +nop(0x00) { +1:op_io(); +} + +sleep(0xef), +stop(0xff) { +1:op_io(); +2:op_io(); + regs.pc--; +} + +xcn(0x9f) { +1:op_io(); +2:op_io(); +3:op_io(); +4:op_io(); + regs.a = (regs.a >> 4) | (regs.a << 4); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} + +daa(0xdf) { +1:op_io(); +2:op_io(); + if(regs.p.c || (regs.a) > 0x99) { + regs.a += 0x60; + regs.p.c = 1; + } + if(regs.p.h || (regs.a & 15) > 0x09) { + regs.a += 0x06; + } + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} + +das(0xbe) { +1:op_io(); +2:op_io(); + if(!regs.p.c || (regs.a) > 0x99) { + regs.a -= 0x60; + regs.p.c = 0; + } + if(!regs.p.h || (regs.a & 15) > 0x09) { + regs.a -= 0x06; + } + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} + +clrc(0x60, regs.p.c = 0), +clrp(0x20, regs.p.p = 0), +setc(0x80, regs.p.c = 1), +setp(0x40, regs.p.p = 1) { +1:op_io(); + $1; +} + +clrv(0xe0) { +1:op_io(); + regs.p.v = 0; + regs.p.h = 0; +} + +notc(0xed) { +1:op_io(); +2:op_io(); + regs.p.c = !regs.p.c; +} + +ei(0xa0, 1), +di(0xc0, 0) { +1:op_io(); +2:op_io(); + regs.p.i = $1; +} + +set0_dp(0x02, rd |= 0x01), +clr0_dp(0x12, rd &= ~0x01), +set1_dp(0x22, rd |= 0x02), +clr1_dp(0x32, rd &= ~0x02), +set2_dp(0x42, rd |= 0x04), +clr2_dp(0x52, rd &= ~0x04), +set3_dp(0x62, rd |= 0x08), +clr3_dp(0x72, rd &= ~0x08), +set4_dp(0x82, rd |= 0x10), +clr4_dp(0x92, rd &= ~0x10), +set5_dp(0xa2, rd |= 0x20), +clr5_dp(0xb2, rd &= ~0x20), +set6_dp(0xc2, rd |= 0x40), +clr6_dp(0xd2, rd &= ~0x40), +set7_dp(0xe2, rd |= 0x80), +clr7_dp(0xf2, rd &= ~0x80) { +1:dp = op_readpc(); +2:rd = op_readdp(dp); +3:$1; + op_writedp(dp, rd); +} + +push_a(0x2d, a), +push_x(0x4d, x), +push_y(0x6d, y), +push_p(0x0d, p) { +1:op_io(); +2:op_io(); +3:op_writestack(regs.$1); +} + +pop_a(0xae, a), +pop_x(0xce, x), +pop_y(0xee, y), +pop_p(0x8e, p) { +1:op_io(); +2:op_io(); +3:regs.$1 = op_readstack(); +} + +mul_ya(0xcf) { +1:op_io(); +2:op_io(); +3:op_io(); +4:op_io(); +5:op_io(); +6:op_io(); +7:op_io(); +8:op_io(); + ya = regs.y * regs.a; + regs.a = ya; + regs.y = ya >> 8; + //result is set based on y (high-byte) only + regs.p.n = !!(regs.y & 0x80); + regs.p.z = (regs.y == 0); +} + +div_ya_x(0x9e) { +1:op_io(); +2:op_io(); +3:op_io(); +4:op_io(); +5:op_io(); +6:op_io(); +7:op_io(); +8:op_io(); +9:op_io(); +10:op_io(); +11:op_io(); + ya = regs.ya; + //overflow set if quotient >= 256 + regs.p.v = !!(regs.y >= regs.x); + regs.p.h = !!((regs.y & 15) >= (regs.x & 15)); + if(regs.y < (regs.x << 1)) { + //if quotient is <= 511 (will fit into 9-bit result) + regs.a = ya / regs.x; + regs.y = ya % regs.x; + } else { + //otherwise, the quotient won't fit into regs.p.v + regs.a + //this emulates the odd behavior of the S-SMP in this case + regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x); + regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x); + } + //result is set based on a (quotient) only + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} diff --git a/libsnes/bsnes/snes/alt/smp/core/op_misc.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/core/op_misc.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/core/op_misc.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/core/op_misc.cpp diff --git a/libsnes/bsnes/snes/alt/smp/core/op_mov.b b/waterbox/libsnes/bsnes/snes/alt/smp/core/op_mov.b similarity index 94% rename from libsnes/bsnes/snes/alt/smp/core/op_mov.b rename to waterbox/libsnes/bsnes/snes/alt/smp/core/op_mov.b index dee821afad..37b1116b09 100644 --- a/libsnes/bsnes/snes/alt/smp/core/op_mov.b +++ b/waterbox/libsnes/bsnes/snes/alt/smp/core/op_mov.b @@ -1,217 +1,217 @@ -mov_a_x(0x7d, a, x), -mov_a_y(0xdd, a, y), -mov_x_a(0x5d, x, a), -mov_y_a(0xfd, y, a), -mov_x_sp(0x9d, x, sp) { -1:op_io(); - regs.$1 = regs.$2; - regs.p.n = !!(regs.$1 & 0x80); - regs.p.z = (regs.$1 == 0); -} - -mov_sp_x(0xbd, sp, x) { -1:op_io(); - regs.$1 = regs.$2; -} - -mov_a_const(0xe8, a), -mov_x_const(0xcd, x), -mov_y_const(0x8d, y) { -1:regs.$1 = op_readpc(); - regs.p.n = !!(regs.$1 & 0x80); - regs.p.z = (regs.$1 == 0); -} - -mov_a_ix(0xe6) { -1:op_io(); -2:regs.a = op_readdp(regs.x); - regs.p.n = !!(regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -mov_a_ixinc(0xbf) { -1:op_io(); -2:regs.a = op_readdp(regs.x++); -3:op_io(); - regs.p.n = !!(regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -mov_a_dp(0xe4, a), -mov_x_dp(0xf8, x), -mov_y_dp(0xeb, y) { -1:sp = op_readpc(); -2:regs.$1 = op_readdp(sp); - regs.p.n = !!(regs.$1 & 0x80); - regs.p.z = (regs.$1 == 0); -} - -mov_a_dpx(0xf4, a, x), -mov_x_dpy(0xf9, x, y), -mov_y_dpx(0xfb, y, x) { -1:sp = op_readpc(); -2:op_io(); -3:regs.$1 = op_readdp(sp + regs.$2); - regs.p.n = !!(regs.$1 & 0x80); - regs.p.z = (regs.$1 == 0); -} - -mov_a_addr(0xe5, a), -mov_x_addr(0xe9, x), -mov_y_addr(0xec, y) { -1:sp = op_readpc(); -2:sp |= op_readpc() << 8; -3:regs.$1 = op_readaddr(sp); - regs.p.n = !!(regs.$1 & 0x80); - regs.p.z = (regs.$1 == 0); -} - -mov_a_addrx(0xf5, x), -mov_a_addry(0xf6, y) { -1:sp = op_readpc(); -2:sp |= op_readpc() << 8; -3:op_io(); -4:regs.a = op_readaddr(sp + regs.$1); - regs.p.n = !!(regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -mov_a_idpx(0xe7) { -1:dp = op_readpc() + regs.x; -2:op_io(); -3:sp = op_readdp(dp); -4:sp |= op_readdp(dp + 1) << 8; -5:regs.a = op_readaddr(sp); - regs.p.n = !!(regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -mov_a_idpy(0xf7) { -1:dp = op_readpc(); -2:op_io(); -3:sp = op_readdp(dp); -4:sp |= op_readdp(dp + 1) << 8; -5:regs.a = op_readaddr(sp + regs.y); - regs.p.n = !!(regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -mov_dp_dp(0xfa) { -1:sp = op_readpc(); -2:rd = op_readdp(sp); -3:dp = op_readpc(); -4:op_writedp(dp, rd); -} - -mov_dp_const(0x8f) { -1:rd = op_readpc(); -2:dp = op_readpc(); -3:op_readdp(dp); -4:op_writedp(dp, rd); -} - -mov_ix_a(0xc6) { -1:op_io(); -2:op_readdp(regs.x); -3:op_writedp(regs.x, regs.a); -} - -mov_ixinc_a(0xaf) { -1:op_io(); -2:op_io(); -3:op_writedp(regs.x++, regs.a); -} - -mov_dp_a(0xc4, a), -mov_dp_x(0xd8, x), -mov_dp_y(0xcb, y) { -1:dp = op_readpc(); -2:op_readdp(dp); -3:op_writedp(dp, regs.$1); -} - -mov_dpx_a(0xd4, x, a), -mov_dpy_x(0xd9, y, x), -mov_dpx_y(0xdb, x, y) { -1:dp = op_readpc(); -2:op_io(); - dp += regs.$1; -3:op_readdp(dp); -4:op_writedp(dp, regs.$2); -} - -mov_addr_a(0xc5, a), -mov_addr_x(0xc9, x), -mov_addr_y(0xcc, y) { -1:dp = op_readpc(); -2:dp |= op_readpc() << 8; -3:op_readaddr(dp); -4:op_writeaddr(dp, regs.$1); -} - -mov_addrx_a(0xd5, x), -mov_addry_a(0xd6, y) { -1:dp = op_readpc(); -2:dp |= op_readpc() << 8; -3:op_io(); - dp += regs.$1; -4:op_readaddr(dp); -5:op_writeaddr(dp, regs.a); -} - -mov_idpx_a(0xc7) { -1:sp = op_readpc(); -2:op_io(); - sp += regs.x; -3:dp = op_readdp(sp); -4:dp |= op_readdp(sp + 1) << 8; -5:op_readaddr(dp); -6:op_writeaddr(dp, regs.a); -} - -mov_idpy_a(0xd7) { -1:sp = op_readpc(); -2:dp = op_readdp(sp); -3:dp |= op_readdp(sp + 1) << 8; -4:op_io(); - dp += regs.y; -5:op_readaddr(dp); -6:op_writeaddr(dp, regs.a); -} - -movw_ya_dp(0xba) { -1:sp = op_readpc(); -2:regs.a = op_readdp(sp); -3:op_io(); -4:regs.y = op_readdp(sp + 1); - regs.p.n = !!(regs.ya & 0x8000); - regs.p.z = (regs.ya == 0); -} - -movw_dp_ya(0xda) { -1:dp = op_readpc(); -2:op_readdp(dp); -3:op_writedp(dp, regs.a); -4:op_writedp(dp + 1, regs.y); -} - -mov1_c_bit(0xaa) { -1:sp = op_readpc(); -2:sp |= op_readpc() << 8; -3:bit = sp >> 13; - sp &= 0x1fff; - rd = op_readaddr(sp); - regs.p.c = !!(rd & (1 << bit)); -} - -mov1_bit_c(0xca) { -1:dp = op_readpc(); -2:dp |= op_readpc() << 8; -3:bit = dp >> 13; - dp &= 0x1fff; - rd = op_readaddr(dp); - if(regs.p.c)rd |= (1 << bit); - else rd &= ~(1 << bit); -4:op_io(); -5:op_writeaddr(dp, rd); -} +mov_a_x(0x7d, a, x), +mov_a_y(0xdd, a, y), +mov_x_a(0x5d, x, a), +mov_y_a(0xfd, y, a), +mov_x_sp(0x9d, x, sp) { +1:op_io(); + regs.$1 = regs.$2; + regs.p.n = !!(regs.$1 & 0x80); + regs.p.z = (regs.$1 == 0); +} + +mov_sp_x(0xbd, sp, x) { +1:op_io(); + regs.$1 = regs.$2; +} + +mov_a_const(0xe8, a), +mov_x_const(0xcd, x), +mov_y_const(0x8d, y) { +1:regs.$1 = op_readpc(); + regs.p.n = !!(regs.$1 & 0x80); + regs.p.z = (regs.$1 == 0); +} + +mov_a_ix(0xe6) { +1:op_io(); +2:regs.a = op_readdp(regs.x); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} + +mov_a_ixinc(0xbf) { +1:op_io(); +2:regs.a = op_readdp(regs.x++); +3:op_io(); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} + +mov_a_dp(0xe4, a), +mov_x_dp(0xf8, x), +mov_y_dp(0xeb, y) { +1:sp = op_readpc(); +2:regs.$1 = op_readdp(sp); + regs.p.n = !!(regs.$1 & 0x80); + regs.p.z = (regs.$1 == 0); +} + +mov_a_dpx(0xf4, a, x), +mov_x_dpy(0xf9, x, y), +mov_y_dpx(0xfb, y, x) { +1:sp = op_readpc(); +2:op_io(); +3:regs.$1 = op_readdp(sp + regs.$2); + regs.p.n = !!(regs.$1 & 0x80); + regs.p.z = (regs.$1 == 0); +} + +mov_a_addr(0xe5, a), +mov_x_addr(0xe9, x), +mov_y_addr(0xec, y) { +1:sp = op_readpc(); +2:sp |= op_readpc() << 8; +3:regs.$1 = op_readaddr(sp); + regs.p.n = !!(regs.$1 & 0x80); + regs.p.z = (regs.$1 == 0); +} + +mov_a_addrx(0xf5, x), +mov_a_addry(0xf6, y) { +1:sp = op_readpc(); +2:sp |= op_readpc() << 8; +3:op_io(); +4:regs.a = op_readaddr(sp + regs.$1); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} + +mov_a_idpx(0xe7) { +1:dp = op_readpc() + regs.x; +2:op_io(); +3:sp = op_readdp(dp); +4:sp |= op_readdp(dp + 1) << 8; +5:regs.a = op_readaddr(sp); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} + +mov_a_idpy(0xf7) { +1:dp = op_readpc(); +2:op_io(); +3:sp = op_readdp(dp); +4:sp |= op_readdp(dp + 1) << 8; +5:regs.a = op_readaddr(sp + regs.y); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} + +mov_dp_dp(0xfa) { +1:sp = op_readpc(); +2:rd = op_readdp(sp); +3:dp = op_readpc(); +4:op_writedp(dp, rd); +} + +mov_dp_const(0x8f) { +1:rd = op_readpc(); +2:dp = op_readpc(); +3:op_readdp(dp); +4:op_writedp(dp, rd); +} + +mov_ix_a(0xc6) { +1:op_io(); +2:op_readdp(regs.x); +3:op_writedp(regs.x, regs.a); +} + +mov_ixinc_a(0xaf) { +1:op_io(); +2:op_io(); +3:op_writedp(regs.x++, regs.a); +} + +mov_dp_a(0xc4, a), +mov_dp_x(0xd8, x), +mov_dp_y(0xcb, y) { +1:dp = op_readpc(); +2:op_readdp(dp); +3:op_writedp(dp, regs.$1); +} + +mov_dpx_a(0xd4, x, a), +mov_dpy_x(0xd9, y, x), +mov_dpx_y(0xdb, x, y) { +1:dp = op_readpc(); +2:op_io(); + dp += regs.$1; +3:op_readdp(dp); +4:op_writedp(dp, regs.$2); +} + +mov_addr_a(0xc5, a), +mov_addr_x(0xc9, x), +mov_addr_y(0xcc, y) { +1:dp = op_readpc(); +2:dp |= op_readpc() << 8; +3:op_readaddr(dp); +4:op_writeaddr(dp, regs.$1); +} + +mov_addrx_a(0xd5, x), +mov_addry_a(0xd6, y) { +1:dp = op_readpc(); +2:dp |= op_readpc() << 8; +3:op_io(); + dp += regs.$1; +4:op_readaddr(dp); +5:op_writeaddr(dp, regs.a); +} + +mov_idpx_a(0xc7) { +1:sp = op_readpc(); +2:op_io(); + sp += regs.x; +3:dp = op_readdp(sp); +4:dp |= op_readdp(sp + 1) << 8; +5:op_readaddr(dp); +6:op_writeaddr(dp, regs.a); +} + +mov_idpy_a(0xd7) { +1:sp = op_readpc(); +2:dp = op_readdp(sp); +3:dp |= op_readdp(sp + 1) << 8; +4:op_io(); + dp += regs.y; +5:op_readaddr(dp); +6:op_writeaddr(dp, regs.a); +} + +movw_ya_dp(0xba) { +1:sp = op_readpc(); +2:regs.a = op_readdp(sp); +3:op_io(); +4:regs.y = op_readdp(sp + 1); + regs.p.n = !!(regs.ya & 0x8000); + regs.p.z = (regs.ya == 0); +} + +movw_dp_ya(0xda) { +1:dp = op_readpc(); +2:op_readdp(dp); +3:op_writedp(dp, regs.a); +4:op_writedp(dp + 1, regs.y); +} + +mov1_c_bit(0xaa) { +1:sp = op_readpc(); +2:sp |= op_readpc() << 8; +3:bit = sp >> 13; + sp &= 0x1fff; + rd = op_readaddr(sp); + regs.p.c = !!(rd & (1 << bit)); +} + +mov1_bit_c(0xca) { +1:dp = op_readpc(); +2:dp |= op_readpc() << 8; +3:bit = dp >> 13; + dp &= 0x1fff; + rd = op_readaddr(dp); + if(regs.p.c)rd |= (1 << bit); + else rd &= ~(1 << bit); +4:op_io(); +5:op_writeaddr(dp, rd); +} diff --git a/libsnes/bsnes/snes/alt/smp/core/op_mov.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/core/op_mov.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/core/op_mov.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/core/op_mov.cpp diff --git a/libsnes/bsnes/snes/alt/smp/core/op_pc.b b/waterbox/libsnes/bsnes/snes/alt/smp/core/op_pc.b similarity index 94% rename from libsnes/bsnes/snes/alt/smp/core/op_pc.b rename to waterbox/libsnes/bsnes/snes/alt/smp/core/op_pc.b index affaf844c5..4339377d84 100644 --- a/libsnes/bsnes/snes/alt/smp/core/op_pc.b +++ b/waterbox/libsnes/bsnes/snes/alt/smp/core/op_pc.b @@ -1,179 +1,179 @@ -bra(0x2f, 0), -beq(0xf0, !regs.p.z), -bne(0xd0, regs.p.z), -bcs(0xb0, !regs.p.c), -bcc(0x90, regs.p.c), -bvs(0x70, !regs.p.v), -bvc(0x50, regs.p.v), -bmi(0x30, !regs.p.n), -bpl(0x10, regs.p.n) { -1:rd = op_readpc(); - if($1)end; -2:op_io(); -3:op_io(); - regs.pc += (int8)rd; -} - -bbs0(0x03, 0x01, !=), -bbc0(0x13, 0x01, ==), -bbs1(0x23, 0x02, !=), -bbc1(0x33, 0x02, ==), -bbs2(0x43, 0x04, !=), -bbc2(0x53, 0x04, ==), -bbs3(0x63, 0x08, !=), -bbc3(0x73, 0x08, ==), -bbs4(0x83, 0x10, !=), -bbc4(0x93, 0x10, ==), -bbs5(0xa3, 0x20, !=), -bbc5(0xb3, 0x20, ==), -bbs6(0xc3, 0x40, !=), -bbc6(0xd3, 0x40, ==), -bbs7(0xe3, 0x80, !=), -bbc7(0xf3, 0x80, ==) { -1:dp = op_readpc(); -2:sp = op_readdp(dp); -3:rd = op_readpc(); -4:op_io(); - if((sp & $1) $2 $1)end; -5:op_io(); -6:op_io(); - regs.pc += (int8)rd; -} - -cbne_dp(0x2e) { -1:dp = op_readpc(); -2:sp = op_readdp(dp); -3:rd = op_readpc(); -4:op_io(); - if(regs.a == sp)end; -5:op_io(); -6:op_io(); - regs.pc += (int8)rd; -} - -cbne_dpx(0xde) { -1:dp = op_readpc(); -2:op_io(); -3:sp = op_readdp(dp + regs.x); -4:rd = op_readpc(); -5:op_io(); - if(regs.a == sp)end; -6:op_io(); -7:op_io(); - regs.pc += (int8)rd; -} - -dbnz_dp(0x6e) { -1:dp = op_readpc(); -2:wr = op_readdp(dp); -3:op_writedp(dp, --wr); -4:rd = op_readpc(); - if(wr == 0x00)end; -5:op_io(); -6:op_io(); - regs.pc += (int8)rd; -} - -dbnz_y(0xfe) { -1:rd = op_readpc(); -2:op_io(); - regs.y--; -3:op_io(); - if(regs.y == 0x00)end; -4:op_io(); -5:op_io(); - regs.pc += (int8)rd; -} - -jmp_addr(0x5f) { -1:rd = op_readpc(); -2:rd |= op_readpc() << 8; - regs.pc = rd; -} - -jmp_iaddrx(0x1f) { -1:dp = op_readpc(); -2:dp |= op_readpc() << 8; -3:op_io(); - dp += regs.x; -4:rd = op_readaddr(dp); -5:rd |= op_readaddr(dp + 1) << 8; - regs.pc = rd; -} - -call(0x3f) { -1:rd = op_readpc(); -2:rd |= op_readpc() << 8; -3:op_io(); -4:op_io(); -5:op_io(); -6:op_writestack(regs.pc >> 8); -7:op_writestack(regs.pc); - regs.pc = rd; -} - -pcall(0x4f) { -1:rd = op_readpc(); -2:op_io(); -3:op_io(); -4:op_writestack(regs.pc >> 8); -5:op_writestack(regs.pc); - regs.pc = 0xff00 | rd; -} - -tcall_0(0x01, 0), -tcall_1(0x11, 1), -tcall_2(0x21, 2), -tcall_3(0x31, 3), -tcall_4(0x41, 4), -tcall_5(0x51, 5), -tcall_6(0x61, 6), -tcall_7(0x71, 7), -tcall_8(0x81, 8), -tcall_9(0x91, 9), -tcall_10(0xa1, 10), -tcall_11(0xb1, 11), -tcall_12(0xc1, 12), -tcall_13(0xd1, 13), -tcall_14(0xe1, 14), -tcall_15(0xf1, 15) { -1:dp = 0xffde - ($1 << 1); - rd = op_readaddr(dp); -2:rd |= op_readaddr(dp + 1) << 8; -3:op_io(); -4:op_io(); -5:op_io(); -6:op_writestack(regs.pc >> 8); -7:op_writestack(regs.pc); - regs.pc = rd; -} - -brk(0x0f) { -1:rd = op_readaddr(0xffde); -2:rd |= op_readaddr(0xffdf) << 8; -3:op_io(); -4:op_io(); -5:op_writestack(regs.pc >> 8); -6:op_writestack(regs.pc); -7:op_writestack(regs.p); - regs.pc = rd; - regs.p.b = 1; - regs.p.i = 0; -} - -ret(0x6f) { -1:rd = op_readstack(); -2:rd |= op_readstack() << 8; -3:op_io(); -4:op_io(); - regs.pc = rd; -} - -reti(0x7f) { -1:regs.p = op_readstack(); -2:rd = op_readstack(); -3:rd |= op_readstack() << 8; -4:op_io(); -5:op_io(); - regs.pc = rd; -} +bra(0x2f, 0), +beq(0xf0, !regs.p.z), +bne(0xd0, regs.p.z), +bcs(0xb0, !regs.p.c), +bcc(0x90, regs.p.c), +bvs(0x70, !regs.p.v), +bvc(0x50, regs.p.v), +bmi(0x30, !regs.p.n), +bpl(0x10, regs.p.n) { +1:rd = op_readpc(); + if($1)end; +2:op_io(); +3:op_io(); + regs.pc += (int8)rd; +} + +bbs0(0x03, 0x01, !=), +bbc0(0x13, 0x01, ==), +bbs1(0x23, 0x02, !=), +bbc1(0x33, 0x02, ==), +bbs2(0x43, 0x04, !=), +bbc2(0x53, 0x04, ==), +bbs3(0x63, 0x08, !=), +bbc3(0x73, 0x08, ==), +bbs4(0x83, 0x10, !=), +bbc4(0x93, 0x10, ==), +bbs5(0xa3, 0x20, !=), +bbc5(0xb3, 0x20, ==), +bbs6(0xc3, 0x40, !=), +bbc6(0xd3, 0x40, ==), +bbs7(0xe3, 0x80, !=), +bbc7(0xf3, 0x80, ==) { +1:dp = op_readpc(); +2:sp = op_readdp(dp); +3:rd = op_readpc(); +4:op_io(); + if((sp & $1) $2 $1)end; +5:op_io(); +6:op_io(); + regs.pc += (int8)rd; +} + +cbne_dp(0x2e) { +1:dp = op_readpc(); +2:sp = op_readdp(dp); +3:rd = op_readpc(); +4:op_io(); + if(regs.a == sp)end; +5:op_io(); +6:op_io(); + regs.pc += (int8)rd; +} + +cbne_dpx(0xde) { +1:dp = op_readpc(); +2:op_io(); +3:sp = op_readdp(dp + regs.x); +4:rd = op_readpc(); +5:op_io(); + if(regs.a == sp)end; +6:op_io(); +7:op_io(); + regs.pc += (int8)rd; +} + +dbnz_dp(0x6e) { +1:dp = op_readpc(); +2:wr = op_readdp(dp); +3:op_writedp(dp, --wr); +4:rd = op_readpc(); + if(wr == 0x00)end; +5:op_io(); +6:op_io(); + regs.pc += (int8)rd; +} + +dbnz_y(0xfe) { +1:rd = op_readpc(); +2:op_io(); + regs.y--; +3:op_io(); + if(regs.y == 0x00)end; +4:op_io(); +5:op_io(); + regs.pc += (int8)rd; +} + +jmp_addr(0x5f) { +1:rd = op_readpc(); +2:rd |= op_readpc() << 8; + regs.pc = rd; +} + +jmp_iaddrx(0x1f) { +1:dp = op_readpc(); +2:dp |= op_readpc() << 8; +3:op_io(); + dp += regs.x; +4:rd = op_readaddr(dp); +5:rd |= op_readaddr(dp + 1) << 8; + regs.pc = rd; +} + +call(0x3f) { +1:rd = op_readpc(); +2:rd |= op_readpc() << 8; +3:op_io(); +4:op_io(); +5:op_io(); +6:op_writestack(regs.pc >> 8); +7:op_writestack(regs.pc); + regs.pc = rd; +} + +pcall(0x4f) { +1:rd = op_readpc(); +2:op_io(); +3:op_io(); +4:op_writestack(regs.pc >> 8); +5:op_writestack(regs.pc); + regs.pc = 0xff00 | rd; +} + +tcall_0(0x01, 0), +tcall_1(0x11, 1), +tcall_2(0x21, 2), +tcall_3(0x31, 3), +tcall_4(0x41, 4), +tcall_5(0x51, 5), +tcall_6(0x61, 6), +tcall_7(0x71, 7), +tcall_8(0x81, 8), +tcall_9(0x91, 9), +tcall_10(0xa1, 10), +tcall_11(0xb1, 11), +tcall_12(0xc1, 12), +tcall_13(0xd1, 13), +tcall_14(0xe1, 14), +tcall_15(0xf1, 15) { +1:dp = 0xffde - ($1 << 1); + rd = op_readaddr(dp); +2:rd |= op_readaddr(dp + 1) << 8; +3:op_io(); +4:op_io(); +5:op_io(); +6:op_writestack(regs.pc >> 8); +7:op_writestack(regs.pc); + regs.pc = rd; +} + +brk(0x0f) { +1:rd = op_readaddr(0xffde); +2:rd |= op_readaddr(0xffdf) << 8; +3:op_io(); +4:op_io(); +5:op_writestack(regs.pc >> 8); +6:op_writestack(regs.pc); +7:op_writestack(regs.p); + regs.pc = rd; + regs.p.b = 1; + regs.p.i = 0; +} + +ret(0x6f) { +1:rd = op_readstack(); +2:rd |= op_readstack() << 8; +3:op_io(); +4:op_io(); + regs.pc = rd; +} + +reti(0x7f) { +1:regs.p = op_readstack(); +2:rd = op_readstack(); +3:rd |= op_readstack() << 8; +4:op_io(); +5:op_io(); + regs.pc = rd; +} diff --git a/libsnes/bsnes/snes/alt/smp/core/op_pc.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/core/op_pc.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/core/op_pc.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/core/op_pc.cpp diff --git a/libsnes/bsnes/snes/alt/smp/core/op_read.b b/waterbox/libsnes/bsnes/snes/alt/smp/core/op_read.b similarity index 95% rename from libsnes/bsnes/snes/alt/smp/core/op_read.b rename to waterbox/libsnes/bsnes/snes/alt/smp/core/op_read.b index fd2f9d8256..d46e1d2f3f 100644 --- a/libsnes/bsnes/snes/alt/smp/core/op_read.b +++ b/waterbox/libsnes/bsnes/snes/alt/smp/core/op_read.b @@ -1,205 +1,205 @@ -adc_a_const(0x88, adc, a), -and_a_const(0x28, and, a), -cmp_a_const(0x68, cmp, a), -cmp_x_const(0xc8, cmp, x), -cmp_y_const(0xad, cmp, y), -eor_a_const(0x48, eor, a), -or_a_const(0x08, or, a), -sbc_a_const(0xa8, sbc, a) { -1:rd = op_readpc(); - regs.$2 = op_$1(regs.$2, rd); -} - -adc_a_ix(0x86, adc), -and_a_ix(0x26, and), -cmp_a_ix(0x66, cmp), -eor_a_ix(0x46, eor), -or_a_ix(0x06, or), -sbc_a_ix(0xa6, sbc) { -1:op_io(); -2:rd = op_readdp(regs.x); - regs.a = op_$1(regs.a, rd); -} - -adc_a_dp(0x84, adc, a), -and_a_dp(0x24, and, a), -cmp_a_dp(0x64, cmp, a), -cmp_x_dp(0x3e, cmp, x), -cmp_y_dp(0x7e, cmp, y), -eor_a_dp(0x44, eor, a), -or_a_dp(0x04, or, a), -sbc_a_dp(0xa4, sbc, a) { -1:dp = op_readpc(); -2:rd = op_readdp(dp); - regs.$2 = op_$1(regs.$2, rd); -} - -adc_a_dpx(0x94, adc), -and_a_dpx(0x34, and), -cmp_a_dpx(0x74, cmp), -eor_a_dpx(0x54, eor), -or_a_dpx(0x14, or), -sbc_a_dpx(0xb4, sbc) { -1:dp = op_readpc(); -2:op_io(); -3:rd = op_readdp(dp + regs.x); - regs.a = op_$1(regs.a, rd); -} - -adc_a_addr(0x85, adc, a), -and_a_addr(0x25, and, a), -cmp_a_addr(0x65, cmp, a), -cmp_x_addr(0x1e, cmp, x), -cmp_y_addr(0x5e, cmp, y), -eor_a_addr(0x45, eor, a), -or_a_addr(0x05, or, a), -sbc_a_addr(0xa5, sbc, a) { -1:dp = op_readpc(); -2:dp |= op_readpc() << 8; -3:rd = op_readaddr(dp); - regs.$2 = op_$1(regs.$2, rd); -} - -adc_a_addrx(0x95, adc, x), -adc_a_addry(0x96, adc, y), -and_a_addrx(0x35, and, x), -and_a_addry(0x36, and, y), -cmp_a_addrx(0x75, cmp, x), -cmp_a_addry(0x76, cmp, y), -eor_a_addrx(0x55, eor, x), -eor_a_addry(0x56, eor, y), -or_a_addrx(0x15, or, x), -or_a_addry(0x16, or, y), -sbc_a_addrx(0xb5, sbc, x), -sbc_a_addry(0xb6, sbc, y) { -1:dp = op_readpc(); -2:dp |= op_readpc() << 8; -3:op_io(); -4:rd = op_readaddr(dp + regs.$2); - regs.a = op_$1(regs.a, rd); -} - -adc_a_idpx(0x87, adc), -and_a_idpx(0x27, and), -cmp_a_idpx(0x67, cmp), -eor_a_idpx(0x47, eor), -or_a_idpx(0x07, or), -sbc_a_idpx(0xa7, sbc) { -1:dp = op_readpc() + regs.x; -2:op_io(); -3:sp = op_readdp(dp); -4:sp |= op_readdp(dp + 1) << 8; -5:rd = op_readaddr(sp); - regs.a = op_$1(regs.a, rd); -} - -adc_a_idpy(0x97, adc), -and_a_idpy(0x37, and), -cmp_a_idpy(0x77, cmp), -eor_a_idpy(0x57, eor), -or_a_idpy(0x17, or), -sbc_a_idpy(0xb7, sbc) { -1:dp = op_readpc(); -2:op_io(); -3:sp = op_readdp(dp); -4:sp |= op_readdp(dp + 1) << 8; -5:rd = op_readaddr(sp + regs.y); - regs.a = op_$1(regs.a, rd); -} - -adc_ix_iy(0x99, adc, 1), -and_ix_iy(0x39, and, 1), -cmp_ix_iy(0x79, cmp, 0), -eor_ix_iy(0x59, eor, 1), -or_ix_iy(0x19, or, 1), -sbc_ix_iy(0xb9, sbc, 1) { -1:op_io(); -2:rd = op_readdp(regs.y); -3:wr = op_readdp(regs.x); - wr = op_$1(wr, rd); -4:($2) ? op_writedp(regs.x, wr) : op_io(); -} - -adc_dp_dp(0x89, adc, 1), -and_dp_dp(0x29, and, 1), -cmp_dp_dp(0x69, cmp, 0), -eor_dp_dp(0x49, eor, 1), -or_dp_dp(0x09, or, 1), -sbc_dp_dp(0xa9, sbc, 1) { -1:sp = op_readpc(); -2:rd = op_readdp(sp); -3:dp = op_readpc(); -4:wr = op_readdp(dp); -5:wr = op_$1(wr, rd); - ($2) ? op_writedp(dp, wr) : op_io(); -} - -adc_dp_const(0x98, adc, 1), -and_dp_const(0x38, and, 1), -cmp_dp_const(0x78, cmp, 0), -eor_dp_const(0x58, eor, 1), -or_dp_const(0x18, or, 1), -sbc_dp_const(0xb8, sbc, 1) { -1:rd = op_readpc(); -2:dp = op_readpc(); -3:wr = op_readdp(dp); -4:wr = op_$1(wr, rd); - ($2) ? op_writedp(dp, wr) : op_io(); -} - -addw_ya_dp(0x7a, addw), -subw_ya_dp(0x9a, subw) { -1:dp = op_readpc(); -2:rd = op_readdp(dp); -3:op_io(); -4:rd |= op_readdp(dp + 1) << 8; - regs.ya = op_$1(regs.ya, rd); -} - -cmpw_ya_dp(0x5a) { -1:dp = op_readpc(); -2:rd = op_readdp(dp); -3:rd |= op_readdp(dp + 1) << 8; - op_cmpw(regs.ya, rd); -} - -and1_bit(0x4a, !!), -and1_notbit(0x6a, !) { -1:dp = op_readpc(); -2:dp |= op_readpc() << 8; -3:bit = dp >> 13; - dp &= 0x1fff; - rd = op_readaddr(dp); - regs.p.c = regs.p.c & $1(rd & (1 << bit)); -} - -eor1_bit(0x8a) { -1:dp = op_readpc(); -2:dp |= op_readpc() << 8; -3:bit = dp >> 13; - dp &= 0x1fff; - rd = op_readaddr(dp); -4:op_io(); - regs.p.c = regs.p.c ^ !!(rd & (1 << bit)); -} - -not1_bit(0xea) { -1:dp = op_readpc(); -2:dp |= op_readpc() << 8; -3:bit = dp >> 13; - dp &= 0x1fff; - rd = op_readaddr(dp); - rd ^= (1 << bit); -4:op_writeaddr(dp, rd); -} - -or1_bit(0x0a, !!), -or1_notbit(0x2a, !) { -1:dp = op_readpc(); -2:dp |= op_readpc() << 8; -3:bit = dp >> 13; - dp &= 0x1fff; - rd = op_readaddr(dp); -4:op_io(); - regs.p.c = regs.p.c | $1(rd & (1 << bit)); -} +adc_a_const(0x88, adc, a), +and_a_const(0x28, and, a), +cmp_a_const(0x68, cmp, a), +cmp_x_const(0xc8, cmp, x), +cmp_y_const(0xad, cmp, y), +eor_a_const(0x48, eor, a), +or_a_const(0x08, or, a), +sbc_a_const(0xa8, sbc, a) { +1:rd = op_readpc(); + regs.$2 = op_$1(regs.$2, rd); +} + +adc_a_ix(0x86, adc), +and_a_ix(0x26, and), +cmp_a_ix(0x66, cmp), +eor_a_ix(0x46, eor), +or_a_ix(0x06, or), +sbc_a_ix(0xa6, sbc) { +1:op_io(); +2:rd = op_readdp(regs.x); + regs.a = op_$1(regs.a, rd); +} + +adc_a_dp(0x84, adc, a), +and_a_dp(0x24, and, a), +cmp_a_dp(0x64, cmp, a), +cmp_x_dp(0x3e, cmp, x), +cmp_y_dp(0x7e, cmp, y), +eor_a_dp(0x44, eor, a), +or_a_dp(0x04, or, a), +sbc_a_dp(0xa4, sbc, a) { +1:dp = op_readpc(); +2:rd = op_readdp(dp); + regs.$2 = op_$1(regs.$2, rd); +} + +adc_a_dpx(0x94, adc), +and_a_dpx(0x34, and), +cmp_a_dpx(0x74, cmp), +eor_a_dpx(0x54, eor), +or_a_dpx(0x14, or), +sbc_a_dpx(0xb4, sbc) { +1:dp = op_readpc(); +2:op_io(); +3:rd = op_readdp(dp + regs.x); + regs.a = op_$1(regs.a, rd); +} + +adc_a_addr(0x85, adc, a), +and_a_addr(0x25, and, a), +cmp_a_addr(0x65, cmp, a), +cmp_x_addr(0x1e, cmp, x), +cmp_y_addr(0x5e, cmp, y), +eor_a_addr(0x45, eor, a), +or_a_addr(0x05, or, a), +sbc_a_addr(0xa5, sbc, a) { +1:dp = op_readpc(); +2:dp |= op_readpc() << 8; +3:rd = op_readaddr(dp); + regs.$2 = op_$1(regs.$2, rd); +} + +adc_a_addrx(0x95, adc, x), +adc_a_addry(0x96, adc, y), +and_a_addrx(0x35, and, x), +and_a_addry(0x36, and, y), +cmp_a_addrx(0x75, cmp, x), +cmp_a_addry(0x76, cmp, y), +eor_a_addrx(0x55, eor, x), +eor_a_addry(0x56, eor, y), +or_a_addrx(0x15, or, x), +or_a_addry(0x16, or, y), +sbc_a_addrx(0xb5, sbc, x), +sbc_a_addry(0xb6, sbc, y) { +1:dp = op_readpc(); +2:dp |= op_readpc() << 8; +3:op_io(); +4:rd = op_readaddr(dp + regs.$2); + regs.a = op_$1(regs.a, rd); +} + +adc_a_idpx(0x87, adc), +and_a_idpx(0x27, and), +cmp_a_idpx(0x67, cmp), +eor_a_idpx(0x47, eor), +or_a_idpx(0x07, or), +sbc_a_idpx(0xa7, sbc) { +1:dp = op_readpc() + regs.x; +2:op_io(); +3:sp = op_readdp(dp); +4:sp |= op_readdp(dp + 1) << 8; +5:rd = op_readaddr(sp); + regs.a = op_$1(regs.a, rd); +} + +adc_a_idpy(0x97, adc), +and_a_idpy(0x37, and), +cmp_a_idpy(0x77, cmp), +eor_a_idpy(0x57, eor), +or_a_idpy(0x17, or), +sbc_a_idpy(0xb7, sbc) { +1:dp = op_readpc(); +2:op_io(); +3:sp = op_readdp(dp); +4:sp |= op_readdp(dp + 1) << 8; +5:rd = op_readaddr(sp + regs.y); + regs.a = op_$1(regs.a, rd); +} + +adc_ix_iy(0x99, adc, 1), +and_ix_iy(0x39, and, 1), +cmp_ix_iy(0x79, cmp, 0), +eor_ix_iy(0x59, eor, 1), +or_ix_iy(0x19, or, 1), +sbc_ix_iy(0xb9, sbc, 1) { +1:op_io(); +2:rd = op_readdp(regs.y); +3:wr = op_readdp(regs.x); + wr = op_$1(wr, rd); +4:($2) ? op_writedp(regs.x, wr) : op_io(); +} + +adc_dp_dp(0x89, adc, 1), +and_dp_dp(0x29, and, 1), +cmp_dp_dp(0x69, cmp, 0), +eor_dp_dp(0x49, eor, 1), +or_dp_dp(0x09, or, 1), +sbc_dp_dp(0xa9, sbc, 1) { +1:sp = op_readpc(); +2:rd = op_readdp(sp); +3:dp = op_readpc(); +4:wr = op_readdp(dp); +5:wr = op_$1(wr, rd); + ($2) ? op_writedp(dp, wr) : op_io(); +} + +adc_dp_const(0x98, adc, 1), +and_dp_const(0x38, and, 1), +cmp_dp_const(0x78, cmp, 0), +eor_dp_const(0x58, eor, 1), +or_dp_const(0x18, or, 1), +sbc_dp_const(0xb8, sbc, 1) { +1:rd = op_readpc(); +2:dp = op_readpc(); +3:wr = op_readdp(dp); +4:wr = op_$1(wr, rd); + ($2) ? op_writedp(dp, wr) : op_io(); +} + +addw_ya_dp(0x7a, addw), +subw_ya_dp(0x9a, subw) { +1:dp = op_readpc(); +2:rd = op_readdp(dp); +3:op_io(); +4:rd |= op_readdp(dp + 1) << 8; + regs.ya = op_$1(regs.ya, rd); +} + +cmpw_ya_dp(0x5a) { +1:dp = op_readpc(); +2:rd = op_readdp(dp); +3:rd |= op_readdp(dp + 1) << 8; + op_cmpw(regs.ya, rd); +} + +and1_bit(0x4a, !!), +and1_notbit(0x6a, !) { +1:dp = op_readpc(); +2:dp |= op_readpc() << 8; +3:bit = dp >> 13; + dp &= 0x1fff; + rd = op_readaddr(dp); + regs.p.c = regs.p.c & $1(rd & (1 << bit)); +} + +eor1_bit(0x8a) { +1:dp = op_readpc(); +2:dp |= op_readpc() << 8; +3:bit = dp >> 13; + dp &= 0x1fff; + rd = op_readaddr(dp); +4:op_io(); + regs.p.c = regs.p.c ^ !!(rd & (1 << bit)); +} + +not1_bit(0xea) { +1:dp = op_readpc(); +2:dp |= op_readpc() << 8; +3:bit = dp >> 13; + dp &= 0x1fff; + rd = op_readaddr(dp); + rd ^= (1 << bit); +4:op_writeaddr(dp, rd); +} + +or1_bit(0x0a, !!), +or1_notbit(0x2a, !) { +1:dp = op_readpc(); +2:dp |= op_readpc() << 8; +3:bit = dp >> 13; + dp &= 0x1fff; + rd = op_readaddr(dp); +4:op_io(); + regs.p.c = regs.p.c | $1(rd & (1 << bit)); +} diff --git a/libsnes/bsnes/snes/alt/smp/core/op_read.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/core/op_read.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/core/op_read.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/core/op_read.cpp diff --git a/libsnes/bsnes/snes/alt/smp/core/op_rmw.b b/waterbox/libsnes/bsnes/snes/alt/smp/core/op_rmw.b similarity index 94% rename from libsnes/bsnes/snes/alt/smp/core/op_rmw.b rename to waterbox/libsnes/bsnes/snes/alt/smp/core/op_rmw.b index 425574e8a7..327082a139 100644 --- a/libsnes/bsnes/snes/alt/smp/core/op_rmw.b +++ b/waterbox/libsnes/bsnes/snes/alt/smp/core/op_rmw.b @@ -1,74 +1,74 @@ -inc_a(0xbc, inc, a), -inc_x(0x3d, inc, x), -inc_y(0xfc, inc, y), -dec_a(0x9c, dec, a), -dec_x(0x1d, dec, x), -dec_y(0xdc, dec, y), -asl_a(0x1c, asl, a), -lsr_a(0x5c, lsr, a), -rol_a(0x3c, rol, a), -ror_a(0x7c, ror, a) { -1:op_io(); - regs.$2 = op_$1(regs.$2); -} - -inc_dp(0xab, inc), -dec_dp(0x8b, dec), -asl_dp(0x0b, asl), -lsr_dp(0x4b, lsr), -rol_dp(0x2b, rol), -ror_dp(0x6b, ror) { -1:dp = op_readpc(); -2:rd = op_readdp(dp); -3:rd = op_$1(rd); - op_writedp(dp, rd); -} - -inc_dpx(0xbb, inc), -dec_dpx(0x9b, dec), -asl_dpx(0x1b, asl), -lsr_dpx(0x5b, lsr), -rol_dpx(0x3b, rol), -ror_dpx(0x7b, ror) { -1:dp = op_readpc(); -2:op_io(); -3:rd = op_readdp(dp + regs.x); -4:rd = op_$1(rd); - op_writedp(dp + regs.x, rd); -} - -inc_addr(0xac, inc), -dec_addr(0x8c, dec), -asl_addr(0x0c, asl), -lsr_addr(0x4c, lsr), -rol_addr(0x2c, rol), -ror_addr(0x6c, ror) { -1:dp = op_readpc(); -2:dp |= op_readpc() << 8; -3:rd = op_readaddr(dp); -4:rd = op_$1(rd); - op_writeaddr(dp, rd); -} - -tset_addr_a(0x0e, |), -tclr_addr_a(0x4e, &~) { -1:dp = op_readpc(); -2:dp |= op_readpc() << 8; -3:rd = op_readaddr(dp); - regs.p.n = !!((regs.a - rd) & 0x80); - regs.p.z = ((regs.a - rd) == 0); -4:op_readaddr(dp); -5:op_writeaddr(dp, rd $1 regs.a); -} - -incw_dp(0x3a, ++), -decw_dp(0x1a, --) { -1:dp = op_readpc(); -2:rd = op_readdp(dp); - rd$1; -3:op_writedp(dp++, rd); -4:rd += op_readdp(dp) << 8; -5:op_writedp(dp, rd >> 8); - regs.p.n = !!(rd & 0x8000); - regs.p.z = (rd == 0); -} +inc_a(0xbc, inc, a), +inc_x(0x3d, inc, x), +inc_y(0xfc, inc, y), +dec_a(0x9c, dec, a), +dec_x(0x1d, dec, x), +dec_y(0xdc, dec, y), +asl_a(0x1c, asl, a), +lsr_a(0x5c, lsr, a), +rol_a(0x3c, rol, a), +ror_a(0x7c, ror, a) { +1:op_io(); + regs.$2 = op_$1(regs.$2); +} + +inc_dp(0xab, inc), +dec_dp(0x8b, dec), +asl_dp(0x0b, asl), +lsr_dp(0x4b, lsr), +rol_dp(0x2b, rol), +ror_dp(0x6b, ror) { +1:dp = op_readpc(); +2:rd = op_readdp(dp); +3:rd = op_$1(rd); + op_writedp(dp, rd); +} + +inc_dpx(0xbb, inc), +dec_dpx(0x9b, dec), +asl_dpx(0x1b, asl), +lsr_dpx(0x5b, lsr), +rol_dpx(0x3b, rol), +ror_dpx(0x7b, ror) { +1:dp = op_readpc(); +2:op_io(); +3:rd = op_readdp(dp + regs.x); +4:rd = op_$1(rd); + op_writedp(dp + regs.x, rd); +} + +inc_addr(0xac, inc), +dec_addr(0x8c, dec), +asl_addr(0x0c, asl), +lsr_addr(0x4c, lsr), +rol_addr(0x2c, rol), +ror_addr(0x6c, ror) { +1:dp = op_readpc(); +2:dp |= op_readpc() << 8; +3:rd = op_readaddr(dp); +4:rd = op_$1(rd); + op_writeaddr(dp, rd); +} + +tset_addr_a(0x0e, |), +tclr_addr_a(0x4e, &~) { +1:dp = op_readpc(); +2:dp |= op_readpc() << 8; +3:rd = op_readaddr(dp); + regs.p.n = !!((regs.a - rd) & 0x80); + regs.p.z = ((regs.a - rd) == 0); +4:op_readaddr(dp); +5:op_writeaddr(dp, rd $1 regs.a); +} + +incw_dp(0x3a, ++), +decw_dp(0x1a, --) { +1:dp = op_readpc(); +2:rd = op_readdp(dp); + rd$1; +3:op_writedp(dp++, rd); +4:rd += op_readdp(dp) << 8; +5:op_writedp(dp, rd >> 8); + regs.p.n = !!(rd & 0x8000); + regs.p.z = (rd == 0); +} diff --git a/libsnes/bsnes/snes/alt/smp/core/op_rmw.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/core/op_rmw.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/core/op_rmw.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/core/op_rmw.cpp diff --git a/libsnes/bsnes/snes/alt/smp/core/opcycle_misc.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/core/opcycle_misc.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/core/opcycle_misc.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/core/opcycle_misc.cpp diff --git a/libsnes/bsnes/snes/alt/smp/core/opcycle_mov.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/core/opcycle_mov.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/core/opcycle_mov.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/core/opcycle_mov.cpp diff --git a/libsnes/bsnes/snes/alt/smp/core/opcycle_pc.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/core/opcycle_pc.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/core/opcycle_pc.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/core/opcycle_pc.cpp diff --git a/libsnes/bsnes/snes/alt/smp/core/opcycle_read.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/core/opcycle_read.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/core/opcycle_read.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/core/opcycle_read.cpp diff --git a/libsnes/bsnes/snes/alt/smp/core/opcycle_rmw.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/core/opcycle_rmw.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/core/opcycle_rmw.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/core/opcycle_rmw.cpp diff --git a/libsnes/bsnes/snes/alt/smp/disassembler.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/disassembler.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/disassembler.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/disassembler.cpp diff --git a/libsnes/bsnes/snes/alt/smp/iplrom.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/iplrom.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/iplrom.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/iplrom.cpp diff --git a/libsnes/bsnes/snes/alt/smp/memory.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/memory.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/memory.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/memory.cpp diff --git a/libsnes/bsnes/snes/alt/smp/smp.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/smp.cpp similarity index 62% rename from libsnes/bsnes/snes/alt/smp/smp.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/smp.cpp index 94d2a59475..9002683342 100644 --- a/libsnes/bsnes/snes/alt/smp/smp.cpp +++ b/waterbox/libsnes/bsnes/snes/alt/smp/smp.cpp @@ -81,63 +81,6 @@ void SMP::reset() { timer0.stage3_ticks = timer1.stage3_ticks = timer2.stage3_ticks = 0; } -void SMP::serialize(serializer &s) { - Processor::serialize(s); - - s.array(apuram, 64 * 1024); - - s.integer(opcode_number); - s.integer(opcode_cycle); - - s.integer(regs.pc); - s.integer(regs.sp); - s.integer(regs.a); - s.integer(regs.x); - s.integer(regs.y); - - s.integer(regs.p.n); - s.integer(regs.p.v); - s.integer(regs.p.p); - s.integer(regs.p.b); - s.integer(regs.p.h); - s.integer(regs.p.i); - s.integer(regs.p.z); - s.integer(regs.p.c); - - s.integer(rd); - s.integer(wr); - s.integer(dp); - s.integer(sp); - s.integer(ya); - s.integer(bit); - - s.integer(status.iplrom_enable); - - s.integer(status.dsp_addr); - - s.integer(status.ram00f8); - s.integer(status.ram00f9); - - s.integer(timer0.enable); - s.integer(timer0.target); - s.integer(timer0.stage1_ticks); - s.integer(timer0.stage2_ticks); - s.integer(timer0.stage3_ticks); - - s.integer(timer1.enable); - s.integer(timer1.target); - s.integer(timer1.stage1_ticks); - s.integer(timer1.stage2_ticks); - s.integer(timer1.stage3_ticks); - - s.integer(timer2.enable); - s.integer(timer2.target); - - s.integer(timer2.stage1_ticks); - s.integer(timer2.stage2_ticks); - s.integer(timer2.stage3_ticks); -} - SMP::SMP() : apuram(nullptr) { diff --git a/libsnes/bsnes/snes/alt/smp/smp.hpp b/waterbox/libsnes/bsnes/snes/alt/smp/smp.hpp similarity index 98% rename from libsnes/bsnes/snes/alt/smp/smp.hpp rename to waterbox/libsnes/bsnes/snes/alt/smp/smp.hpp index f50184446c..77d8ca33b0 100644 --- a/libsnes/bsnes/snes/alt/smp/smp.hpp +++ b/waterbox/libsnes/bsnes/snes/alt/smp/smp.hpp @@ -17,7 +17,6 @@ public: void power(); void reset(); - void serialize(serializer&); SMP(); ~SMP(); void initialize(); diff --git a/libsnes/bsnes/snes/alt/smp/timing.cpp b/waterbox/libsnes/bsnes/snes/alt/smp/timing.cpp similarity index 100% rename from libsnes/bsnes/snes/alt/smp/timing.cpp rename to waterbox/libsnes/bsnes/snes/alt/smp/timing.cpp diff --git a/libsnes/bsnes/snes/cartridge/cartridge.cpp b/waterbox/libsnes/bsnes/snes/cartridge/cartridge.cpp similarity index 98% rename from libsnes/bsnes/snes/cartridge/cartridge.cpp rename to waterbox/libsnes/bsnes/snes/cartridge/cartridge.cpp index bfc33d7927..6827beae54 100644 --- a/libsnes/bsnes/snes/cartridge/cartridge.cpp +++ b/waterbox/libsnes/bsnes/snes/cartridge/cartridge.cpp @@ -7,7 +7,6 @@ namespace SNES { #include "markup.cpp" -#include "serialization.cpp" Cartridge cartridge; diff --git a/libsnes/bsnes/snes/cartridge/cartridge.hpp b/waterbox/libsnes/bsnes/snes/cartridge/cartridge.hpp similarity index 98% rename from libsnes/bsnes/snes/cartridge/cartridge.hpp rename to waterbox/libsnes/bsnes/snes/cartridge/cartridge.hpp index 958aabd2c1..d4099227d3 100644 --- a/libsnes/bsnes/snes/cartridge/cartridge.hpp +++ b/waterbox/libsnes/bsnes/snes/cartridge/cartridge.hpp @@ -85,7 +85,6 @@ struct Cartridge : property { void load(Mode, const char*); void unload(); - void serialize(serializer&); Cartridge(); ~Cartridge(); diff --git a/libsnes/bsnes/snes/cartridge/markup.cpp b/waterbox/libsnes/bsnes/snes/cartridge/markup.cpp similarity index 99% rename from libsnes/bsnes/snes/cartridge/markup.cpp rename to waterbox/libsnes/bsnes/snes/cartridge/markup.cpp index a4ac63bb8c..e4cde6a3fa 100644 --- a/libsnes/bsnes/snes/cartridge/markup.cpp +++ b/waterbox/libsnes/bsnes/snes/cartridge/markup.cpp @@ -259,11 +259,10 @@ void Cartridge::parse_markup_necdsp(XML::Node &root) { if(!sha256.empty()) { //XML file specified SHA256 sum for program. Verify file matches the hash. fp.seek(0); - //uint8_t data[filesize]; //test - uint8_t *data = (uint8_t*)alloca(filesize); - fp.read(data, filesize); + std::vector data(filesize); + fp.read(data.data(), filesize); - if(sha256 != nall::sha256(data, filesize)) { + if(sha256 != nall::sha256(data.data(), filesize)) { interface()->message({ "Warning: NEC DSP firmware ", firmware, " SHA256 sum is incorrect." }); } } diff --git a/libsnes/bsnes/snes/chip/armdsp/armdsp.cpp b/waterbox/libsnes/bsnes/snes/chip/armdsp/armdsp.cpp similarity index 98% rename from libsnes/bsnes/snes/chip/armdsp/armdsp.cpp rename to waterbox/libsnes/bsnes/snes/chip/armdsp/armdsp.cpp index 259ab6ad52..344829ca2f 100644 --- a/libsnes/bsnes/snes/chip/armdsp/armdsp.cpp +++ b/waterbox/libsnes/bsnes/snes/chip/armdsp/armdsp.cpp @@ -13,7 +13,6 @@ static bool trace = 0; #include "opcodes.cpp" #include "memory.cpp" #include "disassembler.cpp" -#include "serialization.cpp" ArmDSP armdsp; void ArmDSP::Enter() { armdsp.enter(); } @@ -156,7 +155,7 @@ void ArmDSP::reset() { } void ArmDSP::arm_reset() { - create(ArmDSP::Enter, 21477272); + create(ArmDSP::Enter, 21477272, 8192); bridge.ready = false; bridge.timer = 0; diff --git a/libsnes/bsnes/snes/chip/armdsp/armdsp.hpp b/waterbox/libsnes/bsnes/snes/chip/armdsp/armdsp.hpp similarity index 96% rename from libsnes/bsnes/snes/chip/armdsp/armdsp.hpp rename to waterbox/libsnes/bsnes/snes/chip/armdsp/armdsp.hpp index 50e84971cf..968fa139d8 100644 --- a/libsnes/bsnes/snes/chip/armdsp/armdsp.hpp +++ b/waterbox/libsnes/bsnes/snes/chip/armdsp/armdsp.hpp @@ -61,9 +61,6 @@ struct ArmDSP : public Coprocessor { //disassembler.cpp string disassemble_opcode(uint32 pc); string disassemble_registers(); - - //serialization.cpp - void serialize(serializer&); }; extern ArmDSP armdsp; diff --git a/libsnes/bsnes/snes/chip/armdsp/disassembler.cpp b/waterbox/libsnes/bsnes/snes/chip/armdsp/disassembler.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/armdsp/disassembler.cpp rename to waterbox/libsnes/bsnes/snes/chip/armdsp/disassembler.cpp diff --git a/libsnes/bsnes/snes/chip/armdsp/memory.cpp b/waterbox/libsnes/bsnes/snes/chip/armdsp/memory.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/armdsp/memory.cpp rename to waterbox/libsnes/bsnes/snes/chip/armdsp/memory.cpp diff --git a/libsnes/bsnes/snes/chip/armdsp/opcodes.cpp b/waterbox/libsnes/bsnes/snes/chip/armdsp/opcodes.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/armdsp/opcodes.cpp rename to waterbox/libsnes/bsnes/snes/chip/armdsp/opcodes.cpp diff --git a/libsnes/bsnes/snes/chip/armdsp/registers.hpp b/waterbox/libsnes/bsnes/snes/chip/armdsp/registers.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/armdsp/registers.hpp rename to waterbox/libsnes/bsnes/snes/chip/armdsp/registers.hpp diff --git a/libsnes/bsnes/snes/chip/bsx/bsx.cpp b/waterbox/libsnes/bsnes/snes/chip/bsx/bsx.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/bsx/bsx.cpp rename to waterbox/libsnes/bsnes/snes/chip/bsx/bsx.cpp diff --git a/libsnes/bsnes/snes/chip/bsx/bsx.hpp b/waterbox/libsnes/bsnes/snes/chip/bsx/bsx.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/bsx/bsx.hpp rename to waterbox/libsnes/bsnes/snes/chip/bsx/bsx.hpp diff --git a/libsnes/bsnes/snes/chip/bsx/cartridge/cartridge.cpp b/waterbox/libsnes/bsnes/snes/chip/bsx/cartridge/cartridge.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/bsx/cartridge/cartridge.cpp rename to waterbox/libsnes/bsnes/snes/chip/bsx/cartridge/cartridge.cpp diff --git a/libsnes/bsnes/snes/chip/bsx/cartridge/cartridge.hpp b/waterbox/libsnes/bsnes/snes/chip/bsx/cartridge/cartridge.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/bsx/cartridge/cartridge.hpp rename to waterbox/libsnes/bsnes/snes/chip/bsx/cartridge/cartridge.hpp diff --git a/libsnes/bsnes/snes/chip/bsx/flash/flash.cpp b/waterbox/libsnes/bsnes/snes/chip/bsx/flash/flash.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/bsx/flash/flash.cpp rename to waterbox/libsnes/bsnes/snes/chip/bsx/flash/flash.cpp diff --git a/libsnes/bsnes/snes/chip/bsx/flash/flash.hpp b/waterbox/libsnes/bsnes/snes/chip/bsx/flash/flash.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/bsx/flash/flash.hpp rename to waterbox/libsnes/bsnes/snes/chip/bsx/flash/flash.hpp diff --git a/libsnes/bsnes/snes/chip/bsx/satellaview/satellaview.cpp b/waterbox/libsnes/bsnes/snes/chip/bsx/satellaview/satellaview.cpp similarity index 99% rename from libsnes/bsnes/snes/chip/bsx/satellaview/satellaview.cpp rename to waterbox/libsnes/bsnes/snes/chip/bsx/satellaview/satellaview.cpp index dccfe1c9cf..c52c10aa17 100644 --- a/libsnes/bsnes/snes/chip/bsx/satellaview/satellaview.cpp +++ b/waterbox/libsnes/bsnes/snes/chip/bsx/satellaview/satellaview.cpp @@ -35,13 +35,13 @@ uint8 BSXSatellaview::mmio_read(unsigned addr) { case 0x2192: { unsigned counter = regs.r2192_counter++; if(regs.r2192_counter >= 18) regs.r2192_counter = 0; - - if(counter == 0) { - time_t rawtime; - rawtime = SNES::interface()->currentTime(); - tm *t = localtime(&rawtime); - - regs.r2192_hour = t->tm_hour; + + if(counter == 0) { + time_t rawtime; + rawtime = SNES::interface()->currentTime(); + tm *t = localtime(&rawtime); + + regs.r2192_hour = t->tm_hour; regs.r2192_minute = t->tm_min; regs.r2192_second = t->tm_sec; } diff --git a/libsnes/bsnes/snes/chip/bsx/satellaview/satellaview.hpp b/waterbox/libsnes/bsnes/snes/chip/bsx/satellaview/satellaview.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/bsx/satellaview/satellaview.hpp rename to waterbox/libsnes/bsnes/snes/chip/bsx/satellaview/satellaview.hpp diff --git a/libsnes/bsnes/snes/chip/chip.hpp b/waterbox/libsnes/bsnes/snes/chip/chip.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/chip.hpp rename to waterbox/libsnes/bsnes/snes/chip/chip.hpp diff --git a/libsnes/bsnes/snes/chip/hitachidsp/hitachidsp.cpp b/waterbox/libsnes/bsnes/snes/chip/hitachidsp/hitachidsp.cpp similarity index 82% rename from libsnes/bsnes/snes/chip/hitachidsp/hitachidsp.cpp rename to waterbox/libsnes/bsnes/snes/chip/hitachidsp/hitachidsp.cpp index 698f1e15e8..235d08f1a6 100644 --- a/libsnes/bsnes/snes/chip/hitachidsp/hitachidsp.cpp +++ b/waterbox/libsnes/bsnes/snes/chip/hitachidsp/hitachidsp.cpp @@ -6,7 +6,6 @@ namespace SNES { #include "memory.cpp" #include "opcodes.cpp" #include "registers.cpp" -#include "serialization.cpp" HitachiDSP hitachidsp; //zero 01-sep-2014 - dont clobber these when reconstructing! @@ -16,14 +15,10 @@ uint24 HitachiDSP::dataROM[1024]; void HitachiDSP::Enter() { hitachidsp.enter(); } void HitachiDSP::enter() { - while(true) { - // exit requested due to savestate + while(true) { if(scheduler.sync == Scheduler::SynchronizeMode::All) { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - // if we bail out due to savestating, the first thing we'll try afterwards is synchronize_cpu() again - synchronize_cpu(); + } switch(state) { case State::Idle: @@ -45,9 +40,8 @@ void HitachiDSP::enter() { step(1); break; } - - // this call is gone, but it's the first thing we try at the top of the loop AFTER we bail out - //synchronize_cpu(); + + synchronize_cpu(); } } @@ -64,7 +58,7 @@ void HitachiDSP::power() { } void HitachiDSP::reset() { - create(HitachiDSP::Enter, frequency); + create(HitachiDSP::Enter, frequency, 8192); state = State::Idle; regs.n = 0; diff --git a/libsnes/bsnes/snes/chip/hitachidsp/hitachidsp.hpp b/waterbox/libsnes/bsnes/snes/chip/hitachidsp/hitachidsp.hpp similarity index 96% rename from libsnes/bsnes/snes/chip/hitachidsp/hitachidsp.hpp rename to waterbox/libsnes/bsnes/snes/chip/hitachidsp/hitachidsp.hpp index 7efff3fc97..4aae361ad3 100644 --- a/libsnes/bsnes/snes/chip/hitachidsp/hitachidsp.hpp +++ b/waterbox/libsnes/bsnes/snes/chip/hitachidsp/hitachidsp.hpp @@ -43,8 +43,6 @@ public: //registers.cpp unsigned reg_read(unsigned n) const; void reg_write(unsigned n, unsigned data); - - void serialize(serializer&); }; extern HitachiDSP hitachidsp; diff --git a/libsnes/bsnes/snes/chip/hitachidsp/memory.cpp b/waterbox/libsnes/bsnes/snes/chip/hitachidsp/memory.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/hitachidsp/memory.cpp rename to waterbox/libsnes/bsnes/snes/chip/hitachidsp/memory.cpp diff --git a/libsnes/bsnes/snes/chip/hitachidsp/opcodes.cpp b/waterbox/libsnes/bsnes/snes/chip/hitachidsp/opcodes.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/hitachidsp/opcodes.cpp rename to waterbox/libsnes/bsnes/snes/chip/hitachidsp/opcodes.cpp diff --git a/libsnes/bsnes/snes/chip/hitachidsp/registers.cpp b/waterbox/libsnes/bsnes/snes/chip/hitachidsp/registers.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/hitachidsp/registers.cpp rename to waterbox/libsnes/bsnes/snes/chip/hitachidsp/registers.cpp diff --git a/libsnes/bsnes/snes/chip/hitachidsp/registers.hpp b/waterbox/libsnes/bsnes/snes/chip/hitachidsp/registers.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/hitachidsp/registers.hpp rename to waterbox/libsnes/bsnes/snes/chip/hitachidsp/registers.hpp diff --git a/libsnes/bsnes/snes/chip/icd2/icd2.cpp b/waterbox/libsnes/bsnes/snes/chip/icd2/icd2.cpp similarity index 95% rename from libsnes/bsnes/snes/chip/icd2/icd2.cpp rename to waterbox/libsnes/bsnes/snes/chip/icd2/icd2.cpp index 0b7a7dfdea..bd2828e5dd 100644 --- a/libsnes/bsnes/snes/chip/icd2/icd2.cpp +++ b/waterbox/libsnes/bsnes/snes/chip/icd2/icd2.cpp @@ -7,7 +7,6 @@ namespace SNES { #include "interface/interface.cpp" #include "mmio/mmio.cpp" -#include "serialization.cpp" ICD2 icd2; void ICD2::Enter() { icd2.enter(); } @@ -46,7 +45,7 @@ void ICD2::power() { } void ICD2::reset() { - create(ICD2::Enter, cpu.frequency / 5); + create(ICD2::Enter, cpu.frequency / 5, 16384); r6000_ly = 0x00; r6000_row = 0x00; diff --git a/libsnes/bsnes/snes/chip/icd2/icd2.hpp b/waterbox/libsnes/bsnes/snes/chip/icd2/icd2.hpp similarity index 92% rename from libsnes/bsnes/snes/chip/icd2/icd2.hpp rename to waterbox/libsnes/bsnes/snes/chip/icd2/icd2.hpp index 19480f840b..5c741a1e25 100644 --- a/libsnes/bsnes/snes/chip/icd2/icd2.hpp +++ b/waterbox/libsnes/bsnes/snes/chip/icd2/icd2.hpp @@ -14,8 +14,6 @@ public: uint8 read(unsigned addr); void write(unsigned addr, uint8 data); - void serialize(serializer&); - ICD2(); private: diff --git a/libsnes/bsnes/snes/chip/icd2/interface/interface.cpp b/waterbox/libsnes/bsnes/snes/chip/icd2/interface/interface.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/icd2/interface/interface.cpp rename to waterbox/libsnes/bsnes/snes/chip/icd2/interface/interface.cpp diff --git a/libsnes/bsnes/snes/chip/icd2/interface/interface.hpp b/waterbox/libsnes/bsnes/snes/chip/icd2/interface/interface.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/icd2/interface/interface.hpp rename to waterbox/libsnes/bsnes/snes/chip/icd2/interface/interface.hpp diff --git a/libsnes/bsnes/snes/chip/icd2/mmio/mmio.cpp b/waterbox/libsnes/bsnes/snes/chip/icd2/mmio/mmio.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/icd2/mmio/mmio.cpp rename to waterbox/libsnes/bsnes/snes/chip/icd2/mmio/mmio.cpp diff --git a/libsnes/bsnes/snes/chip/icd2/mmio/mmio.hpp b/waterbox/libsnes/bsnes/snes/chip/icd2/mmio/mmio.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/icd2/mmio/mmio.hpp rename to waterbox/libsnes/bsnes/snes/chip/icd2/mmio/mmio.hpp diff --git a/libsnes/bsnes/snes/chip/link/link.cpp b/waterbox/libsnes/bsnes/snes/chip/link/link.cpp similarity index 96% rename from libsnes/bsnes/snes/chip/link/link.cpp rename to waterbox/libsnes/bsnes/snes/chip/link/link.cpp index 0df610d995..da50e519c1 100644 --- a/libsnes/bsnes/snes/chip/link/link.cpp +++ b/waterbox/libsnes/bsnes/snes/chip/link/link.cpp @@ -44,7 +44,7 @@ void Link::power() { void Link::reset() { if(link_reset) link_reset(); - create(Link::Enter, frequency); + create(Link::Enter, frequency, 8192); } uint8 Link::read(unsigned addr) { diff --git a/libsnes/bsnes/snes/chip/link/link.hpp b/waterbox/libsnes/bsnes/snes/chip/link/link.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/link/link.hpp rename to waterbox/libsnes/bsnes/snes/chip/link/link.hpp diff --git a/libsnes/bsnes/snes/chip/msu1/msu1.cpp b/waterbox/libsnes/bsnes/snes/chip/msu1/msu1.cpp similarity index 98% rename from libsnes/bsnes/snes/chip/msu1/msu1.cpp rename to waterbox/libsnes/bsnes/snes/chip/msu1/msu1.cpp index c4644bc8f5..bf44fddb12 100644 --- a/libsnes/bsnes/snes/chip/msu1/msu1.cpp +++ b/waterbox/libsnes/bsnes/snes/chip/msu1/msu1.cpp @@ -5,8 +5,6 @@ namespace SNES { MSU1 msu1; -#include "serialization.cpp" - void MSU1::Enter() { msu1.enter(); } void MSU1::enter() { @@ -65,7 +63,7 @@ void MSU1::power() { } void MSU1::reset() { - create(MSU1::Enter, 44100); + create(MSU1::Enter, 44100, 16384); mmio.data_offset = 0; mmio.audio_offset = 0; diff --git a/libsnes/bsnes/snes/chip/msu1/msu1.hpp b/waterbox/libsnes/bsnes/snes/chip/msu1/msu1.hpp similarity index 95% rename from libsnes/bsnes/snes/chip/msu1/msu1.hpp rename to waterbox/libsnes/bsnes/snes/chip/msu1/msu1.hpp index 25572eaffc..a109c339af 100644 --- a/libsnes/bsnes/snes/chip/msu1/msu1.hpp +++ b/waterbox/libsnes/bsnes/snes/chip/msu1/msu1.hpp @@ -11,8 +11,6 @@ public: uint8 mmio_read(unsigned addr); void mmio_write(unsigned addr, uint8 data); - void serialize(serializer&); - private: file datafile; file audiofile; diff --git a/libsnes/bsnes/snes/chip/necdsp/disassembler.cpp b/waterbox/libsnes/bsnes/snes/chip/necdsp/disassembler.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/necdsp/disassembler.cpp rename to waterbox/libsnes/bsnes/snes/chip/necdsp/disassembler.cpp diff --git a/libsnes/bsnes/snes/chip/necdsp/memory.cpp b/waterbox/libsnes/bsnes/snes/chip/necdsp/memory.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/necdsp/memory.cpp rename to waterbox/libsnes/bsnes/snes/chip/necdsp/memory.cpp diff --git a/libsnes/bsnes/snes/chip/necdsp/necdsp.cpp b/waterbox/libsnes/bsnes/snes/chip/necdsp/necdsp.cpp similarity index 99% rename from libsnes/bsnes/snes/chip/necdsp/necdsp.cpp rename to waterbox/libsnes/bsnes/snes/chip/necdsp/necdsp.cpp index 188440eb32..37b49e4106 100644 --- a/libsnes/bsnes/snes/chip/necdsp/necdsp.cpp +++ b/waterbox/libsnes/bsnes/snes/chip/necdsp/necdsp.cpp @@ -5,7 +5,6 @@ namespace SNES { #include "memory.cpp" #include "disassembler.cpp" -#include "serialization.cpp" NECDSP necdsp; //zero 01-sep-2014 - dont clobber these when reconstructing! @@ -276,7 +275,7 @@ void NECDSP::power() { } void NECDSP::reset() { - create(NECDSP::Enter, frequency); + create(NECDSP::Enter, frequency, 8192); for(unsigned n = 0; n < 16; n++) regs.stack[n] = 0x0000; regs.pc = 0x0000; diff --git a/libsnes/bsnes/snes/chip/necdsp/necdsp.hpp b/waterbox/libsnes/bsnes/snes/chip/necdsp/necdsp.hpp similarity index 96% rename from libsnes/bsnes/snes/chip/necdsp/necdsp.hpp rename to waterbox/libsnes/bsnes/snes/chip/necdsp/necdsp.hpp index b02ab3567f..318734f987 100644 --- a/libsnes/bsnes/snes/chip/necdsp/necdsp.hpp +++ b/waterbox/libsnes/bsnes/snes/chip/necdsp/necdsp.hpp @@ -42,7 +42,6 @@ public: void power(); void reset(); - void serialize(serializer&); NECDSP(); ~NECDSP(); }; diff --git a/libsnes/bsnes/snes/chip/necdsp/registers.hpp b/waterbox/libsnes/bsnes/snes/chip/necdsp/registers.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/necdsp/registers.hpp rename to waterbox/libsnes/bsnes/snes/chip/necdsp/registers.hpp diff --git a/libsnes/bsnes/snes/chip/nss/nss.cpp b/waterbox/libsnes/bsnes/snes/chip/nss/nss.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/nss/nss.cpp rename to waterbox/libsnes/bsnes/snes/chip/nss/nss.cpp diff --git a/libsnes/bsnes/snes/chip/nss/nss.hpp b/waterbox/libsnes/bsnes/snes/chip/nss/nss.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/nss/nss.hpp rename to waterbox/libsnes/bsnes/snes/chip/nss/nss.hpp diff --git a/libsnes/bsnes/snes/chip/obc1/obc1.cpp b/waterbox/libsnes/bsnes/snes/chip/obc1/obc1.cpp similarity index 98% rename from libsnes/bsnes/snes/chip/obc1/obc1.cpp rename to waterbox/libsnes/bsnes/snes/chip/obc1/obc1.cpp index 8d7d337607..0d25410fac 100644 --- a/libsnes/bsnes/snes/chip/obc1/obc1.cpp +++ b/waterbox/libsnes/bsnes/snes/chip/obc1/obc1.cpp @@ -3,7 +3,6 @@ #define OBC1_CPP namespace SNES { -#include "serialization.cpp" OBC1 obc1; void OBC1::init() { diff --git a/libsnes/bsnes/snes/chip/obc1/obc1.hpp b/waterbox/libsnes/bsnes/snes/chip/obc1/obc1.hpp similarity index 91% rename from libsnes/bsnes/snes/chip/obc1/obc1.hpp rename to waterbox/libsnes/bsnes/snes/chip/obc1/obc1.hpp index 686adbc987..2209b2a64d 100644 --- a/libsnes/bsnes/snes/chip/obc1/obc1.hpp +++ b/waterbox/libsnes/bsnes/snes/chip/obc1/obc1.hpp @@ -9,8 +9,6 @@ public: uint8 read(unsigned addr); void write(unsigned addr, uint8 data); - void serialize(serializer&); - private: uint8 ram_read(unsigned addr); void ram_write(unsigned addr, uint8 data); diff --git a/libsnes/bsnes/snes/chip/sa1/bus/bus.cpp b/waterbox/libsnes/bsnes/snes/chip/sa1/bus/bus.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/sa1/bus/bus.cpp rename to waterbox/libsnes/bsnes/snes/chip/sa1/bus/bus.cpp diff --git a/libsnes/bsnes/snes/chip/sa1/bus/bus.hpp b/waterbox/libsnes/bsnes/snes/chip/sa1/bus/bus.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/sa1/bus/bus.hpp rename to waterbox/libsnes/bsnes/snes/chip/sa1/bus/bus.hpp diff --git a/libsnes/bsnes/snes/chip/sa1/dma/dma.cpp b/waterbox/libsnes/bsnes/snes/chip/sa1/dma/dma.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/sa1/dma/dma.cpp rename to waterbox/libsnes/bsnes/snes/chip/sa1/dma/dma.cpp diff --git a/libsnes/bsnes/snes/chip/sa1/dma/dma.hpp b/waterbox/libsnes/bsnes/snes/chip/sa1/dma/dma.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/sa1/dma/dma.hpp rename to waterbox/libsnes/bsnes/snes/chip/sa1/dma/dma.hpp diff --git a/libsnes/bsnes/snes/chip/sa1/memory/memory.cpp b/waterbox/libsnes/bsnes/snes/chip/sa1/memory/memory.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/sa1/memory/memory.cpp rename to waterbox/libsnes/bsnes/snes/chip/sa1/memory/memory.cpp diff --git a/libsnes/bsnes/snes/chip/sa1/memory/memory.hpp b/waterbox/libsnes/bsnes/snes/chip/sa1/memory/memory.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/sa1/memory/memory.hpp rename to waterbox/libsnes/bsnes/snes/chip/sa1/memory/memory.hpp diff --git a/libsnes/bsnes/snes/chip/sa1/mmio/mmio.cpp b/waterbox/libsnes/bsnes/snes/chip/sa1/mmio/mmio.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/sa1/mmio/mmio.cpp rename to waterbox/libsnes/bsnes/snes/chip/sa1/mmio/mmio.cpp diff --git a/libsnes/bsnes/snes/chip/sa1/mmio/mmio.hpp b/waterbox/libsnes/bsnes/snes/chip/sa1/mmio/mmio.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/sa1/mmio/mmio.hpp rename to waterbox/libsnes/bsnes/snes/chip/sa1/mmio/mmio.hpp diff --git a/libsnes/bsnes/snes/chip/sa1/sa1.cpp b/waterbox/libsnes/bsnes/snes/chip/sa1/sa1.cpp similarity index 92% rename from libsnes/bsnes/snes/chip/sa1/sa1.cpp rename to waterbox/libsnes/bsnes/snes/chip/sa1/sa1.cpp index a8edc92c0e..0f086e49f0 100644 --- a/libsnes/bsnes/snes/chip/sa1/sa1.cpp +++ b/waterbox/libsnes/bsnes/snes/chip/sa1/sa1.cpp @@ -5,7 +5,6 @@ namespace SNES { SA1 sa1; -#include "serialization.cpp" #include "bus/bus.cpp" #include "dma/dma.cpp" #include "memory/memory.cpp" @@ -19,25 +18,20 @@ void SA1::enter() { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); } - if (regs.hang == HangType::Wait) this->op_wai(); - else if (regs.hang == HangType::Stop) this->op_stp(); - else - { - if(mmio.sa1_rdyb || mmio.sa1_resb) { - //SA-1 co-processor is asleep - tick(); - synchronize_cpu(); - continue; - } + if(mmio.sa1_rdyb || mmio.sa1_resb) { + //SA-1 co-processor is asleep + tick(); + synchronize_cpu(); + continue; + } - if(status.interrupt_pending) { - status.interrupt_pending = false; - op_irq(); - continue; - } + if(status.interrupt_pending) { + status.interrupt_pending = false; + op_irq(); + continue; + } - (this->*opcode_table[op_readpc()])(); - } + (this->*opcode_table[op_readpc()])(); } } @@ -136,7 +130,7 @@ void SA1::power() { } void SA1::reset() { - create(SA1::Enter, system.cpu_frequency()); + create(SA1::Enter, system.cpu_frequency(), 8192); cpubwram.dma = false; for(unsigned addr = 0; addr < iram.size(); addr++) { diff --git a/libsnes/bsnes/snes/chip/sa1/sa1.hpp b/waterbox/libsnes/bsnes/snes/chip/sa1/sa1.hpp similarity index 95% rename from libsnes/bsnes/snes/chip/sa1/sa1.hpp rename to waterbox/libsnes/bsnes/snes/chip/sa1/sa1.hpp index 732b2a851e..1f559a97ee 100644 --- a/libsnes/bsnes/snes/chip/sa1/sa1.hpp +++ b/waterbox/libsnes/bsnes/snes/chip/sa1/sa1.hpp @@ -30,7 +30,6 @@ public: void power(); void reset(); - void serialize(serializer&); SA1(); }; diff --git a/libsnes/bsnes/snes/chip/sdd1/decomp.cpp b/waterbox/libsnes/bsnes/snes/chip/sdd1/decomp.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/sdd1/decomp.cpp rename to waterbox/libsnes/bsnes/snes/chip/sdd1/decomp.cpp diff --git a/libsnes/bsnes/snes/chip/sdd1/decomp.hpp b/waterbox/libsnes/bsnes/snes/chip/sdd1/decomp.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/sdd1/decomp.hpp rename to waterbox/libsnes/bsnes/snes/chip/sdd1/decomp.hpp diff --git a/libsnes/bsnes/snes/chip/sdd1/sdd1.cpp b/waterbox/libsnes/bsnes/snes/chip/sdd1/sdd1.cpp similarity index 99% rename from libsnes/bsnes/snes/chip/sdd1/sdd1.cpp rename to waterbox/libsnes/bsnes/snes/chip/sdd1/sdd1.cpp index c9b8b1c40a..f3f197daa0 100644 --- a/libsnes/bsnes/snes/chip/sdd1/sdd1.cpp +++ b/waterbox/libsnes/bsnes/snes/chip/sdd1/sdd1.cpp @@ -6,7 +6,6 @@ namespace SNES { SDD1 sdd1; #include "decomp.cpp" -#include "serialization.cpp" void SDD1::init() { } diff --git a/libsnes/bsnes/snes/chip/sdd1/sdd1.hpp b/waterbox/libsnes/bsnes/snes/chip/sdd1/sdd1.hpp similarity index 95% rename from libsnes/bsnes/snes/chip/sdd1/sdd1.hpp rename to waterbox/libsnes/bsnes/snes/chip/sdd1/sdd1.hpp index b0af2ac429..1a0fc335a0 100644 --- a/libsnes/bsnes/snes/chip/sdd1/sdd1.hpp +++ b/waterbox/libsnes/bsnes/snes/chip/sdd1/sdd1.hpp @@ -13,7 +13,6 @@ public: uint8 mcu_read(unsigned addr); void mcu_write(unsigned addr, uint8 data); - void serialize(serializer&); SDD1(); ~SDD1(); diff --git a/libsnes/bsnes/snes/chip/spc7110/decomp.cpp b/waterbox/libsnes/bsnes/snes/chip/spc7110/decomp.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/spc7110/decomp.cpp rename to waterbox/libsnes/bsnes/snes/chip/spc7110/decomp.cpp diff --git a/libsnes/bsnes/snes/chip/spc7110/decomp.hpp b/waterbox/libsnes/bsnes/snes/chip/spc7110/decomp.hpp similarity index 96% rename from libsnes/bsnes/snes/chip/spc7110/decomp.hpp rename to waterbox/libsnes/bsnes/snes/chip/spc7110/decomp.hpp index c11c6ad478..41b2924b10 100644 --- a/libsnes/bsnes/snes/chip/spc7110/decomp.hpp +++ b/waterbox/libsnes/bsnes/snes/chip/spc7110/decomp.hpp @@ -4,7 +4,6 @@ public: void init(unsigned mode, unsigned offset, unsigned index); void reset(); - void serialize(serializer&); Decomp(); ~Decomp(); diff --git a/libsnes/bsnes/snes/chip/spc7110/spc7110.cpp b/waterbox/libsnes/bsnes/snes/chip/spc7110/spc7110.cpp similarity index 99% rename from libsnes/bsnes/snes/chip/spc7110/spc7110.cpp rename to waterbox/libsnes/bsnes/snes/chip/spc7110/spc7110.cpp index 5a97ec7594..37e45f80b2 100644 --- a/libsnes/bsnes/snes/chip/spc7110/spc7110.cpp +++ b/waterbox/libsnes/bsnes/snes/chip/spc7110/spc7110.cpp @@ -5,7 +5,6 @@ namespace SNES { SPC7110 spc7110; -#include "serialization.cpp" #include "decomp.cpp" const unsigned SPC7110::months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; @@ -98,13 +97,13 @@ unsigned SPC7110::data_adjust() { return r4814 + (r4815 << 8); } unsigned SPC7110::data_increment() { return r4816 + (r4817 << 8); } void SPC7110::set_data_pointer(unsigned addr) { r4811 = addr; r4812 = addr >> 8; r4813 = addr >> 16; } void SPC7110::set_data_adjust(unsigned addr) { r4814 = addr; r4815 = addr >> 8; } - -void SPC7110::update_time(int offset) { - time_t rtc_time = (rtc[16] << 0) | (rtc[17] << 8) | (rtc[18] << 16) | (rtc[19] << 24); - time_t current_time = SNES::interface()->currentTime() - offset; - - //sizeof(time_t) is platform-dependent; though rtc[] needs to be platform-agnostic. - //yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by + +void SPC7110::update_time(int offset) { + time_t rtc_time = (rtc[16] << 0) | (rtc[17] << 8) | (rtc[18] << 16) | (rtc[19] << 24); + time_t current_time = SNES::interface()->currentTime() - offset; + + //sizeof(time_t) is platform-dependent; though rtc[] needs to be platform-agnostic. + //yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by //accounting for overflow at the cost of 1-bit precision (to catch underflow). this will allow //rtc[] timestamp to remain valid for up to ~34 years from the last update, even if //time_t overflows. calculation should be valid regardless of number representation, time_t size, diff --git a/libsnes/bsnes/snes/chip/spc7110/spc7110.hpp b/waterbox/libsnes/bsnes/snes/chip/spc7110/spc7110.hpp similarity index 99% rename from libsnes/bsnes/snes/chip/spc7110/spc7110.hpp rename to waterbox/libsnes/bsnes/snes/chip/spc7110/spc7110.hpp index 5610bebfe8..acf6743fd0 100644 --- a/libsnes/bsnes/snes/chip/spc7110/spc7110.hpp +++ b/waterbox/libsnes/bsnes/snes/chip/spc7110/spc7110.hpp @@ -39,7 +39,6 @@ public: void decomp_init(); uint8 decomp_read(); - void serialize(serializer&); SPC7110(); ~SPC7110(); void initialize(); diff --git a/libsnes/bsnes/snes/chip/srtc/srtc.cpp b/waterbox/libsnes/bsnes/snes/chip/srtc/srtc.cpp similarity index 99% rename from libsnes/bsnes/snes/chip/srtc/srtc.cpp rename to waterbox/libsnes/bsnes/snes/chip/srtc/srtc.cpp index 947b02abfe..606eb7502e 100644 --- a/libsnes/bsnes/snes/chip/srtc/srtc.cpp +++ b/waterbox/libsnes/bsnes/snes/chip/srtc/srtc.cpp @@ -5,8 +5,6 @@ namespace SNES { SRTC srtc; -#include "serialization.cpp" - const unsigned SRTC::months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; SRTC::SRTC() @@ -43,13 +41,13 @@ void SRTC::reset() { rtc_index = -1; update_time(); } - -void SRTC::update_time() { - time_t rtc_time = (rtc[16] << 0) | (rtc[17] << 8) | (rtc[18] << 16) | (rtc[19] << 24); - time_t current_time = SNES::interface()->currentTime(); - - //sizeof(time_t) is platform-dependent; though rtc[] needs to be platform-agnostic. - //yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by + +void SRTC::update_time() { + time_t rtc_time = (rtc[16] << 0) | (rtc[17] << 8) | (rtc[18] << 16) | (rtc[19] << 24); + time_t current_time = SNES::interface()->currentTime(); + + //sizeof(time_t) is platform-dependent; though rtc[] needs to be platform-agnostic. + //yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by //accounting for overflow at the cost of 1-bit precision (to catch underflow). this will allow //rtc[] timestamp to remain valid for up to ~34 years from the last update, even if //time_t overflows. calculation should be valid regardless of number representation, time_t size, diff --git a/libsnes/bsnes/snes/chip/srtc/srtc.hpp b/waterbox/libsnes/bsnes/snes/chip/srtc/srtc.hpp similarity index 94% rename from libsnes/bsnes/snes/chip/srtc/srtc.hpp rename to waterbox/libsnes/bsnes/snes/chip/srtc/srtc.hpp index 2bbc7d65ba..c6ce9bbe0c 100644 --- a/libsnes/bsnes/snes/chip/srtc/srtc.hpp +++ b/waterbox/libsnes/bsnes/snes/chip/srtc/srtc.hpp @@ -11,7 +11,6 @@ public: uint8 read(unsigned addr); void write(unsigned addr, uint8 data); - void serialize(serializer&); void initialize(); SRTC(); ~SRTC(); diff --git a/libsnes/bsnes/snes/chip/sufamiturbo/sufamiturbo.cpp b/waterbox/libsnes/bsnes/snes/chip/sufamiturbo/sufamiturbo.cpp similarity index 96% rename from libsnes/bsnes/snes/chip/sufamiturbo/sufamiturbo.cpp rename to waterbox/libsnes/bsnes/snes/chip/sufamiturbo/sufamiturbo.cpp index 52bca64403..15bbeaa636 100644 --- a/libsnes/bsnes/snes/chip/sufamiturbo/sufamiturbo.cpp +++ b/waterbox/libsnes/bsnes/snes/chip/sufamiturbo/sufamiturbo.cpp @@ -3,7 +3,6 @@ #define SUFAMITURBO_CPP namespace SNES { -#include "serialization.cpp" SufamiTurbo sufamiturbo; SufamiTurbo::SufamiTurbo() diff --git a/libsnes/bsnes/snes/chip/sufamiturbo/sufamiturbo.hpp b/waterbox/libsnes/bsnes/snes/chip/sufamiturbo/sufamiturbo.hpp similarity index 85% rename from libsnes/bsnes/snes/chip/sufamiturbo/sufamiturbo.hpp rename to waterbox/libsnes/bsnes/snes/chip/sufamiturbo/sufamiturbo.hpp index 9234254c6c..a2e6a4b5c2 100644 --- a/libsnes/bsnes/snes/chip/sufamiturbo/sufamiturbo.hpp +++ b/waterbox/libsnes/bsnes/snes/chip/sufamiturbo/sufamiturbo.hpp @@ -7,7 +7,6 @@ public: void load(); void unload(); - void serialize(serializer&); SufamiTurbo(); }; diff --git a/libsnes/bsnes/snes/chip/superfx/bus/bus.cpp b/waterbox/libsnes/bsnes/snes/chip/superfx/bus/bus.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/superfx/bus/bus.cpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/bus/bus.cpp diff --git a/libsnes/bsnes/snes/chip/superfx/bus/bus.hpp b/waterbox/libsnes/bsnes/snes/chip/superfx/bus/bus.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/superfx/bus/bus.hpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/bus/bus.hpp diff --git a/libsnes/bsnes/snes/chip/superfx/core/core.cpp b/waterbox/libsnes/bsnes/snes/chip/superfx/core/core.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/superfx/core/core.cpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/core/core.cpp diff --git a/libsnes/bsnes/snes/chip/superfx/core/core.hpp b/waterbox/libsnes/bsnes/snes/chip/superfx/core/core.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/superfx/core/core.hpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/core/core.hpp diff --git a/libsnes/bsnes/snes/chip/superfx/core/opcode_table.cpp b/waterbox/libsnes/bsnes/snes/chip/superfx/core/opcode_table.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/superfx/core/opcode_table.cpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/core/opcode_table.cpp diff --git a/libsnes/bsnes/snes/chip/superfx/core/opcodes.cpp b/waterbox/libsnes/bsnes/snes/chip/superfx/core/opcodes.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/superfx/core/opcodes.cpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/core/opcodes.cpp diff --git a/libsnes/bsnes/snes/chip/superfx/core/registers.hpp b/waterbox/libsnes/bsnes/snes/chip/superfx/core/registers.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/superfx/core/registers.hpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/core/registers.hpp diff --git a/libsnes/bsnes/snes/chip/superfx/disasm/disasm.cpp b/waterbox/libsnes/bsnes/snes/chip/superfx/disasm/disasm.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/superfx/disasm/disasm.cpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/disasm/disasm.cpp diff --git a/libsnes/bsnes/snes/chip/superfx/disasm/disasm.hpp b/waterbox/libsnes/bsnes/snes/chip/superfx/disasm/disasm.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/superfx/disasm/disasm.hpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/disasm/disasm.hpp diff --git a/libsnes/bsnes/snes/chip/superfx/memory/memory.cpp b/waterbox/libsnes/bsnes/snes/chip/superfx/memory/memory.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/superfx/memory/memory.cpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/memory/memory.cpp diff --git a/libsnes/bsnes/snes/chip/superfx/memory/memory.hpp b/waterbox/libsnes/bsnes/snes/chip/superfx/memory/memory.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/superfx/memory/memory.hpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/memory/memory.hpp diff --git a/libsnes/bsnes/snes/chip/superfx/mmio/mmio.cpp b/waterbox/libsnes/bsnes/snes/chip/superfx/mmio/mmio.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/superfx/mmio/mmio.cpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/mmio/mmio.cpp diff --git a/libsnes/bsnes/snes/chip/superfx/mmio/mmio.hpp b/waterbox/libsnes/bsnes/snes/chip/superfx/mmio/mmio.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/superfx/mmio/mmio.hpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/mmio/mmio.hpp diff --git a/libsnes/bsnes/snes/chip/superfx/superfx.cpp b/waterbox/libsnes/bsnes/snes/chip/superfx/superfx.cpp similarity index 95% rename from libsnes/bsnes/snes/chip/superfx/superfx.cpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/superfx.cpp index 52060fa23b..d12736d693 100644 --- a/libsnes/bsnes/snes/chip/superfx/superfx.cpp +++ b/waterbox/libsnes/bsnes/snes/chip/superfx/superfx.cpp @@ -3,7 +3,6 @@ #define SUPERFX_CPP namespace SNES { -#include "serialization.cpp" #include "bus/bus.cpp" #include "core/core.cpp" #include "memory/memory.cpp" @@ -54,7 +53,7 @@ void SuperFX::power() { } void SuperFX::reset() { - create(SuperFX::Enter, system.cpu_frequency()); + create(SuperFX::Enter, system.cpu_frequency(), 16384); instruction_counter = 0; for(unsigned n = 0; n < 16; n++) regs.r[n] = 0x0000; diff --git a/libsnes/bsnes/snes/chip/superfx/superfx.hpp b/waterbox/libsnes/bsnes/snes/chip/superfx/superfx.hpp similarity index 93% rename from libsnes/bsnes/snes/chip/superfx/superfx.hpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/superfx.hpp index cf28952b43..48483ca759 100644 --- a/libsnes/bsnes/snes/chip/superfx/superfx.hpp +++ b/waterbox/libsnes/bsnes/snes/chip/superfx/superfx.hpp @@ -14,7 +14,6 @@ public: void unload(); void power(); void reset(); - void serialize(serializer&); private: unsigned clockmode; diff --git a/libsnes/bsnes/snes/chip/superfx/timing/timing.cpp b/waterbox/libsnes/bsnes/snes/chip/superfx/timing/timing.cpp similarity index 100% rename from libsnes/bsnes/snes/chip/superfx/timing/timing.cpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/timing/timing.cpp diff --git a/libsnes/bsnes/snes/chip/superfx/timing/timing.hpp b/waterbox/libsnes/bsnes/snes/chip/superfx/timing/timing.hpp similarity index 100% rename from libsnes/bsnes/snes/chip/superfx/timing/timing.hpp rename to waterbox/libsnes/bsnes/snes/chip/superfx/timing/timing.hpp diff --git a/libsnes/bsnes/snes/config/config.cpp b/waterbox/libsnes/bsnes/snes/config/config.cpp similarity index 100% rename from libsnes/bsnes/snes/config/config.cpp rename to waterbox/libsnes/bsnes/snes/config/config.cpp diff --git a/libsnes/bsnes/snes/config/config.hpp b/waterbox/libsnes/bsnes/snes/config/config.hpp similarity index 100% rename from libsnes/bsnes/snes/config/config.hpp rename to waterbox/libsnes/bsnes/snes/config/config.hpp diff --git a/libsnes/bsnes/snes/controller/controller.cpp b/waterbox/libsnes/bsnes/snes/controller/controller.cpp similarity index 83% rename from libsnes/bsnes/snes/controller/controller.cpp rename to waterbox/libsnes/bsnes/snes/controller/controller.cpp index 4b3fb800ff..8e3791f79f 100644 --- a/libsnes/bsnes/snes/controller/controller.cpp +++ b/waterbox/libsnes/bsnes/snes/controller/controller.cpp @@ -43,19 +43,12 @@ void Controller::iobit(bool data) { switch(port) { case Controller::Port1: bus.write(0x4201, (cpu.pio() & ~0x40) | (data << 6)); break; case Controller::Port2: bus.write(0x4201, (cpu.pio() & ~0x80) | (data << 7)); break; - } -} - -void Controller::serialize(serializer& s) { - Processor::serialize(s); - //Save a zero block. - unsigned char blockzeroes[SaveSize] = {0}; - s.array(blockzeroes, SaveSize); -} - -Controller::Controller(bool port) : port(port) { - if(!thread) create(Controller::Enter, 1); -} - - -} + } +} + +Controller::Controller(bool port) : port(port) { + if(!thread) create(Controller::Enter, 1, 4096); +} + + +} diff --git a/libsnes/bsnes/snes/controller/controller.hpp b/waterbox/libsnes/bsnes/snes/controller/controller.hpp similarity index 95% rename from libsnes/bsnes/snes/controller/controller.hpp rename to waterbox/libsnes/bsnes/snes/controller/controller.hpp index 9ab4651693..94ab2ce7cd 100644 --- a/libsnes/bsnes/snes/controller/controller.hpp +++ b/waterbox/libsnes/bsnes/snes/controller/controller.hpp @@ -10,20 +10,19 @@ // 5: data2 $4016.d1 read $4017.d1 read // 6: iobit $4201.d6 write; $4213.d6 read $4201.d7 write; $4213.d7 read // 7: gnd - -struct Controller : Processor { - enum : bool { Port1 = 0, Port2 = 1 }; - enum { SaveSize = 16 }; - const bool port; - - static void Enter(); - virtual void enter(); - void step(unsigned clocks); - void synchronize_cpu(); - virtual void serialize(serializer& s); - - bool iobit(); - void iobit(bool data); + +struct Controller : Processor { + enum : bool { Port1 = 0, Port2 = 1 }; + enum { SaveSize = 16 }; + const bool port; + + static void Enter(); + virtual void enter(); + void step(unsigned clocks); + void synchronize_cpu(); + + bool iobit(); + void iobit(bool data); virtual uint2 data() { return 0; } virtual void latch(bool data) {} Controller(bool port); diff --git a/libsnes/bsnes/snes/controller/gamepad/gamepad.cpp b/waterbox/libsnes/bsnes/snes/controller/gamepad/gamepad.cpp similarity index 53% rename from libsnes/bsnes/snes/controller/gamepad/gamepad.cpp rename to waterbox/libsnes/bsnes/snes/controller/gamepad/gamepad.cpp index 957040a3f8..b37d099b30 100644 --- a/libsnes/bsnes/snes/controller/gamepad/gamepad.cpp +++ b/waterbox/libsnes/bsnes/snes/controller/gamepad/gamepad.cpp @@ -10,25 +10,12 @@ uint2 Gamepad::data() { void Gamepad::latch(bool data) { if(latched == data) return; latched = data; - counter = 0; -} - -void Gamepad::serialize(serializer& s) { - Processor::serialize(s); - //Save block. - unsigned char block[Controller::SaveSize] = {0}; - block[0] = latched ? 1 : 0; - block[1] = counter; - s.array(block, Controller::SaveSize); - if(s.mode() == nall::serializer::Load) { - latched = (block[0] != 0); - counter = block[1]; - } -} - -Gamepad::Gamepad(bool port) : Controller(port) { - latched = 0; - counter = 0; + counter = 0; +} + +Gamepad::Gamepad(bool port) : Controller(port) { + latched = 0; + counter = 0; } #endif diff --git a/libsnes/bsnes/snes/controller/gamepad/gamepad.hpp b/waterbox/libsnes/bsnes/snes/controller/gamepad/gamepad.hpp similarity index 77% rename from libsnes/bsnes/snes/controller/gamepad/gamepad.hpp rename to waterbox/libsnes/bsnes/snes/controller/gamepad/gamepad.hpp index 86fbabb551..63394dd44b 100644 --- a/libsnes/bsnes/snes/controller/gamepad/gamepad.hpp +++ b/waterbox/libsnes/bsnes/snes/controller/gamepad/gamepad.hpp @@ -1,9 +1,8 @@ struct Gamepad : Controller { - uint2 data(); - void latch(bool data); - Gamepad(bool port); - void serialize(serializer& s); -private: - bool latched; - unsigned counter; + uint2 data(); + void latch(bool data); + Gamepad(bool port); +private: + bool latched; + unsigned counter; }; diff --git a/libsnes/bsnes/snes/controller/justifier/justifier.cpp b/waterbox/libsnes/bsnes/snes/controller/justifier/justifier.cpp similarity index 69% rename from libsnes/bsnes/snes/controller/justifier/justifier.cpp rename to waterbox/libsnes/bsnes/snes/controller/justifier/justifier.cpp index 00d661b475..af8ff3edfb 100644 --- a/libsnes/bsnes/snes/controller/justifier/justifier.cpp +++ b/waterbox/libsnes/bsnes/snes/controller/justifier/justifier.cpp @@ -95,48 +95,12 @@ void Justifier::latch(bool data) { if(latched == data) return; latched = data; counter = 0; - if(latched == 0) active = !active; //toggle between both controllers, even when unchained -} - -void Justifier::serialize(serializer& s) { - Processor::serialize(s); - //Save block. - unsigned char block[Controller::SaveSize] = {0}; - block[0] = latched ? 1 : 0; - block[1] = counter; - block[2] = active ? 1 : 0; - block[3] = player1.trigger ? 1 : 0; - block[4] = player2.trigger ? 1 : 0; - block[5] = player1.start ? 1 : 0; - block[6] = player2.start ? 1 : 0; - block[7] = (unsigned short)player1.x >> 8; - block[8] = (unsigned short)player1.x; - block[9] = (unsigned short)player2.x >> 8; - block[10] = (unsigned short)player2.x; - block[11] = (unsigned short)player1.y >> 8; - block[12] = (unsigned short)player1.y; - block[13] = (unsigned short)player2.y >> 8; - block[14] = (unsigned short)player2.y; - s.array(block, Controller::SaveSize); - if(s.mode() == nall::serializer::Load) { - latched = (block[0] != 0); - counter = block[1]; - active = (block[2] != 0); - player1.trigger = (block[3] != 0); - player2.trigger = (block[4] != 0); - player1.start = (block[5] != 0); - player2.start = (block[6] != 0); - player1.x = (short)(((unsigned short)block[7] << 8) | (unsigned short)block[8]); - player2.x = (short)(((unsigned short)block[9] << 8) | (unsigned short)block[10]); - player1.y = (short)(((unsigned short)block[11] << 8) | (unsigned short)block[12]); - player2.y = (short)(((unsigned short)block[13] << 8) | (unsigned short)block[14]); - } -} - - -Justifier::Justifier(bool port, bool chained) : Controller(port), chained(chained) { - create(Controller::Enter, 21477272); - latched = 0; + if(latched == 0) active = !active; //toggle between both controllers, even when unchained +} + +Justifier::Justifier(bool port, bool chained) : Controller(port), chained(chained) { + create(Controller::Enter, 21477272, 8192); + latched = 0; counter = 0; active = 0; diff --git a/libsnes/bsnes/snes/controller/justifier/justifier.hpp b/waterbox/libsnes/bsnes/snes/controller/justifier/justifier.hpp similarity index 89% rename from libsnes/bsnes/snes/controller/justifier/justifier.hpp rename to waterbox/libsnes/bsnes/snes/controller/justifier/justifier.hpp index aeffc1e50b..f927acf6bf 100644 --- a/libsnes/bsnes/snes/controller/justifier/justifier.hpp +++ b/waterbox/libsnes/bsnes/snes/controller/justifier/justifier.hpp @@ -1,11 +1,10 @@ struct Justifier : Controller { - void enter(); - uint2 data(); - void latch(bool data); - void serialize(serializer& s); - Justifier(bool port, bool chained); - -//private: + void enter(); + uint2 data(); + void latch(bool data); + Justifier(bool port, bool chained); + +//private: const bool chained; //true if the second justifier is attached to the first bool latched; unsigned counter; diff --git a/libsnes/bsnes/snes/controller/mouse/mouse.cpp b/waterbox/libsnes/bsnes/snes/controller/mouse/mouse.cpp similarity index 76% rename from libsnes/bsnes/snes/controller/mouse/mouse.cpp rename to waterbox/libsnes/bsnes/snes/controller/mouse/mouse.cpp index 15f97e3fb6..97d0339170 100644 --- a/libsnes/bsnes/snes/controller/mouse/mouse.cpp +++ b/waterbox/libsnes/bsnes/snes/controller/mouse/mouse.cpp @@ -1,20 +1,20 @@ #ifdef CONTROLLER_CPP -uint2 Mouse::data() { - if(counter >= 32) return 1; - - if(counter == 0) { - position_x = interface()->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::X); //-n = left, 0 = center, +n = right - position_y = interface()->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::Y); //-n = up, 0 = center, +n = down - } - - - bool direction_x = position_x < 0; //0 = right, 1 = left - bool direction_y = position_y < 0; //0 = down, 1 = up - - int position_x_fixed = position_x; - int position_y_fixed = position_y; - +uint2 Mouse::data() { + if(counter >= 32) return 1; + + if(counter == 0) { + position_x = interface()->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::X); //-n = left, 0 = center, +n = right + position_y = interface()->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::Y); //-n = up, 0 = center, +n = down + } + + + bool direction_x = position_x < 0; //0 = right, 1 = left + bool direction_y = position_y < 0; //0 = down, 1 = up + + int position_x_fixed = position_x; + int position_y_fixed = position_y; + if(position_x < 0) position_x_fixed = -position_x; //abs(position_x) if(position_y < 0) position_y_fixed = -position_y; //abs(position_y) @@ -65,31 +65,12 @@ uint2 Mouse::data() { void Mouse::latch(bool data) { if(latched == data) return; latched = data; - counter = 0; -} - -void Mouse::serialize(serializer& s) { - Processor::serialize(s); - //Save block. - unsigned char block[Controller::SaveSize] = {0}; - block[0] = latched ? 1 : 0; - block[1] = counter; - block[2] = (unsigned short)position_x >> 8; - block[3] = (unsigned short)position_x; - block[4] = (unsigned short)position_y >> 8; - block[5] = (unsigned short)position_y; - s.array(block, Controller::SaveSize); - if(s.mode() == nall::serializer::Load) { - latched = (block[0] != 0); - counter = block[1]; - position_x = (short)(((unsigned short)block[2] << 8) | (unsigned short)block[3]); - position_y = (short)(((unsigned short)block[4] << 8) | (unsigned short)block[5]); - } -} - -Mouse::Mouse(bool port) : Controller(port) { - latched = 0; - counter = 0; + counter = 0; +} + +Mouse::Mouse(bool port) : Controller(port) { + latched = 0; + counter = 0; } #endif diff --git a/libsnes/bsnes/snes/controller/mouse/mouse.hpp b/waterbox/libsnes/bsnes/snes/controller/mouse/mouse.hpp similarity index 80% rename from libsnes/bsnes/snes/controller/mouse/mouse.hpp rename to waterbox/libsnes/bsnes/snes/controller/mouse/mouse.hpp index cad1b5569d..dd4d239995 100644 --- a/libsnes/bsnes/snes/controller/mouse/mouse.hpp +++ b/waterbox/libsnes/bsnes/snes/controller/mouse/mouse.hpp @@ -1,11 +1,10 @@ struct Mouse : Controller { - uint2 data(); - void latch(bool data); - Mouse(bool port); - void serialize(serializer& s); -private: - bool latched; - unsigned counter; - int position_x; - int position_y; -}; + uint2 data(); + void latch(bool data); + Mouse(bool port); +private: + bool latched; + unsigned counter; + int position_x; + int position_y; +}; diff --git a/libsnes/bsnes/snes/controller/multitap/multitap.cpp b/waterbox/libsnes/bsnes/snes/controller/multitap/multitap.cpp similarity index 68% rename from libsnes/bsnes/snes/controller/multitap/multitap.cpp rename to waterbox/libsnes/bsnes/snes/controller/multitap/multitap.cpp index 0f1e4d995b..9409946479 100644 --- a/libsnes/bsnes/snes/controller/multitap/multitap.cpp +++ b/waterbox/libsnes/bsnes/snes/controller/multitap/multitap.cpp @@ -35,32 +35,12 @@ void Multitap::latch(bool data) { latched = data; counter1 = 0; - counter2 = 0; -} - -void Multitap::serialize(serializer& s) { - Processor::serialize(s); - //Save block. - unsigned char block[Controller::SaveSize] = {0}; - block[0] = latched ? 1 : 0; - block[1] = counter1; - block[2] = counter2; - block[3] = connected; - block[4] = toggleConnectedInput; - s.array(block, Controller::SaveSize); - if(s.mode() == nall::serializer::Load) { - latched = (block[0] != 0); - counter1 = block[1]; - counter2 = block[2]; - connected = block[3]; - toggleConnectedInput = block[4]; - } -} - - -Multitap::Multitap(bool port) : Controller(port) { - latched = 0; - counter1 = 0; + counter2 = 0; +} + +Multitap::Multitap(bool port) : Controller(port) { + latched = 0; + counter1 = 0; counter2 = 0; connected = true; toggleConnectedInput = false; diff --git a/libsnes/bsnes/snes/controller/multitap/multitap.hpp b/waterbox/libsnes/bsnes/snes/controller/multitap/multitap.hpp similarity index 83% rename from libsnes/bsnes/snes/controller/multitap/multitap.hpp rename to waterbox/libsnes/bsnes/snes/controller/multitap/multitap.hpp index 7aee454a89..b64feb44b3 100644 --- a/libsnes/bsnes/snes/controller/multitap/multitap.hpp +++ b/waterbox/libsnes/bsnes/snes/controller/multitap/multitap.hpp @@ -1,12 +1,11 @@ struct Multitap : Controller { - uint2 data(); - void latch(bool data); - Multitap(bool port); - void serialize(serializer& s); -private: - bool connected; - bool toggleConnectedInput; - bool latched; - unsigned counter1; + uint2 data(); + void latch(bool data); + Multitap(bool port); +private: + bool connected; + bool toggleConnectedInput; + bool latched; + unsigned counter1; unsigned counter2; }; diff --git a/libsnes/bsnes/snes/controller/superscope/superscope.cpp b/waterbox/libsnes/bsnes/snes/controller/superscope/superscope.cpp similarity index 78% rename from libsnes/bsnes/snes/controller/superscope/superscope.cpp rename to waterbox/libsnes/bsnes/snes/controller/superscope/superscope.cpp index ee6a312709..09967f2676 100644 --- a/libsnes/bsnes/snes/controller/superscope/superscope.cpp +++ b/waterbox/libsnes/bsnes/snes/controller/superscope/superscope.cpp @@ -95,43 +95,12 @@ uint2 SuperScope::data() { void SuperScope::latch(bool data) { if(latched == data) return; latched = data; - counter = 0; -} - -void SuperScope::serialize(serializer& s) { - Processor::serialize(s); - //Save block. - unsigned char block[Controller::SaveSize] = {0}; - block[0] = latched ? 1 : 0; - block[1] = counter; - block[2] = trigger ? 1 : 0; - block[3] = cursor ? 1 : 0; - block[4] = turbo ? 1 : 0; - block[5] = pause ? 1 : 0; - block[6] = offscreen ? 1 : 0; - block[7] = (unsigned short)x >> 8; - block[8] = (unsigned short)x; - block[9] = (unsigned short)y >> 8; - block[10] = (unsigned short)y; - - s.array(block, Controller::SaveSize); - if(s.mode() == nall::serializer::Load) { - latched = (block[0] != 0); - counter = block[1]; - trigger = (block[2] != 0); - cursor = (block[3] != 0); - turbo = (block[4] != 0); - pause = (block[5] != 0); - offscreen = (block[6] != 0); - x = (short)(((unsigned short)block[7] << 8) | (unsigned short)block[8]); - y = (short)(((unsigned short)block[9] << 8) | (unsigned short)block[10]); - } -} - - -SuperScope::SuperScope(bool port) : Controller(port) { - create(Controller::Enter, 21477272); - latched = 0; + counter = 0; +} + +SuperScope::SuperScope(bool port) : Controller(port) { + create(Controller::Enter, 21477272, 8192); + latched = 0; counter = 0; //center cursor onscreen diff --git a/libsnes/bsnes/snes/controller/superscope/superscope.hpp b/waterbox/libsnes/bsnes/snes/controller/superscope/superscope.hpp similarity index 88% rename from libsnes/bsnes/snes/controller/superscope/superscope.hpp rename to waterbox/libsnes/bsnes/snes/controller/superscope/superscope.hpp index 452bb9d1f5..a7a90b71a3 100644 --- a/libsnes/bsnes/snes/controller/superscope/superscope.hpp +++ b/waterbox/libsnes/bsnes/snes/controller/superscope/superscope.hpp @@ -1,11 +1,10 @@ struct SuperScope : Controller { - void enter(); - uint2 data(); - void latch(bool data); - void serialize(serializer& s); - SuperScope(bool port); - -//private: + void enter(); + uint2 data(); + void latch(bool data); + SuperScope(bool port); + +//private: bool latched; unsigned counter; diff --git a/libsnes/bsnes/snes/controller/usart/usart.cpp b/waterbox/libsnes/bsnes/snes/controller/usart/usart.cpp similarity index 94% rename from libsnes/bsnes/snes/controller/usart/usart.cpp rename to waterbox/libsnes/bsnes/snes/controller/usart/usart.cpp index 617b2d696f..2573d8794d 100644 --- a/libsnes/bsnes/snes/controller/usart/usart.cpp +++ b/waterbox/libsnes/bsnes/snes/controller/usart/usart.cpp @@ -89,10 +89,10 @@ USART::USART(bool port) : Controller(port) { txdata = 0; string filename = interface()->path(Cartridge::Slot::Base, "usart.so"); - if(open_absolute(filename)) { + if(0 /*open_absolute(filename)*/) { init = sym("usart_init"); main = sym("usart_main"); - if(init && main) create(Controller::Enter, 1000000); + if(init && main) create(Controller::Enter, 1000000, 8192); } } diff --git a/libsnes/bsnes/snes/controller/usart/usart.hpp b/waterbox/libsnes/bsnes/snes/controller/usart/usart.hpp similarity index 100% rename from libsnes/bsnes/snes/controller/usart/usart.hpp rename to waterbox/libsnes/bsnes/snes/controller/usart/usart.hpp diff --git a/libsnes/bsnes/snes/cpu/core/algorithms.cpp b/waterbox/libsnes/bsnes/snes/cpu/core/algorithms.cpp similarity index 100% rename from libsnes/bsnes/snes/cpu/core/algorithms.cpp rename to waterbox/libsnes/bsnes/snes/cpu/core/algorithms.cpp diff --git a/libsnes/bsnes/snes/cpu/core/core.cpp b/waterbox/libsnes/bsnes/snes/cpu/core/core.cpp similarity index 98% rename from libsnes/bsnes/snes/cpu/core/core.cpp rename to waterbox/libsnes/bsnes/snes/cpu/core/core.cpp index 427176b05a..bef86eae07 100644 --- a/libsnes/bsnes/snes/cpu/core/core.cpp +++ b/waterbox/libsnes/bsnes/snes/cpu/core/core.cpp @@ -3,7 +3,6 @@ #define CPUCORE_CPP namespace SNES { -#include "serialization.cpp" #include "algorithms.cpp" #include "disassembler/disassembler.cpp" diff --git a/libsnes/bsnes/snes/cpu/core/core.hpp b/waterbox/libsnes/bsnes/snes/cpu/core/core.hpp similarity index 99% rename from libsnes/bsnes/snes/cpu/core/core.hpp rename to waterbox/libsnes/bsnes/snes/cpu/core/core.hpp index 65c5fa9bc3..825ccd390b 100644 --- a/libsnes/bsnes/snes/cpu/core/core.hpp +++ b/waterbox/libsnes/bsnes/snes/cpu/core/core.hpp @@ -212,6 +212,5 @@ struct CPUcore { table_mx = 1024, //16-bit accumulator, 16-bit index }; - void core_serialize(serializer&); CPUcore(); }; diff --git a/libsnes/bsnes/snes/cpu/core/disassembler/disassembler.cpp b/waterbox/libsnes/bsnes/snes/cpu/core/disassembler/disassembler.cpp similarity index 100% rename from libsnes/bsnes/snes/cpu/core/disassembler/disassembler.cpp rename to waterbox/libsnes/bsnes/snes/cpu/core/disassembler/disassembler.cpp diff --git a/libsnes/bsnes/snes/cpu/core/disassembler/disassembler.hpp b/waterbox/libsnes/bsnes/snes/cpu/core/disassembler/disassembler.hpp similarity index 100% rename from libsnes/bsnes/snes/cpu/core/disassembler/disassembler.hpp rename to waterbox/libsnes/bsnes/snes/cpu/core/disassembler/disassembler.hpp diff --git a/libsnes/bsnes/snes/cpu/core/memory.hpp b/waterbox/libsnes/bsnes/snes/cpu/core/memory.hpp similarity index 100% rename from libsnes/bsnes/snes/cpu/core/memory.hpp rename to waterbox/libsnes/bsnes/snes/cpu/core/memory.hpp diff --git a/libsnes/bsnes/snes/cpu/core/opcode_misc.cpp b/waterbox/libsnes/bsnes/snes/cpu/core/opcode_misc.cpp similarity index 94% rename from libsnes/bsnes/snes/cpu/core/opcode_misc.cpp rename to waterbox/libsnes/bsnes/snes/cpu/core/opcode_misc.cpp index 6d2b72fae7..8087fe66e1 100644 --- a/libsnes/bsnes/snes/cpu/core/opcode_misc.cpp +++ b/waterbox/libsnes/bsnes/snes/cpu/core/opcode_misc.cpp @@ -72,28 +72,16 @@ L rd.h = op_readlong(vectorN + 1); } void CPUcore::op_stp() { - if(regs.hang == HangType::Stop) - goto SKIP; - regs.hang = HangType::Stop; while(regs.wai = true) { L op_io(); - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); -SKIP: ; - } - regs.hang = HangType::None; + } } void CPUcore::op_wai() { - if (regs.hang == HangType::Wait) - goto SKIP; regs.wai = true; - regs.hang = HangType::Wait; while(regs.wai) { L op_io(); - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - SKIP: ; - } - regs.hang = HangType::None; + } op_io(); } diff --git a/libsnes/bsnes/snes/cpu/core/opcode_pc.cpp b/waterbox/libsnes/bsnes/snes/cpu/core/opcode_pc.cpp similarity index 100% rename from libsnes/bsnes/snes/cpu/core/opcode_pc.cpp rename to waterbox/libsnes/bsnes/snes/cpu/core/opcode_pc.cpp diff --git a/libsnes/bsnes/snes/cpu/core/opcode_read.cpp b/waterbox/libsnes/bsnes/snes/cpu/core/opcode_read.cpp similarity index 100% rename from libsnes/bsnes/snes/cpu/core/opcode_read.cpp rename to waterbox/libsnes/bsnes/snes/cpu/core/opcode_read.cpp diff --git a/libsnes/bsnes/snes/cpu/core/opcode_rmw.cpp b/waterbox/libsnes/bsnes/snes/cpu/core/opcode_rmw.cpp similarity index 100% rename from libsnes/bsnes/snes/cpu/core/opcode_rmw.cpp rename to waterbox/libsnes/bsnes/snes/cpu/core/opcode_rmw.cpp diff --git a/libsnes/bsnes/snes/cpu/core/opcode_write.cpp b/waterbox/libsnes/bsnes/snes/cpu/core/opcode_write.cpp similarity index 100% rename from libsnes/bsnes/snes/cpu/core/opcode_write.cpp rename to waterbox/libsnes/bsnes/snes/cpu/core/opcode_write.cpp diff --git a/libsnes/bsnes/snes/cpu/core/registers.hpp b/waterbox/libsnes/bsnes/snes/cpu/core/registers.hpp similarity index 95% rename from libsnes/bsnes/snes/cpu/core/registers.hpp rename to waterbox/libsnes/bsnes/snes/cpu/core/registers.hpp index 46fea03208..adcf797fd8 100644 --- a/libsnes/bsnes/snes/cpu/core/registers.hpp +++ b/waterbox/libsnes/bsnes/snes/cpu/core/registers.hpp @@ -1,5 +1,3 @@ -enum class HangType: unsigned { None, Wait, Stop }; - struct flag_t { bool n, v, m, x, d, i, z, c; @@ -75,14 +73,11 @@ struct regs_t { bool irq; //IRQ pin (0 = low, 1 = trigger) bool wai; //raised during wai, cleared after interrupt triggered - uint8 mdr; //memory data register uint16 vector; //interrupt vector address - HangType hang; - regs_t(): - a(r[0]), x(r[1]), y(r[2]), z(r[3]), s(r[4]), d(r[5]), db(0), e(false), irq(false), wai(false), mdr(0), vector(0), hang(HangType::None) { + a(r[0]), x(r[1]), y(r[2]), z(r[3]), s(r[4]), d(r[5]), db(0), e(false), irq(false), wai(false), mdr(0), vector(0) { z = 0; } }; diff --git a/libsnes/bsnes/snes/cpu/core/table.cpp b/waterbox/libsnes/bsnes/snes/cpu/core/table.cpp similarity index 100% rename from libsnes/bsnes/snes/cpu/core/table.cpp rename to waterbox/libsnes/bsnes/snes/cpu/core/table.cpp diff --git a/libsnes/bsnes/snes/cpu/cpu.cpp b/waterbox/libsnes/bsnes/snes/cpu/cpu.cpp similarity index 92% rename from libsnes/bsnes/snes/cpu/cpu.cpp rename to waterbox/libsnes/bsnes/snes/cpu/cpu.cpp index 398ac0e7dd..0710232d34 100644 --- a/libsnes/bsnes/snes/cpu/cpu.cpp +++ b/waterbox/libsnes/bsnes/snes/cpu/cpu.cpp @@ -5,7 +5,6 @@ namespace SNES { CPU cpu; -#include "serialization.cpp" #include "dma/dma.cpp" #include "memory/memory.cpp" #include "mmio/mmio.cpp" @@ -55,13 +54,9 @@ void CPU::Enter() { cpu.enter(); } void CPU::enter() { while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::CPU) { - // we can only stop if there's enough time for at least one more event - // on both the PPU and the SMP - if (smp.clock < 0 && ppu.clock < 0) { - scheduler.sync = Scheduler::SynchronizeMode::All; - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } + if(scheduler.sync == Scheduler::SynchronizeMode::CPU) { + scheduler.sync = Scheduler::SynchronizeMode::All; + scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); } if(status.interrupt_pending) { @@ -143,7 +138,7 @@ void CPU::power() { } void CPU::reset() { - create(Enter, system.cpu_frequency()); + create(Enter, system.cpu_frequency(), 16384); coprocessors.reset(); PPUcounter::reset(); diff --git a/libsnes/bsnes/snes/cpu/cpu.hpp b/waterbox/libsnes/bsnes/snes/cpu/cpu.hpp similarity index 98% rename from libsnes/bsnes/snes/cpu/cpu.hpp rename to waterbox/libsnes/bsnes/snes/cpu/cpu.hpp index bb70ac78b4..bf0ecd2fdb 100644 --- a/libsnes/bsnes/snes/cpu/cpu.hpp +++ b/waterbox/libsnes/bsnes/snes/cpu/cpu.hpp @@ -24,7 +24,6 @@ struct CPU : public Processor, public CPUcore, public PPUcounter { void power(); void reset(); - void serialize(serializer&); CPU(); ~CPU(); void initialize(); diff --git a/libsnes/bsnes/snes/cpu/dma/dma.cpp b/waterbox/libsnes/bsnes/snes/cpu/dma/dma.cpp similarity index 100% rename from libsnes/bsnes/snes/cpu/dma/dma.cpp rename to waterbox/libsnes/bsnes/snes/cpu/dma/dma.cpp diff --git a/libsnes/bsnes/snes/cpu/dma/dma.hpp b/waterbox/libsnes/bsnes/snes/cpu/dma/dma.hpp similarity index 100% rename from libsnes/bsnes/snes/cpu/dma/dma.hpp rename to waterbox/libsnes/bsnes/snes/cpu/dma/dma.hpp diff --git a/libsnes/bsnes/snes/cpu/memory/memory.cpp b/waterbox/libsnes/bsnes/snes/cpu/memory/memory.cpp similarity index 100% rename from libsnes/bsnes/snes/cpu/memory/memory.cpp rename to waterbox/libsnes/bsnes/snes/cpu/memory/memory.cpp diff --git a/libsnes/bsnes/snes/cpu/memory/memory.hpp b/waterbox/libsnes/bsnes/snes/cpu/memory/memory.hpp similarity index 100% rename from libsnes/bsnes/snes/cpu/memory/memory.hpp rename to waterbox/libsnes/bsnes/snes/cpu/memory/memory.hpp diff --git a/libsnes/bsnes/snes/cpu/mmio/mmio.cpp b/waterbox/libsnes/bsnes/snes/cpu/mmio/mmio.cpp similarity index 100% rename from libsnes/bsnes/snes/cpu/mmio/mmio.cpp rename to waterbox/libsnes/bsnes/snes/cpu/mmio/mmio.cpp diff --git a/libsnes/bsnes/snes/cpu/mmio/mmio.hpp b/waterbox/libsnes/bsnes/snes/cpu/mmio/mmio.hpp similarity index 100% rename from libsnes/bsnes/snes/cpu/mmio/mmio.hpp rename to waterbox/libsnes/bsnes/snes/cpu/mmio/mmio.hpp diff --git a/libsnes/bsnes/snes/cpu/timing/irq.cpp b/waterbox/libsnes/bsnes/snes/cpu/timing/irq.cpp similarity index 100% rename from libsnes/bsnes/snes/cpu/timing/irq.cpp rename to waterbox/libsnes/bsnes/snes/cpu/timing/irq.cpp diff --git a/libsnes/bsnes/snes/cpu/timing/joypad.cpp b/waterbox/libsnes/bsnes/snes/cpu/timing/joypad.cpp similarity index 100% rename from libsnes/bsnes/snes/cpu/timing/joypad.cpp rename to waterbox/libsnes/bsnes/snes/cpu/timing/joypad.cpp diff --git a/libsnes/bsnes/snes/cpu/timing/timing.cpp b/waterbox/libsnes/bsnes/snes/cpu/timing/timing.cpp similarity index 100% rename from libsnes/bsnes/snes/cpu/timing/timing.cpp rename to waterbox/libsnes/bsnes/snes/cpu/timing/timing.cpp diff --git a/libsnes/bsnes/snes/cpu/timing/timing.hpp b/waterbox/libsnes/bsnes/snes/cpu/timing/timing.hpp similarity index 100% rename from libsnes/bsnes/snes/cpu/timing/timing.hpp rename to waterbox/libsnes/bsnes/snes/cpu/timing/timing.hpp diff --git a/libsnes/bsnes/snes/dsp/brr.cpp b/waterbox/libsnes/bsnes/snes/dsp/brr.cpp similarity index 100% rename from libsnes/bsnes/snes/dsp/brr.cpp rename to waterbox/libsnes/bsnes/snes/dsp/brr.cpp diff --git a/libsnes/bsnes/snes/dsp/counter.cpp b/waterbox/libsnes/bsnes/snes/dsp/counter.cpp similarity index 100% rename from libsnes/bsnes/snes/dsp/counter.cpp rename to waterbox/libsnes/bsnes/snes/dsp/counter.cpp diff --git a/libsnes/bsnes/snes/dsp/dsp.cpp b/waterbox/libsnes/bsnes/snes/dsp/dsp.cpp similarity index 99% rename from libsnes/bsnes/snes/dsp/dsp.cpp rename to waterbox/libsnes/bsnes/snes/dsp/dsp.cpp index f03b319e81..75255205d7 100644 --- a/libsnes/bsnes/snes/dsp/dsp.cpp +++ b/waterbox/libsnes/bsnes/snes/dsp/dsp.cpp @@ -8,7 +8,6 @@ DSP dsp; #define REG(n) state.regs[r_##n] #define VREG(n) state.regs[v.vidx + v_##n] -#include "serialization.cpp" #include "gaussian.cpp" #include "counter.cpp" #include "envelope.cpp" diff --git a/libsnes/bsnes/snes/dsp/dsp.hpp b/waterbox/libsnes/bsnes/snes/dsp/dsp.hpp similarity index 99% rename from libsnes/bsnes/snes/dsp/dsp.hpp rename to waterbox/libsnes/bsnes/snes/dsp/dsp.hpp index a80b38e659..532fcbecab 100644 --- a/libsnes/bsnes/snes/dsp/dsp.hpp +++ b/waterbox/libsnes/bsnes/snes/dsp/dsp.hpp @@ -10,7 +10,6 @@ struct DSP : public Processor { void power(); void reset(); - void serialize(serializer&); DSP(); ~DSP(); diff --git a/libsnes/bsnes/snes/dsp/echo.cpp b/waterbox/libsnes/bsnes/snes/dsp/echo.cpp similarity index 100% rename from libsnes/bsnes/snes/dsp/echo.cpp rename to waterbox/libsnes/bsnes/snes/dsp/echo.cpp diff --git a/libsnes/bsnes/snes/dsp/envelope.cpp b/waterbox/libsnes/bsnes/snes/dsp/envelope.cpp similarity index 100% rename from libsnes/bsnes/snes/dsp/envelope.cpp rename to waterbox/libsnes/bsnes/snes/dsp/envelope.cpp diff --git a/libsnes/bsnes/snes/dsp/gaussian.cpp b/waterbox/libsnes/bsnes/snes/dsp/gaussian.cpp similarity index 100% rename from libsnes/bsnes/snes/dsp/gaussian.cpp rename to waterbox/libsnes/bsnes/snes/dsp/gaussian.cpp diff --git a/libsnes/bsnes/snes/dsp/misc.cpp b/waterbox/libsnes/bsnes/snes/dsp/misc.cpp similarity index 100% rename from libsnes/bsnes/snes/dsp/misc.cpp rename to waterbox/libsnes/bsnes/snes/dsp/misc.cpp diff --git a/libsnes/bsnes/snes/dsp/voice.cpp b/waterbox/libsnes/bsnes/snes/dsp/voice.cpp similarity index 100% rename from libsnes/bsnes/snes/dsp/voice.cpp rename to waterbox/libsnes/bsnes/snes/dsp/voice.cpp diff --git a/libsnes/bsnes/snes/interface/interface.cpp b/waterbox/libsnes/bsnes/snes/interface/interface.cpp similarity index 97% rename from libsnes/bsnes/snes/interface/interface.cpp rename to waterbox/libsnes/bsnes/snes/interface/interface.cpp index 03d3e207f3..a117889cae 100644 --- a/libsnes/bsnes/snes/interface/interface.cpp +++ b/waterbox/libsnes/bsnes/snes/interface/interface.cpp @@ -21,25 +21,25 @@ void Interface::inputNotify(int index) { } void Interface::message(const string &text) { - print(text, "\n"); -} - -time_t Interface::currentTime() -{ - return time(0); -} - -time_t Interface::randomSeed() -{ - return time(0); -} - -int Interface::getBackdropColor() -{ - return -1; + print(text, "\n"); +} + +time_t Interface::currentTime() +{ + return time(0); +} + +time_t Interface::randomSeed() +{ + return time(0); +} + +int Interface::getBackdropColor() +{ + return -1; } void Interface::cpuTrace(uint32_t which, const char *msg) { -} - -} +} + +} diff --git a/libsnes/bsnes/snes/interface/interface.hpp b/waterbox/libsnes/bsnes/snes/interface/interface.hpp similarity index 99% rename from libsnes/bsnes/snes/interface/interface.hpp rename to waterbox/libsnes/bsnes/snes/interface/interface.hpp index af94e1955d..f8c152f8c1 100644 --- a/libsnes/bsnes/snes/interface/interface.hpp +++ b/waterbox/libsnes/bsnes/snes/interface/interface.hpp @@ -15,11 +15,11 @@ struct Interface { virtual int16_t inputPoll(bool port, Input::Device device, unsigned index, unsigned id); virtual void inputNotify(int index); - - virtual string path(Cartridge::Slot slot, const string &hint) = 0; - virtual void message(const string &text); - virtual time_t currentTime(); - virtual time_t randomSeed(); + + virtual string path(Cartridge::Slot slot, const string &hint) = 0; + virtual void message(const string &text); + virtual time_t currentTime(); + virtual time_t randomSeed(); //zero 27-sep-2012 virtual void scanlineStart(int line) = 0; @@ -33,6 +33,6 @@ struct Interface { //zero 23-dec-2012 virtual void* allocSharedMemory(const char* memtype, size_t amt, int initialByte = -1) = 0; virtual void freeSharedMemory(void* ptr) = 0; -}; - -Interface *interface(); +}; + +Interface *interface(); diff --git a/libsnes/bsnes/snes/memory/memory-inline.hpp b/waterbox/libsnes/bsnes/snes/memory/memory-inline.hpp similarity index 93% rename from libsnes/bsnes/snes/memory/memory-inline.hpp rename to waterbox/libsnes/bsnes/snes/memory/memory-inline.hpp index 85cd958943..6fce1b1d47 100644 --- a/libsnes/bsnes/snes/memory/memory-inline.hpp +++ b/waterbox/libsnes/bsnes/snes/memory/memory-inline.hpp @@ -19,9 +19,10 @@ StaticRAM::~StaticRAM() { delete[] data_; } void MappedRAM::reset() { if(data_) { - if(name_) interface()->freeSharedMemory(data_); + /*if(name_) interface()->freeSharedMemory(data_); else free(data_); - data_ = 0; + data_ = 0;*/ + abort(); } size_ = 0; write_protect_ = false; @@ -54,7 +55,6 @@ MappedRAM::MappedRAM(const char* name) : data_(0), size_(0), write_protect_(fals //Bus uint8 Bus::read(unsigned addr) { - if(cheat.override[addr]) return cheat.read(addr); return reader[lookup[addr]](target[addr]); } diff --git a/libsnes/bsnes/snes/memory/memory.cpp b/waterbox/libsnes/bsnes/snes/memory/memory.cpp similarity index 92% rename from libsnes/bsnes/snes/memory/memory.cpp rename to waterbox/libsnes/bsnes/snes/memory/memory.cpp index ede9cbd0ef..a2ced25c58 100644 --- a/libsnes/bsnes/snes/memory/memory.cpp +++ b/waterbox/libsnes/bsnes/snes/memory/memory.cpp @@ -1,4 +1,5 @@ #include +#include #define MEMORY_CPP namespace SNES { @@ -67,13 +68,11 @@ void Bus::map_xml() { } Bus::Bus() { - lookup = new uint8 [16 * 1024 * 1024]; - target = new uint32[16 * 1024 * 1024]; + lookup = (uint8*)alloc_sealed(16 * 1024 * 1024); + target = (uint32*)alloc_sealed(16 * 1024 * 1024 * sizeof(uint32)); } Bus::~Bus() { - delete[] lookup; - delete[] target; } } diff --git a/libsnes/bsnes/snes/memory/memory.hpp b/waterbox/libsnes/bsnes/snes/memory/memory.hpp similarity index 100% rename from libsnes/bsnes/snes/memory/memory.hpp rename to waterbox/libsnes/bsnes/snes/memory/memory.hpp diff --git a/libsnes/bsnes/snes/ppu/background/background.cpp b/waterbox/libsnes/bsnes/snes/ppu/background/background.cpp similarity index 100% rename from libsnes/bsnes/snes/ppu/background/background.cpp rename to waterbox/libsnes/bsnes/snes/ppu/background/background.cpp diff --git a/libsnes/bsnes/snes/ppu/background/background.hpp b/waterbox/libsnes/bsnes/snes/ppu/background/background.hpp similarity index 97% rename from libsnes/bsnes/snes/ppu/background/background.hpp rename to waterbox/libsnes/bsnes/snes/ppu/background/background.hpp index c279a80631..080e37cb39 100644 --- a/libsnes/bsnes/snes/ppu/background/background.hpp +++ b/waterbox/libsnes/bsnes/snes/ppu/background/background.hpp @@ -70,7 +70,6 @@ struct Background { void begin_mode7(); void run_mode7(); - void serialize(serializer&); Background(PPU &self, unsigned id); PPU &self; diff --git a/libsnes/bsnes/snes/ppu/background/mode7.cpp b/waterbox/libsnes/bsnes/snes/ppu/background/mode7.cpp similarity index 100% rename from libsnes/bsnes/snes/ppu/background/mode7.cpp rename to waterbox/libsnes/bsnes/snes/ppu/background/mode7.cpp diff --git a/libsnes/bsnes/snes/ppu/counter/counter-inline.hpp b/waterbox/libsnes/bsnes/snes/ppu/counter/counter-inline.hpp similarity index 100% rename from libsnes/bsnes/snes/ppu/counter/counter-inline.hpp rename to waterbox/libsnes/bsnes/snes/ppu/counter/counter-inline.hpp diff --git a/libsnes/bsnes/snes/ppu/counter/counter.hpp b/waterbox/libsnes/bsnes/snes/ppu/counter/counter.hpp similarity index 97% rename from libsnes/bsnes/snes/ppu/counter/counter.hpp rename to waterbox/libsnes/bsnes/snes/ppu/counter/counter.hpp index b8d7aa7e2e..f872d6b1b7 100644 --- a/libsnes/bsnes/snes/ppu/counter/counter.hpp +++ b/waterbox/libsnes/bsnes/snes/ppu/counter/counter.hpp @@ -27,7 +27,6 @@ public: inline void reset(); function scanline; - void serialize(serializer&); private: inline void vcounter_tick(); diff --git a/libsnes/bsnes/snes/ppu/mmio/mmio.cpp b/waterbox/libsnes/bsnes/snes/ppu/mmio/mmio.cpp similarity index 100% rename from libsnes/bsnes/snes/ppu/mmio/mmio.cpp rename to waterbox/libsnes/bsnes/snes/ppu/mmio/mmio.cpp diff --git a/libsnes/bsnes/snes/ppu/mmio/mmio.hpp b/waterbox/libsnes/bsnes/snes/ppu/mmio/mmio.hpp similarity index 100% rename from libsnes/bsnes/snes/ppu/mmio/mmio.hpp rename to waterbox/libsnes/bsnes/snes/ppu/mmio/mmio.hpp diff --git a/libsnes/bsnes/snes/ppu/ppu.cpp b/waterbox/libsnes/bsnes/snes/ppu/ppu.cpp similarity index 94% rename from libsnes/bsnes/snes/ppu/ppu.cpp rename to waterbox/libsnes/bsnes/snes/ppu/ppu.cpp index ba0ca1c2fb..f78373e557 100644 --- a/libsnes/bsnes/snes/ppu/ppu.cpp +++ b/waterbox/libsnes/bsnes/snes/ppu/ppu.cpp @@ -10,7 +10,6 @@ PPU ppu; #include "screen/screen.cpp" #include "sprite/sprite.cpp" #include "window/window.cpp" -#include "serialization.cpp" void PPU::step(unsigned clocks) { clock += clocks; @@ -152,7 +151,7 @@ void PPU::initialize() vram = (uint8*)interface()->allocSharedMemory("VRAM",128 * 1024); oam = (uint8*)interface()->allocSharedMemory("OAM",544); cgram = (uint8*)interface()->allocSharedMemory("CGRAM",512); - surface = new uint32[512 * 512]; + surface = (uint32_t*)alloc_invisible(512 * 512 * sizeof(uint32_t)); output = surface + 16 * 512; } @@ -168,10 +167,7 @@ screen(*this) { } PPU::~PPU() { - delete[] surface; - interface()->freeSharedMemory(vram); - interface()->freeSharedMemory(oam); - interface()->freeSharedMemory(cgram); + abort(); } } diff --git a/libsnes/bsnes/snes/ppu/ppu.hpp b/waterbox/libsnes/bsnes/snes/ppu/ppu.hpp similarity index 97% rename from libsnes/bsnes/snes/ppu/ppu.hpp rename to waterbox/libsnes/bsnes/snes/ppu/ppu.hpp index 01748c472f..d099251083 100644 --- a/libsnes/bsnes/snes/ppu/ppu.hpp +++ b/waterbox/libsnes/bsnes/snes/ppu/ppu.hpp @@ -18,7 +18,6 @@ struct PPU : public Processor, public PPUcounter { void reset(); void layer_enable(unsigned layer, unsigned priority, bool enable); - void serialize(serializer&); void initialize(); PPU(); ~PPU(); diff --git a/libsnes/bsnes/snes/ppu/screen/screen.cpp b/waterbox/libsnes/bsnes/snes/ppu/screen/screen.cpp similarity index 100% rename from libsnes/bsnes/snes/ppu/screen/screen.cpp rename to waterbox/libsnes/bsnes/snes/ppu/screen/screen.cpp diff --git a/libsnes/bsnes/snes/ppu/screen/screen.hpp b/waterbox/libsnes/bsnes/snes/ppu/screen/screen.hpp similarity index 95% rename from libsnes/bsnes/snes/ppu/screen/screen.hpp rename to waterbox/libsnes/bsnes/snes/ppu/screen/screen.hpp index 6c6748410c..a194f7a5a4 100644 --- a/libsnes/bsnes/snes/ppu/screen/screen.hpp +++ b/waterbox/libsnes/bsnes/snes/ppu/screen/screen.hpp @@ -28,7 +28,6 @@ struct Screen { uint16 get_color(unsigned palette); uint16 get_direct_color(unsigned palette, unsigned tile); - void serialize(serializer&); Screen(PPU &self); PPU &self; diff --git a/libsnes/bsnes/snes/ppu/sprite/list.cpp b/waterbox/libsnes/bsnes/snes/ppu/sprite/list.cpp similarity index 100% rename from libsnes/bsnes/snes/ppu/sprite/list.cpp rename to waterbox/libsnes/bsnes/snes/ppu/sprite/list.cpp diff --git a/libsnes/bsnes/snes/ppu/sprite/sprite.cpp b/waterbox/libsnes/bsnes/snes/ppu/sprite/sprite.cpp similarity index 100% rename from libsnes/bsnes/snes/ppu/sprite/sprite.cpp rename to waterbox/libsnes/bsnes/snes/ppu/sprite/sprite.cpp diff --git a/libsnes/bsnes/snes/ppu/sprite/sprite.hpp b/waterbox/libsnes/bsnes/snes/ppu/sprite/sprite.hpp similarity index 97% rename from libsnes/bsnes/snes/ppu/sprite/sprite.hpp rename to waterbox/libsnes/bsnes/snes/ppu/sprite/sprite.hpp index 7735f35822..925bc4e502 100644 --- a/libsnes/bsnes/snes/ppu/sprite/sprite.hpp +++ b/waterbox/libsnes/bsnes/snes/ppu/sprite/sprite.hpp @@ -74,7 +74,6 @@ struct Sprite { bool on_scanline(SpriteItem&); - void serialize(serializer&); Sprite(PPU &self); PPU &self; diff --git a/libsnes/bsnes/snes/ppu/window/window.cpp b/waterbox/libsnes/bsnes/snes/ppu/window/window.cpp similarity index 100% rename from libsnes/bsnes/snes/ppu/window/window.cpp rename to waterbox/libsnes/bsnes/snes/ppu/window/window.cpp diff --git a/libsnes/bsnes/snes/ppu/window/window.hpp b/waterbox/libsnes/bsnes/snes/ppu/window/window.hpp similarity index 98% rename from libsnes/bsnes/snes/ppu/window/window.hpp rename to waterbox/libsnes/bsnes/snes/ppu/window/window.hpp index e1fcd4a4f0..fe3ddc7b69 100644 --- a/libsnes/bsnes/snes/ppu/window/window.hpp +++ b/waterbox/libsnes/bsnes/snes/ppu/window/window.hpp @@ -80,7 +80,6 @@ struct Window { uint8 mask, bool main_enable, bool sub_enable ); - void serialize(serializer&); Window(PPU &self); PPU &self; diff --git a/libsnes/bsnes/snes/profile-accuracy.hpp b/waterbox/libsnes/bsnes/snes/profile-accuracy.hpp similarity index 100% rename from libsnes/bsnes/snes/profile-accuracy.hpp rename to waterbox/libsnes/bsnes/snes/profile-accuracy.hpp diff --git a/libsnes/bsnes/snes/profile-compatibility.hpp b/waterbox/libsnes/bsnes/snes/profile-compatibility.hpp similarity index 100% rename from libsnes/bsnes/snes/profile-compatibility.hpp rename to waterbox/libsnes/bsnes/snes/profile-compatibility.hpp diff --git a/libsnes/bsnes/snes/profile-performance.hpp b/waterbox/libsnes/bsnes/snes/profile-performance.hpp similarity index 100% rename from libsnes/bsnes/snes/profile-performance.hpp rename to waterbox/libsnes/bsnes/snes/profile-performance.hpp diff --git a/libsnes/bsnes/snes/random/random.cpp b/waterbox/libsnes/bsnes/snes/random/random.cpp similarity index 81% rename from libsnes/bsnes/snes/random/random.cpp rename to waterbox/libsnes/bsnes/snes/random/random.cpp index a92a980aa4..09c9095bf2 100644 --- a/libsnes/bsnes/snes/random/random.cpp +++ b/waterbox/libsnes/bsnes/snes/random/random.cpp @@ -9,10 +9,6 @@ unsigned Random::operator()(unsigned result) { return iter = (iter >> 1) ^ (((iter & 1) - 1) & 0xedb88320); } -void Random::serialize(serializer &s) { - s.integer(iter); -} - Random::Random() { iter = 0; } diff --git a/libsnes/bsnes/snes/random/random.hpp b/waterbox/libsnes/bsnes/snes/random/random.hpp similarity index 83% rename from libsnes/bsnes/snes/random/random.hpp rename to waterbox/libsnes/bsnes/snes/random/random.hpp index 927d717250..e424da8cf9 100644 --- a/libsnes/bsnes/snes/random/random.hpp +++ b/waterbox/libsnes/bsnes/snes/random/random.hpp @@ -1,7 +1,6 @@ struct Random { void seed(unsigned seed); unsigned operator()(unsigned result = 0); - void serialize(serializer&); Random(); private: diff --git a/libsnes/bsnes/snes/scheduler/scheduler.cpp b/waterbox/libsnes/bsnes/snes/scheduler/scheduler.cpp similarity index 100% rename from libsnes/bsnes/snes/scheduler/scheduler.cpp rename to waterbox/libsnes/bsnes/snes/scheduler/scheduler.cpp diff --git a/libsnes/bsnes/snes/scheduler/scheduler.hpp b/waterbox/libsnes/bsnes/snes/scheduler/scheduler.hpp similarity index 100% rename from libsnes/bsnes/snes/scheduler/scheduler.hpp rename to waterbox/libsnes/bsnes/snes/scheduler/scheduler.hpp diff --git a/libsnes/bsnes/snes/smp/core/algorithms.cpp b/waterbox/libsnes/bsnes/snes/smp/core/algorithms.cpp similarity index 100% rename from libsnes/bsnes/snes/smp/core/algorithms.cpp rename to waterbox/libsnes/bsnes/snes/smp/core/algorithms.cpp diff --git a/libsnes/bsnes/snes/smp/core/core.cpp b/waterbox/libsnes/bsnes/snes/smp/core/core.cpp similarity index 99% rename from libsnes/bsnes/snes/smp/core/core.cpp rename to waterbox/libsnes/bsnes/snes/smp/core/core.cpp index 915efa3ad4..6908884eff 100644 --- a/libsnes/bsnes/snes/smp/core/core.cpp +++ b/waterbox/libsnes/bsnes/snes/smp/core/core.cpp @@ -4,13 +4,9 @@ namespace SNES { #include "algorithms.cpp" -//#include "opcodes.cpp" +#include "opcodes.cpp" #include "disassembler.cpp" -#include "serialization.cpp" - -#include "uop.cpp" - -/* + void SMPcore::op_step() { switch(opcode = op_readpc()) { case 0x00: return op_nop(); @@ -271,5 +267,5 @@ void SMPcore::op_step() { case 0xff: return op_wait(); } } -*/ + } diff --git a/libsnes/bsnes/snes/smp/core/core.hpp b/waterbox/libsnes/bsnes/snes/smp/core/core.hpp similarity index 98% rename from libsnes/bsnes/snes/smp/core/core.hpp rename to waterbox/libsnes/bsnes/snes/smp/core/core.hpp index 0b3da3f330..b7f30d9f9a 100644 --- a/libsnes/bsnes/snes/smp/core/core.hpp +++ b/waterbox/libsnes/bsnes/snes/smp/core/core.hpp @@ -9,11 +9,8 @@ struct SMPcore { regs_t regs; word_t dp, sp, rd, wr, bit, ya; - uint8 opcode; - - int uindex; + uint8 opcode; - void core_serialize(serializer&); string disassemble_opcode(uint16 addr); protected: diff --git a/libsnes/bsnes/snes/smp/core/disassembler.cpp b/waterbox/libsnes/bsnes/snes/smp/core/disassembler.cpp similarity index 100% rename from libsnes/bsnes/snes/smp/core/disassembler.cpp rename to waterbox/libsnes/bsnes/snes/smp/core/disassembler.cpp diff --git a/libsnes/bsnes/snes/smp/core/memory.hpp b/waterbox/libsnes/bsnes/snes/smp/core/memory.hpp similarity index 96% rename from libsnes/bsnes/snes/smp/core/memory.hpp rename to waterbox/libsnes/bsnes/snes/smp/core/memory.hpp index ac33f22232..973a2d6840 100644 --- a/libsnes/bsnes/snes/smp/core/memory.hpp +++ b/waterbox/libsnes/bsnes/snes/smp/core/memory.hpp @@ -20,10 +20,9 @@ alwaysinline uint8 op_readdp(uint8 addr) { alwaysinline void op_writedp(uint8 addr, uint8 data) { return op_write((regs.p.p << 8) + addr, data); -} - -alwaysinline void op_next() { - opcode = op_readpcfirst(); - uindex = -1; -} +} + +alwaysinline void op_next() { + opcode = op_readpcfirst(); +} diff --git a/libsnes/bsnes/snes/smp/core/opcodes.cpp b/waterbox/libsnes/bsnes/snes/smp/core/opcodes.cpp similarity index 98% rename from libsnes/bsnes/snes/smp/core/opcodes.cpp rename to waterbox/libsnes/bsnes/snes/smp/core/opcodes.cpp index 703dda93e3..95b9844f66 100644 --- a/libsnes/bsnes/snes/smp/core/opcodes.cpp +++ b/waterbox/libsnes/bsnes/snes/smp/core/opcodes.cpp @@ -540,10 +540,6 @@ void SMPcore::op_stw_dp() { void SMPcore::op_wait() { while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - regs.pc--; // repeat this opcode on next run - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } op_io(); op_io(); } diff --git a/libsnes/bsnes/snes/smp/core/registers.hpp b/waterbox/libsnes/bsnes/snes/smp/core/registers.hpp similarity index 100% rename from libsnes/bsnes/snes/smp/core/registers.hpp rename to waterbox/libsnes/bsnes/snes/smp/core/registers.hpp diff --git a/libsnes/bsnes/snes/smp/iplrom.cpp b/waterbox/libsnes/bsnes/snes/smp/iplrom.cpp similarity index 100% rename from libsnes/bsnes/snes/smp/iplrom.cpp rename to waterbox/libsnes/bsnes/snes/smp/iplrom.cpp diff --git a/libsnes/bsnes/snes/smp/memory/memory.cpp b/waterbox/libsnes/bsnes/snes/smp/memory/memory.cpp similarity index 98% rename from libsnes/bsnes/snes/smp/memory/memory.cpp rename to waterbox/libsnes/bsnes/snes/smp/memory/memory.cpp index 7a53df5df1..b46dc45802 100644 --- a/libsnes/bsnes/snes/smp/memory/memory.cpp +++ b/waterbox/libsnes/bsnes/snes/smp/memory/memory.cpp @@ -40,7 +40,7 @@ uint8 SMP::op_busread(uint16 addr) { case 0xf5: //CPUIO1 case 0xf6: //CPUIO2 case 0xf7: //CPUIO3 - synchronize_cpu_force(); + synchronize_cpu(); return cpu.port_read(addr); case 0xf8: //RAM0 @@ -99,7 +99,7 @@ void SMP::op_buswrite(uint16 addr, uint8 data) { if(data & 0x30) { //one-time clearing of APU port read registers, //emulated by simulating CPU writes of 0x00 - synchronize_cpu_force(); + synchronize_cpu(); if(data & 0x20) { cpu.port_write(2, 0x00); cpu.port_write(3, 0x00); @@ -143,7 +143,7 @@ void SMP::op_buswrite(uint16 addr, uint8 data) { case 0xf5: //CPUIO1 case 0xf6: //CPUIO2 case 0xf7: //CPUIO3 - synchronize_cpu_force(); + synchronize_cpu(); port_write(addr, data); break; diff --git a/libsnes/bsnes/snes/smp/memory/memory.hpp b/waterbox/libsnes/bsnes/snes/smp/memory/memory.hpp similarity index 100% rename from libsnes/bsnes/snes/smp/memory/memory.hpp rename to waterbox/libsnes/bsnes/snes/smp/memory/memory.hpp diff --git a/libsnes/bsnes/snes/smp/smp.cpp b/waterbox/libsnes/bsnes/snes/smp/smp.cpp similarity index 76% rename from libsnes/bsnes/snes/smp/smp.cpp rename to waterbox/libsnes/bsnes/snes/smp/smp.cpp index 92e4d72621..8d84b8f61c 100644 --- a/libsnes/bsnes/snes/smp/smp.cpp +++ b/waterbox/libsnes/bsnes/snes/smp/smp.cpp @@ -5,7 +5,6 @@ namespace SNES { SMP smp; -#include "serialization.cpp" #include "iplrom.cpp" #include "memory/memory.cpp" #include "timing/timing.cpp" @@ -16,23 +15,12 @@ void SMP::step(unsigned clocks) { } void SMP::synchronize_cpu() { - if(CPU::Threaded == true) { + if(CPU::Threaded == true) { if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); } else { while(clock >= 0) cpu.enter(); } -} - -void SMP::synchronize_cpu_force() { - if(CPU::Threaded == true) { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) - co_switch(cpu.thread); - else if(clock >= 0 && scheduler.sync == Scheduler::SynchronizeMode::All) - interface()->message("SMP had to advance nondeterministically!"); - } else { - while(clock >= 0) cpu.enter(); - } -} +} void SMP::synchronize_dsp() { if(DSP::Threaded == true) { @@ -45,17 +33,10 @@ void SMP::synchronize_dsp() { void SMP::Enter() { smp.enter(); } void SMP::enter() { - while(true) { - // see comment in timing.cpp - if(clock > +(768 * 24 * (int64)24000000)) - synchronize_cpu(); - - if(scheduler.sync == Scheduler::SynchronizeMode::CPU) { - synchronize_cpu(); // when in CPU sync mode, always switch back to CPU as soon as possible - } + while(true) { if(scheduler.sync == Scheduler::SynchronizeMode::All) { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } + } debugger.op_exec(regs.pc); if(interface()->wanttrace & TRACE_SMP_MASK) @@ -79,13 +60,9 @@ void SMP::power() { } void SMP::reset() { - create(Enter, system.apu_frequency()); - - regs.pc = 0xffc0; - // exact value doesn't matter much, so long as "fetch" is next - opcode = 0; // NOP - uindex = 1; // fetch phase + create(Enter, system.apu_frequency(), 16384); + regs.pc = 0xffc0; regs.a = 0x00; regs.x = 0x00; regs.y = 0x00; diff --git a/libsnes/bsnes/snes/smp/smp.hpp b/waterbox/libsnes/bsnes/snes/smp/smp.hpp similarity index 93% rename from libsnes/bsnes/snes/smp/smp.hpp rename to waterbox/libsnes/bsnes/snes/smp/smp.hpp index da1d56ec16..cbaa81affc 100644 --- a/libsnes/bsnes/snes/smp/smp.hpp +++ b/waterbox/libsnes/bsnes/snes/smp/smp.hpp @@ -4,8 +4,7 @@ struct SMP : public Processor, public SMPcore { enum : bool { Threaded = true }; alwaysinline void step(unsigned clocks); - alwaysinline void synchronize_cpu(); - alwaysinline void synchronize_cpu_force(); + alwaysinline void synchronize_cpu(); alwaysinline void synchronize_dsp(); uint8 port_read(uint2 port) const; @@ -15,7 +14,6 @@ struct SMP : public Processor, public SMPcore { void power(); void reset(); - void serialize(serializer&); SMP(); ~SMP(); void initialize(); diff --git a/libsnes/bsnes/snes/smp/timing/timing.cpp b/waterbox/libsnes/bsnes/snes/smp/timing/timing.cpp similarity index 68% rename from libsnes/bsnes/snes/smp/timing/timing.cpp rename to waterbox/libsnes/bsnes/snes/smp/timing/timing.cpp index 419d6c5c20..3709ba9887 100644 --- a/libsnes/bsnes/snes/smp/timing/timing.cpp +++ b/waterbox/libsnes/bsnes/snes/smp/timing/timing.cpp @@ -4,22 +4,12 @@ void SMP::add_clocks(unsigned clocks) { step(clocks); synchronize_dsp(); - #if defined(DEBUGGER) - #error -DDEBUGGER SMP runtosave() correctness not checked + #if defined(DEBUGGER) synchronize_cpu(); #else //forcefully sync S-SMP to S-CPU in case chips are not communicating - //sync if S-SMP is more than 24 samples ahead of S-CPU -/* -our new smp design guarantees that there is at most one required synchronize_cpu() per uop, -inside an op_busread() or op_buswrite(). this extra synchronize can cause problems if we -swap out of the SMP at the beginning of a uop with an add_clocks() call when there is an -important op_busread() / op_buswrite() later on. the SMP will need to finish that uop in -order to reach a savable state, but it might never get to do so until it's too late (ie, -scheduler.sync == Scheduler.SynchronizeMode::All). so we remove this call and instead -do catchup sync in the main Enter() loop. -*/ - //if(clock > +(768 * 24 * (int64)24000000)) synchronize_cpu(); + //sync if S-SMP is more than 24 samples ahead of S-CPU + if(clock > +(768 * 24 * (int64)24000000)) synchronize_cpu(); #endif } diff --git a/libsnes/bsnes/snes/smp/timing/timing.hpp b/waterbox/libsnes/bsnes/snes/smp/timing/timing.hpp similarity index 100% rename from libsnes/bsnes/snes/smp/timing/timing.hpp rename to waterbox/libsnes/bsnes/snes/smp/timing/timing.hpp diff --git a/libsnes/bsnes/snes/snes.hpp b/waterbox/libsnes/bsnes/snes/snes.hpp similarity index 74% rename from libsnes/bsnes/snes/snes.hpp rename to waterbox/libsnes/bsnes/snes/snes.hpp index 29861846e9..6ca7ae969b 100644 --- a/libsnes/bsnes/snes/snes.hpp +++ b/waterbox/libsnes/bsnes/snes/snes.hpp @@ -1,15 +1,9 @@ #ifndef SNES_HPP #define SNES_HPP +#include #include -namespace SNES { - namespace Info { - static const char Name[] = "bsnes"; - static const unsigned SerializerVersion = 23; - } -} - /* bsnes - SNES emulator author: byuu @@ -17,7 +11,7 @@ namespace SNES { project started: 2004-10-14 */ -#include +#include #if defined(GAMEBOY) #include @@ -29,18 +23,13 @@ namespace SNES { unsigned frequency; int64 clock; - inline void create(void (*entrypoint)(), unsigned frequency) { + inline void create(void (*entrypoint)(), unsigned frequency, int size) { if(thread) co_delete(thread); - thread = co_create(65536 * sizeof(void*), entrypoint); + thread = co_create(size * sizeof(void*), entrypoint); this->frequency = frequency; clock = 0; } - inline void serialize(serializer &s) { - s.integer(frequency); - s.integer(clock); - } - inline Processor() : thread(nullptr) { } @@ -66,7 +55,6 @@ namespace SNES { #include #include #include - #include #include #include diff --git a/libsnes/bsnes/snes/system/audio.cpp b/waterbox/libsnes/bsnes/snes/system/audio.cpp similarity index 100% rename from libsnes/bsnes/snes/system/audio.cpp rename to waterbox/libsnes/bsnes/snes/system/audio.cpp diff --git a/libsnes/bsnes/snes/system/audio.hpp b/waterbox/libsnes/bsnes/snes/system/audio.hpp similarity index 100% rename from libsnes/bsnes/snes/system/audio.hpp rename to waterbox/libsnes/bsnes/snes/system/audio.hpp diff --git a/libsnes/bsnes/snes/system/input.cpp b/waterbox/libsnes/bsnes/snes/system/input.cpp similarity index 76% rename from libsnes/bsnes/snes/system/input.cpp rename to waterbox/libsnes/bsnes/snes/system/input.cpp index 74461c4ef8..894de0e763 100644 --- a/libsnes/bsnes/snes/system/input.cpp +++ b/waterbox/libsnes/bsnes/snes/system/input.cpp @@ -23,28 +23,12 @@ void Input::connect(bool port, Input::Device id) { switch(port) { case Controller::Port1: config.controller_port1 = id; break; case Controller::Port2: config.controller_port2 = id; break; - } -} - -void Input::serialize(serializer &s) -{ - int p1, p2; - p1 = (int)config.controller_port1; - p2 = (int)config.controller_port2; - s.integer(p1); - s.integer(p2); - if(s.mode() == nall::serializer::Load) { - connect(Controller::Port1, (Device)p1); - connect(Controller::Port2, (Device)p2); - } - port1->serialize(s); - port2->serialize(s); -} - - -Input::Input() : port1(nullptr), port2(nullptr) { - connect(Controller::Port1, Input::Device::Joypad); - connect(Controller::Port2, Input::Device::Joypad); + } +} + +Input::Input() : port1(nullptr), port2(nullptr) { + connect(Controller::Port1, Input::Device::Joypad); + connect(Controller::Port2, Input::Device::Joypad); } Input::~Input() { diff --git a/libsnes/bsnes/snes/system/input.hpp b/waterbox/libsnes/bsnes/snes/system/input.hpp similarity index 94% rename from libsnes/bsnes/snes/system/input.hpp rename to waterbox/libsnes/bsnes/snes/system/input.hpp index 9d7686161b..7a6bd9e705 100644 --- a/libsnes/bsnes/snes/system/input.hpp +++ b/waterbox/libsnes/bsnes/snes/system/input.hpp @@ -28,13 +28,12 @@ struct Input { X = 0, Y = 1, Trigger = 2, Start = 3, }; - Controller *port1; - Controller *port2; - - void serialize(serializer &s); - void connect(bool port, Input::Device id); - Input(); - ~Input(); + Controller *port1; + Controller *port2; + + void connect(bool port, Input::Device id); + Input(); + ~Input(); }; extern Input input; diff --git a/libsnes/bsnes/snes/system/system.cpp b/waterbox/libsnes/bsnes/snes/system/system.cpp similarity index 99% rename from libsnes/bsnes/snes/system/system.cpp rename to waterbox/libsnes/bsnes/snes/system/system.cpp index 746e7808de..8836b03fd7 100644 --- a/libsnes/bsnes/snes/system/system.cpp +++ b/waterbox/libsnes/bsnes/snes/system/system.cpp @@ -12,7 +12,6 @@ System system; #include "video.cpp" #include "audio.cpp" #include "input.cpp" -#include "serialization.cpp" void System::run() { scheduler.sync = Scheduler::SynchronizeMode::None; @@ -122,9 +121,6 @@ void System::load() { if(cartridge.has_obc1()) obc1.load(); if(cartridge.has_msu1()) msu1.load(); if(cartridge.has_link()) link.load(); - - serialize_init(); - cheat.init(); } void System::unload() { @@ -148,13 +144,13 @@ void System::unload() { if(cartridge.has_obc1()) obc1.unload(); if(cartridge.has_msu1()) msu1.unload(); if(cartridge.has_link()) link.unload(); -} - -void System::power() { - random.seed((unsigned)interface()->randomSeed()); - - region = config.region; - expansion = config.expansion_port; +} + +void System::power() { + random.seed((unsigned)interface()->randomSeed()); + + region = config.region; + expansion = config.expansion_port; if(region.value == Region::Autodetect) { region = (cartridge.region() == Cartridge::Region::NTSC ? Region::NTSC : Region::PAL); } diff --git a/libsnes/bsnes/snes/system/system.hpp b/waterbox/libsnes/bsnes/snes/system/system.hpp similarity index 82% rename from libsnes/bsnes/snes/system/system.hpp rename to waterbox/libsnes/bsnes/snes/system/system.hpp index 56eb37a152..299fb88129 100644 --- a/libsnes/bsnes/snes/system/system.hpp +++ b/waterbox/libsnes/bsnes/snes/system/system.hpp @@ -22,20 +22,12 @@ struct System : property { readonly expansion; readonly cpu_frequency; readonly apu_frequency; - readonly serialize_size; - - serializer serialize(); - bool unserialize(serializer&); System(); private: void runthreadtosave(); - void serialize(serializer&); - void serialize_all(serializer&); - void serialize_init(); - friend class Cartridge; friend class Video; friend class Audio; diff --git a/libsnes/bsnes/snes/system/video.cpp b/waterbox/libsnes/bsnes/snes/system/video.cpp similarity index 68% rename from libsnes/bsnes/snes/system/video.cpp rename to waterbox/libsnes/bsnes/snes/system/video.cpp index 124949a520..dd817c88da 100644 --- a/libsnes/bsnes/snes/system/video.cpp +++ b/waterbox/libsnes/bsnes/snes/system/video.cpp @@ -1,151 +1,103 @@ -#ifdef SYSTEM_CPP - -Video video; - -unsigned Video::palette30(unsigned color) { - unsigned l = (color >> 15) & 15; - unsigned b = (color >> 10) & 31; - unsigned g = (color >> 5) & 31; - unsigned r = (color >> 0) & 31; - - double L = (1.0 + l) / 16.0; - if(l == 0) L *= 0.5; - unsigned R = L * ((r << 5) + (r << 0)); - unsigned G = L * ((g << 5) + (g << 0)); - unsigned B = L * ((b << 5) + (b << 0)); - - return (R << 20) + (G << 10) + (B << 0); -} - -void Video::generate(Format format) { - for(unsigned n = 0; n < (1 << 19); n++) palette[n] = palette30(n); - - if(format == Format::RGB24) { - for(unsigned n = 0; n < (1 << 19); n++) { - unsigned color = palette[n]; - palette[n] = ((color >> 6) & 0xff0000) + ((color >> 4) & 0x00ff00) + ((color >> 2) & 0x0000ff); - } - } - - if(format == Format::RGB16) { - for(unsigned n = 0; n < (1 << 19); n++) { - unsigned color = palette[n]; - palette[n] = ((color >> 14) & 0xf800) + ((color >> 9) & 0x07e0) + ((color >> 5) & 0x001f); - } - } - - if(format == Format::RGB15) { - for(unsigned n = 0; n < (1 << 19); n++) { - unsigned color = palette[n]; - palette[n] = ((color >> 15) & 0x7c00) + ((color >> 10) & 0x03e0) + ((color >> 5) & 0x001f); - } - } -} - -Video::Video() { - palette = new unsigned[1 << 19]; -} - -Video::~Video() { - delete[] palette; -} - -//internal - -const uint8_t Video::cursor[15 * 15] = { - 0,0,0,0,0,0,1,1,1,0,0,0,0,0,0, - 0,0,0,0,1,1,2,2,2,1,1,0,0,0,0, - 0,0,0,1,2,2,1,2,1,2,2,1,0,0,0, - 0,0,1,2,1,1,0,1,0,1,1,2,1,0,0, - 0,1,2,1,0,0,0,1,0,0,0,1,2,1,0, - 0,1,2,1,0,0,1,2,1,0,0,1,2,1,0, - 1,2,1,0,0,1,1,2,1,1,0,0,1,2,1, - 1,2,2,1,1,2,2,2,2,2,1,1,2,2,1, - 1,2,1,0,0,1,1,2,1,1,0,0,1,2,1, - 0,1,2,1,0,0,1,2,1,0,0,1,2,1,0, - 0,1,2,1,0,0,0,1,0,0,0,1,2,1,0, - 0,0,1,2,1,1,0,1,0,1,1,2,1,0,0, - 0,0,0,1,2,2,1,2,1,2,2,1,0,0,0, - 0,0,0,0,1,1,2,2,2,1,1,0,0,0,0, - 0,0,0,0,0,0,1,1,1,0,0,0,0,0,0, -}; - -void Video::draw_cursor(uint16_t color, int x, int y) { - uint32_t *data = (uint32_t*)ppu.output; - if(ppu.interlace() && ppu.field()) data += 512; - - for(int cy = 0; cy < 15; cy++) { - int vy = y + cy - 7; - if(vy <= 0 || vy >= 240) continue; //do not draw offscreen - - bool hires = (line_width[vy] == 512); - for(int cx = 0; cx < 15; cx++) { - int vx = x + cx - 7; - if(vx < 0 || vx >= 256) continue; //do not draw offscreen - uint8_t pixel = cursor[cy * 15 + cx]; - if(pixel == 0) continue; - uint32_t pixelcolor = (15 << 15) | ((pixel == 1) ? 0 : color); - - if(hires == false) { - *((uint32_t*)data + vy * 1024 + vx) = pixelcolor; - } else { - *((uint32_t*)data + vy * 1024 + vx * 2 + 0) = pixelcolor; - *((uint32_t*)data + vy * 1024 + vx * 2 + 1) = pixelcolor; - } - } - } -} - -void Video::update() { - switch(config.controller_port2) { - case Input::Device::SuperScope: - if(dynamic_cast(input.port2)) { - SuperScope &device = (SuperScope&)*input.port2; - draw_cursor(0x7c00, device.x, device.y); - } - break; - case Input::Device::Justifier: - case Input::Device::Justifiers: - if(dynamic_cast(input.port2)) { - Justifier &device = (Justifier&)*input.port2; - draw_cursor(0x001f, device.player1.x, device.player1.y); - if(device.chained == false) break; - draw_cursor(0x02e0, device.player2.x, device.player2.y); - } - break; - } - - uint32_t *data = (uint32_t*)ppu.output; - if(ppu.interlace() && ppu.field()) data += 512; - - if(hires) { - //normalize line widths - for(unsigned y = 0; y < 240; y++) { - if(line_width[y] == 512) continue; - uint32_t *buffer = data + y * 1024; - for(signed x = 255; x >= 0; x--) { - buffer[(x * 2) + 0] = buffer[(x * 2) + 1] = buffer[x]; - } - } - } - - interface()->videoRefresh(ppu.surface, hires, ppu.interlace(), ppu.overscan()); - - hires = false; -} - -void Video::scanline() { - unsigned y = cpu.vcounter(); - if(y >= 240) return; - - hires |= ppu.hires(); - unsigned width = (ppu.hires() == false ? 256 : 512); - line_width[y] = width; -} - -void Video::init() { - hires = false; - for(auto &n : line_width) n = 256; -} - -#endif +#ifdef SYSTEM_CPP + +Video video; + +//internal + +const uint8_t Video::cursor[15 * 15] = { + 0,0,0,0,0,0,1,1,1,0,0,0,0,0,0, + 0,0,0,0,1,1,2,2,2,1,1,0,0,0,0, + 0,0,0,1,2,2,1,2,1,2,2,1,0,0,0, + 0,0,1,2,1,1,0,1,0,1,1,2,1,0,0, + 0,1,2,1,0,0,0,1,0,0,0,1,2,1,0, + 0,1,2,1,0,0,1,2,1,0,0,1,2,1,0, + 1,2,1,0,0,1,1,2,1,1,0,0,1,2,1, + 1,2,2,1,1,2,2,2,2,2,1,1,2,2,1, + 1,2,1,0,0,1,1,2,1,1,0,0,1,2,1, + 0,1,2,1,0,0,1,2,1,0,0,1,2,1,0, + 0,1,2,1,0,0,0,1,0,0,0,1,2,1,0, + 0,0,1,2,1,1,0,1,0,1,1,2,1,0,0, + 0,0,0,1,2,2,1,2,1,2,2,1,0,0,0, + 0,0,0,0,1,1,2,2,2,1,1,0,0,0,0, + 0,0,0,0,0,0,1,1,1,0,0,0,0,0,0, +}; + +void Video::draw_cursor(uint16_t color, int x, int y) { + uint32_t *data = (uint32_t*)ppu.output; + if(ppu.interlace() && ppu.field()) data += 512; + + for(int cy = 0; cy < 15; cy++) { + int vy = y + cy - 7; + if(vy <= 0 || vy >= 240) continue; //do not draw offscreen + + bool hires = (line_width[vy] == 512); + for(int cx = 0; cx < 15; cx++) { + int vx = x + cx - 7; + if(vx < 0 || vx >= 256) continue; //do not draw offscreen + uint8_t pixel = cursor[cy * 15 + cx]; + if(pixel == 0) continue; + uint32_t pixelcolor = (15 << 15) | ((pixel == 1) ? 0 : color); + + if(hires == false) { + *((uint32_t*)data + vy * 1024 + vx) = pixelcolor; + } else { + *((uint32_t*)data + vy * 1024 + vx * 2 + 0) = pixelcolor; + *((uint32_t*)data + vy * 1024 + vx * 2 + 1) = pixelcolor; + } + } + } +} + +void Video::update() { + switch(config.controller_port2) { + case Input::Device::SuperScope: + if(dynamic_cast(input.port2)) { + SuperScope &device = (SuperScope&)*input.port2; + draw_cursor(0x7c00, device.x, device.y); + } + break; + case Input::Device::Justifier: + case Input::Device::Justifiers: + if(dynamic_cast(input.port2)) { + Justifier &device = (Justifier&)*input.port2; + draw_cursor(0x001f, device.player1.x, device.player1.y); + if(device.chained == false) break; + draw_cursor(0x02e0, device.player2.x, device.player2.y); + } + break; + } + + uint32_t *data = (uint32_t*)ppu.output; + if(ppu.interlace() && ppu.field()) data += 512; + + if(hires) { + //normalize line widths + for(unsigned y = 0; y < 240; y++) { + if(line_width[y] == 512) continue; + uint32_t *buffer = data + y * 1024; + for(signed x = 255; x >= 0; x--) { + buffer[(x * 2) + 0] = buffer[(x * 2) + 1] = buffer[x]; + } + } + } + + interface()->videoRefresh(ppu.surface, hires, ppu.interlace(), ppu.overscan()); + + hires = false; +} + +void Video::scanline() { + unsigned y = cpu.vcounter(); + if(y >= 240) return; + + hires |= ppu.hires(); + unsigned width = (ppu.hires() == false ? 256 : 512); + line_width[y] = width; +} + +void Video::init() { + hires = false; + for(auto &n : line_width) n = 256; +} + +#endif diff --git a/libsnes/bsnes/snes/system/video.hpp b/waterbox/libsnes/bsnes/snes/system/video.hpp similarity index 73% rename from libsnes/bsnes/snes/system/video.hpp rename to waterbox/libsnes/bsnes/snes/system/video.hpp index 6fbeace0e0..777176f2b5 100644 --- a/libsnes/bsnes/snes/system/video.hpp +++ b/waterbox/libsnes/bsnes/snes/system/video.hpp @@ -1,25 +1,19 @@ -struct Video { - enum class Format : unsigned { RGB30, RGB24, RGB16, RGB15 }; - unsigned *palette; - - unsigned palette30(unsigned color); - void generate(Format format); - Video(); - ~Video(); - - void update(); - -private: - bool hires; - unsigned line_width[240]; - - void scanline(); - void init(); - - static const uint8_t cursor[15 * 15]; - void draw_cursor(uint16_t color, int x, int y); - - friend class System; -}; - -extern Video video; +struct Video { + enum class Format : unsigned { RGB30, RGB24, RGB16, RGB15 }; +public: + void update(); + +private: + bool hires; + unsigned line_width[240]; + + void scanline(); + void init(); + + static const uint8_t cursor[15 * 15]; + void draw_cursor(uint16_t color, int x, int y); + + friend class System; +}; + +extern Video video; diff --git a/libsnes/bsnes/target-libsnes/libsnes.cpp b/waterbox/libsnes/bsnes/target-libsnes/libsnes.cpp similarity index 91% rename from libsnes/bsnes/target-libsnes/libsnes.cpp rename to waterbox/libsnes/bsnes/target-libsnes/libsnes.cpp index 9e13608d53..2de426e555 100644 --- a/libsnes/bsnes/target-libsnes/libsnes.cpp +++ b/waterbox/libsnes/bsnes/target-libsnes/libsnes.cpp @@ -6,8 +6,6 @@ #include -#include - using namespace nall; struct Interface : public SNES::Interface { @@ -132,26 +130,25 @@ struct Interface : public SNES::Interface { ptrace(0), cart(nullptr, 0) { - buffer = new uint32_t[512 * 480]; - palette = new uint32_t[16 * 32768]; + buffer = (uint32_t*)alloc_invisible(512 * 480 * sizeof(uint32_t)); + palette = (uint32_t*)alloc_invisible(16 * 32768 * sizeof(uint32_t)); memset(&cdlInfo,0,sizeof(cdlInfo)); } ~Interface() { - delete[] buffer; - delete[] palette; + abort(); } }; -void pwrap_init(); +void pwrap_init(); Interface *iface = nullptr; namespace SNES { -SNES::Interface *interface() -{ - if(iface != nullptr) return iface; - iface = new ::Interface(); - pwrap_init(); - return iface; +SNES::Interface *interface() +{ + if(iface != nullptr) return iface; + iface = new ::Interface(); + pwrap_init(); + return iface; } } @@ -216,9 +213,9 @@ void snes_set_cartridge_basename(const char *basename) { } template inline void reconstruct(T* t) { - t->~T(); + /*t->~T(); memset(t,0,sizeof(*t)); - new(t) T(); + new(t) T();*/ } void snes_init(void) { @@ -281,77 +278,6 @@ void snes_run(void) { SNES::system.run(); } -unsigned snes_serialize_size(void) { - return SNES::system.serialize_size(); -} - -bool snes_serialize(uint8_t *data, unsigned size) { - SNES::system.runtosave(); - serializer s = SNES::system.serialize(); - if(s.size() > size) return false; - memcpy(data, s.data(), s.size()); - return true; -} - -bool snes_unserialize(const uint8_t *data, unsigned size) { - serializer s(data, size); - return SNES::system.unserialize(s); -} - -struct CheatList { - bool enable; - string code; - CheatList() : enable(false) {} -}; - -static linear_vector cheatList; - -void snes_cheat_reset(void) { - cheatList.reset(); - GameBoy::cheat.reset(); - GameBoy::cheat.synchronize(); - SNES::cheat.reset(); - SNES::cheat.synchronize(); -} - -void snes_cheat_set(unsigned index, bool enable, const char *code) { - cheatList[index].enable = enable; - cheatList[index].code = code; - lstring list; - for(unsigned n = 0; n < cheatList.size(); n++) { - if(cheatList[n].enable) list.append(cheatList[n].code); - } - - if(SNES::cartridge.mode() == SNES::Cartridge::Mode::SuperGameBoy) { - GameBoy::cheat.reset(); - for(auto &code : list) { - lstring codelist; - codelist.split("+", code); - for(auto &part : codelist) { - unsigned addr, data, comp; - if(GameBoy::Cheat::decode(part, addr, data, comp)) { - GameBoy::cheat.append({ addr, data, comp }); - } - } - } - GameBoy::cheat.synchronize(); - return; - } - - SNES::cheat.reset(); - for(auto &code : list) { - lstring codelist; - codelist.split("+", code); - for(auto &part : codelist) { - unsigned addr, data; - if(SNES::Cheat::decode(part, addr, data)) { - SNES::cheat.append({ addr, data }); - } - } - } - SNES::cheat.synchronize(); -} - //zero 21-sep-2012 void snes_set_scanlineStart(snes_scanlineStart_t cb) { @@ -466,7 +392,6 @@ int snes_peek_logical_register(int reg) bool snes_load_cartridge_normal( const char *rom_xml, const uint8_t *rom_data, unsigned rom_size ) { - snes_cheat_reset(); if(rom_data) SNES::cartridge.rom.copy(rom_data, rom_size); iface->cart = SnesCartridge(rom_data, rom_size); string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : iface->cart.markup; @@ -479,7 +404,6 @@ bool snes_load_cartridge_bsx_slotted( const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size ) { - snes_cheat_reset(); if(rom_data) SNES::cartridge.rom.copy(rom_data, rom_size); iface->cart = SnesCartridge(rom_data, rom_size); string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : iface->cart.markup; @@ -494,7 +418,6 @@ bool snes_load_cartridge_bsx( const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size ) { - snes_cheat_reset(); if(rom_data) SNES::cartridge.rom.copy(rom_data, rom_size); iface->cart = SnesCartridge(rom_data, rom_size); string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : iface->cart.markup; @@ -510,7 +433,6 @@ bool snes_load_cartridge_sufami_turbo( const char *sta_xml, const uint8_t *sta_data, unsigned sta_size, const char *stb_xml, const uint8_t *stb_data, unsigned stb_size ) { - snes_cheat_reset(); if(rom_data) SNES::cartridge.rom.copy(rom_data, rom_size); iface->cart = SnesCartridge(rom_data, rom_size); string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : iface->cart.markup; @@ -527,7 +449,6 @@ bool snes_load_cartridge_super_game_boy( const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, const char *dmg_xml, const uint8_t *dmg_data, unsigned dmg_size ) { - snes_cheat_reset(); if(rom_data) SNES::cartridge.rom.copy(rom_data, rom_size); iface->cart = SnesCartridge(rom_data, rom_size); string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : iface->cart.markup; diff --git a/libsnes/bsnes/target-libsnes/libsnes.hpp b/waterbox/libsnes/bsnes/target-libsnes/libsnes.hpp similarity index 97% rename from libsnes/bsnes/target-libsnes/libsnes.hpp rename to waterbox/libsnes/bsnes/target-libsnes/libsnes.hpp index 4d22dea1fc..411488bfce 100644 --- a/libsnes/bsnes/target-libsnes/libsnes.hpp +++ b/waterbox/libsnes/bsnes/target-libsnes/libsnes.hpp @@ -114,13 +114,6 @@ void snes_power(void); void snes_reset(void); void snes_run(void); -unsigned snes_serialize_size(void); -bool snes_serialize(uint8_t *data, unsigned size); -bool snes_unserialize(const uint8_t *data, unsigned size); - -void snes_cheat_reset(void); -void snes_cheat_set(unsigned index, bool enable, const char *code); - bool snes_load_cartridge_normal( const char *rom_xml, const uint8_t *rom_data, unsigned rom_size ); diff --git a/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp b/waterbox/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp similarity index 90% rename from libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp rename to waterbox/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp index 302dcde6f5..ed230e6cb8 100644 --- a/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp +++ b/waterbox/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp @@ -1,637 +1,670 @@ -//types of messages: -//cmd: frontend->core: "command to core" a command from the frontend which causes emulation to proceed. when sending a command, the frontend should wait for an eMessage_BRK_Complete before proceeding, although a debugger might proceed after any BRK -//query: frontend->core: "query to core" a query from the frontend which can (and should) be satisfied immediately by the core but which does not result in emulation processes (notably, nothing resembling a CMD and nothing which can trigger a BRK) -//sig: core->frontend: "core signal" a synchronous operation called from the emulation process which the frontend should handle immediately without issuing any calls into the core -//brk: core->frontend: "core break" the emulation process has suspended. the frontend is free to do whatever it wishes. - -#include - -#define LIBSNES_IMPORT -#include "snes/snes.hpp" -#include "libsnes.hpp" - -#include - -#include -#include -#include - -#include -#include - -extern SNES::Interface *iface; - -typedef uint8 u8; -typedef uint16 u16; -typedef uint64 u64; -typedef uint32 u32; - -typedef int32 s32; - -typedef void(*Action)(); - -enum eMessage : int32 -{ - eMessage_NotSet, - - eMessage_Resume, - - eMessage_QUERY_FIRST, - eMessage_QUERY_get_memory_size, - eMessage_QUERY_peek, - eMessage_QUERY_poke, - eMessage_QUERY_serialize_size, - eMessage_QUERY_set_color_lut, - eMessage_QUERY_GetMemoryIdName, - eMessage_QUERY_state_hook_exec, - eMessage_QUERY_state_hook_read, - eMessage_QUERY_state_hook_write, - eMessage_QUERY_state_hook_nmi, - eMessage_QUERY_state_hook_irq, - eMessage_QUERY_enable_trace, - eMessage_QUERY_enable_scanline, - eMessage_QUERY_enable_audio, - eMessage_QUERY_set_layer_enable, - eMessage_QUERY_set_backdropColor, - eMessage_QUERY_peek_logical_register, - eMessage_QUERY_peek_cpu_regs, - eMessage_QUERY_set_cdl, - eMessage_QUERY_LAST, - - eMessage_CMD_FIRST, - eMessage_CMD_init, - eMessage_CMD_power, - eMessage_CMD_reset, - eMessage_CMD_run, - eMessage_CMD_serialize, - eMessage_CMD_unserialize, - eMessage_CMD_load_cartridge_normal, - eMessage_CMD_load_cartridge_sgb, - eMessage_CMD_term, - eMessage_CMD_unload_cartridge, - eMessage_CMD_LAST, - - eMessage_SIG_video_refresh, - eMessage_SIG_input_poll, - eMessage_SIG_input_state, - eMessage_SIG_input_notify, - eMessage_SIG_audio_flush, - eMessage_SIG_path_request, - eMessage_SIG_trace_callback, - eMessage_SIG_allocSharedMemory, - eMessage_SIG_freeSharedMemory, - - eMessage_BRK_Complete, - eMessage_BRK_hook_exec, - eMessage_BRK_hook_read, - eMessage_BRK_hook_write, - eMessage_BRK_hook_nmi, - eMessage_BRK_hook_irq, - eMessage_BRK_scanlineStart, -}; - -enum eStatus : int32 -{ - eStatus_Idle, - eStatus_CMD, - eStatus_BRK -}; - - -//watch it! the size of this struct is important! -#ifdef _MSC_VER -#pragma pack(push,1) -#endif -struct CPURegsComm { - u32 pc; - u16 a, x, y, z, s, d, vector; //7x - u8 p, nothing; - u32 aa, rd; - u8 sp, dp, db, mdr; -} -#ifndef _MSC_VER -__attribute__((__packed__)) -#endif -; -#ifdef _MSC_VER -#pragma pack(pop) -#endif - -struct LayerEnablesComm -{ - u8 BG1_Prio0, BG1_Prio1; - u8 BG2_Prio0, BG2_Prio1; - u8 BG3_Prio0, BG3_Prio1; - u8 BG4_Prio0, BG4_Prio1; - u8 Obj_Prio0, Obj_Prio1, Obj_Prio2, Obj_Prio3; -}; - -//TODO: do any of these need to be volatile? -struct CommStruct -{ - //the cmd being executed - eMessage cmd; - - //the status of the core - eStatus status; - - //the SIG or BRK that the core is halted in - eMessage reason; - - //flexible in/out parameters - //these are all "overloaded" a little so it isn't clear what's used for what in for any particular message.. - //but I think it will beat having to have some kind of extremely verbose custom layouts for every message - char* str; - void* ptr; - uint32 id, addr, value, size; - int32 port, device, index, slot; - int32 width, height; - int32 scanline; - SNES::Input::Device inports[2]; - - //always used in pairs - void* buf[3]; - int32 buf_size[3]; - - int64 cdl_ptr[4]; - int32 cdl_size[4]; - - CPURegsComm cpuregs; - LayerEnablesComm layerEnables; - - //static configuration-type information which can be grabbed off the core at any time without even needing a QUERY command - uint32 region; - uint32 mapper; - - //=========================================================== - - //private stuff - void* privbuf[2]; //TODO remember to tidy this.. - - void CopyBuffer(int id, void* ptr, int32 size) - { - if (privbuf[id]) free(privbuf[id]); - buf[id] = privbuf[id] = malloc(size); - memcpy(buf[id], ptr, size); - buf_size[id] = size; - } - - void SetBuffer(int id, void* ptr, int32 size) - { - if (privbuf[id]) free(privbuf[id]); - privbuf[id] = nullptr; - buf[id] = ptr; - buf_size[id] = size; - } - - -} comm; - -//coroutines -cothread_t co_control, co_emu, co_emu_suspended; - -//internal state -bool audio_en = false; -static const int AUDIOBUFFER_SIZE = 44100 * 2; -uint16_t audiobuffer[AUDIOBUFFER_SIZE]; -int audiobuffer_idx = 0; -Action CMD_cb; - -void BREAK(eMessage msg) -{ - comm.status = eStatus_BRK; - comm.reason = msg; - co_emu_suspended = co_active(); - co_switch(co_control); - comm.status = eStatus_CMD; -} - -void snes_video_refresh(const uint32_t *data, unsigned width, unsigned height) -{ - comm.width = width; - comm.height = height; - comm.ptr = (void*)data; - - BREAK(eMessage_SIG_video_refresh); -} - -void do_SIG_audio_flush() -{ - comm.ptr = audiobuffer; - comm.size = audiobuffer_idx; - BREAK(eMessage_SIG_audio_flush); - audiobuffer_idx = 0; -} - -//this is the raw callback from the emulator internals when a new audio sample is available -void snes_audio_sample(uint16_t left, uint16_t right) -{ - if(!audio_en) return; - - //if theres no room in the audio buffer, we need to send a flush signal - if (audiobuffer_idx == AUDIOBUFFER_SIZE) - { - do_SIG_audio_flush(); - } - - audiobuffer[audiobuffer_idx++] = left; - audiobuffer[audiobuffer_idx++] = right; -} - -void snes_input_poll(void) -{ - BREAK(eMessage_SIG_input_poll); -} - -int16_t snes_input_state(unsigned port, unsigned device, unsigned index, unsigned id) -{ - comm.port = port; - comm.device = device; - comm.index = index; - comm.id = id; - BREAK(eMessage_SIG_input_state); - return comm.value; -} -void snes_input_notify(int index) -{ - comm.index = index; - BREAK(eMessage_SIG_input_notify); -} - -void snes_trace(uint32_t which, const char *msg) -{ - comm.value = which; - comm.str = (char*) msg; - BREAK(eMessage_SIG_trace_callback); -} - -const char* snes_path_request(int slot, const char* hint) -{ - comm.slot = slot; - comm.str= (char *)hint; - BREAK(eMessage_SIG_path_request); - return (const char*)comm.buf[0]; -} - -void snes_scanlineStart(int line) -{ - comm.scanline = line; - BREAK(eMessage_BRK_scanlineStart); -} - -void* snes_allocSharedMemory(const char* memtype, size_t amt) -{ - //its important that this happen before the message marshaling because allocation/free attempts can happen before the marshaling is setup (or at shutdown time, in case of errors?) - //if(!running) return NULL; - - comm.str = (char*)memtype; - comm.size = amt; - - BREAK(eMessage_SIG_allocSharedMemory); - - return comm.ptr; -} - -void snes_freeSharedMemory(void* ptr) -{ - //its important that this happen before the message marshaling because allocation/free attempts can happen before the marshaling is setup (or at shutdown time, in case of errors?) - //if(!running) return; - - if (!ptr) return; - - comm.ptr = ptr; - - BREAK(eMessage_SIG_freeSharedMemory); -} - -static void debug_op_exec(uint24 addr) -{ - comm.addr = addr; - BREAK(eMessage_BRK_hook_exec); -} - -static void debug_op_read(uint24 addr) -{ - comm.addr = addr; - BREAK(eMessage_BRK_hook_read); -} - -static void debug_op_write(uint24 addr, uint8 value) -{ - comm.addr = addr; - comm.value = value; - BREAK(eMessage_BRK_hook_write); -} - -static void debug_op_nmi() -{ - BREAK(eMessage_BRK_hook_nmi); -} - -static void debug_op_irq() -{ - BREAK(eMessage_BRK_hook_irq); -} - -void pwrap_init() -{ - //bsnes's interface initialization calls into this after initializing itself, so we can get a chance to mod it for pwrap functionalities - snes_set_video_refresh(snes_video_refresh); - snes_set_audio_sample(snes_audio_sample); - snes_set_input_poll(snes_input_poll); - snes_set_input_state(snes_input_state); - snes_set_input_notify(snes_input_notify); - snes_set_path_request(snes_path_request); - snes_set_allocSharedMemory(snes_allocSharedMemory); - snes_set_freeSharedMemory(snes_freeSharedMemory); -} - -static void Analyze() -{ - //gather some "static" type information, so we dont have to poll annoyingly for it later - comm.mapper = snes_get_mapper(); - comm.region = snes_get_region(); -} - -void CMD_LoadCartridgeNormal() -{ - const char* xml = (const char*)comm.buf[0]; - if(!xml[0]) xml = nullptr; - bool ret = snes_load_cartridge_normal(xml, (const uint8_t*)comm.buf[1], comm.buf_size[1]); - comm.value = ret?1:0; - - if(ret) - Analyze(); -} - -void CMD_LoadCartridgeSGB() -{ - bool ret = snes_load_cartridge_super_game_boy((const char*)comm.buf[0], (const u8*)comm.buf[1], comm.buf_size[1], nullptr, (const u8*)comm.buf[2], comm.buf_size[2]); - comm.value = ret ? 1 : 0; - - if(ret) - Analyze(); -} - -void CMD_init() -{ - snes_init(); - +//types of messages: +//cmd: frontend->core: "command to core" a command from the frontend which causes emulation to proceed. when sending a command, the frontend should wait for an eMessage_BRK_Complete before proceeding, although a debugger might proceed after any BRK +//query: frontend->core: "query to core" a query from the frontend which can (and should) be satisfied immediately by the core but which does not result in emulation processes (notably, nothing resembling a CMD and nothing which can trigger a BRK) +//sig: core->frontend: "core signal" a synchronous operation called from the emulation process which the frontend should handle immediately without issuing any calls into the core +//brk: core->frontend: "core break" the emulation process has suspended. the frontend is free to do whatever it wishes. + +#define LIBSNES_IMPORT +#include "snes/snes.hpp" +#include "libsnes.hpp" +#include + +#include + +#include +#include +#include + +#include +#include + +extern SNES::Interface *iface; + +typedef uint8 u8; +typedef uint16 u16; +typedef uint64 u64; +typedef uint32 u32; + +typedef int32 s32; + +typedef void(*Action)(); + +enum eMessage : int32 +{ + eMessage_NotSet, + + eMessage_Resume, + + eMessage_QUERY_FIRST, + eMessage_QUERY_get_memory_size, + eMessage_QUERY_peek, + eMessage_QUERY_poke, + eMessage_QUERY_serialize_size, + eMessage_QUERY_set_color_lut, + eMessage_QUERY_GetMemoryIdName, + eMessage_QUERY_state_hook_exec, + eMessage_QUERY_state_hook_read, + eMessage_QUERY_state_hook_write, + eMessage_QUERY_state_hook_nmi, + eMessage_QUERY_state_hook_irq, + eMessage_QUERY_enable_trace, + eMessage_QUERY_enable_scanline, + eMessage_QUERY_enable_audio, + eMessage_QUERY_set_layer_enable, + eMessage_QUERY_set_backdropColor, + eMessage_QUERY_peek_logical_register, + eMessage_QUERY_peek_cpu_regs, + eMessage_QUERY_set_cdl, + eMessage_QUERY_LAST, + + eMessage_CMD_FIRST, + eMessage_CMD_init, + eMessage_CMD_power, + eMessage_CMD_reset, + eMessage_CMD_run, + eMessage_CMD_serialize, + eMessage_CMD_unserialize, + eMessage_CMD_load_cartridge_normal, + eMessage_CMD_load_cartridge_sgb, + eMessage_CMD_term, + eMessage_CMD_unload_cartridge, + eMessage_CMD_LAST, + + eMessage_SIG_video_refresh, + eMessage_SIG_input_poll, + eMessage_SIG_input_state, + eMessage_SIG_input_notify, + eMessage_SIG_audio_flush, + eMessage_SIG_path_request, + eMessage_SIG_trace_callback, + eMessage_SIG_allocSharedMemory, + eMessage_SIG_freeSharedMemory, + + eMessage_BRK_Complete, + eMessage_BRK_hook_exec, + eMessage_BRK_hook_read, + eMessage_BRK_hook_write, + eMessage_BRK_hook_nmi, + eMessage_BRK_hook_irq, + eMessage_BRK_scanlineStart, +}; + +enum eStatus : int32 +{ + eStatus_Idle, + eStatus_CMD, + eStatus_BRK +}; + + +//watch it! the size of this struct is important! +#ifdef _MSC_VER +#pragma pack(push,1) +#endif +struct CPURegsComm { + u32 pc; + u16 a, x, y, z, s, d, vector; //7x + u8 p, nothing; + u32 aa, rd; + u8 sp, dp, db, mdr; +} +#ifndef _MSC_VER +__attribute__((__packed__)) +#endif +; +#ifdef _MSC_VER +#pragma pack(pop) +#endif + +struct LayerEnablesComm +{ + u8 BG1_Prio0, BG1_Prio1; + u8 BG2_Prio0, BG2_Prio1; + u8 BG3_Prio0, BG3_Prio1; + u8 BG4_Prio0, BG4_Prio1; + u8 Obj_Prio0, Obj_Prio1, Obj_Prio2, Obj_Prio3; +}; + +//TODO: do any of these need to be volatile? +struct CommStruct +{ + //the cmd being executed + eMessage cmd; + + //the status of the core + eStatus status; + + //the SIG or BRK that the core is halted in + eMessage reason; + + int32 padding1; + + //flexible in/out parameters + //these are all "overloaded" a little so it isn't clear what's used for what in for any particular message.. + //but I think it will beat having to have some kind of extremely verbose custom layouts for every message + char* str; + void* ptr; + uint32 id, addr, value, size; + int32 port, device, index, slot; + int32 width, height; + int32 scanline; + SNES::Input::Device inports[2]; + + int32 padding2; + + //always used in pairs + void* buf[3]; + int32 buf_size[3]; + + int32 padding3; + + int64 cdl_ptr[4]; + int32 cdl_size[4]; + + CPURegsComm cpuregs; + LayerEnablesComm layerEnables; + + //static configuration-type information which can be grabbed off the core at any time without even needing a QUERY command + uint32 region; + uint32 mapper; + + int32 padding4; + + //=========================================================== + + //private stuff + void* privbuf[3]; //TODO remember to tidy this.. + + void CopyBuffer(int id, void* ptr, int32 size) + { + if (privbuf[id]) free(privbuf[id]); + buf[id] = privbuf[id] = malloc(size); + memcpy(buf[id], ptr, size); + buf_size[id] = size; + } + + void SetBuffer(int id, void* ptr, int32 size) + { + if (privbuf[id]) free(privbuf[id]); + privbuf[id] = nullptr; + buf[id] = ptr; + buf_size[id] = size; + } + + +} comm; + +//coroutines +cothread_t co_control, co_emu, co_emu_suspended; + +//internal state +bool audio_en = false; +static const int AUDIOBUFFER_SIZE = 44100 * 2; +uint16_t audiobuffer[AUDIOBUFFER_SIZE]; +int audiobuffer_idx = 0; +Action CMD_cb; + +void BREAK(eMessage msg) +{ + comm.status = eStatus_BRK; + comm.reason = msg; + co_emu_suspended = co_active(); + co_switch(co_control); + comm.status = eStatus_CMD; +} + +void snes_video_refresh(const uint32_t *data, unsigned width, unsigned height) +{ + comm.width = width; + comm.height = height; + comm.ptr = (void*)data; + + BREAK(eMessage_SIG_video_refresh); +} + +void do_SIG_audio_flush() +{ + comm.ptr = audiobuffer; + comm.size = audiobuffer_idx; + BREAK(eMessage_SIG_audio_flush); + audiobuffer_idx = 0; +} + +//this is the raw callback from the emulator internals when a new audio sample is available +void snes_audio_sample(uint16_t left, uint16_t right) +{ + if(!audio_en) return; + + //if theres no room in the audio buffer, we need to send a flush signal + if (audiobuffer_idx == AUDIOBUFFER_SIZE) + { + do_SIG_audio_flush(); + } + + audiobuffer[audiobuffer_idx++] = left; + audiobuffer[audiobuffer_idx++] = right; +} + +void snes_input_poll(void) +{ + BREAK(eMessage_SIG_input_poll); +} + +int16_t snes_input_state(unsigned port, unsigned device, unsigned index, unsigned id) +{ + comm.port = port; + comm.device = device; + comm.index = index; + comm.id = id; + BREAK(eMessage_SIG_input_state); + return comm.value; +} +void snes_input_notify(int index) +{ + comm.index = index; + BREAK(eMessage_SIG_input_notify); +} + +void snes_trace(uint32_t which, const char *msg) +{ + comm.value = which; + comm.str = (char*) msg; + BREAK(eMessage_SIG_trace_callback); +} + +const char* snes_path_request(int slot, const char* hint) +{ + comm.slot = slot; + comm.str= (char *)hint; + BREAK(eMessage_SIG_path_request); + return (const char*)comm.buf[0]; +} + +void snes_scanlineStart(int line) +{ + comm.scanline = line; + BREAK(eMessage_BRK_scanlineStart); +} + +void* snes_allocSharedMemory(const char* memtype, size_t amt) +{ + //its important that this happen before the message marshaling because allocation/free attempts can happen before the marshaling is setup (or at shutdown time, in case of errors?) + //if(!running) return NULL; + + void* ret; + + if (strcmp(memtype, "CARTRIDGE_ROM") == 0) + ret = alloc_sealed(amt); + else + ret = alloc_plain(amt); + + comm.str = (char*)memtype; + comm.size = amt; + comm.ptr = ret; + + BREAK(eMessage_SIG_allocSharedMemory); + + return comm.ptr; +} + +void snes_freeSharedMemory(void* ptr) +{ + //its important that this happen before the message marshaling because allocation/free attempts can happen before the marshaling is setup (or at shutdown time, in case of errors?) + //if(!running) return; + + if (!ptr) return; + + comm.ptr = ptr; + + BREAK(eMessage_SIG_freeSharedMemory); +} + +static void debug_op_exec(uint24 addr) +{ + comm.addr = addr; + BREAK(eMessage_BRK_hook_exec); +} + +static void debug_op_read(uint24 addr) +{ + comm.addr = addr; + BREAK(eMessage_BRK_hook_read); +} + +static void debug_op_write(uint24 addr, uint8 value) +{ + comm.addr = addr; + comm.value = value; + BREAK(eMessage_BRK_hook_write); +} + +static void debug_op_nmi() +{ + BREAK(eMessage_BRK_hook_nmi); +} + +static void debug_op_irq() +{ + BREAK(eMessage_BRK_hook_irq); +} + +void pwrap_init() +{ + //bsnes's interface initialization calls into this after initializing itself, so we can get a chance to mod it for pwrap functionalities + snes_set_video_refresh(snes_video_refresh); + snes_set_audio_sample(snes_audio_sample); + snes_set_input_poll(snes_input_poll); + snes_set_input_state(snes_input_state); + snes_set_input_notify(snes_input_notify); + snes_set_path_request(snes_path_request); + snes_set_allocSharedMemory(snes_allocSharedMemory); + snes_set_freeSharedMemory(snes_freeSharedMemory); +} + +static void Analyze() +{ + //gather some "static" type information, so we dont have to poll annoyingly for it later + comm.mapper = snes_get_mapper(); + comm.region = snes_get_region(); +} + +void CMD_LoadCartridgeNormal() +{ + const char* xml = (const char*)comm.buf[0]; + if(!xml[0]) xml = nullptr; + bool ret = snes_load_cartridge_normal(xml, (const uint8_t*)comm.buf[1], comm.buf_size[1]); + comm.value = ret?1:0; + + if(ret) + Analyze(); +} + +void CMD_LoadCartridgeSGB() +{ + bool ret = snes_load_cartridge_super_game_boy((const char*)comm.buf[0], (const u8*)comm.buf[1], comm.buf_size[1], nullptr, (const u8*)comm.buf[2], comm.buf_size[2]); + comm.value = ret ? 1 : 0; + + if(ret) + Analyze(); +} + +void CMD_init() +{ + snes_init(); + SNES::input.connect(SNES::Controller::Port1, comm.inports[0]); - SNES::input.connect(SNES::Controller::Port2, comm.inports[1]); -} - -void CMD_Serialize() -{ - int size = comm.buf_size[0]; - char* buf = (char*)comm.buf[0]; - bool ret = snes_serialize((uint8_t*)buf,size); - comm.value = ret ? 1 : 0; -} - -void CMD_Unserialize() -{ - int size = comm.buf_size[0]; - char* buf = (char*)comm.buf[0]; - bool ret = snes_unserialize((uint8_t*)buf ,size); - comm.value = ret ? 1 : 0; -} - -static void CMD_Run() -{ - do_SIG_audio_flush(); - - //we could avoid this if we saved the current thread before jumping back to co_control, instead of always jumping back to co_emu - //in effect, we're scrambling the scheduler - //EDIT - well, we changed that, but.. we still want this probably, for debugging and stuff - for (;;) - { - SNES::scheduler.sync = SNES::Scheduler::SynchronizeMode::None; - SNES::scheduler.clearExitReason(); - SNES::scheduler.enter(); - if (SNES::scheduler.exit_reason() == SNES::Scheduler::ExitReason::FrameEvent) - { - SNES::video.update(); - break; - } - //not used yet - if (SNES::scheduler.exit_reason() == SNES::Scheduler::ExitReason::DebuggerEvent) - break; - } - - do_SIG_audio_flush(); -} - -void QUERY_get_memory_size() { - comm.value = snes_get_memory_size(comm.value); -} -void QUERY_peek() { - if (comm.id == SNES_MEMORY_SYSBUS) - comm.value = bus_read(comm.addr); - else comm.value = snes_get_memory_data(comm.id)[comm.addr]; -} -void QUERY_poke() { - if (comm.id == SNES_MEMORY_SYSBUS) - bus_write(comm.addr, comm.value); - else snes_get_memory_data(comm.id)[comm.addr] = comm.value; -} -void QUERY_set_color_lut() { - snes_set_color_lut((uint32_t*)comm.ptr); -} -void QUERY_GetMemoryIdName() { - comm.str = (char* )snes_get_memory_id_name(comm.id); -} -void QUERY_state_hook_exec() { - SNES::cpu.debugger.op_exec = comm.value ? debug_op_exec : hook(); -} -void QUERY_state_hook_read() { - SNES::cpu.debugger.op_read = comm.value ? debug_op_read : hook(); -} -void QUERY_state_hook_write() { - SNES::cpu.debugger.op_write = comm.value ? debug_op_write : hook(); -} -void QUERY_state_hook_nmi() { - SNES::cpu.debugger.op_nmi = comm.value ? debug_op_nmi : hook(); -} -void QUERY_state_hook_irq() { - SNES::cpu.debugger.op_irq = comm.value ? debug_op_irq : hook(); -} -void QUERY_state_enable_trace() { - snes_set_trace_callback(comm.value, snes_trace); -} -void QUERY_state_enable_scanline() { - if (comm.value) - snes_set_scanlineStart(snes_scanlineStart); - else snes_set_scanlineStart(nullptr); -} -void QUERY_state_enable_audio() { - audio_en = !!comm.value; -} -void QUERY_state_set_layer_enable() { - snes_set_layer_enable(0, 0, !!comm.layerEnables.BG1_Prio0); - snes_set_layer_enable(0, 1, !!comm.layerEnables.BG1_Prio1); - snes_set_layer_enable(1, 0, !!comm.layerEnables.BG2_Prio0); - snes_set_layer_enable(1, 1, !!comm.layerEnables.BG2_Prio1); - snes_set_layer_enable(2, 0, !!comm.layerEnables.BG3_Prio0); - snes_set_layer_enable(2, 1, !!comm.layerEnables.BG3_Prio1); - snes_set_layer_enable(3, 0, !!comm.layerEnables.BG4_Prio0); - snes_set_layer_enable(3, 1, !!comm.layerEnables.BG4_Prio1); - snes_set_layer_enable(4, 0, !!comm.layerEnables.Obj_Prio0); - snes_set_layer_enable(4, 1, !!comm.layerEnables.Obj_Prio1); - snes_set_layer_enable(4, 2, !!comm.layerEnables.Obj_Prio2); - snes_set_layer_enable(4, 3, !!comm.layerEnables.Obj_Prio3); -} -void QUERY_set_backdropColor() { - snes_set_backdropColor((s32)comm.value); -} -void QUERY_peek_logical_register() { - comm.value = snes_peek_logical_register(comm.id); -} -void QUERY_peek_cpu_regs() { - comm.cpuregs.pc = (u32)SNES::cpu.regs.pc; - comm.cpuregs.a = SNES::cpu.regs.a; - comm.cpuregs.x = SNES::cpu.regs.x; - comm.cpuregs.y = SNES::cpu.regs.y; - comm.cpuregs.z = SNES::cpu.regs.z; - comm.cpuregs.s = SNES::cpu.regs.s; - comm.cpuregs.d = SNES::cpu.regs.d; - comm.cpuregs.aa = (u32)SNES::cpu.aa; - comm.cpuregs.rd = (u32)SNES::cpu.rd; - comm.cpuregs.sp = SNES::cpu.sp; - comm.cpuregs.dp = SNES::cpu.dp; - comm.cpuregs.db = SNES::cpu.regs.db; - comm.cpuregs.mdr = SNES::cpu.regs.mdr; - comm.cpuregs.vector = SNES::cpu.regs.vector; - comm.cpuregs.p = SNES::cpu.regs.p; - comm.cpuregs.nothing = 0; -} -void QUERY_peek_set_cdl() { - for (int i = 0; i= eMessage_CMD_FIRST && msg <= eMessage_CMD_LAST) - { - //CMD is only valid if status is idle - if (comm.status != eStatus_Idle) - { - printf("ERROR: cmd during non-idle\n"); - return; - } - - comm.status = eStatus_CMD; - comm.cmd = msg; - - CMD_cb = kHandlers_CMD[msg - eMessage_CMD_FIRST - 1]; - co_switch(co_emu); - - //we could be in ANY STATE when we return from here - } - - //QUERY can run any time - //but... some of them might not be safe for re-entrancy. - //later, we should have metadata for messages that indicates that - if (msg >= eMessage_QUERY_FIRST && msg <= eMessage_QUERY_LAST) - { - Action cb = kHandlers_QUERY[msg - eMessage_QUERY_FIRST - 1]; - if (cb) cb(); - } -} - - -//receives the given buffer and COPIES it. use this for returning values from SIGs -extern "C" dllexport void __cdecl CopyBuffer(int id, void* ptr, int32 size) -{ - comm.CopyBuffer(id, ptr, size); -} - -//receives the given buffer and STASHES IT. use this (carefully) for sending params for CMDs -extern "C" dllexport void __cdecl SetBuffer(int id, void* ptr, int32 size) -{ - comm.SetBuffer(id, ptr, size); -} \ No newline at end of file + SNES::input.connect(SNES::Controller::Port2, comm.inports[1]); +} + +static void CMD_Run() +{ + do_SIG_audio_flush(); + + //we could avoid this if we saved the current thread before jumping back to co_control, instead of always jumping back to co_emu + //in effect, we're scrambling the scheduler + //EDIT - well, we changed that, but.. we still want this probably, for debugging and stuff + for (;;) + { + SNES::scheduler.sync = SNES::Scheduler::SynchronizeMode::None; + SNES::scheduler.clearExitReason(); + SNES::scheduler.enter(); + if (SNES::scheduler.exit_reason() == SNES::Scheduler::ExitReason::FrameEvent) + { + SNES::video.update(); + break; + } + //not used yet + if (SNES::scheduler.exit_reason() == SNES::Scheduler::ExitReason::DebuggerEvent) + break; + } + + do_SIG_audio_flush(); +} + +void QUERY_get_memory_size() { + comm.value = snes_get_memory_size(comm.value); +} +void QUERY_peek() { + if (comm.id == SNES_MEMORY_SYSBUS) + comm.value = bus_read(comm.addr); + else comm.value = snes_get_memory_data(comm.id)[comm.addr]; +} +void QUERY_poke() { + if (comm.id == SNES_MEMORY_SYSBUS) + bus_write(comm.addr, comm.value); + else snes_get_memory_data(comm.id)[comm.addr] = comm.value; +} +void QUERY_set_color_lut() { + snes_set_color_lut((uint32_t*)comm.ptr); +} +void QUERY_GetMemoryIdName() { + comm.str = (char* )snes_get_memory_id_name(comm.id); +} +void QUERY_state_hook_exec() { + SNES::cpu.debugger.op_exec = comm.value ? debug_op_exec : hook(); +} +void QUERY_state_hook_read() { + SNES::cpu.debugger.op_read = comm.value ? debug_op_read : hook(); +} +void QUERY_state_hook_write() { + SNES::cpu.debugger.op_write = comm.value ? debug_op_write : hook(); +} +void QUERY_state_hook_nmi() { + SNES::cpu.debugger.op_nmi = comm.value ? debug_op_nmi : hook(); +} +void QUERY_state_hook_irq() { + SNES::cpu.debugger.op_irq = comm.value ? debug_op_irq : hook(); +} +void QUERY_state_enable_trace() { + snes_set_trace_callback(comm.value, snes_trace); +} +void QUERY_state_enable_scanline() { + if (comm.value) + snes_set_scanlineStart(snes_scanlineStart); + else snes_set_scanlineStart(nullptr); +} +void QUERY_state_enable_audio() { + audio_en = !!comm.value; +} +void QUERY_state_set_layer_enable() { + snes_set_layer_enable(0, 0, !!comm.layerEnables.BG1_Prio0); + snes_set_layer_enable(0, 1, !!comm.layerEnables.BG1_Prio1); + snes_set_layer_enable(1, 0, !!comm.layerEnables.BG2_Prio0); + snes_set_layer_enable(1, 1, !!comm.layerEnables.BG2_Prio1); + snes_set_layer_enable(2, 0, !!comm.layerEnables.BG3_Prio0); + snes_set_layer_enable(2, 1, !!comm.layerEnables.BG3_Prio1); + snes_set_layer_enable(3, 0, !!comm.layerEnables.BG4_Prio0); + snes_set_layer_enable(3, 1, !!comm.layerEnables.BG4_Prio1); + snes_set_layer_enable(4, 0, !!comm.layerEnables.Obj_Prio0); + snes_set_layer_enable(4, 1, !!comm.layerEnables.Obj_Prio1); + snes_set_layer_enable(4, 2, !!comm.layerEnables.Obj_Prio2); + snes_set_layer_enable(4, 3, !!comm.layerEnables.Obj_Prio3); +} +void QUERY_set_backdropColor() { + snes_set_backdropColor((s32)comm.value); +} +void QUERY_peek_logical_register() { + comm.value = snes_peek_logical_register(comm.id); +} +void QUERY_peek_cpu_regs() { + comm.cpuregs.pc = (u32)SNES::cpu.regs.pc; + comm.cpuregs.a = SNES::cpu.regs.a; + comm.cpuregs.x = SNES::cpu.regs.x; + comm.cpuregs.y = SNES::cpu.regs.y; + comm.cpuregs.z = SNES::cpu.regs.z; + comm.cpuregs.s = SNES::cpu.regs.s; + comm.cpuregs.d = SNES::cpu.regs.d; + comm.cpuregs.aa = (u32)SNES::cpu.aa; + comm.cpuregs.rd = (u32)SNES::cpu.rd; + comm.cpuregs.sp = SNES::cpu.sp; + comm.cpuregs.dp = SNES::cpu.dp; + comm.cpuregs.db = SNES::cpu.regs.db; + comm.cpuregs.mdr = SNES::cpu.regs.mdr; + comm.cpuregs.vector = SNES::cpu.regs.vector; + comm.cpuregs.p = SNES::cpu.regs.p; + comm.cpuregs.nothing = 0; +} +void QUERY_peek_set_cdl() { + for (int i = 0; i +#define EXPORT extern "C" ECL_EXPORT + +EXPORT void* DllInit() +{ + #define T(s,n) static_assert(offsetof(CommStruct,s)==n,#n) + T(cmd, 0); + T(status, 4); + T(reason, 8); + T(str, 16); + T(ptr, 24); + T(id, 32); + T(port, 48); + T(width, 64); + T(scanline, 72); + T(inports, 76); + T(buf, 88); + T(buf_size, 112); + T(cdl_ptr, 128); + T(cdl_size, 160); + T(cpuregs, 176); + T(layerEnables, 208); + T(region, 220); + T(mapper, 224); + // start of private stuff + T(privbuf, 232); + #undef T + + memset(&comm, 0, sizeof(comm)); + + //make a coroutine thread to run the emulation in. we'll switch back to this cothread when communicating with the frontend + co_control = co_active(); + if (co_emu) + { + // if this was called again, that's OK; delete the old emuthread + co_delete(co_emu); + co_emu = nullptr; + } + co_emu = co_create(32768 * sizeof(void*), new_emuthread); + + return &comm; +} + +EXPORT void Message(eMessage msg) +{ + if (msg == eMessage_Resume) + { + cothread_t temp = co_emu_suspended; + co_emu_suspended = NULL; + co_switch(temp); + } + + if (msg >= eMessage_CMD_FIRST && msg <= eMessage_CMD_LAST) + { + //CMD is only valid if status is idle + if (comm.status != eStatus_Idle) + { + printf("ERROR: cmd during non-idle\n"); + return; + } + + comm.status = eStatus_CMD; + comm.cmd = msg; + + CMD_cb = kHandlers_CMD[msg - eMessage_CMD_FIRST - 1]; + co_switch(co_emu); + + //we could be in ANY STATE when we return from here + } + + //QUERY can run any time + //but... some of them might not be safe for re-entrancy. + //later, we should have metadata for messages that indicates that + if (msg >= eMessage_QUERY_FIRST && msg <= eMessage_QUERY_LAST) + { + Action cb = kHandlers_QUERY[msg - eMessage_QUERY_FIRST - 1]; + if (cb) cb(); + } +} + + +//receives the given buffer and COPIES it. use this for returning values from SIGs +EXPORT void CopyBuffer(int id, void* ptr, int32 size) +{ + comm.CopyBuffer(id, ptr, size); +} + +//receives the given buffer and STASHES IT. use this (carefully) for sending params for CMDs +EXPORT void SetBuffer(int id, void* ptr, int32 size) +{ + comm.SetBuffer(id, ptr, size); +} + +EXPORT void PostLoadState() +{ + SNES::ppu.flush_tiledata_cache(); +} + +int main() +{ + return 0; +} diff --git a/libsnes/libco_debugging/build.sh b/waterbox/libsnes/libco_debugging/build.sh similarity index 94% rename from libsnes/libco_debugging/build.sh rename to waterbox/libsnes/libco_debugging/build.sh index a499104d22..27160d209a 100644 --- a/libsnes/libco_debugging/build.sh +++ b/waterbox/libsnes/libco_debugging/build.sh @@ -1,2 +1,2 @@ -gcc libco_win32threads.c -o libco.dll -Wall -shared -O0 -g +gcc libco_win32threads.c -o libco.dll -Wall -shared -O0 -g mv libco.dll ../../BizHawk.MultiClient/output/dll/libco_msvc_win32.dll \ No newline at end of file diff --git a/libsnes/libco_debugging/libco.h b/waterbox/libsnes/libco_debugging/libco.h similarity index 100% rename from libsnes/libco_debugging/libco.h rename to waterbox/libsnes/libco_debugging/libco.h diff --git a/libsnes/libco_debugging/libco_win32threads.c b/waterbox/libsnes/libco_debugging/libco_win32threads.c similarity index 97% rename from libsnes/libco_debugging/libco_win32threads.c rename to waterbox/libsnes/libco_debugging/libco_win32threads.c index 4739947e22..f33bb7b4bb 100644 --- a/libsnes/libco_debugging/libco_win32threads.c +++ b/waterbox/libsnes/libco_debugging/libco_win32threads.c @@ -1,138 +1,138 @@ -/* -win32 implementation of libco using actual threads. much slower than other implementations, -but far from glacial. may be useful for debuggers that don't understand libco cothreads. - -compiles in mingw. try: -gcc libco_win32threads.c -o libco.dll -Wall -shared -O0 -g -*/ - -#include -#include // asserts don't happen in co_switch(), so no real performance gain from turning them off -#define LIBCO_C -#include "libco.h" -#define WIN32_LEAN_AND_MEAN -#include - -typedef struct -{ - HANDLE thread; - HANDLE sem; - int wantdie; - void (*entrypoint)(void); -} coprivate; - -static __thread coprivate *libco_priv = NULL; - - -/* -Return handle to current cothread. Always returns a valid handle, even when called from the main program thread. -*/ -cothread_t co_active(void) -{ - if (!libco_priv) - { - // thread started out as a real thread, so we must make a libco_priv for it - libco_priv = malloc(sizeof (*libco_priv)); - assert(libco_priv); - DWORD ret = DuplicateHandle - ( - GetCurrentProcess(), - GetCurrentThread(), - GetCurrentProcess(), - &libco_priv->thread, - 0, - FALSE, - DUPLICATE_SAME_ACCESS - ); - assert(ret); - libco_priv->sem = CreateSemaphore(NULL, 0, 1, NULL); - assert(libco_priv->sem); - libco_priv->wantdie = 0; - libco_priv->entrypoint = NULL; - } - return (cothread_t) libco_priv; -} - -void waittorun(void) -{ - // i suppose it would be possible to switch off the main thread - // without ever having made a context for it. then it would never - // be able to activate again. - coprivate *this = (coprivate *) co_active(); - WaitForSingleObject(this->sem, INFINITE); - if (this->wantdie) - { - CloseHandle(this->sem); - ExitThread(0); - } -} - -DWORD WINAPI thread_entry(LPVOID lpParameter) -{ - libco_priv = (coprivate *) lpParameter; - waittorun(); - libco_priv->entrypoint(); - assert(0); // returning from entry point not allowed - return 0; -} - -/* -Create new cothread. -Heapsize is the amount of memory allocated for the cothread stack, specified in bytes. This is unfortunately impossible to make fully portable. It is recommended to specify sizes using `n * sizeof(void*)'. It is better to err on the side of caution and allocate more memory than will be needed to ensure compatibility with other platforms, within reason. A typical heapsize for a 32-bit architecture is ~1MB. -When the new cothread is first called, program execution jumps to coentry. This function does not take any arguments, due to portability issues with passing function arguments. However, arguments can be simulated by the use of global variables, which can be set before the first call to each cothread. -coentry() must not return, and should end with an appropriate co_switch() statement. Behavior is undefined if entry point returns normally. -Library is responsible for allocating cothread stack memory, to free the user from needing to allocate special memory capable of being used as program stack memory on platforms where this is required. -User is always responsible for deleting cothreads with co_delete(). -Return value of null (0) indicates cothread creation failed. -*/ -cothread_t co_create(unsigned int heapsize, void (*entry)(void)) -{ - coprivate *new_thread = malloc(sizeof (*new_thread)); - assert(new_thread); - new_thread->sem = CreateSemaphore(NULL, 0, 1, NULL); - assert(new_thread->sem); - new_thread->wantdie = 0; - new_thread->entrypoint = entry; - assert(new_thread->entrypoint); - new_thread->thread = CreateThread - ( - NULL, - heapsize, - thread_entry, - (void *)new_thread, - 0, // runs immediately - NULL - ); - assert(new_thread->thread); - return (cothread_t) new_thread; -} - -/* -Delete specified cothread. -Null (0) or invalid cothread handle is not allowed. -Passing handle of active cothread to this function is not allowed. -Passing handle of primary cothread is not allowed. -*/ -void co_delete(cothread_t _thread) -{ - coprivate *thread = (coprivate *) _thread; - assert(thread); - assert(thread->entrypoint); // Passing handle of primary cothread is not allowed - thread->wantdie = 1; - ReleaseSemaphore(thread->sem, 1, NULL); - WaitForSingleObject(thread->thread, INFINITE); - CloseHandle(thread->thread); - free(thread); -} - -/* -Switch to specified cothread. -Null (0) or invalid cothread handle is not allowed. -Passing handle of active cothread to this function is not allowed. -*/ -void co_switch(cothread_t _thread) -{ - coprivate *thread = (coprivate *) _thread; - ReleaseSemaphore(thread->sem, 1, NULL); - waittorun(); -} +/* +win32 implementation of libco using actual threads. much slower than other implementations, +but far from glacial. may be useful for debuggers that don't understand libco cothreads. + +compiles in mingw. try: +gcc libco_win32threads.c -o libco.dll -Wall -shared -O0 -g +*/ + +#include +#include // asserts don't happen in co_switch(), so no real performance gain from turning them off +#define LIBCO_C +#include "libco.h" +#define WIN32_LEAN_AND_MEAN +#include + +typedef struct +{ + HANDLE thread; + HANDLE sem; + int wantdie; + void (*entrypoint)(void); +} coprivate; + +static __thread coprivate *libco_priv = NULL; + + +/* +Return handle to current cothread. Always returns a valid handle, even when called from the main program thread. +*/ +cothread_t co_active(void) +{ + if (!libco_priv) + { + // thread started out as a real thread, so we must make a libco_priv for it + libco_priv = malloc(sizeof (*libco_priv)); + assert(libco_priv); + DWORD ret = DuplicateHandle + ( + GetCurrentProcess(), + GetCurrentThread(), + GetCurrentProcess(), + &libco_priv->thread, + 0, + FALSE, + DUPLICATE_SAME_ACCESS + ); + assert(ret); + libco_priv->sem = CreateSemaphore(NULL, 0, 1, NULL); + assert(libco_priv->sem); + libco_priv->wantdie = 0; + libco_priv->entrypoint = NULL; + } + return (cothread_t) libco_priv; +} + +void waittorun(void) +{ + // i suppose it would be possible to switch off the main thread + // without ever having made a context for it. then it would never + // be able to activate again. + coprivate *this = (coprivate *) co_active(); + WaitForSingleObject(this->sem, INFINITE); + if (this->wantdie) + { + CloseHandle(this->sem); + ExitThread(0); + } +} + +DWORD WINAPI thread_entry(LPVOID lpParameter) +{ + libco_priv = (coprivate *) lpParameter; + waittorun(); + libco_priv->entrypoint(); + assert(0); // returning from entry point not allowed + return 0; +} + +/* +Create new cothread. +Heapsize is the amount of memory allocated for the cothread stack, specified in bytes. This is unfortunately impossible to make fully portable. It is recommended to specify sizes using `n * sizeof(void*)'. It is better to err on the side of caution and allocate more memory than will be needed to ensure compatibility with other platforms, within reason. A typical heapsize for a 32-bit architecture is ~1MB. +When the new cothread is first called, program execution jumps to coentry. This function does not take any arguments, due to portability issues with passing function arguments. However, arguments can be simulated by the use of global variables, which can be set before the first call to each cothread. +coentry() must not return, and should end with an appropriate co_switch() statement. Behavior is undefined if entry point returns normally. +Library is responsible for allocating cothread stack memory, to free the user from needing to allocate special memory capable of being used as program stack memory on platforms where this is required. +User is always responsible for deleting cothreads with co_delete(). +Return value of null (0) indicates cothread creation failed. +*/ +cothread_t co_create(unsigned int heapsize, void (*entry)(void)) +{ + coprivate *new_thread = malloc(sizeof (*new_thread)); + assert(new_thread); + new_thread->sem = CreateSemaphore(NULL, 0, 1, NULL); + assert(new_thread->sem); + new_thread->wantdie = 0; + new_thread->entrypoint = entry; + assert(new_thread->entrypoint); + new_thread->thread = CreateThread + ( + NULL, + heapsize, + thread_entry, + (void *)new_thread, + 0, // runs immediately + NULL + ); + assert(new_thread->thread); + return (cothread_t) new_thread; +} + +/* +Delete specified cothread. +Null (0) or invalid cothread handle is not allowed. +Passing handle of active cothread to this function is not allowed. +Passing handle of primary cothread is not allowed. +*/ +void co_delete(cothread_t _thread) +{ + coprivate *thread = (coprivate *) _thread; + assert(thread); + assert(thread->entrypoint); // Passing handle of primary cothread is not allowed + thread->wantdie = 1; + ReleaseSemaphore(thread->sem, 1, NULL); + WaitForSingleObject(thread->thread, INFINITE); + CloseHandle(thread->thread); + free(thread); +} + +/* +Switch to specified cothread. +Null (0) or invalid cothread handle is not allowed. +Passing handle of active cothread to this function is not allowed. +*/ +void co_switch(cothread_t _thread) +{ + coprivate *thread = (coprivate *) _thread; + ReleaseSemaphore(thread->sem, 1, NULL); + waittorun(); +} diff --git a/libsnes/libco_debugging/makefile b/waterbox/libsnes/libco_debugging/makefile similarity index 97% rename from libsnes/libco_debugging/makefile rename to waterbox/libsnes/libco_debugging/makefile index d318edaba2..72bb5bd15e 100644 --- a/libsnes/libco_debugging/makefile +++ b/waterbox/libsnes/libco_debugging/makefile @@ -1,2 +1,2 @@ -libco.dll: libco_win32threads.c - gcc libco_win32threads.c -o libco.dll -Wall -shared -O0 -g +libco.dll: libco_win32threads.c + gcc libco_win32threads.c -o libco.dll -Wall -shared -O0 -g diff --git a/libsnes/lsnes_patches/0001-Don-t-use-time-in-emulating-chips.patch b/waterbox/libsnes/lsnes_patches/0001-Don-t-use-time-in-emulating-chips.patch similarity index 97% rename from libsnes/lsnes_patches/0001-Don-t-use-time-in-emulating-chips.patch rename to waterbox/libsnes/lsnes_patches/0001-Don-t-use-time-in-emulating-chips.patch index a2963ab7c4..7df8070176 100644 --- a/libsnes/lsnes_patches/0001-Don-t-use-time-in-emulating-chips.patch +++ b/waterbox/libsnes/lsnes_patches/0001-Don-t-use-time-in-emulating-chips.patch @@ -1,84 +1,84 @@ -From 22205d4d339cfa11f6d53e644eae1c859a56d349 Mon Sep 17 00:00:00 2001 -From: Ilari Liusvaara -Date: Wed, 9 Nov 2011 00:37:44 +0200 -Subject: [PATCH 1/4] Don't use time() in emulating chips - -Instead of using time() in chip emulation, create new interface method -currentTime(), defaulting to time(0). This way frontend can cleanly -override the current time bsnes is using. ---- - snes/chip/bsx/satellaview/satellaview.cpp | 2 +- - snes/chip/spc7110/spc7110.cpp | 2 +- - snes/chip/srtc/srtc.cpp | 2 +- - snes/interface/interface.cpp | 5 +++++ - snes/interface/interface.hpp | 1 + - 5 files changed, 9 insertions(+), 3 deletions(-) - -diff --git a/snes/chip/bsx/satellaview/satellaview.cpp b/snes/chip/bsx/satellaview/satellaview.cpp -index 386fb62..3c98019 100755 ---- snes/chip/bsx/satellaview/satellaview.cpp -+++ snes/chip/bsx/satellaview/satellaview.cpp -@@ -38,7 +38,7 @@ uint8 BSXSatellaview::mmio_read(unsigned addr) { - - if(counter == 0) { - time_t rawtime; -- time(&rawtime); -+ rawtime = SNES::interface->currentTime(); - tm *t = localtime(&rawtime); - - regs.r2192_hour = t->tm_hour; -diff --git a/snes/chip/spc7110/spc7110.cpp b/snes/chip/spc7110/spc7110.cpp -index 27b8b77..061aa5e 100755 ---- snes/chip/spc7110/spc7110.cpp -+++ snes/chip/spc7110/spc7110.cpp -@@ -101,7 +101,7 @@ void SPC7110::set_data_adjust(unsigned addr) { r4814 = addr; r4815 = addr >> 8; - - void SPC7110::update_time(int offset) { - time_t rtc_time = (rtc[16] << 0) | (rtc[17] << 8) | (rtc[18] << 16) | (rtc[19] << 24); -- time_t current_time = time(0) - offset; -+ time_t current_time = SNES::interface->currentTime() - offset; - - //sizeof(time_t) is platform-dependent; though rtc[] needs to be platform-agnostic. - //yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by -diff --git a/snes/chip/srtc/srtc.cpp b/snes/chip/srtc/srtc.cpp -index 0044113..725e891 100755 ---- snes/chip/srtc/srtc.cpp -+++ snes/chip/srtc/srtc.cpp -@@ -31,7 +31,7 @@ void SRTC::reset() { - - void SRTC::update_time() { - time_t rtc_time = (rtc[16] << 0) | (rtc[17] << 8) | (rtc[18] << 16) | (rtc[19] << 24); -- time_t current_time = time(0); -+ time_t current_time = SNES::interface->currentTime(); - - //sizeof(time_t) is platform-dependent; though rtc[] needs to be platform-agnostic. - //yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by -diff --git a/snes/interface/interface.cpp b/snes/interface/interface.cpp -index a0e3a81..b3017c9 100755 ---- snes/interface/interface.cpp -+++ snes/interface/interface.cpp -@@ -18,4 +18,9 @@ void Interface::message(const string &text) { - print(text, "\n"); - } - -+time_t Interface::currentTime() -+{ -+ return time(0); -+} -+ - } -diff --git a/snes/interface/interface.hpp b/snes/interface/interface.hpp -index f1a48c0..df975e8 100755 ---- snes/interface/interface.hpp -+++ snes/interface/interface.hpp -@@ -5,6 +5,7 @@ struct Interface { - - virtual string path(Cartridge::Slot slot, const string &hint) = 0; - virtual void message(const string &text); -+ virtual time_t currentTime(); - }; - - extern Interface *interface; --- -1.7.9.48.g85da4d - +From 22205d4d339cfa11f6d53e644eae1c859a56d349 Mon Sep 17 00:00:00 2001 +From: Ilari Liusvaara +Date: Wed, 9 Nov 2011 00:37:44 +0200 +Subject: [PATCH 1/4] Don't use time() in emulating chips + +Instead of using time() in chip emulation, create new interface method +currentTime(), defaulting to time(0). This way frontend can cleanly +override the current time bsnes is using. +--- + snes/chip/bsx/satellaview/satellaview.cpp | 2 +- + snes/chip/spc7110/spc7110.cpp | 2 +- + snes/chip/srtc/srtc.cpp | 2 +- + snes/interface/interface.cpp | 5 +++++ + snes/interface/interface.hpp | 1 + + 5 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/snes/chip/bsx/satellaview/satellaview.cpp b/snes/chip/bsx/satellaview/satellaview.cpp +index 386fb62..3c98019 100755 +--- snes/chip/bsx/satellaview/satellaview.cpp ++++ snes/chip/bsx/satellaview/satellaview.cpp +@@ -38,7 +38,7 @@ uint8 BSXSatellaview::mmio_read(unsigned addr) { + + if(counter == 0) { + time_t rawtime; +- time(&rawtime); ++ rawtime = SNES::interface->currentTime(); + tm *t = localtime(&rawtime); + + regs.r2192_hour = t->tm_hour; +diff --git a/snes/chip/spc7110/spc7110.cpp b/snes/chip/spc7110/spc7110.cpp +index 27b8b77..061aa5e 100755 +--- snes/chip/spc7110/spc7110.cpp ++++ snes/chip/spc7110/spc7110.cpp +@@ -101,7 +101,7 @@ void SPC7110::set_data_adjust(unsigned addr) { r4814 = addr; r4815 = addr >> 8; + + void SPC7110::update_time(int offset) { + time_t rtc_time = (rtc[16] << 0) | (rtc[17] << 8) | (rtc[18] << 16) | (rtc[19] << 24); +- time_t current_time = time(0) - offset; ++ time_t current_time = SNES::interface->currentTime() - offset; + + //sizeof(time_t) is platform-dependent; though rtc[] needs to be platform-agnostic. + //yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by +diff --git a/snes/chip/srtc/srtc.cpp b/snes/chip/srtc/srtc.cpp +index 0044113..725e891 100755 +--- snes/chip/srtc/srtc.cpp ++++ snes/chip/srtc/srtc.cpp +@@ -31,7 +31,7 @@ void SRTC::reset() { + + void SRTC::update_time() { + time_t rtc_time = (rtc[16] << 0) | (rtc[17] << 8) | (rtc[18] << 16) | (rtc[19] << 24); +- time_t current_time = time(0); ++ time_t current_time = SNES::interface->currentTime(); + + //sizeof(time_t) is platform-dependent; though rtc[] needs to be platform-agnostic. + //yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by +diff --git a/snes/interface/interface.cpp b/snes/interface/interface.cpp +index a0e3a81..b3017c9 100755 +--- snes/interface/interface.cpp ++++ snes/interface/interface.cpp +@@ -18,4 +18,9 @@ void Interface::message(const string &text) { + print(text, "\n"); + } + ++time_t Interface::currentTime() ++{ ++ return time(0); ++} ++ + } +diff --git a/snes/interface/interface.hpp b/snes/interface/interface.hpp +index f1a48c0..df975e8 100755 +--- snes/interface/interface.hpp ++++ snes/interface/interface.hpp +@@ -5,6 +5,7 @@ struct Interface { + + virtual string path(Cartridge::Slot slot, const string &hint) = 0; + virtual void message(const string &text); ++ virtual time_t currentTime(); + }; + + extern Interface *interface; +-- +1.7.9.48.g85da4d + diff --git a/libsnes/lsnes_patches/0002-Save-controller-state-when-savestating.patch b/waterbox/libsnes/lsnes_patches/0002-Save-controller-state-when-savestating.patch similarity index 97% rename from libsnes/lsnes_patches/0002-Save-controller-state-when-savestating.patch rename to waterbox/libsnes/lsnes_patches/0002-Save-controller-state-when-savestating.patch index fdbb563e82..a585958334 100644 --- a/libsnes/lsnes_patches/0002-Save-controller-state-when-savestating.patch +++ b/waterbox/libsnes/lsnes_patches/0002-Save-controller-state-when-savestating.patch @@ -1,346 +1,346 @@ -From fe11984ad18561506a7cc874cb7c0421f1e21ad1 Mon Sep 17 00:00:00 2001 -From: Ilari Liusvaara -Date: Wed, 9 Nov 2011 01:52:08 +0200 -Subject: [PATCH 2/4] Save controller state when savestating - -When savestating, save the controller state and restore it upon loadstate. -Prevents libsnes from mixing up buttons. ---- - snes/controller/controller.cpp | 8 ++++++ - snes/controller/controller.hpp | 2 + - snes/controller/gamepad/gamepad.cpp | 13 ++++++++++ - snes/controller/gamepad/gamepad.hpp | 2 +- - snes/controller/justifier/justifier.cpp | 36 +++++++++++++++++++++++++++++ - snes/controller/justifier/justifier.hpp | 1 + - snes/controller/mouse/mouse.cpp | 13 ++++++++++ - snes/controller/mouse/mouse.hpp | 2 +- - snes/controller/multitap/multitap.cpp | 16 +++++++++++++ - snes/controller/multitap/multitap.hpp | 2 +- - snes/controller/superscope/superscope.cpp | 31 +++++++++++++++++++++++++ - snes/controller/superscope/superscope.hpp | 1 + - snes/system/input.cpp | 16 +++++++++++++ - snes/system/input.hpp | 1 + - snes/system/serialization.cpp | 1 + - 15 files changed, 142 insertions(+), 3 deletions(-) - -diff --git a/snes/controller/controller.cpp b/snes/controller/controller.cpp -index fa8e07d..5f37849 100755 ---- snes/controller/controller.cpp -+++ snes/controller/controller.cpp -@@ -46,8 +46,16 @@ void Controller::iobit(bool data) { - } - } - -+void Controller::serialize(serializer& s) { -+ Processor::serialize(s); -+ //Save a zero block. -+ unsigned char blockzeroes[SaveSize] = {0}; -+ s.array(blockzeroes, SaveSize); -+} -+ - Controller::Controller(bool port) : port(port) { - if(!thread) create(Controller::Enter, 1); - } - -+ - } -diff --git a/snes/controller/controller.hpp b/snes/controller/controller.hpp -index dd748a1..46095a8 100755 ---- snes/controller/controller.hpp -+++ snes/controller/controller.hpp -@@ -13,12 +13,14 @@ - - struct Controller : Processor { - enum : bool { Port1 = 0, Port2 = 1 }; -+ enum { SaveSize = 16 }; - const bool port; - - static void Enter(); - virtual void enter(); - void step(unsigned clocks); - void synchronize_cpu(); -+ virtual void serialize(serializer& s); - - bool iobit(); - void iobit(bool data); -diff --git a/snes/controller/gamepad/gamepad.cpp b/snes/controller/gamepad/gamepad.cpp -index 594020d..4fa1c99 100755 ---- snes/controller/gamepad/gamepad.cpp -+++ snes/controller/gamepad/gamepad.cpp -@@ -13,6 +13,19 @@ void Gamepad::latch(bool data) { - counter = 0; - } - -+void Gamepad::serialize(serializer& s) { -+ Processor::serialize(s); -+ //Save block. -+ unsigned char block[Controller::SaveSize] = {0}; -+ block[0] = latched ? 1 : 0; -+ block[1] = counter; -+ s.array(block, Controller::SaveSize); -+ if(s.mode() == nall::serializer::Load) { -+ latched = (block[0] != 0); -+ counter = block[1]; -+ } -+} -+ - Gamepad::Gamepad(bool port) : Controller(port) { - latched = 0; - counter = 0; -diff --git a/snes/controller/gamepad/gamepad.hpp b/snes/controller/gamepad/gamepad.hpp -index c5ca69c..a2392d1 100755 ---- snes/controller/gamepad/gamepad.hpp -+++ snes/controller/gamepad/gamepad.hpp -@@ -2,7 +2,7 @@ struct Gamepad : Controller { - uint2 data(); - void latch(bool data); - Gamepad(bool port); -- -+ void serialize(serializer& s); - private: - bool latched; - unsigned counter; -diff --git a/snes/controller/justifier/justifier.cpp b/snes/controller/justifier/justifier.cpp -index 6207916..ad13a9b 100755 ---- snes/controller/justifier/justifier.cpp -+++ snes/controller/justifier/justifier.cpp -@@ -100,6 +100,42 @@ void Justifier::latch(bool data) { - if(latched == 0) active = !active; //toggle between both controllers, even when unchained - } - -+void Justifier::serialize(serializer& s) { -+ Processor::serialize(s); -+ //Save block. -+ unsigned char block[Controller::SaveSize] = {0}; -+ block[0] = latched ? 1 : 0; -+ block[1] = counter; -+ block[2] = active ? 1 : 0; -+ block[3] = player1.trigger ? 1 : 0; -+ block[4] = player2.trigger ? 1 : 0; -+ block[5] = player1.start ? 1 : 0; -+ block[6] = player2.start ? 1 : 0; -+ block[7] = (unsigned short)player1.x >> 8; -+ block[8] = (unsigned short)player1.x; -+ block[9] = (unsigned short)player2.x >> 8; -+ block[10] = (unsigned short)player2.x; -+ block[11] = (unsigned short)player1.y >> 8; -+ block[12] = (unsigned short)player1.y; -+ block[13] = (unsigned short)player2.y >> 8; -+ block[14] = (unsigned short)player2.y; -+ s.array(block, Controller::SaveSize); -+ if(s.mode() == nall::serializer::Load) { -+ latched = (block[0] != 0); -+ counter = block[1]; -+ active = (block[2] != 0); -+ player1.trigger = (block[3] != 0); -+ player2.trigger = (block[4] != 0); -+ player1.start = (block[5] != 0); -+ player2.start = (block[6] != 0); -+ player1.x = (short)(((unsigned short)block[7] << 8) | (unsigned short)block[8]); -+ player2.x = (short)(((unsigned short)block[9] << 8) | (unsigned short)block[10]); -+ player1.y = (short)(((unsigned short)block[11] << 8) | (unsigned short)block[12]); -+ player2.y = (short)(((unsigned short)block[13] << 8) | (unsigned short)block[14]); -+ } -+} -+ -+ - Justifier::Justifier(bool port, bool chained) : Controller(port), chained(chained) { - create(Controller::Enter, 21477272); - latched = 0; -diff --git a/snes/controller/justifier/justifier.hpp b/snes/controller/justifier/justifier.hpp -index f927acf..6b7bba0 100755 ---- snes/controller/justifier/justifier.hpp -+++ snes/controller/justifier/justifier.hpp -@@ -2,6 +2,7 @@ struct Justifier : Controller { - void enter(); - uint2 data(); - void latch(bool data); -+ void serialize(serializer& s); - Justifier(bool port, bool chained); - - //private: -diff --git a/snes/controller/mouse/mouse.cpp b/snes/controller/mouse/mouse.cpp -index c9f5d16..6b26fae 100755 ---- snes/controller/mouse/mouse.cpp -+++ snes/controller/mouse/mouse.cpp -@@ -61,6 +61,19 @@ void Mouse::latch(bool data) { - counter = 0; - } - -+void Mouse::serialize(serializer& s) { -+ Processor::serialize(s); -+ //Save block. -+ unsigned char block[Controller::SaveSize] = {0}; -+ block[0] = latched ? 1 : 0; -+ block[1] = counter; -+ s.array(block, Controller::SaveSize); -+ if(s.mode() == nall::serializer::Load) { -+ latched = (block[0] != 0); -+ counter = block[1]; -+ } -+} -+ - Mouse::Mouse(bool port) : Controller(port) { - latched = 0; - counter = 0; -diff --git a/snes/controller/mouse/mouse.hpp b/snes/controller/mouse/mouse.hpp -index 95e24b6..b66ea51 100755 ---- snes/controller/mouse/mouse.hpp -+++ snes/controller/mouse/mouse.hpp -@@ -2,7 +2,7 @@ struct Mouse : Controller { - uint2 data(); - void latch(bool data); - Mouse(bool port); -- -+ void serialize(serializer& s); - private: - bool latched; - unsigned counter; -diff --git a/snes/controller/multitap/multitap.cpp b/snes/controller/multitap/multitap.cpp -index 3a6eb72..146c41d 100755 ---- snes/controller/multitap/multitap.cpp -+++ snes/controller/multitap/multitap.cpp -@@ -30,6 +30,22 @@ void Multitap::latch(bool data) { - counter2 = 0; - } - -+void Multitap::serialize(serializer& s) { -+ Processor::serialize(s); -+ //Save block. -+ unsigned char block[Controller::SaveSize] = {0}; -+ block[0] = latched ? 1 : 0; -+ block[1] = counter1; -+ block[2] = counter2; -+ s.array(block, Controller::SaveSize); -+ if(s.mode() == nall::serializer::Load) { -+ latched = (block[0] != 0); -+ counter1 = block[1]; -+ counter2 = block[2]; -+ } -+} -+ -+ - Multitap::Multitap(bool port) : Controller(port) { - latched = 0; - counter1 = 0; -diff --git a/snes/controller/multitap/multitap.hpp b/snes/controller/multitap/multitap.hpp -index 0540af7..e6324ac 100755 ---- snes/controller/multitap/multitap.hpp -+++ snes/controller/multitap/multitap.hpp -@@ -2,7 +2,7 @@ struct Multitap : Controller { - uint2 data(); - void latch(bool data); - Multitap(bool port); -- -+ void serialize(serializer& s); - private: - bool latched; - unsigned counter1; -diff --git a/snes/controller/superscope/superscope.cpp b/snes/controller/superscope/superscope.cpp -index 12068f0..1a1dfbf 100755 ---- snes/controller/superscope/superscope.cpp -+++ snes/controller/superscope/superscope.cpp -@@ -100,6 +100,37 @@ void SuperScope::latch(bool data) { - counter = 0; - } - -+void SuperScope::serialize(serializer& s) { -+ Processor::serialize(s); -+ //Save block. -+ unsigned char block[Controller::SaveSize] = {0}; -+ block[0] = latched ? 1 : 0; -+ block[1] = counter; -+ block[2] = trigger ? 1 : 0; -+ block[3] = cursor ? 1 : 0; -+ block[4] = turbo ? 1 : 0; -+ block[5] = pause ? 1 : 0; -+ block[6] = offscreen ? 1 : 0; -+ block[7] = (unsigned short)x >> 8; -+ block[8] = (unsigned short)x; -+ block[9] = (unsigned short)y >> 8; -+ block[10] = (unsigned short)y; -+ -+ s.array(block, Controller::SaveSize); -+ if(s.mode() == nall::serializer::Load) { -+ latched = (block[0] != 0); -+ counter = block[1]; -+ trigger = (block[2] != 0); -+ cursor = (block[3] != 0); -+ turbo = (block[4] != 0); -+ pause = (block[5] != 0); -+ offscreen = (block[6] != 0); -+ x = (short)(((unsigned short)block[7] << 8) | (unsigned short)block[8]); -+ y = (short)(((unsigned short)block[9] << 8) | (unsigned short)block[10]); -+ } -+} -+ -+ - SuperScope::SuperScope(bool port) : Controller(port) { - create(Controller::Enter, 21477272); - latched = 0; -diff --git a/snes/controller/superscope/superscope.hpp b/snes/controller/superscope/superscope.hpp -index a7a90b7..93509d7 100755 ---- snes/controller/superscope/superscope.hpp -+++ snes/controller/superscope/superscope.hpp -@@ -2,6 +2,7 @@ struct SuperScope : Controller { - void enter(); - uint2 data(); - void latch(bool data); -+ void serialize(serializer& s); - SuperScope(bool port); - - //private: -diff --git a/snes/system/input.cpp b/snes/system/input.cpp -index 894de0e..4479acc 100755 ---- snes/system/input.cpp -+++ snes/system/input.cpp -@@ -26,6 +26,22 @@ void Input::connect(bool port, Input::Device id) { - } - } - -+void Input::serialize(serializer &s) -+{ -+ int p1, p2; -+ p1 = (int)config.controller_port1; -+ p2 = (int)config.controller_port2; -+ s.integer(p1); -+ s.integer(p2); -+ if(s.mode() == nall::serializer::Load) { -+ connect(Controller::Port1, (Device)p1); -+ connect(Controller::Port2, (Device)p2); -+ } -+ port1->serialize(s); -+ port2->serialize(s); -+} -+ -+ - Input::Input() : port1(nullptr), port2(nullptr) { - connect(Controller::Port1, Input::Device::Joypad); - connect(Controller::Port2, Input::Device::Joypad); -diff --git a/snes/system/input.hpp b/snes/system/input.hpp -index 7a6bd9e..d2f5fef 100755 ---- snes/system/input.hpp -+++ snes/system/input.hpp -@@ -31,6 +31,7 @@ struct Input { - Controller *port1; - Controller *port2; - -+ void serialize(serializer &s); - void connect(bool port, Input::Device id); - Input(); - ~Input(); -diff --git a/snes/system/serialization.cpp b/snes/system/serialization.cpp -index f746c3a..67e08a2 100755 ---- snes/system/serialization.cpp -+++ snes/system/serialization.cpp -@@ -56,6 +56,7 @@ void System::serialize_all(serializer &s) { - smp.serialize(s); - ppu.serialize(s); - dsp.serialize(s); -+ input.serialize(s); - - if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.serialize(s); - #if defined(GAMEBOY) --- -1.7.9.48.g85da4d - +From fe11984ad18561506a7cc874cb7c0421f1e21ad1 Mon Sep 17 00:00:00 2001 +From: Ilari Liusvaara +Date: Wed, 9 Nov 2011 01:52:08 +0200 +Subject: [PATCH 2/4] Save controller state when savestating + +When savestating, save the controller state and restore it upon loadstate. +Prevents libsnes from mixing up buttons. +--- + snes/controller/controller.cpp | 8 ++++++ + snes/controller/controller.hpp | 2 + + snes/controller/gamepad/gamepad.cpp | 13 ++++++++++ + snes/controller/gamepad/gamepad.hpp | 2 +- + snes/controller/justifier/justifier.cpp | 36 +++++++++++++++++++++++++++++ + snes/controller/justifier/justifier.hpp | 1 + + snes/controller/mouse/mouse.cpp | 13 ++++++++++ + snes/controller/mouse/mouse.hpp | 2 +- + snes/controller/multitap/multitap.cpp | 16 +++++++++++++ + snes/controller/multitap/multitap.hpp | 2 +- + snes/controller/superscope/superscope.cpp | 31 +++++++++++++++++++++++++ + snes/controller/superscope/superscope.hpp | 1 + + snes/system/input.cpp | 16 +++++++++++++ + snes/system/input.hpp | 1 + + snes/system/serialization.cpp | 1 + + 15 files changed, 142 insertions(+), 3 deletions(-) + +diff --git a/snes/controller/controller.cpp b/snes/controller/controller.cpp +index fa8e07d..5f37849 100755 +--- snes/controller/controller.cpp ++++ snes/controller/controller.cpp +@@ -46,8 +46,16 @@ void Controller::iobit(bool data) { + } + } + ++void Controller::serialize(serializer& s) { ++ Processor::serialize(s); ++ //Save a zero block. ++ unsigned char blockzeroes[SaveSize] = {0}; ++ s.array(blockzeroes, SaveSize); ++} ++ + Controller::Controller(bool port) : port(port) { + if(!thread) create(Controller::Enter, 1); + } + ++ + } +diff --git a/snes/controller/controller.hpp b/snes/controller/controller.hpp +index dd748a1..46095a8 100755 +--- snes/controller/controller.hpp ++++ snes/controller/controller.hpp +@@ -13,12 +13,14 @@ + + struct Controller : Processor { + enum : bool { Port1 = 0, Port2 = 1 }; ++ enum { SaveSize = 16 }; + const bool port; + + static void Enter(); + virtual void enter(); + void step(unsigned clocks); + void synchronize_cpu(); ++ virtual void serialize(serializer& s); + + bool iobit(); + void iobit(bool data); +diff --git a/snes/controller/gamepad/gamepad.cpp b/snes/controller/gamepad/gamepad.cpp +index 594020d..4fa1c99 100755 +--- snes/controller/gamepad/gamepad.cpp ++++ snes/controller/gamepad/gamepad.cpp +@@ -13,6 +13,19 @@ void Gamepad::latch(bool data) { + counter = 0; + } + ++void Gamepad::serialize(serializer& s) { ++ Processor::serialize(s); ++ //Save block. ++ unsigned char block[Controller::SaveSize] = {0}; ++ block[0] = latched ? 1 : 0; ++ block[1] = counter; ++ s.array(block, Controller::SaveSize); ++ if(s.mode() == nall::serializer::Load) { ++ latched = (block[0] != 0); ++ counter = block[1]; ++ } ++} ++ + Gamepad::Gamepad(bool port) : Controller(port) { + latched = 0; + counter = 0; +diff --git a/snes/controller/gamepad/gamepad.hpp b/snes/controller/gamepad/gamepad.hpp +index c5ca69c..a2392d1 100755 +--- snes/controller/gamepad/gamepad.hpp ++++ snes/controller/gamepad/gamepad.hpp +@@ -2,7 +2,7 @@ struct Gamepad : Controller { + uint2 data(); + void latch(bool data); + Gamepad(bool port); +- ++ void serialize(serializer& s); + private: + bool latched; + unsigned counter; +diff --git a/snes/controller/justifier/justifier.cpp b/snes/controller/justifier/justifier.cpp +index 6207916..ad13a9b 100755 +--- snes/controller/justifier/justifier.cpp ++++ snes/controller/justifier/justifier.cpp +@@ -100,6 +100,42 @@ void Justifier::latch(bool data) { + if(latched == 0) active = !active; //toggle between both controllers, even when unchained + } + ++void Justifier::serialize(serializer& s) { ++ Processor::serialize(s); ++ //Save block. ++ unsigned char block[Controller::SaveSize] = {0}; ++ block[0] = latched ? 1 : 0; ++ block[1] = counter; ++ block[2] = active ? 1 : 0; ++ block[3] = player1.trigger ? 1 : 0; ++ block[4] = player2.trigger ? 1 : 0; ++ block[5] = player1.start ? 1 : 0; ++ block[6] = player2.start ? 1 : 0; ++ block[7] = (unsigned short)player1.x >> 8; ++ block[8] = (unsigned short)player1.x; ++ block[9] = (unsigned short)player2.x >> 8; ++ block[10] = (unsigned short)player2.x; ++ block[11] = (unsigned short)player1.y >> 8; ++ block[12] = (unsigned short)player1.y; ++ block[13] = (unsigned short)player2.y >> 8; ++ block[14] = (unsigned short)player2.y; ++ s.array(block, Controller::SaveSize); ++ if(s.mode() == nall::serializer::Load) { ++ latched = (block[0] != 0); ++ counter = block[1]; ++ active = (block[2] != 0); ++ player1.trigger = (block[3] != 0); ++ player2.trigger = (block[4] != 0); ++ player1.start = (block[5] != 0); ++ player2.start = (block[6] != 0); ++ player1.x = (short)(((unsigned short)block[7] << 8) | (unsigned short)block[8]); ++ player2.x = (short)(((unsigned short)block[9] << 8) | (unsigned short)block[10]); ++ player1.y = (short)(((unsigned short)block[11] << 8) | (unsigned short)block[12]); ++ player2.y = (short)(((unsigned short)block[13] << 8) | (unsigned short)block[14]); ++ } ++} ++ ++ + Justifier::Justifier(bool port, bool chained) : Controller(port), chained(chained) { + create(Controller::Enter, 21477272); + latched = 0; +diff --git a/snes/controller/justifier/justifier.hpp b/snes/controller/justifier/justifier.hpp +index f927acf..6b7bba0 100755 +--- snes/controller/justifier/justifier.hpp ++++ snes/controller/justifier/justifier.hpp +@@ -2,6 +2,7 @@ struct Justifier : Controller { + void enter(); + uint2 data(); + void latch(bool data); ++ void serialize(serializer& s); + Justifier(bool port, bool chained); + + //private: +diff --git a/snes/controller/mouse/mouse.cpp b/snes/controller/mouse/mouse.cpp +index c9f5d16..6b26fae 100755 +--- snes/controller/mouse/mouse.cpp ++++ snes/controller/mouse/mouse.cpp +@@ -61,6 +61,19 @@ void Mouse::latch(bool data) { + counter = 0; + } + ++void Mouse::serialize(serializer& s) { ++ Processor::serialize(s); ++ //Save block. ++ unsigned char block[Controller::SaveSize] = {0}; ++ block[0] = latched ? 1 : 0; ++ block[1] = counter; ++ s.array(block, Controller::SaveSize); ++ if(s.mode() == nall::serializer::Load) { ++ latched = (block[0] != 0); ++ counter = block[1]; ++ } ++} ++ + Mouse::Mouse(bool port) : Controller(port) { + latched = 0; + counter = 0; +diff --git a/snes/controller/mouse/mouse.hpp b/snes/controller/mouse/mouse.hpp +index 95e24b6..b66ea51 100755 +--- snes/controller/mouse/mouse.hpp ++++ snes/controller/mouse/mouse.hpp +@@ -2,7 +2,7 @@ struct Mouse : Controller { + uint2 data(); + void latch(bool data); + Mouse(bool port); +- ++ void serialize(serializer& s); + private: + bool latched; + unsigned counter; +diff --git a/snes/controller/multitap/multitap.cpp b/snes/controller/multitap/multitap.cpp +index 3a6eb72..146c41d 100755 +--- snes/controller/multitap/multitap.cpp ++++ snes/controller/multitap/multitap.cpp +@@ -30,6 +30,22 @@ void Multitap::latch(bool data) { + counter2 = 0; + } + ++void Multitap::serialize(serializer& s) { ++ Processor::serialize(s); ++ //Save block. ++ unsigned char block[Controller::SaveSize] = {0}; ++ block[0] = latched ? 1 : 0; ++ block[1] = counter1; ++ block[2] = counter2; ++ s.array(block, Controller::SaveSize); ++ if(s.mode() == nall::serializer::Load) { ++ latched = (block[0] != 0); ++ counter1 = block[1]; ++ counter2 = block[2]; ++ } ++} ++ ++ + Multitap::Multitap(bool port) : Controller(port) { + latched = 0; + counter1 = 0; +diff --git a/snes/controller/multitap/multitap.hpp b/snes/controller/multitap/multitap.hpp +index 0540af7..e6324ac 100755 +--- snes/controller/multitap/multitap.hpp ++++ snes/controller/multitap/multitap.hpp +@@ -2,7 +2,7 @@ struct Multitap : Controller { + uint2 data(); + void latch(bool data); + Multitap(bool port); +- ++ void serialize(serializer& s); + private: + bool latched; + unsigned counter1; +diff --git a/snes/controller/superscope/superscope.cpp b/snes/controller/superscope/superscope.cpp +index 12068f0..1a1dfbf 100755 +--- snes/controller/superscope/superscope.cpp ++++ snes/controller/superscope/superscope.cpp +@@ -100,6 +100,37 @@ void SuperScope::latch(bool data) { + counter = 0; + } + ++void SuperScope::serialize(serializer& s) { ++ Processor::serialize(s); ++ //Save block. ++ unsigned char block[Controller::SaveSize] = {0}; ++ block[0] = latched ? 1 : 0; ++ block[1] = counter; ++ block[2] = trigger ? 1 : 0; ++ block[3] = cursor ? 1 : 0; ++ block[4] = turbo ? 1 : 0; ++ block[5] = pause ? 1 : 0; ++ block[6] = offscreen ? 1 : 0; ++ block[7] = (unsigned short)x >> 8; ++ block[8] = (unsigned short)x; ++ block[9] = (unsigned short)y >> 8; ++ block[10] = (unsigned short)y; ++ ++ s.array(block, Controller::SaveSize); ++ if(s.mode() == nall::serializer::Load) { ++ latched = (block[0] != 0); ++ counter = block[1]; ++ trigger = (block[2] != 0); ++ cursor = (block[3] != 0); ++ turbo = (block[4] != 0); ++ pause = (block[5] != 0); ++ offscreen = (block[6] != 0); ++ x = (short)(((unsigned short)block[7] << 8) | (unsigned short)block[8]); ++ y = (short)(((unsigned short)block[9] << 8) | (unsigned short)block[10]); ++ } ++} ++ ++ + SuperScope::SuperScope(bool port) : Controller(port) { + create(Controller::Enter, 21477272); + latched = 0; +diff --git a/snes/controller/superscope/superscope.hpp b/snes/controller/superscope/superscope.hpp +index a7a90b7..93509d7 100755 +--- snes/controller/superscope/superscope.hpp ++++ snes/controller/superscope/superscope.hpp +@@ -2,6 +2,7 @@ struct SuperScope : Controller { + void enter(); + uint2 data(); + void latch(bool data); ++ void serialize(serializer& s); + SuperScope(bool port); + + //private: +diff --git a/snes/system/input.cpp b/snes/system/input.cpp +index 894de0e..4479acc 100755 +--- snes/system/input.cpp ++++ snes/system/input.cpp +@@ -26,6 +26,22 @@ void Input::connect(bool port, Input::Device id) { + } + } + ++void Input::serialize(serializer &s) ++{ ++ int p1, p2; ++ p1 = (int)config.controller_port1; ++ p2 = (int)config.controller_port2; ++ s.integer(p1); ++ s.integer(p2); ++ if(s.mode() == nall::serializer::Load) { ++ connect(Controller::Port1, (Device)p1); ++ connect(Controller::Port2, (Device)p2); ++ } ++ port1->serialize(s); ++ port2->serialize(s); ++} ++ ++ + Input::Input() : port1(nullptr), port2(nullptr) { + connect(Controller::Port1, Input::Device::Joypad); + connect(Controller::Port2, Input::Device::Joypad); +diff --git a/snes/system/input.hpp b/snes/system/input.hpp +index 7a6bd9e..d2f5fef 100755 +--- snes/system/input.hpp ++++ snes/system/input.hpp +@@ -31,6 +31,7 @@ struct Input { + Controller *port1; + Controller *port2; + ++ void serialize(serializer &s); + void connect(bool port, Input::Device id); + Input(); + ~Input(); +diff --git a/snes/system/serialization.cpp b/snes/system/serialization.cpp +index f746c3a..67e08a2 100755 +--- snes/system/serialization.cpp ++++ snes/system/serialization.cpp +@@ -56,6 +56,7 @@ void System::serialize_all(serializer &s) { + smp.serialize(s); + ppu.serialize(s); + dsp.serialize(s); ++ input.serialize(s); + + if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.serialize(s); + #if defined(GAMEBOY) +-- +1.7.9.48.g85da4d + diff --git a/libsnes/lsnes_patches/0003-Allow-frontend-to-control-random-number-seed.patch b/waterbox/libsnes/lsnes_patches/0003-Allow-frontend-to-control-random-number-seed.patch similarity index 96% rename from libsnes/lsnes_patches/0003-Allow-frontend-to-control-random-number-seed.patch rename to waterbox/libsnes/lsnes_patches/0003-Allow-frontend-to-control-random-number-seed.patch index f6feec1d12..828e83a810 100644 --- a/libsnes/lsnes_patches/0003-Allow-frontend-to-control-random-number-seed.patch +++ b/waterbox/libsnes/lsnes_patches/0003-Allow-frontend-to-control-random-number-seed.patch @@ -1,53 +1,53 @@ -From 5f76449a70c9a546e18c2fdebe7588bbe90b56d2 Mon Sep 17 00:00:00 2001 -From: Ilari Liusvaara -Date: Fri, 11 Nov 2011 19:49:46 +0200 -Subject: [PATCH 3/4] Allow frontend to control random number seed - ---- - snes/interface/interface.cpp | 5 +++++ - snes/interface/interface.hpp | 1 + - snes/system/system.cpp | 2 +- - 3 files changed, 7 insertions(+), 1 deletions(-) - -diff --git a/snes/interface/interface.cpp b/snes/interface/interface.cpp -index b3017c9..0a21a13 100755 ---- snes/interface/interface.cpp -+++ snes/interface/interface.cpp -@@ -23,4 +23,9 @@ time_t Interface::currentTime() - return time(0); - } - -+time_t Interface::randomSeed() -+{ -+ return time(0); -+} -+ - } -diff --git a/snes/interface/interface.hpp b/snes/interface/interface.hpp -index df975e8..30ee7fd 100755 ---- snes/interface/interface.hpp -+++ snes/interface/interface.hpp -@@ -6,6 +6,7 @@ struct Interface { - virtual string path(Cartridge::Slot slot, const string &hint) = 0; - virtual void message(const string &text); - virtual time_t currentTime(); -+ virtual time_t randomSeed(); - }; - - extern Interface *interface; -diff --git a/snes/system/system.cpp b/snes/system/system.cpp -index 9b70bbf..cbd096c 100755 ---- snes/system/system.cpp -+++ snes/system/system.cpp -@@ -151,7 +151,7 @@ void System::unload() { - } - - void System::power() { -- random.seed((unsigned)time(0)); -+ random.seed((unsigned)interface->randomSeed()); - - region = config.region; - expansion = config.expansion_port; --- -1.7.9.48.g85da4d - +From 5f76449a70c9a546e18c2fdebe7588bbe90b56d2 Mon Sep 17 00:00:00 2001 +From: Ilari Liusvaara +Date: Fri, 11 Nov 2011 19:49:46 +0200 +Subject: [PATCH 3/4] Allow frontend to control random number seed + +--- + snes/interface/interface.cpp | 5 +++++ + snes/interface/interface.hpp | 1 + + snes/system/system.cpp | 2 +- + 3 files changed, 7 insertions(+), 1 deletions(-) + +diff --git a/snes/interface/interface.cpp b/snes/interface/interface.cpp +index b3017c9..0a21a13 100755 +--- snes/interface/interface.cpp ++++ snes/interface/interface.cpp +@@ -23,4 +23,9 @@ time_t Interface::currentTime() + return time(0); + } + ++time_t Interface::randomSeed() ++{ ++ return time(0); ++} ++ + } +diff --git a/snes/interface/interface.hpp b/snes/interface/interface.hpp +index df975e8..30ee7fd 100755 +--- snes/interface/interface.hpp ++++ snes/interface/interface.hpp +@@ -6,6 +6,7 @@ struct Interface { + virtual string path(Cartridge::Slot slot, const string &hint) = 0; + virtual void message(const string &text); + virtual time_t currentTime(); ++ virtual time_t randomSeed(); + }; + + extern Interface *interface; +diff --git a/snes/system/system.cpp b/snes/system/system.cpp +index 9b70bbf..cbd096c 100755 +--- snes/system/system.cpp ++++ snes/system/system.cpp +@@ -151,7 +151,7 @@ void System::unload() { + } + + void System::power() { +- random.seed((unsigned)time(0)); ++ random.seed((unsigned)interface->randomSeed()); + + region = config.region; + expansion = config.expansion_port; +-- +1.7.9.48.g85da4d + diff --git a/libsnes/lsnes_patches/0004-Fix-mouse-polling.patch b/waterbox/libsnes/lsnes_patches/0004-Fix-mouse-polling.patch similarity index 97% rename from libsnes/lsnes_patches/0004-Fix-mouse-polling.patch rename to waterbox/libsnes/lsnes_patches/0004-Fix-mouse-polling.patch index 8fb4e43fe9..bdecda2782 100644 --- a/libsnes/lsnes_patches/0004-Fix-mouse-polling.patch +++ b/waterbox/libsnes/lsnes_patches/0004-Fix-mouse-polling.patch @@ -1,60 +1,60 @@ -From 160dedf35571478781737ee35307b9321cfb41bb Mon Sep 17 00:00:00 2001 -From: Ilari Liusvaara -Date: Wed, 7 Mar 2012 16:57:18 +0200 -Subject: [PATCH 4/4] Fix mouse polling - -Don't poll for mouse motion excessive number of times (no need to poll it for -each bit!) ---- - snes/controller/mouse/mouse.cpp | 12 ++++++++++-- - snes/controller/mouse/mouse.hpp | 2 ++ - 2 files changed, 12 insertions(+), 2 deletions(-) - -diff --git a/snes/controller/mouse/mouse.cpp b/snes/controller/mouse/mouse.cpp -index 6b26fae..824ecd3 100755 ---- snes/controller/mouse/mouse.cpp -+++ snes/controller/mouse/mouse.cpp -@@ -3,8 +3,10 @@ - uint2 Mouse::data() { - if(counter >= 32) return 1; - -- int position_x = interface->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::X); //-n = left, 0 = center, +n = right -- int position_y = interface->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::Y); //-n = up, 0 = center, +n = down -+ if(counter == 0) { -+ position_x = interface->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::X); //-n = left, 0 = center, +n = right -+ position_y = interface->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::Y); //-n = up, 0 = center, +n = down -+ } - - bool direction_x = position_x < 0; //0 = right, 1 = left - bool direction_y = position_y < 0; //0 = down, 1 = up -@@ -67,10 +69,16 @@ void Mouse::serialize(serializer& s) { - unsigned char block[Controller::SaveSize] = {0}; - block[0] = latched ? 1 : 0; - block[1] = counter; -+ block[2] = (unsigned short)position_x >> 8; -+ block[3] = (unsigned short)position_x; -+ block[4] = (unsigned short)position_y >> 8; -+ block[5] = (unsigned short)position_y; - s.array(block, Controller::SaveSize); - if(s.mode() == nall::serializer::Load) { - latched = (block[0] != 0); - counter = block[1]; -+ position_x = (short)(((unsigned short)block[2] << 8) | (unsigned short)block[3]); -+ position_y = (short)(((unsigned short)block[4] << 8) | (unsigned short)block[5]); - } - } - -diff --git a/snes/controller/mouse/mouse.hpp b/snes/controller/mouse/mouse.hpp -index b66ea51..6074f34 100755 ---- snes/controller/mouse/mouse.hpp -+++ snes/controller/mouse/mouse.hpp -@@ -6,4 +6,6 @@ struct Mouse : Controller { - private: - bool latched; - unsigned counter; -+ int position_x; -+ int position_y; - }; --- -1.7.9.48.g85da4d - +From 160dedf35571478781737ee35307b9321cfb41bb Mon Sep 17 00:00:00 2001 +From: Ilari Liusvaara +Date: Wed, 7 Mar 2012 16:57:18 +0200 +Subject: [PATCH 4/4] Fix mouse polling + +Don't poll for mouse motion excessive number of times (no need to poll it for +each bit!) +--- + snes/controller/mouse/mouse.cpp | 12 ++++++++++-- + snes/controller/mouse/mouse.hpp | 2 ++ + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/snes/controller/mouse/mouse.cpp b/snes/controller/mouse/mouse.cpp +index 6b26fae..824ecd3 100755 +--- snes/controller/mouse/mouse.cpp ++++ snes/controller/mouse/mouse.cpp +@@ -3,8 +3,10 @@ + uint2 Mouse::data() { + if(counter >= 32) return 1; + +- int position_x = interface->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::X); //-n = left, 0 = center, +n = right +- int position_y = interface->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::Y); //-n = up, 0 = center, +n = down ++ if(counter == 0) { ++ position_x = interface->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::X); //-n = left, 0 = center, +n = right ++ position_y = interface->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::Y); //-n = up, 0 = center, +n = down ++ } + + bool direction_x = position_x < 0; //0 = right, 1 = left + bool direction_y = position_y < 0; //0 = down, 1 = up +@@ -67,10 +69,16 @@ void Mouse::serialize(serializer& s) { + unsigned char block[Controller::SaveSize] = {0}; + block[0] = latched ? 1 : 0; + block[1] = counter; ++ block[2] = (unsigned short)position_x >> 8; ++ block[3] = (unsigned short)position_x; ++ block[4] = (unsigned short)position_y >> 8; ++ block[5] = (unsigned short)position_y; + s.array(block, Controller::SaveSize); + if(s.mode() == nall::serializer::Load) { + latched = (block[0] != 0); + counter = block[1]; ++ position_x = (short)(((unsigned short)block[2] << 8) | (unsigned short)block[3]); ++ position_y = (short)(((unsigned short)block[4] << 8) | (unsigned short)block[5]); + } + } + +diff --git a/snes/controller/mouse/mouse.hpp b/snes/controller/mouse/mouse.hpp +index b66ea51..6074f34 100755 +--- snes/controller/mouse/mouse.hpp ++++ snes/controller/mouse/mouse.hpp +@@ -6,4 +6,6 @@ struct Mouse : Controller { + private: + bool latched; + unsigned counter; ++ int position_x; ++ int position_y; + }; +-- +1.7.9.48.g85da4d + diff --git a/waterbox/ngp/.vscode/settings.json b/waterbox/ngp/.vscode/settings.json new file mode 100644 index 0000000000..3e56d7d118 --- /dev/null +++ b/waterbox/ngp/.vscode/settings.json @@ -0,0 +1,13 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "editor.insertSpaces": false, + "editor.detectIndentation": false, + "files.associations": { + "algorithm": "cpp", + "vector": "cpp", + "xstring": "cpp", + "xutility": "cpp", + "xmemory0": "cpp", + "iosfwd": "cpp" + } +} \ No newline at end of file diff --git a/waterbox/ngp/Makefile b/waterbox/ngp/Makefile new file mode 100644 index 0000000000..fe067ba74b --- /dev/null +++ b/waterbox/ngp/Makefile @@ -0,0 +1,44 @@ +CC = x86_64-nt64-midipix-g++ + +CCFLAGS:= -I. -I../emulibc \ + -Wall -Werror=pointer-to-int-cast -Werror=int-to-pointer-cast -Werror=implicit-function-declaration \ + -std=c++0x -fomit-frame-pointer -fvisibility=hidden -fno-exceptions -fno-rtti \ + -DLSB_FIRST \ + -O3 -flto + +TARGET = ngp.wbx + +LDFLAGS = -Wl,--dynamicbase,--export-all-symbols + +ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) +SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.cpp') +OBJ_DIR:=$(ROOT_DIR)/obj + +_OBJS:=$(SRCS:.cpp=.o) +OBJS:=$(patsubst $(ROOT_DIR)%,$(OBJ_DIR)%,$(_OBJS)) + +$(OBJ_DIR)/%.o: %.cpp + @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) + +print-%: + @echo $* = $($*) + +#install: +# $(CP) $(TARGET) $(DEST_$(ARCH)) diff --git a/waterbox/ngp/T6W28_Apu.cpp b/waterbox/ngp/T6W28_Apu.cpp new file mode 100644 index 0000000000..ccc6452d98 --- /dev/null +++ b/waterbox/ngp/T6W28_Apu.cpp @@ -0,0 +1,422 @@ +// T6W28_Snd_Emu + +#include "defs.h" +#include "T6W28_Apu.h" + +/* Copyright (C) 2003-2006 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. You should have received a copy of the GNU Lesser General +Public License along with this module; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +// T6W28_Osc + +namespace MDFN_IEN_NGP +{ + +T6W28_Osc::T6W28_Osc() +{ + outputs[0] = NULL; // always stays NULL + outputs[1] = NULL; + outputs[2] = NULL; + outputs[3] = NULL; +} + +void T6W28_Osc::reset() +{ + delay = 0; + last_amp_left = 0; + last_amp_right = 0; + + volume_left = 0; + volume_right = 0; +} + +// T6W28_Square + +blip_inline void T6W28_Square::reset() +{ + period = 0; + phase = 0; + T6W28_Osc::reset(); +} + +void T6W28_Square::run(sms_time_t time, sms_time_t end_time) +{ + if ((!volume_left && !volume_right) || period <= 128) + { + // ignore 16kHz and higher + if (last_amp_left) + { + synth->offset(time, -last_amp_left, outputs[2]); + last_amp_left = 0; + } + + if (last_amp_right) + { + synth->offset(time, -last_amp_right, outputs[1]); + last_amp_right = 0; + } + + time += delay; + if (!period) + { + time = end_time; + } + else if (time < end_time) + { + // keep calculating phase + int count = (end_time - time + period - 1) / period; + phase = (phase + count) & 1; + time += count * period; + } + } + else + { + int amp_left = phase ? volume_left : -volume_left; + int amp_right = phase ? volume_right : -volume_right; + + { + int delta_left = amp_left - last_amp_left; + int delta_right = amp_right - last_amp_right; + + if (delta_left) + { + last_amp_left = amp_left; + synth->offset(time, delta_left, outputs[2]); + } + + if (delta_right) + { + last_amp_right = amp_right; + synth->offset(time, delta_right, outputs[1]); + } + } + + time += delay; + if (time < end_time) + { + Blip_Buffer *const output_left = this->outputs[2]; + Blip_Buffer *const output_right = this->outputs[1]; + + int delta_left = amp_left * 2; + int delta_right = amp_right * 2; + do + { + delta_left = -delta_left; + delta_right = -delta_right; + + synth->offset_inline(time, delta_left, output_left); + synth->offset_inline(time, delta_right, output_right); + time += period; + phase ^= 1; + } while (time < end_time); + + this->last_amp_left = phase ? volume_left : -volume_left; + this->last_amp_right = phase ? volume_right : -volume_right; + } + } + delay = time - end_time; +} + +// T6W28_Noise + +static const int noise_periods[3] = {0x100, 0x200, 0x400}; + +blip_inline void T6W28_Noise::reset() +{ + period = &noise_periods[0]; + shifter = 0x4000; + tap = 13; + T6W28_Osc::reset(); +} + +void T6W28_Noise::run(sms_time_t time, sms_time_t end_time) +{ + int amp_left = volume_left; + int amp_right = volume_right; + + if (shifter & 1) + { + amp_left = -amp_left; + amp_right = -amp_right; + } + + { + int delta_left = amp_left - last_amp_left; + int delta_right = amp_right - last_amp_right; + + if (delta_left) + { + last_amp_left = amp_left; + synth.offset(time, delta_left, outputs[2]); + } + + if (delta_right) + { + last_amp_right = amp_right; + synth.offset(time, delta_right, outputs[1]); + } + } + + time += delay; + + if (!volume_left && !volume_right) + time = end_time; + + if (time < end_time) + { + Blip_Buffer *const output_left = this->outputs[2]; + Blip_Buffer *const output_right = this->outputs[1]; + + unsigned l_shifter = this->shifter; + int delta_left = amp_left * 2; + int delta_right = amp_right * 2; + + int l_period = *this->period * 2; + if (!l_period) + l_period = 16; + + do + { + int changed = (l_shifter + 1) & 2; // set if prev and next bits differ + l_shifter = (((l_shifter << 14) ^ (l_shifter << tap)) & 0x4000) | (l_shifter >> 1); + if (changed) + { + delta_left = -delta_left; + synth.offset_inline(time, delta_left, output_left); + + delta_right = -delta_right; + synth.offset_inline(time, delta_right, output_right); + } + time += l_period; + } while (time < end_time); + + this->shifter = l_shifter; + this->last_amp_left = delta_left >> 1; + this->last_amp_right = delta_right >> 1; + } + delay = time - end_time; +} + +// T6W28_Apu + +T6W28_Apu::T6W28_Apu() +{ + for (int i = 0; i < 3; i++) + { + squares[i].synth = &square_synth; + oscs[i] = &squares[i]; + } + oscs[3] = &noise; + + volume(1.0); + reset(); +} + +T6W28_Apu::~T6W28_Apu() +{ +} + +void T6W28_Apu::volume(double vol) +{ + vol *= 0.85 / (osc_count * 64 * 2); + square_synth.volume(vol); + noise.synth.volume(vol); +} + +void T6W28_Apu::treble_eq(const blip_eq_t &eq) +{ + square_synth.treble_eq(eq); + noise.synth.treble_eq(eq); +} + +void T6W28_Apu::osc_output(int index, Blip_Buffer *center, Blip_Buffer *left, Blip_Buffer *right) +{ + require((unsigned)index < osc_count); + require((center && left && right) || (!center && !left && !right)); + T6W28_Osc &osc = *oscs[index]; + osc.outputs[1] = right; + osc.outputs[2] = left; + osc.outputs[3] = center; +} + +void T6W28_Apu::output(Blip_Buffer *center, Blip_Buffer *left, Blip_Buffer *right) +{ + for (int i = 0; i < osc_count; i++) + osc_output(i, center, left, right); +} + +void T6W28_Apu::reset() +{ + last_time = 0; + latch_left = 0; + latch_right = 0; + + squares[0].reset(); + squares[1].reset(); + squares[2].reset(); + noise.reset(); +} + +void T6W28_Apu::run_until(sms_time_t end_time) +{ + require(end_time >= last_time); // end_time must not be before previous time + + if (end_time > last_time) + { + // run oscillators + for (int i = 0; i < osc_count; ++i) + { + T6W28_Osc &osc = *oscs[i]; + if (osc.outputs[1]) + { + if (i < 3) + squares[i].run(last_time, end_time); + else + noise.run(last_time, end_time); + } + } + + last_time = end_time; + } +} + +bool T6W28_Apu::end_frame(sms_time_t end_time) +{ + if (end_time > last_time) + run_until(end_time); + + assert(last_time >= end_time); + last_time -= end_time; + + return (1); +} + +static const unsigned char volumes[16] = { + // volumes [i] = 64 * pow( 1.26, 15 - i ) / pow( 1.26, 15 ) + 64, 50, 39, 31, 24, 19, 15, 12, 9, 7, 5, 4, 3, 2, 1, 0}; + +void T6W28_Apu::write_data_left(sms_time_t time, int data) +{ + require((unsigned)data <= 0xFF); + + run_until(time); + + if (data & 0x80) + latch_left = data; + + int index = (latch_left >> 5) & 3; + + if (latch_left & 0x10) + { + oscs[index]->volume_left = volumes[data & 15]; + } + else if (index < 3) + { + T6W28_Square &sq = squares[index]; + if (data & 0x80) + sq.period = (sq.period & 0xFF00) | (data << 4 & 0x00FF); + else + sq.period = (sq.period & 0x00FF) | (data << 8 & 0x3F00); + } +} + +void T6W28_Apu::write_data_right(sms_time_t time, int data) +{ + require((unsigned)data <= 0xFF); + + run_until(time); + + if (data & 0x80) + latch_right = data; + + int index = (latch_right >> 5) & 3; + //printf("%d\n", index); + + if (latch_right & 0x10) + { + oscs[index]->volume_right = volumes[data & 15]; + } + else if (index == 2) + { + if (data & 0x80) + noise.period_extra = (noise.period_extra & 0xFF00) | (data << 4 & 0x00FF); + else + noise.period_extra = (noise.period_extra & 0x00FF) | (data << 8 & 0x3F00); + } + else if (index == 3) + { + int select = data & 3; + if (select < 3) + noise.period = &noise_periods[select]; + else + noise.period = &noise.period_extra; + + int const tap_disabled = 16; + noise.tap = (data & 0x04) ? 13 : tap_disabled; + noise.shifter = 0x4000; + } +} + +void T6W28_Apu::save_state(T6W28_ApuState *ret) +{ + for (int x = 0; x < 4; x++) + { + ret->volume_left[x] = oscs[x]->volume_left; + ret->volume_right[x] = oscs[x]->volume_right; + } + for (int x = 0; x < 3; x++) + { + ret->sq_period[x] = squares[x].period; + ret->sq_phase[x] = squares[x].phase; + } + ret->noise_shifter = noise.shifter; + ret->noise_tap = noise.tap; + ret->noise_period_extra = noise.period_extra; + + if (noise.period == &noise_periods[0]) + ret->noise_period = 0; + else if (noise.period == &noise_periods[1]) + ret->noise_period = 1; + else if (noise.period == &noise_periods[2]) + ret->noise_period = 2; + else + ret->noise_period = 3; + + ret->latch_left = latch_left; + ret->latch_right = latch_right; +} + +void T6W28_Apu::load_state(const T6W28_ApuState *state) +{ + for (int x = 0; x < 4; x++) + { + oscs[x]->volume_left = state->volume_left[x]; + oscs[x]->volume_right = state->volume_right[x]; + } + for (int x = 0; x < 3; x++) + { + squares[x].period = state->sq_period[x] & 0x3FFF; + squares[x].phase = state->sq_phase[x]; + } + noise.shifter = state->noise_shifter; + noise.tap = state->noise_tap; + noise.period_extra = state->noise_period_extra & 0x3FFF; + + unsigned select = state->noise_period; + + if (select < 3) + noise.period = &noise_periods[select]; + else + noise.period = &noise.period_extra; + + latch_left = state->latch_left; + latch_right = state->latch_right; +} +} diff --git a/waterbox/ngp/T6W28_Apu.h b/waterbox/ngp/T6W28_Apu.h new file mode 100644 index 0000000000..cbedba0923 --- /dev/null +++ b/waterbox/ngp/T6W28_Apu.h @@ -0,0 +1,95 @@ +// T6W28_Snd_Emu + +#ifndef SMS_APU_H +#define SMS_APU_H + +namespace MDFN_IEN_NGP +{ + +typedef long sms_time_t; // clock cycle count + +} + +#include "T6W28_Oscs.h" + +namespace MDFN_IEN_NGP +{ + +typedef struct +{ + int32 sq_period[3]; + int32 sq_phase[3]; + uint32 noise_period; + uint32 noise_period_extra; + uint32 noise_shifter; + uint32 noise_tap; + + int32 volume_left[4]; + int32 volume_right[4]; + uint8 latch_left, latch_right; +} T6W28_ApuState; + +class T6W28_Apu { +public: + // Set overall volume of all oscillators, where 1.0 is full volume + void volume( double ); + + // Set treble equalization + void treble_eq( const blip_eq_t& ); + + // Outputs can be assigned to a single buffer for mono output, or to three + // buffers for stereo output (using Stereo_Buffer to do the mixing). + + // Assign all oscillator outputs to specified buffer(s). If buffer + // is NULL, silences all oscillators. + void output( Blip_Buffer* mono ); + void output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right ); + + // Assign single oscillator output to buffer(s). Valid indicies are 0 to 3, + // which refer to Square 1, Square 2, Square 3, and Noise. If buffer is NULL, + // silences oscillator. + enum { osc_count = 4 }; + void osc_output( int index, Blip_Buffer* mono ); + void osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right ); + + // Reset oscillators and internal state + void reset(); + + // Write to data port + void write_data_left( sms_time_t, int ); + void write_data_right( sms_time_t, int ); + + // Run all oscillators up to specified time, end current frame, then + // start a new frame at time 0. Returns true if any oscillators added + // sound to one of the left/right buffers, false if they only added + // to the center buffer. + bool end_frame( sms_time_t ); + + void save_state(T6W28_ApuState*); + void load_state(const T6W28_ApuState*); +public: + T6W28_Apu(); + ~T6W28_Apu(); +private: + // noncopyable + T6W28_Apu( const T6W28_Apu& ); + T6W28_Apu& operator = ( const T6W28_Apu& ); + + T6W28_Osc* oscs [osc_count]; + T6W28_Square squares [3]; + T6W28_Square::Synth square_synth; // used by squares + sms_time_t last_time; + int latch_left, latch_right; + T6W28_Noise noise; + + void run_until( sms_time_t ); +}; + +inline void T6W28_Apu::output( Blip_Buffer* b ) { output( b, b, b ); } + +inline void T6W28_Apu::osc_output( int i, Blip_Buffer* b ) { osc_output( i, b, b, b ); } + +} + +#endif + diff --git a/waterbox/ngp/T6W28_Oscs.h b/waterbox/ngp/T6W28_Oscs.h new file mode 100644 index 0000000000..e946aaf90b --- /dev/null +++ b/waterbox/ngp/T6W28_Oscs.h @@ -0,0 +1,60 @@ + +// Private oscillators used by T6W28_Apu + +// T6W28_Snd_Emu + +#ifndef SMS_OSCS_H +#define SMS_OSCS_H + +#include "sound/Blip_Buffer.h" + +namespace MDFN_IEN_NGP +{ + +struct T6W28_Osc +{ + Blip_Buffer* outputs [4]; // NULL, right, left, center + Blip_Buffer* output; + int output_select; + + int delay; + int last_amp_left; + int last_amp_right; + + int volume_left; + int volume_right; + + T6W28_Osc(); + void reset(); +}; + +struct T6W28_Square : T6W28_Osc +{ + int period; + int phase; + + typedef Blip_Synth Synth; + const Synth* synth; + + void reset(); + void run( sms_time_t, sms_time_t ); +}; + +struct T6W28_Noise : T6W28_Osc +{ + const int* period; + int period_extra; + unsigned shifter; + unsigned tap; + + typedef Blip_Synth Synth; + Synth synth; + + void reset(); + void run( sms_time_t, sms_time_t ); +}; + +} + +#endif + diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_disassemble.cpp b/waterbox/ngp/TLCS-900h/TLCS900h_disassemble.cpp new file mode 100644 index 0000000000..48cff31cb6 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_disassemble.cpp @@ -0,0 +1,641 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_disassemble.c + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +25 JUL 2002 - neopop_uk +======================================= +- Added missing registers to disassmbly table (unused, I hope!) + +//--------------------------------------------------------------------------- +*/ + +//========================================================================= + +#include "../neopop.h" +#include "TLCS900h_disassemble.h" +#include "TLCS900h_registers.h" +#include "TLCS900h_interpret.h" +#include "../mem.h" + +namespace TLCS900H +{ + +void TLCS900h_disassemble_extra(void); +void TLCS900h_disassemble_src(int size); +void TLCS900h_disassemble_dst(void); +void TLCS900h_disassemble_reg(int size); + +//========================================================================= + +char str_R[8]; //Big R +char str_r[8]; //Little R + +//Control register names +const char* crName[3][0x40] = +{ + { + 0,0,0,0, + 0,0,0,0, + 0,0,0,0, + 0,0,0,0, + 0,0,0,0, + 0,0,0,0, + 0,0,0,0, + 0,0,0,0, + + 0,0, "DMAM0", 0, + 0,0, "DMAM1", 0, + 0,0, "DMAM2", 0, + 0,0, "DMAM3", 0, + }, + + { + 0,0, + 0,0, + 0,0, + 0,0, + 0,0, + 0,0, + 0,0, + 0,0, + + "DMAC0", 0, + "DMAC1", 0, + "DMAC2", 0, + "DMAC3", 0, + + 0,0, //30 + 0,0, + 0,0, + "NSP",0, //3C + }, + + { + "DMAS0", //00 + "DMAS1", + "DMAS2", + "DMAS3", + "DMAD0", //10 + "DMAD1", + "DMAD2", + "DMAD3", + 0, //20 + 0, + 0, + 0, + 0, //30 + 0, + 0, + "XNSP", //3C + } +}; + +//Register names +const char* gprName[8][3] = +{ + {"W", "WA", "XWA"}, + {"A", "BC", "XBC"}, + {"B", "DE", "XDE"}, + {"C", "HL", "XHL"}, + {"D", "IX", "XIX"}, + {"E", "IY", "XIY"}, + {"H", "IZ", "XIZ"}, + {"L", "SP", "XSP"} +}; + +//Condition Code names +const char* ccName[] = +{ + "F","LT","LE","ULE", + "OV","MI","Z","C", + "T","GE","GT","UGT", + "NOV","PL","NZ","NC" +}; + +const char* regCodeName[3][256] = +{ + { + "RA0","RW0","QA0","QW0","RC0","RB0","QC0","QB0", //BANK 0 + "RE0","RD0","QE0","QD0","RL0","RH0","QL0","QH0", + "RA1","RW1","QA1","QW1","RC1","RB1","QC1","QB1", //BANK 1 + "RE1","RD1","QE1","QD1","RL1","RH1","QL1","QH1", + "RA2","RW2","QA2","QW2","RC2","RB2","QC2","QB2", //BANK 2 + "RE2","RD2","QE2","QD2","RL2","RH2","QL2","QH2", + "RA3","RW3","QA3","QW3","RC3","RB3","QC3","QB3", //BANK 3 + "RE3","RD3","QE3","QD3","RL3","RH3","QL3","QH3", + + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + + "A'","W'","QA'","QW'","C'","B'","QC'","QB'", //Previous Bank + "E'","D'","QE'","QD'","L'","H'","QL'","QH'", + "A","W","QA","QW","C","B","QC","QB", //Current Bank + "E","D","QE","QD","L","H","QL","QH", + + "IXL","IXH","QIXL","QIXH","IYL","IYH","QIYL","QIYH", + "IZL","IZH","QIZL","QIZH","SPL","SPH","QSPL","QSPX" + }, + + { + "RWA0","QWA0","RBC0","QBC0", //BANK 0 + "RDE0","QDE0","RHL0","QHL0", + "RWA1","QWA1","RBC1","QBC1", //BANK 1 + "RDE1","QDE1","RHL1","QHL1", + "RWA2","QWA2","RBC2","QBC2", //BANK 2 + "RDE2","QDE2","RHL2","QHL2", + "RWA3","QWA3","RBC3","QBC3", //BANK 3 + "RDE3","QDE3","RHL3","QHL3", + + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + + "WA'","QWA'","BC'","QBC'","DE'","QDE'","HL'","QHL'",//Previous Bank + "WA","QWA","BC","QBC","DE","QDE","HL","QHL", //Current Bank + + "IX","QIX","IY","QIY","IZ","QIZ","SP","QSP" + }, + + { + "XWA0","XBC0","XDE0","XHL0", //BANK 0 + "XWA1","XBC1","XDE1","XHL1", //BANK 1 + "XWA2","XBC2","XDE2","XHL2", //BANK 2 + "XWA3","XBC3","XDE3","XHL3", //BANK 3 + + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0, + + "XWA'","XBC'","XDE'","XHL'", //Previous Bank + "XWA","XBC","XDE","XHL", //Current Bank + + "XIX","XIY","XIZ","XSP" + } +}; + +//========================================================================= + +void get_rr_Name(void) +{ + sprintf(str_r, "???"); + + if (size == 0 && first == 0xC7) + { + sprintf(str_r, "%s", extra); + return; + } + + switch(first & 7) + { + case 0: if (size == 1) sprintf(str_r, "XWA"); break; + case 1: + if (size == 0) sprintf(str_r, "WA"); + if (size == 1) sprintf(str_r, "XBC"); + break; + case 2: if (size == 1) sprintf(str_r, "XDE"); break; + case 3: + if (size == 0) sprintf(str_r, "BC"); + if (size == 1) sprintf(str_r, "XHL"); + break; + case 4: if (size == 1) sprintf(str_r, "XIX"); break; + case 5: + if (size == 0) sprintf(str_r, "DE"); + if (size == 1) sprintf(str_r, "XIY"); + break; + case 6: if (size == 1) sprintf(str_r, "XIZ"); break; + case 7: + if (size == 0) sprintf(str_r, "HL"); + if (size == 1) sprintf(str_r, "XSP"); + break; + } +} + +void get_RR_Name(void) +{ + sprintf(str_R, "???"); + + switch(second & 7) + { + case 0: if (size == 1) sprintf(str_R, "XWA"); break; + case 1: + if (size == 0) sprintf(str_R, "WA"); + if (size == 1) sprintf(str_R, "XBC"); + break; + case 2: if (size == 1) sprintf(str_R, "XDE"); break; + case 3: + if (size == 0) sprintf(str_R, "BC"); + if (size == 1) sprintf(str_R, "XHL"); + break; + case 4: if (size == 1) sprintf(str_R, "XIX"); break; + case 5: + if (size == 0) sprintf(str_R, "DE"); + if (size == 1) sprintf(str_R, "XIY"); + break; + case 6: if (size == 1) sprintf(str_R, "XIZ"); break; + case 7: + if (size == 0) sprintf(str_R, "HL"); + if (size == 1) sprintf(str_R, "XSP"); + break; + } +} + +//============================================================================= + +char instr[128]; //Print the disassembled instruction to this string +uint8 bytes[16]; //Stores the bytes used +uint8 bcnt; //Byte Counter for above + +//============================================================================= + +uint8 get8_dis(void) +{ + uint8 a = bytes[bcnt++] = loadB(pc++); + return a; +} + +uint16 get16_dis(void) +{ + uint16 a = *(uint16*)(uint8*)(bytes + bcnt) = loadW(pc); + pc += 2; bcnt += 2; + return a; +} + +uint32 get24_dis(void) +{ + uint8 b; uint16 a; + a = *(uint16*)(uint8*)(bytes + bcnt) = loadW(pc); + pc += 2; bcnt += 2; + b = bytes[bcnt++] = loadB(pc++); + return ((uint32)b << 16) | (uint32)a; +} + +uint32 get32_dis(void) +{ + uint32 a = *(uint32*)(uint8*)(bytes + bcnt) = loadL(pc); + pc += 4; bcnt += 4; + return a; +} + +//========================================================================= + +static void src_B() { TLCS900h_disassemble_src(0); } +static void src_W() { TLCS900h_disassemble_src(1); } +static void src_L() { TLCS900h_disassemble_src(2); } +static void dst() { TLCS900h_disassemble_dst(); } +static void reg_B() { TLCS900h_disassemble_reg(0);} +static void reg_W() { TLCS900h_disassemble_reg(1);} +static void reg_L() { TLCS900h_disassemble_reg(2);} + +//========================================================================= + +//Single Byte Opcode + +static void NOP() +{ + sprintf(instr, "NOP"); +} + +static void NORMAL() +{ + sprintf(instr, "NORMAL"); +} + +static void PUSHSR() +{ + sprintf(instr, "PUSH SR"); +} + +static void POPSR() +{ + sprintf(instr, "POP SR"); +} + +static void MAX() +{ + sprintf(instr, "MAX"); +} + +static void HALT() +{ + sprintf(instr, "HALT"); +} + +static void EI() +{ + uint8 value = get8_dis(); + + if (value == 7) + sprintf(instr, "DI"); + else + sprintf(instr, "EI %d", value); +} + +static void RETI() +{ + sprintf(instr, "RETI"); +} + +static void LD8_8() +{ + uint8 dst = get8_dis(), src = get8_dis(); + sprintf(instr, "LD (0x%02X),0x%02X", dst, src); +} + +static void PUSH8() +{ + sprintf(instr, "PUSH 0x%02X", get8_dis()); +} + +static void LD8_16() +{ + uint8 dst = get8_dis(); + uint16 src = get16_dis(); + sprintf(instr, "LD.w (0x%02X),0x%04X", dst, src); +} + +static void PUSH16() +{ + sprintf(instr, "PUSH 0x%04X", get16_dis()); +} + +static void INCF() +{ + sprintf(instr, "INCF"); +} + +static void DECF() +{ + sprintf(instr, "DECF"); +} + +static void RET() +{ + sprintf(instr, "RET"); +} + +static void RETD() +{ + sprintf(instr, "RETD %d", get16_dis()); +} + +static void RCF() +{ + sprintf(instr, "RCF"); +} + +static void SCF() +{ + sprintf(instr, "SCF"); +} + +static void CCF() +{ + sprintf(instr, "CCF"); +} + +static void ZCF() +{ + sprintf(instr, "ZCF"); +} + +static void PUSHA() +{ + sprintf(instr, "PUSH A"); +} + +static void POPA() +{ + sprintf(instr, "POP A"); +} + +static void EX() +{ + sprintf(instr, "EX F,F'"); +} + +static void LDF() +{ + sprintf(instr, "LDF 0x%02X", get8_dis()); +} + +static void PUSHF() +{ + sprintf(instr, "PUSH F"); +} + +static void POPF() +{ + sprintf(instr, "POP F"); +} + +static void JP16() +{ + sprintf(instr, "JP 0x%04X", get16_dis()); +} + +static void JP24() +{ + sprintf(instr, "JP 0x%06X", get24_dis()); +} + +static void CALL16() +{ + sprintf(instr, "CALL 0x%04X", get16_dis()); +} + +static void CALL24() +{ + sprintf(instr, "CALL 0x%06X", get24_dis()); +} + +static void CALR() +{ + sprintf(instr, "CALR 0x%06X", (int16)get16_dis() + pc); +} + +static void LDB() +{ + sprintf(instr, "LD %s,0x%02X", gprName[first & 7][0], get8_dis()); +} + +static void PUSHW() +{ + sprintf(instr, "PUSH %s", gprName[first & 7][1]); +} + +static void LDW() +{ + sprintf(instr, "LD %s,0x%04X", gprName[first & 7][1], get16_dis()); +} + +static void PUSHL() +{ + sprintf(instr, "PUSH %s", gprName[first & 7][2]); +} + +static void LDL() +{ + sprintf(instr, "LD %s,0x%08X", gprName[first & 7][2], get32_dis()); +} + +static void POPW() +{ + sprintf(instr, "POP %s", gprName[first & 7][1]); +} + +static void POPL() +{ + sprintf(instr, "POP %s", gprName[first & 7][2]); +} + +static void JR() +{ + sprintf(instr, "JR %s,0x%06X", ccName[first & 0xF], (int8)get8_dis() + pc); +} + +static void JRL() +{ + sprintf(instr, "JRL %s,0x%06X", ccName[first & 0xF], (int16)get16_dis() + pc); +} + +static void LDX() +{ + uint8 dst, src; + + get8_dis(); //00 + dst = get8_dis(); //#8 + get8_dis(); //00 + src = get8_dis(); //# + get8_dis(); //00 + sprintf(instr, "LDX (0x%02X),0x%02X", dst, src); +} + +static void SWI() +{ + sprintf(instr, "SWI %d", first & 7); +} + +//========================================================================= + +static void dBIOSHLE() +{ + sprintf(instr, "BIOS-HLE"); +} + +//========================================================================= + +//Primary Instruction decode +static void (*decode[256])() = +{ +/*0*/ NOP, NORMAL, PUSHSR, POPSR, MAX, HALT, EI, RETI, + LD8_8, PUSH8, LD8_16, PUSH16, INCF, DECF, RET, RETD, +/*1*/ RCF, SCF, CCF, ZCF, PUSHA, POPA, EX, LDF, + PUSHF, POPF, JP16, JP24, CALL16, CALL24, CALR, dBIOSHLE, +/*2*/ LDB, LDB, LDB, LDB, LDB, LDB, LDB, LDB, + PUSHW, PUSHW, PUSHW, PUSHW, PUSHW, PUSHW, PUSHW, PUSHW, +/*3*/ LDW, LDW, LDW, LDW, LDW, LDW, LDW, LDW, + PUSHL, PUSHL, PUSHL, PUSHL, PUSHL, PUSHL, PUSHL, PUSHL, +/*4*/ LDL, LDL, LDL, LDL, LDL, LDL, LDL, LDL, + POPW, POPW, POPW, POPW, POPW, POPW, POPW, POPW, +/*5*/ 0, 0, 0, 0, 0, 0, 0, 0, + POPL, POPL, POPL, POPL, POPL, POPL, POPL, POPL, +/*6*/ JR, JR, JR, JR, JR, JR, JR, JR, + JR, JR, JR, JR, JR, JR, JR, JR, +/*7*/ JRL, JRL, JRL, JRL, JRL, JRL, JRL, JRL, + JRL, JRL, JRL, JRL, JRL, JRL, JRL, JRL, +/*8*/ src_B, src_B, src_B, src_B, src_B, src_B, src_B, src_B, + src_B, src_B, src_B, src_B, src_B, src_B, src_B, src_B, +/*9*/ src_W, src_W, src_W, src_W, src_W, src_W, src_W, src_W, + src_W, src_W, src_W, src_W, src_W, src_W, src_W, src_W, +/*A*/ src_L, src_L, src_L, src_L, src_L, src_L, src_L, src_L, + src_L, src_L, src_L, src_L, src_L, src_L, src_L, src_L, +/*B*/ dst, dst, dst, dst, dst, dst, dst, dst, + dst, dst, dst, dst, dst, dst, dst, dst, +/*C*/ src_B, src_B, src_B, src_B, src_B, src_B, 0, reg_B, + reg_B, reg_B, reg_B, reg_B, reg_B, reg_B, reg_B, reg_B, +/*D*/ src_W, src_W, src_W, src_W, src_W, src_W, 0, reg_W, + reg_W, reg_W, reg_W, reg_W, reg_W, reg_W, reg_W, reg_W, +/*E*/ src_L, src_L, src_L, src_L, src_L, src_L, 0, reg_L, + reg_L, reg_L, reg_L, reg_L, reg_L, reg_L, reg_L, reg_L, +/*F*/ dst, dst, dst, dst, dst, dst, 0, LDX, + SWI, SWI, SWI, SWI, SWI, SWI, SWI, SWI +}; + +//============================================================================= + +char* TLCS900h_disassemble(void) +{ + char str[80]; + unsigned int i; + + memset(str, 0, 80); + + //Reset + bcnt = 0; + brCode = FALSE; + sprintf(instr, "unknown"); + sprintf(extra, "unknown"); + + //Fix big addresses + pc &= 0xFFFFFF; + + //Add the program counter + sprintf(str, "%06X: ", pc); + + first = get8_dis(); //Get the first opcode + + //Disassemble + if (decode[first]) + { + //Decode any extra data + TLCS900h_disassemble_extra(); + (*decode[first])(); + } + + //Add the instruction + strcat(str, instr); + + //Add the bytes used + for (i = strlen(str); i < 32; i++) + str[i] = ' '; + str[32] = '\"'; + for (i = 0; i < bcnt; i++) + { + char tmp[80]; + sprintf(tmp, "%02X ", bytes[i]); + strcat(str, tmp); + } + str[strlen(str) - 1] = '\"'; + + return strdup(str); +} +}; +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_disassemble.h b/waterbox/ngp/TLCS-900h/TLCS900h_disassemble.h new file mode 100644 index 0000000000..2995be36aa --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_disassemble.h @@ -0,0 +1,77 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_disassemble.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + +#ifndef __TLCS900H_DISASSEMBLE__ +#define __TLCS900H_DISASSEMBLE__ + +namespace TLCS900H +{ +//============================================================================= + +//Disassembles a single instruction from 'pc', +//pc is incremented to the start of the next instruction. +char* TLCS900h_disassemble(void); + +//Print to this string the disassembled instruction +extern char instr[128]; + +//Print the mnemonic for the addressing mode / reg code. +extern char extra[256]; + +//============================================================================= + +extern char str_R[8]; //Big R +extern char str_r[8]; //Little R + +//Translate an rr or RR value for MUL/MULS/DIV/DIVS +void get_rr_Name(void); +void get_RR_Name(void); + +extern uint8 bytes[16]; //Stores the bytes used +extern uint8 bcnt; //Byte Counter for above + +extern const char* gprName[8][3]; //8 regs * 3 names (byte, word, long) +extern const char* regCodeName[3][256]; +extern const char* crName[3][0x40]; + +extern const char* ccName[]; + +uint8 get8_dis(void); +uint16 get16_dis(void); +uint32 get24_dis(void); +uint32 get32_dis(void); + +}; + +//============================================================================= +#endif diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_disassemble_dst.cpp b/waterbox/ngp/TLCS-900h/TLCS900h_disassemble_dst.cpp new file mode 100644 index 0000000000..ff35e1f80a --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_disassemble_dst.cpp @@ -0,0 +1,240 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_disassemble_dst.c + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + +//========================================================================= + +#include "../neopop.h" +#include "TLCS900h_disassemble.h" +#include "TLCS900h_registers.h" +#include "TLCS900h_interpret.h" + +//========================================================================= +namespace TLCS900H +{ + +static void LDBi() +{ + sprintf(instr, "LD (%s),0x%02X", extra, get8_dis()); +} + +static void LDWi() +{ + sprintf(instr, "LD (%s),0x%04X", extra, get16_dis()); +} + +static void POPB() +{ + sprintf(instr, "POP.b (%s)", extra); +} + +static void POPW() +{ + sprintf(instr, "POP.w (%s)", extra); +} + +static void LDBm16() +{ + sprintf(instr, "LD.b (%s),(0x%04X)", extra, get16_dis()); +} + +static void LDWm16() +{ + sprintf(instr, "LD.w (%s),(0x%04X)", extra, get16_dis()); +} + +static void LDAW() +{ + sprintf(instr, "LDA %s,%s", gprName[second & 7][1], extra); +} + +static void LDAL() +{ + sprintf(instr, "LDA %s,%s", gprName[second & 7][2], extra); +} + +static void ANDCFA() +{ + sprintf(instr, "ANDCF A,(%s)", extra); +} + +static void ORCFA() +{ + sprintf(instr, "ORCF A,(%s)", extra); +} + +static void XORCFA() +{ + sprintf(instr, "XORCF A,(%s)", extra); +} + +static void LDCFA() +{ + sprintf(instr, "LDCF A,(%s)", extra); +} + +static void STCFA() +{ + sprintf(instr, "STCF A,(%s)", extra); +} + +static void LDBR() +{ + sprintf(instr, "LD (%s),%s", extra, gprName[second&7][0]); +} + +static void LDWR() +{ + sprintf(instr, "LD (%s),%s", extra, gprName[second&7][1]); +} + +static void LDLR() +{ + sprintf(instr, "LD (%s),%s", extra, gprName[second&7][2]); +} + +static void ANDCF() +{ + sprintf(instr, "ANDCF %d,(%s)", second & 7, extra); +} + +static void ORCF() +{ + sprintf(instr, "ORCF %d,(%s)", second & 7, extra); +} + +static void XORCF() +{ + sprintf(instr, "XORCF %d,(%s)", second & 7, extra); +} + +static void LDCF() +{ + sprintf(instr, "LDCF %d,(%s)", second & 7, extra); +} + +static void STCF() +{ + sprintf(instr, "STCF %d,(%s)", second & 7, extra); +} + +static void TSET() +{ + sprintf(instr, "TSET %d,(%s)", second & 7, extra); +} + +static void RES() +{ + sprintf(instr, "RES %d,(%s)", second & 7, extra); +} + +static void SET() +{ + sprintf(instr, "SET %d,(%s)", second & 7, extra); +} + +static void CHG() +{ + sprintf(instr, "CHG %d,(%s)", second & 7, extra); +} + +static void BIT() +{ + sprintf(instr, "BIT %d,(%s)", second & 7, extra); +} + +static void JP() +{ + sprintf(instr, "JP %s,%s", ccName[second & 0xF], extra); +} + +static void CALL() +{ + sprintf(instr, "CALL %s,%s", ccName[second & 0xF], extra); +} + +static void RET() +{ + sprintf(instr, "RET %s", ccName[second & 0xF]); +} + +//========================================================================= + +//Secondary (DST) Instruction decode +static void (*decode[256])() = +{ +/*0*/ LDBi, 0, LDWi, 0, POPB, 0, POPW, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +/*1*/ 0, 0, 0, 0, LDBm16, 0, LDWm16, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +/*2*/ LDAW, LDAW, LDAW, LDAW, LDAW, LDAW, LDAW, LDAW, + ANDCFA, ORCFA, XORCFA, LDCFA, STCFA, 0, 0, 0, +/*3*/ LDAL, LDAL, LDAL, LDAL, LDAL, LDAL, LDAL, LDAL, + 0, 0, 0, 0, 0, 0, 0, 0, +/*4*/ LDBR, LDBR, LDBR, LDBR, LDBR, LDBR, LDBR, LDBR, + 0, 0, 0, 0, 0, 0, 0, 0, +/*5*/ LDWR, LDWR, LDWR, LDWR, LDWR, LDWR, LDWR, LDWR, + 0, 0, 0, 0, 0, 0, 0, 0, +/*6*/ LDLR, LDLR, LDLR, LDLR, LDLR, LDLR, LDLR, LDLR, + 0, 0, 0, 0, 0, 0, 0, 0, +/*7*/ 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +/*8*/ ANDCF, ANDCF, ANDCF, ANDCF, ANDCF, ANDCF, ANDCF, ANDCF, + ORCF, ORCF, ORCF, ORCF, ORCF, ORCF, ORCF, ORCF, +/*9*/ XORCF, XORCF, XORCF, XORCF, XORCF, XORCF, XORCF, XORCF, + LDCF, LDCF, LDCF, LDCF, LDCF, LDCF, LDCF, LDCF, +/*A*/ STCF, STCF, STCF, STCF, STCF, STCF, STCF, STCF, + TSET, TSET, TSET, TSET, TSET, TSET, TSET, TSET, +/*B*/ RES, RES, RES, RES, RES, RES, RES, RES, + SET, SET, SET, SET, SET, SET, SET, SET, +/*C*/ CHG, CHG, CHG, CHG, CHG, CHG, CHG, CHG, + BIT, BIT, BIT, BIT, BIT, BIT, BIT, BIT, +/*D*/ JP, JP, JP, JP, JP, JP, JP, JP, + JP, JP, JP, JP, JP, JP, JP, JP, +/*E*/ CALL, CALL, CALL, CALL, CALL, CALL, CALL, CALL, + CALL, CALL, CALL, CALL, CALL, CALL, CALL, CALL, +/*F*/ RET, RET, RET, RET, RET, RET, RET, RET, + RET, RET, RET, RET, RET, RET, RET, RET +}; + +//============================================================================= + +void TLCS900h_disassemble_dst(void) +{ + second = get8_dis(); //Get the second opcode + + if (decode[second]) + (*decode[second])(); + else + sprintf(instr, "unknown dst instr. %02X", second); +} +}; diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_disassemble_extra.cpp b/waterbox/ngp/TLCS-900h/TLCS900h_disassemble_extra.cpp new file mode 100644 index 0000000000..cd69775c2d --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_disassemble_extra.cpp @@ -0,0 +1,199 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_disassemble_extra.c + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +02 SEP 2002 - neopop_uk +======================================= +- Added the undocumented type 0x13 R32 address mode. + +//--------------------------------------------------------------------------- +*/ + +//========================================================================= + +#include "../neopop.h" +#include "TLCS900h_disassemble.h" +#include "TLCS900h_interpret.h" + +#define RCN_fetch(_a, _b) (regCodeName[(_a)][(_b)] ? regCodeName[(_a)][(_b)] : "-UNK-") + +namespace TLCS900H +{ + +//========================================================================= + +char extra[256]; //Print the mnemonic for the addressing mode here. + +//========================================================================= + +static void ExXWA() {sprintf(extra, "XWA");} +static void ExXBC() {sprintf(extra, "XBC");} +static void ExXDE() {sprintf(extra, "XDE");} +static void ExXHL() {sprintf(extra, "XHL");} +static void ExXIX() {sprintf(extra, "XIX");} +static void ExXIY() {sprintf(extra, "XIY");} +static void ExXIZ() {sprintf(extra, "XIZ");} +static void ExXSP() {sprintf(extra, "XSP");} + +static void ExXWAd() {sprintf(extra, "XWA %+d", (int8)get8_dis());} +static void ExXBCd() {sprintf(extra, "XBC %+d", (int8)get8_dis());} +static void ExXDEd() {sprintf(extra, "XDE %+d", (int8)get8_dis());} +static void ExXHLd() {sprintf(extra, "XHL %+d", (int8)get8_dis());} +static void ExXIXd() {sprintf(extra, "XIX %+d", (int8)get8_dis());} +static void ExXIYd() {sprintf(extra, "XIY %+d", (int8)get8_dis());} +static void ExXIZd() {sprintf(extra, "XIZ %+d", (int8)get8_dis());} +static void ExXSPd() {sprintf(extra, "XSP %+d", (int8)get8_dis());} + +static void Ex8() {sprintf(extra, "0x%02X", get8_dis());} +static void Ex16() {sprintf(extra, "0x%04X", get16_dis());} +static void Ex24() {sprintf(extra, "0x%06X", get24_dis());} + +static void ExR32() +{ + uint8 data = get8_dis(); + + if (data == 0x03) + { + uint8 rIndex, r32; + r32 = get8_dis(); //r32, upper 6 bits + rIndex = get8_dis(); //r8 / r16 + sprintf(extra, "%s + %s", + RCN_fetch(2, r32 >> 2), RCN_fetch(0, rIndex >> 0)); + return; + } + + if (data == 0x07) + { + uint8 rIndex, r32; + r32 = get8_dis(); //r32, upper 6 bits + rIndex = get8_dis(); //r8 / r16 + sprintf(extra, "%s + %s", + RCN_fetch(2, r32 >> 2), RCN_fetch(1, rIndex >> 1)); + return; + } + + //Undocumented mode. + if (data == 0x13) + { + sprintf(extra, "pc %+d", (int16)get16_dis()); + return; + } + + if ((data & 3) == 1) + sprintf(extra, "%s %+d", RCN_fetch(2, data >> 2), (int16)get16_dis()); + else + sprintf(extra, "%s", RCN_fetch(2, data >> 2)); +} + +static void ExDec() +{ + uint8 data = get8_dis(); + uint8 r32 = data & 0xFC; + + switch(data & 3) + { + case 0: sprintf(extra, "1--%s", RCN_fetch(2, r32 >> 2)); break; + case 1: sprintf(extra, "2--%s", RCN_fetch(2, r32 >> 2)); break; + case 2: sprintf(extra, "4--%s", RCN_fetch(2, r32 >> 2)); break; + } +} + +static void ExInc() +{ + uint8 data = get8_dis(); + uint8 r32 = data & 0xFC; + + switch(data & 3) + { + case 0: sprintf(extra, "%s++1", RCN_fetch(2, r32 >> 2)); break; + case 1: sprintf(extra, "%s++2", RCN_fetch(2, r32 >> 2)); break; + case 2: sprintf(extra, "%s++4", RCN_fetch(2, r32 >> 2)); break; + } +} + +static void ExRCB() +{ + uint8 data = get8_dis(); + sprintf(extra, "%s", RCN_fetch(0, data >> 0)); + brCode = TRUE; +} + +static void ExRCW() +{ + uint8 data = get8_dis(); + sprintf(extra, "%s", RCN_fetch(1, data >> 1)); + brCode = TRUE; +} + +static void ExRCL() +{ + uint8 data = get8_dis(); + sprintf(extra, "%s", RCN_fetch(2, data >> 2)); + brCode = TRUE; +} + +//========================================================================= + +//Address Mode & Register Code +static void (*decodeExtra[256])() = +{ +/*0*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/*1*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/*2*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/*3*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/*4*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/*5*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/*6*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/*7*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/*8*/ ExXWA, ExXBC, ExXDE, ExXHL, ExXIX, ExXIY, ExXIZ, ExXSP, + ExXWAd, ExXBCd, ExXDEd, ExXHLd, ExXIXd, ExXIYd, ExXIZd, ExXSPd, +/*9*/ ExXWA, ExXBC, ExXDE, ExXHL, ExXIX, ExXIY, ExXIZ, ExXSP, + ExXWAd, ExXBCd, ExXDEd, ExXHLd, ExXIXd, ExXIYd, ExXIZd, ExXSPd, +/*A*/ ExXWA, ExXBC, ExXDE, ExXHL, ExXIX, ExXIY, ExXIZ, ExXSP, + ExXWAd, ExXBCd, ExXDEd, ExXHLd, ExXIXd, ExXIYd, ExXIZd, ExXSPd, +/*B*/ ExXWA, ExXBC, ExXDE, ExXHL, ExXIX, ExXIY, ExXIZ, ExXSP, + ExXWAd, ExXBCd, ExXDEd, ExXHLd, ExXIXd, ExXIYd, ExXIZd, ExXSPd, +/*C*/ Ex8, Ex16, Ex24, ExR32, ExDec, ExInc, 0, ExRCB, + 0, 0, 0, 0, 0, 0, 0, 0, +/*D*/ Ex8, Ex16, Ex24, ExR32, ExDec, ExInc, 0, ExRCW, + 0, 0, 0, 0, 0, 0, 0, 0, +/*E*/ Ex8, Ex16, Ex24, ExR32, ExDec, ExInc, 0, ExRCL, + 0, 0, 0, 0, 0, 0, 0, 0, +/*F*/ Ex8, Ex16, Ex24, ExR32, ExDec, ExInc, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void TLCS900h_disassemble_extra(void) +{ + //Is any extra data used by this instruction? + if (decodeExtra[first]) + (*decodeExtra[first])(); +} + +}; diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_disassemble_reg.cpp b/waterbox/ngp/TLCS-900h/TLCS900h_disassemble_reg.cpp new file mode 100644 index 0000000000..9d0eb10c07 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_disassemble_reg.cpp @@ -0,0 +1,662 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_disassemble_reg.c + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +22 JUL 2002 - neopop_uk +======================================= +- Fixed disassembly of Link, it's second operand is signed. + +28 JUL 2002 - neopop_uk +======================================= +- Better disassembly of MUL/MULS/DIV/DIVS - operand size is shown. + +//--------------------------------------------------------------------------- +*/ + +#include "../neopop.h" +#include "TLCS900h_disassemble.h" +#include "TLCS900h_registers.h" +#include "TLCS900h_interpret.h" + +//========================================================================= + +namespace TLCS900H +{ + +static void LDi() +{ + switch(size) + { + case 0: sprintf(instr, "LD %s,0x%02X", str_r, get8_dis()); break; + case 1: sprintf(instr, "LD %s,0x%04X", str_r, get16_dis()); break; + case 2: sprintf(instr, "LD %s,0x%08X", str_r, get32_dis()); break; + } +} + +static void PUSH() +{ + sprintf(instr, "PUSH %s", str_r); +} + +static void POP() +{ + sprintf(instr, "POP %s", str_r); +} + +static void CPL() +{ + sprintf(instr, "CPL %s", str_r); +} + +static void NEG() +{ + sprintf(instr, "NEG %s", str_r); +} + +static void MULi() +{ + get_rr_Name(); + + switch(size) + { + case 0: sprintf(instr, "MUL.b %s,0x%02X", str_r, get8_dis()); break; + case 1: sprintf(instr, "MUL.w %s,0x%04X", str_r, get16_dis()); break; + } +} + +static void MULSi() +{ + get_rr_Name(); + + switch(size) + { + case 0: sprintf(instr, "MULS.b %s,0x%02X", str_r, get8_dis()); break; + case 1: sprintf(instr, "MULS.w %s,0x%04X", str_r, get16_dis()); break; + } +} + +static void DIVi() +{ + get_rr_Name(); + + switch(size) + { + case 0: sprintf(instr, "DIV.b %s,0x%02X", str_r, get8_dis()); break; + case 1: sprintf(instr, "DIV.w %s,0x%04X", str_r, get16_dis()); break; + } +} + +static void DIVSi() +{ + get_rr_Name(); + + switch(size) + { + case 0: sprintf(instr, "DIVS.b %s,0x%02X", str_r, get8_dis()); break; + case 1: sprintf(instr, "DIVS.w %s,0x%04X", str_r, get16_dis()); break; + } +} + +static void LINK() +{ + sprintf(instr, "LINK %s, %d", str_r, (int16)get16_dis()); +} + +static void UNLK() +{ + sprintf(instr, "UNLK %s", str_r); +} + +static void BS1F() +{ + sprintf(instr, "BS1F A,%s", str_r); +} + +static void BS1B() +{ + sprintf(instr, "BS1B A,%s", str_r); +} + +static void DAA() +{ + sprintf(instr, "DAA %s", str_r); +} + +static void EXTZ() +{ + sprintf(instr, "EXTZ %s", str_r); +} + +static void EXTS() +{ + sprintf(instr, "EXTS %s", str_r); +} + +static void PAA() +{ + sprintf(instr, "PAA %s", str_r); +} + +static void MIRR() +{ + sprintf(instr, "MIRR %s", str_r); +} + +static void MULA() +{ + sprintf(instr, "MULA %s", str_r); +} + +static void DJNZ() +{ + sprintf(instr, "DJNZ %s,0x%06X", str_r, (int8)get8_dis() + pc); +} + +static void ANDCFi() +{ + sprintf(instr, "ANDCF %d,%s", get8_dis() & 0xF, str_r); +} + +static void ORCFi() +{ + sprintf(instr, "ORCF %d,%s", get8_dis() & 0xF, str_r); +} + +static void XORCFi() +{ + sprintf(instr, "XORCF %d,%s", get8_dis() & 0xF, str_r); +} + +static void LDCFi() +{ + sprintf(instr, "LDCF %d,%s", get8_dis() & 0xF, str_r); +} + +static void STCFi() +{ + sprintf(instr, "STCF %d,%s", get8_dis() & 0xF, str_r); +} + +static void ANDCFA() +{ + sprintf(instr, "ANDCF A,%s", str_r); +} + +static void ORCFA() +{ + sprintf(instr, "ORCF A,%s", str_r); +} + +static void XORCFA() +{ + sprintf(instr, "XORCF A,%s", str_r); +} + +static void LDCFA() +{ + sprintf(instr, "LDCF A,%s", str_r); +} + +static void STCFA() +{ + sprintf(instr, "STCF A,%s", str_r); +} + +static void LDCcrr() +{ + uint8 cr = get8_dis(); + sprintf(instr, "LDC %s,%s", crName[size][cr >> size], str_r); +} + +static void LDCrcr() +{ + uint8 cr = get8_dis(); + sprintf(instr, "LDC %s,%s", str_r, crName[size][cr >> size]); +} + +static void RES() +{ + sprintf(instr, "RES %d,%s", get8_dis() & 0xF, str_r); +} + +static void SET() +{ + sprintf(instr, "SET %d,%s", get8_dis() & 0xF, str_r); +} + +static void CHG() +{ + sprintf(instr, "CHG %d,%s", get8_dis() & 0xF, str_r); +} + +static void BIT() +{ + sprintf(instr, "BIT %d,%s", get8_dis() & 0xF, str_r); +} + +static void TSET() +{ + sprintf(instr, "TSET %d,%s", get8_dis() & 0xF, str_r); +} + +static void MINC1() +{ + sprintf(instr, "MINC1 %d,%s", get16_dis()+1, str_r); +} + +static void MINC2() +{ + sprintf(instr, "MINC2 %d,%s", get16_dis()+2, str_r); +} + +static void MINC4() +{ + sprintf(instr, "MINC4 %d,%s", get16_dis()+4, str_r); +} + +static void MDEC1() +{ + sprintf(instr, "MDEC1 %d,%s", get16_dis()+1, str_r); +} + +static void MDEC2() +{ + sprintf(instr, "MDEC2 %d,%s", get16_dis()+2, str_r); +} + +static void MDEC4() +{ + sprintf(instr, "MDEC4 %d,%s", get16_dis()+4, str_r); +} + +static void MUL() +{ + get_RR_Name(); + switch(size) + { + case 0: sprintf(instr, "MUL.b %s,%s", str_R, str_r); break; + case 1: sprintf(instr, "MUL.w %s,%s", str_R, str_r); break; + } +} + +static void MULS() +{ + get_RR_Name(); + switch(size) + { + case 0: sprintf(instr, "MULS.b %s,%s", str_R, str_r); break; + case 1: sprintf(instr, "MULS.w %s,%s", str_R, str_r); break; + } +} + +static void DIV() +{ + get_RR_Name(); + switch(size) + { + case 0: sprintf(instr, "DIV.b %s,%s", str_R, str_r); break; + case 1: sprintf(instr, "DIV.w %s,%s", str_R, str_r); break; + } +} + +static void DIVS() +{ + get_RR_Name(); + switch(size) + { + case 0: sprintf(instr, "DIVS.b %s,%s", str_R, str_r); break; + case 1: sprintf(instr, "DIVS.w %s,%s", str_R, str_r); break; + } +} + +static void INC() +{ + uint8 val = (second & 7); + if (val == 0) + val = 8; + + sprintf(instr, "INC %d,%s", val, str_r); +} + +static void DEC() +{ + uint8 val = (second & 7); + if (val == 0) + val = 8; + + sprintf(instr, "DEC %d,%s", val, str_r); +} + +static void SCC() +{ + sprintf(instr, "SCC %s,%s", ccName[second & 0xF], str_r); +} + +static void ADD() +{ + sprintf(instr, "ADD %s,%s", str_R, str_r); +} + +static void LDRr() +{ + sprintf(instr, "LD %s,%s", str_R, str_r); +} + +static void LDrR() +{ + sprintf(instr, "LD %s,%s", str_r, str_R); +} + +static void ADC() +{ + sprintf(instr, "ADC %s,%s", str_R, str_r); +} + +static void SUB() +{ + sprintf(instr, "SUB %s,%s", str_R, str_r); +} + +static void SBC() +{ + sprintf(instr, "SBC %s,%s", str_R, str_r); +} + +static void LDr3() +{ + sprintf(instr, "LD %s,%d", str_r, second & 7); +} + +static void EX() +{ + sprintf(instr, "EX %s,%s", str_R, str_r); +} + +static void AND() +{ + sprintf(instr, "AND %s,%s", str_R, str_r); +} + +static void ADDi() +{ + switch(size) + { + case 0: sprintf(instr, "ADD %s,0x%02X", str_r, get8_dis()); break; + case 1: sprintf(instr, "ADD %s,0x%04X", str_r, get16_dis()); break; + case 2: sprintf(instr, "ADD %s,0x%08X", str_r, get32_dis()); break; + } +} + +static void ADCi() +{ + switch(size) + { + case 0: sprintf(instr, "ADC %s,0x%02X", str_r, get8_dis()); break; + case 1: sprintf(instr, "ADC %s,0x%04X", str_r, get16_dis()); break; + case 2: sprintf(instr, "ADC %s,0x%08X", str_r, get32_dis()); break; + } +} + +static void SUBi() +{ + switch(size) + { + case 0: sprintf(instr, "SUB %s,0x%02X", str_r, get8_dis()); break; + case 1: sprintf(instr, "SUB %s,0x%04X", str_r, get16_dis()); break; + case 2: sprintf(instr, "SUB %s,0x%08X", str_r, get32_dis()); break; + } +} + +static void SBCi() +{ + switch(size) + { + case 0: sprintf(instr, "SBC %s,0x%02X", str_r, get8_dis()); break; + case 1: sprintf(instr, "SBC %s,0x%04X", str_r, get16_dis()); break; + case 2: sprintf(instr, "SBC %s,0x%08X", str_r, get32_dis()); break; + } +} + +static void ANDi() +{ + switch(size) + { + case 0: sprintf(instr, "AND %s,0x%02X", str_r, get8_dis()); break; + case 1: sprintf(instr, "AND %s,0x%04X", str_r, get16_dis()); break; + case 2: sprintf(instr, "AND %s,0x%08X", str_r, get32_dis()); break; + } +} + +static void XORi() +{ + switch(size) + { + case 0: sprintf(instr, "XOR %s,0x%02X", str_r, get8_dis()); break; + case 1: sprintf(instr, "XOR %s,0x%04X", str_r, get16_dis()); break; + case 2: sprintf(instr, "XOR %s,0x%08X", str_r, get32_dis()); break; + } +} + +static void ORi() +{ + switch(size) + { + case 0: sprintf(instr, "OR %s,0x%02X", str_r, get8_dis()); break; + case 1: sprintf(instr, "OR %s,0x%04X", str_r, get16_dis()); break; + case 2: sprintf(instr, "OR %s,0x%08X", str_r, get32_dis()); break; + } +} + +static void CPi() +{ + switch(size) + { + case 0: sprintf(instr, "CP %s,0x%02X", str_r, get8_dis()); break; + case 1: sprintf(instr, "CP %s,0x%04X", str_r, get16_dis()); break; + case 2: sprintf(instr, "CP %s,0x%08X", str_r, get32_dis()); break; + } +} + +static void XOR() +{ + sprintf(instr, "XOR %s,%s", str_R, str_r); +} + +static void CPr3() +{ + sprintf(instr,"CP %s,%d", str_r, second&7); +} + +static void OR() +{ + sprintf(instr, "OR %s,%s", str_R, str_r); +} + +static void RLCi() +{ + uint8 val = get8_dis() & 0xF; + if (val == 0) val = 16; + sprintf(instr, "RLC %d,%s", val, str_r); +} + +static void RRCi() +{ + uint8 val = get8_dis() & 0xF; + if (val == 0) val = 16; + sprintf(instr, "RRC %d,%s", val, str_r); +} + +static void RLi() +{ + uint8 val = get8_dis() & 0xF; + if (val == 0) val = 16; + sprintf(instr, "RL %d,%s", val, str_r); +} + +static void RRi() +{ + uint8 val = get8_dis() & 0xF; + if (val == 0) val = 16; + sprintf(instr, "RR %d,%s", val, str_r); +} + +static void SLAi() +{ + uint8 val = get8_dis() & 0xF; + if (val == 0) val = 16; + sprintf(instr, "SLA %d,%s", val, str_r); +} + +static void SRAi() +{ + uint8 val = get8_dis() & 0xF; + if (val == 0) val = 16; + sprintf(instr, "SRA %d,%s", val, str_r); +} + +static void SLLi() +{ + uint8 val = get8_dis() & 0xF; + if (val == 0) val = 16; + sprintf(instr, "SLL %d,%s", val, str_r); +} + +static void SRLi() +{ + uint8 val = get8_dis() & 0xF; + if (val == 0) val = 16; + sprintf(instr, "SRL %d,%s", val, str_r); +} + +static void CP() +{ + sprintf(instr, "CP %s,%s", str_R, str_r); +} + +static void RLCA() +{ + sprintf(instr, "RLC A,%s", str_r); +} + +static void RRCA() +{ + sprintf(instr, "RRC A,%s", str_r); +} + +static void RLA() +{ + sprintf(instr, "RL A,%s", str_r); +} + +static void RRA() +{ + sprintf(instr, "RR A,%s", str_r); +} + +static void SLAA() +{ + sprintf(instr, "SLA A,%s", str_r); +} + +static void SRAA() +{ + sprintf(instr, "SRA A,%s", str_r); +} + +static void SLLA() +{ + sprintf(instr, "SLL A,%s", str_r); +} + +static void SRLA() +{ + sprintf(instr, "SRL A,%s", str_r); +} + +//========================================================================= + +//Secondary (REG) Instruction decode +static void (*decode[256])() = +{ +/*0*/ 0, 0, 0, LDi, PUSH, POP, CPL, NEG, + MULi, MULSi, DIVi, DIVSi, LINK, UNLK, BS1F, BS1B, +/*1*/ DAA, 0, EXTZ, EXTS, PAA, 0, MIRR, 0, + 0, MULA, 0, 0, DJNZ, 0, 0, 0, +/*2*/ ANDCFi, ORCFi, XORCFi, LDCFi, STCFi, 0, 0, 0, + ANDCFA, ORCFA, XORCFA, LDCFA, STCFA, 0, LDCcrr, LDCrcr, +/*3*/ RES, SET, CHG, BIT, TSET, 0, 0, 0, + MINC1, MINC2, MINC4, 0, MDEC1, MDEC2, MDEC4, 0, +/*4*/ MUL, MUL, MUL, MUL, MUL, MUL, MUL, MUL, + MULS, MULS, MULS, MULS, MULS, MULS, MULS, MULS, +/*5*/ DIV, DIV, DIV, DIV, DIV, DIV, DIV, DIV, + DIVS, DIVS, DIVS, DIVS, DIVS, DIVS, DIVS, DIVS, +/*6*/ INC, INC, INC, INC, INC, INC, INC, INC, + DEC, DEC, DEC, DEC, DEC, DEC, DEC, DEC, +/*7*/ SCC, SCC, SCC, SCC, SCC, SCC, SCC, SCC, + SCC, SCC, SCC, SCC, SCC, SCC, SCC, SCC, +/*8*/ ADD, ADD, ADD, ADD, ADD, ADD, ADD, ADD, + LDRr, LDRr, LDRr, LDRr, LDRr, LDRr, LDRr, LDRr, +/*9*/ ADC, ADC, ADC, ADC, ADC, ADC, ADC, ADC, + LDrR, LDrR, LDrR, LDrR, LDrR, LDrR, LDrR, LDrR, +/*A*/ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, + LDr3, LDr3, LDr3, LDr3, LDr3, LDr3, LDr3, LDr3, +/*B*/ SBC, SBC, SBC, SBC, SBC, SBC, SBC, SBC, + EX, EX, EX, EX, EX, EX, EX, EX, +/*C*/ AND, AND, AND, AND, AND, AND, AND, AND, + ADDi, ADCi, SUBi, SBCi, ANDi, XORi, ORi, CPi, +/*D*/ XOR, XOR, XOR, XOR, XOR, XOR, XOR, XOR, + CPr3, CPr3, CPr3, CPr3, CPr3, CPr3, CPr3, CPr3, +/*E*/ OR, OR, OR, OR, OR, OR, OR, OR, + RLCi, RRCi, RLi, RRi, SLAi, SRAi, SLLi, SRLi, +/*F*/ CP, CP, CP, CP, CP, CP, CP, CP, + RLCA, RRCA, RLA, RRA, SLAA, SRAA, SLLA, SRLA +}; + +//============================================================================= + +void TLCS900h_disassemble_reg(int opsize) +{ + second = get8_dis(); //Get the second opcode + size = opsize; + + //Prepare 'Big R' + sprintf(str_R, "%s", gprName[second & 7][size]); + + //Prepare 'little r' + if (brCode) + sprintf(str_r, "%s", extra); + else + sprintf(str_r, "%s", gprName[first & 7][opsize]); + + if (decode[second]) + (*decode[second])(); + else + sprintf(instr, "unknown reg instr. %02X", second); +} +}; diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_disassemble_src.cpp b/waterbox/ngp/TLCS-900h/TLCS900h_disassemble_src.cpp new file mode 100644 index 0000000000..27e42d5035 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_disassemble_src.cpp @@ -0,0 +1,507 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_disassemble_src.c + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +28 JUL 2002 - neopop_uk +======================================= +- Better disassembly of MUL/MULS/DIV/DIVS - operand size is shown. + +//--------------------------------------------------------------------------- +*/ + +//========================================================================= + +#include "../neopop.h" +#include "TLCS900h_disassemble.h" +#include "TLCS900h_registers.h" +#include "TLCS900h_interpret.h" + +//========================================================================= + +namespace TLCS900H +{ + +static void PUSH() +{ + sprintf(instr, "PUSH (%s)", extra); +} + +static void RLD() +{ + sprintf(instr, "RLD A,(%s)", extra); +} + +static void RRD() +{ + sprintf(instr, "RRD A,(%s)", extra); +} + +static void LDI() +{ + if ((first & 0xF) == 3) + { + switch(size) + { + case 0: sprintf(instr, "LDI.b (XDE+),(XHL+)"); break; + case 1: sprintf(instr, "LDI.w (XDE+),(XHL+)"); break; + } + } + + if ((first & 0xF) == 5) + { + switch(size) + { + case 0: sprintf(instr, "LDI.b (XIX+),(XIY+)"); break; + case 1: sprintf(instr, "LDI.w (XIX+),(XIY+)"); break; + } + } +} + +static void LDIR() +{ + if ((first & 0xF) == 3) + { + switch(size) + { + case 0: sprintf(instr, "LDIR.b (XDE+),(XHL+)"); break; + case 1: sprintf(instr, "LDIR.w (XDE+),(XHL+)"); break; + } + } + + if ((first & 0xF) == 5) + { + switch(size) + { + case 0: sprintf(instr, "LDIR.b (XIX+),(XIY+)"); break; + case 1: sprintf(instr, "LDIR.w (XIX+),(XIY+)"); break; + } + } +} + +static void LDD() +{ + if ((first & 0xF) == 3) + { + switch(size) + { + case 0: sprintf(instr, "LDD.b (XDE-),(XHL-)"); break; + case 1: sprintf(instr, "LDD.w (XDE-),(XHL-)"); break; + } + } + + if ((first & 0xF) == 5) + { + switch(size) + { + case 0: sprintf(instr, "LDD.b (XIX-),(XIY-)"); break; + case 1: sprintf(instr, "LDD.w (XIX-),(XIY-)"); break; + } + } +} + +static void LDDR() +{ + if ((first & 0xF) == 3) + { + switch(size) + { + case 0: sprintf(instr, "LDDR.b (XDE-),(XHL-)"); break; + case 1: sprintf(instr, "LDDR.w (XDE-),(XHL-)"); break; + } + } + + if ((first & 0xF) == 5) + { + switch(size) + { + case 0: sprintf(instr, "LDDR.b (XIX-),(XIY-)"); break; + case 1: sprintf(instr, "LDDR.w (XIX-),(XIY-)"); break; + } + } +} + +static void CPI() +{ + sprintf(instr, "CPI"); +} + +static void CPIR() +{ + switch(size) + { + case 0: sprintf(instr, "CPIR.b A,(%s+)", gprName[first & 7][2]); break; + case 1: sprintf(instr, "CPIR.w WA,(%s+)", gprName[first & 7][2]); break; + } +} + +static void CPD() +{ + switch(size) + { + case 0: sprintf(instr, "CPD.b A,(%s+)", gprName[first & 7][2]); break; + case 1: sprintf(instr, "CPD.w WA,(%s+)", gprName[first & 7][2]); break; + } +} + +static void CPDR() +{ + switch(size) + { + case 0: sprintf(instr, "CPDR.b A,(%s+)", gprName[first & 7][2]); break; + case 1: sprintf(instr, "CPDR.w WA,(%s+)", gprName[first & 7][2]); break; + } +} + +static void LD16m() +{ + sprintf(instr, "LD (0x%04X),(%s)", get16_dis(), extra); +} + +static void LD() +{ + sprintf(instr, "LD %s,(%s)", str_R, extra); +} + +static void EX() +{ + switch(size) + { + case 0: sprintf(instr, "EX.b (%s),%s", extra, str_R); break; + case 1: sprintf(instr, "EX.w (%s),%s", extra, str_R); break; + } + +} + +static void ADDi() +{ + switch(size) + { + case 0: sprintf(instr, "ADD (%s), 0x%02X", extra, get8_dis()); break; + case 1: sprintf(instr, "ADD (%s), 0x%04X", extra, get16_dis()); break; + } +} + +static void ADCi() +{ + switch(size) + { + case 0: sprintf(instr, "ADC (%s), 0x%02X", extra, get8_dis()); break; + case 1: sprintf(instr, "ADC (%s), 0x%04X", extra, get16_dis()); break; + } +} + +static void SUBi() +{ + switch(size) + { + case 0: sprintf(instr, "SUB (%s), 0x%02X", extra, get8_dis()); break; + case 1: sprintf(instr, "SUB (%s), 0x%04X", extra, get16_dis()); break; + } +} + +static void SBCi() +{ + switch(size) + { + case 0: sprintf(instr, "SBC (%s), 0x%02X", extra, get8_dis()); break; + case 1: sprintf(instr, "SBC (%s), 0x%04X", extra, get16_dis()); break; + } +} + +static void ANDi() +{ + switch(size) + { + case 0: sprintf(instr, "AND (%s), 0x%02X", extra, get8_dis()); break; + case 1: sprintf(instr, "AND (%s), 0x%04X", extra, get16_dis()); break; + } +} + +static void XORi() +{ + switch(size) + { + case 0: sprintf(instr, "XOR (%s), 0x%02X", extra, get8_dis()); break; + case 1: sprintf(instr, "XOR (%s), 0x%04X", extra, get16_dis()); break; + } +} + +static void ORi() +{ + switch(size) + { + case 0: sprintf(instr, "OR (%s), 0x%02X", extra, get8_dis()); break; + case 1: sprintf(instr, "OR (%s), 0x%04X", extra, get16_dis()); break; + } +} + +static void CPi() +{ + switch(size) + { + case 0: sprintf(instr, "CP (%s),0x%02X", extra, get8_dis()); break; + case 1: sprintf(instr, "CP (%s),0x%04X", extra, get16_dis()); break; + } +} + +static void MUL() +{ + get_RR_Name(); + switch(size) + { + case 0: sprintf(instr, "MUL.b (%s),(%s)",str_R, extra); break; + case 1: sprintf(instr, "MUL.w (%s),(%s)",str_R, extra); break; + } +} + +static void MULS() +{ + get_RR_Name(); + switch(size) + { + case 0: sprintf(instr, "MULS.b (%s),(%s)",str_R, extra); break; + case 1: sprintf(instr, "MULS.w (%s),(%s)",str_R, extra); break; + } +} + +static void DIV() +{ + get_RR_Name(); + switch(size) + { + case 0: sprintf(instr, "DIV.b (%s),(%s)",str_R, extra); break; + case 1: sprintf(instr, "DIV.w (%s),(%s)",str_R, extra); break; + } +} + +static void DIVS() +{ + get_RR_Name(); + switch(size) + { + case 0: sprintf(instr, "DIVS.b (%s),(%s)",str_R, extra); break; + case 1: sprintf(instr, "DIVS.w (%s),(%s)",str_R, extra); break; + } +} + +static void INC() +{ + uint8 val = (second & 7); + if (val == 0) + val = 8; + + sprintf(instr, "INC %d,(%s)", val, extra); +} + +static void DEC() +{ + uint8 val = (second & 7); + if (val == 0) + val = 8; + + sprintf(instr, "DEC %d,(%s)", val, extra); +} + +static void RLC() +{ + sprintf(instr, "RLC (%s)", extra); +} + +static void RRC() +{ + sprintf(instr, "RRC (%s)", extra); +} + +static void RL() +{ + sprintf(instr, "RL (%s)", extra); +} + +static void RR() +{ + sprintf(instr, "RR (%s)", extra); +} + +static void SLA() +{ + sprintf(instr, "SLA (%s)", extra); +} + +static void SRA() +{ + sprintf(instr, "SRA (%s)", extra); +} + +static void SLL() +{ + sprintf(instr, "SLL (%s)", extra); +} + +static void SRL() +{ + sprintf(instr, "SRL (%s)", extra); +} + +static void ADDRm() +{ + sprintf(instr, "ADD %s,(%s)", str_R, extra); +} + +static void ADDmR() +{ + sprintf(instr, "ADD (%s),%s", extra, str_R); +} + +static void ADCRm() +{ + sprintf(instr, "ADC %s,(%s)", str_R, extra); +} + +static void ADCmR() +{ + sprintf(instr, "ADC (%s),%s", extra, str_R); +} + +static void SUBRm() +{ + sprintf(instr, "SUB %s,(%s)", str_R, extra); +} + +static void SUBmR() +{ + sprintf(instr, "SUB (%s),%s", extra, str_R); +} + +static void SBCRm() +{ + sprintf(instr, "SBC %s,(%s)", str_R, extra); +} + +static void SBCmR() +{ + sprintf(instr, "SBC (%s),%s", extra, str_R); +} + +static void ANDmR() +{ + sprintf(instr, "AND (%s),%s", extra, str_R); +} + +static void ANDRm() +{ + sprintf(instr, "AND %s,(%s)", str_R, extra); +} + +static void XORmR() +{ + sprintf(instr, "XOR (%s),%s", extra, str_R); +} + +static void XORRm() +{ + sprintf(instr, "XOR %s,(%s)", str_R, extra); +} + +static void ORmR() +{ + sprintf(instr, "OR (%s),%s", extra, str_R); +} + +static void ORRm() +{ + sprintf(instr, "OR %s,(%s)", str_R, extra); +} + +static void CPmR() +{ + sprintf(instr, "CP (%s),%s", extra, str_R); +} + +static void CPRm() +{ + sprintf(instr, "CP %s,(%s)", str_R, extra); +} + +//========================================================================= + +//Secondary (SRC) Instruction decode +static void (*decode[256])() = +{ +/*0*/ 0, 0, 0, 0, PUSH, 0, RLD, RRD, + 0, 0, 0, 0, 0, 0, 0, 0, +/*1*/ LDI, LDIR, LDD, LDDR, CPI, CPIR, CPD, CPDR, + 0, LD16m, 0, 0, 0, 0, 0, 0, +/*2*/ LD, LD, LD, LD, LD, LD, LD, LD, + 0, 0, 0, 0, 0, 0, 0, 0, +/*3*/ EX, EX, EX, EX, EX, EX, EX, EX, + ADDi, ADCi, SUBi, SBCi, ANDi, XORi, ORi, CPi, +/*4*/ MUL, MUL, MUL, MUL, MUL, MUL, MUL, MUL, + MULS, MULS, MULS, MULS, MULS, MULS, MULS, MULS, +/*5*/ DIV, DIV, DIV, DIV, DIV, DIV, DIV, DIV, + DIVS, DIVS, DIVS, DIVS, DIVS, DIVS, DIVS, DIVS, +/*6*/ INC, INC, INC, INC, INC, INC, INC, INC, + DEC, DEC, DEC, DEC, DEC, DEC, DEC, DEC, +/*7*/ 0, 0, 0, 0, 0, 0, 0, 0, + RLC, RRC, RL, RR, SLA, SRA, SLL, SRL, +/*8*/ ADDRm, ADDRm, ADDRm, ADDRm, ADDRm, ADDRm, ADDRm, ADDRm, + ADDmR, ADDmR, ADDmR, ADDmR, ADDmR, ADDmR, ADDmR, ADDmR, +/*9*/ ADCRm, ADCRm, ADCRm, ADCRm, ADCRm, ADCRm, ADCRm, ADCRm, + ADCmR, ADCmR, ADCmR, ADCmR, ADCmR, ADCmR, ADCmR, ADCmR, +/*A*/ SUBRm, SUBRm, SUBRm, SUBRm, SUBRm, SUBRm, SUBRm, SUBRm, + SUBmR, SUBmR, SUBmR, SUBmR, SUBmR, SUBmR, SUBmR, SUBmR, +/*B*/ SBCRm, SBCRm, SBCRm, SBCRm, SBCRm, SBCRm, SBCRm, SBCRm, + SBCmR, SBCmR, SBCmR, SBCmR, SBCmR, SBCmR, SBCmR, SBCmR, +/*C*/ ANDRm, ANDRm, ANDRm, ANDRm, ANDRm, ANDRm, ANDRm, ANDRm, + ANDmR, ANDmR, ANDmR, ANDmR, ANDmR, ANDmR, ANDmR, ANDmR, +/*D*/ XORRm, XORRm, XORRm, XORRm, XORRm, XORRm, XORRm, XORRm, + XORmR, XORmR, XORmR, XORmR, XORmR, XORmR, XORmR, XORmR, +/*E*/ ORRm, ORRm, ORRm, ORRm, ORRm, ORRm, ORRm, ORRm, + ORmR, ORmR, ORmR, ORmR, ORmR, ORmR, ORmR, ORmR, +/*F*/ CPRm, CPRm, CPRm, CPRm, CPRm, CPRm, CPRm, CPRm, + CPmR, CPmR, CPmR, CPmR, CPmR, CPmR, CPmR, CPmR +}; + +//============================================================================= + +void TLCS900h_disassemble_src(int opsize) +{ + second = get8_dis(); //Get the second opcode + size = opsize; + + //Prepare 'Big R' + sprintf(str_R, "%s", gprName[second & 7][size]); + + if (decode[second]) + (*decode[second])(); + else + sprintf(instr, "unknown src instr. %02X", second); +} +}; + +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_interpret.cpp b/waterbox/ngp/TLCS-900h/TLCS900h_interpret.cpp new file mode 100644 index 0000000000..275e799b86 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_interpret.cpp @@ -0,0 +1,975 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_interpret.c + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +26 JUL 2002 - neopop_uk +======================================= +- Fixed a nasty bug that only affects [src]"EX (mem), XWA", + it was executing "EX F,F'" instead - Very bad! + +28 JUL 2002 - neopop_uk +======================================= +- Added generic DIV and DIVS functions + +30 AUG 2002 - neopop_uk +======================================= +- Fixed detection of R32+d16 addressing mode. + +02 SEP 2002 - neopop_uk +======================================= +- Added the undocumented type 0x13 R32 address mode. + +09 SEP 2002 - neopop_uk +======================================= +- Extra cycles for addressing modes. + +//--------------------------------------------------------------------------- +*/ + +#include "../neopop.h" +#include "TLCS900h_registers.h" +#include "../interrupt.h" +#include "../mem.h" +#include "../bios.h" +#include "TLCS900h_interpret.h" +#include "TLCS900h_interpret_single.h" +#include "TLCS900h_interpret_src.h" +#include "TLCS900h_interpret_dst.h" +#include "TLCS900h_interpret_reg.h" + +namespace TLCS900H +{ + +static void DUMMY_instruction_error(const char* vaMessage,...) +{ + + +} + +void (*instruction_error)(const char* vaMessage,...) = DUMMY_instruction_error; + +//========================================================================= + +uint32 mem; //Result of addressing mode +int size; //operand size, 0 = Byte, 1 = Word, 2 = Long + +uint8 first; //The first byte +uint8 R; //big R +uint8 second; //The second opcode + +bool brCode; //Register code used? +uint8 rCode; //The code + +int32 cycles; //How many state changes? +int32 cycles_extra; //How many extra state changes? + +//========================================================================= + +uint16 fetch16(void) +{ + uint16 a = loadW(pc); + pc += 2; + return a; +} + +uint32 fetch24(void) +{ + uint32 b, a = loadW(pc); + pc += 2; + b = loadB(pc++); + return (b << 16) | a; +} + +uint32 fetch32(void) +{ + uint32 a = loadL(pc); + pc += 4; + return a; +} + +//============================================================================= + +void parityB(uint8 value) +{ + uint8 count = 0, i; + + for (i = 0; i < 8; i++) + { + if (value & 1) count++; + value >>= 1; + } + + // if (count & 1) == FALSE, means even, thus SET + SETFLAG_V((count & 1) == 0); +} + +void parityW(uint16 value) +{ + uint8 count = 0, i; + + for (i = 0; i < 16; i++) + { + if (value & 1) count++; + value >>= 1; + } + + // if (count & 1) == FALSE, means even, thus SET + SETFLAG_V((count & 1) == 0); +} + +//========================================================================= + +void push8(uint8 data) { REGXSP -= 1; storeB(REGXSP, data);} +void push16(uint16 data) { REGXSP -= 2; storeW(REGXSP, data);} +void push32(uint32 data) { REGXSP -= 4; storeL(REGXSP, data);} + +uint8 pop8(void) { uint8 temp = loadB(REGXSP); REGXSP += 1; return temp;} +uint16 pop16(void) { uint16 temp = loadW(REGXSP); REGXSP += 2; return temp;} +uint32 pop32(void) { uint32 temp = loadL(REGXSP); REGXSP += 4; return temp;} + +//============================================================================= + +uint16 generic_DIV_B(uint16 val, uint8 div) +{ + if (div == 0) + { + SETFLAG_V1 + return (val << 8) | ((val >> 8) ^ 0xFF); + } + else + { + uint16 quo = val / (uint16)div; + uint16 rem = val % (uint16)div; + if (quo > 0xFF) SETFLAG_V1 else SETFLAG_V0 + return (quo & 0xFF) | ((rem & 0xFF) << 8); + } +} + +uint32 generic_DIV_W(uint32 val, uint16 div) +{ + if (div == 0) + { + SETFLAG_V1 + return (val << 16) | ((val >> 16) ^ 0xFFFF); + } + else + { + uint32 quo = val / (uint32)div; + uint32 rem = val % (uint32)div; + if (quo > 0xFFFF) SETFLAG_V1 else SETFLAG_V0 + return (quo & 0xFFFF) | ((rem & 0xFFFF) << 16); + } +} + +//============================================================================= + +uint16 generic_DIVS_B(int16 val, int8 div) +{ + if (div == 0) + { + SETFLAG_V1 + return (val << 8) | ((val >> 8) ^ 0xFF); + } + else + { + int16 quo = val / (int16)div; + int16 rem = val % (int16)div; + if (quo > 0xFF) SETFLAG_V1 else SETFLAG_V0 + return (quo & 0xFF) | ((rem & 0xFF) << 8); + } +} + +uint32 generic_DIVS_W(int32 val, int16 div) +{ + if (div == 0) + { + SETFLAG_V1 + return (val << 16) | ((val >> 16) ^ 0xFFFF); + } + else + { + int32 quo = val / (int32)div; + int32 rem = val % (int32)div; + if (quo > 0xFFFF) SETFLAG_V1 else SETFLAG_V0 + return (quo & 0xFFFF) | ((rem & 0xFFFF) << 16); + } +} + +//============================================================================= + +uint8 generic_ADD_B(uint8 dst, uint8 src) +{ + uint8 half = (dst & 0xF) + (src & 0xF); + uint32 resultC = (uint32)dst + (uint32)src; + uint8 result = (uint8)(resultC & 0xFF); + + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + SETFLAG_H(half > 0xF); + + if ((((int8)dst >= 0) && ((int8)src >= 0) && ((int8)result < 0)) || + (((int8)dst < 0) && ((int8)src < 0) && ((int8)result >= 0))) + {SETFLAG_V1} else {SETFLAG_V0} + + SETFLAG_N0; + SETFLAG_C(resultC > 0xFF); + + return result; +} + +uint16 generic_ADD_W(uint16 dst, uint16 src) +{ + uint16 half = (dst & 0xF) + (src & 0xF); + uint32 resultC = (uint32)dst + (uint32)src; + uint16 result = (uint16)(resultC & 0xFFFF); + + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + SETFLAG_H(half > 0xF); + + if ((((int16)dst >= 0) && ((int16)src >= 0) && ((int16)result < 0)) || + (((int16)dst < 0) && ((int16)src < 0) && ((int16)result >= 0))) + {SETFLAG_V1} else {SETFLAG_V0} + + SETFLAG_N0; + SETFLAG_C(resultC > 0xFFFF); + + return result; +} + +uint32 generic_ADD_L(uint32 dst, uint32 src) +{ + uint64 resultC = (uint64)dst + (uint64)src; + uint32 result = (uint32)(resultC & 0xFFFFFFFF); + + SETFLAG_S(result & 0x80000000); + SETFLAG_Z(result == 0); + + if ((((int32)dst >= 0) && ((int32)src >= 0) && ((int32)result < 0)) || + (((int32)dst < 0) && ((int32)src < 0) && ((int32)result >= 0))) + {SETFLAG_V1} else {SETFLAG_V0} + + SETFLAG_N0; + SETFLAG_C(resultC > 0xFFFFFFFF); + + return result; +} + +//============================================================================= + +uint8 generic_ADC_B(uint8 dst, uint8 src) +{ + uint8 half = (dst & 0xF) + (src & 0xF) + FLAG_C; + uint32 resultC = (uint32)dst + (uint32)src + (uint32)FLAG_C; + uint8 result = (uint8)(resultC & 0xFF); + + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + SETFLAG_H(half > 0xF); + + if ((((int8)dst >= 0) && ((int8)src >= 0) && ((int8)result < 0)) || + (((int8)dst < 0) && ((int8)src < 0) && ((int8)result >= 0))) + {SETFLAG_V1} else {SETFLAG_V0} + + SETFLAG_N0; + SETFLAG_C(resultC > 0xFF); + + return result; +} + +uint16 generic_ADC_W(uint16 dst, uint16 src) +{ + uint16 half = (dst & 0xF) + (src & 0xF) + FLAG_C; + uint32 resultC = (uint32)dst + (uint32)src + (uint32)FLAG_C; + uint16 result = (uint16)(resultC & 0xFFFF); + + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + SETFLAG_H(half > 0xF); + + if ((((int16)dst >= 0) && ((int16)src >= 0) && ((int16)result < 0)) || + (((int16)dst < 0) && ((int16)src < 0) && ((int16)result >= 0))) + {SETFLAG_V1} else {SETFLAG_V0} + + SETFLAG_N0; + SETFLAG_C(resultC > 0xFFFF); + + return result; +} + +uint32 generic_ADC_L(uint32 dst, uint32 src) +{ + uint64 resultC = (uint64)dst + (uint64)src + (uint64)FLAG_C; + uint32 result = (uint32)(resultC & 0xFFFFFFFF); + + SETFLAG_S(result & 0x80000000); + SETFLAG_Z(result == 0); + + if ((((int32)dst >= 0) && ((int32)src >= 0) && ((int32)result < 0)) || + (((int32)dst < 0) && ((int32)src < 0) && ((int32)result >= 0))) + {SETFLAG_V1} else {SETFLAG_V0} + + SETFLAG_N0; + SETFLAG_C(resultC > 0xFFFFFFFF); + + return result; +} + +//============================================================================= + +uint8 generic_SUB_B(uint8 dst, uint8 src) +{ + uint8 half = (dst & 0xF) - (src & 0xF); + uint32 resultC = (uint32)dst - (uint32)src; + uint8 result = (uint8)(resultC & 0xFF); + + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + SETFLAG_H(half > 0xF); + + if ((((int8)dst >= 0) && ((int8)src < 0) && ((int8)result < 0)) || + (((int8)dst < 0) && ((int8)src >= 0) && ((int8)result >= 0))) + {SETFLAG_V1} else {SETFLAG_V0} + + SETFLAG_N1; + SETFLAG_C(resultC > 0xFF); + + return result; +} + +uint16 generic_SUB_W(uint16 dst, uint16 src) +{ + uint16 half = (dst & 0xF) - (src & 0xF); + uint32 resultC = (uint32)dst - (uint32)src; + uint16 result = (uint16)(resultC & 0xFFFF); + + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + SETFLAG_H(half > 0xF); + + if ((((int16)dst >= 0) && ((int16)src < 0) && ((int16)result < 0)) || + (((int16)dst < 0) && ((int16)src >= 0) && ((int16)result >= 0))) + {SETFLAG_V1} else {SETFLAG_V0} + + SETFLAG_N1; + SETFLAG_C(resultC > 0xFFFF); + + return result; +} + +uint32 generic_SUB_L(uint32 dst, uint32 src) +{ + uint64 resultC = (uint64)dst - (uint64)src; + uint32 result = (uint32)(resultC & 0xFFFFFFFF); + + SETFLAG_S(result & 0x80000000); + SETFLAG_Z(result == 0); + + if ((((int32)dst >= 0) && ((int32)src < 0) && ((int32)result < 0)) || + (((int32)dst < 0) && ((int32)src >= 0) && ((int32)result >= 0))) + {SETFLAG_V1} else {SETFLAG_V0} + + SETFLAG_N1; + SETFLAG_C(resultC > 0xFFFFFFFF); + + return result; +} + +//============================================================================= + +uint8 generic_SBC_B(uint8 dst, uint8 src) +{ + uint8 half = (dst & 0xF) - (src & 0xF) - FLAG_C; + uint32 resultC = (uint32)dst - (uint32)src - (uint32)FLAG_C; + uint8 result = (uint8)(resultC & 0xFF); + + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + SETFLAG_H(half > 0xF); + + if ((((int8)dst >= 0) && ((int8)src < 0) && ((int8)result < 0)) || + (((int8)dst < 0) && ((int8)src >= 0) && ((int8)result >= 0))) + {SETFLAG_V1} else {SETFLAG_V0} + + SETFLAG_N1; + SETFLAG_C(resultC > 0xFF); + + return result; +} + +uint16 generic_SBC_W(uint16 dst, uint16 src) +{ + uint16 half = (dst & 0xF) - (src & 0xF) - FLAG_C; + uint32 resultC = (uint32)dst - (uint32)src - (uint32)FLAG_C; + uint16 result = (uint16)(resultC & 0xFFFF); + + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + SETFLAG_H(half > 0xF); + + if ((((int16)dst >= 0) && ((int16)src < 0) && ((int16)result < 0)) || + (((int16)dst < 0) && ((int16)src >= 0) && ((int16)result >= 0))) + {SETFLAG_V1} else {SETFLAG_V0} + + SETFLAG_N1; + SETFLAG_C(resultC > 0xFFFF); + + return result; +} + +uint32 generic_SBC_L(uint32 dst, uint32 src) +{ + uint64 resultC = (uint64)dst - (uint64)src - (uint64)FLAG_C; + uint32 result = (uint32)(resultC & 0xFFFFFFFF); + + SETFLAG_S(result & 0x80000000); + SETFLAG_Z(result == 0); + + if ((((int32)dst >= 0) && ((int32)src < 0) && ((int32)result < 0)) || + (((int32)dst < 0) && ((int32)src >= 0) && ((int32)result >= 0))) + {SETFLAG_V1} else {SETFLAG_V0} + + SETFLAG_N1; + SETFLAG_C(resultC > 0xFFFFFFFF); + + return result; +} + +//============================================================================= + +bool conditionCode(int cc) +{ + switch(cc) + { + case 0: return 0; //(F) + case 1: if (FLAG_S ^ FLAG_V) return 1; else return 0; //(LT) + case 2: if (FLAG_Z | (FLAG_S ^ FLAG_V)) return 1; else return 0; //(LE) + case 3: if (FLAG_C | FLAG_Z) return 1; else return 0; //(ULE) + case 4: if (FLAG_V) return 1; else return 0; //(OV) + case 5: if (FLAG_S) return 1; else return 0; //(MI) + case 6: if (FLAG_Z) return 1; else return 0; //(Z) + case 7: if (FLAG_C) return 1; else return 0; //(C) + case 8: return 1; //always True + case 9: if (FLAG_S ^ FLAG_V) return 0; else return 1; //(GE) + case 10:if (FLAG_Z | (FLAG_S ^ FLAG_V)) return 0; else return 1; //(GT) + case 11:if (FLAG_C | FLAG_Z) return 0; else return 1; //(UGT) + case 12:if (FLAG_V) return 0; else return 1; //(NOV) + case 13:if (FLAG_S) return 0; else return 1; //(PL) + case 14:if (FLAG_Z) return 0; else return 1; //(NZ) + case 15:if (FLAG_C) return 0; else return 1; //(NC) + } + +#ifdef NEOPOP_DEBUG + system_debug_message("Unknown Condition Code %d", cc); +#endif + return FALSE; +} + +//============================================================================= + +uint8 get_rr_Target(void) +{ + uint8 target = 0x80; + + if (size == 0 && first == 0xC7) + return rCode; + + //Create a regCode + switch(first & 7) + { + case 0: if (size == 1) target = 0xE0; break; + case 1: + if (size == 0) target = 0xE0; + if (size == 1) target = 0xE4; + break; + case 2: if (size == 1) target = 0xE8; break; + case 3: + if (size == 0) target = 0xE4; + if (size == 1) target = 0xEC; + break; + case 4: if (size == 1) target = 0xF0; break; + case 5: + if (size == 0) target = 0xE8; + if (size == 1) target = 0xF4; + break; + case 6: if (size == 1) target = 0xF8; break; + case 7: + if (size == 0) target = 0xEC; + if (size == 1) target = 0xFC; + break; + } + + return target; +} + +uint8 get_RR_Target(void) +{ + uint8 target = 0x80; + + //Create a regCode + switch(second & 7) + { + case 0: if (size == 1) target = 0xE0; break; + case 1: + if (size == 0) target = 0xE0; + if (size == 1) target = 0xE4; + break; + case 2: if (size == 1) target = 0xE8; break; + case 3: + if (size == 0) target = 0xE4; + if (size == 1) target = 0xEC; + break; + case 4: if (size == 1) target = 0xF0; break; + case 5: + if (size == 0) target = 0xE8; + if (size == 1) target = 0xF4; + break; + case 6: if (size == 1) target = 0xF8; break; + case 7: + if (size == 0) target = 0xEC; + if (size == 1) target = 0xFC; + break; + } + + return target; +} + +//========================================================================= + +static void ExXWA() {mem = regL(0);} +static void ExXBC() {mem = regL(1);} +static void ExXDE() {mem = regL(2);} +static void ExXHL() {mem = regL(3);} +static void ExXIX() {mem = regL(4);} +static void ExXIY() {mem = regL(5);} +static void ExXIZ() {mem = regL(6);} +static void ExXSP() {mem = regL(7);} + +static void ExXWAd() {mem = regL(0) + (int8)FETCH8; cycles_extra = 2;} +static void ExXBCd() {mem = regL(1) + (int8)FETCH8; cycles_extra = 2;} +static void ExXDEd() {mem = regL(2) + (int8)FETCH8; cycles_extra = 2;} +static void ExXHLd() {mem = regL(3) + (int8)FETCH8; cycles_extra = 2;} +static void ExXIXd() {mem = regL(4) + (int8)FETCH8; cycles_extra = 2;} +static void ExXIYd() {mem = regL(5) + (int8)FETCH8; cycles_extra = 2;} +static void ExXIZd() {mem = regL(6) + (int8)FETCH8; cycles_extra = 2;} +static void ExXSPd() {mem = regL(7) + (int8)FETCH8; cycles_extra = 2;} + +static void Ex8() {mem = FETCH8; cycles_extra = 2;} +static void Ex16() {mem = fetch16(); cycles_extra = 2;} +static void Ex24() {mem = fetch24(); cycles_extra = 3;} + +static void ExR32() +{ + uint8 data = FETCH8; + + if (data == 0x03) + { + uint8 rIndex, r32; + r32 = FETCH8; //r32 + rIndex = FETCH8; //r8 + mem = rCodeL(r32) + (int8)rCodeB(rIndex); + cycles_extra = 8; + return; + } + + if (data == 0x07) + { + uint8 rIndex, r32; + r32 = FETCH8; //r32 + rIndex = FETCH8; //r16 + mem = rCodeL(r32) + (int16)rCodeW(rIndex); + cycles_extra = 8; + return; + } + + //Undocumented mode! + if (data == 0x13) + { + mem = pc + (int16)fetch16(); + cycles_extra = 8; //Unconfirmed... doesn't make much difference + return; + } + + cycles_extra = 5; + + if ((data & 3) == 1) + mem = rCodeL(data) + (int16)fetch16(); + else + mem = rCodeL(data); +} + +static void ExDec() +{ + uint8 data = FETCH8; + uint8 r32 = data & 0xFC; + + cycles_extra = 3; + + switch(data & 3) + { + case 0: rCodeL(r32) -= 1; mem = rCodeL(r32); break; + case 1: rCodeL(r32) -= 2; mem = rCodeL(r32); break; + case 2: rCodeL(r32) -= 4; mem = rCodeL(r32); break; + } +} + +static void ExInc() +{ + uint8 data = FETCH8; + uint8 r32 = data & 0xFC; + + cycles_extra = 3; + + switch(data & 3) + { + case 0: mem = rCodeL(r32); rCodeL(r32) += 1; break; + case 1: mem = rCodeL(r32); rCodeL(r32) += 2; break; + case 2: mem = rCodeL(r32); rCodeL(r32) += 4; break; + } +} + +static void ExRC() +{ + brCode = TRUE; + rCode = FETCH8; + cycles_extra = 1; +} + +//========================================================================= + +//Address Mode & Register Code +static void (*decodeExtra[256])() = +{ +/*0*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/*1*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/*2*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/*3*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/*4*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/*5*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/*6*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/*7*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +/*8*/ ExXWA, ExXBC, ExXDE, ExXHL, ExXIX, ExXIY, ExXIZ, ExXSP, + ExXWAd, ExXBCd, ExXDEd, ExXHLd, ExXIXd, ExXIYd, ExXIZd, ExXSPd, +/*9*/ ExXWA, ExXBC, ExXDE, ExXHL, ExXIX, ExXIY, ExXIZ, ExXSP, + ExXWAd, ExXBCd, ExXDEd, ExXHLd, ExXIXd, ExXIYd, ExXIZd, ExXSPd, +/*A*/ ExXWA, ExXBC, ExXDE, ExXHL, ExXIX, ExXIY, ExXIZ, ExXSP, + ExXWAd, ExXBCd, ExXDEd, ExXHLd, ExXIXd, ExXIYd, ExXIZd, ExXSPd, +/*B*/ ExXWA, ExXBC, ExXDE, ExXHL, ExXIX, ExXIY, ExXIZ, ExXSP, + ExXWAd, ExXBCd, ExXDEd, ExXHLd, ExXIXd, ExXIYd, ExXIZd, ExXSPd, +/*C*/ Ex8, Ex16, Ex24, ExR32, ExDec, ExInc, 0, ExRC, + 0, 0, 0, 0, 0, 0, 0, 0, +/*D*/ Ex8, Ex16, Ex24, ExR32, ExDec, ExInc, 0, ExRC, + 0, 0, 0, 0, 0, 0, 0, 0, +/*E*/ Ex8, Ex16, Ex24, ExR32, ExDec, ExInc, 0, ExRC, + 0, 0, 0, 0, 0, 0, 0, 0, +/*F*/ Ex8, Ex16, Ex24, ExR32, ExDec, ExInc, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +//========================================================================= + +static void e(void) +{ + instruction_error("Unknown instruction %02X", first); +} + +static void es(void) +{ + //instruction_error("Unknown [src] instruction %02X", second); +} + +static void ed(void) +{ + //instruction_error("Unknown [dst] instruction %02X", second); +} + +static void er(void) +{ + //instruction_error("Unknown [reg] instruction %02X", second); +} + +//========================================================================= + +//Secondary (SRC) Instruction decode +static void (*srcDecode[256])() = +{ +/*0*/ es, es, es, es, srcPUSH, es, srcRLD, srcRRD, + es, es, es, es, es, es, es, es, +/*1*/ srcLDI, srcLDIR, srcLDD, srcLDDR, srcCPI, srcCPIR, srcCPD, srcCPDR, + es, srcLD16m, es, es, es, es, es, es, +/*2*/ srcLD, srcLD, srcLD, srcLD, srcLD, srcLD, srcLD, srcLD, + es, es, es, es, es, es, es, es, +/*3*/ srcEX, srcEX, srcEX, srcEX, srcEX, srcEX, srcEX, srcEX, + srcADDi, srcADCi, srcSUBi, srcSBCi, srcANDi, srcXORi, srcORi, srcCPi, +/*4*/ srcMUL, srcMUL, srcMUL, srcMUL, srcMUL, srcMUL, srcMUL, srcMUL, + srcMULS, srcMULS, srcMULS, srcMULS, srcMULS, srcMULS, srcMULS, srcMULS, +/*5*/ srcDIV, srcDIV, srcDIV, srcDIV, srcDIV, srcDIV, srcDIV, srcDIV, + srcDIVS, srcDIVS, srcDIVS, srcDIVS, srcDIVS, srcDIVS, srcDIVS, srcDIVS, +/*6*/ srcINC, srcINC, srcINC, srcINC, srcINC, srcINC, srcINC, srcINC, + srcDEC, srcDEC, srcDEC, srcDEC, srcDEC, srcDEC, srcDEC, srcDEC, +/*7*/ es, es, es, es, es, es, es, es, + srcRLC, srcRRC, srcRL, srcRR, srcSLA, srcSRA, srcSLL, srcSRL, +/*8*/ srcADDRm, srcADDRm, srcADDRm, srcADDRm, srcADDRm, srcADDRm, srcADDRm, srcADDRm, + srcADDmR, srcADDmR, srcADDmR, srcADDmR, srcADDmR, srcADDmR, srcADDmR, srcADDmR, +/*9*/ srcADCRm, srcADCRm, srcADCRm, srcADCRm, srcADCRm, srcADCRm, srcADCRm, srcADCRm, + srcADCmR, srcADCmR, srcADCmR, srcADCmR, srcADCmR, srcADCmR, srcADCmR, srcADCmR, +/*A*/ srcSUBRm, srcSUBRm, srcSUBRm, srcSUBRm, srcSUBRm, srcSUBRm, srcSUBRm, srcSUBRm, + srcSUBmR, srcSUBmR, srcSUBmR, srcSUBmR, srcSUBmR, srcSUBmR, srcSUBmR, srcSUBmR, +/*B*/ srcSBCRm, srcSBCRm, srcSBCRm, srcSBCRm, srcSBCRm, srcSBCRm, srcSBCRm, srcSBCRm, + srcSBCmR, srcSBCmR, srcSBCmR, srcSBCmR, srcSBCmR, srcSBCmR, srcSBCmR, srcSBCmR, +/*C*/ srcANDRm, srcANDRm, srcANDRm, srcANDRm, srcANDRm, srcANDRm, srcANDRm, srcANDRm, + srcANDmR, srcANDmR, srcANDmR, srcANDmR, srcANDmR, srcANDmR, srcANDmR, srcANDmR, +/*D*/ srcXORRm, srcXORRm, srcXORRm, srcXORRm, srcXORRm, srcXORRm, srcXORRm, srcXORRm, + srcXORmR, srcXORmR, srcXORmR, srcXORmR, srcXORmR, srcXORmR, srcXORmR, srcXORmR, +/*E*/ srcORRm, srcORRm, srcORRm, srcORRm, srcORRm, srcORRm, srcORRm, srcORRm, + srcORmR, srcORmR, srcORmR, srcORmR, srcORmR, srcORmR, srcORmR, srcORmR, +/*F*/ srcCPRm, srcCPRm, srcCPRm, srcCPRm, srcCPRm, srcCPRm, srcCPRm, srcCPRm, + srcCPmR, srcCPmR, srcCPmR, srcCPmR, srcCPmR, srcCPmR, srcCPmR, srcCPmR +}; + +//Secondary (DST) Instruction decode +static void (*dstDecode[256])() = +{ +/*0*/ dstLDBi, ed, dstLDWi, ed, dstPOPB, ed, dstPOPW, ed, + ed, ed, ed, ed, ed, ed, ed, ed, +/*1*/ ed, ed, ed, ed, dstLDBm16, ed, dstLDWm16, ed, + ed, ed, ed, ed, ed, ed, ed, ed, +/*2*/ dstLDAW, dstLDAW, dstLDAW, dstLDAW, dstLDAW, dstLDAW, dstLDAW, dstLDAW, + dstANDCFA, dstORCFA, dstXORCFA, dstLDCFA, dstSTCFA, ed, ed, ed, +/*3*/ dstLDAL, dstLDAL, dstLDAL, dstLDAL, dstLDAL, dstLDAL, dstLDAL, dstLDAL, + ed, ed, ed, ed, ed, ed, ed, ed, +/*4*/ dstLDBR, dstLDBR, dstLDBR, dstLDBR, dstLDBR, dstLDBR, dstLDBR, dstLDBR, + ed, ed, ed, ed, ed, ed, ed, ed, +/*5*/ dstLDWR, dstLDWR, dstLDWR, dstLDWR, dstLDWR, dstLDWR, dstLDWR, dstLDWR, + ed, ed, ed, ed, ed, ed, ed, ed, +/*6*/ dstLDLR, dstLDLR, dstLDLR, dstLDLR, dstLDLR, dstLDLR, dstLDLR, dstLDLR, + ed, ed, ed, ed, ed, ed, ed, ed, +/*7*/ ed, ed, ed, ed, ed, ed, ed, ed, + ed, ed, ed, ed, ed, ed, ed, ed, +/*8*/ dstANDCF, dstANDCF, dstANDCF, dstANDCF, dstANDCF, dstANDCF, dstANDCF, dstANDCF, + dstORCF, dstORCF, dstORCF, dstORCF, dstORCF, dstORCF, dstORCF, dstORCF, +/*9*/ dstXORCF, dstXORCF, dstXORCF, dstXORCF, dstXORCF, dstXORCF, dstXORCF, dstXORCF, + dstLDCF, dstLDCF, dstLDCF, dstLDCF, dstLDCF, dstLDCF, dstLDCF, dstLDCF, +/*A*/ dstSTCF, dstSTCF, dstSTCF, dstSTCF, dstSTCF, dstSTCF, dstSTCF, dstSTCF, + dstTSET, dstTSET, dstTSET, dstTSET, dstTSET, dstTSET, dstTSET, dstTSET, +/*B*/ dstRES, dstRES, dstRES, dstRES, dstRES, dstRES, dstRES, dstRES, + dstSET, dstSET, dstSET, dstSET, dstSET, dstSET, dstSET, dstSET, +/*C*/ dstCHG, dstCHG, dstCHG, dstCHG, dstCHG, dstCHG, dstCHG, dstCHG, + dstBIT, dstBIT, dstBIT, dstBIT, dstBIT, dstBIT, dstBIT, dstBIT, +/*D*/ dstJP, dstJP, dstJP, dstJP, dstJP, dstJP, dstJP, dstJP, + dstJP, dstJP, dstJP, dstJP, dstJP, dstJP, dstJP, dstJP, +/*E*/ dstCALL, dstCALL, dstCALL, dstCALL, dstCALL, dstCALL, dstCALL, dstCALL, + dstCALL, dstCALL, dstCALL, dstCALL, dstCALL, dstCALL, dstCALL, dstCALL, +/*F*/ dstRET, dstRET, dstRET, dstRET, dstRET, dstRET, dstRET, dstRET, + dstRET, dstRET, dstRET, dstRET, dstRET, dstRET, dstRET, dstRET +}; + +//Secondary (REG) Instruction decode +static void (*regDecode[256])() = +{ +/*0*/ er, er, er, regLDi, regPUSH, regPOP, regCPL, regNEG, + regMULi, regMULSi, regDIVi, regDIVSi, regLINK, regUNLK, regBS1F, regBS1B, +/*1*/ regDAA, er, regEXTZ, regEXTS, regPAA, er, regMIRR, er, + er, regMULA, er, er, regDJNZ, er, er, er, +/*2*/ regANDCFi, regORCFi, regXORCFi, regLDCFi, regSTCFi, er, er, er, + regANDCFA, regORCFA, regXORCFA, regLDCFA, regSTCFA, er, regLDCcrr, regLDCrcr, +/*3*/ regRES, regSET, regCHG, regBIT, regTSET, er, er, er, + regMINC1, regMINC2, regMINC4, er, regMDEC1, regMDEC2, regMDEC4, er, +/*4*/ regMUL, regMUL, regMUL, regMUL, regMUL, regMUL, regMUL, regMUL, + regMULS, regMULS, regMULS, regMULS, regMULS, regMULS, regMULS, regMULS, +/*5*/ regDIV, regDIV, regDIV, regDIV, regDIV, regDIV, regDIV, regDIV, + regDIVS, regDIVS, regDIVS, regDIVS, regDIVS, regDIVS, regDIVS, regDIVS, +/*6*/ regINC, regINC, regINC, regINC, regINC, regINC, regINC, regINC, + regDEC, regDEC, regDEC, regDEC, regDEC, regDEC, regDEC, regDEC, +/*7*/ regSCC, regSCC, regSCC, regSCC, regSCC, regSCC, regSCC, regSCC, + regSCC, regSCC, regSCC, regSCC, regSCC, regSCC, regSCC, regSCC, +/*8*/ regADD, regADD, regADD, regADD, regADD, regADD, regADD, regADD, + regLDRr, regLDRr, regLDRr, regLDRr, regLDRr, regLDRr, regLDRr, regLDRr, +/*9*/ regADC, regADC, regADC, regADC, regADC, regADC, regADC, regADC, + regLDrR, regLDrR, regLDrR, regLDrR, regLDrR, regLDrR, regLDrR, regLDrR, +/*A*/ regSUB, regSUB, regSUB, regSUB, regSUB, regSUB, regSUB, regSUB, + regLDr3, regLDr3, regLDr3, regLDr3, regLDr3, regLDr3, regLDr3, regLDr3, +/*B*/ regSBC, regSBC, regSBC, regSBC, regSBC, regSBC, regSBC, regSBC, + regEX, regEX, regEX, regEX, regEX, regEX, regEX, regEX, +/*C*/ regAND, regAND, regAND, regAND, regAND, regAND, regAND, regAND, + regADDi, regADCi, regSUBi, regSBCi, regANDi, regXORi, regORi, regCPi, +/*D*/ regXOR, regXOR, regXOR, regXOR, regXOR, regXOR, regXOR, regXOR, + regCPr3, regCPr3, regCPr3, regCPr3, regCPr3, regCPr3, regCPr3, regCPr3, +/*E*/ regOR, regOR, regOR, regOR, regOR, regOR, regOR, regOR, + regRLCi, regRRCi, regRLi, regRRi, regSLAi, regSRAi, regSLLi, regSRLi, +/*F*/ regCP, regCP, regCP, regCP, regCP, regCP, regCP, regCP, + regRLCA, regRRCA, regRLA, regRRA, regSLAA, regSRAA, regSLLA, regSRLA +}; + +//========================================================================= + +static void src_B() +{ + second = FETCH8; //Get the second opcode + R = second & 7; + size = 0; //Byte Size + + (*srcDecode[second])(); //Call +} + +static void src_W() +{ + second = FETCH8; //Get the second opcode + R = second & 7; + size = 1; //Word Size + + (*srcDecode[second])(); //Call +} + +static void src_L() +{ + second = FETCH8; //Get the second opcode + R = second & 7; + size = 2; //Long Size + + (*srcDecode[second])(); //Call +} + +static void dst() +{ + second = FETCH8; //Get the second opcode + R = second & 7; + + (*dstDecode[second])(); //Call +} + +static uint8 rCodeConversionB[8] = { 0xE1, 0xE0, 0xE5, 0xE4, 0xE9, 0xE8, 0xED, 0xEC }; +static uint8 rCodeConversionW[8] = { 0xE0, 0xE4, 0xE8, 0xEC, 0xF0, 0xF4, 0xF8, 0xFC }; +static uint8 rCodeConversionL[8] = { 0xE0, 0xE4, 0xE8, 0xEC, 0xF0, 0xF4, 0xF8, 0xFC }; + +static void reg_B() +{ + second = FETCH8; //Get the second opcode + R = second & 7; + size = 0; //Byte Size + + if (brCode == FALSE) + { + brCode = TRUE; + rCode = rCodeConversionB[first & 7]; + } + + (*regDecode[second])(); //Call +} + +static void reg_W() +{ + second = FETCH8; //Get the second opcode + R = second & 7; + size = 1; //Word Size + + if (brCode == FALSE) + { + brCode = TRUE; + rCode = rCodeConversionW[first & 7]; + } + + (*regDecode[second])(); //Call +} + +static void reg_L() +{ + second = FETCH8; //Get the second opcode + R = second & 7; + size = 2; //Long Size + + if (brCode == FALSE) + { + brCode = TRUE; + rCode = rCodeConversionL[first & 7]; + } + + (*regDecode[second])(); //Call +} + +//============================================================================= + +//Primary Instruction decode +static void (*decode[256])() = +{ +/*0*/ sngNOP, sngNORMAL, sngPUSHSR, sngPOPSR, sngMAX, sngHALT, sngEI, sngRETI, + sngLD8_8, sngPUSH8, sngLD8_16, sngPUSH16, sngINCF, sngDECF, sngRET, sngRETD, +/*1*/ sngRCF, sngSCF, sngCCF, sngZCF, sngPUSHA, sngPOPA, sngEX, sngLDF, + sngPUSHF, sngPOPF, sngJP16, sngJP24, sngCALL16, sngCALL24, sngCALR, iBIOSHLE, +/*2*/ sngLDB, sngLDB, sngLDB, sngLDB, sngLDB, sngLDB, sngLDB, sngLDB, + sngPUSHW, sngPUSHW, sngPUSHW, sngPUSHW, sngPUSHW, sngPUSHW, sngPUSHW, sngPUSHW, +/*3*/ sngLDW, sngLDW, sngLDW, sngLDW, sngLDW, sngLDW, sngLDW, sngLDW, + sngPUSHL, sngPUSHL, sngPUSHL, sngPUSHL, sngPUSHL, sngPUSHL, sngPUSHL, sngPUSHL, +/*4*/ sngLDL, sngLDL, sngLDL, sngLDL, sngLDL, sngLDL, sngLDL, sngLDL, + sngPOPW, sngPOPW, sngPOPW, sngPOPW, sngPOPW, sngPOPW, sngPOPW, sngPOPW, +/*5*/ e, e, e, e, e, e, e, e, + sngPOPL, sngPOPL, sngPOPL, sngPOPL, sngPOPL, sngPOPL, sngPOPL, sngPOPL, +/*6*/ sngJR, sngJR, sngJR, sngJR, sngJR, sngJR, sngJR, sngJR, + sngJR, sngJR, sngJR, sngJR, sngJR, sngJR, sngJR, sngJR, +/*7*/ sngJRL, sngJRL, sngJRL, sngJRL, sngJRL, sngJRL, sngJRL, sngJRL, + sngJRL, sngJRL, sngJRL, sngJRL, sngJRL, sngJRL, sngJRL, sngJRL, +/*8*/ src_B, src_B, src_B, src_B, src_B, src_B, src_B, src_B, + src_B, src_B, src_B, src_B, src_B, src_B, src_B, src_B, +/*9*/ src_W, src_W, src_W, src_W, src_W, src_W, src_W, src_W, + src_W, src_W, src_W, src_W, src_W, src_W, src_W, src_W, +/*A*/ src_L, src_L, src_L, src_L, src_L, src_L, src_L, src_L, + src_L, src_L, src_L, src_L, src_L, src_L, src_L, src_L, +/*B*/ dst, dst, dst, dst, dst, dst, dst, dst, + dst, dst, dst, dst, dst, dst, dst, dst, +/*C*/ src_B, src_B, src_B, src_B, src_B, src_B, e, reg_B, + reg_B, reg_B, reg_B, reg_B, reg_B, reg_B, reg_B, reg_B, +/*D*/ src_W, src_W, src_W, src_W, src_W, src_W, e, reg_W, + reg_W, reg_W, reg_W, reg_W, reg_W, reg_W, reg_W, reg_W, +/*E*/ src_L, src_L, src_L, src_L, src_L, src_L, e, reg_L, + reg_L, reg_L, reg_L, reg_L, reg_L, reg_L, reg_L, reg_L, +/*F*/ dst, dst, dst, dst, dst, dst, e, sngLDX, + sngSWI, sngSWI, sngSWI, sngSWI, sngSWI, sngSWI, sngSWI, sngSWI +}; + +//============================================================================= + +int32 TLCS900h_interpret(void) +{ + brCode = FALSE; + + first = FETCH8; //Get the first byte + + //Is any extra data used by this instruction? + cycles_extra = 0; + if (decodeExtra[first]) + (*decodeExtra[first])(); + + (*decode[first])(); //Decode + + return cycles + cycles_extra; +} + +}; + +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_interpret.h b/waterbox/ngp/TLCS-900h/TLCS900h_interpret.h new file mode 100644 index 0000000000..056b58521e --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_interpret.h @@ -0,0 +1,137 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_interpret.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +21 JUL 2002 - neopop_uk +======================================= +- Added the 'instruction_error' function declaration here. + +28 JUL 2002 - neopop_uk +======================================= +- Removed CYCLE_WARNING as it is now obsolete. +- Added generic DIV prototypes. + +//--------------------------------------------------------------------------- +*/ + +#ifndef __TLCS900H_INTERPRET__ +#define __TLCS900H_INTERPRET__ +namespace TLCS900H +{ + +//============================================================================= + +//Interprets a single instruction from 'pc', +//pc is incremented to the start of the next instruction. +//Returns the number of cycles taken for this instruction +int32 TLCS900h_interpret(void); + +//============================================================================= + +extern uint32 mem; +extern int size; +extern uint8 first; //First byte +extern uint8 second; //Second byte +extern uint8 R; //(second & 7) +extern uint8 rCode; +extern int32 cycles; +extern bool brCode; + +//============================================================================= + +extern void (*instruction_error)(const char* vaMessage,...); + +//============================================================================= + +#define FETCH8 loadB(pc++) + +uint16 fetch16(void); +uint32 fetch24(void); +uint32 fetch32(void); + +//============================================================================= + +void parityB(uint8 value); +void parityW(uint16 value); + +//============================================================================= + +void push8(uint8 data); +void push16(uint16 data); +void push32(uint32 data); + +uint8 pop8(void); +uint16 pop16(void); +uint32 pop32(void); + +//============================================================================= + +//DIV =============== +uint16 generic_DIV_B(uint16 val, uint8 div); +uint32 generic_DIV_W(uint32 val, uint16 div); + +//DIVS =============== +uint16 generic_DIVS_B(int16 val, int8 div); +uint32 generic_DIVS_W(int32 val, int16 div); + +//ADD =============== +uint8 generic_ADD_B(uint8 dst, uint8 src); +uint16 generic_ADD_W(uint16 dst, uint16 src); +uint32 generic_ADD_L(uint32 dst, uint32 src); + +//ADC =============== +uint8 generic_ADC_B(uint8 dst, uint8 src); +uint16 generic_ADC_W(uint16 dst, uint16 src); +uint32 generic_ADC_L(uint32 dst, uint32 src); + +//SUB =============== +uint8 generic_SUB_B(uint8 dst, uint8 src); +uint16 generic_SUB_W(uint16 dst, uint16 src); +uint32 generic_SUB_L(uint32 dst, uint32 src); + +//SBC =============== +uint8 generic_SBC_B(uint8 dst, uint8 src); +uint16 generic_SBC_W(uint16 dst, uint16 src); +uint32 generic_SBC_L(uint32 dst, uint32 src); + +//============================================================================= + +//Confirms a condition code check +bool conditionCode(int cc); + +//============================================================================= + +//Translate an rr or RR value for MUL/MULS/DIV/DIVS +uint8 get_rr_Target(void); +uint8 get_RR_Target(void); + +}; + +//============================================================================= +#endif diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_interpret_dst.cpp b/waterbox/ngp/TLCS-900h/TLCS900h_interpret_dst.cpp new file mode 100644 index 0000000000..e59b3d554c --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_interpret_dst.cpp @@ -0,0 +1,315 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_interpret_dst.c + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +22 JUL 2002 - neopop_uk +======================================= +- Added ANDCF,ORCF and XORCF in # and A modes. These were being used + by one of the obscure pachinko "games". + +23 JUL 2002 - neopop_uk +======================================= +- Added cycle count for TSET. + +16 AUG 2002 - neopop_uk +======================================= +- Replaced 'second & 7' with 'R', clearer, faster - and for some reason + more accurate... oh well! + +21 AUG 2002 - neopop_uk +======================================= +- Added TSET. + +//--------------------------------------------------------------------------- +*/ + +#include "../neopop.h" +#include "TLCS900h_interpret.h" +#include "TLCS900h_registers.h" +#include "../mem.h" + +namespace TLCS900H +{ + +//========================================================================= + +//===== LD (mem),# +void dstLDBi() +{ + storeB(mem, FETCH8); + cycles = 5; +} + +//===== LD (mem),# +void dstLDWi() +{ + storeW(mem, fetch16()); + cycles = 6; +} + +//===== POP (mem) +void dstPOPB() +{ + storeB(mem, pop8()); + cycles = 6; +} + +//===== POP (mem) +void dstPOPW() +{ + storeW(mem, pop16()); + cycles = 6; +} + +//===== LD (mem),(nn) +void dstLDBm16() +{ + storeB(mem, loadB(fetch16())); + cycles = 8; +} + +//===== LD (mem),(nn) +void dstLDWm16() +{ + storeW(mem, loadW(fetch16())); + cycles = 8; +} + +//===== LDA R,mem +void dstLDAW() +{ + regW(R) = (uint16)mem; + cycles = 4; +} + +//===== LDA R,mem +void dstLDAL() +{ + regL(R) = (uint32)mem; + cycles = 4; +} + +//===== ANDCF A,(mem) +void dstANDCFA() +{ + uint8 bit = REGA & 0xF; + uint8 mbit = (loadB(mem) >> bit) & 1; + if (bit < 8) SETFLAG_C(mbit & FLAG_C); + cycles = 8; +} + +//===== ORCF A,(mem) +void dstORCFA() +{ + uint8 bit = REGA & 0xF; + uint8 mbit = (loadB(mem) >> bit) & 1; + if (bit < 8) SETFLAG_C(mbit | FLAG_C); + cycles = 8; +} + +//===== XORCF A,(mem) +void dstXORCFA() +{ + uint8 bit = REGA & 0xF; + uint8 mbit = (loadB(mem) >> bit) & 1; + if (bit < 8) SETFLAG_C(mbit ^ FLAG_C); + cycles = 8; +} + +//===== LDCF A,(mem) +void dstLDCFA() +{ + uint8 bit = REGA & 0xF; + uint8 mask = (1 << bit); + if (bit < 8) SETFLAG_C(loadB(mem) & mask); + cycles = 8; +} + +//===== STCF A,(mem) +void dstSTCFA() +{ + uint8 bit = REGA & 0xF; + uint8 cmask = ~(1 << bit); + uint8 set = FLAG_C << bit; + if (bit < 8) storeB(mem, (loadB(mem) & cmask) | set); + cycles = 8; +} + +//===== LD (mem),R +void dstLDBR() +{ + storeB(mem, regB(R)); + cycles = 4; +} + +//===== LD (mem),R +void dstLDWR() +{ + storeW(mem, regW(R)); + cycles = 4; +} + +//===== LD (mem),R +void dstLDLR() +{ + storeL(mem, regL(R)); + cycles = 6; +} + +//===== ANDCF #3,(mem) +void dstANDCF() +{ + uint8 bit = R; + uint8 mbit = (loadB(mem) >> bit) & 1; + SETFLAG_C(mbit & FLAG_C); + cycles = 8; +} + +//===== ORCF #3,(mem) +void dstORCF() +{ + uint8 bit = R; + uint8 mbit = (loadB(mem) >> bit) & 1; + SETFLAG_C(mbit | FLAG_C); + cycles = 8; +} + +//===== XORCF #3,(mem) +void dstXORCF() +{ + uint8 bit = R; + uint8 mbit = (loadB(mem) >> bit) & 1; + SETFLAG_C(mbit ^ FLAG_C); + cycles = 8; +} + +//===== LDCF #3,(mem) +void dstLDCF() +{ + uint8 bit = R; + uint32 mask = (1 << bit); + SETFLAG_C(loadB(mem) & mask); + cycles = 8; +} + +//===== STCF #3,(mem) +void dstSTCF() +{ + uint8 bit = R; + uint8 cmask = ~(1 << bit); + uint8 set = FLAG_C << bit; + storeB(mem, (loadB(mem) & cmask) | set); + cycles = 8; +} + +//===== TSET #3,(mem) +void dstTSET() +{ + SETFLAG_Z(! (loadB(mem) & (1 << R)) ); + storeB(mem, loadB(mem) | (1 << R)); + + SETFLAG_H1 + SETFLAG_N0 + cycles = 10; +} + +//===== RES #3,(mem) +void dstRES() +{ + storeB(mem, loadB(mem) & (~(1 << R))); + cycles = 8; +} + +//===== SET #3,(mem) +void dstSET() +{ + storeB(mem, loadB(mem) | (1 << R)); + cycles = 8; +} + +//===== CHG #3,(mem) +void dstCHG() +{ + storeB(mem, loadB(mem) ^ (1 << R)); + cycles = 8; +} + +//===== BIT #3,(mem) +void dstBIT() +{ + SETFLAG_Z(! (loadB(mem) & (1 << R)) ); + SETFLAG_H1; + SETFLAG_N0; + cycles = 8; +} + +//===== JP cc,mem +void dstJP() +{ + if (conditionCode(second & 0xF)) + { + pc = mem; + cycles = 9; + } + else + { + cycles = 6; + } +} + +//===== CALL cc,mem +void dstCALL() +{ + if (conditionCode(second & 0xF)) + { + push32(pc); + pc = mem; + cycles = 12; + } + else + { + cycles = 6; + } +} + +//===== RET cc +void dstRET() +{ + if (conditionCode(second & 0xF)) + { + pc = pop32(); + cycles = 12; + } + else + { + cycles = 6; + } +} +}; +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_interpret_dst.h b/waterbox/ngp/TLCS-900h/TLCS900h_interpret_dst.h new file mode 100644 index 0000000000..2a8a579ff7 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_interpret_dst.h @@ -0,0 +1,132 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_interpret_dst.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + +#ifndef __TLCS900H_DST__ +#define __TLCS900H_DST__ + +namespace TLCS900H +{ + +//========================================================================= + +//===== LD (mem),# +void dstLDBi(void); + +//===== LD (mem),# +void dstLDWi(void); + +//===== POP (mem) +void dstPOPB(void); + +//===== POP (mem) +void dstPOPW(void); + +//===== LD (mem),(nn) +void dstLDBm16(void); + +//===== LD (mem),(nn) +void dstLDWm16(void); + +//===== LDA R,mem +void dstLDAW(void); + +//===== LDA R,mem +void dstLDAL(void); + +//===== ANDCF A,(mem) +void dstANDCFA(void); + +//===== ORCF A,(mem) +void dstORCFA(void); + +//===== XORCF A,(mem) +void dstXORCFA(void); + +//===== LDCF A,(mem) +void dstLDCFA(void); + +//===== STCF A,(mem) +void dstSTCFA(void); + +//===== LD (mem),R +void dstLDBR(void); + +//===== LD (mem),R +void dstLDWR(void); + +//===== LD (mem),R +void dstLDLR(void); + +//===== ANDCF #3,(mem) +void dstANDCF(void); + +//===== ORCF #3,(mem) +void dstORCF(void); + +//===== XORCF #3,(mem) +void dstXORCF(void); + +//===== LDCF #3,(mem) +void dstLDCF(void); + +//===== STCF #3,(mem) +void dstSTCF(void); + +//===== TSET #3,(mem) +void dstTSET(void); + +//===== RES #3,(mem) +void dstRES(void); + +//===== SET #3,(mem) +void dstSET(void); + +//===== CHG #3,(mem) +void dstCHG(void); + +//===== BIT #3,(mem) +void dstBIT(void); + +//===== JP cc,mem +void dstJP(void); + +//===== CALL cc,mem +void dstCALL(void); + +//===== RET cc +void dstRET(void); + +}; + +//========================================================================= +#endif diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_interpret_reg.cpp b/waterbox/ngp/TLCS-900h/TLCS900h_interpret_reg.cpp new file mode 100644 index 0000000000..4d928edb70 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_interpret_reg.cpp @@ -0,0 +1,2187 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_interpret_reg.c + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +22 JUL 2002 - neopop_uk +======================================= +- Added ANDCF,ORCF and XORCF in A mode and improved the remaining ones. + +22 JUL 2002 - neopop_uk +======================================= +- Added LINK and UNLK to fix "Rockman Battle and Fighters" + +23 JUL 2002 - neopop_uk +======================================= +- Added MIRR to fix "Card Fighters 2" +- Added cycle counts for TSET. + +28 JUL 2002 - neopop_uk +======================================= +- Converted DIV/DIVS to use the generic function + +16 AUG 2002 - neopop_uk +======================================= +- Removed all of the 'second & 7' with R as it's pre-calculated anyway. +- Fixed V flag emulation of INC/DEC, fixes "Cotton" menus +- Fixed MINC4 + +21 AUG 2002 - neopop_uk +======================================= +- Added TSET and MULA, both untested. + +04 SEP 2002 - neopop_uk +======================================= +- Fixed GCC compatibility. + +//--------------------------------------------------------------------------- +*/ + +#include "../neopop.h" +#include "TLCS900h_interpret.h" +#include "TLCS900h_registers.h" +#include "../mem.h" +#include "../dma.h" + +namespace TLCS900H +{ + +//========================================================================= + +//===== LD r,# +void regLDi() +{ + switch(size) + { + case 0: rCodeB(rCode) = FETCH8; cycles = 4; break; + case 1: rCodeW(rCode) = fetch16(); cycles = 4; break; + case 2: rCodeL(rCode) = fetch32(); cycles = 6; break; + } +} + +//===== PUSH r +void regPUSH() +{ + switch(size) + { + case 0: push8(rCodeB(rCode)); cycles = 5;break; + case 1: push16(rCodeW(rCode)); cycles = 5;break; + case 2: push32(rCodeL(rCode)); cycles = 7;break; + } +} + +//===== POP r +void regPOP() +{ + switch(size) + { + case 0: rCodeB(rCode) = pop8(); cycles = 6;break; + case 1: rCodeW(rCode) = pop16(); cycles = 6;break; + case 2: rCodeL(rCode) = pop32(); cycles = 8;break; + } +} + +//===== CPL r +void regCPL() +{ + switch(size) + { + case 0: rCodeB(rCode) = ~ rCodeB(rCode); break; + case 1: rCodeW(rCode) = ~ rCodeW(rCode); break; + } + + SETFLAG_H1; + SETFLAG_N1; + cycles = 4; +} + +//===== NEG r +void regNEG() +{ + switch(size) + { + case 0: rCodeB(rCode) = generic_SUB_B(0, rCodeB(rCode)); break; + case 1: rCodeW(rCode) = generic_SUB_W(0, rCodeW(rCode)); break; + } + cycles = 5; +} + +//===== MUL rr,# +void regMULi() +{ + uint8 target = get_rr_Target(); + if (target == 0x80) + { +#ifdef NEOPOP_DEBUG + instruction_error("reg: MULi bad \'rr\' dst code"); +#endif + return; + } + + switch(size) + { + case 0: rCodeW(target) = (rCodeW(target) & 0xFF) * FETCH8; + cycles = 18; break; + case 1: rCodeL(target) = (rCodeL(target) & 0xFFFF) * fetch16(); + cycles = 26; break; + } +} + +//===== MULS rr,# +void regMULSi() +{ + uint8 target = get_rr_Target(); + if (target == 0x80) + { + instruction_error("reg: MULSi bad \'rr\' dst code"); + return; + } + + switch(size) + { + case 0: rCodeW(target) = (int8)(rCodeW(target) & 0xFF) * (int8)FETCH8; + cycles = 18; break; + case 1: rCodeL(target) = (int16)(rCodeL(target) & 0xFFFF) * (int16)fetch16(); + cycles = 26; break; + } +} + +//===== DIV rr,# +void regDIVi() +{ + uint8 target = get_rr_Target(); + if (target == 0x80) + { + instruction_error("reg: DIVi bad \'rr\' dst code"); + return; + } + + switch(size) + { + case 0: { rCodeW(target) = generic_DIV_B(rCodeW(target), FETCH8); + cycles = 22; + break; } + + case 1: { rCodeL(target) = generic_DIV_W(rCodeL(target), fetch16()); + cycles = 30; + break; } + } +} + +//===== DIVS rr,# +void regDIVSi() +{ + uint8 target = get_rr_Target(); + if (target == 0x80) + { + instruction_error("reg: DIVSi bad \'rr\' dst code"); + return; + } + + switch(size) + { + case 0: { rCodeW(target) = generic_DIVS_B(rCodeW(target), FETCH8); + cycles = 24; + break; } + + case 1: { rCodeL(target) = generic_DIVS_W(rCodeL(target), fetch16()); + cycles = 32; + break; } + } +} + +//===== LINK r,dd +void regLINK() +{ + int16 d = (int16)fetch16(); + push32(rCodeL(rCode)); + rCodeL(rCode) = REGXSP; + REGXSP += d; + cycles = 10; +} + +//===== UNLK r +void regUNLK() +{ + REGXSP = rCodeL(rCode); + rCodeL(rCode) = pop32(); + cycles = 8; +} + +//===== BS1F A,r +void regBS1F() +{ + uint16 data = rCodeW(rCode), mask = 0x0001; + uint8 i; + + SETFLAG_V0; + for (i = 0; i < 15; i++) + { + if (data & mask) + { + REGA = i; + return; + } + + mask <<= 1; + } + + SETFLAG_V1; + cycles = 4; +} + +//===== BS1B A,r +void regBS1B() +{ + uint16 data = rCodeW(rCode), mask = 0x8000; + uint8 i; + + SETFLAG_V0; + for (i = 0; i < 15; i++) + { + if (data & mask) + { + REGA = 15 - i; + return; + } + + mask >>= 1; + } + + SETFLAG_V1; + cycles = 4; +} + +//===== DAA r +void regDAA() +{ + uint16 resultC; + uint8 src = rCodeB(rCode), result, added = 0, half; + bool setC = FALSE; + + uint8 upper4 = (src & 0xF0); + uint8 lower4 = (src & 0x0F); + + if (FLAG_C) // {C = 1} + { + if (FLAG_H) // {H = 1} + { + setC = TRUE; + added = 0x66; + } + else // {H = 0} + { + if (lower4 < 0x0a) { added = 0x60; } + else { added = 0x66; } + setC = TRUE; + } + } + else // {C = 0} + { + if (FLAG_H) // {H = 1} + { + if (src < 0x9A) { added = 0x06; } + else { added = 0x66; } + } + else // {H = 0} + { + if ((upper4 < 0x90) && (lower4 > 0x9)) { added = 0x06; } + else if ((upper4 > 0x80) && (lower4 > 0x9)) { added = 0x66; } + else if ((upper4 > 0x90) && (lower4 < 0xa)) { added = 0x60; } + } + } + + if (FLAG_N) + { + resultC = (uint16)src - (uint16)added; + half = (src & 0xF) - (added & 0xF); + } + else + { + resultC = (uint16)src + (uint16)added; + half = (src & 0xF) + (added & 0xF); + } + + result = (uint8)(resultC & 0xFF); + + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + SETFLAG_H(half > 0xF); + + if (FLAG_N) SETFLAG_C(result > src || setC) + else SETFLAG_C(result < src || setC) + + parityB(result); + rCodeB(rCode) = result; + cycles = 6; +} + +//===== EXTZ r +void regEXTZ() +{ + switch(size) + { + case 1: rCodeW(rCode) &= 0xFF; break; + case 2: rCodeL(rCode) &= 0xFFFF; break; + } + + cycles = 4; +} + +//===== EXTS r +void regEXTS() +{ + switch(size) + { + case 1: if (rCodeW(rCode) & 0x0080) + { rCodeW(rCode) |= 0xFF00; } else + { rCodeW(rCode) &= 0x00FF; } + break; + + case 2: if (rCodeL(rCode) & 0x00008000) + { rCodeL(rCode) |= 0xFFFF0000; } else + { rCodeL(rCode) &= 0x0000FFFF; } + break; + } + + cycles = 5; +} + +//===== PAA r +void regPAA() +{ + switch(size) + { + case 1: if (rCodeW(rCode) & 0x1) rCodeW(rCode)++; break; + case 2: if (rCodeL(rCode) & 0x1) rCodeL(rCode)++; break; + } + cycles = 4; +} + +//===== MIRR r +void regMIRR() +{ + uint16 src = rCodeW(rCode), dst = 0, bit; + + //Undocumented - see p165 of CPU .PDF + //Seems to mirror bits completely, ie. 1234 -> 4321 + + for (bit = 0; bit < 16; bit++) + if (src & (1 << bit)) + dst |= (1 << (15 - bit)); + + rCodeW(rCode) = dst; + cycles = 4; +} + +//===== MULA rr +void regMULA() +{ + uint32 src = (int16)loadW(regL(2/*XDE*/)) * (int16)loadW(regL(3/*XHL*/)); + uint32 dst = rCodeL(rCode); + uint32 result = dst + src; + + SETFLAG_S(result & 0x80000000); + SETFLAG_Z(result == 0); + + if ((((int32)dst >= 0) && ((int32)src >= 0) && ((int32)result < 0)) || + (((int32)dst < 0) && ((int32)src < 0) && ((int32)result >= 0))) + {SETFLAG_V1} else {SETFLAG_V0} + + cycles = 31; +} + +//===== DJNZ r,d +void regDJNZ() +{ + int8 offset = FETCH8; + + cycles = 7; + + switch(size) + { + case 0: + rCodeB(rCode) --; + if (rCodeB(rCode) != 0) + { + cycles = 11; + pc = pc + offset; + } + break; + + case 1: + rCodeW(rCode) --; + if (rCodeW(rCode) != 0) + { + cycles = 11; + pc = pc + offset; + } + break; + } +} + +//===== ANDCF #,r +void regANDCFi() +{ + uint8 data, bit = FETCH8 & 0xF; + switch(size) + { + case 0: { data = (rCodeB(rCode) >> bit) & 1; + if (bit < 8) SETFLAG_C(FLAG_C & data); + break; } + + case 1: { data = (rCodeW(rCode) >> bit) & 1; + SETFLAG_C(FLAG_C & data); + break; } + } + cycles = 4; +} + +//===== ORCF #,r +void regORCFi() +{ + uint8 data, bit = FETCH8 & 0xF; + switch(size) + { + case 0: { data = (rCodeB(rCode) >> bit) & 1; + if (bit < 8) SETFLAG_C(FLAG_C | data); + break; } + + case 1: { data = (rCodeW(rCode) >> bit) & 1; + SETFLAG_C(FLAG_C | data); + break; } + } + cycles = 4; +} + +//===== XORCF #,r +void regXORCFi() +{ + uint8 data, bit = FETCH8 & 0xF; + switch(size) + { + case 0: { data = (rCodeB(rCode) >> bit) & 1; + if (bit < 8) SETFLAG_C(FLAG_C ^ data); + break; } + + case 1: { data = (rCodeW(rCode) >> bit) & 1; + SETFLAG_C(FLAG_C ^ data); + break; } + } + cycles = 4; +} + +//===== LDCF #,r +void regLDCFi() +{ + uint8 bit = FETCH8 & 0xF; + switch(size) + { + case 0: { uint8 mask = (1 << bit); + if (bit < 8) + SETFLAG_C(rCodeB(rCode) & mask); + break; } + + + case 1: { uint16 mask = (1 << bit); + SETFLAG_C(rCodeW(rCode) & mask); + break; } + } + + cycles = 4; +} + +//===== STCF #,r +void regSTCFi() +{ + uint8 bit = FETCH8 & 0xF; + switch(size) + { + case 0: { uint8 cmask = ~(1 << bit); + uint8 set = FLAG_C << bit; + if (bit < 8) rCodeB(rCode) = (rCodeB(rCode) & cmask) | set; + break; } + + case 1: { uint16 cmask = ~(1 << bit); + uint16 set = FLAG_C << bit; + rCodeW(rCode) = (rCodeW(rCode) & cmask) | set; + break; } + } + + cycles = 4; +} + +//===== ANDCF A,r +void regANDCFA() +{ + uint8 data, bit = REGA & 0xF; + switch(size) + { + case 0: { data = (rCodeB(rCode) >> bit) & 1; + if (bit < 8) SETFLAG_C(FLAG_C & data); + break; } + + case 1: { data = (rCodeW(rCode) >> bit) & 1; + SETFLAG_C(FLAG_C & data); + break; } + } + cycles = 4; +} + +//===== ORCF A,r +void regORCFA() +{ + uint8 data, bit = REGA & 0xF; + switch(size) + { + case 0: { data = (rCodeB(rCode) >> bit) & 1; + if (bit < 8) SETFLAG_C(FLAG_C | data); + break; } + + case 1: { data = (rCodeW(rCode) >> bit) & 1; + SETFLAG_C(FLAG_C | data); + break; } + } + cycles = 4; +} + +//===== XORCF A,r +void regXORCFA() +{ + uint8 data, bit = REGA & 0xF; + switch(size) + { + case 0: { data = (rCodeB(rCode) >> bit) & 1; + if (bit < 8) SETFLAG_C(FLAG_C ^ data); + break; } + + case 1: { data = (rCodeW(rCode) >> bit) & 1; + SETFLAG_C(FLAG_C ^ data); + break; } + } + cycles = 4; +} + +//===== LDCF A,r +void regLDCFA() +{ + uint8 bit = REGA & 0xF; + uint32 mask = (1 << bit); + + switch(size) + { + case 0: if (bit < 8) SETFLAG_C(rCodeB(rCode) & mask); break; + case 1: SETFLAG_C(rCodeW(rCode) & mask); break; + } + + cycles = 4; +} + +//===== STCF A,r +void regSTCFA() +{ + switch(size) + { + case 0: { uint8 bit = REGA & 0xF; + uint8 cmask = ~(1 << bit); + uint8 set = FLAG_C << bit; + if (bit < 8) rCodeB(rCode) = (rCodeB(rCode) & cmask) | set; + break; } + + case 1: { uint8 bit = REGA & 0xF; + uint16 cmask = ~(1 << bit); + uint16 set = FLAG_C << bit; + rCodeW(rCode) = (rCodeW(rCode) & cmask) | set; + break; } + } + + cycles = 4; +} + +//===== LDC cr,r +void regLDCcrr() +{ + uint8 cr = FETCH8; + + switch(size) + { + case 0: dmaStoreB(cr, rCodeB(rCode)); break; + case 1: dmaStoreW(cr, rCodeW(rCode)); break; + case 2: dmaStoreL(cr, rCodeL(rCode)); break; + } + + cycles = 8; +} + +//===== LDC r,cr +void regLDCrcr() +{ + uint8 cr = FETCH8; + + switch(size) + { + case 0: rCodeB(rCode) = dmaLoadB(cr); break; + case 1: rCodeW(rCode) = dmaLoadW(cr); break; + case 2: rCodeL(rCode) = dmaLoadL(cr); break; + } + + cycles = 8; +} + +//===== RES #,r +void regRES() +{ + uint8 b = FETCH8 & 0xF; + + switch(size) + { + case 0: rCodeB(rCode) &= ~(uint8)(1 << b); break; + case 1: rCodeW(rCode) &= ~(uint16)(1 << b); break; + } + + cycles = 4; +} + +//===== SET #,r +void regSET() +{ + uint8 b = FETCH8 & 0xF; + + switch(size) + { + case 0: rCodeB(rCode) |= (1 << b); break; + case 1: rCodeW(rCode) |= (1 << b); break; + } + + cycles = 4; +} + +//===== CHG #,r +void regCHG() +{ + uint8 b = FETCH8 & 0xF; + + switch(size) + { + case 0: rCodeB(rCode) ^= (1 << b); break; + case 1: rCodeW(rCode) ^= (1 << b); break; + } + + cycles = 4; +} + +//===== BIT #,r +void regBIT() +{ + uint8 b = FETCH8 & 0xF; + + switch(size) + { + case 0: SETFLAG_Z(! (rCodeB(rCode) & (1 << b)) ); break; + case 1: SETFLAG_Z(! (rCodeW(rCode) & (1 << b)) ); break; + } + + SETFLAG_H1; + SETFLAG_N0; + cycles = 4; +} + +//===== TSET #,r +void regTSET() +{ + uint8 b = FETCH8 & 0xF; + + switch(size) + { + case 0: SETFLAG_Z(! (rCodeB(rCode) & (1 << b)) ); + rCodeB(rCode) |= (1 << b); + break; + + case 1: SETFLAG_Z(! (rCodeW(rCode) & (1 << b)) ); + rCodeW(rCode) |= (1 << b); + break; + } + + SETFLAG_H1 + SETFLAG_N0 + cycles = 6; +} + +//===== MINC1 #,r +void regMINC1() +{ + uint16 num = fetch16() + 1; + + if (size == 1) + { + if ((rCodeW(rCode) % num) == (num - 1)) + rCodeW(rCode) -= (num - 1); + else + rCodeW(rCode) += 1; + } + + cycles = 8; +} + +//===== MINC2 #,r +void regMINC2() +{ + uint16 num = fetch16() + 2; + + if (size == 1) + { + if ((rCodeW(rCode) % num) == (num - 2)) + rCodeW(rCode) -= (num - 2); + else + rCodeW(rCode) += 2; + } + + cycles = 8; +} + +//===== MINC4 #,r +void regMINC4() +{ + uint16 num = fetch16() + 4; + + if (size == 1) + { + if ((rCodeW(rCode) % num) == (num - 4)) + rCodeW(rCode) -= (num - 4); + else + rCodeW(rCode) += 4; + } + + cycles = 8; +} + +//===== MDEC1 #,r +void regMDEC1() +{ + uint16 num = fetch16() + 1; + + if (size == 1) + { + if ((rCodeW(rCode) % num) == 0) + rCodeW(rCode) += (num - 1); + else + rCodeW(rCode) -= 1; + } + + cycles = 7; +} + +//===== MDEC2 #,r +void regMDEC2() +{ + uint16 num = fetch16() + 2; + + if (size == 1) + { + if ((rCodeW(rCode) % num) == 0) + rCodeW(rCode) += (num - 2); + else + rCodeW(rCode) -= 2; + } + + cycles = 7; +} + +//===== MDEC4 #,r +void regMDEC4() +{ + uint16 num = fetch16() + 4; + + if (size == 1) + { + if ((rCodeW(rCode) % num) == 0) + rCodeW(rCode) += (num - 4); + else + rCodeW(rCode) -= 4; + } + + cycles = 7; +} + +//===== MUL RR,r +void regMUL() +{ + uint8 target = get_RR_Target(); + if (target == 0x80) + { + instruction_error("reg: MUL bad \'RR\' dst code"); + return; + } + + switch(size) + { + case 0: rCodeW(target) = (rCodeW(target) & 0xFF) * rCodeB(rCode); + cycles = 18; break; + case 1: rCodeL(target) = (rCodeL(target) & 0xFFFF) * rCodeW(rCode); + cycles = 26; break; + } +} + +//===== MULS RR,r +void regMULS() +{ + uint8 target = get_RR_Target(); + if (target == 0x80) + { + instruction_error("reg: MUL bad \'RR\' dst code"); + return; + } + + switch(size) + { + case 0: rCodeW(target) = (int8)(rCodeW(target) & 0xFF) * (int8)rCodeB(rCode); + cycles = 18; break; + case 1: rCodeL(target) = (int16)(rCodeL(target) & 0xFFFF) * (int16)rCodeW(rCode); + cycles = 26; break; + } +} + +//===== DIV RR,r +void regDIV() +{ + uint8 target = get_RR_Target(); + if (target == 0x80) + { + instruction_error("reg: DIV bad \'RR\' dst code"); + return; + } + + switch(size) + { + case 0: { rCodeW(target) = generic_DIV_B(rCodeW(target), rCodeB(rCode)); + cycles = 22; + break; } + + case 1: { rCodeL(target) = generic_DIV_W(rCodeL(target), rCodeW(rCode)); + cycles = 30; + break; } + } +} + +//===== DIVS RR,r +void regDIVS() +{ + uint8 target = get_RR_Target(); + if (target == 0x80) + { + instruction_error("reg: DIVS bad \'RR\' dst code"); + return; + } + + switch(size) + { + case 0: { rCodeW(target) = generic_DIVS_B(rCodeW(target), rCodeB(rCode)); + cycles = 24; + break; } + + case 1: { rCodeL(target) = generic_DIVS_W(rCodeL(target), rCodeW(rCode)); + cycles = 32; + break; } + } +} + +//===== INC #3,r +void regINC() +{ + uint8 val = R; + if (val == 0) + val = 8; + + switch(size) + { + case 0: { uint8 dst = rCodeB(rCode); + uint8 half = (dst & 0xF) + val; + uint32 resultC = dst + val; + uint8 result = (uint8)(resultC & 0xFF); + SETFLAG_S(result & 0x80); + + if (((int8)dst >= 0) && ((int8)result < 0)) + {SETFLAG_V1} else {SETFLAG_V0} + + SETFLAG_H(half > 0xF); + SETFLAG_Z(result == 0); + SETFLAG_N0; + rCodeB(rCode) = result; + break; } + + case 1: { rCodeW(rCode) += val; break; } + + case 2: { rCodeL(rCode) += val; break; } + } + + cycles = 4; +} + +//===== DEC #3,r +void regDEC() +{ + uint8 val = R; + if (val == 0) + val = 8; + + switch(size) + { + case 0: { uint8 dst = rCodeB(rCode); + uint8 half = (dst & 0xF) - val; + uint32 resultC = dst - val; + uint8 result = (uint8)(resultC & 0xFF); + SETFLAG_S(result & 0x80); + + if (((int8)dst < 0) && ((int8)result >= 0)) + {SETFLAG_V1} else {SETFLAG_V0} + + SETFLAG_H(half > 0xF); + SETFLAG_Z(result == 0); + SETFLAG_N1; + rCodeB(rCode) = result; + cycles = 4; + break; } + + case 1: { rCodeW(rCode) -= val; cycles = 4; break; } + + case 2: { rCodeL(rCode) -= val; cycles = 5; break; } + } +} + +//===== SCC cc,r +void regSCC() +{ + uint32 result; + + if (conditionCode(second & 0xF)) + result = 1; + else + result = 0; + + switch(size) + { + case 0: rCodeB(rCode) = (uint8)result; break; + case 1: rCodeW(rCode) = (uint16)result; break; + } + + cycles = 6; +} + +//===== LD R,r +void regLDRr() +{ + switch(size) + { + case 0: regB(R) = rCodeB(rCode); break; + case 1: regW(R) = rCodeW(rCode); break; + case 2: regL(R) = rCodeL(rCode); break; + } + + cycles = 4; +} + +//===== LD r,R +void regLDrR() +{ + switch(size) + { + case 0: rCodeB(rCode) = regB(R); break; + case 1: rCodeW(rCode) = regW(R); break; + case 2: rCodeL(rCode) = regL(R); break; + } + + cycles = 4; +} + +//===== ADD R,r +void regADD() +{ + switch(size) + { + case 0: regB(R) = generic_ADD_B(regB(R), rCodeB(rCode)); cycles = 4; break; + case 1: regW(R) = generic_ADD_W(regW(R), rCodeW(rCode)); cycles = 4; break; + case 2: regL(R) = generic_ADD_L(regL(R), rCodeL(rCode)); cycles = 7; break; + } +} + +//===== ADC R,r +void regADC() +{ + switch(size) + { + case 0: regB(R) = generic_ADC_B(regB(R), rCodeB(rCode)); cycles = 4; break; + case 1: regW(R) = generic_ADC_W(regW(R), rCodeW(rCode)); cycles = 4; break; + case 2: regL(R) = generic_ADC_L(regL(R), rCodeL(rCode)); cycles = 7; break; + } +} + +//===== SUB R,r +void regSUB() +{ + switch(size) + { + case 0: regB(R) = generic_SUB_B(regB(R), rCodeB(rCode)); cycles = 4; break; + case 1: regW(R) = generic_SUB_W(regW(R), rCodeW(rCode)); cycles = 4; break; + case 2: regL(R) = generic_SUB_L(regL(R), rCodeL(rCode)); cycles = 7; break; + } +} + +//===== SBC R,r +void regSBC() +{ + switch(size) + { + case 0: regB(R) = generic_SBC_B(regB(R), rCodeB(rCode)); cycles = 4; break; + case 1: regW(R) = generic_SBC_W(regW(R), rCodeW(rCode)); cycles = 4; break; + case 2: regL(R) = generic_SBC_L(regL(R), rCodeL(rCode)); cycles = 7; break; + } +} + +//===== LD r,#3 +void regLDr3() +{ + switch(size) + { + case 0: rCodeB(rCode) = R; break; + case 1: rCodeW(rCode) = R; break; + case 2: rCodeL(rCode) = R; break; + } + + cycles = 4; +} + +//===== EX R,r +void regEX() +{ + switch(size) + { + case 0: { uint8 temp = regB(R); regB(R) = rCodeB(rCode); rCodeB(rCode) = temp; break;} + case 1: { uint16 temp = regW(R); regW(R) = rCodeW(rCode); rCodeW(rCode) = temp; break;} + case 2: { uint32 temp = regL(R); regL(R) = rCodeL(rCode); rCodeL(rCode) = temp; break;} + } + + cycles = 5; +} + +//===== ADD r,# +void regADDi() +{ + switch(size) + { + case 0: rCodeB(rCode) = generic_ADD_B(rCodeB(rCode), FETCH8); cycles = 4;break; + case 1: rCodeW(rCode) = generic_ADD_W(rCodeW(rCode), fetch16()); cycles = 4;break; + case 2: rCodeL(rCode) = generic_ADD_L(rCodeL(rCode), fetch32()); cycles = 7;break; + } +} + +//===== ADC r,# +void regADCi() +{ + switch(size) + { + case 0: rCodeB(rCode) = generic_ADC_B(rCodeB(rCode), FETCH8); cycles = 4;break; + case 1: rCodeW(rCode) = generic_ADC_W(rCodeW(rCode), fetch16()); cycles = 4;break; + case 2: rCodeL(rCode) = generic_ADC_L(rCodeL(rCode), fetch32()); cycles = 7;break; + } +} + +//===== SUB r,# +void regSUBi() +{ + switch(size) + { + case 0: rCodeB(rCode) = generic_SUB_B(rCodeB(rCode), FETCH8); cycles = 4;break; + case 1: rCodeW(rCode) = generic_SUB_W(rCodeW(rCode), fetch16()); cycles = 4;break; + case 2: rCodeL(rCode) = generic_SUB_L(rCodeL(rCode), fetch32()); cycles = 7;break; + } +} + +//===== SBC r,# +void regSBCi() +{ + switch(size) + { + case 0: rCodeB(rCode) = generic_SBC_B(rCodeB(rCode), FETCH8); cycles = 4;break; + case 1: rCodeW(rCode) = generic_SBC_W(rCodeW(rCode), fetch16()); cycles = 4;break; + case 2: rCodeL(rCode) = generic_SBC_L(rCodeL(rCode), fetch32()); cycles = 7;break; + } +} + +//===== CP r,# +void regCPi() +{ + switch(size) + { + case 0: generic_SUB_B(rCodeB(rCode), FETCH8); cycles = 4;break; + case 1: generic_SUB_W(rCodeW(rCode), fetch16());cycles = 4; break; + case 2: generic_SUB_L(rCodeL(rCode), fetch32());cycles = 7; break; + } +} + +//===== AND r,# +void regANDi() +{ + switch(size) + { + case 0: { uint8 result = rCodeB(rCode) & FETCH8; + rCodeB(rCode) = result; + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x80); + parityB(result); + cycles = 4; + break; } + + case 1: { uint16 result = rCodeW(rCode) & fetch16(); + rCodeW(rCode) = result; + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x8000); + parityW(result); + cycles = 4; + break; } + + case 2: { uint32 result = rCodeL(rCode) & fetch32(); + rCodeL(rCode) = result; + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x80000000); + cycles = 7; + break; } + } + + SETFLAG_H1; + SETFLAG_N0; + SETFLAG_C0; +} + +//===== OR r,# +void regORi() +{ + switch(size) + { + case 0: { uint8 result = rCodeB(rCode) | FETCH8; + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + rCodeB(rCode) = result; + parityB(result); + cycles = 4; + break; } + + case 1: { uint16 result = rCodeW(rCode) | fetch16(); + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + rCodeW(rCode) = result; + parityW(result); + cycles = 4; + break; } + + case 2: { uint32 result = rCodeL(rCode) | fetch32(); + SETFLAG_S(result & 0x80000000); + SETFLAG_Z(result == 0); + rCodeL(rCode) = result; + cycles = 7; + break; } + } + + SETFLAG_H0; + SETFLAG_N0; + SETFLAG_C0; +} + +//===== XOR r,# +void regXORi() +{ + switch(size) + { + case 0: { uint8 result = rCodeB(rCode) ^ FETCH8; + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + rCodeB(rCode) = result; + parityB(result); + cycles = 4; + break; } + + case 1: { uint16 result = rCodeW(rCode) ^ fetch16(); + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + rCodeW(rCode) = result; + parityW(result); + cycles = 4; + break; } + + case 2: { uint32 result = rCodeL(rCode) ^ fetch32(); + SETFLAG_S(result & 0x80000000); + SETFLAG_Z(result == 0); + rCodeL(rCode) = result; + cycles = 7; + break; } + } + + SETFLAG_H0; + SETFLAG_N0; + SETFLAG_C0; +} + +//===== AND R,r +void regAND() +{ + switch(size) + { + case 0: { uint8 result = regB(R) & rCodeB(rCode); + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + regB(R) = result; + parityB(result); + cycles = 4; + break; } + + case 1: { uint16 result = regW(R) & rCodeW(rCode); + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + regW(R) = result; + parityW(result); + cycles = 4; + break; } + + case 2: { uint32 result = regL(R) & rCodeL(rCode); + SETFLAG_S(result & 0x80000000); + SETFLAG_Z(result == 0); + regL(R) = result; + cycles = 7; + break; } + } + + SETFLAG_H1; + SETFLAG_N0; + SETFLAG_C0; +} + +//===== OR R,r +void regOR() +{ + switch(size) + { + case 0: { uint8 result = regB(R) | rCodeB(rCode); + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + regB(R) = result; + parityB(result); + cycles = 4; + break; } + + case 1: { uint16 result = regW(R) | rCodeW(rCode); + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + regW(R) = result; + parityW(result); + cycles = 4; + break; } + + case 2: { uint32 result = regL(R) | rCodeL(rCode); + SETFLAG_S(result & 0x80000000); + SETFLAG_Z(result == 0); + regL(R) = result; + cycles = 7; + break; } + } + + SETFLAG_H0; + SETFLAG_N0; + SETFLAG_C0; +} + +//===== XOR R,r +void regXOR() +{ + switch(size) + { + case 0: { uint8 result = regB(R) ^ rCodeB(rCode); + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + regB(R) = result; + parityB(result); + cycles = 4; + break; } + + case 1: { uint16 result = regW(R) ^ rCodeW(rCode); + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + regW(R) = result; + parityW(result); + cycles = 4; + break; } + + case 2: { uint32 result = regL(R) ^ rCodeL(rCode); + SETFLAG_S(result & 0x80000000); + SETFLAG_Z(result == 0); + regL(R) = result; + cycles = 7; + break; } + } + + SETFLAG_H0; + SETFLAG_N0; + SETFLAG_C0; +} + +//===== CP r,#3 +void regCPr3() +{ + switch(size) + { + case 0: generic_SUB_B(rCodeB(rCode), R); break; + case 1: generic_SUB_W(rCodeW(rCode), R); break; + } + + cycles = 4; +} + +//===== CP R,r +void regCP() +{ + switch(size) + { + case 0: generic_SUB_B(regB(R), rCodeB(rCode));cycles = 4; break; + case 1: generic_SUB_W(regW(R), rCodeW(rCode));cycles = 4; break; + case 2: generic_SUB_L(regL(R), rCodeL(rCode));cycles = 7; break; + } +} + +//===== RLC #,r +void regRLCi() +{ + int i; + uint8 sa = FETCH8 & 0xF; + if (sa == 0) sa = 16; + + switch(size) + { + case 0: for (i = 0; i < sa; i++) + { + SETFLAG_C(rCodeB(rCode) & 0x80); + rCodeB(rCode) <<= 1; + if (FLAG_C) rCodeB(rCode) |= 1; + } + SETFLAG_S(rCodeB(rCode) & 0x80); + SETFLAG_Z(rCodeB(rCode) == 0); + parityB(rCodeB(rCode)); + cycles = 6 + (2*sa); + break; + + case 1: for (i = 0; i < sa; i++) + { + SETFLAG_C(rCodeW(rCode) & 0x8000); + rCodeW(rCode) <<= 1; + if (FLAG_C) rCodeW(rCode) |= 1; + } + SETFLAG_S(rCodeW(rCode) & 0x8000); + SETFLAG_Z(rCodeW(rCode) == 0); + parityW(rCodeW(rCode)); + cycles = 6 + (2*sa); + break; + + case 2: for (i = 0; i < sa; i++) + { + SETFLAG_C(rCodeL(rCode) & 0x80000000); + rCodeL(rCode) <<= 1; + if (FLAG_C) rCodeL(rCode) |= 1; + } + SETFLAG_S(rCodeL(rCode) & 0x80000000); + SETFLAG_Z(rCodeL(rCode) == 0); + cycles = 8 + (2*sa); + break; + } + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== RRC #,r +void regRRCi() +{ + int i; + uint8 sa = FETCH8 & 0xF; + if (sa == 0) sa = 16; + + switch(size) + { + case 0: for (i = 0; i < sa; i++) + { + SETFLAG_C(rCodeB(rCode) & 1); + rCodeB(rCode) >>= 1; + if (FLAG_C) rCodeB(rCode) |= 0x80; + } + SETFLAG_S(rCodeB(rCode) & 0x80); + SETFLAG_Z(rCodeB(rCode) == 0); + parityB(rCodeB(rCode)); + cycles = 6 + (2*sa); + break; + + case 1: for (i = 0; i < sa; i++) + { + SETFLAG_C(rCodeW(rCode) & 1); + rCodeW(rCode) >>= 1; + if (FLAG_C) rCodeW(rCode) |= 0x8000; + } + SETFLAG_S(rCodeW(rCode) & 0x8000); + SETFLAG_Z(rCodeW(rCode) == 0); + parityW(rCodeW(rCode)); + cycles = 6 + (2*sa); + break; + + case 2: for (i = 0; i < sa; i++) + { + SETFLAG_C(rCodeL(rCode) & 1); + rCodeL(rCode) >>= 1; + if (FLAG_C) rCodeL(rCode) |= 0x80000000; + } + SETFLAG_S(rCodeL(rCode) & 0x80000000); + SETFLAG_Z(rCodeL(rCode) == 0); + cycles = 8 + (2*sa); + break; + } + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== RL #,r +void regRLi() +{ + int i; + bool tempC; + uint8 sa = FETCH8 & 0xF; + if (sa == 0) sa = 16; + + switch(size) + { + case 0: { uint8 result; + for (i = 0; i < sa; i++) + { + result = rCodeB(rCode); + tempC = FLAG_C; + SETFLAG_C(result & 0x80); + result <<= 1; + if (tempC) result |= 1; + rCodeB(rCode) = result; + } + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + parityB(result); + cycles = 6 + (2*sa); + break; } + + case 1: { uint16 result; + for (i = 0; i < sa; i++) + { + result = rCodeW(rCode); + tempC = FLAG_C; + SETFLAG_C(result & 0x8000); + result <<= 1; + if (tempC) result |= 1; + rCodeW(rCode) = result; + } + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + parityW(result); + cycles = 6 + (2*sa); + break; } + + case 2: { uint32 result; + for (i = 0; i < sa; i++) + { + result = rCodeL(rCode); + tempC = FLAG_C; + SETFLAG_C(result & 0x80000000); + result <<= 1; + if (tempC) result |= 1; + rCodeL(rCode) = result; + } + SETFLAG_S(result & 0x80000000); + SETFLAG_Z(result == 0); + cycles = 8 + (2*sa); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== RR #,r +void regRRi() +{ + int i; + bool tempC; + uint8 sa = FETCH8 & 0xF; + if (sa == 0) sa = 16; + + switch(size) + { + case 0: { uint8 result; + for (i = 0; i < sa; i++) + { + result = rCodeB(rCode); + tempC = FLAG_C; + SETFLAG_C(result & 0x01); + result >>= 1; + if (tempC) result |= 0x80; + rCodeB(rCode) = result; + } + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + cycles = 6 + (2*sa); + parityB(result); + break; } + + case 1: { uint16 result; + for (i = 0; i < sa; i++) + { + result = rCodeW(rCode); + tempC = FLAG_C; + SETFLAG_C(result & 0x01); + result >>= 1; + if (tempC) result |= 0x8000; + rCodeW(rCode) = result; + } + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + cycles = 6 + (2*sa); + parityW(result); + break; } + + case 2: { uint32 result; + for (i = 0; i < sa; i++) + { + result = rCodeL(rCode); + tempC = FLAG_C; + SETFLAG_C(result & 0x01); + result >>= 1; + if (tempC) result |= 0x80000000; + rCodeL(rCode) = result; + } + SETFLAG_S(result & 0x80000000); + SETFLAG_Z(result == 0); + cycles = 8 + (2*sa); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== SLA #,r +void regSLAi() +{ + int8 sa = FETCH8 & 0xF; + if (sa == 0) sa = 16; + sa--; + + switch(size) + { + case 0: { int8 result, data = (int8)rCodeB(rCode); + result = (data << sa); + SETFLAG_C(result & 0x80); + result <<= 1; + SETFLAG_S(result & 0x80); + rCodeB(rCode) = result; + SETFLAG_Z(result == 0); + parityB(result); + cycles = 6 + 2 + (2*sa); + break; } + + case 1: { int16 result, data = (int16)rCodeW(rCode); + result = (data << sa); + SETFLAG_C(result & 0x8000); + result <<= 1; + SETFLAG_S(result & 0x8000); + rCodeW(rCode) = result; + SETFLAG_Z(result == 0); + parityW(result); + cycles = 6 + 2 + (2*sa); + break; } + + case 2: { int32 result, data = (int32)rCodeL(rCode); + result = (data << sa); + SETFLAG_C(result & 0x80000000); + result <<= 1; + SETFLAG_S(result & 0x80000000); + rCodeL(rCode) = result; + SETFLAG_Z(result == 0); + cycles = 8 + 2 + (2*sa); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== SRA #,r +void regSRAi() +{ + int8 sa = FETCH8 & 0xF; + if (sa == 0) sa = 16; + sa--; + + switch(size) + { + case 0: { int8 data = (int8)rCodeB(rCode), result; + result = (data >> sa); + SETFLAG_C(result & 1); + result >>= 1; + SETFLAG_S(result & 0x80); + rCodeB(rCode) = result; + SETFLAG_Z(result == 0); + parityB(result); + cycles = 6 + 2 + (2*sa); + break; } + + case 1: { int16 data = (int16)rCodeW(rCode), result; + result = (data >> sa); + SETFLAG_C(result & 1); + result >>= 1; + SETFLAG_S(result & 0x8000); + rCodeW(rCode) = result; + SETFLAG_Z(result == 0); + parityW(result); + cycles = 6 + 2 + (2*sa); + break; } + + case 2: { int32 data = (int32)rCodeL(rCode), result; + result = (data >> sa); + SETFLAG_C(result & 1); + result >>= 1; + SETFLAG_S(result & 0x80000000); + rCodeL(rCode) = result; + SETFLAG_Z(result == 0); + cycles = 8 + 2 + (2*sa); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== SLL #,r +void regSLLi() +{ + uint8 sa = FETCH8 & 0xF; + if (sa == 0) sa = 16; + sa--; + + switch(size) + { + case 0: { uint8 result, data = rCodeB(rCode); + result = (data << sa); + SETFLAG_C(result & 0x80); + result <<= 1; + SETFLAG_S(result & 0x80); + rCodeB(rCode) = result; + SETFLAG_Z(result == 0); + parityB(result); + cycles = 6 + 2 + (2*sa); + break; } + + case 1: { uint16 result, data = rCodeW(rCode); + result = (data << sa); + SETFLAG_C(result & 0x8000); + result <<= 1; + SETFLAG_S(result & 0x8000); + rCodeW(rCode) = result; + SETFLAG_Z(result == 0); + parityW(result); + cycles = 6 + 2 + (2*sa); + break; } + + case 2: { uint32 result, data = rCodeL(rCode); + result = (data << sa); + SETFLAG_C(result & 0x80000000); + result <<= 1; + SETFLAG_S(result & 0x80000000); + rCodeL(rCode) = result; + SETFLAG_Z(result == 0); + cycles = 8 + 2 + (2*sa); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== SRL #,r +void regSRLi() +{ + uint8 sa = FETCH8 & 0xF; + if (sa == 0) sa = 16; + sa--; + + switch(size) + { + case 0: { uint8 data = rCodeB(rCode), result; + result = (data >> sa); + SETFLAG_C(result & 1); + result >>= 1; + SETFLAG_S(result & 0x80); + rCodeB(rCode) = result; + SETFLAG_Z(result == 0); + parityB(result); + cycles = 6 + 2 + (2*sa); + break; } + + case 1: { uint16 data = rCodeW(rCode), result; + result = (data >> sa); + SETFLAG_C(result & 1); + result >>= 1; + SETFLAG_S(result & 0x8000); + rCodeW(rCode) = result; + SETFLAG_Z(result == 0); + parityW(result); + cycles = 6 + 2 + (2*sa); + break; } + + case 2: { uint32 data = rCodeL(rCode), result; + result = (data >> sa); + SETFLAG_C(result & 1); + result >>= 1; + SETFLAG_S(result & 0x80000000); + rCodeL(rCode) = result; + SETFLAG_Z(result == 0); + cycles = 8 + 2 + (2*sa); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== RLC A,r +void regRLCA() +{ + int i; + uint8 sa = REGA & 0xF; + if (sa == 0) sa = 16; + + switch(size) + { + case 0: for (i = 0; i < sa; i++) + { + SETFLAG_C(rCodeB(rCode) & 0x80); + rCodeB(rCode) <<= 1; + if (FLAG_C) rCodeB(rCode) |= 1; + } + SETFLAG_S(rCodeB(rCode) & 0x80); + SETFLAG_Z(rCodeB(rCode) == 0); + cycles = 6 + (2*sa); + parityB(rCodeB(rCode)); + break; + + case 1: for (i = 0; i < sa; i++) + { + SETFLAG_C(rCodeW(rCode) & 0x8000); + rCodeW(rCode) <<= 1; + if (FLAG_C) rCodeW(rCode) |= 1; + } + SETFLAG_S(rCodeW(rCode) & 0x8000); + SETFLAG_Z(rCodeW(rCode) == 0); + cycles = 6 + (2*sa); + parityW(rCodeW(rCode)); + break; + + case 2: for (i = 0; i < sa; i++) + { + SETFLAG_C(rCodeL(rCode) & 0x80000000); + rCodeL(rCode) <<= 1; + if (FLAG_C) rCodeL(rCode) |= 1; + } + SETFLAG_S(rCodeL(rCode) & 0x80000000); + SETFLAG_Z(rCodeL(rCode) == 0); + cycles = 8 + (2*sa); + break; + } + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== RRC A,r +void regRRCA() +{ + int i; + uint8 sa = REGA & 0xF; + if (sa == 0) sa = 16; + + switch(size) + { + case 0: for (i = 0; i < sa; i++) + { + SETFLAG_C(rCodeB(rCode) & 1); + rCodeB(rCode) >>= 1; + if (FLAG_C) rCodeB(rCode) |= 0x80; + } + SETFLAG_S(rCodeB(rCode) & 0x80); + SETFLAG_Z(rCodeB(rCode) == 0); + parityB(rCodeB(rCode)); + cycles = 6 + (2*sa); + break; + + case 1: for (i = 0; i < sa; i++) + { + SETFLAG_C(rCodeW(rCode) & 1); + rCodeW(rCode) >>= 1; + if (FLAG_C) rCodeW(rCode) |= 0x8000; + } + SETFLAG_S(rCodeW(rCode) & 0x8000); + SETFLAG_Z(rCodeW(rCode) == 0); + parityW(rCodeW(rCode)); + cycles = 6 + (2*sa); + break; + + case 2: for (i = 0; i < sa; i++) + { + SETFLAG_C(rCodeL(rCode) & 1); + rCodeL(rCode) >>= 1; + if (FLAG_C) rCodeL(rCode) |= 0x80000000; + } + SETFLAG_S(rCodeL(rCode) & 0x80000000); + SETFLAG_Z(rCodeL(rCode) == 0); + cycles = 8 + (2*sa); + break; + } + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== RL A,r +void regRLA() +{ + int i; + bool tempC; + uint8 sa = REGA & 0xF; + if (sa == 0) sa = 16; + + switch(size) + { + case 0: { uint8 result; + for (i = 0; i < sa; i++) + { + result = rCodeB(rCode); + tempC = FLAG_C; + SETFLAG_C(result & 0x80); + result <<= 1; + if (tempC) result |= 1; + rCodeB(rCode) = result; + } + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + cycles = 6 + (2*sa); + parityB(result); + break; } + + case 1: { uint16 result; + for (i = 0; i < sa; i++) + { + result = rCodeW(rCode); + tempC = FLAG_C; + SETFLAG_C(result & 0x8000); + result <<= 1; + if (tempC) result |= 1; + rCodeW(rCode) = result; + } + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + cycles = 6 + (2*sa); + parityW(result); + break; } + + case 2: { uint32 result; + for (i = 0; i < sa; i++) + { + result = rCodeL(rCode); + tempC = FLAG_C; + SETFLAG_C(result & 0x80000000); + result <<= 1; + if (tempC) result |= 1; + rCodeL(rCode) = result; + } + SETFLAG_S(result & 0x80000000); + SETFLAG_Z(result == 0); + cycles = 8 + (2*sa); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== RR A,r +void regRRA() +{ + int i; + bool tempC; + uint8 sa = REGA & 0xF; + if (sa == 0) sa = 16; + + switch(size) + { + case 0: { uint8 result; + for (i = 0; i < sa; i++) + { + result = rCodeB(rCode); + tempC = FLAG_C; + SETFLAG_C(result & 0x01); + result >>= 1; + if (tempC) result |= 0x80; + rCodeB(rCode) = result; + } + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + cycles = 6 + (2*sa); + parityB(result); + break; } + + case 1: { uint16 result; + for (i = 0; i < sa; i++) + { + result = rCodeW(rCode); + tempC = FLAG_C; + SETFLAG_C(result & 0x01); + result >>= 1; + if (tempC) result |= 0x8000; + rCodeW(rCode) = result; + } + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + cycles = 6 + (2*sa); + parityW(result); + break; } + + case 2: { uint32 result; + for (i = 0; i < sa; i++) + { + result = rCodeL(rCode); + tempC = FLAG_C; + SETFLAG_C(result & 0x01); + result >>= 1; + if (tempC) result |= 0x80000000; + rCodeL(rCode) = result; + } + SETFLAG_S(result & 0x80000000); + SETFLAG_Z(result == 0); + cycles = 8 + (2*sa); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== SLA A,r +void regSLAA() +{ + int8 sa = REGA & 0xF; + if (sa == 0) sa = 16; + sa--; + + switch(size) + { + case 0: { int8 result, data = (int8)rCodeB(rCode); + result = (data << sa); + SETFLAG_C(result & 0x80); + result <<= 1; + SETFLAG_S(result & 0x80); + rCodeB(rCode) = result; + SETFLAG_Z(result == 0); + parityB(result); + cycles = 6 + 2 + (2*sa); + break; } + + case 1: { int16 result, data = (int16)rCodeW(rCode); + result = (data << sa); + SETFLAG_C(result & 0x8000); + result <<= 1; + SETFLAG_S(result & 0x8000); + rCodeW(rCode) = result; + SETFLAG_Z(result == 0); + parityW(result); + cycles = 6 + 2 + (2*sa); + break; } + + case 2: { int32 result, data = (int32)rCodeL(rCode); + result = (data << sa); + SETFLAG_C(result & 0x80000000); + result <<= 1; + SETFLAG_S(result & 0x80000000); + rCodeL(rCode) = result; + SETFLAG_Z(result == 0); + cycles = 8 + 2 + (2*sa); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== SRA A,r +void regSRAA() +{ + int8 sa = REGA & 0xF; + if (sa == 0) sa = 16; + sa--; + + switch(size) + { + case 0: { int8 data = (int8)rCodeB(rCode), result; + result = (data >> sa); + SETFLAG_C(result & 1); + result >>= 1; + SETFLAG_S(result & 0x80); + rCodeB(rCode) = result; + SETFLAG_Z(result == 0); + parityB(result); + cycles = 6 + 2 + (2*sa); + break; } + + case 1: { int16 data = (int16)rCodeW(rCode), result; + result = (data >> sa); + SETFLAG_C(result & 1); + result >>= 1; + SETFLAG_S(result & 0x8000); + rCodeW(rCode) = result; + SETFLAG_Z(result == 0); + parityW(result); + cycles = 6 + 2 + (2*sa); + break; } + + case 2: { int32 data = (int32)rCodeL(rCode), result; + result = (data >> sa); + SETFLAG_C(result & 1); + result >>= 1; + SETFLAG_S(result & 0x80000000); + rCodeL(rCode) = result; + SETFLAG_Z(result == 0); + cycles = 8 + 2 + (2*sa); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== SLL A,r +void regSLLA() +{ + uint8 sa = REGA & 0xF; + if (sa == 0) sa = 16; + sa--; + + switch(size) + { + case 0: { uint8 result, data = rCodeB(rCode); + result = (data << sa); + SETFLAG_C(result & 0x80); + result <<= 1; + SETFLAG_S(result & 0x80); + rCodeB(rCode) = result; + SETFLAG_Z(result == 0); + parityB(result); + cycles = 6 + 2 + (2*sa); + break; } + + case 1: { uint16 result, data = rCodeW(rCode); + result = (data << sa); + SETFLAG_C(result & 0x8000); + result <<= 1; + SETFLAG_S(result & 0x8000); + rCodeW(rCode) = result; + SETFLAG_Z(result == 0); + parityW(result); + cycles = 6 + 2 + (2*sa); + break; } + + case 2: { uint32 result, data = rCodeL(rCode); + result = (data << sa); + SETFLAG_C(result & 0x80000000); + result <<= 1; + SETFLAG_S(result & 0x80000000); + rCodeL(rCode) = result; + SETFLAG_Z(result == 0); + cycles = 8 + 2 + (2*sa); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== SRL A,r +void regSRLA() +{ + uint8 sa = REGA & 0xF; + if (sa == 0) sa = 16; + sa--; + + switch(size) + { + case 0: { uint8 data = rCodeB(rCode), result; + result = (data >> sa); + SETFLAG_C(result & 1); + result >>= 1; + SETFLAG_S(result & 0x80); + rCodeB(rCode) = result; + SETFLAG_Z(result == 0); + parityB(result); + cycles = 6 + 2 + (2*sa); + break; } + + case 1: { uint16 data = rCodeW(rCode), result; + result = (data >> sa); + SETFLAG_C(result & 1); + result >>= 1; + SETFLAG_S(result & 0x8000); + rCodeW(rCode) = result; + SETFLAG_Z(result == 0); + parityW(result); + cycles = 6 + 2 + (2*sa); + break; } + + case 2: { uint32 data = rCodeL(rCode), result; + result = (data >> sa); + SETFLAG_C(result & 1); + result >>= 1; + SETFLAG_S(result & 0x80000000); + rCodeL(rCode) = result; + SETFLAG_Z(result == 0); + cycles = 8 + 2 + (2*sa); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; +} + +}; + +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_interpret_reg.h b/waterbox/ngp/TLCS-900h/TLCS900h_interpret_reg.h new file mode 100644 index 0000000000..1895c8dc62 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_interpret_reg.h @@ -0,0 +1,305 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_interpret_reg.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + +#ifndef __TLCS900H_REG__ +#define __TLCS900H_REG__ +//========================================================================= + +namespace TLCS900H +{ + +//===== LD r,# +void regLDi(void); + +//===== PUSH r +void regPUSH(void); + +//===== POP r +void regPOP(void); + +//===== CPL r +void regCPL(void); + +//===== NEG r +void regNEG(void); + +//===== MUL rr,# +void regMULi(void); + +//===== MULS rr,# +void regMULSi(void); + +//===== DIV rr,# +void regDIVi(void); + +//===== DIVS rr,# +void regDIVSi(void); + +//===== LINK r,dd +void regLINK(void); + +//===== UNLK r +void regUNLK(void); + +//===== BS1F A,r +void regBS1F(void); + +//===== BS1B A,r +void regBS1B(void); + +//===== DAA r +void regDAA(void); + +//===== EXTZ r +void regEXTZ(void); + +//===== EXTS r +void regEXTS(void); + +//===== PAA r +void regPAA(void); + +//===== MIRR r +void regMIRR(void); + +//===== MULA r +void regMULA(void); + +//===== DJNZ r,d +void regDJNZ(void); + +//===== ANDCF #,r +void regANDCFi(void); + +//===== ORCF #,r +void regORCFi(void); + +//===== XORCF #,r +void regXORCFi(void); + +//===== LDCF #,r +void regLDCFi(void); + +//===== STCF #,r +void regSTCFi(void); + +//===== ANDCF A,r +void regANDCFA(void); + +//===== ORCF A,r +void regORCFA(void); + +//===== XORCF A,r +void regXORCFA(void); + +//===== LDCF A,r +void regLDCFA(void); + +//===== STCF A,r +void regSTCFA(void); + +//===== LDC cr,r +void regLDCcrr(void); + +//===== LDC r,cr +void regLDCrcr(void); + +//===== RES #,r +void regRES(void); + +//===== SET #,r +void regSET(void); + +//===== CHG #,r +void regCHG(void); + +//===== BIT #,r +void regBIT(void); + +//===== TSET #,r +void regTSET(void); + +//===== MINC1 #,r +void regMINC1(void); + +//===== MINC2 #,r +void regMINC2(void); + +//===== MINC4 #,r +void regMINC4(void); + +//===== MDEC1 #,r +void regMDEC1(void); + +//===== MDEC2 #,r +void regMDEC2(void); + +//===== MDEC4 #,r +void regMDEC4(void); + +//===== MUL RR,r +void regMUL(void); + +//===== MULS RR,r +void regMULS(void); + +//===== DIV RR,r +void regDIV(void); + +//===== DIVS RR,r +void regDIVS(void); + +//===== INC #3,r +void regINC(void); + +//===== DEC #3,r +void regDEC(void); + +//===== SCC cc,r +void regSCC(void); + +//===== LD R,r +void regLDRr(void); + +//===== LD r,R +void regLDrR(void); + +//===== ADD R,r +void regADD(void); + +//===== ADC R,r +void regADC(void); + +//===== SUB R,r +void regSUB(void); + +//===== SBC R,r +void regSBC(void); + +//===== LD r,#3 +void regLDr3(void); + +//===== EX R,r +void regEX(void); + +//===== ADD r,# +void regADDi(void); + +//===== ADC r,# +void regADCi(void); + +//===== SUB r,# +void regSUBi(void); + +//===== SBC r,# +void regSBCi(void); + +//===== CP r,# +void regCPi(void); + +//===== AND r,# +void regANDi(void); + +//===== OR r,# +void regORi(void); + +//===== XOR r,# +void regXORi(void); + +//===== AND R,r +void regAND(void); + +//===== OR R,r +void regOR(void); + +//===== XOR R,r +void regXOR(void); + +//===== CP r,#3 +void regCPr3(void); + +//===== CP R,r +void regCP(void); + +//===== RLC #,r +void regRLCi(void); + +//===== RRC #,r +void regRRCi(void); + +//===== RL #,r +void regRLi(void); + +//===== RR #,r +void regRRi(void); + +//===== SLA #,r +void regSLAi(void); + +//===== SRA #,r +void regSRAi(void); + +//===== SLL #,r +void regSLLi(void); + +//===== SRL #,r +void regSRLi(void); + +//===== RLC A,r +void regRLCA(void); + +//===== RRC A,r +void regRRCA(void); + +//===== RL A,r +void regRLA(void); + +//===== RR A,r +void regRRA(void); + +//===== SLA A,r +void regSLAA(void); + +//===== SRA A,r +void regSRAA(void); + +//===== SLL A,r +void regSLLA(void); + +//===== SRL A,r +void regSRLA(void); + +}; + +//========================================================================= +#endif diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_interpret_single.cpp b/waterbox/ngp/TLCS-900h/TLCS900h_interpret_single.cpp new file mode 100644 index 0000000000..96422b249f --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_interpret_single.cpp @@ -0,0 +1,428 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_interpret_single.c + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +22 JUL 2002 - neopop_uk +======================================= +- Removed setting the register file pointer to 3 in the SWI instruction + This has fixed "Metal Slug 2" and flash saving in many games. + +26 JUL 2002 - neopop_uk +======================================= +- Prefixed all instruction functions with "sng" to avoid a repeat of the + the 'EX' fiasco. + +30 JUL 2002 - neopop_uk +======================================= +- Um... SWI doesn't cause a problem if IFF is set to 3... why did +"Metal Slug 2" start working??? + +//--------------------------------------------------------------------------- +*/ + +#include "../neopop.h" +#include "TLCS900h_interpret.h" +#include "TLCS900h_registers.h" +#include "../mem.h" +#include "../interrupt.h" + +namespace TLCS900H +{ + +//========================================================================= + +//===== NOP +void sngNOP() +{ + cycles = 2; +} + +//===== NORMAL +void sngNORMAL() +{ + //Not supported + cycles = 4; +} + +//===== PUSH SR +void sngPUSHSR() +{ + push16(sr); + cycles = 4; +} + +//===== POP SR +void sngPOPSR() +{ + sr = pop16(); changedSP(); + cycles = 6; +} + +//===== MAX +void sngMAX() +{ + //Not supported + cycles = 4; +} + +//===== HALT +void sngHALT() +{ + MDFN_printf("CPU halt requested and ignored.\nPlease send me a saved state."); + cycles = 8; +} + +//===== EI #3 +void sngEI() +{ + setStatusIFF(FETCH8); + int_check_pending(); + cycles = 5; +} + +//===== RETI +void sngRETI() +{ + uint16 temp = pop16(); + pc = pop32(); + sr = temp; changedSP(); + cycles = 12; +} + +//===== LD (n), n +void sngLD8_8() +{ + uint8 dst = FETCH8; + uint8 src = FETCH8; + storeB(dst, src); + cycles = 5; +} + +//===== PUSH n +void sngPUSH8() +{ + uint8 data = FETCH8; + push8(data); + cycles = 4; +} + +//===== LD (n), nn +void sngLD8_16() +{ + uint8 dst = FETCH8; + uint16 src = fetch16(); + storeW(dst, src); + cycles = 6; +} + +//===== PUSH nn +void sngPUSH16() +{ + push16(fetch16()); + cycles = 5; +} + +//===== INCF +void sngINCF() +{ + setStatusRFP(((sr & 0x300) >> 8) + 1); + cycles = 2; +} + +//===== DECF +void sngDECF() +{ + setStatusRFP(((sr & 0x300) >> 8) - 1); + cycles = 2; +} + +//===== RET condition +void sngRET() +{ + pc = pop32(); + cycles = 9; +} + +//===== RETD dd +void sngRETD() +{ + int16 d = (int16)fetch16(); + pc = pop32(); + REGXSP += d; + cycles = 9; +} + +//===== RCF +void sngRCF() +{ + SETFLAG_N0; + SETFLAG_V0; + SETFLAG_C0; + cycles = 2; +} + +//===== SCF +void sngSCF() +{ + SETFLAG_H0; + SETFLAG_N0; + SETFLAG_C1; + cycles = 2; +} + +//===== CCF +void sngCCF() +{ + SETFLAG_N0; + SETFLAG_C(!FLAG_C); + cycles = 2; +} + +//===== ZCF +void sngZCF() +{ + SETFLAG_N0; + SETFLAG_C(!FLAG_Z); + cycles = 2; +} + +//===== PUSH A +void sngPUSHA() +{ + push8(REGA); + cycles = 3; +} + +//===== POP A +void sngPOPA() +{ + REGA = pop8(); + cycles = 4; +} + +//===== EX F,F' +void sngEX() +{ + uint8 f = sr & 0xFF; + sr = (sr & 0xFF00) | f_dash; + f_dash = f; + cycles = 2; +} + +//===== LDF #3 +void sngLDF() +{ + setStatusRFP(FETCH8); + cycles = 2; +} + +//===== PUSH F +void sngPUSHF() +{ + push8(sr & 0xFF); + cycles = 3; +} + +//===== POP F +void sngPOPF() +{ + sr = (sr & 0xFF00) | pop8(); + cycles = 4; +} + +//===== JP nn +void sngJP16() +{ + pc = fetch16(); + cycles = 7; +} + +//===== JP nnn +void sngJP24() +{ + pc = fetch24(); + cycles = 7; +} + +//===== CALL #16 +void sngCALL16() +{ + uint32 target = fetch16(); + push32(pc); + pc = target; + cycles = 12; +} + +//===== CALL #24 +void sngCALL24() +{ + uint32 target = fetch24(); + push32(pc); + pc = target; + cycles = 12; +} + +//===== CALR $+3+d16 +void sngCALR() +{ + int16 displacement = (int16)fetch16(); + uint32 target = pc + displacement; + push32(pc); + pc = target; + cycles = 12; +} + +//===== LD R, n +void sngLDB() +{ + regB(first & 7) = FETCH8; + cycles = 2; +} + +//===== PUSH RR +void sngPUSHW() +{ + push16(regW(first & 7)); + cycles = 3; +} + +//===== LD RR, nn +void sngLDW() +{ + regW(first & 7) = fetch16(); + cycles = 3; +} + +//===== PUSH XRR +void sngPUSHL() +{ + push32(regL(first & 7)); + cycles = 5; +} + +//===== LD XRR, nnnn +void sngLDL() +{ + regL(first & 7) = fetch32(); + cycles = 5; +} + +//===== POP RR +void sngPOPW() +{ + regW(first & 7) = pop16(); + cycles = 4; +} + +//===== POP XRR +void sngPOPL() +{ + regL(first & 7) = pop32(); + cycles = 6; +} + +//===== JR cc,PC + d +void sngJR() +{ + if (conditionCode(first & 0xF)) + { + int8 displacement = (int8)FETCH8; + + cycles = 8; + pc += displacement; + } + else + { + cycles = 4; + FETCH8; + } +} + +//===== JR cc,PC + dd +void sngJRL() +{ + if (conditionCode(first & 0xF)) + { + int16 displacement = (int16)fetch16(); + cycles = 8; + pc += displacement; + } + else + { + cycles = 4; + fetch16(); + } +} + +//===== LDX dst,src +void sngLDX() +{ + uint8 dst, src; + + FETCH8; //00 + dst = FETCH8; //#8 + FETCH8; //00 + src = FETCH8; //# + FETCH8; //00 + + storeB(dst, src); + cycles = 9; +} + +//===== SWI num +void sngSWI() +{ + cycles = 16; + + //printf("SWI: %02x\n", first & 0x7); + switch(first & 7) + { + //System Call + case 1: push32(pc); + pc = loadL(0xFFFE00 + ((rCodeB(0x31) & 0x1F) << 2)); + break; + + case 3: interrupt(0); //SWI 3 + break; + + case 4: interrupt(1); //SWI 4 + break; + + case 5: interrupt(2); //SWI 5 + break; + + case 6: interrupt(3); //SWI 6 + break; + + default: instruction_error("SWI %d is not valid.", first & 7); + break; + } +} +}; +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_interpret_single.h b/waterbox/ngp/TLCS-900h/TLCS900h_interpret_single.h new file mode 100644 index 0000000000..f34d758493 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_interpret_single.h @@ -0,0 +1,170 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_interpret_single.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + +#ifndef __TLCS900H_SINGLE__ +#define __TLCS900H_SINGLE__ +//========================================================================= + +namespace TLCS900H +{ + +//===== NOP +void sngNOP(void); + +//===== NORMAL +void sngNORMAL(void); + +//===== PUSH SR +void sngPUSHSR(void); + +//===== POP SR +void sngPOPSR(void); + +//===== MAX +void sngMAX(void); + +//===== HALT +void sngHALT(void); + +//===== EI #3 +void sngEI(void); + +//===== RETI +void sngRETI(void); + +//===== LD (n), n +void sngLD8_8(void); + +//===== PUSH n +void sngPUSH8(void); + +//===== LD (n), nn +void sngLD8_16(void); + +//===== PUSH nn +void sngPUSH16(void); + +//===== INCF +void sngINCF(void); + +//===== DECF +void sngDECF(void); + +//===== RET condition +void sngRET(void); + +//===== RETD dd +void sngRETD(void); + +//===== RCF +void sngRCF(void); + +//===== SCF +void sngSCF(void); + +//===== CCF +void sngCCF(void); + +//===== ZCF +void sngZCF(void); + +//===== PUSH A +void sngPUSHA(void); + +//===== POP A +void sngPOPA(void); + +//===== EX F,F' +void sngEX(void); + +//===== LDF #3 +void sngLDF(void); + +//===== PUSH F +void sngPUSHF(void); + +//===== POP F +void sngPOPF(void); + +//===== JP nn +void sngJP16(void); + +//===== JP nnn +void sngJP24(void); + +//===== CALL #16 +void sngCALL16(void); + +//===== CALL #24 +void sngCALL24(void); + +//===== CALR $+3+d16 +void sngCALR(void); + +//===== LD R, n +void sngLDB(void); + +//===== PUSH RR +void sngPUSHW(void); + +//===== LD RR, nn +void sngLDW(void); + +//===== PUSH XRR +void sngPUSHL(void); + +//===== LD XRR, nnnn +void sngLDL(void); + +//===== POP RR +void sngPOPW(void); + +//===== POP XRR +void sngPOPL(void); + +//===== JR cc,PC + d +void sngJR(void); + +//===== JR cc,PC + dd +void sngJRL(void); + +//===== LDX dst,src +void sngLDX(void); + +//===== SWI num +void sngSWI(void); + +}; + +//============================================================================= +#endif diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_interpret_src.cpp b/waterbox/ngp/TLCS-900h/TLCS900h_interpret_src.cpp new file mode 100644 index 0000000000..9e16ea5590 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_interpret_src.cpp @@ -0,0 +1,1266 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_interpret_src.c + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +24 JUL 2002 - neopop_uk +======================================= +- Fixed S flag in "RRC (mem)" + +25 JUL 2002 - neopop_uk +======================================= +- Removed unneeded Long mode from EX. + +28 JUL 2002 - neopop_uk +======================================= +- Improved the LDIR/LDDR/CPIR/CPDR instructions so that they + finish with the correct register settings, even if there is + a memory error. +- Converted DIV/DIVS to use the generic function + +16 AUG 2002 - neopop_uk +======================================= +- Replaced 'second & 7' with 'R', clearer, faster - and for some reason + more accurate... oh well! +- Fixed V flag emulation of INC/DEC, fixes "Cotton" menus + +21 AUG 2002 - neopop_uk +======================================= +- Fixed "RR (mem)" - It was actually the [REG] version that hadn't been + changed to use memory accesses! + +30 AUG 2002 - neopop_uk +======================================= +- Fixed "DIV RR,(mem)" in long mode, wrong operand size. + +04 SEP 2002 - neopop_uk +======================================= +- Fixed GCC compatibility. + +//--------------------------------------------------------------------------- +*/ + +#include "../neopop.h" +#include "TLCS900h_interpret.h" +#include "TLCS900h_registers.h" +#include "../mem.h" + +namespace TLCS900H +{ + +//========================================================================= + +//===== PUSH (mem) +void srcPUSH() +{ + switch(size) + { + case 0: push8(loadB(mem)); break; + case 1: push16(loadW(mem)); break; + } + cycles = 7; +} + +//===== RLD A,(mem) +void srcRLD() +{ + uint8 al = REGA & 0xF, m, mh, ml; + + m = loadB(mem); + mh = (m & 0xF0) >> 4; + ml = (m & 0x0F) << 4; + + REGA = (REGA & 0xF0) | mh; + storeB(mem, ml | al); + + SETFLAG_S(REGA & 0x80); + SETFLAG_Z(REGA == 0); + SETFLAG_H0 + SETFLAG_N0 + parityB(REGA); + + cycles = 12; +} + +//===== RRD A,(mem) +void srcRRD() +{ + uint8 al = (REGA & 0xF) << 4, m, mh, ml; + + m = loadB(mem); + mh = (m & 0xF0) >> 4; + ml = m & 0x0F; + + REGA = (REGA & 0xF0) | ml; + storeB(mem, al | mh); + + SETFLAG_S(REGA & 0x80); + SETFLAG_Z(REGA == 0); + SETFLAG_H0 + SETFLAG_N0 + parityB(REGA); + + cycles = 12; +} + +//===== LDI +void srcLDI() +{ + uint8 dst = 2/*XDE*/, src = 3/*XHL*/; + if ((first & 0xF) == 5) { dst = 4/*XIX*/; src = 5/*XIY*/; } + + switch(size) + { + case 0: + storeB(regL(dst), loadB(regL(src))); + regL(dst) += 1; + regL(src) += 1; + break; + + case 1: + storeW(regL(dst), loadW(regL(src))); + regL(dst) += 2; + regL(src) += 2; + break; + } + + REGBC --; + SETFLAG_V(REGBC); + + SETFLAG_H0; + SETFLAG_N0; + cycles = 10; +} + +//===== LDIR +void srcLDIR() +{ + uint8 dst = 2/*XDE*/, src = 3/*XHL*/; + if ((first & 0xF) == 5) { dst = 4/*XIX*/; src = 5/*XIY*/; } + + cycles = 10; + + do + { + switch(size) + { + case 0: if (debug_abort_memory == FALSE) + storeB(regL(dst), loadB(regL(src))); + regL(dst) += 1; + regL(src) += 1; + break; + + case 1: if (debug_abort_memory == FALSE) + storeW(regL(dst), loadW(regL(src))); + regL(dst) += 2; + regL(src) += 2; + break; + } + + REGBC --; + SETFLAG_V(REGBC); + + cycles += 14; + } + while (FLAG_V); + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== LDD +void srcLDD() +{ + uint8 dst = 2/*XDE*/, src = 3/*XHL*/; + if ((first & 0xF) == 5) { dst = 4/*XIX*/; src = 5/*XIY*/; } + + switch(size) + { + case 0: + storeB(regL(dst), loadB(regL(src))); + regL(dst) -= 1; + regL(src) -= 1; + break; + + case 1: + storeW(regL(dst), loadW(regL(src))); + regL(dst) -= 2; + regL(src) -= 2; + break; + } + + REGBC --; + SETFLAG_V(REGBC); + + SETFLAG_H0; + SETFLAG_N0; + cycles = 10; +} + +//===== LDDR +void srcLDDR() +{ + uint8 dst = 2/*XDE*/, src = 3/*XHL*/; + if ((first & 0xF) == 5) { dst = 4/*XIX*/; src = 5/*XIY*/; } + + cycles = 10; + + do + { + switch(size) + { + case 0: + if (debug_abort_memory == FALSE) + storeB(regL(dst), loadB(regL(src))); + regL(dst) -= 1; + regL(src) -= 1; + break; + + case 1: + if (debug_abort_memory == FALSE) + storeW(regL(dst), loadW(regL(src))); + regL(dst) -= 2; + regL(src) -= 2; + break; + } + + REGBC --; + SETFLAG_V(REGBC); + + cycles += 14; + } + while (FLAG_V); + + SETFLAG_H0; + SETFLAG_N0; +} + +//===== CPI +void srcCPI() +{ + uint8 R = first & 7; + + switch(size) + { + case 0: generic_SUB_B(REGA, loadB(regL(R))); + regL(R) ++; break; + + case 1: generic_SUB_W(REGWA, loadW(regL(R))); + regL(R) += 2; break; + } + + REGBC --; + SETFLAG_V(REGBC); + + cycles = 8; +} + +//===== CPIR +void srcCPIR() +{ + uint8 R = first & 7; + + cycles = 10; + + do + { + switch(size) + { + case 0: if (debug_abort_memory == FALSE) + generic_SUB_B(REGA, loadB(regL(R))); + regL(R) ++; break; + + case 1: if (debug_abort_memory == FALSE) + generic_SUB_W(REGWA, loadW(regL(R))); + regL(R) += 2; break; + } + + REGBC --; + SETFLAG_V(REGBC); + + cycles += 14; + } + while (FLAG_V && (FLAG_Z == FALSE)); +} + +//===== CPD +void srcCPD() +{ + uint8 R = first & 7; + + switch(size) + { + case 0: generic_SUB_B(REGA, loadB(regL(R))); + regL(R) --; break; + + case 1: generic_SUB_W(REGWA, loadW(regL(R))); + regL(R) -= 2; break; + } + + REGBC --; + SETFLAG_V(REGBC); + + cycles = 8; +} + +//===== CPDR +void srcCPDR() +{ + uint8 R = first & 7; + + cycles = 10; + + do + { + switch(size) + { + case 0: if (debug_abort_memory == FALSE) + generic_SUB_B(REGA, loadB(regL(R))); + regL(R) -= 1; break; + + case 1: if (debug_abort_memory == FALSE) + generic_SUB_W(REGWA, loadW(regL(R))); + regL(R) -= 2; break; + } + + REGBC --; + SETFLAG_V(REGBC); + + cycles += 14; + } + while (FLAG_V && (FLAG_Z == FALSE)); +} + +//===== LD (nn),(mem) +void srcLD16m() +{ + switch(size) + { + case 0: storeB(fetch16(), loadB(mem)); break; + case 1: storeW(fetch16(), loadW(mem)); break; + } + + cycles = 8; +} + +//===== LD R,(mem) +void srcLD() +{ + switch(size) + { + case 0: regB(R) = loadB(mem); cycles = 4; break; + case 1: regW(R) = loadW(mem); cycles = 4; break; + case 2: regL(R) = loadL(mem); cycles = 6; break; + } +} + +//===== EX (mem),R +void srcEX() +{ + switch(size) + { + case 0: { uint8 temp = regB(R); + regB(R) = loadB(mem); + storeB(mem, temp); break; } + + case 1: { uint16 temp = regW(R); + regW(R) = loadW(mem); + storeW(mem, temp); break; } + } + + cycles = 6; +} + +//===== ADD (mem),# +void srcADDi() +{ + switch(size) + { + case 0: storeB(mem, generic_ADD_B(loadB(mem), FETCH8)); cycles = 7;break; + case 1: storeW(mem, generic_ADD_W(loadW(mem), fetch16())); cycles = 8;break; + } +} + +//===== ADC (mem),# +void srcADCi() +{ + switch(size) + { + case 0: storeB(mem, generic_ADC_B(loadB(mem), FETCH8)); cycles = 7;break; + case 1: storeW(mem, generic_ADC_W(loadW(mem), fetch16())); cycles = 8;break; + } +} + +//===== SUB (mem),# +void srcSUBi() +{ + switch(size) + { + case 0: storeB(mem, generic_SUB_B(loadB(mem), FETCH8)); cycles = 7;break; + case 1: storeW(mem, generic_SUB_W(loadW(mem), fetch16())); cycles = 8;break; + } +} + +//===== SBC (mem),# +void srcSBCi() +{ + switch(size) + { + case 0: storeB(mem, generic_SBC_B(loadB(mem), FETCH8)); cycles = 7;break; + case 1: storeW(mem, generic_SBC_W(loadW(mem), fetch16())); cycles = 8;break; + } +} + +//===== AND (mem),# +void srcANDi() +{ + switch(size) + { + case 0: { uint8 result = loadB(mem) & FETCH8; + storeB(mem, result); + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + parityB(result); + cycles = 7; + break; } + + case 1: { uint16 result = loadW(mem) & fetch16(); + storeW(mem, result); + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + parityW(result); + cycles = 8; + break; } + } + + SETFLAG_H1; + SETFLAG_N0; + SETFLAG_C0; +} + +//===== OR (mem),# +void srcORi() +{ + switch(size) + { + case 0: { uint8 result = loadB(mem) | FETCH8; + storeB(mem, result); + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + parityB(result); + cycles = 7; + break; } + + case 1: { uint16 result = loadW(mem) | fetch16(); + storeW(mem, result); + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + parityW(result); + cycles = 8; + break; } + } + + SETFLAG_H0; + SETFLAG_N0; + SETFLAG_C0; +} + +//===== XOR (mem),# +void srcXORi() +{ + switch(size) + { + case 0: { uint8 result = loadB(mem) ^ FETCH8; + storeB(mem, result); + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + parityB(result); + cycles = 7; + break; } + + case 1: { uint16 result = loadW(mem) ^ fetch16(); + storeW(mem, result); + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + parityW(result); + cycles = 8; + break; } + } + + SETFLAG_H0; + SETFLAG_N0; + SETFLAG_C0; +} + +//===== CP (mem),# +void srcCPi() +{ + switch(size) + { + case 0: generic_SUB_B(loadB(mem), FETCH8); break; + case 1: generic_SUB_W(loadW(mem), fetch16()); break; + } + + cycles = 6; +} + +//===== MUL RR,(mem) +void srcMUL() +{ + uint8 target = get_RR_Target(); + if (target == 0x80) + { + instruction_error("src: MUL bad \'RR\' dst code"); + return; + } + + switch(size) + { + case 0: rCodeW(target) = (rCodeW(target) & 0xFF) * loadB(mem); + cycles = 18; break; + case 1: rCodeL(target) = (rCodeL(target) & 0xFFFF) * loadW(mem); + cycles = 26; break; + } +} + +//===== MULS RR,(mem) +void srcMULS() +{ + uint8 target = get_RR_Target(); + if (target == 0x80) + { + instruction_error("src: MUL bad \'RR\' dst code"); + return; + } + + switch(size) + { + case 0: rCodeW(target) = (int8)(rCodeW(target) & 0xFF) * (int8)loadB(mem); + cycles = 18; break; + case 1: rCodeL(target) = (int16)(rCodeL(target) & 0xFFFF) * (int16)loadW(mem); + cycles = 26; break; + } +} + +//===== DIV RR,(mem) +void srcDIV() +{ + uint8 target = get_RR_Target(); + if (target == 0x80) + { + instruction_error("src: DIV bad \'RR\' dst code"); + return; + } + + switch(size) + { + case 0: { rCodeW(target) = generic_DIV_B(rCodeW(target), loadB(mem)); + cycles = 22; + break; } + + case 1: { rCodeL(target) = generic_DIV_W(rCodeL(target), loadW(mem)); + cycles = 30; + break; } + } +} + +//===== DIVS RR,(mem) +void srcDIVS() +{ + uint8 target = get_RR_Target(); + if (target == 0x80) + { + instruction_error("src: DIVS bad \'RR\' dst code"); + return; + } + + switch(size) + { + case 0: { rCodeW(target) = generic_DIVS_B(rCodeW(target), loadB(mem)); + cycles = 24; + break; } + + case 1: { rCodeL(target) = generic_DIVS_W(rCodeL(target), loadW(mem)); + cycles = 32; + break; } + } +} + +//===== INC #3,(mem) +void srcINC() +{ + uint8 val = R; + if (val == 0) + val = 8; + + switch(size) + { + case 0: { uint8 dst = loadB(mem); + uint32 resultC = dst + val; + uint8 half = (dst & 0xF) + val; + uint8 result = (uint8)(resultC & 0xFF); + SETFLAG_Z(result == 0); + SETFLAG_H(half > 0xF); + SETFLAG_S(result & 0x80); + SETFLAG_N0; + + if (((int8)dst >= 0) && ((int8)result < 0)) + {SETFLAG_V1} else {SETFLAG_V0} + + storeB(mem, result); + break; } + + case 1: { uint16 dst = loadW(mem); + uint32 resultC = dst + val; + uint8 half = (dst & 0xF) + val; + uint16 result = (uint16)(resultC & 0xFFFF); + SETFLAG_Z(result == 0); + SETFLAG_H(half > 0xF); + SETFLAG_S(result & 0x8000); + SETFLAG_N0; + + if (((int16)dst >= 0) && ((int16)result < 0)) + {SETFLAG_V1} else {SETFLAG_V0} + + storeW(mem, result); + break; } + } + + cycles = 6; +} + +//===== DEC #3,(mem) +void srcDEC() +{ + uint8 val = R; + if (val == 0) + val = 8; + + switch(size) + { + case 0: { uint8 dst = loadB(mem); + uint32 resultC = dst - val; + uint8 half = (dst & 0xF) - val; + uint8 result = (uint8)(resultC & 0xFF); + SETFLAG_Z(result == 0); + SETFLAG_H(half > 0xF); + SETFLAG_S(result & 0x80); + SETFLAG_N1; + + if (((int8)dst < 0) && ((int8)result >= 0)) + {SETFLAG_V1} else {SETFLAG_V0} + + storeB(mem, result); + break; } + + case 1: { uint16 dst = loadW(mem); + uint32 resultC = dst - val; + uint8 half = (dst & 0xF) - val; + uint16 result = (uint16)(resultC & 0xFFFF); + SETFLAG_Z(result == 0); + SETFLAG_H(half > 0xF); + SETFLAG_S(result & 0x8000); + SETFLAG_N1; + + if (((int16)dst < 0) && ((int16)result >= 0)) + {SETFLAG_V1} else {SETFLAG_V0} + + storeW(mem, result); + break; } + } + + cycles = 6; +} + +//===== RLC (mem) +void srcRLC() +{ + switch(size) + { + case 0: { uint8 result = loadB(mem); + SETFLAG_C(result & 0x80); + result <<= 1; + if (FLAG_C) result |= 1; + storeB(mem, result); + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + parityB(result); + break; } + + case 1: { uint16 result = loadW(mem); + SETFLAG_C(result & 0x8000); + result <<= 1; + if (FLAG_C) result |= 1; + storeW(mem, result); + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + parityW(result); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; + + cycles = 8; +} + +//===== RRC (mem) +void srcRRC() +{ + switch(size) + { + case 0: { uint8 data = loadB(mem), result; + SETFLAG_C(data & 1); + result = data >> 1; + if (FLAG_C) result |= 0x80; + storeB(mem, result); + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + parityB(result); + break; } + + case 1: { uint16 data = loadW(mem), result; + SETFLAG_C(data & 1); + result = data >> 1; + if (FLAG_C) result |= 0x8000; + storeW(mem, result); + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + parityW(result); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; + + cycles = 8; +} + +//===== RL (mem) +void srcRL() +{ + bool tempC; + + switch(size) + { + case 0: { uint8 result = loadB(mem); + tempC = FLAG_C; + SETFLAG_C(result & 0x80); + result <<= 1; + if (tempC) result |= 1; + storeB(mem, result); + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + parityB(result); + break; } + + case 1: { uint16 result = loadW(mem); + tempC = FLAG_C; + SETFLAG_C(result & 0x8000); + result <<= 1; + if (tempC) result |= 1; + storeW(mem, result); + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + parityW(result); + break; } + } + + cycles = 8; +} + +//===== RR (mem) +void srcRR() +{ + bool tempC; + + switch(size) + { + case 0: { uint8 result = loadB(mem); + tempC = FLAG_C; + SETFLAG_C(result & 1); + result >>= 1; + if (tempC) result |= 0x80; + storeB(mem, result); + SETFLAG_S(result & 0x80); + SETFLAG_Z(result == 0); + parityB(result); + break; } + + case 1: { uint16 result = loadW(mem); + tempC = FLAG_C; + SETFLAG_C(result & 1); + result >>= 1; + if (tempC) result |= 0x8000; + storeW(mem, result); + SETFLAG_S(result & 0x8000); + SETFLAG_Z(result == 0); + parityW(result); + break; } + } + + cycles = 8; +} + +//===== SLA (mem) +void srcSLA() +{ + switch(size) + { + case 0: { uint8 result, data = loadB(mem); + SETFLAG_C(data & 0x80); + result = ((int8)data << 1); + SETFLAG_S(result & 0x80); + storeB(mem, result); + SETFLAG_Z(result == 0); + parityB(result); + break; } + + case 1: { uint16 result, data = loadW(mem); + SETFLAG_C(data & 0x8000); + result = ((int16)data << 1); + SETFLAG_S(result & 0x8000); + storeW(mem, result); + SETFLAG_Z(result == 0); + parityW(result); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; + + cycles = 8; +} + +//===== SRA (mem) +void srcSRA() +{ + switch(size) + { + case 0: { uint8 result, data = loadB(mem); + SETFLAG_C(data & 0x1); + result = ((int8)data >> 1); + SETFLAG_S(result & 0x80); + storeB(mem, result); + SETFLAG_Z(result == 0); + parityB(result); + break; } + + case 1: { uint16 result, data = loadW(mem); + SETFLAG_C(data & 0x1); + result = ((int16)data >> 1); + SETFLAG_S(result & 0x8000); + storeW(mem, result); + SETFLAG_Z(result == 0); + parityW(result); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; + + cycles = 8; +} + +//===== SLL (mem) +void srcSLL() +{ + switch(size) + { + case 0: { uint8 result, data = loadB(mem); + SETFLAG_C(data & 0x80); + result = (data << 1); + SETFLAG_S(result & 0x80); + storeB(mem, result); + SETFLAG_Z(result == 0); + parityB(result); + break; } + + case 1: { uint16 result, data = loadW(mem); + SETFLAG_C(data & 0x8000); + result = (data << 1); + SETFLAG_S(result & 0x8000); + storeW(mem, result); + SETFLAG_Z(result == 0); + parityW(result); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; + + cycles = 8; +} + +//===== SRL (mem) +void srcSRL() +{ + switch(size) + { + case 0: { uint8 result, data = loadB(mem); + SETFLAG_C(data & 0x01); + result = (data >> 1); + SETFLAG_S(result & 0x80); + storeB(mem, result); + SETFLAG_Z(result == 0); + parityB(result); + break; } + + case 1: { uint16 result, data = loadW(mem); + SETFLAG_C(data & 0x0001); + result = (data >> 1); + SETFLAG_S(result & 0x8000); + storeW(mem, result); + SETFLAG_Z(result == 0); + parityW(result); + break; } + } + + SETFLAG_H0; + SETFLAG_N0; + + cycles = 8; +} + +//===== ADD R,(mem) +void srcADDRm() +{ + switch(size) + { + case 0: regB(R) = generic_ADD_B(regB(R), loadB(mem)); cycles = 4;break; + case 1: regW(R) = generic_ADD_W(regW(R), loadW(mem)); cycles = 4;break; + case 2: regL(R) = generic_ADD_L(regL(R), loadL(mem)); cycles = 6;break; + } +} + +//===== ADD (mem),R +void srcADDmR() +{ + switch(size) + { + case 0: storeB(mem, generic_ADD_B(loadB(mem), regB(R))); cycles = 6;break; + case 1: storeW(mem, generic_ADD_W(loadW(mem), regW(R))); cycles = 6;break; + case 2: storeL(mem, generic_ADD_L(loadL(mem), regL(R))); cycles = 10;break; + } +} + +//===== ADC R,(mem) +void srcADCRm() +{ + switch(size) + { + case 0: regB(R) = generic_ADC_B(regB(R), loadB(mem)); cycles = 4;break; + case 1: regW(R) = generic_ADC_W(regW(R), loadW(mem)); cycles = 4;break; + case 2: regL(R) = generic_ADC_L(regL(R), loadL(mem)); cycles = 6;break; + } +} + +//===== ADC (mem),R +void srcADCmR() +{ + switch(size) + { + case 0: storeB(mem, generic_ADC_B(loadB(mem), regB(R))); cycles = 6;break; + case 1: storeW(mem, generic_ADC_W(loadW(mem), regW(R))); cycles = 6;break; + case 2: storeL(mem, generic_ADC_L(loadL(mem), regL(R))); cycles = 10;break; + } +} + +//===== SUB R,(mem) +void srcSUBRm() +{ + switch(size) + { + case 0: regB(R) = generic_SUB_B(regB(R), loadB(mem)); cycles = 4;break; + case 1: regW(R) = generic_SUB_W(regW(R), loadW(mem)); cycles = 4;break; + case 2: regL(R) = generic_SUB_L(regL(R), loadL(mem)); cycles = 6;break; + } +} + +//===== SUB (mem),R +void srcSUBmR() +{ + switch(size) + { + case 0: storeB(mem, generic_SUB_B(loadB(mem), regB(R))); cycles = 6;break; + case 1: storeW(mem, generic_SUB_W(loadW(mem), regW(R))); cycles = 6;break; + case 2: storeL(mem, generic_SUB_L(loadL(mem), regL(R))); cycles = 10;break; + } +} + +//===== SBC R,(mem) +void srcSBCRm() +{ + switch(size) + { + case 0: regB(R) = generic_SBC_B(regB(R), loadB(mem)); cycles = 4;break; + case 1: regW(R) = generic_SBC_W(regW(R), loadW(mem)); cycles = 4;break; + case 2: regL(R) = generic_SBC_L(regL(R), loadL(mem)); cycles = 6;break; + } +} + +//===== SBC (mem),R +void srcSBCmR() +{ + switch(size) + { + case 0: storeB(mem, generic_SBC_B(loadB(mem), regB(R))); cycles = 6;break; + case 1: storeW(mem, generic_SBC_W(loadW(mem), regW(R))); cycles = 6;break; + case 2: storeL(mem, generic_SBC_L(loadL(mem), regL(R))); cycles = 10;break; + } +} + +//===== AND R,(mem) +void srcANDRm() +{ + switch(size) + { + case 0: { uint8 result = regB(R) & loadB(mem); + regB(R) = result; + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x80); + parityB(result); + cycles = 4; + break; } + + case 1: { uint16 result = regW(R) & loadW(mem); + regW(R) = result; + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x8000); + parityW(result); + cycles = 4; + break; } + + case 2: { uint32 result = regL(R) & loadL(mem); + regL(R) = result; + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x80000000); + cycles = 6; + break; } + } + + SETFLAG_H1; + SETFLAG_N0; + SETFLAG_C0; +} + +//===== AND (mem),R +void srcANDmR() +{ + switch(size) + { + case 0: { uint8 result = regB(R) & loadB(mem); + storeB(mem, result); + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x80); + parityB(result); + cycles = 6; + break; } + + case 1: { uint16 result = regW(R) & loadW(mem); + storeW(mem, result); + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x8000); + parityW(result); + cycles = 6; + break; } + + case 2: { uint32 result = regL(R) & loadL(mem); + storeL(mem, result); + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x80000000); + cycles = 10; + break; } + } + + SETFLAG_H1; + SETFLAG_N0; + SETFLAG_C0; +} + +//===== XOR R,(mem) +void srcXORRm() +{ + switch(size) + { + case 0: { uint8 result = regB(R) ^ loadB(mem); + regB(R) = result; + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x80); + parityB(result); + cycles = 4; + break; } + + case 1: { uint16 result = regW(R) ^ loadW(mem); + regW(R) = result; + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x8000); + parityW(result); + cycles = 4; + break; } + + case 2: { uint32 result = regL(R) ^ loadL(mem); + regL(R) = result; + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x80000000); + cycles = 6; + break; } + } + + SETFLAG_H0; + SETFLAG_N0; + SETFLAG_C0; +} + +//===== XOR (mem),R +void srcXORmR() +{ + switch(size) + { + case 0: { uint8 result = regB(R) ^ loadB(mem); + storeB(mem, result); + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x80); + parityB(result); + cycles = 6; + break; } + + case 1: { uint16 result = regW(R) ^ loadW(mem); + storeW(mem, result); + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x8000); + parityW(result); + cycles = 6; + break; } + + case 2: { uint32 result = regL(R) ^ loadL(mem); + storeL(mem, result); + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x80000000); + cycles = 10; + break; } + } + + SETFLAG_H0; + SETFLAG_N0; + SETFLAG_C0; +} + +//===== OR R,(mem) +void srcORRm() +{ + switch(size) + { + case 0: { uint8 result = regB(R) | loadB(mem); + regB(R) = result; + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x80); + parityB(result); + cycles = 4; + break; } + + case 1: { uint16 result = regW(R) | loadW(mem); + regW(R) = result; + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x8000); + parityW(result); + cycles = 4; + break; } + + case 2: { uint32 result = regL(R) | loadL(mem); + regL(R) = result; + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x80000000); + cycles = 6; + break; } + } + + SETFLAG_H0; + SETFLAG_N0; + SETFLAG_C0; +} + +//===== OR (mem),R +void srcORmR() +{ + switch(size) + { + case 0: { uint8 result = regB(R) | loadB(mem); + storeB(mem, result); + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x80); + parityB(result); + cycles = 6; + break; } + + case 1: { uint16 result = regW(R) | loadW(mem); + storeW(mem, result); + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x8000); + parityW(result); + cycles = 6; + break; } + + case 2: { uint32 result = regL(R) | loadL(mem); + storeL(mem, result); + SETFLAG_Z(result == 0); + SETFLAG_S(result & 0x80000000); + cycles = 10; + break; } + } + + SETFLAG_H0; + SETFLAG_N0; + SETFLAG_C0; +} + +//===== CP R,(mem) +void srcCPRm() +{ + switch(size) + { + case 0: generic_SUB_B(regB(R), loadB(mem)); cycles = 4; break; + case 1: generic_SUB_W(regW(R), loadW(mem)); cycles = 4; break; + case 2: generic_SUB_L(regL(R), loadL(mem)); cycles = 6; break; + } +} + +//===== CP (mem),R +void srcCPmR() +{ + switch(size) + { + case 0: generic_SUB_B(loadB(mem), regB(R)); break; + case 1: generic_SUB_W(loadW(mem), regW(R)); break; + case 2: generic_SUB_L(loadL(mem), regL(R)); break; + } + + cycles = 6; +} +}; +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_interpret_src.h b/waterbox/ngp/TLCS-900h/TLCS900h_interpret_src.h new file mode 100644 index 0000000000..a89e775df8 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_interpret_src.h @@ -0,0 +1,200 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_interpret_src.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + +#ifndef __TLCS900H_SRC__ +#define __TLCS900H_SRC__ +//========================================================================= +namespace TLCS900H +{ + + +//===== PUSH (mem) +void srcPUSH(void); + +//===== RLD A,(mem) +void srcRLD(void); + +//===== RRD A,(mem) +void srcRRD(void); + +//===== LDI +void srcLDI(void); + +//===== LDIR +void srcLDIR(void); + +//===== LDD +void srcLDD(void); + +//===== LDDR +void srcLDDR(void); + +//===== CPI +void srcCPI(void); + +//===== CPIR +void srcCPIR(void); + +//===== CPD +void srcCPD(void); + +//===== CPDR +void srcCPDR(void); + +//===== LD (nn),(mem) +void srcLD16m(void); + +//===== LD R,(mem) +void srcLD(void); + +//===== EX (mem),R +void srcEX(void); + +//===== ADD (mem),# +void srcADDi(void); + +//===== ADC (mem),# +void srcADCi(void); + +//===== SUB (mem),# +void srcSUBi(void); + +//===== SBC (mem),# +void srcSBCi(void); + +//===== AND (mem),# +void srcANDi(void); + +//===== OR (mem),# +void srcORi(void); + +//===== XOR (mem),# +void srcXORi(void); + +//===== CP (mem),# +void srcCPi(void); + +//===== MUL RR,(mem) +void srcMUL(void); + +//===== MULS RR,(mem) +void srcMULS(void); + +//===== DIV RR,(mem) +void srcDIV(void); + +//===== DIVS RR,(mem) +void srcDIVS(void); + +//===== INC #3,(mem) +void srcINC(void); + +//===== DEC #3,(mem) +void srcDEC(void); + +//===== RLC (mem) +void srcRLC(void); + +//===== RRC (mem) +void srcRRC(void); + +//===== RL (mem) +void srcRL(void); + +//===== RR (mem) +void srcRR(void); + +//===== SLA (mem) +void srcSLA(void); + +//===== SRA (mem) +void srcSRA(void); + +//===== SLL (mem) +void srcSLL(void); + +//===== SRL (mem) +void srcSRL(void); + +//===== ADD R,(mem) +void srcADDRm(void); + +//===== ADD (mem),R +void srcADDmR(void); + +//===== ADC R,(mem) +void srcADCRm(void); + +//===== ADC (mem),R +void srcADCmR(void); + +//===== SUB R,(mem) +void srcSUBRm(void); + +//===== SUB (mem),R +void srcSUBmR(void); + +//===== SBC R,(mem) +void srcSBCRm(void); + +//===== SBC (mem),R +void srcSBCmR(void); + +//===== AND R,(mem) +void srcANDRm(void); + +//===== AND (mem),R +void srcANDmR(void); + +//===== XOR R,(mem) +void srcXORRm(void); + +//===== XOR (mem),R +void srcXORmR(void); + +//===== OR R,(mem) +void srcORRm(void); + +//===== OR (mem),R +void srcORmR(void); + +//===== CP R,(mem) +void srcCPRm(void); + +//===== CP (mem),R +void srcCPmR(void); + +}; + +//============================================================================= +#endif diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers.cpp b/waterbox/ngp/TLCS-900h/TLCS900h_registers.cpp new file mode 100644 index 0000000000..d17e4a2a31 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers.cpp @@ -0,0 +1,208 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers.c + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +10 AUG 2002 - neopop_uk +======================================= +- Moved default PC setup to the 'reset_registers' function. + +//--------------------------------------------------------------------------- +*/ + +#include "../neopop.h" +#include "../interrupt.h" +#include "TLCS900h_registers.h" + +namespace TLCS900H +{ + +#ifdef MSB_FIRST +#define BYTE0 3 +#define BYTE1 2 +#define BYTE2 1 +#define BYTE3 0 +#define WORD0 2 +#define WORD1 0 +#else +#define BYTE0 0 +#define BYTE1 1 +#define BYTE2 2 +#define BYTE3 3 +#define WORD0 0 +#define WORD1 2 +#endif + +//============================================================================= + +uint32 pc, gprBank[4][4], gpr[4]; +uint16 sr; +uint8 f_dash; + +//============================================================================= + +//Bank Data +uint8* gprMapB[4][8] = +{ + #include "TLCS900h_registers_mapB.h" +}; + +uint16* gprMapW[4][8] = +{ + #include "TLCS900h_registers_mapW.h" +}; + +uint32* gprMapL[4][8] = +{ + #include "TLCS900h_registers_mapL.h" +}; + +//============================================================================= + +uint32 rErr; + +uint8* regCodeMapB[4][256] = +{ + { + #include "TLCS900h_registers_mapCodeB0.h" + }, + + { + #include "TLCS900h_registers_mapCodeB1.h" + }, + + { + #include "TLCS900h_registers_mapCodeB2.h" + }, + + { + #include "TLCS900h_registers_mapCodeB3.h" + } +}; + +uint16* regCodeMapW[4][128] = +{ + { + #include "TLCS900h_registers_mapCodeW0.h" + }, + + { + #include "TLCS900h_registers_mapCodeW1.h" + }, + + { + #include "TLCS900h_registers_mapCodeW2.h" + }, + + { + #include "TLCS900h_registers_mapCodeW3.h" + } +}; + +uint32* regCodeMapL[4][64] = +{ + { + #include "TLCS900h_registers_mapCodeL0.h" + }, + + { + #include "TLCS900h_registers_mapCodeL1.h" + }, + + { + #include "TLCS900h_registers_mapCodeL2.h" + }, + + { + #include "TLCS900h_registers_mapCodeL3.h" + } +}; + +//============================================================================= + +uint8 statusIFF(void) +{ + uint8 iff = (sr & 0x7000) >> 12; + + if (iff == 1) + return 0; + else + return iff; +} + +void setStatusIFF(uint8 iff) +{ + sr = (sr & 0x8FFF) | ((iff & 0x7) << 12); +} + +//============================================================================= + +uint8 statusRFP; + +void setStatusRFP(uint8 rfp) +{ + sr = (sr & 0xF8FF) | ((rfp & 0x3) << 8); + changedSP(); +} + +void changedSP(void) +{ + //Store global RFP for optimisation. + statusRFP = ((sr & 0x300) >> 8); + int_check_pending(); +} + +//============================================================================= + +void reset_registers(void) +{ + memset(gprBank, 0, sizeof(gprBank)); + memset(gpr, 0, sizeof(gpr)); + + if (ngpc_rom.data) + pc = MDFN_de32lsb(rom_header->startPC) & 0xFFFFFF; + else + pc = 0xFFFFFE; + + sr = 0xF800; // = %11111000???????? (?) are undefined in the manual) + changedSP(); + + f_dash = 00; + + rErr = RERR_VALUE; + + gpr[0] = 0xff23c3; + gpr[1] = 0xff23df; + gpr[2] = 0x006480; + REGXSP = 0x00006C00; //Confirmed from BIOS, + //immediately changes value from default of 0x100 +} + +}; + +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers.h b/waterbox/ngp/TLCS-900h/TLCS900h_registers.h new file mode 100644 index 0000000000..b343cf8f43 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers.h @@ -0,0 +1,126 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +21 AUG 2002 - neopop_uk +======================================= +- Fixed potential precidence problems in regX and rCodeX by using ()'s + +//--------------------------------------------------------------------------- +*/ + +#ifndef __TLCS900H_REGISTERS__ +#define __TLCS900H_REGISTERS__ +//============================================================================= + +namespace TLCS900H +{ + +void reset_registers(void); +void dump_registers_TLCS900h(void); + +//The value read by bad rCodes, leave 0, improves "Gals Fighters" +#define RERR_VALUE 0 + +//============================================================================= + +extern uint32 pc; +extern uint16 sr; +extern uint8 f_dash; + +extern uint32 gprBank[4][4], gpr[4]; + +extern uint32 rErr; + +extern uint8 statusRFP; + +//GPR Access +extern uint8* gprMapB[4][8]; +extern uint16* gprMapW[4][8]; +extern uint32* gprMapL[4][8]; + +#define regB(x) (*(gprMapB[statusRFP][(x)])) +#define regW(x) (*(gprMapW[statusRFP][(x)])) +#define regL(x) (*(gprMapL[statusRFP][(x)])) + +//Reg.Code Access +extern uint8* regCodeMapB[4][256]; +extern uint16* regCodeMapW[4][128]; +extern uint32* regCodeMapL[4][64]; + +#define rCodeB(r) (*(regCodeMapB[statusRFP][(r)])) +#define rCodeW(r) (*(regCodeMapW[statusRFP][(r) >> 1])) +#define rCodeL(r) (*(regCodeMapL[statusRFP][(r) >> 2])) + +//Common Registers +#define REGA (regB(1)) +#define REGWA (regW(0)) +#define REGBC (regW(1)) +#define REGXSP (gpr[3]) + +//============================================================================= + +uint8 statusIFF(void); +void setStatusIFF(uint8 iff); + +void setStatusRFP(uint8 rfp); +void changedSP(void); + +#define FLAG_S ((sr & 0x0080) >> 7) +#define FLAG_Z ((sr & 0x0040) >> 6) +#define FLAG_H ((sr & 0x0010) >> 4) +#define FLAG_V ((sr & 0x0004) >> 2) +#define FLAG_N ((sr & 0x0002) >> 1) +#define FLAG_C (sr & 1) + +#define SETFLAG_S(s) { uint16 sr1 = sr & 0xFF7F; if (s) sr1 |= 0x0080; sr = sr1; } +#define SETFLAG_Z(z) { uint16 sr1 = sr & 0xFFBF; if (z) sr1 |= 0x0040; sr = sr1; } +#define SETFLAG_H(h) { uint16 sr1 = sr & 0xFFEF; if (h) sr1 |= 0x0010; sr = sr1; } +#define SETFLAG_V(v) { uint16 sr1 = sr & 0xFFFB; if (v) sr1 |= 0x0004; sr = sr1; } +#define SETFLAG_N(n) { uint16 sr1 = sr & 0xFFFD; if (n) sr1 |= 0x0002; sr = sr1; } +#define SETFLAG_C(c) { uint16 sr1 = sr & 0xFFFE; if (c) sr1 |= 0x0001; sr = sr1; } + +#define SETFLAG_S0 { sr &= 0xFF7F; } +#define SETFLAG_Z0 { sr &= 0xFFBF; } +#define SETFLAG_H0 { sr &= 0xFFEF; } +#define SETFLAG_V0 { sr &= 0xFFFB; } +#define SETFLAG_N0 { sr &= 0xFFFD; } +#define SETFLAG_C0 { sr &= 0xFFFE; } + +#define SETFLAG_S1 { sr |= 0x0080; } +#define SETFLAG_Z1 { sr |= 0x0040; } +#define SETFLAG_H1 { sr |= 0x0010; } +#define SETFLAG_V1 { sr |= 0x0004; } +#define SETFLAG_N1 { sr |= 0x0002; } +#define SETFLAG_C1 { sr |= 0x0001; } + +}; + +//============================================================================= +#endif diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapB.h b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapB.h new file mode 100644 index 0000000000..f6688f88bd --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapB.h @@ -0,0 +1,83 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers_mapB.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + + //Bank 0 + { + (uint8*)&(gprBank[0][0]) + BYTE1, + (uint8*)&(gprBank[0][0]) + BYTE0, + (uint8*)&(gprBank[0][1]) + BYTE1, + (uint8*)&(gprBank[0][1]) + BYTE0, + (uint8*)&(gprBank[0][2]) + BYTE1, + (uint8*)&(gprBank[0][2]) + BYTE0, + (uint8*)&(gprBank[0][3]) + BYTE1, + (uint8*)&(gprBank[0][3]) + BYTE0, + }, + + //Bank 1 + { + (uint8*)&(gprBank[1][0]) + BYTE1, + (uint8*)&(gprBank[1][0]) + BYTE0, + (uint8*)&(gprBank[1][1]) + BYTE1, + (uint8*)&(gprBank[1][1]) + BYTE0, + (uint8*)&(gprBank[1][2]) + BYTE1, + (uint8*)&(gprBank[1][2]) + BYTE0, + (uint8*)&(gprBank[1][3]) + BYTE1, + (uint8*)&(gprBank[1][3]) + BYTE0, + }, + + //Bank 2 + { + (uint8*)&(gprBank[2][0]) + BYTE1, + (uint8*)&(gprBank[2][0]) + BYTE0, + (uint8*)&(gprBank[2][1]) + BYTE1, + (uint8*)&(gprBank[2][1]) + BYTE0, + (uint8*)&(gprBank[2][2]) + BYTE1, + (uint8*)&(gprBank[2][2]) + BYTE0, + (uint8*)&(gprBank[2][3]) + BYTE1, + (uint8*)&(gprBank[2][3]) + BYTE0, + }, + + //Bank 3 + { + (uint8*)&(gprBank[3][0]) + BYTE1, + (uint8*)&(gprBank[3][0]) + BYTE0, + (uint8*)&(gprBank[3][1]) + BYTE1, + (uint8*)&(gprBank[3][1]) + BYTE0, + (uint8*)&(gprBank[3][2]) + BYTE1, + (uint8*)&(gprBank[3][2]) + BYTE0, + (uint8*)&(gprBank[3][3]) + BYTE1, + (uint8*)&(gprBank[3][3]) + BYTE0, + } + +//============================================================================= + diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeB0.h b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeB0.h new file mode 100644 index 0000000000..8b76446da5 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeB0.h @@ -0,0 +1,105 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers_mapCodeB0.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + + ((uint8*)&gprBank[0][0]) + BYTE0,((uint8*)&gprBank[0][0]) + BYTE1, //BANK 0 + ((uint8*)&gprBank[0][0]) + BYTE2, ((uint8*)&gprBank[0][0]) + BYTE3, + ((uint8*)&gprBank[0][1]) + BYTE0,((uint8*)&gprBank[0][1]) + BYTE1, + ((uint8*)&gprBank[0][1]) + BYTE2, ((uint8*)&gprBank[0][1]) + BYTE3, + ((uint8*)&gprBank[0][2]) + BYTE0,((uint8*)&gprBank[0][2]) + BYTE1, + ((uint8*)&gprBank[0][2]) + BYTE2, ((uint8*)&gprBank[0][2]) + BYTE3, + ((uint8*)&gprBank[0][3]) + BYTE0,((uint8*)&gprBank[0][3]) + BYTE1, + ((uint8*)&gprBank[0][3]) + BYTE2, ((uint8*)&gprBank[0][3]) + BYTE3, + + ((uint8*)&gprBank[1][0]) + BYTE0,((uint8*)&gprBank[1][0]) + BYTE1, //BANK 1 + ((uint8*)&gprBank[1][0]) + BYTE2, ((uint8*)&gprBank[1][0]) + BYTE3, + ((uint8*)&gprBank[1][1]) + BYTE0,((uint8*)&gprBank[1][1]) + BYTE1, + ((uint8*)&gprBank[1][1]) + BYTE2, ((uint8*)&gprBank[1][1]) + BYTE3, + ((uint8*)&gprBank[1][2]) + BYTE0,((uint8*)&gprBank[1][2]) + BYTE1, + ((uint8*)&gprBank[1][2]) + BYTE2, ((uint8*)&gprBank[1][2]) + BYTE3, + ((uint8*)&gprBank[1][3]) + BYTE0,((uint8*)&gprBank[1][3]) + BYTE1, + ((uint8*)&gprBank[1][3]) + BYTE2, ((uint8*)&gprBank[1][3]) + BYTE3, + + ((uint8*)&gprBank[2][0]) + BYTE0,((uint8*)&gprBank[2][0]) + BYTE1, //BANK 2 + ((uint8*)&gprBank[2][0]) + BYTE2, ((uint8*)&gprBank[2][0]) + BYTE3, + ((uint8*)&gprBank[2][1]) + BYTE0,((uint8*)&gprBank[2][1]) + BYTE1, + ((uint8*)&gprBank[2][1]) + BYTE2, ((uint8*)&gprBank[2][1]) + BYTE3, + ((uint8*)&gprBank[2][2]) + BYTE0,((uint8*)&gprBank[2][2]) + BYTE1, + ((uint8*)&gprBank[2][2]) + BYTE2, ((uint8*)&gprBank[2][2]) + BYTE3, + ((uint8*)&gprBank[2][3]) + BYTE0,((uint8*)&gprBank[2][3]) + BYTE1, + ((uint8*)&gprBank[2][3]) + BYTE2, ((uint8*)&gprBank[2][3]) + BYTE3, + + ((uint8*)&gprBank[3][0]) + BYTE0,((uint8*)&gprBank[3][0]) + BYTE1, //BANK 3 + ((uint8*)&gprBank[3][0]) + BYTE2, ((uint8*)&gprBank[3][0]) + BYTE3, + ((uint8*)&gprBank[3][1]) + BYTE0,((uint8*)&gprBank[3][1]) + BYTE1, + ((uint8*)&gprBank[3][1]) + BYTE2, ((uint8*)&gprBank[3][1]) + BYTE3, + ((uint8*)&gprBank[3][2]) + BYTE0,((uint8*)&gprBank[3][2]) + BYTE1, + ((uint8*)&gprBank[3][2]) + BYTE2, ((uint8*)&gprBank[3][2]) + BYTE3, + ((uint8*)&gprBank[3][3]) + BYTE0,((uint8*)&gprBank[3][3]) + BYTE1, + ((uint8*)&gprBank[3][3]) + BYTE2, ((uint8*)&gprBank[3][3]) + BYTE3, + + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + + //Previous Bank + (uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr, + + //Current Bank + ((uint8*)&gprBank[0][0]) + BYTE0,((uint8*)&gprBank[0][0]) + BYTE1, + ((uint8*)&gprBank[0][0]) + BYTE2, ((uint8*)&gprBank[0][0]) + BYTE3, + ((uint8*)&gprBank[0][1]) + BYTE0,((uint8*)&gprBank[0][1]) + BYTE1, + ((uint8*)&gprBank[0][1]) + BYTE2, ((uint8*)&gprBank[0][1]) + BYTE3, + ((uint8*)&gprBank[0][2]) + BYTE0,((uint8*)&gprBank[0][2]) + BYTE1, + ((uint8*)&gprBank[0][2]) + BYTE2, ((uint8*)&gprBank[0][2]) + BYTE3, + ((uint8*)&gprBank[0][3]) + BYTE0,((uint8*)&gprBank[0][3]) + BYTE1, + ((uint8*)&gprBank[0][3]) + BYTE2, ((uint8*)&gprBank[0][3]) + BYTE3, + + ((uint8*)&gpr[0]) + BYTE0, ((uint8*)&gpr[0]) + BYTE1, + ((uint8*)&gpr[0]) + BYTE2, ((uint8*)&gpr[0]) + BYTE3, + ((uint8*)&gpr[1]) + BYTE0, ((uint8*)&gpr[1]) + BYTE1, + ((uint8*)&gpr[1]) + BYTE2, ((uint8*)&gpr[1]) + BYTE3, + ((uint8*)&gpr[2]) + BYTE0, ((uint8*)&gpr[2]) + BYTE1, + ((uint8*)&gpr[2]) + BYTE2, ((uint8*)&gpr[2]) + BYTE3, + ((uint8*)&gpr[3]) + BYTE0, ((uint8*)&gpr[3]) + BYTE1, + ((uint8*)&gpr[3]) + BYTE2, ((uint8*)&gpr[3]) + BYTE3 + +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeB1.h b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeB1.h new file mode 100644 index 0000000000..d9f7868bf5 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeB1.h @@ -0,0 +1,105 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers_mapCodeB1.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + + ((uint8*)&gprBank[0][0]) + BYTE0,((uint8*)&gprBank[0][0]) + BYTE1, //BANK 0 + ((uint8*)&gprBank[0][0]) + BYTE2, ((uint8*)&gprBank[0][0]) + BYTE3, + ((uint8*)&gprBank[0][1]) + BYTE0,((uint8*)&gprBank[0][1]) + BYTE1, + ((uint8*)&gprBank[0][1]) + BYTE2, ((uint8*)&gprBank[0][1]) + BYTE3, + ((uint8*)&gprBank[0][2]) + BYTE0,((uint8*)&gprBank[0][2]) + BYTE1, + ((uint8*)&gprBank[0][2]) + BYTE2, ((uint8*)&gprBank[0][2]) + BYTE3, + ((uint8*)&gprBank[0][3]) + BYTE0,((uint8*)&gprBank[0][3]) + BYTE1, + ((uint8*)&gprBank[0][3]) + BYTE2, ((uint8*)&gprBank[0][3]) + BYTE3, + + ((uint8*)&gprBank[1][0]) + BYTE0,((uint8*)&gprBank[1][0]) + BYTE1, //BANK 1 + ((uint8*)&gprBank[1][0]) + BYTE2, ((uint8*)&gprBank[1][0]) + BYTE3, + ((uint8*)&gprBank[1][1]) + BYTE0,((uint8*)&gprBank[1][1]) + BYTE1, + ((uint8*)&gprBank[1][1]) + BYTE2, ((uint8*)&gprBank[1][1]) + BYTE3, + ((uint8*)&gprBank[1][2]) + BYTE0,((uint8*)&gprBank[1][2]) + BYTE1, + ((uint8*)&gprBank[1][2]) + BYTE2, ((uint8*)&gprBank[1][2]) + BYTE3, + ((uint8*)&gprBank[1][3]) + BYTE0,((uint8*)&gprBank[1][3]) + BYTE1, + ((uint8*)&gprBank[1][3]) + BYTE2, ((uint8*)&gprBank[1][3]) + BYTE3, + + ((uint8*)&gprBank[2][0]) + BYTE0,((uint8*)&gprBank[2][0]) + BYTE1, //BANK 2 + ((uint8*)&gprBank[2][0]) + BYTE2, ((uint8*)&gprBank[2][0]) + BYTE3, + ((uint8*)&gprBank[2][1]) + BYTE0,((uint8*)&gprBank[2][1]) + BYTE1, + ((uint8*)&gprBank[2][1]) + BYTE2, ((uint8*)&gprBank[2][1]) + BYTE3, + ((uint8*)&gprBank[2][2]) + BYTE0,((uint8*)&gprBank[2][2]) + BYTE1, + ((uint8*)&gprBank[2][2]) + BYTE2, ((uint8*)&gprBank[2][2]) + BYTE3, + ((uint8*)&gprBank[2][3]) + BYTE0,((uint8*)&gprBank[2][3]) + BYTE1, + ((uint8*)&gprBank[2][3]) + BYTE2, ((uint8*)&gprBank[2][3]) + BYTE3, + + ((uint8*)&gprBank[3][0]) + BYTE0,((uint8*)&gprBank[3][0]) + BYTE1, //BANK 3 + ((uint8*)&gprBank[3][0]) + BYTE2, ((uint8*)&gprBank[3][0]) + BYTE3, + ((uint8*)&gprBank[3][1]) + BYTE0,((uint8*)&gprBank[3][1]) + BYTE1, + ((uint8*)&gprBank[3][1]) + BYTE2, ((uint8*)&gprBank[3][1]) + BYTE3, + ((uint8*)&gprBank[3][2]) + BYTE0,((uint8*)&gprBank[3][2]) + BYTE1, + ((uint8*)&gprBank[3][2]) + BYTE2, ((uint8*)&gprBank[3][2]) + BYTE3, + ((uint8*)&gprBank[3][3]) + BYTE0,((uint8*)&gprBank[3][3]) + BYTE1, + ((uint8*)&gprBank[3][3]) + BYTE2, ((uint8*)&gprBank[3][3]) + BYTE3, + + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + + //Previous Bank + ((uint8*)&gprBank[0][0]) + BYTE0,((uint8*)&gprBank[0][0]) + BYTE1, + ((uint8*)&gprBank[0][0]) + BYTE2, ((uint8*)&gprBank[0][0]) + BYTE3, + ((uint8*)&gprBank[0][1]) + BYTE0,((uint8*)&gprBank[0][1]) + BYTE1, + ((uint8*)&gprBank[0][1]) + BYTE2, ((uint8*)&gprBank[0][1]) + BYTE3, + ((uint8*)&gprBank[0][2]) + BYTE0,((uint8*)&gprBank[0][2]) + BYTE1, + ((uint8*)&gprBank[0][2]) + BYTE2, ((uint8*)&gprBank[0][2]) + BYTE3, + ((uint8*)&gprBank[0][3]) + BYTE0,((uint8*)&gprBank[0][3]) + BYTE1, + ((uint8*)&gprBank[0][3]) + BYTE2, ((uint8*)&gprBank[0][3]) + BYTE3, + + //Current Bank + ((uint8*)&gprBank[1][0]) + BYTE0,((uint8*)&gprBank[1][0]) + BYTE1, + ((uint8*)&gprBank[1][0]) + BYTE2, ((uint8*)&gprBank[1][0]) + BYTE3, + ((uint8*)&gprBank[1][1]) + BYTE0,((uint8*)&gprBank[1][1]) + BYTE1, + ((uint8*)&gprBank[1][1]) + BYTE2, ((uint8*)&gprBank[1][1]) + BYTE3, + ((uint8*)&gprBank[1][2]) + BYTE0,((uint8*)&gprBank[1][2]) + BYTE1, + ((uint8*)&gprBank[1][2]) + BYTE2, ((uint8*)&gprBank[1][2]) + BYTE3, + ((uint8*)&gprBank[1][3]) + BYTE0,((uint8*)&gprBank[1][3]) + BYTE1, + ((uint8*)&gprBank[1][3]) + BYTE2, ((uint8*)&gprBank[1][3]) + BYTE3, + + ((uint8*)&gpr[0]) + BYTE0, ((uint8*)&gpr[0]) + BYTE1, + ((uint8*)&gpr[0]) + BYTE2, ((uint8*)&gpr[0]) + BYTE3, + ((uint8*)&gpr[1]) + BYTE0, ((uint8*)&gpr[1]) + BYTE1, + ((uint8*)&gpr[1]) + BYTE2, ((uint8*)&gpr[1]) + BYTE3, + ((uint8*)&gpr[2]) + BYTE0, ((uint8*)&gpr[2]) + BYTE1, + ((uint8*)&gpr[2]) + BYTE2, ((uint8*)&gpr[2]) + BYTE3, + ((uint8*)&gpr[3]) + BYTE0, ((uint8*)&gpr[3]) + BYTE1, + ((uint8*)&gpr[3]) + BYTE2, ((uint8*)&gpr[3]) + BYTE3 + +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeB2.h b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeB2.h new file mode 100644 index 0000000000..036604be22 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeB2.h @@ -0,0 +1,105 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers_mapCodeB2.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + + ((uint8*)&gprBank[0][0]) + BYTE0,((uint8*)&gprBank[0][0]) + BYTE1, //BANK 0 + ((uint8*)&gprBank[0][0]) + BYTE2, ((uint8*)&gprBank[0][0]) + BYTE3, + ((uint8*)&gprBank[0][1]) + BYTE0,((uint8*)&gprBank[0][1]) + BYTE1, + ((uint8*)&gprBank[0][1]) + BYTE2, ((uint8*)&gprBank[0][1]) + BYTE3, + ((uint8*)&gprBank[0][2]) + BYTE0,((uint8*)&gprBank[0][2]) + BYTE1, + ((uint8*)&gprBank[0][2]) + BYTE2, ((uint8*)&gprBank[0][2]) + BYTE3, + ((uint8*)&gprBank[0][3]) + BYTE0,((uint8*)&gprBank[0][3]) + BYTE1, + ((uint8*)&gprBank[0][3]) + BYTE2, ((uint8*)&gprBank[0][3]) + BYTE3, + + ((uint8*)&gprBank[1][0]) + BYTE0,((uint8*)&gprBank[1][0]) + BYTE1, //BANK 1 + ((uint8*)&gprBank[1][0]) + BYTE2, ((uint8*)&gprBank[1][0]) + BYTE3, + ((uint8*)&gprBank[1][1]) + BYTE0,((uint8*)&gprBank[1][1]) + BYTE1, + ((uint8*)&gprBank[1][1]) + BYTE2, ((uint8*)&gprBank[1][1]) + BYTE3, + ((uint8*)&gprBank[1][2]) + BYTE0,((uint8*)&gprBank[1][2]) + BYTE1, + ((uint8*)&gprBank[1][2]) + BYTE2, ((uint8*)&gprBank[1][2]) + BYTE3, + ((uint8*)&gprBank[1][3]) + BYTE0,((uint8*)&gprBank[1][3]) + BYTE1, + ((uint8*)&gprBank[1][3]) + BYTE2, ((uint8*)&gprBank[1][3]) + BYTE3, + + ((uint8*)&gprBank[2][0]) + BYTE0,((uint8*)&gprBank[2][0]) + BYTE1, //BANK 2 + ((uint8*)&gprBank[2][0]) + BYTE2, ((uint8*)&gprBank[2][0]) + BYTE3, + ((uint8*)&gprBank[2][1]) + BYTE0,((uint8*)&gprBank[2][1]) + BYTE1, + ((uint8*)&gprBank[2][1]) + BYTE2, ((uint8*)&gprBank[2][1]) + BYTE3, + ((uint8*)&gprBank[2][2]) + BYTE0,((uint8*)&gprBank[2][2]) + BYTE1, + ((uint8*)&gprBank[2][2]) + BYTE2, ((uint8*)&gprBank[2][2]) + BYTE3, + ((uint8*)&gprBank[2][3]) + BYTE0,((uint8*)&gprBank[2][3]) + BYTE1, + ((uint8*)&gprBank[2][3]) + BYTE2, ((uint8*)&gprBank[2][3]) + BYTE3, + + ((uint8*)&gprBank[3][0]) + BYTE0,((uint8*)&gprBank[3][0]) + BYTE1, //BANK 3 + ((uint8*)&gprBank[3][0]) + BYTE2, ((uint8*)&gprBank[3][0]) + BYTE3, + ((uint8*)&gprBank[3][1]) + BYTE0,((uint8*)&gprBank[3][1]) + BYTE1, + ((uint8*)&gprBank[3][1]) + BYTE2, ((uint8*)&gprBank[3][1]) + BYTE3, + ((uint8*)&gprBank[3][2]) + BYTE0,((uint8*)&gprBank[3][2]) + BYTE1, + ((uint8*)&gprBank[3][2]) + BYTE2, ((uint8*)&gprBank[3][2]) + BYTE3, + ((uint8*)&gprBank[3][3]) + BYTE0,((uint8*)&gprBank[3][3]) + BYTE1, + ((uint8*)&gprBank[3][3]) + BYTE2, ((uint8*)&gprBank[3][3]) + BYTE3, + + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + + //Previous Bank + ((uint8*)&gprBank[1][0]) + BYTE0,((uint8*)&gprBank[1][0]) + BYTE1, + ((uint8*)&gprBank[1][0]) + BYTE2, ((uint8*)&gprBank[1][0]) + BYTE3, + ((uint8*)&gprBank[1][1]) + BYTE0,((uint8*)&gprBank[1][1]) + BYTE1, + ((uint8*)&gprBank[1][1]) + BYTE2, ((uint8*)&gprBank[1][1]) + BYTE3, + ((uint8*)&gprBank[1][2]) + BYTE0,((uint8*)&gprBank[1][2]) + BYTE1, + ((uint8*)&gprBank[1][2]) + BYTE2, ((uint8*)&gprBank[1][2]) + BYTE3, + ((uint8*)&gprBank[1][3]) + BYTE0,((uint8*)&gprBank[1][3]) + BYTE1, + ((uint8*)&gprBank[1][3]) + BYTE2, ((uint8*)&gprBank[1][3]) + BYTE3, + + //Current Bank + ((uint8*)&gprBank[2][0]) + BYTE0,((uint8*)&gprBank[2][0]) + BYTE1, + ((uint8*)&gprBank[2][0]) + BYTE2, ((uint8*)&gprBank[2][0]) + BYTE3, + ((uint8*)&gprBank[2][1]) + BYTE0,((uint8*)&gprBank[2][1]) + BYTE1, + ((uint8*)&gprBank[2][1]) + BYTE2, ((uint8*)&gprBank[2][1]) + BYTE3, + ((uint8*)&gprBank[2][2]) + BYTE0,((uint8*)&gprBank[2][2]) + BYTE1, + ((uint8*)&gprBank[2][2]) + BYTE2, ((uint8*)&gprBank[2][2]) + BYTE3, + ((uint8*)&gprBank[2][3]) + BYTE0,((uint8*)&gprBank[2][3]) + BYTE1, + ((uint8*)&gprBank[2][3]) + BYTE2, ((uint8*)&gprBank[2][3]) + BYTE3, + + ((uint8*)&gpr[0]) + BYTE0, ((uint8*)&gpr[0]) + BYTE1, + ((uint8*)&gpr[0]) + BYTE2, ((uint8*)&gpr[0]) + BYTE3, + ((uint8*)&gpr[1]) + BYTE0, ((uint8*)&gpr[1]) + BYTE1, + ((uint8*)&gpr[1]) + BYTE2, ((uint8*)&gpr[1]) + BYTE3, + ((uint8*)&gpr[2]) + BYTE0, ((uint8*)&gpr[2]) + BYTE1, + ((uint8*)&gpr[2]) + BYTE2, ((uint8*)&gpr[2]) + BYTE3, + ((uint8*)&gpr[3]) + BYTE0, ((uint8*)&gpr[3]) + BYTE1, + ((uint8*)&gpr[3]) + BYTE2, ((uint8*)&gpr[3]) + BYTE3 + +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeB3.h b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeB3.h new file mode 100644 index 0000000000..b3e1fd77fb --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeB3.h @@ -0,0 +1,105 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers_mapCodeB3.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + + ((uint8*)&gprBank[0][0]) + BYTE0,((uint8*)&gprBank[0][0]) + BYTE1, //BANK 0 + ((uint8*)&gprBank[0][0]) + BYTE2, ((uint8*)&gprBank[0][0]) + BYTE3, + ((uint8*)&gprBank[0][1]) + BYTE0,((uint8*)&gprBank[0][1]) + BYTE1, + ((uint8*)&gprBank[0][1]) + BYTE2, ((uint8*)&gprBank[0][1]) + BYTE3, + ((uint8*)&gprBank[0][2]) + BYTE0,((uint8*)&gprBank[0][2]) + BYTE1, + ((uint8*)&gprBank[0][2]) + BYTE2, ((uint8*)&gprBank[0][2]) + BYTE3, + ((uint8*)&gprBank[0][3]) + BYTE0,((uint8*)&gprBank[0][3]) + BYTE1, + ((uint8*)&gprBank[0][3]) + BYTE2, ((uint8*)&gprBank[0][3]) + BYTE3, + + ((uint8*)&gprBank[1][0]) + BYTE0,((uint8*)&gprBank[1][0]) + BYTE1, //BANK 1 + ((uint8*)&gprBank[1][0]) + BYTE2, ((uint8*)&gprBank[1][0]) + BYTE3, + ((uint8*)&gprBank[1][1]) + BYTE0,((uint8*)&gprBank[1][1]) + BYTE1, + ((uint8*)&gprBank[1][1]) + BYTE2, ((uint8*)&gprBank[1][1]) + BYTE3, + ((uint8*)&gprBank[1][2]) + BYTE0,((uint8*)&gprBank[1][2]) + BYTE1, + ((uint8*)&gprBank[1][2]) + BYTE2, ((uint8*)&gprBank[1][2]) + BYTE3, + ((uint8*)&gprBank[1][3]) + BYTE0,((uint8*)&gprBank[1][3]) + BYTE1, + ((uint8*)&gprBank[1][3]) + BYTE2, ((uint8*)&gprBank[1][3]) + BYTE3, + + ((uint8*)&gprBank[2][0]) + BYTE0,((uint8*)&gprBank[2][0]) + BYTE1, //BANK 2 + ((uint8*)&gprBank[2][0]) + BYTE2, ((uint8*)&gprBank[2][0]) + BYTE3, + ((uint8*)&gprBank[2][1]) + BYTE0,((uint8*)&gprBank[2][1]) + BYTE1, + ((uint8*)&gprBank[2][1]) + BYTE2, ((uint8*)&gprBank[2][1]) + BYTE3, + ((uint8*)&gprBank[2][2]) + BYTE0,((uint8*)&gprBank[2][2]) + BYTE1, + ((uint8*)&gprBank[2][2]) + BYTE2, ((uint8*)&gprBank[2][2]) + BYTE3, + ((uint8*)&gprBank[2][3]) + BYTE0,((uint8*)&gprBank[2][3]) + BYTE1, + ((uint8*)&gprBank[2][3]) + BYTE2, ((uint8*)&gprBank[2][3]) + BYTE3, + + ((uint8*)&gprBank[3][0]) + BYTE0,((uint8*)&gprBank[3][0]) + BYTE1, //BANK 3 + ((uint8*)&gprBank[3][0]) + BYTE2, ((uint8*)&gprBank[3][0]) + BYTE3, + ((uint8*)&gprBank[3][1]) + BYTE0,((uint8*)&gprBank[3][1]) + BYTE1, + ((uint8*)&gprBank[3][1]) + BYTE2, ((uint8*)&gprBank[3][1]) + BYTE3, + ((uint8*)&gprBank[3][2]) + BYTE0,((uint8*)&gprBank[3][2]) + BYTE1, + ((uint8*)&gprBank[3][2]) + BYTE2, ((uint8*)&gprBank[3][2]) + BYTE3, + ((uint8*)&gprBank[3][3]) + BYTE0,((uint8*)&gprBank[3][3]) + BYTE1, + ((uint8*)&gprBank[3][3]) + BYTE2, ((uint8*)&gprBank[3][3]) + BYTE3, + + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + (uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr,(uint8*)&rErr, + + //Previous Bank + ((uint8*)&gprBank[2][0]) + BYTE0,((uint8*)&gprBank[2][0]) + BYTE1, + ((uint8*)&gprBank[2][0]) + BYTE2, ((uint8*)&gprBank[2][0]) + BYTE3, + ((uint8*)&gprBank[2][1]) + BYTE0,((uint8*)&gprBank[2][1]) + BYTE1, + ((uint8*)&gprBank[2][1]) + BYTE2, ((uint8*)&gprBank[2][1]) + BYTE3, + ((uint8*)&gprBank[2][2]) + BYTE0,((uint8*)&gprBank[2][2]) + BYTE1, + ((uint8*)&gprBank[2][2]) + BYTE2, ((uint8*)&gprBank[2][2]) + BYTE3, + ((uint8*)&gprBank[2][3]) + BYTE0,((uint8*)&gprBank[2][3]) + BYTE1, + ((uint8*)&gprBank[2][3]) + BYTE2, ((uint8*)&gprBank[2][3]) + BYTE3, + + //Current Bank + ((uint8*)&gprBank[3][0]) + BYTE0,((uint8*)&gprBank[3][0]) + BYTE1, + ((uint8*)&gprBank[3][0]) + BYTE2, ((uint8*)&gprBank[3][0]) + BYTE3, + ((uint8*)&gprBank[3][1]) + BYTE0,((uint8*)&gprBank[3][1]) + BYTE1, + ((uint8*)&gprBank[3][1]) + BYTE2, ((uint8*)&gprBank[3][1]) + BYTE3, + ((uint8*)&gprBank[3][2]) + BYTE0,((uint8*)&gprBank[3][2]) + BYTE1, + ((uint8*)&gprBank[3][2]) + BYTE2, ((uint8*)&gprBank[3][2]) + BYTE3, + ((uint8*)&gprBank[3][3]) + BYTE0,((uint8*)&gprBank[3][3]) + BYTE1, + ((uint8*)&gprBank[3][3]) + BYTE2, ((uint8*)&gprBank[3][3]) + BYTE3, + + ((uint8*)&gpr[0]) + BYTE0, ((uint8*)&gpr[0]) + BYTE1, + ((uint8*)&gpr[0]) + BYTE2, ((uint8*)&gpr[0]) + BYTE3, + ((uint8*)&gpr[1]) + BYTE0, ((uint8*)&gpr[1]) + BYTE1, + ((uint8*)&gpr[1]) + BYTE2, ((uint8*)&gpr[1]) + BYTE3, + ((uint8*)&gpr[2]) + BYTE0, ((uint8*)&gpr[2]) + BYTE1, + ((uint8*)&gpr[2]) + BYTE2, ((uint8*)&gpr[2]) + BYTE3, + ((uint8*)&gpr[3]) + BYTE0, ((uint8*)&gpr[3]) + BYTE1, + ((uint8*)&gpr[3]) + BYTE2, ((uint8*)&gpr[3]) + BYTE3 + +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeL0.h b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeL0.h new file mode 100644 index 0000000000..6897182d51 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeL0.h @@ -0,0 +1,60 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers_mapCodeL0.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + + //BANK 0 + &(gprBank[0][0]), &(gprBank[0][1]), &(gprBank[0][2]), &(gprBank[0][3]), + + //BANK 1 + &(gprBank[1][0]), &(gprBank[1][1]), &(gprBank[1][2]), &(gprBank[1][3]), + + //BANK 2 + &(gprBank[2][0]), &(gprBank[2][1]), &(gprBank[2][2]), &(gprBank[2][3]), + + //BANK 3 + &(gprBank[3][0]), &(gprBank[3][1]), &(gprBank[3][2]), &(gprBank[3][3]), + + &rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr, + &rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr, + &rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr, + &rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr, + &rErr,&rErr,&rErr,&rErr, + + //Previous Bank + &rErr,&rErr,&rErr,&rErr, + + //Current Bank + &(gprBank[0][0]), &(gprBank[0][1]), &(gprBank[0][2]), &(gprBank[0][3]), + + &(gpr[0]), &(gpr[1]), &(gpr[2]), &(gpr[3]) + +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeL1.h b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeL1.h new file mode 100644 index 0000000000..6099806d63 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeL1.h @@ -0,0 +1,60 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers_mapCodeL1.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + + //BANK 0 + &(gprBank[0][0]), &(gprBank[0][1]), &(gprBank[0][2]), &(gprBank[0][3]), + + //BANK 1 + &(gprBank[1][0]), &(gprBank[1][1]), &(gprBank[1][2]), &(gprBank[1][3]), + + //BANK 2 + &(gprBank[2][0]), &(gprBank[2][1]), &(gprBank[2][2]), &(gprBank[2][3]), + + //BANK 3 + &(gprBank[3][0]), &(gprBank[3][1]), &(gprBank[3][2]), &(gprBank[3][3]), + + &rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr, + &rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr, + &rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr, + &rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr, + &rErr,&rErr,&rErr,&rErr, + + //Previous Bank + &(gprBank[0][0]), &(gprBank[0][1]), &(gprBank[0][2]), &(gprBank[0][3]), + + //Current Bank + &(gprBank[1][0]), &(gprBank[1][1]), &(gprBank[1][2]), &(gprBank[1][3]), + + &(gpr[0]), &(gpr[1]), &(gpr[2]), &(gpr[3]) + +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeL2.h b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeL2.h new file mode 100644 index 0000000000..57492049bf --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeL2.h @@ -0,0 +1,60 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers_mapCodeL2.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + + //BANK 0 + &(gprBank[0][0]), &(gprBank[0][1]), &(gprBank[0][2]), &(gprBank[0][3]), + + //BANK 1 + &(gprBank[1][0]), &(gprBank[1][1]), &(gprBank[1][2]), &(gprBank[1][3]), + + //BANK 2 + &(gprBank[2][0]), &(gprBank[2][1]), &(gprBank[2][2]), &(gprBank[2][3]), + + //BANK 3 + &(gprBank[3][0]), &(gprBank[3][1]), &(gprBank[3][2]), &(gprBank[3][3]), + + &rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr, + &rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr, + &rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr, + &rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr, + &rErr,&rErr,&rErr,&rErr, + + //Previous Bank + &(gprBank[1][0]), &(gprBank[1][1]), &(gprBank[1][2]), &(gprBank[1][3]), + + //Current Bank + &(gprBank[2][0]), &(gprBank[2][1]), &(gprBank[2][2]), &(gprBank[2][3]), + + &(gpr[0]), &(gpr[1]), &(gpr[2]), &(gpr[3]) + +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeL3.h b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeL3.h new file mode 100644 index 0000000000..aa597cadba --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeL3.h @@ -0,0 +1,60 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers_mapCodeL3.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + + //BANK 0 + &(gprBank[0][0]), &(gprBank[0][1]), &(gprBank[0][2]), &(gprBank[0][3]), + + //BANK 1 + &(gprBank[1][0]), &(gprBank[1][1]), &(gprBank[1][2]), &(gprBank[1][3]), + + //BANK 2 + &(gprBank[2][0]), &(gprBank[2][1]), &(gprBank[2][2]), &(gprBank[2][3]), + + //BANK 3 + &(gprBank[3][0]), &(gprBank[3][1]), &(gprBank[3][2]), &(gprBank[3][3]), + + &rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr, + &rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr, + &rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr, + &rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr,&rErr, + &rErr,&rErr,&rErr,&rErr, + + //Previous Bank + &(gprBank[2][0]), &(gprBank[2][1]), &(gprBank[2][2]), &(gprBank[2][3]), + + //Current Bank + &(gprBank[3][0]), &(gprBank[3][1]), &(gprBank[3][2]), &(gprBank[3][3]), + + &(gpr[0]), &(gpr[1]), &(gpr[2]), &(gpr[3]) + +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeW0.h b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeW0.h new file mode 100644 index 0000000000..ba9fb6954d --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeW0.h @@ -0,0 +1,94 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers_mapCodeW0.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + + //BANK 0 + (uint16*)(((uint8*)&gprBank[0][0]) + WORD0), (uint16*)(((uint8*)&gprBank[0][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][1]) + WORD0), (uint16*)(((uint8*)&gprBank[0][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][2]) + WORD0), (uint16*)(((uint8*)&gprBank[0][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][3]) + WORD0), (uint16*)(((uint8*)&gprBank[0][3]) + WORD1), + + //BANK 1 + (uint16*)(((uint8*)&gprBank[1][0]) + WORD0), (uint16*)(((uint8*)&gprBank[1][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][1]) + WORD0), (uint16*)(((uint8*)&gprBank[1][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][2]) + WORD0), (uint16*)(((uint8*)&gprBank[1][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][3]) + WORD0), (uint16*)(((uint8*)&gprBank[1][3]) + WORD1), + + //BANK 2 + (uint16*)(((uint8*)&gprBank[2][0]) + WORD0), (uint16*)(((uint8*)&gprBank[2][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][1]) + WORD0), (uint16*)(((uint8*)&gprBank[2][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][2]) + WORD0), (uint16*)(((uint8*)&gprBank[2][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][3]) + WORD0), (uint16*)(((uint8*)&gprBank[2][3]) + WORD1), + + //BANK 3 + (uint16*)(((uint8*)&gprBank[3][0]) + WORD0), (uint16*)(((uint8*)&gprBank[3][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[3][1]) + WORD0), (uint16*)(((uint8*)&gprBank[3][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[3][2]) + WORD0), (uint16*)(((uint8*)&gprBank[3][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[3][3]) + WORD0), (uint16*)(((uint8*)&gprBank[3][3]) + WORD1), + + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + + //Previous Bank + (uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr, + + //Current Bank + (uint16*)(((uint8*)&gprBank[0][0]) + WORD0), (uint16*)(((uint8*)&gprBank[0][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][1]) + WORD0), (uint16*)(((uint8*)&gprBank[0][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][2]) + WORD0), (uint16*)(((uint8*)&gprBank[0][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][3]) + WORD0), (uint16*)(((uint8*)&gprBank[0][3]) + WORD1), + + (uint16*)((uint8*)&(gpr[0]) + WORD0), (uint16*)((uint8*)&(gpr[0]) + WORD1), + (uint16*)((uint8*)&(gpr[1]) + WORD0), (uint16*)((uint8*)&(gpr[1]) + WORD1), + (uint16*)((uint8*)&(gpr[2]) + WORD0), (uint16*)((uint8*)&(gpr[2]) + WORD1), + (uint16*)((uint8*)&(gpr[3]) + WORD0), (uint16*)((uint8*)&(gpr[3]) + WORD1), + +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeW1.h b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeW1.h new file mode 100644 index 0000000000..fa7f93f1d9 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeW1.h @@ -0,0 +1,94 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers_mapCodeW1.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + + //BANK 0 + (uint16*)(((uint8*)&gprBank[0][0]) + WORD0), (uint16*)(((uint8*)&gprBank[0][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][1]) + WORD0), (uint16*)(((uint8*)&gprBank[0][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][2]) + WORD0), (uint16*)(((uint8*)&gprBank[0][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][3]) + WORD0), (uint16*)(((uint8*)&gprBank[0][3]) + WORD1), + + //BANK 1 + (uint16*)(((uint8*)&gprBank[1][0]) + WORD0), (uint16*)(((uint8*)&gprBank[1][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][1]) + WORD0), (uint16*)(((uint8*)&gprBank[1][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][2]) + WORD0), (uint16*)(((uint8*)&gprBank[1][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][3]) + WORD0), (uint16*)(((uint8*)&gprBank[1][3]) + WORD1), + + //BANK 2 + (uint16*)(((uint8*)&gprBank[2][0]) + WORD0), (uint16*)(((uint8*)&gprBank[2][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][1]) + WORD0), (uint16*)(((uint8*)&gprBank[2][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][2]) + WORD0), (uint16*)(((uint8*)&gprBank[2][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][3]) + WORD0), (uint16*)(((uint8*)&gprBank[2][3]) + WORD1), + + //BANK 3 + (uint16*)(((uint8*)&gprBank[3][0]) + WORD0), (uint16*)(((uint8*)&gprBank[3][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[3][1]) + WORD0), (uint16*)(((uint8*)&gprBank[3][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[3][2]) + WORD0), (uint16*)(((uint8*)&gprBank[3][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[3][3]) + WORD0), (uint16*)(((uint8*)&gprBank[3][3]) + WORD1), + + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + + //Previous Bank + (uint16*)(((uint8*)&gprBank[0][0]) + WORD0), (uint16*)(((uint8*)&gprBank[0][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][1]) + WORD0), (uint16*)(((uint8*)&gprBank[0][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][2]) + WORD0), (uint16*)(((uint8*)&gprBank[0][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][3]) + WORD0), (uint16*)(((uint8*)&gprBank[0][3]) + WORD1), + + //Current Bank + (uint16*)(((uint8*)&gprBank[1][0]) + WORD0), (uint16*)(((uint8*)&gprBank[1][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][1]) + WORD0), (uint16*)(((uint8*)&gprBank[1][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][2]) + WORD0), (uint16*)(((uint8*)&gprBank[1][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][3]) + WORD0), (uint16*)(((uint8*)&gprBank[1][3]) + WORD1), + + (uint16*)((uint8*)&(gpr[0]) + WORD0), (uint16*)((uint8*)&(gpr[0]) + WORD1), + (uint16*)((uint8*)&(gpr[1]) + WORD0), (uint16*)((uint8*)&(gpr[1]) + WORD1), + (uint16*)((uint8*)&(gpr[2]) + WORD0), (uint16*)((uint8*)&(gpr[2]) + WORD1), + (uint16*)((uint8*)&(gpr[3]) + WORD0), (uint16*)((uint8*)&(gpr[3]) + WORD1), + +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeW2.h b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeW2.h new file mode 100644 index 0000000000..805c605598 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeW2.h @@ -0,0 +1,94 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers_mapCodeW2.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + + //BANK 0 + (uint16*)(((uint8*)&gprBank[0][0]) + WORD0), (uint16*)(((uint8*)&gprBank[0][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][1]) + WORD0), (uint16*)(((uint8*)&gprBank[0][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][2]) + WORD0), (uint16*)(((uint8*)&gprBank[0][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][3]) + WORD0), (uint16*)(((uint8*)&gprBank[0][3]) + WORD1), + + //BANK 1 + (uint16*)(((uint8*)&gprBank[1][0]) + WORD0), (uint16*)(((uint8*)&gprBank[1][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][1]) + WORD0), (uint16*)(((uint8*)&gprBank[1][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][2]) + WORD0), (uint16*)(((uint8*)&gprBank[1][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][3]) + WORD0), (uint16*)(((uint8*)&gprBank[1][3]) + WORD1), + + //BANK 2 + (uint16*)(((uint8*)&gprBank[2][0]) + WORD0), (uint16*)(((uint8*)&gprBank[2][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][1]) + WORD0), (uint16*)(((uint8*)&gprBank[2][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][2]) + WORD0), (uint16*)(((uint8*)&gprBank[2][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][3]) + WORD0), (uint16*)(((uint8*)&gprBank[2][3]) + WORD1), + + //BANK 3 + (uint16*)(((uint8*)&gprBank[3][0]) + WORD0), (uint16*)(((uint8*)&gprBank[3][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[3][1]) + WORD0), (uint16*)(((uint8*)&gprBank[3][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[3][2]) + WORD0), (uint16*)(((uint8*)&gprBank[3][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[3][3]) + WORD0), (uint16*)(((uint8*)&gprBank[3][3]) + WORD1), + + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + + //Previous Bank + (uint16*)(((uint8*)&gprBank[1][0]) + WORD0), (uint16*)(((uint8*)&gprBank[1][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][1]) + WORD0), (uint16*)(((uint8*)&gprBank[1][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][2]) + WORD0), (uint16*)(((uint8*)&gprBank[1][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][3]) + WORD0), (uint16*)(((uint8*)&gprBank[1][3]) + WORD1), + + //Current Bank + (uint16*)(((uint8*)&gprBank[2][0]) + WORD0), (uint16*)(((uint8*)&gprBank[2][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][1]) + WORD0), (uint16*)(((uint8*)&gprBank[2][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][2]) + WORD0), (uint16*)(((uint8*)&gprBank[2][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][3]) + WORD0), (uint16*)(((uint8*)&gprBank[2][3]) + WORD1), + + (uint16*)((uint8*)&(gpr[0]) + WORD0), (uint16*)((uint8*)&(gpr[0]) + WORD1), + (uint16*)((uint8*)&(gpr[1]) + WORD0), (uint16*)((uint8*)&(gpr[1]) + WORD1), + (uint16*)((uint8*)&(gpr[2]) + WORD0), (uint16*)((uint8*)&(gpr[2]) + WORD1), + (uint16*)((uint8*)&(gpr[3]) + WORD0), (uint16*)((uint8*)&(gpr[3]) + WORD1), + +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeW3.h b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeW3.h new file mode 100644 index 0000000000..a1f431766e --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapCodeW3.h @@ -0,0 +1,94 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers_mapCodeW3.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + + //BANK 0 + (uint16*)(((uint8*)&gprBank[0][0]) + WORD0), (uint16*)(((uint8*)&gprBank[0][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][1]) + WORD0), (uint16*)(((uint8*)&gprBank[0][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][2]) + WORD0), (uint16*)(((uint8*)&gprBank[0][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[0][3]) + WORD0), (uint16*)(((uint8*)&gprBank[0][3]) + WORD1), + + //BANK 1 + (uint16*)(((uint8*)&gprBank[1][0]) + WORD0), (uint16*)(((uint8*)&gprBank[1][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][1]) + WORD0), (uint16*)(((uint8*)&gprBank[1][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][2]) + WORD0), (uint16*)(((uint8*)&gprBank[1][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[1][3]) + WORD0), (uint16*)(((uint8*)&gprBank[1][3]) + WORD1), + + //BANK 2 + (uint16*)(((uint8*)&gprBank[2][0]) + WORD0), (uint16*)(((uint8*)&gprBank[2][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][1]) + WORD0), (uint16*)(((uint8*)&gprBank[2][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][2]) + WORD0), (uint16*)(((uint8*)&gprBank[2][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][3]) + WORD0), (uint16*)(((uint8*)&gprBank[2][3]) + WORD1), + + //BANK 3 + (uint16*)(((uint8*)&gprBank[3][0]) + WORD0), (uint16*)(((uint8*)&gprBank[3][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[3][1]) + WORD0), (uint16*)(((uint8*)&gprBank[3][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[3][2]) + WORD0), (uint16*)(((uint8*)&gprBank[3][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[3][3]) + WORD0), (uint16*)(((uint8*)&gprBank[3][3]) + WORD1), + + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + (uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr,(uint16*)&rErr, + + //Previous Bank + (uint16*)(((uint8*)&gprBank[2][0]) + WORD0), (uint16*)(((uint8*)&gprBank[2][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][1]) + WORD0), (uint16*)(((uint8*)&gprBank[2][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][2]) + WORD0), (uint16*)(((uint8*)&gprBank[2][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[2][3]) + WORD0), (uint16*)(((uint8*)&gprBank[2][3]) + WORD1), + + //Current Bank + (uint16*)(((uint8*)&gprBank[3][0]) + WORD0), (uint16*)(((uint8*)&gprBank[3][0]) + WORD1), + (uint16*)(((uint8*)&gprBank[3][1]) + WORD0), (uint16*)(((uint8*)&gprBank[3][1]) + WORD1), + (uint16*)(((uint8*)&gprBank[3][2]) + WORD0), (uint16*)(((uint8*)&gprBank[3][2]) + WORD1), + (uint16*)(((uint8*)&gprBank[3][3]) + WORD0), (uint16*)(((uint8*)&gprBank[3][3]) + WORD1), + + (uint16*)((uint8*)&(gpr[0]) + WORD0), (uint16*)((uint8*)&(gpr[0]) + WORD1), + (uint16*)((uint8*)&(gpr[1]) + WORD0), (uint16*)((uint8*)&(gpr[1]) + WORD1), + (uint16*)((uint8*)&(gpr[2]) + WORD0), (uint16*)((uint8*)&(gpr[2]) + WORD1), + (uint16*)((uint8*)&(gpr[3]) + WORD0), (uint16*)((uint8*)&(gpr[3]) + WORD1), + +//============================================================================= diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapL.h b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapL.h new file mode 100644 index 0000000000..102a9f0436 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapL.h @@ -0,0 +1,84 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers_mapL.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + + //Bank 0 + { + (uint32*)&(gprBank[0][0]), + (uint32*)&(gprBank[0][1]), + (uint32*)&(gprBank[0][2]), + (uint32*)&(gprBank[0][3]), + (uint32*)&(gpr[0]), + (uint32*)&(gpr[1]), + (uint32*)&(gpr[2]), + (uint32*)&(gpr[3]), + }, + + //Bank 1 + { + (uint32*)&(gprBank[1][0]), + (uint32*)&(gprBank[1][1]), + (uint32*)&(gprBank[1][2]), + (uint32*)&(gprBank[1][3]), + (uint32*)&(gpr[0]), + (uint32*)&(gpr[1]), + (uint32*)&(gpr[2]), + (uint32*)&(gpr[3]), + }, + + //Bank 2 + { + (uint32*)&(gprBank[2][0]), + (uint32*)&(gprBank[2][1]), + (uint32*)&(gprBank[2][2]), + (uint32*)&(gprBank[2][3]), + (uint32*)&(gpr[0]), + (uint32*)&(gpr[1]), + (uint32*)&(gpr[2]), + (uint32*)&(gpr[3]), + }, + + //Bank 3 + { + (uint32*)&(gprBank[3][0]), + (uint32*)&(gprBank[3][1]), + (uint32*)&(gprBank[3][2]), + (uint32*)&(gprBank[3][3]), + (uint32*)&(gpr[0]), + (uint32*)&(gpr[1]), + (uint32*)&(gpr[2]), + (uint32*)&(gpr[3]), + }, + +//============================================================================= + + diff --git a/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapW.h b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapW.h new file mode 100644 index 0000000000..0cd86877d5 --- /dev/null +++ b/waterbox/ngp/TLCS-900h/TLCS900h_registers_mapW.h @@ -0,0 +1,84 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + TLCS900h_registers_mapW.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +//--------------------------------------------------------------------------- +*/ + + //Bank 0 + { + (uint16*)(((uint8*)&gprBank[0][0]) + WORD0), + (uint16*)(((uint8*)&gprBank[0][1]) + WORD0), + (uint16*)(((uint8*)&gprBank[0][2]) + WORD0), + (uint16*)(((uint8*)&gprBank[0][3]) + WORD0), + (uint16*)(((uint8*)&gpr[0]) + WORD0), + (uint16*)(((uint8*)&gpr[1]) + WORD0), + (uint16*)(((uint8*)&gpr[2]) + WORD0), + (uint16*)(((uint8*)&gpr[3]) + WORD0), + }, + + //Bank 1 + { + (uint16*)(((uint8*)&gprBank[1][0]) + WORD0), + (uint16*)(((uint8*)&gprBank[1][1]) + WORD0), + (uint16*)(((uint8*)&gprBank[1][2]) + WORD0), + (uint16*)(((uint8*)&gprBank[1][3]) + WORD0), + (uint16*)(((uint8*)&gpr[0]) + WORD0), + (uint16*)(((uint8*)&gpr[1]) + WORD0), + (uint16*)(((uint8*)&gpr[2]) + WORD0), + (uint16*)(((uint8*)&gpr[3]) + WORD0), + }, + + //Bank 2 + { + (uint16*)(((uint8*)&gprBank[2][0]) + WORD0), + (uint16*)(((uint8*)&gprBank[2][1]) + WORD0), + (uint16*)(((uint8*)&gprBank[2][2]) + WORD0), + (uint16*)(((uint8*)&gprBank[2][3]) + WORD0), + (uint16*)(((uint8*)&gpr[0]) + WORD0), + (uint16*)(((uint8*)&gpr[1]) + WORD0), + (uint16*)(((uint8*)&gpr[2]) + WORD0), + (uint16*)(((uint8*)&gpr[3]) + WORD0), + }, + + //Bank 3 + { + (uint16*)(((uint8*)&gprBank[3][0]) + WORD0), + (uint16*)(((uint8*)&gprBank[3][1]) + WORD0), + (uint16*)(((uint8*)&gprBank[3][2]) + WORD0), + (uint16*)(((uint8*)&gprBank[3][3]) + WORD0), + (uint16*)(((uint8*)&gpr[0]) + WORD0), + (uint16*)(((uint8*)&gpr[1]) + WORD0), + (uint16*)(((uint8*)&gpr[2]) + WORD0), + (uint16*)(((uint8*)&gpr[3]) + WORD0), + }, + +//============================================================================= + + diff --git a/waterbox/ngp/Z80_interface.cpp b/waterbox/ngp/Z80_interface.cpp new file mode 100644 index 0000000000..ef47a9f3e1 --- /dev/null +++ b/waterbox/ngp/Z80_interface.cpp @@ -0,0 +1,139 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#include "neopop.h" +#include "mem.h" +#include "sound.h" +#include "Z80_interface.h" +#include "interrupt.h" +#include "dma.h" + +namespace MDFN_IEN_NGP +{ + +static uint8 CommByte; +static bool Z80Enabled; + +uint8 Z80_ReadComm(void) +{ + return (CommByte); +} + +void Z80_WriteComm(uint8 data) +{ + CommByte = data; +} + +static uint8 NGP_z80_readbyte(uint16 address) +{ + if (address <= 0xFFF) + return loadB(0x7000 + address); + + if (address == 0x8000) + { + return CommByte; + } + return 0; +} + +//============================================================================= + +static void NGP_z80_writebyte(uint16 address, uint8 value) +{ + if (address <= 0x0FFF) + { + storeB(0x7000 + address, value); + return; + } + + if (address == 0x8000) + { + CommByte = value; + return; + } + + if (address == 0x4001) + { + Write_SoundChipLeft(value); + return; + } + if (address == 0x4000) + { + Write_SoundChipRight(value); + return; + } + + if (address == 0xC000) + { + TestIntHDMA(6, 0x0C); + } +} + +//============================================================================= + +static void NGP_z80_writeport(uint16 port, uint8 value) +{ + //printf("Portout: %04x %02x\n", port, value); + z80_set_interrupt(0); +} + +static uint8 NGP_z80_readport(uint16 port) +{ + //printf("Portin: %04x\n", port); + return 0; +} + +void Z80_nmi(void) +{ + z80_nmi(); +} + +void Z80_irq(void) +{ + z80_set_interrupt(1); +} + +void Z80_reset(void) +{ + Z80Enabled = 0; + + z80_writebyte = NGP_z80_writebyte; + z80_readbyte = NGP_z80_readbyte; + z80_writeport = NGP_z80_writeport; + z80_readport = NGP_z80_readport; + + z80_init(); + z80_reset(); +} + +void Z80_SetEnable(bool set) +{ + Z80Enabled = set; + if (!set) + z80_reset(); +} + +bool Z80_IsEnabled(void) +{ + return (Z80Enabled); +} + +int Z80_RunOP(void) +{ + if (!Z80Enabled) + return (-1); + + return (z80_do_opcode()); +} +} diff --git a/waterbox/ngp/Z80_interface.h b/waterbox/ngp/Z80_interface.h new file mode 100644 index 0000000000..e3cc8baa74 --- /dev/null +++ b/waterbox/ngp/Z80_interface.h @@ -0,0 +1,37 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#ifndef __Z80_CONTROL__ +#define __Z80_CONTROL__ +//============================================================================= + +#include "z80-fuse/z80.h" + +namespace MDFN_IEN_NGP +{ + +uint8 Z80_ReadComm(void); +void Z80_WriteComm(uint8 data); + +void Z80_reset(void); // z80 reset + +void Z80_irq(void); // Cause an interrupt +void Z80_nmi(void); // Cause an NMI +void Z80_SetEnable(bool set); +bool Z80_IsEnabled(void); +int Z80_RunOP(void); + +} + +#endif diff --git a/waterbox/ngp/bios.cpp b/waterbox/ngp/bios.cpp new file mode 100644 index 0000000000..8a91c7f490 --- /dev/null +++ b/waterbox/ngp/bios.cpp @@ -0,0 +1,241 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#include "neopop.h" +#include "Z80_interface.h" +#include "gfx.h" +#include "mem.h" +#include "interrupt.h" +#include "sound.h" +#include "dma.h" +#include "bios.h" + +namespace MDFN_IEN_NGP +{ + +//============================================================================= + +uint8 ngpc_bios[0x10000]; //Holds bios program data + +//============================================================================= + +void reset(void) +{ + NGPGfx->power(); + Z80_reset(); + reset_int(); + reset_timers(); + + reset_memory(); + BIOSHLE_Reset(); + reset_registers(); // TLCS900H registers + reset_dma(); +} + +//============================================================================= + +static const uint8 font[0x800] = { + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF8,0xF8,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0, + 0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0, + 0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x20,0x30,0x38,0x3C,0x38,0x30,0x20,0x00,0x04,0x0C,0x1C,0x3C,0x1C,0x0C,0x04,0x00, + 0x00,0x00,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,0x10,0x38,0x7C,0xFE,0x00,0x00, + 0x20,0x3C,0x08,0x3C,0x28,0x7E,0x08,0x00,0x3C,0x24,0x3C,0x24,0x3C,0x24,0x24,0x00, + 0x3C,0x24,0x24,0x3C,0x24,0x24,0x3C,0x00,0x10,0x10,0x54,0x54,0x10,0x28,0xC6,0x00, + 0x10,0x12,0xD4,0x58,0x54,0x92,0x10,0x00,0x10,0x10,0x7C,0x10,0x38,0x54,0x92,0x00, + 0x10,0x28,0x7C,0x92,0x38,0x54,0xFE,0x00,0x10,0x10,0x10,0x7C,0x10,0x10,0xFE,0x00, + 0x7F,0xFF,0xE0,0xFF,0x7F,0x01,0xFF,0xFF,0xDC,0xDE,0x1F,0x9F,0xDF,0xDD,0xDC,0x9C, + 0x3B,0x3B,0x3B,0xBB,0xFB,0xFB,0xFB,0x7B,0x8F,0x9E,0xBC,0xF8,0xF8,0xBC,0x9E,0x8F, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x08,0x10,0x00,0x18,0x00, + 0x6C,0x6C,0x24,0x48,0x00,0x00,0x00,0x00,0x14,0x14,0xFE,0x28,0xFE,0x50,0x50,0x00, + 0x10,0x7C,0x90,0x7C,0x12,0xFC,0x10,0x00,0x42,0xA4,0xA8,0x54,0x2A,0x4A,0x84,0x00, + 0x30,0x48,0x38,0x62,0x94,0x88,0x76,0x00,0x18,0x18,0x08,0x10,0x00,0x00,0x00,0x00, + 0x08,0x10,0x20,0x20,0x20,0x10,0x08,0x00,0x20,0x10,0x08,0x08,0x08,0x10,0x20,0x00, + 0x10,0x92,0x54,0x38,0x38,0x54,0x92,0x00,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x00, + 0x00,0x00,0x00,0x30,0x30,0x10,0x20,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x00, + 0x3C,0x42,0x46,0x5A,0x62,0x42,0x3C,0x00,0x08,0x38,0x08,0x08,0x08,0x08,0x08,0x00, + 0x3C,0x42,0x42,0x0C,0x30,0x40,0x7E,0x00,0x3C,0x42,0x02,0x1C,0x02,0x42,0x3C,0x00, + 0x0C,0x14,0x24,0x44,0x7E,0x04,0x04,0x00,0x7E,0x40,0x7C,0x02,0x02,0x42,0x3C,0x00, + 0x3C,0x40,0x7C,0x42,0x42,0x42,0x3C,0x00,0x7E,0x02,0x04,0x08,0x08,0x10,0x10,0x00, + 0x3C,0x42,0x42,0x3C,0x42,0x42,0x3C,0x00,0x3C,0x42,0x42,0x42,0x3E,0x02,0x3C,0x00, + 0x00,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x18,0x08,0x10,0x00, + 0x00,0x08,0x10,0x20,0x10,0x08,0x00,0x00,0x00,0x00,0x3C,0x00,0x3C,0x00,0x00,0x00, + 0x00,0x10,0x08,0x04,0x08,0x10,0x00,0x00,0x3C,0x62,0x62,0x0C,0x18,0x00,0x18,0x00, + 0x7C,0x82,0xBA,0xA2,0xBA,0x82,0x7C,0x00,0x10,0x28,0x28,0x44,0x7C,0x82,0x82,0x00, + 0x7C,0x42,0x42,0x7C,0x42,0x42,0x7C,0x00,0x1C,0x22,0x40,0x40,0x40,0x22,0x1C,0x00, + 0x78,0x44,0x42,0x42,0x42,0x44,0x78,0x00,0x7E,0x40,0x40,0x7E,0x40,0x40,0x7E,0x00, + 0x7E,0x40,0x40,0x7C,0x40,0x40,0x40,0x00,0x3C,0x42,0x80,0x9E,0x82,0x46,0x3A,0x00, + 0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00, + 0x02,0x02,0x02,0x02,0x42,0x42,0x3C,0x00,0x42,0x44,0x48,0x50,0x68,0x44,0x42,0x00, + 0x40,0x40,0x40,0x40,0x40,0x40,0x7E,0x00,0x82,0xC6,0xAA,0x92,0x82,0x82,0x82,0x00, + 0x42,0x62,0x52,0x4A,0x46,0x42,0x42,0x00,0x38,0x44,0x82,0x82,0x82,0x44,0x38,0x00, + 0x7C,0x42,0x42,0x7C,0x40,0x40,0x40,0x00,0x38,0x44,0x82,0x82,0x8A,0x44,0x3A,0x00, + 0x7C,0x42,0x42,0x7C,0x48,0x44,0x42,0x00,0x3C,0x42,0x40,0x3C,0x02,0x42,0x3C,0x00, + 0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00, + 0x82,0x82,0x44,0x44,0x28,0x28,0x10,0x00,0x82,0x92,0x92,0xAA,0xAA,0x44,0x44,0x00, + 0x82,0x44,0x28,0x10,0x28,0x44,0x82,0x00,0x82,0x44,0x28,0x10,0x10,0x10,0x10,0x00, + 0x7E,0x04,0x08,0x10,0x20,0x40,0x7E,0x00,0x18,0x10,0x10,0x10,0x10,0x10,0x18,0x00, + 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x18,0x00, + 0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, + 0x08,0x10,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x78,0x04,0x7C,0x84,0x84,0x7E,0x00, + 0x40,0x40,0x7C,0x42,0x42,0x42,0x3C,0x00,0x00,0x00,0x3C,0x42,0x40,0x42,0x3C,0x00, + 0x02,0x02,0x3E,0x42,0x42,0x42,0x3C,0x00,0x00,0x00,0x3C,0x42,0x7E,0x40,0x3E,0x00, + 0x0C,0x10,0x3E,0x10,0x10,0x10,0x10,0x00,0x00,0x3C,0x42,0x42,0x3E,0x02,0x7C,0x00, + 0x40,0x40,0x7C,0x42,0x42,0x42,0x42,0x00,0x18,0x18,0x00,0x08,0x08,0x08,0x08,0x00, + 0x06,0x06,0x00,0x02,0x42,0x42,0x3C,0x00,0x20,0x20,0x26,0x28,0x30,0x28,0x26,0x00, + 0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x80,0xEC,0x92,0x92,0x92,0x92,0x00, + 0x00,0x40,0x78,0x44,0x44,0x44,0x44,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x3C,0x00, + 0x00,0x3C,0x42,0x42,0x7C,0x40,0x40,0x00,0x00,0x78,0x84,0x84,0x7C,0x04,0x06,0x00, + 0x00,0x00,0x5C,0x62,0x40,0x40,0x40,0x00,0x00,0x00,0x3E,0x40,0x3C,0x02,0x7C,0x00, + 0x00,0x10,0x7C,0x10,0x10,0x10,0x0E,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x3F,0x00, + 0x00,0x00,0x42,0x42,0x24,0x24,0x18,0x00,0x00,0x00,0x92,0x92,0x92,0x92,0x6C,0x00, + 0x00,0x00,0x42,0x24,0x18,0x24,0x42,0x00,0x00,0x00,0x42,0x42,0x3E,0x02,0x7C,0x00, + 0x00,0x00,0x7E,0x02,0x3C,0x40,0x7E,0x00,0x08,0x10,0x10,0x20,0x10,0x10,0x08,0x00, + 0x10,0x10,0x10,0x00,0x10,0x10,0x10,0x00,0x20,0x10,0x10,0x08,0x10,0x10,0x20,0x00, + 0x00,0x00,0x60,0x92,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x90,0x90,0x60,0x00, + 0x1E,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0xF0,0x00, + 0x00,0x00,0x00,0x80,0x40,0x60,0x60,0x00,0x00,0x00,0x00,0x30,0x78,0x30,0x00,0x00, + 0x20,0xF8,0x26,0x78,0xD0,0x80,0x7C,0x00,0x00,0x10,0x3A,0x1C,0x36,0x5A,0x36,0x00, + 0x00,0x00,0x44,0x42,0x42,0x42,0x30,0x00,0x00,0x3C,0x00,0x3C,0x42,0x02,0x3C,0x00, + 0x00,0x3C,0x00,0x7C,0x08,0x38,0x66,0x00,0x00,0x14,0x72,0x1C,0x32,0x52,0x34,0x00, + 0x00,0x28,0x2C,0x3A,0x62,0x16,0x10,0x00,0x00,0x08,0x5C,0x6A,0x4A,0x0C,0x18,0x00, + 0x00,0x08,0x0C,0x38,0x4C,0x4A,0x38,0x00,0x00,0x00,0x00,0x1C,0x62,0x02,0x1C,0x00, + 0x00,0x00,0x80,0x7E,0x00,0x00,0x00,0x00,0x28,0xF2,0x3C,0x6A,0xAA,0xB6,0xEC,0x00, + 0x80,0x88,0x84,0x84,0x82,0x92,0x70,0x00,0x78,0x00,0x3C,0xC2,0x02,0x04,0x78,0x00, + 0x78,0x00,0xFC,0x08,0x30,0x50,0x9E,0x00,0x2C,0xF2,0x20,0x7C,0xA2,0xA2,0xE4,0x00, + 0x28,0xF4,0x2A,0x4A,0x4A,0x88,0xB0,0x00,0x20,0xFC,0x12,0xFC,0x08,0xC2,0x7C,0x00, + 0x04,0x18,0x60,0x80,0xC0,0x30,0x0E,0x00,0x84,0xBE,0x84,0x84,0x84,0x84,0x58,0x00, + 0x00,0x7C,0x02,0x00,0x80,0x82,0x7E,0x00,0x20,0xFE,0x10,0x78,0x8C,0xC0,0x7C,0x00, + 0x80,0x80,0x80,0x80,0x82,0x84,0x78,0x00,0x04,0xFE,0x3C,0x44,0x7C,0x04,0x78,0x00, + 0x44,0x5E,0xF4,0x44,0x48,0x40,0x3E,0x00,0x44,0x58,0xE0,0x3E,0xC0,0x40,0x3C,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x90,0x90,0x60,0x00, + 0x1E,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0xF0,0x00, + 0x00,0x00,0x00,0x80,0x40,0x60,0x60,0x00,0x00,0x00,0x00,0x30,0x78,0x30,0x00,0x00, + 0x1E,0x62,0x1E,0x62,0x04,0x0C,0x30,0x00,0x00,0x00,0x1E,0x6A,0x0E,0x08,0x18,0x00, + 0x00,0x00,0x06,0x18,0x68,0x08,0x08,0x00,0x00,0x10,0x1C,0x72,0x42,0x04,0x38,0x00, + 0x00,0x00,0x0C,0x78,0x10,0x10,0x7E,0x00,0x00,0x08,0x08,0x7C,0x18,0x28,0x48,0x00, + 0x00,0x00,0x26,0x1A,0x72,0x10,0x08,0x00,0x00,0x00,0x0C,0x34,0x04,0x08,0x7E,0x00, + 0x00,0x00,0x78,0x04,0x3C,0x04,0x78,0x00,0x00,0x00,0x52,0x4A,0x22,0x04,0x38,0x00, + 0x00,0x00,0x80,0x7E,0x00,0x00,0x00,0x00,0x3C,0xC2,0x14,0x1C,0x10,0x30,0x60,0x00, + 0x02,0x0C,0x38,0xC8,0x08,0x08,0x08,0x00,0x60,0x3C,0xE2,0x82,0x82,0x04,0x38,0x00, + 0x00,0x1C,0x70,0x10,0x10,0x1C,0xE2,0x00,0x08,0xFE,0x18,0x38,0x68,0xC8,0x18,0x00, + 0x10,0x3E,0xD2,0x12,0x22,0x62,0xCC,0x00,0x20,0x3C,0xF0,0x1E,0xF0,0x08,0x08,0x00, + 0x10,0x3E,0x62,0xC2,0x04,0x0C,0x70,0x00,0x40,0x7E,0x44,0x84,0x84,0x08,0x30,0x00, + 0x3E,0xC2,0x02,0x02,0x02,0x02,0xFC,0x00,0x44,0x5E,0xE4,0x44,0x44,0x08,0xF0,0x00, + 0x60,0x12,0xC2,0x22,0x04,0x04,0xF8,0x00,0x3C,0xC6,0x0C,0x08,0x38,0x6C,0xC6,0x00, + 0x40,0x4E,0x72,0xC4,0x4C,0x40,0x3E,0x00,0x82,0x42,0x62,0x04,0x04,0x08,0x70,0x00, + 0x3C,0x42,0x72,0x8A,0x04,0x0C,0x70,0x00,0x0C,0xF8,0x10,0xFE,0x10,0x10,0x60,0x00, + 0x22,0xA2,0x92,0x42,0x04,0x08,0x70,0x00,0x3C,0x40,0x1E,0xE8,0x08,0x10,0x60,0x00, + 0x40,0x40,0x70,0x4C,0x42,0x40,0x40,0x00,0x08,0x3E,0xC8,0x08,0x08,0x18,0x70,0x00, + 0x00,0x1C,0x60,0x00,0x00,0x3C,0xC2,0x00,0x3C,0xC2,0x26,0x38,0x1C,0x36,0xE2,0x00, + 0x10,0x3C,0xC6,0x1C,0x38,0xD6,0x12,0x00,0x02,0x02,0x02,0x06,0x04,0x1C,0xF0,0x00, + 0x18,0x4C,0x44,0x46,0x42,0x82,0x82,0x00,0x80,0x86,0xBC,0xE0,0x80,0x80,0x7E,0x00, + 0x3C,0xC2,0x02,0x02,0x04,0x08,0x30,0x00,0x30,0x48,0x4C,0x84,0x86,0x02,0x02,0x00, + 0x10,0xFE,0x10,0x54,0x52,0x92,0x92,0x00,0x3C,0xC2,0x02,0x44,0x28,0x10,0x0C,0x00, + 0x70,0x0C,0x60,0x18,0xC4,0x30,0x0E,0x00,0x30,0x40,0x4C,0x84,0x8E,0xBA,0x62,0x00, + 0x04,0x04,0x64,0x18,0x0C,0x16,0xE2,0x00,0x1C,0xE0,0x3E,0xE0,0x20,0x20,0x1E,0x00, + 0x4E,0x52,0x62,0xE4,0x20,0x10,0x18,0x00,0x1C,0x64,0x04,0x08,0x08,0x10,0xFE,0x00, + 0x1C,0x62,0x02,0x3E,0x02,0x02,0x7C,0x00,0x3C,0xC0,0x3E,0xC2,0x02,0x04,0x78,0x00, + 0x44,0x42,0x42,0x42,0x22,0x04,0x78,0x00,0x50,0x50,0x52,0x52,0x52,0x54,0x88,0x00, + 0x80,0x80,0x82,0x82,0x84,0x88,0xF0,0x00,0x1C,0xE2,0x82,0x82,0x82,0x4C,0x74,0x00, + 0x3C,0xC2,0x82,0x82,0x02,0x04,0x38,0x00,0xC0,0x62,0x22,0x02,0x04,0x08,0xF0,0x00, + 0x00,0x00,0x00,0x00,0x0A,0x05,0x05,0x00,0x00,0x00,0x00,0x00,0x02,0x05,0x02,0x00, + 0x20,0xF8,0x40,0x5E,0x80,0xA0,0x9E,0x00,0x20,0xFE,0x40,0x7C,0xC2,0x86,0x3C,0x00, + 0x00,0x3C,0xC6,0x02,0x02,0x0C,0x38,0x00,0x0E,0xF8,0x10,0x20,0x20,0x10,0x0E,0x00, + 0x40,0x4C,0x30,0x40,0x80,0x80,0x7E,0x00,0x44,0xF2,0x4A,0x9C,0xA4,0xA6,0x3A,0x00, + 0x40,0x5C,0x82,0x80,0xA0,0xA0,0x9E,0x00,0x48,0x7C,0x52,0xB2,0xBE,0xAA,0x4C,0x00, + 0x20,0xFC,0x32,0x62,0xEE,0xAA,0x2C,0x00,0x38,0x54,0x92,0x92,0xB2,0xA2,0x4C,0x00, + 0x44,0x5E,0x84,0x9C,0xA4,0xA6,0x9C,0x00,0x28,0xEE,0x44,0x84,0x84,0x44,0x38,0x00, + 0x78,0x10,0x64,0x34,0x8A,0x8A,0x30,0x00,0x30,0x58,0x48,0x84,0x84,0x02,0x02,0x00, + 0xBC,0x88,0xBE,0x84,0xBC,0xA6,0x9C,0x00,0x68,0x1E,0x68,0x1E,0x78,0x8C,0x7A,0x00, + 0x70,0x14,0x7C,0x96,0x94,0x94,0x68,0x00,0x2C,0xF2,0x60,0xA0,0xA2,0xC2,0x7C,0x00, + 0x48,0x7C,0x6A,0xAA,0xB2,0xB2,0x6C,0x00,0x10,0xF8,0x20,0xF8,0x22,0x22,0x1C,0x00, + 0x48,0x5C,0x6A,0xC2,0x64,0x20,0x18,0x00,0x10,0xBC,0xD6,0xCA,0xAA,0x1C,0x70,0x00, + 0x10,0x1C,0x12,0x70,0x9C,0x92,0x70,0x00,0xE0,0x18,0x40,0x7C,0xC2,0x82,0x3C,0x00, + 0x44,0x42,0x82,0xA2,0x62,0x04,0x78,0x00,0x7C,0x38,0x7C,0xC2,0xBA,0x26,0x3C,0x00, + 0x48,0xD4,0x64,0x64,0xC4,0xC4,0x46,0x00,0x7C,0x30,0x7C,0xC2,0x82,0x06,0x3C,0x00, + 0x20,0xFC,0x32,0x62,0xE2,0xA2,0x2C,0x00,0x10,0x30,0x60,0x72,0xD2,0x92,0x9C,0x00, + 0x00,0x00,0x00,0x00,0x0A,0x05,0x05,0x00,0x00,0x00,0x00,0x00,0x02,0x05,0x02,0x00 +}; + +bool bios_install(void) +{ + //=== Install the reverse engineered bios + int i; + + uint32 vectable[] = + { + 0xFF27A2, //0 VECT_SHUTDOWN + 0xFF1030, //1 VECT_CLOCKGEARSET + 0xFF1440, //2 VECT_RTCGET + 0xFF12B4, //3 ? + 0xFF1222, //4 VECT_INTLVSET + 0xFF8D8A, //5 VECT_SYSFONTSET + 0xFF6FD8, //6 VECT_FLASHWRITE + 0xFF7042, //7 VECT_FLASHALLERS + 0xFF7082, //8 VECT_FLASHERS + 0xFF149B, //9 VECT_ALARMSET + 0xFF1033, //10 ? + 0xFF1487, //11 VECT_ALARMDOWNSET + 0xFF731F, //12 ? + 0xFF70CA, //13 VECT_FLASHPROTECT + 0xFF17C4, //14 VECT_GEMODESET + 0xFF1032, //15 ? + + 0xFF2BBD, //0x10 VECT_COMINIT + 0xFF2C0C, //0x11 VECT_COMSENDSTART + 0xFF2C44, //0x12 VECT_COMRECIVESTART + 0xFF2C86, //0x13 VECT_COMCREATEDATA + 0xFF2CB4, //0x14 VECT_COMGETDATA + 0xFF2D27, //0x15 VECT_COMONRTS + 0xFF2D33, //0x16 VECT_COMOFFRTS + 0xFF2D3A, //0x17 VECT_COMSENDSTATUS + 0xFF2D4E, //0x18 VECT_COMRECIVESTATUS + 0xFF2D6C, //0x19 VECT_COMCREATEBUFDATA + 0xFF2D85, //0x1a VECT_COMGETBUFDATA + }; + + //System Call Table, install iBIOSHLE instructions + for (i = 0; i <= 0x1A; i++) + { + MDFN_en32lsb(&ngpc_bios[0xFE00 + (i * 4)], vectable[i]); + ngpc_bios[vectable[i] & 0xFFFF] = 0x1F; //iBIOSHLE + } + + //System Font + memcpy(ngpc_bios + 0x8DCF, font, 0x800); + + //Default Interrupt handler + ngpc_bios[0x23DF] = 0x07; //RETI + + // ========== + + //Install a Quick and Dirty Bios + ngpc_bios[0xFFFE] = 0x68; // - JR 0xFFFFFE (Infinite loop!) + ngpc_bios[0xFFFF] = 0xFE; + + return TRUE; //Success +} + +} + +//============================================================================= diff --git a/waterbox/ngp/bios.h b/waterbox/ngp/bios.h new file mode 100644 index 0000000000..4c6c7a2b8d --- /dev/null +++ b/waterbox/ngp/bios.h @@ -0,0 +1,55 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + bios.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +18 AUG 2002 - neopop_uk +======================================= +- Moved reset() and biosInstall() to neopop.h + +//--------------------------------------------------------------------------- +*/ + +#ifndef __NEOPOP_BIOS__ +#define __NEOPOP_BIOS__ +//============================================================================= + +namespace MDFN_IEN_NGP +{ + +extern uint8 ngpc_bios[0x10000]; + +void iBIOSHLE(void); + +void biosDecode(int function); +void BIOSHLE_Reset(void); +} + +//============================================================================= +#endif + diff --git a/waterbox/ngp/biosHLE.cpp b/waterbox/ngp/biosHLE.cpp new file mode 100644 index 0000000000..7c097fcb23 --- /dev/null +++ b/waterbox/ngp/biosHLE.cpp @@ -0,0 +1,629 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#include "neopop.h" +#include "bios.h" +#include "mem.h" +#include "flash.h" +#include "dma.h" +#include "interrupt.h" + +namespace MDFN_IEN_NGP +{ + +static uint8 CacheIntPrio[0xB]; // Iinterrupt prio registers at 0x0070-0x007a don't have priority readable. + // This should probably be stored in BIOS work RAM somewhere instead of a separate array, but I don't know where! + +void BIOSHLE_Reset(void) +{ + memset(CacheIntPrio, 0, sizeof(CacheIntPrio)); + CacheIntPrio[0] = 0x02; + CacheIntPrio[1] = 0x32; + + for (int x = 0; x < 0xB; x++) + storeB(0x70 + x, CacheIntPrio[x]); +} + +/* This is the custom HLE instruction. I considered it was the fastest and +most streamlined way of intercepting a bios call. The operation performed +is dependant on the current program counter. */ + +void iBIOSHLE(void) +{ + //Only works within the bios + if ((pc & 0xFF0000) != 0xFF0000) + return; + + pc--; //Compensate for processing this instruction. + + cycles = 8; //TODO: Correct cycle counts (or approx?) + + //if(pc != 0xff1222) + //printf("SPOON: %08x\n", pc); + + switch (pc & 0xffffff) + { + + //default: printf("SPOON: %08x\n", pc); break; + //VECT_SHUTDOWN + case 0xFF27A2: +#ifdef NEOPOP_DEBUG + if (filter_bios) + { + uint32 a = pop32(); + if (a != 0xBAADC0DE) + system_debug_message("VECT_SHUTDOWN: called before %06X", a); + push32(a); + } + + system_debug_stop(); +#endif + { + //Cheap bit of code to stop the message appearing repeatedly. + uint32 a = pop32(); + if (a != 0xBAADC0DE) + MDFN_printf("IDS_POWER"); + push32(0xBAADC0DE); //Sure is! + } + + return; //Don't pop a return address, stay here + + //VECT_CLOCKGEARSET + case 0xFF1030: +#ifdef NEOPOP_DEBUG + if (filter_bios) + { + uint32 a = pop32(); + system_debug_message("VECT_CLOCKGEARSET: called before %06X", a); + push32(a); + } +#endif + //MDFN_printf("%d\n", rCodeB(0x35)); + //TODO + // if (rCodeB(0x35) > 0) + // system_message("Unsupported clock gear %d set\nPlease inform the author", rCodeB(0x35)); + + break; + + //VECT_RTCGET + case 0xFF1440: +#ifdef NEOPOP_DEBUG + if (filter_bios) + { + uint32 a = pop32(); + system_debug_message("VECT_RTCGET: called before %06X", a); + push32(a); + } +#endif + + if (rCodeL(0x3C) < 0xC000) + { + //Copy data from hardware area + storeB(rCodeL(0x3C) + 0, loadB(0x91)); + storeB(rCodeL(0x3C) + 1, loadB(0x92)); + storeB(rCodeL(0x3C) + 2, loadB(0x93)); + storeB(rCodeL(0x3C) + 3, loadB(0x94)); + storeB(rCodeL(0x3C) + 4, loadB(0x95)); + storeB(rCodeL(0x3C) + 5, loadB(0x96)); + storeB(rCodeL(0x3C) + 6, loadB(0x97)); + } + + break; + + //? + //case 0xFF12B4: + // break; + + //VECT_INTLVSET + case 0xFF1222: +#ifdef NEOPOP_DEBUG + if (filter_bios) + { + uint32 a = pop32(); + system_debug_message("VECT_INTLVSET: called before %06X", a); + push32(a); + } +#endif + + { + + uint8 level = rCodeB(0x35); //RB3 + uint8 interrupt = rCodeB(0x34); //RC3 + + // 0 - Interrupt from RTC alarm + // 1 - Interrupt from the Z80 CPU + // 2 - Interrupt from the 8 bit timer 0 + // 3 - Interrupt from the 8 bit timer 1 + // 4 - Interrupt from the 8 bit timer 2 + // 5 - Interrupt from the 8 bit timer 3 + // 6 - End of transfer interrupt from DMA channel 0 + // 7 - End of transfer interrupt from DMA channel 1 + // 8 - End of transfer interrupt from DMA channel 2 + // 9 - End of transfer interrupt from DMA channel 3 + + switch (interrupt) + { + case 0x00: + CacheIntPrio[0x0] = (CacheIntPrio[0x0] & 0xf0) | (level & 0x07); + storeB(0x70, CacheIntPrio[0x0]); + break; + + case 0x01: + CacheIntPrio[0x1] = (CacheIntPrio[0x1] & 0x0f) | ((level & 0x07) << 4); + storeB(0x71, CacheIntPrio[0x1]); + break; + + case 0x02: + CacheIntPrio[0x3] = (CacheIntPrio[0x3] & 0xf0) | (level & 0x07); + storeB(0x73, CacheIntPrio[0x3]); + break; + + case 0x03: + CacheIntPrio[0x3] = (CacheIntPrio[0x3] & 0x0f) | ((level & 0x07) << 4); + storeB(0x73, CacheIntPrio[0x3]); + break; + + case 0x04: + CacheIntPrio[0x4] = (CacheIntPrio[0x4] & 0xf0) | (level & 0x07); + storeB(0x74, CacheIntPrio[0x4]); + break; + + case 0x05: + CacheIntPrio[0x4] = (CacheIntPrio[0x4] & 0x0f) | ((level & 0x07) << 4); + storeB(0x74, CacheIntPrio[0x4]); + break; + + case 0x06: + CacheIntPrio[0x9] = (CacheIntPrio[0x9] & 0xf0) | (level & 0x07); + storeB(0x79, CacheIntPrio[0x9]); + break; + + case 0x07: + CacheIntPrio[0x9] = (CacheIntPrio[0x9] & 0x0f) | ((level & 0x07) << 4); + storeB(0x79, CacheIntPrio[0x9]); + break; + + case 0x08: + CacheIntPrio[0xa] = (CacheIntPrio[0xa] & 0xf0) | (level & 0x07); + storeB(0x7a, CacheIntPrio[0xa]); + break; + + case 0x09: + CacheIntPrio[0xa] = (CacheIntPrio[0xa] & 0x0f) | ((level & 0x07) << 4); + storeB(0x7a, CacheIntPrio[0xa]); + break; + default: + puts("DOH"); + break; + } + } + break; + + //VECT_SYSFONTSET + case 0xFF8D8A: +#ifdef NEOPOP_DEBUG + if (filter_bios) + { + uint32 a = pop32(); + system_debug_message("VECT_SYSFONTSET: called before %06X", a); + push32(a); + } +#endif + { + uint8 a, b, c, j; + uint16 i, dst = 0xA000; + + b = rCodeB(0x30) >> 4; + a = rCodeB(0x30) & 3; + + for (i = 0; i < 0x800; i++) + { + c = ngpc_bios[0x8DCF + i]; + + for (j = 0; j < 8; j++, c <<= 1) + { + uint16 data16; + + data16 = loadW(dst); + data16 <<= 2; + storeW(dst, data16); + + if (c & 0x80) + storeB(dst, loadB(dst) | a); + else + storeB(dst, loadB(dst) | b); + } + + dst += 2; + } + } + + break; + + //VECT_FLASHWRITE + case 0xFF6FD8: +#ifdef NEOPOP_DEBUG + if (filter_bios) + { + uint32 a = pop32(); + system_debug_message("VECT_FLASHWRITE: called before %06X", a); + push32(a); + } +#endif + { + uint32 i, bank = 0x200000; + + //Select HI rom? + if (rCodeB(0x30) == 1) + bank = 0x800000; + +#ifdef NEOPOP_DEBUG + if (filter_bios) + system_debug_message("VECT_FLASHWRITE: Copy %06X -> %06X, %d bytes", + rCodeL(0x3C), rCodeL(0x38) + bank, rCodeW(0x34) * 256); +#endif + + memory_flash_error = FALSE; + memory_unlock_flash_write = TRUE; + //Copy as 32 bit values for speed + for (i = 0; i < rCodeW(0x34) * 64ul; i++) + storeL(rCodeL(0x38) + bank + (i * 4), loadL(rCodeL(0x3C) + (i * 4))); + memory_unlock_flash_write = FALSE; + + if (memory_flash_error) + { +#ifdef NEOPOP_DEBUG + if (filter_bios) + system_debug_message("VECT_FLASHWRITE: Error"); +#endif + rCodeB(0x30) = 0xFF; //RA3 = SYS_FAILURE + } + else + { + uint32 address = rCodeL(0x38); + if (rCodeB(0x30) == 1) + address += 0x800000; + else + address += 0x200000; + + //Save this data to an external file + flash_write(address, rCodeW(0x34) * 256); + + rCodeB(0x30) = 0; //RA3 = SYS_SUCCESS + } + } + + break; + + //VECT_FLASHALLERS + case 0xFF7042: +#ifdef NEOPOP_DEBUG + if (filter_bios) + { + uint32 a = pop32(); + system_debug_message("VECT_FLASHALLERS: called before %06X", a); + push32(a); + } +#endif + //TODO + rCodeB(0x30) = 0; //RA3 = SYS_SUCCESS + break; + + //VECT_FLASHERS + case 0xFF7082: +#ifdef NEOPOP_DEBUG + if (filter_bios) + { + uint32 a = pop32(); + system_debug_message("VECT_FLASHERS: called before %06X", a); + push32(a); + } +#endif +#ifdef NEOPOP_DEBUG + if (filter_bios) + system_debug_message("VECT_FLASHERS: bank %d, block %d (?)", rCodeB(0x30), rCodeB(0x35)); +#endif + //TODO + rCodeB(0x30) = 0; //RA3 = SYS_SUCCESS + break; + + //VECT_ALARMSET + case 0xFF149B: +#ifdef NEOPOP_DEBUG + if (filter_bios) + { + uint32 a = pop32(); + system_debug_message("VECT_ALARMSET: called before %06X", a); + push32(a); + } +#endif + //TODO + rCodeB(0x30) = 0; //RA3 = SYS_SUCCESS + break; + + //? + //case 0xFF1033: break; + + //VECT_ALARMDOWNSET + case 0xFF1487: +#ifdef NEOPOP_DEBUG + if (filter_bios) + { + uint32 a = pop32(); + system_debug_message("VECT_ALARMDOWNSET: called before %06X", a); + push32(a); + } +#endif + //TODO + rCodeB(0x30) = 0; //RA3 = SYS_SUCCESS + break; + + //? + //case 0xFF731F: break; + + //VECT_FLASHPROTECT + case 0xFF70CA: +#ifdef NEOPOP_DEBUG + if (filter_bios) + { + uint32 a = pop32(); + system_debug_message("VECT_FLASHPROTECT: called before %06X", a); + push32(a); + } +#endif + //TODO + rCodeB(0x30) = 0; //RA3 = SYS_SUCCESS + break; + + //VECT_GEMODESET + case 0xFF17C4: +#ifdef NEOPOP_DEBUG + if (filter_bios) + { + uint32 a = pop32(); + system_debug_message("VECT_GEMODESET: called before %06X", a); + push32(a); + } +#endif + //TODO + break; + + //? + //case 0xFF1032: break; + + //VECT_COMINIT + case 0xFF2BBD: +#ifdef NEOPOP_DEBUG + if (filter_comms) + { + uint32 a = pop32(); + system_debug_message("VECT_COMINIT: called before %06X", a); + push32(a); + } +#endif + // Nothing to do. + rCodeB(0x30) = 0; //RA3 = COM_BUF_OK + break; + + //VECT_COMSENDSTART + case 0xFF2C0C: +#ifdef NEOPOP_DEBUG + if (filter_comms) + { + uint32 a = pop32(); + system_debug_message("VECT_COMSENDSTART: called before %06X", a); + push32(a); + } +#endif + // Nothing to do. + break; + + //VECT_COMRECIVESTART + case 0xFF2C44: +#ifdef NEOPOP_DEBUG + if (filter_comms) + { + uint32 a = pop32(); + system_debug_message("VECT_COMRECIVESTART: called before %06X", a); + push32(a); + } +#endif + // Nothing to do. + break; + + //VECT_COMCREATEDATA + case 0xFF2C86: +#ifdef NEOPOP_DEBUG + if (filter_comms) + { + uint32 a = pop32(); + system_debug_message("VECT_COMCREATEDATA: called before %06X", a); + push32(a); + } +#endif + { + //Write the byte + uint8 data = rCodeB(0x35); + system_comms_write(data); + } + + //Restore $PC after BIOS-HLE instruction + pc = pop32(); + + TestIntHDMA(11, 0x18); + + //Always COM_BUF_OK because the write call always succeeds. + rCodeB(0x30) = 0x0; //RA3 = COM_BUF_OK + return; + + //VECT_COMGETDATA + case 0xFF2CB4: +#ifdef NEOPOP_DEBUG + if (filter_comms) + { + uint32 a = pop32(); + system_debug_message("VECT_COMGETDATA: called before %06X", a); + push32(a); + } +#endif + { + uint8 data; + + if (system_comms_read(&data)) + { + rCodeB(0x30) = 0; //COM_BUF_OK + rCodeB(0x35) = data; + + pc = pop32(); + + //Comms. Read interrupt + storeB(0x50, data); + TestIntHDMA(12, 0x19); + + return; + } + else + { + rCodeB(0x30) = 1; //COM_BUF_EMPTY + } + } + + break; + + //VECT_COMONRTS + case 0xFF2D27: +#ifdef NEOPOP_DEBUG + if (filter_comms) + { + uint32 a = pop32(); + system_debug_message("VECT_COMONRTS: called before %06X", a); + push32(a); + } +#endif + storeB(0xB2, 0); + break; + + //VECT_COMOFFRTS + case 0xFF2D33: +#ifdef NEOPOP_DEBUG + if (filter_comms) + { + uint32 a = pop32(); + system_debug_message("VECT_COMOFFRTS: called before %06X", a); + push32(a); + } +#endif + storeB(0xB2, 1); + break; + + //VECT_COMSENDSTATUS + case 0xFF2D3A: +#ifdef NEOPOP_DEBUG + if (filter_comms) + { + uint32 a = pop32(); + system_debug_message("VECT_COMSENDSTATUS: called before %06X", a); + push32(a); + } +#endif + // Nothing to do. + rCodeW(0x30) = 0; //Send Buffer Count, never any pending data! + break; + + //VECT_COMRECIVESTATUS + case 0xFF2D4E: +#ifdef NEOPOP_DEBUG + if (filter_comms) + { + uint32 a = pop32(); + system_debug_message("VECT_COMRECIVESTATUS: called before %06X", a); + push32(a); + } +#endif + + // Receive Buffer Count + rCodeW(0x30) = system_comms_read(NULL); + + break; + + //VECT_COMCREATEBUFDATA + case 0xFF2D6C: +#ifdef NEOPOP_DEBUG + if (filter_comms) + { + uint32 a = pop32(); + system_debug_message("VECT_COMCREATEBUFDATA: called before %06X", a); + push32(a); + } +#endif + pc = pop32(); + + while (rCodeB(0x35) > 0) + { + uint8 data; + data = loadB(rCodeL(0x3C)); + + //Write data from (XHL3++) + system_comms_write(data); + rCodeL(0x3C)++; //Next data + + rCodeB(0x35)--; //RB3 = Count Left + } + + TestIntHDMA(11, 0x18); + return; + + //VECT_COMGETBUFDATA + case 0xFF2D85: +#ifdef NEOPOP_DEBUG + if (filter_comms) + { + uint32 a = pop32(); + system_debug_message("VECT_COMGETBUFDATA: called before %06X", a); + push32(a); + } +#endif + { + pc = pop32(); + + while (rCodeB(0x35) > 0) + { + uint8 data; + + if (system_comms_read(&data)) + { + //Read data into (XHL3++) + storeB(rCodeL(0x3C), data); + rCodeL(0x3C)++; //Next data + rCodeB(0x35)--; //RB3 = Count Left + + //Comms. Read interrupt + storeB(0x50, data); + TestIntHDMA(12, 0x19); + return; + } + else + break; + } + } + + return; + } + + //RET + pc = pop32(); +} +} + +//============================================================================= diff --git a/waterbox/ngp/defs.h b/waterbox/ngp/defs.h new file mode 100644 index 0000000000..4ae5ba1597 --- /dev/null +++ b/waterbox/ngp/defs.h @@ -0,0 +1,62 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +typedef uint64_t uint64; +typedef int8_t int8; +typedef int16_t int16; +typedef int32_t int32; +typedef int64_t int64; + +//#define MDFN_FASTCALL +#define INLINE inline +#define MDFN_COLD +#define NO_INLINE +//#define MDFN_ASSUME_ALIGNED(p, align) ((decltype(p))__builtin_assume_aligned((p), (align))) +#define MDFN_ASSUME_ALIGNED(p, align) (p) +#define trio_snprintf snprintf +#define TRUE true +#define FALSE false +#ifndef __alignas_is_defined +#define alignas(p) +#endif + +#include +#define EXPORT extern "C" ECL_EXPORT +#include + +struct MyFrameInfo: public FrameInfo +{ + int64_t FrontendTime; + int32_t SkipRendering; + int32_t Buttons; +}; + + +struct MDFN_Surface +{ + uint32 *pixels; + int pitch32; +}; + +#define MDFN_printf(...) +#define MDFN_PrintError(...) +#define require assert + +#include "endian.h" + +inline char* strdup(const char* p) +{ + char* ret = (char*)malloc(strlen(p) + 1); + if (ret) + strcpy(ret, p); + return ret; +} diff --git a/waterbox/ngp/dma.cpp b/waterbox/ngp/dma.cpp new file mode 100644 index 0000000000..c9e8277c9f --- /dev/null +++ b/waterbox/ngp/dma.cpp @@ -0,0 +1,379 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + dma.c + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +25 JUL 2002 - neopop_uk +======================================= +- Removed incorrect quick-fix code and added new DMA_update functions + to process the dma values. +- Fixed setting of C and M registers +- Added source copy byte and word mode DMA, seems to be only ones used. + +26 JUL 2002 - neopop_uk +======================================= +- Added more DMA modes - "Kikouseki Unitron (J)" uses counter mode + and 4 byte memory to I/O transfer. +- Added load *from* dma control register. + +30 JUL 2002 - neopop_uk +======================================= +- Made DMA_update more secure in it's ability to detect unknown DMA modes. +- DMA mode and count are printed in decimal, for internal consistancy. + +01 AUG 2002 - neopop_uk +======================================= +- Re-written DMA_update for clarity, and added missing modes, + fixes "Super Real Mahjong" + +//--------------------------------------------------------------------------- +*/ + +#include "neopop.h" +#include "dma.h" +#include "mem.h" +#include "interrupt.h" + +namespace MDFN_IEN_NGP +{ + +//============================================================================= + +static uint32 dmaS[4], dmaD[4]; +static uint16 dmaC[4]; +static uint8 dmaM[4]; + +//============================================================================= + +void reset_dma(void) +{ + memset(dmaS, 0, sizeof(dmaS)); + memset(dmaD, 0, sizeof(dmaD)); + memset(dmaC, 0, sizeof(dmaC)); + memset(dmaM, 0, sizeof(dmaM)); +} + +//============================================================================= + +void DMA_update(int channel) +{ + uint8 mode = (dmaM[channel] & 0x1C) >> 2; + uint8 size = (dmaM[channel] & 0x03); //byte, word or long + + // Correct? + if (dmaC[channel] == 0) + return; + + switch (mode) + { + case 0: // Destination INC mode, I/O to Memory transfer + switch (size) + { + case 0: + storeB(dmaD[channel], loadB(dmaS[channel])); + dmaD[channel] += 1; //Byte increment + break; + + case 1: + storeW(dmaD[channel], loadW(dmaS[channel])); + dmaD[channel] += 2; //Word increment + break; + + case 2: + storeL(dmaD[channel], loadL(dmaS[channel])); + dmaD[channel] += 4; //Long increment + break; + } + break; + + case 1: // Destination DEC mode, I/O to Memory transfer + switch (size) + { + case 0: + storeB(dmaD[channel], loadB(dmaS[channel])); + dmaD[channel] -= 1; //Byte decrement + break; + + case 1: + storeW(dmaD[channel], loadW(dmaS[channel])); + dmaD[channel] -= 2; //Word decrement + break; + + case 2: + storeL(dmaD[channel], loadL(dmaS[channel])); + dmaD[channel] -= 4; //Long decrement + break; + } + break; + + case 2: // Source INC mode, Memory to I/O transfer + switch (size) + { + case 0: + storeB(dmaD[channel], loadB(dmaS[channel])); + dmaS[channel] += 1; //Byte increment + break; + + case 1: + storeW(dmaD[channel], loadW(dmaS[channel])); + dmaS[channel] += 2; //Word increment + break; + + case 2: + storeL(dmaD[channel], loadL(dmaS[channel])); + dmaS[channel] += 4; //Long increment + break; + } + break; + + case 3: // Source DEC mode, Memory to I/O transfer + switch (size) + { + case 0: + storeB(dmaD[channel], loadB(dmaS[channel])); + dmaS[channel] -= 1; //Byte decrement + break; + + case 1: + storeW(dmaD[channel], loadW(dmaS[channel])); + dmaS[channel] -= 2; //Word decrement + break; + + case 2: + storeL(dmaD[channel], loadL(dmaS[channel])); + dmaS[channel] -= 4; //Long decrement + break; + } + break; + + case 4: // Fixed Address Mode + switch (size) + { + case 0: + storeB(dmaD[channel], loadB(dmaS[channel])); + break; + + case 1: + storeW(dmaD[channel], loadW(dmaS[channel])); + break; + + case 2: + storeL(dmaD[channel], loadL(dmaS[channel])); + break; + } + break; + + case 5: // Counter Mode + dmaS[channel]++; + break; + + default: + MDFN_printf("Bad DMA mode %d\nPlease report this to the author.", dmaM[channel]); + return; + } + + // Perform common counter decrement, + // vector clearing, and interrupt handling. + + dmaC[channel]--; + if (dmaC[channel] == 0) + { + interrupt(14 + channel); + storeB(0x7C + channel, 0); + } +} + +//============================================================================= + +void dmaStoreB(uint8 cr, uint8 data) +{ + switch (cr) + { + case 0x22: + dmaM[0] = data; + break; + case 0x26: + dmaM[1] = data; + break; + case 0x2A: + dmaM[2] = data; + break; + case 0x2E: + dmaM[3] = data; + break; + + default: + MDFN_printf("dmaStoreB: Unknown register 0x%02X <- %02X\nPlease report this to the author.\n", cr, data); + break; + } +} + +void dmaStoreW(uint8 cr, uint16 data) +{ + switch (cr) + { + case 0x20: + dmaC[0] = data; + break; + case 0x24: + dmaC[1] = data; + break; + case 0x28: + dmaC[2] = data; + break; + case 0x2C: + dmaC[3] = data; + break; + + default: + MDFN_printf("dmaStoreW: Unknown register 0x%02X <- %04X\nPlease report this to the author.\n", cr, data); + break; + } +} + +void dmaStoreL(uint8 cr, uint32 data) +{ + switch (cr) + { + case 0x00: + dmaS[0] = data; + break; + case 0x04: + dmaS[1] = data; + break; + case 0x08: + dmaS[2] = data; + break; + case 0x0C: + dmaS[3] = data; + break; + + case 0x10: + dmaD[0] = data; + break; + case 0x14: + dmaD[1] = data; + break; + case 0x18: + dmaD[2] = data; + break; + case 0x1C: + dmaD[3] = data; + break; + + default: + MDFN_printf("dmaStoreL: Unknown register 0x%02X <- %08X\nPlease report this to the author.\n", cr, data); + break; + } +} + +//============================================================================= + +uint8 dmaLoadB(uint8 cr) +{ + + switch (cr) + { + case 0x22: + return dmaM[0]; + break; + case 0x26: + return dmaM[1]; + break; + case 0x2A: + return dmaM[2]; + break; + case 0x2E: + return dmaM[3]; + break; + + default: + MDFN_printf("dmaLoadB: Unknown register 0x%02X\nPlease report this to the author.", cr); + return 0; + } +} + +uint16 dmaLoadW(uint8 cr) +{ + switch (cr) + { + case 0x20: + return dmaC[0]; + break; + case 0x24: + return dmaC[1]; + break; + case 0x28: + return dmaC[2]; + break; + case 0x2C: + return dmaC[3]; + break; + + default: + MDFN_printf("dmaLoadW: Unknown register 0x%02X\nPlease report this to the author.", cr); + return 0; + } +} + +uint32 dmaLoadL(uint8 cr) +{ + switch (cr) + { + case 0x00: + return dmaS[0]; + break; + case 0x04: + return dmaS[1]; + break; + case 0x08: + return dmaS[2]; + break; + case 0x0C: + return dmaS[3]; + break; + + case 0x10: + return dmaD[0]; + break; + case 0x14: + return dmaD[1]; + break; + case 0x18: + return dmaD[2]; + break; + case 0x1C: + return dmaD[3]; + break; + + default: + MDFN_printf("dmaLoadL: Unknown register 0x%02X\nPlease report this to the author.", cr); + return 0; + } +} +} diff --git a/waterbox/ngp/dma.h b/waterbox/ngp/dma.h new file mode 100644 index 0000000000..d09951d2cb --- /dev/null +++ b/waterbox/ngp/dma.h @@ -0,0 +1,60 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +/* +//--------------------------------------------------------------------------- +//========================================================================= + + dma.h + +//========================================================================= +//--------------------------------------------------------------------------- + + History of changes: + =================== + +20 JUL 2002 - neopop_uk +======================================= +- Cleaned and tidied up for the source release + +25 JUL 2002 - neopop_uk +======================================= +- Added function prototype for DMA_update + +//--------------------------------------------------------------------------- +*/ + +#ifndef __NEOPOP_DMA__ +#define __NEOPOP_DMA__ +//============================================================================= + +namespace MDFN_IEN_NGP +{ + +void reset_dma(void); + +void DMA_update(int channel); + +uint8 dmaLoadB(uint8 cr); +uint16 dmaLoadW(uint8 cr); +uint32 dmaLoadL(uint8 cr); + +void dmaStoreB(uint8 cr, uint8 data); +void dmaStoreW(uint8 cr, uint16 data); +void dmaStoreL(uint8 cr, uint32 data); + +} + +//============================================================================= +#endif diff --git a/waterbox/ngp/endian.h b/waterbox/ngp/endian.h new file mode 100644 index 0000000000..e78a0c577f --- /dev/null +++ b/waterbox/ngp/endian.h @@ -0,0 +1,494 @@ +/******************************************************************************/ +/* Mednafen - Multi-system Emulator */ +/******************************************************************************/ +/* endian.h: +** Copyright (C) 2006-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_ENDIAN_H +#define __MDFN_ENDIAN_H + +void Endian_A16_Swap(void *src, uint32 nelements); +void Endian_A32_Swap(void *src, uint32 nelements); +void Endian_A64_Swap(void *src, uint32 nelements); + +void Endian_A16_NE_LE(void *src, uint32 nelements); +void Endian_A32_NE_LE(void *src, uint32 nelements); +void Endian_A64_NE_LE(void *src, uint32 nelements); + +void Endian_A16_NE_BE(void *src, uint32 nelements); +void Endian_A32_NE_BE(void *src, uint32 nelements); +void Endian_A64_NE_BE(void *src, uint32 nelements); + +void Endian_V_NE_LE(void* p, size_t len); +void Endian_V_NE_BE(void* p, size_t len); + +// +// +// + +static INLINE uint32 BitsExtract(const uint8* ptr, const size_t bit_offset, const size_t bit_count) +{ + uint32 ret = 0; + + for(size_t x = 0; x < bit_count; x++) + { + size_t co = bit_offset + x; + bool b = (ptr[co >> 3] >> (co & 7)) & 1; + + ret |= (uint64)b << x; + } + + return ret; +} + +static INLINE void BitsIntract(uint8* ptr, const size_t bit_offset, const size_t bit_count, uint32 value) +{ + for(size_t x = 0; x < bit_count; x++) + { + size_t co = bit_offset + x; + bool b = (value >> x) & 1; + uint8 tmp = ptr[co >> 3]; + + tmp &= ~(1 << (co & 7)); + tmp |= b << (co & 7); + + ptr[co >> 3] = tmp; + } +} + +/* + Regarding safety of calling MDFN_*sb on dynamically-allocated memory with new uint8[], see C++ standard 3.7.3.1(i.e. it should be + safe provided the offsets into the memory are aligned/multiples of the MDFN_*sb access type). malloc()'d and calloc()'d + memory should be safe as well. + + Statically-allocated arrays/memory should be unioned with a big POD type or C++11 "alignas"'d. (May need to audit code to ensure + this is being done). +*/ + +static INLINE uint16 MDFN_bswap16(uint16 v) +{ + return (v << 8) | (v >> 8); +} + +static INLINE uint32 MDFN_bswap32(uint32 v) +{ + return (v << 24) | ((v & 0xFF00) << 8) | ((v >> 8) & 0xFF00) | (v >> 24); +} + +static INLINE uint64 MDFN_bswap64(uint64 v) +{ + return (v << 56) | (v >> 56) | ((v & 0xFF00) << 40) | ((v >> 40) & 0xFF00) | ((uint64)MDFN_bswap32(v >> 16) << 16); +} + +#ifdef LSB_FIRST + #define MDFN_ENDIANH_IS_BIGENDIAN 0 +#else + #define MDFN_ENDIANH_IS_BIGENDIAN 1 +#endif + +// +// X endian. +// +template +static INLINE T MDFN_deXsb(const void* ptr) +{ + T tmp; + + memcpy(&tmp, MDFN_ASSUME_ALIGNED(ptr, (aligned ? sizeof(T) : 1)), sizeof(T)); + + if(isbigendian != -1 && isbigendian != MDFN_ENDIANH_IS_BIGENDIAN) + { + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Gummy penguins."); + + if(sizeof(T) == 8) + return MDFN_bswap64(tmp); + else if(sizeof(T) == 4) + return MDFN_bswap32(tmp); + else if(sizeof(T) == 2) + return MDFN_bswap16(tmp); + } + + return tmp; +} + +// +// Native endian. +// +template +static INLINE T MDFN_densb(const void* ptr) +{ + return MDFN_deXsb<-1, T, aligned>(ptr); +} + +// +// Little endian. +// +template +static INLINE T MDFN_delsb(const void* ptr) +{ + return MDFN_deXsb<0, T, aligned>(ptr); +} + +template +static INLINE uint16 MDFN_de16lsb(const void* ptr) +{ + return MDFN_delsb(ptr); +} + +static INLINE uint32 MDFN_de24lsb(const void* ptr) +{ + const uint8* ptr_u8 = (const uint8*)ptr; + + return (ptr_u8[0] << 0) | (ptr_u8[1] << 8) | (ptr_u8[2] << 16); +} + +template +static INLINE uint32 MDFN_de32lsb(const void* ptr) +{ + return MDFN_delsb(ptr); +} + +template +static INLINE uint64 MDFN_de64lsb(const void* ptr) +{ + return MDFN_delsb(ptr); +} + +// +// Big endian. +// +template +static INLINE T MDFN_demsb(const void* ptr) +{ + return MDFN_deXsb<1, T, aligned>(ptr); +} + +template +static INLINE uint16 MDFN_de16msb(const void* ptr) +{ + return MDFN_demsb(ptr); +} + +static INLINE uint32 MDFN_de24msb(const void* ptr) +{ + const uint8* ptr_u8 = (const uint8*)ptr; + + return (ptr_u8[0] << 16) | (ptr_u8[1] << 8) | (ptr_u8[2] << 0); +} + +template +static INLINE uint32 MDFN_de32msb(const void* ptr) +{ + return MDFN_demsb(ptr); +} + +template +static INLINE uint64 MDFN_de64msb(const void* ptr) +{ + return MDFN_demsb(ptr); +} + +// +// +// +// +// +// +// +// + +// +// X endian. +// +template +static INLINE void MDFN_enXsb(void* ptr, T value) +{ + T tmp = value; + + if(isbigendian != -1 && isbigendian != MDFN_ENDIANH_IS_BIGENDIAN) + { + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Gummy penguins."); + + if(sizeof(T) == 8) + tmp = MDFN_bswap64(value); + else if(sizeof(T) == 4) + tmp = MDFN_bswap32(value); + else if(sizeof(T) == 2) + tmp = MDFN_bswap16(value); + } + + memcpy(MDFN_ASSUME_ALIGNED(ptr, (aligned ? sizeof(T) : 1)), &tmp, sizeof(T)); +} + +// +// Native endian. +// +template +static INLINE void MDFN_ennsb(void* ptr, T value) +{ + MDFN_enXsb<-1, T, aligned>(ptr, value); +} + +// +// Little endian. +// +template +static INLINE void MDFN_enlsb(void* ptr, T value) +{ + MDFN_enXsb<0, T, aligned>(ptr, value); +} + +template +static INLINE void MDFN_en16lsb(void* ptr, uint16 value) +{ + MDFN_enlsb(ptr, value); +} + +static INLINE void MDFN_en24lsb(void* ptr, uint32 value) +{ + uint8* ptr_u8 = (uint8*)ptr; + + ptr_u8[0] = value >> 0; + ptr_u8[1] = value >> 8; + ptr_u8[2] = value >> 16; +} + +template +static INLINE void MDFN_en32lsb(void* ptr, uint32 value) +{ + MDFN_enlsb(ptr, value); +} + +template +static INLINE void MDFN_en64lsb(void* ptr, uint64 value) +{ + MDFN_enlsb(ptr, value); +} + + +// +// Big endian. +// +template +static INLINE void MDFN_enmsb(void* ptr, T value) +{ + MDFN_enXsb<1, T, aligned>(ptr, value); +} + +template +static INLINE void MDFN_en16msb(void* ptr, uint16 value) +{ + MDFN_enmsb(ptr, value); +} + +static INLINE void MDFN_en24msb(void* ptr, uint32 value) +{ + uint8* ptr_u8 = (uint8*)ptr; + + ptr_u8[0] = value >> 16; + ptr_u8[1] = value >> 8; + ptr_u8[2] = value >> 0; +} + +template +static INLINE void MDFN_en32msb(void* ptr, uint32 value) +{ + MDFN_enmsb(ptr, value); +} + +template +static INLINE void MDFN_en64msb(void* ptr, uint64 value) +{ + MDFN_enmsb(ptr, value); +} + + +// +// +// +// +// +// + +template +static INLINE uint8* ne16_ptr_be(BT* const base, const size_t byte_offset) +{ +#ifdef MSB_FIRST + return (uint8*)base + (byte_offset &~ (sizeof(T) - 1)); +#else + return (uint8*)base + (((byte_offset &~ (sizeof(T) - 1)) ^ (2 - std::min(2, sizeof(T))))); +#endif +} + +template +static INLINE void ne16_wbo_be(uint16* const base, const size_t byte_offset, const T value) +{ + uint8* const ptr = ne16_ptr_be(base, byte_offset); + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size"); + + if(sizeof(T) == 4) + { + uint16* const ptr16 = (uint16*)ptr; + + ptr16[0] = value >> 16; + ptr16[1] = value; + } + else + *(T*)ptr = value; +} + +template +static INLINE T ne16_rbo_be(const uint16* const base, const size_t byte_offset) +{ + uint8* const ptr = ne16_ptr_be(base, byte_offset); + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size"); + + if(sizeof(T) == 4) + { + uint16* const ptr16 = (uint16*)ptr; + T tmp; + + tmp = ptr16[0] << 16; + tmp |= ptr16[1]; + + return tmp; + } + else + return *(T*)ptr; +} + +template +static INLINE void ne16_rwbo_be(uint16* const base, const size_t byte_offset, T* value) +{ + if(IsWrite) + ne16_wbo_be(base, byte_offset, *value); + else + *value = ne16_rbo_be(base, byte_offset); +} + +// +// +// + +template +static INLINE uint8* ne16_ptr_le(BT* const base, const size_t byte_offset) +{ +#ifdef LSB_FIRST + return (uint8*)base + (byte_offset &~ (sizeof(T) - 1)); +#else + return (uint8*)base + (((byte_offset &~ (sizeof(T) - 1)) ^ (2 - std::min(2, sizeof(T))))); +#endif +} + +template +static INLINE void ne16_wbo_le(uint16* const base, const size_t byte_offset, const T value) +{ + uint8* const ptr = ne16_ptr_le(base, byte_offset); + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size"); + + if(sizeof(T) == 4) + { + uint16* const ptr16 = (uint16*)ptr; + + ptr16[0] = value; + ptr16[1] = value >> 16; + } + else + *(T*)ptr = value; +} + +template +static INLINE T ne16_rbo_le(const uint16* const base, const size_t byte_offset) +{ + uint8* const ptr = ne16_ptr_le(base, byte_offset); + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size"); + + if(sizeof(T) == 4) + { + uint16* const ptr16 = (uint16*)ptr; + T tmp; + + tmp = ptr16[0]; + tmp |= ptr16[1] << 16; + + return tmp; + } + else + return *(T*)ptr; +} + + +template +static INLINE void ne16_rwbo_le(uint16* const base, const size_t byte_offset, T* value) +{ + if(IsWrite) + ne16_wbo_le(base, byte_offset, *value); + else + *value = ne16_rbo_le(base, byte_offset); +} + +// +// +// +template +static INLINE uint8* ne64_ptr_be(uint64* const base, const size_t byte_offset) +{ +#ifdef MSB_FIRST + return (uint8*)base + (byte_offset &~ (sizeof(T) - 1)); +#else + return (uint8*)base + (((byte_offset &~ (sizeof(T) - 1)) ^ (8 - sizeof(T)))); +#endif +} + +template +static INLINE void ne64_wbo_be(uint64* const base, const size_t byte_offset, const T value) +{ + uint8* const ptr = ne64_ptr_be(base, byte_offset); + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Unsupported type size"); + + memcpy(MDFN_ASSUME_ALIGNED(ptr, sizeof(T)), &value, sizeof(T)); +} + +template +static INLINE T ne64_rbo_be(uint64* const base, const size_t byte_offset) +{ + uint8* const ptr = ne64_ptr_be(base, byte_offset); + T ret; + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size"); + + memcpy(&ret, MDFN_ASSUME_ALIGNED(ptr, sizeof(T)), sizeof(T)); + + return ret; +} + +template +static INLINE void ne64_rwbo_be(uint64* const base, const size_t byte_offset, T* value) +{ + if(IsWrite) + ne64_wbo_be(base, byte_offset, *value); + else + *value = ne64_rbo_be(base, byte_offset); +} + +#endif diff --git a/waterbox/ngp/flash.cpp b/waterbox/ngp/flash.cpp new file mode 100644 index 0000000000..7f03d788ca --- /dev/null +++ b/waterbox/ngp/flash.cpp @@ -0,0 +1,323 @@ +/* + FIXME: + File format is not endian-safe. + + Still possible for corrupt/malicious save game data to cause a crash, from blindly reading past the end of the buffer. +*/ + +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#include "neopop.h" +#include "flash.h" +#include "mem.h" + +#include + +namespace MDFN_IEN_NGP +{ + +//----------------------------------------------------------------------------- +// Local Definitions +//----------------------------------------------------------------------------- +//This value is used to verify flash data - it is set to the +//version number that the flash description was modified for. + +#define FLASH_VALID_ID 0x0053 + +//Number of different flash blocks, this should be enough. + +#define FLASH_MAX_BLOCKS 256 + +typedef struct +{ + //Flash Id + uint16 valid_flash_id; // = FLASH_VALID_ID + + uint16 block_count; //Number of flash data blocks + + uint32 total_file_length; // header + block[0 - block_count] + +} FlashFileHeader; + +typedef struct +{ + uint32 start_address; // 24 bit address + uint16 data_length; // length of following data + + //Followed by data_length bytes of the actual data. + +} FlashFileBlockHeader; + +//----------------------------------------------------------------------------- +// Local Data +//----------------------------------------------------------------------------- +static FlashFileBlockHeader blocks[FLASH_MAX_BLOCKS]; +static uint16 block_count; + +//============================================================================= + +//----------------------------------------------------------------------------- +// optimise_blocks() +//----------------------------------------------------------------------------- +static void optimise_blocks(void) +{ + int i, j; + + // Bubble Sort by address + for (i = 0; i < block_count - 1; i++) + { + for (j = i + 1; j < block_count; j++) + { + //Swap? + if (blocks[i].start_address > blocks[j].start_address) + { + uint32 temp32; + uint16 temp16; + + temp32 = blocks[i].start_address; + blocks[i].start_address = blocks[j].start_address; + blocks[j].start_address = temp32; + + temp16 = blocks[i].data_length; + blocks[i].data_length = blocks[j].data_length; + blocks[j].data_length = temp16; + } + } + } + + //Join contiguous blocks + //Only advance 'i' if required, this will allow subsequent + //blocks to be compared to the newly expanded block. + for (i = 0; i < block_count - 1; /**/) + { + //Next block lies within (or borders) this one? + if (blocks[i + 1].start_address <= + (blocks[i].start_address + blocks[i].data_length)) + { + //Extend the first block + blocks[i].data_length = + (uint16)((blocks[i + 1].start_address + blocks[i + 1].data_length) - + blocks[i].start_address); + + //Remove the next one. + for (j = i + 2; j < block_count; j++) + { + blocks[j - 1].start_address = blocks[j].start_address; + blocks[j - 1].data_length = blocks[j].data_length; + } + block_count--; + } + else + { + i++; // Try the next block + } + } +} + +static bool do_flash_read(const uint8 *flashdata) +{ + FlashFileHeader header; + const uint8 *fileptr; + uint16 i; + uint32 j; + bool PREV_memory_unlock_flash_write = memory_unlock_flash_write; // kludge, hack, FIXME + + memcpy(&header, flashdata, sizeof(header)); + + if (header.block_count > FLASH_MAX_BLOCKS) + { + return false; + //throw MDFN_Error(0, _("FLASH header block_count(%u) > FLASH_MAX_BLOCKS!"), header.block_count); + } + + //Read header + block_count = header.block_count; + fileptr = flashdata + sizeof(FlashFileHeader); + + //Copy blocks + memory_unlock_flash_write = TRUE; + for (i = 0; i < block_count; i++) + { + FlashFileBlockHeader *current = (FlashFileBlockHeader *)fileptr; + fileptr += sizeof(FlashFileBlockHeader); + + blocks[i].start_address = current->start_address; + blocks[i].data_length = current->data_length; + + //Copy data + for (j = 0; j < blocks[i].data_length; j++) + { + storeB(blocks[i].start_address + j, *fileptr); + fileptr++; + } + } + memory_unlock_flash_write = PREV_memory_unlock_flash_write; + + optimise_blocks(); //Optimise + +#if 0 + //Output block list... + for (i = 0; i < block_count; i++) + printf("flash block: %06X, %d bytes\n", + blocks[i].start_address, blocks[i].data_length); +#endif + return true; +} + +bool FLASH_LoadNV(const uint8* data, uint32 size) +{ + FlashFileHeader header; + std::vector flashdata; + + //Initialise the internal flash configuration + block_count = 0; + + //Read flash buffer header + if (size < sizeof(FlashFileHeader)) + return false; + memcpy((uint8 *)&header, data, sizeof(FlashFileHeader)); + + //Verify correct flash id + if (header.valid_flash_id != FLASH_VALID_ID) + { + return false; + //throw MDFN_Error(0, _("FLASH header ID is bad!")); + } + + if (header.total_file_length < sizeof(FlashFileHeader) || header.total_file_length > 16384 * 1024) + { + return false; + //throw MDFN_Error(0, _("FLASH header total_file_length is bad!")); + } + + if (size < header.total_file_length) + return false; + + flashdata.resize(header.total_file_length); + memcpy(&flashdata[0], data, flashdata.size()); + + if (!do_flash_read(&flashdata[0])) + return false; + + return true; +} + +//----------------------------------------------------------------------------- +// flash_write() +//----------------------------------------------------------------------------- +void flash_write(uint32 start_address, uint16 length) +{ + uint16 i; + + //Now we need a new flash command before the next flash write will work! + memory_flash_command = FALSE; + + // system_debug_message("flash write: %06X, %d bytes", start_address, length); + + for (i = 0; i < block_count; i++) + { + //Got this block with enough bytes to cover it + if (blocks[i].start_address == start_address && + blocks[i].data_length >= length) + { + return; //Nothing to do, block already registered. + } + + //Got this block with but it's length is too short + if (blocks[i].start_address == start_address && + blocks[i].data_length < length) + { + blocks[i].data_length = length; //Enlarge block updating. + return; + } + } + + if (block_count >= FLASH_MAX_BLOCKS) + { + MDFN_PrintError(_("[FLASH] Block list overflow!")); + return; + } + else + { + // New block needs to be added + blocks[block_count].start_address = start_address; + blocks[block_count].data_length = length; + block_count++; + } +} + +static void make_flash_commit(std::vector &flashdata) +{ + FlashFileHeader header; + uint8 *fileptr; + + flashdata.clear(); + + //No flash data? + if (block_count == 0) + return; + + //Optimise before writing + optimise_blocks(); + + //Build a header; + header.valid_flash_id = FLASH_VALID_ID; + header.block_count = block_count; + header.total_file_length = sizeof(FlashFileHeader); + for (int i = 0; i < block_count; i++) + { + header.total_file_length += sizeof(FlashFileBlockHeader); + header.total_file_length += blocks[i].data_length; + } + + //Write the flash data + flashdata.resize(header.total_file_length); + + //Copy header + memcpy(&flashdata[0], &header, sizeof(FlashFileHeader)); + fileptr = &flashdata[0] + sizeof(FlashFileHeader); + + //Copy blocks + for (int i = 0; i < block_count; i++) + { + memcpy(fileptr, &blocks[i], sizeof(FlashFileBlockHeader)); + fileptr += sizeof(FlashFileBlockHeader); + + //Copy data + for (uint32 j = 0; j < blocks[i].data_length; j++) + { + *fileptr = loadB(blocks[i].start_address + j); + fileptr++; + } + } +} + +bool FLASH_IsModified() +{ + return block_count > 0; +} + +void FLASH_SaveNV(void (*callback)(const uint8* data, uint32 size)) +{ + std::vector flashdata; + + make_flash_commit(flashdata); + + if (flashdata.size() > 0) + { + callback(&flashdata[0], flashdata.size()); + } +} +} diff --git a/waterbox/ngp/flash.h b/waterbox/ngp/flash.h new file mode 100644 index 0000000000..c463c8df3e --- /dev/null +++ b/waterbox/ngp/flash.h @@ -0,0 +1,31 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#ifndef __NEOPOP_FLASH__ +#define __NEOPOP_FLASH__ +//============================================================================= + +namespace MDFN_IEN_NGP +{ + +//Marks flash blocks for saving. +void flash_write(uint32 start_address, uint16 length); + +bool FLASH_LoadNV(const uint8* data, uint32 size); +void FLASH_SaveNV(void (*callback)(const uint8* data, uint32 size)); +bool FLASH_IsModified(); +} + +//============================================================================= +#endif diff --git a/waterbox/ngp/gfx.cpp b/waterbox/ngp/gfx.cpp new file mode 100644 index 0000000000..b9aece94b8 --- /dev/null +++ b/waterbox/ngp/gfx.cpp @@ -0,0 +1,474 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#include "neopop.h" +#include "mem.h" +#include "gfx.h" +#include "interrupt.h" +#include "dma.h" + +namespace MDFN_IEN_NGP +{ + +NGPGFX_CLASS::NGPGFX_CLASS(void) +{ + layer_enable_setting = 1 | 2 | 4; + + for (int x = 0; x < 4096; x++) + { + int r = (x & 0xF) * 17; + int g = ((x >> 4) & 0xF) * 17; + int b = ((x >> 8) & 0xF) * 17; + + ColorMap[x] = b | g << 8 | r << 16 | 0xff000000; + } +} + +NGPGFX_CLASS::~NGPGFX_CLASS() +{ +} + +void NGPGFX_CLASS::reset(void) +{ + memset(SPPLT, 0x7, sizeof(SPPLT)); + memset(SCRP1PLT, 0x7, sizeof(SCRP1PLT)); + memset(SCRP2PLT, 0x7, sizeof(SCRP2PLT)); + + raster_line = 0; + S1SO_H = 0; + S1SO_V = 0; + S2SO_H = 0; + S2SO_V = 0; + WBA_H = 0; + WBA_V = 0; + + WSI_H = 0xFF; + WSI_V = 0xFF; + + C_OVR = 0; + BLNK = 0; + + PO_H = 0; + PO_V = 0; + P_F = 0; + + BG_COL = 0x7; + CONTROL_2D = 0; + CONTROL_INT = 0; + SCREEN_PERIOD = 0xC6; + K2GE_MODE = 0; + + delayed_settings(); +} + +void NGPGFX_CLASS::power(void) +{ + reset(); + + memset(ScrollVRAM, 0, sizeof(ScrollVRAM)); + memset(CharacterRAM, 0, sizeof(CharacterRAM)); + memset(SpriteVRAM, 0, sizeof(SpriteVRAM)); + memset(SpriteVRAMColor, 0, sizeof(SpriteVRAMColor)); + memset(ColorPaletteRAM, 0, sizeof(ColorPaletteRAM)); +} + +void NGPGFX_CLASS::delayed_settings(void) +{ + //Window dimensions + winx = WBA_H; + winy = WBA_V; + winw = WSI_H; + winh = WSI_V; + + //Scroll Planes (Confirmed delayed) + scroll1x = S1SO_H; + scroll1y = S1SO_V; + + scroll2x = S2SO_H; + scroll2y = S2SO_V; + + //Sprite offset (Confirmed delayed) + scrollsprx = PO_H; + scrollspry = PO_V; + + //Plane Priority (Confirmed delayed) + planeSwap = P_F & 0x80; + + //Background colour register (Confirmed delayed) + bgc = BG_COL; + + //2D Control register (Confirmed delayed) + oowc = CONTROL_2D & 7; + negative = CONTROL_2D & 0x80; +} + +bool NGPGFX_CLASS::hint(void) +{ + //H_Int / Delayed settings + if ((raster_line < SCREEN_HEIGHT - 1 || raster_line == SCREEN_PERIOD)) + { + delayed_settings(); //Get delayed settings + + //Allowed? + if (CONTROL_INT & 0x40) + return (1); + } + return (0); +} + +bool NGPGFX_CLASS::draw(MDFN_Surface *surface, bool skip) +{ + bool ret = 0; + + //Draw the scanline + if (raster_line < SCREEN_HEIGHT && !skip) + { + if (!K2GE_MODE) + draw_scanline_colour(layer_enable_setting, raster_line); + else + draw_scanline_mono(layer_enable_setting, raster_line); + + uint32 *dest = surface->pixels + surface->pitch32 * raster_line; + for (int x = 0; x < SCREEN_WIDTH; x++) + dest[x] = ColorMap[cfb_scanline[x] & 4095]; + } + raster_line++; + + //V_Int? + if (raster_line == SCREEN_HEIGHT) + { + BLNK = 1; + ret = 1; + + if (CONTROL_INT & 0x80) // (statusIFF() <= 4 + TestIntHDMA(5, 0x0B); + } + + //End of V_Int + if (raster_line == SCREEN_PERIOD + 1) //Last scanline + 1 + { + raster_line = 0; + C_OVR = 0; + BLNK = 0; + } + + return (ret); +} + +void NGPGFX_CLASS::SetLayerEnableMask(uint64 mask) +{ + layer_enable_setting = mask; +} + +//extern uint32 ngpc_soundTS; +void NGPGFX_CLASS::write8(uint32 address, uint8 data) +{ + //if(address >= 0x8032 && address <= 0x8035) + // printf("%08x %02x %d\n", address, data, ngpc_soundTS); + + if (address >= 0x9000 && address <= 0x9fff) + ScrollVRAM[address - 0x9000] = data; + else if (address >= 0xa000 && address <= 0xbfff) + CharacterRAM[address - 0xa000] = data; + else if (address >= 0x8800 && address <= 0x88ff) + SpriteVRAM[address - 0x8800] = data; + else if (address >= 0x8c00 && address <= 0x8c3f) + SpriteVRAMColor[address - 0x8c00] = data & 0x0f; + else if (address >= 0x8200 && address <= 0x83ff) + ColorPaletteRAM[address - 0x8200] = data; + else + switch (address) + { + //default: printf("HuhW: %08x\n", address); break; + + case 0x8000: + CONTROL_INT = data & 0xC0; + break; + case 0x8002: + WBA_H = data; + break; + case 0x8003: + WBA_V = data; + break; + case 0x8004: + WSI_H = data; + break; + case 0x8005: + WSI_V = data; + break; + case 0x8006: + SCREEN_PERIOD = data; + break; + case 0x8012: + CONTROL_2D = data & 0x87; + break; + case 0x8020: + PO_H = data; + break; + case 0x8021: + PO_V = data; + break; + case 0x8030: + P_F = data & 0x80; + break; + case 0x8032: + S1SO_H = data; + break; + case 0x8033: + S1SO_V = data; + break; + case 0x8034: + S2SO_H = data; + break; + case 0x8035: + S2SO_V = data; + break; + + case 0x8101: + SPPLT[0] = data & 0x7; + break; + case 0x8102: + SPPLT[1] = data & 0x7; + break; + case 0x8103: + SPPLT[2] = data & 0x7; + break; + + case 0x8105: + SPPLT[3] = data & 0x7; + break; + case 0x8106: + SPPLT[4] = data & 0x7; + break; + case 0x8107: + SPPLT[5] = data & 0x7; + break; + + case 0x8109: + SCRP1PLT[0] = data & 0x7; + break; + case 0x810a: + SCRP1PLT[1] = data & 0x7; + break; + case 0x810b: + SCRP1PLT[2] = data & 0x7; + break; + + case 0x810d: + SCRP1PLT[3] = data & 0x7; + break; + case 0x810e: + SCRP1PLT[4] = data & 0x7; + break; + case 0x810f: + SCRP1PLT[5] = data & 0x7; + break; + + case 0x8111: + SCRP2PLT[0] = data & 0x7; + break; + case 0x8112: + SCRP2PLT[1] = data & 0x7; + break; + case 0x8113: + SCRP2PLT[2] = data & 0x7; + break; + + case 0x8115: + SCRP2PLT[3] = data & 0x7; + break; + case 0x8116: + SCRP2PLT[4] = data & 0x7; + break; + case 0x8117: + SCRP2PLT[5] = data & 0x7; + break; + + case 0x8118: + BG_COL = data & 0xC7; + break; + + case 0x87e0: + if (data == 0x52) + { + puts("GEreset"); + reset(); + } + break; + case 0x87e2: + K2GE_MODE = data & 0x80; + break; + } +} + +void NGPGFX_CLASS::write16(uint32 address, uint16 data) +{ + write8(address, data & 0xFF); + write8(address + 1, data >> 8); +} + +#if 0 +namespace TLCS900H +{ + extern uint32 pc; +}; +#endif + +uint8 NGPGFX_CLASS::read8(uint32 address) +{ +#if 0 + if(address >= 0x8200 && address <= 0xbfff) + { + printf("[GFX] Read8: %08x -- %08x\n", address, TLCS900H::pc); + if(pc == 0x0028dd3d) //21) + { + TLCS900H::pc = 0x28DD15; + for(int x = 0; x < 256; x++) + puts(TLCS900h_disassemble()); + + abort(); + } + } +#endif + + if (address >= 0x9000 && address <= 0x9fff) + return (ScrollVRAM[address - 0x9000]); + else if (address >= 0xa000 && address <= 0xbfff) + return (CharacterRAM[address - 0xa000]); + else if (address >= 0x8800 && address <= 0x88ff) + return (SpriteVRAM[address - 0x8800]); + else if (address >= 0x8c00 && address <= 0x8c3f) + return (SpriteVRAMColor[address - 0x8c00]); + else if (address >= 0x8200 && address <= 0x83ff) + return (ColorPaletteRAM[address - 0x8200]); + else + switch (address) + { + //default: printf("Huh: %08x\n", address); break; + case 0x8000: + return (CONTROL_INT); + case 0x8002: + return (WBA_H); + case 0x8003: + return (WBA_V); + case 0x8004: + return (WSI_H); + case 0x8005: + return (WSI_V); + case 0x8006: + return (SCREEN_PERIOD); + + case 0x8008: + return ((uint8)((abs(TIMER_HINT_RATE - (int)timer_hint)) >> 2)); //RAS.H read (Simulated horizontal raster position) + case 0x8009: + return (raster_line); + case 0x8010: + return ((C_OVR ? 0x80 : 0x00) | (BLNK ? 0x40 : 0x00)); + case 0x8012: + return (CONTROL_2D); + case 0x8020: + return (PO_H); + case 0x8021: + return (PO_V); + case 0x8030: + return (P_F); + case 0x8032: + return (S1SO_H); + case 0x8033: + return (S1SO_V); + case 0x8034: + return (S2SO_H); + case 0x8035: + return (S2SO_V); + + case 0x8101: + return (SPPLT[0]); + break; + case 0x8102: + return (SPPLT[1]); + break; + case 0x8103: + return (SPPLT[2]); + break; + + case 0x8105: + return (SPPLT[3]); + break; + case 0x8106: + return (SPPLT[4]); + break; + case 0x8107: + return (SPPLT[5]); + break; + + case 0x8108: + return (SCRP1PLT[0]); + break; + case 0x8109: + return (SCRP1PLT[1]); + break; + case 0x810a: + return (SCRP1PLT[2]); + break; + + case 0x810d: + return (SCRP1PLT[3]); + break; + case 0x810e: + return (SCRP1PLT[4]); + break; + case 0x810f: + return (SCRP1PLT[5]); + break; + + case 0x8111: + return (SCRP2PLT[0]); + break; + case 0x8112: + return (SCRP2PLT[1]); + break; + case 0x8113: + return (SCRP2PLT[2]); + break; + + case 0x8115: + return (SCRP2PLT[3]); + break; + case 0x8116: + return (SCRP2PLT[4]); + break; + case 0x8117: + return (SCRP2PLT[5]); + break; + + case 0x8118: + return (BG_COL); + + case 0x87e2: + return (K2GE_MODE); + } + + return (0); +} + +uint16 NGPGFX_CLASS::read16(uint32 address) +{ + uint16 ret; + + ret = read8(address); + ret |= read8(address + 1) << 8; + + return (ret); +} +} diff --git a/waterbox/ngp/gfx.h b/waterbox/ngp/gfx.h new file mode 100644 index 0000000000..aac7a9deab --- /dev/null +++ b/waterbox/ngp/gfx.h @@ -0,0 +1,105 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#ifndef __NEOPOP_GFX__ +#define __NEOPOP_GFX__ +//============================================================================= + +namespace MDFN_IEN_NGP +{ + +#define ZDEPTH_BACK_SPRITE 2 +#define ZDEPTH_BACKGROUND_SCROLL 3 +#define ZDEPTH_MIDDLE_SPRITE 4 +#define ZDEPTH_FOREGROUND_SCROLL 5 +#define ZDEPTH_FRONT_SPRITE 6 + +class NGPGFX_CLASS +{ + public: + NGPGFX_CLASS() + MDFN_COLD; + ~NGPGFX_CLASS() MDFN_COLD; + + void write8(uint32 address, uint8 data); + void write16(uint32 address, uint16 data); + + uint8 read8(uint32 address); + uint16 read16(uint32 address); + + void SetLayerEnableMask(uint64 mask); + + bool draw(MDFN_Surface *surface, bool skip); + bool hint(void); + + void power(void); + + private: + // TODO: Alignment for faster memset + uint8 zbuffer[256]; // __attribute__ ((aligned (8))); //Line z-buffer + uint16 cfb_scanline[256]; // __attribute__ ((aligned (8))); + + uint8 winx, winw; + uint8 winy, winh; + uint8 scroll1x, scroll1y; + uint8 scroll2x, scroll2y; + uint8 scrollsprx, scrollspry; + uint8 planeSwap; + uint8 bgc, oowc, negative; + + void reset(void); + void delayed_settings(void); + + void draw_scanline_colour(int, int); + void drawColourPattern(uint8 screenx, uint16 tile, uint8 tiley, uint16 mirror, + uint16 *palette_ptr, uint8 pal, uint8 depth); + void draw_colour_scroll1(uint8 depth, int ngpc_scanline); + void draw_colour_scroll2(uint8 depth, int ngpc_scanline); + + void draw_scanline_mono(int, int); + void MonoPlot(uint8 x, uint8 *palette_ptr, uint16 pal_hi, uint8 index, uint8 depth); + void drawMonoPattern(uint8 screenx, uint16 tile, uint8 tiley, uint16 mirror, + uint8 *palette_ptr, uint16 pal, uint8 depth); + void draw_mono_scroll1(uint8 depth, int ngpc_scanline); + void draw_mono_scroll2(uint8 depth, int ngpc_scanline); + + uint8 ScrollVRAM[4096]; // 9000-9fff + uint8 CharacterRAM[8192]; // a000-bfff + uint8 SpriteVRAM[256]; // 8800-88ff + uint8 SpriteVRAMColor[0x40]; // 8C00-8C3F + uint8 ColorPaletteRAM[0x200]; // 8200-83ff + + uint8 SPPLT[6]; + uint8 SCRP1PLT[6]; + uint8 SCRP2PLT[6]; + + uint8 raster_line; + uint8 S1SO_H, S1SO_V, S2SO_H, S2SO_V; + uint8 WBA_H, WBA_V, WSI_H, WSI_V; + bool C_OVR, BLNK; + uint8 PO_H, PO_V; + uint8 P_F; + uint8 BG_COL; + uint8 CONTROL_2D; + uint8 CONTROL_INT; + uint8 SCREEN_PERIOD; + uint8 K2GE_MODE; + + uint32 ColorMap[4096]; + + int layer_enable_setting; +}; +} + +#endif diff --git a/waterbox/ngp/gfx_scanline_colour.cpp b/waterbox/ngp/gfx_scanline_colour.cpp new file mode 100644 index 0000000000..272f1491c5 --- /dev/null +++ b/waterbox/ngp/gfx_scanline_colour.cpp @@ -0,0 +1,270 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#include "neopop.h" +#include "mem.h" +#include "gfx.h" + +//============================================================================= + +namespace MDFN_IEN_NGP +{ + +static const unsigned char mirrored[] = { + 0x00, 0x40, 0x80, 0xc0, 0x10, 0x50, 0x90, 0xd0, + 0x20, 0x60, 0xa0, 0xe0, 0x30, 0x70, 0xb0, 0xf0, + 0x04, 0x44, 0x84, 0xc4, 0x14, 0x54, 0x94, 0xd4, + 0x24, 0x64, 0xa4, 0xe4, 0x34, 0x74, 0xb4, 0xf4, + 0x08, 0x48, 0x88, 0xc8, 0x18, 0x58, 0x98, 0xd8, + 0x28, 0x68, 0xa8, 0xe8, 0x38, 0x78, 0xb8, 0xf8, + 0x0c, 0x4c, 0x8c, 0xcc, 0x1c, 0x5c, 0x9c, 0xdc, + 0x2c, 0x6c, 0xac, 0xec, 0x3c, 0x7c, 0xbc, 0xfc, + 0x01, 0x41, 0x81, 0xc1, 0x11, 0x51, 0x91, 0xd1, + 0x21, 0x61, 0xa1, 0xe1, 0x31, 0x71, 0xb1, 0xf1, + 0x05, 0x45, 0x85, 0xc5, 0x15, 0x55, 0x95, 0xd5, + 0x25, 0x65, 0xa5, 0xe5, 0x35, 0x75, 0xb5, 0xf5, + 0x09, 0x49, 0x89, 0xc9, 0x19, 0x59, 0x99, 0xd9, + 0x29, 0x69, 0xa9, 0xe9, 0x39, 0x79, 0xb9, 0xf9, + 0x0d, 0x4d, 0x8d, 0xcd, 0x1d, 0x5d, 0x9d, 0xdd, + 0x2d, 0x6d, 0xad, 0xed, 0x3d, 0x7d, 0xbd, 0xfd, + 0x02, 0x42, 0x82, 0xc2, 0x12, 0x52, 0x92, 0xd2, + 0x22, 0x62, 0xa2, 0xe2, 0x32, 0x72, 0xb2, 0xf2, + 0x06, 0x46, 0x86, 0xc6, 0x16, 0x56, 0x96, 0xd6, + 0x26, 0x66, 0xa6, 0xe6, 0x36, 0x76, 0xb6, 0xf6, + 0x0a, 0x4a, 0x8a, 0xca, 0x1a, 0x5a, 0x9a, 0xda, + 0x2a, 0x6a, 0xaa, 0xea, 0x3a, 0x7a, 0xba, 0xfa, + 0x0e, 0x4e, 0x8e, 0xce, 0x1e, 0x5e, 0x9e, 0xde, + 0x2e, 0x6e, 0xae, 0xee, 0x3e, 0x7e, 0xbe, 0xfe, + 0x03, 0x43, 0x83, 0xc3, 0x13, 0x53, 0x93, 0xd3, + 0x23, 0x63, 0xa3, 0xe3, 0x33, 0x73, 0xb3, 0xf3, + 0x07, 0x47, 0x87, 0xc7, 0x17, 0x57, 0x97, 0xd7, + 0x27, 0x67, 0xa7, 0xe7, 0x37, 0x77, 0xb7, 0xf7, + 0x0b, 0x4b, 0x8b, 0xcb, 0x1b, 0x5b, 0x9b, 0xdb, + 0x2b, 0x6b, 0xab, 0xeb, 0x3b, 0x7b, 0xbb, 0xfb, + 0x0f, 0x4f, 0x8f, 0xcf, 0x1f, 0x5f, 0x9f, 0xdf, + 0x2f, 0x6f, 0xaf, 0xef, 0x3f, 0x7f, 0xbf, 0xff +}; + +//============================================================================= + + +void NGPGFX_CLASS::drawColourPattern(uint8 screenx, uint16 tile, uint8 tiley, uint16 mirror, + uint16* palette_ptr, uint8 pal, uint8 depth) +{ + int index, x, left, right, highmark, xx; + uint16 data16; + + x = screenx; + if (x > 0xf8) + x -= 256; + if (x >= SCREEN_WIDTH) + return; + + //Get the data for the "tiley'th" line of "tile". + index = MDFN_de16lsb(CharacterRAM + (tile * 16) + (tiley * 2)); + + //Horizontal Flip + if (mirror) + index = mirrored[(index & 0xff00)>>8] | (mirrored[(index & 0xff)] << 8); + + palette_ptr += pal << 2; + left = max(max(x, winx), 0); + right = x+7; + + highmark = min(winw+winx, SCREEN_WIDTH)-1; + + if (right > highmark) { + index >>= (right - highmark)*2; + right = highmark; + } + + for (xx=right; xx>=left; --xx,index>>=2) { + if (depth <= zbuffer[xx] || (index&3)==0) + continue; + zbuffer[xx] = depth; + + //Get the colour of the pixel + data16 = MDFN_de16lsb(&palette_ptr[index&3]); + + if (negative) + cfb_scanline[xx] = ~data16; + else + cfb_scanline[xx] = data16; + } +} + +void NGPGFX_CLASS::draw_colour_scroll1(uint8 depth, int ngpc_scanline) +{ + uint8 tx, row, line; + uint16 data16; + + line = ngpc_scanline + scroll1y; + row = line & 7; //Which row? + + //Draw Foreground scroll plane (Scroll 1) + for (tx = 0; tx < 32; tx++) + { + data16 = MDFN_de16lsb(ScrollVRAM + ((tx + ((line >> 3) << 5)) << 1)); + + //Draw the line of the tile + drawColourPattern((tx << 3) - scroll1x, data16 & 0x01FF, + (data16 & 0x4000) ? (7 - row) : row, data16 & 0x8000, (uint16*)(ColorPaletteRAM + 0x0080), + (data16 & 0x1E00) >> 9, depth); + } +} + +void NGPGFX_CLASS::draw_colour_scroll2(uint8 depth, int ngpc_scanline) +{ + uint8 tx, row, line; + uint16 data16; + + line = ngpc_scanline + scroll2y; + row = line & 7; //Which row? + + //Draw Background scroll plane (Scroll 2) + for (tx = 0; tx < 32; tx++) + { + data16 = MDFN_de16lsb(ScrollVRAM + 0x0800 + ((tx + ((line >> 3) << 5)) << 1)); + + //Draw the line of the tile + drawColourPattern((tx << 3) - scroll2x, data16 & 0x01FF, + (data16 & 0x4000) ? (7 - row) : row, data16 & 0x8000, (uint16*)(ColorPaletteRAM + 0x0100), + (data16 & 0x1E00) >> 9, depth); + } +} + +void NGPGFX_CLASS::draw_scanline_colour(int layer_enable, int ngpc_scanline) +{ + int16 lastSpriteX; + int16 lastSpriteY; + int spr; + uint16 win_color; + + memset(cfb_scanline, 0, SCREEN_WIDTH * sizeof(uint16)); + memset(zbuffer, 0, SCREEN_WIDTH); + + //Window colour + win_color = MDFN_de16lsb(ColorPaletteRAM + 0x01F0 + (oowc << 1)); + if (negative) win_color = ~win_color; + + //Top + if (ngpc_scanline < winy) + { + for (int x = 0; x < SCREEN_WIDTH; x++) + cfb_scanline[x] = win_color; + } + else + { + //Middle + if (ngpc_scanline < winy + winh) + { + for (int x = 0; x < min(winx, SCREEN_WIDTH); x++) + cfb_scanline[x] = win_color; + + for (int x = min(winx + winw, SCREEN_WIDTH); x < SCREEN_WIDTH; x++) + cfb_scanline[x] = win_color; + } + else //Bottom + { + for (int x = 0; x < SCREEN_WIDTH; x++) + cfb_scanline[x] = win_color; + } + } + + //Ignore above and below the window's top and bottom + if (ngpc_scanline >= winy && ngpc_scanline < winy + winh) + { + //Background colour Enabled? HACK: 01 AUG 2002 - Always on! + // if ((bgc & 0xC0) == 0x80) + { + win_color = MDFN_de16lsb(ColorPaletteRAM + 0x01E0 + ((bgc & 7) << 1)); + } + // else win_color = 0; + + if (negative) win_color = ~win_color; + + //Draw background! + for (int x = winx; x < min(winx + winw, SCREEN_WIDTH); x++) + cfb_scanline[x] = win_color; + + //Swap Front/Back scroll planes? + if (planeSwap) + { + if(layer_enable & 1) + draw_colour_scroll1(ZDEPTH_BACKGROUND_SCROLL, ngpc_scanline); //Swap + if(layer_enable & 2) + draw_colour_scroll2(ZDEPTH_FOREGROUND_SCROLL, ngpc_scanline); + } + else + { + if(layer_enable & 1) + draw_colour_scroll2(ZDEPTH_BACKGROUND_SCROLL, ngpc_scanline); //Normal + if(layer_enable & 2) + draw_colour_scroll1(ZDEPTH_FOREGROUND_SCROLL, ngpc_scanline); + } + + //Draw Sprites + //Last sprite position, (defaults to top-left, sure?) + lastSpriteX = 0; + lastSpriteY = 0; + + if(layer_enable & 4) + for (spr = 0; spr < 64; spr++) + { + uint8 priority, row; + uint8 sx = SpriteVRAM[(spr * 4) + 2]; //X position + uint8 sy = SpriteVRAM[(spr * 4) + 3]; //Y position + int16 x = sx; + int16 y = sy; + uint16 data16; + + data16 = MDFN_de16lsb(SpriteVRAM + (spr * 4)); + priority = (data16 & 0x1800) >> 11; + + if (data16 & 0x0400) x = lastSpriteX + sx; //Horizontal chain? + if (data16 & 0x0200) y = lastSpriteY + sy; //Vertical chain? + + //Store the position for chaining + lastSpriteX = x; + lastSpriteY = y; + + //Visible? + if (priority == 0) continue; + + //Scroll the sprite + x += scrollsprx; + y += scrollspry; + + //Off-screen? + if (x > 248 && x < 256) x = x - 256; else x &= 0xFF; + if (y > 248 && y < 256) y = y - 256; else y &= 0xFF; + + //In range? + if (ngpc_scanline >= y && ngpc_scanline <= y + 7) + { + row = (ngpc_scanline - y) & 7; //Which row? + drawColourPattern((uint8)x, data16 & 0x01FF, + (data16 & 0x4000) ? 7 - row : row, data16 & 0x8000, + (uint16*)ColorPaletteRAM, SpriteVRAMColor[spr] & 0xF, priority << 1); + } + } + + //========== + } + +} + +} + +//============================================================================= diff --git a/waterbox/ngp/gfx_scanline_mono.cpp b/waterbox/ngp/gfx_scanline_mono.cpp new file mode 100644 index 0000000000..549a0b8e71 --- /dev/null +++ b/waterbox/ngp/gfx_scanline_mono.cpp @@ -0,0 +1,253 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#include "neopop.h" +#include "mem.h" +#include "gfx.h" + +//============================================================================= + +namespace MDFN_IEN_NGP +{ + +void NGPGFX_CLASS::MonoPlot(uint8 x, uint8* palette_ptr, uint16 pal_hi, uint8 index, uint8 depth) +{ + uint8 data8; + + //Clip + if (index == 0 || x < winx || x >= (winw + winx) || x >= SCREEN_WIDTH) + return; + + //Depth check, <= to stop later sprites overwriting pixels! + if (depth <= zbuffer[x]) return; + zbuffer[x] = depth; + + //Get the colour of the pixel + if (pal_hi) + data8 = palette_ptr[3 + index - 1]; + else + data8 = palette_ptr[0 + index - 1]; + + uint16 r = (data8 & 7) << 1; + uint16 g = (data8 & 7) << 5; + uint16 b = (data8 & 7) << 9; + + if (negative) + cfb_scanline[x] = (r | g | b); + else + cfb_scanline[x] = ~(r | g | b); +} + +void NGPGFX_CLASS::drawMonoPattern(uint8 screenx, uint16 tile, uint8 tiley, uint16 mirror, + uint8* palette_ptr, uint16 pal, uint8 depth) +{ + //Get the data for th e "tiley'th" line of "tile". + uint16 data = MDFN_de16lsb(CharacterRAM + (tile * 16) + (tiley * 2)); + + //Horizontal Flip + if (mirror) + { + MonoPlot(screenx + 7, palette_ptr, pal, (data & 0xC000) >> 0xE, depth); + MonoPlot(screenx + 6, palette_ptr, pal, (data & 0x3000) >> 0xC, depth); + MonoPlot(screenx + 5, palette_ptr, pal, (data & 0x0C00) >> 0xA, depth); + MonoPlot(screenx + 4, palette_ptr, pal, (data & 0x0300) >> 0x8, depth); + MonoPlot(screenx + 3, palette_ptr, pal, (data & 0x00C0) >> 0x6, depth); + MonoPlot(screenx + 2, palette_ptr, pal, (data & 0x0030) >> 0x4, depth); + MonoPlot(screenx + 1, palette_ptr, pal, (data & 0x000C) >> 0x2, depth); + MonoPlot(screenx + 0, palette_ptr, pal, (data & 0x0003) >> 0x0, depth); + } + else + //Normal + { + MonoPlot(screenx + 0, palette_ptr, pal, (data & 0xC000) >> 0xE, depth); + MonoPlot(screenx + 1, palette_ptr, pal, (data & 0x3000) >> 0xC, depth); + MonoPlot(screenx + 2, palette_ptr, pal, (data & 0x0C00) >> 0xA, depth); + MonoPlot(screenx + 3, palette_ptr, pal, (data & 0x0300) >> 0x8, depth); + MonoPlot(screenx + 4, palette_ptr, pal, (data & 0x00C0) >> 0x6, depth); + MonoPlot(screenx + 5, palette_ptr, pal, (data & 0x0030) >> 0x4, depth); + MonoPlot(screenx + 6, palette_ptr, pal, (data & 0x000C) >> 0x2, depth); + MonoPlot(screenx + 7, palette_ptr, pal, (data & 0x0003) >> 0x0, depth); + } +} + +void NGPGFX_CLASS::draw_mono_scroll1(uint8 depth, int ngpc_scanline) +{ + uint8 tx, row, line; + uint16 data16; + + line = ngpc_scanline + scroll1y; + row = line & 7; //Which row? + + //Draw Foreground scroll plane (Scroll 1) + for (tx = 0; tx < 32; tx++) + { + data16 = MDFN_de16lsb(ScrollVRAM + ((tx + ((line >> 3) << 5)) << 1)); + + //Draw the line of the tile + drawMonoPattern((tx << 3) - scroll1x, data16 & 0x01FF, + (data16 & 0x4000) ? 7 - row : row, data16 & 0x8000, SCRP1PLT, + data16 & 0x2000, depth); + } +} + +void NGPGFX_CLASS::draw_mono_scroll2(uint8 depth, int ngpc_scanline) +{ + uint8 tx, row, line; + uint16 data16; + + line = ngpc_scanline + scroll2y; + row = line & 7; //Which row? + + //Draw Background scroll plane (Scroll 2) + for (tx = 0; tx < 32; tx++) + { + data16 = MDFN_de16lsb(ScrollVRAM + 0x0800 + ((tx + ((line >> 3) << 5)) << 1)); + + //Draw the line of the tile + drawMonoPattern((tx << 3) - scroll2x, data16 & 0x01FF, + (data16 & 0x4000) ? 7 - row : row, data16 & 0x8000, SCRP2PLT, + data16 & 0x2000, depth); + } +} + +void NGPGFX_CLASS::draw_scanline_mono(int layer_enable, int ngpc_scanline) +{ + int16 lastSpriteX; + int16 lastSpriteY; + int spr; + uint16 data16; + + memset(cfb_scanline, 0, SCREEN_WIDTH * sizeof(uint16)); + memset(zbuffer, 0, SCREEN_WIDTH); + + //Window colour + uint16 r = (uint16)oowc << 1; + uint16 g = (uint16)oowc << 5; + uint16 b = (uint16)oowc << 9; + + if (negative) + data16 = (r | g | b); + else + data16 = ~(r | g | b); + + //Top + if (ngpc_scanline < winy) + { + for (int x = 0; x < SCREEN_WIDTH; x++) + cfb_scanline[x] = data16; + } + else + { + //Middle + if (ngpc_scanline < winy + winh) + { + for (int x = 0; x < min(winx, SCREEN_WIDTH); x++) + cfb_scanline[x] = data16; + for (int x = min(winx + winw, SCREEN_WIDTH); x < SCREEN_WIDTH; x++) + cfb_scanline[x] = data16; + } + else //Bottom + { + for (int x = 0; x < SCREEN_WIDTH; x++) + cfb_scanline[x] = data16; + } + } + + //Ignore above and below the window's top and bottom + if (ngpc_scanline >= winy && ngpc_scanline < winy + winh) + { + //Background colour Enabled? + if ((bgc & 0xC0) == 0x80) + { + r = (uint16)(bgc & 7) << 1; + g = (uint16)(bgc & 7) << 5; + b = (uint16)(bgc & 7) << 9; + data16 = ~(r | g | b); + } + else data16 = 0x0FFF; + + if (negative) data16 = ~data16; + + //Draw background! + for (int x = winx; x < min(winx + winw, SCREEN_WIDTH); x++) + cfb_scanline[x] = data16; + + //Swap Front/Back scroll planes? + if (planeSwap) + { + if(layer_enable & 1) + draw_mono_scroll1(ZDEPTH_BACKGROUND_SCROLL, ngpc_scanline); //Swap + if(layer_enable & 2) + draw_mono_scroll2(ZDEPTH_FOREGROUND_SCROLL, ngpc_scanline); + } + else + { + if(layer_enable & 1) + draw_mono_scroll2(ZDEPTH_BACKGROUND_SCROLL, ngpc_scanline); //Normal + if(layer_enable & 2) + draw_mono_scroll1(ZDEPTH_FOREGROUND_SCROLL, ngpc_scanline); + } + + //Draw Sprites + //Last sprite position, (defaults to top-left, sure?) + lastSpriteX = 0; + lastSpriteY = 0; + if(layer_enable & 4) + for (spr = 0; spr < 64; spr++) + { + uint8 priority, row; + uint8 sx = SpriteVRAM[(spr * 4) + 2]; //X position + uint8 sy = SpriteVRAM[(spr * 4) + 3]; //Y position + int16 x = sx; + int16 y = sy; + + data16 = MDFN_de16lsb(SpriteVRAM + (spr * 4)); + priority = (data16 & 0x1800) >> 11; + + if (data16 & 0x0400) x = lastSpriteX + sx; //Horizontal chain? + if (data16 & 0x0200) y = lastSpriteY + sy; //Vertical chain? + + //Store the position for chaining + lastSpriteX = x; + lastSpriteY = y; + + //Visible? + if (priority == 0) continue; + + //Scroll the sprite + x += scrollsprx; + y += scrollspry; + + //Off-screen? + if (x > 248 && x < 256) x = x - 256; else x &= 0xFF; + if (y > 248 && y < 256) y = y - 256; else y &= 0xFF; + + //In range? + if (ngpc_scanline >= y && ngpc_scanline <= y + 7) + { + row = (ngpc_scanline - y) & 7; //Which row? + drawMonoPattern((uint8)x, data16 & 0x01FF, + (data16 & 0x4000) ? 7 - row : row, data16 & 0x8000, + SPPLT, data16 & 0x2000, priority << 1); + } + } + + } + + //========== +} + +} + +//============================================================================= diff --git a/waterbox/ngp/interrupt.cpp b/waterbox/ngp/interrupt.cpp new file mode 100644 index 0000000000..dc96bcf784 --- /dev/null +++ b/waterbox/ngp/interrupt.cpp @@ -0,0 +1,598 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#include "neopop.h" +#include "mem.h" +#include "gfx.h" +#include "interrupt.h" +#include "Z80_interface.h" +#include "dma.h" + +//============================================================================= + +namespace MDFN_IEN_NGP +{ + +uint32 timer_hint; +static uint32 timer_clock[4]; +static uint8 timer[4]; //Up-counters +static uint8 timer_threshold[4]; + +static uint8 TRUN; +static uint8 T01MOD, T23MOD; +static uint8 TRDC; +static uint8 TFFCR; +static uint8 HDMAStartVector[4]; + +static int32 ipending[24]; +static int32 IntPrio[0xB]; // 0070-007a +static bool h_int, timer0, timer2; + +// The way interrupt processing is set up is still written towards BIOS HLE emulation, which assumes +// that the interrupt handler will immediately call DI, clear the interrupt latch(so the interrupt won't happen again when interrupts are re-enabled), +// and then call the game's interrupt handler. + +// We automatically clear the interrupt latch when the interrupt is accepted, and the interrupt latch is not checked every instruction, +// but only when: an EI/DI, POP SR, or RETI instruction occurs; after a write to an interrupt priority register occurs; and when +// a device sets the virual interrupt latch register, signaling it wants an interrupt. + +// FIXME in the future if we ever add real bios support? +void interrupt(uint8 index) +{ + //printf("INT: %d\n", index); + push32(pc); + push16(sr); + + //Up the IFF + if (((sr & 0x7000) >> 12) < 7) + setStatusIFF(((sr & 0x7000) >> 12) + 1); + + //Access the interrupt vector table to find the jump destination + pc = loadL(0x6FB8 + index * 4); +} + +void set_interrupt(uint8 index, bool set) +{ + assert(index < 24); + + ipending[index] = set; + int_check_pending(); +} + +void int_check_pending(void) +{ + uint8 prio; + uint8 curIFF = statusIFF(); + + // Technically, the BIOS should clear the interrupt pending flag by writing with IxxC set to "0", but + // we'll actually need to implement a BIOS to do that! + + prio = IntPrio[0x1] & 0x07; // INT4 + if (ipending[5] && curIFF <= prio && prio && prio != 7) + { + ipending[5] = 0; + interrupt(5); + return; + } + + prio = (IntPrio[0x1] & 0x70) >> 4; // INT5 (Z80) + if (ipending[6] && curIFF <= prio && prio && prio != 7) + { + ipending[6] = 0; + interrupt(6); + return; + } + + prio = IntPrio[0x3] & 0x07; // INTT0 + if (ipending[7] && curIFF <= prio && prio && prio != 7) + { + ipending[7] = 0; + interrupt(7); + return; + } + + prio = (IntPrio[0x3] & 0x70) >> 4; // INTT1 + if (ipending[8] && curIFF <= prio && prio && prio != 7) + { + ipending[8] = 0; + interrupt(8); + return; + } + + prio = (IntPrio[0x4] & 0x07); // INTT2 + if (ipending[9] && curIFF <= prio && prio && prio != 7) + { + ipending[9] = 0; + interrupt(9); + return; + } + + prio = ((IntPrio[0x4] & 0x70) >> 4); // INTT3 + if (ipending[10] && curIFF <= prio && prio && prio != 7) + { + ipending[10] = 0; + interrupt(10); + return; + } + + prio = (IntPrio[0x7] & 0x07); // INTRX0 + if (ipending[11] && curIFF <= prio && prio && prio != 7) + { + ipending[11] = 0; + interrupt(11); + return; + } + + prio = ((IntPrio[0x7] & 0x70) >> 4); // INTTX0 + if (ipending[12] && curIFF <= prio && prio && prio != 7) + { + ipending[12] = 0; + interrupt(12); + return; + } +} + +void int_write8(uint32 address, uint8 data) +{ + switch (address) + { + case 0x71: + if (!(data & 0x08)) + ipending[5] = 0; + if (!(data & 0x80)) + ipending[6] = 0; + break; + case 0x73: + if (!(data & 0x08)) + ipending[7] = 0; + if (!(data & 0x80)) + ipending[8] = 0; + break; + case 0x74: + if (!(data & 0x08)) + ipending[9] = 0; + if (!(data & 0x80)) + ipending[10] = 0; + break; + case 0x77: + if (!(data & 0x08)) + ipending[11] = 0; + if (!(data & 0x80)) + ipending[12] = 0; + break; + case 0x7C: + HDMAStartVector[0] = data; + break; + case 0x7D: + HDMAStartVector[1] = data; + break; + case 0x7E: + HDMAStartVector[2] = data; + break; + case 0x7F: + HDMAStartVector[3] = data; + break; + } + if (address >= 0x70 && address <= 0x7A) + { + IntPrio[address - 0x70] = data; + int_check_pending(); + } +} + +uint8 int_read8(uint32 address) +{ + uint8 ret = 0; + switch (address) + { + case 0x71: + ret = ((ipending[5] ? 0x08 : 0x00) | (ipending[6] ? 0x80 : 0x00)); + break; + case 0x73: + ret = ((ipending[7] ? 0x08 : 0x00) | (ipending[8] ? 0x80 : 0x00)); + break; + case 0x74: + ret = ((ipending[9] ? 0x08 : 0x00) | (ipending[10] ? 0x80 : 0x00)); + break; + case 0x77: + ret = ((ipending[11] ? 0x08 : 0x00) | (ipending[12] ? 0x80 : 0x00)); + break; + } + + return (ret); +} + +void TestIntHDMA(int bios_num, int vec_num) +{ + bool WasDMA = 0; + + if (HDMAStartVector[0] == vec_num) + { + WasDMA = 1; + DMA_update(0); + } + else + { + if (HDMAStartVector[1] == vec_num) + { + WasDMA = 1; + DMA_update(1); + } + else + { + if (HDMAStartVector[2] == vec_num) + { + WasDMA = 1; + DMA_update(2); + } + else + { + if (HDMAStartVector[3] == vec_num) + { + WasDMA = 1; + DMA_update(3); + } + } + } + } + if (!WasDMA) + set_interrupt(bios_num, TRUE); +} + +extern int32 ngpc_soundTS; +extern bool NGPFrameSkip; + +bool updateTimers(MDFN_Surface *surface, int cputicks) +{ + bool ret = 0; + + ngpc_soundTS += cputicks; + //increment H-INT timer + timer_hint += cputicks; + + //======================= + + //End of scanline / Start of Next one + if (timer_hint >= TIMER_HINT_RATE) + { + uint8 data; + + // ============= END OF CURRENT SCANLINE ============= + + h_int = NGPGfx->hint(); + ret = NGPGfx->draw(surface, NGPFrameSkip); + + // ============= START OF NEXT SCANLINE ============= + + timer_hint -= TIMER_HINT_RATE; //Start of next scanline + + //Comms. Read interrupt + if ((COMMStatus & 1) == 0 && system_comms_poll(&data)) + { + storeB(0x50, data); + TestIntHDMA(12, 0x19); + } + } + + //======================= + + //Tick the Clock Generator + timer_clock[0] += cputicks; + timer_clock[1] += cputicks; + + timer0 = FALSE; //Clear the timer0 tick, for timer1 chain mode. + + //======================= + + //Run Timer 0 (TRUN)? + if ((TRUN & 0x01)) + { + //T01MOD + switch (T01MOD & 0x03) + { + case 0: + if (h_int) //Horizontal interrupt trigger + { + timer[0]++; + + timer_clock[0] = 0; + h_int = FALSE; // Stop h_int remaining active + } + break; + + case 1: + while (timer_clock[0] >= TIMER_T1_RATE) + { + timer[0]++; + timer_clock[0] -= TIMER_T1_RATE; + } + break; + + case 2: + while (timer_clock[0] >= TIMER_T4_RATE) + { + timer[0]++; + timer_clock[0] -= TIMER_T4_RATE; + } + break; + + case 3: + while (timer_clock[0] >= TIMER_T16_RATE) + { + timer[0]++; + timer_clock[0] -= TIMER_T16_RATE; + } + break; + } + + //Threshold check + if (timer_threshold[0] && timer[0] >= timer_threshold[0]) + { + timer[0] = 0; + timer0 = TRUE; + + TestIntHDMA(7, 0x10); + } + } + + //======================= + + //Run Timer 1 (TRUN)? + if ((TRUN & 0x02)) + { + //T01MOD + switch ((T01MOD & 0x0C) >> 2) + { + case 0: + if (timer0) //Timer 0 chain mode. + { + timer[1] += timer0; + timer_clock[1] = 0; + } + break; + + case 1: + while (timer_clock[1] >= TIMER_T1_RATE) + { + timer[1]++; + timer_clock[1] -= TIMER_T1_RATE; + } + break; + + case 2: + while (timer_clock[1] >= TIMER_T16_RATE) + { + timer[1]++; + timer_clock[1] -= TIMER_T16_RATE; + } + break; + + case 3: + while (timer_clock[1] >= TIMER_T256_RATE) + { + timer[1]++; + timer_clock[1] -= TIMER_T256_RATE; + } + break; + } + + //Threshold check + if (timer_threshold[1] && timer[1] >= timer_threshold[1]) + { + timer[1] = 0; + + TestIntHDMA(8, 0x11); + } + } + + //======================= + + //Tick the Clock Generator + timer_clock[2] += cputicks; + timer_clock[3] += cputicks; + + timer2 = FALSE; //Clear the timer2 tick, for timer3 chain mode. + + //======================= + + //Run Timer 2 (TRUN)? + if ((TRUN & 0x04)) + { + //T23MOD + switch (T23MOD & 0x03) + { + case 0: // - + break; + + case 1: + while (timer_clock[2] >= TIMER_T1_RATE / 2) // Kludge :( + { + timer[2]++; + timer_clock[2] -= TIMER_T1_RATE / 2; + } + break; + + case 2: + while (timer_clock[2] >= TIMER_T4_RATE) + { + timer[2]++; + timer_clock[2] -= TIMER_T4_RATE; + } + break; + + case 3: + while (timer_clock[2] >= TIMER_T16_RATE) + { + timer[2]++; + timer_clock[2] -= TIMER_T16_RATE; + } + break; + } + + //Threshold check + if (timer_threshold[2] && timer[2] >= timer_threshold[2]) + { + timer[2] = 0; + timer2 = TRUE; + + TestIntHDMA(9, 0x12); + } + } + + //======================= + + //Run Timer 3 (TRUN)? + if ((TRUN & 0x08)) + { + //T23MOD + switch ((T23MOD & 0x0C) >> 2) + { + case 0: + if (timer2) //Timer 2 chain mode. + { + timer[3] += timer2; + timer_clock[3] = 0; + } + break; + + case 1: + while (timer_clock[3] >= TIMER_T1_RATE) + { + timer[3]++; + timer_clock[3] -= TIMER_T1_RATE; + } + break; + + case 2: + while (timer_clock[3] >= TIMER_T16_RATE) + { + timer[3]++; + timer_clock[3] -= TIMER_T16_RATE; + } + break; + + case 3: + while (timer_clock[3] >= TIMER_T256_RATE) + { + timer[3]++; + timer_clock[3] -= TIMER_T256_RATE; + } + break; + } + + //Threshold check + if (timer_threshold[3] && timer[3] >= timer_threshold[3]) + { + timer[3] = 0; + + Z80_irq(); + TestIntHDMA(10, 0x13); + } + } + return (ret); +} + +void reset_timers(void) +{ + timer_hint = 0; + + memset(timer, 0, sizeof(timer)); + memset(timer_clock, 0, sizeof(timer_clock)); + memset(timer_threshold, 0, sizeof(timer_threshold)); + + timer0 = FALSE; + timer2 = FALSE; +} + +void reset_int(void) +{ + TRUN = 0; + T01MOD = 0; + T23MOD = 0; + TRDC = 0; + TFFCR = 0; + + memset(HDMAStartVector, 0, sizeof(HDMAStartVector)); + memset(ipending, 0, sizeof(ipending)); + memset(IntPrio, 0, sizeof(IntPrio)); + + h_int = FALSE; +} + +void timer_write8(uint32 address, uint8 data) +{ + switch (address) + { + case 0x20: + TRUN = data; + if ((TRUN & 0x01) == 0) + timer[0] = 0; + if ((TRUN & 0x02) == 0) + timer[1] = 0; + if ((TRUN & 0x04) == 0) + timer[2] = 0; + if ((TRUN & 0x08) == 0) + timer[3] = 0; + break; + case 0x22: + timer_threshold[0] = data; + break; + case 0x23: + timer_threshold[1] = data; + break; + case 0x24: + T01MOD = data; + break; + case 0x25: + TFFCR = data & 0x33; + break; + case 0x26: + timer_threshold[2] = data; + break; + case 0x27: + timer_threshold[3] = data; + break; + case 0x28: + T23MOD = data; + break; + case 0x29: + TRDC = data & 0x3; + break; + } +} + +uint8 timer_read8(uint32 address) +{ + uint8 ret = 0; + + switch (address) + { + //default: printf("Baaaad: %08x\n", address); break; + // Cool boarders is stupid and tries to read from a write-only register >_< + // Returning 4 makes the game run ok, so 4 it is! + default: + ret = 0x4; + break; + case 0x20: + ret = TRUN; + break; + case 0x29: + ret = TRDC; + break; + } + + //printf("UNK B R: %08x\n", address); + return (ret); +} +} diff --git a/waterbox/ngp/interrupt.h b/waterbox/ngp/interrupt.h new file mode 100644 index 0000000000..a82510d4cd --- /dev/null +++ b/waterbox/ngp/interrupt.h @@ -0,0 +1,61 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#ifndef __NEOPOP_INTERRUPT__ +#define __NEOPOP_INTERRUPT__ +//============================================================================= + +namespace MDFN_IEN_NGP +{ + +void interrupt(uint8 index); + +#define TIMER_HINT_RATE 515 //CPU Ticks between horizontal interrupts + +#define TIMER_BASE_RATE 32 //1 //ticks + +#define TIMER_T1_RATE (8 * TIMER_BASE_RATE) +#define TIMER_T4_RATE (32 * TIMER_BASE_RATE) +#define TIMER_T16_RATE (128 * TIMER_BASE_RATE) +#define TIMER_T256_RATE (2048 * TIMER_BASE_RATE) + +void reset_timers(void); +void reset_int(void); + +//Call this after each instruction +bool updateTimers(MDFN_Surface *surface, int cputicks); + +//H-INT Timer +extern uint32 timer_hint; + +void timer_write8(uint32 address, uint8 data); +uint8 timer_read8(uint32 address); + + +// Set this value to fix problems with glitching extra lines. +extern bool gfx_hack; + + +void int_write8(uint32 address, uint8 data); +uint8 int_read8(uint32 address); +void int_check_pending(void); +void TestIntHDMA(int bios_num, int vec_num); +} + +//============================================================================= +#endif + + + + diff --git a/waterbox/ngp/mem.cpp b/waterbox/ngp/mem.cpp new file mode 100644 index 0000000000..457eadffff --- /dev/null +++ b/waterbox/ngp/mem.cpp @@ -0,0 +1,689 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#include "neopop.h" +#include "Z80_interface.h" +#include "bios.h" +#include "gfx.h" +#include "mem.h" +#include "interrupt.h" +#include "sound.h" +#include "flash.h" +#include "rtc.h" + +//============================================================================= + +namespace MDFN_IEN_NGP +{ +extern uint8 settings_language; +extern bool lagged; +extern void (*inputcallback)(); + +//Hack way of returning good Flash status. +bool FlashStatusEnable = FALSE; +static uint32 FlashStatus; + +uint8 CPUExRAM[16384]; + +bool debug_abort_memory = FALSE; +bool debug_mask_memory_error_messages = FALSE; + +bool memory_unlock_flash_write = FALSE; +bool memory_flash_error = FALSE; +bool memory_flash_command = FALSE; + +uint8 SC0BUF; // Serial channel 0 buffer. +uint8 COMMStatus; + +// In very very very rare conditions(like on embedded platforms with no virtual memory and very limited RAM and +// malloc happens to return a pointer aligned to a 64KiB boundary), a FastReadMap entry may be NULL even if +// it points to valid data when it's added to the address of the read, but +// if this happens, it will only make the emulator slightly slower. +static uint8 *FastReadMap[256], *FastReadMapReal[256]; + +void SetFRM(void) // Call this function after rom is loaded +{ + for (unsigned int x = 0; x < 256; x++) + FastReadMapReal[x] = NULL; + + for (unsigned int x = 0x20; x <= 0x3f; x++) + { + if (ngpc_rom.length > (x * 65536 + 65535 - 0x20000)) + FastReadMapReal[x] = &ngpc_rom.data[x * 65536 - 0x200000] - x * 65536; + } + + for (unsigned int x = 0x80; x <= 0x9f; x++) + { + if (ngpc_rom.length > (x * 65536 + 65535 - 0x80000)) + FastReadMapReal[x] = &ngpc_rom.data[x * 65536 - 0x800000] - x * 65536; + } +} + +void RecacheFRM(void) +{ + for (int x = 0; x < 256; x++) + FastReadMap[x] = FlashStatusEnable ? NULL : FastReadMapReal[x]; +} + +static void *translate_address_read(uint32 address) +{ + address &= 0xFFFFFF; + + //Get Flash status? + if (FlashStatusEnable) + { + if ((address >= ROM_START && address <= ROM_END) || (address >= HIROM_START && address <= HIROM_END)) + { + FlashStatusEnable = FALSE; + RecacheFRM(); + if (address == 0x220000 || address == 0x230000) + { + FlashStatus = 0xFFFFFFFF; + return &FlashStatus; + } + } + } + + //ROM (LOW) + if (address >= ROM_START && address <= ROM_END) + { + if (address < ROM_START + ngpc_rom.length) + return ngpc_rom.data + (address - ROM_START); + else + return NULL; + } + + //ROM (HIGH) + if (address >= HIROM_START && address <= HIROM_END) + { + if (address < HIROM_START + (ngpc_rom.length - 0x200000)) + return ngpc_rom.data + 0x200000 + (address - HIROM_START); + else + return NULL; + } + + // =================================== + + //BIOS Access? + if ((address & 0xFF0000) == 0xFF0000) + { + return ngpc_bios + (address & 0xFFFF); // BIOS ROM + } + return NULL; +} + +//============================================================================= + +static void *translate_address_write(uint32 address) +{ + address &= 0xFFFFFF; + + if (memory_unlock_flash_write) + { + //ROM (LOW) + if (address >= ROM_START && address <= ROM_END) + { + if (address < ROM_START + ngpc_rom.length) + return ngpc_rom.data + (address - ROM_START); + else + return NULL; + } + + //ROM (HIGH) + if (address >= HIROM_START && address <= HIROM_END) + { + if (address < HIROM_START + (ngpc_rom.length - 0x200000)) + return ngpc_rom.data + 0x200000 + (address - HIROM_START); + else + return NULL; + } + } + else + { + //ROM (LOW) + if (address >= ROM_START && address <= ROM_END) + { + //Ignore Flash commands + if (address == 0x202AAA || address == 0x205555) + { + // system_debug_message("%06X: Enable Flash command from %06X", pc, address); + memory_flash_command = TRUE; + return NULL; + } + + //Set Flash status reading? + if (address == 0x220000 || address == 0x230000) + { + // system_debug_message("%06X: Flash status read from %06X", pc, address); + FlashStatusEnable = TRUE; + RecacheFRM(); + return NULL; + } + + if (memory_flash_command) + { + //Write the 256byte block around the flash data + flash_write(address & 0xFFFF00, 256); + + //Need to issue a new command before writing will work again. + memory_flash_command = FALSE; + + // system_debug_message("%06X: Direct Flash write to %06X", pc, address & 0xFFFF00); + // system_debug_stop(); + + //Write to the rom itself. + if (address < ROM_START + ngpc_rom.length) + return ngpc_rom.data + (address - ROM_START); + } + } + } + + // =================================== + return NULL; +} + +/* WARNING: 32-bit loads and stores apparently DON'T have to be 4-byte-aligned(so we must +2 instead of |2). */ +/* Treat all 32-bit operations as two 16-bit operations */ +uint8 loadB(uint32 address) +{ + address &= 0xFFFFFF; + + if (FastReadMap[address >> 16]) + return (FastReadMap[address >> 16][address]); + + if (address == 0x6f82) + { + lagged = false; + if (inputcallback) + inputcallback(); + } + + uint8 *ptr = (uint8 *)translate_address_read(address); + + if (ptr) + return *ptr; + + if (address >= 0x8000 && address <= 0xbfff) + return (NGPGfx->read8(address)); + if (address >= 0x4000 && address <= 0x7fff) + { + return (*(uint8 *)(CPUExRAM + address - 0x4000)); + } + + if (address >= 0x70 && address <= 0x7F) + { + return (int_read8(address)); + } + + if (address >= 0x90 && address <= 0x97) + { + return (rtc_read8(address)); + } + + if (address >= 0x20 && address <= 0x29) + { + return (timer_read8(address)); + } + + if (address == 0x50) + return (SC0BUF); + + if (address == 0xBC) + return Z80_ReadComm(); + + //printf("UNK B R: %08x\n", address); + + return (0); +} + +uint16 loadW(uint32 address) +{ + address &= 0xFFFFFF; + + if (address & 1) + { + uint16 ret; + + ret = loadB(address); + ret |= loadB(address + 1) << 8; + + return (ret); + } + + if (FastReadMap[address >> 16]) + return (MDFN_de16lsb(&FastReadMap[address >> 16][address])); + + if (address == 0x6f82) + { + lagged = false; + if (inputcallback) + inputcallback(); + } + + uint16 *ptr = (uint16 *)translate_address_read(address); + if (ptr) + return MDFN_de16lsb(ptr); + + if (address >= 0x8000 && address <= 0xbfff) + return (NGPGfx->read16(address)); + + if (address >= 0x4000 && address <= 0x7fff) + { + return (MDFN_de16lsb(CPUExRAM + address - 0x4000)); + } + if (address == 0x50) + return (SC0BUF); + + if (address >= 0x70 && address <= 0x7F) + { + uint16 ret; + + ret = int_read8(address); + ret |= int_read8(address + 1) << 8; + + return (ret); + } + + if (address >= 0x90 && address <= 0x97) + { + uint16 ret; + + ret = rtc_read8(address); + ret |= rtc_read8(address + 1) << 8; + + return (ret); + } + + if (address >= 0x20 && address <= 0x29) + { + uint16 ret; + + ret = timer_read8(address); + ret |= timer_read8(address + 1) << 8; + + return (ret); + } + + if (address == 0xBC) + return Z80_ReadComm(); + + //printf("UNK W R: %08x\n", address); + + return (0); +} + +uint32 loadL(uint32 address) +{ + uint32 ret; + + ret = loadW(address); + ret |= loadW(address + 2) << 16; + + return (ret); +} + +//============================================================================= + +void storeB(uint32 address, uint8 data) +{ + address &= 0xFFFFFF; + + if (address >= 0x8000 && address <= 0xbfff) + { + NGPGfx->write8(address, data); + return; + } + if (address >= 0x4000 && address <= 0x7fff) + { + *(uint8 *)(CPUExRAM + address - 0x4000) = data; + return; + } + if (address >= 0x70 && address <= 0x7F) + { + int_write8(address, data); + return; + } + if (address >= 0x20 && address <= 0x29) + { + timer_write8(address, data); + return; + } + + if (address == 0x50) + { + SC0BUF = data; + return; + } + + if (address == 0x6f) // Watchdog timer + { + return; + } + + if (address == 0xb2) // Comm? + { + COMMStatus = data & 1; + return; + } + + if (address == 0xb9) + { + if (data == 0x55) + Z80_SetEnable(1); + else if (data == 0xAA) + Z80_SetEnable(0); + return; + } + + if (address == 0xb8) + { + if (data == 0x55) + MDFNNGPCSOUND_SetEnable(1); + else if (data == 0xAA) + MDFNNGPCSOUND_SetEnable(0); + return; + } + + if (address == 0xBA) + { + Z80_nmi(); + return; + } + + if (address == 0xBC) + { + Z80_WriteComm(data); + return; + } + + if (address >= 0xa0 && address <= 0xA3) + { + if (!Z80_IsEnabled()) + { + if (address == 0xA1) + Write_SoundChipLeft(data); + else if (address == 0xA0) + Write_SoundChipRight(data); + } + //DAC Write + if (address == 0xA2) + { + dac_write_left(data); + } + else if (address == 0xA3) + { + dac_write_right(data); + } + return; + } + + //printf("%08x %02x\n", address, data); + uint8 *ptr = (uint8 *)translate_address_write(address); + + //Write + if (ptr) + { + *ptr = data; + } + //else + // printf("ACK: %08x %02x\n", address, data); +} + +void storeW(uint32 address, uint16 data) +{ + address &= 0xFFFFFF; + + if (address & 1) + { + storeB(address + 0, data & 0xFF); + storeB(address + 1, data >> 8); + return; + } + + if (address >= 0x8000 && address <= 0xbfff) + { + NGPGfx->write16(address, data); + return; + } + if (address >= 0x4000 && address <= 0x7fff) + { + MDFN_en16lsb(CPUExRAM + address - 0x4000, data); + return; + } + if (address >= 0x70 && address <= 0x7F) + { + int_write8(address, data & 0xFF); + int_write8(address + 1, data >> 8); + return; + } + + if (address >= 0x20 && address <= 0x29) + { + timer_write8(address, data & 0xFF); + timer_write8(address + 1, data >> 8); + } + + if (address == 0x50) + { + SC0BUF = data & 0xFF; + return; + } + + if (address == 0x6e) // Watchdog timer(technically 0x6f) + { + return; + } + + if (address == 0xb2) // Comm? + { + COMMStatus = data & 1; + return; + } + + if (address == 0xb8) + { + if ((data & 0xFF00) == 0x5500) + Z80_SetEnable(1); + else if ((data & 0xFF00) == 0xAA00) + Z80_SetEnable(0); + + if ((data & 0xFF) == 0x55) + MDFNNGPCSOUND_SetEnable(1); + else if ((data & 0xFF) == 0xAA) + MDFNNGPCSOUND_SetEnable(0); + return; + } + + if (address == 0xBA) + { + Z80_nmi(); + return; + } + + if (address == 0xBC) + { + Z80_WriteComm(data); + return; + } + + if (address >= 0xa0 && address <= 0xA3) + { + storeB(address, data & 0xFF); + storeB(address + 1, data >> 8); + return; + } + + uint16 *ptr = (uint16 *)translate_address_write(address); + + //Write + if (ptr) + { + MDFN_en16lsb(ptr, data); + } + //else + // printf("ACK16: %08x %04x\n", address, data); +} + +void storeL(uint32 address, uint32 data) +{ + storeW(address, data & 0xFFFF); + storeW(address + 2, data >> 16); +} + +//============================================================================= + +static const uint8 systemMemory[] = + { + // 0x00 // 0x08 + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0xFF, 0xFF, + // 0x10 // 0x18 + 0x34, 0x3C, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x3F, 0xFF, 0x2D, 0x01, 0xFF, 0xFF, 0x03, 0xB2, + // 0x20 // 0x28 + 0x80, 0x00, 0x01, 0x90, 0x03, 0xB0, 0x90, 0x62, 0x05, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x4C, 0x4C, + // 0x30 // 0x38 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x20, 0xFF, 0x80, 0x7F, + // 0x40 // 0x48 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x50 // 0x58 + 0x00, 0x20, 0x69, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + // 0x60 // 0x68 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x17, 0x03, 0x03, 0x02, 0x00, 0x00, 0x4E, + // 0x70 // 0x78 + 0x02, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x80 // 0x88 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x90 // 0x98 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xA0 // 0xA8 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xB0 // 0xB8 + 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xC0 // 0xC8 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xD0 // 0xD8 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xE0 // 0xE8 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0xF0 // 0xF8 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +//============================================================================= + +void reset_memory(void) +{ + unsigned int i; + + FlashStatusEnable = FALSE; + RecacheFRM(); + + memory_flash_command = FALSE; + + //============================================================================= + //000000 -> 000100 CPU Internal RAM (Timers/DMA/Z80) + //===================================================== + + for (i = 0; i < sizeof(systemMemory); i++) + storeB(i, systemMemory[i]); + + //============================================================================= + //006C00 -> 006FFF BIOS Workspace + //================================== + + storeL(0x6C00, MDFN_de32lsb(rom_header->startPC)); //Start + + storeW(0x6C04, MDFN_de16lsb(rom_header->catalog)); + storeW(0x6E82, MDFN_de16lsb(rom_header->catalog)); + + storeB(0x6C06, rom_header->subCatalog); + storeB(0x6E84, rom_header->subCatalog); + + for (i = 0; i < 12; i++) + storeB(0x6c08 + i, ngpc_rom.data[0x24 + i]); + + storeB(0x6C58, 0x01); + + //32MBit cart? + if (ngpc_rom.length > 0x200000) + storeB(0x6C59, 0x01); + else + storeB(0x6C59, 0x00); + + storeB(0x6C55, 1); //Commercial game + + storeB(0x6F80, 0xFF); //Lots of battery power! + storeB(0x6F81, 0x03); + + storeB(0x6F84, 0x40); // "Power On" startup + storeB(0x6F85, 0x00); // No shutdown request + storeB(0x6F86, 0x00); // No user answer (?) + + //Language: 0 = Japanese, 1 = English + storeB(0x6F87, settings_language); + + //Color Mode Selection: 0x00 = B&W, 0x10 = Colour + storeB(0x6F91, rom_header->mode); + storeB(0x6F95, rom_header->mode); + + //Interrupt table + for (i = 0; i < 0x12; i++) + storeL(0x6FB8 + i * 4, 0x00FF23DF); + + //============================================================================= + //008000 -> 00BFFF Video RAM + //============================= + + storeB(0x8000, 0xC0); // Both interrupts allowed + + //Hardware window + storeB(0x8002, 0x00); + storeB(0x8003, 0x00); + storeB(0x8004, 0xFF); + storeB(0x8005, 0xFF); + + storeB(0x8006, 0xc6); // Frame Rate Register + + storeB(0x8012, 0x00); // NEG / OOWC setting. + + storeB(0x8118, 0x80); // BGC on! + + storeB(0x83E0, 0xFF); // Default background colour + storeB(0x83E1, 0x0F); + + storeB(0x83F0, 0xFF); // Default window colour + storeB(0x83F1, 0x0F); + + storeB(0x8400, 0xFF); // LED on + storeB(0x8402, 0x80); // Flash cycle = 1.3s + + storeB(0x87E2, loadB(0x6F95) ? 0x00 : 0x80); + + // + // Metal Slug - 2nd Mission oddly relies on a specific character RAM pattern. + // + { + static const uint8 char_data[64] = { + 255, 63, 255, 255, 0, 252, 255, 255, 255, 63, 3, 0, 255, 255, 255, 255, + 240, 243, 252, 243, 255, 3, 255, 195, 255, 243, 243, 243, 240, 243, 240, 195, + 207, 15, 207, 15, 207, 15, 207, 207, 207, 255, 207, 255, 207, 255, 207, 63, + 255, 192, 252, 195, 240, 207, 192, 255, 192, 255, 240, 207, 252, 195, 255, 192}; + + for (i = 0; i < 64; i++) + { + storeB(0xA1C0 + i, char_data[i]); + } + } +} +} + +//============================================================================= diff --git a/waterbox/ngp/mem.h b/waterbox/ngp/mem.h new file mode 100644 index 0000000000..c467354d2c --- /dev/null +++ b/waterbox/ngp/mem.h @@ -0,0 +1,61 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#ifndef __NEOPOP_MEM__ +#define __NEOPOP_MEM__ +//============================================================================= + +namespace MDFN_IEN_NGP +{ + +#define ROM_START 0x200000 +#define ROM_END 0x3FFFFF + +#define HIROM_START 0x800000 +#define HIROM_END 0x9FFFFF + +#define BIOS_START 0xFF0000 +#define BIOS_END 0xFFFFFF + +void reset_memory(void); + +void dump_memory(uint32 start, uint32 length); + +extern bool debug_abort_memory; +extern bool debug_mask_memory_error_messages; + +extern bool memory_unlock_flash_write; +extern bool memory_flash_error; +extern bool memory_flash_command; + +extern bool FlashStatusEnable; +extern uint8 COMMStatus; + +//============================================================================= + +uint8 loadB(uint32 address); +uint16 loadW(uint32 address); +uint32 loadL(uint32 address); + +void storeB(uint32 address, uint8 data); +void storeW(uint32 address, uint16 data); +void storeL(uint32 address, uint32 data); + +void SetFRM(void); +void RecacheFRM(void); + +} + +//============================================================================= +#endif diff --git a/waterbox/ngp/neopop.cpp b/waterbox/ngp/neopop.cpp new file mode 100644 index 0000000000..e7335d6f8a --- /dev/null +++ b/waterbox/ngp/neopop.cpp @@ -0,0 +1,244 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#include "neopop.h" + +#include "Z80_interface.h" +#include "interrupt.h" +#include "mem.h" +#include "gfx.h" +#include "sound.h" +#include "dma.h" +#include "bios.h" +#include "flash.h" + +#include + +namespace MDFN_IEN_NGP +{ +bool lagged; +void (*inputcallback)(); + + +extern uint8 CPUExRAM[16384]; + +NGPGFX_CLASS *NGPGfx = NULL; + +COLOURMODE system_colour = COLOURMODE_AUTO; + +uint8 NGPJoyLatch; +uint8 settings_language; +time_t frontend_time; + +int (*comms_read_cb)(uint8* buffer); +int (*comms_poll_cb)(uint8* buffer); +void (*comms_write_cb)(uint8 data); + +bool system_comms_read(uint8 *buffer) +{ + if (comms_read_cb) + return comms_read_cb(buffer); + else + return false; +} + +bool system_comms_poll(uint8 *buffer) +{ + if (comms_poll_cb) + return comms_poll_cb(buffer); + else + return false; +} + +void system_comms_write(uint8 data) +{ + if (comms_write_cb) + comms_write_cb(data); +} + +void instruction_error(char *vaMessage, ...) +{ + /*char message[1000]; + va_list vl; + + va_start(vl, vaMessage); + vsprintf(message, vaMessage, vl); + va_end(vl); + + MDFN_printf("[PC %06X] %s\n", pc, message);*/ +} + +bool NGPFrameSkip; +int32 ngpc_soundTS = 0; +//static int32 main_timeaccum; +static int32 z80_runtime; + +EXPORT void FrameAdvance(MyFrameInfo* frame) +{ + lagged = true; + bool MeowMeow = 0; + MDFN_Surface surface; + surface.pixels = frame->VideoBuffer; + surface.pitch32 = 160; + frame->Width = 160; + frame->Height = 152; + frontend_time = frame->FrontendTime; + storeB(0x6f82, frame->Buttons); + + ngpc_soundTS = 0; + NGPFrameSkip = frame->SkipRendering; + + do + { + int32 timetime = (uint8)TLCS900h_interpret(); // This is sooo not right, but it's replicating the old behavior(which is necessary + // now since I've fixed the TLCS900h core and other places not to truncate cycle counts + // internally to 8-bits). Switch to the #if 0'd block of code once we fix cycle counts in the + // TLCS900h core(they're all sorts of messed up), and investigate if certain long + // instructions are interruptable(by interrupts) and later resumable, RE Rockman Battle + // & Fighters voice sample playback. + + //if(timetime > 255) + // printf("%d\n", timetime); + + // Note: Don't call updateTimers with a time/tick/cycle/whatever count greater than 255. + MeowMeow |= updateTimers(&surface, timetime); + + z80_runtime += timetime; + + while (z80_runtime > 0) + { + int z80rantime = Z80_RunOP(); + + if (z80rantime < 0) // Z80 inactive, so take up all run time! + { + z80_runtime = 0; + break; + } + + z80_runtime -= z80rantime << 1; + } + } while (!MeowMeow); + + frame->Cycles = ngpc_soundTS; + frame->Samples = MDFNNGPCSOUND_Flush(frame->SoundBuffer, 8192); + frame->Lagged = lagged; +} + +static MDFN_COLD bool Load(const uint8* romdata, int32 romlength) +{ + const uint64 fp_size = romlength; + + if (fp_size > 1024 * 1024 * 8) // 4MiB maximum ROM size, 2* to be a little tolerant of garbage. + return false; + //throw MDFN_Error(0, _("NGP/NGPC ROM image is too large.")); + + ngpc_rom.length = fp_size; + ngpc_rom.data = (uint8*)alloc_plain(ngpc_rom.length); + memcpy(ngpc_rom.data, romdata, romlength); + + rom_loaded(); + //if (!FLASH_LoadNV()) + // return false; + + //MDFNMP_Init(1024, 1024 * 1024 * 16 / 1024); + + NGPGfx = new NGPGFX_CLASS(); + + //MDFNGameInfo->fps = (uint32)((uint64)6144000 * 65536 * 256 / 515 / 198); // 3072000 * 2 * 10000 / 515 / 198 + + MDFNNGPCSOUND_Init(); + + //MDFNMP_AddRAM(16384, 0x4000, CPUExRAM); + + SetFRM(); // Set up fast read memory mapping + + bios_install(); + + //main_timeaccum = 0; + z80_runtime = 0; + + reset(); + + MDFNNGPC_SetSoundRate(44100); + return true; +} +} +using namespace MDFN_IEN_NGP; + +int main(void) +{ + return 0; +} + +EXPORT int LoadSystem(const uint8* rom, int romlength, int language) +{ + settings_language = language; + return Load(rom, romlength); +} + +EXPORT void SetLayers(int enable) // 1, 2, 4 bg,fg,sprites +{ + NGPGfx->SetLayerEnableMask(enable); +} + +EXPORT void HardReset() +{ + reset(); +} + +EXPORT void SetInputCallback(void (*callback)()) +{ + inputcallback = callback; +} + +EXPORT void SetCommsCallbacks(int (*read_cb)(uint8* buffer), int (*poll_cb)(uint8* buffer), void (*write_cb)(uint8 data)) +{ + comms_read_cb = read_cb; + comms_poll_cb = poll_cb; + comms_write_cb = write_cb; +} + +EXPORT void GetMemoryAreas(MemoryArea* m) +{ + m[0].Data = CPUExRAM; + m[0].Name = "RAM"; + m[0].Size = 16384; + m[0].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_PRIMARY | MEMORYAREA_FLAGS_WORDSIZE4; + + m[1].Data = ngpc_rom.data; + m[1].Name = "ROM"; + m[1].Size = ngpc_rom.length; + m[1].Flags = MEMORYAREA_FLAGS_WORDSIZE4; + + m[2].Data = ngpc_rom.orig_data; + m[2].Name = "ORIGINAL ROM"; + m[2].Size = ngpc_rom.length; + m[2].Flags = MEMORYAREA_FLAGS_WORDSIZE4; +} + +EXPORT bool HasSaveRam() +{ + return FLASH_IsModified(); +} + +EXPORT bool PutSaveRam(const uint8* data, uint32 length) +{ + return FLASH_LoadNV(data, length); +} + +EXPORT void GetSaveRam(void (*callback)(const uint8* data, uint32 length)) +{ + FLASH_SaveNV(callback); +} + diff --git a/waterbox/ngp/neopop.h b/waterbox/ngp/neopop.h new file mode 100644 index 0000000000..18ab2723da --- /dev/null +++ b/waterbox/ngp/neopop.h @@ -0,0 +1,178 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#ifndef __NEOPOP__ +#define __NEOPOP__ +//============================================================================= + +#include "defs.h" + +#include +#include +#include +#include + +#include "TLCS-900h/TLCS900h_disassemble.h" +#include "TLCS-900h/TLCS900h_interpret_dst.h" +#include "TLCS-900h/TLCS900h_interpret.h" +#include "TLCS-900h/TLCS900h_interpret_reg.h" +#include "TLCS-900h/TLCS900h_interpret_single.h" +#include "TLCS-900h/TLCS900h_interpret_src.h" +#include "TLCS-900h/TLCS900h_registers.h" + + +// I put the TLCS900h code in its own namespace, so it doesn't +// pollute the global namespace with all of its CARAZZZY short-named global variables. +// (I'm too lazy to clean up and turn it into an object :b) +using namespace TLCS900H; + +//============================================================================= + +namespace MDFN_IEN_NGP +{ + +//=========================== +// GCC specific +//=========================== + +#ifndef max +#define max(a,b) ((a)>(b)?(a):(b)) +#endif + +#ifndef min +#define min(a,b) ((a)<(b)?(a):(b)) +#endif + +//COLOURMODE +typedef enum +{ + COLOURMODE_GREYSCALE, + COLOURMODE_COLOUR, + COLOURMODE_AUTO +} +COLOURMODE; + +//RomInfo +typedef struct +{ + uint8* data; //Pointer to the rom data + uint8 *orig_data; // Original data(without flash writes during emulation; necessary for save states) + + uint32 length; //Length of the rom + + uint8 name[16]; //Null terminated string, holding the Game name +} +RomInfo; + +//RomHeader +typedef struct +{ + uint8 licence[28]; // 0x00 - 0x1B + uint8 startPC[4]; // 0x1C - 0x1F + uint8 catalog[2]; // 0x20 - 0x21 + uint8 subCatalog; // 0x22 + uint8 mode; // 0x23 + uint8 name[12]; // 0x24 - 0x2F + + uint8 reserved1[4]; // 0x30 - 0x33 + uint8 reserved2[4]; // 0x34 - 0x37 + uint8 reserved3[4]; // 0x38 - 0x3B + uint8 reserved4[4]; // 0x3C - 0x3F +} __attribute__((__packed__)) RomHeader; + +//============================================================================= + +//----------------------------------------------------------------------------- +// Core <--> System-Main Interface +//----------------------------------------------------------------------------- + + void reset(void); + +/* Fill the bios rom area with a bios. call once at program start */ + bool bios_install(void); + + extern RomInfo ngpc_rom; + + extern RomHeader* rom_header; + +/*! Emulate a single instruction with correct TLCS900h:Z80 timing */ + + void emulate(void); + +/*! Call this function when a rom has just been loaded, it will perform + the system independent actions required. */ + + void rom_loaded(void); + +/*! Tidy up the rom and free the resources used. */ + + void rom_unload(void); + + //========================================= + +/*! Used to generate a critical message for the user. After the message + has been displayed, the function should return. The message is not + necessarily a fatal error. */ + + void system_message(char* vaMessage,...); + +//----------------------------------------------------------------------------- +// Core <--> System-Graphics Interface +//----------------------------------------------------------------------------- + + // Physical screen dimensions +#define SCREEN_WIDTH 160 +#define SCREEN_HEIGHT 152 + + extern COLOURMODE system_colour; + + +//----------------------------------------------------------------------------- +// Core <--> System-IO Interface +//----------------------------------------------------------------------------- + +/*! Reads a byte from the other system. If no data is available or no + high-level communications have been established, then return FALSE. + If buffer is NULL, then no data is read, only status is returned */ + + bool system_comms_read(uint8* buffer); + + +/*! Peeks at any data from the other system. If no data is available or + no high-level communications have been established, then return FALSE. + If buffer is NULL, then no data is read, only status is returned */ + + bool system_comms_poll(uint8* buffer); + + +/*! Writes a byte from the other system. This function should block until + the data is written. USE RELIABLE COMMS! Data cannot be re-requested. */ + + void system_comms_write(uint8 data); + +void int_redo_icache(void); + +} + +#include "gfx.h" + +namespace MDFN_IEN_NGP +{ +extern NGPGFX_CLASS *NGPGfx; +extern uint8 NGPJoyLatch; +} + +using namespace MDFN_IEN_NGP; + +#endif diff --git a/waterbox/ngp/rom.cpp b/waterbox/ngp/rom.cpp new file mode 100644 index 0000000000..57f057d6fd --- /dev/null +++ b/waterbox/ngp/rom.cpp @@ -0,0 +1,114 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#include "neopop.h" +#include "flash.h" +#include "interrupt.h" +#include + +//============================================================================= + +namespace MDFN_IEN_NGP +{ + +RomInfo ngpc_rom; +RomHeader* rom_header; + +#define MATCH_CATALOG(c, s) (MDFN_de16lsb(rom_header->catalog) == (c) && rom_header->subCatalog == (s)) + +//============================================================================= +static void rom_hack(void) +{ + //============================= + // SPECIFIC ROM HACKS ! + //============================= + + //"Neo-Neo! V1.0 (PD)" + if (MATCH_CATALOG(0, 16)) + { + ngpc_rom.data[0x23] = 0x10; // Fix rom header + + MDFN_printf("HACK: \"Neo-Neo! V1.0 (PD)\"\n"); + } + + //"Cool Cool Jam SAMPLE (U)" + if (MATCH_CATALOG(4660, 161)) + { + ngpc_rom.data[0x23] = 0x10; // Fix rom header + + MDFN_printf("HACK: \"Cool Cool Jam SAMPLE (U)\"\n"); + } + + //"Dokodemo Mahjong (J)" + if (MATCH_CATALOG(51, 33)) + { + ngpc_rom.data[0x23] = 0x00; // Fix rom header + + MDFN_printf("HACK: \"Dokodemo Mahjong (J)\"\n"); + } +} + +//============================================================================= + +static void rom_display_header(void) +{ + MDFN_printf(_("Name: %s\n"), ngpc_rom.name); + MDFN_printf(_("System: ")); + + if(rom_header->mode & 0x10) + MDFN_printf(_("Color")); + else + MDFN_printf(_("Greyscale")); + + MDFN_printf("\n"); + + MDFN_printf(_("Catalog: %u (sub %u)\n"), + MDFN_de16lsb(rom_header->catalog), + rom_header->subCatalog); + + //Starting PC + MDFN_printf(_("Starting PC: 0x%06X\n"), MDFN_de32lsb(rom_header->startPC) & 0xFFFFFF); +} + +//============================================================================= + +//----------------------------------------------------------------------------- +// rom_loaded() +//----------------------------------------------------------------------------- +void rom_loaded(void) +{ + //Extract the header + rom_header = (RomHeader*)(ngpc_rom.data); + + //Rom Name + for(int i = 0; i < 12; i++) + { + if (rom_header->name[i] >= 32 && rom_header->name[i] < 128) + ngpc_rom.name[i] = rom_header->name[i]; + else + ngpc_rom.name[i] = ' '; + } + ngpc_rom.name[12] = 0; + + rom_hack(); //Apply a hack if required! + + rom_display_header(); + + ngpc_rom.orig_data = (uint8*)alloc_sealed(ngpc_rom.length); + memcpy(ngpc_rom.orig_data, ngpc_rom.data, ngpc_rom.length); +} + +} + +//============================================================================= diff --git a/waterbox/ngp/rtc.cpp b/waterbox/ngp/rtc.cpp new file mode 100644 index 0000000000..b4deb6f28d --- /dev/null +++ b/waterbox/ngp/rtc.cpp @@ -0,0 +1,70 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#include "neopop.h" +#include + +namespace MDFN_IEN_NGP +{ + +extern time_t frontend_time; + +static uint8 rtc_latch[7]; + +static void update_rtc_latch(void) +{ + uint8 low, high; + + //Get the system time + const struct tm* localTime = gmtime(&frontend_time); + + low = localTime->tm_year - 100; + high = low; //Years + rtc_latch[0x00] = ((high / 10) << 4) | (low % 10); + + low = localTime->tm_mon + 1; + high = low; //Months + rtc_latch[0x01] = ((high / 10) << 4) | (low % 10); + + low = localTime->tm_mday; + high = low; //Days + rtc_latch[0x02] = ((high / 10) << 4) | (low % 10); + + low = localTime->tm_hour; + high = low; //Hours + rtc_latch[0x03] = ((high / 10) << 4) | (low % 10); + + low = localTime->tm_min; + high = low; //Minutes + rtc_latch[0x04] = ((high / 10) << 4) | (low % 10); + + low = localTime->tm_sec; + high = low; //Seconds + rtc_latch[0x05] = ((high / 10) << 4) | (low % 10); + + rtc_latch[0x06] = ((rtc_latch[0x00] % 4) << 4) | (localTime->tm_wday & 0x0F); +} + +uint8 rtc_read8(uint32 address) +{ + if (address >= 0x0091 && address <= 0x0097) + { + if (address == 0x0091) + update_rtc_latch(); + + return (rtc_latch[address - 0x0091]); + } + return (0); +} +} diff --git a/waterbox/ngp/rtc.h b/waterbox/ngp/rtc.h new file mode 100644 index 0000000000..871dd29959 --- /dev/null +++ b/waterbox/ngp/rtc.h @@ -0,0 +1,11 @@ +#ifndef __NGP_RTC_H +#define __NGP_RTC_H + +namespace MDFN_IEN_NGP +{ + +uint8 rtc_read8(uint32 address); + +} + +#endif diff --git a/waterbox/ngp/sound.cpp b/waterbox/ngp/sound.cpp new file mode 100644 index 0000000000..d14dd248f8 --- /dev/null +++ b/waterbox/ngp/sound.cpp @@ -0,0 +1,114 @@ +/* Mednafen - Multi-system Emulator + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "neopop.h" +#include "sound.h" + +#include "sound/Blip_Buffer.h" +#include "T6W28_Apu.h" +#include "sound/Stereo_Buffer.h" + +namespace MDFN_IEN_NGP +{ + +static T6W28_Apu apu; + +static Stereo_Buffer st_buf; + +static uint8 LastDACLeft = 0, LastDACRight = 0; +static uint8 CurrentDACLeft = 0, CurrentDACRight = 0; + +typedef Blip_Synth Synth; +static Synth synth; +extern int32 ngpc_soundTS; +static bool schipenable = 0; + +void MDFNNGPCSOUND_SetEnable(bool set) +{ + schipenable = set; + if (!set) + apu.reset(); +} + +void Write_SoundChipLeft(uint8 data) +{ + if (schipenable) + apu.write_data_left(ngpc_soundTS >> 1, data); +} + +void Write_SoundChipRight(uint8 data) +{ + if (schipenable) + apu.write_data_right(ngpc_soundTS >> 1, data); +} + +void dac_write_left(uint8 data) +{ + CurrentDACLeft = data; + + synth.offset_inline(ngpc_soundTS >> 1, CurrentDACLeft - LastDACLeft, st_buf.left()); + + LastDACLeft = data; +} + +void dac_write_right(uint8 data) +{ + CurrentDACRight = data; + + synth.offset_inline(ngpc_soundTS >> 1, CurrentDACRight - LastDACRight, st_buf.right()); + + LastDACRight = data; +} + +int32 MDFNNGPCSOUND_Flush(int16 *SoundBuf, const int32 MaxSoundFrames) +{ + int32 FrameCount = 0; + + apu.end_frame(ngpc_soundTS >> 1); + + st_buf.end_frame(ngpc_soundTS >> 1); + + if (SoundBuf) + FrameCount = st_buf.read_samples(SoundBuf, MaxSoundFrames * 2) / 2; + else + st_buf.clear(); + + return (FrameCount); +} + +static void RedoVolume(void) +{ + apu.output(st_buf.center(), st_buf.left(), st_buf.right()); + apu.volume(0.30); + synth.volume(0.40); +} + +void MDFNNGPCSOUND_Init(void) +{ + MDFNNGPC_SetSoundRate(0); + st_buf.clock_rate((long)(3072000)); + + RedoVolume(); + st_buf.bass_freq(20); +} + +bool MDFNNGPC_SetSoundRate(uint32 rate) +{ + st_buf.set_sample_rate(rate ? rate : 44100, 60); + return (TRUE); +} +} diff --git a/waterbox/ngp/sound.h b/waterbox/ngp/sound.h new file mode 100644 index 0000000000..bde71033c5 --- /dev/null +++ b/waterbox/ngp/sound.h @@ -0,0 +1,34 @@ +//--------------------------------------------------------------------------- +// NEOPOP : Emulator as in Dreamland +// +// Copyright (c) 2001-2002 by neopop_uk +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. See also the license.txt file for +// additional informations. +//--------------------------------------------------------------------------- + +#ifndef __NEOPOP_SOUND__ +#define __NEOPOP_SOUND__ + +namespace MDFN_IEN_NGP +{ + +void Write_SoundChipLeft(uint8 data); +void Write_SoundChipRight(uint8 data); + +void dac_write_left(uint8); +void dac_write_right(uint8); + +int32 MDFNNGPCSOUND_Flush(int16 *SoundBuf, const int32 MaxSoundFrames); +void MDFNNGPCSOUND_Init(void) MDFN_COLD; +bool MDFNNGPC_SetSoundRate(uint32 rate); +void MDFNNGPCSOUND_SetEnable(bool set); + +} + +#endif diff --git a/waterbox/ngp/sound/Blip_Buffer.cpp b/waterbox/ngp/sound/Blip_Buffer.cpp new file mode 100644 index 0000000000..f04a1fc599 --- /dev/null +++ b/waterbox/ngp/sound/Blip_Buffer.cpp @@ -0,0 +1,457 @@ +// Blip_Buffer 0.4.1. http://www.slack.net/~ant/ + +#include "Blip_Buffer.h" + +#include +#include +#include +#include +#include +#include + +/* Copyright (C) 2003-2006 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifdef BLARGG_ENABLE_OPTIMIZER + #include BLARGG_ENABLE_OPTIMIZER +#endif + +int const silent_buf_size = 1; // size used for Silent_Blip_Buffer + +Blip_Buffer::Blip_Buffer() +{ + factor_ = (blip_u64)ULLONG_MAX; + offset_ = 0; + buffer_ = 0; + buffer_size_ = 0; + sample_rate_ = 0; + reader_accum_ = 0; + bass_shift_ = 0; + clock_rate_ = 0; + bass_freq_ = 16; + length_ = 0; + + // assumptions code makes about implementation-defined features + #ifndef NDEBUG + // right shift of negative value preserves sign + buf_t_ i = -0x7FFFFFFE; + assert( (i >> 1) == -0x3FFFFFFF ); + + // casting to short truncates to 16 bits and sign-extends + i = 0x18000; + assert( (short) i == -0x8000 ); + #endif +} + +Blip_Buffer::~Blip_Buffer() +{ + if ( buffer_size_ != silent_buf_size ) + free( buffer_ ); +} + +Silent_Blip_Buffer::Silent_Blip_Buffer() +{ + factor_ = 0; + buffer_ = buf; + buffer_size_ = silent_buf_size; + memset( buf, 0, sizeof buf ); // in case machine takes exception for signed overflow +} + +void Blip_Buffer::clear( int entire_buffer ) +{ + offset_ = 0; + reader_accum_ = 0; + modified_ = 0; + if ( buffer_ ) + { + long count = (entire_buffer ? buffer_size_ : samples_avail()); + memset( buffer_, 0, (count + blip_buffer_extra_) * sizeof (buf_t_) ); + } +} + +Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec ) +{ + if ( buffer_size_ == silent_buf_size ) + { + assert( 0 ); + return "Internal (tried to resize Silent_Blip_Buffer)"; + } + + // start with maximum length that resampled time can represent + blip_s64 new_size = (ULLONG_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64; + + // simple safety check, since code elsewhere may not be safe for sizes approaching (2 ^ 31). + if(new_size > ((1LL << 30) - 1)) + new_size = (1LL << 30) - 1; + + if ( msec != blip_max_length ) + { + blip_s64 s = ((blip_s64)new_rate * (msec + 1) + 999) / 1000; + if ( s < new_size ) + new_size = s; + else + assert( 0 ); // fails if requested buffer length exceeds limit + } + + if ( buffer_size_ != new_size ) + { + void* p = realloc( buffer_, (new_size + blip_buffer_extra_) * sizeof *buffer_ ); + if ( !p ) + return "Out of memory"; + + //if(new_size > buffer_size_) + // memset(buffer_ + buffer_size_, 0, (new_size + blip_buffer_extra_) * sizeof *buffer_ + + buffer_ = (buf_t_*) p; + } + + buffer_size_ = new_size; + assert( buffer_size_ != silent_buf_size ); + + // update things based on the sample rate + sample_rate_ = new_rate; + length_ = new_size * 1000 / new_rate - 1; + if ( msec ) + assert( length_ == msec ); // ensure length is same as that passed in + if ( clock_rate_ ) + clock_rate( clock_rate_ ); + bass_freq( bass_freq_ ); + + clear(); + + return 0; // success +} + +blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const +{ + double ratio = (double) sample_rate_ / rate; + blip_s64 factor = (blip_s64) floor( ratio * (1LL << BLIP_BUFFER_ACCURACY) + 0.5 ); + assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio is too large + return (blip_resampled_time_t) factor; +} + +void Blip_Buffer::bass_freq( int freq ) +{ + bass_freq_ = freq; + int shift = 31; + if ( freq > 0 ) + { + shift = 13; + long f = (freq << 16) / sample_rate_; + while ( (f >>= 1) && --shift ) { } + } + bass_shift_ = shift; + //printf("%d\n", bass_shift_); +} + +void Blip_Buffer::end_frame( blip_time_t t ) +{ + offset_ += t * factor_; + assert( samples_avail() <= (long) buffer_size_ ); // time outside buffer length +} + +void Blip_Buffer::remove_silence( long count ) +{ + assert( count <= samples_avail() ); // tried to remove more samples than available + offset_ -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY; +} + +long Blip_Buffer::count_samples( blip_time_t t ) const +{ + unsigned long last_sample = resampled_time( t ) >> BLIP_BUFFER_ACCURACY; + unsigned long first_sample = offset_ >> BLIP_BUFFER_ACCURACY; + return (long) (last_sample - first_sample); +} + +blip_time_t Blip_Buffer::count_clocks( long count ) const +{ + if ( !factor_ ) + { + assert( 0 ); // sample rate and clock rates must be set first + return 0; + } + + if ( count > buffer_size_ ) + count = buffer_size_; + blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY; + return (blip_time_t) ((time - offset_ + factor_ - 1) / factor_); +} + +void Blip_Buffer::remove_samples( long count ) +{ + if ( count ) + { + remove_silence( count ); + + // copy remaining samples to beginning and clear old samples + long remain = samples_avail() + blip_buffer_extra_; + memmove( buffer_, buffer_ + count, remain * sizeof *buffer_ ); + memset( buffer_ + remain, 0, count * sizeof *buffer_ ); + } +} + +// Blip_Synth_ + +Blip_Synth_Fast_::Blip_Synth_Fast_() +{ + buf = 0; + last_amp = 0; + delta_factor = 0; +} + +void Blip_Synth_Fast_::volume_unit( double new_unit ) +{ + delta_factor = int (new_unit * (1L << blip_sample_bits) + 0.5); +} + +#if !BLIP_BUFFER_FAST + +Blip_Synth_::Blip_Synth_( short* p, int w ) : + impulses( p ), + width( w ) +{ + volume_unit_ = 0.0; + kernel_unit = 0; + buf = 0; + last_amp = 0; + delta_factor = 0; +} + +#undef PI +#define PI 3.1415926535897932384626433832795029 + +static void gen_sinc( float* out, int count, double oversample, double treble, double cutoff ) +{ + if ( cutoff >= 0.999 ) + cutoff = 0.999; + + if ( treble < -300.0 ) + treble = -300.0; + if ( treble > 5.0 ) + treble = 5.0; + + double const maxh = 4096.0; + double const rolloff = pow( 10.0, 1.0 / (maxh * 20.0) * treble / (1.0 - cutoff) ); + double const pow_a_n = pow( rolloff, maxh - maxh * cutoff ); + double const to_angle = PI / 2 / maxh / oversample; + for ( int i = 0; i < count; i++ ) + { + double angle = ((i - count) * 2 + 1) * to_angle; + double c = rolloff * cos( (maxh - 1.0) * angle ) - cos( maxh * angle ); + double cos_nc_angle = cos( maxh * cutoff * angle ); + double cos_nc1_angle = cos( (maxh * cutoff - 1.0) * angle ); + double cos_angle = cos( angle ); + + c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle; + double d = 1.0 + rolloff * (rolloff - cos_angle - cos_angle); + double b = 2.0 - cos_angle - cos_angle; + double a = 1.0 - cos_angle - cos_nc_angle + cos_nc1_angle; + + out [i] = (float) ((a * d + c * b) / (b * d)); // a / b + c / d + } +} + +void blip_eq_t::generate( float* out, int count ) const +{ + // lower cutoff freq for narrow kernels with their wider transition band + // (8 points->1.49, 16 points->1.15) + double oversample = blip_res * 2.25 / count + 0.85; + double half_rate = sample_rate * 0.5; + if ( cutoff_freq ) + oversample = half_rate / cutoff_freq; + double cutoff = rolloff_freq * oversample / half_rate; + + gen_sinc( out, count, blip_res * oversample, treble, cutoff ); + + // apply (half of) hamming window + double to_fraction = PI / (count - 1); + for ( int i = count; i--; ) + out [i] *= 0.54f - 0.46f * (float) cos( i * to_fraction ); +} + +void Blip_Synth_::adjust_impulse() +{ + // sum pairs for each phase and add error correction to end of first half + int const size = impulses_size(); + for ( int p = blip_res; p-- >= blip_res / 2; ) + { + int p2 = blip_res - 2 - p; + long error = kernel_unit; + for ( int i = 1; i < size; i += blip_res ) + { + error -= impulses [i + p ]; + error -= impulses [i + p2]; + } + if ( p == p2 ) + error /= 2; // phase = 0.5 impulse uses same half for both sides + impulses [size - blip_res + p] += (short) error; + //printf( "error: %ld\n", error ); + } + + //for ( int i = blip_res; i--; printf( "\n" ) ) + // for ( int j = 0; j < width / 2; j++ ) + // printf( "%5ld,", impulses [j * blip_res + i + 1] ); +} + +void Blip_Synth_::treble_eq( blip_eq_t const& eq ) +{ + float fimpulse [blip_res / 2 * (blip_widest_impulse_ - 1) + blip_res * 2]; + + int const half_size = blip_res / 2 * (width - 1); + eq.generate( &fimpulse [blip_res], half_size ); + + int i; + + // need mirror slightly past center for calculation + for ( i = blip_res; i--; ) + fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i]; + + // starts at 0 + for ( i = 0; i < blip_res; i++ ) + fimpulse [i] = 0.0f; + + // find rescale factor + double total = 0.0; + for ( i = 0; i < half_size; i++ ) + total += fimpulse [blip_res + i]; + + //double const base_unit = 44800.0 - 128 * 18; // allows treble up to +0 dB + //double const base_unit = 37888.0; // allows treble to +5 dB + double const base_unit = 32768.0; // necessary for blip_unscaled to work + double rescale = base_unit / 2 / total; + kernel_unit = (long) base_unit; + + // integrate, first difference, rescale, convert to int + double sum = 0.0; + double next = 0.0; + int const impulses_size_local = this->impulses_size(); + for ( i = 0; i < impulses_size_local; i++ ) + { + impulses [i] = (short) floor( (next - sum) * rescale + 0.5 ); + sum += fimpulse [i]; + next += fimpulse [i + blip_res]; + } + adjust_impulse(); + + // volume might require rescaling + double vol = volume_unit_; + if ( vol ) + { + volume_unit_ = 0.0; + volume_unit( vol ); + } +} + +void Blip_Synth_::volume_unit( double new_unit ) +{ + if ( new_unit != volume_unit_ ) + { + // use default eq if it hasn't been set yet + if ( !kernel_unit ) + treble_eq( -8.0 ); + + volume_unit_ = new_unit; + double factor = new_unit * (1L << blip_sample_bits) / kernel_unit; + + if ( factor > 0.0 ) + { + int shift = 0; + + // if unit is really small, might need to attenuate kernel + while ( factor < 2.0 ) + { + shift++; + factor *= 2.0; + } + + if ( shift ) + { + kernel_unit >>= shift; + assert( kernel_unit > 0 ); // fails if volume unit is too low + + // keep values positive to avoid round-towards-zero of sign-preserving + // right shift for negative values + long offset = 0x8000 + (1 << (shift - 1)); + long offset2 = 0x8000 >> shift; + for ( int i = impulses_size(); i--; ) + impulses [i] = (short) (((impulses [i] + offset) >> shift) - offset2); + adjust_impulse(); + } + } + delta_factor = (int) floor( factor + 0.5 ); + //printf( "delta_factor: %d, kernel_unit: %d\n", delta_factor, kernel_unit ); + } +} +#endif + +long Blip_Buffer::read_samples( blip_sample_t* BLIP_RESTRICT out, long max_samples, int stereo ) +{ + long count = samples_avail(); + if ( count > max_samples ) + count = max_samples; + + if ( count ) + { + int const bass = BLIP_READER_BASS( *this ); + BLIP_READER_BEGIN( reader, *this ); + + if ( !stereo ) + { + for ( blip_long n = count; n; --n ) + { + blip_long s = BLIP_READER_READ( reader ); + if ( (blip_sample_t) s != s ) + s = 0x7FFF - (s >> 24); + *out++ = (blip_sample_t) s; + BLIP_READER_NEXT( reader, bass ); + } + } + else + { + for ( blip_long n = count; n; --n ) + { + blip_long s = BLIP_READER_READ( reader ); + if ( (blip_sample_t) s != s ) + s = 0x7FFF - (s >> 24); + *out = (blip_sample_t) s; + out += 2; + BLIP_READER_NEXT( reader, bass ); + } + } + BLIP_READER_END( reader, *this ); + + remove_samples( count ); + } + return count; +} + +void Blip_Buffer::mix_samples( blip_sample_t const* in, long count ) +{ + if ( buffer_size_ == silent_buf_size ) + { + assert( 0 ); + return; + } + + buf_t_* out = buffer_ + (offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2; + + int const sample_shift = blip_sample_bits - 16; + int prev = 0; + while ( count-- ) + { + blip_long s = (blip_long) *in++ << sample_shift; + *out += s - prev; + prev = s; + ++out; + } + *out -= prev; +} + diff --git a/waterbox/ngp/sound/Blip_Buffer.h b/waterbox/ngp/sound/Blip_Buffer.h new file mode 100644 index 0000000000..a8e90ee053 --- /dev/null +++ b/waterbox/ngp/sound/Blip_Buffer.h @@ -0,0 +1,498 @@ +// Band-limited sound synthesis buffer +// Various changes and hacks for use in Mednafen. + +#ifdef __GNUC__ + #define blip_inline inline __attribute__((always_inline)) +#else + #define blip_inline inline +#endif + +#include +#include + +// Blip_Buffer 0.4.1 +#ifndef BLIP_BUFFER_H +#define BLIP_BUFFER_H + +// Internal +typedef int32_t blip_long; +typedef uint32_t blip_ulong; +typedef int64_t blip_s64; +typedef uint64_t blip_u64; + +// Time unit at source clock rate +typedef blip_long blip_time_t; + +// Output samples are 16-bit signed, with a range of -32768 to 32767 +typedef short blip_sample_t; +enum { blip_sample_max = 32767 }; + +class Blip_Buffer { +public: + typedef const char* blargg_err_t; + + // Set output sample rate and buffer length in milliseconds (1/1000 sec, defaults + // to 1/4 second), then clear buffer. Returns NULL on success, otherwise if there + // isn't enough memory, returns error without affecting current buffer setup. + blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 ); + + // Set number of source time units per second + void clock_rate( long ); + + // End current time frame of specified duration and make its samples available + // (along with any still-unread samples) for reading with read_samples(). Begins + // a new time frame at the end of the current frame. + void end_frame( blip_time_t time ); + + // Read at most 'max_samples' out of buffer into 'dest', removing them from from + // the buffer. Returns number of samples actually read and removed. If stereo is + // true, increments 'dest' one extra time after writing each sample, to allow + // easy interleving of two channels into a stereo output buffer. + long read_samples( blip_sample_t* dest, long max_samples, int stereo = 0 ); + +// Additional optional features + + // Current output sample rate + long sample_rate() const; + + // Length of buffer, in milliseconds + int length() const; + + // Number of source time units per second + long clock_rate() const; + + // Set frequency high-pass filter frequency, where higher values reduce bass more + void bass_freq( int frequency ); + + // Number of samples delay from synthesis to samples read out + int output_latency() const; + + // Remove all available samples and clear buffer to silence. If 'entire_buffer' is + // false, just clears out any samples waiting rather than the entire buffer. + void clear( int entire_buffer = 1 ); + + // Number of samples available for reading with read_samples() + long samples_avail() const; + + // Remove 'count' samples from those waiting to be read + void remove_samples( long count ); + +// Experimental features + + // Count number of clocks needed until 'count' samples will be available. + // If buffer can't even hold 'count' samples, returns number of clocks until + // buffer becomes full. + blip_time_t count_clocks( long count ) const; + + // Number of raw samples that can be mixed within frame of specified duration. + long count_samples( blip_time_t duration ) const; + + // Mix 'count' samples from 'buf' into buffer. + void mix_samples( blip_sample_t const* buf, long count ); + + // not documented yet + void set_modified() { modified_ = 1; } + int clear_modified() { int b = modified_; modified_ = 0; return b; } + typedef blip_u64 blip_resampled_time_t; + void remove_silence( long count ); + blip_resampled_time_t resampled_duration( int t ) const { return t * factor_; } + blip_resampled_time_t resampled_time( blip_time_t t ) const { return t * factor_ + offset_; } + blip_resampled_time_t clock_rate_factor( long clock_rate ) const; +public: + Blip_Buffer(); + ~Blip_Buffer(); + + // Deprecated + typedef blip_resampled_time_t resampled_time_t; + blargg_err_t sample_rate( long r ) { return set_sample_rate( r ); } + blargg_err_t sample_rate( long r, int msec ) { return set_sample_rate( r, msec ); } +private: + // noncopyable + Blip_Buffer( const Blip_Buffer& ); + Blip_Buffer& operator = ( const Blip_Buffer& ); +public: + typedef blip_time_t buf_t_; + blip_u64 factor_; + blip_resampled_time_t offset_; + buf_t_* buffer_; + blip_long buffer_size_; + blip_long reader_accum_; + int bass_shift_; +private: + long sample_rate_; + long clock_rate_; + int bass_freq_; + int length_; + int modified_; + friend class Blip_Reader; +}; + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#define BLIP_BUFFER_ACCURACY 32 +#define BLIP_PHASE_BITS 8 + +// Number of bits in resample ratio fraction. Higher values give a more accurate ratio +// but reduce maximum buffer size. +//#ifndef BLIP_BUFFER_ACCURACY +// #define BLIP_BUFFER_ACCURACY 16 +//#endif + +// Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in +// noticeable broadband noise when synthesizing high frequency square waves. +// Affects size of Blip_Synth objects since they store the waveform directly. +//#ifndef BLIP_PHASE_BITS +// #if BLIP_BUFFER_FAST +// #define BLIP_PHASE_BITS 8 +// #else +// #define BLIP_PHASE_BITS 6 +// #endif +//#endif + + // Internal + typedef blip_u64 blip_resampled_time_t; + int const blip_widest_impulse_ = 16; + int const blip_buffer_extra_ = blip_widest_impulse_ + 2; + int const blip_res = 1 << BLIP_PHASE_BITS; + class blip_eq_t; + + class Blip_Synth_Fast_ { + public: + Blip_Buffer* buf; + int last_amp; + int delta_factor; + + void volume_unit( double ); + Blip_Synth_Fast_(); + void treble_eq( blip_eq_t const& ) { } + }; + + class Blip_Synth_ { + public: + Blip_Buffer* buf; + int last_amp; + int delta_factor; + + void volume_unit( double ); + Blip_Synth_( short* impulses, int width ); + void treble_eq( blip_eq_t const& ); + private: + double volume_unit_; + short* const impulses; + int const width; + blip_long kernel_unit; + int impulses_size() const { return blip_res / 2 * width + 1; } + void adjust_impulse(); + }; + +// Quality level. Start with blip_good_quality. +const int blip_med_quality = 8; +const int blip_good_quality = 12; +const int blip_high_quality = 16; + +// Range specifies the greatest expected change in amplitude. Calculate it +// by finding the difference between the maximum and minimum expected +// amplitudes (max - min). +template +class Blip_Synth { +public: + // Set overall volume of waveform + void volume( double v ) { impl.volume_unit( v * (1.0 / (range < 0 ? -range : range)) ); } + + // Configure low-pass filter (see blip_buffer.txt) + void treble_eq( blip_eq_t const& eq ) { impl.treble_eq( eq ); } + + // Get/set Blip_Buffer used for output + Blip_Buffer* output() const { return impl.buf; } + void output( Blip_Buffer* b ) { impl.buf = b; impl.last_amp = 0; } + + // Update amplitude of waveform at given time. Using this requires a separate + // Blip_Synth for each waveform. + void update( blip_time_t time, int amplitude ); + +// Low-level interface + + // Add an amplitude transition of specified delta, optionally into specified buffer + // rather than the one set with output(). Delta can be positive or negative. + // The actual change in amplitude is delta * (volume / range) + void offset( blip_time_t, int delta, Blip_Buffer* ) const; + void offset( blip_time_t t, int delta ) const { offset( t, delta, impl.buf ); } + + // Works directly in terms of fractional output samples. Contact author for more info. + void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const; + + // Same as offset(), except code is inlined for higher performance + void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const { + offset_resampled( t * buf->factor_ + buf->offset_, delta, buf ); + } + void offset_inline( blip_time_t t, int delta ) const { + offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf ); + } + +private: +#if BLIP_BUFFER_FAST + Blip_Synth_Fast_ impl; +#else + Blip_Synth_ impl; + typedef short imp_t; + imp_t impulses [blip_res * (quality / 2) + 1]; +public: + Blip_Synth() : impl( impulses, quality ) { } +#endif +}; + +// Low-pass equalization parameters +class blip_eq_t { +public: + // Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce + // treble, small positive values (0 to 5.0) increase treble. + blip_eq_t( double treble_db = 0 ); + + // See blip_buffer.txt + blip_eq_t( double treble, long rolloff_freq, long sample_rate, long cutoff_freq = 0 ); + +private: + double treble; + long rolloff_freq; + long sample_rate; + long cutoff_freq; + void generate( float* out, int count ) const; + friend class Blip_Synth_; +}; + +int const blip_sample_bits = 30; + +// Dummy Blip_Buffer to direct sound output to, for easy muting without +// having to stop sound code. +class Silent_Blip_Buffer : public Blip_Buffer { + buf_t_ buf [blip_buffer_extra_ + 1]; +public: + // The following cannot be used (an assertion will fail if attempted): + blargg_err_t set_sample_rate( long samples_per_sec, int msec_length ); + blip_time_t count_clocks( long count ) const; + void mix_samples( blip_sample_t const* buf, long count ); + + Silent_Blip_Buffer(); +}; + + #if defined (__GNUC__) || _MSC_VER >= 1100 + #define BLIP_RESTRICT __restrict + #else + #define BLIP_RESTRICT + #endif + +// Optimized reading from Blip_Buffer, for use in custom sample output + +// Begin reading from buffer. Name should be unique to the current block. +#define BLIP_READER_BEGIN( name, blip_buffer ) \ + const Blip_Buffer::buf_t_* BLIP_RESTRICT name##_reader_buf = (blip_buffer).buffer_;\ + blip_long name##_reader_accum = (blip_buffer).reader_accum_ + +// Get value to pass to BLIP_READER_NEXT() +#define BLIP_READER_BASS( blip_buffer ) ((blip_buffer).bass_shift_) + +// Constant value to use instead of BLIP_READER_BASS(), for slightly more optimal +// code at the cost of having no bass control +int const blip_reader_default_bass = 9; + +// Current sample +#define BLIP_READER_READ( name ) (name##_reader_accum >> (blip_sample_bits - 16)) + +// Current raw sample in full internal resolution +#define BLIP_READER_READ_RAW( name ) (name##_reader_accum) + +// Advance to next sample +#define BLIP_READER_NEXT( name, bass ) \ + (void) (name##_reader_accum += *name##_reader_buf++ - (name##_reader_accum >> (bass))) + +// End reading samples from buffer. The number of samples read must now be removed +// using Blip_Buffer::remove_samples(). +#define BLIP_READER_END( name, blip_buffer ) \ + (void) ((blip_buffer).reader_accum_ = name##_reader_accum) + + +// Compatibility with older version +const long blip_unscaled = 65535; +const int blip_low_quality = blip_med_quality; +const int blip_best_quality = blip_high_quality; + +// Deprecated; use BLIP_READER macros as follows: +// Blip_Reader r; r.begin( buf ); -> BLIP_READER_BEGIN( r, buf ); +// int bass = r.begin( buf ) -> BLIP_READER_BEGIN( r, buf ); int bass = BLIP_READER_BASS( buf ); +// r.read() -> BLIP_READER_READ( r ) +// r.read_raw() -> BLIP_READER_READ_RAW( r ) +// r.next( bass ) -> BLIP_READER_NEXT( r, bass ) +// r.next() -> BLIP_READER_NEXT( r, blip_reader_default_bass ) +// r.end( buf ) -> BLIP_READER_END( r, buf ) +class Blip_Reader { +public: + int begin( Blip_Buffer& ); + blip_long read() const { return accum >> (blip_sample_bits - 16); } + blip_long read_raw() const { return accum; } + void next( int bass_shift = 9 ) { accum += *buf++ - (accum >> bass_shift); } + void end( Blip_Buffer& b ) { b.reader_accum_ = accum; } + +private: + const Blip_Buffer::buf_t_* buf; + blip_long accum; +}; + +// End of public interface + +#include + +template +blip_inline void Blip_Synth::offset_resampled( blip_resampled_time_t time, + int delta, Blip_Buffer* blip_buf ) const +{ + // Fails if time is beyond end of Blip_Buffer, due to a bug in caller code or the + // need for a longer buffer as set by set_sample_rate(). + assert( (blip_long) (time >> BLIP_BUFFER_ACCURACY) < blip_buf->buffer_size_ ); + delta *= impl.delta_factor; + blip_long* BLIP_RESTRICT buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY); + int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1)); + +#if BLIP_BUFFER_FAST + blip_long left = buf [0] + delta; + + // Kind of crappy, but doing shift after multiply results in overflow. + // Alternate way of delaying multiply by delta_factor results in worse + // sub-sample resolution. + blip_long right = (delta >> BLIP_PHASE_BITS) * phase; + left -= right; + right += buf [1]; + + buf [0] = left; + buf [1] = right; +#else + + int const fwd = (blip_widest_impulse_ - quality) / 2; + int const rev = fwd + quality - 2; + int const mid = quality / 2 - 1; + + imp_t const* BLIP_RESTRICT imp = impulses + blip_res - phase; + + #if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \ + defined (__x86_64__) || defined (__ia64__) || defined (__i386__) + + // straight forward implementation resulted in better code on GCC for x86 + + #define ADD_IMP( out, in ) \ + buf [out] += (blip_long) imp [blip_res * (in)] * delta + + #define BLIP_FWD( i ) {\ + ADD_IMP( fwd + i, i );\ + ADD_IMP( fwd + 1 + i, i + 1 );\ + } + #define BLIP_REV( r ) {\ + ADD_IMP( rev - r, r + 1 );\ + ADD_IMP( rev + 1 - r, r );\ + } + + BLIP_FWD( 0 ) + if ( quality > 8 ) BLIP_FWD( 2 ) + if ( quality > 12 ) BLIP_FWD( 4 ) + { + ADD_IMP( fwd + mid - 1, mid - 1 ); + ADD_IMP( fwd + mid , mid ); + imp = impulses + phase; + } + if ( quality > 12 ) BLIP_REV( 6 ) + if ( quality > 8 ) BLIP_REV( 4 ) + BLIP_REV( 2 ) + + ADD_IMP( rev , 1 ); + ADD_IMP( rev + 1, 0 ); + + #else + + // for RISC processors, help compiler by reading ahead of writes + + #define BLIP_FWD( i ) {\ + blip_long t0 = i0 * delta + buf [fwd + i];\ + blip_long t1 = imp [blip_res * (i + 1)] * delta + buf [fwd + 1 + i];\ + i0 = imp [blip_res * (i + 2)];\ + buf [fwd + i] = t0;\ + buf [fwd + 1 + i] = t1;\ + } + #define BLIP_REV( r ) {\ + blip_long t0 = i0 * delta + buf [rev - r];\ + blip_long t1 = imp [blip_res * r] * delta + buf [rev + 1 - r];\ + i0 = imp [blip_res * (r - 1)];\ + buf [rev - r] = t0;\ + buf [rev + 1 - r] = t1;\ + } + + blip_long i0 = *imp; + BLIP_FWD( 0 ) + if ( quality > 8 ) BLIP_FWD( 2 ) + if ( quality > 12 ) BLIP_FWD( 4 ) + { + blip_long t0 = i0 * delta + buf [fwd + mid - 1]; + blip_long t1 = imp [blip_res * mid] * delta + buf [fwd + mid ]; + imp = impulses + phase; + i0 = imp [blip_res * mid]; + buf [fwd + mid - 1] = t0; + buf [fwd + mid ] = t1; + } + if ( quality > 12 ) BLIP_REV( 6 ) + if ( quality > 8 ) BLIP_REV( 4 ) + BLIP_REV( 2 ) + + blip_long t0 = i0 * delta + buf [rev ]; + blip_long t1 = *imp * delta + buf [rev + 1]; + buf [rev ] = t0; + buf [rev + 1] = t1; + #endif + +#endif +} + +#undef BLIP_FWD +#undef BLIP_REV + +template +#if BLIP_BUFFER_FAST + blip_inline +#endif +void Blip_Synth::offset( blip_time_t t, int delta, Blip_Buffer* buf ) const +{ + offset_resampled( t * buf->factor_ + buf->offset_, delta, buf ); +} + +template +#if BLIP_BUFFER_FAST + blip_inline +#endif +void Blip_Synth::update( blip_time_t t, int amp ) +{ + int delta = amp - impl.last_amp; + impl.last_amp = amp; + offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf ); +} + +blip_inline blip_eq_t::blip_eq_t( double t ) : + treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), cutoff_freq( 0 ) { } +blip_inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) : + treble( t ), rolloff_freq( rf ), sample_rate( sr ), cutoff_freq( cf ) { } + +blip_inline int Blip_Buffer::length() const { return length_; } +blip_inline long Blip_Buffer::samples_avail() const { return (long) (offset_ >> BLIP_BUFFER_ACCURACY); } +blip_inline long Blip_Buffer::sample_rate() const { return sample_rate_; } +blip_inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; } +blip_inline long Blip_Buffer::clock_rate() const { return clock_rate_; } +blip_inline void Blip_Buffer::clock_rate( long cps ) { factor_ = clock_rate_factor( clock_rate_ = cps ); } + +blip_inline int Blip_Reader::begin( Blip_Buffer& blip_buf ) +{ + buf = blip_buf.buffer_; + accum = blip_buf.reader_accum_; + return blip_buf.bass_shift_; +} + +int const blip_max_length = 0; +int const blip_default_length = 250; + +#endif diff --git a/waterbox/ngp/sound/Stereo_Buffer.cpp b/waterbox/ngp/sound/Stereo_Buffer.cpp new file mode 100644 index 0000000000..6e65464685 --- /dev/null +++ b/waterbox/ngp/sound/Stereo_Buffer.cpp @@ -0,0 +1,146 @@ + +// Blip_Buffer 0.3.0. http://www.slack.net/~ant/nes-emu/ + +#include "Stereo_Buffer.h" + +/* Library Copyright (C) 2004 Shay Green. Blip_Buffer is free software; +you can redistribute it and/or modify it under the terms of the GNU +General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. +Stereo_Buffer is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. You should have received a copy of the GNU General +Public License along with Stereo_Buffer; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +Stereo_Buffer::Stereo_Buffer() { + stereo_added = false; + was_stereo = false; +} + +Stereo_Buffer::~Stereo_Buffer() { +} + +bool Stereo_Buffer::set_sample_rate( long rate, int msec ) +{ + for ( int i = 0; i < buf_count; i++ ) { + if ( bufs [i].set_sample_rate( rate, msec ) ) + { + return false; + } + } + + return true; +} + +void Stereo_Buffer::clock_rate( long rate ) +{ + for ( int i = 0; i < buf_count; i++ ) + bufs [i].clock_rate( rate ); +} + +void Stereo_Buffer::bass_freq( int bass ) +{ + for ( unsigned i = 0; i < buf_count; i++ ) + bufs [i].bass_freq( bass ); +} + +void Stereo_Buffer::clear() +{ + stereo_added = false; + was_stereo = false; + for ( int i = 0; i < buf_count; i++ ) + bufs [i].clear(); +} + +void Stereo_Buffer::end_frame( blip_time_t clock_count, bool stereo ) +{ + for ( unsigned i = 0; i < buf_count; i++ ) + { + bufs [i].end_frame( clock_count ); + } + stereo_added |= stereo; +} + + + +long Stereo_Buffer::read_samples( blip_sample_t* out, long max_samples ) +{ + long count = bufs [0].samples_avail(); + if ( count > max_samples / 2 ) + count = max_samples / 2; + if ( count ) + { + if ( stereo_added || was_stereo ) + { + mix_stereo( out, count ); + + bufs [0].remove_samples( count ); + bufs [1].remove_samples( count ); + bufs [2].remove_samples( count ); + } + else + { + mix_mono( out, count ); + + bufs [0].remove_samples( count ); + + bufs [1].remove_silence( count ); + bufs [2].remove_silence( count ); + } + + // to do: this might miss opportunities for optimization + if ( !bufs [0].samples_avail() ) { + was_stereo = stereo_added; + stereo_added = false; + } + } + + return count * 2; +} + +void Stereo_Buffer::mix_stereo( blip_sample_t* out, long count ) +{ + Blip_Reader l_left; + Blip_Reader l_right; + Blip_Reader l_center; + + l_left.begin( bufs [1] ); + l_right.begin( bufs [2] ); + int bass = l_center.begin( bufs [0] ); + + while ( count-- ) + { + int c = l_center.read(); + out [0] = c + l_left.read(); + out [1] = c + l_right.read(); + out += 2; + + l_center.next( bass ); + l_left.next( bass ); + l_right.next( bass ); + } + + l_center.end( bufs [0] ); + l_right.end( bufs [2] ); + l_left.end( bufs [1] ); +} + +void Stereo_Buffer::mix_mono( blip_sample_t* out, long count ) +{ + Blip_Reader in; + int bass = in.begin( bufs [0] ); + + while ( count-- ) + { + int sample = in.read(); + out [0] = sample; + out [1] = sample; + out += 2; + in.next( bass ); + } + + in.end( bufs [0] ); +} + diff --git a/waterbox/ngp/sound/Stereo_Buffer.h b/waterbox/ngp/sound/Stereo_Buffer.h new file mode 100644 index 0000000000..3d907fac54 --- /dev/null +++ b/waterbox/ngp/sound/Stereo_Buffer.h @@ -0,0 +1,69 @@ + +// Simple stereo Blip_Buffer for sound emulators whose oscillators output +// either on the left only, center, or right only. + +// Blip_Buffer 0.3.0. Copyright (C) 2003-2004 Shay Green. GNU GPL license. + +#ifndef STEREO_BUFFER_H +#define STEREO_BUFFER_H + +#include "Blip_Buffer.h" + +class Stereo_Buffer { +public: + Stereo_Buffer(); + ~Stereo_Buffer(); + + // Same as in Blip_Buffer (see Blip_Buffer.h) + bool set_sample_rate( long, int msec = 0 ); + void clock_rate( long ); + void bass_freq( int ); + void clear(); + + // Buffers to output synthesis to + Blip_Buffer* left(); + Blip_Buffer* center(); + Blip_Buffer* right(); + + // Same as in Blip_Buffer. For more efficient operation, pass false + // for was_stereo if the left and right buffers had nothing added + // to them for this frame. + void end_frame( blip_time_t, bool was_stereo = true ); + + // Output is stereo with channels interleved, left before right. Counts + // are in samples, *not* pairs. + long samples_avail() const; + long read_samples( blip_sample_t*, long ); + +private: + // noncopyable + Stereo_Buffer( const Stereo_Buffer& ); + Stereo_Buffer& operator = ( const Stereo_Buffer& ); + + enum { buf_count = 3 }; + Blip_Buffer bufs [buf_count]; + bool stereo_added; + bool was_stereo; + + void mix_stereo( blip_sample_t*, long ); + void mix_mono( blip_sample_t*, long ); +}; + + inline Blip_Buffer* Stereo_Buffer::left() { + return &bufs [1]; + } + + inline Blip_Buffer* Stereo_Buffer::center() { + return &bufs [0]; + } + + inline Blip_Buffer* Stereo_Buffer::right() { + return &bufs [2]; + } + + inline long Stereo_Buffer::samples_avail() const { + return bufs [0].samples_avail(); + } + +#endif + diff --git a/waterbox/ngp/z80-fuse/opcodes_base.c b/waterbox/ngp/z80-fuse/opcodes_base.c new file mode 100644 index 0000000000..f56121db70 --- /dev/null +++ b/waterbox/ngp/z80-fuse/opcodes_base.c @@ -0,0 +1,1123 @@ +/* opcodes_base.c: unshifted Z80 opcodes + Copyright (c) 1999-2003 Philip Kendall + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: philip-fuse@shadowmagic.org.uk + +*/ + +/* NB: this file is autogenerated by 'z80.pl' from 'opcodes_base.dat', + and included in 'z80_ops.c' */ + + case 0x00: /* NOP */ + break; + case 0x01: /* LD BC,nnnn */ + C=Z80_RB_MACRO(PC++); + B=Z80_RB_MACRO(PC++); + break; + case 0x02: /* LD (BC),A */ + Z80_WB_MACRO(BC,A); + break; + case 0x03: /* INC BC */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + BC++; + break; + case 0x04: /* INC B */ + INC(B); + break; + case 0x05: /* DEC B */ + DEC(B); + break; + case 0x06: /* LD B,nn */ + B = Z80_RB_MACRO( PC++ ); + break; + case 0x07: /* RLCA */ + A = ( A << 1 ) | ( A >> 7 ); + F = ( F & ( FLAG_P | FLAG_Z | FLAG_S ) ) | + ( A & ( FLAG_C | FLAG_3 | FLAG_5 ) ); + break; + case 0x08: /* EX AF,AF' */ + { + uint16 wordtemp = AF; AF = AF_; AF_ = wordtemp; + } + break; + case 0x09: /* ADD HL,BC */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + ADD16(HL,BC); + break; + case 0x0a: /* LD A,(BC) */ + A=Z80_RB_MACRO(BC); + break; + case 0x0b: /* DEC BC */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + BC--; + break; + case 0x0c: /* INC C */ + INC(C); + break; + case 0x0d: /* DEC C */ + DEC(C); + break; + case 0x0e: /* LD C,nn */ + C = Z80_RB_MACRO( PC++ ); + break; + case 0x0f: /* RRCA */ + F = ( F & ( FLAG_P | FLAG_Z | FLAG_S ) ) | ( A & FLAG_C ); + A = ( A >> 1) | ( A << 7 ); + F |= ( A & ( FLAG_3 | FLAG_5 ) ); + break; + case 0x10: /* DJNZ offset */ + contend_read_no_mreq( IR, 1 ); + B--; + if(B) { + JR(); + } else { + contend_read( PC, 3 ); + } + PC++; + break; + case 0x11: /* LD DE,nnnn */ + E=Z80_RB_MACRO(PC++); + D=Z80_RB_MACRO(PC++); + break; + case 0x12: /* LD (DE),A */ + Z80_WB_MACRO(DE,A); + break; + case 0x13: /* INC DE */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + DE++; + break; + case 0x14: /* INC D */ + INC(D); + break; + case 0x15: /* DEC D */ + DEC(D); + break; + case 0x16: /* LD D,nn */ + D = Z80_RB_MACRO( PC++ ); + break; + case 0x17: /* RLA */ + { + uint8 bytetemp = A; + A = ( A << 1 ) | ( F & FLAG_C ); + F = ( F & ( FLAG_P | FLAG_Z | FLAG_S ) ) | + ( A & ( FLAG_3 | FLAG_5 ) ) | ( bytetemp >> 7 ); + } + break; + case 0x18: /* JR offset */ + JR(); + PC++; + break; + case 0x19: /* ADD HL,DE */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + ADD16(HL,DE); + break; + case 0x1a: /* LD A,(DE) */ + A=Z80_RB_MACRO(DE); + break; + case 0x1b: /* DEC DE */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + DE--; + break; + case 0x1c: /* INC E */ + INC(E); + break; + case 0x1d: /* DEC E */ + DEC(E); + break; + case 0x1e: /* LD E,nn */ + E = Z80_RB_MACRO( PC++ ); + break; + case 0x1f: /* RRA */ + { + uint8 bytetemp = A; + A = ( A >> 1 ) | ( F << 7 ); + F = ( F & ( FLAG_P | FLAG_Z | FLAG_S ) ) | + ( A & ( FLAG_3 | FLAG_5 ) ) | ( bytetemp & FLAG_C ) ; + } + break; + case 0x20: /* JR NZ,offset */ + if( ! ( F & FLAG_Z ) ) { + JR(); + } else { + contend_read( PC, 3 ); + } + PC++; + break; + case 0x21: /* LD HL,nnnn */ + L=Z80_RB_MACRO(PC++); + H=Z80_RB_MACRO(PC++); + break; + case 0x22: /* LD (nnnn),HL */ + LD16_NNRR(L,H); + break; + case 0x23: /* INC HL */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + HL++; + break; + case 0x24: /* INC H */ + INC(H); + break; + case 0x25: /* DEC H */ + DEC(H); + break; + case 0x26: /* LD H,nn */ + H = Z80_RB_MACRO( PC++ ); + break; + case 0x27: /* DAA */ + { + uint8 add = 0, carry = ( F & FLAG_C ); + if( ( F & FLAG_H ) || ( ( A & 0x0f ) > 9 ) ) add = 6; + if( carry || ( A > 0x99 ) ) add |= 0x60; + if( A > 0x99 ) carry = FLAG_C; + if( F & FLAG_N ) { + SUB(add); + } else { + ADD(add); + } + F = ( F & ~( FLAG_C | FLAG_P ) ) | carry | parity_table[A]; + } + break; + case 0x28: /* JR Z,offset */ + if( F & FLAG_Z ) { + JR(); + } else { + contend_read( PC, 3 ); + } + PC++; + break; + case 0x29: /* ADD HL,HL */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + ADD16(HL,HL); + break; + case 0x2a: /* LD HL,(nnnn) */ + LD16_RRNN(L,H); + break; + case 0x2b: /* DEC HL */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + HL--; + break; + case 0x2c: /* INC L */ + INC(L); + break; + case 0x2d: /* DEC L */ + DEC(L); + break; + case 0x2e: /* LD L,nn */ + L = Z80_RB_MACRO( PC++ ); + break; + case 0x2f: /* CPL */ + A ^= 0xff; + F = ( F & ( FLAG_C | FLAG_P | FLAG_Z | FLAG_S ) ) | + ( A & ( FLAG_3 | FLAG_5 ) ) | ( FLAG_N | FLAG_H ); + break; + case 0x30: /* JR NC,offset */ + if( ! ( F & FLAG_C ) ) { + JR(); + } else { + contend_read( PC, 3 ); + } + PC++; + break; + case 0x31: /* LD SP,nnnn */ + SPL=Z80_RB_MACRO(PC++); + SPH=Z80_RB_MACRO(PC++); + break; + case 0x32: /* LD (nnnn),A */ + { + uint16 wordtemp = Z80_RB_MACRO( PC++ ); + wordtemp|=Z80_RB_MACRO(PC++) << 8; + Z80_WB_MACRO(wordtemp,A); + } + break; + case 0x33: /* INC SP */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + SP++; + break; + case 0x34: /* INC (HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + INC(bytetemp); + Z80_WB_MACRO(HL,bytetemp); + } + break; + case 0x35: /* DEC (HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + DEC(bytetemp); + Z80_WB_MACRO(HL,bytetemp); + } + break; + case 0x36: /* LD (HL),nn */ + Z80_WB_MACRO(HL,Z80_RB_MACRO(PC++)); + break; + case 0x37: /* SCF */ + F = ( F & ( FLAG_P | FLAG_Z | FLAG_S ) ) | + ( A & ( FLAG_3 | FLAG_5 ) ) | + FLAG_C; + break; + case 0x38: /* JR C,offset */ + if( F & FLAG_C ) { + JR(); + } else { + contend_read( PC, 3 ); + } + PC++; + break; + case 0x39: /* ADD HL,SP */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + ADD16(HL,SP); + break; + case 0x3a: /* LD A,(nnnn) */ + { + uint16 wordtemp; + wordtemp = Z80_RB_MACRO(PC++); + wordtemp|= ( Z80_RB_MACRO(PC++) << 8 ); + A=Z80_RB_MACRO(wordtemp); + } + break; + case 0x3b: /* DEC SP */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + SP--; + break; + case 0x3c: /* INC A */ + INC(A); + break; + case 0x3d: /* DEC A */ + DEC(A); + break; + case 0x3e: /* LD A,nn */ + A = Z80_RB_MACRO( PC++ ); + break; + case 0x3f: /* CCF */ + F = ( F & ( FLAG_P | FLAG_Z | FLAG_S ) ) | + ( ( F & FLAG_C ) ? FLAG_H : FLAG_C ) | ( A & ( FLAG_3 | FLAG_5 ) ); + break; + case 0x40: /* LD B,B */ + break; + case 0x41: /* LD B,C */ + B=C; + break; + case 0x42: /* LD B,D */ + B=D; + break; + case 0x43: /* LD B,E */ + B=E; + break; + case 0x44: /* LD B,H */ + B=H; + break; + case 0x45: /* LD B,L */ + B=L; + break; + case 0x46: /* LD B,(HL) */ + B=Z80_RB_MACRO(HL); + break; + case 0x47: /* LD B,A */ + B=A; + break; + case 0x48: /* LD C,B */ + C=B; + break; + case 0x49: /* LD C,C */ + break; + case 0x4a: /* LD C,D */ + C=D; + break; + case 0x4b: /* LD C,E */ + C=E; + break; + case 0x4c: /* LD C,H */ + C=H; + break; + case 0x4d: /* LD C,L */ + C=L; + break; + case 0x4e: /* LD C,(HL) */ + C=Z80_RB_MACRO(HL); + break; + case 0x4f: /* LD C,A */ + C=A; + break; + case 0x50: /* LD D,B */ + D=B; + break; + case 0x51: /* LD D,C */ + D=C; + break; + case 0x52: /* LD D,D */ + break; + case 0x53: /* LD D,E */ + D=E; + break; + case 0x54: /* LD D,H */ + D=H; + break; + case 0x55: /* LD D,L */ + D=L; + break; + case 0x56: /* LD D,(HL) */ + D=Z80_RB_MACRO(HL); + break; + case 0x57: /* LD D,A */ + D=A; + break; + case 0x58: /* LD E,B */ + E=B; + break; + case 0x59: /* LD E,C */ + E=C; + break; + case 0x5a: /* LD E,D */ + E=D; + break; + case 0x5b: /* LD E,E */ + break; + case 0x5c: /* LD E,H */ + E=H; + break; + case 0x5d: /* LD E,L */ + E=L; + break; + case 0x5e: /* LD E,(HL) */ + E=Z80_RB_MACRO(HL); + break; + case 0x5f: /* LD E,A */ + E=A; + break; + case 0x60: /* LD H,B */ + H=B; + break; + case 0x61: /* LD H,C */ + H=C; + break; + case 0x62: /* LD H,D */ + H=D; + break; + case 0x63: /* LD H,E */ + H=E; + break; + case 0x64: /* LD H,H */ + break; + case 0x65: /* LD H,L */ + H=L; + break; + case 0x66: /* LD H,(HL) */ + H=Z80_RB_MACRO(HL); + break; + case 0x67: /* LD H,A */ + H=A; + break; + case 0x68: /* LD L,B */ + L=B; + break; + case 0x69: /* LD L,C */ + L=C; + break; + case 0x6a: /* LD L,D */ + L=D; + break; + case 0x6b: /* LD L,E */ + L=E; + break; + case 0x6c: /* LD L,H */ + L=H; + break; + case 0x6d: /* LD L,L */ + break; + case 0x6e: /* LD L,(HL) */ + L=Z80_RB_MACRO(HL); + break; + case 0x6f: /* LD L,A */ + L=A; + break; + case 0x70: /* LD (HL),B */ + Z80_WB_MACRO(HL,B); + break; + case 0x71: /* LD (HL),C */ + Z80_WB_MACRO(HL,C); + break; + case 0x72: /* LD (HL),D */ + Z80_WB_MACRO(HL,D); + break; + case 0x73: /* LD (HL),E */ + Z80_WB_MACRO(HL,E); + break; + case 0x74: /* LD (HL),H */ + Z80_WB_MACRO(HL,H); + break; + case 0x75: /* LD (HL),L */ + Z80_WB_MACRO(HL,L); + break; + case 0x76: /* HALT */ + z80.halted=1; + PC--; + break; + case 0x77: /* LD (HL),A */ + Z80_WB_MACRO(HL,A); + break; + case 0x78: /* LD A,B */ + A=B; + break; + case 0x79: /* LD A,C */ + A=C; + break; + case 0x7a: /* LD A,D */ + A=D; + break; + case 0x7b: /* LD A,E */ + A=E; + break; + case 0x7c: /* LD A,H */ + A=H; + break; + case 0x7d: /* LD A,L */ + A=L; + break; + case 0x7e: /* LD A,(HL) */ + A=Z80_RB_MACRO(HL); + break; + case 0x7f: /* LD A,A */ + break; + case 0x80: /* ADD A,B */ + ADD(B); + break; + case 0x81: /* ADD A,C */ + ADD(C); + break; + case 0x82: /* ADD A,D */ + ADD(D); + break; + case 0x83: /* ADD A,E */ + ADD(E); + break; + case 0x84: /* ADD A,H */ + ADD(H); + break; + case 0x85: /* ADD A,L */ + ADD(L); + break; + case 0x86: /* ADD A,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + ADD(bytetemp); + } + break; + case 0x87: /* ADD A,A */ + ADD(A); + break; + case 0x88: /* ADC A,B */ + ADC(B); + break; + case 0x89: /* ADC A,C */ + ADC(C); + break; + case 0x8a: /* ADC A,D */ + ADC(D); + break; + case 0x8b: /* ADC A,E */ + ADC(E); + break; + case 0x8c: /* ADC A,H */ + ADC(H); + break; + case 0x8d: /* ADC A,L */ + ADC(L); + break; + case 0x8e: /* ADC A,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + ADC(bytetemp); + } + break; + case 0x8f: /* ADC A,A */ + ADC(A); + break; + case 0x90: /* SUB A,B */ + SUB(B); + break; + case 0x91: /* SUB A,C */ + SUB(C); + break; + case 0x92: /* SUB A,D */ + SUB(D); + break; + case 0x93: /* SUB A,E */ + SUB(E); + break; + case 0x94: /* SUB A,H */ + SUB(H); + break; + case 0x95: /* SUB A,L */ + SUB(L); + break; + case 0x96: /* SUB A,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + SUB(bytetemp); + } + break; + case 0x97: /* SUB A,A */ + SUB(A); + break; + case 0x98: /* SBC A,B */ + SBC(B); + break; + case 0x99: /* SBC A,C */ + SBC(C); + break; + case 0x9a: /* SBC A,D */ + SBC(D); + break; + case 0x9b: /* SBC A,E */ + SBC(E); + break; + case 0x9c: /* SBC A,H */ + SBC(H); + break; + case 0x9d: /* SBC A,L */ + SBC(L); + break; + case 0x9e: /* SBC A,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + SBC(bytetemp); + } + break; + case 0x9f: /* SBC A,A */ + SBC(A); + break; + case 0xa0: /* AND A,B */ + AND(B); + break; + case 0xa1: /* AND A,C */ + AND(C); + break; + case 0xa2: /* AND A,D */ + AND(D); + break; + case 0xa3: /* AND A,E */ + AND(E); + break; + case 0xa4: /* AND A,H */ + AND(H); + break; + case 0xa5: /* AND A,L */ + AND(L); + break; + case 0xa6: /* AND A,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + AND(bytetemp); + } + break; + case 0xa7: /* AND A,A */ + AND(A); + break; + case 0xa8: /* XOR A,B */ + XOR(B); + break; + case 0xa9: /* XOR A,C */ + XOR(C); + break; + case 0xaa: /* XOR A,D */ + XOR(D); + break; + case 0xab: /* XOR A,E */ + XOR(E); + break; + case 0xac: /* XOR A,H */ + XOR(H); + break; + case 0xad: /* XOR A,L */ + XOR(L); + break; + case 0xae: /* XOR A,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + XOR(bytetemp); + } + break; + case 0xaf: /* XOR A,A */ + XOR(A); + break; + case 0xb0: /* OR A,B */ + OR(B); + break; + case 0xb1: /* OR A,C */ + OR(C); + break; + case 0xb2: /* OR A,D */ + OR(D); + break; + case 0xb3: /* OR A,E */ + OR(E); + break; + case 0xb4: /* OR A,H */ + OR(H); + break; + case 0xb5: /* OR A,L */ + OR(L); + break; + case 0xb6: /* OR A,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + OR(bytetemp); + } + break; + case 0xb7: /* OR A,A */ + OR(A); + break; + case 0xb8: /* CP B */ + CP(B); + break; + case 0xb9: /* CP C */ + CP(C); + break; + case 0xba: /* CP D */ + CP(D); + break; + case 0xbb: /* CP E */ + CP(E); + break; + case 0xbc: /* CP H */ + CP(H); + break; + case 0xbd: /* CP L */ + CP(L); + break; + case 0xbe: /* CP (HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + CP(bytetemp); + } + break; + case 0xbf: /* CP A */ + CP(A); + break; + case 0xc0: /* RET NZ */ + contend_read_no_mreq( IR, 1 ); + if( ! ( F & FLAG_Z ) ) { RET(); } + break; + case 0xc1: /* POP BC */ + POP16(C,B); + break; + case 0xc2: /* JP NZ,nnnn */ + if( ! ( F & FLAG_Z ) ) { + JP(); + } else { + contend_read( PC, 3 ); contend_read( PC + 1, 3 ); PC += 2; + } + break; + case 0xc3: /* JP nnnn */ + JP(); + break; + case 0xc4: /* CALL NZ,nnnn */ + if( ! ( F & FLAG_Z ) ) { + CALL(); + } else { + contend_read( PC, 3 ); contend_read( PC + 1, 3 ); PC += 2; + } + break; + case 0xc5: /* PUSH BC */ + contend_read_no_mreq( IR, 1 ); + PUSH16(C,B); + break; + case 0xc6: /* ADD A,nn */ + { + uint8 bytetemp = Z80_RB_MACRO( PC++ ); + ADD(bytetemp); + } + break; + case 0xc7: /* RST 00 */ + contend_read_no_mreq( IR, 1 ); + RST(0x00); + break; + case 0xc8: /* RET Z */ + contend_read_no_mreq( IR, 1 ); + if( F & FLAG_Z ) { RET(); } + break; + case 0xc9: /* RET */ + RET(); + break; + case 0xca: /* JP Z,nnnn */ + if( F & FLAG_Z ) { + JP(); + } else { + contend_read( PC, 3 ); contend_read( PC + 1, 3 ); PC += 2; + } + break; + case 0xcb: /* shift CB */ + { + uint8 opcode2; + opcode2 = Z80_RB_MACRO( PC ); + z80_tstates++; + PC++; + R++; + switch(opcode2) { +#include "z80_cb.c" + } + } + break; + case 0xcc: /* CALL Z,nnnn */ + if( F & FLAG_Z ) { + CALL(); + } else { + contend_read( PC, 3 ); contend_read( PC + 1, 3 ); PC += 2; + } + break; + case 0xcd: /* CALL nnnn */ + CALL(); + break; + case 0xce: /* ADC A,nn */ + { + uint8 bytetemp = Z80_RB_MACRO( PC++ ); + ADC(bytetemp); + } + break; + case 0xcf: /* RST 8 */ + contend_read_no_mreq( IR, 1 ); + RST(0x08); + break; + case 0xd0: /* RET NC */ + contend_read_no_mreq( IR, 1 ); + if( ! ( F & FLAG_C ) ) { RET(); } + break; + case 0xd1: /* POP DE */ + POP16(E,D); + break; + case 0xd2: /* JP NC,nnnn */ + if( ! ( F & FLAG_C ) ) { + JP(); + } else { + contend_read( PC, 3 ); contend_read( PC + 1, 3 ); PC += 2; + } + break; + case 0xd3: /* OUT (nn),A */ + { + uint16 outtemp; + outtemp = Z80_RB_MACRO( PC++ ) + ( A << 8 ); + Z80_WP_MACRO( outtemp, A ); + } + break; + case 0xd4: /* CALL NC,nnnn */ + if( ! ( F & FLAG_C ) ) { + CALL(); + } else { + contend_read( PC, 3 ); contend_read( PC + 1, 3 ); PC += 2; + } + break; + case 0xd5: /* PUSH DE */ + contend_read_no_mreq( IR, 1 ); + PUSH16(E,D); + break; + case 0xd6: /* SUB nn */ + { + uint8 bytetemp = Z80_RB_MACRO( PC++ ); + SUB(bytetemp); + } + break; + case 0xd7: /* RST 10 */ + contend_read_no_mreq( IR, 1 ); + RST(0x10); + break; + case 0xd8: /* RET C */ + contend_read_no_mreq( IR, 1 ); + if( F & FLAG_C ) { RET(); } + break; + case 0xd9: /* EXX */ + { + uint16 wordtemp; + wordtemp = BC; BC = BC_; BC_ = wordtemp; + wordtemp = DE; DE = DE_; DE_ = wordtemp; + wordtemp = HL; HL = HL_; HL_ = wordtemp; + } + break; + case 0xda: /* JP C,nnnn */ + if( F & FLAG_C ) { + JP(); + } else { + contend_read( PC, 3 ); contend_read( PC + 1, 3 ); PC += 2; + } + break; + case 0xdb: /* IN A,(nn) */ + { + uint16 intemp; + intemp = Z80_RB_MACRO( PC++ ) + ( A << 8 ); + A=Z80_RP_MACRO( intemp ); + } + break; + case 0xdc: /* CALL C,nnnn */ + if( F & FLAG_C ) { + CALL(); + } else { + contend_read( PC, 3 ); contend_read( PC + 1, 3 ); PC += 2; + } + break; + case 0xdd: /* shift DD */ + { + uint8 opcode2; + opcode2 = Z80_RB_MACRO( PC ); + z80_tstates++; + PC++; + R++; + switch(opcode2) { +#define REGISTER IX +#define REGISTERL IXL +#define REGISTERH IXH +#include "z80_ddfd.c" +#undef REGISTERH +#undef REGISTERL +#undef REGISTER + } + } + break; + case 0xde: /* SBC A,nn */ + { + uint8 bytetemp = Z80_RB_MACRO( PC++ ); + SBC(bytetemp); + } + break; + case 0xdf: /* RST 18 */ + contend_read_no_mreq( IR, 1 ); + RST(0x18); + break; + case 0xe0: /* RET PO */ + contend_read_no_mreq( IR, 1 ); + if( ! ( F & FLAG_P ) ) { RET(); } + break; + case 0xe1: /* POP HL */ + POP16(L,H); + break; + case 0xe2: /* JP PO,nnnn */ + if( ! ( F & FLAG_P ) ) { + JP(); + } else { + contend_read( PC, 3 ); contend_read( PC + 1, 3 ); PC += 2; + } + break; + case 0xe3: /* EX (SP),HL */ + { + uint8 bytetempl, bytetemph; + bytetempl = Z80_RB_MACRO( SP ); + bytetemph = Z80_RB_MACRO( SP + 1 ); contend_read_no_mreq( SP + 1, 1 ); + Z80_WB_MACRO( SP + 1, H ); + Z80_WB_MACRO( SP, L ); + contend_write_no_mreq( SP, 1 ); contend_write_no_mreq( SP, 1 ); + L=bytetempl; H=bytetemph; + } + break; + case 0xe4: /* CALL PO,nnnn */ + if( ! ( F & FLAG_P ) ) { + CALL(); + } else { + contend_read( PC, 3 ); contend_read( PC + 1, 3 ); PC += 2; + } + break; + case 0xe5: /* PUSH HL */ + contend_read_no_mreq( IR, 1 ); + PUSH16(L,H); + break; + case 0xe6: /* AND nn */ + { + uint8 bytetemp = Z80_RB_MACRO( PC++ ); + AND(bytetemp); + } + break; + case 0xe7: /* RST 20 */ + contend_read_no_mreq( IR, 1 ); + RST(0x20); + break; + case 0xe8: /* RET PE */ + contend_read_no_mreq( IR, 1 ); + if( F & FLAG_P ) { RET(); } + break; + case 0xe9: /* JP HL */ + PC=HL; /* NB: NOT INDIRECT! */ + break; + case 0xea: /* JP PE,nnnn */ + if( F & FLAG_P ) { + JP(); + } else { + contend_read( PC, 3 ); contend_read( PC + 1, 3 ); PC += 2; + } + break; + case 0xeb: /* EX DE,HL */ + { + uint16 wordtemp=DE; DE=HL; HL=wordtemp; + } + break; + case 0xec: /* CALL PE,nnnn */ + if( F & FLAG_P ) { + CALL(); + } else { + contend_read( PC, 3 ); contend_read( PC + 1, 3 ); PC += 2; + } + break; + case 0xed: /* shift ED */ + { + uint8 opcode2; + opcode2 = Z80_RB_MACRO( PC ); + z80_tstates++; + PC++; + R++; + switch(opcode2) { +#include "z80_ed.c" + } + } + break; + case 0xee: /* XOR A,nn */ + { + uint8 bytetemp = Z80_RB_MACRO( PC++ ); + XOR(bytetemp); + } + break; + case 0xef: /* RST 28 */ + contend_read_no_mreq( IR, 1 ); + RST(0x28); + break; + case 0xf0: /* RET P */ + contend_read_no_mreq( IR, 1 ); + if( ! ( F & FLAG_S ) ) { RET(); } + break; + case 0xf1: /* POP AF */ + POP16(F,A); + break; + case 0xf2: /* JP P,nnnn */ + if( ! ( F & FLAG_S ) ) { + JP(); + } else { + contend_read( PC, 3 ); contend_read( PC + 1, 3 ); PC += 2; + } + break; + case 0xf3: /* DI */ + IFF1=IFF2=0; + break; + case 0xf4: /* CALL P,nnnn */ + if( ! ( F & FLAG_S ) ) { + CALL(); + } else { + contend_read( PC, 3 ); contend_read( PC + 1, 3 ); PC += 2; + } + break; + case 0xf5: /* PUSH AF */ + contend_read_no_mreq( IR, 1 ); + PUSH16(F,A); + break; + case 0xf6: /* OR nn */ + { + uint8 bytetemp = Z80_RB_MACRO( PC++ ); + OR(bytetemp); + } + break; + case 0xf7: /* RST 30 */ + contend_read_no_mreq( IR, 1 ); + RST(0x30); + break; + case 0xf8: /* RET M */ + contend_read_no_mreq( IR, 1 ); + if( F & FLAG_S ) { RET(); } + break; + case 0xf9: /* LD SP,HL */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + SP = HL; + break; + case 0xfa: /* JP M,nnnn */ + if( F & FLAG_S ) { + JP(); + } else { + contend_read( PC, 3 ); contend_read( PC + 1, 3 ); PC += 2; + } + break; + case 0xfb: /* EI */ + /* Interrupts are not accepted immediately after an EI, but are + accepted after the next instruction */ + IFF1 = IFF2 = 1; + z80.interrupts_enabled_at = z80_tstates; + //event_add( z80_tstates + 1, z80_interrupt_event ); + break; + case 0xfc: /* CALL M,nnnn */ + if( F & FLAG_S ) { + CALL(); + } else { + contend_read( PC, 3 ); contend_read( PC + 1, 3 ); PC += 2; + } + break; + case 0xfd: /* shift FD */ + { + uint8 opcode2; + opcode2 = Z80_RB_MACRO( PC ); + z80_tstates++; + PC++; + R++; + switch(opcode2) { +#define REGISTER IY +#define REGISTERL IYL +#define REGISTERH IYH +#include "z80_ddfd.c" +#undef REGISTERH +#undef REGISTERL +#undef REGISTER + } + } + break; + case 0xfe: /* CP nn */ + { + uint8 bytetemp = Z80_RB_MACRO( PC++ ); + CP(bytetemp); + } + break; + case 0xff: /* RST 38 */ + contend_read_no_mreq( IR, 1 ); + RST(0x38); + break; diff --git a/waterbox/ngp/z80-fuse/z80.cpp b/waterbox/ngp/z80-fuse/z80.cpp new file mode 100644 index 0000000000..d37b70795c --- /dev/null +++ b/waterbox/ngp/z80-fuse/z80.cpp @@ -0,0 +1,183 @@ +/* z80.c: z80 supplementary functions + Copyright (c) 1999-2003 Philip Kendall + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: philip-fuse@shadowmagic.org.uk + +*/ + +#include "z80.h" +#include "z80_macros.h" + +void (*z80_writebyte)(uint16, uint8); +uint8 (*z80_readbyte)(uint16); +void (*z80_writeport)(uint16, uint8); +uint8 (*z80_readport)(uint16); + +/* Whether a half carry occurred or not can be determined by looking at + the 3rd bit of the two arguments and the result; these are hashed + into this table in the form r12, where r is the 3rd bit of the + result, 1 is the 3rd bit of the 1st argument and 2 is the + third bit of the 2nd argument; the tables differ for add and subtract + operations */ +const uint8 halfcarry_add_table[] = + {0, FLAG_H, FLAG_H, FLAG_H, 0, 0, 0, FLAG_H}; +const uint8 halfcarry_sub_table[] = + {0, 0, FLAG_H, 0, FLAG_H, 0, FLAG_H, FLAG_H}; + +/* Similarly, overflow can be determined by looking at the 7th bits; again + the hash into this table is r12 */ +const uint8 overflow_add_table[] = {0, 0, 0, FLAG_V, FLAG_V, 0, 0, 0}; +const uint8 overflow_sub_table[] = {0, FLAG_V, 0, 0, 0, 0, FLAG_V, 0}; + +/* Some more tables; initialised in z80_init_tables() */ + +uint8 sz53_table[0x100]; /* The S, Z, 5 and 3 bits of the index */ +uint8 parity_table[0x100]; /* The parity of the lookup value */ +uint8 sz53p_table[0x100]; /* OR the above two tables together */ + +/* This is what everything acts on! */ +processor z80; +uint64 z80_tstates; +uint64 last_z80_tstates; + +static void z80_init_tables(void); + +/* Set up the z80 emulation */ +void z80_init(void) +{ + z80_init_tables(); +} + +/* Initalise the tables used to set flags */ +static void z80_init_tables(void) +{ + int i, j, k; + uint8 parity; + + for (i = 0; i < 0x100; i++) + { + sz53_table[i] = i & (FLAG_3 | FLAG_5 | FLAG_S); + j = i; + parity = 0; + for (k = 0; k < 8; k++) + { + parity ^= j & 1; + j >>= 1; + } + parity_table[i] = (parity ? 0 : FLAG_P); + sz53p_table[i] = sz53_table[i] | parity_table[i]; + } + + sz53_table[0] |= FLAG_Z; + sz53p_table[0] |= FLAG_Z; +} + +/* Reset the z80 */ +void z80_reset(void) +{ + AF = BC = DE = HL = 0; + AF_ = BC_ = DE_ = HL_ = 0; + IX = IY = 0; + I = R = R7 = 0; + SP = PC = 0; + IFF1 = IFF2 = IM = 0; + z80.halted = 0; + + z80.interrupts_enabled_at = 0; + z80_tstates = last_z80_tstates = 0; +} + +/* Process a z80 maskable interrupt */ +int z80_interrupt(void) +{ + + if (IFF1) + { + + /* If interrupts have just been enabled, don't accept the interrupt now, + but check after the next instruction has been executed */ + if (z80_tstates == z80.interrupts_enabled_at) + { + return 0; + } + + if (z80.halted) + { + PC++; + z80.halted = 0; + } + + IFF1 = IFF2 = 0; + + Z80_WB_MACRO(--SP, PCH); + Z80_WB_MACRO(--SP, PCL); + + R++; + + switch (IM) + { + case 0: + PC = 0x0038; + z80_tstates += 7; + break; + case 1: + PC = 0x0038; + z80_tstates += 7; + break; + case 2: + { + uint16 inttemp = (0x100 * I) + 0xff; + PCL = Z80_RB_MACRO(inttemp++); + PCH = Z80_RB_MACRO(inttemp); + z80_tstates += 7; + break; + } + //default: + // ui_error( UI_ERROR_ERROR, "Unknown interrupt mode %d", IM ); + // fuse_abort(); + } + + return 1; /* Accepted an interrupt */ + } + else + { + return 0; /* Did not accept an interrupt */ + } +} + +/* Process a z80 non-maskable interrupt */ +void z80_nmi(void) +{ + if (z80.halted) + { + PC++; + z80.halted = 0; + } + + IFF1 = 0; + + Z80_WB_MACRO(--SP, PCH); + Z80_WB_MACRO(--SP, PCL); + + /* FIXME: how is R affected? */ + + /* FIXME: how does contention apply here? */ + z80_tstates += 11; + PC = 0x0066; +} diff --git a/waterbox/ngp/z80-fuse/z80.h b/waterbox/ngp/z80-fuse/z80.h new file mode 100644 index 0000000000..a87b3c947a --- /dev/null +++ b/waterbox/ngp/z80-fuse/z80.h @@ -0,0 +1,126 @@ +/* z80.h: z80 emulation core + Copyright (c) 1999-2003 Philip Kendall + + $Id: z80.h 4640 2012-01-21 13:26:35Z pak21 $ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: philip-fuse@shadowmagic.org.uk + +*/ + +#ifndef FUSE_Z80_H +#define FUSE_Z80_H + +#include "defs.h" + +/* Union allowing a register pair to be accessed as bytes or as a word */ +typedef union { +#ifdef MSB_FIRST + struct + { + uint8 h, l; + } b; +#else + struct + { + uint8 l, h; + } b; +#endif + uint16 w; +} regpair; + +/* What's stored in the main processor */ +typedef struct +{ + regpair af, bc, de, hl; + regpair af_, bc_, de_, hl_; + regpair ix, iy; + uint8 i; + uint16 r; /* The low seven bits of the R register. 16 bits long + so it can also act as an RZX instruction counter */ + uint8 r7; /* The high bit of the R register */ + regpair sp, pc; + uint8 iff1, iff2, im; + int halted; + + /* Interrupts were enabled at this time; do not accept any interrupts + until z80_tstates > this value */ + uint64 interrupts_enabled_at; + +} processor; + +void z80_init(void); +void z80_reset(void); + +int z80_interrupt(void); +void z80_nmi(void); + +int z80_do_opcode(void); + +void z80_enable_interrupts(void); + +extern processor z80; +inline uint16 z80_getpc(void) { return z80.pc.w; } +extern const uint8 halfcarry_add_table[]; +extern const uint8 halfcarry_sub_table[]; +extern const uint8 overflow_add_table[]; +extern const uint8 overflow_sub_table[]; +extern uint8 sz53_table[]; +extern uint8 sz53p_table[]; +extern uint8 parity_table[]; + +extern uint64 z80_tstates, last_z80_tstates; + +extern void (*z80_writebyte)(uint16, uint8); +extern uint8 (*z80_readbyte)(uint16); +extern void (*z80_writeport)(uint16, uint8); +extern uint8 (*z80_readport)(uint16); + +// Ok, I lied, not a macro! + +//Write mem +static INLINE void Z80_WB_MACRO(uint16 A, uint8 V) +{ + z80_tstates += 3; + z80_writebyte(A, V); +} + +// Write port +static INLINE void Z80_WP_MACRO(uint16 A, uint8 V) +{ + z80_tstates += 4; + z80_writeport(A, V); +} + +// Read mem +static INLINE uint8 Z80_RB_MACRO(uint16 A) +{ + z80_tstates += 3; + return (z80_readbyte(A)); +} + +// Read port +static INLINE uint8 Z80_RP_MACRO(uint16 A) +{ + z80_tstates += 4; + return (z80_readport(A)); +} + +void z80_set_interrupt(int set); + +#endif /* #ifndef FUSE_Z80_H */ diff --git a/waterbox/ngp/z80-fuse/z80_cb.c b/waterbox/ngp/z80-fuse/z80_cb.c new file mode 100644 index 0000000000..aba27af952 --- /dev/null +++ b/waterbox/ngp/z80-fuse/z80_cb.c @@ -0,0 +1,930 @@ +/* z80_cb.c: Z80 CBxx opcodes + Copyright (c) 1999-2003 Philip Kendall + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: philip-fuse@shadowmagic.org.uk + +*/ + +/* NB: this file is autogenerated by 'z80.pl' from 'opcodes_cb.dat', + and included in 'z80_ops.c' */ + + case 0x00: /* RLC B */ + RLC(B); + break; + case 0x01: /* RLC C */ + RLC(C); + break; + case 0x02: /* RLC D */ + RLC(D); + break; + case 0x03: /* RLC E */ + RLC(E); + break; + case 0x04: /* RLC H */ + RLC(H); + break; + case 0x05: /* RLC L */ + RLC(L); + break; + case 0x06: /* RLC (HL) */ + { + uint8 bytetemp = Z80_RB_MACRO(HL); + contend_read_no_mreq( HL, 1 ); + RLC(bytetemp); + Z80_WB_MACRO(HL,bytetemp); + } + break; + case 0x07: /* RLC A */ + RLC(A); + break; + case 0x08: /* RRC B */ + RRC(B); + break; + case 0x09: /* RRC C */ + RRC(C); + break; + case 0x0a: /* RRC D */ + RRC(D); + break; + case 0x0b: /* RRC E */ + RRC(E); + break; + case 0x0c: /* RRC H */ + RRC(H); + break; + case 0x0d: /* RRC L */ + RRC(L); + break; + case 0x0e: /* RRC (HL) */ + { + uint8 bytetemp = Z80_RB_MACRO(HL); + contend_read_no_mreq( HL, 1 ); + RRC(bytetemp); + Z80_WB_MACRO(HL,bytetemp); + } + break; + case 0x0f: /* RRC A */ + RRC(A); + break; + case 0x10: /* RL B */ + RL(B); + break; + case 0x11: /* RL C */ + RL(C); + break; + case 0x12: /* RL D */ + RL(D); + break; + case 0x13: /* RL E */ + RL(E); + break; + case 0x14: /* RL H */ + RL(H); + break; + case 0x15: /* RL L */ + RL(L); + break; + case 0x16: /* RL (HL) */ + { + uint8 bytetemp = Z80_RB_MACRO(HL); + contend_read_no_mreq( HL, 1 ); + RL(bytetemp); + Z80_WB_MACRO(HL,bytetemp); + } + break; + case 0x17: /* RL A */ + RL(A); + break; + case 0x18: /* RR B */ + RR(B); + break; + case 0x19: /* RR C */ + RR(C); + break; + case 0x1a: /* RR D */ + RR(D); + break; + case 0x1b: /* RR E */ + RR(E); + break; + case 0x1c: /* RR H */ + RR(H); + break; + case 0x1d: /* RR L */ + RR(L); + break; + case 0x1e: /* RR (HL) */ + { + uint8 bytetemp = Z80_RB_MACRO(HL); + contend_read_no_mreq( HL, 1 ); + RR(bytetemp); + Z80_WB_MACRO(HL,bytetemp); + } + break; + case 0x1f: /* RR A */ + RR(A); + break; + case 0x20: /* SLA B */ + SLA(B); + break; + case 0x21: /* SLA C */ + SLA(C); + break; + case 0x22: /* SLA D */ + SLA(D); + break; + case 0x23: /* SLA E */ + SLA(E); + break; + case 0x24: /* SLA H */ + SLA(H); + break; + case 0x25: /* SLA L */ + SLA(L); + break; + case 0x26: /* SLA (HL) */ + { + uint8 bytetemp = Z80_RB_MACRO(HL); + contend_read_no_mreq( HL, 1 ); + SLA(bytetemp); + Z80_WB_MACRO(HL,bytetemp); + } + break; + case 0x27: /* SLA A */ + SLA(A); + break; + case 0x28: /* SRA B */ + SRA(B); + break; + case 0x29: /* SRA C */ + SRA(C); + break; + case 0x2a: /* SRA D */ + SRA(D); + break; + case 0x2b: /* SRA E */ + SRA(E); + break; + case 0x2c: /* SRA H */ + SRA(H); + break; + case 0x2d: /* SRA L */ + SRA(L); + break; + case 0x2e: /* SRA (HL) */ + { + uint8 bytetemp = Z80_RB_MACRO(HL); + contend_read_no_mreq( HL, 1 ); + SRA(bytetemp); + Z80_WB_MACRO(HL,bytetemp); + } + break; + case 0x2f: /* SRA A */ + SRA(A); + break; + case 0x30: /* SLL B */ + SLL(B); + break; + case 0x31: /* SLL C */ + SLL(C); + break; + case 0x32: /* SLL D */ + SLL(D); + break; + case 0x33: /* SLL E */ + SLL(E); + break; + case 0x34: /* SLL H */ + SLL(H); + break; + case 0x35: /* SLL L */ + SLL(L); + break; + case 0x36: /* SLL (HL) */ + { + uint8 bytetemp = Z80_RB_MACRO(HL); + contend_read_no_mreq( HL, 1 ); + SLL(bytetemp); + Z80_WB_MACRO(HL,bytetemp); + } + break; + case 0x37: /* SLL A */ + SLL(A); + break; + case 0x38: /* SRL B */ + SRL(B); + break; + case 0x39: /* SRL C */ + SRL(C); + break; + case 0x3a: /* SRL D */ + SRL(D); + break; + case 0x3b: /* SRL E */ + SRL(E); + break; + case 0x3c: /* SRL H */ + SRL(H); + break; + case 0x3d: /* SRL L */ + SRL(L); + break; + case 0x3e: /* SRL (HL) */ + { + uint8 bytetemp = Z80_RB_MACRO(HL); + contend_read_no_mreq( HL, 1 ); + SRL(bytetemp); + Z80_WB_MACRO(HL,bytetemp); + } + break; + case 0x3f: /* SRL A */ + SRL(A); + break; + case 0x40: /* BIT 0,B */ + BIT( 0, B ); + break; + case 0x41: /* BIT 0,C */ + BIT( 0, C ); + break; + case 0x42: /* BIT 0,D */ + BIT( 0, D ); + break; + case 0x43: /* BIT 0,E */ + BIT( 0, E ); + break; + case 0x44: /* BIT 0,H */ + BIT( 0, H ); + break; + case 0x45: /* BIT 0,L */ + BIT( 0, L ); + break; + case 0x46: /* BIT 0,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + BIT( 0, bytetemp ); + } + break; + case 0x47: /* BIT 0,A */ + BIT( 0, A ); + break; + case 0x48: /* BIT 1,B */ + BIT( 1, B ); + break; + case 0x49: /* BIT 1,C */ + BIT( 1, C ); + break; + case 0x4a: /* BIT 1,D */ + BIT( 1, D ); + break; + case 0x4b: /* BIT 1,E */ + BIT( 1, E ); + break; + case 0x4c: /* BIT 1,H */ + BIT( 1, H ); + break; + case 0x4d: /* BIT 1,L */ + BIT( 1, L ); + break; + case 0x4e: /* BIT 1,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + BIT( 1, bytetemp ); + } + break; + case 0x4f: /* BIT 1,A */ + BIT( 1, A ); + break; + case 0x50: /* BIT 2,B */ + BIT( 2, B ); + break; + case 0x51: /* BIT 2,C */ + BIT( 2, C ); + break; + case 0x52: /* BIT 2,D */ + BIT( 2, D ); + break; + case 0x53: /* BIT 2,E */ + BIT( 2, E ); + break; + case 0x54: /* BIT 2,H */ + BIT( 2, H ); + break; + case 0x55: /* BIT 2,L */ + BIT( 2, L ); + break; + case 0x56: /* BIT 2,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + BIT( 2, bytetemp ); + } + break; + case 0x57: /* BIT 2,A */ + BIT( 2, A ); + break; + case 0x58: /* BIT 3,B */ + BIT( 3, B ); + break; + case 0x59: /* BIT 3,C */ + BIT( 3, C ); + break; + case 0x5a: /* BIT 3,D */ + BIT( 3, D ); + break; + case 0x5b: /* BIT 3,E */ + BIT( 3, E ); + break; + case 0x5c: /* BIT 3,H */ + BIT( 3, H ); + break; + case 0x5d: /* BIT 3,L */ + BIT( 3, L ); + break; + case 0x5e: /* BIT 3,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + BIT( 3, bytetemp ); + } + break; + case 0x5f: /* BIT 3,A */ + BIT( 3, A ); + break; + case 0x60: /* BIT 4,B */ + BIT( 4, B ); + break; + case 0x61: /* BIT 4,C */ + BIT( 4, C ); + break; + case 0x62: /* BIT 4,D */ + BIT( 4, D ); + break; + case 0x63: /* BIT 4,E */ + BIT( 4, E ); + break; + case 0x64: /* BIT 4,H */ + BIT( 4, H ); + break; + case 0x65: /* BIT 4,L */ + BIT( 4, L ); + break; + case 0x66: /* BIT 4,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + BIT( 4, bytetemp ); + } + break; + case 0x67: /* BIT 4,A */ + BIT( 4, A ); + break; + case 0x68: /* BIT 5,B */ + BIT( 5, B ); + break; + case 0x69: /* BIT 5,C */ + BIT( 5, C ); + break; + case 0x6a: /* BIT 5,D */ + BIT( 5, D ); + break; + case 0x6b: /* BIT 5,E */ + BIT( 5, E ); + break; + case 0x6c: /* BIT 5,H */ + BIT( 5, H ); + break; + case 0x6d: /* BIT 5,L */ + BIT( 5, L ); + break; + case 0x6e: /* BIT 5,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + BIT( 5, bytetemp ); + } + break; + case 0x6f: /* BIT 5,A */ + BIT( 5, A ); + break; + case 0x70: /* BIT 6,B */ + BIT( 6, B ); + break; + case 0x71: /* BIT 6,C */ + BIT( 6, C ); + break; + case 0x72: /* BIT 6,D */ + BIT( 6, D ); + break; + case 0x73: /* BIT 6,E */ + BIT( 6, E ); + break; + case 0x74: /* BIT 6,H */ + BIT( 6, H ); + break; + case 0x75: /* BIT 6,L */ + BIT( 6, L ); + break; + case 0x76: /* BIT 6,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + BIT( 6, bytetemp ); + } + break; + case 0x77: /* BIT 6,A */ + BIT( 6, A ); + break; + case 0x78: /* BIT 7,B */ + BIT( 7, B ); + break; + case 0x79: /* BIT 7,C */ + BIT( 7, C ); + break; + case 0x7a: /* BIT 7,D */ + BIT( 7, D ); + break; + case 0x7b: /* BIT 7,E */ + BIT( 7, E ); + break; + case 0x7c: /* BIT 7,H */ + BIT( 7, H ); + break; + case 0x7d: /* BIT 7,L */ + BIT( 7, L ); + break; + case 0x7e: /* BIT 7,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + BIT( 7, bytetemp ); + } + break; + case 0x7f: /* BIT 7,A */ + BIT( 7, A ); + break; + case 0x80: /* RES 0,B */ + B &= 0xfe; + break; + case 0x81: /* RES 0,C */ + C &= 0xfe; + break; + case 0x82: /* RES 0,D */ + D &= 0xfe; + break; + case 0x83: /* RES 0,E */ + E &= 0xfe; + break; + case 0x84: /* RES 0,H */ + H &= 0xfe; + break; + case 0x85: /* RES 0,L */ + L &= 0xfe; + break; + case 0x86: /* RES 0,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO( HL, bytetemp & 0xfe ); + } + break; + case 0x87: /* RES 0,A */ + A &= 0xfe; + break; + case 0x88: /* RES 1,B */ + B &= 0xfd; + break; + case 0x89: /* RES 1,C */ + C &= 0xfd; + break; + case 0x8a: /* RES 1,D */ + D &= 0xfd; + break; + case 0x8b: /* RES 1,E */ + E &= 0xfd; + break; + case 0x8c: /* RES 1,H */ + H &= 0xfd; + break; + case 0x8d: /* RES 1,L */ + L &= 0xfd; + break; + case 0x8e: /* RES 1,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO( HL, bytetemp & 0xfd ); + } + break; + case 0x8f: /* RES 1,A */ + A &= 0xfd; + break; + case 0x90: /* RES 2,B */ + B &= 0xfb; + break; + case 0x91: /* RES 2,C */ + C &= 0xfb; + break; + case 0x92: /* RES 2,D */ + D &= 0xfb; + break; + case 0x93: /* RES 2,E */ + E &= 0xfb; + break; + case 0x94: /* RES 2,H */ + H &= 0xfb; + break; + case 0x95: /* RES 2,L */ + L &= 0xfb; + break; + case 0x96: /* RES 2,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO( HL, bytetemp & 0xfb ); + } + break; + case 0x97: /* RES 2,A */ + A &= 0xfb; + break; + case 0x98: /* RES 3,B */ + B &= 0xf7; + break; + case 0x99: /* RES 3,C */ + C &= 0xf7; + break; + case 0x9a: /* RES 3,D */ + D &= 0xf7; + break; + case 0x9b: /* RES 3,E */ + E &= 0xf7; + break; + case 0x9c: /* RES 3,H */ + H &= 0xf7; + break; + case 0x9d: /* RES 3,L */ + L &= 0xf7; + break; + case 0x9e: /* RES 3,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO( HL, bytetemp & 0xf7 ); + } + break; + case 0x9f: /* RES 3,A */ + A &= 0xf7; + break; + case 0xa0: /* RES 4,B */ + B &= 0xef; + break; + case 0xa1: /* RES 4,C */ + C &= 0xef; + break; + case 0xa2: /* RES 4,D */ + D &= 0xef; + break; + case 0xa3: /* RES 4,E */ + E &= 0xef; + break; + case 0xa4: /* RES 4,H */ + H &= 0xef; + break; + case 0xa5: /* RES 4,L */ + L &= 0xef; + break; + case 0xa6: /* RES 4,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO( HL, bytetemp & 0xef ); + } + break; + case 0xa7: /* RES 4,A */ + A &= 0xef; + break; + case 0xa8: /* RES 5,B */ + B &= 0xdf; + break; + case 0xa9: /* RES 5,C */ + C &= 0xdf; + break; + case 0xaa: /* RES 5,D */ + D &= 0xdf; + break; + case 0xab: /* RES 5,E */ + E &= 0xdf; + break; + case 0xac: /* RES 5,H */ + H &= 0xdf; + break; + case 0xad: /* RES 5,L */ + L &= 0xdf; + break; + case 0xae: /* RES 5,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO( HL, bytetemp & 0xdf ); + } + break; + case 0xaf: /* RES 5,A */ + A &= 0xdf; + break; + case 0xb0: /* RES 6,B */ + B &= 0xbf; + break; + case 0xb1: /* RES 6,C */ + C &= 0xbf; + break; + case 0xb2: /* RES 6,D */ + D &= 0xbf; + break; + case 0xb3: /* RES 6,E */ + E &= 0xbf; + break; + case 0xb4: /* RES 6,H */ + H &= 0xbf; + break; + case 0xb5: /* RES 6,L */ + L &= 0xbf; + break; + case 0xb6: /* RES 6,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO( HL, bytetemp & 0xbf ); + } + break; + case 0xb7: /* RES 6,A */ + A &= 0xbf; + break; + case 0xb8: /* RES 7,B */ + B &= 0x7f; + break; + case 0xb9: /* RES 7,C */ + C &= 0x7f; + break; + case 0xba: /* RES 7,D */ + D &= 0x7f; + break; + case 0xbb: /* RES 7,E */ + E &= 0x7f; + break; + case 0xbc: /* RES 7,H */ + H &= 0x7f; + break; + case 0xbd: /* RES 7,L */ + L &= 0x7f; + break; + case 0xbe: /* RES 7,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO( HL, bytetemp & 0x7f ); + } + break; + case 0xbf: /* RES 7,A */ + A &= 0x7f; + break; + case 0xc0: /* SET 0,B */ + B |= 0x01; + break; + case 0xc1: /* SET 0,C */ + C |= 0x01; + break; + case 0xc2: /* SET 0,D */ + D |= 0x01; + break; + case 0xc3: /* SET 0,E */ + E |= 0x01; + break; + case 0xc4: /* SET 0,H */ + H |= 0x01; + break; + case 0xc5: /* SET 0,L */ + L |= 0x01; + break; + case 0xc6: /* SET 0,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO( HL, bytetemp | 0x01 ); + } + break; + case 0xc7: /* SET 0,A */ + A |= 0x01; + break; + case 0xc8: /* SET 1,B */ + B |= 0x02; + break; + case 0xc9: /* SET 1,C */ + C |= 0x02; + break; + case 0xca: /* SET 1,D */ + D |= 0x02; + break; + case 0xcb: /* SET 1,E */ + E |= 0x02; + break; + case 0xcc: /* SET 1,H */ + H |= 0x02; + break; + case 0xcd: /* SET 1,L */ + L |= 0x02; + break; + case 0xce: /* SET 1,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO( HL, bytetemp | 0x02 ); + } + break; + case 0xcf: /* SET 1,A */ + A |= 0x02; + break; + case 0xd0: /* SET 2,B */ + B |= 0x04; + break; + case 0xd1: /* SET 2,C */ + C |= 0x04; + break; + case 0xd2: /* SET 2,D */ + D |= 0x04; + break; + case 0xd3: /* SET 2,E */ + E |= 0x04; + break; + case 0xd4: /* SET 2,H */ + H |= 0x04; + break; + case 0xd5: /* SET 2,L */ + L |= 0x04; + break; + case 0xd6: /* SET 2,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO( HL, bytetemp | 0x04 ); + } + break; + case 0xd7: /* SET 2,A */ + A |= 0x04; + break; + case 0xd8: /* SET 3,B */ + B |= 0x08; + break; + case 0xd9: /* SET 3,C */ + C |= 0x08; + break; + case 0xda: /* SET 3,D */ + D |= 0x08; + break; + case 0xdb: /* SET 3,E */ + E |= 0x08; + break; + case 0xdc: /* SET 3,H */ + H |= 0x08; + break; + case 0xdd: /* SET 3,L */ + L |= 0x08; + break; + case 0xde: /* SET 3,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO( HL, bytetemp | 0x08 ); + } + break; + case 0xdf: /* SET 3,A */ + A |= 0x08; + break; + case 0xe0: /* SET 4,B */ + B |= 0x10; + break; + case 0xe1: /* SET 4,C */ + C |= 0x10; + break; + case 0xe2: /* SET 4,D */ + D |= 0x10; + break; + case 0xe3: /* SET 4,E */ + E |= 0x10; + break; + case 0xe4: /* SET 4,H */ + H |= 0x10; + break; + case 0xe5: /* SET 4,L */ + L |= 0x10; + break; + case 0xe6: /* SET 4,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO( HL, bytetemp | 0x10 ); + } + break; + case 0xe7: /* SET 4,A */ + A |= 0x10; + break; + case 0xe8: /* SET 5,B */ + B |= 0x20; + break; + case 0xe9: /* SET 5,C */ + C |= 0x20; + break; + case 0xea: /* SET 5,D */ + D |= 0x20; + break; + case 0xeb: /* SET 5,E */ + E |= 0x20; + break; + case 0xec: /* SET 5,H */ + H |= 0x20; + break; + case 0xed: /* SET 5,L */ + L |= 0x20; + break; + case 0xee: /* SET 5,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO( HL, bytetemp | 0x20 ); + } + break; + case 0xef: /* SET 5,A */ + A |= 0x20; + break; + case 0xf0: /* SET 6,B */ + B |= 0x40; + break; + case 0xf1: /* SET 6,C */ + C |= 0x40; + break; + case 0xf2: /* SET 6,D */ + D |= 0x40; + break; + case 0xf3: /* SET 6,E */ + E |= 0x40; + break; + case 0xf4: /* SET 6,H */ + H |= 0x40; + break; + case 0xf5: /* SET 6,L */ + L |= 0x40; + break; + case 0xf6: /* SET 6,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO( HL, bytetemp | 0x40 ); + } + break; + case 0xf7: /* SET 6,A */ + A |= 0x40; + break; + case 0xf8: /* SET 7,B */ + B |= 0x80; + break; + case 0xf9: /* SET 7,C */ + C |= 0x80; + break; + case 0xfa: /* SET 7,D */ + D |= 0x80; + break; + case 0xfb: /* SET 7,E */ + E |= 0x80; + break; + case 0xfc: /* SET 7,H */ + H |= 0x80; + break; + case 0xfd: /* SET 7,L */ + L |= 0x80; + break; + case 0xfe: /* SET 7,(HL) */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO( HL, bytetemp | 0x80 ); + } + break; + case 0xff: /* SET 7,A */ + A |= 0x80; + break; diff --git a/waterbox/ngp/z80-fuse/z80_ddfd.c b/waterbox/ngp/z80-fuse/z80_ddfd.c new file mode 100644 index 0000000000..aff392f15d --- /dev/null +++ b/waterbox/ngp/z80-fuse/z80_ddfd.c @@ -0,0 +1,534 @@ +/* z80_ddfd.c Z80 {DD,FD}xx opcodes + Copyright (c) 1999-2003 Philip Kendall + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: philip-fuse@shadowmagic.org.uk + +*/ + +/* NB: this file is autogenerated by 'z80.pl' from 'opcodes_ddfd.dat', + and included in 'z80_ops.c' */ + + case 0x09: /* ADD REGISTER,BC */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + ADD16(REGISTER,BC); + break; + case 0x19: /* ADD REGISTER,DE */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + ADD16(REGISTER,DE); + break; + case 0x21: /* LD REGISTER,nnnn */ + REGISTERL=Z80_RB_MACRO(PC++); + REGISTERH=Z80_RB_MACRO(PC++); + break; + case 0x22: /* LD (nnnn),REGISTER */ + LD16_NNRR(REGISTERL,REGISTERH); + break; + case 0x23: /* INC REGISTER */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + REGISTER++; + break; + case 0x24: /* INC REGISTERH */ + INC(REGISTERH); + break; + case 0x25: /* DEC REGISTERH */ + DEC(REGISTERH); + break; + case 0x26: /* LD REGISTERH,nn */ + REGISTERH = Z80_RB_MACRO( PC++ ); + break; + case 0x29: /* ADD REGISTER,REGISTER */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + ADD16(REGISTER,REGISTER); + break; + case 0x2a: /* LD REGISTER,(nnnn) */ + LD16_RRNN(REGISTERL,REGISTERH); + break; + case 0x2b: /* DEC REGISTER */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + REGISTER--; + break; + case 0x2c: /* INC REGISTERL */ + INC(REGISTERL); + break; + case 0x2d: /* DEC REGISTERL */ + DEC(REGISTERL); + break; + case 0x2e: /* LD REGISTERL,nn */ + REGISTERL = Z80_RB_MACRO( PC++ ); + break; + case 0x34: /* INC (REGISTER+dd) */ + { + uint8 offset, bytetemp; + uint16 wordtemp; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + wordtemp = REGISTER + (int8)offset; + bytetemp = Z80_RB_MACRO( wordtemp ); + contend_read_no_mreq( wordtemp, 1 ); + INC(bytetemp); + Z80_WB_MACRO(wordtemp,bytetemp); + } + break; + case 0x35: /* DEC (REGISTER+dd) */ + { + uint8 offset, bytetemp; + uint16 wordtemp; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + wordtemp = REGISTER + (int8)offset; + bytetemp = Z80_RB_MACRO( wordtemp ); + contend_read_no_mreq( wordtemp, 1 ); + DEC(bytetemp); + Z80_WB_MACRO(wordtemp,bytetemp); + } + break; + case 0x36: /* LD (REGISTER+dd),nn */ + { + uint8 offset, value; + offset = Z80_RB_MACRO( PC++ ); + value = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); PC++; + Z80_WB_MACRO( REGISTER + (int8)offset, value ); + } + break; + case 0x39: /* ADD REGISTER,SP */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + ADD16(REGISTER,SP); + break; + case 0x44: /* LD B,REGISTERH */ + B=REGISTERH; + break; + case 0x45: /* LD B,REGISTERL */ + B=REGISTERL; + break; + case 0x46: /* LD B,(REGISTER+dd) */ + { + uint8 offset; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + B = Z80_RB_MACRO( REGISTER + (int8)offset ); + } + break; + case 0x4c: /* LD C,REGISTERH */ + C=REGISTERH; + break; + case 0x4d: /* LD C,REGISTERL */ + C=REGISTERL; + break; + case 0x4e: /* LD C,(REGISTER+dd) */ + { + uint8 offset; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + C = Z80_RB_MACRO( REGISTER + (int8)offset ); + } + break; + case 0x54: /* LD D,REGISTERH */ + D=REGISTERH; + break; + case 0x55: /* LD D,REGISTERL */ + D=REGISTERL; + break; + case 0x56: /* LD D,(REGISTER+dd) */ + { + uint8 offset; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + D = Z80_RB_MACRO( REGISTER + (int8)offset ); + } + break; + case 0x5c: /* LD E,REGISTERH */ + E=REGISTERH; + break; + case 0x5d: /* LD E,REGISTERL */ + E=REGISTERL; + break; + case 0x5e: /* LD E,(REGISTER+dd) */ + { + uint8 offset; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + E = Z80_RB_MACRO( REGISTER + (int8)offset ); + } + break; + case 0x60: /* LD REGISTERH,B */ + REGISTERH=B; + break; + case 0x61: /* LD REGISTERH,C */ + REGISTERH=C; + break; + case 0x62: /* LD REGISTERH,D */ + REGISTERH=D; + break; + case 0x63: /* LD REGISTERH,E */ + REGISTERH=E; + break; + case 0x64: /* LD REGISTERH,REGISTERH */ + break; + case 0x65: /* LD REGISTERH,REGISTERL */ + REGISTERH=REGISTERL; + break; + case 0x66: /* LD H,(REGISTER+dd) */ + { + uint8 offset; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + H = Z80_RB_MACRO( REGISTER + (int8)offset ); + } + break; + case 0x67: /* LD REGISTERH,A */ + REGISTERH=A; + break; + case 0x68: /* LD REGISTERL,B */ + REGISTERL=B; + break; + case 0x69: /* LD REGISTERL,C */ + REGISTERL=C; + break; + case 0x6a: /* LD REGISTERL,D */ + REGISTERL=D; + break; + case 0x6b: /* LD REGISTERL,E */ + REGISTERL=E; + break; + case 0x6c: /* LD REGISTERL,REGISTERH */ + REGISTERL=REGISTERH; + break; + case 0x6d: /* LD REGISTERL,REGISTERL */ + break; + case 0x6e: /* LD L,(REGISTER+dd) */ + { + uint8 offset; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + L = Z80_RB_MACRO( REGISTER + (int8)offset ); + } + break; + case 0x6f: /* LD REGISTERL,A */ + REGISTERL=A; + break; + case 0x70: /* LD (REGISTER+dd),B */ + { + uint8 offset; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + Z80_WB_MACRO( REGISTER + (int8)offset, B ); + } + break; + case 0x71: /* LD (REGISTER+dd),C */ + { + uint8 offset; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + Z80_WB_MACRO( REGISTER + (int8)offset, C ); + } + break; + case 0x72: /* LD (REGISTER+dd),D */ + { + uint8 offset; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + Z80_WB_MACRO( REGISTER + (int8)offset, D ); + } + break; + case 0x73: /* LD (REGISTER+dd),E */ + { + uint8 offset; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + Z80_WB_MACRO( REGISTER + (int8)offset, E ); + } + break; + case 0x74: /* LD (REGISTER+dd),H */ + { + uint8 offset; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + Z80_WB_MACRO( REGISTER + (int8)offset, H ); + } + break; + case 0x75: /* LD (REGISTER+dd),L */ + { + uint8 offset; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + Z80_WB_MACRO( REGISTER + (int8)offset, L ); + } + break; + case 0x77: /* LD (REGISTER+dd),A */ + { + uint8 offset; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + Z80_WB_MACRO( REGISTER + (int8)offset, A ); + } + break; + case 0x7c: /* LD A,REGISTERH */ + A=REGISTERH; + break; + case 0x7d: /* LD A,REGISTERL */ + A=REGISTERL; + break; + case 0x7e: /* LD A,(REGISTER+dd) */ + { + uint8 offset; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + A = Z80_RB_MACRO( REGISTER + (int8)offset ); + } + break; + case 0x84: /* ADD A,REGISTERH */ + ADD(REGISTERH); + break; + case 0x85: /* ADD A,REGISTERL */ + ADD(REGISTERL); + break; + case 0x86: /* ADD A,(REGISTER+dd) */ + { + uint8 offset, bytetemp; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + bytetemp = Z80_RB_MACRO( REGISTER + (int8)offset ); + ADD(bytetemp); + } + break; + case 0x8c: /* ADC A,REGISTERH */ + ADC(REGISTERH); + break; + case 0x8d: /* ADC A,REGISTERL */ + ADC(REGISTERL); + break; + case 0x8e: /* ADC A,(REGISTER+dd) */ + { + uint8 offset, bytetemp; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + bytetemp = Z80_RB_MACRO( REGISTER + (int8)offset ); + ADC(bytetemp); + } + break; + case 0x94: /* SUB A,REGISTERH */ + SUB(REGISTERH); + break; + case 0x95: /* SUB A,REGISTERL */ + SUB(REGISTERL); + break; + case 0x96: /* SUB A,(REGISTER+dd) */ + { + uint8 offset, bytetemp; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + bytetemp = Z80_RB_MACRO( REGISTER + (int8)offset ); + SUB(bytetemp); + } + break; + case 0x9c: /* SBC A,REGISTERH */ + SBC(REGISTERH); + break; + case 0x9d: /* SBC A,REGISTERL */ + SBC(REGISTERL); + break; + case 0x9e: /* SBC A,(REGISTER+dd) */ + { + uint8 offset, bytetemp; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + bytetemp = Z80_RB_MACRO( REGISTER + (int8)offset ); + SBC(bytetemp); + } + break; + case 0xa4: /* AND A,REGISTERH */ + AND(REGISTERH); + break; + case 0xa5: /* AND A,REGISTERL */ + AND(REGISTERL); + break; + case 0xa6: /* AND A,(REGISTER+dd) */ + { + uint8 offset, bytetemp; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + bytetemp = Z80_RB_MACRO( REGISTER + (int8)offset ); + AND(bytetemp); + } + break; + case 0xac: /* XOR A,REGISTERH */ + XOR(REGISTERH); + break; + case 0xad: /* XOR A,REGISTERL */ + XOR(REGISTERL); + break; + case 0xae: /* XOR A,(REGISTER+dd) */ + { + uint8 offset, bytetemp; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + bytetemp = Z80_RB_MACRO( REGISTER + (int8)offset ); + XOR(bytetemp); + } + break; + case 0xb4: /* OR A,REGISTERH */ + OR(REGISTERH); + break; + case 0xb5: /* OR A,REGISTERL */ + OR(REGISTERL); + break; + case 0xb6: /* OR A,(REGISTER+dd) */ + { + uint8 offset, bytetemp; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + bytetemp = Z80_RB_MACRO( REGISTER + (int8)offset ); + OR(bytetemp); + } + break; + case 0xbc: /* CP A,REGISTERH */ + CP(REGISTERH); + break; + case 0xbd: /* CP A,REGISTERL */ + CP(REGISTERL); + break; + case 0xbe: /* CP A,(REGISTER+dd) */ + { + uint8 offset, bytetemp; + offset = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); + contend_read_no_mreq( PC, 1 ); PC++; + bytetemp = Z80_RB_MACRO( REGISTER + (int8)offset ); + CP(bytetemp); + } + break; + case 0xcb: /* shift DDFDCB */ + { + uint16 tempaddr; uint8 opcode3; + tempaddr = REGISTER + (int8)Z80_RB_MACRO( PC ); + PC++; + opcode3 = Z80_RB_MACRO( PC ); + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); PC++; + switch(opcode3) { +#include "z80_ddfdcb.c" + } + } + break; + case 0xe1: /* POP REGISTER */ + POP16(REGISTERL,REGISTERH); + break; + case 0xe3: /* EX (SP),REGISTER */ + { + uint8 bytetempl, bytetemph; + bytetempl = Z80_RB_MACRO( SP ); + bytetemph = Z80_RB_MACRO( SP + 1 ); contend_read_no_mreq( SP + 1, 1 ); + Z80_WB_MACRO( SP + 1, REGISTERH ); + Z80_WB_MACRO( SP, REGISTERL ); + contend_write_no_mreq( SP, 1 ); contend_write_no_mreq( SP, 1 ); + REGISTERL=bytetempl; REGISTERH=bytetemph; + } + break; + case 0xe5: /* PUSH REGISTER */ + contend_read_no_mreq( IR, 1 ); + PUSH16(REGISTERL,REGISTERH); + break; + case 0xe9: /* JP REGISTER */ + PC=REGISTER; /* NB: NOT INDIRECT! */ + break; + case 0xf9: /* LD SP,REGISTER */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + SP = REGISTER; + break; + default: /* Instruction did not involve H or L, so backtrack + one instruction and parse again */ + PC--; + R--; + opcode = opcode2; + break; // FIXME! + //goto end_opcode; diff --git a/waterbox/ngp/z80-fuse/z80_ddfdcb.c b/waterbox/ngp/z80-fuse/z80_ddfdcb.c new file mode 100644 index 0000000000..9e59d53229 --- /dev/null +++ b/waterbox/ngp/z80-fuse/z80_ddfdcb.c @@ -0,0 +1,1226 @@ +/* z80_ddfdcb.c Z80 {DD,FD}CBxx opcodes + Copyright (c) 1999-2003 Philip Kendall + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: philip-fuse@shadowmagic.org.uk + +*/ + +/* NB: this file is autogenerated by 'z80.pl' from 'opcodes_ddfdcb.dat', + and included in 'z80_ops.c' */ + + case 0x00: /* LD B,RLC (REGISTER+dd) */ + B=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RLC(B); + Z80_WB_MACRO(tempaddr, B); + break; + case 0x01: /* LD C,RLC (REGISTER+dd) */ + C=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RLC(C); + Z80_WB_MACRO(tempaddr, C); + break; + case 0x02: /* LD D,RLC (REGISTER+dd) */ + D=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RLC(D); + Z80_WB_MACRO(tempaddr, D); + break; + case 0x03: /* LD E,RLC (REGISTER+dd) */ + E=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RLC(E); + Z80_WB_MACRO(tempaddr, E); + break; + case 0x04: /* LD H,RLC (REGISTER+dd) */ + H=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RLC(H); + Z80_WB_MACRO(tempaddr, H); + break; + case 0x05: /* LD L,RLC (REGISTER+dd) */ + L=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RLC(L); + Z80_WB_MACRO(tempaddr, L); + break; + case 0x06: /* RLC (REGISTER+dd) */ + { + uint8 bytetemp = Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RLC(bytetemp); + Z80_WB_MACRO(tempaddr,bytetemp); + } + break; + case 0x07: /* LD A,RLC (REGISTER+dd) */ + A=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RLC(A); + Z80_WB_MACRO(tempaddr, A); + break; + case 0x08: /* LD B,RRC (REGISTER+dd) */ + B=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RRC(B); + Z80_WB_MACRO(tempaddr, B); + break; + case 0x09: /* LD C,RRC (REGISTER+dd) */ + C=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RRC(C); + Z80_WB_MACRO(tempaddr, C); + break; + case 0x0a: /* LD D,RRC (REGISTER+dd) */ + D=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RRC(D); + Z80_WB_MACRO(tempaddr, D); + break; + case 0x0b: /* LD E,RRC (REGISTER+dd) */ + E=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RRC(E); + Z80_WB_MACRO(tempaddr, E); + break; + case 0x0c: /* LD H,RRC (REGISTER+dd) */ + H=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RRC(H); + Z80_WB_MACRO(tempaddr, H); + break; + case 0x0d: /* LD L,RRC (REGISTER+dd) */ + L=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RRC(L); + Z80_WB_MACRO(tempaddr, L); + break; + case 0x0e: /* RRC (REGISTER+dd) */ + { + uint8 bytetemp = Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RRC(bytetemp); + Z80_WB_MACRO(tempaddr,bytetemp); + } + break; + case 0x0f: /* LD A,RRC (REGISTER+dd) */ + A=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RRC(A); + Z80_WB_MACRO(tempaddr, A); + break; + case 0x10: /* LD B,RL (REGISTER+dd) */ + B=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RL(B); + Z80_WB_MACRO(tempaddr, B); + break; + case 0x11: /* LD C,RL (REGISTER+dd) */ + C=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RL(C); + Z80_WB_MACRO(tempaddr, C); + break; + case 0x12: /* LD D,RL (REGISTER+dd) */ + D=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RL(D); + Z80_WB_MACRO(tempaddr, D); + break; + case 0x13: /* LD E,RL (REGISTER+dd) */ + E=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RL(E); + Z80_WB_MACRO(tempaddr, E); + break; + case 0x14: /* LD H,RL (REGISTER+dd) */ + H=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RL(H); + Z80_WB_MACRO(tempaddr, H); + break; + case 0x15: /* LD L,RL (REGISTER+dd) */ + L=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RL(L); + Z80_WB_MACRO(tempaddr, L); + break; + case 0x16: /* RL (REGISTER+dd) */ + { + uint8 bytetemp = Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RL(bytetemp); + Z80_WB_MACRO(tempaddr,bytetemp); + } + break; + case 0x17: /* LD A,RL (REGISTER+dd) */ + A=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RL(A); + Z80_WB_MACRO(tempaddr, A); + break; + case 0x18: /* LD B,RR (REGISTER+dd) */ + B=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RR(B); + Z80_WB_MACRO(tempaddr, B); + break; + case 0x19: /* LD C,RR (REGISTER+dd) */ + C=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RR(C); + Z80_WB_MACRO(tempaddr, C); + break; + case 0x1a: /* LD D,RR (REGISTER+dd) */ + D=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RR(D); + Z80_WB_MACRO(tempaddr, D); + break; + case 0x1b: /* LD E,RR (REGISTER+dd) */ + E=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RR(E); + Z80_WB_MACRO(tempaddr, E); + break; + case 0x1c: /* LD H,RR (REGISTER+dd) */ + H=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RR(H); + Z80_WB_MACRO(tempaddr, H); + break; + case 0x1d: /* LD L,RR (REGISTER+dd) */ + L=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RR(L); + Z80_WB_MACRO(tempaddr, L); + break; + case 0x1e: /* RR (REGISTER+dd) */ + { + uint8 bytetemp = Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RR(bytetemp); + Z80_WB_MACRO(tempaddr,bytetemp); + } + break; + case 0x1f: /* LD A,RR (REGISTER+dd) */ + A=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + RR(A); + Z80_WB_MACRO(tempaddr, A); + break; + case 0x20: /* LD B,SLA (REGISTER+dd) */ + B=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SLA(B); + Z80_WB_MACRO(tempaddr, B); + break; + case 0x21: /* LD C,SLA (REGISTER+dd) */ + C=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SLA(C); + Z80_WB_MACRO(tempaddr, C); + break; + case 0x22: /* LD D,SLA (REGISTER+dd) */ + D=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SLA(D); + Z80_WB_MACRO(tempaddr, D); + break; + case 0x23: /* LD E,SLA (REGISTER+dd) */ + E=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SLA(E); + Z80_WB_MACRO(tempaddr, E); + break; + case 0x24: /* LD H,SLA (REGISTER+dd) */ + H=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SLA(H); + Z80_WB_MACRO(tempaddr, H); + break; + case 0x25: /* LD L,SLA (REGISTER+dd) */ + L=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SLA(L); + Z80_WB_MACRO(tempaddr, L); + break; + case 0x26: /* SLA (REGISTER+dd) */ + { + uint8 bytetemp = Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SLA(bytetemp); + Z80_WB_MACRO(tempaddr,bytetemp); + } + break; + case 0x27: /* LD A,SLA (REGISTER+dd) */ + A=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SLA(A); + Z80_WB_MACRO(tempaddr, A); + break; + case 0x28: /* LD B,SRA (REGISTER+dd) */ + B=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SRA(B); + Z80_WB_MACRO(tempaddr, B); + break; + case 0x29: /* LD C,SRA (REGISTER+dd) */ + C=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SRA(C); + Z80_WB_MACRO(tempaddr, C); + break; + case 0x2a: /* LD D,SRA (REGISTER+dd) */ + D=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SRA(D); + Z80_WB_MACRO(tempaddr, D); + break; + case 0x2b: /* LD E,SRA (REGISTER+dd) */ + E=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SRA(E); + Z80_WB_MACRO(tempaddr, E); + break; + case 0x2c: /* LD H,SRA (REGISTER+dd) */ + H=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SRA(H); + Z80_WB_MACRO(tempaddr, H); + break; + case 0x2d: /* LD L,SRA (REGISTER+dd) */ + L=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SRA(L); + Z80_WB_MACRO(tempaddr, L); + break; + case 0x2e: /* SRA (REGISTER+dd) */ + { + uint8 bytetemp = Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SRA(bytetemp); + Z80_WB_MACRO(tempaddr,bytetemp); + } + break; + case 0x2f: /* LD A,SRA (REGISTER+dd) */ + A=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SRA(A); + Z80_WB_MACRO(tempaddr, A); + break; + case 0x30: /* LD B,SLL (REGISTER+dd) */ + B=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SLL(B); + Z80_WB_MACRO(tempaddr, B); + break; + case 0x31: /* LD C,SLL (REGISTER+dd) */ + C=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SLL(C); + Z80_WB_MACRO(tempaddr, C); + break; + case 0x32: /* LD D,SLL (REGISTER+dd) */ + D=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SLL(D); + Z80_WB_MACRO(tempaddr, D); + break; + case 0x33: /* LD E,SLL (REGISTER+dd) */ + E=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SLL(E); + Z80_WB_MACRO(tempaddr, E); + break; + case 0x34: /* LD H,SLL (REGISTER+dd) */ + H=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SLL(H); + Z80_WB_MACRO(tempaddr, H); + break; + case 0x35: /* LD L,SLL (REGISTER+dd) */ + L=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SLL(L); + Z80_WB_MACRO(tempaddr, L); + break; + case 0x36: /* SLL (REGISTER+dd) */ + { + uint8 bytetemp = Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SLL(bytetemp); + Z80_WB_MACRO(tempaddr,bytetemp); + } + break; + case 0x37: /* LD A,SLL (REGISTER+dd) */ + A=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SLL(A); + Z80_WB_MACRO(tempaddr, A); + break; + case 0x38: /* LD B,SRL (REGISTER+dd) */ + B=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SRL(B); + Z80_WB_MACRO(tempaddr, B); + break; + case 0x39: /* LD C,SRL (REGISTER+dd) */ + C=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SRL(C); + Z80_WB_MACRO(tempaddr, C); + break; + case 0x3a: /* LD D,SRL (REGISTER+dd) */ + D=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SRL(D); + Z80_WB_MACRO(tempaddr, D); + break; + case 0x3b: /* LD E,SRL (REGISTER+dd) */ + E=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SRL(E); + Z80_WB_MACRO(tempaddr, E); + break; + case 0x3c: /* LD H,SRL (REGISTER+dd) */ + H=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SRL(H); + Z80_WB_MACRO(tempaddr, H); + break; + case 0x3d: /* LD L,SRL (REGISTER+dd) */ + L=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SRL(L); + Z80_WB_MACRO(tempaddr, L); + break; + case 0x3e: /* SRL (REGISTER+dd) */ + { + uint8 bytetemp = Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SRL(bytetemp); + Z80_WB_MACRO(tempaddr,bytetemp); + } + break; + case 0x3f: /* LD A,SRL (REGISTER+dd) */ + A=Z80_RB_MACRO(tempaddr); + contend_read_no_mreq( tempaddr, 1 ); + SRL(A); + Z80_WB_MACRO(tempaddr, A); + break; + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: /* BIT 0,(REGISTER+dd) */ + { + uint8 bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + BIT_I( 0, bytetemp, tempaddr ); + } + break; + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: /* BIT 1,(REGISTER+dd) */ + { + uint8 bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + BIT_I( 1, bytetemp, tempaddr ); + } + break; + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: /* BIT 2,(REGISTER+dd) */ + { + uint8 bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + BIT_I( 2, bytetemp, tempaddr ); + } + break; + case 0x58: + case 0x59: + case 0x5a: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x5e: + case 0x5f: /* BIT 3,(REGISTER+dd) */ + { + uint8 bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + BIT_I( 3, bytetemp, tempaddr ); + } + break; + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: /* BIT 4,(REGISTER+dd) */ + { + uint8 bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + BIT_I( 4, bytetemp, tempaddr ); + } + break; + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: /* BIT 5,(REGISTER+dd) */ + { + uint8 bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + BIT_I( 5, bytetemp, tempaddr ); + } + break; + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: /* BIT 6,(REGISTER+dd) */ + { + uint8 bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + BIT_I( 6, bytetemp, tempaddr ); + } + break; + case 0x78: + case 0x79: + case 0x7a: + case 0x7b: + case 0x7c: + case 0x7d: + case 0x7e: + case 0x7f: /* BIT 7,(REGISTER+dd) */ + { + uint8 bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + BIT_I( 7, bytetemp, tempaddr ); + } + break; + case 0x80: /* LD B,RES 0,(REGISTER+dd) */ + B = Z80_RB_MACRO(tempaddr) & 0xfe; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, B); + break; + case 0x81: /* LD C,RES 0,(REGISTER+dd) */ + C = Z80_RB_MACRO(tempaddr) & 0xfe; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, C); + break; + case 0x82: /* LD D,RES 0,(REGISTER+dd) */ + D = Z80_RB_MACRO(tempaddr) & 0xfe; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, D); + break; + case 0x83: /* LD E,RES 0,(REGISTER+dd) */ + E = Z80_RB_MACRO(tempaddr) & 0xfe; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, E); + break; + case 0x84: /* LD H,RES 0,(REGISTER+dd) */ + H = Z80_RB_MACRO(tempaddr) & 0xfe; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, H); + break; + case 0x85: /* LD L,RES 0,(REGISTER+dd) */ + L = Z80_RB_MACRO(tempaddr) & 0xfe; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, L); + break; + case 0x86: /* RES 0,(REGISTER+dd) */ + { + uint8 bytetemp; + bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO( tempaddr, bytetemp & 0xfe ); + } + break; + case 0x87: /* LD A,RES 0,(REGISTER+dd) */ + A = Z80_RB_MACRO(tempaddr) & 0xfe; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, A); + break; + case 0x88: /* LD B,RES 1,(REGISTER+dd) */ + B = Z80_RB_MACRO(tempaddr) & 0xfd; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, B); + break; + case 0x89: /* LD C,RES 1,(REGISTER+dd) */ + C = Z80_RB_MACRO(tempaddr) & 0xfd; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, C); + break; + case 0x8a: /* LD D,RES 1,(REGISTER+dd) */ + D = Z80_RB_MACRO(tempaddr) & 0xfd; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, D); + break; + case 0x8b: /* LD E,RES 1,(REGISTER+dd) */ + E = Z80_RB_MACRO(tempaddr) & 0xfd; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, E); + break; + case 0x8c: /* LD H,RES 1,(REGISTER+dd) */ + H = Z80_RB_MACRO(tempaddr) & 0xfd; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, H); + break; + case 0x8d: /* LD L,RES 1,(REGISTER+dd) */ + L = Z80_RB_MACRO(tempaddr) & 0xfd; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, L); + break; + case 0x8e: /* RES 1,(REGISTER+dd) */ + { + uint8 bytetemp; + bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO( tempaddr, bytetemp & 0xfd ); + } + break; + case 0x8f: /* LD A,RES 1,(REGISTER+dd) */ + A = Z80_RB_MACRO(tempaddr) & 0xfd; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, A); + break; + case 0x90: /* LD B,RES 2,(REGISTER+dd) */ + B = Z80_RB_MACRO(tempaddr) & 0xfb; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, B); + break; + case 0x91: /* LD C,RES 2,(REGISTER+dd) */ + C = Z80_RB_MACRO(tempaddr) & 0xfb; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, C); + break; + case 0x92: /* LD D,RES 2,(REGISTER+dd) */ + D = Z80_RB_MACRO(tempaddr) & 0xfb; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, D); + break; + case 0x93: /* LD E,RES 2,(REGISTER+dd) */ + E = Z80_RB_MACRO(tempaddr) & 0xfb; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, E); + break; + case 0x94: /* LD H,RES 2,(REGISTER+dd) */ + H = Z80_RB_MACRO(tempaddr) & 0xfb; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, H); + break; + case 0x95: /* LD L,RES 2,(REGISTER+dd) */ + L = Z80_RB_MACRO(tempaddr) & 0xfb; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, L); + break; + case 0x96: /* RES 2,(REGISTER+dd) */ + { + uint8 bytetemp; + bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO( tempaddr, bytetemp & 0xfb ); + } + break; + case 0x97: /* LD A,RES 2,(REGISTER+dd) */ + A = Z80_RB_MACRO(tempaddr) & 0xfb; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, A); + break; + case 0x98: /* LD B,RES 3,(REGISTER+dd) */ + B = Z80_RB_MACRO(tempaddr) & 0xf7; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, B); + break; + case 0x99: /* LD C,RES 3,(REGISTER+dd) */ + C = Z80_RB_MACRO(tempaddr) & 0xf7; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, C); + break; + case 0x9a: /* LD D,RES 3,(REGISTER+dd) */ + D = Z80_RB_MACRO(tempaddr) & 0xf7; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, D); + break; + case 0x9b: /* LD E,RES 3,(REGISTER+dd) */ + E = Z80_RB_MACRO(tempaddr) & 0xf7; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, E); + break; + case 0x9c: /* LD H,RES 3,(REGISTER+dd) */ + H = Z80_RB_MACRO(tempaddr) & 0xf7; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, H); + break; + case 0x9d: /* LD L,RES 3,(REGISTER+dd) */ + L = Z80_RB_MACRO(tempaddr) & 0xf7; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, L); + break; + case 0x9e: /* RES 3,(REGISTER+dd) */ + { + uint8 bytetemp; + bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO( tempaddr, bytetemp & 0xf7 ); + } + break; + case 0x9f: /* LD A,RES 3,(REGISTER+dd) */ + A = Z80_RB_MACRO(tempaddr) & 0xf7; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, A); + break; + case 0xa0: /* LD B,RES 4,(REGISTER+dd) */ + B = Z80_RB_MACRO(tempaddr) & 0xef; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, B); + break; + case 0xa1: /* LD C,RES 4,(REGISTER+dd) */ + C = Z80_RB_MACRO(tempaddr) & 0xef; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, C); + break; + case 0xa2: /* LD D,RES 4,(REGISTER+dd) */ + D = Z80_RB_MACRO(tempaddr) & 0xef; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, D); + break; + case 0xa3: /* LD E,RES 4,(REGISTER+dd) */ + E = Z80_RB_MACRO(tempaddr) & 0xef; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, E); + break; + case 0xa4: /* LD H,RES 4,(REGISTER+dd) */ + H = Z80_RB_MACRO(tempaddr) & 0xef; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, H); + break; + case 0xa5: /* LD L,RES 4,(REGISTER+dd) */ + L = Z80_RB_MACRO(tempaddr) & 0xef; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, L); + break; + case 0xa6: /* RES 4,(REGISTER+dd) */ + { + uint8 bytetemp; + bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO( tempaddr, bytetemp & 0xef ); + } + break; + case 0xa7: /* LD A,RES 4,(REGISTER+dd) */ + A = Z80_RB_MACRO(tempaddr) & 0xef; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, A); + break; + case 0xa8: /* LD B,RES 5,(REGISTER+dd) */ + B = Z80_RB_MACRO(tempaddr) & 0xdf; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, B); + break; + case 0xa9: /* LD C,RES 5,(REGISTER+dd) */ + C = Z80_RB_MACRO(tempaddr) & 0xdf; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, C); + break; + case 0xaa: /* LD D,RES 5,(REGISTER+dd) */ + D = Z80_RB_MACRO(tempaddr) & 0xdf; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, D); + break; + case 0xab: /* LD E,RES 5,(REGISTER+dd) */ + E = Z80_RB_MACRO(tempaddr) & 0xdf; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, E); + break; + case 0xac: /* LD H,RES 5,(REGISTER+dd) */ + H = Z80_RB_MACRO(tempaddr) & 0xdf; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, H); + break; + case 0xad: /* LD L,RES 5,(REGISTER+dd) */ + L = Z80_RB_MACRO(tempaddr) & 0xdf; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, L); + break; + case 0xae: /* RES 5,(REGISTER+dd) */ + { + uint8 bytetemp; + bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO( tempaddr, bytetemp & 0xdf ); + } + break; + case 0xaf: /* LD A,RES 5,(REGISTER+dd) */ + A = Z80_RB_MACRO(tempaddr) & 0xdf; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, A); + break; + case 0xb0: /* LD B,RES 6,(REGISTER+dd) */ + B = Z80_RB_MACRO(tempaddr) & 0xbf; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, B); + break; + case 0xb1: /* LD C,RES 6,(REGISTER+dd) */ + C = Z80_RB_MACRO(tempaddr) & 0xbf; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, C); + break; + case 0xb2: /* LD D,RES 6,(REGISTER+dd) */ + D = Z80_RB_MACRO(tempaddr) & 0xbf; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, D); + break; + case 0xb3: /* LD E,RES 6,(REGISTER+dd) */ + E = Z80_RB_MACRO(tempaddr) & 0xbf; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, E); + break; + case 0xb4: /* LD H,RES 6,(REGISTER+dd) */ + H = Z80_RB_MACRO(tempaddr) & 0xbf; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, H); + break; + case 0xb5: /* LD L,RES 6,(REGISTER+dd) */ + L = Z80_RB_MACRO(tempaddr) & 0xbf; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, L); + break; + case 0xb6: /* RES 6,(REGISTER+dd) */ + { + uint8 bytetemp; + bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO( tempaddr, bytetemp & 0xbf ); + } + break; + case 0xb7: /* LD A,RES 6,(REGISTER+dd) */ + A = Z80_RB_MACRO(tempaddr) & 0xbf; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, A); + break; + case 0xb8: /* LD B,RES 7,(REGISTER+dd) */ + B = Z80_RB_MACRO(tempaddr) & 0x7f; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, B); + break; + case 0xb9: /* LD C,RES 7,(REGISTER+dd) */ + C = Z80_RB_MACRO(tempaddr) & 0x7f; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, C); + break; + case 0xba: /* LD D,RES 7,(REGISTER+dd) */ + D = Z80_RB_MACRO(tempaddr) & 0x7f; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, D); + break; + case 0xbb: /* LD E,RES 7,(REGISTER+dd) */ + E = Z80_RB_MACRO(tempaddr) & 0x7f; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, E); + break; + case 0xbc: /* LD H,RES 7,(REGISTER+dd) */ + H = Z80_RB_MACRO(tempaddr) & 0x7f; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, H); + break; + case 0xbd: /* LD L,RES 7,(REGISTER+dd) */ + L = Z80_RB_MACRO(tempaddr) & 0x7f; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, L); + break; + case 0xbe: /* RES 7,(REGISTER+dd) */ + { + uint8 bytetemp; + bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO( tempaddr, bytetemp & 0x7f ); + } + break; + case 0xbf: /* LD A,RES 7,(REGISTER+dd) */ + A = Z80_RB_MACRO(tempaddr) & 0x7f; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, A); + break; + case 0xc0: /* LD B,SET 0,(REGISTER+dd) */ + B = Z80_RB_MACRO(tempaddr) | 0x01; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, B); + break; + case 0xc1: /* LD C,SET 0,(REGISTER+dd) */ + C = Z80_RB_MACRO(tempaddr) | 0x01; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, C); + break; + case 0xc2: /* LD D,SET 0,(REGISTER+dd) */ + D = Z80_RB_MACRO(tempaddr) | 0x01; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, D); + break; + case 0xc3: /* LD E,SET 0,(REGISTER+dd) */ + E = Z80_RB_MACRO(tempaddr) | 0x01; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, E); + break; + case 0xc4: /* LD H,SET 0,(REGISTER+dd) */ + H = Z80_RB_MACRO(tempaddr) | 0x01; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, H); + break; + case 0xc5: /* LD L,SET 0,(REGISTER+dd) */ + L = Z80_RB_MACRO(tempaddr) | 0x01; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, L); + break; + case 0xc6: /* SET 0,(REGISTER+dd) */ + { + uint8 bytetemp; + bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO( tempaddr, bytetemp | 0x01 ); + } + break; + case 0xc7: /* LD A,SET 0,(REGISTER+dd) */ + A = Z80_RB_MACRO(tempaddr) | 0x01; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, A); + break; + case 0xc8: /* LD B,SET 1,(REGISTER+dd) */ + B = Z80_RB_MACRO(tempaddr) | 0x02; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, B); + break; + case 0xc9: /* LD C,SET 1,(REGISTER+dd) */ + C = Z80_RB_MACRO(tempaddr) | 0x02; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, C); + break; + case 0xca: /* LD D,SET 1,(REGISTER+dd) */ + D = Z80_RB_MACRO(tempaddr) | 0x02; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, D); + break; + case 0xcb: /* LD E,SET 1,(REGISTER+dd) */ + E = Z80_RB_MACRO(tempaddr) | 0x02; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, E); + break; + case 0xcc: /* LD H,SET 1,(REGISTER+dd) */ + H = Z80_RB_MACRO(tempaddr) | 0x02; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, H); + break; + case 0xcd: /* LD L,SET 1,(REGISTER+dd) */ + L = Z80_RB_MACRO(tempaddr) | 0x02; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, L); + break; + case 0xce: /* SET 1,(REGISTER+dd) */ + { + uint8 bytetemp; + bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO( tempaddr, bytetemp | 0x02 ); + } + break; + case 0xcf: /* LD A,SET 1,(REGISTER+dd) */ + A = Z80_RB_MACRO(tempaddr) | 0x02; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, A); + break; + case 0xd0: /* LD B,SET 2,(REGISTER+dd) */ + B = Z80_RB_MACRO(tempaddr) | 0x04; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, B); + break; + case 0xd1: /* LD C,SET 2,(REGISTER+dd) */ + C = Z80_RB_MACRO(tempaddr) | 0x04; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, C); + break; + case 0xd2: /* LD D,SET 2,(REGISTER+dd) */ + D = Z80_RB_MACRO(tempaddr) | 0x04; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, D); + break; + case 0xd3: /* LD E,SET 2,(REGISTER+dd) */ + E = Z80_RB_MACRO(tempaddr) | 0x04; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, E); + break; + case 0xd4: /* LD H,SET 2,(REGISTER+dd) */ + H = Z80_RB_MACRO(tempaddr) | 0x04; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, H); + break; + case 0xd5: /* LD L,SET 2,(REGISTER+dd) */ + L = Z80_RB_MACRO(tempaddr) | 0x04; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, L); + break; + case 0xd6: /* SET 2,(REGISTER+dd) */ + { + uint8 bytetemp; + bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO( tempaddr, bytetemp | 0x04 ); + } + break; + case 0xd7: /* LD A,SET 2,(REGISTER+dd) */ + A = Z80_RB_MACRO(tempaddr) | 0x04; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, A); + break; + case 0xd8: /* LD B,SET 3,(REGISTER+dd) */ + B = Z80_RB_MACRO(tempaddr) | 0x08; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, B); + break; + case 0xd9: /* LD C,SET 3,(REGISTER+dd) */ + C = Z80_RB_MACRO(tempaddr) | 0x08; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, C); + break; + case 0xda: /* LD D,SET 3,(REGISTER+dd) */ + D = Z80_RB_MACRO(tempaddr) | 0x08; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, D); + break; + case 0xdb: /* LD E,SET 3,(REGISTER+dd) */ + E = Z80_RB_MACRO(tempaddr) | 0x08; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, E); + break; + case 0xdc: /* LD H,SET 3,(REGISTER+dd) */ + H = Z80_RB_MACRO(tempaddr) | 0x08; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, H); + break; + case 0xdd: /* LD L,SET 3,(REGISTER+dd) */ + L = Z80_RB_MACRO(tempaddr) | 0x08; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, L); + break; + case 0xde: /* SET 3,(REGISTER+dd) */ + { + uint8 bytetemp; + bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO( tempaddr, bytetemp | 0x08 ); + } + break; + case 0xdf: /* LD A,SET 3,(REGISTER+dd) */ + A = Z80_RB_MACRO(tempaddr) | 0x08; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, A); + break; + case 0xe0: /* LD B,SET 4,(REGISTER+dd) */ + B = Z80_RB_MACRO(tempaddr) | 0x10; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, B); + break; + case 0xe1: /* LD C,SET 4,(REGISTER+dd) */ + C = Z80_RB_MACRO(tempaddr) | 0x10; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, C); + break; + case 0xe2: /* LD D,SET 4,(REGISTER+dd) */ + D = Z80_RB_MACRO(tempaddr) | 0x10; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, D); + break; + case 0xe3: /* LD E,SET 4,(REGISTER+dd) */ + E = Z80_RB_MACRO(tempaddr) | 0x10; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, E); + break; + case 0xe4: /* LD H,SET 4,(REGISTER+dd) */ + H = Z80_RB_MACRO(tempaddr) | 0x10; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, H); + break; + case 0xe5: /* LD L,SET 4,(REGISTER+dd) */ + L = Z80_RB_MACRO(tempaddr) | 0x10; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, L); + break; + case 0xe6: /* SET 4,(REGISTER+dd) */ + { + uint8 bytetemp; + bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO( tempaddr, bytetemp | 0x10 ); + } + break; + case 0xe7: /* LD A,SET 4,(REGISTER+dd) */ + A = Z80_RB_MACRO(tempaddr) | 0x10; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, A); + break; + case 0xe8: /* LD B,SET 5,(REGISTER+dd) */ + B = Z80_RB_MACRO(tempaddr) | 0x20; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, B); + break; + case 0xe9: /* LD C,SET 5,(REGISTER+dd) */ + C = Z80_RB_MACRO(tempaddr) | 0x20; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, C); + break; + case 0xea: /* LD D,SET 5,(REGISTER+dd) */ + D = Z80_RB_MACRO(tempaddr) | 0x20; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, D); + break; + case 0xeb: /* LD E,SET 5,(REGISTER+dd) */ + E = Z80_RB_MACRO(tempaddr) | 0x20; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, E); + break; + case 0xec: /* LD H,SET 5,(REGISTER+dd) */ + H = Z80_RB_MACRO(tempaddr) | 0x20; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, H); + break; + case 0xed: /* LD L,SET 5,(REGISTER+dd) */ + L = Z80_RB_MACRO(tempaddr) | 0x20; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, L); + break; + case 0xee: /* SET 5,(REGISTER+dd) */ + { + uint8 bytetemp; + bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO( tempaddr, bytetemp | 0x20 ); + } + break; + case 0xef: /* LD A,SET 5,(REGISTER+dd) */ + A = Z80_RB_MACRO(tempaddr) | 0x20; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, A); + break; + case 0xf0: /* LD B,SET 6,(REGISTER+dd) */ + B = Z80_RB_MACRO(tempaddr) | 0x40; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, B); + break; + case 0xf1: /* LD C,SET 6,(REGISTER+dd) */ + C = Z80_RB_MACRO(tempaddr) | 0x40; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, C); + break; + case 0xf2: /* LD D,SET 6,(REGISTER+dd) */ + D = Z80_RB_MACRO(tempaddr) | 0x40; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, D); + break; + case 0xf3: /* LD E,SET 6,(REGISTER+dd) */ + E = Z80_RB_MACRO(tempaddr) | 0x40; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, E); + break; + case 0xf4: /* LD H,SET 6,(REGISTER+dd) */ + H = Z80_RB_MACRO(tempaddr) | 0x40; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, H); + break; + case 0xf5: /* LD L,SET 6,(REGISTER+dd) */ + L = Z80_RB_MACRO(tempaddr) | 0x40; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, L); + break; + case 0xf6: /* SET 6,(REGISTER+dd) */ + { + uint8 bytetemp; + bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO( tempaddr, bytetemp | 0x40 ); + } + break; + case 0xf7: /* LD A,SET 6,(REGISTER+dd) */ + A = Z80_RB_MACRO(tempaddr) | 0x40; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, A); + break; + case 0xf8: /* LD B,SET 7,(REGISTER+dd) */ + B = Z80_RB_MACRO(tempaddr) | 0x80; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, B); + break; + case 0xf9: /* LD C,SET 7,(REGISTER+dd) */ + C = Z80_RB_MACRO(tempaddr) | 0x80; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, C); + break; + case 0xfa: /* LD D,SET 7,(REGISTER+dd) */ + D = Z80_RB_MACRO(tempaddr) | 0x80; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, D); + break; + case 0xfb: /* LD E,SET 7,(REGISTER+dd) */ + E = Z80_RB_MACRO(tempaddr) | 0x80; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, E); + break; + case 0xfc: /* LD H,SET 7,(REGISTER+dd) */ + H = Z80_RB_MACRO(tempaddr) | 0x80; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, H); + break; + case 0xfd: /* LD L,SET 7,(REGISTER+dd) */ + L = Z80_RB_MACRO(tempaddr) | 0x80; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, L); + break; + case 0xfe: /* SET 7,(REGISTER+dd) */ + { + uint8 bytetemp; + bytetemp = Z80_RB_MACRO( tempaddr ); + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO( tempaddr, bytetemp | 0x80 ); + } + break; + case 0xff: /* LD A,SET 7,(REGISTER+dd) */ + A = Z80_RB_MACRO(tempaddr) | 0x80; + contend_read_no_mreq( tempaddr, 1 ); + Z80_WB_MACRO(tempaddr, A); + break; diff --git a/waterbox/ngp/z80-fuse/z80_ed.c b/waterbox/ngp/z80-fuse/z80_ed.c new file mode 100644 index 0000000000..e53ce22942 --- /dev/null +++ b/waterbox/ngp/z80-fuse/z80_ed.c @@ -0,0 +1,567 @@ +/* z80_ed.c: Z80 CBxx opcodes + Copyright (c) 1999-2003 Philip Kendall + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: philip-fuse@shadowmagic.org.uk + +*/ + +/* NB: this file is autogenerated by 'z80.pl' from 'opcodes_ed.dat', + and included in 'z80_ops.c' */ + + case 0x40: /* IN B,(C) */ + Z80_IN( B, BC ); + break; + case 0x41: /* OUT (C),B */ + Z80_WP_MACRO( BC, B ); + break; + case 0x42: /* SBC HL,BC */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + SBC16(BC); + break; + case 0x43: /* LD (nnnn),BC */ + LD16_NNRR(C,B); + break; + case 0x44: + case 0x4c: + case 0x54: + case 0x5c: + case 0x64: + case 0x6c: + case 0x74: + case 0x7c: /* NEG */ + { + uint8 bytetemp=A; + A=0; + SUB(bytetemp); + } + break; + case 0x45: + case 0x4d: + case 0x55: + case 0x5d: + case 0x65: + case 0x6d: + case 0x75: + case 0x7d: /* RETN */ + IFF1=IFF2; + RET(); + break; + case 0x46: + case 0x4e: + case 0x66: + case 0x6e: /* IM 0 */ + IM=0; + break; + case 0x47: /* LD I,A */ + contend_read_no_mreq( IR, 1 ); + I=A; + break; + case 0x48: /* IN C,(C) */ + Z80_IN( C, BC ); + break; + case 0x49: /* OUT (C),C */ + Z80_WP_MACRO( BC, C ); + break; + case 0x4a: /* ADC HL,BC */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + ADC16(BC); + break; + case 0x4b: /* LD BC,(nnnn) */ + LD16_RRNN(C,B); + break; + case 0x4f: /* LD R,A */ + contend_read_no_mreq( IR, 1 ); + R=R7=A; + break; + case 0x50: /* IN D,(C) */ + Z80_IN( D, BC ); + break; + case 0x51: /* OUT (C),D */ + Z80_WP_MACRO( BC, D ); + break; + case 0x52: /* SBC HL,DE */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + SBC16(DE); + break; + case 0x53: /* LD (nnnn),DE */ + LD16_NNRR(E,D); + break; + case 0x56: + case 0x76: /* IM 1 */ + IM=1; + break; + case 0x57: /* LD A,I */ + contend_read_no_mreq( IR, 1 ); + A=I; + F = ( F & FLAG_C ) | sz53_table[A] | ( IFF2 ? FLAG_V : 0 ); + break; + case 0x58: /* IN E,(C) */ + Z80_IN( E, BC ); + break; + case 0x59: /* OUT (C),E */ + Z80_WP_MACRO( BC, E ); + break; + case 0x5a: /* ADC HL,DE */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + ADC16(DE); + break; + case 0x5b: /* LD DE,(nnnn) */ + LD16_RRNN(E,D); + break; + case 0x5e: + case 0x7e: /* IM 2 */ + IM=2; + break; + case 0x5f: /* LD A,R */ + contend_read_no_mreq( IR, 1 ); + A=(R&0x7f) | (R7&0x80); + F = ( F & FLAG_C ) | sz53_table[A] | ( IFF2 ? FLAG_V : 0 ); + break; + case 0x60: /* IN H,(C) */ + Z80_IN( H, BC ); + break; + case 0x61: /* OUT (C),H */ + Z80_WP_MACRO( BC, H ); + break; + case 0x62: /* SBC HL,HL */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + SBC16(HL); + break; + case 0x63: /* LD (nnnn),HL */ + LD16_NNRR(L,H); + break; + case 0x67: /* RRD */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); contend_read_no_mreq( HL, 1 ); + contend_read_no_mreq( HL, 1 ); contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO(HL, ( A << 4 ) | ( bytetemp >> 4 ) ); + A = ( A & 0xf0 ) | ( bytetemp & 0x0f ); + F = ( F & FLAG_C ) | sz53p_table[A]; + } + break; + case 0x68: /* IN L,(C) */ + Z80_IN( L, BC ); + break; + case 0x69: /* OUT (C),L */ + Z80_WP_MACRO( BC, L ); + break; + case 0x6a: /* ADC HL,HL */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + ADC16(HL); + break; + case 0x6b: /* LD HL,(nnnn) */ + LD16_RRNN(L,H); + break; + case 0x6f: /* RLD */ + { + uint8 bytetemp = Z80_RB_MACRO( HL ); + contend_read_no_mreq( HL, 1 ); contend_read_no_mreq( HL, 1 ); + contend_read_no_mreq( HL, 1 ); contend_read_no_mreq( HL, 1 ); + Z80_WB_MACRO(HL, (bytetemp << 4 ) | ( A & 0x0f ) ); + A = ( A & 0xf0 ) | ( bytetemp >> 4 ); + F = ( F & FLAG_C ) | sz53p_table[A]; + } + break; + case 0x70: /* IN F,(C) */ + { + uint8 bytetemp; + Z80_IN( bytetemp, BC ); + } + break; + case 0x71: /* OUT (C),0 */ + Z80_WP_MACRO( BC, 0 ); + break; + case 0x72: /* SBC HL,SP */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + SBC16(SP); + break; + case 0x73: /* LD (nnnn),SP */ + LD16_NNRR(SPL,SPH); + break; + case 0x78: /* IN A,(C) */ + Z80_IN( A, BC ); + break; + case 0x79: /* OUT (C),A */ + Z80_WP_MACRO( BC, A ); + break; + case 0x7a: /* ADC HL,SP */ + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + contend_read_no_mreq( IR, 1 ); + ADC16(SP); + break; + case 0x7b: /* LD SP,(nnnn) */ + LD16_RRNN(SPL,SPH); + break; + case 0xa0: /* LDI */ + { + uint8 bytetemp=Z80_RB_MACRO( HL ); + BC--; + Z80_WB_MACRO(DE,bytetemp); + contend_write_no_mreq( DE, 1 ); contend_write_no_mreq( DE, 1 ); + DE++; HL++; + bytetemp += A; + F = ( F & ( FLAG_C | FLAG_Z | FLAG_S ) ) | ( BC ? FLAG_V : 0 ) | + ( bytetemp & FLAG_3 ) | ( (bytetemp & 0x02) ? FLAG_5 : 0 ); + } + break; + case 0xa1: /* CPI */ + { + uint8 value = Z80_RB_MACRO( HL ), bytetemp = A - value, + lookup = ( ( A & 0x08 ) >> 3 ) | + ( ( (value) & 0x08 ) >> 2 ) | + ( ( bytetemp & 0x08 ) >> 1 ); + contend_read_no_mreq( HL, 1 ); contend_read_no_mreq( HL, 1 ); + contend_read_no_mreq( HL, 1 ); contend_read_no_mreq( HL, 1 ); + contend_read_no_mreq( HL, 1 ); + HL++; BC--; + F = ( F & FLAG_C ) | ( BC ? ( FLAG_V | FLAG_N ) : FLAG_N ) | + halfcarry_sub_table[lookup] | ( bytetemp ? 0 : FLAG_Z ) | + ( bytetemp & FLAG_S ); + if(F & FLAG_H) bytetemp--; + F |= ( bytetemp & FLAG_3 ) | ( (bytetemp&0x02) ? FLAG_5 : 0 ); + } + break; + case 0xa2: /* INI */ + { + uint8 initemp, initemp2; + + contend_read_no_mreq( IR, 1 ); + initemp = Z80_RP_MACRO( BC ); + Z80_WB_MACRO( HL, initemp ); + + B--; HL++; + initemp2 = initemp + C + 1; + F = ( initemp & 0x80 ? FLAG_N : 0 ) | + ( ( initemp2 < initemp ) ? FLAG_H | FLAG_C : 0 ) | + ( parity_table[ ( initemp2 & 0x07 ) ^ B ] ? FLAG_P : 0 ) | + sz53_table[B]; + } + break; + case 0xa3: /* OUTI */ + { + uint8 outitemp, outitemp2; + + contend_read_no_mreq( IR, 1 ); + outitemp = Z80_RB_MACRO( HL ); + B--; /* This does happen first, despite what the specs say */ + Z80_WP_MACRO(BC,outitemp); + + HL++; + outitemp2 = outitemp + L; + F = ( outitemp & 0x80 ? FLAG_N : 0 ) | + ( ( outitemp2 < outitemp ) ? FLAG_H | FLAG_C : 0 ) | + ( parity_table[ ( outitemp2 & 0x07 ) ^ B ] ? FLAG_P : 0 ) | + sz53_table[B]; + } + break; + case 0xa8: /* LDD */ + { + uint8 bytetemp=Z80_RB_MACRO( HL ); + BC--; + Z80_WB_MACRO(DE,bytetemp); + contend_write_no_mreq( DE, 1 ); contend_write_no_mreq( DE, 1 ); + DE--; HL--; + bytetemp += A; + F = ( F & ( FLAG_C | FLAG_Z | FLAG_S ) ) | ( BC ? FLAG_V : 0 ) | + ( bytetemp & FLAG_3 ) | ( (bytetemp & 0x02) ? FLAG_5 : 0 ); + } + break; + case 0xa9: /* CPD */ + { + uint8 value = Z80_RB_MACRO( HL ), bytetemp = A - value, + lookup = ( ( A & 0x08 ) >> 3 ) | + ( ( (value) & 0x08 ) >> 2 ) | + ( ( bytetemp & 0x08 ) >> 1 ); + contend_read_no_mreq( HL, 1 ); contend_read_no_mreq( HL, 1 ); + contend_read_no_mreq( HL, 1 ); contend_read_no_mreq( HL, 1 ); + contend_read_no_mreq( HL, 1 ); + HL--; BC--; + F = ( F & FLAG_C ) | ( BC ? ( FLAG_V | FLAG_N ) : FLAG_N ) | + halfcarry_sub_table[lookup] | ( bytetemp ? 0 : FLAG_Z ) | + ( bytetemp & FLAG_S ); + if(F & FLAG_H) bytetemp--; + F |= ( bytetemp & FLAG_3 ) | ( (bytetemp&0x02) ? FLAG_5 : 0 ); + } + break; + case 0xaa: /* IND */ + { + uint8 initemp, initemp2; + + contend_read_no_mreq( IR, 1 ); + initemp = Z80_RP_MACRO( BC ); + Z80_WB_MACRO( HL, initemp ); + + B--; HL--; + initemp2 = initemp + C - 1; + F = ( initemp & 0x80 ? FLAG_N : 0 ) | + ( ( initemp2 < initemp ) ? FLAG_H | FLAG_C : 0 ) | + ( parity_table[ ( initemp2 & 0x07 ) ^ B ] ? FLAG_P : 0 ) | + sz53_table[B]; + } + break; + case 0xab: /* OUTD */ + { + uint8 outitemp, outitemp2; + + contend_read_no_mreq( IR, 1 ); + outitemp = Z80_RB_MACRO( HL ); + B--; /* This does happen first, despite what the specs say */ + Z80_WP_MACRO(BC,outitemp); + + HL--; + outitemp2 = outitemp + L; + F = ( outitemp & 0x80 ? FLAG_N : 0 ) | + ( ( outitemp2 < outitemp ) ? FLAG_H | FLAG_C : 0 ) | + ( parity_table[ ( outitemp2 & 0x07 ) ^ B ] ? FLAG_P : 0 ) | + sz53_table[B]; + } + break; + case 0xb0: /* LDIR */ + { + uint8 bytetemp=Z80_RB_MACRO( HL ); + Z80_WB_MACRO(DE,bytetemp); + contend_write_no_mreq( DE, 1 ); contend_write_no_mreq( DE, 1 ); + BC--; + bytetemp += A; + F = ( F & ( FLAG_C | FLAG_Z | FLAG_S ) ) | ( BC ? FLAG_V : 0 ) | + ( bytetemp & FLAG_3 ) | ( (bytetemp & 0x02) ? FLAG_5 : 0 ); + if(BC) { + contend_write_no_mreq( DE, 1 ); contend_write_no_mreq( DE, 1 ); + contend_write_no_mreq( DE, 1 ); contend_write_no_mreq( DE, 1 ); + contend_write_no_mreq( DE, 1 ); + PC-=2; + } + HL++; DE++; + } + break; + case 0xb1: /* CPIR */ + { + uint8 value = Z80_RB_MACRO( HL ), bytetemp = A - value, + lookup = ( ( A & 0x08 ) >> 3 ) | + ( ( (value) & 0x08 ) >> 2 ) | + ( ( bytetemp & 0x08 ) >> 1 ); + contend_read_no_mreq( HL, 1 ); contend_read_no_mreq( HL, 1 ); + contend_read_no_mreq( HL, 1 ); contend_read_no_mreq( HL, 1 ); + contend_read_no_mreq( HL, 1 ); + BC--; + F = ( F & FLAG_C ) | ( BC ? ( FLAG_V | FLAG_N ) : FLAG_N ) | + halfcarry_sub_table[lookup] | ( bytetemp ? 0 : FLAG_Z ) | + ( bytetemp & FLAG_S ); + if(F & FLAG_H) bytetemp--; + F |= ( bytetemp & FLAG_3 ) | ( (bytetemp&0x02) ? FLAG_5 : 0 ); + if( ( F & ( FLAG_V | FLAG_Z ) ) == FLAG_V ) { + contend_read_no_mreq( HL, 1 ); contend_read_no_mreq( HL, 1 ); + contend_read_no_mreq( HL, 1 ); contend_read_no_mreq( HL, 1 ); + contend_read_no_mreq( HL, 1 ); + PC-=2; + } + HL++; + } + break; + case 0xb2: /* INIR */ + { + uint8 initemp, initemp2; + + contend_read_no_mreq( IR, 1 ); + initemp = Z80_RP_MACRO( BC ); + Z80_WB_MACRO( HL, initemp ); + + B--; + initemp2 = initemp + C + 1; + F = ( initemp & 0x80 ? FLAG_N : 0 ) | + ( ( initemp2 < initemp ) ? FLAG_H | FLAG_C : 0 ) | + ( parity_table[ ( initemp2 & 0x07 ) ^ B ] ? FLAG_P : 0 ) | + sz53_table[B]; + + if( B ) { + contend_write_no_mreq( HL, 1 ); contend_write_no_mreq( HL, 1 ); + contend_write_no_mreq( HL, 1 ); contend_write_no_mreq( HL, 1 ); + contend_write_no_mreq( HL, 1 ); + PC -= 2; + } + HL++; + } + break; + case 0xb3: /* OTIR */ + { + uint8 outitemp, outitemp2; + + contend_read_no_mreq( IR, 1 ); + outitemp = Z80_RB_MACRO( HL ); + B--; /* This does happen first, despite what the specs say */ + Z80_WP_MACRO(BC,outitemp); + + HL++; + outitemp2 = outitemp + L; + F = ( outitemp & 0x80 ? FLAG_N : 0 ) | + ( ( outitemp2 < outitemp ) ? FLAG_H | FLAG_C : 0 ) | + ( parity_table[ ( outitemp2 & 0x07 ) ^ B ] ? FLAG_P : 0 ) | + sz53_table[B]; + + if( B ) { + contend_read_no_mreq( BC, 1 ); contend_read_no_mreq( BC, 1 ); + contend_read_no_mreq( BC, 1 ); contend_read_no_mreq( BC, 1 ); + contend_read_no_mreq( BC, 1 ); + PC -= 2; + } + } + break; + case 0xb8: /* LDDR */ + { + uint8 bytetemp=Z80_RB_MACRO( HL ); + Z80_WB_MACRO(DE,bytetemp); + contend_write_no_mreq( DE, 1 ); contend_write_no_mreq( DE, 1 ); + BC--; + bytetemp += A; + F = ( F & ( FLAG_C | FLAG_Z | FLAG_S ) ) | ( BC ? FLAG_V : 0 ) | + ( bytetemp & FLAG_3 ) | ( (bytetemp & 0x02) ? FLAG_5 : 0 ); + if(BC) { + contend_write_no_mreq( DE, 1 ); contend_write_no_mreq( DE, 1 ); + contend_write_no_mreq( DE, 1 ); contend_write_no_mreq( DE, 1 ); + contend_write_no_mreq( DE, 1 ); + PC-=2; + } + HL--; DE--; + } + break; + case 0xb9: /* CPDR */ + { + uint8 value = Z80_RB_MACRO( HL ), bytetemp = A - value, + lookup = ( ( A & 0x08 ) >> 3 ) | + ( ( (value) & 0x08 ) >> 2 ) | + ( ( bytetemp & 0x08 ) >> 1 ); + contend_read_no_mreq( HL, 1 ); contend_read_no_mreq( HL, 1 ); + contend_read_no_mreq( HL, 1 ); contend_read_no_mreq( HL, 1 ); + contend_read_no_mreq( HL, 1 ); + BC--; + F = ( F & FLAG_C ) | ( BC ? ( FLAG_V | FLAG_N ) : FLAG_N ) | + halfcarry_sub_table[lookup] | ( bytetemp ? 0 : FLAG_Z ) | + ( bytetemp & FLAG_S ); + if(F & FLAG_H) bytetemp--; + F |= ( bytetemp & FLAG_3 ) | ( (bytetemp&0x02) ? FLAG_5 : 0 ); + if( ( F & ( FLAG_V | FLAG_Z ) ) == FLAG_V ) { + contend_read_no_mreq( HL, 1 ); contend_read_no_mreq( HL, 1 ); + contend_read_no_mreq( HL, 1 ); contend_read_no_mreq( HL, 1 ); + contend_read_no_mreq( HL, 1 ); + PC-=2; + } + HL--; + } + break; + case 0xba: /* INDR */ + { + uint8 initemp, initemp2; + + contend_read_no_mreq( IR, 1 ); + initemp = Z80_RP_MACRO( BC ); + Z80_WB_MACRO( HL, initemp ); + + B--; + initemp2 = initemp + C - 1; + F = ( initemp & 0x80 ? FLAG_N : 0 ) | + ( ( initemp2 < initemp ) ? FLAG_H | FLAG_C : 0 ) | + ( parity_table[ ( initemp2 & 0x07 ) ^ B ] ? FLAG_P : 0 ) | + sz53_table[B]; + + if( B ) { + contend_write_no_mreq( HL, 1 ); contend_write_no_mreq( HL, 1 ); + contend_write_no_mreq( HL, 1 ); contend_write_no_mreq( HL, 1 ); + contend_write_no_mreq( HL, 1 ); + PC -= 2; + } + HL--; + } + break; + case 0xbb: /* OTDR */ + { + uint8 outitemp, outitemp2; + + contend_read_no_mreq( IR, 1 ); + outitemp = Z80_RB_MACRO( HL ); + B--; /* This does happen first, despite what the specs say */ + Z80_WP_MACRO(BC,outitemp); + + HL--; + outitemp2 = outitemp + L; + F = ( outitemp & 0x80 ? FLAG_N : 0 ) | + ( ( outitemp2 < outitemp ) ? FLAG_H | FLAG_C : 0 ) | + ( parity_table[ ( outitemp2 & 0x07 ) ^ B ] ? FLAG_P : 0 ) | + sz53_table[B]; + + if( B ) { + contend_read_no_mreq( BC, 1 ); contend_read_no_mreq( BC, 1 ); + contend_read_no_mreq( BC, 1 ); contend_read_no_mreq( BC, 1 ); + contend_read_no_mreq( BC, 1 ); + PC -= 2; + } + } + break; + case 0xfb: /* slttrap */ + //slt_trap( HL, A ); + break; + default: /* All other opcodes are NOPD */ + break; diff --git a/waterbox/ngp/z80-fuse/z80_macros.h b/waterbox/ngp/z80-fuse/z80_macros.h new file mode 100644 index 0000000000..e109994fc5 --- /dev/null +++ b/waterbox/ngp/z80-fuse/z80_macros.h @@ -0,0 +1,432 @@ +/* z80_macros.h: Some commonly used z80 things as macros + Copyright (c) 1999-2011 Philip Kendall + + $Id: z80_macros.h 4624 2012-01-09 20:59:35Z pak21 $ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: philip-fuse@shadowmagic.org.uk + +*/ + +#ifndef FUSE_Z80_MACROS_H +#define FUSE_Z80_MACROS_H + +/* Macros used for accessing the registers */ +#define A z80.af.b.h +#define F z80.af.b.l +#define AF z80.af.w + +#define B z80.bc.b.h +#define C z80.bc.b.l +#define BC z80.bc.w + +#define D z80.de.b.h +#define E z80.de.b.l +#define DE z80.de.w + +#define H z80.hl.b.h +#define L z80.hl.b.l +#define HL z80.hl.w + +#define A_ z80.af_.b.h +#define F_ z80.af_.b.l +#define AF_ z80.af_.w + +#define B_ z80.bc_.b.h +#define C_ z80.bc_.b.l +#define BC_ z80.bc_.w + +#define D_ z80.de_.b.h +#define E_ z80.de_.b.l +#define DE_ z80.de_.w + +#define H_ z80.hl_.b.h +#define L_ z80.hl_.b.l +#define HL_ z80.hl_.w + +#define IXH z80.ix.b.h +#define IXL z80.ix.b.l +#define IX z80.ix.w + +#define IYH z80.iy.b.h +#define IYL z80.iy.b.l +#define IY z80.iy.w + +#define SPH z80.sp.b.h +#define SPL z80.sp.b.l +#define SP z80.sp.w + +#define PCH z80.pc.b.h +#define PCL z80.pc.b.l +#define PC z80.pc.w + +#define I z80.i +#define R z80.r +#define R7 z80.r7 + +#define IFF1 z80.iff1 +#define IFF2 z80.iff2 +#define IM z80.im + +#define IR ( ( z80.i ) << 8 | ( z80.r7 & 0x80 ) | ( z80.r & 0x7f ) ) + +/* The flags */ + +#define FLAG_C 0x01 +#define FLAG_N 0x02 +#define FLAG_P 0x04 +#define FLAG_V FLAG_P +#define FLAG_3 0x08 +#define FLAG_H 0x10 +#define FLAG_5 0x20 +#define FLAG_Z 0x40 +#define FLAG_S 0x80 + +/* Get the appropriate contended memory delay. Use a macro for performance + reasons in the main core, but a function for flexibility when building + the core tester */ + +#ifndef CORETEST + +#if 0 +#define contend_read(address,time) \ + if( memory_map_read[ (address) >> MEMORY_PAGE_SIZE_LOGARITHM ].contended ) \ + z80_tstates += ula_contention[ z80_tstates ]; \ + z80_tstates += (time); + +#define contend_read_no_mreq(address,time) \ + if( memory_map_read[ (address) >> MEMORY_PAGE_SIZE_LOGARITHM ].contended ) \ + z80_tstates += ula_contention_no_mreq[ z80_tstates ]; \ + z80_tstates += (time); + +#define contend_write_no_mreq(address,time) \ + if( memory_map_write[ (address) >> MEMORY_PAGE_SIZE_LOGARITHM ].contended ) \ + z80_tstates += ula_contention_no_mreq[ z80_tstates ]; \ + z80_tstates += (time); +#endif + +#define contend_read(address,time) \ + z80_tstates += (time); + +#define contend_read_no_mreq(address,time) \ + z80_tstates += (time); + +#define contend_write_no_mreq(address,time) \ + z80_tstates += (time); + + +#else /* #ifndef CORETEST */ + +void contend_read( uint16 address, uint32 time ); +void contend_read_no_mreq( uint16 address, uint32 time ); +void contend_write_no_mreq( uint16 address, uint32 time ); + +#endif /* #ifndef CORETEST */ + +/* Some commonly used instructions */ +#define AND(value)\ +{\ + A &= (value);\ + F = FLAG_H | sz53p_table[A];\ +} + +#define ADC(value)\ +{\ + uint16 adctemp = A + (value) + ( F & FLAG_C ); \ + uint8 lookup = ( ( A & 0x88 ) >> 3 ) | \ + ( ( (value) & 0x88 ) >> 2 ) | \ + ( ( adctemp & 0x88 ) >> 1 ); \ + A=adctemp;\ + F = ( adctemp & 0x100 ? FLAG_C : 0 ) |\ + halfcarry_add_table[lookup & 0x07] | overflow_add_table[lookup >> 4] |\ + sz53_table[A];\ +} + +#define ADC16(value)\ +{\ + uint32 add16temp= HL + (value) + ( F & FLAG_C ); \ + uint8 lookup = ( ( HL & 0x8800 ) >> 11 ) | \ + ( ( (value) & 0x8800 ) >> 10 ) | \ + ( ( add16temp & 0x8800 ) >> 9 ); \ + HL = add16temp;\ + F = ( add16temp & 0x10000 ? FLAG_C : 0 )|\ + overflow_add_table[lookup >> 4] |\ + ( H & ( FLAG_3 | FLAG_5 | FLAG_S ) ) |\ + halfcarry_add_table[lookup&0x07]|\ + ( HL ? 0 : FLAG_Z );\ +} + +#define ADD(value)\ +{\ + uint16 addtemp = A + (value); \ + uint8 lookup = ( ( A & 0x88 ) >> 3 ) | \ + ( ( (value) & 0x88 ) >> 2 ) | \ + ( ( addtemp & 0x88 ) >> 1 ); \ + A=addtemp;\ + F = ( addtemp & 0x100 ? FLAG_C : 0 ) |\ + halfcarry_add_table[lookup & 0x07] | overflow_add_table[lookup >> 4] |\ + sz53_table[A];\ +} + +#define ADD16(value1,value2)\ +{\ + uint32 add16temp = (value1) + (value2); \ + uint8 lookup = ( ( (value1) & 0x0800 ) >> 11 ) | \ + ( ( (value2) & 0x0800 ) >> 10 ) | \ + ( ( add16temp & 0x0800 ) >> 9 ); \ + (value1) = add16temp;\ + F = ( F & ( FLAG_V | FLAG_Z | FLAG_S ) ) |\ + ( add16temp & 0x10000 ? FLAG_C : 0 )|\ + ( ( add16temp >> 8 ) & ( FLAG_3 | FLAG_5 ) ) |\ + halfcarry_add_table[lookup];\ +} + +/* This may look fairly inefficient, but the (gcc) optimiser does the + right thing assuming it's given a constant for 'bit' */ +#define BIT( bit, value ) \ +{ \ + F = ( F & FLAG_C ) | FLAG_H | ( value & ( FLAG_3 | FLAG_5 ) ); \ + if( ! ( (value) & ( 0x01 << (bit) ) ) ) F |= FLAG_P | FLAG_Z; \ + if( (bit) == 7 && (value) & 0x80 ) F |= FLAG_S; \ +} + +#define BIT_I( bit, value, address ) \ +{ \ + F = ( F & FLAG_C ) | FLAG_H | ( ( address >> 8 ) & ( FLAG_3 | FLAG_5 ) ); \ + if( ! ( (value) & ( 0x01 << (bit) ) ) ) F |= FLAG_P | FLAG_Z; \ + if( (bit) == 7 && (value) & 0x80 ) F |= FLAG_S; \ +} + +#define CALL()\ +{\ + uint8 calltempl, calltemph; \ + calltempl=Z80_RB_MACRO(PC++);\ + calltemph=Z80_RB_MACRO( PC ); \ + contend_read_no_mreq( PC, 1 ); PC++;\ + PUSH16(PCL,PCH);\ + PCL=calltempl; PCH=calltemph;\ +} + +#define CP(value)\ +{\ + uint16 cptemp = A - value; \ + uint8 lookup = ( ( A & 0x88 ) >> 3 ) | \ + ( ( (value) & 0x88 ) >> 2 ) | \ + ( ( cptemp & 0x88 ) >> 1 ); \ + F = ( cptemp & 0x100 ? FLAG_C : ( cptemp ? 0 : FLAG_Z ) ) | FLAG_N |\ + halfcarry_sub_table[lookup & 0x07] |\ + overflow_sub_table[lookup >> 4] |\ + ( value & ( FLAG_3 | FLAG_5 ) ) |\ + ( cptemp & FLAG_S );\ +} + +/* Macro for the {DD,FD} CB dd xx rotate/shift instructions */ +#define DDFDCB_ROTATESHIFT(time, target, instruction)\ +z80_tstates+=(time);\ +{\ + (target) = Z80_RB_MACRO( tempaddr );\ + instruction( (target) );\ + Z80_WB_MACRO( tempaddr, (target) );\ +}\ +break + +#define DEC(value)\ +{\ + F = ( F & FLAG_C ) | ( (value)&0x0f ? 0 : FLAG_H ) | FLAG_N;\ + (value)--;\ + F |= ( (value)==0x7f ? FLAG_V : 0 ) | sz53_table[value];\ +} + +#define Z80_IN( reg, port )\ +{\ + (reg)=Z80_RP_MACRO((port));\ + F = ( F & FLAG_C) | sz53p_table[(reg)];\ +} + +#define INC(value)\ +{\ + (value)++;\ + F = ( F & FLAG_C ) | ( (value)==0x80 ? FLAG_V : 0 ) |\ + ( (value)&0x0f ? 0 : FLAG_H ) | sz53_table[(value)];\ +} + +#define LD16_NNRR(regl,regh)\ +{\ + uint16 ldtemp; \ + ldtemp=Z80_RB_MACRO(PC++);\ + ldtemp|=Z80_RB_MACRO(PC++) << 8;\ + Z80_WB_MACRO(ldtemp++,(regl));\ + Z80_WB_MACRO(ldtemp,(regh));\ + break;\ +} + +#define LD16_RRNN(regl,regh)\ +{\ + uint16 ldtemp; \ + ldtemp=Z80_RB_MACRO(PC++);\ + ldtemp|=Z80_RB_MACRO(PC++) << 8;\ + (regl)=Z80_RB_MACRO(ldtemp++);\ + (regh)=Z80_RB_MACRO(ldtemp);\ + break;\ +} + +#define JP()\ +{\ + uint16 jptemp=PC; \ + PCL=Z80_RB_MACRO(jptemp++);\ + PCH=Z80_RB_MACRO(jptemp);\ +} + +#define JR()\ +{\ + int8 jrtemp = Z80_RB_MACRO( PC ); \ + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); \ + contend_read_no_mreq( PC, 1 ); contend_read_no_mreq( PC, 1 ); \ + contend_read_no_mreq( PC, 1 ); \ + PC += jrtemp; \ +} + +#define OR(value)\ +{\ + A |= (value);\ + F = sz53p_table[A];\ +} + +#define POP16(regl,regh)\ +{\ + (regl)=Z80_RB_MACRO(SP++);\ + (regh)=Z80_RB_MACRO(SP++);\ +} + +#define PUSH16(regl,regh)\ +{\ + Z80_WB_MACRO( --SP, (regh) );\ + Z80_WB_MACRO( --SP, (regl) );\ +} + +#define RET()\ +{\ + POP16(PCL,PCH);\ +} + +#define RL(value)\ +{\ + uint8 rltemp = (value); \ + (value) = ( (value)<<1 ) | ( F & FLAG_C );\ + F = ( rltemp >> 7 ) | sz53p_table[(value)];\ +} + +#define RLC(value)\ +{\ + (value) = ( (value)<<1 ) | ( (value)>>7 );\ + F = ( (value) & FLAG_C ) | sz53p_table[(value)];\ +} + +#define RR(value)\ +{\ + uint8 rrtemp = (value); \ + (value) = ( (value)>>1 ) | ( F << 7 );\ + F = ( rrtemp & FLAG_C ) | sz53p_table[(value)];\ +} + +#define RRC(value)\ +{\ + F = (value) & FLAG_C;\ + (value) = ( (value)>>1 ) | ( (value)<<7 );\ + F |= sz53p_table[(value)];\ +} + +#define RST(value)\ +{\ + PUSH16(PCL,PCH);\ + PC=(value);\ +} + +#define SBC(value)\ +{\ + uint16 sbctemp = A - (value) - ( F & FLAG_C ); \ + uint8 lookup = ( ( A & 0x88 ) >> 3 ) | \ + ( ( (value) & 0x88 ) >> 2 ) | \ + ( ( sbctemp & 0x88 ) >> 1 ); \ + A=sbctemp;\ + F = ( sbctemp & 0x100 ? FLAG_C : 0 ) | FLAG_N |\ + halfcarry_sub_table[lookup & 0x07] | overflow_sub_table[lookup >> 4] |\ + sz53_table[A];\ +} + +#define SBC16(value)\ +{\ + uint32 sub16temp = HL - (value) - (F & FLAG_C); \ + uint8 lookup = ( ( HL & 0x8800 ) >> 11 ) | \ + ( ( (value) & 0x8800 ) >> 10 ) | \ + ( ( sub16temp & 0x8800 ) >> 9 ); \ + HL = sub16temp;\ + F = ( sub16temp & 0x10000 ? FLAG_C : 0 ) |\ + FLAG_N | overflow_sub_table[lookup >> 4] |\ + ( H & ( FLAG_3 | FLAG_5 | FLAG_S ) ) |\ + halfcarry_sub_table[lookup&0x07] |\ + ( HL ? 0 : FLAG_Z) ;\ +} + +#define SLA(value)\ +{\ + F = (value) >> 7;\ + (value) <<= 1;\ + F |= sz53p_table[(value)];\ +} + +#define SLL(value)\ +{\ + F = (value) >> 7;\ + (value) = ( (value) << 1 ) | 0x01;\ + F |= sz53p_table[(value)];\ +} + +#define SRA(value)\ +{\ + F = (value) & FLAG_C;\ + (value) = ( (value) & 0x80 ) | ( (value) >> 1 );\ + F |= sz53p_table[(value)];\ +} + +#define SRL(value)\ +{\ + F = (value) & FLAG_C;\ + (value) >>= 1;\ + F |= sz53p_table[(value)];\ +} + +#define SUB(value)\ +{\ + uint16 subtemp = A - (value); \ + uint8 lookup = ( ( A & 0x88 ) >> 3 ) | \ + ( ( (value) & 0x88 ) >> 2 ) | \ + ( (subtemp & 0x88 ) >> 1 ); \ + A=subtemp;\ + F = ( subtemp & 0x100 ? FLAG_C : 0 ) | FLAG_N |\ + halfcarry_sub_table[lookup & 0x07] | overflow_sub_table[lookup >> 4] |\ + sz53_table[A];\ +} + +#define XOR(value)\ +{\ + A ^= (value);\ + F = sz53p_table[A];\ +} + +#endif /* #ifndef FUSE_Z80_MACROS_H */ diff --git a/waterbox/ngp/z80-fuse/z80_ops.cpp b/waterbox/ngp/z80-fuse/z80_ops.cpp new file mode 100644 index 0000000000..bbe985c567 --- /dev/null +++ b/waterbox/ngp/z80-fuse/z80_ops.cpp @@ -0,0 +1,74 @@ +/* z80_ops.c: Process the next opcode + Copyright (c) 1999-2005 Philip Kendall, Witold Filipczyk + + $Id: z80_ops.c 4624 2012-01-09 20:59:35Z pak21 $ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: philip-fuse@shadowmagic.org.uk + +*/ + +#include "z80.h" + +#include "z80_macros.h" + +static int iline = 0; + +void z80_set_interrupt(int set) +{ + iline = set; +} + +int z80_do_opcode( void ) +{ + if(iline) + { + if(z80_interrupt()) + { + int ret = z80_tstates - last_z80_tstates; + last_z80_tstates = z80_tstates; + return(ret); + } + } + + uint8 opcode; + + /* Check to see if M1 cycles happen on even z80_tstates */ + //if( z80_tstates & 1 ) + // z80_tstates++; + //uint16 lastpc = PC; + + opcode = Z80_RB_MACRO( PC ); + //printf("Z80-op: %04x, %02x\n", PC, opcode); + z80_tstates++; + + PC++; + R++; + + switch(opcode) + { + #include "opcodes_base.c" + } + + int ret = z80_tstates - last_z80_tstates; + last_z80_tstates = z80_tstates; + + //printf("PC: %04x, %02x, time=%d\n", lastpc, opcode, ret); + + return(ret); +} diff --git a/waterbox/o2em/.vscode/settings.json b/waterbox/o2em/.vscode/settings.json new file mode 100644 index 0000000000..a5401e1c1f --- /dev/null +++ b/waterbox/o2em/.vscode/settings.json @@ -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 +} \ No newline at end of file diff --git a/waterbox/o2em/CHANGELOG b/waterbox/o2em/CHANGELOG new file mode 100644 index 0000000000..71dbb60f39 --- /dev/null +++ b/waterbox/o2em/CHANGELOG @@ -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 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 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. + + + diff --git a/waterbox/o2em/COPYING b/waterbox/o2em/COPYING new file mode 100644 index 0000000000..255c6f4511 --- /dev/null +++ b/waterbox/o2em/COPYING @@ -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 + diff --git a/waterbox/o2em/Makefile b/waterbox/o2em/Makefile new file mode 100644 index 0000000000..e7c1641880 --- /dev/null +++ b/waterbox/o2em/Makefile @@ -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)) diff --git a/waterbox/o2em/README b/waterbox/o2em/README new file mode 100644 index 0000000000..8811fe86c5 --- /dev/null +++ b/waterbox/o2em/README @@ -0,0 +1,341 @@ + + + O2EM v1.18 (Jan/2007) + + an Odyssey 2 & Videopac+ emulator + + copyright 1996/1998 by Daniel Boris + + 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 [options] + + = 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 + +---------------------------------------------------------------------------- + + diff --git a/waterbox/o2em/audio.c b/waterbox/o2em/audio.c new file mode 100644 index 0000000000..345eb55002 --- /dev/null +++ b/waterbox/o2em/audio.c @@ -0,0 +1,95 @@ + +/* + * O2EM Free Odyssey2 / Videopac+ Emulator + * + * Created by Daniel Boris (c) 1997,1998 + * + * Developed by Andre de la Rocha + * Arlindo M. de Oliveira + * + * http://o2em.sourceforge.net + * + * + * + * O2 audio emulation + */ + +#include +#include +#include +#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; +} diff --git a/waterbox/o2em/audio.h b/waterbox/o2em/audio.h new file mode 100644 index 0000000000..6d4a805cc4 --- /dev/null +++ b/waterbox/o2em/audio.h @@ -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 + + diff --git a/waterbox/o2em/bitmap.c b/waterbox/o2em/bitmap.c new file mode 100644 index 0000000000..715fe79c5f --- /dev/null +++ b/waterbox/o2em/bitmap.c @@ -0,0 +1,22 @@ +#include "bitmap.h" +#include +#include + +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; +} diff --git a/waterbox/o2em/bitmap.h b/waterbox/o2em/bitmap.h new file mode 100644 index 0000000000..dec2e6e437 --- /dev/null +++ b/waterbox/o2em/bitmap.h @@ -0,0 +1,13 @@ +#pragma once +#include + +typedef struct +{ + uint8_t** line; + uint8_t* dat; + int w; + int h; +} Bitmap; + +void clear(Bitmap* b); +Bitmap* NewBitmap(int w, int h); diff --git a/waterbox/o2em/config.h b/waterbox/o2em/config.h new file mode 100644 index 0000000000..715a373990 --- /dev/null +++ b/waterbox/o2em/config.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 + diff --git a/waterbox/o2em/cpu.c b/waterbox/o2em/cpu.c new file mode 100644 index 0000000000..addf20d4cf --- /dev/null +++ b/waterbox/o2em/cpu.c @@ -0,0 +1,1670 @@ + +/* + * O2EM Free Odyssey2 / Videopac+ Emulator + * + * Created by Daniel Boris (c) 1997,1998 + * + ** Developed by Andre de la Rocha + * Arlindo M. de Oliveira + * + * http://o2em.sourceforge.net + * + * + * + * 8048 microcontroller emulation + */ + +#include +#include "types.h" +#include "vmachine.h" +#include "keyboard.h" +#include "voice.h" +#include "vdc.h" +#include "vpp.h" +#include "cpu.h" + +static int64_t clk; + +#define push(d) \ + { \ + intRAM[sp++] = (d); \ + if (sp > 23) \ + sp = 8; \ + } +#define pull() (sp--, (sp < 8) ? (sp = 23) : 0, intRAM[sp]) +#define make_psw() \ + { \ + psw = (cy << 7) | ac | f0 | bs | 0x08; \ + psw = psw | ((sp - 8) >> 1); \ + } +#define illegal(o) \ + { \ + } +#define undef(i) \ + { \ + printf("** unimplemented instruction %x, %x**\n", i, pc); \ + } +#define ROM(adr) (rom[(adr)&0xfff]) + +void init_cpu(void) +{ + pc = 0; + sp = 8; + bs = 0; + p1 = p2 = 0xFF; + ac = cy = f0 = 0; + A11 = A11ff = 0; + timer_on = 0; + count_on = 0; + reg_pnt = 0; + tirq_en = xirq_en = irq_ex = xirq_pend = tirq_pend = 0; +} + +void ext_IRQ(void) +{ + int_clk = 5; /* length of pulse on /INT */ + if (xirq_en && !irq_ex) + { + irq_ex = 1; + xirq_pend = 0; + clk += 2; + make_psw(); + push(pc & 0xFF); + push(((pc & 0xF00) >> 8) | (psw & 0xF0)); + pc = 0x03; + A11ff = A11; + A11 = 0; + } + if (pendirq && (!xirq_en)) + xirq_pend = 1; +} + +void tim_IRQ(void) +{ + if (tirq_en && !irq_ex) + { + irq_ex = 2; + tirq_pend = 0; + clk += 2; + make_psw(); + push(pc & 0xFF); + push(((pc & 0xF00) >> 8) | (psw & 0xF0)); + pc = 0x07; + A11ff = A11; + A11 = 0; + } + if (pendirq && (!tirq_en)) + tirq_pend = 1; +} + +void make_psw_debug(void) +{ + make_psw(); +} + +int64_t cpu_exec(int64_t ncycles) +{ + int64_t startclk = clk; + int64_t targetclk = clk + ncycles; + + Byte op; + ADDRESS adr; + Byte dat; + int temp; + + while (clk < targetclk) + { + lastpc = pc; + op = ROM(pc++); + switch (op) + { + case 0x00: /* NOP */ + clk++; + break; + case 0x01: /* ILL */ + illegal(op); + clk++; + break; + case 0x02: /* OUTL BUS,A */ + clk += 2; + undef(0x02); + break; + case 0x03: /* ADD A,#data */ + clk += 2; + cy = ac = 0; + dat = ROM(pc++); + if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) + ac = 0x40; + temp = acc + dat; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x04: /* JMP */ + pc = ROM(pc) | A11; + clk += 2; + break; + case 0x05: /* EN I */ + xirq_en = 1; + clk++; + break; + case 0x06: /* ILL */ + clk++; + illegal(op); + break; + case 0x07: /* DEC A */ + acc--; + clk++; + break; + case 0x08: /* INS A,BUS*/ + clk += 2; + acc = in_bus(); + break; + case 0x09: /* IN A,Pp */ + acc = p1; + clk += 2; + break; + case 0x0A: /* IN A,Pp */ + acc = read_P2(); + clk += 2; + break; + case 0x0B: /* ILL */ + clk++; + illegal(op); + break; + case 0x0C: /* MOVD A,P4 */ + clk += 2; + acc = read_PB(0); + break; + case 0x0D: /* MOVD A,P5 */ + clk += 2; + acc = read_PB(1); + break; + case 0x0E: /* MOVD A,P6 */ + clk += 2; + acc = read_PB(2); + break; + case 0x0F: /* MOVD A,P7 */ + clk += 2; + acc = read_PB(3); + break; + case 0x10: /* INC @Ri */ + intRAM[intRAM[reg_pnt] & 0x3F]++; + clk++; + break; + case 0x11: /* INC @Ri */ + intRAM[intRAM[reg_pnt + 1] & 0x3F]++; + clk++; + break; + case 0x12: /* JBb address */ + clk += 2; + dat = ROM(pc); + if (acc & 0x01) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0x13: /* ADDC A,#data */ + clk += 2; + dat = ROM(pc++); + ac = 0; + if (((acc & 0x0f) + (dat & 0x0f) + cy) > 0x0f) + ac = 0x40; + temp = acc + dat + cy; + cy = 0; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + + case 0x14: /* CALL */ + make_psw(); + adr = ROM(pc) | A11; + pc++; + clk += 2; + push(pc & 0xFF); + push(((pc & 0xF00) >> 8) | (psw & 0xF0)); + pc = adr; + break; + case 0x15: /* DIS I */ + xirq_en = 0; + clk++; + break; + case 0x16: /* JTF */ + clk += 2; + dat = ROM(pc); + if (t_flag) + pc = (pc & 0xF00) | dat; + else + pc++; + t_flag = 0; + break; + case 0x17: /* INC A */ + acc++; + clk++; + break; + case 0x18: /* INC Rr */ + intRAM[reg_pnt]++; + clk++; + break; + case 0x19: /* INC Rr */ + intRAM[reg_pnt + 1]++; + clk++; + break; + case 0x1A: /* INC Rr */ + intRAM[reg_pnt + 2]++; + clk++; + break; + case 0x1B: /* INC Rr */ + intRAM[reg_pnt + 3]++; + clk++; + break; + case 0x1C: /* INC Rr */ + intRAM[reg_pnt + 4]++; + clk++; + break; + case 0x1D: /* INC Rr */ + intRAM[reg_pnt + 5]++; + clk++; + break; + case 0x1E: /* INC Rr */ + intRAM[reg_pnt + 6]++; + clk++; + break; + case 0x1F: /* INC Rr */ + intRAM[reg_pnt + 7]++; + clk++; + break; + case 0x20: /* XCH A,@Ri */ + clk++; + dat = acc; + acc = intRAM[intRAM[reg_pnt] & 0x3F]; + intRAM[intRAM[reg_pnt] & 0x3F] = dat; + break; + case 0x21: /* XCH A,@Ri */ + clk++; + dat = acc; + acc = intRAM[intRAM[reg_pnt + 1] & 0x3F]; + intRAM[intRAM[reg_pnt + 1] & 0x3F] = dat; + break; + case 0x22: /* ILL */ + clk++; + illegal(op); + break; + case 0x23: /* MOV a,#data */ + clk += 2; + acc = ROM(pc++); + break; + + case 0x24: /* JMP */ + pc = ROM(pc) | 0x100 | A11; + clk += 2; + break; + case 0x25: /* EN TCNTI */ + tirq_en = 1; + clk++; + break; + case 0x26: /* JNT0 */ + clk += 2; + dat = ROM(pc); + if (!get_voice_status()) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0x27: /* CLR A */ + clk++; + acc = 0; + break; + case 0x28: /* XCH A,Rr */ + dat = acc; + acc = intRAM[reg_pnt]; + intRAM[reg_pnt] = dat; + clk++; + break; + case 0x29: /* XCH A,Rr */ + dat = acc; + acc = intRAM[reg_pnt + 1]; + intRAM[reg_pnt + 1] = dat; + clk++; + break; + case 0x2A: /* XCH A,Rr */ + dat = acc; + acc = intRAM[reg_pnt + 2]; + intRAM[reg_pnt + 2] = dat; + clk++; + break; + case 0x2B: /* XCH A,Rr */ + dat = acc; + acc = intRAM[reg_pnt + 3]; + intRAM[reg_pnt + 3] = dat; + clk++; + break; + case 0x2C: /* XCH A,Rr */ + dat = acc; + acc = intRAM[reg_pnt + 4]; + intRAM[reg_pnt + 4] = dat; + clk++; + break; + case 0x2D: /* XCH A,Rr */ + dat = acc; + acc = intRAM[reg_pnt + 5]; + intRAM[reg_pnt + 5] = dat; + clk++; + break; + case 0x2E: /* XCH A,Rr */ + dat = acc; + acc = intRAM[reg_pnt + 6]; + intRAM[reg_pnt + 6] = dat; + clk++; + break; + case 0x2F: /* XCH A,Rr */ + dat = acc; + acc = intRAM[reg_pnt + 7]; + intRAM[reg_pnt + 7] = dat; + clk++; + break; + case 0x30: /* XCHD A,@Ri */ + clk++; + adr = intRAM[reg_pnt] & 0x3F; + dat = acc & 0x0F; + acc = acc & 0xF0; + acc = acc | (intRAM[adr] & 0x0F); + intRAM[adr] &= 0xF0; + intRAM[adr] |= dat; + break; + case 0x31: /* XCHD A,@Ri */ + clk++; + adr = intRAM[reg_pnt + 1] & 0x3F; + dat = acc & 0x0F; + acc = acc & 0xF0; + acc = acc | (intRAM[adr] & 0x0F); + intRAM[adr] &= 0xF0; + intRAM[adr] |= dat; + break; + case 0x32: /* JBb address */ + clk += 2; + dat = ROM(pc); + if (acc & 0x02) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0x33: /* ILL */ + clk++; + illegal(op); + break; + case 0x34: /* CALL */ + make_psw(); + adr = ROM(pc) | 0x100 | A11; + pc++; + clk += 2; + push(pc & 0xFF); + push(((pc & 0xF00) >> 8) | (psw & 0xF0)); + pc = adr; + break; + case 0x35: /* DIS TCNTI */ + tirq_en = 0; + tirq_pend = 0; + clk++; + break; + case 0x36: /* JT0 */ + clk += 2; + dat = ROM(pc); + if (get_voice_status()) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0x37: /* CPL A */ + acc = acc ^ 0xFF; + clk++; + break; + case 0x38: /* ILL */ + clk++; + illegal(op); + break; + case 0x39: /* OUTL P1,A */ + clk += 2; + write_p1(acc); + break; + case 0x3A: /* OUTL P2,A */ + clk += 2; + p2 = acc; + break; + case 0x3B: /* ILL */ + clk++; + illegal(op); + break; + case 0x3C: /* MOVD P4,A */ + clk += 2; + write_PB(0, acc); + break; + case 0x3D: /* MOVD P5,A */ + clk += 2; + write_PB(1, acc); + break; + case 0x3E: /* MOVD P6,A */ + clk += 2; + write_PB(2, acc); + break; + case 0x3F: /* MOVD P7,A */ + clk += 2; + write_PB(3, acc); + break; + case 0x40: /* ORL A,@Ri */ + clk++; + acc = acc | intRAM[intRAM[reg_pnt] & 0x3F]; + break; + case 0x41: /* ORL A,@Ri */ + clk++; + acc = acc | intRAM[intRAM[reg_pnt + 1] & 0x3F]; + break; + case 0x42: /* MOV A,T */ + clk++; + acc = itimer; + break; + case 0x43: /* ORL A,#data */ + clk += 2; + acc = acc | ROM(pc++); + break; + case 0x44: /* JMP */ + pc = ROM(pc) | 0x200 | A11; + clk += 2; + break; + case 0x45: /* STRT CNT */ + /* printf("START: %d=%d\n",master_clk/22,itimer); */ + count_on = 1; + clk++; + break; + case 0x46: /* JNT1 */ + clk += 2; + dat = ROM(pc); + if (!read_t1()) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0x47: /* SWAP A */ + clk++; + dat = (acc & 0xF0) >> 4; + acc = acc << 4; + acc = acc | dat; + break; + case 0x48: /* ORL A,Rr */ + clk++; + acc = acc | intRAM[reg_pnt]; + break; + case 0x49: /* ORL A,Rr */ + clk++; + acc = acc | intRAM[reg_pnt + 1]; + break; + case 0x4A: /* ORL A,Rr */ + clk++; + acc = acc | intRAM[reg_pnt + 2]; + break; + case 0x4B: /* ORL A,Rr */ + clk++; + acc = acc | intRAM[reg_pnt + 3]; + break; + case 0x4C: /* ORL A,Rr */ + clk++; + acc = acc | intRAM[reg_pnt + 4]; + break; + case 0x4D: /* ORL A,Rr */ + clk++; + acc = acc | intRAM[reg_pnt + 5]; + break; + case 0x4E: /* ORL A,Rr */ + clk++; + acc = acc | intRAM[reg_pnt + 6]; + break; + case 0x4F: /* ORL A,Rr */ + clk++; + acc = acc | intRAM[reg_pnt + 7]; + break; + + case 0x50: /* ANL A,@Ri */ + acc = acc & intRAM[intRAM[reg_pnt] & 0x3F]; + clk++; + break; + case 0x51: /* ANL A,@Ri */ + acc = acc & intRAM[intRAM[reg_pnt + 1] & 0x3F]; + clk++; + break; + case 0x52: /* JBb address */ + clk += 2; + dat = ROM(pc); + if (acc & 0x04) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0x53: /* ANL A,#data */ + clk += 2; + acc = acc & ROM(pc++); + break; + case 0x54: /* CALL */ + make_psw(); + adr = ROM(pc) | 0x200 | A11; + pc++; + clk += 2; + push(pc & 0xFF); + push(((pc & 0xF00) >> 8) | (psw & 0xF0)); + pc = adr; + break; + case 0x55: /* STRT T */ + timer_on = 1; + clk++; + break; + case 0x56: /* JT1 */ + clk += 2; + dat = ROM(pc); + if (read_t1()) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0x57: /* DA A */ + clk++; + if (((acc & 0x0F) > 0x09) || ac) + { + if (acc > 0xf9) + cy = 1; + acc += 6; + } + dat = (acc & 0xF0) >> 4; + if ((dat > 9) || cy) + { + dat += 6; + cy = 1; + } + acc = (acc & 0x0F) | (dat << 4); + break; + case 0x58: /* ANL A,Rr */ + clk++; + acc = acc & intRAM[reg_pnt]; + break; + case 0x59: /* ANL A,Rr */ + clk++; + acc = acc & intRAM[reg_pnt + 1]; + break; + case 0x5A: /* ANL A,Rr */ + clk++; + acc = acc & intRAM[reg_pnt + 2]; + break; + case 0x5B: /* ANL A,Rr */ + clk++; + acc = acc & intRAM[reg_pnt + 3]; + break; + case 0x5C: /* ANL A,Rr */ + clk++; + acc = acc & intRAM[reg_pnt + 4]; + break; + case 0x5D: /* ANL A,Rr */ + clk++; + acc = acc & intRAM[reg_pnt + 5]; + break; + case 0x5E: /* ANL A,Rr */ + clk++; + acc = acc & intRAM[reg_pnt + 6]; + break; + case 0x5F: /* ANL A,Rr */ + clk++; + acc = acc & intRAM[reg_pnt + 7]; + break; + + case 0x60: /* ADD A,@Ri */ + clk++; + cy = ac = 0; + dat = intRAM[intRAM[reg_pnt] & 0x3F]; + if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) + ac = 0x40; + temp = acc + dat; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x61: /* ADD A,@Ri */ + clk++; + cy = ac = 0; + dat = intRAM[intRAM[reg_pnt + 1] & 0x3F]; + if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) + ac = 0x40; + temp = acc + dat; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x62: /* MOV T,A */ + clk++; + itimer = acc; + break; + case 0x63: /* ILL */ + clk++; + illegal(op); + break; + case 0x64: /* JMP */ + pc = ROM(pc) | 0x300 | A11; + clk += 2; + break; + case 0x65: /* STOP TCNT */ + clk++; + /* printf("STOP %d\n",master_clk/22); */ + count_on = timer_on = 0; + break; + case 0x66: /* ILL */ + clk++; + illegal(op); + break; + case 0x67: /* RRC A */ + dat = cy; + cy = acc & 0x01; + acc = acc >> 1; + if (dat) + acc = acc | 0x80; + else + acc = acc & 0x7F; + clk++; + break; + case 0x68: /* ADD A,Rr */ + clk++; + cy = ac = 0; + dat = intRAM[reg_pnt]; + if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) + ac = 0x40; + temp = acc + dat; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x69: /* ADD A,Rr */ + clk++; + cy = ac = 0; + dat = intRAM[reg_pnt + 1]; + if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) + ac = 0x40; + temp = acc + dat; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x6A: /* ADD A,Rr */ + clk++; + cy = ac = 0; + dat = intRAM[reg_pnt + 2]; + if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) + ac = 0x40; + temp = acc + dat; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x6B: /* ADD A,Rr */ + clk++; + cy = ac = 0; + dat = intRAM[reg_pnt + 3]; + if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) + ac = 0x40; + temp = acc + dat; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x6C: /* ADD A,Rr */ + clk++; + cy = ac = 0; + dat = intRAM[reg_pnt + 4]; + if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) + ac = 0x40; + temp = acc + dat; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x6D: /* ADD A,Rr */ + clk++; + cy = ac = 0; + dat = intRAM[reg_pnt + 5]; + if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) + ac = 0x40; + temp = acc + dat; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x6E: /* ADD A,Rr */ + clk++; + cy = ac = 0; + dat = intRAM[reg_pnt + 6]; + if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) + ac = 0x40; + temp = acc + dat; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x6F: /* ADD A,Rr */ + clk++; + cy = ac = 0; + dat = intRAM[reg_pnt + 7]; + if (((acc & 0x0f) + (dat & 0x0f)) > 0x0f) + ac = 0x40; + temp = acc + dat; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x70: /* ADDC A,@Ri */ + clk++; + ac = 0; + dat = intRAM[intRAM[reg_pnt] & 0x3F]; + if (((acc & 0x0f) + (dat & 0x0f) + cy) > 0x0f) + ac = 0x40; + temp = acc + dat + cy; + cy = 0; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x71: /* ADDC A,@Ri */ + clk++; + ac = 0; + dat = intRAM[intRAM[reg_pnt + 1] & 0x3F]; + if (((acc & 0x0f) + (dat & 0x0f) + cy) > 0x0f) + ac = 0x40; + temp = acc + dat + cy; + cy = 0; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + + case 0x72: /* JBb address */ + clk += 2; + dat = ROM(pc); + if (acc & 0x08) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0x73: /* ILL */ + clk++; + illegal(op); + break; + case 0x74: /* CALL */ + make_psw(); + adr = ROM(pc) | 0x300 | A11; + pc++; + clk += 2; + push(pc & 0xFF); + push(((pc & 0xF00) >> 8) | (psw & 0xF0)); + pc = adr; + break; + case 0x75: /* EN CLK */ + clk++; + undef(op); + break; + case 0x76: /* JF1 address */ + clk += 2; + dat = ROM(pc); + if (f1) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0x77: /* RR A */ + clk++; + dat = acc & 0x01; + acc = acc >> 1; + if (dat) + acc = acc | 0x80; + else + acc = acc & 0x7f; + break; + + case 0x78: /* ADDC A,Rr */ + clk++; + ac = 0; + dat = intRAM[reg_pnt]; + if (((acc & 0x0f) + (dat & 0x0f) + cy) > 0x0f) + ac = 0x40; + temp = acc + dat + cy; + cy = 0; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x79: /* ADDC A,Rr */ + clk++; + ac = 0; + dat = intRAM[reg_pnt + 1]; + if (((acc & 0x0f) + (dat & 0x0f) + cy) > 0x0f) + ac = 0x40; + temp = acc + dat + cy; + cy = 0; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x7A: /* ADDC A,Rr */ + clk++; + ac = 0; + dat = intRAM[reg_pnt + 2]; + if (((acc & 0x0f) + (dat & 0x0f) + cy) > 0x0f) + ac = 0x40; + temp = acc + dat + cy; + cy = 0; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x7B: /* ADDC A,Rr */ + clk++; + ac = 0; + dat = intRAM[reg_pnt + 3]; + if (((acc & 0x0f) + (dat & 0x0f) + cy) > 0x0f) + ac = 0x40; + temp = acc + dat + cy; + cy = 0; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x7C: /* ADDC A,Rr */ + clk++; + ac = 0; + dat = intRAM[reg_pnt + 4]; + if (((acc & 0x0f) + (dat & 0x0f) + cy) > 0x0f) + ac = 0x40; + temp = acc + dat + cy; + cy = 0; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x7D: /* ADDC A,Rr */ + clk++; + ac = 0; + dat = intRAM[reg_pnt + 5]; + if (((acc & 0x0f) + (dat & 0x0f) + cy) > 0x0f) + ac = 0x40; + temp = acc + dat + cy; + cy = 0; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x7E: /* ADDC A,Rr */ + clk++; + ac = 0; + dat = intRAM[reg_pnt + 6]; + if (((acc & 0x0f) + (dat & 0x0f) + cy) > 0x0f) + ac = 0x40; + temp = acc + dat + cy; + cy = 0; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + case 0x7F: /* ADDC A,Rr */ + clk++; + ac = 0; + dat = intRAM[reg_pnt + 7]; + if (((acc & 0x0f) + (dat & 0x0f) + cy) > 0x0f) + ac = 0x40; + temp = acc + dat + cy; + cy = 0; + if (temp > 0xFF) + cy = 1; + acc = (temp & 0xFF); + break; + + case 0x80: /* MOVX A,@Ri */ + acc = ext_read(intRAM[reg_pnt]); + clk += 2; + break; + case 0x81: /* MOVX A,@Ri */ + acc = ext_read(intRAM[reg_pnt + 1]); + clk += 2; + break; + case 0x82: /* ILL */ + clk++; + illegal(op); + break; + case 0x83: /* RET */ + clk += 2; + pc = ((pull() & 0x0F) << 8); + pc = pc | pull(); + break; + case 0x84: /* JMP */ + pc = ROM(pc) | 0x400 | A11; + clk += 2; + break; + case 0x85: /* CLR F0 */ + clk++; + f0 = 0; + break; + case 0x86: /* JNI address */ + clk += 2; + dat = ROM(pc); + if (int_clk > 0) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0x87: /* ILL */ + illegal(op); + clk++; + break; + case 0x88: /* BUS,#data */ + clk += 2; + undef(op); + break; + case 0x89: /* ORL Pp,#data */ + write_p1(p1 | ROM(pc++)); + clk += 2; + break; + case 0x8A: /* ORL Pp,#data */ + p2 = p2 | ROM(pc++); + clk += 2; + break; + case 0x8B: /* ILL */ + illegal(op); + clk++; + break; + case 0x8C: /* ORLD P4,A */ + write_PB(0, read_PB(0) | acc); + clk += 2; + break; + case 0x8D: /* ORLD P5,A */ + write_PB(1, read_PB(1) | acc); + clk += 2; + break; + case 0x8E: /* ORLD P6,A */ + write_PB(2, read_PB(2) | acc); + clk += 2; + break; + case 0x8F: /* ORLD P7,A */ + write_PB(3, read_PB(3) | acc); + clk += 2; + break; + case 0x90: /* MOVX @Ri,A */ + ext_write(acc, intRAM[reg_pnt]); + clk += 2; + break; + case 0x91: /* MOVX @Ri,A */ + ext_write(acc, intRAM[reg_pnt + 1]); + clk += 2; + break; + case 0x92: /* JBb address */ + clk += 2; + dat = ROM(pc); + if (acc & 0x10) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0x93: /* RETR*/ + /* printf("RETR %d\n",master_clk/22); */ + clk += 2; + dat = pull(); + pc = (dat & 0x0F) << 8; + cy = (dat & 0x80) >> 7; + ac = dat & 0x40; + f0 = dat & 0x20; + bs = dat & 0x10; + if (bs) + reg_pnt = 24; + else + reg_pnt = 0; + pc = pc | pull(); + irq_ex = 0; + A11 = A11ff; + break; + case 0x94: /* CALL */ + make_psw(); + adr = ROM(pc) | 0x400 | A11; + pc++; + clk += 2; + push(pc & 0xFF); + push(((pc & 0xF00) >> 8) | (psw & 0xF0)); + pc = adr; + break; + case 0x95: /* CPL F0 */ + f0 = f0 ^ 0x20; + clk++; + break; + case 0x96: /* JNZ address */ + clk += 2; + dat = ROM(pc); + if (acc != 0) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0x97: /* CLR C */ + cy = 0; + clk++; + break; + case 0x98: /* ANL BUS,#data */ + clk += 2; + undef(op); + break; + case 0x99: /* ANL Pp,#data */ + write_p1(p1 & ROM(pc++)); + clk += 2; + break; + case 0x9A: /* ANL Pp,#data */ + p2 = p2 & ROM(pc++); + clk += 2; + break; + case 0x9B: /* ILL */ + illegal(op); + clk++; + break; + case 0x9C: /* ANLD P4,A */ + write_PB(0, read_PB(0) & acc); + clk += 2; + break; + case 0x9D: /* ANLD P5,A */ + write_PB(1, read_PB(1) & acc); + clk += 2; + break; + case 0x9E: /* ANLD P6,A */ + write_PB(2, read_PB(2) & acc); + clk += 2; + break; + case 0x9F: /* ANLD P7,A */ + write_PB(3, read_PB(3) & acc); + clk += 2; + break; + case 0xA0: /* MOV @Ri,A */ + intRAM[intRAM[reg_pnt] & 0x3F] = acc; + clk++; + break; + case 0xA1: /* MOV @Ri,A */ + intRAM[intRAM[reg_pnt + 1] & 0x3F] = acc; + clk++; + break; + case 0xA2: /* ILL */ + clk++; + illegal(op); + break; + case 0xA3: /* MOVP A,@A */ + acc = ROM((pc & 0xF00) | acc); + clk += 2; + break; + case 0xA4: /* JMP */ + pc = ROM(pc) | 0x500 | A11; + clk += 2; + break; + case 0xA5: /* CLR F1 */ + clk++; + f1 = 0; + break; + case 0xA6: /* ILL */ + illegal(op); + clk++; + break; + case 0xA7: /* CPL C */ + cy = cy ^ 0x01; + clk++; + break; + case 0xA8: /* MOV Rr,A */ + intRAM[reg_pnt] = acc; + clk++; + break; + case 0xA9: /* MOV Rr,A */ + intRAM[reg_pnt + 1] = acc; + clk++; + break; + case 0xAA: /* MOV Rr,A */ + intRAM[reg_pnt + 2] = acc; + clk++; + break; + case 0xAB: /* MOV Rr,A */ + intRAM[reg_pnt + 3] = acc; + clk++; + break; + case 0xAC: /* MOV Rr,A */ + intRAM[reg_pnt + 4] = acc; + clk++; + break; + case 0xAD: /* MOV Rr,A */ + intRAM[reg_pnt + 5] = acc; + clk++; + break; + case 0xAE: /* MOV Rr,A */ + intRAM[reg_pnt + 6] = acc; + clk++; + break; + case 0xAF: /* MOV Rr,A */ + intRAM[reg_pnt + 7] = acc; + clk++; + break; + case 0xB0: /* MOV @Ri,#data */ + intRAM[intRAM[reg_pnt] & 0x3F] = ROM(pc++); + clk += 2; + break; + case 0xB1: /* MOV @Ri,#data */ + intRAM[intRAM[reg_pnt + 1] & 0x3F] = ROM(pc++); + clk += 2; + break; + case 0xB2: /* JBb address */ + clk += 2; + dat = ROM(pc); + if (acc & 0x20) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0xB3: /* JMPP @A */ + adr = (pc & 0xF00) | acc; + pc = (pc & 0xF00) | ROM(adr); + clk += 2; + break; + case 0xB4: /* CALL */ + make_psw(); + adr = ROM(pc) | 0x500 | A11; + pc++; + clk += 2; + push(pc & 0xFF); + push(((pc & 0xF00) >> 8) | (psw & 0xF0)); + pc = adr; + break; + case 0xB5: /* CPL F1 */ + f1 = f1 ^ 0x01; + clk++; + break; + case 0xB6: /* JF0 address */ + clk += 2; + dat = ROM(pc); + if (f0) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0xB7: /* ILL */ + clk++; + illegal(op); + break; + case 0xB8: /* MOV Rr,#data */ + intRAM[reg_pnt] = ROM(pc++); + clk += 2; + break; + case 0xB9: /* MOV Rr,#data */ + intRAM[reg_pnt + 1] = ROM(pc++); + clk += 2; + break; + case 0xBA: /* MOV Rr,#data */ + intRAM[reg_pnt + 2] = ROM(pc++); + clk += 2; + break; + case 0xBB: /* MOV Rr,#data */ + intRAM[reg_pnt + 3] = ROM(pc++); + clk += 2; + break; + case 0xBC: /* MOV Rr,#data */ + intRAM[reg_pnt + 4] = ROM(pc++); + clk += 2; + break; + case 0xBD: /* MOV Rr,#data */ + intRAM[reg_pnt + 5] = ROM(pc++); + clk += 2; + break; + case 0xBE: /* MOV Rr,#data */ + intRAM[reg_pnt + 6] = ROM(pc++); + clk += 2; + break; + case 0xBF: /* MOV Rr,#data */ + intRAM[reg_pnt + 7] = ROM(pc++); + clk += 2; + break; + case 0xC0: /* ILL */ + illegal(op); + clk++; + break; + case 0xC1: /* ILL */ + illegal(op); + clk++; + break; + case 0xC2: /* ILL */ + illegal(op); + clk++; + break; + case 0xC3: /* ILL */ + illegal(op); + clk++; + break; + case 0xC4: /* JMP */ + pc = ROM(pc) | 0x600 | A11; + clk += 2; + break; + case 0xC5: /* SEL RB0 */ + bs = reg_pnt = 0; + clk++; + break; + case 0xC6: /* JZ address */ + clk += 2; + dat = ROM(pc); + if (acc == 0) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0xC7: /* MOV A,PSW */ + clk++; + make_psw(); + acc = psw; + break; + case 0xC8: /* DEC Rr */ + intRAM[reg_pnt]--; + clk++; + break; + case 0xC9: /* DEC Rr */ + intRAM[reg_pnt + 1]--; + clk++; + break; + case 0xCA: /* DEC Rr */ + intRAM[reg_pnt + 2]--; + clk++; + break; + case 0xCB: /* DEC Rr */ + intRAM[reg_pnt + 3]--; + clk++; + break; + case 0xCC: /* DEC Rr */ + intRAM[reg_pnt + 4]--; + clk++; + break; + case 0xCD: /* DEC Rr */ + intRAM[reg_pnt + 5]--; + clk++; + break; + case 0xCE: /* DEC Rr */ + intRAM[reg_pnt + 6]--; + clk++; + break; + case 0xCF: /* DEC Rr */ + intRAM[reg_pnt + 7]--; + clk++; + break; + case 0xD0: /* XRL A,@Ri */ + acc = acc ^ intRAM[intRAM[reg_pnt] & 0x3F]; + clk++; + break; + case 0xD1: /* XRL A,@Ri */ + acc = acc ^ intRAM[intRAM[reg_pnt + 1] & 0x3F]; + clk++; + break; + case 0xD2: /* JBb address */ + clk += 2; + dat = ROM(pc); + if (acc & 0x40) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0xD3: /* XRL A,#data */ + clk += 2; + acc = acc ^ ROM(pc++); + break; + case 0xD4: /* CALL */ + make_psw(); + adr = ROM(pc) | 0x600 | A11; + pc++; + clk += 2; + push(pc & 0xFF); + push(((pc & 0xF00) >> 8) | (psw & 0xF0)); + pc = adr; + break; + case 0xD5: /* SEL RB1 */ + bs = 0x10; + reg_pnt = 24; + clk++; + break; + case 0xD6: /* ILL */ + illegal(op); + clk++; + break; + case 0xD7: /* MOV PSW,A */ + psw = acc; + clk++; + cy = (psw & 0x80) >> 7; + ac = psw & 0x40; + f0 = psw & 0x20; + bs = psw & 0x10; + if (bs) + reg_pnt = 24; + else + reg_pnt = 0; + sp = (psw & 0x07) << 1; + sp += 8; + break; + case 0xD8: /* XRL A,Rr */ + acc = acc ^ intRAM[reg_pnt]; + clk++; + break; + case 0xD9: /* XRL A,Rr */ + acc = acc ^ intRAM[reg_pnt + 1]; + clk++; + break; + case 0xDA: /* XRL A,Rr */ + acc = acc ^ intRAM[reg_pnt + 2]; + clk++; + break; + case 0xDB: /* XRL A,Rr */ + acc = acc ^ intRAM[reg_pnt + 3]; + clk++; + break; + case 0xDC: /* XRL A,Rr */ + acc = acc ^ intRAM[reg_pnt + 4]; + clk++; + break; + case 0xDD: /* XRL A,Rr */ + acc = acc ^ intRAM[reg_pnt + 5]; + clk++; + break; + case 0xDE: /* XRL A,Rr */ + acc = acc ^ intRAM[reg_pnt + 6]; + clk++; + break; + case 0xDF: /* XRL A,Rr */ + acc = acc ^ intRAM[reg_pnt + 7]; + clk++; + break; + case 0xE0: /* ILL */ + clk++; + illegal(op); + break; + case 0xE1: /* ILL */ + clk++; + illegal(op); + break; + case 0xE2: /* ILL */ + clk++; + illegal(op); + break; + case 0xE3: /* MOVP3 A,@A */ + + adr = 0x300 | acc; + acc = ROM(adr); + clk += 2; + break; + case 0xE4: /* JMP */ + pc = ROM(pc) | 0x700 | A11; + clk += 2; + break; + case 0xE5: /* SEL MB0 */ + A11 = 0; + A11ff = 0; + clk++; + break; + case 0xE6: /* JNC address */ + clk += 2; + dat = ROM(pc); + if (!cy) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0xE7: /* RL A */ + clk++; + dat = acc & 0x80; + acc = acc << 1; + if (dat) + acc = acc | 0x01; + else + acc = acc & 0xFE; + break; + case 0xE8: /* DJNZ Rr,address */ + clk += 2; + intRAM[reg_pnt]--; + dat = ROM(pc); + if (intRAM[reg_pnt] != 0) + { + pc = pc & 0xF00; + pc = pc | dat; + } + else + pc++; + break; + case 0xE9: /* DJNZ Rr,address */ + clk += 2; + intRAM[reg_pnt + 1]--; + dat = ROM(pc); + if (intRAM[reg_pnt + 1] != 0) + { + pc = pc & 0xF00; + pc = pc | dat; + } + else + pc++; + break; + case 0xEA: /* DJNZ Rr,address */ + clk += 2; + intRAM[reg_pnt + 2]--; + dat = ROM(pc); + if (intRAM[reg_pnt + 2] != 0) + { + pc = pc & 0xF00; + pc = pc | dat; + } + else + pc++; + break; + case 0xEB: /* DJNZ Rr,address */ + clk += 2; + intRAM[reg_pnt + 3]--; + dat = ROM(pc); + if (intRAM[reg_pnt + 3] != 0) + { + pc = pc & 0xF00; + pc = pc | dat; + } + else + pc++; + break; + case 0xEC: /* DJNZ Rr,address */ + clk += 2; + intRAM[reg_pnt + 4]--; + dat = ROM(pc); + if (intRAM[reg_pnt + 4] != 0) + { + pc = pc & 0xF00; + pc = pc | dat; + } + else + pc++; + break; + case 0xED: /* DJNZ Rr,address */ + clk += 2; + intRAM[reg_pnt + 5]--; + dat = ROM(pc); + if (intRAM[reg_pnt + 5] != 0) + { + pc = pc & 0xF00; + pc = pc | dat; + } + else + pc++; + break; + case 0xEE: /* DJNZ Rr,address */ + clk += 2; + intRAM[reg_pnt + 6]--; + dat = ROM(pc); + if (intRAM[reg_pnt + 6] != 0) + { + pc = pc & 0xF00; + pc = pc | dat; + } + else + pc++; + break; + case 0xEF: /* DJNZ Rr,address */ + clk += 2; + intRAM[reg_pnt + 7]--; + dat = ROM(pc); + if (intRAM[reg_pnt + 7] != 0) + { + pc = pc & 0xF00; + pc = pc | dat; + } + else + pc++; + break; + case 0xF0: /* MOV A,@Ri */ + clk++; + acc = intRAM[intRAM[reg_pnt] & 0x3F]; + break; + case 0xF1: /* MOV A,@Ri */ + clk++; + acc = intRAM[intRAM[reg_pnt + 1] & 0x3F]; + break; + case 0xF2: /* JBb address */ + clk += 2; + dat = ROM(pc); + if (acc & 0x80) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0xF3: /* ILL */ + illegal(op); + clk++; + break; + case 0xF4: /* CALL */ + clk += 2; + make_psw(); + adr = ROM(pc) | 0x700 | A11; + pc++; + push(pc & 0xFF); + push(((pc & 0xF00) >> 8) | (psw & 0xF0)); + pc = adr; + break; + case 0xF5: /* SEL MB1 */ + if (irq_ex) + { + A11ff = 0x800; + } + else + { + A11 = 0x800; + A11ff = 0x800; + } + clk++; + break; + case 0xF6: /* JC address */ + clk += 2; + dat = ROM(pc); + if (cy) + pc = (pc & 0xF00) | dat; + else + pc++; + break; + case 0xF7: /* RLC A */ + dat = cy; + cy = (acc & 0x80) >> 7; + acc = acc << 1; + if (dat) + acc = acc | 0x01; + else + acc = acc & 0xFE; + clk++; + break; + case 0xF8: /* MOV A,Rr */ + clk++; + acc = intRAM[reg_pnt]; + break; + case 0xF9: /* MOV A,Rr */ + clk++; + acc = intRAM[reg_pnt + 1]; + break; + case 0xFA: /* MOV A,Rr */ + clk++; + acc = intRAM[reg_pnt + 2]; + break; + case 0xFB: /* MOV A,Rr */ + clk++; + acc = intRAM[reg_pnt + 3]; + break; + case 0xFC: /* MOV A,Rr */ + clk++; + acc = intRAM[reg_pnt + 4]; + break; + case 0xFD: /* MOV A,Rr */ + clk++; + acc = intRAM[reg_pnt + 5]; + break; + case 0xFE: /* MOV A,Rr */ + clk++; + acc = intRAM[reg_pnt + 6]; + break; + case 0xFF: /* MOV A,Rr */ + clk++; + acc = intRAM[reg_pnt + 7]; + break; + } + + master_clk += clk; + h_clk += clk; + clk_counter += clk; + + /* flag for JNI */ + if (int_clk > clk) + int_clk -= clk; + else + int_clk = 0; + + /* pending IRQs */ + if (xirq_pend) + ext_IRQ(); + if (tirq_pend) + tim_IRQ(); + + if (h_clk > LINECNT - 1) + { + h_clk -= LINECNT; + if (enahirq && (VDCwrite[0xA0] & 0x01)) + ext_IRQ(); + if (count_on && mstate == 0) + { + itimer++; + if (itimer == 0) + { + t_flag = 1; + tim_IRQ(); + draw_region(); + } + } + } + + if (timer_on) + { + master_count += clk; + if (master_count > 31) + { + master_count -= 31; + itimer++; + if (itimer == 0) + { + t_flag = 1; + tim_IRQ(); + } + } + } + + if ((mstate == 0) && (master_clk > VBLCLK)) + handle_vbl(); + + if ((mstate == 1) && (master_clk > evblclk)) + { + handle_evbl(); + if (app_data.crc == 0xA7344D1F) + handle_evbll(); /* Atlantis */ + break; + } + } + return clk - startclk; +} diff --git a/waterbox/o2em/cpu.h b/waterbox/o2em/cpu.h new file mode 100644 index 0000000000..1082d0f46e --- /dev/null +++ b/waterbox/o2em/cpu.h @@ -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 */ + diff --git a/waterbox/o2em/crc32.c b/waterbox/o2em/crc32.c new file mode 100644 index 0000000000..fc58b7d466 --- /dev/null +++ b/waterbox/o2em/crc32.c @@ -0,0 +1,97 @@ + +/* + * O2EM Free Odyssey2 / Videopac+ Emulator + * + * Created by Daniel Boris (c) 1997,1998 + * + * Developed by Andre de la Rocha + * Arlindo M. de Oliveira + * + * 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; +} diff --git a/waterbox/o2em/crc32.h b/waterbox/o2em/crc32.h new file mode 100644 index 0000000000..f011a2fea4 --- /dev/null +++ b/waterbox/o2em/crc32.h @@ -0,0 +1,4 @@ +#pragma once +#include +#include "types.h" +uint32_t crc32_buf(const void *buf, size_t len); diff --git a/waterbox/o2em/cset.c b/waterbox/o2em/cset.c new file mode 100644 index 0000000000..353e2fccb6 --- /dev/null +++ b/waterbox/o2em/cset.c @@ -0,0 +1,83 @@ +/* + * O2EM Free Odyssey2 / Videopac+ Emulator + * + * Created by Daniel Boris (c) 1997,1998 + * + * Developed by Andre de la Rocha + * Arlindo M. de Oliveira + * + * 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}; diff --git a/waterbox/o2em/cset.h b/waterbox/o2em/cset.h new file mode 100644 index 0000000000..1528ba8c32 --- /dev/null +++ b/waterbox/o2em/cset.h @@ -0,0 +1,6 @@ +#ifndef __CSET_H +#define __CSET_H + +extern const Byte cset[512]; + +#endif diff --git a/waterbox/o2em/keyboard.c b/waterbox/o2em/keyboard.c new file mode 100644 index 0000000000..2fa54e067d --- /dev/null +++ b/waterbox/o2em/keyboard.c @@ -0,0 +1,41 @@ +/* + * O2EM Free Odyssey2 / Videopac+ Emulator + * + * Created by Daniel Boris (c) 1997,1998 + * + * Developed by Andre de la Rocha + * Arlindo M. de Oliveira + * + * http://o2em.sourceforge.net + * + * + * + * Keyboard emulation + */ + +#include +#include +#include +#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); +} diff --git a/waterbox/o2em/keyboard.h b/waterbox/o2em/keyboard.h new file mode 100644 index 0000000000..b5cc55bb03 --- /dev/null +++ b/waterbox/o2em/keyboard.h @@ -0,0 +1,7 @@ +#ifndef __KEYBOARD_H +#define __KEYBOARD_H + +void handle_key(void); + +#endif + diff --git a/waterbox/o2em/main.c b/waterbox/o2em/main.c new file mode 100644 index 0000000000..ea8380987d --- /dev/null +++ b/waterbox/o2em/main.c @@ -0,0 +1,312 @@ +/* + * O2EM Free Odyssey2 / Videopac+ Emulator + * + * Created by Daniel Boris (c) 1997,1998 + * + * Developed by Andre de la Rocha + * Arlindo M. de Oliveira + * + * http://o2em.sourceforge.net + * + */ + +#include +#include +#include +#include +#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(6026); + 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; +} diff --git a/waterbox/o2em/score.c b/waterbox/o2em/score.c new file mode 100644 index 0000000000..883b812375 --- /dev/null +++ b/waterbox/o2em/score.c @@ -0,0 +1,143 @@ + +/* + * O2EM Free Odyssey2 / Videopac+ Emulator + * + * Created by Daniel Boris (c) 1997,1998 + * + * Developed by Andre de la Rocha + * + * http://o2em.sourceforge.net + * + * + * + * Score loading/saving by manopac + */ + +#include +#include +#include +#include +#include +#include +#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�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>(((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�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); + } +} diff --git a/waterbox/o2em/score.h b/waterbox/o2em/score.h new file mode 100644 index 0000000000..0868801ea0 --- /dev/null +++ b/waterbox/o2em/score.h @@ -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 + diff --git a/waterbox/o2em/types.h b/waterbox/o2em/types.h new file mode 100644 index 0000000000..1201c1bc0f --- /dev/null +++ b/waterbox/o2em/types.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +typedef uint8_t Byte; +typedef uint16_t ADDRESS; +#define MAXC 1024 diff --git a/waterbox/o2em/vdc.c b/waterbox/o2em/vdc.c new file mode 100644 index 0000000000..97a275db75 --- /dev/null +++ b/waterbox/o2em/vdc.c @@ -0,0 +1,556 @@ +/* + * O2EM Free Odyssey2 / Videopac+ Emulator + * + * Created by Daniel Boris (c) 1997,1998 + * + * Developed by Andre de la Rocha + * Arlindo M. de Oliveira + * + * http://o2em.sourceforge.net + * + * + * + * O2 Video Display Controller emulation + */ + +#include +#include +#include +#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> 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); +} diff --git a/waterbox/o2em/vdc.h b/waterbox/o2em/vdc.h new file mode 100644 index 0000000000..5689b94953 --- /dev/null +++ b/waterbox/o2em/vdc.h @@ -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 diff --git a/waterbox/o2em/vmachine.c b/waterbox/o2em/vmachine.c new file mode 100644 index 0000000000..e1fe648466 --- /dev/null +++ b/waterbox/o2em/vmachine.c @@ -0,0 +1,746 @@ +/* + * O2EM Free Odyssey2 / Videopac+ Emulator + * + * Created by Daniel Boris (c) 1997,1998 + * + * Developed by Andre de la Rocha + * Arlindo M. de Oliveira + * + * http://o2em.sourceforge.net + * + * + * + * Main O2 machine emulation + */ + +#include +#include +#include +#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 0xff; + // 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; + } +} diff --git a/waterbox/o2em/vmachine.h b/waterbox/o2em/vmachine.h new file mode 100644 index 0000000000..57ba491fe0 --- /dev/null +++ b/waterbox/o2em/vmachine.h @@ -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 */ + diff --git a/waterbox/o2em/voice.c b/waterbox/o2em/voice.c new file mode 100644 index 0000000000..b1eba1b24b --- /dev/null +++ b/waterbox/o2em/voice.c @@ -0,0 +1,143 @@ +/* + * O2EM Free Odyssey2 / Videopac+ Emulator + * + * Created by Daniel Boris (c) 1997,1998 + * + * Developed by Andre de la Rocha + * Arlindo M. de Oliveira + * + * http://o2em.sourceforge.net + * + * + * + * O2 Voice emulation + */ + +#include +#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; + }*/ +} diff --git a/waterbox/o2em/voice.h b/waterbox/o2em/voice.h new file mode 100644 index 0000000000..1afbead738 --- /dev/null +++ b/waterbox/o2em/voice.h @@ -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 + diff --git a/waterbox/o2em/vpp.c b/waterbox/o2em/vpp.c new file mode 100644 index 0000000000..cd4bc829f1 --- /dev/null +++ b/waterbox/o2em/vpp.c @@ -0,0 +1,588 @@ +/* + * O2EM Free Odyssey2 / Videopac+ Emulator + * + * Created by Daniel Boris (c) 1997,1998 + * + * Developed by Andre de la Rocha + * Arlindo M. de Oliveira + * + * http://o2em.sourceforge.net + * + * + * + * Videopac+ G7400 emulation + */ + +#include +#include +#include +#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; +} diff --git a/waterbox/o2em/vpp.h b/waterbox/o2em/vpp.h new file mode 100644 index 0000000000..a9e1276dcd --- /dev/null +++ b/waterbox/o2em/vpp.h @@ -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 diff --git a/waterbox/o2em/vpp_cset.c b/waterbox/o2em/vpp_cset.c new file mode 100644 index 0000000000..46d3c5cf12 --- /dev/null +++ b/waterbox/o2em/vpp_cset.c @@ -0,0 +1,279 @@ + +/* + * O2EM Free Odyssey2 / Videopac+ Emulator + * + * Created by Daniel Boris (c) 1997,1998 + * + * Developed by Andre de la Rocha + * Arlindo M. de Oliveira + * + * 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}}; diff --git a/waterbox/o2em/vpp_cset.h b/waterbox/o2em/vpp_cset.h new file mode 100644 index 0000000000..29987836dc --- /dev/null +++ b/waterbox/o2em/vpp_cset.h @@ -0,0 +1,6 @@ +#ifndef __VPP_CSET_H +#define __VPP_CSET_H + +extern const Byte vpp_cset[2][1280]; + +#endif diff --git a/waterbox/pizza/.vscode/settings.json b/waterbox/pizza/.vscode/settings.json new file mode 100644 index 0000000000..d5073385ae --- /dev/null +++ b/waterbox/pizza/.vscode/settings.json @@ -0,0 +1,6 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "editor.insertSpaces": false, + "editor.tabSize": 4, + "editor.detectIndentation": false +} \ No newline at end of file diff --git a/waterbox/pizza/Makefile b/waterbox/pizza/Makefile new file mode 100644 index 0000000000..4893bc03f3 --- /dev/null +++ b/waterbox/pizza/Makefile @@ -0,0 +1,54 @@ +CC = x86_64-nt64-midipix-gcc +CPP = x86_64-nt64-midipix-g++ + +FLAGS:=-Wall -Werror=pointer-to-int-cast -Werror=int-to-pointer-cast -Werror=implicit-function-declaration \ + -fomit-frame-pointer -fvisibility=hidden \ + -O3 -flto + +CCFLAGS:=$(FLAGS) -Ilib \ + -I../emulibc \ + -std=c99 \ + -DLSB_FIRST -D_GNU_SOURCE + +CPPFLAGS:=$(FLAGS) -DSPC_NO_COPY_STATE_FUNCS + +TARGET = pizza.wbx + +LDFLAGS = -Wl,--dynamicbase,--export-all-symbols + +ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) +C_SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.c') +CPP_SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.cpp') +SRCS:=$(C_SRCS) $(CPP_SRCS) +OBJ_DIR:=$(ROOT_DIR)/obj + +__OBJS:=$(SRCS:.c=.o) +_OBJS:=$(__OBJS:.cpp=.opp) +OBJS:=$(patsubst $(ROOT_DIR)%,$(OBJ_DIR)%,$(_OBJS)) + +$(OBJ_DIR)/%.o: %.c + @mkdir -p $(@D) + @$(CC) -c -o $@ $< $(CCFLAGS) + +$(OBJ_DIR)/%.opp: %.cpp + @mkdir -p $(@D) + @$(CPP) -c -o $@ $< $(CPPFLAGS) + +all: $(TARGET) + +.PHONY: clean all + +$(TARGET).in: $(OBJS) + @$(CPP) -o $@ $(LDFLAGS) $(FLAGS) $(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)) diff --git a/waterbox/pizza/README.md b/waterbox/pizza/README.md new file mode 100644 index 0000000000..edc069a750 --- /dev/null +++ b/waterbox/pizza/README.md @@ -0,0 +1,49 @@ +# Emu-pizza +A new born Gameboy Classic/Color emulator.... + +Requirements +----------- +Emu-pizza requires libSDL2 to compile and run Space Invaders and Gameboy games. To install it + +on an APT based distro: +``` +sudo apt-get install libsdl2-dev +``` + +on a YUM based distro: +``` +sudo yum install SDL2-devel +``` + +Compile +------- +``` +make +``` + +Usage +----- +``` +emu-pizza [gameboy rom] +``` + +Gameboy keys +------------------- +* Arrows -- Arrows (rly?) +* Enter -- Start +* Space -- Select +* Z/X -- A/B buttons +* Q -- Exit + +Supported ROMS +-------------- +* Almost totality of Gameboy roms + +Todo +---- +* Serial cable emulation + +Credits +------- + +Thanks to [Emulator 101](http://www.emulator101.com), the source of all my current knowledge on 8080 emulation diff --git a/waterbox/pizza/blip_buf/blip_buf.c b/waterbox/pizza/blip_buf/blip_buf.c new file mode 100644 index 0000000000..1bd3377e92 --- /dev/null +++ b/waterbox/pizza/blip_buf/blip_buf.c @@ -0,0 +1,344 @@ +/* blip_buf 1.1.0. http://www.slack.net/~ant/ */ + +#include "blip_buf.h" + +#include +#include +#include +#include + +/* Library Copyright (C) 2003-2009 Shay Green. This library is free software; +you can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +library is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#if defined (BLARGG_TEST) && BLARGG_TEST + #include "blargg_test.h" +#endif + +/* Equivalent to ULONG_MAX >= 0xFFFFFFFF00000000. +Avoids constants that don't fit in 32 bits. */ +#if ULONG_MAX/0xFFFFFFFF > 0xFFFFFFFF + typedef unsigned long fixed_t; + enum { pre_shift = 32 }; + +#elif defined(ULLONG_MAX) + typedef unsigned long long fixed_t; + enum { pre_shift = 32 }; + +#else + typedef unsigned fixed_t; + enum { pre_shift = 0 }; + +#endif + +enum { time_bits = pre_shift + 20 }; + +static fixed_t const time_unit = (fixed_t) 1 << time_bits; + +enum { bass_shift = 9 }; /* affects high-pass filter breakpoint frequency */ +enum { end_frame_extra = 2 }; /* allows deltas slightly after frame length */ + +enum { half_width = 8 }; +enum { buf_extra = half_width*2 + end_frame_extra }; +enum { phase_bits = 5 }; +enum { phase_count = 1 << phase_bits }; +enum { delta_bits = 15 }; +enum { delta_unit = 1 << delta_bits }; +enum { frac_bits = time_bits - pre_shift }; + +/* We could eliminate avail and encode whole samples in offset, but that would +limit the total buffered samples to blip_max_frame. That could only be +increased by decreasing time_bits, which would reduce resample ratio accuracy. +*/ + +/** Sample buffer that resamples to output rate and accumulates samples +until they're read out */ +struct blip_t +{ + fixed_t factor; + fixed_t offset; + int avail; + int size; + int integrator; +}; + +typedef int buf_t; + +/* probably not totally portable */ +#define SAMPLES( buf ) ((buf_t*) ((buf) + 1)) + +/* Arithmetic (sign-preserving) right shift */ +#define ARITH_SHIFT( n, shift ) \ + ((n) >> (shift)) + +enum { max_sample = +32767 }; +enum { min_sample = -32768 }; + +#define CLAMP( n ) \ + {\ + if ( (short) n != n )\ + n = ARITH_SHIFT( n, 16 ) ^ max_sample;\ + } + +static void check_assumptions( void ) +{ + int n; + + #if INT_MAX < 0x7FFFFFFF || UINT_MAX < 0xFFFFFFFF + #error "int must be at least 32 bits" + #endif + + assert( (-3 >> 1) == -2 ); /* right shift must preserve sign */ + + n = max_sample * 2; + CLAMP( n ); + assert( n == max_sample ); + + n = min_sample * 2; + CLAMP( n ); + assert( n == min_sample ); + + assert( blip_max_ratio <= time_unit ); + assert( blip_max_frame <= (fixed_t) -1 >> time_bits ); +} + +blip_t* blip_new( int size ) +{ + blip_t* m; + assert( size >= 0 ); + + m = (blip_t*) malloc( sizeof *m + (size + buf_extra) * sizeof (buf_t) ); + if ( m ) + { + m->factor = time_unit / blip_max_ratio; + m->size = size; + blip_clear( m ); + check_assumptions(); + } + return m; +} + +void blip_delete( blip_t* m ) +{ + if ( m != NULL ) + { + /* Clear fields in case user tries to use after freeing */ + memset( m, 0, sizeof *m ); + free( m ); + } +} + +void blip_set_rates( blip_t* m, double clock_rate, double sample_rate ) +{ + double factor = time_unit * sample_rate / clock_rate; + m->factor = (fixed_t) factor; + + /* Fails if clock_rate exceeds maximum, relative to sample_rate */ + assert( 0 <= factor - m->factor && factor - m->factor < 1 ); + + /* Avoid requiring math.h. Equivalent to + m->factor = (int) ceil( factor ) */ + if ( m->factor < factor ) + m->factor++; + + /* At this point, factor is most likely rounded up, but could still + have been rounded down in the floating-point calculation. */ +} + +void blip_clear( blip_t* m ) +{ + /* We could set offset to 0, factor/2, or factor-1. 0 is suitable if + factor is rounded up. factor-1 is suitable if factor is rounded down. + Since we don't know rounding direction, factor/2 accommodates either, + with the slight loss of showing an error in half the time. Since for + a 64-bit factor this is years, the halving isn't a problem. */ + + m->offset = m->factor / 2; + m->avail = 0; + m->integrator = 0; + memset( SAMPLES( m ), 0, (m->size + buf_extra) * sizeof (buf_t) ); +} + +int blip_clocks_needed( const blip_t* m, int samples ) +{ + fixed_t needed; + + /* Fails if buffer can't hold that many more samples */ + assert( samples >= 0 && m->avail + samples <= m->size ); + + needed = (fixed_t) samples * time_unit; + if ( needed < m->offset ) + return 0; + + return (needed - m->offset + m->factor - 1) / m->factor; +} + +void blip_end_frame( blip_t* m, unsigned t ) +{ + fixed_t off = t * m->factor + m->offset; + m->avail += off >> time_bits; + m->offset = off & (time_unit - 1); + + /* Fails if buffer size was exceeded */ + assert( m->avail <= m->size ); +} + +int blip_samples_avail( const blip_t* m ) +{ + return m->avail; +} + +static void remove_samples( blip_t* m, int count ) +{ + buf_t* buf = SAMPLES( m ); + int remain = m->avail + buf_extra - count; + m->avail -= count; + + memmove( &buf [0], &buf [count], remain * sizeof buf [0] ); + memset( &buf [remain], 0, count * sizeof buf [0] ); +} + +int blip_read_samples( blip_t* m, short out [], int count, int stereo ) +{ + assert( count >= 0 ); + + if ( count > m->avail ) + count = m->avail; + + if ( count ) + { + int const step = stereo ? 2 : 1; + buf_t const* in = SAMPLES( m ); + buf_t const* end = in + count; + int sum = m->integrator; + do + { + /* Eliminate fraction */ + int s = ARITH_SHIFT( sum, delta_bits ); + + sum += *in++; + + CLAMP( s ); + + *out = s; + out += step; + + /* High-pass filter */ + sum -= s << (delta_bits - bass_shift); + } + while ( in != end ); + m->integrator = sum; + + remove_samples( m, count ); + } + + return count; +} + +/* Things that didn't help performance on x86: + __attribute__((aligned(128))) + #define short int + restrict +*/ + +/* Sinc_Generator( 0.9, 0.55, 4.5 ) */ +static short const bl_step [phase_count + 1] [half_width] = +{ +{ 43, -115, 350, -488, 1136, -914, 5861,21022}, +{ 44, -118, 348, -473, 1076, -799, 5274,21001}, +{ 45, -121, 344, -454, 1011, -677, 4706,20936}, +{ 46, -122, 336, -431, 942, -549, 4156,20829}, +{ 47, -123, 327, -404, 868, -418, 3629,20679}, +{ 47, -122, 316, -375, 792, -285, 3124,20488}, +{ 47, -120, 303, -344, 714, -151, 2644,20256}, +{ 46, -117, 289, -310, 634, -17, 2188,19985}, +{ 46, -114, 273, -275, 553, 117, 1758,19675}, +{ 44, -108, 255, -237, 471, 247, 1356,19327}, +{ 43, -103, 237, -199, 390, 373, 981,18944}, +{ 42, -98, 218, -160, 310, 495, 633,18527}, +{ 40, -91, 198, -121, 231, 611, 314,18078}, +{ 38, -84, 178, -81, 153, 722, 22,17599}, +{ 36, -76, 157, -43, 80, 824, -241,17092}, +{ 34, -68, 135, -3, 8, 919, -476,16558}, +{ 32, -61, 115, 34, -60, 1006, -683,16001}, +{ 29, -52, 94, 70, -123, 1083, -862,15422}, +{ 27, -44, 73, 106, -184, 1152,-1015,14824}, +{ 25, -36, 53, 139, -239, 1211,-1142,14210}, +{ 22, -27, 34, 170, -290, 1261,-1244,13582}, +{ 20, -20, 16, 199, -335, 1301,-1322,12942}, +{ 18, -12, -3, 226, -375, 1331,-1376,12293}, +{ 15, -4, -19, 250, -410, 1351,-1408,11638}, +{ 13, 3, -35, 272, -439, 1361,-1419,10979}, +{ 11, 9, -49, 292, -464, 1362,-1410,10319}, +{ 9, 16, -63, 309, -483, 1354,-1383, 9660}, +{ 7, 22, -75, 322, -496, 1337,-1339, 9005}, +{ 6, 26, -85, 333, -504, 1312,-1280, 8355}, +{ 4, 31, -94, 341, -507, 1278,-1205, 7713}, +{ 3, 35, -102, 347, -506, 1238,-1119, 7082}, +{ 1, 40, -110, 350, -499, 1190,-1021, 6464}, +{ 0, 43, -115, 350, -488, 1136, -914, 5861} +}; + +/* Shifting by pre_shift allows calculation using unsigned int rather than +possibly-wider fixed_t. On 32-bit platforms, this is likely more efficient. +And by having pre_shift 32, a 32-bit platform can easily do the shift by +simply ignoring the low half. */ + +void blip_add_delta( blip_t* m, unsigned time, int delta ) +{ + unsigned fixed = (unsigned) ((time * m->factor + m->offset) >> pre_shift); + buf_t* out = SAMPLES( m ) + m->avail + (fixed >> frac_bits); + + int const phase_shift = frac_bits - phase_bits; + int phase = fixed >> phase_shift & (phase_count - 1); + short const* in = bl_step [phase]; + short const* rev = bl_step [phase_count - phase]; + + int interp = fixed >> (phase_shift - delta_bits) & (delta_unit - 1); + int delta2 = (delta * interp) >> delta_bits; + delta -= delta2; + + /* Fails if buffer size was exceeded */ + assert( out <= &SAMPLES( m ) [m->size + end_frame_extra] ); + + out [0] += in[0]*delta + in[half_width+0]*delta2; + out [1] += in[1]*delta + in[half_width+1]*delta2; + out [2] += in[2]*delta + in[half_width+2]*delta2; + out [3] += in[3]*delta + in[half_width+3]*delta2; + out [4] += in[4]*delta + in[half_width+4]*delta2; + out [5] += in[5]*delta + in[half_width+5]*delta2; + out [6] += in[6]*delta + in[half_width+6]*delta2; + out [7] += in[7]*delta + in[half_width+7]*delta2; + + in = rev; + out [ 8] += in[7]*delta + in[7-half_width]*delta2; + out [ 9] += in[6]*delta + in[6-half_width]*delta2; + out [10] += in[5]*delta + in[5-half_width]*delta2; + out [11] += in[4]*delta + in[4-half_width]*delta2; + out [12] += in[3]*delta + in[3-half_width]*delta2; + out [13] += in[2]*delta + in[2-half_width]*delta2; + out [14] += in[1]*delta + in[1-half_width]*delta2; + out [15] += in[0]*delta + in[0-half_width]*delta2; +} + +void blip_add_delta_fast( blip_t* m, unsigned time, int delta ) +{ + unsigned fixed = (unsigned) ((time * m->factor + m->offset) >> pre_shift); + buf_t* out = SAMPLES( m ) + m->avail + (fixed >> frac_bits); + + int interp = fixed >> (frac_bits - delta_bits) & (delta_unit - 1); + int delta2 = delta * interp; + + /* Fails if buffer size was exceeded */ + assert( out <= &SAMPLES( m ) [m->size + end_frame_extra] ); + + out [7] += delta * delta_unit - delta2; + out [8] += delta2; +} diff --git a/waterbox/pizza/blip_buf/blip_buf.h b/waterbox/pizza/blip_buf/blip_buf.h new file mode 100644 index 0000000000..e9a5d4cc3b --- /dev/null +++ b/waterbox/pizza/blip_buf/blip_buf.h @@ -0,0 +1,72 @@ +/** \file +Sample buffer that resamples from input clock rate to output sample rate */ + +/* blip_buf 1.1.0 */ +#ifndef BLIP_BUF_H +#define BLIP_BUF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** First parameter of most functions is blip_t*, or const blip_t* if nothing +is changed. */ +typedef struct blip_t blip_t; + +/** Creates new buffer that can hold at most sample_count samples. Sets rates +so that there are blip_max_ratio clocks per sample. Returns pointer to new +buffer, or NULL if insufficient memory. */ +blip_t* blip_new( int sample_count ); + +/** Sets approximate input clock rate and output sample rate. For every +clock_rate input clocks, approximately sample_rate samples are generated. */ +void blip_set_rates( blip_t*, double clock_rate, double sample_rate ); + +enum { /** Maximum clock_rate/sample_rate ratio. For a given sample_rate, +clock_rate must not be greater than sample_rate*blip_max_ratio. */ +blip_max_ratio = 1 << 20 }; + +/** Clears entire buffer. Afterwards, blip_samples_avail() == 0. */ +void blip_clear( blip_t* ); + +/** Adds positive/negative delta into buffer at specified clock time. */ +void blip_add_delta( blip_t*, unsigned int clock_time, int delta ); + +/** Same as blip_add_delta(), but uses faster, lower-quality synthesis. */ +void blip_add_delta_fast( blip_t*, unsigned int clock_time, int delta ); + +/** Length of time frame, in clocks, needed to make sample_count additional +samples available. */ +int blip_clocks_needed( const blip_t*, int sample_count ); + +enum { /** Maximum number of samples that can be generated from one time frame. */ +blip_max_frame = 4000 }; + +/** Makes input clocks before clock_duration available for reading as output +samples. Also begins new time frame at clock_duration, so that clock time 0 in +the new time frame specifies the same clock as clock_duration in the old time +frame specified. Deltas can have been added slightly past clock_duration (up to +however many clocks there are in two output samples). */ +void blip_end_frame( blip_t*, unsigned int clock_duration ); + +/** Number of buffered samples available for reading. */ +int blip_samples_avail( const blip_t* ); + +/** Reads and removes at most 'count' samples and writes them to 'out'. If +'stereo' is true, writes output to every other element of 'out', allowing easy +interleaving of two buffers into a stereo sample stream. Outputs 16-bit signed +samples. Returns number of samples actually read. */ +int blip_read_samples( blip_t*, short out [], int count, int stereo ); + +/** Frees buffer. No effect if NULL is passed. */ +void blip_delete( blip_t* ); + + +/* Deprecated */ +typedef blip_t blip_buffer_t; + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/waterbox/pizza/lib/cartridge.c b/waterbox/pizza/lib/cartridge.c new file mode 100644 index 0000000000..8a69fefe30 --- /dev/null +++ b/waterbox/pizza/lib/cartridge.c @@ -0,0 +1,233 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#include +#include +#include +#include + +#include "global.h" +#include "mmu.h" +#include "utils.h" + +/* guess what */ +/* return values */ +/* 0: OK */ +/* 1: Can't open/read file */ +/* 2: Unknown cartridge */ + +char cartridge_load(const void *data, size_t sz) +{ + int i, z = 0; + + if (sz < 1 || sz > 1 << 22) + return 1; + + const uint8_t *rom = (const uint8_t *)data; + + /* gameboy color? */ + if (rom[0x143] == 0xC0 || rom[0x143] == 0x80) + { + utils_log("Gameboy Color cartridge\n"); + global_cgb = 1; + } + else + { + utils_log("Gameboy Classic cartridge\n"); + global_cgb = 0; + } + + /* get cartridge infos */ + uint8_t mbc = rom[0x147]; + + utils_log("Cartridge code: %02x\n", mbc); + + switch (mbc) + { + case 0x00: + utils_log("ROM ONLY\n"); + break; + case 0x01: + utils_log("MBC1\n"); + break; + case 0x02: + utils_log("MBC1 + RAM\n"); + break; + case 0x03: + utils_log("MBC1 + RAM + BATTERY\n"); + break; + case 0x05: + utils_log("MBC2\n"); + break; + case 0x06: + mmu_init_ram(512); + utils_log("MBC2 + BATTERY\n"); + break; + case 0x10: + utils_log("MBC3 + TIMER + RAM + BATTERY\n"); + break; + case 0x11: + utils_log("MBC3\n"); + break; + case 0x12: + utils_log("MBC3 + RAM\n"); + break; + case 0x13: + utils_log("MBC3 + RAM + BATTERY\n"); + break; + case 0x19: + utils_log("MBC5\n"); + break; + case 0x1A: + utils_log("MBC5 + RAM\n"); + break; + case 0x1B: + utils_log("MBC5 + RAM + BATTERY\n"); + break; + case 0x1C: + global_rumble = 1; + utils_log("MBC5 + RUMBLE\n"); + break; + case 0x1D: + global_rumble = 1; + utils_log("MBC5 + RUMBLE + RAM\n"); + break; + case 0x1E: + global_rumble = 1; + utils_log("MBC5 + RUMBLE + RAM + BATTERY\n"); + break; + + default: + utils_log("Unknown cartridge type: %02x\n", mbc); + return 2; + } + + /* title */ + for (i = 0x134; i < 0x143; i++) + if (rom[i] > 0x40 && rom[i] < 0x5B) + global_cart_name[z++] = rom[i]; + + global_cart_name[z] = '\0'; + + utils_log("%s\n", global_cart_name); + + /* get ROM banks */ + uint8_t byte = rom[0x148]; + + utils_log("ROM: "); + + switch (byte) + { + case 0x00: + utils_log("0 banks\n"); + break; + case 0x01: + utils_log("4 banks\n"); + break; + case 0x02: + utils_log("8 banks\n"); + break; + case 0x03: + utils_log("16 banks\n"); + break; + case 0x04: + utils_log("32 banks\n"); + break; + case 0x05: + utils_log("64 banks\n"); + break; + case 0x06: + utils_log("128 banks\n"); + break; + case 0x07: + utils_log("256 banks\n"); + break; + case 0x52: + utils_log("72 banks\n"); + break; + case 0x53: + utils_log("80 banks\n"); + break; + case 0x54: + utils_log("96 banks\n"); + break; + } + + /* init MMU */ + mmu_init(mbc, byte); + + /* get RAM banks */ + byte = rom[0x149]; + + utils_log("RAM: "); + + switch (byte) + { + case 0x00: + utils_log("NO RAM\n"); + break; + case 0x01: + mmu_init_ram(1 << 11); + utils_log("2 kB\n"); + break; + case 0x02: + /* MBC5 got bigger values */ + if (mbc >= 0x19 && mbc <= 0x1E) + { + mmu_init_ram(1 << 16); + utils_log("64 kB\n"); + } + else + { + mmu_init_ram(1 << 13); + utils_log("8 kB\n"); + } + break; + case 0x03: + mmu_init_ram(1 << 15); + utils_log("32 kB\n"); + break; + case 0x04: + mmu_init_ram(1 << 17); + utils_log("128 kB\n"); + break; + case 0x05: + mmu_init_ram(1 << 16); + utils_log("64 kB\n"); + break; + } + + /* restore saved RAM if it's the case */ + //mmu_restore_ram(file_sav); + + /* restore saved RTC if it's the case */ + //mmu_restore_rtc(file_rtc); + + /* load FULL ROM at 0x0000 address of system memory */ + mmu_load_cartridge(rom, sz); + + return 0; +} + +/*void cartridge_term() +{ + // save persistent data (battery backed RAM and RTC clock) + mmu_save_ram(file_sav); + mmu_save_rtc(file_rtc); +}*/ diff --git a/waterbox/pizza/lib/cartridge.h b/waterbox/pizza/lib/cartridge.h new file mode 100644 index 0000000000..ebc95de13c --- /dev/null +++ b/waterbox/pizza/lib/cartridge.h @@ -0,0 +1,28 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#ifndef __CARTRIDGE_HDR__ +#define __CARTRIDGE_HDR__ + +#include + +/* prototypes */ +char cartridge_load(const void* data, size_t sz); + +#endif diff --git a/waterbox/pizza/lib/cycles.c b/waterbox/pizza/lib/cycles.c new file mode 100644 index 0000000000..f8a350462e --- /dev/null +++ b/waterbox/pizza/lib/cycles.c @@ -0,0 +1,321 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#include +#include "cycles.h" +#include "global.h" +#include "gpu.h" +#include "mmu.h" +#include "serial.h" +#include "sound.h" +#include "timer.h" +#include "interrupt.h" +#include "utils.h" + +interrupts_flags_t *cycles_if; + +/* instance of the main struct */ +cycles_t cycles = {0, 0, 0, 0}; + +#define CYCLES_PAUSES 256 + +/* hard sync stuff (for remote connection) */ +uint8_t cycles_hs_mode = 0; + +/* type of next */ +typedef enum { + CYCLES_NEXT_TYPE_CYCLES, + CYCLES_NEXT_TYPE_CYCLES_HS, + CYCLES_NEXT_TYPE_DMA, +} cycles_next_type_enum_e; + +/* closest next and its type */ +uint_fast32_t cycles_very_next; +cycles_next_type_enum_e cycles_next_type; + +/* set hard sync mode. sync is given by the remote peer + local timer */ +void cycles_start_hs() +{ + utils_log("Hard sync mode ON\n"); + + /* boolean set to on */ + cycles_hs_mode = 1; +} + +void cycles_stop_hs() +{ + utils_log("Hard sync mode OFF\n"); + + /* boolean set to on */ + cycles_hs_mode = 0; +} + +/* set double or normal speed */ +void cycles_set_speed(char dbl) +{ + /* set global */ + global_cpu_double_speed = dbl; + + /* update clock */ + if (global_cpu_double_speed) + cycles.clock = 4194304 * 2; + else + cycles.clock = 4194304; + + /* calculate the mask */ + cycles_change_emulation_speed(); +} + +/* set emulation speed */ +void cycles_change_emulation_speed() +{ + cycles.step = ((4194304 / CYCLES_PAUSES) + << global_cpu_double_speed); +} + +void cycles_closest_next() +{ + int_fast32_t diff = cycles.cnt - cycles.next; + + /* init */ + cycles_very_next = cycles.next; + cycles_next_type = CYCLES_NEXT_TYPE_CYCLES; + + int_fast32_t diff_new = cycles.cnt - mmu.dma_next; + + /* DMA? */ + if (diff_new < diff) + { + /* this is the new lowest */ + cycles_very_next = mmu.dma_next; + cycles_next_type = CYCLES_NEXT_TYPE_DMA; + } +} + +/* this function is gonna be called every M-cycle = 4 ticks of CPU */ +void cycles_step() +{ + cycles.cnt += 4; + cycles.sampleclock += 2 >> global_cpu_double_speed; + + /* + while (cycles.cnt >= cycles_very_next) + { + switch (cycles_next_type) + { + case CYCLES_NEXT_TYPE_CYCLES: + + deadline.tv_nsec += 1000000000 / CYCLES_PAUSES; + + if (deadline.tv_nsec > 1000000000) + { + deadline.tv_sec += 1; + deadline.tv_nsec -= 1000000000; + } + + clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, + &deadline, NULL); + + cycles.next += cycles.step; + + if (cycles.cnt % cycles.clock == 0) + cycles.seconds++; + + break; + + case CYCLES_NEXT_TYPE_DMA: + + memcpy(&mmu.memory[0xFE00], &mmu.memory[mmu.dma_address], 160); + + mmu.dma_address = 0x0000; + + mmu.dma_next = 1; + + break; + } + + cycles_closest_next(); + } +*/ + + /* 65536 == cpu clock / CYCLES_PAUSES pauses every second */ + if (cycles.cnt == cycles.next) + { + cycles.next += cycles.step; + } + + /* hard sync next step */ + if (cycles.cnt == cycles.hs_next) + { + /* set cycles for hard sync */ + cycles.hs_next += ((4096 * 4) << global_cpu_double_speed); + + /* hard sync is on? */ + if (cycles_hs_mode) + { + /* send my status and wait for peer status back */ + serial_send_byte(); + + /* wait for reply */ + serial_wait_data(); + + /* verify if we need to trigger an interrupt */ + serial_verify_intr(); + } + } + + /* DMA */ + if (mmu.dma_next == cycles.cnt) + { + memcpy(&mmu.memory[0xFE00], &mmu.memory[mmu.dma_address], 160); + + /* reset address */ + mmu.dma_address = 0x0000; + + /* reset */ + mmu.dma_next = 1; + } + + /* update GPU state */ + if (gpu.next == cycles.cnt) + gpu_step(); + + /* fs clock */ + if (sound.fs_cycles_next == cycles.cnt) + sound_step_fs(); + + /* channel one */ + if (sound.channel_one.duty_cycles_next == cycles.cnt) + sound_step_ch1(); + + /* channel two */ + if (sound.channel_two.duty_cycles_next == cycles.cnt) + sound_step_ch2(); + + /* channel three */ + if (sound.channel_three.cycles_next <= cycles.cnt) + sound_step_ch3(); + + /* channel four */ + if (sound.channel_four.cycles_next == cycles.cnt) + sound_step_ch4(); + + /* update timer state */ + if (cycles.cnt == timer.next) + { + timer.next += 256; + timer.div++; + } + + /* timer is on? */ + if (timer.sub_next == cycles.cnt) + { + timer.sub_next += timer.threshold; + timer.cnt++; + + /* cnt value > 255? trigger an interrupt */ + if (timer.cnt > 255) + { + timer.cnt = timer.mod; + + /* trigger timer interrupt */ + cycles_if->timer = 1; + } + } + + /* update serial state */ + if (serial.next == cycles.cnt) + { + /* nullize serial next */ + serial.next -= 1; + + /* reset counter */ + serial.bits_sent = 0; + + /* gotta reply with 0xff when asking for ff01 */ + serial.data = 0xFF; + + /* reset transfer_start flag to yell I'M DONE */ + serial.transfer_start = 0; + + /* if not connected, trig the fucking interrupt */ + cycles_if->serial_io = 1; + } +} + +/* things to do when vsync kicks in */ +void cycles_vblank() +{ + return; +} + +/* stuff tied to entering into hblank state */ +void cycles_hdma() +{ + /* HDMA (only CGB) */ + if (mmu.hdma_to_transfer) + { + /* hblank transfer */ + if (mmu.hdma_transfer_mode) + { + /* transfer when line is changed and we're into HBLANK phase */ + if (mmu.memory[0xFF44] < 143 && + mmu.hdma_current_line != mmu.memory[0xFF44] && + (mmu.memory[0xFF41] & 0x03) == 0x00) + { + /* update current line */ + mmu.hdma_current_line = mmu.memory[0xFF44]; + + /* copy 0x10 bytes */ + if (mmu.vram_idx) + memcpy(mmu_addr_vram1() + mmu.hdma_dst_address - 0x8000, + &mmu.memory[mmu.hdma_src_address], 0x10); + else + memcpy(mmu_addr_vram0() + mmu.hdma_dst_address - 0x8000, + &mmu.memory[mmu.hdma_src_address], 0x10); + + /* decrease bytes to transfer */ + mmu.hdma_to_transfer -= 0x10; + + /* increase pointers */ + mmu.hdma_dst_address += 0x10; + mmu.hdma_src_address += 0x10; + } + } + } +} + +char cycles_init() +{ + cycles.inited = 1; + + /* interrupt registers */ + cycles_if = mmu_addr(0xFF0F); + + /* init clock and counter */ + cycles.clock = 4194304; + cycles.cnt = 0; + cycles.hs_next = 70224; + + /* mask for pauses cycles fast calc */ + cycles.step = 4194304 / CYCLES_PAUSES; + cycles.next = 4194304 / CYCLES_PAUSES; + + return 0; +} diff --git a/waterbox/pizza/lib/cycles.h b/waterbox/pizza/lib/cycles.h new file mode 100644 index 0000000000..58c7c2bb4c --- /dev/null +++ b/waterbox/pizza/lib/cycles.h @@ -0,0 +1,68 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#ifndef __CYCLES_HDR__ +#define __CYCLES_HDR__ + +#include +#include + +typedef struct cycles_s +{ + /* am i init'ed? */ + uint_fast32_t inited; + + /* ticks counter */ + uint64_t cnt; + + // CPU clock. advances at 4MHz or 8MHz depending on current cgb setting + uint_fast32_t clock; + + /* handy for calculation */ + uint64_t next; + + /* step varying on cpu and emulation speed */ + uint_fast32_t step; + + /* 2 spares */ + uint64_t hs_next; + + // reference clock. advances at 2MHz always + uint64_t sampleclock; +} cycles_t; + +extern cycles_t cycles; + +// extern uint8_t cycles_hs_local_cnt; +// extern uint8_t cycles_hs_peer_cnt; + +/* callback function */ +typedef void (*cycles_send_cb_t)(uint32_t v); + +/* prototypes */ +void cycles_change_emulation_speed(); +void cycles_hdma(); +char cycles_init(); +void cycles_set_speed(char dbl); +void cycles_start_hs(); +void cycles_step(); +void cycles_stop_hs(); +void cycles_vblank(); + +#endif diff --git a/waterbox/pizza/lib/gameboy.c b/waterbox/pizza/lib/gameboy.c new file mode 100644 index 0000000000..be64e6436d --- /dev/null +++ b/waterbox/pizza/lib/gameboy.c @@ -0,0 +1,235 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#include +#include +#include "cartridge.h" +#include "sound.h" +#include "mmu.h" +#include "cycles.h" +#include "gpu.h" +#include "global.h" +#include "input.h" +#include "timer.h" +#include "serial.h" +#include "utils.h" +#include "z80_gameboy_regs.h" +#include "z80_gameboy.h" + +char gameboy_inited = 0; + +void gameboy_init() +{ + /* init z80 */ + z80_init(); + + /* init cycles syncronizer */ + cycles_init(); + + /* init timer */ + timer_init(); + + /* init serial */ + serial_init(); + + /* init sound (this will start audio thread) */ + sound_init(); + + /* reset GPU counters */ + gpu_reset(); + + /* reset to default values */ + mmu_write_no_cyc(0xFF05, 0x00); + mmu_write_no_cyc(0xFF06, 0x00); + mmu_write_no_cyc(0xFF07, 0x00); + mmu_write_no_cyc(0xFF10, 0x80); + mmu_write_no_cyc(0xFF11, 0xBF); + mmu_write_no_cyc(0xFF12, 0xF3); + mmu_write_no_cyc(0xFF14, 0xBF); + mmu_write_no_cyc(0xFF16, 0x3F); + mmu_write_no_cyc(0xFF17, 0x00); + mmu_write_no_cyc(0xFF19, 0xBF); + mmu_write_no_cyc(0xFF1A, 0x7F); + mmu_write_no_cyc(0xFF1B, 0xFF); + mmu_write_no_cyc(0xFF1C, 0x9F); + mmu_write_no_cyc(0xFF1E, 0xBF); + mmu_write_no_cyc(0xFF20, 0xFF); + mmu_write_no_cyc(0xFF21, 0x00); + mmu_write_no_cyc(0xFF22, 0x00); + mmu_write_no_cyc(0xFF23, 0xBF); + mmu_write_no_cyc(0xFF24, 0x77); + mmu_write_no_cyc(0xFF25, 0xF3); + mmu_write_no_cyc(0xFF26, 0xF1); + mmu_write_no_cyc(0xFF40, 0x91); + mmu_write_no_cyc(0xFF41, 0x80); + mmu_write_no_cyc(0xFF42, 0x00); + mmu_write_no_cyc(0xFF43, 0x00); + mmu_write_no_cyc(0xFF44, 0x00); + mmu_write_no_cyc(0xFF45, 0x00); + mmu_write_no_cyc(0xFF47, 0xFC); + mmu_write_no_cyc(0xFF48, 0xFF); + mmu_write_no_cyc(0xFF49, 0xFF); + mmu_write_no_cyc(0xFF4A, 0x00); + mmu_write_no_cyc(0xFF4B, 0x00); + mmu_write_no_cyc(0xFF98, 0xDC); + mmu_write_no_cyc(0xFFFF, 0x00); + mmu_write_no_cyc(0xC000, 0x08); + mmu_write_no_cyc(0xFFFE, 0x69); + + if (global_cgb) + state.a = 0x11; + else + state.a = 0x00; + + state.b = 0x00; + state.c = 0x13; + state.d = 0x00; + state.e = 0xd8; + state.h = 0x01; + state.l = 0x4d; + state.pc = 0x0100; + state.sp = 0xFFFE; + *state.f = 0xB0; + + /* reset counter */ + cycles.cnt = 0; + /* start at normal speed */ + global_cpu_double_speed = 0; + + /* mark as inited */ + gameboy_inited = 1; + + return; +} + +void gameboy_run(uint64_t target) +{ + uint8_t op; + + /* get interrupt flags and interrupt enables */ + uint8_t *int_e; + uint8_t *int_f; + + /* pointers to memory location of interrupt enables/flags */ + int_e = mmu_addr(0xFFFF); + int_f = mmu_addr(0xFF0F); + + /* run stuff! */ + /* mechanism is simple. */ + /* 1) execute instruction 2) update cycles counter 3) check interrupts */ + /* and repeat forever */ + while (cycles.sampleclock < target) + { + /* get op */ + op = mmu_read(state.pc); + + /* print out CPU state if enabled by debug flag */ + if (global_debug) + { + utils_log("OP: %02x F: %02x PC: %04x:%02x:%02x SP: %04x:%02x:%02x ", + op, *state.f & 0xd0, state.pc, + mmu_read_no_cyc(state.pc + 1), + mmu_read_no_cyc(state.pc + 2), state.sp, + mmu_read_no_cyc(state.sp), + mmu_read_no_cyc(state.sp + 1)); + + utils_log("A: %02x BC: %04x DE: %04x HL: %04x FF41: %02x " + "FF44: %02x ENAB: %02x INTE: %02x INTF: %02x\n", + state.a, *state.bc, + *state.de, *state.hl, + mmu_read_no_cyc(0xFF41), + mmu_read_no_cyc(0xFF44), + state.int_enable, + *int_e, *int_f); + } + + /* execute instruction by the GB Z80 version */ + z80_execute(op); + + /* if last op was Interrupt Enable (0xFB) */ + /* we need to check for INTR on next cycle */ + if (op == 0xFB) + continue; + + /* interrupts filtered by enable flags */ + uint8_t int_r = (*int_f & *int_e); + + /* check for interrupts */ + if ((state.int_enable || op == 0x76) && (int_r != 0)) + { + /* discard useless bits */ + if ((int_r & 0x1F) == 0x00) + continue; + + /* beware of instruction that doesn't move PC! */ + /* like HALT (0x76) */ + if (op == 0x76) + { + state.pc++; + + if (state.int_enable == 0) + continue; + } + + /* reset int-enable flag, it will be restored after a RETI op */ + state.int_enable = 0; + + if ((int_r & 0x01) == 0x01) + { + /* vblank interrupt triggers RST 5 */ + + /* reset flag */ + *int_f &= 0xFE; + + /* handle the interrupt */ + z80_intr(0x0040); + } + else if ((int_r & 0x02) == 0x02) + { + /* LCD Stat interrupt */ + + /* reset flag */ + *int_f &= 0xFD; + + /* handle the interrupt! */ + z80_intr(0x0048); + } + else if ((int_r & 0x04) == 0x04) + { + /* timer interrupt */ + + /* reset flag */ + *int_f &= 0xFB; + + /* handle the interrupt! */ + z80_intr(0x0050); + } + else if ((int_r & 0x08) == 0x08) + { + /* serial interrupt */ + + /* reset flag */ + *int_f &= 0xF7; + + /* handle the interrupt! */ + z80_intr(0x0058); + } + } + } +} diff --git a/waterbox/pizza/lib/gameboy.h b/waterbox/pizza/lib/gameboy.h new file mode 100644 index 0000000000..06efa026a8 --- /dev/null +++ b/waterbox/pizza/lib/gameboy.h @@ -0,0 +1,28 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#ifndef __GAMEBOY_HDR__ +#define __GAMEBOY_HDR__ + +/* prototypes */ +void gameboy_init(); +void gameboy_run(uint64_t target); +void gameboy_stop(); + +#endif diff --git a/waterbox/pizza/lib/global.c b/waterbox/pizza/lib/global.c new file mode 100644 index 0000000000..e14d158dc3 --- /dev/null +++ b/waterbox/pizza/lib/global.c @@ -0,0 +1,47 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#include +#include + +#include "global.h" + +char global_cart_name[256]; +char global_cgb; // if true, in CGB mode +char global_sgb; // if true, in SGB mode +char global_cpu_double_speed; +char global_debug; +char global_rumble; +char global_window; // if true, show window +int global_lagged; +void (*global_input_callback)(void); +int64_t global_currenttime; + +void global_init() +{ + global_window = 1; + global_debug = 0; + global_cgb = 0; + global_sgb = 0; + global_cpu_double_speed = 0; + global_rumble = 0; + global_lagged = 0; + global_input_callback = NULL; + sprintf(global_cart_name, "NOCARTIRDGE"); +} diff --git a/waterbox/pizza/lib/global.h b/waterbox/pizza/lib/global.h new file mode 100644 index 0000000000..06e3cff320 --- /dev/null +++ b/waterbox/pizza/lib/global.h @@ -0,0 +1,40 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#ifndef __GLOBAL__ +#define __GLOBAL__ + +#include + +extern char global_window; +extern char global_debug; +extern char global_cgb; +extern char global_sgb; +// extern char global_started; +extern char global_cpu_double_speed; +extern char global_rumble; +extern char global_cart_name[256]; +extern int global_lagged; +extern void (*global_input_callback)(void); +extern int64_t global_currenttime; + +/* prototypes */ +void global_init(); + +#endif diff --git a/waterbox/pizza/lib/gpu.c b/waterbox/pizza/lib/gpu.c new file mode 100644 index 0000000000..44859f824d --- /dev/null +++ b/waterbox/pizza/lib/gpu.c @@ -0,0 +1,1072 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#include +#include + +#include "cycles.h" +#include "gameboy.h" +#include "global.h" +#include "gpu.h" +#include "interrupt.h" +#include "mmu.h" +#include "utils.h" +#include "sgb.h" + +/* Gameboy OAM 4 bytes data */ +typedef struct gpu_oam_s +{ + uint8_t y; + uint8_t x; + uint8_t pattern; + + uint8_t palette_cgb : 3; + uint8_t vram_bank : 1; + uint8_t palette : 1; + uint8_t x_flip : 1; + uint8_t y_flip : 1; + uint8_t priority : 1; + +} gpu_oam_t; + +/* Gameboy Color additional tile attributes */ +typedef struct gpu_cgb_bg_tile_s +{ + uint8_t palette : 3; + uint8_t vram_bank : 1; + uint8_t spare : 1; + uint8_t x_flip : 1; + uint8_t y_flip : 1; + uint8_t priority : 1; + +} gpu_cgb_bg_tile_t; + +/* ordered sprite list */ +typedef struct oam_list_s +{ + int idx; + struct oam_list_s *next; +} oam_list_t; + +/* pointer to interrupt flags (handy) */ +interrupts_flags_t *gpu_if; + +/* internal functions prototypes */ +void gpu_draw_sprite_line(gpu_oam_t *oam, + uint8_t sprites_size, + uint8_t line); +void gpu_draw_window_line(int tile_idx, uint8_t frame_x, + uint8_t frame_y, uint8_t line); + +/* 2 bit to 8 bit color lookup */ +// TODO: hook these up to the same color logic that that the other GB core uses +static const uint32_t gpu_color_lookup[] = {0xffffffff, 0xffaaaaaa, 0xff555555, 0xff000000}; + +/* function to call when frame is ready */ +gpu_frame_ready_cb_t gpu_frame_ready_cb; + +/* global state of GPU */ +gpu_t gpu; + +void gpu_dump_oam() +{ + /* make it point to the first OAM object */ + gpu_oam_t *oam = (gpu_oam_t *)mmu_addr(0xFE00); + + int i; + + for (i = 0; i < 40; i++) + { + if (oam[i].x != 0 && oam[i].y != 0) + printf("OAM X %d Y %d VRAM %d PATTERN %d\n", oam[i].x, oam[i].y, + oam[i].vram_bank, + oam[i].pattern); + } +} + +/* init pointers */ +void gpu_init_pointers() +{ + /* make gpu field points to the related memory area */ + gpu.lcd_ctrl = mmu_addr(0xFF40); + gpu.lcd_status = mmu_addr(0xFF41); + gpu.scroll_y = mmu_addr(0xFF42); + gpu.scroll_x = mmu_addr(0xFF43); + gpu.window_y = mmu_addr(0xFF4A); + gpu.window_x = mmu_addr(0xFF4B); + gpu.ly = mmu_addr(0xFF44); + gpu.lyc = mmu_addr(0xFF45); + gpu_if = mmu_addr(0xFF0F); +} + +/* reset */ +void gpu_reset() +{ + /* init counters */ + gpu.next = 456 << global_cpu_double_speed; + gpu.frame_counter = 0; +} + +/* init GPU states */ +void gpu_init(gpu_frame_ready_cb_t cb) +{ + /* reset gpu structure */ + bzero(&gpu, sizeof(gpu_t)); + + /* init memory pointers */ + gpu_init_pointers(); + + /* init counters */ + gpu.next = 456 << global_cpu_double_speed; + gpu.frame_counter = 0; + + /* step for normal CPU speed */ + gpu.step = 4; + + /* init palette */ + memcpy(gpu.bg_palette, gpu_color_lookup, sizeof(uint32_t) * 4); + memcpy(gpu.obj_palette_0, gpu_color_lookup, sizeof(uint32_t) * 4); + memcpy(gpu.obj_palette_1, gpu_color_lookup, sizeof(uint32_t) * 4); + + /* set callback */ + gpu_frame_ready_cb = cb; +} + +/* turn on/off lcd */ +void gpu_toggle(uint8_t state) +{ + /* from off to on */ + if (state & 0x80) + { + /* LCD turned on */ + gpu.next = cycles.cnt + (456 << global_cpu_double_speed); + *gpu.ly = 0; + (*gpu.lcd_status).mode = 0x00; + (*gpu.lcd_status).ly_coincidence = 0x00; + } + else + { + /* LCD turned off - reset stuff */ + gpu.next = cycles.cnt - 1; // + (80 << global_cpu_double_speed); + *gpu.ly = 0; + (*gpu.lcd_status).mode = 0x00; + } +} + +/* push frame on screen */ +void gpu_draw_frame() +{ + /* increase frame counter */ + gpu.frame_counter++; + + /* is it the case to push samples? */ + /*if ((global_emulation_speed == GLOBAL_EMULATION_SPEED_DOUBLE && + (gpu.frame_counter & 0x0001) != 0) || + (global_emulation_speed == GLOBAL_EMULATION_SPEED_4X && + (gpu.frame_counter & 0x0003) != 0)) + return;*/ + + if (global_sgb) + { + sgb_take_frame(gpu.frame_buffer); + } + + /* call the callback */ + if (gpu_frame_ready_cb) + (*gpu_frame_ready_cb)(); + + /* reset priority matrix */ + bzero(gpu.priority, 160 * 144); + bzero(gpu.palette_idx, 160 * 144); + + return; +} + +/* draw a single line */ +void gpu_draw_line(uint8_t line) +{ + /* avoid mess */ + if (line > 144) + return; + + /* is it the case to push samples? */ + /*if ((global_emulation_speed == GLOBAL_EMULATION_SPEED_DOUBLE && + (gpu.frame_counter & 0x0001) != 0) || + (global_emulation_speed == GLOBAL_EMULATION_SPEED_4X && + (gpu.frame_counter & 0x0003) != 0)) + return;*/ + + int i, t, y, px_start, px_drawn; + uint8_t *tiles_map, tile_subline, palette_idx, x_flip, priority; + uint16_t tiles_addr, tile_n, tile_idx, tile_line; + uint16_t tile_y; + + /* gotta show BG? Answer is always YES in case of Gameboy Color */ + if ((*gpu.lcd_ctrl).bg || global_cgb) + { + gpu_cgb_bg_tile_t *tiles_map_cgb = NULL; + uint8_t *tiles = NULL; + uint32_t *palette; + + if (global_cgb) + { + /* CGB tile map into VRAM0 */ + tiles_map = mmu_addr_vram0() + ((*gpu.lcd_ctrl).bg_tiles_map ? 0x1C00 : 0x1800); + + /* additional attribute table is into VRAM1 */ + tiles_map_cgb = mmu_addr_vram1() + ((*gpu.lcd_ctrl).bg_tiles_map ? 0x1C00 : 0x1800); + } + else + { + /* never flip */ + x_flip = 0; + + /* get tile map offset */ + tiles_map = mmu_addr((*gpu.lcd_ctrl).bg_tiles_map ? 0x9C00 : 0x9800); + + if ((*gpu.lcd_ctrl).bg_tiles) + tiles_addr = 0x8000; + else + tiles_addr = 0x9000; + + /* get absolute address of tiles area */ + tiles = mmu_addr(tiles_addr); + + /* monochrome GB uses a single BG palette */ + palette = gpu.bg_palette; + + /* always priority = 0 */ + priority = 0; + } + + /* calc tile y */ + tile_y = (*(gpu.scroll_y) + line) & 0xFF; + + /* calc first tile idx */ + tile_idx = ((tile_y >> 3) * 32) + (*(gpu.scroll_x) / 8); + + /* tile line because if we reach the end of the line, */ + /* we have to rewind to the first tile of the same line */ + tile_line = ((tile_y >> 3) * 32); + + /* calc first pixel of frame buffer of the current line */ + uint_fast16_t pos_fb = line * 160; + uint_fast16_t pos; + + /* calc tile subline */ + tile_subline = tile_y % 8; + + /* walk through different tiles */ + for (t = 0; t < 21; t++) + { + /* resolv tile data memory area */ + if ((*gpu.lcd_ctrl).bg_tiles == 0) + tile_n = (int8_t)tiles_map[tile_idx]; + else + tile_n = (tiles_map[tile_idx] & 0x00FF); + + /* if color gameboy, resolv which palette is bound */ + if (global_cgb) + { + /* extract palette index (0-31) */ + palette_idx = tiles_map_cgb[tile_idx].palette; + + /* get palette pointer to 4 (16bit) colors */ + palette = &gpu.cgb_palette_bg_rgb888[palette_idx * 4]; + + /* get priority of the tile */ + priority = tiles_map_cgb[tile_idx].priority; + + if (tiles_map_cgb[tile_idx].vram_bank) + tiles = mmu_addr_vram1() + + ((*gpu.lcd_ctrl).bg_tiles ? 0x0000 : 0x1000); + else + tiles = mmu_addr_vram0() + + ((*gpu.lcd_ctrl).bg_tiles ? 0x0000 : 0x1000); + + /* calc subline in case of flip_y */ + if (tiles_map_cgb[tile_idx].y_flip) + tile_subline = 7 - (tile_y % 8); + else + tile_subline = tile_y % 8; + + /* save x_flip */ + x_flip = tiles_map_cgb[tile_idx].x_flip; + } + + /* calc tile data pointer */ + int16_t tile_ptr = (tile_n * 16) + (tile_subline * 2); + + /* pixels are handled in a super shitty way */ + /* bit 0 of the pixel is taken from even position tile bytes */ + /* bit 1 of the pixel is taken from odd position tile bytes */ + + uint8_t pxa[8]; + uint8_t shft; + uint8_t b1 = *(tiles + tile_ptr); + uint8_t b2 = *(tiles + tile_ptr + 1); + + for (y = 0; y < 8; y++) + { + if (x_flip) + shft = (1 << (7 - y)); + else + shft = (1 << y); + + pxa[y] = ((b1 & shft) ? 1 : 0) | + ((b2 & shft) ? 2 : 0); + } + + /* particular cases for first and last tile */ + /* (could be shown just a part) */ + if (t == 0) + { + px_start = (*(gpu.scroll_x) % 8); + + px_drawn = 8 - px_start; + + /* set n pixels */ + for (i = 0; i < px_drawn; i++) + { + pos = pos_fb + (px_drawn - i - 1); + + gpu.priority[pos] = priority; + gpu.palette_idx[pos] = pxa[i]; + gpu.frame_buffer[pos] = palette[pxa[i]]; + } + } + else if (t == 20) + { + px_drawn = *(gpu.scroll_x) % 8; + + /* set n pixels */ + for (i = 0; i < px_drawn; i++) + { + pos = pos_fb + (px_drawn - i - 1); + + gpu.priority[pos] = priority; + gpu.palette_idx[pos] = pxa[i]; + gpu.frame_buffer[pos] = palette[pxa[i + (8 - px_drawn)]]; + } + } + else + { + /* set 8 pixels */ + for (i = 0; i < 8; i++) + { + pos = pos_fb + (7 - i); + + gpu.priority[pos] = priority; + gpu.palette_idx[pos] = pxa[i]; + gpu.frame_buffer[pos] = palette[pxa[i]]; + } + + px_drawn = 8; + } + + /* go to the next tile and rewind in case we reached the 32th */ + tile_idx++; + + /* don't go to the next line, just rewind */ + if (tile_idx == (tile_line + 32)) + tile_idx = tile_line; + + /* go to the next block of 8 pixels of the frame buffer */ + pos_fb += px_drawn; + } + } + + /* gotta show sprites? */ + if ((*gpu.lcd_ctrl).sprites) + { + /* make it point to the first OAM object */ + gpu_oam_t *oam = (gpu_oam_t *)mmu_addr(0xFE00); + + /* calc sprite height */ + uint8_t h = ((*gpu.lcd_ctrl).sprites_size + 1) * 8; + + int sort[40]; + int j = 0; + + /* prepare sorted list of oams */ + for (i = 0; i < 40; i++) + sort[i] = -1; + + for (i = 0; i < 40; i++) + { + /* the sprite intersects the current line? */ + if (oam[i].x != 0 && oam[i].y != 0 && + oam[i].x < 168 && oam[i].y < 160 && + line < (oam[i].y + h - 16) && + line >= (oam[i].y - 16)) + { + /* color GB uses memory position as priority criteria */ + if (global_cgb) + { + sort[j++] = i; + continue; + } + + /* find its position on sort array */ + for (j = 0; j < 40; j++) + { + if (sort[j] == -1) + { + sort[j] = i; + break; + } + + if (global_cgb) + continue; + + if ((oam[i].y < oam[sort[j]].y) || + ((oam[i].y == oam[sort[j]].y) && + (oam[i].x < oam[sort[j]].x))) + { + int z; + + for (z = 40; z > j; z--) + sort[z] = sort[z - 1]; + + sort[j] = i; + break; + } + } + } + } + + /* draw ordered sprite list */ + for (i = 0; i < 40 && sort[i] != -1; i++) + gpu_draw_sprite_line(&oam[sort[i]], + (*gpu.lcd_ctrl).sprites_size, line); + } + + /* wanna show window? */ + if (global_window && (*gpu.lcd_ctrl).window) + { + /* at least the current line is covering the window area? */ + if (line < *(gpu.window_y)) + return; + + /* TODO - reset this in a better place */ + if (line == *(gpu.window_y)) + gpu.window_skipped_lines = 0; + + int z, first_z; + uint8_t tile_pos_x, tile_pos_y; + + /* gotta draw a window? check if it is inside screen coordinates */ + if (*(gpu.window_y) >= 144 || + *(gpu.window_x) >= 160) + { + gpu.window_skipped_lines++; + return; + } + + /* calc the first interesting tile */ + first_z = ((line - *(gpu.window_y) - + gpu.window_skipped_lines) >> + 3) + << 5; + + for (z = first_z; z < first_z + 21; z++) + { + /* calc tile coordinates on frame buffer */ + tile_pos_x = ((z & 0x1F) << 3) + *(gpu.window_x) - 7; + tile_pos_y = ((z >> 5) << 3) + *(gpu.window_y) + + gpu.window_skipped_lines; + + /* gone over the current line? */ + if (tile_pos_y > line) + break; + + if (tile_pos_y < (line - 7)) + continue; + + /* gone over the screen visible X? */ + /* being between last column and first one is valid */ + if (tile_pos_x >= 160 && tile_pos_x < 248) + break; + + /* gone over the screen visible section? stop it */ + if (tile_pos_y >= 144) // || (tile_pos_x >= 160)) + break; + + /* put tile on frame buffer */ + gpu_draw_window_line(z, (uint8_t)tile_pos_x, + (uint8_t)tile_pos_y, line); + } + } +} + +/* draw a tile in x,y coordinates */ +void gpu_draw_window_line(int tile_idx, uint8_t frame_x, + uint8_t frame_y, uint8_t line) +{ + int i, p, y, pos; + int16_t tile_n; + uint8_t *tiles_map; + gpu_cgb_bg_tile_t *tiles_map_cgb = NULL; + uint8_t *tiles, x_flip; + uint32_t *palette; + + if (global_cgb) + { + /* CGB tile map into VRAM0 */ + tiles_map = mmu_addr_vram0() + ((*gpu.lcd_ctrl).window_tiles_map ? 0x1C00 : 0x1800); + + /* additional attribute table is into VRAM1 */ + tiles_map_cgb = mmu_addr_vram1() + ((*gpu.lcd_ctrl).window_tiles_map ? 0x1C00 : 0x1800); + + /* get palette index */ + uint8_t palette_idx = tiles_map_cgb[tile_idx].palette; + x_flip = tiles_map_cgb[tile_idx].x_flip; + + /* get palette pointer to 4 (16bit) colors */ + palette = &gpu.cgb_palette_bg_rgb888[palette_idx * 4]; + + /* attribute table will tell us where is the tile */ + if (tiles_map_cgb[tile_idx].vram_bank) + tiles = mmu_addr_vram1() + + ((*gpu.lcd_ctrl).bg_tiles ? 0x0000 : 0x1000); + else + tiles = mmu_addr_vram0() + + ((*gpu.lcd_ctrl).bg_tiles ? 0x0000 : 0x1000); + } + else + { + /* get tile map offset */ + tiles_map = mmu_addr((*gpu.lcd_ctrl).window_tiles_map ? 0x9C00 : 0x9800); + + /* get tile offset */ + if ((*gpu.lcd_ctrl).bg_tiles) + tiles = mmu_addr(0x8000); + else + tiles = mmu_addr(0x9000); + + /* monochrome GB uses a single BG palette */ + palette = gpu.bg_palette; + + /* never flip */ + x_flip = 0; + } + + /* obtain tile number */ + if ((*gpu.lcd_ctrl).bg_tiles == 0) + tile_n = (int8_t)tiles_map[tile_idx]; + else + tile_n = (tiles_map[tile_idx] & 0x00ff); + + /* calc vertical offset INSIDE the tile */ + p = (line - frame_y) * 2; + + /* calc frame position buffer for 4 pixels */ + uint32_t pos_fb = (line * 160); + + /* calc tile pointer */ + int16_t tile_ptr = (tile_n * 16) + p; + + /* pixels are handled in a super shitty way */ + /* bit 0 of the pixel is taken from even position tile bytes */ + /* bit 1 of the pixel is taken from odd position tile bytes */ + + uint8_t pxa[8]; + uint8_t shft; + + for (y = 0; y < 8; y++) + { + //uint8_t shft = (1 << y); + + if (x_flip) + shft = (1 << (7 - y)); + else + shft = (1 << y); + + pxa[y] = ((*(tiles + tile_ptr) & shft) ? 1 : 0) | + ((*(tiles + tile_ptr + 1) & shft) ? 2 : 0); + } + + /* set 8 pixels (full tile line) */ + for (i = 0; i < 8; i++) + { + /* over the last column? */ + uint8_t x = frame_x + (7 - i); + + if (x > 159) + continue; + + /* calc position on frame buffer */ + pos = pos_fb + x; + + /* can overwrite sprites? depends on pixel priority */ + if (gpu.priority[pos] != 0x02) + gpu.frame_buffer[pos] = palette[pxa[i]]; + } +} + +/* draw a sprite tile in x,y coordinates */ +void gpu_draw_sprite_line(gpu_oam_t *oam, uint8_t sprites_size, uint8_t line) +{ + int_fast32_t x, y, pos, fb_x, off; + uint_fast16_t p, i, j; + uint8_t sprite_bytes; + int16_t tile_ptr; + uint32_t *palette; + uint8_t *tiles; + + /* REMEMBER! position of sprites is relative to the visible screen area */ + /* ... and y is shifted by 16 pixels, x by 8 */ + y = oam->y - 16; + x = oam->x - 8; + + if (x < -7) + return; + + /* first pixel on frame buffer position */ + uint32_t tile_pos_fb = (y * 160) + x; + + /* choose palette */ + if (global_cgb) + { + uint8_t palette_idx = oam->palette_cgb; + + /* get palette pointer to 4 (16bit) colors */ + palette = &gpu.cgb_palette_oam_rgb888[palette_idx * 4]; + + /* tiles are into vram0 */ + if (oam->vram_bank) + tiles = mmu_addr_vram1(); + else + tiles = mmu_addr_vram0(); + } + else + { + /* tiles are int fixed 0x8000 address */ + tiles = mmu_addr(0x8000); + + if (oam->palette) + palette = gpu.obj_palette_1; + else + palette = gpu.obj_palette_0; + } + + /* calc sprite in byte */ + sprite_bytes = 16 * (sprites_size + 1); + + /* walk through 8x8 pixels (2bit per pixel -> 4 pixels per byte) */ + /* 1 line is 8 pixels -> 2 bytes per line */ + for (p = 0; p < sprite_bytes; p += 2) + { + uint8_t tile_y = p / 2; + + if (tile_y + y != line) + continue; + + /* calc frame position buffer for 4 pixels */ + uint32_t pos_fb = (tile_pos_fb + (tile_y * 160)) & 0xFFFF; //% 65536; + + /* calc tile pointer */ + if (oam->y_flip) + tile_ptr = (oam->pattern * 16) + (sprite_bytes - p - 2); + else + tile_ptr = (oam->pattern * 16) + p; + + /* pixels are handled in a super shitty way */ + /* bit 0 of the pixel is taken from even position tile bytes */ + /* bit 1 of the pixel is taken from odd position tile bytes */ + + uint8_t pxa[8]; + + for (j = 0; j < 8; j++) + { + uint8_t shft = (1 << j); + + pxa[j] = ((*(tiles + tile_ptr) & shft) ? 1 : 0) | + ((*(tiles + tile_ptr + 1) & shft) ? 2 : 0); + } + + /* set 8 pixels (full tile line) */ + for (i = 0; i < 8; i++) + { + if (oam->x_flip) + off = i; + else + off = 7 - i; + + /* is it on screen? */ + fb_x = x + off; + + if (fb_x < 0 || fb_x > 160) + continue; + + /* set serial position on frame buffer */ + pos = pos_fb + off; + + /* is it inside the screen? */ + if (pos >= 144 * 160 || pos < 0) + continue; + + if (global_cgb) + { + /* sprite color 0 = transparent */ + if (pxa[i] != 0x00) + { + /* flag clr = sprites always on top of bg and window */ + if ((*gpu.lcd_ctrl).bg == 0) + { + gpu.frame_buffer[pos] = palette[pxa[i]]; + gpu.priority[pos] = 0x02; + } + else + { + if (((gpu.priority[pos] == 0) && + (oam->priority == 0 || + (oam->priority == 1 && + gpu.palette_idx[pos] == 0x00))) || + (gpu.priority[pos] == 1 && + gpu.palette_idx[pos] == 0x00)) + { + gpu.frame_buffer[pos] = palette[pxa[i]]; + gpu.priority[pos] = (oam->priority ? 0x00 : 0x02); + } + } + } + } + else + { + /* push on screen pixels not set to zero (transparent) */ + /* and if the priority is set to one, overwrite just */ + /* bg pixels set to zero */ + if ((pxa[i] != 0x00) && + (oam->priority == 0 || + (oam->priority == 1 && + gpu.frame_buffer[pos] == gpu.bg_palette[0x00]))) + { + gpu.frame_buffer[pos] = palette[pxa[i]]; + gpu.priority[pos] = (oam->priority ? 0x00 : 0x02); + } + } + } + } +} + +/* update GPU internal state given CPU T-states */ +void gpu_step() +{ + char ly_changed = 0; + char mode_changed = 0; + + /* take different action based on current state */ + switch ((*gpu.lcd_status).mode) + { + /* + * during HBLANK (CPU can access VRAM) + */ + case 0: + /* handle HDMA stuff during hblank */ + cycles_hdma(); + + /* + * if current line == 143 (and it's about to turn 144) + * enter mode 01 (VBLANK) + */ + if (*gpu.ly == 143) + { + /* notify mode has changes */ + mode_changed = 1; + + (*gpu.lcd_status).mode = 0x01; + + /* mode one lasts 456 cycles */ + gpu.next = cycles.cnt + + (456 << global_cpu_double_speed); + + /* DRAW! TODO */ + /* CHECK INTERRUPTS! TODO */ + cycles_vblank(); + + /* set VBLANK interrupt flag */ + gpu_if->lcd_vblank = 1; + + /* apply gameshark patches */ + //mmu_apply_gs(); + + /* and finally push it on screen! */ + gpu_draw_frame(); + } + else + { + /* notify mode has changed */ + mode_changed = 1; + + /* enter OAM mode */ + (*gpu.lcd_status).mode = 0x02; + + /* mode 2 needs 80 cycles */ + gpu.next = cycles.cnt + + (80 << global_cpu_double_speed); + } + + /* notify mode has changed */ + ly_changed = 1; + + /* inc current line */ + (*gpu.ly)++; + + // cycles_hblank(*gpu.ly); + + break; + + /* + * during VBLANK (CPU can access VRAM) + */ + case 1: + /* notify ly has changed */ + ly_changed = 1; + + /* inc current line */ + (*gpu.ly)++; + + /* reached the bottom? */ + if ((*gpu.ly) > 153) + { + /* go back to line 0 */ + (*gpu.ly) = 0; + + /* switch to OAM mode */ + (*gpu.lcd_status).mode = 0x02; + + /* */ + gpu.next = + cycles.cnt + (80 << global_cpu_double_speed); + } + else + gpu.next = + cycles.cnt + (456 << global_cpu_double_speed); + + break; + + /* + * during OAM (LCD access FE00-FE90, so CPU cannot) + */ + case 2: + /* reset clock counter */ + gpu.next = + cycles.cnt + (172 << global_cpu_double_speed); + + /* notify mode has changed */ + mode_changed = 1; + + /* switch to VRAM mode */ + (*gpu.lcd_status).mode = 0x03; + + break; + + /* + * during VRAM (LCD access both OAM and VRAM, so CPU cannot) + */ + case 3: + /* reset clock counter */ + gpu.next = + cycles.cnt + (204 << global_cpu_double_speed); + + /* notify mode has changed */ + mode_changed = 1; + + /* go back to HBLANK mode */ + (*gpu.lcd_status).mode = 0x00; + + /* draw line */ + gpu_draw_line(*gpu.ly); + + /* notify cycles */ + // cycles_hblank(*gpu.ly); + + //printf("COLLA %d\n", *gpu.ly); + + break; + } + + /* ly changed? is it the case to trig an interrupt? */ + if (ly_changed) + { + /* check if we gotta trigger an interrupt */ + if ((*gpu.ly) == (*gpu.lyc)) + { + /* set lcd status flags indicating there's a concidence */ + (*gpu.lcd_status).ly_coincidence = 1; + + /* an interrupt is desiderable? */ + if ((*gpu.lcd_status).ir_ly_coincidence) + gpu_if->lcd_ctrl = 1; + } + else + { + /* set lcd status flags indicating there's NOT a concidence */ + (*gpu.lcd_status).ly_coincidence = 0; + } + } + + /* mode changed? is is the case to trig an interrupt? */ + if (mode_changed) + { + if ((*gpu.lcd_status).mode == 0x00 && + (*gpu.lcd_status).ir_mode_00) + gpu_if->lcd_ctrl = 1; + else if ((*gpu.lcd_status).mode == 0x01 && + (*gpu.lcd_status).ir_mode_01) + gpu_if->lcd_ctrl = 1; + else if ((*gpu.lcd_status).mode == 0x02 && + (*gpu.lcd_status).ir_mode_10) + gpu_if->lcd_ctrl = 1; + } +} + +uint8_t gpu_read_reg(uint16_t a) +{ + switch (a) + { + case 0xFF68: + + return (gpu.cgb_palette_bg_autoinc << 7 | gpu.cgb_palette_bg_idx); + + case 0xFF69: + + if ((gpu.cgb_palette_bg_idx & 0x01) == 0x00) + return gpu.cgb_palette_bg[gpu.cgb_palette_bg_idx / 2] & + 0x00ff; + else + return (gpu.cgb_palette_bg[gpu.cgb_palette_bg_idx / 2] & + 0xff00) >> + 8; + + case 0xFF6A: + + return (gpu.cgb_palette_oam_autoinc << 7 | gpu.cgb_palette_oam_idx); + + case 0xFF6B: + + if ((gpu.cgb_palette_oam_idx & 0x01) == 0x00) + return gpu.cgb_palette_oam[gpu.cgb_palette_oam_idx / 2] & + 0x00ff; + else + return (gpu.cgb_palette_oam[gpu.cgb_palette_oam_idx / 2] & + 0xff00) >> + 8; + } + + return 0x00; +} + +static uint32_t makecol(uint16_t c) +{ + // TODO: hook this up to the same color logic that the other cores use + return c >> 7 & 0xf8 | c >> 12 & 0x07 + | c << 6 & 0xf800 | c << 1 & 0x0700 + | c << 19 & 0xf80000 | c << 14 & 0x070000 + | 0xff000000; +} + +void gpu_write_reg(uint16_t a, uint8_t v) +{ + int i; + switch (a) + { + case 0xFF47: + gpu.bg_palette[0] = gpu_color_lookup[v & 0x03]; + gpu.bg_palette[1] = gpu_color_lookup[(v & 0x0c) >> 2]; + gpu.bg_palette[2] = gpu_color_lookup[(v & 0x30) >> 4]; + gpu.bg_palette[3] = gpu_color_lookup[(v & 0xc0) >> 6]; + break; + + case 0xFF48: + gpu.obj_palette_0[0] = gpu_color_lookup[v & 0x03]; + gpu.obj_palette_0[1] = gpu_color_lookup[(v & 0x0c) >> 2]; + gpu.obj_palette_0[2] = gpu_color_lookup[(v & 0x30) >> 4]; + gpu.obj_palette_0[3] = gpu_color_lookup[(v & 0xc0) >> 6]; + break; + + case 0xFF49: + gpu.obj_palette_1[0] = gpu_color_lookup[v & 0x03]; + gpu.obj_palette_1[1] = gpu_color_lookup[(v & 0x0c) >> 2]; + gpu.obj_palette_1[2] = gpu_color_lookup[(v & 0x30) >> 4]; + gpu.obj_palette_1[3] = gpu_color_lookup[(v & 0xc0) >> 6]; + break; + + case 0xFF68: + gpu.cgb_palette_bg_idx = (v & 0x3f); + gpu.cgb_palette_bg_autoinc = ((v & 0x80) == 0x80); + break; + + case 0xFF69: + i = gpu.cgb_palette_bg_idx / 2; + + if ((gpu.cgb_palette_bg_idx & 0x01) == 0x00) + { + gpu.cgb_palette_bg[i] &= 0xff00; + gpu.cgb_palette_bg[i] |= v; + } + else + { + gpu.cgb_palette_bg[i] &= 0x00ff; + gpu.cgb_palette_bg[i] |= (v << 8); + } + + gpu.cgb_palette_bg_rgb888[i] = makecol(gpu.cgb_palette_bg[i]); + + if (gpu.cgb_palette_bg_autoinc) + gpu.cgb_palette_bg_idx = (gpu.cgb_palette_bg_idx + 1) & 0x3f; + + break; + + case 0xFF6A: + gpu.cgb_palette_oam_idx = v & 0x3f; + gpu.cgb_palette_oam_autoinc = ((v & 0x80) == 0x80); + break; + + case 0xFF6B: + i = gpu.cgb_palette_oam_idx / 2; + + if ((gpu.cgb_palette_oam_idx & 0x01) == 0x00) + { + gpu.cgb_palette_oam[i] &= 0xff00; + gpu.cgb_palette_oam[i] |= v; + } + else + { + gpu.cgb_palette_oam[i] &= 0x00ff; + gpu.cgb_palette_oam[i] |= (v << 8); + } + + gpu.cgb_palette_oam_rgb888[i] = makecol(gpu.cgb_palette_oam[i]); + + if (gpu.cgb_palette_oam_autoinc) + gpu.cgb_palette_oam_idx = (gpu.cgb_palette_oam_idx + 1) & 0x3f; + + break; + } +} + +void gpu_set_speed(char speed) +{ + if (speed == 1) + gpu.step = 2; + else + gpu.step = 4; +} diff --git a/waterbox/pizza/lib/gpu.h b/waterbox/pizza/lib/gpu.h new file mode 100644 index 0000000000..1fd8105d4e --- /dev/null +++ b/waterbox/pizza/lib/gpu.h @@ -0,0 +1,133 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#ifndef __GPU_HDR__ +#define __GPU_HDR__ + +#include +#include + +/* callback function */ +typedef void (*gpu_frame_ready_cb_t) (); + +/* prototypes */ +void gpu_dump_oam(); +void gpu_init(gpu_frame_ready_cb_t cb); +void gpu_reset(); +void gpu_set_speed(char speed); +void gpu_step(); +void gpu_toggle(uint8_t state); +void gpu_write_reg(uint16_t a, uint8_t v); +uint8_t gpu_read_reg(uint16_t a); + + +/* Gameboy LCD Control - R/W accessing 0xFF40 address */ +typedef struct gpu_lcd_ctrl_s +{ + uint8_t bg:1; /* 0 = BG off, 1 = BG on */ + uint8_t sprites:1; /* ??? */ + uint8_t sprites_size:1; /* 0 = 8x8, 1 = 8x16 */ + uint8_t bg_tiles_map:1; /* 0 = 9800-9BFF, 1 = 9C00-9FFF */ + uint8_t bg_tiles:1; /* 0 = 8800-97FF, 1 = 8000-8FFF */ + uint8_t window:1; /* 0 = window off, 1 = on */ + uint8_t window_tiles_map:1; /* 0 = 9800-9BFF, 1 = 9C00-9FFF */ + uint8_t display:1; /* 0 = LCD off, 1 = LCD on */ +} gpu_lcd_ctrl_t; + +/* Gameboy LCD Status - R/W accessing 0xFF41 address */ +typedef struct gpu_lcd_status_s +{ + uint8_t mode:2; + uint8_t ly_coincidence:1; + uint8_t ir_mode_00:1; + uint8_t ir_mode_01:1; + uint8_t ir_mode_10:1; + uint8_t ir_ly_coincidence:1; + uint8_t spare:1; +} gpu_lcd_status_t; + +/* RGB color */ +typedef struct rgb_s +{ + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; +} rgb_t; + +/* Gameboy GPU status */ +typedef struct gpu_s +{ + gpu_lcd_ctrl_t *lcd_ctrl; + gpu_lcd_status_t *lcd_status; + + /* scroll positions */ + uint8_t *scroll_x; + uint8_t *scroll_y; + + /* window position */ + uint8_t *window_x; + uint8_t *window_y; + + /* current scanline and it's compare values */ + uint8_t *ly; + uint8_t *lyc; + + /* clocks counter */ + uint64_t next; + + /* gpu step span */ + uint_fast32_t step; + + /* window last drawn lines */ + uint8_t window_last_ly; + uint8_t window_skipped_lines; + uint16_t spare; + + /* frame counter */ + uint_fast16_t frame_counter; + + /* BG palette */ + uint32_t bg_palette[4]; + + /* Obj palette 0/1 */ + uint32_t obj_palette_0[4]; + uint32_t obj_palette_1[4]; + + /* CGB palette for background */ + uint32_t cgb_palette_bg_rgb888[0x20]; + uint16_t cgb_palette_bg[0x20]; + uint8_t cgb_palette_bg_idx; + uint8_t cgb_palette_bg_autoinc; + + /* CGB palette for sprites */ + uint32_t cgb_palette_oam_rgb888[0x20]; + uint16_t cgb_palette_oam[0x20]; + uint8_t cgb_palette_oam_idx; + uint8_t cgb_palette_oam_autoinc; + + /* frame buffer */ + uint32_t frame_buffer[160 * 144]; + uint8_t priority[160 * 144]; + uint8_t palette_idx[160 * 144]; +} gpu_t; + +extern gpu_t gpu; + +#endif diff --git a/waterbox/pizza/lib/input.c b/waterbox/pizza/lib/input.c new file mode 100644 index 0000000000..4dfde8d5aa --- /dev/null +++ b/waterbox/pizza/lib/input.c @@ -0,0 +1,50 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#include "global.h" +#include "utils.h" + +#include + +/* button states */ +static uint8_t input_keys; + +void input_set_keys(uint8_t keys) +{ + // 7......0 + // DULRSsBA + input_keys = keys & 0xff; +} + +uint8_t input_get_keys(uint8_t line) +{ + uint8_t v = line | 0x0f; + + if ((line & 0x30) == 0x20) + { + v ^= input_keys >> 4; + } + + if ((line & 0x30) == 0x10) + { + v ^= input_keys & 0x0f; + } + + return v | 0xc0; +} diff --git a/waterbox/pizza/lib/input.h b/waterbox/pizza/lib/input.h new file mode 100644 index 0000000000..3f678ea009 --- /dev/null +++ b/waterbox/pizza/lib/input.h @@ -0,0 +1,27 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#ifndef __INPUT_HDR__ +#define __INPUT_HDR__ + +/* prototypes */ +uint8_t input_get_keys(uint8_t line); +void input_set_keys(uint8_t keys); + +#endif diff --git a/waterbox/pizza/lib/interrupt.h b/waterbox/pizza/lib/interrupt.h new file mode 100644 index 0000000000..0fbc4b0873 --- /dev/null +++ b/waterbox/pizza/lib/interrupt.h @@ -0,0 +1,35 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#ifndef __INTERRUPTS_HDR__ +#define __INTERRUPTS_HDR__ + +#include + +typedef struct interrupts_flags_s +{ + uint8_t lcd_vblank:1; + uint8_t lcd_ctrl:1; + uint8_t timer:1; + uint8_t serial_io:1; + uint8_t pins1013:1; + uint8_t spare:3; +} interrupts_flags_t; + +#endif \ No newline at end of file diff --git a/waterbox/pizza/lib/mmu.c b/waterbox/pizza/lib/mmu.c new file mode 100644 index 0000000000..8a8bc9b30b --- /dev/null +++ b/waterbox/pizza/lib/mmu.c @@ -0,0 +1,1029 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#include "cycles.h" +#include "global.h" +#include "gpu.h" +#include "interrupt.h" +#include "input.h" +#include "mmu.h" +#include "sound.h" +#include "serial.h" +#include "timer.h" +#include "utils.h" + +#include +#include +#include +#include +#include "sgb.h" +#include + +/* GAMEBOY MEMORY AREAS + +0x0000 - 0x00FF - BIOS +0x0000 - 0x3FFF - First 16k of game ROM (permanent) +0x4000 - 0x7FFF - ROM banks (switchable) +0x8000 - 0x9FFF - Video RAM (8kb - keeps pixels data) +0xA000 - 0xBFFF - External RAM (switchable, it was on cartridge, + 8kb banks, max 32k, NON volatile) +0xC000 - 0xDFFF - Gameboy RAM +0xE000 - 0xEFFF - ???????????????? +0xFE00 - 0xFF7F - I/O +0xFF80 - 0xFFFE - Temp RAM +0xFFFF - Turn on/off interrupts + +*/ + +/* cartridge memory (max 8MB) */ +uint8_t* cart_memory; + +/* RAM memory area */ +uint8_t *ram; +uint32_t ram_sz; + +/* main struct */ +mmu_t mmu; + +/* function to call when rumble */ +mmu_rumble_cb_t mmu_rumble_cb = NULL; + + +/* return absolute memory address */ +void *mmu_addr(uint16_t a) +{ + return (void *) &mmu.memory[a]; +} + +/* return absolute memory address */ +void *mmu_addr_vram0() +{ + return (void *) &mmu.vram0; +} + +/* return absolute memory address */ +void *mmu_addr_vram1() +{ + return (void *) &mmu.vram1; +} + +/* debug purposes */ +void mmu_dump_all() +{ + int i; + + printf("#### MAIN MEMORY ####\n\n"); + + for (i=0; i<0x10000; i++) + { + if ((i & 0x0f) == 0x00) + printf("\n%04x: ", i); + printf(" %02x", mmu.memory[i]); + } + + if (global_cgb) + { + printf("#### VRAM 0 ####\n\n"); + + for (i=0; i<0x2000; i++) + { + if ((i & 0x0f) == 0x00) + printf("\n%04x: ", i); + printf(" %02x", mmu.vram0[i]); + } + + printf("#### VRAM 1 ####\n\n"); + + for (i=0; i<0x2000; i++) + { + if ((i & 0x0f) == 0x00) + printf("\n%04x: ", i); + printf(" %02x", mmu.vram1[i]); + } + } +} + +/* init (alloc) system state.memory */ +void mmu_init(uint8_t c, uint8_t rn) +{ + mmu.rom_current_bank = 0x01; + mmu.ram_current_bank = 0x00; + + /* set ram to NULL */ + ram = NULL; + + /* save carttype and qty of ROM blocks */ + mmu.carttype = c; + mmu.roms = rn; + + mmu.vram_idx = 0; + mmu.wram_current_bank = 1; + mmu.ram_current_bank = 0; + mmu.ram_external_enabled = 0; + mmu.dma_cycles = 0; + mmu.dma_address = 0; + mmu.rtc_mode = 0; + + /* reset memory */ + bzero(mmu.memory, 65536); +} + +/* init (alloc) system state.memory */ +void mmu_init_ram(uint32_t c) +{ + ram_sz = c; + + ram = malloc(c); + + bzero(ram, c); +} + +/* load data in a certain address */ +void mmu_load(uint8_t *data, size_t sz, uint16_t a) +{ + memcpy(&mmu.memory[a], data, sz); +} + +/* load full cartridge */ +void mmu_load_cartridge(const uint8_t *data, size_t sz) +{ + /* copy max 32k into working memory */ + memcpy(mmu.memory, data, 2 << 14); + + cart_memory = alloc_sealed(1 << 22); + /* copy full cartridge */ + memcpy(cart_memory, data, sz); +} + +/* move 8 bit from s to d */ +void mmu_move(uint16_t d, uint16_t s) +{ + mmu_write(d, mmu_read(s)); +} + +/* read 8 bit data from a memory addres */ +uint8_t mmu_read(uint16_t a) +{ + /* always takes 4 cycles */ + cycles_step(); + + /* 90% of the read is in the ROM area */ + if (a < 0x8000) + return mmu.memory[a]; + + /* test VRAM */ + if (a < 0xA000) + { + if (global_cgb) + { + if (mmu.vram_idx == 0) + return mmu.vram0[a - 0x8000]; + else + return mmu.vram1[a - 0x8000]; + } + + return mmu.memory[a]; + } + + if (a < 0xC000) + { + if (mmu.rtc_mode != 0x00) + { + int64_t diff = mmu.rtc_latch_time - mmu.rtc_time; + + switch (mmu.rtc_mode) + { + case 0x08: + return (diff % 60); + case 0x09: + return ((diff / 60) % 60); + case 0x0A: + return (diff / 3600) % 24; + case 0x0B: + return (diff / (3600 * 24)) & 0x00FF; + case 0x0C: + return ((diff / (3600 * 24)) & 0xFF00) >> 8; + } + } + else + return mmu.memory[a]; + } + + /* RAM */ + if (a < 0xE000) + return mmu.memory[a]; + + /* RAM mirror */ + if (a < 0xFE00) + return mmu.memory[a - 0x2000]; + + switch (a) + { + /* serial registers */ + case 0xFF01: + case 0xFF02: + return serial_read_reg(a); + + /* don't ask me why.... */ + case 0xFF44: + return (mmu.memory[0xFF44] == 153 ? 0 : mmu.memory[0xFF44]); + + /* sound registers */ + case 0xFF10 ... 0xFF3F: + return sound_read_reg(a, mmu.memory[a]); + + /* joypad reading */ + case 0xFF00: + global_lagged = 0; + if (global_input_callback) + global_input_callback(); + return global_sgb ? sgb_read_ff00(cycles.sampleclock) : input_get_keys(mmu.memory[a]); + + /* CGB HDMA transfer */ + case 0xFF55: + + if (!global_cgb) break; + + /* HDMA result */ + if (mmu.hdma_to_transfer) + return (mmu.hdma_to_transfer / 0x10 - 0x01); + else + return 0xFF; + + /* CGB color palette registers */ + case 0xFF68: + case 0xFF69: + case 0xFF6A: + case 0xFF6B: + + if (!global_cgb) break; + + /* color palettes registers */ + return gpu_read_reg(a); + + /* timer registers */ + case 0xFF04 ... 0xFF07: + return timer_read_reg(a); + + } + + return mmu.memory[a]; +} + +/* read 16 bit data from a memory addres */ +unsigned int mmu_read_16(uint16_t a) +{ + return (mmu_read(a) | (mmu_read(a + 1) << 8)); +} + +/* read 8 bit data from a memory addres (not affecting cycles) */ +uint8_t mmu_read_no_cyc(uint16_t a) +{ + if (a >= 0xE000 && a <= 0xFDFF) + return mmu.memory[a - 0x2000]; + + return mmu.memory[a]; +} + +static int has_saveram(void) +{ + return mmu.carttype == 0x03 || + mmu.carttype == 0x06 || + mmu.carttype == 0x09 || + mmu.carttype == 0x0D || + mmu.carttype == 0x0F || + mmu.carttype == 0x10 || + mmu.carttype == 0x13 || + mmu.carttype == 0x17 || + mmu.carttype == 0x1B || + mmu.carttype == 0x1E || + mmu.carttype == 0x22 || + mmu.carttype == 0xFF; +} + +int mmu_saveram_size(void) +{ + return has_saveram() ? ram_sz : 0; +} + +void mmu_restore_saveram(const uint8_t* data, int sz) +{ + if (sz == mmu_saveram_size()) + { + if (ram_sz <= 0x2000) + { + memcpy(&mmu.memory[0xa000], data, ram_sz); + } + else + { + memcpy(ram, data, ram_sz); + if (mmu.ram_external_enabled) + memcpy(&mmu.memory[0xa000], &ram[0x2000 * mmu.ram_current_bank], 0x2000); + } + } +} + +void mmu_save_saveram(uint8_t* dest, int sz) +{ + if (sz == mmu_saveram_size()) + { + if (ram_sz <= 0x2000) + { + memcpy(dest, &mmu.memory[0xa000], ram_sz); + } + else + { + memcpy(dest, ram, ram_sz); + if (mmu.ram_external_enabled) + memcpy(&dest[0x2000 * mmu.ram_current_bank], &mmu.memory[0xa000], 0x2000); + } + } +} + +void mmu_set_rumble_cb(mmu_rumble_cb_t cb) +{ + mmu_rumble_cb = cb; +} + +/* write 16 bit block on a memory address */ +void mmu_write(uint16_t a, uint8_t v) +{ + /* update cycles AFTER memory set */ + cycles_step(); + + /* color gameboy stuff */ + if (global_cgb) + { + /* VRAM write? */ + if (a >= 0x8000 && a < 0xA000) + { + if (mmu.vram_idx == 0) + mmu.vram0[a - 0x8000] = v; + else + mmu.vram1[a - 0x8000] = v; + + return; + } + else + { + /* wanna access to RTC register? */ + if (a >= 0xA000 && a <= 0xBFFF && mmu.rtc_mode != 0x00) + { + int64_t t,s1,s2,m1,m2,h1,h2,d1,d2,days; + + t = global_currenttime; + + /* extract parts in seconds from current and ref times */ + s1 = t % 60; + s2 = mmu.rtc_time % 60; + + m1 = (t - s1) % (60 * 60); + m2 = (mmu.rtc_time - s2) % (60 * 60); + + h1 = (t - m1 - s1) % (60 * 60 * 24); + h2 = (mmu.rtc_time - m2 - s2) % (60 * 60 * 24); + + d1 = t - h1 - m1 - s1; + d2 = mmu.rtc_time - h2 - m2 - s2; + + switch (mmu.rtc_mode) + { + case 0x08: + + /* remove seconds from current time */ + mmu.rtc_time -= s2; + + /* set new seconds */ + mmu.rtc_time += (s1 - v); + + return; + + case 0x09: + + /* remove seconds from current time */ + mmu.rtc_time -= m2; + + /* set new seconds */ + mmu.rtc_time += (m1 - (v * 60)); + + return; + + case 0x0A: + + /* remove seconds from current time */ + mmu.rtc_time -= h2; + + /* set new seconds */ + mmu.rtc_time += (h1 - (v * 60 * 24)); + + return; + + case 0x0B: + + days = (((d1 - d2) / + (60 * 60 * 24)) & 0xFF00) | v; + + /* remove seconds from current time */ + mmu.rtc_time -= d2; + + /* set new seconds */ + mmu.rtc_time += (d1 - (days * 60 * 60 * 24)); + + return; + + case 0x0C: + + days = (((d1 - d2) / + (60 * 60 * 24)) & 0xFEFF) | (v << 8); + + /* remove seconds from current time */ + mmu.rtc_time -= d2; + + /* set new seconds */ + mmu.rtc_time += (d1 - (days * 60 * 60 * 24)); + + return; + } + } + } + + /* switch WRAM */ + if (a == 0xFF70) + { + /* number goes from 1 to 7 */ + uint8_t new = (v & 0x07); + + if (new == 0) + new = 1; + + if (new == mmu.wram_current_bank) + return; + + /* save current bank */ + memcpy(&mmu.wram[0x1000 * mmu.wram_current_bank], + &mmu.memory[0xD000], 0x1000); + + mmu.wram_current_bank = new; + + /* move new ram bank */ + memcpy(&mmu.memory[0xD000], + &mmu.wram[0x1000 * mmu.wram_current_bank], + 0x1000); + + /* save current bank */ + mmu.memory[0xFF70] = new; + + return; + } + + if (a == 0xFF4F) + { + /* extract VRAM index from last bit */ + mmu.vram_idx = (v & 0x01); + + /* save current VRAM bank */ + mmu.memory[0xFF4F] = mmu.vram_idx; + + return; + } + } + + /* wanna write on ROM? */ + if (a < 0x8000) + { + /* return in case of ONLY ROM */ + if (mmu.carttype == 0x00) + return; + + /* TODO - MBC strategies */ + uint8_t b = mmu.rom_current_bank; + + switch (mmu.carttype) + { + /* MBC1 */ + case 0x01: + case 0x02: + case 0x03: + + if (a >= 0x2000 && a <= 0x3FFF) + { + /* reset 5 bits */ + b = mmu.rom_current_bank & 0xE0; + + /* set them with new value */ + b |= v & 0x1F; + + /* doesn't fit on max rom number? */ + if (b > (2 << mmu.roms)) + { + /* filter result to get a value < max rom number */ + b %= (2 << mmu.roms); + } + + /* 0x00 is not valid, switch it to 0x01 */ + if (b == 0x00) + b = 0x01; + } + else if (a >= 0x4000 && a <= 0x5FFF) + { + /* ROM banking? it's about 2 higher bits */ + if (mmu.banking == 0) + { + /* reset 5 bits */ + b = mmu.rom_current_bank & 0x1F; + + /* set them with new value */ + b |= (v << 5); + + /* doesn't fit on max rom number? */ + if (b > (2 << mmu.roms)) + { + /* filter result to get a value < max rom number */ + b %= (2 << mmu.roms); + } + } + else + { + if ((0x2000 * v) < ram_sz) + { + /* save current bank */ + memcpy(&ram[0x2000 * mmu.ram_current_bank], + &mmu.memory[0xA000], 0x2000); + + mmu.ram_current_bank = v; + + /* move new ram bank */ + memcpy(&mmu.memory[0xA000], + &ram[0x2000 * mmu.ram_current_bank], + 0x2000); + } + } + } + else if (a >= 0x6000 && a <= 0x7FFF) + mmu.banking = v; + + break; + + /* MBC2 */ + case 0x05: + case 0x06: + + if (a >= 0x2000 && a <= 0x3FFF) + { + /* use lower nibble to set current bank */ + b = v & 0x0f; + + /*if (b != rom_current_bank) + memcpy(&memory[0x4000], + &cart_memory[b * 0x4000], 0x4000); + + rom_current_bank = b;*/ + } + + break; + + /* MBC3 */ + case 0x10: + case 0x13: + + if (a >= 0x0000 && a <= 0x1FFF) + { + if (v == 0x0A) + { + /* already enabled? */ + if (mmu.ram_external_enabled) + return; + + /* restore external ram bank */ + memcpy(&mmu.memory[0xA000], + &ram[0x2000 * mmu.ram_current_bank], + 0x2000); + + /* set external RAM eanbled flag */ + mmu.ram_external_enabled = 1; + + return; + } + + if (v == 0x00) + { + /* already disabled? */ + if (mmu.ram_external_enabled == 0) + return; + + /* save current bank */ + memcpy(&ram[0x2000 * mmu.ram_current_bank], + &mmu.memory[0xA000], 0x2000); + + /* clear external RAM eanbled flag */ + mmu.ram_external_enabled = 0; + } + } + else if (a >= 0x2000 && a <= 0x3FFF) + { + /* set them with new value */ + b = v & 0x7F; + + /* doesn't fit on max rom number? */ + if (b > (2 << mmu.roms)) + { + /* filter result to get a value < max rom number */ + b %= (2 << mmu.roms); + } + + /* 0x00 is not valid, switch it to 0x01 */ + if (b == 0x00) + b = 0x01; + } + else if (a >= 0x4000 && a <= 0x5FFF) + { + /* 0x00 to 0x07 is referred to RAM bank */ + if (v < 0x08) + { + /* not on RTC mode anymore */ + mmu.rtc_mode = 0x00; + + if ((0x2000 * (v & 0x0f)) < ram_sz) + { + /* save current bank */ + memcpy(&ram[0x2000 * mmu.ram_current_bank], + &mmu.memory[0xA000], 0x2000); + + mmu.ram_current_bank = v & 0x0f; + + /* move new ram bank */ + memcpy(&mmu.memory[0xA000], + &ram[0x2000 * mmu.ram_current_bank], + 0x2000); + } + } + else if (v < 0x0d) + { + /* from 0x08 to 0x0C trigger RTC mode */ + mmu.rtc_mode = v; + } + + } + else if (a >= 0x6000 && a <= 0x7FFF) + { + /* latch clock data. move clock data to RTC registers */ + mmu.rtc_latch_time = global_currenttime; + } + + + break; + + /* MBC5 */ + case 0x19: + case 0x1A: + case 0x1B: + case 0x1C: + case 0x1D: + case 0x1E: + + if (a >= 0x0000 && a <= 0x1FFF) + { + if (v == 0x0A) + { + /* we got external RAM? some stupid game try */ + /* to access it despite it doesn't have it */ + if (ram_sz == 0) + return; + + /* already enabled? */ + if (mmu.ram_external_enabled) + return; + + /* restore external ram bank */ + memcpy(&mmu.memory[0xA000], + &ram[0x2000 * mmu.ram_current_bank], + 0x2000); + + /* set external RAM eanbled flag */ + mmu.ram_external_enabled = 1; + + return; + } + + if (v == 0x00) + { + /* we got external RAM? some stpd game try to do shit */ + if (ram_sz == 0) + return; + + /* already disabled? */ + if (mmu.ram_external_enabled == 0) + return; + + /* save current bank */ + memcpy(&ram[0x2000 * mmu.ram_current_bank], + &mmu.memory[0xA000], 0x2000); + + /* clear external RAM eanbled flag */ + mmu.ram_external_enabled = 0; + } + } + if (a >= 0x2000 && a <= 0x2FFF) + { + /* set them with new value */ + b = (mmu.rom_current_bank & 0xFF00) | v; + + /* doesn't fit on max rom number? */ + if (b > (2 << mmu.roms)) + { + /* filter result to get a value < max rom number */ + b %= (2 << mmu.roms); + } + } + else if (a >= 0x3000 && a <= 0x3FFF) + { + /* set them with new value */ + b = (mmu.rom_current_bank & 0x00FF) | ((v & 0x01) << 8); + + /* doesn't fit on max rom number? */ + if (b > (2 << mmu.roms)) + { + /* filter result to get a value < max rom number */ + b %= (2 << mmu.roms); + } + } + else if (a >= 0x4000 && a <= 0x5FFF) + { + uint8_t mask = 0x0F; + + if (global_rumble) + { + mask = 0x07; + + if (mmu_rumble_cb) + (*mmu_rumble_cb) ((v & 0x08) ? 1 : 0); + + /* check if we want to appizz the motor */ +/* if (v & 0x08) + printf("APPIZZ MOTOR\n"); + else + printf("SPEGN MOTOR\n");*/ + } + + if ((0x2000 * (v & mask)) < ram_sz) + { + /* is externa RAM enabled? */ + if (!mmu.ram_external_enabled) + break; + + /* wanna switch on the same bank? =\ just discard it */ + if ((v & 0x0f) == mmu.ram_current_bank) + break; + + /* save current bank */ + memcpy(&ram[0x2000 * mmu.ram_current_bank], + &mmu.memory[0xA000], 0x2000); + + mmu.ram_current_bank = (v & 0x0f); + + /* move new ram bank */ + memcpy(&mmu.memory[0xA000], + &ram[0x2000 * mmu.ram_current_bank], + 0x2000); + } + } + + break; + + } + + /* need to switch? */ + if (b != mmu.rom_current_bank) + { + /* copy from cartridge rom to GB switchable bank area */ + memcpy(&mmu.memory[0x4000], &cart_memory[b * 0x4000], 0x4000); + + /* save new current bank */ + mmu.rom_current_bank = b; + } + + return; + } + + if (a >= 0xE000) + { + /* changes on sound registers? */ + if (a >= 0xFF10 && a <= 0xFF3F) + { + /* set memory */ + sound_write_reg(a, v); + + return; + } + + /* mirror area */ + if (a >= 0xE000 && a <= 0xFDFF) + { + mmu.memory[a - 0x2000] = v; + return; + } + + /* TODO - put them all */ + switch(a) + { + case 0xFF00: + sgb_write_ff00(v, cycles.sampleclock); + break; + case 0xFF01: + case 0xFF02: + serial_write_reg(a, v); + return; + case 0xFF04 ... 0xFF07: + timer_write_reg(a, v); + return; + } + + /* LCD turned on/off? */ + if (a == 0xFF40) + { + if ((v ^ mmu.memory[0xFF40]) & 0x80) + gpu_toggle(v); + } + + /* only 5 high bits are writable */ + if (a == 0xFF41) + { + mmu.memory[a] = (mmu.memory[a] & 0x07) | (v & 0xf8); + return; + } + + /* palette update */ + if ((a >= 0xFF47 && a <= 0xFF49) || + (a >= 0xFF68 && a <= 0xFF6B)) + gpu_write_reg(a, v); + + /* CGB only registers */ + if (global_cgb) + { + switch (a) + { + case 0xFF4D: + + /* wanna switch speed? */ + if (v & 0x01) + { + global_cpu_double_speed ^= 0x01; + + /* update new clock */ + // cycles_clock = 4194304 << global_double_speed; + cycles_set_speed(1); + sound_set_speed(1); + gpu_set_speed(1); + + /* save into memory i'm working at double speed */ + if (global_cpu_double_speed) + mmu.memory[a] = 0x80; + else + mmu.memory[a] = 0x00; + } + + return; + + case 0xFF52: + + /* high byte of HDMA source address */ + mmu.hdma_src_address &= 0xff00; + + /* lower 4 bits are ignored */ + mmu.hdma_src_address |= (v & 0xf0); + + break; + + case 0xFF51: + + /* low byte of HDMA source address */ + mmu.hdma_src_address &= 0x00ff; + + /* highet 3 bits are ignored (always 100 binary) */ + mmu.hdma_src_address |= (v << 8); + + break; + + case 0xFF54: + + /* high byte of HDMA source address */ + mmu.hdma_dst_address &= 0xff00; + + /* lower 4 bits are ignored */ + mmu.hdma_dst_address |= (v & 0xf0); + + break; + + case 0xFF53: + + /* low byte of HDMA source address */ + mmu.hdma_dst_address &= 0x00ff; + + /* highet 3 bits are ignored (always 100 binary) */ + mmu.hdma_dst_address |= ((v & 0x1f) | 0x80) << 8; + + break; + + case 0xFF55: + + /* wanna stop HBLANK transfer? a zero on 7th bit will do */ + if ((v & 0x80) == 0 && + mmu.hdma_transfer_mode == 0x01 && + mmu.hdma_to_transfer) + { + mmu.hdma_to_transfer = 0x00; + mmu.hdma_transfer_mode = 0x00; + + return; + } + + /* general (0) or hblank (1) ? */ + mmu.hdma_transfer_mode = ((v & 0x80) ? 1 : 0); + + /* calc how many bytes gotta be transferred */ + uint16_t to_transfer = ((v & 0x7f) + 1) * 0x10; + + /* general must be done immediately */ + if (mmu.hdma_transfer_mode == 0) + { + /* copy right now */ + if (mmu.vram_idx) + memcpy(mmu_addr_vram1() + + (mmu.hdma_dst_address - 0x8000), + &mmu.memory[mmu.hdma_src_address], + to_transfer); + else + memcpy(mmu_addr_vram0() + + (mmu.hdma_dst_address - 0x8000), + &mmu.memory[mmu.hdma_src_address], + to_transfer); + + /* reset to_transfer var */ + mmu.hdma_to_transfer = 0; + + /* move forward src and dst addresses =| */ + mmu.hdma_src_address += to_transfer; + mmu.hdma_dst_address += to_transfer; + } + else + { + mmu.hdma_to_transfer = to_transfer; + + /* check if we're already into hblank phase */ + cycles_hdma(); + } + + break; + } + } + + /* finally set memory byte with data */ + mmu.memory[a] = v; + + /* DMA access */ + if (a == 0xFF46) + { + /* calc source address */ + mmu.dma_address = v * 256; + + /* initialize counter, DMA needs 672 ticks */ + mmu.dma_next = cycles.cnt + 4; // 168 / 2; + } + } + else + mmu.memory[a] = v; +} + +/* write 16 bit block on a memory address */ +void mmu_write_16(uint16_t a, uint16_t v) +{ + mmu.memory[a] = (uint8_t) (v & 0x00ff); + mmu.memory[a + 1] = (uint8_t) (v >> 8); + + /* 16 bit write = +8 cycles */ + cycles_step(); + cycles_step(); +} + + +/* write 16 bit block on a memory address (no cycles affected) */ +void mmu_write_no_cyc(uint16_t a, uint8_t v) +{ + mmu.memory[a] = v; +} diff --git a/waterbox/pizza/lib/mmu.h b/waterbox/pizza/lib/mmu.h new file mode 100644 index 0000000000..cc36b8e0cc --- /dev/null +++ b/waterbox/pizza/lib/mmu.h @@ -0,0 +1,112 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#ifndef __MMU_HDR__ +#define __MMU_HDR__ + +#include +#include + +typedef struct mmu_s +{ + /* main 64K of memory */ + uint8_t memory[65536]; + + /* vram in standby */ + uint8_t vram0[0x2000]; + uint8_t vram1[0x2000]; + + /* vram current idx */ + uint8_t vram_idx; + uint8_t spare; + uint16_t spare2; + + // cartridge RAM + uint8_t ram_external_enabled; + uint8_t ram_current_bank; + + /* cartridge type */ + uint8_t carttype; + + /* number of switchable roms */ + uint8_t roms; + + /* current ROM bank */ + uint8_t rom_current_bank; + + /* type of banking */ + uint8_t banking; + + /* working RAM (only CGB) */ + uint8_t wram[0x8000]; + + /* current WRAM bank (only CGB) */ + uint8_t wram_current_bank; + uint8_t spare3; + uint16_t spare4; + + /* DMA transfer stuff */ + uint_fast16_t dma_address; + uint_fast16_t dma_cycles; + + /* HDMA transfer stuff */ + uint16_t hdma_src_address; + uint16_t hdma_dst_address; + uint16_t hdma_to_transfer; + uint8_t hdma_transfer_mode; + uint8_t hdma_current_line; + + /* RTC stuff */ + uint8_t rtc_mode; + int64_t rtc_time; + int64_t rtc_latch_time; + + uint64_t dma_next; +} mmu_t; + +extern mmu_t mmu; + +/* callback function */ +typedef void (*mmu_rumble_cb_t)(uint8_t onoff); + +/* functions prototypes */ +void *mmu_addr(uint16_t a); +void *mmu_addr_vram0(); +void *mmu_addr_vram1(); +void mmu_dump_all(); +void mmu_init(uint8_t c, uint8_t rn); +void mmu_init_ram(uint32_t c); +void mmu_load(uint8_t *data, size_t sz, uint16_t a); +void mmu_load_cartridge(const uint8_t *data, size_t sz); +void mmu_move(uint16_t d, uint16_t s); +uint8_t mmu_read_no_cyc(uint16_t a); +uint8_t mmu_read(uint16_t a); +unsigned int mmu_read_16(uint16_t a); +int mmu_saveram_size(void); +void mmu_restore_saveram(const uint8_t *data, int sz); +void mmu_save_saveram(uint8_t *dest, int sz); +void mmu_restore_rtc(char *fn); +void mmu_save_rtc(char *fn); +void mmu_set_rumble_cb(mmu_rumble_cb_t cb); +void mmu_step(); +void mmu_write_no_cyc(uint16_t a, uint8_t v); +void mmu_write(uint16_t a, uint8_t v); +void mmu_write_16(uint16_t a, uint16_t v); + +#endif diff --git a/waterbox/pizza/lib/serial.c b/waterbox/pizza/lib/serial.c new file mode 100644 index 0000000000..497d8a65c1 --- /dev/null +++ b/waterbox/pizza/lib/serial.c @@ -0,0 +1,192 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#include "cycles.h" +#include "interrupt.h" +#include "mmu.h" +#include "serial.h" +#include "utils.h" + +/* main variable */ +serial_t serial; + +/* function to call when frame is ready */ +serial_data_send_cb_t serial_data_send_cb; + +interrupts_flags_t *serial_if; + +/* second message before the first was handled? */ +uint8_t serial_second_set = 0; +uint8_t serial_second_data = 0; +uint8_t serial_second_clock = 0; +uint8_t serial_second_transfer_start = 0; +uint8_t serial_waiting_data = 0; + +void serial_verify_intr() +{ + if (serial.data_recv && serial.data_sent) + { + serial.data_recv = 0; + serial.data_sent = 0; + + /* valid couple of messages for a serial interrupt? */ + if ((serial.data_recv_clock != serial.data_sent_clock) && + serial.data_recv_transfer_start && + serial.data_sent_transfer_start) + { + /* put received data into 0xFF01 (serial.data) */ + /* and notify with an interrupt */ + serial.transfer_start = 0; + serial.data = serial.data_to_recv; + + serial_if->serial_io = 1; + } + + /* a message is already on queue? */ + if (serial_second_set) + { + serial_second_set = 0; + serial.data_recv = 1; + serial.data_to_recv = serial_second_data; + serial.data_recv_clock = serial_second_clock; + serial.data_recv_transfer_start = serial_second_transfer_start; + } + } +} + +void serial_init() +{ + /* pointer to interrupt flags */ + serial_if = mmu_addr(0xFF0F); + + /* init counters */ + serial.bits_sent = 0; + + /* start as not connected */ + serial.peer_connected = 0; +} + +void serial_write_reg(uint16_t a, uint8_t v) +{ + switch (a) + { + case 0xFF01: + serial.data = v; + return; + case 0xFF02: + serial.clock = v & 0x01; + serial.speed = (v & 0x02) ? 0x01 : 0x00; + serial.spare = ((v >> 2) & 0x1F); + serial.transfer_start = (v & 0x80) ? 0x01 : 0x00; + + /* reset? */ + serial.data_sent = 0; + break; + } + + if (serial.transfer_start && + !serial.peer_connected && + serial.clock) + { + if (serial.speed) + serial.next = cycles.cnt + 8 * 8; + else + serial.next = cycles.cnt + 256 * 8; + } +} + +uint8_t serial_read_reg(uint16_t a) +{ + uint8_t v = 0xFF; + + switch (a) + { + case 0xFF01: v = serial.data; break; + case 0xFF02: v = ((serial.clock) ? 0x01 : 0x00) | + ((serial.speed) ? 0x02 : 0x00) | + (serial.spare << 2) | + ((serial.transfer_start) ? 0x80 : 0x00); + } + + return v; +} + +void serial_recv_byte(uint8_t v, uint8_t clock, uint8_t transfer_start) +{ + /* second message during same span time? */ + if (serial.data_recv) + { + /* store it. handle it later */ + serial_second_set = 1; + serial_second_data = v; + serial_second_clock = clock; + serial_second_transfer_start = transfer_start; + return; + } + + /* received side OK */ + serial.data_recv = 1; + serial.data_recv_clock = clock; + serial.data_to_recv = v; + serial.data_recv_transfer_start = transfer_start; + + /* notify main thread in case it's waiting */ + //if (serial_waiting_data) + //pthread_cond_signal(&serial_cond); +} + +void serial_send_byte() +{ + serial.data_sent = 1; + serial.data_to_send = serial.data; + serial.data_sent_clock = serial.clock; + serial.data_sent_transfer_start = serial.transfer_start; + + if (serial_data_send_cb) + (*serial_data_send_cb) (serial.data, serial.clock, + serial.transfer_start); +} + +void serial_set_send_cb(serial_data_send_cb_t cb) +{ + serial_data_send_cb = cb; +} + +void serial_wait_data() +{ + if (serial.data_sent && serial.data_recv == 0) + { + /* wait max 3 seconds */ + //struct timespec wait; + + //wait.tv_sec = time(NULL) + 3; + + /* this is very important to avoid EINVAL return! */ + //wait.tv_nsec = 0; + + /* declare i'm waiting for data */ + //serial_waiting_data = 1; + + /* notify something has arrived */ + // pthread_cond_timedwait(&serial_cond, &serial_mutex, &wait); + + /* not waiting anymore */ + //serial_waiting_data = 0; + } +} diff --git a/waterbox/pizza/lib/serial.h b/waterbox/pizza/lib/serial.h new file mode 100644 index 0000000000..d4cfb918eb --- /dev/null +++ b/waterbox/pizza/lib/serial.h @@ -0,0 +1,92 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#ifndef __SERIAL_HDR__ +#define __SERIAL_HDR__ + +#include +#include + +typedef struct serial_ctrl_s +{ + uint8_t clock; + uint8_t speed; + uint8_t spare; + uint8_t transfer_start; +} serial_ctrl_t; + +typedef struct serial_s { + + /* pointer to serial controller register */ + // serial_ctrl_t ctrl; + + uint8_t clock; + uint8_t speed; + uint8_t spare; + uint8_t transfer_start; + + /* pointer to FF01 data */ + uint8_t data; + + /* sent bits */ + uint8_t bits_sent; + + /* data to send */ + uint8_t data_to_send; + + /* peer clock */ + uint8_t data_to_recv; + + /* counter */ + uint64_t next; + + /* peer connected? */ + uint8_t peer_connected:1; + uint8_t data_sent:1; + uint8_t data_sent_clock:1; + uint8_t data_sent_transfer_start:1; + uint8_t data_recv:1; + uint8_t data_recv_clock:1; + uint8_t data_recv_transfer_start:1; + uint8_t spare10:1; + + uint_fast32_t last_send_cnt; + +} serial_t; + +extern serial_t serial; + +/* callback when receive something on serial */ +typedef void (*serial_data_send_cb_t) (uint8_t v, uint8_t clock, + uint8_t transfer_start); + +/* prototypes */ +void serial_init(); +void serial_lock(); +void serial_write_reg(uint16_t a, uint8_t v); +void serial_verify_intr(); +uint8_t serial_read_reg(uint16_t a); +void serial_recv_byte(uint8_t v, uint8_t clock, uint8_t transfer_start); +void serial_recv_clock(); +void serial_send_byte(); +void serial_set_send_cb(serial_data_send_cb_t cb); +void serial_unlock(); +void serial_wait_data(); + +#endif diff --git a/waterbox/pizza/lib/sgb.c b/waterbox/pizza/lib/sgb.c new file mode 100644 index 0000000000..a006431c78 --- /dev/null +++ b/waterbox/pizza/lib/sgb.c @@ -0,0 +1,997 @@ +#include "sgb.h" +#include "utils.h" +#include +#include +#include "snes_spc/spc.h" + +const uint8_t iplrom[64] = { + /*ffc0*/ 0xcd, 0xef, //mov x,#$ef + /*ffc2*/ 0xbd, //mov sp,x + /*ffc3*/ 0xe8, 0x00, //mov a,#$00 + /*ffc5*/ 0xc6, //mov (x),a + /*ffc6*/ 0x1d, //dec x + /*ffc7*/ 0xd0, 0xfc, //bne $ffc5 + /*ffc9*/ 0x8f, 0xaa, 0xf4, //mov $f4,#$aa + /*ffcc*/ 0x8f, 0xbb, 0xf5, //mov $f5,#$bb + /*ffcf*/ 0x78, 0xcc, 0xf4, //cmp $f4,#$cc + /*ffd2*/ 0xd0, 0xfb, //bne $ffcf + /*ffd4*/ 0x2f, 0x19, //bra $ffef + /*ffd6*/ 0xeb, 0xf4, //mov y,$f4 + /*ffd8*/ 0xd0, 0xfc, //bne $ffd6 + /*ffda*/ 0x7e, 0xf4, //cmp y,$f4 + /*ffdc*/ 0xd0, 0x0b, //bne $ffe9 + /*ffde*/ 0xe4, 0xf5, //mov a,$f5 + /*ffe0*/ 0xcb, 0xf4, //mov $f4,y + /*ffe2*/ 0xd7, 0x00, //mov ($00)+y,a + /*ffe4*/ 0xfc, //inc y + /*ffe5*/ 0xd0, 0xf3, //bne $ffda + /*ffe7*/ 0xab, 0x01, //inc $01 + /*ffe9*/ 0x10, 0xef, //bpl $ffda + /*ffeb*/ 0x7e, 0xf4, //cmp y,$f4 + /*ffed*/ 0x10, 0xeb, //bpl $ffda + /*ffef*/ 0xba, 0xf6, //movw ya,$f6 + /*fff1*/ 0xda, 0x00, //movw $00,ya + /*fff3*/ 0xba, 0xf4, //movw ya,$f4 + /*fff5*/ 0xc4, 0xf4, //mov $f4,a + /*fff7*/ 0xdd, //mov a,y + /*fff8*/ 0x5d, //mov x,a + /*fff9*/ 0xd0, 0xdb, //bne $ffd6 + /*fffb*/ 0x1f, 0x00, 0x00, //jmp ($0000+x) + /*fffe*/ 0xc0, 0xff //reset vector location ($ffc0) +}; + +// the "reference clock" is tied to the GB cpu. 35112 of these should equal one GB LCD frame. +// it is always increasing and never resets/rebases + +const int refclocks_per_spc_sample = 67; // ~32055hz + +typedef struct +{ + // writes to FF00 + uint64_t last_write_time; // last write time relative to reference clock + uint8_t last_write_value; + + // recv packets + uint8_t read_index; // 0-127, index of the next bit read. if 255, not currently reading + uint8_t packet[16]; // a packet in the process of being formed + + uint8_t command[16 * 7]; // a command in the process of being formed + uint8_t expected_packets; // total number of packets expected for a command + uint8_t next_packet; // index of the next packet to be read + + // joypad reading + uint8_t joypad_index; // index of currently reading joypad + uint8_t num_joypads; // number of currently selected joypads (MLT_REQ) + uint8_t joypad_data[4]; // data for each joypad + uint8_t joypad_has_been_read; // state for advancing joypad_index. extermely weird; logic lifted from VBA and probably wrong + + // palettes + uint32_t palette[8][16]; + uint32_t auxpalette[512][4]; + + // border + uint8_t tiles[256][64]; // tiles stored in packed form + uint16_t tilemap[32 * 32]; + + // frame data + uint8_t frame[160 * 144]; // the most recent obtained full frame + uint8_t frozenframe[160 * 144]; // the most recent saved full frame (MASK_EN) + uint8_t attr[20 * 18]; // current attr map for the GB screen + uint8_t auxattr[45][20 * 18]; // 45 attr files + + // MASK_EN + uint8_t active_mask; // true if mask is currently being used + + // audio + SNES_SPC *spc; + uint64_t frame_start; // when the current audio frame started relative to reference clock + uint32_t clock_remainder; // number of reference clocks not sent to the SPC last frame + uint8_t sound_control[4]; // TODO... + + // transfers + uint32_t waiting_transfer; +#define TRN_NONE 0 +#define TRN_SOUND 1 +#define TRN_PAL 2 +#define TRN_CHR_LOW 3 +#define TRN_CHR_HI 4 +#define TRN_PCT 5 +#define TRN_ATTR 6 + int32_t transfer_countdown; // number of frames until transfer. not entirely accurate +} sgb_t; + +static sgb_t sgb; + +static uint32_t makecol(uint16_t c) +{ + return c >> 7 & 0xf8 | c >> 12 & 0x07 | c << 6 & 0xf800 | c << 1 & 0x0700 | c << 19 & 0xf80000 | c << 14 & 0x070000 | 0xff000000; +} + +static void cmd_trn(uint32_t which) +{ + if ((sgb.command[0] & 7) == 1) + { + if (sgb.waiting_transfer == TRN_NONE) + { + sgb.waiting_transfer = which; + sgb.transfer_countdown = 4; + } + else + { + utils_log("SGB: TRN already queued!"); + } + } + else + { + utils_log("SGB: cmd_trn bad length"); + } +} + +static void cmd_pal(int a, int b) +{ + if ((sgb.command[0] & 7) == 1) + { + uint32_t c[7]; + for (int i = 0; i < 7; i++) + c[i] = makecol(sgb.command[i * 2 + 1] | sgb.command[i * 2 + 2] << 8); + sgb.palette[0][0] = c[0]; + sgb.palette[1][0] = c[0]; + sgb.palette[2][0] = c[0]; + sgb.palette[3][0] = c[0]; + sgb.palette[a][1] = c[1]; + sgb.palette[a][2] = c[2]; + sgb.palette[a][3] = c[3]; + sgb.palette[b][1] = c[4]; + sgb.palette[b][2] = c[5]; + sgb.palette[b][3] = c[6]; + } + else + { + utils_log("SGB: cmd_pal bad length"); + } +} + +static void cmd_pal_set(void) +{ + if ((sgb.command[0] & 7) == 1) + { + int p0 = sgb.command[1] | sgb.command[2] << 8 & 0x100; + for (int i = 0; i < 4; i++) + { + int p = sgb.command[i * 2 + 1] | sgb.command[i * 2 + 2] << 8 & 0x100; + sgb.palette[i][0] = sgb.auxpalette[p0][0]; + sgb.palette[i][1] = sgb.auxpalette[p][1]; + sgb.palette[i][2] = sgb.auxpalette[p][2]; + sgb.palette[i][3] = sgb.auxpalette[p][3]; + } + if (sgb.command[9] & 0x80) // change attribute + { + int attr = sgb.command[9] & 0x3f; + if (attr >= 45) + attr = 44; + memcpy(sgb.attr, sgb.auxattr[attr], sizeof(sgb.attr)); + } + if (sgb.command[9] & 0x40) // cancel mask + { + sgb.active_mask = 0; + } + } + else + { + utils_log("SGB: cmd_pal bad length"); + } +} + +static void cmd_attr_blk() +{ + int nset = sgb.command[1]; + if (nset <= 0 || nset >= 19) + { + utils_log("SGB: cmd_attr_blk bad nset"); + return; + } + int npacket = (nset * 6 + 16) / 16; + if ((sgb.command[0] & 7) != npacket) + { + utils_log("SGB: cmd_attr_blk bad length"); + return; + } + for (int i = 0; i < nset; i++) + { + int ctrl = sgb.command[i * 6 + 2] & 7; + int pals = sgb.command[i * 6 + 3]; + int x1 = sgb.command[i * 6 + 4]; + int y1 = sgb.command[i * 6 + 5]; + int x2 = sgb.command[i * 6 + 6]; + int y2 = sgb.command[i * 6 + 7]; + int inside = ctrl & 1; + int line = ctrl & 2; + int outside = ctrl & 4; + int insidepal = pals & 3; + int linepal = pals >> 2 & 3; + int outsidepal = pals >> 4 & 3; + if (ctrl == 1) + { + ctrl = 3; + linepal = insidepal; + } + else if (ctrl == 4) + { + ctrl = 6; + linepal = outsidepal; + } + uint8_t *dst = sgb.attr; + for (int y = 0; y < 18; y++) + { + for (int x = 0; x < 20; x++) + { + if (outside && (x < x1 || x > x2 || y < y1 || y > y2)) + *dst = outsidepal; + else if (inside && x > x1 && x < x2 && y > y1 && y < y2) + *dst = insidepal; + else if (line) + *dst = linepal; + dst++; + } + } + } +} + +static void cmd_attr_lin() +{ + int nset = sgb.command[1]; + if (nset <= 0 || nset >= 111) + { + utils_log("SGB: cmd_attr_lin bad nset"); + return; + } + int npacket = (nset + 17) / 16; + if ((sgb.command[0] & 7) != npacket) + { + utils_log("SGB: cmd_attr_lin bad length"); + return; + } + for (int i = 0; i < nset; i++) + { + uint8_t v = sgb.command[i + 2]; + int line = v & 31; + int a = v >> 5 & 3; + if (v & 0x80) // horizontal + { + if (line > 17) + line = 17; + memset(sgb.attr + line * 20, a, 20); + } + else // vertical + { + if (line > 19) + line = 19; + uint8_t *dst = sgb.attr + line; + for (int i = 0; i < 18; i++, dst += 20) + dst[0] = a; + } + } +} + +static void cmd_attr_div() +{ + if ((sgb.command[0] & 7) == 1) + { + uint8_t v = sgb.command[1]; + + int c = v & 3; + int a = v >> 2 & 3; + int b = v >> 4 & 3; + + int pos = sgb.command[2]; + uint8_t *dst = sgb.attr; + if (v & 0x40) // horizontal + { + if (pos > 17) + pos = 17; + int i; + for (i = 0; i < pos; i++, dst += 20) + memset(dst, a, 20); + memset(dst, b, 20); + i++, dst += 20; + for (; i < 18; i++, dst += 20) + memset(dst, c, 20); + } + else // vertical + { + if (pos > 19) + pos = 19; + for (int j = 0; j < 18; j++) + { + int i; + for (i = 0; i < pos; i++) + *dst++ = a; + *dst++ = b; + i++; + for (; i < 20; i++) + *dst++ = c; + } + } + } + else + { + utils_log("SGB: cmd_attr_div bad length"); + } +} + +static void cmd_attr_chr() +{ + int x = sgb.command[1]; + int y = sgb.command[2]; + int n = sgb.command[3] | sgb.command[4] << 8; + if (n > 360) + { + utils_log("SGB: cmd_attr_chr bad n"); + return; + } + int npacket = (n + 87) / 64; + if ((sgb.command[0] & 7) != npacket) + { + utils_log("SGB: cmd_attr_chr bad length"); + return; + } + uint8_t *dst = sgb.attr; + if (x > 19) + x = 19; + if (y > 17) + y = 17; + int vertical = sgb.command[5]; + for (int i = 0; i < 360; i++) + { + uint8_t v = i / 4 + 6; + int a = v >> (2 * (3 - (i & 3))) & 3; + dst[y * 20 + x] = a; + if (vertical) + { + y++; + if (y == 18) + { + y = 0; + x++; + if (x == 20) + return; + } + } + else + { + x++; + if (x == 20) + { + x = 0; + y++; + if (y == 18) + return; + } + } + } +} + +static void cmd_attr_set() +{ + if ((sgb.command[0] & 7) == 1) + { + int attr = sgb.command[1] & 0x3f; + if (attr >= 45) + attr = 44; + memcpy(sgb.attr, sgb.auxattr[attr], sizeof(sgb.attr)); + if (sgb.command[1] & 0x40) + { + sgb.active_mask = 0; + } + } + else + { + utils_log("SGB: cmd_attr_set bad length"); + } +} + +static void cmd_mlt_req(void) +{ + if ((sgb.command[0] & 7) == 1) + { + switch (sgb.command[1] & 3) + { + case 0: + case 2: + sgb.num_joypads = 1; + sgb.joypad_index = 0; + break; + case 1: + sgb.num_joypads = 2; + sgb.joypad_index = 1; + break; + case 3: + sgb.num_joypads = 4; + sgb.joypad_index = 1; + break; + } + utils_log("SGB: %u joypads", sgb.num_joypads); + } + else + { + utils_log("SGB: cmd_mlt_req bad length"); + } +} + +static void cmd_mask(void) +{ + if ((sgb.command[0] & 7) == 1) + { + switch (sgb.command[1] & 3) + { + case 0: + sgb.active_mask = 0; + break; + case 1: + sgb.active_mask = 1; + break; + case 2: + case 3: + sgb.active_mask = 1; + memset(sgb.frozenframe, 0, sizeof(sgb.frozenframe)); + break; + } + } + else + { + utils_log("SGB: cmd_mask bad length"); + } +} + +static void cmd_sound(void) +{ + if ((sgb.command[0] & 7) == 1) + { + sgb.sound_control[1] = sgb.command[1]; + sgb.sound_control[2] = sgb.command[2]; + sgb.sound_control[3] = sgb.command[3]; + sgb.sound_control[0] = sgb.command[4]; + } + else + { + utils_log("SGB: cmd_sound bad length"); + } +} + +static void do_command(void) +{ + const int command = sgb.command[0] >> 3; + switch (command) + { + default: + utils_log("SGB: Unknown or unimplemented command %02xh", command); + break; + + case 0x00: // PAL01 + utils_log("SGB: PAL01"); + cmd_pal(0, 1); + break; + case 0x01: // PAL23 + utils_log("SGB: PAL23"); + cmd_pal(2, 3); + break; + case 0x02: // PAL03 + utils_log("SGB: PAL03"); + cmd_pal(0, 3); + break; + case 0x03: // PAL12 + utils_log("SGB: PAL12"); + cmd_pal(1, 2); + break; + case 0x0a: // PAL_SET + utils_log("SGB: PAL_SET"); + cmd_pal_set(); + break; + + case 0x04: // ATTR_BLK + utils_log("SGB: ATTR_BLK"); + cmd_attr_blk(); + break; + case 0x05: // ATTR_LIN + utils_log("SGB: ATTR_LIN"); + cmd_attr_lin(); + break; + case 0x06: // ATTR_DIV + utils_log("SGB: ATTR_DIV"); + cmd_attr_div(); + break; + case 0x07: // ATTR_CHR + utils_log("SGB: ATTR_CHR"); + cmd_attr_chr(); + break; + case 0x16: // ATTR_SET + utils_log("SGB: ATTR_SET"); + cmd_attr_set(); + break; + + case 0x17: // MASK_EN + utils_log("SGB: MASK_EN"); + cmd_mask(); + break; + + // unknown functions + case 0x0c: // ATRC_EN + utils_log("SGB: ATRC_EN??"); + break; + case 0x0d: // TEST_EN + utils_log("SGB: TEST_EN??"); + break; + case 0x0e: // ICON_EN + utils_log("SGB: ICON_EN??"); + break; + case 0x18: // OBJ_TRN + // no game used this + utils_log("SGB: OBJ_TRN??"); + break; + + // unimplementable functions + case 0x0f: // DATA_SND + // TODO: Is it possible for this (and DATA_TRN) to write data to + // memory areas used for the attribute file, etc? + // If so, do games do this? + utils_log("SGB: DATA_SND!! %02x:%02x%02x [%02x]", sgb.command[3], sgb.command[2], sgb.command[1], sgb.command[4]); + break; + case 0x10: // DATA_TRN + utils_log("SGB: DATA_TRN!!"); + break; + case 0x12: // JUMP + utils_log("SGB: JUMP!!"); + break; + + // joypad + case 0x11: // MLT_REQ + utils_log("SGB: MLT_REQ"); + cmd_mlt_req(); + break; + + // sound + case 0x08: // SOUND + utils_log("SGB: SOUND %02x %02x %02x %02x", sgb.command[1], sgb.command[2], sgb.command[3], sgb.command[4]); + cmd_sound(); + break; + + // all vram transfers + case 0x09: // SOU_TRN + utils_log("SGB: SOU_TRN"); + cmd_trn(TRN_SOUND); + break; + case 0x0b: // PAL_TRN + utils_log("SGB: PAL_TRN"); + cmd_trn(TRN_PAL); + break; + case 0x13: // CHR_TRN + utils_log("SGB: CHR_TRN"); + cmd_trn(sgb.command[1] & 1 ? TRN_CHR_HI : TRN_CHR_LOW); + break; + case 0x14: // PCT_TRN + utils_log("SGB: PCT_TRN"); + cmd_trn(TRN_PCT); + break; + case 0x15: // ATTR_TRN + utils_log("SGB: ATTR_TRN"); + cmd_trn(TRN_ATTR); + break; + } +} + +static void do_packet(void) +{ + memcpy(sgb.command + sgb.next_packet * 16, sgb.packet, sizeof(sgb.packet)); + sgb.next_packet++; + + if (sgb.expected_packets == 0) // not in the middle of a command + sgb.expected_packets = sgb.command[0] & 7; + + if (sgb.expected_packets == 0) // huh? + { + utils_log("SGB: zero packet command"); + sgb.expected_packets = 0; + sgb.next_packet = 0; + } + else if (sgb.next_packet == sgb.expected_packets) + { + do_command(); + sgb.expected_packets = 0; + sgb.next_packet = 0; + } +} + +int sgb_init(const uint8_t *spc, int length) +{ + memset(&sgb, 0, sizeof(sgb)); + sgb.read_index = 255; + sgb.num_joypads = 1; + sgb.palette[0][0] = 0xffffffff; + sgb.palette[0][1] = 0xffaaaaaa; + sgb.palette[0][2] = 0xff555555; + sgb.palette[0][3] = 0xff000000; + + sgb.spc = spc_new(); + spc_init_rom(sgb.spc, iplrom); + spc_reset(sgb.spc); + if (spc_load_spc(sgb.spc, spc, length) != NULL) + { + utils_log("SGB: Failed to load SPC"); + return 0; + } + + return 1; +} + +void sgb_write_ff00(uint8_t val, uint64_t time) +{ + val &= 0x30; + + //utils_log("ZZ: %02x, %llu", val, time); + const int p14_fell = (val & 0x10) < (sgb.last_write_value & 0x10); + const int p15_fell = (val & 0x20) < (sgb.last_write_value & 0x20); + const int p14_rose = (val & 0x10) > (sgb.last_write_value & 0x10); + const int p15_rose = (val & 0x20) > (sgb.last_write_value & 0x20); + + if (val == 0) // reset command processing + { + sgb.read_index = 0; + memset(sgb.packet, 0, sizeof(sgb.packet)); + } + else if (sgb.read_index != 255) // currently reading a packet + { + if (p14_fell || p15_fell) + { + if (sgb.read_index == 128) // end of packet + { + if (p14_fell) + do_packet(); + else + utils_log("SGB: Stop bit not present"); + sgb.read_index = 255; + } + else + { + if (p15_fell) + { + int byte = sgb.read_index >> 3; + int bit = sgb.read_index & 7; + sgb.packet[byte] |= 1 << bit; + } + sgb.read_index++; + } + } + } + else // joypad processing + { + if (val == 0x10) + sgb.joypad_has_been_read |= 2; // reading P15 + if (val == 0x20) + sgb.joypad_has_been_read |= 1; // reading P14 + if (val == 0x30 && (p14_rose || p15_rose)) + { + if (sgb.joypad_has_been_read == 7) + { + sgb.joypad_has_been_read = 0; + sgb.joypad_index++; + sgb.joypad_index &= sgb.num_joypads - 1; + //utils_log("SGB: joypad index to %u", sgb.joypad_index); + } + else + { + sgb.joypad_has_been_read &= 3; // the other line must be asserted and a read must happen before joypad_index inc?? + } + } + } + + sgb.last_write_value = val; + sgb.last_write_time = time; +} + +uint8_t sgb_read_ff00(uint64_t time) +{ + uint8_t ret = sgb.last_write_value & 0xf0 | 0xc0; + const int p14 = !(ret & 0x10); + const int p15 = !(ret & 0x20); + const int ji = sgb.joypad_index; + + // TODO: is this "reset" correct? + sgb.joypad_has_been_read |= 4; // read occured + sgb.read_index = 255; + sgb.next_packet = 0; + sgb.expected_packets = 0; + + if (!p14 && !p15) + { + //utils_log("SGB: SCAN%u", ji); + // scan id + return ret | (15 - ji); + } + else + { + // get data + const uint8_t j = sgb.joypad_data[ji]; + if (p14) + ret |= j >> 4; + if (p15) + ret |= j & 0x0f; + //utils_log("SGB: READ%u %02x", ji, ret ^ 0x0f); + return ret ^ 0x0f; + } +} + +// for each of 4 joypads: +// 7......0 +// DULRSsBA +void sgb_set_controller_data(const uint8_t *buttons) +{ + memcpy(sgb.joypad_data, buttons, sizeof(sgb.joypad_data)); +} + +static void trn_sound(const uint8_t* data) +{ + int len = data[0] | data[1] << 8; + int addr = data[2] | data[3] << 8; + utils_log("TRN_SOUND %04x %04x", addr, len); + uint8_t* dst = spc_get_ram(sgb.spc); + + if (len > 0xffc) + { + utils_log("TRN_SOUND src overflow"); + return; + } + if (len + addr >= 0x10000) + { + utils_log("TRN_SOUND dst overflow"); + return; + } + memcpy(dst + addr, data + 4, len); +} + +static void trn_pal(const uint8_t *data) +{ + const uint16_t *src = (const uint16_t *)data; + uint32_t *dst = sgb.auxpalette[0]; + for (int i = 0; i < 2048; i++) + dst[i] = makecol(src[i]); +} + +static void trn_attr(const uint8_t *data) +{ + uint8_t *dst = sgb.auxattr[0]; + for (int n = 0; n < 45 * 90; n++) + { + uint8_t s = *data++; + *dst++ = s >> 6 & 3; + *dst++ = s >> 4 & 3; + *dst++ = s >> 2 & 3; + *dst++ = s >> 0 & 3; + } +} + +static void trn_pct(const uint8_t *data) +{ + memcpy(sgb.tilemap, data, sizeof(sgb.tilemap)); + const uint16_t *palettes = (const uint16_t *)(data + sizeof(sgb.tilemap)); + uint32_t *dst = sgb.palette[4]; + for (int i = 0; i < 64; i++) + dst[i] = makecol(palettes[i]); +} + +static void trn_chr(const uint8_t *data, int bank) +{ + uint8_t *dst = sgb.tiles[128 * bank]; + for (int n = 0; n < 128; n++) + { + for (int y = 0; y < 8; y++) + { + int a = data[0]; + int b = data[1] << 1; + int c = data[16] << 2; + int d = data[17] << 3; + for (int x = 7; x >= 0; x--) + { + dst[x] = a & 1 | b & 2 | c & 4 | d & 8; + a >>= 1; + b >>= 1; + c >>= 1; + d >>= 1; + } + dst += 8; + data += 2; + } + data += 16; + } +} + +static void do_vram_transfer(void) +{ + uint8_t vram[4096]; + for (int tilenum = 0; tilenum < 256; tilenum++) + { + const int ty = tilenum / 20; + const int tx = tilenum % 20; + const uint8_t *src = sgb.frame + ty * 8 * 160 + tx * 8; + uint8_t *dst = vram + 16 * tilenum; + for (int j = 0; j < 8; j++) + { + uint32_t a = 0, b = 0; + a |= (src[7] & 1) << 0; + a |= (src[6] & 1) << 1; + a |= (src[5] & 1) << 2; + a |= (src[4] & 1) << 3; + a |= (src[3] & 1) << 4; + a |= (src[2] & 1) << 5; + a |= (src[1] & 1) << 6; + a |= (src[0] & 1) << 7; + + b |= (src[7] & 2) >> 1; + b |= (src[6] & 2) << 0; + b |= (src[5] & 2) << 1; + b |= (src[4] & 2) << 2; + b |= (src[3] & 2) << 3; + b |= (src[2] & 2) << 4; + b |= (src[1] & 2) << 5; + b |= (src[0] & 2) << 6; + *dst++ = a; + *dst++ = b; + src += 160; + } + } + + switch (sgb.waiting_transfer) + { + case TRN_SOUND: + trn_sound(vram); + break; + case TRN_PAL: + trn_pal(vram); + break; + case TRN_CHR_LOW: + trn_chr(vram, 0); + break; + case TRN_CHR_HI: + trn_chr(vram, 1); + break; + case TRN_PCT: + trn_pct(vram); + break; + case TRN_ATTR: + trn_attr(vram); + break; + } +} + +// 160x144 32bpp pixel data +// assumed to contain exact pixel values 00, 55, aa, ff +void sgb_take_frame(uint32_t *vbuff) +{ + for (int i = 0; i < 160 * 144; i++) + { + sgb.frame[i] = 3 - (vbuff[i] >> 6 & 3); // 0, 1, 2, or 3 for each pixel + } + if (sgb.waiting_transfer != TRN_NONE) + { + if (!--sgb.transfer_countdown) + { + do_vram_transfer(); + sgb.waiting_transfer = TRN_NONE; + } + } + if (!sgb.active_mask) + { + memcpy(sgb.frozenframe, sgb.frame, sizeof(sgb.frame)); + } +} + +static void sgb_render_frame_gb(uint32_t *vbuff) +{ + const uint8_t *attr = sgb.attr; + const uint8_t *src = sgb.active_mask ? sgb.frozenframe : sgb.frame; + uint32_t *dst = vbuff + ((224 - 144) / 2 * 256 + (256 - 160) / 2); + + for (int j = 0; j < 144; j++) + { + const uint8_t *attr_line = attr + j / 8 * 20; + for (int i = 0; i < 160; i++) + { + const int attr_index = i / 8; + *dst++ = sgb.palette[attr_line[attr_index]][*src++]; + } + dst += 256 - 160; + } +} + +static void draw_tile(uint16_t entry, uint32_t *dest) +{ + const uint8_t *tile = sgb.tiles[entry & 0xff]; + const uint32_t *palette = sgb.palette[entry >> 10 & 7]; + int hflip = entry & 0x4000; + int vflip = entry & 0x8000; + int hinc, vinc; + if (hflip) + { + hinc = -1; + dest += 7; + } + else + { + hinc = 1; + } + if (vflip) + { + vinc = -256; + dest += 7 * 256; + } + else + { + vinc = 256; + } + vinc -= 8 * hinc; + for (int y = 0; y < 8; y++, dest += vinc) + { + for (int x = 0; x < 8; x++, dest += hinc) + { + int c = *tile++; + if (c) + *dest = palette[c]; + } + } +} + +static void sgb_render_border(uint32_t *vbuff) +{ + const uint16_t *tilemap = sgb.tilemap; + for (int n = 0; n < 32 * 28; n++) + { + draw_tile(*tilemap++, vbuff); + vbuff += 8; + if ((n & 31) == 31) + vbuff += 256 * 7; + } +} + +void sgb_render_frame(uint32_t *vbuff) +{ + for (int i = 0; i < 256 * 224; i++) + vbuff[i] = sgb.palette[0][0]; + sgb_render_frame_gb(vbuff); + sgb_render_border(vbuff); +} + +void sgb_render_audio(uint64_t time, void (*callback)(int16_t l, int16_t r, uint64_t time)) +{ + int16_t sound_buffer[4096]; + uint32_t diff = time - sgb.frame_start + sgb.clock_remainder; + //utils_log("%ul", diff); + + uint32_t samples = diff / refclocks_per_spc_sample; + uint32_t new_remainder = diff % refclocks_per_spc_sample; + + spc_set_output(sgb.spc, sound_buffer, sizeof(sound_buffer) / sizeof(sound_buffer[0])); + int p; + for (p = 0; p < 4; p++) + { + if (spc_read_port(sgb.spc, 0, p) != sgb.sound_control[p]) + break; + } + if (p == 4) // recived + { + sgb.sound_control[0] = 0; + sgb.sound_control[1] = 0; + sgb.sound_control[2] = 0; + } + for (p = 0; p < 4; p++) + { + spc_write_port(sgb.spc, 0, p, sgb.sound_control[p]); + } + + spc_end_frame(sgb.spc, samples * 32); + + uint64_t t = sgb.frame_start + refclocks_per_spc_sample - sgb.clock_remainder; + for (int i = 0; i < samples; i++, t += refclocks_per_spc_sample) + callback(sound_buffer[i * 2], sound_buffer[i * 2] + 1, t); + + sgb.frame_start = time; + sgb.clock_remainder = new_remainder; +} diff --git a/waterbox/pizza/lib/sgb.h b/waterbox/pizza/lib/sgb.h new file mode 100644 index 0000000000..4c1009ac08 --- /dev/null +++ b/waterbox/pizza/lib/sgb.h @@ -0,0 +1,16 @@ +#pragma once +#include + +void sgb_write_ff00(uint8_t val, uint64_t time); + +uint8_t sgb_read_ff00(uint64_t time); + +void sgb_set_controller_data(const uint8_t* buttons); + +int sgb_init(const uint8_t* spc, int length); + +void sgb_take_frame(uint32_t* vbuff); + +void sgb_render_frame(uint32_t* vbuff); + +void sgb_render_audio(uint64_t time, void(*callback)(int16_t l, int16_t r, uint64_t time)); diff --git a/waterbox/pizza/lib/snes_spc/SNES_SPC.cpp b/waterbox/pizza/lib/snes_spc/SNES_SPC.cpp new file mode 100644 index 0000000000..fb3b147ae8 --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/SNES_SPC.cpp @@ -0,0 +1,564 @@ +// Core SPC emulation: CPU, timers, SMP registers, memory + +// snes_spc 0.9.0. http://www.slack.net/~ant/ + +#include "SNES_SPC.h" + +#include + +/* Copyright (C) 2004-2007 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "blargg_source.h" + +#define RAM (m.ram.ram) +#define REGS (m.smp_regs [0]) +#define REGS_IN (m.smp_regs [1]) + +// (n ? n : 256) +#define IF_0_THEN_256( n ) ((uint8_t) ((n) - 1) + 1) + +// Note: SPC_MORE_ACCURACY exists mainly so I can run my validation tests, which +// do crazy echo buffer accesses. +#ifndef SPC_MORE_ACCURACY + #define SPC_MORE_ACCURACY 0 +#endif + +#ifdef BLARGG_ENABLE_OPTIMIZER + #include BLARGG_ENABLE_OPTIMIZER +#endif + + +//// Timers + +#if SPC_DISABLE_TEMPO + #define TIMER_DIV( t, n ) ((n) >> t->prescaler) + #define TIMER_MUL( t, n ) ((n) << t->prescaler) +#else + #define TIMER_DIV( t, n ) ((n) / t->prescaler) + #define TIMER_MUL( t, n ) ((n) * t->prescaler) +#endif + +SNES_SPC::Timer* SNES_SPC::run_timer_( Timer* t, rel_time_t time ) +{ + int elapsed = TIMER_DIV( t, time - t->next_time ) + 1; + t->next_time += TIMER_MUL( t, elapsed ); + + if ( t->enabled ) + { + int remain = IF_0_THEN_256( t->period - t->divider ); + int divider = t->divider + elapsed; + int over = elapsed - remain; + if ( over >= 0 ) + { + int n = over / t->period; + t->counter = (t->counter + 1 + n) & 0x0F; + divider = over - n * t->period; + } + t->divider = (uint8_t) divider; + } + return t; +} + +inline SNES_SPC::Timer* SNES_SPC::run_timer( Timer* t, rel_time_t time ) +{ + if ( time >= t->next_time ) + t = run_timer_( t, time ); + return t; +} + + +//// ROM + +void SNES_SPC::enable_rom( int enable ) +{ + if ( m.rom_enabled != enable ) + { + m.rom_enabled = enable; + if ( enable ) + memcpy( m.hi_ram, &RAM [rom_addr], sizeof m.hi_ram ); + memcpy( &RAM [rom_addr], (enable ? m.rom : m.hi_ram), rom_size ); + // TODO: ROM can still get overwritten when DSP writes to echo buffer + } +} + + +//// DSP + +#if SPC_LESS_ACCURATE + int const max_reg_time = 29; + + signed char const SNES_SPC::reg_times_ [256] = + { + -1, 0,-11,-10,-15,-11, -2, -2, 4, 3, 14, 14, 26, 26, 14, 22, + 2, 3, 0, 1,-12, 0, 1, 1, 7, 6, 14, 14, 27, 14, 14, 23, + 5, 6, 3, 4, -1, 3, 4, 4, 10, 9, 14, 14, 26, -5, 14, 23, + 8, 9, 6, 7, 2, 6, 7, 7, 13, 12, 14, 14, 27, -4, 14, 24, + 11, 12, 9, 10, 5, 9, 10, 10, 16, 15, 14, 14, -2, -4, 14, 24, + 14, 15, 12, 13, 8, 12, 13, 13, 19, 18, 14, 14, -2,-36, 14, 24, + 17, 18, 15, 16, 11, 15, 16, 16, 22, 21, 14, 14, 28, -3, 14, 25, + 20, 21, 18, 19, 14, 18, 19, 19, 25, 24, 14, 14, 14, 29, 14, 25, + + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + }; + + #define RUN_DSP( time, offset ) \ + int count = (time) - (offset) - m.dsp_time;\ + if ( count >= 0 )\ + {\ + int clock_count = (count & ~(clocks_per_sample - 1)) + clocks_per_sample;\ + m.dsp_time += clock_count;\ + dsp.run( clock_count );\ + } +#else + #define RUN_DSP( time, offset ) \ + {\ + int count = (time) - m.dsp_time;\ + if ( !SPC_MORE_ACCURACY || count )\ + {\ + assert( count > 0 );\ + m.dsp_time = (time);\ + dsp.run( count );\ + }\ + } +#endif + +int SNES_SPC::dsp_read( rel_time_t time ) +{ + RUN_DSP( time, reg_times [REGS [r_dspaddr] & 0x7F] ); + + int result = dsp.read( REGS [r_dspaddr] & 0x7F ); + + #ifdef SPC_DSP_READ_HOOK + SPC_DSP_READ_HOOK( spc_time + time, (REGS [r_dspaddr] & 0x7F), result ); + #endif + + return result; +} + +inline void SNES_SPC::dsp_write( int data, rel_time_t time ) +{ + RUN_DSP( time, reg_times [REGS [r_dspaddr]] ) + #if SPC_LESS_ACCURATE + else if ( m.dsp_time == skipping_time ) + { + int r = REGS [r_dspaddr]; + if ( r == SPC_DSP::r_kon ) + m.skipped_kon |= data & ~dsp.read( SPC_DSP::r_koff ); + + if ( r == SPC_DSP::r_koff ) + { + m.skipped_koff |= data; + m.skipped_kon &= ~data; + } + } + #endif + + #ifdef SPC_DSP_WRITE_HOOK + SPC_DSP_WRITE_HOOK( m.spc_time + time, REGS [r_dspaddr], (uint8_t) data ); + #endif + + if ( REGS [r_dspaddr] <= 0x7F ) + dsp.write( REGS [r_dspaddr], data ); + else if ( !SPC_MORE_ACCURACY ) + dprintf( "SPC wrote to DSP register > $7F\n" ); +} + + +//// Memory access extras + +#if SPC_MORE_ACCURACY + #define MEM_ACCESS( time, addr ) \ + {\ + if ( time >= m.dsp_time )\ + {\ + RUN_DSP( time, max_reg_time );\ + }\ + } +#elif !defined (NDEBUG) + // Debug-only check for read/write within echo buffer, since this might result in + // inaccurate emulation due to the DSP not being caught up to the present. + + bool SNES_SPC::check_echo_access( int addr ) + { + if ( !(dsp.read( SPC_DSP::r_flg ) & 0x20) ) + { + int start = 0x100 * dsp.read( SPC_DSP::r_esa ); + int size = 0x800 * (dsp.read( SPC_DSP::r_edl ) & 0x0F); + int end = start + (size ? size : 4); + if ( start <= addr && addr < end ) + { + if ( !m.echo_accessed ) + { + m.echo_accessed = 1; + return true; + } + } + } + return false; + } + + #define MEM_ACCESS( time, addr ) check( !check_echo_access( (uint16_t) addr ) ); +#else + #define MEM_ACCESS( time, addr ) +#endif + + +//// CPU write + +#if SPC_MORE_ACCURACY +static unsigned char const glitch_probs [3] [256] = +{ + 0xC3,0x92,0x5B,0x1C,0xD1,0x92,0x5B,0x1C,0xDB,0x9C,0x72,0x18,0xCD,0x5C,0x38,0x0B, + 0xE1,0x9C,0x74,0x17,0xCF,0x75,0x45,0x0C,0xCF,0x6E,0x4A,0x0D,0xA3,0x3A,0x1D,0x08, + 0xDB,0xA0,0x82,0x19,0xD9,0x73,0x3C,0x0E,0xCB,0x76,0x52,0x0B,0xA5,0x46,0x1D,0x09, + 0xDA,0x74,0x55,0x0F,0xA2,0x3F,0x21,0x05,0x9A,0x40,0x20,0x07,0x63,0x1E,0x10,0x01, + 0xDF,0xA9,0x85,0x1D,0xD3,0x84,0x4B,0x0E,0xCF,0x6F,0x49,0x0F,0xB3,0x48,0x1E,0x05, + 0xD8,0x77,0x52,0x12,0xB7,0x49,0x23,0x06,0xAA,0x45,0x28,0x07,0x7D,0x28,0x0F,0x07, + 0xCC,0x7B,0x4A,0x0E,0xB2,0x4F,0x24,0x07,0xAD,0x43,0x2C,0x06,0x86,0x29,0x11,0x07, + 0xAE,0x48,0x1F,0x0A,0x76,0x21,0x19,0x05,0x76,0x21,0x14,0x05,0x44,0x11,0x0B,0x01, + 0xE7,0xAD,0x96,0x23,0xDC,0x86,0x59,0x0E,0xDC,0x7C,0x5F,0x15,0xBB,0x53,0x2E,0x09, + 0xD6,0x7C,0x4A,0x16,0xBB,0x4A,0x25,0x08,0xB3,0x4F,0x28,0x0B,0x8E,0x23,0x15,0x08, + 0xCF,0x7F,0x57,0x11,0xB5,0x4A,0x23,0x0A,0xAA,0x42,0x28,0x05,0x7D,0x22,0x12,0x03, + 0xA6,0x49,0x28,0x09,0x82,0x2B,0x0D,0x04,0x7A,0x20,0x0F,0x04,0x3D,0x0F,0x09,0x03, + 0xD1,0x7C,0x4C,0x0F,0xAF,0x4E,0x21,0x09,0xA8,0x46,0x2A,0x07,0x85,0x1F,0x0E,0x07, + 0xA6,0x3F,0x26,0x07,0x7C,0x24,0x14,0x07,0x78,0x22,0x16,0x04,0x46,0x12,0x0A,0x02, + 0xA6,0x41,0x2C,0x0A,0x7E,0x28,0x11,0x05,0x73,0x1B,0x14,0x05,0x3D,0x11,0x0A,0x02, + 0x70,0x22,0x17,0x05,0x48,0x13,0x08,0x03,0x3C,0x07,0x0D,0x07,0x26,0x07,0x06,0x01, + + 0xE0,0x9F,0xDA,0x7C,0x4F,0x18,0x28,0x0D,0xE9,0x9F,0xDA,0x7C,0x4F,0x18,0x1F,0x07, + 0xE6,0x97,0xD8,0x72,0x64,0x13,0x26,0x09,0xDC,0x67,0xA9,0x38,0x21,0x07,0x15,0x06, + 0xE9,0x91,0xD2,0x6B,0x63,0x14,0x2B,0x0E,0xD6,0x61,0xB7,0x41,0x2B,0x0E,0x10,0x09, + 0xCF,0x59,0xB0,0x2F,0x35,0x08,0x0F,0x07,0xB6,0x30,0x7A,0x21,0x17,0x07,0x09,0x03, + 0xE7,0xA3,0xE5,0x6B,0x65,0x1F,0x34,0x09,0xD8,0x6B,0xBE,0x45,0x27,0x07,0x10,0x07, + 0xDA,0x54,0xB1,0x39,0x2E,0x0E,0x17,0x08,0xA9,0x3C,0x86,0x22,0x16,0x06,0x07,0x03, + 0xD4,0x51,0xBC,0x3D,0x38,0x0A,0x13,0x06,0xB2,0x37,0x79,0x1C,0x17,0x05,0x0E,0x06, + 0xA7,0x31,0x74,0x1C,0x11,0x06,0x0C,0x02,0x6D,0x1A,0x38,0x10,0x0B,0x05,0x06,0x03, + 0xEB,0x9A,0xE1,0x7A,0x6F,0x13,0x34,0x0E,0xE6,0x75,0xC5,0x45,0x3E,0x0B,0x1A,0x05, + 0xD8,0x63,0xC1,0x40,0x3C,0x1B,0x19,0x06,0xB3,0x42,0x83,0x29,0x18,0x0A,0x08,0x04, + 0xD4,0x58,0xBA,0x43,0x3F,0x0A,0x1F,0x09,0xB1,0x33,0x8A,0x1F,0x1F,0x06,0x0D,0x05, + 0xAF,0x3C,0x7A,0x1F,0x16,0x08,0x0A,0x01,0x72,0x1B,0x52,0x0D,0x0B,0x09,0x06,0x01, + 0xCF,0x63,0xB7,0x47,0x40,0x10,0x14,0x06,0xC0,0x41,0x96,0x20,0x1C,0x09,0x10,0x05, + 0xA6,0x35,0x82,0x1A,0x20,0x0C,0x0E,0x04,0x80,0x1F,0x53,0x0F,0x0B,0x02,0x06,0x01, + 0xA6,0x31,0x81,0x1B,0x1D,0x01,0x08,0x08,0x7B,0x20,0x4D,0x19,0x0E,0x05,0x07,0x03, + 0x6B,0x17,0x49,0x07,0x0E,0x03,0x0A,0x05,0x37,0x0B,0x1F,0x06,0x04,0x02,0x07,0x01, + + 0xF0,0xD6,0xED,0xAD,0xEC,0xB1,0xEB,0x79,0xAC,0x22,0x47,0x1E,0x6E,0x1B,0x32,0x0A, + 0xF0,0xD6,0xEA,0xA4,0xED,0xC4,0xDE,0x82,0x98,0x1F,0x50,0x13,0x52,0x15,0x2A,0x0A, + 0xF1,0xD1,0xEB,0xA2,0xEB,0xB7,0xD8,0x69,0xA2,0x1F,0x5B,0x18,0x55,0x18,0x2C,0x0A, + 0xED,0xB5,0xDE,0x7E,0xE6,0x85,0xD3,0x59,0x59,0x0F,0x2C,0x09,0x24,0x07,0x15,0x09, + 0xF1,0xD6,0xEA,0xA0,0xEC,0xBB,0xDA,0x77,0xA9,0x23,0x58,0x14,0x5D,0x12,0x2F,0x09, + 0xF1,0xC1,0xE3,0x86,0xE4,0x87,0xD2,0x4E,0x68,0x15,0x26,0x0B,0x27,0x09,0x15,0x02, + 0xEE,0xA6,0xE0,0x5C,0xE0,0x77,0xC3,0x41,0x67,0x1B,0x3C,0x07,0x2A,0x06,0x19,0x07, + 0xE4,0x75,0xC6,0x43,0xCC,0x50,0x95,0x23,0x35,0x09,0x14,0x04,0x15,0x05,0x0B,0x04, + 0xEE,0xD6,0xED,0xAD,0xEC,0xB1,0xEB,0x79,0xAC,0x22,0x56,0x14,0x5A,0x12,0x26,0x0A, + 0xEE,0xBB,0xE7,0x7E,0xE9,0x8D,0xCB,0x49,0x67,0x11,0x34,0x07,0x2B,0x0B,0x14,0x07, + 0xED,0xA7,0xE5,0x76,0xE3,0x7E,0xC4,0x4B,0x77,0x14,0x34,0x08,0x27,0x07,0x14,0x04, + 0xE7,0x8B,0xD2,0x4C,0xCA,0x56,0x9E,0x31,0x36,0x0C,0x11,0x07,0x14,0x04,0x0A,0x02, + 0xF0,0x9B,0xEA,0x6F,0xE5,0x81,0xC4,0x43,0x74,0x10,0x30,0x0B,0x2D,0x08,0x1B,0x06, + 0xE6,0x83,0xCA,0x48,0xD9,0x56,0xA7,0x23,0x3B,0x09,0x12,0x09,0x15,0x07,0x0A,0x03, + 0xE5,0x5F,0xCB,0x3C,0xCF,0x48,0x91,0x22,0x31,0x0A,0x17,0x08,0x15,0x04,0x0D,0x02, + 0xD1,0x43,0x91,0x20,0xA9,0x2D,0x54,0x12,0x17,0x07,0x09,0x02,0x0C,0x04,0x05,0x03, +}; +#endif + +// divided into multiple functions to keep rarely-used functionality separate +// so often-used functionality can be optimized better by compiler + +// If write isn't preceded by read, data has this added to it +int const no_read_before_write = 0x2000; + +void SNES_SPC::cpu_write_smp_reg_( int data, rel_time_t time, int addr ) +{ + switch ( addr ) + { + case r_t0target: + case r_t1target: + case r_t2target: { + Timer* t = &m.timers [addr - r_t0target]; + int period = IF_0_THEN_256( data ); + if ( t->period != period ) + { + t = run_timer( t, time ); + #if SPC_MORE_ACCURACY + // Insane behavior when target is written just after counter is + // clocked and counter matches new period and new period isn't 1, 2, 4, or 8 + if ( t->divider == (period & 0xFF) && + t->next_time == time + TIMER_MUL( t, 1 ) && + ((period - 1) | ~0x0F) & period ) + { + //dprintf( "SPC pathological timer target write\n" ); + + // If the period is 3, 5, or 9, there's a probability this behavior won't occur, + // based on the previous period + int prob = 0xFF; + int old_period = t->period & 0xFF; + if ( period == 3 ) prob = glitch_probs [0] [old_period]; + if ( period == 5 ) prob = glitch_probs [1] [old_period]; + if ( period == 9 ) prob = glitch_probs [2] [old_period]; + + // The glitch suppresses incrementing of one of the counter bits, based on + // the lowest set bit in the new period + int b = 1; + while ( !(period & b) ) + b <<= 1; + + if ( (rand() >> 4 & 0xFF) <= prob ) + t->divider = (t->divider - b) & 0xFF; + } + #endif + t->period = period; + } + break; + } + + case r_t0out: + case r_t1out: + case r_t2out: + if ( !SPC_MORE_ACCURACY ) + dprintf( "SPC wrote to counter %d\n", (int) addr - r_t0out ); + + if ( data < no_read_before_write / 2 ) + run_timer( &m.timers [addr - r_t0out], time - 1 )->counter = 0; + break; + + // Registers that act like RAM + case 0x8: + case 0x9: + REGS_IN [addr] = (uint8_t) data; + break; + + case r_test: + if ( (uint8_t) data != 0x0A ) + dprintf( "SPC wrote to test register\n" ); + break; + + case r_control: + // port clears + if ( data & 0x10 ) + { + REGS_IN [r_cpuio0] = 0; + REGS_IN [r_cpuio1] = 0; + } + if ( data & 0x20 ) + { + REGS_IN [r_cpuio2] = 0; + REGS_IN [r_cpuio3] = 0; + } + + // timers + { + for ( int i = 0; i < timer_count; i++ ) + { + Timer* t = &m.timers [i]; + int enabled = data >> i & 1; + if ( t->enabled != enabled ) + { + t = run_timer( t, time ); + t->enabled = enabled; + if ( enabled ) + { + t->divider = 0; + t->counter = 0; + } + } + } + } + enable_rom( data & 0x80 ); + break; + } +} + +void SNES_SPC::cpu_write_smp_reg( int data, rel_time_t time, int addr ) +{ + if ( addr == r_dspdata ) // 99% + dsp_write( data, time ); + else + cpu_write_smp_reg_( data, time, addr ); +} + +void SNES_SPC::cpu_write_high( int data, int i, rel_time_t time ) +{ + if ( i < rom_size ) + { + m.hi_ram [i] = (uint8_t) data; + if ( m.rom_enabled ) + RAM [i + rom_addr] = m.rom [i]; // restore overwritten ROM + } + else + { + assert( RAM [i + rom_addr] == (uint8_t) data ); + RAM [i + rom_addr] = cpu_pad_fill; // restore overwritten padding + cpu_write( data, i + rom_addr - 0x10000, time ); + } +} + +int const bits_in_int = CHAR_BIT * sizeof (int); + +void SNES_SPC::cpu_write( int data, int addr, rel_time_t time ) +{ + MEM_ACCESS( time, addr ) + + // RAM + RAM [addr] = (uint8_t) data; + int reg = addr - 0xF0; + if ( reg >= 0 ) // 64% + { + // $F0-$FF + if ( reg < reg_count ) // 87% + { + REGS [reg] = (uint8_t) data; + + // Ports + #ifdef SPC_PORT_WRITE_HOOK + if ( (unsigned) (reg - r_cpuio0) < port_count ) + SPC_PORT_WRITE_HOOK( m.spc_time + time, (reg - r_cpuio0), + (uint8_t) data, ®S [r_cpuio0] ); + #endif + + // Registers other than $F2 and $F4-$F7 + //if ( reg != 2 && reg != 4 && reg != 5 && reg != 6 && reg != 7 ) + // TODO: this is a bit on the fragile side + if ( ((~0x2F00 << (bits_in_int - 16)) << reg) < 0 ) // 36% + cpu_write_smp_reg( data, time, reg ); + } + // High mem/address wrap-around + else + { + reg -= rom_addr - 0xF0; + if ( reg >= 0 ) // 1% in IPL ROM area or address wrapped around + cpu_write_high( data, reg, time ); + } + } +} + + +//// CPU read + +inline int SNES_SPC::cpu_read_smp_reg( int reg, rel_time_t time ) +{ + int result = REGS_IN [reg]; + reg -= r_dspaddr; + // DSP addr and data + if ( (unsigned) reg <= 1 ) // 4% 0xF2 and 0xF3 + { + result = REGS [r_dspaddr]; + if ( (unsigned) reg == 1 ) + result = dsp_read( time ); // 0xF3 + } + return result; +} + +int SNES_SPC::cpu_read( int addr, rel_time_t time ) +{ + MEM_ACCESS( time, addr ) + + // RAM + int result = RAM [addr]; + int reg = addr - 0xF0; + if ( reg >= 0 ) // 40% + { + reg -= 0x10; + if ( (unsigned) reg >= 0xFF00 ) // 21% + { + reg += 0x10 - r_t0out; + + // Timers + if ( (unsigned) reg < timer_count ) // 90% + { + Timer* t = &m.timers [reg]; + if ( time >= t->next_time ) + t = run_timer_( t, time ); + result = t->counter; + t->counter = 0; + } + // Other registers + else if ( reg < 0 ) // 10% + { + result = cpu_read_smp_reg( reg + r_t0out, time ); + } + else // 1% + { + assert( reg + (r_t0out + 0xF0 - 0x10000) < 0x100 ); + result = cpu_read( reg + (r_t0out + 0xF0 - 0x10000), time ); + } + } + } + + return result; +} + + +//// Run + +// Prefix and suffix for CPU emulator function +#define SPC_CPU_RUN_FUNC \ +BOOST::uint8_t* SNES_SPC::run_until_( time_t end_time )\ +{\ + rel_time_t rel_time = m.spc_time - end_time;\ + assert( rel_time <= 0 );\ + m.spc_time = end_time;\ + m.dsp_time += rel_time;\ + m.timers [0].next_time += rel_time;\ + m.timers [1].next_time += rel_time;\ + m.timers [2].next_time += rel_time; + +#define SPC_CPU_RUN_FUNC_END \ + m.spc_time += rel_time;\ + m.dsp_time -= rel_time;\ + m.timers [0].next_time -= rel_time;\ + m.timers [1].next_time -= rel_time;\ + m.timers [2].next_time -= rel_time;\ + assert( m.spc_time <= end_time );\ + return ®S [r_cpuio0];\ +} + +int const cpu_lag_max = 12 - 1; // DIV YA,X takes 12 clocks + +void SNES_SPC::end_frame( time_t end_time ) +{ + // Catch CPU up to as close to end as possible. If final instruction + // would exceed end, does NOT execute it and leaves m.spc_time < end. + if ( end_time > m.spc_time ) + run_until_( end_time ); + + m.spc_time -= end_time; + m.extra_clocks += end_time; + + // Greatest number of clocks early that emulation can stop early due to + // not being able to execute current instruction without going over + // allowed time. + assert( -cpu_lag_max <= m.spc_time && m.spc_time <= 0 ); + + // Catch timers up to CPU + for ( int i = 0; i < timer_count; i++ ) + run_timer( &m.timers [i], 0 ); + + // Catch DSP up to CPU + if ( m.dsp_time < 0 ) + { + RUN_DSP( 0, max_reg_time ); + } + + // Save any extra samples beyond what should be generated + if ( m.buf_begin ) + save_extra(); +} + +// Inclusion here allows static memory access functions and better optimization +#include "SPC_CPU.h" diff --git a/waterbox/pizza/lib/snes_spc/SNES_SPC.h b/waterbox/pizza/lib/snes_spc/SNES_SPC.h new file mode 100644 index 0000000000..fb1ad18a45 --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/SNES_SPC.h @@ -0,0 +1,284 @@ +// SNES SPC-700 APU emulator + +// snes_spc 0.9.0 +#ifndef SNES_SPC_H +#define SNES_SPC_H + +#include "SPC_DSP.h" +#include "blargg_endian.h" +#include + +struct SNES_SPC { +public: + typedef BOOST::uint8_t uint8_t; + + // Must be called once before using + blargg_err_t init(); + + // Sample pairs generated per second + enum { sample_rate = 32000 }; + +// Emulator use + + // Sets IPL ROM data. Library does not include ROM data. Most SPC music files + // don't need ROM, but a full emulator must provide this. + enum { rom_size = 0x40 }; + void init_rom( uint8_t const rom [rom_size] ); + + // Sets destination for output samples + typedef short sample_t; + void set_output( sample_t* out, int out_size ); + + // Number of samples written to output since last set + int sample_count() const; + + // Resets SPC to power-on state. This resets your output buffer, so you must + // call set_output() after this. + void reset(); + + // Emulates pressing reset switch on SNES. This resets your output buffer, so + // you must call set_output() after this. + void soft_reset(); + + // 1024000 SPC clocks per second, sample pair every 32 clocks + typedef int time_t; + enum { clock_rate = 1024000 }; + enum { clocks_per_sample = 32 }; + + // Emulated port read/write at specified time + enum { port_count = 4 }; + int read_port ( time_t, int port ); + void write_port( time_t, int port, int data ); + + // Runs SPC to end_time and starts a new time frame at 0 + void end_frame( time_t end_time ); + + uint8_t* get_ram(); + +// Sound control + + // Mutes voices corresponding to non-zero bits in mask (issues repeated KOFF events). + // Reduces emulation accuracy. + enum { voice_count = 8 }; + void mute_voices( int mask ); + + // If true, prevents channels and global volumes from being phase-negated. + // Only supported by fast DSP. + void disable_surround( bool disable = true ); + + // Sets tempo, where tempo_unit = normal, tempo_unit / 2 = half speed, etc. + enum { tempo_unit = 0x100 }; + void set_tempo( int ); + +// SPC music files + + // Loads SPC data into emulator + enum { spc_min_file_size = 0x10180 }; + enum { spc_file_size = 0x10200 }; + blargg_err_t load_spc( void const* in, long size ); + + // Clears echo region. Useful after loading an SPC as many have garbage in echo. + void clear_echo(); + + // Plays for count samples and write samples to out. Discards samples if out + // is NULL. Count must be a multiple of 2 since output is stereo. + blargg_err_t play( int count, sample_t* out ); + + // Skips count samples. Several times faster than play() when using fast DSP. + blargg_err_t skip( int count ); + +// State save/load (only available with accurate DSP) + +#if !SPC_NO_COPY_STATE_FUNCS + // Saves/loads state + enum { state_size = 67 * 1024L }; // maximum space needed when saving + typedef SPC_DSP::copy_func_t copy_func_t; + void copy_state( unsigned char** io, copy_func_t ); + + // Writes minimal header to spc_out + static void init_header( void* spc_out ); + + // Saves emulator state as SPC file data. Writes spc_file_size bytes to spc_out. + // Does not set up SPC header; use init_header() for that. + void save_spc( void* spc_out ); + + // Returns true if new key-on events occurred since last check. Useful for + // trimming silence while saving an SPC. + bool check_kon(); +#endif + +public: + BLARGG_DISABLE_NOTHROW + + typedef BOOST::uint16_t uint16_t; + + // Time relative to m_spc_time. Speeds up code a bit by eliminating need to + // constantly add m_spc_time to time from CPU. CPU uses time that ends at + // 0 to eliminate reloading end time every instruction. It pays off. + typedef int rel_time_t; + + struct Timer + { + rel_time_t next_time; // time of next event + int prescaler; + int period; + int divider; + int enabled; + int counter; + }; + enum { reg_count = 0x10 }; + enum { timer_count = 3 }; + enum { extra_size = SPC_DSP::extra_size }; + + enum { signature_size = 35 }; + +private: + SPC_DSP dsp; + + #if SPC_LESS_ACCURATE + static signed char const reg_times_ [256]; + signed char reg_times [256]; + #endif + + struct state_t + { + Timer timers [timer_count]; + + uint8_t smp_regs [2] [reg_count]; + + struct + { + int pc; + int a; + int x; + int y; + int psw; + int sp; + } cpu_regs; + + rel_time_t dsp_time; + time_t spc_time; + bool echo_accessed; + + int tempo; + int skipped_kon; + int skipped_koff; + const char* cpu_error; + + int extra_clocks; + sample_t* buf_begin; + sample_t const* buf_end; + sample_t* extra_pos; + sample_t extra_buf [extra_size]; + + int rom_enabled; + uint8_t rom [rom_size]; + uint8_t hi_ram [rom_size]; + + unsigned char cycle_table [256]; + + struct + { + // padding to neutralize address overflow + union { + uint8_t padding1 [0x100]; + uint16_t align; // makes compiler align data for 16-bit access + } padding1 [1]; + uint8_t ram [0x10000]; + uint8_t padding2 [0x100]; + } ram; + }; + state_t m; + + enum { rom_addr = 0xFFC0 }; + + enum { skipping_time = 127 }; + + // Value that padding should be filled with + enum { cpu_pad_fill = 0xFF }; + + enum { + r_test = 0x0, r_control = 0x1, + r_dspaddr = 0x2, r_dspdata = 0x3, + r_cpuio0 = 0x4, r_cpuio1 = 0x5, + r_cpuio2 = 0x6, r_cpuio3 = 0x7, + r_f8 = 0x8, r_f9 = 0x9, + r_t0target = 0xA, r_t1target = 0xB, r_t2target = 0xC, + r_t0out = 0xD, r_t1out = 0xE, r_t2out = 0xF + }; + + void timers_loaded(); + void enable_rom( int enable ); + void reset_buf(); + void save_extra(); + void load_regs( uint8_t const in [reg_count] ); + void ram_loaded(); + void regs_loaded(); + void reset_time_regs(); + void reset_common( int timer_counter_init ); + + Timer* run_timer_ ( Timer* t, rel_time_t ); + Timer* run_timer ( Timer* t, rel_time_t ); + int dsp_read ( rel_time_t ); + void dsp_write ( int data, rel_time_t ); + void cpu_write_smp_reg_( int data, rel_time_t, int addr ); + void cpu_write_smp_reg ( int data, rel_time_t, int addr ); + void cpu_write_high ( int data, int i, rel_time_t ); + void cpu_write ( int data, int addr, rel_time_t ); + int cpu_read_smp_reg ( int i, rel_time_t ); + int cpu_read ( int addr, rel_time_t ); + unsigned CPU_mem_bit ( uint8_t const* pc, rel_time_t ); + + bool check_echo_access ( int addr ); + uint8_t* run_until_( time_t end_time ); + + struct spc_file_t + { + char signature [signature_size]; + uint8_t has_id666; + uint8_t version; + uint8_t pcl, pch; + uint8_t a; + uint8_t x; + uint8_t y; + uint8_t psw; + uint8_t sp; + char text [212]; + uint8_t ram [0x10000]; + uint8_t dsp [128]; + uint8_t unused [0x40]; + uint8_t ipl_rom [0x40]; + }; + + static char const signature [signature_size + 1]; + + void save_regs( uint8_t out [reg_count] ); +}; + +#include + +inline uint8_t* SNES_SPC::get_ram() { return m.ram.ram; } + +inline int SNES_SPC::sample_count() const { return (m.extra_clocks >> 5) * 2; } + +inline int SNES_SPC::read_port( time_t t, int port ) +{ + assert( (unsigned) port < port_count ); + return run_until_( t ) [port]; +} + +inline void SNES_SPC::write_port( time_t t, int port, int data ) +{ + assert( (unsigned) port < port_count ); + run_until_( t ) [0x10 + port] = data; +} + +inline void SNES_SPC::mute_voices( int mask ) { dsp.mute_voices( mask ); } + +inline void SNES_SPC::disable_surround( bool disable ) { dsp.disable_surround( disable ); } + +#if !SPC_NO_COPY_STATE_FUNCS +inline bool SNES_SPC::check_kon() { return dsp.check_kon(); } +#endif + +#endif diff --git a/waterbox/pizza/lib/snes_spc/SNES_SPC_misc.cpp b/waterbox/pizza/lib/snes_spc/SNES_SPC_misc.cpp new file mode 100644 index 0000000000..87288ab8ee --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/SNES_SPC_misc.cpp @@ -0,0 +1,380 @@ +// SPC emulation support: init, sample buffering, reset, SPC loading + +// snes_spc 0.9.0. http://www.slack.net/~ant/ + +#include "SNES_SPC.h" + +#include + +/* Copyright (C) 2004-2007 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "blargg_source.h" + +#define RAM (m.ram.ram) +#define REGS (m.smp_regs [0]) +#define REGS_IN (m.smp_regs [1]) + +// (n ? n : 256) +#define IF_0_THEN_256( n ) ((uint8_t) ((n) - 1) + 1) + + +//// Init + +blargg_err_t SNES_SPC::init() +{ + memset( &m, 0, sizeof m ); + dsp.init( RAM ); + + m.tempo = tempo_unit; + + // Most SPC music doesn't need ROM, and almost all the rest only rely + // on these two bytes + m.rom [0x3E] = 0xFF; + m.rom [0x3F] = 0xC0; + + static unsigned char const cycle_table [128] = + {// 01 23 45 67 89 AB CD EF + 0x28,0x47,0x34,0x36,0x26,0x54,0x54,0x68, // 0 + 0x48,0x47,0x45,0x56,0x55,0x65,0x22,0x46, // 1 + 0x28,0x47,0x34,0x36,0x26,0x54,0x54,0x74, // 2 + 0x48,0x47,0x45,0x56,0x55,0x65,0x22,0x38, // 3 + 0x28,0x47,0x34,0x36,0x26,0x44,0x54,0x66, // 4 + 0x48,0x47,0x45,0x56,0x55,0x45,0x22,0x43, // 5 + 0x28,0x47,0x34,0x36,0x26,0x44,0x54,0x75, // 6 + 0x48,0x47,0x45,0x56,0x55,0x55,0x22,0x36, // 7 + 0x28,0x47,0x34,0x36,0x26,0x54,0x52,0x45, // 8 + 0x48,0x47,0x45,0x56,0x55,0x55,0x22,0xC5, // 9 + 0x38,0x47,0x34,0x36,0x26,0x44,0x52,0x44, // A + 0x48,0x47,0x45,0x56,0x55,0x55,0x22,0x34, // B + 0x38,0x47,0x45,0x47,0x25,0x64,0x52,0x49, // C + 0x48,0x47,0x56,0x67,0x45,0x55,0x22,0x83, // D + 0x28,0x47,0x34,0x36,0x24,0x53,0x43,0x40, // E + 0x48,0x47,0x45,0x56,0x34,0x54,0x22,0x60, // F + }; + + // unpack cycle table + for ( int i = 0; i < 128; i++ ) + { + int n = cycle_table [i]; + m.cycle_table [i * 2 + 0] = n >> 4; + m.cycle_table [i * 2 + 1] = n & 0x0F; + } + + #if SPC_LESS_ACCURATE + memcpy( reg_times, reg_times_, sizeof reg_times ); + #endif + + reset(); + return 0; +} + +void SNES_SPC::init_rom( uint8_t const in [rom_size] ) +{ + memcpy( m.rom, in, sizeof m.rom ); +} + +void SNES_SPC::set_tempo( int t ) +{ + m.tempo = t; + int const timer2_shift = 4; // 64 kHz + int const other_shift = 3; // 8 kHz + + #if SPC_DISABLE_TEMPO + m.timers [2].prescaler = timer2_shift; + m.timers [1].prescaler = timer2_shift + other_shift; + m.timers [0].prescaler = timer2_shift + other_shift; + #else + if ( !t ) + t = 1; + int const timer2_rate = 1 << timer2_shift; + int rate = (timer2_rate * tempo_unit + (t >> 1)) / t; + if ( rate < timer2_rate / 4 ) + rate = timer2_rate / 4; // max 4x tempo + m.timers [2].prescaler = rate; + m.timers [1].prescaler = rate << other_shift; + m.timers [0].prescaler = rate << other_shift; + #endif +} + +// Timer registers have been loaded. Applies these to the timers. Does not +// reset timer prescalers or dividers. +void SNES_SPC::timers_loaded() +{ + int i; + for ( i = 0; i < timer_count; i++ ) + { + Timer* t = &m.timers [i]; + t->period = IF_0_THEN_256( REGS [r_t0target + i] ); + t->enabled = REGS [r_control] >> i & 1; + t->counter = REGS_IN [r_t0out + i] & 0x0F; + } + + set_tempo( m.tempo ); +} + +// Loads registers from unified 16-byte format +void SNES_SPC::load_regs( uint8_t const in [reg_count] ) +{ + memcpy( REGS, in, reg_count ); + memcpy( REGS_IN, REGS, reg_count ); + + // These always read back as 0 + REGS_IN [r_test ] = 0; + REGS_IN [r_control ] = 0; + REGS_IN [r_t0target] = 0; + REGS_IN [r_t1target] = 0; + REGS_IN [r_t2target] = 0; +} + +// RAM was just loaded from SPC, with $F0-$FF containing SMP registers +// and timer counts. Copies these to proper registers. +void SNES_SPC::ram_loaded() +{ + m.rom_enabled = 0; + load_regs( &RAM [0xF0] ); + + // Put STOP instruction around memory to catch PC underflow/overflow + memset( m.ram.padding1, cpu_pad_fill, sizeof m.ram.padding1 ); + memset( m.ram.padding2, cpu_pad_fill, sizeof m.ram.padding2 ); +} + +// Registers were just loaded. Applies these new values. +void SNES_SPC::regs_loaded() +{ + enable_rom( REGS [r_control] & 0x80 ); + timers_loaded(); +} + +void SNES_SPC::reset_time_regs() +{ + m.cpu_error = 0; + m.echo_accessed = 0; + m.spc_time = 0; + m.dsp_time = 0; + #if SPC_LESS_ACCURATE + m.dsp_time = clocks_per_sample + 1; + #endif + + for ( int i = 0; i < timer_count; i++ ) + { + Timer* t = &m.timers [i]; + t->next_time = 1; + t->divider = 0; + } + + regs_loaded(); + + m.extra_clocks = 0; + reset_buf(); +} + +void SNES_SPC::reset_common( int timer_counter_init ) +{ + int i; + for ( i = 0; i < timer_count; i++ ) + REGS_IN [r_t0out + i] = timer_counter_init; + + // Run IPL ROM + memset( &m.cpu_regs, 0, sizeof m.cpu_regs ); + m.cpu_regs.pc = rom_addr; + + REGS [r_test ] = 0x0A; + REGS [r_control] = 0xB0; // ROM enabled, clear ports + for ( i = 0; i < port_count; i++ ) + REGS_IN [r_cpuio0 + i] = 0; + + reset_time_regs(); +} + +void SNES_SPC::soft_reset() +{ + reset_common( 0 ); + dsp.soft_reset(); +} + +void SNES_SPC::reset() +{ + memset( RAM, 0xFF, 0x10000 ); + ram_loaded(); + reset_common( 0x0F ); + dsp.reset(); +} + +char const SNES_SPC::signature [signature_size + 1] = + "SNES-SPC700 Sound File Data v0.30\x1A\x1A"; + +blargg_err_t SNES_SPC::load_spc( void const* data, long size ) +{ + spc_file_t const* const spc = (spc_file_t const*) data; + + // be sure compiler didn't insert any padding into fle_t + assert( sizeof (spc_file_t) == spc_min_file_size + 0x80 ); + + // Check signature and file size + if ( size < signature_size || memcmp( spc, signature, 27 ) ) + return "Not an SPC file"; + + if ( size < spc_min_file_size ) + return "Corrupt SPC file"; + + // CPU registers + m.cpu_regs.pc = spc->pch * 0x100 + spc->pcl; + m.cpu_regs.a = spc->a; + m.cpu_regs.x = spc->x; + m.cpu_regs.y = spc->y; + m.cpu_regs.psw = spc->psw; + m.cpu_regs.sp = spc->sp; + + // RAM and registers + memcpy( RAM, spc->ram, 0x10000 ); + ram_loaded(); + + // DSP registers + dsp.load( spc->dsp ); + + reset_time_regs(); + + return 0; +} + +void SNES_SPC::clear_echo() +{ + if ( !(dsp.read( SPC_DSP::r_flg ) & 0x20) ) + { + int addr = 0x100 * dsp.read( SPC_DSP::r_esa ); + int end = addr + 0x800 * (dsp.read( SPC_DSP::r_edl ) & 0x0F); + if ( end > 0x10000 ) + end = 0x10000; + memset( &RAM [addr], 0xFF, end - addr ); + } +} + + +//// Sample output + +void SNES_SPC::reset_buf() +{ + // Start with half extra buffer of silence + sample_t* out = m.extra_buf; + while ( out < &m.extra_buf [extra_size / 2] ) + *out++ = 0; + + m.extra_pos = out; + m.buf_begin = 0; + + dsp.set_output( 0, 0 ); +} + +void SNES_SPC::set_output( sample_t* out, int size ) +{ + require( (size & 1) == 0 ); // size must be even + + m.extra_clocks &= clocks_per_sample - 1; + if ( out ) + { + sample_t const* out_end = out + size; + m.buf_begin = out; + m.buf_end = out_end; + + // Copy extra to output + sample_t const* in = m.extra_buf; + while ( in < m.extra_pos && out < out_end ) + *out++ = *in++; + + // Handle output being full already + if ( out >= out_end ) + { + // Have DSP write to remaining extra space + out = dsp.extra(); + out_end = &dsp.extra() [extra_size]; + + // Copy any remaining extra samples as if DSP wrote them + while ( in < m.extra_pos ) + *out++ = *in++; + assert( out <= out_end ); + } + + dsp.set_output( out, out_end - out ); + } + else + { + reset_buf(); + } +} + +void SNES_SPC::save_extra() +{ + // Get end pointers + sample_t const* main_end = m.buf_end; // end of data written to buf + sample_t const* dsp_end = dsp.out_pos(); // end of data written to dsp.extra() + if ( m.buf_begin <= dsp_end && dsp_end <= main_end ) + { + main_end = dsp_end; + dsp_end = dsp.extra(); // nothing in DSP's extra + } + + // Copy any extra samples at these ends into extra_buf + sample_t* out = m.extra_buf; + sample_t const* in; + for ( in = m.buf_begin + sample_count(); in < main_end; in++ ) + *out++ = *in; + for ( in = dsp.extra(); in < dsp_end ; in++ ) + *out++ = *in; + + m.extra_pos = out; + assert( out <= &m.extra_buf [extra_size] ); +} + +blargg_err_t SNES_SPC::play( int count, sample_t* out ) +{ + require( (count & 1) == 0 ); // must be even + if ( count ) + { + set_output( out, count ); + end_frame( count * (clocks_per_sample / 2) ); + } + + const char* err = m.cpu_error; + m.cpu_error = 0; + return err; +} + +blargg_err_t SNES_SPC::skip( int count ) +{ + #if SPC_LESS_ACCURATE + if ( count > 2 * sample_rate * 2 ) + { + set_output( 0, 0 ); + + // Skip a multiple of 4 samples + time_t end = count; + count = (count & 3) + 1 * sample_rate * 2; + end = (end - count) * (clocks_per_sample / 2); + + m.skipped_kon = 0; + m.skipped_koff = 0; + + // Preserve DSP and timer synchronization + // TODO: verify that this really preserves it + int old_dsp_time = m.dsp_time + m.spc_time; + m.dsp_time = end - m.spc_time + skipping_time; + end_frame( end ); + m.dsp_time = m.dsp_time - skipping_time + old_dsp_time; + + dsp.write( SPC_DSP::r_koff, m.skipped_koff & ~m.skipped_kon ); + dsp.write( SPC_DSP::r_kon , m.skipped_kon ); + clear_echo(); + } + #endif + + return play( count, 0 ); +} diff --git a/waterbox/pizza/lib/snes_spc/SNES_SPC_state.cpp b/waterbox/pizza/lib/snes_spc/SNES_SPC_state.cpp new file mode 100644 index 0000000000..a8052b6587 --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/SNES_SPC_state.cpp @@ -0,0 +1,129 @@ +// SPC emulation state save/load: copy_state(), save_spc() +// Separate file to avoid linking in unless needed + +// snes_spc 0.9.0. http://www.slack.net/~ant/ + +#include "SNES_SPC.h" + +#if !SPC_NO_COPY_STATE_FUNCS + +#include + +/* Copyright (C) 2004-2007 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "blargg_source.h" + +#define RAM (m.ram.ram) +#define REGS (m.smp_regs [0]) +#define REGS_IN (m.smp_regs [1]) + +void SNES_SPC::save_regs( uint8_t out [reg_count] ) +{ + // Use current timer counter values + for ( int i = 0; i < timer_count; i++ ) + out [r_t0out + i] = m.timers [i].counter; + + // Last written values + memcpy( out, REGS, r_t0out ); +} + +void SNES_SPC::init_header( void* spc_out ) +{ + spc_file_t* const spc = (spc_file_t*) spc_out; + + spc->has_id666 = 26; // has none + spc->version = 30; + memcpy( spc, signature, sizeof spc->signature ); + memset( spc->text, 0, sizeof spc->text ); +} + +void SNES_SPC::save_spc( void* spc_out ) +{ + spc_file_t* const spc = (spc_file_t*) spc_out; + + // CPU + spc->pcl = (uint8_t) (m.cpu_regs.pc >> 0); + spc->pch = (uint8_t) (m.cpu_regs.pc >> 8); + spc->a = m.cpu_regs.a; + spc->x = m.cpu_regs.x; + spc->y = m.cpu_regs.y; + spc->psw = m.cpu_regs.psw; + spc->sp = m.cpu_regs.sp; + + // RAM, ROM + memcpy( spc->ram, RAM, sizeof spc->ram ); + if ( m.rom_enabled ) + memcpy( spc->ram + rom_addr, m.hi_ram, sizeof m.hi_ram ); + memset( spc->unused, 0, sizeof spc->unused ); + memcpy( spc->ipl_rom, m.rom, sizeof spc->ipl_rom ); + + // SMP registers + save_regs( &spc->ram [0xF0] ); + int i; + for ( i = 0; i < port_count; i++ ) + spc->ram [0xF0 + r_cpuio0 + i] = REGS_IN [r_cpuio0 + i]; + + // DSP registers + for ( i = 0; i < SPC_DSP::register_count; i++ ) + spc->dsp [i] = dsp.read( i ); +} + +void SNES_SPC::copy_state( unsigned char** io, copy_func_t copy ) +{ + SPC_State_Copier copier( io, copy ); + + // Make state data more readable by putting 64K RAM, 16 SMP registers, + // then DSP (with its 128 registers) first + + // RAM + enable_rom( 0 ); // will get re-enabled if necessary in regs_loaded() below + copier.copy( RAM, 0x10000 ); + + { + // SMP registers + uint8_t out_ports [port_count]; + uint8_t regs [reg_count]; + memcpy( out_ports, ®S [r_cpuio0], sizeof out_ports ); + save_regs( regs ); + copier.copy( regs, sizeof regs ); + copier.copy( out_ports, sizeof out_ports ); + load_regs( regs ); + regs_loaded(); + memcpy( ®S [r_cpuio0], out_ports, sizeof out_ports ); + } + + // CPU registers + SPC_COPY( uint16_t, m.cpu_regs.pc ); + SPC_COPY( uint8_t, m.cpu_regs.a ); + SPC_COPY( uint8_t, m.cpu_regs.x ); + SPC_COPY( uint8_t, m.cpu_regs.y ); + SPC_COPY( uint8_t, m.cpu_regs.psw ); + SPC_COPY( uint8_t, m.cpu_regs.sp ); + copier.extra(); + + SPC_COPY( int16_t, m.spc_time ); + SPC_COPY( int16_t, m.dsp_time ); + + // DSP + dsp.copy_state( io, copy ); + + // Timers + for ( int i = 0; i < timer_count; i++ ) + { + Timer* t = &m.timers [i]; + SPC_COPY( int16_t, t->next_time ); + SPC_COPY( uint8_t, t->divider ); + copier.extra(); + } + copier.extra(); +} +#endif diff --git a/waterbox/pizza/lib/snes_spc/SPC_CPU.h b/waterbox/pizza/lib/snes_spc/SPC_CPU.h new file mode 100644 index 0000000000..664fc4886e --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/SPC_CPU.h @@ -0,0 +1,1220 @@ +// snes_spc 0.9.0. http://www.slack.net/~ant/ + +/* Copyright (C) 2004-2007 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +//// Memory access + +#if SPC_MORE_ACCURACY + #define SUSPICIOUS_OPCODE( name ) ((void) 0) +#else + #define SUSPICIOUS_OPCODE( name ) dprintf( "SPC: suspicious opcode: " name "\n" ) +#endif + +#define CPU_READ( time, offset, addr )\ + cpu_read( addr, time + offset ) + +#define CPU_WRITE( time, offset, addr, data )\ + cpu_write( data, addr, time + offset ) + +#if SPC_MORE_ACCURACY + #define CPU_READ_TIMER( time, offset, addr, out )\ + { out = CPU_READ( time, offset, addr ); } + +#else + // timers are by far the most common thing read from dp + #define CPU_READ_TIMER( time, offset, addr_, out )\ + {\ + rel_time_t adj_time = time + offset;\ + int dp_addr = addr_;\ + int ti = dp_addr - (r_t0out + 0xF0);\ + if ( (unsigned) ti < timer_count )\ + {\ + Timer* t = &m.timers [ti];\ + if ( adj_time >= t->next_time )\ + t = run_timer_( t, adj_time );\ + out = t->counter;\ + t->counter = 0;\ + }\ + else\ + {\ + out = ram [dp_addr];\ + int i = dp_addr - 0xF0;\ + if ( (unsigned) i < 0x10 )\ + out = cpu_read_smp_reg( i, adj_time );\ + }\ + } +#endif + +#define TIME_ADJ( n ) (n) + +#define READ_TIMER( time, addr, out ) CPU_READ_TIMER( rel_time, TIME_ADJ(time), (addr), out ) +#define READ( time, addr ) CPU_READ ( rel_time, TIME_ADJ(time), (addr) ) +#define WRITE( time, addr, data ) CPU_WRITE( rel_time, TIME_ADJ(time), (addr), (data) ) + +#define DP_ADDR( addr ) (dp + (addr)) + +#define READ_DP_TIMER( time, addr, out ) CPU_READ_TIMER( rel_time, TIME_ADJ(time), DP_ADDR( addr ), out ) +#define READ_DP( time, addr ) READ ( time, DP_ADDR( addr ) ) +#define WRITE_DP( time, addr, data ) WRITE( time, DP_ADDR( addr ), data ) + +#define READ_PROG16( addr ) GET_LE16( ram + (addr) ) + +#define SET_PC( n ) (pc = ram + (n)) +#define GET_PC() (pc - ram) +#define READ_PC( pc ) (*(pc)) +#define READ_PC16( pc ) GET_LE16( pc ) + +// TODO: remove non-wrapping versions? +#define SPC_NO_SP_WRAPAROUND 0 + +#define SET_SP( v ) (sp = ram + 0x101 + (v)) +#define GET_SP() (sp - 0x101 - ram) + +#if SPC_NO_SP_WRAPAROUND +#define PUSH16( v ) (sp -= 2, SET_LE16( sp, v )) +#define PUSH( v ) (void) (*--sp = (uint8_t) (v)) +#define POP( out ) (void) ((out) = *sp++) + +#else +#define PUSH16( data )\ +{\ + int addr = (sp -= 2) - ram;\ + if ( addr > 0x100 )\ + {\ + SET_LE16( sp, data );\ + }\ + else\ + {\ + ram [(uint8_t) addr + 0x100] = (uint8_t) data;\ + sp [1] = (uint8_t) (data >> 8);\ + sp += 0x100;\ + }\ +} + +#define PUSH( data )\ +{\ + *--sp = (uint8_t) (data);\ + if ( sp - ram == 0x100 )\ + sp += 0x100;\ +} + +#define POP( out )\ +{\ + out = *sp++;\ + if ( sp - ram == 0x201 )\ + {\ + out = sp [-0x101];\ + sp -= 0x100;\ + }\ +} + +#endif + +#define MEM_BIT( rel ) CPU_mem_bit( pc, rel_time + rel ) + +unsigned SNES_SPC::CPU_mem_bit( uint8_t const* pc, rel_time_t rel_time ) +{ + unsigned addr = READ_PC16( pc ); + unsigned t = READ( 0, addr & 0x1FFF ) >> (addr >> 13); + return t << 8 & 0x100; +} + +//// Status flag handling + +// Hex value in name to clarify code and bit shifting. +// Flag stored in indicated variable during emulation +int const n80 = 0x80; // nz +int const v40 = 0x40; // psw +int const p20 = 0x20; // dp +int const b10 = 0x10; // psw +int const h08 = 0x08; // psw +int const i04 = 0x04; // psw +int const z02 = 0x02; // nz +int const c01 = 0x01; // c + +int const nz_neg_mask = 0x880; // either bit set indicates N flag set + +#define GET_PSW( out )\ +{\ + out = psw & ~(n80 | p20 | z02 | c01);\ + out |= c >> 8 & c01;\ + out |= dp >> 3 & p20;\ + out |= ((nz >> 4) | nz) & n80;\ + if ( !(uint8_t) nz ) out |= z02;\ +} + +#define SET_PSW( in )\ +{\ + psw = in;\ + c = in << 8;\ + dp = in << 3 & 0x100;\ + nz = (in << 4 & 0x800) | (~in & z02);\ +} + +SPC_CPU_RUN_FUNC +{ + uint8_t* const ram = RAM; + int a = m.cpu_regs.a; + int x = m.cpu_regs.x; + int y = m.cpu_regs.y; + uint8_t const* pc; + uint8_t* sp; + int psw; + int c; + int nz; + int dp; + + SET_PC( m.cpu_regs.pc ); + SET_SP( m.cpu_regs.sp ); + SET_PSW( m.cpu_regs.psw ); + + goto loop; + + + // Main loop + +cbranch_taken_loop: + pc += *(BOOST::int8_t const*) pc; +inc_pc_loop: + pc++; +loop: +{ + unsigned opcode; + unsigned data; + + check( (unsigned) a < 0x100 ); + check( (unsigned) x < 0x100 ); + check( (unsigned) y < 0x100 ); + + opcode = *pc; + if ( (rel_time += m.cycle_table [opcode]) > 0 ) + goto out_of_time; + + #ifdef SPC_CPU_OPCODE_HOOK + SPC_CPU_OPCODE_HOOK( GET_PC(), opcode ); + #endif + /* + //SUB_CASE_COUNTER( 1 ); + #define PROFILE_TIMER_LOOP( op, addr, len )\ + if ( opcode == op )\ + {\ + int cond = (unsigned) ((addr) - 0xFD) < 3 &&\ + pc [len] == 0xF0 && pc [len+1] == 0xFE - len;\ + SUB_CASE_COUNTER( op && cond );\ + } + + PROFILE_TIMER_LOOP( 0xEC, GET_LE16( pc + 1 ), 3 ); + PROFILE_TIMER_LOOP( 0xEB, pc [1], 2 ); + PROFILE_TIMER_LOOP( 0xE4, pc [1], 2 ); + */ + + // TODO: if PC is at end of memory, this will get wrong operand (very obscure) + data = *++pc; + switch ( opcode ) + { + +// Common instructions + +#define BRANCH( cond )\ +{\ + pc++;\ + pc += (BOOST::int8_t) data;\ + if ( cond )\ + goto loop;\ + pc -= (BOOST::int8_t) data;\ + rel_time -= 2;\ + goto loop;\ +} + + case 0xF0: // BEQ + BRANCH( !(uint8_t) nz ) // 89% taken + + case 0xD0: // BNE + BRANCH( (uint8_t) nz ) + + case 0x3F:{// CALL + int old_addr = GET_PC() + 2; + SET_PC( READ_PC16( pc ) ); + PUSH16( old_addr ); + goto loop; + } + + case 0x6F:// RET + #if SPC_NO_SP_WRAPAROUND + { + SET_PC( GET_LE16( sp ) ); + sp += 2; + } + #else + { + int addr = sp - ram; + SET_PC( GET_LE16( sp ) ); + sp += 2; + if ( addr < 0x1FF ) + goto loop; + + SET_PC( sp [-0x101] * 0x100 + ram [(uint8_t) addr + 0x100] ); + sp -= 0x100; + } + #endif + goto loop; + + case 0xE4: // MOV a,dp + ++pc; + // 80% from timer + READ_DP_TIMER( 0, data, a = nz ); + goto loop; + + case 0xFA:{// MOV dp,dp + int temp; + READ_DP_TIMER( -2, data, temp ); + data = temp + no_read_before_write ; + } + // fall through + case 0x8F:{// MOV dp,#imm + int temp = READ_PC( pc + 1 ); + pc += 2; + + #if !SPC_MORE_ACCURACY + { + int i = dp + temp; + ram [i] = (uint8_t) data; + i -= 0xF0; + if ( (unsigned) i < 0x10 ) // 76% + { + REGS [i] = (uint8_t) data; + + // Registers other than $F2 and $F4-$F7 + //if ( i != 2 && i != 4 && i != 5 && i != 6 && i != 7 ) + if ( ((~0x2F00 << (bits_in_int - 16)) << i) < 0 ) // 12% + cpu_write_smp_reg( data, rel_time, i ); + } + } + #else + WRITE_DP( 0, temp, data ); + #endif + goto loop; + } + + case 0xC4: // MOV dp,a + ++pc; + #if !SPC_MORE_ACCURACY + { + int i = dp + data; + ram [i] = (uint8_t) a; + i -= 0xF0; + if ( (unsigned) i < 0x10 ) // 39% + { + unsigned sel = i - 2; + REGS [i] = (uint8_t) a; + + if ( sel == 1 ) // 51% $F3 + dsp_write( a, rel_time ); + else if ( sel > 1 ) // 1% not $F2 or $F3 + cpu_write_smp_reg_( a, rel_time, i ); + } + } + #else + WRITE_DP( 0, data, a ); + #endif + goto loop; + +#define CASE( n ) case n: + +// Define common address modes based on opcode for immediate mode. Execution +// ends with data set to the address of the operand. +#define ADDR_MODES_( op )\ + CASE( op - 0x02 ) /* (X) */\ + data = x + dp;\ + pc--;\ + goto end_##op;\ + CASE( op + 0x0F ) /* (dp)+Y */\ + data = READ_PROG16( data + dp ) + y;\ + goto end_##op;\ + CASE( op - 0x01 ) /* (dp+X) */\ + data = READ_PROG16( ((uint8_t) (data + x)) + dp );\ + goto end_##op;\ + CASE( op + 0x0E ) /* abs+Y */\ + data += y;\ + goto abs_##op;\ + CASE( op + 0x0D ) /* abs+X */\ + data += x;\ + CASE( op - 0x03 ) /* abs */\ + abs_##op:\ + data += 0x100 * READ_PC( ++pc );\ + goto end_##op;\ + CASE( op + 0x0C ) /* dp+X */\ + data = (uint8_t) (data + x); + +#define ADDR_MODES_NO_DP( op )\ + ADDR_MODES_( op )\ + data += dp;\ + end_##op: + +#define ADDR_MODES( op )\ + ADDR_MODES_( op )\ + CASE( op - 0x04 ) /* dp */\ + data += dp;\ + end_##op: + +// 1. 8-bit Data Transmission Commands. Group I + + ADDR_MODES_NO_DP( 0xE8 ) // MOV A,addr + a = nz = READ( 0, data ); + goto inc_pc_loop; + + case 0xBF:{// MOV A,(X)+ + int temp = x + dp; + x = (uint8_t) (x + 1); + a = nz = READ( -1, temp ); + goto loop; + } + + case 0xE8: // MOV A,imm + a = data; + nz = data; + goto inc_pc_loop; + + case 0xF9: // MOV X,dp+Y + data = (uint8_t) (data + y); + case 0xF8: // MOV X,dp + READ_DP_TIMER( 0, data, x = nz ); + goto inc_pc_loop; + + case 0xE9: // MOV X,abs + data = READ_PC16( pc ); + ++pc; + data = READ( 0, data ); + case 0xCD: // MOV X,imm + x = data; + nz = data; + goto inc_pc_loop; + + case 0xFB: // MOV Y,dp+X + data = (uint8_t) (data + x); + case 0xEB: // MOV Y,dp + // 70% from timer + pc++; + READ_DP_TIMER( 0, data, y = nz ); + goto loop; + + case 0xEC:{// MOV Y,abs + int temp = READ_PC16( pc ); + pc += 2; + READ_TIMER( 0, temp, y = nz ); + //y = nz = READ( 0, temp ); + goto loop; + } + + case 0x8D: // MOV Y,imm + y = data; + nz = data; + goto inc_pc_loop; + +// 2. 8-BIT DATA TRANSMISSION COMMANDS, GROUP 2 + + ADDR_MODES_NO_DP( 0xC8 ) // MOV addr,A + WRITE( 0, data, a ); + goto inc_pc_loop; + + { + int temp; + case 0xCC: // MOV abs,Y + temp = y; + goto mov_abs_temp; + case 0xC9: // MOV abs,X + temp = x; + mov_abs_temp: + WRITE( 0, READ_PC16( pc ), temp ); + pc += 2; + goto loop; + } + + case 0xD9: // MOV dp+Y,X + data = (uint8_t) (data + y); + case 0xD8: // MOV dp,X + WRITE( 0, data + dp, x ); + goto inc_pc_loop; + + case 0xDB: // MOV dp+X,Y + data = (uint8_t) (data + x); + case 0xCB: // MOV dp,Y + WRITE( 0, data + dp, y ); + goto inc_pc_loop; + +// 3. 8-BIT DATA TRANSMISSIN COMMANDS, GROUP 3. + + case 0x7D: // MOV A,X + a = x; + nz = x; + goto loop; + + case 0xDD: // MOV A,Y + a = y; + nz = y; + goto loop; + + case 0x5D: // MOV X,A + x = a; + nz = a; + goto loop; + + case 0xFD: // MOV Y,A + y = a; + nz = a; + goto loop; + + case 0x9D: // MOV X,SP + x = nz = GET_SP(); + goto loop; + + case 0xBD: // MOV SP,X + SET_SP( x ); + goto loop; + + //case 0xC6: // MOV (X),A (handled by MOV addr,A in group 2) + + case 0xAF: // MOV (X)+,A + WRITE_DP( 0, x, a + no_read_before_write ); + x++; + goto loop; + +// 5. 8-BIT LOGIC OPERATION COMMANDS + +#define LOGICAL_OP( op, func )\ + ADDR_MODES( op ) /* addr */\ + data = READ( 0, data );\ + case op: /* imm */\ + nz = a func##= data;\ + goto inc_pc_loop;\ + { unsigned addr;\ + case op + 0x11: /* X,Y */\ + data = READ_DP( -2, y );\ + addr = x + dp;\ + goto addr_##op;\ + case op + 0x01: /* dp,dp */\ + data = READ_DP( -3, data );\ + case op + 0x10:{/*dp,imm*/\ + uint8_t const* addr2 = pc + 1;\ + pc += 2;\ + addr = READ_PC( addr2 ) + dp;\ + }\ + addr_##op:\ + nz = data func READ( -1, addr );\ + WRITE( 0, addr, nz );\ + goto loop;\ + } + + LOGICAL_OP( 0x28, & ); // AND + + LOGICAL_OP( 0x08, | ); // OR + + LOGICAL_OP( 0x48, ^ ); // EOR + +// 4. 8-BIT ARITHMETIC OPERATION COMMANDS + + ADDR_MODES( 0x68 ) // CMP addr + data = READ( 0, data ); + case 0x68: // CMP imm + nz = a - data; + c = ~nz; + nz &= 0xFF; + goto inc_pc_loop; + + case 0x79: // CMP (X),(Y) + data = READ_DP( -2, y ); + nz = READ_DP( -1, x ) - data; + c = ~nz; + nz &= 0xFF; + goto loop; + + case 0x69: // CMP dp,dp + data = READ_DP( -3, data ); + case 0x78: // CMP dp,imm + nz = READ_DP( -1, READ_PC( ++pc ) ) - data; + c = ~nz; + nz &= 0xFF; + goto inc_pc_loop; + + case 0x3E: // CMP X,dp + data += dp; + goto cmp_x_addr; + case 0x1E: // CMP X,abs + data = READ_PC16( pc ); + pc++; + cmp_x_addr: + data = READ( 0, data ); + case 0xC8: // CMP X,imm + nz = x - data; + c = ~nz; + nz &= 0xFF; + goto inc_pc_loop; + + case 0x7E: // CMP Y,dp + data += dp; + goto cmp_y_addr; + case 0x5E: // CMP Y,abs + data = READ_PC16( pc ); + pc++; + cmp_y_addr: + data = READ( 0, data ); + case 0xAD: // CMP Y,imm + nz = y - data; + c = ~nz; + nz &= 0xFF; + goto inc_pc_loop; + + { + int addr; + case 0xB9: // SBC (x),(y) + case 0x99: // ADC (x),(y) + pc--; // compensate for inc later + data = READ_DP( -2, y ); + addr = x + dp; + goto adc_addr; + case 0xA9: // SBC dp,dp + case 0x89: // ADC dp,dp + data = READ_DP( -3, data ); + case 0xB8: // SBC dp,imm + case 0x98: // ADC dp,imm + addr = READ_PC( ++pc ) + dp; + adc_addr: + nz = READ( -1, addr ); + goto adc_data; + +// catch ADC and SBC together, then decode later based on operand +#undef CASE +#define CASE( n ) case n: case (n) + 0x20: + ADDR_MODES( 0x88 ) // ADC/SBC addr + data = READ( 0, data ); + case 0xA8: // SBC imm + case 0x88: // ADC imm + addr = -1; // A + nz = a; + adc_data: { + int flags; + if ( opcode >= 0xA0 ) // SBC + data ^= 0xFF; + + flags = data ^ nz; + nz += data + (c >> 8 & 1); + flags ^= nz; + + psw = (psw & ~(v40 | h08)) | + (flags >> 1 & h08) | + ((flags + 0x80) >> 2 & v40); + c = nz; + if ( addr < 0 ) + { + a = (uint8_t) nz; + goto inc_pc_loop; + } + WRITE( 0, addr, /*(uint8_t)*/ nz ); + goto inc_pc_loop; + } + + } + +// 6. ADDITION & SUBTRACTION COMMANDS + +#define INC_DEC_REG( reg, op )\ + nz = reg op;\ + reg = (uint8_t) nz;\ + goto loop; + + case 0xBC: INC_DEC_REG( a, + 1 ) // INC A + case 0x3D: INC_DEC_REG( x, + 1 ) // INC X + case 0xFC: INC_DEC_REG( y, + 1 ) // INC Y + + case 0x9C: INC_DEC_REG( a, - 1 ) // DEC A + case 0x1D: INC_DEC_REG( x, - 1 ) // DEC X + case 0xDC: INC_DEC_REG( y, - 1 ) // DEC Y + + case 0x9B: // DEC dp+X + case 0xBB: // INC dp+X + data = (uint8_t) (data + x); + case 0x8B: // DEC dp + case 0xAB: // INC dp + data += dp; + goto inc_abs; + case 0x8C: // DEC abs + case 0xAC: // INC abs + data = READ_PC16( pc ); + pc++; + inc_abs: + nz = (opcode >> 4 & 2) - 1; + nz += READ( -1, data ); + WRITE( 0, data, /*(uint8_t)*/ nz ); + goto inc_pc_loop; + +// 7. SHIFT, ROTATION COMMANDS + + case 0x5C: // LSR A + c = 0; + case 0x7C:{// ROR A + nz = (c >> 1 & 0x80) | (a >> 1); + c = a << 8; + a = nz; + goto loop; + } + + case 0x1C: // ASL A + c = 0; + case 0x3C:{// ROL A + int temp = c >> 8 & 1; + c = a << 1; + nz = c | temp; + a = (uint8_t) nz; + goto loop; + } + + case 0x0B: // ASL dp + c = 0; + data += dp; + goto rol_mem; + case 0x1B: // ASL dp+X + c = 0; + case 0x3B: // ROL dp+X + data = (uint8_t) (data + x); + case 0x2B: // ROL dp + data += dp; + goto rol_mem; + case 0x0C: // ASL abs + c = 0; + case 0x2C: // ROL abs + data = READ_PC16( pc ); + pc++; + rol_mem: + nz = c >> 8 & 1; + nz |= (c = READ( -1, data ) << 1); + WRITE( 0, data, /*(uint8_t)*/ nz ); + goto inc_pc_loop; + + case 0x4B: // LSR dp + c = 0; + data += dp; + goto ror_mem; + case 0x5B: // LSR dp+X + c = 0; + case 0x7B: // ROR dp+X + data = (uint8_t) (data + x); + case 0x6B: // ROR dp + data += dp; + goto ror_mem; + case 0x4C: // LSR abs + c = 0; + case 0x6C: // ROR abs + data = READ_PC16( pc ); + pc++; + ror_mem: { + int temp = READ( -1, data ); + nz = (c >> 1 & 0x80) | (temp >> 1); + c = temp << 8; + WRITE( 0, data, nz ); + goto inc_pc_loop; + } + + case 0x9F: // XCN + nz = a = (a >> 4) | (uint8_t) (a << 4); + goto loop; + +// 8. 16-BIT TRANSMISION COMMANDS + + case 0xBA: // MOVW YA,dp + a = READ_DP( -2, data ); + nz = (a & 0x7F) | (a >> 1); + y = READ_DP( 0, (uint8_t) (data + 1) ); + nz |= y; + goto inc_pc_loop; + + case 0xDA: // MOVW dp,YA + WRITE_DP( -1, data, a ); + WRITE_DP( 0, (uint8_t) (data + 1), y + no_read_before_write ); + goto inc_pc_loop; + +// 9. 16-BIT OPERATION COMMANDS + + case 0x3A: // INCW dp + case 0x1A:{// DECW dp + int temp; + // low byte + data += dp; + temp = READ( -3, data ); + temp += (opcode >> 4 & 2) - 1; // +1 for INCW, -1 for DECW + nz = ((temp >> 1) | temp) & 0x7F; + WRITE( -2, data, /*(uint8_t)*/ temp ); + + // high byte + data = (uint8_t) (data + 1) + dp; + temp = (uint8_t) ((temp >> 8) + READ( -1, data )); + nz |= temp; + WRITE( 0, data, temp ); + + goto inc_pc_loop; + } + + case 0x7A: // ADDW YA,dp + case 0x9A:{// SUBW YA,dp + int lo = READ_DP( -2, data ); + int hi = READ_DP( 0, (uint8_t) (data + 1) ); + int result; + int flags; + + if ( opcode == 0x9A ) // SUBW + { + lo = (lo ^ 0xFF) + 1; + hi ^= 0xFF; + } + + lo += a; + result = y + hi + (lo >> 8); + flags = hi ^ y ^ result; + + psw = (psw & ~(v40 | h08)) | + (flags >> 1 & h08) | + ((flags + 0x80) >> 2 & v40); + c = result; + a = (uint8_t) lo; + result = (uint8_t) result; + y = result; + nz = (((lo >> 1) | lo) & 0x7F) | result; + + goto inc_pc_loop; + } + + case 0x5A: { // CMPW YA,dp + int temp = a - READ_DP( -1, data ); + nz = ((temp >> 1) | temp) & 0x7F; + temp = y + (temp >> 8); + temp -= READ_DP( 0, (uint8_t) (data + 1) ); + nz |= temp; + c = ~temp; + nz &= 0xFF; + goto inc_pc_loop; + } + +// 10. MULTIPLICATION & DIVISON COMMANDS + + case 0xCF: { // MUL YA + unsigned temp = y * a; + a = (uint8_t) temp; + nz = ((temp >> 1) | temp) & 0x7F; + y = temp >> 8; + nz |= y; + goto loop; + } + + case 0x9E: // DIV YA,X + { + unsigned ya = y * 0x100 + a; + + psw &= ~(h08 | v40); + + if ( y >= x ) + psw |= v40; + + if ( (y & 15) >= (x & 15) ) + psw |= h08; + + if ( y < x * 2 ) + { + a = ya / x; + y = ya - a * x; + } + else + { + a = 255 - (ya - x * 0x200) / (256 - x); + y = x + (ya - x * 0x200) % (256 - x); + } + + nz = (uint8_t) a; + a = (uint8_t) a; + + goto loop; + } + +// 11. DECIMAL COMPENSATION COMMANDS + + case 0xDF: // DAA + SUSPICIOUS_OPCODE( "DAA" ); + if ( a > 0x99 || c & 0x100 ) + { + a += 0x60; + c = 0x100; + } + + if ( (a & 0x0F) > 9 || psw & h08 ) + a += 0x06; + + nz = a; + a = (uint8_t) a; + goto loop; + + case 0xBE: // DAS + SUSPICIOUS_OPCODE( "DAS" ); + if ( a > 0x99 || !(c & 0x100) ) + { + a -= 0x60; + c = 0; + } + + if ( (a & 0x0F) > 9 || !(psw & h08) ) + a -= 0x06; + + nz = a; + a = (uint8_t) a; + goto loop; + +// 12. BRANCHING COMMANDS + + case 0x2F: // BRA rel + pc += (BOOST::int8_t) data; + goto inc_pc_loop; + + case 0x30: // BMI + BRANCH( (nz & nz_neg_mask) ) + + case 0x10: // BPL + BRANCH( !(nz & nz_neg_mask) ) + + case 0xB0: // BCS + BRANCH( c & 0x100 ) + + case 0x90: // BCC + BRANCH( !(c & 0x100) ) + + case 0x70: // BVS + BRANCH( psw & v40 ) + + case 0x50: // BVC + BRANCH( !(psw & v40) ) + + #define CBRANCH( cond )\ + {\ + pc++;\ + if ( cond )\ + goto cbranch_taken_loop;\ + rel_time -= 2;\ + goto inc_pc_loop;\ + } + + case 0x03: // BBS dp.bit,rel + case 0x23: + case 0x43: + case 0x63: + case 0x83: + case 0xA3: + case 0xC3: + case 0xE3: + CBRANCH( READ_DP( -4, data ) >> (opcode >> 5) & 1 ) + + case 0x13: // BBC dp.bit,rel + case 0x33: + case 0x53: + case 0x73: + case 0x93: + case 0xB3: + case 0xD3: + case 0xF3: + CBRANCH( !(READ_DP( -4, data ) >> (opcode >> 5) & 1) ) + + case 0xDE: // CBNE dp+X,rel + data = (uint8_t) (data + x); + // fall through + case 0x2E:{// CBNE dp,rel + int temp; + // 61% from timer + READ_DP_TIMER( -4, data, temp ); + CBRANCH( temp != a ) + } + + case 0x6E: { // DBNZ dp,rel + unsigned temp = READ_DP( -4, data ) - 1; + WRITE_DP( -3, (uint8_t) data, /*(uint8_t)*/ temp + no_read_before_write ); + CBRANCH( temp ) + } + + case 0xFE: // DBNZ Y,rel + y = (uint8_t) (y - 1); + BRANCH( y ) + + case 0x1F: // JMP [abs+X] + SET_PC( READ_PC16( pc ) + x ); + // fall through + case 0x5F: // JMP abs + SET_PC( READ_PC16( pc ) ); + goto loop; + +// 13. SUB-ROUTINE CALL RETURN COMMANDS + + case 0x0F:{// BRK + int temp; + int ret_addr = GET_PC(); + SUSPICIOUS_OPCODE( "BRK" ); + SET_PC( READ_PROG16( 0xFFDE ) ); // vector address verified + PUSH16( ret_addr ); + GET_PSW( temp ); + psw = (psw | b10) & ~i04; + PUSH( temp ); + goto loop; + } + + case 0x4F:{// PCALL offset + int ret_addr = GET_PC() + 1; + SET_PC( 0xFF00 | data ); + PUSH16( ret_addr ); + goto loop; + } + + case 0x01: // TCALL n + case 0x11: + case 0x21: + case 0x31: + case 0x41: + case 0x51: + case 0x61: + case 0x71: + case 0x81: + case 0x91: + case 0xA1: + case 0xB1: + case 0xC1: + case 0xD1: + case 0xE1: + case 0xF1: { + int ret_addr = GET_PC(); + SET_PC( READ_PROG16( 0xFFDE - (opcode >> 3) ) ); + PUSH16( ret_addr ); + goto loop; + } + +// 14. STACK OPERATION COMMANDS + + { + int temp; + case 0x7F: // RET1 + temp = *sp; + SET_PC( GET_LE16( sp + 1 ) ); + sp += 3; + goto set_psw; + case 0x8E: // POP PSW + POP( temp ); + set_psw: + SET_PSW( temp ); + goto loop; + } + + case 0x0D: { // PUSH PSW + int temp; + GET_PSW( temp ); + PUSH( temp ); + goto loop; + } + + case 0x2D: // PUSH A + PUSH( a ); + goto loop; + + case 0x4D: // PUSH X + PUSH( x ); + goto loop; + + case 0x6D: // PUSH Y + PUSH( y ); + goto loop; + + case 0xAE: // POP A + POP( a ); + goto loop; + + case 0xCE: // POP X + POP( x ); + goto loop; + + case 0xEE: // POP Y + POP( y ); + goto loop; + +// 15. BIT OPERATION COMMANDS + + case 0x02: // SET1 + case 0x22: + case 0x42: + case 0x62: + case 0x82: + case 0xA2: + case 0xC2: + case 0xE2: + case 0x12: // CLR1 + case 0x32: + case 0x52: + case 0x72: + case 0x92: + case 0xB2: + case 0xD2: + case 0xF2: { + int bit = 1 << (opcode >> 5); + int mask = ~bit; + if ( opcode & 0x10 ) + bit = 0; + data += dp; + WRITE( 0, data, (READ( -1, data ) & mask) | bit ); + goto inc_pc_loop; + } + + case 0x0E: // TSET1 abs + case 0x4E: // TCLR1 abs + data = READ_PC16( pc ); + pc += 2; + { + unsigned temp = READ( -2, data ); + nz = (uint8_t) (a - temp); + temp &= ~a; + if ( opcode == 0x0E ) + temp |= a; + WRITE( 0, data, temp ); + } + goto loop; + + case 0x4A: // AND1 C,mem.bit + c &= MEM_BIT( 0 ); + pc += 2; + goto loop; + + case 0x6A: // AND1 C,/mem.bit + c &= ~MEM_BIT( 0 ); + pc += 2; + goto loop; + + case 0x0A: // OR1 C,mem.bit + c |= MEM_BIT( -1 ); + pc += 2; + goto loop; + + case 0x2A: // OR1 C,/mem.bit + c |= ~MEM_BIT( -1 ); + pc += 2; + goto loop; + + case 0x8A: // EOR1 C,mem.bit + c ^= MEM_BIT( -1 ); + pc += 2; + goto loop; + + case 0xEA: // NOT1 mem.bit + data = READ_PC16( pc ); + pc += 2; + { + unsigned temp = READ( -1, data & 0x1FFF ); + temp ^= 1 << (data >> 13); + WRITE( 0, data & 0x1FFF, temp ); + } + goto loop; + + case 0xCA: // MOV1 mem.bit,C + data = READ_PC16( pc ); + pc += 2; + { + unsigned temp = READ( -2, data & 0x1FFF ); + unsigned bit = data >> 13; + temp = (temp & ~(1 << bit)) | ((c >> 8 & 1) << bit); + WRITE( 0, data & 0x1FFF, temp + no_read_before_write ); + } + goto loop; + + case 0xAA: // MOV1 C,mem.bit + c = MEM_BIT( 0 ); + pc += 2; + goto loop; + +// 16. PROGRAM PSW FLAG OPERATION COMMANDS + + case 0x60: // CLRC + c = 0; + goto loop; + + case 0x80: // SETC + c = ~0; + goto loop; + + case 0xED: // NOTC + c ^= 0x100; + goto loop; + + case 0xE0: // CLRV + psw &= ~(v40 | h08); + goto loop; + + case 0x20: // CLRP + dp = 0; + goto loop; + + case 0x40: // SETP + dp = 0x100; + goto loop; + + case 0xA0: // EI + SUSPICIOUS_OPCODE( "EI" ); + psw |= i04; + goto loop; + + case 0xC0: // DI + SUSPICIOUS_OPCODE( "DI" ); + psw &= ~i04; + goto loop; + +// 17. OTHER COMMANDS + + case 0x00: // NOP + goto loop; + + case 0xFF:{// STOP + // handle PC wrap-around + unsigned addr = GET_PC() - 1; + if ( addr >= 0x10000 ) + { + addr &= 0xFFFF; + SET_PC( addr ); + dprintf( "SPC: PC wrapped around\n" ); + goto loop; + } + } + // fall through + case 0xEF: // SLEEP + SUSPICIOUS_OPCODE( "STOP/SLEEP" ); + --pc; + rel_time = 0; + m.cpu_error = "SPC emulation error"; + goto stop; + } // switch + + assert( 0 ); // catch any unhandled instructions +} +out_of_time: + rel_time -= m.cycle_table [*pc]; // undo partial execution of opcode +stop: + + // Uncache registers + if ( GET_PC() >= 0x10000 ) + dprintf( "SPC: PC wrapped around\n" ); + m.cpu_regs.pc = (uint16_t) GET_PC(); + m.cpu_regs.sp = ( uint8_t) GET_SP(); + m.cpu_regs.a = ( uint8_t) a; + m.cpu_regs.x = ( uint8_t) x; + m.cpu_regs.y = ( uint8_t) y; + { + int temp; + GET_PSW( temp ); + m.cpu_regs.psw = (uint8_t) temp; + } +} +SPC_CPU_RUN_FUNC_END diff --git a/waterbox/pizza/lib/snes_spc/SPC_DSP.cpp b/waterbox/pizza/lib/snes_spc/SPC_DSP.cpp new file mode 100644 index 0000000000..dd180506fc --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/SPC_DSP.cpp @@ -0,0 +1,1018 @@ +// snes_spc 0.9.0. http://www.slack.net/~ant/ + +#include "SPC_DSP.h" + +#include "blargg_endian.h" +#include + +/* Copyright (C) 2007 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "blargg_source.h" + +#ifdef BLARGG_ENABLE_OPTIMIZER + #include BLARGG_ENABLE_OPTIMIZER +#endif + +#if INT_MAX < 0x7FFFFFFF + #error "Requires that int type have at least 32 bits" +#endif + +// TODO: add to blargg_endian.h +#define GET_LE16SA( addr ) ((BOOST::int16_t) GET_LE16( addr )) +#define GET_LE16A( addr ) GET_LE16( addr ) +#define SET_LE16A( addr, data ) SET_LE16( addr, data ) + +static BOOST::uint8_t const initial_regs [SPC_DSP::register_count] = +{ + 0x45,0x8B,0x5A,0x9A,0xE4,0x82,0x1B,0x78,0x00,0x00,0xAA,0x96,0x89,0x0E,0xE0,0x80, + 0x2A,0x49,0x3D,0xBA,0x14,0xA0,0xAC,0xC5,0x00,0x00,0x51,0xBB,0x9C,0x4E,0x7B,0xFF, + 0xF4,0xFD,0x57,0x32,0x37,0xD9,0x42,0x22,0x00,0x00,0x5B,0x3C,0x9F,0x1B,0x87,0x9A, + 0x6F,0x27,0xAF,0x7B,0xE5,0x68,0x0A,0xD9,0x00,0x00,0x9A,0xC5,0x9C,0x4E,0x7B,0xFF, + 0xEA,0x21,0x78,0x4F,0xDD,0xED,0x24,0x14,0x00,0x00,0x77,0xB1,0xD1,0x36,0xC1,0x67, + 0x52,0x57,0x46,0x3D,0x59,0xF4,0x87,0xA4,0x00,0x00,0x7E,0x44,0x9C,0x4E,0x7B,0xFF, + 0x75,0xF5,0x06,0x97,0x10,0xC3,0x24,0xBB,0x00,0x00,0x7B,0x7A,0xE0,0x60,0x12,0x0F, + 0xF7,0x74,0x1C,0xE5,0x39,0x3D,0x73,0xC1,0x00,0x00,0x7A,0xB3,0xFF,0x4E,0x7B,0xFF +}; + +// if ( io < -32768 ) io = -32768; +// if ( io > 32767 ) io = 32767; +#define CLAMP16( io )\ +{\ + if ( (int16_t) io != io )\ + io = (io >> 31) ^ 0x7FFF;\ +} + +// Access global DSP register +#define REG(n) m.regs [r_##n] + +// Access voice DSP register +#define VREG(r,n) r [v_##n] + +#define WRITE_SAMPLES( l, r, out ) \ +{\ + out [0] = l;\ + out [1] = r;\ + out += 2;\ + if ( out >= m.out_end )\ + {\ + check( out == m.out_end );\ + check( m.out_end != &m.extra [extra_size] || \ + (m.extra <= m.out_begin && m.extra < &m.extra [extra_size]) );\ + out = m.extra;\ + m.out_end = &m.extra [extra_size];\ + }\ +}\ + +void SPC_DSP::set_output( sample_t* out, int size ) +{ + require( (size & 1) == 0 ); // must be even + if ( !out ) + { + out = m.extra; + size = extra_size; + } + m.out_begin = out; + m.out = out; + m.out_end = out + size; +} + +// Volume registers and efb are signed! Easy to forget int8_t cast. +// Prefixes are to avoid accidental use of locals with same names. + +// Gaussian interpolation + +static short const gauss [512] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, + 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, + 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, + 18, 19, 19, 20, 20, 21, 21, 22, 23, 23, 24, 24, 25, 26, 27, 27, + 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 36, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 58, 59, 60, 61, 62, 64, 65, 66, 67, 69, 70, 71, 73, 74, 76, 77, + 78, 80, 81, 83, 84, 86, 87, 89, 90, 92, 94, 95, 97, 99, 100, 102, + 104, 106, 107, 109, 111, 113, 115, 117, 118, 120, 122, 124, 126, 128, 130, 132, + 134, 137, 139, 141, 143, 145, 147, 150, 152, 154, 156, 159, 161, 163, 166, 168, + 171, 173, 175, 178, 180, 183, 186, 188, 191, 193, 196, 199, 201, 204, 207, 210, + 212, 215, 218, 221, 224, 227, 230, 233, 236, 239, 242, 245, 248, 251, 254, 257, + 260, 263, 267, 270, 273, 276, 280, 283, 286, 290, 293, 297, 300, 304, 307, 311, + 314, 318, 321, 325, 328, 332, 336, 339, 343, 347, 351, 354, 358, 362, 366, 370, + 374, 378, 381, 385, 389, 393, 397, 401, 405, 410, 414, 418, 422, 426, 430, 434, + 439, 443, 447, 451, 456, 460, 464, 469, 473, 477, 482, 486, 491, 495, 499, 504, + 508, 513, 517, 522, 527, 531, 536, 540, 545, 550, 554, 559, 563, 568, 573, 577, + 582, 587, 592, 596, 601, 606, 611, 615, 620, 625, 630, 635, 640, 644, 649, 654, + 659, 664, 669, 674, 678, 683, 688, 693, 698, 703, 708, 713, 718, 723, 728, 732, + 737, 742, 747, 752, 757, 762, 767, 772, 777, 782, 787, 792, 797, 802, 806, 811, + 816, 821, 826, 831, 836, 841, 846, 851, 855, 860, 865, 870, 875, 880, 884, 889, + 894, 899, 904, 908, 913, 918, 923, 927, 932, 937, 941, 946, 951, 955, 960, 965, + 969, 974, 978, 983, 988, 992, 997,1001,1005,1010,1014,1019,1023,1027,1032,1036, +1040,1045,1049,1053,1057,1061,1066,1070,1074,1078,1082,1086,1090,1094,1098,1102, +1106,1109,1113,1117,1121,1125,1128,1132,1136,1139,1143,1146,1150,1153,1157,1160, +1164,1167,1170,1174,1177,1180,1183,1186,1190,1193,1196,1199,1202,1205,1207,1210, +1213,1216,1219,1221,1224,1227,1229,1232,1234,1237,1239,1241,1244,1246,1248,1251, +1253,1255,1257,1259,1261,1263,1265,1267,1269,1270,1272,1274,1275,1277,1279,1280, +1282,1283,1284,1286,1287,1288,1290,1291,1292,1293,1294,1295,1296,1297,1297,1298, +1299,1300,1300,1301,1302,1302,1303,1303,1303,1304,1304,1304,1304,1304,1305,1305, +}; + +inline int SPC_DSP::interpolate( voice_t const* v ) +{ + // Make pointers into gaussian based on fractional position between samples + int offset = v->interp_pos >> 4 & 0xFF; + short const* fwd = gauss + 255 - offset; + short const* rev = gauss + offset; // mirror left half of gaussian + + int const* in = &v->buf [(v->interp_pos >> 12) + v->buf_pos]; + int out; + out = (fwd [ 0] * in [0]) >> 11; + out += (fwd [256] * in [1]) >> 11; + out += (rev [256] * in [2]) >> 11; + out = (int16_t) out; + out += (rev [ 0] * in [3]) >> 11; + + CLAMP16( out ); + out &= ~1; + return out; +} + + +//// Counters + +int const simple_counter_range = 2048 * 5 * 3; // 30720 + +static unsigned const counter_rates [32] = +{ + simple_counter_range + 1, // never fires + 2048, 1536, + 1280, 1024, 768, + 640, 512, 384, + 320, 256, 192, + 160, 128, 96, + 80, 64, 48, + 40, 32, 24, + 20, 16, 12, + 10, 8, 6, + 5, 4, 3, + 2, + 1 +}; + +static unsigned const counter_offsets [32] = +{ + 1, 0, 1040, + 536, 0, 1040, + 536, 0, 1040, + 536, 0, 1040, + 536, 0, 1040, + 536, 0, 1040, + 536, 0, 1040, + 536, 0, 1040, + 536, 0, 1040, + 536, 0, 1040, + 0, + 0 +}; + +inline void SPC_DSP::init_counter() +{ + m.counter = 0; +} + +inline void SPC_DSP::run_counters() +{ + if ( --m.counter < 0 ) + m.counter = simple_counter_range - 1; +} + +inline unsigned SPC_DSP::read_counter( int rate ) +{ + return ((unsigned) m.counter + counter_offsets [rate]) % counter_rates [rate]; +} + + +//// Envelope + +inline void SPC_DSP::run_envelope( voice_t* const v ) +{ + int env = v->env; + if ( v->env_mode == env_release ) // 60% + { + if ( (env -= 0x8) < 0 ) + env = 0; + v->env = env; + } + else + { + int rate; + int env_data = VREG(v->regs,adsr1); + if ( m.t_adsr0 & 0x80 ) // 99% ADSR + { + if ( v->env_mode >= env_decay ) // 99% + { + env--; + env -= env >> 8; + rate = env_data & 0x1F; + if ( v->env_mode == env_decay ) // 1% + rate = (m.t_adsr0 >> 3 & 0x0E) + 0x10; + } + else // env_attack + { + rate = (m.t_adsr0 & 0x0F) * 2 + 1; + env += rate < 31 ? 0x20 : 0x400; + } + } + else // GAIN + { + int mode; + env_data = VREG(v->regs,gain); + mode = env_data >> 5; + if ( mode < 4 ) // direct + { + env = env_data * 0x10; + rate = 31; + } + else + { + rate = env_data & 0x1F; + if ( mode == 4 ) // 4: linear decrease + { + env -= 0x20; + } + else if ( mode < 6 ) // 5: exponential decrease + { + env--; + env -= env >> 8; + } + else // 6,7: linear increase + { + env += 0x20; + if ( mode > 6 && (unsigned) v->hidden_env >= 0x600 ) + env += 0x8 - 0x20; // 7: two-slope linear increase + } + } + } + + // Sustain level + if ( (env >> 8) == (env_data >> 5) && v->env_mode == env_decay ) + v->env_mode = env_sustain; + + v->hidden_env = env; + + // unsigned cast because linear decrease going negative also triggers this + if ( (unsigned) env > 0x7FF ) + { + env = (env < 0 ? 0 : 0x7FF); + if ( v->env_mode == env_attack ) + v->env_mode = env_decay; + } + + if ( !read_counter( rate ) ) + v->env = env; // nothing else is controlled by the counter + } +} + + +//// BRR Decoding + +inline void SPC_DSP::decode_brr( voice_t* v ) +{ + // Arrange the four input nybbles in 0xABCD order for easy decoding + int nybbles = m.t_brr_byte * 0x100 + m.ram [(v->brr_addr + v->brr_offset + 1) & 0xFFFF]; + + int const header = m.t_brr_header; + + // Write to next four samples in circular buffer + int* pos = &v->buf [v->buf_pos]; + int* end; + if ( (v->buf_pos += 4) >= brr_buf_size ) + v->buf_pos = 0; + + // Decode four samples + for ( end = pos + 4; pos < end; pos++, nybbles <<= 4 ) + { + // Extract nybble and sign-extend + int s = (int16_t) nybbles >> 12; + + // Shift sample based on header + int const shift = header >> 4; + s = (s << shift) >> 1; + if ( shift >= 0xD ) // handle invalid range + s = (s >> 25) << 11; // same as: s = (s < 0 ? -0x800 : 0) + + // Apply IIR filter (8 is the most commonly used) + int const filter = header & 0x0C; + int const p1 = pos [brr_buf_size - 1]; + int const p2 = pos [brr_buf_size - 2] >> 1; + if ( filter >= 8 ) + { + s += p1; + s -= p2; + if ( filter == 8 ) // s += p1 * 0.953125 - p2 * 0.46875 + { + s += p2 >> 4; + s += (p1 * -3) >> 6; + } + else // s += p1 * 0.8984375 - p2 * 0.40625 + { + s += (p1 * -13) >> 7; + s += (p2 * 3) >> 4; + } + } + else if ( filter ) // s += p1 * 0.46875 + { + s += p1 >> 1; + s += (-p1) >> 5; + } + + // Adjust and write sample + CLAMP16( s ); + s = (int16_t) (s * 2); + pos [brr_buf_size] = pos [0] = s; // second copy simplifies wrap-around + } +} + + +//// Misc + +#define MISC_CLOCK( n ) inline void SPC_DSP::misc_##n() + +MISC_CLOCK( 27 ) +{ + m.t_pmon = REG(pmon) & 0xFE; // voice 0 doesn't support PMON +} +MISC_CLOCK( 28 ) +{ + m.t_non = REG(non); + m.t_eon = REG(eon); + m.t_dir = REG(dir); +} +MISC_CLOCK( 29 ) +{ + if ( (m.every_other_sample ^= 1) != 0 ) + m.new_kon &= ~m.kon; // clears KON 63 clocks after it was last read +} +MISC_CLOCK( 30 ) +{ + if ( m.every_other_sample ) + { + m.kon = m.new_kon; + m.t_koff = REG(koff) | m.mute_mask; + } + + run_counters(); + + // Noise + if ( !read_counter( REG(flg) & 0x1F ) ) + { + int feedback = (m.noise << 13) ^ (m.noise << 14); + m.noise = (feedback & 0x4000) ^ (m.noise >> 1); + } +} + + +//// Voices + +#define VOICE_CLOCK( n ) void SPC_DSP::voice_##n( voice_t* const v ) + +inline VOICE_CLOCK( V1 ) +{ + m.t_dir_addr = m.t_dir * 0x100 + m.t_srcn * 4; + m.t_srcn = VREG(v->regs,srcn); +} +inline VOICE_CLOCK( V2 ) +{ + // Read sample pointer (ignored if not needed) + uint8_t const* entry = &m.ram [m.t_dir_addr]; + if ( !v->kon_delay ) + entry += 2; + m.t_brr_next_addr = GET_LE16A( entry ); + + m.t_adsr0 = VREG(v->regs,adsr0); + + // Read pitch, spread over two clocks + m.t_pitch = VREG(v->regs,pitchl); +} +inline VOICE_CLOCK( V3a ) +{ + m.t_pitch += (VREG(v->regs,pitchh) & 0x3F) << 8; +} +inline VOICE_CLOCK( V3b ) +{ + // Read BRR header and byte + m.t_brr_byte = m.ram [(v->brr_addr + v->brr_offset) & 0xFFFF]; + m.t_brr_header = m.ram [v->brr_addr]; // brr_addr doesn't need masking +} +VOICE_CLOCK( V3c ) +{ + // Pitch modulation using previous voice's output + if ( m.t_pmon & v->vbit ) + m.t_pitch += ((m.t_output >> 5) * m.t_pitch) >> 10; + + if ( v->kon_delay ) + { + // Get ready to start BRR decoding on next sample + if ( v->kon_delay == 5 ) + { + v->brr_addr = m.t_brr_next_addr; + v->brr_offset = 1; + v->buf_pos = 0; + m.t_brr_header = 0; // header is ignored on this sample + m.kon_check = true; + } + + // Envelope is never run during KON + v->env = 0; + v->hidden_env = 0; + + // Disable BRR decoding until last three samples + v->interp_pos = 0; + if ( --v->kon_delay & 3 ) + v->interp_pos = 0x4000; + + // Pitch is never added during KON + m.t_pitch = 0; + } + + // Gaussian interpolation + { + int output = interpolate( v ); + + // Noise + if ( m.t_non & v->vbit ) + output = (int16_t) (m.noise * 2); + + // Apply envelope + m.t_output = (output * v->env) >> 11 & ~1; + v->t_envx_out = (uint8_t) (v->env >> 4); + } + + // Immediate silence due to end of sample or soft reset + if ( REG(flg) & 0x80 || (m.t_brr_header & 3) == 1 ) + { + v->env_mode = env_release; + v->env = 0; + } + + if ( m.every_other_sample ) + { + // KOFF + if ( m.t_koff & v->vbit ) + v->env_mode = env_release; + + // KON + if ( m.kon & v->vbit ) + { + v->kon_delay = 5; + v->env_mode = env_attack; + } + } + + // Run envelope for next sample + if ( !v->kon_delay ) + run_envelope( v ); +} +inline void SPC_DSP::voice_output( voice_t const* v, int ch ) +{ + // Apply left/right volume + int amp = (m.t_output * (int8_t) VREG(v->regs,voll + ch)) >> 7; + + // Add to output total + m.t_main_out [ch] += amp; + CLAMP16( m.t_main_out [ch] ); + + // Optionally add to echo total + if ( m.t_eon & v->vbit ) + { + m.t_echo_out [ch] += amp; + CLAMP16( m.t_echo_out [ch] ); + } +} +VOICE_CLOCK( V4 ) +{ + // Decode BRR + m.t_looped = 0; + if ( v->interp_pos >= 0x4000 ) + { + decode_brr( v ); + + if ( (v->brr_offset += 2) >= brr_block_size ) + { + // Start decoding next BRR block + assert( v->brr_offset == brr_block_size ); + v->brr_addr = (v->brr_addr + brr_block_size) & 0xFFFF; + if ( m.t_brr_header & 1 ) + { + v->brr_addr = m.t_brr_next_addr; + m.t_looped = v->vbit; + } + v->brr_offset = 1; + } + } + + // Apply pitch + v->interp_pos = (v->interp_pos & 0x3FFF) + m.t_pitch; + + // Keep from getting too far ahead (when using pitch modulation) + if ( v->interp_pos > 0x7FFF ) + v->interp_pos = 0x7FFF; + + // Output left + voice_output( v, 0 ); +} +inline VOICE_CLOCK( V5 ) +{ + // Output right + voice_output( v, 1 ); + + // ENDX, OUTX, and ENVX won't update if you wrote to them 1-2 clocks earlier + int endx_buf = REG(endx) | m.t_looped; + + // Clear bit in ENDX if KON just began + if ( v->kon_delay == 5 ) + endx_buf &= ~v->vbit; + m.endx_buf = (uint8_t) endx_buf; +} +inline VOICE_CLOCK( V6 ) +{ + (void) v; // avoid compiler warning about unused v + m.outx_buf = (uint8_t) (m.t_output >> 8); +} +inline VOICE_CLOCK( V7 ) +{ + // Update ENDX + REG(endx) = m.endx_buf; + + m.envx_buf = v->t_envx_out; +} +inline VOICE_CLOCK( V8 ) +{ + // Update OUTX + VREG(v->regs,outx) = m.outx_buf; +} +inline VOICE_CLOCK( V9 ) +{ + // Update ENVX + VREG(v->regs,envx) = m.envx_buf; +} + +// Most voices do all these in one clock, so make a handy composite +inline VOICE_CLOCK( V3 ) +{ + voice_V3a( v ); + voice_V3b( v ); + voice_V3c( v ); +} + +// Common combinations of voice steps on different voices. This greatly reduces +// code size and allows everything to be inlined in these functions. +VOICE_CLOCK(V7_V4_V1) { voice_V7(v); voice_V1(v+3); voice_V4(v+1); } +VOICE_CLOCK(V8_V5_V2) { voice_V8(v); voice_V5(v+1); voice_V2(v+2); } +VOICE_CLOCK(V9_V6_V3) { voice_V9(v); voice_V6(v+1); voice_V3(v+2); } + + +//// Echo + +// Current echo buffer pointer for left/right channel +#define ECHO_PTR( ch ) (&m.ram [m.t_echo_ptr + ch * 2]) + +// Sample in echo history buffer, where 0 is the oldest +#define ECHO_FIR( i ) (m.echo_hist_pos [i]) + +// Calculate FIR point for left/right channel +#define CALC_FIR( i, ch ) ((ECHO_FIR( i + 1 ) [ch] * (int8_t) REG(fir + i * 0x10)) >> 6) + +#define ECHO_CLOCK( n ) inline void SPC_DSP::echo_##n() + +inline void SPC_DSP::echo_read( int ch ) +{ + int s = GET_LE16SA( ECHO_PTR( ch ) ); + // second copy simplifies wrap-around handling + ECHO_FIR( 0 ) [ch] = ECHO_FIR( 8 ) [ch] = s >> 1; +} + +ECHO_CLOCK( 22 ) +{ + // History + if ( ++m.echo_hist_pos >= &m.echo_hist [echo_hist_size] ) + m.echo_hist_pos = m.echo_hist; + + m.t_echo_ptr = (m.t_esa * 0x100 + m.echo_offset) & 0xFFFF; + echo_read( 0 ); + + // FIR (using l and r temporaries below helps compiler optimize) + int l = CALC_FIR( 0, 0 ); + int r = CALC_FIR( 0, 1 ); + + m.t_echo_in [0] = l; + m.t_echo_in [1] = r; +} +ECHO_CLOCK( 23 ) +{ + int l = CALC_FIR( 1, 0 ) + CALC_FIR( 2, 0 ); + int r = CALC_FIR( 1, 1 ) + CALC_FIR( 2, 1 ); + + m.t_echo_in [0] += l; + m.t_echo_in [1] += r; + + echo_read( 1 ); +} +ECHO_CLOCK( 24 ) +{ + int l = CALC_FIR( 3, 0 ) + CALC_FIR( 4, 0 ) + CALC_FIR( 5, 0 ); + int r = CALC_FIR( 3, 1 ) + CALC_FIR( 4, 1 ) + CALC_FIR( 5, 1 ); + + m.t_echo_in [0] += l; + m.t_echo_in [1] += r; +} +ECHO_CLOCK( 25 ) +{ + int l = m.t_echo_in [0] + CALC_FIR( 6, 0 ); + int r = m.t_echo_in [1] + CALC_FIR( 6, 1 ); + + l = (int16_t) l; + r = (int16_t) r; + + l += (int16_t) CALC_FIR( 7, 0 ); + r += (int16_t) CALC_FIR( 7, 1 ); + + CLAMP16( l ); + CLAMP16( r ); + + m.t_echo_in [0] = l & ~1; + m.t_echo_in [1] = r & ~1; +} +inline int SPC_DSP::echo_output( int ch ) +{ + int out = (int16_t) ((m.t_main_out [ch] * (int8_t) REG(mvoll + ch * 0x10)) >> 7) + + (int16_t) ((m.t_echo_in [ch] * (int8_t) REG(evoll + ch * 0x10)) >> 7); + CLAMP16( out ); + return out; +} +ECHO_CLOCK( 26 ) +{ + // Left output volumes + // (save sample for next clock so we can output both together) + m.t_main_out [0] = echo_output( 0 ); + + // Echo feedback + int l = m.t_echo_out [0] + (int16_t) ((m.t_echo_in [0] * (int8_t) REG(efb)) >> 7); + int r = m.t_echo_out [1] + (int16_t) ((m.t_echo_in [1] * (int8_t) REG(efb)) >> 7); + + CLAMP16( l ); + CLAMP16( r ); + + m.t_echo_out [0] = l & ~1; + m.t_echo_out [1] = r & ~1; +} +ECHO_CLOCK( 27 ) +{ + // Output + int l = m.t_main_out [0]; + int r = echo_output( 1 ); + m.t_main_out [0] = 0; + m.t_main_out [1] = 0; + + // TODO: global muting isn't this simple (turns DAC on and off + // or something, causing small ~37-sample pulse when first muted) + if ( REG(flg) & 0x40 ) + { + l = 0; + r = 0; + } + + // Output sample to DAC + #ifdef SPC_DSP_OUT_HOOK + SPC_DSP_OUT_HOOK( l, r ); + #else + sample_t* out = m.out; + WRITE_SAMPLES( l, r, out ); + m.out = out; + #endif +} +ECHO_CLOCK( 28 ) +{ + m.t_echo_enabled = REG(flg); +} +inline void SPC_DSP::echo_write( int ch ) +{ + if ( !(m.t_echo_enabled & 0x20) ) + SET_LE16A( ECHO_PTR( ch ), m.t_echo_out [ch] ); + m.t_echo_out [ch] = 0; +} +ECHO_CLOCK( 29 ) +{ + m.t_esa = REG(esa); + + if ( !m.echo_offset ) + m.echo_length = (REG(edl) & 0x0F) * 0x800; + + m.echo_offset += 4; + if ( m.echo_offset >= m.echo_length ) + m.echo_offset = 0; + + // Write left echo + echo_write( 0 ); + + m.t_echo_enabled = REG(flg); +} +ECHO_CLOCK( 30 ) +{ + // Write right echo + echo_write( 1 ); +} + + +//// Timing + +// Execute clock for a particular voice +#define V( clock, voice ) voice_##clock( &m.voices [voice] ); + +/* The most common sequence of clocks uses composite operations +for efficiency. For example, the following are equivalent to the +individual steps on the right: + +V(V7_V4_V1,2) -> V(V7,2) V(V4,3) V(V1,5) +V(V8_V5_V2,2) -> V(V8,2) V(V5,3) V(V2,4) +V(V9_V6_V3,2) -> V(V9,2) V(V6,3) V(V3,4) */ + +// Voice 0 1 2 3 4 5 6 7 +#define GEN_DSP_TIMING \ +PHASE( 0) V(V5,0)V(V2,1)\ +PHASE( 1) V(V6,0)V(V3,1)\ +PHASE( 2) V(V7_V4_V1,0)\ +PHASE( 3) V(V8_V5_V2,0)\ +PHASE( 4) V(V9_V6_V3,0)\ +PHASE( 5) V(V7_V4_V1,1)\ +PHASE( 6) V(V8_V5_V2,1)\ +PHASE( 7) V(V9_V6_V3,1)\ +PHASE( 8) V(V7_V4_V1,2)\ +PHASE( 9) V(V8_V5_V2,2)\ +PHASE(10) V(V9_V6_V3,2)\ +PHASE(11) V(V7_V4_V1,3)\ +PHASE(12) V(V8_V5_V2,3)\ +PHASE(13) V(V9_V6_V3,3)\ +PHASE(14) V(V7_V4_V1,4)\ +PHASE(15) V(V8_V5_V2,4)\ +PHASE(16) V(V9_V6_V3,4)\ +PHASE(17) V(V1,0) V(V7,5)V(V4,6)\ +PHASE(18) V(V8_V5_V2,5)\ +PHASE(19) V(V9_V6_V3,5)\ +PHASE(20) V(V1,1) V(V7,6)V(V4,7)\ +PHASE(21) V(V8,6)V(V5,7) V(V2,0) /* t_brr_next_addr order dependency */\ +PHASE(22) V(V3a,0) V(V9,6)V(V6,7) echo_22();\ +PHASE(23) V(V7,7) echo_23();\ +PHASE(24) V(V8,7) echo_24();\ +PHASE(25) V(V3b,0) V(V9,7) echo_25();\ +PHASE(26) echo_26();\ +PHASE(27) misc_27(); echo_27();\ +PHASE(28) misc_28(); echo_28();\ +PHASE(29) misc_29(); echo_29();\ +PHASE(30) misc_30();V(V3c,0) echo_30();\ +PHASE(31) V(V4,0) V(V1,2)\ + +#if !SPC_DSP_CUSTOM_RUN + +void SPC_DSP::run( int clocks_remain ) +{ + require( clocks_remain > 0 ); + + int const phase = m.phase; + m.phase = (phase + clocks_remain) & 31; + switch ( phase ) + { + loop: + + #define PHASE( n ) if ( n && !--clocks_remain ) break; case n: + GEN_DSP_TIMING + #undef PHASE + + if ( --clocks_remain ) + goto loop; + } +} + +#endif + + +//// Setup + +void SPC_DSP::init( void* ram_64k ) +{ + m.ram = (uint8_t*) ram_64k; + mute_voices( 0 ); + disable_surround( false ); + set_output( 0, 0 ); + reset(); + + #ifndef NDEBUG + // be sure this sign-extends + assert( (int16_t) 0x8000 == -0x8000 ); + + // be sure right shift preserves sign + assert( (-1 >> 1) == -1 ); + + // check clamp macro + int i; + i = +0x8000; CLAMP16( i ); assert( i == +0x7FFF ); + i = -0x8001; CLAMP16( i ); assert( i == -0x8000 ); + + blargg_verify_byte_order(); + #endif +} + +void SPC_DSP::soft_reset_common() +{ + require( m.ram ); // init() must have been called already + + m.noise = 0x4000; + m.echo_hist_pos = m.echo_hist; + m.every_other_sample = 1; + m.echo_offset = 0; + m.phase = 0; + + init_counter(); +} + +void SPC_DSP::soft_reset() +{ + REG(flg) = 0xE0; + soft_reset_common(); +} + +void SPC_DSP::load( uint8_t const regs [register_count] ) +{ + memcpy( m.regs, regs, sizeof m.regs ); + memset( &m.regs [register_count], 0, offsetof (state_t,ram) - register_count ); + + // Internal state + for ( int i = voice_count; --i >= 0; ) + { + voice_t* v = &m.voices [i]; + v->brr_offset = 1; + v->vbit = 1 << i; + v->regs = &m.regs [i * 0x10]; + } + m.new_kon = REG(kon); + m.t_dir = REG(dir); + m.t_esa = REG(esa); + + soft_reset_common(); +} + +void SPC_DSP::reset() { load( initial_regs ); } + + +//// State save/load + +#if !SPC_NO_COPY_STATE_FUNCS + +void SPC_State_Copier::copy( void* state, size_t size ) +{ + func( buf, state, size ); +} + +int SPC_State_Copier::copy_int( int state, int size ) +{ + BOOST::uint8_t s [2]; + SET_LE16( s, state ); + func( buf, &s, size ); + return GET_LE16( s ); +} + +void SPC_State_Copier::skip( int count ) +{ + if ( count > 0 ) + { + char temp [64]; + memset( temp, 0, sizeof temp ); + do + { + int n = sizeof temp; + if ( n > count ) + n = count; + count -= n; + func( buf, temp, n ); + } + while ( count ); + } +} + +void SPC_State_Copier::extra() +{ + int n = 0; + SPC_State_Copier& copier = *this; + SPC_COPY( uint8_t, n ); + skip( n ); +} + +void SPC_DSP::copy_state( unsigned char** io, copy_func_t copy ) +{ + SPC_State_Copier copier( io, copy ); + + // DSP registers + copier.copy( m.regs, register_count ); + + // Internal state + + // Voices + int i; + for ( i = 0; i < voice_count; i++ ) + { + voice_t* v = &m.voices [i]; + + // BRR buffer + int i; + for ( i = 0; i < brr_buf_size; i++ ) + { + int s = v->buf [i]; + SPC_COPY( int16_t, s ); + v->buf [i] = v->buf [i + brr_buf_size] = s; + } + + SPC_COPY( uint16_t, v->interp_pos ); + SPC_COPY( uint16_t, v->brr_addr ); + SPC_COPY( uint16_t, v->env ); + SPC_COPY( int16_t, v->hidden_env ); + SPC_COPY( uint8_t, v->buf_pos ); + SPC_COPY( uint8_t, v->brr_offset ); + SPC_COPY( uint8_t, v->kon_delay ); + { + int m = v->env_mode; + SPC_COPY( uint8_t, m ); + v->env_mode = (enum env_mode_t) m; + } + SPC_COPY( uint8_t, v->t_envx_out ); + + copier.extra(); + } + + // Echo history + for ( i = 0; i < echo_hist_size; i++ ) + { + int j; + for ( j = 0; j < 2; j++ ) + { + int s = m.echo_hist_pos [i] [j]; + SPC_COPY( int16_t, s ); + m.echo_hist [i] [j] = s; // write back at offset 0 + } + } + m.echo_hist_pos = m.echo_hist; + memcpy( &m.echo_hist [echo_hist_size], m.echo_hist, echo_hist_size * sizeof m.echo_hist [0] ); + + // Misc + SPC_COPY( uint8_t, m.every_other_sample ); + SPC_COPY( uint8_t, m.kon ); + + SPC_COPY( uint16_t, m.noise ); + SPC_COPY( uint16_t, m.counter ); + SPC_COPY( uint16_t, m.echo_offset ); + SPC_COPY( uint16_t, m.echo_length ); + SPC_COPY( uint8_t, m.phase ); + + SPC_COPY( uint8_t, m.new_kon ); + SPC_COPY( uint8_t, m.endx_buf ); + SPC_COPY( uint8_t, m.envx_buf ); + SPC_COPY( uint8_t, m.outx_buf ); + + SPC_COPY( uint8_t, m.t_pmon ); + SPC_COPY( uint8_t, m.t_non ); + SPC_COPY( uint8_t, m.t_eon ); + SPC_COPY( uint8_t, m.t_dir ); + SPC_COPY( uint8_t, m.t_koff ); + + SPC_COPY( uint16_t, m.t_brr_next_addr ); + SPC_COPY( uint8_t, m.t_adsr0 ); + SPC_COPY( uint8_t, m.t_brr_header ); + SPC_COPY( uint8_t, m.t_brr_byte ); + SPC_COPY( uint8_t, m.t_srcn ); + SPC_COPY( uint8_t, m.t_esa ); + SPC_COPY( uint8_t, m.t_echo_enabled ); + + SPC_COPY( int16_t, m.t_main_out [0] ); + SPC_COPY( int16_t, m.t_main_out [1] ); + SPC_COPY( int16_t, m.t_echo_out [0] ); + SPC_COPY( int16_t, m.t_echo_out [1] ); + SPC_COPY( int16_t, m.t_echo_in [0] ); + SPC_COPY( int16_t, m.t_echo_in [1] ); + + SPC_COPY( uint16_t, m.t_dir_addr ); + SPC_COPY( uint16_t, m.t_pitch ); + SPC_COPY( int16_t, m.t_output ); + SPC_COPY( uint16_t, m.t_echo_ptr ); + SPC_COPY( uint8_t, m.t_looped ); + + copier.extra(); +} +#endif diff --git a/waterbox/pizza/lib/snes_spc/SPC_DSP.h b/waterbox/pizza/lib/snes_spc/SPC_DSP.h new file mode 100644 index 0000000000..4522ace915 --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/SPC_DSP.h @@ -0,0 +1,304 @@ +// Highly accurate SNES SPC-700 DSP emulator + +// snes_spc 0.9.0 +#ifndef SPC_DSP_H +#define SPC_DSP_H + +#include "blargg_common.h" + +extern "C" { typedef void (*dsp_copy_func_t)( unsigned char** io, void* state, size_t ); } + +class SPC_DSP { +public: + typedef BOOST::uint8_t uint8_t; + +// Setup + + // Initializes DSP and has it use the 64K RAM provided + void init( void* ram_64k ); + + // Sets destination for output samples. If out is NULL or out_size is 0, + // doesn't generate any. + typedef short sample_t; + void set_output( sample_t* out, int out_size ); + + // Number of samples written to output since it was last set, always + // a multiple of 2. Undefined if more samples were generated than + // output buffer could hold. + int sample_count() const; + +// Emulation + + // Resets DSP to power-on state + void reset(); + + // Emulates pressing reset switch on SNES + void soft_reset(); + + // Reads/writes DSP registers. For accuracy, you must first call run() + // to catch the DSP up to present. + int read ( int addr ) const; + void write( int addr, int data ); + + // Runs DSP for specified number of clocks (~1024000 per second). Every 32 clocks + // a pair of samples is be generated. + void run( int clock_count ); + +// Sound control + + // Mutes voices corresponding to non-zero bits in mask (issues repeated KOFF events). + // Reduces emulation accuracy. + enum { voice_count = 8 }; + void mute_voices( int mask ); + +// State + + // Resets DSP and uses supplied values to initialize registers + enum { register_count = 128 }; + void load( uint8_t const regs [register_count] ); + + // Saves/loads exact emulator state + enum { state_size = 640 }; // maximum space needed when saving + typedef dsp_copy_func_t copy_func_t; + void copy_state( unsigned char** io, copy_func_t ); + + // Returns non-zero if new key-on events occurred since last call + bool check_kon(); + +// DSP register addresses + + // Global registers + enum { + r_mvoll = 0x0C, r_mvolr = 0x1C, + r_evoll = 0x2C, r_evolr = 0x3C, + r_kon = 0x4C, r_koff = 0x5C, + r_flg = 0x6C, r_endx = 0x7C, + r_efb = 0x0D, r_pmon = 0x2D, + r_non = 0x3D, r_eon = 0x4D, + r_dir = 0x5D, r_esa = 0x6D, + r_edl = 0x7D, + r_fir = 0x0F // 8 coefficients at 0x0F, 0x1F ... 0x7F + }; + + // Voice registers + enum { + v_voll = 0x00, v_volr = 0x01, + v_pitchl = 0x02, v_pitchh = 0x03, + v_srcn = 0x04, v_adsr0 = 0x05, + v_adsr1 = 0x06, v_gain = 0x07, + v_envx = 0x08, v_outx = 0x09 + }; + +public: + enum { extra_size = 16 }; + sample_t* extra() { return m.extra; } + sample_t const* out_pos() const { return m.out; } + void disable_surround( bool ) { } // not supported +public: + BLARGG_DISABLE_NOTHROW + + typedef BOOST::int8_t int8_t; + typedef BOOST::int16_t int16_t; + + enum { echo_hist_size = 8 }; + + enum env_mode_t { env_release, env_attack, env_decay, env_sustain }; + enum { brr_buf_size = 12 }; + struct voice_t + { + int buf [brr_buf_size*2];// decoded samples (twice the size to simplify wrap handling) + int buf_pos; // place in buffer where next samples will be decoded + int interp_pos; // relative fractional position in sample (0x1000 = 1.0) + int brr_addr; // address of current BRR block + int brr_offset; // current decoding offset in BRR block + uint8_t* regs; // pointer to voice's DSP registers + int vbit; // bitmask for voice: 0x01 for voice 0, 0x02 for voice 1, etc. + int kon_delay; // KON delay/current setup phase + env_mode_t env_mode; + int env; // current envelope level + int hidden_env; // used by GAIN mode 7, very obscure quirk + uint8_t t_envx_out; + }; +private: + enum { brr_block_size = 9 }; + + struct state_t + { + uint8_t regs [register_count]; + + // Echo history keeps most recent 8 samples (twice the size to simplify wrap handling) + int echo_hist [echo_hist_size * 2] [2]; + int (*echo_hist_pos) [2]; // &echo_hist [0 to 7] + + int every_other_sample; // toggles every sample + int kon; // KON value when last checked + int noise; + int counter; + int echo_offset; // offset from ESA in echo buffer + int echo_length; // number of bytes that echo_offset will stop at + int phase; // next clock cycle to run (0-31) + bool kon_check; // set when a new KON occurs + + // Hidden registers also written to when main register is written to + int new_kon; + uint8_t endx_buf; + uint8_t envx_buf; + uint8_t outx_buf; + + // Temporary state between clocks + + // read once per sample + int t_pmon; + int t_non; + int t_eon; + int t_dir; + int t_koff; + + // read a few clocks ahead then used + int t_brr_next_addr; + int t_adsr0; + int t_brr_header; + int t_brr_byte; + int t_srcn; + int t_esa; + int t_echo_enabled; + + // internal state that is recalculated every sample + int t_dir_addr; + int t_pitch; + int t_output; + int t_looped; + int t_echo_ptr; + + // left/right sums + int t_main_out [2]; + int t_echo_out [2]; + int t_echo_in [2]; + + voice_t voices [voice_count]; + + // non-emulation state + uint8_t* ram; // 64K shared RAM between DSP and SMP + int mute_mask; + sample_t* out; + sample_t* out_end; + sample_t* out_begin; + sample_t extra [extra_size]; + }; + state_t m; + + void init_counter(); + void run_counters(); + unsigned read_counter( int rate ); + + int interpolate( voice_t const* v ); + void run_envelope( voice_t* const v ); + void decode_brr( voice_t* v ); + + void misc_27(); + void misc_28(); + void misc_29(); + void misc_30(); + + void voice_output( voice_t const* v, int ch ); + void voice_V1( voice_t* const ); + void voice_V2( voice_t* const ); + void voice_V3( voice_t* const ); + void voice_V3a( voice_t* const ); + void voice_V3b( voice_t* const ); + void voice_V3c( voice_t* const ); + void voice_V4( voice_t* const ); + void voice_V5( voice_t* const ); + void voice_V6( voice_t* const ); + void voice_V7( voice_t* const ); + void voice_V8( voice_t* const ); + void voice_V9( voice_t* const ); + void voice_V7_V4_V1( voice_t* const ); + void voice_V8_V5_V2( voice_t* const ); + void voice_V9_V6_V3( voice_t* const ); + + void echo_read( int ch ); + int echo_output( int ch ); + void echo_write( int ch ); + void echo_22(); + void echo_23(); + void echo_24(); + void echo_25(); + void echo_26(); + void echo_27(); + void echo_28(); + void echo_29(); + void echo_30(); + + void soft_reset_common(); +}; + +#include + +inline int SPC_DSP::sample_count() const { return m.out - m.out_begin; } + +inline int SPC_DSP::read( int addr ) const +{ + assert( (unsigned) addr < register_count ); + return m.regs [addr]; +} + +inline void SPC_DSP::write( int addr, int data ) +{ + assert( (unsigned) addr < register_count ); + + m.regs [addr] = (uint8_t) data; + switch ( addr & 0x0F ) + { + case v_envx: + m.envx_buf = (uint8_t) data; + break; + + case v_outx: + m.outx_buf = (uint8_t) data; + break; + + case 0x0C: + if ( addr == r_kon ) + m.new_kon = (uint8_t) data; + + if ( addr == r_endx ) // always cleared, regardless of data written + { + m.endx_buf = 0; + m.regs [r_endx] = 0; + } + break; + } +} + +inline void SPC_DSP::mute_voices( int mask ) { m.mute_mask = mask; } + +inline bool SPC_DSP::check_kon() +{ + bool old = m.kon_check; + m.kon_check = 0; + return old; +} + +#if !SPC_NO_COPY_STATE_FUNCS + +class SPC_State_Copier { + SPC_DSP::copy_func_t func; + unsigned char** buf; +public: + SPC_State_Copier( unsigned char** p, SPC_DSP::copy_func_t f ) { func = f; buf = p; } + void copy( void* state, size_t size ); + int copy_int( int state, int size ); + void skip( int count ); + void extra(); +}; + +#define SPC_COPY( type, state )\ +{\ + state = (BOOST::type) copier.copy_int( state, sizeof (BOOST::type) );\ + assert( (BOOST::type) state == state );\ +} + +#endif + +#endif diff --git a/waterbox/pizza/lib/snes_spc/SPC_Filter.cpp b/waterbox/pizza/lib/snes_spc/SPC_Filter.cpp new file mode 100644 index 0000000000..b3d5770822 --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/SPC_Filter.cpp @@ -0,0 +1,68 @@ +// snes_spc 0.9.0. http://www.slack.net/~ant/ + +#include "SPC_Filter.h" + +#include + +/* Copyright (C) 2007 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "blargg_source.h" + +void SPC_Filter::clear() { memset( ch, 0, sizeof ch ); } + +SPC_Filter::SPC_Filter() +{ + gain = gain_unit; + bass = bass_norm; + clear(); +} + +void SPC_Filter::run( short* io, int count ) +{ + require( (count & 1) == 0 ); // must be even + + int const gain = this->gain; + int const bass = this->bass; + chan_t* c = &ch [2]; + do + { + // cache in registers + int sum = (--c)->sum; + int pp1 = c->pp1; + int p1 = c->p1; + + for ( int i = 0; i < count; i += 2 ) + { + // Low-pass filter (two point FIR with coeffs 0.25, 0.75) + int f = io [i] + p1; + p1 = io [i] * 3; + + // High-pass filter ("leaky integrator") + int delta = f - pp1; + pp1 = f; + int s = sum >> (gain_bits + 2); + sum += (delta * gain) - (sum >> bass); + + // Clamp to 16 bits + if ( (short) s != s ) + s = (s >> 31) ^ 0x7FFF; + + io [i] = (short) s; + } + + c->p1 = p1; + c->pp1 = pp1; + c->sum = sum; + ++io; + } + while ( c != ch ); +} diff --git a/waterbox/pizza/lib/snes_spc/SPC_Filter.h b/waterbox/pizza/lib/snes_spc/SPC_Filter.h new file mode 100644 index 0000000000..d5c83cb8f1 --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/SPC_Filter.h @@ -0,0 +1,47 @@ +// Simple low-pass and high-pass filter to better match sound output of a SNES + +// snes_spc 0.9.0 +#ifndef SPC_FILTER_H +#define SPC_FILTER_H + +#include "blargg_common.h" + +struct SPC_Filter { +public: + + // Filters count samples of stereo sound in place. Count must be a multiple of 2. + typedef short sample_t; + void run( sample_t* io, int count ); + +// Optional features + + // Clears filter to silence + void clear(); + + // Sets gain (volume), where gain_unit is normal. Gains greater than gain_unit + // are fine, since output is clamped to 16-bit sample range. + enum { gain_unit = 0x100 }; + void set_gain( int gain ); + + // Sets amount of bass (logarithmic scale) + enum { bass_none = 0 }; + enum { bass_norm = 8 }; // normal amount + enum { bass_max = 31 }; + void set_bass( int bass ); + +public: + SPC_Filter(); + BLARGG_DISABLE_NOTHROW +private: + enum { gain_bits = 8 }; + int gain; + int bass; + struct chan_t { int p1, pp1, sum; }; + chan_t ch [2]; +}; + +inline void SPC_Filter::set_gain( int g ) { gain = g; } + +inline void SPC_Filter::set_bass( int b ) { bass = b; } + +#endif diff --git a/waterbox/pizza/lib/snes_spc/blargg_common.h b/waterbox/pizza/lib/snes_spc/blargg_common.h new file mode 100644 index 0000000000..75edff3914 --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/blargg_common.h @@ -0,0 +1,186 @@ +// Sets up common environment for Shay Green's libraries. +// To change configuration options, modify blargg_config.h, not this file. + +// snes_spc 0.9.0 +#ifndef BLARGG_COMMON_H +#define BLARGG_COMMON_H + +#include +#include +#include +#include + +#undef BLARGG_COMMON_H +// allow blargg_config.h to #include blargg_common.h +#include "blargg_config.h" +#ifndef BLARGG_COMMON_H +#define BLARGG_COMMON_H + +// BLARGG_RESTRICT: equivalent to restrict, where supported +#if defined (__GNUC__) || _MSC_VER >= 1100 + #define BLARGG_RESTRICT __restrict +#else + #define BLARGG_RESTRICT +#endif + +// STATIC_CAST(T,expr): Used in place of static_cast (expr) +#ifndef STATIC_CAST + #define STATIC_CAST(T,expr) ((T) (expr)) +#endif + +// blargg_err_t (0 on success, otherwise error string) +#ifndef blargg_err_t + typedef const char* blargg_err_t; +#endif + +// blargg_vector - very lightweight vector of POD types (no constructor/destructor) +template +class blargg_vector { + T* begin_; + size_t size_; +public: + blargg_vector() : begin_( 0 ), size_( 0 ) { } + ~blargg_vector() { free( begin_ ); } + size_t size() const { return size_; } + T* begin() const { return begin_; } + T* end() const { return begin_ + size_; } + blargg_err_t resize( size_t n ) + { + // TODO: blargg_common.cpp to hold this as an outline function, ugh + void* p = realloc( begin_, n * sizeof (T) ); + if ( p ) + begin_ = (T*) p; + else if ( n > size_ ) // realloc failure only a problem if expanding + return "Out of memory"; + size_ = n; + return 0; + } + void clear() { void* p = begin_; begin_ = 0; size_ = 0; free( p ); } + T& operator [] ( size_t n ) const + { + assert( n <= size_ ); // <= to allow past-the-end value + return begin_ [n]; + } +}; + +#ifndef BLARGG_DISABLE_NOTHROW + // throw spec mandatory in ISO C++ if operator new can return NULL + #if __cplusplus >= 199711 || defined (__GNUC__) + #define BLARGG_THROWS( spec ) throw spec + #else + #define BLARGG_THROWS( spec ) + #endif + #define BLARGG_DISABLE_NOTHROW \ + void* operator new ( size_t s ) BLARGG_THROWS(()) { return malloc( s ); }\ + void operator delete ( void* p ) { free( p ); } + #define BLARGG_NEW new +#else + #include + #define BLARGG_NEW new (std::nothrow) +#endif + +// BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant) +#define BLARGG_4CHAR( a, b, c, d ) \ + ((a&0xFF)*0x1000000L + (b&0xFF)*0x10000L + (c&0xFF)*0x100L + (d&0xFF)) + +// BOOST_STATIC_ASSERT( expr ): Generates compile error if expr is 0. +#ifndef BOOST_STATIC_ASSERT + #ifdef _MSC_VER + // MSVC6 (_MSC_VER < 1300) fails for use of __LINE__ when /Zl is specified + #define BOOST_STATIC_ASSERT( expr ) \ + void blargg_failed_( int (*arg) [2 / (int) !!(expr) - 1] ) + #else + // Some other compilers fail when declaring same function multiple times in class, + // so differentiate them by line + #define BOOST_STATIC_ASSERT( expr ) \ + void blargg_failed_( int (*arg) [2 / !!(expr) - 1] [__LINE__] ) + #endif +#endif + +// BLARGG_COMPILER_HAS_BOOL: If 0, provides bool support for old compiler. If 1, +// compiler is assumed to support bool. If undefined, availability is determined. +#ifndef BLARGG_COMPILER_HAS_BOOL + #if defined (__MWERKS__) + #if !__option(bool) + #define BLARGG_COMPILER_HAS_BOOL 0 + #endif + #elif defined (_MSC_VER) + #if _MSC_VER < 1100 + #define BLARGG_COMPILER_HAS_BOOL 0 + #endif + #elif defined (__GNUC__) + // supports bool + #elif __cplusplus < 199711 + #define BLARGG_COMPILER_HAS_BOOL 0 + #endif +#endif +#if defined (BLARGG_COMPILER_HAS_BOOL) && !BLARGG_COMPILER_HAS_BOOL + // If you get errors here, modify your blargg_config.h file + typedef int bool; + const bool true = 1; + const bool false = 0; +#endif + +// blargg_long/blargg_ulong = at least 32 bits, int if it's big enough + +#if INT_MAX < 0x7FFFFFFF || LONG_MAX == 0x7FFFFFFF + typedef long blargg_long; +#else + typedef int blargg_long; +#endif + +#if UINT_MAX < 0xFFFFFFFF || ULONG_MAX == 0xFFFFFFFF + typedef unsigned long blargg_ulong; +#else + typedef unsigned blargg_ulong; +#endif + +// BOOST::int8_t etc. + +// HAVE_STDINT_H: If defined, use for int8_t etc. +#if defined (HAVE_STDINT_H) + #include + #define BOOST + +// HAVE_INTTYPES_H: If defined, use for int8_t etc. +#elif defined (HAVE_INTTYPES_H) + #include + #define BOOST + +#else + struct BOOST + { + #if UCHAR_MAX == 0xFF && SCHAR_MAX == 0x7F + typedef signed char int8_t; + typedef unsigned char uint8_t; + #else + // No suitable 8-bit type available + typedef struct see_blargg_common_h int8_t; + typedef struct see_blargg_common_h uint8_t; + #endif + + #if USHRT_MAX == 0xFFFF + typedef short int16_t; + typedef unsigned short uint16_t; + #else + // No suitable 16-bit type available + typedef struct see_blargg_common_h int16_t; + typedef struct see_blargg_common_h uint16_t; + #endif + + #if ULONG_MAX == 0xFFFFFFFF + typedef long int32_t; + typedef unsigned long uint32_t; + #elif UINT_MAX == 0xFFFFFFFF + typedef int int32_t; + typedef unsigned int uint32_t; + #else + // No suitable 32-bit type available + typedef struct see_blargg_common_h int32_t; + typedef struct see_blargg_common_h uint32_t; + #endif + }; +#endif + +#endif +#endif diff --git a/waterbox/pizza/lib/snes_spc/blargg_config.h b/waterbox/pizza/lib/snes_spc/blargg_config.h new file mode 100644 index 0000000000..9dc69db836 --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/blargg_config.h @@ -0,0 +1,24 @@ +// snes_spc 0.9.0 user configuration file. Don't replace when updating library. + +// snes_spc 0.9.0 +#ifndef BLARGG_CONFIG_H +#define BLARGG_CONFIG_H + +// Uncomment to disable debugging checks +//#define NDEBUG 1 + +// Uncomment to enable platform-specific (and possibly non-portable) optimizations +//#define BLARGG_NONPORTABLE 1 + +// Uncomment if automatic byte-order determination doesn't work +//#define BLARGG_BIG_ENDIAN 1 + +// Uncomment if you get errors in the bool section of blargg_common.h +//#define BLARGG_COMPILER_HAS_BOOL 1 + +// Use standard config.h if present +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#endif diff --git a/waterbox/pizza/lib/snes_spc/blargg_endian.h b/waterbox/pizza/lib/snes_spc/blargg_endian.h new file mode 100644 index 0000000000..f2daca6416 --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/blargg_endian.h @@ -0,0 +1,185 @@ +// CPU Byte Order Utilities + +// snes_spc 0.9.0 +#ifndef BLARGG_ENDIAN +#define BLARGG_ENDIAN + +#include "blargg_common.h" + +// BLARGG_CPU_CISC: Defined if CPU has very few general-purpose registers (< 16) +#if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \ + defined (__x86_64__) || defined (__ia64__) || defined (__i386__) + #define BLARGG_CPU_X86 1 + #define BLARGG_CPU_CISC 1 +#endif + +#if defined (__powerpc__) || defined (__ppc__) || defined (__POWERPC__) || defined (__powerc) + #define BLARGG_CPU_POWERPC 1 + #define BLARGG_CPU_RISC 1 +#endif + +// BLARGG_BIG_ENDIAN, BLARGG_LITTLE_ENDIAN: Determined automatically, otherwise only +// one may be #defined to 1. Only needed if something actually depends on byte order. +#if !defined (BLARGG_BIG_ENDIAN) && !defined (BLARGG_LITTLE_ENDIAN) +#ifdef __GLIBC__ + // GCC handles this for us + #include + #if __BYTE_ORDER == __LITTLE_ENDIAN + #define BLARGG_LITTLE_ENDIAN 1 + #elif __BYTE_ORDER == __BIG_ENDIAN + #define BLARGG_BIG_ENDIAN 1 + #endif +#else + +#if defined (LSB_FIRST) || defined (__LITTLE_ENDIAN__) || BLARGG_CPU_X86 || \ + (defined (LITTLE_ENDIAN) && LITTLE_ENDIAN+0 != 1234) + #define BLARGG_LITTLE_ENDIAN 1 +#endif + +#if defined (MSB_FIRST) || defined (__BIG_ENDIAN__) || defined (WORDS_BIGENDIAN) || \ + defined (__sparc__) || BLARGG_CPU_POWERPC || \ + (defined (BIG_ENDIAN) && BIG_ENDIAN+0 != 4321) + #define BLARGG_BIG_ENDIAN 1 +#elif !defined (__mips__) + // No endian specified; assume little-endian, since it's most common + #define BLARGG_LITTLE_ENDIAN 1 +#endif +#endif +#endif + +#if BLARGG_LITTLE_ENDIAN && BLARGG_BIG_ENDIAN + #undef BLARGG_LITTLE_ENDIAN + #undef BLARGG_BIG_ENDIAN +#endif + +inline void blargg_verify_byte_order() +{ + #ifndef NDEBUG + #if BLARGG_BIG_ENDIAN + volatile int i = 1; + assert( *(volatile char*) &i == 0 ); + #elif BLARGG_LITTLE_ENDIAN + volatile int i = 1; + assert( *(volatile char*) &i != 0 ); + #endif + #endif +} + +inline unsigned get_le16( void const* p ) +{ + return (unsigned) ((unsigned char const*) p) [1] << 8 | + (unsigned) ((unsigned char const*) p) [0]; +} + +inline unsigned get_be16( void const* p ) +{ + return (unsigned) ((unsigned char const*) p) [0] << 8 | + (unsigned) ((unsigned char const*) p) [1]; +} + +inline blargg_ulong get_le32( void const* p ) +{ + return (blargg_ulong) ((unsigned char const*) p) [3] << 24 | + (blargg_ulong) ((unsigned char const*) p) [2] << 16 | + (blargg_ulong) ((unsigned char const*) p) [1] << 8 | + (blargg_ulong) ((unsigned char const*) p) [0]; +} + +inline blargg_ulong get_be32( void const* p ) +{ + return (blargg_ulong) ((unsigned char const*) p) [0] << 24 | + (blargg_ulong) ((unsigned char const*) p) [1] << 16 | + (blargg_ulong) ((unsigned char const*) p) [2] << 8 | + (blargg_ulong) ((unsigned char const*) p) [3]; +} + +inline void set_le16( void* p, unsigned n ) +{ + ((unsigned char*) p) [1] = (unsigned char) (n >> 8); + ((unsigned char*) p) [0] = (unsigned char) n; +} + +inline void set_be16( void* p, unsigned n ) +{ + ((unsigned char*) p) [0] = (unsigned char) (n >> 8); + ((unsigned char*) p) [1] = (unsigned char) n; +} + +inline void set_le32( void* p, blargg_ulong n ) +{ + ((unsigned char*) p) [0] = (unsigned char) n; + ((unsigned char*) p) [1] = (unsigned char) (n >> 8); + ((unsigned char*) p) [2] = (unsigned char) (n >> 16); + ((unsigned char*) p) [3] = (unsigned char) (n >> 24); +} + +inline void set_be32( void* p, blargg_ulong n ) +{ + ((unsigned char*) p) [3] = (unsigned char) n; + ((unsigned char*) p) [2] = (unsigned char) (n >> 8); + ((unsigned char*) p) [1] = (unsigned char) (n >> 16); + ((unsigned char*) p) [0] = (unsigned char) (n >> 24); +} + +#if BLARGG_NONPORTABLE + // Optimized implementation if byte order is known + #if BLARGG_LITTLE_ENDIAN + #define GET_LE16( addr ) (*(BOOST::uint16_t*) (addr)) + #define GET_LE32( addr ) (*(BOOST::uint32_t*) (addr)) + #define SET_LE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data)) + #define SET_LE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data)) + #elif BLARGG_BIG_ENDIAN + #define GET_BE16( addr ) (*(BOOST::uint16_t*) (addr)) + #define GET_BE32( addr ) (*(BOOST::uint32_t*) (addr)) + #define SET_BE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data)) + #define SET_BE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data)) + + #if BLARGG_CPU_POWERPC + // PowerPC has special byte-reversed instructions + #if defined (__MWERKS__) + #define GET_LE16( addr ) (__lhbrx( addr, 0 )) + #define GET_LE32( addr ) (__lwbrx( addr, 0 )) + #define SET_LE16( addr, in ) (__sthbrx( in, addr, 0 )) + #define SET_LE32( addr, in ) (__stwbrx( in, addr, 0 )) + #elif defined (__GNUC__) + #define GET_LE16( addr ) ({unsigned ppc_lhbrx_; asm( "lhbrx %0,0,%1" : "=r" (ppc_lhbrx_) : "r" (addr), "0" (ppc_lhbrx_) ); ppc_lhbrx_;}) + #define GET_LE32( addr ) ({unsigned ppc_lwbrx_; asm( "lwbrx %0,0,%1" : "=r" (ppc_lwbrx_) : "r" (addr), "0" (ppc_lwbrx_) ); ppc_lwbrx_;}) + #define SET_LE16( addr, in ) ({asm( "sthbrx %0,0,%1" : : "r" (in), "r" (addr) );}) + #define SET_LE32( addr, in ) ({asm( "stwbrx %0,0,%1" : : "r" (in), "r" (addr) );}) + #endif + #endif + #endif +#endif + +#ifndef GET_LE16 + #define GET_LE16( addr ) get_le16( addr ) + #define SET_LE16( addr, data ) set_le16( addr, data ) +#endif + +#ifndef GET_LE32 + #define GET_LE32( addr ) get_le32( addr ) + #define SET_LE32( addr, data ) set_le32( addr, data ) +#endif + +#ifndef GET_BE16 + #define GET_BE16( addr ) get_be16( addr ) + #define SET_BE16( addr, data ) set_be16( addr, data ) +#endif + +#ifndef GET_BE32 + #define GET_BE32( addr ) get_be32( addr ) + #define SET_BE32( addr, data ) set_be32( addr, data ) +#endif + +// auto-selecting versions + +inline void set_le( BOOST::uint16_t* p, unsigned n ) { SET_LE16( p, n ); } +inline void set_le( BOOST::uint32_t* p, blargg_ulong n ) { SET_LE32( p, n ); } +inline void set_be( BOOST::uint16_t* p, unsigned n ) { SET_BE16( p, n ); } +inline void set_be( BOOST::uint32_t* p, blargg_ulong n ) { SET_BE32( p, n ); } +inline unsigned get_le( BOOST::uint16_t* p ) { return GET_LE16( p ); } +inline blargg_ulong get_le( BOOST::uint32_t* p ) { return GET_LE32( p ); } +inline unsigned get_be( BOOST::uint16_t* p ) { return GET_BE16( p ); } +inline blargg_ulong get_be( BOOST::uint32_t* p ) { return GET_BE32( p ); } + +#endif diff --git a/waterbox/pizza/lib/snes_spc/blargg_source.h b/waterbox/pizza/lib/snes_spc/blargg_source.h new file mode 100644 index 0000000000..5e45c4fb42 --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/blargg_source.h @@ -0,0 +1,100 @@ +/* Included at the beginning of library source files, after all other #include lines. +Sets up helpful macros and services used in my source code. They don't need +module an annoying module prefix on their names since they are defined after +all other #include lines. */ + +// snes_spc 0.9.0 +#ifndef BLARGG_SOURCE_H +#define BLARGG_SOURCE_H + +// If debugging is enabled, abort program if expr is false. Meant for checking +// internal state and consistency. A failed assertion indicates a bug in the module. +// void assert( bool expr ); +#include + +// If debugging is enabled and expr is false, abort program. Meant for checking +// caller-supplied parameters and operations that are outside the control of the +// module. A failed requirement indicates a bug outside the module. +// void require( bool expr ); +#undef require +#define require( expr ) assert( expr ) + +// Like printf() except output goes to debug log file. Might be defined to do +// nothing (not even evaluate its arguments). +// void dprintf( const char* format, ... ); +static inline void blargg_dprintf_( const char*, ... ) { } +#undef dprintf +#define dprintf (1) ? (void) 0 : blargg_dprintf_ + +// If enabled, evaluate expr and if false, make debug log entry with source file +// and line. Meant for finding situations that should be examined further, but that +// don't indicate a problem. In all cases, execution continues normally. +#undef check +#define check( expr ) ((void) 0) + +// If expr yields error string, return it from current function, otherwise continue. +#undef RETURN_ERR +#define RETURN_ERR( expr ) do { \ + blargg_err_t blargg_return_err_ = (expr); \ + if ( blargg_return_err_ ) return blargg_return_err_; \ + } while ( 0 ) + +// If ptr is 0, return out of memory error string. +#undef CHECK_ALLOC +#define CHECK_ALLOC( ptr ) do { if ( (ptr) == 0 ) return "Out of memory"; } while ( 0 ) + +// Avoid any macros which evaluate their arguments multiple times +#undef min +#undef max + +#define DEF_MIN_MAX( type ) \ + static inline type min( type x, type y ) { if ( x < y ) return x; return y; }\ + static inline type max( type x, type y ) { if ( y < x ) return x; return y; } + +DEF_MIN_MAX( int ) +DEF_MIN_MAX( unsigned ) +DEF_MIN_MAX( long ) +DEF_MIN_MAX( unsigned long ) +DEF_MIN_MAX( float ) +DEF_MIN_MAX( double ) + +#undef DEF_MIN_MAX + +/* +// using const references generates crappy code, and I am currenly only using these +// for built-in types, so they take arguments by value + +// TODO: remove +inline int min( int x, int y ) +template +inline T min( T x, T y ) +{ + if ( x < y ) + return x; + return y; +} + +template +inline T max( T x, T y ) +{ + if ( x < y ) + return y; + return x; +} +*/ + +// TODO: good idea? bad idea? +#undef byte +#define byte byte_ +typedef unsigned char byte; + +// deprecated +#define BLARGG_CHECK_ALLOC CHECK_ALLOC +#define BLARGG_RETURN_ERR RETURN_ERR + +// BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of dprintf and check +#ifdef BLARGG_SOURCE_BEGIN + #include BLARGG_SOURCE_BEGIN +#endif + +#endif diff --git a/waterbox/pizza/lib/snes_spc/changes.txt b/waterbox/pizza/lib/snes_spc/changes.txt new file mode 100644 index 0000000000..33661832b4 --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/changes.txt @@ -0,0 +1,107 @@ +snes_spc Change Log +------------------- + +snes_spc 0.9.0 +-------------- +- Improved documentation + +- SPC: Added spc_skip() function for quickly seeking in an SPC music +file. Runs 3-4x faster than normal playback using the fast DSP (or about +43-60X real-time on my 400 MHz Mac). + +- SPC: Added spc_set_tempo() to change tempo of SPC music playback. + +- SPC: Sample generation is now corrected to generate exactly one pair +of samples every 32 clocks without exception. Before it could generate a +few samples more or less depending on how far ahead or behind DSP was at +the moment. + +- SPC: Changed spc_reset() and spc_soft_reset() to also reset output +buffer (see spc.h). + +- SPC: Fixed minor timer counting bug. + +- SPC: Stack pointer wrap-around is now emulated (and without any +noticeable performance hit). + +- SPC: Runs about 5% faster due to various optimizations. + +- SPC: Found way to make fast DSP register accesses cycle-accurate in +most cases, without reducing performance. Allows fast DSP to pass most +of my validation tests. + +- DSP: Added surround disable support to fast DSP again. + +- DSP: Improved voice un-muting to take effect immediately on fast DSP. + +- DSP: Noise shift register now starts at 0x4000 instead of 0x4001 as it +incorrectly did before. + +- Converted library to C++ code internally. A C interface is still +included in spc.h and dsp.h. Note that these are different than the +previous interface, so your code will require minor changes: + + Old SPC code New SPC code + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + #include "spc/spc.h" #include "snes_spc/spc.h" + + snes_spc_t* spc; SNES_SPC* spc; + spc = malloc( sizeof (snes_spc_t) ); spc = spc_new(); + spc_init( spc ); + + spc_end_frame( time ); spc_end_frame( spc, time ); + /* etc. */ + + /* done using SPC */ spc_delete( spc ); + + + Old DSP code New DSP code + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + #include "spc/spc_dsp.h" #include "snes_spc/dsp.h" + + spc_dsp_init( ram ); SPC_DSP* dsp; + dsp = spc_dsp_new(); + spc_dsp_init( dsp, ram ); + + spc_dsp_run( count ); spc_dsp_run( dsp, count ); + /* etc. */ + + /* done using DSP */ spc_dsp_delete( dsp ); + + +snes_spc 0.8.0 +-------------- +- Added several demos + +- Added high-pass/low-pass filter to better match SNES sound + +- Added save state functionality for SPC and accurate DSP (but not fast +DSP) + +- Added emulation of reset switch on NES (soft reset) + +- Made source more compatible with pre-C99 compilers by eliminating +mid-block declarations + +- SPC: Many S-SMP accuracy improvements, mostly in memory access times + +- SPC: S-SMP speed improvements + +- SPC: Added SPC load/save functions and KON checking to help trim +silence from beginning + +- SPC: Changed spc_init() to have you allocate most of the memory used +by the library so you have more control over it + +- DSP: New highly accurate DSP and faster version derived from same code + +- DSP: Changed prefix from dsp_ to spc_dsp_. Your DSP code will require +changes. + +- DSP: Removed surround disable and gain. Gain can now be done with the +dsp_filter module, and surround disable will probably only be +implemented in the fast DSP at some point. + +- DSP: Changed interface to work in clocks rather than samples, +necessary for the new accurate DSP. Sample output is now done with +separate functions. Your DSP code will require changes. diff --git a/waterbox/pizza/lib/snes_spc/dsp.cpp b/waterbox/pizza/lib/snes_spc/dsp.cpp new file mode 100644 index 0000000000..99d0cf5c5e --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/dsp.cpp @@ -0,0 +1,48 @@ +// snes_spc 0.9.0. http://www.slack.net/~ant/ + +#include "dsp.h" + +#include "SPC_DSP.h" + +/* Copyright (C) 2007 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "blargg_source.h" + +SPC_DSP* spc_dsp_new( void ) +{ + // be sure constants match + assert( spc_dsp_voice_count == (int) SPC_DSP::voice_count ); + assert( spc_dsp_register_count == (int) SPC_DSP::register_count ); + #if !SPC_NO_COPY_STATE_FUNCS + assert( spc_dsp_state_size == (int) SPC_DSP::state_size ); + #endif + + return new SPC_DSP; +} + +void spc_dsp_delete ( SPC_DSP* s ) { delete s; } +void spc_dsp_init ( SPC_DSP* s, void* ram_64k ) { s->init( ram_64k ); } +void spc_dsp_set_output ( SPC_DSP* s, spc_dsp_sample_t* p, int n ) { s->set_output( p, n ); } +int spc_dsp_sample_count( SPC_DSP const* s ) { return s->sample_count(); } +void spc_dsp_reset ( SPC_DSP* s ) { s->reset(); } +void spc_dsp_soft_reset ( SPC_DSP* s ) { s->soft_reset(); } +int spc_dsp_read ( SPC_DSP const* s, int addr ) { return s->read( addr ); } +void spc_dsp_write ( SPC_DSP* s, int addr, int data ) { s->write( addr, data ); } +void spc_dsp_run ( SPC_DSP* s, int clock_count ) { s->run( clock_count ); } +void spc_dsp_mute_voices ( SPC_DSP* s, int mask ) { s->mute_voices( mask ); } +void spc_dsp_disable_surround( SPC_DSP* s, int disable ) { s->disable_surround( disable ); } +void spc_dsp_load ( SPC_DSP* s, unsigned char const regs [spc_dsp_register_count] ) { s->load( regs ); } + +#if !SPC_NO_COPY_STATE_FUNCS +void spc_dsp_copy_state ( SPC_DSP* s, unsigned char** p, spc_dsp_copy_func_t f ) { s->copy_state( p, f ); } +int spc_dsp_check_kon ( SPC_DSP* s ) { return s->check_kon(); } +#endif diff --git a/waterbox/pizza/lib/snes_spc/dsp.h b/waterbox/pizza/lib/snes_spc/dsp.h new file mode 100644 index 0000000000..59867d92f9 --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/dsp.h @@ -0,0 +1,83 @@ +/* SNES SPC-700 DSP emulator C interface (also usable from C++) */ + +/* snes_spc 0.9.0 */ +#ifndef DSP_H +#define DSP_H + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct SPC_DSP SPC_DSP; + +/* Creates new DSP emulator. NULL if out of memory. */ +SPC_DSP* spc_dsp_new( void ); + +/* Frees DSP emulator */ +void spc_dsp_delete( SPC_DSP* ); + +/* Initializes DSP and has it use the 64K RAM provided */ +void spc_dsp_init( SPC_DSP*, void* ram_64k ); + +/* Sets destination for output samples. If out is NULL or out_size is 0, +doesn't generate any. */ +typedef short spc_dsp_sample_t; +void spc_dsp_set_output( SPC_DSP*, spc_dsp_sample_t* out, int out_size ); + +/* Number of samples written to output since it was last set, always +a multiple of 2. Undefined if more samples were generated than +output buffer could hold. */ +int spc_dsp_sample_count( SPC_DSP const* ); + + +/**** Emulation *****/ + +/* Resets DSP to power-on state */ +void spc_dsp_reset( SPC_DSP* ); + +/* Emulates pressing reset switch on SNES */ +void spc_dsp_soft_reset( SPC_DSP* ); + +/* Reads/writes DSP registers. For accuracy, you must first call spc_dsp_run() */ +/* to catch the DSP up to present. */ +int spc_dsp_read ( SPC_DSP const*, int addr ); +void spc_dsp_write( SPC_DSP*, int addr, int data ); + +/* Runs DSP for specified number of clocks (~1024000 per second). Every 32 clocks */ +/* a pair of samples is be generated. */ +void spc_dsp_run( SPC_DSP*, int clock_count ); + + +/**** Sound control *****/ + +/* Mutes voices corresponding to non-zero bits in mask. Reduces emulation accuracy. */ +enum { spc_dsp_voice_count = 8 }; +void spc_dsp_mute_voices( SPC_DSP*, int mask ); + +/* If true, prevents channels and global volumes from being phase-negated. +Only supported by fast DSP; has no effect on accurate DSP. */ +void spc_dsp_disable_surround( SPC_DSP*, int disable ); + + +/**** State save/load *****/ + +/* Resets DSP and uses supplied values to initialize registers */ +enum { spc_dsp_register_count = 128 }; +void spc_dsp_load( SPC_DSP*, unsigned char const regs [spc_dsp_register_count] ); + +/* Saves/loads exact emulator state (accurate DSP only) */ +enum { spc_dsp_state_size = 640 }; /* maximum space needed when saving */ +typedef void (*spc_dsp_copy_func_t)( unsigned char** io, void* state, size_t ); +void spc_dsp_copy_state( SPC_DSP*, unsigned char** io, spc_dsp_copy_func_t ); + +/* Returns non-zero if new key-on events occurred since last call (accurate DSP only) */ +int spc_dsp_check_kon( SPC_DSP* ); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/waterbox/pizza/lib/snes_spc/license.txt b/waterbox/pizza/lib/snes_spc/license.txt new file mode 100644 index 0000000000..5faba9d48c --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/license.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/waterbox/pizza/lib/snes_spc/readme.txt b/waterbox/pizza/lib/snes_spc/readme.txt new file mode 100644 index 0000000000..979913f0ac --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/readme.txt @@ -0,0 +1,86 @@ +snes_spc 0.9.0: SNES SPC-700 APU Emulator +----------------------------------------- +This library includes a full SPC emulator and an S-DSP emulator that can +be used on its own. Two S-DSP emulators are available: a highly accurate +one for use in a SNES emulator, and a 3x faster one for use in an SPC +music player or a resource-limited SNES emulator. + +* Can be used from C and C++ code +* Full SPC-700 APU emulator with cycle accuracy in most cases +* Loads, plays, and saves SPC music files +* Can save and load exact full emulator state +* DSP voice muting, surround sound disable, and song tempo adjustment +* Uses 7% CPU average on 400 MHz Mac to play an SPC using fast DSP + +The accurate DSP emulator is based on past research by others and +hundreds of hours of recent research by me. It passes over a hundred +strenuous timing and behavior validation tests that were also run on the +SNES. As far as I know, it's the first DSP emulator with cycle accuracy, +properly emulating every DSP register and memory access at the exact SPC +cycle it occurs at, whereas previous DSP emulators emulated these only +to the nearest sample (which occurs every 32 clocks). + +Author : Shay Green +Website: http://www.slack.net/~ant/ +Forum : http://groups.google.com/group/blargg-sound-libs +License: GNU Lesser General Public License (LGPL) + + +Getting Started +--------------- +Build a program consisting of demo/play_spc.c, demo/demo_util.c, +demo/wave_writer.c, and all source files in snes_spc/. Put an SPC music +file in the same directory and name it "test.spc". Running the program +should generate the recording "out.wav". + +Read snes_spc.txt for more information. Post to the discussion forum for +assistance. + + +Files +----- +snes_spc.txt Documentation +changes.txt Change log +license.txt GNU LGPL license + +demo/ + play_spc.c Records SPC file to wave sound file + benchmark.c Finds how fast emulator runs on your computer + trim_spc.c Trims silence off beginning of an SPC file + save_state.c Saves/loads exact emulator state to/from file + comm.c Communicates with SPC how SNES would + demo_util.h General utility functions used by demos + demo_util.c + wave_writer.h WAVE sound file writer used for demo output + wave_writer.c + +fast_dsp/ Optional standalone fast DSP emulator + SPC_DSP.h To use with full SPC emulator, move into + SPC_DSP.cpp snes_spc/ and replace original files + +snes_spc/ Library sources + blargg_config.h Configuration (modify as necessary) + + spc.h C interface to SPC emulator and sound filter + spc.cpp + + SPC_Filter.h Optional filter to make sound more authentic + SPC_Filter.cpp + + SNES_SPC.h Full SPC emulator + SNES_SPC.cpp + SNES_SPC_misc.cpp + SNES_SPC_state.cpp + SPC_CPU.h + + dsp.h C interface to DSP emulator + dsp.cpp + + SPC_DSP.h Standalone accurate DSP emulator + SPC_DSP.cpp + blargg_common.h + blargg_endian.h + blargg_source.h + +-- +Shay Green diff --git a/waterbox/pizza/lib/snes_spc/snes_spc.txt b/waterbox/pizza/lib/snes_spc/snes_spc.txt new file mode 100644 index 0000000000..d37b34347f --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/snes_spc.txt @@ -0,0 +1,318 @@ +snes_spc 0.9.0: SNES SPC-700 APU Emulator +----------------------------------------- +Author : Shay Green +Website: http://www.slack.net/~ant/ +Forum : http://groups.google.com/group/blargg-sound-libs +License: GNU Lesser General Public License (LGPL) + + +Contents +-------- +* C and C++ Interfaces +* Overview +* Full SPC Emulation +* DSP Emulation +* SPC Music Playback +* State Copying +* Library Compilation +* Error handling +* Solving Problems +* Accurate S-DSP Limitations +* Fast S-DSP Limitations +* S-SMP Limitations +* To Do +* Thanks + + +C and C++ Interfaces +-------------------- +The library includes a C interface in spc.h and dsp.h, which can be used +from C and C++. This C interface is referred to in the following +documentation. If you're building this as a shared library (rather than +linking statically), you should use the C interface since it will change +less in future versions. + +The native C++ interface is in the header files SNES_SPC.h, SPC_DSP.h, +and SPC_Filter.h, and the two interfaces can be freely mixed in C++ +code. Conversion between the two interfaces generally follows a pattern: + + C interface C++ interface + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + SNES_SPC* spc; SNES_SPC* spc; + + spc = spc_new(); spc = new SNES_SPC; + + spc_play( spc, count, buf ); spc->play( count, buf ); + + spc_sample_rate SNES_SPC::sample_rate + + spc_delete( spc ); delete spc; + + +Overview +-------- +There are three main roles for this library: +* Full SPC emulation in a SNES emulator +* DSP emulation in a SNES emulator (where you emulate the SMP CPU) +* SPC playback in an SPC music file player + +Each of these uses are described separately below. + + +Full SPC Emulation +------------------ +See spc.h for full function reference (SNES_SPC.h if using C++). + +* Create SPC emulator with spc_new() and check for NULL. + +* Call spc_init_rom() with a pointer to the 64-byte IPL ROM dump (not +included with library). + +* When your emulated SNES is powered on, call spc_reset(). When the +reset switch is pressed, call spc_soft_reset(). + +* Call spc_set_output() with your output buffer, then do emulation. + +* When the SNES CPU accesses APU ports, call spc_read_port() and +spc_write_port(). + +* When your emulator's timebase is going back to 0, call +spc_end_frame(), usually at the end of a video frame or scanline. + +* Periodically play samples from your buffer. Use spc_sample_count() to +find out how many samples have been written, then spc_set_output() after +you've made more space in your buffer. + +* Save/load full emulator state with spc_copy_state(). + +* You can save as an SPC music file with spc_save_spc(). + +* When done, use spc_delete() to free memory. + + +DSP Emulation +------------- +See dsp.h for full function reference (SPC_DSP.h if using C++). + +* Create DSP emulator with spc_dsp_new() and check for NULL. + +* Let the DSP know where your 64K RAM is with spc_dsp_init(). + +* When your emulated SNES is powered on, call spc_dsp_reset(). When the +reset switch is pressed, call spc_dsp_soft_reset(). + +* Call spc_dsp_set_output() with your output buffer, then do emulation. + +* Use spc_dsp_run() to run DSP for specified number of clocks (1024000 +per second). Every 32 clocks a pair of samples is added to your output +buffer. + +* Use spc_dsp_read() and spc_dsp_write() to handle DSP reads/writes from +the S-SMP. Before calling these always catch the DSP up to present time +with spc_dsp_run(). + +* Periodically play samples from your buffer. Use spc_dsp_sample_count() +to find out how many samples have been written, then +spc_dsp_set_output() after you've made more space in your buffer. + +* Use spc_dsp_copy_state() to save/load full DSP state. + +* When done, use spc_delete() to free memory. + + +SPC Music Playback +------------------ +See spc.h for full function reference (SNES_SPC.h if using C++). + +* Create SPC emulator with spc_new() and check for NULL. + +* Load SPC with spc_load_spc() and check for error. + +* Optionally cear echo buffer with spc_clear_echo(). Many SPCs have +garbage in echo buffer, which causes noise at the beginning. + +* Generate samples as needed with spc_play(). + +* When done, use spc_delete() to free memory. + +* For a more complete game music playback library, use Game_Music_Emu + + +State Copying +------------- +The SPC and DSP modules include state save/load functions. They take a +pointer to a pointer to a buffer to store state, and a copy function. +This copy function can either copy data to the buffer or from it, +allowing state save and restore with the same library function. The +internal save state format allows for future expansion without making +previous save states unusable. + +The SPC save state format puts the most important parts first to make it +easier to manually examine. It's organized as follows: + +Offset Size Data +- - - - - - - - - - - - - - - - - - + 0 $10000 SPC RAM +$10000 $10 SMP $F0-$FF registers +$10010 4 SMP $F4-$F8 output registers +$10014 2 PC +$10016 1 A +$10017 1 X +$10018 1 Y +$10019 1 PSW +$1001A 1 SP +$1001B 5 internal +$10020 $80 DSP registers +$100A0 ... internal + + +Library Compilation +------------------- +While this library is in C++, it has been written to easily link in a C +program *without* needing the standard C++ library. It doesn't use +exception handling or run-time type information (RTTI), so you can +disable these in your C++ compiler to increase efficiency. + +If you're building a shared library (DLL), I recommend only exporting +the C interfaces in spc.h and dsp.h, as the C++ interfaces expose +implementation details that will break link compatibility across +versions. + +If you're using C and compiling with GCC, I recommend the following +command-line options when compiling the library source, otherwise GCC +will insert calls to the standard C++ library and require that it be +linked in: + + -fno-rtti -fno-exceptions + +For maximum optimization, see the NDEBUG and BLARGG_NONPORTABLE options +in blargg_config. If using GCC, you can enable these by adding the +following command-line options when you invoke gcc. If you encounter +problems, try without -DBLARGG_NONPORTABLE; if that works, contact me so +I can figure out why BLARGG_NONPORTABLE was causing it to fail. + + -O3 -DNDEBUG -DBLARGG_NONPORTABLE -fno-rtti -fno-exceptions + + + +Error handling +-------------- +Functions which can fail have a return type of spc_err_t (blargg_err_t +in the C++ interfaces), which is a pointer to an error string (const +char*). If a function is successful it returns NULL. Errors that you can +easily avoid are checked with debug assertions; spc_err_t return values +are only used for genuine run-time errors that can't be easily predicted +in advance (out of memory, I/O errors, incompatible file data). Your +code should check all error values. + +To improve usability for C programmers, C++ programmers unfamiliar with +exceptions, and compatibility with older C++ compilers, the library does +*not* throw any C++ exceptions and uses malloc() instead of the standard +operator new. This means that you *must* check for NULL when creating a +library object with the new operator. + + +Solving Problems +---------------- +If you're having problems, try the following: + +* If you're getting garbled sound, try this simple siren generator in +place of your call to play(). This will quickly tell whether the problem +is in the library or in your code. + + static void play_siren( long count, short* out ) + { + static double a, a2; + while ( count-- ) + *out++ = 0x2000 * sin( a += .1 + .05*sin( a2+=.00005 ) ); + } + +* Enable debugging support in your environment. This enables assertions +and other run-time checks. + +* Turn the compiler's optimizer is off. Sometimes an optimizer generates +bad code. + +* If multiple threads are being used, ensure that only one at a time is +accessing a given set of objects from the library. This library is not +in general thread-safe, though independent objects can be used in +separate threads. + +* If all else fails, see if the demos work. + + +Accurate S-DSP Limitations +-------------------------- +* Power-up and soft reset behavior might have slight inaccuracies. + +* Muting (FLG bit 6) behavior when toggling bit very rapidly is not +emulated properly. + +* No other known inaccuracies. Has passed 100+ strenuous tests. + + +Fast S-DSP Limitations +---------------------- +* Uses faster sample calculations except in cases where exact value is +actually important (BRR decoding, and gaussian interpolation combined +with pitch modulation). + +* Stops decoding BRR data when a voice's envelope has released to +silence. + +* Emulates 32 clocks at a time, so DSP register and memory accesses are +all done in a bunch rather than spread out. Even though, some clever +code makes register accesses separated by 40 or so clocks occur with +cycle-accurate timing. + + +S-SMP Limitations +----------------- +* Opcode fetches and indirect pointers are always read directly from +memory, even for the $F0-$FF region, and the DSP is not caught up for +these fetches. + +* Attempts to perversely execute data in registers or an area being +modified by echo will not be emulated properly. + +* Has not been thoroughly tested. + +* Test register ($F0) is not implemented. + +* Echo buffer can overwrite IPL ROM area, and does not correctly update +extra RAM there. + + +To Do +----- +* I'd like feedback on the interface and any ways to improve it. In +particular, the differing features between the accurate and fast DSP +emulators might make it harder to cleanly switch between them without +modifying source code. + +* Finish thorough tests on SMP memory access times. + +* Finish thorough tests on SMP instruction behavior (flags, registers). + +* Finish thorough tests on SMP timers. + +* Finish power-up and reset behavior testing. + +* Come up with best starting conditions to play an SPC and implement in +hardware SNES SPC player for verification. + + +Thanks +------ +Thanks to Anti-Resonance's SPC2ROM and help getting SPCs playing on my +SNES in the first place, then Brad Martin's openspc and Chris Moeller's +openspc++ C++ adaptation, giving me a good SPC emulator to start with +several years ago. Thanks to Richard Bannister, Mahendra Tallur, Shazz, +nenolod, theHobbit, Johan Samuelsson, nes6502, and Micket for helping +test my Game_Music_Emu library. Thanks to hcs for help in converting to +C for the Rockbox port. Thanks to byuu (bsnes author) and pagefault and +Nach (zsnes team) for testing and using my new rewritten DSP in their +emulators. Thanks to anomie for his good SNES documentation and +discussions with me to keep it up to date with my latest findings. +-- +Shay Green diff --git a/waterbox/pizza/lib/snes_spc/spc.cpp b/waterbox/pizza/lib/snes_spc/spc.cpp new file mode 100644 index 0000000000..4e5a77ef15 --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/spc.cpp @@ -0,0 +1,74 @@ +// snes_spc 0.9.0. http://www.slack.net/~ant/ + +#include "spc.h" + +#include "SNES_SPC.h" +#include "SPC_Filter.h" + +/* Copyright (C) 2004-2007 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "blargg_source.h" + +SNES_SPC* spc_new( void ) +{ + // be sure constants match + assert( spc_sample_rate == (int) SNES_SPC::sample_rate ); + assert( spc_rom_size == (int) SNES_SPC::rom_size ); + assert( spc_clock_rate == (int) SNES_SPC::clock_rate ); + assert( spc_clocks_per_sample == (int) SNES_SPC::clocks_per_sample ); + assert( spc_port_count == (int) SNES_SPC::port_count ); + assert( spc_voice_count == (int) SNES_SPC::voice_count ); + assert( spc_tempo_unit == (int) SNES_SPC::tempo_unit ); + assert( spc_file_size == (int) SNES_SPC::spc_file_size ); + #if !SPC_NO_COPY_STATE_FUNCS + assert( spc_state_size == (int) SNES_SPC::state_size ); + #endif + + SNES_SPC* s = new SNES_SPC; + if ( s && s->init() ) + { + delete s; + s = 0; + } + return s; +} + +void spc_delete ( SNES_SPC* s ) { delete s; } +void spc_init_rom ( SNES_SPC* s, unsigned char const r [64] ) { s->init_rom( r ); } +void spc_set_output ( SNES_SPC* s, spc_sample_t* p, int n ) { s->set_output( p, n ); } +int spc_sample_count ( SNES_SPC const* s ) { return s->sample_count(); } +void spc_reset ( SNES_SPC* s ) { s->reset(); } +void spc_soft_reset ( SNES_SPC* s ) { s->soft_reset(); } +int spc_read_port ( SNES_SPC* s, spc_time_t t, int p ) { return s->read_port( t, p ); } +void spc_write_port ( SNES_SPC* s, spc_time_t t, int p, int d ) { s->write_port( t, p, d ); } +void spc_end_frame ( SNES_SPC* s, spc_time_t t ) { s->end_frame( t ); } +void spc_mute_voices ( SNES_SPC* s, int mask ) { s->mute_voices( mask ); } +void spc_disable_surround( SNES_SPC* s, int disable ) { s->disable_surround( disable ); } +void spc_set_tempo ( SNES_SPC* s, int tempo ) { s->set_tempo( tempo ); } +uint8_t* spc_get_ram(SNES_SPC* s) { return s->get_ram(); } +spc_err_t spc_load_spc ( SNES_SPC* s, void const* p, long n ) { return s->load_spc( p, n ); } +void spc_clear_echo ( SNES_SPC* s ) { s->clear_echo(); } +spc_err_t spc_play ( SNES_SPC* s, int count, short* out ) { return s->play( count, out ); } +spc_err_t spc_skip ( SNES_SPC* s, int count ) { return s->skip( count ); } +#if !SPC_NO_COPY_STATE_FUNCS +void spc_copy_state ( SNES_SPC* s, unsigned char** p, spc_copy_func_t f ) { s->copy_state( p, f ); } +void spc_init_header ( void* spc_out ) { SNES_SPC::init_header( spc_out ); } +void spc_save_spc ( SNES_SPC* s, void* spc_out ) { s->save_spc( spc_out ); } +int spc_check_kon ( SNES_SPC* s ) { return s->check_kon(); } +#endif + +SPC_Filter* spc_filter_new( void ) { return new SPC_Filter; } +void spc_filter_delete( SPC_Filter* f ) { delete f; } +void spc_filter_run( SPC_Filter* f, spc_sample_t* p, int s ) { f->run( p, s ); } +void spc_filter_clear( SPC_Filter* f ) { f->clear(); } +void spc_filter_set_gain( SPC_Filter* f, int gain ) { f->set_gain( gain ); } +void spc_filter_set_bass( SPC_Filter* f, int bass ) { f->set_bass( bass ); } diff --git a/waterbox/pizza/lib/snes_spc/spc.h b/waterbox/pizza/lib/snes_spc/spc.h new file mode 100644 index 0000000000..cf23f3c945 --- /dev/null +++ b/waterbox/pizza/lib/snes_spc/spc.h @@ -0,0 +1,149 @@ +/* SNES SPC-700 APU emulator C interface (also usable from C++) */ + +/* snes_spc 0.9.0 */ +#ifndef SPC_H +#define SPC_H + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/* Error string return. NULL if success, otherwise error message. */ +typedef const char* spc_err_t; + +typedef struct SNES_SPC SNES_SPC; + +/* Creates new SPC emulator. NULL if out of memory. */ +SNES_SPC* spc_new( void ); + +/* Frees SPC emulator */ +void spc_delete( SNES_SPC* ); + +/* Sample pairs generated per second */ +enum { spc_sample_rate = 32000 }; + + +/**** Emulator use ****/ + +/* Sets IPL ROM data. Library does not include ROM data. Most SPC music files +don't need ROM, but a full emulator must provide this. */ +enum { spc_rom_size = 0x40 }; +void spc_init_rom( SNES_SPC*, unsigned char const rom [spc_rom_size] ); + +/* Sets destination for output samples */ +typedef short spc_sample_t; +void spc_set_output( SNES_SPC*, spc_sample_t* out, int out_size ); + +/* Number of samples written to output since last set */ +int spc_sample_count( SNES_SPC const* ); + +/* Resets SPC to power-on state. This resets your output buffer, so you must +call spc_set_output() after this. */ +void spc_reset( SNES_SPC* ); + +/* Emulates pressing reset switch on SNES. This resets your output buffer, so +you must call spc_set_output() after this. */ +void spc_soft_reset( SNES_SPC* ); + +/* 1024000 SPC clocks per second, sample pair every 32 clocks */ +typedef int spc_time_t; +enum { spc_clock_rate = 1024000 }; +enum { spc_clocks_per_sample = 32 }; + +/* Reads/writes port at specified time */ +enum { spc_port_count = 4 }; +int spc_read_port ( SNES_SPC*, spc_time_t, int port ); +void spc_write_port( SNES_SPC*, spc_time_t, int port, int data ); + +/* Runs SPC to end_time and starts a new time frame at 0 */ +void spc_end_frame( SNES_SPC*, spc_time_t end_time ); + +uint8_t* spc_get_ram(SNES_SPC*); + +/**** Sound control ****/ + +/*Mutes voices corresponding to non-zero bits in mask. Reduces emulation accuracy. */ +enum { spc_voice_count = 8 }; +void spc_mute_voices( SNES_SPC*, int mask ); + +/* If true, prevents channels and global volumes from being phase-negated. +Only supported by fast DSP; has no effect on accurate DSP. */ +void spc_disable_surround( SNES_SPC*, int disable ); + +/* Sets tempo, where spc_tempo_unit = normal, spc_tempo_unit / 2 = half speed, etc. */ +enum { spc_tempo_unit = 0x100 }; +void spc_set_tempo( SNES_SPC*, int ); + + +/**** SPC music playback *****/ + +/* Loads SPC data into emulator. Returns NULL on success, otherwise error string. */ +spc_err_t spc_load_spc( SNES_SPC*, void const* spc_in, long size ); + +/* Clears echo region. Useful after loading an SPC as many have garbage in echo. */ +void spc_clear_echo( SNES_SPC* ); + +/* Plays for count samples and write samples to out. Discards samples if out +is NULL. Count must be a multiple of 2 since output is stereo. */ +spc_err_t spc_play( SNES_SPC*, int count, short* out ); + +/* Skips count samples. Several times faster than spc_play(). */ +spc_err_t spc_skip( SNES_SPC*, int count ); + + +/**** State save/load (only available with accurate DSP) ****/ + +/* Saves/loads exact emulator state */ +enum { spc_state_size = 67 * 1024L }; /* maximum space needed when saving */ +typedef void (*spc_copy_func_t)( unsigned char** io, void* state, size_t ); +void spc_copy_state( SNES_SPC*, unsigned char** io, spc_copy_func_t ); + +/* Writes minimal SPC file header to spc_out */ +void spc_init_header( void* spc_out ); + +/* Saves emulator state as SPC file data. Writes spc_file_size bytes to spc_out. +Does not set up SPC header; use spc_init_header() for that. */ +enum { spc_file_size = 0x10200 }; /* spc_out must have this many bytes allocated */ +void spc_save_spc( SNES_SPC*, void* spc_out ); + +/* Returns non-zero if new key-on events occurred since last check. Useful for +trimming silence while saving an SPC. */ +int spc_check_kon( SNES_SPC* ); + + +/**** SPC_Filter ****/ + +typedef struct SPC_Filter SPC_Filter; + +/* Creates new filter. NULL if out of memory. */ +SPC_Filter* spc_filter_new( void ); + +/* Frees filter */ +void spc_filter_delete( SPC_Filter* ); + +/* Filters count samples of stereo sound in place. Count must be a multiple of 2. */ +void spc_filter_run( SPC_Filter*, spc_sample_t* io, int count ); + +/* Clears filter to silence */ +void spc_filter_clear( SPC_Filter* ); + +/* Sets gain (volume), where spc_filter_gain_unit is normal. Gains greater than +spc_filter_gain_unit are fine, since output is clamped to 16-bit sample range. */ +enum { spc_filter_gain_unit = 0x100 }; +void spc_filter_set_gain( SPC_Filter*, int gain ); + +/* Sets amount of bass (logarithmic scale) */ +enum { spc_filter_bass_none = 0 }; +enum { spc_filter_bass_norm = 8 }; /* normal amount */ +enum { spc_filter_bass_max = 31 }; +void spc_filter_set_bass( SPC_Filter*, int bass ); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/waterbox/pizza/lib/sound.c b/waterbox/pizza/lib/sound.c new file mode 100644 index 0000000000..9573ad1d04 --- /dev/null +++ b/waterbox/pizza/lib/sound.c @@ -0,0 +1,1165 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#include "cycles.h" +#include "global.h" +#include "gpu.h" +#include "mmu.h" +#include "sound.h" +#include "utils.h" +#include "sound_output.h" + +#include +#include +#include + +/* super variable for audio controller */ +sound_t sound; + +// functions to connect to blip buf +static int16_t last_sample[8]; + +#define BLIP_LEFT(v,i) if(1){int32_t d = (v)-last_sample[(i)*2];blip_left(d);last_sample[(i)*2] = (v);} +#define BLIP_RIGHT(v,i) if(1){int32_t d = (v)-last_sample[(i)*2+1];blip_right(d);last_sample[(i)*2+1] = (v);} + +static void blip_ch1() +{ + if (sound.channel_one.active) + { + if (sound.nr51->ch1_to_so1) + BLIP_RIGHT(sound.channel_one.sample, 0); + if (sound.nr51->ch1_to_so2) + BLIP_LEFT(sound.channel_one.sample, 0); + } +} +static void blip_ch2() +{ + if (sound.channel_two.active) + { + if (sound.nr51->ch2_to_so1) + BLIP_RIGHT(sound.channel_two.sample, 1); + if (sound.nr51->ch2_to_so2) + BLIP_LEFT(sound.channel_two.sample, 1); + } +} +static void blip_ch3() +{ + if (sound.channel_three.active) + { + uint16_t sample; + uint8_t shift = (sound.nr32->volume_code == 0 ? + 4 : sound.nr32->volume_code - 1); + + /* volume is zero in any case */ + if (shift == 4) + sample = 0; + else + { + /* apply volume change */ + uint8_t idx = sound.channel_three.index; + uint16_t s; + + /* extract current sample */ + if ((idx & 0x01) == 0) + s = (sound.wave_table[idx >> 1] & 0xf0) >> 4; + else + s = sound.wave_table[idx >> 1] & 0x0f; + + /* transform it into signed 16 bit sample */ + sample = ((s * 0x222) >> shift); + } + + + /* not silence? */ + if (sample != 0) + { + if (sound.nr51->ch3_to_so1) + BLIP_RIGHT(sample, 2); + if (sound.nr51->ch3_to_so2) + BLIP_LEFT(sample, 2); + } + } +} +static void blip_ch4() +{ + if (sound.channel_four.active) + { + if (sound.nr51->ch4_to_so1) + BLIP_RIGHT(sound.channel_four.sample, 3); + if (sound.nr51->ch4_to_so2) + BLIP_LEFT(sound.channel_four.sample, 3); + } +} + +/* internal prototypes */ +void sound_envelope_step(); +void sound_length_ctrl_step(); +void sound_sweep_step(); +void sound_write_wave(uint16_t a, uint8_t v); + +void sound_init_pointers() +{ + /* point sound structures to their memory areas */ + sound.nr10 = (nr10_t *) mmu_addr(0xFF10); + sound.nr11 = (nr11_t *) mmu_addr(0xFF11); + sound.nr12 = (nr12_t *) mmu_addr(0xFF12); + sound.nr13 = (nr13_t *) mmu_addr(0xFF13); + sound.nr14 = (nr14_t *) mmu_addr(0xFF14); + + sound.nr21 = (nr21_t *) mmu_addr(0xFF16); + sound.nr22 = (nr22_t *) mmu_addr(0xFF17); + sound.nr23 = (nr23_t *) mmu_addr(0xFF18); + sound.nr24 = (nr24_t *) mmu_addr(0xFF19); + + sound.nr30 = (nr30_t *) mmu_addr(0xFF1A); + sound.nr31 = (nr31_t *) mmu_addr(0xFF1B); + sound.nr32 = (nr32_t *) mmu_addr(0xFF1C); + sound.nr33 = (nr33_t *) mmu_addr(0xFF1D); + sound.nr34 = (nr34_t *) mmu_addr(0xFF1E); + + sound.nr41 = (nr41_t *) mmu_addr(0xFF20); + sound.nr42 = (nr42_t *) mmu_addr(0xFF21); + sound.nr43 = (nr43_t *) mmu_addr(0xFF22); + sound.nr44 = (nr44_t *) mmu_addr(0xFF23); + + sound.nr50 = mmu_addr(0xFF24); + sound.nr51 = mmu_addr(0xFF25); + sound.nr52 = mmu_addr(0xFF26); + + sound.wave_table = mmu_addr(0xFF30); +} + +/* init sound states */ +void sound_init() +{ + /* reset structure */ + bzero(&sound, sizeof(sound_t)); + + /* point sound structures to their memory areas */ + sound_init_pointers(); + + /* how many cpu cycles we need to emit a 512hz clock (frame sequencer) */ + sound.fs_cycles = 4194304 / 512; + + /* how many cpu cycles to generate a single frame seq clock? */ + sound.fs_cycles_next = sound.fs_cycles; +} + +void sound_set_speed(char dbl) +{ +} + +/* update sound internal state given CPU T-states */ +void sound_step_fs() +{ + /* rotate from 0 to 7 */ + sound.fs_cycles_idx = (sound.fs_cycles_idx + 1) & 0x07; + + /* reset fs cycles counter */ + sound.fs_cycles_next = cycles.cnt + + (sound.fs_cycles << global_cpu_double_speed); + + /* length controller works at 256hz */ + if ((sound.fs_cycles_idx & 0x01) == 0) + sound_length_ctrl_step(); + + /* sweep works at 128hz */ + if (sound.fs_cycles_idx == 2 || sound.fs_cycles_idx == 6) + sound_sweep_step(); + + /* envelope works at 64hz */ + if (sound.fs_cycles_idx == 7) + sound_envelope_step(); + blip_ch1(); + blip_ch2(); + blip_ch3(); + blip_ch4(); +} + +/* update all channels */ +void sound_step_ch1() +{ + /* recalc current samples */ + if ((sound.channel_one.duty >> sound.channel_one.duty_idx) & 0x01) + sound.channel_one.sample = sound.channel_one.volume; + else + sound.channel_one.sample = -sound.channel_one.volume; + + /* step to the next duty value */ + sound.channel_one.duty_idx = + (sound.channel_one.duty_idx + 1) & 0x07; + + /* go back */ + sound.channel_one.duty_cycles_next += sound.channel_one.duty_cycles; + blip_ch1(); +} + +void sound_step_ch2() +{ + /* recalc current samples */ + if ((sound.channel_two.duty >> sound.channel_two.duty_idx) & 0x01) + sound.channel_two.sample = sound.channel_two.volume; + else + sound.channel_two.sample = -sound.channel_two.volume; + + /* step to the next duty value */ + sound.channel_two.duty_idx = + (sound.channel_two.duty_idx + 1) & 0x07; + + /* go back */ + sound.channel_two.duty_cycles_next += sound.channel_two.duty_cycles; + blip_ch2(); +} + +void sound_step_ch3() +{ + /* switch to the next wave sample */ + sound.channel_three.index = (sound.channel_three.index + 1) & 0x1F; + + /* set the new current sample */ + sound.channel_three.sample = + sound.channel_three.wave[sound.channel_three.index]; + + /* reload new period */ + uint_fast16_t freq = sound.nr33->frequency_lsb | + (sound.nr34->frequency_msb << 8); + + /* qty of cpu ticks needed for a wave sample change */ + sound.channel_three.cycles = ((2048 - freq) * 2) << global_cpu_double_speed; + sound.channel_three.cycles_next += sound.channel_three.cycles; + blip_ch3(); +} + +void sound_step_ch4() +{ + /* update LSFR */ + if (sound.nr43->shift < 14) + { + /* shift register one bit right */ + uint16_t s = sound.channel_four.reg >> 1; + + /* xor current register and the shifted version */ + /* and extract bit zero */ + uint16_t x = (sound.channel_four.reg ^ s) & 1; + + /* update register */ + sound.channel_four.reg = s | x << 14; + + /* if width is set... */ + if (sound.nr43->width) + sound.channel_four.reg = + (sound.channel_four.reg & 0xBF) | x << 6; + } + + /* update sample */ + if (sound.channel_four.reg & 0x01) + sound.channel_four.sample = -sound.channel_four.volume; + else + sound.channel_four.sample = sound.channel_four.volume; + + /* qty of cpu ticks needed for a wave sample change */ + sound.channel_four.cycles_next += sound.channel_four.period_lfsr; + blip_ch4(); +} + +/* update length of channel1 */ +void static inline sound_length_ctrl_step_ch(char length_enable, + uint_fast32_t *length, + uint8_t *active) +{ + if (length_enable && *length != 0) + { + (*length)--; + + /* if ZERO is reached, turn off the channel */ + if (*length == 0) + *active = 0; + } +} + +/* length controller step */ +void sound_length_ctrl_step() +{ + /* step every channel */ + sound_length_ctrl_step_ch(sound.nr14->length_enable, + &sound.channel_one.length, + &sound.channel_one.active); + + sound_length_ctrl_step_ch(sound.nr24->length_enable, + &sound.channel_two.length, + &sound.channel_two.active); + + sound_length_ctrl_step_ch(sound.nr34->length_enable, + &sound.channel_three.length, + &sound.channel_three.active); + + sound_length_ctrl_step_ch(sound.nr44->length_enable, + &sound.channel_four.length, + &sound.channel_four.active); +} + +/* calc the new frequency by sweep module */ +uint_fast32_t sound_sweep_calc() +{ + uint_fast32_t new_freq; + + /* time to update frequency */ + uint_fast32_t diff = + sound.channel_one.sweep_shadow_frequency >> + sound.nr10->shift; + + /* the calculated diff must be summed or subtracted to frequency */ + if (sound.nr10->negate) + { + new_freq = sound.channel_one.sweep_shadow_frequency - diff; + sound.channel_one.sweep_neg = 1; + } + else + new_freq = sound.channel_one.sweep_shadow_frequency + diff; + + /* if freq > 2047, turn off the channel */ + if (new_freq > 2047) + sound.channel_one.active = 0; + + return new_freq; +} + +/* set channel one new frequency */ +void sound_set_frequency(uint_fast32_t new_freq) +{ + /* too high? */ + if (new_freq > 2047) + { + sound.channel_one.active = 0; + return; + } + + /* update with the new frequency */ + sound.channel_one.frequency = new_freq; + + /* update them also into memory */ + sound.nr13->frequency_lsb = (uint8_t) (new_freq & 0x000000ff); + sound.nr14->frequency_msb = (uint8_t) ((new_freq >> 8) & 0x00000007); + + /* update the duty cycles */ + sound.channel_one.duty_cycles = + ((2048 - new_freq) * 4) << global_cpu_double_speed; + + /* and reset them */ + sound.channel_one.duty_cycles_next = + cycles.cnt + sound.channel_one.duty_cycles; +} + +/* step of frequency sweep at 128hz */ +void sound_sweep_step() +{ + uint_fast32_t new_freq; + + if (sound.channel_one.active && + sound.channel_one.sweep_active) + { + /* make it rotate from 0 to 8 */ + sound.channel_one.sweep_cnt++; + + /* enough cycles? */ + if (sound.channel_one.sweep_cnt == sound.channel_one.sweep_next) + { + /* reload the next step - 0 is treated as 8 */ + sound.channel_one.sweep_next = + sound.nr10->sweep_period ? + sound.nr10->sweep_period : 8; + + /* reset sweep counter */ + sound.channel_one.sweep_cnt = 0; + + /* period must be > 0 if new freq gotta be updated */ + if (sound.nr10->sweep_period == 0) + return; + + /* calc new frequency */ + new_freq = sound_sweep_calc(); + + /* set it only if < 2048 and shift != 0 */ + if (sound.nr10->shift && + new_freq < 2048) + { + /* copy new_freq into shadow register */ + sound.channel_one.sweep_shadow_frequency = new_freq; + + /* update all the stuff related to new frequency */ + sound_set_frequency(new_freq); + + /* update freq again (but only in shadow register) */ + sound_sweep_calc(); + } + } + } +} + +/* step of envelope at 64hz */ +void sound_envelope_step() +{ + if (sound.channel_one.active && sound.nr12->period) + { + /* update counter */ + sound.channel_one.envelope_cnt++; + + /* if counter reaches period, update volume */ + if (sound.channel_one.envelope_cnt == sound.nr12->period) + { + if (sound.nr12->add) + { + if (sound.channel_one.volume < (14 * 0x111)) + sound.channel_one.volume += 0x111; + } + else + { + if (sound.channel_one.volume >= 0x111) + sound.channel_one.volume -= 0x111; + } + + /* reset counter */ + sound.channel_one.envelope_cnt = 0; + } + } + + if (sound.channel_two.active && sound.nr22->period) + { + /* update counter */ + sound.channel_two.envelope_cnt++; + + /* if counter reaches period, update volume */ + if (sound.channel_two.envelope_cnt == sound.nr22->period) + { + if (sound.nr22->add) + { + if (sound.channel_two.volume < (14 * 0x111)) + sound.channel_two.volume += 0x111; + } + else + { + if (sound.channel_two.volume >= 0x111) + sound.channel_two.volume -= 0x111; + } + + /* reset counter */ + sound.channel_two.envelope_cnt = 0; + } + } + + if (sound.channel_four.active && sound.nr42->period) + { + /* update counter */ + sound.channel_four.envelope_cnt++; + + /* if counter reaches period, update volume */ + if (sound.channel_four.envelope_cnt == sound.nr42->period) + { + if (sound.nr42->add) + { + if (sound.channel_four.volume < (14 * 0x111)) + sound.channel_four.volume += 0x111; + } + else + { + if (sound.channel_four.volume > 0x111) + sound.channel_four.volume -= 0x111; + } + + /* reset counter */ + sound.channel_four.envelope_cnt = 0; + } + } +} + +uint8_t sound_read_reg(uint16_t a, uint8_t v) +{ + switch (a) + { + /* NR1X */ + case 0xFF10: return v | 0x80; + case 0xFF11: return v | 0x3F; + case 0xFF12: return v; + case 0xFF13: return v | 0xFF; + case 0xFF14: return v | 0xBF; + /* NR2X */ + case 0xFF15: return v | 0xFF; + case 0xFF16: return v | 0x3F; + case 0xFF17: return v; + case 0xFF18: return v | 0xFF; + case 0xFF19: return v | 0xBF; + /* NR3X */ + case 0xFF1A: return v | 0x7F; + case 0xFF1B: return v | 0xFF; + case 0xFF1C: return v | 0x9F; + case 0xFF1D: return v | 0xFF; + case 0xFF1E: return v | 0xBF; + /* NR4X */ + case 0xFF1F: return v | 0xFF; + case 0xFF20: return v | 0xFF; + case 0xFF21: return v; + case 0xFF22: return v; + case 0xFF23: return v | 0xBF; + /* NR5X */ + case 0xFF24: return v; + case 0xFF25: return v; + case 0xFF26: + if (sound.nr52->power) + return 0xf0 | + sound.channel_one.active | + (sound.channel_two.active << 1) | + (sound.channel_three.active << 2) | + (sound.channel_four.active << 3); + else + return 0x70; + case 0xFF27: + case 0xFF28: + case 0xFF29: + case 0xFF2A: + case 0xFF2B: + case 0xFF2C: + case 0xFF2D: + case 0xFF2E: + case 0xFF2F: return 0xFF; + case 0xFF30: + case 0xFF31: + case 0xFF32: + case 0xFF33: + case 0xFF34: + case 0xFF35: + case 0xFF36: + case 0xFF37: + case 0xFF38: + case 0xFF39: + case 0xFF3A: + case 0xFF3B: + case 0xFF3C: + case 0xFF3D: + case 0xFF3E: + case 0xFF3F: + if (sound.channel_three.active) + { +/* if (!global_cgb && sound.channel_three.ram_access != 0) + { + printf("RAM ACCESSO NON ZERO %u - CNT %d NEXT %d\n", + sound.channel_three.ram_access, cycles.cnt, sound.channel_three.ram_access_next); + return 0xFF; + }*/ + if (!global_cgb && + cycles.cnt < sound.channel_three.ram_access_next) + return 0xFF; + + return sound.wave_table[sound.channel_three.index >> 1]; + } + + default: return v; + } +} + +void sound_write_reg(uint16_t a, uint8_t v) +{ + /* when turned off, only write to NR52 (0xFF26) is legit */ + if (!sound.nr52->power && a != 0xFF26) + { + /* CGB mode doesnt allow any write on register during power off */ + if (global_cgb) + return; + + /* in DMG mode, update length is legit while no power */ + switch (a) + { + case 0xFF11: sound.channel_one.length = 64 - (v & 0x3f); return; + case 0xFF16: sound.channel_two.length = 64 - (v & 0x3f); return; + case 0xFF1B: sound.channel_three.length = 256 - v; return; + case 0xFF20: sound.channel_four.length = 64 - (v & 0x3f); return; + default: return; + } + } + + /* wave write */ + if (a >= 0xFF30 && a <= 0xFF3F) + return sound_write_wave(a, v); + + /* save old value */ + uint8_t old = *((uint8_t *) mmu_addr(a)); + + /* confirm write on memory */ + *((uint8_t *) mmu_addr(a)) = v; + + switch (a) + { + case 0xFF10: + + if (!sound.nr10->negate && sound.channel_one.sweep_neg) + sound.channel_one.active = 0; + + break; + + case 0xFF11: + + /* set length as 64 - length_load */ + sound.channel_one.length = 64 - sound.nr11->length_load; + + /* update duty type */ + switch (sound.nr11->duty) + { + /* 12.5 % */ + case 0x00: sound.channel_one.duty = 0x80; + break; + + /* 25% */ + case 0x01: sound.channel_one.duty = 0x81; + break; + + /* 50% */ + case 0x02: sound.channel_one.duty = 0xE1; + break; + + /* 75% */ + case 0x03: sound.channel_one.duty = 0x7E; + break; + } + + break; + + case 0xFF12: + + /* volume 0 = turn off the DAC = turn off channeru */ + if (sound.nr12->volume == 0 && + sound.nr12->add == 0) + sound.channel_one.active = 0; + + break; + + case 0xFF13: + + /* update frequncy */ + sound.channel_one.frequency = sound.nr13->frequency_lsb | + (sound.nr14->frequency_msb << 8); + + /* update duty cycles */ + sound.channel_one.duty_cycles = + ((2048 - sound.channel_one.frequency) * 4) + << global_cpu_double_speed; + + break; + + case 0xFF14: + + /* length counter turned on */ + if (sound.nr14->length_enable) + { + nr14_t *old_nr14 = (nr14_t *) &old; + + /* give an extra length clock if */ + /* 1) we switched from off to on the len counter */ + /* 2) we are in the first half of len clock */ + /* 3) actual length is not zero */ + if ((old_nr14->length_enable == 0) && + ((sound.fs_cycles_idx & 0x01) == 0x00) && + (sound.channel_one.length != 0)) + sound_length_ctrl_step_ch(sound.nr14->length_enable, + &sound.channel_one.length, + &sound.channel_one.active); + } + + /* always update frequency, even if it's not a trigger */ + sound.channel_one.frequency = sound.nr13->frequency_lsb | + (sound.nr14->frequency_msb << 8); + + /* qty of cpu ticks needed for a duty change */ + /* (1/8 of wave cycle) */ + sound.channel_one.duty_cycles = + ((2048 - sound.channel_one.frequency) * 4) + << global_cpu_double_speed; + + if (v & 0x80) + { + /* if we switch from OFF to ON, reset duty idx */ + if (sound.channel_two.active == 0) + sound.channel_two.duty_idx = 0; + + /* setting internal modules data with stuff taken from memory */ + sound.channel_one.active = 1; + sound.channel_one.duty_cycles_next = + cycles.cnt + sound.channel_one.duty_cycles; + + /* set the 8 phase of a duty cycle by setting 8 bits */ + switch (sound.nr11->duty) + { + /* 12.5 % */ + case 0x00: sound.channel_one.duty = 0x80; + break; + + /* 25% */ + case 0x01: sound.channel_one.duty = 0x81; + break; + + /* 50% */ + case 0x02: sound.channel_one.duty = 0xE1; + break; + + /* 75% */ + case 0x03: sound.channel_one.duty = 0x7E; + break; + } + + /* calc length */ + if (sound.channel_one.length == 0) + sound.channel_one.length = 64; + + /* base volume */ + sound.channel_one.volume = + sound.nr12->volume * 0x111; + + /* reset envelope counter */ + sound.channel_one.envelope_cnt = 0; + + /* save current freq into sweep shadow register */ + sound.channel_one.sweep_shadow_frequency = + sound.channel_one.frequency; + + /* reset sweep timer */ + sound.channel_one.sweep_cnt = 0; + + /* reset sweep neg bool */ + sound.channel_one.sweep_neg = 0; + + /* reload the next step */ + sound.channel_one.sweep_next = sound.nr10->sweep_period ? + sound.nr10->sweep_period : 8; + + /* set sweep as active if period != 0 or shift != 0 */ + if (sound.nr10->sweep_period != 0 || + sound.nr10->shift != 0) + sound.channel_one.sweep_active = 1; + else + sound.channel_one.sweep_active = 0; + + /* if shift is != 0, calc the new frequency */ + if (sound.nr10->shift != 0) + { + uint32_t new_freq = sound_sweep_calc(); + + /* update all the stuff related to new frequency */ + sound_set_frequency(new_freq); + } + + /* if DAC is off, turn off the channel */ + if (sound.nr12->add == 0 && + sound.nr12->volume == 0) + sound.channel_one.active = 0; + + /* extra length clock if length == 64 */ + /* and FS is in the fist half */ + if ((sound.fs_cycles_idx & 0x01) == 0x00 && + sound.channel_one.length == 64) + sound_length_ctrl_step_ch(sound.nr14->length_enable, + &sound.channel_one.length, + &sound.channel_one.active); + } + + + break; + + case 0xFF16: + + sound.channel_two.length = 64 - sound.nr21->length_load; + + /* update duty type */ + switch (sound.nr21->duty) + { + /* 12.5 % */ + case 0x00: sound.channel_two.duty = 0x80; + break; + + /* 25% */ + case 0x01: sound.channel_two.duty = 0x81; + break; + + /* 50% */ + case 0x02: sound.channel_two.duty = 0xE1; + break; + + /* 75% */ + case 0x03: sound.channel_two.duty = 0x7E; + break; + } + + break; + + case 0xFF17: + + /* volume 0 = turn off the DAC = turn off channeru */ + if (sound.nr22->volume == 0 && + sound.nr22->add == 0) + sound.channel_two.active = 0; + + break; + + case 0xFF18: + + /* update frequncy */ + sound.channel_two.frequency = (sound.nr23->frequency_lsb | + (sound.nr24->frequency_msb << 8)); + + /* update duty cycles */ + sound.channel_two.duty_cycles = + ((2048 - sound.channel_two.frequency) * 4) + << global_cpu_double_speed; + + break; + + case 0xFF19: + + /* length counter turned on */ + if (sound.nr24->length_enable) + { + nr24_t *old_nr24 = (nr24_t *) &old; + + /* give an extra length clock if */ + /* 1) we switched from off to on the len counter */ + /* 2) we are in the first half of len clock */ + /* 3) actual length is not zero */ + if ((old_nr24->length_enable == 0) && + ((sound.fs_cycles_idx & 0x01) == 0x00) && + (sound.channel_two.length != 0)) + sound_length_ctrl_step_ch(sound.nr24->length_enable, + &sound.channel_two.length, + &sound.channel_two.active); + } + + /* always update frequency, even if it's not a trigger */ + sound.channel_two.frequency = sound.nr23->frequency_lsb | + (sound.nr24->frequency_msb << 8); + + /* qty of cpu ticks needed for a duty change */ + /* (1/8 of wave cycle) */ + sound.channel_two.duty_cycles = + ((2048 - sound.channel_two.frequency) * 4) + << global_cpu_double_speed; + + if (v & 0x80) + { + /* if we switch from OFF to ON, reset duty idx */ + if (sound.channel_two.active == 0) + sound.channel_two.duty_idx = 0; + + /* setting internal modules data with stuff taken from memory */ + sound.channel_two.active = 1; + sound.channel_two.duty_cycles_next = + cycles.cnt + sound.channel_two.duty_cycles; + + /* set the 8 phase of a duty cycle by setting 8 bits */ + switch (sound.nr21->duty) + { + /* 12.5 % */ + case 0x00: sound.channel_two.duty = 0x80; + break; + + /* 25% */ + case 0x01: sound.channel_two.duty = 0x81; + break; + + /* 50% */ + case 0x02: sound.channel_two.duty = 0xE1; + break; + + /* 75% */ + case 0x03: sound.channel_two.duty = 0x7E; + break; + } + + /* calc length */ + if (sound.channel_two.length == 0) + sound.channel_two.length = 64; + + /* base volume */ + sound.channel_two.volume = + sound.nr22->volume * 0x111; + + /* reset envelope counter */ + sound.channel_two.envelope_cnt = 0; + + /* if DAC is off, turn off the channel */ + if (sound.nr22->add == 0 && + sound.nr22->volume == 0) + sound.channel_two.active = 0; + + /* extra length clock if length == 64 */ + /* and FS is in the fist half */ + if ((sound.fs_cycles_idx & 0x01) == 0x00 && + sound.channel_two.length == 64) + sound_length_ctrl_step_ch(sound.nr24->length_enable, + &sound.channel_two.length, + &sound.channel_two.active); + } + + break; + + case 0xFF1A: + + /* if DAC is off, disable the channel */ + if (sound.nr30->dac == 0) + sound.channel_three.active = 0; + + break; + + case 0xFF1B: + + sound.channel_three.length = + 256 - sound.nr31->length_load; + + break; + + case 0xFF1C: + + break; + + case 0xFF1E: + + /* length counter turned on */ + if (sound.nr34->length_enable) + { + nr34_t *old_nr34 = (nr34_t *) &old; + + /* give an extra length clock if */ + /* 1) we switched from off to on the len counter */ + /* 2) we are in the first half of len clock */ + /* 3) actual length is not zero */ + if ((old_nr34->length_enable == 0) && + ((sound.fs_cycles_idx & 0x01) == 0x00) && + (sound.channel_three.length != 0)) + sound_length_ctrl_step_ch(sound.nr34->length_enable, + &sound.channel_three.length, + &sound.channel_three.active); + } + + if (v & 0x80) + { + uint16_t freq = sound.nr33->frequency_lsb | + (sound.nr34->frequency_msb << 8); + + /* setting internal modules data with stuff taken from memory */ + sound.channel_three.active = 1; + + uint_fast32_t old_cycles = sound.channel_three.cycles; + + /* qty of cpu ticks needed for a wave sample change */ + sound.channel_three.cycles = + (((2048 - freq) * 2) + 6) << global_cpu_double_speed; + + + /* treat obscure behaviours.... */ + if (!global_cgb && + cycles.cnt + 8 == sound.channel_three.cycles_next + + sound.channel_three.cycles - + old_cycles) + { + uint8_t next = + ((sound.channel_three.index + 1) & 0x1F) >> 1; + + if (next < 4) + sound.wave_table[0] = sound.wave_table[next]; + else + memcpy(sound.wave_table, + &sound.wave_table[next & 0xfc], 4); + } + + /* init wave table index */ + sound.channel_three.index = 0; + sound.channel_three.cycles_next = + cycles.cnt + sound.channel_three.cycles; + + /* calc length */ + if (sound.channel_three.length == 0) + sound.channel_three.length = 256; + + /* if DAC is off, disable the channel */ + if (sound.nr30->dac == 0) + sound.channel_three.active = 0; + + /* extra length clock if length == 256 */ + /* and FS is in the fist half */ + if ((sound.fs_cycles_idx & 0x01) == 0x00 && + sound.channel_three.length == 256) + sound_length_ctrl_step_ch(sound.nr34->length_enable, + &sound.channel_three.length, + &sound.channel_three.active); + + /* i accessed to the wave RAM... */ + sound.channel_three.ram_access = sound.channel_three.cycles; + + if (sound.channel_three.cycles % 4 == 0) + sound.channel_three.ram_access_next = + cycles.cnt + sound.channel_three.cycles; + else + sound.channel_three.ram_access_next = -1; + +/* printf("RAM ACCESS RICARICATO %u - CNT %d CYCLES %d \n", + sound.channel_three.ram_access, + cycles.cnt, sound.channel_three.cycles);*/ + } + break; + + case 0xFF20: + + sound.channel_four.length = 64 - sound.nr41->length_load; + + break; + + case 0xFF21: + + /* highest 5 bits cleared = turn off the DAC = turn off channeru */ + if (sound.nr42->volume == 0 && + sound.nr42->add == 0) + sound.channel_four.active = 0; + + break; + + case 0xFF23: + + /* length counter turned on */ + if (sound.nr44->length_enable) + { + nr44_t *old_nr44 = (nr44_t *) &old; + + /* give an extra length clock if */ + /* 1) we switched from off to on the len counter */ + /* 2) we are in the first half of len clock */ + /* 3) actual length is not zero */ + if ((old_nr44->length_enable == 0) && + ((sound.fs_cycles_idx & 0x01) == 0x00) && + (sound.channel_four.length != 0)) + sound_length_ctrl_step_ch(sound.nr44->length_enable, + &sound.channel_four.length, + &sound.channel_four.active); + } + + if (v & 0x80) + { + /* setting internal modules data with stuff taken from memory */ + sound.channel_four.active = 1; + + /* calc length */ + if (sound.channel_four.length == 0) + sound.channel_four.length = 64; + + uint16_t divisor; + + /* calc LFSR period */ + switch (sound.nr43->divisor) + { + case 0: divisor = 8; break; + case 1: divisor = 16; break; + case 2: divisor = 32; break; + case 3: divisor = 48; break; + case 4: divisor = 64; break; + case 5: divisor = 80; break; + case 6: divisor = 96; break; + case 7: divisor = 112; break; + } + + /* calc LFSR period */ + sound.channel_four.period_lfsr = divisor << sound.nr43->shift; + sound.channel_four.cycles_next = + cycles.cnt + sound.channel_four.period_lfsr; + + /* init reg to all bits to 1 */ + sound.channel_four.reg = 0x7FFF; + + /* base volume */ + sound.channel_four.volume = + sound.nr42->volume * 0x111; + + /* reset envelope counter */ + sound.channel_four.envelope_cnt = 0; + + /* if DAC is off, turn off the channel */ + if (sound.nr42->add == 0 && + sound.nr42->volume == 0) + sound.channel_four.active = 0; + + /* extra length clock if length == 64 */ + /* and FS is in the fist half */ + if ((sound.fs_cycles_idx & 0x01) == 0x00 && + sound.channel_four.length == 64) + sound_length_ctrl_step_ch(sound.nr44->length_enable, + &sound.channel_four.length, + &sound.channel_four.active); + } + + break; + + case 0xFF26: + + if (v & 0x80) + { + /* power from off to on! */ + if (!(old & 0x80)) + { + /* reset frame sequencer so the next step will be zero */ + sound.fs_cycles_idx = 7; + + /* reset wave index */ + sound.channel_three.index = 0; + + /* wave samples are resetted */ + bzero(sound.wave_table, 16); + } + } + else + { + /* power off */ + + /* clear all the sound memory */ + bzero(mmu_addr(0xFF10), 22); + + if (global_cgb) + { + sound.nr41->length_load = 0; + sound.channel_four.length = 0; + } + + /* turn off every channeru */ + sound.channel_one.active = 0; + sound.channel_two.active = 0; + sound.channel_three.active = 0; + sound.channel_four.active = 0; + } + + } +} + +void sound_write_wave(uint16_t a, uint8_t v) +{ + if (sound.channel_three.active) + { +// if (!global_cgb && sound.channel_three.ram_access != 0) +// return; + if (!global_cgb && cycles.cnt < sound.channel_three.ram_access_next) + return; + + sound.wave_table[sound.channel_three.index >> 1] = v; + + return; + } + + sound.wave_table[a - 0xFF30] = v; +} diff --git a/waterbox/pizza/lib/sound.h b/waterbox/pizza/lib/sound.h new file mode 100644 index 0000000000..226b8650bd --- /dev/null +++ b/waterbox/pizza/lib/sound.h @@ -0,0 +1,300 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#ifndef __SOUND_HDR__ +#define __SOUND_HDR__ + +#define SOUND_SAMPLES 4096 + +typedef struct nr10_s +{ + uint8_t shift:3; + uint8_t negate:1; + uint8_t sweep_period:3; + uint8_t spare:1; + +} nr10_t; + +typedef struct nr11_s +{ + uint8_t length_load:6; + uint8_t duty:2; + +} nr11_t; + +typedef struct nr12_s +{ + uint8_t period:3; + uint8_t add:1; + uint8_t volume:4; + +} nr12_t; + +typedef struct nr13_s +{ + uint8_t frequency_lsb; + +} nr13_t; + +typedef struct nr14_s +{ + uint8_t frequency_msb:3; + uint8_t spare:3; + uint8_t length_enable:1; + uint8_t trigger:1; + +} nr14_t; + +typedef struct nr21_s +{ + uint8_t length_load:6; + uint8_t duty:2; + +} nr21_t; + +typedef struct nr22_s +{ + uint8_t period:3; + uint8_t add:1; + uint8_t volume:4; + +} nr22_t; + +typedef struct nr23_s +{ + uint8_t frequency_lsb; + +} nr23_t; + +typedef struct nr24_s +{ + uint8_t frequency_msb:3; + uint8_t spare:3; + uint8_t length_enable:1; + uint8_t trigger:1; + +} nr24_t; + + +typedef struct nr30_s +{ + uint8_t spare:7; + uint8_t dac:1; + +} nr30_t; + +typedef struct nr31_s +{ + uint8_t length_load; + +} nr31_t; + +typedef struct nr32_s +{ + uint8_t spare:5; + uint8_t volume_code:2; + uint8_t spare2:1; + +} nr32_t; + +typedef struct nr33_s +{ + uint8_t frequency_lsb; + +} nr33_t; + +typedef struct nr34_s +{ + uint8_t frequency_msb:3; + uint8_t spare:3; + uint8_t length_enable:1; + uint8_t trigger:1; + +} nr34_t; + +typedef struct nr41_s +{ + uint8_t length_load:6; + uint8_t spare:2; + +} nr41_t; + +typedef struct nr42_s +{ + uint8_t period:3; + uint8_t add:1; + uint8_t volume:4; + +} nr42_t; + +typedef struct nr43_s +{ + uint8_t divisor:3; + uint8_t width:1; + uint8_t shift:4; + +} nr43_t; + +typedef struct nr44_s +{ + uint8_t spare:6; + uint8_t length_enable:1; + uint8_t trigger:1; + +} nr44_t; + +typedef struct nr50_s +{ + uint8_t so1_volume:3; + uint8_t vin_to_so1:1; + uint8_t so2_volume:3; + uint8_t vin_to_so2:1; +} nr50_t; + +typedef struct nr51_s +{ + uint8_t ch1_to_so1:1; + uint8_t ch2_to_so1:1; + uint8_t ch3_to_so1:1; + uint8_t ch4_to_so1:1; + uint8_t ch1_to_so2:1; + uint8_t ch2_to_so2:1; + uint8_t ch3_to_so2:1; + uint8_t ch4_to_so2:1; +} nr51_t; + +typedef struct nr52_s +{ + uint8_t spare:7; + uint8_t power:1; +} nr52_t; + +typedef struct channel_square_s +{ + uint8_t active; + uint8_t duty; + uint8_t duty_idx; + uint8_t envelope_cnt; + uint_fast16_t duty_cycles; + uint64_t duty_cycles_next; + uint_fast32_t length; + uint_fast32_t frequency; + int16_t sample; + int16_t spare; + uint_fast16_t sweep_active; + uint_fast16_t sweep_cnt; + uint_fast16_t sweep_neg; + uint_fast16_t sweep_next; + int16_t volume; + int16_t spare2; + uint32_t sweep_shadow_frequency; + +} channel_square_t; + +typedef struct channel_wave_s +{ + uint8_t active; + uint8_t index; + uint16_t ram_access; + int16_t sample; + int16_t spare; + int16_t wave[32]; + uint_fast32_t cycles; + uint64_t cycles_next; + uint_fast32_t ram_access_next; + uint_fast32_t length; + +} channel_wave_t; + +typedef struct channel_noise_s +{ + uint8_t active; + uint8_t envelope_cnt; + uint16_t spare; + uint_fast32_t length; + uint_fast16_t period_lfsr; + uint64_t cycles_next; + int16_t volume; + int16_t sample; + uint16_t reg; + uint16_t spare2; + +} channel_noise_t; + +typedef struct sound_s +{ + nr10_t *nr10; + nr11_t *nr11; + nr12_t *nr12; + nr13_t *nr13; + nr14_t *nr14; + + nr21_t *nr21; + nr22_t *nr22; + nr23_t *nr23; + nr24_t *nr24; + + nr30_t *nr30; + nr31_t *nr31; + nr32_t *nr32; + nr33_t *nr33; + nr34_t *nr34; + + nr41_t *nr41; + nr42_t *nr42; + nr43_t *nr43; + nr44_t *nr44; + + nr50_t *nr50; + nr51_t *nr51; + nr52_t *nr52; + + uint8_t *wave_table; + + channel_square_t channel_one; + channel_square_t channel_two; + channel_wave_t channel_three; + channel_noise_t channel_four; + + /* emulation speed stuff */ + uint_fast16_t frame_counter; + + /* output rate */ + uint_fast32_t output_rate; + + /* CPU cycles to internal cycles counters */ + uint_fast32_t fs_cycles; + uint_fast32_t fs_cycles_idx; + uint64_t fs_cycles_next; +} sound_t; + +extern sound_t sound; + +/* prototypes */ +void sound_init(); +uint8_t sound_read_reg(uint16_t a, uint8_t v); +void sound_set_speed(char dbl); +void sound_step_fs(); +void sound_step_ch1(); +void sound_step_ch2(); +void sound_step_ch3(); +void sound_step_ch4(); +void sound_write_reg(uint16_t a, uint8_t v); + +#endif diff --git a/waterbox/pizza/lib/sound_output.c b/waterbox/pizza/lib/sound_output.c new file mode 100644 index 0000000000..cf9d32c949 --- /dev/null +++ b/waterbox/pizza/lib/sound_output.c @@ -0,0 +1,57 @@ +#include "../blip_buf/blip_buf.h" +#include "sound_output.h" +#include "cycles.h" +#include "sgb.h" +#include "global.h" + +static blip_t* lb; +static blip_t* rb; +static uint64_t startclock; + +#define RELATIVECLOCK (cycles.sampleclock - startclock) + +void blip_left(int delta) +{ + if (delta) + blip_add_delta(lb, RELATIVECLOCK, delta); +} +void blip_right(int delta) +{ + if (delta) + blip_add_delta(rb, RELATIVECLOCK, delta); +} + +void sound_output_init(double clock_rate, double sample_rate) +{ + lb = blip_new(1024); + rb = blip_new(1024); + blip_set_rates(lb, clock_rate, sample_rate); + blip_set_rates(rb, clock_rate, sample_rate); +} + +static int32_t sgb_last_l; +static int32_t sgb_last_r; + +static void sgb_audio_callback(int16_t l, int16_t r, uint64_t time) +{ + uint64_t t = time - startclock; + int32_t ld = l - sgb_last_l; + int32_t rd = r - sgb_last_r; + blip_add_delta(lb, t, ld); + blip_add_delta(rb, t, rd); + sgb_last_l = l; + sgb_last_r = r; +} + +int sound_output_read(int16_t* output) +{ + if (global_sgb) + sgb_render_audio(cycles.sampleclock, sgb_audio_callback); + + blip_end_frame(lb, RELATIVECLOCK); + blip_end_frame(rb, RELATIVECLOCK); + startclock = cycles.sampleclock; + int ret = blip_read_samples(lb, output, 2048, 1); + blip_read_samples(rb, output + 1, 2048, 1); + return ret; +} diff --git a/waterbox/pizza/lib/sound_output.h b/waterbox/pizza/lib/sound_output.h new file mode 100644 index 0000000000..91561da49a --- /dev/null +++ b/waterbox/pizza/lib/sound_output.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +void blip_left(int delta); +void blip_right(int delta); + +void sound_output_init(double clock_rate, double sample_rate); +int sound_output_read(int16_t* output); diff --git a/waterbox/pizza/lib/timer.c b/waterbox/pizza/lib/timer.c new file mode 100644 index 0000000000..a46c224bda --- /dev/null +++ b/waterbox/pizza/lib/timer.c @@ -0,0 +1,79 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#include "cycles.h" +#include "interrupt.h" +#include "mmu.h" +#include "timer.h" + +/* pointer to interrupt flags (handy) */ +interrupts_flags_t *timer_if; + + +void timer_init() +{ + /* reset values */ + timer.next = 256; + timer.sub = 0; + + /* pointer to interrupt flags */ + timer_if = mmu_addr(0xFF0F); +} + +void timer_write_reg(uint16_t a, uint8_t v) +{ + switch (a) + { + case 0xFF04: timer.div = 0; return; + case 0xFF05: timer.cnt = v; return; + case 0xFF06: timer.mod = v; return; + case 0xFF07: timer.ctrl = v; + } + + if (timer.ctrl & 0x04) + timer.active = 1; + else + timer.active = 0; + + switch (timer.ctrl & 0x03) + { + case 0x00: timer.threshold = 1024; break; + case 0x01: timer.threshold = 16; break; + case 0x02: timer.threshold = 64; break; + case 0x03: timer.threshold = 256; break; + } + + if (timer.active) + timer.sub_next = cycles.cnt + timer.threshold; +} + +uint8_t timer_read_reg(uint16_t a) +{ + switch (a) + { + case 0xFF04: return timer.div; + case 0xFF05: return timer.cnt; + case 0xFF06: return timer.mod; + case 0xFF07: return timer.ctrl; + } + + return 0xFF; +} + + diff --git a/waterbox/pizza/lib/timer.h b/waterbox/pizza/lib/timer.h new file mode 100644 index 0000000000..531116121b --- /dev/null +++ b/waterbox/pizza/lib/timer.h @@ -0,0 +1,63 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#ifndef __TIMER_HDR__ +#define __TIMER_HDR__ + +#include + +/* timer status */ +typedef struct timer_gb_s +{ + /* is it active? */ + uint8_t active; + + /* divider - 0xFF04 */ + uint8_t div; + + /* modulo - 0xFF06 */ + uint8_t mod; + + /* control - 0xFF07 */ + uint8_t ctrl; + + /* counter - 0xFF05 */ + uint_fast32_t cnt; + + /* threshold */ + uint32_t threshold; + + /* current value */ + uint_fast32_t sub; + uint64_t next; + + /* spare */ + uint_fast32_t sub_next; +} timer_gb_t; + +/* global status of timer */ +timer_gb_t timer; + +/* prototypes */ +void timer_init(); +void timer_step(); +void timer_write_reg(uint16_t a, uint8_t v); +uint8_t timer_read_reg(uint16_t a); + +#endif diff --git a/waterbox/pizza/lib/utils.c b/waterbox/pizza/lib/utils.c new file mode 100644 index 0000000000..dff5dd1d79 --- /dev/null +++ b/waterbox/pizza/lib/utils.c @@ -0,0 +1,75 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#include +#include + +#include +#include + +#include "cycles.h" +#include "gpu.h" +#include "utils.h" + +uint64_t prev_cycles = 0; + +void utils_log(const char *format, ...) +{ + char buf[256]; + + va_list args; + va_start(args, format); + vsnprintf(buf, 256, format, args); + _debug_puts(buf); + va_end(args); +} + + +void utils_log_urgent(const char *format, ...) +{ + char buf[256]; + + va_list args; + va_start(args, format); + vsnprintf(buf, 256, format, args); + _debug_puts(buf); + va_end(args); +} + +void utils_ts_log(const char *format, ...) +{ + va_list args; + va_start(args, format); + + char buf[256]; + char buf2[512]; + struct timeval tv; + + + vsprintf(buf, format, args); + //gettimeofday(&tv, NULL); +// printf("%ld - %s\n", tv.tv_sec, buf); + sprintf(buf2, "LINE %u - CYCLES %lu - DIFF %lu - %ld:%06ld - %s", + *(gpu.ly), cycles.cnt, cycles.cnt - prev_cycles, + tv.tv_sec, tv.tv_usec, buf); + _debug_puts(buf2); + prev_cycles = cycles.cnt; + + va_end(args); +} diff --git a/waterbox/pizza/lib/utils.h b/waterbox/pizza/lib/utils.h new file mode 100644 index 0000000000..17e632de51 --- /dev/null +++ b/waterbox/pizza/lib/utils.h @@ -0,0 +1,27 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#ifndef __UTILS_HDR__ +#define __UTILS_HDR__ + +void utils_log(const char *format, ...); +void utils_log_urgent(const char *format, ...); +void utils_ts_log(const char *format, ...); + +#endif diff --git a/waterbox/pizza/lib/z80_gameboy.h b/waterbox/pizza/lib/z80_gameboy.h new file mode 100644 index 0000000000..db8c78c66d --- /dev/null +++ b/waterbox/pizza/lib/z80_gameboy.h @@ -0,0 +1,2480 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#include +#include +#include +#include +#include +#include "mmu.h" +#include "z80_gameboy_regs.h" + +/* main struct describing CPU state */ + +typedef struct z80_state_s +{ + uint8_t spare; + uint8_t a; +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + uint8_t c; + uint8_t b; +#else + uint8_t b; + uint8_t c; +#endif +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + uint8_t e; + uint8_t d; +#else + uint8_t d; + uint8_t e; +#endif +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + uint8_t l; + uint8_t h; +#else + uint8_t h; + uint8_t l; +#endif + + uint16_t sp; + uint16_t pc; + + /* shortcuts */ + uint16_t *bc; + uint16_t *de; + uint16_t *hl; + uint8_t *f; + + uint32_t spare4; + uint32_t skip_cycle; + + z80_flags_t flags; + uint8_t int_enable; + + /* latest T-state */ + uint16_t spare3; + + /* total cycles */ + uint64_t cycles; + +} z80_state_t; + +#define Z80_MAX_MEMORY 65536 + + +/* state of the Z80 CPU */ +z80_state_t state; + +/* precomputed flags masks */ +uint8_t zc[1 << 9]; +uint8_t z[1 << 9]; + +/* macro to access addresses passed as parameters */ +#define ADDR mmu_read_16(state.pc + 1) +#define NN mmu_read_16(state.pc + 2) + +/* dummy value for 0x06 regs resulution table */ +uint8_t dummy; + +/* Registers table */ +uint8_t **regs_dst; +uint8_t **regs_src; + +#define FLAG_MASK_Z (1 << FLAG_OFFSET_Z) +#define FLAG_MASK_AC (1 << FLAG_OFFSET_AC) +#define FLAG_MASK_N (1 << FLAG_OFFSET_N) +#define FLAG_MASK_CY (1 << FLAG_OFFSET_CY) + + +/********************************/ +/* */ +/* FLAGS OPS */ +/* */ +/********************************/ + +/* calc flags SZ with 16 bit param */ +void static inline z80_set_flags_z(unsigned int v) +{ + state.flags.z = (v & 0xff) == 0; +} + +/* calc flags SZC with 16 bit param */ +void static inline z80_set_flags_zc(unsigned int v) +{ + state.flags.z = (v & 0xff) == 0; + state.flags.cy = (v > 0xff); +} + +/* calc flags SZC with 32 bit result */ +void static inline z80_set_flags_zc_16(unsigned int v) +{ + state.flags.z = (v & 0xffff) == 0; + state.flags.cy = (v > 0xffff); +} + +/* calc AC for given operands */ +void static inline z80_set_flags_ac(uint8_t a, uint8_t b, + unsigned int r) +{ + /* calc xor for AC and overflow */ + unsigned int c = (a ^ b ^ r); + + /* set AC */ + state.flags.ac = ((c & 0x10) != 0); + + return; +} + +/* calc AC and overflow flag given operands (16 bit flavour) */ +void static inline z80_set_flags_ac_16(unsigned int a, + unsigned int b, + unsigned int r) +{ + /* calc xor for AC and overflow */ + unsigned int c = (a ^ b ^ r); + + /* set AC */ + state.flags.ac = ((c & 0x01000) != 0); + + return; +} + +/* calc AC flag given operands and result */ +char static inline z80_calc_ac(uint8_t a, uint8_t b, unsigned int r) +{ + /* calc xor for AC and overflow */ + unsigned int c = a ^ b ^ r; + + /* AC */ + if (c & 0x10) + return 1; + + return 0; +} + +/* calculate flags mask array */ +void static z80_calc_flags_mask_array() +{ + z80_flags_t f; + unsigned int i; + + // bzero(sz53pc, sizeof(sz53pc)); + + /* create a mask for bit 5 and 3 and its reverse */ +/* f.spare = 0= 1; f.z = 1; f.u5 = 0; f.ac = 1; f.u3 = 0; f.p = 1; f.n = 1; f.cy = 1; + u53_mask = *((uint8_t *) &f); + r53_mask = ~(u53_mask); */ + + bzero(&f, 1); + + for (i=0; i<512; i++) + { + f.z = ((i & 0xff) == 0); + f.cy = (i > 0xff); + + zc[i] = *((uint8_t *) &f); + + f.cy = 0; + + z[i] = *((uint8_t *) &f); + + /* no CY and parity */ +/* f.cy = 0; + f.p = parity[i & 0xff]; + sz53p[i] = *((uint8_t *) &f); +*/ + /* similar but with no u3 and u5 */ +/* f.u3 = 0; + f.u5 = 0; + szp[i] = *((uint8_t *) &f); +*/ + /* similar but with carry and no p */ +/* f.cy = (i > 0xff); + f.p = 0; + szc[i] = *((uint8_t *) &f); */ + } +} + + +/********************************/ +/* */ +/* INSTRUCTIONS SEGMENT */ +/* ordered by name */ +/* */ +/********************************/ + + +/* add A register, b parameter and Carry flag, then calculate flags */ +void static inline z80_adc(uint8_t b) +{ + /* calc result */ + unsigned int result = state.a + b + state.flags.cy; + + /* set flags - SZ5H3V0C */ + *state.f = zc[result & 0x1ff]; + + /* set AC and overflow flags */ + z80_set_flags_ac(state.a, b, result); + + /* save result into A register */ + state.a = (uint8_t) result; + + return; +} + +/* add a and b parameters (both 16 bits) and the carry, thencalculate flags */ +unsigned int static inline z80_adc_16(unsigned int a, unsigned int b) +{ + /* calc result */ + unsigned int result = a + b + state.flags.cy; + + /* set them - SZ5H3V0C */ + z80_set_flags_zc_16(result); + state.flags.n = 0; + + /* get only high byte */ + // unsigned int r16 = (result >> 8); + + /* set AC and overflow flags */ + z80_set_flags_ac_16(a, b, result); + + return result; +} + +/* add A register and b parameter and calculate flags */ +void static inline z80_add(uint8_t b) +{ + /* calc result */ + unsigned int result = state.a + b; + + /* set them - SZ5H3P0C */ + *state.f = zc[result & 0x1ff]; + + /* set AC and overflow flags - given AC and V set to 0 */ + z80_set_flags_ac(state.a, b, result); + + /* save result into A register */ + state.a = result; + + return; +} + +/* add a and b parameters (both 16 bits), then calculate flags */ +unsigned int static inline z80_add_16(unsigned int a, unsigned int b) +{ + /* calc result */ + unsigned int result = a + b; + + /* get only high byte */ + // uint8_t r16 = (result >> 8); + + /* not a subtraction */ + state.flags.n = 0; + + /* calc xor for AC */ + z80_set_flags_ac(a, b, result); + + /* set CY */ + state.flags.cy = (result > 0xffff); + + return result; +} + +/* b AND A register and calculate flags */ +void static inline z80_ana(uint8_t b) +{ + /* calc result */ + uint8_t result = state.a & b; + + /* set them */ + *state.f = zc[result] | FLAG_MASK_AC; + + /* save result into A register */ + state.a = result; + + return; +} + +/* BIT instruction, test pos-th bit and set flags */ +void static inline z80_bit(uint8_t *v, uint8_t pos, uint8_t muffa) +{ + uint8_t r = *v & (0x01 << pos); + + /* set flags AC,Z, N = 0 */ + state.flags.n = 0; + state.flags.ac = 1; + state.flags.z = (r == 0) ; + + return; +} + +/* push the current PC on the stack and move PC to the function addr */ +int static inline z80_call(unsigned int addr) +{ + /* move to the next instruction */ + state.pc += 3; + + /* add 4 more cycles */ + cycles_step(); + + /* save it into stack */ + mmu_write_16(state.sp - 2, state.pc); + + /* update stack pointer */ + state.sp -= 2; + + /* move PC to the called function address */ + state.pc = addr; + + return 0; +} + +/* compare b parameter against A register and calculate flags */ +void static inline z80_cmp(uint8_t b) +{ + /* calc result */ + unsigned int result = state.a - b; + + /* set flags - SZ5H3PN* */ + *state.f = zc[result & 0x1ff] | + FLAG_MASK_N; + + /* set AC and overflow flags */ + z80_set_flags_ac(state.a, b, result); + + return; +} + +/* compare b parameter against A register and calculate flags */ +void static inline z80_cpid(uint8_t b, int8_t add) +{ + /* calc result */ + unsigned int result = state.a - b; + + /* calc AC */ + state.flags.ac = z80_calc_ac(state.a, b, result); + + /* increase (add = +1) or decrease (add = -1) HL */ + *state.hl += add; + + /* decrease BC */ + *state.bc = *state.bc - 1; + + /* calc n as result - half carry flag */ + // unsigned int n = result - state.flags.ac; + + /* set flags - SZ5H3P1* */ + state.flags.z = (result & 0xff) == 0; + +// z80_set_flags_z(result); + + /* cmp = subtraction */ + state.flags.n = 1; + + /* set P if BC != 0 */ + // state.flags.p = (*state.bc != 0); + + /* flag 3 and 5 are taken from (result - ac) and not the result */ + /* and u5 is taken exceptionally from the bit 1 */ +// state.flags.u5 = (n & 0x0002) != 0; +// state.flags.u3 = (n & 0x0008) != 0; + + return; +} + +/* DAA instruction... what else? */ +void static inline z80_daa() +{ + unsigned int a = state.a; + uint8_t al = state.a & 0x0f; + + if (state.flags.n) + { + if (state.flags.ac) + a = (a - 6) & 0xFF; + + if (state.flags.cy) + a -= 0x60; + } + else + { + if (al > 9 || state.flags.ac) + { + state.flags.ac = (al > 9); + a += 6; + } + + if (state.flags.cy || ((a & 0x1f0) > 0x90)) + a += 0x60; + } + + if (a & 0x0100) state.flags.cy = 1; + + /* set computer A value */ + state.a = a & 0xff; + + state.flags.ac = 0; + state.flags.z = (state.a == 0); + + return; +} + +/* DAA instruction... what else? */ +void static inline z80_daa_ignore_n() +{ + unsigned int a = state.a; + uint8_t al = state.a & 0x0f; + + if (al > 9 || state.flags.ac) + { + state.flags.ac = (al > 9); + a += 6; + } + + if (state.flags.cy || ((a & 0x1f0) > 0x90)) + a += 0x60; + + if (a & 0x0100) state.flags.cy = 1; + + /* set computer A value */ + state.a = a & 0xff; + + /* reset H flag */ + state.flags.z = (state.a == 0x00); + state.flags.ac = 0; + + /* and its flags */ + // z80_set_flags_sz53p(state.a); + + return; +} + +/* add a and b parameters (both 16 bits) and the carry, thencalculate flags */ +unsigned int static inline dad_16(unsigned int a, unsigned int b) +{ + /* calc result */ + unsigned int result = a + b; + + /* reset n */ + state.flags.n = 0; + + /* calc xor for AC and overflow */ + unsigned int c = a ^ b ^ result; + + /* set AC */ + state.flags.ac = ((c & 0x1000) != 0); + + /* set CY */ + state.flags.cy = (result > 0xffff); + + return result; +} + +/* dec the operand and return result increased by one */ +uint8_t static inline z80_dcr(uint8_t b) +{ + unsigned int result = b - 1; + + /* set flags - SZ5H3V1* */ + z80_set_flags_z(result); + + /* it's a subtraction */ + state.flags.n = 1; + + /* set overflow and AC */ + z80_set_flags_ac(b, 1, result); + +// state.flags.ac = 0; + + return result; +} + +/* inc the operand and return result increased by one */ +uint8_t static inline z80_inr(uint8_t b) +{ + unsigned int result = b + 1; + + /* set flags - SZ5H3V1* */ + z80_set_flags_z(result); + + /* it's not a subtraction */ + state.flags.n = 0; + + /* set overflow and AC */ + z80_set_flags_ac(1, b, result); + + return result; +} + +/* same as call, but save on the stack the current PC instead of next instr */ +int static inline z80_intr(unsigned int addr) +{ + /* push the current PC into stack */ + mmu_write_16(state.sp - 2, state.pc); + + cycles_step(); + + /* update stack pointer */ + state.sp -= 2; + + /* move PC to the called function address */ + state.pc = addr; + + return 0; +} + +/* copy (HL) in (DE) and decrease HL, DE and BC */ +void static inline z80_ldd() +{ + uint8_t byte; + + /* copy! */ + mmu_move(*state.de, *state.hl); + + /* get last moved byte and sum A */ + byte = mmu_read(*state.de); + byte += state.a; + + /* decrease HL, DE and BC */ + *state.hl = *state.hl - 1; + *state.de = *state.de - 1; + *state.bc = *state.bc - 1; + + /* reset flags - preserve ZC */ + *state.f &= FLAG_MASK_Z | + FLAG_MASK_CY; + + return; +} + +/* copy (HL) in (DE) and increase HL and DE. BC is decreased */ +void static inline z80_ldi() +{ + uint8_t byte; + + /* copy! */ + mmu_move(*state.de, *state.hl); + + /* get last moved byte and sum A */ + byte = mmu_read(*state.de); + byte += state.a; + + /* u5 flag is bit 1 of last moved byte + A (WTF?) */ + // state.flags.u5 = (byte & 0x02) >> 1; + + /* u3 flag is bit 3 of last moved byte + A (WTF?) */ + // state.flags.u3 = (byte & 0x08) >> 3; + + /* decrease HL, DE and BC */ + *state.hl = *state.hl + 1; + *state.de = *state.de + 1; + *state.bc = *state.bc - 1; + + /* reset negative, half carry and parity flags */ + state.flags.n = 0; + state.flags.ac = 0; + // state.flags.p = (*state.bc != 0); + + return; +} + +/* negate register A */ +void static inline z80_neg() +{ + /* calc result */ + unsigned int result = 0 - state.a; + + /* set flags - SZ5H3V1C */ + *state.f = zc[result & 0x1ff] | FLAG_MASK_N; + + /* set AC and overflow */ + z80_set_flags_ac(0, state.a, result); + + /* save result into A register */ + state.a = (uint8_t) result; + + return; +} + +/* OR b parameter and A register and calculate flags */ +void static inline z80_ora(uint8_t b) +{ + state.a |= b; + + /* set them SZ503P0C */ + *state.f = zc[state.a]; + + return; +} + +/* RES instruction, put a 0 on pos-th bit and set flags */ +uint8_t static inline z80_res(uint8_t *v, uint8_t pos) +{ + *v &= ~(0x01 << pos); + + return *v; +} + +/* pop the return address from the stack and move PC to that address */ +int static inline z80_ret() +{ + state.pc = mmu_read_16(state.sp); + state.sp += 2; + + /* add 4 cycles */ + cycles_step(); + + return 0; +} + +/* RL (Rotate Left) instruction */ +uint8_t static inline z80_rl(uint8_t *v, char with_carry) +{ + uint8_t carry; + + /* apply RLC to the memory pointed byte */ + carry = (*v & 0x80) >> 7; + *v = *v << 1; + + if (with_carry) + *v |= carry; + else + *v |= state.flags.cy; + + /* set flags - SZ503P0C */ + *state.f = 0; // sz53p[*v]; + + state.flags.z = (*v == 0); + state.flags.cy = carry; + + return *v; +} + +/* RLA instruction */ +uint8_t static inline z80_rla(uint8_t *v, char with_carry) +{ + uint8_t carry; + + /* apply RLA to the memory pointed byte */ + carry = (*v & 0x80) >> 7; + *v = *v << 1; + + if (with_carry) + *v |= carry; + else + *v |= state.flags.cy; + + /* reset flags */ + *state.f = 0; + + /* just set carry */ + state.flags.cy = carry; + + return *v; +} + +/* RLD instruction */ +void static inline z80_rld() +{ + uint8_t hl = mmu_read(*state.hl); + + /* save lowest A 4 bits */ + uint8_t al = state.a & 0x0f; + + /* A lowest bits are overwritten by (HL) highest ones */ + state.a &= 0xf0; + state.a |= (hl >> 4); + + /* (HL) highest bits are overwritten by (HL) lowest ones */ + hl <<= 4; + + /* finally, (HL) lowest bits are overwritten by A lowest */ + hl &= 0xf0; + hl |= al; + + /* set (HL) with his new value ((HL) low | A low) */ + mmu_write(*state.hl, hl); + + /* reset flags - preserve CY */ + *state.f &= FLAG_MASK_CY; + + /* set flags - SZ503P0* */ + *state.f |= z[state.a]; + + return; +} + +/* RR instruction */ +uint8_t static inline z80_rr(uint8_t *v, char with_carry) +{ + uint8_t carry; + + /* apply RRC to the memory pointed byte */ + carry = *v & 0x01; + *v = (*v >> 1); + + /* 7th bit taken from old bit 0 or from CY */ + if (with_carry) + *v |= (carry << 7); + else + *v |= (state.flags.cy << 7); + + /* set flags - SZ503P0C */ + *state.f = z[*v]; + + state.flags.cy = carry; + + return *v; +} + +/* RRA instruction */ +uint8_t static inline z80_rra(uint8_t *v, char with_carry) +{ + uint8_t carry; + + /* apply RRC to the memory pointed byte */ + carry = *v & 0x01; + *v = (*v >> 1); + + /* 7th bit taken from old bit 0 or from CY */ + if (with_carry) + *v |= (carry << 7); + else + *v |= (state.flags.cy << 7); + + /* reset flags */ + *state.f = 0; + + state.flags.cy = carry; + +// state.flags.n = 0; +// state.flags.ac = 0; + + /* copy bit 3 and 5 of the result */ + // state.flags.u3 = ((*v & 0x08) != 0); + // state.flags.u5 = ((*v & 0x20) != 0); + + return *v; +} + +/* RRD instruction */ +void static inline z80_rrd() +{ + uint8_t hl = mmu_read(*state.hl); + + /* save lowest (HL) 4 bits */ + uint8_t hll = hl & 0x0f; + + /* (HL) lowest bits are overwritten by (HL) highest ones */ + hl >>= 4; + + /* (HL) highest bits are overwritten by A lowest ones */ + hl |= ((state.a & 0x0f) << 4); + + /* set (HL) with his new value (A low | (HL) high) */ + mmu_write(*state.hl, hl); + + /* finally, A lowest bits are overwritten by (HL) lowest */ + state.a &= 0xf0; + state.a |= hll; + + /* reset flags - preserve CY */ + *state.f &= FLAG_MASK_CY; + + /* set flags - SZ503P0* */ + *state.f |= z[state.a]; + + return; +} + +/* subtract b parameter and Carry from A register and calculate flags */ +void static inline z80_sbc(uint8_t b) +{ + /* calc result */ + unsigned int result = state.a - b - state.flags.cy; + + /* set flags - ZC and N = 1 */ + *state.f = zc[result & 0x1ff] | FLAG_MASK_N; + + /* set AC */ + z80_set_flags_ac(state.a, b, result); + + /* save result into A register */ + state.a = (uint8_t) result; + + return; +} + +/* subtract a and b parameters (both 16 bits) and the carry, then calculate flags */ +unsigned int static inline z80_sbc_16(unsigned int a, unsigned int b) +{ + /* calc result */ + unsigned int result = a - b - state.flags.cy; + + /* set flags - SZ5H3V1C */ + z80_set_flags_zc_16(result); + state.flags.n = 1; + + /* get only high byte */ + // unsigned int r16 = (result >> 8); + + /* set AC and overflow flags */ + z80_set_flags_ac_16(a, b, result); + + return result; +} + +/* SET instruction, put a 1 on pos-th bit and set flags */ +uint8_t static inline z80_set(uint8_t *v, uint8_t pos) +{ + *v |= (0x01 << pos); + + return *v; +} + +/* SL instruction (SLA = v * 2, SLL = v * 2 + 1) */ +uint8_t static inline z80_sl(uint8_t *v, char one_insertion) +{ + /* move pointed value to local (gives an huge boost in perf!) */ + uint8_t l = *v; + + /* apply SL to the memory pointed byte */ + uint8_t cy = (l & 0x80) != 0; + l = (l << 1) | one_insertion; + + /* set flags - SZ503P0C */ + *state.f = z[l]; + + state.flags.cy = cy; + + /* re-assign local value */ + *v = l; + + return l; +} + +/* SR instruction (SRA = preserve 8th bit, SRL = discard 8th bit) */ +uint8_t static inline z80_sr(uint8_t *v, char preserve) +{ + uint8_t bit = 0; + + /* save the bit 0 */ + uint8_t cy = (*v & 0x01); + + /* apply SL to the memory pointed byte */ + if (preserve) + bit = *v & 0x80; + + /* move 1 pos right and restore highest bit (in case of SRA) */ + *v = (*v >> 1) | bit; + + /* set flags - SZ503P0C */ + *state.f = z[*v]; + + state.flags.cy = cy; + + return *v; +} + +/* subtract b parameter from A register and calculate flags */ +void static inline z80_sub(uint8_t b) +{ + /* calc result */ + unsigned int result = state.a - b; + + /* set them - SZ5H3V1C */ + *state.f = zc[result & 0x1ff] | FLAG_MASK_N; + + /* set AC and overflow flags */ + z80_set_flags_ac(state.a, b, result); + + /* save result into A register */ + state.a = (uint8_t) result; + + return; +} + +/* xor b parameter and A register and calculate flags */ +void static inline z80_xra(uint8_t b) +{ + /* calc result */ + state.a ^= b; + + /* set them SZ503P00 */ + *state.f = z[state.a]; + + return; +} + + + +/********************************/ +/* */ +/* INSTRUCTIONS BRANCHES */ +/* */ +/********************************/ + + +/* Z80 extended OPs */ +int static inline z80_ext_cb_execute() +{ + uint8_t byte = 1; + int b = 2; + + /* CB family (ROT, BIT, RES, SET) */ + uint8_t cbfam; + + /* CB operation */ + uint8_t cbop; + + /* choosen register */ + uint8_t reg; + + /* get CB code */ + uint8_t code = mmu_read(state.pc + 1); + + /* extract family */ + cbfam = code >> 6; + + /* extract involved register */ + reg = code & 0x07; + + /* if reg == 0x06, refresh the pointer */ + // if (reg == 0x06 && code != 0x36) + // { + /* add 4 more cycles for reading data from memory */ + // cycles_step(); + + // regs_src[0x06] = mmu_addr(*state.hl); + // } + + switch (cbfam) + { + /* Rotate Family */ + case 0x00: cbop = code & 0xf8; + + switch(cbop) + { + /* RLC REG */ + case 0x00: if (reg == 0x06) + { + byte = mmu_read(*state.hl); + mmu_write(*state.hl, z80_rl(&byte, 1)); + } + else + z80_rl(regs_src[reg], 1); + break; + + /* RRC REG */ + case 0x08: if (reg == 0x06) + { + byte = mmu_read(*state.hl); + mmu_write(*state.hl, z80_rr(&byte, 1)); + } + else + z80_rr(regs_src[reg], 1); + + break; + + /* RL REG */ + case 0x10: if (reg == 0x06) + { + byte = mmu_read(*state.hl); + mmu_write(*state.hl, z80_rl(&byte, 0)); + } + else + z80_rl(regs_src[reg], 0); + + break; + + /* RR REG */ + case 0x18: if (reg == 0x06) + { + byte = mmu_read(*state.hl); + mmu_write(*state.hl, z80_rr(&byte, 0)); + } + else + z80_rr(regs_src[reg], 0); + + break; + + /* SLA REG */ + case 0x20: if (reg == 0x06) + { + byte = mmu_read(*state.hl); + mmu_write(*state.hl, z80_sl(&byte, 0)); + } + else + z80_sl(regs_src[reg], 0); + + break; + + /* SRA REG */ + case 0x28: if (reg == 0x06) + { + byte = mmu_read(*state.hl); + mmu_write(*state.hl, z80_sr(&byte, 1)); + } + else + z80_sr(regs_src[reg], 1); + + break; + + /* SWAP */ + case 0x30: + switch (code & 0x37) + { + /* SWAP B */ + case 0x30: byte = state.b; + state.b = ((byte & 0xf0) >> 4) | + ((byte & 0x0f) << 4); + break; + + /* SWAP C */ + case 0x31: byte = state.c; + state.c = ((byte & 0xf0) >> 4) | + ((byte & 0x0f) << 4); + break; + + /* SWAP D */ + case 0x32: byte = state.d; + state.d = ((byte & 0xf0) >> 4) | + ((byte & 0x0f) << 4); + break; + + /* SWAP E */ + case 0x33: byte = state.e; + state.e = ((byte & 0xf0) >> 4) | + ((byte & 0x0f) << 4); + break; + + /* SWAP H */ + case 0x34: byte = state.h; + state.h = ((byte & 0xf0) >> 4) | + ((byte & 0x0f) << 4); + break; + + /* SWAP L */ + case 0x35: byte = state.l; + state.l = ((byte & 0xf0) >> 4) | + ((byte & 0x0f) << 4); + break; + + /* SWAP *HL */ + case 0x36: byte = mmu_read(*state.hl); + mmu_write(*state.hl, + ((byte & 0xf0) >> 4) | + ((byte & 0x0f) << 4)); + + break; + + /* SWAP A */ + case 0x37: + byte = state.a; + state.a = ((byte & 0xf0) >> 4) | + ((byte & 0x0f) << 4); + break; + + } + + /* swap functions set Z flags */ + state.flags.z = (byte == 0x00); + + /* reset all the others */ + state.flags.ac = 0; + state.flags.cy = 0; + state.flags.n = 0; + + break; + + /* SRL REG */ + case 0x38: if (reg == 0x06) + { + byte = mmu_read(*state.hl); + mmu_write(*state.hl, z80_sr(&byte, 0)); + } + else + z80_sr(regs_src[reg], 0); + + break; + } + + /* accessing HL needs more T-cycles */ + //if (reg == 0x06 && code != 0x36) + // cycles_step(); + + /* accessing HL needs more T-cycles */ +// if (reg == 0x06) +// cycles_step(); + + break; + + /* BIT Family */ + case 0x01: if (reg == 0x06) + { + byte = mmu_read(*state.hl); + z80_bit(&byte, (code >> 3) & 0x07, + (uint8_t) *state.hl); + } + else + z80_bit(regs_src[reg], (code >> 3) & 0x07, + *regs_src[reg]); + break; + + /* RES Family */ + case 0x02: if (reg == 0x06) + { + byte = mmu_read(*state.hl); + mmu_write(*state.hl, z80_res(&byte, (code >> 3) & 0x07)); + } + else + z80_res(regs_src[reg], (code >> 3) & 0x07); + + break; + + /* SET Family */ + case 0x03: if (reg == 0x06) + { + byte = mmu_read(*state.hl); + mmu_write(*state.hl, z80_set(&byte, (code >> 3) & 0x07)); + } + else + z80_set(regs_src[reg], (code >> 3) & 0x07); + + break; + +// default: printf("Unimplemented CB family: %02x\n", +// cbfam); + + } + + return b; +} + + +/* really execute the OP. Could be ran by normal execution or * + * because an interrupt occours */ +int static inline z80_execute(unsigned char code) +{ + int b = 1; + uint8_t *p; + uint8_t byte = 1; + uint8_t byte2 = 1; + unsigned int result; + uint_fast16_t addr; + + switch (code) + { + /* NOP */ + case 0x00: break; + + /* LXI B */ + case 0x01: *state.bc = ADDR; + b = 3; + break; + + /* STAX B */ + case 0x02: mmu_write(*state.bc, state.a); + break; + + /* INX B */ + case 0x03: (*state.bc)++; + cycles_step(); + break; + + /* INR B */ + case 0x04: state.b = z80_inr(state.b); + break; + + /* DCR B */ + case 0x05: state.b = z80_dcr(state.b); + break; + + /* MVI B */ + case 0x06: state.b = mmu_read(state.pc + 1); + b = 2; + break; + + /* RLCA */ + case 0x07: z80_rla(&state.a, 1); + break; + + /* LD (NN),SP */ + case 0x08: mmu_write_16(ADDR, state.sp); + b = 3; + break; + + /* DAD B */ + case 0x09: *state.hl = dad_16(*state.hl, *state.bc); + + /* needs 4 more cycles */ + cycles_step(); + + break; + + /* LDAX B */ + case 0x0A: state.a = mmu_read(*state.bc); + break; + + /* DCX B */ + case 0x0B: (*state.bc)--; + cycles_step(); + break; + + /* INR C */ + case 0x0C: state.c = z80_inr(state.c); + break; + + /* DCR C */ + case 0x0D: state.c = z80_dcr(state.c); + break; + + /* MVI C */ + case 0x0E: state.c = mmu_read(state.pc + 1); + b = 2; + break; + + /* RRC */ + case 0x0F: z80_rra(&state.a, 1); + break; + + /* STOP */ + case 0x10: b = 2; + break; + + /* LXI D */ + case 0x11: *state.de = ADDR; + b = 3; + break; + + /* STAX D */ + case 0x12: mmu_write(*state.de, state.a); + break; + + /* INX D */ + case 0x13: (*state.de)++; + cycles_step(); + break; + + /* INR D */ + case 0x14: state.d = z80_inr(state.d); + break; + + /* DCR D */ + case 0x15: state.d = z80_dcr(state.d); + break; + + /* MVI D */ + case 0x16: state.d = mmu_read(state.pc + 1); + b = 2; + break; + + /* RLA */ + case 0x17: z80_rla(&state.a, 0); + break; + + /* JR */ + case 0x18: cycles_step(); + state.pc += (int8_t) mmu_read(state.pc + 1); + b = 2; + break; + + /* DAD D */ + case 0x19: *state.hl = dad_16(*state.hl, *state.de); + + /* needs 4 more cycles */ + cycles_step(); + + break; + + /* LDAX D */ + case 0x1A: state.a = mmu_read(*state.de); + break; + + /* DCX D */ + case 0x1B: (*state.de)--; + cycles_step(); + break; + + /* INR E */ + case 0x1C: state.e = z80_inr(state.e); + break; + + /* DCR E */ + case 0x1D: state.e = z80_dcr(state.e); + break; + + /* MVI E */ + case 0x1E: state.e = mmu_read(state.pc + 1); + b = 2; + break; + + /* RRA */ + case 0x1F: z80_rra(&state.a, 0); + break; + + /* JRNZ */ + case 0x20: cycles_step(); + + if (!state.flags.z) + state.pc += (int8_t) mmu_read(state.pc + 1); + + b = 2; + break; + + /* LXI H */ + case 0x21: *state.hl = ADDR; + b = 3; + break; + + /* LDI (HL), A */ + case 0x22: mmu_write(*state.hl, state.a); + (*state.hl)++; + break; + + /* INX H */ + case 0x23: (*state.hl)++; + cycles_step(); + break; + + /* INR H */ + case 0x24: state.h = z80_inr(state.h); + break; + + /* DCR H */ + case 0x25: state.h = z80_dcr(state.h); + break; + + /* MVI H */ + case 0x26: state.h = mmu_read(state.pc + 1); + b = 2; + break; + + /* DAA */ + case 0x27: z80_daa(); + break; + + /* JRZ */ + case 0x28: cycles_step(); + if (state.flags.z) + state.pc += (int8_t) mmu_read(state.pc + 1); + + b = 2; + break; + + /* DAD H */ + case 0x29: *state.hl = dad_16(*state.hl, *state.hl); + + /* needs 4 more cycles */ + cycles_step(); + + break; + + /* LDI A,(HL) */ + case 0x2A: state.a = mmu_read(*state.hl); + (*state.hl)++; + break; + + /* DCX H */ + case 0x2B: (*state.hl)--; + cycles_step(); + break; + + /* INR L */ + case 0x2C: state.l = z80_inr(state.l); + break; + + /* DCR L */ + case 0x2D: state.l = z80_dcr(state.l); + break; + + /* MVI L */ + case 0x2E: state.l = mmu_read(state.pc + 1); + b = 2; + break; + + /* CMA A */ + case 0x2F: state.a = ~state.a; + state.flags.ac = 1; + state.flags.n = 1; + break; + + /* JRNC */ + case 0x30: cycles_step(); + + if (!state.flags.cy) + state.pc += (int8_t) mmu_read(state.pc + 1); + + b = 2; + break; + + /* LXI SP */ + case 0x31: state.sp = ADDR; + b = 3; + break; + + /* LDD (HL), A */ + case 0x32: mmu_write(*state.hl, state.a); + (*state.hl)--; + break; + + /* INX SP */ + case 0x33: state.sp++; + cycles_step(); + break; + + /* INR M */ + case 0x34: mmu_write(*state.hl, z80_inr(mmu_read(*state.hl))); + break; + + /* DCR M */ + case 0x35: mmu_write(*state.hl, z80_dcr(mmu_read(*state.hl))); + break; + + /* MVI M */ + case 0x36: mmu_move(*state.hl, state.pc + 1); + b = 2; + break; + + /* STC */ + case 0x37: state.flags.cy = 1; + state.flags.ac = 0; + state.flags.n = 0; + break; + + /* JRC */ + case 0x38: cycles_step(); + if (state.flags.cy) + state.pc += (int8_t) mmu_read(state.pc + 1); + + b = 2; + break; + + /* DAD SP */ + case 0x39: *state.hl = dad_16(*state.hl, state.sp); + + /* needs 4 more cycles */ + cycles_step(); + + break; + + /* LDD A,(HL) */ + case 0x3A: state.a = mmu_read(*state.hl); + (*state.hl)--; + break; + + /* DCX SP */ + case 0x3B: state.sp--; + cycles_step(); + break; + + /* INR A */ + case 0x3C: state.a = z80_inr(state.a); + break; + + /* DCR A */ + case 0x3D: state.a = z80_dcr(state.a); + break; + + /* MVI A */ + case 0x3E: state.a = mmu_read(state.pc + 1); + b = 2; + break; + + /* CCF */ + case 0x3F: state.flags.ac = 0; + state.flags.cy = !state.flags.cy; + state.flags.n = 0; + + break; + + /* MOV B,B */ + case 0x40: state.b = state.b; + break; + + /* MOV B,C */ + case 0x41: state.b = state.c; + break; + + /* MOV B,D */ + case 0x42: state.b = state.d; + break; + + /* MOV B,E */ + case 0x43: state.b = state.e; + break; + + /* MOV B,H */ + case 0x44: state.b = state.h; + break; + + /* MOV B,L */ + case 0x45: state.b = state.l; + break; + + /* MOV B,M */ + case 0x46: state.b = mmu_read(*state.hl); + break; + + /* MOV B,A */ + case 0x47: state.b = state.a; + break; + + /* MOV C,B */ + case 0x48: state.c = state.b; + break; + + /* MOV C,C */ + case 0x49: state.c = state.c; + break; + + /* MOV C,D */ + case 0x4A: state.c = state.d; + break; + + /* MOV C,E */ + case 0x4B: state.c = state.e; + break; + + /* MOV C,H */ + case 0x4C: state.c = state.h; + break; + + /* MOV C,L */ + case 0x4D: state.c = state.l; + break; + + /* MOV C,M */ + case 0x4E: state.c = mmu_read(*state.hl); + break; + + /* MOV C,A */ + case 0x4F: state.c = state.a; + break; + + /* MOV D,B */ + case 0x50: state.d = state.b; + break; + + /* MOV D,C */ + case 0x51: state.d = state.c; + break; + + /* MOV D,D */ + case 0x52: state.d = state.d; + break; + + /* MOV D,E */ + case 0x53: state.d = state.e; + break; + + /* MOV D,H */ + case 0x54: state.d = state.h; + break; + + /* MOV D,L */ + case 0x55: state.d = state.l; + break; + + /* MOV D,M */ + case 0x56: state.d = mmu_read(*state.hl); + break; + + /* MOV D,A */ + case 0x57: state.d = state.a; + break; + + /* MOV E,B */ + case 0x58: state.e = state.b; + break; + + /* MOV E,C */ + case 0x59: state.e = state.c; + break; + + /* MOV E,D */ + case 0x5A: state.e = state.d; + break; + + /* MOV E,E */ + case 0x5B: state.e = state.e; + break; + + /* MOV E,H */ + case 0x5C: state.e = state.h; + break; + + /* MOV E,L */ + case 0x5D: state.e = state.l; + break; + + /* MOV E,M */ + case 0x5E: state.e = mmu_read(*state.hl); + break; + + /* MOV E,A */ + case 0x5F: state.e = state.a; + break; + + /* MOV H,B */ + case 0x60: state.h = state.b; + break; + + /* MOV H,C */ + case 0x61: state.h = state.c; + break; + + /* MOV H,D */ + case 0x62: state.h = state.d; + break; + + /* MOV H,E */ + case 0x63: state.h = state.e; + break; + + /* MOV H,H */ + case 0x64: state.h = state.h; + break; + + /* MOV H,L */ + case 0x65: state.h = state.l; + break; + + /* MOV H,M */ + case 0x66: state.h = mmu_read(*state.hl); + break; + + /* MOV H,A */ + case 0x67: state.h = state.a; + break; + + /* MOV L,B */ + case 0x68: state.l = state.b; + break; + + /* MOV L,C */ + case 0x69: state.l = state.c; + break; + + /* MOV L,D */ + case 0x6A: state.l = state.d; + break; + + /* MOV L,E */ + case 0x6B: state.l = state.e; + break; + + /* MOV L,H */ + case 0x6C: state.l = state.h; + break; + + /* MOV L,L */ + case 0x6D: state.l = state.l; + break; + + /* MOV L,M */ + case 0x6E: state.l = mmu_read(*state.hl); + break; + + /* MOV L,A */ + case 0x6F: state.l = state.a; + break; + + /* MOV M,B */ + case 0x70: mmu_write(*state.hl, state.b); + break; + + /* MOV M,C */ + case 0x71: mmu_write(*state.hl, state.c); + break; + + /* MOV M,D */ + case 0x72: mmu_write(*state.hl, state.d); + break; + + /* MOV M,E */ + case 0x73: mmu_write(*state.hl, state.e); + break; + + /* MOV M,H */ + case 0x74: mmu_write(*state.hl, state.h); + break; + + /* MOV M,L */ + case 0x75: mmu_write(*state.hl, state.l); + break; + + /* HLT */ + case 0x76: return 1; + + /* MOV M,A */ + case 0x77: mmu_write(*state.hl, state.a); + break; + + /* MOV A,B */ + case 0x78: state.a = state.b; + break; + + /* MOV A,C */ + case 0x79: state.a = state.c; + break; + + /* MOV A,D */ + case 0x7A: state.a = state.d; + break; + + /* MOV A,E */ + case 0x7B: state.a = state.e; + break; + + /* MOV A,H */ + case 0x7C: state.a = state.h; + break; + + /* MOV A,L */ + case 0x7D: state.a = state.l; + break; + + /* MOV A,M */ + case 0x7E: state.a = mmu_read(*state.hl); + break; + + /* MOV A,A */ + case 0x7F: state.a = state.a; + break; + + /* ADD B */ + case 0x80: z80_add(state.b); + break; + + /* ADD C */ + case 0x81: z80_add(state.c); + break; + + /* ADD D */ + case 0x82: z80_add(state.d); + break; + + /* ADD E */ + case 0x83: z80_add(state.e); + break; + + /* ADD H */ + case 0x84: z80_add(state.h); + break; + + /* ADD L */ + case 0x85: z80_add(state.l); + break; + + /* ADD M */ + case 0x86: z80_add(mmu_read(*state.hl)); + break; + + /* ADD A */ + case 0x87: z80_add(state.a); + break; + + /* ADC B */ + case 0x88: z80_adc(state.b); + break; + + /* ADC C */ + case 0x89: z80_adc(state.c); + break; + + /* ADC D */ + case 0x8A: z80_adc(state.d); + break; + + /* ADC E */ + case 0x8B: z80_adc(state.e); + break; + + /* ADC H */ + case 0x8C: z80_adc(state.h); + break; + + /* ADC L */ + case 0x8D: z80_adc(state.l); + break; + + /* ADC M */ + case 0x8E: z80_adc(mmu_read(*state.hl)); + break; + + /* ADC A */ + case 0x8F: z80_adc(state.a); + break; + + /* SUB B */ + case 0x90: z80_sub(state.b); + break; + + /* SUB C */ + case 0x91: z80_sub(state.c); + break; + + /* SUB D */ + case 0x92: z80_sub(state.d); + break; + + /* SUB E */ + case 0x93: z80_sub(state.e); + break; + + /* SUB H */ + case 0x94: z80_sub(state.h); + break; + + /* SUB L */ + case 0x95: z80_sub(state.l); + break; + + /* SUB M */ + case 0x96: z80_sub(mmu_read(*state.hl)); + break; + + /* SUB A */ + case 0x97: z80_sub(state.a); + break; + + /* SBC B */ + case 0x98: z80_sbc(state.b); + break; + + /* SBC C */ + case 0x99: z80_sbc(state.c); + break; + + /* SBC D */ + case 0x9a: z80_sbc(state.d); + break; + + /* SBC E */ + case 0x9b: z80_sbc(state.e); + break; + + /* SBC H */ + case 0x9c: z80_sbc(state.h); + break; + + /* SBC L */ + case 0x9d: z80_sbc(state.l); + break; + + /* SBC M */ + case 0x9E: z80_sbc(mmu_read(*state.hl)); + break; + + /* SBC A */ + case 0x9f: z80_sbc(state.a); + break; + + /* ANA B */ + case 0xA0: z80_ana(state.b); + break; + + /* ANA C */ + case 0xA1: z80_ana(state.c); + break; + + /* ANA D */ + case 0xA2: z80_ana(state.d); + break; + + /* ANA E */ + case 0xA3: z80_ana(state.e); + break; + + /* ANA H */ + case 0xA4: z80_ana(state.h); + break; + + /* ANA L */ + case 0xA5: z80_ana(state.l); + break; + + /* ANA M */ + case 0xA6: z80_ana(mmu_read(*state.hl)); + break; + + /* ANA A */ + case 0xA7: z80_ana(state.a); + break; + + /* XRA B */ + case 0xA8: z80_xra(state.b); + break; + + /* XRA C */ + case 0xA9: z80_xra(state.c); + break; + + /* XRA D */ + case 0xAA: z80_xra(state.d); + break; + + /* XRA E */ + case 0xAB: z80_xra(state.e); + break; + + /* XRA H */ + case 0xAC: z80_xra(state.h); + break; + + /* XRA L */ + case 0xAD: z80_xra(state.l); + break; + + /* XRA M */ + case 0xAE: z80_xra(mmu_read(*state.hl)); + break; + + /* XRA A */ + case 0xAF: z80_xra(state.a); + break; + + /* ORA B */ + case 0xB0: z80_ora(state.b); + break; + + /* ORA C */ + case 0xB1: z80_ora(state.c); + break; + + /* ORA D */ + case 0xB2: z80_ora(state.d); + break; + + /* ORA E */ + case 0xB3: z80_ora(state.e); + break; + + /* ORA H */ + case 0xB4: z80_ora(state.h); + break; + + /* ORA L */ + case 0xB5: z80_ora(state.l); + break; + + /* ORA M */ + case 0xB6: z80_ora(mmu_read(*state.hl)); + break; + + /* ORA A */ + case 0xB7: z80_ora(state.a); + break; + + /* CMP B */ + case 0xB8: z80_cmp(state.b); + break; + + /* CMP C */ + case 0xB9: z80_cmp(state.c); + break; + + /* CMP D */ + case 0xBA: z80_cmp(state.d); + break; + + /* CMP E */ + case 0xBB: z80_cmp(state.e); + break; + + /* CMP H */ + case 0xBC: z80_cmp(state.h); + break; + + /* CMP L */ + case 0xBD: z80_cmp(state.l); + break; + + /* CMP M */ + case 0xBE: z80_cmp(mmu_read(*state.hl)); + break; + + /* CMP A */ + case 0xBF: z80_cmp(state.a); + break; + + /* RNZ */ + case 0xC0: cycles_step(); + + if (state.flags.z == 0) + return z80_ret(); + + break; + + /* POP B */ + case 0xC1: *state.bc = mmu_read_16(state.sp); + state.sp += 2; + break; + + /* JNZ addr */ + case 0xC2: /* this will add 8 cycles */ + addr = ADDR; + + if (state.flags.z == 0) + { + /* add 4 more cycles */ + cycles_step(); + + state.pc = addr; + return 0; + } + + b = 3; + break; + + /* JMP addr */ + case 0xC3: state.pc = ADDR; + + /* add 4 cycles */ + cycles_step(); + + return 0; + + /* CNZ */ + case 0xC4: addr = ADDR; + + if (state.flags.z == 0) + return z80_call(addr); + + b = 3; + break; + + /* PUSH B */ + case 0xC5: cycles_step(); + mmu_write_16(state.sp - 2, *state.bc); + state.sp -= 2; + break; + + /* ADI */ + case 0xC6: z80_add(mmu_read(state.pc + 1)); + b = 2; + break; + + /* RST 0 */ + case 0xC7: state.pc++; + return z80_intr(0x0008 * 0); + + /* RZ */ + case 0xC8: cycles_step(); + + if (state.flags.z) + return z80_ret(); + + break; + + /* RET */ + case 0xC9: return z80_ret(); + + /* JZ */ + case 0xCA: /* add 8 cycles */ + addr = ADDR; + + if (state.flags.z) + { + /* add 4 more cycles */ + cycles_step(); + + state.pc = addr; + return 0; + } + + b = 3; + break; + + /* CB */ + case 0xCB: b = z80_ext_cb_execute(); + break; + + /* CZ */ + case 0xCC: addr = ADDR; + + if (state.flags.z) + return z80_call(addr); + + b = 3; + break; + + /* CALL addr */ + case 0xCD: return z80_call(ADDR); + + /* ACI */ + case 0xCE: z80_adc(mmu_read(state.pc + 1)); + b = 2; + break; + + /* RST 1 */ + case 0xCF: state.pc++; + return z80_intr(0x0008 * 1); + + /* RNC */ + case 0xD0: cycles_step(); + + if (state.flags.cy == 0) + return z80_ret(); + + break; + + /* POP D */ + case 0xD1: *state.de = mmu_read_16(state.sp); + state.sp += 2; + break; + + /* JNC */ + case 0xD2: /* add 8 cycles */ + addr = ADDR; + + if (state.flags.cy == 0) + { + /* add 4 more cycles */ + cycles_step(); + + state.pc = addr; + return 0; + } + + b = 3; + break; + + /* not present */ + case 0xD3: // b = 2; + break; + + /* CNC */ + case 0xD4: addr = ADDR; + + if (state.flags.cy == 0) + return z80_call(addr); + + b = 3; + break; + + /* PUSH D */ + case 0xD5: cycles_step(); + mmu_write_16(state.sp - 2, *state.de); + state.sp -= 2; + break; + + /* SUI */ + case 0xD6: z80_sub(mmu_read(state.pc + 1)); + b = 2; + break; + + /* RST 2 */ + case 0xD7: state.pc++; + return z80_intr(0x0008 * 2); + + /* RC */ + case 0xD8: cycles_step(); + + if (state.flags.cy) + return z80_ret(); + + break; + + /* RETI */ + case 0xD9: state.int_enable = 1; + return z80_ret(); + break; + + /* JC */ + case 0xDA: /* add 8 cycles */ + addr = ADDR; + + if (state.flags.cy) + { + /* add 4 more cycles */ + cycles_step(); + + state.pc = addr; + return 0; + } + + b = 3; + break; + + /* not present */ + case 0xDB: break; + + /* CC */ + case 0xDC: addr = ADDR; + + if (state.flags.cy) + return z80_call(addr); + + b = 3; + break; + + /* SBI */ + case 0xDE: z80_sbc(mmu_read(state.pc + 1)); + b = 2; + break; + + /* RST 3 */ + case 0xDF: state.pc++; + return z80_intr(0x0008 * 3); + + /* LD (FF00+N),A */ + case 0xE0: mmu_write(0xFF00 + mmu_read(state.pc + 1), state.a); + b = 2; + break; + + /* POP H */ + case 0xE1: *state.hl = mmu_read_16(state.sp); + state.sp += 2; + break; + + /* LD (FF00+C),A */ + case 0xE2: mmu_write(0xFF00 + state.c, state.a); + break; + + /* not present on Gameboy Z80 */ + case 0xE3: + case 0xE4: break; + + /* PUSH H */ + case 0xE5: cycles_step(); + mmu_write_16(state.sp - 2, *state.hl); + state.sp -= 2; + break; + + /* ANI */ + case 0xE6: z80_ana(mmu_read(state.pc + 1)); + b = 2; + break; + + /* RST 4 */ + case 0xE7: state.pc++; + return z80_intr(0x0008 * 4); + + /* ADD SP,dd */ + case 0xE8: byte = mmu_read(state.pc + 1); + byte2 = (uint8_t) (state.sp & 0x00ff); + result = byte2 + byte; + + state.flags.z = 0; + state.flags.n = 0; + + state.flags.cy = (result > 0xff); + + /* add 8 cycles */ + cycles_step(); + cycles_step(); + + /* calc xor for AC */ + z80_set_flags_ac(byte2, byte, result); + + /* set sp */ + state.sp += (int8_t) byte; // result & 0xffff; + + b = 2; + break; + + /* PCHL */ + case 0xE9: state.pc = *state.hl; + return 0; + + /* LD (NN),A */ + case 0xEA: mmu_write(ADDR, state.a); + b = 3; + break; + + /* not present on Gameboy Z80 */ + case 0xEB: + case 0xEC: + case 0xED: break; + + /* XRI */ + case 0xEE: z80_xra(mmu_read(state.pc + 1)); + b = 2; + break; + + /* RST 5 */ + case 0xEF: state.pc++; + return z80_intr(0x0008 * 5); + + /* LD A,(FF00+N) */ + case 0xF0: state.a = mmu_read(0xFF00 + mmu_read(state.pc + 1)); + b = 2; + break; + + /* POP PSW */ + case 0xF1: p = (uint8_t *) &state.flags; + *p = (mmu_read(state.sp) & 0xf0); + state.a = mmu_read(state.sp + 1); + + state.sp += 2; + break; + + /* LD A,(FF00+C) */ + case 0xF2: state.a = mmu_read(0xFF00 + state.c); + break; + + /* DI */ + case 0xF3: state.int_enable = 0; + break; + + /* not present on Gameboy Z80 */ + case 0xF4: break; + + /* PUSH PSW */ + case 0xF5: p = (uint8_t *) &state.flags; + + cycles_step(); + + mmu_write(state.sp - 1, state.a); + mmu_write(state.sp - 2, *p); + state.sp -= 2; + break; + + /* ORI */ + case 0xF6: z80_ora(mmu_read(state.pc + 1)); + b = 2; + break; + + /* RST 6 */ + case 0xF7: state.pc++; + return z80_intr(0x0008 * 6); + + /* LD HL,SP+dd */ + case 0xF8: byte = mmu_read(state.pc + 1); + byte2 = (uint8_t) (state.sp & 0x00ff); + result = byte2 + byte; + + state.flags.z = 0; + state.flags.n = 0; + + state.flags.cy = (result > 0xff); + + /* add 4 cycles */ + cycles_step(); + + /* calc xor for AC */ + z80_set_flags_ac(byte2, byte, result); + + /* set sp */ + *state.hl = state.sp + (int8_t) byte; // result & 0xffff; + + b = 2; + break; + + /* SPHL */ + case 0xF9: cycles_step(); + state.sp = *state.hl; + break; + + /* LD A, (NN) */ + case 0xFA: state.a = mmu_read(ADDR); + b = 3; + break; + + /* EI */ + case 0xFB: state.int_enable = 1; + break; + + /* not present on Gameboy Z80 */ + case 0xFC: + case 0xFD: break; + + /* CPI */ + case 0xFE: z80_cmp(mmu_read(state.pc + 1)); + b = 2; + break; + + /* RST 7 */ + case 0xFF: state.pc++; + return z80_intr(0x0008 * 7); + + default: return 1; + } + + /* make the PC points to the next instruction */ + state.pc += b; + + return 0; +} + +/* init registers, flags and state.memory of Gameboy Z80 CPU */ +z80_state_t static *z80_init() +{ + /* wipe all the structs */ + bzero(&state, sizeof(z80_state_t)); + +/* 16 bit values just point to the first reg of the pairs */ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + state.hl = (uint16_t *) &state.l; + state.bc = (uint16_t *) &state.c; + state.de = (uint16_t *) &state.e; +#else + state.hl = (uint16_t *) &state.h; + state.bc = (uint16_t *) &state.b; + state.de = (uint16_t *) &state.d; +#endif + + state.sp = 0xffff; + state.a = 0xff; + + state.b = 0x7f; + state.c = 0xbc; + state.d = 0x00; + state.e = 0x00; + state.h = 0x34; + state.l = 0xc0; + + regs_dst = malloc(8 * sizeof(uint8_t *)); + + regs_dst[0x00] = &state.b; + regs_dst[0x01] = &state.c; + regs_dst[0x02] = &state.d; + regs_dst[0x03] = &state.e; + regs_dst[0x04] = &state.h; + regs_dst[0x05] = &state.l; + regs_dst[0x06] = &dummy; + regs_dst[0x07] = &state.a; + + regs_src = malloc(8 * sizeof(uint8_t *)); + + regs_src[0x00] = &state.b; + regs_src[0x01] = &state.c; + regs_src[0x02] = &state.d; + regs_src[0x03] = &state.e; + regs_src[0x04] = &state.h; + regs_src[0x05] = &state.l; + regs_src[0x06] = mmu_addr(*state.hl); + regs_src[0x07] = &state.a; + + state.flags.cy = 1; + state.flags.n = 1; + state.flags.ac = 1; + state.flags.z = 1; + + /* flags shortcut */ + state.f = (uint8_t *) &state.flags; + + /* flags mask array */ + z80_calc_flags_mask_array(); + + return &state; +} diff --git a/waterbox/pizza/lib/z80_gameboy_regs.h b/waterbox/pizza/lib/z80_gameboy_regs.h new file mode 100644 index 0000000000..6b403005f1 --- /dev/null +++ b/waterbox/pizza/lib/z80_gameboy_regs.h @@ -0,0 +1,48 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + + +#ifndef Z80_REGS_H +#define Z80_REGS_H + +#include + +/* structs emulating z80 registers and flags */ +typedef struct z80_flags_s +{ + uint8_t spare:4; + uint8_t cy:1; + uint8_t ac:1; + uint8_t n:1; + uint8_t z:1; +} z80_flags_t; + + +/* flags offsets */ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + + #define FLAG_OFFSET_CY 4 + #define FLAG_OFFSET_AC 5 + #define FLAG_OFFSET_N 6 + #define FLAG_OFFSET_Z 7 + +#endif + + +#endif diff --git a/waterbox/pizza/pizza.c b/waterbox/pizza/pizza.c new file mode 100644 index 0000000000..70f6083146 --- /dev/null +++ b/waterbox/pizza/pizza.c @@ -0,0 +1,194 @@ +/* + + This file is part of Emu-Pizza + + Emu-Pizza is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Emu-Pizza is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Emu-Pizza. If not, see . + +*/ + +#include +#include +#include +#include "../emulibc/emulibc.h" +#include "../emulibc/waterboxcore.h" +#include + +#define EXPORT ECL_EXPORT + +#include "cartridge.h" +#include "cycles.h" +#include "gameboy.h" +#include "global.h" +#include "gpu.h" +#include "input.h" +#include "sound.h" +#include "serial.h" +#include "utils.h" +#include "mmu.h" +#include "sound_output.h" +#include "sgb.h" + +/* proto */ +void frame_cb(); +void connected_cb(); +void disconnected_cb(); +void rumble_cb(uint8_t rumble); +void network_send_data(uint8_t v); +void *start_thread(void *args); +void *start_thread_network(void *args); + +/* cartridge name */ +char cart_name[64]; + +int main(void) +{ +} + +EXPORT int Init(const void *rom, int romlen, int sgb, const void *spc, int spclen) +{ + /* init global variables */ + global_init(); + + /* first, load cartridge */ + char ret = cartridge_load(rom, romlen); + + if (ret != 0) + return 0; // failure + global_sgb = !!sgb; + if (global_sgb && global_cgb) + utils_log("Warn: CGB game in SGB mode"); + if (sgb && !sgb_init((const uint8_t*)spc, spclen)) + return 0; + + gameboy_init(); + + /* init GPU */ + gpu_init(frame_cb); + + /* set rumble cb */ + mmu_set_rumble_cb(&rumble_cb); + + sound_output_init(global_sgb ? 2147727 : 2097152, 44100); + + return 1; +} + +typedef struct +{ + uint32_t *VideoBuffer; + int16_t *SoundBuffer; + int64_t Cycles; + int32_t Width; + int32_t Height; + int32_t Samples; + int32_t Lagged; + int64_t Time; + uint32_t Keys; +} MyFrameInfo; + +static uint32_t *current_vbuff; +static uint64_t overflow; + +EXPORT void FrameAdvance(MyFrameInfo *frame) +{ + if (global_sgb) + sgb_set_controller_data((uint8_t *)&frame->Keys); + else + input_set_keys(frame->Keys); + current_vbuff = frame->VideoBuffer; + global_lagged = 1; + global_currenttime = frame->Time; + + uint64_t current = cycles.sampleclock; + uint64_t target = current + 35112 - overflow; + gameboy_run(target); + uint64_t elapsed = cycles.sampleclock - current; + frame->Cycles = elapsed; + overflow = cycles.sampleclock - target; + + frame->Samples = sound_output_read(frame->SoundBuffer); + if (global_sgb) + { + frame->Width = 256; + frame->Height = 224; + } + else + { + frame->Width = 160; + frame->Height = 144; + } + frame->Lagged = global_lagged; + current_vbuff = NULL; +} + +EXPORT int IsCGB(void) +{ + return global_cgb; +} + +EXPORT void SetInputCallback(void (*callback)(void)) +{ + global_input_callback = callback; +} + +EXPORT void GetMemoryAreas(MemoryArea *m) +{ + m[0].Data = mmu.memory; + m[0].Name = "Fake System Bus"; + m[0].Size = 0x10000; + m[0].Flags = MEMORYAREA_FLAGS_PRIMARY | MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE1; +} + +EXPORT int GetSaveramSize(void) +{ + return mmu_saveram_size(); +} + +EXPORT void PutSaveram(const uint8_t* data, int size) +{ + mmu_restore_saveram(data, size); +} + +EXPORT void GetSaveram(uint8_t* data, int size) +{ + mmu_save_saveram(data, size); +} + +void frame_cb() +{ + if (global_sgb) + { + sgb_render_frame(current_vbuff); + } + else + { + memcpy(current_vbuff, gpu.frame_buffer, sizeof(gpu.frame_buffer)); + } +} + +void connected_cb() +{ + utils_log("Connected\n"); +} + +void disconnected_cb() +{ + utils_log("Disconnected\n"); +} + +void rumble_cb(uint8_t rumble) +{ + if (rumble) + printf("RUMBLE\n"); +} diff --git a/waterbox/readme.txt b/waterbox/readme.txt index eaa944fb2b..caddbd4343 100644 --- a/waterbox/readme.txt +++ b/waterbox/readme.txt @@ -1,25 +1,12 @@ This is the experimental "waterbox" project for bizhawk. -Build has been tested only on a recent Debian, but many Linuxes will probably work. amd64 is the only supported platform. -libc: This is pdclib, with the jam makesystem butchered and replaced by a custom Makefile, and some things removed. -libm from musl is added. sjlj from newlib is added. +libc.so, libgcc_s.so, libstdc++.so.6, and the waterbox executables are built with a modified verion of the midipix project. +The makefiles for the cores only support the cross compilation setup (build from whatever linux box you built midipix +from). -gpgx: This is more or less our current gpgx core. Not much has been changed. +The mmglue portion of the midipix project is modified; get the correct version from . + +gpgx: This is a modified version of our gpgx core +snes9x: Based off of snes9x 1.54. -To build: - -cd libc -make -cd ../gpgx -make - -Copy gpgx.elf to Bizhawk's output64\dll folder. - -Everything is still very much WIP. -Notes: -1. Remember ms-abi vs systemv! -2. gpgx codeblocks project isn't for building. -3. SJLJ might be busted. -4. VA_ARGS is probably busted. -5. STDIO isn't hooked up yet. diff --git a/waterbox/snes9x b/waterbox/snes9x new file mode 160000 index 0000000000..06a2bc83c9 --- /dev/null +++ b/waterbox/snes9x @@ -0,0 +1 @@ +Subproject commit 06a2bc83c9288c5efd5872d5d2e4b94f03d6e4b7 diff --git a/waterbox/ss/.vscode/settings.json b/waterbox/ss/.vscode/settings.json new file mode 100644 index 0000000000..218a94a620 --- /dev/null +++ b/waterbox/ss/.vscode/settings.json @@ -0,0 +1,51 @@ +{ + "files.associations": { + "iosfwd": "cpp", + "xstring": "cpp", + "xutility": "cpp", + "system_error": "cpp", + "xlocale": "cpp", + "*.inc": "cpp", + "algorithm": "cpp", + "array": "cpp", + "atomic": "cpp", + "bitset": "cpp", + "cmath": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "cwchar": "cpp", + "deque": "cpp", + "exception": "cpp", + "initializer_list": "cpp", + "ios": "cpp", + "istream": "cpp", + "iterator": "cpp", + "limits": "cpp", + "memory": "cpp", + "new": "cpp", + "ostream": "cpp", + "queue": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "string": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeinfo": "cpp", + "utility": "cpp", + "vector": "cpp", + "xfacet": "cpp", + "xiosbase": "cpp", + "xlocinfo": "cpp", + "xlocnum": "cpp", + "xmemory": "cpp", + "xmemory0": "cpp", + "xstddef": "cpp", + "xtr1common": "cpp" + }, + "editor.insertSpaces": false, + "editor.tabSize": 4, + "editor.detectIndentation": false +} \ No newline at end of file diff --git a/waterbox/ss/Makefile b/waterbox/ss/Makefile new file mode 100644 index 0000000000..9e3ee58d92 --- /dev/null +++ b/waterbox/ss/Makefile @@ -0,0 +1,44 @@ +CC = x86_64-nt64-midipix-g++ + +CCFLAGS:= -I. -I../emulibc \ + -Wall -Werror=pointer-to-int-cast -Werror=int-to-pointer-cast -Werror=implicit-function-declaration \ + -std=c++0x -fomit-frame-pointer -fvisibility=hidden -fno-exceptions -fno-rtti \ + -DLSB_FIRST \ + -O3 -flto + +TARGET = ss.wbx + +LDFLAGS = -Wl,--dynamicbase,--export-all-symbols + +ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) +SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.cpp') +OBJ_DIR:=$(ROOT_DIR)/obj + +_OBJS:=$(SRCS:.cpp=.o) +OBJS:=$(patsubst $(ROOT_DIR)%,$(OBJ_DIR)%,$(_OBJS)) + +$(OBJ_DIR)/%.o: %.cpp + @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) + +print-%: + @echo $* = $($*) + +#install: +# $(CP) $(TARGET) $(DEST_$(ARCH)) diff --git a/waterbox/ss/bizhawk.cpp b/waterbox/ss/bizhawk.cpp new file mode 100644 index 0000000000..a58898c1f9 --- /dev/null +++ b/waterbox/ss/bizhawk.cpp @@ -0,0 +1,328 @@ +#include "ss.h" +#include +#include "cdrom/cdromif.h" +#include "cdb.h" +#include "smpc.h" +#include "cart.h" +#include + +#define EXPORT extern "C" ECL_EXPORT +using namespace MDFN_IEN_SS; + +int32 (*FirmwareSizeCallback)(const char *filename); +void (*FirmwareDataCallback)(const char *filename, uint8 *dest); + +EXPORT void SetFirmwareCallbacks(int32 (*sizecallback)(const char *filename), void (*datacallback)(const char *filename, uint8 *dest)) +{ + FirmwareSizeCallback = sizecallback; + FirmwareDataCallback = datacallback; +} + +struct FrontendTOC +{ + int32 FirstTrack; + int32 LastTrack; + int32 DiskType; + struct + { + int32 Adr; + int32 Control; + int32 Lba; + int32 Valid; + } Tracks[101]; +}; + +static void (*ReadTOCCallback)(int disk, FrontendTOC *dest); +static void (*ReadSector2448Callback)(int disk, int lba, uint8 *dest); + +EXPORT void SetCDCallbacks(void (*toccallback)(int disk, FrontendTOC *dest), void (*sectorcallback)(int disk, int lba, uint8 *dest)) +{ + ReadTOCCallback = toccallback; + ReadSector2448Callback = sectorcallback; +} + +class MyCDIF : public CDIF +{ + private: + int disk; + + public: + MyCDIF(int disk) : disk(disk) + { + FrontendTOC t; + ReadTOCCallback(disk, &t); + disc_toc.first_track = t.FirstTrack; + disc_toc.last_track = t.LastTrack; + disc_toc.disc_type = t.DiskType; + for (int i = 0; i < 101; i++) + { + disc_toc.tracks[i].adr = t.Tracks[i].Adr; + disc_toc.tracks[i].control = t.Tracks[i].Control; + disc_toc.tracks[i].lba = t.Tracks[i].Lba; + disc_toc.tracks[i].valid = t.Tracks[i].Valid; + } + } + + virtual void HintReadSector(int32 lba) {} + virtual bool ReadRawSector(uint8 *buf, int32 lba) + { + ReadSector2448Callback(disk, lba, buf); + return true; + } + virtual bool ReadRawSectorPWOnly(uint8 *pwbuf, int32 lba, bool hint_fullread) + { + uint8 buff[2448]; + ReadSector2448Callback(disk, lba, buff); + memcpy(pwbuf, buff + 2352, 96); + return true; + } +}; + +static std::vector CDInterfaces; +static uint32 *FrameBuffer; +static uint8 IsResetPushed; // 1 or 0 + +namespace MDFN_IEN_SS +{ +extern bool LoadCD(std::vector *CDInterfaces); +} +EXPORT bool Init(int numDisks, int cartType, int regionDefault, int regionAutodetect) +{ + setting_ss_cart = cartType; + setting_ss_region_autodetect = regionAutodetect; + setting_ss_region_default = regionDefault; + + FrameBuffer = (uint32 *)alloc_invisible(1024 * 1024 * sizeof(*FrameBuffer)); + for (int i = 0; i < numDisks; i++) + CDInterfaces.push_back(new MyCDIF(i)); + auto ret = LoadCD(&CDInterfaces); + if (ret) + SMPC_SetInput(12, nullptr, &IsResetPushed); + return ret; +} + +EXPORT void HardReset() +{ + // soft reset is handled as a normal button + SS_Reset(true); +} + +EXPORT void SetDisk(int disk, bool open) +{ + CDB_SetDisc(open, disk < 0 ? nullptr : CDInterfaces[disk]); +} + +int setting_ss_slstartp = 0; +int setting_ss_slendp = 255; +int setting_ss_slstart = 0; +int setting_ss_slend = 239; +int setting_ss_region_default = SMPC_AREA_JP; +int setting_ss_cart = CART_NONE; +bool setting_ss_correct_aspect = true; +bool setting_ss_h_blend = false; +bool setting_ss_h_overscan = true; +bool setting_ss_region_autodetect = true; +bool setting_ss_input_sport1_multitap = false; +bool setting_ss_input_sport0_multitap = false; + +namespace MDFN_IEN_SS +{ +extern void Emulate(EmulateSpecStruct *espec_arg); +} + +static uint8 ControllerInput[12 * 32]; +bool InputLagged; + +EXPORT void SetControllerData(const uint8_t* controllerData) +{ + memcpy(ControllerInput, controllerData, sizeof(ControllerInput)); +} + +struct MyFrameInfo: public FrameInfo +{ + int32_t ResetPushed; +}; + +EXPORT void FrameAdvance(MyFrameInfo& f) +{ + EmulateSpecStruct e; + int32 LineWidths[1024]; + memset(LineWidths, 0, sizeof(LineWidths)); + e.pixels = FrameBuffer; + e.pitch32 = 1024; + e.LineWidths = LineWidths; + e.SoundBuf = f.SoundBuffer; + e.SoundBufMaxSize = 8192; + IsResetPushed = f.ResetPushed; + InputLagged = true; + Emulate(&e); + f.Samples = e.SoundBufSize; + f.Cycles = e.MasterCycles; + f.Lagged = InputLagged; + + int w = 256; + for (int i = 0; i < e.h; i++) + w = std::max(w, LineWidths[i]); + + const uint32 *src = FrameBuffer; + uint32 *dst = f.VideoBuffer; + const int srcp = 1024; + const int dstp = w; + src += e.y * srcp + e.x; + + for (int j = 0; j < e.h; j++, src += srcp, dst += dstp) + { + memcpy(dst, src, LineWidths[j + e.y] * sizeof(*dst)); + } + f.Width = w; + f.Height = e.h; +} + +static const char *DeviceNames[] = + { + "none", + "gamepad", + "3dpad", + "mouse", + "wheel", + "mission", + "dmission", + "keyboard"}; + +EXPORT void SetupInput(const int *portdevices, const int *multitaps) +{ + for (int i = 0; i < 2; i++) + SMPC_SetMultitap(i, multitaps[i]); + for (int i = 0; i < 12; i++) + SMPC_SetInput(i, DeviceNames[portdevices[i]], ControllerInput + i * 32); +} + +void (*InputCallback)(); +EXPORT void SetInputCallback(void (*callback)()) +{ + InputCallback = callback; +} + +static std::vector MemoryAreas; + +void AddMemoryDomain(const char *name, const void *ptr, int size, int flags) +{ + MemoryArea m; + m.Data = (void*)ptr; + m.Name = name; + m.Size = size; + m.Flags = flags; + MemoryAreas.push_back(m); +} + +EXPORT void GetMemoryAreas(MemoryArea* m) +{ + memcpy(m, MemoryAreas.data(), MemoryAreas.size() * sizeof(MemoryArea)); +} + +EXPORT void SetRtc(int64 ticks, int language) +{ + time_t time = ticks; + const struct tm *tm = gmtime(&time); + SMPC_SetRTC(tm, language); +} + +namespace MDFN_IEN_SS +{ +extern bool CorrectAspect; +extern bool ShowHOverscan; +extern bool DoHBlend; +extern int LineVisFirst; +extern int LineVisLast; +} +EXPORT void SetVideoParameters(bool correctAspect, bool hBlend, bool hOverscan, int sls, int sle) +{ + CorrectAspect = correctAspect; + ShowHOverscan = hOverscan; + DoHBlend = hBlend; + LineVisFirst = sls; + LineVisLast = sle; +} + +// if (BackupRAM_Dirty)SaveBackupRAM(); +// if (CART_GetClearNVDirty())SaveCartNV(); + +/*static MDFN_COLD void CloseGame(void) +{ + try { SaveBackupRAM(); } catch(std::exception& e) { MDFN_PrintError("%s", e.what()); } + try { SaveCartNV(); } catch(std::exception& e) { MDFN_PrintError("%s", e.what()); } + try { SaveRTC(); } catch(std::exception& e) { MDFN_PrintError("%s", e.what()); } + + Cleanup(); +}*/ + +/* + +static MDFN_COLD void BackupCartNV(void) +{ + const char* ext = nullptr; + void* nv_ptr = nullptr; + uint64 nv_size = 0; + + CART_GetNVInfo(&ext, &nv_ptr, &nv_size); + + if(ext) + MDFN_BackupSavFile(10, ext); +}*/ + +/*static MDFN_COLD void LoadCartNV(void) +{ + const char* ext = nullptr; + void* nv_ptr = nullptr; + uint64 nv_size = 0; + + CART_GetNVInfo(&ext, &nv_ptr, &nv_size); + + if(ext) + { + //FileStream nvs(MDFN_MakeFName(MDFNMKF_SAV, 0, ext), FileStream::MODE_READ); + GZFileStream nvs(MDFN_MakeFName(MDFNMKF_SAV, 0, ext), GZFileStream::MODE::READ); + + nvs.read(nv_ptr, nv_size); + } +} + +static MDFN_COLD void SaveCartNV(void) +{ + const char* ext = nullptr; + void* nv_ptr = nullptr; + uint64 nv_size = 0; + + CART_GetNVInfo(&ext, &nv_ptr, &nv_size); + + if(ext) + { + //FileStream nvs(MDFN_MakeFName(MDFNMKF_SAV, 0, ext), FileStream::MODE_WRITE_INPLACE); + GZFileStream nvs(MDFN_MakeFName(MDFNMKF_SAV, 0, ext), GZFileStream::MODE::WRITE); + + nvs.write(nv_ptr, nv_size); + + nvs.close(); + } +}*/ + +/*static MDFN_COLD void SaveRTC(void) +{ + FileStream sds(MDFN_MakeFName(MDFNMKF_SAV, 0, "smpc"), FileStream::MODE_WRITE_INPLACE); + + SMPC_SaveNV(&sds); + + sds.close(); +} + +static MDFN_COLD void LoadRTC(void) +{ + FileStream sds(MDFN_MakeFName(MDFNMKF_SAV, 0, "smpc"), FileStream::MODE_READ); + + SMPC_LoadNV(&sds); +}*/ + +int main() +{ + return 0; +} diff --git a/waterbox/ss/cart.cpp b/waterbox/ss/cart.cpp new file mode 100644 index 0000000000..f2ee5519b9 --- /dev/null +++ b/waterbox/ss/cart.cpp @@ -0,0 +1,171 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* cart.cpp - Expansion cart emulation +** Copyright (C) 2016-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "ss.h" + +#include "cart.h" +#include "cart/backup.h" +#include "cart/cs1ram.h" +#include "cart/debug.h" +#include "cart/extram.h" +//#include "cart/nlmodem.h" +#include "cart/rom.h" + +namespace MDFN_IEN_SS +{ + +CartInfo Cart; + +template +static MDFN_HOT void DummyRead(uint32 A, uint16* DB) +{ + // Don't set *DB here. + SS_DBG(SS_DBG_WARNING, "[CART] Unknown %zu-byte read from 0x%08x\n", sizeof(T), A); +} + +template +static MDFN_HOT void DummyWrite(uint32 A, uint16* DB) +{ + SS_DBG(SS_DBG_WARNING, "[CART] Unknown %zu-byte write to 0x%08x(DB=0x%04x)\n", sizeof(T), A, *DB); +} + +static sscpu_timestamp_t DummyUpdate(sscpu_timestamp_t timestamp) +{ + return SS_EVENT_DISABLED_TS; +} + +static void DummyAdjustTS(const int32 delta) +{ + +} + +static void DummySetCPUClock(const int32 master_clock, const int32 divider) +{ + +} + +static MDFN_COLD void DummyReset(bool powering_up) +{ + +} + +static MDFN_COLD bool DummyGetClearNVDirty(void) +{ + return false; +} + +static MDFN_COLD void DummyGetNVInfo(const char** ext, void** nv_ptr, uint64* nv_size) +{ + *ext = nullptr; + *nv_ptr = nullptr; + *nv_size = 0; +} + +void CartInfo::CS01_SetRW8W16(uint32 Astart, uint32 Aend, void (*r16)(uint32 A, uint16* DB), void (*w8)(uint32 A, uint16* DB), void (*w16)(uint32 A, uint16* DB)) +{ + assert(Astart >= 0x02000000 && Aend <= 0x04FFFFFF); + + assert(!(Astart & ((1U << 20) - 1))); + assert(!((Aend + 1) & ((1U << 20) - 1))); + + for(unsigned i = (Astart - 0x02000000) >> 20; i <= (Aend - 0x02000000) >> 20; i++) + { + auto& rw = Cart.CS01_RW[i]; + + if(r16) rw.Read16 = r16; + if(w8) rw.Write8 = w8; + if(w16) rw.Write16 = w16; + } +} + +void CartInfo::CS2M_SetRW8W16(uint8 Ostart, uint8 Oend, void (*r16)(uint32 A, uint16* DB), void (*w8)(uint32 A, uint16* DB), void (*w16)(uint32 A, uint16* DB)) +{ + assert(!(Ostart & 0x1)); + assert(Oend & 0x1); + assert(Ostart < 0x40); + assert(Oend < 0x40); + + for(int i = Ostart >> 1; i <= Oend >> 1; i++) + { + auto& rw = Cart.CS2M_RW[i]; + + if(r16) rw.Read16 = r16; + if(w8) rw.Write8 = w8; + if(w16) rw.Write16 = w16; + } +} + + +void CART_Init(const int cart_type) +{ + Cart.CS01_SetRW8W16(0x02000000, 0x04FFFFFF, DummyRead, DummyWrite, DummyWrite); + Cart.CS2M_SetRW8W16(0x00, 0x3F, DummyRead, DummyWrite, DummyWrite); + + Cart.Reset = DummyReset; + Cart.GetNVInfo = DummyGetNVInfo; + Cart.GetClearNVDirty = DummyGetClearNVDirty; + Cart.EventHandler = DummyUpdate; + Cart.AdjustTS = DummyAdjustTS; + Cart.SetCPUClock = DummySetCPUClock; + + switch(cart_type) + { + default: + case CART_NONE: + break; + + case CART_BACKUP_MEM: + CART_Backup_Init(&Cart); + break; + + case CART_EXTRAM_1M: + case CART_EXTRAM_4M: + CART_ExtRAM_Init(&Cart, cart_type == CART_EXTRAM_4M); + break; + + case CART_KOF95: + case CART_ULTRAMAN: + { + CART_ROM_Init(&Cart, cart_type == CART_KOF95 ? "ss.cart.kof95_path" : "ss.cart.ultraman_path"); + } + break; + + case CART_CS1RAM_16M: + CART_CS1RAM_Init(&Cart); + break; + + case CART_MDFN_DEBUG: + CART_Debug_Init(&Cart); + break; + +// case CART_NLMODEM: +// CART_NLModem_Init(&Cart); +// break; + } + + for(auto& m : Cart.CS01_RW) + assert(m.Read16 != nullptr && m.Write8 != nullptr && m.Write16 != nullptr); + + for(auto& m : Cart.CS2M_RW) + assert(m.Read16 != nullptr && m.Write8 != nullptr && m.Write16 != nullptr); +} + +} diff --git a/waterbox/ss/cart.h b/waterbox/ss/cart.h new file mode 100644 index 0000000000..985e467499 --- /dev/null +++ b/waterbox/ss/cart.h @@ -0,0 +1,95 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* cart.h - Expansion cart emulation +** Copyright (C) 2016-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_CART_H +#define __MDFN_SS_CART_H + +namespace MDFN_IEN_SS +{ + +struct CartInfo +{ + void (*Reset)(bool powering_up); + + void (*GetNVInfo)(const char** ext, void** nv_ptr, uint64* nv_size); + bool (*GetClearNVDirty)(void); + + void (*AdjustTS)(const int32 delta); + + // For calculating clock ratios. + void (*SetCPUClock)(const int32 master_clock, const int32 cpu_divider); + + ss_event_handler EventHandler; + + // A >> 20 + struct + { + void (*Read16)(uint32 A, uint16* DB); + void (*Write8)(uint32 A, uint16* DB); + void (*Write16)(uint32 A, uint16* DB); + } CS01_RW[0x30]; + + struct + { + void (*Read16)(uint32 A, uint16* DB); + void (*Write8)(uint32 A, uint16* DB); + void (*Write16)(uint32 A, uint16* DB); + } CS2M_RW[0x20]; + + void CS01_SetRW8W16(uint32 Astart, uint32 Aend, void (*r16)(uint32 A, uint16* DB), void (*w8)(uint32 A, uint16* DB) = nullptr, void (*w16)(uint32 A, uint16* DB) = nullptr); + void CS2M_SetRW8W16(uint8 Ostart, uint8 Oend, void (*r16)(uint32 A, uint16* DB), void (*w8)(uint32 A, uint16* DB) = nullptr, void (*w16)(uint32 A, uint16* DB) = nullptr); +}; + +static INLINE void CART_CS01_Read16_DB(uint32 A, uint16* DB) { extern CartInfo Cart; Cart.CS01_RW[(size_t)(A >> 20) - (0x02000000 >> 20)].Read16 (A, DB); } +static INLINE void CART_CS01_Write8_DB(uint32 A, uint16* DB) { extern CartInfo Cart; Cart.CS01_RW[(size_t)(A >> 20) - (0x02000000 >> 20)].Write8 (A, DB); } +static INLINE void CART_CS01_Write16_DB(uint32 A, uint16* DB) { extern CartInfo Cart; Cart.CS01_RW[(size_t)(A >> 20) - (0x02000000 >> 20)].Write16(A, DB); } + +static INLINE void CART_CS2_Read16_DB(uint32 A, uint16* DB) { extern CartInfo Cart; Cart.CS2M_RW[(A >> 1) & 0x1F].Read16 (A, DB); } +static INLINE void CART_CS2_Write8_DB(uint32 A, uint16* DB) { extern CartInfo Cart; Cart.CS2M_RW[(A >> 1) & 0x1F].Write8 (A, DB); } +static INLINE void CART_CS2_Write16_DB(uint32 A, uint16* DB) { extern CartInfo Cart; Cart.CS2M_RW[(A >> 1) & 0x1F].Write16(A, DB); } + +enum +{ + CART__RESERVED = -1, + CART_NONE = 0, + CART_BACKUP_MEM, + CART_EXTRAM_1M, + CART_EXTRAM_4M, + + CART_KOF95, + CART_ULTRAMAN, + + CART_CS1RAM_16M, + + CART_NLMODEM, + + CART_MDFN_DEBUG +}; + +void CART_Init(const int cart_type) MDFN_COLD; +static INLINE ss_event_handler CART_GetEventHandler(void) { extern CartInfo Cart; return Cart.EventHandler; } +static INLINE void CART_AdjustTS(const int32 delta) { extern CartInfo Cart; Cart.AdjustTS(delta); } +static INLINE void CART_SetCPUClock(const int32 master_clock, const int32 cpu_divider) { extern CartInfo Cart; Cart.SetCPUClock(master_clock, cpu_divider); } +static INLINE void CART_GetNVInfo(const char** ext, void** nv_ptr, uint64* nv_size) { extern CartInfo Cart; Cart.GetNVInfo(ext, nv_ptr, nv_size); } +static INLINE bool CART_GetClearNVDirty(void) { extern CartInfo Cart; return Cart.GetClearNVDirty(); } +static INLINE void CART_Reset(bool powering_up) { extern CartInfo Cart; Cart.Reset(powering_up); } +} +#endif diff --git a/waterbox/ss/cart/backup.cpp b/waterbox/ss/cart/backup.cpp new file mode 100644 index 0000000000..bab8a23c64 --- /dev/null +++ b/waterbox/ss/cart/backup.cpp @@ -0,0 +1,91 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* backup.cpp - Backup memory(512KiB) cart emulation +** Copyright (C) 2016-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "common.h" +#include "backup.h" + +namespace MDFN_IEN_SS +{ + +static uint8 *ExtBackupRAM; +static bool ExtBackupRAM_Dirty; + +// TODO: Check mirroring. +template +static MDFN_HOT void ExtBackupRAM_RW_DB(uint32 A, uint16 *DB) +{ + uint8 *const ptr = ExtBackupRAM + ((A >> 1) & 0x7FFFF); + + if (IsWrite) + { + if (A & 1) + { + ExtBackupRAM_Dirty = true; + *ptr = *DB; + } + } + else + { + *DB = (*ptr << 0) | 0xFF00; + + if ((A & ~1) == 0x04FFFFFE) + *DB = 0x21; + } +} + +static MDFN_COLD bool GetClearNVDirty(void) +{ + bool ret = ExtBackupRAM_Dirty; + + ExtBackupRAM_Dirty = false; + + return ret; +} + +static MDFN_COLD void GetNVInfo(const char **ext, void **nv_ptr, uint64 *nv_size) +{ + *ext = "bcr"; + *nv_ptr = ExtBackupRAM; + *nv_size = 524288; +} + +void CART_Backup_Init(CartInfo *c) +{ + static const uint8 init[0x10] = {0x42, 0x61, 0x63, 0x6B, 0x55, 0x70, 0x52, 0x61, 0x6D, 0x20, 0x46, 0x6F, 0x72, 0x6D, 0x61, 0x74}; + + ExtBackupRAM = (uint8 *)alloc_plain(524288); + memset(ExtBackupRAM, 0x00, 524288); + for (unsigned i = 0; i < 0x200; i += 0x10) + memcpy(ExtBackupRAM + i, init, 0x10); + + ExtBackupRAM_Dirty = false; + + c->CS01_SetRW8W16(0x04000000, 0x04FFFFFF, + ExtBackupRAM_RW_DB, + ExtBackupRAM_RW_DB, + ExtBackupRAM_RW_DB); + + c->GetClearNVDirty = GetClearNVDirty; + c->GetNVInfo = GetNVInfo; + + AddMemoryDomain("Backup Cart", ExtBackupRAM, 524288, MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_SAVERAMMABLE | MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_WORDSIZE2); +} +} diff --git a/waterbox/ss/cart/backup.h b/waterbox/ss/cart/backup.h new file mode 100644 index 0000000000..7d7946f871 --- /dev/null +++ b/waterbox/ss/cart/backup.h @@ -0,0 +1,30 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* backup.h - Backup memory(512KiB) cart emulation +** Copyright (C) 2016-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_CART_BACKUP_H +#define __MDFN_SS_CART_BACKUP_H + +namespace MDFN_IEN_SS +{ +void CART_Backup_Init(CartInfo* c) MDFN_COLD; +} + +#endif diff --git a/waterbox/ss/cart/common.h b/waterbox/ss/cart/common.h new file mode 100644 index 0000000000..5b2961eb74 --- /dev/null +++ b/waterbox/ss/cart/common.h @@ -0,0 +1,3 @@ +#include "../ss.h" +#include "../cart.h" + diff --git a/waterbox/ss/cart/cs1ram.cpp b/waterbox/ss/cart/cs1ram.cpp new file mode 100644 index 0000000000..75ea7a4b29 --- /dev/null +++ b/waterbox/ss/cart/cs1ram.cpp @@ -0,0 +1,60 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* cs1ram.cpp - CS1 RAM(16MiB) cart emulation +** Copyright (C) 2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "common.h" +#include "cs1ram.h" + +namespace MDFN_IEN_SS +{ +static uint16 *CS1RAM = nullptr; + +template +static MDFN_HOT void CS1RAM_RW_DB(uint32 A, uint16 *DB) +{ + const uint32 mask = (sizeof(T) == 2) ? 0xFFFF : (0xFF << (((A & 1) ^ 1) << 3)); + uint16 *const ptr = (uint16 *)((uint8 *)CS1RAM + (A & 0x00FFFFFE)); + + if (IsWrite) + *ptr = (*ptr & ~mask) | (*DB & mask); + else + *DB = *ptr; +} + +static MDFN_COLD void Reset(bool powering_up) +{ + if (powering_up) + memset(CS1RAM, 0, 0x1000000); +} + +void CART_CS1RAM_Init(CartInfo *c) +{ + CS1RAM = (uint16 *)alloc_plain(0x1000000); + + SS_SetPhysMemMap(0x04000000, 0x04FFFFFF, CS1RAM, 0x1000000, true); + c->CS01_SetRW8W16(0x04000000, 0x04FFFFFF, + CS1RAM_RW_DB, + CS1RAM_RW_DB, + CS1RAM_RW_DB); + + c->Reset = Reset; + AddMemoryDomain("CS1 Cart", CS1RAM, 0x1000000, MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_WORDSIZE2); +} +} diff --git a/waterbox/ss/cart/cs1ram.h b/waterbox/ss/cart/cs1ram.h new file mode 100644 index 0000000000..56f06cab25 --- /dev/null +++ b/waterbox/ss/cart/cs1ram.h @@ -0,0 +1,30 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* cs1ram.h - CS1 RAM(16MiB) cart emulation +** Copyright (C) 2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_CART_CS1RAM_H +#define __MDFN_SS_CART_CS1RAM_H + +namespace MDFN_IEN_SS +{ +void CART_CS1RAM_Init(CartInfo* c) MDFN_COLD; +} + +#endif diff --git a/waterbox/ss/cart/debug.cpp b/waterbox/ss/cart/debug.cpp new file mode 100644 index 0000000000..37b169e4e0 --- /dev/null +++ b/waterbox/ss/cart/debug.cpp @@ -0,0 +1,60 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* debug.cpp - Mednafen debug cart emulation +** Copyright (C) 2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "common.h" +#include "debug.h" + +namespace MDFN_IEN_SS +{ + +template +static void Debug_RW_DB(uint32 A, uint16* DB) +{ + // + // printf-related debugging + // + if((A &~ 0x3) == 0x02100000) + { + if(IsWrite) + { + if(A == 0x02100001) + { + fputc(*DB, stderr); + fflush(stderr); + } + } + else + *DB = 0; + + return; + } +} + + +void CART_Debug_Init(CartInfo* c) +{ + c->CS01_SetRW8W16(0x02100000, /*0x02100001*/ 0x021FFFFF, + Debug_RW_DB, + Debug_RW_DB, + Debug_RW_DB); +} + +} diff --git a/waterbox/ss/cart/debug.h b/waterbox/ss/cart/debug.h new file mode 100644 index 0000000000..0413b85a60 --- /dev/null +++ b/waterbox/ss/cart/debug.h @@ -0,0 +1,30 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* debug.h - Mednafen debug cart emulation +** Copyright (C) 2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_CART_DEBUG_H +#define __MDFN_SS_CART_DEBUG_H + +namespace MDFN_IEN_SS +{ +void CART_Debug_Init(CartInfo* c) MDFN_COLD; +} + +#endif diff --git a/waterbox/ss/cart/extram.cpp b/waterbox/ss/cart/extram.cpp new file mode 100644 index 0000000000..5761ad15e4 --- /dev/null +++ b/waterbox/ss/cart/extram.cpp @@ -0,0 +1,84 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* extram.cpp - Extended RAM(1MiB and 4MiB) cart emulation +** Copyright (C) 2016-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "common.h" +#include "extram.h" + +namespace MDFN_IEN_SS +{ +static uint16 *ExtRAM; //[0x200000]; +static size_t ExtRAM_Mask; +static uint8 Cart_ID; + +template +static MDFN_HOT void ExtRAM_RW_DB(uint32 A, uint16 *DB) +{ + const uint32 mask = (sizeof(T) == 2) ? 0xFFFF : (0xFF << (((A & 1) ^ 1) << 3)); + uint16 *const ptr = (uint16 *)((uint8 *)ExtRAM + (A & ExtRAM_Mask)); + + //printf("Barf %zu %d: %08x\n", sizeof(T), IsWrite, A); + + if (IsWrite) + *ptr = (*ptr & ~mask) | (*DB & mask); + else + *DB = *ptr; +} + +static MDFN_HOT void CartID_Read_DB(uint32 A, uint16 *DB) +{ + if ((A & ~1) == 0x04FFFFFE) + *DB = Cart_ID; +} + +static MDFN_COLD void Reset(bool powering_up) +{ + if (powering_up) + memset(ExtRAM, 0, 0x400000); // TODO: Test. +} + +void CART_ExtRAM_Init(CartInfo *c, bool R4MiB) +{ + ExtRAM = (uint16 *)alloc_plain(0x400000); + if (R4MiB) + { + Cart_ID = 0x5C; + ExtRAM_Mask = 0x3FFFFE; + } + else + { + Cart_ID = 0x5A; + ExtRAM_Mask = 0x27FFFE; + } + + SS_SetPhysMemMap(0x02400000, 0x025FFFFF, ExtRAM + (0x000000 / sizeof(uint16)), (R4MiB ? 0x200000 : 0x080000), true); + SS_SetPhysMemMap(0x02600000, 0x027FFFFF, ExtRAM + (0x200000 / sizeof(uint16)), (R4MiB ? 0x200000 : 0x080000), true); + + c->CS01_SetRW8W16(0x02400000, 0x027FFFFF, + ExtRAM_RW_DB, + ExtRAM_RW_DB, + ExtRAM_RW_DB); + + c->CS01_SetRW8W16(/*0x04FFFFFE*/ 0x04F00000, 0x04FFFFFF, CartID_Read_DB); + + c->Reset = Reset; + AddMemoryDomain("Ram Cart", ExtRAM, 0x400000, MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_WORDSIZE2); +} +} diff --git a/waterbox/ss/cart/extram.h b/waterbox/ss/cart/extram.h new file mode 100644 index 0000000000..c63287b0ae --- /dev/null +++ b/waterbox/ss/cart/extram.h @@ -0,0 +1,30 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* extram.h - Extended RAM(1MiB and 4MiB) cart emulation +** Copyright (C) 2016-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_CART_EXTRAM_H +#define __MDFN_SS_CART_EXTRAM_H + +namespace MDFN_IEN_SS +{ +void CART_ExtRAM_Init(CartInfo* c, bool R4MiB) MDFN_COLD; +} + +#endif diff --git a/waterbox/ss/cart/rom.cpp b/waterbox/ss/cart/rom.cpp new file mode 100644 index 0000000000..f4d07817e3 --- /dev/null +++ b/waterbox/ss/cart/rom.cpp @@ -0,0 +1,53 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* rom.cpp - ROM cart emulation +** Copyright (C) 2016-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "common.h" +#include "rom.h" + +namespace MDFN_IEN_SS +{ + +static uint16 *ROM; //[0x100000]; + +static MDFN_HOT void ROM_Read(uint32 A, uint16 *DB) +{ + // TODO: Check mirroring. + //printf("ROM: %08x\n", A); + *DB = *(uint16 *)((uint8 *)ROM + (A & 0x1FFFFE)); +} + +void CART_ROM_Init(CartInfo *c, const char *filename) +{ + if (FirmwareSizeCallback(filename) != 0x200000) + abort(); + ROM = (uint16 *)alloc_sealed(0x200000); + FirmwareDataCallback(filename, (uint8 *)ROM); + + for (unsigned i = 0; i < 0x100000; i++) + { + ROM[i] = MDFN_de16msb(&ROM[i]); + } + + SS_SetPhysMemMap(0x02000000, 0x03FFFFFF, ROM, 0x200000, false); + c->CS01_SetRW8W16(0x02000000, 0x03FFFFFF, ROM_Read); + AddMemoryDomain("Rom Cart", ROM, 0x200000, MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_WORDSIZE2); +} +} diff --git a/waterbox/ss/cart/rom.h b/waterbox/ss/cart/rom.h new file mode 100644 index 0000000000..3d4a393658 --- /dev/null +++ b/waterbox/ss/cart/rom.h @@ -0,0 +1,30 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* rom.h - ROM cart emulation +** Copyright (C) 2016-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_CART_ROM_H +#define __MDFN_SS_CART_ROM_H + +namespace MDFN_IEN_SS +{ +void CART_ROM_Init(CartInfo* c, const char* filename) MDFN_COLD; +} + +#endif diff --git a/waterbox/ss/cdb.cpp b/waterbox/ss/cdb.cpp new file mode 100644 index 0000000000..ee3ab3496a --- /dev/null +++ b/waterbox/ss/cdb.cpp @@ -0,0 +1,3630 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* cdb.cpp - CD Block Emulation +** Copyright (C) 2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +// TODO: Respect auth type with COMMAND_AUTH_DEVICE. + +// TODO: Test INIT 0x00 side effects(and see if it affects CD device connection) + +// TODO: edc_lec_check_and_correct + +// TODO: Proper seek delays(for "Gungriffon" FMV) + +// TODO: Some filesys commands(at least change dir, read file) seem to reset the saved command start and end positions(accessed via 0xFFFFFF to PLAY command) to something +// akin to 0. + +// TODO: SMPC CD off/on + +// TODO: Consider serializing HIRQ_PEND and HIRQ_SCDQ with command execution. + +// TODO: Look into weird issue where WAIT status for Change Dir might be set to 1 slightly after CMOK IRQ is triggered... + +// TODO: Test state reset on Init with SW reset. + +// TODO: Scan command. + +// TODO: assert()s + +// TODO: Reject all commands during disc startup? + +// TODO: for(unsigned i = 0; i < 5; i++) DT_ReadIntoFIFO(); + +// TODO: Auth and auth type. + +// TODO: Test play command while filesys op is in progress. + +#include "ss.h" +#include "scu.h" +#include "sound.h" + +#include "cdrom/CDUtility.h" +#include "cdrom/cdromif.h" +using namespace CDUtility; + +namespace MDFN_IEN_SS +{ + +enum +{ + SECLEN__FIRST = 0, + + SECLEN_2048 = 0, + SECLEN_2336 = 1, + SECLEN_2340 = 2, + SECLEN_2352 = 3, + + SECLEN__LAST = 3, +}; + +static uint8 GetSecLen, PutSecLen; + +static uint8 AuthDiscType; +enum +{ + COMMAND_GET_CDSTATUS = 0x00, + COMMAND_GET_HWINFO = 0x01, + COMMAND_GET_TOC = 0x02, + COMMAND_GET_SESSINFO = 0x03, + COMMAND_INIT = 0x04, + COMMAND_OPEN = 0x05, + COMMAND_END_DATAXFER = 0x06, + + COMMAND_PLAY = 0x10, + COMMAND_SEEK = 0x11, + COMMAND_SCAN = 0x12, + + COMMAND_GET_SUBCODE = 0x20, + + COMMAND_SET_CDDEVCONN = 0x30, + COMMAND_GET_CDDEVCONN = 0x31, + COMMAND_GET_LASTBUFDST = 0x32, + + COMMAND_SET_FILTRANGE = 0x40, + COMMAND_GET_FILTRANGE = 0x41, + COMMAND_SET_FILTSUBHC = 0x42, + COMMAND_GET_FILTSUBHC = 0x43, + COMMAND_SET_FILTMODE = 0x44, + COMMAND_GET_FILTMODE = 0x45, + COMMAND_SET_FILTCONN = 0x46, + COMMAND_GET_FILTCONN = 0x47, + COMMAND_RESET_SEL = 0x48, + + COMMAND_GET_BUFSIZE = 0x50, + COMMAND_GET_SECNUM = 0x51, + COMMAND_CALC_ACTSIZE = 0x52, + COMMAND_GET_ACTSIZE = 0x53, + COMMAND_GET_SECINFO = 0x54, + COMMAND_EXEC_FADSRCH = 0x55, + COMMAND_GET_FADSRCH = 0x56, + + COMMAND_SET_SECLEN = 0x60, + COMMAND_GET_SECDATA = 0x61, + COMMAND_DEL_SECDATA = 0x62, + COMMAND_GETDEL_SECDATA = 0x63, + COMMAND_PUT_SECDATA = 0x64, + COMMAND_COPY_SECDATA = 0x65, + COMMAND_MOVE_SECDATA = 0x66, + COMMAND_GET_COPYERR = 0x67, + + COMMAND_CHANGE_DIR = 0x70, + COMMAND_READ_DIR = 0x71, + COMMAND_GET_FSSCOPE = 0x72, + COMMAND_GET_FINFO = 0x73, + COMMAND_READ_FILE = 0x74, + COMMAND_ABORT_FILE = 0x75, + + COMMAND_AUTH_DEVICE = 0xE0, + COMMAND_GET_AUTH = 0xE1 +}; + +static MDFN_COLD void GetCommandDetails(const uint16* CD, char* s, size_t sl) +{ + switch(CD[0] >> 8) + { + default: + trio_snprintf(s, sl, "UNKNOWN: 0x%04x, 0x%04x, 0x%04x, 0x%04x", CD[0], CD[1], CD[2], CD[3]); + break; + + case COMMAND_GET_CDSTATUS: + trio_snprintf(s, sl, "Get CD Status"); + break; + + case COMMAND_GET_HWINFO: + trio_snprintf(s, sl, "Get Hardware Info"); + break; + + case COMMAND_GET_TOC: + trio_snprintf(s, sl, "Get TOC"); + break; + + case COMMAND_GET_SESSINFO: + trio_snprintf(s, sl, "Get Session Info; Type=0x%02x", CD[0] & 0xFF); + break; + + case COMMAND_INIT: + trio_snprintf(s, sl, "Initialize; Flags=0x%02x", CD[0] & 0xFF); + break; + + case COMMAND_OPEN: + trio_snprintf(s, sl, "Open Tray"); + break; + + case COMMAND_END_DATAXFER: + trio_snprintf(s, sl, "End Data Transfer"); + break; + + case COMMAND_PLAY: + trio_snprintf(s, sl, "Play; Start=0x%06x, End=0x%06x, Mode=0x%02x", ((CD[0] & 0xFF) << 16) | CD[1], ((CD[2] & 0xFF) << 16) | CD[3], CD[2] >> 8); + break; + + case COMMAND_SEEK: + // 0xFFFFFF=pause, 0=stop + trio_snprintf(s, sl, "Seek; Target=0x%06x", ((CD[0] & 0xFF) << 16) | CD[1]); + break; + + case COMMAND_SCAN: + trio_snprintf(s, sl, "Scan; Direction=0x%02x", CD[0] & 0xFF); + break; + + case COMMAND_GET_SUBCODE: + trio_snprintf(s, sl, "Get Subcode; Type=0x%02x", CD[0] & 0xFF); + break; + + case COMMAND_SET_CDDEVCONN: + trio_snprintf(s, sl, "Set CD Device Connection; Filter=0x%02x", CD[2] >> 8); + break; + + case COMMAND_GET_CDDEVCONN: + trio_snprintf(s, sl, "Get CD Device Connection"); + break; + + case COMMAND_GET_LASTBUFDST: + trio_snprintf(s, sl, "Get Last Buffer Destination"); + break; + + case COMMAND_SET_FILTRANGE: + trio_snprintf(s, sl, "Set Filter Range; Filter=0x%02x, FAD=0x%06x, Count=0x%06x", CD[2] >> 8, ((CD[0] & 0xFF) << 16) | CD[1], ((CD[2] & 0xFF) << 16) | CD[3]); + break; + + case COMMAND_GET_FILTRANGE: + trio_snprintf(s, sl, "Get Filter Range; Filter=0x%02x", CD[2] >> 8); + break; + + case COMMAND_SET_FILTSUBHC: + trio_snprintf(s, sl, "Set Filter Subheader Conditions; Filter=0x%02x, Channel=0x%02x, Sub Mode: 0x%02x(Mask=0x%02x), Coding Info: 0x%02x(Mask=0x%02x), File: 0x%02x", (CD[2] >> 8), CD[0] & 0xFF, CD[3] >> 8, CD[1] >> 8, CD[3] & 0xFF, CD[1] & 0xFF, CD[2] & 0xFF); + break; + + case COMMAND_GET_FILTSUBHC: + trio_snprintf(s, sl, "Get Filter Subheader Conditions; Filter=0x%02x", CD[2] >> 8); + break; + + case COMMAND_SET_FILTMODE: + trio_snprintf(s, sl, "Set Filter Mode; Filter=0x%02x, Mode=0x%02x", (CD[2] >> 8), CD[0] & 0xFF); + break; + + case COMMAND_GET_FILTMODE: + trio_snprintf(s, sl, "Get Filter Mode; Filter=0x%02x", CD[2] >> 8); + break; + + case COMMAND_SET_FILTCONN: + trio_snprintf(s, sl, "Set Filter Connection; Filter=0x%02x, Flags=0x%02x, True=0x%02x, False=0x%02x", (CD[2] >> 8), (CD[0] & 0xFF), (CD[1] >> 8), (CD[1] & 0xFF)); + break; + + case COMMAND_GET_FILTCONN: + trio_snprintf(s, sl, "Get Filter Connection; Filter=0x%02x", CD[2] >> 8); + break; + + case COMMAND_RESET_SEL: + trio_snprintf(s, sl, "Reset Selector; Flags=0x%02x, pn=0x%04x", CD[0] & 0xFF, CD[2] >> 8); + break; + + case COMMAND_GET_BUFSIZE: + trio_snprintf(s, sl, "Get Buffer Size"); + break; + + case COMMAND_GET_SECNUM: + trio_snprintf(s, sl, "Get Sector Number; Source=0x%02x", CD[2] >> 8); + break; + + case COMMAND_CALC_ACTSIZE: + trio_snprintf(s, sl, "Calculate Actual Size; Source=0x%02x[0x%04x], Count=0x%02x", CD[2] >> 8, CD[1], CD[3]); + break; + + case COMMAND_GET_ACTSIZE: + trio_snprintf(s, sl, "Get Actual Size"); + break; + + case COMMAND_GET_SECINFO: + trio_snprintf(s, sl, "Get Sector Info; Source=0x%02x[0x%04x]", CD[2] >> 8, CD[1]); + break; + + case COMMAND_EXEC_FADSRCH: + trio_snprintf(s, sl, "Execute FAD Search; Source=0x%02x[0x%04x], FAD=0x%06x", CD[2] >> 8, CD[1], ((CD[2] & 0xFF) << 16) | CD[3]); + break; + + case COMMAND_GET_FADSRCH: + trio_snprintf(s, sl, "Get FAD Search Results"); + break; + + case COMMAND_SET_SECLEN: + trio_snprintf(s, sl, "Set Sector Length; Get: 0x%02x, Put: 0x%02x", (CD[0] & 0xFF), (CD[1] >> 8)); + break; + + case COMMAND_GET_SECDATA: + trio_snprintf(s, sl, "Get Sector Data; Source=0x%02x[0x%04x], Count=0x%04x", CD[2] >> 8, CD[1], CD[3]); + break; + + case COMMAND_DEL_SECDATA: + trio_snprintf(s, sl, "Delete Sector Data; Source=0x%02x[0x%04x], Count=0x%04x", CD[2] >> 8, CD[1], CD[3]); + break; + + case COMMAND_GETDEL_SECDATA: + trio_snprintf(s, sl, "Get and Delete Sector Data; Source=0x%02x[0x%04x], Count=0x%04x", CD[2] >> 8, CD[1], CD[3]); + break; + + case COMMAND_PUT_SECDATA: + trio_snprintf(s, sl, "Put Sector Data; Filter=0x%02x, Count=0x%04x", CD[2] >> 8, CD[3]); + break; + + case COMMAND_COPY_SECDATA: + trio_snprintf(s, sl, "Copy Sector Data; Source=0x%02x[0x%04x], Dest=0x%02x, Count=0x%04x", CD[2] >> 8, CD[1], CD[0] & 0xFF, CD[3]); + break; + + case COMMAND_MOVE_SECDATA: + trio_snprintf(s, sl, "Move Sector Data; Source=0x%02x[0x%04x], Dest=0x%02x, Count=0x%04x", CD[2] >> 8, CD[1], CD[0] & 0xFF, CD[3]); + break; + + case COMMAND_GET_COPYERR: + trio_snprintf(s, sl, "Get Copy Error"); + break; + + case COMMAND_CHANGE_DIR: + trio_snprintf(s, sl, "Change Directory; ID=0x%06x, Filter: 0x%02x", ((CD[2] & 0xFF) << 16) | CD[3], (CD[2] >> 8)); + break; + + case COMMAND_READ_DIR: + trio_snprintf(s, sl, "Read Directory; ID=0x%06x, Filter=0x%02x", ((CD[2] & 0xFF) << 16) | CD[3], (CD[2] >> 8)); + break; + + case COMMAND_GET_FSSCOPE: + trio_snprintf(s, sl, "Get Filesystem Scope"); + break; + + case COMMAND_GET_FINFO: + trio_snprintf(s, sl, "Get File Info; ID=0x%06x", ((CD[2] & 0xFF) << 16) | CD[3]); + break; + + case COMMAND_READ_FILE: + trio_snprintf(s, sl, "Read File; Offset=0x%06x, ID=0x%06x, Filter=0x%02x\n", ((CD[0] & 0xFF) << 16) | CD[1], ((CD[2] & 0xFF) << 16) | CD[3], CD[2] >> 8); + break; + + case COMMAND_ABORT_FILE: + trio_snprintf(s, sl, "Abort File"); + break; + + case COMMAND_AUTH_DEVICE: + trio_snprintf(s, sl, "Authenticate Device; Type=0x%04x, Filter=0x%02x", CD[1], CD[2] >> 8); + break; + + case COMMAND_GET_AUTH: + trio_snprintf(s, sl, "Get Device Authentication Status"); + break; + } +} + + +enum +{ + STATUS_BUSY = 0x00, + STATUS_PAUSE = 0x01, + STATUS_STANDBY = 0x02, + STATUS_PLAY = 0x03, + STATUS_SEEK = 0x04, + STATUS_SCAN = 0x05, + STATUS_OPEN = 0x06, + STATUS_NODISC = 0x07, + STATUS_RETRY = 0x08, + STATUS_ERROR = 0x09, + STATUS_FATAL = 0x0A, + + // + STATUS_PERIODIC = 0x20, + STATUS_DTREQ = 0x40, + STATUS_WAIT = 0x80, + + // + STATUS_REJECTED = 0xFF +}; + +enum +{ + HIRQ_CMOK = 0x0001, // command ok? + HIRQ_DRDY = 0x0002, // data transfer ready + HIRQ_CSCT = 0x0004, // 1 sector read complete? + HIRQ_BFUL = 0x0008, // buffer full + HIRQ_PEND = 0x0010, // play end (FIXME: Status must indicate a "Pause" state at the time this is triggered) + HIRQ_DCHG = 0x0020, // disc change + HIRQ_ESEL = 0x0040, // end of selector something? + HIRQ_EHST = 0x0080, // end of host I/O? + HIRQ_ECPY = 0x0100, // end of copy/move + HIRQ_EFLS = 0x0200, // end of filesystem something? + HIRQ_SCDQ = 0x0400, // Sub-channel Q update complete? + + HIRQ_MPED = 0x0800, + HIRQ_MPCM = 0x1000, + HIRQ_MPST = 0x2000 +}; +static uint16 HIRQ, HIRQ_Mask; +static uint16 CData[4]; +static uint16 Results[4]; +static bool CommandPending; + +static uint8 CDDevConn; +static uint8 LastBufDest; + +enum { NumBuffers = 0xC8 }; +static struct BufferT +{ + uint8 Data[2352]; + uint8 Prev; + uint8 Next; +} Buffers[NumBuffers]; + +static struct FilterS +{ + enum + { + MODE_SEL_FILE = 0x01, + MODE_SEL_CHANNEL = 0x02, + MODE_SEL_SUBMODE = 0x04, + MODE_SEL_CINFO = 0x08, + MODE_SEL_SHREV = 0x10, // Reverse sub-header conditions + MODE_SEL_FADR = 0x40, + MODE_INIT = 0x80 + }; + + uint8 Mode; + uint8 TrueConn; + uint8 FalseConn; + // + uint32 FAD; + uint32 Range; + + uint8 Channel; + uint8 File; + + uint8 SubMode; + uint8 SubModeMask; + + uint8 CInfo; + uint8 CInfoMask; +} Filters[0x18]; + +static struct +{ + uint8 FirstBuf; + uint8 LastBuf; + uint8 Count; +} Partitions[0x18]; + +static uint8 FirstFreeBuf; +static uint8 FreeBufferCount; + +static struct +{ + uint32 fad; + uint16 spos; + uint8 pnum; +} FADSearch; + +static uint32 CalcedActualSize; +// +// +// +// +// +static bool TrayOpen; +static CDIF* Cur_CDIF; +static CDUtility::TOC toc; +static sscpu_timestamp_t lastts; +static int32 CommandPhase; +//static bool CommandYield; +static int64 CommandClockCounter; +static uint32 CDB_ClockRatio; + +static struct +{ + uint8 Command; + uint16 CD[4]; +} CTR; + +static struct +{ + bool Active; + bool Writing; + bool NeedBufFree; + + unsigned CurBufIndex; + unsigned BufCount; + + unsigned InBufOffs; + unsigned InBufCounter; + + unsigned TotalCounter; + + uint8 FNum; + + uint16 FIFO[6]; + uint8 FIFO_RP; + uint8 FIFO_WP; + uint8 FIFO_In; + + uint8 BufList[NumBuffers]; +} DT; + +static uint16 StandbyTime; +static uint8 ECCEnable; +static uint8 RetryCount; + +static bool ResultsRead; + +static int32 SeekIndexPhase; +static uint32 CurSector; +static int32 DrivePhase; + +enum +{ + DRIVEPHASE_STOPPED = 0, + DRIVEPHASE_PLAY, + + DRIVEPHASE_SEEK_START, + DRIVEPHASE_SEEK, + DRIVEPHASE_SCAN, + + DRIVEPHASE_EJECTED0, + DRIVEPHASE_EJECTED1, + DRIVEPHASE_EJECTED_WAITING, + DRIVEPHASE_STARTUP, + + DRIVEPHASE_RESETTING +}; +static int64 DriveCounter; +static int64 PeriodicIdleCounter; +enum { PeriodicIdleCounter_Reload = (int64)187065 << 32 }; + +static uint8 PlayRepeatCounter; +static uint8 CurPlayRepeat; + +static uint32 CurPlayStart; +static uint32 CurPlayEnd; +static uint32 PlayEndIRQType; +//static uint32 PlayEndIRQPending; + +static uint32 PlayCmdStartPos, PlayCmdEndPos; +static uint8 PlayCmdRepCnt; + +enum { CDDABuf_PrefillCount = 4 }; +enum { CDDABuf_MaxCount = 4 + 588 + 4 }; +static uint16 CDDABuf[CDDABuf_MaxCount][2]; +static uint32 CDDABuf_RP, CDDABuf_WP; +static uint32 CDDABuf_Count; + +static uint8 SecPreBuf[2352 + 96]; +static int SecPreBuf_In; + +static uint8 TOC_Buffer[(99 + 3) * 4]; + +static struct +{ + uint8 status; + uint32 fad; + uint32 rel_fad; + uint8 ctrl_adr; + uint8 idx; + uint8 tno; + + bool is_cdrom; +} CurPosInfo; + +// Higher-level: +static uint8 SubCodeQBuf[10]; +static uint8 SubCodeRWBuf[24]; + +// SubQBuf for ADR=1 only for now. +static uint8 SubQBuf[0xC]; +static uint8 SubQBuf_Safe[0xC]; +static bool SubQBuf_Safe_Valid; + +static bool DecodeSubQ(uint8 *subpw) +{ + uint8 tmp_q[0xC]; + + memset(tmp_q, 0, 0xC); + + for(int i = 0; i < 96; i++) + tmp_q[i >> 3] |= ((subpw[i] & 0x40) >> 6) << (7 - (i & 7)); + + if((tmp_q[0] & 0xF) == 1) + { + memcpy(SubQBuf, tmp_q, 0xC); + + if(subq_check_checksum(tmp_q)) + { + memcpy(SubQBuf_Safe, tmp_q, 0xC); + SubQBuf_Safe_Valid = true; + return(true); + } + } + + return(false); +} + +static void ResetBuffers(void) +{ + Buffers[0].Prev = 0xFF; + Buffers[0].Next = 1; + for(unsigned i = 1; i < (NumBuffers - 1); i++) + { + Buffers[i].Prev = i - 1; + Buffers[i].Next = i + 1; + } + Buffers[NumBuffers - 1].Prev = NumBuffers - 1 - 1; + Buffers[NumBuffers - 1].Next = 0xFF; + + FirstFreeBuf = 0; + FreeBufferCount = NumBuffers; + + for(unsigned i = 0; i < 0x18; i++) + { + Partitions[i].FirstBuf = 0xFF; + Partitions[i].LastBuf = 0xFF; + Partitions[i].Count = 0; + } +} + +static void Filter_ResetCond(const unsigned fnum) +{ + auto& f = Filters[fnum]; + + f.Mode = 0; + + f.FAD = 0; + f.Range = 0; + + f.Channel = 0; + f.File = 0; + + f.SubMode = 0; + f.SubModeMask = 0; + + f.CInfo = 0; + f.CInfoMask = 0; +} + +static uint8 Buffer_Allocate(const bool zero_clear) +{ + const unsigned bfsidx = FirstFreeBuf; + assert(bfsidx != 0xFF && FreeBufferCount > 0); + + if(zero_clear) + memset(Buffers[bfsidx].Data, 0x00, sizeof(Buffers[bfsidx].Data)); + + if(Buffers[bfsidx].Prev == 0xFF) + FirstFreeBuf = Buffers[bfsidx].Next; + else + Buffers[Buffers[bfsidx].Prev].Next = Buffers[bfsidx].Next; + + if(Buffers[bfsidx].Next == 0xFF) + { + + } + else + Buffers[Buffers[bfsidx].Next].Prev = Buffers[bfsidx].Prev; + + FreeBufferCount--; + + // + Buffers[bfsidx].Prev = 0xFF; + Buffers[bfsidx].Next = 0xFF; + // + + return bfsidx; +} + +// Must not alter "Data" member, as it may be used while "free"'d. +static void Buffer_Free(const uint8 bfsidx) +{ + assert((FirstFreeBuf == 0xFF && FreeBufferCount == 0) || (FirstFreeBuf != 0xFF && FreeBufferCount > 0)); + assert(Buffers[bfsidx].Next == 0xFF && Buffers[bfsidx].Prev == 0xFF); + + Buffers[bfsidx].Prev = 0xFF; + Buffers[bfsidx].Next = FirstFreeBuf; + + if(FirstFreeBuf != 0xFF) + { + assert(Buffers[FirstFreeBuf].Prev == 0xFF); + Buffers[FirstFreeBuf].Prev = bfsidx; + } + + FreeBufferCount++; + FirstFreeBuf = bfsidx; +} + +static void Partition_LinkBuffer(const unsigned pnum, const unsigned bfsidx) +{ + assert(Buffers[bfsidx].Next == 0xFF && Buffers[bfsidx].Prev == 0xFF); + + Buffers[bfsidx].Next = 0xFF; + + if(Partitions[pnum].FirstBuf == 0xFF) + { + assert(Partitions[pnum].LastBuf == 0xFF); + Partitions[pnum].FirstBuf = bfsidx; + Partitions[pnum].LastBuf = bfsidx; + Buffers[bfsidx].Prev = 0xFF; + } + else + { + assert(Partitions[pnum].LastBuf != 0xFF); + Buffers[Partitions[pnum].LastBuf].Next = bfsidx; + Buffers[bfsidx].Prev = Partitions[pnum].LastBuf; + } + + Partitions[pnum].LastBuf = bfsidx; + Partitions[pnum].Count++; +} + +static int Partition_GetBuffer(unsigned pnum, unsigned rbi) +{ + for(unsigned ii = Partitions[pnum].FirstBuf; ii != 0xFF; ii = Buffers[ii].Next) + { + if(!rbi) + return ii; + + rbi--; + } + + return -1; +} + +// Must not alter "Data" member, as it may be used while unlinked. +static void Partition_UnlinkBuffer(unsigned pnum, unsigned bfsidx) +{ + assert(Partitions[pnum].Count > 0); + + Partitions[pnum].Count--; + + if(Buffers[bfsidx].Prev == 0xFF) + { + assert(Partitions[pnum].FirstBuf == bfsidx); + Partitions[pnum].FirstBuf = Buffers[bfsidx].Next; + } + else + { + assert(Partitions[pnum].FirstBuf != bfsidx); + Buffers[Buffers[bfsidx].Prev].Next = Buffers[bfsidx].Next; + } + + if(Buffers[bfsidx].Next == 0xFF) + { + assert(Partitions[pnum].LastBuf == bfsidx); + Partitions[pnum].LastBuf = Buffers[bfsidx].Prev; + } + else + { + assert(Partitions[pnum].LastBuf != bfsidx); + Buffers[Buffers[bfsidx].Next].Prev = Buffers[bfsidx].Prev; + } + + // + Buffers[bfsidx].Prev = 0xFF; + Buffers[bfsidx].Next = 0xFF; +} + +static void SetCDDeviceConn(const uint8 fnum) +{ + for(unsigned fs = 0; fs < 0x18; fs++) + if(Filters[fs].FalseConn == fnum) + Filters[fs].FalseConn = 0xFF; + + CDDevConn = fnum; +} + +static void Filter_SetRange(const uint8 fnum, const uint32 fad, const uint32 range) +{ + Filters[fnum].FAD = fad; + Filters[fnum].Range = range; +} + +static void Filter_SetTrueConn(const uint8 fnum, const uint8 tconn) +{ + Filters[fnum].TrueConn = tconn; +} + +static void Filter_SetFalseConn(const uint8 fnum, const uint8 fconn) +{ + if(CDDevConn == fconn) + CDDevConn = 0xFF; + + for(unsigned fs = 0; fs < 0x18; fs++) + if(Filters[fs].FalseConn == fconn) + Filters[fs].FalseConn = 0xFF; + + Filters[fnum].FalseConn = fconn; +} + +static void Partition_Clear(const unsigned pnum) +{ + while(Partitions[pnum].Count > 0) + { + const unsigned bfi = Partitions[pnum].FirstBuf; + + Partition_UnlinkBuffer(pnum, bfi); + Buffer_Free(bfi); + } +} + +// +// +// +// +// +static struct FileInfoS +{ + uint8 fad_be[4]; + uint8 size_be[4]; + + INLINE uint32 fad(void) const { return MDFN_de32msb(fad_be); } + INLINE uint32 size(void) const { return MDFN_de32msb(size_be); } + + uint8 unit_size; + uint8 gap_size; + uint8 fnum; + uint8 attr; +} __attribute__((__packed__)) FileInfo[256]; +static bool FileInfoValid; + +enum +{ + FATTR_DIR = 0x02, + FATTR_XA_M2F1 = 0x08, + FATTR_XA_M2F2 = 0x10, + FATTR_XA_ILEAVE = 0x20, + FATTR_XA_CDDA = 0x40, + FATTR_XA_DIR = 0x80 +}; + + +static FileInfoS RootDirInfo; +static bool RootDirInfoValid; + +static struct +{ + bool Active; + bool DoAuth; + bool Abort; + uint8 pnum; + + uint32 CurDirFAD; + + uint8 FileInfoValidCount; // 0 ... 254 + uint32 FileInfoOffs; // 2 ... whatever + uint32 FileInfoOnDiscCount; // 0 ... infinities + + uint32 Phase; + + uint8 pbuf[2048]; + uint32 pbuf_offs; + uint32 pbuf_read_i; + + uint32 total_counter; + uint32 total_max; + + uint8 record[256]; + uint32 record_counter; + + uint32 finfo_read_start_offs; + uint32 finfo_offs; +} FLS; + + +enum { FLSPhaseBias = __COUNTER__ + 1 }; + +#define FLS_PROLOGUE switch(FLS.Phase + FLSPhaseBias) { for(;;) { default: case __COUNTER__: ; +#define FLS_EPILOGUE } } FLSGetOut:; + +#define FLS_YIELD { \ + FLS.Phase = __COUNTER__ - FLSPhaseBias + 1; \ + goto FLSGetOut; \ + case __COUNTER__:; \ + } + +#define FLS_WAIT_UNTIL_COND(n) { \ + case __COUNTER__: \ + if(!(n)) \ + { \ + FLS.Phase = __COUNTER__ - FLSPhaseBias - 1; \ + goto FLSGetOut; \ + } \ + } + +#define FLS_WAIT_GRAB_BUF \ + FLS_WAIT_UNTIL_COND(Partitions[FLS.pnum].Count > 0); \ + { \ + const unsigned bfi = Partitions[FLS.pnum].FirstBuf; \ + const uint8* const dptr = Buffers[bfi].Data; \ + Partition_UnlinkBuffer(FLS.pnum, bfi); \ + memcpy(FLS.pbuf, &dptr[(dptr[15] == 0x2) ? 24 : 16], 2048); \ + Buffer_Free(bfi); \ + } + +#define FLS_READ(buffer, count) \ + for(FLS.pbuf_read_i = 0; FLS.pbuf_read_i < (count); FLS.pbuf_read_i++) \ + { \ + if(FLS.pbuf_offs == 0) \ + { \ + FLS_WAIT_GRAB_BUF; \ + } \ + if((buffer) != NULL) \ + (buffer)[FLS.pbuf_read_i] = FLS.pbuf[FLS.pbuf_offs]; \ + FLS.pbuf_offs = (FLS.pbuf_offs + 1) % 2048; \ + FLS.total_counter++; \ + } + +static void ReadRecord(FileInfoS* fi, const uint8* rr) +{ + const uint8 rec_len = rr[0]; + const uint8 fi_len = rr[32]; + + MDFN_en32msb(fi->fad_be, 150 + MDFN_de32msb(&rr[6])); + MDFN_en32msb(fi->size_be, MDFN_de32msb(&rr[14])); + + fi->attr = rr[25] & 0x2; + fi->unit_size = rr[26]; + fi->gap_size = rr[27]; + fi->fnum = 0; + + int su_offs = 33 + (fi_len | 1); + int su_len = (rec_len - su_offs); + + //printf("%d %d %d %d\n", rec_len, fi_len, su_offs, su_len); + + if(su_len >= 14 && (su_offs + su_len) <= 256) + { + if(rr[su_offs + 6] == 'X' && rr[su_offs + 7] == 'A') + { + fi->attr |= rr[su_offs + 4] & 0xF8; + fi->fnum = rr[su_offs + 8]; + } + } + + //printf("Meow: fad=%08x size=%08x attr=%02x us=%02x gs=%02x fnum=%02x %s\n", fi->fad(), fi->size(), fi->attr, fi->unit_size, fi->gap_size, fi->fnum, &FLS.record[33]); +} + +static void ClearPendingSec(void); + +static bool FLS_Run(void) +{ + bool ret = false; + //printf("%d, %d\n", Partitions[FLS.pnum].Count, FreeBufferCount); + + if(FLS.Abort) + { + if(FLS.Active) + { + SS_DBG(SS_DBG_CDB, "[CDB] FLS Abort: %d %d\n", FLS.Active, FLS.DoAuth); + } + + goto Abort; + } + + // + FLS_PROLOGUE; + // + if(FLS.Active) + { + if(FLS.DoAuth) + { + RootDirInfoValid = false; + AuthDiscType = 0x04; // FIXME: //0x02; + + for(;;) + { + static const char stdid[5] = { 'C', 'D', '0', '0', '1' }; + FLS_WAIT_GRAB_BUF; + + if(memcmp(FLS.pbuf + 1, stdid, 5) || FLS.pbuf[0] == 0xFF) + break; + else if(FLS.pbuf[0] == 0x01) // PVD + { + //printf("MEOW MEOW:"); + //for(unsigned i = 0; i < 64; i++) + // printf("%02x ", FLS.pbuf[156 + i]); + //printf("\n"); + + ReadRecord(&RootDirInfo, &FLS.pbuf[156]); + RootDirInfoValid = true; + break; + } + } + SetCDDeviceConn(0xFF); + } + else + { + FileInfoValid = false; + // + // + FLS.total_counter = 0; + FLS.pbuf_offs = 0; + FLS.FileInfoValidCount = 0; + FLS.record_counter = 0; + FLS.finfo_offs = 0; + + //printf("Start\n"); + while(FLS.total_counter < FLS.total_max) + { + memset(FLS.record, 0, sizeof(FLS.record)); + + FLS_READ(&FLS.record[0], 1); + if(!FLS.record[0]) + continue; + FLS_READ(&FLS.record[1], FLS.record[0] - 1); + + if(FLS.finfo_offs < 256) + { + if(FLS.record_counter < 2 || FLS.record_counter >= FLS.FileInfoOffs) + { + ReadRecord(&FileInfo[FLS.finfo_offs], FLS.record); + + FLS.finfo_offs++; + + if(FLS.record_counter >= 2) + FLS.FileInfoValidCount++; + } + FLS.record_counter++; + } + } + + FLS.FileInfoOnDiscCount = FLS.record_counter; + // + // + FileInfoValid = true; + } + + Partition_Clear(FLS.pnum); // Place before Abort:; + // + // + // + Abort:; + FLS.Active = false; + FLS.DoAuth = false; + FLS.Abort = false; + // + // Pause + // + PlayEndIRQType = 0; + CurPlayStart = 0x800000; + CurPlayEnd = 0x800000; + CurPlayRepeat = 0; + // + // + // + + ret = true; + } + FLS_YIELD; + // + FLS_EPILOGUE; + + return ret; +} + +// +// Sector size can change in the middle of the transfer, and takes effect around sector buffer boundaries +// +static void DT_SetIBOffsCount(const uint8* sd) +{ + if(DT.Writing) + { + static const unsigned DTW_OffsTab[4] = { 12, 8, 6, 0 }; + static const unsigned DTW_CountTab[4] = { 1024, 1168, 1170, 1176 }; + + DT.InBufOffs = DTW_OffsTab[PutSecLen]; + DT.InBufCounter = DTW_CountTab[PutSecLen]; + } + else switch(GetSecLen) + { + case SECLEN_2048: + if(sd[12 + 3] == 0x1) // Mode 1 + { + DT.InBufOffs = 8; + DT.InBufCounter = 1024; + } + else // Mode 2 + { + if(sd[16 + 2] & 0x20) // Form 2 + { + DT.InBufOffs = 12; + DT.InBufCounter = 1162; + } + else // Form 1 + { + DT.InBufOffs = 12; + DT.InBufCounter = 1024; + } + } + break; + + case SECLEN_2336: + DT.InBufOffs = 8; + DT.InBufCounter = 1168; + break; + + case SECLEN_2340: + DT.InBufOffs = 6; + DT.InBufCounter = 1170; + break; + + case SECLEN_2352: + DT.InBufOffs = 0; + DT.InBufCounter = 1176; + break; + } + + if(!DT.Writing) + { + const uint32 fad = AMSF_to_ABA(BCD_to_U8(sd[12 + 0]), BCD_to_U8(sd[12 + 1]), BCD_to_U8(sd[12 + 2])); + SS_DBG(SS_DBG_CDB, "[CDB] DT FAD: %08x --- %d %d\n", fad, DT.InBufOffs, DT.InBufCounter); + } +} + +static void DT_ReadIntoFIFO(void) +{ + uint16 tmp; + + if(MDFN_UNLIKELY(DT.BufList[DT.CurBufIndex] >= 0xF0)) + { + const uint8 t = DT.BufList[DT.CurBufIndex]; + + if(t == 0xFF) + tmp = MDFN_de16msb(&TOC_Buffer[DT.InBufOffs << 1]); + else if(t == 0xFE) + tmp = MDFN_de16msb(&SubCodeQBuf[DT.InBufOffs << 1]); + else if(t == 0xFD) + tmp = MDFN_de16msb(&SubCodeRWBuf[DT.InBufOffs << 1]); + else + tmp = MDFN_de16msb((uint8*)FileInfo + (DT.InBufOffs << 1)); + } + else + tmp = MDFN_de16msb(&Buffers[DT.BufList[DT.CurBufIndex]].Data[DT.InBufOffs << 1]); + + //printf("%02x %02x\n", DT.BufList[DT.CurBufIndex], DT.CurBufIndex); + DT.FIFO[DT.FIFO_WP] = tmp; + DT.FIFO_WP = (DT.FIFO_WP + 1) % (sizeof(DT.FIFO) / sizeof(DT.FIFO[0])); + DT.FIFO_In++; + DT.InBufOffs++; + DT.InBufCounter--; + DT.TotalCounter++; + + if(!DT.InBufCounter) + { + DT.CurBufIndex++; + if(DT.CurBufIndex < DT.BufCount) + { + DT_SetIBOffsCount(Buffers[DT.BufList[DT.CurBufIndex]].Data); + } + } +} + + + +// Ratio between SH-2 clock and sound subsystem 68K clock (sound clock / 2) +// (needs to match the algorithm precision in sound.cpp, for proper CD-DA stream synch without having to get into more complicated designs) +void CDB_SetClockRatio(uint32 ratio) +{ + CDB_ClockRatio = ratio; +} + +static void SWReset(void) +{ + GetSecLen = SECLEN_2048; + PutSecLen = SECLEN_2048; + + CDDevConn = 0xFF; + + LastBufDest = 0xFF; + + memset(&DT, 0, sizeof(DT)); + DT.Active = false; + + for(unsigned i = 0; i < 0x18; i++) + { + auto& f = Filters[i]; + + f.TrueConn = i; + f.FalseConn = 0xFF; + + Filter_ResetCond(i); + } + + ResetBuffers(); + + FADSearch.fad = 0; + FADSearch.spos = 0; + FADSearch.pnum = 0; + + CalcedActualSize = 0; + + PlayEndIRQType = 0; + CurPlayEnd = 0x800000; + CurPlayRepeat = 0; + ClearPendingSec(); + // + // + // + memset(&FLS, 0, sizeof(FLS)); + FileInfoValid = false; + FLS.Phase = 0; +} + +void CDB_ResetCD(void) // TODO +{ + PeriodicIdleCounter = 0x7FFFFFFFFFFFFFFFLL; + DrivePhase = DRIVEPHASE_RESETTING; + DriveCounter = 0x7FFFFFFFFFFFFFFFLL; + + Results[0] = 0; + Results[1] = 0; + Results[2] = 0; + Results[3] = 0; + ResultsRead = true; + + CommandPhase = -1; + CommandClockCounter = 0; + // TODO: Set next event, timestamp + 1. +} + +void CDB_SetCDActive(bool active) // TODO +{ + +} + + + +void CDB_Init(void) +{ + lastts = 0; + Cur_CDIF = NULL; + TrayOpen = false; +} + +void CDB_SetDisc(bool tray_open, CDIF *cdif) +{ + TrayOpen = tray_open; + Cur_CDIF = tray_open ? NULL : cdif; + + if(!Cur_CDIF) + { + if(DrivePhase != DRIVEPHASE_RESETTING) + { + AuthDiscType = 0x00; + DrivePhase = DRIVEPHASE_EJECTED0; + DriveCounter = (int64)1000 << 32; + } + } +} + +static INLINE void RecalcIRQOut(void) +{ + SCU_SetInt(16, (bool)(HIRQ & HIRQ_Mask)); +} + +void CDB_Reset(bool powering_up) +{ + HIRQ = 0; + HIRQ_Mask = 0; + RecalcIRQOut(); + + CDB_ResetCD(); +} + +static INLINE void TriggerIRQ(unsigned bs) +{ + HIRQ |= bs; + + RecalcIRQOut(); +} + +enum { CommandPhaseBias = __COUNTER__ + 1 }; + +#define CMD_YIELD { \ + CommandPhase = __COUNTER__ - CommandPhaseBias + 1; \ + CommandClockCounter = -(500LL << 32); \ + /*CommandYield = true;*/ \ + goto CommandGetOut; \ + case __COUNTER__: \ + /*CommandYield = false;*/ \ + CommandClockCounter = 0; \ + } + +#define CMD_EAT_CLOCKS(n) { \ + CommandClockCounter -= (int64)(n) << 32; \ + { \ + case __COUNTER__: \ + if(CommandClockCounter < 0) \ + { \ + CommandPhase = __COUNTER__ - CommandPhaseBias - 1; \ + goto CommandGetOut; \ + } \ + /*printf("%f\n", (double)ClockCounter / (1LL << 32));*/ \ + } \ + } + + +// Drive commands: Init, Open, Play, Seek, Scan +// return busy status +// Commands that change drive status: +// Init, Open, Play, Seek, Scan +// + +static uint8 MakeBaseStatus(const bool rejected = false, const uint8 hb = 0) +{ + if(rejected) + return STATUS_REJECTED; + + uint8 ret = 0; + + if(TrayOpen) + ret = STATUS_OPEN; + else if(!Cur_CDIF) + ret = STATUS_NODISC; + else + ret = CurPosInfo.status; + + return ret | hb; +} + +static bool TestFilterCond(const unsigned fnum, const uint8* data) +{ + auto& f = Filters[fnum]; + + if(f.Mode & FilterS::MODE_SEL_FADR) + { + const uint32 fad = AMSF_to_ABA(BCD_to_U8(data[12 + 0]), BCD_to_U8(data[12 + 1]), BCD_to_U8(data[12 + 2])); + + if(fad < f.FAD || fad >= (f.FAD + f.Range)) + return false; + } + + uint8 file, channel, submode, cinfo; + + if(data[15] == 0x2) + { + file = data[16]; + channel = data[17]; + submode = data[18]; + cinfo = data[19]; + } + else + file = channel = submode = cinfo = 0x00; + + const bool shinv = (bool)(f.Mode & FilterS::MODE_SEL_SHREV) && (bool)(f.Mode & 0x0F); + + if(f.Mode & FilterS::MODE_SEL_FILE) + { + if((bool)(file != f.File)) + return shinv; + } + + if(f.Mode & FilterS::MODE_SEL_CHANNEL) + { + if((bool)(channel != f.Channel)) + return shinv; + } + + if(f.Mode & FilterS::MODE_SEL_SUBMODE) + { + if((bool)((submode & f.SubModeMask) != f.SubMode)) + return shinv; + } + + if(f.Mode & FilterS::MODE_SEL_CINFO) + { + if((bool)((cinfo & f.CInfoMask) != f.CInfo)) + return shinv; + } + + return !shinv; +} + +static uint8 FilterBuf(const unsigned fnum, const unsigned bfsidx) +{ + assert(bfsidx != 0xFF); + + unsigned cur = fnum; + unsigned max_iter = 0x18; + //uint32 done = 0; + + SS_DBG(SS_DBG_CDB, "[CDB] DT FilterBuf: fad=0x%08x -- %02x %02x --- %02x %02x\n", AMSF_to_ABA(BCD_to_U8(Buffers[bfsidx].Data[12 + 0]), BCD_to_U8(Buffers[bfsidx].Data[12 + 1]), BCD_to_U8(Buffers[bfsidx].Data[12 + 2])), fnum, bfsidx, Filters[fnum].TrueConn, Filters[fnum].FalseConn); + + while(cur != 0xFF && max_iter--) + { + if(TestFilterCond(cur, Buffers[bfsidx].Data)) + { + if(Filters[cur].TrueConn != 0xFF) + { + Partition_LinkBuffer(Filters[cur].TrueConn, bfsidx); + return cur; + } + cur = 0xFF; + } + else + cur = Filters[cur].FalseConn; + } + + // Discarded. Poor buffer. + Buffer_Free(bfsidx); + + return 0xFF; +} + +static void TranslateTOC(void) +{ + uint8* td = TOC_Buffer; + + for(unsigned i = 1; i < 100; i++) + { + const auto& t = toc.tracks[i]; + + if(t.valid) + { + const uint32 fad = t.lba + 150; + + td[0] = (t.control << 4) | t.adr; + td[1] = fad >> 16; + td[2] = fad >> 8; + td[3] = fad >> 0; + } + else + td[0] = td[1] = td[2] = td[3] = 0xFF; + + td += 4; + } + + // TODO: Better raw TOC support in core code. + + // POINT=A0 + { + const auto& t = toc.tracks[toc.first_track]; + + td[0] = (t.control << 4) | t.adr; + td[1] = toc.first_track; + td[2] = toc.disc_type; + td[3] = 0; + + td += 4; + } + + // POINT=A1 + { + const auto& t = toc.tracks[toc.last_track]; + + td[0] = (t.control << 4) | t.adr; + td[1] = toc.last_track; + td[2] = 0; + td[3] = 0; + + td += 4; + } + + // Lead-out + { + const auto& t = toc.tracks[100]; + const uint32 fad = t.lba + 150; + + td[0] = (t.control << 4) | t.adr; + td[1] = fad >> 16; + td[2] = fad >> 8; + td[3] = fad >> 0; + td += 4; + } + + assert((td - TOC_Buffer) == sizeof(TOC_Buffer)); + assert(sizeof(TOC_Buffer) == 0xCC * 2); +} + +// +// +// +// +// +// +static void MakeReport(const bool rejected = false, const uint8 hb = 0, const bool nobs = false) +{ + Results[0] = ((nobs ? 0x00 : MakeBaseStatus(rejected, hb)) << 8) | (CurPosInfo.is_cdrom << 7) | PlayRepeatCounter; + + Results[1] = (CurPosInfo.ctrl_adr << 8) | CurPosInfo.tno; + Results[2] = (CurPosInfo.idx << 8) | (CurPosInfo.fad >> 16); + Results[3] = CurPosInfo.fad; +} + +static void CDStatusResults(const bool rejected = false, const uint8 hb = 0, const bool nobs = false) +{ + MakeReport(rejected, hb, nobs); + + SS_DBG(SS_DBG_CDB, "[CDB] Results: %04x %04x %04x %04x\n", Results[0], Results[1], Results[2], Results[3]); + ResultsRead = false; + CommandPending = false; + TriggerIRQ(HIRQ_CMOK); +} + +static void BasicResults(uint32 res0, uint32 res1, uint32 res2, uint32 res3) +{ + Results[0] = res0; + Results[1] = res1; + Results[2] = res2; + Results[3] = res3; + ResultsRead = false; + + SS_DBG(SS_DBG_CDB, "[CDB] Results: %04x %04x %04x %04x\n", Results[0], Results[1], Results[2], Results[3]); + + CommandPending = false; + TriggerIRQ(HIRQ_CMOK); +} + +static void StartSeek(const uint32 cmd_target, const bool no_pickup_change = false) +{ + if(!Cur_CDIF) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_CDB, "[CDB] [BUG] StartSeek() called when no disc present or tray open.\n"); + return; + } + + CurPlayStart = cmd_target; + + if(no_pickup_change) + { + if(DrivePhase == DRIVEPHASE_PLAY) + { + // Maybe stop scanning? or before the if(no_pickup_change)... + return; + } + } + else if(cmd_target & 0x800000) + { + int32 fad_target = cmd_target & 0x7FFFFF; + int32 tt = 1; + + if(fad_target < 150) + fad_target = 150; + else if(fad_target >= (150 + (int32)toc.tracks[100].lba)) + fad_target = 150 + toc.tracks[100].lba; + + for(int32 track = 1; track <= 100; track++) + { + if(!toc.tracks[track].valid) + continue; + + if(fad_target < (150 + (int32)toc.tracks[track].lba)) + break; + + tt = track; + } + + CurPosInfo.tno = (tt == 100) ? 0xAA : tt; + CurPosInfo.idx = 1; + CurPosInfo.fad = fad_target; + CurPosInfo.rel_fad = fad_target - (150 + toc.tracks[tt].lba); + CurPosInfo.ctrl_adr = (toc.tracks[tt].control << 4) | (toc.tracks[tt].adr << 0); + } + else + { + int32 track_target = (cmd_target >> 8) & 0xFF; + int32 index_target = cmd_target & 0xFF; + + if(track_target > toc.last_track) + track_target = toc.last_track; + else if(track_target < toc.first_track) + track_target = toc.first_track; + + if(index_target < 1) + index_target = 1; + else if(index_target > 99) + index_target = 99; + + CurPosInfo.tno = track_target; + CurPosInfo.idx = index_target; + CurPosInfo.fad = 150 + toc.tracks[track_target].lba; + CurPosInfo.rel_fad = 0; + CurPosInfo.ctrl_adr = (toc.tracks[track_target].control << 4) | (toc.tracks[track_target].adr << 0); + } + // + CurPosInfo.status = STATUS_BUSY; + CurPosInfo.is_cdrom = false; + DrivePhase = DRIVEPHASE_SEEK_START; + + Cur_CDIF->HintReadSector(CurPosInfo.fad); + +// PlayEndIRQPending = false; + PeriodicIdleCounter = PeriodicIdleCounter_Reload; + DriveCounter = (int64)256000 << 32; //(int64)((44100 * 256) / 150) << 32; + SeekIndexPhase = 0; +} + +static void Drive_Run(int64 clocks) +{ + DriveCounter -= clocks; + PeriodicIdleCounter -= clocks; + while(DriveCounter <= 0) + { + switch(DrivePhase) + { + case DRIVEPHASE_EJECTED0: + memset(TOC_Buffer, 0xFF, sizeof(TOC_Buffer)); // TODO: confirm 0xFF(or 0x00?) + + // TODO: Check DrivePhase and these vars in command processing. + AuthDiscType = 0x00; + FileInfoValid = false; + RootDirInfoValid = false; + + CurPosInfo.status = STATUS_OPEN; + CurPosInfo.is_cdrom = false; + CurPosInfo.fad = 0xFFFFFF; + CurPosInfo.rel_fad = 0xFFFFFF; + CurPosInfo.ctrl_adr = 0xFF; + CurPosInfo.idx = 0xFF; + CurPosInfo.tno = 0xFF; + TriggerIRQ(HIRQ_DCHG); + + DrivePhase = DRIVEPHASE_EJECTED1; + DriveCounter = (int64)4000 << 32; + break; + + case DRIVEPHASE_EJECTED1: + TriggerIRQ(HIRQ_EFLS); + DrivePhase = DRIVEPHASE_EJECTED_WAITING; + DriveCounter = (int64)1 << 32; + break; + + case DRIVEPHASE_EJECTED_WAITING: + if(Cur_CDIF) + { + CurPosInfo.status = STATUS_BUSY; + DrivePhase = DRIVEPHASE_STARTUP; + DriveCounter = (int64)(1 * 44100 * 256) << 32; + } + else + DriveCounter = (int64)1000 << 32; + + break; + + case DRIVEPHASE_STARTUP: + Cur_CDIF->ReadTOC(&toc); + TranslateTOC(); + // + // + // + ClearPendingSec(); + StartSeek(0x800096); + + PlayEndIRQType = 0; + CurPlayEnd = 0x800000; + CurPlayRepeat = 0; + break; + + case DRIVEPHASE_STOPPED: + CurPosInfo.status = STATUS_STANDBY; + DriveCounter += (int64)2000 << 32; + break; + +/* + DoSeek +*/ + case DRIVEPHASE_SEEK_START: + { + int32 seek_base_time = 2 * (44100 * 256) / 150; + int32 fad_delta; + + fad_delta = CurPosInfo.fad - CurSector; + + //if(abs(fad_delta) >= 4000) // FIXME ! ! !something) + //{ + // seek_base_time += abs(fad_delta) somethingelse; // FIXME ! ! ! + //} + seek_base_time += abs(fad_delta) * (44100 * 256) / 300000 / 2; // FIXME ! ! ! + + CurPosInfo.status = STATUS_SEEK; + DrivePhase = DRIVEPHASE_SEEK; + DriveCounter += (int64)seek_base_time << 32; + CurSector = CurPosInfo.fad; + SubQBuf_Safe_Valid = false; + } + break; + + + case DRIVEPHASE_SEEK: + // + // Extremely crude approximation. + // + { + static uint8 pwbuf[96]; + const bool old_safe_valid = SubQBuf_Safe_Valid; + + Cur_CDIF->ReadRawSectorPWOnly(pwbuf, CurSector - 150, false); + DecodeSubQ(pwbuf); + + if(!SubQBuf_Safe_Valid) + { + CurSector++; + DriveCounter += (int64)((44100 * 256) / 150) << 32; + } + else + { + bool index_ok = true; + + if(!old_safe_valid) + CurSector = CurPosInfo.fad; + + if(!(CurPlayStart & 0x800000)) + { + const unsigned start_track = std::min(toc.last_track, std::max(toc.first_track, (CurPlayStart >> 8) & 0xFF)); + const unsigned start_index = std::min(99, std::max(1, CurPlayStart & 0xFF)); + const unsigned sq_idx = BCD_to_U8(SubQBuf_Safe[0x2]); + const unsigned sq_tno = (SubQBuf_Safe[0x1] >= 0xA0) ? SubQBuf_Safe[0x1] : BCD_to_U8(SubQBuf_Safe[0x1]); + + if(sq_idx < start_index && sq_tno <= start_track) + { + if(SeekIndexPhase == 2) + { + index_ok = false; + CurSector += 4; + DriveCounter += (int64)((44100 * 256) / 150) << 32; + } + else + { + index_ok = false; + CurSector += 128; + DriveCounter += (int64)((44100 * 256) / 150) << 32; + SeekIndexPhase = 1; + } + } + else + { + if(SeekIndexPhase == 1) + { + index_ok = false; + CurSector -= 124; + DriveCounter += (int64)((44100 * 256) / 150) << 32; + SeekIndexPhase = 2; + } + } + } + + if(index_ok) + { + DrivePhase = DRIVEPHASE_PLAY; + DriveCounter += (int64)((44100 * 256) / ((SubQBuf_Safe[0] & 0x40) ? 150 : 75)) << 32; + } + //else + // printf("%d\n", CurSector); + } + } + break; + + case DRIVEPHASE_PLAY: + if(SecPreBuf_In > 0) + { + if(SubQBuf_Safe[0] & 0x40) + { + CurPosInfo.is_cdrom = true; + + //assert(edc_check(SecPreBuf, false)); + + if(FreeBufferCount > 0) + { + const uint8 bfi = Buffer_Allocate(false); + + memcpy(Buffers[bfi].Data, SecPreBuf, 2352); + + SecPreBuf_In = false; + LastBufDest = FilterBuf(CDDevConn, bfi); + TriggerIRQ(HIRQ_CSCT); + if(FreeBufferCount == 0) + TriggerIRQ(HIRQ_BFUL); + } + } + else + { + CurPosInfo.is_cdrom = false; + if(!CDDABuf_Count) + { + for(int i = 0; i < CDDABuf_PrefillCount; i++) + { + CDDABuf[CDDABuf_WP][0] = 0; + CDDABuf[CDDABuf_WP][1] = 0; + CDDABuf_WP = (CDDABuf_WP + 1) % CDDABuf_MaxCount; + CDDABuf_Count++; + } + } + + for(int i = 0; i < 588 && CDDABuf_Count < CDDABuf_MaxCount; i++) + { + CDDABuf[CDDABuf_WP][0] = MDFN_de16lsb(&SecPreBuf[i * 4 + 0]); + CDDABuf[CDDABuf_WP][1] = MDFN_de16lsb(&SecPreBuf[i * 4 + 2]); + CDDABuf_WP = (CDDABuf_WP + 1) % CDDABuf_MaxCount; + CDDABuf_Count++; + } + + SecPreBuf_In = false; + } + + if(!SecPreBuf_In) + { + CurPosInfo.status = STATUS_PLAY; + } + } // end if(SecPreBuf_In > 0) + + PeriodicIdleCounter = 17712LL << 32; + if(DrivePhase == DRIVEPHASE_PLAY) + { + if(SecPreBuf_In) + { + // TODO: More accurate: + CurPosInfo.status = STATUS_PAUSE; + + if(SecPreBuf_In > 0) + SS_DBG(SS_DBG_CDB, "[CDB] SB Overflow\n"); + } + else + { + Cur_CDIF->ReadRawSector(SecPreBuf, CurSector - 150); + SecPreBuf_In = true; + + // TODO:(maybe pointless...) + //if(SubQBuf_Safe[0] & 0x40) + // CurPosInfo.fad = SECTOR HEADER + //else + // CurPosInfo.fad = SUBQ STUFF + CurPosInfo.fad = CurSector; + if(DecodeSubQ(SecPreBuf + 2352)) + { + CurPosInfo.rel_fad = (BCD_to_U8(SubQBuf[0x3]) * 60 + BCD_to_U8(SubQBuf[0x4])) * 75 + BCD_to_U8(SubQBuf[0x5]); + CurPosInfo.tno = (SubQBuf[0x1] >= 0xA0) ? SubQBuf[0x1] : BCD_to_U8(SubQBuf[0x1]); + CurPosInfo.idx = BCD_to_U8(SubQBuf[0x2]); + } + CurSector++; + } + } + + DriveCounter += (int64)((44100 * 256) / ((SubQBuf_Safe[0] & 0x40) ? 150 : 75)) << 32; + break; + } + } + + if(PeriodicIdleCounter <= 0) + { + PeriodicIdleCounter = PeriodicIdleCounter_Reload; + + // + // + // + if(SecPreBuf_In && DrivePhase == DRIVEPHASE_PLAY) + { + bool end_met = (CurPosInfo.tno == 0xAA); + + if(CurPlayEnd != 0) + { + if(CurPlayEnd & 0x800000) + end_met |= (CurPosInfo.fad >= (CurPlayEnd & 0x7FFFFF)); + else + { + const unsigned end_track = std::min(toc.last_track, std::max(toc.first_track, (CurPlayEnd >> 8) & 0xFF)); + const unsigned end_index = std::min(99, std::max(1, CurPlayEnd & 0xFF)); + + end_met |= (CurPosInfo.tno > end_track) || (CurPosInfo.tno == end_track && CurPosInfo.idx > end_index); + } + } + + // + // Steam Heart's, it's always Steam Heart's... + // + if(CurPlayStart & 0x800000) + { + end_met |= (CurPosInfo.fad < (CurPlayStart & 0x7FFFFF)); + } + else + { + const unsigned start_track = std::min(toc.last_track, std::max(toc.first_track, (CurPlayStart >> 8) & 0xFF)); + const unsigned start_index = std::min(99, std::max(1, CurPlayStart & 0xFF)); + + end_met |= (CurPosInfo.tno < start_track); //|| (CurPosInfo.tno == start_track && CurPosInfo.idx < start_index); + } + + if(end_met) + { + SecPreBuf_In = false; + if(PlayRepeatCounter >= CurPlayRepeat) + { + CurSector = CurPosInfo.fad; + + if(PlayEndIRQType) + { + CurPosInfo.status = STATUS_BUSY; + + PlayEndIRQType += 1 << 30; + + if((PlayEndIRQType >> 30) >= 3) + { + TriggerIRQ(PlayEndIRQType & 0xFFFF); // May not be right for EFLS with Read File, maybe EFLS is only triggered after the buffer is written? + PlayEndIRQType = 0; + } + } + + if(!PlayEndIRQType) + CurPosInfo.status = STATUS_PAUSE; + } + else + { + StartSeek(PlayCmdStartPos); + + if(PlayRepeatCounter < 0xE) + PlayRepeatCounter++; + } + } + } + // + // + // + PeriodicIdleCounter = PeriodicIdleCounter_Reload; + + if(ResultsRead) + MakeReport(false, STATUS_PERIODIC); + + // FIXME: Other ADR types, and correct handling when in STANDBY/STOPPED state? + SubCodeQBuf[0] = CurPosInfo.ctrl_adr; + SubCodeQBuf[1] = CurPosInfo.tno; + SubCodeQBuf[2] = CurPosInfo.idx; + SubCodeQBuf[3] = CurPosInfo.rel_fad >> 16; + SubCodeQBuf[4] = CurPosInfo.rel_fad >> 8; + SubCodeQBuf[5] = CurPosInfo.rel_fad >> 0; + SubCodeQBuf[6] = 0; // ? OxFF in some cases... + SubCodeQBuf[7] = CurPosInfo.fad >> 16; + SubCodeQBuf[8] = CurPosInfo.fad >> 8; + SubCodeQBuf[9] = CurPosInfo.fad >> 0; + + TriggerIRQ(HIRQ_SCDQ); + } +} + +void CDB_GetCDDA(uint16* outbuf) +{ + outbuf[0] = outbuf[1] = 0; + + if(CDDABuf_Count) + { + outbuf[0] = CDDABuf[CDDABuf_RP][0]; + outbuf[1] = CDDABuf[CDDABuf_RP][1]; + + CDDABuf_RP = (CDDABuf_RP + 1) % CDDABuf_MaxCount; + CDDABuf_Count--; + } + + //static int32 counter = 0; + //outbuf[0] = (counter & 0xFF) << 6; + //outbuf[1] = (counter & 0xFF) << 6; + //counter++; +} + +static void ClearPendingSec(void) +{ + //PlayEndIRQPending = 0; + PlayEndIRQType = 0; + + SecPreBuf_In = false; + + CDDABuf_WP = CDDABuf_RP = 0; + CDDABuf_Count = 0; +} + +sscpu_timestamp_t CDB_Update(sscpu_timestamp_t timestamp) +{ + if(MDFN_UNLIKELY(timestamp < lastts)) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_CDB, "[CDB] [BUG] timestamp(%d) < lastts(%d)\n", timestamp, lastts); + } + else + { + int64 clocks = (int64)(timestamp - lastts) * CDB_ClockRatio; + lastts = timestamp; + + Drive_Run(clocks); + + // + // + // + CommandClockCounter += clocks; + switch(CommandPhase + CommandPhaseBias) + { + for(;;) + { + default: + case __COUNTER__: + + while(!CommandPending) + { + if(FLS_Run()) + { + CMD_EAT_CLOCKS(60); + TriggerIRQ(HIRQ_EFLS); + CMD_EAT_CLOCKS(60); + } + else + { + CMD_YIELD; + } + } + + for(unsigned i = 0; i < 4; i++) + CTR.CD[i] = CData[i]; + + CTR.Command = CTR.CD[0] >> 8; + if(MDFN_UNLIKELY(ss_dbg_mask & SS_DBG_CDB)) + { + char cdet[128]; + GetCommandDetails(CTR.CD, cdet, sizeof(cdet)); + SS_DBG(SS_DBG_CDB, "[CDB] Command: %s --- HIRQ=0x%04x, HIRQ_Mask=0x%04x\n", cdet, HIRQ, HIRQ_Mask); + } + // + // + CMD_EAT_CLOCKS(84); + + // + // + // + if(CTR.Command == COMMAND_GET_CDSTATUS) // = 0x00, + { + CDStatusResults(); + } + // + // + // + else if(CTR.Command == COMMAND_GET_HWINFO) // = 0x01, + { + BasicResults(MakeBaseStatus() << 8, + 0x0002, + 0x0000, + 0x0600); // TODO: Before INIT: 0xFF00; + } + // + // + // + else if(CTR.Command == COMMAND_GET_TOC) // = 0x02, + { + if(DrivePhase == DRIVEPHASE_STARTUP || DT.Active) + CDStatusResults(false, STATUS_WAIT); + else + { + BasicResults(MakeBaseStatus(false, STATUS_DTREQ) << 8, 0xCC, 0, 0); + + // + // + DT.CurBufIndex = 0; + DT.BufCount = 1; + + DT.InBufOffs = 0; + DT.InBufCounter = 0xCC; + + DT.TotalCounter = 0; + + DT.FIFO_RP = 0; + DT.FIFO_WP = 0; + DT.FIFO_In = 0; + + DT.BufList[0] = 0xFF; + + DT.Writing = false; + DT.NeedBufFree = false; + DT.Active = true; + // + // + // + CMD_EAT_CLOCKS(128); + TriggerIRQ(HIRQ_DRDY); + } + } + // + // + // + else if(CTR.Command == COMMAND_GET_SESSINFO) // = 0x03, + { + if(DrivePhase == DRIVEPHASE_STARTUP) + CDStatusResults(false, STATUS_WAIT); + else + { + const unsigned sess = CTR.CD[0] & 0xFF; + uint32 fad; + uint8 rsw; + + if(!sess) + { + fad = 150 + toc.tracks[100].lba; + rsw = 0x01; // Session count; + } + else if(sess <= 0x01) + { + fad = 0; + rsw = sess; + } + else + { + fad = 0xFFFFFF; + rsw = 0xFF; + } + + BasicResults(MakeBaseStatus() << 8, 0, (rsw << 8) | (fad >> 16), fad); + } + } + // + // + // + else if(CTR.Command == COMMAND_INIT) // = 0x04, + { + CDStatusResults(false, 0x00, true); + + // + if(CTR.CD[0] & 0x01) // Software reset of CD block + { + SWReset(); + + CMD_EAT_CLOCKS(8192); + TriggerIRQ(HIRQ_MPED | HIRQ_EFLS | HIRQ_ECPY | HIRQ_EHST | HIRQ_ESEL | HIRQ_CMOK); + } + + // TODO TODO TODO + // & 0x02; // Decode subcode RW + // & 0x04; // Ignore mode2 subheader? + // & 0x08; // Retry form2 read + // & 0x30; // CD read speed(unused?) + // & 0x80; // No change? + } +/* + // + // + // + else if(CTR.Command == COMMAND_OPEN) // = 0x05, + { + } +*/ + // + // + // + else if(CTR.Command == COMMAND_END_DATAXFER) // = 0x06, + { + if(DT.Active) + { + DT.Active = false; + + BasicResults((MakeBaseStatus() << 8) | (DT.TotalCounter >> 16), DT.TotalCounter, 0, 0); + + if(DT.InBufCounter > 0 || DT.FIFO_In > 0) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_CDB, "[CDB] Data transfer ended prematurely at %u bytes left!\n", (DT.InBufCounter + DT.FIFO_In) * 2); + } + + if(DT.Writing) + { + if(CDDevConn == DT.FNum) + CDDevConn = 0xFF; + + for(unsigned i = 0; i < DT.BufCount; i++) + { + FilterBuf(DT.FNum, DT.BufList[i]); + } + + CMD_EAT_CLOCKS(270); + if(FreeBufferCount == 0) + TriggerIRQ(HIRQ_BFUL); + TriggerIRQ(HIRQ_EHST); + } + else + { + if(DT.NeedBufFree) + { + for(unsigned i = 0; i < DT.BufCount; i++) + { + Buffer_Free(DT.BufList[i]); + } + } + + if(DT.BufList[0] != 0xFE && DT.BufList[0] != 0xFD) // FIXME: Cleanup(use enums for special buffer ids) - Also check for TOC and FINFO + { + CMD_EAT_CLOCKS(130); + TriggerIRQ(HIRQ_EHST); + } + } + } + else + BasicResults((MakeBaseStatus() << 8) | 0xFF, 0xFFFF, 0, 0); + } + // + // + // + else if(CTR.Command == COMMAND_PLAY) // = 0x10, + { + uint32 cmd_psp = ((CTR.CD[0] & 0xFF) << 16) | CTR.CD[1]; + uint32 cmd_pep = ((CTR.CD[2] & 0xFF) << 16) | CTR.CD[3]; + uint8 pm = CTR.CD[2] >> 8; + + if(cmd_psp == 0xFFFFFF) + cmd_psp = PlayCmdStartPos; + + if(cmd_pep == 0xFFFFFF) + cmd_pep = PlayCmdEndPos; + else if((cmd_psp & 0x800000) && (cmd_pep & 0x800000)) + cmd_pep = 0x800000 | ((cmd_psp + cmd_pep) & 0x7FFFFF); + + if(((cmd_psp ^ cmd_pep) & 0x800000) && cmd_pep != 0) + CDStatusResults(true); + else + { + PlayCmdStartPos = cmd_psp; + PlayCmdEndPos = cmd_pep; + // + + CurPosInfo.status = STATUS_BUSY; // Happens even if (PlayMode & 0x80)... + CDStatusResults(); + // + // + if(!(pm & 0x80)) + ClearPendingSec(); + + StartSeek(PlayCmdStartPos, (bool)(pm & 0x80)); + + PlayEndIRQType = HIRQ_PEND; + CurPlayEnd = PlayCmdEndPos; + + if(!(pm & 0x70)) + PlayCmdRepCnt = pm & 0x0F; + + PlayRepeatCounter = 0; + CurPlayRepeat = PlayCmdRepCnt; + } + } + // + // + // + else if(CTR.Command == COMMAND_SEEK) // = 0x11, + { + CurPosInfo.status = STATUS_BUSY; + CDStatusResults(); + // + // + const uint32 cmd_sp = ((CTR.CD[0] & 0xFF) << 16) | CTR.CD[1]; + + if(!cmd_sp) // Stop + { + ClearPendingSec(); + CurPosInfo.is_cdrom = false; // FIXME? Correct? + CurPosInfo.status = STATUS_BUSY; + CurPosInfo.fad = 0xFFFFFF; + CurPosInfo.rel_fad = 0xFFFFFF; + CurPosInfo.ctrl_adr = 0xFF; + CurPosInfo.idx = 0xFF; + CurPosInfo.tno = 0xFF; + + DrivePhase = DRIVEPHASE_STOPPED; + DriveCounter = (int64)380000 << 32; + } + else if(cmd_sp == 0xFFFFFF) // Pause + { + if(DrivePhase == DRIVEPHASE_STOPPED) // TODO: Test + { + ClearPendingSec(); + StartSeek(0x800096); + } + + SecPreBuf_In = -abs(SecPreBuf_In); + PlayEndIRQType = 0; + CurPlayEnd = 0x800000; + CurPlayRepeat = 0; + } + else + { + ClearPendingSec(); + CurPlayEnd = 0x800000; + CurPlayRepeat = 0; + StartSeek(cmd_sp); + } + } +/* + // + // + // + else if(CTR.Command == COMMAND_SCAN) // = 0x12, + { + //CurPosInfo.is_cdrom = false; + Forward scan data track(on Saturn CD): + 4-5 sequential position updates, then jumps like: + 17f-> 1e1 (62) + 96d-> 9d0 (63) + fd8->103b (63) + 202c->2093 (67) + 2fa1->300a (69) + 3fdf->404a (6b) + 4fa3->5011 (6e) + 5fad->601c (6f) + 6f96->7007 (71) + 7fcd->8040 (73) + 8fd7->904e (77) + 9faf->a028 (79) + afcd->b047 (7a) + + 97.79888435299837 + 0.0005527097174003169x + } +*/ + // + // + // + else if(CTR.Command == COMMAND_GET_SUBCODE) // = 0x20, + { + if(DT.Active) + CDStatusResults(false, STATUS_WAIT); + else + { + uint8 type; + + type = CTR.CD[0] & 0xFF; + + if(type >= 0x02) + CDStatusResults(true); + else + { + if(type == 0) // Q (TODO: ADR other than 0x1) + { + BasicResults(MakeBaseStatus(false, STATUS_DTREQ) << 8, 0x05, 0, 0); + DT.BufList[0] = 0xFE; + DT.InBufCounter = 0x05; + } + else // R-W (TODO) + { + BasicResults(MakeBaseStatus(false, STATUS_DTREQ) << 8, 0x0C, 0, 0); + + for(unsigned i = 0; i < 24; i++) + SubCodeRWBuf[i] = 0xFF; + + DT.BufList[0] = 0xFD; + DT.InBufCounter = 0x0C; + } + + DT.CurBufIndex = 0; + DT.BufCount = 1; + + DT.InBufOffs = 0; + + DT.TotalCounter = 0; + DT.FIFO_RP = 0; + DT.FIFO_WP = 0; + DT.FIFO_In = 0; + + DT.Writing = false; + DT.NeedBufFree = false; + DT.Active = true; + // + // + // + CMD_EAT_CLOCKS(128); + TriggerIRQ(HIRQ_DRDY); + } + } + } + // + // + // + else if(CTR.Command == COMMAND_AUTH_DEVICE) + { + uint8 fnum; + + fnum = (CTR.CD[2] >> 8); + + if(fnum >= 0x18) + CDStatusResults(true); + else if(FLS.Active) + CDStatusResults(false, STATUS_WAIT); + else + { + CDStatusResults(); + // + // + // + bool is_audio_cd; + uint32 data_track_fad; + + is_audio_cd = true; + + // TODO: Check DrivePhase == DRIVEPHASE_STARTUP + for(int32 track = toc.first_track; track <= toc.last_track; track++) + { + if(toc.tracks[track].control & SUBQ_CTRLF_DATA) + { + data_track_fad = 150 + toc.tracks[track].lba; + is_audio_cd = false; + break; + } + } + + if(is_audio_cd) + { + AuthDiscType = 0x01; //0x04; + CMD_EAT_CLOCKS(200); + TriggerIRQ(HIRQ_EFLS); + } + else + { + SetCDDeviceConn(fnum); + Filter_SetTrueConn(fnum, fnum); + Filter_SetFalseConn(fnum, 0xFF); + Filter_SetRange(fnum, 0, 0); + Filters[fnum].Mode = 0; + + FLS.pnum = fnum; + FLS.DoAuth = true; + FLS.Active = true; + + ClearPendingSec(); + StartSeek(0x800000 | (data_track_fad + 16)); + + CurPlayEnd = 0; + CurPlayRepeat = 0; + PlayRepeatCounter = 0; + } + } + } + // + // + // + else if(CTR.Command == COMMAND_GET_AUTH) + { + if(FLS.Active && FLS.DoAuth) + CDStatusResults(true); + else + BasicResults(MakeBaseStatus() << 8, AuthDiscType, 0, 0); + } + // + // + // + else if(CTR.Command == COMMAND_SET_CDDEVCONN) // = 0x30, + { + #define fnum (CTR.CD[2] >> 8) + + if(fnum >= 0x18 && fnum != 0xFF) + CDStatusResults(true); + else + { + SetCDDeviceConn(fnum); + + CDStatusResults(); + + CMD_EAT_CLOCKS(96); + TriggerIRQ(HIRQ_ESEL); + } + #undef fnum + } + // + // + // + else if(CTR.Command == COMMAND_GET_CDDEVCONN) // = 0x31, + { + BasicResults((MakeBaseStatus() << 8), 0, CDDevConn << 8, 0); + } + // + // + // + else if(CTR.Command == COMMAND_GET_LASTBUFDST) // = 0x32, + { + BasicResults(MakeBaseStatus() << 8, 0, LastBufDest << 8, 0); + } + // + // + // + else if(CTR.Command == COMMAND_SET_FILTRANGE) // = 0x40, + { + #define fnum (CTR.CD[2] >> 8) + + if(fnum >= 0x18) + CDStatusResults(true); + else + { + { + const uint32 fad = ((CTR.CD[0] & 0xFF) << 16) | CTR.CD[1]; + const uint32 range = ((CTR.CD[2] & 0xFF) << 16) | CTR.CD[3]; + + Filter_SetRange(fnum, fad, range); + + CDStatusResults(); + } + CMD_EAT_CLOCKS(96); + TriggerIRQ(HIRQ_ESEL); + } + #undef fnum + } + // + // + // + else if(CTR.Command == COMMAND_GET_FILTRANGE) // = 0x41, + { + const unsigned fnum = CTR.CD[2] >> 8; + + if(fnum >= 0x18) + CDStatusResults(true); + else + { + const uint32 fad = Filters[fnum].FAD; + const uint32 range = Filters[fnum].Range; + + BasicResults((MakeBaseStatus() << 8) | (fad >> 16), + fad, + (fnum << 8) | (range >> 16), + range); + } + } + // + // + // + else if(CTR.Command == COMMAND_SET_FILTSUBHC) // = 0x42, + { + #define fnum (CTR.CD[2] >> 8) + + if(fnum >= 0x18) + CDStatusResults(true); + else + { + Filters[fnum].Channel = CTR.CD[0] & 0xFF; + Filters[fnum].SubModeMask = CTR.CD[1] >> 8; + Filters[fnum].CInfoMask = CTR.CD[1] & 0xFF; + Filters[fnum].File = CTR.CD[2] & 0xFF; + Filters[fnum].SubMode = CTR.CD[3] >> 8; + Filters[fnum].CInfo = CTR.CD[3] & 0xFF; + + CDStatusResults(); + + CMD_EAT_CLOCKS(96); + TriggerIRQ(HIRQ_ESEL); + } + #undef fnum + } + // + // + // + else if(CTR.Command == COMMAND_GET_FILTSUBHC) // = 0x43, + { + const unsigned fnum = CTR.CD[2] >> 8; + + if(fnum >= 0x18) + CDStatusResults(true); + else + { + const auto& f = Filters[fnum]; + + BasicResults((MakeBaseStatus() << 8) | f.Channel, + (f.SubModeMask << 8) | f.CInfoMask, + (fnum << 8) | f.File, + (f.SubMode << 8) | f.CInfo); + } + } + // + // + // + else if(CTR.Command == COMMAND_SET_FILTMODE) // = 0x44, + { + #define fnum (CTR.CD[2] >> 8) + + if(fnum >= 0x18) + CDStatusResults(true); + else + { + Filters[fnum].Mode = CTR.CD[0] & 0xFF; + + if(CTR.CD[0] & 0x80) + Filter_ResetCond(fnum); + + CDStatusResults(); + + CMD_EAT_CLOCKS(96); + TriggerIRQ(HIRQ_ESEL); + } + #undef fnum + } + // + // + // + else if(CTR.Command == COMMAND_GET_FILTMODE) // = 0x45, + { + const unsigned fnum = CTR.CD[2] >> 8; + + if(fnum >= 0x18) + CDStatusResults(true); + else + BasicResults((MakeBaseStatus() << 8) | Filters[fnum].Mode, + 0, + fnum << 8, + 0); + } + // + // + // + else if(CTR.Command == COMMAND_SET_FILTCONN) // = 0x46, + { + #define fnum (CTR.CD[2] >> 8) + #define fcflags (CTR.CD[0] & 0xFF) + #define tconn (CTR.CD[1] >> 8) + #define fconn (CTR.CD[1] & 0xFF) + + if(fnum >= 0x18 || ((fcflags & 0x1) && (tconn >= 0x18) && tconn != 0xFF) || ((fcflags & 0x2) && (fconn >= 0x18) && fconn != 0xFF)) + CDStatusResults(true); + else + { + if(fcflags & 0x1) + Filter_SetTrueConn(fnum, tconn); + + if(fcflags & 0x2) + Filter_SetFalseConn(fnum, fconn); + + CDStatusResults(); + + CMD_EAT_CLOCKS(96); + TriggerIRQ(HIRQ_ESEL); + } + #undef fconn + #undef tconn + #undef fcflags + #undef fnum + } + // + // + // + else if(CTR.Command == COMMAND_GET_FILTCONN) // = 0x47, + { + const unsigned fnum = CTR.CD[2] >> 8; + + if(fnum >= 0x18) + CDStatusResults(true); + else + { + const auto& f = Filters[fnum]; + + BasicResults((MakeBaseStatus() << 8), + (f.TrueConn << 8) | f.FalseConn, + fnum << 8, + 0); + } + } + // + // + // + else if(CTR.Command == COMMAND_RESET_SEL) // = 0x48, + { + unsigned rflags; + + rflags = CTR.CD[0] & 0xFF; + + if(!rflags) + { + unsigned pnum; + + pnum = CTR.CD[2] >> 8; + + if(pnum >= 0x18) + CDStatusResults(true); + else + { + Partition_Clear(pnum); + + CDStatusResults(); + // + // + // + CMD_EAT_CLOCKS(150); + TriggerIRQ(HIRQ_ESEL); + } + } + else + { + for(unsigned pnum = 0; pnum < 0x18; pnum++) + { + if(rflags & 0x04) // Initialize all partition data + { + Partition_Clear(pnum); + } + + if(rflags & 0x08) // Initialize all partition output connectors? ? ? + { + + } + + if(rflags & 0x10) // Initialize all filter conditions + { + Filter_ResetCond(pnum); + } + + if(rflags & 0x20) // Initialize all filter input connectors? ? ? + { + if(pnum == CDDevConn) + CDDevConn = 0xFF; + + if(Filters[pnum].FalseConn < 0x18) + Filters[pnum].FalseConn = 0xFF; + } + + if(rflags & 0x40) // Initialize all true output connectors + { + Filters[pnum].TrueConn = pnum; + } + + if(rflags & 0x80) // Initialize all false output connectors + { + Filters[pnum].FalseConn = 0xFF; + } + } + CDStatusResults(); + // + // + // + // TODO: Accurate timing(while not blocking other command execution and sector reading). + CMD_EAT_CLOCKS(300); + TriggerIRQ(HIRQ_ESEL); + } + } + // + // + // + else if(CTR.Command == COMMAND_GET_BUFSIZE) // = 0x50, + { + BasicResults(MakeBaseStatus() << 8, + FreeBufferCount, + 0x18 << 8, + NumBuffers); + } + // + // + // + else if(CTR.Command == COMMAND_GET_SECNUM) // = 0x51, + { + const unsigned pnum = CTR.CD[2] >> 8; + + if(pnum >= 0x18) + { + CDStatusResults(true); + } + else + { + BasicResults(MakeBaseStatus() << 8, + 0, + 0, + Partitions[pnum].Count); + } + } + // + // + // + else if(CTR.Command == COMMAND_CALC_ACTSIZE) // = 0x52, + { + unsigned pnum; + int offs, numsec; + + offs = CTR.CD[1]; + pnum = CTR.CD[2] >> 8; + numsec = CTR.CD[3]; + + if(pnum >= 0x18) + CDStatusResults(true); + else + { + offs = CTR.CD[1]; + numsec = CTR.CD[3]; + + if(offs == 0xFFFF) + offs = Partitions[pnum].Count - 1; + + if(numsec == 0xFFFF) + numsec = Partitions[pnum].Count - offs; + + if((DT.Active && DT.Writing) || numsec <= 0 || offs < 0 || (offs + numsec) > (int)Partitions[pnum].Count) + CDStatusResults(false, STATUS_WAIT); + else + { + CDStatusResults(); + + // + { + uint32 tmp_accum = 0; + for(int i = 0, bfi = Partition_GetBuffer(pnum, offs); i < numsec; i++, bfi = Buffers[bfi].Next) + { + const uint8* const sd = Buffers[bfi].Data; + + switch(GetSecLen) + { + default: + case SECLEN_2048: + if((sd[12 + 3] == 0x2) && (sd[16 + 2] & 0x20)) // Mode 2 Form 2 + tmp_accum += 1162; + else // M2F1 and Mode 1(weird tested inconsistency with Get Sector Data command, not that it probably matters) + tmp_accum += 1024; + break; + + case SECLEN_2336: tmp_accum += 1168; break; + case SECLEN_2340: tmp_accum += 1170; break; + case SECLEN_2352: tmp_accum += 1176; break; + } + } + CalcedActualSize = tmp_accum; + } + // + CMD_EAT_CLOCKS(240); // TODO: proper timing(can be surprisingly large for higher numsec) + TriggerIRQ(HIRQ_ESEL); + } + } + } + // + // + // + else if(CTR.Command == COMMAND_GET_ACTSIZE) // = 0x53, + { + BasicResults((MakeBaseStatus() << 8) | (CalcedActualSize >> 16), CalcedActualSize, 0, 0); + } + // + // + // + else if(CTR.Command == COMMAND_GET_SECINFO) // = 0x54, + { + unsigned offs; + unsigned pnum; + + offs = CTR.CD[1]; + pnum = CTR.CD[2] >> 8; + + if(pnum >= 0x18 || (offs != 0xFFFF && offs >= Partitions[pnum].Count) || Partitions[pnum].Count == 0) + CDStatusResults(true); + else + { + const int bfi = ((offs == 0xFFFF) ? Partitions[pnum].LastBuf : Partition_GetBuffer(pnum, offs)); + const uint8* sd = Buffers[bfi].Data; + uint32 fad; + uint8 file = 0, chan = 0, submode = 0, cinfo = 0; + + fad = AMSF_to_ABA(BCD_to_U8(sd[12 + 0]), BCD_to_U8(sd[12 + 1]), BCD_to_U8(sd[12 + 2])); + if(sd[12 + 3] == 0x2) + { + file = sd[16]; + chan = sd[17]; + submode = sd[18]; + cinfo = sd[19]; + } + + BasicResults((MakeBaseStatus() << 8) | (fad >> 16), + fad, + (file << 8) | chan, + (submode << 8) | cinfo); + } + } + // + // + // + else if(CTR.Command == COMMAND_EXEC_FADSRCH) // = 0x55, + { + unsigned offs; + unsigned pnum; + uint32 sfad; + + offs = CTR.CD[1]; + pnum = CTR.CD[2] >> 8; + sfad = ((CTR.CD[2] & 0xFF) << 16) | CTR.CD[3]; + + if(pnum >= 0x18 || (offs != 0xFFFF && offs >= Partitions[pnum].Count) || Partitions[pnum].Count == 0) + CDStatusResults(true); + else + { + int counter; + int effoffs, bfi; + bool match_made; + + FADSearch.spos = 0xFFFF; + FADSearch.pnum = pnum; + FADSearch.fad = 0; + + counter = 0; + effoffs = (offs == 0xFFFF) ? (Partitions[pnum].Count - 1) : offs; + bfi = Partitions[pnum].FirstBuf; + match_made = false; + + do + { + if(counter >= effoffs) + { + const uint8* sd = Buffers[bfi].Data; + const uint32 fad = AMSF_to_ABA(BCD_to_U8(sd[12 + 0]), BCD_to_U8(sd[12 + 1]), BCD_to_U8(sd[12 + 2])); + + if(fad <= sfad && fad >= (FADSearch.fad + match_made)) + { + FADSearch.spos = counter; + FADSearch.fad = fad; + match_made = true; + } + } + bfi = Buffers[bfi].Next; + counter++; + } while(bfi != 0xFF); + + CDStatusResults(); + // + // + // + CMD_EAT_CLOCKS(300); + TriggerIRQ(HIRQ_ESEL); + } + } + // + // + // + else if(CTR.Command == COMMAND_GET_FADSRCH) // = 0x56, + { + BasicResults(MakeBaseStatus() << 8, FADSearch.spos, (FADSearch.pnum << 8) | (FADSearch.fad >> 16), FADSearch.fad); + } + // + // + // + else if(CTR.Command == COMMAND_SET_SECLEN) // = 0x60, + { + const unsigned NewGetSecLen = (CTR.CD[0] & 0xFF); + const unsigned NewPutSecLen = (CTR.CD[1] >> 8); + const bool NewGetSecLenBad = NewGetSecLen != 0xFF && (NewGetSecLen < SECLEN__FIRST || NewGetSecLen > SECLEN__LAST); + const bool NewPutSecLenBad = NewPutSecLen != 0xFF && (NewPutSecLen < SECLEN__FIRST || NewPutSecLen > SECLEN__LAST); + + if(NewGetSecLenBad || NewPutSecLenBad) + { + CDStatusResults(true); + } + else + { + if(NewGetSecLen != 0xFF) + GetSecLen = NewGetSecLen; + + if(NewPutSecLen != 0xFF) + PutSecLen = NewPutSecLen; + + CDStatusResults(); + TriggerIRQ(HIRQ_ESEL); + } + } + // + // + // + else if(CTR.Command == COMMAND_GET_SECDATA || CTR.Command == COMMAND_DEL_SECDATA || CTR.Command == COMMAND_GETDEL_SECDATA) // = 0x61, 0x62, 0x63 + { + unsigned pnum; + int offs, numsec; + + pnum = CTR.CD[2] >> 8; + if(pnum >= 0x18) + CDStatusResults(true); + else + { + offs = CTR.CD[1]; + numsec = CTR.CD[3]; + + if(offs == 0xFFFF) + offs = Partitions[pnum].Count - 1; + + if(numsec == 0xFFFF) + numsec = Partitions[pnum].Count - offs; + + if((DT.Active && CTR.Command != COMMAND_DEL_SECDATA) || numsec <= 0 || offs < 0 || (offs + numsec) > (int)Partitions[pnum].Count) + CDStatusResults(false, STATUS_WAIT); + else + { + int sbfi; + + sbfi = Partition_GetBuffer(pnum, offs); + + if(CTR.Command != COMMAND_DEL_SECDATA) + { + for(int i = 0, bfi = sbfi; i < numsec; i++) + { + const int next_bfi = Buffers[bfi].Next; + DT.BufList[i] = bfi; + if(CTR.Command == COMMAND_GETDEL_SECDATA) + Partition_UnlinkBuffer(pnum, bfi); + bfi = next_bfi; + } + + CDStatusResults(false, STATUS_DTREQ); + + DT.Writing = false; + DT.NeedBufFree = (CTR.Command == COMMAND_GETDEL_SECDATA); + DT.CurBufIndex = 0; + DT.BufCount = numsec; + + DT_SetIBOffsCount(Buffers[DT.BufList[0]].Data); + + DT.TotalCounter = 0; + + DT.FIFO_RP = 0; + DT.FIFO_WP = 0; + DT.FIFO_In = 0; + + for(unsigned i = 0; i < 5; i++) + DT_ReadIntoFIFO(); + + DT.Active = true; + } + else + CDStatusResults(); + + // + // + // + if(CTR.Command == COMMAND_DEL_SECDATA) + { + for(int i = 0, bfi = sbfi; i < numsec; i++) + { + const int next_bfi = Buffers[bfi].Next; + Partition_UnlinkBuffer(pnum, bfi); + Buffer_Free(bfi); + bfi = next_bfi; + } + + CMD_EAT_CLOCKS(485); + TriggerIRQ(HIRQ_EHST); + } + else + { + CMD_EAT_CLOCKS(460); + TriggerIRQ(HIRQ_DRDY); + } + } + } + } + // + // + // + else if(CTR.Command == COMMAND_PUT_SECDATA) // = 0x64, + { + unsigned fnum, numsec; + + fnum = CTR.CD[2] >> 8; + numsec = CTR.CD[3]; + + if(fnum >= 0x18) + { + CDStatusResults(true); + } + else if(numsec == 0 || numsec > FreeBufferCount || DT.Active) + { + CDStatusResults(false, STATUS_WAIT); + } + else + { + if(CDDevConn == fnum) + CDDevConn = 0xFF; + + CDStatusResults(false, STATUS_DTREQ); + + DT.Writing = true; + DT.NeedBufFree = false; + DT.FNum = fnum; + DT.CurBufIndex = 0; + for(unsigned i = 0; i < numsec; i++) + { + DT.BufList[i] = Buffer_Allocate(true); + } + + DT.BufCount = numsec; + + DT_SetIBOffsCount(NULL); + + DT.TotalCounter = 0; + + DT.FIFO_RP = 0; + DT.FIFO_WP = 0; + DT.FIFO_In = 0; + DT.Active = true; + // + // + // + CMD_EAT_CLOCKS(300); + TriggerIRQ(HIRQ_DRDY); + } + } + // + // + // + else if(CTR.Command == COMMAND_COPY_SECDATA || CTR.Command == COMMAND_MOVE_SECDATA) // = 0x65, =0x66 + { + unsigned dst_fnum, src_pnum; + + dst_fnum = CTR.CD[0] & 0xFF; + src_pnum = CTR.CD[2] >> 8; + + if(src_pnum >= 0x18 || dst_fnum >= 0x18) + CDStatusResults(true); + else + { + int src_offs, numsec; + + src_offs = CTR.CD[1]; + numsec = CTR.CD[3]; + + if(src_offs == 0xFFFF) + src_offs = Partitions[src_pnum].Count - 1; + + if(numsec == 0xFFFF) + numsec = Partitions[src_pnum].Count - src_offs; + + if(DT.Active || numsec <= 0 || (numsec > (int)FreeBufferCount && CTR.Command != COMMAND_MOVE_SECDATA) || src_offs < 0 || (src_offs + numsec) > (int)Partitions[src_pnum].Count) + CDStatusResults(false, STATUS_WAIT); + else + { + if(CDDevConn == dst_fnum) + CDDevConn = 0xFF; + + for(int i = 0, bfi = Partition_GetBuffer(src_pnum, src_offs); i < numsec; i++) + { + const uint8* bufdata = Buffers[bfi].Data; + const int next_bfi = Buffers[bfi].Next; + + if(CTR.Command == COMMAND_MOVE_SECDATA) + { + Partition_UnlinkBuffer(src_pnum, bfi); + FilterBuf(dst_fnum, bfi); + } + else + { + int abfi = Buffer_Allocate(false); + + memcpy(Buffers[abfi].Data, bufdata, sizeof(Buffers[abfi].Data)); + + FilterBuf(dst_fnum, abfi); + } + + bfi = next_bfi; + } + CDStatusResults(); + // + // + // TODO: Accurate timing(while not blocking other command execution and sector reading). Note that "move sector data" is much faster than "copy sector data". + CMD_EAT_CLOCKS(300); + if(FreeBufferCount == 0) + TriggerIRQ(HIRQ_BFUL); + TriggerIRQ(HIRQ_ECPY); + } + } + } + // + // + // + else if(CTR.Command == COMMAND_GET_COPYERR) // = 0x67, + { + // TODO: Implement if we ever implement proper asynch copy/moving + BasicResults((MakeBaseStatus() << 8) | 0x00, 0, 0, 0); + } + // + // + // + else if(CTR.Command == COMMAND_CHANGE_DIR) // = 0x70, + { + bool reject; + uint8 fnum; + uint32 fileid; + uint32 fiaoffs; + + fnum = (CTR.CD[2] >> 8); + fileid = ((CTR.CD[2] & 0xFF) << 16) | CTR.CD[3]; + fiaoffs = (fileid < 2) ? fileid : (2 + fileid - FLS.FileInfoOffs); + + reject = false; + + if(fnum >= 0x18) + reject = true; + + if(fileid == 0xFFFFFF) + { + if(!RootDirInfoValid) + reject = true; + } + else + { + if(!FileInfoValid) + reject = true; + else if(fileid >= 2 && (fileid < FLS.FileInfoOffs || fileid >= (FLS.FileInfoOffs + FLS.FileInfoValidCount))) + reject = true; + else if(!(FileInfo[fiaoffs].attr & 0x2)) // FIXME: test XA directory flag too? + reject = true; + } + + if(FLS.Active) + CDStatusResults(false, STATUS_WAIT); + else if(reject) + CDStatusResults(true); + else if(fileid == 0) // NOP, kind of apparently(test after READ_DIR with a largeish file start id)... + { + CDStatusResults(); + CMD_EAT_CLOCKS(400); + TriggerIRQ(HIRQ_EFLS); + } + else + { + CDStatusResults(); + // + // Check (attr & 2) first? and & 0x80 for XA? + // + const FileInfoS* fi; + + if(fileid == 0xFFFFFF) + fi = &RootDirInfo; + else + fi = &FileInfo[fiaoffs]; + + Partition_Clear(fnum); + + SetCDDeviceConn(fnum); + Filter_SetTrueConn(fnum, fnum); + Filter_SetFalseConn(fnum, 0xFF); + Filter_SetRange(fnum, fi->fad(), (fi->size() + 2047) >> 11); // TODO: maybe remove + 2047, actual Saturn drive seems buggy... + Filters[fnum].Mode = FilterS::MODE_SEL_FADR; + Filters[fnum].File = fi->fnum; + + Filters[fnum].Channel = 0; + Filters[fnum].SubMode = 0; + Filters[fnum].SubModeMask = 0; + Filters[fnum].CInfo = 0; + Filters[fnum].CInfoMask = 0; + + FLS.pnum = fnum; + FLS.total_max = fi->size(); + FLS.FileInfoOffs = 2; + FLS.DoAuth = false; + FLS.Active = true; + + ClearPendingSec(); + StartSeek(0x800000 | fi->fad()); + + CurPlayEnd = 0; + CurPlayRepeat = 0; + PlayRepeatCounter = 0; + } + } + // + // + // + else if(CTR.Command == COMMAND_READ_DIR) // = 0x71, + { + uint8 fnum; + uint32 start_fileid; + + fnum = (CTR.CD[2] >> 8); + start_fileid = ((CTR.CD[2] & 0xFF) << 16) | CTR.CD[3]; + + if(FLS.Active) + CDStatusResults(false, STATUS_WAIT); + else if(fnum >= 0x18 || !FileInfoValid) + CDStatusResults(true); + else + { + CDStatusResults(); + // + // Check (attr & 2) first? and & 0x80 for XA? + // + const FileInfoS* fi = &FileInfo[0]; + + if(start_fileid < FLS.FileInfoOffs || start_fileid >= (FLS.FileInfoOffs + FLS.FileInfoValidCount)) + start_fileid = 2; + + SetCDDeviceConn(fnum); + Filter_SetTrueConn(fnum, fnum); + Filter_SetFalseConn(fnum, 0xFF); + Filter_SetRange(fnum, fi->fad(), (fi->size() + 2047) >> 11); + Filters[fnum].Mode = FilterS::MODE_SEL_FADR; + + FLS.pnum = fnum; + FLS.total_max = fi->size(); + FLS.FileInfoOffs = start_fileid; + FLS.DoAuth = false; + FLS.Active = true; + + ClearPendingSec(); + StartSeek(0x800000 | fi->fad()); + + CurPlayEnd = 0; + CurPlayRepeat = 0; + PlayRepeatCounter = 0; + } + } + // + // + // + else if(CTR.Command == COMMAND_GET_FSSCOPE) // = 0x72, + { + if(FLS.Active) // Maybe add a specific check for directory reading? (Will have to if we chain READ_FILE into FLS.Active someday for whatever reason) + CDStatusResults(false, STATUS_WAIT); + else if(!FileInfoValid) + CDStatusResults(true); + else + { + // FIXME: Not sure about the [0].fad == [1].fad root dir thing... Might instead be 0x01 to note that the number of files in the directory + // can be held without using Read Directory? + BasicResults((MakeBaseStatus() << 8), + FLS.FileInfoValidCount, + ((FileInfo[0].fad() == FileInfo[1].fad()) << 8) | (FLS.FileInfoOffs >> 16), + FLS.FileInfoOffs); + } + } + // + // + // + else if(CTR.Command == COMMAND_GET_FINFO) // = 0x73, + { + if(FLS.Active || DT.Active) + CDStatusResults(false, STATUS_WAIT); + else if(!FileInfoValid) + CDStatusResults(true); + else + { + uint32 fileid; + + fileid = ((CTR.CD[2] & 0xFF) << 16) | CTR.CD[3]; + + if(fileid != 0xFFFFFF && (fileid >= 2 && (fileid < FLS.FileInfoOffs || fileid >= (FLS.FileInfoOffs + FLS.FileInfoValidCount)))) + CDStatusResults(true); + else + { + { + const uint32 fiaoffs = (fileid < 2) ? fileid : (2 + fileid - FLS.FileInfoOffs); + + DT.CurBufIndex = 0; + DT.BufCount = 1; + + if(fileid == 0xFFFFFF) + { + DT.InBufOffs = 6 * 2; + DT.InBufCounter = 6 * FLS.FileInfoValidCount; + } + else + { + DT.InBufOffs = 6 * fiaoffs; + DT.InBufCounter = 6; + } + + DT.TotalCounter = 0; + + DT.FIFO_RP = 0; + DT.FIFO_WP = 0; + DT.FIFO_In = 0; + + DT.BufList[0] = 0xF0; + + DT.Writing = false; + DT.NeedBufFree = false; + DT.Active = true; + + BasicResults(MakeBaseStatus(false, STATUS_DTREQ) << 8, DT.InBufCounter, 0, 0); + } + // + // + // + CMD_EAT_CLOCKS(128); + TriggerIRQ(HIRQ_DRDY); + } + } + } + // + // + // + else if(CTR.Command == COMMAND_READ_FILE) // = 0x74, + { + uint32 offset; + uint32 fileid; + uint8 fnum; + + offset = ((CTR.CD[0] & 0xFF) << 16) | CTR.CD[1]; + fileid = ((CTR.CD[2] & 0xFF) << 16) | CTR.CD[3]; + fnum = CTR.CD[2] >> 8; + + if(FLS.Active) + CDStatusResults(false, STATUS_WAIT); + else if(fnum >= 0x18 || !FileInfoValid || (fileid >= 2 && (fileid < FLS.FileInfoOffs || fileid >= (FLS.FileInfoOffs + FLS.FileInfoValidCount)))) + CDStatusResults(true); + else + { + CDStatusResults(); + + Partition_Clear(fnum); + + //printf("DT Meow READ: 0x%08x 0x%08x --- offs=0x%08x\n", FileInfo[fileid].fad(), FileInfo[fileid].size(), offset); + const uint32 fiaoffs = (fileid < 2) ? fileid : (2 + fileid - FLS.FileInfoOffs); + uint32 start_fad = (FileInfo[fiaoffs].fad() + offset) & 0xFFFFFF; + uint32 sec_count = ((FileInfo[fiaoffs].size() + 2047) >> 11) - offset; // FIXME: Check offset versus ifile size. + + ClearPendingSec(); + StartSeek(start_fad | 0x800000); + + PlayEndIRQType = HIRQ_EFLS; + CurPlayEnd = 0x800000 | ((start_fad + sec_count) & 0x7FFFFF); + CurPlayRepeat = 0; + PlayRepeatCounter = 0; + + SetCDDeviceConn(fnum); + Filter_SetTrueConn(fnum, fnum); + Filter_SetFalseConn(fnum, 0xFF); + Filter_SetRange(fnum, start_fad, sec_count); // Not sure if correct for XA interleaved files... + + Filters[fnum].Mode = FilterS::MODE_SEL_FADR | FilterS::MODE_SEL_FILE; + Filters[fnum].File = FileInfo[fiaoffs].fnum; + + Filters[fnum].Channel = 0; + Filters[fnum].SubMode = 0; + Filters[fnum].SubModeMask = 0; + Filters[fnum].CInfo = 0; + Filters[fnum].CInfoMask = 0; + } + } + // + // + // + else if(CTR.Command == COMMAND_ABORT_FILE) // = 0x75, + { + // TODO: Does tray opening during a file operation trigger HIRQ_EFLS? + CDStatusResults(); + + FLS.Abort = true; + } + else + { + SS_DBG(SS_DBG_WARNING | SS_DBG_CDB, "[CDB] Unknown Command: 0x%04x 0x%04x 0x%04x 0x%04x --- HIRQ=0x%04x, HIRQ_Mask=0x%04x\n", CTR.CD[0], CTR.CD[1], CTR.CD[2], CTR.CD[3], HIRQ, HIRQ_Mask); + + ResultsRead = false; + CommandPending = false; + } + continue; + // + // + // + case -1 + CommandPhaseBias: + + CMD_EAT_CLOCKS(4880000); + + StandbyTime = 0; + ECCEnable = 0xFF; + RetryCount = 1; + CommandPending = false; + ResultsRead = true; + + memset(&DT, 0, sizeof(DT)); + + PlayCmdStartPos = 0; // TODO: Test for correct value. + PlayCmdEndPos = 0; // TODO: Test for correct value. + PlayCmdRepCnt = 0; // TODO: ... + + CurPlayRepeat = 0; // TODO: . . . + PlayRepeatCounter = 0; + + DriveCounter = (int64)1000 << 32; + DrivePhase = DRIVEPHASE_EJECTED_WAITING; + + memset(TOC_Buffer, 0xFF, sizeof(TOC_Buffer)); // TODO: confirm 0xFF(or 0x00?) + + AuthDiscType = 0x00; + FileInfoValid = false; + RootDirInfoValid = false; + PeriodicIdleCounter = PeriodicIdleCounter_Reload; + + CurPosInfo.status = STATUS_OPEN; + CurPosInfo.is_cdrom = false; + CurPosInfo.fad = 0xFFFFFF; + CurPosInfo.rel_fad = 0xFFFFFF; + CurPosInfo.ctrl_adr = 0xFF; + CurPosInfo.idx = 0xFF; + CurPosInfo.tno = 0xFF; + + CDDABuf_WP = 0; + CDDABuf_RP = 0; + CDDABuf_Count = 0; + + // + // + RootDirInfoValid = false; + // + // + SWReset(); + + CurPosInfo.status = STATUS_BUSY; // FIXME(so it's set long enough from POV of program) + CurPosInfo.is_cdrom = false; + CurSector = 0; + + Results[0] = 0x0043; + Results[1] = 0x4442; + Results[2] = 0x4c4f; + Results[3] = 0x434b; + ResultsRead = false; + TriggerIRQ(HIRQ_CMOK | HIRQ_DCHG | HIRQ_ESEL | HIRQ_EHST | HIRQ_MPED | HIRQ_ECPY | HIRQ_EFLS); + continue; + } + } + CommandGetOut:; + // + // + // + + //RunFLS(clocks); + } + + + assert(DriveCounter > 0); + + { + int64 net = -CommandClockCounter; + + if(DriveCounter < net) + net = DriveCounter; + + if(PeriodicIdleCounter < net) + net = PeriodicIdleCounter; + + return timestamp + (net + CDB_ClockRatio - 1) / CDB_ClockRatio; + } +} + +void CDB_ResetTS(void) +{ + lastts = 0; +} + + +uint16 CDB_Read(uint32 offset) +{ + uint16 ret = 0; //0xFFFF; + +#if 1 + if(offset >= 0x6 && offset <= 0x9 && CommandPending) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_CDB, "[CDB] Read from register 0x%01x while busy processing command!\n", offset); + } +#endif + + switch(offset) + { + case 0x0: + if(DT.Active && !DT.Writing) + { + if(DT.InBufCounter > 0) + DT_ReadIntoFIFO(); + + if(MDFN_UNLIKELY(!DT.FIFO_In)) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_CDB, "[CDB] DT FIFO underflow.\n"); + } + + ret = DT.FIFO[DT.FIFO_RP]; + DT.FIFO_RP = (DT.FIFO_RP + 1) % (sizeof(DT.FIFO) / sizeof(DT.FIFO[0])); + DT.FIFO_In -= (bool)DT.FIFO_In; + } + break; + + case 0x2: // HIRQ + ret = HIRQ; + break; + + case 0x3: // HIRQ mask + ret = HIRQ_Mask; + break; + + case 0x6: ret = Results[0]; /*if(!ResultsRead) printf(" [CDB] Result0 Read: 0x%04x\n", ret);*/ break; + case 0x7: ret = Results[1]; /*if(!ResultsRead) printf(" [CDB] Result1 Read: 0x%04x\n", ret);*/ break; + case 0x8: ret = Results[2]; /*if(!ResultsRead) printf(" [CDB] Result2 Read: 0x%04x\n", ret);*/ break; + case 0x9: ret = Results[3]; /*if(!ResultsRead) printf(" [CDB] Result3 Read: 0x%04x\n", ret);*/ ResultsRead = true; break; + } + + //if(offset == 0) + // fprintf(stderr, "Read: %02x %04x\n", offset, ret); + + return ret; +} + +void CDB_Write_DBM(uint32 offset, uint16 DB, uint16 mask) +{ + sscpu_timestamp_t nt = CDB_Update(SH7095_mem_timestamp); + + //SS_DBG(SS_DBG_WARNING | SS_DBG_CDB, "[CDB] Write %02x %04x %04x\n", offset, DB, mask); + +#if 1 + if(offset >= 0x6 && offset <= 0x9 && CommandPending) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_CDB, "[CDB] Write to register 0x%01x(DB=0x%04x, mask=0x%04x) while busy processing command!\n", offset, DB, mask); + } +#endif + + switch(offset) + { + case 0x0: + if(DT.Active && DT.Writing) + { + if(DT.InBufCounter > 0) + { + DT.FIFO[DT.FIFO_WP] = (DT.FIFO[DT.FIFO_WP] &~ mask) | (DB & mask); + DT.FIFO_WP = (DT.FIFO_WP + 1) % (sizeof(DT.FIFO) / sizeof(DT.FIFO[0])); + DT.FIFO_In++; + + MDFN_en16msb(&Buffers[DT.BufList[DT.CurBufIndex]].Data[DT.InBufOffs << 1], DT.FIFO[DT.FIFO_RP]); + DT.InBufOffs++; + DT.FIFO_RP = (DT.FIFO_RP + 1) % (sizeof(DT.FIFO) / sizeof(DT.FIFO[0])); + DT.FIFO_In--; + + DT.InBufCounter--; + DT.TotalCounter++; + + if(!DT.InBufCounter) + { + DT.CurBufIndex++; + if(DT.CurBufIndex < DT.BufCount) + { + DT_SetIBOffsCount(NULL); + } + } + } + } + break; + + case 0x2: + HIRQ = HIRQ & (DB | ~mask); + RecalcIRQOut(); + break; + + case 0x3: + HIRQ_Mask = (HIRQ_Mask &~ mask) | (DB & mask); + RecalcIRQOut(); + break; + + case 0x6: + CData[0] = (CData[0] &~ mask) | (DB & mask); + break; + + case 0x7: + CData[1] = (CData[1] &~ mask) | (DB & mask); + break; + + case 0x8: + CData[2] = (CData[2] &~ mask) | (DB & mask); + break; + + case 0x9: + CData[3] = (CData[3] &~ mask) | (DB & mask); + if(mask == 0xFFFF) + { + CommandPending = true; + nt = SH7095_mem_timestamp + 1; + } + break; + } + + SS_SetEventNT(&events[SS_EVENT_CDB], nt); +} + + + + +} diff --git a/waterbox/ss/cdb.h b/waterbox/ss/cdb.h new file mode 100644 index 0000000000..beb643c3e8 --- /dev/null +++ b/waterbox/ss/cdb.h @@ -0,0 +1,51 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* cdb.h: +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_CDB_H +#define __MDFN_SS_CDB_H + +class CDIF; + +namespace MDFN_IEN_SS +{ + +void CDB_Init(void) MDFN_COLD; + +void CDB_SetDisc(bool tray_open, CDIF *cdif) MDFN_COLD; + +void CDB_Write_DBM(uint32 offset, uint16 DB, uint16 mask) MDFN_HOT; +uint16 CDB_Read(uint32 offset) MDFN_HOT; + +void CDB_Reset(bool powering_up) MDFN_COLD; + +sscpu_timestamp_t CDB_Update(sscpu_timestamp_t timestamp); +void CDB_ResetTS(void); + +void CDB_GetCDDA(uint16* outbuf); // writes to outbuf[0] and outbuf[1] + + +void CDB_SetClockRatio(uint32 ratio); +void CDB_ResetCD(void); +void CDB_SetCDActive(bool active); + +} + +#endif diff --git a/waterbox/ss/cdrom/CDUtility.cpp b/waterbox/ss/cdrom/CDUtility.cpp new file mode 100644 index 0000000000..5d097e016d --- /dev/null +++ b/waterbox/ss/cdrom/CDUtility.cpp @@ -0,0 +1,430 @@ +/* Mednafen - Multi-system Emulator + * + * Subchannel Q CRC Code: Copyright (C) 1998 Andreas Mueller + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "defs.h" +#include "CDUtility.h" +#include "dvdisaster.h" +#include "lec.h" + +#include + +namespace CDUtility +{ + +// lookup table for crc calculation +static uint16 subq_crctab[256] = +{ + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, + 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210, + 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B, + 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401, + 0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, + 0xF5CF, 0xC5AC, 0xD58D, 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, + 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, + 0xC7BC, 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 0x5AF5, + 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC, + 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0x6CA6, 0x7C87, 0x4CE4, + 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, + 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, + 0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, + 0x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, + 0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1, + 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB, + 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2, 0x24C3, 0x14A0, + 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8, + 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, + 0x7676, 0x4615, 0x5634, 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, + 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, + 0x28A3, 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 0xFD2E, + 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07, + 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D, + 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74, + 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 +}; + + +static uint8 scramble_table[2352 - 12]; + +static bool CDUtility_Inited = false; + +static void InitScrambleTable(void) +{ + unsigned cv = 1; + + for(unsigned i = 12; i < 2352; i++) + { + unsigned char z = 0; + + for(int b = 0; b < 8; b++) + { + z |= (cv & 1) << b; + + int feedback = ((cv >> 1) & 1) ^ (cv & 1); + cv = (cv >> 1) | (feedback << 14); + } + + scramble_table[i - 12] = z; + } + + //for(int i = 0; i < 2352 - 12; i++) + // printf("0x%02x, ", scramble_table[i]); +} + +void CDUtility_Init(void) +{ + if(!CDUtility_Inited) + { + //Init_LEC_Correct(); + + InitScrambleTable(); + + CDUtility_Inited = true; + } +} + +void encode_mode0_sector(uint32 aba, uint8 *sector_data) +{ + CDUtility_Init(); + + lec_encode_mode0_sector(aba, sector_data); +} + +void encode_mode1_sector(uint32 aba, uint8 *sector_data) +{ + CDUtility_Init(); + + lec_encode_mode1_sector(aba, sector_data); +} + +void encode_mode2_sector(uint32 aba, uint8 *sector_data) +{ + CDUtility_Init(); + + lec_encode_mode2_sector(aba, sector_data); +} + +void encode_mode2_form1_sector(uint32 aba, uint8 *sector_data) +{ + CDUtility_Init(); + + lec_encode_mode2_form1_sector(aba, sector_data); +} + +void encode_mode2_form2_sector(uint32 aba, uint8 *sector_data) +{ + CDUtility_Init(); + + lec_encode_mode2_form2_sector(aba, sector_data); +} + +bool edc_check(const uint8 *sector_data, bool xa) +{ + CDUtility_Init(); + + return(CheckEDC(sector_data, xa)); +} + +bool edc_lec_check_and_correct(uint8 *sector_data, bool xa) +{ + CDUtility_Init(); + + return(ValidateRawSector(sector_data, xa)); +} + + +bool subq_check_checksum(const uint8 *SubQBuf) +{ + uint16 crc = 0; + uint16 stored_crc = 0; + + stored_crc = SubQBuf[0xA] << 8; + stored_crc |= SubQBuf[0xB]; + + for(int i = 0; i < 0xA; i++) + crc = subq_crctab[(crc >> 8) ^ SubQBuf[i]] ^ (crc << 8); + + crc = ~crc; + + return(crc == stored_crc); +} + +void subq_generate_checksum(uint8 *buf) +{ + uint16 crc = 0; + + for(int i = 0; i < 0xA; i++) + crc = subq_crctab[(crc >> 8) ^ buf[i]] ^ (crc << 8); + + // Checksum + buf[0xa] = ~(crc >> 8); + buf[0xb] = ~(crc); +} + +void subq_deinterleave(const uint8 *SubPWBuf, uint8 *qbuf) +{ + memset(qbuf, 0, 0xC); + + for(int i = 0; i < 96; i++) + { + qbuf[i >> 3] |= ((SubPWBuf[i] >> 6) & 0x1) << (7 - (i & 0x7)); + } +} + + +// Deinterleaves 96 bytes of subchannel P-W data from 96 bytes of interleaved subchannel PW data. +void subpw_deinterleave(const uint8 *in_buf, uint8 *out_buf) +{ + assert(in_buf != out_buf); + + memset(out_buf, 0, 96); + + for(unsigned ch = 0; ch < 8; ch++) + { + for(unsigned i = 0; i < 96; i++) + { + out_buf[(ch * 12) + (i >> 3)] |= ((in_buf[i] >> (7 - ch)) & 0x1) << (7 - (i & 0x7)); + } + } + +} + +// Interleaves 96 bytes of subchannel P-W data from 96 bytes of uninterleaved subchannel PW data. +void subpw_interleave(const uint8 *in_buf, uint8 *out_buf) +{ + assert(in_buf != out_buf); + + for(unsigned d = 0; d < 12; d++) + { + for(unsigned bitpoodle = 0; bitpoodle < 8; bitpoodle++) + { + uint8 rawb = 0; + + for(unsigned ch = 0; ch < 8; ch++) + { + rawb |= ((in_buf[ch * 12 + d] >> (7 - bitpoodle)) & 1) << (7 - ch); + } + out_buf[(d << 3) + bitpoodle] = rawb; + } + } +} + +// NOTES ON LEADOUT AREA SYNTHESIS +// +// I'm not trusting that the "control" field for the TOC leadout entry will always be set properly, so | the control fields for the last track entry +// and the leadout entry together before extracting the D2 bit. Audio track->data leadout is fairly benign though maybe noisy(especially if we ever implement +// data scrambling properly), but data track->audio leadout could break things in an insidious manner for the more accurate drive emulation code). +// +void subpw_synth_leadout_lba(const TOC& toc, const int32 lba, uint8* SubPWBuf) +{ + uint8 buf[0xC]; + uint32 lba_relative; + uint32 ma, sa, fa; + uint32 m, s, f; + + lba_relative = lba - toc.tracks[100].lba; + + f = (lba_relative % 75); + s = ((lba_relative / 75) % 60); + m = (lba_relative / 75 / 60); + + fa = (lba + 150) % 75; + sa = ((lba + 150) / 75) % 60; + ma = ((lba + 150) / 75 / 60); + + uint8 adr = 0x1; // Q channel data encodes position + uint8 control = toc.tracks[100].control; + + if(toc.tracks[toc.last_track].valid) + control |= toc.tracks[toc.last_track].control & 0x4; + else if(toc.disc_type == DISC_TYPE_CD_I) + control |= 0x4; + + memset(buf, 0, 0xC); + buf[0] = (adr << 0) | (control << 4); + buf[1] = 0xAA; + buf[2] = 0x01; + + // Track relative MSF address + buf[3] = U8_to_BCD(m); + buf[4] = U8_to_BCD(s); + buf[5] = U8_to_BCD(f); + + buf[6] = 0; // Zerroooo + + // Absolute MSF address + buf[7] = U8_to_BCD(ma); + buf[8] = U8_to_BCD(sa); + buf[9] = U8_to_BCD(fa); + + subq_generate_checksum(buf); + + for(int i = 0; i < 96; i++) + SubPWBuf[i] = (((buf[i >> 3] >> (7 - (i & 0x7))) & 1) ? 0x40 : 0x00) | 0x80; +} + +void synth_leadout_sector_lba(uint8 mode, const TOC& toc, const int32 lba, uint8* out_buf) +{ + memset(out_buf, 0, 2352 + 96); + subpw_synth_leadout_lba(toc, lba, out_buf + 2352); + + if(out_buf[2352 + 1] & 0x40) + { + if(mode == 0xFF) + { + if(toc.disc_type == DISC_TYPE_CD_XA || toc.disc_type == DISC_TYPE_CD_I) + mode = 0x02; + else + mode = 0x01; + } + + switch(mode) + { + default: + encode_mode0_sector(LBA_to_ABA(lba), out_buf); + break; + + case 0x01: + encode_mode1_sector(LBA_to_ABA(lba), out_buf); + break; + + case 0x02: + out_buf[12 + 6] = 0x20; + out_buf[12 + 10] = 0x20; + encode_mode2_form2_sector(LBA_to_ABA(lba), out_buf); + break; + } + } +} + +// ISO/IEC 10149:1995 (E): 20.2 +// +void subpw_synth_udapp_lba(const TOC& toc, const int32 lba, const int32 lba_subq_relative_offs, uint8* SubPWBuf) +{ + uint8 buf[0xC]; + uint32 lba_relative; + uint32 ma, sa, fa; + uint32 m, s, f; + + if(lba < -150 || lba >= 0) + printf("[BUG] subpw_synth_udapp_lba() lba out of range --- %d\n", lba); + + { + int32 lba_tmp = lba + lba_subq_relative_offs; + + if(lba_tmp < 0) + lba_relative = 0 - 1 - lba_tmp; + else + lba_relative = lba_tmp - 0; + } + + f = (lba_relative % 75); + s = ((lba_relative / 75) % 60); + m = (lba_relative / 75 / 60); + + fa = (lba + 150) % 75; + sa = ((lba + 150) / 75) % 60; + ma = ((lba + 150) / 75 / 60); + + uint8 adr = 0x1; // Q channel data encodes position + uint8 control; + + if(toc.disc_type == DISC_TYPE_CD_I && toc.first_track > 1) + control = 0x4; + else if(toc.tracks[toc.first_track].valid) + control = toc.tracks[toc.first_track].control; + else + control = 0x0; + + memset(buf, 0, 0xC); + buf[0] = (adr << 0) | (control << 4); + buf[1] = U8_to_BCD(toc.first_track); + buf[2] = U8_to_BCD(0x00); + + // Track relative MSF address + buf[3] = U8_to_BCD(m); + buf[4] = U8_to_BCD(s); + buf[5] = U8_to_BCD(f); + + buf[6] = 0; // Zerroooo + + // Absolute MSF address + buf[7] = U8_to_BCD(ma); + buf[8] = U8_to_BCD(sa); + buf[9] = U8_to_BCD(fa); + + subq_generate_checksum(buf); + + for(int i = 0; i < 96; i++) + SubPWBuf[i] = (((buf[i >> 3] >> (7 - (i & 0x7))) & 1) ? 0x40 : 0x00) | 0x80; +} + +void synth_udapp_sector_lba(uint8 mode, const TOC& toc, const int32 lba, int32 lba_subq_relative_offs, uint8* out_buf) +{ + memset(out_buf, 0, 2352 + 96); + subpw_synth_udapp_lba(toc, lba, lba_subq_relative_offs, out_buf + 2352); + + if(out_buf[2352 + 1] & 0x40) + { + if(mode == 0xFF) + { + if(toc.disc_type == DISC_TYPE_CD_XA || toc.disc_type == DISC_TYPE_CD_I) + mode = 0x02; + else + mode = 0x01; + } + + switch(mode) + { + default: + encode_mode0_sector(LBA_to_ABA(lba), out_buf); + break; + + case 0x01: + encode_mode1_sector(LBA_to_ABA(lba), out_buf); + break; + + case 0x02: + out_buf[12 + 6] = 0x20; + out_buf[12 + 10] = 0x20; + encode_mode2_form2_sector(LBA_to_ABA(lba), out_buf); + break; + } + } +} + +#if 0 +bool subq_extrapolate(const uint8 *subq_input, int32 position_delta, uint8 *subq_output) +{ + assert(subq_check_checksum(subq_input)); + + + subq_generate_checksum(subq_output); +} +#endif + +void scrambleize_data_sector(uint8 *sector_data) +{ + for(unsigned i = 12; i < 2352; i++) + sector_data[i] ^= scramble_table[i - 12]; +} + +} diff --git a/waterbox/ss/cdrom/CDUtility.h b/waterbox/ss/cdrom/CDUtility.h new file mode 100644 index 0000000000..6539dc622d --- /dev/null +++ b/waterbox/ss/cdrom/CDUtility.h @@ -0,0 +1,237 @@ +#ifndef __MDFN_CDROM_CDUTILITY_H +#define __MDFN_CDROM_CDUTILITY_H + +namespace CDUtility +{ + // Call once at app startup before creating any threads that could potentially cause re-entrancy to these functions. + // It will also be called automatically if needed for the first time a function in this namespace that requires + // the initialization function to be called is called, for potential + // usage in constructors of statically-declared objects. + void CDUtility_Init(void) MDFN_COLD; + + // Quick definitions here: + // + // ABA - Absolute block address, synonymous to absolute MSF + // aba = (m_a * 60 * 75) + (s_a * 75) + f_a + // + // LBA - Logical block address(related: data CDs are required to have a pregap of 2 seconds, IE 150 frames/sectors) + // lba = aba - 150 + + + enum + { + ADR_NOQINFO = 0x00, + ADR_CURPOS = 0x01, + ADR_MCN = 0x02, + ADR_ISRC = 0x03 + }; + + + struct TOC_Track + { + uint8 adr; + uint8 control; + uint32 lba; + bool valid; // valid/present; oh CD-i... + }; + + // SubQ control field flags. + enum + { + SUBQ_CTRLF_PRE = 0x01, // With 50/15us pre-emphasis. + SUBQ_CTRLF_DCP = 0x02, // Digital copy permitted. + SUBQ_CTRLF_DATA = 0x04, // Data track. + SUBQ_CTRLF_4CH = 0x08, // 4-channel CD-DA. + }; + + enum + { + DISC_TYPE_CDDA_OR_M1 = 0x00, + DISC_TYPE_CD_I = 0x10, + DISC_TYPE_CD_XA = 0x20 + }; + + struct TOC + { + INLINE TOC() + { + Clear(); + } + + INLINE void Clear(void) + { + first_track = last_track = 0; + disc_type = 0; + + memset(tracks, 0, sizeof(tracks)); // FIXME if we change TOC_Track to non-POD type. + } + + INLINE int FindTrackByLBA(uint32 LBA) const + { + int32 lvt = 0; + + for(int32 track = 1; track <= 100; track++) + { + if(!tracks[track].valid) + continue; + + if(LBA < tracks[track].lba) + break; + + lvt = track; + } + + return(lvt); + } + + uint8 first_track; + uint8 last_track; + uint8 disc_type; + TOC_Track tracks[100 + 1]; // [0] is unused, [100] is for the leadout track. + }; + + // + // Address conversion functions. + // + static INLINE uint32 AMSF_to_ABA(int32 m_a, int32 s_a, int32 f_a) + { + return(f_a + 75 * s_a + 75 * 60 * m_a); + } + + static INLINE void ABA_to_AMSF(uint32 aba, uint8 *m_a, uint8 *s_a, uint8 *f_a) + { + *m_a = aba / 75 / 60; + *s_a = (aba - *m_a * 75 * 60) / 75; + *f_a = aba - (*m_a * 75 * 60) - (*s_a * 75); + } + + static INLINE int32 ABA_to_LBA(uint32 aba) + { + return(aba - 150); + } + + static INLINE uint32 LBA_to_ABA(int32 lba) + { + return(lba + 150); + } + + static INLINE int32 AMSF_to_LBA(uint8 m_a, uint8 s_a, uint8 f_a) + { + return(ABA_to_LBA(AMSF_to_ABA(m_a, s_a, f_a))); + } + + static INLINE void LBA_to_AMSF(int32 lba, uint8 *m_a, uint8 *s_a, uint8 *f_a) + { + ABA_to_AMSF(LBA_to_ABA(lba), m_a, s_a, f_a); + } + + // + // BCD conversion functions + // + static INLINE bool BCD_is_valid(uint8 bcd_number) + { + if((bcd_number & 0xF0) >= 0xA0) + return(false); + + if((bcd_number & 0x0F) >= 0x0A) + return(false); + + return(true); + } + + static INLINE uint8 BCD_to_U8(uint8 bcd_number) + { + return( ((bcd_number >> 4) * 10) + (bcd_number & 0x0F) ); + } + + static INLINE uint8 U8_to_BCD(uint8 num) + { + return( ((num / 10) << 4) + (num % 10) ); + } + + // should always perform the conversion, even if the bcd number is invalid. + static INLINE bool BCD_to_U8_check(uint8 bcd_number, uint8 *out_number) + { + *out_number = BCD_to_U8(bcd_number); + + if(!BCD_is_valid(bcd_number)) + return(false); + + return(true); + } + + // + // Sector data encoding functions(to full 2352 bytes raw sector). + // + // sector_data must be able to contain at least 2352 bytes. + void encode_mode0_sector(uint32 aba, uint8 *sector_data); + void encode_mode1_sector(uint32 aba, uint8 *sector_data); // 2048 bytes of user data at offset 16 + void encode_mode2_sector(uint32 aba, uint8 *sector_data); // 2336 bytes of user data at offset 16 + void encode_mode2_form1_sector(uint32 aba, uint8 *sector_data); // 2048+8 bytes of user data at offset 16 + void encode_mode2_form2_sector(uint32 aba, uint8 *sector_data); // 2324+8 bytes of user data at offset 16 + + + // User data area pre-pause(MSF 00:00:00 through 00:01:74), lba -150 through -1 + // out_buf must be able to contain 2352+96 bytes. + // "mode" is not used if the area is to be encoded as audio. + // pass 0xFF for "mode" for "don't know", and to make guess based on the TOC. + void synth_udapp_sector_lba(uint8 mode, const TOC& toc, const int32 lba, int32 lba_subq_relative_offs, uint8* out_buf); + void subpw_synth_udapp_lba(const TOC& toc, const int32 lba, const int32 lba_subq_relative_offs, uint8* SubPWBuf); + + // out_buf must be able to contain 2352+96 bytes. + // "mode" is not used if the area is to be encoded as audio. + // pass 0xFF for "mode" for "don't know", and to make guess based on the TOC. + void synth_leadout_sector_lba(uint8 mode, const TOC& toc, const int32 lba, uint8* out_buf); + void subpw_synth_leadout_lba(const TOC& toc, const int32 lba, uint8* SubPWBuf); + + + // + // User data error detection and correction + // + + // Check EDC of a mode 1 or mode 2 form 1 sector. + // Returns "true" if checksum is ok(matches). + // Returns "false" if checksum mismatch. + // sector_data should contain 2352 bytes of raw sector data. + bool edc_check(const uint8 *sector_data, bool xa); + + // Check EDC and L-EC data of a mode 1 or mode 2 form 1 sector, and correct bit errors if any exist. + // Returns "true" if errors weren't detected, or they were corrected succesfully. + // Returns "false" if errors couldn't be corrected. + // sector_data should contain 2352 bytes of raw sector data. + // + // Note: mode 2 form 1 L-EC data can't correct errors in the 4-byte sector header(address + mode), + // but the error(s) will still be detected by EDC. + bool edc_lec_check_and_correct(uint8 *sector_data, bool xa); + + // + // Subchannel(Q in particular) functions + // + + // Returns false on checksum mismatch, true on match. + bool subq_check_checksum(const uint8 *subq_buf); + + // Calculates the checksum of Q subchannel data(not including the checksum bytes of course ;)) from subq_buf, and stores it into the appropriate position + // in subq_buf. + void subq_generate_checksum(uint8 *subq_buf); + + // Deinterleaves 12 bytes of subchannel Q data from 96 bytes of interleaved subchannel PW data. + void subq_deinterleave(const uint8 *subpw_buf, uint8 *subq_buf); + + // Deinterleaves 96 bytes of subchannel P-W data from 96 bytes of interleaved subchannel PW data. + void subpw_deinterleave(const uint8 *in_buf, uint8 *out_buf); + + // Interleaves 96 bytes of subchannel P-W data from 96 bytes of uninterleaved subchannel PW data. + void subpw_interleave(const uint8 *in_buf, uint8 *out_buf); + + // Extrapolates Q subchannel current position data from subq_input, with frame/sector delta position_delta, and writes to subq_output. + // Only valid for ADR_CURPOS. + // subq_input must pass subq_check_checksum(). + // TODO + //void subq_extrapolate(const uint8 *subq_input, int32 position_delta, uint8 *subq_output); + + // (De)Scrambles data sector. + void scrambleize_data_sector(uint8 *sector_data); +} + +#endif diff --git a/waterbox/ss/cdrom/cdromif.cpp b/waterbox/ss/cdrom/cdromif.cpp new file mode 100644 index 0000000000..a0aac4e2d2 --- /dev/null +++ b/waterbox/ss/cdrom/cdromif.cpp @@ -0,0 +1,131 @@ +/* Mednafen - Multi-system Emulator + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "ss.h" +#include +#include +#include "cdromif.h" +//#include "CDAccess.h" +//#include "../general.h" + +#include + +using namespace CDUtility; + +enum +{ + // Status/Error messages + CDIF_MSG_DONE = 0, // Read -> emu. args: No args. + CDIF_MSG_INFO, // Read -> emu. args: str_message + CDIF_MSG_FATAL_ERROR, // Read -> emu. args: *TODO ARGS* + + // + // Command messages. + // + CDIF_MSG_DIEDIEDIE, // Emu -> read + + CDIF_MSG_READ_SECTOR, /* Emu -> read + args[0] = lba + */ +}; + + +typedef struct +{ + bool valid; + bool error; + int32 lba; + uint8 data[2352 + 96]; +} CDIF_Sector_Buffer; + + +CDIF::CDIF() : UnrecoverableError(false) +{ + +} + +CDIF::~CDIF() +{ + +} + +bool CDIF::ValidateRawSector(uint8 *buf) +{ + int mode = buf[12 + 3]; + + if(mode != 0x1 && mode != 0x2) + return(false); + + if(!edc_lec_check_and_correct(buf, mode == 2)) + return(false); + + return(true); +} + +int CDIF::ReadSector(uint8* buf, int32 lba, uint32 sector_count, bool suppress_uncorrectable_message) +{ + int ret = 0; + + if(UnrecoverableError) + return(false); + + while(sector_count--) + { + uint8 tmpbuf[2352 + 96]; + + if(!ReadRawSector(tmpbuf, lba)) + { + puts("CDIF Raw Read error"); + return(FALSE); + } + + if(!ValidateRawSector(tmpbuf)) + { + /*if(!suppress_uncorrectable_message) + { + MDFN_DispMessage(_("Uncorrectable data at sector %d"), lba); + MDFN_PrintError(_("Uncorrectable data at sector %d"), lba); + }*/ + + return(false); + } + + const int mode = tmpbuf[12 + 3]; + + if(!ret) + ret = mode; + + if(mode == 1) + { + memcpy(buf, &tmpbuf[12 + 4], 2048); + } + else if(mode == 2) + { + memcpy(buf, &tmpbuf[12 + 4 + 8], 2048); + } + else + { + printf("CDIF_ReadSector() invalid sector type at LBA=%u\n", (unsigned int)lba); + return(false); + } + + buf += 2048; + lba++; + } + + return(ret); +} diff --git a/waterbox/ss/cdrom/cdromif.h b/waterbox/ss/cdrom/cdromif.h new file mode 100644 index 0000000000..51125e8409 --- /dev/null +++ b/waterbox/ss/cdrom/cdromif.h @@ -0,0 +1,59 @@ +/* Mednafen - Multi-system Emulator + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __MDFN_CDROM_CDROMIF_H +#define __MDFN_CDROM_CDROMIF_H + +#include "CDUtility.h" + +#include + +typedef CDUtility::TOC CD_TOC; + +class CDIF +{ + public: + + CDIF(); + virtual ~CDIF(); + + static const int32 LBA_Read_Minimum = -150; + static const int32 LBA_Read_Maximum = 449849; // 100 * 75 * 60 - 150 - 1 + + inline void ReadTOC(CDUtility::TOC *read_target) + { + *read_target = disc_toc; + } + + virtual void HintReadSector(int32 lba) = 0; + virtual bool ReadRawSector(uint8 *buf, int32 lba) = 0; // Reads 2352+96 bytes of data into buf. + virtual bool ReadRawSectorPWOnly(uint8* pwbuf, int32 lba, bool hint_fullread) = 0; // Reads 96 bytes(of raw subchannel PW data) into pwbuf. + + // Call for mode 1 or mode 2 form 1 only. + bool ValidateRawSector(uint8 *buf); + + // Utility/Wrapped functions + // Reads mode 1 and mode2 form 1 sectors(2048 bytes per sector returned) + // Will return the type(1, 2) of the first sector read to the buffer supplied, 0 on error + int ReadSector(uint8* buf, int32 lba, uint32 sector_count, bool suppress_uncorrectable_message = false); + + protected: + bool UnrecoverableError; + CDUtility::TOC disc_toc; +}; + +#endif diff --git a/waterbox/ss/cdrom/crc32.cpp b/waterbox/ss/cdrom/crc32.cpp new file mode 100644 index 0000000000..2aa4ee14a3 --- /dev/null +++ b/waterbox/ss/cdrom/crc32.cpp @@ -0,0 +1,130 @@ +/* dvdisaster: Additional error correction for optical media. + * Copyright (C) 2004-2007 Carsten Gnoerlich. + * Project home page: http://www.dvdisaster.com + * Email: carsten@dvdisaster.com -or- cgnoerlich@fsfe.org + * + * CRC32 code based upon public domain code by Ross Williams (see notes below) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, + * or direct your browser at http://www.gnu.org. + */ + +#include "dvdisaster.h" + +/*** + *** EDC checksum used in CDROM sectors + ***/ + +/*****************************************************************/ +/* */ +/* CRC LOOKUP TABLE */ +/* ================ */ +/* The following CRC lookup table was generated automagically */ +/* by the Rocksoft^tm Model CRC Algorithm Table Generation */ +/* Program V1.0 using the following model parameters: */ +/* */ +/* Width : 4 bytes. */ +/* Poly : 0x8001801BL */ +/* Reverse : TRUE. */ +/* */ +/* For more information on the Rocksoft^tm Model CRC Algorithm, */ +/* see the document titled "A Painless Guide to CRC Error */ +/* Detection Algorithms" by Ross Williams */ +/* (ross@guest.adelaide.edu.au.). This document is likely to be */ +/* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". */ +/* */ +/*****************************************************************/ + +static const unsigned long edctable[256] = +{ + 0x00000000L, 0x90910101L, 0x91210201L, 0x01B00300L, + 0x92410401L, 0x02D00500L, 0x03600600L, 0x93F10701L, + 0x94810801L, 0x04100900L, 0x05A00A00L, 0x95310B01L, + 0x06C00C00L, 0x96510D01L, 0x97E10E01L, 0x07700F00L, + 0x99011001L, 0x09901100L, 0x08201200L, 0x98B11301L, + 0x0B401400L, 0x9BD11501L, 0x9A611601L, 0x0AF01700L, + 0x0D801800L, 0x9D111901L, 0x9CA11A01L, 0x0C301B00L, + 0x9FC11C01L, 0x0F501D00L, 0x0EE01E00L, 0x9E711F01L, + 0x82012001L, 0x12902100L, 0x13202200L, 0x83B12301L, + 0x10402400L, 0x80D12501L, 0x81612601L, 0x11F02700L, + 0x16802800L, 0x86112901L, 0x87A12A01L, 0x17302B00L, + 0x84C12C01L, 0x14502D00L, 0x15E02E00L, 0x85712F01L, + 0x1B003000L, 0x8B913101L, 0x8A213201L, 0x1AB03300L, + 0x89413401L, 0x19D03500L, 0x18603600L, 0x88F13701L, + 0x8F813801L, 0x1F103900L, 0x1EA03A00L, 0x8E313B01L, + 0x1DC03C00L, 0x8D513D01L, 0x8CE13E01L, 0x1C703F00L, + 0xB4014001L, 0x24904100L, 0x25204200L, 0xB5B14301L, + 0x26404400L, 0xB6D14501L, 0xB7614601L, 0x27F04700L, + 0x20804800L, 0xB0114901L, 0xB1A14A01L, 0x21304B00L, + 0xB2C14C01L, 0x22504D00L, 0x23E04E00L, 0xB3714F01L, + 0x2D005000L, 0xBD915101L, 0xBC215201L, 0x2CB05300L, + 0xBF415401L, 0x2FD05500L, 0x2E605600L, 0xBEF15701L, + 0xB9815801L, 0x29105900L, 0x28A05A00L, 0xB8315B01L, + 0x2BC05C00L, 0xBB515D01L, 0xBAE15E01L, 0x2A705F00L, + 0x36006000L, 0xA6916101L, 0xA7216201L, 0x37B06300L, + 0xA4416401L, 0x34D06500L, 0x35606600L, 0xA5F16701L, + 0xA2816801L, 0x32106900L, 0x33A06A00L, 0xA3316B01L, + 0x30C06C00L, 0xA0516D01L, 0xA1E16E01L, 0x31706F00L, + 0xAF017001L, 0x3F907100L, 0x3E207200L, 0xAEB17301L, + 0x3D407400L, 0xADD17501L, 0xAC617601L, 0x3CF07700L, + 0x3B807800L, 0xAB117901L, 0xAAA17A01L, 0x3A307B00L, + 0xA9C17C01L, 0x39507D00L, 0x38E07E00L, 0xA8717F01L, + 0xD8018001L, 0x48908100L, 0x49208200L, 0xD9B18301L, + 0x4A408400L, 0xDAD18501L, 0xDB618601L, 0x4BF08700L, + 0x4C808800L, 0xDC118901L, 0xDDA18A01L, 0x4D308B00L, + 0xDEC18C01L, 0x4E508D00L, 0x4FE08E00L, 0xDF718F01L, + 0x41009000L, 0xD1919101L, 0xD0219201L, 0x40B09300L, + 0xD3419401L, 0x43D09500L, 0x42609600L, 0xD2F19701L, + 0xD5819801L, 0x45109900L, 0x44A09A00L, 0xD4319B01L, + 0x47C09C00L, 0xD7519D01L, 0xD6E19E01L, 0x46709F00L, + 0x5A00A000L, 0xCA91A101L, 0xCB21A201L, 0x5BB0A300L, + 0xC841A401L, 0x58D0A500L, 0x5960A600L, 0xC9F1A701L, + 0xCE81A801L, 0x5E10A900L, 0x5FA0AA00L, 0xCF31AB01L, + 0x5CC0AC00L, 0xCC51AD01L, 0xCDE1AE01L, 0x5D70AF00L, + 0xC301B001L, 0x5390B100L, 0x5220B200L, 0xC2B1B301L, + 0x5140B400L, 0xC1D1B501L, 0xC061B601L, 0x50F0B700L, + 0x5780B800L, 0xC711B901L, 0xC6A1BA01L, 0x5630BB00L, + 0xC5C1BC01L, 0x5550BD00L, 0x54E0BE00L, 0xC471BF01L, + 0x6C00C000L, 0xFC91C101L, 0xFD21C201L, 0x6DB0C300L, + 0xFE41C401L, 0x6ED0C500L, 0x6F60C600L, 0xFFF1C701L, + 0xF881C801L, 0x6810C900L, 0x69A0CA00L, 0xF931CB01L, + 0x6AC0CC00L, 0xFA51CD01L, 0xFBE1CE01L, 0x6B70CF00L, + 0xF501D001L, 0x6590D100L, 0x6420D200L, 0xF4B1D301L, + 0x6740D400L, 0xF7D1D501L, 0xF661D601L, 0x66F0D700L, + 0x6180D800L, 0xF111D901L, 0xF0A1DA01L, 0x6030DB00L, + 0xF3C1DC01L, 0x6350DD00L, 0x62E0DE00L, 0xF271DF01L, + 0xEE01E001L, 0x7E90E100L, 0x7F20E200L, 0xEFB1E301L, + 0x7C40E400L, 0xECD1E501L, 0xED61E601L, 0x7DF0E700L, + 0x7A80E800L, 0xEA11E901L, 0xEBA1EA01L, 0x7B30EB00L, + 0xE8C1EC01L, 0x7850ED00L, 0x79E0EE00L, 0xE971EF01L, + 0x7700F000L, 0xE791F101L, 0xE621F201L, 0x76B0F300L, + 0xE541F401L, 0x75D0F500L, 0x7460F600L, 0xE4F1F701L, + 0xE381F801L, 0x7310F900L, 0x72A0FA00L, 0xE231FB01L, + 0x71C0FC00L, 0xE151FD01L, 0xE0E1FE01L, 0x7070FF00L +}; + +/* + * CDROM EDC calculation + */ + +uint32 EDCCrc32(const unsigned char *data, int len) +{ + uint32 crc = 0; + + while(len--) + crc = edctable[(crc ^ *data++) & 0xFF] ^ (crc >> 8); + + return crc; +} diff --git a/waterbox/ss/cdrom/dvdisaster.h b/waterbox/ss/cdrom/dvdisaster.h new file mode 100644 index 0000000000..2875ae29b4 --- /dev/null +++ b/waterbox/ss/cdrom/dvdisaster.h @@ -0,0 +1,171 @@ +/* dvdisaster: Additional error correction for optical media. + * Copyright (C) 2004-2007 Carsten Gnoerlich. + * Project home page: http://www.dvdisaster.com + * Email: carsten@dvdisaster.com -or- cgnoerlich@fsfe.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, + * or direct your browser at http://www.gnu.org. + */ + +#ifndef DVDISASTER_H +#define DVDISASTER_H + +/* "Dare to be gorgeous and unique. + * But don't ever be cryptic or otherwise unfathomable. + * Make it unforgettably great." + * + * From "A Final Note on Style", + * Amiga Intuition Reference Manual, 1986, p. 231 + */ + +/*** + *** I'm too lazy to mess with #include dependencies. + *** Everything #includeable is rolled up herein... + */ + +#include "ss.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*** + *** dvdisaster.c + ***/ + +void PrepareDeadSector(void); + +void CreateEcc(void); +void FixEcc(void); +void Verify(void); + +uint32 EDCCrc32(const unsigned char*, int); + +/*** + *** galois.c + *** + * This is currently the hardcoded GF(2**8). + * int32 gives abundant space for the GF. + * Squeezing it down to uint8 won't probably gain much, + * so we implement this defensively here. + * + * Note that some performance critical stuff needs to + * be #included from galois-inlines.h + */ + +/* Galois field parameters for 8bit symbol Reed-Solomon code */ + +#define GF_SYMBOLSIZE 8 +#define GF_FIELDSIZE (1<= GF_FIELDMAX) + { + x -= GF_FIELDMAX; + x = (x >> GF_SYMBOLSIZE) + (x & GF_FIELDMAX); + } + + return x; +} diff --git a/waterbox/ss/cdrom/galois.cpp b/waterbox/ss/cdrom/galois.cpp new file mode 100644 index 0000000000..2792cfc341 --- /dev/null +++ b/waterbox/ss/cdrom/galois.cpp @@ -0,0 +1,156 @@ +/* dvdisaster: Additional error correction for optical media. + * Copyright (C) 2004-2007 Carsten Gnoerlich. + * Project home page: http://www.dvdisaster.com + * Email: carsten@dvdisaster.com -or- cgnoerlich@fsfe.org + * + * The Reed-Solomon error correction draws a lot of inspiration - and even code - + * from Phil Karn's excellent Reed-Solomon library: http://www.ka9q.net/code/fec/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, + * or direct your browser at http://www.gnu.org. + */ + +#include "dvdisaster.h" + +#include "galois-inlines.h" + +/*** + *** Galois field arithmetic. + *** + * Calculations are done over the extension field GF(2**n). + * Be careful not to overgeneralize these arithmetics; + * they only work for the case of GF(p**n) with p being prime. + */ + +/* Initialize the Galois field tables */ + + +GaloisTables* CreateGaloisTables(int32 gf_generator) +{ + GaloisTables *gt = (GaloisTables *)calloc(1, sizeof(GaloisTables)); + int32 b,log; + + /* Allocate the tables. + The encoder uses a special version of alpha_to which has the mod_fieldmax() + folded into the table. */ + + gt->gfGenerator = gf_generator; + + gt->indexOf = (int32 *)calloc(GF_FIELDSIZE, sizeof(int32)); + gt->alphaTo = (int32 *)calloc(GF_FIELDSIZE, sizeof(int32)); + gt->encAlphaTo = (int32 *)calloc(2*GF_FIELDSIZE, sizeof(int32)); + + /* create the log/ilog values */ + + for(b=1, log=0; logindexOf[b] = log; + gt->alphaTo[log] = b; + b = b << 1; + if(b & GF_FIELDSIZE) + b = b ^ gf_generator; + } + + if(b!=1) + { + printf("Failed to create the Galois field log tables!\n"); + exit(1); + } + + /* we're even closed using infinity (makes things easier) */ + + gt->indexOf[0] = GF_ALPHA0; /* log(0) = inf */ + gt->alphaTo[GF_ALPHA0] = 0; /* and the other way around */ + + for(b=0; b<2*GF_FIELDSIZE; b++) + gt->encAlphaTo[b] = gt->alphaTo[mod_fieldmax(b)]; + + return gt; +} + +void FreeGaloisTables(GaloisTables *gt) +{ + if(gt->indexOf) free(gt->indexOf); + if(gt->alphaTo) free(gt->alphaTo); + if(gt->encAlphaTo) free(gt->encAlphaTo); + + free(gt); +} + +/*** + *** Create the the Reed-Solomon generator polynomial + *** and some auxiliary data structures. + */ + +ReedSolomonTables *CreateReedSolomonTables(GaloisTables *gt, + int32 first_consecutive_root, + int32 prim_elem, + int nroots_in) +{ ReedSolomonTables *rt = (ReedSolomonTables *)calloc(1, sizeof(ReedSolomonTables)); + int32 i,j,root; + + rt->gfTables = gt; + rt->fcr = first_consecutive_root; + rt->primElem = prim_elem; + rt->nroots = nroots_in; + rt->ndata = GF_FIELDMAX - rt->nroots; + + rt->gpoly = (int32 *)calloc((rt->nroots+1), sizeof(int32)); + + /* Create the RS code generator polynomial */ + + rt->gpoly[0] = 1; + + for(i=0, root=first_consecutive_root*prim_elem; inroots; i++, root+=prim_elem) + { rt->gpoly[i+1] = 1; + + /* Multiply gpoly by alpha**(root+x) */ + + for(j=i; j>0; j--) + { + if(rt->gpoly[j] != 0) + rt->gpoly[j] = rt->gpoly[j-1] ^ gt->alphaTo[mod_fieldmax(gt->indexOf[rt->gpoly[j]] + root)]; + else + rt->gpoly[j] = rt->gpoly[j-1]; + } + + rt->gpoly[0] = gt->alphaTo[mod_fieldmax(gt->indexOf[rt->gpoly[0]] + root)]; + } + + /* Store the polynomials index for faster encoding */ + + for(i=0; i<=rt->nroots; i++) + rt->gpoly[i] = gt->indexOf[rt->gpoly[i]]; + +#if 0 + /* for the precalculated unrolled loops only */ + + for(i=gt->nroots-1; i>0; i--) + PrintCLI( + " par_idx[((++spk)&%d)] ^= enc_alpha_to[feedback + %3d];\n", + nroots-1,gt->gpoly[i]); + + PrintCLI(" par_idx[sp] = enc_alpha_to[feedback + %3d];\n", + gt->gpoly[0]); +#endif + + return rt; +} + +void FreeReedSolomonTables(ReedSolomonTables *rt) +{ + if(rt->gpoly) free(rt->gpoly); + + free(rt); +} diff --git a/waterbox/ss/cdrom/l-ec.cpp b/waterbox/ss/cdrom/l-ec.cpp new file mode 100644 index 0000000000..5c035ce4ab --- /dev/null +++ b/waterbox/ss/cdrom/l-ec.cpp @@ -0,0 +1,478 @@ +/* dvdisaster: Additional error correction for optical media. + * Copyright (C) 2004-2007 Carsten Gnoerlich. + * Project home page: http://www.dvdisaster.com + * Email: carsten@dvdisaster.com -or- cgnoerlich@fsfe.org + * + * The Reed-Solomon error correction draws a lot of inspiration - and even code - + * from Phil Karn's excellent Reed-Solomon library: http://www.ka9q.net/code/fec/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, + * or direct your browser at http://www.gnu.org. + */ + +#include "dvdisaster.h" + +#include "galois-inlines.h" + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +/*** + *** Mapping between cd frame and parity vectors + ***/ + +/* + * Mapping of frame bytes to P/Q Vectors + */ + +int PToByteIndex(int p, int i) +{ return 12 + p + i*86; +} + +void ByteIndexToP(int b, int *p, int *i) +{ *p = (b-12)%86; + *i = (b-12)/86; +} + +int QToByteIndex(int q, int i) +{ int offset = 12 + (q & 1); + + if(i == 43) return 2248+q; + if(i == 44) return 2300+q; + + q&=~1; + return offset + (q*43 + i*88) % 2236; +} + +void ByteIndexToQ(int b, int *q, int *i) +{ int x,y,offset; + + if(b >= 2300) + { *i = 44; + *q = (b-2300); + return; + } + + if(b >= 2248) + { *i = 43; + *q = (b-2248); + return; + } + + offset = b&1; + b = (b-12)/2; + x = b/43; + y = (b-(x*43))%26; + *i = b-(x*43); + *q = 2*((x+26-y)%26)+offset; +} + +/* + * There are 86 vectors of P-parity, yielding a RS(26,24) code. + */ + +void GetPVector(unsigned char *frame, unsigned char *data, int n) +{ int i; + int w_idx = n+12; + + for(i=0; i<26; i++, w_idx+=86) + data[i] = frame[w_idx]; +} + +void SetPVector(unsigned char *frame, unsigned char *data, int n) +{ int i; + int w_idx = n+12; + + for(i=0; i<26; i++, w_idx+=86) + frame[w_idx] = data[i]; +} + +void FillPVector(unsigned char *frame, unsigned char data, int n) +{ int i; + int w_idx = n+12; + + for(i=0; i<26; i++, w_idx+=86) + frame[w_idx] = data; +} + +void OrPVector(unsigned char *frame, unsigned char value, int n) +{ int i; + int w_idx = n+12; + + for(i=0; i<26; i++, w_idx+=86) + frame[w_idx] |= value; +} + +void AndPVector(unsigned char *frame, unsigned char value, int n) +{ int i; + int w_idx = n+12; + + for(i=0; i<26; i++, w_idx+=86) + frame[w_idx] &= value; +} + +/* + * There are 52 vectors of Q-parity, yielding a RS(45,43) code. + */ + +void GetQVector(unsigned char *frame, unsigned char *data, int n) +{ int offset = 12 + (n & 1); + int w_idx = (n&~1) * 43; + int i; + + for(i=0; i<43; i++, w_idx+=88) + data[i] = frame[(w_idx % 2236) + offset]; + + data[43] = frame[2248 + n]; + data[44] = frame[2300 + n]; +} + +void SetQVector(unsigned char *frame, unsigned char *data, int n) +{ int offset = 12 + (n & 1); + int w_idx = (n&~1) * 43; + int i; + + for(i=0; i<43; i++, w_idx+=88) + frame[(w_idx % 2236) + offset] = data[i]; + + frame[2248 + n] = data[43]; + frame[2300 + n] = data[44]; +} + +void FillQVector(unsigned char *frame, unsigned char data, int n) +{ int offset = 12 + (n & 1); + int w_idx = (n&~1) * 43; + int i; + + for(i=0; i<43; i++, w_idx+=88) + frame[(w_idx % 2236) + offset] = data; + + frame[2248 + n] = data; + frame[2300 + n] = data; +} + +void OrQVector(unsigned char *frame, unsigned char data, int n) +{ int offset = 12 + (n & 1); + int w_idx = (n&~1) * 43; + int i; + + for(i=0; i<43; i++, w_idx+=88) + frame[(w_idx % 2236) + offset] |= data; + + frame[2248 + n] |= data; + frame[2300 + n] |= data; +} + +void AndQVector(unsigned char *frame, unsigned char data, int n) +{ int offset = 12 + (n & 1); + int w_idx = (n&~1) * 43; + int i; + + for(i=0; i<43; i++, w_idx+=88) + frame[(w_idx % 2236) + offset] &= data; + + frame[2248 + n] &= data; + frame[2300 + n] &= data; +} + +/*** + *** C2 error counting + ***/ + +int CountC2Errors(unsigned char *frame) +{ int i,count = 0; + frame += 2352; + + for(i=0; i<294; i++, frame++) + { if(*frame & 0x01) count++; + if(*frame & 0x02) count++; + if(*frame & 0x04) count++; + if(*frame & 0x08) count++; + if(*frame & 0x10) count++; + if(*frame & 0x20) count++; + if(*frame & 0x40) count++; + if(*frame & 0x80) count++; + } + + return count; +} + +/*** + *** L-EC error correction for CD raw data sectors + ***/ + +/* + * These could be used from ReedSolomonTables, + * but hardcoding them is faster. + */ + +#define NROOTS 2 +#define LEC_FIRST_ROOT 0 //GF_ALPHA0 +#define LEC_PRIM_ELEM 1 +#define LEC_PRIMTH_ROOT 1 + +/* + * Calculate the error syndrome + */ + +int DecodePQ(ReedSolomonTables *rt, unsigned char *data, int padding, + int *erasure_list, int erasure_count) +{ GaloisTables *gt = rt->gfTables; + int syndrome[NROOTS]; + int lambda[NROOTS+1]; + int omega[NROOTS+1]; + int b[NROOTS+1]; + int reg[NROOTS+1]; + int root[NROOTS]; + int loc[NROOTS]; + int syn_error; + int deg_lambda,lambda_roots; + int deg_omega; + int shortened_size = GF_FIELDMAX - padding; + int corrected = 0; + int i,j,k; + int r,el; + + /*** Form the syndromes: Evaluate data(x) at roots of g(x) */ + + for(i=0; ialphaTo[mod_fieldmax(gt->indexOf[syndrome[i]] + + (LEC_FIRST_ROOT+i)*LEC_PRIM_ELEM)]; + + /*** Convert syndrome to index form, check for nonzero condition. */ + + syn_error = 0; + for(i=0; iindexOf[syndrome[i]]; + } + + /*** If the syndrome is zero, everything is fine. */ + + if(!syn_error) + return 0; + + /*** Initialize lambda to be the erasure locator polynomial */ + + lambda[0] = 1; + lambda[1] = lambda[2] = 0; + + erasure_list[0] += padding; + erasure_list[1] += padding; + + if(erasure_count > 2) /* sanity check */ + erasure_count = 0; + + if(erasure_count > 0) + { lambda[1] = gt->alphaTo[mod_fieldmax(LEC_PRIM_ELEM*(GF_FIELDMAX-1-erasure_list[0]))]; + + for(i=1; i0; j--) + { int tmp = gt->indexOf[lambda[j-1]]; + + if(tmp != GF_ALPHA0) + lambda[j] ^= gt->alphaTo[mod_fieldmax(u + tmp)]; + } + } + } + + for(i=0; iindexOf[lambda[i]]; + + /*** Berlekamp-Massey algorithm to determine error+erasure locator polynomial */ + + r = erasure_count; /* r is the step number */ + el = erasure_count; + + /* Compute discrepancy at the r-th step in poly-form */ + + while(++r <= NROOTS) + { int discr_r = 0; + + for(i=0; ialphaTo[mod_fieldmax(gt->indexOf[lambda[i]] + syndrome[r-i-1])]; + + discr_r = gt->indexOf[discr_r]; + + if(discr_r == GF_ALPHA0) + { /* B(x) = x*B(x) */ + memmove(b+1, b, NROOTS*sizeof(b[0])); + b[0] = GF_ALPHA0; + } + else + { int t[NROOTS+1]; + + /* T(x) = lambda(x) - discr_r*x*b(x) */ + t[0] = lambda[0]; + for(i=0; ialphaTo[mod_fieldmax(discr_r + b[i])]; + else t[i+1] = lambda[i+1]; + } + + if(2*el <= r+erasure_count-1) + { el = r + erasure_count - el; + + /* B(x) <-- inv(discr_r) * lambda(x) */ + for(i=0; i<=NROOTS; i++) + b[i] = (lambda[i] == 0) ? GF_ALPHA0 + : mod_fieldmax(gt->indexOf[lambda[i]] - discr_r + GF_FIELDMAX); + } + else + { /* 2 lines below: B(x) <-- x*B(x) */ + memmove(b+1, b, NROOTS*sizeof(b[0])); + b[0] = GF_ALPHA0; + } + + memcpy(lambda, t, (NROOTS+1)*sizeof(t[0])); + } + } + + /*** Convert lambda to index form and compute deg(lambda(x)) */ + + deg_lambda = 0; + for(i=0; iindexOf[lambda[i]]; + if(lambda[i] != GF_ALPHA0) + deg_lambda = i; + } + + /*** Find roots of the error+erasure locator polynomial by Chien search */ + + memcpy(reg+1, lambda+1, NROOTS*sizeof(reg[0])); + lambda_roots = 0; /* Number of roots of lambda(x) */ + + for(i=1, k=LEC_PRIMTH_ROOT-1; i<=GF_FIELDMAX; i++, k=mod_fieldmax(k+LEC_PRIMTH_ROOT)) + { int q=1; /* lambda[0] is always 0 */ + + for(j=deg_lambda; j>0; j--) + { if(reg[j] != GF_ALPHA0) + { reg[j] = mod_fieldmax(reg[j] + j); + q ^= gt->alphaTo[reg[j]]; + } + } + + if(q != 0) continue; /* Not a root */ + + /* store root in index-form and the error location number */ + + root[lambda_roots] = i; + loc[lambda_roots] = k; + + /* If we've already found max possible roots, abort the search to save time */ + + if(++lambda_roots == deg_lambda) break; + } + + /* deg(lambda) unequal to number of roots => uncorrectable error detected + This is not reliable for very small numbers of roots, e.g. nroots = 2 */ + + if(deg_lambda != lambda_roots) + { return -1; + } + + /* Compute err+eras evaluator poly omega(x) = syn(x)*lambda(x) + (modulo x**nroots). in index form. Also find deg(omega). */ + + deg_omega = deg_lambda-1; + + for(i=0; i<=deg_omega; i++) + { int tmp = 0; + + for(j=i; j>=0; j--) + { if((syndrome[i - j] != GF_ALPHA0) && (lambda[j] != GF_ALPHA0)) + tmp ^= gt->alphaTo[mod_fieldmax(syndrome[i - j] + lambda[j])]; + } + + omega[i] = gt->indexOf[tmp]; + } + + /* Compute error values in poly-form. + num1 = omega(inv(X(l))), + num2 = inv(X(l))**(FIRST_ROOT-1) and + den = lambda_pr(inv(X(l))) all in poly-form. */ + + for(j=lambda_roots-1; j>=0; j--) + { int num1 = 0; + int num2; + int den; + int location = loc[j]; + + for(i=deg_omega; i>=0; i--) + { if(omega[i] != GF_ALPHA0) + num1 ^= gt->alphaTo[mod_fieldmax(omega[i] + i * root[j])]; + } + + num2 = gt->alphaTo[mod_fieldmax(root[j] * (LEC_FIRST_ROOT - 1) + GF_FIELDMAX)]; + den = 0; + + /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */ + + for(i=MIN(deg_lambda, NROOTS-1) & ~1; i>=0; i-=2) + { if(lambda[i+1] != GF_ALPHA0) + den ^= gt->alphaTo[mod_fieldmax(lambda[i+1] + i * root[j])]; + } + + /* Apply error to data */ + + if(num1 != 0 && location >= padding) + { + corrected++; + data[location-padding] ^= gt->alphaTo[mod_fieldmax(gt->indexOf[num1] + gt->indexOf[num2] + + GF_FIELDMAX - gt->indexOf[den])]; + + /* If no erasures were given, at most one error was corrected. + Return its position in erasure_list[0]. */ + + if(!erasure_count) + erasure_list[0] = location-padding; + } +#if 1 + else return -3; +#endif + } + + /*** Form the syndromes: Evaluate data(x) at roots of g(x) */ + + for(i=0; ialphaTo[mod_fieldmax(gt->indexOf[syndrome[i]] + + (LEC_FIRST_ROOT+i)*LEC_PRIM_ELEM)]; + } + + /*** Convert syndrome to index form, check for nonzero condition. */ +#if 1 + for(i=0; i + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "lec.h" + +#define GF8_PRIM_POLY 0x11d /* x^8 + x^4 + x^3 + x^2 + 1 */ + +#define EDC_POLY 0x8001801b /* (x^16 + x^15 + x^2 + 1) (x^16 + x^2 + x + 1) */ + +#define LEC_HEADER_OFFSET 12 +#define LEC_DATA_OFFSET 16 +#define LEC_MODE1_DATA_LEN 2048 +#define LEC_MODE1_EDC_OFFSET 2064 +#define LEC_MODE1_INTERMEDIATE_OFFSET 2068 +#define LEC_MODE1_P_PARITY_OFFSET 2076 +#define LEC_MODE1_Q_PARITY_OFFSET 2248 +#define LEC_MODE2_FORM1_DATA_LEN (2048+8) +#define LEC_MODE2_FORM1_EDC_OFFSET 2072 +#define LEC_MODE2_FORM2_DATA_LEN (2324+8) +#define LEC_MODE2_FORM2_EDC_OFFSET 2348 + + +typedef u_int8_t gf8_t; + +static u_int8_t GF8_LOG[256]; +static gf8_t GF8_ILOG[256]; + +static const class Gf8_Q_Coeffs_Results_01 { +private: + u_int16_t table[43][256]; +public: + Gf8_Q_Coeffs_Results_01(); + ~Gf8_Q_Coeffs_Results_01() {} + const u_int16_t *operator[] (int i) const { return &table[i][0]; } + operator const u_int16_t *() const { return &table[0][0]; } +} CF8_Q_COEFFS_RESULTS_01; + +static const class CrcTable { +private: + u_int32_t table[256]; +public: + CrcTable(); + ~CrcTable() {} + u_int32_t operator[](int i) const { return table[i]; } + operator const u_int32_t *() const { return table; } +} CRCTABLE; + +static const class ScrambleTable { +private: + u_int8_t table[2340]; +public: + ScrambleTable(); + ~ScrambleTable() {} + u_int8_t operator[](int i) const { return table[i]; } + operator const u_int8_t *() const { return table; } +} SCRAMBLE_TABLE; + +/* Creates the logarithm and inverse logarithm table that is required + * for performing multiplication in the GF(8) domain. + */ +static void gf8_create_log_tables() +{ + u_int8_t log; + u_int16_t b; + + for (b = 0; b <= 255; b++) { + GF8_LOG[b] = 0; + GF8_ILOG[b] = 0; + } + + b = 1; + + for (log = 0; log < 255; log++) { + GF8_LOG[(u_int8_t)b] = log; + GF8_ILOG[log] = (u_int8_t)b; + + b <<= 1; + + if ((b & 0x100) != 0) + b ^= GF8_PRIM_POLY; + } +} + +/* Addition in the GF(8) domain: just the XOR of the values. + */ +#define gf8_add(a, b) (a) ^ (b) + + +/* Multiplication in the GF(8) domain: add the logarithms (modulo 255) + * and return the inverse logarithm. Not used! + */ +#if 0 +static gf8_t gf8_mult(gf8_t a, gf8_t b) +{ + int16_t sum; + + if (a == 0 || b == 0) + return 0; + + sum = GF8_LOG[a] + GF8_LOG[b]; + + if (sum >= 255) + sum -= 255; + + return GF8_ILOG[sum]; +} +#endif + +/* Division in the GF(8) domain: Like multiplication but logarithms a + * subtracted. + */ +static gf8_t gf8_div(gf8_t a, gf8_t b) +{ + int16_t sum; + + assert(b != 0); + + if (a == 0) + return 0; + + sum = GF8_LOG[a] - GF8_LOG[b]; + + if (sum < 0) + sum += 255; + + return GF8_ILOG[sum]; +} + +Gf8_Q_Coeffs_Results_01::Gf8_Q_Coeffs_Results_01() +{ + int i, j; + u_int16_t c; + gf8_t GF8_COEFFS_HELP[2][45]; + u_int8_t GF8_Q_COEFFS[2][45]; + + + gf8_create_log_tables(); + + /* build matrix H: + * 1 1 ... 1 1 + * a^44 a^43 ... a^1 a^0 + * + * + */ + + for (j = 0; j < 45; j++) { + GF8_COEFFS_HELP[0][j] = 1; /* e0 */ + GF8_COEFFS_HELP[1][j] = GF8_ILOG[44-j]; /* e1 */ + } + + + /* resolve equation system for parity byte 0 and 1 */ + + /* e1' = e1 + e0 */ + for (j = 0; j < 45; j++) { + GF8_Q_COEFFS[1][j] = gf8_add(GF8_COEFFS_HELP[1][j], + GF8_COEFFS_HELP[0][j]); + } + + /* e1'' = e1' / (a^1 + 1) */ + for (j = 0; j < 45; j++) { + GF8_Q_COEFFS[1][j] = gf8_div(GF8_Q_COEFFS[1][j], GF8_Q_COEFFS[1][43]); + } + + /* e0' = e0 + e1 / a^1 */ + for (j = 0; j < 45; j++) { + GF8_Q_COEFFS[0][j] = gf8_add(GF8_COEFFS_HELP[0][j], + gf8_div(GF8_COEFFS_HELP[1][j], + GF8_ILOG[1])); + } + + /* e0'' = e0' / (1 + 1 / a^1) */ + for (j = 0; j < 45; j++) { + GF8_Q_COEFFS[0][j] = gf8_div(GF8_Q_COEFFS[0][j], GF8_Q_COEFFS[0][44]); + } + + /* + * Compute the products of 0..255 with all of the Q coefficients in + * advance. When building the scalar product between the data vectors + * and the P/Q vectors the individual products can be looked up in + * this table + * + * The P parity coefficients are just a subset of the Q coefficients so + * that we do not need to create a separate table for them. + */ + + for (j = 0; j < 43; j++) { + + table[j][0] = 0; + + for (i = 1; i < 256; i++) { + c = GF8_LOG[i] + GF8_LOG[GF8_Q_COEFFS[0][j]]; + if (c >= 255) c -= 255; + table[j][i] = GF8_ILOG[c]; + + c = GF8_LOG[i] + GF8_LOG[GF8_Q_COEFFS[1][j]]; + if (c >= 255) c -= 255; + table[j][i] |= GF8_ILOG[c]<<8; + } + } +} + +/* Reverses the bits in 'd'. 'bits' defines the bit width of 'd'. + */ +static u_int32_t mirror_bits(u_int32_t d, int bits) +{ + int i; + u_int32_t r = 0; + + for (i = 0; i < bits; i++) { + r <<= 1; + + if ((d & 0x1) != 0) + r |= 0x1; + + d >>= 1; + } + + return r; +} + +/* Build the CRC lookup table for EDC_POLY poly. The CRC is 32 bit wide + * and reversed (i.e. the bit stream is divided by the EDC_POLY with the + * LSB first order). + */ +CrcTable::CrcTable () +{ + u_int32_t i, j; + u_int32_t r; + + for (i = 0; i < 256; i++) { + r = mirror_bits(i, 8); + + r <<= 24; + + for (j = 0; j < 8; j++) { + if ((r & 0x80000000) != 0) { + r <<= 1; + r ^= EDC_POLY; + } + else { + r <<= 1; + } + } + + r = mirror_bits(r, 32); + + table[i] = r; + } +} + +/* Calculates the CRC of given data with given lengths based on the + * table lookup algorithm. + */ +static u_int32_t calc_edc(u_int8_t *data, int len) +{ + u_int32_t crc = 0; + + while (len--) { + crc = CRCTABLE[(int)(crc ^ *data++) & 0xff] ^ (crc >> 8); + } + + return crc; +} + +/* Build the scramble table as defined in the yellow book. The bytes + 12 to 2351 of a sector will be XORed with the data of this table. + */ +ScrambleTable::ScrambleTable() +{ + u_int16_t i, j; + u_int16_t reg = 1; + u_int8_t d; + + for (i = 0; i < 2340; i++) { + d = 0; + + for (j = 0; j < 8; j++) { + d >>= 1; + + if ((reg & 0x1) != 0) + d |= 0x80; + + if ((reg & 0x1) != ((reg >> 1) & 0x1)) { + reg >>= 1; + reg |= 0x4000; /* 15-bit register */ + } + else { + reg >>= 1; + } + } + + table[i] = d; + } +} + +/* Calc EDC for a MODE 1 sector + */ +static void calc_mode1_edc(u_int8_t *sector) +{ + u_int32_t crc = calc_edc(sector, LEC_MODE1_DATA_LEN + 16); + + sector[LEC_MODE1_EDC_OFFSET] = crc & 0xffL; + sector[LEC_MODE1_EDC_OFFSET + 1] = (crc >> 8) & 0xffL; + sector[LEC_MODE1_EDC_OFFSET + 2] = (crc >> 16) & 0xffL; + sector[LEC_MODE1_EDC_OFFSET + 3] = (crc >> 24) & 0xffL; +} + +/* Calc EDC for a XA form 1 sector + */ +static void calc_mode2_form1_edc(u_int8_t *sector) +{ + u_int32_t crc = calc_edc(sector + LEC_DATA_OFFSET, + LEC_MODE2_FORM1_DATA_LEN); + + sector[LEC_MODE2_FORM1_EDC_OFFSET] = crc & 0xffL; + sector[LEC_MODE2_FORM1_EDC_OFFSET + 1] = (crc >> 8) & 0xffL; + sector[LEC_MODE2_FORM1_EDC_OFFSET + 2] = (crc >> 16) & 0xffL; + sector[LEC_MODE2_FORM1_EDC_OFFSET + 3] = (crc >> 24) & 0xffL; +} + +/* Calc EDC for a XA form 2 sector + */ +static void calc_mode2_form2_edc(u_int8_t *sector) +{ + u_int32_t crc = calc_edc(sector + LEC_DATA_OFFSET, + LEC_MODE2_FORM2_DATA_LEN); + + sector[LEC_MODE2_FORM2_EDC_OFFSET] = crc & 0xffL; + sector[LEC_MODE2_FORM2_EDC_OFFSET + 1] = (crc >> 8) & 0xffL; + sector[LEC_MODE2_FORM2_EDC_OFFSET + 2] = (crc >> 16) & 0xffL; + sector[LEC_MODE2_FORM2_EDC_OFFSET + 3] = (crc >> 24) & 0xffL; +} + +/* Writes the sync pattern to the given sector. + */ +static void set_sync_pattern(u_int8_t *sector) +{ + sector[0] = 0; + + sector[1] = sector[2] = sector[3] = sector[4] = sector[5] = + sector[6] = sector[7] = sector[8] = sector[9] = sector[10] = 0xff; + + sector[11] = 0; +} + + +static u_int8_t bin2bcd(u_int8_t b) +{ + return (((b/10) << 4) & 0xf0) | ((b%10) & 0x0f); +} + +/* Builds the sector header. + */ +static void set_sector_header(u_int8_t mode, u_int32_t adr, u_int8_t *sector) +{ + sector[LEC_HEADER_OFFSET] = bin2bcd(adr / (60*75)); + sector[LEC_HEADER_OFFSET + 1] = bin2bcd((adr / 75) % 60); + sector[LEC_HEADER_OFFSET + 2] = bin2bcd(adr % 75); + sector[LEC_HEADER_OFFSET + 3] = mode; +} + +/* Calculate the P parities for the sector. + * The 43 P vectors of length 24 are combined with the GF8_P_COEFFS. + */ +static void calc_P_parity(u_int8_t *sector) +{ + int i, j; + u_int16_t p01_msb, p01_lsb; + u_int8_t *p_lsb_start; + u_int8_t *p_lsb; + u_int8_t *p0, *p1; + u_int8_t d0,d1; + + p_lsb_start = sector + LEC_HEADER_OFFSET; + + p1 = sector + LEC_MODE1_P_PARITY_OFFSET; + p0 = sector + LEC_MODE1_P_PARITY_OFFSET + 2 * 43; + + for (i = 0; i <= 42; i++) { + p_lsb = p_lsb_start; + + p01_lsb = p01_msb = 0; + + for (j = 19; j <= 42; j++) { + d0 = *p_lsb; + d1 = *(p_lsb+1); + + p01_lsb ^= CF8_Q_COEFFS_RESULTS_01[j][d0]; + p01_msb ^= CF8_Q_COEFFS_RESULTS_01[j][d1]; + + p_lsb += 2 * 43; + } + + *p0 = p01_lsb; + *(p0 + 1) = p01_msb; + + *p1 = p01_lsb>>8; + *(p1 + 1) = p01_msb>>8; + + p0 += 2; + p1 += 2; + + p_lsb_start += 2; + } +} + +/* Calculate the Q parities for the sector. + * The 26 Q vectors of length 43 are combined with the GF8_Q_COEFFS. + */ +static void calc_Q_parity(u_int8_t *sector) +{ + int i, j; + u_int16_t q01_lsb, q01_msb; + u_int8_t *q_lsb_start; + u_int8_t *q_lsb; + u_int8_t *q0, *q1, *q_start; + u_int8_t d0,d1; + + q_lsb_start = sector + LEC_HEADER_OFFSET; + + q_start = sector + LEC_MODE1_Q_PARITY_OFFSET; + q1 = sector + LEC_MODE1_Q_PARITY_OFFSET; + q0 = sector + LEC_MODE1_Q_PARITY_OFFSET + 2 * 26; + + for (i = 0; i <= 25; i++) { + q_lsb = q_lsb_start; + + q01_lsb = q01_msb = 0; + + for (j = 0; j <= 42; j++) { + d0 = *q_lsb; + d1 = *(q_lsb+1); + + q01_lsb ^= CF8_Q_COEFFS_RESULTS_01[j][d0]; + q01_msb ^= CF8_Q_COEFFS_RESULTS_01[j][d1]; + + q_lsb += 2 * 44; + + if (q_lsb >= q_start) { + q_lsb -= 2 * 1118; + } + } + + *q0 = q01_lsb; + *(q0 + 1) = q01_msb; + + *q1 = q01_lsb>>8; + *(q1 + 1) = q01_msb>>8; + + q0 += 2; + q1 += 2; + + q_lsb_start += 2 * 43; + } +} + +/* Encodes a MODE 0 sector. + * 'adr' is the current physical sector address + * 'sector' must be 2352 byte wide + */ +void lec_encode_mode0_sector(u_int32_t adr, u_int8_t *sector) +{ + u_int16_t i; + + set_sync_pattern(sector); + set_sector_header(0, adr, sector); + + sector += 16; + + for (i = 0; i < 2336; i++) + *sector++ = 0; +} + +/* Encodes a MODE 1 sector. + * 'adr' is the current physical sector address + * 'sector' must be 2352 byte wide containing 2048 bytes user data at + * offset 16 + */ +void lec_encode_mode1_sector(u_int32_t adr, u_int8_t *sector) +{ + set_sync_pattern(sector); + set_sector_header(1, adr, sector); + + calc_mode1_edc(sector); + + /* clear the intermediate field */ + sector[LEC_MODE1_INTERMEDIATE_OFFSET] = + sector[LEC_MODE1_INTERMEDIATE_OFFSET + 1] = + sector[LEC_MODE1_INTERMEDIATE_OFFSET + 2] = + sector[LEC_MODE1_INTERMEDIATE_OFFSET + 3] = + sector[LEC_MODE1_INTERMEDIATE_OFFSET + 4] = + sector[LEC_MODE1_INTERMEDIATE_OFFSET + 5] = + sector[LEC_MODE1_INTERMEDIATE_OFFSET + 6] = + sector[LEC_MODE1_INTERMEDIATE_OFFSET + 7] = 0; + + calc_P_parity(sector); + calc_Q_parity(sector); +} + +/* Encodes a MODE 2 sector. + * 'adr' is the current physical sector address + * 'sector' must be 2352 byte wide containing 2336 bytes user data at + * offset 16 + */ +void lec_encode_mode2_sector(u_int32_t adr, u_int8_t *sector) +{ + set_sync_pattern(sector); + set_sector_header(2, adr, sector); +} + +/* Encodes a XA form 1 sector. + * 'adr' is the current physical sector address + * 'sector' must be 2352 byte wide containing 2048+8 bytes user data at + * offset 16 + */ +void lec_encode_mode2_form1_sector(u_int32_t adr, u_int8_t *sector) +{ + set_sync_pattern(sector); + + calc_mode2_form1_edc(sector); + + /* P/Q partiy must not contain the sector header so clear it */ + sector[LEC_HEADER_OFFSET] = + sector[LEC_HEADER_OFFSET + 1] = + sector[LEC_HEADER_OFFSET + 2] = + sector[LEC_HEADER_OFFSET + 3] = 0; + + calc_P_parity(sector); + calc_Q_parity(sector); + + /* finally add the sector header */ + set_sector_header(2, adr, sector); +} + +/* Encodes a XA form 2 sector. + * 'adr' is the current physical sector address + * 'sector' must be 2352 byte wide containing 2324+8 bytes user data at + * offset 16 + */ +void lec_encode_mode2_form2_sector(u_int32_t adr, u_int8_t *sector) +{ + set_sync_pattern(sector); + + calc_mode2_form2_edc(sector); + + set_sector_header(2, adr, sector); +} + +/* Scrambles and byte swaps an encoded sector. + * 'sector' must be 2352 byte wide. + */ +void lec_scramble(u_int8_t *sector) +{ + u_int16_t i; + const u_int8_t *stable = SCRAMBLE_TABLE; + u_int8_t *p = sector; + u_int8_t tmp; + + + for (i = 0; i < 6; i++) { + /* just swap bytes of sector sync */ + tmp = *p; + *p = *(p + 1); + p++; + *p++ = tmp; + } + for (;i < (2352 / 2); i++) { + /* scramble and swap bytes */ + tmp = *p ^ *stable++; + *p = *(p + 1) ^ *stable++; + p++; + *p++ = tmp; + } +} + +#if 0 +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + char *infile; + char *outfile; + int fd_in, fd_out; + u_int8_t buffer1[2352]; + u_int8_t buffer2[2352]; + u_int32_t lba; + int i; + +#if 0 + for (i = 0; i < 2048; i++) + buffer1[i + 16] = 234; + + lba = 150; + + for (i = 0; i < 100000; i++) { + lec_encode_mode1_sector(lba, buffer1); + lec_scramble(buffer2); + lba++; + } + +#else + + if (argc != 3) + return 1; + + infile = argv[1]; + outfile = argv[2]; + + + if ((fd_in = open(infile, O_RDONLY)) < 0) { + perror("Cannot open input file"); + return 1; + } + + if ((fd_out = open(outfile, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) { + perror("Cannot open output file"); + return 1; + } + + lba = 150; + + do { + if (read(fd_in, buffer1, 2352) != 2352) + break; + + switch (*(buffer1 + 12 + 3)) { + case 1: + memcpy(buffer2 + 16, buffer1 + 16, 2048); + + lec_encode_mode1_sector(lba, buffer2); + break; + + case 2: + if ((*(buffer1 + 12 + 4 + 2) & 0x20) != 0) { + /* form 2 sector */ + memcpy(buffer2 + 16, buffer1 + 16, 2324 + 8); + lec_encode_mode2_form2_sector(lba, buffer2); + } + else { + /* form 1 sector */ + memcpy(buffer2 + 16, buffer1 + 16, 2048 + 8); + lec_encode_mode2_form1_sector(lba, buffer2); + } + break; + } + + if (memcmp(buffer1, buffer2, 2352) != 0) { + printf("Verify error at lba %ld\n", lba); + } + + lec_scramble(buffer2); + write(fd_out, buffer2, 2352); + + lba++; + } while (1); + + close(fd_in); + close(fd_out); + +#endif + + return 0; +} +#endif diff --git a/waterbox/ss/cdrom/lec.h b/waterbox/ss/cdrom/lec.h new file mode 100644 index 0000000000..c5e874c3f3 --- /dev/null +++ b/waterbox/ss/cdrom/lec.h @@ -0,0 +1,77 @@ +/* cdrdao - write audio CD-Rs in disc-at-once mode + * + * Copyright (C) 1998-2002 Andreas Mueller + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __LEC_H__ +#define __LEC_H__ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +typedef uint32_t u_int32_t; +typedef uint16_t u_int16_t; +typedef uint8_t u_int8_t; + +#ifndef TRUE +#define TRUE 1 +#endif + +/* Encodes a MODE 0 sector. + * 'adr' is the current physical sector address + * 'sector' must be 2352 byte wide + */ +void lec_encode_mode0_sector(u_int32_t adr, u_int8_t *sector); + +/* Encodes a MODE 1 sector. + * 'adr' is the current physical sector address + * 'sector' must be 2352 byte wide containing 2048 bytes user data at + * offset 16 + */ +void lec_encode_mode1_sector(u_int32_t adr, u_int8_t *sector); + +/* Encodes a MODE 2 sector. + * 'adr' is the current physical sector address + * 'sector' must be 2352 byte wide containing 2336 bytes user data at + * offset 16 + */ +void lec_encode_mode2_sector(u_int32_t adr, u_int8_t *sector); + +/* Encodes a XA form 1 sector. + * 'adr' is the current physical sector address + * 'sector' must be 2352 byte wide containing 2048+8 bytes user data at + * offset 16 + */ +void lec_encode_mode2_form1_sector(u_int32_t adr, u_int8_t *sector); + +/* Encodes a XA form 2 sector. + * 'adr' is the current physical sector address + * 'sector' must be 2352 byte wide containing 2324+8 bytes user data at + * offset 16 + */ +void lec_encode_mode2_form2_sector(u_int32_t adr, u_int8_t *sector); + +/* Scrambles and byte swaps an encoded sector. + * 'sector' must be 2352 byte wide. + */ +void lec_scramble(u_int8_t *sector); + +#endif diff --git a/waterbox/ss/cdrom/recover-raw.cpp b/waterbox/ss/cdrom/recover-raw.cpp new file mode 100644 index 0000000000..689f1f3c8f --- /dev/null +++ b/waterbox/ss/cdrom/recover-raw.cpp @@ -0,0 +1,210 @@ +/* dvdisaster: Additional error correction for optical media. + * Copyright (C) 2004-2007 Carsten Gnoerlich. + * Project home page: http://www.dvdisaster.com + * Email: carsten@dvdisaster.com -or- cgnoerlich@fsfe.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, + * or direct your browser at http://www.gnu.org. + */ + +#include "dvdisaster.h" + +static GaloisTables *gt = NULL; /* for L-EC Reed-Solomon */ +static ReedSolomonTables *rt = NULL; + +bool Init_LEC_Correct(void) +{ + gt = CreateGaloisTables(0x11d); + rt = CreateReedSolomonTables(gt, 0, 1, 10); + + return(1); +} + + + +/*** + *** CD level CRC calculation + ***/ + +/* + * Test raw sector against its 32bit CRC. + * Returns TRUE if frame is good. + */ + +int CheckEDC(const unsigned char *cd_frame, bool xa_mode) +{ + unsigned int expected_crc, real_crc; + unsigned int crc_base = xa_mode ? 2072 : 2064; + + expected_crc = cd_frame[crc_base + 0] << 0; + expected_crc |= cd_frame[crc_base + 1] << 8; + expected_crc |= cd_frame[crc_base + 2] << 16; + expected_crc |= cd_frame[crc_base + 3] << 24; + + if(xa_mode) + real_crc = EDCCrc32(cd_frame+16, 2056); + else + real_crc = EDCCrc32(cd_frame, 2064); + + if(expected_crc == real_crc) + return(1); + else + { + //printf("Bad EDC CRC: Calculated: %08x, Recorded: %08x\n", real_crc, expected_crc); + return(0); + } +} + +/*** + *** A very simple L-EC error correction. + *** + * Perform just one pass over the Q and P vectors to see if everything + * is okay respectively correct minor errors. This is pretty much the + * same stuff the drive is supposed to do in the final L-EC stage. + */ + +static int simple_lec(unsigned char *frame) +{ + unsigned char byte_state[2352]; + unsigned char p_vector[P_VECTOR_SIZE]; + unsigned char q_vector[Q_VECTOR_SIZE]; + unsigned char p_state[P_VECTOR_SIZE]; + int erasures[Q_VECTOR_SIZE], erasure_count; + int ignore[2]; + int p_failures, q_failures; + int p_corrected, q_corrected; + int p,q; + + /* Setup */ + + memset(byte_state, 0, 2352); + + p_failures = q_failures = 0; + p_corrected = q_corrected = 0; + + /* Perform Q-Parity error correction */ + + for(q=0; q 2) + { GetPVector(byte_state, p_state, p); + erasure_count = 0; + + for(i=0; i 0 && erasure_count <= 2) + { GetPVector(frame, p_vector, p); + err = DecodePQ(rt, p_vector, P_PADDING, erasures, erasure_count); + } + } + + /* See what we've got */ + + if(err < 0) /* Uncorrectable. */ + { p_failures++; + } + else /* Correctable. */ + { if(err == 1 || err == 2) /* Store back corrected vector */ + { SetPVector(frame, p_vector, p); + p_corrected++; + } + } + } + + /* Sum up */ + + if(q_failures || p_failures || q_corrected || p_corrected) + { + return 1; + } + + return 0; +} + +/*** + *** Validate CD raw sector + ***/ + +int ValidateRawSector(unsigned char *frame, bool xaMode) +{ + int lec_did_sth = FALSE; + + /* Do simple L-EC. + It seems that drives stop their internal L-EC as soon as the + EDC is okay, so we may see uncorrected errors in the parity bytes. + Since we are also interested in the user data only and doing the + L-EC is expensive, we skip our L-EC as well when the EDC is fine. */ + + if(!CheckEDC(frame, xaMode)) + { + unsigned char header[4]; + + if(xaMode) + { + memcpy(header, frame + 12, 4); + memset(frame + 12, 0, 4); + } + + lec_did_sth = simple_lec(frame); + + if(xaMode) + memcpy(frame + 12, header, 4); + } + + /* Test internal sector checksum again */ + if(!CheckEDC(frame, xaMode)) + { + /* EDC failure in RAW sector */ + return FALSE; + } + + return TRUE; +} + diff --git a/waterbox/ss/db.cpp b/waterbox/ss/db.cpp new file mode 100644 index 0000000000..d89487d715 --- /dev/null +++ b/waterbox/ss/db.cpp @@ -0,0 +1,161 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* db.cpp: +** Copyright (C) 2016-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "ss.h" +#include "smpc.h" +#include "cart.h" +#include "db.h" + +namespace MDFN_IEN_SS +{ + +bool DB_LookupRegionDB(const uint8* fd_id, unsigned* const region) +{ + static const struct + { + uint8 id[16]; + unsigned area; + } regiondb[] = + { + { { 0x10, 0x8f, 0xe1, 0xaf, 0x55, 0x5a, 0x95, 0x42, 0x04, 0x85, 0x7e, 0x98, 0x8c, 0x53, 0x6a, 0x31, }, SMPC_AREA_EU_PAL }, // Preview Sega Saturn Vol. 1 (Europe) + { { 0xed, 0x4c, 0x0b, 0x87, 0x35, 0x37, 0x86, 0x76, 0xa0, 0xf6, 0x32, 0xc6, 0xa4, 0xc3, 0x99, 0x88, }, SMPC_AREA_EU_PAL }, // Primal Rage (Europe) (En,Fr,De,Es,It,Pt) + { { 0x15, 0xfc, 0x3a, 0x82, 0x16, 0xa9, 0x85, 0xa5, 0xa8, 0xad, 0x30, 0xaf, 0x9a, 0xff, 0x03, 0xa9, }, SMPC_AREA_JP }, // Race Drivin' (Japan) (2M) + { { 0xe1, 0xdd, 0xfd, 0xa1, 0x8b, 0x47, 0x02, 0x21, 0x36, 0x1e, 0x5a, 0xae, 0x20, 0xc0, 0x59, 0x9f, }, SMPC_AREA_CSA_NTSC }, // Riven - A Sequencia de Myst (Brazil) (Disc 1) + { { 0xbf, 0x5f, 0xf8, 0x5f, 0xf2, 0x0c, 0x35, 0xf6, 0xc9, 0x8d, 0x03, 0xbc, 0x34, 0xd9, 0xda, 0x7f, }, SMPC_AREA_CSA_NTSC }, // Riven - A Sequencia de Myst (Brazil) (Disc 2) + { { 0x98, 0xb6, 0x6e, 0x09, 0xe6, 0xdc, 0x30, 0xe6, 0x55, 0xdb, 0x85, 0x01, 0x33, 0x0c, 0x0b, 0x9c, }, SMPC_AREA_CSA_NTSC }, // Riven - A Sequencia de Myst (Brazil) (Disc 3) + { { 0xa2, 0x34, 0xb0, 0xb9, 0xaa, 0x47, 0x74, 0x1f, 0xd4, 0x1e, 0x35, 0xda, 0x3d, 0xe7, 0x4d, 0xe3, }, SMPC_AREA_CSA_NTSC }, // Riven - A Sequencia de Myst (Brazil) (Disc 4) + { { 0xf7, 0xe9, 0x23, 0x0a, 0x9e, 0x92, 0xf1, 0x93, 0x16, 0x43, 0xf8, 0x6c, 0xe8, 0x21, 0x50, 0x66, }, SMPC_AREA_JP }, // Sega International Victory Goal (Japan) (5M) + { { 0x64, 0x75, 0x25, 0x0c, 0xa1, 0x9b, 0x6c, 0x5e, 0x4e, 0xa0, 0x6d, 0x69, 0xd9, 0x0f, 0x32, 0xca, }, SMPC_AREA_EU_PAL }, // Virtua Racing (Europe) + { { 0x0d, 0xe3, 0xfa, 0xfb, 0x2b, 0xb9, 0x6d, 0x79, 0xe0, 0x3a, 0xb7, 0x6d, 0xcc, 0xbf, 0xb0, 0x2c, }, SMPC_AREA_JP }, // Virtua Racing (Japan) + { { 0x6b, 0x29, 0x33, 0xfc, 0xdd, 0xad, 0x8e, 0x0d, 0x95, 0x81, 0xa6, 0xee, 0xfd, 0x90, 0x4b, 0x43, }, SMPC_AREA_EU_PAL }, // Winter Heat (Europe) (Demo) + { { 0x73, 0x91, 0x4b, 0xe1, 0xad, 0x4d, 0xaf, 0x69, 0xc3, 0xeb, 0xb8, 0x43, 0xee, 0x3e, 0xb5, 0x09, }, SMPC_AREA_EU_PAL }, // WWF WrestleMania - The Arcade Game (Europe) (Demo) + }; + + for(auto& re : regiondb) + { + if(!memcmp(re.id, fd_id, 16)) + { + *region = re.area; + return true; + } + } + + return false; +} + +bool DB_LookupCartDB(const char* sgid, const uint8* fd_id, int* const cart_type) +{ +// printf(" { \"%s\", CART_EXTRAM_1M },\n", sgid); +// printf(" { \"%s\", CART_EXTRAM_4M },\n", sgid); +// printf(" { \"%s\", CART_NONE },\n", sgid); + + static const struct + { + const char* sgid; + int cart_type; + uint8 fd_id[16]; + } cartdb[] = + { +#if 0 + { "T-19708G", CART_NONE }, // Pia Carrot e Youkoso + { "T-32901G", CART_NONE }, // Silhouette Mirage + { "MK-81086", CART_NONE }, // Tomb Raider (Europe) + { "T-7910H", CART_NONE }, // Tomb Raider (USA) + { "T-6010G", CART_NONE }, // Tomb Raiders +#endif + // + // + // + // NetLink Modem TODO: + { "MK-81218", CART_NONE }, // Daytona USA CCE Net Link Edition + { "MK-81071", CART_NONE }, // Duke Nukem 3D + { "T-319-01H", CART_NONE }, // PlanetWeb Browser (multiple versions) + { "MK-81070", CART_NONE }, // Saturn Bomberman + { "MK-81215", CART_NONE }, // Sega Rally Championship Plus NetLink Edition + { "MK-81072", CART_NONE }, // Virtual On NetLink Edition + // + // + // Japanese modem TODO: + { "GS-7106", CART_NONE }, // Dennou Senki Virtual On (SegaNet) + { "GS-7105", CART_NONE }, // Habitat II + { "GS-7101", CART_NONE }, // Pad Nifty + { "GS-7113", CART_NONE }, // Puzzle Bobble 3 (SegaNet) + { "T-14305G", CART_NONE }, // Saturn Bomberman (SegaNet) + { "T-31301G", CART_NONE }, // SegaSaturn Internet Vol. 1 + // + // + // + { "MK-81088", CART_KOF95 }, // The King of Fighters '95 (Europe) + { "T-3101G", CART_KOF95 }, // The King of Fighters '95 + { "T-13308G", CART_ULTRAMAN },// Ultraman: Hikari no Kyojin Densetsu + // + // + // + { "T-1521G", CART_EXTRAM_1M }, // Astra Superstars + { "T-9904G", CART_EXTRAM_1M }, // Cotton 2 + { "T-1217G", CART_EXTRAM_1M }, // Cyberbots + { "GS-9107", CART_EXTRAM_1M }, // Fighter's History Dynamite + { "T-20109G", CART_EXTRAM_1M }, // Friends + { "T-14411G", CART_EXTRAM_1M }, // Groove on Fight + { "T-7032H-50", CART_EXTRAM_1M }, // Marvel Super Heroes (Europe) + { "T-1215G", CART_EXTRAM_1M }, // Marvel Super Heroes (Japan) + { "T-3111G", CART_EXTRAM_1M }, // Metal Slug + { "T-22205G", CART_EXTRAM_1M }, // Noel 3 + { "T-22206G", CART_EXTRAM_1M }, // Noel 3 (TODO: Test) + { "T-20114G", CART_EXTRAM_1M }, // Pia Carrot e Youkoso!! 2 (TODO: Test) + { "T-20121M", CART_EXTRAM_1M }, // Pia Carrot e Youkoso!! 2 (TODO: Test) + { "T-3105G", CART_EXTRAM_1M }, // Real Bout Garou Densetsu + { "T-3119G", CART_EXTRAM_1M }, // Real Bout Garou Densetsu Special + { "T-3116G", CART_EXTRAM_1M }, // Samurai Spirits - Amakusa Kourin + { "T-3104G", CART_EXTRAM_1M }, // Samurai Spirits - Zankurou Musouken + { "T-16509G", CART_EXTRAM_1M }, // Super Real Mahjong P7 (TODO: Test) + { "T-16510G", CART_EXTRAM_1M }, // Super Real Mahjong P7 (TODO: Test) + { "T-3108G", CART_EXTRAM_1M }, // The King of Fighters '96 + { "T-3121G", CART_EXTRAM_1M }, // The King of Fighters '97 + { "T-1515G", CART_EXTRAM_1M }, // Waku Waku 7 + // + // + // + { "T-1245G", CART_EXTRAM_4M }, // D&D Collection + { "T-1248G", CART_EXTRAM_4M }, // Final Fight Revenge + { "T-1238G", CART_EXTRAM_4M }, // Marvel Super Heroes vs. Street Fighter + { "T-1230G", CART_EXTRAM_4M }, // Pocket Fighter + { "T-1246G", CART_EXTRAM_4M }, // Street Fighter Zero 3 + { "T-1229G", CART_EXTRAM_4M }, // Vampire Savior + { "T-1226G", CART_EXTRAM_4M }, // X-Men vs. Street Fighter + // + // + // + { nullptr, CART_CS1RAM_16M, { 0x4a, 0xf9, 0xff, 0x30, 0xea, 0x54, 0xfe, 0x3a, 0x79, 0xa7, 0x68, 0x69, 0xae, 0xde, 0x55, 0xbb } }, // Heart of Darkness (Prototype) + }; + + for(auto& ca : cartdb) + { + if((ca.sgid && !strcmp(ca.sgid, sgid)) || (!ca.sgid && !memcmp(ca.fd_id, fd_id, 16))) + { + *cart_type = ca.cart_type; + return true; + } + } + return false; +} + +} diff --git a/waterbox/ss/db.h b/waterbox/ss/db.h new file mode 100644 index 0000000000..2e9723c4ab --- /dev/null +++ b/waterbox/ss/db.h @@ -0,0 +1,15 @@ +#ifndef __MDFN_SS_DB_H +#define __MDFN_SS_DB_H + +namespace MDFN_IEN_SS +{ + +bool DB_LookupRegionDB(const uint8* fd_id, unsigned* const region); +bool DB_LookupCartDB(const char* sgid, const uint8* fd_id, int* const cart_type); + + +} + + +#endif + diff --git a/waterbox/ss/debug.inc b/waterbox/ss/debug.inc new file mode 100644 index 0000000000..3fd8f3e133 --- /dev/null +++ b/waterbox/ss/debug.inc @@ -0,0 +1,820 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* debug.inc: +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifdef WANT_DEBUGGER +static struct DBGS +{ + enum { NUMBT = 24 }; + + struct + { + uint32 from; + uint32 to; + uint32 branch_count; + int exception; // -1 on no exception. + unsigned vecnum; + bool valid; + } BTEntries[2][NUMBT]; + + bool BTEnabled; + unsigned BTIndex[2]; + + struct SS_BPOINT + { + uint32 A[2]; + }; + + std::vector BreakPointsRead, BreakPointsWrite, BreakPointsPC; + + void (*CPUHook)(uint32, bool); + bool CPUHookContinuous; + + bool FoundBPoint; + + uint32 CurPC[2]; + + unsigned ActiveCPU; +} DBG; + +static void DBG_Break(void) +{ + DBG.FoundBPoint = true; +} + +static void DBG_CheckReadBP(unsigned len, uint32 addr) +{ + for(auto const& bp : DBG.BreakPointsRead) + { + for(uint32 ta = addr; ta != (addr + len); ta++) // TODO: Optimize + { + if(ta >= bp.A[0] && ta <= bp.A[1]) + { + DBG.FoundBPoint = true; + return; + } + } + } +} + +static void DBG_CheckWriteBP(unsigned len, uint32 addr) +{ + for(auto const& bp : DBG.BreakPointsWrite) + { + for(uint32 ta = addr; ta != (addr + len); ta++) // TODO: Optimize + { + if(ta >= bp.A[0] && ta <= bp.A[1]) + { + DBG.FoundBPoint = true; + return; + } + } + } +} + +static void GetAddressSpaceBytes(const char *name, uint32 Address, uint32 Length, uint8 *Buffer) +{ + if(!strcmp(name, "physical")) + { + while(Length--) + { + //Address &= 0xFFFFFFFF; + //*Buffer = CPU->PeekMem8(Address); + Address++; + Buffer++; + } + } + else if(!strcmp(name, "workraml")) + { + while(Length--) + { + Address &= 0xFFFFF; + *Buffer = ne16_rbo_be(WorkRAML, Address); + Address++; + Buffer++; + } + } + else if(!strcmp(name, "workramh")) + { + while(Length--) + { + Address &= 0xFFFFF; + *Buffer = ne16_rbo_be(WorkRAMH, Address); + Address++; + Buffer++; + } + } + else if(!strcmp(name, "scspram")) + { + while(Length--) + { + Address &= 0x7FFFF; + *Buffer = SOUND_PeekRAM(Address); + Address++; + Buffer++; + } + } + else if(!strcmp(name, "dspprog")) + { + while(Length--) + { + Address &= 0x3FF; + *Buffer = SCU_DSP_PeekProgRAM(Address >> 2) >> (((Address & 0x3) ^ 0x3) << 3); + Address++; + Buffer++; + } + } + else if(!strcmp(name, "vdp1vram")) + { + while(Length--) + { + Address &= 0x7FFFF; + *Buffer = VDP1::PeekVRAM(Address); + Address++; + Buffer++; + } + } + else if(!strcmp(name, "vdp2vram")) + { + while(Length--) + { + Address &= 0x7FFFF; + *Buffer = VDP2::PeekVRAM(Address); + Address++; + Buffer++; + } + } +} + + +static void PutAddressSpaceBytes(const char *name, uint32 Address, uint32 Length, uint32 Granularity, bool hl, const uint8 *Buffer) +{ + if(!strcmp(name, "physical")) + { + while(Length--) + { + //Address &= 0xFFFFFFFF; + //CPU->PokeMem8(Address, *Buffer); + Address++; + Buffer++; + } + } + else if(!strcmp(name, "workramh")) + { + while(Length--) + { + Address &= 0xFFFFF; + ne16_wbo_be(WorkRAMH, Address, *Buffer); + Address++; + Buffer++; + } + } + else if(!strcmp(name, "scspram")) + { + while(Length--) + { + Address &= 0x7FFFF; + SOUND_PokeRAM(Address, *Buffer); + Address++; + Buffer++; + } + } + else if(!strcmp(name, "vdp1vram")) + { + while(Length--) + { + Address &= 0x7FFFF; + VDP1::PokeVRAM(Address, *Buffer); + Address++; + Buffer++; + } + } + else if(!strcmp(name, "vdp2vram")) + { + while(Length--) + { + Address &= 0x7FFFF; + VDP2::PokeVRAM(Address, *Buffer); + Address++; + Buffer++; + } + } +} + + +static uint32 DBG_MemPeek(uint32 A, unsigned int bsize, bool hl, bool logical) +{ +/* + uint32 ret = 0; + + for(unsigned int i = 0; i < bsize; i++) + ret |= CPU->PeekMem8(A + i) << (i * 8); + + return(ret); +*/ + return 0xAA; +} + + +static MDFN_COLD void DBG_FlushBreakPoints(int type) +{ + if(type == BPOINT_READ) + DBG.BreakPointsRead.clear(); + else if(type == BPOINT_WRITE) + DBG.BreakPointsWrite.clear(); + else if(type == BPOINT_PC) + DBG.BreakPointsPC.clear(); +} + +static MDFN_COLD void DBG_AddBreakPoint(int type, unsigned int A1, unsigned int A2, bool logical) +{ + DBGS::SS_BPOINT tmp; + + tmp.A[0] = A1; + tmp.A[1] = A2; + + if(type == BPOINT_READ) + DBG.BreakPointsRead.push_back(tmp); + else if(type == BPOINT_WRITE) + DBG.BreakPointsWrite.push_back(tmp); + else if(type == BPOINT_PC) + DBG.BreakPointsPC.push_back(tmp); +} + +static void DBG_SetCPUCallback(void (*callb)(uint32 PC, bool bpoint), bool continuous) +{ + DBG.CPUHook = callb; + DBG.CPUHookContinuous = continuous; +} + +static void DBG_EnableBranchTrace(bool enable) +{ + if((DBG.BTEnabled ^ enable) & DBG.BTEnabled) + { + for(unsigned which = 0; which < 2; which++) + for(unsigned i = 0; i < DBGS::NUMBT; i++) + DBG.BTEntries[which][i].valid = false; + } + + DBG.BTEnabled = enable; +} + +static void DBG_AddBranchTrace(unsigned which, uint32 to, int exception, unsigned vecnum = 0) +{ + const uint32 from = DBG.CurPC[which]; + auto *prevbt = &DBG.BTEntries[which][(DBG.BTIndex[which] + DBGS::NUMBT - 1) % DBGS::NUMBT]; + + //if(BTEntries[(BTIndex - 1) & 0xF] == PC) return; + + if(prevbt->from == from && prevbt->to == to && prevbt->exception == exception && prevbt->branch_count < 0xFFFFFFFF && prevbt->valid) + prevbt->branch_count++; + else + { + auto& bte = DBG.BTEntries[which][DBG.BTIndex[which]]; + bte.from = from; + bte.to = to; + bte.exception = exception; + bte.vecnum = vecnum; + bte.branch_count = 1; + bte.valid = true; + + DBG.BTIndex[which] = (DBG.BTIndex[which] + 1) % DBGS::NUMBT; + } +} + +static std::vector DBG_GetBranchTrace(void) +{ + std::vector ret; + BranchTraceResult tmp; + + for(unsigned x = 0; x < DBGS::NUMBT; x++) + { + char estr[32]; + const auto* bt = &DBG.BTEntries[DBG.ActiveCPU][(x + DBG.BTIndex[DBG.ActiveCPU]) % DBGS::NUMBT]; + + if(!bt->valid) + continue; + + tmp.count = bt->branch_count; + trio_snprintf(tmp.from, sizeof(tmp.from), "%08x", bt->from); + trio_snprintf(tmp.to, sizeof(tmp.to), "%08x", bt->to); + + trio_snprintf(estr, sizeof(estr), "UNK"); + + switch(bt->exception) + { + case -1: + estr[0] = 0; + break; + + case SH7095::EXCEPTION_POWERON: + trio_snprintf(estr, sizeof(estr), "PRST"); + break; + + case SH7095::EXCEPTION_RESET: + trio_snprintf(estr, sizeof(estr), "MRST"); + break; + + case SH7095::EXCEPTION_ILLINSTR: + trio_snprintf(estr, sizeof(estr), "ILL"); + break; + + case SH7095::EXCEPTION_ILLSLOT: + trio_snprintf(estr, sizeof(estr), "ILLS"); + break; + + case SH7095::EXCEPTION_CPUADDR: + trio_snprintf(estr, sizeof(estr), "CPUA"); + break; + + case SH7095::EXCEPTION_DMAADDR: + trio_snprintf(estr, sizeof(estr), "DMAA"); + break; + + case SH7095::EXCEPTION_NMI: + trio_snprintf(estr, sizeof(estr), "NMI"); + break; + + case SH7095::EXCEPTION_BREAK: + trio_snprintf(estr, sizeof(estr), "BRK"); + break; + + case SH7095::EXCEPTION_TRAP: + trio_snprintf(estr, sizeof(estr), "TRAP%02X", bt->vecnum); + break; + + case SH7095::EXCEPTION_INT: + trio_snprintf(estr, sizeof(estr), "INT%02X", bt->vecnum); + break; + } + + trio_snprintf(tmp.code, sizeof(tmp.code), "%s", estr); + + ret.push_back(tmp); + } + return(ret); +} + +template +static void DBG_CPUHandler(const sscpu_timestamp_t timestamp) +{ + const uint32 PC = CPU[which].GetRegister(SH7095::GSREG_PC_ID, NULL, 0); + + if(which != DBG.ActiveCPU) + { + DBG.CurPC[which] = PC; + return; + } + +#if 0 + if(LogFunc) + { + static const uint32 addr_mask[8] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF, 0x1FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + uint32 tpc = PC & addr_mask[PC >> 29];; + + if(MDFN_UNLIKELY(tpc <= 0xC0)) + { + if(tpc == 0xA0 || tpc == 0xB0 || tpc == 0xC0) + { + const uint32 function = CPU->GetRegister(PS_CPU::GSREG_GPR + 9, NULL, 0); + + if(tpc != 0xB0 || function != 0x17) + { + char tmp[64]; + trio_snprintf(tmp, sizeof(tmp), "0x%02x:0x%02x", PC & 0xFF, function); + LogFunc("BIOS", tmp); + } + } + } + } +#endif + + for(auto& bp : DBG.BreakPointsPC) + { + if(PC >= bp.A[0] && PC <= bp.A[1]) + { + DBG.FoundBPoint = true; + break; + } + } + + CPU[which].CheckRWBreakpoints(DBG_CheckReadBP, DBG_CheckWriteBP); + //CPU->CheckBreakpoints(CheckCPUBPCallB, CPU->PeekMem32(PC)); + + DBG.CPUHookContinuous |= DBG.FoundBPoint; + + if(DBG.CPUHookContinuous && DBG.CPUHook) + { + ForceEventUpdates(timestamp); + DBG.CPUHook(PC, DBG.FoundBPoint); + } + + DBG.FoundBPoint = false; + // + // + // No, no, this isn't right for dual-CPUs(FIXME): + DBG.CurPC[which] = CPU[which].GetRegister(SH7095::GSREG_PC_ID, NULL, 0); +} + + +static bool DBG_NeedCPUHooks(void) +{ + return DBG.BTEnabled || DBG.CPUHook || DBG.BreakPointsPC.size() || DBG.BreakPointsRead.size() || DBG.BreakPointsWrite.size(); +} + +// TODO: Standard peek functions +static INLINE uint16 DBG_DisPeek16(uint32 A) +{ + return *(uint16*)(SH7095_FastMap[A >> SH7095_EXT_MAP_GRAN_BITS] + A); +} + +static INLINE uint32 DBG_DisPeek32(uint32 A) +{ + uint32 ret; + + ret = *(uint16*)(SH7095_FastMap[A >> SH7095_EXT_MAP_GRAN_BITS] + A) << 16; + A |= 2; + ret |= *(uint16*)(SH7095_FastMap[A >> SH7095_EXT_MAP_GRAN_BITS] + A) << 0; + + return ret; +} + +static void DBG_Disassemble(uint32 &A, uint32 SpecialA, char *TextBuf) +{ + if(A & 0x1) + { + strncpy(TextBuf, "UNALIGNED", 256); + A &= ~0x1; + } + else + { + uint16 instr; + + if(A == CPU[DBG.ActiveCPU].GetRegister(SH7095::GSREG_PC_ID, NULL, 0)) + instr = CPU[DBG.ActiveCPU].GetRegister(SH7095::GSREG_PID, NULL, 0); + else if(A == CPU[DBG.ActiveCPU].GetRegister(SH7095::GSREG_PC_IF, NULL, 0)) + instr = CPU[DBG.ActiveCPU].GetRegister(SH7095::GSREG_PIF, NULL, 0); + else + instr = DBG_DisPeek16(A); + + SH7095::Disassemble(instr, A + 4, TextBuf, DBG_DisPeek16, DBG_DisPeek32); + } + + char* tlc = TextBuf; + + while((uint8)*tlc != 0) + { + *tlc = tolower(*tlc); + tlc++; + } + + A += 2; +} + +static MDFN_COLD void DBG_ToggleSyntax(void) +{ + // Right, "syntax". ;) + DBG.ActiveCPU = !DBG.ActiveCPU; +} +// +// +// + +static const RegType DBG_Regs_CPU[] = +{ + { SH7095::GSREG_PC_ID, "PC", "PC (Effective)", 4 }, + { SH7095::GSREG_RPC, "RPC", "PC (Real)", 4 }, + + { SH7095::GSREG_PID, "PID", "Pipeline ID Buffer", 4 }, + { SH7095::GSREG_PIF, "PIF", "Pipeline IF Buffer", 4 }, + + { SH7095::GSREG_EP, "EP", "Exception Pending", 4 }, + + { SH7095::GSREG_R0, "R0", "R0", 4 }, + { SH7095::GSREG_R1, "R1", "R1", 4 }, + { SH7095::GSREG_R2, "R2", "R2", 4 }, + { SH7095::GSREG_R3, "R3", "R3", 4 }, + { SH7095::GSREG_R4, "R4", "R4", 4 }, + { SH7095::GSREG_R5, "R5", "R5", 4 }, + { SH7095::GSREG_R6, "R6", "R6", 4 }, + { SH7095::GSREG_R7, "R7", "R7", 4 }, + { SH7095::GSREG_R8, "R8", "R8", 4 }, + { SH7095::GSREG_R9, "R9", "R9", 4 }, + { SH7095::GSREG_R10, "R10", "R10", 4 }, + { SH7095::GSREG_R11, "R11", "R11", 4 }, + { SH7095::GSREG_R12, "R12", "R12", 4 }, + { SH7095::GSREG_R13, "R13", "R13", 4 }, + { SH7095::GSREG_R14, "R14", "R14", 4 }, + { SH7095::GSREG_R15, "R15", "R15/Stack Pointer", 4 }, + + { 0, "------", "", 0xFFFF }, + + { SH7095::GSREG_SR, "SR", "Status Register", 4 }, + { SH7095::GSREG_GBR, "GBR", "Global Base Register", 4 }, + { SH7095::GSREG_VBR, "VBR", "Vector Base Register", 4 }, + + { 0, "------", "", 0xFFFF }, + + { SH7095::GSREG_MACH, "MACH", "Multiply-and-Accumulate High", 4 }, + { SH7095::GSREG_MACL, "MACL", "Multiply-and-Accumulate Low", 4 }, + + { 0, "------", "", 0xFFFF }, + + { SH7095::GSREG_PR, "PR", "Procedure Register", 4 }, + + { 0, "------", "", 0xFFFF }, + + { SH7095::GSREG_NMIL, "NMIL", "NMI Level(Input)", 1 }, + { SH7095::GSREG_IRL, "IRL", "Interrupt Level(Input)", 1 }, + { SH7095::GSREG_IPRA, "IPRA", "IPRA", 2 }, + { SH7095::GSREG_IPRB, "IPRB", "IPRB", 2 }, + { SH7095::GSREG_VCRWDT, "VCRWDT", "VCRWDT", 2 }, + { SH7095::GSREG_VCRA, "VCRA", "VCRA", 2 }, + { SH7095::GSREG_VCRB, "VCRB", "VCRB", 2 }, + { SH7095::GSREG_VCRC, "VCRC", "VCRC", 2 }, + { SH7095::GSREG_VCRD, "VCRD", "VCRD", 2 }, + { SH7095::GSREG_ICR, "ICR", "ICR", 2 }, + + { 0, "------", "", 0xFFFF }, + + { SH7095::GSREG_DVSR, "DVSR", "Divisor", 4 }, + { SH7095::GSREG_DVDNT, "DVDNT", "DVDNT", 4 }, + { SH7095::GSREG_DVDNTH, "DVDNTH", "DVDNTH", 4 }, + { SH7095::GSREG_DVDNTL, "DVDNTL", "DVDNTL", 4 }, + { SH7095::GSREG_DVDNTHS, "DVDNTHS", "DVDNTH Shadow", 4 }, + { SH7095::GSREG_DVDNTLS, "DVDNTLS", "DVDNTL Shadow", 4 }, + { SH7095::GSREG_VCRDIV, "VCRDIV", "VCRDIV", 2 }, + { SH7095::GSREG_DVCR, "DVCR", "DVCR", 1 }, + + { 0, "------", "", 0xFFFF }, + + { SH7095::GSREG_WTCSR, "WTCSR", "WTCSR", 1 }, + { SH7095::GSREG_WTCSRM, "WTCSRM", "WTCSRM", 1 }, + { SH7095::GSREG_WTCNT, "WTCNT", "WTCNT", 1 }, + { SH7095::GSREG_RSTCSR, "RSTCSR", "RSTCSR", 1 }, + { SH7095::GSREG_RSTCSRM, "RSTCSRM", "RSTCSRM", 1 }, + + { 0, "", "", 0 }, +}; + +static const RegType DBG_Regs_CPUE[] = +{ + { SH7095::GSREG_DMAOR, "DMAOR", "DMAOR", 1 }, + { SH7095::GSREG_DMAORM, "DMAORM", "DMAORM", 1 }, + + { 0, "--DMACH0:--", "", 0xFFFF }, + { SH7095::GSREG_DMA0_SAR, "SAR", "SAR", 4 }, + { SH7095::GSREG_DMA0_DAR, "DAR", "DAR", 4 }, + { SH7095::GSREG_DMA0_TCR, "TCR", "TCR", 4 }, + { SH7095::GSREG_DMA0_CHCR, "CHCR", "CHCR", 2 }, + { SH7095::GSREG_DMA0_CHCRM, "CHCRM", "CHCRM", 2 }, + { SH7095::GSREG_DMA0_VCR, "VCR", "VCR", 1 }, + { SH7095::GSREG_DMA0_DRCR, "DRCR", "DRCR", 1 }, + + { 0, "--DMACH1:--", "", 0xFFFF }, + { SH7095::GSREG_DMA1_SAR, "SAR", "SAR", 4 }, + { SH7095::GSREG_DMA1_DAR, "DAR", "DAR", 4 }, + { SH7095::GSREG_DMA1_TCR, "TCR", "TCR", 4 }, + { SH7095::GSREG_DMA1_CHCR, "CHCR", "CHCR", 2 }, + { SH7095::GSREG_DMA1_CHCRM, "CHCRM", "CHCRM", 2 }, + { SH7095::GSREG_DMA1_VCR, "VCR", "VCR", 1 }, + { SH7095::GSREG_DMA1_DRCR, "DRCR", "DRCR", 1 }, + + { 0, "-----------", "", 0xFFFF }, + + { SH7095::GSREG_FRC, "FRC", "FRC", 2 }, + { SH7095::GSREG_OCR0, "OCRA", "OCRA", 2 }, + { SH7095::GSREG_OCR1, "OCRB", "OCRB", 2 }, + { SH7095::GSREG_FICR, "FICR", "FICR", 2 }, + { SH7095::GSREG_TIER, "TIER", "TIER", 1 }, + { SH7095::GSREG_FTCSR, "FTCSR", "FTCSR", 1 }, + { SH7095::GSREG_FTCSRM, "FTCSRM", "FTCSRM", 1 }, + { SH7095::GSREG_TCR, "TCR", "TCR", 1 }, + { SH7095::GSREG_TOCR, "TOCR", "TOCR", 1 }, + { SH7095::GSREG_RWT, "RWT", "R/W Temp", 1 }, + + { 0, "", "", 0 }, +}; + +static uint32 DBG_GetRegister_CPU(const unsigned int id, char* special, const uint32 special_len) +{ + return CPU[DBG.ActiveCPU].GetRegister(id, special, special_len); +} + +static MDFN_COLD void DBG_SetRegister_CPU(const unsigned int id, uint32 value) +{ + CPU[DBG.ActiveCPU].SetRegister(id, value); +} + +static const RegGroupType DBG_RegGroup_CPU = +{ + NULL, + DBG_Regs_CPU, + DBG_GetRegister_CPU, + DBG_SetRegister_CPU +}; + +static const RegGroupType DBG_RegGroup_CPUE = +{ + NULL, + DBG_Regs_CPUE, + DBG_GetRegister_CPU, + DBG_SetRegister_CPU +}; + + +static const RegType DBG_Regs_SCU[] = +{ + { SCU_GSREG_ILEVEL, "ILevel", "IRL Output to SH2-M", 1 }, + { SCU_GSREG_IVEC, "IVec", "Pending IRQ Vector Number", 1 }, + + { 0, "------", "", 0xFFFF }, + + { SCU_GSREG_IASSERTED, "IAss", "Status of Input IRQ Lines", 4 }, + { SCU_GSREG_IPENDING, "IPend", "Pending IRQs", 4 }, + { SCU_GSREG_IMASK, "IMask", "IRQ Mask", 2 }, + + { 0, "------", "", 0xFFFF }, + + { SCU_GSREG_TENBL, "TENBL", "Timers Enable", 0x100 | 1 }, + + { SCU_GSREG_T0CNT, "T0CNT", "Timer0 Counter", 0x100 | 10 }, + { SCU_GSREG_T0CMP, "T0CMP", "Timer0 Compare Value", 0x100 | 10 }, + { SCU_GSREG_T0MET, "T0MET", "Timer0 Met", 0x100 | 1 }, + + { SCU_GSREG_T1RLV, "T1RLV", "Timer1 Reload Value", 0x100 | 9 }, + { SCU_GSREG_T1CNT, "T1CNT", "Timer1 Counter", 0x100 | 9 }, + { SCU_GSREG_T1MOD, "T1MOD", "Timer1 Mode", 0x100 | 1 }, + { SCU_GSREG_T1MET, "T1MET", "Timer1 Met", 0x100 | 1 }, + + { 0, "--DSP:--", "", 0xFFFF }, + + { SCU_GSREG_DSP_EXEC, "EXEC", "Executing", 0x100 | 1 }, + { SCU_GSREG_DSP_PAUSE, "PAUSE", "Paused", 0x100 | 1 }, + { SCU_GSREG_DSP_PC, "PC", "Program Counter", 1 }, + { SCU_GSREG_DSP_END, "END", "End Flag", 0x100 | 1 }, + + { 0, "", "", 0 }, +}; + +static const RegGroupType DBG_RegGroup_SCU = +{ + NULL, + DBG_Regs_SCU, + SCU_GetRegister, + SCU_SetRegister +}; + +// +// + +static const RegType DBG_Regs_VDP1_VDP2_SCSP[] = +{ + { 0, "------", "", 0xFFFF }, + + { (1 << 16) | VDP2::GSREG_LINE, "Line", "Line", 2 }, + { (1 << 16) | VDP2::GSREG_DON, "DON", "Display On", 0x100 | 1 }, + { (1 << 16) | VDP2::GSREG_BM, "BM", "Border Mode", 0x100 | 1 }, + { (1 << 16) | VDP2::GSREG_IM, "IM", "Interlace Mode", 0x100 | 2 }, + { (1 << 16) | VDP2::GSREG_VRES, "VRES", "Vertical Resolution", 0x100 | 2 }, + { (1 << 16) | VDP2::GSREG_HRES, "HRES", "Horizontal Resolution", 0x100 | 3 }, + + { 0, "------", "", 0xFFFF }, + + { (2 << 16) | SS_SCSP::GSREG_MVOL, "MVOL", "Master Volume", 0x100 | 4 }, + { (2 << 16) | SS_SCSP::GSREG_DAC18B, "DAC18B", "18-bit DAC Enable", 0x100 | 1 }, + { (2 << 16) | SS_SCSP::GSREG_MEM4MB, "Mem4Mb", "4Mb Memory Enable", 0x100 | 1 }, + { (2 << 16) | SS_SCSP::GSREG_RBP, "RBP", "DSP Ringbuffer Base Address", 0x100 | 7 }, + { (2 << 16) | SS_SCSP::GSREG_RBL, "RBL", "DSP Ringbuffer Length", 0x100 | 2 }, + { (2 << 16) | SS_SCSP::GSREG_MSLC, "MSLC", "Slot to Monitor", 0x100 | 5 }, + + { 0, "", "", 0 }, +}; + +static uint32 VDP1_VDP2_SCSP_GetRegister(const unsigned id, char* const special, const uint32 special_len) +{ + switch(id >> 16) + { + case 0: return 0; //return VDP1::GetRegister((uint16)id, special, special_len); + case 1: return VDP2::GetRegister((uint16)id, special, special_len); + case 2: return SOUND_GetSCSPRegister((uint16)id, special, special_len); + } + + return 0; +} + +static void VDP1_VDP2_SCSP_SetRegister(const unsigned id, const uint32 value) +{ + switch(id >> 16) + { + case 0: break; //return VDP1::GetRegister((uint16)id, special, special_len); + case 1: VDP2::SetRegister((uint16)id, value); break; + case 2: SOUND_SetSCSPRegister((uint16)id, value); break; + } +} + +static const RegGroupType DBG_RegGroup_VDP1_VDP2_SCSP = +{ + NULL, + DBG_Regs_VDP1_VDP2_SCSP, + VDP1_VDP2_SCSP_GetRegister, + VDP1_VDP2_SCSP_SetRegister +}; + +// +// +// +static void DBG_Init(void) MDFN_COLD; +static void DBG_Init(void) +{ + DBG.ActiveCPU = 0; + DBG.BTEnabled = false; + + for(unsigned which = 0; which < 2; which++) + { + DBG.BTIndex[which] = 0; + + for(unsigned i = 0; i < DBGS::NUMBT; i++) + DBG.BTEntries[which][i].valid = false; + } + + DBG.CPUHook = NULL; + DBG.CPUHookContinuous = false; + DBG.FoundBPoint = false; + + MDFNDBG_AddRegGroup(&DBG_RegGroup_CPU); + MDFNDBG_AddRegGroup(&DBG_RegGroup_CPUE); + MDFNDBG_AddRegGroup(&DBG_RegGroup_SCU); + MDFNDBG_AddRegGroup(&DBG_RegGroup_VDP1_VDP2_SCSP); + // + // + // + ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "physical", "SH-2 Physical (TODO)", 27); + ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "workraml", "Low Work RAM", 20); + ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "workramh", "High Work RAM", 20); + ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "scspram", "SCSP RAM", 19); + + ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "dspprog", "DSP Program RAM", 10); + + ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "vdp1vram", "VDP1 VRAM", 19); + ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "vdp2vram", "VDP2 VRAM", 19); +} + +static DebuggerInfoStruct DBGInfo +{ + "SJIS", + + 2, + 2, + + 32, + 27, + + 0x06004000, + ~0U, + + DBG_MemPeek, + + DBG_Disassemble, + DBG_ToggleSyntax, + + NULL, + NULL, + + DBG_FlushBreakPoints, + DBG_AddBreakPoint, + DBG_SetCPUCallback, + + DBG_EnableBranchTrace, + DBG_GetBranchTrace, + + NULL, + NULL, + + NULL, + NULL, +}; +#else +template +static INLINE void DBG_CPUHandler(const sscpu_timestamp_t timestamp) { } +static INLINE void DBG_AddBranchTrace(unsigned which, uint32 to, int exception, unsigned vecnum = 0) { } +static INLINE bool DBG_NeedCPUHooks(void) { return false; } +static INLINE void DBG_Init(void) { } +#endif diff --git a/waterbox/ss/defs.h b/waterbox/ss/defs.h new file mode 100644 index 0000000000..127cf2ef86 --- /dev/null +++ b/waterbox/ss/defs.h @@ -0,0 +1,112 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +typedef uint64_t uint64; +typedef int8_t int8; +typedef int16_t int16; +typedef int32_t int32; +typedef int64_t int64; + +#define MDFN_FASTCALL +#define INLINE inline +#define MDFN_COLD +#define MDFN_HOT +#define NO_INLINE +#define NO_CLONE +#define MDFN_UNLIKELY(p) (p) +#define MDFN_LIKELY(p) (p) +//#define MDFN_ASSUME_ALIGNED(p, align) ((decltype(p))__builtin_assume_aligned((p), (align))) +#define MDFN_ASSUME_ALIGNED(p, align) (p) +#define trio_snprintf snprintf +#define trio_vprintf vprintf +#define trio_printf printf +#define trio_sprintf sprintf +#define TRUE true +#define FALSE false +#ifndef __alignas_is_defined +#define alignas(p) +#endif +#define override // remove for gcc 4.7 +#define final +#define gettext_noop(s) (s) +#define MDFN_MASTERCLOCK_FIXED(n) ((int64)((double)(n) * (1LL << 32))) + +typedef struct +{ + // Pitch(32-bit) must be equal to width and >= the "fb_width" specified in the MDFNGI struct for the emulated system. + // Height must be >= to the "fb_height" specified in the MDFNGI struct for the emulated system. + // The framebuffer pointed to by surface->pixels is written to by the system emulation code. + uint32 *pixels; + int pitch32; + + // Pointer to an array of int32, number of elements = fb_height, set by the driver code. Individual elements written + // to by system emulation code. If the emulated system doesn't support multiple screen widths per frame, or if you handle + // such a situation by outputting at a constant width-per-frame that is the least-common-multiple of the screen widths, then + // you can ignore this. If you do wish to use this, you must set all elements every frame. + int32 *LineWidths; + + // Pointer to sound buffer, set by the driver code, that the emulation code should render sound to. + int16 *SoundBuf; + + // Number of cycles that this frame consumed, using MDFNGI::MasterClock as a time base. + // Set by emulation code. + int64 MasterCycles; + + // Maximum size of the sound buffer, in frames. Set by the driver code. + int32 SoundBufMaxSize; + + // Number of frames currently in internal sound buffer. Set by the system emulation code, to be read by the driver code. + int32 SoundBufSize; + + // Set by the system emulation code every frame, to denote the horizontal and vertical offsets of the image, and the size + // of the image. If the emulated system sets the elements of LineWidths, then the width(w) of this structure + // is ignored while drawing the image. + int32 x, y, h; + + // Set(optionally) by emulation code. If InterlaceOn is true, then assume field height is 1/2 DisplayRect.h, and + // only every other line in surface (with the start line defined by InterlacedField) has valid data + // (it's up to internal Mednafen code to deinterlace it). + bool InterlaceOn; + bool InterlaceField; +} EmulateSpecStruct; + +#define MDFN_printf(...) +#define MDFN_PrintError(...) +#define MDFN_FORMATSTR(...) +#define require assert + +#include "endian.h" + +#include "math_ops.h" + +#include "../emulibc/emulibc.h" +#include "../emulibc/waterboxcore.h" + +extern int32 (*FirmwareSizeCallback)(const char *filename); +extern void (*FirmwareDataCallback)(const char *filename, uint8 *dest); + +extern int setting_ss_slstartp; +extern int setting_ss_slendp; +extern int setting_ss_slstart; +extern int setting_ss_slend; +extern int setting_ss_region_default; +extern int setting_ss_cart; +extern bool setting_ss_correct_aspect; +extern bool setting_ss_h_overscan; +extern bool setting_ss_h_blend; +extern bool setting_ss_region_autodetect; + +extern bool InputLagged; +extern void (*InputCallback)(); + +void AddMemoryDomain(const char* name, const void* ptr, int size, int flags); diff --git a/waterbox/ss/endian.h b/waterbox/ss/endian.h new file mode 100644 index 0000000000..e78a0c577f --- /dev/null +++ b/waterbox/ss/endian.h @@ -0,0 +1,494 @@ +/******************************************************************************/ +/* Mednafen - Multi-system Emulator */ +/******************************************************************************/ +/* endian.h: +** Copyright (C) 2006-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_ENDIAN_H +#define __MDFN_ENDIAN_H + +void Endian_A16_Swap(void *src, uint32 nelements); +void Endian_A32_Swap(void *src, uint32 nelements); +void Endian_A64_Swap(void *src, uint32 nelements); + +void Endian_A16_NE_LE(void *src, uint32 nelements); +void Endian_A32_NE_LE(void *src, uint32 nelements); +void Endian_A64_NE_LE(void *src, uint32 nelements); + +void Endian_A16_NE_BE(void *src, uint32 nelements); +void Endian_A32_NE_BE(void *src, uint32 nelements); +void Endian_A64_NE_BE(void *src, uint32 nelements); + +void Endian_V_NE_LE(void* p, size_t len); +void Endian_V_NE_BE(void* p, size_t len); + +// +// +// + +static INLINE uint32 BitsExtract(const uint8* ptr, const size_t bit_offset, const size_t bit_count) +{ + uint32 ret = 0; + + for(size_t x = 0; x < bit_count; x++) + { + size_t co = bit_offset + x; + bool b = (ptr[co >> 3] >> (co & 7)) & 1; + + ret |= (uint64)b << x; + } + + return ret; +} + +static INLINE void BitsIntract(uint8* ptr, const size_t bit_offset, const size_t bit_count, uint32 value) +{ + for(size_t x = 0; x < bit_count; x++) + { + size_t co = bit_offset + x; + bool b = (value >> x) & 1; + uint8 tmp = ptr[co >> 3]; + + tmp &= ~(1 << (co & 7)); + tmp |= b << (co & 7); + + ptr[co >> 3] = tmp; + } +} + +/* + Regarding safety of calling MDFN_*sb on dynamically-allocated memory with new uint8[], see C++ standard 3.7.3.1(i.e. it should be + safe provided the offsets into the memory are aligned/multiples of the MDFN_*sb access type). malloc()'d and calloc()'d + memory should be safe as well. + + Statically-allocated arrays/memory should be unioned with a big POD type or C++11 "alignas"'d. (May need to audit code to ensure + this is being done). +*/ + +static INLINE uint16 MDFN_bswap16(uint16 v) +{ + return (v << 8) | (v >> 8); +} + +static INLINE uint32 MDFN_bswap32(uint32 v) +{ + return (v << 24) | ((v & 0xFF00) << 8) | ((v >> 8) & 0xFF00) | (v >> 24); +} + +static INLINE uint64 MDFN_bswap64(uint64 v) +{ + return (v << 56) | (v >> 56) | ((v & 0xFF00) << 40) | ((v >> 40) & 0xFF00) | ((uint64)MDFN_bswap32(v >> 16) << 16); +} + +#ifdef LSB_FIRST + #define MDFN_ENDIANH_IS_BIGENDIAN 0 +#else + #define MDFN_ENDIANH_IS_BIGENDIAN 1 +#endif + +// +// X endian. +// +template +static INLINE T MDFN_deXsb(const void* ptr) +{ + T tmp; + + memcpy(&tmp, MDFN_ASSUME_ALIGNED(ptr, (aligned ? sizeof(T) : 1)), sizeof(T)); + + if(isbigendian != -1 && isbigendian != MDFN_ENDIANH_IS_BIGENDIAN) + { + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Gummy penguins."); + + if(sizeof(T) == 8) + return MDFN_bswap64(tmp); + else if(sizeof(T) == 4) + return MDFN_bswap32(tmp); + else if(sizeof(T) == 2) + return MDFN_bswap16(tmp); + } + + return tmp; +} + +// +// Native endian. +// +template +static INLINE T MDFN_densb(const void* ptr) +{ + return MDFN_deXsb<-1, T, aligned>(ptr); +} + +// +// Little endian. +// +template +static INLINE T MDFN_delsb(const void* ptr) +{ + return MDFN_deXsb<0, T, aligned>(ptr); +} + +template +static INLINE uint16 MDFN_de16lsb(const void* ptr) +{ + return MDFN_delsb(ptr); +} + +static INLINE uint32 MDFN_de24lsb(const void* ptr) +{ + const uint8* ptr_u8 = (const uint8*)ptr; + + return (ptr_u8[0] << 0) | (ptr_u8[1] << 8) | (ptr_u8[2] << 16); +} + +template +static INLINE uint32 MDFN_de32lsb(const void* ptr) +{ + return MDFN_delsb(ptr); +} + +template +static INLINE uint64 MDFN_de64lsb(const void* ptr) +{ + return MDFN_delsb(ptr); +} + +// +// Big endian. +// +template +static INLINE T MDFN_demsb(const void* ptr) +{ + return MDFN_deXsb<1, T, aligned>(ptr); +} + +template +static INLINE uint16 MDFN_de16msb(const void* ptr) +{ + return MDFN_demsb(ptr); +} + +static INLINE uint32 MDFN_de24msb(const void* ptr) +{ + const uint8* ptr_u8 = (const uint8*)ptr; + + return (ptr_u8[0] << 16) | (ptr_u8[1] << 8) | (ptr_u8[2] << 0); +} + +template +static INLINE uint32 MDFN_de32msb(const void* ptr) +{ + return MDFN_demsb(ptr); +} + +template +static INLINE uint64 MDFN_de64msb(const void* ptr) +{ + return MDFN_demsb(ptr); +} + +// +// +// +// +// +// +// +// + +// +// X endian. +// +template +static INLINE void MDFN_enXsb(void* ptr, T value) +{ + T tmp = value; + + if(isbigendian != -1 && isbigendian != MDFN_ENDIANH_IS_BIGENDIAN) + { + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Gummy penguins."); + + if(sizeof(T) == 8) + tmp = MDFN_bswap64(value); + else if(sizeof(T) == 4) + tmp = MDFN_bswap32(value); + else if(sizeof(T) == 2) + tmp = MDFN_bswap16(value); + } + + memcpy(MDFN_ASSUME_ALIGNED(ptr, (aligned ? sizeof(T) : 1)), &tmp, sizeof(T)); +} + +// +// Native endian. +// +template +static INLINE void MDFN_ennsb(void* ptr, T value) +{ + MDFN_enXsb<-1, T, aligned>(ptr, value); +} + +// +// Little endian. +// +template +static INLINE void MDFN_enlsb(void* ptr, T value) +{ + MDFN_enXsb<0, T, aligned>(ptr, value); +} + +template +static INLINE void MDFN_en16lsb(void* ptr, uint16 value) +{ + MDFN_enlsb(ptr, value); +} + +static INLINE void MDFN_en24lsb(void* ptr, uint32 value) +{ + uint8* ptr_u8 = (uint8*)ptr; + + ptr_u8[0] = value >> 0; + ptr_u8[1] = value >> 8; + ptr_u8[2] = value >> 16; +} + +template +static INLINE void MDFN_en32lsb(void* ptr, uint32 value) +{ + MDFN_enlsb(ptr, value); +} + +template +static INLINE void MDFN_en64lsb(void* ptr, uint64 value) +{ + MDFN_enlsb(ptr, value); +} + + +// +// Big endian. +// +template +static INLINE void MDFN_enmsb(void* ptr, T value) +{ + MDFN_enXsb<1, T, aligned>(ptr, value); +} + +template +static INLINE void MDFN_en16msb(void* ptr, uint16 value) +{ + MDFN_enmsb(ptr, value); +} + +static INLINE void MDFN_en24msb(void* ptr, uint32 value) +{ + uint8* ptr_u8 = (uint8*)ptr; + + ptr_u8[0] = value >> 16; + ptr_u8[1] = value >> 8; + ptr_u8[2] = value >> 0; +} + +template +static INLINE void MDFN_en32msb(void* ptr, uint32 value) +{ + MDFN_enmsb(ptr, value); +} + +template +static INLINE void MDFN_en64msb(void* ptr, uint64 value) +{ + MDFN_enmsb(ptr, value); +} + + +// +// +// +// +// +// + +template +static INLINE uint8* ne16_ptr_be(BT* const base, const size_t byte_offset) +{ +#ifdef MSB_FIRST + return (uint8*)base + (byte_offset &~ (sizeof(T) - 1)); +#else + return (uint8*)base + (((byte_offset &~ (sizeof(T) - 1)) ^ (2 - std::min(2, sizeof(T))))); +#endif +} + +template +static INLINE void ne16_wbo_be(uint16* const base, const size_t byte_offset, const T value) +{ + uint8* const ptr = ne16_ptr_be(base, byte_offset); + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size"); + + if(sizeof(T) == 4) + { + uint16* const ptr16 = (uint16*)ptr; + + ptr16[0] = value >> 16; + ptr16[1] = value; + } + else + *(T*)ptr = value; +} + +template +static INLINE T ne16_rbo_be(const uint16* const base, const size_t byte_offset) +{ + uint8* const ptr = ne16_ptr_be(base, byte_offset); + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size"); + + if(sizeof(T) == 4) + { + uint16* const ptr16 = (uint16*)ptr; + T tmp; + + tmp = ptr16[0] << 16; + tmp |= ptr16[1]; + + return tmp; + } + else + return *(T*)ptr; +} + +template +static INLINE void ne16_rwbo_be(uint16* const base, const size_t byte_offset, T* value) +{ + if(IsWrite) + ne16_wbo_be(base, byte_offset, *value); + else + *value = ne16_rbo_be(base, byte_offset); +} + +// +// +// + +template +static INLINE uint8* ne16_ptr_le(BT* const base, const size_t byte_offset) +{ +#ifdef LSB_FIRST + return (uint8*)base + (byte_offset &~ (sizeof(T) - 1)); +#else + return (uint8*)base + (((byte_offset &~ (sizeof(T) - 1)) ^ (2 - std::min(2, sizeof(T))))); +#endif +} + +template +static INLINE void ne16_wbo_le(uint16* const base, const size_t byte_offset, const T value) +{ + uint8* const ptr = ne16_ptr_le(base, byte_offset); + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size"); + + if(sizeof(T) == 4) + { + uint16* const ptr16 = (uint16*)ptr; + + ptr16[0] = value; + ptr16[1] = value >> 16; + } + else + *(T*)ptr = value; +} + +template +static INLINE T ne16_rbo_le(const uint16* const base, const size_t byte_offset) +{ + uint8* const ptr = ne16_ptr_le(base, byte_offset); + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size"); + + if(sizeof(T) == 4) + { + uint16* const ptr16 = (uint16*)ptr; + T tmp; + + tmp = ptr16[0]; + tmp |= ptr16[1] << 16; + + return tmp; + } + else + return *(T*)ptr; +} + + +template +static INLINE void ne16_rwbo_le(uint16* const base, const size_t byte_offset, T* value) +{ + if(IsWrite) + ne16_wbo_le(base, byte_offset, *value); + else + *value = ne16_rbo_le(base, byte_offset); +} + +// +// +// +template +static INLINE uint8* ne64_ptr_be(uint64* const base, const size_t byte_offset) +{ +#ifdef MSB_FIRST + return (uint8*)base + (byte_offset &~ (sizeof(T) - 1)); +#else + return (uint8*)base + (((byte_offset &~ (sizeof(T) - 1)) ^ (8 - sizeof(T)))); +#endif +} + +template +static INLINE void ne64_wbo_be(uint64* const base, const size_t byte_offset, const T value) +{ + uint8* const ptr = ne64_ptr_be(base, byte_offset); + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Unsupported type size"); + + memcpy(MDFN_ASSUME_ALIGNED(ptr, sizeof(T)), &value, sizeof(T)); +} + +template +static INLINE T ne64_rbo_be(uint64* const base, const size_t byte_offset) +{ + uint8* const ptr = ne64_ptr_be(base, byte_offset); + T ret; + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size"); + + memcpy(&ret, MDFN_ASSUME_ALIGNED(ptr, sizeof(T)), sizeof(T)); + + return ret; +} + +template +static INLINE void ne64_rwbo_be(uint64* const base, const size_t byte_offset, T* value) +{ + if(IsWrite) + ne64_wbo_be(base, byte_offset, *value); + else + *value = ne64_rbo_be(base, byte_offset); +} + +#endif diff --git a/waterbox/ss/input/3dpad.cpp b/waterbox/ss/input/3dpad.cpp new file mode 100644 index 0000000000..04c489ec88 --- /dev/null +++ b/waterbox/ss/input/3dpad.cpp @@ -0,0 +1,131 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* 3dpad.cpp: +** Copyright (C) 2016-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "common.h" +#include "3dpad.h" + +namespace MDFN_IEN_SS +{ + +IODevice_3DPad::IODevice_3DPad() : dbuttons(0), mode(false) +{ + +} + +IODevice_3DPad::~IODevice_3DPad() +{ + +} + +void IODevice_3DPad::Power(void) +{ + phase = -1; + tl = true; + data_out = 0x01; +} + +void IODevice_3DPad::UpdateInput(const uint8 *data, const int32 time_elapsed) +{ + const uint16 dtmp = MDFN_de16lsb(&data[0]); + + dbuttons = (dbuttons & 0x8800) | (dtmp & 0x0FFF); + mode = (bool)(dtmp & 0x1000); + + thumb[0] = data[2]; + thumb[1] = data[3]; + shoulder[0] = data[4]; + shoulder[1] = data[5]; + + for (unsigned w = 0; w < 2; w++) + { + // May not be right for digital mode, but shouldn't matter too much: + if (shoulder[w] <= 0x55) + dbuttons &= ~(0x0800 << (w << 2)); + else if (shoulder[w] >= 0x8E) + dbuttons |= 0x0800 << (w << 2); + } +} + +uint8 IODevice_3DPad::UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) +{ + uint8 tmp; + + if(smpc_out & 0x40) + { + phase = -1; + tl = true; + data_out = 0x01; + } + else + { + if((bool)(smpc_out & 0x20) != tl) + { + if(phase < 15) + { + tl = !tl; + phase++; + } + + if(!phase) + { + if(mode) + { + buffer[ 0] = 0x1; + buffer[ 1] = 0x6; + buffer[ 2] = (((dbuttons >> 0) & 0xF) ^ 0xF); + buffer[ 3] = (((dbuttons >> 4) & 0xF) ^ 0xF); + buffer[ 4] = (((dbuttons >> 8) & 0xF) ^ 0xF); + buffer[ 5] = (((dbuttons >> 12) & 0xF) ^ 0xF); + buffer[ 6] = (thumb[0] >> 4) & 0xF; + buffer[ 7] = (thumb[0] >> 0) & 0xF; + buffer[ 8] = (thumb[1] >> 4) & 0xF; + buffer[ 9] = (thumb[1] >> 0) & 0xF; + buffer[10] = (shoulder[0] >> 4) & 0xF; + buffer[11] = (shoulder[0] >> 0) & 0xF; + buffer[12] = (shoulder[1] >> 4) & 0xF; + buffer[13] = (shoulder[1] >> 0) & 0xF; + buffer[14] = 0x0; + buffer[15] = 0x1; + } + else + { + phase = 8; + buffer[ 8] = 0x0; + buffer[ 9] = 0x2; + buffer[10] = (((dbuttons >> 0) & 0xF) ^ 0xF); + buffer[11] = (((dbuttons >> 4) & 0xF) ^ 0xF); + buffer[12] = (((dbuttons >> 8) & 0xF) ^ 0xF); + buffer[13] = (((dbuttons >> 12) & 0xF) ^ 0xF); + buffer[14] = 0x0; + buffer[15] = 0x1; + } + } + + data_out = buffer[phase]; + } + } + + tmp = (tl << 4) | data_out; + + return (smpc_out & (smpc_out_asserted | 0xE0)) | (tmp &~ smpc_out_asserted); +} + +} diff --git a/waterbox/ss/input/3dpad.h b/waterbox/ss/input/3dpad.h new file mode 100644 index 0000000000..0eea5a60d3 --- /dev/null +++ b/waterbox/ss/input/3dpad.h @@ -0,0 +1,53 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* 3dpad.h: +** Copyright (C) 2016-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_INPUT_3DPAD_H +#define __MDFN_SS_INPUT_3DPAD_H + +namespace MDFN_IEN_SS +{ + +class IODevice_3DPad final : public IODevice +{ + public: + IODevice_3DPad() MDFN_COLD; + virtual ~IODevice_3DPad() override MDFN_COLD; + + virtual void Power(void) override MDFN_COLD; + virtual void UpdateInput(const uint8* data, const int32 time_elapsed) override; + + virtual uint8 UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) override; + + private: + uint16 dbuttons; + uint8 thumb[2]; + uint8 shoulder[2]; + + uint8 buffer[0x10]; + uint8 data_out; + bool tl; + int8 phase; + bool mode; +}; + +} + +#endif diff --git a/waterbox/ss/input/common.h b/waterbox/ss/input/common.h new file mode 100644 index 0000000000..e868193d45 --- /dev/null +++ b/waterbox/ss/input/common.h @@ -0,0 +1,2 @@ +#include "../ss.h" +#include "../smpc.h" diff --git a/waterbox/ss/input/gamepad.cpp b/waterbox/ss/input/gamepad.cpp new file mode 100644 index 0000000000..80e3560242 --- /dev/null +++ b/waterbox/ss/input/gamepad.cpp @@ -0,0 +1,57 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* gamepad.cpp - Digital Gamepad Emulation +** Copyright (C) 2015-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "common.h" +#include "gamepad.h" + +namespace MDFN_IEN_SS +{ + +IODevice_Gamepad::IODevice_Gamepad() : buttons(~3) +{ + +} + +IODevice_Gamepad::~IODevice_Gamepad() +{ + +} + +void IODevice_Gamepad::Power(void) +{ + +} + +void IODevice_Gamepad::UpdateInput(const uint8* data, const int32 time_elapsed) +{ + buttons = (~(data[0] | (data[1] << 8))) &~ 0x3000; +} + +uint8 IODevice_Gamepad::UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) +{ + uint8 tmp; + + tmp = (buttons >> ((smpc_out >> 5) << 2)) & 0xF; + + return 0x10 | (smpc_out & (smpc_out_asserted | 0xE0)) | (tmp &~ smpc_out_asserted); +} + +} diff --git a/waterbox/ss/input/gamepad.h b/waterbox/ss/input/gamepad.h new file mode 100644 index 0000000000..99a856c487 --- /dev/null +++ b/waterbox/ss/input/gamepad.h @@ -0,0 +1,45 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* gamepad.h: +** Copyright (C) 2015-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_INPUT_GAMEPAD_H +#define __MDFN_SS_INPUT_GAMEPAD_H + +namespace MDFN_IEN_SS +{ + +class IODevice_Gamepad final : public IODevice +{ + public: + IODevice_Gamepad() MDFN_COLD; + virtual ~IODevice_Gamepad() override MDFN_COLD; + + virtual void Power(void) override MDFN_COLD; + virtual void UpdateInput(const uint8* data, const int32 time_elapsed) override; + + virtual uint8 UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) override; + + private: + uint16 buttons; +}; + +} + +#endif diff --git a/waterbox/ss/input/keyboard.cpp b/waterbox/ss/input/keyboard.cpp new file mode 100644 index 0000000000..a5aaf6aa3b --- /dev/null +++ b/waterbox/ss/input/keyboard.cpp @@ -0,0 +1,231 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* keyboard.cpp: +** Copyright (C) 2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +// TODO: Debouncing? + +// +// PS/2 keyboard adapter seems to do PS/2 processing near/at the end of a Saturn-side read sequence, which creates about 1 frame of extra latency +// in practice. We handle things a bit differently here, to avoid the latency. +// +// Also, the PS/2 adapter seems to set the typematic delay to around 250ms, but we emulate it here as 400ms, as 250ms is +// a tad bit too short. It can be changed to 250ms by adjusting a single #if statement, though. +// +// During testing, a couple of early-1990s PS/2 keyboards malfunctioned and failed to work with the PS/2 adapter. +// Not sure why, maybe a power draw issue? +// +// The keyboard emulated doesn't have special Windows-keyboard keys, as they don't appear to work correctly with the PS/2 adapter +// (scancode field is updated, but no make nor break bits are set to 1), and it's good to have some non-shared keys for input grabbing toggling purposes... +// +// + +// make and break bits should not both be set to 1 at the same time. +// pause is special +// new key press halts repeat of held key, and it doesn't restart even if new key is released. +// + +#include "common.h" +#include "keyboard.h" + +namespace MDFN_IEN_SS +{ + +IODevice_Keyboard::IODevice_Keyboard() : phys{0,0,0,0} +{ + +} + +IODevice_Keyboard::~IODevice_Keyboard() +{ + +} + +void IODevice_Keyboard::Power(void) +{ + phase = -1; + tl = true; + data_out = 0x01; + + simbutt = simbutt_pend = 0; + lock = lock_pend = 0; + + mkbrk_pend = 0; + memset(buffer, 0, sizeof(buffer)); + + //memcpy(processed, phys, sizeof(processed)); + memset(processed, 0, sizeof(processed)); + memset(fifo, 0, sizeof(fifo)); + fifo_rdp = 0; + fifo_wrp = 0; + fifo_cnt = 0; + + rep_sc = -1; + rep_dcnt = 0; +} + +void IODevice_Keyboard::UpdateInput(const uint8* data, const int32 time_elapsed) +{ + phys[0] = MDFN_de64lsb(&data[0x00]); + phys[1] = MDFN_de64lsb(&data[0x08]); + phys[2] = MDFN_de16lsb(&data[0x10]); + phys[3] = 0; + // + if(rep_dcnt > 0) + rep_dcnt -= time_elapsed; + + for(unsigned i = 0; i < 4; i++) + { + uint64 tmp = phys[i] ^ processed[i]; + unsigned bp; + + while((bp = (63 ^ MDFN_lzcount64(tmp))) < 64) + { + const uint64 mask = ((uint64)1 << bp); + const int sc = ((i << 6) + bp); + + if(fifo_cnt >= (fifo_size - (sc == 0x82))) + goto fifo_oflow_abort; + + if(phys[i] & mask) + { + rep_sc = sc; +#if 1 + rep_dcnt = 400000; +#else + rep_dcnt = 250000; +#endif + fifo[fifo_wrp] = 0x800 | sc; + fifo_wrp = (fifo_wrp + 1) % fifo_size; + fifo_cnt++; + } + + if(!(phys[i] & mask) == (sc != 0x82)) + { + if(rep_sc == sc) + rep_sc = -1; + + fifo[fifo_wrp] = 0x100 | sc; + fifo_wrp = (fifo_wrp + 1) % fifo_size; + fifo_cnt++; + } + + processed[i] = (processed[i] & ~mask) | (phys[i] & mask); + tmp &= ~mask; + } + } + + if(rep_sc >= 0) + { + while(rep_dcnt <= 0) + { + if(fifo_cnt >= fifo_size) + goto fifo_oflow_abort; + + fifo[fifo_wrp] = 0x800 | rep_sc; + fifo_wrp = (fifo_wrp + 1) % fifo_size; + fifo_cnt++; + + rep_dcnt += 33333; + } + } + + fifo_oflow_abort:; +} + +void IODevice_Keyboard::UpdateOutput(uint8* data) +{ + data[0x12] = lock; +} + +uint8 IODevice_Keyboard::UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) +{ + if(smpc_out & 0x40) + { + phase = -1; + tl = true; + data_out = 0x01; + } + else + { + if((bool)(smpc_out & 0x20) != tl) + { + tl = !tl; + phase += (phase < 11); + + if(!phase) + { + if(mkbrk_pend == (uint8)mkbrk_pend && fifo_cnt) + { + mkbrk_pend = fifo[fifo_rdp]; + fifo_rdp = (fifo_rdp + 1) % fifo_size; + fifo_cnt--; + + bool p = mkbrk_pend & 0x800; + + switch(mkbrk_pend & 0xFF) + { + case 0x89: /* Up */ simbutt_pend = simbutt & ~(1 << 0); simbutt_pend &= ~(p << 1); simbutt_pend |= (p << 0); break; + case 0x8A: /*Down */ simbutt_pend = simbutt & ~(1 << 1); simbutt_pend &= ~(p << 0); simbutt_pend |= (p << 1); break; + case 0x86: /*Left */ simbutt_pend = simbutt & ~(1 << 2); simbutt_pend &= ~(p << 3); simbutt_pend |= (p << 2); break; + case 0x8D: /*Right*/ simbutt_pend = simbutt & ~(1 << 3); simbutt_pend &= ~(p << 2); simbutt_pend |= (p << 3); break; + case 0x22: /* X */ simbutt_pend = simbutt & ~(1 << 4); simbutt_pend |= (p << 4); break; + case 0x21: /* C */ simbutt_pend = simbutt & ~(1 << 5); simbutt_pend |= (p << 5); break; + case 0x1A: /* Z */ simbutt_pend = simbutt & ~(1 << 6); simbutt_pend |= (p << 6); break; + case 0x76: /* Esc */ simbutt_pend = simbutt & ~(1 << 7); simbutt_pend |= (p << 7); break; + case 0x23: /* D */ simbutt_pend = simbutt & ~(1 << 8); simbutt_pend |= (p << 8); break; + case 0x1B: /* S */ simbutt_pend = simbutt & ~(1 << 9); simbutt_pend |= (p << 9); break; + case 0x1C: /* A */ simbutt_pend = simbutt & ~(1 << 10); simbutt_pend |= (p << 10); break; + case 0x24: /* E */ simbutt_pend = simbutt & ~(1 << 11); simbutt_pend |= (p << 11); break; + case 0x15: /* Q */ simbutt_pend = simbutt & ~(1 << 15); simbutt_pend |= (p << 15); break; + + case 0x7E: /* Scrl */ lock_pend = lock ^ (p ? LOCK_SCROLL : 0); break; + case 0x77: /* Num */ lock_pend = lock ^ (p ? LOCK_NUM : 0); break; + case 0x58: /* Caps */ lock_pend = lock ^ (p ? LOCK_CAPS : 0); break; + } + } + buffer[ 0] = 0x3; + buffer[ 1] = 0x4; + buffer[ 2] = (((simbutt_pend >> 0) ^ 0xF) & 0xF); + buffer[ 3] = (((simbutt_pend >> 4) ^ 0xF) & 0xF); + buffer[ 4] = (((simbutt_pend >> 8) ^ 0xF) & 0xF); + buffer[ 5] = (((simbutt_pend >> 12) ^ 0xF) & 0x8) | 0x0; + buffer[ 6] = lock_pend; + buffer[ 7] = ((mkbrk_pend >> 8) & 0xF) | 0x6; + buffer[ 8] = (mkbrk_pend >> 4) & 0xF; + buffer[ 9] = (mkbrk_pend >> 0) & 0xF; + buffer[10] = 0x0; + buffer[11] = 0x1; + } + + if(phase == 9) + { + mkbrk_pend = (uint8)mkbrk_pend; + lock = lock_pend; + simbutt = simbutt_pend; + } + + data_out = buffer[phase]; + } + } + + return (smpc_out & (smpc_out_asserted | 0xE0)) | (((tl << 4) | data_out) &~ smpc_out_asserted); +} + +} diff --git a/waterbox/ss/input/keyboard.h b/waterbox/ss/input/keyboard.h new file mode 100644 index 0000000000..f6b756ba06 --- /dev/null +++ b/waterbox/ss/input/keyboard.h @@ -0,0 +1,72 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* keyboard.h: +** Copyright (C) 2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_INPUT_KEYBOARD_H +#define __MDFN_SS_INPUT_KEYBOARD_H + +namespace MDFN_IEN_SS +{ + +class IODevice_Keyboard final : public IODevice +{ + public: + IODevice_Keyboard() MDFN_COLD; + virtual ~IODevice_Keyboard() override MDFN_COLD; + + virtual void Power(void) override MDFN_COLD; + virtual void UpdateInput(const uint8* data, const int32 time_elapsed) override; + virtual void UpdateOutput(uint8* data) override; + + virtual uint8 UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) override; + + private: + + uint64 phys[4]; + uint64 processed[4]; + uint8 lock; + uint8 lock_pend; + uint16 simbutt; + uint16 simbutt_pend; + enum { fifo_size = 16 }; + uint16 fifo[fifo_size]; + uint8 fifo_rdp; + uint8 fifo_wrp; + uint8 fifo_cnt; + enum + { + LOCK_SCROLL = 0x01, + LOCK_NUM = 0x02, + LOCK_CAPS = 0x04 + }; + + int16 rep_sc; + int32 rep_dcnt; + + int16 mkbrk_pend; + uint8 buffer[12]; + uint8 data_out; + bool tl; + int8 phase; +}; + +} + +#endif diff --git a/waterbox/ss/input/mission.cpp b/waterbox/ss/input/mission.cpp new file mode 100644 index 0000000000..8416399a90 --- /dev/null +++ b/waterbox/ss/input/mission.cpp @@ -0,0 +1,160 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* mission.cpp: +** Copyright (C) 2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +/* + Real mission stick has bugs and quirks that aren't emulated here(like apparently latching/updating the physical input state at the end of the + read sequence instead of near the beginning like other controllers do, resulting in increased latency). +*/ + + +#include "common.h" +#include "mission.h" + +namespace MDFN_IEN_SS +{ + +IODevice_Mission::IODevice_Mission(const bool dual_) : dbuttons(0), afeswitches(0), afspeed(0), dual(dual_) +{ + +} + +IODevice_Mission::~IODevice_Mission() +{ + +} + +void IODevice_Mission::Power(void) +{ + phase = -1; + tl = true; + data_out = 0x01; + + // Power-on state not tested: + afcounter = 0; + afphase = false; +} + +void IODevice_Mission::UpdateInput(const uint8 *data, const int32 time_elapsed) +{ + const uint32 dtmp = MDFN_de32lsb(&data[0]); + + dbuttons = (dbuttons & 0xF) | ((dtmp & 0xFFF) << 4); + afeswitches = ((dtmp >> 12) & 0x8FF) << 4; + afspeed = (dtmp >> 20) & 0x7; + + int offs = 4; + for (unsigned stick = 0; stick < (dual ? 2 : 1); stick++) + { + for (unsigned axis = 0; axis < 3; axis++) + { + axes[stick][axis] = data[offs++]; + } + } + + //printf("Update: %02x %02x %02x\n", axes[0][0], axes[0][1], axes[0][2]); +} + +uint8 IODevice_Mission::UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) +{ + uint8 tmp; + + if(smpc_out & 0x40) + { + phase = -1; + tl = true; + data_out = 0x01; + } + else + { + if((bool)(smpc_out & 0x20) != tl) + { + if(phase < (dual ? 21 : 13)) + { + tl = !tl; + phase++; + } + + if(!phase) + { + unsigned dbaf = dbuttons & ((afphase - 1) | ~afeswitches); + unsigned c = 0; + + // Digital Left + dbuttons |= ((axes[0][0] <= 0x56) ? 0x4 : 0); + dbuttons &= ~((axes[0][0] >= 0x6C) ? 0x4 : 0); + + // Digital Right + dbuttons |= ((axes[0][0] >= 0xAB) ? 0x8 : 0); + dbuttons &= ~((axes[0][0] <= 0x95) ? 0x8 : 0); + + // Digital Up + dbuttons |= ((axes[0][1] <= 0x54) ? 0x1 : 0); + dbuttons &= ~((axes[0][1] >= 0x6A) ? 0x1 : 0); + + // Digital Down + dbuttons |= ((axes[0][1] >= 0xA9) ? 0x2 : 0); + dbuttons &= ~((axes[0][1] <= 0x94) ? 0x2 : 0); + + if(!afcounter) + { + static const uint8 speedtab[7] = { 12, 8, 7, 5, 4, 4/* ? */, 1 }; + afphase = !afphase; + afcounter = speedtab[afspeed]; + } + afcounter--; + + buffer[c++] = 0x1; + buffer[c++] = dual ? 0x9 : 0x5; + buffer[c++] = (((dbaf >> 0) & 0xF) ^ 0xF); + buffer[c++] = (((dbaf >> 4) & 0xF) ^ 0xF); + buffer[c++] = (((dbaf >> 8) & 0xF) ^ 0xF); + buffer[c++] = (((dbaf >> 12) & 0xF) ^ 0xF); + + for(unsigned stick = 0; stick < (dual ? 2 : 1); stick++) + { + if(stick) + { + // Not sure, looks like something buggy. + buffer[c++] = 0x0; + buffer[c++] = 0x0; + } + + buffer[c++] = (axes[stick][0] >> 4) & 0xF; + buffer[c++] = (axes[stick][0] >> 0) & 0xF; + buffer[c++] = (axes[stick][1] >> 4) & 0xF; + buffer[c++] = (axes[stick][1] >> 0) & 0xF; + buffer[c++] = (axes[stick][2] >> 4) & 0xF; + buffer[c++] = (axes[stick][2] >> 0) & 0xF; + } + buffer[c++] = 0x0; + buffer[c++] = 0x1; + } + + data_out = buffer[phase]; + } + } + + tmp = (tl << 4) | data_out; + + return (smpc_out & (smpc_out_asserted | 0xE0)) | (tmp &~ smpc_out_asserted); +} + +} diff --git a/waterbox/ss/input/mission.h b/waterbox/ss/input/mission.h new file mode 100644 index 0000000000..0f2bf648dc --- /dev/null +++ b/waterbox/ss/input/mission.h @@ -0,0 +1,58 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* mission.h: +** Copyright (C) 2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_INPUT_MISSION_H +#define __MDFN_SS_INPUT_MISSION_H + +namespace MDFN_IEN_SS +{ + +class IODevice_Mission final : public IODevice +{ + public: + IODevice_Mission(const bool dual_) MDFN_COLD; + virtual ~IODevice_Mission() override MDFN_COLD; + + virtual void Power(void) override MDFN_COLD; + virtual void UpdateInput(const uint8* data, const int32 time_elapsed) override; + + virtual uint8 UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) override; + + private: + uint16 dbuttons; + uint16 afeswitches; + uint8 afspeed; + + uint8 axes[2][3]; + + uint8 buffer[0x20]; + uint8 data_out; + bool tl; + int8 phase; + uint8 afcounter; + bool afphase; + + const bool dual; +}; + +} + +#endif diff --git a/waterbox/ss/input/mouse.cpp b/waterbox/ss/input/mouse.cpp new file mode 100644 index 0000000000..e56e61f3a5 --- /dev/null +++ b/waterbox/ss/input/mouse.cpp @@ -0,0 +1,131 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* mouse.cpp: +** Copyright (C) 2016-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "common.h" +#include "mouse.h" + +namespace MDFN_IEN_SS +{ + +IODevice_Mouse::IODevice_Mouse() : buttons(0) +{ + +} + +IODevice_Mouse::~IODevice_Mouse() +{ + +} + +void IODevice_Mouse::Power(void) +{ + phase = -1; + tl = true; + data_out = 0x00; + accum_xdelta = 0; + accum_ydelta = 0; +} + +void IODevice_Mouse::UpdateInput(const uint8* data, const int32 time_elapsed) +{ + accum_xdelta += data[1]; + accum_ydelta -= data[2]; + buttons = data[0] & 0xF; +} + +uint8 IODevice_Mouse::UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) +{ + uint8 tmp; + + if(smpc_out & 0x40) + { + if(smpc_out & 0x20) + { + if(!tl) + accum_xdelta = accum_ydelta = 0; + + phase = -1; + tl = true; + data_out = 0x00; + } + else + { + if(tl) + tl = false; + } + } + else + { + if(phase < 0) + { + uint8 flags = 0; + + if(accum_xdelta < 0) + flags |= 0x1; + + if(accum_ydelta < 0) + flags |= 0x2; + + if(accum_xdelta > 255 || accum_xdelta < -256) + { + flags |= 0x4; + accum_xdelta = (accum_xdelta < 0) ? -256 : 255; + } + + if(accum_ydelta > 255 || accum_ydelta < -256) + { + flags |= 0x8; + accum_ydelta = (accum_ydelta < 0) ? -256 : 255; + } + + buffer[0] = 0xB; + buffer[1] = 0xF; + buffer[2] = 0xF; + buffer[3] = flags; + buffer[4] = buttons; + buffer[5] = (accum_xdelta >> 4) & 0xF; + buffer[6] = (accum_xdelta >> 0) & 0xF; + buffer[7] = (accum_ydelta >> 4) & 0xF; + buffer[8] = (accum_ydelta >> 0) & 0xF; + + for(int i = 9; i < 16; i++) + buffer[i] = buffer[8]; + + phase++; + } + + if((bool)(smpc_out & 0x20) != tl) + { + phase = (phase + 1) & 0xF; + tl = !tl; + + if(phase == 8) + accum_xdelta = accum_ydelta = 0; + } + data_out = buffer[phase]; + } + + tmp = (tl << 4) | data_out; + + return (smpc_out & (smpc_out_asserted | 0xE0)) | (tmp &~ smpc_out_asserted); +} + +} diff --git a/waterbox/ss/input/mouse.h b/waterbox/ss/input/mouse.h new file mode 100644 index 0000000000..aa434b7943 --- /dev/null +++ b/waterbox/ss/input/mouse.h @@ -0,0 +1,52 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* mouse.h: +** Copyright (C) 2016-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_INPUT_MOUSE_H +#define __MDFN_SS_INPUT_MOUSE_H + +namespace MDFN_IEN_SS +{ + +class IODevice_Mouse final : public IODevice +{ + public: + IODevice_Mouse() MDFN_COLD; + virtual ~IODevice_Mouse() override MDFN_COLD; + + virtual void Power(void) override MDFN_COLD; + virtual void UpdateInput(const uint8* data, const int32 time_elapsed) override; + + virtual uint8 UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) override; + + private: + int32 accum_xdelta; + int32 accum_ydelta; + + uint8 buttons; + uint8 buffer[0x10]; + uint8 data_out; + bool tl; + int8 phase; +}; + +} + +#endif diff --git a/waterbox/ss/input/multitap.cpp b/waterbox/ss/input/multitap.cpp new file mode 100644 index 0000000000..e8fb3e7fdd --- /dev/null +++ b/waterbox/ss/input/multitap.cpp @@ -0,0 +1,209 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* multitap.cpp: +** Copyright (C) 2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "common.h" +#include "multitap.h" + +namespace MDFN_IEN_SS +{ + +IODevice_Multitap::IODevice_Multitap() +{ + +} + +IODevice_Multitap::~IODevice_Multitap() +{ + +} + +void IODevice_Multitap::Power(void) +{ + phase = -2; + tl = true; + data_out = 0x01; + + memset(tmp, 0x00, sizeof(tmp)); + id1 = 0; + id2 = 0; + port_counter = 0; + read_counter = 0; + + for(unsigned i = 0; i < 6; i++) + { + if(devices[i]) + { + sub_state[i] = 0x60; + devices[i]->UpdateBus(sub_state[i], 0x60); + devices[i]->Power(); + } + } +} + +void IODevice_Multitap::SetSubDevice(unsigned sub_index, IODevice* device) +{ + assert(sub_index < 6); + devices[sub_index] = device; + devices[sub_index]->UpdateBus(sub_state[sub_index], 0x60); +} + +IODevice* IODevice_Multitap::GetSubDevice(unsigned sub_index) +{ + assert(sub_index < 6); + + return devices[sub_index]; +} + +enum { PhaseBias = __COUNTER__ + 1 }; + +#define WAIT_UNTIL(cond) { \ + case __COUNTER__: \ + if(!(cond)) \ + { \ + phase = __COUNTER__ - PhaseBias - 1; \ + goto BreakOut; \ + } \ + } + +#define WR_NYB(v) { WAIT_UNTIL((bool)(smpc_out & 0x20) != tl); data_out = (v) & 0xF; tl = !tl; } + + +INLINE uint8 IODevice_Multitap::UASB(void) +{ + return devices[port_counter]->UpdateBus(sub_state[port_counter], 0x60); +} + +uint8 IODevice_Multitap::UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) +{ + if(smpc_out & 0x40) + { + phase = -1; + tl = true; + data_out = 0x01; + } + else + { + switch(phase + PhaseBias) + { + for(;;) + { + default: + case __COUNTER__: + + WAIT_UNTIL(phase == -1); + + WR_NYB(0x4); + WR_NYB(0x1); + WR_NYB(0x6); + WR_NYB(0x0); + // + // + port_counter = 0; + + do + { + sub_state[port_counter] = 0x60; + UASB(); + // ... + tmp[0] = UASB(); + id1 = ((((tmp[0] >> 3) | (tmp[0] >> 2)) & 1) << 3) | ((((tmp[0] >> 1) | (tmp[0] >> 0)) & 1) << 2); + + sub_state[port_counter] = 0x20; + UASB(); + // ... + tmp[1] = UASB(); + id1 |= ((((tmp[1] >> 3) | (tmp[1] >> 2)) & 1) << 1) | ((((tmp[1] >> 1) | (tmp[1] >> 0)) & 1) << 0); + + //printf("%d, %01x\n", port_counter, id1); + + if(id1 == 0xB) // Digital pad + { + WR_NYB(0x0); + WR_NYB(0x2); + + sub_state[port_counter] = 0x40; + UASB(); + WR_NYB(tmp[1] & 0xF); + tmp[2] = UASB(); + + sub_state[port_counter] = 0x00; + UASB(); + WR_NYB(tmp[2] & 0xF); + tmp[3] = UASB(); + + WR_NYB(tmp[3] & 0xF); + WR_NYB((tmp[0] & 0xF) | 0x7); + } + else if(id1 == 0x3 || id1 == 0x5) // Analog + { + sub_state[port_counter] = 0x00; + WAIT_UNTIL(!(UASB() & 0x10)); + id2 = ((UASB() & 0xF) << 4); + + sub_state[port_counter] = 0x20; + WAIT_UNTIL(UASB() & 0x10); + id2 |= ((UASB() & 0xF) << 0); + + if(id1 == 0x3) + id2 = 0xE3; + + WR_NYB(id2 >> 4); + WR_NYB(id2 >> 0); + + read_counter = 0; + while(read_counter < (id2 & 0xF)) + { + sub_state[port_counter] = 0x00; + WAIT_UNTIL(!(UASB() & 0x10)); + WR_NYB(UASB() & 0xF); + + sub_state[port_counter] = 0x20; + WAIT_UNTIL(UASB() & 0x10); + WR_NYB(UASB() & 0xF); + + read_counter++; + } + } + else + { + WR_NYB(0xF); + WR_NYB(0xF); + } + + sub_state[port_counter] = 0x60; + UASB(); + } while(++port_counter < 6); + + // + // + WR_NYB(0x0); + WR_NYB(0x1); + } + } + } + + BreakOut:; + + return (smpc_out & (smpc_out_asserted | 0xE0)) | (((tl << 4) | data_out) &~ smpc_out_asserted); +} + + +} diff --git a/waterbox/ss/input/multitap.h b/waterbox/ss/input/multitap.h new file mode 100644 index 0000000000..b753b9f1d2 --- /dev/null +++ b/waterbox/ss/input/multitap.h @@ -0,0 +1,59 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* multitap.h: +** Copyright (C) 2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_INPUT_MULTITAP_H +#define __MDFN_SS_INPUT_MULTITAP_H + +namespace MDFN_IEN_SS +{ + +class IODevice_Multitap final : public IODevice +{ + public: + IODevice_Multitap() MDFN_COLD; + virtual ~IODevice_Multitap() override MDFN_COLD; + + virtual void Power(void) override MDFN_COLD; + + virtual uint8 UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) override; + + void SetSubDevice(unsigned sub_index, IODevice* device); + IODevice* GetSubDevice(unsigned sub_index); + + private: + + uint8 UASB(void); + + IODevice* devices[6]; + uint8 sub_state[6]; + uint8 tmp[4]; + uint8 id1; + uint8 id2; + uint8 data_out; + bool tl; + int32 phase; + uint8 port_counter; + uint8 read_counter; +}; + +} + +#endif diff --git a/waterbox/ss/input/wheel.cpp b/waterbox/ss/input/wheel.cpp new file mode 100644 index 0000000000..2060fedcd1 --- /dev/null +++ b/waterbox/ss/input/wheel.cpp @@ -0,0 +1,105 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* wheel.cpp: +** Copyright (C) 2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "common.h" +#include "wheel.h" + +namespace MDFN_IEN_SS +{ + +IODevice_Wheel::IODevice_Wheel() : dbuttons(0) +{ + +} + +IODevice_Wheel::~IODevice_Wheel() +{ + +} + +void IODevice_Wheel::Power(void) +{ + phase = -1; + tl = true; + data_out = 0x01; +} + +void IODevice_Wheel::UpdateInput(const uint8 *data, const int32 time_elapsed) +{ + dbuttons = (dbuttons & 0xC) | (MDFN_de16lsb(&data[0]) & 0x07F3); + wheel = data[2]; + if (wheel >= 0x6F) + dbuttons &= ~0x4; + else if (wheel <= 0x67) + dbuttons |= 0x4; + + if (wheel <= 0x8F) + dbuttons &= ~0x8; + else if (wheel >= 0x97) + dbuttons |= 0x8; +} + +uint8 IODevice_Wheel::UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) +{ + uint8 tmp; + + if(smpc_out & 0x40) + { + phase = -1; + tl = true; + data_out = 0x01; + } + else + { + if((bool)(smpc_out & 0x20) != tl) + { + if(phase < 0) + { + buffer[ 0] = 0x1; + buffer[ 1] = 0x3; + buffer[ 2] = (((dbuttons >> 0) & 0xF) ^ 0xF); + buffer[ 3] = (((dbuttons >> 4) & 0xF) ^ 0xF); + buffer[ 4] = (((dbuttons >> 8) & 0xF) ^ 0xF); + buffer[ 5] = (((dbuttons >> 12) & 0xF) ^ 0xF); + buffer[ 6] = ((wheel >> 4) & 0xF); + buffer[ 7] = ((wheel >> 0) & 0xF); + buffer[ 8] = 0x0; + buffer[ 9] = 0x1; + buffer[10] = 0x1; + buffer[11] = ((wheel >> 0) & 0xF); + buffer[12] = 0x0; + buffer[13] = 0x1; + buffer[14] = 0x1; + buffer[15] = 0x1; + } + + phase = (phase + 1) & 0xF; + data_out = buffer[phase]; + tl = !tl; + } + } + + tmp = (tl << 4) | data_out; + + return (smpc_out & (smpc_out_asserted | 0xE0)) | (tmp &~ smpc_out_asserted); +} + +} diff --git a/waterbox/ss/input/wheel.h b/waterbox/ss/input/wheel.h new file mode 100644 index 0000000000..02f54dd98d --- /dev/null +++ b/waterbox/ss/input/wheel.h @@ -0,0 +1,51 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* wheel.h: +** Copyright (C) 2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_INPUT_WHEEL_H +#define __MDFN_SS_INPUT_WHEEL_H + +namespace MDFN_IEN_SS +{ + +class IODevice_Wheel final : public IODevice +{ + public: + IODevice_Wheel() MDFN_COLD; + virtual ~IODevice_Wheel() override MDFN_COLD; + + virtual void Power(void) override MDFN_COLD; + virtual void UpdateInput(const uint8* data, const int32 time_elapsed) override; + + virtual uint8 UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) override; + + private: + uint16 dbuttons; + uint8 wheel; + + uint8 buffer[0x10]; + uint8 data_out; + bool tl; + int8 phase; +}; + +} + +#endif diff --git a/waterbox/ss/m68k/m68k.cpp b/waterbox/ss/m68k/m68k.cpp new file mode 100644 index 0000000000..6ca5c4e951 --- /dev/null +++ b/waterbox/ss/m68k/m68k.cpp @@ -0,0 +1,2295 @@ +/******************************************************************************/ +/* Mednafen - Multi-system Emulator */ +/******************************************************************************/ +/* m68k.cpp - Motorola 68000 CPU Emulator +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +// TODO: Check CHK +// +// TODO: Address errors(or just cheap out and mask off the lower bit on 16-bit memory accesses). +// +// TODO: Predec, postinc order for same address register. +// +// TODO: Fix instruction timings(currently execute too fast). +// +// TODO: Fix multiplication and division timing, and make sure flags are ok for divide by zero. +// +// FIXME: Handle NMI differently; how to test? Maybe MOVEM to interrupt control registers... +// +// TODO: Test MOVEM +// +/* + Be sure to test the following thoroughly: + SUBA -(a0), a0 + SUBX -(a0),-(a0) + CMPM (a0)+,(a0)+ + + SUBA -(a7), a7 + SUBX -(a7),-(a7) + CMPM (a7)+,(a7)+ +*/ + +#include "ss.h" +#include "m68k.h" + +#include + +#pragma GCC optimize ("no-crossjumping,no-gcse") + +static MDFN_FASTCALL void Dummy_BusRESET(bool state) +{ + +} + +static void DummyDBG(const char* format, ...) noexcept +{ + +} + +M68K::M68K(const bool rev_e) : Revision_E(rev_e), + BusReadInstr(nullptr), BusRead8(nullptr), BusRead16(nullptr), + BusWrite8(nullptr), BusWrite16(nullptr), + BusRMW(nullptr), + BusIntAck(nullptr), + BusRESET(Dummy_BusRESET), + DBG_Warning(DummyDBG), + DBG_Verbose(DummyDBG) +{ + timestamp = 0; + XPending = 0; + IPL = 0; + Reset(true); +} + +M68K::~M68K() +{ + +} + +INLINE void M68K::RecalcInt(void) +{ + XPending &= ~XPENDING_MASK_INT; + + if(IPL > (SRHB & 0x7)) + XPending |= XPENDING_MASK_INT; +} + +void M68K::SetIPL(uint8 ipl_new) +{ + if(IPL < 0x7 && ipl_new == 0x7) + XPending |= XPENDING_MASK_NMI; + else if(ipl_new < 0x7) + XPending &= ~XPENDING_MASK_NMI; + + IPL = ipl_new; + RecalcInt(); +} + +void M68K::SetExtHalted(bool state) +{ + XPending &= ~XPENDING_MASK_EXTHALTED; + if(state) + XPending |= XPENDING_MASK_EXTHALTED; +} + +template +INLINE T M68K::Read(uint32 addr) +{ + if(sizeof(T) == 4) + { + uint32 ret; + + ret = BusRead16(addr) << 16; + ret |= BusRead16(addr + 2); + + return ret; + } + else if(sizeof(T) == 2) + return BusRead16(addr); + else + return BusRead8(addr); +} + +INLINE uint16 M68K::ReadOp(void) +{ + uint16 ret; + + ret = BusReadInstr(PC); + PC += 2; + + return ret; +} + +template +INLINE void M68K::Write(uint32 addr, const T val) +{ + if(sizeof(T) == 4) + { + if(long_dec) + { + BusWrite16(addr + 2, val); + BusWrite16(addr, val >> 16); + } + else + { + BusWrite16(addr, val >> 16); + BusWrite16(addr + 2, val); + } + } + else if(sizeof(T) == 2) + BusWrite16(addr, val); + else + BusWrite8(addr, val); +} + +template +INLINE void M68K::Push(const T value) +{ + static_assert(sizeof(T) != 1, "Wrong type."); + A[7] -= sizeof(T); + Write(A[7], value); +} + +template +INLINE T M68K::Pull(void) +{ + static_assert(sizeof(T) != 1, "Wrong type."); + + T ret; + + ret = Read(A[7]); + + A[7] += sizeof(T); + + return ret; +} + +// +// MOVE byte and word: instructions, 2 cycle penalty for source predecrement only +// 2 cycle penalty for (d8, An, Xn) for both source and dest ams +// 2 cycle penalty for (d8, PC, Xn) for dest am +// + +// +// Careful on declaration order of HAM objects(needs to be source then dest). +// +template +struct M68K::HAM +{ + INLINE HAM(M68K* z) : zptr(z), reg(0), have_ea(false) + { + static_assert(am == PC_DISP || am == PC_INDEX || am == ABS_SHORT || am == ABS_LONG || am == IMMEDIATE, "Wrong arg count."); + + switch(am) + { + case PC_DISP: // (d16, PC) + case PC_INDEX: // PC with index + ea = zptr->PC; + ext = zptr->ReadOp(); + break; + + case ABS_SHORT: // (xxxx).W + ext = zptr->ReadOp(); + break; + + case ABS_LONG: // (xxxx).L + ext = zptr->ReadOp() << 16; + ext |= zptr->ReadOp(); + break; + + case IMMEDIATE: // Immediate + if(sizeof(T) == 4) + { + ext = zptr->ReadOp() << 16; + ext |= zptr->ReadOp(); + } + else + { + ext = zptr->ReadOp(); + } + break; + } + } + + INLINE HAM(M68K* z, uint32 arg) : zptr(z), reg(arg), have_ea(false) + { + static_assert(am != PC_DISP && am != PC_INDEX && am != ABS_SHORT && am != ABS_LONG, "Wrong arg count."); + + static_assert(am != ADDR_REG_DIR || sizeof(T) != 1, "Wrong size for address reg direct read"); + + switch(am) + { + case DATA_REG_DIR: + case ADDR_REG_DIR: + case ADDR_REG_INDIR: + case ADDR_REG_INDIR_POST: + case ADDR_REG_INDIR_PRE: + break; + + case ADDR_REG_INDIR_DISP: // (d16, An) + case ADDR_REG_INDIR_INDX: // (d8, An, Xn) + ext = zptr->ReadOp(); + break; + + case IMMEDIATE: // Immediate (quick) + ext = arg; + break; + } + } + + private: + INLINE void calcea(const int predec_penalty) + { + if(have_ea) + return; + + have_ea = true; + + switch(am) + { + default: + break; + + case ADDR_REG_INDIR: + ea = zptr->A[reg]; + break; + + case ADDR_REG_INDIR_POST: + ea = zptr->A[reg]; + zptr->A[reg] += (sizeof(T) == 1 && reg == 0x7) ? 2 : sizeof(T); + break; + + case ADDR_REG_INDIR_PRE: + zptr->timestamp += predec_penalty; + zptr->A[reg] -= (sizeof(T) == 1 && reg == 0x7) ? 2 : sizeof(T); + ea = zptr->A[reg]; + break; + + case ADDR_REG_INDIR_DISP: + ea = zptr->A[reg] + (int16)ext; + break; + + case ADDR_REG_INDIR_INDX: + zptr->timestamp += 2; + ea = zptr->A[reg] + (int8)ext + ((ext & 0x800) ? zptr->DA[ext >> 12] : (int16)zptr->DA[ext >> 12]); + break; + + case ABS_SHORT: + ea = (int16)ext; + break; + + case ABS_LONG: + ea = ext; + break; + + case PC_DISP: + ea = ea + (int16)ext; + break; + + case PC_INDEX: + zptr->timestamp += 2; + ea = ea + (int8)ext + ((ext & 0x800) ? zptr->DA[ext >> 12] : (int16)zptr->DA[ext >> 12]); + break; + } + } + public: + + // + // TODO: check pre-decrement 32-bit->2x 16-bit write order + // + + INLINE void write(const T val, const int predec_penalty = 2) + { + static_assert(am != PC_DISP && am != PC_INDEX && am != IMMEDIATE, "What"); + + static_assert(am != ADDR_REG_DIR || sizeof(T) == 4, "Wrong size for address reg direct write"); + + switch(am) + { + case ADDR_REG_DIR: + zptr->A[reg] = val; + break; + + case DATA_REG_DIR: + #ifdef MSB_FIRST + memcpy((uint8*)&zptr->D[reg] + (4 - sizeof(T)), &val, sizeof(T)); + #else + memcpy((uint8*)&zptr->D[reg] + 0, &val, sizeof(T)); + #endif + break; + + case ADDR_REG_INDIR: + case ADDR_REG_INDIR_POST: + case ADDR_REG_INDIR_PRE: + case ADDR_REG_INDIR_DISP: + case ADDR_REG_INDIR_INDX: + case ABS_SHORT: + case ABS_LONG: + calcea(predec_penalty); + zptr->Write(ea, val); + break; + } + } + + INLINE T read(void) + { + switch(am) + { + case DATA_REG_DIR: + return zptr->D[reg]; + + case ADDR_REG_DIR: + return zptr->A[reg]; + + case IMMEDIATE: + return ext; + + case ADDR_REG_INDIR: + case ADDR_REG_INDIR_POST: + case ADDR_REG_INDIR_PRE: + case ADDR_REG_INDIR_DISP: + case ADDR_REG_INDIR_INDX: + case ABS_SHORT: + case ABS_LONG: + case PC_DISP: + case PC_INDEX: + calcea(2); + return zptr->Read(ea); + } + } + + INLINE void rmw(T (MDFN_FASTCALL *cb)(M68K*, T)) + { + static_assert(am != PC_DISP && am != PC_INDEX && am != IMMEDIATE, "What"); + + switch(am) + { + case DATA_REG_DIR: + { + T tmp = cb(zptr, zptr->D[reg]); + #ifdef MSB_FIRST + memcpy((uint8*)&zptr->D[reg] + (4 - sizeof(T)), &tmp, sizeof(T)); + #else + memcpy((uint8*)&zptr->D[reg] + 0, &tmp, sizeof(T)); + #endif + } + break; + + case ADDR_REG_INDIR: + case ADDR_REG_INDIR_POST: + case ADDR_REG_INDIR_PRE: + case ADDR_REG_INDIR_DISP: + case ADDR_REG_INDIR_INDX: + case ABS_SHORT: + case ABS_LONG: + calcea(2); + + zptr->BusRMW(ea, cb); + break; + } + } + + + INLINE void jump(void) + { + calcea(0); + zptr->PC = ea; + } + + INLINE uint32 getea(void) + { + static_assert(am == ADDR_REG_INDIR || am == ADDR_REG_INDIR_DISP || am == ADDR_REG_INDIR_INDX || am == ABS_SHORT || am == ABS_LONG || am == PC_DISP || am == PC_INDEX, "Wrong addressing mode"); + calcea(0); + return ea; + } + + M68K* zptr; + + uint32 ea; + uint32 ext; + const unsigned reg; + + private: + bool have_ea; +}; + + + +INLINE void M68K::SetC(bool val) { Flag_C = val; } +INLINE void M68K::SetV(bool val) { Flag_V = val; } +INLINE void M68K::SetZ(bool val) { Flag_Z = val; } +INLINE void M68K::SetN(bool val) { Flag_N = val; } +INLINE void M68K::SetX(bool val) { Flag_X = val; } + +INLINE bool M68K::GetC(void) { return Flag_C; } +INLINE bool M68K::GetV(void) { return Flag_V; } +INLINE bool M68K::GetZ(void) { return Flag_Z; } +INLINE bool M68K::GetN(void) { return Flag_N; } +INLINE bool M68K::GetX(void) { return Flag_X; } + + +INLINE void M68K::SetCX(bool val) +{ + SetC(val); + SetX(val); +} + +// +// Z_OnlyClear should be true for ADDX, SUBX, NEGX, ABCD, SBCD, NBCD. +// +template +INLINE void M68K::CalcZN(const T val) +{ + if(Z_OnlyClear) + { + if(val != 0) + SetZ(false); + } + else + SetZ(val == 0); + + SetN(static_cast::type>(val) < 0); +} + +template +INLINE void M68K::CalcCX(const uint64& val) +{ + SetCX((val >> (sizeof(T) * 8)) & 1); +} + +INLINE uint8 M68K::GetCCR(void) +{ + return (GetC() << 0) | (GetV() << 1) | (GetZ() << 2) | (GetN() << 3) | (GetX() << 4); +} + +INLINE void M68K::SetCCR(uint8 val) +{ + SetC((val >> 0) & 1); + SetV((val >> 1) & 1); + SetZ((val >> 2) & 1); + SetN((val >> 3) & 1); + SetX((val >> 4) & 1); +} + +INLINE uint16 M68K::GetSR(void) +{ + return GetCCR() | (SRHB << 8); +} + +INLINE void M68K::SetSR(uint16 val) +{ + const uint8 new_srhb = (val >> 8) & 0xA7; + + SetCCR(val); + + if((SRHB ^ new_srhb) & 0x20) // Supervisor mode change + { + std::swap(A[7], SP_Inactive); + } + + SRHB = new_srhb; + RecalcInt(); +} + +INLINE uint8 M68K::GetIMask(void) +{ + return (GetSR() >> 8) & 0x7; +} + +INLINE void M68K::SetIMask(uint8 val) +{ + SetSR((GetSR() & ~0x0700) | ((val & 0x7) << 8)); +} + +INLINE bool M68K::GetSVisor(void) +{ + return (bool)(GetSR() & 0x2000); +} + +INLINE void M68K::SetSVisor(bool value) +{ + SetSR((GetSR() & ~0x2000) | (value << 13)); +} + +INLINE bool M68K::GetTrace(void) +{ + return (bool)(GetSR() & 0x8000); +} + +INLINE void M68K::SetTrace(bool value) +{ + SetSR((GetSR() & ~0x8000) | (value << 15)); +} + +// +// +// +enum +{ + VECNUM_RESET_SSP = 0, + VECNUM_RESET_PC = 1, + VECNUM_BUS_ERROR = 2, + VECNUM_ADDRESS_ERROR = 3, + VECNUM_ILLEGAL = 4, + VECNUM_ZERO_DIVIDE = 5, + VECNUM_CHK = 6, + VECNUM_TRAPV = 7, + VECNUM_PRIVILEGE = 8, + VECNUM_TRACE = 9, + VECNUM_LINEA = 10, + VECNUM_LINEF = 11, + + VECNUM_UNINI_INT = 15, + + VECNUM_SPURIOUS_INT = 24, + VECNUM_INT_BASE = 24, + + VECNUM_TRAP_BASE = 32 +}; + +enum +{ + EXCEPTION_RESET = 0, + EXCEPTION_BUS_ERROR, + EXCEPTION_ADDRESS_ERROR, + EXCEPTION_ILLEGAL, + EXCEPTION_ZERO_DIVIDE, + EXCEPTION_CHK, + EXCEPTION_TRAPV, + EXCEPTION_PRIVILEGE, + EXCEPTION_TRACE, + + EXCEPTION_INT, + EXCEPTION_TRAP +}; + +// +// Instruction traps(TRAP, TRAPV, CHK, DIVS, DIVU): +// Saved PC points to the instruction after the instruction that triggered the exception. +// +// Illegal instructions: +// +// +// Privilege violation: +// Saved PC points to the instruction that generated the privilege violation. +// +// Base exception timing is 34 cycles? +void NO_INLINE M68K::Exception(unsigned which, unsigned vecnum) +{ + const uint32 PC_save = PC; + const uint16 SR_save = GetSR(); + + SetSVisor(true); + SetTrace(false); + + if(which == EXCEPTION_INT) + { + unsigned evn; + + timestamp += 4; + + SetIMask(IPL); + + evn = BusIntAck(IPL); + + if(evn > 255) + vecnum = vecnum + IPL; + else + vecnum = evn; + + timestamp += 2; + } + + Push(PC_save); + Push(SR_save); + PC = Read(vecnum << 2); + + // + { + auto dbgw = DBG_Verbose; + + if(which != EXCEPTION_INT || vecnum == VECNUM_UNINI_INT || vecnum == VECNUM_SPURIOUS_INT) + dbgw = DBG_Warning; + + dbgw("[M68K] Exception %u(vec=%u) @PC=0x%08x SR=0x%04x ---> PC=0x%08x, SR=0x%04x\n", which, vecnum, PC_save, SR_save, PC, GetSR()); + } + // + + // TODO: Prefetch + ReadOp(); + ReadOp(); + PC -= 4; +} + +// +// +// + +// +// ADD +// +template +INLINE void M68K::ADD(HAM &src, HAM &dst) +{ + static_assert(DAM == ADDR_REG_DIR || std::is_same::value, "Type mismatch"); + + uint32 const src_data = (DT)static_cast::type>(src.read()); + uint32 const dst_data = dst.read(); + uint64 const result = (uint64)dst_data + src_data; + + if(DAM == ADDR_REG_DIR) + { + if(sizeof(T) != 4 || SAM == DATA_REG_DIR || SAM == ADDR_REG_DIR || SAM == IMMEDIATE) + timestamp += 4; + else + timestamp += 2; + } + else if(DAM == DATA_REG_DIR && sizeof(DT) == 4) + { + if(SAM == DATA_REG_DIR || SAM == IMMEDIATE) + timestamp += 4; + else + timestamp += 2; + } + + if(DAM != ADDR_REG_DIR) + { + CalcZN
    (result); + SetCX((result >> (sizeof(DT) * 8)) & 1); + SetV((((~(dst_data ^ src_data)) & (dst_data ^ result)) >> (sizeof(DT) * 8 - 1)) & 1); + } + + dst.write(result); +} + + +// +// ADDX +// +template +INLINE void M68K::ADDX(HAM &src, HAM &dst) +{ + uint32 const src_data = src.read(); + uint32 const dst_data = dst.read(); + uint64 const result = (uint64)dst_data + src_data + GetX(); + + if(DAM != DATA_REG_DIR) + { + timestamp += 2; + } + else + { + if(sizeof(T) == 4) + timestamp += 4; + } + + CalcZN(result); + SetCX((result >> (sizeof(T) * 8)) & 1); + SetV((((~(dst_data ^ src_data)) & (dst_data ^ result)) >> (sizeof(T) * 8 - 1)) & 1); + + dst.write(result); +} + + +// +// Used to implement SUB, SUBA, SUBX, NEG, NEGX +// +template +INLINE DT M68K::Subtract(HAM &src, HAM &dst) +{ + static_assert(DAM == ADDR_REG_DIR || std::is_same::value, "Type mismatch"); + static_assert(DAM == ADDR_REG_DIR || DAM == DATA_REG_DIR || DAM == IMMEDIATE || SAM == ADDR_REG_DIR || SAM == DATA_REG_DIR || SAM == IMMEDIATE || X_form, "Wrong addressing modes."); + + uint32 const src_data = (DT)static_cast::type>(src.read()); + uint32 const dst_data = dst.read(); + const uint64 result = (uint64)dst_data - src_data - (X_form ? GetX() : 0); + + if(DAM == ADDR_REG_DIR) // SUBA, SUBQ(A) only. + { + if(sizeof(T) != 4 || SAM == DATA_REG_DIR || SAM == ADDR_REG_DIR || SAM == IMMEDIATE) + timestamp += 4; + else + timestamp += 2; + } + else if(DAM == DATA_REG_DIR) // SUB, SUBQ, SUBX only. + { + if(sizeof(DT) == 4) + { + if(SAM == DATA_REG_DIR || SAM == IMMEDIATE) + timestamp += 4; + else + timestamp += 2; + } + } + else if(DAM == IMMEDIATE) // NEG, NEGX only and always. + { + if(sizeof(T) == 4) + { + timestamp += 2; + } + } + else if(SAM != IMMEDIATE && SAM != ADDR_REG_DIR && SAM != DATA_REG_DIR) // SUBX m,m + { + timestamp += 2; + } + + + if(DAM != ADDR_REG_DIR) + { + CalcZN(result); + SetCX((result >> (sizeof(DT) * 8)) & 1); + SetV(((((dst_data ^ src_data)) & (dst_data ^ result)) >> (sizeof(DT) * 8 - 1)) & 1); + } + + return result; +} + + +// +// SUB +// +template +INLINE void M68K::SUB(HAM &src, HAM &dst) +{ + dst.write(Subtract(src, dst)); +} + + +// +// SUBX +// +template +INLINE void M68K::SUBX(HAM &src, HAM &dst) +{ + dst.write(Subtract(src, dst)); +} + + +// +// NEG +// +template +INLINE void M68K::NEG(HAM &dst) +{ + HAM dummy_zero(this, 0); + + dst.write(Subtract(dst, dummy_zero)); +} + + +// +// NEGX +// +template +INLINE void M68K::NEGX(HAM &dst) +{ + HAM dummy_zero(this, 0); + + dst.write(Subtract(dst, dummy_zero)); +} + + +// +// CMP +// +template +INLINE void M68K::CMP(HAM &src, HAM &dst) +{ + static_assert(DAM == ADDR_REG_DIR || std::is_same::value, "Type mismatch"); + + // Doesn't affect X flag + uint32 const src_data = (DT)static_cast::type>(src.read()); + uint32 const dst_data = dst.read(); + uint64 const result = (uint64)dst_data - src_data; + + CalcZN
    (result); + SetC((result >> (sizeof(DT) * 8)) & 1); + SetV(((((dst_data ^ src_data)) & (dst_data ^ result)) >> (sizeof(DT) * 8 - 1)) & 1); +} + + +// +// CHK +// +// Exception on dst < 0 || dst > src +template +INLINE void M68K::CHK(HAM &src, HAM &dst) +{ + uint32 const src_data = src.read(); + uint32 const dst_data = dst.read(); + + timestamp += 6; + + CalcZN(dst_data); + if(GetN()) + { + Exception(EXCEPTION_CHK, VECNUM_CHK); + } + else + { + // 7 - 1 + uint64 const result = (uint64)dst_data - src_data; + + CalcZN(result); + SetC((result >> (sizeof(T) * 8)) & 1); + SetV(((((dst_data ^ src_data)) & (dst_data ^ result)) >> (sizeof(T) * 8 - 1)) & 1); + + if(GetN() == GetV() && !GetZ()) + { + Exception(EXCEPTION_CHK, VECNUM_CHK); + } + } +} + + +// +// OR +// +template +INLINE void M68K::OR(HAM &src, HAM &dst) +{ + T const src_data = src.read(); + T const dst_data = dst.read(); + T const result = dst_data | src_data; + + if(sizeof(T) == 4 && DAM == DATA_REG_DIR) + { + if(SAM == IMMEDIATE || SAM == DATA_REG_DIR) + timestamp += 4; + else + timestamp += 2; + } + + CalcZN(result); + SetC(false); + SetV(false); + + dst.write(result); +} + + +// +// EOR +// +template +INLINE void M68K::EOR(HAM &src, HAM &dst) +{ + T const src_data = src.read(); + T const dst_data = dst.read(); + T const result = dst_data ^ src_data; + + if(sizeof(T) == 4 && DAM == DATA_REG_DIR) + { + if(SAM == IMMEDIATE || SAM == DATA_REG_DIR) + timestamp += 4; + else + timestamp += 2; + } + + CalcZN(result); + SetC(false); + SetV(false); + + dst.write(result); +} + + +// +// AND +// +template +INLINE void M68K::AND(HAM &src, HAM &dst) +{ + T const src_data = src.read(); + T const dst_data = dst.read(); + T const result = dst_data & src_data; + + if(sizeof(T) == 4 && DAM == DATA_REG_DIR) + { + if(SAM == IMMEDIATE || SAM == DATA_REG_DIR) + timestamp += 4; + else + timestamp += 2; + } + + CalcZN(result); + SetC(false); + SetV(false); + + dst.write(result); +} + + +// +// ORI CCR +// +INLINE void M68K::ORI_CCR(void) +{ + const uint8 imm = ReadOp(); + + SetCCR(GetCCR() | imm); + + // + // + timestamp += 8; + ReadOp(); + PC -= 2; +} + + +// +// ORI SR +// +INLINE void M68K::ORI_SR(void) +{ + const uint16 imm = ReadOp(); + + SetSR(GetSR() | imm); + + // + // + timestamp += 8; + ReadOp(); + PC -= 2; +} + + +// +// ANDI CCR +// +INLINE void M68K::ANDI_CCR(void) +{ + const uint8 imm = ReadOp(); + + SetCCR(GetCCR() & imm); + + // + // + timestamp += 8; + ReadOp(); + PC -= 2; +} + + +// +// ANDI SR +// +INLINE void M68K::ANDI_SR(void) +{ + const uint16 imm = ReadOp(); + + SetSR(GetSR() & imm); + + // + // + timestamp += 8; + ReadOp(); + PC -= 2; +} + + +// +// EORI CCR +// +INLINE void M68K::EORI_CCR(void) +{ + const uint8 imm = ReadOp(); + + SetCCR(GetCCR() ^ imm); + + // + // + timestamp += 8; + ReadOp(); + PC -= 2; +} + + +// +// EORI SR +// +INLINE void M68K::EORI_SR(void) +{ + const uint16 imm = ReadOp(); + + SetSR(GetSR() ^ imm); + + // + // + timestamp += 8; + ReadOp(); + PC -= 2; +} + + +// +// MULU +// +template +INLINE void M68K::MULU(HAM &src, const unsigned dr) +{ + // Doesn't affect X flag + static_assert(sizeof(T) == 2, "Wrong type."); + + T const src_data = src.read(); + uint32 const result = (uint32)(uint16)D[dr] * (uint32)src_data; + + CalcZN(result); + SetC(false); + SetV(false); + + D[dr] = result; +} + + +// +// MULS +// +template +INLINE void M68K::MULS(HAM &src, const unsigned dr) +{ + // Doesn't affect X flag + static_assert(sizeof(T) == 2, "Wrong type."); + + T const src_data = src.read(); + uint32 const result = (int16)D[dr] * (int16)src_data; + + CalcZN(result); + SetC(false); + SetV(false); + + D[dr] = result; +} + + +template +INLINE void M68K::Divide(uint16 divisor, const unsigned dr) +{ + uint32 dividend = D[dr]; + uint32 tmp; + bool neg_quotient = false; + bool neg_remainder = false; + bool oflow = false; + + if(!divisor) + { + Exception(EXCEPTION_ZERO_DIVIDE, VECNUM_ZERO_DIVIDE); + return; + } + + if(sdiv) + { + neg_quotient = (dividend >> 31) ^ (divisor >> 15); + if(dividend & 0x80000000) + { + dividend = -dividend; + neg_remainder = true; + } + + if(divisor & 0x8000) + divisor = -divisor; + } + + tmp = dividend; + + for(int i = 0; i < 16; i++) + { + bool lb = false; + bool ob; + + if(tmp >= ((uint32)divisor << 15)) + { + tmp -= divisor << 15; + lb = true; + } + + ob = tmp >> 31; + tmp = (tmp << 1) | lb; + + if(ob) + { + oflow = true; + //puts("OVERFLOW"); + //break; + } + } + + if(sdiv) + { + if((tmp & 0xFFFF) > (uint32)(0x7FFF + neg_quotient)) + oflow = true; + } + + if((uint32)(tmp >> 16) >= divisor) + oflow = true; + + if(sdiv && !oflow) + { + if(neg_quotient) + tmp = ((-tmp) & 0xFFFF) | (tmp & 0xFFFF0000); + + if(neg_remainder) + tmp = (((-(tmp >> 16)) << 16) & 0xFFFF0000) | (tmp & 0xFFFF); + } + + // + // Doesn't affect X flag + // + CalcZN(tmp); + SetC(false); + SetV(oflow); + + if(!oflow) + D[dr] = tmp; +} + + +// +// DIVU +// +template +INLINE void M68K::DIVU(HAM &src, const unsigned dr) +{ + static_assert(sizeof(T) == 2, "Wrong type."); + + T const src_data = src.read(); + + Divide(src_data, dr); +} + + +// +// DIVS +// +template +INLINE void M68K::DIVS(HAM &src, const unsigned dr) +{ + // Doesn't affect X flag + static_assert(sizeof(T) == 2, "Wrong type."); + + T const src_data = src.read(); + + Divide(src_data, dr); +} + + +// +// ABCD +// +template +INLINE void M68K::ABCD(HAM &src, HAM &dst) // ...XYZ, now I know my ABCs~ +{ + static_assert(sizeof(T) == 1, "Wrong size."); + + bool V = false; + uint8 const src_data = src.read(); + uint8 const dst_data = dst.read(); + uint32 tmp; + + tmp = dst_data + src_data + GetX(); + + if(((dst_data ^ src_data ^ tmp) & 0x10) || (tmp & 0xF) >= 0x0A) + { + uint8 prev_tmp = tmp; + tmp += 0x06; + V |= ((~prev_tmp & 0x80) & (tmp & 0x80)); + } + + if(tmp >= 0xA0) + { + uint8 prev_tmp = tmp; + tmp += 0x60; + V |= ((~prev_tmp & 0x80) & (tmp & 0x80)); + } + + CalcZN(tmp); + SetCX((bool)(tmp >> 8)); + SetV(V); + + if(DAM == DATA_REG_DIR) + timestamp += 2; + else + timestamp += 4; + + dst.write(tmp); +} + + +INLINE uint8 M68K::DecimalSubtractX(const uint8 src_data, const uint8 dst_data) +{ + bool V = false; + uint32 tmp; + + tmp = dst_data - src_data - GetX(); + + const bool adj0 = ((dst_data ^ src_data ^ tmp) & 0x10); + const bool adj1 = (tmp & 0x100); + + if(adj0) + { + uint8 prev_tmp = tmp; + tmp -= 0x06; + V |= (prev_tmp & 0x80) & (~tmp & 0x80); + } + + if(adj1) + { + uint8 prev_tmp = tmp; + tmp -= 0x60; + V |= (prev_tmp & 0x80) & (~tmp & 0x80); + } + + SetV(V); + CalcZN(tmp); + SetCX((bool)(tmp >> 8)); + + return tmp; +} + +// +// SBCD +// +template +INLINE void M68K::SBCD(HAM &src, HAM &dst) +{ + static_assert(sizeof(T) == 1, "Wrong size."); + uint8 const src_data = src.read(); + uint8 const dst_data = dst.read(); + + if(DAM == DATA_REG_DIR) + timestamp += 2; + else + timestamp += 4; + + dst.write(DecimalSubtractX(src_data, dst_data)); +} + + +// +// NBCD +// +template +INLINE void M68K::NBCD(HAM &dst) +{ + static_assert(sizeof(T) == 1, "Wrong size."); + uint8 const dst_data = dst.read(); + + timestamp += 2; + + dst.write(DecimalSubtractX(dst_data, 0)); +} + +// +// MOVEP +// +template +INLINE void M68K::MOVEP(const unsigned ar, const unsigned dr) +{ + const int16 ext = ReadOp(); + uint32 ea = A[ar] + (int16)ext; + unsigned shift = (sizeof(T) - 1) << 3; + + for(unsigned i = 0; i < sizeof(T); i++) + { + if(reg_to_mem) + Write(ea, D[dr] >> shift); + else + { + D[dr] &= ~(0xFF << shift); + D[dr] |= Read(ea) << shift; + } + ea += 2; + shift -= 8; + } +} + + +template +INLINE void M68K::BTST(HAM &targ, unsigned wb) +{ + T const src_data = targ.read(); + wb &= (sizeof(T) << 3) - 1; + + SetZ(((src_data >> wb) & 1) == 0); +} + +template +INLINE void M68K::BCHG(HAM &targ, unsigned wb) +{ + T const src_data = targ.read(); + wb &= (sizeof(T) << 3) - 1; + + SetZ(((src_data >> wb) & 1) == 0); + + targ.write(src_data ^ (1U << wb)); +} + +template +INLINE void M68K::BCLR(HAM &targ, unsigned wb) +{ + T const src_data = targ.read(); + wb &= (sizeof(T) << 3) - 1; + + SetZ(((src_data >> wb) & 1) == 0); + + targ.write(src_data & ~(1U << wb)); +} + +template +INLINE void M68K::BSET(HAM &targ, unsigned wb) +{ + T const src_data = targ.read(); + wb &= (sizeof(T) << 3) - 1; + + SetZ(((src_data >> wb) & 1) == 0); + + targ.write(src_data | (1U << wb)); +} + + + +// +// MOVE +// +template +INLINE void M68K::MOVE(HAM &src, HAM &dst) +{ + T const tmp = src.read(); + + if(DAM != ADDR_REG_DIR) + { + CalcZN(tmp); + SetV(false); + SetC(false); + } + + dst.write(tmp); +} + +template +INLINE void M68K::MOVEA(HAM &src, const unsigned ar) +{ + uint32 const src_data = static_cast::type>(src.read()); + + A[ar] = src_data; +} + + +// +// MOVEM to memory +// +template +INLINE void M68K::MOVEM_to_MEM(const uint16 reglist, HAM &dst) +{ + static_assert(DAM != ADDR_REG_INDIR_PRE && DAM != ADDR_REG_INDIR_POST, "Wrong address mode."); + static_assert(!pseudo_predec || DAM == ADDR_REG_INDIR, "Wrong address mode."); + + uint32 ea = dst.getea(); + + for(unsigned i = 0; i < 16; i++) + { + if(reglist & (1U << i)) + { + if(pseudo_predec) + ea -= sizeof(T); + + Write(ea, DA[(pseudo_predec ? (15 - i) : i)]); + + if(!pseudo_predec) + ea += sizeof(T); + } + } + + if(pseudo_predec) + A[dst.reg] = ea; +} + + +// +// MOVEM to regs(from memory) +// +template +INLINE void M68K::MOVEM_to_REGS(HAM &src, const uint16 reglist) +{ + static_assert(SAM != ADDR_REG_INDIR_PRE && SAM != ADDR_REG_INDIR_POST, "Wrong address mode."); + static_assert(!pseudo_postinc || SAM == ADDR_REG_INDIR, "Wrong address mode."); + + uint32 ea = src.getea(); + + for(unsigned i = 0; i < 16; i++) + { + if(reglist & (1U << i)) + { + T tmp = Read(ea); + + DA[i] = static_cast::type>(tmp); + + ea += sizeof(T); + } + } + + Read(ea); // or should be ? + + if(pseudo_postinc) + A[src.reg] = ea; +} + + +template +INLINE void M68K::ShiftBase(HAM &targ, unsigned count) +{ + T vchange = 0; + T result = targ.read(); + count &= 0x3F; + + if(TAM == DATA_REG_DIR) + timestamp += (sizeof(T) == 4) ? 4 : 2; + + if(count == 0) + { + // X is unaffected with a shift count of 0! + SetC(false); + } + else + { + bool shifted_out = false; + + do + { + if(TAM == DATA_REG_DIR) + timestamp += 2; + + if(ShiftLeft) + shifted_out = (result >> (sizeof(T) * 8 - 1)) & 1; + else + shifted_out = result & 1; + + if(Arithmetic) + { + const T prev = result; + + if(ShiftLeft) + result = result << 1; + else + result = static_cast::type>(result) >> 1; + + vchange |= prev ^ result; + } + else + { + if(ShiftLeft) + result = result << 1; + else + result = result >> 1; + } + } while(--count != 0); + + SetCX(shifted_out); + } + + CalcZN(result); + + if(Arithmetic) + SetV((vchange >> (sizeof(T) * 8 - 1)) & 1); + else + SetV(false); + + targ.write(result); +} + +template +INLINE void M68K::ASL(HAM &targ, unsigned count) +{ + ShiftBase(targ, count); +} + +template +INLINE void M68K::ASR(HAM &targ, unsigned count) +{ + ShiftBase(targ, count); +} + +template +INLINE void M68K::LSL(HAM &targ, unsigned count) +{ + ShiftBase(targ, count); +} + +template +INLINE void M68K::LSR(HAM &targ, unsigned count) +{ + ShiftBase(targ, count); +} + +template +INLINE void M68K::RotateBase(HAM &targ, unsigned count) +{ + T result = targ.read(); + count &= 0x3F; + + if(TAM == DATA_REG_DIR) + timestamp += (sizeof(T) == 4) ? 4 : 2; + + if(count == 0) + { + if(X_Form) + SetC(GetX()); + else + SetC(false); + } + else + { + bool shifted_out = GetX(); + + do + { + const bool shift_in = shifted_out; + + if(TAM == DATA_REG_DIR) + timestamp += 2; + + if(ShiftLeft) + { + shifted_out = (result >> (sizeof(T) * 8 - 1)) & 1; + result <<= 1; + result |= (X_Form ? shift_in : shifted_out); + } + else + { + shifted_out = (result & 1); + result >>= 1; + result |= (T)(X_Form ? shift_in : shifted_out) << (sizeof(T) * 8 - 1); + } + } while(--count != 0); + + SetC(shifted_out); + if(X_Form) + SetX(shifted_out); + } + + CalcZN(result); + SetV(false); + + targ.write(result); +} + +template +INLINE void M68K::ROL(HAM &targ, unsigned count) +{ + RotateBase(targ, count); +} + +template +INLINE void M68K::ROR(HAM &targ, unsigned count) +{ + RotateBase(targ, count); +} + +template +INLINE void M68K::ROXL(HAM &targ, unsigned count) +{ + RotateBase(targ, count); +} + +template +INLINE void M68K::ROXR(HAM &targ, unsigned count) +{ + RotateBase(targ, count); +} + +// +// TAS +// +static MDFN_FASTCALL uint8 TAS_Callback(M68K* zptr, uint8 data) +{ + zptr->CalcZN(data); + zptr->SetC(false); + zptr->SetV(false); + + data |= 0x80; + return data; +} + +template +INLINE void M68K::TAS(HAM &dst) +{ + static_assert(std::is_same::value, "Wrong type"); + + dst.rmw(TAS_Callback); +} + +// +// TST +// +template +INLINE void M68K::TST(HAM &dst) +{ + T const dst_data = dst.read(); + + CalcZN(dst_data); + + SetC(false); + SetV(false); +} + + +// +// CLR +// +template +INLINE void M68K::CLR(HAM &dst) +{ + dst.read(); + + if(sizeof(T) == 4 && DAM == DATA_REG_DIR) + timestamp += 2; + + SetZ(true); + SetN(false); + + SetC(false); + SetV(false); + + dst.write(0); +} + +// +// NOT +// +template +INLINE void M68K::NOT(HAM &dst) +{ + T result = dst.read(); + + if(sizeof(T) == 4 && DAM == DATA_REG_DIR) + timestamp += 2; + + result = ~result; + + CalcZN(result); + SetC(false); + SetV(false); + + dst.write(result); +} + + +// +// EXT +// +template +INLINE void M68K::EXT(HAM &dst) +{ + static_assert(std::is_same::value || std::is_same::value, "Wrong type"); + T result = dst.read(); + + if(std::is_same::value) + result = (int8)result; + else + result = (int16)result; + + CalcZN(result); + SetC(false); + SetV(false); + + dst.write(result); +} + +// +// SWAP +// +INLINE void M68K::SWAP(const unsigned dr) +{ + D[dr] = (D[dr] << 16) | (D[dr] >> 16); + + CalcZN(D[dr]); + SetC(false); + SetV(false); +} + + +// +// EXG (doesn't affect flags) +// +INLINE void M68K::EXG(uint32* a, uint32* b) +{ + timestamp += 2; + + std::swap(*a, *b); +} + +// +// +// + +template +INLINE bool M68K::TestCond(void) +{ + static_assert(cc < 0x10, "Invalid CC"); + + switch(cc) + { + case 0x00: // TRUE + return true; + + case 0x01: // FALSE + return false; + + case 0x02: // HI + return !GetC() && !GetZ(); + + case 0x03: // LS + return GetC() || GetZ(); + + case 0x04: // CC/HS + return !GetC(); + + case 0x05: // CS/LO + return GetC(); + + case 0x06: // NE + return !GetZ(); + + case 0x07: // EQ + return GetZ(); + + case 0x08: // VC + return !GetV(); + + case 0x09: // VS + return GetV(); + + case 0x0A: // PL + return !GetN(); + + case 0x0B: // MI + return GetN(); + + case 0x0C: // GE + return GetN() == GetV(); + + case 0x0D: // LT + return GetN() != GetV(); + + case 0x0E: // GT + return GetN() == GetV() && !GetZ(); + + case 0x0F: // LE + return GetN() != GetV() || GetZ(); + } +} + +// +// Bcc, BRA, BSR +// +// (caller of this function should sign-extend the 8-bit displacement) +// +template +INLINE void M68K::Bxx(uint32 disp) +{ + const uint32 BPC = PC; + + if(TestCond<(cc == 0x01) ? 0x00 : cc>()) + { + const uint16 disp16 = (int16)ReadOp(); + + if(!disp) + disp = (int16)disp16; + else + PC -= 2; + + if(cc == 0x01) + Push(PC); + + timestamp += 2; + PC = BPC + disp; + } + else + { + if(!disp) + ReadOp(); + + timestamp += 4; + } +} + +template +INLINE void M68K::DBcc(const unsigned dr) +{ + const uint32 BPC = PC; + uint32 disp; + + disp = (int16)ReadOp(); + + if(!TestCond()) + { + const uint16 result = D[dr] - 1; + + timestamp += 2; + D[dr] = (D[dr] & 0xFFFF0000) | result; + + if(result != 0xFFFF) + PC = BPC + disp; + else + timestamp += 4; + } + else + timestamp += 4; +} + + +// +// Scc +// +template +INLINE void M68K::Scc(HAM &dst) +{ + static_assert(std::is_same::value, "Wrong type"); + + T const result = TestCond() ? ~(T)0 : 0; + + if(DAM == DATA_REG_DIR && result) + timestamp += 2; + + dst.write(result); +} + + +// +// JSR +// +template +INLINE void M68K::JSR(HAM &targ) +{ + Push(PC); + targ.jump(); +} + + +// +// JMP +// +template +INLINE void M68K::JMP(HAM &targ) +{ + targ.jump(); +} + + +// +// MOVE from SR +// +template +INLINE void M68K::MOVE_from_SR(HAM &dst) +{ + static_assert(std::is_same::value, "Wrong type"); + + dst.read(); + + if(DAM == DATA_REG_DIR) + timestamp += 2; + + dst.write(GetSR()); +} + + +// +// MOVE to CCR +// +template +INLINE void M68K::MOVE_to_CCR(HAM &src) +{ + static_assert(std::is_same::value, "Wrong type"); + + SetCCR(src.read()); + + timestamp += 8; +} + +// +// MOVE to SR +// +template +INLINE void M68K::MOVE_to_SR(HAM &src) +{ + static_assert(std::is_same::value, "Wrong type"); + + SetSR(src.read()); + + timestamp += 8; +} + + +// +// MOVE to/from USP +// +template +INLINE void M68K::MOVE_USP(const unsigned ar) +{ + if(!direction) + SP_Inactive = A[ar]; + else + A[ar] = SP_Inactive; +} + + +// +// LEA +// +template +INLINE void M68K::LEA(HAM &src, const unsigned ar) +{ + const uint32 ea = src.getea(); + + A[ar] = ea; +} + + +// +// PEA +// +template +INLINE void M68K::PEA(HAM &src) +{ + const uint32 ea = src.getea(); + + Push(ea); +} + +// +// UNLK +// +INLINE void M68K::UNLK(const unsigned ar) +{ + A[7] = A[ar]; + A[ar] = Pull(); +} + + +// +// LINK +// +INLINE void M68K::LINK(const unsigned ar) +{ + const uint32 disp = (int16)ReadOp(); + + Push(A[ar]); + A[ar] = A[7]; + A[7] += disp; +} + + + + + +// +// RTE +// +INLINE void M68K::RTE(void) +{ + uint16 new_SR; + + new_SR = Pull(); + PC = Pull(); + + SetSR(new_SR); +} + + +// +// RTR +// +INLINE void M68K::RTR(void) +{ + SetCCR(Pull()); + PC = Pull(); +} + + +// +// RTS +// +INLINE void M68K::RTS(void) +{ + PC = Pull(); +} + + +// +// TRAP +// +INLINE void M68K::TRAP(const unsigned vf) +{ + Exception(EXCEPTION_TRAP, VECNUM_TRAP_BASE + vf); +} + + +// +// TRAPV +// +INLINE void M68K::TRAPV(void) +{ + if(GetV()) + Exception(EXCEPTION_TRAPV, VECNUM_TRAPV); +} + + +// +// ILLEGAL +// +INLINE void M68K::ILLEGAL(const uint16 instr) +{ + //printf("ILLEGAL: %04x\n", instr); + + PC -= 2; + Exception(EXCEPTION_ILLEGAL, VECNUM_ILLEGAL); +} + + +INLINE void M68K::LINEA(void) +{ + PC -= 2; + Exception(EXCEPTION_ILLEGAL, VECNUM_LINEA); +} + +INLINE void M68K::LINEF(void) +{ + PC -= 2; + Exception(EXCEPTION_ILLEGAL, VECNUM_LINEF); +} + + +// +// NOP +// +INLINE void M68K::NOP(void) +{ + +} + + +// +// RESET +// +INLINE void M68K::RESET(void) +{ + timestamp += 2; + // + BusRESET(true); + timestamp += 124; + BusRESET(false); + // + timestamp += 2; +} + + +// +// STOP +// +INLINE void M68K::STOP(void) +{ + uint16 new_SR = ReadOp(); + + SetSR(new_SR); + XPending |= XPENDING_MASK_STOPPED; +} + + +INLINE bool M68K::CheckPrivilege(void) +{ + if(MDFN_UNLIKELY(!GetSVisor())) + { + PC -= 2; + Exception(EXCEPTION_PRIVILEGE, VECNUM_PRIVILEGE); + return false; + } + + return true; +} + +// +// +INLINE void M68K::InternalStep(void) +{ + if(MDFN_UNLIKELY(XPending)) + { + if(MDFN_LIKELY(!(XPending & XPENDING_MASK_EXTHALTED))) + { + if(MDFN_UNLIKELY(XPending & XPENDING_MASK_RESET)) + { + XPending &= ~XPENDING_MASK_RESET; + + SetSVisor(true); + SetTrace(false); + SetIMask(0x7); + + A[7] = Read(VECNUM_RESET_SSP << 2); + PC = Read(VECNUM_RESET_PC << 2); + + return; + } + else if(XPending & (XPENDING_MASK_INT | XPENDING_MASK_NMI)) + { + assert(IPL == 0x7 || IPL > ((GetSR() >> 8) & 0x7)); + XPending &= ~(XPENDING_MASK_STOPPED | XPENDING_MASK_INT | XPENDING_MASK_NMI); + + Exception(EXCEPTION_INT, VECNUM_INT_BASE); + + return; + } + } + + // STOP and ExtHalted fallthrough: + timestamp += 4; + return; + } + // + // + // + uint16 instr = ReadOp(); + const unsigned instr_b11_b9 = (instr >> 9) & 0x7; + const unsigned instr_b2_b0 = instr & 0x7; + +#if 0 + printf("PC=%08x: %04x ---", PC - 2, instr); + + for(unsigned i = 0; i < 8; i++) + printf(" A%u=0x%08x", i, A[i]); + + for(unsigned i = 0; i < 8; i++) + printf(" D%u=0x%08x", i, D[i]); + + printf("\n"); +#endif + switch(instr) + { + default: ILLEGAL(instr); break; + #include "m68k_instr.inc" + } +} + + +void NO_INLINE M68K::Run(int32 run_until_time) +{ + while(MDFN_LIKELY(timestamp < run_until_time)) + InternalStep(); +} + +void NO_INLINE M68K::Step(void) +{ + //printf("%08x\n", PC); + InternalStep(); +} + +// +// Reset() may be called from BusRESET, which is called from RESET, so ensure it continues working for that case. +// +void M68K::Reset(bool powering_up) +{ + if(powering_up) + { + for(unsigned i = 0; i < 8; i++) + D[i] = 0; + + for(unsigned i = 0; i < 8; i++) + A[i] = 0; + + SP_Inactive = 0; + + SetSR(0); + } + XPending = (XPending & ~XPENDING_MASK_STOPPED) | XPENDING_MASK_RESET; +} + + +// +// +// +uint32 M68K::GetRegister(unsigned which, char* special, const uint32 special_len) +{ + switch(which) + { + default: + return 0xDEADBEEF; + + case GSREG_D0: case GSREG_D1: case GSREG_D2: case GSREG_D3: + case GSREG_D4: case GSREG_D5: case GSREG_D6: case GSREG_D7: + return D[which - GSREG_D0]; + + case GSREG_A0: case GSREG_A1: case GSREG_A2: case GSREG_A3: + case GSREG_A4: case GSREG_A5: case GSREG_A6: case GSREG_A7: + return A[which - GSREG_A0]; + + case GSREG_PC: + return PC; + + case GSREG_SR: + return GetSR(); + + case GSREG_SSP: + if(GetSVisor()) + return A[7]; + else + return SP_Inactive; + + case GSREG_USP: + if(!GetSVisor()) + return A[7]; + else + return SP_Inactive; + } +} + +void M68K::SetRegister(unsigned which, uint32 value) +{ + switch(which) + { + case GSREG_D0: case GSREG_D1: case GSREG_D2: case GSREG_D3: + case GSREG_D4: case GSREG_D5: case GSREG_D6: case GSREG_D7: + D[which - GSREG_D0] = value; + break; + + case GSREG_A0: case GSREG_A1: case GSREG_A2: case GSREG_A3: + case GSREG_A4: case GSREG_A5: case GSREG_A6: case GSREG_A7: + A[which - GSREG_A0] = value; + break; + + case GSREG_PC: + PC = value; + break; + + case GSREG_SR: + SetSR(value); + break; + + case GSREG_SSP: + if(GetSVisor()) + A[7] = value; + else + SP_Inactive = value; + break; + + case GSREG_USP: + if(!GetSVisor()) + A[7] = value; + else + SP_Inactive = value; + break; + } +} + diff --git a/waterbox/ss/m68k/m68k.h b/waterbox/ss/m68k/m68k.h new file mode 100644 index 0000000000..83aa930728 --- /dev/null +++ b/waterbox/ss/m68k/m68k.h @@ -0,0 +1,492 @@ +/******************************************************************************/ +/* Mednafen - Multi-system Emulator */ +/******************************************************************************/ +/* m68k.h - Motorola 68000 CPU Emulator +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_M68K_H +#define __MDFN_M68K_H + +#include "ss.h" + +class M68K +{ + public: + + M68K(const bool rev_e = false) MDFN_COLD; + ~M68K() MDFN_COLD; + + void Run(int32 run_until_time); + void Step(void); + + void Reset(bool powering_up) MDFN_COLD; + + void SetIPL(uint8 ipl_new); + void SetExtHalted(bool state); + + // + // + // + // + // + // + // + // + union + { + uint32 DA[16]; + struct + { + uint32 D[8]; + uint32 A[8]; + }; + }; + int32 timestamp; + + uint32 PC; + uint8 SRHB; + uint8 IPL; + + bool Flag_Z, Flag_N; + bool Flag_X, Flag_C, Flag_V; + + uint32 SP_Inactive; + uint32 XPending; + enum + { + XPENDING_MASK_INT = 0x0001, + XPENDING_MASK_NMI = 0x0002, + XPENDING_MASK_RESET = 0x0010, + XPENDING_MASK_STOPPED = 0x0100, // via STOP instruction + XPENDING_MASK_EXTHALTED= 0x1000 + }; + + const bool Revision_E; + + //private: + void RecalcInt(void); + + template + T Read(uint32 addr); + + uint16 ReadOp(void); + + template + void Write(uint32 addr, const T val); + + template + void Push(const T value); + + template + T Pull(void); + + enum AddressMode + { + DATA_REG_DIR, + ADDR_REG_DIR, + + ADDR_REG_INDIR, + ADDR_REG_INDIR_POST, + ADDR_REG_INDIR_PRE, + + ADDR_REG_INDIR_DISP, + + ADDR_REG_INDIR_INDX, + + ABS_SHORT, + ABS_LONG, + + PC_DISP, + PC_INDEX, + + IMMEDIATE + }; + + // + // MOVE byte and word: instructions, 2 cycle penalty for source predecrement only + // 2 cycle penalty for (d8, An, Xn) for both source and dest ams + // 2 cycle penalty for (d8, PC, Xn) for dest am + // + + // + // Careful on declaration order of HAM objects(needs to be source then dest). + // + template + struct HAM; + + void SetC(bool val); + void SetV(bool val); + void SetZ(bool val); + void SetN(bool val); + void SetX(bool val); + + bool GetC(void); + bool GetV(void); + bool GetZ(void); + bool GetN(void); + bool GetX(void); + + void SetCX(bool val); + + template + void CalcZN(const T val); + + template + void CalcCX(const uint64& val); + + uint8 GetCCR(void); + void SetCCR(uint8 val); + uint16 GetSR(void); + void SetSR(uint16 val); + + uint8 GetIMask(void); + void SetIMask(uint8 val); + + bool GetSVisor(void); + void SetSVisor(bool value); + bool GetTrace(void); + void SetTrace(bool value); + + // + // + // + enum + { + VECNUM_RESET_SSP = 0, + VECNUM_RESET_PC = 1, + VECNUM_BUS_ERROR = 2, + VECNUM_ADDRESS_ERROR = 3, + VECNUM_ILLEGAL = 4, + VECNUM_ZERO_DIVIDE = 5, + VECNUM_CHK = 6, + VECNUM_TRAPV = 7, + VECNUM_PRIVILEGE = 8, + VECNUM_TRACE = 9, + VECNUM_LINEA = 10, + VECNUM_LINEF = 11, + + VECNUM_UNINI_INT = 15, + + VECNUM_SPURIOUS_INT = 24, + VECNUM_INT_BASE = 24, + + VECNUM_TRAP_BASE = 32 + }; + + enum + { + EXCEPTION_RESET = 0, + EXCEPTION_BUS_ERROR, + EXCEPTION_ADDRESS_ERROR, + EXCEPTION_ILLEGAL, + EXCEPTION_ZERO_DIVIDE, + EXCEPTION_CHK, + EXCEPTION_TRAPV, + EXCEPTION_PRIVILEGE, + EXCEPTION_TRACE, + + EXCEPTION_INT, + EXCEPTION_TRAP + }; + + void NO_INLINE Exception(unsigned which, unsigned vecnum); + + template + void ADD(HAM &src, HAM &dst); + + template + void ADDX(HAM &src, HAM &dst); + + template + DT Subtract(HAM &src, HAM &dst); + + template + void SUB(HAM &src, HAM &dst); + + template + void SUBX(HAM &src, HAM &dst); + + template + void NEG(HAM &dst); + + template + void NEGX(HAM &dst); + + template + void CMP(HAM &src, HAM &dst); + + template + void CHK(HAM &src, HAM &dst); + + template + void OR(HAM &src, HAM &dst); + + template + void EOR(HAM &src, HAM &dst); + + template + void AND(HAM &src, HAM &dst); + + void ORI_CCR(void); + void ORI_SR(void); + void ANDI_CCR(void); + void ANDI_SR(void); + void EORI_CCR(void); + void EORI_SR(void); + + template + void MULU(HAM &src, const unsigned dr); + + template + void MULS(HAM &src, const unsigned dr); + + template + void Divide(uint16 divisor, const unsigned dr); + + template + void DIVU(HAM &src, const unsigned dr); + + template + void DIVS(HAM &src, const unsigned dr); + + template + void ABCD(HAM &src, HAM &dst); + + uint8 DecimalSubtractX(const uint8 src_data, const uint8 dst_data); + + template + void SBCD(HAM &src, HAM &dst); + + template + void NBCD(HAM &dst); + + template + void MOVEP(const unsigned ar, const unsigned dr); + + template + void BTST(HAM &targ, unsigned wb); + + template + void BCHG(HAM &targ, unsigned wb); + + template + void BCLR(HAM &targ, unsigned wb); + + template + void BSET(HAM &targ, unsigned wb); + + template + void MOVE(HAM &src, HAM &dst); + + template + void MOVEA(HAM &src, const unsigned ar); + + template + void MOVEM_to_MEM(const uint16 reglist, HAM &dst); + + template + void MOVEM_to_REGS(HAM &src, const uint16 reglist); + + template + void ShiftBase(HAM &targ, unsigned count); + + template + void ASL(HAM &targ, unsigned count); + + template + void ASR(HAM &targ, unsigned count); + + template + void LSL(HAM &targ, unsigned count); + + template + void LSR(HAM &targ, unsigned count); + + template + void RotateBase(HAM &targ, unsigned count); + + template + void ROL(HAM &targ, unsigned count); + + template + void ROR(HAM &targ, unsigned count); + + template + void ROXL(HAM &targ, unsigned count); + + template + void ROXR(HAM &targ, unsigned count); + +#if 0 +static uint8 TAS_Callback(uint8 data) +{ + CalcZN(data); + SetC(false); + SetV(false); + + data |= 0x80; + return data; +} +#endif + + template + void TAS(HAM &dst); + + template + void TST(HAM &dst); + + template + void CLR(HAM &dst); + + template + void NOT(HAM &dst); + + template + void EXT(HAM &dst); + + void SWAP(const unsigned dr); + + void EXG(uint32* a, uint32* b); + + template + bool TestCond(void); + + template + void Bxx(uint32 disp); + + template + void DBcc(const unsigned dr); + + template + void Scc(HAM &dst); + + template + void JSR(HAM &targ); + + template + void JMP(HAM &targ); + + template + void MOVE_from_SR(HAM &dst); + + template + void MOVE_to_CCR(HAM &src); + + template + void MOVE_to_SR(HAM &src); + + template + void MOVE_USP(const unsigned ar); + + template + void LEA(HAM &src, const unsigned ar); + + template + void PEA(HAM &src); + void UNLK(const unsigned ar); + void LINK(const unsigned ar); + void RTE(void); + void RTR(void); + void RTS(void); + void TRAP(const unsigned vf); + void TRAPV(void); + void ILLEGAL(const uint16 instr); + void LINEA(void); + void LINEF(void); + void NOP(void); + void RESET(void); + void STOP(void); + + bool CheckPrivilege(void); + + void InternalStep(void); + + // + // + // + // + // + // These externally-provided functions should add >= 4 to M68K::timestamp per call: + enum { BUS_INT_ACK_AUTO = -1 }; + + uint16 (MDFN_FASTCALL *BusReadInstr)(uint32 A); + uint8 (MDFN_FASTCALL *BusRead8)(uint32 A); + uint16 (MDFN_FASTCALL *BusRead16)(uint32 A); + void (MDFN_FASTCALL *BusWrite8)(uint32 A, uint8 V); + void (MDFN_FASTCALL *BusWrite16)(uint32 A, uint16 V); + // + // + void (MDFN_FASTCALL *BusRMW)(uint32 A, uint8 (MDFN_FASTCALL *cb)(M68K*, uint8)); + unsigned (MDFN_FASTCALL *BusIntAck)(uint8 level); + void (MDFN_FASTCALL *BusRESET)(bool state); // Optional; Calling Reset(false) from this callback *is* permitted. + + // + // + // + void (*DBG_Warning)(const char* format, ...) noexcept MDFN_FORMATSTR(gnu_printf, 1, 2); + void (*DBG_Verbose)(const char* format, ...) noexcept MDFN_FORMATSTR(gnu_printf, 1, 2); + // + // + // + public: + enum + { + GSREG_D0 = 0, + GSREG_D1, + GSREG_D2, + GSREG_D3, + GSREG_D4, + GSREG_D5, + GSREG_D6, + GSREG_D7, + + GSREG_A0 = 8, + GSREG_A1, + GSREG_A2, + GSREG_A3, + GSREG_A4, + GSREG_A5, + GSREG_A6, + GSREG_A7, + + GSREG_PC = 16, + GSREG_SR, + GSREG_SSP, + GSREG_USP + }; + + uint32 GetRegister(unsigned which, char* special = nullptr, const uint32 special_len = 0); + void SetRegister(unsigned which, uint32 value); + INLINE void DupeState(const M68K* const src) + { + memcpy(DA, src->DA, 16 * sizeof(uint32)); + timestamp = src->timestamp; + PC = src->PC; + SRHB = src->SRHB; + IPL = src->IPL; + Flag_Z = src->Flag_Z; + Flag_N = src->Flag_N; + Flag_X = src->Flag_X; + Flag_C = src->Flag_C; + Flag_V = src->Flag_V; + SP_Inactive = src->SP_Inactive; + XPending = src->XPending; + } +}; + +#endif diff --git a/waterbox/ss/m68k/m68k_instr.inc b/waterbox/ss/m68k/m68k_instr.inc new file mode 100644 index 0000000000..23a1d51940 --- /dev/null +++ b/waterbox/ss/m68k/m68k_instr.inc @@ -0,0 +1,61700 @@ +case 0x023c: + { + ANDI_CCR(); + } + break; + +case 0x6000: +case 0x6001: +case 0x6002: +case 0x6003: +case 0x6004: +case 0x6005: +case 0x6006: +case 0x6007: +case 0x6008: +case 0x6009: +case 0x600a: +case 0x600b: +case 0x600c: +case 0x600d: +case 0x600e: +case 0x600f: +case 0x6010: +case 0x6011: +case 0x6012: +case 0x6013: +case 0x6014: +case 0x6015: +case 0x6016: +case 0x6017: +case 0x6018: +case 0x6019: +case 0x601a: +case 0x601b: +case 0x601c: +case 0x601d: +case 0x601e: +case 0x601f: +case 0x6020: +case 0x6021: +case 0x6022: +case 0x6023: +case 0x6024: +case 0x6025: +case 0x6026: +case 0x6027: +case 0x6028: +case 0x6029: +case 0x602a: +case 0x602b: +case 0x602c: +case 0x602d: +case 0x602e: +case 0x602f: +case 0x6030: +case 0x6031: +case 0x6032: +case 0x6033: +case 0x6034: +case 0x6035: +case 0x6036: +case 0x6037: +case 0x6038: +case 0x6039: +case 0x603a: +case 0x603b: +case 0x603c: +case 0x603d: +case 0x603e: +case 0x603f: +case 0x6040: +case 0x6041: +case 0x6042: +case 0x6043: +case 0x6044: +case 0x6045: +case 0x6046: +case 0x6047: +case 0x6048: +case 0x6049: +case 0x604a: +case 0x604b: +case 0x604c: +case 0x604d: +case 0x604e: +case 0x604f: +case 0x6050: +case 0x6051: +case 0x6052: +case 0x6053: +case 0x6054: +case 0x6055: +case 0x6056: +case 0x6057: +case 0x6058: +case 0x6059: +case 0x605a: +case 0x605b: +case 0x605c: +case 0x605d: +case 0x605e: +case 0x605f: +case 0x6060: +case 0x6061: +case 0x6062: +case 0x6063: +case 0x6064: +case 0x6065: +case 0x6066: +case 0x6067: +case 0x6068: +case 0x6069: +case 0x606a: +case 0x606b: +case 0x606c: +case 0x606d: +case 0x606e: +case 0x606f: +case 0x6070: +case 0x6071: +case 0x6072: +case 0x6073: +case 0x6074: +case 0x6075: +case 0x6076: +case 0x6077: +case 0x6078: +case 0x6079: +case 0x607a: +case 0x607b: +case 0x607c: +case 0x607d: +case 0x607e: +case 0x607f: +case 0x6080: +case 0x6081: +case 0x6082: +case 0x6083: +case 0x6084: +case 0x6085: +case 0x6086: +case 0x6087: +case 0x6088: +case 0x6089: +case 0x608a: +case 0x608b: +case 0x608c: +case 0x608d: +case 0x608e: +case 0x608f: +case 0x6090: +case 0x6091: +case 0x6092: +case 0x6093: +case 0x6094: +case 0x6095: +case 0x6096: +case 0x6097: +case 0x6098: +case 0x6099: +case 0x609a: +case 0x609b: +case 0x609c: +case 0x609d: +case 0x609e: +case 0x609f: +case 0x60a0: +case 0x60a1: +case 0x60a2: +case 0x60a3: +case 0x60a4: +case 0x60a5: +case 0x60a6: +case 0x60a7: +case 0x60a8: +case 0x60a9: +case 0x60aa: +case 0x60ab: +case 0x60ac: +case 0x60ad: +case 0x60ae: +case 0x60af: +case 0x60b0: +case 0x60b1: +case 0x60b2: +case 0x60b3: +case 0x60b4: +case 0x60b5: +case 0x60b6: +case 0x60b7: +case 0x60b8: +case 0x60b9: +case 0x60ba: +case 0x60bb: +case 0x60bc: +case 0x60bd: +case 0x60be: +case 0x60bf: +case 0x60c0: +case 0x60c1: +case 0x60c2: +case 0x60c3: +case 0x60c4: +case 0x60c5: +case 0x60c6: +case 0x60c7: +case 0x60c8: +case 0x60c9: +case 0x60ca: +case 0x60cb: +case 0x60cc: +case 0x60cd: +case 0x60ce: +case 0x60cf: +case 0x60d0: +case 0x60d1: +case 0x60d2: +case 0x60d3: +case 0x60d4: +case 0x60d5: +case 0x60d6: +case 0x60d7: +case 0x60d8: +case 0x60d9: +case 0x60da: +case 0x60db: +case 0x60dc: +case 0x60dd: +case 0x60de: +case 0x60df: +case 0x60e0: +case 0x60e1: +case 0x60e2: +case 0x60e3: +case 0x60e4: +case 0x60e5: +case 0x60e6: +case 0x60e7: +case 0x60e8: +case 0x60e9: +case 0x60ea: +case 0x60eb: +case 0x60ec: +case 0x60ed: +case 0x60ee: +case 0x60ef: +case 0x60f0: +case 0x60f1: +case 0x60f2: +case 0x60f3: +case 0x60f4: +case 0x60f5: +case 0x60f6: +case 0x60f7: +case 0x60f8: +case 0x60f9: +case 0x60fa: +case 0x60fb: +case 0x60fc: +case 0x60fd: +case 0x60fe: +case 0x60ff: + { + Bxx<0x00>((int8)instr); + } + break; + +case 0x6100: +case 0x6101: +case 0x6102: +case 0x6103: +case 0x6104: +case 0x6105: +case 0x6106: +case 0x6107: +case 0x6108: +case 0x6109: +case 0x610a: +case 0x610b: +case 0x610c: +case 0x610d: +case 0x610e: +case 0x610f: +case 0x6110: +case 0x6111: +case 0x6112: +case 0x6113: +case 0x6114: +case 0x6115: +case 0x6116: +case 0x6117: +case 0x6118: +case 0x6119: +case 0x611a: +case 0x611b: +case 0x611c: +case 0x611d: +case 0x611e: +case 0x611f: +case 0x6120: +case 0x6121: +case 0x6122: +case 0x6123: +case 0x6124: +case 0x6125: +case 0x6126: +case 0x6127: +case 0x6128: +case 0x6129: +case 0x612a: +case 0x612b: +case 0x612c: +case 0x612d: +case 0x612e: +case 0x612f: +case 0x6130: +case 0x6131: +case 0x6132: +case 0x6133: +case 0x6134: +case 0x6135: +case 0x6136: +case 0x6137: +case 0x6138: +case 0x6139: +case 0x613a: +case 0x613b: +case 0x613c: +case 0x613d: +case 0x613e: +case 0x613f: +case 0x6140: +case 0x6141: +case 0x6142: +case 0x6143: +case 0x6144: +case 0x6145: +case 0x6146: +case 0x6147: +case 0x6148: +case 0x6149: +case 0x614a: +case 0x614b: +case 0x614c: +case 0x614d: +case 0x614e: +case 0x614f: +case 0x6150: +case 0x6151: +case 0x6152: +case 0x6153: +case 0x6154: +case 0x6155: +case 0x6156: +case 0x6157: +case 0x6158: +case 0x6159: +case 0x615a: +case 0x615b: +case 0x615c: +case 0x615d: +case 0x615e: +case 0x615f: +case 0x6160: +case 0x6161: +case 0x6162: +case 0x6163: +case 0x6164: +case 0x6165: +case 0x6166: +case 0x6167: +case 0x6168: +case 0x6169: +case 0x616a: +case 0x616b: +case 0x616c: +case 0x616d: +case 0x616e: +case 0x616f: +case 0x6170: +case 0x6171: +case 0x6172: +case 0x6173: +case 0x6174: +case 0x6175: +case 0x6176: +case 0x6177: +case 0x6178: +case 0x6179: +case 0x617a: +case 0x617b: +case 0x617c: +case 0x617d: +case 0x617e: +case 0x617f: +case 0x6180: +case 0x6181: +case 0x6182: +case 0x6183: +case 0x6184: +case 0x6185: +case 0x6186: +case 0x6187: +case 0x6188: +case 0x6189: +case 0x618a: +case 0x618b: +case 0x618c: +case 0x618d: +case 0x618e: +case 0x618f: +case 0x6190: +case 0x6191: +case 0x6192: +case 0x6193: +case 0x6194: +case 0x6195: +case 0x6196: +case 0x6197: +case 0x6198: +case 0x6199: +case 0x619a: +case 0x619b: +case 0x619c: +case 0x619d: +case 0x619e: +case 0x619f: +case 0x61a0: +case 0x61a1: +case 0x61a2: +case 0x61a3: +case 0x61a4: +case 0x61a5: +case 0x61a6: +case 0x61a7: +case 0x61a8: +case 0x61a9: +case 0x61aa: +case 0x61ab: +case 0x61ac: +case 0x61ad: +case 0x61ae: +case 0x61af: +case 0x61b0: +case 0x61b1: +case 0x61b2: +case 0x61b3: +case 0x61b4: +case 0x61b5: +case 0x61b6: +case 0x61b7: +case 0x61b8: +case 0x61b9: +case 0x61ba: +case 0x61bb: +case 0x61bc: +case 0x61bd: +case 0x61be: +case 0x61bf: +case 0x61c0: +case 0x61c1: +case 0x61c2: +case 0x61c3: +case 0x61c4: +case 0x61c5: +case 0x61c6: +case 0x61c7: +case 0x61c8: +case 0x61c9: +case 0x61ca: +case 0x61cb: +case 0x61cc: +case 0x61cd: +case 0x61ce: +case 0x61cf: +case 0x61d0: +case 0x61d1: +case 0x61d2: +case 0x61d3: +case 0x61d4: +case 0x61d5: +case 0x61d6: +case 0x61d7: +case 0x61d8: +case 0x61d9: +case 0x61da: +case 0x61db: +case 0x61dc: +case 0x61dd: +case 0x61de: +case 0x61df: +case 0x61e0: +case 0x61e1: +case 0x61e2: +case 0x61e3: +case 0x61e4: +case 0x61e5: +case 0x61e6: +case 0x61e7: +case 0x61e8: +case 0x61e9: +case 0x61ea: +case 0x61eb: +case 0x61ec: +case 0x61ed: +case 0x61ee: +case 0x61ef: +case 0x61f0: +case 0x61f1: +case 0x61f2: +case 0x61f3: +case 0x61f4: +case 0x61f5: +case 0x61f6: +case 0x61f7: +case 0x61f8: +case 0x61f9: +case 0x61fa: +case 0x61fb: +case 0x61fc: +case 0x61fd: +case 0x61fe: +case 0x61ff: + { + Bxx<0x01>((int8)instr); + } + break; + +case 0x6200: +case 0x6201: +case 0x6202: +case 0x6203: +case 0x6204: +case 0x6205: +case 0x6206: +case 0x6207: +case 0x6208: +case 0x6209: +case 0x620a: +case 0x620b: +case 0x620c: +case 0x620d: +case 0x620e: +case 0x620f: +case 0x6210: +case 0x6211: +case 0x6212: +case 0x6213: +case 0x6214: +case 0x6215: +case 0x6216: +case 0x6217: +case 0x6218: +case 0x6219: +case 0x621a: +case 0x621b: +case 0x621c: +case 0x621d: +case 0x621e: +case 0x621f: +case 0x6220: +case 0x6221: +case 0x6222: +case 0x6223: +case 0x6224: +case 0x6225: +case 0x6226: +case 0x6227: +case 0x6228: +case 0x6229: +case 0x622a: +case 0x622b: +case 0x622c: +case 0x622d: +case 0x622e: +case 0x622f: +case 0x6230: +case 0x6231: +case 0x6232: +case 0x6233: +case 0x6234: +case 0x6235: +case 0x6236: +case 0x6237: +case 0x6238: +case 0x6239: +case 0x623a: +case 0x623b: +case 0x623c: +case 0x623d: +case 0x623e: +case 0x623f: +case 0x6240: +case 0x6241: +case 0x6242: +case 0x6243: +case 0x6244: +case 0x6245: +case 0x6246: +case 0x6247: +case 0x6248: +case 0x6249: +case 0x624a: +case 0x624b: +case 0x624c: +case 0x624d: +case 0x624e: +case 0x624f: +case 0x6250: +case 0x6251: +case 0x6252: +case 0x6253: +case 0x6254: +case 0x6255: +case 0x6256: +case 0x6257: +case 0x6258: +case 0x6259: +case 0x625a: +case 0x625b: +case 0x625c: +case 0x625d: +case 0x625e: +case 0x625f: +case 0x6260: +case 0x6261: +case 0x6262: +case 0x6263: +case 0x6264: +case 0x6265: +case 0x6266: +case 0x6267: +case 0x6268: +case 0x6269: +case 0x626a: +case 0x626b: +case 0x626c: +case 0x626d: +case 0x626e: +case 0x626f: +case 0x6270: +case 0x6271: +case 0x6272: +case 0x6273: +case 0x6274: +case 0x6275: +case 0x6276: +case 0x6277: +case 0x6278: +case 0x6279: +case 0x627a: +case 0x627b: +case 0x627c: +case 0x627d: +case 0x627e: +case 0x627f: +case 0x6280: +case 0x6281: +case 0x6282: +case 0x6283: +case 0x6284: +case 0x6285: +case 0x6286: +case 0x6287: +case 0x6288: +case 0x6289: +case 0x628a: +case 0x628b: +case 0x628c: +case 0x628d: +case 0x628e: +case 0x628f: +case 0x6290: +case 0x6291: +case 0x6292: +case 0x6293: +case 0x6294: +case 0x6295: +case 0x6296: +case 0x6297: +case 0x6298: +case 0x6299: +case 0x629a: +case 0x629b: +case 0x629c: +case 0x629d: +case 0x629e: +case 0x629f: +case 0x62a0: +case 0x62a1: +case 0x62a2: +case 0x62a3: +case 0x62a4: +case 0x62a5: +case 0x62a6: +case 0x62a7: +case 0x62a8: +case 0x62a9: +case 0x62aa: +case 0x62ab: +case 0x62ac: +case 0x62ad: +case 0x62ae: +case 0x62af: +case 0x62b0: +case 0x62b1: +case 0x62b2: +case 0x62b3: +case 0x62b4: +case 0x62b5: +case 0x62b6: +case 0x62b7: +case 0x62b8: +case 0x62b9: +case 0x62ba: +case 0x62bb: +case 0x62bc: +case 0x62bd: +case 0x62be: +case 0x62bf: +case 0x62c0: +case 0x62c1: +case 0x62c2: +case 0x62c3: +case 0x62c4: +case 0x62c5: +case 0x62c6: +case 0x62c7: +case 0x62c8: +case 0x62c9: +case 0x62ca: +case 0x62cb: +case 0x62cc: +case 0x62cd: +case 0x62ce: +case 0x62cf: +case 0x62d0: +case 0x62d1: +case 0x62d2: +case 0x62d3: +case 0x62d4: +case 0x62d5: +case 0x62d6: +case 0x62d7: +case 0x62d8: +case 0x62d9: +case 0x62da: +case 0x62db: +case 0x62dc: +case 0x62dd: +case 0x62de: +case 0x62df: +case 0x62e0: +case 0x62e1: +case 0x62e2: +case 0x62e3: +case 0x62e4: +case 0x62e5: +case 0x62e6: +case 0x62e7: +case 0x62e8: +case 0x62e9: +case 0x62ea: +case 0x62eb: +case 0x62ec: +case 0x62ed: +case 0x62ee: +case 0x62ef: +case 0x62f0: +case 0x62f1: +case 0x62f2: +case 0x62f3: +case 0x62f4: +case 0x62f5: +case 0x62f6: +case 0x62f7: +case 0x62f8: +case 0x62f9: +case 0x62fa: +case 0x62fb: +case 0x62fc: +case 0x62fd: +case 0x62fe: +case 0x62ff: + { + Bxx<0x02>((int8)instr); + } + break; + +case 0x6300: +case 0x6301: +case 0x6302: +case 0x6303: +case 0x6304: +case 0x6305: +case 0x6306: +case 0x6307: +case 0x6308: +case 0x6309: +case 0x630a: +case 0x630b: +case 0x630c: +case 0x630d: +case 0x630e: +case 0x630f: +case 0x6310: +case 0x6311: +case 0x6312: +case 0x6313: +case 0x6314: +case 0x6315: +case 0x6316: +case 0x6317: +case 0x6318: +case 0x6319: +case 0x631a: +case 0x631b: +case 0x631c: +case 0x631d: +case 0x631e: +case 0x631f: +case 0x6320: +case 0x6321: +case 0x6322: +case 0x6323: +case 0x6324: +case 0x6325: +case 0x6326: +case 0x6327: +case 0x6328: +case 0x6329: +case 0x632a: +case 0x632b: +case 0x632c: +case 0x632d: +case 0x632e: +case 0x632f: +case 0x6330: +case 0x6331: +case 0x6332: +case 0x6333: +case 0x6334: +case 0x6335: +case 0x6336: +case 0x6337: +case 0x6338: +case 0x6339: +case 0x633a: +case 0x633b: +case 0x633c: +case 0x633d: +case 0x633e: +case 0x633f: +case 0x6340: +case 0x6341: +case 0x6342: +case 0x6343: +case 0x6344: +case 0x6345: +case 0x6346: +case 0x6347: +case 0x6348: +case 0x6349: +case 0x634a: +case 0x634b: +case 0x634c: +case 0x634d: +case 0x634e: +case 0x634f: +case 0x6350: +case 0x6351: +case 0x6352: +case 0x6353: +case 0x6354: +case 0x6355: +case 0x6356: +case 0x6357: +case 0x6358: +case 0x6359: +case 0x635a: +case 0x635b: +case 0x635c: +case 0x635d: +case 0x635e: +case 0x635f: +case 0x6360: +case 0x6361: +case 0x6362: +case 0x6363: +case 0x6364: +case 0x6365: +case 0x6366: +case 0x6367: +case 0x6368: +case 0x6369: +case 0x636a: +case 0x636b: +case 0x636c: +case 0x636d: +case 0x636e: +case 0x636f: +case 0x6370: +case 0x6371: +case 0x6372: +case 0x6373: +case 0x6374: +case 0x6375: +case 0x6376: +case 0x6377: +case 0x6378: +case 0x6379: +case 0x637a: +case 0x637b: +case 0x637c: +case 0x637d: +case 0x637e: +case 0x637f: +case 0x6380: +case 0x6381: +case 0x6382: +case 0x6383: +case 0x6384: +case 0x6385: +case 0x6386: +case 0x6387: +case 0x6388: +case 0x6389: +case 0x638a: +case 0x638b: +case 0x638c: +case 0x638d: +case 0x638e: +case 0x638f: +case 0x6390: +case 0x6391: +case 0x6392: +case 0x6393: +case 0x6394: +case 0x6395: +case 0x6396: +case 0x6397: +case 0x6398: +case 0x6399: +case 0x639a: +case 0x639b: +case 0x639c: +case 0x639d: +case 0x639e: +case 0x639f: +case 0x63a0: +case 0x63a1: +case 0x63a2: +case 0x63a3: +case 0x63a4: +case 0x63a5: +case 0x63a6: +case 0x63a7: +case 0x63a8: +case 0x63a9: +case 0x63aa: +case 0x63ab: +case 0x63ac: +case 0x63ad: +case 0x63ae: +case 0x63af: +case 0x63b0: +case 0x63b1: +case 0x63b2: +case 0x63b3: +case 0x63b4: +case 0x63b5: +case 0x63b6: +case 0x63b7: +case 0x63b8: +case 0x63b9: +case 0x63ba: +case 0x63bb: +case 0x63bc: +case 0x63bd: +case 0x63be: +case 0x63bf: +case 0x63c0: +case 0x63c1: +case 0x63c2: +case 0x63c3: +case 0x63c4: +case 0x63c5: +case 0x63c6: +case 0x63c7: +case 0x63c8: +case 0x63c9: +case 0x63ca: +case 0x63cb: +case 0x63cc: +case 0x63cd: +case 0x63ce: +case 0x63cf: +case 0x63d0: +case 0x63d1: +case 0x63d2: +case 0x63d3: +case 0x63d4: +case 0x63d5: +case 0x63d6: +case 0x63d7: +case 0x63d8: +case 0x63d9: +case 0x63da: +case 0x63db: +case 0x63dc: +case 0x63dd: +case 0x63de: +case 0x63df: +case 0x63e0: +case 0x63e1: +case 0x63e2: +case 0x63e3: +case 0x63e4: +case 0x63e5: +case 0x63e6: +case 0x63e7: +case 0x63e8: +case 0x63e9: +case 0x63ea: +case 0x63eb: +case 0x63ec: +case 0x63ed: +case 0x63ee: +case 0x63ef: +case 0x63f0: +case 0x63f1: +case 0x63f2: +case 0x63f3: +case 0x63f4: +case 0x63f5: +case 0x63f6: +case 0x63f7: +case 0x63f8: +case 0x63f9: +case 0x63fa: +case 0x63fb: +case 0x63fc: +case 0x63fd: +case 0x63fe: +case 0x63ff: + { + Bxx<0x03>((int8)instr); + } + break; + +case 0x6400: +case 0x6401: +case 0x6402: +case 0x6403: +case 0x6404: +case 0x6405: +case 0x6406: +case 0x6407: +case 0x6408: +case 0x6409: +case 0x640a: +case 0x640b: +case 0x640c: +case 0x640d: +case 0x640e: +case 0x640f: +case 0x6410: +case 0x6411: +case 0x6412: +case 0x6413: +case 0x6414: +case 0x6415: +case 0x6416: +case 0x6417: +case 0x6418: +case 0x6419: +case 0x641a: +case 0x641b: +case 0x641c: +case 0x641d: +case 0x641e: +case 0x641f: +case 0x6420: +case 0x6421: +case 0x6422: +case 0x6423: +case 0x6424: +case 0x6425: +case 0x6426: +case 0x6427: +case 0x6428: +case 0x6429: +case 0x642a: +case 0x642b: +case 0x642c: +case 0x642d: +case 0x642e: +case 0x642f: +case 0x6430: +case 0x6431: +case 0x6432: +case 0x6433: +case 0x6434: +case 0x6435: +case 0x6436: +case 0x6437: +case 0x6438: +case 0x6439: +case 0x643a: +case 0x643b: +case 0x643c: +case 0x643d: +case 0x643e: +case 0x643f: +case 0x6440: +case 0x6441: +case 0x6442: +case 0x6443: +case 0x6444: +case 0x6445: +case 0x6446: +case 0x6447: +case 0x6448: +case 0x6449: +case 0x644a: +case 0x644b: +case 0x644c: +case 0x644d: +case 0x644e: +case 0x644f: +case 0x6450: +case 0x6451: +case 0x6452: +case 0x6453: +case 0x6454: +case 0x6455: +case 0x6456: +case 0x6457: +case 0x6458: +case 0x6459: +case 0x645a: +case 0x645b: +case 0x645c: +case 0x645d: +case 0x645e: +case 0x645f: +case 0x6460: +case 0x6461: +case 0x6462: +case 0x6463: +case 0x6464: +case 0x6465: +case 0x6466: +case 0x6467: +case 0x6468: +case 0x6469: +case 0x646a: +case 0x646b: +case 0x646c: +case 0x646d: +case 0x646e: +case 0x646f: +case 0x6470: +case 0x6471: +case 0x6472: +case 0x6473: +case 0x6474: +case 0x6475: +case 0x6476: +case 0x6477: +case 0x6478: +case 0x6479: +case 0x647a: +case 0x647b: +case 0x647c: +case 0x647d: +case 0x647e: +case 0x647f: +case 0x6480: +case 0x6481: +case 0x6482: +case 0x6483: +case 0x6484: +case 0x6485: +case 0x6486: +case 0x6487: +case 0x6488: +case 0x6489: +case 0x648a: +case 0x648b: +case 0x648c: +case 0x648d: +case 0x648e: +case 0x648f: +case 0x6490: +case 0x6491: +case 0x6492: +case 0x6493: +case 0x6494: +case 0x6495: +case 0x6496: +case 0x6497: +case 0x6498: +case 0x6499: +case 0x649a: +case 0x649b: +case 0x649c: +case 0x649d: +case 0x649e: +case 0x649f: +case 0x64a0: +case 0x64a1: +case 0x64a2: +case 0x64a3: +case 0x64a4: +case 0x64a5: +case 0x64a6: +case 0x64a7: +case 0x64a8: +case 0x64a9: +case 0x64aa: +case 0x64ab: +case 0x64ac: +case 0x64ad: +case 0x64ae: +case 0x64af: +case 0x64b0: +case 0x64b1: +case 0x64b2: +case 0x64b3: +case 0x64b4: +case 0x64b5: +case 0x64b6: +case 0x64b7: +case 0x64b8: +case 0x64b9: +case 0x64ba: +case 0x64bb: +case 0x64bc: +case 0x64bd: +case 0x64be: +case 0x64bf: +case 0x64c0: +case 0x64c1: +case 0x64c2: +case 0x64c3: +case 0x64c4: +case 0x64c5: +case 0x64c6: +case 0x64c7: +case 0x64c8: +case 0x64c9: +case 0x64ca: +case 0x64cb: +case 0x64cc: +case 0x64cd: +case 0x64ce: +case 0x64cf: +case 0x64d0: +case 0x64d1: +case 0x64d2: +case 0x64d3: +case 0x64d4: +case 0x64d5: +case 0x64d6: +case 0x64d7: +case 0x64d8: +case 0x64d9: +case 0x64da: +case 0x64db: +case 0x64dc: +case 0x64dd: +case 0x64de: +case 0x64df: +case 0x64e0: +case 0x64e1: +case 0x64e2: +case 0x64e3: +case 0x64e4: +case 0x64e5: +case 0x64e6: +case 0x64e7: +case 0x64e8: +case 0x64e9: +case 0x64ea: +case 0x64eb: +case 0x64ec: +case 0x64ed: +case 0x64ee: +case 0x64ef: +case 0x64f0: +case 0x64f1: +case 0x64f2: +case 0x64f3: +case 0x64f4: +case 0x64f5: +case 0x64f6: +case 0x64f7: +case 0x64f8: +case 0x64f9: +case 0x64fa: +case 0x64fb: +case 0x64fc: +case 0x64fd: +case 0x64fe: +case 0x64ff: + { + Bxx<0x04>((int8)instr); + } + break; + +case 0x6500: +case 0x6501: +case 0x6502: +case 0x6503: +case 0x6504: +case 0x6505: +case 0x6506: +case 0x6507: +case 0x6508: +case 0x6509: +case 0x650a: +case 0x650b: +case 0x650c: +case 0x650d: +case 0x650e: +case 0x650f: +case 0x6510: +case 0x6511: +case 0x6512: +case 0x6513: +case 0x6514: +case 0x6515: +case 0x6516: +case 0x6517: +case 0x6518: +case 0x6519: +case 0x651a: +case 0x651b: +case 0x651c: +case 0x651d: +case 0x651e: +case 0x651f: +case 0x6520: +case 0x6521: +case 0x6522: +case 0x6523: +case 0x6524: +case 0x6525: +case 0x6526: +case 0x6527: +case 0x6528: +case 0x6529: +case 0x652a: +case 0x652b: +case 0x652c: +case 0x652d: +case 0x652e: +case 0x652f: +case 0x6530: +case 0x6531: +case 0x6532: +case 0x6533: +case 0x6534: +case 0x6535: +case 0x6536: +case 0x6537: +case 0x6538: +case 0x6539: +case 0x653a: +case 0x653b: +case 0x653c: +case 0x653d: +case 0x653e: +case 0x653f: +case 0x6540: +case 0x6541: +case 0x6542: +case 0x6543: +case 0x6544: +case 0x6545: +case 0x6546: +case 0x6547: +case 0x6548: +case 0x6549: +case 0x654a: +case 0x654b: +case 0x654c: +case 0x654d: +case 0x654e: +case 0x654f: +case 0x6550: +case 0x6551: +case 0x6552: +case 0x6553: +case 0x6554: +case 0x6555: +case 0x6556: +case 0x6557: +case 0x6558: +case 0x6559: +case 0x655a: +case 0x655b: +case 0x655c: +case 0x655d: +case 0x655e: +case 0x655f: +case 0x6560: +case 0x6561: +case 0x6562: +case 0x6563: +case 0x6564: +case 0x6565: +case 0x6566: +case 0x6567: +case 0x6568: +case 0x6569: +case 0x656a: +case 0x656b: +case 0x656c: +case 0x656d: +case 0x656e: +case 0x656f: +case 0x6570: +case 0x6571: +case 0x6572: +case 0x6573: +case 0x6574: +case 0x6575: +case 0x6576: +case 0x6577: +case 0x6578: +case 0x6579: +case 0x657a: +case 0x657b: +case 0x657c: +case 0x657d: +case 0x657e: +case 0x657f: +case 0x6580: +case 0x6581: +case 0x6582: +case 0x6583: +case 0x6584: +case 0x6585: +case 0x6586: +case 0x6587: +case 0x6588: +case 0x6589: +case 0x658a: +case 0x658b: +case 0x658c: +case 0x658d: +case 0x658e: +case 0x658f: +case 0x6590: +case 0x6591: +case 0x6592: +case 0x6593: +case 0x6594: +case 0x6595: +case 0x6596: +case 0x6597: +case 0x6598: +case 0x6599: +case 0x659a: +case 0x659b: +case 0x659c: +case 0x659d: +case 0x659e: +case 0x659f: +case 0x65a0: +case 0x65a1: +case 0x65a2: +case 0x65a3: +case 0x65a4: +case 0x65a5: +case 0x65a6: +case 0x65a7: +case 0x65a8: +case 0x65a9: +case 0x65aa: +case 0x65ab: +case 0x65ac: +case 0x65ad: +case 0x65ae: +case 0x65af: +case 0x65b0: +case 0x65b1: +case 0x65b2: +case 0x65b3: +case 0x65b4: +case 0x65b5: +case 0x65b6: +case 0x65b7: +case 0x65b8: +case 0x65b9: +case 0x65ba: +case 0x65bb: +case 0x65bc: +case 0x65bd: +case 0x65be: +case 0x65bf: +case 0x65c0: +case 0x65c1: +case 0x65c2: +case 0x65c3: +case 0x65c4: +case 0x65c5: +case 0x65c6: +case 0x65c7: +case 0x65c8: +case 0x65c9: +case 0x65ca: +case 0x65cb: +case 0x65cc: +case 0x65cd: +case 0x65ce: +case 0x65cf: +case 0x65d0: +case 0x65d1: +case 0x65d2: +case 0x65d3: +case 0x65d4: +case 0x65d5: +case 0x65d6: +case 0x65d7: +case 0x65d8: +case 0x65d9: +case 0x65da: +case 0x65db: +case 0x65dc: +case 0x65dd: +case 0x65de: +case 0x65df: +case 0x65e0: +case 0x65e1: +case 0x65e2: +case 0x65e3: +case 0x65e4: +case 0x65e5: +case 0x65e6: +case 0x65e7: +case 0x65e8: +case 0x65e9: +case 0x65ea: +case 0x65eb: +case 0x65ec: +case 0x65ed: +case 0x65ee: +case 0x65ef: +case 0x65f0: +case 0x65f1: +case 0x65f2: +case 0x65f3: +case 0x65f4: +case 0x65f5: +case 0x65f6: +case 0x65f7: +case 0x65f8: +case 0x65f9: +case 0x65fa: +case 0x65fb: +case 0x65fc: +case 0x65fd: +case 0x65fe: +case 0x65ff: + { + Bxx<0x05>((int8)instr); + } + break; + +case 0x6600: +case 0x6601: +case 0x6602: +case 0x6603: +case 0x6604: +case 0x6605: +case 0x6606: +case 0x6607: +case 0x6608: +case 0x6609: +case 0x660a: +case 0x660b: +case 0x660c: +case 0x660d: +case 0x660e: +case 0x660f: +case 0x6610: +case 0x6611: +case 0x6612: +case 0x6613: +case 0x6614: +case 0x6615: +case 0x6616: +case 0x6617: +case 0x6618: +case 0x6619: +case 0x661a: +case 0x661b: +case 0x661c: +case 0x661d: +case 0x661e: +case 0x661f: +case 0x6620: +case 0x6621: +case 0x6622: +case 0x6623: +case 0x6624: +case 0x6625: +case 0x6626: +case 0x6627: +case 0x6628: +case 0x6629: +case 0x662a: +case 0x662b: +case 0x662c: +case 0x662d: +case 0x662e: +case 0x662f: +case 0x6630: +case 0x6631: +case 0x6632: +case 0x6633: +case 0x6634: +case 0x6635: +case 0x6636: +case 0x6637: +case 0x6638: +case 0x6639: +case 0x663a: +case 0x663b: +case 0x663c: +case 0x663d: +case 0x663e: +case 0x663f: +case 0x6640: +case 0x6641: +case 0x6642: +case 0x6643: +case 0x6644: +case 0x6645: +case 0x6646: +case 0x6647: +case 0x6648: +case 0x6649: +case 0x664a: +case 0x664b: +case 0x664c: +case 0x664d: +case 0x664e: +case 0x664f: +case 0x6650: +case 0x6651: +case 0x6652: +case 0x6653: +case 0x6654: +case 0x6655: +case 0x6656: +case 0x6657: +case 0x6658: +case 0x6659: +case 0x665a: +case 0x665b: +case 0x665c: +case 0x665d: +case 0x665e: +case 0x665f: +case 0x6660: +case 0x6661: +case 0x6662: +case 0x6663: +case 0x6664: +case 0x6665: +case 0x6666: +case 0x6667: +case 0x6668: +case 0x6669: +case 0x666a: +case 0x666b: +case 0x666c: +case 0x666d: +case 0x666e: +case 0x666f: +case 0x6670: +case 0x6671: +case 0x6672: +case 0x6673: +case 0x6674: +case 0x6675: +case 0x6676: +case 0x6677: +case 0x6678: +case 0x6679: +case 0x667a: +case 0x667b: +case 0x667c: +case 0x667d: +case 0x667e: +case 0x667f: +case 0x6680: +case 0x6681: +case 0x6682: +case 0x6683: +case 0x6684: +case 0x6685: +case 0x6686: +case 0x6687: +case 0x6688: +case 0x6689: +case 0x668a: +case 0x668b: +case 0x668c: +case 0x668d: +case 0x668e: +case 0x668f: +case 0x6690: +case 0x6691: +case 0x6692: +case 0x6693: +case 0x6694: +case 0x6695: +case 0x6696: +case 0x6697: +case 0x6698: +case 0x6699: +case 0x669a: +case 0x669b: +case 0x669c: +case 0x669d: +case 0x669e: +case 0x669f: +case 0x66a0: +case 0x66a1: +case 0x66a2: +case 0x66a3: +case 0x66a4: +case 0x66a5: +case 0x66a6: +case 0x66a7: +case 0x66a8: +case 0x66a9: +case 0x66aa: +case 0x66ab: +case 0x66ac: +case 0x66ad: +case 0x66ae: +case 0x66af: +case 0x66b0: +case 0x66b1: +case 0x66b2: +case 0x66b3: +case 0x66b4: +case 0x66b5: +case 0x66b6: +case 0x66b7: +case 0x66b8: +case 0x66b9: +case 0x66ba: +case 0x66bb: +case 0x66bc: +case 0x66bd: +case 0x66be: +case 0x66bf: +case 0x66c0: +case 0x66c1: +case 0x66c2: +case 0x66c3: +case 0x66c4: +case 0x66c5: +case 0x66c6: +case 0x66c7: +case 0x66c8: +case 0x66c9: +case 0x66ca: +case 0x66cb: +case 0x66cc: +case 0x66cd: +case 0x66ce: +case 0x66cf: +case 0x66d0: +case 0x66d1: +case 0x66d2: +case 0x66d3: +case 0x66d4: +case 0x66d5: +case 0x66d6: +case 0x66d7: +case 0x66d8: +case 0x66d9: +case 0x66da: +case 0x66db: +case 0x66dc: +case 0x66dd: +case 0x66de: +case 0x66df: +case 0x66e0: +case 0x66e1: +case 0x66e2: +case 0x66e3: +case 0x66e4: +case 0x66e5: +case 0x66e6: +case 0x66e7: +case 0x66e8: +case 0x66e9: +case 0x66ea: +case 0x66eb: +case 0x66ec: +case 0x66ed: +case 0x66ee: +case 0x66ef: +case 0x66f0: +case 0x66f1: +case 0x66f2: +case 0x66f3: +case 0x66f4: +case 0x66f5: +case 0x66f6: +case 0x66f7: +case 0x66f8: +case 0x66f9: +case 0x66fa: +case 0x66fb: +case 0x66fc: +case 0x66fd: +case 0x66fe: +case 0x66ff: + { + Bxx<0x06>((int8)instr); + } + break; + +case 0x6700: +case 0x6701: +case 0x6702: +case 0x6703: +case 0x6704: +case 0x6705: +case 0x6706: +case 0x6707: +case 0x6708: +case 0x6709: +case 0x670a: +case 0x670b: +case 0x670c: +case 0x670d: +case 0x670e: +case 0x670f: +case 0x6710: +case 0x6711: +case 0x6712: +case 0x6713: +case 0x6714: +case 0x6715: +case 0x6716: +case 0x6717: +case 0x6718: +case 0x6719: +case 0x671a: +case 0x671b: +case 0x671c: +case 0x671d: +case 0x671e: +case 0x671f: +case 0x6720: +case 0x6721: +case 0x6722: +case 0x6723: +case 0x6724: +case 0x6725: +case 0x6726: +case 0x6727: +case 0x6728: +case 0x6729: +case 0x672a: +case 0x672b: +case 0x672c: +case 0x672d: +case 0x672e: +case 0x672f: +case 0x6730: +case 0x6731: +case 0x6732: +case 0x6733: +case 0x6734: +case 0x6735: +case 0x6736: +case 0x6737: +case 0x6738: +case 0x6739: +case 0x673a: +case 0x673b: +case 0x673c: +case 0x673d: +case 0x673e: +case 0x673f: +case 0x6740: +case 0x6741: +case 0x6742: +case 0x6743: +case 0x6744: +case 0x6745: +case 0x6746: +case 0x6747: +case 0x6748: +case 0x6749: +case 0x674a: +case 0x674b: +case 0x674c: +case 0x674d: +case 0x674e: +case 0x674f: +case 0x6750: +case 0x6751: +case 0x6752: +case 0x6753: +case 0x6754: +case 0x6755: +case 0x6756: +case 0x6757: +case 0x6758: +case 0x6759: +case 0x675a: +case 0x675b: +case 0x675c: +case 0x675d: +case 0x675e: +case 0x675f: +case 0x6760: +case 0x6761: +case 0x6762: +case 0x6763: +case 0x6764: +case 0x6765: +case 0x6766: +case 0x6767: +case 0x6768: +case 0x6769: +case 0x676a: +case 0x676b: +case 0x676c: +case 0x676d: +case 0x676e: +case 0x676f: +case 0x6770: +case 0x6771: +case 0x6772: +case 0x6773: +case 0x6774: +case 0x6775: +case 0x6776: +case 0x6777: +case 0x6778: +case 0x6779: +case 0x677a: +case 0x677b: +case 0x677c: +case 0x677d: +case 0x677e: +case 0x677f: +case 0x6780: +case 0x6781: +case 0x6782: +case 0x6783: +case 0x6784: +case 0x6785: +case 0x6786: +case 0x6787: +case 0x6788: +case 0x6789: +case 0x678a: +case 0x678b: +case 0x678c: +case 0x678d: +case 0x678e: +case 0x678f: +case 0x6790: +case 0x6791: +case 0x6792: +case 0x6793: +case 0x6794: +case 0x6795: +case 0x6796: +case 0x6797: +case 0x6798: +case 0x6799: +case 0x679a: +case 0x679b: +case 0x679c: +case 0x679d: +case 0x679e: +case 0x679f: +case 0x67a0: +case 0x67a1: +case 0x67a2: +case 0x67a3: +case 0x67a4: +case 0x67a5: +case 0x67a6: +case 0x67a7: +case 0x67a8: +case 0x67a9: +case 0x67aa: +case 0x67ab: +case 0x67ac: +case 0x67ad: +case 0x67ae: +case 0x67af: +case 0x67b0: +case 0x67b1: +case 0x67b2: +case 0x67b3: +case 0x67b4: +case 0x67b5: +case 0x67b6: +case 0x67b7: +case 0x67b8: +case 0x67b9: +case 0x67ba: +case 0x67bb: +case 0x67bc: +case 0x67bd: +case 0x67be: +case 0x67bf: +case 0x67c0: +case 0x67c1: +case 0x67c2: +case 0x67c3: +case 0x67c4: +case 0x67c5: +case 0x67c6: +case 0x67c7: +case 0x67c8: +case 0x67c9: +case 0x67ca: +case 0x67cb: +case 0x67cc: +case 0x67cd: +case 0x67ce: +case 0x67cf: +case 0x67d0: +case 0x67d1: +case 0x67d2: +case 0x67d3: +case 0x67d4: +case 0x67d5: +case 0x67d6: +case 0x67d7: +case 0x67d8: +case 0x67d9: +case 0x67da: +case 0x67db: +case 0x67dc: +case 0x67dd: +case 0x67de: +case 0x67df: +case 0x67e0: +case 0x67e1: +case 0x67e2: +case 0x67e3: +case 0x67e4: +case 0x67e5: +case 0x67e6: +case 0x67e7: +case 0x67e8: +case 0x67e9: +case 0x67ea: +case 0x67eb: +case 0x67ec: +case 0x67ed: +case 0x67ee: +case 0x67ef: +case 0x67f0: +case 0x67f1: +case 0x67f2: +case 0x67f3: +case 0x67f4: +case 0x67f5: +case 0x67f6: +case 0x67f7: +case 0x67f8: +case 0x67f9: +case 0x67fa: +case 0x67fb: +case 0x67fc: +case 0x67fd: +case 0x67fe: +case 0x67ff: + { + Bxx<0x07>((int8)instr); + } + break; + +case 0x6800: +case 0x6801: +case 0x6802: +case 0x6803: +case 0x6804: +case 0x6805: +case 0x6806: +case 0x6807: +case 0x6808: +case 0x6809: +case 0x680a: +case 0x680b: +case 0x680c: +case 0x680d: +case 0x680e: +case 0x680f: +case 0x6810: +case 0x6811: +case 0x6812: +case 0x6813: +case 0x6814: +case 0x6815: +case 0x6816: +case 0x6817: +case 0x6818: +case 0x6819: +case 0x681a: +case 0x681b: +case 0x681c: +case 0x681d: +case 0x681e: +case 0x681f: +case 0x6820: +case 0x6821: +case 0x6822: +case 0x6823: +case 0x6824: +case 0x6825: +case 0x6826: +case 0x6827: +case 0x6828: +case 0x6829: +case 0x682a: +case 0x682b: +case 0x682c: +case 0x682d: +case 0x682e: +case 0x682f: +case 0x6830: +case 0x6831: +case 0x6832: +case 0x6833: +case 0x6834: +case 0x6835: +case 0x6836: +case 0x6837: +case 0x6838: +case 0x6839: +case 0x683a: +case 0x683b: +case 0x683c: +case 0x683d: +case 0x683e: +case 0x683f: +case 0x6840: +case 0x6841: +case 0x6842: +case 0x6843: +case 0x6844: +case 0x6845: +case 0x6846: +case 0x6847: +case 0x6848: +case 0x6849: +case 0x684a: +case 0x684b: +case 0x684c: +case 0x684d: +case 0x684e: +case 0x684f: +case 0x6850: +case 0x6851: +case 0x6852: +case 0x6853: +case 0x6854: +case 0x6855: +case 0x6856: +case 0x6857: +case 0x6858: +case 0x6859: +case 0x685a: +case 0x685b: +case 0x685c: +case 0x685d: +case 0x685e: +case 0x685f: +case 0x6860: +case 0x6861: +case 0x6862: +case 0x6863: +case 0x6864: +case 0x6865: +case 0x6866: +case 0x6867: +case 0x6868: +case 0x6869: +case 0x686a: +case 0x686b: +case 0x686c: +case 0x686d: +case 0x686e: +case 0x686f: +case 0x6870: +case 0x6871: +case 0x6872: +case 0x6873: +case 0x6874: +case 0x6875: +case 0x6876: +case 0x6877: +case 0x6878: +case 0x6879: +case 0x687a: +case 0x687b: +case 0x687c: +case 0x687d: +case 0x687e: +case 0x687f: +case 0x6880: +case 0x6881: +case 0x6882: +case 0x6883: +case 0x6884: +case 0x6885: +case 0x6886: +case 0x6887: +case 0x6888: +case 0x6889: +case 0x688a: +case 0x688b: +case 0x688c: +case 0x688d: +case 0x688e: +case 0x688f: +case 0x6890: +case 0x6891: +case 0x6892: +case 0x6893: +case 0x6894: +case 0x6895: +case 0x6896: +case 0x6897: +case 0x6898: +case 0x6899: +case 0x689a: +case 0x689b: +case 0x689c: +case 0x689d: +case 0x689e: +case 0x689f: +case 0x68a0: +case 0x68a1: +case 0x68a2: +case 0x68a3: +case 0x68a4: +case 0x68a5: +case 0x68a6: +case 0x68a7: +case 0x68a8: +case 0x68a9: +case 0x68aa: +case 0x68ab: +case 0x68ac: +case 0x68ad: +case 0x68ae: +case 0x68af: +case 0x68b0: +case 0x68b1: +case 0x68b2: +case 0x68b3: +case 0x68b4: +case 0x68b5: +case 0x68b6: +case 0x68b7: +case 0x68b8: +case 0x68b9: +case 0x68ba: +case 0x68bb: +case 0x68bc: +case 0x68bd: +case 0x68be: +case 0x68bf: +case 0x68c0: +case 0x68c1: +case 0x68c2: +case 0x68c3: +case 0x68c4: +case 0x68c5: +case 0x68c6: +case 0x68c7: +case 0x68c8: +case 0x68c9: +case 0x68ca: +case 0x68cb: +case 0x68cc: +case 0x68cd: +case 0x68ce: +case 0x68cf: +case 0x68d0: +case 0x68d1: +case 0x68d2: +case 0x68d3: +case 0x68d4: +case 0x68d5: +case 0x68d6: +case 0x68d7: +case 0x68d8: +case 0x68d9: +case 0x68da: +case 0x68db: +case 0x68dc: +case 0x68dd: +case 0x68de: +case 0x68df: +case 0x68e0: +case 0x68e1: +case 0x68e2: +case 0x68e3: +case 0x68e4: +case 0x68e5: +case 0x68e6: +case 0x68e7: +case 0x68e8: +case 0x68e9: +case 0x68ea: +case 0x68eb: +case 0x68ec: +case 0x68ed: +case 0x68ee: +case 0x68ef: +case 0x68f0: +case 0x68f1: +case 0x68f2: +case 0x68f3: +case 0x68f4: +case 0x68f5: +case 0x68f6: +case 0x68f7: +case 0x68f8: +case 0x68f9: +case 0x68fa: +case 0x68fb: +case 0x68fc: +case 0x68fd: +case 0x68fe: +case 0x68ff: + { + Bxx<0x08>((int8)instr); + } + break; + +case 0x6900: +case 0x6901: +case 0x6902: +case 0x6903: +case 0x6904: +case 0x6905: +case 0x6906: +case 0x6907: +case 0x6908: +case 0x6909: +case 0x690a: +case 0x690b: +case 0x690c: +case 0x690d: +case 0x690e: +case 0x690f: +case 0x6910: +case 0x6911: +case 0x6912: +case 0x6913: +case 0x6914: +case 0x6915: +case 0x6916: +case 0x6917: +case 0x6918: +case 0x6919: +case 0x691a: +case 0x691b: +case 0x691c: +case 0x691d: +case 0x691e: +case 0x691f: +case 0x6920: +case 0x6921: +case 0x6922: +case 0x6923: +case 0x6924: +case 0x6925: +case 0x6926: +case 0x6927: +case 0x6928: +case 0x6929: +case 0x692a: +case 0x692b: +case 0x692c: +case 0x692d: +case 0x692e: +case 0x692f: +case 0x6930: +case 0x6931: +case 0x6932: +case 0x6933: +case 0x6934: +case 0x6935: +case 0x6936: +case 0x6937: +case 0x6938: +case 0x6939: +case 0x693a: +case 0x693b: +case 0x693c: +case 0x693d: +case 0x693e: +case 0x693f: +case 0x6940: +case 0x6941: +case 0x6942: +case 0x6943: +case 0x6944: +case 0x6945: +case 0x6946: +case 0x6947: +case 0x6948: +case 0x6949: +case 0x694a: +case 0x694b: +case 0x694c: +case 0x694d: +case 0x694e: +case 0x694f: +case 0x6950: +case 0x6951: +case 0x6952: +case 0x6953: +case 0x6954: +case 0x6955: +case 0x6956: +case 0x6957: +case 0x6958: +case 0x6959: +case 0x695a: +case 0x695b: +case 0x695c: +case 0x695d: +case 0x695e: +case 0x695f: +case 0x6960: +case 0x6961: +case 0x6962: +case 0x6963: +case 0x6964: +case 0x6965: +case 0x6966: +case 0x6967: +case 0x6968: +case 0x6969: +case 0x696a: +case 0x696b: +case 0x696c: +case 0x696d: +case 0x696e: +case 0x696f: +case 0x6970: +case 0x6971: +case 0x6972: +case 0x6973: +case 0x6974: +case 0x6975: +case 0x6976: +case 0x6977: +case 0x6978: +case 0x6979: +case 0x697a: +case 0x697b: +case 0x697c: +case 0x697d: +case 0x697e: +case 0x697f: +case 0x6980: +case 0x6981: +case 0x6982: +case 0x6983: +case 0x6984: +case 0x6985: +case 0x6986: +case 0x6987: +case 0x6988: +case 0x6989: +case 0x698a: +case 0x698b: +case 0x698c: +case 0x698d: +case 0x698e: +case 0x698f: +case 0x6990: +case 0x6991: +case 0x6992: +case 0x6993: +case 0x6994: +case 0x6995: +case 0x6996: +case 0x6997: +case 0x6998: +case 0x6999: +case 0x699a: +case 0x699b: +case 0x699c: +case 0x699d: +case 0x699e: +case 0x699f: +case 0x69a0: +case 0x69a1: +case 0x69a2: +case 0x69a3: +case 0x69a4: +case 0x69a5: +case 0x69a6: +case 0x69a7: +case 0x69a8: +case 0x69a9: +case 0x69aa: +case 0x69ab: +case 0x69ac: +case 0x69ad: +case 0x69ae: +case 0x69af: +case 0x69b0: +case 0x69b1: +case 0x69b2: +case 0x69b3: +case 0x69b4: +case 0x69b5: +case 0x69b6: +case 0x69b7: +case 0x69b8: +case 0x69b9: +case 0x69ba: +case 0x69bb: +case 0x69bc: +case 0x69bd: +case 0x69be: +case 0x69bf: +case 0x69c0: +case 0x69c1: +case 0x69c2: +case 0x69c3: +case 0x69c4: +case 0x69c5: +case 0x69c6: +case 0x69c7: +case 0x69c8: +case 0x69c9: +case 0x69ca: +case 0x69cb: +case 0x69cc: +case 0x69cd: +case 0x69ce: +case 0x69cf: +case 0x69d0: +case 0x69d1: +case 0x69d2: +case 0x69d3: +case 0x69d4: +case 0x69d5: +case 0x69d6: +case 0x69d7: +case 0x69d8: +case 0x69d9: +case 0x69da: +case 0x69db: +case 0x69dc: +case 0x69dd: +case 0x69de: +case 0x69df: +case 0x69e0: +case 0x69e1: +case 0x69e2: +case 0x69e3: +case 0x69e4: +case 0x69e5: +case 0x69e6: +case 0x69e7: +case 0x69e8: +case 0x69e9: +case 0x69ea: +case 0x69eb: +case 0x69ec: +case 0x69ed: +case 0x69ee: +case 0x69ef: +case 0x69f0: +case 0x69f1: +case 0x69f2: +case 0x69f3: +case 0x69f4: +case 0x69f5: +case 0x69f6: +case 0x69f7: +case 0x69f8: +case 0x69f9: +case 0x69fa: +case 0x69fb: +case 0x69fc: +case 0x69fd: +case 0x69fe: +case 0x69ff: + { + Bxx<0x09>((int8)instr); + } + break; + +case 0x6a00: +case 0x6a01: +case 0x6a02: +case 0x6a03: +case 0x6a04: +case 0x6a05: +case 0x6a06: +case 0x6a07: +case 0x6a08: +case 0x6a09: +case 0x6a0a: +case 0x6a0b: +case 0x6a0c: +case 0x6a0d: +case 0x6a0e: +case 0x6a0f: +case 0x6a10: +case 0x6a11: +case 0x6a12: +case 0x6a13: +case 0x6a14: +case 0x6a15: +case 0x6a16: +case 0x6a17: +case 0x6a18: +case 0x6a19: +case 0x6a1a: +case 0x6a1b: +case 0x6a1c: +case 0x6a1d: +case 0x6a1e: +case 0x6a1f: +case 0x6a20: +case 0x6a21: +case 0x6a22: +case 0x6a23: +case 0x6a24: +case 0x6a25: +case 0x6a26: +case 0x6a27: +case 0x6a28: +case 0x6a29: +case 0x6a2a: +case 0x6a2b: +case 0x6a2c: +case 0x6a2d: +case 0x6a2e: +case 0x6a2f: +case 0x6a30: +case 0x6a31: +case 0x6a32: +case 0x6a33: +case 0x6a34: +case 0x6a35: +case 0x6a36: +case 0x6a37: +case 0x6a38: +case 0x6a39: +case 0x6a3a: +case 0x6a3b: +case 0x6a3c: +case 0x6a3d: +case 0x6a3e: +case 0x6a3f: +case 0x6a40: +case 0x6a41: +case 0x6a42: +case 0x6a43: +case 0x6a44: +case 0x6a45: +case 0x6a46: +case 0x6a47: +case 0x6a48: +case 0x6a49: +case 0x6a4a: +case 0x6a4b: +case 0x6a4c: +case 0x6a4d: +case 0x6a4e: +case 0x6a4f: +case 0x6a50: +case 0x6a51: +case 0x6a52: +case 0x6a53: +case 0x6a54: +case 0x6a55: +case 0x6a56: +case 0x6a57: +case 0x6a58: +case 0x6a59: +case 0x6a5a: +case 0x6a5b: +case 0x6a5c: +case 0x6a5d: +case 0x6a5e: +case 0x6a5f: +case 0x6a60: +case 0x6a61: +case 0x6a62: +case 0x6a63: +case 0x6a64: +case 0x6a65: +case 0x6a66: +case 0x6a67: +case 0x6a68: +case 0x6a69: +case 0x6a6a: +case 0x6a6b: +case 0x6a6c: +case 0x6a6d: +case 0x6a6e: +case 0x6a6f: +case 0x6a70: +case 0x6a71: +case 0x6a72: +case 0x6a73: +case 0x6a74: +case 0x6a75: +case 0x6a76: +case 0x6a77: +case 0x6a78: +case 0x6a79: +case 0x6a7a: +case 0x6a7b: +case 0x6a7c: +case 0x6a7d: +case 0x6a7e: +case 0x6a7f: +case 0x6a80: +case 0x6a81: +case 0x6a82: +case 0x6a83: +case 0x6a84: +case 0x6a85: +case 0x6a86: +case 0x6a87: +case 0x6a88: +case 0x6a89: +case 0x6a8a: +case 0x6a8b: +case 0x6a8c: +case 0x6a8d: +case 0x6a8e: +case 0x6a8f: +case 0x6a90: +case 0x6a91: +case 0x6a92: +case 0x6a93: +case 0x6a94: +case 0x6a95: +case 0x6a96: +case 0x6a97: +case 0x6a98: +case 0x6a99: +case 0x6a9a: +case 0x6a9b: +case 0x6a9c: +case 0x6a9d: +case 0x6a9e: +case 0x6a9f: +case 0x6aa0: +case 0x6aa1: +case 0x6aa2: +case 0x6aa3: +case 0x6aa4: +case 0x6aa5: +case 0x6aa6: +case 0x6aa7: +case 0x6aa8: +case 0x6aa9: +case 0x6aaa: +case 0x6aab: +case 0x6aac: +case 0x6aad: +case 0x6aae: +case 0x6aaf: +case 0x6ab0: +case 0x6ab1: +case 0x6ab2: +case 0x6ab3: +case 0x6ab4: +case 0x6ab5: +case 0x6ab6: +case 0x6ab7: +case 0x6ab8: +case 0x6ab9: +case 0x6aba: +case 0x6abb: +case 0x6abc: +case 0x6abd: +case 0x6abe: +case 0x6abf: +case 0x6ac0: +case 0x6ac1: +case 0x6ac2: +case 0x6ac3: +case 0x6ac4: +case 0x6ac5: +case 0x6ac6: +case 0x6ac7: +case 0x6ac8: +case 0x6ac9: +case 0x6aca: +case 0x6acb: +case 0x6acc: +case 0x6acd: +case 0x6ace: +case 0x6acf: +case 0x6ad0: +case 0x6ad1: +case 0x6ad2: +case 0x6ad3: +case 0x6ad4: +case 0x6ad5: +case 0x6ad6: +case 0x6ad7: +case 0x6ad8: +case 0x6ad9: +case 0x6ada: +case 0x6adb: +case 0x6adc: +case 0x6add: +case 0x6ade: +case 0x6adf: +case 0x6ae0: +case 0x6ae1: +case 0x6ae2: +case 0x6ae3: +case 0x6ae4: +case 0x6ae5: +case 0x6ae6: +case 0x6ae7: +case 0x6ae8: +case 0x6ae9: +case 0x6aea: +case 0x6aeb: +case 0x6aec: +case 0x6aed: +case 0x6aee: +case 0x6aef: +case 0x6af0: +case 0x6af1: +case 0x6af2: +case 0x6af3: +case 0x6af4: +case 0x6af5: +case 0x6af6: +case 0x6af7: +case 0x6af8: +case 0x6af9: +case 0x6afa: +case 0x6afb: +case 0x6afc: +case 0x6afd: +case 0x6afe: +case 0x6aff: + { + Bxx<0x0a>((int8)instr); + } + break; + +case 0x6b00: +case 0x6b01: +case 0x6b02: +case 0x6b03: +case 0x6b04: +case 0x6b05: +case 0x6b06: +case 0x6b07: +case 0x6b08: +case 0x6b09: +case 0x6b0a: +case 0x6b0b: +case 0x6b0c: +case 0x6b0d: +case 0x6b0e: +case 0x6b0f: +case 0x6b10: +case 0x6b11: +case 0x6b12: +case 0x6b13: +case 0x6b14: +case 0x6b15: +case 0x6b16: +case 0x6b17: +case 0x6b18: +case 0x6b19: +case 0x6b1a: +case 0x6b1b: +case 0x6b1c: +case 0x6b1d: +case 0x6b1e: +case 0x6b1f: +case 0x6b20: +case 0x6b21: +case 0x6b22: +case 0x6b23: +case 0x6b24: +case 0x6b25: +case 0x6b26: +case 0x6b27: +case 0x6b28: +case 0x6b29: +case 0x6b2a: +case 0x6b2b: +case 0x6b2c: +case 0x6b2d: +case 0x6b2e: +case 0x6b2f: +case 0x6b30: +case 0x6b31: +case 0x6b32: +case 0x6b33: +case 0x6b34: +case 0x6b35: +case 0x6b36: +case 0x6b37: +case 0x6b38: +case 0x6b39: +case 0x6b3a: +case 0x6b3b: +case 0x6b3c: +case 0x6b3d: +case 0x6b3e: +case 0x6b3f: +case 0x6b40: +case 0x6b41: +case 0x6b42: +case 0x6b43: +case 0x6b44: +case 0x6b45: +case 0x6b46: +case 0x6b47: +case 0x6b48: +case 0x6b49: +case 0x6b4a: +case 0x6b4b: +case 0x6b4c: +case 0x6b4d: +case 0x6b4e: +case 0x6b4f: +case 0x6b50: +case 0x6b51: +case 0x6b52: +case 0x6b53: +case 0x6b54: +case 0x6b55: +case 0x6b56: +case 0x6b57: +case 0x6b58: +case 0x6b59: +case 0x6b5a: +case 0x6b5b: +case 0x6b5c: +case 0x6b5d: +case 0x6b5e: +case 0x6b5f: +case 0x6b60: +case 0x6b61: +case 0x6b62: +case 0x6b63: +case 0x6b64: +case 0x6b65: +case 0x6b66: +case 0x6b67: +case 0x6b68: +case 0x6b69: +case 0x6b6a: +case 0x6b6b: +case 0x6b6c: +case 0x6b6d: +case 0x6b6e: +case 0x6b6f: +case 0x6b70: +case 0x6b71: +case 0x6b72: +case 0x6b73: +case 0x6b74: +case 0x6b75: +case 0x6b76: +case 0x6b77: +case 0x6b78: +case 0x6b79: +case 0x6b7a: +case 0x6b7b: +case 0x6b7c: +case 0x6b7d: +case 0x6b7e: +case 0x6b7f: +case 0x6b80: +case 0x6b81: +case 0x6b82: +case 0x6b83: +case 0x6b84: +case 0x6b85: +case 0x6b86: +case 0x6b87: +case 0x6b88: +case 0x6b89: +case 0x6b8a: +case 0x6b8b: +case 0x6b8c: +case 0x6b8d: +case 0x6b8e: +case 0x6b8f: +case 0x6b90: +case 0x6b91: +case 0x6b92: +case 0x6b93: +case 0x6b94: +case 0x6b95: +case 0x6b96: +case 0x6b97: +case 0x6b98: +case 0x6b99: +case 0x6b9a: +case 0x6b9b: +case 0x6b9c: +case 0x6b9d: +case 0x6b9e: +case 0x6b9f: +case 0x6ba0: +case 0x6ba1: +case 0x6ba2: +case 0x6ba3: +case 0x6ba4: +case 0x6ba5: +case 0x6ba6: +case 0x6ba7: +case 0x6ba8: +case 0x6ba9: +case 0x6baa: +case 0x6bab: +case 0x6bac: +case 0x6bad: +case 0x6bae: +case 0x6baf: +case 0x6bb0: +case 0x6bb1: +case 0x6bb2: +case 0x6bb3: +case 0x6bb4: +case 0x6bb5: +case 0x6bb6: +case 0x6bb7: +case 0x6bb8: +case 0x6bb9: +case 0x6bba: +case 0x6bbb: +case 0x6bbc: +case 0x6bbd: +case 0x6bbe: +case 0x6bbf: +case 0x6bc0: +case 0x6bc1: +case 0x6bc2: +case 0x6bc3: +case 0x6bc4: +case 0x6bc5: +case 0x6bc6: +case 0x6bc7: +case 0x6bc8: +case 0x6bc9: +case 0x6bca: +case 0x6bcb: +case 0x6bcc: +case 0x6bcd: +case 0x6bce: +case 0x6bcf: +case 0x6bd0: +case 0x6bd1: +case 0x6bd2: +case 0x6bd3: +case 0x6bd4: +case 0x6bd5: +case 0x6bd6: +case 0x6bd7: +case 0x6bd8: +case 0x6bd9: +case 0x6bda: +case 0x6bdb: +case 0x6bdc: +case 0x6bdd: +case 0x6bde: +case 0x6bdf: +case 0x6be0: +case 0x6be1: +case 0x6be2: +case 0x6be3: +case 0x6be4: +case 0x6be5: +case 0x6be6: +case 0x6be7: +case 0x6be8: +case 0x6be9: +case 0x6bea: +case 0x6beb: +case 0x6bec: +case 0x6bed: +case 0x6bee: +case 0x6bef: +case 0x6bf0: +case 0x6bf1: +case 0x6bf2: +case 0x6bf3: +case 0x6bf4: +case 0x6bf5: +case 0x6bf6: +case 0x6bf7: +case 0x6bf8: +case 0x6bf9: +case 0x6bfa: +case 0x6bfb: +case 0x6bfc: +case 0x6bfd: +case 0x6bfe: +case 0x6bff: + { + Bxx<0x0b>((int8)instr); + } + break; + +case 0x6c00: +case 0x6c01: +case 0x6c02: +case 0x6c03: +case 0x6c04: +case 0x6c05: +case 0x6c06: +case 0x6c07: +case 0x6c08: +case 0x6c09: +case 0x6c0a: +case 0x6c0b: +case 0x6c0c: +case 0x6c0d: +case 0x6c0e: +case 0x6c0f: +case 0x6c10: +case 0x6c11: +case 0x6c12: +case 0x6c13: +case 0x6c14: +case 0x6c15: +case 0x6c16: +case 0x6c17: +case 0x6c18: +case 0x6c19: +case 0x6c1a: +case 0x6c1b: +case 0x6c1c: +case 0x6c1d: +case 0x6c1e: +case 0x6c1f: +case 0x6c20: +case 0x6c21: +case 0x6c22: +case 0x6c23: +case 0x6c24: +case 0x6c25: +case 0x6c26: +case 0x6c27: +case 0x6c28: +case 0x6c29: +case 0x6c2a: +case 0x6c2b: +case 0x6c2c: +case 0x6c2d: +case 0x6c2e: +case 0x6c2f: +case 0x6c30: +case 0x6c31: +case 0x6c32: +case 0x6c33: +case 0x6c34: +case 0x6c35: +case 0x6c36: +case 0x6c37: +case 0x6c38: +case 0x6c39: +case 0x6c3a: +case 0x6c3b: +case 0x6c3c: +case 0x6c3d: +case 0x6c3e: +case 0x6c3f: +case 0x6c40: +case 0x6c41: +case 0x6c42: +case 0x6c43: +case 0x6c44: +case 0x6c45: +case 0x6c46: +case 0x6c47: +case 0x6c48: +case 0x6c49: +case 0x6c4a: +case 0x6c4b: +case 0x6c4c: +case 0x6c4d: +case 0x6c4e: +case 0x6c4f: +case 0x6c50: +case 0x6c51: +case 0x6c52: +case 0x6c53: +case 0x6c54: +case 0x6c55: +case 0x6c56: +case 0x6c57: +case 0x6c58: +case 0x6c59: +case 0x6c5a: +case 0x6c5b: +case 0x6c5c: +case 0x6c5d: +case 0x6c5e: +case 0x6c5f: +case 0x6c60: +case 0x6c61: +case 0x6c62: +case 0x6c63: +case 0x6c64: +case 0x6c65: +case 0x6c66: +case 0x6c67: +case 0x6c68: +case 0x6c69: +case 0x6c6a: +case 0x6c6b: +case 0x6c6c: +case 0x6c6d: +case 0x6c6e: +case 0x6c6f: +case 0x6c70: +case 0x6c71: +case 0x6c72: +case 0x6c73: +case 0x6c74: +case 0x6c75: +case 0x6c76: +case 0x6c77: +case 0x6c78: +case 0x6c79: +case 0x6c7a: +case 0x6c7b: +case 0x6c7c: +case 0x6c7d: +case 0x6c7e: +case 0x6c7f: +case 0x6c80: +case 0x6c81: +case 0x6c82: +case 0x6c83: +case 0x6c84: +case 0x6c85: +case 0x6c86: +case 0x6c87: +case 0x6c88: +case 0x6c89: +case 0x6c8a: +case 0x6c8b: +case 0x6c8c: +case 0x6c8d: +case 0x6c8e: +case 0x6c8f: +case 0x6c90: +case 0x6c91: +case 0x6c92: +case 0x6c93: +case 0x6c94: +case 0x6c95: +case 0x6c96: +case 0x6c97: +case 0x6c98: +case 0x6c99: +case 0x6c9a: +case 0x6c9b: +case 0x6c9c: +case 0x6c9d: +case 0x6c9e: +case 0x6c9f: +case 0x6ca0: +case 0x6ca1: +case 0x6ca2: +case 0x6ca3: +case 0x6ca4: +case 0x6ca5: +case 0x6ca6: +case 0x6ca7: +case 0x6ca8: +case 0x6ca9: +case 0x6caa: +case 0x6cab: +case 0x6cac: +case 0x6cad: +case 0x6cae: +case 0x6caf: +case 0x6cb0: +case 0x6cb1: +case 0x6cb2: +case 0x6cb3: +case 0x6cb4: +case 0x6cb5: +case 0x6cb6: +case 0x6cb7: +case 0x6cb8: +case 0x6cb9: +case 0x6cba: +case 0x6cbb: +case 0x6cbc: +case 0x6cbd: +case 0x6cbe: +case 0x6cbf: +case 0x6cc0: +case 0x6cc1: +case 0x6cc2: +case 0x6cc3: +case 0x6cc4: +case 0x6cc5: +case 0x6cc6: +case 0x6cc7: +case 0x6cc8: +case 0x6cc9: +case 0x6cca: +case 0x6ccb: +case 0x6ccc: +case 0x6ccd: +case 0x6cce: +case 0x6ccf: +case 0x6cd0: +case 0x6cd1: +case 0x6cd2: +case 0x6cd3: +case 0x6cd4: +case 0x6cd5: +case 0x6cd6: +case 0x6cd7: +case 0x6cd8: +case 0x6cd9: +case 0x6cda: +case 0x6cdb: +case 0x6cdc: +case 0x6cdd: +case 0x6cde: +case 0x6cdf: +case 0x6ce0: +case 0x6ce1: +case 0x6ce2: +case 0x6ce3: +case 0x6ce4: +case 0x6ce5: +case 0x6ce6: +case 0x6ce7: +case 0x6ce8: +case 0x6ce9: +case 0x6cea: +case 0x6ceb: +case 0x6cec: +case 0x6ced: +case 0x6cee: +case 0x6cef: +case 0x6cf0: +case 0x6cf1: +case 0x6cf2: +case 0x6cf3: +case 0x6cf4: +case 0x6cf5: +case 0x6cf6: +case 0x6cf7: +case 0x6cf8: +case 0x6cf9: +case 0x6cfa: +case 0x6cfb: +case 0x6cfc: +case 0x6cfd: +case 0x6cfe: +case 0x6cff: + { + Bxx<0x0c>((int8)instr); + } + break; + +case 0x6d00: +case 0x6d01: +case 0x6d02: +case 0x6d03: +case 0x6d04: +case 0x6d05: +case 0x6d06: +case 0x6d07: +case 0x6d08: +case 0x6d09: +case 0x6d0a: +case 0x6d0b: +case 0x6d0c: +case 0x6d0d: +case 0x6d0e: +case 0x6d0f: +case 0x6d10: +case 0x6d11: +case 0x6d12: +case 0x6d13: +case 0x6d14: +case 0x6d15: +case 0x6d16: +case 0x6d17: +case 0x6d18: +case 0x6d19: +case 0x6d1a: +case 0x6d1b: +case 0x6d1c: +case 0x6d1d: +case 0x6d1e: +case 0x6d1f: +case 0x6d20: +case 0x6d21: +case 0x6d22: +case 0x6d23: +case 0x6d24: +case 0x6d25: +case 0x6d26: +case 0x6d27: +case 0x6d28: +case 0x6d29: +case 0x6d2a: +case 0x6d2b: +case 0x6d2c: +case 0x6d2d: +case 0x6d2e: +case 0x6d2f: +case 0x6d30: +case 0x6d31: +case 0x6d32: +case 0x6d33: +case 0x6d34: +case 0x6d35: +case 0x6d36: +case 0x6d37: +case 0x6d38: +case 0x6d39: +case 0x6d3a: +case 0x6d3b: +case 0x6d3c: +case 0x6d3d: +case 0x6d3e: +case 0x6d3f: +case 0x6d40: +case 0x6d41: +case 0x6d42: +case 0x6d43: +case 0x6d44: +case 0x6d45: +case 0x6d46: +case 0x6d47: +case 0x6d48: +case 0x6d49: +case 0x6d4a: +case 0x6d4b: +case 0x6d4c: +case 0x6d4d: +case 0x6d4e: +case 0x6d4f: +case 0x6d50: +case 0x6d51: +case 0x6d52: +case 0x6d53: +case 0x6d54: +case 0x6d55: +case 0x6d56: +case 0x6d57: +case 0x6d58: +case 0x6d59: +case 0x6d5a: +case 0x6d5b: +case 0x6d5c: +case 0x6d5d: +case 0x6d5e: +case 0x6d5f: +case 0x6d60: +case 0x6d61: +case 0x6d62: +case 0x6d63: +case 0x6d64: +case 0x6d65: +case 0x6d66: +case 0x6d67: +case 0x6d68: +case 0x6d69: +case 0x6d6a: +case 0x6d6b: +case 0x6d6c: +case 0x6d6d: +case 0x6d6e: +case 0x6d6f: +case 0x6d70: +case 0x6d71: +case 0x6d72: +case 0x6d73: +case 0x6d74: +case 0x6d75: +case 0x6d76: +case 0x6d77: +case 0x6d78: +case 0x6d79: +case 0x6d7a: +case 0x6d7b: +case 0x6d7c: +case 0x6d7d: +case 0x6d7e: +case 0x6d7f: +case 0x6d80: +case 0x6d81: +case 0x6d82: +case 0x6d83: +case 0x6d84: +case 0x6d85: +case 0x6d86: +case 0x6d87: +case 0x6d88: +case 0x6d89: +case 0x6d8a: +case 0x6d8b: +case 0x6d8c: +case 0x6d8d: +case 0x6d8e: +case 0x6d8f: +case 0x6d90: +case 0x6d91: +case 0x6d92: +case 0x6d93: +case 0x6d94: +case 0x6d95: +case 0x6d96: +case 0x6d97: +case 0x6d98: +case 0x6d99: +case 0x6d9a: +case 0x6d9b: +case 0x6d9c: +case 0x6d9d: +case 0x6d9e: +case 0x6d9f: +case 0x6da0: +case 0x6da1: +case 0x6da2: +case 0x6da3: +case 0x6da4: +case 0x6da5: +case 0x6da6: +case 0x6da7: +case 0x6da8: +case 0x6da9: +case 0x6daa: +case 0x6dab: +case 0x6dac: +case 0x6dad: +case 0x6dae: +case 0x6daf: +case 0x6db0: +case 0x6db1: +case 0x6db2: +case 0x6db3: +case 0x6db4: +case 0x6db5: +case 0x6db6: +case 0x6db7: +case 0x6db8: +case 0x6db9: +case 0x6dba: +case 0x6dbb: +case 0x6dbc: +case 0x6dbd: +case 0x6dbe: +case 0x6dbf: +case 0x6dc0: +case 0x6dc1: +case 0x6dc2: +case 0x6dc3: +case 0x6dc4: +case 0x6dc5: +case 0x6dc6: +case 0x6dc7: +case 0x6dc8: +case 0x6dc9: +case 0x6dca: +case 0x6dcb: +case 0x6dcc: +case 0x6dcd: +case 0x6dce: +case 0x6dcf: +case 0x6dd0: +case 0x6dd1: +case 0x6dd2: +case 0x6dd3: +case 0x6dd4: +case 0x6dd5: +case 0x6dd6: +case 0x6dd7: +case 0x6dd8: +case 0x6dd9: +case 0x6dda: +case 0x6ddb: +case 0x6ddc: +case 0x6ddd: +case 0x6dde: +case 0x6ddf: +case 0x6de0: +case 0x6de1: +case 0x6de2: +case 0x6de3: +case 0x6de4: +case 0x6de5: +case 0x6de6: +case 0x6de7: +case 0x6de8: +case 0x6de9: +case 0x6dea: +case 0x6deb: +case 0x6dec: +case 0x6ded: +case 0x6dee: +case 0x6def: +case 0x6df0: +case 0x6df1: +case 0x6df2: +case 0x6df3: +case 0x6df4: +case 0x6df5: +case 0x6df6: +case 0x6df7: +case 0x6df8: +case 0x6df9: +case 0x6dfa: +case 0x6dfb: +case 0x6dfc: +case 0x6dfd: +case 0x6dfe: +case 0x6dff: + { + Bxx<0x0d>((int8)instr); + } + break; + +case 0x6e00: +case 0x6e01: +case 0x6e02: +case 0x6e03: +case 0x6e04: +case 0x6e05: +case 0x6e06: +case 0x6e07: +case 0x6e08: +case 0x6e09: +case 0x6e0a: +case 0x6e0b: +case 0x6e0c: +case 0x6e0d: +case 0x6e0e: +case 0x6e0f: +case 0x6e10: +case 0x6e11: +case 0x6e12: +case 0x6e13: +case 0x6e14: +case 0x6e15: +case 0x6e16: +case 0x6e17: +case 0x6e18: +case 0x6e19: +case 0x6e1a: +case 0x6e1b: +case 0x6e1c: +case 0x6e1d: +case 0x6e1e: +case 0x6e1f: +case 0x6e20: +case 0x6e21: +case 0x6e22: +case 0x6e23: +case 0x6e24: +case 0x6e25: +case 0x6e26: +case 0x6e27: +case 0x6e28: +case 0x6e29: +case 0x6e2a: +case 0x6e2b: +case 0x6e2c: +case 0x6e2d: +case 0x6e2e: +case 0x6e2f: +case 0x6e30: +case 0x6e31: +case 0x6e32: +case 0x6e33: +case 0x6e34: +case 0x6e35: +case 0x6e36: +case 0x6e37: +case 0x6e38: +case 0x6e39: +case 0x6e3a: +case 0x6e3b: +case 0x6e3c: +case 0x6e3d: +case 0x6e3e: +case 0x6e3f: +case 0x6e40: +case 0x6e41: +case 0x6e42: +case 0x6e43: +case 0x6e44: +case 0x6e45: +case 0x6e46: +case 0x6e47: +case 0x6e48: +case 0x6e49: +case 0x6e4a: +case 0x6e4b: +case 0x6e4c: +case 0x6e4d: +case 0x6e4e: +case 0x6e4f: +case 0x6e50: +case 0x6e51: +case 0x6e52: +case 0x6e53: +case 0x6e54: +case 0x6e55: +case 0x6e56: +case 0x6e57: +case 0x6e58: +case 0x6e59: +case 0x6e5a: +case 0x6e5b: +case 0x6e5c: +case 0x6e5d: +case 0x6e5e: +case 0x6e5f: +case 0x6e60: +case 0x6e61: +case 0x6e62: +case 0x6e63: +case 0x6e64: +case 0x6e65: +case 0x6e66: +case 0x6e67: +case 0x6e68: +case 0x6e69: +case 0x6e6a: +case 0x6e6b: +case 0x6e6c: +case 0x6e6d: +case 0x6e6e: +case 0x6e6f: +case 0x6e70: +case 0x6e71: +case 0x6e72: +case 0x6e73: +case 0x6e74: +case 0x6e75: +case 0x6e76: +case 0x6e77: +case 0x6e78: +case 0x6e79: +case 0x6e7a: +case 0x6e7b: +case 0x6e7c: +case 0x6e7d: +case 0x6e7e: +case 0x6e7f: +case 0x6e80: +case 0x6e81: +case 0x6e82: +case 0x6e83: +case 0x6e84: +case 0x6e85: +case 0x6e86: +case 0x6e87: +case 0x6e88: +case 0x6e89: +case 0x6e8a: +case 0x6e8b: +case 0x6e8c: +case 0x6e8d: +case 0x6e8e: +case 0x6e8f: +case 0x6e90: +case 0x6e91: +case 0x6e92: +case 0x6e93: +case 0x6e94: +case 0x6e95: +case 0x6e96: +case 0x6e97: +case 0x6e98: +case 0x6e99: +case 0x6e9a: +case 0x6e9b: +case 0x6e9c: +case 0x6e9d: +case 0x6e9e: +case 0x6e9f: +case 0x6ea0: +case 0x6ea1: +case 0x6ea2: +case 0x6ea3: +case 0x6ea4: +case 0x6ea5: +case 0x6ea6: +case 0x6ea7: +case 0x6ea8: +case 0x6ea9: +case 0x6eaa: +case 0x6eab: +case 0x6eac: +case 0x6ead: +case 0x6eae: +case 0x6eaf: +case 0x6eb0: +case 0x6eb1: +case 0x6eb2: +case 0x6eb3: +case 0x6eb4: +case 0x6eb5: +case 0x6eb6: +case 0x6eb7: +case 0x6eb8: +case 0x6eb9: +case 0x6eba: +case 0x6ebb: +case 0x6ebc: +case 0x6ebd: +case 0x6ebe: +case 0x6ebf: +case 0x6ec0: +case 0x6ec1: +case 0x6ec2: +case 0x6ec3: +case 0x6ec4: +case 0x6ec5: +case 0x6ec6: +case 0x6ec7: +case 0x6ec8: +case 0x6ec9: +case 0x6eca: +case 0x6ecb: +case 0x6ecc: +case 0x6ecd: +case 0x6ece: +case 0x6ecf: +case 0x6ed0: +case 0x6ed1: +case 0x6ed2: +case 0x6ed3: +case 0x6ed4: +case 0x6ed5: +case 0x6ed6: +case 0x6ed7: +case 0x6ed8: +case 0x6ed9: +case 0x6eda: +case 0x6edb: +case 0x6edc: +case 0x6edd: +case 0x6ede: +case 0x6edf: +case 0x6ee0: +case 0x6ee1: +case 0x6ee2: +case 0x6ee3: +case 0x6ee4: +case 0x6ee5: +case 0x6ee6: +case 0x6ee7: +case 0x6ee8: +case 0x6ee9: +case 0x6eea: +case 0x6eeb: +case 0x6eec: +case 0x6eed: +case 0x6eee: +case 0x6eef: +case 0x6ef0: +case 0x6ef1: +case 0x6ef2: +case 0x6ef3: +case 0x6ef4: +case 0x6ef5: +case 0x6ef6: +case 0x6ef7: +case 0x6ef8: +case 0x6ef9: +case 0x6efa: +case 0x6efb: +case 0x6efc: +case 0x6efd: +case 0x6efe: +case 0x6eff: + { + Bxx<0x0e>((int8)instr); + } + break; + +case 0x6f00: +case 0x6f01: +case 0x6f02: +case 0x6f03: +case 0x6f04: +case 0x6f05: +case 0x6f06: +case 0x6f07: +case 0x6f08: +case 0x6f09: +case 0x6f0a: +case 0x6f0b: +case 0x6f0c: +case 0x6f0d: +case 0x6f0e: +case 0x6f0f: +case 0x6f10: +case 0x6f11: +case 0x6f12: +case 0x6f13: +case 0x6f14: +case 0x6f15: +case 0x6f16: +case 0x6f17: +case 0x6f18: +case 0x6f19: +case 0x6f1a: +case 0x6f1b: +case 0x6f1c: +case 0x6f1d: +case 0x6f1e: +case 0x6f1f: +case 0x6f20: +case 0x6f21: +case 0x6f22: +case 0x6f23: +case 0x6f24: +case 0x6f25: +case 0x6f26: +case 0x6f27: +case 0x6f28: +case 0x6f29: +case 0x6f2a: +case 0x6f2b: +case 0x6f2c: +case 0x6f2d: +case 0x6f2e: +case 0x6f2f: +case 0x6f30: +case 0x6f31: +case 0x6f32: +case 0x6f33: +case 0x6f34: +case 0x6f35: +case 0x6f36: +case 0x6f37: +case 0x6f38: +case 0x6f39: +case 0x6f3a: +case 0x6f3b: +case 0x6f3c: +case 0x6f3d: +case 0x6f3e: +case 0x6f3f: +case 0x6f40: +case 0x6f41: +case 0x6f42: +case 0x6f43: +case 0x6f44: +case 0x6f45: +case 0x6f46: +case 0x6f47: +case 0x6f48: +case 0x6f49: +case 0x6f4a: +case 0x6f4b: +case 0x6f4c: +case 0x6f4d: +case 0x6f4e: +case 0x6f4f: +case 0x6f50: +case 0x6f51: +case 0x6f52: +case 0x6f53: +case 0x6f54: +case 0x6f55: +case 0x6f56: +case 0x6f57: +case 0x6f58: +case 0x6f59: +case 0x6f5a: +case 0x6f5b: +case 0x6f5c: +case 0x6f5d: +case 0x6f5e: +case 0x6f5f: +case 0x6f60: +case 0x6f61: +case 0x6f62: +case 0x6f63: +case 0x6f64: +case 0x6f65: +case 0x6f66: +case 0x6f67: +case 0x6f68: +case 0x6f69: +case 0x6f6a: +case 0x6f6b: +case 0x6f6c: +case 0x6f6d: +case 0x6f6e: +case 0x6f6f: +case 0x6f70: +case 0x6f71: +case 0x6f72: +case 0x6f73: +case 0x6f74: +case 0x6f75: +case 0x6f76: +case 0x6f77: +case 0x6f78: +case 0x6f79: +case 0x6f7a: +case 0x6f7b: +case 0x6f7c: +case 0x6f7d: +case 0x6f7e: +case 0x6f7f: +case 0x6f80: +case 0x6f81: +case 0x6f82: +case 0x6f83: +case 0x6f84: +case 0x6f85: +case 0x6f86: +case 0x6f87: +case 0x6f88: +case 0x6f89: +case 0x6f8a: +case 0x6f8b: +case 0x6f8c: +case 0x6f8d: +case 0x6f8e: +case 0x6f8f: +case 0x6f90: +case 0x6f91: +case 0x6f92: +case 0x6f93: +case 0x6f94: +case 0x6f95: +case 0x6f96: +case 0x6f97: +case 0x6f98: +case 0x6f99: +case 0x6f9a: +case 0x6f9b: +case 0x6f9c: +case 0x6f9d: +case 0x6f9e: +case 0x6f9f: +case 0x6fa0: +case 0x6fa1: +case 0x6fa2: +case 0x6fa3: +case 0x6fa4: +case 0x6fa5: +case 0x6fa6: +case 0x6fa7: +case 0x6fa8: +case 0x6fa9: +case 0x6faa: +case 0x6fab: +case 0x6fac: +case 0x6fad: +case 0x6fae: +case 0x6faf: +case 0x6fb0: +case 0x6fb1: +case 0x6fb2: +case 0x6fb3: +case 0x6fb4: +case 0x6fb5: +case 0x6fb6: +case 0x6fb7: +case 0x6fb8: +case 0x6fb9: +case 0x6fba: +case 0x6fbb: +case 0x6fbc: +case 0x6fbd: +case 0x6fbe: +case 0x6fbf: +case 0x6fc0: +case 0x6fc1: +case 0x6fc2: +case 0x6fc3: +case 0x6fc4: +case 0x6fc5: +case 0x6fc6: +case 0x6fc7: +case 0x6fc8: +case 0x6fc9: +case 0x6fca: +case 0x6fcb: +case 0x6fcc: +case 0x6fcd: +case 0x6fce: +case 0x6fcf: +case 0x6fd0: +case 0x6fd1: +case 0x6fd2: +case 0x6fd3: +case 0x6fd4: +case 0x6fd5: +case 0x6fd6: +case 0x6fd7: +case 0x6fd8: +case 0x6fd9: +case 0x6fda: +case 0x6fdb: +case 0x6fdc: +case 0x6fdd: +case 0x6fde: +case 0x6fdf: +case 0x6fe0: +case 0x6fe1: +case 0x6fe2: +case 0x6fe3: +case 0x6fe4: +case 0x6fe5: +case 0x6fe6: +case 0x6fe7: +case 0x6fe8: +case 0x6fe9: +case 0x6fea: +case 0x6feb: +case 0x6fec: +case 0x6fed: +case 0x6fee: +case 0x6fef: +case 0x6ff0: +case 0x6ff1: +case 0x6ff2: +case 0x6ff3: +case 0x6ff4: +case 0x6ff5: +case 0x6ff6: +case 0x6ff7: +case 0x6ff8: +case 0x6ff9: +case 0x6ffa: +case 0x6ffb: +case 0x6ffc: +case 0x6ffd: +case 0x6ffe: +case 0x6fff: + { + Bxx<0x0f>((int8)instr); + } + break; + +case 0x50c8: +case 0x50c9: +case 0x50ca: +case 0x50cb: +case 0x50cc: +case 0x50cd: +case 0x50ce: +case 0x50cf: + { + DBcc<0x00>(instr_b2_b0); + } + break; + +case 0x51c8: +case 0x51c9: +case 0x51ca: +case 0x51cb: +case 0x51cc: +case 0x51cd: +case 0x51ce: +case 0x51cf: + { + DBcc<0x01>(instr_b2_b0); + } + break; + +case 0x52c8: +case 0x52c9: +case 0x52ca: +case 0x52cb: +case 0x52cc: +case 0x52cd: +case 0x52ce: +case 0x52cf: + { + DBcc<0x02>(instr_b2_b0); + } + break; + +case 0x53c8: +case 0x53c9: +case 0x53ca: +case 0x53cb: +case 0x53cc: +case 0x53cd: +case 0x53ce: +case 0x53cf: + { + DBcc<0x03>(instr_b2_b0); + } + break; + +case 0x54c8: +case 0x54c9: +case 0x54ca: +case 0x54cb: +case 0x54cc: +case 0x54cd: +case 0x54ce: +case 0x54cf: + { + DBcc<0x04>(instr_b2_b0); + } + break; + +case 0x55c8: +case 0x55c9: +case 0x55ca: +case 0x55cb: +case 0x55cc: +case 0x55cd: +case 0x55ce: +case 0x55cf: + { + DBcc<0x05>(instr_b2_b0); + } + break; + +case 0x56c8: +case 0x56c9: +case 0x56ca: +case 0x56cb: +case 0x56cc: +case 0x56cd: +case 0x56ce: +case 0x56cf: + { + DBcc<0x06>(instr_b2_b0); + } + break; + +case 0x57c8: +case 0x57c9: +case 0x57ca: +case 0x57cb: +case 0x57cc: +case 0x57cd: +case 0x57ce: +case 0x57cf: + { + DBcc<0x07>(instr_b2_b0); + } + break; + +case 0x58c8: +case 0x58c9: +case 0x58ca: +case 0x58cb: +case 0x58cc: +case 0x58cd: +case 0x58ce: +case 0x58cf: + { + DBcc<0x08>(instr_b2_b0); + } + break; + +case 0x59c8: +case 0x59c9: +case 0x59ca: +case 0x59cb: +case 0x59cc: +case 0x59cd: +case 0x59ce: +case 0x59cf: + { + DBcc<0x09>(instr_b2_b0); + } + break; + +case 0x5ac8: +case 0x5ac9: +case 0x5aca: +case 0x5acb: +case 0x5acc: +case 0x5acd: +case 0x5ace: +case 0x5acf: + { + DBcc<0x0a>(instr_b2_b0); + } + break; + +case 0x5bc8: +case 0x5bc9: +case 0x5bca: +case 0x5bcb: +case 0x5bcc: +case 0x5bcd: +case 0x5bce: +case 0x5bcf: + { + DBcc<0x0b>(instr_b2_b0); + } + break; + +case 0x5cc8: +case 0x5cc9: +case 0x5cca: +case 0x5ccb: +case 0x5ccc: +case 0x5ccd: +case 0x5cce: +case 0x5ccf: + { + DBcc<0x0c>(instr_b2_b0); + } + break; + +case 0x5dc8: +case 0x5dc9: +case 0x5dca: +case 0x5dcb: +case 0x5dcc: +case 0x5dcd: +case 0x5dce: +case 0x5dcf: + { + DBcc<0x0d>(instr_b2_b0); + } + break; + +case 0x5ec8: +case 0x5ec9: +case 0x5eca: +case 0x5ecb: +case 0x5ecc: +case 0x5ecd: +case 0x5ece: +case 0x5ecf: + { + DBcc<0x0e>(instr_b2_b0); + } + break; + +case 0x5fc8: +case 0x5fc9: +case 0x5fca: +case 0x5fcb: +case 0x5fcc: +case 0x5fcd: +case 0x5fce: +case 0x5fcf: + { + DBcc<0x0f>(instr_b2_b0); + } + break; + +case 0x0a3c: + { + EORI_CCR(); + } + break; + +case 0xc148: +case 0xc149: +case 0xc14a: +case 0xc14b: +case 0xc14c: +case 0xc14d: +case 0xc14e: +case 0xc14f: +case 0xc348: +case 0xc349: +case 0xc34a: +case 0xc34b: +case 0xc34c: +case 0xc34d: +case 0xc34e: +case 0xc34f: +case 0xc548: +case 0xc549: +case 0xc54a: +case 0xc54b: +case 0xc54c: +case 0xc54d: +case 0xc54e: +case 0xc54f: +case 0xc748: +case 0xc749: +case 0xc74a: +case 0xc74b: +case 0xc74c: +case 0xc74d: +case 0xc74e: +case 0xc74f: +case 0xc948: +case 0xc949: +case 0xc94a: +case 0xc94b: +case 0xc94c: +case 0xc94d: +case 0xc94e: +case 0xc94f: +case 0xcb48: +case 0xcb49: +case 0xcb4a: +case 0xcb4b: +case 0xcb4c: +case 0xcb4d: +case 0xcb4e: +case 0xcb4f: +case 0xcd48: +case 0xcd49: +case 0xcd4a: +case 0xcd4b: +case 0xcd4c: +case 0xcd4d: +case 0xcd4e: +case 0xcd4f: +case 0xcf48: +case 0xcf49: +case 0xcf4a: +case 0xcf4b: +case 0xcf4c: +case 0xcf4d: +case 0xcf4e: +case 0xcf4f: + { + EXG(&A[instr_b11_b9], &A[instr_b2_b0]); /* EXG Ax, Ay */ + } + break; + +case 0xc188: +case 0xc189: +case 0xc18a: +case 0xc18b: +case 0xc18c: +case 0xc18d: +case 0xc18e: +case 0xc18f: +case 0xc388: +case 0xc389: +case 0xc38a: +case 0xc38b: +case 0xc38c: +case 0xc38d: +case 0xc38e: +case 0xc38f: +case 0xc588: +case 0xc589: +case 0xc58a: +case 0xc58b: +case 0xc58c: +case 0xc58d: +case 0xc58e: +case 0xc58f: +case 0xc788: +case 0xc789: +case 0xc78a: +case 0xc78b: +case 0xc78c: +case 0xc78d: +case 0xc78e: +case 0xc78f: +case 0xc988: +case 0xc989: +case 0xc98a: +case 0xc98b: +case 0xc98c: +case 0xc98d: +case 0xc98e: +case 0xc98f: +case 0xcb88: +case 0xcb89: +case 0xcb8a: +case 0xcb8b: +case 0xcb8c: +case 0xcb8d: +case 0xcb8e: +case 0xcb8f: +case 0xcd88: +case 0xcd89: +case 0xcd8a: +case 0xcd8b: +case 0xcd8c: +case 0xcd8d: +case 0xcd8e: +case 0xcd8f: +case 0xcf88: +case 0xcf89: +case 0xcf8a: +case 0xcf8b: +case 0xcf8c: +case 0xcf8d: +case 0xcf8e: +case 0xcf8f: + { + EXG(&D[instr_b11_b9], &A[instr_b2_b0]); /* EXG Dx, Ay */ + } + break; + +case 0xc140: +case 0xc141: +case 0xc142: +case 0xc143: +case 0xc144: +case 0xc145: +case 0xc146: +case 0xc147: +case 0xc340: +case 0xc341: +case 0xc342: +case 0xc343: +case 0xc344: +case 0xc345: +case 0xc346: +case 0xc347: +case 0xc540: +case 0xc541: +case 0xc542: +case 0xc543: +case 0xc544: +case 0xc545: +case 0xc546: +case 0xc547: +case 0xc740: +case 0xc741: +case 0xc742: +case 0xc743: +case 0xc744: +case 0xc745: +case 0xc746: +case 0xc747: +case 0xc940: +case 0xc941: +case 0xc942: +case 0xc943: +case 0xc944: +case 0xc945: +case 0xc946: +case 0xc947: +case 0xcb40: +case 0xcb41: +case 0xcb42: +case 0xcb43: +case 0xcb44: +case 0xcb45: +case 0xcb46: +case 0xcb47: +case 0xcd40: +case 0xcd41: +case 0xcd42: +case 0xcd43: +case 0xcd44: +case 0xcd45: +case 0xcd46: +case 0xcd47: +case 0xcf40: +case 0xcf41: +case 0xcf42: +case 0xcf43: +case 0xcf44: +case 0xcf45: +case 0xcf46: +case 0xcf47: + { + EXG(&D[instr_b11_b9], &D[instr_b2_b0]); /* EXG Dx, Dy */ + } + break; + +case 0x41f9: +case 0x43f9: +case 0x45f9: +case 0x47f9: +case 0x49f9: +case 0x4bf9: +case 0x4df9: +case 0x4ff9: + { + HAM, ABS_LONG> src(this); LEA(src, instr_b11_b9); + } + break; + +case 0x4879: + { + HAM, ABS_LONG> src(this); PEA(src); + } + break; + +case 0x4ef9: + { + HAM, ABS_LONG> targ(this); JMP(targ); + } + break; + +case 0x4eb9: + { + HAM, ABS_LONG> targ(this); JSR(targ); + } + break; + +case 0x41f8: +case 0x43f8: +case 0x45f8: +case 0x47f8: +case 0x49f8: +case 0x4bf8: +case 0x4df8: +case 0x4ff8: + { + HAM, ABS_SHORT> src(this); LEA(src, instr_b11_b9); + } + break; + +case 0x4878: + { + HAM, ABS_SHORT> src(this); PEA(src); + } + break; + +case 0x4ef8: + { + HAM, ABS_SHORT> targ(this); JMP(targ); + } + break; + +case 0x4eb8: + { + HAM, ABS_SHORT> targ(this); JSR(targ); + } + break; + +case 0x41d0: +case 0x41d1: +case 0x41d2: +case 0x41d3: +case 0x41d4: +case 0x41d5: +case 0x41d6: +case 0x41d7: +case 0x43d0: +case 0x43d1: +case 0x43d2: +case 0x43d3: +case 0x43d4: +case 0x43d5: +case 0x43d6: +case 0x43d7: +case 0x45d0: +case 0x45d1: +case 0x45d2: +case 0x45d3: +case 0x45d4: +case 0x45d5: +case 0x45d6: +case 0x45d7: +case 0x47d0: +case 0x47d1: +case 0x47d2: +case 0x47d3: +case 0x47d4: +case 0x47d5: +case 0x47d6: +case 0x47d7: +case 0x49d0: +case 0x49d1: +case 0x49d2: +case 0x49d3: +case 0x49d4: +case 0x49d5: +case 0x49d6: +case 0x49d7: +case 0x4bd0: +case 0x4bd1: +case 0x4bd2: +case 0x4bd3: +case 0x4bd4: +case 0x4bd5: +case 0x4bd6: +case 0x4bd7: +case 0x4dd0: +case 0x4dd1: +case 0x4dd2: +case 0x4dd3: +case 0x4dd4: +case 0x4dd5: +case 0x4dd6: +case 0x4dd7: +case 0x4fd0: +case 0x4fd1: +case 0x4fd2: +case 0x4fd3: +case 0x4fd4: +case 0x4fd5: +case 0x4fd6: +case 0x4fd7: + { + HAM, ADDR_REG_INDIR> src(this, instr_b2_b0); LEA(src, instr_b11_b9); + } + break; + +case 0x4850: +case 0x4851: +case 0x4852: +case 0x4853: +case 0x4854: +case 0x4855: +case 0x4856: +case 0x4857: + { + HAM, ADDR_REG_INDIR> src(this, instr_b2_b0); PEA(src); + } + break; + +case 0x4ed0: +case 0x4ed1: +case 0x4ed2: +case 0x4ed3: +case 0x4ed4: +case 0x4ed5: +case 0x4ed6: +case 0x4ed7: + { + HAM, ADDR_REG_INDIR> targ(this, instr_b2_b0); JMP(targ); + } + break; + +case 0x4e90: +case 0x4e91: +case 0x4e92: +case 0x4e93: +case 0x4e94: +case 0x4e95: +case 0x4e96: +case 0x4e97: + { + HAM, ADDR_REG_INDIR> targ(this, instr_b2_b0); JSR(targ); + } + break; + +case 0x41e8: +case 0x41e9: +case 0x41ea: +case 0x41eb: +case 0x41ec: +case 0x41ed: +case 0x41ee: +case 0x41ef: +case 0x43e8: +case 0x43e9: +case 0x43ea: +case 0x43eb: +case 0x43ec: +case 0x43ed: +case 0x43ee: +case 0x43ef: +case 0x45e8: +case 0x45e9: +case 0x45ea: +case 0x45eb: +case 0x45ec: +case 0x45ed: +case 0x45ee: +case 0x45ef: +case 0x47e8: +case 0x47e9: +case 0x47ea: +case 0x47eb: +case 0x47ec: +case 0x47ed: +case 0x47ee: +case 0x47ef: +case 0x49e8: +case 0x49e9: +case 0x49ea: +case 0x49eb: +case 0x49ec: +case 0x49ed: +case 0x49ee: +case 0x49ef: +case 0x4be8: +case 0x4be9: +case 0x4bea: +case 0x4beb: +case 0x4bec: +case 0x4bed: +case 0x4bee: +case 0x4bef: +case 0x4de8: +case 0x4de9: +case 0x4dea: +case 0x4deb: +case 0x4dec: +case 0x4ded: +case 0x4dee: +case 0x4def: +case 0x4fe8: +case 0x4fe9: +case 0x4fea: +case 0x4feb: +case 0x4fec: +case 0x4fed: +case 0x4fee: +case 0x4fef: + { + HAM, ADDR_REG_INDIR_DISP> src(this, instr_b2_b0); LEA(src, instr_b11_b9); + } + break; + +case 0x4868: +case 0x4869: +case 0x486a: +case 0x486b: +case 0x486c: +case 0x486d: +case 0x486e: +case 0x486f: + { + HAM, ADDR_REG_INDIR_DISP> src(this, instr_b2_b0); PEA(src); + } + break; + +case 0x4ee8: +case 0x4ee9: +case 0x4eea: +case 0x4eeb: +case 0x4eec: +case 0x4eed: +case 0x4eee: +case 0x4eef: + { + HAM, ADDR_REG_INDIR_DISP> targ(this, instr_b2_b0); JMP(targ); + } + break; + +case 0x4ea8: +case 0x4ea9: +case 0x4eaa: +case 0x4eab: +case 0x4eac: +case 0x4ead: +case 0x4eae: +case 0x4eaf: + { + HAM, ADDR_REG_INDIR_DISP> targ(this, instr_b2_b0); JSR(targ); + } + break; + +case 0x41f0: +case 0x41f1: +case 0x41f2: +case 0x41f3: +case 0x41f4: +case 0x41f5: +case 0x41f6: +case 0x41f7: +case 0x43f0: +case 0x43f1: +case 0x43f2: +case 0x43f3: +case 0x43f4: +case 0x43f5: +case 0x43f6: +case 0x43f7: +case 0x45f0: +case 0x45f1: +case 0x45f2: +case 0x45f3: +case 0x45f4: +case 0x45f5: +case 0x45f6: +case 0x45f7: +case 0x47f0: +case 0x47f1: +case 0x47f2: +case 0x47f3: +case 0x47f4: +case 0x47f5: +case 0x47f6: +case 0x47f7: +case 0x49f0: +case 0x49f1: +case 0x49f2: +case 0x49f3: +case 0x49f4: +case 0x49f5: +case 0x49f6: +case 0x49f7: +case 0x4bf0: +case 0x4bf1: +case 0x4bf2: +case 0x4bf3: +case 0x4bf4: +case 0x4bf5: +case 0x4bf6: +case 0x4bf7: +case 0x4df0: +case 0x4df1: +case 0x4df2: +case 0x4df3: +case 0x4df4: +case 0x4df5: +case 0x4df6: +case 0x4df7: +case 0x4ff0: +case 0x4ff1: +case 0x4ff2: +case 0x4ff3: +case 0x4ff4: +case 0x4ff5: +case 0x4ff6: +case 0x4ff7: + { + HAM, ADDR_REG_INDIR_INDX> src(this, instr_b2_b0); LEA(src, instr_b11_b9); + } + break; + +case 0x4870: +case 0x4871: +case 0x4872: +case 0x4873: +case 0x4874: +case 0x4875: +case 0x4876: +case 0x4877: + { + HAM, ADDR_REG_INDIR_INDX> src(this, instr_b2_b0); PEA(src); + } + break; + +case 0x4ef0: +case 0x4ef1: +case 0x4ef2: +case 0x4ef3: +case 0x4ef4: +case 0x4ef5: +case 0x4ef6: +case 0x4ef7: + { + HAM, ADDR_REG_INDIR_INDX> targ(this, instr_b2_b0); JMP(targ); + } + break; + +case 0x4eb0: +case 0x4eb1: +case 0x4eb2: +case 0x4eb3: +case 0x4eb4: +case 0x4eb5: +case 0x4eb6: +case 0x4eb7: + { + HAM, ADDR_REG_INDIR_INDX> targ(this, instr_b2_b0); JSR(targ); + } + break; + +case 0x41fa: +case 0x43fa: +case 0x45fa: +case 0x47fa: +case 0x49fa: +case 0x4bfa: +case 0x4dfa: +case 0x4ffa: + { + HAM, PC_DISP> src(this); LEA(src, instr_b11_b9); + } + break; + +case 0x487a: + { + HAM, PC_DISP> src(this); PEA(src); + } + break; + +case 0x4efa: + { + HAM, PC_DISP> targ(this); JMP(targ); + } + break; + +case 0x4eba: + { + HAM, PC_DISP> targ(this); JSR(targ); + } + break; + +case 0x41fb: +case 0x43fb: +case 0x45fb: +case 0x47fb: +case 0x49fb: +case 0x4bfb: +case 0x4dfb: +case 0x4ffb: + { + HAM, PC_INDEX> src(this); LEA(src, instr_b11_b9); + } + break; + +case 0x487b: + { + HAM, PC_INDEX> src(this); PEA(src); + } + break; + +case 0x4efb: + { + HAM, PC_INDEX> targ(this); JMP(targ); + } + break; + +case 0x4ebb: + { + HAM, PC_INDEX> targ(this); JSR(targ); + } + break; + +case 0x4279: + { + HAM dst(this); CLR(dst); + } + break; + +case 0x4479: + { + HAM dst(this); NEG(dst); + } + break; + +case 0x4079: + { + HAM dst(this); NEGX(dst); + } + break; + +case 0x4679: + { + HAM dst(this); NOT(dst); + } + break; + +case 0x4a79: + { + HAM dst(this); TST(dst); + } + break; + +case 0x81f9: +case 0x83f9: +case 0x85f9: +case 0x87f9: +case 0x89f9: +case 0x8bf9: +case 0x8df9: +case 0x8ff9: + { + HAM src(this); DIVS(src, instr_b11_b9); + } + break; + +case 0x80f9: +case 0x82f9: +case 0x84f9: +case 0x86f9: +case 0x88f9: +case 0x8af9: +case 0x8cf9: +case 0x8ef9: + { + HAM src(this); DIVU(src, instr_b11_b9); + } + break; + +case 0x33f9: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x31f9: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x30b9: +case 0x32b9: +case 0x34b9: +case 0x36b9: +case 0x38b9: +case 0x3ab9: +case 0x3cb9: +case 0x3eb9: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3179: +case 0x3379: +case 0x3579: +case 0x3779: +case 0x3979: +case 0x3b79: +case 0x3d79: +case 0x3f79: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x31b9: +case 0x33b9: +case 0x35b9: +case 0x37b9: +case 0x39b9: +case 0x3bb9: +case 0x3db9: +case 0x3fb9: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x30f9: +case 0x32f9: +case 0x34f9: +case 0x36f9: +case 0x38f9: +case 0x3af9: +case 0x3cf9: +case 0x3ef9: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3139: +case 0x3339: +case 0x3539: +case 0x3739: +case 0x3939: +case 0x3b39: +case 0x3d39: +case 0x3f39: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd079: +case 0xd279: +case 0xd479: +case 0xd679: +case 0xd879: +case 0xda79: +case 0xdc79: +case 0xde79: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc079: +case 0xc279: +case 0xc479: +case 0xc679: +case 0xc879: +case 0xca79: +case 0xcc79: +case 0xce79: + { + HAM src(this); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0x41b9: +case 0x43b9: +case 0x45b9: +case 0x47b9: +case 0x49b9: +case 0x4bb9: +case 0x4db9: +case 0x4fb9: + { + HAM src(this); HAM dst(this, instr_b11_b9); CHK(src, dst); + } + break; + +case 0xb079: +case 0xb279: +case 0xb479: +case 0xb679: +case 0xb879: +case 0xba79: +case 0xbc79: +case 0xbe79: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x3039: +case 0x3239: +case 0x3439: +case 0x3639: +case 0x3839: +case 0x3a39: +case 0x3c39: +case 0x3e39: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8079: +case 0x8279: +case 0x8479: +case 0x8679: +case 0x8879: +case 0x8a79: +case 0x8c79: +case 0x8e79: + { + HAM src(this); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9079: +case 0x9279: +case 0x9479: +case 0x9679: +case 0x9879: +case 0x9a79: +case 0x9c79: +case 0x9e79: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0xd0f9: +case 0xd2f9: +case 0xd4f9: +case 0xd6f9: +case 0xd8f9: +case 0xdaf9: +case 0xdcf9: +case 0xdef9: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb0f9: +case 0xb2f9: +case 0xb4f9: +case 0xb6f9: +case 0xb8f9: +case 0xbaf9: +case 0xbcf9: +case 0xbef9: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x90f9: +case 0x92f9: +case 0x94f9: +case 0x96f9: +case 0x98f9: +case 0x9af9: +case 0x9cf9: +case 0x9ef9: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x3079: +case 0x3279: +case 0x3479: +case 0x3679: +case 0x3879: +case 0x3a79: +case 0x3c79: +case 0x3e79: + { + HAM src(this); MOVEA(src, instr_b11_b9); + } + break; + +case 0x44f9: + { + HAM src(this); MOVE_to_CCR(src); + } + break; + +case 0xc1f9: +case 0xc3f9: +case 0xc5f9: +case 0xc7f9: +case 0xc9f9: +case 0xcbf9: +case 0xcdf9: +case 0xcff9: + { + HAM src(this); MULS(src, instr_b11_b9); + } + break; + +case 0xc0f9: +case 0xc2f9: +case 0xc4f9: +case 0xc6f9: +case 0xc8f9: +case 0xcaf9: +case 0xccf9: +case 0xcef9: + { + HAM src(this); MULU(src, instr_b11_b9); + } + break; + +case 0xe1f9: + { + HAM targ(this); ASL(targ, 1); + } + break; + +case 0xe0f9: + { + HAM targ(this); ASR(targ, 1); + } + break; + +case 0xe3f9: + { + HAM targ(this); LSL(targ, 1); + } + break; + +case 0xe2f9: + { + HAM targ(this); LSR(targ, 1); + } + break; + +case 0xe7f9: + { + HAM targ(this); ROL(targ, 1); + } + break; + +case 0xe6f9: + { + HAM targ(this); ROR(targ, 1); + } + break; + +case 0xe5f9: + { + HAM targ(this); ROXL(targ, 1); + } + break; + +case 0xe4f9: + { + HAM targ(this); ROXR(targ, 1); + } + break; + +case 0x4278: + { + HAM dst(this); CLR(dst); + } + break; + +case 0x4478: + { + HAM dst(this); NEG(dst); + } + break; + +case 0x4078: + { + HAM dst(this); NEGX(dst); + } + break; + +case 0x4678: + { + HAM dst(this); NOT(dst); + } + break; + +case 0x4a78: + { + HAM dst(this); TST(dst); + } + break; + +case 0x81f8: +case 0x83f8: +case 0x85f8: +case 0x87f8: +case 0x89f8: +case 0x8bf8: +case 0x8df8: +case 0x8ff8: + { + HAM src(this); DIVS(src, instr_b11_b9); + } + break; + +case 0x80f8: +case 0x82f8: +case 0x84f8: +case 0x86f8: +case 0x88f8: +case 0x8af8: +case 0x8cf8: +case 0x8ef8: + { + HAM src(this); DIVU(src, instr_b11_b9); + } + break; + +case 0x33f8: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x31f8: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x30b8: +case 0x32b8: +case 0x34b8: +case 0x36b8: +case 0x38b8: +case 0x3ab8: +case 0x3cb8: +case 0x3eb8: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3178: +case 0x3378: +case 0x3578: +case 0x3778: +case 0x3978: +case 0x3b78: +case 0x3d78: +case 0x3f78: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x31b8: +case 0x33b8: +case 0x35b8: +case 0x37b8: +case 0x39b8: +case 0x3bb8: +case 0x3db8: +case 0x3fb8: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x30f8: +case 0x32f8: +case 0x34f8: +case 0x36f8: +case 0x38f8: +case 0x3af8: +case 0x3cf8: +case 0x3ef8: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3138: +case 0x3338: +case 0x3538: +case 0x3738: +case 0x3938: +case 0x3b38: +case 0x3d38: +case 0x3f38: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd078: +case 0xd278: +case 0xd478: +case 0xd678: +case 0xd878: +case 0xda78: +case 0xdc78: +case 0xde78: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc078: +case 0xc278: +case 0xc478: +case 0xc678: +case 0xc878: +case 0xca78: +case 0xcc78: +case 0xce78: + { + HAM src(this); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0x41b8: +case 0x43b8: +case 0x45b8: +case 0x47b8: +case 0x49b8: +case 0x4bb8: +case 0x4db8: +case 0x4fb8: + { + HAM src(this); HAM dst(this, instr_b11_b9); CHK(src, dst); + } + break; + +case 0xb078: +case 0xb278: +case 0xb478: +case 0xb678: +case 0xb878: +case 0xba78: +case 0xbc78: +case 0xbe78: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x3038: +case 0x3238: +case 0x3438: +case 0x3638: +case 0x3838: +case 0x3a38: +case 0x3c38: +case 0x3e38: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8078: +case 0x8278: +case 0x8478: +case 0x8678: +case 0x8878: +case 0x8a78: +case 0x8c78: +case 0x8e78: + { + HAM src(this); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9078: +case 0x9278: +case 0x9478: +case 0x9678: +case 0x9878: +case 0x9a78: +case 0x9c78: +case 0x9e78: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0xd0f8: +case 0xd2f8: +case 0xd4f8: +case 0xd6f8: +case 0xd8f8: +case 0xdaf8: +case 0xdcf8: +case 0xdef8: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb0f8: +case 0xb2f8: +case 0xb4f8: +case 0xb6f8: +case 0xb8f8: +case 0xbaf8: +case 0xbcf8: +case 0xbef8: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x90f8: +case 0x92f8: +case 0x94f8: +case 0x96f8: +case 0x98f8: +case 0x9af8: +case 0x9cf8: +case 0x9ef8: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x3078: +case 0x3278: +case 0x3478: +case 0x3678: +case 0x3878: +case 0x3a78: +case 0x3c78: +case 0x3e78: + { + HAM src(this); MOVEA(src, instr_b11_b9); + } + break; + +case 0x44f8: + { + HAM src(this); MOVE_to_CCR(src); + } + break; + +case 0xc1f8: +case 0xc3f8: +case 0xc5f8: +case 0xc7f8: +case 0xc9f8: +case 0xcbf8: +case 0xcdf8: +case 0xcff8: + { + HAM src(this); MULS(src, instr_b11_b9); + } + break; + +case 0xc0f8: +case 0xc2f8: +case 0xc4f8: +case 0xc6f8: +case 0xc8f8: +case 0xcaf8: +case 0xccf8: +case 0xcef8: + { + HAM src(this); MULU(src, instr_b11_b9); + } + break; + +case 0xe1f8: + { + HAM targ(this); ASL(targ, 1); + } + break; + +case 0xe0f8: + { + HAM targ(this); ASR(targ, 1); + } + break; + +case 0xe3f8: + { + HAM targ(this); LSL(targ, 1); + } + break; + +case 0xe2f8: + { + HAM targ(this); LSR(targ, 1); + } + break; + +case 0xe7f8: + { + HAM targ(this); ROL(targ, 1); + } + break; + +case 0xe6f8: + { + HAM targ(this); ROR(targ, 1); + } + break; + +case 0xe5f8: + { + HAM targ(this); ROXL(targ, 1); + } + break; + +case 0xe4f8: + { + HAM targ(this); ROXR(targ, 1); + } + break; + +case 0x33c8: +case 0x33c9: +case 0x33ca: +case 0x33cb: +case 0x33cc: +case 0x33cd: +case 0x33ce: +case 0x33cf: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x31c8: +case 0x31c9: +case 0x31ca: +case 0x31cb: +case 0x31cc: +case 0x31cd: +case 0x31ce: +case 0x31cf: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x3088: +case 0x3089: +case 0x308a: +case 0x308b: +case 0x308c: +case 0x308d: +case 0x308e: +case 0x308f: +case 0x3288: +case 0x3289: +case 0x328a: +case 0x328b: +case 0x328c: +case 0x328d: +case 0x328e: +case 0x328f: +case 0x3488: +case 0x3489: +case 0x348a: +case 0x348b: +case 0x348c: +case 0x348d: +case 0x348e: +case 0x348f: +case 0x3688: +case 0x3689: +case 0x368a: +case 0x368b: +case 0x368c: +case 0x368d: +case 0x368e: +case 0x368f: +case 0x3888: +case 0x3889: +case 0x388a: +case 0x388b: +case 0x388c: +case 0x388d: +case 0x388e: +case 0x388f: +case 0x3a88: +case 0x3a89: +case 0x3a8a: +case 0x3a8b: +case 0x3a8c: +case 0x3a8d: +case 0x3a8e: +case 0x3a8f: +case 0x3c88: +case 0x3c89: +case 0x3c8a: +case 0x3c8b: +case 0x3c8c: +case 0x3c8d: +case 0x3c8e: +case 0x3c8f: +case 0x3e88: +case 0x3e89: +case 0x3e8a: +case 0x3e8b: +case 0x3e8c: +case 0x3e8d: +case 0x3e8e: +case 0x3e8f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3148: +case 0x3149: +case 0x314a: +case 0x314b: +case 0x314c: +case 0x314d: +case 0x314e: +case 0x314f: +case 0x3348: +case 0x3349: +case 0x334a: +case 0x334b: +case 0x334c: +case 0x334d: +case 0x334e: +case 0x334f: +case 0x3548: +case 0x3549: +case 0x354a: +case 0x354b: +case 0x354c: +case 0x354d: +case 0x354e: +case 0x354f: +case 0x3748: +case 0x3749: +case 0x374a: +case 0x374b: +case 0x374c: +case 0x374d: +case 0x374e: +case 0x374f: +case 0x3948: +case 0x3949: +case 0x394a: +case 0x394b: +case 0x394c: +case 0x394d: +case 0x394e: +case 0x394f: +case 0x3b48: +case 0x3b49: +case 0x3b4a: +case 0x3b4b: +case 0x3b4c: +case 0x3b4d: +case 0x3b4e: +case 0x3b4f: +case 0x3d48: +case 0x3d49: +case 0x3d4a: +case 0x3d4b: +case 0x3d4c: +case 0x3d4d: +case 0x3d4e: +case 0x3d4f: +case 0x3f48: +case 0x3f49: +case 0x3f4a: +case 0x3f4b: +case 0x3f4c: +case 0x3f4d: +case 0x3f4e: +case 0x3f4f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3188: +case 0x3189: +case 0x318a: +case 0x318b: +case 0x318c: +case 0x318d: +case 0x318e: +case 0x318f: +case 0x3388: +case 0x3389: +case 0x338a: +case 0x338b: +case 0x338c: +case 0x338d: +case 0x338e: +case 0x338f: +case 0x3588: +case 0x3589: +case 0x358a: +case 0x358b: +case 0x358c: +case 0x358d: +case 0x358e: +case 0x358f: +case 0x3788: +case 0x3789: +case 0x378a: +case 0x378b: +case 0x378c: +case 0x378d: +case 0x378e: +case 0x378f: +case 0x3988: +case 0x3989: +case 0x398a: +case 0x398b: +case 0x398c: +case 0x398d: +case 0x398e: +case 0x398f: +case 0x3b88: +case 0x3b89: +case 0x3b8a: +case 0x3b8b: +case 0x3b8c: +case 0x3b8d: +case 0x3b8e: +case 0x3b8f: +case 0x3d88: +case 0x3d89: +case 0x3d8a: +case 0x3d8b: +case 0x3d8c: +case 0x3d8d: +case 0x3d8e: +case 0x3d8f: +case 0x3f88: +case 0x3f89: +case 0x3f8a: +case 0x3f8b: +case 0x3f8c: +case 0x3f8d: +case 0x3f8e: +case 0x3f8f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x30c8: +case 0x30c9: +case 0x30ca: +case 0x30cb: +case 0x30cc: +case 0x30cd: +case 0x30ce: +case 0x30cf: +case 0x32c8: +case 0x32c9: +case 0x32ca: +case 0x32cb: +case 0x32cc: +case 0x32cd: +case 0x32ce: +case 0x32cf: +case 0x34c8: +case 0x34c9: +case 0x34ca: +case 0x34cb: +case 0x34cc: +case 0x34cd: +case 0x34ce: +case 0x34cf: +case 0x36c8: +case 0x36c9: +case 0x36ca: +case 0x36cb: +case 0x36cc: +case 0x36cd: +case 0x36ce: +case 0x36cf: +case 0x38c8: +case 0x38c9: +case 0x38ca: +case 0x38cb: +case 0x38cc: +case 0x38cd: +case 0x38ce: +case 0x38cf: +case 0x3ac8: +case 0x3ac9: +case 0x3aca: +case 0x3acb: +case 0x3acc: +case 0x3acd: +case 0x3ace: +case 0x3acf: +case 0x3cc8: +case 0x3cc9: +case 0x3cca: +case 0x3ccb: +case 0x3ccc: +case 0x3ccd: +case 0x3cce: +case 0x3ccf: +case 0x3ec8: +case 0x3ec9: +case 0x3eca: +case 0x3ecb: +case 0x3ecc: +case 0x3ecd: +case 0x3ece: +case 0x3ecf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3108: +case 0x3109: +case 0x310a: +case 0x310b: +case 0x310c: +case 0x310d: +case 0x310e: +case 0x310f: +case 0x3308: +case 0x3309: +case 0x330a: +case 0x330b: +case 0x330c: +case 0x330d: +case 0x330e: +case 0x330f: +case 0x3508: +case 0x3509: +case 0x350a: +case 0x350b: +case 0x350c: +case 0x350d: +case 0x350e: +case 0x350f: +case 0x3708: +case 0x3709: +case 0x370a: +case 0x370b: +case 0x370c: +case 0x370d: +case 0x370e: +case 0x370f: +case 0x3908: +case 0x3909: +case 0x390a: +case 0x390b: +case 0x390c: +case 0x390d: +case 0x390e: +case 0x390f: +case 0x3b08: +case 0x3b09: +case 0x3b0a: +case 0x3b0b: +case 0x3b0c: +case 0x3b0d: +case 0x3b0e: +case 0x3b0f: +case 0x3d08: +case 0x3d09: +case 0x3d0a: +case 0x3d0b: +case 0x3d0c: +case 0x3d0d: +case 0x3d0e: +case 0x3d0f: +case 0x3f08: +case 0x3f09: +case 0x3f0a: +case 0x3f0b: +case 0x3f0c: +case 0x3f0d: +case 0x3f0e: +case 0x3f0f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd048: +case 0xd049: +case 0xd04a: +case 0xd04b: +case 0xd04c: +case 0xd04d: +case 0xd04e: +case 0xd04f: +case 0xd248: +case 0xd249: +case 0xd24a: +case 0xd24b: +case 0xd24c: +case 0xd24d: +case 0xd24e: +case 0xd24f: +case 0xd448: +case 0xd449: +case 0xd44a: +case 0xd44b: +case 0xd44c: +case 0xd44d: +case 0xd44e: +case 0xd44f: +case 0xd648: +case 0xd649: +case 0xd64a: +case 0xd64b: +case 0xd64c: +case 0xd64d: +case 0xd64e: +case 0xd64f: +case 0xd848: +case 0xd849: +case 0xd84a: +case 0xd84b: +case 0xd84c: +case 0xd84d: +case 0xd84e: +case 0xd84f: +case 0xda48: +case 0xda49: +case 0xda4a: +case 0xda4b: +case 0xda4c: +case 0xda4d: +case 0xda4e: +case 0xda4f: +case 0xdc48: +case 0xdc49: +case 0xdc4a: +case 0xdc4b: +case 0xdc4c: +case 0xdc4d: +case 0xdc4e: +case 0xdc4f: +case 0xde48: +case 0xde49: +case 0xde4a: +case 0xde4b: +case 0xde4c: +case 0xde4d: +case 0xde4e: +case 0xde4f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb048: +case 0xb049: +case 0xb04a: +case 0xb04b: +case 0xb04c: +case 0xb04d: +case 0xb04e: +case 0xb04f: +case 0xb248: +case 0xb249: +case 0xb24a: +case 0xb24b: +case 0xb24c: +case 0xb24d: +case 0xb24e: +case 0xb24f: +case 0xb448: +case 0xb449: +case 0xb44a: +case 0xb44b: +case 0xb44c: +case 0xb44d: +case 0xb44e: +case 0xb44f: +case 0xb648: +case 0xb649: +case 0xb64a: +case 0xb64b: +case 0xb64c: +case 0xb64d: +case 0xb64e: +case 0xb64f: +case 0xb848: +case 0xb849: +case 0xb84a: +case 0xb84b: +case 0xb84c: +case 0xb84d: +case 0xb84e: +case 0xb84f: +case 0xba48: +case 0xba49: +case 0xba4a: +case 0xba4b: +case 0xba4c: +case 0xba4d: +case 0xba4e: +case 0xba4f: +case 0xbc48: +case 0xbc49: +case 0xbc4a: +case 0xbc4b: +case 0xbc4c: +case 0xbc4d: +case 0xbc4e: +case 0xbc4f: +case 0xbe48: +case 0xbe49: +case 0xbe4a: +case 0xbe4b: +case 0xbe4c: +case 0xbe4d: +case 0xbe4e: +case 0xbe4f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x3008: +case 0x3009: +case 0x300a: +case 0x300b: +case 0x300c: +case 0x300d: +case 0x300e: +case 0x300f: +case 0x3208: +case 0x3209: +case 0x320a: +case 0x320b: +case 0x320c: +case 0x320d: +case 0x320e: +case 0x320f: +case 0x3408: +case 0x3409: +case 0x340a: +case 0x340b: +case 0x340c: +case 0x340d: +case 0x340e: +case 0x340f: +case 0x3608: +case 0x3609: +case 0x360a: +case 0x360b: +case 0x360c: +case 0x360d: +case 0x360e: +case 0x360f: +case 0x3808: +case 0x3809: +case 0x380a: +case 0x380b: +case 0x380c: +case 0x380d: +case 0x380e: +case 0x380f: +case 0x3a08: +case 0x3a09: +case 0x3a0a: +case 0x3a0b: +case 0x3a0c: +case 0x3a0d: +case 0x3a0e: +case 0x3a0f: +case 0x3c08: +case 0x3c09: +case 0x3c0a: +case 0x3c0b: +case 0x3c0c: +case 0x3c0d: +case 0x3c0e: +case 0x3c0f: +case 0x3e08: +case 0x3e09: +case 0x3e0a: +case 0x3e0b: +case 0x3e0c: +case 0x3e0d: +case 0x3e0e: +case 0x3e0f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x9048: +case 0x9049: +case 0x904a: +case 0x904b: +case 0x904c: +case 0x904d: +case 0x904e: +case 0x904f: +case 0x9248: +case 0x9249: +case 0x924a: +case 0x924b: +case 0x924c: +case 0x924d: +case 0x924e: +case 0x924f: +case 0x9448: +case 0x9449: +case 0x944a: +case 0x944b: +case 0x944c: +case 0x944d: +case 0x944e: +case 0x944f: +case 0x9648: +case 0x9649: +case 0x964a: +case 0x964b: +case 0x964c: +case 0x964d: +case 0x964e: +case 0x964f: +case 0x9848: +case 0x9849: +case 0x984a: +case 0x984b: +case 0x984c: +case 0x984d: +case 0x984e: +case 0x984f: +case 0x9a48: +case 0x9a49: +case 0x9a4a: +case 0x9a4b: +case 0x9a4c: +case 0x9a4d: +case 0x9a4e: +case 0x9a4f: +case 0x9c48: +case 0x9c49: +case 0x9c4a: +case 0x9c4b: +case 0x9c4c: +case 0x9c4d: +case 0x9c4e: +case 0x9c4f: +case 0x9e48: +case 0x9e49: +case 0x9e4a: +case 0x9e4b: +case 0x9e4c: +case 0x9e4d: +case 0x9e4e: +case 0x9e4f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0xd0c8: +case 0xd0c9: +case 0xd0ca: +case 0xd0cb: +case 0xd0cc: +case 0xd0cd: +case 0xd0ce: +case 0xd0cf: +case 0xd2c8: +case 0xd2c9: +case 0xd2ca: +case 0xd2cb: +case 0xd2cc: +case 0xd2cd: +case 0xd2ce: +case 0xd2cf: +case 0xd4c8: +case 0xd4c9: +case 0xd4ca: +case 0xd4cb: +case 0xd4cc: +case 0xd4cd: +case 0xd4ce: +case 0xd4cf: +case 0xd6c8: +case 0xd6c9: +case 0xd6ca: +case 0xd6cb: +case 0xd6cc: +case 0xd6cd: +case 0xd6ce: +case 0xd6cf: +case 0xd8c8: +case 0xd8c9: +case 0xd8ca: +case 0xd8cb: +case 0xd8cc: +case 0xd8cd: +case 0xd8ce: +case 0xd8cf: +case 0xdac8: +case 0xdac9: +case 0xdaca: +case 0xdacb: +case 0xdacc: +case 0xdacd: +case 0xdace: +case 0xdacf: +case 0xdcc8: +case 0xdcc9: +case 0xdcca: +case 0xdccb: +case 0xdccc: +case 0xdccd: +case 0xdcce: +case 0xdccf: +case 0xdec8: +case 0xdec9: +case 0xdeca: +case 0xdecb: +case 0xdecc: +case 0xdecd: +case 0xdece: +case 0xdecf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb0c8: +case 0xb0c9: +case 0xb0ca: +case 0xb0cb: +case 0xb0cc: +case 0xb0cd: +case 0xb0ce: +case 0xb0cf: +case 0xb2c8: +case 0xb2c9: +case 0xb2ca: +case 0xb2cb: +case 0xb2cc: +case 0xb2cd: +case 0xb2ce: +case 0xb2cf: +case 0xb4c8: +case 0xb4c9: +case 0xb4ca: +case 0xb4cb: +case 0xb4cc: +case 0xb4cd: +case 0xb4ce: +case 0xb4cf: +case 0xb6c8: +case 0xb6c9: +case 0xb6ca: +case 0xb6cb: +case 0xb6cc: +case 0xb6cd: +case 0xb6ce: +case 0xb6cf: +case 0xb8c8: +case 0xb8c9: +case 0xb8ca: +case 0xb8cb: +case 0xb8cc: +case 0xb8cd: +case 0xb8ce: +case 0xb8cf: +case 0xbac8: +case 0xbac9: +case 0xbaca: +case 0xbacb: +case 0xbacc: +case 0xbacd: +case 0xbace: +case 0xbacf: +case 0xbcc8: +case 0xbcc9: +case 0xbcca: +case 0xbccb: +case 0xbccc: +case 0xbccd: +case 0xbcce: +case 0xbccf: +case 0xbec8: +case 0xbec9: +case 0xbeca: +case 0xbecb: +case 0xbecc: +case 0xbecd: +case 0xbece: +case 0xbecf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x90c8: +case 0x90c9: +case 0x90ca: +case 0x90cb: +case 0x90cc: +case 0x90cd: +case 0x90ce: +case 0x90cf: +case 0x92c8: +case 0x92c9: +case 0x92ca: +case 0x92cb: +case 0x92cc: +case 0x92cd: +case 0x92ce: +case 0x92cf: +case 0x94c8: +case 0x94c9: +case 0x94ca: +case 0x94cb: +case 0x94cc: +case 0x94cd: +case 0x94ce: +case 0x94cf: +case 0x96c8: +case 0x96c9: +case 0x96ca: +case 0x96cb: +case 0x96cc: +case 0x96cd: +case 0x96ce: +case 0x96cf: +case 0x98c8: +case 0x98c9: +case 0x98ca: +case 0x98cb: +case 0x98cc: +case 0x98cd: +case 0x98ce: +case 0x98cf: +case 0x9ac8: +case 0x9ac9: +case 0x9aca: +case 0x9acb: +case 0x9acc: +case 0x9acd: +case 0x9ace: +case 0x9acf: +case 0x9cc8: +case 0x9cc9: +case 0x9cca: +case 0x9ccb: +case 0x9ccc: +case 0x9ccd: +case 0x9cce: +case 0x9ccf: +case 0x9ec8: +case 0x9ec9: +case 0x9eca: +case 0x9ecb: +case 0x9ecc: +case 0x9ecd: +case 0x9ece: +case 0x9ecf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x3048: +case 0x3049: +case 0x304a: +case 0x304b: +case 0x304c: +case 0x304d: +case 0x304e: +case 0x304f: +case 0x3248: +case 0x3249: +case 0x324a: +case 0x324b: +case 0x324c: +case 0x324d: +case 0x324e: +case 0x324f: +case 0x3448: +case 0x3449: +case 0x344a: +case 0x344b: +case 0x344c: +case 0x344d: +case 0x344e: +case 0x344f: +case 0x3648: +case 0x3649: +case 0x364a: +case 0x364b: +case 0x364c: +case 0x364d: +case 0x364e: +case 0x364f: +case 0x3848: +case 0x3849: +case 0x384a: +case 0x384b: +case 0x384c: +case 0x384d: +case 0x384e: +case 0x384f: +case 0x3a48: +case 0x3a49: +case 0x3a4a: +case 0x3a4b: +case 0x3a4c: +case 0x3a4d: +case 0x3a4e: +case 0x3a4f: +case 0x3c48: +case 0x3c49: +case 0x3c4a: +case 0x3c4b: +case 0x3c4c: +case 0x3c4d: +case 0x3c4e: +case 0x3c4f: +case 0x3e48: +case 0x3e49: +case 0x3e4a: +case 0x3e4b: +case 0x3e4c: +case 0x3e4d: +case 0x3e4e: +case 0x3e4f: + { + HAM src(this, instr_b2_b0); MOVEA(src, instr_b11_b9); + } + break; + +case 0x4250: +case 0x4251: +case 0x4252: +case 0x4253: +case 0x4254: +case 0x4255: +case 0x4256: +case 0x4257: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x4450: +case 0x4451: +case 0x4452: +case 0x4453: +case 0x4454: +case 0x4455: +case 0x4456: +case 0x4457: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x4050: +case 0x4051: +case 0x4052: +case 0x4053: +case 0x4054: +case 0x4055: +case 0x4056: +case 0x4057: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x4650: +case 0x4651: +case 0x4652: +case 0x4653: +case 0x4654: +case 0x4655: +case 0x4656: +case 0x4657: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x4a50: +case 0x4a51: +case 0x4a52: +case 0x4a53: +case 0x4a54: +case 0x4a55: +case 0x4a56: +case 0x4a57: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0x81d0: +case 0x81d1: +case 0x81d2: +case 0x81d3: +case 0x81d4: +case 0x81d5: +case 0x81d6: +case 0x81d7: +case 0x83d0: +case 0x83d1: +case 0x83d2: +case 0x83d3: +case 0x83d4: +case 0x83d5: +case 0x83d6: +case 0x83d7: +case 0x85d0: +case 0x85d1: +case 0x85d2: +case 0x85d3: +case 0x85d4: +case 0x85d5: +case 0x85d6: +case 0x85d7: +case 0x87d0: +case 0x87d1: +case 0x87d2: +case 0x87d3: +case 0x87d4: +case 0x87d5: +case 0x87d6: +case 0x87d7: +case 0x89d0: +case 0x89d1: +case 0x89d2: +case 0x89d3: +case 0x89d4: +case 0x89d5: +case 0x89d6: +case 0x89d7: +case 0x8bd0: +case 0x8bd1: +case 0x8bd2: +case 0x8bd3: +case 0x8bd4: +case 0x8bd5: +case 0x8bd6: +case 0x8bd7: +case 0x8dd0: +case 0x8dd1: +case 0x8dd2: +case 0x8dd3: +case 0x8dd4: +case 0x8dd5: +case 0x8dd6: +case 0x8dd7: +case 0x8fd0: +case 0x8fd1: +case 0x8fd2: +case 0x8fd3: +case 0x8fd4: +case 0x8fd5: +case 0x8fd6: +case 0x8fd7: + { + HAM src(this, instr_b2_b0); DIVS(src, instr_b11_b9); + } + break; + +case 0x80d0: +case 0x80d1: +case 0x80d2: +case 0x80d3: +case 0x80d4: +case 0x80d5: +case 0x80d6: +case 0x80d7: +case 0x82d0: +case 0x82d1: +case 0x82d2: +case 0x82d3: +case 0x82d4: +case 0x82d5: +case 0x82d6: +case 0x82d7: +case 0x84d0: +case 0x84d1: +case 0x84d2: +case 0x84d3: +case 0x84d4: +case 0x84d5: +case 0x84d6: +case 0x84d7: +case 0x86d0: +case 0x86d1: +case 0x86d2: +case 0x86d3: +case 0x86d4: +case 0x86d5: +case 0x86d6: +case 0x86d7: +case 0x88d0: +case 0x88d1: +case 0x88d2: +case 0x88d3: +case 0x88d4: +case 0x88d5: +case 0x88d6: +case 0x88d7: +case 0x8ad0: +case 0x8ad1: +case 0x8ad2: +case 0x8ad3: +case 0x8ad4: +case 0x8ad5: +case 0x8ad6: +case 0x8ad7: +case 0x8cd0: +case 0x8cd1: +case 0x8cd2: +case 0x8cd3: +case 0x8cd4: +case 0x8cd5: +case 0x8cd6: +case 0x8cd7: +case 0x8ed0: +case 0x8ed1: +case 0x8ed2: +case 0x8ed3: +case 0x8ed4: +case 0x8ed5: +case 0x8ed6: +case 0x8ed7: + { + HAM src(this, instr_b2_b0); DIVU(src, instr_b11_b9); + } + break; + +case 0x33d0: +case 0x33d1: +case 0x33d2: +case 0x33d3: +case 0x33d4: +case 0x33d5: +case 0x33d6: +case 0x33d7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x31d0: +case 0x31d1: +case 0x31d2: +case 0x31d3: +case 0x31d4: +case 0x31d5: +case 0x31d6: +case 0x31d7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x3090: +case 0x3091: +case 0x3092: +case 0x3093: +case 0x3094: +case 0x3095: +case 0x3096: +case 0x3097: +case 0x3290: +case 0x3291: +case 0x3292: +case 0x3293: +case 0x3294: +case 0x3295: +case 0x3296: +case 0x3297: +case 0x3490: +case 0x3491: +case 0x3492: +case 0x3493: +case 0x3494: +case 0x3495: +case 0x3496: +case 0x3497: +case 0x3690: +case 0x3691: +case 0x3692: +case 0x3693: +case 0x3694: +case 0x3695: +case 0x3696: +case 0x3697: +case 0x3890: +case 0x3891: +case 0x3892: +case 0x3893: +case 0x3894: +case 0x3895: +case 0x3896: +case 0x3897: +case 0x3a90: +case 0x3a91: +case 0x3a92: +case 0x3a93: +case 0x3a94: +case 0x3a95: +case 0x3a96: +case 0x3a97: +case 0x3c90: +case 0x3c91: +case 0x3c92: +case 0x3c93: +case 0x3c94: +case 0x3c95: +case 0x3c96: +case 0x3c97: +case 0x3e90: +case 0x3e91: +case 0x3e92: +case 0x3e93: +case 0x3e94: +case 0x3e95: +case 0x3e96: +case 0x3e97: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3150: +case 0x3151: +case 0x3152: +case 0x3153: +case 0x3154: +case 0x3155: +case 0x3156: +case 0x3157: +case 0x3350: +case 0x3351: +case 0x3352: +case 0x3353: +case 0x3354: +case 0x3355: +case 0x3356: +case 0x3357: +case 0x3550: +case 0x3551: +case 0x3552: +case 0x3553: +case 0x3554: +case 0x3555: +case 0x3556: +case 0x3557: +case 0x3750: +case 0x3751: +case 0x3752: +case 0x3753: +case 0x3754: +case 0x3755: +case 0x3756: +case 0x3757: +case 0x3950: +case 0x3951: +case 0x3952: +case 0x3953: +case 0x3954: +case 0x3955: +case 0x3956: +case 0x3957: +case 0x3b50: +case 0x3b51: +case 0x3b52: +case 0x3b53: +case 0x3b54: +case 0x3b55: +case 0x3b56: +case 0x3b57: +case 0x3d50: +case 0x3d51: +case 0x3d52: +case 0x3d53: +case 0x3d54: +case 0x3d55: +case 0x3d56: +case 0x3d57: +case 0x3f50: +case 0x3f51: +case 0x3f52: +case 0x3f53: +case 0x3f54: +case 0x3f55: +case 0x3f56: +case 0x3f57: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3190: +case 0x3191: +case 0x3192: +case 0x3193: +case 0x3194: +case 0x3195: +case 0x3196: +case 0x3197: +case 0x3390: +case 0x3391: +case 0x3392: +case 0x3393: +case 0x3394: +case 0x3395: +case 0x3396: +case 0x3397: +case 0x3590: +case 0x3591: +case 0x3592: +case 0x3593: +case 0x3594: +case 0x3595: +case 0x3596: +case 0x3597: +case 0x3790: +case 0x3791: +case 0x3792: +case 0x3793: +case 0x3794: +case 0x3795: +case 0x3796: +case 0x3797: +case 0x3990: +case 0x3991: +case 0x3992: +case 0x3993: +case 0x3994: +case 0x3995: +case 0x3996: +case 0x3997: +case 0x3b90: +case 0x3b91: +case 0x3b92: +case 0x3b93: +case 0x3b94: +case 0x3b95: +case 0x3b96: +case 0x3b97: +case 0x3d90: +case 0x3d91: +case 0x3d92: +case 0x3d93: +case 0x3d94: +case 0x3d95: +case 0x3d96: +case 0x3d97: +case 0x3f90: +case 0x3f91: +case 0x3f92: +case 0x3f93: +case 0x3f94: +case 0x3f95: +case 0x3f96: +case 0x3f97: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x30d0: +case 0x30d1: +case 0x30d2: +case 0x30d3: +case 0x30d4: +case 0x30d5: +case 0x30d6: +case 0x30d7: +case 0x32d0: +case 0x32d1: +case 0x32d2: +case 0x32d3: +case 0x32d4: +case 0x32d5: +case 0x32d6: +case 0x32d7: +case 0x34d0: +case 0x34d1: +case 0x34d2: +case 0x34d3: +case 0x34d4: +case 0x34d5: +case 0x34d6: +case 0x34d7: +case 0x36d0: +case 0x36d1: +case 0x36d2: +case 0x36d3: +case 0x36d4: +case 0x36d5: +case 0x36d6: +case 0x36d7: +case 0x38d0: +case 0x38d1: +case 0x38d2: +case 0x38d3: +case 0x38d4: +case 0x38d5: +case 0x38d6: +case 0x38d7: +case 0x3ad0: +case 0x3ad1: +case 0x3ad2: +case 0x3ad3: +case 0x3ad4: +case 0x3ad5: +case 0x3ad6: +case 0x3ad7: +case 0x3cd0: +case 0x3cd1: +case 0x3cd2: +case 0x3cd3: +case 0x3cd4: +case 0x3cd5: +case 0x3cd6: +case 0x3cd7: +case 0x3ed0: +case 0x3ed1: +case 0x3ed2: +case 0x3ed3: +case 0x3ed4: +case 0x3ed5: +case 0x3ed6: +case 0x3ed7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3110: +case 0x3111: +case 0x3112: +case 0x3113: +case 0x3114: +case 0x3115: +case 0x3116: +case 0x3117: +case 0x3310: +case 0x3311: +case 0x3312: +case 0x3313: +case 0x3314: +case 0x3315: +case 0x3316: +case 0x3317: +case 0x3510: +case 0x3511: +case 0x3512: +case 0x3513: +case 0x3514: +case 0x3515: +case 0x3516: +case 0x3517: +case 0x3710: +case 0x3711: +case 0x3712: +case 0x3713: +case 0x3714: +case 0x3715: +case 0x3716: +case 0x3717: +case 0x3910: +case 0x3911: +case 0x3912: +case 0x3913: +case 0x3914: +case 0x3915: +case 0x3916: +case 0x3917: +case 0x3b10: +case 0x3b11: +case 0x3b12: +case 0x3b13: +case 0x3b14: +case 0x3b15: +case 0x3b16: +case 0x3b17: +case 0x3d10: +case 0x3d11: +case 0x3d12: +case 0x3d13: +case 0x3d14: +case 0x3d15: +case 0x3d16: +case 0x3d17: +case 0x3f10: +case 0x3f11: +case 0x3f12: +case 0x3f13: +case 0x3f14: +case 0x3f15: +case 0x3f16: +case 0x3f17: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd050: +case 0xd051: +case 0xd052: +case 0xd053: +case 0xd054: +case 0xd055: +case 0xd056: +case 0xd057: +case 0xd250: +case 0xd251: +case 0xd252: +case 0xd253: +case 0xd254: +case 0xd255: +case 0xd256: +case 0xd257: +case 0xd450: +case 0xd451: +case 0xd452: +case 0xd453: +case 0xd454: +case 0xd455: +case 0xd456: +case 0xd457: +case 0xd650: +case 0xd651: +case 0xd652: +case 0xd653: +case 0xd654: +case 0xd655: +case 0xd656: +case 0xd657: +case 0xd850: +case 0xd851: +case 0xd852: +case 0xd853: +case 0xd854: +case 0xd855: +case 0xd856: +case 0xd857: +case 0xda50: +case 0xda51: +case 0xda52: +case 0xda53: +case 0xda54: +case 0xda55: +case 0xda56: +case 0xda57: +case 0xdc50: +case 0xdc51: +case 0xdc52: +case 0xdc53: +case 0xdc54: +case 0xdc55: +case 0xdc56: +case 0xdc57: +case 0xde50: +case 0xde51: +case 0xde52: +case 0xde53: +case 0xde54: +case 0xde55: +case 0xde56: +case 0xde57: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc050: +case 0xc051: +case 0xc052: +case 0xc053: +case 0xc054: +case 0xc055: +case 0xc056: +case 0xc057: +case 0xc250: +case 0xc251: +case 0xc252: +case 0xc253: +case 0xc254: +case 0xc255: +case 0xc256: +case 0xc257: +case 0xc450: +case 0xc451: +case 0xc452: +case 0xc453: +case 0xc454: +case 0xc455: +case 0xc456: +case 0xc457: +case 0xc650: +case 0xc651: +case 0xc652: +case 0xc653: +case 0xc654: +case 0xc655: +case 0xc656: +case 0xc657: +case 0xc850: +case 0xc851: +case 0xc852: +case 0xc853: +case 0xc854: +case 0xc855: +case 0xc856: +case 0xc857: +case 0xca50: +case 0xca51: +case 0xca52: +case 0xca53: +case 0xca54: +case 0xca55: +case 0xca56: +case 0xca57: +case 0xcc50: +case 0xcc51: +case 0xcc52: +case 0xcc53: +case 0xcc54: +case 0xcc55: +case 0xcc56: +case 0xcc57: +case 0xce50: +case 0xce51: +case 0xce52: +case 0xce53: +case 0xce54: +case 0xce55: +case 0xce56: +case 0xce57: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0x4190: +case 0x4191: +case 0x4192: +case 0x4193: +case 0x4194: +case 0x4195: +case 0x4196: +case 0x4197: +case 0x4390: +case 0x4391: +case 0x4392: +case 0x4393: +case 0x4394: +case 0x4395: +case 0x4396: +case 0x4397: +case 0x4590: +case 0x4591: +case 0x4592: +case 0x4593: +case 0x4594: +case 0x4595: +case 0x4596: +case 0x4597: +case 0x4790: +case 0x4791: +case 0x4792: +case 0x4793: +case 0x4794: +case 0x4795: +case 0x4796: +case 0x4797: +case 0x4990: +case 0x4991: +case 0x4992: +case 0x4993: +case 0x4994: +case 0x4995: +case 0x4996: +case 0x4997: +case 0x4b90: +case 0x4b91: +case 0x4b92: +case 0x4b93: +case 0x4b94: +case 0x4b95: +case 0x4b96: +case 0x4b97: +case 0x4d90: +case 0x4d91: +case 0x4d92: +case 0x4d93: +case 0x4d94: +case 0x4d95: +case 0x4d96: +case 0x4d97: +case 0x4f90: +case 0x4f91: +case 0x4f92: +case 0x4f93: +case 0x4f94: +case 0x4f95: +case 0x4f96: +case 0x4f97: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CHK(src, dst); + } + break; + +case 0xb050: +case 0xb051: +case 0xb052: +case 0xb053: +case 0xb054: +case 0xb055: +case 0xb056: +case 0xb057: +case 0xb250: +case 0xb251: +case 0xb252: +case 0xb253: +case 0xb254: +case 0xb255: +case 0xb256: +case 0xb257: +case 0xb450: +case 0xb451: +case 0xb452: +case 0xb453: +case 0xb454: +case 0xb455: +case 0xb456: +case 0xb457: +case 0xb650: +case 0xb651: +case 0xb652: +case 0xb653: +case 0xb654: +case 0xb655: +case 0xb656: +case 0xb657: +case 0xb850: +case 0xb851: +case 0xb852: +case 0xb853: +case 0xb854: +case 0xb855: +case 0xb856: +case 0xb857: +case 0xba50: +case 0xba51: +case 0xba52: +case 0xba53: +case 0xba54: +case 0xba55: +case 0xba56: +case 0xba57: +case 0xbc50: +case 0xbc51: +case 0xbc52: +case 0xbc53: +case 0xbc54: +case 0xbc55: +case 0xbc56: +case 0xbc57: +case 0xbe50: +case 0xbe51: +case 0xbe52: +case 0xbe53: +case 0xbe54: +case 0xbe55: +case 0xbe56: +case 0xbe57: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x3010: +case 0x3011: +case 0x3012: +case 0x3013: +case 0x3014: +case 0x3015: +case 0x3016: +case 0x3017: +case 0x3210: +case 0x3211: +case 0x3212: +case 0x3213: +case 0x3214: +case 0x3215: +case 0x3216: +case 0x3217: +case 0x3410: +case 0x3411: +case 0x3412: +case 0x3413: +case 0x3414: +case 0x3415: +case 0x3416: +case 0x3417: +case 0x3610: +case 0x3611: +case 0x3612: +case 0x3613: +case 0x3614: +case 0x3615: +case 0x3616: +case 0x3617: +case 0x3810: +case 0x3811: +case 0x3812: +case 0x3813: +case 0x3814: +case 0x3815: +case 0x3816: +case 0x3817: +case 0x3a10: +case 0x3a11: +case 0x3a12: +case 0x3a13: +case 0x3a14: +case 0x3a15: +case 0x3a16: +case 0x3a17: +case 0x3c10: +case 0x3c11: +case 0x3c12: +case 0x3c13: +case 0x3c14: +case 0x3c15: +case 0x3c16: +case 0x3c17: +case 0x3e10: +case 0x3e11: +case 0x3e12: +case 0x3e13: +case 0x3e14: +case 0x3e15: +case 0x3e16: +case 0x3e17: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8050: +case 0x8051: +case 0x8052: +case 0x8053: +case 0x8054: +case 0x8055: +case 0x8056: +case 0x8057: +case 0x8250: +case 0x8251: +case 0x8252: +case 0x8253: +case 0x8254: +case 0x8255: +case 0x8256: +case 0x8257: +case 0x8450: +case 0x8451: +case 0x8452: +case 0x8453: +case 0x8454: +case 0x8455: +case 0x8456: +case 0x8457: +case 0x8650: +case 0x8651: +case 0x8652: +case 0x8653: +case 0x8654: +case 0x8655: +case 0x8656: +case 0x8657: +case 0x8850: +case 0x8851: +case 0x8852: +case 0x8853: +case 0x8854: +case 0x8855: +case 0x8856: +case 0x8857: +case 0x8a50: +case 0x8a51: +case 0x8a52: +case 0x8a53: +case 0x8a54: +case 0x8a55: +case 0x8a56: +case 0x8a57: +case 0x8c50: +case 0x8c51: +case 0x8c52: +case 0x8c53: +case 0x8c54: +case 0x8c55: +case 0x8c56: +case 0x8c57: +case 0x8e50: +case 0x8e51: +case 0x8e52: +case 0x8e53: +case 0x8e54: +case 0x8e55: +case 0x8e56: +case 0x8e57: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9050: +case 0x9051: +case 0x9052: +case 0x9053: +case 0x9054: +case 0x9055: +case 0x9056: +case 0x9057: +case 0x9250: +case 0x9251: +case 0x9252: +case 0x9253: +case 0x9254: +case 0x9255: +case 0x9256: +case 0x9257: +case 0x9450: +case 0x9451: +case 0x9452: +case 0x9453: +case 0x9454: +case 0x9455: +case 0x9456: +case 0x9457: +case 0x9650: +case 0x9651: +case 0x9652: +case 0x9653: +case 0x9654: +case 0x9655: +case 0x9656: +case 0x9657: +case 0x9850: +case 0x9851: +case 0x9852: +case 0x9853: +case 0x9854: +case 0x9855: +case 0x9856: +case 0x9857: +case 0x9a50: +case 0x9a51: +case 0x9a52: +case 0x9a53: +case 0x9a54: +case 0x9a55: +case 0x9a56: +case 0x9a57: +case 0x9c50: +case 0x9c51: +case 0x9c52: +case 0x9c53: +case 0x9c54: +case 0x9c55: +case 0x9c56: +case 0x9c57: +case 0x9e50: +case 0x9e51: +case 0x9e52: +case 0x9e53: +case 0x9e54: +case 0x9e55: +case 0x9e56: +case 0x9e57: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0xd0d0: +case 0xd0d1: +case 0xd0d2: +case 0xd0d3: +case 0xd0d4: +case 0xd0d5: +case 0xd0d6: +case 0xd0d7: +case 0xd2d0: +case 0xd2d1: +case 0xd2d2: +case 0xd2d3: +case 0xd2d4: +case 0xd2d5: +case 0xd2d6: +case 0xd2d7: +case 0xd4d0: +case 0xd4d1: +case 0xd4d2: +case 0xd4d3: +case 0xd4d4: +case 0xd4d5: +case 0xd4d6: +case 0xd4d7: +case 0xd6d0: +case 0xd6d1: +case 0xd6d2: +case 0xd6d3: +case 0xd6d4: +case 0xd6d5: +case 0xd6d6: +case 0xd6d7: +case 0xd8d0: +case 0xd8d1: +case 0xd8d2: +case 0xd8d3: +case 0xd8d4: +case 0xd8d5: +case 0xd8d6: +case 0xd8d7: +case 0xdad0: +case 0xdad1: +case 0xdad2: +case 0xdad3: +case 0xdad4: +case 0xdad5: +case 0xdad6: +case 0xdad7: +case 0xdcd0: +case 0xdcd1: +case 0xdcd2: +case 0xdcd3: +case 0xdcd4: +case 0xdcd5: +case 0xdcd6: +case 0xdcd7: +case 0xded0: +case 0xded1: +case 0xded2: +case 0xded3: +case 0xded4: +case 0xded5: +case 0xded6: +case 0xded7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb0d0: +case 0xb0d1: +case 0xb0d2: +case 0xb0d3: +case 0xb0d4: +case 0xb0d5: +case 0xb0d6: +case 0xb0d7: +case 0xb2d0: +case 0xb2d1: +case 0xb2d2: +case 0xb2d3: +case 0xb2d4: +case 0xb2d5: +case 0xb2d6: +case 0xb2d7: +case 0xb4d0: +case 0xb4d1: +case 0xb4d2: +case 0xb4d3: +case 0xb4d4: +case 0xb4d5: +case 0xb4d6: +case 0xb4d7: +case 0xb6d0: +case 0xb6d1: +case 0xb6d2: +case 0xb6d3: +case 0xb6d4: +case 0xb6d5: +case 0xb6d6: +case 0xb6d7: +case 0xb8d0: +case 0xb8d1: +case 0xb8d2: +case 0xb8d3: +case 0xb8d4: +case 0xb8d5: +case 0xb8d6: +case 0xb8d7: +case 0xbad0: +case 0xbad1: +case 0xbad2: +case 0xbad3: +case 0xbad4: +case 0xbad5: +case 0xbad6: +case 0xbad7: +case 0xbcd0: +case 0xbcd1: +case 0xbcd2: +case 0xbcd3: +case 0xbcd4: +case 0xbcd5: +case 0xbcd6: +case 0xbcd7: +case 0xbed0: +case 0xbed1: +case 0xbed2: +case 0xbed3: +case 0xbed4: +case 0xbed5: +case 0xbed6: +case 0xbed7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x90d0: +case 0x90d1: +case 0x90d2: +case 0x90d3: +case 0x90d4: +case 0x90d5: +case 0x90d6: +case 0x90d7: +case 0x92d0: +case 0x92d1: +case 0x92d2: +case 0x92d3: +case 0x92d4: +case 0x92d5: +case 0x92d6: +case 0x92d7: +case 0x94d0: +case 0x94d1: +case 0x94d2: +case 0x94d3: +case 0x94d4: +case 0x94d5: +case 0x94d6: +case 0x94d7: +case 0x96d0: +case 0x96d1: +case 0x96d2: +case 0x96d3: +case 0x96d4: +case 0x96d5: +case 0x96d6: +case 0x96d7: +case 0x98d0: +case 0x98d1: +case 0x98d2: +case 0x98d3: +case 0x98d4: +case 0x98d5: +case 0x98d6: +case 0x98d7: +case 0x9ad0: +case 0x9ad1: +case 0x9ad2: +case 0x9ad3: +case 0x9ad4: +case 0x9ad5: +case 0x9ad6: +case 0x9ad7: +case 0x9cd0: +case 0x9cd1: +case 0x9cd2: +case 0x9cd3: +case 0x9cd4: +case 0x9cd5: +case 0x9cd6: +case 0x9cd7: +case 0x9ed0: +case 0x9ed1: +case 0x9ed2: +case 0x9ed3: +case 0x9ed4: +case 0x9ed5: +case 0x9ed6: +case 0x9ed7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x3050: +case 0x3051: +case 0x3052: +case 0x3053: +case 0x3054: +case 0x3055: +case 0x3056: +case 0x3057: +case 0x3250: +case 0x3251: +case 0x3252: +case 0x3253: +case 0x3254: +case 0x3255: +case 0x3256: +case 0x3257: +case 0x3450: +case 0x3451: +case 0x3452: +case 0x3453: +case 0x3454: +case 0x3455: +case 0x3456: +case 0x3457: +case 0x3650: +case 0x3651: +case 0x3652: +case 0x3653: +case 0x3654: +case 0x3655: +case 0x3656: +case 0x3657: +case 0x3850: +case 0x3851: +case 0x3852: +case 0x3853: +case 0x3854: +case 0x3855: +case 0x3856: +case 0x3857: +case 0x3a50: +case 0x3a51: +case 0x3a52: +case 0x3a53: +case 0x3a54: +case 0x3a55: +case 0x3a56: +case 0x3a57: +case 0x3c50: +case 0x3c51: +case 0x3c52: +case 0x3c53: +case 0x3c54: +case 0x3c55: +case 0x3c56: +case 0x3c57: +case 0x3e50: +case 0x3e51: +case 0x3e52: +case 0x3e53: +case 0x3e54: +case 0x3e55: +case 0x3e56: +case 0x3e57: + { + HAM src(this, instr_b2_b0); MOVEA(src, instr_b11_b9); + } + break; + +case 0x44d0: +case 0x44d1: +case 0x44d2: +case 0x44d3: +case 0x44d4: +case 0x44d5: +case 0x44d6: +case 0x44d7: + { + HAM src(this, instr_b2_b0); MOVE_to_CCR(src); + } + break; + +case 0xc1d0: +case 0xc1d1: +case 0xc1d2: +case 0xc1d3: +case 0xc1d4: +case 0xc1d5: +case 0xc1d6: +case 0xc1d7: +case 0xc3d0: +case 0xc3d1: +case 0xc3d2: +case 0xc3d3: +case 0xc3d4: +case 0xc3d5: +case 0xc3d6: +case 0xc3d7: +case 0xc5d0: +case 0xc5d1: +case 0xc5d2: +case 0xc5d3: +case 0xc5d4: +case 0xc5d5: +case 0xc5d6: +case 0xc5d7: +case 0xc7d0: +case 0xc7d1: +case 0xc7d2: +case 0xc7d3: +case 0xc7d4: +case 0xc7d5: +case 0xc7d6: +case 0xc7d7: +case 0xc9d0: +case 0xc9d1: +case 0xc9d2: +case 0xc9d3: +case 0xc9d4: +case 0xc9d5: +case 0xc9d6: +case 0xc9d7: +case 0xcbd0: +case 0xcbd1: +case 0xcbd2: +case 0xcbd3: +case 0xcbd4: +case 0xcbd5: +case 0xcbd6: +case 0xcbd7: +case 0xcdd0: +case 0xcdd1: +case 0xcdd2: +case 0xcdd3: +case 0xcdd4: +case 0xcdd5: +case 0xcdd6: +case 0xcdd7: +case 0xcfd0: +case 0xcfd1: +case 0xcfd2: +case 0xcfd3: +case 0xcfd4: +case 0xcfd5: +case 0xcfd6: +case 0xcfd7: + { + HAM src(this, instr_b2_b0); MULS(src, instr_b11_b9); + } + break; + +case 0xc0d0: +case 0xc0d1: +case 0xc0d2: +case 0xc0d3: +case 0xc0d4: +case 0xc0d5: +case 0xc0d6: +case 0xc0d7: +case 0xc2d0: +case 0xc2d1: +case 0xc2d2: +case 0xc2d3: +case 0xc2d4: +case 0xc2d5: +case 0xc2d6: +case 0xc2d7: +case 0xc4d0: +case 0xc4d1: +case 0xc4d2: +case 0xc4d3: +case 0xc4d4: +case 0xc4d5: +case 0xc4d6: +case 0xc4d7: +case 0xc6d0: +case 0xc6d1: +case 0xc6d2: +case 0xc6d3: +case 0xc6d4: +case 0xc6d5: +case 0xc6d6: +case 0xc6d7: +case 0xc8d0: +case 0xc8d1: +case 0xc8d2: +case 0xc8d3: +case 0xc8d4: +case 0xc8d5: +case 0xc8d6: +case 0xc8d7: +case 0xcad0: +case 0xcad1: +case 0xcad2: +case 0xcad3: +case 0xcad4: +case 0xcad5: +case 0xcad6: +case 0xcad7: +case 0xccd0: +case 0xccd1: +case 0xccd2: +case 0xccd3: +case 0xccd4: +case 0xccd5: +case 0xccd6: +case 0xccd7: +case 0xced0: +case 0xced1: +case 0xced2: +case 0xced3: +case 0xced4: +case 0xced5: +case 0xced6: +case 0xced7: + { + HAM src(this, instr_b2_b0); MULU(src, instr_b11_b9); + } + break; + +case 0xe1d0: +case 0xe1d1: +case 0xe1d2: +case 0xe1d3: +case 0xe1d4: +case 0xe1d5: +case 0xe1d6: +case 0xe1d7: + { + HAM targ(this, instr_b2_b0); ASL(targ, 1); + } + break; + +case 0xe0d0: +case 0xe0d1: +case 0xe0d2: +case 0xe0d3: +case 0xe0d4: +case 0xe0d5: +case 0xe0d6: +case 0xe0d7: + { + HAM targ(this, instr_b2_b0); ASR(targ, 1); + } + break; + +case 0xe3d0: +case 0xe3d1: +case 0xe3d2: +case 0xe3d3: +case 0xe3d4: +case 0xe3d5: +case 0xe3d6: +case 0xe3d7: + { + HAM targ(this, instr_b2_b0); LSL(targ, 1); + } + break; + +case 0xe2d0: +case 0xe2d1: +case 0xe2d2: +case 0xe2d3: +case 0xe2d4: +case 0xe2d5: +case 0xe2d6: +case 0xe2d7: + { + HAM targ(this, instr_b2_b0); LSR(targ, 1); + } + break; + +case 0xe7d0: +case 0xe7d1: +case 0xe7d2: +case 0xe7d3: +case 0xe7d4: +case 0xe7d5: +case 0xe7d6: +case 0xe7d7: + { + HAM targ(this, instr_b2_b0); ROL(targ, 1); + } + break; + +case 0xe6d0: +case 0xe6d1: +case 0xe6d2: +case 0xe6d3: +case 0xe6d4: +case 0xe6d5: +case 0xe6d6: +case 0xe6d7: + { + HAM targ(this, instr_b2_b0); ROR(targ, 1); + } + break; + +case 0xe5d0: +case 0xe5d1: +case 0xe5d2: +case 0xe5d3: +case 0xe5d4: +case 0xe5d5: +case 0xe5d6: +case 0xe5d7: + { + HAM targ(this, instr_b2_b0); ROXL(targ, 1); + } + break; + +case 0xe4d0: +case 0xe4d1: +case 0xe4d2: +case 0xe4d3: +case 0xe4d4: +case 0xe4d5: +case 0xe4d6: +case 0xe4d7: + { + HAM targ(this, instr_b2_b0); ROXR(targ, 1); + } + break; + +case 0x4268: +case 0x4269: +case 0x426a: +case 0x426b: +case 0x426c: +case 0x426d: +case 0x426e: +case 0x426f: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x4468: +case 0x4469: +case 0x446a: +case 0x446b: +case 0x446c: +case 0x446d: +case 0x446e: +case 0x446f: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x4068: +case 0x4069: +case 0x406a: +case 0x406b: +case 0x406c: +case 0x406d: +case 0x406e: +case 0x406f: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x4668: +case 0x4669: +case 0x466a: +case 0x466b: +case 0x466c: +case 0x466d: +case 0x466e: +case 0x466f: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x4a68: +case 0x4a69: +case 0x4a6a: +case 0x4a6b: +case 0x4a6c: +case 0x4a6d: +case 0x4a6e: +case 0x4a6f: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0x81e8: +case 0x81e9: +case 0x81ea: +case 0x81eb: +case 0x81ec: +case 0x81ed: +case 0x81ee: +case 0x81ef: +case 0x83e8: +case 0x83e9: +case 0x83ea: +case 0x83eb: +case 0x83ec: +case 0x83ed: +case 0x83ee: +case 0x83ef: +case 0x85e8: +case 0x85e9: +case 0x85ea: +case 0x85eb: +case 0x85ec: +case 0x85ed: +case 0x85ee: +case 0x85ef: +case 0x87e8: +case 0x87e9: +case 0x87ea: +case 0x87eb: +case 0x87ec: +case 0x87ed: +case 0x87ee: +case 0x87ef: +case 0x89e8: +case 0x89e9: +case 0x89ea: +case 0x89eb: +case 0x89ec: +case 0x89ed: +case 0x89ee: +case 0x89ef: +case 0x8be8: +case 0x8be9: +case 0x8bea: +case 0x8beb: +case 0x8bec: +case 0x8bed: +case 0x8bee: +case 0x8bef: +case 0x8de8: +case 0x8de9: +case 0x8dea: +case 0x8deb: +case 0x8dec: +case 0x8ded: +case 0x8dee: +case 0x8def: +case 0x8fe8: +case 0x8fe9: +case 0x8fea: +case 0x8feb: +case 0x8fec: +case 0x8fed: +case 0x8fee: +case 0x8fef: + { + HAM src(this, instr_b2_b0); DIVS(src, instr_b11_b9); + } + break; + +case 0x80e8: +case 0x80e9: +case 0x80ea: +case 0x80eb: +case 0x80ec: +case 0x80ed: +case 0x80ee: +case 0x80ef: +case 0x82e8: +case 0x82e9: +case 0x82ea: +case 0x82eb: +case 0x82ec: +case 0x82ed: +case 0x82ee: +case 0x82ef: +case 0x84e8: +case 0x84e9: +case 0x84ea: +case 0x84eb: +case 0x84ec: +case 0x84ed: +case 0x84ee: +case 0x84ef: +case 0x86e8: +case 0x86e9: +case 0x86ea: +case 0x86eb: +case 0x86ec: +case 0x86ed: +case 0x86ee: +case 0x86ef: +case 0x88e8: +case 0x88e9: +case 0x88ea: +case 0x88eb: +case 0x88ec: +case 0x88ed: +case 0x88ee: +case 0x88ef: +case 0x8ae8: +case 0x8ae9: +case 0x8aea: +case 0x8aeb: +case 0x8aec: +case 0x8aed: +case 0x8aee: +case 0x8aef: +case 0x8ce8: +case 0x8ce9: +case 0x8cea: +case 0x8ceb: +case 0x8cec: +case 0x8ced: +case 0x8cee: +case 0x8cef: +case 0x8ee8: +case 0x8ee9: +case 0x8eea: +case 0x8eeb: +case 0x8eec: +case 0x8eed: +case 0x8eee: +case 0x8eef: + { + HAM src(this, instr_b2_b0); DIVU(src, instr_b11_b9); + } + break; + +case 0x33e8: +case 0x33e9: +case 0x33ea: +case 0x33eb: +case 0x33ec: +case 0x33ed: +case 0x33ee: +case 0x33ef: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x31e8: +case 0x31e9: +case 0x31ea: +case 0x31eb: +case 0x31ec: +case 0x31ed: +case 0x31ee: +case 0x31ef: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x30a8: +case 0x30a9: +case 0x30aa: +case 0x30ab: +case 0x30ac: +case 0x30ad: +case 0x30ae: +case 0x30af: +case 0x32a8: +case 0x32a9: +case 0x32aa: +case 0x32ab: +case 0x32ac: +case 0x32ad: +case 0x32ae: +case 0x32af: +case 0x34a8: +case 0x34a9: +case 0x34aa: +case 0x34ab: +case 0x34ac: +case 0x34ad: +case 0x34ae: +case 0x34af: +case 0x36a8: +case 0x36a9: +case 0x36aa: +case 0x36ab: +case 0x36ac: +case 0x36ad: +case 0x36ae: +case 0x36af: +case 0x38a8: +case 0x38a9: +case 0x38aa: +case 0x38ab: +case 0x38ac: +case 0x38ad: +case 0x38ae: +case 0x38af: +case 0x3aa8: +case 0x3aa9: +case 0x3aaa: +case 0x3aab: +case 0x3aac: +case 0x3aad: +case 0x3aae: +case 0x3aaf: +case 0x3ca8: +case 0x3ca9: +case 0x3caa: +case 0x3cab: +case 0x3cac: +case 0x3cad: +case 0x3cae: +case 0x3caf: +case 0x3ea8: +case 0x3ea9: +case 0x3eaa: +case 0x3eab: +case 0x3eac: +case 0x3ead: +case 0x3eae: +case 0x3eaf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3168: +case 0x3169: +case 0x316a: +case 0x316b: +case 0x316c: +case 0x316d: +case 0x316e: +case 0x316f: +case 0x3368: +case 0x3369: +case 0x336a: +case 0x336b: +case 0x336c: +case 0x336d: +case 0x336e: +case 0x336f: +case 0x3568: +case 0x3569: +case 0x356a: +case 0x356b: +case 0x356c: +case 0x356d: +case 0x356e: +case 0x356f: +case 0x3768: +case 0x3769: +case 0x376a: +case 0x376b: +case 0x376c: +case 0x376d: +case 0x376e: +case 0x376f: +case 0x3968: +case 0x3969: +case 0x396a: +case 0x396b: +case 0x396c: +case 0x396d: +case 0x396e: +case 0x396f: +case 0x3b68: +case 0x3b69: +case 0x3b6a: +case 0x3b6b: +case 0x3b6c: +case 0x3b6d: +case 0x3b6e: +case 0x3b6f: +case 0x3d68: +case 0x3d69: +case 0x3d6a: +case 0x3d6b: +case 0x3d6c: +case 0x3d6d: +case 0x3d6e: +case 0x3d6f: +case 0x3f68: +case 0x3f69: +case 0x3f6a: +case 0x3f6b: +case 0x3f6c: +case 0x3f6d: +case 0x3f6e: +case 0x3f6f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x31a8: +case 0x31a9: +case 0x31aa: +case 0x31ab: +case 0x31ac: +case 0x31ad: +case 0x31ae: +case 0x31af: +case 0x33a8: +case 0x33a9: +case 0x33aa: +case 0x33ab: +case 0x33ac: +case 0x33ad: +case 0x33ae: +case 0x33af: +case 0x35a8: +case 0x35a9: +case 0x35aa: +case 0x35ab: +case 0x35ac: +case 0x35ad: +case 0x35ae: +case 0x35af: +case 0x37a8: +case 0x37a9: +case 0x37aa: +case 0x37ab: +case 0x37ac: +case 0x37ad: +case 0x37ae: +case 0x37af: +case 0x39a8: +case 0x39a9: +case 0x39aa: +case 0x39ab: +case 0x39ac: +case 0x39ad: +case 0x39ae: +case 0x39af: +case 0x3ba8: +case 0x3ba9: +case 0x3baa: +case 0x3bab: +case 0x3bac: +case 0x3bad: +case 0x3bae: +case 0x3baf: +case 0x3da8: +case 0x3da9: +case 0x3daa: +case 0x3dab: +case 0x3dac: +case 0x3dad: +case 0x3dae: +case 0x3daf: +case 0x3fa8: +case 0x3fa9: +case 0x3faa: +case 0x3fab: +case 0x3fac: +case 0x3fad: +case 0x3fae: +case 0x3faf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x30e8: +case 0x30e9: +case 0x30ea: +case 0x30eb: +case 0x30ec: +case 0x30ed: +case 0x30ee: +case 0x30ef: +case 0x32e8: +case 0x32e9: +case 0x32ea: +case 0x32eb: +case 0x32ec: +case 0x32ed: +case 0x32ee: +case 0x32ef: +case 0x34e8: +case 0x34e9: +case 0x34ea: +case 0x34eb: +case 0x34ec: +case 0x34ed: +case 0x34ee: +case 0x34ef: +case 0x36e8: +case 0x36e9: +case 0x36ea: +case 0x36eb: +case 0x36ec: +case 0x36ed: +case 0x36ee: +case 0x36ef: +case 0x38e8: +case 0x38e9: +case 0x38ea: +case 0x38eb: +case 0x38ec: +case 0x38ed: +case 0x38ee: +case 0x38ef: +case 0x3ae8: +case 0x3ae9: +case 0x3aea: +case 0x3aeb: +case 0x3aec: +case 0x3aed: +case 0x3aee: +case 0x3aef: +case 0x3ce8: +case 0x3ce9: +case 0x3cea: +case 0x3ceb: +case 0x3cec: +case 0x3ced: +case 0x3cee: +case 0x3cef: +case 0x3ee8: +case 0x3ee9: +case 0x3eea: +case 0x3eeb: +case 0x3eec: +case 0x3eed: +case 0x3eee: +case 0x3eef: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3128: +case 0x3129: +case 0x312a: +case 0x312b: +case 0x312c: +case 0x312d: +case 0x312e: +case 0x312f: +case 0x3328: +case 0x3329: +case 0x332a: +case 0x332b: +case 0x332c: +case 0x332d: +case 0x332e: +case 0x332f: +case 0x3528: +case 0x3529: +case 0x352a: +case 0x352b: +case 0x352c: +case 0x352d: +case 0x352e: +case 0x352f: +case 0x3728: +case 0x3729: +case 0x372a: +case 0x372b: +case 0x372c: +case 0x372d: +case 0x372e: +case 0x372f: +case 0x3928: +case 0x3929: +case 0x392a: +case 0x392b: +case 0x392c: +case 0x392d: +case 0x392e: +case 0x392f: +case 0x3b28: +case 0x3b29: +case 0x3b2a: +case 0x3b2b: +case 0x3b2c: +case 0x3b2d: +case 0x3b2e: +case 0x3b2f: +case 0x3d28: +case 0x3d29: +case 0x3d2a: +case 0x3d2b: +case 0x3d2c: +case 0x3d2d: +case 0x3d2e: +case 0x3d2f: +case 0x3f28: +case 0x3f29: +case 0x3f2a: +case 0x3f2b: +case 0x3f2c: +case 0x3f2d: +case 0x3f2e: +case 0x3f2f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd068: +case 0xd069: +case 0xd06a: +case 0xd06b: +case 0xd06c: +case 0xd06d: +case 0xd06e: +case 0xd06f: +case 0xd268: +case 0xd269: +case 0xd26a: +case 0xd26b: +case 0xd26c: +case 0xd26d: +case 0xd26e: +case 0xd26f: +case 0xd468: +case 0xd469: +case 0xd46a: +case 0xd46b: +case 0xd46c: +case 0xd46d: +case 0xd46e: +case 0xd46f: +case 0xd668: +case 0xd669: +case 0xd66a: +case 0xd66b: +case 0xd66c: +case 0xd66d: +case 0xd66e: +case 0xd66f: +case 0xd868: +case 0xd869: +case 0xd86a: +case 0xd86b: +case 0xd86c: +case 0xd86d: +case 0xd86e: +case 0xd86f: +case 0xda68: +case 0xda69: +case 0xda6a: +case 0xda6b: +case 0xda6c: +case 0xda6d: +case 0xda6e: +case 0xda6f: +case 0xdc68: +case 0xdc69: +case 0xdc6a: +case 0xdc6b: +case 0xdc6c: +case 0xdc6d: +case 0xdc6e: +case 0xdc6f: +case 0xde68: +case 0xde69: +case 0xde6a: +case 0xde6b: +case 0xde6c: +case 0xde6d: +case 0xde6e: +case 0xde6f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc068: +case 0xc069: +case 0xc06a: +case 0xc06b: +case 0xc06c: +case 0xc06d: +case 0xc06e: +case 0xc06f: +case 0xc268: +case 0xc269: +case 0xc26a: +case 0xc26b: +case 0xc26c: +case 0xc26d: +case 0xc26e: +case 0xc26f: +case 0xc468: +case 0xc469: +case 0xc46a: +case 0xc46b: +case 0xc46c: +case 0xc46d: +case 0xc46e: +case 0xc46f: +case 0xc668: +case 0xc669: +case 0xc66a: +case 0xc66b: +case 0xc66c: +case 0xc66d: +case 0xc66e: +case 0xc66f: +case 0xc868: +case 0xc869: +case 0xc86a: +case 0xc86b: +case 0xc86c: +case 0xc86d: +case 0xc86e: +case 0xc86f: +case 0xca68: +case 0xca69: +case 0xca6a: +case 0xca6b: +case 0xca6c: +case 0xca6d: +case 0xca6e: +case 0xca6f: +case 0xcc68: +case 0xcc69: +case 0xcc6a: +case 0xcc6b: +case 0xcc6c: +case 0xcc6d: +case 0xcc6e: +case 0xcc6f: +case 0xce68: +case 0xce69: +case 0xce6a: +case 0xce6b: +case 0xce6c: +case 0xce6d: +case 0xce6e: +case 0xce6f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0x41a8: +case 0x41a9: +case 0x41aa: +case 0x41ab: +case 0x41ac: +case 0x41ad: +case 0x41ae: +case 0x41af: +case 0x43a8: +case 0x43a9: +case 0x43aa: +case 0x43ab: +case 0x43ac: +case 0x43ad: +case 0x43ae: +case 0x43af: +case 0x45a8: +case 0x45a9: +case 0x45aa: +case 0x45ab: +case 0x45ac: +case 0x45ad: +case 0x45ae: +case 0x45af: +case 0x47a8: +case 0x47a9: +case 0x47aa: +case 0x47ab: +case 0x47ac: +case 0x47ad: +case 0x47ae: +case 0x47af: +case 0x49a8: +case 0x49a9: +case 0x49aa: +case 0x49ab: +case 0x49ac: +case 0x49ad: +case 0x49ae: +case 0x49af: +case 0x4ba8: +case 0x4ba9: +case 0x4baa: +case 0x4bab: +case 0x4bac: +case 0x4bad: +case 0x4bae: +case 0x4baf: +case 0x4da8: +case 0x4da9: +case 0x4daa: +case 0x4dab: +case 0x4dac: +case 0x4dad: +case 0x4dae: +case 0x4daf: +case 0x4fa8: +case 0x4fa9: +case 0x4faa: +case 0x4fab: +case 0x4fac: +case 0x4fad: +case 0x4fae: +case 0x4faf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CHK(src, dst); + } + break; + +case 0xb068: +case 0xb069: +case 0xb06a: +case 0xb06b: +case 0xb06c: +case 0xb06d: +case 0xb06e: +case 0xb06f: +case 0xb268: +case 0xb269: +case 0xb26a: +case 0xb26b: +case 0xb26c: +case 0xb26d: +case 0xb26e: +case 0xb26f: +case 0xb468: +case 0xb469: +case 0xb46a: +case 0xb46b: +case 0xb46c: +case 0xb46d: +case 0xb46e: +case 0xb46f: +case 0xb668: +case 0xb669: +case 0xb66a: +case 0xb66b: +case 0xb66c: +case 0xb66d: +case 0xb66e: +case 0xb66f: +case 0xb868: +case 0xb869: +case 0xb86a: +case 0xb86b: +case 0xb86c: +case 0xb86d: +case 0xb86e: +case 0xb86f: +case 0xba68: +case 0xba69: +case 0xba6a: +case 0xba6b: +case 0xba6c: +case 0xba6d: +case 0xba6e: +case 0xba6f: +case 0xbc68: +case 0xbc69: +case 0xbc6a: +case 0xbc6b: +case 0xbc6c: +case 0xbc6d: +case 0xbc6e: +case 0xbc6f: +case 0xbe68: +case 0xbe69: +case 0xbe6a: +case 0xbe6b: +case 0xbe6c: +case 0xbe6d: +case 0xbe6e: +case 0xbe6f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x3028: +case 0x3029: +case 0x302a: +case 0x302b: +case 0x302c: +case 0x302d: +case 0x302e: +case 0x302f: +case 0x3228: +case 0x3229: +case 0x322a: +case 0x322b: +case 0x322c: +case 0x322d: +case 0x322e: +case 0x322f: +case 0x3428: +case 0x3429: +case 0x342a: +case 0x342b: +case 0x342c: +case 0x342d: +case 0x342e: +case 0x342f: +case 0x3628: +case 0x3629: +case 0x362a: +case 0x362b: +case 0x362c: +case 0x362d: +case 0x362e: +case 0x362f: +case 0x3828: +case 0x3829: +case 0x382a: +case 0x382b: +case 0x382c: +case 0x382d: +case 0x382e: +case 0x382f: +case 0x3a28: +case 0x3a29: +case 0x3a2a: +case 0x3a2b: +case 0x3a2c: +case 0x3a2d: +case 0x3a2e: +case 0x3a2f: +case 0x3c28: +case 0x3c29: +case 0x3c2a: +case 0x3c2b: +case 0x3c2c: +case 0x3c2d: +case 0x3c2e: +case 0x3c2f: +case 0x3e28: +case 0x3e29: +case 0x3e2a: +case 0x3e2b: +case 0x3e2c: +case 0x3e2d: +case 0x3e2e: +case 0x3e2f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8068: +case 0x8069: +case 0x806a: +case 0x806b: +case 0x806c: +case 0x806d: +case 0x806e: +case 0x806f: +case 0x8268: +case 0x8269: +case 0x826a: +case 0x826b: +case 0x826c: +case 0x826d: +case 0x826e: +case 0x826f: +case 0x8468: +case 0x8469: +case 0x846a: +case 0x846b: +case 0x846c: +case 0x846d: +case 0x846e: +case 0x846f: +case 0x8668: +case 0x8669: +case 0x866a: +case 0x866b: +case 0x866c: +case 0x866d: +case 0x866e: +case 0x866f: +case 0x8868: +case 0x8869: +case 0x886a: +case 0x886b: +case 0x886c: +case 0x886d: +case 0x886e: +case 0x886f: +case 0x8a68: +case 0x8a69: +case 0x8a6a: +case 0x8a6b: +case 0x8a6c: +case 0x8a6d: +case 0x8a6e: +case 0x8a6f: +case 0x8c68: +case 0x8c69: +case 0x8c6a: +case 0x8c6b: +case 0x8c6c: +case 0x8c6d: +case 0x8c6e: +case 0x8c6f: +case 0x8e68: +case 0x8e69: +case 0x8e6a: +case 0x8e6b: +case 0x8e6c: +case 0x8e6d: +case 0x8e6e: +case 0x8e6f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9068: +case 0x9069: +case 0x906a: +case 0x906b: +case 0x906c: +case 0x906d: +case 0x906e: +case 0x906f: +case 0x9268: +case 0x9269: +case 0x926a: +case 0x926b: +case 0x926c: +case 0x926d: +case 0x926e: +case 0x926f: +case 0x9468: +case 0x9469: +case 0x946a: +case 0x946b: +case 0x946c: +case 0x946d: +case 0x946e: +case 0x946f: +case 0x9668: +case 0x9669: +case 0x966a: +case 0x966b: +case 0x966c: +case 0x966d: +case 0x966e: +case 0x966f: +case 0x9868: +case 0x9869: +case 0x986a: +case 0x986b: +case 0x986c: +case 0x986d: +case 0x986e: +case 0x986f: +case 0x9a68: +case 0x9a69: +case 0x9a6a: +case 0x9a6b: +case 0x9a6c: +case 0x9a6d: +case 0x9a6e: +case 0x9a6f: +case 0x9c68: +case 0x9c69: +case 0x9c6a: +case 0x9c6b: +case 0x9c6c: +case 0x9c6d: +case 0x9c6e: +case 0x9c6f: +case 0x9e68: +case 0x9e69: +case 0x9e6a: +case 0x9e6b: +case 0x9e6c: +case 0x9e6d: +case 0x9e6e: +case 0x9e6f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0xd0e8: +case 0xd0e9: +case 0xd0ea: +case 0xd0eb: +case 0xd0ec: +case 0xd0ed: +case 0xd0ee: +case 0xd0ef: +case 0xd2e8: +case 0xd2e9: +case 0xd2ea: +case 0xd2eb: +case 0xd2ec: +case 0xd2ed: +case 0xd2ee: +case 0xd2ef: +case 0xd4e8: +case 0xd4e9: +case 0xd4ea: +case 0xd4eb: +case 0xd4ec: +case 0xd4ed: +case 0xd4ee: +case 0xd4ef: +case 0xd6e8: +case 0xd6e9: +case 0xd6ea: +case 0xd6eb: +case 0xd6ec: +case 0xd6ed: +case 0xd6ee: +case 0xd6ef: +case 0xd8e8: +case 0xd8e9: +case 0xd8ea: +case 0xd8eb: +case 0xd8ec: +case 0xd8ed: +case 0xd8ee: +case 0xd8ef: +case 0xdae8: +case 0xdae9: +case 0xdaea: +case 0xdaeb: +case 0xdaec: +case 0xdaed: +case 0xdaee: +case 0xdaef: +case 0xdce8: +case 0xdce9: +case 0xdcea: +case 0xdceb: +case 0xdcec: +case 0xdced: +case 0xdcee: +case 0xdcef: +case 0xdee8: +case 0xdee9: +case 0xdeea: +case 0xdeeb: +case 0xdeec: +case 0xdeed: +case 0xdeee: +case 0xdeef: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb0e8: +case 0xb0e9: +case 0xb0ea: +case 0xb0eb: +case 0xb0ec: +case 0xb0ed: +case 0xb0ee: +case 0xb0ef: +case 0xb2e8: +case 0xb2e9: +case 0xb2ea: +case 0xb2eb: +case 0xb2ec: +case 0xb2ed: +case 0xb2ee: +case 0xb2ef: +case 0xb4e8: +case 0xb4e9: +case 0xb4ea: +case 0xb4eb: +case 0xb4ec: +case 0xb4ed: +case 0xb4ee: +case 0xb4ef: +case 0xb6e8: +case 0xb6e9: +case 0xb6ea: +case 0xb6eb: +case 0xb6ec: +case 0xb6ed: +case 0xb6ee: +case 0xb6ef: +case 0xb8e8: +case 0xb8e9: +case 0xb8ea: +case 0xb8eb: +case 0xb8ec: +case 0xb8ed: +case 0xb8ee: +case 0xb8ef: +case 0xbae8: +case 0xbae9: +case 0xbaea: +case 0xbaeb: +case 0xbaec: +case 0xbaed: +case 0xbaee: +case 0xbaef: +case 0xbce8: +case 0xbce9: +case 0xbcea: +case 0xbceb: +case 0xbcec: +case 0xbced: +case 0xbcee: +case 0xbcef: +case 0xbee8: +case 0xbee9: +case 0xbeea: +case 0xbeeb: +case 0xbeec: +case 0xbeed: +case 0xbeee: +case 0xbeef: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x90e8: +case 0x90e9: +case 0x90ea: +case 0x90eb: +case 0x90ec: +case 0x90ed: +case 0x90ee: +case 0x90ef: +case 0x92e8: +case 0x92e9: +case 0x92ea: +case 0x92eb: +case 0x92ec: +case 0x92ed: +case 0x92ee: +case 0x92ef: +case 0x94e8: +case 0x94e9: +case 0x94ea: +case 0x94eb: +case 0x94ec: +case 0x94ed: +case 0x94ee: +case 0x94ef: +case 0x96e8: +case 0x96e9: +case 0x96ea: +case 0x96eb: +case 0x96ec: +case 0x96ed: +case 0x96ee: +case 0x96ef: +case 0x98e8: +case 0x98e9: +case 0x98ea: +case 0x98eb: +case 0x98ec: +case 0x98ed: +case 0x98ee: +case 0x98ef: +case 0x9ae8: +case 0x9ae9: +case 0x9aea: +case 0x9aeb: +case 0x9aec: +case 0x9aed: +case 0x9aee: +case 0x9aef: +case 0x9ce8: +case 0x9ce9: +case 0x9cea: +case 0x9ceb: +case 0x9cec: +case 0x9ced: +case 0x9cee: +case 0x9cef: +case 0x9ee8: +case 0x9ee9: +case 0x9eea: +case 0x9eeb: +case 0x9eec: +case 0x9eed: +case 0x9eee: +case 0x9eef: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x3068: +case 0x3069: +case 0x306a: +case 0x306b: +case 0x306c: +case 0x306d: +case 0x306e: +case 0x306f: +case 0x3268: +case 0x3269: +case 0x326a: +case 0x326b: +case 0x326c: +case 0x326d: +case 0x326e: +case 0x326f: +case 0x3468: +case 0x3469: +case 0x346a: +case 0x346b: +case 0x346c: +case 0x346d: +case 0x346e: +case 0x346f: +case 0x3668: +case 0x3669: +case 0x366a: +case 0x366b: +case 0x366c: +case 0x366d: +case 0x366e: +case 0x366f: +case 0x3868: +case 0x3869: +case 0x386a: +case 0x386b: +case 0x386c: +case 0x386d: +case 0x386e: +case 0x386f: +case 0x3a68: +case 0x3a69: +case 0x3a6a: +case 0x3a6b: +case 0x3a6c: +case 0x3a6d: +case 0x3a6e: +case 0x3a6f: +case 0x3c68: +case 0x3c69: +case 0x3c6a: +case 0x3c6b: +case 0x3c6c: +case 0x3c6d: +case 0x3c6e: +case 0x3c6f: +case 0x3e68: +case 0x3e69: +case 0x3e6a: +case 0x3e6b: +case 0x3e6c: +case 0x3e6d: +case 0x3e6e: +case 0x3e6f: + { + HAM src(this, instr_b2_b0); MOVEA(src, instr_b11_b9); + } + break; + +case 0x44e8: +case 0x44e9: +case 0x44ea: +case 0x44eb: +case 0x44ec: +case 0x44ed: +case 0x44ee: +case 0x44ef: + { + HAM src(this, instr_b2_b0); MOVE_to_CCR(src); + } + break; + +case 0xc1e8: +case 0xc1e9: +case 0xc1ea: +case 0xc1eb: +case 0xc1ec: +case 0xc1ed: +case 0xc1ee: +case 0xc1ef: +case 0xc3e8: +case 0xc3e9: +case 0xc3ea: +case 0xc3eb: +case 0xc3ec: +case 0xc3ed: +case 0xc3ee: +case 0xc3ef: +case 0xc5e8: +case 0xc5e9: +case 0xc5ea: +case 0xc5eb: +case 0xc5ec: +case 0xc5ed: +case 0xc5ee: +case 0xc5ef: +case 0xc7e8: +case 0xc7e9: +case 0xc7ea: +case 0xc7eb: +case 0xc7ec: +case 0xc7ed: +case 0xc7ee: +case 0xc7ef: +case 0xc9e8: +case 0xc9e9: +case 0xc9ea: +case 0xc9eb: +case 0xc9ec: +case 0xc9ed: +case 0xc9ee: +case 0xc9ef: +case 0xcbe8: +case 0xcbe9: +case 0xcbea: +case 0xcbeb: +case 0xcbec: +case 0xcbed: +case 0xcbee: +case 0xcbef: +case 0xcde8: +case 0xcde9: +case 0xcdea: +case 0xcdeb: +case 0xcdec: +case 0xcded: +case 0xcdee: +case 0xcdef: +case 0xcfe8: +case 0xcfe9: +case 0xcfea: +case 0xcfeb: +case 0xcfec: +case 0xcfed: +case 0xcfee: +case 0xcfef: + { + HAM src(this, instr_b2_b0); MULS(src, instr_b11_b9); + } + break; + +case 0xc0e8: +case 0xc0e9: +case 0xc0ea: +case 0xc0eb: +case 0xc0ec: +case 0xc0ed: +case 0xc0ee: +case 0xc0ef: +case 0xc2e8: +case 0xc2e9: +case 0xc2ea: +case 0xc2eb: +case 0xc2ec: +case 0xc2ed: +case 0xc2ee: +case 0xc2ef: +case 0xc4e8: +case 0xc4e9: +case 0xc4ea: +case 0xc4eb: +case 0xc4ec: +case 0xc4ed: +case 0xc4ee: +case 0xc4ef: +case 0xc6e8: +case 0xc6e9: +case 0xc6ea: +case 0xc6eb: +case 0xc6ec: +case 0xc6ed: +case 0xc6ee: +case 0xc6ef: +case 0xc8e8: +case 0xc8e9: +case 0xc8ea: +case 0xc8eb: +case 0xc8ec: +case 0xc8ed: +case 0xc8ee: +case 0xc8ef: +case 0xcae8: +case 0xcae9: +case 0xcaea: +case 0xcaeb: +case 0xcaec: +case 0xcaed: +case 0xcaee: +case 0xcaef: +case 0xcce8: +case 0xcce9: +case 0xccea: +case 0xcceb: +case 0xccec: +case 0xcced: +case 0xccee: +case 0xccef: +case 0xcee8: +case 0xcee9: +case 0xceea: +case 0xceeb: +case 0xceec: +case 0xceed: +case 0xceee: +case 0xceef: + { + HAM src(this, instr_b2_b0); MULU(src, instr_b11_b9); + } + break; + +case 0xe1e8: +case 0xe1e9: +case 0xe1ea: +case 0xe1eb: +case 0xe1ec: +case 0xe1ed: +case 0xe1ee: +case 0xe1ef: + { + HAM targ(this, instr_b2_b0); ASL(targ, 1); + } + break; + +case 0xe0e8: +case 0xe0e9: +case 0xe0ea: +case 0xe0eb: +case 0xe0ec: +case 0xe0ed: +case 0xe0ee: +case 0xe0ef: + { + HAM targ(this, instr_b2_b0); ASR(targ, 1); + } + break; + +case 0xe3e8: +case 0xe3e9: +case 0xe3ea: +case 0xe3eb: +case 0xe3ec: +case 0xe3ed: +case 0xe3ee: +case 0xe3ef: + { + HAM targ(this, instr_b2_b0); LSL(targ, 1); + } + break; + +case 0xe2e8: +case 0xe2e9: +case 0xe2ea: +case 0xe2eb: +case 0xe2ec: +case 0xe2ed: +case 0xe2ee: +case 0xe2ef: + { + HAM targ(this, instr_b2_b0); LSR(targ, 1); + } + break; + +case 0xe7e8: +case 0xe7e9: +case 0xe7ea: +case 0xe7eb: +case 0xe7ec: +case 0xe7ed: +case 0xe7ee: +case 0xe7ef: + { + HAM targ(this, instr_b2_b0); ROL(targ, 1); + } + break; + +case 0xe6e8: +case 0xe6e9: +case 0xe6ea: +case 0xe6eb: +case 0xe6ec: +case 0xe6ed: +case 0xe6ee: +case 0xe6ef: + { + HAM targ(this, instr_b2_b0); ROR(targ, 1); + } + break; + +case 0xe5e8: +case 0xe5e9: +case 0xe5ea: +case 0xe5eb: +case 0xe5ec: +case 0xe5ed: +case 0xe5ee: +case 0xe5ef: + { + HAM targ(this, instr_b2_b0); ROXL(targ, 1); + } + break; + +case 0xe4e8: +case 0xe4e9: +case 0xe4ea: +case 0xe4eb: +case 0xe4ec: +case 0xe4ed: +case 0xe4ee: +case 0xe4ef: + { + HAM targ(this, instr_b2_b0); ROXR(targ, 1); + } + break; + +case 0x4270: +case 0x4271: +case 0x4272: +case 0x4273: +case 0x4274: +case 0x4275: +case 0x4276: +case 0x4277: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x4470: +case 0x4471: +case 0x4472: +case 0x4473: +case 0x4474: +case 0x4475: +case 0x4476: +case 0x4477: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x4070: +case 0x4071: +case 0x4072: +case 0x4073: +case 0x4074: +case 0x4075: +case 0x4076: +case 0x4077: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x4670: +case 0x4671: +case 0x4672: +case 0x4673: +case 0x4674: +case 0x4675: +case 0x4676: +case 0x4677: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x4a70: +case 0x4a71: +case 0x4a72: +case 0x4a73: +case 0x4a74: +case 0x4a75: +case 0x4a76: +case 0x4a77: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0x81f0: +case 0x81f1: +case 0x81f2: +case 0x81f3: +case 0x81f4: +case 0x81f5: +case 0x81f6: +case 0x81f7: +case 0x83f0: +case 0x83f1: +case 0x83f2: +case 0x83f3: +case 0x83f4: +case 0x83f5: +case 0x83f6: +case 0x83f7: +case 0x85f0: +case 0x85f1: +case 0x85f2: +case 0x85f3: +case 0x85f4: +case 0x85f5: +case 0x85f6: +case 0x85f7: +case 0x87f0: +case 0x87f1: +case 0x87f2: +case 0x87f3: +case 0x87f4: +case 0x87f5: +case 0x87f6: +case 0x87f7: +case 0x89f0: +case 0x89f1: +case 0x89f2: +case 0x89f3: +case 0x89f4: +case 0x89f5: +case 0x89f6: +case 0x89f7: +case 0x8bf0: +case 0x8bf1: +case 0x8bf2: +case 0x8bf3: +case 0x8bf4: +case 0x8bf5: +case 0x8bf6: +case 0x8bf7: +case 0x8df0: +case 0x8df1: +case 0x8df2: +case 0x8df3: +case 0x8df4: +case 0x8df5: +case 0x8df6: +case 0x8df7: +case 0x8ff0: +case 0x8ff1: +case 0x8ff2: +case 0x8ff3: +case 0x8ff4: +case 0x8ff5: +case 0x8ff6: +case 0x8ff7: + { + HAM src(this, instr_b2_b0); DIVS(src, instr_b11_b9); + } + break; + +case 0x80f0: +case 0x80f1: +case 0x80f2: +case 0x80f3: +case 0x80f4: +case 0x80f5: +case 0x80f6: +case 0x80f7: +case 0x82f0: +case 0x82f1: +case 0x82f2: +case 0x82f3: +case 0x82f4: +case 0x82f5: +case 0x82f6: +case 0x82f7: +case 0x84f0: +case 0x84f1: +case 0x84f2: +case 0x84f3: +case 0x84f4: +case 0x84f5: +case 0x84f6: +case 0x84f7: +case 0x86f0: +case 0x86f1: +case 0x86f2: +case 0x86f3: +case 0x86f4: +case 0x86f5: +case 0x86f6: +case 0x86f7: +case 0x88f0: +case 0x88f1: +case 0x88f2: +case 0x88f3: +case 0x88f4: +case 0x88f5: +case 0x88f6: +case 0x88f7: +case 0x8af0: +case 0x8af1: +case 0x8af2: +case 0x8af3: +case 0x8af4: +case 0x8af5: +case 0x8af6: +case 0x8af7: +case 0x8cf0: +case 0x8cf1: +case 0x8cf2: +case 0x8cf3: +case 0x8cf4: +case 0x8cf5: +case 0x8cf6: +case 0x8cf7: +case 0x8ef0: +case 0x8ef1: +case 0x8ef2: +case 0x8ef3: +case 0x8ef4: +case 0x8ef5: +case 0x8ef6: +case 0x8ef7: + { + HAM src(this, instr_b2_b0); DIVU(src, instr_b11_b9); + } + break; + +case 0x33f0: +case 0x33f1: +case 0x33f2: +case 0x33f3: +case 0x33f4: +case 0x33f5: +case 0x33f6: +case 0x33f7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x31f0: +case 0x31f1: +case 0x31f2: +case 0x31f3: +case 0x31f4: +case 0x31f5: +case 0x31f6: +case 0x31f7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x30b0: +case 0x30b1: +case 0x30b2: +case 0x30b3: +case 0x30b4: +case 0x30b5: +case 0x30b6: +case 0x30b7: +case 0x32b0: +case 0x32b1: +case 0x32b2: +case 0x32b3: +case 0x32b4: +case 0x32b5: +case 0x32b6: +case 0x32b7: +case 0x34b0: +case 0x34b1: +case 0x34b2: +case 0x34b3: +case 0x34b4: +case 0x34b5: +case 0x34b6: +case 0x34b7: +case 0x36b0: +case 0x36b1: +case 0x36b2: +case 0x36b3: +case 0x36b4: +case 0x36b5: +case 0x36b6: +case 0x36b7: +case 0x38b0: +case 0x38b1: +case 0x38b2: +case 0x38b3: +case 0x38b4: +case 0x38b5: +case 0x38b6: +case 0x38b7: +case 0x3ab0: +case 0x3ab1: +case 0x3ab2: +case 0x3ab3: +case 0x3ab4: +case 0x3ab5: +case 0x3ab6: +case 0x3ab7: +case 0x3cb0: +case 0x3cb1: +case 0x3cb2: +case 0x3cb3: +case 0x3cb4: +case 0x3cb5: +case 0x3cb6: +case 0x3cb7: +case 0x3eb0: +case 0x3eb1: +case 0x3eb2: +case 0x3eb3: +case 0x3eb4: +case 0x3eb5: +case 0x3eb6: +case 0x3eb7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3170: +case 0x3171: +case 0x3172: +case 0x3173: +case 0x3174: +case 0x3175: +case 0x3176: +case 0x3177: +case 0x3370: +case 0x3371: +case 0x3372: +case 0x3373: +case 0x3374: +case 0x3375: +case 0x3376: +case 0x3377: +case 0x3570: +case 0x3571: +case 0x3572: +case 0x3573: +case 0x3574: +case 0x3575: +case 0x3576: +case 0x3577: +case 0x3770: +case 0x3771: +case 0x3772: +case 0x3773: +case 0x3774: +case 0x3775: +case 0x3776: +case 0x3777: +case 0x3970: +case 0x3971: +case 0x3972: +case 0x3973: +case 0x3974: +case 0x3975: +case 0x3976: +case 0x3977: +case 0x3b70: +case 0x3b71: +case 0x3b72: +case 0x3b73: +case 0x3b74: +case 0x3b75: +case 0x3b76: +case 0x3b77: +case 0x3d70: +case 0x3d71: +case 0x3d72: +case 0x3d73: +case 0x3d74: +case 0x3d75: +case 0x3d76: +case 0x3d77: +case 0x3f70: +case 0x3f71: +case 0x3f72: +case 0x3f73: +case 0x3f74: +case 0x3f75: +case 0x3f76: +case 0x3f77: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x31b0: +case 0x31b1: +case 0x31b2: +case 0x31b3: +case 0x31b4: +case 0x31b5: +case 0x31b6: +case 0x31b7: +case 0x33b0: +case 0x33b1: +case 0x33b2: +case 0x33b3: +case 0x33b4: +case 0x33b5: +case 0x33b6: +case 0x33b7: +case 0x35b0: +case 0x35b1: +case 0x35b2: +case 0x35b3: +case 0x35b4: +case 0x35b5: +case 0x35b6: +case 0x35b7: +case 0x37b0: +case 0x37b1: +case 0x37b2: +case 0x37b3: +case 0x37b4: +case 0x37b5: +case 0x37b6: +case 0x37b7: +case 0x39b0: +case 0x39b1: +case 0x39b2: +case 0x39b3: +case 0x39b4: +case 0x39b5: +case 0x39b6: +case 0x39b7: +case 0x3bb0: +case 0x3bb1: +case 0x3bb2: +case 0x3bb3: +case 0x3bb4: +case 0x3bb5: +case 0x3bb6: +case 0x3bb7: +case 0x3db0: +case 0x3db1: +case 0x3db2: +case 0x3db3: +case 0x3db4: +case 0x3db5: +case 0x3db6: +case 0x3db7: +case 0x3fb0: +case 0x3fb1: +case 0x3fb2: +case 0x3fb3: +case 0x3fb4: +case 0x3fb5: +case 0x3fb6: +case 0x3fb7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x30f0: +case 0x30f1: +case 0x30f2: +case 0x30f3: +case 0x30f4: +case 0x30f5: +case 0x30f6: +case 0x30f7: +case 0x32f0: +case 0x32f1: +case 0x32f2: +case 0x32f3: +case 0x32f4: +case 0x32f5: +case 0x32f6: +case 0x32f7: +case 0x34f0: +case 0x34f1: +case 0x34f2: +case 0x34f3: +case 0x34f4: +case 0x34f5: +case 0x34f6: +case 0x34f7: +case 0x36f0: +case 0x36f1: +case 0x36f2: +case 0x36f3: +case 0x36f4: +case 0x36f5: +case 0x36f6: +case 0x36f7: +case 0x38f0: +case 0x38f1: +case 0x38f2: +case 0x38f3: +case 0x38f4: +case 0x38f5: +case 0x38f6: +case 0x38f7: +case 0x3af0: +case 0x3af1: +case 0x3af2: +case 0x3af3: +case 0x3af4: +case 0x3af5: +case 0x3af6: +case 0x3af7: +case 0x3cf0: +case 0x3cf1: +case 0x3cf2: +case 0x3cf3: +case 0x3cf4: +case 0x3cf5: +case 0x3cf6: +case 0x3cf7: +case 0x3ef0: +case 0x3ef1: +case 0x3ef2: +case 0x3ef3: +case 0x3ef4: +case 0x3ef5: +case 0x3ef6: +case 0x3ef7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3130: +case 0x3131: +case 0x3132: +case 0x3133: +case 0x3134: +case 0x3135: +case 0x3136: +case 0x3137: +case 0x3330: +case 0x3331: +case 0x3332: +case 0x3333: +case 0x3334: +case 0x3335: +case 0x3336: +case 0x3337: +case 0x3530: +case 0x3531: +case 0x3532: +case 0x3533: +case 0x3534: +case 0x3535: +case 0x3536: +case 0x3537: +case 0x3730: +case 0x3731: +case 0x3732: +case 0x3733: +case 0x3734: +case 0x3735: +case 0x3736: +case 0x3737: +case 0x3930: +case 0x3931: +case 0x3932: +case 0x3933: +case 0x3934: +case 0x3935: +case 0x3936: +case 0x3937: +case 0x3b30: +case 0x3b31: +case 0x3b32: +case 0x3b33: +case 0x3b34: +case 0x3b35: +case 0x3b36: +case 0x3b37: +case 0x3d30: +case 0x3d31: +case 0x3d32: +case 0x3d33: +case 0x3d34: +case 0x3d35: +case 0x3d36: +case 0x3d37: +case 0x3f30: +case 0x3f31: +case 0x3f32: +case 0x3f33: +case 0x3f34: +case 0x3f35: +case 0x3f36: +case 0x3f37: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd070: +case 0xd071: +case 0xd072: +case 0xd073: +case 0xd074: +case 0xd075: +case 0xd076: +case 0xd077: +case 0xd270: +case 0xd271: +case 0xd272: +case 0xd273: +case 0xd274: +case 0xd275: +case 0xd276: +case 0xd277: +case 0xd470: +case 0xd471: +case 0xd472: +case 0xd473: +case 0xd474: +case 0xd475: +case 0xd476: +case 0xd477: +case 0xd670: +case 0xd671: +case 0xd672: +case 0xd673: +case 0xd674: +case 0xd675: +case 0xd676: +case 0xd677: +case 0xd870: +case 0xd871: +case 0xd872: +case 0xd873: +case 0xd874: +case 0xd875: +case 0xd876: +case 0xd877: +case 0xda70: +case 0xda71: +case 0xda72: +case 0xda73: +case 0xda74: +case 0xda75: +case 0xda76: +case 0xda77: +case 0xdc70: +case 0xdc71: +case 0xdc72: +case 0xdc73: +case 0xdc74: +case 0xdc75: +case 0xdc76: +case 0xdc77: +case 0xde70: +case 0xde71: +case 0xde72: +case 0xde73: +case 0xde74: +case 0xde75: +case 0xde76: +case 0xde77: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc070: +case 0xc071: +case 0xc072: +case 0xc073: +case 0xc074: +case 0xc075: +case 0xc076: +case 0xc077: +case 0xc270: +case 0xc271: +case 0xc272: +case 0xc273: +case 0xc274: +case 0xc275: +case 0xc276: +case 0xc277: +case 0xc470: +case 0xc471: +case 0xc472: +case 0xc473: +case 0xc474: +case 0xc475: +case 0xc476: +case 0xc477: +case 0xc670: +case 0xc671: +case 0xc672: +case 0xc673: +case 0xc674: +case 0xc675: +case 0xc676: +case 0xc677: +case 0xc870: +case 0xc871: +case 0xc872: +case 0xc873: +case 0xc874: +case 0xc875: +case 0xc876: +case 0xc877: +case 0xca70: +case 0xca71: +case 0xca72: +case 0xca73: +case 0xca74: +case 0xca75: +case 0xca76: +case 0xca77: +case 0xcc70: +case 0xcc71: +case 0xcc72: +case 0xcc73: +case 0xcc74: +case 0xcc75: +case 0xcc76: +case 0xcc77: +case 0xce70: +case 0xce71: +case 0xce72: +case 0xce73: +case 0xce74: +case 0xce75: +case 0xce76: +case 0xce77: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0x41b0: +case 0x41b1: +case 0x41b2: +case 0x41b3: +case 0x41b4: +case 0x41b5: +case 0x41b6: +case 0x41b7: +case 0x43b0: +case 0x43b1: +case 0x43b2: +case 0x43b3: +case 0x43b4: +case 0x43b5: +case 0x43b6: +case 0x43b7: +case 0x45b0: +case 0x45b1: +case 0x45b2: +case 0x45b3: +case 0x45b4: +case 0x45b5: +case 0x45b6: +case 0x45b7: +case 0x47b0: +case 0x47b1: +case 0x47b2: +case 0x47b3: +case 0x47b4: +case 0x47b5: +case 0x47b6: +case 0x47b7: +case 0x49b0: +case 0x49b1: +case 0x49b2: +case 0x49b3: +case 0x49b4: +case 0x49b5: +case 0x49b6: +case 0x49b7: +case 0x4bb0: +case 0x4bb1: +case 0x4bb2: +case 0x4bb3: +case 0x4bb4: +case 0x4bb5: +case 0x4bb6: +case 0x4bb7: +case 0x4db0: +case 0x4db1: +case 0x4db2: +case 0x4db3: +case 0x4db4: +case 0x4db5: +case 0x4db6: +case 0x4db7: +case 0x4fb0: +case 0x4fb1: +case 0x4fb2: +case 0x4fb3: +case 0x4fb4: +case 0x4fb5: +case 0x4fb6: +case 0x4fb7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CHK(src, dst); + } + break; + +case 0xb070: +case 0xb071: +case 0xb072: +case 0xb073: +case 0xb074: +case 0xb075: +case 0xb076: +case 0xb077: +case 0xb270: +case 0xb271: +case 0xb272: +case 0xb273: +case 0xb274: +case 0xb275: +case 0xb276: +case 0xb277: +case 0xb470: +case 0xb471: +case 0xb472: +case 0xb473: +case 0xb474: +case 0xb475: +case 0xb476: +case 0xb477: +case 0xb670: +case 0xb671: +case 0xb672: +case 0xb673: +case 0xb674: +case 0xb675: +case 0xb676: +case 0xb677: +case 0xb870: +case 0xb871: +case 0xb872: +case 0xb873: +case 0xb874: +case 0xb875: +case 0xb876: +case 0xb877: +case 0xba70: +case 0xba71: +case 0xba72: +case 0xba73: +case 0xba74: +case 0xba75: +case 0xba76: +case 0xba77: +case 0xbc70: +case 0xbc71: +case 0xbc72: +case 0xbc73: +case 0xbc74: +case 0xbc75: +case 0xbc76: +case 0xbc77: +case 0xbe70: +case 0xbe71: +case 0xbe72: +case 0xbe73: +case 0xbe74: +case 0xbe75: +case 0xbe76: +case 0xbe77: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x3030: +case 0x3031: +case 0x3032: +case 0x3033: +case 0x3034: +case 0x3035: +case 0x3036: +case 0x3037: +case 0x3230: +case 0x3231: +case 0x3232: +case 0x3233: +case 0x3234: +case 0x3235: +case 0x3236: +case 0x3237: +case 0x3430: +case 0x3431: +case 0x3432: +case 0x3433: +case 0x3434: +case 0x3435: +case 0x3436: +case 0x3437: +case 0x3630: +case 0x3631: +case 0x3632: +case 0x3633: +case 0x3634: +case 0x3635: +case 0x3636: +case 0x3637: +case 0x3830: +case 0x3831: +case 0x3832: +case 0x3833: +case 0x3834: +case 0x3835: +case 0x3836: +case 0x3837: +case 0x3a30: +case 0x3a31: +case 0x3a32: +case 0x3a33: +case 0x3a34: +case 0x3a35: +case 0x3a36: +case 0x3a37: +case 0x3c30: +case 0x3c31: +case 0x3c32: +case 0x3c33: +case 0x3c34: +case 0x3c35: +case 0x3c36: +case 0x3c37: +case 0x3e30: +case 0x3e31: +case 0x3e32: +case 0x3e33: +case 0x3e34: +case 0x3e35: +case 0x3e36: +case 0x3e37: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8070: +case 0x8071: +case 0x8072: +case 0x8073: +case 0x8074: +case 0x8075: +case 0x8076: +case 0x8077: +case 0x8270: +case 0x8271: +case 0x8272: +case 0x8273: +case 0x8274: +case 0x8275: +case 0x8276: +case 0x8277: +case 0x8470: +case 0x8471: +case 0x8472: +case 0x8473: +case 0x8474: +case 0x8475: +case 0x8476: +case 0x8477: +case 0x8670: +case 0x8671: +case 0x8672: +case 0x8673: +case 0x8674: +case 0x8675: +case 0x8676: +case 0x8677: +case 0x8870: +case 0x8871: +case 0x8872: +case 0x8873: +case 0x8874: +case 0x8875: +case 0x8876: +case 0x8877: +case 0x8a70: +case 0x8a71: +case 0x8a72: +case 0x8a73: +case 0x8a74: +case 0x8a75: +case 0x8a76: +case 0x8a77: +case 0x8c70: +case 0x8c71: +case 0x8c72: +case 0x8c73: +case 0x8c74: +case 0x8c75: +case 0x8c76: +case 0x8c77: +case 0x8e70: +case 0x8e71: +case 0x8e72: +case 0x8e73: +case 0x8e74: +case 0x8e75: +case 0x8e76: +case 0x8e77: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9070: +case 0x9071: +case 0x9072: +case 0x9073: +case 0x9074: +case 0x9075: +case 0x9076: +case 0x9077: +case 0x9270: +case 0x9271: +case 0x9272: +case 0x9273: +case 0x9274: +case 0x9275: +case 0x9276: +case 0x9277: +case 0x9470: +case 0x9471: +case 0x9472: +case 0x9473: +case 0x9474: +case 0x9475: +case 0x9476: +case 0x9477: +case 0x9670: +case 0x9671: +case 0x9672: +case 0x9673: +case 0x9674: +case 0x9675: +case 0x9676: +case 0x9677: +case 0x9870: +case 0x9871: +case 0x9872: +case 0x9873: +case 0x9874: +case 0x9875: +case 0x9876: +case 0x9877: +case 0x9a70: +case 0x9a71: +case 0x9a72: +case 0x9a73: +case 0x9a74: +case 0x9a75: +case 0x9a76: +case 0x9a77: +case 0x9c70: +case 0x9c71: +case 0x9c72: +case 0x9c73: +case 0x9c74: +case 0x9c75: +case 0x9c76: +case 0x9c77: +case 0x9e70: +case 0x9e71: +case 0x9e72: +case 0x9e73: +case 0x9e74: +case 0x9e75: +case 0x9e76: +case 0x9e77: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0xd0f0: +case 0xd0f1: +case 0xd0f2: +case 0xd0f3: +case 0xd0f4: +case 0xd0f5: +case 0xd0f6: +case 0xd0f7: +case 0xd2f0: +case 0xd2f1: +case 0xd2f2: +case 0xd2f3: +case 0xd2f4: +case 0xd2f5: +case 0xd2f6: +case 0xd2f7: +case 0xd4f0: +case 0xd4f1: +case 0xd4f2: +case 0xd4f3: +case 0xd4f4: +case 0xd4f5: +case 0xd4f6: +case 0xd4f7: +case 0xd6f0: +case 0xd6f1: +case 0xd6f2: +case 0xd6f3: +case 0xd6f4: +case 0xd6f5: +case 0xd6f6: +case 0xd6f7: +case 0xd8f0: +case 0xd8f1: +case 0xd8f2: +case 0xd8f3: +case 0xd8f4: +case 0xd8f5: +case 0xd8f6: +case 0xd8f7: +case 0xdaf0: +case 0xdaf1: +case 0xdaf2: +case 0xdaf3: +case 0xdaf4: +case 0xdaf5: +case 0xdaf6: +case 0xdaf7: +case 0xdcf0: +case 0xdcf1: +case 0xdcf2: +case 0xdcf3: +case 0xdcf4: +case 0xdcf5: +case 0xdcf6: +case 0xdcf7: +case 0xdef0: +case 0xdef1: +case 0xdef2: +case 0xdef3: +case 0xdef4: +case 0xdef5: +case 0xdef6: +case 0xdef7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb0f0: +case 0xb0f1: +case 0xb0f2: +case 0xb0f3: +case 0xb0f4: +case 0xb0f5: +case 0xb0f6: +case 0xb0f7: +case 0xb2f0: +case 0xb2f1: +case 0xb2f2: +case 0xb2f3: +case 0xb2f4: +case 0xb2f5: +case 0xb2f6: +case 0xb2f7: +case 0xb4f0: +case 0xb4f1: +case 0xb4f2: +case 0xb4f3: +case 0xb4f4: +case 0xb4f5: +case 0xb4f6: +case 0xb4f7: +case 0xb6f0: +case 0xb6f1: +case 0xb6f2: +case 0xb6f3: +case 0xb6f4: +case 0xb6f5: +case 0xb6f6: +case 0xb6f7: +case 0xb8f0: +case 0xb8f1: +case 0xb8f2: +case 0xb8f3: +case 0xb8f4: +case 0xb8f5: +case 0xb8f6: +case 0xb8f7: +case 0xbaf0: +case 0xbaf1: +case 0xbaf2: +case 0xbaf3: +case 0xbaf4: +case 0xbaf5: +case 0xbaf6: +case 0xbaf7: +case 0xbcf0: +case 0xbcf1: +case 0xbcf2: +case 0xbcf3: +case 0xbcf4: +case 0xbcf5: +case 0xbcf6: +case 0xbcf7: +case 0xbef0: +case 0xbef1: +case 0xbef2: +case 0xbef3: +case 0xbef4: +case 0xbef5: +case 0xbef6: +case 0xbef7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x90f0: +case 0x90f1: +case 0x90f2: +case 0x90f3: +case 0x90f4: +case 0x90f5: +case 0x90f6: +case 0x90f7: +case 0x92f0: +case 0x92f1: +case 0x92f2: +case 0x92f3: +case 0x92f4: +case 0x92f5: +case 0x92f6: +case 0x92f7: +case 0x94f0: +case 0x94f1: +case 0x94f2: +case 0x94f3: +case 0x94f4: +case 0x94f5: +case 0x94f6: +case 0x94f7: +case 0x96f0: +case 0x96f1: +case 0x96f2: +case 0x96f3: +case 0x96f4: +case 0x96f5: +case 0x96f6: +case 0x96f7: +case 0x98f0: +case 0x98f1: +case 0x98f2: +case 0x98f3: +case 0x98f4: +case 0x98f5: +case 0x98f6: +case 0x98f7: +case 0x9af0: +case 0x9af1: +case 0x9af2: +case 0x9af3: +case 0x9af4: +case 0x9af5: +case 0x9af6: +case 0x9af7: +case 0x9cf0: +case 0x9cf1: +case 0x9cf2: +case 0x9cf3: +case 0x9cf4: +case 0x9cf5: +case 0x9cf6: +case 0x9cf7: +case 0x9ef0: +case 0x9ef1: +case 0x9ef2: +case 0x9ef3: +case 0x9ef4: +case 0x9ef5: +case 0x9ef6: +case 0x9ef7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x3070: +case 0x3071: +case 0x3072: +case 0x3073: +case 0x3074: +case 0x3075: +case 0x3076: +case 0x3077: +case 0x3270: +case 0x3271: +case 0x3272: +case 0x3273: +case 0x3274: +case 0x3275: +case 0x3276: +case 0x3277: +case 0x3470: +case 0x3471: +case 0x3472: +case 0x3473: +case 0x3474: +case 0x3475: +case 0x3476: +case 0x3477: +case 0x3670: +case 0x3671: +case 0x3672: +case 0x3673: +case 0x3674: +case 0x3675: +case 0x3676: +case 0x3677: +case 0x3870: +case 0x3871: +case 0x3872: +case 0x3873: +case 0x3874: +case 0x3875: +case 0x3876: +case 0x3877: +case 0x3a70: +case 0x3a71: +case 0x3a72: +case 0x3a73: +case 0x3a74: +case 0x3a75: +case 0x3a76: +case 0x3a77: +case 0x3c70: +case 0x3c71: +case 0x3c72: +case 0x3c73: +case 0x3c74: +case 0x3c75: +case 0x3c76: +case 0x3c77: +case 0x3e70: +case 0x3e71: +case 0x3e72: +case 0x3e73: +case 0x3e74: +case 0x3e75: +case 0x3e76: +case 0x3e77: + { + HAM src(this, instr_b2_b0); MOVEA(src, instr_b11_b9); + } + break; + +case 0x44f0: +case 0x44f1: +case 0x44f2: +case 0x44f3: +case 0x44f4: +case 0x44f5: +case 0x44f6: +case 0x44f7: + { + HAM src(this, instr_b2_b0); MOVE_to_CCR(src); + } + break; + +case 0xc1f0: +case 0xc1f1: +case 0xc1f2: +case 0xc1f3: +case 0xc1f4: +case 0xc1f5: +case 0xc1f6: +case 0xc1f7: +case 0xc3f0: +case 0xc3f1: +case 0xc3f2: +case 0xc3f3: +case 0xc3f4: +case 0xc3f5: +case 0xc3f6: +case 0xc3f7: +case 0xc5f0: +case 0xc5f1: +case 0xc5f2: +case 0xc5f3: +case 0xc5f4: +case 0xc5f5: +case 0xc5f6: +case 0xc5f7: +case 0xc7f0: +case 0xc7f1: +case 0xc7f2: +case 0xc7f3: +case 0xc7f4: +case 0xc7f5: +case 0xc7f6: +case 0xc7f7: +case 0xc9f0: +case 0xc9f1: +case 0xc9f2: +case 0xc9f3: +case 0xc9f4: +case 0xc9f5: +case 0xc9f6: +case 0xc9f7: +case 0xcbf0: +case 0xcbf1: +case 0xcbf2: +case 0xcbf3: +case 0xcbf4: +case 0xcbf5: +case 0xcbf6: +case 0xcbf7: +case 0xcdf0: +case 0xcdf1: +case 0xcdf2: +case 0xcdf3: +case 0xcdf4: +case 0xcdf5: +case 0xcdf6: +case 0xcdf7: +case 0xcff0: +case 0xcff1: +case 0xcff2: +case 0xcff3: +case 0xcff4: +case 0xcff5: +case 0xcff6: +case 0xcff7: + { + HAM src(this, instr_b2_b0); MULS(src, instr_b11_b9); + } + break; + +case 0xc0f0: +case 0xc0f1: +case 0xc0f2: +case 0xc0f3: +case 0xc0f4: +case 0xc0f5: +case 0xc0f6: +case 0xc0f7: +case 0xc2f0: +case 0xc2f1: +case 0xc2f2: +case 0xc2f3: +case 0xc2f4: +case 0xc2f5: +case 0xc2f6: +case 0xc2f7: +case 0xc4f0: +case 0xc4f1: +case 0xc4f2: +case 0xc4f3: +case 0xc4f4: +case 0xc4f5: +case 0xc4f6: +case 0xc4f7: +case 0xc6f0: +case 0xc6f1: +case 0xc6f2: +case 0xc6f3: +case 0xc6f4: +case 0xc6f5: +case 0xc6f6: +case 0xc6f7: +case 0xc8f0: +case 0xc8f1: +case 0xc8f2: +case 0xc8f3: +case 0xc8f4: +case 0xc8f5: +case 0xc8f6: +case 0xc8f7: +case 0xcaf0: +case 0xcaf1: +case 0xcaf2: +case 0xcaf3: +case 0xcaf4: +case 0xcaf5: +case 0xcaf6: +case 0xcaf7: +case 0xccf0: +case 0xccf1: +case 0xccf2: +case 0xccf3: +case 0xccf4: +case 0xccf5: +case 0xccf6: +case 0xccf7: +case 0xcef0: +case 0xcef1: +case 0xcef2: +case 0xcef3: +case 0xcef4: +case 0xcef5: +case 0xcef6: +case 0xcef7: + { + HAM src(this, instr_b2_b0); MULU(src, instr_b11_b9); + } + break; + +case 0xe1f0: +case 0xe1f1: +case 0xe1f2: +case 0xe1f3: +case 0xe1f4: +case 0xe1f5: +case 0xe1f6: +case 0xe1f7: + { + HAM targ(this, instr_b2_b0); ASL(targ, 1); + } + break; + +case 0xe0f0: +case 0xe0f1: +case 0xe0f2: +case 0xe0f3: +case 0xe0f4: +case 0xe0f5: +case 0xe0f6: +case 0xe0f7: + { + HAM targ(this, instr_b2_b0); ASR(targ, 1); + } + break; + +case 0xe3f0: +case 0xe3f1: +case 0xe3f2: +case 0xe3f3: +case 0xe3f4: +case 0xe3f5: +case 0xe3f6: +case 0xe3f7: + { + HAM targ(this, instr_b2_b0); LSL(targ, 1); + } + break; + +case 0xe2f0: +case 0xe2f1: +case 0xe2f2: +case 0xe2f3: +case 0xe2f4: +case 0xe2f5: +case 0xe2f6: +case 0xe2f7: + { + HAM targ(this, instr_b2_b0); LSR(targ, 1); + } + break; + +case 0xe7f0: +case 0xe7f1: +case 0xe7f2: +case 0xe7f3: +case 0xe7f4: +case 0xe7f5: +case 0xe7f6: +case 0xe7f7: + { + HAM targ(this, instr_b2_b0); ROL(targ, 1); + } + break; + +case 0xe6f0: +case 0xe6f1: +case 0xe6f2: +case 0xe6f3: +case 0xe6f4: +case 0xe6f5: +case 0xe6f6: +case 0xe6f7: + { + HAM targ(this, instr_b2_b0); ROR(targ, 1); + } + break; + +case 0xe5f0: +case 0xe5f1: +case 0xe5f2: +case 0xe5f3: +case 0xe5f4: +case 0xe5f5: +case 0xe5f6: +case 0xe5f7: + { + HAM targ(this, instr_b2_b0); ROXL(targ, 1); + } + break; + +case 0xe4f0: +case 0xe4f1: +case 0xe4f2: +case 0xe4f3: +case 0xe4f4: +case 0xe4f5: +case 0xe4f6: +case 0xe4f7: + { + HAM targ(this, instr_b2_b0); ROXR(targ, 1); + } + break; + +case 0x4258: +case 0x4259: +case 0x425a: +case 0x425b: +case 0x425c: +case 0x425d: +case 0x425e: +case 0x425f: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x4458: +case 0x4459: +case 0x445a: +case 0x445b: +case 0x445c: +case 0x445d: +case 0x445e: +case 0x445f: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x4058: +case 0x4059: +case 0x405a: +case 0x405b: +case 0x405c: +case 0x405d: +case 0x405e: +case 0x405f: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x4658: +case 0x4659: +case 0x465a: +case 0x465b: +case 0x465c: +case 0x465d: +case 0x465e: +case 0x465f: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x4a58: +case 0x4a59: +case 0x4a5a: +case 0x4a5b: +case 0x4a5c: +case 0x4a5d: +case 0x4a5e: +case 0x4a5f: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0x81d8: +case 0x81d9: +case 0x81da: +case 0x81db: +case 0x81dc: +case 0x81dd: +case 0x81de: +case 0x81df: +case 0x83d8: +case 0x83d9: +case 0x83da: +case 0x83db: +case 0x83dc: +case 0x83dd: +case 0x83de: +case 0x83df: +case 0x85d8: +case 0x85d9: +case 0x85da: +case 0x85db: +case 0x85dc: +case 0x85dd: +case 0x85de: +case 0x85df: +case 0x87d8: +case 0x87d9: +case 0x87da: +case 0x87db: +case 0x87dc: +case 0x87dd: +case 0x87de: +case 0x87df: +case 0x89d8: +case 0x89d9: +case 0x89da: +case 0x89db: +case 0x89dc: +case 0x89dd: +case 0x89de: +case 0x89df: +case 0x8bd8: +case 0x8bd9: +case 0x8bda: +case 0x8bdb: +case 0x8bdc: +case 0x8bdd: +case 0x8bde: +case 0x8bdf: +case 0x8dd8: +case 0x8dd9: +case 0x8dda: +case 0x8ddb: +case 0x8ddc: +case 0x8ddd: +case 0x8dde: +case 0x8ddf: +case 0x8fd8: +case 0x8fd9: +case 0x8fda: +case 0x8fdb: +case 0x8fdc: +case 0x8fdd: +case 0x8fde: +case 0x8fdf: + { + HAM src(this, instr_b2_b0); DIVS(src, instr_b11_b9); + } + break; + +case 0x80d8: +case 0x80d9: +case 0x80da: +case 0x80db: +case 0x80dc: +case 0x80dd: +case 0x80de: +case 0x80df: +case 0x82d8: +case 0x82d9: +case 0x82da: +case 0x82db: +case 0x82dc: +case 0x82dd: +case 0x82de: +case 0x82df: +case 0x84d8: +case 0x84d9: +case 0x84da: +case 0x84db: +case 0x84dc: +case 0x84dd: +case 0x84de: +case 0x84df: +case 0x86d8: +case 0x86d9: +case 0x86da: +case 0x86db: +case 0x86dc: +case 0x86dd: +case 0x86de: +case 0x86df: +case 0x88d8: +case 0x88d9: +case 0x88da: +case 0x88db: +case 0x88dc: +case 0x88dd: +case 0x88de: +case 0x88df: +case 0x8ad8: +case 0x8ad9: +case 0x8ada: +case 0x8adb: +case 0x8adc: +case 0x8add: +case 0x8ade: +case 0x8adf: +case 0x8cd8: +case 0x8cd9: +case 0x8cda: +case 0x8cdb: +case 0x8cdc: +case 0x8cdd: +case 0x8cde: +case 0x8cdf: +case 0x8ed8: +case 0x8ed9: +case 0x8eda: +case 0x8edb: +case 0x8edc: +case 0x8edd: +case 0x8ede: +case 0x8edf: + { + HAM src(this, instr_b2_b0); DIVU(src, instr_b11_b9); + } + break; + +case 0x33d8: +case 0x33d9: +case 0x33da: +case 0x33db: +case 0x33dc: +case 0x33dd: +case 0x33de: +case 0x33df: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x31d8: +case 0x31d9: +case 0x31da: +case 0x31db: +case 0x31dc: +case 0x31dd: +case 0x31de: +case 0x31df: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x3098: +case 0x3099: +case 0x309a: +case 0x309b: +case 0x309c: +case 0x309d: +case 0x309e: +case 0x309f: +case 0x3298: +case 0x3299: +case 0x329a: +case 0x329b: +case 0x329c: +case 0x329d: +case 0x329e: +case 0x329f: +case 0x3498: +case 0x3499: +case 0x349a: +case 0x349b: +case 0x349c: +case 0x349d: +case 0x349e: +case 0x349f: +case 0x3698: +case 0x3699: +case 0x369a: +case 0x369b: +case 0x369c: +case 0x369d: +case 0x369e: +case 0x369f: +case 0x3898: +case 0x3899: +case 0x389a: +case 0x389b: +case 0x389c: +case 0x389d: +case 0x389e: +case 0x389f: +case 0x3a98: +case 0x3a99: +case 0x3a9a: +case 0x3a9b: +case 0x3a9c: +case 0x3a9d: +case 0x3a9e: +case 0x3a9f: +case 0x3c98: +case 0x3c99: +case 0x3c9a: +case 0x3c9b: +case 0x3c9c: +case 0x3c9d: +case 0x3c9e: +case 0x3c9f: +case 0x3e98: +case 0x3e99: +case 0x3e9a: +case 0x3e9b: +case 0x3e9c: +case 0x3e9d: +case 0x3e9e: +case 0x3e9f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3158: +case 0x3159: +case 0x315a: +case 0x315b: +case 0x315c: +case 0x315d: +case 0x315e: +case 0x315f: +case 0x3358: +case 0x3359: +case 0x335a: +case 0x335b: +case 0x335c: +case 0x335d: +case 0x335e: +case 0x335f: +case 0x3558: +case 0x3559: +case 0x355a: +case 0x355b: +case 0x355c: +case 0x355d: +case 0x355e: +case 0x355f: +case 0x3758: +case 0x3759: +case 0x375a: +case 0x375b: +case 0x375c: +case 0x375d: +case 0x375e: +case 0x375f: +case 0x3958: +case 0x3959: +case 0x395a: +case 0x395b: +case 0x395c: +case 0x395d: +case 0x395e: +case 0x395f: +case 0x3b58: +case 0x3b59: +case 0x3b5a: +case 0x3b5b: +case 0x3b5c: +case 0x3b5d: +case 0x3b5e: +case 0x3b5f: +case 0x3d58: +case 0x3d59: +case 0x3d5a: +case 0x3d5b: +case 0x3d5c: +case 0x3d5d: +case 0x3d5e: +case 0x3d5f: +case 0x3f58: +case 0x3f59: +case 0x3f5a: +case 0x3f5b: +case 0x3f5c: +case 0x3f5d: +case 0x3f5e: +case 0x3f5f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3198: +case 0x3199: +case 0x319a: +case 0x319b: +case 0x319c: +case 0x319d: +case 0x319e: +case 0x319f: +case 0x3398: +case 0x3399: +case 0x339a: +case 0x339b: +case 0x339c: +case 0x339d: +case 0x339e: +case 0x339f: +case 0x3598: +case 0x3599: +case 0x359a: +case 0x359b: +case 0x359c: +case 0x359d: +case 0x359e: +case 0x359f: +case 0x3798: +case 0x3799: +case 0x379a: +case 0x379b: +case 0x379c: +case 0x379d: +case 0x379e: +case 0x379f: +case 0x3998: +case 0x3999: +case 0x399a: +case 0x399b: +case 0x399c: +case 0x399d: +case 0x399e: +case 0x399f: +case 0x3b98: +case 0x3b99: +case 0x3b9a: +case 0x3b9b: +case 0x3b9c: +case 0x3b9d: +case 0x3b9e: +case 0x3b9f: +case 0x3d98: +case 0x3d99: +case 0x3d9a: +case 0x3d9b: +case 0x3d9c: +case 0x3d9d: +case 0x3d9e: +case 0x3d9f: +case 0x3f98: +case 0x3f99: +case 0x3f9a: +case 0x3f9b: +case 0x3f9c: +case 0x3f9d: +case 0x3f9e: +case 0x3f9f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xb148: +case 0xb149: +case 0xb14a: +case 0xb14b: +case 0xb14c: +case 0xb14d: +case 0xb14e: +case 0xb14f: +case 0xb348: +case 0xb349: +case 0xb34a: +case 0xb34b: +case 0xb34c: +case 0xb34d: +case 0xb34e: +case 0xb34f: +case 0xb548: +case 0xb549: +case 0xb54a: +case 0xb54b: +case 0xb54c: +case 0xb54d: +case 0xb54e: +case 0xb54f: +case 0xb748: +case 0xb749: +case 0xb74a: +case 0xb74b: +case 0xb74c: +case 0xb74d: +case 0xb74e: +case 0xb74f: +case 0xb948: +case 0xb949: +case 0xb94a: +case 0xb94b: +case 0xb94c: +case 0xb94d: +case 0xb94e: +case 0xb94f: +case 0xbb48: +case 0xbb49: +case 0xbb4a: +case 0xbb4b: +case 0xbb4c: +case 0xbb4d: +case 0xbb4e: +case 0xbb4f: +case 0xbd48: +case 0xbd49: +case 0xbd4a: +case 0xbd4b: +case 0xbd4c: +case 0xbd4d: +case 0xbd4e: +case 0xbd4f: +case 0xbf48: +case 0xbf49: +case 0xbf4a: +case 0xbf4b: +case 0xbf4c: +case 0xbf4d: +case 0xbf4e: +case 0xbf4f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x30d8: +case 0x30d9: +case 0x30da: +case 0x30db: +case 0x30dc: +case 0x30dd: +case 0x30de: +case 0x30df: +case 0x32d8: +case 0x32d9: +case 0x32da: +case 0x32db: +case 0x32dc: +case 0x32dd: +case 0x32de: +case 0x32df: +case 0x34d8: +case 0x34d9: +case 0x34da: +case 0x34db: +case 0x34dc: +case 0x34dd: +case 0x34de: +case 0x34df: +case 0x36d8: +case 0x36d9: +case 0x36da: +case 0x36db: +case 0x36dc: +case 0x36dd: +case 0x36de: +case 0x36df: +case 0x38d8: +case 0x38d9: +case 0x38da: +case 0x38db: +case 0x38dc: +case 0x38dd: +case 0x38de: +case 0x38df: +case 0x3ad8: +case 0x3ad9: +case 0x3ada: +case 0x3adb: +case 0x3adc: +case 0x3add: +case 0x3ade: +case 0x3adf: +case 0x3cd8: +case 0x3cd9: +case 0x3cda: +case 0x3cdb: +case 0x3cdc: +case 0x3cdd: +case 0x3cde: +case 0x3cdf: +case 0x3ed8: +case 0x3ed9: +case 0x3eda: +case 0x3edb: +case 0x3edc: +case 0x3edd: +case 0x3ede: +case 0x3edf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3118: +case 0x3119: +case 0x311a: +case 0x311b: +case 0x311c: +case 0x311d: +case 0x311e: +case 0x311f: +case 0x3318: +case 0x3319: +case 0x331a: +case 0x331b: +case 0x331c: +case 0x331d: +case 0x331e: +case 0x331f: +case 0x3518: +case 0x3519: +case 0x351a: +case 0x351b: +case 0x351c: +case 0x351d: +case 0x351e: +case 0x351f: +case 0x3718: +case 0x3719: +case 0x371a: +case 0x371b: +case 0x371c: +case 0x371d: +case 0x371e: +case 0x371f: +case 0x3918: +case 0x3919: +case 0x391a: +case 0x391b: +case 0x391c: +case 0x391d: +case 0x391e: +case 0x391f: +case 0x3b18: +case 0x3b19: +case 0x3b1a: +case 0x3b1b: +case 0x3b1c: +case 0x3b1d: +case 0x3b1e: +case 0x3b1f: +case 0x3d18: +case 0x3d19: +case 0x3d1a: +case 0x3d1b: +case 0x3d1c: +case 0x3d1d: +case 0x3d1e: +case 0x3d1f: +case 0x3f18: +case 0x3f19: +case 0x3f1a: +case 0x3f1b: +case 0x3f1c: +case 0x3f1d: +case 0x3f1e: +case 0x3f1f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd058: +case 0xd059: +case 0xd05a: +case 0xd05b: +case 0xd05c: +case 0xd05d: +case 0xd05e: +case 0xd05f: +case 0xd258: +case 0xd259: +case 0xd25a: +case 0xd25b: +case 0xd25c: +case 0xd25d: +case 0xd25e: +case 0xd25f: +case 0xd458: +case 0xd459: +case 0xd45a: +case 0xd45b: +case 0xd45c: +case 0xd45d: +case 0xd45e: +case 0xd45f: +case 0xd658: +case 0xd659: +case 0xd65a: +case 0xd65b: +case 0xd65c: +case 0xd65d: +case 0xd65e: +case 0xd65f: +case 0xd858: +case 0xd859: +case 0xd85a: +case 0xd85b: +case 0xd85c: +case 0xd85d: +case 0xd85e: +case 0xd85f: +case 0xda58: +case 0xda59: +case 0xda5a: +case 0xda5b: +case 0xda5c: +case 0xda5d: +case 0xda5e: +case 0xda5f: +case 0xdc58: +case 0xdc59: +case 0xdc5a: +case 0xdc5b: +case 0xdc5c: +case 0xdc5d: +case 0xdc5e: +case 0xdc5f: +case 0xde58: +case 0xde59: +case 0xde5a: +case 0xde5b: +case 0xde5c: +case 0xde5d: +case 0xde5e: +case 0xde5f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc058: +case 0xc059: +case 0xc05a: +case 0xc05b: +case 0xc05c: +case 0xc05d: +case 0xc05e: +case 0xc05f: +case 0xc258: +case 0xc259: +case 0xc25a: +case 0xc25b: +case 0xc25c: +case 0xc25d: +case 0xc25e: +case 0xc25f: +case 0xc458: +case 0xc459: +case 0xc45a: +case 0xc45b: +case 0xc45c: +case 0xc45d: +case 0xc45e: +case 0xc45f: +case 0xc658: +case 0xc659: +case 0xc65a: +case 0xc65b: +case 0xc65c: +case 0xc65d: +case 0xc65e: +case 0xc65f: +case 0xc858: +case 0xc859: +case 0xc85a: +case 0xc85b: +case 0xc85c: +case 0xc85d: +case 0xc85e: +case 0xc85f: +case 0xca58: +case 0xca59: +case 0xca5a: +case 0xca5b: +case 0xca5c: +case 0xca5d: +case 0xca5e: +case 0xca5f: +case 0xcc58: +case 0xcc59: +case 0xcc5a: +case 0xcc5b: +case 0xcc5c: +case 0xcc5d: +case 0xcc5e: +case 0xcc5f: +case 0xce58: +case 0xce59: +case 0xce5a: +case 0xce5b: +case 0xce5c: +case 0xce5d: +case 0xce5e: +case 0xce5f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0x4198: +case 0x4199: +case 0x419a: +case 0x419b: +case 0x419c: +case 0x419d: +case 0x419e: +case 0x419f: +case 0x4398: +case 0x4399: +case 0x439a: +case 0x439b: +case 0x439c: +case 0x439d: +case 0x439e: +case 0x439f: +case 0x4598: +case 0x4599: +case 0x459a: +case 0x459b: +case 0x459c: +case 0x459d: +case 0x459e: +case 0x459f: +case 0x4798: +case 0x4799: +case 0x479a: +case 0x479b: +case 0x479c: +case 0x479d: +case 0x479e: +case 0x479f: +case 0x4998: +case 0x4999: +case 0x499a: +case 0x499b: +case 0x499c: +case 0x499d: +case 0x499e: +case 0x499f: +case 0x4b98: +case 0x4b99: +case 0x4b9a: +case 0x4b9b: +case 0x4b9c: +case 0x4b9d: +case 0x4b9e: +case 0x4b9f: +case 0x4d98: +case 0x4d99: +case 0x4d9a: +case 0x4d9b: +case 0x4d9c: +case 0x4d9d: +case 0x4d9e: +case 0x4d9f: +case 0x4f98: +case 0x4f99: +case 0x4f9a: +case 0x4f9b: +case 0x4f9c: +case 0x4f9d: +case 0x4f9e: +case 0x4f9f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CHK(src, dst); + } + break; + +case 0xb058: +case 0xb059: +case 0xb05a: +case 0xb05b: +case 0xb05c: +case 0xb05d: +case 0xb05e: +case 0xb05f: +case 0xb258: +case 0xb259: +case 0xb25a: +case 0xb25b: +case 0xb25c: +case 0xb25d: +case 0xb25e: +case 0xb25f: +case 0xb458: +case 0xb459: +case 0xb45a: +case 0xb45b: +case 0xb45c: +case 0xb45d: +case 0xb45e: +case 0xb45f: +case 0xb658: +case 0xb659: +case 0xb65a: +case 0xb65b: +case 0xb65c: +case 0xb65d: +case 0xb65e: +case 0xb65f: +case 0xb858: +case 0xb859: +case 0xb85a: +case 0xb85b: +case 0xb85c: +case 0xb85d: +case 0xb85e: +case 0xb85f: +case 0xba58: +case 0xba59: +case 0xba5a: +case 0xba5b: +case 0xba5c: +case 0xba5d: +case 0xba5e: +case 0xba5f: +case 0xbc58: +case 0xbc59: +case 0xbc5a: +case 0xbc5b: +case 0xbc5c: +case 0xbc5d: +case 0xbc5e: +case 0xbc5f: +case 0xbe58: +case 0xbe59: +case 0xbe5a: +case 0xbe5b: +case 0xbe5c: +case 0xbe5d: +case 0xbe5e: +case 0xbe5f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x3018: +case 0x3019: +case 0x301a: +case 0x301b: +case 0x301c: +case 0x301d: +case 0x301e: +case 0x301f: +case 0x3218: +case 0x3219: +case 0x321a: +case 0x321b: +case 0x321c: +case 0x321d: +case 0x321e: +case 0x321f: +case 0x3418: +case 0x3419: +case 0x341a: +case 0x341b: +case 0x341c: +case 0x341d: +case 0x341e: +case 0x341f: +case 0x3618: +case 0x3619: +case 0x361a: +case 0x361b: +case 0x361c: +case 0x361d: +case 0x361e: +case 0x361f: +case 0x3818: +case 0x3819: +case 0x381a: +case 0x381b: +case 0x381c: +case 0x381d: +case 0x381e: +case 0x381f: +case 0x3a18: +case 0x3a19: +case 0x3a1a: +case 0x3a1b: +case 0x3a1c: +case 0x3a1d: +case 0x3a1e: +case 0x3a1f: +case 0x3c18: +case 0x3c19: +case 0x3c1a: +case 0x3c1b: +case 0x3c1c: +case 0x3c1d: +case 0x3c1e: +case 0x3c1f: +case 0x3e18: +case 0x3e19: +case 0x3e1a: +case 0x3e1b: +case 0x3e1c: +case 0x3e1d: +case 0x3e1e: +case 0x3e1f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8058: +case 0x8059: +case 0x805a: +case 0x805b: +case 0x805c: +case 0x805d: +case 0x805e: +case 0x805f: +case 0x8258: +case 0x8259: +case 0x825a: +case 0x825b: +case 0x825c: +case 0x825d: +case 0x825e: +case 0x825f: +case 0x8458: +case 0x8459: +case 0x845a: +case 0x845b: +case 0x845c: +case 0x845d: +case 0x845e: +case 0x845f: +case 0x8658: +case 0x8659: +case 0x865a: +case 0x865b: +case 0x865c: +case 0x865d: +case 0x865e: +case 0x865f: +case 0x8858: +case 0x8859: +case 0x885a: +case 0x885b: +case 0x885c: +case 0x885d: +case 0x885e: +case 0x885f: +case 0x8a58: +case 0x8a59: +case 0x8a5a: +case 0x8a5b: +case 0x8a5c: +case 0x8a5d: +case 0x8a5e: +case 0x8a5f: +case 0x8c58: +case 0x8c59: +case 0x8c5a: +case 0x8c5b: +case 0x8c5c: +case 0x8c5d: +case 0x8c5e: +case 0x8c5f: +case 0x8e58: +case 0x8e59: +case 0x8e5a: +case 0x8e5b: +case 0x8e5c: +case 0x8e5d: +case 0x8e5e: +case 0x8e5f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9058: +case 0x9059: +case 0x905a: +case 0x905b: +case 0x905c: +case 0x905d: +case 0x905e: +case 0x905f: +case 0x9258: +case 0x9259: +case 0x925a: +case 0x925b: +case 0x925c: +case 0x925d: +case 0x925e: +case 0x925f: +case 0x9458: +case 0x9459: +case 0x945a: +case 0x945b: +case 0x945c: +case 0x945d: +case 0x945e: +case 0x945f: +case 0x9658: +case 0x9659: +case 0x965a: +case 0x965b: +case 0x965c: +case 0x965d: +case 0x965e: +case 0x965f: +case 0x9858: +case 0x9859: +case 0x985a: +case 0x985b: +case 0x985c: +case 0x985d: +case 0x985e: +case 0x985f: +case 0x9a58: +case 0x9a59: +case 0x9a5a: +case 0x9a5b: +case 0x9a5c: +case 0x9a5d: +case 0x9a5e: +case 0x9a5f: +case 0x9c58: +case 0x9c59: +case 0x9c5a: +case 0x9c5b: +case 0x9c5c: +case 0x9c5d: +case 0x9c5e: +case 0x9c5f: +case 0x9e58: +case 0x9e59: +case 0x9e5a: +case 0x9e5b: +case 0x9e5c: +case 0x9e5d: +case 0x9e5e: +case 0x9e5f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0xd0d8: +case 0xd0d9: +case 0xd0da: +case 0xd0db: +case 0xd0dc: +case 0xd0dd: +case 0xd0de: +case 0xd0df: +case 0xd2d8: +case 0xd2d9: +case 0xd2da: +case 0xd2db: +case 0xd2dc: +case 0xd2dd: +case 0xd2de: +case 0xd2df: +case 0xd4d8: +case 0xd4d9: +case 0xd4da: +case 0xd4db: +case 0xd4dc: +case 0xd4dd: +case 0xd4de: +case 0xd4df: +case 0xd6d8: +case 0xd6d9: +case 0xd6da: +case 0xd6db: +case 0xd6dc: +case 0xd6dd: +case 0xd6de: +case 0xd6df: +case 0xd8d8: +case 0xd8d9: +case 0xd8da: +case 0xd8db: +case 0xd8dc: +case 0xd8dd: +case 0xd8de: +case 0xd8df: +case 0xdad8: +case 0xdad9: +case 0xdada: +case 0xdadb: +case 0xdadc: +case 0xdadd: +case 0xdade: +case 0xdadf: +case 0xdcd8: +case 0xdcd9: +case 0xdcda: +case 0xdcdb: +case 0xdcdc: +case 0xdcdd: +case 0xdcde: +case 0xdcdf: +case 0xded8: +case 0xded9: +case 0xdeda: +case 0xdedb: +case 0xdedc: +case 0xdedd: +case 0xdede: +case 0xdedf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb0d8: +case 0xb0d9: +case 0xb0da: +case 0xb0db: +case 0xb0dc: +case 0xb0dd: +case 0xb0de: +case 0xb0df: +case 0xb2d8: +case 0xb2d9: +case 0xb2da: +case 0xb2db: +case 0xb2dc: +case 0xb2dd: +case 0xb2de: +case 0xb2df: +case 0xb4d8: +case 0xb4d9: +case 0xb4da: +case 0xb4db: +case 0xb4dc: +case 0xb4dd: +case 0xb4de: +case 0xb4df: +case 0xb6d8: +case 0xb6d9: +case 0xb6da: +case 0xb6db: +case 0xb6dc: +case 0xb6dd: +case 0xb6de: +case 0xb6df: +case 0xb8d8: +case 0xb8d9: +case 0xb8da: +case 0xb8db: +case 0xb8dc: +case 0xb8dd: +case 0xb8de: +case 0xb8df: +case 0xbad8: +case 0xbad9: +case 0xbada: +case 0xbadb: +case 0xbadc: +case 0xbadd: +case 0xbade: +case 0xbadf: +case 0xbcd8: +case 0xbcd9: +case 0xbcda: +case 0xbcdb: +case 0xbcdc: +case 0xbcdd: +case 0xbcde: +case 0xbcdf: +case 0xbed8: +case 0xbed9: +case 0xbeda: +case 0xbedb: +case 0xbedc: +case 0xbedd: +case 0xbede: +case 0xbedf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x90d8: +case 0x90d9: +case 0x90da: +case 0x90db: +case 0x90dc: +case 0x90dd: +case 0x90de: +case 0x90df: +case 0x92d8: +case 0x92d9: +case 0x92da: +case 0x92db: +case 0x92dc: +case 0x92dd: +case 0x92de: +case 0x92df: +case 0x94d8: +case 0x94d9: +case 0x94da: +case 0x94db: +case 0x94dc: +case 0x94dd: +case 0x94de: +case 0x94df: +case 0x96d8: +case 0x96d9: +case 0x96da: +case 0x96db: +case 0x96dc: +case 0x96dd: +case 0x96de: +case 0x96df: +case 0x98d8: +case 0x98d9: +case 0x98da: +case 0x98db: +case 0x98dc: +case 0x98dd: +case 0x98de: +case 0x98df: +case 0x9ad8: +case 0x9ad9: +case 0x9ada: +case 0x9adb: +case 0x9adc: +case 0x9add: +case 0x9ade: +case 0x9adf: +case 0x9cd8: +case 0x9cd9: +case 0x9cda: +case 0x9cdb: +case 0x9cdc: +case 0x9cdd: +case 0x9cde: +case 0x9cdf: +case 0x9ed8: +case 0x9ed9: +case 0x9eda: +case 0x9edb: +case 0x9edc: +case 0x9edd: +case 0x9ede: +case 0x9edf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x3058: +case 0x3059: +case 0x305a: +case 0x305b: +case 0x305c: +case 0x305d: +case 0x305e: +case 0x305f: +case 0x3258: +case 0x3259: +case 0x325a: +case 0x325b: +case 0x325c: +case 0x325d: +case 0x325e: +case 0x325f: +case 0x3458: +case 0x3459: +case 0x345a: +case 0x345b: +case 0x345c: +case 0x345d: +case 0x345e: +case 0x345f: +case 0x3658: +case 0x3659: +case 0x365a: +case 0x365b: +case 0x365c: +case 0x365d: +case 0x365e: +case 0x365f: +case 0x3858: +case 0x3859: +case 0x385a: +case 0x385b: +case 0x385c: +case 0x385d: +case 0x385e: +case 0x385f: +case 0x3a58: +case 0x3a59: +case 0x3a5a: +case 0x3a5b: +case 0x3a5c: +case 0x3a5d: +case 0x3a5e: +case 0x3a5f: +case 0x3c58: +case 0x3c59: +case 0x3c5a: +case 0x3c5b: +case 0x3c5c: +case 0x3c5d: +case 0x3c5e: +case 0x3c5f: +case 0x3e58: +case 0x3e59: +case 0x3e5a: +case 0x3e5b: +case 0x3e5c: +case 0x3e5d: +case 0x3e5e: +case 0x3e5f: + { + HAM src(this, instr_b2_b0); MOVEA(src, instr_b11_b9); + } + break; + +case 0x44d8: +case 0x44d9: +case 0x44da: +case 0x44db: +case 0x44dc: +case 0x44dd: +case 0x44de: +case 0x44df: + { + HAM src(this, instr_b2_b0); MOVE_to_CCR(src); + } + break; + +case 0xc1d8: +case 0xc1d9: +case 0xc1da: +case 0xc1db: +case 0xc1dc: +case 0xc1dd: +case 0xc1de: +case 0xc1df: +case 0xc3d8: +case 0xc3d9: +case 0xc3da: +case 0xc3db: +case 0xc3dc: +case 0xc3dd: +case 0xc3de: +case 0xc3df: +case 0xc5d8: +case 0xc5d9: +case 0xc5da: +case 0xc5db: +case 0xc5dc: +case 0xc5dd: +case 0xc5de: +case 0xc5df: +case 0xc7d8: +case 0xc7d9: +case 0xc7da: +case 0xc7db: +case 0xc7dc: +case 0xc7dd: +case 0xc7de: +case 0xc7df: +case 0xc9d8: +case 0xc9d9: +case 0xc9da: +case 0xc9db: +case 0xc9dc: +case 0xc9dd: +case 0xc9de: +case 0xc9df: +case 0xcbd8: +case 0xcbd9: +case 0xcbda: +case 0xcbdb: +case 0xcbdc: +case 0xcbdd: +case 0xcbde: +case 0xcbdf: +case 0xcdd8: +case 0xcdd9: +case 0xcdda: +case 0xcddb: +case 0xcddc: +case 0xcddd: +case 0xcdde: +case 0xcddf: +case 0xcfd8: +case 0xcfd9: +case 0xcfda: +case 0xcfdb: +case 0xcfdc: +case 0xcfdd: +case 0xcfde: +case 0xcfdf: + { + HAM src(this, instr_b2_b0); MULS(src, instr_b11_b9); + } + break; + +case 0xc0d8: +case 0xc0d9: +case 0xc0da: +case 0xc0db: +case 0xc0dc: +case 0xc0dd: +case 0xc0de: +case 0xc0df: +case 0xc2d8: +case 0xc2d9: +case 0xc2da: +case 0xc2db: +case 0xc2dc: +case 0xc2dd: +case 0xc2de: +case 0xc2df: +case 0xc4d8: +case 0xc4d9: +case 0xc4da: +case 0xc4db: +case 0xc4dc: +case 0xc4dd: +case 0xc4de: +case 0xc4df: +case 0xc6d8: +case 0xc6d9: +case 0xc6da: +case 0xc6db: +case 0xc6dc: +case 0xc6dd: +case 0xc6de: +case 0xc6df: +case 0xc8d8: +case 0xc8d9: +case 0xc8da: +case 0xc8db: +case 0xc8dc: +case 0xc8dd: +case 0xc8de: +case 0xc8df: +case 0xcad8: +case 0xcad9: +case 0xcada: +case 0xcadb: +case 0xcadc: +case 0xcadd: +case 0xcade: +case 0xcadf: +case 0xccd8: +case 0xccd9: +case 0xccda: +case 0xccdb: +case 0xccdc: +case 0xccdd: +case 0xccde: +case 0xccdf: +case 0xced8: +case 0xced9: +case 0xceda: +case 0xcedb: +case 0xcedc: +case 0xcedd: +case 0xcede: +case 0xcedf: + { + HAM src(this, instr_b2_b0); MULU(src, instr_b11_b9); + } + break; + +case 0xe1d8: +case 0xe1d9: +case 0xe1da: +case 0xe1db: +case 0xe1dc: +case 0xe1dd: +case 0xe1de: +case 0xe1df: + { + HAM targ(this, instr_b2_b0); ASL(targ, 1); + } + break; + +case 0xe0d8: +case 0xe0d9: +case 0xe0da: +case 0xe0db: +case 0xe0dc: +case 0xe0dd: +case 0xe0de: +case 0xe0df: + { + HAM targ(this, instr_b2_b0); ASR(targ, 1); + } + break; + +case 0xe3d8: +case 0xe3d9: +case 0xe3da: +case 0xe3db: +case 0xe3dc: +case 0xe3dd: +case 0xe3de: +case 0xe3df: + { + HAM targ(this, instr_b2_b0); LSL(targ, 1); + } + break; + +case 0xe2d8: +case 0xe2d9: +case 0xe2da: +case 0xe2db: +case 0xe2dc: +case 0xe2dd: +case 0xe2de: +case 0xe2df: + { + HAM targ(this, instr_b2_b0); LSR(targ, 1); + } + break; + +case 0xe7d8: +case 0xe7d9: +case 0xe7da: +case 0xe7db: +case 0xe7dc: +case 0xe7dd: +case 0xe7de: +case 0xe7df: + { + HAM targ(this, instr_b2_b0); ROL(targ, 1); + } + break; + +case 0xe6d8: +case 0xe6d9: +case 0xe6da: +case 0xe6db: +case 0xe6dc: +case 0xe6dd: +case 0xe6de: +case 0xe6df: + { + HAM targ(this, instr_b2_b0); ROR(targ, 1); + } + break; + +case 0xe5d8: +case 0xe5d9: +case 0xe5da: +case 0xe5db: +case 0xe5dc: +case 0xe5dd: +case 0xe5de: +case 0xe5df: + { + HAM targ(this, instr_b2_b0); ROXL(targ, 1); + } + break; + +case 0xe4d8: +case 0xe4d9: +case 0xe4da: +case 0xe4db: +case 0xe4dc: +case 0xe4dd: +case 0xe4de: +case 0xe4df: + { + HAM targ(this, instr_b2_b0); ROXR(targ, 1); + } + break; + +case 0x4260: +case 0x4261: +case 0x4262: +case 0x4263: +case 0x4264: +case 0x4265: +case 0x4266: +case 0x4267: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x4460: +case 0x4461: +case 0x4462: +case 0x4463: +case 0x4464: +case 0x4465: +case 0x4466: +case 0x4467: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x4060: +case 0x4061: +case 0x4062: +case 0x4063: +case 0x4064: +case 0x4065: +case 0x4066: +case 0x4067: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x4660: +case 0x4661: +case 0x4662: +case 0x4663: +case 0x4664: +case 0x4665: +case 0x4666: +case 0x4667: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x4a60: +case 0x4a61: +case 0x4a62: +case 0x4a63: +case 0x4a64: +case 0x4a65: +case 0x4a66: +case 0x4a67: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0x81e0: +case 0x81e1: +case 0x81e2: +case 0x81e3: +case 0x81e4: +case 0x81e5: +case 0x81e6: +case 0x81e7: +case 0x83e0: +case 0x83e1: +case 0x83e2: +case 0x83e3: +case 0x83e4: +case 0x83e5: +case 0x83e6: +case 0x83e7: +case 0x85e0: +case 0x85e1: +case 0x85e2: +case 0x85e3: +case 0x85e4: +case 0x85e5: +case 0x85e6: +case 0x85e7: +case 0x87e0: +case 0x87e1: +case 0x87e2: +case 0x87e3: +case 0x87e4: +case 0x87e5: +case 0x87e6: +case 0x87e7: +case 0x89e0: +case 0x89e1: +case 0x89e2: +case 0x89e3: +case 0x89e4: +case 0x89e5: +case 0x89e6: +case 0x89e7: +case 0x8be0: +case 0x8be1: +case 0x8be2: +case 0x8be3: +case 0x8be4: +case 0x8be5: +case 0x8be6: +case 0x8be7: +case 0x8de0: +case 0x8de1: +case 0x8de2: +case 0x8de3: +case 0x8de4: +case 0x8de5: +case 0x8de6: +case 0x8de7: +case 0x8fe0: +case 0x8fe1: +case 0x8fe2: +case 0x8fe3: +case 0x8fe4: +case 0x8fe5: +case 0x8fe6: +case 0x8fe7: + { + HAM src(this, instr_b2_b0); DIVS(src, instr_b11_b9); + } + break; + +case 0x80e0: +case 0x80e1: +case 0x80e2: +case 0x80e3: +case 0x80e4: +case 0x80e5: +case 0x80e6: +case 0x80e7: +case 0x82e0: +case 0x82e1: +case 0x82e2: +case 0x82e3: +case 0x82e4: +case 0x82e5: +case 0x82e6: +case 0x82e7: +case 0x84e0: +case 0x84e1: +case 0x84e2: +case 0x84e3: +case 0x84e4: +case 0x84e5: +case 0x84e6: +case 0x84e7: +case 0x86e0: +case 0x86e1: +case 0x86e2: +case 0x86e3: +case 0x86e4: +case 0x86e5: +case 0x86e6: +case 0x86e7: +case 0x88e0: +case 0x88e1: +case 0x88e2: +case 0x88e3: +case 0x88e4: +case 0x88e5: +case 0x88e6: +case 0x88e7: +case 0x8ae0: +case 0x8ae1: +case 0x8ae2: +case 0x8ae3: +case 0x8ae4: +case 0x8ae5: +case 0x8ae6: +case 0x8ae7: +case 0x8ce0: +case 0x8ce1: +case 0x8ce2: +case 0x8ce3: +case 0x8ce4: +case 0x8ce5: +case 0x8ce6: +case 0x8ce7: +case 0x8ee0: +case 0x8ee1: +case 0x8ee2: +case 0x8ee3: +case 0x8ee4: +case 0x8ee5: +case 0x8ee6: +case 0x8ee7: + { + HAM src(this, instr_b2_b0); DIVU(src, instr_b11_b9); + } + break; + +case 0x33e0: +case 0x33e1: +case 0x33e2: +case 0x33e3: +case 0x33e4: +case 0x33e5: +case 0x33e6: +case 0x33e7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x31e0: +case 0x31e1: +case 0x31e2: +case 0x31e3: +case 0x31e4: +case 0x31e5: +case 0x31e6: +case 0x31e7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x30a0: +case 0x30a1: +case 0x30a2: +case 0x30a3: +case 0x30a4: +case 0x30a5: +case 0x30a6: +case 0x30a7: +case 0x32a0: +case 0x32a1: +case 0x32a2: +case 0x32a3: +case 0x32a4: +case 0x32a5: +case 0x32a6: +case 0x32a7: +case 0x34a0: +case 0x34a1: +case 0x34a2: +case 0x34a3: +case 0x34a4: +case 0x34a5: +case 0x34a6: +case 0x34a7: +case 0x36a0: +case 0x36a1: +case 0x36a2: +case 0x36a3: +case 0x36a4: +case 0x36a5: +case 0x36a6: +case 0x36a7: +case 0x38a0: +case 0x38a1: +case 0x38a2: +case 0x38a3: +case 0x38a4: +case 0x38a5: +case 0x38a6: +case 0x38a7: +case 0x3aa0: +case 0x3aa1: +case 0x3aa2: +case 0x3aa3: +case 0x3aa4: +case 0x3aa5: +case 0x3aa6: +case 0x3aa7: +case 0x3ca0: +case 0x3ca1: +case 0x3ca2: +case 0x3ca3: +case 0x3ca4: +case 0x3ca5: +case 0x3ca6: +case 0x3ca7: +case 0x3ea0: +case 0x3ea1: +case 0x3ea2: +case 0x3ea3: +case 0x3ea4: +case 0x3ea5: +case 0x3ea6: +case 0x3ea7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3160: +case 0x3161: +case 0x3162: +case 0x3163: +case 0x3164: +case 0x3165: +case 0x3166: +case 0x3167: +case 0x3360: +case 0x3361: +case 0x3362: +case 0x3363: +case 0x3364: +case 0x3365: +case 0x3366: +case 0x3367: +case 0x3560: +case 0x3561: +case 0x3562: +case 0x3563: +case 0x3564: +case 0x3565: +case 0x3566: +case 0x3567: +case 0x3760: +case 0x3761: +case 0x3762: +case 0x3763: +case 0x3764: +case 0x3765: +case 0x3766: +case 0x3767: +case 0x3960: +case 0x3961: +case 0x3962: +case 0x3963: +case 0x3964: +case 0x3965: +case 0x3966: +case 0x3967: +case 0x3b60: +case 0x3b61: +case 0x3b62: +case 0x3b63: +case 0x3b64: +case 0x3b65: +case 0x3b66: +case 0x3b67: +case 0x3d60: +case 0x3d61: +case 0x3d62: +case 0x3d63: +case 0x3d64: +case 0x3d65: +case 0x3d66: +case 0x3d67: +case 0x3f60: +case 0x3f61: +case 0x3f62: +case 0x3f63: +case 0x3f64: +case 0x3f65: +case 0x3f66: +case 0x3f67: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x31a0: +case 0x31a1: +case 0x31a2: +case 0x31a3: +case 0x31a4: +case 0x31a5: +case 0x31a6: +case 0x31a7: +case 0x33a0: +case 0x33a1: +case 0x33a2: +case 0x33a3: +case 0x33a4: +case 0x33a5: +case 0x33a6: +case 0x33a7: +case 0x35a0: +case 0x35a1: +case 0x35a2: +case 0x35a3: +case 0x35a4: +case 0x35a5: +case 0x35a6: +case 0x35a7: +case 0x37a0: +case 0x37a1: +case 0x37a2: +case 0x37a3: +case 0x37a4: +case 0x37a5: +case 0x37a6: +case 0x37a7: +case 0x39a0: +case 0x39a1: +case 0x39a2: +case 0x39a3: +case 0x39a4: +case 0x39a5: +case 0x39a6: +case 0x39a7: +case 0x3ba0: +case 0x3ba1: +case 0x3ba2: +case 0x3ba3: +case 0x3ba4: +case 0x3ba5: +case 0x3ba6: +case 0x3ba7: +case 0x3da0: +case 0x3da1: +case 0x3da2: +case 0x3da3: +case 0x3da4: +case 0x3da5: +case 0x3da6: +case 0x3da7: +case 0x3fa0: +case 0x3fa1: +case 0x3fa2: +case 0x3fa3: +case 0x3fa4: +case 0x3fa5: +case 0x3fa6: +case 0x3fa7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x30e0: +case 0x30e1: +case 0x30e2: +case 0x30e3: +case 0x30e4: +case 0x30e5: +case 0x30e6: +case 0x30e7: +case 0x32e0: +case 0x32e1: +case 0x32e2: +case 0x32e3: +case 0x32e4: +case 0x32e5: +case 0x32e6: +case 0x32e7: +case 0x34e0: +case 0x34e1: +case 0x34e2: +case 0x34e3: +case 0x34e4: +case 0x34e5: +case 0x34e6: +case 0x34e7: +case 0x36e0: +case 0x36e1: +case 0x36e2: +case 0x36e3: +case 0x36e4: +case 0x36e5: +case 0x36e6: +case 0x36e7: +case 0x38e0: +case 0x38e1: +case 0x38e2: +case 0x38e3: +case 0x38e4: +case 0x38e5: +case 0x38e6: +case 0x38e7: +case 0x3ae0: +case 0x3ae1: +case 0x3ae2: +case 0x3ae3: +case 0x3ae4: +case 0x3ae5: +case 0x3ae6: +case 0x3ae7: +case 0x3ce0: +case 0x3ce1: +case 0x3ce2: +case 0x3ce3: +case 0x3ce4: +case 0x3ce5: +case 0x3ce6: +case 0x3ce7: +case 0x3ee0: +case 0x3ee1: +case 0x3ee2: +case 0x3ee3: +case 0x3ee4: +case 0x3ee5: +case 0x3ee6: +case 0x3ee7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd148: +case 0xd149: +case 0xd14a: +case 0xd14b: +case 0xd14c: +case 0xd14d: +case 0xd14e: +case 0xd14f: +case 0xd348: +case 0xd349: +case 0xd34a: +case 0xd34b: +case 0xd34c: +case 0xd34d: +case 0xd34e: +case 0xd34f: +case 0xd548: +case 0xd549: +case 0xd54a: +case 0xd54b: +case 0xd54c: +case 0xd54d: +case 0xd54e: +case 0xd54f: +case 0xd748: +case 0xd749: +case 0xd74a: +case 0xd74b: +case 0xd74c: +case 0xd74d: +case 0xd74e: +case 0xd74f: +case 0xd948: +case 0xd949: +case 0xd94a: +case 0xd94b: +case 0xd94c: +case 0xd94d: +case 0xd94e: +case 0xd94f: +case 0xdb48: +case 0xdb49: +case 0xdb4a: +case 0xdb4b: +case 0xdb4c: +case 0xdb4d: +case 0xdb4e: +case 0xdb4f: +case 0xdd48: +case 0xdd49: +case 0xdd4a: +case 0xdd4b: +case 0xdd4c: +case 0xdd4d: +case 0xdd4e: +case 0xdd4f: +case 0xdf48: +case 0xdf49: +case 0xdf4a: +case 0xdf4b: +case 0xdf4c: +case 0xdf4d: +case 0xdf4e: +case 0xdf4f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADDX(src, dst); + } + break; + +case 0x3120: +case 0x3121: +case 0x3122: +case 0x3123: +case 0x3124: +case 0x3125: +case 0x3126: +case 0x3127: +case 0x3320: +case 0x3321: +case 0x3322: +case 0x3323: +case 0x3324: +case 0x3325: +case 0x3326: +case 0x3327: +case 0x3520: +case 0x3521: +case 0x3522: +case 0x3523: +case 0x3524: +case 0x3525: +case 0x3526: +case 0x3527: +case 0x3720: +case 0x3721: +case 0x3722: +case 0x3723: +case 0x3724: +case 0x3725: +case 0x3726: +case 0x3727: +case 0x3920: +case 0x3921: +case 0x3922: +case 0x3923: +case 0x3924: +case 0x3925: +case 0x3926: +case 0x3927: +case 0x3b20: +case 0x3b21: +case 0x3b22: +case 0x3b23: +case 0x3b24: +case 0x3b25: +case 0x3b26: +case 0x3b27: +case 0x3d20: +case 0x3d21: +case 0x3d22: +case 0x3d23: +case 0x3d24: +case 0x3d25: +case 0x3d26: +case 0x3d27: +case 0x3f20: +case 0x3f21: +case 0x3f22: +case 0x3f23: +case 0x3f24: +case 0x3f25: +case 0x3f26: +case 0x3f27: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x9148: +case 0x9149: +case 0x914a: +case 0x914b: +case 0x914c: +case 0x914d: +case 0x914e: +case 0x914f: +case 0x9348: +case 0x9349: +case 0x934a: +case 0x934b: +case 0x934c: +case 0x934d: +case 0x934e: +case 0x934f: +case 0x9548: +case 0x9549: +case 0x954a: +case 0x954b: +case 0x954c: +case 0x954d: +case 0x954e: +case 0x954f: +case 0x9748: +case 0x9749: +case 0x974a: +case 0x974b: +case 0x974c: +case 0x974d: +case 0x974e: +case 0x974f: +case 0x9948: +case 0x9949: +case 0x994a: +case 0x994b: +case 0x994c: +case 0x994d: +case 0x994e: +case 0x994f: +case 0x9b48: +case 0x9b49: +case 0x9b4a: +case 0x9b4b: +case 0x9b4c: +case 0x9b4d: +case 0x9b4e: +case 0x9b4f: +case 0x9d48: +case 0x9d49: +case 0x9d4a: +case 0x9d4b: +case 0x9d4c: +case 0x9d4d: +case 0x9d4e: +case 0x9d4f: +case 0x9f48: +case 0x9f49: +case 0x9f4a: +case 0x9f4b: +case 0x9f4c: +case 0x9f4d: +case 0x9f4e: +case 0x9f4f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUBX(src, dst); + } + break; + +case 0xd060: +case 0xd061: +case 0xd062: +case 0xd063: +case 0xd064: +case 0xd065: +case 0xd066: +case 0xd067: +case 0xd260: +case 0xd261: +case 0xd262: +case 0xd263: +case 0xd264: +case 0xd265: +case 0xd266: +case 0xd267: +case 0xd460: +case 0xd461: +case 0xd462: +case 0xd463: +case 0xd464: +case 0xd465: +case 0xd466: +case 0xd467: +case 0xd660: +case 0xd661: +case 0xd662: +case 0xd663: +case 0xd664: +case 0xd665: +case 0xd666: +case 0xd667: +case 0xd860: +case 0xd861: +case 0xd862: +case 0xd863: +case 0xd864: +case 0xd865: +case 0xd866: +case 0xd867: +case 0xda60: +case 0xda61: +case 0xda62: +case 0xda63: +case 0xda64: +case 0xda65: +case 0xda66: +case 0xda67: +case 0xdc60: +case 0xdc61: +case 0xdc62: +case 0xdc63: +case 0xdc64: +case 0xdc65: +case 0xdc66: +case 0xdc67: +case 0xde60: +case 0xde61: +case 0xde62: +case 0xde63: +case 0xde64: +case 0xde65: +case 0xde66: +case 0xde67: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc060: +case 0xc061: +case 0xc062: +case 0xc063: +case 0xc064: +case 0xc065: +case 0xc066: +case 0xc067: +case 0xc260: +case 0xc261: +case 0xc262: +case 0xc263: +case 0xc264: +case 0xc265: +case 0xc266: +case 0xc267: +case 0xc460: +case 0xc461: +case 0xc462: +case 0xc463: +case 0xc464: +case 0xc465: +case 0xc466: +case 0xc467: +case 0xc660: +case 0xc661: +case 0xc662: +case 0xc663: +case 0xc664: +case 0xc665: +case 0xc666: +case 0xc667: +case 0xc860: +case 0xc861: +case 0xc862: +case 0xc863: +case 0xc864: +case 0xc865: +case 0xc866: +case 0xc867: +case 0xca60: +case 0xca61: +case 0xca62: +case 0xca63: +case 0xca64: +case 0xca65: +case 0xca66: +case 0xca67: +case 0xcc60: +case 0xcc61: +case 0xcc62: +case 0xcc63: +case 0xcc64: +case 0xcc65: +case 0xcc66: +case 0xcc67: +case 0xce60: +case 0xce61: +case 0xce62: +case 0xce63: +case 0xce64: +case 0xce65: +case 0xce66: +case 0xce67: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0x41a0: +case 0x41a1: +case 0x41a2: +case 0x41a3: +case 0x41a4: +case 0x41a5: +case 0x41a6: +case 0x41a7: +case 0x43a0: +case 0x43a1: +case 0x43a2: +case 0x43a3: +case 0x43a4: +case 0x43a5: +case 0x43a6: +case 0x43a7: +case 0x45a0: +case 0x45a1: +case 0x45a2: +case 0x45a3: +case 0x45a4: +case 0x45a5: +case 0x45a6: +case 0x45a7: +case 0x47a0: +case 0x47a1: +case 0x47a2: +case 0x47a3: +case 0x47a4: +case 0x47a5: +case 0x47a6: +case 0x47a7: +case 0x49a0: +case 0x49a1: +case 0x49a2: +case 0x49a3: +case 0x49a4: +case 0x49a5: +case 0x49a6: +case 0x49a7: +case 0x4ba0: +case 0x4ba1: +case 0x4ba2: +case 0x4ba3: +case 0x4ba4: +case 0x4ba5: +case 0x4ba6: +case 0x4ba7: +case 0x4da0: +case 0x4da1: +case 0x4da2: +case 0x4da3: +case 0x4da4: +case 0x4da5: +case 0x4da6: +case 0x4da7: +case 0x4fa0: +case 0x4fa1: +case 0x4fa2: +case 0x4fa3: +case 0x4fa4: +case 0x4fa5: +case 0x4fa6: +case 0x4fa7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CHK(src, dst); + } + break; + +case 0xb060: +case 0xb061: +case 0xb062: +case 0xb063: +case 0xb064: +case 0xb065: +case 0xb066: +case 0xb067: +case 0xb260: +case 0xb261: +case 0xb262: +case 0xb263: +case 0xb264: +case 0xb265: +case 0xb266: +case 0xb267: +case 0xb460: +case 0xb461: +case 0xb462: +case 0xb463: +case 0xb464: +case 0xb465: +case 0xb466: +case 0xb467: +case 0xb660: +case 0xb661: +case 0xb662: +case 0xb663: +case 0xb664: +case 0xb665: +case 0xb666: +case 0xb667: +case 0xb860: +case 0xb861: +case 0xb862: +case 0xb863: +case 0xb864: +case 0xb865: +case 0xb866: +case 0xb867: +case 0xba60: +case 0xba61: +case 0xba62: +case 0xba63: +case 0xba64: +case 0xba65: +case 0xba66: +case 0xba67: +case 0xbc60: +case 0xbc61: +case 0xbc62: +case 0xbc63: +case 0xbc64: +case 0xbc65: +case 0xbc66: +case 0xbc67: +case 0xbe60: +case 0xbe61: +case 0xbe62: +case 0xbe63: +case 0xbe64: +case 0xbe65: +case 0xbe66: +case 0xbe67: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x3020: +case 0x3021: +case 0x3022: +case 0x3023: +case 0x3024: +case 0x3025: +case 0x3026: +case 0x3027: +case 0x3220: +case 0x3221: +case 0x3222: +case 0x3223: +case 0x3224: +case 0x3225: +case 0x3226: +case 0x3227: +case 0x3420: +case 0x3421: +case 0x3422: +case 0x3423: +case 0x3424: +case 0x3425: +case 0x3426: +case 0x3427: +case 0x3620: +case 0x3621: +case 0x3622: +case 0x3623: +case 0x3624: +case 0x3625: +case 0x3626: +case 0x3627: +case 0x3820: +case 0x3821: +case 0x3822: +case 0x3823: +case 0x3824: +case 0x3825: +case 0x3826: +case 0x3827: +case 0x3a20: +case 0x3a21: +case 0x3a22: +case 0x3a23: +case 0x3a24: +case 0x3a25: +case 0x3a26: +case 0x3a27: +case 0x3c20: +case 0x3c21: +case 0x3c22: +case 0x3c23: +case 0x3c24: +case 0x3c25: +case 0x3c26: +case 0x3c27: +case 0x3e20: +case 0x3e21: +case 0x3e22: +case 0x3e23: +case 0x3e24: +case 0x3e25: +case 0x3e26: +case 0x3e27: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8060: +case 0x8061: +case 0x8062: +case 0x8063: +case 0x8064: +case 0x8065: +case 0x8066: +case 0x8067: +case 0x8260: +case 0x8261: +case 0x8262: +case 0x8263: +case 0x8264: +case 0x8265: +case 0x8266: +case 0x8267: +case 0x8460: +case 0x8461: +case 0x8462: +case 0x8463: +case 0x8464: +case 0x8465: +case 0x8466: +case 0x8467: +case 0x8660: +case 0x8661: +case 0x8662: +case 0x8663: +case 0x8664: +case 0x8665: +case 0x8666: +case 0x8667: +case 0x8860: +case 0x8861: +case 0x8862: +case 0x8863: +case 0x8864: +case 0x8865: +case 0x8866: +case 0x8867: +case 0x8a60: +case 0x8a61: +case 0x8a62: +case 0x8a63: +case 0x8a64: +case 0x8a65: +case 0x8a66: +case 0x8a67: +case 0x8c60: +case 0x8c61: +case 0x8c62: +case 0x8c63: +case 0x8c64: +case 0x8c65: +case 0x8c66: +case 0x8c67: +case 0x8e60: +case 0x8e61: +case 0x8e62: +case 0x8e63: +case 0x8e64: +case 0x8e65: +case 0x8e66: +case 0x8e67: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9060: +case 0x9061: +case 0x9062: +case 0x9063: +case 0x9064: +case 0x9065: +case 0x9066: +case 0x9067: +case 0x9260: +case 0x9261: +case 0x9262: +case 0x9263: +case 0x9264: +case 0x9265: +case 0x9266: +case 0x9267: +case 0x9460: +case 0x9461: +case 0x9462: +case 0x9463: +case 0x9464: +case 0x9465: +case 0x9466: +case 0x9467: +case 0x9660: +case 0x9661: +case 0x9662: +case 0x9663: +case 0x9664: +case 0x9665: +case 0x9666: +case 0x9667: +case 0x9860: +case 0x9861: +case 0x9862: +case 0x9863: +case 0x9864: +case 0x9865: +case 0x9866: +case 0x9867: +case 0x9a60: +case 0x9a61: +case 0x9a62: +case 0x9a63: +case 0x9a64: +case 0x9a65: +case 0x9a66: +case 0x9a67: +case 0x9c60: +case 0x9c61: +case 0x9c62: +case 0x9c63: +case 0x9c64: +case 0x9c65: +case 0x9c66: +case 0x9c67: +case 0x9e60: +case 0x9e61: +case 0x9e62: +case 0x9e63: +case 0x9e64: +case 0x9e65: +case 0x9e66: +case 0x9e67: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0xd0e0: +case 0xd0e1: +case 0xd0e2: +case 0xd0e3: +case 0xd0e4: +case 0xd0e5: +case 0xd0e6: +case 0xd0e7: +case 0xd2e0: +case 0xd2e1: +case 0xd2e2: +case 0xd2e3: +case 0xd2e4: +case 0xd2e5: +case 0xd2e6: +case 0xd2e7: +case 0xd4e0: +case 0xd4e1: +case 0xd4e2: +case 0xd4e3: +case 0xd4e4: +case 0xd4e5: +case 0xd4e6: +case 0xd4e7: +case 0xd6e0: +case 0xd6e1: +case 0xd6e2: +case 0xd6e3: +case 0xd6e4: +case 0xd6e5: +case 0xd6e6: +case 0xd6e7: +case 0xd8e0: +case 0xd8e1: +case 0xd8e2: +case 0xd8e3: +case 0xd8e4: +case 0xd8e5: +case 0xd8e6: +case 0xd8e7: +case 0xdae0: +case 0xdae1: +case 0xdae2: +case 0xdae3: +case 0xdae4: +case 0xdae5: +case 0xdae6: +case 0xdae7: +case 0xdce0: +case 0xdce1: +case 0xdce2: +case 0xdce3: +case 0xdce4: +case 0xdce5: +case 0xdce6: +case 0xdce7: +case 0xdee0: +case 0xdee1: +case 0xdee2: +case 0xdee3: +case 0xdee4: +case 0xdee5: +case 0xdee6: +case 0xdee7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb0e0: +case 0xb0e1: +case 0xb0e2: +case 0xb0e3: +case 0xb0e4: +case 0xb0e5: +case 0xb0e6: +case 0xb0e7: +case 0xb2e0: +case 0xb2e1: +case 0xb2e2: +case 0xb2e3: +case 0xb2e4: +case 0xb2e5: +case 0xb2e6: +case 0xb2e7: +case 0xb4e0: +case 0xb4e1: +case 0xb4e2: +case 0xb4e3: +case 0xb4e4: +case 0xb4e5: +case 0xb4e6: +case 0xb4e7: +case 0xb6e0: +case 0xb6e1: +case 0xb6e2: +case 0xb6e3: +case 0xb6e4: +case 0xb6e5: +case 0xb6e6: +case 0xb6e7: +case 0xb8e0: +case 0xb8e1: +case 0xb8e2: +case 0xb8e3: +case 0xb8e4: +case 0xb8e5: +case 0xb8e6: +case 0xb8e7: +case 0xbae0: +case 0xbae1: +case 0xbae2: +case 0xbae3: +case 0xbae4: +case 0xbae5: +case 0xbae6: +case 0xbae7: +case 0xbce0: +case 0xbce1: +case 0xbce2: +case 0xbce3: +case 0xbce4: +case 0xbce5: +case 0xbce6: +case 0xbce7: +case 0xbee0: +case 0xbee1: +case 0xbee2: +case 0xbee3: +case 0xbee4: +case 0xbee5: +case 0xbee6: +case 0xbee7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x90e0: +case 0x90e1: +case 0x90e2: +case 0x90e3: +case 0x90e4: +case 0x90e5: +case 0x90e6: +case 0x90e7: +case 0x92e0: +case 0x92e1: +case 0x92e2: +case 0x92e3: +case 0x92e4: +case 0x92e5: +case 0x92e6: +case 0x92e7: +case 0x94e0: +case 0x94e1: +case 0x94e2: +case 0x94e3: +case 0x94e4: +case 0x94e5: +case 0x94e6: +case 0x94e7: +case 0x96e0: +case 0x96e1: +case 0x96e2: +case 0x96e3: +case 0x96e4: +case 0x96e5: +case 0x96e6: +case 0x96e7: +case 0x98e0: +case 0x98e1: +case 0x98e2: +case 0x98e3: +case 0x98e4: +case 0x98e5: +case 0x98e6: +case 0x98e7: +case 0x9ae0: +case 0x9ae1: +case 0x9ae2: +case 0x9ae3: +case 0x9ae4: +case 0x9ae5: +case 0x9ae6: +case 0x9ae7: +case 0x9ce0: +case 0x9ce1: +case 0x9ce2: +case 0x9ce3: +case 0x9ce4: +case 0x9ce5: +case 0x9ce6: +case 0x9ce7: +case 0x9ee0: +case 0x9ee1: +case 0x9ee2: +case 0x9ee3: +case 0x9ee4: +case 0x9ee5: +case 0x9ee6: +case 0x9ee7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x3060: +case 0x3061: +case 0x3062: +case 0x3063: +case 0x3064: +case 0x3065: +case 0x3066: +case 0x3067: +case 0x3260: +case 0x3261: +case 0x3262: +case 0x3263: +case 0x3264: +case 0x3265: +case 0x3266: +case 0x3267: +case 0x3460: +case 0x3461: +case 0x3462: +case 0x3463: +case 0x3464: +case 0x3465: +case 0x3466: +case 0x3467: +case 0x3660: +case 0x3661: +case 0x3662: +case 0x3663: +case 0x3664: +case 0x3665: +case 0x3666: +case 0x3667: +case 0x3860: +case 0x3861: +case 0x3862: +case 0x3863: +case 0x3864: +case 0x3865: +case 0x3866: +case 0x3867: +case 0x3a60: +case 0x3a61: +case 0x3a62: +case 0x3a63: +case 0x3a64: +case 0x3a65: +case 0x3a66: +case 0x3a67: +case 0x3c60: +case 0x3c61: +case 0x3c62: +case 0x3c63: +case 0x3c64: +case 0x3c65: +case 0x3c66: +case 0x3c67: +case 0x3e60: +case 0x3e61: +case 0x3e62: +case 0x3e63: +case 0x3e64: +case 0x3e65: +case 0x3e66: +case 0x3e67: + { + HAM src(this, instr_b2_b0); MOVEA(src, instr_b11_b9); + } + break; + +case 0x44e0: +case 0x44e1: +case 0x44e2: +case 0x44e3: +case 0x44e4: +case 0x44e5: +case 0x44e6: +case 0x44e7: + { + HAM src(this, instr_b2_b0); MOVE_to_CCR(src); + } + break; + +case 0xc1e0: +case 0xc1e1: +case 0xc1e2: +case 0xc1e3: +case 0xc1e4: +case 0xc1e5: +case 0xc1e6: +case 0xc1e7: +case 0xc3e0: +case 0xc3e1: +case 0xc3e2: +case 0xc3e3: +case 0xc3e4: +case 0xc3e5: +case 0xc3e6: +case 0xc3e7: +case 0xc5e0: +case 0xc5e1: +case 0xc5e2: +case 0xc5e3: +case 0xc5e4: +case 0xc5e5: +case 0xc5e6: +case 0xc5e7: +case 0xc7e0: +case 0xc7e1: +case 0xc7e2: +case 0xc7e3: +case 0xc7e4: +case 0xc7e5: +case 0xc7e6: +case 0xc7e7: +case 0xc9e0: +case 0xc9e1: +case 0xc9e2: +case 0xc9e3: +case 0xc9e4: +case 0xc9e5: +case 0xc9e6: +case 0xc9e7: +case 0xcbe0: +case 0xcbe1: +case 0xcbe2: +case 0xcbe3: +case 0xcbe4: +case 0xcbe5: +case 0xcbe6: +case 0xcbe7: +case 0xcde0: +case 0xcde1: +case 0xcde2: +case 0xcde3: +case 0xcde4: +case 0xcde5: +case 0xcde6: +case 0xcde7: +case 0xcfe0: +case 0xcfe1: +case 0xcfe2: +case 0xcfe3: +case 0xcfe4: +case 0xcfe5: +case 0xcfe6: +case 0xcfe7: + { + HAM src(this, instr_b2_b0); MULS(src, instr_b11_b9); + } + break; + +case 0xc0e0: +case 0xc0e1: +case 0xc0e2: +case 0xc0e3: +case 0xc0e4: +case 0xc0e5: +case 0xc0e6: +case 0xc0e7: +case 0xc2e0: +case 0xc2e1: +case 0xc2e2: +case 0xc2e3: +case 0xc2e4: +case 0xc2e5: +case 0xc2e6: +case 0xc2e7: +case 0xc4e0: +case 0xc4e1: +case 0xc4e2: +case 0xc4e3: +case 0xc4e4: +case 0xc4e5: +case 0xc4e6: +case 0xc4e7: +case 0xc6e0: +case 0xc6e1: +case 0xc6e2: +case 0xc6e3: +case 0xc6e4: +case 0xc6e5: +case 0xc6e6: +case 0xc6e7: +case 0xc8e0: +case 0xc8e1: +case 0xc8e2: +case 0xc8e3: +case 0xc8e4: +case 0xc8e5: +case 0xc8e6: +case 0xc8e7: +case 0xcae0: +case 0xcae1: +case 0xcae2: +case 0xcae3: +case 0xcae4: +case 0xcae5: +case 0xcae6: +case 0xcae7: +case 0xcce0: +case 0xcce1: +case 0xcce2: +case 0xcce3: +case 0xcce4: +case 0xcce5: +case 0xcce6: +case 0xcce7: +case 0xcee0: +case 0xcee1: +case 0xcee2: +case 0xcee3: +case 0xcee4: +case 0xcee5: +case 0xcee6: +case 0xcee7: + { + HAM src(this, instr_b2_b0); MULU(src, instr_b11_b9); + } + break; + +case 0xe1e0: +case 0xe1e1: +case 0xe1e2: +case 0xe1e3: +case 0xe1e4: +case 0xe1e5: +case 0xe1e6: +case 0xe1e7: + { + HAM targ(this, instr_b2_b0); ASL(targ, 1); + } + break; + +case 0xe0e0: +case 0xe0e1: +case 0xe0e2: +case 0xe0e3: +case 0xe0e4: +case 0xe0e5: +case 0xe0e6: +case 0xe0e7: + { + HAM targ(this, instr_b2_b0); ASR(targ, 1); + } + break; + +case 0xe3e0: +case 0xe3e1: +case 0xe3e2: +case 0xe3e3: +case 0xe3e4: +case 0xe3e5: +case 0xe3e6: +case 0xe3e7: + { + HAM targ(this, instr_b2_b0); LSL(targ, 1); + } + break; + +case 0xe2e0: +case 0xe2e1: +case 0xe2e2: +case 0xe2e3: +case 0xe2e4: +case 0xe2e5: +case 0xe2e6: +case 0xe2e7: + { + HAM targ(this, instr_b2_b0); LSR(targ, 1); + } + break; + +case 0xe7e0: +case 0xe7e1: +case 0xe7e2: +case 0xe7e3: +case 0xe7e4: +case 0xe7e5: +case 0xe7e6: +case 0xe7e7: + { + HAM targ(this, instr_b2_b0); ROL(targ, 1); + } + break; + +case 0xe6e0: +case 0xe6e1: +case 0xe6e2: +case 0xe6e3: +case 0xe6e4: +case 0xe6e5: +case 0xe6e6: +case 0xe6e7: + { + HAM targ(this, instr_b2_b0); ROR(targ, 1); + } + break; + +case 0xe5e0: +case 0xe5e1: +case 0xe5e2: +case 0xe5e3: +case 0xe5e4: +case 0xe5e5: +case 0xe5e6: +case 0xe5e7: + { + HAM targ(this, instr_b2_b0); ROXL(targ, 1); + } + break; + +case 0xe4e0: +case 0xe4e1: +case 0xe4e2: +case 0xe4e3: +case 0xe4e4: +case 0xe4e5: +case 0xe4e6: +case 0xe4e7: + { + HAM targ(this, instr_b2_b0); ROXR(targ, 1); + } + break; + +case 0x4240: +case 0x4241: +case 0x4242: +case 0x4243: +case 0x4244: +case 0x4245: +case 0x4246: +case 0x4247: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x4880: +case 0x4881: +case 0x4882: +case 0x4883: +case 0x4884: +case 0x4885: +case 0x4886: +case 0x4887: + { + HAM dst(this, instr_b2_b0); EXT(dst); + } + break; + +case 0x4440: +case 0x4441: +case 0x4442: +case 0x4443: +case 0x4444: +case 0x4445: +case 0x4446: +case 0x4447: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x4040: +case 0x4041: +case 0x4042: +case 0x4043: +case 0x4044: +case 0x4045: +case 0x4046: +case 0x4047: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x4640: +case 0x4641: +case 0x4642: +case 0x4643: +case 0x4644: +case 0x4645: +case 0x4646: +case 0x4647: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x4a40: +case 0x4a41: +case 0x4a42: +case 0x4a43: +case 0x4a44: +case 0x4a45: +case 0x4a46: +case 0x4a47: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0xd179: +case 0xd379: +case 0xd579: +case 0xd779: +case 0xd979: +case 0xdb79: +case 0xdd79: +case 0xdf79: + { + HAM src(this, instr_b11_b9); HAM dst(this); ADD(src, dst); + } + break; + +case 0xc179: +case 0xc379: +case 0xc579: +case 0xc779: +case 0xc979: +case 0xcb79: +case 0xcd79: +case 0xcf79: + { + HAM src(this, instr_b11_b9); HAM dst(this); AND(src, dst); + } + break; + +case 0xb179: +case 0xb379: +case 0xb579: +case 0xb779: +case 0xb979: +case 0xbb79: +case 0xbd79: +case 0xbf79: + { + HAM src(this, instr_b11_b9); HAM dst(this); EOR(src, dst); + } + break; + +case 0x8179: +case 0x8379: +case 0x8579: +case 0x8779: +case 0x8979: +case 0x8b79: +case 0x8d79: +case 0x8f79: + { + HAM src(this, instr_b11_b9); HAM dst(this); OR(src, dst); + } + break; + +case 0x9179: +case 0x9379: +case 0x9579: +case 0x9779: +case 0x9979: +case 0x9b79: +case 0x9d79: +case 0x9f79: + { + HAM src(this, instr_b11_b9); HAM dst(this); SUB(src, dst); + } + break; + +case 0xd178: +case 0xd378: +case 0xd578: +case 0xd778: +case 0xd978: +case 0xdb78: +case 0xdd78: +case 0xdf78: + { + HAM src(this, instr_b11_b9); HAM dst(this); ADD(src, dst); + } + break; + +case 0xc178: +case 0xc378: +case 0xc578: +case 0xc778: +case 0xc978: +case 0xcb78: +case 0xcd78: +case 0xcf78: + { + HAM src(this, instr_b11_b9); HAM dst(this); AND(src, dst); + } + break; + +case 0xb178: +case 0xb378: +case 0xb578: +case 0xb778: +case 0xb978: +case 0xbb78: +case 0xbd78: +case 0xbf78: + { + HAM src(this, instr_b11_b9); HAM dst(this); EOR(src, dst); + } + break; + +case 0x8178: +case 0x8378: +case 0x8578: +case 0x8778: +case 0x8978: +case 0x8b78: +case 0x8d78: +case 0x8f78: + { + HAM src(this, instr_b11_b9); HAM dst(this); OR(src, dst); + } + break; + +case 0x9178: +case 0x9378: +case 0x9578: +case 0x9778: +case 0x9978: +case 0x9b78: +case 0x9d78: +case 0x9f78: + { + HAM src(this, instr_b11_b9); HAM dst(this); SUB(src, dst); + } + break; + +case 0xd150: +case 0xd151: +case 0xd152: +case 0xd153: +case 0xd154: +case 0xd155: +case 0xd156: +case 0xd157: +case 0xd350: +case 0xd351: +case 0xd352: +case 0xd353: +case 0xd354: +case 0xd355: +case 0xd356: +case 0xd357: +case 0xd550: +case 0xd551: +case 0xd552: +case 0xd553: +case 0xd554: +case 0xd555: +case 0xd556: +case 0xd557: +case 0xd750: +case 0xd751: +case 0xd752: +case 0xd753: +case 0xd754: +case 0xd755: +case 0xd756: +case 0xd757: +case 0xd950: +case 0xd951: +case 0xd952: +case 0xd953: +case 0xd954: +case 0xd955: +case 0xd956: +case 0xd957: +case 0xdb50: +case 0xdb51: +case 0xdb52: +case 0xdb53: +case 0xdb54: +case 0xdb55: +case 0xdb56: +case 0xdb57: +case 0xdd50: +case 0xdd51: +case 0xdd52: +case 0xdd53: +case 0xdd54: +case 0xdd55: +case 0xdd56: +case 0xdd57: +case 0xdf50: +case 0xdf51: +case 0xdf52: +case 0xdf53: +case 0xdf54: +case 0xdf55: +case 0xdf56: +case 0xdf57: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0xc150: +case 0xc151: +case 0xc152: +case 0xc153: +case 0xc154: +case 0xc155: +case 0xc156: +case 0xc157: +case 0xc350: +case 0xc351: +case 0xc352: +case 0xc353: +case 0xc354: +case 0xc355: +case 0xc356: +case 0xc357: +case 0xc550: +case 0xc551: +case 0xc552: +case 0xc553: +case 0xc554: +case 0xc555: +case 0xc556: +case 0xc557: +case 0xc750: +case 0xc751: +case 0xc752: +case 0xc753: +case 0xc754: +case 0xc755: +case 0xc756: +case 0xc757: +case 0xc950: +case 0xc951: +case 0xc952: +case 0xc953: +case 0xc954: +case 0xc955: +case 0xc956: +case 0xc957: +case 0xcb50: +case 0xcb51: +case 0xcb52: +case 0xcb53: +case 0xcb54: +case 0xcb55: +case 0xcb56: +case 0xcb57: +case 0xcd50: +case 0xcd51: +case 0xcd52: +case 0xcd53: +case 0xcd54: +case 0xcd55: +case 0xcd56: +case 0xcd57: +case 0xcf50: +case 0xcf51: +case 0xcf52: +case 0xcf53: +case 0xcf54: +case 0xcf55: +case 0xcf56: +case 0xcf57: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0xb150: +case 0xb151: +case 0xb152: +case 0xb153: +case 0xb154: +case 0xb155: +case 0xb156: +case 0xb157: +case 0xb350: +case 0xb351: +case 0xb352: +case 0xb353: +case 0xb354: +case 0xb355: +case 0xb356: +case 0xb357: +case 0xb550: +case 0xb551: +case 0xb552: +case 0xb553: +case 0xb554: +case 0xb555: +case 0xb556: +case 0xb557: +case 0xb750: +case 0xb751: +case 0xb752: +case 0xb753: +case 0xb754: +case 0xb755: +case 0xb756: +case 0xb757: +case 0xb950: +case 0xb951: +case 0xb952: +case 0xb953: +case 0xb954: +case 0xb955: +case 0xb956: +case 0xb957: +case 0xbb50: +case 0xbb51: +case 0xbb52: +case 0xbb53: +case 0xbb54: +case 0xbb55: +case 0xbb56: +case 0xbb57: +case 0xbd50: +case 0xbd51: +case 0xbd52: +case 0xbd53: +case 0xbd54: +case 0xbd55: +case 0xbd56: +case 0xbd57: +case 0xbf50: +case 0xbf51: +case 0xbf52: +case 0xbf53: +case 0xbf54: +case 0xbf55: +case 0xbf56: +case 0xbf57: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x8150: +case 0x8151: +case 0x8152: +case 0x8153: +case 0x8154: +case 0x8155: +case 0x8156: +case 0x8157: +case 0x8350: +case 0x8351: +case 0x8352: +case 0x8353: +case 0x8354: +case 0x8355: +case 0x8356: +case 0x8357: +case 0x8550: +case 0x8551: +case 0x8552: +case 0x8553: +case 0x8554: +case 0x8555: +case 0x8556: +case 0x8557: +case 0x8750: +case 0x8751: +case 0x8752: +case 0x8753: +case 0x8754: +case 0x8755: +case 0x8756: +case 0x8757: +case 0x8950: +case 0x8951: +case 0x8952: +case 0x8953: +case 0x8954: +case 0x8955: +case 0x8956: +case 0x8957: +case 0x8b50: +case 0x8b51: +case 0x8b52: +case 0x8b53: +case 0x8b54: +case 0x8b55: +case 0x8b56: +case 0x8b57: +case 0x8d50: +case 0x8d51: +case 0x8d52: +case 0x8d53: +case 0x8d54: +case 0x8d55: +case 0x8d56: +case 0x8d57: +case 0x8f50: +case 0x8f51: +case 0x8f52: +case 0x8f53: +case 0x8f54: +case 0x8f55: +case 0x8f56: +case 0x8f57: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x9150: +case 0x9151: +case 0x9152: +case 0x9153: +case 0x9154: +case 0x9155: +case 0x9156: +case 0x9157: +case 0x9350: +case 0x9351: +case 0x9352: +case 0x9353: +case 0x9354: +case 0x9355: +case 0x9356: +case 0x9357: +case 0x9550: +case 0x9551: +case 0x9552: +case 0x9553: +case 0x9554: +case 0x9555: +case 0x9556: +case 0x9557: +case 0x9750: +case 0x9751: +case 0x9752: +case 0x9753: +case 0x9754: +case 0x9755: +case 0x9756: +case 0x9757: +case 0x9950: +case 0x9951: +case 0x9952: +case 0x9953: +case 0x9954: +case 0x9955: +case 0x9956: +case 0x9957: +case 0x9b50: +case 0x9b51: +case 0x9b52: +case 0x9b53: +case 0x9b54: +case 0x9b55: +case 0x9b56: +case 0x9b57: +case 0x9d50: +case 0x9d51: +case 0x9d52: +case 0x9d53: +case 0x9d54: +case 0x9d55: +case 0x9d56: +case 0x9d57: +case 0x9f50: +case 0x9f51: +case 0x9f52: +case 0x9f53: +case 0x9f54: +case 0x9f55: +case 0x9f56: +case 0x9f57: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xd168: +case 0xd169: +case 0xd16a: +case 0xd16b: +case 0xd16c: +case 0xd16d: +case 0xd16e: +case 0xd16f: +case 0xd368: +case 0xd369: +case 0xd36a: +case 0xd36b: +case 0xd36c: +case 0xd36d: +case 0xd36e: +case 0xd36f: +case 0xd568: +case 0xd569: +case 0xd56a: +case 0xd56b: +case 0xd56c: +case 0xd56d: +case 0xd56e: +case 0xd56f: +case 0xd768: +case 0xd769: +case 0xd76a: +case 0xd76b: +case 0xd76c: +case 0xd76d: +case 0xd76e: +case 0xd76f: +case 0xd968: +case 0xd969: +case 0xd96a: +case 0xd96b: +case 0xd96c: +case 0xd96d: +case 0xd96e: +case 0xd96f: +case 0xdb68: +case 0xdb69: +case 0xdb6a: +case 0xdb6b: +case 0xdb6c: +case 0xdb6d: +case 0xdb6e: +case 0xdb6f: +case 0xdd68: +case 0xdd69: +case 0xdd6a: +case 0xdd6b: +case 0xdd6c: +case 0xdd6d: +case 0xdd6e: +case 0xdd6f: +case 0xdf68: +case 0xdf69: +case 0xdf6a: +case 0xdf6b: +case 0xdf6c: +case 0xdf6d: +case 0xdf6e: +case 0xdf6f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0xc168: +case 0xc169: +case 0xc16a: +case 0xc16b: +case 0xc16c: +case 0xc16d: +case 0xc16e: +case 0xc16f: +case 0xc368: +case 0xc369: +case 0xc36a: +case 0xc36b: +case 0xc36c: +case 0xc36d: +case 0xc36e: +case 0xc36f: +case 0xc568: +case 0xc569: +case 0xc56a: +case 0xc56b: +case 0xc56c: +case 0xc56d: +case 0xc56e: +case 0xc56f: +case 0xc768: +case 0xc769: +case 0xc76a: +case 0xc76b: +case 0xc76c: +case 0xc76d: +case 0xc76e: +case 0xc76f: +case 0xc968: +case 0xc969: +case 0xc96a: +case 0xc96b: +case 0xc96c: +case 0xc96d: +case 0xc96e: +case 0xc96f: +case 0xcb68: +case 0xcb69: +case 0xcb6a: +case 0xcb6b: +case 0xcb6c: +case 0xcb6d: +case 0xcb6e: +case 0xcb6f: +case 0xcd68: +case 0xcd69: +case 0xcd6a: +case 0xcd6b: +case 0xcd6c: +case 0xcd6d: +case 0xcd6e: +case 0xcd6f: +case 0xcf68: +case 0xcf69: +case 0xcf6a: +case 0xcf6b: +case 0xcf6c: +case 0xcf6d: +case 0xcf6e: +case 0xcf6f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0xb168: +case 0xb169: +case 0xb16a: +case 0xb16b: +case 0xb16c: +case 0xb16d: +case 0xb16e: +case 0xb16f: +case 0xb368: +case 0xb369: +case 0xb36a: +case 0xb36b: +case 0xb36c: +case 0xb36d: +case 0xb36e: +case 0xb36f: +case 0xb568: +case 0xb569: +case 0xb56a: +case 0xb56b: +case 0xb56c: +case 0xb56d: +case 0xb56e: +case 0xb56f: +case 0xb768: +case 0xb769: +case 0xb76a: +case 0xb76b: +case 0xb76c: +case 0xb76d: +case 0xb76e: +case 0xb76f: +case 0xb968: +case 0xb969: +case 0xb96a: +case 0xb96b: +case 0xb96c: +case 0xb96d: +case 0xb96e: +case 0xb96f: +case 0xbb68: +case 0xbb69: +case 0xbb6a: +case 0xbb6b: +case 0xbb6c: +case 0xbb6d: +case 0xbb6e: +case 0xbb6f: +case 0xbd68: +case 0xbd69: +case 0xbd6a: +case 0xbd6b: +case 0xbd6c: +case 0xbd6d: +case 0xbd6e: +case 0xbd6f: +case 0xbf68: +case 0xbf69: +case 0xbf6a: +case 0xbf6b: +case 0xbf6c: +case 0xbf6d: +case 0xbf6e: +case 0xbf6f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x8168: +case 0x8169: +case 0x816a: +case 0x816b: +case 0x816c: +case 0x816d: +case 0x816e: +case 0x816f: +case 0x8368: +case 0x8369: +case 0x836a: +case 0x836b: +case 0x836c: +case 0x836d: +case 0x836e: +case 0x836f: +case 0x8568: +case 0x8569: +case 0x856a: +case 0x856b: +case 0x856c: +case 0x856d: +case 0x856e: +case 0x856f: +case 0x8768: +case 0x8769: +case 0x876a: +case 0x876b: +case 0x876c: +case 0x876d: +case 0x876e: +case 0x876f: +case 0x8968: +case 0x8969: +case 0x896a: +case 0x896b: +case 0x896c: +case 0x896d: +case 0x896e: +case 0x896f: +case 0x8b68: +case 0x8b69: +case 0x8b6a: +case 0x8b6b: +case 0x8b6c: +case 0x8b6d: +case 0x8b6e: +case 0x8b6f: +case 0x8d68: +case 0x8d69: +case 0x8d6a: +case 0x8d6b: +case 0x8d6c: +case 0x8d6d: +case 0x8d6e: +case 0x8d6f: +case 0x8f68: +case 0x8f69: +case 0x8f6a: +case 0x8f6b: +case 0x8f6c: +case 0x8f6d: +case 0x8f6e: +case 0x8f6f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x9168: +case 0x9169: +case 0x916a: +case 0x916b: +case 0x916c: +case 0x916d: +case 0x916e: +case 0x916f: +case 0x9368: +case 0x9369: +case 0x936a: +case 0x936b: +case 0x936c: +case 0x936d: +case 0x936e: +case 0x936f: +case 0x9568: +case 0x9569: +case 0x956a: +case 0x956b: +case 0x956c: +case 0x956d: +case 0x956e: +case 0x956f: +case 0x9768: +case 0x9769: +case 0x976a: +case 0x976b: +case 0x976c: +case 0x976d: +case 0x976e: +case 0x976f: +case 0x9968: +case 0x9969: +case 0x996a: +case 0x996b: +case 0x996c: +case 0x996d: +case 0x996e: +case 0x996f: +case 0x9b68: +case 0x9b69: +case 0x9b6a: +case 0x9b6b: +case 0x9b6c: +case 0x9b6d: +case 0x9b6e: +case 0x9b6f: +case 0x9d68: +case 0x9d69: +case 0x9d6a: +case 0x9d6b: +case 0x9d6c: +case 0x9d6d: +case 0x9d6e: +case 0x9d6f: +case 0x9f68: +case 0x9f69: +case 0x9f6a: +case 0x9f6b: +case 0x9f6c: +case 0x9f6d: +case 0x9f6e: +case 0x9f6f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xd170: +case 0xd171: +case 0xd172: +case 0xd173: +case 0xd174: +case 0xd175: +case 0xd176: +case 0xd177: +case 0xd370: +case 0xd371: +case 0xd372: +case 0xd373: +case 0xd374: +case 0xd375: +case 0xd376: +case 0xd377: +case 0xd570: +case 0xd571: +case 0xd572: +case 0xd573: +case 0xd574: +case 0xd575: +case 0xd576: +case 0xd577: +case 0xd770: +case 0xd771: +case 0xd772: +case 0xd773: +case 0xd774: +case 0xd775: +case 0xd776: +case 0xd777: +case 0xd970: +case 0xd971: +case 0xd972: +case 0xd973: +case 0xd974: +case 0xd975: +case 0xd976: +case 0xd977: +case 0xdb70: +case 0xdb71: +case 0xdb72: +case 0xdb73: +case 0xdb74: +case 0xdb75: +case 0xdb76: +case 0xdb77: +case 0xdd70: +case 0xdd71: +case 0xdd72: +case 0xdd73: +case 0xdd74: +case 0xdd75: +case 0xdd76: +case 0xdd77: +case 0xdf70: +case 0xdf71: +case 0xdf72: +case 0xdf73: +case 0xdf74: +case 0xdf75: +case 0xdf76: +case 0xdf77: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0xc170: +case 0xc171: +case 0xc172: +case 0xc173: +case 0xc174: +case 0xc175: +case 0xc176: +case 0xc177: +case 0xc370: +case 0xc371: +case 0xc372: +case 0xc373: +case 0xc374: +case 0xc375: +case 0xc376: +case 0xc377: +case 0xc570: +case 0xc571: +case 0xc572: +case 0xc573: +case 0xc574: +case 0xc575: +case 0xc576: +case 0xc577: +case 0xc770: +case 0xc771: +case 0xc772: +case 0xc773: +case 0xc774: +case 0xc775: +case 0xc776: +case 0xc777: +case 0xc970: +case 0xc971: +case 0xc972: +case 0xc973: +case 0xc974: +case 0xc975: +case 0xc976: +case 0xc977: +case 0xcb70: +case 0xcb71: +case 0xcb72: +case 0xcb73: +case 0xcb74: +case 0xcb75: +case 0xcb76: +case 0xcb77: +case 0xcd70: +case 0xcd71: +case 0xcd72: +case 0xcd73: +case 0xcd74: +case 0xcd75: +case 0xcd76: +case 0xcd77: +case 0xcf70: +case 0xcf71: +case 0xcf72: +case 0xcf73: +case 0xcf74: +case 0xcf75: +case 0xcf76: +case 0xcf77: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0xb170: +case 0xb171: +case 0xb172: +case 0xb173: +case 0xb174: +case 0xb175: +case 0xb176: +case 0xb177: +case 0xb370: +case 0xb371: +case 0xb372: +case 0xb373: +case 0xb374: +case 0xb375: +case 0xb376: +case 0xb377: +case 0xb570: +case 0xb571: +case 0xb572: +case 0xb573: +case 0xb574: +case 0xb575: +case 0xb576: +case 0xb577: +case 0xb770: +case 0xb771: +case 0xb772: +case 0xb773: +case 0xb774: +case 0xb775: +case 0xb776: +case 0xb777: +case 0xb970: +case 0xb971: +case 0xb972: +case 0xb973: +case 0xb974: +case 0xb975: +case 0xb976: +case 0xb977: +case 0xbb70: +case 0xbb71: +case 0xbb72: +case 0xbb73: +case 0xbb74: +case 0xbb75: +case 0xbb76: +case 0xbb77: +case 0xbd70: +case 0xbd71: +case 0xbd72: +case 0xbd73: +case 0xbd74: +case 0xbd75: +case 0xbd76: +case 0xbd77: +case 0xbf70: +case 0xbf71: +case 0xbf72: +case 0xbf73: +case 0xbf74: +case 0xbf75: +case 0xbf76: +case 0xbf77: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x8170: +case 0x8171: +case 0x8172: +case 0x8173: +case 0x8174: +case 0x8175: +case 0x8176: +case 0x8177: +case 0x8370: +case 0x8371: +case 0x8372: +case 0x8373: +case 0x8374: +case 0x8375: +case 0x8376: +case 0x8377: +case 0x8570: +case 0x8571: +case 0x8572: +case 0x8573: +case 0x8574: +case 0x8575: +case 0x8576: +case 0x8577: +case 0x8770: +case 0x8771: +case 0x8772: +case 0x8773: +case 0x8774: +case 0x8775: +case 0x8776: +case 0x8777: +case 0x8970: +case 0x8971: +case 0x8972: +case 0x8973: +case 0x8974: +case 0x8975: +case 0x8976: +case 0x8977: +case 0x8b70: +case 0x8b71: +case 0x8b72: +case 0x8b73: +case 0x8b74: +case 0x8b75: +case 0x8b76: +case 0x8b77: +case 0x8d70: +case 0x8d71: +case 0x8d72: +case 0x8d73: +case 0x8d74: +case 0x8d75: +case 0x8d76: +case 0x8d77: +case 0x8f70: +case 0x8f71: +case 0x8f72: +case 0x8f73: +case 0x8f74: +case 0x8f75: +case 0x8f76: +case 0x8f77: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x9170: +case 0x9171: +case 0x9172: +case 0x9173: +case 0x9174: +case 0x9175: +case 0x9176: +case 0x9177: +case 0x9370: +case 0x9371: +case 0x9372: +case 0x9373: +case 0x9374: +case 0x9375: +case 0x9376: +case 0x9377: +case 0x9570: +case 0x9571: +case 0x9572: +case 0x9573: +case 0x9574: +case 0x9575: +case 0x9576: +case 0x9577: +case 0x9770: +case 0x9771: +case 0x9772: +case 0x9773: +case 0x9774: +case 0x9775: +case 0x9776: +case 0x9777: +case 0x9970: +case 0x9971: +case 0x9972: +case 0x9973: +case 0x9974: +case 0x9975: +case 0x9976: +case 0x9977: +case 0x9b70: +case 0x9b71: +case 0x9b72: +case 0x9b73: +case 0x9b74: +case 0x9b75: +case 0x9b76: +case 0x9b77: +case 0x9d70: +case 0x9d71: +case 0x9d72: +case 0x9d73: +case 0x9d74: +case 0x9d75: +case 0x9d76: +case 0x9d77: +case 0x9f70: +case 0x9f71: +case 0x9f72: +case 0x9f73: +case 0x9f74: +case 0x9f75: +case 0x9f76: +case 0x9f77: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xd158: +case 0xd159: +case 0xd15a: +case 0xd15b: +case 0xd15c: +case 0xd15d: +case 0xd15e: +case 0xd15f: +case 0xd358: +case 0xd359: +case 0xd35a: +case 0xd35b: +case 0xd35c: +case 0xd35d: +case 0xd35e: +case 0xd35f: +case 0xd558: +case 0xd559: +case 0xd55a: +case 0xd55b: +case 0xd55c: +case 0xd55d: +case 0xd55e: +case 0xd55f: +case 0xd758: +case 0xd759: +case 0xd75a: +case 0xd75b: +case 0xd75c: +case 0xd75d: +case 0xd75e: +case 0xd75f: +case 0xd958: +case 0xd959: +case 0xd95a: +case 0xd95b: +case 0xd95c: +case 0xd95d: +case 0xd95e: +case 0xd95f: +case 0xdb58: +case 0xdb59: +case 0xdb5a: +case 0xdb5b: +case 0xdb5c: +case 0xdb5d: +case 0xdb5e: +case 0xdb5f: +case 0xdd58: +case 0xdd59: +case 0xdd5a: +case 0xdd5b: +case 0xdd5c: +case 0xdd5d: +case 0xdd5e: +case 0xdd5f: +case 0xdf58: +case 0xdf59: +case 0xdf5a: +case 0xdf5b: +case 0xdf5c: +case 0xdf5d: +case 0xdf5e: +case 0xdf5f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0xc158: +case 0xc159: +case 0xc15a: +case 0xc15b: +case 0xc15c: +case 0xc15d: +case 0xc15e: +case 0xc15f: +case 0xc358: +case 0xc359: +case 0xc35a: +case 0xc35b: +case 0xc35c: +case 0xc35d: +case 0xc35e: +case 0xc35f: +case 0xc558: +case 0xc559: +case 0xc55a: +case 0xc55b: +case 0xc55c: +case 0xc55d: +case 0xc55e: +case 0xc55f: +case 0xc758: +case 0xc759: +case 0xc75a: +case 0xc75b: +case 0xc75c: +case 0xc75d: +case 0xc75e: +case 0xc75f: +case 0xc958: +case 0xc959: +case 0xc95a: +case 0xc95b: +case 0xc95c: +case 0xc95d: +case 0xc95e: +case 0xc95f: +case 0xcb58: +case 0xcb59: +case 0xcb5a: +case 0xcb5b: +case 0xcb5c: +case 0xcb5d: +case 0xcb5e: +case 0xcb5f: +case 0xcd58: +case 0xcd59: +case 0xcd5a: +case 0xcd5b: +case 0xcd5c: +case 0xcd5d: +case 0xcd5e: +case 0xcd5f: +case 0xcf58: +case 0xcf59: +case 0xcf5a: +case 0xcf5b: +case 0xcf5c: +case 0xcf5d: +case 0xcf5e: +case 0xcf5f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0xb158: +case 0xb159: +case 0xb15a: +case 0xb15b: +case 0xb15c: +case 0xb15d: +case 0xb15e: +case 0xb15f: +case 0xb358: +case 0xb359: +case 0xb35a: +case 0xb35b: +case 0xb35c: +case 0xb35d: +case 0xb35e: +case 0xb35f: +case 0xb558: +case 0xb559: +case 0xb55a: +case 0xb55b: +case 0xb55c: +case 0xb55d: +case 0xb55e: +case 0xb55f: +case 0xb758: +case 0xb759: +case 0xb75a: +case 0xb75b: +case 0xb75c: +case 0xb75d: +case 0xb75e: +case 0xb75f: +case 0xb958: +case 0xb959: +case 0xb95a: +case 0xb95b: +case 0xb95c: +case 0xb95d: +case 0xb95e: +case 0xb95f: +case 0xbb58: +case 0xbb59: +case 0xbb5a: +case 0xbb5b: +case 0xbb5c: +case 0xbb5d: +case 0xbb5e: +case 0xbb5f: +case 0xbd58: +case 0xbd59: +case 0xbd5a: +case 0xbd5b: +case 0xbd5c: +case 0xbd5d: +case 0xbd5e: +case 0xbd5f: +case 0xbf58: +case 0xbf59: +case 0xbf5a: +case 0xbf5b: +case 0xbf5c: +case 0xbf5d: +case 0xbf5e: +case 0xbf5f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x8158: +case 0x8159: +case 0x815a: +case 0x815b: +case 0x815c: +case 0x815d: +case 0x815e: +case 0x815f: +case 0x8358: +case 0x8359: +case 0x835a: +case 0x835b: +case 0x835c: +case 0x835d: +case 0x835e: +case 0x835f: +case 0x8558: +case 0x8559: +case 0x855a: +case 0x855b: +case 0x855c: +case 0x855d: +case 0x855e: +case 0x855f: +case 0x8758: +case 0x8759: +case 0x875a: +case 0x875b: +case 0x875c: +case 0x875d: +case 0x875e: +case 0x875f: +case 0x8958: +case 0x8959: +case 0x895a: +case 0x895b: +case 0x895c: +case 0x895d: +case 0x895e: +case 0x895f: +case 0x8b58: +case 0x8b59: +case 0x8b5a: +case 0x8b5b: +case 0x8b5c: +case 0x8b5d: +case 0x8b5e: +case 0x8b5f: +case 0x8d58: +case 0x8d59: +case 0x8d5a: +case 0x8d5b: +case 0x8d5c: +case 0x8d5d: +case 0x8d5e: +case 0x8d5f: +case 0x8f58: +case 0x8f59: +case 0x8f5a: +case 0x8f5b: +case 0x8f5c: +case 0x8f5d: +case 0x8f5e: +case 0x8f5f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x9158: +case 0x9159: +case 0x915a: +case 0x915b: +case 0x915c: +case 0x915d: +case 0x915e: +case 0x915f: +case 0x9358: +case 0x9359: +case 0x935a: +case 0x935b: +case 0x935c: +case 0x935d: +case 0x935e: +case 0x935f: +case 0x9558: +case 0x9559: +case 0x955a: +case 0x955b: +case 0x955c: +case 0x955d: +case 0x955e: +case 0x955f: +case 0x9758: +case 0x9759: +case 0x975a: +case 0x975b: +case 0x975c: +case 0x975d: +case 0x975e: +case 0x975f: +case 0x9958: +case 0x9959: +case 0x995a: +case 0x995b: +case 0x995c: +case 0x995d: +case 0x995e: +case 0x995f: +case 0x9b58: +case 0x9b59: +case 0x9b5a: +case 0x9b5b: +case 0x9b5c: +case 0x9b5d: +case 0x9b5e: +case 0x9b5f: +case 0x9d58: +case 0x9d59: +case 0x9d5a: +case 0x9d5b: +case 0x9d5c: +case 0x9d5d: +case 0x9d5e: +case 0x9d5f: +case 0x9f58: +case 0x9f59: +case 0x9f5a: +case 0x9f5b: +case 0x9f5c: +case 0x9f5d: +case 0x9f5e: +case 0x9f5f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xd160: +case 0xd161: +case 0xd162: +case 0xd163: +case 0xd164: +case 0xd165: +case 0xd166: +case 0xd167: +case 0xd360: +case 0xd361: +case 0xd362: +case 0xd363: +case 0xd364: +case 0xd365: +case 0xd366: +case 0xd367: +case 0xd560: +case 0xd561: +case 0xd562: +case 0xd563: +case 0xd564: +case 0xd565: +case 0xd566: +case 0xd567: +case 0xd760: +case 0xd761: +case 0xd762: +case 0xd763: +case 0xd764: +case 0xd765: +case 0xd766: +case 0xd767: +case 0xd960: +case 0xd961: +case 0xd962: +case 0xd963: +case 0xd964: +case 0xd965: +case 0xd966: +case 0xd967: +case 0xdb60: +case 0xdb61: +case 0xdb62: +case 0xdb63: +case 0xdb64: +case 0xdb65: +case 0xdb66: +case 0xdb67: +case 0xdd60: +case 0xdd61: +case 0xdd62: +case 0xdd63: +case 0xdd64: +case 0xdd65: +case 0xdd66: +case 0xdd67: +case 0xdf60: +case 0xdf61: +case 0xdf62: +case 0xdf63: +case 0xdf64: +case 0xdf65: +case 0xdf66: +case 0xdf67: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0xc160: +case 0xc161: +case 0xc162: +case 0xc163: +case 0xc164: +case 0xc165: +case 0xc166: +case 0xc167: +case 0xc360: +case 0xc361: +case 0xc362: +case 0xc363: +case 0xc364: +case 0xc365: +case 0xc366: +case 0xc367: +case 0xc560: +case 0xc561: +case 0xc562: +case 0xc563: +case 0xc564: +case 0xc565: +case 0xc566: +case 0xc567: +case 0xc760: +case 0xc761: +case 0xc762: +case 0xc763: +case 0xc764: +case 0xc765: +case 0xc766: +case 0xc767: +case 0xc960: +case 0xc961: +case 0xc962: +case 0xc963: +case 0xc964: +case 0xc965: +case 0xc966: +case 0xc967: +case 0xcb60: +case 0xcb61: +case 0xcb62: +case 0xcb63: +case 0xcb64: +case 0xcb65: +case 0xcb66: +case 0xcb67: +case 0xcd60: +case 0xcd61: +case 0xcd62: +case 0xcd63: +case 0xcd64: +case 0xcd65: +case 0xcd66: +case 0xcd67: +case 0xcf60: +case 0xcf61: +case 0xcf62: +case 0xcf63: +case 0xcf64: +case 0xcf65: +case 0xcf66: +case 0xcf67: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0xb160: +case 0xb161: +case 0xb162: +case 0xb163: +case 0xb164: +case 0xb165: +case 0xb166: +case 0xb167: +case 0xb360: +case 0xb361: +case 0xb362: +case 0xb363: +case 0xb364: +case 0xb365: +case 0xb366: +case 0xb367: +case 0xb560: +case 0xb561: +case 0xb562: +case 0xb563: +case 0xb564: +case 0xb565: +case 0xb566: +case 0xb567: +case 0xb760: +case 0xb761: +case 0xb762: +case 0xb763: +case 0xb764: +case 0xb765: +case 0xb766: +case 0xb767: +case 0xb960: +case 0xb961: +case 0xb962: +case 0xb963: +case 0xb964: +case 0xb965: +case 0xb966: +case 0xb967: +case 0xbb60: +case 0xbb61: +case 0xbb62: +case 0xbb63: +case 0xbb64: +case 0xbb65: +case 0xbb66: +case 0xbb67: +case 0xbd60: +case 0xbd61: +case 0xbd62: +case 0xbd63: +case 0xbd64: +case 0xbd65: +case 0xbd66: +case 0xbd67: +case 0xbf60: +case 0xbf61: +case 0xbf62: +case 0xbf63: +case 0xbf64: +case 0xbf65: +case 0xbf66: +case 0xbf67: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x8160: +case 0x8161: +case 0x8162: +case 0x8163: +case 0x8164: +case 0x8165: +case 0x8166: +case 0x8167: +case 0x8360: +case 0x8361: +case 0x8362: +case 0x8363: +case 0x8364: +case 0x8365: +case 0x8366: +case 0x8367: +case 0x8560: +case 0x8561: +case 0x8562: +case 0x8563: +case 0x8564: +case 0x8565: +case 0x8566: +case 0x8567: +case 0x8760: +case 0x8761: +case 0x8762: +case 0x8763: +case 0x8764: +case 0x8765: +case 0x8766: +case 0x8767: +case 0x8960: +case 0x8961: +case 0x8962: +case 0x8963: +case 0x8964: +case 0x8965: +case 0x8966: +case 0x8967: +case 0x8b60: +case 0x8b61: +case 0x8b62: +case 0x8b63: +case 0x8b64: +case 0x8b65: +case 0x8b66: +case 0x8b67: +case 0x8d60: +case 0x8d61: +case 0x8d62: +case 0x8d63: +case 0x8d64: +case 0x8d65: +case 0x8d66: +case 0x8d67: +case 0x8f60: +case 0x8f61: +case 0x8f62: +case 0x8f63: +case 0x8f64: +case 0x8f65: +case 0x8f66: +case 0x8f67: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x9160: +case 0x9161: +case 0x9162: +case 0x9163: +case 0x9164: +case 0x9165: +case 0x9166: +case 0x9167: +case 0x9360: +case 0x9361: +case 0x9362: +case 0x9363: +case 0x9364: +case 0x9365: +case 0x9366: +case 0x9367: +case 0x9560: +case 0x9561: +case 0x9562: +case 0x9563: +case 0x9564: +case 0x9565: +case 0x9566: +case 0x9567: +case 0x9760: +case 0x9761: +case 0x9762: +case 0x9763: +case 0x9764: +case 0x9765: +case 0x9766: +case 0x9767: +case 0x9960: +case 0x9961: +case 0x9962: +case 0x9963: +case 0x9964: +case 0x9965: +case 0x9966: +case 0x9967: +case 0x9b60: +case 0x9b61: +case 0x9b62: +case 0x9b63: +case 0x9b64: +case 0x9b65: +case 0x9b66: +case 0x9b67: +case 0x9d60: +case 0x9d61: +case 0x9d62: +case 0x9d63: +case 0x9d64: +case 0x9d65: +case 0x9d66: +case 0x9d67: +case 0x9f60: +case 0x9f61: +case 0x9f62: +case 0x9f63: +case 0x9f64: +case 0x9f65: +case 0x9f66: +case 0x9f67: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xb140: +case 0xb141: +case 0xb142: +case 0xb143: +case 0xb144: +case 0xb145: +case 0xb146: +case 0xb147: +case 0xb340: +case 0xb341: +case 0xb342: +case 0xb343: +case 0xb344: +case 0xb345: +case 0xb346: +case 0xb347: +case 0xb540: +case 0xb541: +case 0xb542: +case 0xb543: +case 0xb544: +case 0xb545: +case 0xb546: +case 0xb547: +case 0xb740: +case 0xb741: +case 0xb742: +case 0xb743: +case 0xb744: +case 0xb745: +case 0xb746: +case 0xb747: +case 0xb940: +case 0xb941: +case 0xb942: +case 0xb943: +case 0xb944: +case 0xb945: +case 0xb946: +case 0xb947: +case 0xbb40: +case 0xbb41: +case 0xbb42: +case 0xbb43: +case 0xbb44: +case 0xbb45: +case 0xbb46: +case 0xbb47: +case 0xbd40: +case 0xbd41: +case 0xbd42: +case 0xbd43: +case 0xbd44: +case 0xbd45: +case 0xbd46: +case 0xbd47: +case 0xbf40: +case 0xbf41: +case 0xbf42: +case 0xbf43: +case 0xbf44: +case 0xbf45: +case 0xbf46: +case 0xbf47: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x81c0: +case 0x81c1: +case 0x81c2: +case 0x81c3: +case 0x81c4: +case 0x81c5: +case 0x81c6: +case 0x81c7: +case 0x83c0: +case 0x83c1: +case 0x83c2: +case 0x83c3: +case 0x83c4: +case 0x83c5: +case 0x83c6: +case 0x83c7: +case 0x85c0: +case 0x85c1: +case 0x85c2: +case 0x85c3: +case 0x85c4: +case 0x85c5: +case 0x85c6: +case 0x85c7: +case 0x87c0: +case 0x87c1: +case 0x87c2: +case 0x87c3: +case 0x87c4: +case 0x87c5: +case 0x87c6: +case 0x87c7: +case 0x89c0: +case 0x89c1: +case 0x89c2: +case 0x89c3: +case 0x89c4: +case 0x89c5: +case 0x89c6: +case 0x89c7: +case 0x8bc0: +case 0x8bc1: +case 0x8bc2: +case 0x8bc3: +case 0x8bc4: +case 0x8bc5: +case 0x8bc6: +case 0x8bc7: +case 0x8dc0: +case 0x8dc1: +case 0x8dc2: +case 0x8dc3: +case 0x8dc4: +case 0x8dc5: +case 0x8dc6: +case 0x8dc7: +case 0x8fc0: +case 0x8fc1: +case 0x8fc2: +case 0x8fc3: +case 0x8fc4: +case 0x8fc5: +case 0x8fc6: +case 0x8fc7: + { + HAM src(this, instr_b2_b0); DIVS(src, instr_b11_b9); + } + break; + +case 0x80c0: +case 0x80c1: +case 0x80c2: +case 0x80c3: +case 0x80c4: +case 0x80c5: +case 0x80c6: +case 0x80c7: +case 0x82c0: +case 0x82c1: +case 0x82c2: +case 0x82c3: +case 0x82c4: +case 0x82c5: +case 0x82c6: +case 0x82c7: +case 0x84c0: +case 0x84c1: +case 0x84c2: +case 0x84c3: +case 0x84c4: +case 0x84c5: +case 0x84c6: +case 0x84c7: +case 0x86c0: +case 0x86c1: +case 0x86c2: +case 0x86c3: +case 0x86c4: +case 0x86c5: +case 0x86c6: +case 0x86c7: +case 0x88c0: +case 0x88c1: +case 0x88c2: +case 0x88c3: +case 0x88c4: +case 0x88c5: +case 0x88c6: +case 0x88c7: +case 0x8ac0: +case 0x8ac1: +case 0x8ac2: +case 0x8ac3: +case 0x8ac4: +case 0x8ac5: +case 0x8ac6: +case 0x8ac7: +case 0x8cc0: +case 0x8cc1: +case 0x8cc2: +case 0x8cc3: +case 0x8cc4: +case 0x8cc5: +case 0x8cc6: +case 0x8cc7: +case 0x8ec0: +case 0x8ec1: +case 0x8ec2: +case 0x8ec3: +case 0x8ec4: +case 0x8ec5: +case 0x8ec6: +case 0x8ec7: + { + HAM src(this, instr_b2_b0); DIVU(src, instr_b11_b9); + } + break; + +case 0x33c0: +case 0x33c1: +case 0x33c2: +case 0x33c3: +case 0x33c4: +case 0x33c5: +case 0x33c6: +case 0x33c7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x31c0: +case 0x31c1: +case 0x31c2: +case 0x31c3: +case 0x31c4: +case 0x31c5: +case 0x31c6: +case 0x31c7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x3080: +case 0x3081: +case 0x3082: +case 0x3083: +case 0x3084: +case 0x3085: +case 0x3086: +case 0x3087: +case 0x3280: +case 0x3281: +case 0x3282: +case 0x3283: +case 0x3284: +case 0x3285: +case 0x3286: +case 0x3287: +case 0x3480: +case 0x3481: +case 0x3482: +case 0x3483: +case 0x3484: +case 0x3485: +case 0x3486: +case 0x3487: +case 0x3680: +case 0x3681: +case 0x3682: +case 0x3683: +case 0x3684: +case 0x3685: +case 0x3686: +case 0x3687: +case 0x3880: +case 0x3881: +case 0x3882: +case 0x3883: +case 0x3884: +case 0x3885: +case 0x3886: +case 0x3887: +case 0x3a80: +case 0x3a81: +case 0x3a82: +case 0x3a83: +case 0x3a84: +case 0x3a85: +case 0x3a86: +case 0x3a87: +case 0x3c80: +case 0x3c81: +case 0x3c82: +case 0x3c83: +case 0x3c84: +case 0x3c85: +case 0x3c86: +case 0x3c87: +case 0x3e80: +case 0x3e81: +case 0x3e82: +case 0x3e83: +case 0x3e84: +case 0x3e85: +case 0x3e86: +case 0x3e87: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3140: +case 0x3141: +case 0x3142: +case 0x3143: +case 0x3144: +case 0x3145: +case 0x3146: +case 0x3147: +case 0x3340: +case 0x3341: +case 0x3342: +case 0x3343: +case 0x3344: +case 0x3345: +case 0x3346: +case 0x3347: +case 0x3540: +case 0x3541: +case 0x3542: +case 0x3543: +case 0x3544: +case 0x3545: +case 0x3546: +case 0x3547: +case 0x3740: +case 0x3741: +case 0x3742: +case 0x3743: +case 0x3744: +case 0x3745: +case 0x3746: +case 0x3747: +case 0x3940: +case 0x3941: +case 0x3942: +case 0x3943: +case 0x3944: +case 0x3945: +case 0x3946: +case 0x3947: +case 0x3b40: +case 0x3b41: +case 0x3b42: +case 0x3b43: +case 0x3b44: +case 0x3b45: +case 0x3b46: +case 0x3b47: +case 0x3d40: +case 0x3d41: +case 0x3d42: +case 0x3d43: +case 0x3d44: +case 0x3d45: +case 0x3d46: +case 0x3d47: +case 0x3f40: +case 0x3f41: +case 0x3f42: +case 0x3f43: +case 0x3f44: +case 0x3f45: +case 0x3f46: +case 0x3f47: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3180: +case 0x3181: +case 0x3182: +case 0x3183: +case 0x3184: +case 0x3185: +case 0x3186: +case 0x3187: +case 0x3380: +case 0x3381: +case 0x3382: +case 0x3383: +case 0x3384: +case 0x3385: +case 0x3386: +case 0x3387: +case 0x3580: +case 0x3581: +case 0x3582: +case 0x3583: +case 0x3584: +case 0x3585: +case 0x3586: +case 0x3587: +case 0x3780: +case 0x3781: +case 0x3782: +case 0x3783: +case 0x3784: +case 0x3785: +case 0x3786: +case 0x3787: +case 0x3980: +case 0x3981: +case 0x3982: +case 0x3983: +case 0x3984: +case 0x3985: +case 0x3986: +case 0x3987: +case 0x3b80: +case 0x3b81: +case 0x3b82: +case 0x3b83: +case 0x3b84: +case 0x3b85: +case 0x3b86: +case 0x3b87: +case 0x3d80: +case 0x3d81: +case 0x3d82: +case 0x3d83: +case 0x3d84: +case 0x3d85: +case 0x3d86: +case 0x3d87: +case 0x3f80: +case 0x3f81: +case 0x3f82: +case 0x3f83: +case 0x3f84: +case 0x3f85: +case 0x3f86: +case 0x3f87: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x30c0: +case 0x30c1: +case 0x30c2: +case 0x30c3: +case 0x30c4: +case 0x30c5: +case 0x30c6: +case 0x30c7: +case 0x32c0: +case 0x32c1: +case 0x32c2: +case 0x32c3: +case 0x32c4: +case 0x32c5: +case 0x32c6: +case 0x32c7: +case 0x34c0: +case 0x34c1: +case 0x34c2: +case 0x34c3: +case 0x34c4: +case 0x34c5: +case 0x34c6: +case 0x34c7: +case 0x36c0: +case 0x36c1: +case 0x36c2: +case 0x36c3: +case 0x36c4: +case 0x36c5: +case 0x36c6: +case 0x36c7: +case 0x38c0: +case 0x38c1: +case 0x38c2: +case 0x38c3: +case 0x38c4: +case 0x38c5: +case 0x38c6: +case 0x38c7: +case 0x3ac0: +case 0x3ac1: +case 0x3ac2: +case 0x3ac3: +case 0x3ac4: +case 0x3ac5: +case 0x3ac6: +case 0x3ac7: +case 0x3cc0: +case 0x3cc1: +case 0x3cc2: +case 0x3cc3: +case 0x3cc4: +case 0x3cc5: +case 0x3cc6: +case 0x3cc7: +case 0x3ec0: +case 0x3ec1: +case 0x3ec2: +case 0x3ec3: +case 0x3ec4: +case 0x3ec5: +case 0x3ec6: +case 0x3ec7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x3100: +case 0x3101: +case 0x3102: +case 0x3103: +case 0x3104: +case 0x3105: +case 0x3106: +case 0x3107: +case 0x3300: +case 0x3301: +case 0x3302: +case 0x3303: +case 0x3304: +case 0x3305: +case 0x3306: +case 0x3307: +case 0x3500: +case 0x3501: +case 0x3502: +case 0x3503: +case 0x3504: +case 0x3505: +case 0x3506: +case 0x3507: +case 0x3700: +case 0x3701: +case 0x3702: +case 0x3703: +case 0x3704: +case 0x3705: +case 0x3706: +case 0x3707: +case 0x3900: +case 0x3901: +case 0x3902: +case 0x3903: +case 0x3904: +case 0x3905: +case 0x3906: +case 0x3907: +case 0x3b00: +case 0x3b01: +case 0x3b02: +case 0x3b03: +case 0x3b04: +case 0x3b05: +case 0x3b06: +case 0x3b07: +case 0x3d00: +case 0x3d01: +case 0x3d02: +case 0x3d03: +case 0x3d04: +case 0x3d05: +case 0x3d06: +case 0x3d07: +case 0x3f00: +case 0x3f01: +case 0x3f02: +case 0x3f03: +case 0x3f04: +case 0x3f05: +case 0x3f06: +case 0x3f07: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd040: +case 0xd041: +case 0xd042: +case 0xd043: +case 0xd044: +case 0xd045: +case 0xd046: +case 0xd047: +case 0xd240: +case 0xd241: +case 0xd242: +case 0xd243: +case 0xd244: +case 0xd245: +case 0xd246: +case 0xd247: +case 0xd440: +case 0xd441: +case 0xd442: +case 0xd443: +case 0xd444: +case 0xd445: +case 0xd446: +case 0xd447: +case 0xd640: +case 0xd641: +case 0xd642: +case 0xd643: +case 0xd644: +case 0xd645: +case 0xd646: +case 0xd647: +case 0xd840: +case 0xd841: +case 0xd842: +case 0xd843: +case 0xd844: +case 0xd845: +case 0xd846: +case 0xd847: +case 0xda40: +case 0xda41: +case 0xda42: +case 0xda43: +case 0xda44: +case 0xda45: +case 0xda46: +case 0xda47: +case 0xdc40: +case 0xdc41: +case 0xdc42: +case 0xdc43: +case 0xdc44: +case 0xdc45: +case 0xdc46: +case 0xdc47: +case 0xde40: +case 0xde41: +case 0xde42: +case 0xde43: +case 0xde44: +case 0xde45: +case 0xde46: +case 0xde47: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xd140: +case 0xd141: +case 0xd142: +case 0xd143: +case 0xd144: +case 0xd145: +case 0xd146: +case 0xd147: +case 0xd340: +case 0xd341: +case 0xd342: +case 0xd343: +case 0xd344: +case 0xd345: +case 0xd346: +case 0xd347: +case 0xd540: +case 0xd541: +case 0xd542: +case 0xd543: +case 0xd544: +case 0xd545: +case 0xd546: +case 0xd547: +case 0xd740: +case 0xd741: +case 0xd742: +case 0xd743: +case 0xd744: +case 0xd745: +case 0xd746: +case 0xd747: +case 0xd940: +case 0xd941: +case 0xd942: +case 0xd943: +case 0xd944: +case 0xd945: +case 0xd946: +case 0xd947: +case 0xdb40: +case 0xdb41: +case 0xdb42: +case 0xdb43: +case 0xdb44: +case 0xdb45: +case 0xdb46: +case 0xdb47: +case 0xdd40: +case 0xdd41: +case 0xdd42: +case 0xdd43: +case 0xdd44: +case 0xdd45: +case 0xdd46: +case 0xdd47: +case 0xdf40: +case 0xdf41: +case 0xdf42: +case 0xdf43: +case 0xdf44: +case 0xdf45: +case 0xdf46: +case 0xdf47: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADDX(src, dst); + } + break; + +case 0xc040: +case 0xc041: +case 0xc042: +case 0xc043: +case 0xc044: +case 0xc045: +case 0xc046: +case 0xc047: +case 0xc240: +case 0xc241: +case 0xc242: +case 0xc243: +case 0xc244: +case 0xc245: +case 0xc246: +case 0xc247: +case 0xc440: +case 0xc441: +case 0xc442: +case 0xc443: +case 0xc444: +case 0xc445: +case 0xc446: +case 0xc447: +case 0xc640: +case 0xc641: +case 0xc642: +case 0xc643: +case 0xc644: +case 0xc645: +case 0xc646: +case 0xc647: +case 0xc840: +case 0xc841: +case 0xc842: +case 0xc843: +case 0xc844: +case 0xc845: +case 0xc846: +case 0xc847: +case 0xca40: +case 0xca41: +case 0xca42: +case 0xca43: +case 0xca44: +case 0xca45: +case 0xca46: +case 0xca47: +case 0xcc40: +case 0xcc41: +case 0xcc42: +case 0xcc43: +case 0xcc44: +case 0xcc45: +case 0xcc46: +case 0xcc47: +case 0xce40: +case 0xce41: +case 0xce42: +case 0xce43: +case 0xce44: +case 0xce45: +case 0xce46: +case 0xce47: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0x4180: +case 0x4181: +case 0x4182: +case 0x4183: +case 0x4184: +case 0x4185: +case 0x4186: +case 0x4187: +case 0x4380: +case 0x4381: +case 0x4382: +case 0x4383: +case 0x4384: +case 0x4385: +case 0x4386: +case 0x4387: +case 0x4580: +case 0x4581: +case 0x4582: +case 0x4583: +case 0x4584: +case 0x4585: +case 0x4586: +case 0x4587: +case 0x4780: +case 0x4781: +case 0x4782: +case 0x4783: +case 0x4784: +case 0x4785: +case 0x4786: +case 0x4787: +case 0x4980: +case 0x4981: +case 0x4982: +case 0x4983: +case 0x4984: +case 0x4985: +case 0x4986: +case 0x4987: +case 0x4b80: +case 0x4b81: +case 0x4b82: +case 0x4b83: +case 0x4b84: +case 0x4b85: +case 0x4b86: +case 0x4b87: +case 0x4d80: +case 0x4d81: +case 0x4d82: +case 0x4d83: +case 0x4d84: +case 0x4d85: +case 0x4d86: +case 0x4d87: +case 0x4f80: +case 0x4f81: +case 0x4f82: +case 0x4f83: +case 0x4f84: +case 0x4f85: +case 0x4f86: +case 0x4f87: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CHK(src, dst); + } + break; + +case 0xb040: +case 0xb041: +case 0xb042: +case 0xb043: +case 0xb044: +case 0xb045: +case 0xb046: +case 0xb047: +case 0xb240: +case 0xb241: +case 0xb242: +case 0xb243: +case 0xb244: +case 0xb245: +case 0xb246: +case 0xb247: +case 0xb440: +case 0xb441: +case 0xb442: +case 0xb443: +case 0xb444: +case 0xb445: +case 0xb446: +case 0xb447: +case 0xb640: +case 0xb641: +case 0xb642: +case 0xb643: +case 0xb644: +case 0xb645: +case 0xb646: +case 0xb647: +case 0xb840: +case 0xb841: +case 0xb842: +case 0xb843: +case 0xb844: +case 0xb845: +case 0xb846: +case 0xb847: +case 0xba40: +case 0xba41: +case 0xba42: +case 0xba43: +case 0xba44: +case 0xba45: +case 0xba46: +case 0xba47: +case 0xbc40: +case 0xbc41: +case 0xbc42: +case 0xbc43: +case 0xbc44: +case 0xbc45: +case 0xbc46: +case 0xbc47: +case 0xbe40: +case 0xbe41: +case 0xbe42: +case 0xbe43: +case 0xbe44: +case 0xbe45: +case 0xbe46: +case 0xbe47: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x3000: +case 0x3001: +case 0x3002: +case 0x3003: +case 0x3004: +case 0x3005: +case 0x3006: +case 0x3007: +case 0x3200: +case 0x3201: +case 0x3202: +case 0x3203: +case 0x3204: +case 0x3205: +case 0x3206: +case 0x3207: +case 0x3400: +case 0x3401: +case 0x3402: +case 0x3403: +case 0x3404: +case 0x3405: +case 0x3406: +case 0x3407: +case 0x3600: +case 0x3601: +case 0x3602: +case 0x3603: +case 0x3604: +case 0x3605: +case 0x3606: +case 0x3607: +case 0x3800: +case 0x3801: +case 0x3802: +case 0x3803: +case 0x3804: +case 0x3805: +case 0x3806: +case 0x3807: +case 0x3a00: +case 0x3a01: +case 0x3a02: +case 0x3a03: +case 0x3a04: +case 0x3a05: +case 0x3a06: +case 0x3a07: +case 0x3c00: +case 0x3c01: +case 0x3c02: +case 0x3c03: +case 0x3c04: +case 0x3c05: +case 0x3c06: +case 0x3c07: +case 0x3e00: +case 0x3e01: +case 0x3e02: +case 0x3e03: +case 0x3e04: +case 0x3e05: +case 0x3e06: +case 0x3e07: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8040: +case 0x8041: +case 0x8042: +case 0x8043: +case 0x8044: +case 0x8045: +case 0x8046: +case 0x8047: +case 0x8240: +case 0x8241: +case 0x8242: +case 0x8243: +case 0x8244: +case 0x8245: +case 0x8246: +case 0x8247: +case 0x8440: +case 0x8441: +case 0x8442: +case 0x8443: +case 0x8444: +case 0x8445: +case 0x8446: +case 0x8447: +case 0x8640: +case 0x8641: +case 0x8642: +case 0x8643: +case 0x8644: +case 0x8645: +case 0x8646: +case 0x8647: +case 0x8840: +case 0x8841: +case 0x8842: +case 0x8843: +case 0x8844: +case 0x8845: +case 0x8846: +case 0x8847: +case 0x8a40: +case 0x8a41: +case 0x8a42: +case 0x8a43: +case 0x8a44: +case 0x8a45: +case 0x8a46: +case 0x8a47: +case 0x8c40: +case 0x8c41: +case 0x8c42: +case 0x8c43: +case 0x8c44: +case 0x8c45: +case 0x8c46: +case 0x8c47: +case 0x8e40: +case 0x8e41: +case 0x8e42: +case 0x8e43: +case 0x8e44: +case 0x8e45: +case 0x8e46: +case 0x8e47: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9040: +case 0x9041: +case 0x9042: +case 0x9043: +case 0x9044: +case 0x9045: +case 0x9046: +case 0x9047: +case 0x9240: +case 0x9241: +case 0x9242: +case 0x9243: +case 0x9244: +case 0x9245: +case 0x9246: +case 0x9247: +case 0x9440: +case 0x9441: +case 0x9442: +case 0x9443: +case 0x9444: +case 0x9445: +case 0x9446: +case 0x9447: +case 0x9640: +case 0x9641: +case 0x9642: +case 0x9643: +case 0x9644: +case 0x9645: +case 0x9646: +case 0x9647: +case 0x9840: +case 0x9841: +case 0x9842: +case 0x9843: +case 0x9844: +case 0x9845: +case 0x9846: +case 0x9847: +case 0x9a40: +case 0x9a41: +case 0x9a42: +case 0x9a43: +case 0x9a44: +case 0x9a45: +case 0x9a46: +case 0x9a47: +case 0x9c40: +case 0x9c41: +case 0x9c42: +case 0x9c43: +case 0x9c44: +case 0x9c45: +case 0x9c46: +case 0x9c47: +case 0x9e40: +case 0x9e41: +case 0x9e42: +case 0x9e43: +case 0x9e44: +case 0x9e45: +case 0x9e46: +case 0x9e47: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x9140: +case 0x9141: +case 0x9142: +case 0x9143: +case 0x9144: +case 0x9145: +case 0x9146: +case 0x9147: +case 0x9340: +case 0x9341: +case 0x9342: +case 0x9343: +case 0x9344: +case 0x9345: +case 0x9346: +case 0x9347: +case 0x9540: +case 0x9541: +case 0x9542: +case 0x9543: +case 0x9544: +case 0x9545: +case 0x9546: +case 0x9547: +case 0x9740: +case 0x9741: +case 0x9742: +case 0x9743: +case 0x9744: +case 0x9745: +case 0x9746: +case 0x9747: +case 0x9940: +case 0x9941: +case 0x9942: +case 0x9943: +case 0x9944: +case 0x9945: +case 0x9946: +case 0x9947: +case 0x9b40: +case 0x9b41: +case 0x9b42: +case 0x9b43: +case 0x9b44: +case 0x9b45: +case 0x9b46: +case 0x9b47: +case 0x9d40: +case 0x9d41: +case 0x9d42: +case 0x9d43: +case 0x9d44: +case 0x9d45: +case 0x9d46: +case 0x9d47: +case 0x9f40: +case 0x9f41: +case 0x9f42: +case 0x9f43: +case 0x9f44: +case 0x9f45: +case 0x9f46: +case 0x9f47: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUBX(src, dst); + } + break; + +case 0xd0c0: +case 0xd0c1: +case 0xd0c2: +case 0xd0c3: +case 0xd0c4: +case 0xd0c5: +case 0xd0c6: +case 0xd0c7: +case 0xd2c0: +case 0xd2c1: +case 0xd2c2: +case 0xd2c3: +case 0xd2c4: +case 0xd2c5: +case 0xd2c6: +case 0xd2c7: +case 0xd4c0: +case 0xd4c1: +case 0xd4c2: +case 0xd4c3: +case 0xd4c4: +case 0xd4c5: +case 0xd4c6: +case 0xd4c7: +case 0xd6c0: +case 0xd6c1: +case 0xd6c2: +case 0xd6c3: +case 0xd6c4: +case 0xd6c5: +case 0xd6c6: +case 0xd6c7: +case 0xd8c0: +case 0xd8c1: +case 0xd8c2: +case 0xd8c3: +case 0xd8c4: +case 0xd8c5: +case 0xd8c6: +case 0xd8c7: +case 0xdac0: +case 0xdac1: +case 0xdac2: +case 0xdac3: +case 0xdac4: +case 0xdac5: +case 0xdac6: +case 0xdac7: +case 0xdcc0: +case 0xdcc1: +case 0xdcc2: +case 0xdcc3: +case 0xdcc4: +case 0xdcc5: +case 0xdcc6: +case 0xdcc7: +case 0xdec0: +case 0xdec1: +case 0xdec2: +case 0xdec3: +case 0xdec4: +case 0xdec5: +case 0xdec6: +case 0xdec7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb0c0: +case 0xb0c1: +case 0xb0c2: +case 0xb0c3: +case 0xb0c4: +case 0xb0c5: +case 0xb0c6: +case 0xb0c7: +case 0xb2c0: +case 0xb2c1: +case 0xb2c2: +case 0xb2c3: +case 0xb2c4: +case 0xb2c5: +case 0xb2c6: +case 0xb2c7: +case 0xb4c0: +case 0xb4c1: +case 0xb4c2: +case 0xb4c3: +case 0xb4c4: +case 0xb4c5: +case 0xb4c6: +case 0xb4c7: +case 0xb6c0: +case 0xb6c1: +case 0xb6c2: +case 0xb6c3: +case 0xb6c4: +case 0xb6c5: +case 0xb6c6: +case 0xb6c7: +case 0xb8c0: +case 0xb8c1: +case 0xb8c2: +case 0xb8c3: +case 0xb8c4: +case 0xb8c5: +case 0xb8c6: +case 0xb8c7: +case 0xbac0: +case 0xbac1: +case 0xbac2: +case 0xbac3: +case 0xbac4: +case 0xbac5: +case 0xbac6: +case 0xbac7: +case 0xbcc0: +case 0xbcc1: +case 0xbcc2: +case 0xbcc3: +case 0xbcc4: +case 0xbcc5: +case 0xbcc6: +case 0xbcc7: +case 0xbec0: +case 0xbec1: +case 0xbec2: +case 0xbec3: +case 0xbec4: +case 0xbec5: +case 0xbec6: +case 0xbec7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x90c0: +case 0x90c1: +case 0x90c2: +case 0x90c3: +case 0x90c4: +case 0x90c5: +case 0x90c6: +case 0x90c7: +case 0x92c0: +case 0x92c1: +case 0x92c2: +case 0x92c3: +case 0x92c4: +case 0x92c5: +case 0x92c6: +case 0x92c7: +case 0x94c0: +case 0x94c1: +case 0x94c2: +case 0x94c3: +case 0x94c4: +case 0x94c5: +case 0x94c6: +case 0x94c7: +case 0x96c0: +case 0x96c1: +case 0x96c2: +case 0x96c3: +case 0x96c4: +case 0x96c5: +case 0x96c6: +case 0x96c7: +case 0x98c0: +case 0x98c1: +case 0x98c2: +case 0x98c3: +case 0x98c4: +case 0x98c5: +case 0x98c6: +case 0x98c7: +case 0x9ac0: +case 0x9ac1: +case 0x9ac2: +case 0x9ac3: +case 0x9ac4: +case 0x9ac5: +case 0x9ac6: +case 0x9ac7: +case 0x9cc0: +case 0x9cc1: +case 0x9cc2: +case 0x9cc3: +case 0x9cc4: +case 0x9cc5: +case 0x9cc6: +case 0x9cc7: +case 0x9ec0: +case 0x9ec1: +case 0x9ec2: +case 0x9ec3: +case 0x9ec4: +case 0x9ec5: +case 0x9ec6: +case 0x9ec7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x3040: +case 0x3041: +case 0x3042: +case 0x3043: +case 0x3044: +case 0x3045: +case 0x3046: +case 0x3047: +case 0x3240: +case 0x3241: +case 0x3242: +case 0x3243: +case 0x3244: +case 0x3245: +case 0x3246: +case 0x3247: +case 0x3440: +case 0x3441: +case 0x3442: +case 0x3443: +case 0x3444: +case 0x3445: +case 0x3446: +case 0x3447: +case 0x3640: +case 0x3641: +case 0x3642: +case 0x3643: +case 0x3644: +case 0x3645: +case 0x3646: +case 0x3647: +case 0x3840: +case 0x3841: +case 0x3842: +case 0x3843: +case 0x3844: +case 0x3845: +case 0x3846: +case 0x3847: +case 0x3a40: +case 0x3a41: +case 0x3a42: +case 0x3a43: +case 0x3a44: +case 0x3a45: +case 0x3a46: +case 0x3a47: +case 0x3c40: +case 0x3c41: +case 0x3c42: +case 0x3c43: +case 0x3c44: +case 0x3c45: +case 0x3c46: +case 0x3c47: +case 0x3e40: +case 0x3e41: +case 0x3e42: +case 0x3e43: +case 0x3e44: +case 0x3e45: +case 0x3e46: +case 0x3e47: + { + HAM src(this, instr_b2_b0); MOVEA(src, instr_b11_b9); + } + break; + +case 0x44c0: +case 0x44c1: +case 0x44c2: +case 0x44c3: +case 0x44c4: +case 0x44c5: +case 0x44c6: +case 0x44c7: + { + HAM src(this, instr_b2_b0); MOVE_to_CCR(src); + } + break; + +case 0xc1c0: +case 0xc1c1: +case 0xc1c2: +case 0xc1c3: +case 0xc1c4: +case 0xc1c5: +case 0xc1c6: +case 0xc1c7: +case 0xc3c0: +case 0xc3c1: +case 0xc3c2: +case 0xc3c3: +case 0xc3c4: +case 0xc3c5: +case 0xc3c6: +case 0xc3c7: +case 0xc5c0: +case 0xc5c1: +case 0xc5c2: +case 0xc5c3: +case 0xc5c4: +case 0xc5c5: +case 0xc5c6: +case 0xc5c7: +case 0xc7c0: +case 0xc7c1: +case 0xc7c2: +case 0xc7c3: +case 0xc7c4: +case 0xc7c5: +case 0xc7c6: +case 0xc7c7: +case 0xc9c0: +case 0xc9c1: +case 0xc9c2: +case 0xc9c3: +case 0xc9c4: +case 0xc9c5: +case 0xc9c6: +case 0xc9c7: +case 0xcbc0: +case 0xcbc1: +case 0xcbc2: +case 0xcbc3: +case 0xcbc4: +case 0xcbc5: +case 0xcbc6: +case 0xcbc7: +case 0xcdc0: +case 0xcdc1: +case 0xcdc2: +case 0xcdc3: +case 0xcdc4: +case 0xcdc5: +case 0xcdc6: +case 0xcdc7: +case 0xcfc0: +case 0xcfc1: +case 0xcfc2: +case 0xcfc3: +case 0xcfc4: +case 0xcfc5: +case 0xcfc6: +case 0xcfc7: + { + HAM src(this, instr_b2_b0); MULS(src, instr_b11_b9); + } + break; + +case 0xc0c0: +case 0xc0c1: +case 0xc0c2: +case 0xc0c3: +case 0xc0c4: +case 0xc0c5: +case 0xc0c6: +case 0xc0c7: +case 0xc2c0: +case 0xc2c1: +case 0xc2c2: +case 0xc2c3: +case 0xc2c4: +case 0xc2c5: +case 0xc2c6: +case 0xc2c7: +case 0xc4c0: +case 0xc4c1: +case 0xc4c2: +case 0xc4c3: +case 0xc4c4: +case 0xc4c5: +case 0xc4c6: +case 0xc4c7: +case 0xc6c0: +case 0xc6c1: +case 0xc6c2: +case 0xc6c3: +case 0xc6c4: +case 0xc6c5: +case 0xc6c6: +case 0xc6c7: +case 0xc8c0: +case 0xc8c1: +case 0xc8c2: +case 0xc8c3: +case 0xc8c4: +case 0xc8c5: +case 0xc8c6: +case 0xc8c7: +case 0xcac0: +case 0xcac1: +case 0xcac2: +case 0xcac3: +case 0xcac4: +case 0xcac5: +case 0xcac6: +case 0xcac7: +case 0xccc0: +case 0xccc1: +case 0xccc2: +case 0xccc3: +case 0xccc4: +case 0xccc5: +case 0xccc6: +case 0xccc7: +case 0xcec0: +case 0xcec1: +case 0xcec2: +case 0xcec3: +case 0xcec4: +case 0xcec5: +case 0xcec6: +case 0xcec7: + { + HAM src(this, instr_b2_b0); MULU(src, instr_b11_b9); + } + break; + +case 0xe160: +case 0xe161: +case 0xe162: +case 0xe163: +case 0xe164: +case 0xe165: +case 0xe166: +case 0xe167: +case 0xe360: +case 0xe361: +case 0xe362: +case 0xe363: +case 0xe364: +case 0xe365: +case 0xe366: +case 0xe367: +case 0xe560: +case 0xe561: +case 0xe562: +case 0xe563: +case 0xe564: +case 0xe565: +case 0xe566: +case 0xe567: +case 0xe760: +case 0xe761: +case 0xe762: +case 0xe763: +case 0xe764: +case 0xe765: +case 0xe766: +case 0xe767: +case 0xe960: +case 0xe961: +case 0xe962: +case 0xe963: +case 0xe964: +case 0xe965: +case 0xe966: +case 0xe967: +case 0xeb60: +case 0xeb61: +case 0xeb62: +case 0xeb63: +case 0xeb64: +case 0xeb65: +case 0xeb66: +case 0xeb67: +case 0xed60: +case 0xed61: +case 0xed62: +case 0xed63: +case 0xed64: +case 0xed65: +case 0xed66: +case 0xed67: +case 0xef60: +case 0xef61: +case 0xef62: +case 0xef63: +case 0xef64: +case 0xef65: +case 0xef66: +case 0xef67: + { + HAM targ(this, instr_b2_b0); ASL(targ, D[instr_b11_b9]); + } + break; + +case 0xe140: +case 0xe141: +case 0xe142: +case 0xe143: +case 0xe144: +case 0xe145: +case 0xe146: +case 0xe147: +case 0xe340: +case 0xe341: +case 0xe342: +case 0xe343: +case 0xe344: +case 0xe345: +case 0xe346: +case 0xe347: +case 0xe540: +case 0xe541: +case 0xe542: +case 0xe543: +case 0xe544: +case 0xe545: +case 0xe546: +case 0xe547: +case 0xe740: +case 0xe741: +case 0xe742: +case 0xe743: +case 0xe744: +case 0xe745: +case 0xe746: +case 0xe747: +case 0xe940: +case 0xe941: +case 0xe942: +case 0xe943: +case 0xe944: +case 0xe945: +case 0xe946: +case 0xe947: +case 0xeb40: +case 0xeb41: +case 0xeb42: +case 0xeb43: +case 0xeb44: +case 0xeb45: +case 0xeb46: +case 0xeb47: +case 0xed40: +case 0xed41: +case 0xed42: +case 0xed43: +case 0xed44: +case 0xed45: +case 0xed46: +case 0xed47: +case 0xef40: +case 0xef41: +case 0xef42: +case 0xef43: +case 0xef44: +case 0xef45: +case 0xef46: +case 0xef47: + { + HAM targ(this, instr_b2_b0); ASL(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe060: +case 0xe061: +case 0xe062: +case 0xe063: +case 0xe064: +case 0xe065: +case 0xe066: +case 0xe067: +case 0xe260: +case 0xe261: +case 0xe262: +case 0xe263: +case 0xe264: +case 0xe265: +case 0xe266: +case 0xe267: +case 0xe460: +case 0xe461: +case 0xe462: +case 0xe463: +case 0xe464: +case 0xe465: +case 0xe466: +case 0xe467: +case 0xe660: +case 0xe661: +case 0xe662: +case 0xe663: +case 0xe664: +case 0xe665: +case 0xe666: +case 0xe667: +case 0xe860: +case 0xe861: +case 0xe862: +case 0xe863: +case 0xe864: +case 0xe865: +case 0xe866: +case 0xe867: +case 0xea60: +case 0xea61: +case 0xea62: +case 0xea63: +case 0xea64: +case 0xea65: +case 0xea66: +case 0xea67: +case 0xec60: +case 0xec61: +case 0xec62: +case 0xec63: +case 0xec64: +case 0xec65: +case 0xec66: +case 0xec67: +case 0xee60: +case 0xee61: +case 0xee62: +case 0xee63: +case 0xee64: +case 0xee65: +case 0xee66: +case 0xee67: + { + HAM targ(this, instr_b2_b0); ASR(targ, D[instr_b11_b9]); + } + break; + +case 0xe040: +case 0xe041: +case 0xe042: +case 0xe043: +case 0xe044: +case 0xe045: +case 0xe046: +case 0xe047: +case 0xe240: +case 0xe241: +case 0xe242: +case 0xe243: +case 0xe244: +case 0xe245: +case 0xe246: +case 0xe247: +case 0xe440: +case 0xe441: +case 0xe442: +case 0xe443: +case 0xe444: +case 0xe445: +case 0xe446: +case 0xe447: +case 0xe640: +case 0xe641: +case 0xe642: +case 0xe643: +case 0xe644: +case 0xe645: +case 0xe646: +case 0xe647: +case 0xe840: +case 0xe841: +case 0xe842: +case 0xe843: +case 0xe844: +case 0xe845: +case 0xe846: +case 0xe847: +case 0xea40: +case 0xea41: +case 0xea42: +case 0xea43: +case 0xea44: +case 0xea45: +case 0xea46: +case 0xea47: +case 0xec40: +case 0xec41: +case 0xec42: +case 0xec43: +case 0xec44: +case 0xec45: +case 0xec46: +case 0xec47: +case 0xee40: +case 0xee41: +case 0xee42: +case 0xee43: +case 0xee44: +case 0xee45: +case 0xee46: +case 0xee47: + { + HAM targ(this, instr_b2_b0); ASR(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe168: +case 0xe169: +case 0xe16a: +case 0xe16b: +case 0xe16c: +case 0xe16d: +case 0xe16e: +case 0xe16f: +case 0xe368: +case 0xe369: +case 0xe36a: +case 0xe36b: +case 0xe36c: +case 0xe36d: +case 0xe36e: +case 0xe36f: +case 0xe568: +case 0xe569: +case 0xe56a: +case 0xe56b: +case 0xe56c: +case 0xe56d: +case 0xe56e: +case 0xe56f: +case 0xe768: +case 0xe769: +case 0xe76a: +case 0xe76b: +case 0xe76c: +case 0xe76d: +case 0xe76e: +case 0xe76f: +case 0xe968: +case 0xe969: +case 0xe96a: +case 0xe96b: +case 0xe96c: +case 0xe96d: +case 0xe96e: +case 0xe96f: +case 0xeb68: +case 0xeb69: +case 0xeb6a: +case 0xeb6b: +case 0xeb6c: +case 0xeb6d: +case 0xeb6e: +case 0xeb6f: +case 0xed68: +case 0xed69: +case 0xed6a: +case 0xed6b: +case 0xed6c: +case 0xed6d: +case 0xed6e: +case 0xed6f: +case 0xef68: +case 0xef69: +case 0xef6a: +case 0xef6b: +case 0xef6c: +case 0xef6d: +case 0xef6e: +case 0xef6f: + { + HAM targ(this, instr_b2_b0); LSL(targ, D[instr_b11_b9]); + } + break; + +case 0xe148: +case 0xe149: +case 0xe14a: +case 0xe14b: +case 0xe14c: +case 0xe14d: +case 0xe14e: +case 0xe14f: +case 0xe348: +case 0xe349: +case 0xe34a: +case 0xe34b: +case 0xe34c: +case 0xe34d: +case 0xe34e: +case 0xe34f: +case 0xe548: +case 0xe549: +case 0xe54a: +case 0xe54b: +case 0xe54c: +case 0xe54d: +case 0xe54e: +case 0xe54f: +case 0xe748: +case 0xe749: +case 0xe74a: +case 0xe74b: +case 0xe74c: +case 0xe74d: +case 0xe74e: +case 0xe74f: +case 0xe948: +case 0xe949: +case 0xe94a: +case 0xe94b: +case 0xe94c: +case 0xe94d: +case 0xe94e: +case 0xe94f: +case 0xeb48: +case 0xeb49: +case 0xeb4a: +case 0xeb4b: +case 0xeb4c: +case 0xeb4d: +case 0xeb4e: +case 0xeb4f: +case 0xed48: +case 0xed49: +case 0xed4a: +case 0xed4b: +case 0xed4c: +case 0xed4d: +case 0xed4e: +case 0xed4f: +case 0xef48: +case 0xef49: +case 0xef4a: +case 0xef4b: +case 0xef4c: +case 0xef4d: +case 0xef4e: +case 0xef4f: + { + HAM targ(this, instr_b2_b0); LSL(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe068: +case 0xe069: +case 0xe06a: +case 0xe06b: +case 0xe06c: +case 0xe06d: +case 0xe06e: +case 0xe06f: +case 0xe268: +case 0xe269: +case 0xe26a: +case 0xe26b: +case 0xe26c: +case 0xe26d: +case 0xe26e: +case 0xe26f: +case 0xe468: +case 0xe469: +case 0xe46a: +case 0xe46b: +case 0xe46c: +case 0xe46d: +case 0xe46e: +case 0xe46f: +case 0xe668: +case 0xe669: +case 0xe66a: +case 0xe66b: +case 0xe66c: +case 0xe66d: +case 0xe66e: +case 0xe66f: +case 0xe868: +case 0xe869: +case 0xe86a: +case 0xe86b: +case 0xe86c: +case 0xe86d: +case 0xe86e: +case 0xe86f: +case 0xea68: +case 0xea69: +case 0xea6a: +case 0xea6b: +case 0xea6c: +case 0xea6d: +case 0xea6e: +case 0xea6f: +case 0xec68: +case 0xec69: +case 0xec6a: +case 0xec6b: +case 0xec6c: +case 0xec6d: +case 0xec6e: +case 0xec6f: +case 0xee68: +case 0xee69: +case 0xee6a: +case 0xee6b: +case 0xee6c: +case 0xee6d: +case 0xee6e: +case 0xee6f: + { + HAM targ(this, instr_b2_b0); LSR(targ, D[instr_b11_b9]); + } + break; + +case 0xe048: +case 0xe049: +case 0xe04a: +case 0xe04b: +case 0xe04c: +case 0xe04d: +case 0xe04e: +case 0xe04f: +case 0xe248: +case 0xe249: +case 0xe24a: +case 0xe24b: +case 0xe24c: +case 0xe24d: +case 0xe24e: +case 0xe24f: +case 0xe448: +case 0xe449: +case 0xe44a: +case 0xe44b: +case 0xe44c: +case 0xe44d: +case 0xe44e: +case 0xe44f: +case 0xe648: +case 0xe649: +case 0xe64a: +case 0xe64b: +case 0xe64c: +case 0xe64d: +case 0xe64e: +case 0xe64f: +case 0xe848: +case 0xe849: +case 0xe84a: +case 0xe84b: +case 0xe84c: +case 0xe84d: +case 0xe84e: +case 0xe84f: +case 0xea48: +case 0xea49: +case 0xea4a: +case 0xea4b: +case 0xea4c: +case 0xea4d: +case 0xea4e: +case 0xea4f: +case 0xec48: +case 0xec49: +case 0xec4a: +case 0xec4b: +case 0xec4c: +case 0xec4d: +case 0xec4e: +case 0xec4f: +case 0xee48: +case 0xee49: +case 0xee4a: +case 0xee4b: +case 0xee4c: +case 0xee4d: +case 0xee4e: +case 0xee4f: + { + HAM targ(this, instr_b2_b0); LSR(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe178: +case 0xe179: +case 0xe17a: +case 0xe17b: +case 0xe17c: +case 0xe17d: +case 0xe17e: +case 0xe17f: +case 0xe378: +case 0xe379: +case 0xe37a: +case 0xe37b: +case 0xe37c: +case 0xe37d: +case 0xe37e: +case 0xe37f: +case 0xe578: +case 0xe579: +case 0xe57a: +case 0xe57b: +case 0xe57c: +case 0xe57d: +case 0xe57e: +case 0xe57f: +case 0xe778: +case 0xe779: +case 0xe77a: +case 0xe77b: +case 0xe77c: +case 0xe77d: +case 0xe77e: +case 0xe77f: +case 0xe978: +case 0xe979: +case 0xe97a: +case 0xe97b: +case 0xe97c: +case 0xe97d: +case 0xe97e: +case 0xe97f: +case 0xeb78: +case 0xeb79: +case 0xeb7a: +case 0xeb7b: +case 0xeb7c: +case 0xeb7d: +case 0xeb7e: +case 0xeb7f: +case 0xed78: +case 0xed79: +case 0xed7a: +case 0xed7b: +case 0xed7c: +case 0xed7d: +case 0xed7e: +case 0xed7f: +case 0xef78: +case 0xef79: +case 0xef7a: +case 0xef7b: +case 0xef7c: +case 0xef7d: +case 0xef7e: +case 0xef7f: + { + HAM targ(this, instr_b2_b0); ROL(targ, D[instr_b11_b9]); + } + break; + +case 0xe158: +case 0xe159: +case 0xe15a: +case 0xe15b: +case 0xe15c: +case 0xe15d: +case 0xe15e: +case 0xe15f: +case 0xe358: +case 0xe359: +case 0xe35a: +case 0xe35b: +case 0xe35c: +case 0xe35d: +case 0xe35e: +case 0xe35f: +case 0xe558: +case 0xe559: +case 0xe55a: +case 0xe55b: +case 0xe55c: +case 0xe55d: +case 0xe55e: +case 0xe55f: +case 0xe758: +case 0xe759: +case 0xe75a: +case 0xe75b: +case 0xe75c: +case 0xe75d: +case 0xe75e: +case 0xe75f: +case 0xe958: +case 0xe959: +case 0xe95a: +case 0xe95b: +case 0xe95c: +case 0xe95d: +case 0xe95e: +case 0xe95f: +case 0xeb58: +case 0xeb59: +case 0xeb5a: +case 0xeb5b: +case 0xeb5c: +case 0xeb5d: +case 0xeb5e: +case 0xeb5f: +case 0xed58: +case 0xed59: +case 0xed5a: +case 0xed5b: +case 0xed5c: +case 0xed5d: +case 0xed5e: +case 0xed5f: +case 0xef58: +case 0xef59: +case 0xef5a: +case 0xef5b: +case 0xef5c: +case 0xef5d: +case 0xef5e: +case 0xef5f: + { + HAM targ(this, instr_b2_b0); ROL(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe078: +case 0xe079: +case 0xe07a: +case 0xe07b: +case 0xe07c: +case 0xe07d: +case 0xe07e: +case 0xe07f: +case 0xe278: +case 0xe279: +case 0xe27a: +case 0xe27b: +case 0xe27c: +case 0xe27d: +case 0xe27e: +case 0xe27f: +case 0xe478: +case 0xe479: +case 0xe47a: +case 0xe47b: +case 0xe47c: +case 0xe47d: +case 0xe47e: +case 0xe47f: +case 0xe678: +case 0xe679: +case 0xe67a: +case 0xe67b: +case 0xe67c: +case 0xe67d: +case 0xe67e: +case 0xe67f: +case 0xe878: +case 0xe879: +case 0xe87a: +case 0xe87b: +case 0xe87c: +case 0xe87d: +case 0xe87e: +case 0xe87f: +case 0xea78: +case 0xea79: +case 0xea7a: +case 0xea7b: +case 0xea7c: +case 0xea7d: +case 0xea7e: +case 0xea7f: +case 0xec78: +case 0xec79: +case 0xec7a: +case 0xec7b: +case 0xec7c: +case 0xec7d: +case 0xec7e: +case 0xec7f: +case 0xee78: +case 0xee79: +case 0xee7a: +case 0xee7b: +case 0xee7c: +case 0xee7d: +case 0xee7e: +case 0xee7f: + { + HAM targ(this, instr_b2_b0); ROR(targ, D[instr_b11_b9]); + } + break; + +case 0xe058: +case 0xe059: +case 0xe05a: +case 0xe05b: +case 0xe05c: +case 0xe05d: +case 0xe05e: +case 0xe05f: +case 0xe258: +case 0xe259: +case 0xe25a: +case 0xe25b: +case 0xe25c: +case 0xe25d: +case 0xe25e: +case 0xe25f: +case 0xe458: +case 0xe459: +case 0xe45a: +case 0xe45b: +case 0xe45c: +case 0xe45d: +case 0xe45e: +case 0xe45f: +case 0xe658: +case 0xe659: +case 0xe65a: +case 0xe65b: +case 0xe65c: +case 0xe65d: +case 0xe65e: +case 0xe65f: +case 0xe858: +case 0xe859: +case 0xe85a: +case 0xe85b: +case 0xe85c: +case 0xe85d: +case 0xe85e: +case 0xe85f: +case 0xea58: +case 0xea59: +case 0xea5a: +case 0xea5b: +case 0xea5c: +case 0xea5d: +case 0xea5e: +case 0xea5f: +case 0xec58: +case 0xec59: +case 0xec5a: +case 0xec5b: +case 0xec5c: +case 0xec5d: +case 0xec5e: +case 0xec5f: +case 0xee58: +case 0xee59: +case 0xee5a: +case 0xee5b: +case 0xee5c: +case 0xee5d: +case 0xee5e: +case 0xee5f: + { + HAM targ(this, instr_b2_b0); ROR(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe170: +case 0xe171: +case 0xe172: +case 0xe173: +case 0xe174: +case 0xe175: +case 0xe176: +case 0xe177: +case 0xe370: +case 0xe371: +case 0xe372: +case 0xe373: +case 0xe374: +case 0xe375: +case 0xe376: +case 0xe377: +case 0xe570: +case 0xe571: +case 0xe572: +case 0xe573: +case 0xe574: +case 0xe575: +case 0xe576: +case 0xe577: +case 0xe770: +case 0xe771: +case 0xe772: +case 0xe773: +case 0xe774: +case 0xe775: +case 0xe776: +case 0xe777: +case 0xe970: +case 0xe971: +case 0xe972: +case 0xe973: +case 0xe974: +case 0xe975: +case 0xe976: +case 0xe977: +case 0xeb70: +case 0xeb71: +case 0xeb72: +case 0xeb73: +case 0xeb74: +case 0xeb75: +case 0xeb76: +case 0xeb77: +case 0xed70: +case 0xed71: +case 0xed72: +case 0xed73: +case 0xed74: +case 0xed75: +case 0xed76: +case 0xed77: +case 0xef70: +case 0xef71: +case 0xef72: +case 0xef73: +case 0xef74: +case 0xef75: +case 0xef76: +case 0xef77: + { + HAM targ(this, instr_b2_b0); ROXL(targ, D[instr_b11_b9]); + } + break; + +case 0xe150: +case 0xe151: +case 0xe152: +case 0xe153: +case 0xe154: +case 0xe155: +case 0xe156: +case 0xe157: +case 0xe350: +case 0xe351: +case 0xe352: +case 0xe353: +case 0xe354: +case 0xe355: +case 0xe356: +case 0xe357: +case 0xe550: +case 0xe551: +case 0xe552: +case 0xe553: +case 0xe554: +case 0xe555: +case 0xe556: +case 0xe557: +case 0xe750: +case 0xe751: +case 0xe752: +case 0xe753: +case 0xe754: +case 0xe755: +case 0xe756: +case 0xe757: +case 0xe950: +case 0xe951: +case 0xe952: +case 0xe953: +case 0xe954: +case 0xe955: +case 0xe956: +case 0xe957: +case 0xeb50: +case 0xeb51: +case 0xeb52: +case 0xeb53: +case 0xeb54: +case 0xeb55: +case 0xeb56: +case 0xeb57: +case 0xed50: +case 0xed51: +case 0xed52: +case 0xed53: +case 0xed54: +case 0xed55: +case 0xed56: +case 0xed57: +case 0xef50: +case 0xef51: +case 0xef52: +case 0xef53: +case 0xef54: +case 0xef55: +case 0xef56: +case 0xef57: + { + HAM targ(this, instr_b2_b0); ROXL(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe070: +case 0xe071: +case 0xe072: +case 0xe073: +case 0xe074: +case 0xe075: +case 0xe076: +case 0xe077: +case 0xe270: +case 0xe271: +case 0xe272: +case 0xe273: +case 0xe274: +case 0xe275: +case 0xe276: +case 0xe277: +case 0xe470: +case 0xe471: +case 0xe472: +case 0xe473: +case 0xe474: +case 0xe475: +case 0xe476: +case 0xe477: +case 0xe670: +case 0xe671: +case 0xe672: +case 0xe673: +case 0xe674: +case 0xe675: +case 0xe676: +case 0xe677: +case 0xe870: +case 0xe871: +case 0xe872: +case 0xe873: +case 0xe874: +case 0xe875: +case 0xe876: +case 0xe877: +case 0xea70: +case 0xea71: +case 0xea72: +case 0xea73: +case 0xea74: +case 0xea75: +case 0xea76: +case 0xea77: +case 0xec70: +case 0xec71: +case 0xec72: +case 0xec73: +case 0xec74: +case 0xec75: +case 0xec76: +case 0xec77: +case 0xee70: +case 0xee71: +case 0xee72: +case 0xee73: +case 0xee74: +case 0xee75: +case 0xee76: +case 0xee77: + { + HAM targ(this, instr_b2_b0); ROXR(targ, D[instr_b11_b9]); + } + break; + +case 0xe050: +case 0xe051: +case 0xe052: +case 0xe053: +case 0xe054: +case 0xe055: +case 0xe056: +case 0xe057: +case 0xe250: +case 0xe251: +case 0xe252: +case 0xe253: +case 0xe254: +case 0xe255: +case 0xe256: +case 0xe257: +case 0xe450: +case 0xe451: +case 0xe452: +case 0xe453: +case 0xe454: +case 0xe455: +case 0xe456: +case 0xe457: +case 0xe650: +case 0xe651: +case 0xe652: +case 0xe653: +case 0xe654: +case 0xe655: +case 0xe656: +case 0xe657: +case 0xe850: +case 0xe851: +case 0xe852: +case 0xe853: +case 0xe854: +case 0xe855: +case 0xe856: +case 0xe857: +case 0xea50: +case 0xea51: +case 0xea52: +case 0xea53: +case 0xea54: +case 0xea55: +case 0xea56: +case 0xea57: +case 0xec50: +case 0xec51: +case 0xec52: +case 0xec53: +case 0xec54: +case 0xec55: +case 0xec56: +case 0xec57: +case 0xee50: +case 0xee51: +case 0xee52: +case 0xee53: +case 0xee54: +case 0xee55: +case 0xee56: +case 0xee57: + { + HAM targ(this, instr_b2_b0); ROXR(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0x81fc: +case 0x83fc: +case 0x85fc: +case 0x87fc: +case 0x89fc: +case 0x8bfc: +case 0x8dfc: +case 0x8ffc: + { + HAM src(this); DIVS(src, instr_b11_b9); + } + break; + +case 0x80fc: +case 0x82fc: +case 0x84fc: +case 0x86fc: +case 0x88fc: +case 0x8afc: +case 0x8cfc: +case 0x8efc: + { + HAM src(this); DIVU(src, instr_b11_b9); + } + break; + +case 0x0679: + { + HAM src(this); HAM dst(this); ADD(src, dst); + } + break; + +case 0x0279: + { + HAM src(this); HAM dst(this); AND(src, dst); + } + break; + +case 0x0c79: + { + HAM src(this); HAM dst(this); CMP(src, dst); + } + break; + +case 0x0a79: + { + HAM src(this); HAM dst(this); EOR(src, dst); + } + break; + +case 0x33fc: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x0079: + { + HAM src(this); HAM dst(this); OR(src, dst); + } + break; + +case 0x0479: + { + HAM src(this); HAM dst(this); SUB(src, dst); + } + break; + +case 0x0678: + { + HAM src(this); HAM dst(this); ADD(src, dst); + } + break; + +case 0x0278: + { + HAM src(this); HAM dst(this); AND(src, dst); + } + break; + +case 0x0c78: + { + HAM src(this); HAM dst(this); CMP(src, dst); + } + break; + +case 0x0a78: + { + HAM src(this); HAM dst(this); EOR(src, dst); + } + break; + +case 0x31fc: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x0078: + { + HAM src(this); HAM dst(this); OR(src, dst); + } + break; + +case 0x0478: + { + HAM src(this); HAM dst(this); SUB(src, dst); + } + break; + +case 0x30bc: +case 0x32bc: +case 0x34bc: +case 0x36bc: +case 0x38bc: +case 0x3abc: +case 0x3cbc: +case 0x3ebc: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x0650: +case 0x0651: +case 0x0652: +case 0x0653: +case 0x0654: +case 0x0655: +case 0x0656: +case 0x0657: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x0250: +case 0x0251: +case 0x0252: +case 0x0253: +case 0x0254: +case 0x0255: +case 0x0256: +case 0x0257: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0c50: +case 0x0c51: +case 0x0c52: +case 0x0c53: +case 0x0c54: +case 0x0c55: +case 0x0c56: +case 0x0c57: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0a50: +case 0x0a51: +case 0x0a52: +case 0x0a53: +case 0x0a54: +case 0x0a55: +case 0x0a56: +case 0x0a57: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x0050: +case 0x0051: +case 0x0052: +case 0x0053: +case 0x0054: +case 0x0055: +case 0x0056: +case 0x0057: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x0450: +case 0x0451: +case 0x0452: +case 0x0453: +case 0x0454: +case 0x0455: +case 0x0456: +case 0x0457: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x317c: +case 0x337c: +case 0x357c: +case 0x377c: +case 0x397c: +case 0x3b7c: +case 0x3d7c: +case 0x3f7c: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x0668: +case 0x0669: +case 0x066a: +case 0x066b: +case 0x066c: +case 0x066d: +case 0x066e: +case 0x066f: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x0268: +case 0x0269: +case 0x026a: +case 0x026b: +case 0x026c: +case 0x026d: +case 0x026e: +case 0x026f: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0c68: +case 0x0c69: +case 0x0c6a: +case 0x0c6b: +case 0x0c6c: +case 0x0c6d: +case 0x0c6e: +case 0x0c6f: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0a68: +case 0x0a69: +case 0x0a6a: +case 0x0a6b: +case 0x0a6c: +case 0x0a6d: +case 0x0a6e: +case 0x0a6f: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x0068: +case 0x0069: +case 0x006a: +case 0x006b: +case 0x006c: +case 0x006d: +case 0x006e: +case 0x006f: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x0468: +case 0x0469: +case 0x046a: +case 0x046b: +case 0x046c: +case 0x046d: +case 0x046e: +case 0x046f: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x31bc: +case 0x33bc: +case 0x35bc: +case 0x37bc: +case 0x39bc: +case 0x3bbc: +case 0x3dbc: +case 0x3fbc: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x0670: +case 0x0671: +case 0x0672: +case 0x0673: +case 0x0674: +case 0x0675: +case 0x0676: +case 0x0677: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x0270: +case 0x0271: +case 0x0272: +case 0x0273: +case 0x0274: +case 0x0275: +case 0x0276: +case 0x0277: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0c70: +case 0x0c71: +case 0x0c72: +case 0x0c73: +case 0x0c74: +case 0x0c75: +case 0x0c76: +case 0x0c77: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0a70: +case 0x0a71: +case 0x0a72: +case 0x0a73: +case 0x0a74: +case 0x0a75: +case 0x0a76: +case 0x0a77: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x0070: +case 0x0071: +case 0x0072: +case 0x0073: +case 0x0074: +case 0x0075: +case 0x0076: +case 0x0077: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x0470: +case 0x0471: +case 0x0472: +case 0x0473: +case 0x0474: +case 0x0475: +case 0x0476: +case 0x0477: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x30fc: +case 0x32fc: +case 0x34fc: +case 0x36fc: +case 0x38fc: +case 0x3afc: +case 0x3cfc: +case 0x3efc: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x0658: +case 0x0659: +case 0x065a: +case 0x065b: +case 0x065c: +case 0x065d: +case 0x065e: +case 0x065f: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x0258: +case 0x0259: +case 0x025a: +case 0x025b: +case 0x025c: +case 0x025d: +case 0x025e: +case 0x025f: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0c58: +case 0x0c59: +case 0x0c5a: +case 0x0c5b: +case 0x0c5c: +case 0x0c5d: +case 0x0c5e: +case 0x0c5f: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0a58: +case 0x0a59: +case 0x0a5a: +case 0x0a5b: +case 0x0a5c: +case 0x0a5d: +case 0x0a5e: +case 0x0a5f: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x0058: +case 0x0059: +case 0x005a: +case 0x005b: +case 0x005c: +case 0x005d: +case 0x005e: +case 0x005f: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x0458: +case 0x0459: +case 0x045a: +case 0x045b: +case 0x045c: +case 0x045d: +case 0x045e: +case 0x045f: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x313c: +case 0x333c: +case 0x353c: +case 0x373c: +case 0x393c: +case 0x3b3c: +case 0x3d3c: +case 0x3f3c: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x0660: +case 0x0661: +case 0x0662: +case 0x0663: +case 0x0664: +case 0x0665: +case 0x0666: +case 0x0667: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x0260: +case 0x0261: +case 0x0262: +case 0x0263: +case 0x0264: +case 0x0265: +case 0x0266: +case 0x0267: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0c60: +case 0x0c61: +case 0x0c62: +case 0x0c63: +case 0x0c64: +case 0x0c65: +case 0x0c66: +case 0x0c67: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0a60: +case 0x0a61: +case 0x0a62: +case 0x0a63: +case 0x0a64: +case 0x0a65: +case 0x0a66: +case 0x0a67: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x0060: +case 0x0061: +case 0x0062: +case 0x0063: +case 0x0064: +case 0x0065: +case 0x0066: +case 0x0067: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x0460: +case 0x0461: +case 0x0462: +case 0x0463: +case 0x0464: +case 0x0465: +case 0x0466: +case 0x0467: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xd07c: +case 0xd27c: +case 0xd47c: +case 0xd67c: +case 0xd87c: +case 0xda7c: +case 0xdc7c: +case 0xde7c: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc07c: +case 0xc27c: +case 0xc47c: +case 0xc67c: +case 0xc87c: +case 0xca7c: +case 0xcc7c: +case 0xce7c: + { + HAM src(this); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0x41bc: +case 0x43bc: +case 0x45bc: +case 0x47bc: +case 0x49bc: +case 0x4bbc: +case 0x4dbc: +case 0x4fbc: + { + HAM src(this); HAM dst(this, instr_b11_b9); CHK(src, dst); + } + break; + +case 0xb07c: +case 0xb27c: +case 0xb47c: +case 0xb67c: +case 0xb87c: +case 0xba7c: +case 0xbc7c: +case 0xbe7c: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x303c: +case 0x323c: +case 0x343c: +case 0x363c: +case 0x383c: +case 0x3a3c: +case 0x3c3c: +case 0x3e3c: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x807c: +case 0x827c: +case 0x847c: +case 0x867c: +case 0x887c: +case 0x8a7c: +case 0x8c7c: +case 0x8e7c: + { + HAM src(this); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x907c: +case 0x927c: +case 0x947c: +case 0x967c: +case 0x987c: +case 0x9a7c: +case 0x9c7c: +case 0x9e7c: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x0640: +case 0x0641: +case 0x0642: +case 0x0643: +case 0x0644: +case 0x0645: +case 0x0646: +case 0x0647: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x0240: +case 0x0241: +case 0x0242: +case 0x0243: +case 0x0244: +case 0x0245: +case 0x0246: +case 0x0247: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0c40: +case 0x0c41: +case 0x0c42: +case 0x0c43: +case 0x0c44: +case 0x0c45: +case 0x0c46: +case 0x0c47: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0a40: +case 0x0a41: +case 0x0a42: +case 0x0a43: +case 0x0a44: +case 0x0a45: +case 0x0a46: +case 0x0a47: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x0040: +case 0x0041: +case 0x0042: +case 0x0043: +case 0x0044: +case 0x0045: +case 0x0046: +case 0x0047: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x0440: +case 0x0441: +case 0x0442: +case 0x0443: +case 0x0444: +case 0x0445: +case 0x0446: +case 0x0447: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xd0fc: +case 0xd2fc: +case 0xd4fc: +case 0xd6fc: +case 0xd8fc: +case 0xdafc: +case 0xdcfc: +case 0xdefc: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb0fc: +case 0xb2fc: +case 0xb4fc: +case 0xb6fc: +case 0xb8fc: +case 0xbafc: +case 0xbcfc: +case 0xbefc: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x90fc: +case 0x92fc: +case 0x94fc: +case 0x96fc: +case 0x98fc: +case 0x9afc: +case 0x9cfc: +case 0x9efc: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x307c: +case 0x327c: +case 0x347c: +case 0x367c: +case 0x387c: +case 0x3a7c: +case 0x3c7c: +case 0x3e7c: + { + HAM src(this); MOVEA(src, instr_b11_b9); + } + break; + +case 0x44fc: + { + HAM src(this); MOVE_to_CCR(src); + } + break; + +case 0xc1fc: +case 0xc3fc: +case 0xc5fc: +case 0xc7fc: +case 0xc9fc: +case 0xcbfc: +case 0xcdfc: +case 0xcffc: + { + HAM src(this); MULS(src, instr_b11_b9); + } + break; + +case 0xc0fc: +case 0xc2fc: +case 0xc4fc: +case 0xc6fc: +case 0xc8fc: +case 0xcafc: +case 0xccfc: +case 0xcefc: + { + HAM src(this); MULU(src, instr_b11_b9); + } + break; + +case 0x5079: +case 0x5279: +case 0x5479: +case 0x5679: +case 0x5879: +case 0x5a79: +case 0x5c79: +case 0x5e79: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this); ADD(src, dst); + } + break; + +case 0x5179: +case 0x5379: +case 0x5579: +case 0x5779: +case 0x5979: +case 0x5b79: +case 0x5d79: +case 0x5f79: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this); SUB(src, dst); + } + break; + +case 0x5078: +case 0x5278: +case 0x5478: +case 0x5678: +case 0x5878: +case 0x5a78: +case 0x5c78: +case 0x5e78: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this); ADD(src, dst); + } + break; + +case 0x5178: +case 0x5378: +case 0x5578: +case 0x5778: +case 0x5978: +case 0x5b78: +case 0x5d78: +case 0x5f78: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this); SUB(src, dst); + } + break; + +case 0x5050: +case 0x5051: +case 0x5052: +case 0x5053: +case 0x5054: +case 0x5055: +case 0x5056: +case 0x5057: +case 0x5250: +case 0x5251: +case 0x5252: +case 0x5253: +case 0x5254: +case 0x5255: +case 0x5256: +case 0x5257: +case 0x5450: +case 0x5451: +case 0x5452: +case 0x5453: +case 0x5454: +case 0x5455: +case 0x5456: +case 0x5457: +case 0x5650: +case 0x5651: +case 0x5652: +case 0x5653: +case 0x5654: +case 0x5655: +case 0x5656: +case 0x5657: +case 0x5850: +case 0x5851: +case 0x5852: +case 0x5853: +case 0x5854: +case 0x5855: +case 0x5856: +case 0x5857: +case 0x5a50: +case 0x5a51: +case 0x5a52: +case 0x5a53: +case 0x5a54: +case 0x5a55: +case 0x5a56: +case 0x5a57: +case 0x5c50: +case 0x5c51: +case 0x5c52: +case 0x5c53: +case 0x5c54: +case 0x5c55: +case 0x5c56: +case 0x5c57: +case 0x5e50: +case 0x5e51: +case 0x5e52: +case 0x5e53: +case 0x5e54: +case 0x5e55: +case 0x5e56: +case 0x5e57: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5150: +case 0x5151: +case 0x5152: +case 0x5153: +case 0x5154: +case 0x5155: +case 0x5156: +case 0x5157: +case 0x5350: +case 0x5351: +case 0x5352: +case 0x5353: +case 0x5354: +case 0x5355: +case 0x5356: +case 0x5357: +case 0x5550: +case 0x5551: +case 0x5552: +case 0x5553: +case 0x5554: +case 0x5555: +case 0x5556: +case 0x5557: +case 0x5750: +case 0x5751: +case 0x5752: +case 0x5753: +case 0x5754: +case 0x5755: +case 0x5756: +case 0x5757: +case 0x5950: +case 0x5951: +case 0x5952: +case 0x5953: +case 0x5954: +case 0x5955: +case 0x5956: +case 0x5957: +case 0x5b50: +case 0x5b51: +case 0x5b52: +case 0x5b53: +case 0x5b54: +case 0x5b55: +case 0x5b56: +case 0x5b57: +case 0x5d50: +case 0x5d51: +case 0x5d52: +case 0x5d53: +case 0x5d54: +case 0x5d55: +case 0x5d56: +case 0x5d57: +case 0x5f50: +case 0x5f51: +case 0x5f52: +case 0x5f53: +case 0x5f54: +case 0x5f55: +case 0x5f56: +case 0x5f57: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x5068: +case 0x5069: +case 0x506a: +case 0x506b: +case 0x506c: +case 0x506d: +case 0x506e: +case 0x506f: +case 0x5268: +case 0x5269: +case 0x526a: +case 0x526b: +case 0x526c: +case 0x526d: +case 0x526e: +case 0x526f: +case 0x5468: +case 0x5469: +case 0x546a: +case 0x546b: +case 0x546c: +case 0x546d: +case 0x546e: +case 0x546f: +case 0x5668: +case 0x5669: +case 0x566a: +case 0x566b: +case 0x566c: +case 0x566d: +case 0x566e: +case 0x566f: +case 0x5868: +case 0x5869: +case 0x586a: +case 0x586b: +case 0x586c: +case 0x586d: +case 0x586e: +case 0x586f: +case 0x5a68: +case 0x5a69: +case 0x5a6a: +case 0x5a6b: +case 0x5a6c: +case 0x5a6d: +case 0x5a6e: +case 0x5a6f: +case 0x5c68: +case 0x5c69: +case 0x5c6a: +case 0x5c6b: +case 0x5c6c: +case 0x5c6d: +case 0x5c6e: +case 0x5c6f: +case 0x5e68: +case 0x5e69: +case 0x5e6a: +case 0x5e6b: +case 0x5e6c: +case 0x5e6d: +case 0x5e6e: +case 0x5e6f: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5168: +case 0x5169: +case 0x516a: +case 0x516b: +case 0x516c: +case 0x516d: +case 0x516e: +case 0x516f: +case 0x5368: +case 0x5369: +case 0x536a: +case 0x536b: +case 0x536c: +case 0x536d: +case 0x536e: +case 0x536f: +case 0x5568: +case 0x5569: +case 0x556a: +case 0x556b: +case 0x556c: +case 0x556d: +case 0x556e: +case 0x556f: +case 0x5768: +case 0x5769: +case 0x576a: +case 0x576b: +case 0x576c: +case 0x576d: +case 0x576e: +case 0x576f: +case 0x5968: +case 0x5969: +case 0x596a: +case 0x596b: +case 0x596c: +case 0x596d: +case 0x596e: +case 0x596f: +case 0x5b68: +case 0x5b69: +case 0x5b6a: +case 0x5b6b: +case 0x5b6c: +case 0x5b6d: +case 0x5b6e: +case 0x5b6f: +case 0x5d68: +case 0x5d69: +case 0x5d6a: +case 0x5d6b: +case 0x5d6c: +case 0x5d6d: +case 0x5d6e: +case 0x5d6f: +case 0x5f68: +case 0x5f69: +case 0x5f6a: +case 0x5f6b: +case 0x5f6c: +case 0x5f6d: +case 0x5f6e: +case 0x5f6f: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x5070: +case 0x5071: +case 0x5072: +case 0x5073: +case 0x5074: +case 0x5075: +case 0x5076: +case 0x5077: +case 0x5270: +case 0x5271: +case 0x5272: +case 0x5273: +case 0x5274: +case 0x5275: +case 0x5276: +case 0x5277: +case 0x5470: +case 0x5471: +case 0x5472: +case 0x5473: +case 0x5474: +case 0x5475: +case 0x5476: +case 0x5477: +case 0x5670: +case 0x5671: +case 0x5672: +case 0x5673: +case 0x5674: +case 0x5675: +case 0x5676: +case 0x5677: +case 0x5870: +case 0x5871: +case 0x5872: +case 0x5873: +case 0x5874: +case 0x5875: +case 0x5876: +case 0x5877: +case 0x5a70: +case 0x5a71: +case 0x5a72: +case 0x5a73: +case 0x5a74: +case 0x5a75: +case 0x5a76: +case 0x5a77: +case 0x5c70: +case 0x5c71: +case 0x5c72: +case 0x5c73: +case 0x5c74: +case 0x5c75: +case 0x5c76: +case 0x5c77: +case 0x5e70: +case 0x5e71: +case 0x5e72: +case 0x5e73: +case 0x5e74: +case 0x5e75: +case 0x5e76: +case 0x5e77: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5170: +case 0x5171: +case 0x5172: +case 0x5173: +case 0x5174: +case 0x5175: +case 0x5176: +case 0x5177: +case 0x5370: +case 0x5371: +case 0x5372: +case 0x5373: +case 0x5374: +case 0x5375: +case 0x5376: +case 0x5377: +case 0x5570: +case 0x5571: +case 0x5572: +case 0x5573: +case 0x5574: +case 0x5575: +case 0x5576: +case 0x5577: +case 0x5770: +case 0x5771: +case 0x5772: +case 0x5773: +case 0x5774: +case 0x5775: +case 0x5776: +case 0x5777: +case 0x5970: +case 0x5971: +case 0x5972: +case 0x5973: +case 0x5974: +case 0x5975: +case 0x5976: +case 0x5977: +case 0x5b70: +case 0x5b71: +case 0x5b72: +case 0x5b73: +case 0x5b74: +case 0x5b75: +case 0x5b76: +case 0x5b77: +case 0x5d70: +case 0x5d71: +case 0x5d72: +case 0x5d73: +case 0x5d74: +case 0x5d75: +case 0x5d76: +case 0x5d77: +case 0x5f70: +case 0x5f71: +case 0x5f72: +case 0x5f73: +case 0x5f74: +case 0x5f75: +case 0x5f76: +case 0x5f77: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x5058: +case 0x5059: +case 0x505a: +case 0x505b: +case 0x505c: +case 0x505d: +case 0x505e: +case 0x505f: +case 0x5258: +case 0x5259: +case 0x525a: +case 0x525b: +case 0x525c: +case 0x525d: +case 0x525e: +case 0x525f: +case 0x5458: +case 0x5459: +case 0x545a: +case 0x545b: +case 0x545c: +case 0x545d: +case 0x545e: +case 0x545f: +case 0x5658: +case 0x5659: +case 0x565a: +case 0x565b: +case 0x565c: +case 0x565d: +case 0x565e: +case 0x565f: +case 0x5858: +case 0x5859: +case 0x585a: +case 0x585b: +case 0x585c: +case 0x585d: +case 0x585e: +case 0x585f: +case 0x5a58: +case 0x5a59: +case 0x5a5a: +case 0x5a5b: +case 0x5a5c: +case 0x5a5d: +case 0x5a5e: +case 0x5a5f: +case 0x5c58: +case 0x5c59: +case 0x5c5a: +case 0x5c5b: +case 0x5c5c: +case 0x5c5d: +case 0x5c5e: +case 0x5c5f: +case 0x5e58: +case 0x5e59: +case 0x5e5a: +case 0x5e5b: +case 0x5e5c: +case 0x5e5d: +case 0x5e5e: +case 0x5e5f: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5158: +case 0x5159: +case 0x515a: +case 0x515b: +case 0x515c: +case 0x515d: +case 0x515e: +case 0x515f: +case 0x5358: +case 0x5359: +case 0x535a: +case 0x535b: +case 0x535c: +case 0x535d: +case 0x535e: +case 0x535f: +case 0x5558: +case 0x5559: +case 0x555a: +case 0x555b: +case 0x555c: +case 0x555d: +case 0x555e: +case 0x555f: +case 0x5758: +case 0x5759: +case 0x575a: +case 0x575b: +case 0x575c: +case 0x575d: +case 0x575e: +case 0x575f: +case 0x5958: +case 0x5959: +case 0x595a: +case 0x595b: +case 0x595c: +case 0x595d: +case 0x595e: +case 0x595f: +case 0x5b58: +case 0x5b59: +case 0x5b5a: +case 0x5b5b: +case 0x5b5c: +case 0x5b5d: +case 0x5b5e: +case 0x5b5f: +case 0x5d58: +case 0x5d59: +case 0x5d5a: +case 0x5d5b: +case 0x5d5c: +case 0x5d5d: +case 0x5d5e: +case 0x5d5f: +case 0x5f58: +case 0x5f59: +case 0x5f5a: +case 0x5f5b: +case 0x5f5c: +case 0x5f5d: +case 0x5f5e: +case 0x5f5f: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x5060: +case 0x5061: +case 0x5062: +case 0x5063: +case 0x5064: +case 0x5065: +case 0x5066: +case 0x5067: +case 0x5260: +case 0x5261: +case 0x5262: +case 0x5263: +case 0x5264: +case 0x5265: +case 0x5266: +case 0x5267: +case 0x5460: +case 0x5461: +case 0x5462: +case 0x5463: +case 0x5464: +case 0x5465: +case 0x5466: +case 0x5467: +case 0x5660: +case 0x5661: +case 0x5662: +case 0x5663: +case 0x5664: +case 0x5665: +case 0x5666: +case 0x5667: +case 0x5860: +case 0x5861: +case 0x5862: +case 0x5863: +case 0x5864: +case 0x5865: +case 0x5866: +case 0x5867: +case 0x5a60: +case 0x5a61: +case 0x5a62: +case 0x5a63: +case 0x5a64: +case 0x5a65: +case 0x5a66: +case 0x5a67: +case 0x5c60: +case 0x5c61: +case 0x5c62: +case 0x5c63: +case 0x5c64: +case 0x5c65: +case 0x5c66: +case 0x5c67: +case 0x5e60: +case 0x5e61: +case 0x5e62: +case 0x5e63: +case 0x5e64: +case 0x5e65: +case 0x5e66: +case 0x5e67: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5160: +case 0x5161: +case 0x5162: +case 0x5163: +case 0x5164: +case 0x5165: +case 0x5166: +case 0x5167: +case 0x5360: +case 0x5361: +case 0x5362: +case 0x5363: +case 0x5364: +case 0x5365: +case 0x5366: +case 0x5367: +case 0x5560: +case 0x5561: +case 0x5562: +case 0x5563: +case 0x5564: +case 0x5565: +case 0x5566: +case 0x5567: +case 0x5760: +case 0x5761: +case 0x5762: +case 0x5763: +case 0x5764: +case 0x5765: +case 0x5766: +case 0x5767: +case 0x5960: +case 0x5961: +case 0x5962: +case 0x5963: +case 0x5964: +case 0x5965: +case 0x5966: +case 0x5967: +case 0x5b60: +case 0x5b61: +case 0x5b62: +case 0x5b63: +case 0x5b64: +case 0x5b65: +case 0x5b66: +case 0x5b67: +case 0x5d60: +case 0x5d61: +case 0x5d62: +case 0x5d63: +case 0x5d64: +case 0x5d65: +case 0x5d66: +case 0x5d67: +case 0x5f60: +case 0x5f61: +case 0x5f62: +case 0x5f63: +case 0x5f64: +case 0x5f65: +case 0x5f66: +case 0x5f67: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x5040: +case 0x5041: +case 0x5042: +case 0x5043: +case 0x5044: +case 0x5045: +case 0x5046: +case 0x5047: +case 0x5240: +case 0x5241: +case 0x5242: +case 0x5243: +case 0x5244: +case 0x5245: +case 0x5246: +case 0x5247: +case 0x5440: +case 0x5441: +case 0x5442: +case 0x5443: +case 0x5444: +case 0x5445: +case 0x5446: +case 0x5447: +case 0x5640: +case 0x5641: +case 0x5642: +case 0x5643: +case 0x5644: +case 0x5645: +case 0x5646: +case 0x5647: +case 0x5840: +case 0x5841: +case 0x5842: +case 0x5843: +case 0x5844: +case 0x5845: +case 0x5846: +case 0x5847: +case 0x5a40: +case 0x5a41: +case 0x5a42: +case 0x5a43: +case 0x5a44: +case 0x5a45: +case 0x5a46: +case 0x5a47: +case 0x5c40: +case 0x5c41: +case 0x5c42: +case 0x5c43: +case 0x5c44: +case 0x5c45: +case 0x5c46: +case 0x5c47: +case 0x5e40: +case 0x5e41: +case 0x5e42: +case 0x5e43: +case 0x5e44: +case 0x5e45: +case 0x5e46: +case 0x5e47: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5140: +case 0x5141: +case 0x5142: +case 0x5143: +case 0x5144: +case 0x5145: +case 0x5146: +case 0x5147: +case 0x5340: +case 0x5341: +case 0x5342: +case 0x5343: +case 0x5344: +case 0x5345: +case 0x5346: +case 0x5347: +case 0x5540: +case 0x5541: +case 0x5542: +case 0x5543: +case 0x5544: +case 0x5545: +case 0x5546: +case 0x5547: +case 0x5740: +case 0x5741: +case 0x5742: +case 0x5743: +case 0x5744: +case 0x5745: +case 0x5746: +case 0x5747: +case 0x5940: +case 0x5941: +case 0x5942: +case 0x5943: +case 0x5944: +case 0x5945: +case 0x5946: +case 0x5947: +case 0x5b40: +case 0x5b41: +case 0x5b42: +case 0x5b43: +case 0x5b44: +case 0x5b45: +case 0x5b46: +case 0x5b47: +case 0x5d40: +case 0x5d41: +case 0x5d42: +case 0x5d43: +case 0x5d44: +case 0x5d45: +case 0x5d46: +case 0x5d47: +case 0x5f40: +case 0x5f41: +case 0x5f42: +case 0x5f43: +case 0x5f44: +case 0x5f45: +case 0x5f46: +case 0x5f47: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x5048: +case 0x5049: +case 0x504a: +case 0x504b: +case 0x504c: +case 0x504d: +case 0x504e: +case 0x504f: +case 0x5248: +case 0x5249: +case 0x524a: +case 0x524b: +case 0x524c: +case 0x524d: +case 0x524e: +case 0x524f: +case 0x5448: +case 0x5449: +case 0x544a: +case 0x544b: +case 0x544c: +case 0x544d: +case 0x544e: +case 0x544f: +case 0x5648: +case 0x5649: +case 0x564a: +case 0x564b: +case 0x564c: +case 0x564d: +case 0x564e: +case 0x564f: +case 0x5848: +case 0x5849: +case 0x584a: +case 0x584b: +case 0x584c: +case 0x584d: +case 0x584e: +case 0x584f: +case 0x5a48: +case 0x5a49: +case 0x5a4a: +case 0x5a4b: +case 0x5a4c: +case 0x5a4d: +case 0x5a4e: +case 0x5a4f: +case 0x5c48: +case 0x5c49: +case 0x5c4a: +case 0x5c4b: +case 0x5c4c: +case 0x5c4d: +case 0x5c4e: +case 0x5c4f: +case 0x5e48: +case 0x5e49: +case 0x5e4a: +case 0x5e4b: +case 0x5e4c: +case 0x5e4d: +case 0x5e4e: +case 0x5e4f: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5148: +case 0x5149: +case 0x514a: +case 0x514b: +case 0x514c: +case 0x514d: +case 0x514e: +case 0x514f: +case 0x5348: +case 0x5349: +case 0x534a: +case 0x534b: +case 0x534c: +case 0x534d: +case 0x534e: +case 0x534f: +case 0x5548: +case 0x5549: +case 0x554a: +case 0x554b: +case 0x554c: +case 0x554d: +case 0x554e: +case 0x554f: +case 0x5748: +case 0x5749: +case 0x574a: +case 0x574b: +case 0x574c: +case 0x574d: +case 0x574e: +case 0x574f: +case 0x5948: +case 0x5949: +case 0x594a: +case 0x594b: +case 0x594c: +case 0x594d: +case 0x594e: +case 0x594f: +case 0x5b48: +case 0x5b49: +case 0x5b4a: +case 0x5b4b: +case 0x5b4c: +case 0x5b4d: +case 0x5b4e: +case 0x5b4f: +case 0x5d48: +case 0x5d49: +case 0x5d4a: +case 0x5d4b: +case 0x5d4c: +case 0x5d4d: +case 0x5d4e: +case 0x5d4f: +case 0x5f48: +case 0x5f49: +case 0x5f4a: +case 0x5f4b: +case 0x5f4c: +case 0x5f4d: +case 0x5f4e: +case 0x5f4f: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x81fa: +case 0x83fa: +case 0x85fa: +case 0x87fa: +case 0x89fa: +case 0x8bfa: +case 0x8dfa: +case 0x8ffa: + { + HAM src(this); DIVS(src, instr_b11_b9); + } + break; + +case 0x80fa: +case 0x82fa: +case 0x84fa: +case 0x86fa: +case 0x88fa: +case 0x8afa: +case 0x8cfa: +case 0x8efa: + { + HAM src(this); DIVU(src, instr_b11_b9); + } + break; + +case 0x33fa: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x31fa: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x30ba: +case 0x32ba: +case 0x34ba: +case 0x36ba: +case 0x38ba: +case 0x3aba: +case 0x3cba: +case 0x3eba: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x317a: +case 0x337a: +case 0x357a: +case 0x377a: +case 0x397a: +case 0x3b7a: +case 0x3d7a: +case 0x3f7a: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x31ba: +case 0x33ba: +case 0x35ba: +case 0x37ba: +case 0x39ba: +case 0x3bba: +case 0x3dba: +case 0x3fba: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x30fa: +case 0x32fa: +case 0x34fa: +case 0x36fa: +case 0x38fa: +case 0x3afa: +case 0x3cfa: +case 0x3efa: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x313a: +case 0x333a: +case 0x353a: +case 0x373a: +case 0x393a: +case 0x3b3a: +case 0x3d3a: +case 0x3f3a: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd07a: +case 0xd27a: +case 0xd47a: +case 0xd67a: +case 0xd87a: +case 0xda7a: +case 0xdc7a: +case 0xde7a: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc07a: +case 0xc27a: +case 0xc47a: +case 0xc67a: +case 0xc87a: +case 0xca7a: +case 0xcc7a: +case 0xce7a: + { + HAM src(this); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0x41ba: +case 0x43ba: +case 0x45ba: +case 0x47ba: +case 0x49ba: +case 0x4bba: +case 0x4dba: +case 0x4fba: + { + HAM src(this); HAM dst(this, instr_b11_b9); CHK(src, dst); + } + break; + +case 0xb07a: +case 0xb27a: +case 0xb47a: +case 0xb67a: +case 0xb87a: +case 0xba7a: +case 0xbc7a: +case 0xbe7a: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x303a: +case 0x323a: +case 0x343a: +case 0x363a: +case 0x383a: +case 0x3a3a: +case 0x3c3a: +case 0x3e3a: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x807a: +case 0x827a: +case 0x847a: +case 0x867a: +case 0x887a: +case 0x8a7a: +case 0x8c7a: +case 0x8e7a: + { + HAM src(this); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x907a: +case 0x927a: +case 0x947a: +case 0x967a: +case 0x987a: +case 0x9a7a: +case 0x9c7a: +case 0x9e7a: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0xd0fa: +case 0xd2fa: +case 0xd4fa: +case 0xd6fa: +case 0xd8fa: +case 0xdafa: +case 0xdcfa: +case 0xdefa: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb0fa: +case 0xb2fa: +case 0xb4fa: +case 0xb6fa: +case 0xb8fa: +case 0xbafa: +case 0xbcfa: +case 0xbefa: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x90fa: +case 0x92fa: +case 0x94fa: +case 0x96fa: +case 0x98fa: +case 0x9afa: +case 0x9cfa: +case 0x9efa: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x307a: +case 0x327a: +case 0x347a: +case 0x367a: +case 0x387a: +case 0x3a7a: +case 0x3c7a: +case 0x3e7a: + { + HAM src(this); MOVEA(src, instr_b11_b9); + } + break; + +case 0x44fa: + { + HAM src(this); MOVE_to_CCR(src); + } + break; + +case 0xc1fa: +case 0xc3fa: +case 0xc5fa: +case 0xc7fa: +case 0xc9fa: +case 0xcbfa: +case 0xcdfa: +case 0xcffa: + { + HAM src(this); MULS(src, instr_b11_b9); + } + break; + +case 0xc0fa: +case 0xc2fa: +case 0xc4fa: +case 0xc6fa: +case 0xc8fa: +case 0xcafa: +case 0xccfa: +case 0xcefa: + { + HAM src(this); MULU(src, instr_b11_b9); + } + break; + +case 0x81fb: +case 0x83fb: +case 0x85fb: +case 0x87fb: +case 0x89fb: +case 0x8bfb: +case 0x8dfb: +case 0x8ffb: + { + HAM src(this); DIVS(src, instr_b11_b9); + } + break; + +case 0x80fb: +case 0x82fb: +case 0x84fb: +case 0x86fb: +case 0x88fb: +case 0x8afb: +case 0x8cfb: +case 0x8efb: + { + HAM src(this); DIVU(src, instr_b11_b9); + } + break; + +case 0x33fb: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x31fb: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x30bb: +case 0x32bb: +case 0x34bb: +case 0x36bb: +case 0x38bb: +case 0x3abb: +case 0x3cbb: +case 0x3ebb: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x317b: +case 0x337b: +case 0x357b: +case 0x377b: +case 0x397b: +case 0x3b7b: +case 0x3d7b: +case 0x3f7b: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x31bb: +case 0x33bb: +case 0x35bb: +case 0x37bb: +case 0x39bb: +case 0x3bbb: +case 0x3dbb: +case 0x3fbb: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x30fb: +case 0x32fb: +case 0x34fb: +case 0x36fb: +case 0x38fb: +case 0x3afb: +case 0x3cfb: +case 0x3efb: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x313b: +case 0x333b: +case 0x353b: +case 0x373b: +case 0x393b: +case 0x3b3b: +case 0x3d3b: +case 0x3f3b: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd07b: +case 0xd27b: +case 0xd47b: +case 0xd67b: +case 0xd87b: +case 0xda7b: +case 0xdc7b: +case 0xde7b: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc07b: +case 0xc27b: +case 0xc47b: +case 0xc67b: +case 0xc87b: +case 0xca7b: +case 0xcc7b: +case 0xce7b: + { + HAM src(this); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0x41bb: +case 0x43bb: +case 0x45bb: +case 0x47bb: +case 0x49bb: +case 0x4bbb: +case 0x4dbb: +case 0x4fbb: + { + HAM src(this); HAM dst(this, instr_b11_b9); CHK(src, dst); + } + break; + +case 0xb07b: +case 0xb27b: +case 0xb47b: +case 0xb67b: +case 0xb87b: +case 0xba7b: +case 0xbc7b: +case 0xbe7b: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x303b: +case 0x323b: +case 0x343b: +case 0x363b: +case 0x383b: +case 0x3a3b: +case 0x3c3b: +case 0x3e3b: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x807b: +case 0x827b: +case 0x847b: +case 0x867b: +case 0x887b: +case 0x8a7b: +case 0x8c7b: +case 0x8e7b: + { + HAM src(this); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x907b: +case 0x927b: +case 0x947b: +case 0x967b: +case 0x987b: +case 0x9a7b: +case 0x9c7b: +case 0x9e7b: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0xd0fb: +case 0xd2fb: +case 0xd4fb: +case 0xd6fb: +case 0xd8fb: +case 0xdafb: +case 0xdcfb: +case 0xdefb: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb0fb: +case 0xb2fb: +case 0xb4fb: +case 0xb6fb: +case 0xb8fb: +case 0xbafb: +case 0xbcfb: +case 0xbefb: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x90fb: +case 0x92fb: +case 0x94fb: +case 0x96fb: +case 0x98fb: +case 0x9afb: +case 0x9cfb: +case 0x9efb: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x307b: +case 0x327b: +case 0x347b: +case 0x367b: +case 0x387b: +case 0x3a7b: +case 0x3c7b: +case 0x3e7b: + { + HAM src(this); MOVEA(src, instr_b11_b9); + } + break; + +case 0x44fb: + { + HAM src(this); MOVE_to_CCR(src); + } + break; + +case 0xc1fb: +case 0xc3fb: +case 0xc5fb: +case 0xc7fb: +case 0xc9fb: +case 0xcbfb: +case 0xcdfb: +case 0xcffb: + { + HAM src(this); MULS(src, instr_b11_b9); + } + break; + +case 0xc0fb: +case 0xc2fb: +case 0xc4fb: +case 0xc6fb: +case 0xc8fb: +case 0xcafb: +case 0xccfb: +case 0xcefb: + { + HAM src(this); MULU(src, instr_b11_b9); + } + break; + +case 0x42b9: + { + HAM dst(this); CLR(dst); + } + break; + +case 0x44b9: + { + HAM dst(this); NEG(dst); + } + break; + +case 0x40b9: + { + HAM dst(this); NEGX(dst); + } + break; + +case 0x46b9: + { + HAM dst(this); NOT(dst); + } + break; + +case 0x4ab9: + { + HAM dst(this); TST(dst); + } + break; + +case 0x23f9: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x21f9: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0xd1f9: +case 0xd3f9: +case 0xd5f9: +case 0xd7f9: +case 0xd9f9: +case 0xdbf9: +case 0xddf9: +case 0xdff9: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb1f9: +case 0xb3f9: +case 0xb5f9: +case 0xb7f9: +case 0xb9f9: +case 0xbbf9: +case 0xbdf9: +case 0xbff9: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x91f9: +case 0x93f9: +case 0x95f9: +case 0x97f9: +case 0x99f9: +case 0x9bf9: +case 0x9df9: +case 0x9ff9: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x20b9: +case 0x22b9: +case 0x24b9: +case 0x26b9: +case 0x28b9: +case 0x2ab9: +case 0x2cb9: +case 0x2eb9: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2179: +case 0x2379: +case 0x2579: +case 0x2779: +case 0x2979: +case 0x2b79: +case 0x2d79: +case 0x2f79: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x21b9: +case 0x23b9: +case 0x25b9: +case 0x27b9: +case 0x29b9: +case 0x2bb9: +case 0x2db9: +case 0x2fb9: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x20f9: +case 0x22f9: +case 0x24f9: +case 0x26f9: +case 0x28f9: +case 0x2af9: +case 0x2cf9: +case 0x2ef9: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2139: +case 0x2339: +case 0x2539: +case 0x2739: +case 0x2939: +case 0x2b39: +case 0x2d39: +case 0x2f39: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd0b9: +case 0xd2b9: +case 0xd4b9: +case 0xd6b9: +case 0xd8b9: +case 0xdab9: +case 0xdcb9: +case 0xdeb9: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc0b9: +case 0xc2b9: +case 0xc4b9: +case 0xc6b9: +case 0xc8b9: +case 0xcab9: +case 0xccb9: +case 0xceb9: + { + HAM src(this); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb0b9: +case 0xb2b9: +case 0xb4b9: +case 0xb6b9: +case 0xb8b9: +case 0xbab9: +case 0xbcb9: +case 0xbeb9: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x2039: +case 0x2239: +case 0x2439: +case 0x2639: +case 0x2839: +case 0x2a39: +case 0x2c39: +case 0x2e39: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x80b9: +case 0x82b9: +case 0x84b9: +case 0x86b9: +case 0x88b9: +case 0x8ab9: +case 0x8cb9: +case 0x8eb9: + { + HAM src(this); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x90b9: +case 0x92b9: +case 0x94b9: +case 0x96b9: +case 0x98b9: +case 0x9ab9: +case 0x9cb9: +case 0x9eb9: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x2079: +case 0x2279: +case 0x2479: +case 0x2679: +case 0x2879: +case 0x2a79: +case 0x2c79: +case 0x2e79: + { + HAM src(this); MOVEA(src, instr_b11_b9); + } + break; + +case 0x42b8: + { + HAM dst(this); CLR(dst); + } + break; + +case 0x44b8: + { + HAM dst(this); NEG(dst); + } + break; + +case 0x40b8: + { + HAM dst(this); NEGX(dst); + } + break; + +case 0x46b8: + { + HAM dst(this); NOT(dst); + } + break; + +case 0x4ab8: + { + HAM dst(this); TST(dst); + } + break; + +case 0x23f8: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x21f8: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0xd1f8: +case 0xd3f8: +case 0xd5f8: +case 0xd7f8: +case 0xd9f8: +case 0xdbf8: +case 0xddf8: +case 0xdff8: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb1f8: +case 0xb3f8: +case 0xb5f8: +case 0xb7f8: +case 0xb9f8: +case 0xbbf8: +case 0xbdf8: +case 0xbff8: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x91f8: +case 0x93f8: +case 0x95f8: +case 0x97f8: +case 0x99f8: +case 0x9bf8: +case 0x9df8: +case 0x9ff8: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x20b8: +case 0x22b8: +case 0x24b8: +case 0x26b8: +case 0x28b8: +case 0x2ab8: +case 0x2cb8: +case 0x2eb8: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2178: +case 0x2378: +case 0x2578: +case 0x2778: +case 0x2978: +case 0x2b78: +case 0x2d78: +case 0x2f78: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x21b8: +case 0x23b8: +case 0x25b8: +case 0x27b8: +case 0x29b8: +case 0x2bb8: +case 0x2db8: +case 0x2fb8: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x20f8: +case 0x22f8: +case 0x24f8: +case 0x26f8: +case 0x28f8: +case 0x2af8: +case 0x2cf8: +case 0x2ef8: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2138: +case 0x2338: +case 0x2538: +case 0x2738: +case 0x2938: +case 0x2b38: +case 0x2d38: +case 0x2f38: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd0b8: +case 0xd2b8: +case 0xd4b8: +case 0xd6b8: +case 0xd8b8: +case 0xdab8: +case 0xdcb8: +case 0xdeb8: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc0b8: +case 0xc2b8: +case 0xc4b8: +case 0xc6b8: +case 0xc8b8: +case 0xcab8: +case 0xccb8: +case 0xceb8: + { + HAM src(this); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb0b8: +case 0xb2b8: +case 0xb4b8: +case 0xb6b8: +case 0xb8b8: +case 0xbab8: +case 0xbcb8: +case 0xbeb8: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x2038: +case 0x2238: +case 0x2438: +case 0x2638: +case 0x2838: +case 0x2a38: +case 0x2c38: +case 0x2e38: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x80b8: +case 0x82b8: +case 0x84b8: +case 0x86b8: +case 0x88b8: +case 0x8ab8: +case 0x8cb8: +case 0x8eb8: + { + HAM src(this); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x90b8: +case 0x92b8: +case 0x94b8: +case 0x96b8: +case 0x98b8: +case 0x9ab8: +case 0x9cb8: +case 0x9eb8: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x2078: +case 0x2278: +case 0x2478: +case 0x2678: +case 0x2878: +case 0x2a78: +case 0x2c78: +case 0x2e78: + { + HAM src(this); MOVEA(src, instr_b11_b9); + } + break; + +case 0x23c8: +case 0x23c9: +case 0x23ca: +case 0x23cb: +case 0x23cc: +case 0x23cd: +case 0x23ce: +case 0x23cf: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x21c8: +case 0x21c9: +case 0x21ca: +case 0x21cb: +case 0x21cc: +case 0x21cd: +case 0x21ce: +case 0x21cf: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0xd1c8: +case 0xd1c9: +case 0xd1ca: +case 0xd1cb: +case 0xd1cc: +case 0xd1cd: +case 0xd1ce: +case 0xd1cf: +case 0xd3c8: +case 0xd3c9: +case 0xd3ca: +case 0xd3cb: +case 0xd3cc: +case 0xd3cd: +case 0xd3ce: +case 0xd3cf: +case 0xd5c8: +case 0xd5c9: +case 0xd5ca: +case 0xd5cb: +case 0xd5cc: +case 0xd5cd: +case 0xd5ce: +case 0xd5cf: +case 0xd7c8: +case 0xd7c9: +case 0xd7ca: +case 0xd7cb: +case 0xd7cc: +case 0xd7cd: +case 0xd7ce: +case 0xd7cf: +case 0xd9c8: +case 0xd9c9: +case 0xd9ca: +case 0xd9cb: +case 0xd9cc: +case 0xd9cd: +case 0xd9ce: +case 0xd9cf: +case 0xdbc8: +case 0xdbc9: +case 0xdbca: +case 0xdbcb: +case 0xdbcc: +case 0xdbcd: +case 0xdbce: +case 0xdbcf: +case 0xddc8: +case 0xddc9: +case 0xddca: +case 0xddcb: +case 0xddcc: +case 0xddcd: +case 0xddce: +case 0xddcf: +case 0xdfc8: +case 0xdfc9: +case 0xdfca: +case 0xdfcb: +case 0xdfcc: +case 0xdfcd: +case 0xdfce: +case 0xdfcf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb1c8: +case 0xb1c9: +case 0xb1ca: +case 0xb1cb: +case 0xb1cc: +case 0xb1cd: +case 0xb1ce: +case 0xb1cf: +case 0xb3c8: +case 0xb3c9: +case 0xb3ca: +case 0xb3cb: +case 0xb3cc: +case 0xb3cd: +case 0xb3ce: +case 0xb3cf: +case 0xb5c8: +case 0xb5c9: +case 0xb5ca: +case 0xb5cb: +case 0xb5cc: +case 0xb5cd: +case 0xb5ce: +case 0xb5cf: +case 0xb7c8: +case 0xb7c9: +case 0xb7ca: +case 0xb7cb: +case 0xb7cc: +case 0xb7cd: +case 0xb7ce: +case 0xb7cf: +case 0xb9c8: +case 0xb9c9: +case 0xb9ca: +case 0xb9cb: +case 0xb9cc: +case 0xb9cd: +case 0xb9ce: +case 0xb9cf: +case 0xbbc8: +case 0xbbc9: +case 0xbbca: +case 0xbbcb: +case 0xbbcc: +case 0xbbcd: +case 0xbbce: +case 0xbbcf: +case 0xbdc8: +case 0xbdc9: +case 0xbdca: +case 0xbdcb: +case 0xbdcc: +case 0xbdcd: +case 0xbdce: +case 0xbdcf: +case 0xbfc8: +case 0xbfc9: +case 0xbfca: +case 0xbfcb: +case 0xbfcc: +case 0xbfcd: +case 0xbfce: +case 0xbfcf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x91c8: +case 0x91c9: +case 0x91ca: +case 0x91cb: +case 0x91cc: +case 0x91cd: +case 0x91ce: +case 0x91cf: +case 0x93c8: +case 0x93c9: +case 0x93ca: +case 0x93cb: +case 0x93cc: +case 0x93cd: +case 0x93ce: +case 0x93cf: +case 0x95c8: +case 0x95c9: +case 0x95ca: +case 0x95cb: +case 0x95cc: +case 0x95cd: +case 0x95ce: +case 0x95cf: +case 0x97c8: +case 0x97c9: +case 0x97ca: +case 0x97cb: +case 0x97cc: +case 0x97cd: +case 0x97ce: +case 0x97cf: +case 0x99c8: +case 0x99c9: +case 0x99ca: +case 0x99cb: +case 0x99cc: +case 0x99cd: +case 0x99ce: +case 0x99cf: +case 0x9bc8: +case 0x9bc9: +case 0x9bca: +case 0x9bcb: +case 0x9bcc: +case 0x9bcd: +case 0x9bce: +case 0x9bcf: +case 0x9dc8: +case 0x9dc9: +case 0x9dca: +case 0x9dcb: +case 0x9dcc: +case 0x9dcd: +case 0x9dce: +case 0x9dcf: +case 0x9fc8: +case 0x9fc9: +case 0x9fca: +case 0x9fcb: +case 0x9fcc: +case 0x9fcd: +case 0x9fce: +case 0x9fcf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x2088: +case 0x2089: +case 0x208a: +case 0x208b: +case 0x208c: +case 0x208d: +case 0x208e: +case 0x208f: +case 0x2288: +case 0x2289: +case 0x228a: +case 0x228b: +case 0x228c: +case 0x228d: +case 0x228e: +case 0x228f: +case 0x2488: +case 0x2489: +case 0x248a: +case 0x248b: +case 0x248c: +case 0x248d: +case 0x248e: +case 0x248f: +case 0x2688: +case 0x2689: +case 0x268a: +case 0x268b: +case 0x268c: +case 0x268d: +case 0x268e: +case 0x268f: +case 0x2888: +case 0x2889: +case 0x288a: +case 0x288b: +case 0x288c: +case 0x288d: +case 0x288e: +case 0x288f: +case 0x2a88: +case 0x2a89: +case 0x2a8a: +case 0x2a8b: +case 0x2a8c: +case 0x2a8d: +case 0x2a8e: +case 0x2a8f: +case 0x2c88: +case 0x2c89: +case 0x2c8a: +case 0x2c8b: +case 0x2c8c: +case 0x2c8d: +case 0x2c8e: +case 0x2c8f: +case 0x2e88: +case 0x2e89: +case 0x2e8a: +case 0x2e8b: +case 0x2e8c: +case 0x2e8d: +case 0x2e8e: +case 0x2e8f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2148: +case 0x2149: +case 0x214a: +case 0x214b: +case 0x214c: +case 0x214d: +case 0x214e: +case 0x214f: +case 0x2348: +case 0x2349: +case 0x234a: +case 0x234b: +case 0x234c: +case 0x234d: +case 0x234e: +case 0x234f: +case 0x2548: +case 0x2549: +case 0x254a: +case 0x254b: +case 0x254c: +case 0x254d: +case 0x254e: +case 0x254f: +case 0x2748: +case 0x2749: +case 0x274a: +case 0x274b: +case 0x274c: +case 0x274d: +case 0x274e: +case 0x274f: +case 0x2948: +case 0x2949: +case 0x294a: +case 0x294b: +case 0x294c: +case 0x294d: +case 0x294e: +case 0x294f: +case 0x2b48: +case 0x2b49: +case 0x2b4a: +case 0x2b4b: +case 0x2b4c: +case 0x2b4d: +case 0x2b4e: +case 0x2b4f: +case 0x2d48: +case 0x2d49: +case 0x2d4a: +case 0x2d4b: +case 0x2d4c: +case 0x2d4d: +case 0x2d4e: +case 0x2d4f: +case 0x2f48: +case 0x2f49: +case 0x2f4a: +case 0x2f4b: +case 0x2f4c: +case 0x2f4d: +case 0x2f4e: +case 0x2f4f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2188: +case 0x2189: +case 0x218a: +case 0x218b: +case 0x218c: +case 0x218d: +case 0x218e: +case 0x218f: +case 0x2388: +case 0x2389: +case 0x238a: +case 0x238b: +case 0x238c: +case 0x238d: +case 0x238e: +case 0x238f: +case 0x2588: +case 0x2589: +case 0x258a: +case 0x258b: +case 0x258c: +case 0x258d: +case 0x258e: +case 0x258f: +case 0x2788: +case 0x2789: +case 0x278a: +case 0x278b: +case 0x278c: +case 0x278d: +case 0x278e: +case 0x278f: +case 0x2988: +case 0x2989: +case 0x298a: +case 0x298b: +case 0x298c: +case 0x298d: +case 0x298e: +case 0x298f: +case 0x2b88: +case 0x2b89: +case 0x2b8a: +case 0x2b8b: +case 0x2b8c: +case 0x2b8d: +case 0x2b8e: +case 0x2b8f: +case 0x2d88: +case 0x2d89: +case 0x2d8a: +case 0x2d8b: +case 0x2d8c: +case 0x2d8d: +case 0x2d8e: +case 0x2d8f: +case 0x2f88: +case 0x2f89: +case 0x2f8a: +case 0x2f8b: +case 0x2f8c: +case 0x2f8d: +case 0x2f8e: +case 0x2f8f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x20c8: +case 0x20c9: +case 0x20ca: +case 0x20cb: +case 0x20cc: +case 0x20cd: +case 0x20ce: +case 0x20cf: +case 0x22c8: +case 0x22c9: +case 0x22ca: +case 0x22cb: +case 0x22cc: +case 0x22cd: +case 0x22ce: +case 0x22cf: +case 0x24c8: +case 0x24c9: +case 0x24ca: +case 0x24cb: +case 0x24cc: +case 0x24cd: +case 0x24ce: +case 0x24cf: +case 0x26c8: +case 0x26c9: +case 0x26ca: +case 0x26cb: +case 0x26cc: +case 0x26cd: +case 0x26ce: +case 0x26cf: +case 0x28c8: +case 0x28c9: +case 0x28ca: +case 0x28cb: +case 0x28cc: +case 0x28cd: +case 0x28ce: +case 0x28cf: +case 0x2ac8: +case 0x2ac9: +case 0x2aca: +case 0x2acb: +case 0x2acc: +case 0x2acd: +case 0x2ace: +case 0x2acf: +case 0x2cc8: +case 0x2cc9: +case 0x2cca: +case 0x2ccb: +case 0x2ccc: +case 0x2ccd: +case 0x2cce: +case 0x2ccf: +case 0x2ec8: +case 0x2ec9: +case 0x2eca: +case 0x2ecb: +case 0x2ecc: +case 0x2ecd: +case 0x2ece: +case 0x2ecf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2108: +case 0x2109: +case 0x210a: +case 0x210b: +case 0x210c: +case 0x210d: +case 0x210e: +case 0x210f: +case 0x2308: +case 0x2309: +case 0x230a: +case 0x230b: +case 0x230c: +case 0x230d: +case 0x230e: +case 0x230f: +case 0x2508: +case 0x2509: +case 0x250a: +case 0x250b: +case 0x250c: +case 0x250d: +case 0x250e: +case 0x250f: +case 0x2708: +case 0x2709: +case 0x270a: +case 0x270b: +case 0x270c: +case 0x270d: +case 0x270e: +case 0x270f: +case 0x2908: +case 0x2909: +case 0x290a: +case 0x290b: +case 0x290c: +case 0x290d: +case 0x290e: +case 0x290f: +case 0x2b08: +case 0x2b09: +case 0x2b0a: +case 0x2b0b: +case 0x2b0c: +case 0x2b0d: +case 0x2b0e: +case 0x2b0f: +case 0x2d08: +case 0x2d09: +case 0x2d0a: +case 0x2d0b: +case 0x2d0c: +case 0x2d0d: +case 0x2d0e: +case 0x2d0f: +case 0x2f08: +case 0x2f09: +case 0x2f0a: +case 0x2f0b: +case 0x2f0c: +case 0x2f0d: +case 0x2f0e: +case 0x2f0f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd088: +case 0xd089: +case 0xd08a: +case 0xd08b: +case 0xd08c: +case 0xd08d: +case 0xd08e: +case 0xd08f: +case 0xd288: +case 0xd289: +case 0xd28a: +case 0xd28b: +case 0xd28c: +case 0xd28d: +case 0xd28e: +case 0xd28f: +case 0xd488: +case 0xd489: +case 0xd48a: +case 0xd48b: +case 0xd48c: +case 0xd48d: +case 0xd48e: +case 0xd48f: +case 0xd688: +case 0xd689: +case 0xd68a: +case 0xd68b: +case 0xd68c: +case 0xd68d: +case 0xd68e: +case 0xd68f: +case 0xd888: +case 0xd889: +case 0xd88a: +case 0xd88b: +case 0xd88c: +case 0xd88d: +case 0xd88e: +case 0xd88f: +case 0xda88: +case 0xda89: +case 0xda8a: +case 0xda8b: +case 0xda8c: +case 0xda8d: +case 0xda8e: +case 0xda8f: +case 0xdc88: +case 0xdc89: +case 0xdc8a: +case 0xdc8b: +case 0xdc8c: +case 0xdc8d: +case 0xdc8e: +case 0xdc8f: +case 0xde88: +case 0xde89: +case 0xde8a: +case 0xde8b: +case 0xde8c: +case 0xde8d: +case 0xde8e: +case 0xde8f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb088: +case 0xb089: +case 0xb08a: +case 0xb08b: +case 0xb08c: +case 0xb08d: +case 0xb08e: +case 0xb08f: +case 0xb288: +case 0xb289: +case 0xb28a: +case 0xb28b: +case 0xb28c: +case 0xb28d: +case 0xb28e: +case 0xb28f: +case 0xb488: +case 0xb489: +case 0xb48a: +case 0xb48b: +case 0xb48c: +case 0xb48d: +case 0xb48e: +case 0xb48f: +case 0xb688: +case 0xb689: +case 0xb68a: +case 0xb68b: +case 0xb68c: +case 0xb68d: +case 0xb68e: +case 0xb68f: +case 0xb888: +case 0xb889: +case 0xb88a: +case 0xb88b: +case 0xb88c: +case 0xb88d: +case 0xb88e: +case 0xb88f: +case 0xba88: +case 0xba89: +case 0xba8a: +case 0xba8b: +case 0xba8c: +case 0xba8d: +case 0xba8e: +case 0xba8f: +case 0xbc88: +case 0xbc89: +case 0xbc8a: +case 0xbc8b: +case 0xbc8c: +case 0xbc8d: +case 0xbc8e: +case 0xbc8f: +case 0xbe88: +case 0xbe89: +case 0xbe8a: +case 0xbe8b: +case 0xbe8c: +case 0xbe8d: +case 0xbe8e: +case 0xbe8f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x2008: +case 0x2009: +case 0x200a: +case 0x200b: +case 0x200c: +case 0x200d: +case 0x200e: +case 0x200f: +case 0x2208: +case 0x2209: +case 0x220a: +case 0x220b: +case 0x220c: +case 0x220d: +case 0x220e: +case 0x220f: +case 0x2408: +case 0x2409: +case 0x240a: +case 0x240b: +case 0x240c: +case 0x240d: +case 0x240e: +case 0x240f: +case 0x2608: +case 0x2609: +case 0x260a: +case 0x260b: +case 0x260c: +case 0x260d: +case 0x260e: +case 0x260f: +case 0x2808: +case 0x2809: +case 0x280a: +case 0x280b: +case 0x280c: +case 0x280d: +case 0x280e: +case 0x280f: +case 0x2a08: +case 0x2a09: +case 0x2a0a: +case 0x2a0b: +case 0x2a0c: +case 0x2a0d: +case 0x2a0e: +case 0x2a0f: +case 0x2c08: +case 0x2c09: +case 0x2c0a: +case 0x2c0b: +case 0x2c0c: +case 0x2c0d: +case 0x2c0e: +case 0x2c0f: +case 0x2e08: +case 0x2e09: +case 0x2e0a: +case 0x2e0b: +case 0x2e0c: +case 0x2e0d: +case 0x2e0e: +case 0x2e0f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x9088: +case 0x9089: +case 0x908a: +case 0x908b: +case 0x908c: +case 0x908d: +case 0x908e: +case 0x908f: +case 0x9288: +case 0x9289: +case 0x928a: +case 0x928b: +case 0x928c: +case 0x928d: +case 0x928e: +case 0x928f: +case 0x9488: +case 0x9489: +case 0x948a: +case 0x948b: +case 0x948c: +case 0x948d: +case 0x948e: +case 0x948f: +case 0x9688: +case 0x9689: +case 0x968a: +case 0x968b: +case 0x968c: +case 0x968d: +case 0x968e: +case 0x968f: +case 0x9888: +case 0x9889: +case 0x988a: +case 0x988b: +case 0x988c: +case 0x988d: +case 0x988e: +case 0x988f: +case 0x9a88: +case 0x9a89: +case 0x9a8a: +case 0x9a8b: +case 0x9a8c: +case 0x9a8d: +case 0x9a8e: +case 0x9a8f: +case 0x9c88: +case 0x9c89: +case 0x9c8a: +case 0x9c8b: +case 0x9c8c: +case 0x9c8d: +case 0x9c8e: +case 0x9c8f: +case 0x9e88: +case 0x9e89: +case 0x9e8a: +case 0x9e8b: +case 0x9e8c: +case 0x9e8d: +case 0x9e8e: +case 0x9e8f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x2048: +case 0x2049: +case 0x204a: +case 0x204b: +case 0x204c: +case 0x204d: +case 0x204e: +case 0x204f: +case 0x2248: +case 0x2249: +case 0x224a: +case 0x224b: +case 0x224c: +case 0x224d: +case 0x224e: +case 0x224f: +case 0x2448: +case 0x2449: +case 0x244a: +case 0x244b: +case 0x244c: +case 0x244d: +case 0x244e: +case 0x244f: +case 0x2648: +case 0x2649: +case 0x264a: +case 0x264b: +case 0x264c: +case 0x264d: +case 0x264e: +case 0x264f: +case 0x2848: +case 0x2849: +case 0x284a: +case 0x284b: +case 0x284c: +case 0x284d: +case 0x284e: +case 0x284f: +case 0x2a48: +case 0x2a49: +case 0x2a4a: +case 0x2a4b: +case 0x2a4c: +case 0x2a4d: +case 0x2a4e: +case 0x2a4f: +case 0x2c48: +case 0x2c49: +case 0x2c4a: +case 0x2c4b: +case 0x2c4c: +case 0x2c4d: +case 0x2c4e: +case 0x2c4f: +case 0x2e48: +case 0x2e49: +case 0x2e4a: +case 0x2e4b: +case 0x2e4c: +case 0x2e4d: +case 0x2e4e: +case 0x2e4f: + { + HAM src(this, instr_b2_b0); MOVEA(src, instr_b11_b9); + } + break; + +case 0x4290: +case 0x4291: +case 0x4292: +case 0x4293: +case 0x4294: +case 0x4295: +case 0x4296: +case 0x4297: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x4490: +case 0x4491: +case 0x4492: +case 0x4493: +case 0x4494: +case 0x4495: +case 0x4496: +case 0x4497: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x4090: +case 0x4091: +case 0x4092: +case 0x4093: +case 0x4094: +case 0x4095: +case 0x4096: +case 0x4097: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x4690: +case 0x4691: +case 0x4692: +case 0x4693: +case 0x4694: +case 0x4695: +case 0x4696: +case 0x4697: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x4a90: +case 0x4a91: +case 0x4a92: +case 0x4a93: +case 0x4a94: +case 0x4a95: +case 0x4a96: +case 0x4a97: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0x23d0: +case 0x23d1: +case 0x23d2: +case 0x23d3: +case 0x23d4: +case 0x23d5: +case 0x23d6: +case 0x23d7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x21d0: +case 0x21d1: +case 0x21d2: +case 0x21d3: +case 0x21d4: +case 0x21d5: +case 0x21d6: +case 0x21d7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0xd1d0: +case 0xd1d1: +case 0xd1d2: +case 0xd1d3: +case 0xd1d4: +case 0xd1d5: +case 0xd1d6: +case 0xd1d7: +case 0xd3d0: +case 0xd3d1: +case 0xd3d2: +case 0xd3d3: +case 0xd3d4: +case 0xd3d5: +case 0xd3d6: +case 0xd3d7: +case 0xd5d0: +case 0xd5d1: +case 0xd5d2: +case 0xd5d3: +case 0xd5d4: +case 0xd5d5: +case 0xd5d6: +case 0xd5d7: +case 0xd7d0: +case 0xd7d1: +case 0xd7d2: +case 0xd7d3: +case 0xd7d4: +case 0xd7d5: +case 0xd7d6: +case 0xd7d7: +case 0xd9d0: +case 0xd9d1: +case 0xd9d2: +case 0xd9d3: +case 0xd9d4: +case 0xd9d5: +case 0xd9d6: +case 0xd9d7: +case 0xdbd0: +case 0xdbd1: +case 0xdbd2: +case 0xdbd3: +case 0xdbd4: +case 0xdbd5: +case 0xdbd6: +case 0xdbd7: +case 0xddd0: +case 0xddd1: +case 0xddd2: +case 0xddd3: +case 0xddd4: +case 0xddd5: +case 0xddd6: +case 0xddd7: +case 0xdfd0: +case 0xdfd1: +case 0xdfd2: +case 0xdfd3: +case 0xdfd4: +case 0xdfd5: +case 0xdfd6: +case 0xdfd7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb1d0: +case 0xb1d1: +case 0xb1d2: +case 0xb1d3: +case 0xb1d4: +case 0xb1d5: +case 0xb1d6: +case 0xb1d7: +case 0xb3d0: +case 0xb3d1: +case 0xb3d2: +case 0xb3d3: +case 0xb3d4: +case 0xb3d5: +case 0xb3d6: +case 0xb3d7: +case 0xb5d0: +case 0xb5d1: +case 0xb5d2: +case 0xb5d3: +case 0xb5d4: +case 0xb5d5: +case 0xb5d6: +case 0xb5d7: +case 0xb7d0: +case 0xb7d1: +case 0xb7d2: +case 0xb7d3: +case 0xb7d4: +case 0xb7d5: +case 0xb7d6: +case 0xb7d7: +case 0xb9d0: +case 0xb9d1: +case 0xb9d2: +case 0xb9d3: +case 0xb9d4: +case 0xb9d5: +case 0xb9d6: +case 0xb9d7: +case 0xbbd0: +case 0xbbd1: +case 0xbbd2: +case 0xbbd3: +case 0xbbd4: +case 0xbbd5: +case 0xbbd6: +case 0xbbd7: +case 0xbdd0: +case 0xbdd1: +case 0xbdd2: +case 0xbdd3: +case 0xbdd4: +case 0xbdd5: +case 0xbdd6: +case 0xbdd7: +case 0xbfd0: +case 0xbfd1: +case 0xbfd2: +case 0xbfd3: +case 0xbfd4: +case 0xbfd5: +case 0xbfd6: +case 0xbfd7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x91d0: +case 0x91d1: +case 0x91d2: +case 0x91d3: +case 0x91d4: +case 0x91d5: +case 0x91d6: +case 0x91d7: +case 0x93d0: +case 0x93d1: +case 0x93d2: +case 0x93d3: +case 0x93d4: +case 0x93d5: +case 0x93d6: +case 0x93d7: +case 0x95d0: +case 0x95d1: +case 0x95d2: +case 0x95d3: +case 0x95d4: +case 0x95d5: +case 0x95d6: +case 0x95d7: +case 0x97d0: +case 0x97d1: +case 0x97d2: +case 0x97d3: +case 0x97d4: +case 0x97d5: +case 0x97d6: +case 0x97d7: +case 0x99d0: +case 0x99d1: +case 0x99d2: +case 0x99d3: +case 0x99d4: +case 0x99d5: +case 0x99d6: +case 0x99d7: +case 0x9bd0: +case 0x9bd1: +case 0x9bd2: +case 0x9bd3: +case 0x9bd4: +case 0x9bd5: +case 0x9bd6: +case 0x9bd7: +case 0x9dd0: +case 0x9dd1: +case 0x9dd2: +case 0x9dd3: +case 0x9dd4: +case 0x9dd5: +case 0x9dd6: +case 0x9dd7: +case 0x9fd0: +case 0x9fd1: +case 0x9fd2: +case 0x9fd3: +case 0x9fd4: +case 0x9fd5: +case 0x9fd6: +case 0x9fd7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x2090: +case 0x2091: +case 0x2092: +case 0x2093: +case 0x2094: +case 0x2095: +case 0x2096: +case 0x2097: +case 0x2290: +case 0x2291: +case 0x2292: +case 0x2293: +case 0x2294: +case 0x2295: +case 0x2296: +case 0x2297: +case 0x2490: +case 0x2491: +case 0x2492: +case 0x2493: +case 0x2494: +case 0x2495: +case 0x2496: +case 0x2497: +case 0x2690: +case 0x2691: +case 0x2692: +case 0x2693: +case 0x2694: +case 0x2695: +case 0x2696: +case 0x2697: +case 0x2890: +case 0x2891: +case 0x2892: +case 0x2893: +case 0x2894: +case 0x2895: +case 0x2896: +case 0x2897: +case 0x2a90: +case 0x2a91: +case 0x2a92: +case 0x2a93: +case 0x2a94: +case 0x2a95: +case 0x2a96: +case 0x2a97: +case 0x2c90: +case 0x2c91: +case 0x2c92: +case 0x2c93: +case 0x2c94: +case 0x2c95: +case 0x2c96: +case 0x2c97: +case 0x2e90: +case 0x2e91: +case 0x2e92: +case 0x2e93: +case 0x2e94: +case 0x2e95: +case 0x2e96: +case 0x2e97: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2150: +case 0x2151: +case 0x2152: +case 0x2153: +case 0x2154: +case 0x2155: +case 0x2156: +case 0x2157: +case 0x2350: +case 0x2351: +case 0x2352: +case 0x2353: +case 0x2354: +case 0x2355: +case 0x2356: +case 0x2357: +case 0x2550: +case 0x2551: +case 0x2552: +case 0x2553: +case 0x2554: +case 0x2555: +case 0x2556: +case 0x2557: +case 0x2750: +case 0x2751: +case 0x2752: +case 0x2753: +case 0x2754: +case 0x2755: +case 0x2756: +case 0x2757: +case 0x2950: +case 0x2951: +case 0x2952: +case 0x2953: +case 0x2954: +case 0x2955: +case 0x2956: +case 0x2957: +case 0x2b50: +case 0x2b51: +case 0x2b52: +case 0x2b53: +case 0x2b54: +case 0x2b55: +case 0x2b56: +case 0x2b57: +case 0x2d50: +case 0x2d51: +case 0x2d52: +case 0x2d53: +case 0x2d54: +case 0x2d55: +case 0x2d56: +case 0x2d57: +case 0x2f50: +case 0x2f51: +case 0x2f52: +case 0x2f53: +case 0x2f54: +case 0x2f55: +case 0x2f56: +case 0x2f57: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2190: +case 0x2191: +case 0x2192: +case 0x2193: +case 0x2194: +case 0x2195: +case 0x2196: +case 0x2197: +case 0x2390: +case 0x2391: +case 0x2392: +case 0x2393: +case 0x2394: +case 0x2395: +case 0x2396: +case 0x2397: +case 0x2590: +case 0x2591: +case 0x2592: +case 0x2593: +case 0x2594: +case 0x2595: +case 0x2596: +case 0x2597: +case 0x2790: +case 0x2791: +case 0x2792: +case 0x2793: +case 0x2794: +case 0x2795: +case 0x2796: +case 0x2797: +case 0x2990: +case 0x2991: +case 0x2992: +case 0x2993: +case 0x2994: +case 0x2995: +case 0x2996: +case 0x2997: +case 0x2b90: +case 0x2b91: +case 0x2b92: +case 0x2b93: +case 0x2b94: +case 0x2b95: +case 0x2b96: +case 0x2b97: +case 0x2d90: +case 0x2d91: +case 0x2d92: +case 0x2d93: +case 0x2d94: +case 0x2d95: +case 0x2d96: +case 0x2d97: +case 0x2f90: +case 0x2f91: +case 0x2f92: +case 0x2f93: +case 0x2f94: +case 0x2f95: +case 0x2f96: +case 0x2f97: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x20d0: +case 0x20d1: +case 0x20d2: +case 0x20d3: +case 0x20d4: +case 0x20d5: +case 0x20d6: +case 0x20d7: +case 0x22d0: +case 0x22d1: +case 0x22d2: +case 0x22d3: +case 0x22d4: +case 0x22d5: +case 0x22d6: +case 0x22d7: +case 0x24d0: +case 0x24d1: +case 0x24d2: +case 0x24d3: +case 0x24d4: +case 0x24d5: +case 0x24d6: +case 0x24d7: +case 0x26d0: +case 0x26d1: +case 0x26d2: +case 0x26d3: +case 0x26d4: +case 0x26d5: +case 0x26d6: +case 0x26d7: +case 0x28d0: +case 0x28d1: +case 0x28d2: +case 0x28d3: +case 0x28d4: +case 0x28d5: +case 0x28d6: +case 0x28d7: +case 0x2ad0: +case 0x2ad1: +case 0x2ad2: +case 0x2ad3: +case 0x2ad4: +case 0x2ad5: +case 0x2ad6: +case 0x2ad7: +case 0x2cd0: +case 0x2cd1: +case 0x2cd2: +case 0x2cd3: +case 0x2cd4: +case 0x2cd5: +case 0x2cd6: +case 0x2cd7: +case 0x2ed0: +case 0x2ed1: +case 0x2ed2: +case 0x2ed3: +case 0x2ed4: +case 0x2ed5: +case 0x2ed6: +case 0x2ed7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2110: +case 0x2111: +case 0x2112: +case 0x2113: +case 0x2114: +case 0x2115: +case 0x2116: +case 0x2117: +case 0x2310: +case 0x2311: +case 0x2312: +case 0x2313: +case 0x2314: +case 0x2315: +case 0x2316: +case 0x2317: +case 0x2510: +case 0x2511: +case 0x2512: +case 0x2513: +case 0x2514: +case 0x2515: +case 0x2516: +case 0x2517: +case 0x2710: +case 0x2711: +case 0x2712: +case 0x2713: +case 0x2714: +case 0x2715: +case 0x2716: +case 0x2717: +case 0x2910: +case 0x2911: +case 0x2912: +case 0x2913: +case 0x2914: +case 0x2915: +case 0x2916: +case 0x2917: +case 0x2b10: +case 0x2b11: +case 0x2b12: +case 0x2b13: +case 0x2b14: +case 0x2b15: +case 0x2b16: +case 0x2b17: +case 0x2d10: +case 0x2d11: +case 0x2d12: +case 0x2d13: +case 0x2d14: +case 0x2d15: +case 0x2d16: +case 0x2d17: +case 0x2f10: +case 0x2f11: +case 0x2f12: +case 0x2f13: +case 0x2f14: +case 0x2f15: +case 0x2f16: +case 0x2f17: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd090: +case 0xd091: +case 0xd092: +case 0xd093: +case 0xd094: +case 0xd095: +case 0xd096: +case 0xd097: +case 0xd290: +case 0xd291: +case 0xd292: +case 0xd293: +case 0xd294: +case 0xd295: +case 0xd296: +case 0xd297: +case 0xd490: +case 0xd491: +case 0xd492: +case 0xd493: +case 0xd494: +case 0xd495: +case 0xd496: +case 0xd497: +case 0xd690: +case 0xd691: +case 0xd692: +case 0xd693: +case 0xd694: +case 0xd695: +case 0xd696: +case 0xd697: +case 0xd890: +case 0xd891: +case 0xd892: +case 0xd893: +case 0xd894: +case 0xd895: +case 0xd896: +case 0xd897: +case 0xda90: +case 0xda91: +case 0xda92: +case 0xda93: +case 0xda94: +case 0xda95: +case 0xda96: +case 0xda97: +case 0xdc90: +case 0xdc91: +case 0xdc92: +case 0xdc93: +case 0xdc94: +case 0xdc95: +case 0xdc96: +case 0xdc97: +case 0xde90: +case 0xde91: +case 0xde92: +case 0xde93: +case 0xde94: +case 0xde95: +case 0xde96: +case 0xde97: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc090: +case 0xc091: +case 0xc092: +case 0xc093: +case 0xc094: +case 0xc095: +case 0xc096: +case 0xc097: +case 0xc290: +case 0xc291: +case 0xc292: +case 0xc293: +case 0xc294: +case 0xc295: +case 0xc296: +case 0xc297: +case 0xc490: +case 0xc491: +case 0xc492: +case 0xc493: +case 0xc494: +case 0xc495: +case 0xc496: +case 0xc497: +case 0xc690: +case 0xc691: +case 0xc692: +case 0xc693: +case 0xc694: +case 0xc695: +case 0xc696: +case 0xc697: +case 0xc890: +case 0xc891: +case 0xc892: +case 0xc893: +case 0xc894: +case 0xc895: +case 0xc896: +case 0xc897: +case 0xca90: +case 0xca91: +case 0xca92: +case 0xca93: +case 0xca94: +case 0xca95: +case 0xca96: +case 0xca97: +case 0xcc90: +case 0xcc91: +case 0xcc92: +case 0xcc93: +case 0xcc94: +case 0xcc95: +case 0xcc96: +case 0xcc97: +case 0xce90: +case 0xce91: +case 0xce92: +case 0xce93: +case 0xce94: +case 0xce95: +case 0xce96: +case 0xce97: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb090: +case 0xb091: +case 0xb092: +case 0xb093: +case 0xb094: +case 0xb095: +case 0xb096: +case 0xb097: +case 0xb290: +case 0xb291: +case 0xb292: +case 0xb293: +case 0xb294: +case 0xb295: +case 0xb296: +case 0xb297: +case 0xb490: +case 0xb491: +case 0xb492: +case 0xb493: +case 0xb494: +case 0xb495: +case 0xb496: +case 0xb497: +case 0xb690: +case 0xb691: +case 0xb692: +case 0xb693: +case 0xb694: +case 0xb695: +case 0xb696: +case 0xb697: +case 0xb890: +case 0xb891: +case 0xb892: +case 0xb893: +case 0xb894: +case 0xb895: +case 0xb896: +case 0xb897: +case 0xba90: +case 0xba91: +case 0xba92: +case 0xba93: +case 0xba94: +case 0xba95: +case 0xba96: +case 0xba97: +case 0xbc90: +case 0xbc91: +case 0xbc92: +case 0xbc93: +case 0xbc94: +case 0xbc95: +case 0xbc96: +case 0xbc97: +case 0xbe90: +case 0xbe91: +case 0xbe92: +case 0xbe93: +case 0xbe94: +case 0xbe95: +case 0xbe96: +case 0xbe97: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x2010: +case 0x2011: +case 0x2012: +case 0x2013: +case 0x2014: +case 0x2015: +case 0x2016: +case 0x2017: +case 0x2210: +case 0x2211: +case 0x2212: +case 0x2213: +case 0x2214: +case 0x2215: +case 0x2216: +case 0x2217: +case 0x2410: +case 0x2411: +case 0x2412: +case 0x2413: +case 0x2414: +case 0x2415: +case 0x2416: +case 0x2417: +case 0x2610: +case 0x2611: +case 0x2612: +case 0x2613: +case 0x2614: +case 0x2615: +case 0x2616: +case 0x2617: +case 0x2810: +case 0x2811: +case 0x2812: +case 0x2813: +case 0x2814: +case 0x2815: +case 0x2816: +case 0x2817: +case 0x2a10: +case 0x2a11: +case 0x2a12: +case 0x2a13: +case 0x2a14: +case 0x2a15: +case 0x2a16: +case 0x2a17: +case 0x2c10: +case 0x2c11: +case 0x2c12: +case 0x2c13: +case 0x2c14: +case 0x2c15: +case 0x2c16: +case 0x2c17: +case 0x2e10: +case 0x2e11: +case 0x2e12: +case 0x2e13: +case 0x2e14: +case 0x2e15: +case 0x2e16: +case 0x2e17: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8090: +case 0x8091: +case 0x8092: +case 0x8093: +case 0x8094: +case 0x8095: +case 0x8096: +case 0x8097: +case 0x8290: +case 0x8291: +case 0x8292: +case 0x8293: +case 0x8294: +case 0x8295: +case 0x8296: +case 0x8297: +case 0x8490: +case 0x8491: +case 0x8492: +case 0x8493: +case 0x8494: +case 0x8495: +case 0x8496: +case 0x8497: +case 0x8690: +case 0x8691: +case 0x8692: +case 0x8693: +case 0x8694: +case 0x8695: +case 0x8696: +case 0x8697: +case 0x8890: +case 0x8891: +case 0x8892: +case 0x8893: +case 0x8894: +case 0x8895: +case 0x8896: +case 0x8897: +case 0x8a90: +case 0x8a91: +case 0x8a92: +case 0x8a93: +case 0x8a94: +case 0x8a95: +case 0x8a96: +case 0x8a97: +case 0x8c90: +case 0x8c91: +case 0x8c92: +case 0x8c93: +case 0x8c94: +case 0x8c95: +case 0x8c96: +case 0x8c97: +case 0x8e90: +case 0x8e91: +case 0x8e92: +case 0x8e93: +case 0x8e94: +case 0x8e95: +case 0x8e96: +case 0x8e97: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9090: +case 0x9091: +case 0x9092: +case 0x9093: +case 0x9094: +case 0x9095: +case 0x9096: +case 0x9097: +case 0x9290: +case 0x9291: +case 0x9292: +case 0x9293: +case 0x9294: +case 0x9295: +case 0x9296: +case 0x9297: +case 0x9490: +case 0x9491: +case 0x9492: +case 0x9493: +case 0x9494: +case 0x9495: +case 0x9496: +case 0x9497: +case 0x9690: +case 0x9691: +case 0x9692: +case 0x9693: +case 0x9694: +case 0x9695: +case 0x9696: +case 0x9697: +case 0x9890: +case 0x9891: +case 0x9892: +case 0x9893: +case 0x9894: +case 0x9895: +case 0x9896: +case 0x9897: +case 0x9a90: +case 0x9a91: +case 0x9a92: +case 0x9a93: +case 0x9a94: +case 0x9a95: +case 0x9a96: +case 0x9a97: +case 0x9c90: +case 0x9c91: +case 0x9c92: +case 0x9c93: +case 0x9c94: +case 0x9c95: +case 0x9c96: +case 0x9c97: +case 0x9e90: +case 0x9e91: +case 0x9e92: +case 0x9e93: +case 0x9e94: +case 0x9e95: +case 0x9e96: +case 0x9e97: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x2050: +case 0x2051: +case 0x2052: +case 0x2053: +case 0x2054: +case 0x2055: +case 0x2056: +case 0x2057: +case 0x2250: +case 0x2251: +case 0x2252: +case 0x2253: +case 0x2254: +case 0x2255: +case 0x2256: +case 0x2257: +case 0x2450: +case 0x2451: +case 0x2452: +case 0x2453: +case 0x2454: +case 0x2455: +case 0x2456: +case 0x2457: +case 0x2650: +case 0x2651: +case 0x2652: +case 0x2653: +case 0x2654: +case 0x2655: +case 0x2656: +case 0x2657: +case 0x2850: +case 0x2851: +case 0x2852: +case 0x2853: +case 0x2854: +case 0x2855: +case 0x2856: +case 0x2857: +case 0x2a50: +case 0x2a51: +case 0x2a52: +case 0x2a53: +case 0x2a54: +case 0x2a55: +case 0x2a56: +case 0x2a57: +case 0x2c50: +case 0x2c51: +case 0x2c52: +case 0x2c53: +case 0x2c54: +case 0x2c55: +case 0x2c56: +case 0x2c57: +case 0x2e50: +case 0x2e51: +case 0x2e52: +case 0x2e53: +case 0x2e54: +case 0x2e55: +case 0x2e56: +case 0x2e57: + { + HAM src(this, instr_b2_b0); MOVEA(src, instr_b11_b9); + } + break; + +case 0x42a8: +case 0x42a9: +case 0x42aa: +case 0x42ab: +case 0x42ac: +case 0x42ad: +case 0x42ae: +case 0x42af: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x44a8: +case 0x44a9: +case 0x44aa: +case 0x44ab: +case 0x44ac: +case 0x44ad: +case 0x44ae: +case 0x44af: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x40a8: +case 0x40a9: +case 0x40aa: +case 0x40ab: +case 0x40ac: +case 0x40ad: +case 0x40ae: +case 0x40af: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x46a8: +case 0x46a9: +case 0x46aa: +case 0x46ab: +case 0x46ac: +case 0x46ad: +case 0x46ae: +case 0x46af: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x4aa8: +case 0x4aa9: +case 0x4aaa: +case 0x4aab: +case 0x4aac: +case 0x4aad: +case 0x4aae: +case 0x4aaf: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0x23e8: +case 0x23e9: +case 0x23ea: +case 0x23eb: +case 0x23ec: +case 0x23ed: +case 0x23ee: +case 0x23ef: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x21e8: +case 0x21e9: +case 0x21ea: +case 0x21eb: +case 0x21ec: +case 0x21ed: +case 0x21ee: +case 0x21ef: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0xd1e8: +case 0xd1e9: +case 0xd1ea: +case 0xd1eb: +case 0xd1ec: +case 0xd1ed: +case 0xd1ee: +case 0xd1ef: +case 0xd3e8: +case 0xd3e9: +case 0xd3ea: +case 0xd3eb: +case 0xd3ec: +case 0xd3ed: +case 0xd3ee: +case 0xd3ef: +case 0xd5e8: +case 0xd5e9: +case 0xd5ea: +case 0xd5eb: +case 0xd5ec: +case 0xd5ed: +case 0xd5ee: +case 0xd5ef: +case 0xd7e8: +case 0xd7e9: +case 0xd7ea: +case 0xd7eb: +case 0xd7ec: +case 0xd7ed: +case 0xd7ee: +case 0xd7ef: +case 0xd9e8: +case 0xd9e9: +case 0xd9ea: +case 0xd9eb: +case 0xd9ec: +case 0xd9ed: +case 0xd9ee: +case 0xd9ef: +case 0xdbe8: +case 0xdbe9: +case 0xdbea: +case 0xdbeb: +case 0xdbec: +case 0xdbed: +case 0xdbee: +case 0xdbef: +case 0xdde8: +case 0xdde9: +case 0xddea: +case 0xddeb: +case 0xddec: +case 0xdded: +case 0xddee: +case 0xddef: +case 0xdfe8: +case 0xdfe9: +case 0xdfea: +case 0xdfeb: +case 0xdfec: +case 0xdfed: +case 0xdfee: +case 0xdfef: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb1e8: +case 0xb1e9: +case 0xb1ea: +case 0xb1eb: +case 0xb1ec: +case 0xb1ed: +case 0xb1ee: +case 0xb1ef: +case 0xb3e8: +case 0xb3e9: +case 0xb3ea: +case 0xb3eb: +case 0xb3ec: +case 0xb3ed: +case 0xb3ee: +case 0xb3ef: +case 0xb5e8: +case 0xb5e9: +case 0xb5ea: +case 0xb5eb: +case 0xb5ec: +case 0xb5ed: +case 0xb5ee: +case 0xb5ef: +case 0xb7e8: +case 0xb7e9: +case 0xb7ea: +case 0xb7eb: +case 0xb7ec: +case 0xb7ed: +case 0xb7ee: +case 0xb7ef: +case 0xb9e8: +case 0xb9e9: +case 0xb9ea: +case 0xb9eb: +case 0xb9ec: +case 0xb9ed: +case 0xb9ee: +case 0xb9ef: +case 0xbbe8: +case 0xbbe9: +case 0xbbea: +case 0xbbeb: +case 0xbbec: +case 0xbbed: +case 0xbbee: +case 0xbbef: +case 0xbde8: +case 0xbde9: +case 0xbdea: +case 0xbdeb: +case 0xbdec: +case 0xbded: +case 0xbdee: +case 0xbdef: +case 0xbfe8: +case 0xbfe9: +case 0xbfea: +case 0xbfeb: +case 0xbfec: +case 0xbfed: +case 0xbfee: +case 0xbfef: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x91e8: +case 0x91e9: +case 0x91ea: +case 0x91eb: +case 0x91ec: +case 0x91ed: +case 0x91ee: +case 0x91ef: +case 0x93e8: +case 0x93e9: +case 0x93ea: +case 0x93eb: +case 0x93ec: +case 0x93ed: +case 0x93ee: +case 0x93ef: +case 0x95e8: +case 0x95e9: +case 0x95ea: +case 0x95eb: +case 0x95ec: +case 0x95ed: +case 0x95ee: +case 0x95ef: +case 0x97e8: +case 0x97e9: +case 0x97ea: +case 0x97eb: +case 0x97ec: +case 0x97ed: +case 0x97ee: +case 0x97ef: +case 0x99e8: +case 0x99e9: +case 0x99ea: +case 0x99eb: +case 0x99ec: +case 0x99ed: +case 0x99ee: +case 0x99ef: +case 0x9be8: +case 0x9be9: +case 0x9bea: +case 0x9beb: +case 0x9bec: +case 0x9bed: +case 0x9bee: +case 0x9bef: +case 0x9de8: +case 0x9de9: +case 0x9dea: +case 0x9deb: +case 0x9dec: +case 0x9ded: +case 0x9dee: +case 0x9def: +case 0x9fe8: +case 0x9fe9: +case 0x9fea: +case 0x9feb: +case 0x9fec: +case 0x9fed: +case 0x9fee: +case 0x9fef: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x20a8: +case 0x20a9: +case 0x20aa: +case 0x20ab: +case 0x20ac: +case 0x20ad: +case 0x20ae: +case 0x20af: +case 0x22a8: +case 0x22a9: +case 0x22aa: +case 0x22ab: +case 0x22ac: +case 0x22ad: +case 0x22ae: +case 0x22af: +case 0x24a8: +case 0x24a9: +case 0x24aa: +case 0x24ab: +case 0x24ac: +case 0x24ad: +case 0x24ae: +case 0x24af: +case 0x26a8: +case 0x26a9: +case 0x26aa: +case 0x26ab: +case 0x26ac: +case 0x26ad: +case 0x26ae: +case 0x26af: +case 0x28a8: +case 0x28a9: +case 0x28aa: +case 0x28ab: +case 0x28ac: +case 0x28ad: +case 0x28ae: +case 0x28af: +case 0x2aa8: +case 0x2aa9: +case 0x2aaa: +case 0x2aab: +case 0x2aac: +case 0x2aad: +case 0x2aae: +case 0x2aaf: +case 0x2ca8: +case 0x2ca9: +case 0x2caa: +case 0x2cab: +case 0x2cac: +case 0x2cad: +case 0x2cae: +case 0x2caf: +case 0x2ea8: +case 0x2ea9: +case 0x2eaa: +case 0x2eab: +case 0x2eac: +case 0x2ead: +case 0x2eae: +case 0x2eaf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2168: +case 0x2169: +case 0x216a: +case 0x216b: +case 0x216c: +case 0x216d: +case 0x216e: +case 0x216f: +case 0x2368: +case 0x2369: +case 0x236a: +case 0x236b: +case 0x236c: +case 0x236d: +case 0x236e: +case 0x236f: +case 0x2568: +case 0x2569: +case 0x256a: +case 0x256b: +case 0x256c: +case 0x256d: +case 0x256e: +case 0x256f: +case 0x2768: +case 0x2769: +case 0x276a: +case 0x276b: +case 0x276c: +case 0x276d: +case 0x276e: +case 0x276f: +case 0x2968: +case 0x2969: +case 0x296a: +case 0x296b: +case 0x296c: +case 0x296d: +case 0x296e: +case 0x296f: +case 0x2b68: +case 0x2b69: +case 0x2b6a: +case 0x2b6b: +case 0x2b6c: +case 0x2b6d: +case 0x2b6e: +case 0x2b6f: +case 0x2d68: +case 0x2d69: +case 0x2d6a: +case 0x2d6b: +case 0x2d6c: +case 0x2d6d: +case 0x2d6e: +case 0x2d6f: +case 0x2f68: +case 0x2f69: +case 0x2f6a: +case 0x2f6b: +case 0x2f6c: +case 0x2f6d: +case 0x2f6e: +case 0x2f6f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x21a8: +case 0x21a9: +case 0x21aa: +case 0x21ab: +case 0x21ac: +case 0x21ad: +case 0x21ae: +case 0x21af: +case 0x23a8: +case 0x23a9: +case 0x23aa: +case 0x23ab: +case 0x23ac: +case 0x23ad: +case 0x23ae: +case 0x23af: +case 0x25a8: +case 0x25a9: +case 0x25aa: +case 0x25ab: +case 0x25ac: +case 0x25ad: +case 0x25ae: +case 0x25af: +case 0x27a8: +case 0x27a9: +case 0x27aa: +case 0x27ab: +case 0x27ac: +case 0x27ad: +case 0x27ae: +case 0x27af: +case 0x29a8: +case 0x29a9: +case 0x29aa: +case 0x29ab: +case 0x29ac: +case 0x29ad: +case 0x29ae: +case 0x29af: +case 0x2ba8: +case 0x2ba9: +case 0x2baa: +case 0x2bab: +case 0x2bac: +case 0x2bad: +case 0x2bae: +case 0x2baf: +case 0x2da8: +case 0x2da9: +case 0x2daa: +case 0x2dab: +case 0x2dac: +case 0x2dad: +case 0x2dae: +case 0x2daf: +case 0x2fa8: +case 0x2fa9: +case 0x2faa: +case 0x2fab: +case 0x2fac: +case 0x2fad: +case 0x2fae: +case 0x2faf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x20e8: +case 0x20e9: +case 0x20ea: +case 0x20eb: +case 0x20ec: +case 0x20ed: +case 0x20ee: +case 0x20ef: +case 0x22e8: +case 0x22e9: +case 0x22ea: +case 0x22eb: +case 0x22ec: +case 0x22ed: +case 0x22ee: +case 0x22ef: +case 0x24e8: +case 0x24e9: +case 0x24ea: +case 0x24eb: +case 0x24ec: +case 0x24ed: +case 0x24ee: +case 0x24ef: +case 0x26e8: +case 0x26e9: +case 0x26ea: +case 0x26eb: +case 0x26ec: +case 0x26ed: +case 0x26ee: +case 0x26ef: +case 0x28e8: +case 0x28e9: +case 0x28ea: +case 0x28eb: +case 0x28ec: +case 0x28ed: +case 0x28ee: +case 0x28ef: +case 0x2ae8: +case 0x2ae9: +case 0x2aea: +case 0x2aeb: +case 0x2aec: +case 0x2aed: +case 0x2aee: +case 0x2aef: +case 0x2ce8: +case 0x2ce9: +case 0x2cea: +case 0x2ceb: +case 0x2cec: +case 0x2ced: +case 0x2cee: +case 0x2cef: +case 0x2ee8: +case 0x2ee9: +case 0x2eea: +case 0x2eeb: +case 0x2eec: +case 0x2eed: +case 0x2eee: +case 0x2eef: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2128: +case 0x2129: +case 0x212a: +case 0x212b: +case 0x212c: +case 0x212d: +case 0x212e: +case 0x212f: +case 0x2328: +case 0x2329: +case 0x232a: +case 0x232b: +case 0x232c: +case 0x232d: +case 0x232e: +case 0x232f: +case 0x2528: +case 0x2529: +case 0x252a: +case 0x252b: +case 0x252c: +case 0x252d: +case 0x252e: +case 0x252f: +case 0x2728: +case 0x2729: +case 0x272a: +case 0x272b: +case 0x272c: +case 0x272d: +case 0x272e: +case 0x272f: +case 0x2928: +case 0x2929: +case 0x292a: +case 0x292b: +case 0x292c: +case 0x292d: +case 0x292e: +case 0x292f: +case 0x2b28: +case 0x2b29: +case 0x2b2a: +case 0x2b2b: +case 0x2b2c: +case 0x2b2d: +case 0x2b2e: +case 0x2b2f: +case 0x2d28: +case 0x2d29: +case 0x2d2a: +case 0x2d2b: +case 0x2d2c: +case 0x2d2d: +case 0x2d2e: +case 0x2d2f: +case 0x2f28: +case 0x2f29: +case 0x2f2a: +case 0x2f2b: +case 0x2f2c: +case 0x2f2d: +case 0x2f2e: +case 0x2f2f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd0a8: +case 0xd0a9: +case 0xd0aa: +case 0xd0ab: +case 0xd0ac: +case 0xd0ad: +case 0xd0ae: +case 0xd0af: +case 0xd2a8: +case 0xd2a9: +case 0xd2aa: +case 0xd2ab: +case 0xd2ac: +case 0xd2ad: +case 0xd2ae: +case 0xd2af: +case 0xd4a8: +case 0xd4a9: +case 0xd4aa: +case 0xd4ab: +case 0xd4ac: +case 0xd4ad: +case 0xd4ae: +case 0xd4af: +case 0xd6a8: +case 0xd6a9: +case 0xd6aa: +case 0xd6ab: +case 0xd6ac: +case 0xd6ad: +case 0xd6ae: +case 0xd6af: +case 0xd8a8: +case 0xd8a9: +case 0xd8aa: +case 0xd8ab: +case 0xd8ac: +case 0xd8ad: +case 0xd8ae: +case 0xd8af: +case 0xdaa8: +case 0xdaa9: +case 0xdaaa: +case 0xdaab: +case 0xdaac: +case 0xdaad: +case 0xdaae: +case 0xdaaf: +case 0xdca8: +case 0xdca9: +case 0xdcaa: +case 0xdcab: +case 0xdcac: +case 0xdcad: +case 0xdcae: +case 0xdcaf: +case 0xdea8: +case 0xdea9: +case 0xdeaa: +case 0xdeab: +case 0xdeac: +case 0xdead: +case 0xdeae: +case 0xdeaf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc0a8: +case 0xc0a9: +case 0xc0aa: +case 0xc0ab: +case 0xc0ac: +case 0xc0ad: +case 0xc0ae: +case 0xc0af: +case 0xc2a8: +case 0xc2a9: +case 0xc2aa: +case 0xc2ab: +case 0xc2ac: +case 0xc2ad: +case 0xc2ae: +case 0xc2af: +case 0xc4a8: +case 0xc4a9: +case 0xc4aa: +case 0xc4ab: +case 0xc4ac: +case 0xc4ad: +case 0xc4ae: +case 0xc4af: +case 0xc6a8: +case 0xc6a9: +case 0xc6aa: +case 0xc6ab: +case 0xc6ac: +case 0xc6ad: +case 0xc6ae: +case 0xc6af: +case 0xc8a8: +case 0xc8a9: +case 0xc8aa: +case 0xc8ab: +case 0xc8ac: +case 0xc8ad: +case 0xc8ae: +case 0xc8af: +case 0xcaa8: +case 0xcaa9: +case 0xcaaa: +case 0xcaab: +case 0xcaac: +case 0xcaad: +case 0xcaae: +case 0xcaaf: +case 0xcca8: +case 0xcca9: +case 0xccaa: +case 0xccab: +case 0xccac: +case 0xccad: +case 0xccae: +case 0xccaf: +case 0xcea8: +case 0xcea9: +case 0xceaa: +case 0xceab: +case 0xceac: +case 0xcead: +case 0xceae: +case 0xceaf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb0a8: +case 0xb0a9: +case 0xb0aa: +case 0xb0ab: +case 0xb0ac: +case 0xb0ad: +case 0xb0ae: +case 0xb0af: +case 0xb2a8: +case 0xb2a9: +case 0xb2aa: +case 0xb2ab: +case 0xb2ac: +case 0xb2ad: +case 0xb2ae: +case 0xb2af: +case 0xb4a8: +case 0xb4a9: +case 0xb4aa: +case 0xb4ab: +case 0xb4ac: +case 0xb4ad: +case 0xb4ae: +case 0xb4af: +case 0xb6a8: +case 0xb6a9: +case 0xb6aa: +case 0xb6ab: +case 0xb6ac: +case 0xb6ad: +case 0xb6ae: +case 0xb6af: +case 0xb8a8: +case 0xb8a9: +case 0xb8aa: +case 0xb8ab: +case 0xb8ac: +case 0xb8ad: +case 0xb8ae: +case 0xb8af: +case 0xbaa8: +case 0xbaa9: +case 0xbaaa: +case 0xbaab: +case 0xbaac: +case 0xbaad: +case 0xbaae: +case 0xbaaf: +case 0xbca8: +case 0xbca9: +case 0xbcaa: +case 0xbcab: +case 0xbcac: +case 0xbcad: +case 0xbcae: +case 0xbcaf: +case 0xbea8: +case 0xbea9: +case 0xbeaa: +case 0xbeab: +case 0xbeac: +case 0xbead: +case 0xbeae: +case 0xbeaf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x2028: +case 0x2029: +case 0x202a: +case 0x202b: +case 0x202c: +case 0x202d: +case 0x202e: +case 0x202f: +case 0x2228: +case 0x2229: +case 0x222a: +case 0x222b: +case 0x222c: +case 0x222d: +case 0x222e: +case 0x222f: +case 0x2428: +case 0x2429: +case 0x242a: +case 0x242b: +case 0x242c: +case 0x242d: +case 0x242e: +case 0x242f: +case 0x2628: +case 0x2629: +case 0x262a: +case 0x262b: +case 0x262c: +case 0x262d: +case 0x262e: +case 0x262f: +case 0x2828: +case 0x2829: +case 0x282a: +case 0x282b: +case 0x282c: +case 0x282d: +case 0x282e: +case 0x282f: +case 0x2a28: +case 0x2a29: +case 0x2a2a: +case 0x2a2b: +case 0x2a2c: +case 0x2a2d: +case 0x2a2e: +case 0x2a2f: +case 0x2c28: +case 0x2c29: +case 0x2c2a: +case 0x2c2b: +case 0x2c2c: +case 0x2c2d: +case 0x2c2e: +case 0x2c2f: +case 0x2e28: +case 0x2e29: +case 0x2e2a: +case 0x2e2b: +case 0x2e2c: +case 0x2e2d: +case 0x2e2e: +case 0x2e2f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x80a8: +case 0x80a9: +case 0x80aa: +case 0x80ab: +case 0x80ac: +case 0x80ad: +case 0x80ae: +case 0x80af: +case 0x82a8: +case 0x82a9: +case 0x82aa: +case 0x82ab: +case 0x82ac: +case 0x82ad: +case 0x82ae: +case 0x82af: +case 0x84a8: +case 0x84a9: +case 0x84aa: +case 0x84ab: +case 0x84ac: +case 0x84ad: +case 0x84ae: +case 0x84af: +case 0x86a8: +case 0x86a9: +case 0x86aa: +case 0x86ab: +case 0x86ac: +case 0x86ad: +case 0x86ae: +case 0x86af: +case 0x88a8: +case 0x88a9: +case 0x88aa: +case 0x88ab: +case 0x88ac: +case 0x88ad: +case 0x88ae: +case 0x88af: +case 0x8aa8: +case 0x8aa9: +case 0x8aaa: +case 0x8aab: +case 0x8aac: +case 0x8aad: +case 0x8aae: +case 0x8aaf: +case 0x8ca8: +case 0x8ca9: +case 0x8caa: +case 0x8cab: +case 0x8cac: +case 0x8cad: +case 0x8cae: +case 0x8caf: +case 0x8ea8: +case 0x8ea9: +case 0x8eaa: +case 0x8eab: +case 0x8eac: +case 0x8ead: +case 0x8eae: +case 0x8eaf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x90a8: +case 0x90a9: +case 0x90aa: +case 0x90ab: +case 0x90ac: +case 0x90ad: +case 0x90ae: +case 0x90af: +case 0x92a8: +case 0x92a9: +case 0x92aa: +case 0x92ab: +case 0x92ac: +case 0x92ad: +case 0x92ae: +case 0x92af: +case 0x94a8: +case 0x94a9: +case 0x94aa: +case 0x94ab: +case 0x94ac: +case 0x94ad: +case 0x94ae: +case 0x94af: +case 0x96a8: +case 0x96a9: +case 0x96aa: +case 0x96ab: +case 0x96ac: +case 0x96ad: +case 0x96ae: +case 0x96af: +case 0x98a8: +case 0x98a9: +case 0x98aa: +case 0x98ab: +case 0x98ac: +case 0x98ad: +case 0x98ae: +case 0x98af: +case 0x9aa8: +case 0x9aa9: +case 0x9aaa: +case 0x9aab: +case 0x9aac: +case 0x9aad: +case 0x9aae: +case 0x9aaf: +case 0x9ca8: +case 0x9ca9: +case 0x9caa: +case 0x9cab: +case 0x9cac: +case 0x9cad: +case 0x9cae: +case 0x9caf: +case 0x9ea8: +case 0x9ea9: +case 0x9eaa: +case 0x9eab: +case 0x9eac: +case 0x9ead: +case 0x9eae: +case 0x9eaf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x2068: +case 0x2069: +case 0x206a: +case 0x206b: +case 0x206c: +case 0x206d: +case 0x206e: +case 0x206f: +case 0x2268: +case 0x2269: +case 0x226a: +case 0x226b: +case 0x226c: +case 0x226d: +case 0x226e: +case 0x226f: +case 0x2468: +case 0x2469: +case 0x246a: +case 0x246b: +case 0x246c: +case 0x246d: +case 0x246e: +case 0x246f: +case 0x2668: +case 0x2669: +case 0x266a: +case 0x266b: +case 0x266c: +case 0x266d: +case 0x266e: +case 0x266f: +case 0x2868: +case 0x2869: +case 0x286a: +case 0x286b: +case 0x286c: +case 0x286d: +case 0x286e: +case 0x286f: +case 0x2a68: +case 0x2a69: +case 0x2a6a: +case 0x2a6b: +case 0x2a6c: +case 0x2a6d: +case 0x2a6e: +case 0x2a6f: +case 0x2c68: +case 0x2c69: +case 0x2c6a: +case 0x2c6b: +case 0x2c6c: +case 0x2c6d: +case 0x2c6e: +case 0x2c6f: +case 0x2e68: +case 0x2e69: +case 0x2e6a: +case 0x2e6b: +case 0x2e6c: +case 0x2e6d: +case 0x2e6e: +case 0x2e6f: + { + HAM src(this, instr_b2_b0); MOVEA(src, instr_b11_b9); + } + break; + +case 0x42b0: +case 0x42b1: +case 0x42b2: +case 0x42b3: +case 0x42b4: +case 0x42b5: +case 0x42b6: +case 0x42b7: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x44b0: +case 0x44b1: +case 0x44b2: +case 0x44b3: +case 0x44b4: +case 0x44b5: +case 0x44b6: +case 0x44b7: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x40b0: +case 0x40b1: +case 0x40b2: +case 0x40b3: +case 0x40b4: +case 0x40b5: +case 0x40b6: +case 0x40b7: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x46b0: +case 0x46b1: +case 0x46b2: +case 0x46b3: +case 0x46b4: +case 0x46b5: +case 0x46b6: +case 0x46b7: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x4ab0: +case 0x4ab1: +case 0x4ab2: +case 0x4ab3: +case 0x4ab4: +case 0x4ab5: +case 0x4ab6: +case 0x4ab7: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0x23f0: +case 0x23f1: +case 0x23f2: +case 0x23f3: +case 0x23f4: +case 0x23f5: +case 0x23f6: +case 0x23f7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x21f0: +case 0x21f1: +case 0x21f2: +case 0x21f3: +case 0x21f4: +case 0x21f5: +case 0x21f6: +case 0x21f7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0xd1f0: +case 0xd1f1: +case 0xd1f2: +case 0xd1f3: +case 0xd1f4: +case 0xd1f5: +case 0xd1f6: +case 0xd1f7: +case 0xd3f0: +case 0xd3f1: +case 0xd3f2: +case 0xd3f3: +case 0xd3f4: +case 0xd3f5: +case 0xd3f6: +case 0xd3f7: +case 0xd5f0: +case 0xd5f1: +case 0xd5f2: +case 0xd5f3: +case 0xd5f4: +case 0xd5f5: +case 0xd5f6: +case 0xd5f7: +case 0xd7f0: +case 0xd7f1: +case 0xd7f2: +case 0xd7f3: +case 0xd7f4: +case 0xd7f5: +case 0xd7f6: +case 0xd7f7: +case 0xd9f0: +case 0xd9f1: +case 0xd9f2: +case 0xd9f3: +case 0xd9f4: +case 0xd9f5: +case 0xd9f6: +case 0xd9f7: +case 0xdbf0: +case 0xdbf1: +case 0xdbf2: +case 0xdbf3: +case 0xdbf4: +case 0xdbf5: +case 0xdbf6: +case 0xdbf7: +case 0xddf0: +case 0xddf1: +case 0xddf2: +case 0xddf3: +case 0xddf4: +case 0xddf5: +case 0xddf6: +case 0xddf7: +case 0xdff0: +case 0xdff1: +case 0xdff2: +case 0xdff3: +case 0xdff4: +case 0xdff5: +case 0xdff6: +case 0xdff7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb1f0: +case 0xb1f1: +case 0xb1f2: +case 0xb1f3: +case 0xb1f4: +case 0xb1f5: +case 0xb1f6: +case 0xb1f7: +case 0xb3f0: +case 0xb3f1: +case 0xb3f2: +case 0xb3f3: +case 0xb3f4: +case 0xb3f5: +case 0xb3f6: +case 0xb3f7: +case 0xb5f0: +case 0xb5f1: +case 0xb5f2: +case 0xb5f3: +case 0xb5f4: +case 0xb5f5: +case 0xb5f6: +case 0xb5f7: +case 0xb7f0: +case 0xb7f1: +case 0xb7f2: +case 0xb7f3: +case 0xb7f4: +case 0xb7f5: +case 0xb7f6: +case 0xb7f7: +case 0xb9f0: +case 0xb9f1: +case 0xb9f2: +case 0xb9f3: +case 0xb9f4: +case 0xb9f5: +case 0xb9f6: +case 0xb9f7: +case 0xbbf0: +case 0xbbf1: +case 0xbbf2: +case 0xbbf3: +case 0xbbf4: +case 0xbbf5: +case 0xbbf6: +case 0xbbf7: +case 0xbdf0: +case 0xbdf1: +case 0xbdf2: +case 0xbdf3: +case 0xbdf4: +case 0xbdf5: +case 0xbdf6: +case 0xbdf7: +case 0xbff0: +case 0xbff1: +case 0xbff2: +case 0xbff3: +case 0xbff4: +case 0xbff5: +case 0xbff6: +case 0xbff7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x91f0: +case 0x91f1: +case 0x91f2: +case 0x91f3: +case 0x91f4: +case 0x91f5: +case 0x91f6: +case 0x91f7: +case 0x93f0: +case 0x93f1: +case 0x93f2: +case 0x93f3: +case 0x93f4: +case 0x93f5: +case 0x93f6: +case 0x93f7: +case 0x95f0: +case 0x95f1: +case 0x95f2: +case 0x95f3: +case 0x95f4: +case 0x95f5: +case 0x95f6: +case 0x95f7: +case 0x97f0: +case 0x97f1: +case 0x97f2: +case 0x97f3: +case 0x97f4: +case 0x97f5: +case 0x97f6: +case 0x97f7: +case 0x99f0: +case 0x99f1: +case 0x99f2: +case 0x99f3: +case 0x99f4: +case 0x99f5: +case 0x99f6: +case 0x99f7: +case 0x9bf0: +case 0x9bf1: +case 0x9bf2: +case 0x9bf3: +case 0x9bf4: +case 0x9bf5: +case 0x9bf6: +case 0x9bf7: +case 0x9df0: +case 0x9df1: +case 0x9df2: +case 0x9df3: +case 0x9df4: +case 0x9df5: +case 0x9df6: +case 0x9df7: +case 0x9ff0: +case 0x9ff1: +case 0x9ff2: +case 0x9ff3: +case 0x9ff4: +case 0x9ff5: +case 0x9ff6: +case 0x9ff7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x20b0: +case 0x20b1: +case 0x20b2: +case 0x20b3: +case 0x20b4: +case 0x20b5: +case 0x20b6: +case 0x20b7: +case 0x22b0: +case 0x22b1: +case 0x22b2: +case 0x22b3: +case 0x22b4: +case 0x22b5: +case 0x22b6: +case 0x22b7: +case 0x24b0: +case 0x24b1: +case 0x24b2: +case 0x24b3: +case 0x24b4: +case 0x24b5: +case 0x24b6: +case 0x24b7: +case 0x26b0: +case 0x26b1: +case 0x26b2: +case 0x26b3: +case 0x26b4: +case 0x26b5: +case 0x26b6: +case 0x26b7: +case 0x28b0: +case 0x28b1: +case 0x28b2: +case 0x28b3: +case 0x28b4: +case 0x28b5: +case 0x28b6: +case 0x28b7: +case 0x2ab0: +case 0x2ab1: +case 0x2ab2: +case 0x2ab3: +case 0x2ab4: +case 0x2ab5: +case 0x2ab6: +case 0x2ab7: +case 0x2cb0: +case 0x2cb1: +case 0x2cb2: +case 0x2cb3: +case 0x2cb4: +case 0x2cb5: +case 0x2cb6: +case 0x2cb7: +case 0x2eb0: +case 0x2eb1: +case 0x2eb2: +case 0x2eb3: +case 0x2eb4: +case 0x2eb5: +case 0x2eb6: +case 0x2eb7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2170: +case 0x2171: +case 0x2172: +case 0x2173: +case 0x2174: +case 0x2175: +case 0x2176: +case 0x2177: +case 0x2370: +case 0x2371: +case 0x2372: +case 0x2373: +case 0x2374: +case 0x2375: +case 0x2376: +case 0x2377: +case 0x2570: +case 0x2571: +case 0x2572: +case 0x2573: +case 0x2574: +case 0x2575: +case 0x2576: +case 0x2577: +case 0x2770: +case 0x2771: +case 0x2772: +case 0x2773: +case 0x2774: +case 0x2775: +case 0x2776: +case 0x2777: +case 0x2970: +case 0x2971: +case 0x2972: +case 0x2973: +case 0x2974: +case 0x2975: +case 0x2976: +case 0x2977: +case 0x2b70: +case 0x2b71: +case 0x2b72: +case 0x2b73: +case 0x2b74: +case 0x2b75: +case 0x2b76: +case 0x2b77: +case 0x2d70: +case 0x2d71: +case 0x2d72: +case 0x2d73: +case 0x2d74: +case 0x2d75: +case 0x2d76: +case 0x2d77: +case 0x2f70: +case 0x2f71: +case 0x2f72: +case 0x2f73: +case 0x2f74: +case 0x2f75: +case 0x2f76: +case 0x2f77: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x21b0: +case 0x21b1: +case 0x21b2: +case 0x21b3: +case 0x21b4: +case 0x21b5: +case 0x21b6: +case 0x21b7: +case 0x23b0: +case 0x23b1: +case 0x23b2: +case 0x23b3: +case 0x23b4: +case 0x23b5: +case 0x23b6: +case 0x23b7: +case 0x25b0: +case 0x25b1: +case 0x25b2: +case 0x25b3: +case 0x25b4: +case 0x25b5: +case 0x25b6: +case 0x25b7: +case 0x27b0: +case 0x27b1: +case 0x27b2: +case 0x27b3: +case 0x27b4: +case 0x27b5: +case 0x27b6: +case 0x27b7: +case 0x29b0: +case 0x29b1: +case 0x29b2: +case 0x29b3: +case 0x29b4: +case 0x29b5: +case 0x29b6: +case 0x29b7: +case 0x2bb0: +case 0x2bb1: +case 0x2bb2: +case 0x2bb3: +case 0x2bb4: +case 0x2bb5: +case 0x2bb6: +case 0x2bb7: +case 0x2db0: +case 0x2db1: +case 0x2db2: +case 0x2db3: +case 0x2db4: +case 0x2db5: +case 0x2db6: +case 0x2db7: +case 0x2fb0: +case 0x2fb1: +case 0x2fb2: +case 0x2fb3: +case 0x2fb4: +case 0x2fb5: +case 0x2fb6: +case 0x2fb7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x20f0: +case 0x20f1: +case 0x20f2: +case 0x20f3: +case 0x20f4: +case 0x20f5: +case 0x20f6: +case 0x20f7: +case 0x22f0: +case 0x22f1: +case 0x22f2: +case 0x22f3: +case 0x22f4: +case 0x22f5: +case 0x22f6: +case 0x22f7: +case 0x24f0: +case 0x24f1: +case 0x24f2: +case 0x24f3: +case 0x24f4: +case 0x24f5: +case 0x24f6: +case 0x24f7: +case 0x26f0: +case 0x26f1: +case 0x26f2: +case 0x26f3: +case 0x26f4: +case 0x26f5: +case 0x26f6: +case 0x26f7: +case 0x28f0: +case 0x28f1: +case 0x28f2: +case 0x28f3: +case 0x28f4: +case 0x28f5: +case 0x28f6: +case 0x28f7: +case 0x2af0: +case 0x2af1: +case 0x2af2: +case 0x2af3: +case 0x2af4: +case 0x2af5: +case 0x2af6: +case 0x2af7: +case 0x2cf0: +case 0x2cf1: +case 0x2cf2: +case 0x2cf3: +case 0x2cf4: +case 0x2cf5: +case 0x2cf6: +case 0x2cf7: +case 0x2ef0: +case 0x2ef1: +case 0x2ef2: +case 0x2ef3: +case 0x2ef4: +case 0x2ef5: +case 0x2ef6: +case 0x2ef7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2130: +case 0x2131: +case 0x2132: +case 0x2133: +case 0x2134: +case 0x2135: +case 0x2136: +case 0x2137: +case 0x2330: +case 0x2331: +case 0x2332: +case 0x2333: +case 0x2334: +case 0x2335: +case 0x2336: +case 0x2337: +case 0x2530: +case 0x2531: +case 0x2532: +case 0x2533: +case 0x2534: +case 0x2535: +case 0x2536: +case 0x2537: +case 0x2730: +case 0x2731: +case 0x2732: +case 0x2733: +case 0x2734: +case 0x2735: +case 0x2736: +case 0x2737: +case 0x2930: +case 0x2931: +case 0x2932: +case 0x2933: +case 0x2934: +case 0x2935: +case 0x2936: +case 0x2937: +case 0x2b30: +case 0x2b31: +case 0x2b32: +case 0x2b33: +case 0x2b34: +case 0x2b35: +case 0x2b36: +case 0x2b37: +case 0x2d30: +case 0x2d31: +case 0x2d32: +case 0x2d33: +case 0x2d34: +case 0x2d35: +case 0x2d36: +case 0x2d37: +case 0x2f30: +case 0x2f31: +case 0x2f32: +case 0x2f33: +case 0x2f34: +case 0x2f35: +case 0x2f36: +case 0x2f37: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd0b0: +case 0xd0b1: +case 0xd0b2: +case 0xd0b3: +case 0xd0b4: +case 0xd0b5: +case 0xd0b6: +case 0xd0b7: +case 0xd2b0: +case 0xd2b1: +case 0xd2b2: +case 0xd2b3: +case 0xd2b4: +case 0xd2b5: +case 0xd2b6: +case 0xd2b7: +case 0xd4b0: +case 0xd4b1: +case 0xd4b2: +case 0xd4b3: +case 0xd4b4: +case 0xd4b5: +case 0xd4b6: +case 0xd4b7: +case 0xd6b0: +case 0xd6b1: +case 0xd6b2: +case 0xd6b3: +case 0xd6b4: +case 0xd6b5: +case 0xd6b6: +case 0xd6b7: +case 0xd8b0: +case 0xd8b1: +case 0xd8b2: +case 0xd8b3: +case 0xd8b4: +case 0xd8b5: +case 0xd8b6: +case 0xd8b7: +case 0xdab0: +case 0xdab1: +case 0xdab2: +case 0xdab3: +case 0xdab4: +case 0xdab5: +case 0xdab6: +case 0xdab7: +case 0xdcb0: +case 0xdcb1: +case 0xdcb2: +case 0xdcb3: +case 0xdcb4: +case 0xdcb5: +case 0xdcb6: +case 0xdcb7: +case 0xdeb0: +case 0xdeb1: +case 0xdeb2: +case 0xdeb3: +case 0xdeb4: +case 0xdeb5: +case 0xdeb6: +case 0xdeb7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc0b0: +case 0xc0b1: +case 0xc0b2: +case 0xc0b3: +case 0xc0b4: +case 0xc0b5: +case 0xc0b6: +case 0xc0b7: +case 0xc2b0: +case 0xc2b1: +case 0xc2b2: +case 0xc2b3: +case 0xc2b4: +case 0xc2b5: +case 0xc2b6: +case 0xc2b7: +case 0xc4b0: +case 0xc4b1: +case 0xc4b2: +case 0xc4b3: +case 0xc4b4: +case 0xc4b5: +case 0xc4b6: +case 0xc4b7: +case 0xc6b0: +case 0xc6b1: +case 0xc6b2: +case 0xc6b3: +case 0xc6b4: +case 0xc6b5: +case 0xc6b6: +case 0xc6b7: +case 0xc8b0: +case 0xc8b1: +case 0xc8b2: +case 0xc8b3: +case 0xc8b4: +case 0xc8b5: +case 0xc8b6: +case 0xc8b7: +case 0xcab0: +case 0xcab1: +case 0xcab2: +case 0xcab3: +case 0xcab4: +case 0xcab5: +case 0xcab6: +case 0xcab7: +case 0xccb0: +case 0xccb1: +case 0xccb2: +case 0xccb3: +case 0xccb4: +case 0xccb5: +case 0xccb6: +case 0xccb7: +case 0xceb0: +case 0xceb1: +case 0xceb2: +case 0xceb3: +case 0xceb4: +case 0xceb5: +case 0xceb6: +case 0xceb7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb0b0: +case 0xb0b1: +case 0xb0b2: +case 0xb0b3: +case 0xb0b4: +case 0xb0b5: +case 0xb0b6: +case 0xb0b7: +case 0xb2b0: +case 0xb2b1: +case 0xb2b2: +case 0xb2b3: +case 0xb2b4: +case 0xb2b5: +case 0xb2b6: +case 0xb2b7: +case 0xb4b0: +case 0xb4b1: +case 0xb4b2: +case 0xb4b3: +case 0xb4b4: +case 0xb4b5: +case 0xb4b6: +case 0xb4b7: +case 0xb6b0: +case 0xb6b1: +case 0xb6b2: +case 0xb6b3: +case 0xb6b4: +case 0xb6b5: +case 0xb6b6: +case 0xb6b7: +case 0xb8b0: +case 0xb8b1: +case 0xb8b2: +case 0xb8b3: +case 0xb8b4: +case 0xb8b5: +case 0xb8b6: +case 0xb8b7: +case 0xbab0: +case 0xbab1: +case 0xbab2: +case 0xbab3: +case 0xbab4: +case 0xbab5: +case 0xbab6: +case 0xbab7: +case 0xbcb0: +case 0xbcb1: +case 0xbcb2: +case 0xbcb3: +case 0xbcb4: +case 0xbcb5: +case 0xbcb6: +case 0xbcb7: +case 0xbeb0: +case 0xbeb1: +case 0xbeb2: +case 0xbeb3: +case 0xbeb4: +case 0xbeb5: +case 0xbeb6: +case 0xbeb7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x2030: +case 0x2031: +case 0x2032: +case 0x2033: +case 0x2034: +case 0x2035: +case 0x2036: +case 0x2037: +case 0x2230: +case 0x2231: +case 0x2232: +case 0x2233: +case 0x2234: +case 0x2235: +case 0x2236: +case 0x2237: +case 0x2430: +case 0x2431: +case 0x2432: +case 0x2433: +case 0x2434: +case 0x2435: +case 0x2436: +case 0x2437: +case 0x2630: +case 0x2631: +case 0x2632: +case 0x2633: +case 0x2634: +case 0x2635: +case 0x2636: +case 0x2637: +case 0x2830: +case 0x2831: +case 0x2832: +case 0x2833: +case 0x2834: +case 0x2835: +case 0x2836: +case 0x2837: +case 0x2a30: +case 0x2a31: +case 0x2a32: +case 0x2a33: +case 0x2a34: +case 0x2a35: +case 0x2a36: +case 0x2a37: +case 0x2c30: +case 0x2c31: +case 0x2c32: +case 0x2c33: +case 0x2c34: +case 0x2c35: +case 0x2c36: +case 0x2c37: +case 0x2e30: +case 0x2e31: +case 0x2e32: +case 0x2e33: +case 0x2e34: +case 0x2e35: +case 0x2e36: +case 0x2e37: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x80b0: +case 0x80b1: +case 0x80b2: +case 0x80b3: +case 0x80b4: +case 0x80b5: +case 0x80b6: +case 0x80b7: +case 0x82b0: +case 0x82b1: +case 0x82b2: +case 0x82b3: +case 0x82b4: +case 0x82b5: +case 0x82b6: +case 0x82b7: +case 0x84b0: +case 0x84b1: +case 0x84b2: +case 0x84b3: +case 0x84b4: +case 0x84b5: +case 0x84b6: +case 0x84b7: +case 0x86b0: +case 0x86b1: +case 0x86b2: +case 0x86b3: +case 0x86b4: +case 0x86b5: +case 0x86b6: +case 0x86b7: +case 0x88b0: +case 0x88b1: +case 0x88b2: +case 0x88b3: +case 0x88b4: +case 0x88b5: +case 0x88b6: +case 0x88b7: +case 0x8ab0: +case 0x8ab1: +case 0x8ab2: +case 0x8ab3: +case 0x8ab4: +case 0x8ab5: +case 0x8ab6: +case 0x8ab7: +case 0x8cb0: +case 0x8cb1: +case 0x8cb2: +case 0x8cb3: +case 0x8cb4: +case 0x8cb5: +case 0x8cb6: +case 0x8cb7: +case 0x8eb0: +case 0x8eb1: +case 0x8eb2: +case 0x8eb3: +case 0x8eb4: +case 0x8eb5: +case 0x8eb6: +case 0x8eb7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x90b0: +case 0x90b1: +case 0x90b2: +case 0x90b3: +case 0x90b4: +case 0x90b5: +case 0x90b6: +case 0x90b7: +case 0x92b0: +case 0x92b1: +case 0x92b2: +case 0x92b3: +case 0x92b4: +case 0x92b5: +case 0x92b6: +case 0x92b7: +case 0x94b0: +case 0x94b1: +case 0x94b2: +case 0x94b3: +case 0x94b4: +case 0x94b5: +case 0x94b6: +case 0x94b7: +case 0x96b0: +case 0x96b1: +case 0x96b2: +case 0x96b3: +case 0x96b4: +case 0x96b5: +case 0x96b6: +case 0x96b7: +case 0x98b0: +case 0x98b1: +case 0x98b2: +case 0x98b3: +case 0x98b4: +case 0x98b5: +case 0x98b6: +case 0x98b7: +case 0x9ab0: +case 0x9ab1: +case 0x9ab2: +case 0x9ab3: +case 0x9ab4: +case 0x9ab5: +case 0x9ab6: +case 0x9ab7: +case 0x9cb0: +case 0x9cb1: +case 0x9cb2: +case 0x9cb3: +case 0x9cb4: +case 0x9cb5: +case 0x9cb6: +case 0x9cb7: +case 0x9eb0: +case 0x9eb1: +case 0x9eb2: +case 0x9eb3: +case 0x9eb4: +case 0x9eb5: +case 0x9eb6: +case 0x9eb7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x2070: +case 0x2071: +case 0x2072: +case 0x2073: +case 0x2074: +case 0x2075: +case 0x2076: +case 0x2077: +case 0x2270: +case 0x2271: +case 0x2272: +case 0x2273: +case 0x2274: +case 0x2275: +case 0x2276: +case 0x2277: +case 0x2470: +case 0x2471: +case 0x2472: +case 0x2473: +case 0x2474: +case 0x2475: +case 0x2476: +case 0x2477: +case 0x2670: +case 0x2671: +case 0x2672: +case 0x2673: +case 0x2674: +case 0x2675: +case 0x2676: +case 0x2677: +case 0x2870: +case 0x2871: +case 0x2872: +case 0x2873: +case 0x2874: +case 0x2875: +case 0x2876: +case 0x2877: +case 0x2a70: +case 0x2a71: +case 0x2a72: +case 0x2a73: +case 0x2a74: +case 0x2a75: +case 0x2a76: +case 0x2a77: +case 0x2c70: +case 0x2c71: +case 0x2c72: +case 0x2c73: +case 0x2c74: +case 0x2c75: +case 0x2c76: +case 0x2c77: +case 0x2e70: +case 0x2e71: +case 0x2e72: +case 0x2e73: +case 0x2e74: +case 0x2e75: +case 0x2e76: +case 0x2e77: + { + HAM src(this, instr_b2_b0); MOVEA(src, instr_b11_b9); + } + break; + +case 0x4298: +case 0x4299: +case 0x429a: +case 0x429b: +case 0x429c: +case 0x429d: +case 0x429e: +case 0x429f: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x4498: +case 0x4499: +case 0x449a: +case 0x449b: +case 0x449c: +case 0x449d: +case 0x449e: +case 0x449f: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x4098: +case 0x4099: +case 0x409a: +case 0x409b: +case 0x409c: +case 0x409d: +case 0x409e: +case 0x409f: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x4698: +case 0x4699: +case 0x469a: +case 0x469b: +case 0x469c: +case 0x469d: +case 0x469e: +case 0x469f: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x4a98: +case 0x4a99: +case 0x4a9a: +case 0x4a9b: +case 0x4a9c: +case 0x4a9d: +case 0x4a9e: +case 0x4a9f: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0x23d8: +case 0x23d9: +case 0x23da: +case 0x23db: +case 0x23dc: +case 0x23dd: +case 0x23de: +case 0x23df: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x21d8: +case 0x21d9: +case 0x21da: +case 0x21db: +case 0x21dc: +case 0x21dd: +case 0x21de: +case 0x21df: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0xd1d8: +case 0xd1d9: +case 0xd1da: +case 0xd1db: +case 0xd1dc: +case 0xd1dd: +case 0xd1de: +case 0xd1df: +case 0xd3d8: +case 0xd3d9: +case 0xd3da: +case 0xd3db: +case 0xd3dc: +case 0xd3dd: +case 0xd3de: +case 0xd3df: +case 0xd5d8: +case 0xd5d9: +case 0xd5da: +case 0xd5db: +case 0xd5dc: +case 0xd5dd: +case 0xd5de: +case 0xd5df: +case 0xd7d8: +case 0xd7d9: +case 0xd7da: +case 0xd7db: +case 0xd7dc: +case 0xd7dd: +case 0xd7de: +case 0xd7df: +case 0xd9d8: +case 0xd9d9: +case 0xd9da: +case 0xd9db: +case 0xd9dc: +case 0xd9dd: +case 0xd9de: +case 0xd9df: +case 0xdbd8: +case 0xdbd9: +case 0xdbda: +case 0xdbdb: +case 0xdbdc: +case 0xdbdd: +case 0xdbde: +case 0xdbdf: +case 0xddd8: +case 0xddd9: +case 0xddda: +case 0xdddb: +case 0xdddc: +case 0xdddd: +case 0xddde: +case 0xdddf: +case 0xdfd8: +case 0xdfd9: +case 0xdfda: +case 0xdfdb: +case 0xdfdc: +case 0xdfdd: +case 0xdfde: +case 0xdfdf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb1d8: +case 0xb1d9: +case 0xb1da: +case 0xb1db: +case 0xb1dc: +case 0xb1dd: +case 0xb1de: +case 0xb1df: +case 0xb3d8: +case 0xb3d9: +case 0xb3da: +case 0xb3db: +case 0xb3dc: +case 0xb3dd: +case 0xb3de: +case 0xb3df: +case 0xb5d8: +case 0xb5d9: +case 0xb5da: +case 0xb5db: +case 0xb5dc: +case 0xb5dd: +case 0xb5de: +case 0xb5df: +case 0xb7d8: +case 0xb7d9: +case 0xb7da: +case 0xb7db: +case 0xb7dc: +case 0xb7dd: +case 0xb7de: +case 0xb7df: +case 0xb9d8: +case 0xb9d9: +case 0xb9da: +case 0xb9db: +case 0xb9dc: +case 0xb9dd: +case 0xb9de: +case 0xb9df: +case 0xbbd8: +case 0xbbd9: +case 0xbbda: +case 0xbbdb: +case 0xbbdc: +case 0xbbdd: +case 0xbbde: +case 0xbbdf: +case 0xbdd8: +case 0xbdd9: +case 0xbdda: +case 0xbddb: +case 0xbddc: +case 0xbddd: +case 0xbdde: +case 0xbddf: +case 0xbfd8: +case 0xbfd9: +case 0xbfda: +case 0xbfdb: +case 0xbfdc: +case 0xbfdd: +case 0xbfde: +case 0xbfdf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x91d8: +case 0x91d9: +case 0x91da: +case 0x91db: +case 0x91dc: +case 0x91dd: +case 0x91de: +case 0x91df: +case 0x93d8: +case 0x93d9: +case 0x93da: +case 0x93db: +case 0x93dc: +case 0x93dd: +case 0x93de: +case 0x93df: +case 0x95d8: +case 0x95d9: +case 0x95da: +case 0x95db: +case 0x95dc: +case 0x95dd: +case 0x95de: +case 0x95df: +case 0x97d8: +case 0x97d9: +case 0x97da: +case 0x97db: +case 0x97dc: +case 0x97dd: +case 0x97de: +case 0x97df: +case 0x99d8: +case 0x99d9: +case 0x99da: +case 0x99db: +case 0x99dc: +case 0x99dd: +case 0x99de: +case 0x99df: +case 0x9bd8: +case 0x9bd9: +case 0x9bda: +case 0x9bdb: +case 0x9bdc: +case 0x9bdd: +case 0x9bde: +case 0x9bdf: +case 0x9dd8: +case 0x9dd9: +case 0x9dda: +case 0x9ddb: +case 0x9ddc: +case 0x9ddd: +case 0x9dde: +case 0x9ddf: +case 0x9fd8: +case 0x9fd9: +case 0x9fda: +case 0x9fdb: +case 0x9fdc: +case 0x9fdd: +case 0x9fde: +case 0x9fdf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x2098: +case 0x2099: +case 0x209a: +case 0x209b: +case 0x209c: +case 0x209d: +case 0x209e: +case 0x209f: +case 0x2298: +case 0x2299: +case 0x229a: +case 0x229b: +case 0x229c: +case 0x229d: +case 0x229e: +case 0x229f: +case 0x2498: +case 0x2499: +case 0x249a: +case 0x249b: +case 0x249c: +case 0x249d: +case 0x249e: +case 0x249f: +case 0x2698: +case 0x2699: +case 0x269a: +case 0x269b: +case 0x269c: +case 0x269d: +case 0x269e: +case 0x269f: +case 0x2898: +case 0x2899: +case 0x289a: +case 0x289b: +case 0x289c: +case 0x289d: +case 0x289e: +case 0x289f: +case 0x2a98: +case 0x2a99: +case 0x2a9a: +case 0x2a9b: +case 0x2a9c: +case 0x2a9d: +case 0x2a9e: +case 0x2a9f: +case 0x2c98: +case 0x2c99: +case 0x2c9a: +case 0x2c9b: +case 0x2c9c: +case 0x2c9d: +case 0x2c9e: +case 0x2c9f: +case 0x2e98: +case 0x2e99: +case 0x2e9a: +case 0x2e9b: +case 0x2e9c: +case 0x2e9d: +case 0x2e9e: +case 0x2e9f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2158: +case 0x2159: +case 0x215a: +case 0x215b: +case 0x215c: +case 0x215d: +case 0x215e: +case 0x215f: +case 0x2358: +case 0x2359: +case 0x235a: +case 0x235b: +case 0x235c: +case 0x235d: +case 0x235e: +case 0x235f: +case 0x2558: +case 0x2559: +case 0x255a: +case 0x255b: +case 0x255c: +case 0x255d: +case 0x255e: +case 0x255f: +case 0x2758: +case 0x2759: +case 0x275a: +case 0x275b: +case 0x275c: +case 0x275d: +case 0x275e: +case 0x275f: +case 0x2958: +case 0x2959: +case 0x295a: +case 0x295b: +case 0x295c: +case 0x295d: +case 0x295e: +case 0x295f: +case 0x2b58: +case 0x2b59: +case 0x2b5a: +case 0x2b5b: +case 0x2b5c: +case 0x2b5d: +case 0x2b5e: +case 0x2b5f: +case 0x2d58: +case 0x2d59: +case 0x2d5a: +case 0x2d5b: +case 0x2d5c: +case 0x2d5d: +case 0x2d5e: +case 0x2d5f: +case 0x2f58: +case 0x2f59: +case 0x2f5a: +case 0x2f5b: +case 0x2f5c: +case 0x2f5d: +case 0x2f5e: +case 0x2f5f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2198: +case 0x2199: +case 0x219a: +case 0x219b: +case 0x219c: +case 0x219d: +case 0x219e: +case 0x219f: +case 0x2398: +case 0x2399: +case 0x239a: +case 0x239b: +case 0x239c: +case 0x239d: +case 0x239e: +case 0x239f: +case 0x2598: +case 0x2599: +case 0x259a: +case 0x259b: +case 0x259c: +case 0x259d: +case 0x259e: +case 0x259f: +case 0x2798: +case 0x2799: +case 0x279a: +case 0x279b: +case 0x279c: +case 0x279d: +case 0x279e: +case 0x279f: +case 0x2998: +case 0x2999: +case 0x299a: +case 0x299b: +case 0x299c: +case 0x299d: +case 0x299e: +case 0x299f: +case 0x2b98: +case 0x2b99: +case 0x2b9a: +case 0x2b9b: +case 0x2b9c: +case 0x2b9d: +case 0x2b9e: +case 0x2b9f: +case 0x2d98: +case 0x2d99: +case 0x2d9a: +case 0x2d9b: +case 0x2d9c: +case 0x2d9d: +case 0x2d9e: +case 0x2d9f: +case 0x2f98: +case 0x2f99: +case 0x2f9a: +case 0x2f9b: +case 0x2f9c: +case 0x2f9d: +case 0x2f9e: +case 0x2f9f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xb188: +case 0xb189: +case 0xb18a: +case 0xb18b: +case 0xb18c: +case 0xb18d: +case 0xb18e: +case 0xb18f: +case 0xb388: +case 0xb389: +case 0xb38a: +case 0xb38b: +case 0xb38c: +case 0xb38d: +case 0xb38e: +case 0xb38f: +case 0xb588: +case 0xb589: +case 0xb58a: +case 0xb58b: +case 0xb58c: +case 0xb58d: +case 0xb58e: +case 0xb58f: +case 0xb788: +case 0xb789: +case 0xb78a: +case 0xb78b: +case 0xb78c: +case 0xb78d: +case 0xb78e: +case 0xb78f: +case 0xb988: +case 0xb989: +case 0xb98a: +case 0xb98b: +case 0xb98c: +case 0xb98d: +case 0xb98e: +case 0xb98f: +case 0xbb88: +case 0xbb89: +case 0xbb8a: +case 0xbb8b: +case 0xbb8c: +case 0xbb8d: +case 0xbb8e: +case 0xbb8f: +case 0xbd88: +case 0xbd89: +case 0xbd8a: +case 0xbd8b: +case 0xbd8c: +case 0xbd8d: +case 0xbd8e: +case 0xbd8f: +case 0xbf88: +case 0xbf89: +case 0xbf8a: +case 0xbf8b: +case 0xbf8c: +case 0xbf8d: +case 0xbf8e: +case 0xbf8f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x20d8: +case 0x20d9: +case 0x20da: +case 0x20db: +case 0x20dc: +case 0x20dd: +case 0x20de: +case 0x20df: +case 0x22d8: +case 0x22d9: +case 0x22da: +case 0x22db: +case 0x22dc: +case 0x22dd: +case 0x22de: +case 0x22df: +case 0x24d8: +case 0x24d9: +case 0x24da: +case 0x24db: +case 0x24dc: +case 0x24dd: +case 0x24de: +case 0x24df: +case 0x26d8: +case 0x26d9: +case 0x26da: +case 0x26db: +case 0x26dc: +case 0x26dd: +case 0x26de: +case 0x26df: +case 0x28d8: +case 0x28d9: +case 0x28da: +case 0x28db: +case 0x28dc: +case 0x28dd: +case 0x28de: +case 0x28df: +case 0x2ad8: +case 0x2ad9: +case 0x2ada: +case 0x2adb: +case 0x2adc: +case 0x2add: +case 0x2ade: +case 0x2adf: +case 0x2cd8: +case 0x2cd9: +case 0x2cda: +case 0x2cdb: +case 0x2cdc: +case 0x2cdd: +case 0x2cde: +case 0x2cdf: +case 0x2ed8: +case 0x2ed9: +case 0x2eda: +case 0x2edb: +case 0x2edc: +case 0x2edd: +case 0x2ede: +case 0x2edf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2118: +case 0x2119: +case 0x211a: +case 0x211b: +case 0x211c: +case 0x211d: +case 0x211e: +case 0x211f: +case 0x2318: +case 0x2319: +case 0x231a: +case 0x231b: +case 0x231c: +case 0x231d: +case 0x231e: +case 0x231f: +case 0x2518: +case 0x2519: +case 0x251a: +case 0x251b: +case 0x251c: +case 0x251d: +case 0x251e: +case 0x251f: +case 0x2718: +case 0x2719: +case 0x271a: +case 0x271b: +case 0x271c: +case 0x271d: +case 0x271e: +case 0x271f: +case 0x2918: +case 0x2919: +case 0x291a: +case 0x291b: +case 0x291c: +case 0x291d: +case 0x291e: +case 0x291f: +case 0x2b18: +case 0x2b19: +case 0x2b1a: +case 0x2b1b: +case 0x2b1c: +case 0x2b1d: +case 0x2b1e: +case 0x2b1f: +case 0x2d18: +case 0x2d19: +case 0x2d1a: +case 0x2d1b: +case 0x2d1c: +case 0x2d1d: +case 0x2d1e: +case 0x2d1f: +case 0x2f18: +case 0x2f19: +case 0x2f1a: +case 0x2f1b: +case 0x2f1c: +case 0x2f1d: +case 0x2f1e: +case 0x2f1f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd098: +case 0xd099: +case 0xd09a: +case 0xd09b: +case 0xd09c: +case 0xd09d: +case 0xd09e: +case 0xd09f: +case 0xd298: +case 0xd299: +case 0xd29a: +case 0xd29b: +case 0xd29c: +case 0xd29d: +case 0xd29e: +case 0xd29f: +case 0xd498: +case 0xd499: +case 0xd49a: +case 0xd49b: +case 0xd49c: +case 0xd49d: +case 0xd49e: +case 0xd49f: +case 0xd698: +case 0xd699: +case 0xd69a: +case 0xd69b: +case 0xd69c: +case 0xd69d: +case 0xd69e: +case 0xd69f: +case 0xd898: +case 0xd899: +case 0xd89a: +case 0xd89b: +case 0xd89c: +case 0xd89d: +case 0xd89e: +case 0xd89f: +case 0xda98: +case 0xda99: +case 0xda9a: +case 0xda9b: +case 0xda9c: +case 0xda9d: +case 0xda9e: +case 0xda9f: +case 0xdc98: +case 0xdc99: +case 0xdc9a: +case 0xdc9b: +case 0xdc9c: +case 0xdc9d: +case 0xdc9e: +case 0xdc9f: +case 0xde98: +case 0xde99: +case 0xde9a: +case 0xde9b: +case 0xde9c: +case 0xde9d: +case 0xde9e: +case 0xde9f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc098: +case 0xc099: +case 0xc09a: +case 0xc09b: +case 0xc09c: +case 0xc09d: +case 0xc09e: +case 0xc09f: +case 0xc298: +case 0xc299: +case 0xc29a: +case 0xc29b: +case 0xc29c: +case 0xc29d: +case 0xc29e: +case 0xc29f: +case 0xc498: +case 0xc499: +case 0xc49a: +case 0xc49b: +case 0xc49c: +case 0xc49d: +case 0xc49e: +case 0xc49f: +case 0xc698: +case 0xc699: +case 0xc69a: +case 0xc69b: +case 0xc69c: +case 0xc69d: +case 0xc69e: +case 0xc69f: +case 0xc898: +case 0xc899: +case 0xc89a: +case 0xc89b: +case 0xc89c: +case 0xc89d: +case 0xc89e: +case 0xc89f: +case 0xca98: +case 0xca99: +case 0xca9a: +case 0xca9b: +case 0xca9c: +case 0xca9d: +case 0xca9e: +case 0xca9f: +case 0xcc98: +case 0xcc99: +case 0xcc9a: +case 0xcc9b: +case 0xcc9c: +case 0xcc9d: +case 0xcc9e: +case 0xcc9f: +case 0xce98: +case 0xce99: +case 0xce9a: +case 0xce9b: +case 0xce9c: +case 0xce9d: +case 0xce9e: +case 0xce9f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb098: +case 0xb099: +case 0xb09a: +case 0xb09b: +case 0xb09c: +case 0xb09d: +case 0xb09e: +case 0xb09f: +case 0xb298: +case 0xb299: +case 0xb29a: +case 0xb29b: +case 0xb29c: +case 0xb29d: +case 0xb29e: +case 0xb29f: +case 0xb498: +case 0xb499: +case 0xb49a: +case 0xb49b: +case 0xb49c: +case 0xb49d: +case 0xb49e: +case 0xb49f: +case 0xb698: +case 0xb699: +case 0xb69a: +case 0xb69b: +case 0xb69c: +case 0xb69d: +case 0xb69e: +case 0xb69f: +case 0xb898: +case 0xb899: +case 0xb89a: +case 0xb89b: +case 0xb89c: +case 0xb89d: +case 0xb89e: +case 0xb89f: +case 0xba98: +case 0xba99: +case 0xba9a: +case 0xba9b: +case 0xba9c: +case 0xba9d: +case 0xba9e: +case 0xba9f: +case 0xbc98: +case 0xbc99: +case 0xbc9a: +case 0xbc9b: +case 0xbc9c: +case 0xbc9d: +case 0xbc9e: +case 0xbc9f: +case 0xbe98: +case 0xbe99: +case 0xbe9a: +case 0xbe9b: +case 0xbe9c: +case 0xbe9d: +case 0xbe9e: +case 0xbe9f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x2018: +case 0x2019: +case 0x201a: +case 0x201b: +case 0x201c: +case 0x201d: +case 0x201e: +case 0x201f: +case 0x2218: +case 0x2219: +case 0x221a: +case 0x221b: +case 0x221c: +case 0x221d: +case 0x221e: +case 0x221f: +case 0x2418: +case 0x2419: +case 0x241a: +case 0x241b: +case 0x241c: +case 0x241d: +case 0x241e: +case 0x241f: +case 0x2618: +case 0x2619: +case 0x261a: +case 0x261b: +case 0x261c: +case 0x261d: +case 0x261e: +case 0x261f: +case 0x2818: +case 0x2819: +case 0x281a: +case 0x281b: +case 0x281c: +case 0x281d: +case 0x281e: +case 0x281f: +case 0x2a18: +case 0x2a19: +case 0x2a1a: +case 0x2a1b: +case 0x2a1c: +case 0x2a1d: +case 0x2a1e: +case 0x2a1f: +case 0x2c18: +case 0x2c19: +case 0x2c1a: +case 0x2c1b: +case 0x2c1c: +case 0x2c1d: +case 0x2c1e: +case 0x2c1f: +case 0x2e18: +case 0x2e19: +case 0x2e1a: +case 0x2e1b: +case 0x2e1c: +case 0x2e1d: +case 0x2e1e: +case 0x2e1f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8098: +case 0x8099: +case 0x809a: +case 0x809b: +case 0x809c: +case 0x809d: +case 0x809e: +case 0x809f: +case 0x8298: +case 0x8299: +case 0x829a: +case 0x829b: +case 0x829c: +case 0x829d: +case 0x829e: +case 0x829f: +case 0x8498: +case 0x8499: +case 0x849a: +case 0x849b: +case 0x849c: +case 0x849d: +case 0x849e: +case 0x849f: +case 0x8698: +case 0x8699: +case 0x869a: +case 0x869b: +case 0x869c: +case 0x869d: +case 0x869e: +case 0x869f: +case 0x8898: +case 0x8899: +case 0x889a: +case 0x889b: +case 0x889c: +case 0x889d: +case 0x889e: +case 0x889f: +case 0x8a98: +case 0x8a99: +case 0x8a9a: +case 0x8a9b: +case 0x8a9c: +case 0x8a9d: +case 0x8a9e: +case 0x8a9f: +case 0x8c98: +case 0x8c99: +case 0x8c9a: +case 0x8c9b: +case 0x8c9c: +case 0x8c9d: +case 0x8c9e: +case 0x8c9f: +case 0x8e98: +case 0x8e99: +case 0x8e9a: +case 0x8e9b: +case 0x8e9c: +case 0x8e9d: +case 0x8e9e: +case 0x8e9f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9098: +case 0x9099: +case 0x909a: +case 0x909b: +case 0x909c: +case 0x909d: +case 0x909e: +case 0x909f: +case 0x9298: +case 0x9299: +case 0x929a: +case 0x929b: +case 0x929c: +case 0x929d: +case 0x929e: +case 0x929f: +case 0x9498: +case 0x9499: +case 0x949a: +case 0x949b: +case 0x949c: +case 0x949d: +case 0x949e: +case 0x949f: +case 0x9698: +case 0x9699: +case 0x969a: +case 0x969b: +case 0x969c: +case 0x969d: +case 0x969e: +case 0x969f: +case 0x9898: +case 0x9899: +case 0x989a: +case 0x989b: +case 0x989c: +case 0x989d: +case 0x989e: +case 0x989f: +case 0x9a98: +case 0x9a99: +case 0x9a9a: +case 0x9a9b: +case 0x9a9c: +case 0x9a9d: +case 0x9a9e: +case 0x9a9f: +case 0x9c98: +case 0x9c99: +case 0x9c9a: +case 0x9c9b: +case 0x9c9c: +case 0x9c9d: +case 0x9c9e: +case 0x9c9f: +case 0x9e98: +case 0x9e99: +case 0x9e9a: +case 0x9e9b: +case 0x9e9c: +case 0x9e9d: +case 0x9e9e: +case 0x9e9f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x2058: +case 0x2059: +case 0x205a: +case 0x205b: +case 0x205c: +case 0x205d: +case 0x205e: +case 0x205f: +case 0x2258: +case 0x2259: +case 0x225a: +case 0x225b: +case 0x225c: +case 0x225d: +case 0x225e: +case 0x225f: +case 0x2458: +case 0x2459: +case 0x245a: +case 0x245b: +case 0x245c: +case 0x245d: +case 0x245e: +case 0x245f: +case 0x2658: +case 0x2659: +case 0x265a: +case 0x265b: +case 0x265c: +case 0x265d: +case 0x265e: +case 0x265f: +case 0x2858: +case 0x2859: +case 0x285a: +case 0x285b: +case 0x285c: +case 0x285d: +case 0x285e: +case 0x285f: +case 0x2a58: +case 0x2a59: +case 0x2a5a: +case 0x2a5b: +case 0x2a5c: +case 0x2a5d: +case 0x2a5e: +case 0x2a5f: +case 0x2c58: +case 0x2c59: +case 0x2c5a: +case 0x2c5b: +case 0x2c5c: +case 0x2c5d: +case 0x2c5e: +case 0x2c5f: +case 0x2e58: +case 0x2e59: +case 0x2e5a: +case 0x2e5b: +case 0x2e5c: +case 0x2e5d: +case 0x2e5e: +case 0x2e5f: + { + HAM src(this, instr_b2_b0); MOVEA(src, instr_b11_b9); + } + break; + +case 0x42a0: +case 0x42a1: +case 0x42a2: +case 0x42a3: +case 0x42a4: +case 0x42a5: +case 0x42a6: +case 0x42a7: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x44a0: +case 0x44a1: +case 0x44a2: +case 0x44a3: +case 0x44a4: +case 0x44a5: +case 0x44a6: +case 0x44a7: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x40a0: +case 0x40a1: +case 0x40a2: +case 0x40a3: +case 0x40a4: +case 0x40a5: +case 0x40a6: +case 0x40a7: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x46a0: +case 0x46a1: +case 0x46a2: +case 0x46a3: +case 0x46a4: +case 0x46a5: +case 0x46a6: +case 0x46a7: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x4aa0: +case 0x4aa1: +case 0x4aa2: +case 0x4aa3: +case 0x4aa4: +case 0x4aa5: +case 0x4aa6: +case 0x4aa7: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0x23e0: +case 0x23e1: +case 0x23e2: +case 0x23e3: +case 0x23e4: +case 0x23e5: +case 0x23e6: +case 0x23e7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x21e0: +case 0x21e1: +case 0x21e2: +case 0x21e3: +case 0x21e4: +case 0x21e5: +case 0x21e6: +case 0x21e7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0xd1e0: +case 0xd1e1: +case 0xd1e2: +case 0xd1e3: +case 0xd1e4: +case 0xd1e5: +case 0xd1e6: +case 0xd1e7: +case 0xd3e0: +case 0xd3e1: +case 0xd3e2: +case 0xd3e3: +case 0xd3e4: +case 0xd3e5: +case 0xd3e6: +case 0xd3e7: +case 0xd5e0: +case 0xd5e1: +case 0xd5e2: +case 0xd5e3: +case 0xd5e4: +case 0xd5e5: +case 0xd5e6: +case 0xd5e7: +case 0xd7e0: +case 0xd7e1: +case 0xd7e2: +case 0xd7e3: +case 0xd7e4: +case 0xd7e5: +case 0xd7e6: +case 0xd7e7: +case 0xd9e0: +case 0xd9e1: +case 0xd9e2: +case 0xd9e3: +case 0xd9e4: +case 0xd9e5: +case 0xd9e6: +case 0xd9e7: +case 0xdbe0: +case 0xdbe1: +case 0xdbe2: +case 0xdbe3: +case 0xdbe4: +case 0xdbe5: +case 0xdbe6: +case 0xdbe7: +case 0xdde0: +case 0xdde1: +case 0xdde2: +case 0xdde3: +case 0xdde4: +case 0xdde5: +case 0xdde6: +case 0xdde7: +case 0xdfe0: +case 0xdfe1: +case 0xdfe2: +case 0xdfe3: +case 0xdfe4: +case 0xdfe5: +case 0xdfe6: +case 0xdfe7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb1e0: +case 0xb1e1: +case 0xb1e2: +case 0xb1e3: +case 0xb1e4: +case 0xb1e5: +case 0xb1e6: +case 0xb1e7: +case 0xb3e0: +case 0xb3e1: +case 0xb3e2: +case 0xb3e3: +case 0xb3e4: +case 0xb3e5: +case 0xb3e6: +case 0xb3e7: +case 0xb5e0: +case 0xb5e1: +case 0xb5e2: +case 0xb5e3: +case 0xb5e4: +case 0xb5e5: +case 0xb5e6: +case 0xb5e7: +case 0xb7e0: +case 0xb7e1: +case 0xb7e2: +case 0xb7e3: +case 0xb7e4: +case 0xb7e5: +case 0xb7e6: +case 0xb7e7: +case 0xb9e0: +case 0xb9e1: +case 0xb9e2: +case 0xb9e3: +case 0xb9e4: +case 0xb9e5: +case 0xb9e6: +case 0xb9e7: +case 0xbbe0: +case 0xbbe1: +case 0xbbe2: +case 0xbbe3: +case 0xbbe4: +case 0xbbe5: +case 0xbbe6: +case 0xbbe7: +case 0xbde0: +case 0xbde1: +case 0xbde2: +case 0xbde3: +case 0xbde4: +case 0xbde5: +case 0xbde6: +case 0xbde7: +case 0xbfe0: +case 0xbfe1: +case 0xbfe2: +case 0xbfe3: +case 0xbfe4: +case 0xbfe5: +case 0xbfe6: +case 0xbfe7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x91e0: +case 0x91e1: +case 0x91e2: +case 0x91e3: +case 0x91e4: +case 0x91e5: +case 0x91e6: +case 0x91e7: +case 0x93e0: +case 0x93e1: +case 0x93e2: +case 0x93e3: +case 0x93e4: +case 0x93e5: +case 0x93e6: +case 0x93e7: +case 0x95e0: +case 0x95e1: +case 0x95e2: +case 0x95e3: +case 0x95e4: +case 0x95e5: +case 0x95e6: +case 0x95e7: +case 0x97e0: +case 0x97e1: +case 0x97e2: +case 0x97e3: +case 0x97e4: +case 0x97e5: +case 0x97e6: +case 0x97e7: +case 0x99e0: +case 0x99e1: +case 0x99e2: +case 0x99e3: +case 0x99e4: +case 0x99e5: +case 0x99e6: +case 0x99e7: +case 0x9be0: +case 0x9be1: +case 0x9be2: +case 0x9be3: +case 0x9be4: +case 0x9be5: +case 0x9be6: +case 0x9be7: +case 0x9de0: +case 0x9de1: +case 0x9de2: +case 0x9de3: +case 0x9de4: +case 0x9de5: +case 0x9de6: +case 0x9de7: +case 0x9fe0: +case 0x9fe1: +case 0x9fe2: +case 0x9fe3: +case 0x9fe4: +case 0x9fe5: +case 0x9fe6: +case 0x9fe7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x20a0: +case 0x20a1: +case 0x20a2: +case 0x20a3: +case 0x20a4: +case 0x20a5: +case 0x20a6: +case 0x20a7: +case 0x22a0: +case 0x22a1: +case 0x22a2: +case 0x22a3: +case 0x22a4: +case 0x22a5: +case 0x22a6: +case 0x22a7: +case 0x24a0: +case 0x24a1: +case 0x24a2: +case 0x24a3: +case 0x24a4: +case 0x24a5: +case 0x24a6: +case 0x24a7: +case 0x26a0: +case 0x26a1: +case 0x26a2: +case 0x26a3: +case 0x26a4: +case 0x26a5: +case 0x26a6: +case 0x26a7: +case 0x28a0: +case 0x28a1: +case 0x28a2: +case 0x28a3: +case 0x28a4: +case 0x28a5: +case 0x28a6: +case 0x28a7: +case 0x2aa0: +case 0x2aa1: +case 0x2aa2: +case 0x2aa3: +case 0x2aa4: +case 0x2aa5: +case 0x2aa6: +case 0x2aa7: +case 0x2ca0: +case 0x2ca1: +case 0x2ca2: +case 0x2ca3: +case 0x2ca4: +case 0x2ca5: +case 0x2ca6: +case 0x2ca7: +case 0x2ea0: +case 0x2ea1: +case 0x2ea2: +case 0x2ea3: +case 0x2ea4: +case 0x2ea5: +case 0x2ea6: +case 0x2ea7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2160: +case 0x2161: +case 0x2162: +case 0x2163: +case 0x2164: +case 0x2165: +case 0x2166: +case 0x2167: +case 0x2360: +case 0x2361: +case 0x2362: +case 0x2363: +case 0x2364: +case 0x2365: +case 0x2366: +case 0x2367: +case 0x2560: +case 0x2561: +case 0x2562: +case 0x2563: +case 0x2564: +case 0x2565: +case 0x2566: +case 0x2567: +case 0x2760: +case 0x2761: +case 0x2762: +case 0x2763: +case 0x2764: +case 0x2765: +case 0x2766: +case 0x2767: +case 0x2960: +case 0x2961: +case 0x2962: +case 0x2963: +case 0x2964: +case 0x2965: +case 0x2966: +case 0x2967: +case 0x2b60: +case 0x2b61: +case 0x2b62: +case 0x2b63: +case 0x2b64: +case 0x2b65: +case 0x2b66: +case 0x2b67: +case 0x2d60: +case 0x2d61: +case 0x2d62: +case 0x2d63: +case 0x2d64: +case 0x2d65: +case 0x2d66: +case 0x2d67: +case 0x2f60: +case 0x2f61: +case 0x2f62: +case 0x2f63: +case 0x2f64: +case 0x2f65: +case 0x2f66: +case 0x2f67: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x21a0: +case 0x21a1: +case 0x21a2: +case 0x21a3: +case 0x21a4: +case 0x21a5: +case 0x21a6: +case 0x21a7: +case 0x23a0: +case 0x23a1: +case 0x23a2: +case 0x23a3: +case 0x23a4: +case 0x23a5: +case 0x23a6: +case 0x23a7: +case 0x25a0: +case 0x25a1: +case 0x25a2: +case 0x25a3: +case 0x25a4: +case 0x25a5: +case 0x25a6: +case 0x25a7: +case 0x27a0: +case 0x27a1: +case 0x27a2: +case 0x27a3: +case 0x27a4: +case 0x27a5: +case 0x27a6: +case 0x27a7: +case 0x29a0: +case 0x29a1: +case 0x29a2: +case 0x29a3: +case 0x29a4: +case 0x29a5: +case 0x29a6: +case 0x29a7: +case 0x2ba0: +case 0x2ba1: +case 0x2ba2: +case 0x2ba3: +case 0x2ba4: +case 0x2ba5: +case 0x2ba6: +case 0x2ba7: +case 0x2da0: +case 0x2da1: +case 0x2da2: +case 0x2da3: +case 0x2da4: +case 0x2da5: +case 0x2da6: +case 0x2da7: +case 0x2fa0: +case 0x2fa1: +case 0x2fa2: +case 0x2fa3: +case 0x2fa4: +case 0x2fa5: +case 0x2fa6: +case 0x2fa7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x20e0: +case 0x20e1: +case 0x20e2: +case 0x20e3: +case 0x20e4: +case 0x20e5: +case 0x20e6: +case 0x20e7: +case 0x22e0: +case 0x22e1: +case 0x22e2: +case 0x22e3: +case 0x22e4: +case 0x22e5: +case 0x22e6: +case 0x22e7: +case 0x24e0: +case 0x24e1: +case 0x24e2: +case 0x24e3: +case 0x24e4: +case 0x24e5: +case 0x24e6: +case 0x24e7: +case 0x26e0: +case 0x26e1: +case 0x26e2: +case 0x26e3: +case 0x26e4: +case 0x26e5: +case 0x26e6: +case 0x26e7: +case 0x28e0: +case 0x28e1: +case 0x28e2: +case 0x28e3: +case 0x28e4: +case 0x28e5: +case 0x28e6: +case 0x28e7: +case 0x2ae0: +case 0x2ae1: +case 0x2ae2: +case 0x2ae3: +case 0x2ae4: +case 0x2ae5: +case 0x2ae6: +case 0x2ae7: +case 0x2ce0: +case 0x2ce1: +case 0x2ce2: +case 0x2ce3: +case 0x2ce4: +case 0x2ce5: +case 0x2ce6: +case 0x2ce7: +case 0x2ee0: +case 0x2ee1: +case 0x2ee2: +case 0x2ee3: +case 0x2ee4: +case 0x2ee5: +case 0x2ee6: +case 0x2ee7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd188: +case 0xd189: +case 0xd18a: +case 0xd18b: +case 0xd18c: +case 0xd18d: +case 0xd18e: +case 0xd18f: +case 0xd388: +case 0xd389: +case 0xd38a: +case 0xd38b: +case 0xd38c: +case 0xd38d: +case 0xd38e: +case 0xd38f: +case 0xd588: +case 0xd589: +case 0xd58a: +case 0xd58b: +case 0xd58c: +case 0xd58d: +case 0xd58e: +case 0xd58f: +case 0xd788: +case 0xd789: +case 0xd78a: +case 0xd78b: +case 0xd78c: +case 0xd78d: +case 0xd78e: +case 0xd78f: +case 0xd988: +case 0xd989: +case 0xd98a: +case 0xd98b: +case 0xd98c: +case 0xd98d: +case 0xd98e: +case 0xd98f: +case 0xdb88: +case 0xdb89: +case 0xdb8a: +case 0xdb8b: +case 0xdb8c: +case 0xdb8d: +case 0xdb8e: +case 0xdb8f: +case 0xdd88: +case 0xdd89: +case 0xdd8a: +case 0xdd8b: +case 0xdd8c: +case 0xdd8d: +case 0xdd8e: +case 0xdd8f: +case 0xdf88: +case 0xdf89: +case 0xdf8a: +case 0xdf8b: +case 0xdf8c: +case 0xdf8d: +case 0xdf8e: +case 0xdf8f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADDX(src, dst); + } + break; + +case 0x2120: +case 0x2121: +case 0x2122: +case 0x2123: +case 0x2124: +case 0x2125: +case 0x2126: +case 0x2127: +case 0x2320: +case 0x2321: +case 0x2322: +case 0x2323: +case 0x2324: +case 0x2325: +case 0x2326: +case 0x2327: +case 0x2520: +case 0x2521: +case 0x2522: +case 0x2523: +case 0x2524: +case 0x2525: +case 0x2526: +case 0x2527: +case 0x2720: +case 0x2721: +case 0x2722: +case 0x2723: +case 0x2724: +case 0x2725: +case 0x2726: +case 0x2727: +case 0x2920: +case 0x2921: +case 0x2922: +case 0x2923: +case 0x2924: +case 0x2925: +case 0x2926: +case 0x2927: +case 0x2b20: +case 0x2b21: +case 0x2b22: +case 0x2b23: +case 0x2b24: +case 0x2b25: +case 0x2b26: +case 0x2b27: +case 0x2d20: +case 0x2d21: +case 0x2d22: +case 0x2d23: +case 0x2d24: +case 0x2d25: +case 0x2d26: +case 0x2d27: +case 0x2f20: +case 0x2f21: +case 0x2f22: +case 0x2f23: +case 0x2f24: +case 0x2f25: +case 0x2f26: +case 0x2f27: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x9188: +case 0x9189: +case 0x918a: +case 0x918b: +case 0x918c: +case 0x918d: +case 0x918e: +case 0x918f: +case 0x9388: +case 0x9389: +case 0x938a: +case 0x938b: +case 0x938c: +case 0x938d: +case 0x938e: +case 0x938f: +case 0x9588: +case 0x9589: +case 0x958a: +case 0x958b: +case 0x958c: +case 0x958d: +case 0x958e: +case 0x958f: +case 0x9788: +case 0x9789: +case 0x978a: +case 0x978b: +case 0x978c: +case 0x978d: +case 0x978e: +case 0x978f: +case 0x9988: +case 0x9989: +case 0x998a: +case 0x998b: +case 0x998c: +case 0x998d: +case 0x998e: +case 0x998f: +case 0x9b88: +case 0x9b89: +case 0x9b8a: +case 0x9b8b: +case 0x9b8c: +case 0x9b8d: +case 0x9b8e: +case 0x9b8f: +case 0x9d88: +case 0x9d89: +case 0x9d8a: +case 0x9d8b: +case 0x9d8c: +case 0x9d8d: +case 0x9d8e: +case 0x9d8f: +case 0x9f88: +case 0x9f89: +case 0x9f8a: +case 0x9f8b: +case 0x9f8c: +case 0x9f8d: +case 0x9f8e: +case 0x9f8f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUBX(src, dst); + } + break; + +case 0xd0a0: +case 0xd0a1: +case 0xd0a2: +case 0xd0a3: +case 0xd0a4: +case 0xd0a5: +case 0xd0a6: +case 0xd0a7: +case 0xd2a0: +case 0xd2a1: +case 0xd2a2: +case 0xd2a3: +case 0xd2a4: +case 0xd2a5: +case 0xd2a6: +case 0xd2a7: +case 0xd4a0: +case 0xd4a1: +case 0xd4a2: +case 0xd4a3: +case 0xd4a4: +case 0xd4a5: +case 0xd4a6: +case 0xd4a7: +case 0xd6a0: +case 0xd6a1: +case 0xd6a2: +case 0xd6a3: +case 0xd6a4: +case 0xd6a5: +case 0xd6a6: +case 0xd6a7: +case 0xd8a0: +case 0xd8a1: +case 0xd8a2: +case 0xd8a3: +case 0xd8a4: +case 0xd8a5: +case 0xd8a6: +case 0xd8a7: +case 0xdaa0: +case 0xdaa1: +case 0xdaa2: +case 0xdaa3: +case 0xdaa4: +case 0xdaa5: +case 0xdaa6: +case 0xdaa7: +case 0xdca0: +case 0xdca1: +case 0xdca2: +case 0xdca3: +case 0xdca4: +case 0xdca5: +case 0xdca6: +case 0xdca7: +case 0xdea0: +case 0xdea1: +case 0xdea2: +case 0xdea3: +case 0xdea4: +case 0xdea5: +case 0xdea6: +case 0xdea7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc0a0: +case 0xc0a1: +case 0xc0a2: +case 0xc0a3: +case 0xc0a4: +case 0xc0a5: +case 0xc0a6: +case 0xc0a7: +case 0xc2a0: +case 0xc2a1: +case 0xc2a2: +case 0xc2a3: +case 0xc2a4: +case 0xc2a5: +case 0xc2a6: +case 0xc2a7: +case 0xc4a0: +case 0xc4a1: +case 0xc4a2: +case 0xc4a3: +case 0xc4a4: +case 0xc4a5: +case 0xc4a6: +case 0xc4a7: +case 0xc6a0: +case 0xc6a1: +case 0xc6a2: +case 0xc6a3: +case 0xc6a4: +case 0xc6a5: +case 0xc6a6: +case 0xc6a7: +case 0xc8a0: +case 0xc8a1: +case 0xc8a2: +case 0xc8a3: +case 0xc8a4: +case 0xc8a5: +case 0xc8a6: +case 0xc8a7: +case 0xcaa0: +case 0xcaa1: +case 0xcaa2: +case 0xcaa3: +case 0xcaa4: +case 0xcaa5: +case 0xcaa6: +case 0xcaa7: +case 0xcca0: +case 0xcca1: +case 0xcca2: +case 0xcca3: +case 0xcca4: +case 0xcca5: +case 0xcca6: +case 0xcca7: +case 0xcea0: +case 0xcea1: +case 0xcea2: +case 0xcea3: +case 0xcea4: +case 0xcea5: +case 0xcea6: +case 0xcea7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb0a0: +case 0xb0a1: +case 0xb0a2: +case 0xb0a3: +case 0xb0a4: +case 0xb0a5: +case 0xb0a6: +case 0xb0a7: +case 0xb2a0: +case 0xb2a1: +case 0xb2a2: +case 0xb2a3: +case 0xb2a4: +case 0xb2a5: +case 0xb2a6: +case 0xb2a7: +case 0xb4a0: +case 0xb4a1: +case 0xb4a2: +case 0xb4a3: +case 0xb4a4: +case 0xb4a5: +case 0xb4a6: +case 0xb4a7: +case 0xb6a0: +case 0xb6a1: +case 0xb6a2: +case 0xb6a3: +case 0xb6a4: +case 0xb6a5: +case 0xb6a6: +case 0xb6a7: +case 0xb8a0: +case 0xb8a1: +case 0xb8a2: +case 0xb8a3: +case 0xb8a4: +case 0xb8a5: +case 0xb8a6: +case 0xb8a7: +case 0xbaa0: +case 0xbaa1: +case 0xbaa2: +case 0xbaa3: +case 0xbaa4: +case 0xbaa5: +case 0xbaa6: +case 0xbaa7: +case 0xbca0: +case 0xbca1: +case 0xbca2: +case 0xbca3: +case 0xbca4: +case 0xbca5: +case 0xbca6: +case 0xbca7: +case 0xbea0: +case 0xbea1: +case 0xbea2: +case 0xbea3: +case 0xbea4: +case 0xbea5: +case 0xbea6: +case 0xbea7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x2020: +case 0x2021: +case 0x2022: +case 0x2023: +case 0x2024: +case 0x2025: +case 0x2026: +case 0x2027: +case 0x2220: +case 0x2221: +case 0x2222: +case 0x2223: +case 0x2224: +case 0x2225: +case 0x2226: +case 0x2227: +case 0x2420: +case 0x2421: +case 0x2422: +case 0x2423: +case 0x2424: +case 0x2425: +case 0x2426: +case 0x2427: +case 0x2620: +case 0x2621: +case 0x2622: +case 0x2623: +case 0x2624: +case 0x2625: +case 0x2626: +case 0x2627: +case 0x2820: +case 0x2821: +case 0x2822: +case 0x2823: +case 0x2824: +case 0x2825: +case 0x2826: +case 0x2827: +case 0x2a20: +case 0x2a21: +case 0x2a22: +case 0x2a23: +case 0x2a24: +case 0x2a25: +case 0x2a26: +case 0x2a27: +case 0x2c20: +case 0x2c21: +case 0x2c22: +case 0x2c23: +case 0x2c24: +case 0x2c25: +case 0x2c26: +case 0x2c27: +case 0x2e20: +case 0x2e21: +case 0x2e22: +case 0x2e23: +case 0x2e24: +case 0x2e25: +case 0x2e26: +case 0x2e27: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x80a0: +case 0x80a1: +case 0x80a2: +case 0x80a3: +case 0x80a4: +case 0x80a5: +case 0x80a6: +case 0x80a7: +case 0x82a0: +case 0x82a1: +case 0x82a2: +case 0x82a3: +case 0x82a4: +case 0x82a5: +case 0x82a6: +case 0x82a7: +case 0x84a0: +case 0x84a1: +case 0x84a2: +case 0x84a3: +case 0x84a4: +case 0x84a5: +case 0x84a6: +case 0x84a7: +case 0x86a0: +case 0x86a1: +case 0x86a2: +case 0x86a3: +case 0x86a4: +case 0x86a5: +case 0x86a6: +case 0x86a7: +case 0x88a0: +case 0x88a1: +case 0x88a2: +case 0x88a3: +case 0x88a4: +case 0x88a5: +case 0x88a6: +case 0x88a7: +case 0x8aa0: +case 0x8aa1: +case 0x8aa2: +case 0x8aa3: +case 0x8aa4: +case 0x8aa5: +case 0x8aa6: +case 0x8aa7: +case 0x8ca0: +case 0x8ca1: +case 0x8ca2: +case 0x8ca3: +case 0x8ca4: +case 0x8ca5: +case 0x8ca6: +case 0x8ca7: +case 0x8ea0: +case 0x8ea1: +case 0x8ea2: +case 0x8ea3: +case 0x8ea4: +case 0x8ea5: +case 0x8ea6: +case 0x8ea7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x90a0: +case 0x90a1: +case 0x90a2: +case 0x90a3: +case 0x90a4: +case 0x90a5: +case 0x90a6: +case 0x90a7: +case 0x92a0: +case 0x92a1: +case 0x92a2: +case 0x92a3: +case 0x92a4: +case 0x92a5: +case 0x92a6: +case 0x92a7: +case 0x94a0: +case 0x94a1: +case 0x94a2: +case 0x94a3: +case 0x94a4: +case 0x94a5: +case 0x94a6: +case 0x94a7: +case 0x96a0: +case 0x96a1: +case 0x96a2: +case 0x96a3: +case 0x96a4: +case 0x96a5: +case 0x96a6: +case 0x96a7: +case 0x98a0: +case 0x98a1: +case 0x98a2: +case 0x98a3: +case 0x98a4: +case 0x98a5: +case 0x98a6: +case 0x98a7: +case 0x9aa0: +case 0x9aa1: +case 0x9aa2: +case 0x9aa3: +case 0x9aa4: +case 0x9aa5: +case 0x9aa6: +case 0x9aa7: +case 0x9ca0: +case 0x9ca1: +case 0x9ca2: +case 0x9ca3: +case 0x9ca4: +case 0x9ca5: +case 0x9ca6: +case 0x9ca7: +case 0x9ea0: +case 0x9ea1: +case 0x9ea2: +case 0x9ea3: +case 0x9ea4: +case 0x9ea5: +case 0x9ea6: +case 0x9ea7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x2060: +case 0x2061: +case 0x2062: +case 0x2063: +case 0x2064: +case 0x2065: +case 0x2066: +case 0x2067: +case 0x2260: +case 0x2261: +case 0x2262: +case 0x2263: +case 0x2264: +case 0x2265: +case 0x2266: +case 0x2267: +case 0x2460: +case 0x2461: +case 0x2462: +case 0x2463: +case 0x2464: +case 0x2465: +case 0x2466: +case 0x2467: +case 0x2660: +case 0x2661: +case 0x2662: +case 0x2663: +case 0x2664: +case 0x2665: +case 0x2666: +case 0x2667: +case 0x2860: +case 0x2861: +case 0x2862: +case 0x2863: +case 0x2864: +case 0x2865: +case 0x2866: +case 0x2867: +case 0x2a60: +case 0x2a61: +case 0x2a62: +case 0x2a63: +case 0x2a64: +case 0x2a65: +case 0x2a66: +case 0x2a67: +case 0x2c60: +case 0x2c61: +case 0x2c62: +case 0x2c63: +case 0x2c64: +case 0x2c65: +case 0x2c66: +case 0x2c67: +case 0x2e60: +case 0x2e61: +case 0x2e62: +case 0x2e63: +case 0x2e64: +case 0x2e65: +case 0x2e66: +case 0x2e67: + { + HAM src(this, instr_b2_b0); MOVEA(src, instr_b11_b9); + } + break; + +case 0x4280: +case 0x4281: +case 0x4282: +case 0x4283: +case 0x4284: +case 0x4285: +case 0x4286: +case 0x4287: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x48c0: +case 0x48c1: +case 0x48c2: +case 0x48c3: +case 0x48c4: +case 0x48c5: +case 0x48c6: +case 0x48c7: + { + HAM dst(this, instr_b2_b0); EXT(dst); + } + break; + +case 0x4480: +case 0x4481: +case 0x4482: +case 0x4483: +case 0x4484: +case 0x4485: +case 0x4486: +case 0x4487: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x4080: +case 0x4081: +case 0x4082: +case 0x4083: +case 0x4084: +case 0x4085: +case 0x4086: +case 0x4087: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x4680: +case 0x4681: +case 0x4682: +case 0x4683: +case 0x4684: +case 0x4685: +case 0x4686: +case 0x4687: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x4a80: +case 0x4a81: +case 0x4a82: +case 0x4a83: +case 0x4a84: +case 0x4a85: +case 0x4a86: +case 0x4a87: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0xd1b9: +case 0xd3b9: +case 0xd5b9: +case 0xd7b9: +case 0xd9b9: +case 0xdbb9: +case 0xddb9: +case 0xdfb9: + { + HAM src(this, instr_b11_b9); HAM dst(this); ADD(src, dst); + } + break; + +case 0xc1b9: +case 0xc3b9: +case 0xc5b9: +case 0xc7b9: +case 0xc9b9: +case 0xcbb9: +case 0xcdb9: +case 0xcfb9: + { + HAM src(this, instr_b11_b9); HAM dst(this); AND(src, dst); + } + break; + +case 0xb1b9: +case 0xb3b9: +case 0xb5b9: +case 0xb7b9: +case 0xb9b9: +case 0xbbb9: +case 0xbdb9: +case 0xbfb9: + { + HAM src(this, instr_b11_b9); HAM dst(this); EOR(src, dst); + } + break; + +case 0x81b9: +case 0x83b9: +case 0x85b9: +case 0x87b9: +case 0x89b9: +case 0x8bb9: +case 0x8db9: +case 0x8fb9: + { + HAM src(this, instr_b11_b9); HAM dst(this); OR(src, dst); + } + break; + +case 0x91b9: +case 0x93b9: +case 0x95b9: +case 0x97b9: +case 0x99b9: +case 0x9bb9: +case 0x9db9: +case 0x9fb9: + { + HAM src(this, instr_b11_b9); HAM dst(this); SUB(src, dst); + } + break; + +case 0xd1b8: +case 0xd3b8: +case 0xd5b8: +case 0xd7b8: +case 0xd9b8: +case 0xdbb8: +case 0xddb8: +case 0xdfb8: + { + HAM src(this, instr_b11_b9); HAM dst(this); ADD(src, dst); + } + break; + +case 0xc1b8: +case 0xc3b8: +case 0xc5b8: +case 0xc7b8: +case 0xc9b8: +case 0xcbb8: +case 0xcdb8: +case 0xcfb8: + { + HAM src(this, instr_b11_b9); HAM dst(this); AND(src, dst); + } + break; + +case 0xb1b8: +case 0xb3b8: +case 0xb5b8: +case 0xb7b8: +case 0xb9b8: +case 0xbbb8: +case 0xbdb8: +case 0xbfb8: + { + HAM src(this, instr_b11_b9); HAM dst(this); EOR(src, dst); + } + break; + +case 0x81b8: +case 0x83b8: +case 0x85b8: +case 0x87b8: +case 0x89b8: +case 0x8bb8: +case 0x8db8: +case 0x8fb8: + { + HAM src(this, instr_b11_b9); HAM dst(this); OR(src, dst); + } + break; + +case 0x91b8: +case 0x93b8: +case 0x95b8: +case 0x97b8: +case 0x99b8: +case 0x9bb8: +case 0x9db8: +case 0x9fb8: + { + HAM src(this, instr_b11_b9); HAM dst(this); SUB(src, dst); + } + break; + +case 0xd190: +case 0xd191: +case 0xd192: +case 0xd193: +case 0xd194: +case 0xd195: +case 0xd196: +case 0xd197: +case 0xd390: +case 0xd391: +case 0xd392: +case 0xd393: +case 0xd394: +case 0xd395: +case 0xd396: +case 0xd397: +case 0xd590: +case 0xd591: +case 0xd592: +case 0xd593: +case 0xd594: +case 0xd595: +case 0xd596: +case 0xd597: +case 0xd790: +case 0xd791: +case 0xd792: +case 0xd793: +case 0xd794: +case 0xd795: +case 0xd796: +case 0xd797: +case 0xd990: +case 0xd991: +case 0xd992: +case 0xd993: +case 0xd994: +case 0xd995: +case 0xd996: +case 0xd997: +case 0xdb90: +case 0xdb91: +case 0xdb92: +case 0xdb93: +case 0xdb94: +case 0xdb95: +case 0xdb96: +case 0xdb97: +case 0xdd90: +case 0xdd91: +case 0xdd92: +case 0xdd93: +case 0xdd94: +case 0xdd95: +case 0xdd96: +case 0xdd97: +case 0xdf90: +case 0xdf91: +case 0xdf92: +case 0xdf93: +case 0xdf94: +case 0xdf95: +case 0xdf96: +case 0xdf97: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0xc190: +case 0xc191: +case 0xc192: +case 0xc193: +case 0xc194: +case 0xc195: +case 0xc196: +case 0xc197: +case 0xc390: +case 0xc391: +case 0xc392: +case 0xc393: +case 0xc394: +case 0xc395: +case 0xc396: +case 0xc397: +case 0xc590: +case 0xc591: +case 0xc592: +case 0xc593: +case 0xc594: +case 0xc595: +case 0xc596: +case 0xc597: +case 0xc790: +case 0xc791: +case 0xc792: +case 0xc793: +case 0xc794: +case 0xc795: +case 0xc796: +case 0xc797: +case 0xc990: +case 0xc991: +case 0xc992: +case 0xc993: +case 0xc994: +case 0xc995: +case 0xc996: +case 0xc997: +case 0xcb90: +case 0xcb91: +case 0xcb92: +case 0xcb93: +case 0xcb94: +case 0xcb95: +case 0xcb96: +case 0xcb97: +case 0xcd90: +case 0xcd91: +case 0xcd92: +case 0xcd93: +case 0xcd94: +case 0xcd95: +case 0xcd96: +case 0xcd97: +case 0xcf90: +case 0xcf91: +case 0xcf92: +case 0xcf93: +case 0xcf94: +case 0xcf95: +case 0xcf96: +case 0xcf97: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0xb190: +case 0xb191: +case 0xb192: +case 0xb193: +case 0xb194: +case 0xb195: +case 0xb196: +case 0xb197: +case 0xb390: +case 0xb391: +case 0xb392: +case 0xb393: +case 0xb394: +case 0xb395: +case 0xb396: +case 0xb397: +case 0xb590: +case 0xb591: +case 0xb592: +case 0xb593: +case 0xb594: +case 0xb595: +case 0xb596: +case 0xb597: +case 0xb790: +case 0xb791: +case 0xb792: +case 0xb793: +case 0xb794: +case 0xb795: +case 0xb796: +case 0xb797: +case 0xb990: +case 0xb991: +case 0xb992: +case 0xb993: +case 0xb994: +case 0xb995: +case 0xb996: +case 0xb997: +case 0xbb90: +case 0xbb91: +case 0xbb92: +case 0xbb93: +case 0xbb94: +case 0xbb95: +case 0xbb96: +case 0xbb97: +case 0xbd90: +case 0xbd91: +case 0xbd92: +case 0xbd93: +case 0xbd94: +case 0xbd95: +case 0xbd96: +case 0xbd97: +case 0xbf90: +case 0xbf91: +case 0xbf92: +case 0xbf93: +case 0xbf94: +case 0xbf95: +case 0xbf96: +case 0xbf97: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x8190: +case 0x8191: +case 0x8192: +case 0x8193: +case 0x8194: +case 0x8195: +case 0x8196: +case 0x8197: +case 0x8390: +case 0x8391: +case 0x8392: +case 0x8393: +case 0x8394: +case 0x8395: +case 0x8396: +case 0x8397: +case 0x8590: +case 0x8591: +case 0x8592: +case 0x8593: +case 0x8594: +case 0x8595: +case 0x8596: +case 0x8597: +case 0x8790: +case 0x8791: +case 0x8792: +case 0x8793: +case 0x8794: +case 0x8795: +case 0x8796: +case 0x8797: +case 0x8990: +case 0x8991: +case 0x8992: +case 0x8993: +case 0x8994: +case 0x8995: +case 0x8996: +case 0x8997: +case 0x8b90: +case 0x8b91: +case 0x8b92: +case 0x8b93: +case 0x8b94: +case 0x8b95: +case 0x8b96: +case 0x8b97: +case 0x8d90: +case 0x8d91: +case 0x8d92: +case 0x8d93: +case 0x8d94: +case 0x8d95: +case 0x8d96: +case 0x8d97: +case 0x8f90: +case 0x8f91: +case 0x8f92: +case 0x8f93: +case 0x8f94: +case 0x8f95: +case 0x8f96: +case 0x8f97: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x9190: +case 0x9191: +case 0x9192: +case 0x9193: +case 0x9194: +case 0x9195: +case 0x9196: +case 0x9197: +case 0x9390: +case 0x9391: +case 0x9392: +case 0x9393: +case 0x9394: +case 0x9395: +case 0x9396: +case 0x9397: +case 0x9590: +case 0x9591: +case 0x9592: +case 0x9593: +case 0x9594: +case 0x9595: +case 0x9596: +case 0x9597: +case 0x9790: +case 0x9791: +case 0x9792: +case 0x9793: +case 0x9794: +case 0x9795: +case 0x9796: +case 0x9797: +case 0x9990: +case 0x9991: +case 0x9992: +case 0x9993: +case 0x9994: +case 0x9995: +case 0x9996: +case 0x9997: +case 0x9b90: +case 0x9b91: +case 0x9b92: +case 0x9b93: +case 0x9b94: +case 0x9b95: +case 0x9b96: +case 0x9b97: +case 0x9d90: +case 0x9d91: +case 0x9d92: +case 0x9d93: +case 0x9d94: +case 0x9d95: +case 0x9d96: +case 0x9d97: +case 0x9f90: +case 0x9f91: +case 0x9f92: +case 0x9f93: +case 0x9f94: +case 0x9f95: +case 0x9f96: +case 0x9f97: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xd1a8: +case 0xd1a9: +case 0xd1aa: +case 0xd1ab: +case 0xd1ac: +case 0xd1ad: +case 0xd1ae: +case 0xd1af: +case 0xd3a8: +case 0xd3a9: +case 0xd3aa: +case 0xd3ab: +case 0xd3ac: +case 0xd3ad: +case 0xd3ae: +case 0xd3af: +case 0xd5a8: +case 0xd5a9: +case 0xd5aa: +case 0xd5ab: +case 0xd5ac: +case 0xd5ad: +case 0xd5ae: +case 0xd5af: +case 0xd7a8: +case 0xd7a9: +case 0xd7aa: +case 0xd7ab: +case 0xd7ac: +case 0xd7ad: +case 0xd7ae: +case 0xd7af: +case 0xd9a8: +case 0xd9a9: +case 0xd9aa: +case 0xd9ab: +case 0xd9ac: +case 0xd9ad: +case 0xd9ae: +case 0xd9af: +case 0xdba8: +case 0xdba9: +case 0xdbaa: +case 0xdbab: +case 0xdbac: +case 0xdbad: +case 0xdbae: +case 0xdbaf: +case 0xdda8: +case 0xdda9: +case 0xddaa: +case 0xddab: +case 0xddac: +case 0xddad: +case 0xddae: +case 0xddaf: +case 0xdfa8: +case 0xdfa9: +case 0xdfaa: +case 0xdfab: +case 0xdfac: +case 0xdfad: +case 0xdfae: +case 0xdfaf: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0xc1a8: +case 0xc1a9: +case 0xc1aa: +case 0xc1ab: +case 0xc1ac: +case 0xc1ad: +case 0xc1ae: +case 0xc1af: +case 0xc3a8: +case 0xc3a9: +case 0xc3aa: +case 0xc3ab: +case 0xc3ac: +case 0xc3ad: +case 0xc3ae: +case 0xc3af: +case 0xc5a8: +case 0xc5a9: +case 0xc5aa: +case 0xc5ab: +case 0xc5ac: +case 0xc5ad: +case 0xc5ae: +case 0xc5af: +case 0xc7a8: +case 0xc7a9: +case 0xc7aa: +case 0xc7ab: +case 0xc7ac: +case 0xc7ad: +case 0xc7ae: +case 0xc7af: +case 0xc9a8: +case 0xc9a9: +case 0xc9aa: +case 0xc9ab: +case 0xc9ac: +case 0xc9ad: +case 0xc9ae: +case 0xc9af: +case 0xcba8: +case 0xcba9: +case 0xcbaa: +case 0xcbab: +case 0xcbac: +case 0xcbad: +case 0xcbae: +case 0xcbaf: +case 0xcda8: +case 0xcda9: +case 0xcdaa: +case 0xcdab: +case 0xcdac: +case 0xcdad: +case 0xcdae: +case 0xcdaf: +case 0xcfa8: +case 0xcfa9: +case 0xcfaa: +case 0xcfab: +case 0xcfac: +case 0xcfad: +case 0xcfae: +case 0xcfaf: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0xb1a8: +case 0xb1a9: +case 0xb1aa: +case 0xb1ab: +case 0xb1ac: +case 0xb1ad: +case 0xb1ae: +case 0xb1af: +case 0xb3a8: +case 0xb3a9: +case 0xb3aa: +case 0xb3ab: +case 0xb3ac: +case 0xb3ad: +case 0xb3ae: +case 0xb3af: +case 0xb5a8: +case 0xb5a9: +case 0xb5aa: +case 0xb5ab: +case 0xb5ac: +case 0xb5ad: +case 0xb5ae: +case 0xb5af: +case 0xb7a8: +case 0xb7a9: +case 0xb7aa: +case 0xb7ab: +case 0xb7ac: +case 0xb7ad: +case 0xb7ae: +case 0xb7af: +case 0xb9a8: +case 0xb9a9: +case 0xb9aa: +case 0xb9ab: +case 0xb9ac: +case 0xb9ad: +case 0xb9ae: +case 0xb9af: +case 0xbba8: +case 0xbba9: +case 0xbbaa: +case 0xbbab: +case 0xbbac: +case 0xbbad: +case 0xbbae: +case 0xbbaf: +case 0xbda8: +case 0xbda9: +case 0xbdaa: +case 0xbdab: +case 0xbdac: +case 0xbdad: +case 0xbdae: +case 0xbdaf: +case 0xbfa8: +case 0xbfa9: +case 0xbfaa: +case 0xbfab: +case 0xbfac: +case 0xbfad: +case 0xbfae: +case 0xbfaf: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x81a8: +case 0x81a9: +case 0x81aa: +case 0x81ab: +case 0x81ac: +case 0x81ad: +case 0x81ae: +case 0x81af: +case 0x83a8: +case 0x83a9: +case 0x83aa: +case 0x83ab: +case 0x83ac: +case 0x83ad: +case 0x83ae: +case 0x83af: +case 0x85a8: +case 0x85a9: +case 0x85aa: +case 0x85ab: +case 0x85ac: +case 0x85ad: +case 0x85ae: +case 0x85af: +case 0x87a8: +case 0x87a9: +case 0x87aa: +case 0x87ab: +case 0x87ac: +case 0x87ad: +case 0x87ae: +case 0x87af: +case 0x89a8: +case 0x89a9: +case 0x89aa: +case 0x89ab: +case 0x89ac: +case 0x89ad: +case 0x89ae: +case 0x89af: +case 0x8ba8: +case 0x8ba9: +case 0x8baa: +case 0x8bab: +case 0x8bac: +case 0x8bad: +case 0x8bae: +case 0x8baf: +case 0x8da8: +case 0x8da9: +case 0x8daa: +case 0x8dab: +case 0x8dac: +case 0x8dad: +case 0x8dae: +case 0x8daf: +case 0x8fa8: +case 0x8fa9: +case 0x8faa: +case 0x8fab: +case 0x8fac: +case 0x8fad: +case 0x8fae: +case 0x8faf: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x91a8: +case 0x91a9: +case 0x91aa: +case 0x91ab: +case 0x91ac: +case 0x91ad: +case 0x91ae: +case 0x91af: +case 0x93a8: +case 0x93a9: +case 0x93aa: +case 0x93ab: +case 0x93ac: +case 0x93ad: +case 0x93ae: +case 0x93af: +case 0x95a8: +case 0x95a9: +case 0x95aa: +case 0x95ab: +case 0x95ac: +case 0x95ad: +case 0x95ae: +case 0x95af: +case 0x97a8: +case 0x97a9: +case 0x97aa: +case 0x97ab: +case 0x97ac: +case 0x97ad: +case 0x97ae: +case 0x97af: +case 0x99a8: +case 0x99a9: +case 0x99aa: +case 0x99ab: +case 0x99ac: +case 0x99ad: +case 0x99ae: +case 0x99af: +case 0x9ba8: +case 0x9ba9: +case 0x9baa: +case 0x9bab: +case 0x9bac: +case 0x9bad: +case 0x9bae: +case 0x9baf: +case 0x9da8: +case 0x9da9: +case 0x9daa: +case 0x9dab: +case 0x9dac: +case 0x9dad: +case 0x9dae: +case 0x9daf: +case 0x9fa8: +case 0x9fa9: +case 0x9faa: +case 0x9fab: +case 0x9fac: +case 0x9fad: +case 0x9fae: +case 0x9faf: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xd1b0: +case 0xd1b1: +case 0xd1b2: +case 0xd1b3: +case 0xd1b4: +case 0xd1b5: +case 0xd1b6: +case 0xd1b7: +case 0xd3b0: +case 0xd3b1: +case 0xd3b2: +case 0xd3b3: +case 0xd3b4: +case 0xd3b5: +case 0xd3b6: +case 0xd3b7: +case 0xd5b0: +case 0xd5b1: +case 0xd5b2: +case 0xd5b3: +case 0xd5b4: +case 0xd5b5: +case 0xd5b6: +case 0xd5b7: +case 0xd7b0: +case 0xd7b1: +case 0xd7b2: +case 0xd7b3: +case 0xd7b4: +case 0xd7b5: +case 0xd7b6: +case 0xd7b7: +case 0xd9b0: +case 0xd9b1: +case 0xd9b2: +case 0xd9b3: +case 0xd9b4: +case 0xd9b5: +case 0xd9b6: +case 0xd9b7: +case 0xdbb0: +case 0xdbb1: +case 0xdbb2: +case 0xdbb3: +case 0xdbb4: +case 0xdbb5: +case 0xdbb6: +case 0xdbb7: +case 0xddb0: +case 0xddb1: +case 0xddb2: +case 0xddb3: +case 0xddb4: +case 0xddb5: +case 0xddb6: +case 0xddb7: +case 0xdfb0: +case 0xdfb1: +case 0xdfb2: +case 0xdfb3: +case 0xdfb4: +case 0xdfb5: +case 0xdfb6: +case 0xdfb7: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0xc1b0: +case 0xc1b1: +case 0xc1b2: +case 0xc1b3: +case 0xc1b4: +case 0xc1b5: +case 0xc1b6: +case 0xc1b7: +case 0xc3b0: +case 0xc3b1: +case 0xc3b2: +case 0xc3b3: +case 0xc3b4: +case 0xc3b5: +case 0xc3b6: +case 0xc3b7: +case 0xc5b0: +case 0xc5b1: +case 0xc5b2: +case 0xc5b3: +case 0xc5b4: +case 0xc5b5: +case 0xc5b6: +case 0xc5b7: +case 0xc7b0: +case 0xc7b1: +case 0xc7b2: +case 0xc7b3: +case 0xc7b4: +case 0xc7b5: +case 0xc7b6: +case 0xc7b7: +case 0xc9b0: +case 0xc9b1: +case 0xc9b2: +case 0xc9b3: +case 0xc9b4: +case 0xc9b5: +case 0xc9b6: +case 0xc9b7: +case 0xcbb0: +case 0xcbb1: +case 0xcbb2: +case 0xcbb3: +case 0xcbb4: +case 0xcbb5: +case 0xcbb6: +case 0xcbb7: +case 0xcdb0: +case 0xcdb1: +case 0xcdb2: +case 0xcdb3: +case 0xcdb4: +case 0xcdb5: +case 0xcdb6: +case 0xcdb7: +case 0xcfb0: +case 0xcfb1: +case 0xcfb2: +case 0xcfb3: +case 0xcfb4: +case 0xcfb5: +case 0xcfb6: +case 0xcfb7: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0xb1b0: +case 0xb1b1: +case 0xb1b2: +case 0xb1b3: +case 0xb1b4: +case 0xb1b5: +case 0xb1b6: +case 0xb1b7: +case 0xb3b0: +case 0xb3b1: +case 0xb3b2: +case 0xb3b3: +case 0xb3b4: +case 0xb3b5: +case 0xb3b6: +case 0xb3b7: +case 0xb5b0: +case 0xb5b1: +case 0xb5b2: +case 0xb5b3: +case 0xb5b4: +case 0xb5b5: +case 0xb5b6: +case 0xb5b7: +case 0xb7b0: +case 0xb7b1: +case 0xb7b2: +case 0xb7b3: +case 0xb7b4: +case 0xb7b5: +case 0xb7b6: +case 0xb7b7: +case 0xb9b0: +case 0xb9b1: +case 0xb9b2: +case 0xb9b3: +case 0xb9b4: +case 0xb9b5: +case 0xb9b6: +case 0xb9b7: +case 0xbbb0: +case 0xbbb1: +case 0xbbb2: +case 0xbbb3: +case 0xbbb4: +case 0xbbb5: +case 0xbbb6: +case 0xbbb7: +case 0xbdb0: +case 0xbdb1: +case 0xbdb2: +case 0xbdb3: +case 0xbdb4: +case 0xbdb5: +case 0xbdb6: +case 0xbdb7: +case 0xbfb0: +case 0xbfb1: +case 0xbfb2: +case 0xbfb3: +case 0xbfb4: +case 0xbfb5: +case 0xbfb6: +case 0xbfb7: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x81b0: +case 0x81b1: +case 0x81b2: +case 0x81b3: +case 0x81b4: +case 0x81b5: +case 0x81b6: +case 0x81b7: +case 0x83b0: +case 0x83b1: +case 0x83b2: +case 0x83b3: +case 0x83b4: +case 0x83b5: +case 0x83b6: +case 0x83b7: +case 0x85b0: +case 0x85b1: +case 0x85b2: +case 0x85b3: +case 0x85b4: +case 0x85b5: +case 0x85b6: +case 0x85b7: +case 0x87b0: +case 0x87b1: +case 0x87b2: +case 0x87b3: +case 0x87b4: +case 0x87b5: +case 0x87b6: +case 0x87b7: +case 0x89b0: +case 0x89b1: +case 0x89b2: +case 0x89b3: +case 0x89b4: +case 0x89b5: +case 0x89b6: +case 0x89b7: +case 0x8bb0: +case 0x8bb1: +case 0x8bb2: +case 0x8bb3: +case 0x8bb4: +case 0x8bb5: +case 0x8bb6: +case 0x8bb7: +case 0x8db0: +case 0x8db1: +case 0x8db2: +case 0x8db3: +case 0x8db4: +case 0x8db5: +case 0x8db6: +case 0x8db7: +case 0x8fb0: +case 0x8fb1: +case 0x8fb2: +case 0x8fb3: +case 0x8fb4: +case 0x8fb5: +case 0x8fb6: +case 0x8fb7: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x91b0: +case 0x91b1: +case 0x91b2: +case 0x91b3: +case 0x91b4: +case 0x91b5: +case 0x91b6: +case 0x91b7: +case 0x93b0: +case 0x93b1: +case 0x93b2: +case 0x93b3: +case 0x93b4: +case 0x93b5: +case 0x93b6: +case 0x93b7: +case 0x95b0: +case 0x95b1: +case 0x95b2: +case 0x95b3: +case 0x95b4: +case 0x95b5: +case 0x95b6: +case 0x95b7: +case 0x97b0: +case 0x97b1: +case 0x97b2: +case 0x97b3: +case 0x97b4: +case 0x97b5: +case 0x97b6: +case 0x97b7: +case 0x99b0: +case 0x99b1: +case 0x99b2: +case 0x99b3: +case 0x99b4: +case 0x99b5: +case 0x99b6: +case 0x99b7: +case 0x9bb0: +case 0x9bb1: +case 0x9bb2: +case 0x9bb3: +case 0x9bb4: +case 0x9bb5: +case 0x9bb6: +case 0x9bb7: +case 0x9db0: +case 0x9db1: +case 0x9db2: +case 0x9db3: +case 0x9db4: +case 0x9db5: +case 0x9db6: +case 0x9db7: +case 0x9fb0: +case 0x9fb1: +case 0x9fb2: +case 0x9fb3: +case 0x9fb4: +case 0x9fb5: +case 0x9fb6: +case 0x9fb7: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xd198: +case 0xd199: +case 0xd19a: +case 0xd19b: +case 0xd19c: +case 0xd19d: +case 0xd19e: +case 0xd19f: +case 0xd398: +case 0xd399: +case 0xd39a: +case 0xd39b: +case 0xd39c: +case 0xd39d: +case 0xd39e: +case 0xd39f: +case 0xd598: +case 0xd599: +case 0xd59a: +case 0xd59b: +case 0xd59c: +case 0xd59d: +case 0xd59e: +case 0xd59f: +case 0xd798: +case 0xd799: +case 0xd79a: +case 0xd79b: +case 0xd79c: +case 0xd79d: +case 0xd79e: +case 0xd79f: +case 0xd998: +case 0xd999: +case 0xd99a: +case 0xd99b: +case 0xd99c: +case 0xd99d: +case 0xd99e: +case 0xd99f: +case 0xdb98: +case 0xdb99: +case 0xdb9a: +case 0xdb9b: +case 0xdb9c: +case 0xdb9d: +case 0xdb9e: +case 0xdb9f: +case 0xdd98: +case 0xdd99: +case 0xdd9a: +case 0xdd9b: +case 0xdd9c: +case 0xdd9d: +case 0xdd9e: +case 0xdd9f: +case 0xdf98: +case 0xdf99: +case 0xdf9a: +case 0xdf9b: +case 0xdf9c: +case 0xdf9d: +case 0xdf9e: +case 0xdf9f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0xc198: +case 0xc199: +case 0xc19a: +case 0xc19b: +case 0xc19c: +case 0xc19d: +case 0xc19e: +case 0xc19f: +case 0xc398: +case 0xc399: +case 0xc39a: +case 0xc39b: +case 0xc39c: +case 0xc39d: +case 0xc39e: +case 0xc39f: +case 0xc598: +case 0xc599: +case 0xc59a: +case 0xc59b: +case 0xc59c: +case 0xc59d: +case 0xc59e: +case 0xc59f: +case 0xc798: +case 0xc799: +case 0xc79a: +case 0xc79b: +case 0xc79c: +case 0xc79d: +case 0xc79e: +case 0xc79f: +case 0xc998: +case 0xc999: +case 0xc99a: +case 0xc99b: +case 0xc99c: +case 0xc99d: +case 0xc99e: +case 0xc99f: +case 0xcb98: +case 0xcb99: +case 0xcb9a: +case 0xcb9b: +case 0xcb9c: +case 0xcb9d: +case 0xcb9e: +case 0xcb9f: +case 0xcd98: +case 0xcd99: +case 0xcd9a: +case 0xcd9b: +case 0xcd9c: +case 0xcd9d: +case 0xcd9e: +case 0xcd9f: +case 0xcf98: +case 0xcf99: +case 0xcf9a: +case 0xcf9b: +case 0xcf9c: +case 0xcf9d: +case 0xcf9e: +case 0xcf9f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0xb198: +case 0xb199: +case 0xb19a: +case 0xb19b: +case 0xb19c: +case 0xb19d: +case 0xb19e: +case 0xb19f: +case 0xb398: +case 0xb399: +case 0xb39a: +case 0xb39b: +case 0xb39c: +case 0xb39d: +case 0xb39e: +case 0xb39f: +case 0xb598: +case 0xb599: +case 0xb59a: +case 0xb59b: +case 0xb59c: +case 0xb59d: +case 0xb59e: +case 0xb59f: +case 0xb798: +case 0xb799: +case 0xb79a: +case 0xb79b: +case 0xb79c: +case 0xb79d: +case 0xb79e: +case 0xb79f: +case 0xb998: +case 0xb999: +case 0xb99a: +case 0xb99b: +case 0xb99c: +case 0xb99d: +case 0xb99e: +case 0xb99f: +case 0xbb98: +case 0xbb99: +case 0xbb9a: +case 0xbb9b: +case 0xbb9c: +case 0xbb9d: +case 0xbb9e: +case 0xbb9f: +case 0xbd98: +case 0xbd99: +case 0xbd9a: +case 0xbd9b: +case 0xbd9c: +case 0xbd9d: +case 0xbd9e: +case 0xbd9f: +case 0xbf98: +case 0xbf99: +case 0xbf9a: +case 0xbf9b: +case 0xbf9c: +case 0xbf9d: +case 0xbf9e: +case 0xbf9f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x8198: +case 0x8199: +case 0x819a: +case 0x819b: +case 0x819c: +case 0x819d: +case 0x819e: +case 0x819f: +case 0x8398: +case 0x8399: +case 0x839a: +case 0x839b: +case 0x839c: +case 0x839d: +case 0x839e: +case 0x839f: +case 0x8598: +case 0x8599: +case 0x859a: +case 0x859b: +case 0x859c: +case 0x859d: +case 0x859e: +case 0x859f: +case 0x8798: +case 0x8799: +case 0x879a: +case 0x879b: +case 0x879c: +case 0x879d: +case 0x879e: +case 0x879f: +case 0x8998: +case 0x8999: +case 0x899a: +case 0x899b: +case 0x899c: +case 0x899d: +case 0x899e: +case 0x899f: +case 0x8b98: +case 0x8b99: +case 0x8b9a: +case 0x8b9b: +case 0x8b9c: +case 0x8b9d: +case 0x8b9e: +case 0x8b9f: +case 0x8d98: +case 0x8d99: +case 0x8d9a: +case 0x8d9b: +case 0x8d9c: +case 0x8d9d: +case 0x8d9e: +case 0x8d9f: +case 0x8f98: +case 0x8f99: +case 0x8f9a: +case 0x8f9b: +case 0x8f9c: +case 0x8f9d: +case 0x8f9e: +case 0x8f9f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x9198: +case 0x9199: +case 0x919a: +case 0x919b: +case 0x919c: +case 0x919d: +case 0x919e: +case 0x919f: +case 0x9398: +case 0x9399: +case 0x939a: +case 0x939b: +case 0x939c: +case 0x939d: +case 0x939e: +case 0x939f: +case 0x9598: +case 0x9599: +case 0x959a: +case 0x959b: +case 0x959c: +case 0x959d: +case 0x959e: +case 0x959f: +case 0x9798: +case 0x9799: +case 0x979a: +case 0x979b: +case 0x979c: +case 0x979d: +case 0x979e: +case 0x979f: +case 0x9998: +case 0x9999: +case 0x999a: +case 0x999b: +case 0x999c: +case 0x999d: +case 0x999e: +case 0x999f: +case 0x9b98: +case 0x9b99: +case 0x9b9a: +case 0x9b9b: +case 0x9b9c: +case 0x9b9d: +case 0x9b9e: +case 0x9b9f: +case 0x9d98: +case 0x9d99: +case 0x9d9a: +case 0x9d9b: +case 0x9d9c: +case 0x9d9d: +case 0x9d9e: +case 0x9d9f: +case 0x9f98: +case 0x9f99: +case 0x9f9a: +case 0x9f9b: +case 0x9f9c: +case 0x9f9d: +case 0x9f9e: +case 0x9f9f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xd1a0: +case 0xd1a1: +case 0xd1a2: +case 0xd1a3: +case 0xd1a4: +case 0xd1a5: +case 0xd1a6: +case 0xd1a7: +case 0xd3a0: +case 0xd3a1: +case 0xd3a2: +case 0xd3a3: +case 0xd3a4: +case 0xd3a5: +case 0xd3a6: +case 0xd3a7: +case 0xd5a0: +case 0xd5a1: +case 0xd5a2: +case 0xd5a3: +case 0xd5a4: +case 0xd5a5: +case 0xd5a6: +case 0xd5a7: +case 0xd7a0: +case 0xd7a1: +case 0xd7a2: +case 0xd7a3: +case 0xd7a4: +case 0xd7a5: +case 0xd7a6: +case 0xd7a7: +case 0xd9a0: +case 0xd9a1: +case 0xd9a2: +case 0xd9a3: +case 0xd9a4: +case 0xd9a5: +case 0xd9a6: +case 0xd9a7: +case 0xdba0: +case 0xdba1: +case 0xdba2: +case 0xdba3: +case 0xdba4: +case 0xdba5: +case 0xdba6: +case 0xdba7: +case 0xdda0: +case 0xdda1: +case 0xdda2: +case 0xdda3: +case 0xdda4: +case 0xdda5: +case 0xdda6: +case 0xdda7: +case 0xdfa0: +case 0xdfa1: +case 0xdfa2: +case 0xdfa3: +case 0xdfa4: +case 0xdfa5: +case 0xdfa6: +case 0xdfa7: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0xc1a0: +case 0xc1a1: +case 0xc1a2: +case 0xc1a3: +case 0xc1a4: +case 0xc1a5: +case 0xc1a6: +case 0xc1a7: +case 0xc3a0: +case 0xc3a1: +case 0xc3a2: +case 0xc3a3: +case 0xc3a4: +case 0xc3a5: +case 0xc3a6: +case 0xc3a7: +case 0xc5a0: +case 0xc5a1: +case 0xc5a2: +case 0xc5a3: +case 0xc5a4: +case 0xc5a5: +case 0xc5a6: +case 0xc5a7: +case 0xc7a0: +case 0xc7a1: +case 0xc7a2: +case 0xc7a3: +case 0xc7a4: +case 0xc7a5: +case 0xc7a6: +case 0xc7a7: +case 0xc9a0: +case 0xc9a1: +case 0xc9a2: +case 0xc9a3: +case 0xc9a4: +case 0xc9a5: +case 0xc9a6: +case 0xc9a7: +case 0xcba0: +case 0xcba1: +case 0xcba2: +case 0xcba3: +case 0xcba4: +case 0xcba5: +case 0xcba6: +case 0xcba7: +case 0xcda0: +case 0xcda1: +case 0xcda2: +case 0xcda3: +case 0xcda4: +case 0xcda5: +case 0xcda6: +case 0xcda7: +case 0xcfa0: +case 0xcfa1: +case 0xcfa2: +case 0xcfa3: +case 0xcfa4: +case 0xcfa5: +case 0xcfa6: +case 0xcfa7: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0xb1a0: +case 0xb1a1: +case 0xb1a2: +case 0xb1a3: +case 0xb1a4: +case 0xb1a5: +case 0xb1a6: +case 0xb1a7: +case 0xb3a0: +case 0xb3a1: +case 0xb3a2: +case 0xb3a3: +case 0xb3a4: +case 0xb3a5: +case 0xb3a6: +case 0xb3a7: +case 0xb5a0: +case 0xb5a1: +case 0xb5a2: +case 0xb5a3: +case 0xb5a4: +case 0xb5a5: +case 0xb5a6: +case 0xb5a7: +case 0xb7a0: +case 0xb7a1: +case 0xb7a2: +case 0xb7a3: +case 0xb7a4: +case 0xb7a5: +case 0xb7a6: +case 0xb7a7: +case 0xb9a0: +case 0xb9a1: +case 0xb9a2: +case 0xb9a3: +case 0xb9a4: +case 0xb9a5: +case 0xb9a6: +case 0xb9a7: +case 0xbba0: +case 0xbba1: +case 0xbba2: +case 0xbba3: +case 0xbba4: +case 0xbba5: +case 0xbba6: +case 0xbba7: +case 0xbda0: +case 0xbda1: +case 0xbda2: +case 0xbda3: +case 0xbda4: +case 0xbda5: +case 0xbda6: +case 0xbda7: +case 0xbfa0: +case 0xbfa1: +case 0xbfa2: +case 0xbfa3: +case 0xbfa4: +case 0xbfa5: +case 0xbfa6: +case 0xbfa7: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x81a0: +case 0x81a1: +case 0x81a2: +case 0x81a3: +case 0x81a4: +case 0x81a5: +case 0x81a6: +case 0x81a7: +case 0x83a0: +case 0x83a1: +case 0x83a2: +case 0x83a3: +case 0x83a4: +case 0x83a5: +case 0x83a6: +case 0x83a7: +case 0x85a0: +case 0x85a1: +case 0x85a2: +case 0x85a3: +case 0x85a4: +case 0x85a5: +case 0x85a6: +case 0x85a7: +case 0x87a0: +case 0x87a1: +case 0x87a2: +case 0x87a3: +case 0x87a4: +case 0x87a5: +case 0x87a6: +case 0x87a7: +case 0x89a0: +case 0x89a1: +case 0x89a2: +case 0x89a3: +case 0x89a4: +case 0x89a5: +case 0x89a6: +case 0x89a7: +case 0x8ba0: +case 0x8ba1: +case 0x8ba2: +case 0x8ba3: +case 0x8ba4: +case 0x8ba5: +case 0x8ba6: +case 0x8ba7: +case 0x8da0: +case 0x8da1: +case 0x8da2: +case 0x8da3: +case 0x8da4: +case 0x8da5: +case 0x8da6: +case 0x8da7: +case 0x8fa0: +case 0x8fa1: +case 0x8fa2: +case 0x8fa3: +case 0x8fa4: +case 0x8fa5: +case 0x8fa6: +case 0x8fa7: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x91a0: +case 0x91a1: +case 0x91a2: +case 0x91a3: +case 0x91a4: +case 0x91a5: +case 0x91a6: +case 0x91a7: +case 0x93a0: +case 0x93a1: +case 0x93a2: +case 0x93a3: +case 0x93a4: +case 0x93a5: +case 0x93a6: +case 0x93a7: +case 0x95a0: +case 0x95a1: +case 0x95a2: +case 0x95a3: +case 0x95a4: +case 0x95a5: +case 0x95a6: +case 0x95a7: +case 0x97a0: +case 0x97a1: +case 0x97a2: +case 0x97a3: +case 0x97a4: +case 0x97a5: +case 0x97a6: +case 0x97a7: +case 0x99a0: +case 0x99a1: +case 0x99a2: +case 0x99a3: +case 0x99a4: +case 0x99a5: +case 0x99a6: +case 0x99a7: +case 0x9ba0: +case 0x9ba1: +case 0x9ba2: +case 0x9ba3: +case 0x9ba4: +case 0x9ba5: +case 0x9ba6: +case 0x9ba7: +case 0x9da0: +case 0x9da1: +case 0x9da2: +case 0x9da3: +case 0x9da4: +case 0x9da5: +case 0x9da6: +case 0x9da7: +case 0x9fa0: +case 0x9fa1: +case 0x9fa2: +case 0x9fa3: +case 0x9fa4: +case 0x9fa5: +case 0x9fa6: +case 0x9fa7: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xb180: +case 0xb181: +case 0xb182: +case 0xb183: +case 0xb184: +case 0xb185: +case 0xb186: +case 0xb187: +case 0xb380: +case 0xb381: +case 0xb382: +case 0xb383: +case 0xb384: +case 0xb385: +case 0xb386: +case 0xb387: +case 0xb580: +case 0xb581: +case 0xb582: +case 0xb583: +case 0xb584: +case 0xb585: +case 0xb586: +case 0xb587: +case 0xb780: +case 0xb781: +case 0xb782: +case 0xb783: +case 0xb784: +case 0xb785: +case 0xb786: +case 0xb787: +case 0xb980: +case 0xb981: +case 0xb982: +case 0xb983: +case 0xb984: +case 0xb985: +case 0xb986: +case 0xb987: +case 0xbb80: +case 0xbb81: +case 0xbb82: +case 0xbb83: +case 0xbb84: +case 0xbb85: +case 0xbb86: +case 0xbb87: +case 0xbd80: +case 0xbd81: +case 0xbd82: +case 0xbd83: +case 0xbd84: +case 0xbd85: +case 0xbd86: +case 0xbd87: +case 0xbf80: +case 0xbf81: +case 0xbf82: +case 0xbf83: +case 0xbf84: +case 0xbf85: +case 0xbf86: +case 0xbf87: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x23c0: +case 0x23c1: +case 0x23c2: +case 0x23c3: +case 0x23c4: +case 0x23c5: +case 0x23c6: +case 0x23c7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x21c0: +case 0x21c1: +case 0x21c2: +case 0x21c3: +case 0x21c4: +case 0x21c5: +case 0x21c6: +case 0x21c7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0xd1c0: +case 0xd1c1: +case 0xd1c2: +case 0xd1c3: +case 0xd1c4: +case 0xd1c5: +case 0xd1c6: +case 0xd1c7: +case 0xd3c0: +case 0xd3c1: +case 0xd3c2: +case 0xd3c3: +case 0xd3c4: +case 0xd3c5: +case 0xd3c6: +case 0xd3c7: +case 0xd5c0: +case 0xd5c1: +case 0xd5c2: +case 0xd5c3: +case 0xd5c4: +case 0xd5c5: +case 0xd5c6: +case 0xd5c7: +case 0xd7c0: +case 0xd7c1: +case 0xd7c2: +case 0xd7c3: +case 0xd7c4: +case 0xd7c5: +case 0xd7c6: +case 0xd7c7: +case 0xd9c0: +case 0xd9c1: +case 0xd9c2: +case 0xd9c3: +case 0xd9c4: +case 0xd9c5: +case 0xd9c6: +case 0xd9c7: +case 0xdbc0: +case 0xdbc1: +case 0xdbc2: +case 0xdbc3: +case 0xdbc4: +case 0xdbc5: +case 0xdbc6: +case 0xdbc7: +case 0xddc0: +case 0xddc1: +case 0xddc2: +case 0xddc3: +case 0xddc4: +case 0xddc5: +case 0xddc6: +case 0xddc7: +case 0xdfc0: +case 0xdfc1: +case 0xdfc2: +case 0xdfc3: +case 0xdfc4: +case 0xdfc5: +case 0xdfc6: +case 0xdfc7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb1c0: +case 0xb1c1: +case 0xb1c2: +case 0xb1c3: +case 0xb1c4: +case 0xb1c5: +case 0xb1c6: +case 0xb1c7: +case 0xb3c0: +case 0xb3c1: +case 0xb3c2: +case 0xb3c3: +case 0xb3c4: +case 0xb3c5: +case 0xb3c6: +case 0xb3c7: +case 0xb5c0: +case 0xb5c1: +case 0xb5c2: +case 0xb5c3: +case 0xb5c4: +case 0xb5c5: +case 0xb5c6: +case 0xb5c7: +case 0xb7c0: +case 0xb7c1: +case 0xb7c2: +case 0xb7c3: +case 0xb7c4: +case 0xb7c5: +case 0xb7c6: +case 0xb7c7: +case 0xb9c0: +case 0xb9c1: +case 0xb9c2: +case 0xb9c3: +case 0xb9c4: +case 0xb9c5: +case 0xb9c6: +case 0xb9c7: +case 0xbbc0: +case 0xbbc1: +case 0xbbc2: +case 0xbbc3: +case 0xbbc4: +case 0xbbc5: +case 0xbbc6: +case 0xbbc7: +case 0xbdc0: +case 0xbdc1: +case 0xbdc2: +case 0xbdc3: +case 0xbdc4: +case 0xbdc5: +case 0xbdc6: +case 0xbdc7: +case 0xbfc0: +case 0xbfc1: +case 0xbfc2: +case 0xbfc3: +case 0xbfc4: +case 0xbfc5: +case 0xbfc6: +case 0xbfc7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x91c0: +case 0x91c1: +case 0x91c2: +case 0x91c3: +case 0x91c4: +case 0x91c5: +case 0x91c6: +case 0x91c7: +case 0x93c0: +case 0x93c1: +case 0x93c2: +case 0x93c3: +case 0x93c4: +case 0x93c5: +case 0x93c6: +case 0x93c7: +case 0x95c0: +case 0x95c1: +case 0x95c2: +case 0x95c3: +case 0x95c4: +case 0x95c5: +case 0x95c6: +case 0x95c7: +case 0x97c0: +case 0x97c1: +case 0x97c2: +case 0x97c3: +case 0x97c4: +case 0x97c5: +case 0x97c6: +case 0x97c7: +case 0x99c0: +case 0x99c1: +case 0x99c2: +case 0x99c3: +case 0x99c4: +case 0x99c5: +case 0x99c6: +case 0x99c7: +case 0x9bc0: +case 0x9bc1: +case 0x9bc2: +case 0x9bc3: +case 0x9bc4: +case 0x9bc5: +case 0x9bc6: +case 0x9bc7: +case 0x9dc0: +case 0x9dc1: +case 0x9dc2: +case 0x9dc3: +case 0x9dc4: +case 0x9dc5: +case 0x9dc6: +case 0x9dc7: +case 0x9fc0: +case 0x9fc1: +case 0x9fc2: +case 0x9fc3: +case 0x9fc4: +case 0x9fc5: +case 0x9fc6: +case 0x9fc7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x2080: +case 0x2081: +case 0x2082: +case 0x2083: +case 0x2084: +case 0x2085: +case 0x2086: +case 0x2087: +case 0x2280: +case 0x2281: +case 0x2282: +case 0x2283: +case 0x2284: +case 0x2285: +case 0x2286: +case 0x2287: +case 0x2480: +case 0x2481: +case 0x2482: +case 0x2483: +case 0x2484: +case 0x2485: +case 0x2486: +case 0x2487: +case 0x2680: +case 0x2681: +case 0x2682: +case 0x2683: +case 0x2684: +case 0x2685: +case 0x2686: +case 0x2687: +case 0x2880: +case 0x2881: +case 0x2882: +case 0x2883: +case 0x2884: +case 0x2885: +case 0x2886: +case 0x2887: +case 0x2a80: +case 0x2a81: +case 0x2a82: +case 0x2a83: +case 0x2a84: +case 0x2a85: +case 0x2a86: +case 0x2a87: +case 0x2c80: +case 0x2c81: +case 0x2c82: +case 0x2c83: +case 0x2c84: +case 0x2c85: +case 0x2c86: +case 0x2c87: +case 0x2e80: +case 0x2e81: +case 0x2e82: +case 0x2e83: +case 0x2e84: +case 0x2e85: +case 0x2e86: +case 0x2e87: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2140: +case 0x2141: +case 0x2142: +case 0x2143: +case 0x2144: +case 0x2145: +case 0x2146: +case 0x2147: +case 0x2340: +case 0x2341: +case 0x2342: +case 0x2343: +case 0x2344: +case 0x2345: +case 0x2346: +case 0x2347: +case 0x2540: +case 0x2541: +case 0x2542: +case 0x2543: +case 0x2544: +case 0x2545: +case 0x2546: +case 0x2547: +case 0x2740: +case 0x2741: +case 0x2742: +case 0x2743: +case 0x2744: +case 0x2745: +case 0x2746: +case 0x2747: +case 0x2940: +case 0x2941: +case 0x2942: +case 0x2943: +case 0x2944: +case 0x2945: +case 0x2946: +case 0x2947: +case 0x2b40: +case 0x2b41: +case 0x2b42: +case 0x2b43: +case 0x2b44: +case 0x2b45: +case 0x2b46: +case 0x2b47: +case 0x2d40: +case 0x2d41: +case 0x2d42: +case 0x2d43: +case 0x2d44: +case 0x2d45: +case 0x2d46: +case 0x2d47: +case 0x2f40: +case 0x2f41: +case 0x2f42: +case 0x2f43: +case 0x2f44: +case 0x2f45: +case 0x2f46: +case 0x2f47: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2180: +case 0x2181: +case 0x2182: +case 0x2183: +case 0x2184: +case 0x2185: +case 0x2186: +case 0x2187: +case 0x2380: +case 0x2381: +case 0x2382: +case 0x2383: +case 0x2384: +case 0x2385: +case 0x2386: +case 0x2387: +case 0x2580: +case 0x2581: +case 0x2582: +case 0x2583: +case 0x2584: +case 0x2585: +case 0x2586: +case 0x2587: +case 0x2780: +case 0x2781: +case 0x2782: +case 0x2783: +case 0x2784: +case 0x2785: +case 0x2786: +case 0x2787: +case 0x2980: +case 0x2981: +case 0x2982: +case 0x2983: +case 0x2984: +case 0x2985: +case 0x2986: +case 0x2987: +case 0x2b80: +case 0x2b81: +case 0x2b82: +case 0x2b83: +case 0x2b84: +case 0x2b85: +case 0x2b86: +case 0x2b87: +case 0x2d80: +case 0x2d81: +case 0x2d82: +case 0x2d83: +case 0x2d84: +case 0x2d85: +case 0x2d86: +case 0x2d87: +case 0x2f80: +case 0x2f81: +case 0x2f82: +case 0x2f83: +case 0x2f84: +case 0x2f85: +case 0x2f86: +case 0x2f87: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x20c0: +case 0x20c1: +case 0x20c2: +case 0x20c3: +case 0x20c4: +case 0x20c5: +case 0x20c6: +case 0x20c7: +case 0x22c0: +case 0x22c1: +case 0x22c2: +case 0x22c3: +case 0x22c4: +case 0x22c5: +case 0x22c6: +case 0x22c7: +case 0x24c0: +case 0x24c1: +case 0x24c2: +case 0x24c3: +case 0x24c4: +case 0x24c5: +case 0x24c6: +case 0x24c7: +case 0x26c0: +case 0x26c1: +case 0x26c2: +case 0x26c3: +case 0x26c4: +case 0x26c5: +case 0x26c6: +case 0x26c7: +case 0x28c0: +case 0x28c1: +case 0x28c2: +case 0x28c3: +case 0x28c4: +case 0x28c5: +case 0x28c6: +case 0x28c7: +case 0x2ac0: +case 0x2ac1: +case 0x2ac2: +case 0x2ac3: +case 0x2ac4: +case 0x2ac5: +case 0x2ac6: +case 0x2ac7: +case 0x2cc0: +case 0x2cc1: +case 0x2cc2: +case 0x2cc3: +case 0x2cc4: +case 0x2cc5: +case 0x2cc6: +case 0x2cc7: +case 0x2ec0: +case 0x2ec1: +case 0x2ec2: +case 0x2ec3: +case 0x2ec4: +case 0x2ec5: +case 0x2ec6: +case 0x2ec7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x2100: +case 0x2101: +case 0x2102: +case 0x2103: +case 0x2104: +case 0x2105: +case 0x2106: +case 0x2107: +case 0x2300: +case 0x2301: +case 0x2302: +case 0x2303: +case 0x2304: +case 0x2305: +case 0x2306: +case 0x2307: +case 0x2500: +case 0x2501: +case 0x2502: +case 0x2503: +case 0x2504: +case 0x2505: +case 0x2506: +case 0x2507: +case 0x2700: +case 0x2701: +case 0x2702: +case 0x2703: +case 0x2704: +case 0x2705: +case 0x2706: +case 0x2707: +case 0x2900: +case 0x2901: +case 0x2902: +case 0x2903: +case 0x2904: +case 0x2905: +case 0x2906: +case 0x2907: +case 0x2b00: +case 0x2b01: +case 0x2b02: +case 0x2b03: +case 0x2b04: +case 0x2b05: +case 0x2b06: +case 0x2b07: +case 0x2d00: +case 0x2d01: +case 0x2d02: +case 0x2d03: +case 0x2d04: +case 0x2d05: +case 0x2d06: +case 0x2d07: +case 0x2f00: +case 0x2f01: +case 0x2f02: +case 0x2f03: +case 0x2f04: +case 0x2f05: +case 0x2f06: +case 0x2f07: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd080: +case 0xd081: +case 0xd082: +case 0xd083: +case 0xd084: +case 0xd085: +case 0xd086: +case 0xd087: +case 0xd280: +case 0xd281: +case 0xd282: +case 0xd283: +case 0xd284: +case 0xd285: +case 0xd286: +case 0xd287: +case 0xd480: +case 0xd481: +case 0xd482: +case 0xd483: +case 0xd484: +case 0xd485: +case 0xd486: +case 0xd487: +case 0xd680: +case 0xd681: +case 0xd682: +case 0xd683: +case 0xd684: +case 0xd685: +case 0xd686: +case 0xd687: +case 0xd880: +case 0xd881: +case 0xd882: +case 0xd883: +case 0xd884: +case 0xd885: +case 0xd886: +case 0xd887: +case 0xda80: +case 0xda81: +case 0xda82: +case 0xda83: +case 0xda84: +case 0xda85: +case 0xda86: +case 0xda87: +case 0xdc80: +case 0xdc81: +case 0xdc82: +case 0xdc83: +case 0xdc84: +case 0xdc85: +case 0xdc86: +case 0xdc87: +case 0xde80: +case 0xde81: +case 0xde82: +case 0xde83: +case 0xde84: +case 0xde85: +case 0xde86: +case 0xde87: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xd180: +case 0xd181: +case 0xd182: +case 0xd183: +case 0xd184: +case 0xd185: +case 0xd186: +case 0xd187: +case 0xd380: +case 0xd381: +case 0xd382: +case 0xd383: +case 0xd384: +case 0xd385: +case 0xd386: +case 0xd387: +case 0xd580: +case 0xd581: +case 0xd582: +case 0xd583: +case 0xd584: +case 0xd585: +case 0xd586: +case 0xd587: +case 0xd780: +case 0xd781: +case 0xd782: +case 0xd783: +case 0xd784: +case 0xd785: +case 0xd786: +case 0xd787: +case 0xd980: +case 0xd981: +case 0xd982: +case 0xd983: +case 0xd984: +case 0xd985: +case 0xd986: +case 0xd987: +case 0xdb80: +case 0xdb81: +case 0xdb82: +case 0xdb83: +case 0xdb84: +case 0xdb85: +case 0xdb86: +case 0xdb87: +case 0xdd80: +case 0xdd81: +case 0xdd82: +case 0xdd83: +case 0xdd84: +case 0xdd85: +case 0xdd86: +case 0xdd87: +case 0xdf80: +case 0xdf81: +case 0xdf82: +case 0xdf83: +case 0xdf84: +case 0xdf85: +case 0xdf86: +case 0xdf87: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADDX(src, dst); + } + break; + +case 0xc080: +case 0xc081: +case 0xc082: +case 0xc083: +case 0xc084: +case 0xc085: +case 0xc086: +case 0xc087: +case 0xc280: +case 0xc281: +case 0xc282: +case 0xc283: +case 0xc284: +case 0xc285: +case 0xc286: +case 0xc287: +case 0xc480: +case 0xc481: +case 0xc482: +case 0xc483: +case 0xc484: +case 0xc485: +case 0xc486: +case 0xc487: +case 0xc680: +case 0xc681: +case 0xc682: +case 0xc683: +case 0xc684: +case 0xc685: +case 0xc686: +case 0xc687: +case 0xc880: +case 0xc881: +case 0xc882: +case 0xc883: +case 0xc884: +case 0xc885: +case 0xc886: +case 0xc887: +case 0xca80: +case 0xca81: +case 0xca82: +case 0xca83: +case 0xca84: +case 0xca85: +case 0xca86: +case 0xca87: +case 0xcc80: +case 0xcc81: +case 0xcc82: +case 0xcc83: +case 0xcc84: +case 0xcc85: +case 0xcc86: +case 0xcc87: +case 0xce80: +case 0xce81: +case 0xce82: +case 0xce83: +case 0xce84: +case 0xce85: +case 0xce86: +case 0xce87: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb080: +case 0xb081: +case 0xb082: +case 0xb083: +case 0xb084: +case 0xb085: +case 0xb086: +case 0xb087: +case 0xb280: +case 0xb281: +case 0xb282: +case 0xb283: +case 0xb284: +case 0xb285: +case 0xb286: +case 0xb287: +case 0xb480: +case 0xb481: +case 0xb482: +case 0xb483: +case 0xb484: +case 0xb485: +case 0xb486: +case 0xb487: +case 0xb680: +case 0xb681: +case 0xb682: +case 0xb683: +case 0xb684: +case 0xb685: +case 0xb686: +case 0xb687: +case 0xb880: +case 0xb881: +case 0xb882: +case 0xb883: +case 0xb884: +case 0xb885: +case 0xb886: +case 0xb887: +case 0xba80: +case 0xba81: +case 0xba82: +case 0xba83: +case 0xba84: +case 0xba85: +case 0xba86: +case 0xba87: +case 0xbc80: +case 0xbc81: +case 0xbc82: +case 0xbc83: +case 0xbc84: +case 0xbc85: +case 0xbc86: +case 0xbc87: +case 0xbe80: +case 0xbe81: +case 0xbe82: +case 0xbe83: +case 0xbe84: +case 0xbe85: +case 0xbe86: +case 0xbe87: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x2000: +case 0x2001: +case 0x2002: +case 0x2003: +case 0x2004: +case 0x2005: +case 0x2006: +case 0x2007: +case 0x2200: +case 0x2201: +case 0x2202: +case 0x2203: +case 0x2204: +case 0x2205: +case 0x2206: +case 0x2207: +case 0x2400: +case 0x2401: +case 0x2402: +case 0x2403: +case 0x2404: +case 0x2405: +case 0x2406: +case 0x2407: +case 0x2600: +case 0x2601: +case 0x2602: +case 0x2603: +case 0x2604: +case 0x2605: +case 0x2606: +case 0x2607: +case 0x2800: +case 0x2801: +case 0x2802: +case 0x2803: +case 0x2804: +case 0x2805: +case 0x2806: +case 0x2807: +case 0x2a00: +case 0x2a01: +case 0x2a02: +case 0x2a03: +case 0x2a04: +case 0x2a05: +case 0x2a06: +case 0x2a07: +case 0x2c00: +case 0x2c01: +case 0x2c02: +case 0x2c03: +case 0x2c04: +case 0x2c05: +case 0x2c06: +case 0x2c07: +case 0x2e00: +case 0x2e01: +case 0x2e02: +case 0x2e03: +case 0x2e04: +case 0x2e05: +case 0x2e06: +case 0x2e07: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8080: +case 0x8081: +case 0x8082: +case 0x8083: +case 0x8084: +case 0x8085: +case 0x8086: +case 0x8087: +case 0x8280: +case 0x8281: +case 0x8282: +case 0x8283: +case 0x8284: +case 0x8285: +case 0x8286: +case 0x8287: +case 0x8480: +case 0x8481: +case 0x8482: +case 0x8483: +case 0x8484: +case 0x8485: +case 0x8486: +case 0x8487: +case 0x8680: +case 0x8681: +case 0x8682: +case 0x8683: +case 0x8684: +case 0x8685: +case 0x8686: +case 0x8687: +case 0x8880: +case 0x8881: +case 0x8882: +case 0x8883: +case 0x8884: +case 0x8885: +case 0x8886: +case 0x8887: +case 0x8a80: +case 0x8a81: +case 0x8a82: +case 0x8a83: +case 0x8a84: +case 0x8a85: +case 0x8a86: +case 0x8a87: +case 0x8c80: +case 0x8c81: +case 0x8c82: +case 0x8c83: +case 0x8c84: +case 0x8c85: +case 0x8c86: +case 0x8c87: +case 0x8e80: +case 0x8e81: +case 0x8e82: +case 0x8e83: +case 0x8e84: +case 0x8e85: +case 0x8e86: +case 0x8e87: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9080: +case 0x9081: +case 0x9082: +case 0x9083: +case 0x9084: +case 0x9085: +case 0x9086: +case 0x9087: +case 0x9280: +case 0x9281: +case 0x9282: +case 0x9283: +case 0x9284: +case 0x9285: +case 0x9286: +case 0x9287: +case 0x9480: +case 0x9481: +case 0x9482: +case 0x9483: +case 0x9484: +case 0x9485: +case 0x9486: +case 0x9487: +case 0x9680: +case 0x9681: +case 0x9682: +case 0x9683: +case 0x9684: +case 0x9685: +case 0x9686: +case 0x9687: +case 0x9880: +case 0x9881: +case 0x9882: +case 0x9883: +case 0x9884: +case 0x9885: +case 0x9886: +case 0x9887: +case 0x9a80: +case 0x9a81: +case 0x9a82: +case 0x9a83: +case 0x9a84: +case 0x9a85: +case 0x9a86: +case 0x9a87: +case 0x9c80: +case 0x9c81: +case 0x9c82: +case 0x9c83: +case 0x9c84: +case 0x9c85: +case 0x9c86: +case 0x9c87: +case 0x9e80: +case 0x9e81: +case 0x9e82: +case 0x9e83: +case 0x9e84: +case 0x9e85: +case 0x9e86: +case 0x9e87: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x9180: +case 0x9181: +case 0x9182: +case 0x9183: +case 0x9184: +case 0x9185: +case 0x9186: +case 0x9187: +case 0x9380: +case 0x9381: +case 0x9382: +case 0x9383: +case 0x9384: +case 0x9385: +case 0x9386: +case 0x9387: +case 0x9580: +case 0x9581: +case 0x9582: +case 0x9583: +case 0x9584: +case 0x9585: +case 0x9586: +case 0x9587: +case 0x9780: +case 0x9781: +case 0x9782: +case 0x9783: +case 0x9784: +case 0x9785: +case 0x9786: +case 0x9787: +case 0x9980: +case 0x9981: +case 0x9982: +case 0x9983: +case 0x9984: +case 0x9985: +case 0x9986: +case 0x9987: +case 0x9b80: +case 0x9b81: +case 0x9b82: +case 0x9b83: +case 0x9b84: +case 0x9b85: +case 0x9b86: +case 0x9b87: +case 0x9d80: +case 0x9d81: +case 0x9d82: +case 0x9d83: +case 0x9d84: +case 0x9d85: +case 0x9d86: +case 0x9d87: +case 0x9f80: +case 0x9f81: +case 0x9f82: +case 0x9f83: +case 0x9f84: +case 0x9f85: +case 0x9f86: +case 0x9f87: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUBX(src, dst); + } + break; + +case 0x2040: +case 0x2041: +case 0x2042: +case 0x2043: +case 0x2044: +case 0x2045: +case 0x2046: +case 0x2047: +case 0x2240: +case 0x2241: +case 0x2242: +case 0x2243: +case 0x2244: +case 0x2245: +case 0x2246: +case 0x2247: +case 0x2440: +case 0x2441: +case 0x2442: +case 0x2443: +case 0x2444: +case 0x2445: +case 0x2446: +case 0x2447: +case 0x2640: +case 0x2641: +case 0x2642: +case 0x2643: +case 0x2644: +case 0x2645: +case 0x2646: +case 0x2647: +case 0x2840: +case 0x2841: +case 0x2842: +case 0x2843: +case 0x2844: +case 0x2845: +case 0x2846: +case 0x2847: +case 0x2a40: +case 0x2a41: +case 0x2a42: +case 0x2a43: +case 0x2a44: +case 0x2a45: +case 0x2a46: +case 0x2a47: +case 0x2c40: +case 0x2c41: +case 0x2c42: +case 0x2c43: +case 0x2c44: +case 0x2c45: +case 0x2c46: +case 0x2c47: +case 0x2e40: +case 0x2e41: +case 0x2e42: +case 0x2e43: +case 0x2e44: +case 0x2e45: +case 0x2e46: +case 0x2e47: + { + HAM src(this, instr_b2_b0); MOVEA(src, instr_b11_b9); + } + break; + +case 0xe1a0: +case 0xe1a1: +case 0xe1a2: +case 0xe1a3: +case 0xe1a4: +case 0xe1a5: +case 0xe1a6: +case 0xe1a7: +case 0xe3a0: +case 0xe3a1: +case 0xe3a2: +case 0xe3a3: +case 0xe3a4: +case 0xe3a5: +case 0xe3a6: +case 0xe3a7: +case 0xe5a0: +case 0xe5a1: +case 0xe5a2: +case 0xe5a3: +case 0xe5a4: +case 0xe5a5: +case 0xe5a6: +case 0xe5a7: +case 0xe7a0: +case 0xe7a1: +case 0xe7a2: +case 0xe7a3: +case 0xe7a4: +case 0xe7a5: +case 0xe7a6: +case 0xe7a7: +case 0xe9a0: +case 0xe9a1: +case 0xe9a2: +case 0xe9a3: +case 0xe9a4: +case 0xe9a5: +case 0xe9a6: +case 0xe9a7: +case 0xeba0: +case 0xeba1: +case 0xeba2: +case 0xeba3: +case 0xeba4: +case 0xeba5: +case 0xeba6: +case 0xeba7: +case 0xeda0: +case 0xeda1: +case 0xeda2: +case 0xeda3: +case 0xeda4: +case 0xeda5: +case 0xeda6: +case 0xeda7: +case 0xefa0: +case 0xefa1: +case 0xefa2: +case 0xefa3: +case 0xefa4: +case 0xefa5: +case 0xefa6: +case 0xefa7: + { + HAM targ(this, instr_b2_b0); ASL(targ, D[instr_b11_b9]); + } + break; + +case 0xe180: +case 0xe181: +case 0xe182: +case 0xe183: +case 0xe184: +case 0xe185: +case 0xe186: +case 0xe187: +case 0xe380: +case 0xe381: +case 0xe382: +case 0xe383: +case 0xe384: +case 0xe385: +case 0xe386: +case 0xe387: +case 0xe580: +case 0xe581: +case 0xe582: +case 0xe583: +case 0xe584: +case 0xe585: +case 0xe586: +case 0xe587: +case 0xe780: +case 0xe781: +case 0xe782: +case 0xe783: +case 0xe784: +case 0xe785: +case 0xe786: +case 0xe787: +case 0xe980: +case 0xe981: +case 0xe982: +case 0xe983: +case 0xe984: +case 0xe985: +case 0xe986: +case 0xe987: +case 0xeb80: +case 0xeb81: +case 0xeb82: +case 0xeb83: +case 0xeb84: +case 0xeb85: +case 0xeb86: +case 0xeb87: +case 0xed80: +case 0xed81: +case 0xed82: +case 0xed83: +case 0xed84: +case 0xed85: +case 0xed86: +case 0xed87: +case 0xef80: +case 0xef81: +case 0xef82: +case 0xef83: +case 0xef84: +case 0xef85: +case 0xef86: +case 0xef87: + { + HAM targ(this, instr_b2_b0); ASL(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe0a0: +case 0xe0a1: +case 0xe0a2: +case 0xe0a3: +case 0xe0a4: +case 0xe0a5: +case 0xe0a6: +case 0xe0a7: +case 0xe2a0: +case 0xe2a1: +case 0xe2a2: +case 0xe2a3: +case 0xe2a4: +case 0xe2a5: +case 0xe2a6: +case 0xe2a7: +case 0xe4a0: +case 0xe4a1: +case 0xe4a2: +case 0xe4a3: +case 0xe4a4: +case 0xe4a5: +case 0xe4a6: +case 0xe4a7: +case 0xe6a0: +case 0xe6a1: +case 0xe6a2: +case 0xe6a3: +case 0xe6a4: +case 0xe6a5: +case 0xe6a6: +case 0xe6a7: +case 0xe8a0: +case 0xe8a1: +case 0xe8a2: +case 0xe8a3: +case 0xe8a4: +case 0xe8a5: +case 0xe8a6: +case 0xe8a7: +case 0xeaa0: +case 0xeaa1: +case 0xeaa2: +case 0xeaa3: +case 0xeaa4: +case 0xeaa5: +case 0xeaa6: +case 0xeaa7: +case 0xeca0: +case 0xeca1: +case 0xeca2: +case 0xeca3: +case 0xeca4: +case 0xeca5: +case 0xeca6: +case 0xeca7: +case 0xeea0: +case 0xeea1: +case 0xeea2: +case 0xeea3: +case 0xeea4: +case 0xeea5: +case 0xeea6: +case 0xeea7: + { + HAM targ(this, instr_b2_b0); ASR(targ, D[instr_b11_b9]); + } + break; + +case 0xe080: +case 0xe081: +case 0xe082: +case 0xe083: +case 0xe084: +case 0xe085: +case 0xe086: +case 0xe087: +case 0xe280: +case 0xe281: +case 0xe282: +case 0xe283: +case 0xe284: +case 0xe285: +case 0xe286: +case 0xe287: +case 0xe480: +case 0xe481: +case 0xe482: +case 0xe483: +case 0xe484: +case 0xe485: +case 0xe486: +case 0xe487: +case 0xe680: +case 0xe681: +case 0xe682: +case 0xe683: +case 0xe684: +case 0xe685: +case 0xe686: +case 0xe687: +case 0xe880: +case 0xe881: +case 0xe882: +case 0xe883: +case 0xe884: +case 0xe885: +case 0xe886: +case 0xe887: +case 0xea80: +case 0xea81: +case 0xea82: +case 0xea83: +case 0xea84: +case 0xea85: +case 0xea86: +case 0xea87: +case 0xec80: +case 0xec81: +case 0xec82: +case 0xec83: +case 0xec84: +case 0xec85: +case 0xec86: +case 0xec87: +case 0xee80: +case 0xee81: +case 0xee82: +case 0xee83: +case 0xee84: +case 0xee85: +case 0xee86: +case 0xee87: + { + HAM targ(this, instr_b2_b0); ASR(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0x0140: +case 0x0141: +case 0x0142: +case 0x0143: +case 0x0144: +case 0x0145: +case 0x0146: +case 0x0147: +case 0x0340: +case 0x0341: +case 0x0342: +case 0x0343: +case 0x0344: +case 0x0345: +case 0x0346: +case 0x0347: +case 0x0540: +case 0x0541: +case 0x0542: +case 0x0543: +case 0x0544: +case 0x0545: +case 0x0546: +case 0x0547: +case 0x0740: +case 0x0741: +case 0x0742: +case 0x0743: +case 0x0744: +case 0x0745: +case 0x0746: +case 0x0747: +case 0x0940: +case 0x0941: +case 0x0942: +case 0x0943: +case 0x0944: +case 0x0945: +case 0x0946: +case 0x0947: +case 0x0b40: +case 0x0b41: +case 0x0b42: +case 0x0b43: +case 0x0b44: +case 0x0b45: +case 0x0b46: +case 0x0b47: +case 0x0d40: +case 0x0d41: +case 0x0d42: +case 0x0d43: +case 0x0d44: +case 0x0d45: +case 0x0d46: +case 0x0d47: +case 0x0f40: +case 0x0f41: +case 0x0f42: +case 0x0f43: +case 0x0f44: +case 0x0f45: +case 0x0f46: +case 0x0f47: + { + HAM targ(this, instr_b2_b0); BCHG(targ, D[instr_b11_b9]); + } + break; + +case 0x0180: +case 0x0181: +case 0x0182: +case 0x0183: +case 0x0184: +case 0x0185: +case 0x0186: +case 0x0187: +case 0x0380: +case 0x0381: +case 0x0382: +case 0x0383: +case 0x0384: +case 0x0385: +case 0x0386: +case 0x0387: +case 0x0580: +case 0x0581: +case 0x0582: +case 0x0583: +case 0x0584: +case 0x0585: +case 0x0586: +case 0x0587: +case 0x0780: +case 0x0781: +case 0x0782: +case 0x0783: +case 0x0784: +case 0x0785: +case 0x0786: +case 0x0787: +case 0x0980: +case 0x0981: +case 0x0982: +case 0x0983: +case 0x0984: +case 0x0985: +case 0x0986: +case 0x0987: +case 0x0b80: +case 0x0b81: +case 0x0b82: +case 0x0b83: +case 0x0b84: +case 0x0b85: +case 0x0b86: +case 0x0b87: +case 0x0d80: +case 0x0d81: +case 0x0d82: +case 0x0d83: +case 0x0d84: +case 0x0d85: +case 0x0d86: +case 0x0d87: +case 0x0f80: +case 0x0f81: +case 0x0f82: +case 0x0f83: +case 0x0f84: +case 0x0f85: +case 0x0f86: +case 0x0f87: + { + HAM targ(this, instr_b2_b0); BCLR(targ, D[instr_b11_b9]); + } + break; + +case 0x01c0: +case 0x01c1: +case 0x01c2: +case 0x01c3: +case 0x01c4: +case 0x01c5: +case 0x01c6: +case 0x01c7: +case 0x03c0: +case 0x03c1: +case 0x03c2: +case 0x03c3: +case 0x03c4: +case 0x03c5: +case 0x03c6: +case 0x03c7: +case 0x05c0: +case 0x05c1: +case 0x05c2: +case 0x05c3: +case 0x05c4: +case 0x05c5: +case 0x05c6: +case 0x05c7: +case 0x07c0: +case 0x07c1: +case 0x07c2: +case 0x07c3: +case 0x07c4: +case 0x07c5: +case 0x07c6: +case 0x07c7: +case 0x09c0: +case 0x09c1: +case 0x09c2: +case 0x09c3: +case 0x09c4: +case 0x09c5: +case 0x09c6: +case 0x09c7: +case 0x0bc0: +case 0x0bc1: +case 0x0bc2: +case 0x0bc3: +case 0x0bc4: +case 0x0bc5: +case 0x0bc6: +case 0x0bc7: +case 0x0dc0: +case 0x0dc1: +case 0x0dc2: +case 0x0dc3: +case 0x0dc4: +case 0x0dc5: +case 0x0dc6: +case 0x0dc7: +case 0x0fc0: +case 0x0fc1: +case 0x0fc2: +case 0x0fc3: +case 0x0fc4: +case 0x0fc5: +case 0x0fc6: +case 0x0fc7: + { + HAM targ(this, instr_b2_b0); BSET(targ, D[instr_b11_b9]); + } + break; + +case 0x0100: +case 0x0101: +case 0x0102: +case 0x0103: +case 0x0104: +case 0x0105: +case 0x0106: +case 0x0107: +case 0x0300: +case 0x0301: +case 0x0302: +case 0x0303: +case 0x0304: +case 0x0305: +case 0x0306: +case 0x0307: +case 0x0500: +case 0x0501: +case 0x0502: +case 0x0503: +case 0x0504: +case 0x0505: +case 0x0506: +case 0x0507: +case 0x0700: +case 0x0701: +case 0x0702: +case 0x0703: +case 0x0704: +case 0x0705: +case 0x0706: +case 0x0707: +case 0x0900: +case 0x0901: +case 0x0902: +case 0x0903: +case 0x0904: +case 0x0905: +case 0x0906: +case 0x0907: +case 0x0b00: +case 0x0b01: +case 0x0b02: +case 0x0b03: +case 0x0b04: +case 0x0b05: +case 0x0b06: +case 0x0b07: +case 0x0d00: +case 0x0d01: +case 0x0d02: +case 0x0d03: +case 0x0d04: +case 0x0d05: +case 0x0d06: +case 0x0d07: +case 0x0f00: +case 0x0f01: +case 0x0f02: +case 0x0f03: +case 0x0f04: +case 0x0f05: +case 0x0f06: +case 0x0f07: + { + HAM targ(this, instr_b2_b0); BTST(targ, D[instr_b11_b9]); + } + break; + +case 0xe1a8: +case 0xe1a9: +case 0xe1aa: +case 0xe1ab: +case 0xe1ac: +case 0xe1ad: +case 0xe1ae: +case 0xe1af: +case 0xe3a8: +case 0xe3a9: +case 0xe3aa: +case 0xe3ab: +case 0xe3ac: +case 0xe3ad: +case 0xe3ae: +case 0xe3af: +case 0xe5a8: +case 0xe5a9: +case 0xe5aa: +case 0xe5ab: +case 0xe5ac: +case 0xe5ad: +case 0xe5ae: +case 0xe5af: +case 0xe7a8: +case 0xe7a9: +case 0xe7aa: +case 0xe7ab: +case 0xe7ac: +case 0xe7ad: +case 0xe7ae: +case 0xe7af: +case 0xe9a8: +case 0xe9a9: +case 0xe9aa: +case 0xe9ab: +case 0xe9ac: +case 0xe9ad: +case 0xe9ae: +case 0xe9af: +case 0xeba8: +case 0xeba9: +case 0xebaa: +case 0xebab: +case 0xebac: +case 0xebad: +case 0xebae: +case 0xebaf: +case 0xeda8: +case 0xeda9: +case 0xedaa: +case 0xedab: +case 0xedac: +case 0xedad: +case 0xedae: +case 0xedaf: +case 0xefa8: +case 0xefa9: +case 0xefaa: +case 0xefab: +case 0xefac: +case 0xefad: +case 0xefae: +case 0xefaf: + { + HAM targ(this, instr_b2_b0); LSL(targ, D[instr_b11_b9]); + } + break; + +case 0xe188: +case 0xe189: +case 0xe18a: +case 0xe18b: +case 0xe18c: +case 0xe18d: +case 0xe18e: +case 0xe18f: +case 0xe388: +case 0xe389: +case 0xe38a: +case 0xe38b: +case 0xe38c: +case 0xe38d: +case 0xe38e: +case 0xe38f: +case 0xe588: +case 0xe589: +case 0xe58a: +case 0xe58b: +case 0xe58c: +case 0xe58d: +case 0xe58e: +case 0xe58f: +case 0xe788: +case 0xe789: +case 0xe78a: +case 0xe78b: +case 0xe78c: +case 0xe78d: +case 0xe78e: +case 0xe78f: +case 0xe988: +case 0xe989: +case 0xe98a: +case 0xe98b: +case 0xe98c: +case 0xe98d: +case 0xe98e: +case 0xe98f: +case 0xeb88: +case 0xeb89: +case 0xeb8a: +case 0xeb8b: +case 0xeb8c: +case 0xeb8d: +case 0xeb8e: +case 0xeb8f: +case 0xed88: +case 0xed89: +case 0xed8a: +case 0xed8b: +case 0xed8c: +case 0xed8d: +case 0xed8e: +case 0xed8f: +case 0xef88: +case 0xef89: +case 0xef8a: +case 0xef8b: +case 0xef8c: +case 0xef8d: +case 0xef8e: +case 0xef8f: + { + HAM targ(this, instr_b2_b0); LSL(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe0a8: +case 0xe0a9: +case 0xe0aa: +case 0xe0ab: +case 0xe0ac: +case 0xe0ad: +case 0xe0ae: +case 0xe0af: +case 0xe2a8: +case 0xe2a9: +case 0xe2aa: +case 0xe2ab: +case 0xe2ac: +case 0xe2ad: +case 0xe2ae: +case 0xe2af: +case 0xe4a8: +case 0xe4a9: +case 0xe4aa: +case 0xe4ab: +case 0xe4ac: +case 0xe4ad: +case 0xe4ae: +case 0xe4af: +case 0xe6a8: +case 0xe6a9: +case 0xe6aa: +case 0xe6ab: +case 0xe6ac: +case 0xe6ad: +case 0xe6ae: +case 0xe6af: +case 0xe8a8: +case 0xe8a9: +case 0xe8aa: +case 0xe8ab: +case 0xe8ac: +case 0xe8ad: +case 0xe8ae: +case 0xe8af: +case 0xeaa8: +case 0xeaa9: +case 0xeaaa: +case 0xeaab: +case 0xeaac: +case 0xeaad: +case 0xeaae: +case 0xeaaf: +case 0xeca8: +case 0xeca9: +case 0xecaa: +case 0xecab: +case 0xecac: +case 0xecad: +case 0xecae: +case 0xecaf: +case 0xeea8: +case 0xeea9: +case 0xeeaa: +case 0xeeab: +case 0xeeac: +case 0xeead: +case 0xeeae: +case 0xeeaf: + { + HAM targ(this, instr_b2_b0); LSR(targ, D[instr_b11_b9]); + } + break; + +case 0xe088: +case 0xe089: +case 0xe08a: +case 0xe08b: +case 0xe08c: +case 0xe08d: +case 0xe08e: +case 0xe08f: +case 0xe288: +case 0xe289: +case 0xe28a: +case 0xe28b: +case 0xe28c: +case 0xe28d: +case 0xe28e: +case 0xe28f: +case 0xe488: +case 0xe489: +case 0xe48a: +case 0xe48b: +case 0xe48c: +case 0xe48d: +case 0xe48e: +case 0xe48f: +case 0xe688: +case 0xe689: +case 0xe68a: +case 0xe68b: +case 0xe68c: +case 0xe68d: +case 0xe68e: +case 0xe68f: +case 0xe888: +case 0xe889: +case 0xe88a: +case 0xe88b: +case 0xe88c: +case 0xe88d: +case 0xe88e: +case 0xe88f: +case 0xea88: +case 0xea89: +case 0xea8a: +case 0xea8b: +case 0xea8c: +case 0xea8d: +case 0xea8e: +case 0xea8f: +case 0xec88: +case 0xec89: +case 0xec8a: +case 0xec8b: +case 0xec8c: +case 0xec8d: +case 0xec8e: +case 0xec8f: +case 0xee88: +case 0xee89: +case 0xee8a: +case 0xee8b: +case 0xee8c: +case 0xee8d: +case 0xee8e: +case 0xee8f: + { + HAM targ(this, instr_b2_b0); LSR(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe1b8: +case 0xe1b9: +case 0xe1ba: +case 0xe1bb: +case 0xe1bc: +case 0xe1bd: +case 0xe1be: +case 0xe1bf: +case 0xe3b8: +case 0xe3b9: +case 0xe3ba: +case 0xe3bb: +case 0xe3bc: +case 0xe3bd: +case 0xe3be: +case 0xe3bf: +case 0xe5b8: +case 0xe5b9: +case 0xe5ba: +case 0xe5bb: +case 0xe5bc: +case 0xe5bd: +case 0xe5be: +case 0xe5bf: +case 0xe7b8: +case 0xe7b9: +case 0xe7ba: +case 0xe7bb: +case 0xe7bc: +case 0xe7bd: +case 0xe7be: +case 0xe7bf: +case 0xe9b8: +case 0xe9b9: +case 0xe9ba: +case 0xe9bb: +case 0xe9bc: +case 0xe9bd: +case 0xe9be: +case 0xe9bf: +case 0xebb8: +case 0xebb9: +case 0xebba: +case 0xebbb: +case 0xebbc: +case 0xebbd: +case 0xebbe: +case 0xebbf: +case 0xedb8: +case 0xedb9: +case 0xedba: +case 0xedbb: +case 0xedbc: +case 0xedbd: +case 0xedbe: +case 0xedbf: +case 0xefb8: +case 0xefb9: +case 0xefba: +case 0xefbb: +case 0xefbc: +case 0xefbd: +case 0xefbe: +case 0xefbf: + { + HAM targ(this, instr_b2_b0); ROL(targ, D[instr_b11_b9]); + } + break; + +case 0xe198: +case 0xe199: +case 0xe19a: +case 0xe19b: +case 0xe19c: +case 0xe19d: +case 0xe19e: +case 0xe19f: +case 0xe398: +case 0xe399: +case 0xe39a: +case 0xe39b: +case 0xe39c: +case 0xe39d: +case 0xe39e: +case 0xe39f: +case 0xe598: +case 0xe599: +case 0xe59a: +case 0xe59b: +case 0xe59c: +case 0xe59d: +case 0xe59e: +case 0xe59f: +case 0xe798: +case 0xe799: +case 0xe79a: +case 0xe79b: +case 0xe79c: +case 0xe79d: +case 0xe79e: +case 0xe79f: +case 0xe998: +case 0xe999: +case 0xe99a: +case 0xe99b: +case 0xe99c: +case 0xe99d: +case 0xe99e: +case 0xe99f: +case 0xeb98: +case 0xeb99: +case 0xeb9a: +case 0xeb9b: +case 0xeb9c: +case 0xeb9d: +case 0xeb9e: +case 0xeb9f: +case 0xed98: +case 0xed99: +case 0xed9a: +case 0xed9b: +case 0xed9c: +case 0xed9d: +case 0xed9e: +case 0xed9f: +case 0xef98: +case 0xef99: +case 0xef9a: +case 0xef9b: +case 0xef9c: +case 0xef9d: +case 0xef9e: +case 0xef9f: + { + HAM targ(this, instr_b2_b0); ROL(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe0b8: +case 0xe0b9: +case 0xe0ba: +case 0xe0bb: +case 0xe0bc: +case 0xe0bd: +case 0xe0be: +case 0xe0bf: +case 0xe2b8: +case 0xe2b9: +case 0xe2ba: +case 0xe2bb: +case 0xe2bc: +case 0xe2bd: +case 0xe2be: +case 0xe2bf: +case 0xe4b8: +case 0xe4b9: +case 0xe4ba: +case 0xe4bb: +case 0xe4bc: +case 0xe4bd: +case 0xe4be: +case 0xe4bf: +case 0xe6b8: +case 0xe6b9: +case 0xe6ba: +case 0xe6bb: +case 0xe6bc: +case 0xe6bd: +case 0xe6be: +case 0xe6bf: +case 0xe8b8: +case 0xe8b9: +case 0xe8ba: +case 0xe8bb: +case 0xe8bc: +case 0xe8bd: +case 0xe8be: +case 0xe8bf: +case 0xeab8: +case 0xeab9: +case 0xeaba: +case 0xeabb: +case 0xeabc: +case 0xeabd: +case 0xeabe: +case 0xeabf: +case 0xecb8: +case 0xecb9: +case 0xecba: +case 0xecbb: +case 0xecbc: +case 0xecbd: +case 0xecbe: +case 0xecbf: +case 0xeeb8: +case 0xeeb9: +case 0xeeba: +case 0xeebb: +case 0xeebc: +case 0xeebd: +case 0xeebe: +case 0xeebf: + { + HAM targ(this, instr_b2_b0); ROR(targ, D[instr_b11_b9]); + } + break; + +case 0xe098: +case 0xe099: +case 0xe09a: +case 0xe09b: +case 0xe09c: +case 0xe09d: +case 0xe09e: +case 0xe09f: +case 0xe298: +case 0xe299: +case 0xe29a: +case 0xe29b: +case 0xe29c: +case 0xe29d: +case 0xe29e: +case 0xe29f: +case 0xe498: +case 0xe499: +case 0xe49a: +case 0xe49b: +case 0xe49c: +case 0xe49d: +case 0xe49e: +case 0xe49f: +case 0xe698: +case 0xe699: +case 0xe69a: +case 0xe69b: +case 0xe69c: +case 0xe69d: +case 0xe69e: +case 0xe69f: +case 0xe898: +case 0xe899: +case 0xe89a: +case 0xe89b: +case 0xe89c: +case 0xe89d: +case 0xe89e: +case 0xe89f: +case 0xea98: +case 0xea99: +case 0xea9a: +case 0xea9b: +case 0xea9c: +case 0xea9d: +case 0xea9e: +case 0xea9f: +case 0xec98: +case 0xec99: +case 0xec9a: +case 0xec9b: +case 0xec9c: +case 0xec9d: +case 0xec9e: +case 0xec9f: +case 0xee98: +case 0xee99: +case 0xee9a: +case 0xee9b: +case 0xee9c: +case 0xee9d: +case 0xee9e: +case 0xee9f: + { + HAM targ(this, instr_b2_b0); ROR(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe1b0: +case 0xe1b1: +case 0xe1b2: +case 0xe1b3: +case 0xe1b4: +case 0xe1b5: +case 0xe1b6: +case 0xe1b7: +case 0xe3b0: +case 0xe3b1: +case 0xe3b2: +case 0xe3b3: +case 0xe3b4: +case 0xe3b5: +case 0xe3b6: +case 0xe3b7: +case 0xe5b0: +case 0xe5b1: +case 0xe5b2: +case 0xe5b3: +case 0xe5b4: +case 0xe5b5: +case 0xe5b6: +case 0xe5b7: +case 0xe7b0: +case 0xe7b1: +case 0xe7b2: +case 0xe7b3: +case 0xe7b4: +case 0xe7b5: +case 0xe7b6: +case 0xe7b7: +case 0xe9b0: +case 0xe9b1: +case 0xe9b2: +case 0xe9b3: +case 0xe9b4: +case 0xe9b5: +case 0xe9b6: +case 0xe9b7: +case 0xebb0: +case 0xebb1: +case 0xebb2: +case 0xebb3: +case 0xebb4: +case 0xebb5: +case 0xebb6: +case 0xebb7: +case 0xedb0: +case 0xedb1: +case 0xedb2: +case 0xedb3: +case 0xedb4: +case 0xedb5: +case 0xedb6: +case 0xedb7: +case 0xefb0: +case 0xefb1: +case 0xefb2: +case 0xefb3: +case 0xefb4: +case 0xefb5: +case 0xefb6: +case 0xefb7: + { + HAM targ(this, instr_b2_b0); ROXL(targ, D[instr_b11_b9]); + } + break; + +case 0xe190: +case 0xe191: +case 0xe192: +case 0xe193: +case 0xe194: +case 0xe195: +case 0xe196: +case 0xe197: +case 0xe390: +case 0xe391: +case 0xe392: +case 0xe393: +case 0xe394: +case 0xe395: +case 0xe396: +case 0xe397: +case 0xe590: +case 0xe591: +case 0xe592: +case 0xe593: +case 0xe594: +case 0xe595: +case 0xe596: +case 0xe597: +case 0xe790: +case 0xe791: +case 0xe792: +case 0xe793: +case 0xe794: +case 0xe795: +case 0xe796: +case 0xe797: +case 0xe990: +case 0xe991: +case 0xe992: +case 0xe993: +case 0xe994: +case 0xe995: +case 0xe996: +case 0xe997: +case 0xeb90: +case 0xeb91: +case 0xeb92: +case 0xeb93: +case 0xeb94: +case 0xeb95: +case 0xeb96: +case 0xeb97: +case 0xed90: +case 0xed91: +case 0xed92: +case 0xed93: +case 0xed94: +case 0xed95: +case 0xed96: +case 0xed97: +case 0xef90: +case 0xef91: +case 0xef92: +case 0xef93: +case 0xef94: +case 0xef95: +case 0xef96: +case 0xef97: + { + HAM targ(this, instr_b2_b0); ROXL(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe0b0: +case 0xe0b1: +case 0xe0b2: +case 0xe0b3: +case 0xe0b4: +case 0xe0b5: +case 0xe0b6: +case 0xe0b7: +case 0xe2b0: +case 0xe2b1: +case 0xe2b2: +case 0xe2b3: +case 0xe2b4: +case 0xe2b5: +case 0xe2b6: +case 0xe2b7: +case 0xe4b0: +case 0xe4b1: +case 0xe4b2: +case 0xe4b3: +case 0xe4b4: +case 0xe4b5: +case 0xe4b6: +case 0xe4b7: +case 0xe6b0: +case 0xe6b1: +case 0xe6b2: +case 0xe6b3: +case 0xe6b4: +case 0xe6b5: +case 0xe6b6: +case 0xe6b7: +case 0xe8b0: +case 0xe8b1: +case 0xe8b2: +case 0xe8b3: +case 0xe8b4: +case 0xe8b5: +case 0xe8b6: +case 0xe8b7: +case 0xeab0: +case 0xeab1: +case 0xeab2: +case 0xeab3: +case 0xeab4: +case 0xeab5: +case 0xeab6: +case 0xeab7: +case 0xecb0: +case 0xecb1: +case 0xecb2: +case 0xecb3: +case 0xecb4: +case 0xecb5: +case 0xecb6: +case 0xecb7: +case 0xeeb0: +case 0xeeb1: +case 0xeeb2: +case 0xeeb3: +case 0xeeb4: +case 0xeeb5: +case 0xeeb6: +case 0xeeb7: + { + HAM targ(this, instr_b2_b0); ROXR(targ, D[instr_b11_b9]); + } + break; + +case 0xe090: +case 0xe091: +case 0xe092: +case 0xe093: +case 0xe094: +case 0xe095: +case 0xe096: +case 0xe097: +case 0xe290: +case 0xe291: +case 0xe292: +case 0xe293: +case 0xe294: +case 0xe295: +case 0xe296: +case 0xe297: +case 0xe490: +case 0xe491: +case 0xe492: +case 0xe493: +case 0xe494: +case 0xe495: +case 0xe496: +case 0xe497: +case 0xe690: +case 0xe691: +case 0xe692: +case 0xe693: +case 0xe694: +case 0xe695: +case 0xe696: +case 0xe697: +case 0xe890: +case 0xe891: +case 0xe892: +case 0xe893: +case 0xe894: +case 0xe895: +case 0xe896: +case 0xe897: +case 0xea90: +case 0xea91: +case 0xea92: +case 0xea93: +case 0xea94: +case 0xea95: +case 0xea96: +case 0xea97: +case 0xec90: +case 0xec91: +case 0xec92: +case 0xec93: +case 0xec94: +case 0xec95: +case 0xec96: +case 0xec97: +case 0xee90: +case 0xee91: +case 0xee92: +case 0xee93: +case 0xee94: +case 0xee95: +case 0xee96: +case 0xee97: + { + HAM targ(this, instr_b2_b0); ROXR(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0x06b9: + { + HAM src(this); HAM dst(this); ADD(src, dst); + } + break; + +case 0x02b9: + { + HAM src(this); HAM dst(this); AND(src, dst); + } + break; + +case 0x0cb9: + { + HAM src(this); HAM dst(this); CMP(src, dst); + } + break; + +case 0x0ab9: + { + HAM src(this); HAM dst(this); EOR(src, dst); + } + break; + +case 0x23fc: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x00b9: + { + HAM src(this); HAM dst(this); OR(src, dst); + } + break; + +case 0x04b9: + { + HAM src(this); HAM dst(this); SUB(src, dst); + } + break; + +case 0x06b8: + { + HAM src(this); HAM dst(this); ADD(src, dst); + } + break; + +case 0x02b8: + { + HAM src(this); HAM dst(this); AND(src, dst); + } + break; + +case 0x0cb8: + { + HAM src(this); HAM dst(this); CMP(src, dst); + } + break; + +case 0x0ab8: + { + HAM src(this); HAM dst(this); EOR(src, dst); + } + break; + +case 0x21fc: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x00b8: + { + HAM src(this); HAM dst(this); OR(src, dst); + } + break; + +case 0x04b8: + { + HAM src(this); HAM dst(this); SUB(src, dst); + } + break; + +case 0xd1fc: +case 0xd3fc: +case 0xd5fc: +case 0xd7fc: +case 0xd9fc: +case 0xdbfc: +case 0xddfc: +case 0xdffc: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb1fc: +case 0xb3fc: +case 0xb5fc: +case 0xb7fc: +case 0xb9fc: +case 0xbbfc: +case 0xbdfc: +case 0xbffc: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x91fc: +case 0x93fc: +case 0x95fc: +case 0x97fc: +case 0x99fc: +case 0x9bfc: +case 0x9dfc: +case 0x9ffc: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x20bc: +case 0x22bc: +case 0x24bc: +case 0x26bc: +case 0x28bc: +case 0x2abc: +case 0x2cbc: +case 0x2ebc: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x0690: +case 0x0691: +case 0x0692: +case 0x0693: +case 0x0694: +case 0x0695: +case 0x0696: +case 0x0697: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x0290: +case 0x0291: +case 0x0292: +case 0x0293: +case 0x0294: +case 0x0295: +case 0x0296: +case 0x0297: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0c90: +case 0x0c91: +case 0x0c92: +case 0x0c93: +case 0x0c94: +case 0x0c95: +case 0x0c96: +case 0x0c97: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0a90: +case 0x0a91: +case 0x0a92: +case 0x0a93: +case 0x0a94: +case 0x0a95: +case 0x0a96: +case 0x0a97: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x0090: +case 0x0091: +case 0x0092: +case 0x0093: +case 0x0094: +case 0x0095: +case 0x0096: +case 0x0097: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x0490: +case 0x0491: +case 0x0492: +case 0x0493: +case 0x0494: +case 0x0495: +case 0x0496: +case 0x0497: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x217c: +case 0x237c: +case 0x257c: +case 0x277c: +case 0x297c: +case 0x2b7c: +case 0x2d7c: +case 0x2f7c: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x06a8: +case 0x06a9: +case 0x06aa: +case 0x06ab: +case 0x06ac: +case 0x06ad: +case 0x06ae: +case 0x06af: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x02a8: +case 0x02a9: +case 0x02aa: +case 0x02ab: +case 0x02ac: +case 0x02ad: +case 0x02ae: +case 0x02af: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0ca8: +case 0x0ca9: +case 0x0caa: +case 0x0cab: +case 0x0cac: +case 0x0cad: +case 0x0cae: +case 0x0caf: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0aa8: +case 0x0aa9: +case 0x0aaa: +case 0x0aab: +case 0x0aac: +case 0x0aad: +case 0x0aae: +case 0x0aaf: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x00a8: +case 0x00a9: +case 0x00aa: +case 0x00ab: +case 0x00ac: +case 0x00ad: +case 0x00ae: +case 0x00af: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x04a8: +case 0x04a9: +case 0x04aa: +case 0x04ab: +case 0x04ac: +case 0x04ad: +case 0x04ae: +case 0x04af: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x21bc: +case 0x23bc: +case 0x25bc: +case 0x27bc: +case 0x29bc: +case 0x2bbc: +case 0x2dbc: +case 0x2fbc: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x06b0: +case 0x06b1: +case 0x06b2: +case 0x06b3: +case 0x06b4: +case 0x06b5: +case 0x06b6: +case 0x06b7: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x02b0: +case 0x02b1: +case 0x02b2: +case 0x02b3: +case 0x02b4: +case 0x02b5: +case 0x02b6: +case 0x02b7: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0cb0: +case 0x0cb1: +case 0x0cb2: +case 0x0cb3: +case 0x0cb4: +case 0x0cb5: +case 0x0cb6: +case 0x0cb7: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0ab0: +case 0x0ab1: +case 0x0ab2: +case 0x0ab3: +case 0x0ab4: +case 0x0ab5: +case 0x0ab6: +case 0x0ab7: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x00b0: +case 0x00b1: +case 0x00b2: +case 0x00b3: +case 0x00b4: +case 0x00b5: +case 0x00b6: +case 0x00b7: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x04b0: +case 0x04b1: +case 0x04b2: +case 0x04b3: +case 0x04b4: +case 0x04b5: +case 0x04b6: +case 0x04b7: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x20fc: +case 0x22fc: +case 0x24fc: +case 0x26fc: +case 0x28fc: +case 0x2afc: +case 0x2cfc: +case 0x2efc: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x0698: +case 0x0699: +case 0x069a: +case 0x069b: +case 0x069c: +case 0x069d: +case 0x069e: +case 0x069f: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x0298: +case 0x0299: +case 0x029a: +case 0x029b: +case 0x029c: +case 0x029d: +case 0x029e: +case 0x029f: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0c98: +case 0x0c99: +case 0x0c9a: +case 0x0c9b: +case 0x0c9c: +case 0x0c9d: +case 0x0c9e: +case 0x0c9f: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0a98: +case 0x0a99: +case 0x0a9a: +case 0x0a9b: +case 0x0a9c: +case 0x0a9d: +case 0x0a9e: +case 0x0a9f: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x0098: +case 0x0099: +case 0x009a: +case 0x009b: +case 0x009c: +case 0x009d: +case 0x009e: +case 0x009f: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x0498: +case 0x0499: +case 0x049a: +case 0x049b: +case 0x049c: +case 0x049d: +case 0x049e: +case 0x049f: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x213c: +case 0x233c: +case 0x253c: +case 0x273c: +case 0x293c: +case 0x2b3c: +case 0x2d3c: +case 0x2f3c: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x06a0: +case 0x06a1: +case 0x06a2: +case 0x06a3: +case 0x06a4: +case 0x06a5: +case 0x06a6: +case 0x06a7: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x02a0: +case 0x02a1: +case 0x02a2: +case 0x02a3: +case 0x02a4: +case 0x02a5: +case 0x02a6: +case 0x02a7: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0ca0: +case 0x0ca1: +case 0x0ca2: +case 0x0ca3: +case 0x0ca4: +case 0x0ca5: +case 0x0ca6: +case 0x0ca7: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0aa0: +case 0x0aa1: +case 0x0aa2: +case 0x0aa3: +case 0x0aa4: +case 0x0aa5: +case 0x0aa6: +case 0x0aa7: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x00a0: +case 0x00a1: +case 0x00a2: +case 0x00a3: +case 0x00a4: +case 0x00a5: +case 0x00a6: +case 0x00a7: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x04a0: +case 0x04a1: +case 0x04a2: +case 0x04a3: +case 0x04a4: +case 0x04a5: +case 0x04a6: +case 0x04a7: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xd0bc: +case 0xd2bc: +case 0xd4bc: +case 0xd6bc: +case 0xd8bc: +case 0xdabc: +case 0xdcbc: +case 0xdebc: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc0bc: +case 0xc2bc: +case 0xc4bc: +case 0xc6bc: +case 0xc8bc: +case 0xcabc: +case 0xccbc: +case 0xcebc: + { + HAM src(this); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb0bc: +case 0xb2bc: +case 0xb4bc: +case 0xb6bc: +case 0xb8bc: +case 0xbabc: +case 0xbcbc: +case 0xbebc: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x203c: +case 0x223c: +case 0x243c: +case 0x263c: +case 0x283c: +case 0x2a3c: +case 0x2c3c: +case 0x2e3c: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x80bc: +case 0x82bc: +case 0x84bc: +case 0x86bc: +case 0x88bc: +case 0x8abc: +case 0x8cbc: +case 0x8ebc: + { + HAM src(this); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x90bc: +case 0x92bc: +case 0x94bc: +case 0x96bc: +case 0x98bc: +case 0x9abc: +case 0x9cbc: +case 0x9ebc: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x0680: +case 0x0681: +case 0x0682: +case 0x0683: +case 0x0684: +case 0x0685: +case 0x0686: +case 0x0687: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x0280: +case 0x0281: +case 0x0282: +case 0x0283: +case 0x0284: +case 0x0285: +case 0x0286: +case 0x0287: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0c80: +case 0x0c81: +case 0x0c82: +case 0x0c83: +case 0x0c84: +case 0x0c85: +case 0x0c86: +case 0x0c87: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0a80: +case 0x0a81: +case 0x0a82: +case 0x0a83: +case 0x0a84: +case 0x0a85: +case 0x0a86: +case 0x0a87: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x0080: +case 0x0081: +case 0x0082: +case 0x0083: +case 0x0084: +case 0x0085: +case 0x0086: +case 0x0087: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x0480: +case 0x0481: +case 0x0482: +case 0x0483: +case 0x0484: +case 0x0485: +case 0x0486: +case 0x0487: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x207c: +case 0x227c: +case 0x247c: +case 0x267c: +case 0x287c: +case 0x2a7c: +case 0x2c7c: +case 0x2e7c: + { + HAM src(this); MOVEA(src, instr_b11_b9); + } + break; + +case 0x7000: +case 0x7001: +case 0x7002: +case 0x7003: +case 0x7004: +case 0x7005: +case 0x7006: +case 0x7007: +case 0x7008: +case 0x7009: +case 0x700a: +case 0x700b: +case 0x700c: +case 0x700d: +case 0x700e: +case 0x700f: +case 0x7010: +case 0x7011: +case 0x7012: +case 0x7013: +case 0x7014: +case 0x7015: +case 0x7016: +case 0x7017: +case 0x7018: +case 0x7019: +case 0x701a: +case 0x701b: +case 0x701c: +case 0x701d: +case 0x701e: +case 0x701f: +case 0x7020: +case 0x7021: +case 0x7022: +case 0x7023: +case 0x7024: +case 0x7025: +case 0x7026: +case 0x7027: +case 0x7028: +case 0x7029: +case 0x702a: +case 0x702b: +case 0x702c: +case 0x702d: +case 0x702e: +case 0x702f: +case 0x7030: +case 0x7031: +case 0x7032: +case 0x7033: +case 0x7034: +case 0x7035: +case 0x7036: +case 0x7037: +case 0x7038: +case 0x7039: +case 0x703a: +case 0x703b: +case 0x703c: +case 0x703d: +case 0x703e: +case 0x703f: +case 0x7040: +case 0x7041: +case 0x7042: +case 0x7043: +case 0x7044: +case 0x7045: +case 0x7046: +case 0x7047: +case 0x7048: +case 0x7049: +case 0x704a: +case 0x704b: +case 0x704c: +case 0x704d: +case 0x704e: +case 0x704f: +case 0x7050: +case 0x7051: +case 0x7052: +case 0x7053: +case 0x7054: +case 0x7055: +case 0x7056: +case 0x7057: +case 0x7058: +case 0x7059: +case 0x705a: +case 0x705b: +case 0x705c: +case 0x705d: +case 0x705e: +case 0x705f: +case 0x7060: +case 0x7061: +case 0x7062: +case 0x7063: +case 0x7064: +case 0x7065: +case 0x7066: +case 0x7067: +case 0x7068: +case 0x7069: +case 0x706a: +case 0x706b: +case 0x706c: +case 0x706d: +case 0x706e: +case 0x706f: +case 0x7070: +case 0x7071: +case 0x7072: +case 0x7073: +case 0x7074: +case 0x7075: +case 0x7076: +case 0x7077: +case 0x7078: +case 0x7079: +case 0x707a: +case 0x707b: +case 0x707c: +case 0x707d: +case 0x707e: +case 0x707f: +case 0x7080: +case 0x7081: +case 0x7082: +case 0x7083: +case 0x7084: +case 0x7085: +case 0x7086: +case 0x7087: +case 0x7088: +case 0x7089: +case 0x708a: +case 0x708b: +case 0x708c: +case 0x708d: +case 0x708e: +case 0x708f: +case 0x7090: +case 0x7091: +case 0x7092: +case 0x7093: +case 0x7094: +case 0x7095: +case 0x7096: +case 0x7097: +case 0x7098: +case 0x7099: +case 0x709a: +case 0x709b: +case 0x709c: +case 0x709d: +case 0x709e: +case 0x709f: +case 0x70a0: +case 0x70a1: +case 0x70a2: +case 0x70a3: +case 0x70a4: +case 0x70a5: +case 0x70a6: +case 0x70a7: +case 0x70a8: +case 0x70a9: +case 0x70aa: +case 0x70ab: +case 0x70ac: +case 0x70ad: +case 0x70ae: +case 0x70af: +case 0x70b0: +case 0x70b1: +case 0x70b2: +case 0x70b3: +case 0x70b4: +case 0x70b5: +case 0x70b6: +case 0x70b7: +case 0x70b8: +case 0x70b9: +case 0x70ba: +case 0x70bb: +case 0x70bc: +case 0x70bd: +case 0x70be: +case 0x70bf: +case 0x70c0: +case 0x70c1: +case 0x70c2: +case 0x70c3: +case 0x70c4: +case 0x70c5: +case 0x70c6: +case 0x70c7: +case 0x70c8: +case 0x70c9: +case 0x70ca: +case 0x70cb: +case 0x70cc: +case 0x70cd: +case 0x70ce: +case 0x70cf: +case 0x70d0: +case 0x70d1: +case 0x70d2: +case 0x70d3: +case 0x70d4: +case 0x70d5: +case 0x70d6: +case 0x70d7: +case 0x70d8: +case 0x70d9: +case 0x70da: +case 0x70db: +case 0x70dc: +case 0x70dd: +case 0x70de: +case 0x70df: +case 0x70e0: +case 0x70e1: +case 0x70e2: +case 0x70e3: +case 0x70e4: +case 0x70e5: +case 0x70e6: +case 0x70e7: +case 0x70e8: +case 0x70e9: +case 0x70ea: +case 0x70eb: +case 0x70ec: +case 0x70ed: +case 0x70ee: +case 0x70ef: +case 0x70f0: +case 0x70f1: +case 0x70f2: +case 0x70f3: +case 0x70f4: +case 0x70f5: +case 0x70f6: +case 0x70f7: +case 0x70f8: +case 0x70f9: +case 0x70fa: +case 0x70fb: +case 0x70fc: +case 0x70fd: +case 0x70fe: +case 0x70ff: +case 0x7200: +case 0x7201: +case 0x7202: +case 0x7203: +case 0x7204: +case 0x7205: +case 0x7206: +case 0x7207: +case 0x7208: +case 0x7209: +case 0x720a: +case 0x720b: +case 0x720c: +case 0x720d: +case 0x720e: +case 0x720f: +case 0x7210: +case 0x7211: +case 0x7212: +case 0x7213: +case 0x7214: +case 0x7215: +case 0x7216: +case 0x7217: +case 0x7218: +case 0x7219: +case 0x721a: +case 0x721b: +case 0x721c: +case 0x721d: +case 0x721e: +case 0x721f: +case 0x7220: +case 0x7221: +case 0x7222: +case 0x7223: +case 0x7224: +case 0x7225: +case 0x7226: +case 0x7227: +case 0x7228: +case 0x7229: +case 0x722a: +case 0x722b: +case 0x722c: +case 0x722d: +case 0x722e: +case 0x722f: +case 0x7230: +case 0x7231: +case 0x7232: +case 0x7233: +case 0x7234: +case 0x7235: +case 0x7236: +case 0x7237: +case 0x7238: +case 0x7239: +case 0x723a: +case 0x723b: +case 0x723c: +case 0x723d: +case 0x723e: +case 0x723f: +case 0x7240: +case 0x7241: +case 0x7242: +case 0x7243: +case 0x7244: +case 0x7245: +case 0x7246: +case 0x7247: +case 0x7248: +case 0x7249: +case 0x724a: +case 0x724b: +case 0x724c: +case 0x724d: +case 0x724e: +case 0x724f: +case 0x7250: +case 0x7251: +case 0x7252: +case 0x7253: +case 0x7254: +case 0x7255: +case 0x7256: +case 0x7257: +case 0x7258: +case 0x7259: +case 0x725a: +case 0x725b: +case 0x725c: +case 0x725d: +case 0x725e: +case 0x725f: +case 0x7260: +case 0x7261: +case 0x7262: +case 0x7263: +case 0x7264: +case 0x7265: +case 0x7266: +case 0x7267: +case 0x7268: +case 0x7269: +case 0x726a: +case 0x726b: +case 0x726c: +case 0x726d: +case 0x726e: +case 0x726f: +case 0x7270: +case 0x7271: +case 0x7272: +case 0x7273: +case 0x7274: +case 0x7275: +case 0x7276: +case 0x7277: +case 0x7278: +case 0x7279: +case 0x727a: +case 0x727b: +case 0x727c: +case 0x727d: +case 0x727e: +case 0x727f: +case 0x7280: +case 0x7281: +case 0x7282: +case 0x7283: +case 0x7284: +case 0x7285: +case 0x7286: +case 0x7287: +case 0x7288: +case 0x7289: +case 0x728a: +case 0x728b: +case 0x728c: +case 0x728d: +case 0x728e: +case 0x728f: +case 0x7290: +case 0x7291: +case 0x7292: +case 0x7293: +case 0x7294: +case 0x7295: +case 0x7296: +case 0x7297: +case 0x7298: +case 0x7299: +case 0x729a: +case 0x729b: +case 0x729c: +case 0x729d: +case 0x729e: +case 0x729f: +case 0x72a0: +case 0x72a1: +case 0x72a2: +case 0x72a3: +case 0x72a4: +case 0x72a5: +case 0x72a6: +case 0x72a7: +case 0x72a8: +case 0x72a9: +case 0x72aa: +case 0x72ab: +case 0x72ac: +case 0x72ad: +case 0x72ae: +case 0x72af: +case 0x72b0: +case 0x72b1: +case 0x72b2: +case 0x72b3: +case 0x72b4: +case 0x72b5: +case 0x72b6: +case 0x72b7: +case 0x72b8: +case 0x72b9: +case 0x72ba: +case 0x72bb: +case 0x72bc: +case 0x72bd: +case 0x72be: +case 0x72bf: +case 0x72c0: +case 0x72c1: +case 0x72c2: +case 0x72c3: +case 0x72c4: +case 0x72c5: +case 0x72c6: +case 0x72c7: +case 0x72c8: +case 0x72c9: +case 0x72ca: +case 0x72cb: +case 0x72cc: +case 0x72cd: +case 0x72ce: +case 0x72cf: +case 0x72d0: +case 0x72d1: +case 0x72d2: +case 0x72d3: +case 0x72d4: +case 0x72d5: +case 0x72d6: +case 0x72d7: +case 0x72d8: +case 0x72d9: +case 0x72da: +case 0x72db: +case 0x72dc: +case 0x72dd: +case 0x72de: +case 0x72df: +case 0x72e0: +case 0x72e1: +case 0x72e2: +case 0x72e3: +case 0x72e4: +case 0x72e5: +case 0x72e6: +case 0x72e7: +case 0x72e8: +case 0x72e9: +case 0x72ea: +case 0x72eb: +case 0x72ec: +case 0x72ed: +case 0x72ee: +case 0x72ef: +case 0x72f0: +case 0x72f1: +case 0x72f2: +case 0x72f3: +case 0x72f4: +case 0x72f5: +case 0x72f6: +case 0x72f7: +case 0x72f8: +case 0x72f9: +case 0x72fa: +case 0x72fb: +case 0x72fc: +case 0x72fd: +case 0x72fe: +case 0x72ff: +case 0x7400: +case 0x7401: +case 0x7402: +case 0x7403: +case 0x7404: +case 0x7405: +case 0x7406: +case 0x7407: +case 0x7408: +case 0x7409: +case 0x740a: +case 0x740b: +case 0x740c: +case 0x740d: +case 0x740e: +case 0x740f: +case 0x7410: +case 0x7411: +case 0x7412: +case 0x7413: +case 0x7414: +case 0x7415: +case 0x7416: +case 0x7417: +case 0x7418: +case 0x7419: +case 0x741a: +case 0x741b: +case 0x741c: +case 0x741d: +case 0x741e: +case 0x741f: +case 0x7420: +case 0x7421: +case 0x7422: +case 0x7423: +case 0x7424: +case 0x7425: +case 0x7426: +case 0x7427: +case 0x7428: +case 0x7429: +case 0x742a: +case 0x742b: +case 0x742c: +case 0x742d: +case 0x742e: +case 0x742f: +case 0x7430: +case 0x7431: +case 0x7432: +case 0x7433: +case 0x7434: +case 0x7435: +case 0x7436: +case 0x7437: +case 0x7438: +case 0x7439: +case 0x743a: +case 0x743b: +case 0x743c: +case 0x743d: +case 0x743e: +case 0x743f: +case 0x7440: +case 0x7441: +case 0x7442: +case 0x7443: +case 0x7444: +case 0x7445: +case 0x7446: +case 0x7447: +case 0x7448: +case 0x7449: +case 0x744a: +case 0x744b: +case 0x744c: +case 0x744d: +case 0x744e: +case 0x744f: +case 0x7450: +case 0x7451: +case 0x7452: +case 0x7453: +case 0x7454: +case 0x7455: +case 0x7456: +case 0x7457: +case 0x7458: +case 0x7459: +case 0x745a: +case 0x745b: +case 0x745c: +case 0x745d: +case 0x745e: +case 0x745f: +case 0x7460: +case 0x7461: +case 0x7462: +case 0x7463: +case 0x7464: +case 0x7465: +case 0x7466: +case 0x7467: +case 0x7468: +case 0x7469: +case 0x746a: +case 0x746b: +case 0x746c: +case 0x746d: +case 0x746e: +case 0x746f: +case 0x7470: +case 0x7471: +case 0x7472: +case 0x7473: +case 0x7474: +case 0x7475: +case 0x7476: +case 0x7477: +case 0x7478: +case 0x7479: +case 0x747a: +case 0x747b: +case 0x747c: +case 0x747d: +case 0x747e: +case 0x747f: +case 0x7480: +case 0x7481: +case 0x7482: +case 0x7483: +case 0x7484: +case 0x7485: +case 0x7486: +case 0x7487: +case 0x7488: +case 0x7489: +case 0x748a: +case 0x748b: +case 0x748c: +case 0x748d: +case 0x748e: +case 0x748f: +case 0x7490: +case 0x7491: +case 0x7492: +case 0x7493: +case 0x7494: +case 0x7495: +case 0x7496: +case 0x7497: +case 0x7498: +case 0x7499: +case 0x749a: +case 0x749b: +case 0x749c: +case 0x749d: +case 0x749e: +case 0x749f: +case 0x74a0: +case 0x74a1: +case 0x74a2: +case 0x74a3: +case 0x74a4: +case 0x74a5: +case 0x74a6: +case 0x74a7: +case 0x74a8: +case 0x74a9: +case 0x74aa: +case 0x74ab: +case 0x74ac: +case 0x74ad: +case 0x74ae: +case 0x74af: +case 0x74b0: +case 0x74b1: +case 0x74b2: +case 0x74b3: +case 0x74b4: +case 0x74b5: +case 0x74b6: +case 0x74b7: +case 0x74b8: +case 0x74b9: +case 0x74ba: +case 0x74bb: +case 0x74bc: +case 0x74bd: +case 0x74be: +case 0x74bf: +case 0x74c0: +case 0x74c1: +case 0x74c2: +case 0x74c3: +case 0x74c4: +case 0x74c5: +case 0x74c6: +case 0x74c7: +case 0x74c8: +case 0x74c9: +case 0x74ca: +case 0x74cb: +case 0x74cc: +case 0x74cd: +case 0x74ce: +case 0x74cf: +case 0x74d0: +case 0x74d1: +case 0x74d2: +case 0x74d3: +case 0x74d4: +case 0x74d5: +case 0x74d6: +case 0x74d7: +case 0x74d8: +case 0x74d9: +case 0x74da: +case 0x74db: +case 0x74dc: +case 0x74dd: +case 0x74de: +case 0x74df: +case 0x74e0: +case 0x74e1: +case 0x74e2: +case 0x74e3: +case 0x74e4: +case 0x74e5: +case 0x74e6: +case 0x74e7: +case 0x74e8: +case 0x74e9: +case 0x74ea: +case 0x74eb: +case 0x74ec: +case 0x74ed: +case 0x74ee: +case 0x74ef: +case 0x74f0: +case 0x74f1: +case 0x74f2: +case 0x74f3: +case 0x74f4: +case 0x74f5: +case 0x74f6: +case 0x74f7: +case 0x74f8: +case 0x74f9: +case 0x74fa: +case 0x74fb: +case 0x74fc: +case 0x74fd: +case 0x74fe: +case 0x74ff: +case 0x7600: +case 0x7601: +case 0x7602: +case 0x7603: +case 0x7604: +case 0x7605: +case 0x7606: +case 0x7607: +case 0x7608: +case 0x7609: +case 0x760a: +case 0x760b: +case 0x760c: +case 0x760d: +case 0x760e: +case 0x760f: +case 0x7610: +case 0x7611: +case 0x7612: +case 0x7613: +case 0x7614: +case 0x7615: +case 0x7616: +case 0x7617: +case 0x7618: +case 0x7619: +case 0x761a: +case 0x761b: +case 0x761c: +case 0x761d: +case 0x761e: +case 0x761f: +case 0x7620: +case 0x7621: +case 0x7622: +case 0x7623: +case 0x7624: +case 0x7625: +case 0x7626: +case 0x7627: +case 0x7628: +case 0x7629: +case 0x762a: +case 0x762b: +case 0x762c: +case 0x762d: +case 0x762e: +case 0x762f: +case 0x7630: +case 0x7631: +case 0x7632: +case 0x7633: +case 0x7634: +case 0x7635: +case 0x7636: +case 0x7637: +case 0x7638: +case 0x7639: +case 0x763a: +case 0x763b: +case 0x763c: +case 0x763d: +case 0x763e: +case 0x763f: +case 0x7640: +case 0x7641: +case 0x7642: +case 0x7643: +case 0x7644: +case 0x7645: +case 0x7646: +case 0x7647: +case 0x7648: +case 0x7649: +case 0x764a: +case 0x764b: +case 0x764c: +case 0x764d: +case 0x764e: +case 0x764f: +case 0x7650: +case 0x7651: +case 0x7652: +case 0x7653: +case 0x7654: +case 0x7655: +case 0x7656: +case 0x7657: +case 0x7658: +case 0x7659: +case 0x765a: +case 0x765b: +case 0x765c: +case 0x765d: +case 0x765e: +case 0x765f: +case 0x7660: +case 0x7661: +case 0x7662: +case 0x7663: +case 0x7664: +case 0x7665: +case 0x7666: +case 0x7667: +case 0x7668: +case 0x7669: +case 0x766a: +case 0x766b: +case 0x766c: +case 0x766d: +case 0x766e: +case 0x766f: +case 0x7670: +case 0x7671: +case 0x7672: +case 0x7673: +case 0x7674: +case 0x7675: +case 0x7676: +case 0x7677: +case 0x7678: +case 0x7679: +case 0x767a: +case 0x767b: +case 0x767c: +case 0x767d: +case 0x767e: +case 0x767f: +case 0x7680: +case 0x7681: +case 0x7682: +case 0x7683: +case 0x7684: +case 0x7685: +case 0x7686: +case 0x7687: +case 0x7688: +case 0x7689: +case 0x768a: +case 0x768b: +case 0x768c: +case 0x768d: +case 0x768e: +case 0x768f: +case 0x7690: +case 0x7691: +case 0x7692: +case 0x7693: +case 0x7694: +case 0x7695: +case 0x7696: +case 0x7697: +case 0x7698: +case 0x7699: +case 0x769a: +case 0x769b: +case 0x769c: +case 0x769d: +case 0x769e: +case 0x769f: +case 0x76a0: +case 0x76a1: +case 0x76a2: +case 0x76a3: +case 0x76a4: +case 0x76a5: +case 0x76a6: +case 0x76a7: +case 0x76a8: +case 0x76a9: +case 0x76aa: +case 0x76ab: +case 0x76ac: +case 0x76ad: +case 0x76ae: +case 0x76af: +case 0x76b0: +case 0x76b1: +case 0x76b2: +case 0x76b3: +case 0x76b4: +case 0x76b5: +case 0x76b6: +case 0x76b7: +case 0x76b8: +case 0x76b9: +case 0x76ba: +case 0x76bb: +case 0x76bc: +case 0x76bd: +case 0x76be: +case 0x76bf: +case 0x76c0: +case 0x76c1: +case 0x76c2: +case 0x76c3: +case 0x76c4: +case 0x76c5: +case 0x76c6: +case 0x76c7: +case 0x76c8: +case 0x76c9: +case 0x76ca: +case 0x76cb: +case 0x76cc: +case 0x76cd: +case 0x76ce: +case 0x76cf: +case 0x76d0: +case 0x76d1: +case 0x76d2: +case 0x76d3: +case 0x76d4: +case 0x76d5: +case 0x76d6: +case 0x76d7: +case 0x76d8: +case 0x76d9: +case 0x76da: +case 0x76db: +case 0x76dc: +case 0x76dd: +case 0x76de: +case 0x76df: +case 0x76e0: +case 0x76e1: +case 0x76e2: +case 0x76e3: +case 0x76e4: +case 0x76e5: +case 0x76e6: +case 0x76e7: +case 0x76e8: +case 0x76e9: +case 0x76ea: +case 0x76eb: +case 0x76ec: +case 0x76ed: +case 0x76ee: +case 0x76ef: +case 0x76f0: +case 0x76f1: +case 0x76f2: +case 0x76f3: +case 0x76f4: +case 0x76f5: +case 0x76f6: +case 0x76f7: +case 0x76f8: +case 0x76f9: +case 0x76fa: +case 0x76fb: +case 0x76fc: +case 0x76fd: +case 0x76fe: +case 0x76ff: +case 0x7800: +case 0x7801: +case 0x7802: +case 0x7803: +case 0x7804: +case 0x7805: +case 0x7806: +case 0x7807: +case 0x7808: +case 0x7809: +case 0x780a: +case 0x780b: +case 0x780c: +case 0x780d: +case 0x780e: +case 0x780f: +case 0x7810: +case 0x7811: +case 0x7812: +case 0x7813: +case 0x7814: +case 0x7815: +case 0x7816: +case 0x7817: +case 0x7818: +case 0x7819: +case 0x781a: +case 0x781b: +case 0x781c: +case 0x781d: +case 0x781e: +case 0x781f: +case 0x7820: +case 0x7821: +case 0x7822: +case 0x7823: +case 0x7824: +case 0x7825: +case 0x7826: +case 0x7827: +case 0x7828: +case 0x7829: +case 0x782a: +case 0x782b: +case 0x782c: +case 0x782d: +case 0x782e: +case 0x782f: +case 0x7830: +case 0x7831: +case 0x7832: +case 0x7833: +case 0x7834: +case 0x7835: +case 0x7836: +case 0x7837: +case 0x7838: +case 0x7839: +case 0x783a: +case 0x783b: +case 0x783c: +case 0x783d: +case 0x783e: +case 0x783f: +case 0x7840: +case 0x7841: +case 0x7842: +case 0x7843: +case 0x7844: +case 0x7845: +case 0x7846: +case 0x7847: +case 0x7848: +case 0x7849: +case 0x784a: +case 0x784b: +case 0x784c: +case 0x784d: +case 0x784e: +case 0x784f: +case 0x7850: +case 0x7851: +case 0x7852: +case 0x7853: +case 0x7854: +case 0x7855: +case 0x7856: +case 0x7857: +case 0x7858: +case 0x7859: +case 0x785a: +case 0x785b: +case 0x785c: +case 0x785d: +case 0x785e: +case 0x785f: +case 0x7860: +case 0x7861: +case 0x7862: +case 0x7863: +case 0x7864: +case 0x7865: +case 0x7866: +case 0x7867: +case 0x7868: +case 0x7869: +case 0x786a: +case 0x786b: +case 0x786c: +case 0x786d: +case 0x786e: +case 0x786f: +case 0x7870: +case 0x7871: +case 0x7872: +case 0x7873: +case 0x7874: +case 0x7875: +case 0x7876: +case 0x7877: +case 0x7878: +case 0x7879: +case 0x787a: +case 0x787b: +case 0x787c: +case 0x787d: +case 0x787e: +case 0x787f: +case 0x7880: +case 0x7881: +case 0x7882: +case 0x7883: +case 0x7884: +case 0x7885: +case 0x7886: +case 0x7887: +case 0x7888: +case 0x7889: +case 0x788a: +case 0x788b: +case 0x788c: +case 0x788d: +case 0x788e: +case 0x788f: +case 0x7890: +case 0x7891: +case 0x7892: +case 0x7893: +case 0x7894: +case 0x7895: +case 0x7896: +case 0x7897: +case 0x7898: +case 0x7899: +case 0x789a: +case 0x789b: +case 0x789c: +case 0x789d: +case 0x789e: +case 0x789f: +case 0x78a0: +case 0x78a1: +case 0x78a2: +case 0x78a3: +case 0x78a4: +case 0x78a5: +case 0x78a6: +case 0x78a7: +case 0x78a8: +case 0x78a9: +case 0x78aa: +case 0x78ab: +case 0x78ac: +case 0x78ad: +case 0x78ae: +case 0x78af: +case 0x78b0: +case 0x78b1: +case 0x78b2: +case 0x78b3: +case 0x78b4: +case 0x78b5: +case 0x78b6: +case 0x78b7: +case 0x78b8: +case 0x78b9: +case 0x78ba: +case 0x78bb: +case 0x78bc: +case 0x78bd: +case 0x78be: +case 0x78bf: +case 0x78c0: +case 0x78c1: +case 0x78c2: +case 0x78c3: +case 0x78c4: +case 0x78c5: +case 0x78c6: +case 0x78c7: +case 0x78c8: +case 0x78c9: +case 0x78ca: +case 0x78cb: +case 0x78cc: +case 0x78cd: +case 0x78ce: +case 0x78cf: +case 0x78d0: +case 0x78d1: +case 0x78d2: +case 0x78d3: +case 0x78d4: +case 0x78d5: +case 0x78d6: +case 0x78d7: +case 0x78d8: +case 0x78d9: +case 0x78da: +case 0x78db: +case 0x78dc: +case 0x78dd: +case 0x78de: +case 0x78df: +case 0x78e0: +case 0x78e1: +case 0x78e2: +case 0x78e3: +case 0x78e4: +case 0x78e5: +case 0x78e6: +case 0x78e7: +case 0x78e8: +case 0x78e9: +case 0x78ea: +case 0x78eb: +case 0x78ec: +case 0x78ed: +case 0x78ee: +case 0x78ef: +case 0x78f0: +case 0x78f1: +case 0x78f2: +case 0x78f3: +case 0x78f4: +case 0x78f5: +case 0x78f6: +case 0x78f7: +case 0x78f8: +case 0x78f9: +case 0x78fa: +case 0x78fb: +case 0x78fc: +case 0x78fd: +case 0x78fe: +case 0x78ff: +case 0x7a00: +case 0x7a01: +case 0x7a02: +case 0x7a03: +case 0x7a04: +case 0x7a05: +case 0x7a06: +case 0x7a07: +case 0x7a08: +case 0x7a09: +case 0x7a0a: +case 0x7a0b: +case 0x7a0c: +case 0x7a0d: +case 0x7a0e: +case 0x7a0f: +case 0x7a10: +case 0x7a11: +case 0x7a12: +case 0x7a13: +case 0x7a14: +case 0x7a15: +case 0x7a16: +case 0x7a17: +case 0x7a18: +case 0x7a19: +case 0x7a1a: +case 0x7a1b: +case 0x7a1c: +case 0x7a1d: +case 0x7a1e: +case 0x7a1f: +case 0x7a20: +case 0x7a21: +case 0x7a22: +case 0x7a23: +case 0x7a24: +case 0x7a25: +case 0x7a26: +case 0x7a27: +case 0x7a28: +case 0x7a29: +case 0x7a2a: +case 0x7a2b: +case 0x7a2c: +case 0x7a2d: +case 0x7a2e: +case 0x7a2f: +case 0x7a30: +case 0x7a31: +case 0x7a32: +case 0x7a33: +case 0x7a34: +case 0x7a35: +case 0x7a36: +case 0x7a37: +case 0x7a38: +case 0x7a39: +case 0x7a3a: +case 0x7a3b: +case 0x7a3c: +case 0x7a3d: +case 0x7a3e: +case 0x7a3f: +case 0x7a40: +case 0x7a41: +case 0x7a42: +case 0x7a43: +case 0x7a44: +case 0x7a45: +case 0x7a46: +case 0x7a47: +case 0x7a48: +case 0x7a49: +case 0x7a4a: +case 0x7a4b: +case 0x7a4c: +case 0x7a4d: +case 0x7a4e: +case 0x7a4f: +case 0x7a50: +case 0x7a51: +case 0x7a52: +case 0x7a53: +case 0x7a54: +case 0x7a55: +case 0x7a56: +case 0x7a57: +case 0x7a58: +case 0x7a59: +case 0x7a5a: +case 0x7a5b: +case 0x7a5c: +case 0x7a5d: +case 0x7a5e: +case 0x7a5f: +case 0x7a60: +case 0x7a61: +case 0x7a62: +case 0x7a63: +case 0x7a64: +case 0x7a65: +case 0x7a66: +case 0x7a67: +case 0x7a68: +case 0x7a69: +case 0x7a6a: +case 0x7a6b: +case 0x7a6c: +case 0x7a6d: +case 0x7a6e: +case 0x7a6f: +case 0x7a70: +case 0x7a71: +case 0x7a72: +case 0x7a73: +case 0x7a74: +case 0x7a75: +case 0x7a76: +case 0x7a77: +case 0x7a78: +case 0x7a79: +case 0x7a7a: +case 0x7a7b: +case 0x7a7c: +case 0x7a7d: +case 0x7a7e: +case 0x7a7f: +case 0x7a80: +case 0x7a81: +case 0x7a82: +case 0x7a83: +case 0x7a84: +case 0x7a85: +case 0x7a86: +case 0x7a87: +case 0x7a88: +case 0x7a89: +case 0x7a8a: +case 0x7a8b: +case 0x7a8c: +case 0x7a8d: +case 0x7a8e: +case 0x7a8f: +case 0x7a90: +case 0x7a91: +case 0x7a92: +case 0x7a93: +case 0x7a94: +case 0x7a95: +case 0x7a96: +case 0x7a97: +case 0x7a98: +case 0x7a99: +case 0x7a9a: +case 0x7a9b: +case 0x7a9c: +case 0x7a9d: +case 0x7a9e: +case 0x7a9f: +case 0x7aa0: +case 0x7aa1: +case 0x7aa2: +case 0x7aa3: +case 0x7aa4: +case 0x7aa5: +case 0x7aa6: +case 0x7aa7: +case 0x7aa8: +case 0x7aa9: +case 0x7aaa: +case 0x7aab: +case 0x7aac: +case 0x7aad: +case 0x7aae: +case 0x7aaf: +case 0x7ab0: +case 0x7ab1: +case 0x7ab2: +case 0x7ab3: +case 0x7ab4: +case 0x7ab5: +case 0x7ab6: +case 0x7ab7: +case 0x7ab8: +case 0x7ab9: +case 0x7aba: +case 0x7abb: +case 0x7abc: +case 0x7abd: +case 0x7abe: +case 0x7abf: +case 0x7ac0: +case 0x7ac1: +case 0x7ac2: +case 0x7ac3: +case 0x7ac4: +case 0x7ac5: +case 0x7ac6: +case 0x7ac7: +case 0x7ac8: +case 0x7ac9: +case 0x7aca: +case 0x7acb: +case 0x7acc: +case 0x7acd: +case 0x7ace: +case 0x7acf: +case 0x7ad0: +case 0x7ad1: +case 0x7ad2: +case 0x7ad3: +case 0x7ad4: +case 0x7ad5: +case 0x7ad6: +case 0x7ad7: +case 0x7ad8: +case 0x7ad9: +case 0x7ada: +case 0x7adb: +case 0x7adc: +case 0x7add: +case 0x7ade: +case 0x7adf: +case 0x7ae0: +case 0x7ae1: +case 0x7ae2: +case 0x7ae3: +case 0x7ae4: +case 0x7ae5: +case 0x7ae6: +case 0x7ae7: +case 0x7ae8: +case 0x7ae9: +case 0x7aea: +case 0x7aeb: +case 0x7aec: +case 0x7aed: +case 0x7aee: +case 0x7aef: +case 0x7af0: +case 0x7af1: +case 0x7af2: +case 0x7af3: +case 0x7af4: +case 0x7af5: +case 0x7af6: +case 0x7af7: +case 0x7af8: +case 0x7af9: +case 0x7afa: +case 0x7afb: +case 0x7afc: +case 0x7afd: +case 0x7afe: +case 0x7aff: +case 0x7c00: +case 0x7c01: +case 0x7c02: +case 0x7c03: +case 0x7c04: +case 0x7c05: +case 0x7c06: +case 0x7c07: +case 0x7c08: +case 0x7c09: +case 0x7c0a: +case 0x7c0b: +case 0x7c0c: +case 0x7c0d: +case 0x7c0e: +case 0x7c0f: +case 0x7c10: +case 0x7c11: +case 0x7c12: +case 0x7c13: +case 0x7c14: +case 0x7c15: +case 0x7c16: +case 0x7c17: +case 0x7c18: +case 0x7c19: +case 0x7c1a: +case 0x7c1b: +case 0x7c1c: +case 0x7c1d: +case 0x7c1e: +case 0x7c1f: +case 0x7c20: +case 0x7c21: +case 0x7c22: +case 0x7c23: +case 0x7c24: +case 0x7c25: +case 0x7c26: +case 0x7c27: +case 0x7c28: +case 0x7c29: +case 0x7c2a: +case 0x7c2b: +case 0x7c2c: +case 0x7c2d: +case 0x7c2e: +case 0x7c2f: +case 0x7c30: +case 0x7c31: +case 0x7c32: +case 0x7c33: +case 0x7c34: +case 0x7c35: +case 0x7c36: +case 0x7c37: +case 0x7c38: +case 0x7c39: +case 0x7c3a: +case 0x7c3b: +case 0x7c3c: +case 0x7c3d: +case 0x7c3e: +case 0x7c3f: +case 0x7c40: +case 0x7c41: +case 0x7c42: +case 0x7c43: +case 0x7c44: +case 0x7c45: +case 0x7c46: +case 0x7c47: +case 0x7c48: +case 0x7c49: +case 0x7c4a: +case 0x7c4b: +case 0x7c4c: +case 0x7c4d: +case 0x7c4e: +case 0x7c4f: +case 0x7c50: +case 0x7c51: +case 0x7c52: +case 0x7c53: +case 0x7c54: +case 0x7c55: +case 0x7c56: +case 0x7c57: +case 0x7c58: +case 0x7c59: +case 0x7c5a: +case 0x7c5b: +case 0x7c5c: +case 0x7c5d: +case 0x7c5e: +case 0x7c5f: +case 0x7c60: +case 0x7c61: +case 0x7c62: +case 0x7c63: +case 0x7c64: +case 0x7c65: +case 0x7c66: +case 0x7c67: +case 0x7c68: +case 0x7c69: +case 0x7c6a: +case 0x7c6b: +case 0x7c6c: +case 0x7c6d: +case 0x7c6e: +case 0x7c6f: +case 0x7c70: +case 0x7c71: +case 0x7c72: +case 0x7c73: +case 0x7c74: +case 0x7c75: +case 0x7c76: +case 0x7c77: +case 0x7c78: +case 0x7c79: +case 0x7c7a: +case 0x7c7b: +case 0x7c7c: +case 0x7c7d: +case 0x7c7e: +case 0x7c7f: +case 0x7c80: +case 0x7c81: +case 0x7c82: +case 0x7c83: +case 0x7c84: +case 0x7c85: +case 0x7c86: +case 0x7c87: +case 0x7c88: +case 0x7c89: +case 0x7c8a: +case 0x7c8b: +case 0x7c8c: +case 0x7c8d: +case 0x7c8e: +case 0x7c8f: +case 0x7c90: +case 0x7c91: +case 0x7c92: +case 0x7c93: +case 0x7c94: +case 0x7c95: +case 0x7c96: +case 0x7c97: +case 0x7c98: +case 0x7c99: +case 0x7c9a: +case 0x7c9b: +case 0x7c9c: +case 0x7c9d: +case 0x7c9e: +case 0x7c9f: +case 0x7ca0: +case 0x7ca1: +case 0x7ca2: +case 0x7ca3: +case 0x7ca4: +case 0x7ca5: +case 0x7ca6: +case 0x7ca7: +case 0x7ca8: +case 0x7ca9: +case 0x7caa: +case 0x7cab: +case 0x7cac: +case 0x7cad: +case 0x7cae: +case 0x7caf: +case 0x7cb0: +case 0x7cb1: +case 0x7cb2: +case 0x7cb3: +case 0x7cb4: +case 0x7cb5: +case 0x7cb6: +case 0x7cb7: +case 0x7cb8: +case 0x7cb9: +case 0x7cba: +case 0x7cbb: +case 0x7cbc: +case 0x7cbd: +case 0x7cbe: +case 0x7cbf: +case 0x7cc0: +case 0x7cc1: +case 0x7cc2: +case 0x7cc3: +case 0x7cc4: +case 0x7cc5: +case 0x7cc6: +case 0x7cc7: +case 0x7cc8: +case 0x7cc9: +case 0x7cca: +case 0x7ccb: +case 0x7ccc: +case 0x7ccd: +case 0x7cce: +case 0x7ccf: +case 0x7cd0: +case 0x7cd1: +case 0x7cd2: +case 0x7cd3: +case 0x7cd4: +case 0x7cd5: +case 0x7cd6: +case 0x7cd7: +case 0x7cd8: +case 0x7cd9: +case 0x7cda: +case 0x7cdb: +case 0x7cdc: +case 0x7cdd: +case 0x7cde: +case 0x7cdf: +case 0x7ce0: +case 0x7ce1: +case 0x7ce2: +case 0x7ce3: +case 0x7ce4: +case 0x7ce5: +case 0x7ce6: +case 0x7ce7: +case 0x7ce8: +case 0x7ce9: +case 0x7cea: +case 0x7ceb: +case 0x7cec: +case 0x7ced: +case 0x7cee: +case 0x7cef: +case 0x7cf0: +case 0x7cf1: +case 0x7cf2: +case 0x7cf3: +case 0x7cf4: +case 0x7cf5: +case 0x7cf6: +case 0x7cf7: +case 0x7cf8: +case 0x7cf9: +case 0x7cfa: +case 0x7cfb: +case 0x7cfc: +case 0x7cfd: +case 0x7cfe: +case 0x7cff: +case 0x7e00: +case 0x7e01: +case 0x7e02: +case 0x7e03: +case 0x7e04: +case 0x7e05: +case 0x7e06: +case 0x7e07: +case 0x7e08: +case 0x7e09: +case 0x7e0a: +case 0x7e0b: +case 0x7e0c: +case 0x7e0d: +case 0x7e0e: +case 0x7e0f: +case 0x7e10: +case 0x7e11: +case 0x7e12: +case 0x7e13: +case 0x7e14: +case 0x7e15: +case 0x7e16: +case 0x7e17: +case 0x7e18: +case 0x7e19: +case 0x7e1a: +case 0x7e1b: +case 0x7e1c: +case 0x7e1d: +case 0x7e1e: +case 0x7e1f: +case 0x7e20: +case 0x7e21: +case 0x7e22: +case 0x7e23: +case 0x7e24: +case 0x7e25: +case 0x7e26: +case 0x7e27: +case 0x7e28: +case 0x7e29: +case 0x7e2a: +case 0x7e2b: +case 0x7e2c: +case 0x7e2d: +case 0x7e2e: +case 0x7e2f: +case 0x7e30: +case 0x7e31: +case 0x7e32: +case 0x7e33: +case 0x7e34: +case 0x7e35: +case 0x7e36: +case 0x7e37: +case 0x7e38: +case 0x7e39: +case 0x7e3a: +case 0x7e3b: +case 0x7e3c: +case 0x7e3d: +case 0x7e3e: +case 0x7e3f: +case 0x7e40: +case 0x7e41: +case 0x7e42: +case 0x7e43: +case 0x7e44: +case 0x7e45: +case 0x7e46: +case 0x7e47: +case 0x7e48: +case 0x7e49: +case 0x7e4a: +case 0x7e4b: +case 0x7e4c: +case 0x7e4d: +case 0x7e4e: +case 0x7e4f: +case 0x7e50: +case 0x7e51: +case 0x7e52: +case 0x7e53: +case 0x7e54: +case 0x7e55: +case 0x7e56: +case 0x7e57: +case 0x7e58: +case 0x7e59: +case 0x7e5a: +case 0x7e5b: +case 0x7e5c: +case 0x7e5d: +case 0x7e5e: +case 0x7e5f: +case 0x7e60: +case 0x7e61: +case 0x7e62: +case 0x7e63: +case 0x7e64: +case 0x7e65: +case 0x7e66: +case 0x7e67: +case 0x7e68: +case 0x7e69: +case 0x7e6a: +case 0x7e6b: +case 0x7e6c: +case 0x7e6d: +case 0x7e6e: +case 0x7e6f: +case 0x7e70: +case 0x7e71: +case 0x7e72: +case 0x7e73: +case 0x7e74: +case 0x7e75: +case 0x7e76: +case 0x7e77: +case 0x7e78: +case 0x7e79: +case 0x7e7a: +case 0x7e7b: +case 0x7e7c: +case 0x7e7d: +case 0x7e7e: +case 0x7e7f: +case 0x7e80: +case 0x7e81: +case 0x7e82: +case 0x7e83: +case 0x7e84: +case 0x7e85: +case 0x7e86: +case 0x7e87: +case 0x7e88: +case 0x7e89: +case 0x7e8a: +case 0x7e8b: +case 0x7e8c: +case 0x7e8d: +case 0x7e8e: +case 0x7e8f: +case 0x7e90: +case 0x7e91: +case 0x7e92: +case 0x7e93: +case 0x7e94: +case 0x7e95: +case 0x7e96: +case 0x7e97: +case 0x7e98: +case 0x7e99: +case 0x7e9a: +case 0x7e9b: +case 0x7e9c: +case 0x7e9d: +case 0x7e9e: +case 0x7e9f: +case 0x7ea0: +case 0x7ea1: +case 0x7ea2: +case 0x7ea3: +case 0x7ea4: +case 0x7ea5: +case 0x7ea6: +case 0x7ea7: +case 0x7ea8: +case 0x7ea9: +case 0x7eaa: +case 0x7eab: +case 0x7eac: +case 0x7ead: +case 0x7eae: +case 0x7eaf: +case 0x7eb0: +case 0x7eb1: +case 0x7eb2: +case 0x7eb3: +case 0x7eb4: +case 0x7eb5: +case 0x7eb6: +case 0x7eb7: +case 0x7eb8: +case 0x7eb9: +case 0x7eba: +case 0x7ebb: +case 0x7ebc: +case 0x7ebd: +case 0x7ebe: +case 0x7ebf: +case 0x7ec0: +case 0x7ec1: +case 0x7ec2: +case 0x7ec3: +case 0x7ec4: +case 0x7ec5: +case 0x7ec6: +case 0x7ec7: +case 0x7ec8: +case 0x7ec9: +case 0x7eca: +case 0x7ecb: +case 0x7ecc: +case 0x7ecd: +case 0x7ece: +case 0x7ecf: +case 0x7ed0: +case 0x7ed1: +case 0x7ed2: +case 0x7ed3: +case 0x7ed4: +case 0x7ed5: +case 0x7ed6: +case 0x7ed7: +case 0x7ed8: +case 0x7ed9: +case 0x7eda: +case 0x7edb: +case 0x7edc: +case 0x7edd: +case 0x7ede: +case 0x7edf: +case 0x7ee0: +case 0x7ee1: +case 0x7ee2: +case 0x7ee3: +case 0x7ee4: +case 0x7ee5: +case 0x7ee6: +case 0x7ee7: +case 0x7ee8: +case 0x7ee9: +case 0x7eea: +case 0x7eeb: +case 0x7eec: +case 0x7eed: +case 0x7eee: +case 0x7eef: +case 0x7ef0: +case 0x7ef1: +case 0x7ef2: +case 0x7ef3: +case 0x7ef4: +case 0x7ef5: +case 0x7ef6: +case 0x7ef7: +case 0x7ef8: +case 0x7ef9: +case 0x7efa: +case 0x7efb: +case 0x7efc: +case 0x7efd: +case 0x7efe: +case 0x7eff: + { + HAM src(this, (int8)instr); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x50b9: +case 0x52b9: +case 0x54b9: +case 0x56b9: +case 0x58b9: +case 0x5ab9: +case 0x5cb9: +case 0x5eb9: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this); ADD(src, dst); + } + break; + +case 0x51b9: +case 0x53b9: +case 0x55b9: +case 0x57b9: +case 0x59b9: +case 0x5bb9: +case 0x5db9: +case 0x5fb9: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this); SUB(src, dst); + } + break; + +case 0x50b8: +case 0x52b8: +case 0x54b8: +case 0x56b8: +case 0x58b8: +case 0x5ab8: +case 0x5cb8: +case 0x5eb8: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this); ADD(src, dst); + } + break; + +case 0x51b8: +case 0x53b8: +case 0x55b8: +case 0x57b8: +case 0x59b8: +case 0x5bb8: +case 0x5db8: +case 0x5fb8: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this); SUB(src, dst); + } + break; + +case 0x5088: +case 0x5089: +case 0x508a: +case 0x508b: +case 0x508c: +case 0x508d: +case 0x508e: +case 0x508f: +case 0x5288: +case 0x5289: +case 0x528a: +case 0x528b: +case 0x528c: +case 0x528d: +case 0x528e: +case 0x528f: +case 0x5488: +case 0x5489: +case 0x548a: +case 0x548b: +case 0x548c: +case 0x548d: +case 0x548e: +case 0x548f: +case 0x5688: +case 0x5689: +case 0x568a: +case 0x568b: +case 0x568c: +case 0x568d: +case 0x568e: +case 0x568f: +case 0x5888: +case 0x5889: +case 0x588a: +case 0x588b: +case 0x588c: +case 0x588d: +case 0x588e: +case 0x588f: +case 0x5a88: +case 0x5a89: +case 0x5a8a: +case 0x5a8b: +case 0x5a8c: +case 0x5a8d: +case 0x5a8e: +case 0x5a8f: +case 0x5c88: +case 0x5c89: +case 0x5c8a: +case 0x5c8b: +case 0x5c8c: +case 0x5c8d: +case 0x5c8e: +case 0x5c8f: +case 0x5e88: +case 0x5e89: +case 0x5e8a: +case 0x5e8b: +case 0x5e8c: +case 0x5e8d: +case 0x5e8e: +case 0x5e8f: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5188: +case 0x5189: +case 0x518a: +case 0x518b: +case 0x518c: +case 0x518d: +case 0x518e: +case 0x518f: +case 0x5388: +case 0x5389: +case 0x538a: +case 0x538b: +case 0x538c: +case 0x538d: +case 0x538e: +case 0x538f: +case 0x5588: +case 0x5589: +case 0x558a: +case 0x558b: +case 0x558c: +case 0x558d: +case 0x558e: +case 0x558f: +case 0x5788: +case 0x5789: +case 0x578a: +case 0x578b: +case 0x578c: +case 0x578d: +case 0x578e: +case 0x578f: +case 0x5988: +case 0x5989: +case 0x598a: +case 0x598b: +case 0x598c: +case 0x598d: +case 0x598e: +case 0x598f: +case 0x5b88: +case 0x5b89: +case 0x5b8a: +case 0x5b8b: +case 0x5b8c: +case 0x5b8d: +case 0x5b8e: +case 0x5b8f: +case 0x5d88: +case 0x5d89: +case 0x5d8a: +case 0x5d8b: +case 0x5d8c: +case 0x5d8d: +case 0x5d8e: +case 0x5d8f: +case 0x5f88: +case 0x5f89: +case 0x5f8a: +case 0x5f8b: +case 0x5f8c: +case 0x5f8d: +case 0x5f8e: +case 0x5f8f: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x5090: +case 0x5091: +case 0x5092: +case 0x5093: +case 0x5094: +case 0x5095: +case 0x5096: +case 0x5097: +case 0x5290: +case 0x5291: +case 0x5292: +case 0x5293: +case 0x5294: +case 0x5295: +case 0x5296: +case 0x5297: +case 0x5490: +case 0x5491: +case 0x5492: +case 0x5493: +case 0x5494: +case 0x5495: +case 0x5496: +case 0x5497: +case 0x5690: +case 0x5691: +case 0x5692: +case 0x5693: +case 0x5694: +case 0x5695: +case 0x5696: +case 0x5697: +case 0x5890: +case 0x5891: +case 0x5892: +case 0x5893: +case 0x5894: +case 0x5895: +case 0x5896: +case 0x5897: +case 0x5a90: +case 0x5a91: +case 0x5a92: +case 0x5a93: +case 0x5a94: +case 0x5a95: +case 0x5a96: +case 0x5a97: +case 0x5c90: +case 0x5c91: +case 0x5c92: +case 0x5c93: +case 0x5c94: +case 0x5c95: +case 0x5c96: +case 0x5c97: +case 0x5e90: +case 0x5e91: +case 0x5e92: +case 0x5e93: +case 0x5e94: +case 0x5e95: +case 0x5e96: +case 0x5e97: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5190: +case 0x5191: +case 0x5192: +case 0x5193: +case 0x5194: +case 0x5195: +case 0x5196: +case 0x5197: +case 0x5390: +case 0x5391: +case 0x5392: +case 0x5393: +case 0x5394: +case 0x5395: +case 0x5396: +case 0x5397: +case 0x5590: +case 0x5591: +case 0x5592: +case 0x5593: +case 0x5594: +case 0x5595: +case 0x5596: +case 0x5597: +case 0x5790: +case 0x5791: +case 0x5792: +case 0x5793: +case 0x5794: +case 0x5795: +case 0x5796: +case 0x5797: +case 0x5990: +case 0x5991: +case 0x5992: +case 0x5993: +case 0x5994: +case 0x5995: +case 0x5996: +case 0x5997: +case 0x5b90: +case 0x5b91: +case 0x5b92: +case 0x5b93: +case 0x5b94: +case 0x5b95: +case 0x5b96: +case 0x5b97: +case 0x5d90: +case 0x5d91: +case 0x5d92: +case 0x5d93: +case 0x5d94: +case 0x5d95: +case 0x5d96: +case 0x5d97: +case 0x5f90: +case 0x5f91: +case 0x5f92: +case 0x5f93: +case 0x5f94: +case 0x5f95: +case 0x5f96: +case 0x5f97: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x50a8: +case 0x50a9: +case 0x50aa: +case 0x50ab: +case 0x50ac: +case 0x50ad: +case 0x50ae: +case 0x50af: +case 0x52a8: +case 0x52a9: +case 0x52aa: +case 0x52ab: +case 0x52ac: +case 0x52ad: +case 0x52ae: +case 0x52af: +case 0x54a8: +case 0x54a9: +case 0x54aa: +case 0x54ab: +case 0x54ac: +case 0x54ad: +case 0x54ae: +case 0x54af: +case 0x56a8: +case 0x56a9: +case 0x56aa: +case 0x56ab: +case 0x56ac: +case 0x56ad: +case 0x56ae: +case 0x56af: +case 0x58a8: +case 0x58a9: +case 0x58aa: +case 0x58ab: +case 0x58ac: +case 0x58ad: +case 0x58ae: +case 0x58af: +case 0x5aa8: +case 0x5aa9: +case 0x5aaa: +case 0x5aab: +case 0x5aac: +case 0x5aad: +case 0x5aae: +case 0x5aaf: +case 0x5ca8: +case 0x5ca9: +case 0x5caa: +case 0x5cab: +case 0x5cac: +case 0x5cad: +case 0x5cae: +case 0x5caf: +case 0x5ea8: +case 0x5ea9: +case 0x5eaa: +case 0x5eab: +case 0x5eac: +case 0x5ead: +case 0x5eae: +case 0x5eaf: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x51a8: +case 0x51a9: +case 0x51aa: +case 0x51ab: +case 0x51ac: +case 0x51ad: +case 0x51ae: +case 0x51af: +case 0x53a8: +case 0x53a9: +case 0x53aa: +case 0x53ab: +case 0x53ac: +case 0x53ad: +case 0x53ae: +case 0x53af: +case 0x55a8: +case 0x55a9: +case 0x55aa: +case 0x55ab: +case 0x55ac: +case 0x55ad: +case 0x55ae: +case 0x55af: +case 0x57a8: +case 0x57a9: +case 0x57aa: +case 0x57ab: +case 0x57ac: +case 0x57ad: +case 0x57ae: +case 0x57af: +case 0x59a8: +case 0x59a9: +case 0x59aa: +case 0x59ab: +case 0x59ac: +case 0x59ad: +case 0x59ae: +case 0x59af: +case 0x5ba8: +case 0x5ba9: +case 0x5baa: +case 0x5bab: +case 0x5bac: +case 0x5bad: +case 0x5bae: +case 0x5baf: +case 0x5da8: +case 0x5da9: +case 0x5daa: +case 0x5dab: +case 0x5dac: +case 0x5dad: +case 0x5dae: +case 0x5daf: +case 0x5fa8: +case 0x5fa9: +case 0x5faa: +case 0x5fab: +case 0x5fac: +case 0x5fad: +case 0x5fae: +case 0x5faf: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x50b0: +case 0x50b1: +case 0x50b2: +case 0x50b3: +case 0x50b4: +case 0x50b5: +case 0x50b6: +case 0x50b7: +case 0x52b0: +case 0x52b1: +case 0x52b2: +case 0x52b3: +case 0x52b4: +case 0x52b5: +case 0x52b6: +case 0x52b7: +case 0x54b0: +case 0x54b1: +case 0x54b2: +case 0x54b3: +case 0x54b4: +case 0x54b5: +case 0x54b6: +case 0x54b7: +case 0x56b0: +case 0x56b1: +case 0x56b2: +case 0x56b3: +case 0x56b4: +case 0x56b5: +case 0x56b6: +case 0x56b7: +case 0x58b0: +case 0x58b1: +case 0x58b2: +case 0x58b3: +case 0x58b4: +case 0x58b5: +case 0x58b6: +case 0x58b7: +case 0x5ab0: +case 0x5ab1: +case 0x5ab2: +case 0x5ab3: +case 0x5ab4: +case 0x5ab5: +case 0x5ab6: +case 0x5ab7: +case 0x5cb0: +case 0x5cb1: +case 0x5cb2: +case 0x5cb3: +case 0x5cb4: +case 0x5cb5: +case 0x5cb6: +case 0x5cb7: +case 0x5eb0: +case 0x5eb1: +case 0x5eb2: +case 0x5eb3: +case 0x5eb4: +case 0x5eb5: +case 0x5eb6: +case 0x5eb7: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x51b0: +case 0x51b1: +case 0x51b2: +case 0x51b3: +case 0x51b4: +case 0x51b5: +case 0x51b6: +case 0x51b7: +case 0x53b0: +case 0x53b1: +case 0x53b2: +case 0x53b3: +case 0x53b4: +case 0x53b5: +case 0x53b6: +case 0x53b7: +case 0x55b0: +case 0x55b1: +case 0x55b2: +case 0x55b3: +case 0x55b4: +case 0x55b5: +case 0x55b6: +case 0x55b7: +case 0x57b0: +case 0x57b1: +case 0x57b2: +case 0x57b3: +case 0x57b4: +case 0x57b5: +case 0x57b6: +case 0x57b7: +case 0x59b0: +case 0x59b1: +case 0x59b2: +case 0x59b3: +case 0x59b4: +case 0x59b5: +case 0x59b6: +case 0x59b7: +case 0x5bb0: +case 0x5bb1: +case 0x5bb2: +case 0x5bb3: +case 0x5bb4: +case 0x5bb5: +case 0x5bb6: +case 0x5bb7: +case 0x5db0: +case 0x5db1: +case 0x5db2: +case 0x5db3: +case 0x5db4: +case 0x5db5: +case 0x5db6: +case 0x5db7: +case 0x5fb0: +case 0x5fb1: +case 0x5fb2: +case 0x5fb3: +case 0x5fb4: +case 0x5fb5: +case 0x5fb6: +case 0x5fb7: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x5098: +case 0x5099: +case 0x509a: +case 0x509b: +case 0x509c: +case 0x509d: +case 0x509e: +case 0x509f: +case 0x5298: +case 0x5299: +case 0x529a: +case 0x529b: +case 0x529c: +case 0x529d: +case 0x529e: +case 0x529f: +case 0x5498: +case 0x5499: +case 0x549a: +case 0x549b: +case 0x549c: +case 0x549d: +case 0x549e: +case 0x549f: +case 0x5698: +case 0x5699: +case 0x569a: +case 0x569b: +case 0x569c: +case 0x569d: +case 0x569e: +case 0x569f: +case 0x5898: +case 0x5899: +case 0x589a: +case 0x589b: +case 0x589c: +case 0x589d: +case 0x589e: +case 0x589f: +case 0x5a98: +case 0x5a99: +case 0x5a9a: +case 0x5a9b: +case 0x5a9c: +case 0x5a9d: +case 0x5a9e: +case 0x5a9f: +case 0x5c98: +case 0x5c99: +case 0x5c9a: +case 0x5c9b: +case 0x5c9c: +case 0x5c9d: +case 0x5c9e: +case 0x5c9f: +case 0x5e98: +case 0x5e99: +case 0x5e9a: +case 0x5e9b: +case 0x5e9c: +case 0x5e9d: +case 0x5e9e: +case 0x5e9f: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5198: +case 0x5199: +case 0x519a: +case 0x519b: +case 0x519c: +case 0x519d: +case 0x519e: +case 0x519f: +case 0x5398: +case 0x5399: +case 0x539a: +case 0x539b: +case 0x539c: +case 0x539d: +case 0x539e: +case 0x539f: +case 0x5598: +case 0x5599: +case 0x559a: +case 0x559b: +case 0x559c: +case 0x559d: +case 0x559e: +case 0x559f: +case 0x5798: +case 0x5799: +case 0x579a: +case 0x579b: +case 0x579c: +case 0x579d: +case 0x579e: +case 0x579f: +case 0x5998: +case 0x5999: +case 0x599a: +case 0x599b: +case 0x599c: +case 0x599d: +case 0x599e: +case 0x599f: +case 0x5b98: +case 0x5b99: +case 0x5b9a: +case 0x5b9b: +case 0x5b9c: +case 0x5b9d: +case 0x5b9e: +case 0x5b9f: +case 0x5d98: +case 0x5d99: +case 0x5d9a: +case 0x5d9b: +case 0x5d9c: +case 0x5d9d: +case 0x5d9e: +case 0x5d9f: +case 0x5f98: +case 0x5f99: +case 0x5f9a: +case 0x5f9b: +case 0x5f9c: +case 0x5f9d: +case 0x5f9e: +case 0x5f9f: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x50a0: +case 0x50a1: +case 0x50a2: +case 0x50a3: +case 0x50a4: +case 0x50a5: +case 0x50a6: +case 0x50a7: +case 0x52a0: +case 0x52a1: +case 0x52a2: +case 0x52a3: +case 0x52a4: +case 0x52a5: +case 0x52a6: +case 0x52a7: +case 0x54a0: +case 0x54a1: +case 0x54a2: +case 0x54a3: +case 0x54a4: +case 0x54a5: +case 0x54a6: +case 0x54a7: +case 0x56a0: +case 0x56a1: +case 0x56a2: +case 0x56a3: +case 0x56a4: +case 0x56a5: +case 0x56a6: +case 0x56a7: +case 0x58a0: +case 0x58a1: +case 0x58a2: +case 0x58a3: +case 0x58a4: +case 0x58a5: +case 0x58a6: +case 0x58a7: +case 0x5aa0: +case 0x5aa1: +case 0x5aa2: +case 0x5aa3: +case 0x5aa4: +case 0x5aa5: +case 0x5aa6: +case 0x5aa7: +case 0x5ca0: +case 0x5ca1: +case 0x5ca2: +case 0x5ca3: +case 0x5ca4: +case 0x5ca5: +case 0x5ca6: +case 0x5ca7: +case 0x5ea0: +case 0x5ea1: +case 0x5ea2: +case 0x5ea3: +case 0x5ea4: +case 0x5ea5: +case 0x5ea6: +case 0x5ea7: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x51a0: +case 0x51a1: +case 0x51a2: +case 0x51a3: +case 0x51a4: +case 0x51a5: +case 0x51a6: +case 0x51a7: +case 0x53a0: +case 0x53a1: +case 0x53a2: +case 0x53a3: +case 0x53a4: +case 0x53a5: +case 0x53a6: +case 0x53a7: +case 0x55a0: +case 0x55a1: +case 0x55a2: +case 0x55a3: +case 0x55a4: +case 0x55a5: +case 0x55a6: +case 0x55a7: +case 0x57a0: +case 0x57a1: +case 0x57a2: +case 0x57a3: +case 0x57a4: +case 0x57a5: +case 0x57a6: +case 0x57a7: +case 0x59a0: +case 0x59a1: +case 0x59a2: +case 0x59a3: +case 0x59a4: +case 0x59a5: +case 0x59a6: +case 0x59a7: +case 0x5ba0: +case 0x5ba1: +case 0x5ba2: +case 0x5ba3: +case 0x5ba4: +case 0x5ba5: +case 0x5ba6: +case 0x5ba7: +case 0x5da0: +case 0x5da1: +case 0x5da2: +case 0x5da3: +case 0x5da4: +case 0x5da5: +case 0x5da6: +case 0x5da7: +case 0x5fa0: +case 0x5fa1: +case 0x5fa2: +case 0x5fa3: +case 0x5fa4: +case 0x5fa5: +case 0x5fa6: +case 0x5fa7: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x5080: +case 0x5081: +case 0x5082: +case 0x5083: +case 0x5084: +case 0x5085: +case 0x5086: +case 0x5087: +case 0x5280: +case 0x5281: +case 0x5282: +case 0x5283: +case 0x5284: +case 0x5285: +case 0x5286: +case 0x5287: +case 0x5480: +case 0x5481: +case 0x5482: +case 0x5483: +case 0x5484: +case 0x5485: +case 0x5486: +case 0x5487: +case 0x5680: +case 0x5681: +case 0x5682: +case 0x5683: +case 0x5684: +case 0x5685: +case 0x5686: +case 0x5687: +case 0x5880: +case 0x5881: +case 0x5882: +case 0x5883: +case 0x5884: +case 0x5885: +case 0x5886: +case 0x5887: +case 0x5a80: +case 0x5a81: +case 0x5a82: +case 0x5a83: +case 0x5a84: +case 0x5a85: +case 0x5a86: +case 0x5a87: +case 0x5c80: +case 0x5c81: +case 0x5c82: +case 0x5c83: +case 0x5c84: +case 0x5c85: +case 0x5c86: +case 0x5c87: +case 0x5e80: +case 0x5e81: +case 0x5e82: +case 0x5e83: +case 0x5e84: +case 0x5e85: +case 0x5e86: +case 0x5e87: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5180: +case 0x5181: +case 0x5182: +case 0x5183: +case 0x5184: +case 0x5185: +case 0x5186: +case 0x5187: +case 0x5380: +case 0x5381: +case 0x5382: +case 0x5383: +case 0x5384: +case 0x5385: +case 0x5386: +case 0x5387: +case 0x5580: +case 0x5581: +case 0x5582: +case 0x5583: +case 0x5584: +case 0x5585: +case 0x5586: +case 0x5587: +case 0x5780: +case 0x5781: +case 0x5782: +case 0x5783: +case 0x5784: +case 0x5785: +case 0x5786: +case 0x5787: +case 0x5980: +case 0x5981: +case 0x5982: +case 0x5983: +case 0x5984: +case 0x5985: +case 0x5986: +case 0x5987: +case 0x5b80: +case 0x5b81: +case 0x5b82: +case 0x5b83: +case 0x5b84: +case 0x5b85: +case 0x5b86: +case 0x5b87: +case 0x5d80: +case 0x5d81: +case 0x5d82: +case 0x5d83: +case 0x5d84: +case 0x5d85: +case 0x5d86: +case 0x5d87: +case 0x5f80: +case 0x5f81: +case 0x5f82: +case 0x5f83: +case 0x5f84: +case 0x5f85: +case 0x5f86: +case 0x5f87: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x23fa: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x21fa: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0xd1fa: +case 0xd3fa: +case 0xd5fa: +case 0xd7fa: +case 0xd9fa: +case 0xdbfa: +case 0xddfa: +case 0xdffa: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb1fa: +case 0xb3fa: +case 0xb5fa: +case 0xb7fa: +case 0xb9fa: +case 0xbbfa: +case 0xbdfa: +case 0xbffa: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x91fa: +case 0x93fa: +case 0x95fa: +case 0x97fa: +case 0x99fa: +case 0x9bfa: +case 0x9dfa: +case 0x9ffa: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x20ba: +case 0x22ba: +case 0x24ba: +case 0x26ba: +case 0x28ba: +case 0x2aba: +case 0x2cba: +case 0x2eba: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x217a: +case 0x237a: +case 0x257a: +case 0x277a: +case 0x297a: +case 0x2b7a: +case 0x2d7a: +case 0x2f7a: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x21ba: +case 0x23ba: +case 0x25ba: +case 0x27ba: +case 0x29ba: +case 0x2bba: +case 0x2dba: +case 0x2fba: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x20fa: +case 0x22fa: +case 0x24fa: +case 0x26fa: +case 0x28fa: +case 0x2afa: +case 0x2cfa: +case 0x2efa: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x213a: +case 0x233a: +case 0x253a: +case 0x273a: +case 0x293a: +case 0x2b3a: +case 0x2d3a: +case 0x2f3a: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd0ba: +case 0xd2ba: +case 0xd4ba: +case 0xd6ba: +case 0xd8ba: +case 0xdaba: +case 0xdcba: +case 0xdeba: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc0ba: +case 0xc2ba: +case 0xc4ba: +case 0xc6ba: +case 0xc8ba: +case 0xcaba: +case 0xccba: +case 0xceba: + { + HAM src(this); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb0ba: +case 0xb2ba: +case 0xb4ba: +case 0xb6ba: +case 0xb8ba: +case 0xbaba: +case 0xbcba: +case 0xbeba: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x203a: +case 0x223a: +case 0x243a: +case 0x263a: +case 0x283a: +case 0x2a3a: +case 0x2c3a: +case 0x2e3a: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x80ba: +case 0x82ba: +case 0x84ba: +case 0x86ba: +case 0x88ba: +case 0x8aba: +case 0x8cba: +case 0x8eba: + { + HAM src(this); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x90ba: +case 0x92ba: +case 0x94ba: +case 0x96ba: +case 0x98ba: +case 0x9aba: +case 0x9cba: +case 0x9eba: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x207a: +case 0x227a: +case 0x247a: +case 0x267a: +case 0x287a: +case 0x2a7a: +case 0x2c7a: +case 0x2e7a: + { + HAM src(this); MOVEA(src, instr_b11_b9); + } + break; + +case 0x23fb: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x21fb: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0xd1fb: +case 0xd3fb: +case 0xd5fb: +case 0xd7fb: +case 0xd9fb: +case 0xdbfb: +case 0xddfb: +case 0xdffb: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xb1fb: +case 0xb3fb: +case 0xb5fb: +case 0xb7fb: +case 0xb9fb: +case 0xbbfb: +case 0xbdfb: +case 0xbffb: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x91fb: +case 0x93fb: +case 0x95fb: +case 0x97fb: +case 0x99fb: +case 0x9bfb: +case 0x9dfb: +case 0x9ffb: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x20bb: +case 0x22bb: +case 0x24bb: +case 0x26bb: +case 0x28bb: +case 0x2abb: +case 0x2cbb: +case 0x2ebb: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x217b: +case 0x237b: +case 0x257b: +case 0x277b: +case 0x297b: +case 0x2b7b: +case 0x2d7b: +case 0x2f7b: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x21bb: +case 0x23bb: +case 0x25bb: +case 0x27bb: +case 0x29bb: +case 0x2bbb: +case 0x2dbb: +case 0x2fbb: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x20fb: +case 0x22fb: +case 0x24fb: +case 0x26fb: +case 0x28fb: +case 0x2afb: +case 0x2cfb: +case 0x2efb: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x213b: +case 0x233b: +case 0x253b: +case 0x273b: +case 0x293b: +case 0x2b3b: +case 0x2d3b: +case 0x2f3b: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd0bb: +case 0xd2bb: +case 0xd4bb: +case 0xd6bb: +case 0xd8bb: +case 0xdabb: +case 0xdcbb: +case 0xdebb: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc0bb: +case 0xc2bb: +case 0xc4bb: +case 0xc6bb: +case 0xc8bb: +case 0xcabb: +case 0xccbb: +case 0xcebb: + { + HAM src(this); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb0bb: +case 0xb2bb: +case 0xb4bb: +case 0xb6bb: +case 0xb8bb: +case 0xbabb: +case 0xbcbb: +case 0xbebb: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x203b: +case 0x223b: +case 0x243b: +case 0x263b: +case 0x283b: +case 0x2a3b: +case 0x2c3b: +case 0x2e3b: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x80bb: +case 0x82bb: +case 0x84bb: +case 0x86bb: +case 0x88bb: +case 0x8abb: +case 0x8cbb: +case 0x8ebb: + { + HAM src(this); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x90bb: +case 0x92bb: +case 0x94bb: +case 0x96bb: +case 0x98bb: +case 0x9abb: +case 0x9cbb: +case 0x9ebb: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x207b: +case 0x227b: +case 0x247b: +case 0x267b: +case 0x287b: +case 0x2a7b: +case 0x2c7b: +case 0x2e7b: + { + HAM src(this); MOVEA(src, instr_b11_b9); + } + break; + +case 0x4239: + { + HAM dst(this); CLR(dst); + } + break; + +case 0x4839: + { + HAM dst(this); NBCD(dst); + } + break; + +case 0x4439: + { + HAM dst(this); NEG(dst); + } + break; + +case 0x4039: + { + HAM dst(this); NEGX(dst); + } + break; + +case 0x4639: + { + HAM dst(this); NOT(dst); + } + break; + +case 0x50f9: + { + HAM dst(this); Scc<0x00>(dst); + } + break; + +case 0x51f9: + { + HAM dst(this); Scc<0x01>(dst); + } + break; + +case 0x52f9: + { + HAM dst(this); Scc<0x02>(dst); + } + break; + +case 0x53f9: + { + HAM dst(this); Scc<0x03>(dst); + } + break; + +case 0x54f9: + { + HAM dst(this); Scc<0x04>(dst); + } + break; + +case 0x55f9: + { + HAM dst(this); Scc<0x05>(dst); + } + break; + +case 0x56f9: + { + HAM dst(this); Scc<0x06>(dst); + } + break; + +case 0x57f9: + { + HAM dst(this); Scc<0x07>(dst); + } + break; + +case 0x58f9: + { + HAM dst(this); Scc<0x08>(dst); + } + break; + +case 0x59f9: + { + HAM dst(this); Scc<0x09>(dst); + } + break; + +case 0x5af9: + { + HAM dst(this); Scc<0x0a>(dst); + } + break; + +case 0x5bf9: + { + HAM dst(this); Scc<0x0b>(dst); + } + break; + +case 0x5cf9: + { + HAM dst(this); Scc<0x0c>(dst); + } + break; + +case 0x5df9: + { + HAM dst(this); Scc<0x0d>(dst); + } + break; + +case 0x5ef9: + { + HAM dst(this); Scc<0x0e>(dst); + } + break; + +case 0x5ff9: + { + HAM dst(this); Scc<0x0f>(dst); + } + break; + +case 0x4af9: + { + HAM dst(this); TAS(dst); + } + break; + +case 0x4a39: + { + HAM dst(this); TST(dst); + } + break; + +case 0x13f9: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x11f9: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x10b9: +case 0x12b9: +case 0x14b9: +case 0x16b9: +case 0x18b9: +case 0x1ab9: +case 0x1cb9: +case 0x1eb9: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1179: +case 0x1379: +case 0x1579: +case 0x1779: +case 0x1979: +case 0x1b79: +case 0x1d79: +case 0x1f79: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x11b9: +case 0x13b9: +case 0x15b9: +case 0x17b9: +case 0x19b9: +case 0x1bb9: +case 0x1db9: +case 0x1fb9: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x10f9: +case 0x12f9: +case 0x14f9: +case 0x16f9: +case 0x18f9: +case 0x1af9: +case 0x1cf9: +case 0x1ef9: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1139: +case 0x1339: +case 0x1539: +case 0x1739: +case 0x1939: +case 0x1b39: +case 0x1d39: +case 0x1f39: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd039: +case 0xd239: +case 0xd439: +case 0xd639: +case 0xd839: +case 0xda39: +case 0xdc39: +case 0xde39: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc039: +case 0xc239: +case 0xc439: +case 0xc639: +case 0xc839: +case 0xca39: +case 0xcc39: +case 0xce39: + { + HAM src(this); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb039: +case 0xb239: +case 0xb439: +case 0xb639: +case 0xb839: +case 0xba39: +case 0xbc39: +case 0xbe39: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x1039: +case 0x1239: +case 0x1439: +case 0x1639: +case 0x1839: +case 0x1a39: +case 0x1c39: +case 0x1e39: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8039: +case 0x8239: +case 0x8439: +case 0x8639: +case 0x8839: +case 0x8a39: +case 0x8c39: +case 0x8e39: + { + HAM src(this); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9039: +case 0x9239: +case 0x9439: +case 0x9639: +case 0x9839: +case 0x9a39: +case 0x9c39: +case 0x9e39: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x0179: +case 0x0379: +case 0x0579: +case 0x0779: +case 0x0979: +case 0x0b79: +case 0x0d79: +case 0x0f79: + { + HAM targ(this); BCHG(targ, D[instr_b11_b9]); + } + break; + +case 0x01b9: +case 0x03b9: +case 0x05b9: +case 0x07b9: +case 0x09b9: +case 0x0bb9: +case 0x0db9: +case 0x0fb9: + { + HAM targ(this); BCLR(targ, D[instr_b11_b9]); + } + break; + +case 0x01f9: +case 0x03f9: +case 0x05f9: +case 0x07f9: +case 0x09f9: +case 0x0bf9: +case 0x0df9: +case 0x0ff9: + { + HAM targ(this); BSET(targ, D[instr_b11_b9]); + } + break; + +case 0x0139: +case 0x0339: +case 0x0539: +case 0x0739: +case 0x0939: +case 0x0b39: +case 0x0d39: +case 0x0f39: + { + HAM targ(this); BTST(targ, D[instr_b11_b9]); + } + break; + +case 0x4238: + { + HAM dst(this); CLR(dst); + } + break; + +case 0x4838: + { + HAM dst(this); NBCD(dst); + } + break; + +case 0x4438: + { + HAM dst(this); NEG(dst); + } + break; + +case 0x4038: + { + HAM dst(this); NEGX(dst); + } + break; + +case 0x4638: + { + HAM dst(this); NOT(dst); + } + break; + +case 0x50f8: + { + HAM dst(this); Scc<0x00>(dst); + } + break; + +case 0x51f8: + { + HAM dst(this); Scc<0x01>(dst); + } + break; + +case 0x52f8: + { + HAM dst(this); Scc<0x02>(dst); + } + break; + +case 0x53f8: + { + HAM dst(this); Scc<0x03>(dst); + } + break; + +case 0x54f8: + { + HAM dst(this); Scc<0x04>(dst); + } + break; + +case 0x55f8: + { + HAM dst(this); Scc<0x05>(dst); + } + break; + +case 0x56f8: + { + HAM dst(this); Scc<0x06>(dst); + } + break; + +case 0x57f8: + { + HAM dst(this); Scc<0x07>(dst); + } + break; + +case 0x58f8: + { + HAM dst(this); Scc<0x08>(dst); + } + break; + +case 0x59f8: + { + HAM dst(this); Scc<0x09>(dst); + } + break; + +case 0x5af8: + { + HAM dst(this); Scc<0x0a>(dst); + } + break; + +case 0x5bf8: + { + HAM dst(this); Scc<0x0b>(dst); + } + break; + +case 0x5cf8: + { + HAM dst(this); Scc<0x0c>(dst); + } + break; + +case 0x5df8: + { + HAM dst(this); Scc<0x0d>(dst); + } + break; + +case 0x5ef8: + { + HAM dst(this); Scc<0x0e>(dst); + } + break; + +case 0x5ff8: + { + HAM dst(this); Scc<0x0f>(dst); + } + break; + +case 0x4af8: + { + HAM dst(this); TAS(dst); + } + break; + +case 0x4a38: + { + HAM dst(this); TST(dst); + } + break; + +case 0x13f8: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x11f8: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x10b8: +case 0x12b8: +case 0x14b8: +case 0x16b8: +case 0x18b8: +case 0x1ab8: +case 0x1cb8: +case 0x1eb8: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1178: +case 0x1378: +case 0x1578: +case 0x1778: +case 0x1978: +case 0x1b78: +case 0x1d78: +case 0x1f78: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x11b8: +case 0x13b8: +case 0x15b8: +case 0x17b8: +case 0x19b8: +case 0x1bb8: +case 0x1db8: +case 0x1fb8: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x10f8: +case 0x12f8: +case 0x14f8: +case 0x16f8: +case 0x18f8: +case 0x1af8: +case 0x1cf8: +case 0x1ef8: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1138: +case 0x1338: +case 0x1538: +case 0x1738: +case 0x1938: +case 0x1b38: +case 0x1d38: +case 0x1f38: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd038: +case 0xd238: +case 0xd438: +case 0xd638: +case 0xd838: +case 0xda38: +case 0xdc38: +case 0xde38: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc038: +case 0xc238: +case 0xc438: +case 0xc638: +case 0xc838: +case 0xca38: +case 0xcc38: +case 0xce38: + { + HAM src(this); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb038: +case 0xb238: +case 0xb438: +case 0xb638: +case 0xb838: +case 0xba38: +case 0xbc38: +case 0xbe38: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x1038: +case 0x1238: +case 0x1438: +case 0x1638: +case 0x1838: +case 0x1a38: +case 0x1c38: +case 0x1e38: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8038: +case 0x8238: +case 0x8438: +case 0x8638: +case 0x8838: +case 0x8a38: +case 0x8c38: +case 0x8e38: + { + HAM src(this); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9038: +case 0x9238: +case 0x9438: +case 0x9638: +case 0x9838: +case 0x9a38: +case 0x9c38: +case 0x9e38: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x0178: +case 0x0378: +case 0x0578: +case 0x0778: +case 0x0978: +case 0x0b78: +case 0x0d78: +case 0x0f78: + { + HAM targ(this); BCHG(targ, D[instr_b11_b9]); + } + break; + +case 0x01b8: +case 0x03b8: +case 0x05b8: +case 0x07b8: +case 0x09b8: +case 0x0bb8: +case 0x0db8: +case 0x0fb8: + { + HAM targ(this); BCLR(targ, D[instr_b11_b9]); + } + break; + +case 0x01f8: +case 0x03f8: +case 0x05f8: +case 0x07f8: +case 0x09f8: +case 0x0bf8: +case 0x0df8: +case 0x0ff8: + { + HAM targ(this); BSET(targ, D[instr_b11_b9]); + } + break; + +case 0x0138: +case 0x0338: +case 0x0538: +case 0x0738: +case 0x0938: +case 0x0b38: +case 0x0d38: +case 0x0f38: + { + HAM targ(this); BTST(targ, D[instr_b11_b9]); + } + break; + +case 0x4210: +case 0x4211: +case 0x4212: +case 0x4213: +case 0x4214: +case 0x4215: +case 0x4216: +case 0x4217: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x4810: +case 0x4811: +case 0x4812: +case 0x4813: +case 0x4814: +case 0x4815: +case 0x4816: +case 0x4817: + { + HAM dst(this, instr_b2_b0); NBCD(dst); + } + break; + +case 0x4410: +case 0x4411: +case 0x4412: +case 0x4413: +case 0x4414: +case 0x4415: +case 0x4416: +case 0x4417: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x4010: +case 0x4011: +case 0x4012: +case 0x4013: +case 0x4014: +case 0x4015: +case 0x4016: +case 0x4017: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x4610: +case 0x4611: +case 0x4612: +case 0x4613: +case 0x4614: +case 0x4615: +case 0x4616: +case 0x4617: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x50d0: +case 0x50d1: +case 0x50d2: +case 0x50d3: +case 0x50d4: +case 0x50d5: +case 0x50d6: +case 0x50d7: + { + HAM dst(this, instr_b2_b0); Scc<0x00>(dst); + } + break; + +case 0x51d0: +case 0x51d1: +case 0x51d2: +case 0x51d3: +case 0x51d4: +case 0x51d5: +case 0x51d6: +case 0x51d7: + { + HAM dst(this, instr_b2_b0); Scc<0x01>(dst); + } + break; + +case 0x52d0: +case 0x52d1: +case 0x52d2: +case 0x52d3: +case 0x52d4: +case 0x52d5: +case 0x52d6: +case 0x52d7: + { + HAM dst(this, instr_b2_b0); Scc<0x02>(dst); + } + break; + +case 0x53d0: +case 0x53d1: +case 0x53d2: +case 0x53d3: +case 0x53d4: +case 0x53d5: +case 0x53d6: +case 0x53d7: + { + HAM dst(this, instr_b2_b0); Scc<0x03>(dst); + } + break; + +case 0x54d0: +case 0x54d1: +case 0x54d2: +case 0x54d3: +case 0x54d4: +case 0x54d5: +case 0x54d6: +case 0x54d7: + { + HAM dst(this, instr_b2_b0); Scc<0x04>(dst); + } + break; + +case 0x55d0: +case 0x55d1: +case 0x55d2: +case 0x55d3: +case 0x55d4: +case 0x55d5: +case 0x55d6: +case 0x55d7: + { + HAM dst(this, instr_b2_b0); Scc<0x05>(dst); + } + break; + +case 0x56d0: +case 0x56d1: +case 0x56d2: +case 0x56d3: +case 0x56d4: +case 0x56d5: +case 0x56d6: +case 0x56d7: + { + HAM dst(this, instr_b2_b0); Scc<0x06>(dst); + } + break; + +case 0x57d0: +case 0x57d1: +case 0x57d2: +case 0x57d3: +case 0x57d4: +case 0x57d5: +case 0x57d6: +case 0x57d7: + { + HAM dst(this, instr_b2_b0); Scc<0x07>(dst); + } + break; + +case 0x58d0: +case 0x58d1: +case 0x58d2: +case 0x58d3: +case 0x58d4: +case 0x58d5: +case 0x58d6: +case 0x58d7: + { + HAM dst(this, instr_b2_b0); Scc<0x08>(dst); + } + break; + +case 0x59d0: +case 0x59d1: +case 0x59d2: +case 0x59d3: +case 0x59d4: +case 0x59d5: +case 0x59d6: +case 0x59d7: + { + HAM dst(this, instr_b2_b0); Scc<0x09>(dst); + } + break; + +case 0x5ad0: +case 0x5ad1: +case 0x5ad2: +case 0x5ad3: +case 0x5ad4: +case 0x5ad5: +case 0x5ad6: +case 0x5ad7: + { + HAM dst(this, instr_b2_b0); Scc<0x0a>(dst); + } + break; + +case 0x5bd0: +case 0x5bd1: +case 0x5bd2: +case 0x5bd3: +case 0x5bd4: +case 0x5bd5: +case 0x5bd6: +case 0x5bd7: + { + HAM dst(this, instr_b2_b0); Scc<0x0b>(dst); + } + break; + +case 0x5cd0: +case 0x5cd1: +case 0x5cd2: +case 0x5cd3: +case 0x5cd4: +case 0x5cd5: +case 0x5cd6: +case 0x5cd7: + { + HAM dst(this, instr_b2_b0); Scc<0x0c>(dst); + } + break; + +case 0x5dd0: +case 0x5dd1: +case 0x5dd2: +case 0x5dd3: +case 0x5dd4: +case 0x5dd5: +case 0x5dd6: +case 0x5dd7: + { + HAM dst(this, instr_b2_b0); Scc<0x0d>(dst); + } + break; + +case 0x5ed0: +case 0x5ed1: +case 0x5ed2: +case 0x5ed3: +case 0x5ed4: +case 0x5ed5: +case 0x5ed6: +case 0x5ed7: + { + HAM dst(this, instr_b2_b0); Scc<0x0e>(dst); + } + break; + +case 0x5fd0: +case 0x5fd1: +case 0x5fd2: +case 0x5fd3: +case 0x5fd4: +case 0x5fd5: +case 0x5fd6: +case 0x5fd7: + { + HAM dst(this, instr_b2_b0); Scc<0x0f>(dst); + } + break; + +case 0x4ad0: +case 0x4ad1: +case 0x4ad2: +case 0x4ad3: +case 0x4ad4: +case 0x4ad5: +case 0x4ad6: +case 0x4ad7: + { + HAM dst(this, instr_b2_b0); TAS(dst); + } + break; + +case 0x4a10: +case 0x4a11: +case 0x4a12: +case 0x4a13: +case 0x4a14: +case 0x4a15: +case 0x4a16: +case 0x4a17: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0x13d0: +case 0x13d1: +case 0x13d2: +case 0x13d3: +case 0x13d4: +case 0x13d5: +case 0x13d6: +case 0x13d7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x11d0: +case 0x11d1: +case 0x11d2: +case 0x11d3: +case 0x11d4: +case 0x11d5: +case 0x11d6: +case 0x11d7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x1090: +case 0x1091: +case 0x1092: +case 0x1093: +case 0x1094: +case 0x1095: +case 0x1096: +case 0x1097: +case 0x1290: +case 0x1291: +case 0x1292: +case 0x1293: +case 0x1294: +case 0x1295: +case 0x1296: +case 0x1297: +case 0x1490: +case 0x1491: +case 0x1492: +case 0x1493: +case 0x1494: +case 0x1495: +case 0x1496: +case 0x1497: +case 0x1690: +case 0x1691: +case 0x1692: +case 0x1693: +case 0x1694: +case 0x1695: +case 0x1696: +case 0x1697: +case 0x1890: +case 0x1891: +case 0x1892: +case 0x1893: +case 0x1894: +case 0x1895: +case 0x1896: +case 0x1897: +case 0x1a90: +case 0x1a91: +case 0x1a92: +case 0x1a93: +case 0x1a94: +case 0x1a95: +case 0x1a96: +case 0x1a97: +case 0x1c90: +case 0x1c91: +case 0x1c92: +case 0x1c93: +case 0x1c94: +case 0x1c95: +case 0x1c96: +case 0x1c97: +case 0x1e90: +case 0x1e91: +case 0x1e92: +case 0x1e93: +case 0x1e94: +case 0x1e95: +case 0x1e96: +case 0x1e97: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1150: +case 0x1151: +case 0x1152: +case 0x1153: +case 0x1154: +case 0x1155: +case 0x1156: +case 0x1157: +case 0x1350: +case 0x1351: +case 0x1352: +case 0x1353: +case 0x1354: +case 0x1355: +case 0x1356: +case 0x1357: +case 0x1550: +case 0x1551: +case 0x1552: +case 0x1553: +case 0x1554: +case 0x1555: +case 0x1556: +case 0x1557: +case 0x1750: +case 0x1751: +case 0x1752: +case 0x1753: +case 0x1754: +case 0x1755: +case 0x1756: +case 0x1757: +case 0x1950: +case 0x1951: +case 0x1952: +case 0x1953: +case 0x1954: +case 0x1955: +case 0x1956: +case 0x1957: +case 0x1b50: +case 0x1b51: +case 0x1b52: +case 0x1b53: +case 0x1b54: +case 0x1b55: +case 0x1b56: +case 0x1b57: +case 0x1d50: +case 0x1d51: +case 0x1d52: +case 0x1d53: +case 0x1d54: +case 0x1d55: +case 0x1d56: +case 0x1d57: +case 0x1f50: +case 0x1f51: +case 0x1f52: +case 0x1f53: +case 0x1f54: +case 0x1f55: +case 0x1f56: +case 0x1f57: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1190: +case 0x1191: +case 0x1192: +case 0x1193: +case 0x1194: +case 0x1195: +case 0x1196: +case 0x1197: +case 0x1390: +case 0x1391: +case 0x1392: +case 0x1393: +case 0x1394: +case 0x1395: +case 0x1396: +case 0x1397: +case 0x1590: +case 0x1591: +case 0x1592: +case 0x1593: +case 0x1594: +case 0x1595: +case 0x1596: +case 0x1597: +case 0x1790: +case 0x1791: +case 0x1792: +case 0x1793: +case 0x1794: +case 0x1795: +case 0x1796: +case 0x1797: +case 0x1990: +case 0x1991: +case 0x1992: +case 0x1993: +case 0x1994: +case 0x1995: +case 0x1996: +case 0x1997: +case 0x1b90: +case 0x1b91: +case 0x1b92: +case 0x1b93: +case 0x1b94: +case 0x1b95: +case 0x1b96: +case 0x1b97: +case 0x1d90: +case 0x1d91: +case 0x1d92: +case 0x1d93: +case 0x1d94: +case 0x1d95: +case 0x1d96: +case 0x1d97: +case 0x1f90: +case 0x1f91: +case 0x1f92: +case 0x1f93: +case 0x1f94: +case 0x1f95: +case 0x1f96: +case 0x1f97: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x10d0: +case 0x10d1: +case 0x10d2: +case 0x10d3: +case 0x10d4: +case 0x10d5: +case 0x10d6: +case 0x10d7: +case 0x12d0: +case 0x12d1: +case 0x12d2: +case 0x12d3: +case 0x12d4: +case 0x12d5: +case 0x12d6: +case 0x12d7: +case 0x14d0: +case 0x14d1: +case 0x14d2: +case 0x14d3: +case 0x14d4: +case 0x14d5: +case 0x14d6: +case 0x14d7: +case 0x16d0: +case 0x16d1: +case 0x16d2: +case 0x16d3: +case 0x16d4: +case 0x16d5: +case 0x16d6: +case 0x16d7: +case 0x18d0: +case 0x18d1: +case 0x18d2: +case 0x18d3: +case 0x18d4: +case 0x18d5: +case 0x18d6: +case 0x18d7: +case 0x1ad0: +case 0x1ad1: +case 0x1ad2: +case 0x1ad3: +case 0x1ad4: +case 0x1ad5: +case 0x1ad6: +case 0x1ad7: +case 0x1cd0: +case 0x1cd1: +case 0x1cd2: +case 0x1cd3: +case 0x1cd4: +case 0x1cd5: +case 0x1cd6: +case 0x1cd7: +case 0x1ed0: +case 0x1ed1: +case 0x1ed2: +case 0x1ed3: +case 0x1ed4: +case 0x1ed5: +case 0x1ed6: +case 0x1ed7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1110: +case 0x1111: +case 0x1112: +case 0x1113: +case 0x1114: +case 0x1115: +case 0x1116: +case 0x1117: +case 0x1310: +case 0x1311: +case 0x1312: +case 0x1313: +case 0x1314: +case 0x1315: +case 0x1316: +case 0x1317: +case 0x1510: +case 0x1511: +case 0x1512: +case 0x1513: +case 0x1514: +case 0x1515: +case 0x1516: +case 0x1517: +case 0x1710: +case 0x1711: +case 0x1712: +case 0x1713: +case 0x1714: +case 0x1715: +case 0x1716: +case 0x1717: +case 0x1910: +case 0x1911: +case 0x1912: +case 0x1913: +case 0x1914: +case 0x1915: +case 0x1916: +case 0x1917: +case 0x1b10: +case 0x1b11: +case 0x1b12: +case 0x1b13: +case 0x1b14: +case 0x1b15: +case 0x1b16: +case 0x1b17: +case 0x1d10: +case 0x1d11: +case 0x1d12: +case 0x1d13: +case 0x1d14: +case 0x1d15: +case 0x1d16: +case 0x1d17: +case 0x1f10: +case 0x1f11: +case 0x1f12: +case 0x1f13: +case 0x1f14: +case 0x1f15: +case 0x1f16: +case 0x1f17: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd010: +case 0xd011: +case 0xd012: +case 0xd013: +case 0xd014: +case 0xd015: +case 0xd016: +case 0xd017: +case 0xd210: +case 0xd211: +case 0xd212: +case 0xd213: +case 0xd214: +case 0xd215: +case 0xd216: +case 0xd217: +case 0xd410: +case 0xd411: +case 0xd412: +case 0xd413: +case 0xd414: +case 0xd415: +case 0xd416: +case 0xd417: +case 0xd610: +case 0xd611: +case 0xd612: +case 0xd613: +case 0xd614: +case 0xd615: +case 0xd616: +case 0xd617: +case 0xd810: +case 0xd811: +case 0xd812: +case 0xd813: +case 0xd814: +case 0xd815: +case 0xd816: +case 0xd817: +case 0xda10: +case 0xda11: +case 0xda12: +case 0xda13: +case 0xda14: +case 0xda15: +case 0xda16: +case 0xda17: +case 0xdc10: +case 0xdc11: +case 0xdc12: +case 0xdc13: +case 0xdc14: +case 0xdc15: +case 0xdc16: +case 0xdc17: +case 0xde10: +case 0xde11: +case 0xde12: +case 0xde13: +case 0xde14: +case 0xde15: +case 0xde16: +case 0xde17: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc010: +case 0xc011: +case 0xc012: +case 0xc013: +case 0xc014: +case 0xc015: +case 0xc016: +case 0xc017: +case 0xc210: +case 0xc211: +case 0xc212: +case 0xc213: +case 0xc214: +case 0xc215: +case 0xc216: +case 0xc217: +case 0xc410: +case 0xc411: +case 0xc412: +case 0xc413: +case 0xc414: +case 0xc415: +case 0xc416: +case 0xc417: +case 0xc610: +case 0xc611: +case 0xc612: +case 0xc613: +case 0xc614: +case 0xc615: +case 0xc616: +case 0xc617: +case 0xc810: +case 0xc811: +case 0xc812: +case 0xc813: +case 0xc814: +case 0xc815: +case 0xc816: +case 0xc817: +case 0xca10: +case 0xca11: +case 0xca12: +case 0xca13: +case 0xca14: +case 0xca15: +case 0xca16: +case 0xca17: +case 0xcc10: +case 0xcc11: +case 0xcc12: +case 0xcc13: +case 0xcc14: +case 0xcc15: +case 0xcc16: +case 0xcc17: +case 0xce10: +case 0xce11: +case 0xce12: +case 0xce13: +case 0xce14: +case 0xce15: +case 0xce16: +case 0xce17: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb010: +case 0xb011: +case 0xb012: +case 0xb013: +case 0xb014: +case 0xb015: +case 0xb016: +case 0xb017: +case 0xb210: +case 0xb211: +case 0xb212: +case 0xb213: +case 0xb214: +case 0xb215: +case 0xb216: +case 0xb217: +case 0xb410: +case 0xb411: +case 0xb412: +case 0xb413: +case 0xb414: +case 0xb415: +case 0xb416: +case 0xb417: +case 0xb610: +case 0xb611: +case 0xb612: +case 0xb613: +case 0xb614: +case 0xb615: +case 0xb616: +case 0xb617: +case 0xb810: +case 0xb811: +case 0xb812: +case 0xb813: +case 0xb814: +case 0xb815: +case 0xb816: +case 0xb817: +case 0xba10: +case 0xba11: +case 0xba12: +case 0xba13: +case 0xba14: +case 0xba15: +case 0xba16: +case 0xba17: +case 0xbc10: +case 0xbc11: +case 0xbc12: +case 0xbc13: +case 0xbc14: +case 0xbc15: +case 0xbc16: +case 0xbc17: +case 0xbe10: +case 0xbe11: +case 0xbe12: +case 0xbe13: +case 0xbe14: +case 0xbe15: +case 0xbe16: +case 0xbe17: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x1010: +case 0x1011: +case 0x1012: +case 0x1013: +case 0x1014: +case 0x1015: +case 0x1016: +case 0x1017: +case 0x1210: +case 0x1211: +case 0x1212: +case 0x1213: +case 0x1214: +case 0x1215: +case 0x1216: +case 0x1217: +case 0x1410: +case 0x1411: +case 0x1412: +case 0x1413: +case 0x1414: +case 0x1415: +case 0x1416: +case 0x1417: +case 0x1610: +case 0x1611: +case 0x1612: +case 0x1613: +case 0x1614: +case 0x1615: +case 0x1616: +case 0x1617: +case 0x1810: +case 0x1811: +case 0x1812: +case 0x1813: +case 0x1814: +case 0x1815: +case 0x1816: +case 0x1817: +case 0x1a10: +case 0x1a11: +case 0x1a12: +case 0x1a13: +case 0x1a14: +case 0x1a15: +case 0x1a16: +case 0x1a17: +case 0x1c10: +case 0x1c11: +case 0x1c12: +case 0x1c13: +case 0x1c14: +case 0x1c15: +case 0x1c16: +case 0x1c17: +case 0x1e10: +case 0x1e11: +case 0x1e12: +case 0x1e13: +case 0x1e14: +case 0x1e15: +case 0x1e16: +case 0x1e17: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8010: +case 0x8011: +case 0x8012: +case 0x8013: +case 0x8014: +case 0x8015: +case 0x8016: +case 0x8017: +case 0x8210: +case 0x8211: +case 0x8212: +case 0x8213: +case 0x8214: +case 0x8215: +case 0x8216: +case 0x8217: +case 0x8410: +case 0x8411: +case 0x8412: +case 0x8413: +case 0x8414: +case 0x8415: +case 0x8416: +case 0x8417: +case 0x8610: +case 0x8611: +case 0x8612: +case 0x8613: +case 0x8614: +case 0x8615: +case 0x8616: +case 0x8617: +case 0x8810: +case 0x8811: +case 0x8812: +case 0x8813: +case 0x8814: +case 0x8815: +case 0x8816: +case 0x8817: +case 0x8a10: +case 0x8a11: +case 0x8a12: +case 0x8a13: +case 0x8a14: +case 0x8a15: +case 0x8a16: +case 0x8a17: +case 0x8c10: +case 0x8c11: +case 0x8c12: +case 0x8c13: +case 0x8c14: +case 0x8c15: +case 0x8c16: +case 0x8c17: +case 0x8e10: +case 0x8e11: +case 0x8e12: +case 0x8e13: +case 0x8e14: +case 0x8e15: +case 0x8e16: +case 0x8e17: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9010: +case 0x9011: +case 0x9012: +case 0x9013: +case 0x9014: +case 0x9015: +case 0x9016: +case 0x9017: +case 0x9210: +case 0x9211: +case 0x9212: +case 0x9213: +case 0x9214: +case 0x9215: +case 0x9216: +case 0x9217: +case 0x9410: +case 0x9411: +case 0x9412: +case 0x9413: +case 0x9414: +case 0x9415: +case 0x9416: +case 0x9417: +case 0x9610: +case 0x9611: +case 0x9612: +case 0x9613: +case 0x9614: +case 0x9615: +case 0x9616: +case 0x9617: +case 0x9810: +case 0x9811: +case 0x9812: +case 0x9813: +case 0x9814: +case 0x9815: +case 0x9816: +case 0x9817: +case 0x9a10: +case 0x9a11: +case 0x9a12: +case 0x9a13: +case 0x9a14: +case 0x9a15: +case 0x9a16: +case 0x9a17: +case 0x9c10: +case 0x9c11: +case 0x9c12: +case 0x9c13: +case 0x9c14: +case 0x9c15: +case 0x9c16: +case 0x9c17: +case 0x9e10: +case 0x9e11: +case 0x9e12: +case 0x9e13: +case 0x9e14: +case 0x9e15: +case 0x9e16: +case 0x9e17: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x0150: +case 0x0151: +case 0x0152: +case 0x0153: +case 0x0154: +case 0x0155: +case 0x0156: +case 0x0157: +case 0x0350: +case 0x0351: +case 0x0352: +case 0x0353: +case 0x0354: +case 0x0355: +case 0x0356: +case 0x0357: +case 0x0550: +case 0x0551: +case 0x0552: +case 0x0553: +case 0x0554: +case 0x0555: +case 0x0556: +case 0x0557: +case 0x0750: +case 0x0751: +case 0x0752: +case 0x0753: +case 0x0754: +case 0x0755: +case 0x0756: +case 0x0757: +case 0x0950: +case 0x0951: +case 0x0952: +case 0x0953: +case 0x0954: +case 0x0955: +case 0x0956: +case 0x0957: +case 0x0b50: +case 0x0b51: +case 0x0b52: +case 0x0b53: +case 0x0b54: +case 0x0b55: +case 0x0b56: +case 0x0b57: +case 0x0d50: +case 0x0d51: +case 0x0d52: +case 0x0d53: +case 0x0d54: +case 0x0d55: +case 0x0d56: +case 0x0d57: +case 0x0f50: +case 0x0f51: +case 0x0f52: +case 0x0f53: +case 0x0f54: +case 0x0f55: +case 0x0f56: +case 0x0f57: + { + HAM targ(this, instr_b2_b0); BCHG(targ, D[instr_b11_b9]); + } + break; + +case 0x0190: +case 0x0191: +case 0x0192: +case 0x0193: +case 0x0194: +case 0x0195: +case 0x0196: +case 0x0197: +case 0x0390: +case 0x0391: +case 0x0392: +case 0x0393: +case 0x0394: +case 0x0395: +case 0x0396: +case 0x0397: +case 0x0590: +case 0x0591: +case 0x0592: +case 0x0593: +case 0x0594: +case 0x0595: +case 0x0596: +case 0x0597: +case 0x0790: +case 0x0791: +case 0x0792: +case 0x0793: +case 0x0794: +case 0x0795: +case 0x0796: +case 0x0797: +case 0x0990: +case 0x0991: +case 0x0992: +case 0x0993: +case 0x0994: +case 0x0995: +case 0x0996: +case 0x0997: +case 0x0b90: +case 0x0b91: +case 0x0b92: +case 0x0b93: +case 0x0b94: +case 0x0b95: +case 0x0b96: +case 0x0b97: +case 0x0d90: +case 0x0d91: +case 0x0d92: +case 0x0d93: +case 0x0d94: +case 0x0d95: +case 0x0d96: +case 0x0d97: +case 0x0f90: +case 0x0f91: +case 0x0f92: +case 0x0f93: +case 0x0f94: +case 0x0f95: +case 0x0f96: +case 0x0f97: + { + HAM targ(this, instr_b2_b0); BCLR(targ, D[instr_b11_b9]); + } + break; + +case 0x01d0: +case 0x01d1: +case 0x01d2: +case 0x01d3: +case 0x01d4: +case 0x01d5: +case 0x01d6: +case 0x01d7: +case 0x03d0: +case 0x03d1: +case 0x03d2: +case 0x03d3: +case 0x03d4: +case 0x03d5: +case 0x03d6: +case 0x03d7: +case 0x05d0: +case 0x05d1: +case 0x05d2: +case 0x05d3: +case 0x05d4: +case 0x05d5: +case 0x05d6: +case 0x05d7: +case 0x07d0: +case 0x07d1: +case 0x07d2: +case 0x07d3: +case 0x07d4: +case 0x07d5: +case 0x07d6: +case 0x07d7: +case 0x09d0: +case 0x09d1: +case 0x09d2: +case 0x09d3: +case 0x09d4: +case 0x09d5: +case 0x09d6: +case 0x09d7: +case 0x0bd0: +case 0x0bd1: +case 0x0bd2: +case 0x0bd3: +case 0x0bd4: +case 0x0bd5: +case 0x0bd6: +case 0x0bd7: +case 0x0dd0: +case 0x0dd1: +case 0x0dd2: +case 0x0dd3: +case 0x0dd4: +case 0x0dd5: +case 0x0dd6: +case 0x0dd7: +case 0x0fd0: +case 0x0fd1: +case 0x0fd2: +case 0x0fd3: +case 0x0fd4: +case 0x0fd5: +case 0x0fd6: +case 0x0fd7: + { + HAM targ(this, instr_b2_b0); BSET(targ, D[instr_b11_b9]); + } + break; + +case 0x0110: +case 0x0111: +case 0x0112: +case 0x0113: +case 0x0114: +case 0x0115: +case 0x0116: +case 0x0117: +case 0x0310: +case 0x0311: +case 0x0312: +case 0x0313: +case 0x0314: +case 0x0315: +case 0x0316: +case 0x0317: +case 0x0510: +case 0x0511: +case 0x0512: +case 0x0513: +case 0x0514: +case 0x0515: +case 0x0516: +case 0x0517: +case 0x0710: +case 0x0711: +case 0x0712: +case 0x0713: +case 0x0714: +case 0x0715: +case 0x0716: +case 0x0717: +case 0x0910: +case 0x0911: +case 0x0912: +case 0x0913: +case 0x0914: +case 0x0915: +case 0x0916: +case 0x0917: +case 0x0b10: +case 0x0b11: +case 0x0b12: +case 0x0b13: +case 0x0b14: +case 0x0b15: +case 0x0b16: +case 0x0b17: +case 0x0d10: +case 0x0d11: +case 0x0d12: +case 0x0d13: +case 0x0d14: +case 0x0d15: +case 0x0d16: +case 0x0d17: +case 0x0f10: +case 0x0f11: +case 0x0f12: +case 0x0f13: +case 0x0f14: +case 0x0f15: +case 0x0f16: +case 0x0f17: + { + HAM targ(this, instr_b2_b0); BTST(targ, D[instr_b11_b9]); + } + break; + +case 0x4228: +case 0x4229: +case 0x422a: +case 0x422b: +case 0x422c: +case 0x422d: +case 0x422e: +case 0x422f: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x4828: +case 0x4829: +case 0x482a: +case 0x482b: +case 0x482c: +case 0x482d: +case 0x482e: +case 0x482f: + { + HAM dst(this, instr_b2_b0); NBCD(dst); + } + break; + +case 0x4428: +case 0x4429: +case 0x442a: +case 0x442b: +case 0x442c: +case 0x442d: +case 0x442e: +case 0x442f: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x4028: +case 0x4029: +case 0x402a: +case 0x402b: +case 0x402c: +case 0x402d: +case 0x402e: +case 0x402f: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x4628: +case 0x4629: +case 0x462a: +case 0x462b: +case 0x462c: +case 0x462d: +case 0x462e: +case 0x462f: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x50e8: +case 0x50e9: +case 0x50ea: +case 0x50eb: +case 0x50ec: +case 0x50ed: +case 0x50ee: +case 0x50ef: + { + HAM dst(this, instr_b2_b0); Scc<0x00>(dst); + } + break; + +case 0x51e8: +case 0x51e9: +case 0x51ea: +case 0x51eb: +case 0x51ec: +case 0x51ed: +case 0x51ee: +case 0x51ef: + { + HAM dst(this, instr_b2_b0); Scc<0x01>(dst); + } + break; + +case 0x52e8: +case 0x52e9: +case 0x52ea: +case 0x52eb: +case 0x52ec: +case 0x52ed: +case 0x52ee: +case 0x52ef: + { + HAM dst(this, instr_b2_b0); Scc<0x02>(dst); + } + break; + +case 0x53e8: +case 0x53e9: +case 0x53ea: +case 0x53eb: +case 0x53ec: +case 0x53ed: +case 0x53ee: +case 0x53ef: + { + HAM dst(this, instr_b2_b0); Scc<0x03>(dst); + } + break; + +case 0x54e8: +case 0x54e9: +case 0x54ea: +case 0x54eb: +case 0x54ec: +case 0x54ed: +case 0x54ee: +case 0x54ef: + { + HAM dst(this, instr_b2_b0); Scc<0x04>(dst); + } + break; + +case 0x55e8: +case 0x55e9: +case 0x55ea: +case 0x55eb: +case 0x55ec: +case 0x55ed: +case 0x55ee: +case 0x55ef: + { + HAM dst(this, instr_b2_b0); Scc<0x05>(dst); + } + break; + +case 0x56e8: +case 0x56e9: +case 0x56ea: +case 0x56eb: +case 0x56ec: +case 0x56ed: +case 0x56ee: +case 0x56ef: + { + HAM dst(this, instr_b2_b0); Scc<0x06>(dst); + } + break; + +case 0x57e8: +case 0x57e9: +case 0x57ea: +case 0x57eb: +case 0x57ec: +case 0x57ed: +case 0x57ee: +case 0x57ef: + { + HAM dst(this, instr_b2_b0); Scc<0x07>(dst); + } + break; + +case 0x58e8: +case 0x58e9: +case 0x58ea: +case 0x58eb: +case 0x58ec: +case 0x58ed: +case 0x58ee: +case 0x58ef: + { + HAM dst(this, instr_b2_b0); Scc<0x08>(dst); + } + break; + +case 0x59e8: +case 0x59e9: +case 0x59ea: +case 0x59eb: +case 0x59ec: +case 0x59ed: +case 0x59ee: +case 0x59ef: + { + HAM dst(this, instr_b2_b0); Scc<0x09>(dst); + } + break; + +case 0x5ae8: +case 0x5ae9: +case 0x5aea: +case 0x5aeb: +case 0x5aec: +case 0x5aed: +case 0x5aee: +case 0x5aef: + { + HAM dst(this, instr_b2_b0); Scc<0x0a>(dst); + } + break; + +case 0x5be8: +case 0x5be9: +case 0x5bea: +case 0x5beb: +case 0x5bec: +case 0x5bed: +case 0x5bee: +case 0x5bef: + { + HAM dst(this, instr_b2_b0); Scc<0x0b>(dst); + } + break; + +case 0x5ce8: +case 0x5ce9: +case 0x5cea: +case 0x5ceb: +case 0x5cec: +case 0x5ced: +case 0x5cee: +case 0x5cef: + { + HAM dst(this, instr_b2_b0); Scc<0x0c>(dst); + } + break; + +case 0x5de8: +case 0x5de9: +case 0x5dea: +case 0x5deb: +case 0x5dec: +case 0x5ded: +case 0x5dee: +case 0x5def: + { + HAM dst(this, instr_b2_b0); Scc<0x0d>(dst); + } + break; + +case 0x5ee8: +case 0x5ee9: +case 0x5eea: +case 0x5eeb: +case 0x5eec: +case 0x5eed: +case 0x5eee: +case 0x5eef: + { + HAM dst(this, instr_b2_b0); Scc<0x0e>(dst); + } + break; + +case 0x5fe8: +case 0x5fe9: +case 0x5fea: +case 0x5feb: +case 0x5fec: +case 0x5fed: +case 0x5fee: +case 0x5fef: + { + HAM dst(this, instr_b2_b0); Scc<0x0f>(dst); + } + break; + +case 0x4ae8: +case 0x4ae9: +case 0x4aea: +case 0x4aeb: +case 0x4aec: +case 0x4aed: +case 0x4aee: +case 0x4aef: + { + HAM dst(this, instr_b2_b0); TAS(dst); + } + break; + +case 0x4a28: +case 0x4a29: +case 0x4a2a: +case 0x4a2b: +case 0x4a2c: +case 0x4a2d: +case 0x4a2e: +case 0x4a2f: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0x13e8: +case 0x13e9: +case 0x13ea: +case 0x13eb: +case 0x13ec: +case 0x13ed: +case 0x13ee: +case 0x13ef: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x11e8: +case 0x11e9: +case 0x11ea: +case 0x11eb: +case 0x11ec: +case 0x11ed: +case 0x11ee: +case 0x11ef: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x10a8: +case 0x10a9: +case 0x10aa: +case 0x10ab: +case 0x10ac: +case 0x10ad: +case 0x10ae: +case 0x10af: +case 0x12a8: +case 0x12a9: +case 0x12aa: +case 0x12ab: +case 0x12ac: +case 0x12ad: +case 0x12ae: +case 0x12af: +case 0x14a8: +case 0x14a9: +case 0x14aa: +case 0x14ab: +case 0x14ac: +case 0x14ad: +case 0x14ae: +case 0x14af: +case 0x16a8: +case 0x16a9: +case 0x16aa: +case 0x16ab: +case 0x16ac: +case 0x16ad: +case 0x16ae: +case 0x16af: +case 0x18a8: +case 0x18a9: +case 0x18aa: +case 0x18ab: +case 0x18ac: +case 0x18ad: +case 0x18ae: +case 0x18af: +case 0x1aa8: +case 0x1aa9: +case 0x1aaa: +case 0x1aab: +case 0x1aac: +case 0x1aad: +case 0x1aae: +case 0x1aaf: +case 0x1ca8: +case 0x1ca9: +case 0x1caa: +case 0x1cab: +case 0x1cac: +case 0x1cad: +case 0x1cae: +case 0x1caf: +case 0x1ea8: +case 0x1ea9: +case 0x1eaa: +case 0x1eab: +case 0x1eac: +case 0x1ead: +case 0x1eae: +case 0x1eaf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1168: +case 0x1169: +case 0x116a: +case 0x116b: +case 0x116c: +case 0x116d: +case 0x116e: +case 0x116f: +case 0x1368: +case 0x1369: +case 0x136a: +case 0x136b: +case 0x136c: +case 0x136d: +case 0x136e: +case 0x136f: +case 0x1568: +case 0x1569: +case 0x156a: +case 0x156b: +case 0x156c: +case 0x156d: +case 0x156e: +case 0x156f: +case 0x1768: +case 0x1769: +case 0x176a: +case 0x176b: +case 0x176c: +case 0x176d: +case 0x176e: +case 0x176f: +case 0x1968: +case 0x1969: +case 0x196a: +case 0x196b: +case 0x196c: +case 0x196d: +case 0x196e: +case 0x196f: +case 0x1b68: +case 0x1b69: +case 0x1b6a: +case 0x1b6b: +case 0x1b6c: +case 0x1b6d: +case 0x1b6e: +case 0x1b6f: +case 0x1d68: +case 0x1d69: +case 0x1d6a: +case 0x1d6b: +case 0x1d6c: +case 0x1d6d: +case 0x1d6e: +case 0x1d6f: +case 0x1f68: +case 0x1f69: +case 0x1f6a: +case 0x1f6b: +case 0x1f6c: +case 0x1f6d: +case 0x1f6e: +case 0x1f6f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x11a8: +case 0x11a9: +case 0x11aa: +case 0x11ab: +case 0x11ac: +case 0x11ad: +case 0x11ae: +case 0x11af: +case 0x13a8: +case 0x13a9: +case 0x13aa: +case 0x13ab: +case 0x13ac: +case 0x13ad: +case 0x13ae: +case 0x13af: +case 0x15a8: +case 0x15a9: +case 0x15aa: +case 0x15ab: +case 0x15ac: +case 0x15ad: +case 0x15ae: +case 0x15af: +case 0x17a8: +case 0x17a9: +case 0x17aa: +case 0x17ab: +case 0x17ac: +case 0x17ad: +case 0x17ae: +case 0x17af: +case 0x19a8: +case 0x19a9: +case 0x19aa: +case 0x19ab: +case 0x19ac: +case 0x19ad: +case 0x19ae: +case 0x19af: +case 0x1ba8: +case 0x1ba9: +case 0x1baa: +case 0x1bab: +case 0x1bac: +case 0x1bad: +case 0x1bae: +case 0x1baf: +case 0x1da8: +case 0x1da9: +case 0x1daa: +case 0x1dab: +case 0x1dac: +case 0x1dad: +case 0x1dae: +case 0x1daf: +case 0x1fa8: +case 0x1fa9: +case 0x1faa: +case 0x1fab: +case 0x1fac: +case 0x1fad: +case 0x1fae: +case 0x1faf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x10e8: +case 0x10e9: +case 0x10ea: +case 0x10eb: +case 0x10ec: +case 0x10ed: +case 0x10ee: +case 0x10ef: +case 0x12e8: +case 0x12e9: +case 0x12ea: +case 0x12eb: +case 0x12ec: +case 0x12ed: +case 0x12ee: +case 0x12ef: +case 0x14e8: +case 0x14e9: +case 0x14ea: +case 0x14eb: +case 0x14ec: +case 0x14ed: +case 0x14ee: +case 0x14ef: +case 0x16e8: +case 0x16e9: +case 0x16ea: +case 0x16eb: +case 0x16ec: +case 0x16ed: +case 0x16ee: +case 0x16ef: +case 0x18e8: +case 0x18e9: +case 0x18ea: +case 0x18eb: +case 0x18ec: +case 0x18ed: +case 0x18ee: +case 0x18ef: +case 0x1ae8: +case 0x1ae9: +case 0x1aea: +case 0x1aeb: +case 0x1aec: +case 0x1aed: +case 0x1aee: +case 0x1aef: +case 0x1ce8: +case 0x1ce9: +case 0x1cea: +case 0x1ceb: +case 0x1cec: +case 0x1ced: +case 0x1cee: +case 0x1cef: +case 0x1ee8: +case 0x1ee9: +case 0x1eea: +case 0x1eeb: +case 0x1eec: +case 0x1eed: +case 0x1eee: +case 0x1eef: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1128: +case 0x1129: +case 0x112a: +case 0x112b: +case 0x112c: +case 0x112d: +case 0x112e: +case 0x112f: +case 0x1328: +case 0x1329: +case 0x132a: +case 0x132b: +case 0x132c: +case 0x132d: +case 0x132e: +case 0x132f: +case 0x1528: +case 0x1529: +case 0x152a: +case 0x152b: +case 0x152c: +case 0x152d: +case 0x152e: +case 0x152f: +case 0x1728: +case 0x1729: +case 0x172a: +case 0x172b: +case 0x172c: +case 0x172d: +case 0x172e: +case 0x172f: +case 0x1928: +case 0x1929: +case 0x192a: +case 0x192b: +case 0x192c: +case 0x192d: +case 0x192e: +case 0x192f: +case 0x1b28: +case 0x1b29: +case 0x1b2a: +case 0x1b2b: +case 0x1b2c: +case 0x1b2d: +case 0x1b2e: +case 0x1b2f: +case 0x1d28: +case 0x1d29: +case 0x1d2a: +case 0x1d2b: +case 0x1d2c: +case 0x1d2d: +case 0x1d2e: +case 0x1d2f: +case 0x1f28: +case 0x1f29: +case 0x1f2a: +case 0x1f2b: +case 0x1f2c: +case 0x1f2d: +case 0x1f2e: +case 0x1f2f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd028: +case 0xd029: +case 0xd02a: +case 0xd02b: +case 0xd02c: +case 0xd02d: +case 0xd02e: +case 0xd02f: +case 0xd228: +case 0xd229: +case 0xd22a: +case 0xd22b: +case 0xd22c: +case 0xd22d: +case 0xd22e: +case 0xd22f: +case 0xd428: +case 0xd429: +case 0xd42a: +case 0xd42b: +case 0xd42c: +case 0xd42d: +case 0xd42e: +case 0xd42f: +case 0xd628: +case 0xd629: +case 0xd62a: +case 0xd62b: +case 0xd62c: +case 0xd62d: +case 0xd62e: +case 0xd62f: +case 0xd828: +case 0xd829: +case 0xd82a: +case 0xd82b: +case 0xd82c: +case 0xd82d: +case 0xd82e: +case 0xd82f: +case 0xda28: +case 0xda29: +case 0xda2a: +case 0xda2b: +case 0xda2c: +case 0xda2d: +case 0xda2e: +case 0xda2f: +case 0xdc28: +case 0xdc29: +case 0xdc2a: +case 0xdc2b: +case 0xdc2c: +case 0xdc2d: +case 0xdc2e: +case 0xdc2f: +case 0xde28: +case 0xde29: +case 0xde2a: +case 0xde2b: +case 0xde2c: +case 0xde2d: +case 0xde2e: +case 0xde2f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc028: +case 0xc029: +case 0xc02a: +case 0xc02b: +case 0xc02c: +case 0xc02d: +case 0xc02e: +case 0xc02f: +case 0xc228: +case 0xc229: +case 0xc22a: +case 0xc22b: +case 0xc22c: +case 0xc22d: +case 0xc22e: +case 0xc22f: +case 0xc428: +case 0xc429: +case 0xc42a: +case 0xc42b: +case 0xc42c: +case 0xc42d: +case 0xc42e: +case 0xc42f: +case 0xc628: +case 0xc629: +case 0xc62a: +case 0xc62b: +case 0xc62c: +case 0xc62d: +case 0xc62e: +case 0xc62f: +case 0xc828: +case 0xc829: +case 0xc82a: +case 0xc82b: +case 0xc82c: +case 0xc82d: +case 0xc82e: +case 0xc82f: +case 0xca28: +case 0xca29: +case 0xca2a: +case 0xca2b: +case 0xca2c: +case 0xca2d: +case 0xca2e: +case 0xca2f: +case 0xcc28: +case 0xcc29: +case 0xcc2a: +case 0xcc2b: +case 0xcc2c: +case 0xcc2d: +case 0xcc2e: +case 0xcc2f: +case 0xce28: +case 0xce29: +case 0xce2a: +case 0xce2b: +case 0xce2c: +case 0xce2d: +case 0xce2e: +case 0xce2f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb028: +case 0xb029: +case 0xb02a: +case 0xb02b: +case 0xb02c: +case 0xb02d: +case 0xb02e: +case 0xb02f: +case 0xb228: +case 0xb229: +case 0xb22a: +case 0xb22b: +case 0xb22c: +case 0xb22d: +case 0xb22e: +case 0xb22f: +case 0xb428: +case 0xb429: +case 0xb42a: +case 0xb42b: +case 0xb42c: +case 0xb42d: +case 0xb42e: +case 0xb42f: +case 0xb628: +case 0xb629: +case 0xb62a: +case 0xb62b: +case 0xb62c: +case 0xb62d: +case 0xb62e: +case 0xb62f: +case 0xb828: +case 0xb829: +case 0xb82a: +case 0xb82b: +case 0xb82c: +case 0xb82d: +case 0xb82e: +case 0xb82f: +case 0xba28: +case 0xba29: +case 0xba2a: +case 0xba2b: +case 0xba2c: +case 0xba2d: +case 0xba2e: +case 0xba2f: +case 0xbc28: +case 0xbc29: +case 0xbc2a: +case 0xbc2b: +case 0xbc2c: +case 0xbc2d: +case 0xbc2e: +case 0xbc2f: +case 0xbe28: +case 0xbe29: +case 0xbe2a: +case 0xbe2b: +case 0xbe2c: +case 0xbe2d: +case 0xbe2e: +case 0xbe2f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x1028: +case 0x1029: +case 0x102a: +case 0x102b: +case 0x102c: +case 0x102d: +case 0x102e: +case 0x102f: +case 0x1228: +case 0x1229: +case 0x122a: +case 0x122b: +case 0x122c: +case 0x122d: +case 0x122e: +case 0x122f: +case 0x1428: +case 0x1429: +case 0x142a: +case 0x142b: +case 0x142c: +case 0x142d: +case 0x142e: +case 0x142f: +case 0x1628: +case 0x1629: +case 0x162a: +case 0x162b: +case 0x162c: +case 0x162d: +case 0x162e: +case 0x162f: +case 0x1828: +case 0x1829: +case 0x182a: +case 0x182b: +case 0x182c: +case 0x182d: +case 0x182e: +case 0x182f: +case 0x1a28: +case 0x1a29: +case 0x1a2a: +case 0x1a2b: +case 0x1a2c: +case 0x1a2d: +case 0x1a2e: +case 0x1a2f: +case 0x1c28: +case 0x1c29: +case 0x1c2a: +case 0x1c2b: +case 0x1c2c: +case 0x1c2d: +case 0x1c2e: +case 0x1c2f: +case 0x1e28: +case 0x1e29: +case 0x1e2a: +case 0x1e2b: +case 0x1e2c: +case 0x1e2d: +case 0x1e2e: +case 0x1e2f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8028: +case 0x8029: +case 0x802a: +case 0x802b: +case 0x802c: +case 0x802d: +case 0x802e: +case 0x802f: +case 0x8228: +case 0x8229: +case 0x822a: +case 0x822b: +case 0x822c: +case 0x822d: +case 0x822e: +case 0x822f: +case 0x8428: +case 0x8429: +case 0x842a: +case 0x842b: +case 0x842c: +case 0x842d: +case 0x842e: +case 0x842f: +case 0x8628: +case 0x8629: +case 0x862a: +case 0x862b: +case 0x862c: +case 0x862d: +case 0x862e: +case 0x862f: +case 0x8828: +case 0x8829: +case 0x882a: +case 0x882b: +case 0x882c: +case 0x882d: +case 0x882e: +case 0x882f: +case 0x8a28: +case 0x8a29: +case 0x8a2a: +case 0x8a2b: +case 0x8a2c: +case 0x8a2d: +case 0x8a2e: +case 0x8a2f: +case 0x8c28: +case 0x8c29: +case 0x8c2a: +case 0x8c2b: +case 0x8c2c: +case 0x8c2d: +case 0x8c2e: +case 0x8c2f: +case 0x8e28: +case 0x8e29: +case 0x8e2a: +case 0x8e2b: +case 0x8e2c: +case 0x8e2d: +case 0x8e2e: +case 0x8e2f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9028: +case 0x9029: +case 0x902a: +case 0x902b: +case 0x902c: +case 0x902d: +case 0x902e: +case 0x902f: +case 0x9228: +case 0x9229: +case 0x922a: +case 0x922b: +case 0x922c: +case 0x922d: +case 0x922e: +case 0x922f: +case 0x9428: +case 0x9429: +case 0x942a: +case 0x942b: +case 0x942c: +case 0x942d: +case 0x942e: +case 0x942f: +case 0x9628: +case 0x9629: +case 0x962a: +case 0x962b: +case 0x962c: +case 0x962d: +case 0x962e: +case 0x962f: +case 0x9828: +case 0x9829: +case 0x982a: +case 0x982b: +case 0x982c: +case 0x982d: +case 0x982e: +case 0x982f: +case 0x9a28: +case 0x9a29: +case 0x9a2a: +case 0x9a2b: +case 0x9a2c: +case 0x9a2d: +case 0x9a2e: +case 0x9a2f: +case 0x9c28: +case 0x9c29: +case 0x9c2a: +case 0x9c2b: +case 0x9c2c: +case 0x9c2d: +case 0x9c2e: +case 0x9c2f: +case 0x9e28: +case 0x9e29: +case 0x9e2a: +case 0x9e2b: +case 0x9e2c: +case 0x9e2d: +case 0x9e2e: +case 0x9e2f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x0168: +case 0x0169: +case 0x016a: +case 0x016b: +case 0x016c: +case 0x016d: +case 0x016e: +case 0x016f: +case 0x0368: +case 0x0369: +case 0x036a: +case 0x036b: +case 0x036c: +case 0x036d: +case 0x036e: +case 0x036f: +case 0x0568: +case 0x0569: +case 0x056a: +case 0x056b: +case 0x056c: +case 0x056d: +case 0x056e: +case 0x056f: +case 0x0768: +case 0x0769: +case 0x076a: +case 0x076b: +case 0x076c: +case 0x076d: +case 0x076e: +case 0x076f: +case 0x0968: +case 0x0969: +case 0x096a: +case 0x096b: +case 0x096c: +case 0x096d: +case 0x096e: +case 0x096f: +case 0x0b68: +case 0x0b69: +case 0x0b6a: +case 0x0b6b: +case 0x0b6c: +case 0x0b6d: +case 0x0b6e: +case 0x0b6f: +case 0x0d68: +case 0x0d69: +case 0x0d6a: +case 0x0d6b: +case 0x0d6c: +case 0x0d6d: +case 0x0d6e: +case 0x0d6f: +case 0x0f68: +case 0x0f69: +case 0x0f6a: +case 0x0f6b: +case 0x0f6c: +case 0x0f6d: +case 0x0f6e: +case 0x0f6f: + { + HAM targ(this, instr_b2_b0); BCHG(targ, D[instr_b11_b9]); + } + break; + +case 0x01a8: +case 0x01a9: +case 0x01aa: +case 0x01ab: +case 0x01ac: +case 0x01ad: +case 0x01ae: +case 0x01af: +case 0x03a8: +case 0x03a9: +case 0x03aa: +case 0x03ab: +case 0x03ac: +case 0x03ad: +case 0x03ae: +case 0x03af: +case 0x05a8: +case 0x05a9: +case 0x05aa: +case 0x05ab: +case 0x05ac: +case 0x05ad: +case 0x05ae: +case 0x05af: +case 0x07a8: +case 0x07a9: +case 0x07aa: +case 0x07ab: +case 0x07ac: +case 0x07ad: +case 0x07ae: +case 0x07af: +case 0x09a8: +case 0x09a9: +case 0x09aa: +case 0x09ab: +case 0x09ac: +case 0x09ad: +case 0x09ae: +case 0x09af: +case 0x0ba8: +case 0x0ba9: +case 0x0baa: +case 0x0bab: +case 0x0bac: +case 0x0bad: +case 0x0bae: +case 0x0baf: +case 0x0da8: +case 0x0da9: +case 0x0daa: +case 0x0dab: +case 0x0dac: +case 0x0dad: +case 0x0dae: +case 0x0daf: +case 0x0fa8: +case 0x0fa9: +case 0x0faa: +case 0x0fab: +case 0x0fac: +case 0x0fad: +case 0x0fae: +case 0x0faf: + { + HAM targ(this, instr_b2_b0); BCLR(targ, D[instr_b11_b9]); + } + break; + +case 0x01e8: +case 0x01e9: +case 0x01ea: +case 0x01eb: +case 0x01ec: +case 0x01ed: +case 0x01ee: +case 0x01ef: +case 0x03e8: +case 0x03e9: +case 0x03ea: +case 0x03eb: +case 0x03ec: +case 0x03ed: +case 0x03ee: +case 0x03ef: +case 0x05e8: +case 0x05e9: +case 0x05ea: +case 0x05eb: +case 0x05ec: +case 0x05ed: +case 0x05ee: +case 0x05ef: +case 0x07e8: +case 0x07e9: +case 0x07ea: +case 0x07eb: +case 0x07ec: +case 0x07ed: +case 0x07ee: +case 0x07ef: +case 0x09e8: +case 0x09e9: +case 0x09ea: +case 0x09eb: +case 0x09ec: +case 0x09ed: +case 0x09ee: +case 0x09ef: +case 0x0be8: +case 0x0be9: +case 0x0bea: +case 0x0beb: +case 0x0bec: +case 0x0bed: +case 0x0bee: +case 0x0bef: +case 0x0de8: +case 0x0de9: +case 0x0dea: +case 0x0deb: +case 0x0dec: +case 0x0ded: +case 0x0dee: +case 0x0def: +case 0x0fe8: +case 0x0fe9: +case 0x0fea: +case 0x0feb: +case 0x0fec: +case 0x0fed: +case 0x0fee: +case 0x0fef: + { + HAM targ(this, instr_b2_b0); BSET(targ, D[instr_b11_b9]); + } + break; + +case 0x0128: +case 0x0129: +case 0x012a: +case 0x012b: +case 0x012c: +case 0x012d: +case 0x012e: +case 0x012f: +case 0x0328: +case 0x0329: +case 0x032a: +case 0x032b: +case 0x032c: +case 0x032d: +case 0x032e: +case 0x032f: +case 0x0528: +case 0x0529: +case 0x052a: +case 0x052b: +case 0x052c: +case 0x052d: +case 0x052e: +case 0x052f: +case 0x0728: +case 0x0729: +case 0x072a: +case 0x072b: +case 0x072c: +case 0x072d: +case 0x072e: +case 0x072f: +case 0x0928: +case 0x0929: +case 0x092a: +case 0x092b: +case 0x092c: +case 0x092d: +case 0x092e: +case 0x092f: +case 0x0b28: +case 0x0b29: +case 0x0b2a: +case 0x0b2b: +case 0x0b2c: +case 0x0b2d: +case 0x0b2e: +case 0x0b2f: +case 0x0d28: +case 0x0d29: +case 0x0d2a: +case 0x0d2b: +case 0x0d2c: +case 0x0d2d: +case 0x0d2e: +case 0x0d2f: +case 0x0f28: +case 0x0f29: +case 0x0f2a: +case 0x0f2b: +case 0x0f2c: +case 0x0f2d: +case 0x0f2e: +case 0x0f2f: + { + HAM targ(this, instr_b2_b0); BTST(targ, D[instr_b11_b9]); + } + break; + +case 0x4230: +case 0x4231: +case 0x4232: +case 0x4233: +case 0x4234: +case 0x4235: +case 0x4236: +case 0x4237: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x4830: +case 0x4831: +case 0x4832: +case 0x4833: +case 0x4834: +case 0x4835: +case 0x4836: +case 0x4837: + { + HAM dst(this, instr_b2_b0); NBCD(dst); + } + break; + +case 0x4430: +case 0x4431: +case 0x4432: +case 0x4433: +case 0x4434: +case 0x4435: +case 0x4436: +case 0x4437: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x4030: +case 0x4031: +case 0x4032: +case 0x4033: +case 0x4034: +case 0x4035: +case 0x4036: +case 0x4037: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x4630: +case 0x4631: +case 0x4632: +case 0x4633: +case 0x4634: +case 0x4635: +case 0x4636: +case 0x4637: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x50f0: +case 0x50f1: +case 0x50f2: +case 0x50f3: +case 0x50f4: +case 0x50f5: +case 0x50f6: +case 0x50f7: + { + HAM dst(this, instr_b2_b0); Scc<0x00>(dst); + } + break; + +case 0x51f0: +case 0x51f1: +case 0x51f2: +case 0x51f3: +case 0x51f4: +case 0x51f5: +case 0x51f6: +case 0x51f7: + { + HAM dst(this, instr_b2_b0); Scc<0x01>(dst); + } + break; + +case 0x52f0: +case 0x52f1: +case 0x52f2: +case 0x52f3: +case 0x52f4: +case 0x52f5: +case 0x52f6: +case 0x52f7: + { + HAM dst(this, instr_b2_b0); Scc<0x02>(dst); + } + break; + +case 0x53f0: +case 0x53f1: +case 0x53f2: +case 0x53f3: +case 0x53f4: +case 0x53f5: +case 0x53f6: +case 0x53f7: + { + HAM dst(this, instr_b2_b0); Scc<0x03>(dst); + } + break; + +case 0x54f0: +case 0x54f1: +case 0x54f2: +case 0x54f3: +case 0x54f4: +case 0x54f5: +case 0x54f6: +case 0x54f7: + { + HAM dst(this, instr_b2_b0); Scc<0x04>(dst); + } + break; + +case 0x55f0: +case 0x55f1: +case 0x55f2: +case 0x55f3: +case 0x55f4: +case 0x55f5: +case 0x55f6: +case 0x55f7: + { + HAM dst(this, instr_b2_b0); Scc<0x05>(dst); + } + break; + +case 0x56f0: +case 0x56f1: +case 0x56f2: +case 0x56f3: +case 0x56f4: +case 0x56f5: +case 0x56f6: +case 0x56f7: + { + HAM dst(this, instr_b2_b0); Scc<0x06>(dst); + } + break; + +case 0x57f0: +case 0x57f1: +case 0x57f2: +case 0x57f3: +case 0x57f4: +case 0x57f5: +case 0x57f6: +case 0x57f7: + { + HAM dst(this, instr_b2_b0); Scc<0x07>(dst); + } + break; + +case 0x58f0: +case 0x58f1: +case 0x58f2: +case 0x58f3: +case 0x58f4: +case 0x58f5: +case 0x58f6: +case 0x58f7: + { + HAM dst(this, instr_b2_b0); Scc<0x08>(dst); + } + break; + +case 0x59f0: +case 0x59f1: +case 0x59f2: +case 0x59f3: +case 0x59f4: +case 0x59f5: +case 0x59f6: +case 0x59f7: + { + HAM dst(this, instr_b2_b0); Scc<0x09>(dst); + } + break; + +case 0x5af0: +case 0x5af1: +case 0x5af2: +case 0x5af3: +case 0x5af4: +case 0x5af5: +case 0x5af6: +case 0x5af7: + { + HAM dst(this, instr_b2_b0); Scc<0x0a>(dst); + } + break; + +case 0x5bf0: +case 0x5bf1: +case 0x5bf2: +case 0x5bf3: +case 0x5bf4: +case 0x5bf5: +case 0x5bf6: +case 0x5bf7: + { + HAM dst(this, instr_b2_b0); Scc<0x0b>(dst); + } + break; + +case 0x5cf0: +case 0x5cf1: +case 0x5cf2: +case 0x5cf3: +case 0x5cf4: +case 0x5cf5: +case 0x5cf6: +case 0x5cf7: + { + HAM dst(this, instr_b2_b0); Scc<0x0c>(dst); + } + break; + +case 0x5df0: +case 0x5df1: +case 0x5df2: +case 0x5df3: +case 0x5df4: +case 0x5df5: +case 0x5df6: +case 0x5df7: + { + HAM dst(this, instr_b2_b0); Scc<0x0d>(dst); + } + break; + +case 0x5ef0: +case 0x5ef1: +case 0x5ef2: +case 0x5ef3: +case 0x5ef4: +case 0x5ef5: +case 0x5ef6: +case 0x5ef7: + { + HAM dst(this, instr_b2_b0); Scc<0x0e>(dst); + } + break; + +case 0x5ff0: +case 0x5ff1: +case 0x5ff2: +case 0x5ff3: +case 0x5ff4: +case 0x5ff5: +case 0x5ff6: +case 0x5ff7: + { + HAM dst(this, instr_b2_b0); Scc<0x0f>(dst); + } + break; + +case 0x4af0: +case 0x4af1: +case 0x4af2: +case 0x4af3: +case 0x4af4: +case 0x4af5: +case 0x4af6: +case 0x4af7: + { + HAM dst(this, instr_b2_b0); TAS(dst); + } + break; + +case 0x4a30: +case 0x4a31: +case 0x4a32: +case 0x4a33: +case 0x4a34: +case 0x4a35: +case 0x4a36: +case 0x4a37: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0x13f0: +case 0x13f1: +case 0x13f2: +case 0x13f3: +case 0x13f4: +case 0x13f5: +case 0x13f6: +case 0x13f7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x11f0: +case 0x11f1: +case 0x11f2: +case 0x11f3: +case 0x11f4: +case 0x11f5: +case 0x11f6: +case 0x11f7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x10b0: +case 0x10b1: +case 0x10b2: +case 0x10b3: +case 0x10b4: +case 0x10b5: +case 0x10b6: +case 0x10b7: +case 0x12b0: +case 0x12b1: +case 0x12b2: +case 0x12b3: +case 0x12b4: +case 0x12b5: +case 0x12b6: +case 0x12b7: +case 0x14b0: +case 0x14b1: +case 0x14b2: +case 0x14b3: +case 0x14b4: +case 0x14b5: +case 0x14b6: +case 0x14b7: +case 0x16b0: +case 0x16b1: +case 0x16b2: +case 0x16b3: +case 0x16b4: +case 0x16b5: +case 0x16b6: +case 0x16b7: +case 0x18b0: +case 0x18b1: +case 0x18b2: +case 0x18b3: +case 0x18b4: +case 0x18b5: +case 0x18b6: +case 0x18b7: +case 0x1ab0: +case 0x1ab1: +case 0x1ab2: +case 0x1ab3: +case 0x1ab4: +case 0x1ab5: +case 0x1ab6: +case 0x1ab7: +case 0x1cb0: +case 0x1cb1: +case 0x1cb2: +case 0x1cb3: +case 0x1cb4: +case 0x1cb5: +case 0x1cb6: +case 0x1cb7: +case 0x1eb0: +case 0x1eb1: +case 0x1eb2: +case 0x1eb3: +case 0x1eb4: +case 0x1eb5: +case 0x1eb6: +case 0x1eb7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1170: +case 0x1171: +case 0x1172: +case 0x1173: +case 0x1174: +case 0x1175: +case 0x1176: +case 0x1177: +case 0x1370: +case 0x1371: +case 0x1372: +case 0x1373: +case 0x1374: +case 0x1375: +case 0x1376: +case 0x1377: +case 0x1570: +case 0x1571: +case 0x1572: +case 0x1573: +case 0x1574: +case 0x1575: +case 0x1576: +case 0x1577: +case 0x1770: +case 0x1771: +case 0x1772: +case 0x1773: +case 0x1774: +case 0x1775: +case 0x1776: +case 0x1777: +case 0x1970: +case 0x1971: +case 0x1972: +case 0x1973: +case 0x1974: +case 0x1975: +case 0x1976: +case 0x1977: +case 0x1b70: +case 0x1b71: +case 0x1b72: +case 0x1b73: +case 0x1b74: +case 0x1b75: +case 0x1b76: +case 0x1b77: +case 0x1d70: +case 0x1d71: +case 0x1d72: +case 0x1d73: +case 0x1d74: +case 0x1d75: +case 0x1d76: +case 0x1d77: +case 0x1f70: +case 0x1f71: +case 0x1f72: +case 0x1f73: +case 0x1f74: +case 0x1f75: +case 0x1f76: +case 0x1f77: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x11b0: +case 0x11b1: +case 0x11b2: +case 0x11b3: +case 0x11b4: +case 0x11b5: +case 0x11b6: +case 0x11b7: +case 0x13b0: +case 0x13b1: +case 0x13b2: +case 0x13b3: +case 0x13b4: +case 0x13b5: +case 0x13b6: +case 0x13b7: +case 0x15b0: +case 0x15b1: +case 0x15b2: +case 0x15b3: +case 0x15b4: +case 0x15b5: +case 0x15b6: +case 0x15b7: +case 0x17b0: +case 0x17b1: +case 0x17b2: +case 0x17b3: +case 0x17b4: +case 0x17b5: +case 0x17b6: +case 0x17b7: +case 0x19b0: +case 0x19b1: +case 0x19b2: +case 0x19b3: +case 0x19b4: +case 0x19b5: +case 0x19b6: +case 0x19b7: +case 0x1bb0: +case 0x1bb1: +case 0x1bb2: +case 0x1bb3: +case 0x1bb4: +case 0x1bb5: +case 0x1bb6: +case 0x1bb7: +case 0x1db0: +case 0x1db1: +case 0x1db2: +case 0x1db3: +case 0x1db4: +case 0x1db5: +case 0x1db6: +case 0x1db7: +case 0x1fb0: +case 0x1fb1: +case 0x1fb2: +case 0x1fb3: +case 0x1fb4: +case 0x1fb5: +case 0x1fb6: +case 0x1fb7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x10f0: +case 0x10f1: +case 0x10f2: +case 0x10f3: +case 0x10f4: +case 0x10f5: +case 0x10f6: +case 0x10f7: +case 0x12f0: +case 0x12f1: +case 0x12f2: +case 0x12f3: +case 0x12f4: +case 0x12f5: +case 0x12f6: +case 0x12f7: +case 0x14f0: +case 0x14f1: +case 0x14f2: +case 0x14f3: +case 0x14f4: +case 0x14f5: +case 0x14f6: +case 0x14f7: +case 0x16f0: +case 0x16f1: +case 0x16f2: +case 0x16f3: +case 0x16f4: +case 0x16f5: +case 0x16f6: +case 0x16f7: +case 0x18f0: +case 0x18f1: +case 0x18f2: +case 0x18f3: +case 0x18f4: +case 0x18f5: +case 0x18f6: +case 0x18f7: +case 0x1af0: +case 0x1af1: +case 0x1af2: +case 0x1af3: +case 0x1af4: +case 0x1af5: +case 0x1af6: +case 0x1af7: +case 0x1cf0: +case 0x1cf1: +case 0x1cf2: +case 0x1cf3: +case 0x1cf4: +case 0x1cf5: +case 0x1cf6: +case 0x1cf7: +case 0x1ef0: +case 0x1ef1: +case 0x1ef2: +case 0x1ef3: +case 0x1ef4: +case 0x1ef5: +case 0x1ef6: +case 0x1ef7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1130: +case 0x1131: +case 0x1132: +case 0x1133: +case 0x1134: +case 0x1135: +case 0x1136: +case 0x1137: +case 0x1330: +case 0x1331: +case 0x1332: +case 0x1333: +case 0x1334: +case 0x1335: +case 0x1336: +case 0x1337: +case 0x1530: +case 0x1531: +case 0x1532: +case 0x1533: +case 0x1534: +case 0x1535: +case 0x1536: +case 0x1537: +case 0x1730: +case 0x1731: +case 0x1732: +case 0x1733: +case 0x1734: +case 0x1735: +case 0x1736: +case 0x1737: +case 0x1930: +case 0x1931: +case 0x1932: +case 0x1933: +case 0x1934: +case 0x1935: +case 0x1936: +case 0x1937: +case 0x1b30: +case 0x1b31: +case 0x1b32: +case 0x1b33: +case 0x1b34: +case 0x1b35: +case 0x1b36: +case 0x1b37: +case 0x1d30: +case 0x1d31: +case 0x1d32: +case 0x1d33: +case 0x1d34: +case 0x1d35: +case 0x1d36: +case 0x1d37: +case 0x1f30: +case 0x1f31: +case 0x1f32: +case 0x1f33: +case 0x1f34: +case 0x1f35: +case 0x1f36: +case 0x1f37: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd030: +case 0xd031: +case 0xd032: +case 0xd033: +case 0xd034: +case 0xd035: +case 0xd036: +case 0xd037: +case 0xd230: +case 0xd231: +case 0xd232: +case 0xd233: +case 0xd234: +case 0xd235: +case 0xd236: +case 0xd237: +case 0xd430: +case 0xd431: +case 0xd432: +case 0xd433: +case 0xd434: +case 0xd435: +case 0xd436: +case 0xd437: +case 0xd630: +case 0xd631: +case 0xd632: +case 0xd633: +case 0xd634: +case 0xd635: +case 0xd636: +case 0xd637: +case 0xd830: +case 0xd831: +case 0xd832: +case 0xd833: +case 0xd834: +case 0xd835: +case 0xd836: +case 0xd837: +case 0xda30: +case 0xda31: +case 0xda32: +case 0xda33: +case 0xda34: +case 0xda35: +case 0xda36: +case 0xda37: +case 0xdc30: +case 0xdc31: +case 0xdc32: +case 0xdc33: +case 0xdc34: +case 0xdc35: +case 0xdc36: +case 0xdc37: +case 0xde30: +case 0xde31: +case 0xde32: +case 0xde33: +case 0xde34: +case 0xde35: +case 0xde36: +case 0xde37: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc030: +case 0xc031: +case 0xc032: +case 0xc033: +case 0xc034: +case 0xc035: +case 0xc036: +case 0xc037: +case 0xc230: +case 0xc231: +case 0xc232: +case 0xc233: +case 0xc234: +case 0xc235: +case 0xc236: +case 0xc237: +case 0xc430: +case 0xc431: +case 0xc432: +case 0xc433: +case 0xc434: +case 0xc435: +case 0xc436: +case 0xc437: +case 0xc630: +case 0xc631: +case 0xc632: +case 0xc633: +case 0xc634: +case 0xc635: +case 0xc636: +case 0xc637: +case 0xc830: +case 0xc831: +case 0xc832: +case 0xc833: +case 0xc834: +case 0xc835: +case 0xc836: +case 0xc837: +case 0xca30: +case 0xca31: +case 0xca32: +case 0xca33: +case 0xca34: +case 0xca35: +case 0xca36: +case 0xca37: +case 0xcc30: +case 0xcc31: +case 0xcc32: +case 0xcc33: +case 0xcc34: +case 0xcc35: +case 0xcc36: +case 0xcc37: +case 0xce30: +case 0xce31: +case 0xce32: +case 0xce33: +case 0xce34: +case 0xce35: +case 0xce36: +case 0xce37: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb030: +case 0xb031: +case 0xb032: +case 0xb033: +case 0xb034: +case 0xb035: +case 0xb036: +case 0xb037: +case 0xb230: +case 0xb231: +case 0xb232: +case 0xb233: +case 0xb234: +case 0xb235: +case 0xb236: +case 0xb237: +case 0xb430: +case 0xb431: +case 0xb432: +case 0xb433: +case 0xb434: +case 0xb435: +case 0xb436: +case 0xb437: +case 0xb630: +case 0xb631: +case 0xb632: +case 0xb633: +case 0xb634: +case 0xb635: +case 0xb636: +case 0xb637: +case 0xb830: +case 0xb831: +case 0xb832: +case 0xb833: +case 0xb834: +case 0xb835: +case 0xb836: +case 0xb837: +case 0xba30: +case 0xba31: +case 0xba32: +case 0xba33: +case 0xba34: +case 0xba35: +case 0xba36: +case 0xba37: +case 0xbc30: +case 0xbc31: +case 0xbc32: +case 0xbc33: +case 0xbc34: +case 0xbc35: +case 0xbc36: +case 0xbc37: +case 0xbe30: +case 0xbe31: +case 0xbe32: +case 0xbe33: +case 0xbe34: +case 0xbe35: +case 0xbe36: +case 0xbe37: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x1030: +case 0x1031: +case 0x1032: +case 0x1033: +case 0x1034: +case 0x1035: +case 0x1036: +case 0x1037: +case 0x1230: +case 0x1231: +case 0x1232: +case 0x1233: +case 0x1234: +case 0x1235: +case 0x1236: +case 0x1237: +case 0x1430: +case 0x1431: +case 0x1432: +case 0x1433: +case 0x1434: +case 0x1435: +case 0x1436: +case 0x1437: +case 0x1630: +case 0x1631: +case 0x1632: +case 0x1633: +case 0x1634: +case 0x1635: +case 0x1636: +case 0x1637: +case 0x1830: +case 0x1831: +case 0x1832: +case 0x1833: +case 0x1834: +case 0x1835: +case 0x1836: +case 0x1837: +case 0x1a30: +case 0x1a31: +case 0x1a32: +case 0x1a33: +case 0x1a34: +case 0x1a35: +case 0x1a36: +case 0x1a37: +case 0x1c30: +case 0x1c31: +case 0x1c32: +case 0x1c33: +case 0x1c34: +case 0x1c35: +case 0x1c36: +case 0x1c37: +case 0x1e30: +case 0x1e31: +case 0x1e32: +case 0x1e33: +case 0x1e34: +case 0x1e35: +case 0x1e36: +case 0x1e37: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8030: +case 0x8031: +case 0x8032: +case 0x8033: +case 0x8034: +case 0x8035: +case 0x8036: +case 0x8037: +case 0x8230: +case 0x8231: +case 0x8232: +case 0x8233: +case 0x8234: +case 0x8235: +case 0x8236: +case 0x8237: +case 0x8430: +case 0x8431: +case 0x8432: +case 0x8433: +case 0x8434: +case 0x8435: +case 0x8436: +case 0x8437: +case 0x8630: +case 0x8631: +case 0x8632: +case 0x8633: +case 0x8634: +case 0x8635: +case 0x8636: +case 0x8637: +case 0x8830: +case 0x8831: +case 0x8832: +case 0x8833: +case 0x8834: +case 0x8835: +case 0x8836: +case 0x8837: +case 0x8a30: +case 0x8a31: +case 0x8a32: +case 0x8a33: +case 0x8a34: +case 0x8a35: +case 0x8a36: +case 0x8a37: +case 0x8c30: +case 0x8c31: +case 0x8c32: +case 0x8c33: +case 0x8c34: +case 0x8c35: +case 0x8c36: +case 0x8c37: +case 0x8e30: +case 0x8e31: +case 0x8e32: +case 0x8e33: +case 0x8e34: +case 0x8e35: +case 0x8e36: +case 0x8e37: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9030: +case 0x9031: +case 0x9032: +case 0x9033: +case 0x9034: +case 0x9035: +case 0x9036: +case 0x9037: +case 0x9230: +case 0x9231: +case 0x9232: +case 0x9233: +case 0x9234: +case 0x9235: +case 0x9236: +case 0x9237: +case 0x9430: +case 0x9431: +case 0x9432: +case 0x9433: +case 0x9434: +case 0x9435: +case 0x9436: +case 0x9437: +case 0x9630: +case 0x9631: +case 0x9632: +case 0x9633: +case 0x9634: +case 0x9635: +case 0x9636: +case 0x9637: +case 0x9830: +case 0x9831: +case 0x9832: +case 0x9833: +case 0x9834: +case 0x9835: +case 0x9836: +case 0x9837: +case 0x9a30: +case 0x9a31: +case 0x9a32: +case 0x9a33: +case 0x9a34: +case 0x9a35: +case 0x9a36: +case 0x9a37: +case 0x9c30: +case 0x9c31: +case 0x9c32: +case 0x9c33: +case 0x9c34: +case 0x9c35: +case 0x9c36: +case 0x9c37: +case 0x9e30: +case 0x9e31: +case 0x9e32: +case 0x9e33: +case 0x9e34: +case 0x9e35: +case 0x9e36: +case 0x9e37: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x0170: +case 0x0171: +case 0x0172: +case 0x0173: +case 0x0174: +case 0x0175: +case 0x0176: +case 0x0177: +case 0x0370: +case 0x0371: +case 0x0372: +case 0x0373: +case 0x0374: +case 0x0375: +case 0x0376: +case 0x0377: +case 0x0570: +case 0x0571: +case 0x0572: +case 0x0573: +case 0x0574: +case 0x0575: +case 0x0576: +case 0x0577: +case 0x0770: +case 0x0771: +case 0x0772: +case 0x0773: +case 0x0774: +case 0x0775: +case 0x0776: +case 0x0777: +case 0x0970: +case 0x0971: +case 0x0972: +case 0x0973: +case 0x0974: +case 0x0975: +case 0x0976: +case 0x0977: +case 0x0b70: +case 0x0b71: +case 0x0b72: +case 0x0b73: +case 0x0b74: +case 0x0b75: +case 0x0b76: +case 0x0b77: +case 0x0d70: +case 0x0d71: +case 0x0d72: +case 0x0d73: +case 0x0d74: +case 0x0d75: +case 0x0d76: +case 0x0d77: +case 0x0f70: +case 0x0f71: +case 0x0f72: +case 0x0f73: +case 0x0f74: +case 0x0f75: +case 0x0f76: +case 0x0f77: + { + HAM targ(this, instr_b2_b0); BCHG(targ, D[instr_b11_b9]); + } + break; + +case 0x01b0: +case 0x01b1: +case 0x01b2: +case 0x01b3: +case 0x01b4: +case 0x01b5: +case 0x01b6: +case 0x01b7: +case 0x03b0: +case 0x03b1: +case 0x03b2: +case 0x03b3: +case 0x03b4: +case 0x03b5: +case 0x03b6: +case 0x03b7: +case 0x05b0: +case 0x05b1: +case 0x05b2: +case 0x05b3: +case 0x05b4: +case 0x05b5: +case 0x05b6: +case 0x05b7: +case 0x07b0: +case 0x07b1: +case 0x07b2: +case 0x07b3: +case 0x07b4: +case 0x07b5: +case 0x07b6: +case 0x07b7: +case 0x09b0: +case 0x09b1: +case 0x09b2: +case 0x09b3: +case 0x09b4: +case 0x09b5: +case 0x09b6: +case 0x09b7: +case 0x0bb0: +case 0x0bb1: +case 0x0bb2: +case 0x0bb3: +case 0x0bb4: +case 0x0bb5: +case 0x0bb6: +case 0x0bb7: +case 0x0db0: +case 0x0db1: +case 0x0db2: +case 0x0db3: +case 0x0db4: +case 0x0db5: +case 0x0db6: +case 0x0db7: +case 0x0fb0: +case 0x0fb1: +case 0x0fb2: +case 0x0fb3: +case 0x0fb4: +case 0x0fb5: +case 0x0fb6: +case 0x0fb7: + { + HAM targ(this, instr_b2_b0); BCLR(targ, D[instr_b11_b9]); + } + break; + +case 0x01f0: +case 0x01f1: +case 0x01f2: +case 0x01f3: +case 0x01f4: +case 0x01f5: +case 0x01f6: +case 0x01f7: +case 0x03f0: +case 0x03f1: +case 0x03f2: +case 0x03f3: +case 0x03f4: +case 0x03f5: +case 0x03f6: +case 0x03f7: +case 0x05f0: +case 0x05f1: +case 0x05f2: +case 0x05f3: +case 0x05f4: +case 0x05f5: +case 0x05f6: +case 0x05f7: +case 0x07f0: +case 0x07f1: +case 0x07f2: +case 0x07f3: +case 0x07f4: +case 0x07f5: +case 0x07f6: +case 0x07f7: +case 0x09f0: +case 0x09f1: +case 0x09f2: +case 0x09f3: +case 0x09f4: +case 0x09f5: +case 0x09f6: +case 0x09f7: +case 0x0bf0: +case 0x0bf1: +case 0x0bf2: +case 0x0bf3: +case 0x0bf4: +case 0x0bf5: +case 0x0bf6: +case 0x0bf7: +case 0x0df0: +case 0x0df1: +case 0x0df2: +case 0x0df3: +case 0x0df4: +case 0x0df5: +case 0x0df6: +case 0x0df7: +case 0x0ff0: +case 0x0ff1: +case 0x0ff2: +case 0x0ff3: +case 0x0ff4: +case 0x0ff5: +case 0x0ff6: +case 0x0ff7: + { + HAM targ(this, instr_b2_b0); BSET(targ, D[instr_b11_b9]); + } + break; + +case 0x0130: +case 0x0131: +case 0x0132: +case 0x0133: +case 0x0134: +case 0x0135: +case 0x0136: +case 0x0137: +case 0x0330: +case 0x0331: +case 0x0332: +case 0x0333: +case 0x0334: +case 0x0335: +case 0x0336: +case 0x0337: +case 0x0530: +case 0x0531: +case 0x0532: +case 0x0533: +case 0x0534: +case 0x0535: +case 0x0536: +case 0x0537: +case 0x0730: +case 0x0731: +case 0x0732: +case 0x0733: +case 0x0734: +case 0x0735: +case 0x0736: +case 0x0737: +case 0x0930: +case 0x0931: +case 0x0932: +case 0x0933: +case 0x0934: +case 0x0935: +case 0x0936: +case 0x0937: +case 0x0b30: +case 0x0b31: +case 0x0b32: +case 0x0b33: +case 0x0b34: +case 0x0b35: +case 0x0b36: +case 0x0b37: +case 0x0d30: +case 0x0d31: +case 0x0d32: +case 0x0d33: +case 0x0d34: +case 0x0d35: +case 0x0d36: +case 0x0d37: +case 0x0f30: +case 0x0f31: +case 0x0f32: +case 0x0f33: +case 0x0f34: +case 0x0f35: +case 0x0f36: +case 0x0f37: + { + HAM targ(this, instr_b2_b0); BTST(targ, D[instr_b11_b9]); + } + break; + +case 0x4218: +case 0x4219: +case 0x421a: +case 0x421b: +case 0x421c: +case 0x421d: +case 0x421e: +case 0x421f: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x4818: +case 0x4819: +case 0x481a: +case 0x481b: +case 0x481c: +case 0x481d: +case 0x481e: +case 0x481f: + { + HAM dst(this, instr_b2_b0); NBCD(dst); + } + break; + +case 0x4418: +case 0x4419: +case 0x441a: +case 0x441b: +case 0x441c: +case 0x441d: +case 0x441e: +case 0x441f: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x4018: +case 0x4019: +case 0x401a: +case 0x401b: +case 0x401c: +case 0x401d: +case 0x401e: +case 0x401f: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x4618: +case 0x4619: +case 0x461a: +case 0x461b: +case 0x461c: +case 0x461d: +case 0x461e: +case 0x461f: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x50d8: +case 0x50d9: +case 0x50da: +case 0x50db: +case 0x50dc: +case 0x50dd: +case 0x50de: +case 0x50df: + { + HAM dst(this, instr_b2_b0); Scc<0x00>(dst); + } + break; + +case 0x51d8: +case 0x51d9: +case 0x51da: +case 0x51db: +case 0x51dc: +case 0x51dd: +case 0x51de: +case 0x51df: + { + HAM dst(this, instr_b2_b0); Scc<0x01>(dst); + } + break; + +case 0x52d8: +case 0x52d9: +case 0x52da: +case 0x52db: +case 0x52dc: +case 0x52dd: +case 0x52de: +case 0x52df: + { + HAM dst(this, instr_b2_b0); Scc<0x02>(dst); + } + break; + +case 0x53d8: +case 0x53d9: +case 0x53da: +case 0x53db: +case 0x53dc: +case 0x53dd: +case 0x53de: +case 0x53df: + { + HAM dst(this, instr_b2_b0); Scc<0x03>(dst); + } + break; + +case 0x54d8: +case 0x54d9: +case 0x54da: +case 0x54db: +case 0x54dc: +case 0x54dd: +case 0x54de: +case 0x54df: + { + HAM dst(this, instr_b2_b0); Scc<0x04>(dst); + } + break; + +case 0x55d8: +case 0x55d9: +case 0x55da: +case 0x55db: +case 0x55dc: +case 0x55dd: +case 0x55de: +case 0x55df: + { + HAM dst(this, instr_b2_b0); Scc<0x05>(dst); + } + break; + +case 0x56d8: +case 0x56d9: +case 0x56da: +case 0x56db: +case 0x56dc: +case 0x56dd: +case 0x56de: +case 0x56df: + { + HAM dst(this, instr_b2_b0); Scc<0x06>(dst); + } + break; + +case 0x57d8: +case 0x57d9: +case 0x57da: +case 0x57db: +case 0x57dc: +case 0x57dd: +case 0x57de: +case 0x57df: + { + HAM dst(this, instr_b2_b0); Scc<0x07>(dst); + } + break; + +case 0x58d8: +case 0x58d9: +case 0x58da: +case 0x58db: +case 0x58dc: +case 0x58dd: +case 0x58de: +case 0x58df: + { + HAM dst(this, instr_b2_b0); Scc<0x08>(dst); + } + break; + +case 0x59d8: +case 0x59d9: +case 0x59da: +case 0x59db: +case 0x59dc: +case 0x59dd: +case 0x59de: +case 0x59df: + { + HAM dst(this, instr_b2_b0); Scc<0x09>(dst); + } + break; + +case 0x5ad8: +case 0x5ad9: +case 0x5ada: +case 0x5adb: +case 0x5adc: +case 0x5add: +case 0x5ade: +case 0x5adf: + { + HAM dst(this, instr_b2_b0); Scc<0x0a>(dst); + } + break; + +case 0x5bd8: +case 0x5bd9: +case 0x5bda: +case 0x5bdb: +case 0x5bdc: +case 0x5bdd: +case 0x5bde: +case 0x5bdf: + { + HAM dst(this, instr_b2_b0); Scc<0x0b>(dst); + } + break; + +case 0x5cd8: +case 0x5cd9: +case 0x5cda: +case 0x5cdb: +case 0x5cdc: +case 0x5cdd: +case 0x5cde: +case 0x5cdf: + { + HAM dst(this, instr_b2_b0); Scc<0x0c>(dst); + } + break; + +case 0x5dd8: +case 0x5dd9: +case 0x5dda: +case 0x5ddb: +case 0x5ddc: +case 0x5ddd: +case 0x5dde: +case 0x5ddf: + { + HAM dst(this, instr_b2_b0); Scc<0x0d>(dst); + } + break; + +case 0x5ed8: +case 0x5ed9: +case 0x5eda: +case 0x5edb: +case 0x5edc: +case 0x5edd: +case 0x5ede: +case 0x5edf: + { + HAM dst(this, instr_b2_b0); Scc<0x0e>(dst); + } + break; + +case 0x5fd8: +case 0x5fd9: +case 0x5fda: +case 0x5fdb: +case 0x5fdc: +case 0x5fdd: +case 0x5fde: +case 0x5fdf: + { + HAM dst(this, instr_b2_b0); Scc<0x0f>(dst); + } + break; + +case 0x4ad8: +case 0x4ad9: +case 0x4ada: +case 0x4adb: +case 0x4adc: +case 0x4add: +case 0x4ade: +case 0x4adf: + { + HAM dst(this, instr_b2_b0); TAS(dst); + } + break; + +case 0x4a18: +case 0x4a19: +case 0x4a1a: +case 0x4a1b: +case 0x4a1c: +case 0x4a1d: +case 0x4a1e: +case 0x4a1f: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0x13d8: +case 0x13d9: +case 0x13da: +case 0x13db: +case 0x13dc: +case 0x13dd: +case 0x13de: +case 0x13df: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x11d8: +case 0x11d9: +case 0x11da: +case 0x11db: +case 0x11dc: +case 0x11dd: +case 0x11de: +case 0x11df: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x1098: +case 0x1099: +case 0x109a: +case 0x109b: +case 0x109c: +case 0x109d: +case 0x109e: +case 0x109f: +case 0x1298: +case 0x1299: +case 0x129a: +case 0x129b: +case 0x129c: +case 0x129d: +case 0x129e: +case 0x129f: +case 0x1498: +case 0x1499: +case 0x149a: +case 0x149b: +case 0x149c: +case 0x149d: +case 0x149e: +case 0x149f: +case 0x1698: +case 0x1699: +case 0x169a: +case 0x169b: +case 0x169c: +case 0x169d: +case 0x169e: +case 0x169f: +case 0x1898: +case 0x1899: +case 0x189a: +case 0x189b: +case 0x189c: +case 0x189d: +case 0x189e: +case 0x189f: +case 0x1a98: +case 0x1a99: +case 0x1a9a: +case 0x1a9b: +case 0x1a9c: +case 0x1a9d: +case 0x1a9e: +case 0x1a9f: +case 0x1c98: +case 0x1c99: +case 0x1c9a: +case 0x1c9b: +case 0x1c9c: +case 0x1c9d: +case 0x1c9e: +case 0x1c9f: +case 0x1e98: +case 0x1e99: +case 0x1e9a: +case 0x1e9b: +case 0x1e9c: +case 0x1e9d: +case 0x1e9e: +case 0x1e9f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1158: +case 0x1159: +case 0x115a: +case 0x115b: +case 0x115c: +case 0x115d: +case 0x115e: +case 0x115f: +case 0x1358: +case 0x1359: +case 0x135a: +case 0x135b: +case 0x135c: +case 0x135d: +case 0x135e: +case 0x135f: +case 0x1558: +case 0x1559: +case 0x155a: +case 0x155b: +case 0x155c: +case 0x155d: +case 0x155e: +case 0x155f: +case 0x1758: +case 0x1759: +case 0x175a: +case 0x175b: +case 0x175c: +case 0x175d: +case 0x175e: +case 0x175f: +case 0x1958: +case 0x1959: +case 0x195a: +case 0x195b: +case 0x195c: +case 0x195d: +case 0x195e: +case 0x195f: +case 0x1b58: +case 0x1b59: +case 0x1b5a: +case 0x1b5b: +case 0x1b5c: +case 0x1b5d: +case 0x1b5e: +case 0x1b5f: +case 0x1d58: +case 0x1d59: +case 0x1d5a: +case 0x1d5b: +case 0x1d5c: +case 0x1d5d: +case 0x1d5e: +case 0x1d5f: +case 0x1f58: +case 0x1f59: +case 0x1f5a: +case 0x1f5b: +case 0x1f5c: +case 0x1f5d: +case 0x1f5e: +case 0x1f5f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1198: +case 0x1199: +case 0x119a: +case 0x119b: +case 0x119c: +case 0x119d: +case 0x119e: +case 0x119f: +case 0x1398: +case 0x1399: +case 0x139a: +case 0x139b: +case 0x139c: +case 0x139d: +case 0x139e: +case 0x139f: +case 0x1598: +case 0x1599: +case 0x159a: +case 0x159b: +case 0x159c: +case 0x159d: +case 0x159e: +case 0x159f: +case 0x1798: +case 0x1799: +case 0x179a: +case 0x179b: +case 0x179c: +case 0x179d: +case 0x179e: +case 0x179f: +case 0x1998: +case 0x1999: +case 0x199a: +case 0x199b: +case 0x199c: +case 0x199d: +case 0x199e: +case 0x199f: +case 0x1b98: +case 0x1b99: +case 0x1b9a: +case 0x1b9b: +case 0x1b9c: +case 0x1b9d: +case 0x1b9e: +case 0x1b9f: +case 0x1d98: +case 0x1d99: +case 0x1d9a: +case 0x1d9b: +case 0x1d9c: +case 0x1d9d: +case 0x1d9e: +case 0x1d9f: +case 0x1f98: +case 0x1f99: +case 0x1f9a: +case 0x1f9b: +case 0x1f9c: +case 0x1f9d: +case 0x1f9e: +case 0x1f9f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xb108: +case 0xb109: +case 0xb10a: +case 0xb10b: +case 0xb10c: +case 0xb10d: +case 0xb10e: +case 0xb10f: +case 0xb308: +case 0xb309: +case 0xb30a: +case 0xb30b: +case 0xb30c: +case 0xb30d: +case 0xb30e: +case 0xb30f: +case 0xb508: +case 0xb509: +case 0xb50a: +case 0xb50b: +case 0xb50c: +case 0xb50d: +case 0xb50e: +case 0xb50f: +case 0xb708: +case 0xb709: +case 0xb70a: +case 0xb70b: +case 0xb70c: +case 0xb70d: +case 0xb70e: +case 0xb70f: +case 0xb908: +case 0xb909: +case 0xb90a: +case 0xb90b: +case 0xb90c: +case 0xb90d: +case 0xb90e: +case 0xb90f: +case 0xbb08: +case 0xbb09: +case 0xbb0a: +case 0xbb0b: +case 0xbb0c: +case 0xbb0d: +case 0xbb0e: +case 0xbb0f: +case 0xbd08: +case 0xbd09: +case 0xbd0a: +case 0xbd0b: +case 0xbd0c: +case 0xbd0d: +case 0xbd0e: +case 0xbd0f: +case 0xbf08: +case 0xbf09: +case 0xbf0a: +case 0xbf0b: +case 0xbf0c: +case 0xbf0d: +case 0xbf0e: +case 0xbf0f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x10d8: +case 0x10d9: +case 0x10da: +case 0x10db: +case 0x10dc: +case 0x10dd: +case 0x10de: +case 0x10df: +case 0x12d8: +case 0x12d9: +case 0x12da: +case 0x12db: +case 0x12dc: +case 0x12dd: +case 0x12de: +case 0x12df: +case 0x14d8: +case 0x14d9: +case 0x14da: +case 0x14db: +case 0x14dc: +case 0x14dd: +case 0x14de: +case 0x14df: +case 0x16d8: +case 0x16d9: +case 0x16da: +case 0x16db: +case 0x16dc: +case 0x16dd: +case 0x16de: +case 0x16df: +case 0x18d8: +case 0x18d9: +case 0x18da: +case 0x18db: +case 0x18dc: +case 0x18dd: +case 0x18de: +case 0x18df: +case 0x1ad8: +case 0x1ad9: +case 0x1ada: +case 0x1adb: +case 0x1adc: +case 0x1add: +case 0x1ade: +case 0x1adf: +case 0x1cd8: +case 0x1cd9: +case 0x1cda: +case 0x1cdb: +case 0x1cdc: +case 0x1cdd: +case 0x1cde: +case 0x1cdf: +case 0x1ed8: +case 0x1ed9: +case 0x1eda: +case 0x1edb: +case 0x1edc: +case 0x1edd: +case 0x1ede: +case 0x1edf: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1118: +case 0x1119: +case 0x111a: +case 0x111b: +case 0x111c: +case 0x111d: +case 0x111e: +case 0x111f: +case 0x1318: +case 0x1319: +case 0x131a: +case 0x131b: +case 0x131c: +case 0x131d: +case 0x131e: +case 0x131f: +case 0x1518: +case 0x1519: +case 0x151a: +case 0x151b: +case 0x151c: +case 0x151d: +case 0x151e: +case 0x151f: +case 0x1718: +case 0x1719: +case 0x171a: +case 0x171b: +case 0x171c: +case 0x171d: +case 0x171e: +case 0x171f: +case 0x1918: +case 0x1919: +case 0x191a: +case 0x191b: +case 0x191c: +case 0x191d: +case 0x191e: +case 0x191f: +case 0x1b18: +case 0x1b19: +case 0x1b1a: +case 0x1b1b: +case 0x1b1c: +case 0x1b1d: +case 0x1b1e: +case 0x1b1f: +case 0x1d18: +case 0x1d19: +case 0x1d1a: +case 0x1d1b: +case 0x1d1c: +case 0x1d1d: +case 0x1d1e: +case 0x1d1f: +case 0x1f18: +case 0x1f19: +case 0x1f1a: +case 0x1f1b: +case 0x1f1c: +case 0x1f1d: +case 0x1f1e: +case 0x1f1f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd018: +case 0xd019: +case 0xd01a: +case 0xd01b: +case 0xd01c: +case 0xd01d: +case 0xd01e: +case 0xd01f: +case 0xd218: +case 0xd219: +case 0xd21a: +case 0xd21b: +case 0xd21c: +case 0xd21d: +case 0xd21e: +case 0xd21f: +case 0xd418: +case 0xd419: +case 0xd41a: +case 0xd41b: +case 0xd41c: +case 0xd41d: +case 0xd41e: +case 0xd41f: +case 0xd618: +case 0xd619: +case 0xd61a: +case 0xd61b: +case 0xd61c: +case 0xd61d: +case 0xd61e: +case 0xd61f: +case 0xd818: +case 0xd819: +case 0xd81a: +case 0xd81b: +case 0xd81c: +case 0xd81d: +case 0xd81e: +case 0xd81f: +case 0xda18: +case 0xda19: +case 0xda1a: +case 0xda1b: +case 0xda1c: +case 0xda1d: +case 0xda1e: +case 0xda1f: +case 0xdc18: +case 0xdc19: +case 0xdc1a: +case 0xdc1b: +case 0xdc1c: +case 0xdc1d: +case 0xdc1e: +case 0xdc1f: +case 0xde18: +case 0xde19: +case 0xde1a: +case 0xde1b: +case 0xde1c: +case 0xde1d: +case 0xde1e: +case 0xde1f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc018: +case 0xc019: +case 0xc01a: +case 0xc01b: +case 0xc01c: +case 0xc01d: +case 0xc01e: +case 0xc01f: +case 0xc218: +case 0xc219: +case 0xc21a: +case 0xc21b: +case 0xc21c: +case 0xc21d: +case 0xc21e: +case 0xc21f: +case 0xc418: +case 0xc419: +case 0xc41a: +case 0xc41b: +case 0xc41c: +case 0xc41d: +case 0xc41e: +case 0xc41f: +case 0xc618: +case 0xc619: +case 0xc61a: +case 0xc61b: +case 0xc61c: +case 0xc61d: +case 0xc61e: +case 0xc61f: +case 0xc818: +case 0xc819: +case 0xc81a: +case 0xc81b: +case 0xc81c: +case 0xc81d: +case 0xc81e: +case 0xc81f: +case 0xca18: +case 0xca19: +case 0xca1a: +case 0xca1b: +case 0xca1c: +case 0xca1d: +case 0xca1e: +case 0xca1f: +case 0xcc18: +case 0xcc19: +case 0xcc1a: +case 0xcc1b: +case 0xcc1c: +case 0xcc1d: +case 0xcc1e: +case 0xcc1f: +case 0xce18: +case 0xce19: +case 0xce1a: +case 0xce1b: +case 0xce1c: +case 0xce1d: +case 0xce1e: +case 0xce1f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb018: +case 0xb019: +case 0xb01a: +case 0xb01b: +case 0xb01c: +case 0xb01d: +case 0xb01e: +case 0xb01f: +case 0xb218: +case 0xb219: +case 0xb21a: +case 0xb21b: +case 0xb21c: +case 0xb21d: +case 0xb21e: +case 0xb21f: +case 0xb418: +case 0xb419: +case 0xb41a: +case 0xb41b: +case 0xb41c: +case 0xb41d: +case 0xb41e: +case 0xb41f: +case 0xb618: +case 0xb619: +case 0xb61a: +case 0xb61b: +case 0xb61c: +case 0xb61d: +case 0xb61e: +case 0xb61f: +case 0xb818: +case 0xb819: +case 0xb81a: +case 0xb81b: +case 0xb81c: +case 0xb81d: +case 0xb81e: +case 0xb81f: +case 0xba18: +case 0xba19: +case 0xba1a: +case 0xba1b: +case 0xba1c: +case 0xba1d: +case 0xba1e: +case 0xba1f: +case 0xbc18: +case 0xbc19: +case 0xbc1a: +case 0xbc1b: +case 0xbc1c: +case 0xbc1d: +case 0xbc1e: +case 0xbc1f: +case 0xbe18: +case 0xbe19: +case 0xbe1a: +case 0xbe1b: +case 0xbe1c: +case 0xbe1d: +case 0xbe1e: +case 0xbe1f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x1018: +case 0x1019: +case 0x101a: +case 0x101b: +case 0x101c: +case 0x101d: +case 0x101e: +case 0x101f: +case 0x1218: +case 0x1219: +case 0x121a: +case 0x121b: +case 0x121c: +case 0x121d: +case 0x121e: +case 0x121f: +case 0x1418: +case 0x1419: +case 0x141a: +case 0x141b: +case 0x141c: +case 0x141d: +case 0x141e: +case 0x141f: +case 0x1618: +case 0x1619: +case 0x161a: +case 0x161b: +case 0x161c: +case 0x161d: +case 0x161e: +case 0x161f: +case 0x1818: +case 0x1819: +case 0x181a: +case 0x181b: +case 0x181c: +case 0x181d: +case 0x181e: +case 0x181f: +case 0x1a18: +case 0x1a19: +case 0x1a1a: +case 0x1a1b: +case 0x1a1c: +case 0x1a1d: +case 0x1a1e: +case 0x1a1f: +case 0x1c18: +case 0x1c19: +case 0x1c1a: +case 0x1c1b: +case 0x1c1c: +case 0x1c1d: +case 0x1c1e: +case 0x1c1f: +case 0x1e18: +case 0x1e19: +case 0x1e1a: +case 0x1e1b: +case 0x1e1c: +case 0x1e1d: +case 0x1e1e: +case 0x1e1f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8018: +case 0x8019: +case 0x801a: +case 0x801b: +case 0x801c: +case 0x801d: +case 0x801e: +case 0x801f: +case 0x8218: +case 0x8219: +case 0x821a: +case 0x821b: +case 0x821c: +case 0x821d: +case 0x821e: +case 0x821f: +case 0x8418: +case 0x8419: +case 0x841a: +case 0x841b: +case 0x841c: +case 0x841d: +case 0x841e: +case 0x841f: +case 0x8618: +case 0x8619: +case 0x861a: +case 0x861b: +case 0x861c: +case 0x861d: +case 0x861e: +case 0x861f: +case 0x8818: +case 0x8819: +case 0x881a: +case 0x881b: +case 0x881c: +case 0x881d: +case 0x881e: +case 0x881f: +case 0x8a18: +case 0x8a19: +case 0x8a1a: +case 0x8a1b: +case 0x8a1c: +case 0x8a1d: +case 0x8a1e: +case 0x8a1f: +case 0x8c18: +case 0x8c19: +case 0x8c1a: +case 0x8c1b: +case 0x8c1c: +case 0x8c1d: +case 0x8c1e: +case 0x8c1f: +case 0x8e18: +case 0x8e19: +case 0x8e1a: +case 0x8e1b: +case 0x8e1c: +case 0x8e1d: +case 0x8e1e: +case 0x8e1f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9018: +case 0x9019: +case 0x901a: +case 0x901b: +case 0x901c: +case 0x901d: +case 0x901e: +case 0x901f: +case 0x9218: +case 0x9219: +case 0x921a: +case 0x921b: +case 0x921c: +case 0x921d: +case 0x921e: +case 0x921f: +case 0x9418: +case 0x9419: +case 0x941a: +case 0x941b: +case 0x941c: +case 0x941d: +case 0x941e: +case 0x941f: +case 0x9618: +case 0x9619: +case 0x961a: +case 0x961b: +case 0x961c: +case 0x961d: +case 0x961e: +case 0x961f: +case 0x9818: +case 0x9819: +case 0x981a: +case 0x981b: +case 0x981c: +case 0x981d: +case 0x981e: +case 0x981f: +case 0x9a18: +case 0x9a19: +case 0x9a1a: +case 0x9a1b: +case 0x9a1c: +case 0x9a1d: +case 0x9a1e: +case 0x9a1f: +case 0x9c18: +case 0x9c19: +case 0x9c1a: +case 0x9c1b: +case 0x9c1c: +case 0x9c1d: +case 0x9c1e: +case 0x9c1f: +case 0x9e18: +case 0x9e19: +case 0x9e1a: +case 0x9e1b: +case 0x9e1c: +case 0x9e1d: +case 0x9e1e: +case 0x9e1f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x0158: +case 0x0159: +case 0x015a: +case 0x015b: +case 0x015c: +case 0x015d: +case 0x015e: +case 0x015f: +case 0x0358: +case 0x0359: +case 0x035a: +case 0x035b: +case 0x035c: +case 0x035d: +case 0x035e: +case 0x035f: +case 0x0558: +case 0x0559: +case 0x055a: +case 0x055b: +case 0x055c: +case 0x055d: +case 0x055e: +case 0x055f: +case 0x0758: +case 0x0759: +case 0x075a: +case 0x075b: +case 0x075c: +case 0x075d: +case 0x075e: +case 0x075f: +case 0x0958: +case 0x0959: +case 0x095a: +case 0x095b: +case 0x095c: +case 0x095d: +case 0x095e: +case 0x095f: +case 0x0b58: +case 0x0b59: +case 0x0b5a: +case 0x0b5b: +case 0x0b5c: +case 0x0b5d: +case 0x0b5e: +case 0x0b5f: +case 0x0d58: +case 0x0d59: +case 0x0d5a: +case 0x0d5b: +case 0x0d5c: +case 0x0d5d: +case 0x0d5e: +case 0x0d5f: +case 0x0f58: +case 0x0f59: +case 0x0f5a: +case 0x0f5b: +case 0x0f5c: +case 0x0f5d: +case 0x0f5e: +case 0x0f5f: + { + HAM targ(this, instr_b2_b0); BCHG(targ, D[instr_b11_b9]); + } + break; + +case 0x0198: +case 0x0199: +case 0x019a: +case 0x019b: +case 0x019c: +case 0x019d: +case 0x019e: +case 0x019f: +case 0x0398: +case 0x0399: +case 0x039a: +case 0x039b: +case 0x039c: +case 0x039d: +case 0x039e: +case 0x039f: +case 0x0598: +case 0x0599: +case 0x059a: +case 0x059b: +case 0x059c: +case 0x059d: +case 0x059e: +case 0x059f: +case 0x0798: +case 0x0799: +case 0x079a: +case 0x079b: +case 0x079c: +case 0x079d: +case 0x079e: +case 0x079f: +case 0x0998: +case 0x0999: +case 0x099a: +case 0x099b: +case 0x099c: +case 0x099d: +case 0x099e: +case 0x099f: +case 0x0b98: +case 0x0b99: +case 0x0b9a: +case 0x0b9b: +case 0x0b9c: +case 0x0b9d: +case 0x0b9e: +case 0x0b9f: +case 0x0d98: +case 0x0d99: +case 0x0d9a: +case 0x0d9b: +case 0x0d9c: +case 0x0d9d: +case 0x0d9e: +case 0x0d9f: +case 0x0f98: +case 0x0f99: +case 0x0f9a: +case 0x0f9b: +case 0x0f9c: +case 0x0f9d: +case 0x0f9e: +case 0x0f9f: + { + HAM targ(this, instr_b2_b0); BCLR(targ, D[instr_b11_b9]); + } + break; + +case 0x01d8: +case 0x01d9: +case 0x01da: +case 0x01db: +case 0x01dc: +case 0x01dd: +case 0x01de: +case 0x01df: +case 0x03d8: +case 0x03d9: +case 0x03da: +case 0x03db: +case 0x03dc: +case 0x03dd: +case 0x03de: +case 0x03df: +case 0x05d8: +case 0x05d9: +case 0x05da: +case 0x05db: +case 0x05dc: +case 0x05dd: +case 0x05de: +case 0x05df: +case 0x07d8: +case 0x07d9: +case 0x07da: +case 0x07db: +case 0x07dc: +case 0x07dd: +case 0x07de: +case 0x07df: +case 0x09d8: +case 0x09d9: +case 0x09da: +case 0x09db: +case 0x09dc: +case 0x09dd: +case 0x09de: +case 0x09df: +case 0x0bd8: +case 0x0bd9: +case 0x0bda: +case 0x0bdb: +case 0x0bdc: +case 0x0bdd: +case 0x0bde: +case 0x0bdf: +case 0x0dd8: +case 0x0dd9: +case 0x0dda: +case 0x0ddb: +case 0x0ddc: +case 0x0ddd: +case 0x0dde: +case 0x0ddf: +case 0x0fd8: +case 0x0fd9: +case 0x0fda: +case 0x0fdb: +case 0x0fdc: +case 0x0fdd: +case 0x0fde: +case 0x0fdf: + { + HAM targ(this, instr_b2_b0); BSET(targ, D[instr_b11_b9]); + } + break; + +case 0x0118: +case 0x0119: +case 0x011a: +case 0x011b: +case 0x011c: +case 0x011d: +case 0x011e: +case 0x011f: +case 0x0318: +case 0x0319: +case 0x031a: +case 0x031b: +case 0x031c: +case 0x031d: +case 0x031e: +case 0x031f: +case 0x0518: +case 0x0519: +case 0x051a: +case 0x051b: +case 0x051c: +case 0x051d: +case 0x051e: +case 0x051f: +case 0x0718: +case 0x0719: +case 0x071a: +case 0x071b: +case 0x071c: +case 0x071d: +case 0x071e: +case 0x071f: +case 0x0918: +case 0x0919: +case 0x091a: +case 0x091b: +case 0x091c: +case 0x091d: +case 0x091e: +case 0x091f: +case 0x0b18: +case 0x0b19: +case 0x0b1a: +case 0x0b1b: +case 0x0b1c: +case 0x0b1d: +case 0x0b1e: +case 0x0b1f: +case 0x0d18: +case 0x0d19: +case 0x0d1a: +case 0x0d1b: +case 0x0d1c: +case 0x0d1d: +case 0x0d1e: +case 0x0d1f: +case 0x0f18: +case 0x0f19: +case 0x0f1a: +case 0x0f1b: +case 0x0f1c: +case 0x0f1d: +case 0x0f1e: +case 0x0f1f: + { + HAM targ(this, instr_b2_b0); BTST(targ, D[instr_b11_b9]); + } + break; + +case 0x4220: +case 0x4221: +case 0x4222: +case 0x4223: +case 0x4224: +case 0x4225: +case 0x4226: +case 0x4227: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x4820: +case 0x4821: +case 0x4822: +case 0x4823: +case 0x4824: +case 0x4825: +case 0x4826: +case 0x4827: + { + HAM dst(this, instr_b2_b0); NBCD(dst); + } + break; + +case 0x4420: +case 0x4421: +case 0x4422: +case 0x4423: +case 0x4424: +case 0x4425: +case 0x4426: +case 0x4427: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x4020: +case 0x4021: +case 0x4022: +case 0x4023: +case 0x4024: +case 0x4025: +case 0x4026: +case 0x4027: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x4620: +case 0x4621: +case 0x4622: +case 0x4623: +case 0x4624: +case 0x4625: +case 0x4626: +case 0x4627: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x50e0: +case 0x50e1: +case 0x50e2: +case 0x50e3: +case 0x50e4: +case 0x50e5: +case 0x50e6: +case 0x50e7: + { + HAM dst(this, instr_b2_b0); Scc<0x00>(dst); + } + break; + +case 0x51e0: +case 0x51e1: +case 0x51e2: +case 0x51e3: +case 0x51e4: +case 0x51e5: +case 0x51e6: +case 0x51e7: + { + HAM dst(this, instr_b2_b0); Scc<0x01>(dst); + } + break; + +case 0x52e0: +case 0x52e1: +case 0x52e2: +case 0x52e3: +case 0x52e4: +case 0x52e5: +case 0x52e6: +case 0x52e7: + { + HAM dst(this, instr_b2_b0); Scc<0x02>(dst); + } + break; + +case 0x53e0: +case 0x53e1: +case 0x53e2: +case 0x53e3: +case 0x53e4: +case 0x53e5: +case 0x53e6: +case 0x53e7: + { + HAM dst(this, instr_b2_b0); Scc<0x03>(dst); + } + break; + +case 0x54e0: +case 0x54e1: +case 0x54e2: +case 0x54e3: +case 0x54e4: +case 0x54e5: +case 0x54e6: +case 0x54e7: + { + HAM dst(this, instr_b2_b0); Scc<0x04>(dst); + } + break; + +case 0x55e0: +case 0x55e1: +case 0x55e2: +case 0x55e3: +case 0x55e4: +case 0x55e5: +case 0x55e6: +case 0x55e7: + { + HAM dst(this, instr_b2_b0); Scc<0x05>(dst); + } + break; + +case 0x56e0: +case 0x56e1: +case 0x56e2: +case 0x56e3: +case 0x56e4: +case 0x56e5: +case 0x56e6: +case 0x56e7: + { + HAM dst(this, instr_b2_b0); Scc<0x06>(dst); + } + break; + +case 0x57e0: +case 0x57e1: +case 0x57e2: +case 0x57e3: +case 0x57e4: +case 0x57e5: +case 0x57e6: +case 0x57e7: + { + HAM dst(this, instr_b2_b0); Scc<0x07>(dst); + } + break; + +case 0x58e0: +case 0x58e1: +case 0x58e2: +case 0x58e3: +case 0x58e4: +case 0x58e5: +case 0x58e6: +case 0x58e7: + { + HAM dst(this, instr_b2_b0); Scc<0x08>(dst); + } + break; + +case 0x59e0: +case 0x59e1: +case 0x59e2: +case 0x59e3: +case 0x59e4: +case 0x59e5: +case 0x59e6: +case 0x59e7: + { + HAM dst(this, instr_b2_b0); Scc<0x09>(dst); + } + break; + +case 0x5ae0: +case 0x5ae1: +case 0x5ae2: +case 0x5ae3: +case 0x5ae4: +case 0x5ae5: +case 0x5ae6: +case 0x5ae7: + { + HAM dst(this, instr_b2_b0); Scc<0x0a>(dst); + } + break; + +case 0x5be0: +case 0x5be1: +case 0x5be2: +case 0x5be3: +case 0x5be4: +case 0x5be5: +case 0x5be6: +case 0x5be7: + { + HAM dst(this, instr_b2_b0); Scc<0x0b>(dst); + } + break; + +case 0x5ce0: +case 0x5ce1: +case 0x5ce2: +case 0x5ce3: +case 0x5ce4: +case 0x5ce5: +case 0x5ce6: +case 0x5ce7: + { + HAM dst(this, instr_b2_b0); Scc<0x0c>(dst); + } + break; + +case 0x5de0: +case 0x5de1: +case 0x5de2: +case 0x5de3: +case 0x5de4: +case 0x5de5: +case 0x5de6: +case 0x5de7: + { + HAM dst(this, instr_b2_b0); Scc<0x0d>(dst); + } + break; + +case 0x5ee0: +case 0x5ee1: +case 0x5ee2: +case 0x5ee3: +case 0x5ee4: +case 0x5ee5: +case 0x5ee6: +case 0x5ee7: + { + HAM dst(this, instr_b2_b0); Scc<0x0e>(dst); + } + break; + +case 0x5fe0: +case 0x5fe1: +case 0x5fe2: +case 0x5fe3: +case 0x5fe4: +case 0x5fe5: +case 0x5fe6: +case 0x5fe7: + { + HAM dst(this, instr_b2_b0); Scc<0x0f>(dst); + } + break; + +case 0x4ae0: +case 0x4ae1: +case 0x4ae2: +case 0x4ae3: +case 0x4ae4: +case 0x4ae5: +case 0x4ae6: +case 0x4ae7: + { + HAM dst(this, instr_b2_b0); TAS(dst); + } + break; + +case 0x4a20: +case 0x4a21: +case 0x4a22: +case 0x4a23: +case 0x4a24: +case 0x4a25: +case 0x4a26: +case 0x4a27: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0x13e0: +case 0x13e1: +case 0x13e2: +case 0x13e3: +case 0x13e4: +case 0x13e5: +case 0x13e6: +case 0x13e7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x11e0: +case 0x11e1: +case 0x11e2: +case 0x11e3: +case 0x11e4: +case 0x11e5: +case 0x11e6: +case 0x11e7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x10a0: +case 0x10a1: +case 0x10a2: +case 0x10a3: +case 0x10a4: +case 0x10a5: +case 0x10a6: +case 0x10a7: +case 0x12a0: +case 0x12a1: +case 0x12a2: +case 0x12a3: +case 0x12a4: +case 0x12a5: +case 0x12a6: +case 0x12a7: +case 0x14a0: +case 0x14a1: +case 0x14a2: +case 0x14a3: +case 0x14a4: +case 0x14a5: +case 0x14a6: +case 0x14a7: +case 0x16a0: +case 0x16a1: +case 0x16a2: +case 0x16a3: +case 0x16a4: +case 0x16a5: +case 0x16a6: +case 0x16a7: +case 0x18a0: +case 0x18a1: +case 0x18a2: +case 0x18a3: +case 0x18a4: +case 0x18a5: +case 0x18a6: +case 0x18a7: +case 0x1aa0: +case 0x1aa1: +case 0x1aa2: +case 0x1aa3: +case 0x1aa4: +case 0x1aa5: +case 0x1aa6: +case 0x1aa7: +case 0x1ca0: +case 0x1ca1: +case 0x1ca2: +case 0x1ca3: +case 0x1ca4: +case 0x1ca5: +case 0x1ca6: +case 0x1ca7: +case 0x1ea0: +case 0x1ea1: +case 0x1ea2: +case 0x1ea3: +case 0x1ea4: +case 0x1ea5: +case 0x1ea6: +case 0x1ea7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1160: +case 0x1161: +case 0x1162: +case 0x1163: +case 0x1164: +case 0x1165: +case 0x1166: +case 0x1167: +case 0x1360: +case 0x1361: +case 0x1362: +case 0x1363: +case 0x1364: +case 0x1365: +case 0x1366: +case 0x1367: +case 0x1560: +case 0x1561: +case 0x1562: +case 0x1563: +case 0x1564: +case 0x1565: +case 0x1566: +case 0x1567: +case 0x1760: +case 0x1761: +case 0x1762: +case 0x1763: +case 0x1764: +case 0x1765: +case 0x1766: +case 0x1767: +case 0x1960: +case 0x1961: +case 0x1962: +case 0x1963: +case 0x1964: +case 0x1965: +case 0x1966: +case 0x1967: +case 0x1b60: +case 0x1b61: +case 0x1b62: +case 0x1b63: +case 0x1b64: +case 0x1b65: +case 0x1b66: +case 0x1b67: +case 0x1d60: +case 0x1d61: +case 0x1d62: +case 0x1d63: +case 0x1d64: +case 0x1d65: +case 0x1d66: +case 0x1d67: +case 0x1f60: +case 0x1f61: +case 0x1f62: +case 0x1f63: +case 0x1f64: +case 0x1f65: +case 0x1f66: +case 0x1f67: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x11a0: +case 0x11a1: +case 0x11a2: +case 0x11a3: +case 0x11a4: +case 0x11a5: +case 0x11a6: +case 0x11a7: +case 0x13a0: +case 0x13a1: +case 0x13a2: +case 0x13a3: +case 0x13a4: +case 0x13a5: +case 0x13a6: +case 0x13a7: +case 0x15a0: +case 0x15a1: +case 0x15a2: +case 0x15a3: +case 0x15a4: +case 0x15a5: +case 0x15a6: +case 0x15a7: +case 0x17a0: +case 0x17a1: +case 0x17a2: +case 0x17a3: +case 0x17a4: +case 0x17a5: +case 0x17a6: +case 0x17a7: +case 0x19a0: +case 0x19a1: +case 0x19a2: +case 0x19a3: +case 0x19a4: +case 0x19a5: +case 0x19a6: +case 0x19a7: +case 0x1ba0: +case 0x1ba1: +case 0x1ba2: +case 0x1ba3: +case 0x1ba4: +case 0x1ba5: +case 0x1ba6: +case 0x1ba7: +case 0x1da0: +case 0x1da1: +case 0x1da2: +case 0x1da3: +case 0x1da4: +case 0x1da5: +case 0x1da6: +case 0x1da7: +case 0x1fa0: +case 0x1fa1: +case 0x1fa2: +case 0x1fa3: +case 0x1fa4: +case 0x1fa5: +case 0x1fa6: +case 0x1fa7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x10e0: +case 0x10e1: +case 0x10e2: +case 0x10e3: +case 0x10e4: +case 0x10e5: +case 0x10e6: +case 0x10e7: +case 0x12e0: +case 0x12e1: +case 0x12e2: +case 0x12e3: +case 0x12e4: +case 0x12e5: +case 0x12e6: +case 0x12e7: +case 0x14e0: +case 0x14e1: +case 0x14e2: +case 0x14e3: +case 0x14e4: +case 0x14e5: +case 0x14e6: +case 0x14e7: +case 0x16e0: +case 0x16e1: +case 0x16e2: +case 0x16e3: +case 0x16e4: +case 0x16e5: +case 0x16e6: +case 0x16e7: +case 0x18e0: +case 0x18e1: +case 0x18e2: +case 0x18e3: +case 0x18e4: +case 0x18e5: +case 0x18e6: +case 0x18e7: +case 0x1ae0: +case 0x1ae1: +case 0x1ae2: +case 0x1ae3: +case 0x1ae4: +case 0x1ae5: +case 0x1ae6: +case 0x1ae7: +case 0x1ce0: +case 0x1ce1: +case 0x1ce2: +case 0x1ce3: +case 0x1ce4: +case 0x1ce5: +case 0x1ce6: +case 0x1ce7: +case 0x1ee0: +case 0x1ee1: +case 0x1ee2: +case 0x1ee3: +case 0x1ee4: +case 0x1ee5: +case 0x1ee6: +case 0x1ee7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xc108: +case 0xc109: +case 0xc10a: +case 0xc10b: +case 0xc10c: +case 0xc10d: +case 0xc10e: +case 0xc10f: +case 0xc308: +case 0xc309: +case 0xc30a: +case 0xc30b: +case 0xc30c: +case 0xc30d: +case 0xc30e: +case 0xc30f: +case 0xc508: +case 0xc509: +case 0xc50a: +case 0xc50b: +case 0xc50c: +case 0xc50d: +case 0xc50e: +case 0xc50f: +case 0xc708: +case 0xc709: +case 0xc70a: +case 0xc70b: +case 0xc70c: +case 0xc70d: +case 0xc70e: +case 0xc70f: +case 0xc908: +case 0xc909: +case 0xc90a: +case 0xc90b: +case 0xc90c: +case 0xc90d: +case 0xc90e: +case 0xc90f: +case 0xcb08: +case 0xcb09: +case 0xcb0a: +case 0xcb0b: +case 0xcb0c: +case 0xcb0d: +case 0xcb0e: +case 0xcb0f: +case 0xcd08: +case 0xcd09: +case 0xcd0a: +case 0xcd0b: +case 0xcd0c: +case 0xcd0d: +case 0xcd0e: +case 0xcd0f: +case 0xcf08: +case 0xcf09: +case 0xcf0a: +case 0xcf0b: +case 0xcf0c: +case 0xcf0d: +case 0xcf0e: +case 0xcf0f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ABCD(src, dst); + } + break; + +case 0xd108: +case 0xd109: +case 0xd10a: +case 0xd10b: +case 0xd10c: +case 0xd10d: +case 0xd10e: +case 0xd10f: +case 0xd308: +case 0xd309: +case 0xd30a: +case 0xd30b: +case 0xd30c: +case 0xd30d: +case 0xd30e: +case 0xd30f: +case 0xd508: +case 0xd509: +case 0xd50a: +case 0xd50b: +case 0xd50c: +case 0xd50d: +case 0xd50e: +case 0xd50f: +case 0xd708: +case 0xd709: +case 0xd70a: +case 0xd70b: +case 0xd70c: +case 0xd70d: +case 0xd70e: +case 0xd70f: +case 0xd908: +case 0xd909: +case 0xd90a: +case 0xd90b: +case 0xd90c: +case 0xd90d: +case 0xd90e: +case 0xd90f: +case 0xdb08: +case 0xdb09: +case 0xdb0a: +case 0xdb0b: +case 0xdb0c: +case 0xdb0d: +case 0xdb0e: +case 0xdb0f: +case 0xdd08: +case 0xdd09: +case 0xdd0a: +case 0xdd0b: +case 0xdd0c: +case 0xdd0d: +case 0xdd0e: +case 0xdd0f: +case 0xdf08: +case 0xdf09: +case 0xdf0a: +case 0xdf0b: +case 0xdf0c: +case 0xdf0d: +case 0xdf0e: +case 0xdf0f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADDX(src, dst); + } + break; + +case 0x1120: +case 0x1121: +case 0x1122: +case 0x1123: +case 0x1124: +case 0x1125: +case 0x1126: +case 0x1127: +case 0x1320: +case 0x1321: +case 0x1322: +case 0x1323: +case 0x1324: +case 0x1325: +case 0x1326: +case 0x1327: +case 0x1520: +case 0x1521: +case 0x1522: +case 0x1523: +case 0x1524: +case 0x1525: +case 0x1526: +case 0x1527: +case 0x1720: +case 0x1721: +case 0x1722: +case 0x1723: +case 0x1724: +case 0x1725: +case 0x1726: +case 0x1727: +case 0x1920: +case 0x1921: +case 0x1922: +case 0x1923: +case 0x1924: +case 0x1925: +case 0x1926: +case 0x1927: +case 0x1b20: +case 0x1b21: +case 0x1b22: +case 0x1b23: +case 0x1b24: +case 0x1b25: +case 0x1b26: +case 0x1b27: +case 0x1d20: +case 0x1d21: +case 0x1d22: +case 0x1d23: +case 0x1d24: +case 0x1d25: +case 0x1d26: +case 0x1d27: +case 0x1f20: +case 0x1f21: +case 0x1f22: +case 0x1f23: +case 0x1f24: +case 0x1f25: +case 0x1f26: +case 0x1f27: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8108: +case 0x8109: +case 0x810a: +case 0x810b: +case 0x810c: +case 0x810d: +case 0x810e: +case 0x810f: +case 0x8308: +case 0x8309: +case 0x830a: +case 0x830b: +case 0x830c: +case 0x830d: +case 0x830e: +case 0x830f: +case 0x8508: +case 0x8509: +case 0x850a: +case 0x850b: +case 0x850c: +case 0x850d: +case 0x850e: +case 0x850f: +case 0x8708: +case 0x8709: +case 0x870a: +case 0x870b: +case 0x870c: +case 0x870d: +case 0x870e: +case 0x870f: +case 0x8908: +case 0x8909: +case 0x890a: +case 0x890b: +case 0x890c: +case 0x890d: +case 0x890e: +case 0x890f: +case 0x8b08: +case 0x8b09: +case 0x8b0a: +case 0x8b0b: +case 0x8b0c: +case 0x8b0d: +case 0x8b0e: +case 0x8b0f: +case 0x8d08: +case 0x8d09: +case 0x8d0a: +case 0x8d0b: +case 0x8d0c: +case 0x8d0d: +case 0x8d0e: +case 0x8d0f: +case 0x8f08: +case 0x8f09: +case 0x8f0a: +case 0x8f0b: +case 0x8f0c: +case 0x8f0d: +case 0x8f0e: +case 0x8f0f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SBCD(src, dst); + } + break; + +case 0x9108: +case 0x9109: +case 0x910a: +case 0x910b: +case 0x910c: +case 0x910d: +case 0x910e: +case 0x910f: +case 0x9308: +case 0x9309: +case 0x930a: +case 0x930b: +case 0x930c: +case 0x930d: +case 0x930e: +case 0x930f: +case 0x9508: +case 0x9509: +case 0x950a: +case 0x950b: +case 0x950c: +case 0x950d: +case 0x950e: +case 0x950f: +case 0x9708: +case 0x9709: +case 0x970a: +case 0x970b: +case 0x970c: +case 0x970d: +case 0x970e: +case 0x970f: +case 0x9908: +case 0x9909: +case 0x990a: +case 0x990b: +case 0x990c: +case 0x990d: +case 0x990e: +case 0x990f: +case 0x9b08: +case 0x9b09: +case 0x9b0a: +case 0x9b0b: +case 0x9b0c: +case 0x9b0d: +case 0x9b0e: +case 0x9b0f: +case 0x9d08: +case 0x9d09: +case 0x9d0a: +case 0x9d0b: +case 0x9d0c: +case 0x9d0d: +case 0x9d0e: +case 0x9d0f: +case 0x9f08: +case 0x9f09: +case 0x9f0a: +case 0x9f0b: +case 0x9f0c: +case 0x9f0d: +case 0x9f0e: +case 0x9f0f: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUBX(src, dst); + } + break; + +case 0xd020: +case 0xd021: +case 0xd022: +case 0xd023: +case 0xd024: +case 0xd025: +case 0xd026: +case 0xd027: +case 0xd220: +case 0xd221: +case 0xd222: +case 0xd223: +case 0xd224: +case 0xd225: +case 0xd226: +case 0xd227: +case 0xd420: +case 0xd421: +case 0xd422: +case 0xd423: +case 0xd424: +case 0xd425: +case 0xd426: +case 0xd427: +case 0xd620: +case 0xd621: +case 0xd622: +case 0xd623: +case 0xd624: +case 0xd625: +case 0xd626: +case 0xd627: +case 0xd820: +case 0xd821: +case 0xd822: +case 0xd823: +case 0xd824: +case 0xd825: +case 0xd826: +case 0xd827: +case 0xda20: +case 0xda21: +case 0xda22: +case 0xda23: +case 0xda24: +case 0xda25: +case 0xda26: +case 0xda27: +case 0xdc20: +case 0xdc21: +case 0xdc22: +case 0xdc23: +case 0xdc24: +case 0xdc25: +case 0xdc26: +case 0xdc27: +case 0xde20: +case 0xde21: +case 0xde22: +case 0xde23: +case 0xde24: +case 0xde25: +case 0xde26: +case 0xde27: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc020: +case 0xc021: +case 0xc022: +case 0xc023: +case 0xc024: +case 0xc025: +case 0xc026: +case 0xc027: +case 0xc220: +case 0xc221: +case 0xc222: +case 0xc223: +case 0xc224: +case 0xc225: +case 0xc226: +case 0xc227: +case 0xc420: +case 0xc421: +case 0xc422: +case 0xc423: +case 0xc424: +case 0xc425: +case 0xc426: +case 0xc427: +case 0xc620: +case 0xc621: +case 0xc622: +case 0xc623: +case 0xc624: +case 0xc625: +case 0xc626: +case 0xc627: +case 0xc820: +case 0xc821: +case 0xc822: +case 0xc823: +case 0xc824: +case 0xc825: +case 0xc826: +case 0xc827: +case 0xca20: +case 0xca21: +case 0xca22: +case 0xca23: +case 0xca24: +case 0xca25: +case 0xca26: +case 0xca27: +case 0xcc20: +case 0xcc21: +case 0xcc22: +case 0xcc23: +case 0xcc24: +case 0xcc25: +case 0xcc26: +case 0xcc27: +case 0xce20: +case 0xce21: +case 0xce22: +case 0xce23: +case 0xce24: +case 0xce25: +case 0xce26: +case 0xce27: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb020: +case 0xb021: +case 0xb022: +case 0xb023: +case 0xb024: +case 0xb025: +case 0xb026: +case 0xb027: +case 0xb220: +case 0xb221: +case 0xb222: +case 0xb223: +case 0xb224: +case 0xb225: +case 0xb226: +case 0xb227: +case 0xb420: +case 0xb421: +case 0xb422: +case 0xb423: +case 0xb424: +case 0xb425: +case 0xb426: +case 0xb427: +case 0xb620: +case 0xb621: +case 0xb622: +case 0xb623: +case 0xb624: +case 0xb625: +case 0xb626: +case 0xb627: +case 0xb820: +case 0xb821: +case 0xb822: +case 0xb823: +case 0xb824: +case 0xb825: +case 0xb826: +case 0xb827: +case 0xba20: +case 0xba21: +case 0xba22: +case 0xba23: +case 0xba24: +case 0xba25: +case 0xba26: +case 0xba27: +case 0xbc20: +case 0xbc21: +case 0xbc22: +case 0xbc23: +case 0xbc24: +case 0xbc25: +case 0xbc26: +case 0xbc27: +case 0xbe20: +case 0xbe21: +case 0xbe22: +case 0xbe23: +case 0xbe24: +case 0xbe25: +case 0xbe26: +case 0xbe27: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x1020: +case 0x1021: +case 0x1022: +case 0x1023: +case 0x1024: +case 0x1025: +case 0x1026: +case 0x1027: +case 0x1220: +case 0x1221: +case 0x1222: +case 0x1223: +case 0x1224: +case 0x1225: +case 0x1226: +case 0x1227: +case 0x1420: +case 0x1421: +case 0x1422: +case 0x1423: +case 0x1424: +case 0x1425: +case 0x1426: +case 0x1427: +case 0x1620: +case 0x1621: +case 0x1622: +case 0x1623: +case 0x1624: +case 0x1625: +case 0x1626: +case 0x1627: +case 0x1820: +case 0x1821: +case 0x1822: +case 0x1823: +case 0x1824: +case 0x1825: +case 0x1826: +case 0x1827: +case 0x1a20: +case 0x1a21: +case 0x1a22: +case 0x1a23: +case 0x1a24: +case 0x1a25: +case 0x1a26: +case 0x1a27: +case 0x1c20: +case 0x1c21: +case 0x1c22: +case 0x1c23: +case 0x1c24: +case 0x1c25: +case 0x1c26: +case 0x1c27: +case 0x1e20: +case 0x1e21: +case 0x1e22: +case 0x1e23: +case 0x1e24: +case 0x1e25: +case 0x1e26: +case 0x1e27: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8020: +case 0x8021: +case 0x8022: +case 0x8023: +case 0x8024: +case 0x8025: +case 0x8026: +case 0x8027: +case 0x8220: +case 0x8221: +case 0x8222: +case 0x8223: +case 0x8224: +case 0x8225: +case 0x8226: +case 0x8227: +case 0x8420: +case 0x8421: +case 0x8422: +case 0x8423: +case 0x8424: +case 0x8425: +case 0x8426: +case 0x8427: +case 0x8620: +case 0x8621: +case 0x8622: +case 0x8623: +case 0x8624: +case 0x8625: +case 0x8626: +case 0x8627: +case 0x8820: +case 0x8821: +case 0x8822: +case 0x8823: +case 0x8824: +case 0x8825: +case 0x8826: +case 0x8827: +case 0x8a20: +case 0x8a21: +case 0x8a22: +case 0x8a23: +case 0x8a24: +case 0x8a25: +case 0x8a26: +case 0x8a27: +case 0x8c20: +case 0x8c21: +case 0x8c22: +case 0x8c23: +case 0x8c24: +case 0x8c25: +case 0x8c26: +case 0x8c27: +case 0x8e20: +case 0x8e21: +case 0x8e22: +case 0x8e23: +case 0x8e24: +case 0x8e25: +case 0x8e26: +case 0x8e27: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x9020: +case 0x9021: +case 0x9022: +case 0x9023: +case 0x9024: +case 0x9025: +case 0x9026: +case 0x9027: +case 0x9220: +case 0x9221: +case 0x9222: +case 0x9223: +case 0x9224: +case 0x9225: +case 0x9226: +case 0x9227: +case 0x9420: +case 0x9421: +case 0x9422: +case 0x9423: +case 0x9424: +case 0x9425: +case 0x9426: +case 0x9427: +case 0x9620: +case 0x9621: +case 0x9622: +case 0x9623: +case 0x9624: +case 0x9625: +case 0x9626: +case 0x9627: +case 0x9820: +case 0x9821: +case 0x9822: +case 0x9823: +case 0x9824: +case 0x9825: +case 0x9826: +case 0x9827: +case 0x9a20: +case 0x9a21: +case 0x9a22: +case 0x9a23: +case 0x9a24: +case 0x9a25: +case 0x9a26: +case 0x9a27: +case 0x9c20: +case 0x9c21: +case 0x9c22: +case 0x9c23: +case 0x9c24: +case 0x9c25: +case 0x9c26: +case 0x9c27: +case 0x9e20: +case 0x9e21: +case 0x9e22: +case 0x9e23: +case 0x9e24: +case 0x9e25: +case 0x9e26: +case 0x9e27: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x0160: +case 0x0161: +case 0x0162: +case 0x0163: +case 0x0164: +case 0x0165: +case 0x0166: +case 0x0167: +case 0x0360: +case 0x0361: +case 0x0362: +case 0x0363: +case 0x0364: +case 0x0365: +case 0x0366: +case 0x0367: +case 0x0560: +case 0x0561: +case 0x0562: +case 0x0563: +case 0x0564: +case 0x0565: +case 0x0566: +case 0x0567: +case 0x0760: +case 0x0761: +case 0x0762: +case 0x0763: +case 0x0764: +case 0x0765: +case 0x0766: +case 0x0767: +case 0x0960: +case 0x0961: +case 0x0962: +case 0x0963: +case 0x0964: +case 0x0965: +case 0x0966: +case 0x0967: +case 0x0b60: +case 0x0b61: +case 0x0b62: +case 0x0b63: +case 0x0b64: +case 0x0b65: +case 0x0b66: +case 0x0b67: +case 0x0d60: +case 0x0d61: +case 0x0d62: +case 0x0d63: +case 0x0d64: +case 0x0d65: +case 0x0d66: +case 0x0d67: +case 0x0f60: +case 0x0f61: +case 0x0f62: +case 0x0f63: +case 0x0f64: +case 0x0f65: +case 0x0f66: +case 0x0f67: + { + HAM targ(this, instr_b2_b0); BCHG(targ, D[instr_b11_b9]); + } + break; + +case 0x01a0: +case 0x01a1: +case 0x01a2: +case 0x01a3: +case 0x01a4: +case 0x01a5: +case 0x01a6: +case 0x01a7: +case 0x03a0: +case 0x03a1: +case 0x03a2: +case 0x03a3: +case 0x03a4: +case 0x03a5: +case 0x03a6: +case 0x03a7: +case 0x05a0: +case 0x05a1: +case 0x05a2: +case 0x05a3: +case 0x05a4: +case 0x05a5: +case 0x05a6: +case 0x05a7: +case 0x07a0: +case 0x07a1: +case 0x07a2: +case 0x07a3: +case 0x07a4: +case 0x07a5: +case 0x07a6: +case 0x07a7: +case 0x09a0: +case 0x09a1: +case 0x09a2: +case 0x09a3: +case 0x09a4: +case 0x09a5: +case 0x09a6: +case 0x09a7: +case 0x0ba0: +case 0x0ba1: +case 0x0ba2: +case 0x0ba3: +case 0x0ba4: +case 0x0ba5: +case 0x0ba6: +case 0x0ba7: +case 0x0da0: +case 0x0da1: +case 0x0da2: +case 0x0da3: +case 0x0da4: +case 0x0da5: +case 0x0da6: +case 0x0da7: +case 0x0fa0: +case 0x0fa1: +case 0x0fa2: +case 0x0fa3: +case 0x0fa4: +case 0x0fa5: +case 0x0fa6: +case 0x0fa7: + { + HAM targ(this, instr_b2_b0); BCLR(targ, D[instr_b11_b9]); + } + break; + +case 0x01e0: +case 0x01e1: +case 0x01e2: +case 0x01e3: +case 0x01e4: +case 0x01e5: +case 0x01e6: +case 0x01e7: +case 0x03e0: +case 0x03e1: +case 0x03e2: +case 0x03e3: +case 0x03e4: +case 0x03e5: +case 0x03e6: +case 0x03e7: +case 0x05e0: +case 0x05e1: +case 0x05e2: +case 0x05e3: +case 0x05e4: +case 0x05e5: +case 0x05e6: +case 0x05e7: +case 0x07e0: +case 0x07e1: +case 0x07e2: +case 0x07e3: +case 0x07e4: +case 0x07e5: +case 0x07e6: +case 0x07e7: +case 0x09e0: +case 0x09e1: +case 0x09e2: +case 0x09e3: +case 0x09e4: +case 0x09e5: +case 0x09e6: +case 0x09e7: +case 0x0be0: +case 0x0be1: +case 0x0be2: +case 0x0be3: +case 0x0be4: +case 0x0be5: +case 0x0be6: +case 0x0be7: +case 0x0de0: +case 0x0de1: +case 0x0de2: +case 0x0de3: +case 0x0de4: +case 0x0de5: +case 0x0de6: +case 0x0de7: +case 0x0fe0: +case 0x0fe1: +case 0x0fe2: +case 0x0fe3: +case 0x0fe4: +case 0x0fe5: +case 0x0fe6: +case 0x0fe7: + { + HAM targ(this, instr_b2_b0); BSET(targ, D[instr_b11_b9]); + } + break; + +case 0x0120: +case 0x0121: +case 0x0122: +case 0x0123: +case 0x0124: +case 0x0125: +case 0x0126: +case 0x0127: +case 0x0320: +case 0x0321: +case 0x0322: +case 0x0323: +case 0x0324: +case 0x0325: +case 0x0326: +case 0x0327: +case 0x0520: +case 0x0521: +case 0x0522: +case 0x0523: +case 0x0524: +case 0x0525: +case 0x0526: +case 0x0527: +case 0x0720: +case 0x0721: +case 0x0722: +case 0x0723: +case 0x0724: +case 0x0725: +case 0x0726: +case 0x0727: +case 0x0920: +case 0x0921: +case 0x0922: +case 0x0923: +case 0x0924: +case 0x0925: +case 0x0926: +case 0x0927: +case 0x0b20: +case 0x0b21: +case 0x0b22: +case 0x0b23: +case 0x0b24: +case 0x0b25: +case 0x0b26: +case 0x0b27: +case 0x0d20: +case 0x0d21: +case 0x0d22: +case 0x0d23: +case 0x0d24: +case 0x0d25: +case 0x0d26: +case 0x0d27: +case 0x0f20: +case 0x0f21: +case 0x0f22: +case 0x0f23: +case 0x0f24: +case 0x0f25: +case 0x0f26: +case 0x0f27: + { + HAM targ(this, instr_b2_b0); BTST(targ, D[instr_b11_b9]); + } + break; + +case 0x4200: +case 0x4201: +case 0x4202: +case 0x4203: +case 0x4204: +case 0x4205: +case 0x4206: +case 0x4207: + { + HAM dst(this, instr_b2_b0); CLR(dst); + } + break; + +case 0x4800: +case 0x4801: +case 0x4802: +case 0x4803: +case 0x4804: +case 0x4805: +case 0x4806: +case 0x4807: + { + HAM dst(this, instr_b2_b0); NBCD(dst); + } + break; + +case 0x4400: +case 0x4401: +case 0x4402: +case 0x4403: +case 0x4404: +case 0x4405: +case 0x4406: +case 0x4407: + { + HAM dst(this, instr_b2_b0); NEG(dst); + } + break; + +case 0x4000: +case 0x4001: +case 0x4002: +case 0x4003: +case 0x4004: +case 0x4005: +case 0x4006: +case 0x4007: + { + HAM dst(this, instr_b2_b0); NEGX(dst); + } + break; + +case 0x4600: +case 0x4601: +case 0x4602: +case 0x4603: +case 0x4604: +case 0x4605: +case 0x4606: +case 0x4607: + { + HAM dst(this, instr_b2_b0); NOT(dst); + } + break; + +case 0x50c0: +case 0x50c1: +case 0x50c2: +case 0x50c3: +case 0x50c4: +case 0x50c5: +case 0x50c6: +case 0x50c7: + { + HAM dst(this, instr_b2_b0); Scc<0x00>(dst); + } + break; + +case 0x51c0: +case 0x51c1: +case 0x51c2: +case 0x51c3: +case 0x51c4: +case 0x51c5: +case 0x51c6: +case 0x51c7: + { + HAM dst(this, instr_b2_b0); Scc<0x01>(dst); + } + break; + +case 0x52c0: +case 0x52c1: +case 0x52c2: +case 0x52c3: +case 0x52c4: +case 0x52c5: +case 0x52c6: +case 0x52c7: + { + HAM dst(this, instr_b2_b0); Scc<0x02>(dst); + } + break; + +case 0x53c0: +case 0x53c1: +case 0x53c2: +case 0x53c3: +case 0x53c4: +case 0x53c5: +case 0x53c6: +case 0x53c7: + { + HAM dst(this, instr_b2_b0); Scc<0x03>(dst); + } + break; + +case 0x54c0: +case 0x54c1: +case 0x54c2: +case 0x54c3: +case 0x54c4: +case 0x54c5: +case 0x54c6: +case 0x54c7: + { + HAM dst(this, instr_b2_b0); Scc<0x04>(dst); + } + break; + +case 0x55c0: +case 0x55c1: +case 0x55c2: +case 0x55c3: +case 0x55c4: +case 0x55c5: +case 0x55c6: +case 0x55c7: + { + HAM dst(this, instr_b2_b0); Scc<0x05>(dst); + } + break; + +case 0x56c0: +case 0x56c1: +case 0x56c2: +case 0x56c3: +case 0x56c4: +case 0x56c5: +case 0x56c6: +case 0x56c7: + { + HAM dst(this, instr_b2_b0); Scc<0x06>(dst); + } + break; + +case 0x57c0: +case 0x57c1: +case 0x57c2: +case 0x57c3: +case 0x57c4: +case 0x57c5: +case 0x57c6: +case 0x57c7: + { + HAM dst(this, instr_b2_b0); Scc<0x07>(dst); + } + break; + +case 0x58c0: +case 0x58c1: +case 0x58c2: +case 0x58c3: +case 0x58c4: +case 0x58c5: +case 0x58c6: +case 0x58c7: + { + HAM dst(this, instr_b2_b0); Scc<0x08>(dst); + } + break; + +case 0x59c0: +case 0x59c1: +case 0x59c2: +case 0x59c3: +case 0x59c4: +case 0x59c5: +case 0x59c6: +case 0x59c7: + { + HAM dst(this, instr_b2_b0); Scc<0x09>(dst); + } + break; + +case 0x5ac0: +case 0x5ac1: +case 0x5ac2: +case 0x5ac3: +case 0x5ac4: +case 0x5ac5: +case 0x5ac6: +case 0x5ac7: + { + HAM dst(this, instr_b2_b0); Scc<0x0a>(dst); + } + break; + +case 0x5bc0: +case 0x5bc1: +case 0x5bc2: +case 0x5bc3: +case 0x5bc4: +case 0x5bc5: +case 0x5bc6: +case 0x5bc7: + { + HAM dst(this, instr_b2_b0); Scc<0x0b>(dst); + } + break; + +case 0x5cc0: +case 0x5cc1: +case 0x5cc2: +case 0x5cc3: +case 0x5cc4: +case 0x5cc5: +case 0x5cc6: +case 0x5cc7: + { + HAM dst(this, instr_b2_b0); Scc<0x0c>(dst); + } + break; + +case 0x5dc0: +case 0x5dc1: +case 0x5dc2: +case 0x5dc3: +case 0x5dc4: +case 0x5dc5: +case 0x5dc6: +case 0x5dc7: + { + HAM dst(this, instr_b2_b0); Scc<0x0d>(dst); + } + break; + +case 0x5ec0: +case 0x5ec1: +case 0x5ec2: +case 0x5ec3: +case 0x5ec4: +case 0x5ec5: +case 0x5ec6: +case 0x5ec7: + { + HAM dst(this, instr_b2_b0); Scc<0x0e>(dst); + } + break; + +case 0x5fc0: +case 0x5fc1: +case 0x5fc2: +case 0x5fc3: +case 0x5fc4: +case 0x5fc5: +case 0x5fc6: +case 0x5fc7: + { + HAM dst(this, instr_b2_b0); Scc<0x0f>(dst); + } + break; + +case 0x4ac0: +case 0x4ac1: +case 0x4ac2: +case 0x4ac3: +case 0x4ac4: +case 0x4ac5: +case 0x4ac6: +case 0x4ac7: + { + HAM dst(this, instr_b2_b0); TAS(dst); + } + break; + +case 0x4a00: +case 0x4a01: +case 0x4a02: +case 0x4a03: +case 0x4a04: +case 0x4a05: +case 0x4a06: +case 0x4a07: + { + HAM dst(this, instr_b2_b0); TST(dst); + } + break; + +case 0xd139: +case 0xd339: +case 0xd539: +case 0xd739: +case 0xd939: +case 0xdb39: +case 0xdd39: +case 0xdf39: + { + HAM src(this, instr_b11_b9); HAM dst(this); ADD(src, dst); + } + break; + +case 0xc139: +case 0xc339: +case 0xc539: +case 0xc739: +case 0xc939: +case 0xcb39: +case 0xcd39: +case 0xcf39: + { + HAM src(this, instr_b11_b9); HAM dst(this); AND(src, dst); + } + break; + +case 0xb139: +case 0xb339: +case 0xb539: +case 0xb739: +case 0xb939: +case 0xbb39: +case 0xbd39: +case 0xbf39: + { + HAM src(this, instr_b11_b9); HAM dst(this); EOR(src, dst); + } + break; + +case 0x8139: +case 0x8339: +case 0x8539: +case 0x8739: +case 0x8939: +case 0x8b39: +case 0x8d39: +case 0x8f39: + { + HAM src(this, instr_b11_b9); HAM dst(this); OR(src, dst); + } + break; + +case 0x9139: +case 0x9339: +case 0x9539: +case 0x9739: +case 0x9939: +case 0x9b39: +case 0x9d39: +case 0x9f39: + { + HAM src(this, instr_b11_b9); HAM dst(this); SUB(src, dst); + } + break; + +case 0xd138: +case 0xd338: +case 0xd538: +case 0xd738: +case 0xd938: +case 0xdb38: +case 0xdd38: +case 0xdf38: + { + HAM src(this, instr_b11_b9); HAM dst(this); ADD(src, dst); + } + break; + +case 0xc138: +case 0xc338: +case 0xc538: +case 0xc738: +case 0xc938: +case 0xcb38: +case 0xcd38: +case 0xcf38: + { + HAM src(this, instr_b11_b9); HAM dst(this); AND(src, dst); + } + break; + +case 0xb138: +case 0xb338: +case 0xb538: +case 0xb738: +case 0xb938: +case 0xbb38: +case 0xbd38: +case 0xbf38: + { + HAM src(this, instr_b11_b9); HAM dst(this); EOR(src, dst); + } + break; + +case 0x8138: +case 0x8338: +case 0x8538: +case 0x8738: +case 0x8938: +case 0x8b38: +case 0x8d38: +case 0x8f38: + { + HAM src(this, instr_b11_b9); HAM dst(this); OR(src, dst); + } + break; + +case 0x9138: +case 0x9338: +case 0x9538: +case 0x9738: +case 0x9938: +case 0x9b38: +case 0x9d38: +case 0x9f38: + { + HAM src(this, instr_b11_b9); HAM dst(this); SUB(src, dst); + } + break; + +case 0xd110: +case 0xd111: +case 0xd112: +case 0xd113: +case 0xd114: +case 0xd115: +case 0xd116: +case 0xd117: +case 0xd310: +case 0xd311: +case 0xd312: +case 0xd313: +case 0xd314: +case 0xd315: +case 0xd316: +case 0xd317: +case 0xd510: +case 0xd511: +case 0xd512: +case 0xd513: +case 0xd514: +case 0xd515: +case 0xd516: +case 0xd517: +case 0xd710: +case 0xd711: +case 0xd712: +case 0xd713: +case 0xd714: +case 0xd715: +case 0xd716: +case 0xd717: +case 0xd910: +case 0xd911: +case 0xd912: +case 0xd913: +case 0xd914: +case 0xd915: +case 0xd916: +case 0xd917: +case 0xdb10: +case 0xdb11: +case 0xdb12: +case 0xdb13: +case 0xdb14: +case 0xdb15: +case 0xdb16: +case 0xdb17: +case 0xdd10: +case 0xdd11: +case 0xdd12: +case 0xdd13: +case 0xdd14: +case 0xdd15: +case 0xdd16: +case 0xdd17: +case 0xdf10: +case 0xdf11: +case 0xdf12: +case 0xdf13: +case 0xdf14: +case 0xdf15: +case 0xdf16: +case 0xdf17: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0xc110: +case 0xc111: +case 0xc112: +case 0xc113: +case 0xc114: +case 0xc115: +case 0xc116: +case 0xc117: +case 0xc310: +case 0xc311: +case 0xc312: +case 0xc313: +case 0xc314: +case 0xc315: +case 0xc316: +case 0xc317: +case 0xc510: +case 0xc511: +case 0xc512: +case 0xc513: +case 0xc514: +case 0xc515: +case 0xc516: +case 0xc517: +case 0xc710: +case 0xc711: +case 0xc712: +case 0xc713: +case 0xc714: +case 0xc715: +case 0xc716: +case 0xc717: +case 0xc910: +case 0xc911: +case 0xc912: +case 0xc913: +case 0xc914: +case 0xc915: +case 0xc916: +case 0xc917: +case 0xcb10: +case 0xcb11: +case 0xcb12: +case 0xcb13: +case 0xcb14: +case 0xcb15: +case 0xcb16: +case 0xcb17: +case 0xcd10: +case 0xcd11: +case 0xcd12: +case 0xcd13: +case 0xcd14: +case 0xcd15: +case 0xcd16: +case 0xcd17: +case 0xcf10: +case 0xcf11: +case 0xcf12: +case 0xcf13: +case 0xcf14: +case 0xcf15: +case 0xcf16: +case 0xcf17: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0xb110: +case 0xb111: +case 0xb112: +case 0xb113: +case 0xb114: +case 0xb115: +case 0xb116: +case 0xb117: +case 0xb310: +case 0xb311: +case 0xb312: +case 0xb313: +case 0xb314: +case 0xb315: +case 0xb316: +case 0xb317: +case 0xb510: +case 0xb511: +case 0xb512: +case 0xb513: +case 0xb514: +case 0xb515: +case 0xb516: +case 0xb517: +case 0xb710: +case 0xb711: +case 0xb712: +case 0xb713: +case 0xb714: +case 0xb715: +case 0xb716: +case 0xb717: +case 0xb910: +case 0xb911: +case 0xb912: +case 0xb913: +case 0xb914: +case 0xb915: +case 0xb916: +case 0xb917: +case 0xbb10: +case 0xbb11: +case 0xbb12: +case 0xbb13: +case 0xbb14: +case 0xbb15: +case 0xbb16: +case 0xbb17: +case 0xbd10: +case 0xbd11: +case 0xbd12: +case 0xbd13: +case 0xbd14: +case 0xbd15: +case 0xbd16: +case 0xbd17: +case 0xbf10: +case 0xbf11: +case 0xbf12: +case 0xbf13: +case 0xbf14: +case 0xbf15: +case 0xbf16: +case 0xbf17: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x8110: +case 0x8111: +case 0x8112: +case 0x8113: +case 0x8114: +case 0x8115: +case 0x8116: +case 0x8117: +case 0x8310: +case 0x8311: +case 0x8312: +case 0x8313: +case 0x8314: +case 0x8315: +case 0x8316: +case 0x8317: +case 0x8510: +case 0x8511: +case 0x8512: +case 0x8513: +case 0x8514: +case 0x8515: +case 0x8516: +case 0x8517: +case 0x8710: +case 0x8711: +case 0x8712: +case 0x8713: +case 0x8714: +case 0x8715: +case 0x8716: +case 0x8717: +case 0x8910: +case 0x8911: +case 0x8912: +case 0x8913: +case 0x8914: +case 0x8915: +case 0x8916: +case 0x8917: +case 0x8b10: +case 0x8b11: +case 0x8b12: +case 0x8b13: +case 0x8b14: +case 0x8b15: +case 0x8b16: +case 0x8b17: +case 0x8d10: +case 0x8d11: +case 0x8d12: +case 0x8d13: +case 0x8d14: +case 0x8d15: +case 0x8d16: +case 0x8d17: +case 0x8f10: +case 0x8f11: +case 0x8f12: +case 0x8f13: +case 0x8f14: +case 0x8f15: +case 0x8f16: +case 0x8f17: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x9110: +case 0x9111: +case 0x9112: +case 0x9113: +case 0x9114: +case 0x9115: +case 0x9116: +case 0x9117: +case 0x9310: +case 0x9311: +case 0x9312: +case 0x9313: +case 0x9314: +case 0x9315: +case 0x9316: +case 0x9317: +case 0x9510: +case 0x9511: +case 0x9512: +case 0x9513: +case 0x9514: +case 0x9515: +case 0x9516: +case 0x9517: +case 0x9710: +case 0x9711: +case 0x9712: +case 0x9713: +case 0x9714: +case 0x9715: +case 0x9716: +case 0x9717: +case 0x9910: +case 0x9911: +case 0x9912: +case 0x9913: +case 0x9914: +case 0x9915: +case 0x9916: +case 0x9917: +case 0x9b10: +case 0x9b11: +case 0x9b12: +case 0x9b13: +case 0x9b14: +case 0x9b15: +case 0x9b16: +case 0x9b17: +case 0x9d10: +case 0x9d11: +case 0x9d12: +case 0x9d13: +case 0x9d14: +case 0x9d15: +case 0x9d16: +case 0x9d17: +case 0x9f10: +case 0x9f11: +case 0x9f12: +case 0x9f13: +case 0x9f14: +case 0x9f15: +case 0x9f16: +case 0x9f17: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xd128: +case 0xd129: +case 0xd12a: +case 0xd12b: +case 0xd12c: +case 0xd12d: +case 0xd12e: +case 0xd12f: +case 0xd328: +case 0xd329: +case 0xd32a: +case 0xd32b: +case 0xd32c: +case 0xd32d: +case 0xd32e: +case 0xd32f: +case 0xd528: +case 0xd529: +case 0xd52a: +case 0xd52b: +case 0xd52c: +case 0xd52d: +case 0xd52e: +case 0xd52f: +case 0xd728: +case 0xd729: +case 0xd72a: +case 0xd72b: +case 0xd72c: +case 0xd72d: +case 0xd72e: +case 0xd72f: +case 0xd928: +case 0xd929: +case 0xd92a: +case 0xd92b: +case 0xd92c: +case 0xd92d: +case 0xd92e: +case 0xd92f: +case 0xdb28: +case 0xdb29: +case 0xdb2a: +case 0xdb2b: +case 0xdb2c: +case 0xdb2d: +case 0xdb2e: +case 0xdb2f: +case 0xdd28: +case 0xdd29: +case 0xdd2a: +case 0xdd2b: +case 0xdd2c: +case 0xdd2d: +case 0xdd2e: +case 0xdd2f: +case 0xdf28: +case 0xdf29: +case 0xdf2a: +case 0xdf2b: +case 0xdf2c: +case 0xdf2d: +case 0xdf2e: +case 0xdf2f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0xc128: +case 0xc129: +case 0xc12a: +case 0xc12b: +case 0xc12c: +case 0xc12d: +case 0xc12e: +case 0xc12f: +case 0xc328: +case 0xc329: +case 0xc32a: +case 0xc32b: +case 0xc32c: +case 0xc32d: +case 0xc32e: +case 0xc32f: +case 0xc528: +case 0xc529: +case 0xc52a: +case 0xc52b: +case 0xc52c: +case 0xc52d: +case 0xc52e: +case 0xc52f: +case 0xc728: +case 0xc729: +case 0xc72a: +case 0xc72b: +case 0xc72c: +case 0xc72d: +case 0xc72e: +case 0xc72f: +case 0xc928: +case 0xc929: +case 0xc92a: +case 0xc92b: +case 0xc92c: +case 0xc92d: +case 0xc92e: +case 0xc92f: +case 0xcb28: +case 0xcb29: +case 0xcb2a: +case 0xcb2b: +case 0xcb2c: +case 0xcb2d: +case 0xcb2e: +case 0xcb2f: +case 0xcd28: +case 0xcd29: +case 0xcd2a: +case 0xcd2b: +case 0xcd2c: +case 0xcd2d: +case 0xcd2e: +case 0xcd2f: +case 0xcf28: +case 0xcf29: +case 0xcf2a: +case 0xcf2b: +case 0xcf2c: +case 0xcf2d: +case 0xcf2e: +case 0xcf2f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0xb128: +case 0xb129: +case 0xb12a: +case 0xb12b: +case 0xb12c: +case 0xb12d: +case 0xb12e: +case 0xb12f: +case 0xb328: +case 0xb329: +case 0xb32a: +case 0xb32b: +case 0xb32c: +case 0xb32d: +case 0xb32e: +case 0xb32f: +case 0xb528: +case 0xb529: +case 0xb52a: +case 0xb52b: +case 0xb52c: +case 0xb52d: +case 0xb52e: +case 0xb52f: +case 0xb728: +case 0xb729: +case 0xb72a: +case 0xb72b: +case 0xb72c: +case 0xb72d: +case 0xb72e: +case 0xb72f: +case 0xb928: +case 0xb929: +case 0xb92a: +case 0xb92b: +case 0xb92c: +case 0xb92d: +case 0xb92e: +case 0xb92f: +case 0xbb28: +case 0xbb29: +case 0xbb2a: +case 0xbb2b: +case 0xbb2c: +case 0xbb2d: +case 0xbb2e: +case 0xbb2f: +case 0xbd28: +case 0xbd29: +case 0xbd2a: +case 0xbd2b: +case 0xbd2c: +case 0xbd2d: +case 0xbd2e: +case 0xbd2f: +case 0xbf28: +case 0xbf29: +case 0xbf2a: +case 0xbf2b: +case 0xbf2c: +case 0xbf2d: +case 0xbf2e: +case 0xbf2f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x8128: +case 0x8129: +case 0x812a: +case 0x812b: +case 0x812c: +case 0x812d: +case 0x812e: +case 0x812f: +case 0x8328: +case 0x8329: +case 0x832a: +case 0x832b: +case 0x832c: +case 0x832d: +case 0x832e: +case 0x832f: +case 0x8528: +case 0x8529: +case 0x852a: +case 0x852b: +case 0x852c: +case 0x852d: +case 0x852e: +case 0x852f: +case 0x8728: +case 0x8729: +case 0x872a: +case 0x872b: +case 0x872c: +case 0x872d: +case 0x872e: +case 0x872f: +case 0x8928: +case 0x8929: +case 0x892a: +case 0x892b: +case 0x892c: +case 0x892d: +case 0x892e: +case 0x892f: +case 0x8b28: +case 0x8b29: +case 0x8b2a: +case 0x8b2b: +case 0x8b2c: +case 0x8b2d: +case 0x8b2e: +case 0x8b2f: +case 0x8d28: +case 0x8d29: +case 0x8d2a: +case 0x8d2b: +case 0x8d2c: +case 0x8d2d: +case 0x8d2e: +case 0x8d2f: +case 0x8f28: +case 0x8f29: +case 0x8f2a: +case 0x8f2b: +case 0x8f2c: +case 0x8f2d: +case 0x8f2e: +case 0x8f2f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x9128: +case 0x9129: +case 0x912a: +case 0x912b: +case 0x912c: +case 0x912d: +case 0x912e: +case 0x912f: +case 0x9328: +case 0x9329: +case 0x932a: +case 0x932b: +case 0x932c: +case 0x932d: +case 0x932e: +case 0x932f: +case 0x9528: +case 0x9529: +case 0x952a: +case 0x952b: +case 0x952c: +case 0x952d: +case 0x952e: +case 0x952f: +case 0x9728: +case 0x9729: +case 0x972a: +case 0x972b: +case 0x972c: +case 0x972d: +case 0x972e: +case 0x972f: +case 0x9928: +case 0x9929: +case 0x992a: +case 0x992b: +case 0x992c: +case 0x992d: +case 0x992e: +case 0x992f: +case 0x9b28: +case 0x9b29: +case 0x9b2a: +case 0x9b2b: +case 0x9b2c: +case 0x9b2d: +case 0x9b2e: +case 0x9b2f: +case 0x9d28: +case 0x9d29: +case 0x9d2a: +case 0x9d2b: +case 0x9d2c: +case 0x9d2d: +case 0x9d2e: +case 0x9d2f: +case 0x9f28: +case 0x9f29: +case 0x9f2a: +case 0x9f2b: +case 0x9f2c: +case 0x9f2d: +case 0x9f2e: +case 0x9f2f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xd130: +case 0xd131: +case 0xd132: +case 0xd133: +case 0xd134: +case 0xd135: +case 0xd136: +case 0xd137: +case 0xd330: +case 0xd331: +case 0xd332: +case 0xd333: +case 0xd334: +case 0xd335: +case 0xd336: +case 0xd337: +case 0xd530: +case 0xd531: +case 0xd532: +case 0xd533: +case 0xd534: +case 0xd535: +case 0xd536: +case 0xd537: +case 0xd730: +case 0xd731: +case 0xd732: +case 0xd733: +case 0xd734: +case 0xd735: +case 0xd736: +case 0xd737: +case 0xd930: +case 0xd931: +case 0xd932: +case 0xd933: +case 0xd934: +case 0xd935: +case 0xd936: +case 0xd937: +case 0xdb30: +case 0xdb31: +case 0xdb32: +case 0xdb33: +case 0xdb34: +case 0xdb35: +case 0xdb36: +case 0xdb37: +case 0xdd30: +case 0xdd31: +case 0xdd32: +case 0xdd33: +case 0xdd34: +case 0xdd35: +case 0xdd36: +case 0xdd37: +case 0xdf30: +case 0xdf31: +case 0xdf32: +case 0xdf33: +case 0xdf34: +case 0xdf35: +case 0xdf36: +case 0xdf37: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0xc130: +case 0xc131: +case 0xc132: +case 0xc133: +case 0xc134: +case 0xc135: +case 0xc136: +case 0xc137: +case 0xc330: +case 0xc331: +case 0xc332: +case 0xc333: +case 0xc334: +case 0xc335: +case 0xc336: +case 0xc337: +case 0xc530: +case 0xc531: +case 0xc532: +case 0xc533: +case 0xc534: +case 0xc535: +case 0xc536: +case 0xc537: +case 0xc730: +case 0xc731: +case 0xc732: +case 0xc733: +case 0xc734: +case 0xc735: +case 0xc736: +case 0xc737: +case 0xc930: +case 0xc931: +case 0xc932: +case 0xc933: +case 0xc934: +case 0xc935: +case 0xc936: +case 0xc937: +case 0xcb30: +case 0xcb31: +case 0xcb32: +case 0xcb33: +case 0xcb34: +case 0xcb35: +case 0xcb36: +case 0xcb37: +case 0xcd30: +case 0xcd31: +case 0xcd32: +case 0xcd33: +case 0xcd34: +case 0xcd35: +case 0xcd36: +case 0xcd37: +case 0xcf30: +case 0xcf31: +case 0xcf32: +case 0xcf33: +case 0xcf34: +case 0xcf35: +case 0xcf36: +case 0xcf37: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0xb130: +case 0xb131: +case 0xb132: +case 0xb133: +case 0xb134: +case 0xb135: +case 0xb136: +case 0xb137: +case 0xb330: +case 0xb331: +case 0xb332: +case 0xb333: +case 0xb334: +case 0xb335: +case 0xb336: +case 0xb337: +case 0xb530: +case 0xb531: +case 0xb532: +case 0xb533: +case 0xb534: +case 0xb535: +case 0xb536: +case 0xb537: +case 0xb730: +case 0xb731: +case 0xb732: +case 0xb733: +case 0xb734: +case 0xb735: +case 0xb736: +case 0xb737: +case 0xb930: +case 0xb931: +case 0xb932: +case 0xb933: +case 0xb934: +case 0xb935: +case 0xb936: +case 0xb937: +case 0xbb30: +case 0xbb31: +case 0xbb32: +case 0xbb33: +case 0xbb34: +case 0xbb35: +case 0xbb36: +case 0xbb37: +case 0xbd30: +case 0xbd31: +case 0xbd32: +case 0xbd33: +case 0xbd34: +case 0xbd35: +case 0xbd36: +case 0xbd37: +case 0xbf30: +case 0xbf31: +case 0xbf32: +case 0xbf33: +case 0xbf34: +case 0xbf35: +case 0xbf36: +case 0xbf37: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x8130: +case 0x8131: +case 0x8132: +case 0x8133: +case 0x8134: +case 0x8135: +case 0x8136: +case 0x8137: +case 0x8330: +case 0x8331: +case 0x8332: +case 0x8333: +case 0x8334: +case 0x8335: +case 0x8336: +case 0x8337: +case 0x8530: +case 0x8531: +case 0x8532: +case 0x8533: +case 0x8534: +case 0x8535: +case 0x8536: +case 0x8537: +case 0x8730: +case 0x8731: +case 0x8732: +case 0x8733: +case 0x8734: +case 0x8735: +case 0x8736: +case 0x8737: +case 0x8930: +case 0x8931: +case 0x8932: +case 0x8933: +case 0x8934: +case 0x8935: +case 0x8936: +case 0x8937: +case 0x8b30: +case 0x8b31: +case 0x8b32: +case 0x8b33: +case 0x8b34: +case 0x8b35: +case 0x8b36: +case 0x8b37: +case 0x8d30: +case 0x8d31: +case 0x8d32: +case 0x8d33: +case 0x8d34: +case 0x8d35: +case 0x8d36: +case 0x8d37: +case 0x8f30: +case 0x8f31: +case 0x8f32: +case 0x8f33: +case 0x8f34: +case 0x8f35: +case 0x8f36: +case 0x8f37: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x9130: +case 0x9131: +case 0x9132: +case 0x9133: +case 0x9134: +case 0x9135: +case 0x9136: +case 0x9137: +case 0x9330: +case 0x9331: +case 0x9332: +case 0x9333: +case 0x9334: +case 0x9335: +case 0x9336: +case 0x9337: +case 0x9530: +case 0x9531: +case 0x9532: +case 0x9533: +case 0x9534: +case 0x9535: +case 0x9536: +case 0x9537: +case 0x9730: +case 0x9731: +case 0x9732: +case 0x9733: +case 0x9734: +case 0x9735: +case 0x9736: +case 0x9737: +case 0x9930: +case 0x9931: +case 0x9932: +case 0x9933: +case 0x9934: +case 0x9935: +case 0x9936: +case 0x9937: +case 0x9b30: +case 0x9b31: +case 0x9b32: +case 0x9b33: +case 0x9b34: +case 0x9b35: +case 0x9b36: +case 0x9b37: +case 0x9d30: +case 0x9d31: +case 0x9d32: +case 0x9d33: +case 0x9d34: +case 0x9d35: +case 0x9d36: +case 0x9d37: +case 0x9f30: +case 0x9f31: +case 0x9f32: +case 0x9f33: +case 0x9f34: +case 0x9f35: +case 0x9f36: +case 0x9f37: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xd118: +case 0xd119: +case 0xd11a: +case 0xd11b: +case 0xd11c: +case 0xd11d: +case 0xd11e: +case 0xd11f: +case 0xd318: +case 0xd319: +case 0xd31a: +case 0xd31b: +case 0xd31c: +case 0xd31d: +case 0xd31e: +case 0xd31f: +case 0xd518: +case 0xd519: +case 0xd51a: +case 0xd51b: +case 0xd51c: +case 0xd51d: +case 0xd51e: +case 0xd51f: +case 0xd718: +case 0xd719: +case 0xd71a: +case 0xd71b: +case 0xd71c: +case 0xd71d: +case 0xd71e: +case 0xd71f: +case 0xd918: +case 0xd919: +case 0xd91a: +case 0xd91b: +case 0xd91c: +case 0xd91d: +case 0xd91e: +case 0xd91f: +case 0xdb18: +case 0xdb19: +case 0xdb1a: +case 0xdb1b: +case 0xdb1c: +case 0xdb1d: +case 0xdb1e: +case 0xdb1f: +case 0xdd18: +case 0xdd19: +case 0xdd1a: +case 0xdd1b: +case 0xdd1c: +case 0xdd1d: +case 0xdd1e: +case 0xdd1f: +case 0xdf18: +case 0xdf19: +case 0xdf1a: +case 0xdf1b: +case 0xdf1c: +case 0xdf1d: +case 0xdf1e: +case 0xdf1f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0xc118: +case 0xc119: +case 0xc11a: +case 0xc11b: +case 0xc11c: +case 0xc11d: +case 0xc11e: +case 0xc11f: +case 0xc318: +case 0xc319: +case 0xc31a: +case 0xc31b: +case 0xc31c: +case 0xc31d: +case 0xc31e: +case 0xc31f: +case 0xc518: +case 0xc519: +case 0xc51a: +case 0xc51b: +case 0xc51c: +case 0xc51d: +case 0xc51e: +case 0xc51f: +case 0xc718: +case 0xc719: +case 0xc71a: +case 0xc71b: +case 0xc71c: +case 0xc71d: +case 0xc71e: +case 0xc71f: +case 0xc918: +case 0xc919: +case 0xc91a: +case 0xc91b: +case 0xc91c: +case 0xc91d: +case 0xc91e: +case 0xc91f: +case 0xcb18: +case 0xcb19: +case 0xcb1a: +case 0xcb1b: +case 0xcb1c: +case 0xcb1d: +case 0xcb1e: +case 0xcb1f: +case 0xcd18: +case 0xcd19: +case 0xcd1a: +case 0xcd1b: +case 0xcd1c: +case 0xcd1d: +case 0xcd1e: +case 0xcd1f: +case 0xcf18: +case 0xcf19: +case 0xcf1a: +case 0xcf1b: +case 0xcf1c: +case 0xcf1d: +case 0xcf1e: +case 0xcf1f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0xb118: +case 0xb119: +case 0xb11a: +case 0xb11b: +case 0xb11c: +case 0xb11d: +case 0xb11e: +case 0xb11f: +case 0xb318: +case 0xb319: +case 0xb31a: +case 0xb31b: +case 0xb31c: +case 0xb31d: +case 0xb31e: +case 0xb31f: +case 0xb518: +case 0xb519: +case 0xb51a: +case 0xb51b: +case 0xb51c: +case 0xb51d: +case 0xb51e: +case 0xb51f: +case 0xb718: +case 0xb719: +case 0xb71a: +case 0xb71b: +case 0xb71c: +case 0xb71d: +case 0xb71e: +case 0xb71f: +case 0xb918: +case 0xb919: +case 0xb91a: +case 0xb91b: +case 0xb91c: +case 0xb91d: +case 0xb91e: +case 0xb91f: +case 0xbb18: +case 0xbb19: +case 0xbb1a: +case 0xbb1b: +case 0xbb1c: +case 0xbb1d: +case 0xbb1e: +case 0xbb1f: +case 0xbd18: +case 0xbd19: +case 0xbd1a: +case 0xbd1b: +case 0xbd1c: +case 0xbd1d: +case 0xbd1e: +case 0xbd1f: +case 0xbf18: +case 0xbf19: +case 0xbf1a: +case 0xbf1b: +case 0xbf1c: +case 0xbf1d: +case 0xbf1e: +case 0xbf1f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x8118: +case 0x8119: +case 0x811a: +case 0x811b: +case 0x811c: +case 0x811d: +case 0x811e: +case 0x811f: +case 0x8318: +case 0x8319: +case 0x831a: +case 0x831b: +case 0x831c: +case 0x831d: +case 0x831e: +case 0x831f: +case 0x8518: +case 0x8519: +case 0x851a: +case 0x851b: +case 0x851c: +case 0x851d: +case 0x851e: +case 0x851f: +case 0x8718: +case 0x8719: +case 0x871a: +case 0x871b: +case 0x871c: +case 0x871d: +case 0x871e: +case 0x871f: +case 0x8918: +case 0x8919: +case 0x891a: +case 0x891b: +case 0x891c: +case 0x891d: +case 0x891e: +case 0x891f: +case 0x8b18: +case 0x8b19: +case 0x8b1a: +case 0x8b1b: +case 0x8b1c: +case 0x8b1d: +case 0x8b1e: +case 0x8b1f: +case 0x8d18: +case 0x8d19: +case 0x8d1a: +case 0x8d1b: +case 0x8d1c: +case 0x8d1d: +case 0x8d1e: +case 0x8d1f: +case 0x8f18: +case 0x8f19: +case 0x8f1a: +case 0x8f1b: +case 0x8f1c: +case 0x8f1d: +case 0x8f1e: +case 0x8f1f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x9118: +case 0x9119: +case 0x911a: +case 0x911b: +case 0x911c: +case 0x911d: +case 0x911e: +case 0x911f: +case 0x9318: +case 0x9319: +case 0x931a: +case 0x931b: +case 0x931c: +case 0x931d: +case 0x931e: +case 0x931f: +case 0x9518: +case 0x9519: +case 0x951a: +case 0x951b: +case 0x951c: +case 0x951d: +case 0x951e: +case 0x951f: +case 0x9718: +case 0x9719: +case 0x971a: +case 0x971b: +case 0x971c: +case 0x971d: +case 0x971e: +case 0x971f: +case 0x9918: +case 0x9919: +case 0x991a: +case 0x991b: +case 0x991c: +case 0x991d: +case 0x991e: +case 0x991f: +case 0x9b18: +case 0x9b19: +case 0x9b1a: +case 0x9b1b: +case 0x9b1c: +case 0x9b1d: +case 0x9b1e: +case 0x9b1f: +case 0x9d18: +case 0x9d19: +case 0x9d1a: +case 0x9d1b: +case 0x9d1c: +case 0x9d1d: +case 0x9d1e: +case 0x9d1f: +case 0x9f18: +case 0x9f19: +case 0x9f1a: +case 0x9f1b: +case 0x9f1c: +case 0x9f1d: +case 0x9f1e: +case 0x9f1f: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xd120: +case 0xd121: +case 0xd122: +case 0xd123: +case 0xd124: +case 0xd125: +case 0xd126: +case 0xd127: +case 0xd320: +case 0xd321: +case 0xd322: +case 0xd323: +case 0xd324: +case 0xd325: +case 0xd326: +case 0xd327: +case 0xd520: +case 0xd521: +case 0xd522: +case 0xd523: +case 0xd524: +case 0xd525: +case 0xd526: +case 0xd527: +case 0xd720: +case 0xd721: +case 0xd722: +case 0xd723: +case 0xd724: +case 0xd725: +case 0xd726: +case 0xd727: +case 0xd920: +case 0xd921: +case 0xd922: +case 0xd923: +case 0xd924: +case 0xd925: +case 0xd926: +case 0xd927: +case 0xdb20: +case 0xdb21: +case 0xdb22: +case 0xdb23: +case 0xdb24: +case 0xdb25: +case 0xdb26: +case 0xdb27: +case 0xdd20: +case 0xdd21: +case 0xdd22: +case 0xdd23: +case 0xdd24: +case 0xdd25: +case 0xdd26: +case 0xdd27: +case 0xdf20: +case 0xdf21: +case 0xdf22: +case 0xdf23: +case 0xdf24: +case 0xdf25: +case 0xdf26: +case 0xdf27: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0xc120: +case 0xc121: +case 0xc122: +case 0xc123: +case 0xc124: +case 0xc125: +case 0xc126: +case 0xc127: +case 0xc320: +case 0xc321: +case 0xc322: +case 0xc323: +case 0xc324: +case 0xc325: +case 0xc326: +case 0xc327: +case 0xc520: +case 0xc521: +case 0xc522: +case 0xc523: +case 0xc524: +case 0xc525: +case 0xc526: +case 0xc527: +case 0xc720: +case 0xc721: +case 0xc722: +case 0xc723: +case 0xc724: +case 0xc725: +case 0xc726: +case 0xc727: +case 0xc920: +case 0xc921: +case 0xc922: +case 0xc923: +case 0xc924: +case 0xc925: +case 0xc926: +case 0xc927: +case 0xcb20: +case 0xcb21: +case 0xcb22: +case 0xcb23: +case 0xcb24: +case 0xcb25: +case 0xcb26: +case 0xcb27: +case 0xcd20: +case 0xcd21: +case 0xcd22: +case 0xcd23: +case 0xcd24: +case 0xcd25: +case 0xcd26: +case 0xcd27: +case 0xcf20: +case 0xcf21: +case 0xcf22: +case 0xcf23: +case 0xcf24: +case 0xcf25: +case 0xcf26: +case 0xcf27: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0xb120: +case 0xb121: +case 0xb122: +case 0xb123: +case 0xb124: +case 0xb125: +case 0xb126: +case 0xb127: +case 0xb320: +case 0xb321: +case 0xb322: +case 0xb323: +case 0xb324: +case 0xb325: +case 0xb326: +case 0xb327: +case 0xb520: +case 0xb521: +case 0xb522: +case 0xb523: +case 0xb524: +case 0xb525: +case 0xb526: +case 0xb527: +case 0xb720: +case 0xb721: +case 0xb722: +case 0xb723: +case 0xb724: +case 0xb725: +case 0xb726: +case 0xb727: +case 0xb920: +case 0xb921: +case 0xb922: +case 0xb923: +case 0xb924: +case 0xb925: +case 0xb926: +case 0xb927: +case 0xbb20: +case 0xbb21: +case 0xbb22: +case 0xbb23: +case 0xbb24: +case 0xbb25: +case 0xbb26: +case 0xbb27: +case 0xbd20: +case 0xbd21: +case 0xbd22: +case 0xbd23: +case 0xbd24: +case 0xbd25: +case 0xbd26: +case 0xbd27: +case 0xbf20: +case 0xbf21: +case 0xbf22: +case 0xbf23: +case 0xbf24: +case 0xbf25: +case 0xbf26: +case 0xbf27: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x8120: +case 0x8121: +case 0x8122: +case 0x8123: +case 0x8124: +case 0x8125: +case 0x8126: +case 0x8127: +case 0x8320: +case 0x8321: +case 0x8322: +case 0x8323: +case 0x8324: +case 0x8325: +case 0x8326: +case 0x8327: +case 0x8520: +case 0x8521: +case 0x8522: +case 0x8523: +case 0x8524: +case 0x8525: +case 0x8526: +case 0x8527: +case 0x8720: +case 0x8721: +case 0x8722: +case 0x8723: +case 0x8724: +case 0x8725: +case 0x8726: +case 0x8727: +case 0x8920: +case 0x8921: +case 0x8922: +case 0x8923: +case 0x8924: +case 0x8925: +case 0x8926: +case 0x8927: +case 0x8b20: +case 0x8b21: +case 0x8b22: +case 0x8b23: +case 0x8b24: +case 0x8b25: +case 0x8b26: +case 0x8b27: +case 0x8d20: +case 0x8d21: +case 0x8d22: +case 0x8d23: +case 0x8d24: +case 0x8d25: +case 0x8d26: +case 0x8d27: +case 0x8f20: +case 0x8f21: +case 0x8f22: +case 0x8f23: +case 0x8f24: +case 0x8f25: +case 0x8f26: +case 0x8f27: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x9120: +case 0x9121: +case 0x9122: +case 0x9123: +case 0x9124: +case 0x9125: +case 0x9126: +case 0x9127: +case 0x9320: +case 0x9321: +case 0x9322: +case 0x9323: +case 0x9324: +case 0x9325: +case 0x9326: +case 0x9327: +case 0x9520: +case 0x9521: +case 0x9522: +case 0x9523: +case 0x9524: +case 0x9525: +case 0x9526: +case 0x9527: +case 0x9720: +case 0x9721: +case 0x9722: +case 0x9723: +case 0x9724: +case 0x9725: +case 0x9726: +case 0x9727: +case 0x9920: +case 0x9921: +case 0x9922: +case 0x9923: +case 0x9924: +case 0x9925: +case 0x9926: +case 0x9927: +case 0x9b20: +case 0x9b21: +case 0x9b22: +case 0x9b23: +case 0x9b24: +case 0x9b25: +case 0x9b26: +case 0x9b27: +case 0x9d20: +case 0x9d21: +case 0x9d22: +case 0x9d23: +case 0x9d24: +case 0x9d25: +case 0x9d26: +case 0x9d27: +case 0x9f20: +case 0x9f21: +case 0x9f22: +case 0x9f23: +case 0x9f24: +case 0x9f25: +case 0x9f26: +case 0x9f27: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xb100: +case 0xb101: +case 0xb102: +case 0xb103: +case 0xb104: +case 0xb105: +case 0xb106: +case 0xb107: +case 0xb300: +case 0xb301: +case 0xb302: +case 0xb303: +case 0xb304: +case 0xb305: +case 0xb306: +case 0xb307: +case 0xb500: +case 0xb501: +case 0xb502: +case 0xb503: +case 0xb504: +case 0xb505: +case 0xb506: +case 0xb507: +case 0xb700: +case 0xb701: +case 0xb702: +case 0xb703: +case 0xb704: +case 0xb705: +case 0xb706: +case 0xb707: +case 0xb900: +case 0xb901: +case 0xb902: +case 0xb903: +case 0xb904: +case 0xb905: +case 0xb906: +case 0xb907: +case 0xbb00: +case 0xbb01: +case 0xbb02: +case 0xbb03: +case 0xbb04: +case 0xbb05: +case 0xbb06: +case 0xbb07: +case 0xbd00: +case 0xbd01: +case 0xbd02: +case 0xbd03: +case 0xbd04: +case 0xbd05: +case 0xbd06: +case 0xbd07: +case 0xbf00: +case 0xbf01: +case 0xbf02: +case 0xbf03: +case 0xbf04: +case 0xbf05: +case 0xbf06: +case 0xbf07: + { + HAM src(this, instr_b11_b9); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x13c0: +case 0x13c1: +case 0x13c2: +case 0x13c3: +case 0x13c4: +case 0x13c5: +case 0x13c6: +case 0x13c7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x11c0: +case 0x11c1: +case 0x11c2: +case 0x11c3: +case 0x11c4: +case 0x11c5: +case 0x11c6: +case 0x11c7: + { + HAM src(this, instr_b2_b0); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x1080: +case 0x1081: +case 0x1082: +case 0x1083: +case 0x1084: +case 0x1085: +case 0x1086: +case 0x1087: +case 0x1280: +case 0x1281: +case 0x1282: +case 0x1283: +case 0x1284: +case 0x1285: +case 0x1286: +case 0x1287: +case 0x1480: +case 0x1481: +case 0x1482: +case 0x1483: +case 0x1484: +case 0x1485: +case 0x1486: +case 0x1487: +case 0x1680: +case 0x1681: +case 0x1682: +case 0x1683: +case 0x1684: +case 0x1685: +case 0x1686: +case 0x1687: +case 0x1880: +case 0x1881: +case 0x1882: +case 0x1883: +case 0x1884: +case 0x1885: +case 0x1886: +case 0x1887: +case 0x1a80: +case 0x1a81: +case 0x1a82: +case 0x1a83: +case 0x1a84: +case 0x1a85: +case 0x1a86: +case 0x1a87: +case 0x1c80: +case 0x1c81: +case 0x1c82: +case 0x1c83: +case 0x1c84: +case 0x1c85: +case 0x1c86: +case 0x1c87: +case 0x1e80: +case 0x1e81: +case 0x1e82: +case 0x1e83: +case 0x1e84: +case 0x1e85: +case 0x1e86: +case 0x1e87: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1140: +case 0x1141: +case 0x1142: +case 0x1143: +case 0x1144: +case 0x1145: +case 0x1146: +case 0x1147: +case 0x1340: +case 0x1341: +case 0x1342: +case 0x1343: +case 0x1344: +case 0x1345: +case 0x1346: +case 0x1347: +case 0x1540: +case 0x1541: +case 0x1542: +case 0x1543: +case 0x1544: +case 0x1545: +case 0x1546: +case 0x1547: +case 0x1740: +case 0x1741: +case 0x1742: +case 0x1743: +case 0x1744: +case 0x1745: +case 0x1746: +case 0x1747: +case 0x1940: +case 0x1941: +case 0x1942: +case 0x1943: +case 0x1944: +case 0x1945: +case 0x1946: +case 0x1947: +case 0x1b40: +case 0x1b41: +case 0x1b42: +case 0x1b43: +case 0x1b44: +case 0x1b45: +case 0x1b46: +case 0x1b47: +case 0x1d40: +case 0x1d41: +case 0x1d42: +case 0x1d43: +case 0x1d44: +case 0x1d45: +case 0x1d46: +case 0x1d47: +case 0x1f40: +case 0x1f41: +case 0x1f42: +case 0x1f43: +case 0x1f44: +case 0x1f45: +case 0x1f46: +case 0x1f47: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1180: +case 0x1181: +case 0x1182: +case 0x1183: +case 0x1184: +case 0x1185: +case 0x1186: +case 0x1187: +case 0x1380: +case 0x1381: +case 0x1382: +case 0x1383: +case 0x1384: +case 0x1385: +case 0x1386: +case 0x1387: +case 0x1580: +case 0x1581: +case 0x1582: +case 0x1583: +case 0x1584: +case 0x1585: +case 0x1586: +case 0x1587: +case 0x1780: +case 0x1781: +case 0x1782: +case 0x1783: +case 0x1784: +case 0x1785: +case 0x1786: +case 0x1787: +case 0x1980: +case 0x1981: +case 0x1982: +case 0x1983: +case 0x1984: +case 0x1985: +case 0x1986: +case 0x1987: +case 0x1b80: +case 0x1b81: +case 0x1b82: +case 0x1b83: +case 0x1b84: +case 0x1b85: +case 0x1b86: +case 0x1b87: +case 0x1d80: +case 0x1d81: +case 0x1d82: +case 0x1d83: +case 0x1d84: +case 0x1d85: +case 0x1d86: +case 0x1d87: +case 0x1f80: +case 0x1f81: +case 0x1f82: +case 0x1f83: +case 0x1f84: +case 0x1f85: +case 0x1f86: +case 0x1f87: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x10c0: +case 0x10c1: +case 0x10c2: +case 0x10c3: +case 0x10c4: +case 0x10c5: +case 0x10c6: +case 0x10c7: +case 0x12c0: +case 0x12c1: +case 0x12c2: +case 0x12c3: +case 0x12c4: +case 0x12c5: +case 0x12c6: +case 0x12c7: +case 0x14c0: +case 0x14c1: +case 0x14c2: +case 0x14c3: +case 0x14c4: +case 0x14c5: +case 0x14c6: +case 0x14c7: +case 0x16c0: +case 0x16c1: +case 0x16c2: +case 0x16c3: +case 0x16c4: +case 0x16c5: +case 0x16c6: +case 0x16c7: +case 0x18c0: +case 0x18c1: +case 0x18c2: +case 0x18c3: +case 0x18c4: +case 0x18c5: +case 0x18c6: +case 0x18c7: +case 0x1ac0: +case 0x1ac1: +case 0x1ac2: +case 0x1ac3: +case 0x1ac4: +case 0x1ac5: +case 0x1ac6: +case 0x1ac7: +case 0x1cc0: +case 0x1cc1: +case 0x1cc2: +case 0x1cc3: +case 0x1cc4: +case 0x1cc5: +case 0x1cc6: +case 0x1cc7: +case 0x1ec0: +case 0x1ec1: +case 0x1ec2: +case 0x1ec3: +case 0x1ec4: +case 0x1ec5: +case 0x1ec6: +case 0x1ec7: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x1100: +case 0x1101: +case 0x1102: +case 0x1103: +case 0x1104: +case 0x1105: +case 0x1106: +case 0x1107: +case 0x1300: +case 0x1301: +case 0x1302: +case 0x1303: +case 0x1304: +case 0x1305: +case 0x1306: +case 0x1307: +case 0x1500: +case 0x1501: +case 0x1502: +case 0x1503: +case 0x1504: +case 0x1505: +case 0x1506: +case 0x1507: +case 0x1700: +case 0x1701: +case 0x1702: +case 0x1703: +case 0x1704: +case 0x1705: +case 0x1706: +case 0x1707: +case 0x1900: +case 0x1901: +case 0x1902: +case 0x1903: +case 0x1904: +case 0x1905: +case 0x1906: +case 0x1907: +case 0x1b00: +case 0x1b01: +case 0x1b02: +case 0x1b03: +case 0x1b04: +case 0x1b05: +case 0x1b06: +case 0x1b07: +case 0x1d00: +case 0x1d01: +case 0x1d02: +case 0x1d03: +case 0x1d04: +case 0x1d05: +case 0x1d06: +case 0x1d07: +case 0x1f00: +case 0x1f01: +case 0x1f02: +case 0x1f03: +case 0x1f04: +case 0x1f05: +case 0x1f06: +case 0x1f07: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xc100: +case 0xc101: +case 0xc102: +case 0xc103: +case 0xc104: +case 0xc105: +case 0xc106: +case 0xc107: +case 0xc300: +case 0xc301: +case 0xc302: +case 0xc303: +case 0xc304: +case 0xc305: +case 0xc306: +case 0xc307: +case 0xc500: +case 0xc501: +case 0xc502: +case 0xc503: +case 0xc504: +case 0xc505: +case 0xc506: +case 0xc507: +case 0xc700: +case 0xc701: +case 0xc702: +case 0xc703: +case 0xc704: +case 0xc705: +case 0xc706: +case 0xc707: +case 0xc900: +case 0xc901: +case 0xc902: +case 0xc903: +case 0xc904: +case 0xc905: +case 0xc906: +case 0xc907: +case 0xcb00: +case 0xcb01: +case 0xcb02: +case 0xcb03: +case 0xcb04: +case 0xcb05: +case 0xcb06: +case 0xcb07: +case 0xcd00: +case 0xcd01: +case 0xcd02: +case 0xcd03: +case 0xcd04: +case 0xcd05: +case 0xcd06: +case 0xcd07: +case 0xcf00: +case 0xcf01: +case 0xcf02: +case 0xcf03: +case 0xcf04: +case 0xcf05: +case 0xcf06: +case 0xcf07: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ABCD(src, dst); + } + break; + +case 0xd000: +case 0xd001: +case 0xd002: +case 0xd003: +case 0xd004: +case 0xd005: +case 0xd006: +case 0xd007: +case 0xd200: +case 0xd201: +case 0xd202: +case 0xd203: +case 0xd204: +case 0xd205: +case 0xd206: +case 0xd207: +case 0xd400: +case 0xd401: +case 0xd402: +case 0xd403: +case 0xd404: +case 0xd405: +case 0xd406: +case 0xd407: +case 0xd600: +case 0xd601: +case 0xd602: +case 0xd603: +case 0xd604: +case 0xd605: +case 0xd606: +case 0xd607: +case 0xd800: +case 0xd801: +case 0xd802: +case 0xd803: +case 0xd804: +case 0xd805: +case 0xd806: +case 0xd807: +case 0xda00: +case 0xda01: +case 0xda02: +case 0xda03: +case 0xda04: +case 0xda05: +case 0xda06: +case 0xda07: +case 0xdc00: +case 0xdc01: +case 0xdc02: +case 0xdc03: +case 0xdc04: +case 0xdc05: +case 0xdc06: +case 0xdc07: +case 0xde00: +case 0xde01: +case 0xde02: +case 0xde03: +case 0xde04: +case 0xde05: +case 0xde06: +case 0xde07: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xd100: +case 0xd101: +case 0xd102: +case 0xd103: +case 0xd104: +case 0xd105: +case 0xd106: +case 0xd107: +case 0xd300: +case 0xd301: +case 0xd302: +case 0xd303: +case 0xd304: +case 0xd305: +case 0xd306: +case 0xd307: +case 0xd500: +case 0xd501: +case 0xd502: +case 0xd503: +case 0xd504: +case 0xd505: +case 0xd506: +case 0xd507: +case 0xd700: +case 0xd701: +case 0xd702: +case 0xd703: +case 0xd704: +case 0xd705: +case 0xd706: +case 0xd707: +case 0xd900: +case 0xd901: +case 0xd902: +case 0xd903: +case 0xd904: +case 0xd905: +case 0xd906: +case 0xd907: +case 0xdb00: +case 0xdb01: +case 0xdb02: +case 0xdb03: +case 0xdb04: +case 0xdb05: +case 0xdb06: +case 0xdb07: +case 0xdd00: +case 0xdd01: +case 0xdd02: +case 0xdd03: +case 0xdd04: +case 0xdd05: +case 0xdd06: +case 0xdd07: +case 0xdf00: +case 0xdf01: +case 0xdf02: +case 0xdf03: +case 0xdf04: +case 0xdf05: +case 0xdf06: +case 0xdf07: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); ADDX(src, dst); + } + break; + +case 0xc000: +case 0xc001: +case 0xc002: +case 0xc003: +case 0xc004: +case 0xc005: +case 0xc006: +case 0xc007: +case 0xc200: +case 0xc201: +case 0xc202: +case 0xc203: +case 0xc204: +case 0xc205: +case 0xc206: +case 0xc207: +case 0xc400: +case 0xc401: +case 0xc402: +case 0xc403: +case 0xc404: +case 0xc405: +case 0xc406: +case 0xc407: +case 0xc600: +case 0xc601: +case 0xc602: +case 0xc603: +case 0xc604: +case 0xc605: +case 0xc606: +case 0xc607: +case 0xc800: +case 0xc801: +case 0xc802: +case 0xc803: +case 0xc804: +case 0xc805: +case 0xc806: +case 0xc807: +case 0xca00: +case 0xca01: +case 0xca02: +case 0xca03: +case 0xca04: +case 0xca05: +case 0xca06: +case 0xca07: +case 0xcc00: +case 0xcc01: +case 0xcc02: +case 0xcc03: +case 0xcc04: +case 0xcc05: +case 0xcc06: +case 0xcc07: +case 0xce00: +case 0xce01: +case 0xce02: +case 0xce03: +case 0xce04: +case 0xce05: +case 0xce06: +case 0xce07: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb000: +case 0xb001: +case 0xb002: +case 0xb003: +case 0xb004: +case 0xb005: +case 0xb006: +case 0xb007: +case 0xb200: +case 0xb201: +case 0xb202: +case 0xb203: +case 0xb204: +case 0xb205: +case 0xb206: +case 0xb207: +case 0xb400: +case 0xb401: +case 0xb402: +case 0xb403: +case 0xb404: +case 0xb405: +case 0xb406: +case 0xb407: +case 0xb600: +case 0xb601: +case 0xb602: +case 0xb603: +case 0xb604: +case 0xb605: +case 0xb606: +case 0xb607: +case 0xb800: +case 0xb801: +case 0xb802: +case 0xb803: +case 0xb804: +case 0xb805: +case 0xb806: +case 0xb807: +case 0xba00: +case 0xba01: +case 0xba02: +case 0xba03: +case 0xba04: +case 0xba05: +case 0xba06: +case 0xba07: +case 0xbc00: +case 0xbc01: +case 0xbc02: +case 0xbc03: +case 0xbc04: +case 0xbc05: +case 0xbc06: +case 0xbc07: +case 0xbe00: +case 0xbe01: +case 0xbe02: +case 0xbe03: +case 0xbe04: +case 0xbe05: +case 0xbe06: +case 0xbe07: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x1000: +case 0x1001: +case 0x1002: +case 0x1003: +case 0x1004: +case 0x1005: +case 0x1006: +case 0x1007: +case 0x1200: +case 0x1201: +case 0x1202: +case 0x1203: +case 0x1204: +case 0x1205: +case 0x1206: +case 0x1207: +case 0x1400: +case 0x1401: +case 0x1402: +case 0x1403: +case 0x1404: +case 0x1405: +case 0x1406: +case 0x1407: +case 0x1600: +case 0x1601: +case 0x1602: +case 0x1603: +case 0x1604: +case 0x1605: +case 0x1606: +case 0x1607: +case 0x1800: +case 0x1801: +case 0x1802: +case 0x1803: +case 0x1804: +case 0x1805: +case 0x1806: +case 0x1807: +case 0x1a00: +case 0x1a01: +case 0x1a02: +case 0x1a03: +case 0x1a04: +case 0x1a05: +case 0x1a06: +case 0x1a07: +case 0x1c00: +case 0x1c01: +case 0x1c02: +case 0x1c03: +case 0x1c04: +case 0x1c05: +case 0x1c06: +case 0x1c07: +case 0x1e00: +case 0x1e01: +case 0x1e02: +case 0x1e03: +case 0x1e04: +case 0x1e05: +case 0x1e06: +case 0x1e07: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x8000: +case 0x8001: +case 0x8002: +case 0x8003: +case 0x8004: +case 0x8005: +case 0x8006: +case 0x8007: +case 0x8200: +case 0x8201: +case 0x8202: +case 0x8203: +case 0x8204: +case 0x8205: +case 0x8206: +case 0x8207: +case 0x8400: +case 0x8401: +case 0x8402: +case 0x8403: +case 0x8404: +case 0x8405: +case 0x8406: +case 0x8407: +case 0x8600: +case 0x8601: +case 0x8602: +case 0x8603: +case 0x8604: +case 0x8605: +case 0x8606: +case 0x8607: +case 0x8800: +case 0x8801: +case 0x8802: +case 0x8803: +case 0x8804: +case 0x8805: +case 0x8806: +case 0x8807: +case 0x8a00: +case 0x8a01: +case 0x8a02: +case 0x8a03: +case 0x8a04: +case 0x8a05: +case 0x8a06: +case 0x8a07: +case 0x8c00: +case 0x8c01: +case 0x8c02: +case 0x8c03: +case 0x8c04: +case 0x8c05: +case 0x8c06: +case 0x8c07: +case 0x8e00: +case 0x8e01: +case 0x8e02: +case 0x8e03: +case 0x8e04: +case 0x8e05: +case 0x8e06: +case 0x8e07: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x8100: +case 0x8101: +case 0x8102: +case 0x8103: +case 0x8104: +case 0x8105: +case 0x8106: +case 0x8107: +case 0x8300: +case 0x8301: +case 0x8302: +case 0x8303: +case 0x8304: +case 0x8305: +case 0x8306: +case 0x8307: +case 0x8500: +case 0x8501: +case 0x8502: +case 0x8503: +case 0x8504: +case 0x8505: +case 0x8506: +case 0x8507: +case 0x8700: +case 0x8701: +case 0x8702: +case 0x8703: +case 0x8704: +case 0x8705: +case 0x8706: +case 0x8707: +case 0x8900: +case 0x8901: +case 0x8902: +case 0x8903: +case 0x8904: +case 0x8905: +case 0x8906: +case 0x8907: +case 0x8b00: +case 0x8b01: +case 0x8b02: +case 0x8b03: +case 0x8b04: +case 0x8b05: +case 0x8b06: +case 0x8b07: +case 0x8d00: +case 0x8d01: +case 0x8d02: +case 0x8d03: +case 0x8d04: +case 0x8d05: +case 0x8d06: +case 0x8d07: +case 0x8f00: +case 0x8f01: +case 0x8f02: +case 0x8f03: +case 0x8f04: +case 0x8f05: +case 0x8f06: +case 0x8f07: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SBCD(src, dst); + } + break; + +case 0x9000: +case 0x9001: +case 0x9002: +case 0x9003: +case 0x9004: +case 0x9005: +case 0x9006: +case 0x9007: +case 0x9200: +case 0x9201: +case 0x9202: +case 0x9203: +case 0x9204: +case 0x9205: +case 0x9206: +case 0x9207: +case 0x9400: +case 0x9401: +case 0x9402: +case 0x9403: +case 0x9404: +case 0x9405: +case 0x9406: +case 0x9407: +case 0x9600: +case 0x9601: +case 0x9602: +case 0x9603: +case 0x9604: +case 0x9605: +case 0x9606: +case 0x9607: +case 0x9800: +case 0x9801: +case 0x9802: +case 0x9803: +case 0x9804: +case 0x9805: +case 0x9806: +case 0x9807: +case 0x9a00: +case 0x9a01: +case 0x9a02: +case 0x9a03: +case 0x9a04: +case 0x9a05: +case 0x9a06: +case 0x9a07: +case 0x9c00: +case 0x9c01: +case 0x9c02: +case 0x9c03: +case 0x9c04: +case 0x9c05: +case 0x9c06: +case 0x9c07: +case 0x9e00: +case 0x9e01: +case 0x9e02: +case 0x9e03: +case 0x9e04: +case 0x9e05: +case 0x9e06: +case 0x9e07: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x9100: +case 0x9101: +case 0x9102: +case 0x9103: +case 0x9104: +case 0x9105: +case 0x9106: +case 0x9107: +case 0x9300: +case 0x9301: +case 0x9302: +case 0x9303: +case 0x9304: +case 0x9305: +case 0x9306: +case 0x9307: +case 0x9500: +case 0x9501: +case 0x9502: +case 0x9503: +case 0x9504: +case 0x9505: +case 0x9506: +case 0x9507: +case 0x9700: +case 0x9701: +case 0x9702: +case 0x9703: +case 0x9704: +case 0x9705: +case 0x9706: +case 0x9707: +case 0x9900: +case 0x9901: +case 0x9902: +case 0x9903: +case 0x9904: +case 0x9905: +case 0x9906: +case 0x9907: +case 0x9b00: +case 0x9b01: +case 0x9b02: +case 0x9b03: +case 0x9b04: +case 0x9b05: +case 0x9b06: +case 0x9b07: +case 0x9d00: +case 0x9d01: +case 0x9d02: +case 0x9d03: +case 0x9d04: +case 0x9d05: +case 0x9d06: +case 0x9d07: +case 0x9f00: +case 0x9f01: +case 0x9f02: +case 0x9f03: +case 0x9f04: +case 0x9f05: +case 0x9f06: +case 0x9f07: + { + HAM src(this, instr_b2_b0); HAM dst(this, instr_b11_b9); SUBX(src, dst); + } + break; + +case 0xe120: +case 0xe121: +case 0xe122: +case 0xe123: +case 0xe124: +case 0xe125: +case 0xe126: +case 0xe127: +case 0xe320: +case 0xe321: +case 0xe322: +case 0xe323: +case 0xe324: +case 0xe325: +case 0xe326: +case 0xe327: +case 0xe520: +case 0xe521: +case 0xe522: +case 0xe523: +case 0xe524: +case 0xe525: +case 0xe526: +case 0xe527: +case 0xe720: +case 0xe721: +case 0xe722: +case 0xe723: +case 0xe724: +case 0xe725: +case 0xe726: +case 0xe727: +case 0xe920: +case 0xe921: +case 0xe922: +case 0xe923: +case 0xe924: +case 0xe925: +case 0xe926: +case 0xe927: +case 0xeb20: +case 0xeb21: +case 0xeb22: +case 0xeb23: +case 0xeb24: +case 0xeb25: +case 0xeb26: +case 0xeb27: +case 0xed20: +case 0xed21: +case 0xed22: +case 0xed23: +case 0xed24: +case 0xed25: +case 0xed26: +case 0xed27: +case 0xef20: +case 0xef21: +case 0xef22: +case 0xef23: +case 0xef24: +case 0xef25: +case 0xef26: +case 0xef27: + { + HAM targ(this, instr_b2_b0); ASL(targ, D[instr_b11_b9]); + } + break; + +case 0xe100: +case 0xe101: +case 0xe102: +case 0xe103: +case 0xe104: +case 0xe105: +case 0xe106: +case 0xe107: +case 0xe300: +case 0xe301: +case 0xe302: +case 0xe303: +case 0xe304: +case 0xe305: +case 0xe306: +case 0xe307: +case 0xe500: +case 0xe501: +case 0xe502: +case 0xe503: +case 0xe504: +case 0xe505: +case 0xe506: +case 0xe507: +case 0xe700: +case 0xe701: +case 0xe702: +case 0xe703: +case 0xe704: +case 0xe705: +case 0xe706: +case 0xe707: +case 0xe900: +case 0xe901: +case 0xe902: +case 0xe903: +case 0xe904: +case 0xe905: +case 0xe906: +case 0xe907: +case 0xeb00: +case 0xeb01: +case 0xeb02: +case 0xeb03: +case 0xeb04: +case 0xeb05: +case 0xeb06: +case 0xeb07: +case 0xed00: +case 0xed01: +case 0xed02: +case 0xed03: +case 0xed04: +case 0xed05: +case 0xed06: +case 0xed07: +case 0xef00: +case 0xef01: +case 0xef02: +case 0xef03: +case 0xef04: +case 0xef05: +case 0xef06: +case 0xef07: + { + HAM targ(this, instr_b2_b0); ASL(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe020: +case 0xe021: +case 0xe022: +case 0xe023: +case 0xe024: +case 0xe025: +case 0xe026: +case 0xe027: +case 0xe220: +case 0xe221: +case 0xe222: +case 0xe223: +case 0xe224: +case 0xe225: +case 0xe226: +case 0xe227: +case 0xe420: +case 0xe421: +case 0xe422: +case 0xe423: +case 0xe424: +case 0xe425: +case 0xe426: +case 0xe427: +case 0xe620: +case 0xe621: +case 0xe622: +case 0xe623: +case 0xe624: +case 0xe625: +case 0xe626: +case 0xe627: +case 0xe820: +case 0xe821: +case 0xe822: +case 0xe823: +case 0xe824: +case 0xe825: +case 0xe826: +case 0xe827: +case 0xea20: +case 0xea21: +case 0xea22: +case 0xea23: +case 0xea24: +case 0xea25: +case 0xea26: +case 0xea27: +case 0xec20: +case 0xec21: +case 0xec22: +case 0xec23: +case 0xec24: +case 0xec25: +case 0xec26: +case 0xec27: +case 0xee20: +case 0xee21: +case 0xee22: +case 0xee23: +case 0xee24: +case 0xee25: +case 0xee26: +case 0xee27: + { + HAM targ(this, instr_b2_b0); ASR(targ, D[instr_b11_b9]); + } + break; + +case 0xe000: +case 0xe001: +case 0xe002: +case 0xe003: +case 0xe004: +case 0xe005: +case 0xe006: +case 0xe007: +case 0xe200: +case 0xe201: +case 0xe202: +case 0xe203: +case 0xe204: +case 0xe205: +case 0xe206: +case 0xe207: +case 0xe400: +case 0xe401: +case 0xe402: +case 0xe403: +case 0xe404: +case 0xe405: +case 0xe406: +case 0xe407: +case 0xe600: +case 0xe601: +case 0xe602: +case 0xe603: +case 0xe604: +case 0xe605: +case 0xe606: +case 0xe607: +case 0xe800: +case 0xe801: +case 0xe802: +case 0xe803: +case 0xe804: +case 0xe805: +case 0xe806: +case 0xe807: +case 0xea00: +case 0xea01: +case 0xea02: +case 0xea03: +case 0xea04: +case 0xea05: +case 0xea06: +case 0xea07: +case 0xec00: +case 0xec01: +case 0xec02: +case 0xec03: +case 0xec04: +case 0xec05: +case 0xec06: +case 0xec07: +case 0xee00: +case 0xee01: +case 0xee02: +case 0xee03: +case 0xee04: +case 0xee05: +case 0xee06: +case 0xee07: + { + HAM targ(this, instr_b2_b0); ASR(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe128: +case 0xe129: +case 0xe12a: +case 0xe12b: +case 0xe12c: +case 0xe12d: +case 0xe12e: +case 0xe12f: +case 0xe328: +case 0xe329: +case 0xe32a: +case 0xe32b: +case 0xe32c: +case 0xe32d: +case 0xe32e: +case 0xe32f: +case 0xe528: +case 0xe529: +case 0xe52a: +case 0xe52b: +case 0xe52c: +case 0xe52d: +case 0xe52e: +case 0xe52f: +case 0xe728: +case 0xe729: +case 0xe72a: +case 0xe72b: +case 0xe72c: +case 0xe72d: +case 0xe72e: +case 0xe72f: +case 0xe928: +case 0xe929: +case 0xe92a: +case 0xe92b: +case 0xe92c: +case 0xe92d: +case 0xe92e: +case 0xe92f: +case 0xeb28: +case 0xeb29: +case 0xeb2a: +case 0xeb2b: +case 0xeb2c: +case 0xeb2d: +case 0xeb2e: +case 0xeb2f: +case 0xed28: +case 0xed29: +case 0xed2a: +case 0xed2b: +case 0xed2c: +case 0xed2d: +case 0xed2e: +case 0xed2f: +case 0xef28: +case 0xef29: +case 0xef2a: +case 0xef2b: +case 0xef2c: +case 0xef2d: +case 0xef2e: +case 0xef2f: + { + HAM targ(this, instr_b2_b0); LSL(targ, D[instr_b11_b9]); + } + break; + +case 0xe108: +case 0xe109: +case 0xe10a: +case 0xe10b: +case 0xe10c: +case 0xe10d: +case 0xe10e: +case 0xe10f: +case 0xe308: +case 0xe309: +case 0xe30a: +case 0xe30b: +case 0xe30c: +case 0xe30d: +case 0xe30e: +case 0xe30f: +case 0xe508: +case 0xe509: +case 0xe50a: +case 0xe50b: +case 0xe50c: +case 0xe50d: +case 0xe50e: +case 0xe50f: +case 0xe708: +case 0xe709: +case 0xe70a: +case 0xe70b: +case 0xe70c: +case 0xe70d: +case 0xe70e: +case 0xe70f: +case 0xe908: +case 0xe909: +case 0xe90a: +case 0xe90b: +case 0xe90c: +case 0xe90d: +case 0xe90e: +case 0xe90f: +case 0xeb08: +case 0xeb09: +case 0xeb0a: +case 0xeb0b: +case 0xeb0c: +case 0xeb0d: +case 0xeb0e: +case 0xeb0f: +case 0xed08: +case 0xed09: +case 0xed0a: +case 0xed0b: +case 0xed0c: +case 0xed0d: +case 0xed0e: +case 0xed0f: +case 0xef08: +case 0xef09: +case 0xef0a: +case 0xef0b: +case 0xef0c: +case 0xef0d: +case 0xef0e: +case 0xef0f: + { + HAM targ(this, instr_b2_b0); LSL(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe028: +case 0xe029: +case 0xe02a: +case 0xe02b: +case 0xe02c: +case 0xe02d: +case 0xe02e: +case 0xe02f: +case 0xe228: +case 0xe229: +case 0xe22a: +case 0xe22b: +case 0xe22c: +case 0xe22d: +case 0xe22e: +case 0xe22f: +case 0xe428: +case 0xe429: +case 0xe42a: +case 0xe42b: +case 0xe42c: +case 0xe42d: +case 0xe42e: +case 0xe42f: +case 0xe628: +case 0xe629: +case 0xe62a: +case 0xe62b: +case 0xe62c: +case 0xe62d: +case 0xe62e: +case 0xe62f: +case 0xe828: +case 0xe829: +case 0xe82a: +case 0xe82b: +case 0xe82c: +case 0xe82d: +case 0xe82e: +case 0xe82f: +case 0xea28: +case 0xea29: +case 0xea2a: +case 0xea2b: +case 0xea2c: +case 0xea2d: +case 0xea2e: +case 0xea2f: +case 0xec28: +case 0xec29: +case 0xec2a: +case 0xec2b: +case 0xec2c: +case 0xec2d: +case 0xec2e: +case 0xec2f: +case 0xee28: +case 0xee29: +case 0xee2a: +case 0xee2b: +case 0xee2c: +case 0xee2d: +case 0xee2e: +case 0xee2f: + { + HAM targ(this, instr_b2_b0); LSR(targ, D[instr_b11_b9]); + } + break; + +case 0xe008: +case 0xe009: +case 0xe00a: +case 0xe00b: +case 0xe00c: +case 0xe00d: +case 0xe00e: +case 0xe00f: +case 0xe208: +case 0xe209: +case 0xe20a: +case 0xe20b: +case 0xe20c: +case 0xe20d: +case 0xe20e: +case 0xe20f: +case 0xe408: +case 0xe409: +case 0xe40a: +case 0xe40b: +case 0xe40c: +case 0xe40d: +case 0xe40e: +case 0xe40f: +case 0xe608: +case 0xe609: +case 0xe60a: +case 0xe60b: +case 0xe60c: +case 0xe60d: +case 0xe60e: +case 0xe60f: +case 0xe808: +case 0xe809: +case 0xe80a: +case 0xe80b: +case 0xe80c: +case 0xe80d: +case 0xe80e: +case 0xe80f: +case 0xea08: +case 0xea09: +case 0xea0a: +case 0xea0b: +case 0xea0c: +case 0xea0d: +case 0xea0e: +case 0xea0f: +case 0xec08: +case 0xec09: +case 0xec0a: +case 0xec0b: +case 0xec0c: +case 0xec0d: +case 0xec0e: +case 0xec0f: +case 0xee08: +case 0xee09: +case 0xee0a: +case 0xee0b: +case 0xee0c: +case 0xee0d: +case 0xee0e: +case 0xee0f: + { + HAM targ(this, instr_b2_b0); LSR(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe138: +case 0xe139: +case 0xe13a: +case 0xe13b: +case 0xe13c: +case 0xe13d: +case 0xe13e: +case 0xe13f: +case 0xe338: +case 0xe339: +case 0xe33a: +case 0xe33b: +case 0xe33c: +case 0xe33d: +case 0xe33e: +case 0xe33f: +case 0xe538: +case 0xe539: +case 0xe53a: +case 0xe53b: +case 0xe53c: +case 0xe53d: +case 0xe53e: +case 0xe53f: +case 0xe738: +case 0xe739: +case 0xe73a: +case 0xe73b: +case 0xe73c: +case 0xe73d: +case 0xe73e: +case 0xe73f: +case 0xe938: +case 0xe939: +case 0xe93a: +case 0xe93b: +case 0xe93c: +case 0xe93d: +case 0xe93e: +case 0xe93f: +case 0xeb38: +case 0xeb39: +case 0xeb3a: +case 0xeb3b: +case 0xeb3c: +case 0xeb3d: +case 0xeb3e: +case 0xeb3f: +case 0xed38: +case 0xed39: +case 0xed3a: +case 0xed3b: +case 0xed3c: +case 0xed3d: +case 0xed3e: +case 0xed3f: +case 0xef38: +case 0xef39: +case 0xef3a: +case 0xef3b: +case 0xef3c: +case 0xef3d: +case 0xef3e: +case 0xef3f: + { + HAM targ(this, instr_b2_b0); ROL(targ, D[instr_b11_b9]); + } + break; + +case 0xe118: +case 0xe119: +case 0xe11a: +case 0xe11b: +case 0xe11c: +case 0xe11d: +case 0xe11e: +case 0xe11f: +case 0xe318: +case 0xe319: +case 0xe31a: +case 0xe31b: +case 0xe31c: +case 0xe31d: +case 0xe31e: +case 0xe31f: +case 0xe518: +case 0xe519: +case 0xe51a: +case 0xe51b: +case 0xe51c: +case 0xe51d: +case 0xe51e: +case 0xe51f: +case 0xe718: +case 0xe719: +case 0xe71a: +case 0xe71b: +case 0xe71c: +case 0xe71d: +case 0xe71e: +case 0xe71f: +case 0xe918: +case 0xe919: +case 0xe91a: +case 0xe91b: +case 0xe91c: +case 0xe91d: +case 0xe91e: +case 0xe91f: +case 0xeb18: +case 0xeb19: +case 0xeb1a: +case 0xeb1b: +case 0xeb1c: +case 0xeb1d: +case 0xeb1e: +case 0xeb1f: +case 0xed18: +case 0xed19: +case 0xed1a: +case 0xed1b: +case 0xed1c: +case 0xed1d: +case 0xed1e: +case 0xed1f: +case 0xef18: +case 0xef19: +case 0xef1a: +case 0xef1b: +case 0xef1c: +case 0xef1d: +case 0xef1e: +case 0xef1f: + { + HAM targ(this, instr_b2_b0); ROL(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe038: +case 0xe039: +case 0xe03a: +case 0xe03b: +case 0xe03c: +case 0xe03d: +case 0xe03e: +case 0xe03f: +case 0xe238: +case 0xe239: +case 0xe23a: +case 0xe23b: +case 0xe23c: +case 0xe23d: +case 0xe23e: +case 0xe23f: +case 0xe438: +case 0xe439: +case 0xe43a: +case 0xe43b: +case 0xe43c: +case 0xe43d: +case 0xe43e: +case 0xe43f: +case 0xe638: +case 0xe639: +case 0xe63a: +case 0xe63b: +case 0xe63c: +case 0xe63d: +case 0xe63e: +case 0xe63f: +case 0xe838: +case 0xe839: +case 0xe83a: +case 0xe83b: +case 0xe83c: +case 0xe83d: +case 0xe83e: +case 0xe83f: +case 0xea38: +case 0xea39: +case 0xea3a: +case 0xea3b: +case 0xea3c: +case 0xea3d: +case 0xea3e: +case 0xea3f: +case 0xec38: +case 0xec39: +case 0xec3a: +case 0xec3b: +case 0xec3c: +case 0xec3d: +case 0xec3e: +case 0xec3f: +case 0xee38: +case 0xee39: +case 0xee3a: +case 0xee3b: +case 0xee3c: +case 0xee3d: +case 0xee3e: +case 0xee3f: + { + HAM targ(this, instr_b2_b0); ROR(targ, D[instr_b11_b9]); + } + break; + +case 0xe018: +case 0xe019: +case 0xe01a: +case 0xe01b: +case 0xe01c: +case 0xe01d: +case 0xe01e: +case 0xe01f: +case 0xe218: +case 0xe219: +case 0xe21a: +case 0xe21b: +case 0xe21c: +case 0xe21d: +case 0xe21e: +case 0xe21f: +case 0xe418: +case 0xe419: +case 0xe41a: +case 0xe41b: +case 0xe41c: +case 0xe41d: +case 0xe41e: +case 0xe41f: +case 0xe618: +case 0xe619: +case 0xe61a: +case 0xe61b: +case 0xe61c: +case 0xe61d: +case 0xe61e: +case 0xe61f: +case 0xe818: +case 0xe819: +case 0xe81a: +case 0xe81b: +case 0xe81c: +case 0xe81d: +case 0xe81e: +case 0xe81f: +case 0xea18: +case 0xea19: +case 0xea1a: +case 0xea1b: +case 0xea1c: +case 0xea1d: +case 0xea1e: +case 0xea1f: +case 0xec18: +case 0xec19: +case 0xec1a: +case 0xec1b: +case 0xec1c: +case 0xec1d: +case 0xec1e: +case 0xec1f: +case 0xee18: +case 0xee19: +case 0xee1a: +case 0xee1b: +case 0xee1c: +case 0xee1d: +case 0xee1e: +case 0xee1f: + { + HAM targ(this, instr_b2_b0); ROR(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe130: +case 0xe131: +case 0xe132: +case 0xe133: +case 0xe134: +case 0xe135: +case 0xe136: +case 0xe137: +case 0xe330: +case 0xe331: +case 0xe332: +case 0xe333: +case 0xe334: +case 0xe335: +case 0xe336: +case 0xe337: +case 0xe530: +case 0xe531: +case 0xe532: +case 0xe533: +case 0xe534: +case 0xe535: +case 0xe536: +case 0xe537: +case 0xe730: +case 0xe731: +case 0xe732: +case 0xe733: +case 0xe734: +case 0xe735: +case 0xe736: +case 0xe737: +case 0xe930: +case 0xe931: +case 0xe932: +case 0xe933: +case 0xe934: +case 0xe935: +case 0xe936: +case 0xe937: +case 0xeb30: +case 0xeb31: +case 0xeb32: +case 0xeb33: +case 0xeb34: +case 0xeb35: +case 0xeb36: +case 0xeb37: +case 0xed30: +case 0xed31: +case 0xed32: +case 0xed33: +case 0xed34: +case 0xed35: +case 0xed36: +case 0xed37: +case 0xef30: +case 0xef31: +case 0xef32: +case 0xef33: +case 0xef34: +case 0xef35: +case 0xef36: +case 0xef37: + { + HAM targ(this, instr_b2_b0); ROXL(targ, D[instr_b11_b9]); + } + break; + +case 0xe110: +case 0xe111: +case 0xe112: +case 0xe113: +case 0xe114: +case 0xe115: +case 0xe116: +case 0xe117: +case 0xe310: +case 0xe311: +case 0xe312: +case 0xe313: +case 0xe314: +case 0xe315: +case 0xe316: +case 0xe317: +case 0xe510: +case 0xe511: +case 0xe512: +case 0xe513: +case 0xe514: +case 0xe515: +case 0xe516: +case 0xe517: +case 0xe710: +case 0xe711: +case 0xe712: +case 0xe713: +case 0xe714: +case 0xe715: +case 0xe716: +case 0xe717: +case 0xe910: +case 0xe911: +case 0xe912: +case 0xe913: +case 0xe914: +case 0xe915: +case 0xe916: +case 0xe917: +case 0xeb10: +case 0xeb11: +case 0xeb12: +case 0xeb13: +case 0xeb14: +case 0xeb15: +case 0xeb16: +case 0xeb17: +case 0xed10: +case 0xed11: +case 0xed12: +case 0xed13: +case 0xed14: +case 0xed15: +case 0xed16: +case 0xed17: +case 0xef10: +case 0xef11: +case 0xef12: +case 0xef13: +case 0xef14: +case 0xef15: +case 0xef16: +case 0xef17: + { + HAM targ(this, instr_b2_b0); ROXL(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0xe030: +case 0xe031: +case 0xe032: +case 0xe033: +case 0xe034: +case 0xe035: +case 0xe036: +case 0xe037: +case 0xe230: +case 0xe231: +case 0xe232: +case 0xe233: +case 0xe234: +case 0xe235: +case 0xe236: +case 0xe237: +case 0xe430: +case 0xe431: +case 0xe432: +case 0xe433: +case 0xe434: +case 0xe435: +case 0xe436: +case 0xe437: +case 0xe630: +case 0xe631: +case 0xe632: +case 0xe633: +case 0xe634: +case 0xe635: +case 0xe636: +case 0xe637: +case 0xe830: +case 0xe831: +case 0xe832: +case 0xe833: +case 0xe834: +case 0xe835: +case 0xe836: +case 0xe837: +case 0xea30: +case 0xea31: +case 0xea32: +case 0xea33: +case 0xea34: +case 0xea35: +case 0xea36: +case 0xea37: +case 0xec30: +case 0xec31: +case 0xec32: +case 0xec33: +case 0xec34: +case 0xec35: +case 0xec36: +case 0xec37: +case 0xee30: +case 0xee31: +case 0xee32: +case 0xee33: +case 0xee34: +case 0xee35: +case 0xee36: +case 0xee37: + { + HAM targ(this, instr_b2_b0); ROXR(targ, D[instr_b11_b9]); + } + break; + +case 0xe010: +case 0xe011: +case 0xe012: +case 0xe013: +case 0xe014: +case 0xe015: +case 0xe016: +case 0xe017: +case 0xe210: +case 0xe211: +case 0xe212: +case 0xe213: +case 0xe214: +case 0xe215: +case 0xe216: +case 0xe217: +case 0xe410: +case 0xe411: +case 0xe412: +case 0xe413: +case 0xe414: +case 0xe415: +case 0xe416: +case 0xe417: +case 0xe610: +case 0xe611: +case 0xe612: +case 0xe613: +case 0xe614: +case 0xe615: +case 0xe616: +case 0xe617: +case 0xe810: +case 0xe811: +case 0xe812: +case 0xe813: +case 0xe814: +case 0xe815: +case 0xe816: +case 0xe817: +case 0xea10: +case 0xea11: +case 0xea12: +case 0xea13: +case 0xea14: +case 0xea15: +case 0xea16: +case 0xea17: +case 0xec10: +case 0xec11: +case 0xec12: +case 0xec13: +case 0xec14: +case 0xec15: +case 0xec16: +case 0xec17: +case 0xee10: +case 0xee11: +case 0xee12: +case 0xee13: +case 0xee14: +case 0xee15: +case 0xee16: +case 0xee17: + { + HAM targ(this, instr_b2_b0); ROXR(targ, instr_b11_b9 ? instr_b11_b9 : 8); + } + break; + +case 0x0639: + { + HAM src(this); HAM dst(this); ADD(src, dst); + } + break; + +case 0x0239: + { + HAM src(this); HAM dst(this); AND(src, dst); + } + break; + +case 0x0c39: + { + HAM src(this); HAM dst(this); CMP(src, dst); + } + break; + +case 0x0a39: + { + HAM src(this); HAM dst(this); EOR(src, dst); + } + break; + +case 0x13fc: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x0039: + { + HAM src(this); HAM dst(this); OR(src, dst); + } + break; + +case 0x0439: + { + HAM src(this); HAM dst(this); SUB(src, dst); + } + break; + +case 0x0638: + { + HAM src(this); HAM dst(this); ADD(src, dst); + } + break; + +case 0x0238: + { + HAM src(this); HAM dst(this); AND(src, dst); + } + break; + +case 0x0c38: + { + HAM src(this); HAM dst(this); CMP(src, dst); + } + break; + +case 0x0a38: + { + HAM src(this); HAM dst(this); EOR(src, dst); + } + break; + +case 0x11fc: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x0038: + { + HAM src(this); HAM dst(this); OR(src, dst); + } + break; + +case 0x0438: + { + HAM src(this); HAM dst(this); SUB(src, dst); + } + break; + +case 0x10bc: +case 0x12bc: +case 0x14bc: +case 0x16bc: +case 0x18bc: +case 0x1abc: +case 0x1cbc: +case 0x1ebc: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x0610: +case 0x0611: +case 0x0612: +case 0x0613: +case 0x0614: +case 0x0615: +case 0x0616: +case 0x0617: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x0210: +case 0x0211: +case 0x0212: +case 0x0213: +case 0x0214: +case 0x0215: +case 0x0216: +case 0x0217: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0c10: +case 0x0c11: +case 0x0c12: +case 0x0c13: +case 0x0c14: +case 0x0c15: +case 0x0c16: +case 0x0c17: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0a10: +case 0x0a11: +case 0x0a12: +case 0x0a13: +case 0x0a14: +case 0x0a15: +case 0x0a16: +case 0x0a17: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x0010: +case 0x0011: +case 0x0012: +case 0x0013: +case 0x0014: +case 0x0015: +case 0x0016: +case 0x0017: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x0410: +case 0x0411: +case 0x0412: +case 0x0413: +case 0x0414: +case 0x0415: +case 0x0416: +case 0x0417: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x117c: +case 0x137c: +case 0x157c: +case 0x177c: +case 0x197c: +case 0x1b7c: +case 0x1d7c: +case 0x1f7c: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x0628: +case 0x0629: +case 0x062a: +case 0x062b: +case 0x062c: +case 0x062d: +case 0x062e: +case 0x062f: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x0228: +case 0x0229: +case 0x022a: +case 0x022b: +case 0x022c: +case 0x022d: +case 0x022e: +case 0x022f: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0c28: +case 0x0c29: +case 0x0c2a: +case 0x0c2b: +case 0x0c2c: +case 0x0c2d: +case 0x0c2e: +case 0x0c2f: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0a28: +case 0x0a29: +case 0x0a2a: +case 0x0a2b: +case 0x0a2c: +case 0x0a2d: +case 0x0a2e: +case 0x0a2f: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x0028: +case 0x0029: +case 0x002a: +case 0x002b: +case 0x002c: +case 0x002d: +case 0x002e: +case 0x002f: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x0428: +case 0x0429: +case 0x042a: +case 0x042b: +case 0x042c: +case 0x042d: +case 0x042e: +case 0x042f: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x11bc: +case 0x13bc: +case 0x15bc: +case 0x17bc: +case 0x19bc: +case 0x1bbc: +case 0x1dbc: +case 0x1fbc: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x0630: +case 0x0631: +case 0x0632: +case 0x0633: +case 0x0634: +case 0x0635: +case 0x0636: +case 0x0637: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x0230: +case 0x0231: +case 0x0232: +case 0x0233: +case 0x0234: +case 0x0235: +case 0x0236: +case 0x0237: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0c30: +case 0x0c31: +case 0x0c32: +case 0x0c33: +case 0x0c34: +case 0x0c35: +case 0x0c36: +case 0x0c37: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0a30: +case 0x0a31: +case 0x0a32: +case 0x0a33: +case 0x0a34: +case 0x0a35: +case 0x0a36: +case 0x0a37: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x0030: +case 0x0031: +case 0x0032: +case 0x0033: +case 0x0034: +case 0x0035: +case 0x0036: +case 0x0037: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x0430: +case 0x0431: +case 0x0432: +case 0x0433: +case 0x0434: +case 0x0435: +case 0x0436: +case 0x0437: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x10fc: +case 0x12fc: +case 0x14fc: +case 0x16fc: +case 0x18fc: +case 0x1afc: +case 0x1cfc: +case 0x1efc: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x0618: +case 0x0619: +case 0x061a: +case 0x061b: +case 0x061c: +case 0x061d: +case 0x061e: +case 0x061f: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x0218: +case 0x0219: +case 0x021a: +case 0x021b: +case 0x021c: +case 0x021d: +case 0x021e: +case 0x021f: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0c18: +case 0x0c19: +case 0x0c1a: +case 0x0c1b: +case 0x0c1c: +case 0x0c1d: +case 0x0c1e: +case 0x0c1f: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0a18: +case 0x0a19: +case 0x0a1a: +case 0x0a1b: +case 0x0a1c: +case 0x0a1d: +case 0x0a1e: +case 0x0a1f: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x0018: +case 0x0019: +case 0x001a: +case 0x001b: +case 0x001c: +case 0x001d: +case 0x001e: +case 0x001f: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x0418: +case 0x0419: +case 0x041a: +case 0x041b: +case 0x041c: +case 0x041d: +case 0x041e: +case 0x041f: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x113c: +case 0x133c: +case 0x153c: +case 0x173c: +case 0x193c: +case 0x1b3c: +case 0x1d3c: +case 0x1f3c: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x0620: +case 0x0621: +case 0x0622: +case 0x0623: +case 0x0624: +case 0x0625: +case 0x0626: +case 0x0627: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x0220: +case 0x0221: +case 0x0222: +case 0x0223: +case 0x0224: +case 0x0225: +case 0x0226: +case 0x0227: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0c20: +case 0x0c21: +case 0x0c22: +case 0x0c23: +case 0x0c24: +case 0x0c25: +case 0x0c26: +case 0x0c27: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0a20: +case 0x0a21: +case 0x0a22: +case 0x0a23: +case 0x0a24: +case 0x0a25: +case 0x0a26: +case 0x0a27: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x0020: +case 0x0021: +case 0x0022: +case 0x0023: +case 0x0024: +case 0x0025: +case 0x0026: +case 0x0027: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x0420: +case 0x0421: +case 0x0422: +case 0x0423: +case 0x0424: +case 0x0425: +case 0x0426: +case 0x0427: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0xd03c: +case 0xd23c: +case 0xd43c: +case 0xd63c: +case 0xd83c: +case 0xda3c: +case 0xdc3c: +case 0xde3c: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc03c: +case 0xc23c: +case 0xc43c: +case 0xc63c: +case 0xc83c: +case 0xca3c: +case 0xcc3c: +case 0xce3c: + { + HAM src(this); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb03c: +case 0xb23c: +case 0xb43c: +case 0xb63c: +case 0xb83c: +case 0xba3c: +case 0xbc3c: +case 0xbe3c: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x103c: +case 0x123c: +case 0x143c: +case 0x163c: +case 0x183c: +case 0x1a3c: +case 0x1c3c: +case 0x1e3c: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x803c: +case 0x823c: +case 0x843c: +case 0x863c: +case 0x883c: +case 0x8a3c: +case 0x8c3c: +case 0x8e3c: + { + HAM src(this); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x903c: +case 0x923c: +case 0x943c: +case 0x963c: +case 0x983c: +case 0x9a3c: +case 0x9c3c: +case 0x9e3c: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x0600: +case 0x0601: +case 0x0602: +case 0x0603: +case 0x0604: +case 0x0605: +case 0x0606: +case 0x0607: + { + HAM src(this); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x0200: +case 0x0201: +case 0x0202: +case 0x0203: +case 0x0204: +case 0x0205: +case 0x0206: +case 0x0207: + { + HAM src(this); HAM dst(this, instr_b2_b0); AND(src, dst); + } + break; + +case 0x0c00: +case 0x0c01: +case 0x0c02: +case 0x0c03: +case 0x0c04: +case 0x0c05: +case 0x0c06: +case 0x0c07: + { + HAM src(this); HAM dst(this, instr_b2_b0); CMP(src, dst); + } + break; + +case 0x0a00: +case 0x0a01: +case 0x0a02: +case 0x0a03: +case 0x0a04: +case 0x0a05: +case 0x0a06: +case 0x0a07: + { + HAM src(this); HAM dst(this, instr_b2_b0); EOR(src, dst); + } + break; + +case 0x0000: +case 0x0001: +case 0x0002: +case 0x0003: +case 0x0004: +case 0x0005: +case 0x0006: +case 0x0007: + { + HAM src(this); HAM dst(this, instr_b2_b0); OR(src, dst); + } + break; + +case 0x0400: +case 0x0401: +case 0x0402: +case 0x0403: +case 0x0404: +case 0x0405: +case 0x0406: +case 0x0407: + { + HAM src(this); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x5008: +case 0x5009: +case 0x500a: +case 0x500b: +case 0x500c: +case 0x500d: +case 0x500e: +case 0x500f: +case 0x5208: +case 0x5209: +case 0x520a: +case 0x520b: +case 0x520c: +case 0x520d: +case 0x520e: +case 0x520f: +case 0x5408: +case 0x5409: +case 0x540a: +case 0x540b: +case 0x540c: +case 0x540d: +case 0x540e: +case 0x540f: +case 0x5608: +case 0x5609: +case 0x560a: +case 0x560b: +case 0x560c: +case 0x560d: +case 0x560e: +case 0x560f: +case 0x5808: +case 0x5809: +case 0x580a: +case 0x580b: +case 0x580c: +case 0x580d: +case 0x580e: +case 0x580f: +case 0x5a08: +case 0x5a09: +case 0x5a0a: +case 0x5a0b: +case 0x5a0c: +case 0x5a0d: +case 0x5a0e: +case 0x5a0f: +case 0x5c08: +case 0x5c09: +case 0x5c0a: +case 0x5c0b: +case 0x5c0c: +case 0x5c0d: +case 0x5c0e: +case 0x5c0f: +case 0x5e08: +case 0x5e09: +case 0x5e0a: +case 0x5e0b: +case 0x5e0c: +case 0x5e0d: +case 0x5e0e: +case 0x5e0f: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5108: +case 0x5109: +case 0x510a: +case 0x510b: +case 0x510c: +case 0x510d: +case 0x510e: +case 0x510f: +case 0x5308: +case 0x5309: +case 0x530a: +case 0x530b: +case 0x530c: +case 0x530d: +case 0x530e: +case 0x530f: +case 0x5508: +case 0x5509: +case 0x550a: +case 0x550b: +case 0x550c: +case 0x550d: +case 0x550e: +case 0x550f: +case 0x5708: +case 0x5709: +case 0x570a: +case 0x570b: +case 0x570c: +case 0x570d: +case 0x570e: +case 0x570f: +case 0x5908: +case 0x5909: +case 0x590a: +case 0x590b: +case 0x590c: +case 0x590d: +case 0x590e: +case 0x590f: +case 0x5b08: +case 0x5b09: +case 0x5b0a: +case 0x5b0b: +case 0x5b0c: +case 0x5b0d: +case 0x5b0e: +case 0x5b0f: +case 0x5d08: +case 0x5d09: +case 0x5d0a: +case 0x5d0b: +case 0x5d0c: +case 0x5d0d: +case 0x5d0e: +case 0x5d0f: +case 0x5f08: +case 0x5f09: +case 0x5f0a: +case 0x5f0b: +case 0x5f0c: +case 0x5f0d: +case 0x5f0e: +case 0x5f0f: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x5039: +case 0x5239: +case 0x5439: +case 0x5639: +case 0x5839: +case 0x5a39: +case 0x5c39: +case 0x5e39: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this); ADD(src, dst); + } + break; + +case 0x5139: +case 0x5339: +case 0x5539: +case 0x5739: +case 0x5939: +case 0x5b39: +case 0x5d39: +case 0x5f39: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this); SUB(src, dst); + } + break; + +case 0x5038: +case 0x5238: +case 0x5438: +case 0x5638: +case 0x5838: +case 0x5a38: +case 0x5c38: +case 0x5e38: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this); ADD(src, dst); + } + break; + +case 0x5138: +case 0x5338: +case 0x5538: +case 0x5738: +case 0x5938: +case 0x5b38: +case 0x5d38: +case 0x5f38: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this); SUB(src, dst); + } + break; + +case 0x5010: +case 0x5011: +case 0x5012: +case 0x5013: +case 0x5014: +case 0x5015: +case 0x5016: +case 0x5017: +case 0x5210: +case 0x5211: +case 0x5212: +case 0x5213: +case 0x5214: +case 0x5215: +case 0x5216: +case 0x5217: +case 0x5410: +case 0x5411: +case 0x5412: +case 0x5413: +case 0x5414: +case 0x5415: +case 0x5416: +case 0x5417: +case 0x5610: +case 0x5611: +case 0x5612: +case 0x5613: +case 0x5614: +case 0x5615: +case 0x5616: +case 0x5617: +case 0x5810: +case 0x5811: +case 0x5812: +case 0x5813: +case 0x5814: +case 0x5815: +case 0x5816: +case 0x5817: +case 0x5a10: +case 0x5a11: +case 0x5a12: +case 0x5a13: +case 0x5a14: +case 0x5a15: +case 0x5a16: +case 0x5a17: +case 0x5c10: +case 0x5c11: +case 0x5c12: +case 0x5c13: +case 0x5c14: +case 0x5c15: +case 0x5c16: +case 0x5c17: +case 0x5e10: +case 0x5e11: +case 0x5e12: +case 0x5e13: +case 0x5e14: +case 0x5e15: +case 0x5e16: +case 0x5e17: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5110: +case 0x5111: +case 0x5112: +case 0x5113: +case 0x5114: +case 0x5115: +case 0x5116: +case 0x5117: +case 0x5310: +case 0x5311: +case 0x5312: +case 0x5313: +case 0x5314: +case 0x5315: +case 0x5316: +case 0x5317: +case 0x5510: +case 0x5511: +case 0x5512: +case 0x5513: +case 0x5514: +case 0x5515: +case 0x5516: +case 0x5517: +case 0x5710: +case 0x5711: +case 0x5712: +case 0x5713: +case 0x5714: +case 0x5715: +case 0x5716: +case 0x5717: +case 0x5910: +case 0x5911: +case 0x5912: +case 0x5913: +case 0x5914: +case 0x5915: +case 0x5916: +case 0x5917: +case 0x5b10: +case 0x5b11: +case 0x5b12: +case 0x5b13: +case 0x5b14: +case 0x5b15: +case 0x5b16: +case 0x5b17: +case 0x5d10: +case 0x5d11: +case 0x5d12: +case 0x5d13: +case 0x5d14: +case 0x5d15: +case 0x5d16: +case 0x5d17: +case 0x5f10: +case 0x5f11: +case 0x5f12: +case 0x5f13: +case 0x5f14: +case 0x5f15: +case 0x5f16: +case 0x5f17: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x5028: +case 0x5029: +case 0x502a: +case 0x502b: +case 0x502c: +case 0x502d: +case 0x502e: +case 0x502f: +case 0x5228: +case 0x5229: +case 0x522a: +case 0x522b: +case 0x522c: +case 0x522d: +case 0x522e: +case 0x522f: +case 0x5428: +case 0x5429: +case 0x542a: +case 0x542b: +case 0x542c: +case 0x542d: +case 0x542e: +case 0x542f: +case 0x5628: +case 0x5629: +case 0x562a: +case 0x562b: +case 0x562c: +case 0x562d: +case 0x562e: +case 0x562f: +case 0x5828: +case 0x5829: +case 0x582a: +case 0x582b: +case 0x582c: +case 0x582d: +case 0x582e: +case 0x582f: +case 0x5a28: +case 0x5a29: +case 0x5a2a: +case 0x5a2b: +case 0x5a2c: +case 0x5a2d: +case 0x5a2e: +case 0x5a2f: +case 0x5c28: +case 0x5c29: +case 0x5c2a: +case 0x5c2b: +case 0x5c2c: +case 0x5c2d: +case 0x5c2e: +case 0x5c2f: +case 0x5e28: +case 0x5e29: +case 0x5e2a: +case 0x5e2b: +case 0x5e2c: +case 0x5e2d: +case 0x5e2e: +case 0x5e2f: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5128: +case 0x5129: +case 0x512a: +case 0x512b: +case 0x512c: +case 0x512d: +case 0x512e: +case 0x512f: +case 0x5328: +case 0x5329: +case 0x532a: +case 0x532b: +case 0x532c: +case 0x532d: +case 0x532e: +case 0x532f: +case 0x5528: +case 0x5529: +case 0x552a: +case 0x552b: +case 0x552c: +case 0x552d: +case 0x552e: +case 0x552f: +case 0x5728: +case 0x5729: +case 0x572a: +case 0x572b: +case 0x572c: +case 0x572d: +case 0x572e: +case 0x572f: +case 0x5928: +case 0x5929: +case 0x592a: +case 0x592b: +case 0x592c: +case 0x592d: +case 0x592e: +case 0x592f: +case 0x5b28: +case 0x5b29: +case 0x5b2a: +case 0x5b2b: +case 0x5b2c: +case 0x5b2d: +case 0x5b2e: +case 0x5b2f: +case 0x5d28: +case 0x5d29: +case 0x5d2a: +case 0x5d2b: +case 0x5d2c: +case 0x5d2d: +case 0x5d2e: +case 0x5d2f: +case 0x5f28: +case 0x5f29: +case 0x5f2a: +case 0x5f2b: +case 0x5f2c: +case 0x5f2d: +case 0x5f2e: +case 0x5f2f: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x5030: +case 0x5031: +case 0x5032: +case 0x5033: +case 0x5034: +case 0x5035: +case 0x5036: +case 0x5037: +case 0x5230: +case 0x5231: +case 0x5232: +case 0x5233: +case 0x5234: +case 0x5235: +case 0x5236: +case 0x5237: +case 0x5430: +case 0x5431: +case 0x5432: +case 0x5433: +case 0x5434: +case 0x5435: +case 0x5436: +case 0x5437: +case 0x5630: +case 0x5631: +case 0x5632: +case 0x5633: +case 0x5634: +case 0x5635: +case 0x5636: +case 0x5637: +case 0x5830: +case 0x5831: +case 0x5832: +case 0x5833: +case 0x5834: +case 0x5835: +case 0x5836: +case 0x5837: +case 0x5a30: +case 0x5a31: +case 0x5a32: +case 0x5a33: +case 0x5a34: +case 0x5a35: +case 0x5a36: +case 0x5a37: +case 0x5c30: +case 0x5c31: +case 0x5c32: +case 0x5c33: +case 0x5c34: +case 0x5c35: +case 0x5c36: +case 0x5c37: +case 0x5e30: +case 0x5e31: +case 0x5e32: +case 0x5e33: +case 0x5e34: +case 0x5e35: +case 0x5e36: +case 0x5e37: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5130: +case 0x5131: +case 0x5132: +case 0x5133: +case 0x5134: +case 0x5135: +case 0x5136: +case 0x5137: +case 0x5330: +case 0x5331: +case 0x5332: +case 0x5333: +case 0x5334: +case 0x5335: +case 0x5336: +case 0x5337: +case 0x5530: +case 0x5531: +case 0x5532: +case 0x5533: +case 0x5534: +case 0x5535: +case 0x5536: +case 0x5537: +case 0x5730: +case 0x5731: +case 0x5732: +case 0x5733: +case 0x5734: +case 0x5735: +case 0x5736: +case 0x5737: +case 0x5930: +case 0x5931: +case 0x5932: +case 0x5933: +case 0x5934: +case 0x5935: +case 0x5936: +case 0x5937: +case 0x5b30: +case 0x5b31: +case 0x5b32: +case 0x5b33: +case 0x5b34: +case 0x5b35: +case 0x5b36: +case 0x5b37: +case 0x5d30: +case 0x5d31: +case 0x5d32: +case 0x5d33: +case 0x5d34: +case 0x5d35: +case 0x5d36: +case 0x5d37: +case 0x5f30: +case 0x5f31: +case 0x5f32: +case 0x5f33: +case 0x5f34: +case 0x5f35: +case 0x5f36: +case 0x5f37: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x5018: +case 0x5019: +case 0x501a: +case 0x501b: +case 0x501c: +case 0x501d: +case 0x501e: +case 0x501f: +case 0x5218: +case 0x5219: +case 0x521a: +case 0x521b: +case 0x521c: +case 0x521d: +case 0x521e: +case 0x521f: +case 0x5418: +case 0x5419: +case 0x541a: +case 0x541b: +case 0x541c: +case 0x541d: +case 0x541e: +case 0x541f: +case 0x5618: +case 0x5619: +case 0x561a: +case 0x561b: +case 0x561c: +case 0x561d: +case 0x561e: +case 0x561f: +case 0x5818: +case 0x5819: +case 0x581a: +case 0x581b: +case 0x581c: +case 0x581d: +case 0x581e: +case 0x581f: +case 0x5a18: +case 0x5a19: +case 0x5a1a: +case 0x5a1b: +case 0x5a1c: +case 0x5a1d: +case 0x5a1e: +case 0x5a1f: +case 0x5c18: +case 0x5c19: +case 0x5c1a: +case 0x5c1b: +case 0x5c1c: +case 0x5c1d: +case 0x5c1e: +case 0x5c1f: +case 0x5e18: +case 0x5e19: +case 0x5e1a: +case 0x5e1b: +case 0x5e1c: +case 0x5e1d: +case 0x5e1e: +case 0x5e1f: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5118: +case 0x5119: +case 0x511a: +case 0x511b: +case 0x511c: +case 0x511d: +case 0x511e: +case 0x511f: +case 0x5318: +case 0x5319: +case 0x531a: +case 0x531b: +case 0x531c: +case 0x531d: +case 0x531e: +case 0x531f: +case 0x5518: +case 0x5519: +case 0x551a: +case 0x551b: +case 0x551c: +case 0x551d: +case 0x551e: +case 0x551f: +case 0x5718: +case 0x5719: +case 0x571a: +case 0x571b: +case 0x571c: +case 0x571d: +case 0x571e: +case 0x571f: +case 0x5918: +case 0x5919: +case 0x591a: +case 0x591b: +case 0x591c: +case 0x591d: +case 0x591e: +case 0x591f: +case 0x5b18: +case 0x5b19: +case 0x5b1a: +case 0x5b1b: +case 0x5b1c: +case 0x5b1d: +case 0x5b1e: +case 0x5b1f: +case 0x5d18: +case 0x5d19: +case 0x5d1a: +case 0x5d1b: +case 0x5d1c: +case 0x5d1d: +case 0x5d1e: +case 0x5d1f: +case 0x5f18: +case 0x5f19: +case 0x5f1a: +case 0x5f1b: +case 0x5f1c: +case 0x5f1d: +case 0x5f1e: +case 0x5f1f: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x5020: +case 0x5021: +case 0x5022: +case 0x5023: +case 0x5024: +case 0x5025: +case 0x5026: +case 0x5027: +case 0x5220: +case 0x5221: +case 0x5222: +case 0x5223: +case 0x5224: +case 0x5225: +case 0x5226: +case 0x5227: +case 0x5420: +case 0x5421: +case 0x5422: +case 0x5423: +case 0x5424: +case 0x5425: +case 0x5426: +case 0x5427: +case 0x5620: +case 0x5621: +case 0x5622: +case 0x5623: +case 0x5624: +case 0x5625: +case 0x5626: +case 0x5627: +case 0x5820: +case 0x5821: +case 0x5822: +case 0x5823: +case 0x5824: +case 0x5825: +case 0x5826: +case 0x5827: +case 0x5a20: +case 0x5a21: +case 0x5a22: +case 0x5a23: +case 0x5a24: +case 0x5a25: +case 0x5a26: +case 0x5a27: +case 0x5c20: +case 0x5c21: +case 0x5c22: +case 0x5c23: +case 0x5c24: +case 0x5c25: +case 0x5c26: +case 0x5c27: +case 0x5e20: +case 0x5e21: +case 0x5e22: +case 0x5e23: +case 0x5e24: +case 0x5e25: +case 0x5e26: +case 0x5e27: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5120: +case 0x5121: +case 0x5122: +case 0x5123: +case 0x5124: +case 0x5125: +case 0x5126: +case 0x5127: +case 0x5320: +case 0x5321: +case 0x5322: +case 0x5323: +case 0x5324: +case 0x5325: +case 0x5326: +case 0x5327: +case 0x5520: +case 0x5521: +case 0x5522: +case 0x5523: +case 0x5524: +case 0x5525: +case 0x5526: +case 0x5527: +case 0x5720: +case 0x5721: +case 0x5722: +case 0x5723: +case 0x5724: +case 0x5725: +case 0x5726: +case 0x5727: +case 0x5920: +case 0x5921: +case 0x5922: +case 0x5923: +case 0x5924: +case 0x5925: +case 0x5926: +case 0x5927: +case 0x5b20: +case 0x5b21: +case 0x5b22: +case 0x5b23: +case 0x5b24: +case 0x5b25: +case 0x5b26: +case 0x5b27: +case 0x5d20: +case 0x5d21: +case 0x5d22: +case 0x5d23: +case 0x5d24: +case 0x5d25: +case 0x5d26: +case 0x5d27: +case 0x5f20: +case 0x5f21: +case 0x5f22: +case 0x5f23: +case 0x5f24: +case 0x5f25: +case 0x5f26: +case 0x5f27: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x5000: +case 0x5001: +case 0x5002: +case 0x5003: +case 0x5004: +case 0x5005: +case 0x5006: +case 0x5007: +case 0x5200: +case 0x5201: +case 0x5202: +case 0x5203: +case 0x5204: +case 0x5205: +case 0x5206: +case 0x5207: +case 0x5400: +case 0x5401: +case 0x5402: +case 0x5403: +case 0x5404: +case 0x5405: +case 0x5406: +case 0x5407: +case 0x5600: +case 0x5601: +case 0x5602: +case 0x5603: +case 0x5604: +case 0x5605: +case 0x5606: +case 0x5607: +case 0x5800: +case 0x5801: +case 0x5802: +case 0x5803: +case 0x5804: +case 0x5805: +case 0x5806: +case 0x5807: +case 0x5a00: +case 0x5a01: +case 0x5a02: +case 0x5a03: +case 0x5a04: +case 0x5a05: +case 0x5a06: +case 0x5a07: +case 0x5c00: +case 0x5c01: +case 0x5c02: +case 0x5c03: +case 0x5c04: +case 0x5c05: +case 0x5c06: +case 0x5c07: +case 0x5e00: +case 0x5e01: +case 0x5e02: +case 0x5e03: +case 0x5e04: +case 0x5e05: +case 0x5e06: +case 0x5e07: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); ADD(src, dst); + } + break; + +case 0x5100: +case 0x5101: +case 0x5102: +case 0x5103: +case 0x5104: +case 0x5105: +case 0x5106: +case 0x5107: +case 0x5300: +case 0x5301: +case 0x5302: +case 0x5303: +case 0x5304: +case 0x5305: +case 0x5306: +case 0x5307: +case 0x5500: +case 0x5501: +case 0x5502: +case 0x5503: +case 0x5504: +case 0x5505: +case 0x5506: +case 0x5507: +case 0x5700: +case 0x5701: +case 0x5702: +case 0x5703: +case 0x5704: +case 0x5705: +case 0x5706: +case 0x5707: +case 0x5900: +case 0x5901: +case 0x5902: +case 0x5903: +case 0x5904: +case 0x5905: +case 0x5906: +case 0x5907: +case 0x5b00: +case 0x5b01: +case 0x5b02: +case 0x5b03: +case 0x5b04: +case 0x5b05: +case 0x5b06: +case 0x5b07: +case 0x5d00: +case 0x5d01: +case 0x5d02: +case 0x5d03: +case 0x5d04: +case 0x5d05: +case 0x5d06: +case 0x5d07: +case 0x5f00: +case 0x5f01: +case 0x5f02: +case 0x5f03: +case 0x5f04: +case 0x5f05: +case 0x5f06: +case 0x5f07: + { + HAM src(this, instr_b11_b9 ? instr_b11_b9 : 8); HAM dst(this, instr_b2_b0); SUB(src, dst); + } + break; + +case 0x013c: +case 0x033c: +case 0x053c: +case 0x073c: +case 0x093c: +case 0x0b3c: +case 0x0d3c: +case 0x0f3c: + { + HAM targ(this); BTST(targ, D[instr_b11_b9]); + } + break; + +case 0x13fa: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x11fa: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x10ba: +case 0x12ba: +case 0x14ba: +case 0x16ba: +case 0x18ba: +case 0x1aba: +case 0x1cba: +case 0x1eba: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x117a: +case 0x137a: +case 0x157a: +case 0x177a: +case 0x197a: +case 0x1b7a: +case 0x1d7a: +case 0x1f7a: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x11ba: +case 0x13ba: +case 0x15ba: +case 0x17ba: +case 0x19ba: +case 0x1bba: +case 0x1dba: +case 0x1fba: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x10fa: +case 0x12fa: +case 0x14fa: +case 0x16fa: +case 0x18fa: +case 0x1afa: +case 0x1cfa: +case 0x1efa: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x113a: +case 0x133a: +case 0x153a: +case 0x173a: +case 0x193a: +case 0x1b3a: +case 0x1d3a: +case 0x1f3a: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd03a: +case 0xd23a: +case 0xd43a: +case 0xd63a: +case 0xd83a: +case 0xda3a: +case 0xdc3a: +case 0xde3a: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc03a: +case 0xc23a: +case 0xc43a: +case 0xc63a: +case 0xc83a: +case 0xca3a: +case 0xcc3a: +case 0xce3a: + { + HAM src(this); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb03a: +case 0xb23a: +case 0xb43a: +case 0xb63a: +case 0xb83a: +case 0xba3a: +case 0xbc3a: +case 0xbe3a: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x103a: +case 0x123a: +case 0x143a: +case 0x163a: +case 0x183a: +case 0x1a3a: +case 0x1c3a: +case 0x1e3a: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x803a: +case 0x823a: +case 0x843a: +case 0x863a: +case 0x883a: +case 0x8a3a: +case 0x8c3a: +case 0x8e3a: + { + HAM src(this); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x903a: +case 0x923a: +case 0x943a: +case 0x963a: +case 0x983a: +case 0x9a3a: +case 0x9c3a: +case 0x9e3a: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x013a: +case 0x033a: +case 0x053a: +case 0x073a: +case 0x093a: +case 0x0b3a: +case 0x0d3a: +case 0x0f3a: + { + HAM targ(this); BTST(targ, D[instr_b11_b9]); + } + break; + +case 0x13fb: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x11fb: + { + HAM src(this); HAM dst(this); MOVE(src, dst); + } + break; + +case 0x10bb: +case 0x12bb: +case 0x14bb: +case 0x16bb: +case 0x18bb: +case 0x1abb: +case 0x1cbb: +case 0x1ebb: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x117b: +case 0x137b: +case 0x157b: +case 0x177b: +case 0x197b: +case 0x1b7b: +case 0x1d7b: +case 0x1f7b: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x11bb: +case 0x13bb: +case 0x15bb: +case 0x17bb: +case 0x19bb: +case 0x1bbb: +case 0x1dbb: +case 0x1fbb: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x10fb: +case 0x12fb: +case 0x14fb: +case 0x16fb: +case 0x18fb: +case 0x1afb: +case 0x1cfb: +case 0x1efb: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x113b: +case 0x133b: +case 0x153b: +case 0x173b: +case 0x193b: +case 0x1b3b: +case 0x1d3b: +case 0x1f3b: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0xd03b: +case 0xd23b: +case 0xd43b: +case 0xd63b: +case 0xd83b: +case 0xda3b: +case 0xdc3b: +case 0xde3b: + { + HAM src(this); HAM dst(this, instr_b11_b9); ADD(src, dst); + } + break; + +case 0xc03b: +case 0xc23b: +case 0xc43b: +case 0xc63b: +case 0xc83b: +case 0xca3b: +case 0xcc3b: +case 0xce3b: + { + HAM src(this); HAM dst(this, instr_b11_b9); AND(src, dst); + } + break; + +case 0xb03b: +case 0xb23b: +case 0xb43b: +case 0xb63b: +case 0xb83b: +case 0xba3b: +case 0xbc3b: +case 0xbe3b: + { + HAM src(this); HAM dst(this, instr_b11_b9); CMP(src, dst); + } + break; + +case 0x103b: +case 0x123b: +case 0x143b: +case 0x163b: +case 0x183b: +case 0x1a3b: +case 0x1c3b: +case 0x1e3b: + { + HAM src(this); HAM dst(this, instr_b11_b9); MOVE(src, dst); + } + break; + +case 0x803b: +case 0x823b: +case 0x843b: +case 0x863b: +case 0x883b: +case 0x8a3b: +case 0x8c3b: +case 0x8e3b: + { + HAM src(this); HAM dst(this, instr_b11_b9); OR(src, dst); + } + break; + +case 0x903b: +case 0x923b: +case 0x943b: +case 0x963b: +case 0x983b: +case 0x9a3b: +case 0x9c3b: +case 0x9e3b: + { + HAM src(this); HAM dst(this, instr_b11_b9); SUB(src, dst); + } + break; + +case 0x013b: +case 0x033b: +case 0x053b: +case 0x073b: +case 0x093b: +case 0x0b3b: +case 0x0d3b: +case 0x0f3b: + { + HAM targ(this); BTST(targ, D[instr_b11_b9]); + } + break; + +case 0xa000: +case 0xa001: +case 0xa002: +case 0xa003: +case 0xa004: +case 0xa005: +case 0xa006: +case 0xa007: +case 0xa008: +case 0xa009: +case 0xa00a: +case 0xa00b: +case 0xa00c: +case 0xa00d: +case 0xa00e: +case 0xa00f: +case 0xa010: +case 0xa011: +case 0xa012: +case 0xa013: +case 0xa014: +case 0xa015: +case 0xa016: +case 0xa017: +case 0xa018: +case 0xa019: +case 0xa01a: +case 0xa01b: +case 0xa01c: +case 0xa01d: +case 0xa01e: +case 0xa01f: +case 0xa020: +case 0xa021: +case 0xa022: +case 0xa023: +case 0xa024: +case 0xa025: +case 0xa026: +case 0xa027: +case 0xa028: +case 0xa029: +case 0xa02a: +case 0xa02b: +case 0xa02c: +case 0xa02d: +case 0xa02e: +case 0xa02f: +case 0xa030: +case 0xa031: +case 0xa032: +case 0xa033: +case 0xa034: +case 0xa035: +case 0xa036: +case 0xa037: +case 0xa038: +case 0xa039: +case 0xa03a: +case 0xa03b: +case 0xa03c: +case 0xa03d: +case 0xa03e: +case 0xa03f: +case 0xa040: +case 0xa041: +case 0xa042: +case 0xa043: +case 0xa044: +case 0xa045: +case 0xa046: +case 0xa047: +case 0xa048: +case 0xa049: +case 0xa04a: +case 0xa04b: +case 0xa04c: +case 0xa04d: +case 0xa04e: +case 0xa04f: +case 0xa050: +case 0xa051: +case 0xa052: +case 0xa053: +case 0xa054: +case 0xa055: +case 0xa056: +case 0xa057: +case 0xa058: +case 0xa059: +case 0xa05a: +case 0xa05b: +case 0xa05c: +case 0xa05d: +case 0xa05e: +case 0xa05f: +case 0xa060: +case 0xa061: +case 0xa062: +case 0xa063: +case 0xa064: +case 0xa065: +case 0xa066: +case 0xa067: +case 0xa068: +case 0xa069: +case 0xa06a: +case 0xa06b: +case 0xa06c: +case 0xa06d: +case 0xa06e: +case 0xa06f: +case 0xa070: +case 0xa071: +case 0xa072: +case 0xa073: +case 0xa074: +case 0xa075: +case 0xa076: +case 0xa077: +case 0xa078: +case 0xa079: +case 0xa07a: +case 0xa07b: +case 0xa07c: +case 0xa07d: +case 0xa07e: +case 0xa07f: +case 0xa080: +case 0xa081: +case 0xa082: +case 0xa083: +case 0xa084: +case 0xa085: +case 0xa086: +case 0xa087: +case 0xa088: +case 0xa089: +case 0xa08a: +case 0xa08b: +case 0xa08c: +case 0xa08d: +case 0xa08e: +case 0xa08f: +case 0xa090: +case 0xa091: +case 0xa092: +case 0xa093: +case 0xa094: +case 0xa095: +case 0xa096: +case 0xa097: +case 0xa098: +case 0xa099: +case 0xa09a: +case 0xa09b: +case 0xa09c: +case 0xa09d: +case 0xa09e: +case 0xa09f: +case 0xa0a0: +case 0xa0a1: +case 0xa0a2: +case 0xa0a3: +case 0xa0a4: +case 0xa0a5: +case 0xa0a6: +case 0xa0a7: +case 0xa0a8: +case 0xa0a9: +case 0xa0aa: +case 0xa0ab: +case 0xa0ac: +case 0xa0ad: +case 0xa0ae: +case 0xa0af: +case 0xa0b0: +case 0xa0b1: +case 0xa0b2: +case 0xa0b3: +case 0xa0b4: +case 0xa0b5: +case 0xa0b6: +case 0xa0b7: +case 0xa0b8: +case 0xa0b9: +case 0xa0ba: +case 0xa0bb: +case 0xa0bc: +case 0xa0bd: +case 0xa0be: +case 0xa0bf: +case 0xa0c0: +case 0xa0c1: +case 0xa0c2: +case 0xa0c3: +case 0xa0c4: +case 0xa0c5: +case 0xa0c6: +case 0xa0c7: +case 0xa0c8: +case 0xa0c9: +case 0xa0ca: +case 0xa0cb: +case 0xa0cc: +case 0xa0cd: +case 0xa0ce: +case 0xa0cf: +case 0xa0d0: +case 0xa0d1: +case 0xa0d2: +case 0xa0d3: +case 0xa0d4: +case 0xa0d5: +case 0xa0d6: +case 0xa0d7: +case 0xa0d8: +case 0xa0d9: +case 0xa0da: +case 0xa0db: +case 0xa0dc: +case 0xa0dd: +case 0xa0de: +case 0xa0df: +case 0xa0e0: +case 0xa0e1: +case 0xa0e2: +case 0xa0e3: +case 0xa0e4: +case 0xa0e5: +case 0xa0e6: +case 0xa0e7: +case 0xa0e8: +case 0xa0e9: +case 0xa0ea: +case 0xa0eb: +case 0xa0ec: +case 0xa0ed: +case 0xa0ee: +case 0xa0ef: +case 0xa0f0: +case 0xa0f1: +case 0xa0f2: +case 0xa0f3: +case 0xa0f4: +case 0xa0f5: +case 0xa0f6: +case 0xa0f7: +case 0xa0f8: +case 0xa0f9: +case 0xa0fa: +case 0xa0fb: +case 0xa0fc: +case 0xa0fd: +case 0xa0fe: +case 0xa0ff: +case 0xa100: +case 0xa101: +case 0xa102: +case 0xa103: +case 0xa104: +case 0xa105: +case 0xa106: +case 0xa107: +case 0xa108: +case 0xa109: +case 0xa10a: +case 0xa10b: +case 0xa10c: +case 0xa10d: +case 0xa10e: +case 0xa10f: +case 0xa110: +case 0xa111: +case 0xa112: +case 0xa113: +case 0xa114: +case 0xa115: +case 0xa116: +case 0xa117: +case 0xa118: +case 0xa119: +case 0xa11a: +case 0xa11b: +case 0xa11c: +case 0xa11d: +case 0xa11e: +case 0xa11f: +case 0xa120: +case 0xa121: +case 0xa122: +case 0xa123: +case 0xa124: +case 0xa125: +case 0xa126: +case 0xa127: +case 0xa128: +case 0xa129: +case 0xa12a: +case 0xa12b: +case 0xa12c: +case 0xa12d: +case 0xa12e: +case 0xa12f: +case 0xa130: +case 0xa131: +case 0xa132: +case 0xa133: +case 0xa134: +case 0xa135: +case 0xa136: +case 0xa137: +case 0xa138: +case 0xa139: +case 0xa13a: +case 0xa13b: +case 0xa13c: +case 0xa13d: +case 0xa13e: +case 0xa13f: +case 0xa140: +case 0xa141: +case 0xa142: +case 0xa143: +case 0xa144: +case 0xa145: +case 0xa146: +case 0xa147: +case 0xa148: +case 0xa149: +case 0xa14a: +case 0xa14b: +case 0xa14c: +case 0xa14d: +case 0xa14e: +case 0xa14f: +case 0xa150: +case 0xa151: +case 0xa152: +case 0xa153: +case 0xa154: +case 0xa155: +case 0xa156: +case 0xa157: +case 0xa158: +case 0xa159: +case 0xa15a: +case 0xa15b: +case 0xa15c: +case 0xa15d: +case 0xa15e: +case 0xa15f: +case 0xa160: +case 0xa161: +case 0xa162: +case 0xa163: +case 0xa164: +case 0xa165: +case 0xa166: +case 0xa167: +case 0xa168: +case 0xa169: +case 0xa16a: +case 0xa16b: +case 0xa16c: +case 0xa16d: +case 0xa16e: +case 0xa16f: +case 0xa170: +case 0xa171: +case 0xa172: +case 0xa173: +case 0xa174: +case 0xa175: +case 0xa176: +case 0xa177: +case 0xa178: +case 0xa179: +case 0xa17a: +case 0xa17b: +case 0xa17c: +case 0xa17d: +case 0xa17e: +case 0xa17f: +case 0xa180: +case 0xa181: +case 0xa182: +case 0xa183: +case 0xa184: +case 0xa185: +case 0xa186: +case 0xa187: +case 0xa188: +case 0xa189: +case 0xa18a: +case 0xa18b: +case 0xa18c: +case 0xa18d: +case 0xa18e: +case 0xa18f: +case 0xa190: +case 0xa191: +case 0xa192: +case 0xa193: +case 0xa194: +case 0xa195: +case 0xa196: +case 0xa197: +case 0xa198: +case 0xa199: +case 0xa19a: +case 0xa19b: +case 0xa19c: +case 0xa19d: +case 0xa19e: +case 0xa19f: +case 0xa1a0: +case 0xa1a1: +case 0xa1a2: +case 0xa1a3: +case 0xa1a4: +case 0xa1a5: +case 0xa1a6: +case 0xa1a7: +case 0xa1a8: +case 0xa1a9: +case 0xa1aa: +case 0xa1ab: +case 0xa1ac: +case 0xa1ad: +case 0xa1ae: +case 0xa1af: +case 0xa1b0: +case 0xa1b1: +case 0xa1b2: +case 0xa1b3: +case 0xa1b4: +case 0xa1b5: +case 0xa1b6: +case 0xa1b7: +case 0xa1b8: +case 0xa1b9: +case 0xa1ba: +case 0xa1bb: +case 0xa1bc: +case 0xa1bd: +case 0xa1be: +case 0xa1bf: +case 0xa1c0: +case 0xa1c1: +case 0xa1c2: +case 0xa1c3: +case 0xa1c4: +case 0xa1c5: +case 0xa1c6: +case 0xa1c7: +case 0xa1c8: +case 0xa1c9: +case 0xa1ca: +case 0xa1cb: +case 0xa1cc: +case 0xa1cd: +case 0xa1ce: +case 0xa1cf: +case 0xa1d0: +case 0xa1d1: +case 0xa1d2: +case 0xa1d3: +case 0xa1d4: +case 0xa1d5: +case 0xa1d6: +case 0xa1d7: +case 0xa1d8: +case 0xa1d9: +case 0xa1da: +case 0xa1db: +case 0xa1dc: +case 0xa1dd: +case 0xa1de: +case 0xa1df: +case 0xa1e0: +case 0xa1e1: +case 0xa1e2: +case 0xa1e3: +case 0xa1e4: +case 0xa1e5: +case 0xa1e6: +case 0xa1e7: +case 0xa1e8: +case 0xa1e9: +case 0xa1ea: +case 0xa1eb: +case 0xa1ec: +case 0xa1ed: +case 0xa1ee: +case 0xa1ef: +case 0xa1f0: +case 0xa1f1: +case 0xa1f2: +case 0xa1f3: +case 0xa1f4: +case 0xa1f5: +case 0xa1f6: +case 0xa1f7: +case 0xa1f8: +case 0xa1f9: +case 0xa1fa: +case 0xa1fb: +case 0xa1fc: +case 0xa1fd: +case 0xa1fe: +case 0xa1ff: +case 0xa200: +case 0xa201: +case 0xa202: +case 0xa203: +case 0xa204: +case 0xa205: +case 0xa206: +case 0xa207: +case 0xa208: +case 0xa209: +case 0xa20a: +case 0xa20b: +case 0xa20c: +case 0xa20d: +case 0xa20e: +case 0xa20f: +case 0xa210: +case 0xa211: +case 0xa212: +case 0xa213: +case 0xa214: +case 0xa215: +case 0xa216: +case 0xa217: +case 0xa218: +case 0xa219: +case 0xa21a: +case 0xa21b: +case 0xa21c: +case 0xa21d: +case 0xa21e: +case 0xa21f: +case 0xa220: +case 0xa221: +case 0xa222: +case 0xa223: +case 0xa224: +case 0xa225: +case 0xa226: +case 0xa227: +case 0xa228: +case 0xa229: +case 0xa22a: +case 0xa22b: +case 0xa22c: +case 0xa22d: +case 0xa22e: +case 0xa22f: +case 0xa230: +case 0xa231: +case 0xa232: +case 0xa233: +case 0xa234: +case 0xa235: +case 0xa236: +case 0xa237: +case 0xa238: +case 0xa239: +case 0xa23a: +case 0xa23b: +case 0xa23c: +case 0xa23d: +case 0xa23e: +case 0xa23f: +case 0xa240: +case 0xa241: +case 0xa242: +case 0xa243: +case 0xa244: +case 0xa245: +case 0xa246: +case 0xa247: +case 0xa248: +case 0xa249: +case 0xa24a: +case 0xa24b: +case 0xa24c: +case 0xa24d: +case 0xa24e: +case 0xa24f: +case 0xa250: +case 0xa251: +case 0xa252: +case 0xa253: +case 0xa254: +case 0xa255: +case 0xa256: +case 0xa257: +case 0xa258: +case 0xa259: +case 0xa25a: +case 0xa25b: +case 0xa25c: +case 0xa25d: +case 0xa25e: +case 0xa25f: +case 0xa260: +case 0xa261: +case 0xa262: +case 0xa263: +case 0xa264: +case 0xa265: +case 0xa266: +case 0xa267: +case 0xa268: +case 0xa269: +case 0xa26a: +case 0xa26b: +case 0xa26c: +case 0xa26d: +case 0xa26e: +case 0xa26f: +case 0xa270: +case 0xa271: +case 0xa272: +case 0xa273: +case 0xa274: +case 0xa275: +case 0xa276: +case 0xa277: +case 0xa278: +case 0xa279: +case 0xa27a: +case 0xa27b: +case 0xa27c: +case 0xa27d: +case 0xa27e: +case 0xa27f: +case 0xa280: +case 0xa281: +case 0xa282: +case 0xa283: +case 0xa284: +case 0xa285: +case 0xa286: +case 0xa287: +case 0xa288: +case 0xa289: +case 0xa28a: +case 0xa28b: +case 0xa28c: +case 0xa28d: +case 0xa28e: +case 0xa28f: +case 0xa290: +case 0xa291: +case 0xa292: +case 0xa293: +case 0xa294: +case 0xa295: +case 0xa296: +case 0xa297: +case 0xa298: +case 0xa299: +case 0xa29a: +case 0xa29b: +case 0xa29c: +case 0xa29d: +case 0xa29e: +case 0xa29f: +case 0xa2a0: +case 0xa2a1: +case 0xa2a2: +case 0xa2a3: +case 0xa2a4: +case 0xa2a5: +case 0xa2a6: +case 0xa2a7: +case 0xa2a8: +case 0xa2a9: +case 0xa2aa: +case 0xa2ab: +case 0xa2ac: +case 0xa2ad: +case 0xa2ae: +case 0xa2af: +case 0xa2b0: +case 0xa2b1: +case 0xa2b2: +case 0xa2b3: +case 0xa2b4: +case 0xa2b5: +case 0xa2b6: +case 0xa2b7: +case 0xa2b8: +case 0xa2b9: +case 0xa2ba: +case 0xa2bb: +case 0xa2bc: +case 0xa2bd: +case 0xa2be: +case 0xa2bf: +case 0xa2c0: +case 0xa2c1: +case 0xa2c2: +case 0xa2c3: +case 0xa2c4: +case 0xa2c5: +case 0xa2c6: +case 0xa2c7: +case 0xa2c8: +case 0xa2c9: +case 0xa2ca: +case 0xa2cb: +case 0xa2cc: +case 0xa2cd: +case 0xa2ce: +case 0xa2cf: +case 0xa2d0: +case 0xa2d1: +case 0xa2d2: +case 0xa2d3: +case 0xa2d4: +case 0xa2d5: +case 0xa2d6: +case 0xa2d7: +case 0xa2d8: +case 0xa2d9: +case 0xa2da: +case 0xa2db: +case 0xa2dc: +case 0xa2dd: +case 0xa2de: +case 0xa2df: +case 0xa2e0: +case 0xa2e1: +case 0xa2e2: +case 0xa2e3: +case 0xa2e4: +case 0xa2e5: +case 0xa2e6: +case 0xa2e7: +case 0xa2e8: +case 0xa2e9: +case 0xa2ea: +case 0xa2eb: +case 0xa2ec: +case 0xa2ed: +case 0xa2ee: +case 0xa2ef: +case 0xa2f0: +case 0xa2f1: +case 0xa2f2: +case 0xa2f3: +case 0xa2f4: +case 0xa2f5: +case 0xa2f6: +case 0xa2f7: +case 0xa2f8: +case 0xa2f9: +case 0xa2fa: +case 0xa2fb: +case 0xa2fc: +case 0xa2fd: +case 0xa2fe: +case 0xa2ff: +case 0xa300: +case 0xa301: +case 0xa302: +case 0xa303: +case 0xa304: +case 0xa305: +case 0xa306: +case 0xa307: +case 0xa308: +case 0xa309: +case 0xa30a: +case 0xa30b: +case 0xa30c: +case 0xa30d: +case 0xa30e: +case 0xa30f: +case 0xa310: +case 0xa311: +case 0xa312: +case 0xa313: +case 0xa314: +case 0xa315: +case 0xa316: +case 0xa317: +case 0xa318: +case 0xa319: +case 0xa31a: +case 0xa31b: +case 0xa31c: +case 0xa31d: +case 0xa31e: +case 0xa31f: +case 0xa320: +case 0xa321: +case 0xa322: +case 0xa323: +case 0xa324: +case 0xa325: +case 0xa326: +case 0xa327: +case 0xa328: +case 0xa329: +case 0xa32a: +case 0xa32b: +case 0xa32c: +case 0xa32d: +case 0xa32e: +case 0xa32f: +case 0xa330: +case 0xa331: +case 0xa332: +case 0xa333: +case 0xa334: +case 0xa335: +case 0xa336: +case 0xa337: +case 0xa338: +case 0xa339: +case 0xa33a: +case 0xa33b: +case 0xa33c: +case 0xa33d: +case 0xa33e: +case 0xa33f: +case 0xa340: +case 0xa341: +case 0xa342: +case 0xa343: +case 0xa344: +case 0xa345: +case 0xa346: +case 0xa347: +case 0xa348: +case 0xa349: +case 0xa34a: +case 0xa34b: +case 0xa34c: +case 0xa34d: +case 0xa34e: +case 0xa34f: +case 0xa350: +case 0xa351: +case 0xa352: +case 0xa353: +case 0xa354: +case 0xa355: +case 0xa356: +case 0xa357: +case 0xa358: +case 0xa359: +case 0xa35a: +case 0xa35b: +case 0xa35c: +case 0xa35d: +case 0xa35e: +case 0xa35f: +case 0xa360: +case 0xa361: +case 0xa362: +case 0xa363: +case 0xa364: +case 0xa365: +case 0xa366: +case 0xa367: +case 0xa368: +case 0xa369: +case 0xa36a: +case 0xa36b: +case 0xa36c: +case 0xa36d: +case 0xa36e: +case 0xa36f: +case 0xa370: +case 0xa371: +case 0xa372: +case 0xa373: +case 0xa374: +case 0xa375: +case 0xa376: +case 0xa377: +case 0xa378: +case 0xa379: +case 0xa37a: +case 0xa37b: +case 0xa37c: +case 0xa37d: +case 0xa37e: +case 0xa37f: +case 0xa380: +case 0xa381: +case 0xa382: +case 0xa383: +case 0xa384: +case 0xa385: +case 0xa386: +case 0xa387: +case 0xa388: +case 0xa389: +case 0xa38a: +case 0xa38b: +case 0xa38c: +case 0xa38d: +case 0xa38e: +case 0xa38f: +case 0xa390: +case 0xa391: +case 0xa392: +case 0xa393: +case 0xa394: +case 0xa395: +case 0xa396: +case 0xa397: +case 0xa398: +case 0xa399: +case 0xa39a: +case 0xa39b: +case 0xa39c: +case 0xa39d: +case 0xa39e: +case 0xa39f: +case 0xa3a0: +case 0xa3a1: +case 0xa3a2: +case 0xa3a3: +case 0xa3a4: +case 0xa3a5: +case 0xa3a6: +case 0xa3a7: +case 0xa3a8: +case 0xa3a9: +case 0xa3aa: +case 0xa3ab: +case 0xa3ac: +case 0xa3ad: +case 0xa3ae: +case 0xa3af: +case 0xa3b0: +case 0xa3b1: +case 0xa3b2: +case 0xa3b3: +case 0xa3b4: +case 0xa3b5: +case 0xa3b6: +case 0xa3b7: +case 0xa3b8: +case 0xa3b9: +case 0xa3ba: +case 0xa3bb: +case 0xa3bc: +case 0xa3bd: +case 0xa3be: +case 0xa3bf: +case 0xa3c0: +case 0xa3c1: +case 0xa3c2: +case 0xa3c3: +case 0xa3c4: +case 0xa3c5: +case 0xa3c6: +case 0xa3c7: +case 0xa3c8: +case 0xa3c9: +case 0xa3ca: +case 0xa3cb: +case 0xa3cc: +case 0xa3cd: +case 0xa3ce: +case 0xa3cf: +case 0xa3d0: +case 0xa3d1: +case 0xa3d2: +case 0xa3d3: +case 0xa3d4: +case 0xa3d5: +case 0xa3d6: +case 0xa3d7: +case 0xa3d8: +case 0xa3d9: +case 0xa3da: +case 0xa3db: +case 0xa3dc: +case 0xa3dd: +case 0xa3de: +case 0xa3df: +case 0xa3e0: +case 0xa3e1: +case 0xa3e2: +case 0xa3e3: +case 0xa3e4: +case 0xa3e5: +case 0xa3e6: +case 0xa3e7: +case 0xa3e8: +case 0xa3e9: +case 0xa3ea: +case 0xa3eb: +case 0xa3ec: +case 0xa3ed: +case 0xa3ee: +case 0xa3ef: +case 0xa3f0: +case 0xa3f1: +case 0xa3f2: +case 0xa3f3: +case 0xa3f4: +case 0xa3f5: +case 0xa3f6: +case 0xa3f7: +case 0xa3f8: +case 0xa3f9: +case 0xa3fa: +case 0xa3fb: +case 0xa3fc: +case 0xa3fd: +case 0xa3fe: +case 0xa3ff: +case 0xa400: +case 0xa401: +case 0xa402: +case 0xa403: +case 0xa404: +case 0xa405: +case 0xa406: +case 0xa407: +case 0xa408: +case 0xa409: +case 0xa40a: +case 0xa40b: +case 0xa40c: +case 0xa40d: +case 0xa40e: +case 0xa40f: +case 0xa410: +case 0xa411: +case 0xa412: +case 0xa413: +case 0xa414: +case 0xa415: +case 0xa416: +case 0xa417: +case 0xa418: +case 0xa419: +case 0xa41a: +case 0xa41b: +case 0xa41c: +case 0xa41d: +case 0xa41e: +case 0xa41f: +case 0xa420: +case 0xa421: +case 0xa422: +case 0xa423: +case 0xa424: +case 0xa425: +case 0xa426: +case 0xa427: +case 0xa428: +case 0xa429: +case 0xa42a: +case 0xa42b: +case 0xa42c: +case 0xa42d: +case 0xa42e: +case 0xa42f: +case 0xa430: +case 0xa431: +case 0xa432: +case 0xa433: +case 0xa434: +case 0xa435: +case 0xa436: +case 0xa437: +case 0xa438: +case 0xa439: +case 0xa43a: +case 0xa43b: +case 0xa43c: +case 0xa43d: +case 0xa43e: +case 0xa43f: +case 0xa440: +case 0xa441: +case 0xa442: +case 0xa443: +case 0xa444: +case 0xa445: +case 0xa446: +case 0xa447: +case 0xa448: +case 0xa449: +case 0xa44a: +case 0xa44b: +case 0xa44c: +case 0xa44d: +case 0xa44e: +case 0xa44f: +case 0xa450: +case 0xa451: +case 0xa452: +case 0xa453: +case 0xa454: +case 0xa455: +case 0xa456: +case 0xa457: +case 0xa458: +case 0xa459: +case 0xa45a: +case 0xa45b: +case 0xa45c: +case 0xa45d: +case 0xa45e: +case 0xa45f: +case 0xa460: +case 0xa461: +case 0xa462: +case 0xa463: +case 0xa464: +case 0xa465: +case 0xa466: +case 0xa467: +case 0xa468: +case 0xa469: +case 0xa46a: +case 0xa46b: +case 0xa46c: +case 0xa46d: +case 0xa46e: +case 0xa46f: +case 0xa470: +case 0xa471: +case 0xa472: +case 0xa473: +case 0xa474: +case 0xa475: +case 0xa476: +case 0xa477: +case 0xa478: +case 0xa479: +case 0xa47a: +case 0xa47b: +case 0xa47c: +case 0xa47d: +case 0xa47e: +case 0xa47f: +case 0xa480: +case 0xa481: +case 0xa482: +case 0xa483: +case 0xa484: +case 0xa485: +case 0xa486: +case 0xa487: +case 0xa488: +case 0xa489: +case 0xa48a: +case 0xa48b: +case 0xa48c: +case 0xa48d: +case 0xa48e: +case 0xa48f: +case 0xa490: +case 0xa491: +case 0xa492: +case 0xa493: +case 0xa494: +case 0xa495: +case 0xa496: +case 0xa497: +case 0xa498: +case 0xa499: +case 0xa49a: +case 0xa49b: +case 0xa49c: +case 0xa49d: +case 0xa49e: +case 0xa49f: +case 0xa4a0: +case 0xa4a1: +case 0xa4a2: +case 0xa4a3: +case 0xa4a4: +case 0xa4a5: +case 0xa4a6: +case 0xa4a7: +case 0xa4a8: +case 0xa4a9: +case 0xa4aa: +case 0xa4ab: +case 0xa4ac: +case 0xa4ad: +case 0xa4ae: +case 0xa4af: +case 0xa4b0: +case 0xa4b1: +case 0xa4b2: +case 0xa4b3: +case 0xa4b4: +case 0xa4b5: +case 0xa4b6: +case 0xa4b7: +case 0xa4b8: +case 0xa4b9: +case 0xa4ba: +case 0xa4bb: +case 0xa4bc: +case 0xa4bd: +case 0xa4be: +case 0xa4bf: +case 0xa4c0: +case 0xa4c1: +case 0xa4c2: +case 0xa4c3: +case 0xa4c4: +case 0xa4c5: +case 0xa4c6: +case 0xa4c7: +case 0xa4c8: +case 0xa4c9: +case 0xa4ca: +case 0xa4cb: +case 0xa4cc: +case 0xa4cd: +case 0xa4ce: +case 0xa4cf: +case 0xa4d0: +case 0xa4d1: +case 0xa4d2: +case 0xa4d3: +case 0xa4d4: +case 0xa4d5: +case 0xa4d6: +case 0xa4d7: +case 0xa4d8: +case 0xa4d9: +case 0xa4da: +case 0xa4db: +case 0xa4dc: +case 0xa4dd: +case 0xa4de: +case 0xa4df: +case 0xa4e0: +case 0xa4e1: +case 0xa4e2: +case 0xa4e3: +case 0xa4e4: +case 0xa4e5: +case 0xa4e6: +case 0xa4e7: +case 0xa4e8: +case 0xa4e9: +case 0xa4ea: +case 0xa4eb: +case 0xa4ec: +case 0xa4ed: +case 0xa4ee: +case 0xa4ef: +case 0xa4f0: +case 0xa4f1: +case 0xa4f2: +case 0xa4f3: +case 0xa4f4: +case 0xa4f5: +case 0xa4f6: +case 0xa4f7: +case 0xa4f8: +case 0xa4f9: +case 0xa4fa: +case 0xa4fb: +case 0xa4fc: +case 0xa4fd: +case 0xa4fe: +case 0xa4ff: +case 0xa500: +case 0xa501: +case 0xa502: +case 0xa503: +case 0xa504: +case 0xa505: +case 0xa506: +case 0xa507: +case 0xa508: +case 0xa509: +case 0xa50a: +case 0xa50b: +case 0xa50c: +case 0xa50d: +case 0xa50e: +case 0xa50f: +case 0xa510: +case 0xa511: +case 0xa512: +case 0xa513: +case 0xa514: +case 0xa515: +case 0xa516: +case 0xa517: +case 0xa518: +case 0xa519: +case 0xa51a: +case 0xa51b: +case 0xa51c: +case 0xa51d: +case 0xa51e: +case 0xa51f: +case 0xa520: +case 0xa521: +case 0xa522: +case 0xa523: +case 0xa524: +case 0xa525: +case 0xa526: +case 0xa527: +case 0xa528: +case 0xa529: +case 0xa52a: +case 0xa52b: +case 0xa52c: +case 0xa52d: +case 0xa52e: +case 0xa52f: +case 0xa530: +case 0xa531: +case 0xa532: +case 0xa533: +case 0xa534: +case 0xa535: +case 0xa536: +case 0xa537: +case 0xa538: +case 0xa539: +case 0xa53a: +case 0xa53b: +case 0xa53c: +case 0xa53d: +case 0xa53e: +case 0xa53f: +case 0xa540: +case 0xa541: +case 0xa542: +case 0xa543: +case 0xa544: +case 0xa545: +case 0xa546: +case 0xa547: +case 0xa548: +case 0xa549: +case 0xa54a: +case 0xa54b: +case 0xa54c: +case 0xa54d: +case 0xa54e: +case 0xa54f: +case 0xa550: +case 0xa551: +case 0xa552: +case 0xa553: +case 0xa554: +case 0xa555: +case 0xa556: +case 0xa557: +case 0xa558: +case 0xa559: +case 0xa55a: +case 0xa55b: +case 0xa55c: +case 0xa55d: +case 0xa55e: +case 0xa55f: +case 0xa560: +case 0xa561: +case 0xa562: +case 0xa563: +case 0xa564: +case 0xa565: +case 0xa566: +case 0xa567: +case 0xa568: +case 0xa569: +case 0xa56a: +case 0xa56b: +case 0xa56c: +case 0xa56d: +case 0xa56e: +case 0xa56f: +case 0xa570: +case 0xa571: +case 0xa572: +case 0xa573: +case 0xa574: +case 0xa575: +case 0xa576: +case 0xa577: +case 0xa578: +case 0xa579: +case 0xa57a: +case 0xa57b: +case 0xa57c: +case 0xa57d: +case 0xa57e: +case 0xa57f: +case 0xa580: +case 0xa581: +case 0xa582: +case 0xa583: +case 0xa584: +case 0xa585: +case 0xa586: +case 0xa587: +case 0xa588: +case 0xa589: +case 0xa58a: +case 0xa58b: +case 0xa58c: +case 0xa58d: +case 0xa58e: +case 0xa58f: +case 0xa590: +case 0xa591: +case 0xa592: +case 0xa593: +case 0xa594: +case 0xa595: +case 0xa596: +case 0xa597: +case 0xa598: +case 0xa599: +case 0xa59a: +case 0xa59b: +case 0xa59c: +case 0xa59d: +case 0xa59e: +case 0xa59f: +case 0xa5a0: +case 0xa5a1: +case 0xa5a2: +case 0xa5a3: +case 0xa5a4: +case 0xa5a5: +case 0xa5a6: +case 0xa5a7: +case 0xa5a8: +case 0xa5a9: +case 0xa5aa: +case 0xa5ab: +case 0xa5ac: +case 0xa5ad: +case 0xa5ae: +case 0xa5af: +case 0xa5b0: +case 0xa5b1: +case 0xa5b2: +case 0xa5b3: +case 0xa5b4: +case 0xa5b5: +case 0xa5b6: +case 0xa5b7: +case 0xa5b8: +case 0xa5b9: +case 0xa5ba: +case 0xa5bb: +case 0xa5bc: +case 0xa5bd: +case 0xa5be: +case 0xa5bf: +case 0xa5c0: +case 0xa5c1: +case 0xa5c2: +case 0xa5c3: +case 0xa5c4: +case 0xa5c5: +case 0xa5c6: +case 0xa5c7: +case 0xa5c8: +case 0xa5c9: +case 0xa5ca: +case 0xa5cb: +case 0xa5cc: +case 0xa5cd: +case 0xa5ce: +case 0xa5cf: +case 0xa5d0: +case 0xa5d1: +case 0xa5d2: +case 0xa5d3: +case 0xa5d4: +case 0xa5d5: +case 0xa5d6: +case 0xa5d7: +case 0xa5d8: +case 0xa5d9: +case 0xa5da: +case 0xa5db: +case 0xa5dc: +case 0xa5dd: +case 0xa5de: +case 0xa5df: +case 0xa5e0: +case 0xa5e1: +case 0xa5e2: +case 0xa5e3: +case 0xa5e4: +case 0xa5e5: +case 0xa5e6: +case 0xa5e7: +case 0xa5e8: +case 0xa5e9: +case 0xa5ea: +case 0xa5eb: +case 0xa5ec: +case 0xa5ed: +case 0xa5ee: +case 0xa5ef: +case 0xa5f0: +case 0xa5f1: +case 0xa5f2: +case 0xa5f3: +case 0xa5f4: +case 0xa5f5: +case 0xa5f6: +case 0xa5f7: +case 0xa5f8: +case 0xa5f9: +case 0xa5fa: +case 0xa5fb: +case 0xa5fc: +case 0xa5fd: +case 0xa5fe: +case 0xa5ff: +case 0xa600: +case 0xa601: +case 0xa602: +case 0xa603: +case 0xa604: +case 0xa605: +case 0xa606: +case 0xa607: +case 0xa608: +case 0xa609: +case 0xa60a: +case 0xa60b: +case 0xa60c: +case 0xa60d: +case 0xa60e: +case 0xa60f: +case 0xa610: +case 0xa611: +case 0xa612: +case 0xa613: +case 0xa614: +case 0xa615: +case 0xa616: +case 0xa617: +case 0xa618: +case 0xa619: +case 0xa61a: +case 0xa61b: +case 0xa61c: +case 0xa61d: +case 0xa61e: +case 0xa61f: +case 0xa620: +case 0xa621: +case 0xa622: +case 0xa623: +case 0xa624: +case 0xa625: +case 0xa626: +case 0xa627: +case 0xa628: +case 0xa629: +case 0xa62a: +case 0xa62b: +case 0xa62c: +case 0xa62d: +case 0xa62e: +case 0xa62f: +case 0xa630: +case 0xa631: +case 0xa632: +case 0xa633: +case 0xa634: +case 0xa635: +case 0xa636: +case 0xa637: +case 0xa638: +case 0xa639: +case 0xa63a: +case 0xa63b: +case 0xa63c: +case 0xa63d: +case 0xa63e: +case 0xa63f: +case 0xa640: +case 0xa641: +case 0xa642: +case 0xa643: +case 0xa644: +case 0xa645: +case 0xa646: +case 0xa647: +case 0xa648: +case 0xa649: +case 0xa64a: +case 0xa64b: +case 0xa64c: +case 0xa64d: +case 0xa64e: +case 0xa64f: +case 0xa650: +case 0xa651: +case 0xa652: +case 0xa653: +case 0xa654: +case 0xa655: +case 0xa656: +case 0xa657: +case 0xa658: +case 0xa659: +case 0xa65a: +case 0xa65b: +case 0xa65c: +case 0xa65d: +case 0xa65e: +case 0xa65f: +case 0xa660: +case 0xa661: +case 0xa662: +case 0xa663: +case 0xa664: +case 0xa665: +case 0xa666: +case 0xa667: +case 0xa668: +case 0xa669: +case 0xa66a: +case 0xa66b: +case 0xa66c: +case 0xa66d: +case 0xa66e: +case 0xa66f: +case 0xa670: +case 0xa671: +case 0xa672: +case 0xa673: +case 0xa674: +case 0xa675: +case 0xa676: +case 0xa677: +case 0xa678: +case 0xa679: +case 0xa67a: +case 0xa67b: +case 0xa67c: +case 0xa67d: +case 0xa67e: +case 0xa67f: +case 0xa680: +case 0xa681: +case 0xa682: +case 0xa683: +case 0xa684: +case 0xa685: +case 0xa686: +case 0xa687: +case 0xa688: +case 0xa689: +case 0xa68a: +case 0xa68b: +case 0xa68c: +case 0xa68d: +case 0xa68e: +case 0xa68f: +case 0xa690: +case 0xa691: +case 0xa692: +case 0xa693: +case 0xa694: +case 0xa695: +case 0xa696: +case 0xa697: +case 0xa698: +case 0xa699: +case 0xa69a: +case 0xa69b: +case 0xa69c: +case 0xa69d: +case 0xa69e: +case 0xa69f: +case 0xa6a0: +case 0xa6a1: +case 0xa6a2: +case 0xa6a3: +case 0xa6a4: +case 0xa6a5: +case 0xa6a6: +case 0xa6a7: +case 0xa6a8: +case 0xa6a9: +case 0xa6aa: +case 0xa6ab: +case 0xa6ac: +case 0xa6ad: +case 0xa6ae: +case 0xa6af: +case 0xa6b0: +case 0xa6b1: +case 0xa6b2: +case 0xa6b3: +case 0xa6b4: +case 0xa6b5: +case 0xa6b6: +case 0xa6b7: +case 0xa6b8: +case 0xa6b9: +case 0xa6ba: +case 0xa6bb: +case 0xa6bc: +case 0xa6bd: +case 0xa6be: +case 0xa6bf: +case 0xa6c0: +case 0xa6c1: +case 0xa6c2: +case 0xa6c3: +case 0xa6c4: +case 0xa6c5: +case 0xa6c6: +case 0xa6c7: +case 0xa6c8: +case 0xa6c9: +case 0xa6ca: +case 0xa6cb: +case 0xa6cc: +case 0xa6cd: +case 0xa6ce: +case 0xa6cf: +case 0xa6d0: +case 0xa6d1: +case 0xa6d2: +case 0xa6d3: +case 0xa6d4: +case 0xa6d5: +case 0xa6d6: +case 0xa6d7: +case 0xa6d8: +case 0xa6d9: +case 0xa6da: +case 0xa6db: +case 0xa6dc: +case 0xa6dd: +case 0xa6de: +case 0xa6df: +case 0xa6e0: +case 0xa6e1: +case 0xa6e2: +case 0xa6e3: +case 0xa6e4: +case 0xa6e5: +case 0xa6e6: +case 0xa6e7: +case 0xa6e8: +case 0xa6e9: +case 0xa6ea: +case 0xa6eb: +case 0xa6ec: +case 0xa6ed: +case 0xa6ee: +case 0xa6ef: +case 0xa6f0: +case 0xa6f1: +case 0xa6f2: +case 0xa6f3: +case 0xa6f4: +case 0xa6f5: +case 0xa6f6: +case 0xa6f7: +case 0xa6f8: +case 0xa6f9: +case 0xa6fa: +case 0xa6fb: +case 0xa6fc: +case 0xa6fd: +case 0xa6fe: +case 0xa6ff: +case 0xa700: +case 0xa701: +case 0xa702: +case 0xa703: +case 0xa704: +case 0xa705: +case 0xa706: +case 0xa707: +case 0xa708: +case 0xa709: +case 0xa70a: +case 0xa70b: +case 0xa70c: +case 0xa70d: +case 0xa70e: +case 0xa70f: +case 0xa710: +case 0xa711: +case 0xa712: +case 0xa713: +case 0xa714: +case 0xa715: +case 0xa716: +case 0xa717: +case 0xa718: +case 0xa719: +case 0xa71a: +case 0xa71b: +case 0xa71c: +case 0xa71d: +case 0xa71e: +case 0xa71f: +case 0xa720: +case 0xa721: +case 0xa722: +case 0xa723: +case 0xa724: +case 0xa725: +case 0xa726: +case 0xa727: +case 0xa728: +case 0xa729: +case 0xa72a: +case 0xa72b: +case 0xa72c: +case 0xa72d: +case 0xa72e: +case 0xa72f: +case 0xa730: +case 0xa731: +case 0xa732: +case 0xa733: +case 0xa734: +case 0xa735: +case 0xa736: +case 0xa737: +case 0xa738: +case 0xa739: +case 0xa73a: +case 0xa73b: +case 0xa73c: +case 0xa73d: +case 0xa73e: +case 0xa73f: +case 0xa740: +case 0xa741: +case 0xa742: +case 0xa743: +case 0xa744: +case 0xa745: +case 0xa746: +case 0xa747: +case 0xa748: +case 0xa749: +case 0xa74a: +case 0xa74b: +case 0xa74c: +case 0xa74d: +case 0xa74e: +case 0xa74f: +case 0xa750: +case 0xa751: +case 0xa752: +case 0xa753: +case 0xa754: +case 0xa755: +case 0xa756: +case 0xa757: +case 0xa758: +case 0xa759: +case 0xa75a: +case 0xa75b: +case 0xa75c: +case 0xa75d: +case 0xa75e: +case 0xa75f: +case 0xa760: +case 0xa761: +case 0xa762: +case 0xa763: +case 0xa764: +case 0xa765: +case 0xa766: +case 0xa767: +case 0xa768: +case 0xa769: +case 0xa76a: +case 0xa76b: +case 0xa76c: +case 0xa76d: +case 0xa76e: +case 0xa76f: +case 0xa770: +case 0xa771: +case 0xa772: +case 0xa773: +case 0xa774: +case 0xa775: +case 0xa776: +case 0xa777: +case 0xa778: +case 0xa779: +case 0xa77a: +case 0xa77b: +case 0xa77c: +case 0xa77d: +case 0xa77e: +case 0xa77f: +case 0xa780: +case 0xa781: +case 0xa782: +case 0xa783: +case 0xa784: +case 0xa785: +case 0xa786: +case 0xa787: +case 0xa788: +case 0xa789: +case 0xa78a: +case 0xa78b: +case 0xa78c: +case 0xa78d: +case 0xa78e: +case 0xa78f: +case 0xa790: +case 0xa791: +case 0xa792: +case 0xa793: +case 0xa794: +case 0xa795: +case 0xa796: +case 0xa797: +case 0xa798: +case 0xa799: +case 0xa79a: +case 0xa79b: +case 0xa79c: +case 0xa79d: +case 0xa79e: +case 0xa79f: +case 0xa7a0: +case 0xa7a1: +case 0xa7a2: +case 0xa7a3: +case 0xa7a4: +case 0xa7a5: +case 0xa7a6: +case 0xa7a7: +case 0xa7a8: +case 0xa7a9: +case 0xa7aa: +case 0xa7ab: +case 0xa7ac: +case 0xa7ad: +case 0xa7ae: +case 0xa7af: +case 0xa7b0: +case 0xa7b1: +case 0xa7b2: +case 0xa7b3: +case 0xa7b4: +case 0xa7b5: +case 0xa7b6: +case 0xa7b7: +case 0xa7b8: +case 0xa7b9: +case 0xa7ba: +case 0xa7bb: +case 0xa7bc: +case 0xa7bd: +case 0xa7be: +case 0xa7bf: +case 0xa7c0: +case 0xa7c1: +case 0xa7c2: +case 0xa7c3: +case 0xa7c4: +case 0xa7c5: +case 0xa7c6: +case 0xa7c7: +case 0xa7c8: +case 0xa7c9: +case 0xa7ca: +case 0xa7cb: +case 0xa7cc: +case 0xa7cd: +case 0xa7ce: +case 0xa7cf: +case 0xa7d0: +case 0xa7d1: +case 0xa7d2: +case 0xa7d3: +case 0xa7d4: +case 0xa7d5: +case 0xa7d6: +case 0xa7d7: +case 0xa7d8: +case 0xa7d9: +case 0xa7da: +case 0xa7db: +case 0xa7dc: +case 0xa7dd: +case 0xa7de: +case 0xa7df: +case 0xa7e0: +case 0xa7e1: +case 0xa7e2: +case 0xa7e3: +case 0xa7e4: +case 0xa7e5: +case 0xa7e6: +case 0xa7e7: +case 0xa7e8: +case 0xa7e9: +case 0xa7ea: +case 0xa7eb: +case 0xa7ec: +case 0xa7ed: +case 0xa7ee: +case 0xa7ef: +case 0xa7f0: +case 0xa7f1: +case 0xa7f2: +case 0xa7f3: +case 0xa7f4: +case 0xa7f5: +case 0xa7f6: +case 0xa7f7: +case 0xa7f8: +case 0xa7f9: +case 0xa7fa: +case 0xa7fb: +case 0xa7fc: +case 0xa7fd: +case 0xa7fe: +case 0xa7ff: +case 0xa800: +case 0xa801: +case 0xa802: +case 0xa803: +case 0xa804: +case 0xa805: +case 0xa806: +case 0xa807: +case 0xa808: +case 0xa809: +case 0xa80a: +case 0xa80b: +case 0xa80c: +case 0xa80d: +case 0xa80e: +case 0xa80f: +case 0xa810: +case 0xa811: +case 0xa812: +case 0xa813: +case 0xa814: +case 0xa815: +case 0xa816: +case 0xa817: +case 0xa818: +case 0xa819: +case 0xa81a: +case 0xa81b: +case 0xa81c: +case 0xa81d: +case 0xa81e: +case 0xa81f: +case 0xa820: +case 0xa821: +case 0xa822: +case 0xa823: +case 0xa824: +case 0xa825: +case 0xa826: +case 0xa827: +case 0xa828: +case 0xa829: +case 0xa82a: +case 0xa82b: +case 0xa82c: +case 0xa82d: +case 0xa82e: +case 0xa82f: +case 0xa830: +case 0xa831: +case 0xa832: +case 0xa833: +case 0xa834: +case 0xa835: +case 0xa836: +case 0xa837: +case 0xa838: +case 0xa839: +case 0xa83a: +case 0xa83b: +case 0xa83c: +case 0xa83d: +case 0xa83e: +case 0xa83f: +case 0xa840: +case 0xa841: +case 0xa842: +case 0xa843: +case 0xa844: +case 0xa845: +case 0xa846: +case 0xa847: +case 0xa848: +case 0xa849: +case 0xa84a: +case 0xa84b: +case 0xa84c: +case 0xa84d: +case 0xa84e: +case 0xa84f: +case 0xa850: +case 0xa851: +case 0xa852: +case 0xa853: +case 0xa854: +case 0xa855: +case 0xa856: +case 0xa857: +case 0xa858: +case 0xa859: +case 0xa85a: +case 0xa85b: +case 0xa85c: +case 0xa85d: +case 0xa85e: +case 0xa85f: +case 0xa860: +case 0xa861: +case 0xa862: +case 0xa863: +case 0xa864: +case 0xa865: +case 0xa866: +case 0xa867: +case 0xa868: +case 0xa869: +case 0xa86a: +case 0xa86b: +case 0xa86c: +case 0xa86d: +case 0xa86e: +case 0xa86f: +case 0xa870: +case 0xa871: +case 0xa872: +case 0xa873: +case 0xa874: +case 0xa875: +case 0xa876: +case 0xa877: +case 0xa878: +case 0xa879: +case 0xa87a: +case 0xa87b: +case 0xa87c: +case 0xa87d: +case 0xa87e: +case 0xa87f: +case 0xa880: +case 0xa881: +case 0xa882: +case 0xa883: +case 0xa884: +case 0xa885: +case 0xa886: +case 0xa887: +case 0xa888: +case 0xa889: +case 0xa88a: +case 0xa88b: +case 0xa88c: +case 0xa88d: +case 0xa88e: +case 0xa88f: +case 0xa890: +case 0xa891: +case 0xa892: +case 0xa893: +case 0xa894: +case 0xa895: +case 0xa896: +case 0xa897: +case 0xa898: +case 0xa899: +case 0xa89a: +case 0xa89b: +case 0xa89c: +case 0xa89d: +case 0xa89e: +case 0xa89f: +case 0xa8a0: +case 0xa8a1: +case 0xa8a2: +case 0xa8a3: +case 0xa8a4: +case 0xa8a5: +case 0xa8a6: +case 0xa8a7: +case 0xa8a8: +case 0xa8a9: +case 0xa8aa: +case 0xa8ab: +case 0xa8ac: +case 0xa8ad: +case 0xa8ae: +case 0xa8af: +case 0xa8b0: +case 0xa8b1: +case 0xa8b2: +case 0xa8b3: +case 0xa8b4: +case 0xa8b5: +case 0xa8b6: +case 0xa8b7: +case 0xa8b8: +case 0xa8b9: +case 0xa8ba: +case 0xa8bb: +case 0xa8bc: +case 0xa8bd: +case 0xa8be: +case 0xa8bf: +case 0xa8c0: +case 0xa8c1: +case 0xa8c2: +case 0xa8c3: +case 0xa8c4: +case 0xa8c5: +case 0xa8c6: +case 0xa8c7: +case 0xa8c8: +case 0xa8c9: +case 0xa8ca: +case 0xa8cb: +case 0xa8cc: +case 0xa8cd: +case 0xa8ce: +case 0xa8cf: +case 0xa8d0: +case 0xa8d1: +case 0xa8d2: +case 0xa8d3: +case 0xa8d4: +case 0xa8d5: +case 0xa8d6: +case 0xa8d7: +case 0xa8d8: +case 0xa8d9: +case 0xa8da: +case 0xa8db: +case 0xa8dc: +case 0xa8dd: +case 0xa8de: +case 0xa8df: +case 0xa8e0: +case 0xa8e1: +case 0xa8e2: +case 0xa8e3: +case 0xa8e4: +case 0xa8e5: +case 0xa8e6: +case 0xa8e7: +case 0xa8e8: +case 0xa8e9: +case 0xa8ea: +case 0xa8eb: +case 0xa8ec: +case 0xa8ed: +case 0xa8ee: +case 0xa8ef: +case 0xa8f0: +case 0xa8f1: +case 0xa8f2: +case 0xa8f3: +case 0xa8f4: +case 0xa8f5: +case 0xa8f6: +case 0xa8f7: +case 0xa8f8: +case 0xa8f9: +case 0xa8fa: +case 0xa8fb: +case 0xa8fc: +case 0xa8fd: +case 0xa8fe: +case 0xa8ff: +case 0xa900: +case 0xa901: +case 0xa902: +case 0xa903: +case 0xa904: +case 0xa905: +case 0xa906: +case 0xa907: +case 0xa908: +case 0xa909: +case 0xa90a: +case 0xa90b: +case 0xa90c: +case 0xa90d: +case 0xa90e: +case 0xa90f: +case 0xa910: +case 0xa911: +case 0xa912: +case 0xa913: +case 0xa914: +case 0xa915: +case 0xa916: +case 0xa917: +case 0xa918: +case 0xa919: +case 0xa91a: +case 0xa91b: +case 0xa91c: +case 0xa91d: +case 0xa91e: +case 0xa91f: +case 0xa920: +case 0xa921: +case 0xa922: +case 0xa923: +case 0xa924: +case 0xa925: +case 0xa926: +case 0xa927: +case 0xa928: +case 0xa929: +case 0xa92a: +case 0xa92b: +case 0xa92c: +case 0xa92d: +case 0xa92e: +case 0xa92f: +case 0xa930: +case 0xa931: +case 0xa932: +case 0xa933: +case 0xa934: +case 0xa935: +case 0xa936: +case 0xa937: +case 0xa938: +case 0xa939: +case 0xa93a: +case 0xa93b: +case 0xa93c: +case 0xa93d: +case 0xa93e: +case 0xa93f: +case 0xa940: +case 0xa941: +case 0xa942: +case 0xa943: +case 0xa944: +case 0xa945: +case 0xa946: +case 0xa947: +case 0xa948: +case 0xa949: +case 0xa94a: +case 0xa94b: +case 0xa94c: +case 0xa94d: +case 0xa94e: +case 0xa94f: +case 0xa950: +case 0xa951: +case 0xa952: +case 0xa953: +case 0xa954: +case 0xa955: +case 0xa956: +case 0xa957: +case 0xa958: +case 0xa959: +case 0xa95a: +case 0xa95b: +case 0xa95c: +case 0xa95d: +case 0xa95e: +case 0xa95f: +case 0xa960: +case 0xa961: +case 0xa962: +case 0xa963: +case 0xa964: +case 0xa965: +case 0xa966: +case 0xa967: +case 0xa968: +case 0xa969: +case 0xa96a: +case 0xa96b: +case 0xa96c: +case 0xa96d: +case 0xa96e: +case 0xa96f: +case 0xa970: +case 0xa971: +case 0xa972: +case 0xa973: +case 0xa974: +case 0xa975: +case 0xa976: +case 0xa977: +case 0xa978: +case 0xa979: +case 0xa97a: +case 0xa97b: +case 0xa97c: +case 0xa97d: +case 0xa97e: +case 0xa97f: +case 0xa980: +case 0xa981: +case 0xa982: +case 0xa983: +case 0xa984: +case 0xa985: +case 0xa986: +case 0xa987: +case 0xa988: +case 0xa989: +case 0xa98a: +case 0xa98b: +case 0xa98c: +case 0xa98d: +case 0xa98e: +case 0xa98f: +case 0xa990: +case 0xa991: +case 0xa992: +case 0xa993: +case 0xa994: +case 0xa995: +case 0xa996: +case 0xa997: +case 0xa998: +case 0xa999: +case 0xa99a: +case 0xa99b: +case 0xa99c: +case 0xa99d: +case 0xa99e: +case 0xa99f: +case 0xa9a0: +case 0xa9a1: +case 0xa9a2: +case 0xa9a3: +case 0xa9a4: +case 0xa9a5: +case 0xa9a6: +case 0xa9a7: +case 0xa9a8: +case 0xa9a9: +case 0xa9aa: +case 0xa9ab: +case 0xa9ac: +case 0xa9ad: +case 0xa9ae: +case 0xa9af: +case 0xa9b0: +case 0xa9b1: +case 0xa9b2: +case 0xa9b3: +case 0xa9b4: +case 0xa9b5: +case 0xa9b6: +case 0xa9b7: +case 0xa9b8: +case 0xa9b9: +case 0xa9ba: +case 0xa9bb: +case 0xa9bc: +case 0xa9bd: +case 0xa9be: +case 0xa9bf: +case 0xa9c0: +case 0xa9c1: +case 0xa9c2: +case 0xa9c3: +case 0xa9c4: +case 0xa9c5: +case 0xa9c6: +case 0xa9c7: +case 0xa9c8: +case 0xa9c9: +case 0xa9ca: +case 0xa9cb: +case 0xa9cc: +case 0xa9cd: +case 0xa9ce: +case 0xa9cf: +case 0xa9d0: +case 0xa9d1: +case 0xa9d2: +case 0xa9d3: +case 0xa9d4: +case 0xa9d5: +case 0xa9d6: +case 0xa9d7: +case 0xa9d8: +case 0xa9d9: +case 0xa9da: +case 0xa9db: +case 0xa9dc: +case 0xa9dd: +case 0xa9de: +case 0xa9df: +case 0xa9e0: +case 0xa9e1: +case 0xa9e2: +case 0xa9e3: +case 0xa9e4: +case 0xa9e5: +case 0xa9e6: +case 0xa9e7: +case 0xa9e8: +case 0xa9e9: +case 0xa9ea: +case 0xa9eb: +case 0xa9ec: +case 0xa9ed: +case 0xa9ee: +case 0xa9ef: +case 0xa9f0: +case 0xa9f1: +case 0xa9f2: +case 0xa9f3: +case 0xa9f4: +case 0xa9f5: +case 0xa9f6: +case 0xa9f7: +case 0xa9f8: +case 0xa9f9: +case 0xa9fa: +case 0xa9fb: +case 0xa9fc: +case 0xa9fd: +case 0xa9fe: +case 0xa9ff: +case 0xaa00: +case 0xaa01: +case 0xaa02: +case 0xaa03: +case 0xaa04: +case 0xaa05: +case 0xaa06: +case 0xaa07: +case 0xaa08: +case 0xaa09: +case 0xaa0a: +case 0xaa0b: +case 0xaa0c: +case 0xaa0d: +case 0xaa0e: +case 0xaa0f: +case 0xaa10: +case 0xaa11: +case 0xaa12: +case 0xaa13: +case 0xaa14: +case 0xaa15: +case 0xaa16: +case 0xaa17: +case 0xaa18: +case 0xaa19: +case 0xaa1a: +case 0xaa1b: +case 0xaa1c: +case 0xaa1d: +case 0xaa1e: +case 0xaa1f: +case 0xaa20: +case 0xaa21: +case 0xaa22: +case 0xaa23: +case 0xaa24: +case 0xaa25: +case 0xaa26: +case 0xaa27: +case 0xaa28: +case 0xaa29: +case 0xaa2a: +case 0xaa2b: +case 0xaa2c: +case 0xaa2d: +case 0xaa2e: +case 0xaa2f: +case 0xaa30: +case 0xaa31: +case 0xaa32: +case 0xaa33: +case 0xaa34: +case 0xaa35: +case 0xaa36: +case 0xaa37: +case 0xaa38: +case 0xaa39: +case 0xaa3a: +case 0xaa3b: +case 0xaa3c: +case 0xaa3d: +case 0xaa3e: +case 0xaa3f: +case 0xaa40: +case 0xaa41: +case 0xaa42: +case 0xaa43: +case 0xaa44: +case 0xaa45: +case 0xaa46: +case 0xaa47: +case 0xaa48: +case 0xaa49: +case 0xaa4a: +case 0xaa4b: +case 0xaa4c: +case 0xaa4d: +case 0xaa4e: +case 0xaa4f: +case 0xaa50: +case 0xaa51: +case 0xaa52: +case 0xaa53: +case 0xaa54: +case 0xaa55: +case 0xaa56: +case 0xaa57: +case 0xaa58: +case 0xaa59: +case 0xaa5a: +case 0xaa5b: +case 0xaa5c: +case 0xaa5d: +case 0xaa5e: +case 0xaa5f: +case 0xaa60: +case 0xaa61: +case 0xaa62: +case 0xaa63: +case 0xaa64: +case 0xaa65: +case 0xaa66: +case 0xaa67: +case 0xaa68: +case 0xaa69: +case 0xaa6a: +case 0xaa6b: +case 0xaa6c: +case 0xaa6d: +case 0xaa6e: +case 0xaa6f: +case 0xaa70: +case 0xaa71: +case 0xaa72: +case 0xaa73: +case 0xaa74: +case 0xaa75: +case 0xaa76: +case 0xaa77: +case 0xaa78: +case 0xaa79: +case 0xaa7a: +case 0xaa7b: +case 0xaa7c: +case 0xaa7d: +case 0xaa7e: +case 0xaa7f: +case 0xaa80: +case 0xaa81: +case 0xaa82: +case 0xaa83: +case 0xaa84: +case 0xaa85: +case 0xaa86: +case 0xaa87: +case 0xaa88: +case 0xaa89: +case 0xaa8a: +case 0xaa8b: +case 0xaa8c: +case 0xaa8d: +case 0xaa8e: +case 0xaa8f: +case 0xaa90: +case 0xaa91: +case 0xaa92: +case 0xaa93: +case 0xaa94: +case 0xaa95: +case 0xaa96: +case 0xaa97: +case 0xaa98: +case 0xaa99: +case 0xaa9a: +case 0xaa9b: +case 0xaa9c: +case 0xaa9d: +case 0xaa9e: +case 0xaa9f: +case 0xaaa0: +case 0xaaa1: +case 0xaaa2: +case 0xaaa3: +case 0xaaa4: +case 0xaaa5: +case 0xaaa6: +case 0xaaa7: +case 0xaaa8: +case 0xaaa9: +case 0xaaaa: +case 0xaaab: +case 0xaaac: +case 0xaaad: +case 0xaaae: +case 0xaaaf: +case 0xaab0: +case 0xaab1: +case 0xaab2: +case 0xaab3: +case 0xaab4: +case 0xaab5: +case 0xaab6: +case 0xaab7: +case 0xaab8: +case 0xaab9: +case 0xaaba: +case 0xaabb: +case 0xaabc: +case 0xaabd: +case 0xaabe: +case 0xaabf: +case 0xaac0: +case 0xaac1: +case 0xaac2: +case 0xaac3: +case 0xaac4: +case 0xaac5: +case 0xaac6: +case 0xaac7: +case 0xaac8: +case 0xaac9: +case 0xaaca: +case 0xaacb: +case 0xaacc: +case 0xaacd: +case 0xaace: +case 0xaacf: +case 0xaad0: +case 0xaad1: +case 0xaad2: +case 0xaad3: +case 0xaad4: +case 0xaad5: +case 0xaad6: +case 0xaad7: +case 0xaad8: +case 0xaad9: +case 0xaada: +case 0xaadb: +case 0xaadc: +case 0xaadd: +case 0xaade: +case 0xaadf: +case 0xaae0: +case 0xaae1: +case 0xaae2: +case 0xaae3: +case 0xaae4: +case 0xaae5: +case 0xaae6: +case 0xaae7: +case 0xaae8: +case 0xaae9: +case 0xaaea: +case 0xaaeb: +case 0xaaec: +case 0xaaed: +case 0xaaee: +case 0xaaef: +case 0xaaf0: +case 0xaaf1: +case 0xaaf2: +case 0xaaf3: +case 0xaaf4: +case 0xaaf5: +case 0xaaf6: +case 0xaaf7: +case 0xaaf8: +case 0xaaf9: +case 0xaafa: +case 0xaafb: +case 0xaafc: +case 0xaafd: +case 0xaafe: +case 0xaaff: +case 0xab00: +case 0xab01: +case 0xab02: +case 0xab03: +case 0xab04: +case 0xab05: +case 0xab06: +case 0xab07: +case 0xab08: +case 0xab09: +case 0xab0a: +case 0xab0b: +case 0xab0c: +case 0xab0d: +case 0xab0e: +case 0xab0f: +case 0xab10: +case 0xab11: +case 0xab12: +case 0xab13: +case 0xab14: +case 0xab15: +case 0xab16: +case 0xab17: +case 0xab18: +case 0xab19: +case 0xab1a: +case 0xab1b: +case 0xab1c: +case 0xab1d: +case 0xab1e: +case 0xab1f: +case 0xab20: +case 0xab21: +case 0xab22: +case 0xab23: +case 0xab24: +case 0xab25: +case 0xab26: +case 0xab27: +case 0xab28: +case 0xab29: +case 0xab2a: +case 0xab2b: +case 0xab2c: +case 0xab2d: +case 0xab2e: +case 0xab2f: +case 0xab30: +case 0xab31: +case 0xab32: +case 0xab33: +case 0xab34: +case 0xab35: +case 0xab36: +case 0xab37: +case 0xab38: +case 0xab39: +case 0xab3a: +case 0xab3b: +case 0xab3c: +case 0xab3d: +case 0xab3e: +case 0xab3f: +case 0xab40: +case 0xab41: +case 0xab42: +case 0xab43: +case 0xab44: +case 0xab45: +case 0xab46: +case 0xab47: +case 0xab48: +case 0xab49: +case 0xab4a: +case 0xab4b: +case 0xab4c: +case 0xab4d: +case 0xab4e: +case 0xab4f: +case 0xab50: +case 0xab51: +case 0xab52: +case 0xab53: +case 0xab54: +case 0xab55: +case 0xab56: +case 0xab57: +case 0xab58: +case 0xab59: +case 0xab5a: +case 0xab5b: +case 0xab5c: +case 0xab5d: +case 0xab5e: +case 0xab5f: +case 0xab60: +case 0xab61: +case 0xab62: +case 0xab63: +case 0xab64: +case 0xab65: +case 0xab66: +case 0xab67: +case 0xab68: +case 0xab69: +case 0xab6a: +case 0xab6b: +case 0xab6c: +case 0xab6d: +case 0xab6e: +case 0xab6f: +case 0xab70: +case 0xab71: +case 0xab72: +case 0xab73: +case 0xab74: +case 0xab75: +case 0xab76: +case 0xab77: +case 0xab78: +case 0xab79: +case 0xab7a: +case 0xab7b: +case 0xab7c: +case 0xab7d: +case 0xab7e: +case 0xab7f: +case 0xab80: +case 0xab81: +case 0xab82: +case 0xab83: +case 0xab84: +case 0xab85: +case 0xab86: +case 0xab87: +case 0xab88: +case 0xab89: +case 0xab8a: +case 0xab8b: +case 0xab8c: +case 0xab8d: +case 0xab8e: +case 0xab8f: +case 0xab90: +case 0xab91: +case 0xab92: +case 0xab93: +case 0xab94: +case 0xab95: +case 0xab96: +case 0xab97: +case 0xab98: +case 0xab99: +case 0xab9a: +case 0xab9b: +case 0xab9c: +case 0xab9d: +case 0xab9e: +case 0xab9f: +case 0xaba0: +case 0xaba1: +case 0xaba2: +case 0xaba3: +case 0xaba4: +case 0xaba5: +case 0xaba6: +case 0xaba7: +case 0xaba8: +case 0xaba9: +case 0xabaa: +case 0xabab: +case 0xabac: +case 0xabad: +case 0xabae: +case 0xabaf: +case 0xabb0: +case 0xabb1: +case 0xabb2: +case 0xabb3: +case 0xabb4: +case 0xabb5: +case 0xabb6: +case 0xabb7: +case 0xabb8: +case 0xabb9: +case 0xabba: +case 0xabbb: +case 0xabbc: +case 0xabbd: +case 0xabbe: +case 0xabbf: +case 0xabc0: +case 0xabc1: +case 0xabc2: +case 0xabc3: +case 0xabc4: +case 0xabc5: +case 0xabc6: +case 0xabc7: +case 0xabc8: +case 0xabc9: +case 0xabca: +case 0xabcb: +case 0xabcc: +case 0xabcd: +case 0xabce: +case 0xabcf: +case 0xabd0: +case 0xabd1: +case 0xabd2: +case 0xabd3: +case 0xabd4: +case 0xabd5: +case 0xabd6: +case 0xabd7: +case 0xabd8: +case 0xabd9: +case 0xabda: +case 0xabdb: +case 0xabdc: +case 0xabdd: +case 0xabde: +case 0xabdf: +case 0xabe0: +case 0xabe1: +case 0xabe2: +case 0xabe3: +case 0xabe4: +case 0xabe5: +case 0xabe6: +case 0xabe7: +case 0xabe8: +case 0xabe9: +case 0xabea: +case 0xabeb: +case 0xabec: +case 0xabed: +case 0xabee: +case 0xabef: +case 0xabf0: +case 0xabf1: +case 0xabf2: +case 0xabf3: +case 0xabf4: +case 0xabf5: +case 0xabf6: +case 0xabf7: +case 0xabf8: +case 0xabf9: +case 0xabfa: +case 0xabfb: +case 0xabfc: +case 0xabfd: +case 0xabfe: +case 0xabff: +case 0xac00: +case 0xac01: +case 0xac02: +case 0xac03: +case 0xac04: +case 0xac05: +case 0xac06: +case 0xac07: +case 0xac08: +case 0xac09: +case 0xac0a: +case 0xac0b: +case 0xac0c: +case 0xac0d: +case 0xac0e: +case 0xac0f: +case 0xac10: +case 0xac11: +case 0xac12: +case 0xac13: +case 0xac14: +case 0xac15: +case 0xac16: +case 0xac17: +case 0xac18: +case 0xac19: +case 0xac1a: +case 0xac1b: +case 0xac1c: +case 0xac1d: +case 0xac1e: +case 0xac1f: +case 0xac20: +case 0xac21: +case 0xac22: +case 0xac23: +case 0xac24: +case 0xac25: +case 0xac26: +case 0xac27: +case 0xac28: +case 0xac29: +case 0xac2a: +case 0xac2b: +case 0xac2c: +case 0xac2d: +case 0xac2e: +case 0xac2f: +case 0xac30: +case 0xac31: +case 0xac32: +case 0xac33: +case 0xac34: +case 0xac35: +case 0xac36: +case 0xac37: +case 0xac38: +case 0xac39: +case 0xac3a: +case 0xac3b: +case 0xac3c: +case 0xac3d: +case 0xac3e: +case 0xac3f: +case 0xac40: +case 0xac41: +case 0xac42: +case 0xac43: +case 0xac44: +case 0xac45: +case 0xac46: +case 0xac47: +case 0xac48: +case 0xac49: +case 0xac4a: +case 0xac4b: +case 0xac4c: +case 0xac4d: +case 0xac4e: +case 0xac4f: +case 0xac50: +case 0xac51: +case 0xac52: +case 0xac53: +case 0xac54: +case 0xac55: +case 0xac56: +case 0xac57: +case 0xac58: +case 0xac59: +case 0xac5a: +case 0xac5b: +case 0xac5c: +case 0xac5d: +case 0xac5e: +case 0xac5f: +case 0xac60: +case 0xac61: +case 0xac62: +case 0xac63: +case 0xac64: +case 0xac65: +case 0xac66: +case 0xac67: +case 0xac68: +case 0xac69: +case 0xac6a: +case 0xac6b: +case 0xac6c: +case 0xac6d: +case 0xac6e: +case 0xac6f: +case 0xac70: +case 0xac71: +case 0xac72: +case 0xac73: +case 0xac74: +case 0xac75: +case 0xac76: +case 0xac77: +case 0xac78: +case 0xac79: +case 0xac7a: +case 0xac7b: +case 0xac7c: +case 0xac7d: +case 0xac7e: +case 0xac7f: +case 0xac80: +case 0xac81: +case 0xac82: +case 0xac83: +case 0xac84: +case 0xac85: +case 0xac86: +case 0xac87: +case 0xac88: +case 0xac89: +case 0xac8a: +case 0xac8b: +case 0xac8c: +case 0xac8d: +case 0xac8e: +case 0xac8f: +case 0xac90: +case 0xac91: +case 0xac92: +case 0xac93: +case 0xac94: +case 0xac95: +case 0xac96: +case 0xac97: +case 0xac98: +case 0xac99: +case 0xac9a: +case 0xac9b: +case 0xac9c: +case 0xac9d: +case 0xac9e: +case 0xac9f: +case 0xaca0: +case 0xaca1: +case 0xaca2: +case 0xaca3: +case 0xaca4: +case 0xaca5: +case 0xaca6: +case 0xaca7: +case 0xaca8: +case 0xaca9: +case 0xacaa: +case 0xacab: +case 0xacac: +case 0xacad: +case 0xacae: +case 0xacaf: +case 0xacb0: +case 0xacb1: +case 0xacb2: +case 0xacb3: +case 0xacb4: +case 0xacb5: +case 0xacb6: +case 0xacb7: +case 0xacb8: +case 0xacb9: +case 0xacba: +case 0xacbb: +case 0xacbc: +case 0xacbd: +case 0xacbe: +case 0xacbf: +case 0xacc0: +case 0xacc1: +case 0xacc2: +case 0xacc3: +case 0xacc4: +case 0xacc5: +case 0xacc6: +case 0xacc7: +case 0xacc8: +case 0xacc9: +case 0xacca: +case 0xaccb: +case 0xaccc: +case 0xaccd: +case 0xacce: +case 0xaccf: +case 0xacd0: +case 0xacd1: +case 0xacd2: +case 0xacd3: +case 0xacd4: +case 0xacd5: +case 0xacd6: +case 0xacd7: +case 0xacd8: +case 0xacd9: +case 0xacda: +case 0xacdb: +case 0xacdc: +case 0xacdd: +case 0xacde: +case 0xacdf: +case 0xace0: +case 0xace1: +case 0xace2: +case 0xace3: +case 0xace4: +case 0xace5: +case 0xace6: +case 0xace7: +case 0xace8: +case 0xace9: +case 0xacea: +case 0xaceb: +case 0xacec: +case 0xaced: +case 0xacee: +case 0xacef: +case 0xacf0: +case 0xacf1: +case 0xacf2: +case 0xacf3: +case 0xacf4: +case 0xacf5: +case 0xacf6: +case 0xacf7: +case 0xacf8: +case 0xacf9: +case 0xacfa: +case 0xacfb: +case 0xacfc: +case 0xacfd: +case 0xacfe: +case 0xacff: +case 0xad00: +case 0xad01: +case 0xad02: +case 0xad03: +case 0xad04: +case 0xad05: +case 0xad06: +case 0xad07: +case 0xad08: +case 0xad09: +case 0xad0a: +case 0xad0b: +case 0xad0c: +case 0xad0d: +case 0xad0e: +case 0xad0f: +case 0xad10: +case 0xad11: +case 0xad12: +case 0xad13: +case 0xad14: +case 0xad15: +case 0xad16: +case 0xad17: +case 0xad18: +case 0xad19: +case 0xad1a: +case 0xad1b: +case 0xad1c: +case 0xad1d: +case 0xad1e: +case 0xad1f: +case 0xad20: +case 0xad21: +case 0xad22: +case 0xad23: +case 0xad24: +case 0xad25: +case 0xad26: +case 0xad27: +case 0xad28: +case 0xad29: +case 0xad2a: +case 0xad2b: +case 0xad2c: +case 0xad2d: +case 0xad2e: +case 0xad2f: +case 0xad30: +case 0xad31: +case 0xad32: +case 0xad33: +case 0xad34: +case 0xad35: +case 0xad36: +case 0xad37: +case 0xad38: +case 0xad39: +case 0xad3a: +case 0xad3b: +case 0xad3c: +case 0xad3d: +case 0xad3e: +case 0xad3f: +case 0xad40: +case 0xad41: +case 0xad42: +case 0xad43: +case 0xad44: +case 0xad45: +case 0xad46: +case 0xad47: +case 0xad48: +case 0xad49: +case 0xad4a: +case 0xad4b: +case 0xad4c: +case 0xad4d: +case 0xad4e: +case 0xad4f: +case 0xad50: +case 0xad51: +case 0xad52: +case 0xad53: +case 0xad54: +case 0xad55: +case 0xad56: +case 0xad57: +case 0xad58: +case 0xad59: +case 0xad5a: +case 0xad5b: +case 0xad5c: +case 0xad5d: +case 0xad5e: +case 0xad5f: +case 0xad60: +case 0xad61: +case 0xad62: +case 0xad63: +case 0xad64: +case 0xad65: +case 0xad66: +case 0xad67: +case 0xad68: +case 0xad69: +case 0xad6a: +case 0xad6b: +case 0xad6c: +case 0xad6d: +case 0xad6e: +case 0xad6f: +case 0xad70: +case 0xad71: +case 0xad72: +case 0xad73: +case 0xad74: +case 0xad75: +case 0xad76: +case 0xad77: +case 0xad78: +case 0xad79: +case 0xad7a: +case 0xad7b: +case 0xad7c: +case 0xad7d: +case 0xad7e: +case 0xad7f: +case 0xad80: +case 0xad81: +case 0xad82: +case 0xad83: +case 0xad84: +case 0xad85: +case 0xad86: +case 0xad87: +case 0xad88: +case 0xad89: +case 0xad8a: +case 0xad8b: +case 0xad8c: +case 0xad8d: +case 0xad8e: +case 0xad8f: +case 0xad90: +case 0xad91: +case 0xad92: +case 0xad93: +case 0xad94: +case 0xad95: +case 0xad96: +case 0xad97: +case 0xad98: +case 0xad99: +case 0xad9a: +case 0xad9b: +case 0xad9c: +case 0xad9d: +case 0xad9e: +case 0xad9f: +case 0xada0: +case 0xada1: +case 0xada2: +case 0xada3: +case 0xada4: +case 0xada5: +case 0xada6: +case 0xada7: +case 0xada8: +case 0xada9: +case 0xadaa: +case 0xadab: +case 0xadac: +case 0xadad: +case 0xadae: +case 0xadaf: +case 0xadb0: +case 0xadb1: +case 0xadb2: +case 0xadb3: +case 0xadb4: +case 0xadb5: +case 0xadb6: +case 0xadb7: +case 0xadb8: +case 0xadb9: +case 0xadba: +case 0xadbb: +case 0xadbc: +case 0xadbd: +case 0xadbe: +case 0xadbf: +case 0xadc0: +case 0xadc1: +case 0xadc2: +case 0xadc3: +case 0xadc4: +case 0xadc5: +case 0xadc6: +case 0xadc7: +case 0xadc8: +case 0xadc9: +case 0xadca: +case 0xadcb: +case 0xadcc: +case 0xadcd: +case 0xadce: +case 0xadcf: +case 0xadd0: +case 0xadd1: +case 0xadd2: +case 0xadd3: +case 0xadd4: +case 0xadd5: +case 0xadd6: +case 0xadd7: +case 0xadd8: +case 0xadd9: +case 0xadda: +case 0xaddb: +case 0xaddc: +case 0xaddd: +case 0xadde: +case 0xaddf: +case 0xade0: +case 0xade1: +case 0xade2: +case 0xade3: +case 0xade4: +case 0xade5: +case 0xade6: +case 0xade7: +case 0xade8: +case 0xade9: +case 0xadea: +case 0xadeb: +case 0xadec: +case 0xaded: +case 0xadee: +case 0xadef: +case 0xadf0: +case 0xadf1: +case 0xadf2: +case 0xadf3: +case 0xadf4: +case 0xadf5: +case 0xadf6: +case 0xadf7: +case 0xadf8: +case 0xadf9: +case 0xadfa: +case 0xadfb: +case 0xadfc: +case 0xadfd: +case 0xadfe: +case 0xadff: +case 0xae00: +case 0xae01: +case 0xae02: +case 0xae03: +case 0xae04: +case 0xae05: +case 0xae06: +case 0xae07: +case 0xae08: +case 0xae09: +case 0xae0a: +case 0xae0b: +case 0xae0c: +case 0xae0d: +case 0xae0e: +case 0xae0f: +case 0xae10: +case 0xae11: +case 0xae12: +case 0xae13: +case 0xae14: +case 0xae15: +case 0xae16: +case 0xae17: +case 0xae18: +case 0xae19: +case 0xae1a: +case 0xae1b: +case 0xae1c: +case 0xae1d: +case 0xae1e: +case 0xae1f: +case 0xae20: +case 0xae21: +case 0xae22: +case 0xae23: +case 0xae24: +case 0xae25: +case 0xae26: +case 0xae27: +case 0xae28: +case 0xae29: +case 0xae2a: +case 0xae2b: +case 0xae2c: +case 0xae2d: +case 0xae2e: +case 0xae2f: +case 0xae30: +case 0xae31: +case 0xae32: +case 0xae33: +case 0xae34: +case 0xae35: +case 0xae36: +case 0xae37: +case 0xae38: +case 0xae39: +case 0xae3a: +case 0xae3b: +case 0xae3c: +case 0xae3d: +case 0xae3e: +case 0xae3f: +case 0xae40: +case 0xae41: +case 0xae42: +case 0xae43: +case 0xae44: +case 0xae45: +case 0xae46: +case 0xae47: +case 0xae48: +case 0xae49: +case 0xae4a: +case 0xae4b: +case 0xae4c: +case 0xae4d: +case 0xae4e: +case 0xae4f: +case 0xae50: +case 0xae51: +case 0xae52: +case 0xae53: +case 0xae54: +case 0xae55: +case 0xae56: +case 0xae57: +case 0xae58: +case 0xae59: +case 0xae5a: +case 0xae5b: +case 0xae5c: +case 0xae5d: +case 0xae5e: +case 0xae5f: +case 0xae60: +case 0xae61: +case 0xae62: +case 0xae63: +case 0xae64: +case 0xae65: +case 0xae66: +case 0xae67: +case 0xae68: +case 0xae69: +case 0xae6a: +case 0xae6b: +case 0xae6c: +case 0xae6d: +case 0xae6e: +case 0xae6f: +case 0xae70: +case 0xae71: +case 0xae72: +case 0xae73: +case 0xae74: +case 0xae75: +case 0xae76: +case 0xae77: +case 0xae78: +case 0xae79: +case 0xae7a: +case 0xae7b: +case 0xae7c: +case 0xae7d: +case 0xae7e: +case 0xae7f: +case 0xae80: +case 0xae81: +case 0xae82: +case 0xae83: +case 0xae84: +case 0xae85: +case 0xae86: +case 0xae87: +case 0xae88: +case 0xae89: +case 0xae8a: +case 0xae8b: +case 0xae8c: +case 0xae8d: +case 0xae8e: +case 0xae8f: +case 0xae90: +case 0xae91: +case 0xae92: +case 0xae93: +case 0xae94: +case 0xae95: +case 0xae96: +case 0xae97: +case 0xae98: +case 0xae99: +case 0xae9a: +case 0xae9b: +case 0xae9c: +case 0xae9d: +case 0xae9e: +case 0xae9f: +case 0xaea0: +case 0xaea1: +case 0xaea2: +case 0xaea3: +case 0xaea4: +case 0xaea5: +case 0xaea6: +case 0xaea7: +case 0xaea8: +case 0xaea9: +case 0xaeaa: +case 0xaeab: +case 0xaeac: +case 0xaead: +case 0xaeae: +case 0xaeaf: +case 0xaeb0: +case 0xaeb1: +case 0xaeb2: +case 0xaeb3: +case 0xaeb4: +case 0xaeb5: +case 0xaeb6: +case 0xaeb7: +case 0xaeb8: +case 0xaeb9: +case 0xaeba: +case 0xaebb: +case 0xaebc: +case 0xaebd: +case 0xaebe: +case 0xaebf: +case 0xaec0: +case 0xaec1: +case 0xaec2: +case 0xaec3: +case 0xaec4: +case 0xaec5: +case 0xaec6: +case 0xaec7: +case 0xaec8: +case 0xaec9: +case 0xaeca: +case 0xaecb: +case 0xaecc: +case 0xaecd: +case 0xaece: +case 0xaecf: +case 0xaed0: +case 0xaed1: +case 0xaed2: +case 0xaed3: +case 0xaed4: +case 0xaed5: +case 0xaed6: +case 0xaed7: +case 0xaed8: +case 0xaed9: +case 0xaeda: +case 0xaedb: +case 0xaedc: +case 0xaedd: +case 0xaede: +case 0xaedf: +case 0xaee0: +case 0xaee1: +case 0xaee2: +case 0xaee3: +case 0xaee4: +case 0xaee5: +case 0xaee6: +case 0xaee7: +case 0xaee8: +case 0xaee9: +case 0xaeea: +case 0xaeeb: +case 0xaeec: +case 0xaeed: +case 0xaeee: +case 0xaeef: +case 0xaef0: +case 0xaef1: +case 0xaef2: +case 0xaef3: +case 0xaef4: +case 0xaef5: +case 0xaef6: +case 0xaef7: +case 0xaef8: +case 0xaef9: +case 0xaefa: +case 0xaefb: +case 0xaefc: +case 0xaefd: +case 0xaefe: +case 0xaeff: +case 0xaf00: +case 0xaf01: +case 0xaf02: +case 0xaf03: +case 0xaf04: +case 0xaf05: +case 0xaf06: +case 0xaf07: +case 0xaf08: +case 0xaf09: +case 0xaf0a: +case 0xaf0b: +case 0xaf0c: +case 0xaf0d: +case 0xaf0e: +case 0xaf0f: +case 0xaf10: +case 0xaf11: +case 0xaf12: +case 0xaf13: +case 0xaf14: +case 0xaf15: +case 0xaf16: +case 0xaf17: +case 0xaf18: +case 0xaf19: +case 0xaf1a: +case 0xaf1b: +case 0xaf1c: +case 0xaf1d: +case 0xaf1e: +case 0xaf1f: +case 0xaf20: +case 0xaf21: +case 0xaf22: +case 0xaf23: +case 0xaf24: +case 0xaf25: +case 0xaf26: +case 0xaf27: +case 0xaf28: +case 0xaf29: +case 0xaf2a: +case 0xaf2b: +case 0xaf2c: +case 0xaf2d: +case 0xaf2e: +case 0xaf2f: +case 0xaf30: +case 0xaf31: +case 0xaf32: +case 0xaf33: +case 0xaf34: +case 0xaf35: +case 0xaf36: +case 0xaf37: +case 0xaf38: +case 0xaf39: +case 0xaf3a: +case 0xaf3b: +case 0xaf3c: +case 0xaf3d: +case 0xaf3e: +case 0xaf3f: +case 0xaf40: +case 0xaf41: +case 0xaf42: +case 0xaf43: +case 0xaf44: +case 0xaf45: +case 0xaf46: +case 0xaf47: +case 0xaf48: +case 0xaf49: +case 0xaf4a: +case 0xaf4b: +case 0xaf4c: +case 0xaf4d: +case 0xaf4e: +case 0xaf4f: +case 0xaf50: +case 0xaf51: +case 0xaf52: +case 0xaf53: +case 0xaf54: +case 0xaf55: +case 0xaf56: +case 0xaf57: +case 0xaf58: +case 0xaf59: +case 0xaf5a: +case 0xaf5b: +case 0xaf5c: +case 0xaf5d: +case 0xaf5e: +case 0xaf5f: +case 0xaf60: +case 0xaf61: +case 0xaf62: +case 0xaf63: +case 0xaf64: +case 0xaf65: +case 0xaf66: +case 0xaf67: +case 0xaf68: +case 0xaf69: +case 0xaf6a: +case 0xaf6b: +case 0xaf6c: +case 0xaf6d: +case 0xaf6e: +case 0xaf6f: +case 0xaf70: +case 0xaf71: +case 0xaf72: +case 0xaf73: +case 0xaf74: +case 0xaf75: +case 0xaf76: +case 0xaf77: +case 0xaf78: +case 0xaf79: +case 0xaf7a: +case 0xaf7b: +case 0xaf7c: +case 0xaf7d: +case 0xaf7e: +case 0xaf7f: +case 0xaf80: +case 0xaf81: +case 0xaf82: +case 0xaf83: +case 0xaf84: +case 0xaf85: +case 0xaf86: +case 0xaf87: +case 0xaf88: +case 0xaf89: +case 0xaf8a: +case 0xaf8b: +case 0xaf8c: +case 0xaf8d: +case 0xaf8e: +case 0xaf8f: +case 0xaf90: +case 0xaf91: +case 0xaf92: +case 0xaf93: +case 0xaf94: +case 0xaf95: +case 0xaf96: +case 0xaf97: +case 0xaf98: +case 0xaf99: +case 0xaf9a: +case 0xaf9b: +case 0xaf9c: +case 0xaf9d: +case 0xaf9e: +case 0xaf9f: +case 0xafa0: +case 0xafa1: +case 0xafa2: +case 0xafa3: +case 0xafa4: +case 0xafa5: +case 0xafa6: +case 0xafa7: +case 0xafa8: +case 0xafa9: +case 0xafaa: +case 0xafab: +case 0xafac: +case 0xafad: +case 0xafae: +case 0xafaf: +case 0xafb0: +case 0xafb1: +case 0xafb2: +case 0xafb3: +case 0xafb4: +case 0xafb5: +case 0xafb6: +case 0xafb7: +case 0xafb8: +case 0xafb9: +case 0xafba: +case 0xafbb: +case 0xafbc: +case 0xafbd: +case 0xafbe: +case 0xafbf: +case 0xafc0: +case 0xafc1: +case 0xafc2: +case 0xafc3: +case 0xafc4: +case 0xafc5: +case 0xafc6: +case 0xafc7: +case 0xafc8: +case 0xafc9: +case 0xafca: +case 0xafcb: +case 0xafcc: +case 0xafcd: +case 0xafce: +case 0xafcf: +case 0xafd0: +case 0xafd1: +case 0xafd2: +case 0xafd3: +case 0xafd4: +case 0xafd5: +case 0xafd6: +case 0xafd7: +case 0xafd8: +case 0xafd9: +case 0xafda: +case 0xafdb: +case 0xafdc: +case 0xafdd: +case 0xafde: +case 0xafdf: +case 0xafe0: +case 0xafe1: +case 0xafe2: +case 0xafe3: +case 0xafe4: +case 0xafe5: +case 0xafe6: +case 0xafe7: +case 0xafe8: +case 0xafe9: +case 0xafea: +case 0xafeb: +case 0xafec: +case 0xafed: +case 0xafee: +case 0xafef: +case 0xaff0: +case 0xaff1: +case 0xaff2: +case 0xaff3: +case 0xaff4: +case 0xaff5: +case 0xaff6: +case 0xaff7: +case 0xaff8: +case 0xaff9: +case 0xaffa: +case 0xaffb: +case 0xaffc: +case 0xaffd: +case 0xaffe: +case 0xafff: + { + LINEA(); + } + break; + +case 0xf000: +case 0xf001: +case 0xf002: +case 0xf003: +case 0xf004: +case 0xf005: +case 0xf006: +case 0xf007: +case 0xf008: +case 0xf009: +case 0xf00a: +case 0xf00b: +case 0xf00c: +case 0xf00d: +case 0xf00e: +case 0xf00f: +case 0xf010: +case 0xf011: +case 0xf012: +case 0xf013: +case 0xf014: +case 0xf015: +case 0xf016: +case 0xf017: +case 0xf018: +case 0xf019: +case 0xf01a: +case 0xf01b: +case 0xf01c: +case 0xf01d: +case 0xf01e: +case 0xf01f: +case 0xf020: +case 0xf021: +case 0xf022: +case 0xf023: +case 0xf024: +case 0xf025: +case 0xf026: +case 0xf027: +case 0xf028: +case 0xf029: +case 0xf02a: +case 0xf02b: +case 0xf02c: +case 0xf02d: +case 0xf02e: +case 0xf02f: +case 0xf030: +case 0xf031: +case 0xf032: +case 0xf033: +case 0xf034: +case 0xf035: +case 0xf036: +case 0xf037: +case 0xf038: +case 0xf039: +case 0xf03a: +case 0xf03b: +case 0xf03c: +case 0xf03d: +case 0xf03e: +case 0xf03f: +case 0xf040: +case 0xf041: +case 0xf042: +case 0xf043: +case 0xf044: +case 0xf045: +case 0xf046: +case 0xf047: +case 0xf048: +case 0xf049: +case 0xf04a: +case 0xf04b: +case 0xf04c: +case 0xf04d: +case 0xf04e: +case 0xf04f: +case 0xf050: +case 0xf051: +case 0xf052: +case 0xf053: +case 0xf054: +case 0xf055: +case 0xf056: +case 0xf057: +case 0xf058: +case 0xf059: +case 0xf05a: +case 0xf05b: +case 0xf05c: +case 0xf05d: +case 0xf05e: +case 0xf05f: +case 0xf060: +case 0xf061: +case 0xf062: +case 0xf063: +case 0xf064: +case 0xf065: +case 0xf066: +case 0xf067: +case 0xf068: +case 0xf069: +case 0xf06a: +case 0xf06b: +case 0xf06c: +case 0xf06d: +case 0xf06e: +case 0xf06f: +case 0xf070: +case 0xf071: +case 0xf072: +case 0xf073: +case 0xf074: +case 0xf075: +case 0xf076: +case 0xf077: +case 0xf078: +case 0xf079: +case 0xf07a: +case 0xf07b: +case 0xf07c: +case 0xf07d: +case 0xf07e: +case 0xf07f: +case 0xf080: +case 0xf081: +case 0xf082: +case 0xf083: +case 0xf084: +case 0xf085: +case 0xf086: +case 0xf087: +case 0xf088: +case 0xf089: +case 0xf08a: +case 0xf08b: +case 0xf08c: +case 0xf08d: +case 0xf08e: +case 0xf08f: +case 0xf090: +case 0xf091: +case 0xf092: +case 0xf093: +case 0xf094: +case 0xf095: +case 0xf096: +case 0xf097: +case 0xf098: +case 0xf099: +case 0xf09a: +case 0xf09b: +case 0xf09c: +case 0xf09d: +case 0xf09e: +case 0xf09f: +case 0xf0a0: +case 0xf0a1: +case 0xf0a2: +case 0xf0a3: +case 0xf0a4: +case 0xf0a5: +case 0xf0a6: +case 0xf0a7: +case 0xf0a8: +case 0xf0a9: +case 0xf0aa: +case 0xf0ab: +case 0xf0ac: +case 0xf0ad: +case 0xf0ae: +case 0xf0af: +case 0xf0b0: +case 0xf0b1: +case 0xf0b2: +case 0xf0b3: +case 0xf0b4: +case 0xf0b5: +case 0xf0b6: +case 0xf0b7: +case 0xf0b8: +case 0xf0b9: +case 0xf0ba: +case 0xf0bb: +case 0xf0bc: +case 0xf0bd: +case 0xf0be: +case 0xf0bf: +case 0xf0c0: +case 0xf0c1: +case 0xf0c2: +case 0xf0c3: +case 0xf0c4: +case 0xf0c5: +case 0xf0c6: +case 0xf0c7: +case 0xf0c8: +case 0xf0c9: +case 0xf0ca: +case 0xf0cb: +case 0xf0cc: +case 0xf0cd: +case 0xf0ce: +case 0xf0cf: +case 0xf0d0: +case 0xf0d1: +case 0xf0d2: +case 0xf0d3: +case 0xf0d4: +case 0xf0d5: +case 0xf0d6: +case 0xf0d7: +case 0xf0d8: +case 0xf0d9: +case 0xf0da: +case 0xf0db: +case 0xf0dc: +case 0xf0dd: +case 0xf0de: +case 0xf0df: +case 0xf0e0: +case 0xf0e1: +case 0xf0e2: +case 0xf0e3: +case 0xf0e4: +case 0xf0e5: +case 0xf0e6: +case 0xf0e7: +case 0xf0e8: +case 0xf0e9: +case 0xf0ea: +case 0xf0eb: +case 0xf0ec: +case 0xf0ed: +case 0xf0ee: +case 0xf0ef: +case 0xf0f0: +case 0xf0f1: +case 0xf0f2: +case 0xf0f3: +case 0xf0f4: +case 0xf0f5: +case 0xf0f6: +case 0xf0f7: +case 0xf0f8: +case 0xf0f9: +case 0xf0fa: +case 0xf0fb: +case 0xf0fc: +case 0xf0fd: +case 0xf0fe: +case 0xf0ff: +case 0xf100: +case 0xf101: +case 0xf102: +case 0xf103: +case 0xf104: +case 0xf105: +case 0xf106: +case 0xf107: +case 0xf108: +case 0xf109: +case 0xf10a: +case 0xf10b: +case 0xf10c: +case 0xf10d: +case 0xf10e: +case 0xf10f: +case 0xf110: +case 0xf111: +case 0xf112: +case 0xf113: +case 0xf114: +case 0xf115: +case 0xf116: +case 0xf117: +case 0xf118: +case 0xf119: +case 0xf11a: +case 0xf11b: +case 0xf11c: +case 0xf11d: +case 0xf11e: +case 0xf11f: +case 0xf120: +case 0xf121: +case 0xf122: +case 0xf123: +case 0xf124: +case 0xf125: +case 0xf126: +case 0xf127: +case 0xf128: +case 0xf129: +case 0xf12a: +case 0xf12b: +case 0xf12c: +case 0xf12d: +case 0xf12e: +case 0xf12f: +case 0xf130: +case 0xf131: +case 0xf132: +case 0xf133: +case 0xf134: +case 0xf135: +case 0xf136: +case 0xf137: +case 0xf138: +case 0xf139: +case 0xf13a: +case 0xf13b: +case 0xf13c: +case 0xf13d: +case 0xf13e: +case 0xf13f: +case 0xf140: +case 0xf141: +case 0xf142: +case 0xf143: +case 0xf144: +case 0xf145: +case 0xf146: +case 0xf147: +case 0xf148: +case 0xf149: +case 0xf14a: +case 0xf14b: +case 0xf14c: +case 0xf14d: +case 0xf14e: +case 0xf14f: +case 0xf150: +case 0xf151: +case 0xf152: +case 0xf153: +case 0xf154: +case 0xf155: +case 0xf156: +case 0xf157: +case 0xf158: +case 0xf159: +case 0xf15a: +case 0xf15b: +case 0xf15c: +case 0xf15d: +case 0xf15e: +case 0xf15f: +case 0xf160: +case 0xf161: +case 0xf162: +case 0xf163: +case 0xf164: +case 0xf165: +case 0xf166: +case 0xf167: +case 0xf168: +case 0xf169: +case 0xf16a: +case 0xf16b: +case 0xf16c: +case 0xf16d: +case 0xf16e: +case 0xf16f: +case 0xf170: +case 0xf171: +case 0xf172: +case 0xf173: +case 0xf174: +case 0xf175: +case 0xf176: +case 0xf177: +case 0xf178: +case 0xf179: +case 0xf17a: +case 0xf17b: +case 0xf17c: +case 0xf17d: +case 0xf17e: +case 0xf17f: +case 0xf180: +case 0xf181: +case 0xf182: +case 0xf183: +case 0xf184: +case 0xf185: +case 0xf186: +case 0xf187: +case 0xf188: +case 0xf189: +case 0xf18a: +case 0xf18b: +case 0xf18c: +case 0xf18d: +case 0xf18e: +case 0xf18f: +case 0xf190: +case 0xf191: +case 0xf192: +case 0xf193: +case 0xf194: +case 0xf195: +case 0xf196: +case 0xf197: +case 0xf198: +case 0xf199: +case 0xf19a: +case 0xf19b: +case 0xf19c: +case 0xf19d: +case 0xf19e: +case 0xf19f: +case 0xf1a0: +case 0xf1a1: +case 0xf1a2: +case 0xf1a3: +case 0xf1a4: +case 0xf1a5: +case 0xf1a6: +case 0xf1a7: +case 0xf1a8: +case 0xf1a9: +case 0xf1aa: +case 0xf1ab: +case 0xf1ac: +case 0xf1ad: +case 0xf1ae: +case 0xf1af: +case 0xf1b0: +case 0xf1b1: +case 0xf1b2: +case 0xf1b3: +case 0xf1b4: +case 0xf1b5: +case 0xf1b6: +case 0xf1b7: +case 0xf1b8: +case 0xf1b9: +case 0xf1ba: +case 0xf1bb: +case 0xf1bc: +case 0xf1bd: +case 0xf1be: +case 0xf1bf: +case 0xf1c0: +case 0xf1c1: +case 0xf1c2: +case 0xf1c3: +case 0xf1c4: +case 0xf1c5: +case 0xf1c6: +case 0xf1c7: +case 0xf1c8: +case 0xf1c9: +case 0xf1ca: +case 0xf1cb: +case 0xf1cc: +case 0xf1cd: +case 0xf1ce: +case 0xf1cf: +case 0xf1d0: +case 0xf1d1: +case 0xf1d2: +case 0xf1d3: +case 0xf1d4: +case 0xf1d5: +case 0xf1d6: +case 0xf1d7: +case 0xf1d8: +case 0xf1d9: +case 0xf1da: +case 0xf1db: +case 0xf1dc: +case 0xf1dd: +case 0xf1de: +case 0xf1df: +case 0xf1e0: +case 0xf1e1: +case 0xf1e2: +case 0xf1e3: +case 0xf1e4: +case 0xf1e5: +case 0xf1e6: +case 0xf1e7: +case 0xf1e8: +case 0xf1e9: +case 0xf1ea: +case 0xf1eb: +case 0xf1ec: +case 0xf1ed: +case 0xf1ee: +case 0xf1ef: +case 0xf1f0: +case 0xf1f1: +case 0xf1f2: +case 0xf1f3: +case 0xf1f4: +case 0xf1f5: +case 0xf1f6: +case 0xf1f7: +case 0xf1f8: +case 0xf1f9: +case 0xf1fa: +case 0xf1fb: +case 0xf1fc: +case 0xf1fd: +case 0xf1fe: +case 0xf1ff: +case 0xf200: +case 0xf201: +case 0xf202: +case 0xf203: +case 0xf204: +case 0xf205: +case 0xf206: +case 0xf207: +case 0xf208: +case 0xf209: +case 0xf20a: +case 0xf20b: +case 0xf20c: +case 0xf20d: +case 0xf20e: +case 0xf20f: +case 0xf210: +case 0xf211: +case 0xf212: +case 0xf213: +case 0xf214: +case 0xf215: +case 0xf216: +case 0xf217: +case 0xf218: +case 0xf219: +case 0xf21a: +case 0xf21b: +case 0xf21c: +case 0xf21d: +case 0xf21e: +case 0xf21f: +case 0xf220: +case 0xf221: +case 0xf222: +case 0xf223: +case 0xf224: +case 0xf225: +case 0xf226: +case 0xf227: +case 0xf228: +case 0xf229: +case 0xf22a: +case 0xf22b: +case 0xf22c: +case 0xf22d: +case 0xf22e: +case 0xf22f: +case 0xf230: +case 0xf231: +case 0xf232: +case 0xf233: +case 0xf234: +case 0xf235: +case 0xf236: +case 0xf237: +case 0xf238: +case 0xf239: +case 0xf23a: +case 0xf23b: +case 0xf23c: +case 0xf23d: +case 0xf23e: +case 0xf23f: +case 0xf240: +case 0xf241: +case 0xf242: +case 0xf243: +case 0xf244: +case 0xf245: +case 0xf246: +case 0xf247: +case 0xf248: +case 0xf249: +case 0xf24a: +case 0xf24b: +case 0xf24c: +case 0xf24d: +case 0xf24e: +case 0xf24f: +case 0xf250: +case 0xf251: +case 0xf252: +case 0xf253: +case 0xf254: +case 0xf255: +case 0xf256: +case 0xf257: +case 0xf258: +case 0xf259: +case 0xf25a: +case 0xf25b: +case 0xf25c: +case 0xf25d: +case 0xf25e: +case 0xf25f: +case 0xf260: +case 0xf261: +case 0xf262: +case 0xf263: +case 0xf264: +case 0xf265: +case 0xf266: +case 0xf267: +case 0xf268: +case 0xf269: +case 0xf26a: +case 0xf26b: +case 0xf26c: +case 0xf26d: +case 0xf26e: +case 0xf26f: +case 0xf270: +case 0xf271: +case 0xf272: +case 0xf273: +case 0xf274: +case 0xf275: +case 0xf276: +case 0xf277: +case 0xf278: +case 0xf279: +case 0xf27a: +case 0xf27b: +case 0xf27c: +case 0xf27d: +case 0xf27e: +case 0xf27f: +case 0xf280: +case 0xf281: +case 0xf282: +case 0xf283: +case 0xf284: +case 0xf285: +case 0xf286: +case 0xf287: +case 0xf288: +case 0xf289: +case 0xf28a: +case 0xf28b: +case 0xf28c: +case 0xf28d: +case 0xf28e: +case 0xf28f: +case 0xf290: +case 0xf291: +case 0xf292: +case 0xf293: +case 0xf294: +case 0xf295: +case 0xf296: +case 0xf297: +case 0xf298: +case 0xf299: +case 0xf29a: +case 0xf29b: +case 0xf29c: +case 0xf29d: +case 0xf29e: +case 0xf29f: +case 0xf2a0: +case 0xf2a1: +case 0xf2a2: +case 0xf2a3: +case 0xf2a4: +case 0xf2a5: +case 0xf2a6: +case 0xf2a7: +case 0xf2a8: +case 0xf2a9: +case 0xf2aa: +case 0xf2ab: +case 0xf2ac: +case 0xf2ad: +case 0xf2ae: +case 0xf2af: +case 0xf2b0: +case 0xf2b1: +case 0xf2b2: +case 0xf2b3: +case 0xf2b4: +case 0xf2b5: +case 0xf2b6: +case 0xf2b7: +case 0xf2b8: +case 0xf2b9: +case 0xf2ba: +case 0xf2bb: +case 0xf2bc: +case 0xf2bd: +case 0xf2be: +case 0xf2bf: +case 0xf2c0: +case 0xf2c1: +case 0xf2c2: +case 0xf2c3: +case 0xf2c4: +case 0xf2c5: +case 0xf2c6: +case 0xf2c7: +case 0xf2c8: +case 0xf2c9: +case 0xf2ca: +case 0xf2cb: +case 0xf2cc: +case 0xf2cd: +case 0xf2ce: +case 0xf2cf: +case 0xf2d0: +case 0xf2d1: +case 0xf2d2: +case 0xf2d3: +case 0xf2d4: +case 0xf2d5: +case 0xf2d6: +case 0xf2d7: +case 0xf2d8: +case 0xf2d9: +case 0xf2da: +case 0xf2db: +case 0xf2dc: +case 0xf2dd: +case 0xf2de: +case 0xf2df: +case 0xf2e0: +case 0xf2e1: +case 0xf2e2: +case 0xf2e3: +case 0xf2e4: +case 0xf2e5: +case 0xf2e6: +case 0xf2e7: +case 0xf2e8: +case 0xf2e9: +case 0xf2ea: +case 0xf2eb: +case 0xf2ec: +case 0xf2ed: +case 0xf2ee: +case 0xf2ef: +case 0xf2f0: +case 0xf2f1: +case 0xf2f2: +case 0xf2f3: +case 0xf2f4: +case 0xf2f5: +case 0xf2f6: +case 0xf2f7: +case 0xf2f8: +case 0xf2f9: +case 0xf2fa: +case 0xf2fb: +case 0xf2fc: +case 0xf2fd: +case 0xf2fe: +case 0xf2ff: +case 0xf300: +case 0xf301: +case 0xf302: +case 0xf303: +case 0xf304: +case 0xf305: +case 0xf306: +case 0xf307: +case 0xf308: +case 0xf309: +case 0xf30a: +case 0xf30b: +case 0xf30c: +case 0xf30d: +case 0xf30e: +case 0xf30f: +case 0xf310: +case 0xf311: +case 0xf312: +case 0xf313: +case 0xf314: +case 0xf315: +case 0xf316: +case 0xf317: +case 0xf318: +case 0xf319: +case 0xf31a: +case 0xf31b: +case 0xf31c: +case 0xf31d: +case 0xf31e: +case 0xf31f: +case 0xf320: +case 0xf321: +case 0xf322: +case 0xf323: +case 0xf324: +case 0xf325: +case 0xf326: +case 0xf327: +case 0xf328: +case 0xf329: +case 0xf32a: +case 0xf32b: +case 0xf32c: +case 0xf32d: +case 0xf32e: +case 0xf32f: +case 0xf330: +case 0xf331: +case 0xf332: +case 0xf333: +case 0xf334: +case 0xf335: +case 0xf336: +case 0xf337: +case 0xf338: +case 0xf339: +case 0xf33a: +case 0xf33b: +case 0xf33c: +case 0xf33d: +case 0xf33e: +case 0xf33f: +case 0xf340: +case 0xf341: +case 0xf342: +case 0xf343: +case 0xf344: +case 0xf345: +case 0xf346: +case 0xf347: +case 0xf348: +case 0xf349: +case 0xf34a: +case 0xf34b: +case 0xf34c: +case 0xf34d: +case 0xf34e: +case 0xf34f: +case 0xf350: +case 0xf351: +case 0xf352: +case 0xf353: +case 0xf354: +case 0xf355: +case 0xf356: +case 0xf357: +case 0xf358: +case 0xf359: +case 0xf35a: +case 0xf35b: +case 0xf35c: +case 0xf35d: +case 0xf35e: +case 0xf35f: +case 0xf360: +case 0xf361: +case 0xf362: +case 0xf363: +case 0xf364: +case 0xf365: +case 0xf366: +case 0xf367: +case 0xf368: +case 0xf369: +case 0xf36a: +case 0xf36b: +case 0xf36c: +case 0xf36d: +case 0xf36e: +case 0xf36f: +case 0xf370: +case 0xf371: +case 0xf372: +case 0xf373: +case 0xf374: +case 0xf375: +case 0xf376: +case 0xf377: +case 0xf378: +case 0xf379: +case 0xf37a: +case 0xf37b: +case 0xf37c: +case 0xf37d: +case 0xf37e: +case 0xf37f: +case 0xf380: +case 0xf381: +case 0xf382: +case 0xf383: +case 0xf384: +case 0xf385: +case 0xf386: +case 0xf387: +case 0xf388: +case 0xf389: +case 0xf38a: +case 0xf38b: +case 0xf38c: +case 0xf38d: +case 0xf38e: +case 0xf38f: +case 0xf390: +case 0xf391: +case 0xf392: +case 0xf393: +case 0xf394: +case 0xf395: +case 0xf396: +case 0xf397: +case 0xf398: +case 0xf399: +case 0xf39a: +case 0xf39b: +case 0xf39c: +case 0xf39d: +case 0xf39e: +case 0xf39f: +case 0xf3a0: +case 0xf3a1: +case 0xf3a2: +case 0xf3a3: +case 0xf3a4: +case 0xf3a5: +case 0xf3a6: +case 0xf3a7: +case 0xf3a8: +case 0xf3a9: +case 0xf3aa: +case 0xf3ab: +case 0xf3ac: +case 0xf3ad: +case 0xf3ae: +case 0xf3af: +case 0xf3b0: +case 0xf3b1: +case 0xf3b2: +case 0xf3b3: +case 0xf3b4: +case 0xf3b5: +case 0xf3b6: +case 0xf3b7: +case 0xf3b8: +case 0xf3b9: +case 0xf3ba: +case 0xf3bb: +case 0xf3bc: +case 0xf3bd: +case 0xf3be: +case 0xf3bf: +case 0xf3c0: +case 0xf3c1: +case 0xf3c2: +case 0xf3c3: +case 0xf3c4: +case 0xf3c5: +case 0xf3c6: +case 0xf3c7: +case 0xf3c8: +case 0xf3c9: +case 0xf3ca: +case 0xf3cb: +case 0xf3cc: +case 0xf3cd: +case 0xf3ce: +case 0xf3cf: +case 0xf3d0: +case 0xf3d1: +case 0xf3d2: +case 0xf3d3: +case 0xf3d4: +case 0xf3d5: +case 0xf3d6: +case 0xf3d7: +case 0xf3d8: +case 0xf3d9: +case 0xf3da: +case 0xf3db: +case 0xf3dc: +case 0xf3dd: +case 0xf3de: +case 0xf3df: +case 0xf3e0: +case 0xf3e1: +case 0xf3e2: +case 0xf3e3: +case 0xf3e4: +case 0xf3e5: +case 0xf3e6: +case 0xf3e7: +case 0xf3e8: +case 0xf3e9: +case 0xf3ea: +case 0xf3eb: +case 0xf3ec: +case 0xf3ed: +case 0xf3ee: +case 0xf3ef: +case 0xf3f0: +case 0xf3f1: +case 0xf3f2: +case 0xf3f3: +case 0xf3f4: +case 0xf3f5: +case 0xf3f6: +case 0xf3f7: +case 0xf3f8: +case 0xf3f9: +case 0xf3fa: +case 0xf3fb: +case 0xf3fc: +case 0xf3fd: +case 0xf3fe: +case 0xf3ff: +case 0xf400: +case 0xf401: +case 0xf402: +case 0xf403: +case 0xf404: +case 0xf405: +case 0xf406: +case 0xf407: +case 0xf408: +case 0xf409: +case 0xf40a: +case 0xf40b: +case 0xf40c: +case 0xf40d: +case 0xf40e: +case 0xf40f: +case 0xf410: +case 0xf411: +case 0xf412: +case 0xf413: +case 0xf414: +case 0xf415: +case 0xf416: +case 0xf417: +case 0xf418: +case 0xf419: +case 0xf41a: +case 0xf41b: +case 0xf41c: +case 0xf41d: +case 0xf41e: +case 0xf41f: +case 0xf420: +case 0xf421: +case 0xf422: +case 0xf423: +case 0xf424: +case 0xf425: +case 0xf426: +case 0xf427: +case 0xf428: +case 0xf429: +case 0xf42a: +case 0xf42b: +case 0xf42c: +case 0xf42d: +case 0xf42e: +case 0xf42f: +case 0xf430: +case 0xf431: +case 0xf432: +case 0xf433: +case 0xf434: +case 0xf435: +case 0xf436: +case 0xf437: +case 0xf438: +case 0xf439: +case 0xf43a: +case 0xf43b: +case 0xf43c: +case 0xf43d: +case 0xf43e: +case 0xf43f: +case 0xf440: +case 0xf441: +case 0xf442: +case 0xf443: +case 0xf444: +case 0xf445: +case 0xf446: +case 0xf447: +case 0xf448: +case 0xf449: +case 0xf44a: +case 0xf44b: +case 0xf44c: +case 0xf44d: +case 0xf44e: +case 0xf44f: +case 0xf450: +case 0xf451: +case 0xf452: +case 0xf453: +case 0xf454: +case 0xf455: +case 0xf456: +case 0xf457: +case 0xf458: +case 0xf459: +case 0xf45a: +case 0xf45b: +case 0xf45c: +case 0xf45d: +case 0xf45e: +case 0xf45f: +case 0xf460: +case 0xf461: +case 0xf462: +case 0xf463: +case 0xf464: +case 0xf465: +case 0xf466: +case 0xf467: +case 0xf468: +case 0xf469: +case 0xf46a: +case 0xf46b: +case 0xf46c: +case 0xf46d: +case 0xf46e: +case 0xf46f: +case 0xf470: +case 0xf471: +case 0xf472: +case 0xf473: +case 0xf474: +case 0xf475: +case 0xf476: +case 0xf477: +case 0xf478: +case 0xf479: +case 0xf47a: +case 0xf47b: +case 0xf47c: +case 0xf47d: +case 0xf47e: +case 0xf47f: +case 0xf480: +case 0xf481: +case 0xf482: +case 0xf483: +case 0xf484: +case 0xf485: +case 0xf486: +case 0xf487: +case 0xf488: +case 0xf489: +case 0xf48a: +case 0xf48b: +case 0xf48c: +case 0xf48d: +case 0xf48e: +case 0xf48f: +case 0xf490: +case 0xf491: +case 0xf492: +case 0xf493: +case 0xf494: +case 0xf495: +case 0xf496: +case 0xf497: +case 0xf498: +case 0xf499: +case 0xf49a: +case 0xf49b: +case 0xf49c: +case 0xf49d: +case 0xf49e: +case 0xf49f: +case 0xf4a0: +case 0xf4a1: +case 0xf4a2: +case 0xf4a3: +case 0xf4a4: +case 0xf4a5: +case 0xf4a6: +case 0xf4a7: +case 0xf4a8: +case 0xf4a9: +case 0xf4aa: +case 0xf4ab: +case 0xf4ac: +case 0xf4ad: +case 0xf4ae: +case 0xf4af: +case 0xf4b0: +case 0xf4b1: +case 0xf4b2: +case 0xf4b3: +case 0xf4b4: +case 0xf4b5: +case 0xf4b6: +case 0xf4b7: +case 0xf4b8: +case 0xf4b9: +case 0xf4ba: +case 0xf4bb: +case 0xf4bc: +case 0xf4bd: +case 0xf4be: +case 0xf4bf: +case 0xf4c0: +case 0xf4c1: +case 0xf4c2: +case 0xf4c3: +case 0xf4c4: +case 0xf4c5: +case 0xf4c6: +case 0xf4c7: +case 0xf4c8: +case 0xf4c9: +case 0xf4ca: +case 0xf4cb: +case 0xf4cc: +case 0xf4cd: +case 0xf4ce: +case 0xf4cf: +case 0xf4d0: +case 0xf4d1: +case 0xf4d2: +case 0xf4d3: +case 0xf4d4: +case 0xf4d5: +case 0xf4d6: +case 0xf4d7: +case 0xf4d8: +case 0xf4d9: +case 0xf4da: +case 0xf4db: +case 0xf4dc: +case 0xf4dd: +case 0xf4de: +case 0xf4df: +case 0xf4e0: +case 0xf4e1: +case 0xf4e2: +case 0xf4e3: +case 0xf4e4: +case 0xf4e5: +case 0xf4e6: +case 0xf4e7: +case 0xf4e8: +case 0xf4e9: +case 0xf4ea: +case 0xf4eb: +case 0xf4ec: +case 0xf4ed: +case 0xf4ee: +case 0xf4ef: +case 0xf4f0: +case 0xf4f1: +case 0xf4f2: +case 0xf4f3: +case 0xf4f4: +case 0xf4f5: +case 0xf4f6: +case 0xf4f7: +case 0xf4f8: +case 0xf4f9: +case 0xf4fa: +case 0xf4fb: +case 0xf4fc: +case 0xf4fd: +case 0xf4fe: +case 0xf4ff: +case 0xf500: +case 0xf501: +case 0xf502: +case 0xf503: +case 0xf504: +case 0xf505: +case 0xf506: +case 0xf507: +case 0xf508: +case 0xf509: +case 0xf50a: +case 0xf50b: +case 0xf50c: +case 0xf50d: +case 0xf50e: +case 0xf50f: +case 0xf510: +case 0xf511: +case 0xf512: +case 0xf513: +case 0xf514: +case 0xf515: +case 0xf516: +case 0xf517: +case 0xf518: +case 0xf519: +case 0xf51a: +case 0xf51b: +case 0xf51c: +case 0xf51d: +case 0xf51e: +case 0xf51f: +case 0xf520: +case 0xf521: +case 0xf522: +case 0xf523: +case 0xf524: +case 0xf525: +case 0xf526: +case 0xf527: +case 0xf528: +case 0xf529: +case 0xf52a: +case 0xf52b: +case 0xf52c: +case 0xf52d: +case 0xf52e: +case 0xf52f: +case 0xf530: +case 0xf531: +case 0xf532: +case 0xf533: +case 0xf534: +case 0xf535: +case 0xf536: +case 0xf537: +case 0xf538: +case 0xf539: +case 0xf53a: +case 0xf53b: +case 0xf53c: +case 0xf53d: +case 0xf53e: +case 0xf53f: +case 0xf540: +case 0xf541: +case 0xf542: +case 0xf543: +case 0xf544: +case 0xf545: +case 0xf546: +case 0xf547: +case 0xf548: +case 0xf549: +case 0xf54a: +case 0xf54b: +case 0xf54c: +case 0xf54d: +case 0xf54e: +case 0xf54f: +case 0xf550: +case 0xf551: +case 0xf552: +case 0xf553: +case 0xf554: +case 0xf555: +case 0xf556: +case 0xf557: +case 0xf558: +case 0xf559: +case 0xf55a: +case 0xf55b: +case 0xf55c: +case 0xf55d: +case 0xf55e: +case 0xf55f: +case 0xf560: +case 0xf561: +case 0xf562: +case 0xf563: +case 0xf564: +case 0xf565: +case 0xf566: +case 0xf567: +case 0xf568: +case 0xf569: +case 0xf56a: +case 0xf56b: +case 0xf56c: +case 0xf56d: +case 0xf56e: +case 0xf56f: +case 0xf570: +case 0xf571: +case 0xf572: +case 0xf573: +case 0xf574: +case 0xf575: +case 0xf576: +case 0xf577: +case 0xf578: +case 0xf579: +case 0xf57a: +case 0xf57b: +case 0xf57c: +case 0xf57d: +case 0xf57e: +case 0xf57f: +case 0xf580: +case 0xf581: +case 0xf582: +case 0xf583: +case 0xf584: +case 0xf585: +case 0xf586: +case 0xf587: +case 0xf588: +case 0xf589: +case 0xf58a: +case 0xf58b: +case 0xf58c: +case 0xf58d: +case 0xf58e: +case 0xf58f: +case 0xf590: +case 0xf591: +case 0xf592: +case 0xf593: +case 0xf594: +case 0xf595: +case 0xf596: +case 0xf597: +case 0xf598: +case 0xf599: +case 0xf59a: +case 0xf59b: +case 0xf59c: +case 0xf59d: +case 0xf59e: +case 0xf59f: +case 0xf5a0: +case 0xf5a1: +case 0xf5a2: +case 0xf5a3: +case 0xf5a4: +case 0xf5a5: +case 0xf5a6: +case 0xf5a7: +case 0xf5a8: +case 0xf5a9: +case 0xf5aa: +case 0xf5ab: +case 0xf5ac: +case 0xf5ad: +case 0xf5ae: +case 0xf5af: +case 0xf5b0: +case 0xf5b1: +case 0xf5b2: +case 0xf5b3: +case 0xf5b4: +case 0xf5b5: +case 0xf5b6: +case 0xf5b7: +case 0xf5b8: +case 0xf5b9: +case 0xf5ba: +case 0xf5bb: +case 0xf5bc: +case 0xf5bd: +case 0xf5be: +case 0xf5bf: +case 0xf5c0: +case 0xf5c1: +case 0xf5c2: +case 0xf5c3: +case 0xf5c4: +case 0xf5c5: +case 0xf5c6: +case 0xf5c7: +case 0xf5c8: +case 0xf5c9: +case 0xf5ca: +case 0xf5cb: +case 0xf5cc: +case 0xf5cd: +case 0xf5ce: +case 0xf5cf: +case 0xf5d0: +case 0xf5d1: +case 0xf5d2: +case 0xf5d3: +case 0xf5d4: +case 0xf5d5: +case 0xf5d6: +case 0xf5d7: +case 0xf5d8: +case 0xf5d9: +case 0xf5da: +case 0xf5db: +case 0xf5dc: +case 0xf5dd: +case 0xf5de: +case 0xf5df: +case 0xf5e0: +case 0xf5e1: +case 0xf5e2: +case 0xf5e3: +case 0xf5e4: +case 0xf5e5: +case 0xf5e6: +case 0xf5e7: +case 0xf5e8: +case 0xf5e9: +case 0xf5ea: +case 0xf5eb: +case 0xf5ec: +case 0xf5ed: +case 0xf5ee: +case 0xf5ef: +case 0xf5f0: +case 0xf5f1: +case 0xf5f2: +case 0xf5f3: +case 0xf5f4: +case 0xf5f5: +case 0xf5f6: +case 0xf5f7: +case 0xf5f8: +case 0xf5f9: +case 0xf5fa: +case 0xf5fb: +case 0xf5fc: +case 0xf5fd: +case 0xf5fe: +case 0xf5ff: +case 0xf600: +case 0xf601: +case 0xf602: +case 0xf603: +case 0xf604: +case 0xf605: +case 0xf606: +case 0xf607: +case 0xf608: +case 0xf609: +case 0xf60a: +case 0xf60b: +case 0xf60c: +case 0xf60d: +case 0xf60e: +case 0xf60f: +case 0xf610: +case 0xf611: +case 0xf612: +case 0xf613: +case 0xf614: +case 0xf615: +case 0xf616: +case 0xf617: +case 0xf618: +case 0xf619: +case 0xf61a: +case 0xf61b: +case 0xf61c: +case 0xf61d: +case 0xf61e: +case 0xf61f: +case 0xf620: +case 0xf621: +case 0xf622: +case 0xf623: +case 0xf624: +case 0xf625: +case 0xf626: +case 0xf627: +case 0xf628: +case 0xf629: +case 0xf62a: +case 0xf62b: +case 0xf62c: +case 0xf62d: +case 0xf62e: +case 0xf62f: +case 0xf630: +case 0xf631: +case 0xf632: +case 0xf633: +case 0xf634: +case 0xf635: +case 0xf636: +case 0xf637: +case 0xf638: +case 0xf639: +case 0xf63a: +case 0xf63b: +case 0xf63c: +case 0xf63d: +case 0xf63e: +case 0xf63f: +case 0xf640: +case 0xf641: +case 0xf642: +case 0xf643: +case 0xf644: +case 0xf645: +case 0xf646: +case 0xf647: +case 0xf648: +case 0xf649: +case 0xf64a: +case 0xf64b: +case 0xf64c: +case 0xf64d: +case 0xf64e: +case 0xf64f: +case 0xf650: +case 0xf651: +case 0xf652: +case 0xf653: +case 0xf654: +case 0xf655: +case 0xf656: +case 0xf657: +case 0xf658: +case 0xf659: +case 0xf65a: +case 0xf65b: +case 0xf65c: +case 0xf65d: +case 0xf65e: +case 0xf65f: +case 0xf660: +case 0xf661: +case 0xf662: +case 0xf663: +case 0xf664: +case 0xf665: +case 0xf666: +case 0xf667: +case 0xf668: +case 0xf669: +case 0xf66a: +case 0xf66b: +case 0xf66c: +case 0xf66d: +case 0xf66e: +case 0xf66f: +case 0xf670: +case 0xf671: +case 0xf672: +case 0xf673: +case 0xf674: +case 0xf675: +case 0xf676: +case 0xf677: +case 0xf678: +case 0xf679: +case 0xf67a: +case 0xf67b: +case 0xf67c: +case 0xf67d: +case 0xf67e: +case 0xf67f: +case 0xf680: +case 0xf681: +case 0xf682: +case 0xf683: +case 0xf684: +case 0xf685: +case 0xf686: +case 0xf687: +case 0xf688: +case 0xf689: +case 0xf68a: +case 0xf68b: +case 0xf68c: +case 0xf68d: +case 0xf68e: +case 0xf68f: +case 0xf690: +case 0xf691: +case 0xf692: +case 0xf693: +case 0xf694: +case 0xf695: +case 0xf696: +case 0xf697: +case 0xf698: +case 0xf699: +case 0xf69a: +case 0xf69b: +case 0xf69c: +case 0xf69d: +case 0xf69e: +case 0xf69f: +case 0xf6a0: +case 0xf6a1: +case 0xf6a2: +case 0xf6a3: +case 0xf6a4: +case 0xf6a5: +case 0xf6a6: +case 0xf6a7: +case 0xf6a8: +case 0xf6a9: +case 0xf6aa: +case 0xf6ab: +case 0xf6ac: +case 0xf6ad: +case 0xf6ae: +case 0xf6af: +case 0xf6b0: +case 0xf6b1: +case 0xf6b2: +case 0xf6b3: +case 0xf6b4: +case 0xf6b5: +case 0xf6b6: +case 0xf6b7: +case 0xf6b8: +case 0xf6b9: +case 0xf6ba: +case 0xf6bb: +case 0xf6bc: +case 0xf6bd: +case 0xf6be: +case 0xf6bf: +case 0xf6c0: +case 0xf6c1: +case 0xf6c2: +case 0xf6c3: +case 0xf6c4: +case 0xf6c5: +case 0xf6c6: +case 0xf6c7: +case 0xf6c8: +case 0xf6c9: +case 0xf6ca: +case 0xf6cb: +case 0xf6cc: +case 0xf6cd: +case 0xf6ce: +case 0xf6cf: +case 0xf6d0: +case 0xf6d1: +case 0xf6d2: +case 0xf6d3: +case 0xf6d4: +case 0xf6d5: +case 0xf6d6: +case 0xf6d7: +case 0xf6d8: +case 0xf6d9: +case 0xf6da: +case 0xf6db: +case 0xf6dc: +case 0xf6dd: +case 0xf6de: +case 0xf6df: +case 0xf6e0: +case 0xf6e1: +case 0xf6e2: +case 0xf6e3: +case 0xf6e4: +case 0xf6e5: +case 0xf6e6: +case 0xf6e7: +case 0xf6e8: +case 0xf6e9: +case 0xf6ea: +case 0xf6eb: +case 0xf6ec: +case 0xf6ed: +case 0xf6ee: +case 0xf6ef: +case 0xf6f0: +case 0xf6f1: +case 0xf6f2: +case 0xf6f3: +case 0xf6f4: +case 0xf6f5: +case 0xf6f6: +case 0xf6f7: +case 0xf6f8: +case 0xf6f9: +case 0xf6fa: +case 0xf6fb: +case 0xf6fc: +case 0xf6fd: +case 0xf6fe: +case 0xf6ff: +case 0xf700: +case 0xf701: +case 0xf702: +case 0xf703: +case 0xf704: +case 0xf705: +case 0xf706: +case 0xf707: +case 0xf708: +case 0xf709: +case 0xf70a: +case 0xf70b: +case 0xf70c: +case 0xf70d: +case 0xf70e: +case 0xf70f: +case 0xf710: +case 0xf711: +case 0xf712: +case 0xf713: +case 0xf714: +case 0xf715: +case 0xf716: +case 0xf717: +case 0xf718: +case 0xf719: +case 0xf71a: +case 0xf71b: +case 0xf71c: +case 0xf71d: +case 0xf71e: +case 0xf71f: +case 0xf720: +case 0xf721: +case 0xf722: +case 0xf723: +case 0xf724: +case 0xf725: +case 0xf726: +case 0xf727: +case 0xf728: +case 0xf729: +case 0xf72a: +case 0xf72b: +case 0xf72c: +case 0xf72d: +case 0xf72e: +case 0xf72f: +case 0xf730: +case 0xf731: +case 0xf732: +case 0xf733: +case 0xf734: +case 0xf735: +case 0xf736: +case 0xf737: +case 0xf738: +case 0xf739: +case 0xf73a: +case 0xf73b: +case 0xf73c: +case 0xf73d: +case 0xf73e: +case 0xf73f: +case 0xf740: +case 0xf741: +case 0xf742: +case 0xf743: +case 0xf744: +case 0xf745: +case 0xf746: +case 0xf747: +case 0xf748: +case 0xf749: +case 0xf74a: +case 0xf74b: +case 0xf74c: +case 0xf74d: +case 0xf74e: +case 0xf74f: +case 0xf750: +case 0xf751: +case 0xf752: +case 0xf753: +case 0xf754: +case 0xf755: +case 0xf756: +case 0xf757: +case 0xf758: +case 0xf759: +case 0xf75a: +case 0xf75b: +case 0xf75c: +case 0xf75d: +case 0xf75e: +case 0xf75f: +case 0xf760: +case 0xf761: +case 0xf762: +case 0xf763: +case 0xf764: +case 0xf765: +case 0xf766: +case 0xf767: +case 0xf768: +case 0xf769: +case 0xf76a: +case 0xf76b: +case 0xf76c: +case 0xf76d: +case 0xf76e: +case 0xf76f: +case 0xf770: +case 0xf771: +case 0xf772: +case 0xf773: +case 0xf774: +case 0xf775: +case 0xf776: +case 0xf777: +case 0xf778: +case 0xf779: +case 0xf77a: +case 0xf77b: +case 0xf77c: +case 0xf77d: +case 0xf77e: +case 0xf77f: +case 0xf780: +case 0xf781: +case 0xf782: +case 0xf783: +case 0xf784: +case 0xf785: +case 0xf786: +case 0xf787: +case 0xf788: +case 0xf789: +case 0xf78a: +case 0xf78b: +case 0xf78c: +case 0xf78d: +case 0xf78e: +case 0xf78f: +case 0xf790: +case 0xf791: +case 0xf792: +case 0xf793: +case 0xf794: +case 0xf795: +case 0xf796: +case 0xf797: +case 0xf798: +case 0xf799: +case 0xf79a: +case 0xf79b: +case 0xf79c: +case 0xf79d: +case 0xf79e: +case 0xf79f: +case 0xf7a0: +case 0xf7a1: +case 0xf7a2: +case 0xf7a3: +case 0xf7a4: +case 0xf7a5: +case 0xf7a6: +case 0xf7a7: +case 0xf7a8: +case 0xf7a9: +case 0xf7aa: +case 0xf7ab: +case 0xf7ac: +case 0xf7ad: +case 0xf7ae: +case 0xf7af: +case 0xf7b0: +case 0xf7b1: +case 0xf7b2: +case 0xf7b3: +case 0xf7b4: +case 0xf7b5: +case 0xf7b6: +case 0xf7b7: +case 0xf7b8: +case 0xf7b9: +case 0xf7ba: +case 0xf7bb: +case 0xf7bc: +case 0xf7bd: +case 0xf7be: +case 0xf7bf: +case 0xf7c0: +case 0xf7c1: +case 0xf7c2: +case 0xf7c3: +case 0xf7c4: +case 0xf7c5: +case 0xf7c6: +case 0xf7c7: +case 0xf7c8: +case 0xf7c9: +case 0xf7ca: +case 0xf7cb: +case 0xf7cc: +case 0xf7cd: +case 0xf7ce: +case 0xf7cf: +case 0xf7d0: +case 0xf7d1: +case 0xf7d2: +case 0xf7d3: +case 0xf7d4: +case 0xf7d5: +case 0xf7d6: +case 0xf7d7: +case 0xf7d8: +case 0xf7d9: +case 0xf7da: +case 0xf7db: +case 0xf7dc: +case 0xf7dd: +case 0xf7de: +case 0xf7df: +case 0xf7e0: +case 0xf7e1: +case 0xf7e2: +case 0xf7e3: +case 0xf7e4: +case 0xf7e5: +case 0xf7e6: +case 0xf7e7: +case 0xf7e8: +case 0xf7e9: +case 0xf7ea: +case 0xf7eb: +case 0xf7ec: +case 0xf7ed: +case 0xf7ee: +case 0xf7ef: +case 0xf7f0: +case 0xf7f1: +case 0xf7f2: +case 0xf7f3: +case 0xf7f4: +case 0xf7f5: +case 0xf7f6: +case 0xf7f7: +case 0xf7f8: +case 0xf7f9: +case 0xf7fa: +case 0xf7fb: +case 0xf7fc: +case 0xf7fd: +case 0xf7fe: +case 0xf7ff: +case 0xf800: +case 0xf801: +case 0xf802: +case 0xf803: +case 0xf804: +case 0xf805: +case 0xf806: +case 0xf807: +case 0xf808: +case 0xf809: +case 0xf80a: +case 0xf80b: +case 0xf80c: +case 0xf80d: +case 0xf80e: +case 0xf80f: +case 0xf810: +case 0xf811: +case 0xf812: +case 0xf813: +case 0xf814: +case 0xf815: +case 0xf816: +case 0xf817: +case 0xf818: +case 0xf819: +case 0xf81a: +case 0xf81b: +case 0xf81c: +case 0xf81d: +case 0xf81e: +case 0xf81f: +case 0xf820: +case 0xf821: +case 0xf822: +case 0xf823: +case 0xf824: +case 0xf825: +case 0xf826: +case 0xf827: +case 0xf828: +case 0xf829: +case 0xf82a: +case 0xf82b: +case 0xf82c: +case 0xf82d: +case 0xf82e: +case 0xf82f: +case 0xf830: +case 0xf831: +case 0xf832: +case 0xf833: +case 0xf834: +case 0xf835: +case 0xf836: +case 0xf837: +case 0xf838: +case 0xf839: +case 0xf83a: +case 0xf83b: +case 0xf83c: +case 0xf83d: +case 0xf83e: +case 0xf83f: +case 0xf840: +case 0xf841: +case 0xf842: +case 0xf843: +case 0xf844: +case 0xf845: +case 0xf846: +case 0xf847: +case 0xf848: +case 0xf849: +case 0xf84a: +case 0xf84b: +case 0xf84c: +case 0xf84d: +case 0xf84e: +case 0xf84f: +case 0xf850: +case 0xf851: +case 0xf852: +case 0xf853: +case 0xf854: +case 0xf855: +case 0xf856: +case 0xf857: +case 0xf858: +case 0xf859: +case 0xf85a: +case 0xf85b: +case 0xf85c: +case 0xf85d: +case 0xf85e: +case 0xf85f: +case 0xf860: +case 0xf861: +case 0xf862: +case 0xf863: +case 0xf864: +case 0xf865: +case 0xf866: +case 0xf867: +case 0xf868: +case 0xf869: +case 0xf86a: +case 0xf86b: +case 0xf86c: +case 0xf86d: +case 0xf86e: +case 0xf86f: +case 0xf870: +case 0xf871: +case 0xf872: +case 0xf873: +case 0xf874: +case 0xf875: +case 0xf876: +case 0xf877: +case 0xf878: +case 0xf879: +case 0xf87a: +case 0xf87b: +case 0xf87c: +case 0xf87d: +case 0xf87e: +case 0xf87f: +case 0xf880: +case 0xf881: +case 0xf882: +case 0xf883: +case 0xf884: +case 0xf885: +case 0xf886: +case 0xf887: +case 0xf888: +case 0xf889: +case 0xf88a: +case 0xf88b: +case 0xf88c: +case 0xf88d: +case 0xf88e: +case 0xf88f: +case 0xf890: +case 0xf891: +case 0xf892: +case 0xf893: +case 0xf894: +case 0xf895: +case 0xf896: +case 0xf897: +case 0xf898: +case 0xf899: +case 0xf89a: +case 0xf89b: +case 0xf89c: +case 0xf89d: +case 0xf89e: +case 0xf89f: +case 0xf8a0: +case 0xf8a1: +case 0xf8a2: +case 0xf8a3: +case 0xf8a4: +case 0xf8a5: +case 0xf8a6: +case 0xf8a7: +case 0xf8a8: +case 0xf8a9: +case 0xf8aa: +case 0xf8ab: +case 0xf8ac: +case 0xf8ad: +case 0xf8ae: +case 0xf8af: +case 0xf8b0: +case 0xf8b1: +case 0xf8b2: +case 0xf8b3: +case 0xf8b4: +case 0xf8b5: +case 0xf8b6: +case 0xf8b7: +case 0xf8b8: +case 0xf8b9: +case 0xf8ba: +case 0xf8bb: +case 0xf8bc: +case 0xf8bd: +case 0xf8be: +case 0xf8bf: +case 0xf8c0: +case 0xf8c1: +case 0xf8c2: +case 0xf8c3: +case 0xf8c4: +case 0xf8c5: +case 0xf8c6: +case 0xf8c7: +case 0xf8c8: +case 0xf8c9: +case 0xf8ca: +case 0xf8cb: +case 0xf8cc: +case 0xf8cd: +case 0xf8ce: +case 0xf8cf: +case 0xf8d0: +case 0xf8d1: +case 0xf8d2: +case 0xf8d3: +case 0xf8d4: +case 0xf8d5: +case 0xf8d6: +case 0xf8d7: +case 0xf8d8: +case 0xf8d9: +case 0xf8da: +case 0xf8db: +case 0xf8dc: +case 0xf8dd: +case 0xf8de: +case 0xf8df: +case 0xf8e0: +case 0xf8e1: +case 0xf8e2: +case 0xf8e3: +case 0xf8e4: +case 0xf8e5: +case 0xf8e6: +case 0xf8e7: +case 0xf8e8: +case 0xf8e9: +case 0xf8ea: +case 0xf8eb: +case 0xf8ec: +case 0xf8ed: +case 0xf8ee: +case 0xf8ef: +case 0xf8f0: +case 0xf8f1: +case 0xf8f2: +case 0xf8f3: +case 0xf8f4: +case 0xf8f5: +case 0xf8f6: +case 0xf8f7: +case 0xf8f8: +case 0xf8f9: +case 0xf8fa: +case 0xf8fb: +case 0xf8fc: +case 0xf8fd: +case 0xf8fe: +case 0xf8ff: +case 0xf900: +case 0xf901: +case 0xf902: +case 0xf903: +case 0xf904: +case 0xf905: +case 0xf906: +case 0xf907: +case 0xf908: +case 0xf909: +case 0xf90a: +case 0xf90b: +case 0xf90c: +case 0xf90d: +case 0xf90e: +case 0xf90f: +case 0xf910: +case 0xf911: +case 0xf912: +case 0xf913: +case 0xf914: +case 0xf915: +case 0xf916: +case 0xf917: +case 0xf918: +case 0xf919: +case 0xf91a: +case 0xf91b: +case 0xf91c: +case 0xf91d: +case 0xf91e: +case 0xf91f: +case 0xf920: +case 0xf921: +case 0xf922: +case 0xf923: +case 0xf924: +case 0xf925: +case 0xf926: +case 0xf927: +case 0xf928: +case 0xf929: +case 0xf92a: +case 0xf92b: +case 0xf92c: +case 0xf92d: +case 0xf92e: +case 0xf92f: +case 0xf930: +case 0xf931: +case 0xf932: +case 0xf933: +case 0xf934: +case 0xf935: +case 0xf936: +case 0xf937: +case 0xf938: +case 0xf939: +case 0xf93a: +case 0xf93b: +case 0xf93c: +case 0xf93d: +case 0xf93e: +case 0xf93f: +case 0xf940: +case 0xf941: +case 0xf942: +case 0xf943: +case 0xf944: +case 0xf945: +case 0xf946: +case 0xf947: +case 0xf948: +case 0xf949: +case 0xf94a: +case 0xf94b: +case 0xf94c: +case 0xf94d: +case 0xf94e: +case 0xf94f: +case 0xf950: +case 0xf951: +case 0xf952: +case 0xf953: +case 0xf954: +case 0xf955: +case 0xf956: +case 0xf957: +case 0xf958: +case 0xf959: +case 0xf95a: +case 0xf95b: +case 0xf95c: +case 0xf95d: +case 0xf95e: +case 0xf95f: +case 0xf960: +case 0xf961: +case 0xf962: +case 0xf963: +case 0xf964: +case 0xf965: +case 0xf966: +case 0xf967: +case 0xf968: +case 0xf969: +case 0xf96a: +case 0xf96b: +case 0xf96c: +case 0xf96d: +case 0xf96e: +case 0xf96f: +case 0xf970: +case 0xf971: +case 0xf972: +case 0xf973: +case 0xf974: +case 0xf975: +case 0xf976: +case 0xf977: +case 0xf978: +case 0xf979: +case 0xf97a: +case 0xf97b: +case 0xf97c: +case 0xf97d: +case 0xf97e: +case 0xf97f: +case 0xf980: +case 0xf981: +case 0xf982: +case 0xf983: +case 0xf984: +case 0xf985: +case 0xf986: +case 0xf987: +case 0xf988: +case 0xf989: +case 0xf98a: +case 0xf98b: +case 0xf98c: +case 0xf98d: +case 0xf98e: +case 0xf98f: +case 0xf990: +case 0xf991: +case 0xf992: +case 0xf993: +case 0xf994: +case 0xf995: +case 0xf996: +case 0xf997: +case 0xf998: +case 0xf999: +case 0xf99a: +case 0xf99b: +case 0xf99c: +case 0xf99d: +case 0xf99e: +case 0xf99f: +case 0xf9a0: +case 0xf9a1: +case 0xf9a2: +case 0xf9a3: +case 0xf9a4: +case 0xf9a5: +case 0xf9a6: +case 0xf9a7: +case 0xf9a8: +case 0xf9a9: +case 0xf9aa: +case 0xf9ab: +case 0xf9ac: +case 0xf9ad: +case 0xf9ae: +case 0xf9af: +case 0xf9b0: +case 0xf9b1: +case 0xf9b2: +case 0xf9b3: +case 0xf9b4: +case 0xf9b5: +case 0xf9b6: +case 0xf9b7: +case 0xf9b8: +case 0xf9b9: +case 0xf9ba: +case 0xf9bb: +case 0xf9bc: +case 0xf9bd: +case 0xf9be: +case 0xf9bf: +case 0xf9c0: +case 0xf9c1: +case 0xf9c2: +case 0xf9c3: +case 0xf9c4: +case 0xf9c5: +case 0xf9c6: +case 0xf9c7: +case 0xf9c8: +case 0xf9c9: +case 0xf9ca: +case 0xf9cb: +case 0xf9cc: +case 0xf9cd: +case 0xf9ce: +case 0xf9cf: +case 0xf9d0: +case 0xf9d1: +case 0xf9d2: +case 0xf9d3: +case 0xf9d4: +case 0xf9d5: +case 0xf9d6: +case 0xf9d7: +case 0xf9d8: +case 0xf9d9: +case 0xf9da: +case 0xf9db: +case 0xf9dc: +case 0xf9dd: +case 0xf9de: +case 0xf9df: +case 0xf9e0: +case 0xf9e1: +case 0xf9e2: +case 0xf9e3: +case 0xf9e4: +case 0xf9e5: +case 0xf9e6: +case 0xf9e7: +case 0xf9e8: +case 0xf9e9: +case 0xf9ea: +case 0xf9eb: +case 0xf9ec: +case 0xf9ed: +case 0xf9ee: +case 0xf9ef: +case 0xf9f0: +case 0xf9f1: +case 0xf9f2: +case 0xf9f3: +case 0xf9f4: +case 0xf9f5: +case 0xf9f6: +case 0xf9f7: +case 0xf9f8: +case 0xf9f9: +case 0xf9fa: +case 0xf9fb: +case 0xf9fc: +case 0xf9fd: +case 0xf9fe: +case 0xf9ff: +case 0xfa00: +case 0xfa01: +case 0xfa02: +case 0xfa03: +case 0xfa04: +case 0xfa05: +case 0xfa06: +case 0xfa07: +case 0xfa08: +case 0xfa09: +case 0xfa0a: +case 0xfa0b: +case 0xfa0c: +case 0xfa0d: +case 0xfa0e: +case 0xfa0f: +case 0xfa10: +case 0xfa11: +case 0xfa12: +case 0xfa13: +case 0xfa14: +case 0xfa15: +case 0xfa16: +case 0xfa17: +case 0xfa18: +case 0xfa19: +case 0xfa1a: +case 0xfa1b: +case 0xfa1c: +case 0xfa1d: +case 0xfa1e: +case 0xfa1f: +case 0xfa20: +case 0xfa21: +case 0xfa22: +case 0xfa23: +case 0xfa24: +case 0xfa25: +case 0xfa26: +case 0xfa27: +case 0xfa28: +case 0xfa29: +case 0xfa2a: +case 0xfa2b: +case 0xfa2c: +case 0xfa2d: +case 0xfa2e: +case 0xfa2f: +case 0xfa30: +case 0xfa31: +case 0xfa32: +case 0xfa33: +case 0xfa34: +case 0xfa35: +case 0xfa36: +case 0xfa37: +case 0xfa38: +case 0xfa39: +case 0xfa3a: +case 0xfa3b: +case 0xfa3c: +case 0xfa3d: +case 0xfa3e: +case 0xfa3f: +case 0xfa40: +case 0xfa41: +case 0xfa42: +case 0xfa43: +case 0xfa44: +case 0xfa45: +case 0xfa46: +case 0xfa47: +case 0xfa48: +case 0xfa49: +case 0xfa4a: +case 0xfa4b: +case 0xfa4c: +case 0xfa4d: +case 0xfa4e: +case 0xfa4f: +case 0xfa50: +case 0xfa51: +case 0xfa52: +case 0xfa53: +case 0xfa54: +case 0xfa55: +case 0xfa56: +case 0xfa57: +case 0xfa58: +case 0xfa59: +case 0xfa5a: +case 0xfa5b: +case 0xfa5c: +case 0xfa5d: +case 0xfa5e: +case 0xfa5f: +case 0xfa60: +case 0xfa61: +case 0xfa62: +case 0xfa63: +case 0xfa64: +case 0xfa65: +case 0xfa66: +case 0xfa67: +case 0xfa68: +case 0xfa69: +case 0xfa6a: +case 0xfa6b: +case 0xfa6c: +case 0xfa6d: +case 0xfa6e: +case 0xfa6f: +case 0xfa70: +case 0xfa71: +case 0xfa72: +case 0xfa73: +case 0xfa74: +case 0xfa75: +case 0xfa76: +case 0xfa77: +case 0xfa78: +case 0xfa79: +case 0xfa7a: +case 0xfa7b: +case 0xfa7c: +case 0xfa7d: +case 0xfa7e: +case 0xfa7f: +case 0xfa80: +case 0xfa81: +case 0xfa82: +case 0xfa83: +case 0xfa84: +case 0xfa85: +case 0xfa86: +case 0xfa87: +case 0xfa88: +case 0xfa89: +case 0xfa8a: +case 0xfa8b: +case 0xfa8c: +case 0xfa8d: +case 0xfa8e: +case 0xfa8f: +case 0xfa90: +case 0xfa91: +case 0xfa92: +case 0xfa93: +case 0xfa94: +case 0xfa95: +case 0xfa96: +case 0xfa97: +case 0xfa98: +case 0xfa99: +case 0xfa9a: +case 0xfa9b: +case 0xfa9c: +case 0xfa9d: +case 0xfa9e: +case 0xfa9f: +case 0xfaa0: +case 0xfaa1: +case 0xfaa2: +case 0xfaa3: +case 0xfaa4: +case 0xfaa5: +case 0xfaa6: +case 0xfaa7: +case 0xfaa8: +case 0xfaa9: +case 0xfaaa: +case 0xfaab: +case 0xfaac: +case 0xfaad: +case 0xfaae: +case 0xfaaf: +case 0xfab0: +case 0xfab1: +case 0xfab2: +case 0xfab3: +case 0xfab4: +case 0xfab5: +case 0xfab6: +case 0xfab7: +case 0xfab8: +case 0xfab9: +case 0xfaba: +case 0xfabb: +case 0xfabc: +case 0xfabd: +case 0xfabe: +case 0xfabf: +case 0xfac0: +case 0xfac1: +case 0xfac2: +case 0xfac3: +case 0xfac4: +case 0xfac5: +case 0xfac6: +case 0xfac7: +case 0xfac8: +case 0xfac9: +case 0xfaca: +case 0xfacb: +case 0xfacc: +case 0xfacd: +case 0xface: +case 0xfacf: +case 0xfad0: +case 0xfad1: +case 0xfad2: +case 0xfad3: +case 0xfad4: +case 0xfad5: +case 0xfad6: +case 0xfad7: +case 0xfad8: +case 0xfad9: +case 0xfada: +case 0xfadb: +case 0xfadc: +case 0xfadd: +case 0xfade: +case 0xfadf: +case 0xfae0: +case 0xfae1: +case 0xfae2: +case 0xfae3: +case 0xfae4: +case 0xfae5: +case 0xfae6: +case 0xfae7: +case 0xfae8: +case 0xfae9: +case 0xfaea: +case 0xfaeb: +case 0xfaec: +case 0xfaed: +case 0xfaee: +case 0xfaef: +case 0xfaf0: +case 0xfaf1: +case 0xfaf2: +case 0xfaf3: +case 0xfaf4: +case 0xfaf5: +case 0xfaf6: +case 0xfaf7: +case 0xfaf8: +case 0xfaf9: +case 0xfafa: +case 0xfafb: +case 0xfafc: +case 0xfafd: +case 0xfafe: +case 0xfaff: +case 0xfb00: +case 0xfb01: +case 0xfb02: +case 0xfb03: +case 0xfb04: +case 0xfb05: +case 0xfb06: +case 0xfb07: +case 0xfb08: +case 0xfb09: +case 0xfb0a: +case 0xfb0b: +case 0xfb0c: +case 0xfb0d: +case 0xfb0e: +case 0xfb0f: +case 0xfb10: +case 0xfb11: +case 0xfb12: +case 0xfb13: +case 0xfb14: +case 0xfb15: +case 0xfb16: +case 0xfb17: +case 0xfb18: +case 0xfb19: +case 0xfb1a: +case 0xfb1b: +case 0xfb1c: +case 0xfb1d: +case 0xfb1e: +case 0xfb1f: +case 0xfb20: +case 0xfb21: +case 0xfb22: +case 0xfb23: +case 0xfb24: +case 0xfb25: +case 0xfb26: +case 0xfb27: +case 0xfb28: +case 0xfb29: +case 0xfb2a: +case 0xfb2b: +case 0xfb2c: +case 0xfb2d: +case 0xfb2e: +case 0xfb2f: +case 0xfb30: +case 0xfb31: +case 0xfb32: +case 0xfb33: +case 0xfb34: +case 0xfb35: +case 0xfb36: +case 0xfb37: +case 0xfb38: +case 0xfb39: +case 0xfb3a: +case 0xfb3b: +case 0xfb3c: +case 0xfb3d: +case 0xfb3e: +case 0xfb3f: +case 0xfb40: +case 0xfb41: +case 0xfb42: +case 0xfb43: +case 0xfb44: +case 0xfb45: +case 0xfb46: +case 0xfb47: +case 0xfb48: +case 0xfb49: +case 0xfb4a: +case 0xfb4b: +case 0xfb4c: +case 0xfb4d: +case 0xfb4e: +case 0xfb4f: +case 0xfb50: +case 0xfb51: +case 0xfb52: +case 0xfb53: +case 0xfb54: +case 0xfb55: +case 0xfb56: +case 0xfb57: +case 0xfb58: +case 0xfb59: +case 0xfb5a: +case 0xfb5b: +case 0xfb5c: +case 0xfb5d: +case 0xfb5e: +case 0xfb5f: +case 0xfb60: +case 0xfb61: +case 0xfb62: +case 0xfb63: +case 0xfb64: +case 0xfb65: +case 0xfb66: +case 0xfb67: +case 0xfb68: +case 0xfb69: +case 0xfb6a: +case 0xfb6b: +case 0xfb6c: +case 0xfb6d: +case 0xfb6e: +case 0xfb6f: +case 0xfb70: +case 0xfb71: +case 0xfb72: +case 0xfb73: +case 0xfb74: +case 0xfb75: +case 0xfb76: +case 0xfb77: +case 0xfb78: +case 0xfb79: +case 0xfb7a: +case 0xfb7b: +case 0xfb7c: +case 0xfb7d: +case 0xfb7e: +case 0xfb7f: +case 0xfb80: +case 0xfb81: +case 0xfb82: +case 0xfb83: +case 0xfb84: +case 0xfb85: +case 0xfb86: +case 0xfb87: +case 0xfb88: +case 0xfb89: +case 0xfb8a: +case 0xfb8b: +case 0xfb8c: +case 0xfb8d: +case 0xfb8e: +case 0xfb8f: +case 0xfb90: +case 0xfb91: +case 0xfb92: +case 0xfb93: +case 0xfb94: +case 0xfb95: +case 0xfb96: +case 0xfb97: +case 0xfb98: +case 0xfb99: +case 0xfb9a: +case 0xfb9b: +case 0xfb9c: +case 0xfb9d: +case 0xfb9e: +case 0xfb9f: +case 0xfba0: +case 0xfba1: +case 0xfba2: +case 0xfba3: +case 0xfba4: +case 0xfba5: +case 0xfba6: +case 0xfba7: +case 0xfba8: +case 0xfba9: +case 0xfbaa: +case 0xfbab: +case 0xfbac: +case 0xfbad: +case 0xfbae: +case 0xfbaf: +case 0xfbb0: +case 0xfbb1: +case 0xfbb2: +case 0xfbb3: +case 0xfbb4: +case 0xfbb5: +case 0xfbb6: +case 0xfbb7: +case 0xfbb8: +case 0xfbb9: +case 0xfbba: +case 0xfbbb: +case 0xfbbc: +case 0xfbbd: +case 0xfbbe: +case 0xfbbf: +case 0xfbc0: +case 0xfbc1: +case 0xfbc2: +case 0xfbc3: +case 0xfbc4: +case 0xfbc5: +case 0xfbc6: +case 0xfbc7: +case 0xfbc8: +case 0xfbc9: +case 0xfbca: +case 0xfbcb: +case 0xfbcc: +case 0xfbcd: +case 0xfbce: +case 0xfbcf: +case 0xfbd0: +case 0xfbd1: +case 0xfbd2: +case 0xfbd3: +case 0xfbd4: +case 0xfbd5: +case 0xfbd6: +case 0xfbd7: +case 0xfbd8: +case 0xfbd9: +case 0xfbda: +case 0xfbdb: +case 0xfbdc: +case 0xfbdd: +case 0xfbde: +case 0xfbdf: +case 0xfbe0: +case 0xfbe1: +case 0xfbe2: +case 0xfbe3: +case 0xfbe4: +case 0xfbe5: +case 0xfbe6: +case 0xfbe7: +case 0xfbe8: +case 0xfbe9: +case 0xfbea: +case 0xfbeb: +case 0xfbec: +case 0xfbed: +case 0xfbee: +case 0xfbef: +case 0xfbf0: +case 0xfbf1: +case 0xfbf2: +case 0xfbf3: +case 0xfbf4: +case 0xfbf5: +case 0xfbf6: +case 0xfbf7: +case 0xfbf8: +case 0xfbf9: +case 0xfbfa: +case 0xfbfb: +case 0xfbfc: +case 0xfbfd: +case 0xfbfe: +case 0xfbff: +case 0xfc00: +case 0xfc01: +case 0xfc02: +case 0xfc03: +case 0xfc04: +case 0xfc05: +case 0xfc06: +case 0xfc07: +case 0xfc08: +case 0xfc09: +case 0xfc0a: +case 0xfc0b: +case 0xfc0c: +case 0xfc0d: +case 0xfc0e: +case 0xfc0f: +case 0xfc10: +case 0xfc11: +case 0xfc12: +case 0xfc13: +case 0xfc14: +case 0xfc15: +case 0xfc16: +case 0xfc17: +case 0xfc18: +case 0xfc19: +case 0xfc1a: +case 0xfc1b: +case 0xfc1c: +case 0xfc1d: +case 0xfc1e: +case 0xfc1f: +case 0xfc20: +case 0xfc21: +case 0xfc22: +case 0xfc23: +case 0xfc24: +case 0xfc25: +case 0xfc26: +case 0xfc27: +case 0xfc28: +case 0xfc29: +case 0xfc2a: +case 0xfc2b: +case 0xfc2c: +case 0xfc2d: +case 0xfc2e: +case 0xfc2f: +case 0xfc30: +case 0xfc31: +case 0xfc32: +case 0xfc33: +case 0xfc34: +case 0xfc35: +case 0xfc36: +case 0xfc37: +case 0xfc38: +case 0xfc39: +case 0xfc3a: +case 0xfc3b: +case 0xfc3c: +case 0xfc3d: +case 0xfc3e: +case 0xfc3f: +case 0xfc40: +case 0xfc41: +case 0xfc42: +case 0xfc43: +case 0xfc44: +case 0xfc45: +case 0xfc46: +case 0xfc47: +case 0xfc48: +case 0xfc49: +case 0xfc4a: +case 0xfc4b: +case 0xfc4c: +case 0xfc4d: +case 0xfc4e: +case 0xfc4f: +case 0xfc50: +case 0xfc51: +case 0xfc52: +case 0xfc53: +case 0xfc54: +case 0xfc55: +case 0xfc56: +case 0xfc57: +case 0xfc58: +case 0xfc59: +case 0xfc5a: +case 0xfc5b: +case 0xfc5c: +case 0xfc5d: +case 0xfc5e: +case 0xfc5f: +case 0xfc60: +case 0xfc61: +case 0xfc62: +case 0xfc63: +case 0xfc64: +case 0xfc65: +case 0xfc66: +case 0xfc67: +case 0xfc68: +case 0xfc69: +case 0xfc6a: +case 0xfc6b: +case 0xfc6c: +case 0xfc6d: +case 0xfc6e: +case 0xfc6f: +case 0xfc70: +case 0xfc71: +case 0xfc72: +case 0xfc73: +case 0xfc74: +case 0xfc75: +case 0xfc76: +case 0xfc77: +case 0xfc78: +case 0xfc79: +case 0xfc7a: +case 0xfc7b: +case 0xfc7c: +case 0xfc7d: +case 0xfc7e: +case 0xfc7f: +case 0xfc80: +case 0xfc81: +case 0xfc82: +case 0xfc83: +case 0xfc84: +case 0xfc85: +case 0xfc86: +case 0xfc87: +case 0xfc88: +case 0xfc89: +case 0xfc8a: +case 0xfc8b: +case 0xfc8c: +case 0xfc8d: +case 0xfc8e: +case 0xfc8f: +case 0xfc90: +case 0xfc91: +case 0xfc92: +case 0xfc93: +case 0xfc94: +case 0xfc95: +case 0xfc96: +case 0xfc97: +case 0xfc98: +case 0xfc99: +case 0xfc9a: +case 0xfc9b: +case 0xfc9c: +case 0xfc9d: +case 0xfc9e: +case 0xfc9f: +case 0xfca0: +case 0xfca1: +case 0xfca2: +case 0xfca3: +case 0xfca4: +case 0xfca5: +case 0xfca6: +case 0xfca7: +case 0xfca8: +case 0xfca9: +case 0xfcaa: +case 0xfcab: +case 0xfcac: +case 0xfcad: +case 0xfcae: +case 0xfcaf: +case 0xfcb0: +case 0xfcb1: +case 0xfcb2: +case 0xfcb3: +case 0xfcb4: +case 0xfcb5: +case 0xfcb6: +case 0xfcb7: +case 0xfcb8: +case 0xfcb9: +case 0xfcba: +case 0xfcbb: +case 0xfcbc: +case 0xfcbd: +case 0xfcbe: +case 0xfcbf: +case 0xfcc0: +case 0xfcc1: +case 0xfcc2: +case 0xfcc3: +case 0xfcc4: +case 0xfcc5: +case 0xfcc6: +case 0xfcc7: +case 0xfcc8: +case 0xfcc9: +case 0xfcca: +case 0xfccb: +case 0xfccc: +case 0xfccd: +case 0xfcce: +case 0xfccf: +case 0xfcd0: +case 0xfcd1: +case 0xfcd2: +case 0xfcd3: +case 0xfcd4: +case 0xfcd5: +case 0xfcd6: +case 0xfcd7: +case 0xfcd8: +case 0xfcd9: +case 0xfcda: +case 0xfcdb: +case 0xfcdc: +case 0xfcdd: +case 0xfcde: +case 0xfcdf: +case 0xfce0: +case 0xfce1: +case 0xfce2: +case 0xfce3: +case 0xfce4: +case 0xfce5: +case 0xfce6: +case 0xfce7: +case 0xfce8: +case 0xfce9: +case 0xfcea: +case 0xfceb: +case 0xfcec: +case 0xfced: +case 0xfcee: +case 0xfcef: +case 0xfcf0: +case 0xfcf1: +case 0xfcf2: +case 0xfcf3: +case 0xfcf4: +case 0xfcf5: +case 0xfcf6: +case 0xfcf7: +case 0xfcf8: +case 0xfcf9: +case 0xfcfa: +case 0xfcfb: +case 0xfcfc: +case 0xfcfd: +case 0xfcfe: +case 0xfcff: +case 0xfd00: +case 0xfd01: +case 0xfd02: +case 0xfd03: +case 0xfd04: +case 0xfd05: +case 0xfd06: +case 0xfd07: +case 0xfd08: +case 0xfd09: +case 0xfd0a: +case 0xfd0b: +case 0xfd0c: +case 0xfd0d: +case 0xfd0e: +case 0xfd0f: +case 0xfd10: +case 0xfd11: +case 0xfd12: +case 0xfd13: +case 0xfd14: +case 0xfd15: +case 0xfd16: +case 0xfd17: +case 0xfd18: +case 0xfd19: +case 0xfd1a: +case 0xfd1b: +case 0xfd1c: +case 0xfd1d: +case 0xfd1e: +case 0xfd1f: +case 0xfd20: +case 0xfd21: +case 0xfd22: +case 0xfd23: +case 0xfd24: +case 0xfd25: +case 0xfd26: +case 0xfd27: +case 0xfd28: +case 0xfd29: +case 0xfd2a: +case 0xfd2b: +case 0xfd2c: +case 0xfd2d: +case 0xfd2e: +case 0xfd2f: +case 0xfd30: +case 0xfd31: +case 0xfd32: +case 0xfd33: +case 0xfd34: +case 0xfd35: +case 0xfd36: +case 0xfd37: +case 0xfd38: +case 0xfd39: +case 0xfd3a: +case 0xfd3b: +case 0xfd3c: +case 0xfd3d: +case 0xfd3e: +case 0xfd3f: +case 0xfd40: +case 0xfd41: +case 0xfd42: +case 0xfd43: +case 0xfd44: +case 0xfd45: +case 0xfd46: +case 0xfd47: +case 0xfd48: +case 0xfd49: +case 0xfd4a: +case 0xfd4b: +case 0xfd4c: +case 0xfd4d: +case 0xfd4e: +case 0xfd4f: +case 0xfd50: +case 0xfd51: +case 0xfd52: +case 0xfd53: +case 0xfd54: +case 0xfd55: +case 0xfd56: +case 0xfd57: +case 0xfd58: +case 0xfd59: +case 0xfd5a: +case 0xfd5b: +case 0xfd5c: +case 0xfd5d: +case 0xfd5e: +case 0xfd5f: +case 0xfd60: +case 0xfd61: +case 0xfd62: +case 0xfd63: +case 0xfd64: +case 0xfd65: +case 0xfd66: +case 0xfd67: +case 0xfd68: +case 0xfd69: +case 0xfd6a: +case 0xfd6b: +case 0xfd6c: +case 0xfd6d: +case 0xfd6e: +case 0xfd6f: +case 0xfd70: +case 0xfd71: +case 0xfd72: +case 0xfd73: +case 0xfd74: +case 0xfd75: +case 0xfd76: +case 0xfd77: +case 0xfd78: +case 0xfd79: +case 0xfd7a: +case 0xfd7b: +case 0xfd7c: +case 0xfd7d: +case 0xfd7e: +case 0xfd7f: +case 0xfd80: +case 0xfd81: +case 0xfd82: +case 0xfd83: +case 0xfd84: +case 0xfd85: +case 0xfd86: +case 0xfd87: +case 0xfd88: +case 0xfd89: +case 0xfd8a: +case 0xfd8b: +case 0xfd8c: +case 0xfd8d: +case 0xfd8e: +case 0xfd8f: +case 0xfd90: +case 0xfd91: +case 0xfd92: +case 0xfd93: +case 0xfd94: +case 0xfd95: +case 0xfd96: +case 0xfd97: +case 0xfd98: +case 0xfd99: +case 0xfd9a: +case 0xfd9b: +case 0xfd9c: +case 0xfd9d: +case 0xfd9e: +case 0xfd9f: +case 0xfda0: +case 0xfda1: +case 0xfda2: +case 0xfda3: +case 0xfda4: +case 0xfda5: +case 0xfda6: +case 0xfda7: +case 0xfda8: +case 0xfda9: +case 0xfdaa: +case 0xfdab: +case 0xfdac: +case 0xfdad: +case 0xfdae: +case 0xfdaf: +case 0xfdb0: +case 0xfdb1: +case 0xfdb2: +case 0xfdb3: +case 0xfdb4: +case 0xfdb5: +case 0xfdb6: +case 0xfdb7: +case 0xfdb8: +case 0xfdb9: +case 0xfdba: +case 0xfdbb: +case 0xfdbc: +case 0xfdbd: +case 0xfdbe: +case 0xfdbf: +case 0xfdc0: +case 0xfdc1: +case 0xfdc2: +case 0xfdc3: +case 0xfdc4: +case 0xfdc5: +case 0xfdc6: +case 0xfdc7: +case 0xfdc8: +case 0xfdc9: +case 0xfdca: +case 0xfdcb: +case 0xfdcc: +case 0xfdcd: +case 0xfdce: +case 0xfdcf: +case 0xfdd0: +case 0xfdd1: +case 0xfdd2: +case 0xfdd3: +case 0xfdd4: +case 0xfdd5: +case 0xfdd6: +case 0xfdd7: +case 0xfdd8: +case 0xfdd9: +case 0xfdda: +case 0xfddb: +case 0xfddc: +case 0xfddd: +case 0xfdde: +case 0xfddf: +case 0xfde0: +case 0xfde1: +case 0xfde2: +case 0xfde3: +case 0xfde4: +case 0xfde5: +case 0xfde6: +case 0xfde7: +case 0xfde8: +case 0xfde9: +case 0xfdea: +case 0xfdeb: +case 0xfdec: +case 0xfded: +case 0xfdee: +case 0xfdef: +case 0xfdf0: +case 0xfdf1: +case 0xfdf2: +case 0xfdf3: +case 0xfdf4: +case 0xfdf5: +case 0xfdf6: +case 0xfdf7: +case 0xfdf8: +case 0xfdf9: +case 0xfdfa: +case 0xfdfb: +case 0xfdfc: +case 0xfdfd: +case 0xfdfe: +case 0xfdff: +case 0xfe00: +case 0xfe01: +case 0xfe02: +case 0xfe03: +case 0xfe04: +case 0xfe05: +case 0xfe06: +case 0xfe07: +case 0xfe08: +case 0xfe09: +case 0xfe0a: +case 0xfe0b: +case 0xfe0c: +case 0xfe0d: +case 0xfe0e: +case 0xfe0f: +case 0xfe10: +case 0xfe11: +case 0xfe12: +case 0xfe13: +case 0xfe14: +case 0xfe15: +case 0xfe16: +case 0xfe17: +case 0xfe18: +case 0xfe19: +case 0xfe1a: +case 0xfe1b: +case 0xfe1c: +case 0xfe1d: +case 0xfe1e: +case 0xfe1f: +case 0xfe20: +case 0xfe21: +case 0xfe22: +case 0xfe23: +case 0xfe24: +case 0xfe25: +case 0xfe26: +case 0xfe27: +case 0xfe28: +case 0xfe29: +case 0xfe2a: +case 0xfe2b: +case 0xfe2c: +case 0xfe2d: +case 0xfe2e: +case 0xfe2f: +case 0xfe30: +case 0xfe31: +case 0xfe32: +case 0xfe33: +case 0xfe34: +case 0xfe35: +case 0xfe36: +case 0xfe37: +case 0xfe38: +case 0xfe39: +case 0xfe3a: +case 0xfe3b: +case 0xfe3c: +case 0xfe3d: +case 0xfe3e: +case 0xfe3f: +case 0xfe40: +case 0xfe41: +case 0xfe42: +case 0xfe43: +case 0xfe44: +case 0xfe45: +case 0xfe46: +case 0xfe47: +case 0xfe48: +case 0xfe49: +case 0xfe4a: +case 0xfe4b: +case 0xfe4c: +case 0xfe4d: +case 0xfe4e: +case 0xfe4f: +case 0xfe50: +case 0xfe51: +case 0xfe52: +case 0xfe53: +case 0xfe54: +case 0xfe55: +case 0xfe56: +case 0xfe57: +case 0xfe58: +case 0xfe59: +case 0xfe5a: +case 0xfe5b: +case 0xfe5c: +case 0xfe5d: +case 0xfe5e: +case 0xfe5f: +case 0xfe60: +case 0xfe61: +case 0xfe62: +case 0xfe63: +case 0xfe64: +case 0xfe65: +case 0xfe66: +case 0xfe67: +case 0xfe68: +case 0xfe69: +case 0xfe6a: +case 0xfe6b: +case 0xfe6c: +case 0xfe6d: +case 0xfe6e: +case 0xfe6f: +case 0xfe70: +case 0xfe71: +case 0xfe72: +case 0xfe73: +case 0xfe74: +case 0xfe75: +case 0xfe76: +case 0xfe77: +case 0xfe78: +case 0xfe79: +case 0xfe7a: +case 0xfe7b: +case 0xfe7c: +case 0xfe7d: +case 0xfe7e: +case 0xfe7f: +case 0xfe80: +case 0xfe81: +case 0xfe82: +case 0xfe83: +case 0xfe84: +case 0xfe85: +case 0xfe86: +case 0xfe87: +case 0xfe88: +case 0xfe89: +case 0xfe8a: +case 0xfe8b: +case 0xfe8c: +case 0xfe8d: +case 0xfe8e: +case 0xfe8f: +case 0xfe90: +case 0xfe91: +case 0xfe92: +case 0xfe93: +case 0xfe94: +case 0xfe95: +case 0xfe96: +case 0xfe97: +case 0xfe98: +case 0xfe99: +case 0xfe9a: +case 0xfe9b: +case 0xfe9c: +case 0xfe9d: +case 0xfe9e: +case 0xfe9f: +case 0xfea0: +case 0xfea1: +case 0xfea2: +case 0xfea3: +case 0xfea4: +case 0xfea5: +case 0xfea6: +case 0xfea7: +case 0xfea8: +case 0xfea9: +case 0xfeaa: +case 0xfeab: +case 0xfeac: +case 0xfead: +case 0xfeae: +case 0xfeaf: +case 0xfeb0: +case 0xfeb1: +case 0xfeb2: +case 0xfeb3: +case 0xfeb4: +case 0xfeb5: +case 0xfeb6: +case 0xfeb7: +case 0xfeb8: +case 0xfeb9: +case 0xfeba: +case 0xfebb: +case 0xfebc: +case 0xfebd: +case 0xfebe: +case 0xfebf: +case 0xfec0: +case 0xfec1: +case 0xfec2: +case 0xfec3: +case 0xfec4: +case 0xfec5: +case 0xfec6: +case 0xfec7: +case 0xfec8: +case 0xfec9: +case 0xfeca: +case 0xfecb: +case 0xfecc: +case 0xfecd: +case 0xfece: +case 0xfecf: +case 0xfed0: +case 0xfed1: +case 0xfed2: +case 0xfed3: +case 0xfed4: +case 0xfed5: +case 0xfed6: +case 0xfed7: +case 0xfed8: +case 0xfed9: +case 0xfeda: +case 0xfedb: +case 0xfedc: +case 0xfedd: +case 0xfede: +case 0xfedf: +case 0xfee0: +case 0xfee1: +case 0xfee2: +case 0xfee3: +case 0xfee4: +case 0xfee5: +case 0xfee6: +case 0xfee7: +case 0xfee8: +case 0xfee9: +case 0xfeea: +case 0xfeeb: +case 0xfeec: +case 0xfeed: +case 0xfeee: +case 0xfeef: +case 0xfef0: +case 0xfef1: +case 0xfef2: +case 0xfef3: +case 0xfef4: +case 0xfef5: +case 0xfef6: +case 0xfef7: +case 0xfef8: +case 0xfef9: +case 0xfefa: +case 0xfefb: +case 0xfefc: +case 0xfefd: +case 0xfefe: +case 0xfeff: +case 0xff00: +case 0xff01: +case 0xff02: +case 0xff03: +case 0xff04: +case 0xff05: +case 0xff06: +case 0xff07: +case 0xff08: +case 0xff09: +case 0xff0a: +case 0xff0b: +case 0xff0c: +case 0xff0d: +case 0xff0e: +case 0xff0f: +case 0xff10: +case 0xff11: +case 0xff12: +case 0xff13: +case 0xff14: +case 0xff15: +case 0xff16: +case 0xff17: +case 0xff18: +case 0xff19: +case 0xff1a: +case 0xff1b: +case 0xff1c: +case 0xff1d: +case 0xff1e: +case 0xff1f: +case 0xff20: +case 0xff21: +case 0xff22: +case 0xff23: +case 0xff24: +case 0xff25: +case 0xff26: +case 0xff27: +case 0xff28: +case 0xff29: +case 0xff2a: +case 0xff2b: +case 0xff2c: +case 0xff2d: +case 0xff2e: +case 0xff2f: +case 0xff30: +case 0xff31: +case 0xff32: +case 0xff33: +case 0xff34: +case 0xff35: +case 0xff36: +case 0xff37: +case 0xff38: +case 0xff39: +case 0xff3a: +case 0xff3b: +case 0xff3c: +case 0xff3d: +case 0xff3e: +case 0xff3f: +case 0xff40: +case 0xff41: +case 0xff42: +case 0xff43: +case 0xff44: +case 0xff45: +case 0xff46: +case 0xff47: +case 0xff48: +case 0xff49: +case 0xff4a: +case 0xff4b: +case 0xff4c: +case 0xff4d: +case 0xff4e: +case 0xff4f: +case 0xff50: +case 0xff51: +case 0xff52: +case 0xff53: +case 0xff54: +case 0xff55: +case 0xff56: +case 0xff57: +case 0xff58: +case 0xff59: +case 0xff5a: +case 0xff5b: +case 0xff5c: +case 0xff5d: +case 0xff5e: +case 0xff5f: +case 0xff60: +case 0xff61: +case 0xff62: +case 0xff63: +case 0xff64: +case 0xff65: +case 0xff66: +case 0xff67: +case 0xff68: +case 0xff69: +case 0xff6a: +case 0xff6b: +case 0xff6c: +case 0xff6d: +case 0xff6e: +case 0xff6f: +case 0xff70: +case 0xff71: +case 0xff72: +case 0xff73: +case 0xff74: +case 0xff75: +case 0xff76: +case 0xff77: +case 0xff78: +case 0xff79: +case 0xff7a: +case 0xff7b: +case 0xff7c: +case 0xff7d: +case 0xff7e: +case 0xff7f: +case 0xff80: +case 0xff81: +case 0xff82: +case 0xff83: +case 0xff84: +case 0xff85: +case 0xff86: +case 0xff87: +case 0xff88: +case 0xff89: +case 0xff8a: +case 0xff8b: +case 0xff8c: +case 0xff8d: +case 0xff8e: +case 0xff8f: +case 0xff90: +case 0xff91: +case 0xff92: +case 0xff93: +case 0xff94: +case 0xff95: +case 0xff96: +case 0xff97: +case 0xff98: +case 0xff99: +case 0xff9a: +case 0xff9b: +case 0xff9c: +case 0xff9d: +case 0xff9e: +case 0xff9f: +case 0xffa0: +case 0xffa1: +case 0xffa2: +case 0xffa3: +case 0xffa4: +case 0xffa5: +case 0xffa6: +case 0xffa7: +case 0xffa8: +case 0xffa9: +case 0xffaa: +case 0xffab: +case 0xffac: +case 0xffad: +case 0xffae: +case 0xffaf: +case 0xffb0: +case 0xffb1: +case 0xffb2: +case 0xffb3: +case 0xffb4: +case 0xffb5: +case 0xffb6: +case 0xffb7: +case 0xffb8: +case 0xffb9: +case 0xffba: +case 0xffbb: +case 0xffbc: +case 0xffbd: +case 0xffbe: +case 0xffbf: +case 0xffc0: +case 0xffc1: +case 0xffc2: +case 0xffc3: +case 0xffc4: +case 0xffc5: +case 0xffc6: +case 0xffc7: +case 0xffc8: +case 0xffc9: +case 0xffca: +case 0xffcb: +case 0xffcc: +case 0xffcd: +case 0xffce: +case 0xffcf: +case 0xffd0: +case 0xffd1: +case 0xffd2: +case 0xffd3: +case 0xffd4: +case 0xffd5: +case 0xffd6: +case 0xffd7: +case 0xffd8: +case 0xffd9: +case 0xffda: +case 0xffdb: +case 0xffdc: +case 0xffdd: +case 0xffde: +case 0xffdf: +case 0xffe0: +case 0xffe1: +case 0xffe2: +case 0xffe3: +case 0xffe4: +case 0xffe5: +case 0xffe6: +case 0xffe7: +case 0xffe8: +case 0xffe9: +case 0xffea: +case 0xffeb: +case 0xffec: +case 0xffed: +case 0xffee: +case 0xffef: +case 0xfff0: +case 0xfff1: +case 0xfff2: +case 0xfff3: +case 0xfff4: +case 0xfff5: +case 0xfff6: +case 0xfff7: +case 0xfff8: +case 0xfff9: +case 0xfffa: +case 0xfffb: +case 0xfffc: +case 0xfffd: +case 0xfffe: +case 0xffff: + { + LINEF(); + } + break; + +case 0x4e50: +case 0x4e51: +case 0x4e52: +case 0x4e53: +case 0x4e54: +case 0x4e55: +case 0x4e56: +case 0x4e57: + { + LINK(instr_b2_b0); + } + break; + +case 0x0108: +case 0x0109: +case 0x010a: +case 0x010b: +case 0x010c: +case 0x010d: +case 0x010e: +case 0x010f: +case 0x0308: +case 0x0309: +case 0x030a: +case 0x030b: +case 0x030c: +case 0x030d: +case 0x030e: +case 0x030f: +case 0x0508: +case 0x0509: +case 0x050a: +case 0x050b: +case 0x050c: +case 0x050d: +case 0x050e: +case 0x050f: +case 0x0708: +case 0x0709: +case 0x070a: +case 0x070b: +case 0x070c: +case 0x070d: +case 0x070e: +case 0x070f: +case 0x0908: +case 0x0909: +case 0x090a: +case 0x090b: +case 0x090c: +case 0x090d: +case 0x090e: +case 0x090f: +case 0x0b08: +case 0x0b09: +case 0x0b0a: +case 0x0b0b: +case 0x0b0c: +case 0x0b0d: +case 0x0b0e: +case 0x0b0f: +case 0x0d08: +case 0x0d09: +case 0x0d0a: +case 0x0d0b: +case 0x0d0c: +case 0x0d0d: +case 0x0d0e: +case 0x0d0f: +case 0x0f08: +case 0x0f09: +case 0x0f0a: +case 0x0f0b: +case 0x0f0c: +case 0x0f0d: +case 0x0f0e: +case 0x0f0f: + { + MOVEP(instr_b2_b0, instr_b11_b9); + } + break; + +case 0x0188: +case 0x0189: +case 0x018a: +case 0x018b: +case 0x018c: +case 0x018d: +case 0x018e: +case 0x018f: +case 0x0388: +case 0x0389: +case 0x038a: +case 0x038b: +case 0x038c: +case 0x038d: +case 0x038e: +case 0x038f: +case 0x0588: +case 0x0589: +case 0x058a: +case 0x058b: +case 0x058c: +case 0x058d: +case 0x058e: +case 0x058f: +case 0x0788: +case 0x0789: +case 0x078a: +case 0x078b: +case 0x078c: +case 0x078d: +case 0x078e: +case 0x078f: +case 0x0988: +case 0x0989: +case 0x098a: +case 0x098b: +case 0x098c: +case 0x098d: +case 0x098e: +case 0x098f: +case 0x0b88: +case 0x0b89: +case 0x0b8a: +case 0x0b8b: +case 0x0b8c: +case 0x0b8d: +case 0x0b8e: +case 0x0b8f: +case 0x0d88: +case 0x0d89: +case 0x0d8a: +case 0x0d8b: +case 0x0d8c: +case 0x0d8d: +case 0x0d8e: +case 0x0d8f: +case 0x0f88: +case 0x0f89: +case 0x0f8a: +case 0x0f8b: +case 0x0f8c: +case 0x0f8d: +case 0x0f8e: +case 0x0f8f: + { + MOVEP(instr_b2_b0, instr_b11_b9); + } + break; + +case 0x0148: +case 0x0149: +case 0x014a: +case 0x014b: +case 0x014c: +case 0x014d: +case 0x014e: +case 0x014f: +case 0x0348: +case 0x0349: +case 0x034a: +case 0x034b: +case 0x034c: +case 0x034d: +case 0x034e: +case 0x034f: +case 0x0548: +case 0x0549: +case 0x054a: +case 0x054b: +case 0x054c: +case 0x054d: +case 0x054e: +case 0x054f: +case 0x0748: +case 0x0749: +case 0x074a: +case 0x074b: +case 0x074c: +case 0x074d: +case 0x074e: +case 0x074f: +case 0x0948: +case 0x0949: +case 0x094a: +case 0x094b: +case 0x094c: +case 0x094d: +case 0x094e: +case 0x094f: +case 0x0b48: +case 0x0b49: +case 0x0b4a: +case 0x0b4b: +case 0x0b4c: +case 0x0b4d: +case 0x0b4e: +case 0x0b4f: +case 0x0d48: +case 0x0d49: +case 0x0d4a: +case 0x0d4b: +case 0x0d4c: +case 0x0d4d: +case 0x0d4e: +case 0x0d4f: +case 0x0f48: +case 0x0f49: +case 0x0f4a: +case 0x0f4b: +case 0x0f4c: +case 0x0f4d: +case 0x0f4e: +case 0x0f4f: + { + MOVEP(instr_b2_b0, instr_b11_b9); + } + break; + +case 0x01c8: +case 0x01c9: +case 0x01ca: +case 0x01cb: +case 0x01cc: +case 0x01cd: +case 0x01ce: +case 0x01cf: +case 0x03c8: +case 0x03c9: +case 0x03ca: +case 0x03cb: +case 0x03cc: +case 0x03cd: +case 0x03ce: +case 0x03cf: +case 0x05c8: +case 0x05c9: +case 0x05ca: +case 0x05cb: +case 0x05cc: +case 0x05cd: +case 0x05ce: +case 0x05cf: +case 0x07c8: +case 0x07c9: +case 0x07ca: +case 0x07cb: +case 0x07cc: +case 0x07cd: +case 0x07ce: +case 0x07cf: +case 0x09c8: +case 0x09c9: +case 0x09ca: +case 0x09cb: +case 0x09cc: +case 0x09cd: +case 0x09ce: +case 0x09cf: +case 0x0bc8: +case 0x0bc9: +case 0x0bca: +case 0x0bcb: +case 0x0bcc: +case 0x0bcd: +case 0x0bce: +case 0x0bcf: +case 0x0dc8: +case 0x0dc9: +case 0x0dca: +case 0x0dcb: +case 0x0dcc: +case 0x0dcd: +case 0x0dce: +case 0x0dcf: +case 0x0fc8: +case 0x0fc9: +case 0x0fca: +case 0x0fcb: +case 0x0fcc: +case 0x0fcd: +case 0x0fce: +case 0x0fcf: + { + MOVEP(instr_b2_b0, instr_b11_b9); + } + break; + +case 0x4e71: + { + NOP(); + } + break; + +case 0x003c: + { + ORI_CCR(); + } + break; + +case 0x4e77: + { + RTR(); + } + break; + +case 0x4e75: + { + RTS(); + } + break; + +case 0x4840: +case 0x4841: +case 0x4842: +case 0x4843: +case 0x4844: +case 0x4845: +case 0x4846: +case 0x4847: + { + SWAP(instr_b2_b0); + } + break; + +case 0x4e40: +case 0x4e41: +case 0x4e42: +case 0x4e43: +case 0x4e44: +case 0x4e45: +case 0x4e46: +case 0x4e47: +case 0x4e48: +case 0x4e49: +case 0x4e4a: +case 0x4e4b: +case 0x4e4c: +case 0x4e4d: +case 0x4e4e: +case 0x4e4f: + { + TRAP(instr & 0xF); + } + break; + +case 0x4e76: + { + TRAPV(); + } + break; + +case 0x4e58: +case 0x4e59: +case 0x4e5a: +case 0x4e5b: +case 0x4e5c: +case 0x4e5d: +case 0x4e5e: +case 0x4e5f: + { + UNLK(instr_b2_b0); + } + break; + +case 0x48b9: + { + const uint16 reglist = ReadOp(); HAM dst(this); MOVEM_to_MEM(reglist, dst); + } + break; + +case 0x4cb9: + { + const uint16 reglist = ReadOp(); HAM src(this); MOVEM_to_REGS(src, reglist); + } + break; + +case 0x48b8: + { + const uint16 reglist = ReadOp(); HAM dst(this); MOVEM_to_MEM(reglist, dst); + } + break; + +case 0x4cb8: + { + const uint16 reglist = ReadOp(); HAM src(this); MOVEM_to_REGS(src, reglist); + } + break; + +case 0x4890: +case 0x4891: +case 0x4892: +case 0x4893: +case 0x4894: +case 0x4895: +case 0x4896: +case 0x4897: + { + const uint16 reglist = ReadOp(); HAM dst(this, instr_b2_b0); MOVEM_to_MEM(reglist, dst); + } + break; + +case 0x48a0: +case 0x48a1: +case 0x48a2: +case 0x48a3: +case 0x48a4: +case 0x48a5: +case 0x48a6: +case 0x48a7: + { + const uint16 reglist = ReadOp(); HAM dst(this, instr_b2_b0); MOVEM_to_MEM(reglist, dst); + } + break; + +case 0x4c90: +case 0x4c91: +case 0x4c92: +case 0x4c93: +case 0x4c94: +case 0x4c95: +case 0x4c96: +case 0x4c97: + { + const uint16 reglist = ReadOp(); HAM src(this, instr_b2_b0); MOVEM_to_REGS(src, reglist); + } + break; + +case 0x4c98: +case 0x4c99: +case 0x4c9a: +case 0x4c9b: +case 0x4c9c: +case 0x4c9d: +case 0x4c9e: +case 0x4c9f: + { + const uint16 reglist = ReadOp(); HAM src(this, instr_b2_b0); MOVEM_to_REGS(src, reglist); + } + break; + +case 0x48a8: +case 0x48a9: +case 0x48aa: +case 0x48ab: +case 0x48ac: +case 0x48ad: +case 0x48ae: +case 0x48af: + { + const uint16 reglist = ReadOp(); HAM dst(this, instr_b2_b0); MOVEM_to_MEM(reglist, dst); + } + break; + +case 0x4ca8: +case 0x4ca9: +case 0x4caa: +case 0x4cab: +case 0x4cac: +case 0x4cad: +case 0x4cae: +case 0x4caf: + { + const uint16 reglist = ReadOp(); HAM src(this, instr_b2_b0); MOVEM_to_REGS(src, reglist); + } + break; + +case 0x48b0: +case 0x48b1: +case 0x48b2: +case 0x48b3: +case 0x48b4: +case 0x48b5: +case 0x48b6: +case 0x48b7: + { + const uint16 reglist = ReadOp(); HAM dst(this, instr_b2_b0); MOVEM_to_MEM(reglist, dst); + } + break; + +case 0x4cb0: +case 0x4cb1: +case 0x4cb2: +case 0x4cb3: +case 0x4cb4: +case 0x4cb5: +case 0x4cb6: +case 0x4cb7: + { + const uint16 reglist = ReadOp(); HAM src(this, instr_b2_b0); MOVEM_to_REGS(src, reglist); + } + break; + +case 0x4cba: + { + const uint16 reglist = ReadOp(); HAM src(this); MOVEM_to_REGS(src, reglist); + } + break; + +case 0x4cbb: + { + const uint16 reglist = ReadOp(); HAM src(this); MOVEM_to_REGS(src, reglist); + } + break; + +case 0x48f9: + { + const uint16 reglist = ReadOp(); HAM dst(this); MOVEM_to_MEM(reglist, dst); + } + break; + +case 0x4cf9: + { + const uint16 reglist = ReadOp(); HAM src(this); MOVEM_to_REGS(src, reglist); + } + break; + +case 0x48f8: + { + const uint16 reglist = ReadOp(); HAM dst(this); MOVEM_to_MEM(reglist, dst); + } + break; + +case 0x4cf8: + { + const uint16 reglist = ReadOp(); HAM src(this); MOVEM_to_REGS(src, reglist); + } + break; + +case 0x48d0: +case 0x48d1: +case 0x48d2: +case 0x48d3: +case 0x48d4: +case 0x48d5: +case 0x48d6: +case 0x48d7: + { + const uint16 reglist = ReadOp(); HAM dst(this, instr_b2_b0); MOVEM_to_MEM(reglist, dst); + } + break; + +case 0x48e0: +case 0x48e1: +case 0x48e2: +case 0x48e3: +case 0x48e4: +case 0x48e5: +case 0x48e6: +case 0x48e7: + { + const uint16 reglist = ReadOp(); HAM dst(this, instr_b2_b0); MOVEM_to_MEM(reglist, dst); + } + break; + +case 0x4cd0: +case 0x4cd1: +case 0x4cd2: +case 0x4cd3: +case 0x4cd4: +case 0x4cd5: +case 0x4cd6: +case 0x4cd7: + { + const uint16 reglist = ReadOp(); HAM src(this, instr_b2_b0); MOVEM_to_REGS(src, reglist); + } + break; + +case 0x4cd8: +case 0x4cd9: +case 0x4cda: +case 0x4cdb: +case 0x4cdc: +case 0x4cdd: +case 0x4cde: +case 0x4cdf: + { + const uint16 reglist = ReadOp(); HAM src(this, instr_b2_b0); MOVEM_to_REGS(src, reglist); + } + break; + +case 0x48e8: +case 0x48e9: +case 0x48ea: +case 0x48eb: +case 0x48ec: +case 0x48ed: +case 0x48ee: +case 0x48ef: + { + const uint16 reglist = ReadOp(); HAM dst(this, instr_b2_b0); MOVEM_to_MEM(reglist, dst); + } + break; + +case 0x4ce8: +case 0x4ce9: +case 0x4cea: +case 0x4ceb: +case 0x4cec: +case 0x4ced: +case 0x4cee: +case 0x4cef: + { + const uint16 reglist = ReadOp(); HAM src(this, instr_b2_b0); MOVEM_to_REGS(src, reglist); + } + break; + +case 0x48f0: +case 0x48f1: +case 0x48f2: +case 0x48f3: +case 0x48f4: +case 0x48f5: +case 0x48f6: +case 0x48f7: + { + const uint16 reglist = ReadOp(); HAM dst(this, instr_b2_b0); MOVEM_to_MEM(reglist, dst); + } + break; + +case 0x4cf0: +case 0x4cf1: +case 0x4cf2: +case 0x4cf3: +case 0x4cf4: +case 0x4cf5: +case 0x4cf6: +case 0x4cf7: + { + const uint16 reglist = ReadOp(); HAM src(this, instr_b2_b0); MOVEM_to_REGS(src, reglist); + } + break; + +case 0x4cfa: + { + const uint16 reglist = ReadOp(); HAM src(this); MOVEM_to_REGS(src, reglist); + } + break; + +case 0x4cfb: + { + const uint16 reglist = ReadOp(); HAM src(this); MOVEM_to_REGS(src, reglist); + } + break; + +case 0x40f9: + { + if(!Revision_E || CheckPrivilege()) { HAM dst(this); MOVE_from_SR(dst); } + } + break; + +case 0x40f8: + { + if(!Revision_E || CheckPrivilege()) { HAM dst(this); MOVE_from_SR(dst); } + } + break; + +case 0x40d0: +case 0x40d1: +case 0x40d2: +case 0x40d3: +case 0x40d4: +case 0x40d5: +case 0x40d6: +case 0x40d7: + { + if(!Revision_E || CheckPrivilege()) { HAM dst(this, instr_b2_b0); MOVE_from_SR(dst); } + } + break; + +case 0x40e8: +case 0x40e9: +case 0x40ea: +case 0x40eb: +case 0x40ec: +case 0x40ed: +case 0x40ee: +case 0x40ef: + { + if(!Revision_E || CheckPrivilege()) { HAM dst(this, instr_b2_b0); MOVE_from_SR(dst); } + } + break; + +case 0x40f0: +case 0x40f1: +case 0x40f2: +case 0x40f3: +case 0x40f4: +case 0x40f5: +case 0x40f6: +case 0x40f7: + { + if(!Revision_E || CheckPrivilege()) { HAM dst(this, instr_b2_b0); MOVE_from_SR(dst); } + } + break; + +case 0x40d8: +case 0x40d9: +case 0x40da: +case 0x40db: +case 0x40dc: +case 0x40dd: +case 0x40de: +case 0x40df: + { + if(!Revision_E || CheckPrivilege()) { HAM dst(this, instr_b2_b0); MOVE_from_SR(dst); } + } + break; + +case 0x40e0: +case 0x40e1: +case 0x40e2: +case 0x40e3: +case 0x40e4: +case 0x40e5: +case 0x40e6: +case 0x40e7: + { + if(!Revision_E || CheckPrivilege()) { HAM dst(this, instr_b2_b0); MOVE_from_SR(dst); } + } + break; + +case 0x40c0: +case 0x40c1: +case 0x40c2: +case 0x40c3: +case 0x40c4: +case 0x40c5: +case 0x40c6: +case 0x40c7: + { + if(!Revision_E || CheckPrivilege()) { HAM dst(this, instr_b2_b0); MOVE_from_SR(dst); } + } + break; + +case 0x027c: + { + if(CheckPrivilege()) { ANDI_SR(); } + } + break; + +case 0x0a7c: + { + if(CheckPrivilege()) { EORI_SR(); } + } + break; + +case 0x46f9: + { + if(CheckPrivilege()) { HAM src(this); MOVE_to_SR(src); } + } + break; + +case 0x46f8: + { + if(CheckPrivilege()) { HAM src(this); MOVE_to_SR(src); } + } + break; + +case 0x46d0: +case 0x46d1: +case 0x46d2: +case 0x46d3: +case 0x46d4: +case 0x46d5: +case 0x46d6: +case 0x46d7: + { + if(CheckPrivilege()) { HAM src(this, instr_b2_b0); MOVE_to_SR(src); } + } + break; + +case 0x46e8: +case 0x46e9: +case 0x46ea: +case 0x46eb: +case 0x46ec: +case 0x46ed: +case 0x46ee: +case 0x46ef: + { + if(CheckPrivilege()) { HAM src(this, instr_b2_b0); MOVE_to_SR(src); } + } + break; + +case 0x46f0: +case 0x46f1: +case 0x46f2: +case 0x46f3: +case 0x46f4: +case 0x46f5: +case 0x46f6: +case 0x46f7: + { + if(CheckPrivilege()) { HAM src(this, instr_b2_b0); MOVE_to_SR(src); } + } + break; + +case 0x46d8: +case 0x46d9: +case 0x46da: +case 0x46db: +case 0x46dc: +case 0x46dd: +case 0x46de: +case 0x46df: + { + if(CheckPrivilege()) { HAM src(this, instr_b2_b0); MOVE_to_SR(src); } + } + break; + +case 0x46e0: +case 0x46e1: +case 0x46e2: +case 0x46e3: +case 0x46e4: +case 0x46e5: +case 0x46e6: +case 0x46e7: + { + if(CheckPrivilege()) { HAM src(this, instr_b2_b0); MOVE_to_SR(src); } + } + break; + +case 0x46c0: +case 0x46c1: +case 0x46c2: +case 0x46c3: +case 0x46c4: +case 0x46c5: +case 0x46c6: +case 0x46c7: + { + if(CheckPrivilege()) { HAM src(this, instr_b2_b0); MOVE_to_SR(src); } + } + break; + +case 0x46fc: + { + if(CheckPrivilege()) { HAM src(this); MOVE_to_SR(src); } + } + break; + +case 0x46fa: + { + if(CheckPrivilege()) { HAM src(this); MOVE_to_SR(src); } + } + break; + +case 0x46fb: + { + if(CheckPrivilege()) { HAM src(this); MOVE_to_SR(src); } + } + break; + +case 0x4e60: +case 0x4e61: +case 0x4e62: +case 0x4e63: +case 0x4e64: +case 0x4e65: +case 0x4e66: +case 0x4e67: + { + if(CheckPrivilege()) { MOVE_USP<0>(instr_b2_b0); } + } + break; + +case 0x4e68: +case 0x4e69: +case 0x4e6a: +case 0x4e6b: +case 0x4e6c: +case 0x4e6d: +case 0x4e6e: +case 0x4e6f: + { + if(CheckPrivilege()) { MOVE_USP<1>(instr_b2_b0); } + } + break; + +case 0x007c: + { + if(CheckPrivilege()) { ORI_SR(); } + } + break; + +case 0x4e70: + { + if(CheckPrivilege()) { RESET(); } + } + break; + +case 0x4e73: + { + if(CheckPrivilege()) { RTE(); } + } + break; + +case 0x4e72: + { + if(CheckPrivilege()) { STOP(); } + } + break; + +case 0x0840: +case 0x0841: +case 0x0842: +case 0x0843: +case 0x0844: +case 0x0845: +case 0x0846: +case 0x0847: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BCHG(targ, wb); + } + break; + +case 0x0880: +case 0x0881: +case 0x0882: +case 0x0883: +case 0x0884: +case 0x0885: +case 0x0886: +case 0x0887: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BCLR(targ, wb); + } + break; + +case 0x08c0: +case 0x08c1: +case 0x08c2: +case 0x08c3: +case 0x08c4: +case 0x08c5: +case 0x08c6: +case 0x08c7: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BSET(targ, wb); + } + break; + +case 0x0800: +case 0x0801: +case 0x0802: +case 0x0803: +case 0x0804: +case 0x0805: +case 0x0806: +case 0x0807: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BTST(targ, wb); + } + break; + +case 0x0879: + { + unsigned wb = ReadOp(); HAM targ(this); BCHG(targ, wb); + } + break; + +case 0x08b9: + { + unsigned wb = ReadOp(); HAM targ(this); BCLR(targ, wb); + } + break; + +case 0x08f9: + { + unsigned wb = ReadOp(); HAM targ(this); BSET(targ, wb); + } + break; + +case 0x0839: + { + unsigned wb = ReadOp(); HAM targ(this); BTST(targ, wb); + } + break; + +case 0x0878: + { + unsigned wb = ReadOp(); HAM targ(this); BCHG(targ, wb); + } + break; + +case 0x08b8: + { + unsigned wb = ReadOp(); HAM targ(this); BCLR(targ, wb); + } + break; + +case 0x08f8: + { + unsigned wb = ReadOp(); HAM targ(this); BSET(targ, wb); + } + break; + +case 0x0838: + { + unsigned wb = ReadOp(); HAM targ(this); BTST(targ, wb); + } + break; + +case 0x0850: +case 0x0851: +case 0x0852: +case 0x0853: +case 0x0854: +case 0x0855: +case 0x0856: +case 0x0857: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BCHG(targ, wb); + } + break; + +case 0x0890: +case 0x0891: +case 0x0892: +case 0x0893: +case 0x0894: +case 0x0895: +case 0x0896: +case 0x0897: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BCLR(targ, wb); + } + break; + +case 0x08d0: +case 0x08d1: +case 0x08d2: +case 0x08d3: +case 0x08d4: +case 0x08d5: +case 0x08d6: +case 0x08d7: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BSET(targ, wb); + } + break; + +case 0x0810: +case 0x0811: +case 0x0812: +case 0x0813: +case 0x0814: +case 0x0815: +case 0x0816: +case 0x0817: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BTST(targ, wb); + } + break; + +case 0x0868: +case 0x0869: +case 0x086a: +case 0x086b: +case 0x086c: +case 0x086d: +case 0x086e: +case 0x086f: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BCHG(targ, wb); + } + break; + +case 0x08a8: +case 0x08a9: +case 0x08aa: +case 0x08ab: +case 0x08ac: +case 0x08ad: +case 0x08ae: +case 0x08af: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BCLR(targ, wb); + } + break; + +case 0x08e8: +case 0x08e9: +case 0x08ea: +case 0x08eb: +case 0x08ec: +case 0x08ed: +case 0x08ee: +case 0x08ef: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BSET(targ, wb); + } + break; + +case 0x0828: +case 0x0829: +case 0x082a: +case 0x082b: +case 0x082c: +case 0x082d: +case 0x082e: +case 0x082f: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BTST(targ, wb); + } + break; + +case 0x0870: +case 0x0871: +case 0x0872: +case 0x0873: +case 0x0874: +case 0x0875: +case 0x0876: +case 0x0877: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BCHG(targ, wb); + } + break; + +case 0x08b0: +case 0x08b1: +case 0x08b2: +case 0x08b3: +case 0x08b4: +case 0x08b5: +case 0x08b6: +case 0x08b7: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BCLR(targ, wb); + } + break; + +case 0x08f0: +case 0x08f1: +case 0x08f2: +case 0x08f3: +case 0x08f4: +case 0x08f5: +case 0x08f6: +case 0x08f7: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BSET(targ, wb); + } + break; + +case 0x0830: +case 0x0831: +case 0x0832: +case 0x0833: +case 0x0834: +case 0x0835: +case 0x0836: +case 0x0837: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BTST(targ, wb); + } + break; + +case 0x0858: +case 0x0859: +case 0x085a: +case 0x085b: +case 0x085c: +case 0x085d: +case 0x085e: +case 0x085f: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BCHG(targ, wb); + } + break; + +case 0x0898: +case 0x0899: +case 0x089a: +case 0x089b: +case 0x089c: +case 0x089d: +case 0x089e: +case 0x089f: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BCLR(targ, wb); + } + break; + +case 0x08d8: +case 0x08d9: +case 0x08da: +case 0x08db: +case 0x08dc: +case 0x08dd: +case 0x08de: +case 0x08df: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BSET(targ, wb); + } + break; + +case 0x0818: +case 0x0819: +case 0x081a: +case 0x081b: +case 0x081c: +case 0x081d: +case 0x081e: +case 0x081f: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BTST(targ, wb); + } + break; + +case 0x0860: +case 0x0861: +case 0x0862: +case 0x0863: +case 0x0864: +case 0x0865: +case 0x0866: +case 0x0867: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BCHG(targ, wb); + } + break; + +case 0x08a0: +case 0x08a1: +case 0x08a2: +case 0x08a3: +case 0x08a4: +case 0x08a5: +case 0x08a6: +case 0x08a7: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BCLR(targ, wb); + } + break; + +case 0x08e0: +case 0x08e1: +case 0x08e2: +case 0x08e3: +case 0x08e4: +case 0x08e5: +case 0x08e6: +case 0x08e7: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BSET(targ, wb); + } + break; + +case 0x0820: +case 0x0821: +case 0x0822: +case 0x0823: +case 0x0824: +case 0x0825: +case 0x0826: +case 0x0827: + { + unsigned wb = ReadOp(); HAM targ(this, instr_b2_b0); BTST(targ, wb); + } + break; + +case 0x083a: + { + unsigned wb = ReadOp(); HAM targ(this); BTST(targ, wb); + } + break; + +case 0x083b: + { + unsigned wb = ReadOp(); HAM targ(this); BTST(targ, wb); + } + break; + diff --git a/waterbox/ss/math_ops.h b/waterbox/ss/math_ops.h new file mode 100644 index 0000000000..4154f2d49b --- /dev/null +++ b/waterbox/ss/math_ops.h @@ -0,0 +1,278 @@ +/******************************************************************************/ +/* Mednafen - Multi-system Emulator */ +/******************************************************************************/ +/* math_ops.h: +** Copyright (C) 2007-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +/* +** Some ideas from: +** blargg +** http://graphics.stanford.edu/~seander/bithacks.html +*/ + +#ifndef __MDFN_MATH_OPS_H +#define __MDFN_MATH_OPS_H + +#if defined(_MSC_VER) + #include +#endif + +static INLINE unsigned MDFN_lzcount16_0UD(uint16 v) +{ + #if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER) + return 15 ^ 31 ^ __builtin_clz(v); + #elif defined(_MSC_VER) + unsigned long idx; + + _BitScanReverse(&idx, v); + + return 15 ^ idx; + #else + unsigned ret = 0; + unsigned tmp; + + tmp = !(v & 0xFF00) << 3; v <<= tmp; ret += tmp; + tmp = !(v & 0xF000) << 2; v <<= tmp; ret += tmp; + tmp = !(v & 0xC000) << 1; v <<= tmp; ret += tmp; + tmp = !(v & 0x8000) << 0; ret += tmp; + + return(ret); + #endif +} + +static INLINE unsigned MDFN_lzcount32_0UD(uint32 v) +{ + #if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER) + return __builtin_clz(v); + #elif defined(_MSC_VER) + unsigned long idx; + + _BitScanReverse(&idx, v); + + return 31 ^ idx; + #else + unsigned ret = 0; + unsigned tmp; + + tmp = !(v & 0xFFFF0000) << 4; v <<= tmp; ret += tmp; + tmp = !(v & 0xFF000000) << 3; v <<= tmp; ret += tmp; + tmp = !(v & 0xF0000000) << 2; v <<= tmp; ret += tmp; + tmp = !(v & 0xC0000000) << 1; v <<= tmp; ret += tmp; + tmp = !(v & 0x80000000) << 0; ret += tmp; + + return(ret); + #endif +} + +static INLINE unsigned MDFN_lzcount64_0UD(uint64 v) +{ + #if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER) + return __builtin_clzll(v); + #elif defined(_MSC_VER) + #if defined(_WIN64) + unsigned long idx; + _BitScanReverse64(&idx, v); + return 63 ^ idx; + #else + unsigned long idx0; + unsigned long idx1; + + _BitScanReverse(&idx1, v >> 0); + idx1 -= 32; + if(!_BitScanReverse(&idx0, v >> 32)) + idx0 = idx1; + + idx0 += 32; + + return 63 ^ idx0; + #endif + #else + unsigned ret = 0; + unsigned tmp; + + tmp = !(v & 0xFFFFFFFF00000000ULL) << 5; v <<= tmp; ret += tmp; + tmp = !(v & 0xFFFF000000000000ULL) << 4; v <<= tmp; ret += tmp; + tmp = !(v & 0xFF00000000000000ULL) << 3; v <<= tmp; ret += tmp; + tmp = !(v & 0xF000000000000000ULL) << 2; v <<= tmp; ret += tmp; + tmp = !(v & 0xC000000000000000ULL) << 1; v <<= tmp; ret += tmp; + tmp = !(v & 0x8000000000000000ULL) << 0; ret += tmp; + + return(ret); + #endif +} + +static INLINE unsigned MDFN_tzcount16_0UD(uint16 v) +{ + #if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER) + return __builtin_ctz(v); + #elif defined(_MSC_VER) + unsigned long idx; + + _BitScanForward(&idx, v); + + return idx; + #else + unsigned ret = 0; + unsigned tmp; + + tmp = !( (uint8)v) << 3; v >>= tmp; ret += tmp; + tmp = !(v & 0x000F) << 2; v >>= tmp; ret += tmp; + tmp = !(v & 0x0003) << 1; v >>= tmp; ret += tmp; + tmp = !(v & 0x0001) << 0; ret += tmp; + + return ret; + #endif +} + +static INLINE unsigned MDFN_tzcount32_0UD(uint32 v) +{ + #if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER) + return __builtin_ctz(v); + #elif defined(_MSC_VER) + unsigned long idx; + + _BitScanForward(&idx, v); + + return idx; + #else + unsigned ret = 0; + unsigned tmp; + + tmp = !((uint16)v) << 4; v >>= tmp; ret += tmp; + tmp = !( (uint8)v) << 3; v >>= tmp; ret += tmp; + tmp = !(v & 0x000F) << 2; v >>= tmp; ret += tmp; + tmp = !(v & 0x0003) << 1; v >>= tmp; ret += tmp; + tmp = !(v & 0x0001) << 0; ret += tmp; + + return ret; + #endif +} + +static INLINE unsigned MDFN_tzcount64_0UD(uint64 v) +{ + #if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER) + return __builtin_ctzll(v); + #elif defined(_MSC_VER) + #if defined(_WIN64) + unsigned long idx; + _BitScanForward64(&idx, v); + return idx; + #else + unsigned long idx0, idx1; + + _BitScanForward(&idx1, v >> 32); + idx1 += 32; + if(!_BitScanForward(&idx0, v)) + idx0 = idx1; + + return idx0; + #endif + #else + unsigned ret = 0; + unsigned tmp; + + tmp = !((uint32)v) << 5; v >>= tmp; ret += tmp; + tmp = !((uint16)v) << 4; v >>= tmp; ret += tmp; + tmp = !( (uint8)v) << 3; v >>= tmp; ret += tmp; + tmp = !(v & 0x000F) << 2; v >>= tmp; ret += tmp; + tmp = !(v & 0x0003) << 1; v >>= tmp; ret += tmp; + tmp = !(v & 0x0001) << 0; ret += tmp; + + return ret; + #endif +} + +// +// Result is defined for all possible inputs(including 0). +// +static INLINE unsigned MDFN_lzcount16(uint16 v) { return !v ? 16 : MDFN_lzcount16_0UD(v); } +static INLINE unsigned MDFN_lzcount32(uint32 v) { return !v ? 32 : MDFN_lzcount32_0UD(v); } +static INLINE unsigned MDFN_lzcount64(uint64 v) { return !v ? 64 : MDFN_lzcount64_0UD(v); } + +static INLINE unsigned MDFN_tzcount16(uint16 v) { return !v ? 16 : MDFN_tzcount16_0UD(v); } +static INLINE unsigned MDFN_tzcount32(uint32 v) { return !v ? 32 : MDFN_tzcount32_0UD(v); } +static INLINE unsigned MDFN_tzcount64(uint64 v) { return !v ? 64 : MDFN_tzcount64_0UD(v); } + +static INLINE unsigned MDFN_log2(uint32 v) { return 31 ^ MDFN_lzcount32_0UD(v | 1); } +static INLINE unsigned MDFN_log2(uint64 v) { return 63 ^ MDFN_lzcount64_0UD(v | 1); } + +static INLINE unsigned MDFN_log2(int32 v) { return MDFN_log2((uint32)v); } +static INLINE unsigned MDFN_log2(int64 v) { return MDFN_log2((uint64)v); } + +// Rounds up to the nearest power of 2(treats input as unsigned to a degree, but be aware of integer promotion rules). +// Returns 0 on overflow. +static INLINE uint64 round_up_pow2(uint32 v) { uint64 tmp = (uint64)1 << MDFN_log2(v); return tmp << (tmp < v); } +static INLINE uint64 round_up_pow2(uint64 v) { uint64 tmp = (uint64)1 << MDFN_log2(v); return tmp << (tmp < v); } + +static INLINE uint64 round_up_pow2(int32 v) { return round_up_pow2((uint32)v); } +static INLINE uint64 round_up_pow2(int64 v) { return round_up_pow2((uint64)v); } + +// Rounds to the nearest power of 2(treats input as unsigned to a degree, but be aware of integer promotion rules). +static INLINE uint64 round_nearest_pow2(uint32 v, bool round_half_up = true) { uint64 tmp = (uint64)1 << MDFN_log2(v); return tmp << (v && (((v - tmp) << 1) >= (tmp + !round_half_up))); } +static INLINE uint64 round_nearest_pow2(uint64 v, bool round_half_up = true) { uint64 tmp = (uint64)1 << MDFN_log2(v); return tmp << (v && (((v - tmp) << 1) >= (tmp + !round_half_up))); } + +static INLINE uint64 round_nearest_pow2(int32 v, bool round_half_up = true) { return round_nearest_pow2((uint32)v, round_half_up); } +static INLINE uint64 round_nearest_pow2(int64 v, bool round_half_up = true) { return round_nearest_pow2((uint64)v, round_half_up); } + +// Some compilers' optimizers and some platforms might fubar the generated code from these macros, +// so some tests are run in...tests.cpp +#define sign_8_to_s16(_value) ((int16)(int8)(_value)) +#define sign_9_to_s16(_value) (((int16)((unsigned int)(_value) << 7)) >> 7) +#define sign_10_to_s16(_value) (((int16)((uint32)(_value) << 6)) >> 6) +#define sign_11_to_s16(_value) (((int16)((uint32)(_value) << 5)) >> 5) +#define sign_12_to_s16(_value) (((int16)((uint32)(_value) << 4)) >> 4) +#define sign_13_to_s16(_value) (((int16)((uint32)(_value) << 3)) >> 3) +#define sign_14_to_s16(_value) (((int16)((uint32)(_value) << 2)) >> 2) +#define sign_15_to_s16(_value) (((int16)((uint32)(_value) << 1)) >> 1) + +// This obviously won't convert higher-than-32 bit numbers to signed 32-bit ;) +// Also, this shouldn't be used for 8-bit and 16-bit signed numbers, since you can +// convert those faster with typecasts... +#define sign_x_to_s32(_bits, _value) (((int32)((uint32)(_value) << (32 - _bits))) >> (32 - _bits)) + +static INLINE int32 clamp_to_u8(int32 i) +{ + if(i & 0xFFFFFF00) + i = (((~i) >> 30) & 0xFF); + + return(i); +} + +static INLINE int32 clamp_to_u16(int32 i) +{ + if(i & 0xFFFF0000) + i = (((~i) >> 31) & 0xFFFF); + + return(i); +} + +template static INLINE void clamp(T *val, U minimum, V maximum) +{ + if(*val < minimum) + { + //printf("Warning: clamping to minimum(%d)\n", (int)minimum); + *val = minimum; + } + if(*val > maximum) + { + //printf("Warning: clamping to maximum(%d)\n", (int)maximum); + *val = maximum; + } +} + +#endif diff --git a/waterbox/ss/notes/REFERENCES b/waterbox/ss/notes/REFERENCES new file mode 100644 index 0000000000..2d8d76fe4c --- /dev/null +++ b/waterbox/ss/notes/REFERENCES @@ -0,0 +1,8 @@ +M68000 Programmer's Reference Manual fifth edition (M68000UM/AD REV 4) (ISBN 0-13-541491-1) +M68000 User's Manual Eighth Edition (M68000UM/AD REV 7) (ISBN 0-13-541665-5) + +http://bitsavers.informatik.uni-stuttgart.de/pdf/hitachi/superH/ +http://ppcenter.webou.net/satcart/ +http://dreamjam.co.uk/emuviews/saturn.php +http://koti.kapsi.fi/~antime/sega/ +http://wiki.yabause.org/index.php5?title=CDBlock diff --git a/waterbox/ss/notes/games.txt b/waterbox/ss/notes/games.txt new file mode 100644 index 0000000000..25f518b0fb --- /dev/null +++ b/waterbox/ss/notes/games.txt @@ -0,0 +1,180 @@ +GunBlaze-S: + Game does an excessively-large SCU DMA that runs off the end of VDP1 VRAM and into the VDP1 register area, causing the registers to be + overwritten with (what looks like) garbage. + +Pocket Fighter - Interrupt handler interrupting other interrupt handler in the middle of a read,modify,write sequence of instructions. Same sort of issue as + Street Fighter Alpha 2. + 16-bits var at 0x60443E2 + INT42-> + 0x600D7C4 + 0x600D7D0 + INT41-> + 0x600D738 (writes 0) + +Independence Day + +Batman Forever - Corrupt batmobile graphic during intro(timing issue maybe?). + +Ultimate Mortal Kombat 3 - Major issues and no sound after defeating first opponent. + +Panzer Dragon II - Quasi-illegal window settings. +Panzer Dragon Saga - Quasi-illegal window settings. + +All-Star Baseball 97 - VDP1 glitchy issues + +Space Jam + +Langrisser V - Really sensitive about SMPC timing during startup apparently... + +Street Fighter Alpha 2 - + Line counter @ 0x6050C2E + 0 written to 0x6050C2E in VB Out irq handler @ PC=0x600F374 + VB Out IRQ sometimes happens between PC 0x600F40E and 0x600F414... + + +Christmas Nights - Precision-related VDP1 bug, leading to horribly stretched something or another. + +Magical Drop III - Missing intro graphics. + +Golden Axe The Duel - Flickering title screen + Routine at PC=0x6093DA8, checks byte at 0x607D55C, and if != 0x1, skips writing... + @0x607423C = 0x8001 PC = 0x6093DC4 + @0x607411C = 0x0001 + + @0x607D55C written at PC=0x60910DC + +X-Men vs. Street Fighter - Sometimes locks up if skipping Capcom intro movie. + +Thunderhawk II - Hangs reading from 25D00010, waiting for bit1 to be 1 +Cyberbots - VDP1 timing issue. Hangs during startup. + +Lunar - FMV issues(timing-related; DMA is a bit too fast), @PC=0x60D7C24 + +Nissan Presents Over Drivin' GT-R - SMPC problems + +Break Point - Fails to boot. + +Time Bokan - Freezes a few minutes into gameplay. + [M68K] Exception 9(vec=26) @PC=0x00001ae0 SR=0x2008 ---> PC=0x0000177a, SR=0x2208 + [M68K] Exception 9(vec=26) @PC=0x00001ae4 SR=0x2000 ---> PC=0x0000177a, SR=0x2200 + [M68K] Exception 9(vec=26) @PC=0x00001ae4 SR=0x2000 ---> PC=0x0000177a, SR=0x2200 + [M68K] Exception 9(vec=26) @PC=0x00001af6 SR=0x2008 ---> PC=0x0000177a, SR=0x2208 + +Falcom Classics II - Ys 2 sometimes freezes during startup. + +Virtua Fighter Kids - Wonky FMV. + data @ 0x60435B8 0x60435C0 -- 0x6043318 + 0x060CAAA2 + 0x060CAAE4 + code @ 0x60CA1C6 + PC=0x60BA1D2 + + x inc 0x060FFD38 + (312,gbr) + + Writes to 0x25F80000: + PC=0x20000572 (clock change?) + PC=0x06030AB6 + + +Virtua Cop - Flickery 3D + +Image Fight - uses RBG0 and RBG1 simultaneously during gameplay + +Shienryu - VDP1 output rotation probably. + +Taito Chase HQ - Indexes + +Zero Divide: Bad DMAs? + +---------------------------------------------------------- + 0x060FFC13 (@19,GBR) - SynchCount? + 0x060FFCB0 (@176, GBR) - Resolution/screen mode? +Tilk Aoi Umi kara Kita Shoujo +Zero4 Champ +Yuukyuu Gensoukyoku (Japan) +Yuukyuu no Kobako Official Collection (Japan) +SD Gundam Century S - similar issue to Super Tempo? +Real Sound Kaze no Regret - similar issue to Super Tempo? +Super Tempo - mov.b @(19,gbr), r0 ... 0x060FFC13 + Function pointer of some sort @ 0x60FFFCC + + PC=0x0602C228: 0x0100 -> 0x060FFC12 + PC=0x06020D0A: 0x5 -> 0x060FFC13 + PC=0x06021CB8: 0x0 -> 0x060FFC13 (@0x060FFC12 - 1) + INT41: + PC=0x0602C174: 0x1 -> 0x060FFC13 (((@0x60FFCB0) & 0x10) >> 4) + 1) + PC=0x0602C184: 0x0 -> 0x060FFC13 (@0x060FFC13 - 1) + + Break out of cmp/pz loop manually: + PC=0x06021DAE: 0x1 -> 0x060FFC13 + + What we want...(maybe)...or maybe we need INT4A + PC=0x0602C132 (branch taken) + PC=0x0602C17C + + @0x06021CB8 mov.b r0,@(19,gbr) + Entry point: 0x6021CAC + + + Slave: + @PC=0x0602AB00: first read from 0xFFFFFE11 + FTI by master @PC=0x0602C6A4 + + FTI by master @PC=0x06020CF0 + FTI by master @PC=0x06021CDE + + @PC=0x0602BB7A: read from 0xFFFFFE11 + + + PC=0x06000600: slave entry + +-------------------------------------------------------- + +Virtua Fighter spams SCU DMAs... + +TODO: check SCU write throughput for sparse writes. + +Resident Evil - Probably IM related. Fighting Vipers too +----------------------- +Alone in the Dark +Mr. Bones - PC= 25788C - other: 256D8C ... jumps to 0xC0000064? + +Sega Saturn Choice Cuts - hangs on skipping video, hangs on playing video later. +Marvel Super Heroes vs. Street Fighter - Goes back to CD screen after winning battle? +------------------- + +------------------------------------- + +Probably vblank signal issue for a lot of these... + +Arcade's Greatest Hits - Locks up near Digital Eclipse video. + +Baku Baku - 600091A, Timer0 triggers an IRQ when the software isn't ready? + +Father Christmas - icache or CPU timing related probably + +Doom - Sound effect positioning seems off. + +NBA Jam Extreme - [M68K] Exception 3 @PC=0x0000088e SR=0x2700 ---> PC=0x0000029e, SR=0x2700 + +Whizz - CDB? + +Tenchi Muyou! Ryououki Gokuraku - CDB issues? + +Layer Section - Gets confused and misprograms the CDB? + +Tomb Raider: +Pastel Muses - Tries illegal DMA transfer in indirect mode. +Resident Evil - Almost same: +[SCU] DMA level 1 reading indirect table entries @ 0x060c8000 +[SCU] Starting DMA level 1 transfer; ra=0x00000000 wa=0x05c00060 bc=0x0000001e - read_inc=1, write_inc=0x01 -- indirect=1 7 +[SCU] Attempted DMA from illegal address 0x00000000 + + +---------------------------------------------------------------------------------------------- +Funky Fantasy: +[SCU] DMA level 1 reading indirect table entries @ 0x060c0000 +[SCU] Starting DMA level 1 transfer; ra=0x00000000 wa=0x05c00060 bc=0x0000001e - read_inc=1, write_inc=0x01 -- indirect=1 7 +[SCU] Attempted DMA from illegal address 0x00000000 + diff --git a/waterbox/ss/notes/gen_dsp.cpp_ b/waterbox/ss/notes/gen_dsp.cpp_ new file mode 100644 index 0000000000..da208c04ed --- /dev/null +++ b/waterbox/ss/notes/gen_dsp.cpp_ @@ -0,0 +1,106 @@ +// g++ -Wall -O2 -o gen_dsp gen_dsp.cpp && ./gen_dsp +#include +#include + +int main(int argc, char* argv[]) +{ + FILE* gen = fopen("../scu_dsp_gentab.inc", "wb"); + FILE* misc = fopen("../scu_dsp_misctab.inc", "wb"); + FILE* mvi = fopen("../scu_dsp_mvitab.inc", "wb"); + FILE* dma = fopen("../scu_dsp_dmatab.inc", "wb"); + FILE* jmp = fopen("../scu_dsp_jmptab.inc", "wb"); + + for(int looped = 0; looped < 2; looped++) + { + // + // General + // + fprintf(gen, "{ /* looped=%u */\n", looped); + for(int alu_op = 0; alu_op < 16; alu_op++) + { + fprintf(gen, " { /* alu_op=0x%02x */\n", alu_op); + for(int x_op = 0; x_op < 8; x_op++) + { + fprintf(gen, " { /* x_op=0x%02x */\n", x_op); + for(int y_op = 0; y_op < 8; y_op++) + { + fprintf(gen, " { /* y_op=0x%02x */\n ", y_op); + for(int d1_op_s = 0; d1_op_s < (4/* + 15*/); d1_op_s++) + { + static const unsigned alu_map[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00, 0x08, 0x09, 0x0A, 0x0B, 0x00, 0x00, 0x00, 0x0F }; + static const unsigned x_map[8] = { 0x00, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; + static const unsigned d1s_map[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00 }; + const int d1_op = std::min(3, d1_op_s); + const int d1_s = std::max(0, d1_op_s - 3); + //char label_name[256]; + //snprintf(label_name, sizeof(label_name), "gen_%01x%01x%01x%01x%01x", looped, alu_op, x_op, y_op, d1_op); + //printf("GENSIN(%s, %s, 0x%01x, 0x%01x, 0x%01x, 0x%01x)\n", label_name, looped ? "true" : "false", alu_op, x_op, y_op, d1_op); + //fprintf(stderr, "&&%s, ", label_name); + //fprintf(stderr, "GeneralInstr<%s, 0x%01x,0x%01x,0x%01x,0x%01x,0x%01x>, ", looped ? "true" : "false", alu_map[alu_op], x_map[x_op], y_op, d1_op, d1s_map[d1_s]); + fprintf(gen, "GeneralInstr<%s, 0x%01x,0x%01x,0x%01x,0x%01x>, ", looped ? "true" : "false", alu_map[alu_op], x_map[x_op], y_op, d1_op); + } + fprintf(gen, "\n },\n\n"); + } + fprintf(gen, " },\n"); + } + fprintf(gen, " },\n"); + } + fprintf(gen, "},\n"); + // + // MVI + // + fprintf(mvi, "{ /* looped=%u */\n", looped); + for(unsigned dest = 0; dest < 16; dest++) + { + fprintf(mvi, " {\n "); + for(unsigned cond = 0; cond < 128; cond++) + { + fprintf(mvi, "MVIInstr<%s, 0x%01x, 0x%02x>, ", looped ? "true" : "false", dest, (cond < 0x40) ? 0x00 : cond ); + } + fprintf(mvi, "\n },\n"); + } + fprintf(mvi, " },\n"); + + // + // DMA + // + fprintf(dma, "{ /* looped=%u */\n", looped); + for(unsigned hfd = 0; hfd < 8; hfd++) + { + fprintf(dma, " {\n "); + for(unsigned ram = 0; ram < 8; ram++) + { + fprintf(dma, "DMAInstr<%s, 0x%01x, 0x%01x, 0x%01x, 0x%02x>, ", looped ? "true" : "false", (hfd >> 2) & 0x1, (hfd >> 1) & 0x1, (hfd >> 0) & 0x1, ram); + } + fprintf(dma, "\n },\n"); + } + fprintf(dma, " },\n"); + + // + // JMP + // + fprintf(jmp, "{ /* looped=%u */\n", looped); + for(unsigned cond = 0; cond < 128; cond++) + { + fprintf(jmp, "JMPInstr<%s, 0x%02x>, ", looped ? "true" : "false", (cond < 0x40) ? 0x00 : cond ); + } + fprintf(jmp, " },\n"); + + // + // Misc + // + fprintf(misc, "{ /* looped=%u */ ", looped); + for(unsigned op = 0; op < 4; op++) + { + fprintf(misc, "MiscInstr<%s, %u>, ", looped ? "true" : "false", op); + } + fprintf(misc, " },\n"); + } + + fclose(jmp); + fclose(dma); + fclose(mvi); + fclose(misc); + fclose(gen); + return 0; +} diff --git a/waterbox/ss/scsp.h b/waterbox/ss/scsp.h new file mode 100644 index 0000000000..0e40c6ca10 --- /dev/null +++ b/waterbox/ss/scsp.h @@ -0,0 +1,319 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* scsp.h: +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +class SS_SCSP +{ + public: + + SS_SCSP() MDFN_COLD; + ~SS_SCSP() MDFN_COLD; + + void Reset(bool powering_up) MDFN_COLD; + void RunSample(int16* outlr); + + template + void RW(uint32 A, T& V); //, void (*time_sucker)(); + + INLINE uint16* GetEXTSPtr(void) + { + return EXTS; + } + + INLINE uint16* GetRAMPtr(void) + { + return RAM; + } + + enum + { + GSREG_MVOL = 0, + GSREG_DAC18B, + GSREG_MEM4MB, + GSREG_RBP, + GSREG_RBL, + GSREG_MSLC, + }; + + uint32 GetRegister(const unsigned id, char* const special, const uint32 special_len) MDFN_COLD; + void SetRegister(const unsigned id, const uint32 value) MDFN_COLD; + + private: + + void RecalcSoundInt(void); + void RecalcMainInt(void); + + enum + { + ENV_PHASE_ATTACK = 0, + ENV_PHASE_DECAY1 = 1, + ENV_PHASE_DECAY2 = 2, + ENV_PHASE_RELEASE = 3 + }; + + uint16 SlotRegs[0x20][0x10]; + + struct Slot + { + bool KeyBit; + + uint32 StartAddr; // 20 bits, memory address. + uint16 LoopStart; // 16 bits, in samples. + uint16 LoopEnd; // 16 bits, in samples. + + bool WF8Bit; + uint8 LoopMode; + enum + { + LOOP_DISABLED = 0, + LOOP_NORMAL = 1, + LOOP_REVERSE = 2, + LOOP_ALTERNATING = 3 + }; + + uint8 SourceControl; + enum + { + SOURCE_MEMORY = 0, + SOURCE_NOISE = 1, + SOURCE_ZERO = 2, + SOURCE_UNDEFINED = 3 + }; + + uint8 SBControl; + + union + { + struct + { + uint8 AttackRate; + uint8 Decay1Rate; + uint8 Decay2Rate; + uint8 ReleaseRate; + }; + uint8 EnvRates[4]; + }; + + bool AttackHold; + bool AttackLoopLink; + uint8 DecayLevel; + + uint8 KRS; + uint8 TotalLevel; + bool SoundDirect; // When true, bypass EG, TL, ALFO volume control + + bool StackWriteInhibit; + + uint8 ModLevel; + uint8 ModInputX; + uint8 ModInputY; + + uint8 Octave; + uint16 FreqNum; + + uint8 ALFOModLevel; + uint8 ALFOWaveform; + + uint8 PLFOModLevel; + uint8 PLFOWaveform; + + uint8 LFOFreq; + + bool LFOReset; + + // DSP mix stack + uint8 ToDSPSelect; + uint8 ToDSPLevel; + + int16 DirectVolume[2]; // 1.14 fixed point, derived from DISDL and DIPAN + int16 EffectVolume[2]; // 1.14 fixed point, derived from EFSDL and EFPAN + // + // + uint32 PhaseWhacker; + uint16 CurrentAddr; + bool InLoop; + bool LoopSub; + bool WFAllowAccess; + uint32 EnvLevel; // 0 ... 0x3FF + uint8 EnvPhase; // ENV_PHASE_ATTACK ... ENV_PHASE_RELEASE (0...3) + bool EnvGCBTPrev; + + uint8 LFOCounter; + int16 LFOTimeCounter; + } Slots[32]; + + uint16 EXTS[2]; + + void RunEG(Slot* s, const unsigned key_eg_scale); + + uint8 GetALFO(Slot* s); + int GetPLFO(Slot* s); + void RunLFO(Slot* s); + + uint16 SoundStack[0x40]; + uint16 SoundStackDelayer[4]; + + uint16 MasterVolume; // 1.8 fixed point, derived from MVOL + uint8 MVOL; + bool DAC18bit; + bool Mem4Mb; + + uint32 SlotMonitorWhich; + uint16 SlotMonitorData; + + bool KeyExecute; + uint32 LFSR; + uint32 GlobalCounter; + + // + // + enum + { + MIDIF_INPUT_EMPTY = 0x01, + MIDIF_INPUT_FULL = 0x02, + MIDIF_INPUT_OFLOW = 0x04, + MIDIF_OUTPUT_EMPTY= 0x08, + MIDIF_OUTPUT_FULL = 0x10 + }; + struct + { + uint8 InputFIFO[4]; + uint8 InputRP, InputWP, InputCount; + + uint8 OutputFIFO[4]; + uint8 OutputRP, OutputWP, OutputCount; + + uint8 Flags; + + // + INLINE uint8 ReadInput(void) + { + uint8 ret = InputFIFO[InputRP]; // May not be correct for InputCount == 0; test. + + if(InputCount) + { + InputRP = (InputRP + 1) & 0x3; + InputCount--; + Flags &= ~MIDIF_INPUT_FULL; + if(!InputCount) + Flags |= MIDIF_INPUT_EMPTY; + } + + return ret; + } + + INLINE void WriteOutput(uint8 V) + { + if(OutputCount == 4) // May not be correct; test. + return; + + OutputFIFO[OutputWP] = V; + OutputWP = (OutputWP + 1) & 0x3; + OutputCount++; + + Flags &= ~MIDIF_OUTPUT_EMPTY; + if(OutputCount == 4) + Flags |= MIDIF_OUTPUT_FULL; + } + + void Reset(void) + { + memset(InputFIFO, 0, sizeof(InputFIFO)); + memset(OutputFIFO, 0, sizeof(OutputFIFO)); + + InputRP = InputWP = InputCount = 0; + OutputRP = OutputWP = OutputCount = 0; + + Flags = MIDIF_INPUT_EMPTY | MIDIF_OUTPUT_EMPTY; + } + } MIDI; + // + // + uint16 SCIEB; + uint16 SCIPD; + + uint16 MCIEB; + uint16 MCIPD; + + uint8 SCILV[3]; + // + // + struct + { + uint8 Control; + uint8 Counter; + bool PrevClockIn; + int32 Reload; + } Timers[3]; + // + // + // DMEA, DRGA, and DTLG are apparently not altered by executing DMA. + // + uint32 DMEA; + uint16 DRGA; + uint16 DTLG; + + bool DMA_Execute; + bool DMA_Direction; + bool DMA_Gate; + + void RunDMA(void); + // + // + uint8 RBP; + uint8 RBL; + void RunDSP(void); + + struct DSPS + { + uint64 MPROG[0x80]; + uint32 TEMP[0x80]; // 24 bit + uint32 MEMS[0x20]; // 24 bit + uint16 COEF[64]; // 13 bit + uint16 MADRS[32]; // 16 bit + + uint32 MIXS[0x10]; // 20 bit + uint16 EFREG[0x10]; + + uint32 INPUTS; // 24 bit + + uint32 Product; // 26 bit + uint32 SFT_REG; // 26 bit + uint16 FRC_REG; // 13 bit + uint32 Y_REG; // 24 bit, latches INPUTS + uint16 ADRS_REG; // 12 bit, latches output of A_SEL(which selects between shifter output and upper 8 bits of INPUTS + + uint16 MDEC_CT; + + uint32 RWAddr; + + bool WritePending; + uint16 WriteValue; + + uint8 ReadPending; // = 1 (NOFL=0), =2 (NOFL=1) at time or MRT + uint32 ReadValue; + } DSP; + + // + // + + uint16 RAM[262144 * 2]; // *2 for dummy so we don't have to have so many conditionals in the playback code. +}; + diff --git a/waterbox/ss/scsp.inc b/waterbox/ss/scsp.inc new file mode 100644 index 0000000000..10602a6934 --- /dev/null +++ b/waterbox/ss/scsp.inc @@ -0,0 +1,1550 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* scsp.inc - SCSP Emulation +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +/* + TODO: + Open bus emulation and cycle timing granularity instead of sample(someday?); be careful with DSP input/output buffering + with respect to dry/direct output path delay, and the mapping of the buffers to the address space. + + Finish MIDI interface emulation. + + Proper reset/power-on state. + + Mem4Mb +*/ + +SS_SCSP::SS_SCSP() +{ + memset(&RAM[0x40000], 0x00, 0x80000); // Zero out dummy part. + + Reset(true); +} + +SS_SCSP::~SS_SCSP() +{ + + +} + +void SS_SCSP::RecalcSoundInt(void) // Sound CPU interrupts +{ + unsigned mask_test; + unsigned lvmasked[3]; + unsigned out_level = 0; + + mask_test = SCIPD & SCIEB; + if(mask_test &~ 0xFF) + mask_test = (mask_test & 0xFF) | 0x80; + + lvmasked[0] = (SCILV[0] & mask_test) << 0; + lvmasked[1] = (SCILV[1] & mask_test) << 1; + lvmasked[2] = (SCILV[2] & mask_test) << 2; + + for(unsigned i = 0; i < 8; i++) + { + unsigned l = (lvmasked[0] & 0x1) | (lvmasked[1] & 0x2) | (lvmasked[2] & 0x4); + + if(l > out_level) + out_level = l; + + lvmasked[0] >>= 1; + lvmasked[1] >>= 1; + lvmasked[2] >>= 1; + } + + SCSP_SoundIntChanged(out_level); +#if 0 + if(mask_test) + { + const unsigned shift = std::min(7, MDFN_tzcount32(mask_test)); + unsigned level; + + level = (((SCILV[0] >> which) & 0x1) << 0) | + (((SCILV[1] >> which) & 0x1) << 1) | + (((SCILV[2] >> which) & 0x1) << 2); + } +#endif +} + +void SS_SCSP::RecalcMainInt(void) // Main CPU interrupts +{ + SCSP_MainIntChanged((bool)(MCIPD & MCIEB)); +} + +void SS_SCSP::Reset(bool powering_up) +{ + // + // May need to add a DecodeSlotReg() function or something similar if we implement + // more aggressive slot register value optimizations on writes in the future. + // + memset(SlotRegs, 0, sizeof(SlotRegs)); + memset(Slots, 0, sizeof(Slots)); + + // Some SSFs require this; TODO: test to see if this is correct for a reset, + // and if not, move it into special SSF loading code. + for(unsigned i = 0; i < 32; i++) + { + Slots[i].EnvLevel = 0x3FF; + Slots[i].EnvPhase = ENV_PHASE_RELEASE; + } + + memset(SoundStack, 0, sizeof(SoundStack)); + memset(SoundStackDelayer, 0, sizeof(SoundStackDelayer)); + + if(powering_up) + { + memset(RAM, 0x00, 0x80000); // or something else? + } + + // + // + MVOL = 0; + MasterVolume = 0; + + SlotMonitorWhich = 0; + SlotMonitorData = 0; + + DAC18bit = false; + Mem4Mb = false; + + KeyExecute = false; + LFSR = 1; + GlobalCounter = 0; + + MIDI.Reset(); + // + // + DMEA = 0; + DRGA = 0; + DTLG = 0; + + DMA_Execute = false; + DMA_Direction = false; + DMA_Gate = false; + // + // + for(unsigned i = 0; i < 3; i++) + { + Timers[i].Control = 0; + Timers[i].Counter = 0; + Timers[i].PrevClockIn = false; + } + + // + // + RBP = 0; + RBL = 0; + + memset(&DSP, 0, sizeof(DSP)); + DSP.MDEC_CT = 0; + // + // + SCIEB = 0; + SCIPD = 0; + + MCIEB = 0; + MCIPD = 0; + + for(unsigned i = 0; i < 3; i++) + SCILV[i] = 0; + + RecalcSoundInt(); + RecalcMainInt(); +} + +static INLINE void SDL_PAN_ToVolume(int16* outvol, const unsigned level, const unsigned pan) +{ + const bool pan_which = (bool)(pan & 0x10); + unsigned basev; + unsigned panv; + + basev = (0x80 << level); + + if(!level) + basev = 0; + + panv = basev >> ((pan & 0x0F) >> 1); + if(pan & 0x01) + panv -= (panv >> 2); + + if((pan & 0x0F) == 0x0F) + panv = 0; + + outvol[ pan_which] = panv; + outvol[!pan_which] = basev; +} + +template +INLINE void SS_SCSP::RW(uint32 A, T& DBV) +{ + if(A < 0x100000) + { + if(MDFN_UNLIKELY(A >= 0x80000)) + { + if(IsWrite) + SS_DBG(SS_DBG_WARNING | SS_DBG_SCSP, "[SCSP] %zu-byte write of value 0x%08x to unmapped SCSP RAM address 0x%06x\n", sizeof(T), DBV, A); + else + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SCSP, "[SCSP] %zu-byte read from unmapped SCSP RAM address 0x%06x\n", sizeof(T), A); + DBV = 0; + } + } + else + { + ne16_rwbo_be(RAM, A, &DBV); + } + return; + } + + if(A < 0x100400) + { + //if(IsWrite) + // SS_DBG(SS_DBG_SCSP_REGW, "[SCSP] %zu-byte write to slot 0x%02x register offset 0x%02x: 0x%0*x\n", sizeof(T), (A >> 5) & 0x1F, A & 0x1F, (int)(2 * sizeof(T)), DBV); + // + // Slot regs + // + const unsigned slotnum = (A >> 5) & 0x1F; + + ne16_rwbo_be(SlotRegs[slotnum], A & 0x1F, &DBV); + + if(IsWrite) + { + auto* s = &Slots[slotnum]; + uint16& SRV = SlotRegs[slotnum][(A >> 1) & 0xF]; + + switch((A >> 1) & 0xF) + { + case 0x00: + KeyExecute |= (bool)(SRV & 0x1000); + SRV &= 0x0FFF; + + s->KeyBit = (SRV >> 11) & 0x1; + s->SBControl = (SRV >> 9) & 0x3; + s->SourceControl = (SRV >> 7) & 0x3; + s->LoopMode = (SRV >> 5) & 0x3; + s->WF8Bit = (SRV >> 4) & 0x1; + s->StartAddr = (s->StartAddr & 0xFFFF) | ((SRV & 0xF) << 16); + break; + + case 0x01: + s->StartAddr = (s->StartAddr &~ 0xFFFF) | SRV; + break; + + case 0x02: + s->LoopStart = SRV; + break; + + case 0x03: + s->LoopEnd = SRV; + break; + + case 0x04: + s->AttackRate = SRV & 0x1F; + s->AttackHold = (SRV >> 5) & 0x1; + s->Decay1Rate = (SRV >> 6) & 0x1F; + s->Decay2Rate = (SRV >> 11) & 0x1F; + break; + + case 0x05: + if(SRV & 0x8000) + { + //SS_DBG(SS_DBG_WARNING | SS_DBG_SCSP, "[SCSP] Unknown bits non-zero in slot %u, register %u\n", slotnum, (A >> 1) & 0xF); + } + + s->ReleaseRate = SRV & 0x1F; + s->DecayLevel = (SRV >> 5) & 0x1F; + s->KRS = (SRV >> 10) & 0xF; + s->AttackLoopLink = (SRV >> 14) & 0x1; + break; + + case 0x06: + SRV &= 0x0FFF; + if(SRV & 0x0C00) + { + //SS_DBG(SS_DBG_WARNING | SS_DBG_SCSP, "[SCSP] Unknown bits non-zero in slot %u, register %u\n", slotnum, (A >> 1) & 0xF); + } + + s->TotalLevel = SRV & 0xFF; + s->SoundDirect = (SRV >> 8) & 0x1; + s->StackWriteInhibit = (SRV >> 9) & 0x1; + break; + + case 0x07: + s->ModInputY = SRV & 0x3F; + s->ModInputX = (SRV >> 6) & 0x3F; + s->ModLevel = (SRV >> 12) & 0xF; + break; + + case 0x08: + if(SRV & 0x8400) + { + //SS_DBG(SS_DBG_WARNING | SS_DBG_SCSP, "[SCSP] Unknown bits non-zero in slot %u, register %u\n", slotnum, (A >> 1) & 0xF); + } + + s->FreqNum = SRV & 0x7FF; + s->Octave = (SRV >> 11) & 0xF; + break; + + case 0x09: + s->ALFOModLevel = SRV & 0x7; + s->ALFOWaveform = (SRV >> 3) & 0x3; + s->PLFOModLevel = (SRV >> 5) & 0x7; + s->PLFOWaveform = (SRV >> 8) & 0x3; + s->LFOFreq = (SRV >> 10) & 0x1F; + s->LFOReset = (SRV >> 15) & 0x1; + break; + + case 0x0A: + SRV &= 0x00FF; + if(SRV & 0x0080) + { + //SS_DBG(SS_DBG_WARNING | SS_DBG_SCSP, "[SCSP] Unknown bits non-zero in slot %u, register %u\n", slotnum, (A >> 1) & 0xF); + } + s->ToDSPLevel = SRV & 0x7; + s->ToDSPSelect = (SRV >> 3) & 0xF; + break; + + case 0x0B: + SDL_PAN_ToVolume(s->DirectVolume, (SRV >> 13) & 0x7, (SRV >> 8) & 0x1F); + SDL_PAN_ToVolume(s->EffectVolume, (SRV >> 5) & 0x7, (SRV >> 0) & 0x1F); + break; + + case 0x0C: case 0x0D: case 0x0E: case 0x0F: + SRV = 0; + break; + } + } + + return; + } + + if(A < 0x100430) + { + // OldReg = (OldReg &~ mask) | ((DBV << shift) & mask & whatever); + unsigned mask = 0xFFFF; + unsigned shift = 0; + + if(sizeof(T) == 1) + { + shift = ((A & 1) ^ 1) << 3; + mask = 0xFF << shift; + } + + // + // Common regs + // + switch((A >> 1) & 0x1F) + { + case 0x00: // MVOL (W), DB (W), M4 (W) + if(IsWrite) + { + uint16 tmp = MVOL | (DAC18bit << 8) | (Mem4Mb << 9); + + tmp = (tmp &~ mask) | ((DBV << shift) & mask); + + MVOL = (tmp & 0xF); + DAC18bit = (tmp >> 8) & 1; + Mem4Mb = (tmp >> 9) & 1; + + // + { + unsigned mv; + + mv = 0x2 << (MVOL >> 1); + if(!(MVOL & 1)) + mv -= (mv >> 2); + + if(!MVOL) + mv = 0; + + MasterVolume = mv; + } + } + else + DBV = 0; + break; + + case 0x01: // RBP (W), RBL (W) + if(IsWrite) + { + uint16 tmp = RBP | (RBL << 7); + tmp = (tmp &~ mask) | ((DBV << shift) & mask); + RBP = tmp & 0x7F; + RBL = (tmp >> 7) & 0x3; + } + else + DBV = 0; + break; + + case 0x02: // MIDI input buffer, Input Empty, Input Full, Input Overflow, Output Empty, Output Full (all R) + if(!IsWrite) + { + if(!shift) + { + // TODO: Test correct order of flags latching returning versus input fetching/latching(also maybe take into consideration + // 16-bit access from SCU being split into 2x 8-bit accesses on the real thing...). + unsigned tmp = MIDI.Flags << 8; + tmp |= MIDI.ReadInput(); + DBV = tmp & mask; + } + else + DBV = MIDI.Flags; + } + break; + + case 0x03: // MOBUF (W) + if(IsWrite) + { + + } + else + DBV = 0; + break; + + case 0x04: // CA/SGC/EG (R), MSLC (W) + if(IsWrite) + { + uint16 tmp = (SlotMonitorWhich << 11); + tmp = (tmp &~ mask) | ((DBV << shift) & mask); + SlotMonitorWhich = (tmp >> 11) & 0x1F; + } + else + { + DBV = (SlotMonitorData & mask) >> shift; + } + break; + + case 0x05: + case 0x06: + case 0x07: + case 0x08: + if(!IsWrite) + DBV = 0; + break; + + case 0x09: // DMEA(low) (W) + if(IsWrite) + { + uint16 tmp = DMEA << 1; + tmp = (tmp &~ mask) | ((DBV << shift) & mask); + DMEA = tmp >> 1; + } + else + DBV = 0; + break; + + case 0x0A: // DRGA (W), DMEA(high) (W) + if(IsWrite) + { + uint16 tmp = ((DMEA >> 3) & 0xF000) | (DRGA << 1); + tmp = (tmp &~ mask) | ((DBV << shift) & mask); + DMEA = (DMEA & 0x7FFF) | ((tmp & 0xF000) << 3); + DRGA = (tmp >> 1) & 0x7FF; + } + else + DBV = 0; + break; + + case 0x0B: // DTLG(W), EX(R/W), DI(R/W), GA(R/W) + if(IsWrite) + { + //const bool prev_execute = DMA_Execute; + uint16 tmp = (DTLG << 1) | (DMA_Execute << 12) | (DMA_Direction << 13) | (DMA_Gate << 14); + + tmp = (tmp &~ mask) | ((DBV << shift) & mask); + + DTLG = (tmp >> 1) & 0x7FF; + DMA_Execute |= (tmp >> 12) & 0x1; + DMA_Direction = (tmp >> 13) & 0x1; + DMA_Gate = (tmp >> 14) & 0x1; + +#if 0 + if(!prev_execute && DMA_Execute) + { + printf("[SCSP] DMA Started; Memory Address: 0x%06x, Register Address: 0x%03x, Length: 0x%03x Direction: %u, Gate: %u\n", + DMEA << 1, DRGA << 1, DTLG << 1, DMA_Direction, DMA_Gate); + } +#endif + RunDMA(); + } + else + { + uint16 tmp = (DMA_Execute << 12) | (DMA_Direction << 13) | (DMA_Gate << 14); + + DBV = (tmp & mask) >> shift; + } + break; + + case 0x0C: // TIMA(W), TACTL(W) + case 0x0D: // TIMB(W), TBCTL(W) + case 0x0E: // TIMC(W), TCCTL(W) + if(IsWrite) + { + auto* t = &Timers[((A >> 1) & 0x1F) - 0x0C]; + uint16 tmp = (t->Control << 8); + tmp = (tmp &~ mask) | ((DBV << shift) & mask); + t->Control = (tmp >> 8) & 0x7; + + if(!shift) + t->Reload = DBV & 0xFF; + + //printf("Timer(%zu-byte) %u: %04x\n", sizeof(T), ((A >> 1) & 0x1F) - 0x0C, DBV); + } + else + DBV = 0; + break; + + case 0x0F: // SCIEB (R/W) + if(IsWrite) + { + SCIEB = (SCIEB &~ mask) | ((DBV << shift) & mask & 0x7FF); + RecalcSoundInt(); + } + else + DBV = (SCIEB & mask) >> shift; + break; + + case 0x10: // SCIPD (R) (b5 can be written, like MCIPD) + if(IsWrite) + { + SCIPD |= ((DBV << shift) & mask & 0x020); + RecalcSoundInt(); + } + else + DBV = (SCIPD & mask) >> shift; + break; + + case 0x11: // SCIRE (W) + if(IsWrite) + { + SCIPD &= ~((DBV << shift) & mask); + RecalcSoundInt(); + } + else + DBV = 0; + break; + + case 0x12: // SCILV0 (W) + case 0x13: // SCILV1 (W) + case 0x14: // SCILV2 (W) + if(IsWrite) + { + const unsigned index = ((A >> 1) & 0x1F) - 0x12; + + SCILV[index] = (SCILV[index] &~ mask) | ((DBV << shift) & mask & 0x00FF); + RecalcSoundInt(); + } + else + DBV = 0; + break; + + case 0x15: // MCIEB (W) + if(IsWrite) + { + MCIEB = (MCIEB &~ mask) | ((DBV << shift) & mask & 0x7FF); + RecalcMainInt(); + } + else + DBV = 0; + break; + + case 0x16: // MCIPD (R) (when b5=1 is written, set corresponding bit to 1; writing 0 has no apparent effect) + if(IsWrite) + { + MCIPD |= ((DBV << shift) & mask & 0x020); + RecalcMainInt(); + } + else + DBV = (MCIPD & mask) >> shift; + break; + + case 0x17: // MCIRE (W) + if(IsWrite) + { + MCIPD &= ~((DBV << shift) & mask); + RecalcMainInt(); + } + else + DBV = 0; + break; + + case 0x18: + case 0x19: + case 0x1A: + case 0x1B: + case 0x1C: + case 0x1D: + case 0x1E: + case 0x1F: + if(IsWrite) + { + } + else + DBV = 0; + break; + } + + return; + } + + if(A >= 0x100600 && A <= 0x10067F) + { + // + // Sound stack data + // + if(IsWrite) + *(T*)((uint8*)SoundStack + ((A & 0x7F &~(sizeof(T) - 1)) ^ (2 - sizeof(T)))) = DBV; + else + DBV = *(T*)((uint8*)SoundStack + ((A & 0x7F & ~(sizeof(T) - 1)) ^ (2 - sizeof(T)))); + + return; + } + + if(A >= 0x100700 && A <= 0x10077F) + { + // + // DSP coefficients + // + const unsigned index = (A & 0x7F) >> 1; + unsigned mask = 0xFFFF; + unsigned shift = 0; + + if(sizeof(T) == 1) + { + shift = ((A & 1) ^ 1) << 3; + mask = 0xFF << shift; + } + + if(IsWrite) + DSP.COEF[index] = (((DSP.COEF[index] << 3) &~ mask) | ((DBV << shift) & mask)) >> 3; + else + DBV = ((DSP.COEF[index] << 3) & mask) >> shift; + + return; + } + + if(A >= 0x100780 && A <= 0x1007BF) + { + // + // DSP memory addresses + // + ne16_rwbo_be(DSP.MADRS, A & 0x3F, &DBV); + + return; + } + + if(A >= 0x100800 && A <= 0x100BFF) + { + // + // DSP microprogram + // + ne64_rwbo_be(DSP.MPROG, A & 0x3FF, &DBV); + + return; + } + + // + // DSP work buffer + // + if(A >= 0x100C00 && A <= 0x100DFF) + { + const unsigned index = (A & 0x1FF) >> 2; + unsigned mask; + unsigned shift = (A & 2) ? 8 : 0; + + if(sizeof(T) == 1) + { + shift += ((A & 1) ^ 1) << 3; + mask = 0xFF << shift; + } + else + mask = 0xFFFF << shift; + + if(!(A & 2)) + mask &= 0xFF; + + if(IsWrite) + DSP.TEMP[index] = (DSP.TEMP[index] &~ mask) | ((DBV << shift) & mask & 0xFFFFFF); + else + DBV = (DSP.TEMP[index] & mask) >> shift; + + return; + } + + // + // DSP memory read stack + // + if(A >= 0x100E00 && A <= 0x100E7F) + { + const unsigned index = (A & 0x7F) >> 2; + unsigned mask; + unsigned shift = (A & 2) ? 8 : 0; + + if(sizeof(T) == 1) + { + shift += ((A & 1) ^ 1) << 3; + mask = 0xFF << shift; + } + else + mask = 0xFFFF << shift; + + if(!(A & 2)) + mask &= 0xFF; + + if(IsWrite) + DSP.MEMS[index] = (DSP.MEMS[index] &~ mask) | ((DBV << shift) & mask & 0xFFFFFF); + else + DBV = (DSP.MEMS[index] & mask) >> shift; + + return; + } + + // + // DSP mix stack + // + if(A >= 0x100E80 && A <= 0x100EBF) + { + const unsigned index = (A & 0x3F) >> 2; + unsigned mask; + unsigned shift = (A & 2) ? 4 : 0; + + if(sizeof(T) == 1) + { + shift += ((A & 1) ^ 1) << 3; + mask = 0xFF << shift; + } + else + mask = 0xFFFF << shift; + + if(!(A & 2)) + mask &= 0x0F; + + if(IsWrite) + DSP.MIXS[index] = (DSP.MIXS[index] &~ mask) | ((DBV << shift) & mask & 0xFFFFFF); + else + DBV = (DSP.MIXS[index] & mask) >> shift; + + return; + } + + // + // + // + if(A >= 0x100EC0 && A <= 0x100EDF) + { + ne16_rwbo_be(DSP.EFREG, A & 0x1F, &DBV); + + return; + } + + if(A >= 0x100EE0 && A <= 0x100EE3) + { + if(!IsWrite) + DBV = ne16_rbo_be(EXTS, A & 0x3); + + return; + } + + if(IsWrite) + SS_DBG(SS_DBG_WARNING | SS_DBG_SCSP, "[SCSP] Unknown %zu-byte write of value 0x%08x to address 0x%08x\n", sizeof(T), DBV, A); + else + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SCSP, "[SCSP] Unknown %zu-byte read from address 0x%08x\n", sizeof(T), A); + DBV = 0; + } +} + + +// +// Gate bit only forces the value to 0, the read still seems to occur(or at the very least timing side effects occur for the case of reg->mem). +// +void NO_INLINE SS_SCSP::RunDMA(void) +{ + if(!DMA_Execute) + return; + + uint32 length = DTLG; + uint32 mem_addr = DMEA; + uint32 reg_addr = DRGA; + bool dir = DMA_Direction; + bool gate = DMA_Gate; + + while(length) + { + if(dir) + { + uint16 tmp; + + RW(0x100000 | (reg_addr << 1), tmp); + + if(gate) + tmp = 0; + + if(MDFN_LIKELY(mem_addr < 0x40000)) + RAM[mem_addr] = tmp; + } + else + { + uint16 tmp = RAM[mem_addr]; + + if(gate) + tmp = 0; + + RW(0x100000 | (reg_addr << 1), tmp); + } + + reg_addr = (reg_addr + 1) & 0x000007FF; + mem_addr = (mem_addr + 1) & 0x0007FFFF; + length = length - 1; + } + + DMA_Execute = false; + SCIPD |= 0x10; + MCIPD |= 0x10; + RecalcSoundInt(); + RecalcMainInt(); +} + + +INLINE void SS_SCSP::RunEG(Slot* s, const unsigned key_eg_scale) +{ + if(s->EnvPhase == ENV_PHASE_DECAY1 && (s->EnvLevel >> 5) == s->DecayLevel) + s->EnvPhase = ENV_PHASE_DECAY2; + + // + // + // + bool ClockEG; + const unsigned ERateNoScale = s->EnvRates[s->EnvPhase]; + const unsigned ERate = std::min(0x1F, key_eg_scale + ERateNoScale); + const unsigned ERateWBT = (0x22 - std::min(0x18, ERate)) >> 1; + const bool EGCBT = (GlobalCounter >> ERateWBT) & 1; + + ClockEG = !s->EnvGCBTPrev && EGCBT; + + if((ERate < 0x18) && (ERate & 1)) + ClockEG &= (bool)((GlobalCounter >> (ERateWBT + 1)) & 0x3); + + ClockEG &= (bool)ERateNoScale; + + s->EnvGCBTPrev = EGCBT; + + if(ClockEG) + { + const int32 inc_base = (s->EnvPhase == ENV_PHASE_ATTACK) ? ~s->EnvLevel : 16; + const unsigned ermaxo = std::max(0x18, std::min(0x1E, ERate)); + const uint32 srac = ((0x20 - ermaxo) >> 1) + (ermaxo & 1 & (GlobalCounter >> (ERateWBT + 1))); + + //if(s == &Slots[0] && s->EnvLevel) + // printf("EP: %u, EL: 0x%04x, AR: 0x%02x, %d, %u --- %02x\n", s->EnvPhase, s->EnvLevel, s->AttackRate, inc_base, srac, ERate); + + s->EnvLevel += inc_base >> srac; + + if((int32)s->EnvLevel >= 0x3FF) + { + s->WFAllowAccess = false; + s->EnvLevel = 0x3FF; + } + + if((int32)s->EnvLevel < 0) + s->EnvLevel = 0; + } + // + // + // + + if(s->EnvPhase == ENV_PHASE_ATTACK) + { + if((s->AttackLoopLink && s->InLoop) || (!s->AttackLoopLink && s->EnvLevel == 0)) + s->EnvPhase = ENV_PHASE_DECAY1; + } +} + +// +// Take care in handling LFSR, or else the volume of noise-ALFO-modulated noise will +// be quite off, or have a DC bias. +// +INLINE uint8 SS_SCSP::GetALFO(Slot* s) +{ + uint8 ret; + + switch(s->ALFOWaveform) + { + default: + case 0: // Saw + ret = s->LFOCounter &~ 1; + break; + + case 1: // Square + ret = ((int8)s->LFOCounter >> 7) &~ 1; + break; + + case 2: // Triangle + ret = (unsigned)(s->LFOCounter ^ ((int8)s->LFOCounter >> 7)) << 1; + break; + + case 3: // Noise + ret = LFSR &~ 1; + break; + } + + ret >>= (7 - s->ALFOModLevel); + + if(!s->ALFOModLevel) + ret = 0; + + return ret; +} + +INLINE int SS_SCSP::GetPLFO(Slot* s) +{ + int ret; + + switch(s->PLFOWaveform) + { + default: + case 0: // Saw + ret = (int8)(s->LFOCounter &~ 1); + break; + + case 1: // Square + ret = (int8)((s->LFOCounter & 0x80) ? 0x80 : 0x7E); + break; + + case 2: // Triangle + ret = (int8)(((s->LFOCounter & 0x3F) ^ ((s->LFOCounter & 0x40) ? 0x3F : 0x00) ^ ((s->LFOCounter & 0x80) ? 0x7F : 0x00)) << 1); + break; + + case 3: // Noise + ret = (int8)(LFSR &~ 1); + break; + } + + ret >>= (7 - s->PLFOModLevel); + + if(!s->PLFOModLevel) + ret = 0; + + ret = ((0x40 ^ (s->FreqNum >> 4)) * ret) >> 6; + + return ret; +} + +INLINE void SS_SCSP::RunLFO(Slot* s) +{ + s->LFOTimeCounter--; + if(s->LFOTimeCounter <= 0) + { + s->LFOCounter++; + s->LFOTimeCounter = (((8 - (s->LFOFreq & 0x3)) << 7) >> (s->LFOFreq >> 2)) - 4; + } + + if(s->LFOReset) + s->LFOCounter = 0; +} + +// +// +// +static INLINE uint32 dspfloat_to_int(const uint16 inv) +{ + const uint32 sign_xor = (int32)((inv & 0x8000) << 16) >> 1; + const uint32 exp = (inv >> 11) & 0xF; + uint32 ret; + + ret = inv & 0x7FF; + if(exp < 12) + ret |= 0x800; + ret <<= 11 + 8; + ret ^= sign_xor; + ret = (int32)ret >> (8 + std::min(11, exp)); + + return ret & 0xFFFFFF; +} + +static INLINE uint32 int_to_dspfloat(const uint32 inv) +{ + const uint32 invsl8 = inv << 8; + const uint32 sign_xor = (int)invsl8 >> 31; + uint32 exp, shift; + uint32 ret; + + exp = MDFN_lzcount32(((invsl8 ^ sign_xor) << 1) | (1 << 19)); + shift = exp - (bool)(exp == 12); //std::min(11, exp); + + ret = (int32)invsl8 >> (19 - shift); + ret &= 0x87FF; + ret |= exp << 11; + + return ret; +} + +static const uint16 SB_XOR_Table[4] = { 0x0000, 0x7FFF, 0x8000, 0xFFFF }; + +INLINE void SS_SCSP::RunDSP(void) +{ + // + // + // Instruction field order/width RE'ing notes: + // + // Bit 0: NXADDR + // Bit 1: ADRGB + // Bit 2-6: MASA + // Bit 8: NOFL (disables floating-point conversion when =1, instead just shifting by 8); has effect with MRT=1 or MWT=1 + // Bit 9-14: CRA (Coefficient read address, input into Y_SEL) + // Bit 16: BSEL + // Bit 17: ZERO + // Bit 18: NEGB (apparently no effect when ZERO=1) + // Bit 19: YRL + // Bit 20: SHFT0 + // Bit 21: SHFT1 + // Bit 22: FRCL + // Bit 23: ADRL (latches A_SEL output into ADRS_REG) + // Bit 24-27: EWA(EFREG write address) + // Bit 28: EWT(EFREG write enable) + // Bit 29: MRT (Memory read trigger; to read: [MWR=1] [whatever instruction] [IWT=1] + // Bit 30: MWT (Memory write trigger) + // Bit 31: TABLE + // Bit 32-36: IWA (MEMS write address) + // Bit 37: IWT (MEMS write trigger) + // Bit 38-43: IRA (0x00-0x1F MEMS, 0x20-0x2F MIXS) + // Bit 45-46: YSEL + // Bit 47: XSEL + // Bit 48-54: TWA(temp write address) Seems to be an offset added to a counter changed each sample. + // Bit 55: TWT(temp write trigger) WARNING: Setting this to 1 for all 128 steps apparently can cause a CPU to freeze up if it tries to read/write TEMP afterward. + // Bit 56-62: TRA(temp read address) + for(unsigned step = 0; step < 128; step++) + { + const uint64 instr = DSP.MPROG[step]; + +/* + assert(!(instr & (1ULL << 7))); + assert(!(instr & (1ULL << 15))); + assert(!(instr & (1ULL << 44))); + assert(!(instr & (1ULL << 63))); +*/ + + const bool NXADDR = (instr >> 0) & 1; + const bool ADRGB = (instr >> 1) & 1; + const unsigned MASA = (instr >> 2) & 0x1F; + const bool NOFL = (instr >> 8) & 1; + const unsigned CRA = (instr >> 9) & 0x3F; + const bool BSEL = (instr >> 16) & 1; + const bool ZERO = (instr >> 17) & 1; + const bool NEGB = (instr >> 18) & 1; + const bool YRL = (instr >> 19) & 1; + const bool SHFT0 = (instr >> 20) & 1; + const bool SHFT1 = (instr >> 21) & 1; + const bool FRCL = (instr >> 22) & 1; + const bool ADRL = (instr >> 23) & 1; + const unsigned EWA = (instr >> 24) & 0x0F; + const bool EWT = (instr >> 28) & 1; + const bool MRT = (instr >> 29) & 1; + const bool MWT = (instr >> 30) & 1; + const bool TABLE = (instr >> 31) & 1; + const unsigned IWA = (instr >> 32) & 0x1F; + const bool IWT = (instr >> 37) & 1; + const unsigned IRA = (instr >> 38) & 0x3F; + const unsigned YSEL = (instr >> 45) & 0x03; + const bool XSEL = (instr >> 47) & 1; + const unsigned TEMPWriteAddr = ((instr >> 48) + DSP.MDEC_CT) & 0x7F; + const bool TWT = (instr >> 55) & 1; + const unsigned TEMPReadAddr = ((instr >> 56) + DSP.MDEC_CT) & 0x7F; + +#if 0 + if(!(step & 1) && (MWT || MRT)) + SS_DBG(SS_DBG_WARNING | SS_DBG_SCSP, "[SCSP] Memory access requested at even DSP step %u; 0x%016llx\n", step, instr); + + if(MWT & MRT) + SS_DBG(SS_DBG_WARNING | SS_DBG_SCSP, "[SCSP] MWT and MRT both 1 at DSP step %u; 0x%016llx\n", step, instr); +#endif + // + // + if(IRA & 0x20) + { + if(IRA & 0x10) + { + if(!(IRA & 0xE)) + DSP.INPUTS = EXTS[IRA & 0x1] << 8; + } + else + { + DSP.INPUTS = DSP.MIXS[IRA & 0xF] << 4; + } + } + else + { + DSP.INPUTS = DSP.MEMS[IRA & 0x1F]; + } + + const int32 INPUTS = sign_x_to_s32(24, DSP.INPUTS); + const int32 TEMP = sign_x_to_s32(24, DSP.TEMP[TEMPReadAddr]); + const int32 X_SEL_Inputs[2] = { TEMP, INPUTS }; + const uint16 Y_SEL_Inputs[4] = { DSP.FRC_REG, DSP.COEF[CRA], (uint16)((DSP.Y_REG >> 11) & 0x1FFF), (uint16)((DSP.Y_REG >> 4) & 0x0FFF) }; + const uint32 SGA_Inputs[2] = { (uint32)TEMP, DSP.SFT_REG }; + // + // + // + if(YRL) + { + DSP.Y_REG = INPUTS & 0xFFFFFF; + } + // + // + // + int32 ShifterOutput; + + ShifterOutput = (uint32)sign_x_to_s32(26, DSP.SFT_REG) << (SHFT0 ^ SHFT1); + + if(!SHFT1) + { + if(ShifterOutput > 0x7FFFFF) + ShifterOutput = 0x7FFFFF; + else if(ShifterOutput < -0x800000) + ShifterOutput = 0x800000; + } + ShifterOutput &= 0xFFFFFF; + + if(EWT) + DSP.EFREG[EWA] = (ShifterOutput >> 8); + + if(TWT) + DSP.TEMP[TEMPWriteAddr] = ShifterOutput; + + // + // + if(FRCL) + { + const unsigned F_SEL_Inputs[2] = { (unsigned)(ShifterOutput >> 11), (unsigned)(ShifterOutput & 0xFFF) }; + + DSP.FRC_REG = F_SEL_Inputs[SHFT0 & SHFT1]; + //printf("FRCL: 0x%08x\n", DSP.FRC_REG); + } + // + // + DSP.Product = ((int64)sign_x_to_s32(13, Y_SEL_Inputs[YSEL]) * X_SEL_Inputs[XSEL]) >> 12; + // if(step < 4) + // printf("%u %08x %08x product=0x%08x\n", step, Y_SEL_Inputs[YSEL], X_SEL_Inputs[XSEL], DSP.Product); + // + // + //if((step == 3 || step == 7) && CRA) + // printf("Step %u: %08x %08x %08x --- ysel=%u cra=0x%02x[0x%04x] temp=0x%08x\n", step, SGA_Inputs[BSEL], Y_SEL_Inputs[YSEL], X_SEL_Inputs[XSEL], YSEL, CRA, DSP.COEF[CRA], TEMP); + + uint32 SGAOutput; + + SGAOutput = SGA_Inputs[BSEL]; + + if(NEGB) + SGAOutput = -SGAOutput; + + if(ZERO) + SGAOutput = 0; + + DSP.SFT_REG = (DSP.Product + SGAOutput) & 0x3FFFFFF; + // + // + if(IWT) + { + DSP.MEMS[IWA] = DSP.ReadValue; + } + // + // + if(DSP.ReadPending) + { + uint16 tmp = RAM[DSP.RWAddr]; + DSP.ReadValue = (DSP.ReadPending == 2) ? (tmp << 8) : dspfloat_to_int(tmp); + DSP.ReadPending = false; + } + else if(DSP.WritePending) + { + if(!(DSP.RWAddr & 0x40000)) + RAM[DSP.RWAddr] = DSP.WriteValue; + + DSP.WritePending = false; + } + + { + uint16 addr; + + addr = DSP.MADRS[MASA]; + addr += NXADDR; + + if(ADRGB) + { + addr += sign_x_to_s32(12, DSP.ADRS_REG); + } + + if(!TABLE) + { + addr += DSP.MDEC_CT; + addr &= (0x2000 << RBL) - 1; + } + + DSP.RWAddr = (addr + (RBP << 12)) & 0x7FFFF; + + if(MRT) + { + DSP.ReadPending = 1 + NOFL; + } + if(MWT) + { + DSP.WritePending = true; + DSP.WriteValue = NOFL ? (ShifterOutput >> 8) : int_to_dspfloat(ShifterOutput); + } + } + // + // + if(ADRL) + { + const uint16 A_SEL_Inputs[2] = { /*INPUTS is sign-extended above */ (uint16)((INPUTS >> 16) & 0xFFF), (uint16)(ShifterOutput >> 12) }; + + DSP.ADRS_REG = A_SEL_Inputs[SHFT0 & SHFT1]; + } + } + + if(!DSP.MDEC_CT) + DSP.MDEC_CT = (0x2000 << RBL); + DSP.MDEC_CT--; +} +// +// +// +INLINE void SS_SCSP::RunSample(int16* outlr) +{ + int32 out_accum[2] = { 0, 0 }; + + for(unsigned i = 0; i < 3; i++) + { + auto* t = &Timers[i]; + bool CCB = (GlobalCounter >> (4 + t->Control)) & 1; + bool DoClock = (t->Control == 0) || (!t->PrevClockIn && CCB); + t->PrevClockIn = CCB; + + + if(DoClock) + { + if(t->Reload >= 0) + { + t->Counter = t->Reload; + t->Reload = -1; + } + else + t->Counter++; + + if(t->Counter == 0xFF) + { + SCIPD |= 0x40 << i; + MCIPD |= 0x40 << i; + } + } + } + + SCIPD |= 0x400; + MCIPD |= 0x400; + RecalcSoundInt(); + RecalcMainInt(); + + // + // + // + RunDSP(); + + for(unsigned i = 0; i < 0x10; i++) + DSP.MIXS[i] = 0; + // + // + // + for(unsigned slot = 0; slot < 32; slot++) + { + uint32 mdata = 0; + auto* s = &Slots[slot]; + unsigned key_eg_scale; + + if(s->KRS == 0xF) + key_eg_scale = 0x00; + else + key_eg_scale = std::max(0x00, std::min(0x0F, s->KRS + (s->Octave ^ 0x8) - 0x8)); + + RunEG(s, key_eg_scale); + + if(KeyExecute && (s->EnvPhase == ENV_PHASE_RELEASE) == s->KeyBit) + { + if(s->KeyBit) + { + s->PhaseWhacker = 0; + s->CurrentAddr = 0; + s->InLoop = false; + s->LoopSub = false; + s->WFAllowAccess = true; + s->EnvPhase = ENV_PHASE_ATTACK; + + if((s->AttackRate + key_eg_scale) >= 0x20) + s->EnvLevel = 0x000; + else + s->EnvLevel = 0x280; + } + else + s->EnvPhase = ENV_PHASE_RELEASE; + } + + // + // + uint16 sample = 0; + + if(s->SourceControl == 1) + sample = LFSR << 8; + + sample ^= SB_XOR_Table[s->SBControl]; // For zero and noise case only; waveform playback needs it to occur before linear interpolation. + + if(1) //s->WFAllowAccess) + { + if(!s->InLoop) + { + if((uint16)(s->CurrentAddr + 1) > s->LoopStart) + { + if(s->LoopMode == 2) + s->LoopSub = true; + + s->InLoop = true; + } + } + else + { + const bool cres = s->LoopSub ? ((uint16)(s->LoopEnd - s->CurrentAddr + s->LoopStart) <= s->LoopStart) : ((uint16)(s->CurrentAddr + 1) > s->LoopEnd); + + if(cres) + { + if(s->LoopMode == 0) + s->WFAllowAccess = false; + + if(s->LoopMode == 3) + s->LoopSub = !s->LoopSub; + + s->CurrentAddr += s->LoopStart - s->LoopEnd; + } + } + } + + if(s->WFAllowAccess) + { + uint32 modalizer; + uint32 tmppw = s->PhaseWhacker; + uint16 tmpa = s->CurrentAddr; + int16 s0, s1; + + // + // + modalizer = (int16)SoundStack[(GlobalCounter + s->ModInputX) & 0x3F]; + modalizer += (int16)SoundStack[(GlobalCounter + s->ModInputY) & 0x3F]; + modalizer >>= 0x10 - s->ModLevel; + + if(s->ModLevel <= 0x04) + modalizer = 0; + + modalizer = sign_x_to_s32(11, modalizer); + // + // + + if(s->LoopSub) + { + tmppw = ~tmppw; + tmpa = s->LoopStart + s->LoopEnd + ~tmpa; + } + + mdata |= ((tmpa >> 12) << 7); + + if(s->WF8Bit) + { + const uint32 addr0 = (s->StartAddr + modalizer + (uint16)(tmpa + 0)) & 0xFFFFF; + const uint32 addr1 = (s->StartAddr + modalizer + (uint16)(tmpa + 1)) & 0xFFFFF; + + s0 = ne16_rbo_be(RAM, addr0) << 8; + s1 = ne16_rbo_be(RAM, addr1) << 8; + } + else + { + s0 = RAM[((s->StartAddr >> 1) + modalizer + (uint16)(tmpa + 0)) & 0x7FFFF]; + s1 = RAM[((s->StartAddr >> 1) + modalizer + (uint16)(tmpa + 1)) & 0x7FFFF]; + } + + s0 ^= SB_XOR_Table[s->SBControl]; + s1 ^= SB_XOR_Table[s->SBControl]; + + if(s->SourceControl == 0) + { + const unsigned sia = (tmppw >> (14 - 6)) & 0x3F; + sample = ((s0 * (0x40 - sia)) + (s1 * sia)) >> 6; + } + + s->PhaseWhacker += (((0x400 ^ s->FreqNum) + GetPLFO(s)) << (s->Octave ^ 0x8)) >> 4; + s->CurrentAddr += s->PhaseWhacker >> 14; + s->PhaseWhacker &= (1U << 14) - 1; + } + // + // + + RunLFO(s); // Run between PLFO fetching and ALFO fetching. + + // Do LFSR clocking between sample fetching and ALFO fetching. + LFSR = (LFSR >> 1) | (((LFSR >> 5) ^ LFSR) & 1) << 16; + + + { + int32 vlevel; + + vlevel = (s->EnvPhase == ENV_PHASE_ATTACK && s->AttackHold) ? 0 : s->EnvLevel; + // + mdata |= (s->EnvPhase << 5) | (vlevel >> 5); + // + if(!s->SoundDirect) + { + vlevel += s->TotalLevel << 2; + vlevel += GetALFO(s); + + if(vlevel > 0x3FF) + vlevel = 0x3FF; + + sample = ((int16)sample * ((vlevel & 0x3F) ^ 0x7F)) >> ((vlevel >> 6) + 7); + } + } + + if(!Slots[(GlobalCounter - 4) & 0x1F].StackWriteInhibit) + { + SoundStack[(GlobalCounter - 4) & 0x3F] = SoundStackDelayer[3]; + } + + SoundStackDelayer[3] = SoundStackDelayer[2]; + SoundStackDelayer[2] = SoundStackDelayer[1]; + SoundStackDelayer[1] = SoundStackDelayer[0]; + SoundStackDelayer[0] = sample; + // + // + if(SlotMonitorWhich == slot) + SlotMonitorData = mdata; + // + // + if(s->ToDSPLevel) + DSP.MIXS[s->ToDSPSelect] = (DSP.MIXS[s->ToDSPSelect] + (((uint32)(int16)sample << 4) >> (7 - s->ToDSPLevel))) & 0xFFFFF; + // + // + out_accum[0] += ((int16)sample * s->DirectVolume[0]) >> 14; + out_accum[1] += ((int16)sample * s->DirectVolume[1]) >> 14; + + { + const uint16 eff_sample = (slot & 0x10) ? ((slot & 0xE) ? 0 : EXTS[slot & 0x1]) : DSP.EFREG[slot]; + + out_accum[0] += ((int16)eff_sample * s->EffectVolume[0]) >> 14; + out_accum[1] += ((int16)eff_sample * s->EffectVolume[1]) >> 14; + } + // + // + GlobalCounter++; + } + + KeyExecute = false; + + // + // + // + out_accum[0] = (out_accum[0] * MasterVolume) >> 8; + out_accum[1] = (out_accum[1] * MasterVolume) >> 8; + + out_accum[0] = std::min(32767, std::max(-32768, out_accum[0])); + out_accum[1] = std::min(32767, std::max(-32768, out_accum[1])); + + if(DAC18bit) + { + // Doesn't seem to improve precision. Remember + // to extend the outlr[] types if this SCSP emulator is used + // in a system that actually has an 18-bit DAC. + out_accum[0] = (uint32)out_accum[0] << 2; + out_accum[1] = (uint32)out_accum[1] << 2; + } + + outlr[0] = out_accum[0]; + outlr[1] = out_accum[1]; +} + +// +// +// +uint32 SS_SCSP::GetRegister(const unsigned id, char* const special, const uint32 special_len) +{ + uint32 ret = 0xDEADBEEF; + + switch(id) + { + case GSREG_MVOL: + ret = MVOL; + break; + + case GSREG_DAC18B: + ret = DAC18bit; + break; + + case GSREG_MEM4MB: + ret = Mem4Mb; + break; + + case GSREG_RBP: + ret = RBP; + break; + + case GSREG_RBL: + ret = RBL; + break; + + case GSREG_MSLC: + ret = SlotMonitorWhich; + break; + } + + return ret; +} + +void SS_SCSP::SetRegister(const unsigned id, const uint32 value) +{ + switch(id) + { + //case GSREG_MVOL: MVOL = value & 0xF; // TODO cache + + case GSREG_DAC18B: + DAC18bit = value & 1; + break; + + case GSREG_MEM4MB: + Mem4Mb = value & 1; + break; + + case GSREG_RBP: + RBP = value & 0x7F; + break; + + case GSREG_RBL: + RBL = value & 0x3; + break; + + case GSREG_MSLC: + SlotMonitorWhich = value & 0x1F; + break; + } +} + diff --git a/waterbox/ss/scu.h b/waterbox/ss/scu.h new file mode 100644 index 0000000000..4e38880110 --- /dev/null +++ b/waterbox/ss/scu.h @@ -0,0 +1,95 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* scu.h: +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_SCU_H +#define __MDFN_SS_SCU_H + +namespace MDFN_IEN_SS +{ + +enum +{ + SCU_INT_VBIN = 0x00, + SCU_INT_VBOUT, + SCU_INT_HBIN, + SCU_INT_TIMER0, + SCU_INT_TIMER1, + SCU_INT_DSP, + SCU_INT_SCSP, + SCU_INT_SMPC, + SCU_INT_PAD, + + SCU_INT_L2DMA, + SCU_INT_L1DMA, + SCU_INT_L0DMA, + + SCU_INT_DMA_ILL, + + SCU_INT_VDP1, + + SCU_INT_EXT0 = 0x10, + SCU_INT_EXTF = 0x1F, +}; + +void SCU_Reset(bool powering_up) MDFN_COLD; + +void SCU_SetInt(unsigned which, bool active); +int32 SCU_SetHBVB(int32 pclocks, bool hblank_in, bool vblank_in); + +bool SCU_CheckVDP1HaltKludge(void); + +sscpu_timestamp_t SCU_UpdateDMA(sscpu_timestamp_t timestamp); +sscpu_timestamp_t SCU_UpdateDSP(sscpu_timestamp_t timestamp); + +enum +{ + SCU_GSREG_ILEVEL = 0, + SCU_GSREG_IVEC, + SCU_GSREG_ICLEARMASK, + + SCU_GSREG_IASSERTED, + SCU_GSREG_IPENDING, + SCU_GSREG_IMASK, + + SCU_GSREG_T0CNT, + SCU_GSREG_T0CMP, + SCU_GSREG_T0MET, + + SCU_GSREG_T1RLV, + SCU_GSREG_T1CNT, + SCU_GSREG_T1MOD, + SCU_GSREG_T1MET, + + SCU_GSREG_TENBL, + // + // + // + SCU_GSREG_DSP_EXEC, + SCU_GSREG_DSP_PAUSE, + SCU_GSREG_DSP_PC, + SCU_GSREG_DSP_END, +}; + +uint32 SCU_GetRegister(const unsigned id, char* const special, const uint32 special_len) MDFN_COLD; +void SCU_SetRegister(const unsigned id, const uint32 value) MDFN_COLD; +} + +#endif diff --git a/waterbox/ss/scu.inc b/waterbox/ss/scu.inc new file mode 100644 index 0000000000..6123f55d46 --- /dev/null +++ b/waterbox/ss/scu.inc @@ -0,0 +1,2003 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* scu.inc - SCU Emulation +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +// TODO: Investigate different instruction dispatch mechanisms for DSP to take advantage of modern branch +// prediction, to improve performance and reduce instruction cache footprint. +// TODO: Test slave SH-2 IRQ handling. +// TODO: Open bus, and correct propagation of open bus from one bus to another. +// TODO: Consider logging DMA status register reads. +// TODO: Test indirect DMA table alignment requirements. +// TODO: Indirect same-bus DMA has kind of weird effects that might actually be useful(and hence used), so test! + +/* + Notes(assuming NTSC, HRES=0, VRES=0, LSMD=0): + Timer0 notes: + Counter is effectively forced to 0 while timer enable bit is 0, but it won't generate an IRQ if T0C is also 0(unless timer enable bit is set + to 1 again)... + + Hrm...T0C of 0-263 causes interrupts. In interlace mode though, 263 causes an interrupt at half the rate... + Timer1 notes: + T1S of 1-426(HRES=0x00) causes interrupt for each line, 0 and 427+ causes it every other line? + + + The effect of writes to MCIEB on the interrupt output signal(as examined indirectly via IST) from the SCSP appears to be delayed somewhat; + is the SCU buffering writes, or is the SCSP, or is it something else entirely? + + Reads from A-bus and B-bus are treated by the SCU as always 32-bit, regardless of the actual size(writes are handled properly, though). + + SCU DMA read from VRAM is reportedly unreliable? + + DMA speed for accesses to A-/B-bus, with the exceptions of A-bus CS2, should be best-case in this code + (writes often take longer on the Saturn if the DMA write address doesn't increment). +*/ + +#include "scu_dsp_common.inc" + +static void DSP_Reset(bool powering_up); + +enum { DMA_UpdateTimingGran = 127 }; + +enum { DSP_UpdateTimingGran = 64 }; // Probably should keep it a multiple of 2. + +struct DMAWriteTabS +{ + int16 write_addr_delta; + uint8 write_size; + uint8 compare; +}; + +static const DMAWriteTabS dma_write_tab[2/*bus*/][8/*add setting*/][4/*write align*/][12/*count*/][5] = +{ + { + #include "scu_actab.inc" + }, + { + #include "scu_btab.inc" + } +}; + +static const DMAWriteTabS dma_write_tab_aciv1[4][24][8] = +{ + #include "scu_aciv1tab.inc" +}; + +static struct DMALevelS +{ + uint32 StartReadAddr; + uint32 StartWriteAddr; + uint32 StartByteCount; + + bool ReadAdd; + uint8 WriteAdd; + + bool Enable; + int8 Active; // -1, 0, 1 + bool GoGoGadget; + + bool Indirect; + bool ReadUpdate; + bool WriteUpdate; + uint8 SF; + + sscpu_timestamp_t FinishTime; + + // + // + // + uint32 (*ReadFunc)(uint32 offset); + uint32 WriteBus; + // + uint32 CurReadBase; + uint32 CurReadSub; + + uint32 CurWriteAddr; + uint32 CurByteCount; + + uint64 Buffer; + // + const DMAWriteTabS* WATable; + // + uint32 (*TableReadFunc)(uint32 offset); // Also serves as a kind of "CurIndirect" cache of "Indirect" variable. + uint32 CurTableAddr; + bool FinalTransfer; +} DMALevel[3]; + +static sscpu_timestamp_t SCU_DMA_TimeCounter; +static sscpu_timestamp_t SCU_DMA_RunUntil; +static int32 SCU_DMA_ReadOverhead; // range -whatever to 0. + +static uint32 SCU_DMA_VDP1WriteIgnoreKludge; + +static void RecalcDMAHalt(void); +static void CheckDMAStart(DMALevelS* d); +static void CheckDMASFByInt(unsigned int_which); +static INLINE void CheckForceDMAFinish(void); + +static uint32 IAsserted; +static uint32 IPending; +static uint32 IMask; + +static uint32 ABusIProhibit; +static bool RSEL; + +static uint8 ILevel, IVec; + +static INLINE void RecalcMasterIntOut(void) +{ + if(ILevel == 0) + { + static const uint8 internal_tab[16 + 1] = + { + 0xF, 0xE, 0xD, 0xC, 0xB, 0xA, 0x9, 0x8, + 0x8, 0x6, 0x6, 0x5, 0x3, 0x2, 0x0, 0x0, + 0x0 + }; + + static const uint8 external_tab[16 + 1] + { + 0x7, 0x7, 0x7, 0x7, 0x4, 0x4, 0x4, 0x4, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x0 + }; + const uint32 ipmd = IPending &~ (int16)IMask; + unsigned wi = MDFN_tzcount16(ipmd & 0xFFFF); + unsigned we = MDFN_tzcount16(ipmd >> 16); + unsigned olev, ovec, bpos; + + olev = internal_tab[wi]; + ovec = 0x40 + wi; + bpos = wi; + + if(external_tab[we] > internal_tab[wi]) + { + olev = external_tab[we]; + ovec = 0x50 + we; + bpos = 16 + we; + } + + if(olev != 0) + { + ILevel = olev; + IVec = ovec; + IPending &= ~(1U << bpos); + //SS_DBGTI(SS_DBG_ERROR, "[SCU] Interrupt level=0x%02x, vector=0x%02x --- IPending=0x%04x", ILevel, IVec, IPending); + } + } + + CPU[0].SetIRL(ILevel); +} + +static int32 Timer0_Counter; +static int32 Timer0_Compare; +static bool Timer0_Met; + +static int32 Timer1_Reload; +static int32 Timer1_Counter; +static bool Timer1_Mode; +static bool Timer1_Met; + +static bool Timer_Enable; + +static bool HB_FromVDP2, VB_FromVDP2; + +static uint8 SCU_MSH2VectorFetch(void) +{ + uint8 ret = IVec; + + //SS_DBGTI(SS_DBG_ERROR, "[SCU] Interrupt cleared."); + + if(MDFN_UNLIKELY(ILevel == 0)) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] [MSH2] [BUG] SCU_MSH2VectorFetch() called when ILevel == 0\n"); + } + +// if(MDFN_UNLIKELY(IVec == 0x40 /* || IVec == 0x41 */)) // VB In, apply cheats. +// MDFNMP_ApplyPeriodicCheats(); + + IMask = 0xBFFF; + + ILevel = 0; + RecalcMasterIntOut(); + + return ret; +} + +static uint8 SCU_SSH2VectorFetch(void) +{ + if(VB_FromVDP2) + return 0x43; + + return 0x41; +// return 0xFF; // FIXME? +} + +static INLINE void ABusIRQCheck(void) +{ + const uint32 tt = (ABusIProhibit ^ IAsserted) & (IAsserted & ~0xFFFF); + + IPending |= tt; + ABusIProhibit |= IAsserted & ~0xFFFF; + + if(tt) + RecalcMasterIntOut(); +} + +static INLINE void SetInt(unsigned which, bool active) +{ + const uint32 old_IAsserted = IAsserted; + + IAsserted &= ~(1U << which); + IAsserted |= (unsigned)active << which; + + if(which >= 16) + ABusIRQCheck(); + else + { + if((old_IAsserted ^ IAsserted) & IAsserted) + { + IPending |= 1U << which; + CheckDMASFByInt(which); + RecalcMasterIntOut(); + } + } +} + +void SCU_SetInt(unsigned which, bool active) +{ + SetInt(which, active); +} + +static INLINE void Timer0_Check(void) +{ + if(Timer_Enable) + { + Timer0_Met = (Timer0_Counter == Timer0_Compare); + SetInt(SCU_INT_TIMER0, Timer0_Met); + } +} + +static INLINE void Timer1_Check(void) +{ + if(Timer_Enable) + { + Timer1_Met |= (Timer1_Counter == 0 && (!Timer1_Mode || Timer0_Met)); + SetInt(SCU_INT_TIMER1, Timer1_Met); + } +} + +int32 SCU_SetHBVB(int32 pclocks, bool new_HB_FromVDP2, bool new_VB_FromVDP2) +{ + const bool HB_Start = (HB_FromVDP2 ^ new_HB_FromVDP2) & new_HB_FromVDP2; + const bool VB_End = (VB_FromVDP2 ^ new_VB_FromVDP2) & VB_FromVDP2; + + if(Timer_Enable) + { + if(VB_End) + Timer0_Counter = 0; + + if(HB_Start) + Timer0_Counter = (Timer0_Counter + 1) & 0x1FF; + + Timer0_Check(); + + if(pclocks > 0) + { + Timer1_Counter = (Timer1_Counter - pclocks) & 0x1FF; + Timer1_Check(); + } + + if(Timer1_Met && HB_Start) + { + Timer1_Met = false; + Timer1_Counter = Timer1_Reload; + + SetInt(SCU_INT_TIMER1, Timer1_Met); + } + } + + SetInt(SCU_INT_HBIN, new_HB_FromVDP2); + SetInt(SCU_INT_VBIN, new_VB_FromVDP2); + SetInt(SCU_INT_VBOUT, !new_VB_FromVDP2); + + // + // + CPU[1].SetIRL(((new_VB_FromVDP2 | new_HB_FromVDP2) << 1) | (new_VB_FromVDP2 << 2)); + // + // + // + HB_FromVDP2 = new_HB_FromVDP2; + VB_FromVDP2 = new_VB_FromVDP2; + + return Timer1_Counter ? Timer1_Counter : 0x200; +} + +static void SCU_Init(void) +{ + SCU_DMA_TimeCounter = 0; + SCU_DMA_RunUntil = 0; + IAsserted = 0; + HB_FromVDP2 = false; + VB_FromVDP2 = false; + + DSP_Init(); +} + +void SCU_Reset(bool powering_up) +{ + ILevel = IVec = 0; + IMask = 0xBFFF; + IPending = 0; + ABusIProhibit = 0; + RSEL = 0; + + if(powering_up) + memset(DMALevel, 0x00, sizeof(DMALevel)); + + for(auto& d : DMALevel) + { + d.ReadAdd = true; + d.WriteAdd = 0x1; + + d.Enable = false; + d.GoGoGadget = false; + d.Active = false; + + d.Indirect = false; + d.ReadUpdate = false; + d.WriteUpdate = false; + d.SF = 0; + } + //SCU_DMA_CycleCounter = 0; + SCU_DMA_ReadOverhead = 0; + + SCU_DMA_VDP1WriteIgnoreKludge = 0; + + RecalcDMAHalt(); + + DSP_Reset(powering_up); + + RecalcMasterIntOut(); +} + +static void SCU_AdjustTS(const int32 delta) +{ + SCU_DMA_TimeCounter += delta; + SCU_DMA_RunUntil += delta; + for(auto& d : DMALevel) + { + if(d.Active < 0) + d.FinishTime += delta; + } + + // + // + // + if(DSP.T0_Until > 0x10000000) + DSP.T0_Until = 0x10000000; + + DSP.LastTS += delta; + if(DSP.LastTS < 0) + { + // TODO: Fix properly. + //printf("%d\n", DSP.LastTS); + DSP.LastTS = 0; + } +} + +// +// TODO: Test to see if the entire data bus or only parts are asserted for uint8 and uint16 reads +// +template +static INLINE void SCU_RegRW_DB(uint32 A, uint32* DB) +{ + unsigned mask; + + switch(sizeof(T)) + { + case 1: mask = 0xFF << (((A & 3) ^ 3) << 3); break; + case 2: mask = 0xFFFF << (((A & 2) ^ 2) << 3); break; + case 4: mask = 0xFFFFFFFF; break; + } + + if(IsWrite) + { + SS_DBGTI(SS_DBG_SCU_REGW, "[SCU] %zu-byte write to 0x%02x, DB=0x%08x", sizeof(T), A & 0xFC, *DB); + + switch(A & 0xFC) + { + default: + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] Unknown %zu-byte write to 0x%08x(DB=0x%08x).\n", sizeof(T), A, *DB); + break; + + case 0x90: // Timer 0 Compare + { + VDP2::Update(SH7095_mem_timestamp); + Timer0_Compare = (Timer0_Compare &~ mask) | (*DB & mask & 0x3FF); + SS_SetEventNT(&events[SS_EVENT_VDP2], VDP2::Update(SH7095_mem_timestamp)); + } + break; + + case 0x94: // Timer 1 Reload Value + { + VDP2::Update(SH7095_mem_timestamp); + Timer1_Reload = (Timer1_Reload &~ mask) | (*DB & mask & 0x1FF); + SS_SetEventNT(&events[SS_EVENT_VDP2], VDP2::Update(SH7095_mem_timestamp)); + } + break; + + case 0x98: // Timer Control + { + VDP2::Update(SH7095_mem_timestamp); + uint32 tmp = (Timer1_Mode << 8) | (Timer_Enable << 0); + tmp = (tmp &~ mask) | (*DB & mask); + Timer1_Mode = (tmp >> 8) & 1; + Timer_Enable = (tmp >> 0) & 1; + + if(!Timer_Enable) + { + Timer0_Counter = 0; + } + + SS_SetEventNT(&events[SS_EVENT_VDP2], VDP2::Update(SH7095_mem_timestamp)); + } + break; + + case 0xA0: + IMask = (IMask &~ mask) | (*DB & mask & 0xBFFF); + RecalcMasterIntOut(); + break; + + case 0xA4: + IPending &= *DB | ~mask; + RecalcMasterIntOut(); + break; + + case 0xA8: + if(*DB & mask & 0x0001) + { + ABusIProhibit = 0; //&= ~IAsserted; + ABusIRQCheck(); + } + break; + + case 0xC4: + RSEL = (RSEL &~ mask) | (*DB & mask & 0x1); + if(MDFN_UNLIKELY(!RSEL)) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] Write to RSEL, RSEL=0\n"); + } + break; + + case 0x00: + case 0x20: + case 0x40: + { + auto& d = DMALevel[(A >> 5) & 0x3]; + + d.StartReadAddr = (d.StartReadAddr &~ mask) | (*DB & mask & 0x07FFFFFF); + } + break; + + case 0x04: + case 0x24: + case 0x44: + { + auto& d = DMALevel[(A >> 5) & 0x3]; + + d.StartWriteAddr = (d.StartWriteAddr &~ mask) | (*DB & mask & 0x07FFFFFF); + } + break; + + case 0x08: + case 0x28: + case 0x48: + { + const unsigned level = (A >> 5) & 0x3; + auto& d = DMALevel[level]; + + d.StartByteCount = (d.StartByteCount &~ mask) | (*DB & mask & (level ? 0x00000FFF : 0x000FFFFF)); + } + break; + + case 0x0C: + case 0x2C: + case 0x4C: + { + auto& d = DMALevel[(A >> 5) & 0x3]; + uint32 tmp = (d.ReadAdd << 8) | (d.WriteAdd << 0); + + tmp = (tmp &~ mask) | (*DB & mask); + + d.ReadAdd = (tmp >> 8) & 0x1; + d.WriteAdd = (tmp >> 0) & 0x7; + } + break; + + case 0x10: + case 0x30: + case 0x50: + { + const unsigned level = (A >> 5) & 0x3; + auto& d = DMALevel[level]; + uint32 tmp = (d.Enable << 8); + + tmp = (tmp &~ mask) | (*DB & mask); + d.Enable = (tmp >> 8) & 0x1; + + if((tmp & 0x1) && d.Enable && d.SF == 0x7) + { + SCU_UpdateDMA(SH7095_mem_timestamp); + + d.GoGoGadget = true; + CheckDMAStart(&d); + + SS_SetEventNT(&events[SS_EVENT_SCU_DMA], SCU_UpdateDMA(SH7095_mem_timestamp)); + } + } + break; + + case 0x14: + case 0x34: + case 0x54: + { + auto& d = DMALevel[(A >> 5) & 0x3]; + uint32 tmp = (d.Indirect << 24) | (d.ReadUpdate << 16) | (d.WriteUpdate << 8) | (d.SF << 0); + + tmp = (tmp &~ mask) | (*DB & mask); + + d.Indirect = (tmp >> 24) & 0x1; + d.ReadUpdate = (tmp >> 16) & 0x1; + d.WriteUpdate = (tmp >> 8) & 0x1; + d.SF = (tmp >> 0) & 0x7; + } + break; + + case 0x60: + // TODO: Test + if(*DB & mask & 0x1) + { + SCU_DMA_ReadOverhead = 0; + for(unsigned level = 0; level < 3; level++) + { + auto& d = DMALevel[level]; + + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] Forced stop of DMA level %u\n", level); + + d.Active = false; + d.GoGoGadget = false; + } + RecalcDMAHalt(); + } + break; + + case 0x80: + SCU_UpdateDSP(SH7095_mem_timestamp); + + if(*DB & (1U << 25)) // Pause start + DSP.State |= DSPS::STATE_MASK_PAUSE; + else if(*DB & (1U << 26)) // Pause stop + DSP.State &= ~DSPS::STATE_MASK_PAUSE; + else + { + if(*DB & (1U << 16)) // Execute + DSP.State |= DSPS::STATE_MASK_EXECUTE; + else if(!(*DB & (1U << 16))) // Execute stop + { + if(DSP.State & DSPS::STATE_MASK_EXECUTE) + { + DSP.NextInstr = DSP_DecodeInstruction(0); + DSP.State &= ~DSPS::STATE_MASK_EXECUTE; + + if(DSP.CycleCounter < 0) + DSP.CycleCounter = 0; + + if(DSP.T0_Until < 0) + DSP.T0_Until = 0; + } + } + + if(MDFN_UNLIKELY(*DB & (1U << 17))) // Step + { + if(DSP.State == 0) + { + ((void (*)(void))(DSP_INSTR_BASE_UIPT + (uintptr_t)(DSP_INSTR_RECOVER_TCAST)DSP.NextInstr))(); + if(DSP.CycleCounter < -(DSP_EndCCSubVal / 2)) // Ugh + DSP.CycleCounter += DSP_EndCCSubVal; + } + } + } + + if(*DB & (1U << 15)) // PC load + DSP.PC = *DB; + + SS_SetEventNT(&events[SS_EVENT_SCU_DSP], (DSP.IsRunning() ? SH7095_mem_timestamp + (DSP_UpdateTimingGran / 2) : SS_EVENT_DISABLED_TS)); + break; + + case 0x84: + if(!DSP.IsRunning()) + DSP.ProgRAM[DSP.PC++] = DSP_DecodeInstruction(*DB); + break; + + case 0x88: + DSP.RA = *DB; + break; + + case 0x8C: + if(!DSP.IsRunning()) + (&DSP.DataRAM[0][0])[DSP.RA++] = *DB; + break; + } + } + else + { + switch(A & 0xFC) + { + default: + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] Unknown %zu-byte read from 0x%08x.\n", sizeof(T), A); + *DB = 0; + break; + + case 0xA4: + *DB = IPending; + break; + + case 0xA8: + *DB = 0; //ABusIAck; + break; + + case 0xC4: + *DB = RSEL; + break; + + case 0xC8: + *DB = 0x4; + break; + // + // + // + case 0x00: + case 0x20: + case 0x40: + { + auto const& d = DMALevel[(A >> 5) & 0x3]; + + *DB = d.StartReadAddr; + } + break; + + case 0x04: + case 0x24: + case 0x44: + { + auto const& d = DMALevel[(A >> 5) & 0x3]; + + *DB = d.StartWriteAddr; + } + break; + + case 0x7C: + { + uint32 tmp = 0; + + for(unsigned level = 0; level < 3; level++) + { + auto& d = DMALevel[level]; + + if(d.Active) + { + tmp |= 0x10 << (level << 2); + } + } + + if(DMALevel[0].Active && (DMALevel[1].Active || DMALevel[2].Active)) + tmp |= 1U << 16; + + if(DMALevel[1].Active && DMALevel[2].Active) + tmp |= 1U << 17; + + *DB = tmp; + } + break; + + case 0x80: + SS_SetEventNT(&events[SS_EVENT_SCU_DSP], SCU_UpdateDSP(SH7095_mem_timestamp)); // TODO: Remove? + { + uint32 tmp; + + tmp = DSP.PC; + tmp |= (DSP.T0_Until < DSP.CycleCounter) << 23; + tmp |= DSP.FlagS << 22; + tmp |= DSP.FlagZ << 21; + tmp |= DSP.FlagC << 20; + tmp |= DSP.FlagV << 19; + tmp |= DSP.FlagEnd << 18; + tmp |= DSP.IsRunning() << 16; + *DB = tmp; + // + DSP.FlagV = false; + DSP.FlagEnd = false; + SCU_SetInt(SCU_INT_DSP, false); + } + break; + + case 0x8C: + if(!DSP.IsRunning()) + *DB = (&DSP.DataRAM[0][0])[DSP.RA++]; + else + *DB = 0xFFFFFFFF; + break; + } + } +} + + +template +static INLINE void BBusRW_DB(uint32 A, uint16* DB, int32* time_thing, int32* dma_time_thing = NULL, int32* sh2_dma_time_thing = NULL) // add to time_thing, subtract from dma_time_thing +{ + static_assert(IsWrite || sizeof(T) == 2, "Wrong type."); + + // + // VDP1 + // + if(A >= 0x05C00000 && A <= 0x05D7FFFF) + { + if(sh2_dma_time_thing != NULL) + *sh2_dma_time_thing -= IsWrite ? (SH32 ? 0 : 6) : 10; + + if(dma_time_thing != NULL) + { + *dma_time_thing -= 1; + + if(IsWrite) + { + if(MDFN_UNLIKELY(A >= 0x05D00000)) + { + const bool ignore_write = (A >= 0x5D00004 && SCU_DMA_VDP1WriteIgnoreKludge > 0) | (SCU_DMA_VDP1WriteIgnoreKludge & 0x1); + + SCU_DMA_VDP1WriteIgnoreKludge++; + if(ignore_write) + return; + //printf("%08x %04x\n", A, *DB); + } + else + SCU_DMA_VDP1WriteIgnoreKludge = 0; + } + } + + if(time_thing != NULL) + { + if(IsWrite) + *time_thing += SH32 ? 0 : 11; + else + *time_thing += 14; + + CheckEventsByMemTS(); + } + + if(IsWrite) + { + if(sizeof(T) == 1) + VDP1::Write8_DB(A, *DB); + else + VDP1::Write16_DB(A, *DB); + } + else + { + *DB = VDP1::Read16_DB(A); + } + + return; + } + + // + // VDP2 + // + if(A >= 0x05E00000 && A <= 0x05FBFFFF) + { + if(sh2_dma_time_thing != NULL) + *sh2_dma_time_thing -= IsWrite ? (SH32 ? 0 : 5) : 10; + + if(dma_time_thing != NULL) + { + *dma_time_thing -= 1; + } + + if(time_thing != NULL) + { + if(IsWrite) + *time_thing += SH32 ? 0 : 5; + else + *time_thing += 20; + + CheckEventsByMemTS(); + } + + if(IsWrite) + { + uint32 expenalty; + + if(sizeof(T) == 1) + expenalty = VDP2::Write8_DB(A, *DB); + else + expenalty = VDP2::Write16_DB(A, *DB); + + if(dma_time_thing != NULL) + { + //if(expenalty) + // printf("%u\n", expenalty); + + *dma_time_thing -= expenalty; + } + } + else + { + *DB = VDP2::Read16_DB(A); + } + + return; + } + + // + // SCSP + // + if(A >= 0x05A00000 && A <= 0x05BFFFFF) + { + if(sh2_dma_time_thing != NULL) + *sh2_dma_time_thing -= 13; + + if(dma_time_thing != NULL) + { + *dma_time_thing -= 13; + } + + if(time_thing != NULL) + { + if(IsWrite) + *time_thing += SH32 ? 13 : 19; + else + *time_thing += 24; + } + + if(IsWrite) + { + if(sizeof(T) == 1) + SOUND_Write8(A & 0x1FFFFF, *DB >> (((A & 1) ^ 1) << 3)); + else + SOUND_Write16(A & 0x1FFFFF, *DB); + } + else + *DB = SOUND_Read16(A & 0x1FFFFF); + + return; + } + // + // + // + if(sh2_dma_time_thing != NULL) + *sh2_dma_time_thing -= 1; + + if(dma_time_thing != NULL) + *dma_time_thing -= 1; + + if(IsWrite) + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[B-Bus] Unknown %zu-byte write of 0x%08x(DB=0x%04x)\n", sizeof(T), A, *DB); + else + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[B-Bus] Unknown %zu-byte read from 0x%08x\n", sizeof(T), A); + + *DB = 0; + } +} + +template +static INLINE void ABusRW_DB(uint32 A, uint16* DB, int32* time_thing, int32* dma_time_thing = NULL, int32* sh2_dma_time_thing = NULL) // add to time_thing, subtract from dma_time_thing +{ + // + // A-Bus CS0 and CS1 + // + if(A >= 0x02000000 && A <= 0x04FFFFFF) + { + // [(bool)(A & 0x04000000)] + + if(sh2_dma_time_thing != NULL) + *sh2_dma_time_thing -= 1; // TODO + + if(dma_time_thing != NULL) + *dma_time_thing -= 1; // TODO + + if(IsWrite) + { + if(sizeof(T) == 1) + CART_CS01_Write8_DB(A, DB); + else + CART_CS01_Write16_DB(A, DB); + } + else + CART_CS01_Read16_DB(A, DB); + + return; + } + + // + // A-bus Dummy + // + if(MDFN_UNLIKELY(A >= 0x05000000 && A <= 0x057FFFFF)) + { + if(sh2_dma_time_thing != NULL) + *sh2_dma_time_thing -= 16; + + if(dma_time_thing != NULL) + { + *dma_time_thing -= 16; + } + + if(IsWrite) + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[A-Bus CSD] Unknown %zu-byte write to 0x%08x(DB=0x%04x)\n", sizeof(T), A, *DB); + else + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[A-Bus CSD] Unknown %zu-byte read from 0x%08x\n", sizeof(T), A); + + return; + } + + + // + // A-Bus CS2 + // + if(A >= 0x05800000 && A <= 0x058FFFFF) + { + if(sh2_dma_time_thing != NULL) + *sh2_dma_time_thing -= 8; + + if(dma_time_thing != NULL) + { + *dma_time_thing -= 8; + } + + if(time_thing) + { + if(IsWrite) + *time_thing += 8; + else + *time_thing += 8; + } + + if((A & 0x7FFF) < 0x1000) + { + const uint32 offset = (A & 0x3F) >> 2; + const uint32 mask = (sizeof(T) == 2) ? 0xFFFF : (0xFF << (((A & 1) ^ 1) << 3)); + + if(IsWrite) + { + CDB_Write_DBM(offset, *DB, mask); + } + else + { + if(!SH32 || !(A & 0x80000)) // CD block seems to effectively ignore second read access in 32-bit reads somehow, tested to occur HIRQ and the FIFO at least... + *DB = CDB_Read(offset); + } + return; + } + + if(IsWrite) + { + if(sizeof(T) == 1) + CART_CS2_Write8_DB(A, DB); + else + CART_CS2_Write16_DB(A, DB); + } + else + CART_CS2_Read16_DB(A, DB); + + return; + } + + if(sh2_dma_time_thing != NULL) + *sh2_dma_time_thing -= 1; + + if(dma_time_thing != NULL) + *dma_time_thing -= 1; + + if(IsWrite) + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[A-Bus] Unknown %zu-byte write to 0x%08x(DB=0x%04x)\n", sizeof(T), A, *DB); + else + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[A-Bus] Unknown %zu-byte read from 0x%08x\n", sizeof(T), A); +} + +template +static INLINE void ABus_Write_DB32(uint32 A, uint32 DB32, int32* time_thing, int32* dma_time_thing = NULL, int32* sh2_dma_time_thing = NULL) +{ + if(sizeof(T) == 4) + { + uint16 tmp; + + tmp = DB32 >> 16; + ABusRW_DB(A, &tmp, time_thing, dma_time_thing, sh2_dma_time_thing); + + tmp = DB32 >> 0; + ABusRW_DB(A | 2, &tmp, time_thing, dma_time_thing, sh2_dma_time_thing); + } + else + { + uint16 tmp = DB32 >> (((A & 2) ^ 2) << 3); + + ABusRW_DB(A, &tmp, time_thing, dma_time_thing, sh2_dma_time_thing); + } +} + +// Lower 2 bits of A should be 0 +static INLINE uint32 ABus_Read(uint32 A, int32* time_thing, int32* dma_time_thing = NULL, int32* sh2_dma_time_thing = NULL) +{ + uint32 ret; + uint16 tmp = 0xFFFF; + + ABusRW_DB(A, &tmp, time_thing, dma_time_thing, sh2_dma_time_thing); + ret = tmp << 16; + + ABusRW_DB(A | 2, &tmp, time_thing, dma_time_thing, sh2_dma_time_thing); + ret |= tmp << 0; + + return ret; +} + +template +static INLINE void SCU_FromSH2_BusRW_DB(uint32 A, uint32* DB, int32* SH2DMAHax) +{ + // + // A bus + // + if(A >= 0x02000000 && A <= 0x058FFFFF) + { + CheckForceDMAFinish(); + + if(IsWrite) + ABus_Write_DB32(A, *DB, SH2DMAHax ? NULL : &SH7095_mem_timestamp, NULL, SH2DMAHax); + else // A-bus reads are always 32-bit(divided into two 16-bit accesses internally) + *DB = ABus_Read(A &~ 0x3, SH2DMAHax ? NULL : &SH7095_mem_timestamp, NULL, SH2DMAHax); + + return; + } + + + // + // B bus + // + if(A >= 0x05A00000 && A <= 0x05FBFFFF) + { + CheckForceDMAFinish(); + + if(IsWrite) + { + if(sizeof(T) == 4) + { + uint16 tmp; + + tmp = *DB >> 16; + BBusRW_DB(A, &tmp, SH2DMAHax ? NULL : &SH7095_mem_timestamp, NULL, SH2DMAHax); + + tmp = *DB >> 0; + BBusRW_DB(A | 2, &tmp, SH2DMAHax ? NULL : &SH7095_mem_timestamp, NULL, SH2DMAHax); + } + else + { + uint16 tmp = *DB >> (((A & 2) ^ 2) << 3); + + BBusRW_DB(A, &tmp, SH2DMAHax ? NULL : &SH7095_mem_timestamp, NULL, SH2DMAHax); + } + } + else // B-bus reads are always 32-bit(divided into two 16-bit accesses internally) + { + uint16 tmp = 0; + + BBusRW_DB(A, &tmp, SH2DMAHax ? NULL : &SH7095_mem_timestamp, NULL, SH2DMAHax); + *DB = tmp << 16; + + BBusRW_DB(A | 2, &tmp, SH2DMAHax ? NULL : &SH7095_mem_timestamp, NULL, SH2DMAHax); + *DB |= tmp << 0; + } + return; + } + + + // + // SCU registers + // + if(A >= 0x05FE0000 && A <= 0x05FEFFFF) + { + if(!SH2DMAHax) + { + SH7095_mem_timestamp += IsWrite ? 4 : 8; + CheckEventsByMemTS(); + } + else + *SH2DMAHax -= IsWrite ? 4 : 8; + + SCU_RegRW_DB(A, DB); + return; + } + + // TODO: (investigate 0x5A80000-0x5AFFFFF open bus region) + // + //if(A >= 0x05A00000 && A <= 0x05BFFFFF) + //{ + // return 0; + //} + + if(IsWrite) + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SH2->SCU BUS] Unknown %zu-byte write to 0x%08x(DB=0x%08x)\n", sizeof(T), A, *DB); + else + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SH2->SCU BUS] Unknown %zu-byte read from 0x%08x\n", sizeof(T), A); + + if(!SH2DMAHax) + SH7095_mem_timestamp += IsWrite ? 4 : 7; + else + *SH2DMAHax -= IsWrite ? 4 : 7; +} + + + + + +// +// Offset should have lower 2 bits as 0. +// +static uint32 DMA_ReadABus(uint32 offset) +{ + return ABus_Read(offset, NULL, &SCU_DMA_ReadOverhead); +} + +static uint32 DMA_ReadBBus(uint32 offset) +{ + uint32 ret; + uint16 tmp = 0; + + BBusRW_DB(offset | 0, &tmp, NULL, &SCU_DMA_ReadOverhead); + ret = tmp << 16; + + BBusRW_DB(offset | 2, &tmp, NULL, &SCU_DMA_ReadOverhead); + ret |= tmp << 0; + + return ret; +} + +static uint32 DMA_ReadCBus(uint32 offset) +{ + return ne16_rbo_be(WorkRAMH, offset & 0xFFFFC); +} + +static INLINE int AddressToBus(uint32 A) +{ + int ret = -1; + + if(A >= 0x02000000 && A <= 0x058FFFFF) + ret = 0; + else if(A >= 0x05A00000 && A <= 0x05FBFFFF) + ret = 1; + else if(A >= 0x06000000) + ret = 2; + + return ret; +} + +static uint32 (*const rftab[3])(uint32) = { DMA_ReadABus, DMA_ReadBBus, DMA_ReadCBus }; + +static bool StartDMATransfer(DMALevelS* d, const uint32 ra, const uint32 wa, const uint32 bc) +{ + int rb, wb; + + SCU_DMA_VDP1WriteIgnoreKludge = 0; + + rb = AddressToBus(ra); + wb = AddressToBus(wa); + + SS_DBGTI(SS_DBG_SCU, "[SCU] Starting DMA level %d transfer; ra=0x%08x wa=0x%08x bc=0x%08x - read_inc=%d write_inc=0x%01x - indirect=%d %d", (int)(d - DMALevel), ra, wa, bc, d->ReadAdd, d->WriteAdd, d->Indirect, d->SF); + + if(MDFN_UNLIKELY(rb == -1)) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] Attempted DMA from illegal address 0x%08x\n", ra); + return false; + } + + if(MDFN_UNLIKELY(wb == -1)) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] Attempted DMA to illegal address 0x%08x\n", wa); + return false; + } + + if(MDFN_UNLIKELY(rb == wb)) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] Attempted illegal same-bus DMA from 0x%08x to 0x%08x\n", ra, wa); + return false; + } + + // + // + // + if((wa & 0x1) && wb == 1 && d->WriteAdd != 0x1) + { + // + // This sort of DMA is buggy on real hardware in weird ways(like the bus state controller is getting seriously confused), which we don't emulate. + // + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] Sketchy DMA of 0x%08x bytes from 0x%08x to unaligned B-bus address 0x%08x with write add value 0x%02x\n", bc, ra, wa, d->WriteAdd); + } + + if(wb == 0) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] Possibly sketchy DMA of 0x%08x bytes from 0x%08x to A-bus address 0x%08x\n", bc, ra, wa); + } + + d->CurReadBase = ra &~ 0x3; + d->CurReadSub = ra & 0x3; + + d->CurWriteAddr = wa; + + d->CurByteCount = bc; + + d->ReadFunc = rftab[rb]; + d->WriteBus = wb; + + d->Buffer = d->ReadFunc(d->CurReadBase); + + if(wb != 0x1 && d->WriteAdd == 0x1) + d->WATable = &dma_write_tab_aciv1[wa & 0x3][(bc < 16) ? bc : (16 | (bc & 0x7))][0]; + else + d->WATable = &dma_write_tab[wb == 1][d->WriteAdd][wa & 0x3][(bc < 12) ? bc : (8 | (bc & 0x3))][0]; + + return true; +} + +static bool NextIndirect(DMALevelS* d) +{ + // count, dest, src + uint32 tmp[3]; + + SS_DBG(SS_DBG_SCU, "[SCU] DMA level %d reading indirect table entries @ 0x%08x\n", (int)(d - DMALevel), d->CurTableAddr); + + for(unsigned i = 0; i < 3; i++) + { + tmp[i] = d->TableReadFunc(d->CurTableAddr); + d->CurTableAddr += (d->ReadAdd ? 4 : 0); + } + + d->FinalTransfer = (bool)(tmp[2] & 0x80000000); + + tmp[0] &= 0xFFFFF; + + if(!tmp[0]) + tmp[0] = 0x100000; + + return StartDMATransfer(d, tmp[2] & 0x07FFFFFF, tmp[1] & 0x07FFFFFF, tmp[0]); +} + +bool SCU_CheckVDP1HaltKludge(void) +{ + bool ret = false; + + for(int level = 2; level >= 0; level--) + { + DMALevelS* d = &DMALevel[level]; + + if(d->Active > 0) + { + if(d->WriteBus == 1 && d->ReadFunc == DMA_ReadCBus && d->CurWriteAddr >= 0x5C00000 && d->CurWriteAddr <= 0x5DFFFFF) + ret = true; + //else if(d->WriteBus == 2 && d->ReadFunc == DMA_ReadBBus && d->CurReadBase >= 0x5C00000 && d->CurReadBase <= 0x5C7FFFF) + // ret = true; + + break; + } + } + + return ret; +} + +static void RecalcDMAHalt(void) +{ + bool Halted = false; + + for(int level = 2; level >= 0; level--) + { + DMALevelS* d = &DMALevel[level]; + + if(d->Active > 0) + { + if(d->WriteBus == 2 || d->ReadFunc == DMA_ReadCBus) + Halted = true; +#if 1 + // + // TODO: See how halting works when a higher-priority DMA A-bus<->B-bus is running at the same time as a lower priority A/B-bus<->C-bus DMA. + // For now, just print a warning message if such a situation occurs. + else + { + for(int sl = level - 1; sl >= 0; sl--) + { + DMALevelS* sld = &DMALevel[sl]; + if(sld->Active && (sld->WriteBus == 2 || sld->ReadFunc == DMA_ReadCBus)) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] Higher priority A-bus<->B-bus DMA(level %d) running while lower-priority A-/B-bus<->C-bus DMA(level %d) is pending.\n", level, sl); + } + } + } +#endif + break; + } + } + + //fprintf(stderr, "SCU: %d --- %d %d %d\n", Halted, DMALevel[0].Active, DMALevel[1].Active, DMALevel[2].Active); + + CPU[0].SetExtHalt(Halted); + CPU[1].SetExtHalt(Halted); +} + +// TODO: Alter write tables to use -1, 0, 1 for 1, 2, 4 + +static void CheckDMAStart(DMALevelS* d) +{ + if(!d->Active && d->GoGoGadget) + { + d->GoGoGadget = false; + d->FinalTransfer = true; + d->TableReadFunc = NULL; + + if(d->Indirect) + { + int tb; + + d->CurTableAddr = d->StartWriteAddr & 0x07FFFFFC; // Tested, lower 2 bits are 0 on DMA end when write address update enabled. + tb = AddressToBus(d->CurTableAddr); + + if(tb < 0) + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] Invalid DMA indirect mode table address 0x%08x\n", d->CurTableAddr); + else + { + d->TableReadFunc = rftab[tb]; + + if(NextIndirect(d)) + { + d->Active = true; + RecalcDMAHalt(); + } + } + } + else + { + if(!StartDMATransfer(d, d->StartReadAddr, d->StartWriteAddr, (!d->StartByteCount) ? ((d - DMALevel) ? 0x1000 : 0x100000) : d->StartByteCount)) + { + SCU_SetInt(SCU_INT_DMA_ILL, true); + SCU_SetInt(SCU_INT_DMA_ILL, false); + } + else + { + d->Active = true; + RecalcDMAHalt(); + } + } + } +} + +static void CheckDMASFByInt(unsigned int_which) +{ + static const uint8 sf_to_int_tab[7] = + { + SCU_INT_VBIN, SCU_INT_VBOUT, SCU_INT_HBIN, SCU_INT_TIMER0, + SCU_INT_TIMER1, SCU_INT_SCSP, SCU_INT_VDP1 + }; + + for(unsigned level = 0; level < 3; level++) + { + auto& d = DMALevel[level]; + + if(d.Enable && d.SF < 0x7 && sf_to_int_tab[d.SF] == int_which) + { + d.GoGoGadget = true; + CheckDMAStart(&d); + } + } +} + +template +static INLINE uint32 DMA_Read(DMALevelS* d) +{ + int shift = ((0x3 ^ (d->CurReadSub & 0x3)) - (0x3 ^ (d->CurWriteAddr & 0x3 & (4 - count)))) * 8; + + //printf("Read: CurReadSub=0x%02x, CurWriteAddr=0x%08x, count=%zu --- ", d->CurReadSub, d->CurWriteAddr, count); + + d->CurReadSub += count; + if(d->CurReadSub > 4) + { + if((d->CurReadSub - count) < 4) + shift += 32; + + d->CurReadSub -= 4; //&= 0x3; + d->CurReadBase += (d->ReadAdd ? 4 : 0); + // + SCU_DMA_TimeCounter -= SCU_DMA_ReadOverhead; + SCU_DMA_ReadOverhead = 0; + uint32 tmp = d->ReadFunc(d->CurReadBase); + d->Buffer <<= 32; + d->Buffer |= tmp; + } + + //printf("buffer=%016llx, shift=%d\n", (uint64)d->Buffer, shift); + + if(shift > 0) + return d->Buffer >> shift; + else + return d->Buffer << -shift; +} + +template +static INLINE void DMA_Write(DMALevelS* d, uint32 DB) +{ + const uint32 A = d->CurWriteAddr &~ (sizeof(T) - 1); + int32 WriteOverhead = 0; + + //printf("Write: %zu %08x %08x\n", sizeof(T), A, DB); + if(WriteBus == 0) + { + ABus_Write_DB32(A, DB, NULL, &WriteOverhead); + } + else if(WriteBus == 1) + { + uint16 DB16; + + DB16 = DB >> (((A & 0x2) ^ 0x2) * 8); + BBusRW_DB(A, &DB16, NULL, &WriteOverhead); + } + else + { + ne16_wbo_be(WorkRAMH, A & 0xFFFFF, DB >> (((A & 3) ^ (4 - sizeof(T))) << 3)); + } + + SCU_DMA_TimeCounter -= WriteOverhead; + SCU_DMA_ReadOverhead = std::min(0, SCU_DMA_ReadOverhead - WriteOverhead); + d->CurByteCount -= sizeof(T); +} + +template +static bool NO_INLINE DMA_Loop(DMALevelS* d) +{ + while(MDFN_LIKELY(d->Active > 0 && SCU_DMA_TimeCounter < SCU_DMA_RunUntil)) + { + switch(d->WATable->write_size) + { + case 0x1: DMA_Write (d, DMA_Read<1>(d)); break; + case 0x2: DMA_Write(d, DMA_Read<2>(d)); break; + case 0x4: DMA_Write(d, DMA_Read<4>(d)); break; + } + d->CurWriteAddr += d->WATable->write_addr_delta; + + if(d->CurByteCount <= (uint32)(int8)d->WATable->compare) + d->WATable++; + + if(MDFN_UNLIKELY(!d->CurByteCount)) + { + SCU_DMA_TimeCounter -= SCU_DMA_ReadOverhead; + SCU_DMA_ReadOverhead = 0; + return true; + } + } + + return false; +} + +// +// TODO: Check start read/write address updating when wrapping to next bus or beyond end of SDRAM. +// +static INLINE void UpdateDMAInner(DMALevelS* d) +{ + static bool (*const LoopFuncs[3])(DMALevelS*) = { DMA_Loop<0>, DMA_Loop<1>, DMA_Loop<2> }; + + if(MDFN_UNLIKELY(LoopFuncs[d->WriteBus](d))) + { + if(d->TableReadFunc && !d->FinalTransfer) + { + NextIndirect(d); + } + else + { + if(d->ReadUpdate && !d->TableReadFunc) + d->StartReadAddr = (d->CurReadBase + d->CurReadSub) & 0x07FFFFFF; + + if(d->WriteUpdate) + { + if(d->TableReadFunc) + d->StartWriteAddr = d->CurTableAddr & 0x07FFFFFF; + else + d->StartWriteAddr = d->CurWriteAddr & 0x07FFFFFF; + } + + d->FinishTime = SCU_DMA_TimeCounter; + d->Active = -1; + } + } +} + +static void SCU_DoDMAEnd(const unsigned level) +{ + static const unsigned itab[3] = { SCU_INT_L0DMA, SCU_INT_L1DMA, SCU_INT_L2DMA }; + //printf("FIN: %08x %08x %u\n", d->CurReadBase, d->CurReadSub, d->ReadUpdate); + DMALevel[level].Active = false; + RecalcDMAHalt(); + SCU_SetInt(itab[level], true); + SCU_SetInt(itab[level], false); + CheckDMAStart(&DMALevel[level]); +} + +sscpu_timestamp_t SCU_UpdateDMA(sscpu_timestamp_t timestamp) +{ + if(timestamp < SH7095_mem_timestamp) + return SH7095_mem_timestamp; + // + // + // + SCU_DMA_TimeCounter = std::max(std::min(SCU_DMA_RunUntil, timestamp), SCU_DMA_TimeCounter); + SCU_DMA_RunUntil = timestamp + DMA_UpdateTimingGran; + + for(int level = 2; level >= 0; level--) + { + DMALevelS* d = &DMALevel[level]; + + while(d->Active && SCU_DMA_TimeCounter < SCU_DMA_RunUntil) + { + UpdateDMAInner(d); + + if(MDFN_UNLIKELY(d->Active < 0)) + { + if(MDFN_UNLIKELY(timestamp >= d->FinishTime)) + SCU_DoDMAEnd(level); + else + return d->FinishTime; + } + } + } + + return SCU_DMA_RunUntil; +} + +// +// Check to see if DMA is active, and if so, force the highest-priority DMA +// to finish early(kind of hacky). +// +static NO_INLINE void ForceDMAFinish(void) +{ + for(int level = 2; level >= 0; level--) + { + if(!DMALevel[level].Active) + continue; + + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] Forcing hacky early DMA level %d completion.\n", level); + + if(DMALevel[level].Active > 0) + { + const sscpu_timestamp_t rus = SCU_DMA_RunUntil; + // + SCU_DMA_RunUntil = 0x7FFFFFFF; + UpdateDMAInner(&DMALevel[level]); + // + SCU_DMA_RunUntil = rus; + } + + if(DMALevel[level].Active < 0) + SCU_DoDMAEnd(level); + + break; + } + + SCU_DMA_TimeCounter = SCU_DMA_RunUntil; +} + +static INLINE void CheckForceDMAFinish(void) +{ + if(MDFN_LIKELY(!(DMALevel[0].Active | DMALevel[1].Active | DMALevel[2].Active))) + return; + + ForceDMAFinish(); +} + +// +// +// +DSPS DSP; + +sscpu_timestamp_t SCU_UpdateDSP(sscpu_timestamp_t timestamp) +{ + int32 cycles = timestamp - DSP.LastTS; + DSP.LastTS = timestamp; + // + // + // + DSP.T0_Until += cycles; // Overflow prevented in SCU_ResetTS + DSP.CycleCounter += cycles; + if(DSP.CycleCounter > DSP_UpdateTimingGran) + DSP.CycleCounter = DSP_UpdateTimingGran; + + if(MDFN_UNLIKELY(!DSP.IsRunning())) + return SS_EVENT_DISABLED_TS; + + while(MDFN_LIKELY(DSP.CycleCounter > 0)) + { + //printf("%02x %16llx\n", DSP.PC, DSP.NextInstr); + ((void (*)(void))(DSP_INSTR_BASE_UIPT + (uintptr_t)(DSP_INSTR_RECOVER_TCAST)DSP.NextInstr))(); + DSP.CycleCounter -= 2; + } + + if(MDFN_UNLIKELY(!DSP.IsRunning())) + { + DSP.CycleCounter += DSP_EndCCSubVal; + return SS_EVENT_DISABLED_TS; + } + + return timestamp + DSP_UpdateTimingGran; +} + +static void DSP_Reset(bool powering_up) +{ + DSP.State = 0; + DSP.T0_Until = 0x10000000; + DSP.CycleCounter = 0; + + if(powering_up) + { + for(unsigned i = 0; i < 256; i++) + DSP.ProgRAM[i] = DSP_DecodeInstruction(0); + + for(unsigned i = 0; i < 256; i++) + (&DSP.DataRAM[0][0])[i] = 0; + } + + DSP.PC = 0; + DSP.RA = 0; + DSP.FlagZ = false; + DSP.FlagS = false; + DSP.FlagV = false; + DSP.FlagC = false; + DSP.FlagEnd = false; + SCU_SetInt(SCU_INT_DSP, false); + + DSP.NextInstr = DSP_DecodeInstruction(0); + + DSP.TOP = 0; + DSP.LOP = 0; + + DSP.AC.T = 0; + DSP.P.T = 0; + + for(unsigned i = 0; i < 4; i++) + DSP.CT[i] = 0; + + DSP.RX = 0; + DSP.RY = 0; + + DSP.RAO = 0; + DSP.WAO = 0; +} + +void DSP_Init(void) +{ + DSP.LastTS = 0; + + for(auto* f : DSP_GenFuncTable) + assert((uintptr_t)f == DSP_INSTR_BASE_UIPT + ((uintptr_t)(DSP_INSTR_RECOVER_TCAST)(uint32)((uintptr_t)f - DSP_INSTR_BASE_UIPT))); + + for(auto* f : DSP_DMAFuncTable) + assert((uintptr_t)f == DSP_INSTR_BASE_UIPT + ((uintptr_t)(DSP_INSTR_RECOVER_TCAST)(uint32)((uintptr_t)f - DSP_INSTR_BASE_UIPT))); + + for(auto* f : DSP_MVIFuncTable) + assert((uintptr_t)f == DSP_INSTR_BASE_UIPT + ((uintptr_t)(DSP_INSTR_RECOVER_TCAST)(uint32)((uintptr_t)f - DSP_INSTR_BASE_UIPT))); + + for(auto* f : DSP_JMPFuncTable) + assert((uintptr_t)f == DSP_INSTR_BASE_UIPT + ((uintptr_t)(DSP_INSTR_RECOVER_TCAST)(uint32)((uintptr_t)f - DSP_INSTR_BASE_UIPT))); + + for(auto* f : DSP_MiscFuncTable) + assert((uintptr_t)f == DSP_INSTR_BASE_UIPT + ((uintptr_t)(DSP_INSTR_RECOVER_TCAST)(uint32)((uintptr_t)f - DSP_INSTR_BASE_UIPT))); +} + +template +static NO_INLINE NO_CLONE void DMAInstr(void) +{ + const uint32 instr = DSP_InstrPre(); + const unsigned add_mode = (instr >> 15) & 0x7; + uint8 count; // 0 = 256 + + if(DSP.T0_Until < DSP.CycleCounter) + DSP.CycleCounter = DSP.T0_Until &~ 1; + + DSP.T0_Until = DSP.CycleCounter; + + if(format) + { + const unsigned crw = instr & 0x3; + const bool ctinc = instr & 0x4; + + count = DSP.DataRAM[crw][DSP.CT[crw]] & 0xFF; + DSP.CT[crw] = (DSP.CT[crw] + ctinc) & 0x3F; + } + else + count = instr & 0xFF; + + //printf("%02x %08x Count: %u\n", DSP.PC, instr, count); + //SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] DSP DMA; looped=%u, add_mode=0x%01x, hold=%u, format=%u, dir=%u, drw=0x%02x -- count=%u, RAO=0x%08x, WAO=0x%08x\n", looped, add_mode, hold, format, dir, drw, count, DSP.RAO, DSP.WAO); + + if(dir) + { + const uint32 addr_add_amount = (1 << add_mode) &~ 1; + uint32 addr = (DSP.WAO << 2) & 0x07FFFFFF; + const int WriteBus = AddressToBus(addr); + + if(MDFN_UNLIKELY(WriteBus == -1)) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] Bad DSP DMA to 0x%08x --- Instr=0x%08x, Next_Instr=0x%08x, PC=0x%02x\n", addr, instr, (unsigned)(DSP.NextInstr >> 32), DSP.PC); + return; + } + + // Read from data RAM, write to external bus + do + { + uint32 DB; + + if(drw & 0x4) + DB = 0xFFFFFFFF; + else + { + DB = DSP.DataRAM[drw][DSP.CT[drw]]; + DSP.CT[drw] = (DSP.CT[drw] + 1) & 0x3F; + } + + if(WriteBus == 2) + { + ne16_wbo_be(WorkRAMH, addr & 0xFFFFC, DB); + addr += addr_add_amount; + DSP.T0_Until -= 2; + } + else if(WriteBus == 1) + { + uint16 DB16; + + DB16 = DB >> 16; + BBusRW_DB(addr, &DB16, NULL, &DSP.T0_Until); + + addr += addr_add_amount; + + DB16 = DB; + BBusRW_DB(addr, &DB16, NULL, &DSP.T0_Until); + + addr += addr_add_amount; + } + else if(WriteBus == 0) + { + ABus_Write_DB32(addr, DB, NULL, &DSP.T0_Until); + + addr += addr_add_amount; + } + } while(--count); + + if(!hold) + DSP.WAO = (addr + 2) >> 2; + } + else + { + const uint32 addr_add_amount = (1 << (add_mode & 0x2)) &~ 1; + uint32 addr = (DSP.RAO << 2) & 0x07FFFFFF; + const int ReadBus = AddressToBus(addr); + + if(MDFN_UNLIKELY(ReadBus == -1)) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] Bad DSP DMA from 0x%08x --- Instr=0x%08x, Next_Instr=0x%08x, PC=0x%02x\n", addr, instr, (unsigned)(DSP.NextInstr >> 32), DSP.PC); + return; + } + + if(drw & 0x4) + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] DSP DMA from 0x%08x to %s --- Instr=0x%08x, Next_Instr=0x%08x, PC=0x%02x\n", addr, ((drw == 0x4) ? "program RAM" : "unknown"), instr, (unsigned)(DSP.NextInstr >> 32), DSP.PC); + + // Read from external bus, write to data RAM or program RAM + do + { + uint32 DB = 0; + + if(ReadBus == 2) + { + DB = ne16_rbo_be(WorkRAMH, addr & 0xFFFFF); + DSP.T0_Until -= 2; + } + else if(ReadBus == 1) + { + uint16 tmp = 0; + + BBusRW_DB(addr | 0, &tmp, NULL, &DSP.T0_Until); + DB = tmp << 16; + + BBusRW_DB(addr | 2, &tmp, NULL, &DSP.T0_Until); + DB |= tmp << 0; + } + else if(ReadBus == 0) + DB = ABus_Read(addr, NULL, &DSP.T0_Until); + + addr += addr_add_amount; + + if(drw & 0x4) + { + if(!(drw & 0x3)) + { + DSP.ProgRAM[DSP.PC++] = DSP_DecodeInstruction(DB); + } + } + else + { + DSP.DataRAM[drw][DSP.CT[drw]] = DB; + DSP.CT[drw] = (DSP.CT[drw] + 1) & 0x3F; + } + } while(--count); + + if(!hold) + DSP.RAO = addr >> 2; + } +} + +extern void (*const DSP_DMAFuncTable[2][8][8])(void) = +{ + #include "scu_dsp_dmatab.inc" +}; + +// +// +// +// +// +// +uint32 SCU_DSP_PeekProgRAM(uint8 A) +{ + return DSP.ProgRAM[A] >> 32; +} + +uint32 SCU_GetRegister(const unsigned id, char* const special, const uint32 special_len) +{ + uint32 ret = 0xDEADBEEF; + + switch(id) + { + case SCU_GSREG_ILEVEL: + ret = ILevel; + break; + + case SCU_GSREG_IVEC: + ret = IVec; + break; + + case SCU_GSREG_IASSERTED: + ret = IAsserted; + break; + + case SCU_GSREG_IPENDING: + ret = IPending; + break; + + case SCU_GSREG_IMASK: + ret = IMask; + break; + + case SCU_GSREG_T0CNT: + ret = Timer0_Counter; + break; + + case SCU_GSREG_T0CMP: + ret = Timer0_Compare; + break; + + case SCU_GSREG_T0MET: + ret = Timer0_Met; + break; + + case SCU_GSREG_T1RLV: + ret = Timer1_Reload; + break; + + case SCU_GSREG_T1CNT: + ret = Timer1_Counter; + break; + + case SCU_GSREG_T1MOD: + ret = Timer1_Mode; + break; + + case SCU_GSREG_T1MET: + ret = Timer1_Met; + break; + + case SCU_GSREG_TENBL: + ret = Timer_Enable; + break; + + case SCU_GSREG_DSP_EXEC: + ret = (bool)(DSP.State & DSPS::STATE_MASK_EXECUTE); + break; + + case SCU_GSREG_DSP_PAUSE: + ret = (bool)(DSP.State & DSPS::STATE_MASK_PAUSE); + break; + + case SCU_GSREG_DSP_PC: + ret = DSP.PC; + break; + + case SCU_GSREG_DSP_END: + ret = DSP.FlagEnd; + break; + } + return ret; +} + +void SCU_SetRegister(const unsigned id, const uint32 value) +{ + switch(id) + { + case SCU_GSREG_IPENDING: + IPending = value & 0xFFFF3FFF; + break; + + case SCU_GSREG_IMASK: + IMask = value & 0xBFFF; + break; + // + case SCU_GSREG_T0CNT: + //Timer0_Counter = value & 0x1FF; + break; + + case SCU_GSREG_T0CMP: + Timer0_Compare = value & 0x3FF; + break; + + case SCU_GSREG_T0MET: + //Timer0_Met = value & 0x1; + break; + + case SCU_GSREG_T1RLV: + Timer1_Reload = value & 0x1FF; + break; + + case SCU_GSREG_T1CNT: + //Timer1_Counter = value & 0x1FF; + break; + + case SCU_GSREG_T1MOD: + Timer1_Mode = value & 0x1; + break; + + case SCU_GSREG_T1MET: + //Timer1_Met = value & 0x1; + break; + + case SCU_GSREG_TENBL: + Timer_Enable = value & 0x1; + break; + // + + } + + // Not quite right: +#if 0 + Timer0_Check(); + Timer1_Check(); + SCU_SetHBVB(0, HB_FromVDP2, VB_FromVDP2); +#endif + + RecalcMasterIntOut(); +} + diff --git a/waterbox/ss/scu_aciv1tab.inc b/waterbox/ss/scu_aciv1tab.inc new file mode 100644 index 0000000000..5a49cd445e --- /dev/null +++ b/waterbox/ss/scu_aciv1tab.inc @@ -0,0 +1,112 @@ + /*dest_align=0*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 4, 0x4, 0x00 }, }, + /* 5 */ { { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 0, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 7 */ { { 0, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 2, 0x4, 0x00 }, }, + /* 9 */ { { 2, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 2, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 11 */ { { 2, 0x4, 0x03 }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 12 */ { { 2, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 13 */ { { 2, 0x4, 0x05 }, { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 14 */ { { 2, 0x4, 0x06 }, { 0, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 15 */ { { 2, 0x4, 0x07 }, { 0, 0x4, 0x03 }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 16 */ { { 2, 0x4, 0x00 }, }, + /* 17 */ { { 2, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 18 */ { { 2, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 19 */ { { 2, 0x4, 0x03 }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 20 */ { { 2, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 21 */ { { 2, 0x4, 0x05 }, { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 22 */ { { 2, 0x4, 0x06 }, { 0, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 23 */ { { 2, 0x4, 0x07 }, { 0, 0x4, 0x03 }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=1*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 1, 0x1, 0x00 }, }, + /* 3 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0x03 }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 8 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 12 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0x05 }, { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 13 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0x06 }, { 0, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 14 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0x07 }, { 0, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 15 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0x08 }, { 0, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 16 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0xff }, { 2, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 17 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0xff }, { 2, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 18 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0xff }, { 2, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 19 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0xff }, { 2, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 20 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0xff }, { 2, 0x4, 0x05 }, { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 21 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0xff }, { 2, 0x4, 0x06 }, { 0, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 22 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0xff }, { 2, 0x4, 0x07 }, { 0, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 23 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0xff }, { 2, 0x4, 0x08 }, { 0, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + }, + + /*dest_align=2*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 2, 0x2, 0x00 }, }, + /* 5 */ { { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 2, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 7 */ { { 2, 0x2, 0xff }, { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 2, 0x2, 0xff }, { 0, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 9 */ { { 2, 0x2, 0xff }, { 0, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 2, 0x2, 0xff }, { 2, 0x4, 0x00 }, }, + /* 11 */ { { 2, 0x2, 0xff }, { 2, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 12 */ { { 2, 0x2, 0xff }, { 2, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 13 */ { { 2, 0x2, 0xff }, { 2, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 14 */ { { 2, 0x2, 0xff }, { 2, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 15 */ { { 2, 0x2, 0xff }, { 2, 0x4, 0x05 }, { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 16 */ { { 2, 0x2, 0xff }, { 2, 0x4, 0x06 }, { 0, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 17 */ { { 2, 0x2, 0xff }, { 2, 0x4, 0x07 }, { 0, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 18 */ { { 2, 0x2, 0xff }, { 2, 0x4, 0x00 }, }, + /* 19 */ { { 2, 0x2, 0xff }, { 2, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 20 */ { { 2, 0x2, 0xff }, { 2, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 21 */ { { 2, 0x2, 0xff }, { 2, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 22 */ { { 2, 0x2, 0xff }, { 2, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 23 */ { { 2, 0x2, 0xff }, { 2, 0x4, 0x05 }, { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=3*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 1, 0x1, 0x00 }, }, + /* 3 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 1, 0x1, 0xff }, { 4, 0x4, 0x00 }, }, + /* 6 */ { { 1, 0x1, 0xff }, { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 1, 0x1, 0xff }, { 0, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 8 */ { { 1, 0x1, 0xff }, { 0, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 1, 0x1, 0xff }, { 2, 0x4, 0x00 }, }, + /* 10 */ { { 1, 0x1, 0xff }, { 2, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 1, 0x1, 0xff }, { 2, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 12 */ { { 1, 0x1, 0xff }, { 2, 0x4, 0x07 }, { 2, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 13 */ { { 1, 0x1, 0xff }, { 2, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 14 */ { { 1, 0x1, 0xff }, { 2, 0x4, 0x05 }, { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 15 */ { { 1, 0x1, 0xff }, { 2, 0x4, 0x06 }, { 0, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 16 */ { { 1, 0x1, 0xff }, { 2, 0x4, 0x07 }, { 0, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 17 */ { { 1, 0x1, 0xff }, { 2, 0x4, 0x00 }, }, + /* 18 */ { { 1, 0x1, 0xff }, { 2, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 19 */ { { 1, 0x1, 0xff }, { 2, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 20 */ { { 1, 0x1, 0xff }, { 2, 0x4, 0x07 }, { 2, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 21 */ { { 1, 0x1, 0xff }, { 2, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 22 */ { { 1, 0x1, 0xff }, { 2, 0x4, 0x05 }, { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 23 */ { { 1, 0x1, 0xff }, { 2, 0x4, 0x06 }, { 0, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + }, + diff --git a/waterbox/ss/scu_actab.inc b/waterbox/ss/scu_actab.inc new file mode 100644 index 0000000000..b72a347562 --- /dev/null +++ b/waterbox/ss/scu_actab.inc @@ -0,0 +1,479 @@ +/*dest_raw_inc=0x00 */ +{ + + /*dest_align=0*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 4, 0x4, 0x00 }, }, + /* 5 */ { { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 0, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 7 */ { { 0, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 0, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 9 */ { { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 0, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 11 */ { { 0, 0x4, 0x03 }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=1 */ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 1, 0x1, 0x00 }, }, + /* 3 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 8 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 0, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 0, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 0, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + }, + + /*dest_align=2 */ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { -2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { -2, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 5 */ { { -2, 0x2, 0x03 }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { -2, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 7 */ { { -2, 0x2, 0xff }, { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { -2, 0x2, 0xff }, { 0, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 9 */ { { -2, 0x2, 0xff }, { 0, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { -2, 0x2, 0xff }, { 0, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 11 */ { { -2, 0x2, 0xff }, { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=3 */ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { -3, 0x1, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 3 */ { { -3, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { -3, 0x1, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { -3, 0x1, 0xff }, { 4, 0x4, 0x00 }, }, + /* 6 */ { { -3, 0x1, 0xff }, { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { -3, 0x1, 0xff }, { 0, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 8 */ { { -3, 0x1, 0xff }, { 0, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { -3, 0x1, 0xff }, { 0, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 10 */ { { -3, 0x1, 0xff }, { 0, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { -3, 0x1, 0xff }, { 0, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + }, +}, + +/*dest_raw_inc=0x01 (handled in scu_aciv1tab.inc) */ +{ +}, + +/*dest_raw_inc=0x02*/ +{ + + /*dest_align=0*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 4, 0x4, 0x00 }, }, + /* 5 */ { { 4, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 4, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 7 */ { { 4, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 4, 0x4, 0x00 }, }, + /* 9 */ { { 4, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 4, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 11 */ { { 4, 0x4, 0x03 }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=1*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 1, 0x1, 0x00 }, }, + /* 3 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 8 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0xff }, { 4, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0xff }, { 4, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0xff }, { 4, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + }, + + /*dest_align=2*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 2, 0x2, 0x00 }, }, + /* 5 */ { { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 2, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 7 */ { { 2, 0x2, 0xff }, { 4, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 2, 0x2, 0xff }, { 4, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 9 */ { { 2, 0x2, 0xff }, { 4, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 2, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 11 */ { { 2, 0x2, 0xff }, { 4, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=3*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 1, 0x1, 0x00 }, }, + /* 3 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 1, 0x1, 0xff }, { 4, 0x4, 0x00 }, }, + /* 6 */ { { 1, 0x1, 0xff }, { 4, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 1, 0x1, 0xff }, { 4, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 8 */ { { 1, 0x1, 0xff }, { 4, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 1, 0x1, 0xff }, { 4, 0x4, 0x00 }, }, + /* 10 */ { { 1, 0x1, 0xff }, { 4, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 1, 0x1, 0xff }, { 4, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + }, +}, + +/*dest_raw_inc=0x03*/ +{ + + /*dest_align=0*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 4, 0x4, 0x00 }, }, + /* 5 */ { { 8, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 8, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 7 */ { { 8, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 8, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 9 */ { { 8, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 8, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 11 */ { { 8, 0x4, 0x03 }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=1*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 1, 0x1, 0x00 }, }, + /* 3 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 1, 0x1, 0xff }, { 6, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 1, 0x1, 0xff }, { 6, 0x2, 0xff }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 1, 0x1, 0xff }, { 6, 0x2, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 1, 0x1, 0xff }, { 6, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 8 */ { { 1, 0x1, 0xff }, { 6, 0x2, 0xff }, { 8, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 1, 0x1, 0xff }, { 6, 0x2, 0xff }, { 8, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 1, 0x1, 0xff }, { 6, 0x2, 0xff }, { 8, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 1, 0x1, 0xff }, { 6, 0x2, 0xff }, { 8, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + }, + + /*dest_align=2*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 6, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 6, 0x2, 0xff }, { 2, 0x2, 0x00 }, }, + /* 5 */ { { 6, 0x2, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 6, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 7 */ { { 6, 0x2, 0xff }, { 8, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 6, 0x2, 0xff }, { 8, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 9 */ { { 6, 0x2, 0xff }, { 8, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 6, 0x2, 0xff }, { 8, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 11 */ { { 6, 0x2, 0xff }, { 8, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=3*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 5, 0x1, 0xff }, { 1, 0x1, 0x00 }, }, + /* 3 */ { { 5, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 5, 0x1, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 5, 0x1, 0xff }, { 4, 0x4, 0x00 }, }, + /* 6 */ { { 5, 0x1, 0xff }, { 8, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 5, 0x1, 0xff }, { 8, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 8 */ { { 5, 0x1, 0xff }, { 8, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 5, 0x1, 0xff }, { 8, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 10 */ { { 5, 0x1, 0xff }, { 8, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 5, 0x1, 0xff }, { 8, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + }, +}, + +/*dest_raw_inc=0x04*/ +{ + + /*dest_align=0*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 4, 0x4, 0x00 }, }, + /* 5 */ { { 16, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 16, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 7 */ { { 16, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 16, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 9 */ { { 16, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 16, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 11 */ { { 16, 0x4, 0x03 }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=1*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 1, 0x1, 0x00 }, }, + /* 3 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 1, 0x1, 0xff }, { 14, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 1, 0x1, 0xff }, { 14, 0x2, 0xff }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 1, 0x1, 0xff }, { 14, 0x2, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 1, 0x1, 0xff }, { 14, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 8 */ { { 1, 0x1, 0xff }, { 14, 0x2, 0xff }, { 16, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 1, 0x1, 0xff }, { 14, 0x2, 0xff }, { 16, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 1, 0x1, 0xff }, { 14, 0x2, 0xff }, { 16, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 1, 0x1, 0xff }, { 14, 0x2, 0xff }, { 16, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + }, + + /*dest_align=2*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 14, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 14, 0x2, 0xff }, { 2, 0x2, 0x00 }, }, + /* 5 */ { { 14, 0x2, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 14, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 7 */ { { 14, 0x2, 0xff }, { 16, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 14, 0x2, 0xff }, { 16, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 9 */ { { 14, 0x2, 0xff }, { 16, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 14, 0x2, 0xff }, { 16, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 11 */ { { 14, 0x2, 0xff }, { 16, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=3*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 13, 0x1, 0xff }, { 1, 0x1, 0x00 }, }, + /* 3 */ { { 13, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 13, 0x1, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 13, 0x1, 0xff }, { 4, 0x4, 0x00 }, }, + /* 6 */ { { 13, 0x1, 0xff }, { 16, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 13, 0x1, 0xff }, { 16, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 8 */ { { 13, 0x1, 0xff }, { 16, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 13, 0x1, 0xff }, { 16, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 10 */ { { 13, 0x1, 0xff }, { 16, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 13, 0x1, 0xff }, { 16, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + }, +}, + +/*dest_raw_inc=0x05*/ +{ + + /*dest_align=0*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 4, 0x4, 0x00 }, }, + /* 5 */ { { 32, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 32, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 7 */ { { 32, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 32, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 9 */ { { 32, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 32, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 11 */ { { 32, 0x4, 0x03 }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=1*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 1, 0x1, 0x00 }, }, + /* 3 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 1, 0x1, 0xff }, { 30, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 1, 0x1, 0xff }, { 30, 0x2, 0xff }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 1, 0x1, 0xff }, { 30, 0x2, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 1, 0x1, 0xff }, { 30, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 8 */ { { 1, 0x1, 0xff }, { 30, 0x2, 0xff }, { 32, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 1, 0x1, 0xff }, { 30, 0x2, 0xff }, { 32, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 1, 0x1, 0xff }, { 30, 0x2, 0xff }, { 32, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 1, 0x1, 0xff }, { 30, 0x2, 0xff }, { 32, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + }, + + /*dest_align=2*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 30, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 30, 0x2, 0xff }, { 2, 0x2, 0x00 }, }, + /* 5 */ { { 30, 0x2, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 30, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 7 */ { { 30, 0x2, 0xff }, { 32, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 30, 0x2, 0xff }, { 32, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 9 */ { { 30, 0x2, 0xff }, { 32, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 30, 0x2, 0xff }, { 32, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 11 */ { { 30, 0x2, 0xff }, { 32, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=3*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 29, 0x1, 0xff }, { 1, 0x1, 0x00 }, }, + /* 3 */ { { 29, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 29, 0x1, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 29, 0x1, 0xff }, { 4, 0x4, 0x00 }, }, + /* 6 */ { { 29, 0x1, 0xff }, { 32, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 29, 0x1, 0xff }, { 32, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 8 */ { { 29, 0x1, 0xff }, { 32, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 29, 0x1, 0xff }, { 32, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 10 */ { { 29, 0x1, 0xff }, { 32, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 29, 0x1, 0xff }, { 32, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + }, +}, + +/*dest_raw_inc=0x06*/ +{ + + /*dest_align=0*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 4, 0x4, 0x00 }, }, + /* 5 */ { { 64, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 64, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 7 */ { { 64, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 64, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 9 */ { { 64, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 64, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 11 */ { { 64, 0x4, 0x03 }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=1*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 1, 0x1, 0x00 }, }, + /* 3 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 1, 0x1, 0xff }, { 62, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 1, 0x1, 0xff }, { 62, 0x2, 0xff }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 1, 0x1, 0xff }, { 62, 0x2, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 1, 0x1, 0xff }, { 62, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 8 */ { { 1, 0x1, 0xff }, { 62, 0x2, 0xff }, { 64, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 1, 0x1, 0xff }, { 62, 0x2, 0xff }, { 64, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 1, 0x1, 0xff }, { 62, 0x2, 0xff }, { 64, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 1, 0x1, 0xff }, { 62, 0x2, 0xff }, { 64, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + }, + + /*dest_align=2*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 62, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 62, 0x2, 0xff }, { 2, 0x2, 0x00 }, }, + /* 5 */ { { 62, 0x2, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 62, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 7 */ { { 62, 0x2, 0xff }, { 64, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 62, 0x2, 0xff }, { 64, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 9 */ { { 62, 0x2, 0xff }, { 64, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 62, 0x2, 0xff }, { 64, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 11 */ { { 62, 0x2, 0xff }, { 64, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=3*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 61, 0x1, 0xff }, { 1, 0x1, 0x00 }, }, + /* 3 */ { { 61, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 61, 0x1, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 61, 0x1, 0xff }, { 4, 0x4, 0x00 }, }, + /* 6 */ { { 61, 0x1, 0xff }, { 64, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 61, 0x1, 0xff }, { 64, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 8 */ { { 61, 0x1, 0xff }, { 64, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 61, 0x1, 0xff }, { 64, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 10 */ { { 61, 0x1, 0xff }, { 64, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 61, 0x1, 0xff }, { 64, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + }, +}, + +/*dest_raw_inc=0x07*/ +{ + + /*dest_align=0*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 4, 0x4, 0x00 }, }, + /* 5 */ { { 128, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 128, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 7 */ { { 128, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 128, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 9 */ { { 128, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 128, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 11 */ { { 128, 0x4, 0x03 }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=1*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 1, 0x1, 0x00 }, }, + /* 3 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 1, 0x1, 0xff }, { 126, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 1, 0x1, 0xff }, { 126, 0x2, 0xff }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 1, 0x1, 0xff }, { 126, 0x2, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 1, 0x1, 0xff }, { 126, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 8 */ { { 1, 0x1, 0xff }, { 126, 0x2, 0xff }, { 128, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 1, 0x1, 0xff }, { 126, 0x2, 0xff }, { 128, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 1, 0x1, 0xff }, { 126, 0x2, 0xff }, { 128, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 1, 0x1, 0xff }, { 126, 0x2, 0xff }, { 128, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + }, + + /*dest_align=2*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 126, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 126, 0x2, 0xff }, { 2, 0x2, 0x00 }, }, + /* 5 */ { { 126, 0x2, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 126, 0x2, 0xff }, { 4, 0x4, 0x00 }, }, + /* 7 */ { { 126, 0x2, 0xff }, { 128, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 126, 0x2, 0xff }, { 128, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 9 */ { { 126, 0x2, 0xff }, { 128, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 126, 0x2, 0xff }, { 128, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 11 */ { { 126, 0x2, 0xff }, { 128, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=3*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 125, 0x1, 0xff }, { 1, 0x1, 0x00 }, }, + /* 3 */ { { 125, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 125, 0x1, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 125, 0x1, 0xff }, { 4, 0x4, 0x00 }, }, + /* 6 */ { { 125, 0x1, 0xff }, { 128, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 125, 0x1, 0xff }, { 128, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 8 */ { { 125, 0x1, 0xff }, { 128, 0x4, 0x03 }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 125, 0x1, 0xff }, { 128, 0x4, 0x04 }, { 4, 0x4, 0x00 }, }, + /* 10 */ { { 125, 0x1, 0xff }, { 128, 0x4, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 125, 0x1, 0xff }, { 128, 0x4, 0x02 }, { 2, 0x2, 0x00 }, }, + }, +}, diff --git a/waterbox/ss/scu_btab.inc b/waterbox/ss/scu_btab.inc new file mode 100644 index 0000000000..c6825f39d2 --- /dev/null +++ b/waterbox/ss/scu_btab.inc @@ -0,0 +1,542 @@ +/*dest_raw_inc=0x00 */ +{ + /*dest_align=0*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 0, 0x2, 0x02 }, { 4, 0x2, 0x02 }, }, + /* 5 */ { { 0, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 0, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 7 */ { { 0, 0x2, 0x03 }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 0, 0x2, 0x02 }, { 4, 0x2, 0x02 }, }, + /* 9 */ { { 0, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 0, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 11 */ { { 0, 0x2, 0x03 }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=1*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 1, 0x1, 0x00 }, }, + /* 3 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 0, 0x2, 0x02 }, { 4, 0x2, 0x02 }, }, + /* 8 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 0, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 0, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 0, 0x2, 0x03 }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 1, 0x1, 0xff }, { -2, 0x2, 0xff }, { 0, 0x2, 0x02 }, { 4, 0x2, 0x00 }, }, + }, + + /*dest_align=2*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 0, 0x2, 0xff }, { -1, 0x1, 0x00 }, }, + /* 4 */ { { 0, 0x2, 0x00 }, }, + /* 5 */ { { 0, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 0, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 7 */ { { 0, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 8 */ { { 0, 0x2, 0x00 }, }, + /* 9 */ { { 0, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 0, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 11 */ { { 0, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + }, + + /*dest_align=3*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { -1, 0x1, 0xff }, { -1, 0x1, 0x00 }, }, + /* 3 */ { { -1, 0x1, 0xff }, { 0, 0x2, 0x00 }, }, + /* 4 */ { { -1, 0x1, 0xff }, { 0, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { -1, 0x1, 0xff }, { 0, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { -1, 0x1, 0xff }, { 0, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 7 */ { { -1, 0x1, 0xff }, { 0, 0x2, 0x00 }, }, + /* 8 */ { { -1, 0x1, 0xff }, { 0, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { -1, 0x1, 0xff }, { 0, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { -1, 0x1, 0xff }, { 0, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 11 */ { { -1, 0x1, 0xff }, { 0, 0x2, 0x00 }, }, + }, +}, + + +/*dest_raw_inc=0x01*/ +{ + /*dest_align=0*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 2, 0x2, 0x00 }, }, + /* 5 */ { { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 2, 0x2, 0x00 }, }, + /* 7 */ { { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 2, 0x2, 0x00 }, }, + /* 9 */ { { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 2, 0x2, 0x00 }, }, + /* 11 */ { { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=1*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 1, 0x1, 0x00 }, }, + /* 3 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 8 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + }, + + /*dest_align=2*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 4 */ { { 2, 0x2, 0x00 }, }, + /* 5 */ { { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 2, 0x2, 0x00 }, }, + /* 7 */ { { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 8 */ { { 2, 0x2, 0x00 }, }, + /* 9 */ { { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 2, 0x2, 0x00 }, }, + /* 11 */ { { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + }, + + /*dest_align=3*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 1, 0x1, 0x00 }, }, + /* 3 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 4 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 7 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 8 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 11 */ { { 1, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + }, +}, + +/*dest_raw_inc=0x02*/ +{ + + /*dest_align=0*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 6, 0x2, 0xff }, { -3, 0x1, 0x00 }, }, + /* 4 */ { { 4, 0x2, 0xff }, { 0, 0x2, 0x00 }, }, + /* 5 */ { { 4, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 4, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 7 */ { { 4, 0x2, 0x03 }, { 6, 0x2, 0x01 }, { -3, 0x1, 0x00 }, }, + /* 8 */ { { 4, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + /* 9 */ { { 4, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 4, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 11 */ { { 4, 0x2, 0x03 }, { 6, 0x2, 0x01 }, { -3, 0x1, 0x00 }, }, + }, + + /*dest_align=1*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 5, 0x1, 0xff }, { -3, 0x1, 0x00 }, }, + /* 3 */ { { 5, 0x1, 0xff }, { -2, 0x2, 0x00 }, }, + /* 4 */ { { 5, 0x1, 0xff }, { 2, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 5, 0x1, 0xff }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 5, 0x1, 0xff }, { 2, 0x2, 0xff }, { 6, 0x2, 0xff }, { -3, 0x1, 0x00 }, }, + /* 7 */ { { 5, 0x1, 0xff }, { 2, 0x2, 0xff }, { 4, 0x2, 0xff }, { 0, 0x2, 0x00 }, }, + /* 8 */ { { 5, 0x1, 0xff }, { 2, 0x2, 0xff }, { 4, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 5, 0x1, 0xff }, { 2, 0x2, 0xff }, { 4, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 5, 0x1, 0xff }, { 2, 0x2, 0xff }, { 4, 0x2, 0x03 }, { 6, 0x2, 0x01 }, { -3, 0x1, 0x00 }, }, + /* 11 */ { { 5, 0x1, 0xff }, { 2, 0x2, 0xff }, { 4, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + }, + + /*dest_align=2*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 4, 0x2, 0xff }, { -1, 0x1, 0x00 }, }, + /* 4 */ { { 4, 0x2, 0xff }, { 0, 0x2, 0x00 }, }, + /* 5 */ { { 4, 0x2, 0x01 }, { -3, 0x1, 0x00 }, }, + /* 6 */ { { 4, 0x2, 0x02 }, { -2, 0x2, 0x00 }, }, + /* 7 */ { { 4, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 8 */ { { 4, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + /* 9 */ { { 4, 0x2, 0x01 }, { -3, 0x1, 0x00 }, }, + /* 10 */ { { 4, 0x2, 0x02 }, { -2, 0x2, 0x00 }, }, + /* 11 */ { { 4, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + }, + + /*dest_align=3*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 7, 0x1, 0xff }, { -1, 0x1, 0x00 }, }, + /* 3 */ { { 7, 0x1, 0xff }, { 0, 0x2, 0x00 }, }, + /* 4 */ { { 7, 0x1, 0xff }, { 4, 0x2, 0xff }, { -3, 0x1, 0x00 }, }, + /* 5 */ { { 7, 0x1, 0xff }, { 4, 0x2, 0xff }, { -2, 0x2, 0x00 }, }, + /* 6 */ { { 7, 0x1, 0xff }, { 4, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 7 */ { { 7, 0x1, 0xff }, { 4, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + /* 8 */ { { 7, 0x1, 0xff }, { 4, 0x2, 0x01 }, { -3, 0x1, 0x00 }, }, + /* 9 */ { { 7, 0x1, 0xff }, { 4, 0x2, 0x02 }, { -2, 0x2, 0x00 }, }, + /* 10 */ { { 7, 0x1, 0xff }, { 4, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 11 */ { { 7, 0x1, 0xff }, { 4, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + }, +}, + +/*dest_raw_inc=0x03*/ +{ + + /*dest_align=0*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 10, 0x2, 0xff }, { -7, 0x1, 0x00 }, }, + /* 4 */ { { 8, 0x2, 0xff }, { -4, 0x2, 0x00 }, }, + /* 5 */ { { 8, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 8, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 7 */ { { 8, 0x2, 0x03 }, { 10, 0x2, 0x01 }, { -7, 0x1, 0x00 }, }, + /* 8 */ { { 8, 0x2, 0x02 }, { -4, 0x2, 0x00 }, }, + /* 9 */ { { 8, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 8, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 11 */ { { 8, 0x2, 0x03 }, { 10, 0x2, 0x01 }, { -7, 0x1, 0x00 }, }, + }, + + /*dest_align=1*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 9, 0x1, 0xff }, { -7, 0x1, 0x00 }, }, + /* 3 */ { { 9, 0x1, 0xff }, { -6, 0x2, 0x00 }, }, + /* 4 */ { { 9, 0x1, 0xff }, { 6, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 9, 0x1, 0xff }, { 6, 0x2, 0xff }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 9, 0x1, 0xff }, { 6, 0x2, 0xff }, { 10, 0x2, 0xff }, { -7, 0x1, 0x00 }, }, + /* 7 */ { { 9, 0x1, 0xff }, { 6, 0x2, 0xff }, { 8, 0x2, 0xff }, { -4, 0x2, 0x00 }, }, + /* 8 */ { { 9, 0x1, 0xff }, { 6, 0x2, 0xff }, { 8, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 9, 0x1, 0xff }, { 6, 0x2, 0xff }, { 8, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 9, 0x1, 0xff }, { 6, 0x2, 0xff }, { 8, 0x2, 0x03 }, { 10, 0x2, 0x01 }, { -7, 0x1, 0x00 }, }, + /* 11 */ { { 9, 0x1, 0xff }, { 6, 0x2, 0xff }, { 8, 0x2, 0x02 }, { -4, 0x2, 0x00 }, }, + }, + + /*dest_align=2*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 8, 0x2, 0xff }, { -1, 0x1, 0x00 }, }, + /* 4 */ { { 8, 0x2, 0xff }, { 0, 0x2, 0x00 }, }, + /* 5 */ { { 8, 0x2, 0x01 }, { -7, 0x1, 0x00 }, }, + /* 6 */ { { 8, 0x2, 0x02 }, { -6, 0x2, 0x00 }, }, + /* 7 */ { { 8, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 8 */ { { 8, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + /* 9 */ { { 8, 0x2, 0x01 }, { -7, 0x1, 0x00 }, }, + /* 10 */ { { 8, 0x2, 0x02 }, { -6, 0x2, 0x00 }, }, + /* 11 */ { { 8, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + }, + + /*dest_align=3*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 15, 0x1, 0xff }, { -1, 0x1, 0x00 }, }, + /* 3 */ { { 15, 0x1, 0xff }, { 0, 0x2, 0x00 }, }, + /* 4 */ { { 15, 0x1, 0xff }, { 8, 0x2, 0xff }, { -7, 0x1, 0x00 }, }, + /* 5 */ { { 15, 0x1, 0xff }, { 8, 0x2, 0xff }, { -6, 0x2, 0x00 }, }, + /* 6 */ { { 15, 0x1, 0xff }, { 8, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 7 */ { { 15, 0x1, 0xff }, { 8, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + /* 8 */ { { 15, 0x1, 0xff }, { 8, 0x2, 0x01 }, { -7, 0x1, 0x00 }, }, + /* 9 */ { { 15, 0x1, 0xff }, { 8, 0x2, 0x02 }, { -6, 0x2, 0x00 }, }, + /* 10 */ { { 15, 0x1, 0xff }, { 8, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 11 */ { { 15, 0x1, 0xff }, { 8, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + }, +}, + +/*dest_raw_inc=0x04*/ +{ + + /*dest_align=0*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 18, 0x2, 0xff }, { -15, 0x1, 0x00 }, }, + /* 4 */ { { 16, 0x2, 0xff }, { -12, 0x2, 0x00 }, }, + /* 5 */ { { 16, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 16, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 7 */ { { 16, 0x2, 0x03 }, { 18, 0x2, 0x01 }, { -15, 0x1, 0x00 }, }, + /* 8 */ { { 16, 0x2, 0x02 }, { -12, 0x2, 0x00 }, }, + /* 9 */ { { 16, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 16, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 11 */ { { 16, 0x2, 0x03 }, { 18, 0x2, 0x01 }, { -15, 0x1, 0x00 }, }, + }, + + /*dest_align=1*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 17, 0x1, 0xff }, { -15, 0x1, 0x00 }, }, + /* 3 */ { { 17, 0x1, 0xff }, { -14, 0x2, 0x00 }, }, + /* 4 */ { { 17, 0x1, 0xff }, { 14, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 17, 0x1, 0xff }, { 14, 0x2, 0xff }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 17, 0x1, 0xff }, { 14, 0x2, 0xff }, { 18, 0x2, 0xff }, { -15, 0x1, 0x00 }, }, + /* 7 */ { { 17, 0x1, 0xff }, { 14, 0x2, 0xff }, { 16, 0x2, 0xff }, { -12, 0x2, 0x00 }, }, + /* 8 */ { { 17, 0x1, 0xff }, { 14, 0x2, 0xff }, { 16, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 17, 0x1, 0xff }, { 14, 0x2, 0xff }, { 16, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 17, 0x1, 0xff }, { 14, 0x2, 0xff }, { 16, 0x2, 0x03 }, { 18, 0x2, 0x01 }, { -15, 0x1, 0x00 }, }, + /* 11 */ { { 17, 0x1, 0xff }, { 14, 0x2, 0xff }, { 16, 0x2, 0x02 }, { -12, 0x2, 0x00 }, }, + }, + + /*dest_align=2*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 16, 0x2, 0xff }, { -1, 0x1, 0x00 }, }, + /* 4 */ { { 16, 0x2, 0xff }, { 0, 0x2, 0x00 }, }, + /* 5 */ { { 16, 0x2, 0x01 }, { -15, 0x1, 0x00 }, }, + /* 6 */ { { 16, 0x2, 0x02 }, { -14, 0x2, 0x00 }, }, + /* 7 */ { { 16, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 8 */ { { 16, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + /* 9 */ { { 16, 0x2, 0x01 }, { -15, 0x1, 0x00 }, }, + /* 10 */ { { 16, 0x2, 0x02 }, { -14, 0x2, 0x00 }, }, + /* 11 */ { { 16, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + }, + + /*dest_align=3*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 31, 0x1, 0xff }, { -1, 0x1, 0x00 }, }, + /* 3 */ { { 31, 0x1, 0xff }, { 0, 0x2, 0x00 }, }, + /* 4 */ { { 31, 0x1, 0xff }, { 16, 0x2, 0xff }, { -15, 0x1, 0x00 }, }, + /* 5 */ { { 31, 0x1, 0xff }, { 16, 0x2, 0xff }, { -14, 0x2, 0x00 }, }, + /* 6 */ { { 31, 0x1, 0xff }, { 16, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 7 */ { { 31, 0x1, 0xff }, { 16, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + /* 8 */ { { 31, 0x1, 0xff }, { 16, 0x2, 0x01 }, { -15, 0x1, 0x00 }, }, + /* 9 */ { { 31, 0x1, 0xff }, { 16, 0x2, 0x02 }, { -14, 0x2, 0x00 }, }, + /* 10 */ { { 31, 0x1, 0xff }, { 16, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 11 */ { { 31, 0x1, 0xff }, { 16, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + }, +}, + +/*dest_raw_inc=0x05*/ +{ + + /*dest_align=0*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 34, 0x2, 0xff }, { -31, 0x1, 0x00 }, }, + /* 4 */ { { 32, 0x2, 0xff }, { -28, 0x2, 0x00 }, }, + /* 5 */ { { 32, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 32, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 7 */ { { 32, 0x2, 0x03 }, { 34, 0x2, 0x01 }, { -31, 0x1, 0x00 }, }, + /* 8 */ { { 32, 0x2, 0x02 }, { -28, 0x2, 0x00 }, }, + /* 9 */ { { 32, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 32, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 11 */ { { 32, 0x2, 0x03 }, { 34, 0x2, 0x01 }, { -31, 0x1, 0x00 }, }, + }, + + /*dest_align=1*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 33, 0x1, 0xff }, { -31, 0x1, 0x00 }, }, + /* 3 */ { { 33, 0x1, 0xff }, { -30, 0x2, 0x00 }, }, + /* 4 */ { { 33, 0x1, 0xff }, { 30, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 33, 0x1, 0xff }, { 30, 0x2, 0xff }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 33, 0x1, 0xff }, { 30, 0x2, 0xff }, { 34, 0x2, 0xff }, { -31, 0x1, 0x00 }, }, + /* 7 */ { { 33, 0x1, 0xff }, { 30, 0x2, 0xff }, { 32, 0x2, 0xff }, { -28, 0x2, 0x00 }, }, + /* 8 */ { { 33, 0x1, 0xff }, { 30, 0x2, 0xff }, { 32, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 33, 0x1, 0xff }, { 30, 0x2, 0xff }, { 32, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 33, 0x1, 0xff }, { 30, 0x2, 0xff }, { 32, 0x2, 0x03 }, { 34, 0x2, 0x01 }, { -31, 0x1, 0x00 }, }, + /* 11 */ { { 33, 0x1, 0xff }, { 30, 0x2, 0xff }, { 32, 0x2, 0x02 }, { -28, 0x2, 0x00 }, }, + }, + + /*dest_align=2*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 32, 0x2, 0xff }, { -1, 0x1, 0x00 }, }, + /* 4 */ { { 32, 0x2, 0xff }, { 0, 0x2, 0x00 }, }, + /* 5 */ { { 32, 0x2, 0x01 }, { -31, 0x1, 0x00 }, }, + /* 6 */ { { 32, 0x2, 0x02 }, { -30, 0x2, 0x00 }, }, + /* 7 */ { { 32, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 8 */ { { 32, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + /* 9 */ { { 32, 0x2, 0x01 }, { -31, 0x1, 0x00 }, }, + /* 10 */ { { 32, 0x2, 0x02 }, { -30, 0x2, 0x00 }, }, + /* 11 */ { { 32, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + }, + + /*dest_align=3*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 63, 0x1, 0xff }, { -1, 0x1, 0x00 }, }, + /* 3 */ { { 63, 0x1, 0xff }, { 0, 0x2, 0x00 }, }, + /* 4 */ { { 63, 0x1, 0xff }, { 32, 0x2, 0xff }, { -31, 0x1, 0x00 }, }, + /* 5 */ { { 63, 0x1, 0xff }, { 32, 0x2, 0xff }, { -30, 0x2, 0x00 }, }, + /* 6 */ { { 63, 0x1, 0xff }, { 32, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 7 */ { { 63, 0x1, 0xff }, { 32, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + /* 8 */ { { 63, 0x1, 0xff }, { 32, 0x2, 0x01 }, { -31, 0x1, 0x00 }, }, + /* 9 */ { { 63, 0x1, 0xff }, { 32, 0x2, 0x02 }, { -30, 0x2, 0x00 }, }, + /* 10 */ { { 63, 0x1, 0xff }, { 32, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 11 */ { { 63, 0x1, 0xff }, { 32, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + }, +}, + +/*dest_raw_inc=0x06*/ +{ + + /*dest_align=0*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 66, 0x2, 0xff }, { -63, 0x1, 0x00 }, }, + /* 4 */ { { 64, 0x2, 0xff }, { -60, 0x2, 0x00 }, }, + /* 5 */ { { 64, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 64, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 7 */ { { 64, 0x2, 0x03 }, { 66, 0x2, 0x01 }, { -63, 0x1, 0x00 }, }, + /* 8 */ { { 64, 0x2, 0x02 }, { -60, 0x2, 0x00 }, }, + /* 9 */ { { 64, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 64, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 11 */ { { 64, 0x2, 0x03 }, { 66, 0x2, 0x01 }, { -63, 0x1, 0x00 }, }, + }, + + /*dest_align=1*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 65, 0x1, 0xff }, { -63, 0x1, 0x00 }, }, + /* 3 */ { { 65, 0x1, 0xff }, { -62, 0x2, 0x00 }, }, + /* 4 */ { { 65, 0x1, 0xff }, { 62, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 65, 0x1, 0xff }, { 62, 0x2, 0xff }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 65, 0x1, 0xff }, { 62, 0x2, 0xff }, { 66, 0x2, 0xff }, { -63, 0x1, 0x00 }, }, + /* 7 */ { { 65, 0x1, 0xff }, { 62, 0x2, 0xff }, { 64, 0x2, 0xff }, { -60, 0x2, 0x00 }, }, + /* 8 */ { { 65, 0x1, 0xff }, { 62, 0x2, 0xff }, { 64, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 65, 0x1, 0xff }, { 62, 0x2, 0xff }, { 64, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 65, 0x1, 0xff }, { 62, 0x2, 0xff }, { 64, 0x2, 0x03 }, { 66, 0x2, 0x01 }, { -63, 0x1, 0x00 }, }, + /* 11 */ { { 65, 0x1, 0xff }, { 62, 0x2, 0xff }, { 64, 0x2, 0x02 }, { -60, 0x2, 0x00 }, }, + }, + + /*dest_align=2*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 64, 0x2, 0xff }, { -1, 0x1, 0x00 }, }, + /* 4 */ { { 64, 0x2, 0xff }, { 0, 0x2, 0x00 }, }, + /* 5 */ { { 64, 0x2, 0x01 }, { -63, 0x1, 0x00 }, }, + /* 6 */ { { 64, 0x2, 0x02 }, { -62, 0x2, 0x00 }, }, + /* 7 */ { { 64, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 8 */ { { 64, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + /* 9 */ { { 64, 0x2, 0x01 }, { -63, 0x1, 0x00 }, }, + /* 10 */ { { 64, 0x2, 0x02 }, { -62, 0x2, 0x00 }, }, + /* 11 */ { { 64, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + }, + + /*dest_align=3*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 127, 0x1, 0xff }, { -1, 0x1, 0x00 }, }, + /* 3 */ { { 127, 0x1, 0xff }, { 0, 0x2, 0x00 }, }, + /* 4 */ { { 127, 0x1, 0xff }, { 64, 0x2, 0xff }, { -63, 0x1, 0x00 }, }, + /* 5 */ { { 127, 0x1, 0xff }, { 64, 0x2, 0xff }, { -62, 0x2, 0x00 }, }, + /* 6 */ { { 127, 0x1, 0xff }, { 64, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 7 */ { { 127, 0x1, 0xff }, { 64, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + /* 8 */ { { 127, 0x1, 0xff }, { 64, 0x2, 0x01 }, { -63, 0x1, 0x00 }, }, + /* 9 */ { { 127, 0x1, 0xff }, { 64, 0x2, 0x02 }, { -62, 0x2, 0x00 }, }, + /* 10 */ { { 127, 0x1, 0xff }, { 64, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 11 */ { { 127, 0x1, 0xff }, { 64, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + }, +}, + +/*dest_raw_inc=0x07*/ +{ + + /*dest_align=0*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 130, 0x2, 0xff }, { -127, 0x1, 0x00 }, }, + /* 4 */ { { 128, 0x2, 0xff }, { -124, 0x2, 0x00 }, }, + /* 5 */ { { 128, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 6 */ { { 128, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 7 */ { { 128, 0x2, 0x03 }, { 130, 0x2, 0x01 }, { -127, 0x1, 0x00 }, }, + /* 8 */ { { 128, 0x2, 0x02 }, { -124, 0x2, 0x00 }, }, + /* 9 */ { { 128, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 10 */ { { 128, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 11 */ { { 128, 0x2, 0x03 }, { 130, 0x2, 0x01 }, { -127, 0x1, 0x00 }, }, + }, + + /*dest_align=1*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 129, 0x1, 0xff }, { -127, 0x1, 0x00 }, }, + /* 3 */ { { 129, 0x1, 0xff }, { -126, 0x2, 0x00 }, }, + /* 4 */ { { 129, 0x1, 0xff }, { 126, 0x2, 0xff }, { 1, 0x1, 0x00 }, }, + /* 5 */ { { 129, 0x1, 0xff }, { 126, 0x2, 0xff }, { 2, 0x2, 0x00 }, }, + /* 6 */ { { 129, 0x1, 0xff }, { 126, 0x2, 0xff }, { 130, 0x2, 0xff }, { -127, 0x1, 0x00 }, }, + /* 7 */ { { 129, 0x1, 0xff }, { 126, 0x2, 0xff }, { 128, 0x2, 0xff }, { -124, 0x2, 0x00 }, }, + /* 8 */ { { 129, 0x1, 0xff }, { 126, 0x2, 0xff }, { 128, 0x2, 0x01 }, { 1, 0x1, 0x00 }, }, + /* 9 */ { { 129, 0x1, 0xff }, { 126, 0x2, 0xff }, { 128, 0x2, 0x02 }, { 2, 0x2, 0x00 }, }, + /* 10 */ { { 129, 0x1, 0xff }, { 126, 0x2, 0xff }, { 128, 0x2, 0x03 }, { 130, 0x2, 0x01 }, { -127, 0x1, 0x00 }, }, + /* 11 */ { { 129, 0x1, 0xff }, { 126, 0x2, 0xff }, { 128, 0x2, 0x02 }, { -124, 0x2, 0x00 }, }, + }, + + /*dest_align=2*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 2, 0x2, 0x00 }, }, + /* 3 */ { { 128, 0x2, 0xff }, { -1, 0x1, 0x00 }, }, + /* 4 */ { { 128, 0x2, 0xff }, { 0, 0x2, 0x00 }, }, + /* 5 */ { { 128, 0x2, 0x01 }, { -127, 0x1, 0x00 }, }, + /* 6 */ { { 128, 0x2, 0x02 }, { -126, 0x2, 0x00 }, }, + /* 7 */ { { 128, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 8 */ { { 128, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + /* 9 */ { { 128, 0x2, 0x01 }, { -127, 0x1, 0x00 }, }, + /* 10 */ { { 128, 0x2, 0x02 }, { -126, 0x2, 0x00 }, }, + /* 11 */ { { 128, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + }, + + /*dest_align=3*/ + { + /* 0 */ { }, + /* 1 */ { { 1, 0x1, 0x00 }, }, + /* 2 */ { { 255, 0x1, 0xff }, { -1, 0x1, 0x00 }, }, + /* 3 */ { { 255, 0x1, 0xff }, { 0, 0x2, 0x00 }, }, + /* 4 */ { { 255, 0x1, 0xff }, { 128, 0x2, 0xff }, { -127, 0x1, 0x00 }, }, + /* 5 */ { { 255, 0x1, 0xff }, { 128, 0x2, 0xff }, { -126, 0x2, 0x00 }, }, + /* 6 */ { { 255, 0x1, 0xff }, { 128, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 7 */ { { 255, 0x1, 0xff }, { 128, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + /* 8 */ { { 255, 0x1, 0xff }, { 128, 0x2, 0x01 }, { -127, 0x1, 0x00 }, }, + /* 9 */ { { 255, 0x1, 0xff }, { 128, 0x2, 0x02 }, { -126, 0x2, 0x00 }, }, + /* 10 */ { { 255, 0x1, 0xff }, { 128, 0x2, 0x01 }, { -1, 0x1, 0x00 }, }, + /* 11 */ { { 255, 0x1, 0xff }, { 128, 0x2, 0x02 }, { 0, 0x2, 0x00 }, }, + }, +}, diff --git a/waterbox/ss/scu_dsp_common.inc b/waterbox/ss/scu_dsp_common.inc new file mode 100644 index 0000000000..2ee9dd77e7 --- /dev/null +++ b/waterbox/ss/scu_dsp_common.inc @@ -0,0 +1,235 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* scu_dsp_common.inc: +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +// base ptr must match the waterbox base load location! +#if (defined(__x86_64__) && defined(__code_model_small__) && !defined(__PIC__) && !defined(__pic__)) || SIZEOF_VOID_P <= 4 + #define DSP_INSTR_BASE_UIPT 0x36d00000000ul + #define DSP_INSTR_RECOVER_TCAST uint32 +#else + #define DSP_INSTR_BASE_UIPT ((uintptr_t)DSP_Init) + #define DSP_INSTR_RECOVER_TCAST int32 +#endif + +// See loop in "SCU_UpdateDSP()" in scu.inc, and END/ENDI handling in scu_dsp_misc.cpp +enum { DSP_EndCCSubVal = 1000000 }; + +void DSP_Init(void); + +struct DSP_ITS; + +union DSPR48 +{ +#ifdef MSB_FIRST + struct + { + uint16 dummy; + uint16 H; + uint32 L; + }; +#else + struct + { + uint32 L; + uint16 H; + uint16 dummy; + }; +#endif + uint64 T; // Upper 16 bits may be non-zero "garbage", so don't assume they're zero in code that reads from this variable. +}; + +struct DSPS +{ + sscpu_timestamp_t LastTS; + int32 CycleCounter; + int32 T0_Until; + // + enum + { + // No execute = 0x00000000 <= 0 + // Paused + No execute = 0x80000000 <= 0 + // Paused + Execute = 0x80000001 <= 0 + // Execute = 0x00000001 > 0 + STATE_MASK_PAUSE = 0x80000000, + STATE_MASK_EXECUTE = 0x00000001, + }; + int32 State; + + INLINE bool IsRunning(void) // returns true if not stopped and not paused. + { + return State > 0; + } + + uint64 NextInstr; + + uint8 PC; + uint8 RA; + + bool FlagZ; + bool FlagS; + bool FlagV; + bool FlagC; + + bool FlagEnd; + + uint8 TOP; + uint16 LOP; // 12 bits + + DSPR48 AC; + DSPR48 P; + + union + { + uint8 CT[4]; // 6 bits(each) + uint32 CT32; + }; + + uint32 RX; + uint32 RY; + + uint32 RAO; + uint32 WAO; + + uint32 DataRAM[4][64]; + + uint64 ProgRAM[256]; // Upper 32 bits = actual raw instruction, lower 32 bits = horrible emulator handler pointer madness +}; + + +// ALU Op: bits 26-29 - *16 +// X Op: bits 23-25 - * 8 +// Y Op: bits 17-19 - * 8 +// D1 Op: bits 12-13 - * 4 +extern void (*const DSP_GenFuncTable[2][16][8][8][4])(void); + +// Hold/Format/Direction: bits 12-14 +// Hold: bit 14 +// Format: bit 13 +// Direction: bit 12 +// RAM: bits 8-10 +// +extern void (*const DSP_DMAFuncTable[2][8][8])(void); + +// +// Dest: bits 26-29 +// Condition: bits 19-25 +// +extern void (*const DSP_MVIFuncTable[2][16][128])(void); + +// +// Condition: bits 19-25 +// +extern void (*const DSP_JMPFuncTable[2][128])(void); + + +// +// LPS, BTM, END, ENDI(bits 29-31 = 0x7) +// bits 27-28 +// +extern void (*const DSP_MiscFuncTable[2][4])(void); + +extern DSPS DSP; + +template +static INLINE uint64 DSP_DecodeInstruction(const uint32 instr) +{ + void (*aal)(void); + + switch((instr >> 28) & 0xF) + { + default: + aal = DSP_GenFuncTable[looped][0][0][0][0]; + break; + + case 0x0: + case 0x1: + case 0x2: + case 0x3: + aal = DSP_GenFuncTable[looped][(instr >> 26) & 0xF][(instr >> 23) & 0x7][(instr >> 17) & 0x7][(instr >> 12) & 0x3]; + break; + + case 0x8: + case 0x9: + case 0xA: + case 0xB: + aal = DSP_MVIFuncTable[looped][(instr >> 26) & 0xF][(instr >> 19) & 0x7F]; + break; + + case 0xC: + aal = DSP_DMAFuncTable[looped][(instr >> 12) & 0x7][(instr >> 8) & 0x7]; + break; + + case 0xD: + aal = DSP_JMPFuncTable[looped][(instr >> 19) & 0x7F]; + break; + + case 0xE: + case 0xF: + aal = DSP_MiscFuncTable[looped][(instr >> 27) & 0x3]; + break; + } + + return ((uint64)instr << 32) | (uint32)((uintptr_t)aal - DSP_INSTR_BASE_UIPT); +} + +template +static INLINE uint32 DSP_InstrPre(void) +{ + const uint32 instr = DSP.NextInstr >> 32; + + if(!looped || !DSP.LOP) + { + DSP.NextInstr = DSP.ProgRAM[DSP.PC]; + DSP.PC++; + } + + if(looped) + DSP.LOP -= (bool)DSP.LOP; + + return instr; +} + +template +static INLINE bool DSP_TestCond(void) +{ + if(!(cond & 0x40)) + return true; + // + // + // + bool ret = false; + + if(cond & 0x1) + ret |= DSP.FlagZ; + + if(cond & 0x2) + ret |= DSP.FlagS; + + if(cond & 0x4) + ret |= DSP.FlagC; + + if(cond & 0x8) + ret |= (DSP.T0_Until < DSP.CycleCounter); + + //if(cond & 0x10) // ? + + return ret == (bool)(cond & 0x20); +} + diff --git a/waterbox/ss/scu_dsp_dmatab.inc b/waterbox/ss/scu_dsp_dmatab.inc new file mode 100644 index 0000000000..84b975aceb --- /dev/null +++ b/waterbox/ss/scu_dsp_dmatab.inc @@ -0,0 +1,52 @@ +{ /* looped=0 */ + { + DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, + }, + { + DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, + }, + { + DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, + }, + { + DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, + }, + { + DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, + }, + { + DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, + }, + { + DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, + }, + { + DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, + }, + }, +{ /* looped=1 */ + { + DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, + }, + { + DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, + }, + { + DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, + }, + { + DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, + }, + { + DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, + }, + { + DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, + }, + { + DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, + }, + { + DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, DMAInstr, + }, + }, diff --git a/waterbox/ss/scu_dsp_gen.cpp b/waterbox/ss/scu_dsp_gen.cpp new file mode 100644 index 0000000000..0e96907088 --- /dev/null +++ b/waterbox/ss/scu_dsp_gen.cpp @@ -0,0 +1,343 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* scu_dsp_gen.cpp - SCU DSP General Instructions Emulation +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "ss.h" +#include "scu.h" + +#include "endian.h" + +#pragma GCC optimize("Os") + // Is first DSP instruction cached on PC load, or when execution starts? + + // MOV [s],[d] s=0x8 = 0xFFFFFFFF? + + // MOV [s],[d] when moving from/to the same data RAM bank seems to be treated like a NOP... + +namespace MDFN_IEN_SS +{ +#include "scu_dsp_common.inc" + +static INLINE void SetC(bool value) +{ + DSP.FlagC = value; +} + +static INLINE void CalcZS32(uint32 val) +{ + DSP.FlagS = (int32)val < 0; + DSP.FlagZ = !val; +} + +static INLINE void CalcZS48(uint64 val) +{ + val <<= 16; + + DSP.FlagS = (int64)val < 0; + DSP.FlagZ = !val; +} + + +template +static NO_INLINE NO_CLONE void GeneralInstr(void) +{ + const uint32 instr = DSP_InstrPre(); + // + DSPR48 ALU = DSP.AC; + unsigned dr_read = 0; + unsigned ct_inc = 0; + + switch(alu_op) + { + // + // NOP + // + default: + { + + } + break; + + // + // AND + // + case 0x01: + { + ALU.L &= DSP.P.L; + SetC(false); + CalcZS32(ALU.L); + } + break; + + // + // OR + // + case 0x02: + { + ALU.L |= DSP.P.L; + SetC(false); + CalcZS32(ALU.L); + } + break; + + // + // XOR + // + case 0x03: + { + ALU.L ^= DSP.P.L; + SetC(false); + CalcZS32(ALU.L); + } + break; + + // + // ADD + // + case 0x04: + { + const uint64 tmp = (uint64)ALU.L + DSP.P.L; + + DSP.FlagV |= (((~(ALU.L ^ DSP.P.L)) & (ALU.L ^ tmp)) >> 31) & 1; + SetC((tmp >> 32) & 0x1); + CalcZS32(tmp); + ALU.L = tmp; + } + break; + + // + // SUB + // + case 0x05: + { + const uint64 tmp = (uint64)ALU.L - DSP.P.L; + + DSP.FlagV |= ((((ALU.L ^ DSP.P.L)) & (ALU.L ^ tmp)) >> 31) & 1; + SetC((tmp >> 32) & 0x1); + CalcZS32(tmp); + ALU.L = tmp; + } + break; + + // + // AD2 + // + case 0x06: + { + const uint64 tmp = (ALU.T & 0xFFFFFFFFFFFFULL) + (DSP.P.T & 0xFFFFFFFFFFFFULL); + + DSP.FlagV |= (((~(ALU.T ^ DSP.P.T)) & (ALU.T ^ tmp)) >> 47) & 1; + SetC((tmp >> 48) & 0x1); + CalcZS48(tmp); + ALU.T = tmp; + } + break; + + // + // SR + // + case 0x08: + { + const bool new_C = ALU.L & 0x1; + + SetC(new_C); + ALU.L = (int32)ALU.L >> 1; + CalcZS32(ALU.L); + } + break; + + // + // RR + // + case 0x09: + { + const bool new_C = ALU.L & 0x1; + + SetC(new_C); + ALU.L = (ALU.L >> 1) | (new_C << 31); + CalcZS32(ALU.L); + } + break; + + // + // SL + // + case 0x0A: + { + const bool new_C = ALU.L >> 31; + + SetC(new_C); + ALU.L <<= 1; + CalcZS32(ALU.L); + } + break; + + // + // RL + // + case 0x0B: + { + const bool new_C = ALU.L >> 31; + + SetC(new_C); + ALU.L = (ALU.L << 1) | new_C; + CalcZS32(ALU.L); + } + break; + + // + // RL8 + // + case 0x0F: + { + const bool new_C = (ALU.L >> 24) & 1; + + SetC(new_C); + ALU.L = (ALU.L << 8) | (ALU.L >> 24); + CalcZS32(ALU.L); + } + break; + } + + // + // X Op + // + if((x_op & 0x3) == 0x2) + DSP.P.T = (int64)(int32)DSP.RX * (int32)DSP.RY; + + if(x_op >= 0x3) + { + const unsigned s = (instr >> 20) & 0x7; + const size_t drw = s & 0x3; + uint32 src_data; + + src_data = DSP.DataRAM[drw][DSP.CT[drw]]; + dr_read |= 1U << drw; + ct_inc |= (bool)(s & 0x4) << (drw << 3); + + if((x_op & 0x3) == 0x3) + DSP.P.T = (int32)src_data; + + if(x_op & 0x4) + DSP.RX = src_data; + } + + // + // Y Op + // + if((y_op & 0x3) == 0x1) + DSP.AC.T = 0; + else if((y_op & 0x3) == 0x2) + DSP.AC.T = ALU.T; + + if(y_op >= 0x3) + { + const unsigned s = (instr >> 14) & 0x7; + const size_t drw = s & 0x3; + uint32 src_data; + + src_data = DSP.DataRAM[drw][DSP.CT[drw]]; + dr_read |= 1U << drw; + ct_inc |= (bool)(s & 0x4) << (drw << 3); + + if((y_op & 0x3) == 0x3) + DSP.AC.T = (int32)src_data; + + if(y_op & 0x4) + DSP.RY = src_data; + } + + // + // D1 Op (TODO: Test illegal bit patterns) + // + if(d1_op & 0x1) + { + const unsigned d = (instr >> 8) & 0xF; + uint32 src_data = (int8)instr; + + if(d1_op & 0x2) + { + switch(instr & 0xF) + { + case 0x8: + case 0xB: + case 0xC: + case 0xD: + case 0xE: + case 0xF: src_data = 0xFFFFFFFF; break; + + case 0x0: src_data = DSP.DataRAM[0][DSP.CT[0]]; dr_read |= 0x01; break; + case 0x1: src_data = DSP.DataRAM[1][DSP.CT[1]]; dr_read |= 0x02; break; + case 0x2: src_data = DSP.DataRAM[2][DSP.CT[2]]; dr_read |= 0x04; break; + case 0x3: src_data = DSP.DataRAM[3][DSP.CT[3]]; dr_read |= 0x08; break; + + case 0x4: src_data = DSP.DataRAM[0][DSP.CT[0]]; if(d != 0) { ct_inc |= 1 << 0; } dr_read |= 0x01; break; + case 0x5: src_data = DSP.DataRAM[1][DSP.CT[1]]; if(d != 1) { ct_inc |= 1 << 8; } dr_read |= 0x02; break; + case 0x6: src_data = DSP.DataRAM[2][DSP.CT[2]]; if(d != 2) { ct_inc |= 1 << 16; } dr_read |= 0x04; break; + case 0x7: src_data = DSP.DataRAM[3][DSP.CT[3]]; if(d != 3) { ct_inc |= 1 << 24; } dr_read |= 0x08; break; + + case 0x9: src_data = ALU.T; break; + case 0xA: src_data = ALU.T >> 16; break; + } + } + + switch(d) + { + case 0x0: if(!(dr_read & 0x01)) { DSP.DataRAM[0][DSP.CT[0]] = src_data; ct_inc |= 1 << 0; } break; + case 0x1: if(!(dr_read & 0x02)) { DSP.DataRAM[1][DSP.CT[1]] = src_data; ct_inc |= 1 << 8; } break; + case 0x2: if(!(dr_read & 0x04)) { DSP.DataRAM[2][DSP.CT[2]] = src_data; ct_inc |= 1 << 16; } break; + case 0x3: if(!(dr_read & 0x08)) { DSP.DataRAM[3][DSP.CT[3]] = src_data; ct_inc |= 1 << 24; } break; + case 0x4: DSP.RX = src_data; break; + case 0x5: DSP.P.T = (int32)src_data; break; + case 0x6: DSP.RAO = src_data; break; + case 0x7: DSP.WAO = src_data; break; + case 0x8: + case 0x9: break; + case 0xA: DSP.LOP = src_data & 0x0FFF; break; + case 0xB: DSP.TOP = src_data & 0xFF; break; + + // + // Don't bother masking with 0x3F here, since the & 0x3F3F3F3F mask down below will cover it(and no chance of overflowing into an adjacent byte + // since we're masking out the corresponding byte in ct_inc, too). + // + case 0xC: DSP.CT[0] = src_data; ct_inc &= ~0x000000FF; break; + case 0xD: DSP.CT[1] = src_data; ct_inc &= ~0x0000FF00; break; + case 0xE: DSP.CT[2] = src_data; ct_inc &= ~0x00FF0000; break; + case 0xF: DSP.CT[3] = src_data; ct_inc &= ~0xFF000000; break; + } + } + + // + // + // + #ifdef MSB_FIRST + ct_inc = MDFN_bswap32(ct_inc); + #endif + + if(x_op >= 0x3 || y_op >= 0x3 || (d1_op & 0x1)) + DSP.CT32 = (DSP.CT32 + ct_inc) & 0x3F3F3F3F; +} + +extern void (*const DSP_GenFuncTable[2][16][8][8][4])(void) = +{ + #include "scu_dsp_gentab.inc" +}; + +} diff --git a/waterbox/ss/scu_dsp_gentab.inc b/waterbox/ss/scu_dsp_gentab.inc new file mode 100644 index 0000000000..60d308a2ae --- /dev/null +++ b/waterbox/ss/scu_dsp_gentab.inc @@ -0,0 +1,8772 @@ +{ /* looped=0 */ + { /* alu_op=0x00 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x01 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x02 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x03 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x04 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x05 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x06 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x07 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x08 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x09 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x0a */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x0b */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x0c */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x0d */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x0e */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x0f */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, +}, +{ /* looped=1 */ + { /* alu_op=0x00 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x01 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x02 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x03 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x04 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x05 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x06 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x07 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x08 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x09 */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x0a */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x0b */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x0c */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x0d */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x0e */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, + { /* alu_op=0x0f */ + { /* x_op=0x00 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x01 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x02 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x03 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x04 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x05 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x06 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + { /* x_op=0x07 */ + { /* y_op=0x00 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x01 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x02 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x03 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x04 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x05 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x06 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + { /* y_op=0x07 */ + GeneralInstr, GeneralInstr, GeneralInstr, GeneralInstr, + }, + + }, + }, +}, diff --git a/waterbox/ss/scu_dsp_jmp.cpp b/waterbox/ss/scu_dsp_jmp.cpp new file mode 100644 index 0000000000..0271dfe3d2 --- /dev/null +++ b/waterbox/ss/scu_dsp_jmp.cpp @@ -0,0 +1,45 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* scu_dsp_jmp.cpp - SCU DSP JMP Instructions Emulation +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "ss.h" +#include "scu.h" + +#pragma GCC optimize("Os") + +namespace MDFN_IEN_SS +{ +#include "scu_dsp_common.inc" + +template +static NO_INLINE NO_CLONE void JMPInstr(void) +{ + const uint32 instr = DSP_InstrPre(); + + if(DSP_TestCond()) + DSP.PC = (uint8)instr; +} + +extern void (*const DSP_JMPFuncTable[2][128])(void) = +{ + #include "scu_dsp_jmptab.inc" +}; + +} diff --git a/waterbox/ss/scu_dsp_jmptab.inc b/waterbox/ss/scu_dsp_jmptab.inc new file mode 100644 index 0000000000..d4a68c9100 --- /dev/null +++ b/waterbox/ss/scu_dsp_jmptab.inc @@ -0,0 +1,4 @@ +{ /* looped=0 */ +JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, }, +{ /* looped=1 */ +JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, JMPInstr, }, diff --git a/waterbox/ss/scu_dsp_misc.cpp b/waterbox/ss/scu_dsp_misc.cpp new file mode 100644 index 0000000000..8a7867ab45 --- /dev/null +++ b/waterbox/ss/scu_dsp_misc.cpp @@ -0,0 +1,69 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* scu_dsp_misc.cpp - SCU DSP Miscellaneous Instructions Emulation +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "ss.h" +#include "scu.h" + +#pragma GCC optimize("Os") + +namespace MDFN_IEN_SS +{ +#include "scu_dsp_common.inc" + +template +static NO_INLINE NO_CLONE void MiscInstr(void) +{ + DSP_InstrPre(); + + // + // END/ENDI + // + if(op == 2 || op == 3) + { + if(op & 0x1) + { + DSP.FlagEnd = true; + SCU_SetInt(SCU_INT_DSP, true); + } + DSP.NextInstr = DSP_DecodeInstruction(0); + DSP.State &= ~DSPS::STATE_MASK_EXECUTE; + DSP.CycleCounter -= DSP_EndCCSubVal; // Break out of execution loop(also remember to handle this case for manual stepping via port writes). + } + else if(op == 0) // BTM + { + if(DSP.LOP) + { + DSP.LOP--; + DSP.PC = DSP.TOP; + } + } + else if(op == 1) // LPS + { + DSP.NextInstr = DSP_DecodeInstruction(DSP.NextInstr >> 32); + } +} + +extern void (*const DSP_MiscFuncTable[2][4])(void) = +{ + #include "scu_dsp_misctab.inc" +}; + +} diff --git a/waterbox/ss/scu_dsp_misctab.inc b/waterbox/ss/scu_dsp_misctab.inc new file mode 100644 index 0000000000..9ea38bb818 --- /dev/null +++ b/waterbox/ss/scu_dsp_misctab.inc @@ -0,0 +1,2 @@ +{ /* looped=0 */ MiscInstr, MiscInstr, MiscInstr, MiscInstr, }, +{ /* looped=1 */ MiscInstr, MiscInstr, MiscInstr, MiscInstr, }, diff --git a/waterbox/ss/scu_dsp_mvi.cpp b/waterbox/ss/scu_dsp_mvi.cpp new file mode 100644 index 0000000000..98e0a4e1fa --- /dev/null +++ b/waterbox/ss/scu_dsp_mvi.cpp @@ -0,0 +1,76 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* scu_dsp_mvi.cpp - SCU DSP MVI Instructions Emulation +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "ss.h" +#include "scu.h" + +#pragma GCC optimize("Os") + +namespace MDFN_IEN_SS +{ +#include "scu_dsp_common.inc" + +template +static NO_INLINE NO_CLONE void MVIInstr(void) +{ + const uint32 instr = DSP_InstrPre(); + uint32 imm; + + if(cond & 0x40) + imm = sign_x_to_s32(19, instr); + else + imm = sign_x_to_s32(25, instr); + + if(DSP_TestCond()) + { + switch(dest) + { + default: + SS_DBG(SS_DBG_WARNING | SS_DBG_SCU, "[SCU] MVI unknown dest 0x%01x --- Instr=0x%08x, Next_Instr=0x%08x, PC=0x%02x\n", dest, instr, (unsigned)(DSP.NextInstr >> 32), DSP.PC); + break; + + case 0x0: + case 0x1: + case 0x2: + case 0x3: + DSP.DataRAM[dest][DSP.CT[dest]] = imm; + DSP.CT[dest] = (DSP.CT[dest] + 1) & 0x3F; + break; + + case 0x4: DSP.RX = imm; break; + case 0x5: DSP.P.T = (int32)imm; break; + case 0x6: DSP.RAO = imm; break; + case 0x7: DSP.WAO = imm; break; + + case 0xA: DSP.LOP = imm & 0x0FFF; break; + case 0xC: DSP.TOP = DSP.PC - 1; DSP.PC = imm & 0xFF; break; + } + } +} + + +extern void (*const DSP_MVIFuncTable[2][16][128])(void) = +{ + #include "scu_dsp_mvitab.inc" +}; + +} + diff --git a/waterbox/ss/scu_dsp_mvitab.inc b/waterbox/ss/scu_dsp_mvitab.inc new file mode 100644 index 0000000000..1614f7e694 --- /dev/null +++ b/waterbox/ss/scu_dsp_mvitab.inc @@ -0,0 +1,100 @@ +{ /* looped=0 */ + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + }, +{ /* looped=1 */ + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + { + MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, MVIInstr, + }, + }, diff --git a/waterbox/ss/sh7095.h b/waterbox/ss/sh7095.h new file mode 100644 index 0000000000..da73ec03b9 --- /dev/null +++ b/waterbox/ss/sh7095.h @@ -0,0 +1,534 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* sh7095.h: +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SH7095_H +#define __MDFN_SH7095_H + +class SH7095 final +{ + public: + + SH7095(const char* const name_arg, const unsigned dma_event_id_arg, uint8 (*exivecfn_arg)(void)) MDFN_COLD; + ~SH7095() MDFN_COLD; + + void Init(void) MDFN_COLD; + + void ForceInternalEventUpdates(void); + void AdjustTS(int32 delta, bool force_set = false); + + void TruePowerOn(void) MDFN_COLD; + void Reset(bool power_on_reset, bool from_internal_wdt = false) MDFN_COLD; + void SetNMI(bool level); + void SetIRL(unsigned level); + void SetMD5(bool level); + + void SetFTI(bool state); + void SetFTCI(bool state); + + INLINE void SetExtHalt(bool state) + { + ExtHalt = state; + + if(ExtHalt) + SetPEX(PEX_PSEUDO_EXTHALT); // Only SetPEX() here, ClearPEX() is called in the pseudo exception handling code as necessary. + } + + template + void Step(void); + + + //private: + uint32 R[16]; + uint32 PC; + + // Control registers + union + { + struct + { + uint32 SR; + uint32 GBR; + uint32 VBR; + }; + uint32 CtrlRegs[3]; + }; + + sscpu_timestamp_t timestamp; + sscpu_timestamp_t MA_until; + sscpu_timestamp_t MM_until; + sscpu_timestamp_t write_finish_timestamp; +#if 0 + sscpu_timestamp_t WB_until[16]; +#endif + + INLINE void SetT(bool new_value) { SR &= ~1; SR |= new_value; } + INLINE bool GetT(void) { return SR & 1; } + + INLINE bool GetS(void) { return (bool)(SR & 0x002); } + INLINE bool GetQ(void) { return (bool)(SR & 0x100); } + INLINE bool GetM(void) { return (bool)(SR & 0x200); } + INLINE void SetQ(bool new_q) { SR = (SR &~ 0x100) | (new_q << 8); } + INLINE void SetM(bool new_m) { SR = (SR &~ 0x200) | (new_m << 9); } + + // System registers + union + { + struct + { + uint32 MACH; + uint32 MACL; + uint32 PR; + }; + uint32 SysRegs[3]; + }; + + INLINE uint64 GetMAC64(void) { return MACL | ((uint64)MACH << 32); } + INLINE void SetMAC64(uint64 nv) { MACL = nv; MACH = nv >> 32; } + + enum // must be in range of 0 ... 7 + { + PEX_POWERON = 0, + PEX_RESET = 1, + PEX_CPUADDR = 2, + PEX_DMAADDR = 3, + PEX_INT = 4, + PEX_NMI = 5, + PEX_PSEUDO_DMABURST = 6, + PEX_PSEUDO_EXTHALT = 7 + }; + enum { EPENDING_PEXBITS_SHIFT = 16 }; + enum { EPENDING_OP_OR = 0xFF000000 }; + + uint32 EPending; + + INLINE void SetPEX(const unsigned which) + { + EPending |= (1U << (which + EPENDING_PEXBITS_SHIFT)); + EPending |= EPENDING_OP_OR; + } + + INLINE void ClearPEX(const unsigned which) + { + EPending &= ~(1U << (which + EPENDING_PEXBITS_SHIFT)); + + if(!(EPending & (0xFF << EPENDING_PEXBITS_SHIFT))) + EPending = 0; + } + + uint32 Pipe_ID; + uint32 Pipe_IF; + + enum + { + EXCEPTION_POWERON = 0,// Power-on + EXCEPTION_RESET, // "Manual" reset + EXCEPTION_ILLINSTR, // General illegal instruction + EXCEPTION_ILLSLOT, // Slot illegal instruction + EXCEPTION_CPUADDR, // CPU address error + EXCEPTION_DMAADDR, // DMA Address error + EXCEPTION_NMI, // NMI + EXCEPTION_BREAK, // User break + EXCEPTION_TRAP, // Trap instruction + EXCEPTION_INT, // Interrupt + }; + + enum + { + VECNUM_POWERON = 0, // Power-on + VECNUM_RESET = 2, // "Manual" reset + VECNUM_ILLINSTR = 4, // General illegal instruction + VECNUM_ILLSLOT = 6, // Slot illegal instruction + VECNUM_CPUADDR = 9, // CPU address error + VECNUM_DMAADDR = 10, // DMA Address error + VECNUM_NMI = 11, // NMI + VECNUM_BREAK = 12, // User break + + VECNUM_TRAP_BASE = 32, // Trap instruction + VECNUM_INT_BASE = 64, // Interrupt + }; + + enum + { + EPENDING_IVECNUM_SHIFT = 8, // 8 bits + EPENDING_E_SHIFT = 16, // 8 bits + EPENDING_IPRIOLEV_SHIFT = 28 // 4 bits + }; + + template + uint32 Exception(const unsigned exnum, const unsigned vecnum); + + // + // + // + uint32 IBuffer; + + uint32 (MDFN_FASTCALL *MRFPI[8])(uint32 A); + + uint8 (MDFN_FASTCALL *MRFP8[8])(uint32 A); + uint16 (MDFN_FASTCALL *MRFP16[8])(uint32 A); + uint32 (MDFN_FASTCALL *MRFP32[8])(uint32 A); + + void (MDFN_FASTCALL *MWFP8[8])(uint32 A, uint8); + void (MDFN_FASTCALL *MWFP16[8])(uint32 A, uint16); + void (MDFN_FASTCALL *MWFP32[8])(uint32 A, uint32); + + // + // + // Cache: + // + // + struct + { + // Rather than have separate validity bits, we're putting an INvalidity bit(invalid when =1) + // in the upper bit of the Tag variables. + uint32 Tag[4]; + uint8 LRU; + alignas(4) uint8 Data[4][16]; + } Cache[64]; + + uint8 CCR; + + void SetCCR(uint8 V); + enum { CCR_CE = 0x01 }; // Cache Enable + enum { CCR_ID = 0x02 }; // Instruction Replacement Disable + enum { CCR_OD = 0x04 }; // Data Replacement Disable + enum { CCR_TW = 0x08 }; // Two-Way Mode + enum { CCR_CP = 0x10 }; // Cache Purge + enum { CCR_W0 = 0x40 }; // + enum { CCR_W1 = 0x80 }; // + void AssocPurge(const uint32 A); + + template + void Write_UpdateCache(uint32 A, T V); + // + // End cache stuff + // + + // + // + // Interrupt controller registers and related state + // + // + void INTC_Reset(void) MDFN_COLD; + + bool NMILevel; + uint8 IRL; + + uint16 IPRA; + uint16 IPRB; + uint16 VCRWDT; + uint16 VCRA; + uint16 VCRB; + uint16 VCRC; + uint16 VCRD; + uint16 ICR; + + // + // + // + uint16 BCR1, BCR1M; + + // + // + // + uint8 SBYCR; + bool Standby; + + // + // + // Free-running timer registers and related state + // + // + struct + { + sscpu_timestamp_t lastts; // Internal timestamp related. + + bool FTI; + bool FTCI; + + uint16 FRC; + uint16 OCR[2]; + uint16 FICR; + uint8 TIER; + uint8 FTCSR; + uint8 FTCSRM; // Bits set to 1 like FTCSR, but unconditionally reset all bits to 0 on FTCSR read. + uint8 TCR; + uint8 TOCR; + uint8 RW_Temp; + } FRT; + + void FRT_Reset(void) MDFN_COLD; + + void FRT_CheckOCR(void); + void FRT_ClockFRC(void); + + void FRT_WDT_Update(void); + void FRT_WDT_Recalc_NET(void); + uint32 FRT_WDT_ClockDivider; + sscpu_timestamp_t FRT_WDT_NextTS; + + // + // + // Watchdog timer registers and related state. + // + // + struct + { + uint8 WTCSR; // We don't let a CPU program set bit3 to 1, but we do set bit3 to 1 as part of the standby NMI recovery process(for internal use). + uint8 WTCSRM; + uint8 WTCNT; + uint8 RSTCSR; + uint8 RSTCSRM; + } WDT; + + void WDT_Reset(bool from_internal_wdt) MDFN_COLD; // Reset-reset only, NOT standby reset! + void WDT_StandbyReset(void) MDFN_COLD; + + // + // DMA unit registers and related state + // + bool DMA_RunCond(unsigned ch); + bool DMA_InBurst(void); + void DMA_CheckEnterBurstHack(void); + void DMA_DoTransfer(unsigned ch); + sscpu_timestamp_t DMA_Update(sscpu_timestamp_t); // Takes/return external timestamp + void DMA_StartSG(void); + + const unsigned event_id_dma; + sscpu_timestamp_t dma_lastts; // External SH7095_mem_timestamp related. + + int32 DMA_ClockCounter; + int32 DMA_SGCounter; // When negative, smaller granularity scheduling for DMA_Update() + bool DMA_RoundRobinRockinBoppin; + + struct + { + uint32 SAR; + uint32 DAR; + uint32 TCR; // 24-bit, value of 0 = 2^24 tranfers + uint16 CHCR; + uint16 CHCRM; + uint8 VCR; + uint8 DRCR; + } DMACH[2]; + + uint8 DMAOR; + uint8 DMAORM; + + + // + // + // Division unit registers and related state + // + // + void DIVU_S32_S32(void); + void DIVU_S64_S32(void); + + sscpu_timestamp_t divide_finish_timestamp; + uint32 DVSR; + uint32 DVDNT; + uint32 DVDNTH; + uint32 DVDNTL; + uint32 DVDNTH_Shadow; + uint32 DVDNTL_Shadow; + uint16 VCRDIV; + uint8 DVCR; + +#if 0 + struct + { + uint8 SMR; // Mode + uint8 BRR; // Bit rate + uint8 SCR; // Control + uint8 TDR; // Transmit data + uint8 SSR; // Status + uint8 RDR; // Receive data + + uint8 RSR; // Receive shift register + uint8 TSR; // Transmit shift register + } SCI; +#endif + + const char* const cpu_name; + + // + // + // + bool ExtHalt; + + uint8 (*const ExIVecFetch)(void); + uint8 GetPendingInt(uint8*); + void RecalcPendingIntPEX(void); + + template + INLINE void FetchIF(bool ForceIBufferFill); + + template + void DoIDIF_Real(void); + + template + T ExtBusRead(uint32 A); + + template + void ExtBusWrite(uint32 A, T V); + + template + void OnChipRegWrite(uint32 A, uint32 V); + + template + T OnChipRegRead(uint32 A); + + template + T MemReadRT(uint32 A); + + template + T MemRead(uint32 A); + + template + void MemWriteRT(uint32 A, T V); + + template + void MemWrite(uint32 A, T V); + + + template + INLINE void Branch(uint32 target); + + template + INLINE void CondRelBranch(bool cond, uint32 disp); + + + template + INLINE void UCDelayBranch(uint32 target); + + template + INLINE void UCRelDelayBranch(uint32 disp); + + + // + // + // + // + // + // + public: + + enum + { + // GSREG_PC_ID and GSREG_PC_IF are only valid when Step() was called most recently(but they may be invalid + // for a while after , too...). + GSREG_PC_ID = 0, + GSREG_PC_IF, + + GSREG_PID, + GSREG_PIF, + + GSREG_EP, + + GSREG_RPC, + + GSREG_R0, GSREG_R1, GSREG_R2, GSREG_R3, GSREG_R4, GSREG_R5, GSREG_R6, GSREG_R7, + GSREG_R8, GSREG_R9, GSREG_R10, GSREG_R11, GSREG_R12, GSREG_R13, GSREG_R14, GSREG_R15, + + GSREG_SR, + GSREG_GBR, + GSREG_VBR, + + GSREG_MACH, + GSREG_MACL, + GSREG_PR, + // + // + // + GSREG_NMIL, + GSREG_IRL, + GSREG_IPRA, + GSREG_IPRB, + GSREG_VCRWDT, + GSREG_VCRA, + GSREG_VCRB, + GSREG_VCRC, + GSREG_VCRD, + GSREG_ICR, + // + // + // + GSREG_DVSR, + GSREG_DVDNT, + GSREG_DVDNTH, + GSREG_DVDNTL, + GSREG_DVDNTHS, + GSREG_DVDNTLS, + GSREG_VCRDIV, + GSREG_DVCR, + + // + // + // + GSREG_WTCSR, + GSREG_WTCSRM, + GSREG_WTCNT, + GSREG_RSTCSR, + GSREG_RSTCSRM, + // + // + // + GSREG_DMAOR, + GSREG_DMAORM, + + GSREG_DMA0_SAR, + GSREG_DMA0_DAR, + GSREG_DMA0_TCR, + GSREG_DMA0_CHCR, + GSREG_DMA0_CHCRM, + GSREG_DMA0_VCR, + GSREG_DMA0_DRCR, + + GSREG_DMA1_SAR, + GSREG_DMA1_DAR, + GSREG_DMA1_TCR, + GSREG_DMA1_CHCR, + GSREG_DMA1_CHCRM, + GSREG_DMA1_VCR, + GSREG_DMA1_DRCR, + + GSREG_FRC, + GSREG_OCR0, + GSREG_OCR1, + GSREG_FICR, + GSREG_TIER, + GSREG_FTCSR, + GSREG_FTCSRM, + GSREG_TCR, + GSREG_TOCR, + GSREG_RWT, + }; + + uint32 GetRegister(const unsigned id, char* const special, const uint32 special_len); + void SetRegister(const unsigned id, const uint32 value) MDFN_COLD; + + void CheckRWBreakpoints(void (*MRead)(unsigned len, uint32 addr), void (*MWrite)(unsigned len, uint32 addr)) const; + static void Disassemble(const uint16 instr, const uint32 PC, char* buffer, uint16 (*DisPeek16)(uint32), uint32 (*DisPeek32)(uint32)); + private: + uint32 PC_IF, PC_ID; // Debug-related variables. +}; + +#endif diff --git a/waterbox/ss/sh7095.inc b/waterbox/ss/sh7095.inc new file mode 100644 index 0000000000..53ac2f5a78 --- /dev/null +++ b/waterbox/ss/sh7095.inc @@ -0,0 +1,6736 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* sh7095.inc - Hitachi SH7095 Emulation +** Copyright (C) 2015-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +/* + Emulation implementation notes/deficiencies: + Overall timing is extremely approximate. + + DMA timing is very rough. DMA burst mode probably isn't handled totally correctly, especially in + relation to the other CPU and the SCU(is DMA burst mode even legal on the Saturn?). + + Misaligned memory accesses(that cause address errors) aren't emulated correctly(for + future reference, there's a difference between how cache versus external bus is accessed + for misaligned addresses, and perhaps a difference between 32-bit and 16-bit spaces as + defined by the BSC too; and then there's misaligned OPM register access semantics...). + + Address errors occur one instruction too soon. + + SLEEP instruction, standby mode, and DMA burst stalls are handled by thoroughly (ab)using the + IF/ID pipeline emulation and opcode dispatch mechanism. + + Individual module clocking disabling functionality of SBYCR isn't handled. + + Interrupts are typically delayed by one instruction, but when the interrupt is handled, + the current interrupt state is used instead of the previous interrupt state. + This can result in the exception-handling pseudo-op code being called when there's + no "current" exception to process, which is a quasi-error condition; there's code to log + this condition and recover from it. An SH-2 code sequence that can cause this condition + if there's currently a pending/unacked interrupt: + + + This cooouuuld turn out to be a problem, and if it does, it can be fixed by having two interrupt-pending variables, + with one being copied to the other in DoIDIF(). + + Instruction fetches don't go through the cache emulation, for performance reasons(getting the instruction fetches timed right + versus the instruction data read/write would be critical, to avoid causing inaccurate cache miss patterns which could cause code + to run slower than on the real thing, which is arguably worse than having it run faster). + + SCI, UBC, and BSC are mostly unemulated. +*/ + +// Address error exception order, sleep versus exceptions. + +/* + TODO: PC-relative addressing, uses instruction or data fetches? +*/ + +/* + TODO: Make sure RecalcPendingIntPEX() is called in all places it needs to be called(which is arguably too many...). +*/ + +/* + TODO: Penalize slave CPU external bus access if we ever figure out a solution to the timestamp vs mem_timestamp problem that doesn't murder + performance. +*/ + +// Shouldn't enable instruction cache emulation until we resolve timestamp vs mem_timestamp issues +// in regards to bus contention and time sharing, or else emulated dual-CPU programs will run slower +// than they should and probably glitch out(and also until 5GHz desktop CPUs are the norm ;)). +//#define SH7095_EMULATE_ICACHE + +#ifdef MSB_FIRST + #define NE32ASU8_IDX_ADJ(T, idx) (idx) +#else + #define NE32ASU8_IDX_ADJ(T, idx) ( ((idx) & ~(sizeof(T) - 1)) ^ (4 - (sizeof(T))) ) +#endif + +SH7095::SH7095(const char* const name_arg, const unsigned event_id_dma_arg, uint8 (*exivecfn_arg)(void)) : event_id_dma(event_id_dma_arg), cpu_name(name_arg), ExIVecFetch(exivecfn_arg) +{ + Init(); +} + +template +static NO_INLINE MDFN_FASTCALL T C_MemReadRT(uint32 A); + +template +static NO_INLINE MDFN_FASTCALL void C_MemWriteRT(uint32 A, T V); + +void SH7095::Init(void) +{ + #define MAHL_P(w, region) { \ + MRFP8[region] = C_MemReadRT; \ + MRFP16[region] = C_MemReadRT; \ + MRFP32[region] = C_MemReadRT; \ + MRFPI[region] = C_MemReadRT; \ + MWFP8[region] = C_MemWriteRT; \ + MWFP16[region] = C_MemWriteRT; \ + MWFP32[region] = C_MemWriteRT; \ + } + + #define MAHL(region) \ + if(this == &CPU[0]) \ + { MAHL_P(0, region) } \ + else \ + { MAHL_P(1, region) } + + MAHL(1) + MAHL(2) + MAHL(3) + MAHL(4) + MAHL(5) + MAHL(6) + MAHL(7) + + #undef MAHL + #undef MAHL_P + // + // + // + + // + // Initialize variables that won't be initialized elsewhere since they reflect the overall emulator timing state, or are cache variables + // for signal inputs. + // + timestamp = 0; + write_finish_timestamp = 0; + divide_finish_timestamp = 0; + FRT.lastts = 0; + dma_lastts = 0; + + FRT.FTI = false; + FRT.FTCI = false; + IRL = 0; + NMILevel = false; + BCR1 &= 0x7FFF; //MD5Level = false; + ExtHalt = false; + + TruePowerOn(); +} + +SH7095::~SH7095() +{ + +} + +void SH7095::AdjustTS(int32 delta, bool force_set) +{ + if(force_set) + { + timestamp = delta; + + MA_until = delta; + MM_until = delta; + +#if 0 + for(unsigned i = 0; i < 16; i++) + WB_until[i] = delta; +#endif + + write_finish_timestamp = delta; + divide_finish_timestamp = delta; + + FRT.lastts = delta; + dma_lastts = delta; + } + else + { + if(!(timestamp & 0x40000000)) + timestamp += delta; + + if(!(MA_until & 0x40000000)) + MA_until += delta; + + if(!(MM_until & 0x40000000)) + MM_until += delta; + +#if 0 + for(unsigned i = 0; i < 16; i++) + { + if(!(WB_until[i] & 0x40000000)) + WB_until[i] += delta; + } +#endif + + if(!(write_finish_timestamp & 0x40000000)) + write_finish_timestamp += delta; + + if(!(divide_finish_timestamp & 0x40000000)) + divide_finish_timestamp += delta; + + FRT.lastts += delta; + dma_lastts += delta; + } + + FRT_WDT_ClockDivider &= 0x00FFFFFF; + FRT_WDT_Recalc_NET(); +} + +// +// Initialize everything for determinism, especially state left "undefined" by reset/power exception handling. +// +void SH7095::TruePowerOn(void) +{ + for(unsigned i = 0; i < 16; i++) + R[i] = 0; + +#if 0 + for(unsigned i = 0; i < 16; i++) + WB_until[i] = 0; +#endif + + PC = 0; + + SR = 0; + GBR = 0; + VBR = 0; + + MACH = 0; + MACL = 0; + PR = 0; + + EPending = 0; + Pipe_ID = 0; + Pipe_IF = 0; + + PC_IF = PC_ID = 0; + + memset(Cache, 0, sizeof(Cache)); + CCR = 0; + + MA_until = 0; + MM_until = 0; + // + // + // + IPRA = 0; + IPRB = 0; + VCRWDT = 0; + VCRA = 0; + VCRB = 0; + VCRC = 0; + VCRD = 0; + ICR = 0; + + // + // + // + FRT.FRC = 0; + FRT.OCR[0] = FRT.OCR[1] = 0; + FRT.FICR = 0; + FRT.TIER = 0; + FRT.FTCSR = 0; + FRT.FTCSRM = 0; + FRT.TCR = 0; + FRT.TOCR = 0; + FRT.RW_Temp = 0; + + FRT_WDT_ClockDivider = 0; + + WDT.WTCSR = 0; + WDT.WTCSRM = 0; + WDT.WTCNT = 0; + WDT.RSTCSR = 0; + WDT.RSTCSRM = 0; + + FRT_WDT_Recalc_NET(); + // + // + // + DMA_ClockCounter = 0; + DMA_SGCounter = 0; + DMA_RoundRobinRockinBoppin = 0; + memset(DMACH, 0, sizeof(DMACH)); + DMAOR = 0; + DMAORM = 0; + // + // + // + DVSR = 0; + DVDNT = 0; + DVDNTH = 0; + DVDNTL = 0; + DVDNTH_Shadow = 0; + DVDNTL_Shadow = 0; + VCRDIV = 0; + DVCR = 0; + // + // + // +} + + + + + +// de=1, dme=1, te=0, nmif=0, ae=0 +INLINE bool SH7095::DMA_RunCond(unsigned ch) +{ + return ((DMAOR & 0x07) == 0x01) && ((DMACH[ch].CHCR & 0x03) == 0x01); +} + +bool SH7095::DMA_InBurst(void) +{ + if((DMAOR & 0x08) && DMA_RunCond(0) && DMA_RunCond(1)) + return ((DMACH[0].CHCR | DMACH[1].CHCR) & 0x10); + + if(DMA_RunCond(0)) + return (DMACH[0].CHCR & 0x10); + else if(DMA_RunCond(1)) + return (DMACH[1].CHCR & 0x10); + + return false; +} + +void SH7095::DMA_CheckEnterBurstHack(void) +{ + if(DMA_InBurst()) + SetPEX(PEX_PSEUDO_DMABURST); +} + + +// RecalcPendingIntPEX() will be called higher up, at the end of DMA_Update() +// +// Call SH7095_Bus* directly instead of through ExtBusRead, at least until we can work +// out all this disparate timestamp nonsense properly(maybe around the time we add proper bus controller emulation? ;)). +// +INLINE void SH7095::DMA_DoTransfer(unsigned ch) +{ + static const int8 ainc[3][4] = + { + { 0, 1, -1, -1 }, + { 0, 2, -2, -2 }, + { 0, 4, -4, -4 }, + }; + const unsigned ts = (DMACH[ch].CHCR >> 10) & 3; + const unsigned sm = (DMACH[ch].CHCR >> 12) & 3; + const unsigned dm = (DMACH[ch].CHCR >> 14) & 3; + uint32 sar = DMACH[ch].SAR; + uint32 dar = DMACH[ch].DAR; + uint32 tcr = DMACH[ch].TCR; + + switch(ts) + { + case 0x00: // 8-bit + { + uint8 buffer; + + buffer = SH7095_BusRead(sar & 0x07FFFFFF, false, &DMA_ClockCounter); + SH7095_BusWrite(dar & 0x07FFFFFF, buffer, false, &DMA_ClockCounter); + + sar += ainc[0][sm]; + dar += ainc[0][dm]; + tcr = (tcr - 1) & 0xFFFFFF; + } + break; + + case 0x01: // 16-bit + { + uint16 buffer; + + buffer = SH7095_BusRead(sar & 0x07FFFFFE, false, &DMA_ClockCounter); + SH7095_BusWrite(dar & 0x07FFFFFE, buffer, false, &DMA_ClockCounter); + + if(MDFN_UNLIKELY((sar | dar) & 0x1)) + { + DMAOR |= 4; + DMAORM |= 4; + SetPEX(PEX_DMAADDR); + } + + sar += ainc[1][sm]; + dar += ainc[1][dm]; + tcr = (tcr - 1) & 0xFFFFFF; + } + break; + + case 0x02: // 32-bit + { + uint32 buffer; + + buffer = SH7095_BusRead(sar & 0x07FFFFFC, false, &DMA_ClockCounter); + SH7095_BusWrite(dar & 0x07FFFFFC, buffer, false, &DMA_ClockCounter); + + if(MDFN_UNLIKELY((sar | dar) & 0x3)) + { + DMAOR |= 4; + DMAORM |= 4; + SetPEX(PEX_DMAADDR); + } + + sar += ainc[2][sm]; + dar += ainc[2][dm]; + tcr = (tcr - 1) & 0xFFFFFF; + } + break; + + case 0x03: // 4 * 32-bit, a mess... + { + uint32 buffer[4]; + + if(MDFN_UNLIKELY((sar | dar) & 0x3)) + { + DMAOR |= 4; + DMAORM |= 4; + SetPEX(PEX_DMAADDR); + } + + for(unsigned i = 0; i < 4; i++) + { + buffer[i] = SH7095_BusRead((sar + (i << 2)) & 0x07FFFFFC, (bool)i, &DMA_ClockCounter); + } + + sar += 0x10; + + for(unsigned i = 0; i < 4; i++) + { + SH7095_BusWrite(dar & 0x07FFFFFC, buffer[i], false, &DMA_ClockCounter); + dar += ainc[2][dm]; + tcr = (tcr - 1) & 0xFFFFFF; + if(MDFN_UNLIKELY(!tcr)) + break; + } + } + break; + } + + if(!tcr) + { + SS_DBGTI(SS_DBG_SH2, "[%s] DMA %d finished.", cpu_name, ch); + + DMACH[ch].CHCR |= 2; + DMACH[ch].CHCRM |= 2; + } + + DMACH[ch].SAR = sar; + DMACH[ch].DAR = dar; + DMACH[ch].TCR = tcr; +} + +sscpu_timestamp_t SH7095::DMA_Update(sscpu_timestamp_t et) +{ + if(MDFN_UNLIKELY(et < dma_lastts)) + { + // et < dma_lastts may happen...look into it. + if(et < dma_lastts) + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] DMA_Update called with et(%u) < dma_lastts(%u).\n", cpu_name, et, dma_lastts); + } + else if(MDFN_UNLIKELY(ExtHalt)) + { + dma_lastts = et; + return dma_lastts + 128; + } + else + { + uint32 clocks = et - dma_lastts; + dma_lastts = et; + + // + // + // + bool rr = DMA_RoundRobinRockinBoppin; + + DMA_ClockCounter += clocks; + DMA_SGCounter += clocks; + + if(DMAOR & 0x08) // Round robin + { + while(DMA_RunCond(0) || DMA_RunCond(1)) + { + if(DMA_RunCond(rr)) + { + if(DMA_ClockCounter <= 0) + goto TimeOver; + + DMA_DoTransfer(rr); + } + rr = !rr; + } + } + else // ch 0 > ch1 + { + while(DMA_RunCond(0)) + { + if(DMA_ClockCounter <= 0) + goto TimeOver; + + DMA_DoTransfer(0); + } + + while(DMA_RunCond(1)) + { + if(DMA_ClockCounter <= 0) + goto TimeOver; + + DMA_DoTransfer(1); + } + } + // + // + // + TimeOver:; + + DMA_RoundRobinRockinBoppin = rr; + DMA_ClockCounter = std::min(DMA_ClockCounter, 128); + DMA_SGCounter = std::min(DMA_SGCounter, 0); + + DMA_CheckEnterBurstHack(); + RecalcPendingIntPEX(); // TODO: conditionalize(or make RecalcPendingIntPEX() less expensive). + } + + return dma_lastts + ((DMA_SGCounter < 0) ? 32 : 128); +} + +// DMA_StartSG() must be paired with a DMA_Update(SH7095_mem_timestamp) somewhere before. +void SH7095::DMA_StartSG(void) +{ + DMA_SGCounter = DMA_ClockCounter - 128; + SS_SetEventNT(&events[event_id_dma], SH7095_mem_timestamp + 32); // fixed + 32, don't evaluate DMA_SGCounter here. + + DMA_CheckEnterBurstHack(); +} + + +// +// +// +void NO_INLINE SH7095::FRT_Reset(void) +{ + FRT.FRC = 0x00; + FRT.OCR[0] = FRT.OCR[1] = 0x00; + FRT.FICR = 0x00; + FRT.TIER = 0x00; + FRT.FTCSR = 0x00; + FRT.FTCSRM = 0x00; + FRT.TCR = 0x00; + FRT.TOCR = 0x00; + FRT.RW_Temp = 0x00; // Reset or not? + + FRT_WDT_Recalc_NET(); + RecalcPendingIntPEX(); +} + +INLINE void SH7095::FRT_CheckOCR(void) +{ + if(FRT.FRC == FRT.OCR[0]) // OCRA + { + if(FRT.FTCSR & 0x0001) + FRT.FRC = 0; + + if(!(FRT.FTCSR & 0x08)) + { + FRT.FTCSR |= 0x08; + FRT.FTCSRM |= 0x08; + RecalcPendingIntPEX(); + } + } + + if(FRT.FRC == FRT.OCR[1]) // OCRB + { + if(!(FRT.FTCSR & 0x04)) + { + FRT.FTCSR |= 0x04; + FRT.FTCSRM |= 0x04; + RecalcPendingIntPEX(); + } + } +} + +INLINE void SH7095::FRT_ClockFRC(void) +{ + FRT.FRC++; + if(!FRT.FRC) + { + if(!(FRT.FTCSR & 0x02)) + { + FRT.FTCSR |= 0x02; // OVF + FRT.FTCSRM |= 0x02; + RecalcPendingIntPEX(); + } + } + // + // + // + FRT_CheckOCR(); +} + + +static const uint8 wdt_cstab[8] = { 1, /**/ 6, 7, 8, 9, 10, /**/ 12, 13 }; + +// +// Call after: +// WDT.WTCSR, WDT.WTCNT, FRT.TCR, FRT.OCR[0], FRT.OCR[1] changes due to register write or similar. +// timestamp >= FRT_WDT_NextTS (after call to FRT_WDT_Update()) +// +void SH7095::FRT_WDT_Recalc_NET(void) +{ + int32 rt = 1000; + + if((FRT.TCR & 0x3) != 0x3) // when == 3, count on rising edge of external clock(not handled here). + { + const uint32 frt_clockshift = 3 + ((FRT.TCR & 0x3) << 1); // /8, /32, /128, count at falling edge + int32 next_frc = 0x10000; + + if(FRT.OCR[0] > FRT.FRC) + next_frc = FRT.OCR[0]; + + if(FRT.OCR[1] > FRT.FRC) + next_frc = FRT.OCR[1]; + + rt = ((next_frc - FRT.FRC) << frt_clockshift) - (FRT_WDT_ClockDivider & ((1 << frt_clockshift) - 1)); + } + + if(WDT.WTCSR & 0x28) // TME(0x20) and internal use standby NMI recover bit(0x08) + { + const unsigned wdt_clockshift = wdt_cstab[WDT.WTCSR & 0x7]; + int32 wdt_rt; + + wdt_rt = ((0x100 - WDT.WTCNT) << wdt_clockshift) - (FRT_WDT_ClockDivider & ((1 << wdt_clockshift) - 1)); + rt = std::min(rt, wdt_rt); + } + + assert(rt > 0); + + FRT_WDT_NextTS = timestamp + rt; +} + +void SH7095::FRT_WDT_Update(void) +{ + assert(timestamp >= FRT.lastts); + + uint32 clocks = timestamp - FRT.lastts; + + //if(clocks >= 1000) + // printf("%u, %d %d\n", clocks, timestamp, FRT.lastts); + //assert(clocks < 1000); + + FRT.lastts = timestamp; + + // + // + // + const uint32 PreAddCD = FRT_WDT_ClockDivider; + FRT_WDT_ClockDivider += clocks; + + if((FRT.TCR & 0x3) != 0x3) // when == 3, count on rising edge of external clock(not handled here). + { + const uint32 frt_clockshift = 3 + ((FRT.TCR & 0x3) << 1); // /8, /32, /128, count at falling edge + uint32 divided_clocks = (FRT_WDT_ClockDivider >> frt_clockshift) - (PreAddCD >> frt_clockshift); + + while(divided_clocks-- > 0) + { + FRT_ClockFRC(); + } + } + + // WDT: + if(WDT.WTCSR & 0x28) // TME(0x20) and internal use standby NMI recover bit(0x08) + { + const unsigned wdt_clockshift = wdt_cstab[WDT.WTCSR & 0x7]; + uint32 divided_clocks = (FRT_WDT_ClockDivider >> wdt_clockshift) - (PreAddCD >> wdt_clockshift); + uint32 tmp_counter = WDT.WTCNT; + + tmp_counter += divided_clocks; + WDT.WTCNT = tmp_counter; + // + // + if(MDFN_UNLIKELY(tmp_counter >= 0x100)) + { + if(MDFN_UNLIKELY(WDT.WTCSR & 0x08)) + { + Standby = false; + WDT.WTCNT = 0x00; + WDT.WTCSR &= ~0x08; + } + else if(MDFN_UNLIKELY(WDT.WTCSR & 0x40)) // Watchdog timer mode + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] WDT overflow in WDT mode!\n", cpu_name); + WDT.RSTCSR |= 0x80; + + WDT.WTCNT = 0; + WDT.WTCSR = 0; + + if(WDT.RSTCSR & 0x40) // RSTE + Reset(!(WDT.RSTCSR & 0x20), true); + } + else + { + if(!(WDT.WTCSR & 0x80)) + { + WDT.WTCSR |= 0x80; + WDT.WTCSRM |= 0x80; + RecalcPendingIntPEX(); + } + } + } + } +} + +void SH7095::SetFTI(bool state) +{ + FRT_WDT_Update(); + // + // + bool prev = FRT.FTI; + FRT.FTI = state; + + if((prev ^ state) & (prev ^ (FRT.TCR >> 7))) + { + SS_DBGTI(SS_DBG_SH2, "[%s] FTI input capture triggered.", cpu_name); + if((FRT.FTCSR & 0x80) || (FRT.FTCSRM & 0x80)) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] FTI Input capture interrupt while software not ready? FTCSR=0x%02x, FTCSRM=0x%02x\n", cpu_name, FRT.FTCSR, FRT.FTCSRM); + } + + FRT.FICR = FRT.FRC; + if(!(FRT.FTCSR & 0x80)) + { + FRT.FTCSR |= 0x80; + FRT.FTCSRM |= 0x80; + } + RecalcPendingIntPEX(); + } +} + +void SH7095::SetFTCI(bool state) +{ + bool prev = FRT.FTCI; + FRT.FTCI = state; + + if((FRT.TCR & 0x3) == 0x3) + { + if(!prev && state) + FRT_ClockFRC(); + } +} + +void NO_INLINE SH7095::WDT_Reset(bool from_internal_wdt) +{ + WDT.WTCSR = 0x00; + WDT.WTCSRM = 0x00; + + WDT.WTCNT = 0x00; + + if(!from_internal_wdt) + { + WDT.RSTCSR = 0x00; + WDT.RSTCSRM = 0x00; + } + + FRT_WDT_Recalc_NET(); + RecalcPendingIntPEX(); +} + +void NO_INLINE SH7095::WDT_StandbyReset(void) +{ + WDT.WTCSR &= 0x1F; + WDT.WTCSRM &= 0x1F; + + WDT.RSTCSR = 0x00; + WDT.RSTCSRM = 0x00; + + FRT_WDT_Recalc_NET(); + RecalcPendingIntPEX(); +} + +// +// +// +// +// + +static INLINE uint64 DIVU64_Partial(uint64 dividend, uint32 divisor) +{ + bool M, Q; + + Q = dividend >> 63; + M = divisor >> 31; + + for(unsigned x = 0; x < 3; x++) + { + if(!(Q ^ M)) + dividend -= (uint64)divisor << 32; + else + dividend += (uint64)divisor << 32; + + Q = dividend >> 63; + dividend <<= 1; + dividend |= Q ^ 1 ^ M; + } + + return dividend; +} + +INLINE void SH7095::DIVU_S32_S32(void) +{ + if(!DVSR) + { + divide_finish_timestamp = MA_until + 2 + 6; + + DVCR |= 1; + RecalcPendingIntPEX(); + + DVDNTH = (int32)DVDNT >> 29; + + if(!(DVCR & 2)) + DVDNT = DVDNTL = 0x7FFFFFFF + ((int32)DVDNT < 0); + else + DVDNT = DVDNTL = (DVDNT << 3) | (((int32)~DVDNT >> 31) & 7); + } + else + { + divide_finish_timestamp = MA_until + 1 + 39; + + if(DVSR == 0xFFFFFFFF && DVDNTL == 0x80000000) + { + DVDNT = DVDNTL = 0x80000000; + DVDNTH = 0; + } + else + { + DVDNTH = (int32)DVDNTL % (int32)DVSR; + DVDNT = DVDNTL = (int32)DVDNTL / (int32)DVSR; + } + } + DVDNTH_Shadow = DVDNTH; + DVDNTL_Shadow = DVDNTL; +} + +INLINE void SH7095::DIVU_S64_S32(void) +{ + const int32 divisor = DVSR; + const int64 dividend = ((int64)DVDNTH << 32) | DVDNTL; + int64 quotient; + + if(!divisor) + goto Overflow; + + if((uint64)dividend == (1ULL << 63) && (uint32)divisor == ~(uint32)0) + goto Overflow; + + quotient = dividend / divisor; + + //printf("Divisor=%08x, Dividend=%016llx, Quotient=%016llx\n", divisor, dividend, quotient); + + if(quotient == 2147483648LL && divisor < 0 && (dividend % divisor) == 0) // Ugh, maybe we should just implement it properly the long way... + goto SkipOVCheck; + + if(quotient < -2147483647LL || quotient > 2147483647LL) + { + Overflow: + divide_finish_timestamp = timestamp + 6; + DVCR |= 1; + RecalcPendingIntPEX(); + // + uint64 tmp = DIVU64_Partial(dividend, divisor); + DVDNTH = tmp >> 32; + + if(DVCR & 2) + DVDNT = DVDNTL = tmp; + else + DVDNT = DVDNTL = 0x7FFFFFFF + ((int32)((dividend >> 32) ^ divisor) < 0); + } + else + { + SkipOVCheck: + divide_finish_timestamp = timestamp + 39; + DVDNTH = dividend % divisor; + DVDNT = DVDNTL = quotient; + } + DVDNTH_Shadow = DVDNTH; + DVDNTL_Shadow = DVDNTL; +} + +// +// Misaligned/wrong-sized accesses aren't handled correctly, it's a mess, but probably doesn't matter. +// +template +NO_INLINE void SH7095::OnChipRegWrite(uint32 A, uint32 V) +{ + //SS_DBG(SS_DBG_SH2_REGW, "[%s] %zu-byte write to on-chip register area; address=0x%08x value=0x%08x\n", cpu_name, sizeof(T), A, V); + + if(A & 0x100) + { + if(sizeof(T) == 2) + A &= 0xFE; + else + A &= 0xFC; + + if(sizeof(T) == 1) + { + SetPEX(PEX_CPUADDR); + V |= (uint8)V << 8; + } + + switch(A) + { + default: + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Unhandled %zu-byte write to on-chip high register area; address=0x%08x value=0x%08x\n", cpu_name, sizeof(T), A, V); + break; + + // + // Division Unit registers + // + case 0x20: + case 0x00: + DVSR = V; + break; + + case 0x24: + case 0x04: + DVDNT = V; + DVDNTL = V; + DVDNTH = (int32)V >> 31; + DIVU_S32_S32(); + break; + + case 0x28: + case 0x08: + DVCR = V & 0x3; + break; + + case 0x2C: + case 0x0C: + VCRDIV = V; + break; + + case 0x30: + case 0x10: + DVDNTH = V; + break; + + case 0x34: + case 0x14: + DVDNTL = V; + DIVU_S64_S32(); + break; + + // ? + case 0x38: + case 0x18: + DVDNTH_Shadow = V; + break; + + case 0x3C: + case 0x1C: + DVDNTL_Shadow = V; + break; + // + // + // + + // + // DMA registers + // + case 0x80: + case 0x90: + DMACH[(A >> 4) & 1].SAR = V; + break; + + case 0x84: + case 0x94: + DMACH[(A >> 4) & 1].DAR = V; + break; + + case 0x88: + case 0x98: + DMACH[(A >> 4) & 1].TCR = V & 0xFFFFFF; + break; + + case 0x8C: + case 0x9C: + DMA_Update(SH7095_mem_timestamp); + { + const unsigned ch = (A >> 4) & 1; + + DMACH[ch].CHCR = (V & ~2) | (DMACH[ch].CHCR & (V | DMACH[ch].CHCRM) & 2); + SS_DBGTI(SS_DBG_SH2, "[%s] DMA %d CHCR Write: CHCR=0x%04x SAR=0x%08x DAR=0x%08x TCR=0x%04x", cpu_name, ch, DMACH[ch].CHCR, DMACH[ch].SAR, DMACH[ch].DAR, DMACH[ch].TCR); + + if((DMACH[ch].CHCR & 0x1) && (DMACH[ch].CHCR & 0x3E8) != 0x200) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Unhandled CHCR on DMA channel %u: 0x%08x\n", cpu_name, ch, DMACH[ch].CHCR); + } + } + DMA_StartSG(); + RecalcPendingIntPEX(); + break; + + case 0xA0: + case 0xA8: + DMACH[(A >> 3) & 1].VCR = V; + break; + + case 0xB0: + DMA_Update(SH7095_mem_timestamp); + DMAOR = (V & 0x9) | (DMAOR & (V | DMAORM) & 0x6); + DMA_StartSG(); + break; + + // + // BSC registers + // + case 0xE0: // BCR1 + case 0xE2: + BCR1 = (BCR1 &~ BCR1M) | (V & BCR1M); // Not sure if this is right, TODO: test somehow. + BCR1M = 0; + break; + } + } + else + { + unsigned mask = 0xFFFF; + unsigned shift = 0; + + if(sizeof(T) != 2) + { + shift = ((A & 1) ^ 1) << 3; + mask = 0xFF << shift; + + if(sizeof(T) == 4) + shift ^= 8; + } + + if(sizeof(T) == 4) + SetPEX(PEX_CPUADDR); + + switch(A & 0xFF) + { + default: + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Unhandled %zu-byte write to on-chip low register area; address=0x%08x value=0x%08x\n", cpu_name, sizeof(T), A, V); + break; + + // + // Free-running timer registers. + // + // + // TIER + case 0x10: + FRT_WDT_Update(); + // + FRT.TIER = V; + RecalcPendingIntPEX(); + break; + + // FTCSR + case 0x11: + FRT_WDT_Update(); + // + FRT.FTCSR = (FRT.FTCSR & (FRT.FTCSRM | V) & 0x8E) | (V & 0x01); + RecalcPendingIntPEX(); + FRT_CheckOCR(); + break; + + // FRCH + case 0x12: + FRT.RW_Temp = V; + break; + + // FRCL + case 0x13: + FRT_WDT_Update(); + // + FRT.FRC = (FRT.RW_Temp << 8) | (V & 0xFF); + FRT_CheckOCR(); + FRT_WDT_Recalc_NET(); + break; + + // OCRA/B H + case 0x14: + FRT.RW_Temp = V; + break; + + // OCRA/B L + case 0x15: + FRT_WDT_Update(); + // + FRT.OCR[(FRT.TOCR >> 4) & 1] = (FRT.RW_Temp << 8) | V; + FRT_CheckOCR(); + FRT_WDT_Recalc_NET(); + break; + + // TCR + case 0x16: + { + FRT_WDT_Update(); + // + //const uint8 old_TCR = FRT.TCR; + FRT.TCR = V; +#if 0 + // + // Maybe not worth emulating?: + // + if((old_TCR ^ FRT.TCR) & 3) + { + bool old_cs; + bool clock; + + if((old_TCR & 0x3) == 3) + old_cs = FRT.FTCI; + else + old_cs = (FRT_WDT_.ClockDivider >> (3 - 1 + ((old_TCR & 0x3) << 1))) & 1; + + if((V & 0x3) == 3) + clock = (!old_cs && FRT.FTCI); + else + { + bool new_cs = (FRT_WDT_ClockDivider >> (3 - 1 + ((FRT.TCR & 0x3) << 1))) & 1; + + clock = (old_cs && !new_cs); + } + + if(clock) + FRT_ClockFRC(); + } +#endif + // + // + // + FRT_WDT_Recalc_NET(); + } + break; + + // TOCR + case 0x17: + FRT.TOCR = V & 0x1F; + break; + + // + // + // + case 0x71: + case 0x72: + DMACH[(A & 1) ^ 1].DRCR = V & 0x3; + break; + + + // + // WDT registers + // + case 0x80: + case 0x88: + FRT_WDT_Update(); + if(sizeof(T) == 2) + { + if((V & 0xFF00) == 0x5A00) + { + if(WDT.WTCSR & 0x20) + WDT.WTCNT = V; + } + else if((V & 0xFF00) == 0xA500) + { + WDT.WTCSR = (WDT.WTCSR & (WDT.WTCSRM | V) & 0x80) | (V & 0x67); + + if(WDT.WTCSR & 0x20) + SBYCR &= 0x7F; + else + { + WDT.WTCSR &= ~0x80; // Seemingly undocumented... + WDT.WTCNT = 0; + } + } + } + WDT.RSTCSRM = 0; + FRT_WDT_Recalc_NET(); + RecalcPendingIntPEX(); + break; + + case 0x82: + case 0x8A: + FRT_WDT_Update(); + if(sizeof(T) == 2) + { + if(V == 0xA500) + { + // Clear OVF bit + WDT.RSTCSR &= ~WDT.RSTCSRM; + } + else if((V & 0xFF00) == 0x5A00) + { + // Write RSTE and RSTS bits + WDT.RSTCSR = (WDT.RSTCSR & 0x80) | (V & 0x60); + } + } + WDT.RSTCSRM = 0; + break; + + case 0x81: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x89: + case 0x8B: + case 0x8C: + case 0x8D: + case 0x8E: + case 0x8F: + WDT.RSTCSRM = 0; + break; + + // + // + // + case 0x91: + SBYCR = V; + + if(WDT.WTCSR & 0x20) + SBYCR &= 0x7F; + + if(SBYCR != 0) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] SBYCR set to non-zero value: 0x%02x\n", cpu_name, V); + } + break; + + case 0x92: case 0x93: case 0x94: case 0x95: + case 0x96: case 0x97: case 0x98: case 0x99: + case 0x9A: case 0x9B: case 0x9C: case 0x9D: + case 0x9E: + SetCCR(V); + break; + + + // + // + // + case 0x60: + case 0x61: + IPRB = (IPRB &~ mask) | ((V << shift) & mask & 0xFF00); + RecalcPendingIntPEX(); + break; + + case 0x62: + case 0x63: + VCRA = (VCRA &~ mask) | ((V << shift) & mask & 0x7F7F); + break; + + case 0x64: + case 0x65: + VCRB = (VCRB &~ mask) | ((V << shift) & mask & 0x7F7F); + break; + + case 0x66: + case 0x67: + VCRC = (VCRC &~ mask) | ((V << shift) & mask & 0x7F7F); + break; + + case 0x68: + case 0x69: + VCRD = (VCRD &~ mask) | ((V << shift) & mask & 0x7F00); + break; + + case 0xE0: + case 0xE1: + ICR = (ICR &~ mask) | ((V << shift) & mask & 0x0101); + if(ICR & 0x0100) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] NMIE=1\n", cpu_name); + } + RecalcPendingIntPEX(); + break; + + case 0xE2: + case 0xE3: + IPRA = (IPRA &~ mask) | ((V << shift) & mask & 0xFFF0); + RecalcPendingIntPEX(); + break; + + case 0xE4: + case 0xE5: + VCRWDT = (VCRWDT &~ mask) | ((V << shift) & mask & 0x7F7F); + break; + } + } +} + +template +INLINE T SH7095::OnChipRegRead(uint32 A) +{ + if(A & 0x100) + { + uint32 ret = 0; + + MA_until++; + + if(sizeof(T) == 2) + A &= 0xFE; + else + A &= 0xFC; + + if(sizeof(T) == 1) + SetPEX(PEX_CPUADDR); + + switch(A) + { + default: + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Unhandled %zu-byte read from on-chip high register area; address=0x%08x\n", cpu_name, sizeof(T), A); + break; + + // + // Division Unit registers + // + case 0x20: + case 0x22: + case 0x00: + case 0x02: + MA_until = std::max(MA_until, divide_finish_timestamp); + ret = DVSR; + break; + + case 0x24: + case 0x26: + case 0x04: + case 0x06: + MA_until = std::max(MA_until, divide_finish_timestamp); + ret = DVDNT; + break; + + case 0x28: + case 0x2A: + case 0x08: + case 0x0A: + MA_until = std::max(MA_until, divide_finish_timestamp); + ret = DVCR; + break; + + case 0x2C: + case 0x2E: + case 0x0C: + case 0x0E: + MA_until = std::max(MA_until, divide_finish_timestamp); + ret = VCRDIV; + break; + + case 0x30: + case 0x32: + case 0x10: + case 0x12: + MA_until = std::max(MA_until, divide_finish_timestamp); + ret = DVDNTH; + break; + + case 0x34: + case 0x36: + case 0x14: + case 0x16: + MA_until = std::max(MA_until, divide_finish_timestamp); + ret = DVDNTL; + break; + + // ? + case 0x38: + case 0x3A: + case 0x18: + case 0x1A: + MA_until = std::max(MA_until, divide_finish_timestamp); + ret = DVDNTH_Shadow; + break; + + case 0x3C: + case 0x3E: + case 0x1C: + case 0x1E: + MA_until = std::max(MA_until, divide_finish_timestamp); + ret = DVDNTL_Shadow; + break; + // + // + // + + // + // DMA registers + // + case 0x80: + case 0x90: + ret = DMACH[(A >> 4) & 1].SAR; + break; + + case 0x84: + case 0x94: + ret = DMACH[(A >> 4) & 1].DAR; + break; + + case 0x88: + case 0x98: + ret = DMACH[(A >> 4) & 1].TCR; + break; + + case 0x8C: + case 0x9C: + { + const unsigned ch = (A >> 4) & 1; + + ret = DMACH[ch].CHCR; + DMACH[ch].CHCRM = 0; + } + break; + + case 0xA0: + case 0xA8: + ret = DMACH[(A >> 3) & 1].VCR; + break; + + case 0xB0: + ret = DMAOR; + DMAORM = 0; + break; + + // + // BSC registers + // + case 0xE0: // BCR1 + case 0xE2: + ret = BCR1; + break; + } + + if(sizeof(T) == 1) + ret >>= ((A & 1) ^ 1) << 3; + + return ret; + } + else + { + const unsigned Am = (uint8)A; + const unsigned shift = ((sizeof(T) != 2) ? (((A & 1) ^ 1) << 3) : 0); + uint16 ret = 0; + + if(Am < 0x20) + MA_until = (MA_until + 11) &~ 1; // FIXME: not quite right. //3; + else if((Am >= 0x60 && Am < 0xA0) || Am >= 0xE0) + MA_until += 3; + else + MA_until += 1; + + if(sizeof(T) == 4) + SetPEX(PEX_CPUADDR); + + else switch(Am) + { + default: + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Unhandled %zu-byte read from on-chip low register area; address=0x%08x\n", cpu_name, sizeof(T), A); + break; + + // + // FRT registers. Some weirdness with 16-bit reads duplicating the lower 8 bits in the upper 8-bits, but the upper 8-bits are masked + // with the last data written to the FRT area or something...not emulated here. + // + case 0x10: + ret = FRT.TIER | 1; + break; + + case 0x11: + FRT_WDT_Update(); + // + ret = FRT.FTCSR; + FRT.FTCSRM = 0x00; + break; + + case 0x12: + FRT_WDT_Update(); + // + FRT.RW_Temp = FRT.FRC; + ret = FRT.FRC >> 8; + break; + + case 0x13: + ret = FRT.RW_Temp; + break; + + case 0x14: + ret = FRT.OCR[(FRT.TOCR >> 4) & 1] >> 8; + break; + + case 0x15: + ret = FRT.OCR[(FRT.TOCR >> 4) & 1] & 0xFF; + break; + + case 0x16: + ret = FRT.TCR; + break; + + case 0x17: + ret = FRT.TOCR | 0xE0; + break; + + case 0x18: + FRT.RW_Temp = FRT.FICR; + ret = FRT.FICR >> 8; + break; + + case 0x19: + ret = FRT.RW_Temp; + break; + + // + // + // + case 0x71: + case 0x72: + ret = DMACH[(A & 1) ^ 1].DRCR; + break; + + + // + // WDT registers + // + case 0x80: + case 0x88: + FRT_WDT_Update(); + ret = WDT.WTCSR | 0x18; + WDT.WTCSRM = 0x00; + break; + + case 0x81: + case 0x89: + FRT_WDT_Update(); + ret = WDT.WTCNT; + break; + + case 0x82: + case 0x85: + case 0x86: + case 0x87: + case 0x8A: + case 0x8D: + case 0x8E: + case 0x8F: + ret = 0xFF; + break; + + case 0x83: + case 0x8B: + FRT_WDT_Update(); + ret = WDT.RSTCSR | 0x1F; + WDT.RSTCSRM = (WDT.RSTCSR & 0x80); + break; + + // FIXME: WDT open bus of a sort. + // case 0x84: + // case 0x8C: + + // + // + // + + case 0x91: + ret = SBYCR; + break; + + case 0x92: case 0x93: case 0x94: case 0x95: + case 0x96: case 0x97: case 0x98: case 0x99: + case 0x9A: case 0x9B: case 0x9C: case 0x9D: + case 0x9E: + ret = CCR | (CCR << 8); + break; + // + // + // + case 0x60: + case 0x61: + ret = IPRB >> shift; + break; + + case 0x62: + case 0x63: + ret = VCRA >> shift; + break; + + case 0x64: + case 0x65: + ret = VCRB >> shift; + break; + + case 0x66: + case 0x67: + ret = VCRC >> shift; + break; + + case 0x68: + case 0x69: + ret = VCRD >> shift; + break; + + case 0x6A: case 0x6B: case 0x6C: case 0x6D: case 0x6E: case 0x6F: + ret = 0xFFFF >> shift; + break; + + case 0xE0: + case 0xE1: + ret = (ICR | (NMILevel << 15)) >> shift; + break; + + case 0xE2: + case 0xE3: + ret = IPRA >> shift; + break; + + case 0xE4: + case 0xE5: + ret = VCRWDT >> shift; + break; + + case 0xE6: case 0xE7: + case 0xE8: case 0xE9: case 0xEA: case 0xEB: case 0xEC: case 0xED: case 0xEE: case 0xEF: + case 0xF0: case 0xF1: case 0xF2: case 0xF3: case 0xF4: case 0xF5: case 0xF6: case 0xF7: + case 0xF8: case 0xF9: case 0xFA: case 0xFB: case 0xFC: case 0xFD: case 0xFE: case 0xFF: + ret = 0xFFFF >> shift; + break; + } + + return ret; + } +} + +template +INLINE T SH7095::ExtBusRead(uint32 A) +{ + T ret; + + A &= (1U << 27) - 1; + + if(timestamp > SH7095_mem_timestamp) + SH7095_mem_timestamp = timestamp; + + ret = SH7095_BusRead(A, BurstHax, NULL); + + return ret; +} + +template +INLINE void SH7095::ExtBusWrite(uint32 A, T V) +{ + A &= (1U << 27) - 1; + + if(timestamp > SH7095_mem_timestamp) + SH7095_mem_timestamp = timestamp; + + SH7095_BusWrite(A, V, false, NULL); + + write_finish_timestamp = SH7095_mem_timestamp; +} + + +// +// +// +static const struct +{ + uint8 AND; + uint8 OR; +} LRU_Update_Tab[4] = +{ + { (1 << 2) | (1 << 1) | (1 << 0), /**/ (0 << 5) | (0 << 4) | (0 << 3) }, // Way 0 + { (1 << 4) | (1 << 3) | (1 << 0), /**/ (1 << 5) | (0 << 2) | (0 << 1) }, // Way 1 + { (1 << 5) | (1 << 3) | (1 << 1), /**/ (1 << 4) | (1 << 2) | (0 << 0) }, // Way 2 + { (1 << 5) | (1 << 4) | (1 << 2), /**/ (1 << 3) | (1 << 1) | (1 << 0) }, // Way 3 +}; + +static const int8 LRU_Replace_Tab[0x40] = +{ + /* 0x00 */ 0x03, 0x02, -1, 0x02, 0x03, -1, 0x01, 0x01, -1, 0x02, -1, 0x02, -1, -1, 0x01, 0x01, + /* 0x10 */ 0x03, -1, -1, -1, 0x03, -1, 0x01, 0x01, -1, -1, -1, -1, -1, -1, 0x01, 0x01, + /* 0x20 */ 0x03, 0x02, -1, 0x02, 0x03, -1, -1, -1, -1, 0x02, -1, 0x02, -1, -1, -1, -1, + /* 0x30 */ 0x03, -1, -1, -1, 0x03, -1, -1, -1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static INLINE uint32 cmov_eq_thing(const uint32 reg_compval, const uint32 mem_compval, uint32 var, const uint32 repl_var) +{ + #ifdef ARCH_X86 + asm( "cmpl %1, %2\n\t" + "cmove %3,%0\n\t" + : "+r"(var) + : "r"(reg_compval), "g"(mem_compval), "r"(repl_var) + : "cc"); + #else + #ifdef __GNUC__ + #warning "Conditional move inline assembly not being used." + #endif + var = ((reg_compval == mem_compval) ? repl_var : var); + #endif + + return var; +} + +INLINE void SH7095::AssocPurge(const uint32 A) +{ + const uint32 ATM = A & (0x7FFFF << 10); + auto* cent = &Cache[(A >> 4) & 0x3F]; + + // Ignore two-way-mode bit in CCR here. + if(ATM == cent->Tag[0]) cent->Tag[0] |= 1U << 31; // Set invalid bit to 1. + if(ATM == cent->Tag[1]) cent->Tag[1] |= 1U << 31; + if(ATM == cent->Tag[2]) cent->Tag[2] |= 1U << 31; + if(ATM == cent->Tag[3]) cent->Tag[3] |= 1U << 31; +} + +template +INLINE T SH7095::MemReadRT(uint32 A) +{ + static_assert(region < 0x8, "Wrong region argument."); + const uint32 unmasked_A = A; + + if(!IsInstr) + { + if(MDFN_UNLIKELY(A & (sizeof(T) - 1))) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Misaligned %zu-byte read from 0x%08x\n", cpu_name, sizeof(T), A); + A &= ~(sizeof(T) - 1); + SetPEX(PEX_CPUADDR); + } + } + + if(!IsInstr) + MA_until = std::max(MA_until, timestamp + 1); + else + timestamp = std::max(MA_until, timestamp); + + // + // WARNING: Template arguments CacheEnabled and TwoWayMode are only valid for region==0. In addition, TwoWayMode is only valid for CacheEnabled==true. + // + switch(region) // A >> 29 + { + case 0: + if(CacheEnabled) + { + const uint32 ATM = A & (0x7FFFF << 10); + auto* cent = &Cache[(A >> 4) & 0x3F]; + int way_match = -1; + + way_match = cmov_eq_thing(ATM, cent->Tag[0], way_match, 0); + way_match = cmov_eq_thing(ATM, cent->Tag[1], way_match, 1); + way_match = cmov_eq_thing(ATM, cent->Tag[2], way_match, 2); + way_match = cmov_eq_thing(ATM, cent->Tag[3], way_match, 3); + + if(MDFN_UNLIKELY(way_match < 0)) // Cache miss! + { + if(IsInstr) + { + if(MDFN_UNLIKELY(CCR & CCR_ID)) + goto EBRCase; + } + else + { + if(MDFN_UNLIKELY(CCR & CCR_OD)) + goto EBRCase; + } + + if(TwoWayMode) + way_match = 3 ^ (cent->LRU & 0x1); + else + way_match = LRU_Replace_Tab[cent->LRU]; + + if(MDFN_UNLIKELY(way_match < 0)) + goto EBRCase; + + // + // Load cache line. + // + //printf("Cache load line: %08x\n", A); + cent->Tag[way_match] = ATM; + + { + unsigned di = (A + 4 + 0) & 0xC; MDFN_ennsb(¢->Data[way_match][di], ExtBusRead((A &~ 0xF) + di)); + } + for(unsigned i = 4; i < 16; i += 4) + { + unsigned di = (A + 4 + i) & 0xC; MDFN_ennsb(¢->Data[way_match][di], ExtBusRead((A &~ 0xF) + di)); + } + if(!IsInstr) + MA_until = std::max(MA_until, SH7095_mem_timestamp + 1); + else + timestamp = SH7095_mem_timestamp; + } + cent->LRU = (cent->LRU & LRU_Update_Tab[way_match].AND) | LRU_Update_Tab[way_match].OR; + return MDFN_densb(¢->Data[way_match][NE32ASU8_IDX_ADJ(T, A & 0x0F)]); + } + // Fall-through, no break here + case 1: + EBRCase: + { + T ret = ExtBusRead(A); + + if(!IsInstr) + MA_until = std::max(MA_until, SH7095_mem_timestamp + 1); + else + timestamp = SH7095_mem_timestamp; + + return ret; + } + + case 2: + case 5: + // + // Associative purge(apparently returns open bus of some sort) + // + //SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] %zu-byte read from associative purge area; address=0x%08x\n", cpu_name, sizeof(T), A); + AssocPurge(A); + return ~0; + + case 3: + // + // Direct cache address/tag access + // + // Note: bits 0, 1, 3, 29, 30, 31 are some sort of open-bus(unemulated). + // + // SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] %zu-byte read from cache address array area; address=0x%08x\n", cpu_name, sizeof(T), A); + { + const unsigned way = (CCR >> 6) & 0x3; + const unsigned ena = (A >> 4) & 0x3F; + + return (Cache[ena].Tag[way] & (0x7FFFF << 10)) | (((int32)~Cache[ena].Tag[way] >> 31) & 0x4) | (Cache[ena].LRU << 4); + } + + case 4: + case 6: + // + // Direct cache data access + // + //SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] %zu-byte read from cache data array area; address=0x%08x\n", cpu_name, sizeof(T), A); + { + const unsigned way = (A >> 10) & 0x3; + const unsigned ena = (A >> 4) & 0x3F; + + return MDFN_densb(&Cache[ena].Data[way][NE32ASU8_IDX_ADJ(T, A & 0x0F)]); + } + + case 7: + return OnChipRegRead(unmasked_A); + } +} + +template +INLINE T SH7095::MemRead(uint32 A) +{ + if(sizeof(T) == 1) + return MRFP8[A >> 29](A); + else if(sizeof(T) == 2) + return MRFP16[A >> 29](A); + else + return MRFP32[A >> 29](A); +} + +template +INLINE void SH7095::Write_UpdateCache(uint32 A, T V) +{ + const uint32 ATM = A & (0x7FFFF << 10); + auto* cent = &Cache[(A >> 4) & 0x3F]; + int way_match = -1; + + way_match = cmov_eq_thing(ATM, cent->Tag[0], way_match, 0); + way_match = cmov_eq_thing(ATM, cent->Tag[1], way_match, 1); + way_match = cmov_eq_thing(ATM, cent->Tag[2], way_match, 2); + way_match = cmov_eq_thing(ATM, cent->Tag[3], way_match, 3); + + if(MDFN_LIKELY(way_match >= 0)) // Cache hit! + { + cent->LRU = (cent->LRU & LRU_Update_Tab[way_match].AND) | LRU_Update_Tab[way_match].OR; + MDFN_ennsb(¢->Data[way_match][NE32ASU8_IDX_ADJ(T, A & 0x0F)], V); // Ignore CCR OD bit here. + } +} + +template +INLINE void SH7095::MemWriteRT(uint32 A, T V) +{ + static_assert(region < 0x8, "Wrong region argument."); + const uint32 unmasked_A = A; + + if(MDFN_UNLIKELY(A & (sizeof(T) - 1))) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Misaligned %zu-byte write of 0x%08x to 0x%08x\n", cpu_name, sizeof(T), V, A); + A &= ~(sizeof(T) - 1); + SetPEX(PEX_CPUADDR); + } + + MA_until = std::max(MA_until, timestamp + 1); + + // + // WARNING: Template argument CacheEnabled is only valid for region==0. + // + switch(region) // A >> 29 + { + case 0: + if(CacheEnabled) + Write_UpdateCache(A, V); + // Fall-through, no break + case 1: + MA_until = std::max(MA_until, write_finish_timestamp + 1); + + ExtBusWrite(A, V); + return; + + case 2: + case 5: + // + // Associative purge. + // + //SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] %zu-byte write to associative purge area; address=0x%08x value=0x%x\n", cpu_name, sizeof(T), A, V); + AssocPurge(A); + return; + + case 3: + // + // Direct cache address/tag access + // + // TODO: Check non-32 bit access + //SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] %zu-byte write to cache address array area; address=0x%08x value=0x%x\n", cpu_name, sizeof(T), A, V); + timestamp++; + MA_until = std::max(MA_until, timestamp + 1); + { + const unsigned way = (CCR >> 6) & 0x3; + const unsigned ena = (A >> 4) & 0x3F; + + Cache[ena].Tag[way] = (A & (0x7FFFF << 10)) | ((!(A & 0x4)) << 31); + Cache[ena].LRU = (V >> 4) & 0x3F; + } + return; + + case 4: + case 6: + // + // Direct cache data access + // + //SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] %zu-byte write to cache data array area; address=0x%08x value=0x%x\n", cpu_name, sizeof(T), A, V); + { + const unsigned way = (A >> 10) & 0x3; + const unsigned ena = (A >> 4) & 0x3F; + + MDFN_ennsb(&Cache[ena].Data[way][NE32ASU8_IDX_ADJ(T, A & 0x0F)], V); + } + return; + + case 7: + OnChipRegWrite(unmasked_A, V); + return; + } +} + +template +INLINE void SH7095::MemWrite(uint32 A, T V) +{ + if(sizeof(T) == 1) + MWFP8[A >> 29](A, V); + else if(sizeof(T) == 2) + MWFP16[A >> 29](A, V); + else + MWFP32[A >> 29](A, V); +} + + +template +static NO_INLINE MDFN_FASTCALL T C_MemReadRT(uint32 A) +{ + return CPU[which].MemReadRT(A); +} + +template +static NO_INLINE MDFN_FASTCALL void C_MemWriteRT(uint32 A, T V) +{ + CPU[which].MemWriteRT(A, V); +} + + +INLINE void SH7095::SetCCR(uint8 V) +{ + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Write to CCR: 0x%02x\n", cpu_name, V); + + if(V & CCR_CP) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Cache purge.\n", cpu_name); + + for(unsigned entry = 0; entry < 64; entry++) + { + Cache[entry].LRU = 0; + for(unsigned way = 0; way < 4; way++) + Cache[entry].Tag[way] |= 1U << 31; // Set invalid bit to 1. + } + V &= ~CCR_CP; + } + + CCR = V; + + #define MAHL(bs,w) \ + if(CCR & CCR_CE) \ + { \ + if(CCR & CCR_TW) \ + { \ + MRFP##bs[0] = C_MemReadRT ; \ + MRFPI[0] = C_MemReadRT ; \ + } \ + else \ + { \ + MRFP##bs[0] = C_MemReadRT ; \ + MRFPI[0] = C_MemReadRT ; \ + } \ + MWFP##bs[0] = C_MemWriteRT; \ + } \ + else \ + { \ + MRFP##bs[0] = C_MemReadRT ; \ + MRFPI[0] = C_MemReadRT ; \ + MWFP##bs[0] = C_MemWriteRT; \ + } + if(this == &CPU[0]) + { + MAHL( 8, 0) + MAHL(16, 0) + MAHL(32, 0) + } + else + { + MAHL( 8, 1) + MAHL(16, 1) + MAHL(32, 1) + } + #undef MAHL +} + + + + +/* + + +*/ +void NO_INLINE SH7095::Reset(bool power_on_reset, bool from_internal_wdt) +{ + VBR = 0; + SR |= 0xF << 4; + SetCCR(0); + // + if(power_on_reset) + { + BCR1 = (BCR1 & 0x8000) | 0x03F0; + BCR1M = 0x1FF7; + } + // + for(unsigned ch = 0; ch < 2; ch++) + { + DMACH[ch].CHCR = 0x00; + DMACH[ch].CHCRM = 0x00; + DMACH[ch].DRCR = 0x00; + } + DMAOR = 0x00; + RecalcPendingIntPEX(); + // + INTC_Reset(); + // + DVCR = 0; + RecalcPendingIntPEX(); + // + FRT_Reset(); + WDT_Reset(from_internal_wdt); + // + SBYCR = 0; + Standby = false; + // + // + // + EPending = 0; + SetPEX(power_on_reset ? PEX_POWERON : PEX_RESET); + Pipe_ID = EPending; +} + +void NO_INLINE SH7095::INTC_Reset(void) +{ + IPRA = 0; + IPRB = 0; + VCRA = 0; + VCRB = 0; + VCRC = 0; + VCRD = 0; + VCRWDT = 0; + ICR = 0; + + RecalcPendingIntPEX(); +} + +void SH7095::SetNMI(bool level) +{ + //printf("NMI: %d, %d %d\n", NMILevel, level, (bool)(ICR & 0x100)); + if(NMILevel != level && level == (bool)(ICR & 0x100)) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] NMI - Standby=%u\n", cpu_name, Standby); + + SetPEX(PEX_NMI); + + if(Standby) + { + WDT.WTCSR |= 0x08; + FRT_WDT_Recalc_NET(); + } + else + DMAOR |= 0x02; // TODO: NMIF; set always, or only when DMA was active? + } + NMILevel = level; +} + +void SH7095::SetMD5(bool level) +{ + BCR1 = (BCR1 & 0x7FFF) | (level << 15); +} + +void SH7095::SetIRL(unsigned level) +{ + assert(level < 16); + + IRL = level; + RecalcPendingIntPEX(); +} + +void SH7095::ForceInternalEventUpdates(void) +{ + FRT_WDT_Update(); + FRT_WDT_Recalc_NET(); +} + +// +// Default priority(for same ipr value), highest to lowest: +// NMI +// User break +// IRL15 +// [...] +// IRL1 +// DIVU +// DMAC0 +// DMAC1 +// WDT +// REF +// SCI-ERI +// SCI-RXI +// SCI-TXI +// SCI-TEI +// FRT-ICI +// FRT-OCI +// FRT-OVI +// +// +uint8 INLINE SH7095::GetPendingInt(uint8* vecnum_out) +{ + unsigned ipr; + unsigned vecnum; + unsigned tmp_ipr; + + ipr = IRL; + vecnum = (IRL >> 1) + VECNUM_INT_BASE; + + if(vecnum_out && (ICR & 0x1) && IRL > 0) // External vec fetch has side effects, make sure to only do it if vecnum_out is non-NULL and ICR & 0x1, and if this is the interrupt being serviced. + vecnum = ~0U; + + // + // + // + + if((DVCR & 0x3) == 0x3 && (tmp_ipr = ((IPRA >> 12) & 0xF)) > ipr) + { + ipr = tmp_ipr; + vecnum = (VCRDIV & 0x7F); + } + + for(unsigned ch = 0; ch < 2; ch++) + { + if((DMACH[ch].CHCR & 0x6) == 0x6 && (tmp_ipr = ((IPRA >> 8) & 0xF)) > ipr) + { + ipr = tmp_ipr; + vecnum = (DMACH[ch].VCR & 0x7F); + } + } + + if((WDT.WTCSR & 0x80) && (tmp_ipr = ((IPRA >> 4) & 0xF)) > ipr) + { + ipr = tmp_ipr; + vecnum = (VCRWDT >> 8) & 0x7F; + } + +#if 0 + if(OPMIPending) + { + static const uint32 sci_any_mask = (1U << OPMI_SCI_TEI) | (1U << OPMI_SCI_TXI) | (1U << OPMI_SCI_RXI) | (1U << OPMI_SCI_ERI); + static const uint32 dmac_any_mask = (1U << OPMI_DMAC1) | (1U << OPMI_DMAC0); + uint32 new_ipr; + + if((OPMIPending & sci_any_mask) && (new_ipr = ((IPRB >> 12) & 0xF)) > ipr) + { + + } + } +#endif + // + // + // + const uint32 frt_ip_tmp = (FRT.FTCSR & FRT.TIER & 0x8E); + if(frt_ip_tmp && (tmp_ipr = ((IPRB >> 8) & 0xF)) > ipr) + { + ipr = tmp_ipr; + + if(frt_ip_tmp & 0x80) // ICI + vecnum = (VCRC >> 8) & 0x7F; + else if(frt_ip_tmp & 0x0C) // OCIA+OCIB + vecnum = (VCRC >> 0) & 0x7F; + else // OVI + vecnum = (VCRD >> 8) & 0x7F; + } + + if(vecnum_out) + { + if(vecnum == ~0U) + vecnum = ExIVecFetch(); + + *vecnum_out = vecnum; + } + + return ipr; +} + +// +// Call after changes to: +// IRL +// SR +// +// IPRA +// IPRB +// +// DMACH[*].CHCR +// +// DVCR +// +// FRT.FTCSR +// FRT.TIER +// +void NO_INLINE SH7095::RecalcPendingIntPEX(void) +{ + if(GetPendingInt(NULL) > ((SR >> 4) & 0xF)) + SetPEX(PEX_INT); + else + ClearPEX(PEX_INT); +} + +static const uint8 InstrDecodeTab[65536] = +{ + #include "sh7095_idecodetab.inc" +}; + +template +INLINE void SH7095::FetchIF(bool ForceIBufferFill) +{ + if(DebugMode) + PC_IF = PC; + +#ifdef SH7095_EMULATE_ICACHE + if(ForceIBufferFill) + { + IBuffer = MRFPI[PC >> 29](PC &~ 2); + Pipe_IF = (uint16)(IBuffer >> (((PC & 2) ^ 2) << 3)); + } + else + { + Pipe_IF = (uint16)IBuffer; + if(!(PC & 0x2)) + { + IBuffer = MRFPI[PC >> 29](PC); + Pipe_IF = IBuffer >> 16; + } + } +#else + if(timestamp < (MA_until - (ForceIBufferFill ? 0 : ((int32)(PC & 0x2) << 28)))) + timestamp = MA_until; + + if(MDFN_UNLIKELY((int32)PC < 0)) // Mr. Boooones + { + Pipe_IF = MRFP16[PC >> 29](PC); + timestamp++; + return; + } + + Pipe_IF = *(uint16*)(SH7095_FastMap[PC >> SH7095_EXT_MAP_GRAN_BITS] + PC); +#endif + timestamp++; +} + +// +// TODO: Stop reading from memory when an exception is pending? +// +template +INLINE void SH7095::DoIDIF_Real(void) +{ + if(DelaySlot) + { + // + // Redecode the opcode from the 16-bit instruction to makes sure exceptions won't be taken in the delay slot(due + // to op field being forced to 0xFF in the previous call to DoIDIF()), and forces usage of the second half of the opcode + // table so we can generate illegal slot instruction exceptions as appropriate. + // + // Oh, and this effectively discards the previously-fetched instruction in Pipe_IF. Poor, poor instruction. + // + Pipe_ID = (uint16)Pipe_ID; + Pipe_ID |= (InstrDecodeTab[Pipe_ID] | 0x80) << 24; + } + else + { + uint32 op = InstrDecodeTab[Pipe_IF]; + uint32 epo = EPending; + + if(IntPreventNext) + { + epo &= ~(1U << (PEX_INT + EPENDING_PEXBITS_SHIFT)); + if(!(epo & (0xFF << EPENDING_PEXBITS_SHIFT))) + epo = 0; + } + + if(DebugMode) + PC_ID = PC_IF; + + Pipe_ID = Pipe_IF | (op << 24) | epo; + } + + if(!SkipFetchIF) + FetchIF(false); +} + +template +static NO_INLINE void DoIDIF(void) +{ + CPU[which].DoIDIF_Real(); +} + +template +INLINE void SH7095::Branch(uint32 target) +{ + if(DebugMode > 0) + DBG_AddBranchTrace(which, target, -1); + + PC = target; + + // + // Not totally correct, but simplifies things...probably :p + // + if(delayed) + { + if(MDFN_UNLIKELY(PC & 1)) + { + DoIDIF(); + SetPEX(PEX_CPUADDR); // Pending for the instruction after the delay slot instruction. + } + else + { +#ifdef SH7095_EMULATE_ICACHE + if(PC & 0x2) + IBuffer = MRFPI[PC >> 29](PC &~ 2); +#endif + + DoIDIF(); + } + } + else + { + if(MDFN_UNLIKELY(PC & 1)) + { + SetPEX(PEX_CPUADDR); + DoIDIF(); + } + else + { +#ifdef SH7095_EMULATE_ICACHE + if(PC & 0x2) + IBuffer = MRFPI[PC >> 29](PC &~ 2); +#endif + + DoIDIF(); + PC += 2; + DoIDIF(); + } + } +} + +// Remember to use BEGIN_OP_DLYIDIF instead of BEGIN_OP +template +INLINE void SH7095::UCDelayBranch(uint32 target) +{ + if(DebugMode > 0) + DBG_AddBranchTrace(which, target, -1); + + PC = target; + + if(DebugMode) + PC_ID = PC_IF; + + Pipe_ID = Pipe_IF | ((InstrDecodeTab[Pipe_IF] | 0x80) << 24); + + timestamp++; + + if(MDFN_UNLIKELY(PC & 1)) + { + DoIDIF(); + SetPEX(PEX_CPUADDR); // Pending for the instruction after the delay slot instruction. + } + else + { + FetchIF(true); + } +} + +template +INLINE void SH7095::UCRelDelayBranch(uint32 disp) +{ + UCDelayBranch(PC + disp); +} + + +template +INLINE void SH7095::CondRelBranch(bool cond, uint32 disp) +{ + if(cond) + Branch(PC + disp); +} + +template +uint32 NO_INLINE SH7095::Exception(const unsigned exnum, const unsigned vecnum) +{ + uint32 new_PC; + + timestamp += 2; + + if(exnum == EXCEPTION_RESET || exnum == EXCEPTION_POWERON) + { + new_PC = MemRead((vecnum + 0) << 2); + R[15] = MemRead((vecnum + 1) << 2); + } + else + { + // Save SR to stack + // Save PC to stack + // Read exception vector table + R[15] -= 4; + MemWrite(R[15], SR); + timestamp++; + R[15] -= 4; + MemWrite(R[15], PC); + timestamp++; + timestamp++; + new_PC = MemRead(VBR + (vecnum << 2)); + timestamp++; + } + + if(DebugMode) + DBG_AddBranchTrace(this - CPU, new_PC, exnum, vecnum); + + //SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Exception %u, vecnum=%u, saved PC=0x%08x --- New PC=0x%08x\n", cpu_name, exnum, vecnum, PC, new_PC); + + return new_PC; +} + + +/* + PC == 0 + instr = [?] + ID = [?] + IF = [0] + + PC == 2 + instr = [?] + ID = [0] + IF = [2] + + PC == 4 + instr = [0] + ID = [2] + IF = [4] + +*/ + +template +INLINE void SH7095::Step(void) +{ + // + // Ideally, we would place SPEPRecover: after the FRT event check, but doing + // so causes gcc(multiple versions) to produce inconceivably awful code under certain conditions + // (such as disabling all the SS_DBG stuff at compile-time) because it thinks it's an important loop + // or something?(even with all our branch hinting!) + // + SPEPRecover:; + + if(MDFN_UNLIKELY(timestamp >= FRT_WDT_NextTS)) + { + FRT_WDT_Update(); + FRT_WDT_Recalc_NET(); + } + + const uint32 instr = (uint16)Pipe_ID; + const unsigned instr_nyb1 = (instr >> 4) & 0xF; + const unsigned instr_nyb2 = (instr >> 8) & 0xF; +// asm volatile("":: "a"(instr_nyb1), "d"(instr_nyb2)); + switch(Pipe_ID >> 24) + { + #include "sh7095_opdefs.inc" + + #define PART_OP_NORMIDIF DoIDIF(); + + #define BEGIN_OP(x) OP_##x { PART_OP_NORMIDIF + #define BEGIN_OP_DLYIDIF(x) OP_##x { + + // "Interrupt-disabled" instruction(blocks interrupt from being taken for next instruction). + // Use with BEGIN_OP_DLYIDIF() + #define PART_OP_INTDIS DoIDIF(); + + #define END_OP } break; + +#if 0 + #define WB_EX_CHECK(r) { if(timestamp < WB_until[(r)]) timestamp = WB_until[(r)]; } + + #define WB_WRITE(r, v) { R[(r)] = (v); WB_until[(r)] = MA_until + 1; } +#else + #define WB_EX_CHECK(r) { } + #define WB_WRITE(r, v) { R[(r)] = (v); } +#endif + // + // + // + // + // MOV #imm,Rn + // + BEGIN_OP(MOV_IMM_REG) + const unsigned n = instr_nyb2; + const uint32 imm = (int8)instr; + + WB_EX_CHECK(n) + + R[n] = imm; + END_OP + + + // + // MOV.W @(disp,PC),Rn + // + BEGIN_OP(MOV_W_PCREL_REG) + const unsigned n = instr_nyb2; + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = PC + (d << 1); + + WB_WRITE(n, (int16)MemRead(ea)); + END_OP + + + // + // MOV.L @(disp,PC),Rn + // + BEGIN_OP(MOV_L_PCREL_REG) + const unsigned n = instr_nyb2; + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = (PC &~ 0x3) + (d << 2); + + WB_WRITE(n, MemRead(ea)); + END_OP + + + // + // MOV Rm,Rn + // + BEGIN_OP(MOV_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = R[m]; + END_OP + + + // + // MOV.B Rm,@Rn + // + BEGIN_OP(MOV_B_REG_REGINDIR) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 val = R[m]; + const uint32 ea = R[n]; + + MemWrite(ea, val); + END_OP + + + // + // MOV.W Rm,@Rn + // + BEGIN_OP(MOV_W_REG_REGINDIR) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 val = R[m]; + const uint32 ea = R[n]; + + MemWrite(ea, val); + END_OP + + + // + // MOV.L Rm,@Rn + // + BEGIN_OP(MOV_L_REG_REGINDIR) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 val = R[m]; + const uint32 ea = R[n]; + + MemWrite(ea, val); + END_OP + + + // + // MOV.B @Rm,Rn + // + BEGIN_OP(MOV_B_REGINDIR_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 ea = R[m]; + + WB_WRITE(n, (int8)MemRead(ea)); + END_OP + + + // + // MOV.W @Rm,Rn + // + BEGIN_OP(MOV_W_REGINDIR_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 ea = R[m]; + + WB_WRITE(n, (int16)MemRead(ea)); + END_OP + + + // + // MOV.L @Rm,Rn + // + BEGIN_OP(MOV_L_REGINDIR_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 ea = R[m]; + + WB_WRITE(n, MemRead(ea)); + END_OP + + + // + // MOV.B Rm,@-Rn + // + BEGIN_OP(MOV_B_REG_REGINDIRPD) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 val = R[m]; + uint32 ea; + + R[n] -= 1; + ea = R[n]; + + MemWrite(ea, val); + END_OP + + + // + // MOV.W Rm,@-Rn + // + BEGIN_OP(MOV_W_REG_REGINDIRPD) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 val = R[m]; + uint32 ea; + + R[n] -= 2; + ea = R[n]; + + MemWrite(ea, val); + END_OP + + + // + // MOV.L Rm,@-Rn + // + BEGIN_OP(MOV_L_REG_REGINDIRPD) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 val = R[m]; + uint32 ea; + + R[n] -= 4; + ea = R[n]; + + MemWrite(ea, val); + END_OP + + + // + // MOV.B @Rm+,Rn + // + BEGIN_OP(MOV_B_REGINDIRPI_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + uint32 ea; + + ea = R[m]; + R[m] += 1; + + WB_WRITE(n, (int8)MemRead(ea)); + END_OP + + + // + // MOV.W @Rm+,Rn + // + BEGIN_OP(MOV_W_REGINDIRPI_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + uint32 ea; + + ea = R[m]; + R[m] += 2; + + WB_WRITE(n, (int16)MemRead(ea)); + END_OP + + + // + // MOV.L @Rm+,Rn + // + BEGIN_OP(MOV_L_REGINDIRPI_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + uint32 ea; + + ea = R[m]; + R[m] += 4; + + WB_WRITE(n, MemRead(ea)); + END_OP + + + // + // MOV.B R0,@(disp,Rn) + // + BEGIN_OP(MOV_B_REG0_REGINDIRDISP) + const unsigned n = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + const uint32 ea = R[n] + (d << 0); + + MemWrite(ea, R[0]); + END_OP + + + // + // MOV.W R0,@(disp,Rn) + // + BEGIN_OP(MOV_W_REG0_REGINDIRDISP) + const unsigned n = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + const uint32 ea = R[n] + (d << 1); + + MemWrite(ea, R[0]); + END_OP + + + // + // MOV.L Rm,@(disp,Rn) + // + BEGIN_OP(MOV_L_REG_REGINDIRDISP) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + const uint32 ea = R[n] + (d << 2); + + MemWrite(ea, R[m]); + END_OP + + + // + // MOV.B @(disp,Rm),R0 + // + BEGIN_OP(MOV_B_REGINDIRDISP_REG0) + const unsigned m = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + const uint32 ea = R[m] + (d << 0); + + WB_WRITE(0, (int8)MemRead(ea)); + END_OP + + + // + // MOV.W @(disp,Rm),R0 + // + BEGIN_OP(MOV_W_REGINDIRDISP_REG0) + const unsigned m = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + const uint32 ea = R[m] + (d << 1); + + WB_WRITE(0, (int16)MemRead(ea)); + END_OP + + + // + // MOV.L @(disp,Rm),Rn + // + BEGIN_OP(MOV_L_REGINDIRDISP_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + const uint32 ea = R[m] + (d << 2); + + WB_WRITE(n, MemRead(ea)); + END_OP + + + // + // MOV.B Rm,@(R0,Rn) + // + BEGIN_OP(MOV_B_REG_IDXREGINDIR) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 ea = R[0] + R[n]; + + MemWrite(ea, R[m]); + END_OP + + + // + // MOV.W Rm,@(R0,Rn) + // + BEGIN_OP(MOV_W_REG_IDXREGINDIR) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 ea = R[0] + R[n]; + + MemWrite(ea, R[m]); + END_OP + + + // + // MOV.L Rm,@(R0,Rn) + // + BEGIN_OP(MOV_L_REG_IDXREGINDIR) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 ea = R[0] + R[n]; + + MemWrite(ea, R[m]); + END_OP + + + // + // MOV.B @(R0,Rm),Rn + // + BEGIN_OP(MOV_B_IDXREGINDIR_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 ea = R[0] + R[m]; + + WB_WRITE(n, (int8)MemRead(ea)); + END_OP + + + // + // MOV.W @(R0,Rm),Rn + // + BEGIN_OP(MOV_W_IDXREGINDIR_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 ea = R[0] + R[m]; + + WB_WRITE(n, (int16)MemRead(ea)); + END_OP + + + // + // MOV.L @(R0,Rm),Rn + // + BEGIN_OP(MOV_L_IDXREGINDIR_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 ea = R[0] + R[m]; + + WB_WRITE(n, MemRead(ea)); + END_OP + + + // + // MOV.B R0,@(disp,GBR) + // + BEGIN_OP(MOV_B_REG0_GBRINDIRDISP) + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = GBR + (d << 0); + + MemWrite(ea, R[0]); + END_OP + + + // + // MOV.W R0,@(disp,GBR) + // + BEGIN_OP(MOV_W_REG0_GBRINDIRDISP) + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = GBR + (d << 1); + + MemWrite(ea, R[0]); + END_OP + + + // + // MOV.L R0,@(disp,GBR) + // + BEGIN_OP(MOV_L_REG0_GBRINDIRDISP) + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = GBR + (d << 2); + + MemWrite(ea, R[0]); + END_OP + + + // + // MOV.B @(disp,GBR),R0 + // + BEGIN_OP(MOV_B_GBRINDIRDISP_REG0) + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = GBR + (d << 0); + + WB_WRITE(0, (int8)MemRead(ea)); + END_OP + + + // + // MOV.W @(disp,GBR),R0 + // + BEGIN_OP(MOV_W_GBRINDIRDISP_REG0) + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = GBR + (d << 1); + + WB_WRITE(0, (int16)MemRead(ea)); + END_OP + + + // + // MOV.L @(disp,GBR),R0 + // + BEGIN_OP(MOV_L_GBRINDIRDISP_REG0) + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = GBR + (d << 2); + + WB_WRITE(0, MemRead(ea)); + END_OP + + + // + // MOVA @(disp,PC),R0 + // + BEGIN_OP(MOVA_PCREL_REG0) + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = (PC &~ 0x3) + (d << 2); + + WB_EX_CHECK(0) + + R[0] = ea; + END_OP + + + // + // MOVT Rn + // + BEGIN_OP(MOVT_REG) + const unsigned n = instr_nyb2; + + WB_EX_CHECK(n) + + R[n] = GetT(); + END_OP + + + // + // SWAP.B Rm,Rn + // + BEGIN_OP(SWAP_B_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = (R[m] & 0xFFFF0000) | ((R[m] << 8) & 0xFF00) | ((R[m] >> 8) & 0x00FF); + END_OP + + + // + // SWAP.W Rm,Rn + // + BEGIN_OP(SWAP_W_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = (R[m] << 16) | (R[m] >> 16); + END_OP + + + // + // XTRCT Rm,Rn + // + BEGIN_OP(XTRCT_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = (R[n] >> 16) | (R[m] << 16); + END_OP + + + // + // ADD Rm,Rn + // + BEGIN_OP(ADD_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = R[n] + R[m]; + END_OP + + + // + // ADD #imm,Rn + // + BEGIN_OP(ADD_IMM_REG) + const unsigned n = instr_nyb2; + const uint32 imm = (int8)instr; + + WB_EX_CHECK(n) + + R[n] = R[n] + imm; + END_OP + + + // + // ADDC Rm,Rn + // + BEGIN_OP(ADDC_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint64 result = (uint64)R[n] + R[m] + GetT(); + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = result; + SetT((result >> 32) & 1); + END_OP + + + // + // ADDV Rm,Rn + // + BEGIN_OP(ADDV_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 result = R[n] + R[m]; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + SetT(((~(R[n] ^ R[m])) & (R[n] ^ result)) >> 31); + R[n] = result; + END_OP + + + // + // CMP/EQ #imm,R0 + // + BEGIN_OP(CMP_EQ_IMM_REG0) + const uint32 imm = (int8)instr; + + WB_EX_CHECK(0) + + SetT(imm == R[0]); + END_OP + + + // + // CMP/EQ Rm,Rn + // + BEGIN_OP(CMP_EQ_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + SetT(R[n] == R[m]); + END_OP + + + // + // CMP/HS Rm,Rn + // + BEGIN_OP(CMP_HS_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + SetT(R[n] >= R[m]); + END_OP + + + // + // CMP/GE Rm,Rn + // + BEGIN_OP(CMP_GE_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + SetT((int32)R[n] >= (int32)R[m]); + END_OP + + + // + // CMP/HI Rm,Rn + // + BEGIN_OP(CMP_HI_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + SetT(R[n] > R[m]); + END_OP + + + // + // CMP/GT Rm,Rn + // + BEGIN_OP(CMP_GT_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + SetT((int32)R[n] > (int32)R[m]); + END_OP + + + // + // CMP/PZ Rn + // + BEGIN_OP(CMP_PZ_REG) + const unsigned n = instr_nyb2; + + WB_EX_CHECK(n) + + SetT((int32)R[n] >= 0); + END_OP + + + // + // CMP/PL Rn + // + BEGIN_OP(CMP_PL_REG) + const unsigned n = instr_nyb2; + + WB_EX_CHECK(n) + + SetT((int32)R[n] > 0); + END_OP + + + // + // CMP/STR Rm,Rn + // + BEGIN_OP(CMP_STR_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 tmp = R[n] ^ R[m]; + unsigned new_T = 0; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + if(!(tmp & 0x000000FF)) new_T = 1; + if(!(tmp & 0x0000FF00)) new_T = 1; + if(!(tmp & 0x00FF0000)) new_T = 1; + if(!(tmp & 0xFF000000)) new_T = 1; + + SetT(new_T); + END_OP + + + // + // DIV1 Rm,Rn + // + BEGIN_OP(DIV1_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + uint32 tmp; + bool new_Q; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + new_Q = R[n] >> 31; + R[n] <<= 1; + R[n] |= GetT(); + + tmp = R[n]; + new_Q ^= GetM(); + + if(!(GetQ() ^ GetM())) + { + R[n] -= R[m]; + new_Q ^= (R[n] > tmp); + } + else + { + R[n] += R[m]; + new_Q ^= (R[n] < tmp); + } + + SetQ(new_Q); + SetT(new_Q == GetM()); + END_OP + + + // + // DIV0S Rm,Rn + // + BEGIN_OP(DIV0S_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const unsigned new_Q = R[n] >> 31; + const unsigned new_M = R[m] >> 31; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + SetQ(new_Q); + SetM(new_M); + SetT(new_Q != new_M); + END_OP + + + // + // DIV0U + // + BEGIN_OP(DIV0U) + SetQ(false); + SetM(false); + SetT(false); + END_OP + + + // + // DT + // + BEGIN_OP(DT) + const unsigned n = instr_nyb2; + + WB_EX_CHECK(n) + + R[n]--; + SetT(!R[n]); + END_OP + + + // + // EXTS.B Rm,Rn + // + BEGIN_OP(EXTS_B_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = (int8)R[m]; + END_OP + + + // + // EXTS.W Rm,Rn + // + BEGIN_OP(EXTS_W_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = (int16)R[m]; + END_OP + + + // + // EXTU.B Rm,Rn + // + BEGIN_OP(EXTU_B_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = (uint8)R[m]; + END_OP + + + // + // EXTU.W Rm,Rn + // + BEGIN_OP(EXTU_W_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = (uint16)R[m]; + END_OP + + + // + // MAC.L @Rm+,@Rn+ + // + // Pipeline: page 188(not implemented right here) + BEGIN_OP(MAC_L) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + uint64 a, b, sum; + int32 m0, m1; + + // Order confirmed. + m0 = (int32)MemRead(R[m]); + R[m] += 4; + m1 = (int32)MemRead(R[n]); + R[n] += 4; + + a = GetMAC64(); + b = (int64)m0 * m1; + sum = a + b; + + if(GetS() && sum > 0x00007FFFFFFFFFFFULL && sum < 0xFFFF800000000000ULL) + { + if((int64)b < 0) + sum = 0xFFFF800000000000ULL; + else + sum = 0x00007FFFFFFFFFFFULL; + } + + SetMAC64(sum); + + timestamp++; + END_OP + + + // + // MAC.W @Rm+,@Rn+ + // + // Pipeline: page 180(not implemented right here) + BEGIN_OP(MAC_W) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + int16 m0, m1; + + // Order confirmed. + m0 = (int16)MemRead(R[m]); + R[m] += 2; + m1 = (int16)MemRead(R[n]); + R[n] += 2; + + if(GetS()) + { + int32 b = (int32)m0 * m1; + uint64 sum = (int64)(int32)MACL + b; + + if(sum > 0x000000007FFFFFFFULL && sum < 0xFFFFFFFF80000000ULL) + { + MACH |= 1; + + if(b < 0) + sum = 0x80000000ULL; + else + sum = 0x7FFFFFFFULL; + } + + MACL = sum; + } + else + SetMAC64(GetMAC64() + (int64)m0 * m1); + + timestamp++; + END_OP + + + // + // DMULS.L Rm,Rn + // + // Pipeline: page 215 (not implemented here totally correctly) + BEGIN_OP_DLYIDIF(DMULS_L_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint64 result = (int64)(int32)R[n] * (int32)R[m]; + + timestamp++; + + MA_until = std::max(std::max(MA_until, MM_until), timestamp + 1); + MM_until = MA_until + 4; + PART_OP_NORMIDIF + + MACL = result >> 0; + MACH = result >> 32; + END_OP + + + // + // DMULU.L Rm,Rn + // + // Pipeline: page 215 (not implemented here totally correctly) + BEGIN_OP_DLYIDIF(DMULU_L_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint64 result = (uint64)R[n] * R[m]; + + timestamp++; + + MA_until = std::max(std::max(MA_until, MM_until), timestamp + 1); + MM_until = MA_until + 4; + PART_OP_NORMIDIF + + MACL = result >> 0; + MACH = result >> 32; + END_OP + + + // + // MUL.L Rm,Rn + // + // Pipeline: page 215 (not implemented here totally correctly) + BEGIN_OP_DLYIDIF(MUL_L_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + timestamp++; + + MA_until = std::max(std::max(MA_until, MM_until), timestamp + 1); + MM_until = MA_until + 4; + PART_OP_NORMIDIF + + MACL = R[n] * R[m]; + END_OP + + + // + // MULS.W Rm,Rn + // + // Pipeline: page 207 + BEGIN_OP(MULS_W_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + MA_until = std::max(std::max(MA_until, MM_until), timestamp + 1); + MM_until = MA_until + 2; + + MACL = (int16)R[n] * (int16)R[m]; + END_OP + + + // + // MULU.W Rm,Rn + // + // Pipeline: page 207 + BEGIN_OP(MULU_W_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + MA_until = std::max(std::max(MA_until, MM_until), timestamp + 1); + MM_until = MA_until + 2; + + MACL = (uint32)(uint16)R[n] * (uint32)(uint16)R[m]; + END_OP + + + // + // NEG Rm,Rn + // + BEGIN_OP(NEG_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = -R[m]; + END_OP + + + // + // NEGC Rm,Rn + // + BEGIN_OP(NEGC_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint64 result = (uint64)0 - R[m] - GetT(); + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = result; + SetT((result >> 32) & 1); + END_OP + + + // + // SUB Rm,Rn + // + BEGIN_OP(SUB_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = R[n] - R[m]; + END_OP + + + // + // SUBC Rm,Rn + // + BEGIN_OP(SUBC_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint64 result = (uint64)R[n] - R[m] - GetT(); + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = result; + SetT((result >> 32) & 1); + END_OP + + + // + // SUBV Rm,Rn + // + BEGIN_OP(SUBV_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const uint32 result = R[n] - R[m]; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + SetT((((R[n] ^ R[m])) & (R[n] ^ result)) >> 31); + R[n] = result; + END_OP + + + // + // AND Rm,Rn + // + BEGIN_OP(AND_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = R[n] & R[m]; + END_OP + + + // + // AND #imm,R0 + // + BEGIN_OP(AND_IMM_REG0) + const unsigned imm = (uint8)instr; + + WB_EX_CHECK(0) + + R[0] = R[0] & imm; + END_OP + + + // + // AND.B #imm,@(R0,GBR) + // + BEGIN_OP(AND_B_IMM_IDXGBRINDIR) + const unsigned imm = (uint8)instr; + const uint32 ea = R[0] + GBR; + uint32 tmp; + + tmp = MemRead(ea); + timestamp++; + tmp &= imm; + MemWrite(ea, tmp); + timestamp++; + END_OP + + + // + // NOT Rm,Rn + // + BEGIN_OP(NOT_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = ~R[m]; + END_OP + + + // + // OR Rm,Rn + // + BEGIN_OP(OR_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] |= R[m]; + END_OP + + + // + // OR #imm,R0 + // + BEGIN_OP(OR_IMM_REG0) + const unsigned imm = (uint8)instr; + + WB_EX_CHECK(0) + + R[0] |= imm; + END_OP + + + // + // OR.B #imm,@(R0,GBR) + // + BEGIN_OP(OR_B_IMM_IDXGBRINDIR) + const unsigned imm = (uint8)instr; + const uint32 ea = R[0] + GBR; + uint32 tmp; + + tmp = MemRead(ea); + timestamp++; + tmp |= imm; + MemWrite(ea, tmp); + timestamp++; + END_OP + + + // + // TAS.B @Rn + // + BEGIN_OP(TAS_B_REGINDIR) + const unsigned n = instr_nyb2; + const uint32 ea = R[n]; + uint8 tmp; + + SH7095_BusLock++; + tmp = ExtBusRead(ea); // FIXME: Address error on invalid address(>= 0x40000000 ?). + timestamp = SH7095_mem_timestamp; + + SetT(!tmp); + + tmp |= 0x80; + + MemWrite(ea, tmp); + SH7095_BusLock--; + + timestamp += 3; + END_OP + + + // + // TST Rm,Rn + // + BEGIN_OP(TST_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + SetT(!(R[n] & R[m])); + END_OP + + + // + // TST #imm,R0 + // + BEGIN_OP(TST_IMM_REG0) + const unsigned imm = (uint8)instr; + + WB_EX_CHECK(0) + + SetT(!(R[0] & imm)); + END_OP + + + // + // TST.B #imm,@(R0,GBR) + // + BEGIN_OP(TST_B_IMM_IDXGBRINDIR) + const unsigned imm = (uint8)instr; + const uint32 ea = R[0] + GBR; + uint32 tmp; + + tmp = MemRead(ea); + timestamp++; + SetT(!(tmp & imm)); + timestamp++; + END_OP + + + // + // XOR Rm,Rn + // + BEGIN_OP(XOR_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + WB_EX_CHECK(n) + WB_EX_CHECK(m) + + R[n] = R[n] ^ R[m]; + END_OP + + + // + // XOR #imm,R0 + // + BEGIN_OP(XOR_IMM_REG0) + const unsigned imm = (uint8)instr; + + WB_EX_CHECK(0) + + R[0] = R[0] ^ imm; + END_OP + + + // + // XOR.B #imm,@(R0,GBR) + // + BEGIN_OP(XOR_B_IMM_IDXGBRINDIR) + const unsigned imm = (uint8)instr; + const uint32 ea = R[0] + GBR; + uint32 tmp; + + tmp = MemRead(ea); + timestamp++; + tmp ^= imm; + MemWrite(ea, tmp); + timestamp++; + END_OP + + + // + // ROTL Rn + // + BEGIN_OP(ROTL_REG) + const unsigned n = instr_nyb2; + const unsigned rotbit = R[n] >> 31; + + WB_EX_CHECK(n) + + R[n] = (R[n] << 1) | rotbit; + SetT(rotbit); + END_OP + + + // + // ROTR Rn + // + BEGIN_OP(ROTR_REG) + const unsigned n = instr_nyb2; + const unsigned rotbit = R[n] & 1; + + WB_EX_CHECK(n) + + R[n] = (R[n] >> 1) | (rotbit << 31); + SetT(rotbit); + END_OP + + + // + // ROTCL Rn + // + BEGIN_OP(ROTCL_REG) + const unsigned n = instr_nyb2; + const unsigned rotbit = R[n] >> 31; + + WB_EX_CHECK(n) + + R[n] = (R[n] << 1) | GetT(); + SetT(rotbit); + END_OP + + + // + // ROTCR Rn + // + BEGIN_OP(ROTCR_REG) + const unsigned n = instr_nyb2; + const unsigned rotbit = R[n] & 1; + + WB_EX_CHECK(n) + + R[n] = (R[n] >> 1) | (GetT() << 31); + SetT(rotbit); + END_OP + + + // + // SHAR Rn + // + BEGIN_OP(SHAR_REG) + const unsigned n = instr_nyb2; + const unsigned shbit = R[n] & 1; + + WB_EX_CHECK(n) + + R[n] = (int32)R[n] >> 1; + SetT(shbit); + END_OP + + + // + // SHLL Rn + // + BEGIN_OP(SHLL_REG) + const unsigned n = instr_nyb2; + const unsigned shbit = R[n] >> 31; + + WB_EX_CHECK(n) + + R[n] <<= 1; + SetT(shbit); + END_OP + + + // + // SHLR Rn + // + BEGIN_OP(SHLR_REG) + const unsigned n = instr_nyb2; + const unsigned shbit = R[n] & 1; + + WB_EX_CHECK(n) + + R[n] >>= 1; + SetT(shbit); + END_OP + + + // + // SHLL2 Rn + // + BEGIN_OP(SHLL2_REG) + const unsigned n = instr_nyb2; + + WB_EX_CHECK(n) + + R[n] <<= 2; + END_OP + + + // + // SHLR2 Rn + // + BEGIN_OP(SHLR2_REG) + const unsigned n = instr_nyb2; + + WB_EX_CHECK(n) + + R[n] >>= 2; + END_OP + + + // + // SHLL8 Rn + // + BEGIN_OP(SHLL8_REG) + const unsigned n = instr_nyb2; + + WB_EX_CHECK(n) + + R[n] <<= 8; + END_OP + + + // + // SHLR8 Rn + // + BEGIN_OP(SHLR8_REG) + const unsigned n = instr_nyb2; + + WB_EX_CHECK(n) + + R[n] >>= 8; + END_OP + + + // + // SHLL16 Rn + // + BEGIN_OP(SHLL16_REG) + const unsigned n = instr_nyb2; + + WB_EX_CHECK(n) + + R[n] <<= 16; + END_OP + + + // + // SHLR16 Rn + // + BEGIN_OP(SHLR16_REG) + const unsigned n = instr_nyb2; + + WB_EX_CHECK(n) + + R[n] >>= 16; + END_OP + + + // + // BF + // + BEGIN_OP(BF) + CondRelBranch(!GetT(), (uint32)(int8)instr << 1); + END_OP + + + // + // BF/S + // + BEGIN_OP(BF_S) + CondRelBranch(!GetT(), (uint32)(int8)instr << 1); + END_OP + + + // + // BT + // + BEGIN_OP(BT) + CondRelBranch(GetT(), (uint32)(int8)instr << 1); + END_OP + + + // + // BT/S + // + BEGIN_OP(BT_S) + CondRelBranch(GetT(), (uint32)(int8)instr << 1); + END_OP + + + // + // BRA + // + BEGIN_OP_DLYIDIF(BRA) + UCRelDelayBranch((uint32)sign_x_to_s32(12, instr) << 1); + END_OP + + + // + // BRAF Rm + // + BEGIN_OP_DLYIDIF(BRAF_REG) + const unsigned m = instr_nyb2; + + UCRelDelayBranch(R[m]); + END_OP + + + // + // BSR + // + BEGIN_OP_DLYIDIF(BSR) + PR = PC; + + UCRelDelayBranch((uint32)sign_x_to_s32(12, instr) << 1); + END_OP + + + // + // BSRF Rm + // + BEGIN_OP_DLYIDIF(BSRF_REG) + const unsigned m = instr_nyb2; + + PR = PC; + + UCRelDelayBranch(R[m]); + END_OP + + + // + // JMP @Rm + // + BEGIN_OP_DLYIDIF(JMP_REGINDIR) + const unsigned m = instr_nyb2; + + UCDelayBranch(R[m]); + END_OP + + + // + // JSR @Rm + // + BEGIN_OP_DLYIDIF(JSR_REGINDIR) + const unsigned m = instr_nyb2; + + PR = PC; + + UCDelayBranch(R[m]); + END_OP + + + // + // RTS + // + BEGIN_OP_DLYIDIF(RTS) + UCDelayBranch(PR); + END_OP + + + // + // CLRT + // + BEGIN_OP(CLRT) + SetT(false); + END_OP + + + // + // CLRMAC + // + BEGIN_OP(CLRMAC) + MACH = 0; + MACL = 0; + END_OP + + + // + // LDC + // + BEGIN_OP_DLYIDIF(LDC) + const unsigned m = instr_nyb2; + const unsigned cri = (instr >> 4) & 0x3; + + CtrlRegs[cri] = R[m]; + if(cri == 0) + { + SR &= 0x3F3; + RecalcPendingIntPEX(); + } + PART_OP_INTDIS + END_OP + + // + // LDC.L + // + // Pipeline: page 233 + // + BEGIN_OP_DLYIDIF(LDC_L) + const unsigned m = instr_nyb2; + const unsigned cri = (instr >> 4) & 0x3; + uint32 ea; + + ea = R[m]; + R[m] += 4; + + timestamp++; + CtrlRegs[cri] = MemRead(ea); + if(cri == 0) + { + SR &= 0x3F3; + RecalcPendingIntPEX(); + } + + timestamp++; + PART_OP_INTDIS + END_OP + + + // + // LDS + // + BEGIN_OP_DLYIDIF(LDS) + const unsigned m = instr_nyb2; + const unsigned sri = (instr >> 4) & 0x3; + + SysRegs[sri] = R[m]; + PART_OP_INTDIS + END_OP + + + // + // LDS.L + // + BEGIN_OP_DLYIDIF(LDS_L) // Pipeline same as ordinary load instruction + const unsigned m = instr_nyb2; + const unsigned sri = (instr >> 4) & 0x3; + uint32 ea; + + ea = R[m]; + R[m] += 4; + + PART_OP_INTDIS + + SysRegs[sri] = MemRead(ea); + //printf(" LDS.L: (0x%08x)->0x%08x\n", ea, SysRegs[sri]); + END_OP + + + // + // NOP + // + BEGIN_OP(NOP) + END_OP + + + // + // RTE + // + // Pipeline: page 241 + // + BEGIN_OP(RTE) + uint32 new_PC; + + new_PC = MemRead(R[15]); + R[15] += 4; + + SR = MemRead(R[15]); + RecalcPendingIntPEX(); + R[15] += 4; + + timestamp++; + + Branch(new_PC); + END_OP + + + // + // SETT + // + BEGIN_OP(SETT) + SetT(true); + END_OP + + + // + // SLEEP + // + BEGIN_OP_DLYIDIF(SLEEP) + // + // Standby mode time yay? + // + if(MDFN_UNLIKELY(SBYCR & 0x80)) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Entering standby mode.\n", cpu_name); + + for(unsigned ch = 0; ch < 2; ch++) + { + DMACH[ch].CHCR = 0x00; + DMACH[ch].CHCRM = 0x00; + } + DMAOR = 0x00; + RecalcPendingIntPEX(); + // + // + FRT_Reset(); + // + // + WDT_StandbyReset(); + // + // + + timestamp++; + Pipe_ID = (Pipe_ID & 0x00FFFFFF) | (0x7E << 24); + + Standby = true; + + return; + } + + if(MDFN_LIKELY(!EPending)) + { + timestamp += 3; + return; + } + else + { + DoIDIF(); + } + END_OP + + BEGIN_OP_DLYIDIF(PSEUDO_STANDBY) + if(MDFN_LIKELY(Standby)) + { + timestamp += 7; + return; + } + else + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Exiting standby mode.\n", cpu_name); + + FRT_Reset(); // Reset again(for the counter) because we didn't stop clocking it. + + DoIDIF(); + } + END_OP + + // + // STC + // + BEGIN_OP_DLYIDIF(STC) + const unsigned n = instr_nyb2; + const unsigned cri = (instr >> 4) & 0x3; + + R[n] = CtrlRegs[cri]; + PART_OP_INTDIS + END_OP + + + // + // STC.L + // + // pipeline: page 234 + BEGIN_OP_DLYIDIF(STC_L) + const unsigned n = instr_nyb2; + const unsigned cri = (instr >> 4) & 0x3; + uint32 ea; + + R[n] -= 4; + ea = R[n]; + + MemWrite(ea, CtrlRegs[cri]); + timestamp++; + PART_OP_INTDIS + END_OP + + + // + // STS + // + BEGIN_OP_DLYIDIF(STS) + const unsigned n = instr_nyb2; + const unsigned sri = (instr >> 4) & 0x3; + + R[n] = SysRegs[sri]; + PART_OP_INTDIS + END_OP + + + // + // STS.L + // + BEGIN_OP_DLYIDIF(STS_L) // Pipeline same as ordinary store instruction + const unsigned n = instr_nyb2; + const unsigned sri = (instr >> 4) & 0x3; + uint32 ea; + + R[n] -= 4; + ea = R[n]; + + //printf(" STS.L: 0x%08x->(0x%08x)\n", SysRegs[sri], ea); + + MemWrite(ea, SysRegs[sri]); + + PART_OP_INTDIS + END_OP + + + // + // TRAPA #imm + // + // Saved PC is the address of the instruction after the TRAPA instruction + // + BEGIN_OP_DLYIDIF(TRAPA) + const unsigned imm = (uint8)instr; + + PC -= 2; + Branch(Exception(EXCEPTION_TRAP, imm)); + END_OP + + + /* + ** + ** + */ + // + // Illegal Instruction + // + // Saved PC is the address of the illegal instruction. + // + BEGIN_OP_DLYIDIF(ILLEGAL) + PC -= 4; + Branch(Exception(EXCEPTION_ILLINSTR, VECNUM_ILLINSTR)); + END_OP + + // + // Illegal Slot Instruction + // + // Saved PC is the effective target address of the jump. + // + BEGIN_OP_DLYIDIF(SLOT_ILLEGAL) + PC -= 2; + Branch(Exception(EXCEPTION_ILLSLOT, VECNUM_ILLSLOT)); + END_OP + + // + // Pending exception(address error/interrupt) + // + BEGIN_OP_DLYIDIF(PSEUDO_EPENDING) + uint32 new_PC = 0; + + // + // Priority here(listed highest to lowest): + // External halt + // Power + // Reset + // Pseudo DMA burst(hacky abusey thing to stall the CPU, should be above everything but reset/power and ext halt otherwise kaboom!). + // CPU address error + // DMA address error + // NMI + // Interrupt (final else, may be called quasi-spuriously) + // + #define TPP(x) (Pipe_ID & (1U << ((x) + EPENDING_PEXBITS_SHIFT))) + // + // Test against Pipe_ID, reset bits in EPending(if appropriate). + // + if(MDFN_UNLIKELY(TPP(PEX_PSEUDO_EXTHALT))) + { + //SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Ext halt begin: Pipe_ID=0x%08x PC=0x%08x\n", cpu_name, Pipe_ID, PC); + Pipe_ID = (Pipe_ID & 0x00FFFFFF) | (0xFE << 24); + return; + } + else if(MDFN_UNLIKELY(TPP(PEX_POWERON) || TPP(PEX_RESET))) + { + if(TPP(PEX_POWERON)) + { + EPending = 0; + new_PC = Exception(EXCEPTION_POWERON, VECNUM_POWERON); + } + else + { + EPending = 0; + new_PC = Exception(EXCEPTION_RESET, VECNUM_RESET); + } + } + else if(MDFN_UNLIKELY(TPP(PEX_PSEUDO_DMABURST))) + { + //SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Burst begin: Pipe_ID=0x%08x PC=0x%08x\n", cpu_name, Pipe_ID, PC); + Pipe_ID = (Pipe_ID & 0x00FFFFFF) | (0xFE << 24); + return; + } + else if(MDFN_UNLIKELY(TPP(PEX_CPUADDR))) + { + PC -= 4; + ClearPEX(PEX_CPUADDR); + new_PC = Exception(EXCEPTION_CPUADDR, VECNUM_CPUADDR); + ClearPEX(PEX_CPUADDR); // Infinite recursive address errors are not good(stack wraparound could clobber backup memory). + } + else if(MDFN_UNLIKELY(TPP(PEX_DMAADDR))) + { + PC -= 4; + ClearPEX(PEX_DMAADDR); + new_PC = Exception(EXCEPTION_DMAADDR, VECNUM_DMAADDR); + } + else if(TPP(PEX_NMI)) + { + PC -= 4; + ClearPEX(PEX_NMI); + new_PC = Exception(EXCEPTION_NMI, VECNUM_NMI); + // + // + // + SR |= 0xF << 4; + RecalcPendingIntPEX(); + } + else // Int + { + uint8 ipr; + + ipr = GetPendingInt(NULL); + + if(MDFN_LIKELY(ipr > ((SR >> 4) & 0xF))) + { + uint8 vecnum; + + // Note: GetPendingInt() may call ExIVecFetch(), which may call SetIRL with a new value, so be + // careful to use the "old" value here. + GetPendingInt(&vecnum); + + PC -= 4; + new_PC = Exception(EXCEPTION_INT, vecnum); + // + // + // + SR &= ~(0xF << 4); + SR |= ipr << 4; + RecalcPendingIntPEX(); + } + else + { + // + // Can happen like so(note for future testing): + // + // (WDT interval timer IRQ pending here) + // + // WTCSR_R; + // asm volatile( + // "ldc %0,SR\n\t" + // "mov.w %2, @%1\n\t" + // : + // :"r"(0), "r"(0xFFFFFE88), "r"(0xA500 | 0x00) + // : "memory"); + // + SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Spurious EPENDING. IPR=0x%02x SR=0x%04x EPending=0x%08x Pipe_ID=0x%08x PC=0x%08x\n", cpu_name, ipr, SR, EPending, Pipe_ID, PC); + + Pipe_ID = (uint16)Pipe_ID; + Pipe_ID |= InstrDecodeTab[Pipe_ID] << 24; + goto SPEPRecover; + } + } + // + // + // + Branch(new_PC); + END_OP + + BEGIN_OP_DLYIDIF(PSEUDO_DMABURST) + if(MDFN_LIKELY(DMA_InBurst() || ExtHalt)) + { + timestamp += 7; + return; + } + else + { + ClearPEX(PEX_PSEUDO_DMABURST); + ClearPEX(PEX_PSEUDO_EXTHALT); + + // + // Recover Pipe_ID opcode field; only use Pipe_ID for this, not EPending, otherwise + // we may accidentally allow an interrupt to occur immediately after an interrupt-disabled instruction. + // + Pipe_ID &= 0x00FFFFFF; + Pipe_ID &= ~(1U << (PEX_PSEUDO_DMABURST + EPENDING_PEXBITS_SHIFT)); + Pipe_ID &= ~(1U << (PEX_PSEUDO_EXTHALT + EPENDING_PEXBITS_SHIFT)); + Pipe_ID |= InstrDecodeTab[(uint16)Pipe_ID] << 24; + if(Pipe_ID & (0xFF << EPENDING_PEXBITS_SHIFT)) + Pipe_ID |= EPENDING_OP_OR; + + //SS_DBG(SS_DBG_WARNING | SS_DBG_SH2, "[%s] Burst/External halt end: Pipe_ID=0x%08x PC=0x%08x\n", cpu_name, Pipe_ID, PC); + return; + } + END_OP + + + #undef BEGIN_OP + #undef BEGIN_OP_DLYIDIF + #undef END_OP + } + + PC += 2; +} + +// +// +// +// +// +// +// +// + +INLINE uint32 SH7095::GetRegister(const unsigned id, char* const special, const uint32 special_len) +{ + uint32 ret = 0xDEADBEEF; + + switch(id) + { + case GSREG_PC_ID: + ret = PC_ID; + break; + + case GSREG_PC_IF: + ret = PC_IF; + break; + + case GSREG_PID: + ret = Pipe_ID; + break; + + case GSREG_PIF: + ret = Pipe_IF; + break; + + case GSREG_EP: + ret = EPending; + break; + + case GSREG_RPC: + ret = PC; + break; + + case GSREG_R0: case GSREG_R1: case GSREG_R2: case GSREG_R3: case GSREG_R4: case GSREG_R5: case GSREG_R6: case GSREG_R7: + case GSREG_R8: case GSREG_R9: case GSREG_R10: case GSREG_R11: case GSREG_R12: case GSREG_R13: case GSREG_R14: case GSREG_R15: + ret = R[id - GSREG_R0]; + break; + + case GSREG_SR: + ret = SR; + break; + + case GSREG_GBR: + ret = GBR; + break; + + case GSREG_VBR: + ret = VBR; + break; + + case GSREG_MACH: + ret = MACH; + break; + + case GSREG_MACL: + ret = MACL; + break; + + case GSREG_PR: + ret = PR; + break; + + // + // + // + case GSREG_NMIL: + ret = NMILevel; + break; + + case GSREG_IRL: + ret = IRL; + break; + + case GSREG_IPRA: + ret = IPRA; + break; + + case GSREG_IPRB: + ret = IPRB; + break; + + case GSREG_VCRWDT: + ret = VCRWDT; + break; + + case GSREG_VCRA: + ret = VCRA; + break; + + case GSREG_VCRB: + ret = VCRB; + break; + + case GSREG_VCRC: + ret = VCRC; + if(special) + { + trio_snprintf(special, special_len, "FIC: 0x%02x, FOC: 0x%02x", (ret >> 8) & 0x7F, ret & 0x7F); + } + break; + + case GSREG_VCRD: + ret = VCRD; + break; + + case GSREG_ICR: + ret = ICR; + break; + // + // + // + case GSREG_DVSR: + ret = DVSR; + break; + + case GSREG_DVDNT: + ret = DVDNT; + break; + + case GSREG_DVDNTH: + ret = DVDNTH; + break; + + case GSREG_DVDNTL: + ret = DVDNTL; + break; + + case GSREG_DVDNTHS: + ret = DVDNTH_Shadow; + break; + + case GSREG_DVDNTLS: + ret = DVDNTL_Shadow; + break; + + case GSREG_VCRDIV: + ret = VCRDIV; + break; + + case GSREG_DVCR: + ret = DVCR; + break; + // + // + // + case GSREG_WTCSR: + ret = WDT.WTCSR; + break; + + case GSREG_WTCSRM: + ret = WDT.WTCSRM; + break; + + case GSREG_WTCNT: + ret = WDT.WTCNT; + break; + + case GSREG_RSTCSR: + ret = WDT.RSTCSR; + break; + + case GSREG_RSTCSRM: + ret = WDT.RSTCSRM; + break; + // + // + // + case GSREG_DMAOR: + ret = DMAOR; + break; + + case GSREG_DMAORM: + ret = DMAORM; + break; + + case GSREG_DMA0_SAR: + case GSREG_DMA1_SAR: + ret = DMACH[id == GSREG_DMA1_SAR].SAR; + break; + + case GSREG_DMA0_DAR: + case GSREG_DMA1_DAR: + ret = DMACH[id == GSREG_DMA1_DAR].DAR; + break; + + case GSREG_DMA0_TCR: + case GSREG_DMA1_TCR: + ret = DMACH[id == GSREG_DMA1_TCR].TCR; + break; + + case GSREG_DMA0_CHCR: + case GSREG_DMA1_CHCR: + ret = DMACH[id == GSREG_DMA1_CHCR].CHCR; + break; + + case GSREG_DMA0_CHCRM: + case GSREG_DMA1_CHCRM: + ret = DMACH[id == GSREG_DMA1_CHCRM].CHCRM; + break; + + case GSREG_DMA0_VCR: + case GSREG_DMA1_VCR: + ret = DMACH[id == GSREG_DMA1_VCR].VCR; + break; + + case GSREG_DMA0_DRCR: + case GSREG_DMA1_DRCR: + ret = DMACH[id == GSREG_DMA1_DRCR].DRCR; + break; + // + // + // + case GSREG_FRC: + ret = FRT.FRC; + break; + + case GSREG_OCR0: + ret = FRT.OCR[0]; + break; + + case GSREG_OCR1: + ret = FRT.OCR[1]; + break; + + case GSREG_FICR: + ret = FRT.FICR; + break; + + case GSREG_TIER: + ret = FRT.TIER; + break; + + case GSREG_FTCSR: + ret = FRT.FTCSR; + break; + + case GSREG_FTCSRM: + ret = FRT.FTCSRM; + break; + + case GSREG_TCR: + ret = FRT.TCR; + break; + + case GSREG_TOCR: + ret = FRT.TOCR; + break; + + case GSREG_RWT: + ret = FRT.RW_Temp; + break; + } + + return ret; +} + +void SH7095::SetRegister(const unsigned id, const uint32 value) +{ + switch(id) + { + //case GSREG_PC: break; + + case GSREG_PID: + Pipe_ID = value; + break; + + case GSREG_PIF: + Pipe_IF = value; + break; + + //case GSREG_EP: + // EPending = value; + // break; + + case GSREG_RPC: + PC = value; + break; + + case GSREG_R0: case GSREG_R1: case GSREG_R2: case GSREG_R3: case GSREG_R4: case GSREG_R5: case GSREG_R6: case GSREG_R7: + case GSREG_R8: case GSREG_R9: case GSREG_R10: case GSREG_R11: case GSREG_R12: case GSREG_R13: case GSREG_R14: case GSREG_R15: + R[id - GSREG_R0] = value; + break; + + case GSREG_SR: + SR = value & 0x3F3; + RecalcPendingIntPEX(); + break; + + case GSREG_GBR: + GBR = value; + break; + + case GSREG_VBR: + VBR = value; + break; + + case GSREG_MACH: + MACH = value; + break; + + case GSREG_MACL: + MACL = value; + break; + + case GSREG_PR: + PR = value; + break; + + // + // + // + case GSREG_FTCSR: + FRT.FTCSR = value & 0x8F; + RecalcPendingIntPEX(); + FRT_CheckOCR(); + break; + + case GSREG_FTCSRM: + FRT.FTCSRM = value & 0x8F; + break; + } +} + +// +// +// +// +// +// +// +void MDFN_COLD SH7095::Disassemble(const uint16 instr, const uint32 PC, char* buffer, uint16 (*DisPeek16)(uint32), uint32 (*DisPeek32)(uint32)) +{ + static const char* CR_Names[3] = { "SR", "GBR", "VBR" }; + static const char* SR_Names[3] = { "MACH", "MACL", "PR" }; + const unsigned instr_nyb1 = (instr >> 4) & 0xF; + const unsigned instr_nyb2 = (instr >> 8) & 0xF; + + switch(InstrDecodeTab[instr]) + { + #define BEGIN_DIS_OP(x) OP_##x { + #define END_DIS_OP } break; + + default: + trio_sprintf(buffer, ".word 0x%04x", instr); + break; + + // + // MOV #imm,Rn + // + BEGIN_DIS_OP(MOV_IMM_REG) + const unsigned n = instr_nyb2; + const int32 imm = (int8)instr; + + trio_sprintf(buffer, "MOV #%d,R%u", imm, n); + END_DIS_OP + + + // + // MOV.W @(disp,PC),Rn + // + BEGIN_DIS_OP(MOV_W_PCREL_REG) + const unsigned n = instr_nyb2; + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = PC + (d << 1); + + trio_sprintf(buffer, "MOV.W @(0x%03x,PC),R%u ! 0x%04x", (d << 1), n, DisPeek16(ea)); + END_DIS_OP + + + // + // MOV.L @(disp,PC),Rn + // + BEGIN_DIS_OP(MOV_L_PCREL_REG) + const unsigned n = instr_nyb2; + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = (PC &~ 0x3) + (d << 2); + + trio_sprintf(buffer, "MOV.L @(0x%03x,PC),R%u ! 0x%08x", (d << 2), n, DisPeek32(ea)); + END_DIS_OP + + + // + // MOV Rm,Rn + // + BEGIN_DIS_OP(MOV_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV R%u,R%u", m, n); + END_DIS_OP + + + // + // MOV.B Rm,@Rn + // + BEGIN_DIS_OP(MOV_B_REG_REGINDIR) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.B R%u,@R%u", m, n); + END_DIS_OP + + + // + // MOV.W Rm,@Rn + // + BEGIN_DIS_OP(MOV_W_REG_REGINDIR) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.W R%u,@R%u", m, n); + END_DIS_OP + + + // + // MOV.L Rm,@Rn + // + BEGIN_DIS_OP(MOV_L_REG_REGINDIR) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.L R%u,@R%u", m, n); + END_DIS_OP + + + // + // MOV.B @Rm,Rn + // + BEGIN_DIS_OP(MOV_B_REGINDIR_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.B @R%u,R%u", m, n); + END_DIS_OP + + + // + // MOV.W @Rm,Rn + // + BEGIN_DIS_OP(MOV_W_REGINDIR_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.W @R%u,R%u", m, n); + END_DIS_OP + + + // + // MOV.L @Rm,Rn + // + BEGIN_DIS_OP(MOV_L_REGINDIR_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.L @R%u,R%u", m, n); + END_DIS_OP + + + // + // MOV.B Rm,@-Rn + // + BEGIN_DIS_OP(MOV_B_REG_REGINDIRPD) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.B R%u,@-R%u", m, n); + END_DIS_OP + + + // + // MOV.W Rm,@-Rn + // + BEGIN_DIS_OP(MOV_W_REG_REGINDIRPD) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.W R%u,@-R%u", m, n); + END_DIS_OP + + + // + // MOV.L Rm,@-Rn + // + BEGIN_DIS_OP(MOV_L_REG_REGINDIRPD) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.L R%u,@-R%u", m, n); + END_DIS_OP + + + // + // MOV.B @Rm+,Rn + // + BEGIN_DIS_OP(MOV_B_REGINDIRPI_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.B @R%u+,R%u", m, n); + END_DIS_OP + + + // + // MOV.W @Rm+,Rn + // + BEGIN_DIS_OP(MOV_W_REGINDIRPI_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.W @R%u+,R%u", m, n); + END_DIS_OP + + + // + // MOV.L @Rm+,Rn + // + BEGIN_DIS_OP(MOV_L_REGINDIRPI_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.L @R%u+,R%u", m, n); + END_DIS_OP + + + // + // MOV.B R0,@(disp,Rn) + // + BEGIN_DIS_OP(MOV_B_REG0_REGINDIRDISP) + const unsigned n = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + + trio_sprintf(buffer, "MOV.B R0,@(%u,R%u)", (d << 0), n); + END_DIS_OP + + + // + // MOV.W R0,@(disp,Rn) + // + BEGIN_DIS_OP(MOV_W_REG0_REGINDIRDISP) + const unsigned n = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + + trio_sprintf(buffer, "MOV.W R0,@(%u,R%u)", (d << 1), n); + END_DIS_OP + + + // + // MOV.L Rm,@(disp,Rn) + // + BEGIN_DIS_OP(MOV_L_REG_REGINDIRDISP) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + + trio_sprintf(buffer, "MOV.L R%u,@(%u,R%u)", m, (d << 2), n); + END_DIS_OP + + + // + // MOV.B @(disp,Rm),R0 + // + BEGIN_DIS_OP(MOV_B_REGINDIRDISP_REG0) + const unsigned m = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + + trio_sprintf(buffer, "MOV.B @(%u,R%u),R0", (d << 0), m); + END_DIS_OP + + + // + // MOV.W @(disp,Rm),R0 + // + BEGIN_DIS_OP(MOV_W_REGINDIRDISP_REG0) + const unsigned m = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + + trio_sprintf(buffer, "MOV.W @(%u,R%u),R0", (d << 1), m); + END_DIS_OP + + + // + // MOV.L @(disp,Rm),Rn + // + BEGIN_DIS_OP(MOV_L_REGINDIRDISP_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + + trio_sprintf(buffer, "MOV.L @(%u,R%u),R%u", (d << 2), m, n); + END_DIS_OP + + + // + // MOV.B Rm,@(R0,Rn) + // + BEGIN_DIS_OP(MOV_B_REG_IDXREGINDIR) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.B R%u,@(R0,R%u)", m, n); + END_DIS_OP + + + // + // MOV.W Rm,@(R0,Rn) + // + BEGIN_DIS_OP(MOV_W_REG_IDXREGINDIR) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.W R%u,@(R0,R%u)", m, n); + END_DIS_OP + + + // + // MOV.L Rm,@(R0,Rn) + // + BEGIN_DIS_OP(MOV_L_REG_IDXREGINDIR) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.L R%u,@(R0,R%u)", m, n); + END_DIS_OP + + + // + // MOV.B @(R0,Rm),Rn + // + BEGIN_DIS_OP(MOV_B_IDXREGINDIR_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.B @(R0,R%u),R%u", m, n); + END_DIS_OP + + + // + // MOV.W @(R0,Rm),Rn + // + BEGIN_DIS_OP(MOV_W_IDXREGINDIR_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.W @(R0,R%u),R%u", m, n); + END_DIS_OP + + + // + // MOV.L @(R0,Rm),Rn + // + BEGIN_DIS_OP(MOV_L_IDXREGINDIR_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MOV.L @(R0,R%u),R%u", m, n); + END_DIS_OP + + + // + // MOV.B R0,@(disp,GBR) + // + BEGIN_DIS_OP(MOV_B_REG0_GBRINDIRDISP) + const unsigned d = (instr >> 0) & 0xff; + + trio_sprintf(buffer, "MOV.B R0,@(%u,GBR)", (d << 0)); + END_DIS_OP + + + // + // MOV.W R0,@(disp,GBR) + // + BEGIN_DIS_OP(MOV_W_REG0_GBRINDIRDISP) + const unsigned d = (instr >> 0) & 0xff; + + trio_sprintf(buffer, "MOV.W R0,@(%u,GBR)", (d << 1)); + END_DIS_OP + + + // + // MOV.L R0,@(disp,GBR) + // + BEGIN_DIS_OP(MOV_L_REG0_GBRINDIRDISP) + const unsigned d = (instr >> 0) & 0xff; + + trio_sprintf(buffer, "MOV.L R0,@(%u,GBR)", (d << 2)); + END_DIS_OP + + + // + // MOV.B @(disp,GBR),R0 + // + BEGIN_DIS_OP(MOV_B_GBRINDIRDISP_REG0) + const unsigned d = (instr >> 0) & 0xff; + + trio_sprintf(buffer, "MOV.B @(%u,GBR),R0", (d << 0)); + END_DIS_OP + + + // + // MOV.W @(disp,GBR),R0 + // + BEGIN_DIS_OP(MOV_W_GBRINDIRDISP_REG0) + const unsigned d = (instr >> 0) & 0xff; + + trio_sprintf(buffer, "MOV.W @(%u,GBR),R0", (d << 1)); + END_DIS_OP + + + // + // MOV.L @(disp,GBR),R0 + // + BEGIN_DIS_OP(MOV_L_GBRINDIRDISP_REG0) + const unsigned d = (instr >> 0) & 0xff; + + trio_sprintf(buffer, "MOV.L @(%u,GBR),R0", (d << 2)); + END_DIS_OP + + + // + // MOVA @(disp,PC),R0 + // + BEGIN_DIS_OP(MOVA_PCREL_REG0) + const unsigned d = (instr >> 0) & 0xff; + + trio_sprintf(buffer, "MOVA @(%u,PC),R0", (d << 2)); + END_DIS_OP + + + // + // MOVT Rn + // + BEGIN_DIS_OP(MOVT_REG) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "MOVT R%u", n); + END_DIS_OP + + + // + // SWAP.B Rm,Rn + // + BEGIN_DIS_OP(SWAP_B_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "SWAP.B R%u,R%u", m, n); + END_DIS_OP + + + // + // SWAP.W Rm,Rn + // + BEGIN_DIS_OP(SWAP_W_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "SWAP.W R%u,R%u", m, n); + END_DIS_OP + + + // + // XTRCT Rm,Rn + // + BEGIN_DIS_OP(XTRCT_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "XTRCT R%u,R%u", m, n); + END_DIS_OP + + + // + // ADD Rm,Rn + // + BEGIN_DIS_OP(ADD_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "ADD R%u,R%u", m, n); + END_DIS_OP + + + // + // ADD #imm,Rn + // + BEGIN_DIS_OP(ADD_IMM_REG) + const unsigned n = instr_nyb2; + const int32 imm = (int8)instr; + + trio_sprintf(buffer, "ADD #%d,R%u", imm, n); + END_DIS_OP + + + // + // ADDC Rm,Rn + // + BEGIN_DIS_OP(ADDC_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "ADDC R%u,R%u", m, n); + END_DIS_OP + + + // + // ADDV Rm,Rn + // + BEGIN_DIS_OP(ADDV_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "ADDV R%u,R%u", m, n); + END_DIS_OP + + + // + // CMP/EQ #imm,R0 + // + BEGIN_DIS_OP(CMP_EQ_IMM_REG0) + const int32 imm = (int8)instr; + + trio_sprintf(buffer, "CMP/EQ #%d,R0", imm); + END_DIS_OP + + + // + // CMP/EQ Rm,Rn + // + BEGIN_DIS_OP(CMP_EQ_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "CMP/EQ R%u,R%u", m, n); + END_DIS_OP + + + // + // CMP/HS Rm,Rn + // + BEGIN_DIS_OP(CMP_HS_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "CMP/HS R%u,R%u", m, n); + END_DIS_OP + + + // + // CMP/GE Rm,Rn + // + BEGIN_DIS_OP(CMP_GE_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "CMP/GE R%u,R%u", m, n); + END_DIS_OP + + + // + // CMP/HI Rm,Rn + // + BEGIN_DIS_OP(CMP_HI_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "CMP/HI R%u,R%u", m, n); + END_DIS_OP + + + // + // CMP/GT Rm,Rn + // + BEGIN_DIS_OP(CMP_GT_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "CMP/GT R%u,R%u", m, n); + END_DIS_OP + + + // + // CMP/PZ Rn + // + BEGIN_DIS_OP(CMP_PZ_REG) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "CMP/PZ R%u", n); + END_DIS_OP + + + // + // CMP/PL Rn + // + BEGIN_DIS_OP(CMP_PL_REG) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "CMP/PL R%u", n); + END_DIS_OP + + + // + // CMP/STR Rm,Rn + // + BEGIN_DIS_OP(CMP_STR_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "CMP/STR R%u,R%u", m, n); + END_DIS_OP + + + // + // DIV1 Rm,Rn + // + BEGIN_DIS_OP(DIV1_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "DIV1 R%u,R%u", m, n); + END_DIS_OP + + + // + // DIV0S Rm,Rn + // + BEGIN_DIS_OP(DIV0S_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "DIV0S R%u,R%u", m, n); + END_DIS_OP + + + // + // DIV0U + // + BEGIN_DIS_OP(DIV0U) + trio_sprintf(buffer, "DIV0U"); + END_DIS_OP + + + // + // DMULS.L Rm,Rn + // + BEGIN_DIS_OP(DMULS_L_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "DMULS.L R%u,R%u", m, n); + END_DIS_OP + + + // + // DMULU.L Rm,Rn + // + BEGIN_DIS_OP(DMULU_L_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "DMULU.L R%u,R%u", m, n); + END_DIS_OP + + + // + // DT Rn + // + BEGIN_DIS_OP(DT) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "DT R%u", n); + END_DIS_OP + + + // + // EXTS.B Rm,Rn + // + BEGIN_DIS_OP(EXTS_B_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "EXTS.B R%u,R%u", m, n); + END_DIS_OP + + + // + // EXTS.W Rm,Rn + // + BEGIN_DIS_OP(EXTS_W_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "EXTS.W R%u,R%u", m, n); + END_DIS_OP + + + // + // EXTU.B Rm,Rn + // + BEGIN_DIS_OP(EXTU_B_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "EXTU.B R%u,R%u", m, n); + END_DIS_OP + + + // + // EXTU.W Rm,Rn + // + BEGIN_DIS_OP(EXTU_W_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "EXTU.W R%u,R%u", m, n); + END_DIS_OP + + + // + // MAC.L @Rm+,@Rn+ + // + BEGIN_DIS_OP(MAC_L) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MAC.L @R%u+,@R%u+", m, n); + END_DIS_OP + + + // + // MAC.W @Rm+,@Rn+ + // + BEGIN_DIS_OP(MAC_W) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MAC.W @R%u+,@R%u+", m, n); + END_DIS_OP + + + // + // MUL.L Rm,Rn + // + BEGIN_DIS_OP(MUL_L_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MUL.L R%u,R%u", m, n); + END_DIS_OP + + + // + // MULS.W Rm,Rn + // + BEGIN_DIS_OP(MULS_W_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MULS.W R%u,R%u", m, n); + END_DIS_OP + + + // + // MULU.W Rm,Rn + // + BEGIN_DIS_OP(MULU_W_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "MULU.W R%u,R%u", m, n); + END_DIS_OP + + + // + // NEG Rm,Rn + // + BEGIN_DIS_OP(NEG_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "NEG R%u,R%u", m, n); + END_DIS_OP + + + // + // NEGC Rm,Rn + // + BEGIN_DIS_OP(NEGC_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "NEGC R%u,R%u", m, n); + END_DIS_OP + + + // + // SUB Rm,Rn + // + BEGIN_DIS_OP(SUB_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "SUB R%u,R%u", m, n); + END_DIS_OP + + + // + // SUBC Rm,Rn + // + BEGIN_DIS_OP(SUBC_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "SUBC R%u,R%u", m, n); + END_DIS_OP + + + // + // SUBV Rm,Rn + // + BEGIN_DIS_OP(SUBV_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "SUBV R%u,R%u", m, n); + END_DIS_OP + + + // + // AND Rm,Rn + // + BEGIN_DIS_OP(AND_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "AND R%u,R%u", m, n); + END_DIS_OP + + + // + // AND #imm,R0 + // + BEGIN_DIS_OP(AND_IMM_REG0) + const unsigned imm = (uint8)instr; + + trio_sprintf(buffer, "AND #%u,R0", imm); + END_DIS_OP + + + // + // AND.B #imm,@(R0,GBR) + // + BEGIN_DIS_OP(AND_B_IMM_IDXGBRINDIR) + const unsigned imm = (uint8)instr; + + trio_sprintf(buffer, "AND.B #%u,@(R0,GBR)", imm); + END_DIS_OP + + + // + // NOT Rm,Rn + // + BEGIN_DIS_OP(NOT_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "NOT R%u,R%u", m, n); + END_DIS_OP + + + // + // OR Rm,Rn + // + BEGIN_DIS_OP(OR_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "OR R%u,R%u", m, n); + END_DIS_OP + + + // + // OR #imm,R0 + // + BEGIN_DIS_OP(OR_IMM_REG0) + const unsigned imm = (uint8)instr; + + trio_sprintf(buffer, "OR #%u,R0", imm); + END_DIS_OP + + + // + // OR.B #imm,@(R0,GBR) + // + BEGIN_DIS_OP(OR_B_IMM_IDXGBRINDIR) + const unsigned imm = (uint8)instr; + + trio_sprintf(buffer, "OR.B #%u,@(R0,GBR)", imm); + END_DIS_OP + + + // + // TAS.B @Rn + // + BEGIN_DIS_OP(TAS_B_REGINDIR) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "TAS.B @R%u", n); + END_DIS_OP + + + // + // TST Rm,Rn + // + BEGIN_DIS_OP(TST_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "TST R%u,R%u", m, n); + END_DIS_OP + + + // + // TST #imm,R0 + // + BEGIN_DIS_OP(TST_IMM_REG0) + const unsigned imm = (uint8)instr; + + trio_sprintf(buffer, "TST #%u,R0", imm); + END_DIS_OP + + + // + // TST.B #imm,@(R0,GBR) + // + BEGIN_DIS_OP(TST_B_IMM_IDXGBRINDIR) + const unsigned imm = (uint8)instr; + + trio_sprintf(buffer, "TST.B #%u,@(R0,GBR)", imm); + END_DIS_OP + + + // + // XOR Rm,Rn + // + BEGIN_DIS_OP(XOR_REG_REG) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + trio_sprintf(buffer, "XOR R%u,R%u", m, n); + END_DIS_OP + + + // + // XOR #imm,R0 + // + BEGIN_DIS_OP(XOR_IMM_REG0) + const unsigned imm = (uint8)instr; + + trio_sprintf(buffer, "XOR #%u,R0", imm); + END_DIS_OP + + + // + // XOR.B #imm,@(R0,GBR) + // + BEGIN_DIS_OP(XOR_B_IMM_IDXGBRINDIR) + const unsigned imm = (uint8)instr; + + trio_sprintf(buffer, "XOR.B #%u,@(R0,GBR)", imm); + END_DIS_OP + + + // + // ROTL Rn + // + BEGIN_DIS_OP(ROTL_REG) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "ROTL R%u", n); + END_DIS_OP + + + // + // ROTR Rn + // + BEGIN_DIS_OP(ROTR_REG) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "ROTR R%u", n); + END_DIS_OP + + + // + // ROTCL Rn + // + BEGIN_DIS_OP(ROTCL_REG) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "ROTCL R%u", n); + END_DIS_OP + + + // + // ROTCR Rn + // + BEGIN_DIS_OP(ROTCR_REG) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "ROTCR R%u", n); + END_DIS_OP + + + // + // SHAR Rn + // + BEGIN_DIS_OP(SHAR_REG) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "SHAR R%u", n); + END_DIS_OP + + + // + // SHLL Rn + // + BEGIN_DIS_OP(SHLL_REG) + const unsigned n = instr_nyb2; + + if(instr & 0x20) + trio_sprintf(buffer, "SHAL R%u", n); + else + trio_sprintf(buffer, "SHLL R%u", n); + END_DIS_OP + + + // + // SHLR Rn + // + BEGIN_DIS_OP(SHLR_REG) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "SHLR R%u", n); + END_DIS_OP + + + // + // SHLL2 Rn + // + BEGIN_DIS_OP(SHLL2_REG) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "SHLL2 R%u", n); + END_DIS_OP + + + // + // SHLR2 Rn + // + BEGIN_DIS_OP(SHLR2_REG) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "SHLR2 R%u", n); + END_DIS_OP + + + // + // SHLL8 Rn + // + BEGIN_DIS_OP(SHLL8_REG) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "SHLL8 R%u", n); + END_DIS_OP + + + // + // SHLR8 Rn + // + BEGIN_DIS_OP(SHLR8_REG) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "SHLR8 R%u", n); + END_DIS_OP + + + // + // SHLL16 Rn + // + BEGIN_DIS_OP(SHLL16_REG) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "SHLL16 R%u", n); + END_DIS_OP + + + // + // SHLR16 Rn + // + BEGIN_DIS_OP(SHLR16_REG) + const unsigned n = instr_nyb2; + + trio_sprintf(buffer, "SHLR16 R%u", n); + END_DIS_OP + + + // + // BF + // + BEGIN_DIS_OP(BF) + trio_sprintf(buffer, "BF 0x%08x", (uint32)(PC + ((uint32)(int8)instr << 1))); + END_DIS_OP + + + // + // BF/S + // + BEGIN_DIS_OP(BF_S) + trio_sprintf(buffer, "BF/S 0x%08x", (uint32)(PC + ((uint32)(int8)instr << 1))); + END_DIS_OP + + + // + // BT + // + BEGIN_DIS_OP(BT) + trio_sprintf(buffer, "BT 0x%08x", (uint32)(PC + ((uint32)(int8)instr << 1))); + END_DIS_OP + + + // + // BT/S + // + BEGIN_DIS_OP(BT_S) + trio_sprintf(buffer, "BT/S 0x%08x", (uint32)(PC + ((uint32)(int8)instr << 1))); + END_DIS_OP + + + // + // BRA + // + BEGIN_DIS_OP(BRA) + trio_sprintf(buffer, "BRA 0x%08x", (uint32)(PC + ((uint32)sign_x_to_s32(12, instr) << 1))); + END_DIS_OP + + + // + // BRAF Rm + // + BEGIN_DIS_OP(BRAF_REG) + const unsigned m = instr_nyb2; + + trio_sprintf(buffer, "BRAF R%u", m); + END_DIS_OP + + + // + // BSR + // + BEGIN_DIS_OP(BSR) + trio_sprintf(buffer, "BSR 0x%08x", (uint32)(PC + ((uint32)sign_x_to_s32(12, instr) << 1))); + END_DIS_OP + + + // + // BSRF Rm + // + BEGIN_DIS_OP(BSRF_REG) + const unsigned m = instr_nyb2; + + trio_sprintf(buffer, "BSRF R%u", m); + END_DIS_OP + + + // + // JMP @Rm + // + BEGIN_DIS_OP(JMP_REGINDIR) + const unsigned m = instr_nyb2; + + trio_sprintf(buffer, "JMP @R%u", m); + END_DIS_OP + + + // + // JSR @Rm + // + BEGIN_DIS_OP(JSR_REGINDIR) + const unsigned m = instr_nyb2; + + trio_sprintf(buffer, "JSR @R%u", m); + END_DIS_OP + + + // + // RTS + // + BEGIN_DIS_OP(RTS) + trio_sprintf(buffer, "RTS"); + END_DIS_OP + + + // + // CLRT + // + BEGIN_DIS_OP(CLRT) + trio_sprintf(buffer, "CLRT"); + END_DIS_OP + + + // + // CLRMAC + // + BEGIN_DIS_OP(CLRMAC) + trio_sprintf(buffer, "CLRMAC"); + END_DIS_OP + + + // + // LDC + // + BEGIN_DIS_OP(LDC) + const unsigned m = instr_nyb2; + const unsigned cri = (instr >> 4) & 0x3; + + trio_sprintf(buffer, "LDC R%u, %s", m, CR_Names[cri]); + END_DIS_OP + + // + // LDC.L + // + BEGIN_DIS_OP(LDC_L) + const unsigned m = instr_nyb2; + const unsigned cri = (instr >> 4) & 0x3; + + trio_sprintf(buffer, "LDC.L @R%u+, %s", m, CR_Names[cri]); + END_DIS_OP + + + // + // LDS + // + BEGIN_DIS_OP(LDS) + const unsigned m = instr_nyb2; + const unsigned sri = (instr >> 4) & 0x3; + + trio_sprintf(buffer, "LDS R%u, %s", m, SR_Names[sri]); + END_DIS_OP + + + // + // LDS.L + // + BEGIN_DIS_OP(LDS_L) + const unsigned m = instr_nyb2; + const unsigned sri = (instr >> 4) & 0x3; + + trio_sprintf(buffer, "LDS.L @R%u+, %s", m, SR_Names[sri]); + END_DIS_OP + + + // + // NOP + // + BEGIN_DIS_OP(NOP) + trio_sprintf(buffer, "NOP"); + END_DIS_OP + + + // + // RTE + // + BEGIN_DIS_OP(RTE) + trio_sprintf(buffer, "RTE"); + END_DIS_OP + + + // + // SETT + // + BEGIN_DIS_OP(SETT) + trio_sprintf(buffer, "SETT"); + END_DIS_OP + + + // + // SLEEP + // + BEGIN_DIS_OP(SLEEP) + trio_sprintf(buffer, "SLEEP"); + END_DIS_OP + + // + // STC + // + BEGIN_DIS_OP(STC) + const unsigned n = instr_nyb2; + const unsigned cri = (instr >> 4) & 0x3; + + trio_sprintf(buffer, "STS %s, R%u", CR_Names[cri], n); + END_DIS_OP + + + // + // STC.L + // + BEGIN_DIS_OP(STC_L) + const unsigned n = instr_nyb2; + const unsigned cri = (instr >> 4) & 0x3; + + trio_sprintf(buffer, "STC.L %s, @-R%u", CR_Names[cri], n); + END_DIS_OP + + + // + // STS + // + BEGIN_DIS_OP(STS) + const unsigned n = instr_nyb2; + const unsigned sri = (instr >> 4) & 0x3; + + trio_sprintf(buffer, "STS %s, R%u", SR_Names[sri], n); + END_DIS_OP + + + // + // STS.L + // + BEGIN_DIS_OP(STS_L) + const unsigned n = instr_nyb2; + const unsigned sri = (instr >> 4) & 0x3; + + trio_sprintf(buffer, "STS.L %s, @-R%u", SR_Names[sri], n); + END_DIS_OP + + + // + // TRAPA #imm + // + BEGIN_DIS_OP(TRAPA) + const unsigned imm = (uint8)instr; + + trio_sprintf(buffer, "TRAPA #%u", imm); + END_DIS_OP + + #undef BEGIN_DIS_OP + #undef END_DIS_OP + } +} + +// +// +// +// +INLINE void SH7095::CheckRWBreakpoints(void (*MRead)(unsigned len, uint32 addr), void (*MWrite)(unsigned len, uint32 addr)) const +{ + uint32 lpid = Pipe_ID; + // + // + // + //SPEPRecover:; + const uint32 instr = (uint16)lpid; + const unsigned instr_nyb1 = (instr >> 4) & 0xF; + const unsigned instr_nyb2 = (instr >> 8) & 0xF; + + switch(lpid >> 24) + { + #include "sh7095_opdefs.inc" + #define BEGIN_BP_OP(x) OP_##x { + #define END_BP_OP } break; + + // + // MOV.W @(disp,PC),Rn + // + BEGIN_BP_OP(MOV_W_PCREL_REG) + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = PC + (d << 1); + + MRead(2, ea); + END_BP_OP + + + // + // MOV.L @(disp,PC),Rn + // + BEGIN_BP_OP(MOV_L_PCREL_REG) + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = (PC &~ 0x3) + (d << 2); + + MRead(4, ea); + END_BP_OP + + + // + // MOV.B Rm,@Rn + // + BEGIN_BP_OP(MOV_B_REG_REGINDIR) + const unsigned n = instr_nyb2; + const uint32 ea = R[n]; + + MWrite(1, ea); + END_BP_OP + + + // + // MOV.W Rm,@Rn + // + BEGIN_BP_OP(MOV_W_REG_REGINDIR) + const unsigned n = instr_nyb2; + const uint32 ea = R[n]; + + MWrite(2, ea); + END_BP_OP + + + // + // MOV.L Rm,@Rn + // + BEGIN_BP_OP(MOV_L_REG_REGINDIR) + const unsigned n = instr_nyb2; + const uint32 ea = R[n]; + + MWrite(4, ea); + END_BP_OP + + + // + // MOV.B @Rm,Rn + // + BEGIN_BP_OP(MOV_B_REGINDIR_REG) + const unsigned m = instr_nyb1; + const uint32 ea = R[m]; + + MRead(1, ea); + END_BP_OP + + + // + // MOV.W @Rm,Rn + // + BEGIN_BP_OP(MOV_W_REGINDIR_REG) + const unsigned m = instr_nyb1; + const uint32 ea = R[m]; + + MRead(2, ea); + END_BP_OP + + + // + // MOV.L @Rm,Rn + // + BEGIN_BP_OP(MOV_L_REGINDIR_REG) + const unsigned m = instr_nyb1; + const uint32 ea = R[m]; + + MRead(4, ea); + END_BP_OP + + + // + // MOV.B Rm,@-Rn + // + BEGIN_BP_OP(MOV_B_REG_REGINDIRPD) + const unsigned n = instr_nyb2; + const uint32 ea = R[n] - 1; + + MWrite(1, ea); + END_BP_OP + + + // + // MOV.W Rm,@-Rn + // + BEGIN_BP_OP(MOV_W_REG_REGINDIRPD) + const unsigned n = instr_nyb2; + const uint32 ea = R[n] - 2; + + MWrite(2, ea); + END_BP_OP + + + // + // MOV.L Rm,@-Rn + // + BEGIN_BP_OP(MOV_L_REG_REGINDIRPD) + const unsigned n = instr_nyb2; + const uint32 ea = R[n] - 4; + + MWrite(4, ea); + END_BP_OP + + + // + // MOV.B @Rm+,Rn + // + BEGIN_BP_OP(MOV_B_REGINDIRPI_REG) + const unsigned m = instr_nyb1; + const uint32 ea = R[m]; + + MRead(1, ea); + END_BP_OP + + + // + // MOV.W @Rm+,Rn + // + BEGIN_BP_OP(MOV_W_REGINDIRPI_REG) + const unsigned m = instr_nyb1; + const uint32 ea = R[m]; + + MRead(2, ea); + END_BP_OP + + + // + // MOV.L @Rm+,Rn + // + BEGIN_BP_OP(MOV_L_REGINDIRPI_REG) + const unsigned m = instr_nyb1; + const uint32 ea = R[m]; + + MRead(4, ea); + END_BP_OP + + + // + // MOV.B R0,@(disp,Rn) + // + BEGIN_BP_OP(MOV_B_REG0_REGINDIRDISP) + const unsigned n = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + const uint32 ea = R[n] + (d << 0); + + MWrite(1, ea); + END_BP_OP + + + // + // MOV.W R0,@(disp,Rn) + // + BEGIN_BP_OP(MOV_W_REG0_REGINDIRDISP) + const unsigned n = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + const uint32 ea = R[n] + (d << 1); + + MWrite(2, ea); + END_BP_OP + + + // + // MOV.L Rm,@(disp,Rn) + // + BEGIN_BP_OP(MOV_L_REG_REGINDIRDISP) + const unsigned n = instr_nyb2; + const unsigned d = (instr >> 0) & 0xf; + const uint32 ea = R[n] + (d << 2); + + MWrite(4, ea); + END_BP_OP + + + // + // MOV.B @(disp,Rm),R0 + // + BEGIN_BP_OP(MOV_B_REGINDIRDISP_REG0) + const unsigned m = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + const uint32 ea = R[m] + (d << 0); + + MRead(1, ea); + END_BP_OP + + + // + // MOV.W @(disp,Rm),R0 + // + BEGIN_BP_OP(MOV_W_REGINDIRDISP_REG0) + const unsigned m = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + const uint32 ea = R[m] + (d << 1); + + MRead(2, ea); + END_BP_OP + + + // + // MOV.L @(disp,Rm),Rn + // + BEGIN_BP_OP(MOV_L_REGINDIRDISP_REG) + const unsigned m = instr_nyb1; + const unsigned d = (instr >> 0) & 0xf; + const uint32 ea = R[m] + (d << 2); + + MRead(4, ea); + END_BP_OP + + + // + // MOV.B Rm,@(R0,Rn) + // + BEGIN_BP_OP(MOV_B_REG_IDXREGINDIR) + const unsigned n = instr_nyb2; + const uint32 ea = R[0] + R[n]; + + MWrite(1, ea); + END_BP_OP + + + // + // MOV.W Rm,@(R0,Rn) + // + BEGIN_BP_OP(MOV_W_REG_IDXREGINDIR) + const unsigned n = instr_nyb2; + const uint32 ea = R[0] + R[n]; + + MWrite(2, ea); + END_BP_OP + + + // + // MOV.L Rm,@(R0,Rn) + // + BEGIN_BP_OP(MOV_L_REG_IDXREGINDIR) + const unsigned n = instr_nyb2; + const uint32 ea = R[0] + R[n]; + + MWrite(4, ea); + END_BP_OP + + + // + // MOV.B @(R0,Rm),Rn + // + BEGIN_BP_OP(MOV_B_IDXREGINDIR_REG) + const unsigned m = instr_nyb1; + const uint32 ea = R[0] + R[m]; + + MRead(1, ea); + END_BP_OP + + + // + // MOV.W @(R0,Rm),Rn + // + BEGIN_BP_OP(MOV_W_IDXREGINDIR_REG) + const unsigned m = instr_nyb1; + const uint32 ea = R[0] + R[m]; + + MRead(2, ea); + END_BP_OP + + + // + // MOV.L @(R0,Rm),Rn + // + BEGIN_BP_OP(MOV_L_IDXREGINDIR_REG) + const unsigned m = instr_nyb1; + const uint32 ea = R[0] + R[m]; + + MRead(4, ea); + END_BP_OP + + + // + // MOV.B R0,@(disp,GBR) + // + BEGIN_BP_OP(MOV_B_REG0_GBRINDIRDISP) + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = GBR + (d << 0); + + MWrite(1, ea); + END_BP_OP + + + // + // MOV.W R0,@(disp,GBR) + // + BEGIN_BP_OP(MOV_W_REG0_GBRINDIRDISP) + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = GBR + (d << 1); + + MWrite(2, ea); + END_BP_OP + + + // + // MOV.L R0,@(disp,GBR) + // + BEGIN_BP_OP(MOV_L_REG0_GBRINDIRDISP) + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = GBR + (d << 2); + + MWrite(4, ea); + END_BP_OP + + + // + // MOV.B @(disp,GBR),R0 + // + BEGIN_BP_OP(MOV_B_GBRINDIRDISP_REG0) + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = GBR + (d << 0); + + MRead(1, ea); + END_BP_OP + + + // + // MOV.W @(disp,GBR),R0 + // + BEGIN_BP_OP(MOV_W_GBRINDIRDISP_REG0) + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = GBR + (d << 1); + + MRead(2, ea); + END_BP_OP + + + // + // MOV.L @(disp,GBR),R0 + // + BEGIN_BP_OP(MOV_L_GBRINDIRDISP_REG0) + const unsigned d = (instr >> 0) & 0xff; + const uint32 ea = GBR + (d << 2); + + MRead(4, ea); + END_BP_OP + + + // + // MAC.L @Rm+,@Rn+ + // + BEGIN_BP_OP(MAC_L) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + MRead(4, R[m]); + MRead(4, R[n] + ((m == n) << 2)); + END_BP_OP + + + // + // MAC.W @Rm+,@Rn+ + // + BEGIN_BP_OP(MAC_W) + const unsigned n = instr_nyb2; + const unsigned m = instr_nyb1; + + MRead(2, R[m]); + MRead(2, R[n] + ((m == n) << 1)); + END_BP_OP + + + // + // AND.B #imm,@(R0,GBR) + // + BEGIN_BP_OP(AND_B_IMM_IDXGBRINDIR) + const uint32 ea = R[0] + GBR; + + MRead(1, ea); + MWrite(1, ea); + END_BP_OP + + // + // OR.B #imm,@(R0,GBR) + // + BEGIN_BP_OP(OR_B_IMM_IDXGBRINDIR) + const uint32 ea = R[0] + GBR; + + MRead(1, ea); + MWrite(1, ea); + END_BP_OP + + + // + // TAS.B @Rn + // + BEGIN_BP_OP(TAS_B_REGINDIR) + const unsigned n = instr_nyb2; + const uint32 ea = R[n]; + + MRead(1, ea); + MWrite(1, ea); + END_BP_OP + + + // + // TST.B #imm,@(R0,GBR) + // + BEGIN_BP_OP(TST_B_IMM_IDXGBRINDIR) + const uint32 ea = R[0] + GBR; + + MRead(1, ea); + END_BP_OP + + + // + // XOR.B #imm,@(R0,GBR) + // + BEGIN_BP_OP(XOR_B_IMM_IDXGBRINDIR) + const uint32 ea = R[0] + GBR; + + MRead(1, ea); + MWrite(1, ea); + END_BP_OP + + + // + // LDC.L + // + BEGIN_BP_OP(LDC_L) + const unsigned m = instr_nyb2; + const uint32 ea = R[m]; + + MRead(4, ea); + END_BP_OP + + + // + // LDS.L + // + BEGIN_BP_OP(LDS_L) + const unsigned m = instr_nyb2; + const uint32 ea = R[m]; + + MRead(4, ea); + END_BP_OP + + + // + // RTE + // + BEGIN_BP_OP(RTE) + MRead(4, R[15]); + MRead(4, 4 + R[15]); + END_BP_OP + + // + // STC.L + // + BEGIN_BP_OP(STC_L) + const unsigned n = instr_nyb2; + const uint32 ea = R[n] - 4; + + MWrite(4, ea); + END_BP_OP + + // + // STS.L + // + BEGIN_BP_OP(STS_L) // Pipeline same as ordinary store instruction + const unsigned n = instr_nyb2; + const uint32 ea = R[n] - 4; + + MWrite(4, ea); + END_BP_OP + + +#if 0 + // + // TRAPA #imm + // + // Saved PC is the address of the instruction after the TRAPA instruction + // + BEGIN_BP_OP_DLYIDIF(TRAPA) + const unsigned imm = (uint8)instr; + + BP_EXCEPT(EXCEPTION_TRAP, imm); + END_BP_OP + + + // + // Illegal Instruction + // + BEGIN_BP_OP_DLYIDIF(ILLEGAL) + BP_EXCEPT(EXCEPTION_ILLINSTR, VECNUM_ILLINSTR); + END_BP_OP + + // + // Illegal Slot Instruction + // + BEGIN_BP_OP_DLYIDIF(SLOT_ILLEGAL) + BP_EXCEPT(EXCEPTION_ILLSLOT, VECNUM_ILLSLOT); + END_BP_OP + + // + // Pending exception(address error/interrupt) + // + BEGIN_BP_OP_DLYIDIF(PSEUDO_EPENDING) + #define TPP(x) (Pipe_ID & (1U << ((x) + EPENDING_PEXBITS_SHIFT))) + + if(MDFN_UNLIKELY(TPP(PEX_PSEUDO_EXTHALT))) + return; + else if(MDFN_UNLIKELY(TPP(PEX_POWERON) || TPP(PEX_RESET))) + { + if(TPP(PEX_POWERON)) + BP_EXCEPT(EXCEPTION_POWERON, VECNUM_POWERON); + else + BP_EXCEPT(EXCEPTION_RESET, VECNUM_RESET); + } + else if(MDFN_UNLIKELY(TPP(PEX_PSEUDO_DMABURST))) + return; + else if(MDFN_UNLIKELY(TPP(PEX_CPUADDR))) + BP_EXCEPT(EXCEPTION_CPUADDR, VECNUM_CPUADDR); + else if(MDFN_UNLIKELY(TPP(PEX_DMAADDR))) + BP_EXCEPT(EXCEPTION_DMAADDR, VECNUM_DMAADDR); + else if(TPP(PEX_NMI)) + BP_EXCEPT(EXCEPTION_NMI, VECNUM_NMI); + else // Int + { + uint8 ipr = GetPendingInt(NULL); + + if(MDFN_LIKELY(ipr > ((SR >> 4) & 0xF))) + { + uint8 vecnum; + + // Note: GetPendingInt() may call ExIVecFetch(), which may call SetIRL with a new value, so be + // careful to use the "old" value here. + GetPendingInt(&vecnum); + BP_EXCEPT(EXCEPTION_INT, vecnum); + } + else + { + lpid = (uint16)lpid; + lpid |= InstrDecodeTab[lpid] << 24; + goto SPEPRecover; + } + } +END_BP_OP +#endif + + #undef BEGIN_BP_OP + #undef END_BP_OP + } +} diff --git a/waterbox/ss/sh7095_idecodetab.inc b/waterbox/ss/sh7095_idecodetab.inc new file mode 100644 index 0000000000..e5ac21b44c --- /dev/null +++ b/waterbox/ss/sh7095_idecodetab.inc @@ -0,0 +1,256 @@ + 0x00, 0x00, 0x79, 0x6b, 0x17, 0x18, 0x19, 0x41, 0x6f, 0x75, 0x7b, 0x6e, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x00, 0x17, 0x18, 0x19, 0x41, 0x77, 0x37, 0x7b, 0x78, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x69, 0x17, 0x18, 0x19, 0x41, 0x70, 0x24, 0x7b, 0x76, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, + 0x00, 0x00, 0x79, 0x6b, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x69, 0x17, 0x18, 0x19, 0x41, 0x00, 0x24, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, + 0x00, 0x00, 0x79, 0x6b, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x69, 0x17, 0x18, 0x19, 0x41, 0x00, 0x24, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, + 0x00, 0x00, 0x79, 0x6b, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x69, 0x17, 0x18, 0x19, 0x41, 0x00, 0x24, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, + 0x00, 0x00, 0x79, 0x6b, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x69, 0x17, 0x18, 0x19, 0x41, 0x00, 0x24, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, + 0x00, 0x00, 0x79, 0x6b, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x69, 0x17, 0x18, 0x19, 0x41, 0x00, 0x24, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, + 0x00, 0x00, 0x79, 0x6b, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x69, 0x17, 0x18, 0x19, 0x41, 0x00, 0x24, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, + 0x00, 0x00, 0x79, 0x6b, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x69, 0x17, 0x18, 0x19, 0x41, 0x00, 0x24, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, + 0x00, 0x00, 0x79, 0x6b, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x69, 0x17, 0x18, 0x19, 0x41, 0x00, 0x24, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, + 0x00, 0x00, 0x79, 0x6b, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x69, 0x17, 0x18, 0x19, 0x41, 0x00, 0x24, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, + 0x00, 0x00, 0x79, 0x6b, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x69, 0x17, 0x18, 0x19, 0x41, 0x00, 0x24, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, + 0x00, 0x00, 0x79, 0x6b, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x69, 0x17, 0x18, 0x19, 0x41, 0x00, 0x24, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, + 0x00, 0x00, 0x79, 0x6b, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x69, 0x17, 0x18, 0x19, 0x41, 0x00, 0x24, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, + 0x00, 0x00, 0x79, 0x6b, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x69, 0x17, 0x18, 0x19, 0x41, 0x00, 0x24, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, + 0x00, 0x00, 0x79, 0x6b, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x69, 0x17, 0x18, 0x19, 0x41, 0x00, 0x24, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, + 0x00, 0x00, 0x79, 0x6b, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x79, 0x69, 0x17, 0x18, 0x19, 0x41, 0x00, 0x24, 0x7b, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x17, 0x18, 0x19, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x1b, 0x1c, 0x3f, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, + 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, + 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, + 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, + 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, + 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, + 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, + 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, + 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, + 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, + 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, + 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, + 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, + 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, + 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, + 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, 0x05, 0x06, 0x07, 0x00, 0x0b, 0x0c, 0x0d, 0x36, 0x51, 0x49, 0x54, 0x4d, 0x34, 0x27, 0x43, 0x42, + 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, + 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, + 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, + 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, + 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, + 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, + 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, + 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, + 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, + 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, + 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, + 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, + 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, + 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, + 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, + 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, 0x2d, 0x00, 0x2e, 0x2f, 0x35, 0x39, 0x30, 0x31, 0x46, 0x00, 0x47, 0x48, 0x28, 0x38, 0x2a, 0x2b, + 0x5c, 0x5d, 0x7c, 0x7a, 0x57, 0x58, 0x74, 0x72, 0x5e, 0x5f, 0x73, 0x6d, 0x00, 0x00, 0x71, 0x40, 0x3a, 0x32, 0x7c, 0x7a, 0x00, 0x33, 0x74, 0x72, 0x60, 0x61, 0x73, 0x50, 0x00, 0x00, 0x71, 0x40, 0x5c, 0x5b, 0x7c, 0x7a, 0x59, 0x5a, 0x74, 0x72, 0x62, 0x63, 0x73, 0x6c, 0x00, 0x00, 0x71, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x5c, 0x5d, 0x7c, 0x7a, 0x57, 0x58, 0x74, 0x72, 0x5e, 0x5f, 0x73, 0x6d, 0x00, 0x00, 0x71, 0x40, 0x3a, 0x32, 0x7c, 0x7a, 0x00, 0x33, 0x74, 0x72, 0x60, 0x61, 0x73, 0x50, 0x00, 0x00, 0x71, 0x40, 0x5c, 0x5b, 0x7c, 0x7a, 0x59, 0x5a, 0x74, 0x72, 0x62, 0x63, 0x73, 0x6c, 0x00, 0x00, 0x71, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x5c, 0x5d, 0x7c, 0x7a, 0x57, 0x58, 0x74, 0x72, 0x5e, 0x5f, 0x73, 0x6d, 0x00, 0x00, 0x71, 0x40, 0x3a, 0x32, 0x7c, 0x7a, 0x00, 0x33, 0x74, 0x72, 0x60, 0x61, 0x73, 0x50, 0x00, 0x00, 0x71, 0x40, 0x5c, 0x5b, 0x7c, 0x7a, 0x59, 0x5a, 0x74, 0x72, 0x62, 0x63, 0x73, 0x6c, 0x00, 0x00, 0x71, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x5c, 0x5d, 0x7c, 0x7a, 0x57, 0x58, 0x74, 0x72, 0x5e, 0x5f, 0x73, 0x6d, 0x00, 0x00, 0x71, 0x40, 0x3a, 0x32, 0x7c, 0x7a, 0x00, 0x33, 0x74, 0x72, 0x60, 0x61, 0x73, 0x50, 0x00, 0x00, 0x71, 0x40, 0x5c, 0x5b, 0x7c, 0x7a, 0x59, 0x5a, 0x74, 0x72, 0x62, 0x63, 0x73, 0x6c, 0x00, 0x00, 0x71, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x5c, 0x5d, 0x7c, 0x7a, 0x57, 0x58, 0x74, 0x72, 0x5e, 0x5f, 0x73, 0x6d, 0x00, 0x00, 0x71, 0x40, 0x3a, 0x32, 0x7c, 0x7a, 0x00, 0x33, 0x74, 0x72, 0x60, 0x61, 0x73, 0x50, 0x00, 0x00, 0x71, 0x40, 0x5c, 0x5b, 0x7c, 0x7a, 0x59, 0x5a, 0x74, 0x72, 0x62, 0x63, 0x73, 0x6c, 0x00, 0x00, 0x71, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x5c, 0x5d, 0x7c, 0x7a, 0x57, 0x58, 0x74, 0x72, 0x5e, 0x5f, 0x73, 0x6d, 0x00, 0x00, 0x71, 0x40, 0x3a, 0x32, 0x7c, 0x7a, 0x00, 0x33, 0x74, 0x72, 0x60, 0x61, 0x73, 0x50, 0x00, 0x00, 0x71, 0x40, 0x5c, 0x5b, 0x7c, 0x7a, 0x59, 0x5a, 0x74, 0x72, 0x62, 0x63, 0x73, 0x6c, 0x00, 0x00, 0x71, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x5c, 0x5d, 0x7c, 0x7a, 0x57, 0x58, 0x74, 0x72, 0x5e, 0x5f, 0x73, 0x6d, 0x00, 0x00, 0x71, 0x40, 0x3a, 0x32, 0x7c, 0x7a, 0x00, 0x33, 0x74, 0x72, 0x60, 0x61, 0x73, 0x50, 0x00, 0x00, 0x71, 0x40, 0x5c, 0x5b, 0x7c, 0x7a, 0x59, 0x5a, 0x74, 0x72, 0x62, 0x63, 0x73, 0x6c, 0x00, 0x00, 0x71, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x5c, 0x5d, 0x7c, 0x7a, 0x57, 0x58, 0x74, 0x72, 0x5e, 0x5f, 0x73, 0x6d, 0x00, 0x00, 0x71, 0x40, 0x3a, 0x32, 0x7c, 0x7a, 0x00, 0x33, 0x74, 0x72, 0x60, 0x61, 0x73, 0x50, 0x00, 0x00, 0x71, 0x40, 0x5c, 0x5b, 0x7c, 0x7a, 0x59, 0x5a, 0x74, 0x72, 0x62, 0x63, 0x73, 0x6c, 0x00, 0x00, 0x71, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x5c, 0x5d, 0x7c, 0x7a, 0x57, 0x58, 0x74, 0x72, 0x5e, 0x5f, 0x73, 0x6d, 0x00, 0x00, 0x71, 0x40, 0x3a, 0x32, 0x7c, 0x7a, 0x00, 0x33, 0x74, 0x72, 0x60, 0x61, 0x73, 0x50, 0x00, 0x00, 0x71, 0x40, 0x5c, 0x5b, 0x7c, 0x7a, 0x59, 0x5a, 0x74, 0x72, 0x62, 0x63, 0x73, 0x6c, 0x00, 0x00, 0x71, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x5c, 0x5d, 0x7c, 0x7a, 0x57, 0x58, 0x74, 0x72, 0x5e, 0x5f, 0x73, 0x6d, 0x00, 0x00, 0x71, 0x40, 0x3a, 0x32, 0x7c, 0x7a, 0x00, 0x33, 0x74, 0x72, 0x60, 0x61, 0x73, 0x50, 0x00, 0x00, 0x71, 0x40, 0x5c, 0x5b, 0x7c, 0x7a, 0x59, 0x5a, 0x74, 0x72, 0x62, 0x63, 0x73, 0x6c, 0x00, 0x00, 0x71, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x5c, 0x5d, 0x7c, 0x7a, 0x57, 0x58, 0x74, 0x72, 0x5e, 0x5f, 0x73, 0x6d, 0x00, 0x00, 0x71, 0x40, 0x3a, 0x32, 0x7c, 0x7a, 0x00, 0x33, 0x74, 0x72, 0x60, 0x61, 0x73, 0x50, 0x00, 0x00, 0x71, 0x40, 0x5c, 0x5b, 0x7c, 0x7a, 0x59, 0x5a, 0x74, 0x72, 0x62, 0x63, 0x73, 0x6c, 0x00, 0x00, 0x71, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x5c, 0x5d, 0x7c, 0x7a, 0x57, 0x58, 0x74, 0x72, 0x5e, 0x5f, 0x73, 0x6d, 0x00, 0x00, 0x71, 0x40, 0x3a, 0x32, 0x7c, 0x7a, 0x00, 0x33, 0x74, 0x72, 0x60, 0x61, 0x73, 0x50, 0x00, 0x00, 0x71, 0x40, 0x5c, 0x5b, 0x7c, 0x7a, 0x59, 0x5a, 0x74, 0x72, 0x62, 0x63, 0x73, 0x6c, 0x00, 0x00, 0x71, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x5c, 0x5d, 0x7c, 0x7a, 0x57, 0x58, 0x74, 0x72, 0x5e, 0x5f, 0x73, 0x6d, 0x00, 0x00, 0x71, 0x40, 0x3a, 0x32, 0x7c, 0x7a, 0x00, 0x33, 0x74, 0x72, 0x60, 0x61, 0x73, 0x50, 0x00, 0x00, 0x71, 0x40, 0x5c, 0x5b, 0x7c, 0x7a, 0x59, 0x5a, 0x74, 0x72, 0x62, 0x63, 0x73, 0x6c, 0x00, 0x00, 0x71, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x5c, 0x5d, 0x7c, 0x7a, 0x57, 0x58, 0x74, 0x72, 0x5e, 0x5f, 0x73, 0x6d, 0x00, 0x00, 0x71, 0x40, 0x3a, 0x32, 0x7c, 0x7a, 0x00, 0x33, 0x74, 0x72, 0x60, 0x61, 0x73, 0x50, 0x00, 0x00, 0x71, 0x40, 0x5c, 0x5b, 0x7c, 0x7a, 0x59, 0x5a, 0x74, 0x72, 0x62, 0x63, 0x73, 0x6c, 0x00, 0x00, 0x71, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x5c, 0x5d, 0x7c, 0x7a, 0x57, 0x58, 0x74, 0x72, 0x5e, 0x5f, 0x73, 0x6d, 0x00, 0x00, 0x71, 0x40, 0x3a, 0x32, 0x7c, 0x7a, 0x00, 0x33, 0x74, 0x72, 0x60, 0x61, 0x73, 0x50, 0x00, 0x00, 0x71, 0x40, 0x5c, 0x5b, 0x7c, 0x7a, 0x59, 0x5a, 0x74, 0x72, 0x62, 0x63, 0x73, 0x6c, 0x00, 0x00, 0x71, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x5c, 0x5d, 0x7c, 0x7a, 0x57, 0x58, 0x74, 0x72, 0x5e, 0x5f, 0x73, 0x6d, 0x00, 0x00, 0x71, 0x40, 0x3a, 0x32, 0x7c, 0x7a, 0x00, 0x33, 0x74, 0x72, 0x60, 0x61, 0x73, 0x50, 0x00, 0x00, 0x71, 0x40, 0x5c, 0x5b, 0x7c, 0x7a, 0x59, 0x5a, 0x74, 0x72, 0x62, 0x63, 0x73, 0x6c, 0x00, 0x00, 0x71, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, + 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, + 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, + 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, + 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, + 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, + 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, + 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, + 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, + 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, + 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, + 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, + 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, + 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, + 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, + 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, + 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, 0x08, 0x09, 0x0a, 0x04, 0x0e, 0x0f, 0x10, 0x4c, 0x25, 0x26, 0x45, 0x44, 0x3d, 0x3e, 0x3b, 0x3c, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, + 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, + 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, + 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, + 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, + 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/waterbox/ss/sh7095_opdefs.inc b/waterbox/ss/sh7095_opdefs.inc new file mode 100644 index 0000000000..4ef78c1db4 --- /dev/null +++ b/waterbox/ss/sh7095_opdefs.inc @@ -0,0 +1,157 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* sh7095_opdefs.inc: +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#define OP_ILLEGAL case 0x00: /* (slot illegal) */ +#define OP_MOV_IMM_REG case 0x01:case 0x81: +#define OP_MOV_W_PCREL_REG case 0x02:case 0x82: +#define OP_MOV_L_PCREL_REG case 0x03:case 0x83: +#define OP_MOV_REG_REG case 0x04:case 0x84: +#define OP_MOV_B_REG_REGINDIR case 0x05:case 0x85: +#define OP_MOV_W_REG_REGINDIR case 0x06:case 0x86: +#define OP_MOV_L_REG_REGINDIR case 0x07:case 0x87: +#define OP_MOV_B_REGINDIR_REG case 0x08:case 0x88: +#define OP_MOV_W_REGINDIR_REG case 0x09:case 0x89: +#define OP_MOV_L_REGINDIR_REG case 0x0a:case 0x8a: +#define OP_MOV_B_REG_REGINDIRPD case 0x0b:case 0x8b: +#define OP_MOV_W_REG_REGINDIRPD case 0x0c:case 0x8c: +#define OP_MOV_L_REG_REGINDIRPD case 0x0d:case 0x8d: +#define OP_MOV_B_REGINDIRPI_REG case 0x0e:case 0x8e: +#define OP_MOV_W_REGINDIRPI_REG case 0x0f:case 0x8f: +#define OP_MOV_L_REGINDIRPI_REG case 0x10:case 0x90: +#define OP_MOV_B_REG0_REGINDIRDISP case 0x11:case 0x91: +#define OP_MOV_W_REG0_REGINDIRDISP case 0x12:case 0x92: +#define OP_MOV_L_REG_REGINDIRDISP case 0x13:case 0x93: +#define OP_MOV_B_REGINDIRDISP_REG0 case 0x14:case 0x94: +#define OP_MOV_W_REGINDIRDISP_REG0 case 0x15:case 0x95: +#define OP_MOV_L_REGINDIRDISP_REG case 0x16:case 0x96: +#define OP_MOV_B_REG_IDXREGINDIR case 0x17:case 0x97: +#define OP_MOV_W_REG_IDXREGINDIR case 0x18:case 0x98: +#define OP_MOV_L_REG_IDXREGINDIR case 0x19:case 0x99: +#define OP_MOV_B_IDXREGINDIR_REG case 0x1a:case 0x9a: +#define OP_MOV_W_IDXREGINDIR_REG case 0x1b:case 0x9b: +#define OP_MOV_L_IDXREGINDIR_REG case 0x1c:case 0x9c: +#define OP_MOV_B_REG0_GBRINDIRDISP case 0x1d:case 0x9d: +#define OP_MOV_W_REG0_GBRINDIRDISP case 0x1e:case 0x9e: +#define OP_MOV_L_REG0_GBRINDIRDISP case 0x1f:case 0x9f: +#define OP_MOV_B_GBRINDIRDISP_REG0 case 0x20:case 0xa0: +#define OP_MOV_W_GBRINDIRDISP_REG0 case 0x21:case 0xa1: +#define OP_MOV_L_GBRINDIRDISP_REG0 case 0x22:case 0xa2: +#define OP_MOVA_PCREL_REG0 case 0x23:case 0xa3: +#define OP_MOVT_REG case 0x24:case 0xa4: +#define OP_SWAP_B_REG_REG case 0x25:case 0xa5: +#define OP_SWAP_W_REG_REG case 0x26:case 0xa6: +#define OP_XTRCT_REG_REG case 0x27:case 0xa7: +#define OP_ADD_REG_REG case 0x28:case 0xa8: +#define OP_ADD_IMM_REG case 0x29:case 0xa9: +#define OP_ADDC_REG_REG case 0x2a:case 0xaa: +#define OP_ADDV_REG_REG case 0x2b:case 0xab: +#define OP_CMP_EQ_IMM_REG0 case 0x2c:case 0xac: +#define OP_CMP_EQ_REG_REG case 0x2d:case 0xad: +#define OP_CMP_HS_REG_REG case 0x2e:case 0xae: +#define OP_CMP_GE_REG_REG case 0x2f:case 0xaf: +#define OP_CMP_HI_REG_REG case 0x30:case 0xb0: +#define OP_CMP_GT_REG_REG case 0x31:case 0xb1: +#define OP_CMP_PZ_REG case 0x32:case 0xb2: +#define OP_CMP_PL_REG case 0x33:case 0xb3: +#define OP_CMP_STR_REG_REG case 0x34:case 0xb4: +#define OP_DIV1_REG_REG case 0x35:case 0xb5: +#define OP_DIV0S_REG_REG case 0x36:case 0xb6: +#define OP_DIV0U case 0x37:case 0xb7: +#define OP_DMULS_L_REG_REG case 0x38:case 0xb8: +#define OP_DMULU_L_REG_REG case 0x39:case 0xb9: +#define OP_DT case 0x3a:case 0xba: +#define OP_EXTS_B_REG_REG case 0x3b:case 0xbb: +#define OP_EXTS_W_REG_REG case 0x3c:case 0xbc: +#define OP_EXTU_B_REG_REG case 0x3d:case 0xbd: +#define OP_EXTU_W_REG_REG case 0x3e:case 0xbe: +#define OP_MAC_L case 0x3f:case 0xbf: +#define OP_MAC_W case 0x40:case 0xc0: +#define OP_MUL_L_REG_REG case 0x41:case 0xc1: +#define OP_MULS_W_REG_REG case 0x42:case 0xc2: +#define OP_MULU_W_REG_REG case 0x43:case 0xc3: +#define OP_NEG_REG_REG case 0x44:case 0xc4: +#define OP_NEGC_REG_REG case 0x45:case 0xc5: +#define OP_SUB_REG_REG case 0x46:case 0xc6: +#define OP_SUBC_REG_REG case 0x47:case 0xc7: +#define OP_SUBV_REG_REG case 0x48:case 0xc8: +#define OP_AND_REG_REG case 0x49:case 0xc9: +#define OP_AND_IMM_REG0 case 0x4a:case 0xca: +#define OP_AND_B_IMM_IDXGBRINDIR case 0x4b:case 0xcb: +#define OP_NOT_REG_REG case 0x4c:case 0xcc: +#define OP_OR_REG_REG case 0x4d:case 0xcd: +#define OP_OR_IMM_REG0 case 0x4e:case 0xce: +#define OP_OR_B_IMM_IDXGBRINDIR case 0x4f:case 0xcf: +#define OP_TAS_B_REGINDIR case 0x50:case 0xd0: +#define OP_TST_REG_REG case 0x51:case 0xd1: +#define OP_TST_IMM_REG0 case 0x52:case 0xd2: +#define OP_TST_B_IMM_IDXGBRINDIR case 0x53:case 0xd3: +#define OP_XOR_REG_REG case 0x54:case 0xd4: +#define OP_XOR_IMM_REG0 case 0x55:case 0xd5: +#define OP_XOR_B_IMM_IDXGBRINDIR case 0x56:case 0xd6: +#define OP_ROTL_REG case 0x57:case 0xd7: +#define OP_ROTR_REG case 0x58:case 0xd8: +#define OP_ROTCL_REG case 0x59:case 0xd9: +#define OP_ROTCR_REG case 0x5a:case 0xda: +#define OP_SHAR_REG case 0x5b:case 0xdb: +#define OP_SHLL_REG case 0x5c:case 0xdc: +#define OP_SHLR_REG case 0x5d:case 0xdd: +#define OP_SHLL2_REG case 0x5e:case 0xde: +#define OP_SHLR2_REG case 0x5f:case 0xdf: +#define OP_SHLL8_REG case 0x60:case 0xe0: +#define OP_SHLR8_REG case 0x61:case 0xe1: +#define OP_SHLL16_REG case 0x62:case 0xe2: +#define OP_SHLR16_REG case 0x63:case 0xe3: +#define OP_BF case 0x64: /* (slot illegal) */ +#define OP_BF_S case 0x65: /* (slot illegal) */ +#define OP_BT case 0x66: /* (slot illegal) */ +#define OP_BT_S case 0x67: /* (slot illegal) */ +#define OP_BRA case 0x68: /* (slot illegal) */ +#define OP_BRAF_REG case 0x69: /* (slot illegal) */ +#define OP_BSR case 0x6a: /* (slot illegal) */ +#define OP_BSRF_REG case 0x6b: /* (slot illegal) */ +#define OP_JMP_REGINDIR case 0x6c: /* (slot illegal) */ +#define OP_JSR_REGINDIR case 0x6d: /* (slot illegal) */ +#define OP_RTS case 0x6e: /* (slot illegal) */ +#define OP_CLRT case 0x6f:case 0xef: +#define OP_CLRMAC case 0x70:case 0xf0: +#define OP_LDC case 0x71:case 0xf1: +#define OP_LDC_L case 0x72:case 0xf2: +#define OP_LDS case 0x73:case 0xf3: +#define OP_LDS_L case 0x74:case 0xf4: +#define OP_NOP case 0x75:case 0xf5: +#define OP_RTE case 0x76: /* (slot illegal) */ +#define OP_SETT case 0x77:case 0xf7: +#define OP_SLEEP case 0x78:case 0xf8: +#define OP_STC case 0x79:case 0xf9: +#define OP_STC_L case 0x7a:case 0xfa: +#define OP_STS case 0x7b:case 0xfb: +#define OP_STS_L case 0x7c:case 0xfc: +#define OP_TRAPA case 0x7d: /* (slot illegal) */ + +#define OP_SLOT_ILLEGAL case 0x80:case 0xe4:case 0xe5:case 0xe6:case 0xe7:case 0xe8:case 0xe9:case 0xea:case 0xeb:case 0xec:case 0xed:case 0xee:case 0xf6:case 0xfd: + +// +// Pseudo-instructions: +// +#define OP_PSEUDO_STANDBY case 0x7e: +#define OP_PSEUDO_DMABURST case 0xfe: +#define OP_PSEUDO_EPENDING case 0x7f: case 0xff: + diff --git a/waterbox/ss/smpc.cpp b/waterbox/ss/smpc.cpp new file mode 100644 index 0000000000..e61922eb8c --- /dev/null +++ b/waterbox/ss/smpc.cpp @@ -0,0 +1,1441 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* smpc.cpp - SMPC Emulation +** Copyright (C) 2015-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +/* + TODO: + CD On/Off +*/ + +#include "ss.h" +#include "cdrom/CDUtility.h" +using namespace CDUtility; + +#include "smpc.h" +#include "sound.h" +#include "vdp1.h" +#include "vdp2.h" +#include "cdb.h" +#include "scu.h" + +#include "input/gamepad.h" +#include "input/3dpad.h" +#include "input/mouse.h" +#include "input/wheel.h" +#include "input/mission.h" +#include "input/keyboard.h" +//#include "input/jpkeyboard.h" + +#include "input/multitap.h" + +namespace MDFN_IEN_SS +{ +#include "sh7095.h" + +enum +{ + CLOCK_DIVISOR_26M = 65, + CLOCK_DIVISOR_28M = 61 +}; + +enum +{ + CMD_MSHON = 0x00, + CMD_SSHON = 0x02, + CMD_SSHOFF = 0x03, + + CMD_SNDON = 0x06, + CMD_SNDOFF = 0x07, + + CMD_CDON = 0x08, + CMD_CDOFF = 0x09, + + // A, B, C do something... + + CMD_SYSRES = 0x0D, + + CMD_CKCHG352 = 0x0E, + CMD_CKCHG320 = 0x0F, + + CMD_INTBACK = 0x10, + CMD_SETTIME = 0x16, + CMD_SETSMEM = 0x17, + + CMD_NMIREQ = 0x18, + CMD_RESENAB = 0x19, + CMD_RESDISA = 0x1A +}; + +static uint8 AreaCode; +static int32 MasterClock; + +static struct +{ + uint64 ClockAccum; + + bool Valid; + + union + { + uint8 raw[7]; + struct + { + uint8 year[2]; // BCD; [0] = xx00, [1] = 00xx + uint8 wday_mon; // 0x0-0x6(upper; 6=Saturday), 0x1-0xC(lower) + uint8 mday; // BCD; 0x01-0x31 + uint8 hour; // BCD; 0x00-0x23 + uint8 minute; // BCD; 0x00-0x59 + uint8 second; // BCD; 0x00-0x59 + }; + }; +} RTC; + +static uint8 SaveMem[4]; + +static uint8 IREG[7]; +static uint8 OREG[0x20]; +static uint8 SR; +static bool SF; + +enum +{ + PMODE_15BYTE = 0, + PMODE_255BYTE = 1, + PMODE_ILL = 2, + PMODE_0BYTE = 3 +}; + +enum +{ + SR_RESB = 0x10, + SR_NPE = 0x20, + SR_PDL = 0x40, +}; + +static bool ResetNMIEnable; + +static bool ResetButtonPhysStatus; +static int32 ResetButtonCount; +static bool ResetPending; +static int32 PendingCommand; +static int32 ExecutingCommand; +static int32 PendingClockDivisor; +static int32 CurrentClockDivisor; + +static bool PendingVB; + +static int32 SubPhase; +static int64 ClockCounter; +static uint32 SMPC_ClockRatio; + +static bool SoundCPUOn; +static bool SlaveSH2On; +static bool CDOn; + +static uint8 BusBuffer; +// +// +static struct +{ + int64 TimeCounter; + int32 StartTime; + int32 OptWaitUntilTime; + int32 OptEatTime; + + int32 OptReadTime; + + uint8 Mode[2]; + bool TimeOptEn; + bool NextContBit; + + uint8 CurPort; + uint8 ID1; + uint8 ID2; + uint8 IDTap; + + uint8 CommMode; + + uint8 OWP; + + uint8 work[8]; + // + // + uint8 TapCounter; + uint8 TapCount; + uint8 ReadCounter; + uint8 ReadCount; + uint8 ReadBuffer[255]; //16]; + uint8 WriteCounter; + uint8 PDCounter; +} JRS; +// +// +static uint8 DataOut[2][2]; +static uint8 DataDir[2][2]; +static bool DirectModeEn[2]; +static bool ExLatchEn[2]; + +static uint8 IOBusState[2]; +static IODevice* IOPorts[2]; + +static struct PossibleDevice +{ + IODevice none; + IODevice_Gamepad gamepad; + IODevice_3DPad threedpad; + IODevice_Mouse mouse; + IODevice_Wheel wheel; + IODevice_Mission mission;//{false}; + IODevice_Mission dualmission;//{true}; + IODevice_Keyboard keyboard; +// IODevice_Keyboard jpkeyboard; + PossibleDevice() + :mission(false), dualmission(true) + { + } +} PossibleDevices[12]; + +static IODevice_Multitap PossibleMultitaps[2]; + +static IODevice_Multitap* SPorts[2]; +static IODevice* VirtualPorts[12]; +static uint8* VirtualPortsDPtr[12]; +static uint8* MiscInputPtr; + +IODevice::IODevice() { } +IODevice::~IODevice() { } +void IODevice::Power(void) { } +void IODevice::UpdateInput(const uint8* data, const int32 time_elapsed) { } +void IODevice::UpdateOutput(uint8* data) { } +uint8 IODevice::UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) { return smpc_out; } + +// +// + +static bool vb; +static sscpu_timestamp_t lastts; + +static void UpdateIOBus(unsigned port) +{ + IOBusState[port] = IOPorts[port]->UpdateBus((DataOut[port][DirectModeEn[port]] | ~DataDir[port][DirectModeEn[port]]) & 0x7F, DataDir[port][DirectModeEn[port]]); + assert(!(IOBusState[port] & 0x80)); +} + +static void MapPorts(void) +{ + for(unsigned sp = 0, vp = 0; sp < 2; sp++) + { + IODevice* nd; + + if(SPorts[sp]) + { + for(unsigned i = 0; i < 6; i++) + { + IODevice* const tsd = VirtualPorts[vp++]; + + if(SPorts[sp]->GetSubDevice(i) != tsd) + tsd->Power(); + + SPorts[sp]->SetSubDevice(i, tsd); + } + + nd = SPorts[sp]; + } + else + nd = VirtualPorts[vp++]; + + if(IOPorts[sp] != nd) + nd->Power(); + + IOPorts[sp] = nd; + } +} + +void SMPC_SetMultitap(unsigned sport, bool enabled) +{ + assert(sport < 2); + + SPorts[sport] = (enabled ? &PossibleMultitaps[sport] : nullptr); + MapPorts(); +} + +void SMPC_SetInput(unsigned port, const char* type, uint8* ptr) +{ + assert(port < 13); + + if(port == 12) + { + MiscInputPtr = ptr; + return; + } + // + // + // + IODevice* nd = nullptr; + + if(!strcmp(type, "none")) + nd = &PossibleDevices[port].none; + else if(!strcmp(type, "gamepad")) + nd = &PossibleDevices[port].gamepad; + else if(!strcmp(type, "3dpad")) + nd = &PossibleDevices[port].threedpad; + else if(!strcmp(type, "mouse")) + nd = &PossibleDevices[port].mouse; + else if(!strcmp(type, "wheel")) + nd = &PossibleDevices[port].wheel; + else if(!strcmp(type, "mission") || !strcmp(type, "missionwoa")) + nd = &PossibleDevices[port].mission; + else if(!strcmp(type, "dmission") || !strcmp(type, "dmissionwoa")) + nd = &PossibleDevices[port].dualmission; + else if(!strcmp(type, "keyboard")) + nd = &PossibleDevices[port].keyboard; +// else if(!strcmp(type, "jpkeyboard")) +// nd = &PossibleDevices[port].jpkeyboard; + else + abort(); + + VirtualPorts[port] = nd; + VirtualPortsDPtr[port] = ptr; + + MapPorts(); +} + +#if 0 +static void RTC_Reset(void) +{ + + +} +#endif + +/*void SMPC_LoadNV(Stream* s) +{ + RTC.Valid = s->get_u8(); + s->read(RTC.raw, sizeof(RTC.raw)); + s->read(SaveMem, sizeof(SaveMem)); +} + +void SMPC_SaveNV(Stream* s) +{ + s->put_u8(RTC.Valid); + s->write(RTC.raw, sizeof(RTC.raw)); + s->write(SaveMem, sizeof(SaveMem)); +}*/ + +void SMPC_SetRTC(const struct tm* ht, const uint8 lang) +{ + if(!ht) + { + RTC.Valid = false; + RTC.year[0] = 0x19; + RTC.year[1] = 0x93; + RTC.wday_mon = 0x5C; + RTC.mday = 0x31; + RTC.hour = 0x23; + RTC.minute = 0x59; + RTC.second = 0x59; + + for(unsigned i = 0; i < 4; i++) + SaveMem[i] = 0x00; + } + else + { + int year_adj = ht->tm_year; + //if(year_adj >= 100) + // year_adj = 100 + ((year_adj - 100) % 28); + + RTC.Valid = true; //false; + RTC.year[0] = U8_to_BCD(19 + year_adj / 100); + RTC.year[1] = U8_to_BCD(year_adj % 100); + RTC.wday_mon = (std::min(6, ht->tm_wday) << 4) | ((std::min(11, ht->tm_mon) + 1) << 0); + RTC.mday = U8_to_BCD(std::min(31, ht->tm_mday)); + RTC.hour = U8_to_BCD(std::min(23, ht->tm_hour)); + RTC.minute = U8_to_BCD(std::min(59, ht->tm_min)); + RTC.second = U8_to_BCD(std::min(59, ht->tm_sec)); + + //if((SaveMem[3] & 0x0F) <= 0x05 || (SaveMem[3] & 0x0F) == 0xF) + SaveMem[3] = (SaveMem[3] & 0xF0) | lang; + } +} + +void SMPC_Init(const uint8 area_code_arg, const int32 master_clock_arg) +{ + AreaCode = area_code_arg; + MasterClock = master_clock_arg; + + ResetPending = false; + vb = false; + lastts = 0; + + for(unsigned sp = 0; sp < 2; sp++) + SPorts[sp] = nullptr; + + for(unsigned i = 0; i < 12; i++) + { + VirtualPorts[i] = nullptr; + SMPC_SetInput(i, "none", NULL); + } + + SMPC_SetRTC(NULL, 0); +} + +bool SMPC_IsSlaveOn(void) +{ + return SlaveSH2On; +} + +static void SlaveOn(void) +{ + SlaveSH2On = true; + CPU[1].AdjustTS(SH7095_mem_timestamp, true); + CPU[1].Reset(true); + SS_SetEventNT(&events[SS_EVENT_SH2_S_DMA], SH7095_mem_timestamp + 1); +} + +static void SlaveOff(void) +{ + SlaveSH2On = false; + CPU[1].Reset(true); + CPU[1].AdjustTS(0x7FFFFFFF, true); + SS_SetEventNT(&events[SS_EVENT_SH2_S_DMA], SS_EVENT_DISABLED_TS); +} + +static void TurnSoundCPUOn(void) +{ + SOUND_Reset68K(); + SoundCPUOn = true; + SOUND_Set68KActive(true); +} + +static void TurnSoundCPUOff(void) +{ + SOUND_Reset68K(); + SoundCPUOn = false; + SOUND_Set68KActive(false); +} + +void SMPC_Reset(bool powering_up) +{ + SlaveOff(); + TurnSoundCPUOff(); + CDOn = true; // ? false; + + ResetButtonCount = 0; + ResetNMIEnable = false; // or only on powering_up? + + CPU[0].SetNMI(true); + + memset(IREG, 0, sizeof(IREG)); + memset(OREG, 0, sizeof(OREG)); + PendingCommand = -1; + ExecutingCommand = -1; + SF = 0; + + BusBuffer = 0x00; + + for(unsigned port = 0; port < 2; port++) + { + for(unsigned sel = 0; sel < 2; sel++) + { + DataOut[port][sel] = 0; + DataDir[port][sel] = 0; + } + DirectModeEn[port] = false; + ExLatchEn[port] = false; + UpdateIOBus(port); + } + + ResetPending = false; + + PendingClockDivisor = 0; + CurrentClockDivisor = CLOCK_DIVISOR_26M; + + SubPhase = 0; + PendingVB = false; + ClockCounter = 0; + // + memset(&JRS, 0, sizeof(JRS)); +} + +int32 SMPC_StartFrame(EmulateSpecStruct* espec) +{ + if(ResetPending) + SS_Reset(false); + + if(PendingClockDivisor > 0) + { + CurrentClockDivisor = PendingClockDivisor; + PendingClockDivisor = 0; + } + + if(!SlaveSH2On) + CPU[1].AdjustTS(0x7FFFFFFF, true); + + SMPC_ClockRatio = (1ULL << 32) * 4000000 * CurrentClockDivisor / MasterClock; + SOUND_SetClockRatio((1ULL << 32) * 11289600 * CurrentClockDivisor / MasterClock); + CDB_SetClockRatio((1ULL << 32) * 11289600 * CurrentClockDivisor / MasterClock); + + return CurrentClockDivisor; +} + +void SMPC_UpdateOutput(void) +{ + for(unsigned vp = 0; vp < 12; vp++) + { + VirtualPorts[vp]->UpdateOutput(VirtualPortsDPtr[vp]); + } +} + +void SMPC_UpdateInput(const int32 time_elapsed) +{ + //printf("%8d\n", time_elapsed); + + ResetButtonPhysStatus = (bool)(*MiscInputPtr & 0x1); + for(unsigned vp = 0; vp < 12; vp++) + { + VirtualPorts[vp]->UpdateInput(VirtualPortsDPtr[vp], time_elapsed); + } +} + + +void SMPC_Write(const sscpu_timestamp_t timestamp, uint8 A, uint8 V) +{ + BusBuffer = V; + A &= 0x3F; + + SS_DBGTI(SS_DBG_SMPC_REGW, "[SMPC] Write to 0x%02x:0x%02x", A, V); + + // + // Call VDP2::Update() to prevent out-of-temporal-order calls to SMPC_Update() from here and the event system. + // + SS_SetEventNT(&events[SS_EVENT_VDP2], VDP2::Update(timestamp)); // TODO: conditionalize so we don't consume so much CPU time if a game writes continuously to SMPC ports + sscpu_timestamp_t nt = SMPC_Update(timestamp); + switch(A) + { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + if(MDFN_UNLIKELY(ExecutingCommand >= 0)) + { + SS_DBGTI(SS_DBG_WARNING | SS_DBG_SMPC, "[SMPC] Input register %u port written with 0x%02x while command 0x%02x is executing.", A, V, ExecutingCommand); + } + + IREG[A] = V; + break; + + case 0x0F: + if(MDFN_UNLIKELY(ExecutingCommand >= 0)) + { + SS_DBGTI(SS_DBG_WARNING | SS_DBG_SMPC, "[SMPC] Command port written with 0x%02x while command 0x%02x is still executing.", V, ExecutingCommand); + } + + if(MDFN_UNLIKELY(PendingCommand >= 0)) + { + SS_DBGTI(SS_DBG_WARNING | SS_DBG_SMPC, "[SMPC] Command port written with 0x%02x while command 0x%02x is still pending.", V, PendingCommand); + } + + PendingCommand = V; + break; + + case 0x31: + if(MDFN_UNLIKELY(SF)) + { + SS_DBGTI(SS_DBG_WARNING | SS_DBG_SMPC, "[SMPC] SF port written while SF is 1."); + } + + SF = true; + break; + + // + // + // + case 0x3A: + DataOut[0][1] = V & 0x7F; + UpdateIOBus(0); + break; + + case 0x3B: + DataOut[1][1] = V & 0x7F; + UpdateIOBus(1); + break; + + case 0x3C: + DataDir[0][1] = V & 0x7F; + UpdateIOBus(0); + break; + + case 0x3D: + DataDir[1][1] = V & 0x7F; + UpdateIOBus(1); + break; + + case 0x3E: + DirectModeEn[0] = (bool)(V & 0x1); + UpdateIOBus(0); + + DirectModeEn[1] = (bool)(V & 0x2); + UpdateIOBus(1); + break; + + case 0x3F: + ExLatchEn[0] = (bool)(V & 0x1); + ExLatchEn[1] = (bool)(V & 0x2); + break; + + default: + SS_DBG(SS_DBG_WARNING | SS_DBG_SMPC, "[SMPC] Unknown write of 0x%02x to 0x%02x\n", V, A); + break; + + } + + if(PendingCommand >= 0) + nt = timestamp + 1; + + SS_SetEventNT(&events[SS_EVENT_SMPC], nt); +} + +uint8 SMPC_Read(const sscpu_timestamp_t timestamp, uint8 A) +{ + uint8 ret = BusBuffer; + + A &= 0x3F; + + switch(A) + { + default: + SS_DBG(SS_DBG_WARNING | SS_DBG_SMPC, "[SMPC] Unknown read from 0x%02x\n", A); + break; + + case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: + case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1E: case 0x1F: + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: + case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2E: case 0x2F: + if(MDFN_UNLIKELY(ExecutingCommand >= 0)) + { + //SS_DBG(SS_DBG_WARNING | SS_DBG_SMPC, "[SMPC] Output register %u port read while command 0x%02x is executing.\n", A - 0x10, ExecutingCommand); + } + + ret = (OREG - 0x10)[A]; + break; + + case 0x30: + if(MDFN_UNLIKELY(ExecutingCommand >= 0)) + { + //SS_DBG(SS_DBG_WARNING | SS_DBG_SMPC, "[SMPC] SR port read while command 0x%02x is executing.\n", ExecutingCommand); + } + + ret = SR; + break; + + case 0x31: + ret &= ~0x01; + ret |= SF; + break; + + case 0x3A: + ret = (ret & 0x80) | IOBusState[0]; + break; + + case 0x3B: + ret = (ret & 0x80) | IOBusState[1]; + break; + + } + + return ret; +} + +void SMPC_ResetTS(void) +{ + lastts = 0; +} + +#define SMPC_WAIT_UNTIL_COND(cond) { \ + case __COUNTER__: \ + ClockCounter = 0; /* before if(), not after, otherwise the variable will overflow eventually. */ \ + if(!(cond)) \ + { \ + SubPhase = __COUNTER__ - SubPhaseBias - 1; \ + return timestamp + 1000; \ + } \ + } + +#define SMPC_WAIT_UNTIL_COND_TIMEOUT(cond, n) \ + { \ + ClockCounter -= (int64)(n) << 32; \ + case __COUNTER__: \ + if(!(cond) && ClockCounter < 0) \ + { \ + SubPhase = __COUNTER__ - SubPhaseBias - 1; \ + return timestamp + (-ClockCounter + SMPC_ClockRatio - 1) / SMPC_ClockRatio; \ + } \ + ClockCounter = 0; \ + } + +#define SMPC_EAT_CLOCKS(n) \ + { \ + ClockCounter -= (int64)(n) << 32; \ + case __COUNTER__: \ + if(ClockCounter < 0) \ + { \ + SubPhase = __COUNTER__ - SubPhaseBias - 1; \ + return timestamp + (-ClockCounter + SMPC_ClockRatio - 1) / SMPC_ClockRatio; \ + } \ + /*printf("%f\n", (double)ClockCounter / (1LL << 32));*/ \ + } \ + + +static unsigned RTC_BCDInc(uint8 v) +{ + unsigned tmp = v & 0xF; + + tmp++; + + if(tmp >= 0xA) + tmp += 0x06; + + tmp += v & 0xF0; + + if(tmp >= 0xA0) + tmp += 0x60; + + return tmp; +} + +static void RTC_IncTime(void) +{ + // Seconds + if(RTC.second == 0x59) + { + RTC.second = 0x00; + + // Minutes + if(RTC.minute == 0x59) + { + RTC.minute = 0x00; + + // Hours + if(RTC.hour == 0x23) + { + RTC.hour = 0x00; + + // Day of week + if(RTC.wday_mon >= 0x60) + RTC.wday_mon &= 0x0F; + else + RTC.wday_mon += 0x10; + + // + static const uint8 mdtab[0x10] = { + // Jan, Feb, Mar, Apr, May, June, July, Aug, Sept, Oct, Nov, Dec + 0x10, 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31, 0xC1, 0xF5, 0xFF + }; + const uint8 day_compare = mdtab[RTC.wday_mon & 0x0F] + ((RTC.wday_mon & 0x0F) == 0x02 && ((RTC.year[1] & 0x1F) < 0x1A) && !((RTC.year[1] + ((RTC.year[1] & 0x10) >> 3)) & 0x3)); + + // Day of month + if(RTC.mday >= day_compare) + { + RTC.mday = 0x01; + + // Month of year + if((RTC.wday_mon & 0x0F) == 0x0C) + { + RTC.wday_mon &= 0xF0; + RTC.wday_mon |= 0x01; + + // Year + unsigned tmp = RTC_BCDInc(RTC.year[1]); + RTC.year[1] = tmp; + + if(tmp >= 0x100) + RTC.year[0] = RTC_BCDInc(RTC.year[0]); + } + else + RTC.wday_mon++; + } + else + RTC.mday = RTC_BCDInc(RTC.mday); + } + else + RTC.hour = RTC_BCDInc(RTC.hour); + } + else + RTC.minute = RTC_BCDInc(RTC.minute); + } + else + RTC.second = RTC_BCDInc(RTC.second); +} + +enum { SubPhaseBias = __COUNTER__ + 1 }; +sscpu_timestamp_t SMPC_Update(sscpu_timestamp_t timestamp) +{ + int64 clocks; + + if(MDFN_UNLIKELY(timestamp < lastts)) + { + SS_DBG(SS_DBG_WARNING | SS_DBG_SMPC, "[SMPC] [BUG] timestamp(%d) < lastts(%d)\n", timestamp, lastts); + clocks = 0; + } + else + { + clocks = (int64)(timestamp - lastts) * SMPC_ClockRatio; + lastts = timestamp; + } + + ClockCounter += clocks; + RTC.ClockAccum += clocks; + JRS.TimeCounter += clocks; + + switch(SubPhase + SubPhaseBias) + { + for(;;) + { + default: + case __COUNTER__: + + SMPC_WAIT_UNTIL_COND(PendingCommand >= 0 || PendingVB); + + if(PendingVB && PendingCommand < 0) + { + PendingVB = false; + + if(JRS.OptReadTime) + JRS.OptWaitUntilTime = std::max(0, (JRS.TimeCounter >> 32) - JRS.OptReadTime - 5000); + else + JRS.OptWaitUntilTime = 0; + JRS.TimeCounter = 0; + SMPC_EAT_CLOCKS(234); + + SR &= ~SR_RESB; + if(ResetButtonPhysStatus) // FIXME: Semantics may not be right in regards to CMD_RESENAB timing. + { + SR |= SR_RESB; + if(ResetButtonCount >= 0) + { + ResetButtonCount++; + + if(ResetButtonCount >= 3) + { + ResetButtonCount = 3; + + if(ResetNMIEnable) + { + CPU[0].SetNMI(false); + CPU[0].SetNMI(true); + + ResetButtonCount = -1; + } + } + } + } + else + ResetButtonCount = 0; + + // + // Do RTC increment here + // + while(MDFN_UNLIKELY(RTC.ClockAccum >= (4000000ULL << 32))) + { + RTC_IncTime(); + RTC.ClockAccum -= (4000000ULL << 32); + } + + continue; + } + + ExecutingCommand = PendingCommand; + PendingCommand = -1; + + SMPC_EAT_CLOCKS(92); + if(ExecutingCommand < 0x20) + { + OREG[0x1F] = ExecutingCommand; + + SS_DBGTI(SS_DBG_SMPC, "[SMPC] Command 0x%02x --- 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", ExecutingCommand, IREG[0], IREG[1], IREG[2], IREG[3], IREG[4], IREG[5], IREG[6]); + + if(ExecutingCommand == CMD_MSHON) + { + + } + else if(ExecutingCommand == CMD_SSHON) + { + if(!SlaveSH2On) + SlaveOn(); + } + else if(ExecutingCommand == CMD_SSHOFF) + { + if(SlaveSH2On) + SlaveOff(); + } + else if(ExecutingCommand == CMD_SNDON) + { + if(!SoundCPUOn) + TurnSoundCPUOn(); + } + else if(ExecutingCommand == CMD_SNDOFF) + { + if(SoundCPUOn) + TurnSoundCPUOff(); + } + else if(ExecutingCommand == CMD_CDON) + { + CDOn = true; + } + else if(ExecutingCommand == CMD_CDOFF) + { + CDOn = false; + } + else if(ExecutingCommand == CMD_SYSRES) + { + ResetPending = true; + SMPC_WAIT_UNTIL_COND(!ResetPending); + + // TODO/FIXME(unreachable currently?): + } + else if(ExecutingCommand == CMD_CKCHG352 || ExecutingCommand == CMD_CKCHG320) + { + // Devour some time + + if(SlaveSH2On) + SlaveOff(); + + if(SoundCPUOn) + TurnSoundCPUOff(); + + SOUND_Reset(false); + VDP1::Reset(false); + VDP2::Reset(false); + SCU_Reset(false); + + // Change clock + PendingClockDivisor = (ExecutingCommand == CMD_CKCHG352) ? CLOCK_DIVISOR_28M : CLOCK_DIVISOR_26M; + + // Wait for a few vblanks + SMPC_WAIT_UNTIL_COND(!vb); + SMPC_WAIT_UNTIL_COND(vb); + SMPC_WAIT_UNTIL_COND(!vb); + SMPC_WAIT_UNTIL_COND(vb); + SMPC_WAIT_UNTIL_COND(!vb); + SMPC_WAIT_UNTIL_COND(vb); + + + // + SMPC_WAIT_UNTIL_COND(!PendingClockDivisor); + + // Send NMI to master SH-2 + CPU[0].SetNMI(false); + CPU[0].SetNMI(true); + } + else if(ExecutingCommand == CMD_INTBACK) + { + //SS_DBGTI(SS_DBG_SMPC, "[SMPC] INTBACK IREG0=0x%02x, IREG1=0x%02x, IREG2=0x%02x, %d", IREG[0], IREG[1], IREG[2], vb); + + SR &= ~SR_NPE; + if(IREG[0] & 0xF) + { + SMPC_EAT_CLOCKS(952); + + OREG[0] = (RTC.Valid << 7) | (!ResetNMIEnable << 6); + + for(unsigned i = 0; i < 7; i++) + OREG[1 + i] = RTC.raw[i]; + + OREG[0x8] = 0; // TODO FIXME: Cartridge code? + OREG[0x9] = AreaCode; + OREG[0xA] = 0x24 | + ((CurrentClockDivisor == CLOCK_DIVISOR_28M) << 6) | + (SlaveSH2On << 4) | + (true << 3) | // TODO?: Master NMI + (true << 1) | // TODO?: sysres + (SoundCPUOn << 0); // sndres + + OREG[0xB] = (CDOn << 6) | (1 << 1); // cdres, TODO?: bit1 + + for(unsigned i = 0; i < 4; i++) + OREG[0xC + i] = SaveMem[i]; + + if(IREG[1] & 0x8) + SR |= SR_NPE; + + SR &= ~0x80; + SR |= 0x0F; + + SCU_SetInt(SCU_INT_SMPC, true); + SCU_SetInt(SCU_INT_SMPC, false); + } + + // Wait for !vb, wait until (IREG[0] & 0x80), time-optimization wait. + + if(IREG[1] & 0x8) + { + InputLagged = false; + if (InputCallback) + InputCallback(); + + + #define JR_WAIT(cond) { SMPC_WAIT_UNTIL_COND((cond) || PendingVB); if(PendingVB) { SS_DBGTI(SS_DBG_SMPC, "[SMPC] abortjr wait"); goto AbortJR; } } + #define JR_EAT(n) { SMPC_EAT_CLOCKS(n); if(PendingVB) { SS_DBGTI(SS_DBG_SMPC, "[SMPC] abortjr eat"); goto AbortJR; } } + #define JR_WRNYB(val) \ + { \ + if(!JRS.OWP) \ + { \ + if(JRS.PDCounter > 0) \ + { \ + SR = (SR & ~SR_PDL) | ((JRS.PDCounter < 0x2) ? SR_PDL : 0); \ + SR = (SR & ~0xF) | (JRS.Mode[0] << 0) | (JRS.Mode[1] << 2); \ + SR |= SR_NPE; \ + SR |= 0x80; \ + SCU_SetInt(SCU_INT_SMPC, true); \ + SCU_SetInt(SCU_INT_SMPC, false); \ + JR_WAIT((bool)(IREG[0] & 0x80) == JRS.NextContBit || (IREG[0] & 0x40)); \ + if(IREG[0] & 0x40) \ + { \ + SS_DBGTI(SS_DBG_SMPC, "[SMPC] Big Read Break"); \ + goto AbortJR; \ + } \ + JRS.NextContBit = !JRS.NextContBit; \ + } \ + if(JRS.PDCounter < 0xFF) \ + JRS.PDCounter++; \ + } \ + \ + OREG[(JRS.OWP >> 1)] &= 0x0F << ((JRS.OWP & 1) << 2); \ + OREG[(JRS.OWP >> 1)] |= ((val) & 0xF) << (((JRS.OWP & 1) ^ 1) << 2); \ + JRS.OWP = (JRS.OWP + 1) & 0x3F; \ + } + + #define JR_BS IOBusState[JRS.CurPort] + + #define JR_TH_TR(th, tr) \ + { \ + DataDir[JRS.CurPort][0] = ((th >= 0) << 6) | ((tr >= 0) << 5); \ + DataOut[JRS.CurPort][0] = (DataOut[JRS.CurPort][0] & 0x1F) | (((th) > 0) << 6) | (((tr) > 0) << 5); \ + UpdateIOBus(JRS.CurPort); \ + } + + JR_WAIT(!vb); + JRS.NextContBit = true; + if(SR & SR_NPE) + { + JR_WAIT((bool)(IREG[0] & 0x80) == JRS.NextContBit || (IREG[0] & 0x40)); + if(IREG[0] & 0x40) + { + SS_DBGTI(SS_DBG_SMPC, "[SMPC] Break"); + goto AbortJR; + } + JRS.NextContBit = !JRS.NextContBit; + } + + JRS.PDCounter = 0; + JRS.TimeOptEn = !(IREG[1] & 0x2); + JRS.Mode[0] = (IREG[1] >> 4) & 0x3; + JRS.Mode[1] = (IREG[1] >> 6) & 0x3; + + JRS.OptReadTime = 0; + JRS.OptEatTime = std::max(0, (JRS.OptWaitUntilTime - (JRS.TimeCounter >> 32))); + JRS.OptWaitUntilTime = 0; + + if(JRS.TimeOptEn) + { + SMPC_WAIT_UNTIL_COND_TIMEOUT(PendingVB, JRS.OptEatTime); + if(PendingVB) + { + SS_DBGTI(SS_DBG_SMPC, "[SMPC] abortjr timeopt"); + goto AbortJR; + } + SS_SetEventNT(&events[SS_EVENT_MIDSYNC], timestamp + 1); + } + + JRS.StartTime = JRS.TimeCounter >> 32; + JR_EAT(120); + JRS.OWP = 0; + for(JRS.CurPort = 0; JRS.CurPort < 2; JRS.CurPort++) + { + JR_EAT(380); + + if(JRS.Mode[JRS.CurPort] & 0x2) + continue; + + // TODO: 255-byte read size mode. + + JRS.ID1 = 0; + JR_TH_TR(1, 1); + JR_EAT(50); + JRS.work[0] = JR_BS; + JRS.ID1 |= ((((JRS.work[0] >> 3) | (JRS.work[0] >> 2)) & 1) << 3) | ((((JRS.work[0] >> 1) | (JRS.work[0] >> 0)) & 1) << 2); + + JR_TH_TR(0, 1); + JR_EAT(50); + JRS.work[1] = JR_BS; + JRS.ID1 |= ((((JRS.work[1] >> 3) | (JRS.work[1] >> 2)) & 1) << 1) | ((((JRS.work[1] >> 1) | (JRS.work[1] >> 0)) & 1) << 0); + + //printf("%02x, %02x\n", JRS.work[0], JRS.work[1]); + + if(JRS.ID1 == 0xB) + { + // Saturn digital pad. + JR_TH_TR(1, 0) + JR_EAT(50); + JRS.work[2] = JR_BS; + + JR_TH_TR(0, 0) + JR_EAT(50); + JRS.work[3] = JR_BS; + + JR_EAT(30); + + JR_WRNYB(0xF); // Multitap ID + JR_EAT(21); + + JR_WRNYB(0x1); // Number of connected devices behind multitap + JR_EAT(21); + + JR_WRNYB(0x0); // Peripheral ID-2. + JR_EAT(21); + + JR_WRNYB(0x2); // Data size. + JR_EAT(21); + + JR_WRNYB(JRS.work[1] & 0xF); + JR_EAT(21); + + JR_WRNYB(JRS.work[2] & 0xF); + JR_EAT(21); + + JR_WRNYB(JRS.work[3] & 0xF); + JR_EAT(21); + + JR_WRNYB((JRS.work[0] & 0xF) | 0x7); + JR_EAT(21); + + //JR_EAT(); + + // + // + // + } + else if(JRS.ID1 == 0x3 || JRS.ID1 == 0x5) + { + JR_TH_TR(0, 0) + JR_EAT(50); + JR_WAIT(!(JR_BS & 0x10)); + JRS.ID2 = ((JR_BS & 0xF) << 4); + + JR_TH_TR(0, 1) + JR_EAT(50); + JR_WAIT(JR_BS & 0x10); + JRS.ID2 |= ((JR_BS & 0xF) << 0); + + //printf("%d, %02x %02x\n", JRS.CurPort, JRS.ID1, JRS.ID2); + + if(JRS.ID1 == 0x3) + JRS.ID2 = 0xE3; + + if((JRS.ID2 & 0xF0) == 0x40) // Multitap + { + JR_TH_TR(0, 0) + JR_EAT(50); + JR_WAIT(!(JR_BS & 0x10)); + JRS.IDTap = ((JRS.ID2 & 0xF) << 4) | (JR_BS & 0xF); + + JR_TH_TR(0, 1) + JR_EAT(50); + JR_WAIT(JR_BS & 0x10); + } + else + JRS.IDTap = 0xF1; + + JRS.TapCounter = 0; + JRS.TapCount = (JRS.IDTap & 0xF); + while(JRS.TapCounter < JRS.TapCount) + { + if(JRS.TapCount > 1) + { + JR_TH_TR(0, 0) + JR_EAT(50); + JR_WAIT(!(JR_BS & 0x10)); + JRS.ID2 = ((JR_BS & 0xF) << 4); + + JR_TH_TR(0, 1) + JR_EAT(50); + JR_WAIT(JR_BS & 0x10); + JRS.ID2 |= ((JR_BS & 0xF) << 0); + } + JRS.ReadCounter = 0; + JRS.ReadCount = ((JRS.ID2 & 0xF0) == 0xF0) ? 0 : (JRS.ID2 & 0xF); + while(JRS.ReadCounter < JRS.ReadCount) + { + JR_TH_TR(0, 0) + JR_EAT(50); + JR_WAIT(!(JR_BS & 0x10)); + JRS.ReadBuffer[JRS.ReadCounter] = ((JR_BS & 0xF) << 4); + + JR_TH_TR(0, 1) + JR_EAT(50); + JR_WAIT(JR_BS & 0x10); + JRS.ReadBuffer[JRS.ReadCounter] |= ((JR_BS & 0xF) << 0); + JRS.ReadCounter++; + } + + if(!JRS.TapCounter) + { + JR_WRNYB(JRS.IDTap >> 4); + JR_EAT(21); + + JR_WRNYB(JRS.IDTap >> 0); + JR_EAT(21); + } + + //printf("What: %d, %02x\n", JRS.TapCounter, JRS.ID2); + + JR_WRNYB(JRS.ID2 >> 4); + JR_EAT(21); + + JR_WRNYB(JRS.ID2 >> 0); + JR_EAT(21); + + JRS.WriteCounter = 0; + while(JRS.WriteCounter < JRS.ReadCounter) + { + JR_WRNYB(JRS.ReadBuffer[JRS.WriteCounter] >> 4); + JR_EAT(21); + + JR_WRNYB(JRS.ReadBuffer[JRS.WriteCounter] >> 0); + JR_EAT(21); + + JRS.WriteCounter++; + } + JRS.TapCounter++; + } + // Saturn analog joystick, keyboard, multitap + // OREG[0x0] = 0xF1; // Upper nybble, multitap ID. Lower nybble, number of connected devices behind multitap. + // OREG[0x1] = 0x02; // Upper nybble, peripheral ID 2. Lower nybble, data size. + } + else + { + JR_WRNYB(0xF); + JR_WRNYB(0x0); + } + JR_EAT(26); + JR_TH_TR(-1, -1); + } + + SR = (SR & ~SR_NPE); + SR = (SR & ~0xF) | (JRS.Mode[0] << 0) | (JRS.Mode[1] << 2); + SR = (SR & ~SR_PDL) | ((JRS.PDCounter < 0x2) ? SR_PDL : 0); + SR |= 0x80; + SCU_SetInt(SCU_INT_SMPC, true); + SCU_SetInt(SCU_INT_SMPC, false); + + if(JRS.TimeOptEn) + JRS.OptReadTime = std::max(0, (JRS.TimeCounter >> 32) - JRS.StartTime); + } + AbortJR:; + // TODO: Set TH TR to inputs on abort. + } + else if(ExecutingCommand == CMD_SETTIME) // Warning: Execute RTC setting atomically(all values or none) in regards to emulator exit/power toggle. + { + SMPC_EAT_CLOCKS(380); + + RTC.ClockAccum = 0; // settime resets sub-second count. + RTC.Valid = true; + + for(unsigned i = 0; i < 7; i++) + RTC.raw[i] = IREG[i]; + } + else if(ExecutingCommand == CMD_SETSMEM) // Warning: Execute save mem setting(all values or none) atomically in regards to emulator exit/power toggle. + { + SMPC_EAT_CLOCKS(234); + + for(unsigned i = 0; i < 4; i++) + SaveMem[i] = IREG[i]; + } + else if(ExecutingCommand == CMD_NMIREQ) + { + CPU[0].SetNMI(false); + CPU[0].SetNMI(true); + } + else if(ExecutingCommand == CMD_RESENAB) + { + ResetNMIEnable = true; + } + else if(ExecutingCommand == CMD_RESDISA) + { + ResetNMIEnable = false; + } + } + + ExecutingCommand = -1; + SF = false; + continue; + } + } +} + +void SMPC_SetVB(sscpu_timestamp_t event_timestamp, bool vb_status) +{ + if(vb ^ vb_status) + { + if(vb_status) // Going into vblank + PendingVB = true; + + SS_SetEventNT(&events[SS_EVENT_SMPC], event_timestamp + 1); + } + + vb = vb_status; +} + +/*static const std::vector InputDeviceInfoSSVPort = +{ + // None + { + "none", + "none", + NULL, + IDII_Empty + }, + + // Digital Gamepad + { + "gamepad", + "Digital Gamepad", + "Standard Saturn digital gamepad.", + IODevice_Gamepad_IDII + }, + + // 3D Gamepad + { + "3dpad", + "3D Control Pad", + "3D Control Pad", + IODevice_3DPad_IDII + }, + + // Mouse + { + "mouse", + "Mouse", + "Mouse", + IODevice_Mouse_IDII + }, + + // Steering Wheel + { + "wheel", + "Steering Wheel", + "Arcade Racer/Racing Controller", + IODevice_Wheel_IDII + }, + + // Mission Stick + { + "mission", + "Mission Stick", + "Mission Stick", + IODevice_Mission_IDII + }, +#if 0 + // Mission Stick (No Autofire) + { + "missionwoa", + "Mission (No AF)", + "Mission Stick, without autofire functionality(for less things to map).", + IODevice_MissionNoAF_IDII + }, +#endif + // Dual Mission Stick + { + "dmission", + "Dual Mission", + "Dual Mission Sticks, useful for \"Panzer Dragoon Zwei\". With 30 inputs to map, don't get distracted by..LOOK A LOBSTER!", + IODevice_DualMission_IDII + }, + +#if 0 + // Dual Mission Stick (No Autofire) + { + "dmissionwoa", + "Dual Mission (No AF)", + "Dual Mission Sticks (No Autofire)", + IODevice_DualMissionNoAF_IDII + }, +#endif + + // Keyboard (101-key US) + { + "keyboard", + "Keyboard (US)", + "101-key US keyboard.", + IODevice_Keyboard_US101_IDII, + InputDeviceInfoStruct::FLAG_KEYBOARD + }, + +#if 0 + // Keyboard (Japanese) + { + "jpkeyboard", + "Keyboard (JP)", + "89-key Japanese keyboard.", + IODevice_JPKeyboard_IDII, + InputDeviceInfoStruct::FLAG_KEYBOARD + }, +#endif +}; + +static IDIISG IDII_Builtin = +{ + { "reset", "Reset", -1, IDIT_RESET_BUTTON }, + { "smpc_reset", "SMPC Reset", -1, IDIT_BUTTON }, +}; + +static const std::vector InputDeviceInfoBuiltin = +{ + { + "builtin", + "builtin", + NULL, + IDII_Builtin + } +}; + +const std::vector SMPC_PortInfo = +{ + { "port1", "Virtual Port 1", InputDeviceInfoSSVPort, "gamepad" }, + { "port2", "Virtual Port 2", InputDeviceInfoSSVPort, "gamepad" }, + { "port3", "Virtual Port 3", InputDeviceInfoSSVPort, "gamepad" }, + { "port4", "Virtual Port 4", InputDeviceInfoSSVPort, "gamepad" }, + { "port5", "Virtual Port 5", InputDeviceInfoSSVPort, "gamepad" }, + { "port6", "Virtual Port 6", InputDeviceInfoSSVPort, "gamepad" }, + { "port7", "Virtual Port 7", InputDeviceInfoSSVPort, "gamepad" }, + { "port8", "Virtual Port 8", InputDeviceInfoSSVPort, "gamepad" }, + { "port9", "Virtual Port 9", InputDeviceInfoSSVPort, "gamepad" }, + { "port10", "Virtual Port 10", InputDeviceInfoSSVPort, "gamepad" }, + { "port11", "Virtual Port 11", InputDeviceInfoSSVPort, "gamepad" }, + { "port12", "Virtual Port 12", InputDeviceInfoSSVPort, "gamepad" }, + + { "builtin", "Builtin", InputDeviceInfoBuiltin, "builtin" }, +};*/ + + +} diff --git a/waterbox/ss/smpc.h b/waterbox/ss/smpc.h new file mode 100644 index 0000000000..2076890baa --- /dev/null +++ b/waterbox/ss/smpc.h @@ -0,0 +1,100 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* smpc.h: +** Copyright (C) 2015-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_SMPC_H +#define __MDFN_SS_SMPC_H + +#include + +namespace MDFN_IEN_SS +{ + +enum +{ + SMPC_AREA_JP = 0x1, + SMPC_AREA_ASIA_NTSC = 0x2, + SMPC_AREA_NA = 0x4, + SMPC_AREA_CSA_NTSC = 0x5, + SMPC_AREA_KR = 0x6, + + SMPC_AREA_ASIA_PAL = 0xA, + SMPC_AREA_EU_PAL = 0xC, + SMPC_AREA_CSA_PAL = 0xD, + // + // + // + SMPC_AREA__PAL_MASK = 0x8 +}; + +enum +{ + SMPC_RTC_LANG_ENGLISH = 0, + SMPC_RTC_LANG_GERMAN = 1, + SMPC_RTC_LANG_FRENCH = 2, + SMPC_RTC_LANG_SPANISH = 3, + SMPC_RTC_LANG_ITALIAN = 4, + SMPC_RTC_LANG_JAPANESE = 5, +}; + +void SMPC_Init(const uint8 area_code, const int32 master_clock) MDFN_COLD; +bool SMPC_IsSlaveOn(void); +void SMPC_Reset(bool powering_up) MDFN_COLD; +//void SMPC_LoadNV(Stream* s) MDFN_COLD; +//void SMPC_SaveNV(Stream* s) MDFN_COLD; + +void SMPC_SetRTC(const struct tm* ht, const uint8 lang) MDFN_COLD; + +void SMPC_Write(const sscpu_timestamp_t timestamp, uint8 A, uint8 V) MDFN_HOT; +uint8 SMPC_Read(const sscpu_timestamp_t timestamp, uint8 A) MDFN_HOT; + +sscpu_timestamp_t SMPC_Update(sscpu_timestamp_t timestamp); +void SMPC_ResetTS(void); + +int32 SMPC_StartFrame(EmulateSpecStruct* espec); +void SMPC_UpdateInput(const int32 time_elapsed); +void SMPC_UpdateOutput(void); +void SMPC_SetInput(unsigned port, const char* type, uint8* ptr) MDFN_COLD; +void SMPC_SetMultitap(unsigned sport, bool enabled) MDFN_COLD; + +void SMPC_SetVB(sscpu_timestamp_t event_timestamp, bool vb_status); + +class IODevice +{ + public: + + IODevice() MDFN_COLD; + virtual ~IODevice() MDFN_COLD; + + virtual void Power(void) MDFN_COLD; + + // + // time_elapsed is emulated time elapsed since last call to UpdateInput(), in microseconds; + // it's mostly for keyboard emulation, to keep the implementation from becoming unnecessarily complex. + // + virtual void UpdateInput(const uint8* data, const int32 time_elapsed); + virtual void UpdateOutput(uint8* data); + virtual uint8 UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted); +}; + +//extern const std::vector SMPC_PortInfo; + +} +#endif diff --git a/waterbox/ss/sound.cpp b/waterbox/ss/sound.cpp new file mode 100644 index 0000000000..f4a1f9c76d --- /dev/null +++ b/waterbox/ss/sound.cpp @@ -0,0 +1,358 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* sound.cpp - Sound Emulation +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +// TODO: Bus between SCU and SCSP looks to be 8-bit, maybe implement that, but +// first test to see how the bus access cycle(s) work with respect to reading from +// registers whose values may change between the individual byte reads. +// (May not be worth emulating if it could possibly trigger problems in games) + +#include "ss.h" +#include "sound.h" +#include "scu.h" +#include "cdb.h" + +#include "m68k/m68k.h" + +namespace MDFN_IEN_SS +{ + +#include "scsp.h" + +static SS_SCSP SCSP; + +static M68K SoundCPU(true); +static int64 run_until_time; // 32.32 +static int32 next_scsp_time; + +static uint32 clock_ratio; +static sscpu_timestamp_t lastts; + +static int16 IBuffer[1024][2]; +static uint32 IBufferCount; +static int last_rate; +static uint32 last_quality; + +static INLINE void SCSP_SoundIntChanged(unsigned level) +{ + SoundCPU.SetIPL(level); +} + +static INLINE void SCSP_MainIntChanged(bool state) +{ +#ifndef MDFN_SSFPLAY_COMPILE + SCU_SetInt(SCU_INT_SCSP, state); +#endif +} + +#include "scsp.inc" + +// +// +template +static MDFN_FASTCALL T SoundCPU_BusRead(uint32 A); + +static MDFN_FASTCALL uint16 SoundCPU_BusReadInstr(uint32 A); + +template +static MDFN_FASTCALL void SoundCPU_BusWrite(uint32 A, T V); + +static MDFN_FASTCALL void SoundCPU_BusRMW(uint32 A, uint8(MDFN_FASTCALL *cb)(M68K *, uint8)); +static MDFN_FASTCALL unsigned SoundCPU_BusIntAck(uint8 level); +static MDFN_FASTCALL void SoundCPU_BusRESET(bool state); +// +// + +void SOUND_Init(void) +{ + memset(IBuffer, 0, sizeof(IBuffer)); + IBufferCount = 0; + + last_rate = -1; + last_quality = ~0U; + + run_until_time = 0; + next_scsp_time = 0; + lastts = 0; + + SoundCPU.BusRead8 = SoundCPU_BusRead; + SoundCPU.BusRead16 = SoundCPU_BusRead; + + SoundCPU.BusWrite8 = SoundCPU_BusWrite; + SoundCPU.BusWrite16 = SoundCPU_BusWrite; + + SoundCPU.BusReadInstr = SoundCPU_BusReadInstr; + + SoundCPU.BusRMW = SoundCPU_BusRMW; + + SoundCPU.BusIntAck = SoundCPU_BusIntAck; + SoundCPU.BusRESET = SoundCPU_BusRESET; + +#ifndef MDFN_SSFPLAY_COMPILE + SoundCPU.DBG_Warning = SS_DBG_Wrap; + SoundCPU.DBG_Verbose = SS_DBG_Wrap; +#endif + + SS_SetPhysMemMap(0x05A00000, 0x05A7FFFF, SCSP.GetRAMPtr(), 0x80000, true); + // TODO: MEM4B: SS_SetPhysMemMap(0x05A00000, 0x05AFFFFF, SCSP.GetRAMPtr(), 0x40000, true); + AddMemoryDomain("Sound Ram", SCSP.GetRAMPtr(), 0x100000, MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_WORDSIZE2); +} + +uint8 SOUND_PeekRAM(uint32 A) +{ + return ne16_rbo_be(SCSP.GetRAMPtr(), A & 0x7FFFF); +} + +void SOUND_PokeRAM(uint32 A, uint8 V) +{ + ne16_wbo_be(SCSP.GetRAMPtr(), A & 0x7FFFF, V); +} + +void SOUND_ResetTS(void) +{ + next_scsp_time -= SoundCPU.timestamp; + run_until_time -= (int64)SoundCPU.timestamp << 32; + SoundCPU.timestamp = 0; + + lastts = 0; +} + +void SOUND_Reset(bool powering_up) +{ + SCSP.Reset(powering_up); + SoundCPU.Reset(powering_up); +} + +void SOUND_Reset68K(void) +{ + SoundCPU.Reset(false); +} + +void SOUND_Set68KActive(bool active) +{ + SoundCPU.SetExtHalted(!active); +} + +uint16 SOUND_Read16(uint32 A) +{ + uint16 ret; + + SCSP.RW(A, ret); + + return ret; +} + +void SOUND_Write8(uint32 A, uint8 V) +{ + SCSP.RW(A, V); +} + +void SOUND_Write16(uint32 A, uint16 V) +{ + SCSP.RW(A, V); +} + +static NO_INLINE void RunSCSP(void) +{ + CDB_GetCDDA(SCSP.GetEXTSPtr()); + // + // + int16 *const bp = IBuffer[IBufferCount]; + SCSP.RunSample(bp); + //bp[0] = rand(); + //bp[1] = rand(); + bp[0] = (bp[0] * 27 + 16) >> 5; + bp[1] = (bp[1] * 27 + 16) >> 5; + + IBufferCount = (IBufferCount + 1) & 1023; + next_scsp_time += 256; +} + +// Ratio between SH-2 clock and 68K clock (sound clock / 2) +void SOUND_SetClockRatio(uint32 ratio) +{ + clock_ratio = ratio; +} + +sscpu_timestamp_t SOUND_Update(sscpu_timestamp_t timestamp) +{ + run_until_time += ((uint64)(timestamp - lastts) * clock_ratio); + lastts = timestamp; + // + // + if (MDFN_LIKELY(SoundCPU.timestamp < (run_until_time >> 32))) + { + do + { + int32 next_time = std::min(next_scsp_time, run_until_time >> 32); + + SoundCPU.Run(next_time); + + if (SoundCPU.timestamp >= next_scsp_time) + RunSCSP(); + } while (MDFN_LIKELY(SoundCPU.timestamp < (run_until_time >> 32))); + } + else + { + while (next_scsp_time < (run_until_time >> 32)) + RunSCSP(); + } + + return timestamp + 128; // FIXME +} + +void SOUND_StartFrame(double rate, uint32 quality) +{ + if ((int)rate != last_rate || quality != last_quality) + { + int err = 0; + last_rate = (int)rate; + last_quality = quality; + } +} + +int32 SOUND_FlushOutput(int16 *SoundBuf, const int32 SoundBufMaxSize, const bool reverse) +{ + if (SoundBuf && reverse) + { + for (unsigned lr = 0; lr < 2; lr++) + { + int16 *p0 = &IBuffer[0][lr]; + int16 *p1 = &IBuffer[IBufferCount - 1][lr]; + unsigned count = IBufferCount >> 1; + + while (MDFN_LIKELY(count--)) + { + std::swap(*p0, *p1); + + p0 += 2; + p1 -= 2; + } + } + } + + if (last_rate == 44100) + { + int32 ret = IBufferCount; + + memcpy(SoundBuf, IBuffer, IBufferCount * 2 * sizeof(int16)); + IBufferCount = 0; + + return (ret); + } + else + { + IBufferCount = 0; + return 0; + } +} + +// +// +// TODO: test masks. +// +template +static MDFN_FASTCALL T SoundCPU_BusRead(uint32 A) +{ + T ret; + + SoundCPU.timestamp += 4; + + if (MDFN_UNLIKELY(SoundCPU.timestamp >= next_scsp_time)) + RunSCSP(); + + SCSP.RW(A & 0x1FFFFF, ret); + + SoundCPU.timestamp += 2; + + return ret; +} + +static MDFN_FASTCALL uint16 SoundCPU_BusReadInstr(uint32 A) +{ + uint16 ret; + + SoundCPU.timestamp += 4; + + //if(MDFN_UNLIKELY(SoundCPU.timestamp >= next_scsp_time)) + // RunSCSP(); + + SCSP.RW(A & 0x1FFFFF, ret); + + SoundCPU.timestamp += 2; + + return ret; +} + +template +static MDFN_FASTCALL void SoundCPU_BusWrite(uint32 A, T V) +{ + if (MDFN_UNLIKELY(SoundCPU.timestamp >= next_scsp_time)) + RunSCSP(); + + SoundCPU.timestamp += 2; + SCSP.RW(A & 0x1FFFFF, V); + SoundCPU.timestamp += 2; +} + +static MDFN_FASTCALL void SoundCPU_BusRMW(uint32 A, uint8(MDFN_FASTCALL *cb)(M68K *, uint8)) +{ + uint8 tmp; + + SoundCPU.timestamp += 4; + + if (MDFN_UNLIKELY(SoundCPU.timestamp >= next_scsp_time)) + RunSCSP(); + + SCSP.RW(A & 0x1FFFFF, tmp); + + tmp = cb(&SoundCPU, tmp); + + SoundCPU.timestamp += 6; + + SCSP.RW(A & 0x1FFFFF, tmp); + + SoundCPU.timestamp += 2; +} + +static MDFN_FASTCALL unsigned SoundCPU_BusIntAck(uint8 level) +{ + return M68K::BUS_INT_ACK_AUTO; +} + +static MDFN_FASTCALL void SoundCPU_BusRESET(bool state) +{ + //SS_DBG(SS_DBG_WARNING, "[M68K] RESET: %d @ time %d\n", state, SoundCPU.timestamp); + if (state) + { + SoundCPU.Reset(false); + } +} + +uint32 SOUND_GetSCSPRegister(const unsigned id, char *const special, const uint32 special_len) +{ + return SCSP.GetRegister(id, special, special_len); +} + +void SOUND_SetSCSPRegister(const unsigned id, const uint32 value) +{ + SCSP.SetRegister(id, value); +} +} diff --git a/waterbox/ss/sound.h b/waterbox/ss/sound.h new file mode 100644 index 0000000000..4d0a08b54f --- /dev/null +++ b/waterbox/ss/sound.h @@ -0,0 +1,52 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* sound.h: +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_SOUND_H +#define __MDFN_SS_SOUND_H + +namespace MDFN_IEN_SS +{ + +void SOUND_Init(void) MDFN_COLD; +void SOUND_Reset(bool powering_up) MDFN_COLD; + +void SOUND_Set68KActive(bool active); +void SOUND_Reset68K(void); + +void SOUND_SetClockRatio(uint32 ratio); // Ratio between SH-2 clock and 68K clock (sound clock / 2) +sscpu_timestamp_t SOUND_Update(sscpu_timestamp_t timestamp); +void SOUND_ResetTS(void); +void SOUND_StartFrame(double rate, uint32 quality); +int32 SOUND_FlushOutput(int16* SoundBuf, const int32 SoundBufMaxSize, const bool reverse); + +uint16 SOUND_Read16(uint32 A); +void SOUND_Write8(uint32 A, uint8 V); +void SOUND_Write16(uint32 A, uint16 V); + +uint8 SOUND_PeekRAM(uint32 A); +void SOUND_PokeRAM(uint32 A, uint8 V); + +uint32 SOUND_GetSCSPRegister(const unsigned id, char* const special, const uint32 special_len) MDFN_COLD; +void SOUND_SetSCSPRegister(const unsigned id, const uint32 value) MDFN_COLD; + +} + +#endif diff --git a/waterbox/ss/ss.cpp b/waterbox/ss/ss.cpp new file mode 100644 index 0000000000..ec0cf755ac --- /dev/null +++ b/waterbox/ss/ss.cpp @@ -0,0 +1,1274 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* ss.cpp - Saturn Core Emulation and Support Functions +** Copyright (C) 2015-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +// WARNING: Be careful with 32-bit access to 16-bit space, bus locking, etc. in respect to DMA and event updates(and where they can occur). + +#include + +#include + +#include "ss.h" +#include "cdrom/cdromif.h" +#include "sound.h" +#include "scsp.h" // For debug.inc +#include "smpc.h" +#include "cdb.h" +#include "vdp1.h" +#include "vdp2.h" +#include "scu.h" +#include "cart.h" +#include "db.h" + +namespace MDFN_IEN_SS +{ + +static sscpu_timestamp_t MidSync(const sscpu_timestamp_t timestamp); + +#ifdef MDFN_SS_DEV_BUILD +uint32 ss_dbg_mask; +#endif +static const uint8 BRAM_Init_Data[0x10] = {0x42, 0x61, 0x63, 0x6b, 0x55, 0x70, 0x52, 0x61, 0x6d, 0x20, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74}; + +static void SaveBackupRAM(void); +static void LoadBackupRAM(void); +static void SaveCartNV(void); +static void LoadCartNV(void); +static void SaveRTC(void); +static void LoadRTC(void); + +static MDFN_COLD void BackupBackupRAM(void); +static MDFN_COLD void BackupCartNV(void); + +#include "sh7095.h" + +static uint8 SCU_MSH2VectorFetch(void); +static uint8 SCU_SSH2VectorFetch(void); + +static void INLINE MDFN_HOT CheckEventsByMemTS(void); + +SH7095 CPU[2]{{"SH2-M", SS_EVENT_SH2_M_DMA, SCU_MSH2VectorFetch}, {"SH2-S", SS_EVENT_SH2_S_DMA, SCU_SSH2VectorFetch}}; +static uint16* BIOSROM; +static uint16 WorkRAML[1024 * 1024 / sizeof(uint16)]; +static uint16 WorkRAMH[1024 * 1024 / sizeof(uint16)]; // Effectively 32-bit in reality, but 16-bit here because of CPU interpreter design(regarding fastmap). +static uint8 BackupRAM[32768]; +static bool BackupRAM_Dirty; + +static int64 EmulatedSS_MasterClock; + +#define SH7095_EXT_MAP_GRAN_BITS 16 +static uintptr_t SH7095_FastMap[1U << (32 - SH7095_EXT_MAP_GRAN_BITS)]; + +int32 SH7095_mem_timestamp; +uint32 SH7095_BusLock; +#include "scu.inc" + +#include "debug.inc" + +//static sha256_digest BIOS_SHA256; // SHA-256 hash of the currently-loaded BIOS; used for save state sanity checks. +static std::vector *cdifs = NULL; +static std::bitset<1U << (27 - SH7095_EXT_MAP_GRAN_BITS)> FMIsWriteable; + +template +static void INLINE SH7095_BusWrite(uint32 A, T V, const bool BurstHax, int32 *SH2DMAHax); + +template +static T INLINE SH7095_BusRead(uint32 A, const bool BurstHax, int32 *SH2DMAHax); + +// SH-2 region +// 0: 0x00000000-0x01FFFFFF +// 1: 0x02000000-0x03FFFFFF +// 2: 0x04000000-0x05FFFFFF +// 3: 0x06000000-0x07FFFFFF +// +// Never add anything to SH7095_mem_timestamp when DMAHax is true. +// +// When BurstHax is true and we're accessing high work RAM, don't add anything. +// +template +static INLINE void BusRW(uint32 A, T &V, const bool BurstHax, int32 *SH2DMAHax) +{ + // + // High work RAM + // + if (A >= 0x06000000 && A <= 0x07FFFFFF) + { + ne16_rwbo_be(WorkRAMH, A & 0xFFFFF, &V); + + if (!BurstHax) + { + if (!SH2DMAHax) + { + if (IsWrite) + { + SH7095_mem_timestamp = (SH7095_mem_timestamp + 4) & ~3; + } + else + { + SH7095_mem_timestamp += 7; + } + } + else + *SH2DMAHax -= IsWrite ? 3 : 6; + } + + return; + } + + // + // + // SH-2 region 0 + // + // Note: 0x00400000 - 0x01FFFFFF: Open bus for accesses to 0x00000000-0x01FFFFFF(SH-2 area 0) + // + if (A < 0x02000000) + { + if (sizeof(T) == 4) + { + if (IsWrite) + { + uint16 tmp; + + tmp = V >> 16; + BusRW(A, tmp, BurstHax, SH2DMAHax); + + tmp = V >> 0; + BusRW(A | 2, tmp, BurstHax, SH2DMAHax); + } + else + { + uint16 tmp = 0; + + BusRW(A | 2, tmp, BurstHax, SH2DMAHax); + V = tmp << 0; + + BusRW(A, tmp, BurstHax, SH2DMAHax); + V |= tmp << 16; + } + + return; + } + + // + // Low(and kinda slow) work RAM + // + if (A >= 0x00200000 && A <= 0x003FFFFF) + { + ne16_rwbo_be(WorkRAML, A & 0xFFFFF, &V); + + if (!SH2DMAHax) + SH7095_mem_timestamp += 7; + else + *SH2DMAHax -= 7; + + return; + } + + // + // BIOS ROM + // + if (A >= 0x00000000 && A <= 0x000FFFFF) + { + if (!SH2DMAHax) + SH7095_mem_timestamp += 8; + else + *SH2DMAHax -= 8; + + if (!IsWrite) + V = ne16_rbo_be(BIOSROM, A & 0x7FFFF); + + return; + } + + // + // SMPC + // + if (A >= 0x00100000 && A <= 0x0017FFFF) + { + const uint32 SMPC_A = (A & 0x7F) >> 1; + + if (!SH2DMAHax) + { + // SH7095_mem_timestamp += 2; + CheckEventsByMemTS(); + } + + if (IsWrite) + { + if (sizeof(T) == 2 || (A & 1)) + SMPC_Write(SH7095_mem_timestamp, SMPC_A, V); + } + else + { + if (sizeof(T) == 2) + V = 0xFF00 | SMPC_Read(SH7095_mem_timestamp, SMPC_A); + else if (sizeof(T) == 1 && (A & 1)) + V = SMPC_Read(SH7095_mem_timestamp, SMPC_A); + else + V = 0xFF; + } + + return; + } + + // + // Backup RAM + // + if (A >= 0x00180000 && A <= 0x001FFFFF) + { + if (!SH2DMAHax) + SH7095_mem_timestamp += 8; + else + *SH2DMAHax -= 8; + + if (IsWrite) + { + if (sizeof(T) != 1 || (A & 1)) + { + BackupRAM[(A >> 1) & 0x7FFF] = V; + BackupRAM_Dirty = true; + } + } + else + V = ((BackupRAM[(A >> 1) & 0x7FFF] << 0) | (0xFF << 8)) >> (((A & 1) ^ (sizeof(T) & 1)) << 3); + + return; + } + + // + // FRT trigger region + // + if (A >= 0x01000000 && A <= 0x01FFFFFF) + { + if (!SH2DMAHax) + SH7095_mem_timestamp += 8; + else + *SH2DMAHax -= 8; + + //printf("FT FRT%08x %zu %08x %04x %d %d\n", A, sizeof(T), A, V, SMPC_IsSlaveOn(), SH7095_mem_timestamp); + + if (IsWrite) + { + if (sizeof(T) != 1) + { + const unsigned c = ((A >> 23) & 1) ^ 1; + + if (!c || SMPC_IsSlaveOn()) + { + CPU[c].SetFTI(true); + CPU[c].SetFTI(false); + } + } + } + return; + } + + // + // + // + if (!SH2DMAHax) + SH7095_mem_timestamp += 4; + else + *SH2DMAHax -= 4; + + if (IsWrite) + SS_DBG(SS_DBG_WARNING, "[SH2 BUS] Unknown %zu-byte write of 0x%08x to 0x%08x\n", sizeof(T), V, A); + else + { + SS_DBG(SS_DBG_WARNING, "[SH2 BUS] Unknown %zu-byte read from 0x%08x\n", sizeof(T), A); + + V = 0; + } + + return; + } + + // + // SCU + // + { + uint32 DB; + + if (IsWrite) + DB = V << (((A & 3) ^ (4 - sizeof(T))) << 3); + else + DB = 0; + + SCU_FromSH2_BusRW_DB(A, &DB, SH2DMAHax); + + if (!IsWrite) + V = DB >> (((A & 3) ^ (4 - sizeof(T))) << 3); + } +} + +template +static void INLINE SH7095_BusWrite(uint32 A, T V, const bool BurstHax, int32 *SH2DMAHax) +{ + BusRW(A, V, BurstHax, SH2DMAHax); +} + +template +static T INLINE SH7095_BusRead(uint32 A, const bool BurstHax, int32 *SH2DMAHax) +{ + T ret = 0; + + BusRW(A, ret, BurstHax, SH2DMAHax); + + return ret; +} + +// +// +// +static MDFN_COLD uint8 CheatMemRead(uint32 A) +{ + A &= (1U << 27) - 1; + +#ifdef MSB_FIRST + return *(uint8 *)(SH7095_FastMap[A >> SH7095_EXT_MAP_GRAN_BITS] + (A ^ 0)); +#else + return *(uint8 *)(SH7095_FastMap[A >> SH7095_EXT_MAP_GRAN_BITS] + (A ^ 1)); +#endif +} + +static MDFN_COLD void CheatMemWrite(uint32 A, uint8 V) +{ + A &= (1U << 27) - 1; + + if (FMIsWriteable[A >> SH7095_EXT_MAP_GRAN_BITS]) + { +#ifdef MSB_FIRST + *(uint8 *)(SH7095_FastMap[A >> SH7095_EXT_MAP_GRAN_BITS] + (A ^ 0)) = V; +#else + *(uint8 *)(SH7095_FastMap[A >> SH7095_EXT_MAP_GRAN_BITS] + (A ^ 1)) = V; +#endif + + for (unsigned c = 0; c < 2; c++) + { + if (CPU[c].CCR & SH7095::CCR_CE) + { + for (uint32 Abase = 0x00000000; Abase < 0x20000000; Abase += 0x08000000) + { + CPU[c].Write_UpdateCache(Abase + A, V); + } + } + } + } +} +// +// +// +static void SetFastMemMap(uint32 Astart, uint32 Aend, uint16 *ptr, uint32 length, bool is_writeable) +{ + const uint64 Abound = (uint64)Aend + 1; + assert((Astart & ((1U << SH7095_EXT_MAP_GRAN_BITS) - 1)) == 0); + assert((Abound & ((1U << SH7095_EXT_MAP_GRAN_BITS) - 1)) == 0); + assert((length & ((1U << SH7095_EXT_MAP_GRAN_BITS) - 1)) == 0); + assert(length > 0); + assert(length <= (Abound - Astart)); + + for (uint64 A = Astart; A < Abound; A += (1U << SH7095_EXT_MAP_GRAN_BITS)) + { + uintptr_t tmp = (uintptr_t)ptr + ((A - Astart) % length); + + if (A < (1U << 27)) + FMIsWriteable[A >> SH7095_EXT_MAP_GRAN_BITS] = is_writeable; + + SH7095_FastMap[A >> SH7095_EXT_MAP_GRAN_BITS] = tmp - A; + } +} + +static uint16 fmap_dummy[(1U << SH7095_EXT_MAP_GRAN_BITS) / sizeof(uint16)]; + +static MDFN_COLD void InitFastMemMap(void) +{ + for (unsigned i = 0; i < sizeof(fmap_dummy) / sizeof(fmap_dummy[0]); i++) + { + fmap_dummy[i] = 0; + } + + FMIsWriteable.reset(); + //MDFNMP_Init(1ULL << SH7095_EXT_MAP_GRAN_BITS, (1ULL << 27) / (1ULL << SH7095_EXT_MAP_GRAN_BITS)); + + for (uint64 A = 0; A < 1ULL << 32; A += (1U << SH7095_EXT_MAP_GRAN_BITS)) + { + SH7095_FastMap[A >> SH7095_EXT_MAP_GRAN_BITS] = (uintptr_t)fmap_dummy - A; + } +} + +void SS_SetPhysMemMap(uint32 Astart, uint32 Aend, uint16 *ptr, uint32 length, bool is_writeable) +{ + assert(Astart < 0x20000000); + assert(Aend < 0x20000000); + + if (!ptr) + { + ptr = fmap_dummy; + length = sizeof(fmap_dummy); + } + + for (uint32 Abase = 0; Abase < 0x40000000; Abase += 0x20000000) + SetFastMemMap(Astart + Abase, Aend + Abase, ptr, length, is_writeable); +} + +#include "sh7095.inc" + +static bool Running; +event_list_entry events[SS_EVENT__COUNT]; +static sscpu_timestamp_t next_event_ts; + +template +static sscpu_timestamp_t SH_DMA_EventHandler(sscpu_timestamp_t et) +{ + if (et < SH7095_mem_timestamp) + { + //printf("SH-2 DMA %d reschedule %d->%d\n", c, et, SH7095_mem_timestamp); + return SH7095_mem_timestamp; + } + + // Must come after the (et < SH7095_mem_timestamp) check. + if (MDFN_UNLIKELY(SH7095_BusLock)) + return et + 1; + + return CPU[c].DMA_Update(et); +} + +// +// +// + +static MDFN_COLD void InitEvents(void) +{ + for (unsigned i = 0; i < SS_EVENT__COUNT; i++) + { + if (i == SS_EVENT__SYNFIRST) + events[i].event_time = 0; + else if (i == SS_EVENT__SYNLAST) + events[i].event_time = 0x7FFFFFFF; + else + events[i].event_time = 0; //SS_EVENT_DISABLED_TS; + + events[i].prev = (i > 0) ? &events[i - 1] : NULL; + events[i].next = (i < (SS_EVENT__COUNT - 1)) ? &events[i + 1] : NULL; + } + + events[SS_EVENT_SH2_M_DMA].event_handler = &SH_DMA_EventHandler<0>; + events[SS_EVENT_SH2_S_DMA].event_handler = &SH_DMA_EventHandler<1>; + + events[SS_EVENT_SCU_DMA].event_handler = SCU_UpdateDMA; + events[SS_EVENT_SCU_DSP].event_handler = SCU_UpdateDSP; + + events[SS_EVENT_SMPC].event_handler = SMPC_Update; + + events[SS_EVENT_VDP1].event_handler = VDP1::Update; + events[SS_EVENT_VDP2].event_handler = VDP2::Update; + + events[SS_EVENT_CDB].event_handler = CDB_Update; + + events[SS_EVENT_SOUND].event_handler = SOUND_Update; + + events[SS_EVENT_CART].event_handler = CART_GetEventHandler(); + + events[SS_EVENT_MIDSYNC].event_handler = MidSync; + events[SS_EVENT_MIDSYNC].event_time = SS_EVENT_DISABLED_TS; +} + +static void RebaseTS(const sscpu_timestamp_t timestamp) +{ + for (unsigned i = 0; i < SS_EVENT__COUNT; i++) + { + if (i == SS_EVENT__SYNFIRST || i == SS_EVENT__SYNLAST) + continue; + + assert(events[i].event_time > timestamp); + + if (events[i].event_time != SS_EVENT_DISABLED_TS) + events[i].event_time -= timestamp; + } + + next_event_ts = events[SS_EVENT__SYNFIRST].next->event_time; +} + +void SS_SetEventNT(event_list_entry *e, const sscpu_timestamp_t next_timestamp) +{ + if (next_timestamp < e->event_time) + { + event_list_entry *fe = e; + + do + { + fe = fe->prev; + } while (next_timestamp < fe->event_time); + + // Remove this event from the list, temporarily of course. + e->prev->next = e->next; + e->next->prev = e->prev; + + // Insert into the list, just after "fe". + e->prev = fe; + e->next = fe->next; + fe->next->prev = e; + fe->next = e; + + e->event_time = next_timestamp; + } + else if (next_timestamp > e->event_time) + { + event_list_entry *fe = e; + + do + { + fe = fe->next; + } while (next_timestamp > fe->event_time); + + // Remove this event from the list, temporarily of course + e->prev->next = e->next; + e->next->prev = e->prev; + + // Insert into the list, just BEFORE "fe". + e->prev = fe->prev; + e->next = fe; + fe->prev->next = e; + fe->prev = e; + + e->event_time = next_timestamp; + } + + next_event_ts = (Running ? events[SS_EVENT__SYNFIRST].next->event_time : 0); +} + +// Called from debug.cpp too. +void ForceEventUpdates(const sscpu_timestamp_t timestamp) +{ + CPU[0].ForceInternalEventUpdates(); + + if (SMPC_IsSlaveOn()) + CPU[1].ForceInternalEventUpdates(); + + for (unsigned evnum = SS_EVENT__SYNFIRST + 1; evnum < SS_EVENT__SYNLAST; evnum++) + { + if (events[evnum].event_time != SS_EVENT_DISABLED_TS) + SS_SetEventNT(&events[evnum], events[evnum].event_handler(timestamp)); + } + + next_event_ts = (Running ? events[SS_EVENT__SYNFIRST].next->event_time : 0); +} + +static INLINE bool EventHandler(const sscpu_timestamp_t timestamp) +{ + event_list_entry *e; + + while (timestamp >= (e = events[SS_EVENT__SYNFIRST].next)->event_time) // If Running = 0, EventHandler() may be called even if there isn't an event per-se, so while() instead of do { ... } while + { +#ifdef MDFN_SS_DEV_BUILD + const sscpu_timestamp_t etime = e->event_time; +#endif + sscpu_timestamp_t nt; + + nt = e->event_handler(e->event_time); + +#ifdef MDFN_SS_DEV_BUILD + if (MDFN_UNLIKELY(nt <= etime)) + { + fprintf(stderr, "which=%d event_time=%d nt=%d timestamp=%d\n", (int)(e - events), etime, nt, timestamp); + assert(nt > etime); + } +#endif + + SS_SetEventNT(e, nt); + } + + return (Running); +} + +static void NO_INLINE MDFN_HOT CheckEventsByMemTS_Sub(void) +{ + EventHandler(SH7095_mem_timestamp); +} + +static void INLINE CheckEventsByMemTS(void) +{ + if (MDFN_UNLIKELY(SH7095_mem_timestamp >= next_event_ts)) + { + //puts("Woot"); + CheckEventsByMemTS_Sub(); + } +} + +void SS_RequestMLExit(void) +{ + Running = 0; + next_event_ts = 0; +} + +#pragma GCC push_options +#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 5 +// gcc 5.3.0 and 6.1.0 produce some braindead code for the big switch() statement at -Os. +#pragma GCC optimize("Os,no-unroll-loops,no-peel-loops,no-crossjumping") +#else +#pragma GCC optimize("O2,no-unroll-loops,no-peel-loops,no-crossjumping") +#endif +template +static int32 NO_INLINE MDFN_HOT RunLoop(EmulateSpecStruct *espec) +{ + sscpu_timestamp_t eff_ts = 0; + + //printf("%d %d\n", SH7095_mem_timestamp, CPU[0].timestamp); + + do + { + do + { + if (DebugMode) + DBG_CPUHandler<0>(eff_ts); + + CPU[0].Step<0, DebugMode>(); + + while (MDFN_LIKELY(CPU[0].timestamp > CPU[1].timestamp)) + { + if (DebugMode) + DBG_CPUHandler<1>(eff_ts); + + CPU[1].Step<1, DebugMode>(); + } + + eff_ts = CPU[0].timestamp; + if (SH7095_mem_timestamp > eff_ts) + eff_ts = SH7095_mem_timestamp; + else + SH7095_mem_timestamp = eff_ts; + } while (MDFN_LIKELY(eff_ts < next_event_ts)); + } while (MDFN_LIKELY(EventHandler(eff_ts))); + + //printf(" End: %d %d -- %d\n", SH7095_mem_timestamp, CPU[0].timestamp, eff_ts); + return eff_ts; +} +#pragma GCC pop_options + +// Must not be called within an event or read/write handler. +void SS_Reset(bool powering_up) +{ + SH7095_BusLock = 0; + + if (powering_up) + { + memset(WorkRAML, 0x00, sizeof(WorkRAML)); // TODO: Check + memset(WorkRAMH, 0x00, sizeof(WorkRAMH)); // TODO: Check + } + + if (powering_up) + { + CPU[0].TruePowerOn(); + CPU[1].TruePowerOn(); + } + + SCU_Reset(powering_up); + CPU[0].Reset(powering_up); + + SMPC_Reset(powering_up); + + VDP1::Reset(powering_up); + VDP2::Reset(powering_up); + + CDB_Reset(powering_up); + + SOUND_Reset(powering_up); + + CART_Reset(powering_up); +} + +static EmulateSpecStruct *espec; +static int32 cur_clock_div; + +static int64 UpdateInputLastBigTS; +static INLINE void UpdateSMPCInput(const sscpu_timestamp_t timestamp) +{ + int32 elapsed_time = (((int64)timestamp * cur_clock_div * 1000 * 1000) - UpdateInputLastBigTS) / (EmulatedSS_MasterClock / MDFN_MASTERCLOCK_FIXED(1)); + + UpdateInputLastBigTS += (int64)elapsed_time * (EmulatedSS_MasterClock / MDFN_MASTERCLOCK_FIXED(1)); + + SMPC_UpdateInput(elapsed_time); +} + +static sscpu_timestamp_t MidSync(const sscpu_timestamp_t timestamp) +{ + return SS_EVENT_DISABLED_TS; +} + +void Emulate(EmulateSpecStruct *espec_arg) +{ + int32 end_ts; + + espec = espec_arg; + + cur_clock_div = SMPC_StartFrame(espec); + UpdateSMPCInput(0); + VDP2::StartFrame(espec, cur_clock_div == 61); + SOUND_StartFrame(44100, 5); + CART_SetCPUClock(EmulatedSS_MasterClock / MDFN_MASTERCLOCK_FIXED(1), cur_clock_div); + espec->SoundBufSize = 0; + espec->MasterCycles = 0; + // + // + // + Running = true; // Set before ForceEventUpdates() + ForceEventUpdates(0); + +#ifdef WANT_DEBUGGER + if (DBG_NeedCPUHooks()) + end_ts = RunLoop(espec); + else +#endif + end_ts = RunLoop(espec); + + ForceEventUpdates(end_ts); + // + // + // + RebaseTS(end_ts); + + CDB_ResetTS(); + SOUND_ResetTS(); + VDP1::AdjustTS(-end_ts); + VDP2::AdjustTS(-end_ts); + SMPC_ResetTS(); + SCU_AdjustTS(-end_ts); + CART_AdjustTS(-end_ts); + + UpdateInputLastBigTS -= (int64)end_ts * cur_clock_div * 1000 * 1000; + + if (!(SH7095_mem_timestamp & 0x40000000)) // or maybe >= 0 instead? + SH7095_mem_timestamp -= end_ts; + + CPU[0].AdjustTS(-end_ts); + + if (SMPC_IsSlaveOn()) + CPU[1].AdjustTS(-end_ts); + // + // + // + espec->MasterCycles = end_ts * cur_clock_div; + espec->SoundBufSize += SOUND_FlushOutput(espec->SoundBuf + (espec->SoundBufSize * 2), espec->SoundBufMaxSize - espec->SoundBufSize, false); + // + // + // + SMPC_UpdateOutput(); +} + +static INLINE void CalcGameID(uint8 *fd_id_out16, char *sgid) +{ + std::unique_ptr buf(new uint8[2048]); + + for (size_t x = 0; x < cdifs->size(); x++) + { + auto *c = (*cdifs)[x]; + CDUtility::TOC toc; + + c->ReadTOC(&toc); + + for (unsigned i = 0; i < 512; i++) + { + if (c->ReadSector(&buf[0], i, 1, true) >= 0x1) + { + if (i == 0) + { + char *tmp; + memcpy(sgid, &buf[0x20], 16); + sgid[16] = 0; + if ((tmp = strrchr(sgid, 'V'))) + { + do + { + *tmp = 0; + } while (tmp-- != sgid && (signed char)*tmp <= 0x20); + } + } + } + } + } +} + +// +// Remember to rebuild region database in db.cpp if changing the order of entries in this table(and be careful about game id collisions, e.g. with some Korean games). +// +static const struct +{ + const char c; + const char *str; // Community-defined region string that may appear in filename. + unsigned region; +} region_strings[] = + { + // Listed in order of preference for multi-region games. + {'U', "USA", SMPC_AREA_NA}, + {'J', "Japan", SMPC_AREA_JP}, + {'K', "Korea", SMPC_AREA_KR}, + + {'E', "Europe", SMPC_AREA_EU_PAL}, + {'E', "Germany", SMPC_AREA_EU_PAL}, + {'E', "France", SMPC_AREA_EU_PAL}, + {'E', "Spain", SMPC_AREA_EU_PAL}, + + {'B', "Brazil", SMPC_AREA_CSA_NTSC}, + + {'T', nullptr, SMPC_AREA_ASIA_NTSC}, + {'A', nullptr, SMPC_AREA_ASIA_PAL}, + {'L', nullptr, SMPC_AREA_CSA_PAL}, +}; + +static INLINE bool DetectRegion(unsigned *const region) +{ + std::unique_ptr buf(new uint8[2048 * 16]); + uint64 possible_regions = 0; + + for (auto &c : *cdifs) + { + if (c->ReadSector(&buf[0], 0, 16, true) != 0x1) + continue; + + for (unsigned i = 0; i < 16; i++) + { + for (auto const &rs : region_strings) + { + if (rs.c == buf[0x40 + i]) + { + possible_regions |= (uint64)1 << rs.region; + break; + } + } + } + break; + } + + for (auto const &rs : region_strings) + { + if (possible_regions & ((uint64)1 << rs.region)) + { + *region = rs.region; + return true; + } + } + + return false; +} + +extern bool CorrectAspect; +extern bool ShowHOverscan; +extern bool DoHBlend; +extern int LineVisFirst; +extern int LineVisLast; +static bool MDFN_COLD InitCommon(const unsigned cart_type, const unsigned smpc_area) +{ +#ifdef MDFN_SS_DEV_BUILD + ss_dbg_mask = MDFN_GetSettingUI("ss.dbg_mask"); +#endif + // + /*{ + MDFN_printf(_("Region: 0x%01x\n"), smpc_area); + const struct + { + const unsigned type; + const char *name; + } CartNames[] = + { + {CART_NONE, _("None")}, + {CART_BACKUP_MEM, _("Backup Memory")}, + {CART_EXTRAM_1M, _("1MiB Extended RAM")}, + {CART_EXTRAM_4M, _("4MiB Extended RAM")}, + {CART_KOF95, _("King of Fighters '95 ROM")}, + {CART_ULTRAMAN, _("Ultraman ROM")}, + {CART_CS1RAM_16M, _("16MiB CS1 RAM")}, + {CART_NLMODEM, _("Netlink Modem")}, + {CART_MDFN_DEBUG, _("Mednafen Debug")}, + }; + const char *cn = _("Unknown"); + + for (auto const &cne : CartNames) + { + if (cne.type == cart_type) + { + cn = cne.name; + break; + } + } + MDFN_printf(_("Cart: %s\n"), cn); + }*/ + // + + for (unsigned c = 0; c < 2; c++) + { + CPU[c].Init(); + CPU[c].SetMD5((bool)c); + } + + // + // Initialize backup memory. + // + memset(BackupRAM, 0x00, sizeof(BackupRAM)); + for (unsigned i = 0; i < 0x40; i++) + BackupRAM[i] = BRAM_Init_Data[i & 0x0F]; + AddMemoryDomain("Backup Ram", BackupRAM, sizeof(BackupRAM), MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_SAVERAMMABLE | MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_WORDSIZE2); + + // Call InitFastMemMap() before functions like SOUND_Init() + InitFastMemMap(); + BIOSROM = (uint16*)alloc_sealed(524288); + AddMemoryDomain("Boot Rom", BIOSROM, 524288, MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_WORDSIZE2); + SS_SetPhysMemMap(0x00000000, 0x000FFFFF, BIOSROM, 524288); + SS_SetPhysMemMap(0x00200000, 0x003FFFFF, WorkRAML, sizeof(WorkRAML), true); + SS_SetPhysMemMap(0x06000000, 0x07FFFFFF, WorkRAMH, sizeof(WorkRAMH), true); + AddMemoryDomain("Work Ram Low", WorkRAML, sizeof(WorkRAML), MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_WORDSIZE2); + AddMemoryDomain("Work Ram High", WorkRAMH, sizeof(WorkRAMH), MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_WORDSIZE2 | MEMORYAREA_FLAGS_PRIMARY); + + CART_Init(cart_type); + // + // + // + const bool PAL = (smpc_area & SMPC_AREA__PAL_MASK); + const int32 MasterClock = PAL ? 1734687500 : 1746818182; // NTSC: 1746818181.8181818181, PAL: 1734687500-ish + const char *biospath; + int sls = PAL ? setting_ss_slstartp : setting_ss_slstart; + int sle = PAL ? setting_ss_slendp : setting_ss_slend; + + if (PAL) + { + sls += 16; + sle += 16; + } + + if (sls > sle) + std::swap(sls, sle); + + if (smpc_area == SMPC_AREA_JP) + biospath = "BIOS_J"; + else if (smpc_area == SMPC_AREA_ASIA_NTSC) + biospath = "BIOS_A"; + else if (PAL) + biospath = "BIOS_E"; + else + biospath = "BIOS_U"; + + if (FirmwareSizeCallback(biospath) != 524288) + { + printf("BIOS file is of an incorrect size.\n"); + return false; + } + + FirmwareDataCallback(biospath, (uint8*)&BIOSROM[0]); + for (unsigned i = 0; i < 262144; i++) + BIOSROM[i] = MDFN_de16msb(&BIOSROM[i]); + + EmulatedSS_MasterClock = MDFN_MASTERCLOCK_FIXED(MasterClock); + + SCU_Init(); + SMPC_Init(smpc_area, MasterClock); + VDP1::Init(); + VDP2::Init(PAL); + CDB_Init(); + SOUND_Init(); + + InitEvents(); + UpdateInputLastBigTS = 0; + + DBG_Init(); + // + // + // + MDFN_printf("\n"); + { + CorrectAspect = setting_ss_correct_aspect; + ShowHOverscan = setting_ss_h_overscan; + DoHBlend = setting_ss_h_blend; + LineVisFirst = sls; + LineVisLast = sle; + + MDFN_printf(_("Displayed scanlines: [%u,%u]\n"), sls, sle); + MDFN_printf(_("Correct Aspect Ratio: %s\n"), correct_aspect ? _("Enabled") : _("Disabled")); + MDFN_printf(_("Show H Overscan: %s\n"), h_overscan ? _("Enabled") : _("Disabled")); + MDFN_printf(_("H Blend: %s\n"), h_blend ? _("Enabled") : _("Disabled")); + + // VDP2::SetGetVideoParams(&EmulatedSS, correct_aspect, sls, sle, h_overscan, h_blend); + } + + MDFN_printf("\n"); + for (unsigned sp = 0; sp < 2; sp++) + { + SMPC_SetMultitap(sp, false); + + MDFN_printf(_("Multitap on Saturn Port %u: %s\n"), sp + 1, sv ? _("Enabled") : _("Disabled")); + } + // + // + // + /*try + { + LoadRTC(); + } + catch (MDFN_Error &e) + { + if (e.GetErrno() != ENOENT) + throw; + } + try + { + LoadBackupRAM(); + } + catch (MDFN_Error &e) + { + if (e.GetErrno() != ENOENT) + throw; + } + try + { + LoadCartNV(); + } + catch (MDFN_Error &e) + { + if (e.GetErrno() != ENOENT) + throw; + }*/ + + BackupRAM_Dirty = false; + + CART_GetClearNVDirty(); + + /* + if (MDFN_GetSettingB("ss.smpc.autortc")) + { + struct tm ht = Time::LocalTime(); + + SMPC_SetRTC(&ht, MDFN_GetSettingUI("ss.smpc.autortc.lang")); + } + */ + SS_Reset(true); + return true; +} + +MDFN_COLD bool LoadCD(std::vector *CDInterfaces) +{ + const unsigned region_default = setting_ss_region_default; + unsigned region = region_default; + int cart_type; + uint8 fd_id[16]; + char sgid[16 + 1]; + cdifs = CDInterfaces; + CalcGameID(fd_id, sgid); + + if (setting_ss_region_autodetect) + if (!DB_LookupRegionDB(fd_id, ®ion)) + DetectRegion(®ion); + // + // + if ((cart_type = setting_ss_cart) == CART__RESERVED) + { + cart_type = CART_BACKUP_MEM; + DB_LookupCartDB(sgid, fd_id, &cart_type); + } + + // TODO: auth ID calc + + if (!InitCommon(cart_type, region)) + return false; + + return true; +} + +/*static const FileExtensionSpecStruct KnownExtensions[] = +{ + { ".elf", gettext_noop("SS Homebrew ELF Executable") }, + + { NULL, NULL } +};*/ + +/*static const MDFNSetting_EnumList Region_List[] = +{ + { "jp", SMPC_AREA_JP, gettext_noop("Japan") }, + { "na", SMPC_AREA_NA, gettext_noop("North America") }, + { "eu", SMPC_AREA_EU_PAL, gettext_noop("Europe") }, + { "kr", SMPC_AREA_KR, gettext_noop("South Korea") }, + + { "tw", SMPC_AREA_ASIA_NTSC, gettext_noop("Taiwan") }, // Taiwan, Philippines + { "as", SMPC_AREA_ASIA_PAL, gettext_noop("China") }, // China, Middle East + + { "br", SMPC_AREA_CSA_NTSC, gettext_noop("Brazil") }, + { "la", SMPC_AREA_CSA_PAL, gettext_noop("Latin America") }, + + { NULL, 0 }, +}; + +static const MDFNSetting_EnumList RTCLang_List[] = +{ + { "english", SMPC_RTC_LANG_ENGLISH, gettext_noop("English") }, + { "german", SMPC_RTC_LANG_GERMAN, gettext_noop("Deutsch") }, + { "french", SMPC_RTC_LANG_FRENCH, gettext_noop("Français") }, + { "spanish", SMPC_RTC_LANG_SPANISH, gettext_noop("Español") }, + { "italian", SMPC_RTC_LANG_ITALIAN, gettext_noop("Italiano") }, + { "japanese", SMPC_RTC_LANG_JAPANESE, gettext_noop("日本語") }, + + { "deutsch", SMPC_RTC_LANG_GERMAN, NULL }, + { "français", SMPC_RTC_LANG_FRENCH, NULL }, + { "español", SMPC_RTC_LANG_SPANISH, NULL }, + { "italiano", SMPC_RTC_LANG_ITALIAN, NULL }, + { "日本語", SMPC_RTC_LANG_JAPANESE, NULL}, + + { NULL, 0 }, +}; + +static const MDFNSetting_EnumList Cart_List[] = +{ + { "auto", CART__RESERVED, gettext_noop("Automatic") }, + { "none", CART_NONE, gettext_noop("None") }, + { "backup", CART_BACKUP_MEM, gettext_noop("Backup Memory(512KiB)") }, + { "extram1", CART_EXTRAM_1M, gettext_noop("1MiB Extended RAM") }, + { "extram4", CART_EXTRAM_4M, gettext_noop("4MiB Extended RAM") }, + { "cs1ram16", CART_CS1RAM_16M, gettext_noop("16MiB RAM mapped in A-bus CS1") }, +// { "nlmodem", CART_NLMODEM, gettext_noop("NetLink Modem") }, + + { NULL, 0 }, +}; + +static const MDFNSetting SSSettings[] = +{ + { "ss.bios_jp", MDFNSF_EMU_STATE, gettext_noop("Path to the Japan ROM BIOS"), NULL, MDFNST_STRING, "sega_101.bin" }, + { "ss.bios_na_eu", MDFNSF_EMU_STATE, gettext_noop("Path to the North America and Europe ROM BIOS"), NULL, MDFNST_STRING, "mpr-17933.bin" }, + + { "ss.scsp.resamp_quality", MDFNSF_NOFLAGS, gettext_noop("SCSP output resampler quality."), + gettext_noop("0 is lowest quality and CPU usage, 10 is highest quality and CPU usage. The resampler that this setting refers to is used for converting from 44.1KHz to the sampling rate of the host audio device Mednafen is using. Changing Mednafen's output rate, via the \"sound.rate\" setting, to \"44100\" may bypass the resampler, which can decrease CPU usage by Mednafen, and can increase or decrease audio quality, depending on various operating system and hardware factors."), MDFNST_UINT, "4", "0", "10" }, + + { "ss.region_autodetect", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Attempt to auto-detect region of game."), NULL, MDFNST_BOOL, "1" }, + { "ss.region_default", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Default region to use."), gettext_noop("Used if region autodetection fails or is disabled."), MDFNST_ENUM, "jp", NULL, NULL, NULL, NULL, Region_List }, + + { "ss.input.mouse_sensitivity", MDFNSF_NOFLAGS, gettext_noop("Emulated mouse sensitivity."), NULL, MDFNST_FLOAT, "0.50", NULL, NULL }, + { "ss.input.sport1.multitap", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Enable multitap on Saturn port 1."), NULL, MDFNST_BOOL, "0", NULL, NULL }, + { "ss.input.sport2.multitap", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Enable multitap on Saturn port 2."), NULL, MDFNST_BOOL, "0", NULL, NULL }, + + { "ss.smpc.autortc", MDFNSF_NOFLAGS, gettext_noop("Automatically set RTC on game load."), gettext_noop("Automatically set the SMPC's emulated Real-Time Clock to the host system's current time and date upon game load."), MDFNST_BOOL, "1" }, + { "ss.smpc.autortc.lang", MDFNSF_NOFLAGS, gettext_noop("BIOS language."), gettext_noop("Also affects language used in some games(e.g. the European release of \"Panzer Dragoon\")."), MDFNST_ENUM, "english", NULL, NULL, NULL, NULL, RTCLang_List }, + + { "ss.cart", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Expansion cart."), NULL, MDFNST_ENUM, "auto", NULL, NULL, NULL, NULL, Cart_List }, + { "ss.cart.kof95_path", MDFNSF_EMU_STATE, gettext_noop("Path to KoF 95 ROM image."), NULL, MDFNST_STRING, "mpr-18811-mx.ic1" }, + { "ss.cart.ultraman_path", MDFNSF_EMU_STATE, gettext_noop("Path to Ultraman ROM image."), NULL, MDFNST_STRING, "mpr-19367-mx.ic1" }, + + { "ss.bios_sanity", MDFNSF_NOFLAGS, gettext_noop("Enable BIOS ROM image sanity checks."), NULL, MDFNST_BOOL, "1" }, + + { "ss.cd_sanity", MDFNSF_NOFLAGS, gettext_noop("Enable CD (image) sanity checks."), NULL, MDFNST_BOOL, "1" }, + + { "ss.slstart", MDFNSF_NOFLAGS, gettext_noop("First displayed scanline in NTSC mode."), NULL, MDFNST_INT, "0", "0", "239" }, + { "ss.slend", MDFNSF_NOFLAGS, gettext_noop("Last displayed scanline in NTSC mode."), NULL, MDFNST_INT, "239", "0", "239" }, + + { "ss.h_overscan", MDFNSF_NOFLAGS, gettext_noop("Show horizontal overscan area."), NULL, MDFNST_BOOL, "1" }, + + { "ss.h_blend", MDFNSF_NOFLAGS, gettext_noop("Enable horizontal blend(blur) filter."), gettext_noop("Intended for use in combination with the \"goat\" OpenGL shader, or with bilinear interpolation or linear interpolation on the X axis enabled. Has a more noticeable effect with the Saturn's higher horizontal resolution modes(640/704)."), MDFNST_BOOL, "0" }, + + { "ss.correct_aspect", MDFNSF_NOFLAGS, gettext_noop("Correct aspect ratio."), gettext_noop("Disabling aspect ratio correction with this setting should be considered a hack.\n\nIf disabling it to allow for sharper pixels by also separately disabling interpolation(though using Mednafen's \"autoipsharper\" OpenGL shader is usually a better option), remember to use scale factors that are multiples of 2, or else games that use high-resolution and interlaced modes will have distorted pixels.\n\nDisabling aspect ratio correction with this setting will allow for the QuickTime movie recording feature to produce much smaller files using much less CPU time."), MDFNST_BOOL, "1" }, + + { "ss.slstartp", MDFNSF_NOFLAGS, gettext_noop("First displayed scanline in PAL mode."), NULL, MDFNST_INT, "0", "-16", "271" }, + { "ss.slendp", MDFNSF_NOFLAGS, gettext_noop("Last displayed scanline in PAL mode."), NULL, MDFNST_INT, "255", "-16", "271" }, + + { "ss.midsync", MDFNSF_NOFLAGS, gettext_noop("Enable mid-frame synchronization."), gettext_noop("Mid-frame synchronization can reduce input latency, but it will increase CPU requirements."), MDFNST_BOOL, "0" }, + +#ifdef MDFN_SS_DEV_BUILD + { "ss.dbg_mask", MDFNSF_SUPPRESS_DOC, gettext_noop("Debug printf mask."), NULL, MDFNST_UINT, "0x00001", "0x00000", "0xFFFFF" }, + { "ss.dbg_exe_cdpath", MDFNSF_SUPPRESS_DOC, gettext_noop("CD image to use with homebrew executable loading."), NULL, MDFNST_STRING, "" }, +#endif + + { NULL }, +}; + +static const CheatInfoStruct CheatInfo = +{ + NULL, + NULL, + + CheatMemRead, + CheatMemWrite, + + CheatFormatInfo_Empty, + + true +};*/ +} + +using namespace MDFN_IEN_SS; + +/*MDFNGI EmulatedSS = +{ + "ss", + "Sega Saturn", + KnownExtensions, + MODPRIO_INTERNAL_HIGH, + #ifdef WANT_DEBUGGER + &DBGInfo, + #else + NULL, + #endif + SMPC_PortInfo, +#ifdef MDFN_SS_DEV_BUILD + Load, + TestMagic, +#else + NULL, + NULL, +#endif + LoadCD, + TestMagicCD, + CloseGame, + + VDP2::SetLayerEnableMask, + "NBG0\0NBG1\0NBG2\0NBG3\0RBG0\0RBG1\0Sprite\0", + + NULL, + NULL, + + NULL, + 0, + + CheatInfo, + + false, + NULL, //StateAction, + Emulate, + NULL, + SMPC_SetInput, + SetMedia, + DoSimpleCommand, + NULL, + SSSettings, + 0, + 0, + + true, // Multires possible? + + // + // Note: Following video settings will be overwritten during game load. + // + 320, // lcm_width + 240, // lcm_height + NULL, // Dummy + + 302, // Nominal width + 240, // Nominal height + + 0, // Framebuffer width + 0, // Framebuffer height + // + // + // + + 2, // Number of output sound channels +};*/ diff --git a/waterbox/ss/ss.h b/waterbox/ss/ss.h new file mode 100644 index 0000000000..a76aac0848 --- /dev/null +++ b/waterbox/ss/ss.h @@ -0,0 +1,146 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* ss.h: +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_SS_H +#define __MDFN_SS_SS_H + +#include "defs.h" +#include +#include + +namespace MDFN_IEN_SS +{ + enum + { + SS_DBG_ERROR = 0x00001, + SS_DBG_WARNING = 0x00002, + + SS_DBG_M68K = 0x00004, + + SS_DBG_SH2 = 0x00010, + SS_DBG_SH2_REGW = 0x00020, + + SS_DBG_SCU = 0x00040, + SS_DBG_SCU_REGW = 0x00080, + + SS_DBG_SMPC = 0x00100, + SS_DBG_SMPC_REGW = 0x00200, + + SS_DBG_CDB = 0x00400, + SS_DBG_CDB_REGW = 0x00800, + + SS_DBG_VDP1 = 0x01000, + SS_DBG_VDP1_REGW = 0x02000, + + SS_DBG_VDP2 = 0x04000, + SS_DBG_VDP2_REGW = 0x08000, + + SS_DBG_SCSP = 0x10000, + SS_DBG_SCSP_REGW = 0x20000, + }; +#ifdef MDFN_SS_DEV_BUILD + extern uint32 ss_dbg_mask; +#else + enum { ss_dbg_mask = 0 }; +#endif + + static INLINE void SS_DBG_Dummy(const char* format, ...) { } + #define SS_DBG(which, format, ...) ((MDFN_UNLIKELY(ss_dbg_mask & (which))) ? (void)trio_printf(format, ## __VA_ARGS__) : SS_DBG_Dummy(format, ## __VA_ARGS__)) + #define SS_DBGTI(which, format, ...) SS_DBG(which, format " @Line=0x%03x, HPos=0x%03x, memts=%d\n", ## __VA_ARGS__, VDP2::PeekLine(), VDP2::PeekHPos(), SH7095_mem_timestamp) + + template + static void SS_DBG_Wrap(const char* format, ...) noexcept + { + if(ss_dbg_mask & which) + { + va_list ap; + + va_start(ap, format); + + trio_vprintf(format, ap); + + va_end(ap); + } + } + + typedef int32 sscpu_timestamp_t; + + class SH7095; + + extern SH7095 CPU[2]; // for smpc.cpp + + extern int32 SH7095_mem_timestamp; + + void SS_RequestMLExit(void); + void ForceEventUpdates(const sscpu_timestamp_t timestamp); + + enum + { + SS_EVENT__SYNFIRST = 0, + + SS_EVENT_SH2_M_DMA, + SS_EVENT_SH2_S_DMA, + + SS_EVENT_SCU_DMA, + SS_EVENT_SCU_DSP, + + SS_EVENT_SMPC, + + SS_EVENT_VDP1, + SS_EVENT_VDP2, + + SS_EVENT_CDB, + + SS_EVENT_SOUND, + + SS_EVENT_CART, + + SS_EVENT_MIDSYNC, + + SS_EVENT__SYNLAST, + SS_EVENT__COUNT, + }; + + typedef sscpu_timestamp_t (*ss_event_handler)(const sscpu_timestamp_t timestamp); + + struct event_list_entry + { + sscpu_timestamp_t event_time; + event_list_entry *prev; + event_list_entry *next; + ss_event_handler event_handler; + }; + + extern event_list_entry events[SS_EVENT__COUNT]; + + #define SS_EVENT_DISABLED_TS 0x40000000 + void SS_SetEventNT(event_list_entry* e, const sscpu_timestamp_t next_timestamp); + + // Call from init code, or power/reset code, as appropriate. + // (length is in units of bytes, not 16-bit units) + // + // is_writeable is mostly for cheat stuff. + void SS_SetPhysMemMap(uint32 Astart, uint32 Aend, uint16* ptr, uint32 length, bool is_writeable = false); + + void SS_Reset(bool powering_up) MDFN_COLD; +} + +#endif diff --git a/waterbox/ss/vdp1.cpp b/waterbox/ss/vdp1.cpp new file mode 100644 index 0000000000..38b4a63967 --- /dev/null +++ b/waterbox/ss/vdp1.cpp @@ -0,0 +1,889 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* vdp1.cpp - VDP1 Emulation +** Copyright (C) 2015-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +// TODO: Check to see what registers are reset on reset. + +// TODO: Fix preclipping when raw system clipping values have bit12==1(sign bit?). + +// TODO: SS_SetPhysMemMap(0x05C80000, 0x05CFFFFF, FB[FBDrawWhich], sizeof(FB[0])); +// (...but goes weird in 8bpp rotated mode...) + +// TODO: Test 1x1 line, polyline, sprite, and polygon. + +// TODO: Framebuffer swap/auto drawing start happens a bit too early, should happen near +// end of hblank instead of the beginning. + +#include "ss.h" +#include "scu.h" +#include "vdp1.h" +#include "vdp2.h" +#include "vdp1_common.h" + +enum { VDP1_UpdateTimingGran = 263 }; +enum { VDP1_IdleTimingGran = 1019 }; + +namespace MDFN_IEN_SS +{ +namespace VDP1 +{ + +uint8 spr_w_shift_tab[8]; +line_data LineSetup; +uint8 gouraud_lut[0x40]; + +uint16 VRAM[0x40000]; +uint16 FB[2][0x20000]; +bool FBDrawWhich; + +static bool FBManualPending; + +static bool FBVBErasePending; +static bool FBVBEraseActive; +static sscpu_timestamp_t FBVBEraseLastTS; + +int32 SysClipX, SysClipY; +int32 UserClipX0, UserClipY0, UserClipX1, UserClipY1; +int32 LocalX, LocalY; + +static uint32 CurCommandAddr; +static int32 RetCommandAddr; +static bool DrawingActive; + +static uint16 LOPR; + +static uint16 EWDR; // Erase/Write Data +static uint16 EWLR; // Erase/Write Upper Left Coordinate +static uint16 EWRR; // Erase/Write Lower Right Coordinate + +static struct +{ + bool rot8; + uint32 fb_x_mask; + + uint32 y_start; + uint32 x_start; + + uint32 y_end; + uint32 x_bound; + + uint16 fill_data; +} EraseParams; + +static uint32 EraseYCounter; + +uint8 TVMR; +uint8 FBCR; +uint8 PTMR; +static uint8 EDSR; + +static bool vb_status, hb_status; +static sscpu_timestamp_t lastts; +static int32 CycleCounter; + +static bool vbcdpending; + +void Init(void) +{ + vbcdpending = false; + + for(int i = 0; i < 0x40; i++) + { + gouraud_lut[i] = std::min(31, std::max(0, i - 16)); + } + + for(int i = 0; i < 8; i++) + { + spr_w_shift_tab[i] = (7 - i) / 3; + } + + + // + // + SS_SetPhysMemMap(0x05C00000, 0x05C7FFFF, VRAM, sizeof(VRAM), true); + AddMemoryDomain("VDP1 Ram", VRAM, sizeof(VRAM), MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_WORDSIZE2); + AddMemoryDomain("VDP1 Framebuffer", FB, sizeof(FB), MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_WORDSIZE2); + //SS_SetPhysMemMap(0x05C80000, 0x05CFFFFF, FB[FBDrawWhich], sizeof(FB[0]), true); + + vb_status = false; + hb_status = false; + lastts = 0; + FBVBEraseLastTS = 0; +} + +void Reset(bool powering_up) +{ + if(powering_up) + { + for(unsigned i = 0; i < 0x40000; i++) + { + uint16 val; + + if((i & 0xF) == 0) + val = 0x8000; + else if(i & 0x1) + val = 0x5555; + else + val = 0xAAAA; + + VRAM[i] = val; + } + + for(unsigned fb = 0; fb < 2; fb++) + for(unsigned i = 0; i < 0x20000; i++) + FB[fb][i] = 0xFFFF; + + memset(&LineSetup, 0, sizeof(LineSetup)); + + // + // + // + EWDR = 0; + EWLR = 0; + EWRR = 0; + + TVMR = 0; + FBCR = 0; + } + + UserClipX0 = 0; + UserClipY0 = 0; + UserClipX1 = 0; + UserClipY1 = 0; + + SysClipX = 0; + SysClipY = 0; + + LocalX = 0; + LocalY = 0; + + FBDrawWhich = 0; + //SS_SetPhysMemMap(0x05C80000, 0x05CFFFFF, FB[FBDrawWhich], sizeof(FB[0]), true); + + FBManualPending = false; + FBVBErasePending = false; + FBVBEraseActive = false; + + LOPR = 0; + CurCommandAddr = 0; + RetCommandAddr = -1; + DrawingActive = false; + + PTMR = 0; + EDSR = 0; + + memset(&EraseParams, 0, sizeof(EraseParams)); + EraseYCounter = ~0U; + + CycleCounter = 0; +} + +static int32 CMD_SetUserClip(const uint16* cmd_data) +{ + UserClipX0 = cmd_data[0x6] & 0x3FF; + UserClipY0 = cmd_data[0x7] & 0x1FF; + + UserClipX1 = cmd_data[0xA] & 0x3FF; + UserClipY1 = cmd_data[0xB] & 0x1FF; + + return 0; +} + +int32 CMD_SetSystemClip(const uint16* cmd_data) +{ + SysClipX = cmd_data[0xA] & 0x3FF; + SysClipY = cmd_data[0xB] & 0x1FF; + + return 0; +} + +int32 CMD_SetLocalCoord(const uint16* cmd_data) +{ + LocalX = sign_x_to_s32(11, cmd_data[0x6] & 0x7FF); + LocalY = sign_x_to_s32(11, cmd_data[0x7] & 0x7FF); + + return 0; +} + +template +static uint32 MDFN_FASTCALL TexFetch(uint32 x) +{ + const uint32 base = LineSetup.tex_base; + const bool ECD = ECDSPDMode & 0x10; + const bool SPD = ECDSPDMode & 0x08; + const unsigned ColorMode = ECDSPDMode & 0x07; + + uint32 rtd; + uint32 ret_or = 0; + + switch(ColorMode) + { + case 0: // 16 colors, color bank + rtd = (VRAM[(base + (x >> 2)) & 0x3FFFF] >> (((x & 0x3) ^ 0x3) << 2)) & 0xF; + + if(!ECD && rtd == 0xF) + { + LineSetup.ec_count--; + return -1; + } + ret_or = LineSetup.cb_or; + + if(!SPD) ret_or |= (int32)(rtd - 1) >> 31; + + return rtd | ret_or; + + case 1: // 16 colors, LUT + rtd = (VRAM[(base + (x >> 2)) & 0x3FFFF] >> (((x & 0x3) ^ 0x3) << 2)) & 0xF; + + if(!ECD && rtd == 0xF) + { + LineSetup.ec_count--; + return -1; + } + + if(!SPD) ret_or |= (int32)(rtd - 1) >> 31; + + return LineSetup.CLUT[rtd] | ret_or; + + case 2: // 64 colors, color bank + rtd = (VRAM[(base + (x >> 1)) & 0x3FFFF] >> (((x & 0x1) ^ 0x1) << 3)) & 0xFF; + + if(!ECD && rtd == 0xFF) + { + LineSetup.ec_count--; + return -1; + } + + ret_or = LineSetup.cb_or; + + if(!SPD) ret_or |= (int32)(rtd - 1) >> 31; + + return (rtd & 0x3F) | ret_or; + + case 3: // 128 colors, color bank + rtd = (VRAM[(base + (x >> 1)) & 0x3FFFF] >> (((x & 0x1) ^ 0x1) << 3)) & 0xFF; + + if(!ECD && rtd == 0xFF) + { + LineSetup.ec_count--; + return -1; + } + + ret_or = LineSetup.cb_or; + + if(!SPD) ret_or |= (int32)(rtd - 1) >> 31; + + return (rtd & 0x7F) | ret_or; + + case 4: // 256 colors, color bank + rtd = (VRAM[(base + (x >> 1)) & 0x3FFFF] >> (((x & 0x1) ^ 0x1) << 3)) & 0xFF; + + if(!ECD && rtd == 0xFF) + { + LineSetup.ec_count--; + return -1; + } + + ret_or = LineSetup.cb_or; + + if(!SPD) ret_or |= (int32)(rtd - 1) >> 31; + + return rtd | ret_or; + + case 5: // 32K colors, RGB + case 6: + case 7: + if(ColorMode >= 6) + rtd = VRAM[0]; + else + rtd = VRAM[(base + x) & 0x3FFFF]; + + if(!ECD && (rtd & 0xC000) == 0x4000) + { + LineSetup.ec_count--; + return -1; + } + + if(!SPD) ret_or |= (int32)(rtd - 0x4000) >> 31; + + return rtd | ret_or; + } +} + + +extern uint32 (MDFN_FASTCALL *const TexFetchTab[0x20])(uint32 x) = +{ + #define TF(a) (TexFetch) + + TF(0x00), TF(0x01), TF(0x02), TF(0x03), + TF(0x04), TF(0x05), TF(0x06), TF(0x07), + + TF(0x08), TF(0x09), TF(0x0A), TF(0x0B), + TF(0x0C), TF(0x0D), TF(0x0E), TF(0x0F), + + TF(0x10), TF(0x11), TF(0x12), TF(0x13), + TF(0x14), TF(0x15), TF(0x16), TF(0x17), + + TF(0x18), TF(0x19), TF(0x1A), TF(0x1B), + TF(0x1C), TF(0x1D), TF(0x1E), TF(0x1F), + + #undef TF +}; + + + +/* + Notes: + When vblank starts: Abort command processing, and if VBE=1, erase framebuffer just displayed according to set values. + + When vblank ends: Abort framebuffer erase, swap framebuffer, and if (PTMR&2) start command processing. + + See if EDSR and LOPR are modified or not when PTMR=0 and an auto framebuffer swap occurs. + + FB erase params are latched at framebuffer swap time probably. + + VBE=1 is persistent. +*/ + +sscpu_timestamp_t Update(sscpu_timestamp_t timestamp) +{ + if(MDFN_UNLIKELY(timestamp < lastts)) + { + // Don't else { } normal execution, since this bug condition miiight occur in the call from SetHBVB(), + // and we need drawing to start ASAP before silly games overwrite the beginning of the command table. + // + SS_DBGTI(SS_DBG_WARNING | SS_DBG_VDP1, "[VDP1] [BUG] timestamp(%d) < lastts(%d)", timestamp, lastts); + timestamp = lastts; + } + // + // + // + int32 cycles = timestamp - lastts; + lastts = timestamp; + + CycleCounter += cycles; + if(CycleCounter > VDP1_UpdateTimingGran) + CycleCounter = VDP1_UpdateTimingGran; + + if(CycleCounter > 0 && SCU_CheckVDP1HaltKludge()) + { + //puts("Kludge"); + CycleCounter = 0; + } + else if(DrawingActive) + { + while(CycleCounter > 0) + { + uint16 cmd_data[0x10]; + + // Fetch command data + memcpy(cmd_data, &VRAM[CurCommandAddr], sizeof(cmd_data)); + CycleCounter -= 16; + + //SS_DBGTI(SS_DBG_WARNING | SS_DBG_VDP1, "[VDP1] Command @ 0x%06x: 0x%04x\n", CurCommandAddr, cmd_data[0]); + + if(MDFN_LIKELY(!(cmd_data[0] & 0xC000))) + { + const unsigned cc = cmd_data[0] & 0xF; + + if(MDFN_UNLIKELY(cc >= 0xC)) + { + DrawingActive = false; + break; + } + else + { + static int32 (*const command_table[0xC])(const uint16* cmd_data) = + { + /* 0x0 */ /* 0x1 */ /* 0x2 */ /* 0x3 */ + CMD_NormalSprite, CMD_ScaledSprite, CMD_DistortedSprite, CMD_DistortedSprite, + + /* 0x4 */ /* 0x5 */ /* 0x6 */ /* 0x7 */ + CMD_Polygon, CMD_Polyline, CMD_Line, CMD_Polyline, + + /* 0x8*/ /* 0x9 */ /* 0xA */ /* 0xB */ + CMD_SetUserClip, CMD_SetSystemClip, CMD_SetLocalCoord, CMD_SetUserClip + }; + + CycleCounter -= command_table[cc](cmd_data); + } + } + else if(MDFN_UNLIKELY(cmd_data[0] & 0x8000)) + { + SS_DBGTI(SS_DBG_VDP1, "[VDP1] Drawing finished at 0x%05x", CurCommandAddr); + DrawingActive = false; + + EDSR |= 0x2; // TODO: Does EDSR reflect IRQ out status? + + SCU_SetInt(SCU_INT_VDP1, true); + SCU_SetInt(SCU_INT_VDP1, false); + break; + } + + CurCommandAddr = (CurCommandAddr + 0x10) & 0x3FFFF; + switch((cmd_data[0] >> 12) & 0x3) + { + case 0: + break; + + case 1: + CurCommandAddr = (cmd_data[1] << 2) &~ 0xF; + break; + + case 2: + if(RetCommandAddr < 0) + RetCommandAddr = CurCommandAddr; + + CurCommandAddr = (cmd_data[1] << 2) &~ 0xF; + break; + + case 3: + if(RetCommandAddr >= 0) + { + CurCommandAddr = RetCommandAddr; + RetCommandAddr = -1; + } + break; + } + } + } + + return timestamp + (DrawingActive ? std::max(VDP1_UpdateTimingGran, 0 - CycleCounter) : VDP1_IdleTimingGran); +} + +// Draw-clear minimum x amount is 2(16-bit units) for normal and 8bpp, and 8 for rotate...actually, seems like +// rotate being enabled forces vblank erase mode somehow. + +static void StartDrawing(void) +{ + if(DrawingActive) + { + SS_DBGTI(SS_DBG_WARNING | SS_DBG_VDP1, "[VDP1] Drawing interrupted by new drawing start request."); + } + + SS_DBGTI(SS_DBG_VDP1, "[VDP1] Started drawing to framebuffer %d.", FBDrawWhich); + + // On draw start, clear CEF. + EDSR &= ~0x2; + + CurCommandAddr = 0; + RetCommandAddr = -1; + DrawingActive = true; + CycleCounter = VDP1_UpdateTimingGran; +} + +void SetHBVB(const sscpu_timestamp_t event_timestamp, const bool new_hb_status, const bool new_vb_status) +{ + const bool old_hb_status = hb_status; + const bool old_vb_status = vb_status; + + hb_status = new_hb_status; + vb_status = new_vb_status; + + if(MDFN_UNLIKELY(vbcdpending & hb_status & (old_hb_status ^ hb_status))) + { + vbcdpending = false; + + if(vb_status) // Going into v-blank + { + // + // v-blank erase + // + if((TVMR & TVMR_VBE) || FBVBErasePending) + { + SS_DBGTI(SS_DBG_VDP1, "[VDP1] VB erase start of framebuffer %d.", !FBDrawWhich); + + FBVBErasePending = false; + FBVBEraseActive = true; + FBVBEraseLastTS = event_timestamp; + } + } + else // Leaving v-blank + { + // Run vblank erase at end of vblank all at once(not strictly accurate, but should only have visible side effects wrt the debugger and reset). + if(FBVBEraseActive) + { + int32 count = event_timestamp - FBVBEraseLastTS; + //printf("%d %d, %d\n", event_timestamp, FBVBEraseLastTS, count); + // + // + // + uint32 y = EraseParams.y_start; + + do + { + uint16* fbyptr; + uint32 x = EraseParams.x_start; + + fbyptr = &FB[!FBDrawWhich][(y & 0xFF) << 9]; + if(EraseParams.rot8) + fbyptr += (y & 0x100); + + count -= 8; + do + { + for(unsigned sub = 0; sub < 8; sub++) + { + //printf("%d %d:%d %04x\n", FBDrawWhich, x, y, fill_data); + //printf("%lld\n", &fbyptr[x & fb_x_mask] - FB[!FBDrawWhich]); + fbyptr[x & EraseParams.fb_x_mask] = EraseParams.fill_data; + x++; + } + count -= 8; + if(MDFN_UNLIKELY(count <= 0)) + { + SS_DBGTI(SS_DBG_WARNING | SS_DBG_VDP1, "[VDP1] VB erase of framebuffer %d ran out of time.", !FBDrawWhich); + goto AbortVBErase; + } + } while(x < EraseParams.x_bound); + } while(++y <= EraseParams.y_end); + + AbortVBErase:; + // + FBVBEraseActive = false; + } + // + // + // + // + if(!(FBCR & FBCR_FCM) || (FBManualPending && (FBCR & FBCR_FCT))) // Swap framebuffers + { + if(DrawingActive) + { + SS_DBGTI(SS_DBG_WARNING | SS_DBG_VDP1, "[VDP1] Drawing aborted by framebuffer swap."); + DrawingActive = false; + } + + FBDrawWhich = !FBDrawWhich; + + SS_DBGTI(SS_DBG_VDP1, "[VDP1] Displayed framebuffer changed to %d.", !FBDrawWhich); + + // On fb swap, copy CEF to BEF, clear CEF, and copy COPR to LOPR. + EDSR = EDSR >> 1; + LOPR = CurCommandAddr >> 2; + + // + EraseParams.rot8 = (TVMR & (TVMR_8BPP | TVMR_ROTATE)) == (TVMR_8BPP | TVMR_ROTATE); + EraseParams.fb_x_mask = EraseParams.rot8 ? 0xFF : 0x1FF; + + EraseParams.y_start = EWLR & 0x1FF; + EraseParams.x_start = ((EWLR >> 9) & 0x3F) << 3; + + EraseParams.y_end = EWRR & 0x1FF; + EraseParams.x_bound = ((EWRR >> 9) & 0x7F) << 3; + + EraseParams.fill_data = EWDR; + // + + if(PTMR & 0x2) // Start drawing(but only if we swapped the frame) + { + StartDrawing(); + SS_SetEventNT(&events[SS_EVENT_VDP1], Update(event_timestamp)); + } + } + + if(!(FBCR & FBCR_FCM) || (FBManualPending && !(FBCR & FBCR_FCT))) + { + if(TVMR & TVMR_ROTATE) + { + EraseYCounter = ~0U; + FBVBErasePending = true; + } + else + { + EraseYCounter = EraseParams.y_start; + } + } + + FBManualPending = false; + } + } + vbcdpending |= old_vb_status ^ vb_status; +} + +bool GetLine(const int line, uint16* buf, unsigned w, uint32 rot_x, uint32 rot_y, uint32 rot_xinc, uint32 rot_yinc) +{ + bool ret = false; + // + // + // + if(TVMR & TVMR_ROTATE) + { + const uint16* fbptr = FB[!FBDrawWhich]; + + if(TVMR & TVMR_8BPP) + { + for(unsigned i = 0; MDFN_LIKELY(i < w); i++) + { + const uint32 fb_x = rot_x >> 9; + const uint32 fb_y = rot_y >> 9; + + if((fb_x | fb_y) &~ 0x1FF) + buf[i] = 0; // Not 0xFF00 + else + { + const uint16* fbyptr = fbptr + ((fb_y & 0xFF) << 9); + uint8 tmp = ne16_rbo_be(fbyptr, (fb_x & 0x1FF) | ((fb_y & 0x100) << 1)); + + buf[i] = 0xFF00 | tmp; + } + + rot_x += rot_xinc; + rot_y += rot_yinc; + } + } + else + { + for(unsigned i = 0; MDFN_LIKELY(i < w); i++) + { + const uint32 fb_x = rot_x >> 9; + const uint32 fb_y = rot_y >> 9; + + if((fb_x &~ 0x1FF) | (fb_y &~ 0xFF)) + buf[i] = 0; + else + buf[i] = fbptr[(fb_y << 9) + fb_x]; + + rot_x += rot_xinc; + rot_y += rot_yinc; + } + } + } + else + { + const uint16* fbyptr = &FB[!FBDrawWhich][(line & 0xFF) << 9]; + + if(TVMR & TVMR_8BPP) + ret = true; + + for(unsigned i = 0; MDFN_LIKELY(i < w); i++) + buf[i] = fbyptr[i]; + } + + // + // + // + if(EraseYCounter <= EraseParams.y_end) + { + uint16* fbyptr; + uint32 x = EraseParams.x_start; + + fbyptr = &FB[!FBDrawWhich][(EraseYCounter & 0xFF) << 9]; + if(EraseParams.rot8) + fbyptr += (EraseYCounter & 0x100); + + do + { + for(unsigned sub = 0; sub < 2; sub++) + { + //printf("%d %d:%d %04x\n", FBDrawWhich, x, y, fill_data); + //printf("%lld\n", &fbyptr[x & fb_x_mask] - FB[!FBDrawWhich]); + fbyptr[x & EraseParams.fb_x_mask] = EraseParams.fill_data; + x++; + } + } while(x < EraseParams.x_bound); + + EraseYCounter++; + } + + return ret; +} + +void AdjustTS(const int32 delta) +{ + lastts += delta; + if(FBVBEraseActive) + FBVBEraseLastTS += delta; +} + +static INLINE void WriteReg(const unsigned which, const uint16 value) +{ + SS_SetEventNT(&events[SS_EVENT_VDP2], VDP2::Update(SH7095_mem_timestamp)); + sscpu_timestamp_t nt = Update(SH7095_mem_timestamp); + + SS_DBGTI(SS_DBG_VDP1_REGW, "[VDP1] Register write: 0x%02x: 0x%04x", which << 1, value); + + switch(which) + { + default: + SS_DBGTI(SS_DBG_WARNING | SS_DBG_VDP1, "[VDP1] Unknown write of value 0x%04x to register 0x%02x", value, which << 1); + break; + + case 0x0: // TVMR + TVMR = value & 0xF; + break; + + case 0x1: // FBCR + FBCR = value & 0x1F; + FBManualPending |= value & 0x2; + break; + + case 0x2: // PTMR + PTMR = (value & 0x3); + if(value & 0x1) + { + StartDrawing(); + nt = SH7095_mem_timestamp + 1; + } + break; + + case 0x3: // EWDR + EWDR = value; + break; + + case 0x4: // EWLR + EWLR = value & 0x7FFF; + break; + + case 0x5: // EWRR + EWRR = value; + break; + + case 0x6: // ENDR + if(DrawingActive) + { + DrawingActive = false; + if(CycleCounter < 0) + CycleCounter = 0; + nt = SH7095_mem_timestamp + VDP1_IdleTimingGran; + SS_DBGTI(SS_DBG_WARNING | SS_DBG_VDP1, "[VDP1] Program forced termination of VDP1 drawing."); + } + break; + + } + + SS_SetEventNT(&events[SS_EVENT_VDP1], nt); +} + +static INLINE uint16 ReadReg(const unsigned which) +{ + switch(which) + { + default: + SS_DBGTI(SS_DBG_WARNING | SS_DBG_VDP1, "[VDP1] Unknown read from register 0x%02x", which); + return 0; + + case 0x8: // EDSR + return EDSR; + + case 0x9: // LOPR + return LOPR; + + case 0xA: // COPR + return CurCommandAddr >> 2; + + case 0xB: // MODR + return (0x1 << 12) | ((PTMR & 0x2) << 7) | ((FBCR & 0x1E) << 3) | (TVMR << 0); + } +} + +void Write8_DB(uint32 A, uint16 DB) +{ + A &= 0x1FFFFF; + + if(A < 0x80000) + { + ne16_wbo_be(VRAM, A, DB >> (((A & 1) ^ 1) << 3) ); + return; + } + + if(A < 0x100000) + { + uint32 FBA = A; + + if((TVMR & (TVMR_8BPP | TVMR_ROTATE)) == (TVMR_8BPP | TVMR_ROTATE)) + FBA = (FBA & 0x1FF) | ((FBA << 1) & 0x3FC00) | ((FBA >> 8) & 0x200); + + ne16_wbo_be(FB[FBDrawWhich], FBA & 0x3FFFF, DB >> (((A & 1) ^ 1) << 3) ); + return; + } + + SS_DBGTI(SS_DBG_WARNING | SS_DBG_VDP1, "[VDP1] 8-bit write to 0x%08x(DB=0x%04x)", A, DB); + WriteReg((A - 0x100000) >> 1, DB); +} + +void Write16_DB(uint32 A, uint16 DB) +{ + A &= 0x1FFFFE; + + if(A < 0x80000) + { + VRAM[A >> 1] = DB; + return; + } + + if(A < 0x100000) + { + uint32 FBA = A; + + if((TVMR & (TVMR_8BPP | TVMR_ROTATE)) == (TVMR_8BPP | TVMR_ROTATE)) + FBA = (FBA & 0x1FF) | ((FBA << 1) & 0x3FC00) | ((FBA >> 8) & 0x200); + + FB[FBDrawWhich][(FBA >> 1) & 0x1FFFF] = DB; + return; + } + + WriteReg((A - 0x100000) >> 1, DB); +} + +uint16 Read16_DB(uint32 A) +{ + A &= 0x1FFFFE; + + if(A < 0x080000) + return VRAM[A >> 1]; + + if(A < 0x100000) + { + uint32 FBA = A; + + if((TVMR & (TVMR_8BPP | TVMR_ROTATE)) == (TVMR_8BPP | TVMR_ROTATE)) + FBA = (FBA & 0x1FF) | ((FBA << 1) & 0x3FC00) | ((FBA >> 8) & 0x200); + + return FB[FBDrawWhich][(FBA >> 1) & 0x1FFFF]; + } + + return ReadReg((A - 0x100000) >> 1); +} + + +uint8 PeekVRAM(const uint32 addr) +{ + return ne16_rbo_be(VRAM, addr & 0x7FFFF); +} + +void PokeVRAM(const uint32 addr, const uint8 val) +{ + ne16_wbo_be(VRAM, addr & 0x7FFFF, val); +} + +/*void MakeDump(const std::string& path) +{ + FileStream fp(path, FileStream::MODE_WRITE); + + for(unsigned i = 0; i < 0x40000; i++) + fp.print_format("0x%04x, ", VRAM[i]); + + fp.close(); +}*/ + +} + +} diff --git a/waterbox/ss/vdp1.h b/waterbox/ss/vdp1.h new file mode 100644 index 0000000000..2595edd0ee --- /dev/null +++ b/waterbox/ss/vdp1.h @@ -0,0 +1,59 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* vdp1.h: +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_VDP1_H +#define __MDFN_SS_VDP1_H + +namespace MDFN_IEN_SS +{ + +namespace VDP1 +{ + +void Init(void) MDFN_COLD; + +void Reset(bool powering_up) MDFN_COLD; + +sscpu_timestamp_t Update(sscpu_timestamp_t timestamp); +void AdjustTS(const int32 delta); + +void Write8_DB(uint32 A, uint16 DB) MDFN_HOT; +void Write16_DB(uint32 A, uint16 DB) MDFN_HOT; +uint16 Read16_DB(uint32 A) MDFN_HOT; + +void SetHBVB(const sscpu_timestamp_t event_timestamp, const bool new_hb_status, const bool new_vb_status); + +bool GetLine(const int line, uint16* buf, unsigned w, uint32 rot_x, uint32 rot_y, uint32 rot_xinc, uint32 rot_yinc); + +// __restrict__ in vdp2 +//const uint16* VPD1_FetchLine(void); +// vb start, vb end, field num... + +uint8 PeekVRAM(const uint32 addr); +void PokeVRAM(const uint32 addr, const uint8 val); + +void MakeDump(const std::string& path) MDFN_COLD; +} + +} + + +#endif diff --git a/waterbox/ss/vdp1_common.h b/waterbox/ss/vdp1_common.h new file mode 100644 index 0000000000..ba960a77b1 --- /dev/null +++ b/waterbox/ss/vdp1_common.h @@ -0,0 +1,670 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* vdp1_common.h: +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_VDP1_COMMON_H +#define __MDFN_SS_VDP1_COMMON_H + +#include "endian.h" + +namespace MDFN_IEN_SS +{ + +namespace VDP1 +{ + +int32 CMD_NormalSprite(const uint16*); +int32 CMD_ScaledSprite(const uint16*); +int32 CMD_DistortedSprite(const uint16*); + +int32 CMD_Polygon(const uint16*); +int32 CMD_Polyline(const uint16*); +int32 CMD_Line(const uint16*); + +extern uint16 VRAM[0x40000]; +extern uint16 FB[2][0x20000]; +extern bool FBDrawWhich; + +extern int32 SysClipX, SysClipY; +extern int32 UserClipX0, UserClipY0, UserClipX1, UserClipY1; +extern int32 LocalX, LocalY; + +extern uint32 (MDFN_FASTCALL *const TexFetchTab[0x20])(uint32 x); + +enum { TVMR_8BPP = 0x1 }; +enum { TVMR_ROTATE = 0x2 }; +enum { TVMR_HDTV = 0x4 }; +enum { TVMR_VBE = 0x8 }; +extern uint8 TVMR; + +enum { FBCR_FCT = 0x01 }; // Frame buffer change trigger +enum { FBCR_FCM = 0x02 }; // Frame buffer change mode +enum { FBCR_DIL = 0x04 }; // Double interlace draw line(0=even, 1=odd) (does it affect drawing to FB RAM or reading from FB RAM to VDP2?) +enum { FBCR_DIE = 0x08 }; // Double interlace enable +enum { FBCR_EOS = 0x10 }; // Even/Odd coordinate select(0=even, 1=odd, used with HSS) +extern uint8 FBCR; + +extern uint8 spr_w_shift_tab[8]; +extern uint8 gouraud_lut[0x40]; + +struct GourauderTheTerrible +{ + void Setup(const unsigned length, const uint16 gstart, const uint16 gend) + { + g = gstart & 0x7FFF; + intinc = 0; + + for(unsigned cc = 0; cc < 3; cc++) + { + const int dg = ((gend >> (cc * 5)) & 0x1F) - ((gstart >> (cc * 5)) & 0x1F); + const unsigned abs_dg = abs(dg); + + ginc[cc] = (uint32)((dg >= 0) ? 1 : -1) << (cc * 5); + + if(length <= abs_dg) + { + error_inc[cc] = (abs_dg + 1) * 2; + error_adj[cc] = (length * 2); + error[cc] = abs_dg + 1 - (length * 2 + ((dg < 0) ? 1 : 0)); + + while(error[cc] >= 0) { g += ginc[cc]; error[cc] -= error_adj[cc]; } + while(error_inc[cc] >= error_adj[cc]) { intinc += ginc[cc]; error_inc[cc] -= error_adj[cc]; } + } + else + { + error_inc[cc] = abs_dg * 2; + error_adj[cc] = ((length - 1) * 2); + error[cc] = length - (length * 2 - ((dg < 0) ? 1 : 0)); + if(error[cc] >= 0) { g += ginc[cc]; error[cc] -= error_adj[cc]; } + if(error_inc[cc] >= error_adj[cc]) { intinc += ginc[cc]; error_inc[cc] -= error_adj[cc]; } + } + error[cc] = ~error[cc]; + } + } + + inline uint32 Current(void) + { + return g; + } + + inline uint16 Apply(uint16 pix) const + { + uint16 ret = pix & 0x8000; + + ret |= gouraud_lut[((pix & (0x1F << 0)) + (g & (0x1F << 0))) >> 0] << 0; + ret |= gouraud_lut[((pix & (0x1F << 5)) + (g & (0x1F << 5))) >> 5] << 5; + ret |= gouraud_lut[((pix & (0x1F << 10)) + (g & (0x1F << 10))) >> 10] << 10; + + return ret; + } + + inline void Step(void) + { + g += intinc; + + for(unsigned cc = 0; cc < 3; cc++) + { + error[cc] -= error_inc[cc]; + { + const uint32 mask = (int32)error[cc] >> 31; + g += ginc[cc] & mask; + error[cc] += error_adj[cc] & mask; + } + } + } + + uint32 g; + uint32 intinc; + int32 ginc[3]; + int32 error[3]; + int32 error_inc[3]; + int32 error_adj[3]; +}; + +struct VileTex +{ + INLINE bool Setup(const unsigned length, const int32 tstart, const int32 tend, const int32 sf = 1, const int32 tfudge = 0) + { + int dt = tend - tstart; + unsigned abs_dt = abs(dt); + + t = (tstart * sf) | tfudge; + + tinc = (dt >= 0) ? sf : -sf; + + if(length <= abs_dt) + { + error_inc = (abs_dt + 1) * 2; + error_adj = (length * 2); + error = abs_dt + 1 - (length * 2 + ((dt < 0) ? 1 : 0)); + } + else + { + error_inc = abs_dt * 2; + error_adj = ((length - 1) * 2); + error = length - (length * 2 - ((dt < 0) ? 1 : 0)); + } + + return false; + } + + // + // + // + INLINE bool IncPending(void) { return error >= 0; } + INLINE int32 DoPendingInc(void) { t += tinc; error -= error_adj; return t; } + INLINE void AddError(void) { error += error_inc; } + // + // + // + + INLINE int32 PreStep(void) + { + while(error >= 0) + { + t += tinc; + error -= error_adj; + } + error += error_inc; + + return t; + } + + INLINE int32 Current(void) + { + return t; + } + + int32 t; + int32 tinc; + int32 error; + int32 error_inc; + int32 error_adj; +}; + +// +// +// +template +static INLINE int32 PlotPixel(int32 x, int32 y, uint16 pix, bool transparent, GourauderTheTerrible* g) +{ + static_assert(!MSBOn || (!HalfFGEn && !HalfBGEn), "Table error; sub-optimal template arguments."); + int32 ret = 0; + uint16* fbyptr; + + if(die) + { + fbyptr = &FB[FBDrawWhich][((y >> 1) & 0xFF) << 9]; + transparent |= ((y & 1) != (bool)(FBCR & FBCR_DIL)); + } + else + { + fbyptr = &FB[FBDrawWhich][(y & 0xFF) << 9]; + } + + if(MeshEn) + transparent |= (x ^ y) & 1; + + if(bpp8) + { + if(MSBOn) + { + pix = (fbyptr[((x >> 1) & 0x1FF)] | 0x8000) >> (((x & 1) ^ 1) << 3); + ret += 5; + } + else if(HalfBGEn) + ret += 5; + + if(!transparent) + { + if(bpp8 == 2) // BPP8 + rotated + ne16_wbo_be(fbyptr, (x & 0x1FF) | ((y & 0x100) << 1), pix); + else + ne16_wbo_be(fbyptr, x & 0x3FF, pix); + } + ret++; + } + else + { + uint16* const p = &fbyptr[x & 0x1FF]; + + if(MSBOn) + { + pix = *p | 0x8000; + ret += 5; + } + else + { + if(HalfBGEn) + { + uint16 bg_pix = *p; + ret += 5; + + if(bg_pix & 0x8000) + { + if(HalfFGEn) + { + if(g) + pix = g->Apply(pix); + + pix = ((pix + bg_pix) - ((pix ^ bg_pix) & 0x8421)) >> 1; + } + else + { + if(g) + pix = 0; + else + pix = ((bg_pix & 0x7BDE) >> 1) | (bg_pix & 0x8000); + } + } + else + { + if(HalfFGEn) + { + if(g) + pix = g->Apply(pix); + else + pix = pix; + } + else + { + if(g) + pix = 0; + else + pix = bg_pix; + } + } + } + else + { + if(g) + pix = g->Apply(pix); + + if(HalfFGEn) + pix = ((pix & 0x7BDE) >> 1) | (pix & 0x8000); + } + } + + if(!transparent) + *p = pix; + + ret++; + } + + return ret; +} + + +static INLINE void CheckUndefClipping(void) +{ + if(SysClipX < UserClipX1 || SysClipY < UserClipY1 || UserClipX0 > UserClipX1 || UserClipY0 > UserClipY1) + { + //SS_DBG(SS_DBG_WARNING, "[VDP1] Illegal clipping windows; Sys=%u:%u -- User=%u:%u - %u:%u\n", SysClipX, SysClipY, UserClipX0, UserClipY0, UserClipX1, UserClipY1); + } +} + + +// +// +struct line_vertex +{ + int32 x, y; + uint16 g; + int32 t; +}; + +struct line_data +{ + line_vertex p[2]; + bool PCD; + bool HSS; + uint16 color; + int32 ec_count; + uint32 (MDFN_FASTCALL *tffn)(uint32); + uint16 CLUT[0x10]; + uint32 cb_or; + uint32 tex_base; +}; + +extern line_data LineSetup; + +template +static int32 DrawLine(void) +{ + const uint16 color = LineSetup.color; + line_vertex p0 = LineSetup.p[0]; + line_vertex p1 = LineSetup.p[1]; + int32 ret = 0; + + if(!LineSetup.PCD) + { + // TODO: + // Plain clipping treats system clip X as an unsigned 10-bit quantity... + // Pre-clipping treats system clip X as a signed 13-bit quantity... + // + bool clipped = false; + bool swapped = false; + + ret += 4; + + if(UserClipEn) + { + if(UserClipMode) + { + // not correct: clipped |= (p0.x >= UserClipX0) & (p1.x <= UserClipX1) & (p0.y >= UserClipY0) & (p1.y <= UserClipY1); + clipped |= (p0.x < 0) & (p1.x < 0); + clipped |= (p0.x > SysClipX) & (p1.x > SysClipX); + clipped |= (p0.y < 0) & (p1.y < 0); + clipped |= (p0.y > SysClipY) & (p1.y > SysClipY); + + swapped = (p0.y == p1.y) & ((p0.x < 0) | (p0.x > SysClipX)); + } + else + { + // Ignore system clipping WRT pre-clip for UserClipEn == 1 && UserClipMode == 0 + clipped |= (p0.x < UserClipX0) & (p1.x < UserClipX0); + clipped |= (p0.x > UserClipX1) & (p1.x > UserClipX1); + clipped |= (p0.y < UserClipY0) & (p1.y < UserClipY0); + clipped |= (p0.y > UserClipY1) & (p1.y > UserClipY1); + + swapped = (p0.y == p1.y) & ((p0.x < UserClipX0) | (p0.x > UserClipX1)); + } + } + else + { + clipped |= (p0.x < 0) & (p1.x < 0); + clipped |= (p0.x > SysClipX) & (p1.x > SysClipX); + clipped |= (p0.y < 0) & (p1.y < 0); + clipped |= (p0.y > SysClipY) & (p1.y > SysClipY); + + swapped = (p0.y == p1.y) & ((p0.x < 0) | (p0.x > SysClipX)); + } + + if(clipped) + return ret; + + if(swapped) + std::swap(p0, p1); + } + + ret += 8; + + // + // + const int32 dx = p1.x - p0.x; + const int32 dy = p1.y - p0.y; + const int32 abs_dx = abs(dx); + const int32 abs_dy = abs(dy); + const int32 max_adx_ady = std::max(abs_dx, abs_dy); + int32 x_inc = (dx >= 0) ? 1 : -1; + int32 y_inc = (dy >= 0) ? 1 : -1; + int32 x = p0.x; + int32 y = p0.y; + bool drawn_ac = true; // Drawn all-clipped + uint32 texel; + GourauderTheTerrible g; + VileTex t; + + if(GouraudEn) + g.Setup(max_adx_ady + 1, p0.g, p1.g); + + if(Textured) + { + LineSetup.ec_count = 2; // Call before tffn() + + if(MDFN_UNLIKELY(max_adx_ady < abs(p1.t - p0.t) && LineSetup.HSS)) + { + LineSetup.ec_count = 0x7FFFFFFF; + t.Setup(max_adx_ady + 1, p0.t >> 1, p1.t >> 1, 2, (bool)(FBCR & FBCR_EOS)); + } + else + t.Setup(max_adx_ady + 1, p0.t, p1.t); + + texel = LineSetup.tffn(t.Current()); + } + + #define PSTART \ + bool transparent; \ + uint16 pix; \ + \ + if(Textured) \ + { \ + /*ret++;*/ \ + while(t.IncPending()) \ + { \ + int32 tx = t.DoPendingInc(); \ + \ + /*ret += (bool)t.IncPending();*/ \ + \ + texel = LineSetup.tffn(tx); \ + \ + if(!ECD && MDFN_UNLIKELY(LineSetup.ec_count <= 0)) \ + return ret; \ + } \ + t.AddError(); \ + \ + transparent = (SPD && ECD) ? false : (texel >> 31); \ + pix = texel; \ + } \ + else \ + { \ + pix = color; \ + transparent = !SPD; \ + } + + /* hmm, possible problem with AA and drawn_ac...*/ + #define PBODY(px, py) \ + { \ + bool clipped = ((uint32)px > (uint32)SysClipX) | ((uint32)py > (uint32)SysClipY); \ + \ + if(UserClipEn && !UserClipMode) \ + clipped |= (px < UserClipX0) | (px > UserClipX1) | (py < UserClipY0) | (py > UserClipY1); \ + \ + if(MDFN_UNLIKELY((clipped ^ drawn_ac) & clipped)) \ + return ret; \ + \ + drawn_ac &= clipped; \ + \ + if(UserClipEn && UserClipMode) \ + clipped |= (px >= UserClipX0) & (px <= UserClipX1) & (py >= UserClipY0) & (py <= UserClipY1); \ + \ + ret += PlotPixel(px, py, pix, transparent | clipped, (GouraudEn ? &g : NULL)); \ + } + + #define PEND \ + { \ + if(GouraudEn) \ + g.Step(); \ + } + + + if(abs_dy > abs_dx) + { + int32 error_inc = 2 * abs_dx; + int32 error_adj = -(2 * abs_dy); + int32 error = abs_dy - (2 * abs_dy + (dy >= 0 || AA)); + + y -= y_inc; + + do + { + PSTART; + + y += y_inc; + if(error >= 0) + { + if(AA) + { + int32 aa_x = x, aa_y = y; + + if(y_inc < 0) + { + aa_x += (x_inc >> 31); + aa_y -= (x_inc >> 31); + } + else + { + aa_x -= (~x_inc >> 31); + aa_y += (~x_inc >> 31); + } + + PBODY(aa_x, aa_y); + } + + error += error_adj; + x += x_inc; + } + error += error_inc; + + PBODY(x, y); + + PEND; + } while(MDFN_LIKELY(y != p1.y)); + } + else + { + int32 error_inc = 2 * abs_dy; + int32 error_adj = -(2 * abs_dx); + int32 error = abs_dx - (2 * abs_dx + (dx >= 0 || AA)); + + x -= x_inc; + + do + { + PSTART; + + x += x_inc; + if(error >= 0) + { + if(AA) + { + int32 aa_x = x, aa_y = y; + + if(x_inc < 0) + { + aa_x -= (~y_inc >> 31); + aa_y -= (~y_inc >> 31); + } + else + { + aa_x += (y_inc >> 31); + aa_y += (y_inc >> 31); + } + + PBODY(aa_x, aa_y); + } + + error += error_adj; + y += y_inc; + } + error += error_inc; + + PBODY(x, y); + + PEND; + } while(MDFN_LIKELY(x != p1.x)); + } + + return ret; +} + +template +struct EdgeStepper +{ + INLINE void Setup(const line_vertex& p0, const line_vertex& p1, const int32 dmax) + { + int32 dx = p1.x - p0.x; + int32 dy = p1.y - p0.y; + int32 abs_dx = abs(dx); + int32 abs_dy = abs(dy); + int32 max_adxdy = std::max(abs_dx, abs_dy); + + x = p0.x; + x_inc = (dx >= 0) ? 1 : -1; + x_error = ~(max_adxdy - (2 * max_adxdy + (dy >= 0))); + x_error_inc = 2 * abs_dx; + x_error_adj = 2 * max_adxdy; + + y = p0.y; + y_inc = (dy >= 0) ? 1 : -1; + y_error = ~(max_adxdy - (2 * max_adxdy + (dx >= 0))); + y_error_inc = 2 * abs_dy; + y_error_adj = 2 * max_adxdy; + + d_error = -dmax; + d_error_inc = 2 *max_adxdy; + d_error_adj = 2 * dmax; + + if(gourauden) + g.Setup(max_adxdy + 1, p0.g, p1.g); + } + + INLINE void GetVertex(line_vertex* p) + { + p->x = x; + p->y = y; + + if(gourauden) + p->g = g.Current(); + } + + INLINE void Step(void) + { + uint32 mask; + + d_error += d_error_inc; + if(d_error >= 0) + { + d_error -= d_error_adj; + + x_error -= x_error_inc; + mask = (int32)x_error >> 31; + x += x_inc & mask; + x_error += x_error_adj & mask; + + y_error -= y_error_inc; + mask = (int32)y_error >> 31; + y += y_inc & mask; + y_error += y_error_adj & mask; + + if(gourauden) + g.Step(); + } + } + + int32 d_error, d_error_inc, d_error_adj; + + int32 x, x_inc; + int32 x_error, x_error_inc, x_error_adj; + + int32 y, y_inc; + int32 y_error, y_error_inc, y_error_adj; + + GourauderTheTerrible g; +}; + +// +// +} + +} + + +#endif diff --git a/waterbox/ss/vdp1_line.cpp b/waterbox/ss/vdp1_line.cpp new file mode 100644 index 0000000000..7a3eaa3920 --- /dev/null +++ b/waterbox/ss/vdp1_line.cpp @@ -0,0 +1,130 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* vdp1_line.cpp - VDP1 Line Drawing Commands Emulation +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "ss.h" +#include "vdp1.h" +#include "vdp1_common.h" + +namespace MDFN_IEN_SS +{ + +namespace VDP1 +{ + +static int32 (*LineFuncTab[2][3][0x20][8 + 1])(void) = +{ + #define LINEFN_BC(die, bpp8, b, c) \ + DrawLine + + #define LINEFN_B(die, bpp8, b) \ + { \ + LINEFN_BC(die, bpp8, b, 0x0), LINEFN_BC(die, bpp8, b, 0x1), LINEFN_BC(die, bpp8, b, 0x2), LINEFN_BC(die, bpp8, b, 0x3), \ + LINEFN_BC(die, bpp8, b, 0x4), LINEFN_BC(die, bpp8, b, 0x5), LINEFN_BC(die, bpp8, b, 0x6), LINEFN_BC(die, bpp8, b, 0x7), \ + LINEFN_BC(die, bpp8, b, 0x8), /* msb on */ \ + } + + #define LINEFN_BPP8(die, bpp8) \ + { \ + LINEFN_B(die, bpp8, 0x00), LINEFN_B(die, bpp8, 0x01), LINEFN_B(die, bpp8, 0x02), LINEFN_B(die, bpp8, 0x03), \ + LINEFN_B(die, bpp8, 0x04), LINEFN_B(die, bpp8, 0x05), LINEFN_B(die, bpp8, 0x06), LINEFN_B(die, bpp8, 0x07), \ + LINEFN_B(die, bpp8, 0x08), LINEFN_B(die, bpp8, 0x09), LINEFN_B(die, bpp8, 0x0A), LINEFN_B(die, bpp8, 0x0B), \ + LINEFN_B(die, bpp8, 0x0C), LINEFN_B(die, bpp8, 0x0D), LINEFN_B(die, bpp8, 0x0E), LINEFN_B(die, bpp8, 0x0F), \ + \ + LINEFN_B(die, bpp8, 0x10), LINEFN_B(die, bpp8, 0x11), LINEFN_B(die, bpp8, 0x12), LINEFN_B(die, bpp8, 0x13), \ + LINEFN_B(die, bpp8, 0x14), LINEFN_B(die, bpp8, 0x15), LINEFN_B(die, bpp8, 0x16), LINEFN_B(die, bpp8, 0x17), \ + LINEFN_B(die, bpp8, 0x18), LINEFN_B(die, bpp8, 0x19), LINEFN_B(die, bpp8, 0x1A), LINEFN_B(die, bpp8, 0x1B), \ + LINEFN_B(die, bpp8, 0x1C), LINEFN_B(die, bpp8, 0x1D), LINEFN_B(die, bpp8, 0x1E), LINEFN_B(die, bpp8, 0x1F), \ + } + + { + LINEFN_BPP8(false, 0), + LINEFN_BPP8(false, 1), + LINEFN_BPP8(false, 2), + }, + { + LINEFN_BPP8(true, 0), + LINEFN_BPP8(true, 1), + LINEFN_BPP8(true, 2), + } + + + #undef LINEFN_BPP8 + #undef LINEFN_B + #undef LINEFN_BC +}; + +template +static INLINE int32 CMD_Line_Polyline_T(const uint16* cmd_data) +{ + const uint16 mode = cmd_data[0x2]; + int32 ret = 0; + // + // + bool SPD_Opaque = true; // Abusing the SPD bit passed to the line draw function to denote non-transparency when == 1, transparent when == 0. + + LineSetup.tex_base = 0; + LineSetup.color = cmd_data[0x3]; + LineSetup.PCD = mode & 0x800; + + if(((mode >> 3) & 0x7) < 0x6) + SPD_Opaque = (int32)(TexFetchTab[(mode >> 3) & 0x1F](0xFFFFFFFF)) >= 0; + // + // + // + auto* fnptr = LineFuncTab[(bool)(FBCR & FBCR_DIE)][(TVMR & TVMR_8BPP) ? ((TVMR & TVMR_ROTATE) ? 2 : 1) : 0][((mode >> 6) & 0x1E) | SPD_Opaque /*(mode >> 6) & 0x1F*/][(mode & 0x8000) ? 8 : (mode & 0x7)]; + + CheckUndefClipping(); + + for(unsigned n = 0; n < num_lines; n++) + { + LineSetup.p[0].x = sign_x_to_s32(13, cmd_data[0x6 + (((n << 1) + 0) & 0x7)] & 0x1FFF) + LocalX; + LineSetup.p[0].y = sign_x_to_s32(13, cmd_data[0x7 + (((n << 1) + 0) & 0x7)] & 0x1FFF) + LocalY; + LineSetup.p[1].x = sign_x_to_s32(13, cmd_data[0x6 + (((n << 1) + 2) & 0x7)] & 0x1FFF) + LocalX; + LineSetup.p[1].y = sign_x_to_s32(13, cmd_data[0x7 + (((n << 1) + 2) & 0x7)] & 0x1FFF) + LocalY; + + if(mode & 0x4) // Gouraud + { + const uint16* gtb = &VRAM[cmd_data[0xE] << 2]; + + ret += 2; + LineSetup.p[0].g = gtb[(n + 0) & 0x3]; + LineSetup.p[1].g = gtb[(n + 1) & 0x3]; + } + + ret += fnptr(); + } + + return ret; +} + +int32 CMD_Polyline(const uint16* cmd_data) +{ + return CMD_Line_Polyline_T<4>(cmd_data); +} + +int32 CMD_Line(const uint16* cmd_data) +{ + return CMD_Line_Polyline_T<1>(cmd_data); +} + +} + +} diff --git a/waterbox/ss/vdp1_poly.cpp b/waterbox/ss/vdp1_poly.cpp new file mode 100644 index 0000000000..bfe5cb6dd6 --- /dev/null +++ b/waterbox/ss/vdp1_poly.cpp @@ -0,0 +1,146 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* vdp1_poly.cpp - VDP1 Polygon Drawing Commands Emulation +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "ss.h" +#include "vdp1.h" +#include "vdp1_common.h" + +namespace MDFN_IEN_SS +{ + +namespace VDP1 +{ + +static int32 (*LineFuncTab[2][3][0x20][8 + 1])(void) = +{ + #define LINEFN_BC(die, bpp8, b, c) \ + DrawLine + + #define LINEFN_B(die, bpp8, b) \ + { \ + LINEFN_BC(die, bpp8, b, 0x0), LINEFN_BC(die, bpp8, b, 0x1), LINEFN_BC(die, bpp8, b, 0x2), LINEFN_BC(die, bpp8, b, 0x3), \ + LINEFN_BC(die, bpp8, b, 0x4), LINEFN_BC(die, bpp8, b, 0x5), LINEFN_BC(die, bpp8, b, 0x6), LINEFN_BC(die, bpp8, b, 0x7), \ + LINEFN_BC(die, bpp8, b, 0x8), /* msb on */ \ + } + + #define LINEFN_BPP8(die, bpp8) \ + { \ + LINEFN_B(die, bpp8, 0x00), LINEFN_B(die, bpp8, 0x01), LINEFN_B(die, bpp8, 0x02), LINEFN_B(die, bpp8, 0x03), \ + LINEFN_B(die, bpp8, 0x04), LINEFN_B(die, bpp8, 0x05), LINEFN_B(die, bpp8, 0x06), LINEFN_B(die, bpp8, 0x07), \ + LINEFN_B(die, bpp8, 0x08), LINEFN_B(die, bpp8, 0x09), LINEFN_B(die, bpp8, 0x0A), LINEFN_B(die, bpp8, 0x0B), \ + LINEFN_B(die, bpp8, 0x0C), LINEFN_B(die, bpp8, 0x0D), LINEFN_B(die, bpp8, 0x0E), LINEFN_B(die, bpp8, 0x0F), \ + \ + LINEFN_B(die, bpp8, 0x10), LINEFN_B(die, bpp8, 0x11), LINEFN_B(die, bpp8, 0x12), LINEFN_B(die, bpp8, 0x13), \ + LINEFN_B(die, bpp8, 0x14), LINEFN_B(die, bpp8, 0x15), LINEFN_B(die, bpp8, 0x16), LINEFN_B(die, bpp8, 0x17), \ + LINEFN_B(die, bpp8, 0x18), LINEFN_B(die, bpp8, 0x19), LINEFN_B(die, bpp8, 0x1A), LINEFN_B(die, bpp8, 0x1B), \ + LINEFN_B(die, bpp8, 0x1C), LINEFN_B(die, bpp8, 0x1D), LINEFN_B(die, bpp8, 0x1E), LINEFN_B(die, bpp8, 0x1F), \ + } + + { + LINEFN_BPP8(false, 0), + LINEFN_BPP8(false, 1), + LINEFN_BPP8(false, 2), + }, + { + LINEFN_BPP8(true, 0), + LINEFN_BPP8(true, 1), + LINEFN_BPP8(true, 2), + } + + + #undef LINEFN_BPP8 + #undef LINEFN_B + #undef LINEFN_BC +}; + +template +static INLINE int32 CMD_PolygonG_T(const uint16* cmd_data) +{ + const uint16 mode = cmd_data[0x2]; + line_vertex p[4]; + int32 ret = 0; + // + // + bool SPD_Opaque = true; // Abusing the SPD bit passed to the line draw function to denote non-transparency when == 1, transparent when == 0. + + LineSetup.tex_base = 0; + LineSetup.color = cmd_data[0x3]; + LineSetup.PCD = mode & 0x800; + + if(((mode >> 3) & 0x7) < 0x6) + SPD_Opaque = (int32)(TexFetchTab[(mode >> 3) & 0x1F](0xFFFFFFFF)) >= 0; + // + // + // + auto* fnptr = LineFuncTab[(bool)(FBCR & FBCR_DIE)][(TVMR & TVMR_8BPP) ? ((TVMR & TVMR_ROTATE) ? 2 : 1) : 0][((mode >> 6) & 0x1E) | SPD_Opaque /*(mode >> 6) & 0x1F*/][(mode & 0x8000) ? 8 : (mode & 0x7)]; + + CheckUndefClipping(); + + for(unsigned i = 0; i < 4; i++) + { + p[i].x = sign_x_to_s32(13, cmd_data[0x6 + (i << 1)]) + LocalX; + p[i].y = sign_x_to_s32(13, cmd_data[0x7 + (i << 1)]) + LocalY; + } + + if(gourauden) + { + const uint16* gtb = &VRAM[cmd_data[0xE] << 2]; + + ret += 4; + for(unsigned i = 0; i < 4; i++) + p[i].g = gtb[i]; + } + // + // + // + const int32 dmax = std::max(std::max(abs(p[3].x - p[0].x), abs(p[3].y - p[0].y)), + std::max(abs(p[2].x - p[1].x), abs(p[2].y - p[1].y))); + EdgeStepper e[2]; + + e[0].Setup(p[0], p[3], dmax); + e[1].Setup(p[1], p[2], dmax); + + for(int32 i = 0; i <= dmax; i++) + { + e[0].GetVertex(&LineSetup.p[0]); + e[1].GetVertex(&LineSetup.p[1]); + // + //printf("%d:%d -> %d:%d\n", lp[0].x, lp[0].y, lp[1].x, lp[1].y); + ret += fnptr(); + // + e[0].Step(); + e[1].Step(); + } + + return ret; +} + +int32 CMD_Polygon(const uint16* cmd_data) +{ + if(cmd_data[0x2] & 0x4) // gouraud + return CMD_PolygonG_T(cmd_data); + else + return CMD_PolygonG_T(cmd_data); +} + + +} +} diff --git a/waterbox/ss/vdp1_sprite.cpp b/waterbox/ss/vdp1_sprite.cpp new file mode 100644 index 0000000000..bb30547aae --- /dev/null +++ b/waterbox/ss/vdp1_sprite.cpp @@ -0,0 +1,319 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* vdp1_sprite.cpp - VDP1 Sprite Drawing Commands Emulation +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "ss.h" +#include "vdp1.h" +#include "vdp1_common.h" + +//#pragma GCC optimize("Os,no-crossjumping") + +namespace MDFN_IEN_SS +{ + +namespace VDP1 +{ + +static int32 (*LineFuncTab[2][3][0x20][8 + 1])(void) = +{ + #define LINEFN_BC(die, bpp8, b, c) \ + DrawLine + + #define LINEFN_B(die, bpp8, b) \ + { \ + LINEFN_BC(die, bpp8, b, 0x0), LINEFN_BC(die, bpp8, b, 0x1), LINEFN_BC(die, bpp8, b, 0x2), LINEFN_BC(die, bpp8, b, 0x3), \ + LINEFN_BC(die, bpp8, b, 0x4), LINEFN_BC(die, bpp8, b, 0x5), LINEFN_BC(die, bpp8, b, 0x6), LINEFN_BC(die, bpp8, b, 0x7), \ + LINEFN_BC(die, bpp8, b, 0x8), /* msb on */ \ + } + + #define LINEFN_BPP8(die, bpp8) \ + { \ + LINEFN_B(die, bpp8, 0x00), LINEFN_B(die, bpp8, 0x01), LINEFN_B(die, bpp8, 0x02), LINEFN_B(die, bpp8, 0x03), \ + LINEFN_B(die, bpp8, 0x04), LINEFN_B(die, bpp8, 0x05), LINEFN_B(die, bpp8, 0x06), LINEFN_B(die, bpp8, 0x07), \ + LINEFN_B(die, bpp8, 0x08), LINEFN_B(die, bpp8, 0x09), LINEFN_B(die, bpp8, 0x0A), LINEFN_B(die, bpp8, 0x0B), \ + LINEFN_B(die, bpp8, 0x0C), LINEFN_B(die, bpp8, 0x0D), LINEFN_B(die, bpp8, 0x0E), LINEFN_B(die, bpp8, 0x0F), \ + \ + LINEFN_B(die, bpp8, 0x10), LINEFN_B(die, bpp8, 0x11), LINEFN_B(die, bpp8, 0x12), LINEFN_B(die, bpp8, 0x13), \ + LINEFN_B(die, bpp8, 0x14), LINEFN_B(die, bpp8, 0x15), LINEFN_B(die, bpp8, 0x16), LINEFN_B(die, bpp8, 0x17), \ + LINEFN_B(die, bpp8, 0x18), LINEFN_B(die, bpp8, 0x19), LINEFN_B(die, bpp8, 0x1A), LINEFN_B(die, bpp8, 0x1B), \ + LINEFN_B(die, bpp8, 0x1C), LINEFN_B(die, bpp8, 0x1D), LINEFN_B(die, bpp8, 0x1E), LINEFN_B(die, bpp8, 0x1F), \ + } + + { + LINEFN_BPP8(false, 0), + LINEFN_BPP8(false, 1), + LINEFN_BPP8(false, 2), + }, + { + LINEFN_BPP8(true, 0), + LINEFN_BPP8(true, 1), + LINEFN_BPP8(true, 2), + } + + + #undef LINEFN_BPP8 + #undef LINEFN_B + #undef LINEFN_BC +}; + +/* + Timing notes: + Timing is somewhat complex, and looks like the drawing of the lines of distorted sprites may be terminated + early in some conditions relating to clipping. + + Drawing a 256x1 texture with a 255x1 rectangular distorted sprite takes about twice as much time(even with blending enabled, which is weird...) as drawing + it with a 256x1 or 257x1 rectangular distorted sprite. +*/ +enum +{ + FORMAT_NORMAL, + FORMAT_SCALED, + FORMAT_DISTORTED +}; + +template +static INLINE int32 SpriteBase(const uint16* cmd_data) +{ + const unsigned dir = (cmd_data[0] >> 4) & 0x3; + const uint16 mode = cmd_data[0x2]; + const unsigned cm = (mode >> 3) & 0x7; + const uint16 color = cmd_data[0x3]; + const uint32 w = ((cmd_data[0x5] >> 8) & 0x3F) << 3; + const uint32 h = cmd_data[0x5] & 0xFF; + line_vertex p[4]; + int32 ret = 0; + auto* fnptr = LineFuncTab[(bool)(FBCR & FBCR_DIE)][(TVMR & TVMR_8BPP) ? ((TVMR & TVMR_ROTATE) ? 2 : 1) : 0][(mode >> 6) & 0x1F][(mode & 0x8000) ? 8 : (mode & 0x7)]; + + LineSetup.color = cmd_data[0x3]; + LineSetup.PCD = mode & 0x0800; + LineSetup.HSS = mode & 0x1000; + + CheckUndefClipping(); + + // FIXME: precision is probably not totally right. + if(format == FORMAT_DISTORTED) + { + for(unsigned i = 0; i < 4; i++) + { + p[i].x = sign_x_to_s32(13, cmd_data[0x6 + (i << 1)]) + LocalX; + p[i].y = sign_x_to_s32(13, cmd_data[0x7 + (i << 1)]) + LocalY; + } + //printf("Hrm: %d:%d %d:%d %d:%d %d:%d\n", p[0].x, p[0].y, p[1].x, p[1].y, p[2].x, p[2].y, p[3].x, p[3].y); + } + else if(format == FORMAT_NORMAL) + { + p[0].x = sign_x_to_s32(13, cmd_data[0x6]) + LocalX; + p[0].y = sign_x_to_s32(13, cmd_data[0x7]) + LocalY; + + p[1].x = p[0].x + (std::max(w, 1) - 1); + p[1].y = p[0].y; + + p[2].x = p[1].x; + p[2].y = p[0].y + (std::max(h, 1) - 1); + + p[3].x = p[0].x; + p[3].y = p[2].y; + } + else if(format == FORMAT_SCALED) + { + const unsigned zp = (cmd_data[0] >> 8) & 0xF; + { + int32 zp_x = sign_x_to_s32(13, cmd_data[0x6]); + int32 zp_y = sign_x_to_s32(13, cmd_data[0x7]); + int32 disp_w = sign_x_to_s32(13, cmd_data[0x8]); + int32 disp_h = sign_x_to_s32(13, cmd_data[0x9]); + int32 alt_x = sign_x_to_s32(13, cmd_data[0xA]); + int32 alt_y = sign_x_to_s32(13, cmd_data[0xB]); + + for(unsigned i = 0; i < 4; i++) + { + p[i].x = zp_x; + p[i].y = zp_y; + } + + switch(zp >> 2) + { + case 0x0: + p[2].y = alt_y; + p[3].y = alt_y; + break; + + case 0x1: + p[2].y += disp_h; + p[3].y += disp_h; + break; + + case 0x2: + p[0].y -= disp_h >> 1; + p[1].y -= disp_h >> 1; + p[2].y += (disp_h + 1) >> 1; + p[3].y += (disp_h + 1) >> 1; + break; + + case 0x3: + p[0].y -= disp_h; + p[1].y -= disp_h; + break; + } + + switch(zp & 0x3) + { + case 0x0: + p[1].x = alt_x; + p[2].x = alt_x; + break; + + case 0x1: + p[1].x += disp_w; + p[2].x += disp_w; + break; + + case 0x2: + p[0].x -= disp_w >> 1; + p[1].x += (disp_w + 1) >> 1; + p[2].x += (disp_w + 1) >> 1; + p[3].x -= disp_w >> 1; + break; + + case 0x3: + p[0].x -= disp_w; + p[3].x -= disp_w; + break; + } + + for(unsigned i = 0; i < 4; i++) + { + p[i].x += LocalX; + p[i].y += LocalY; + } + } + } + + if(gourauden) + { + const uint16* gtb = &VRAM[cmd_data[0xE] << 2]; + + ret += 4; + for(unsigned i = 0; i < 4; i++) + p[i].g = gtb[i]; + } + // + // + // + VileTex big_t; + int32 tex_base; + + LineSetup.tffn = TexFetchTab[(mode >> 3) & 0x1F]; + + { + const bool h_inv = dir & 1; + + LineSetup.p[0 ^ h_inv].t = 0; + LineSetup.p[1 ^ h_inv].t = w ? (w - 1) : 0; + } + + switch(cm) + { + case 0: LineSetup.cb_or = color &~ 0xF; + break; + + case 1: + for(unsigned i = 0; i < 16; i++) + LineSetup.CLUT[i] = VRAM[((color &~ 0x3) << 2) | i]; + + ret += 16; + break; + + case 2: LineSetup.cb_or = color &~ 0x3F; break; + case 3: LineSetup.cb_or = color &~ 0x7F; break; + case 4: LineSetup.cb_or = color &~ 0xFF; break; + case 5: break; + case 6: break; + case 7: break; + } + // + // + // + const int32 dmax = std::max(std::max(abs(p[3].x - p[0].x), abs(p[3].y - p[0].y)), + std::max(abs(p[2].x - p[1].x), abs(p[2].y - p[1].y))); + EdgeStepper e[2]; + + e[0].Setup(p[0], p[3], dmax); + e[1].Setup(p[1], p[2], dmax); + + tex_base = cmd_data[0x4] << 2; + if(cm == 5) // RGB + tex_base &= ~0x7; + + { + const bool v_inv = dir & 2; + int32 tv[2]; + + tv[0 ^ v_inv] = 0; + tv[1 ^ v_inv] = h ? (h - 1) : 0; + + big_t.Setup(dmax + 1, tv[0], tv[1], w >> spr_w_shift_tab[cm]); + } + + for(int32 i = 0; i <= dmax; i++) + { + e[0].GetVertex(&LineSetup.p[0]); + e[1].GetVertex(&LineSetup.p[1]); + + LineSetup.tex_base = tex_base + big_t.PreStep(); + // + //printf("%d:%d -> %d:%d\n", lp[0].x, lp[0].y, lp[1].x, lp[1].y); + ret += fnptr(); + // + e[0].Step(); + e[1].Step(); + } + + return ret; +} + +int32 CMD_DistortedSprite(const uint16* cmd_data) +{ + if(cmd_data[0x2] & 0x4) // gouraud + return SpriteBase(cmd_data); + else + return SpriteBase(cmd_data); +} + + +int32 CMD_NormalSprite(const uint16* cmd_data) +{ + if(cmd_data[0x2] & 0x4) // gouraud + return SpriteBase(cmd_data); + else + return SpriteBase(cmd_data); +} + +int32 CMD_ScaledSprite(const uint16* cmd_data) +{ + if(cmd_data[0x2] & 0x4) // gouraud + return SpriteBase(cmd_data); + else + return SpriteBase(cmd_data); +} + + +} +} diff --git a/waterbox/ss/vdp2.cpp b/waterbox/ss/vdp2.cpp new file mode 100644 index 0000000000..298f1bae1e --- /dev/null +++ b/waterbox/ss/vdp2.cpp @@ -0,0 +1,930 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* vdp2.cpp - VDP2 Emulation +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +// TODO: Emulate brokenness(missing vblank) that occurs when switching from 240-height mode to 224-height mode around lines 224-239. + +// TODO: Update output signals on Reset()? Might have to call VDP2::Reset() before other _Reset() then...and take special care in the +// SMPC clock change code. + +#include "ss.h" +#include "vdp1.h" +#include "vdp2.h" +#include "scu.h" +#include "smpc.h" + +#include "vdp2_common.h" +#include "vdp2_render.h" + +namespace MDFN_IEN_SS +{ + +namespace VDP2 +{ + +static bool PAL; +static sscpu_timestamp_t lastts; +// +// +// +static uint16 RawRegs[0x100]; // For debugging + +static bool DisplayOn; +static bool BorderMode; +static bool ExLatchEnable; +static bool ExSyncEnable; +static bool ExBGEnable; +static bool DispAreaSelect; + +static bool VRAMSize; + +static uint8 HRes, VRes; +static uint8 InterlaceMode; +enum { IM_NONE, IM_ILLEGAL, IM_SINGLE, IM_DOUBLE }; + +static uint16 RAMCTL_Raw; +static uint8 CRAM_Mode; +enum +{ + CRAM_MODE_RGB555_1024 = 0, + CRAM_MODE_RGB555_2048 = 1, + CRAM_MODE_RGB888_1024 = 2, + CRAM_MODE_ILLEGAL = 3 +}; + +static uint16 BGON; +static uint8 VCPRegs[4][8]; +static uint32 VRAMPenalty[4]; + +static uint32 RPTA; +static uint8 RPRCTL[2]; +static uint8 KTAOF[2]; + +static uint16 VRAM[262144]; + +static uint16 CRAM[2048]; + +static struct +{ + // Signed values are stored sign-extended to the full 32 bits. + int32 Xst, Yst, Zst; // 1.12.10 + int32 DXst, DYst; // 1. 2.10 + int32 DX, DY; // 1. 2.10 + int32 RotMatrix[6]; // 1. 3.10 + int32 Px, Py, Pz; // 1.13. 0 + int32 Cx, Cy, Cz; // 1.13. 0 + int32 Mx, My; // 1.13.10 + int32 kx, ky; // 1. 7.16 + + uint32 KAst; // 0.16.10 + uint32 DKAst; // 1. 9.10 + uint32 DKAx; // 1. 9.10 + // + // + // + uint32 XstAccum, YstAccum; // 1.12.10 (sorta) + uint32 KAstAccum; // .10 +} RotParams[2]; + +static void FetchRotParams(const bool field) +{ + uint32 a = RPTA & 0x7FFBE; + + for(unsigned i = 0; i < 2; i++) + { + auto& rp = RotParams[i]; + + rp.Xst = sign_x_to_s32(23, ne16_rbo_be(VRAM, ((a + 0x00) & 0x3FFFF) << 1) >> 6); + rp.Yst = sign_x_to_s32(23, ne16_rbo_be(VRAM, ((a + 0x02) & 0x3FFFF) << 1) >> 6); + rp.Zst = sign_x_to_s32(23, ne16_rbo_be(VRAM, ((a + 0x04) & 0x3FFFF) << 1) >> 6); + + rp.DXst = sign_x_to_s32(13, ne16_rbo_be(VRAM, ((a + 0x06) & 0x3FFFF) << 1) >> 6); + rp.DYst = sign_x_to_s32(13, ne16_rbo_be(VRAM, ((a + 0x08) & 0x3FFFF) << 1) >> 6); + + rp.DX = sign_x_to_s32(13, ne16_rbo_be(VRAM, ((a + 0x0A) & 0x3FFFF) << 1) >> 6); + rp.DY = sign_x_to_s32(13, ne16_rbo_be(VRAM, ((a + 0x0C) & 0x3FFFF) << 1) >> 6); + + for(unsigned m = 0; m < 6; m++) + { + rp.RotMatrix[m] = sign_x_to_s32(14, ne16_rbo_be(VRAM, ((a + 0x0E + (m << 1)) & 0x3FFFF) << 1) >> 6); + } + + rp.Px = sign_x_to_s32(14, VRAM[(a + 0x1A) & 0x3FFFF]); + rp.Py = sign_x_to_s32(14, VRAM[(a + 0x1B) & 0x3FFFF]); + rp.Pz = sign_x_to_s32(14, VRAM[(a + 0x1C) & 0x3FFFF]); + + rp.Cx = sign_x_to_s32(14, VRAM[(a + 0x1E) & 0x3FFFF]); + rp.Cy = sign_x_to_s32(14, VRAM[(a + 0x1F) & 0x3FFFF]); + rp.Cz = sign_x_to_s32(14, VRAM[(a + 0x20) & 0x3FFFF]); + + rp.Mx = sign_x_to_s32(24, ne16_rbo_be(VRAM, ((a + 0x22) & 0x3FFFF) << 1) >> 6); + rp.My = sign_x_to_s32(24, ne16_rbo_be(VRAM, ((a + 0x24) & 0x3FFFF) << 1) >> 6); + + rp.kx = sign_x_to_s32(24, ne16_rbo_be(VRAM, ((a + 0x26) & 0x3FFFF) << 1)); + rp.ky = sign_x_to_s32(24, ne16_rbo_be(VRAM, ((a + 0x28) & 0x3FFFF) << 1)); + + rp.KAst = ne16_rbo_be(VRAM, ((a + 0x2A) & 0x3FFFF) << 1) >> 6; + rp.DKAst = sign_x_to_s32(20, ne16_rbo_be(VRAM, ((a + 0x2C) & 0x3FFFF) << 1) >> 6); + rp.DKAx = sign_x_to_s32(20, ne16_rbo_be(VRAM, ((a + 0x2E) & 0x3FFFF) << 1) >> 6); + + a += 0x40; + // + // Interlace mode doesn't seem to affect operation? + // + // const bool imft = (InterlaceMode == IM_DOUBLE && field); + + if(RPRCTL[i] & 0x01) + rp.XstAccum = rp.Xst; // + rp.DXst * imft; + else + rp.XstAccum += rp.DXst; // << (InterlaceMode == IM_DOUBLE); + + if(RPRCTL[i] & 0x02) + rp.YstAccum = rp.Yst; // + rp.DYst * imft; + else + rp.YstAccum += rp.DYst; // << (InterlaceMode == IM_DOUBLE); + + if(RPRCTL[i] & 0x04) + rp.KAstAccum = (KTAOF[i] << 26) + rp.KAst; // + rp.DKAst * imft; + else + rp.KAstAccum += rp.DKAst; // << (InterlaceMode == IM_DOUBLE); + } +} + +enum +{ + VPHASE_ACTIVE = 0, + + VPHASE_BOTTOM_BORDER, + VPHASE_BOTTOM_BLANKING, + + VPHASE_VSYNC, + + VPHASE_TOP_BLANKING, + VPHASE_TOP_BORDER, + + VPHASE__COUNT +}; + +static const int32 VTimings[2][4][VPHASE__COUNT] = // End lines +{ + { // NTSC: + { 0x0E0, 0xE8, 0xED, 0xF0, 0x0FF, 0x107 }, + { 0x0F0, 0xF0, 0xF5, 0xF8, 0x107, 0x107 }, + { 0x0E0, 0xE8, 0xED, 0xF0, 0x0FF, 0x107 }, + { 0x0F0, 0xF0, 0xF5, 0xF8, 0x107, 0x107 }, + }, + { // PAL: + // btm brdr begin, btm blnk begin, vsync begin, /***/ top blnk begin, top brdr begin, total + { 0x0E0, 0x100, 0x103, /***/ 0x103 + 3/*?*/, 0x119, 0x139 }, + { 0x0F0, 0x108, 0x10B, /***/ 0x10B + 3/*?*/, 0x121, 0x139 }, + { 0x100, 0x110, 0x113, /***/ 0x113 + 3/*?*/, 0x129, 0x139 }, + { 0x100, 0x110, 0x113, /***/ 0x113 + 3/*?*/, 0x129, 0x139 }, + }, +}; + +static bool Out_VB; // VB output signal + +static uint32 VPhase; +/*static*/ int32 VCounter; +static bool InternalVB; +static bool Odd; +// +static int SurfInterlaceField; +// +// +// + + +// (No 0) 8 accesses, No split: 0 added cycles +// (No 4) 4 accesses, No split: 1 added cycles +// (No 6) 2 accesses, No split: 2 added cycles +// (No 7) 1 accesses, No split: 3, Split: 3.51? added cycles +// (No 8) 0 accesses, No split: 4, Split: 5.34? added cycles +static INLINE void RecalcVRAMPenalty(void) +{ + if(InternalVB) + VRAMPenalty[0] = VRAMPenalty[1] = VRAMPenalty[2] = VRAMPenalty[3] = 0; + else + { + const unsigned VRAM_Mode = (RAMCTL_Raw >> 8) & 0x3; + const unsigned RDBS_Mode = (RAMCTL_Raw & 0xFF); + const size_t sh = ((HRes & 0x6) ? 0 : 4); + uint8 vcp_type_penalty[0x10]; + + for(unsigned vcp_type = 0; vcp_type < 0x10; vcp_type++) + { + bool penalty; + + if((vcp_type < 0x8) || vcp_type == 0xC || vcp_type == 0xD) + penalty = (bool)(BGON & (1U << (vcp_type & 0x3))); + else + penalty = false; + + vcp_type_penalty[vcp_type] = penalty; + } + + for(unsigned bank = 0; bank < 4; bank++) + { + const unsigned esb = bank & (2 | ((VRAM_Mode >> (bank >> 1)) & 1)); + const uint8 rdbs = (RDBS_Mode >> (esb << 1)) & 0x3; + uint32 tmp = 0; + + if(BGON & 0x20) + { + if(bank >= 2 || ((BGON & 0x10) && rdbs != RDBS_UNUSED)) + tmp = 8; + } + else + { + if((BGON & 0x10) && rdbs != RDBS_UNUSED) + tmp = 8; + else if(BGON & 0x0F) + { + tmp += vcp_type_penalty[VCPRegs[esb][0]]; + tmp += vcp_type_penalty[VCPRegs[esb][1]]; + tmp += vcp_type_penalty[VCPRegs[esb][2]]; + tmp += vcp_type_penalty[VCPRegs[esb][3]]; + + tmp += vcp_type_penalty[VCPRegs[esb][sh + 0]]; + tmp += vcp_type_penalty[VCPRegs[esb][sh + 1]]; + tmp += vcp_type_penalty[VCPRegs[esb][sh + 2]]; + tmp += vcp_type_penalty[VCPRegs[esb][sh + 3]]; + } + } + + static const uint8 tab[9] = { 0, 0, 0, 0, 1, 1, 2, 3, 4 }; + VRAMPenalty[bank] = tab[tmp]; + //printf("%d, %d\n", bank, tmp); + } + } +} + +enum +{ + HPHASE_ACTIVE = 0, + + HPHASE_RIGHT_BORDER, + HPHASE_HSYNC, + + // ... ? ? ? + + HPHASE__COUNT +}; + +static const int32 HTimings[2][HPHASE__COUNT] = +{ + { 0x140, 0x15B, 0x1AB }, + { 0x160, 0x177, 0x1C7 }, +}; + +static uint32 HPhase; +/*static*/ int32 HCounter; + +static uint16 Latched_VCNT, Latched_HCNT; +static bool HVIsExLatched; + +static void LatchHV(void) +{ + { + unsigned vtmp; + + if(VPhase >= VPHASE_VSYNC) + vtmp = VCounter + (0x200 - VTimings[PAL][VRes][VPHASE__COUNT - 1]); + else + vtmp = VCounter; + + if(InterlaceMode == IM_DOUBLE) + vtmp = (vtmp << 1) | !Odd; + + Latched_VCNT = vtmp; + } + + if(HPhase >= HPHASE_HSYNC) + Latched_HCNT = (HCounter + (0x200 - HTimings[HRes & 1][HPHASE__COUNT - 1])) << 1; + else + Latched_HCNT = HCounter << 1; + + //HVIsLatched = true; // Only on external signal-induced latching? +} +// +// +void StartFrame(EmulateSpecStruct* espec, const bool clock28m) +{ + //printf("StartFrame: %d\n", SurfInterlaceField); + VDP2REND_StartFrame(espec, clock28m, SurfInterlaceField); +} + +// +// +static INLINE void IncVCounter(const sscpu_timestamp_t event_timestamp) +{ + VCounter = (VCounter + 1) & 0x1FF; + + if(VCounter == (VTimings[PAL][VRes][VPHASE__COUNT - 1] - 1)) + Out_VB = false; + + // - 1, so the CPU loop will have plenty of time to exit before we reach non-hblank top border area + // (exit granularity could be large if program is executing from SCSP RAM space, for example). + if(VCounter == (VTimings[PAL][VRes][VPHASE_TOP_BLANKING] - 1)) + { +#if 0 + for(unsigned bank = 0; bank < 4; bank++) + { + printf("Bank %d: ", bank); + for(unsigned vc = 0; vc < 8; vc++) + printf("%01x ", VCPRegs[bank][vc]); + printf("\n"); + } +#endif + + SS_RequestMLExit(); + VDP2REND_EndFrame(); + //printf("Meow: %d\n", VCounter); + } + + while(VCounter >= VTimings[PAL][VRes][VPhase] - ((VPhase == VPHASE_VSYNC - 1) && InterlaceMode)) + { + VPhase++; + + if(VPhase == VPHASE__COUNT) + { + VPhase = 0; + VCounter -= VTimings[PAL][VRes][VPHASE__COUNT - 1]; + } + + if(VPhase == VPHASE_ACTIVE) + InternalVB = !DisplayOn; + else if(VPhase == VPHASE_BOTTOM_BORDER) + { + SS_SetEventNT(&events[SS_EVENT_MIDSYNC], event_timestamp + 1); + InternalVB = true; + Out_VB = true; + } + else if(VPhase == VPHASE_VSYNC) + { + if(InterlaceMode) + { + Odd = !Odd; + VCounter += Odd; + SurfInterlaceField = !Odd; + } + else + { + SurfInterlaceField = -1; + Odd = true; + } + } + } + + RecalcVRAMPenalty(); + + SMPC_SetVB(event_timestamp, Out_VB); +} + +static INLINE int32 AddHCounter(const sscpu_timestamp_t event_timestamp, int32 count) +{ + HCounter += count; + + //if(HCounter > HTimings[HRes & 1][HPhase]) + // printf("VDP2 oops: %d %d\n", HCounter, HTimings[HRes & 1][HPhase]); + + while(HCounter >= HTimings[HRes & 1][HPhase]) + { + HPhase++; + + if(HPhase == HPHASE__COUNT) + { + HPhase = 0; + HCounter -= HTimings[HRes & 1][HPHASE__COUNT - 1]; + } + // + // + // + if(HPhase == HPHASE_ACTIVE) + { + if(VPhase == VPHASE_ACTIVE) + { + VDP2Rend_LIB* lib = VDP2REND_GetLIB(VCounter); + + if(!InternalVB) + { + if(BGON & 0x30) + { + if(VCounter == 0) + RPRCTL[0] = RPRCTL[1] = 0x07; + FetchRotParams(false/*field*/); + RPRCTL[0] = RPRCTL[1] = 0; + } + + for(unsigned i = 0; i < 2; i++) + { + auto const& rp = RotParams[i]; + auto& r = lib->rv[i]; + + r.Xsp = ((int64)rp.RotMatrix[0] * ((int32)rp.XstAccum - (rp.Px * 1024)) + + (int64)rp.RotMatrix[1] * ((int32)rp.YstAccum - (rp.Py * 1024)) + + (int64)rp.RotMatrix[2] * (rp.Zst - (rp.Pz * 1024))) >> 10; + r.Ysp = ((int64)rp.RotMatrix[3] * ((int32)rp.XstAccum - (rp.Px * 1024)) + + (int64)rp.RotMatrix[4] * ((int32)rp.YstAccum - (rp.Py * 1024)) + + (int64)rp.RotMatrix[5] * (rp.Zst - (rp.Pz * 1024))) >> 10; + + r.Xp = rp.RotMatrix[0] * (rp.Px - rp.Cx) + + rp.RotMatrix[1] * (rp.Py - rp.Cy) + + rp.RotMatrix[2] * (rp.Pz - rp.Cz) + + (rp.Cx * 1024) + rp.Mx; + + r.Yp = rp.RotMatrix[3] * (rp.Px - rp.Cx) + + rp.RotMatrix[4] * (rp.Py - rp.Cy) + + rp.RotMatrix[5] * (rp.Pz - rp.Cz) + + (rp.Cy * 1024) + rp.My; + + r.dX = (rp.RotMatrix[0] * rp.DX + rp.RotMatrix[1] * rp.DY) >> 10; + r.dY = (rp.RotMatrix[3] * rp.DX + rp.RotMatrix[4] * rp.DY) >> 10; + + r.kx = rp.kx; + r.ky = rp.ky; + + r.KAstAccum = rp.KAstAccum; + r.DKAx = rp.DKAx; + } + } + //printf("%d, 0x%08x(%f) 0x%08x(%f)\n", VCounter, RotParams[0].KAstAccum >> 10, (int32)RotParams[0].DKAst / 1024.0, RotParams[1].KAstAccum >> 10, (int32)RotParams[1].DKAst / 1024.0); + //printf("DL: %d\n", VCounter); + lib->vdp1_hires8 = VDP1::GetLine(VCounter, lib->vdp1_line, (HRes & 1) ? 352 : 320, (int32)RotParams[0].XstAccum >> 1, (int32)RotParams[0].YstAccum >> 1, (int32)RotParams[0].DX >> 1, (int32)RotParams[0].DY >> 1); // Always call, has side effects. + VDP2REND_DrawLine(InternalVB ? -1 : VCounter, !Odd); + } + else if(VPhase == VPHASE_TOP_BORDER || VPhase == VPHASE_BOTTOM_BORDER) + VDP2REND_DrawLine(-1, !Odd); + } + else if(HPhase == HPHASE_HSYNC) + { + IncVCounter(event_timestamp); + } + } + + return (HTimings[HRes & 1][HPhase] - HCounter); +} + +sscpu_timestamp_t Update(sscpu_timestamp_t timestamp) +{ + int32 clocks = (timestamp - lastts) >> 2; + + if(MDFN_UNLIKELY(timestamp < lastts)) + { + SS_DBGTI(SS_DBG_WARNING | SS_DBG_VDP2, "[VDP2] [BUG] timestamp(%d) < lastts(%d)", timestamp, lastts); + clocks = 0; + } + + lastts += clocks << 2; + // + // + int32 ne; + int32 tmp; + + ne = AddHCounter(timestamp, clocks); + VDP1::SetHBVB(timestamp, HPhase > HPHASE_ACTIVE, Out_VB); + tmp = SCU_SetHBVB(clocks, HPhase > HPHASE_ACTIVE, Out_VB); + if(tmp < ne) + ne = tmp; + + return lastts + (ne << 2); +} + +// +// Register writes seem to always be 16-bit +// +static INLINE void RegsWrite(uint32 A, uint16 V) +{ + A &= 0x1FE; + + RawRegs[A >> 1] = V; + + SS_DBGTI(SS_DBG_VDP2_REGW, "[VDP2] Register write 0x%03x: 0x%04x", A, V); + + switch(A) + { + default: +// SS_DBGTI(SS_DBG_WARNING | SS_DBG_VDP2, "[VDP2] Unknown write to register at 0x%08x of value 0x%04x", A, V); + break; + + case 0x00: + Update(SH7095_mem_timestamp); + // + DisplayOn = (V >> 15) & 0x1; + BorderMode = (V >> 8) & 0x1; + InterlaceMode = (V >> 6) & 0x3; + VRes = (V >> 4) & 0x3; + HRes = (V >> 0) & 0x7; + // + InternalVB |= !DisplayOn; + // + SS_SetEventNT(&events[SS_EVENT_VDP2], Update(SH7095_mem_timestamp)); + break; + + case 0x02: + ExLatchEnable = (V >> 9) & 0x1; + ExSyncEnable = (V >> 8) & 0x1; + + DispAreaSelect = (V >> 1) & 0x1; + ExBGEnable = (V >> 0) & 0x1; + break; + + case 0x06: + VRAMSize = (V >> 15) & 0x1; + + if(VRAMSize) + SS_DBGTI(SS_DBG_WARNING | SS_DBG_VDP2, "[VDP2] VRAMSize=%d (unemulated)", VRAMSize); + break; + + case 0x0E: + RAMCTL_Raw = V & 0xB3FF; + CRAM_Mode = (V >> 12) & 0x3; + break; + + case 0x10: + case 0x12: + case 0x14: + case 0x16: + case 0x18: + case 0x1A: + case 0x1C: + case 0x1E: + { + uint8* const b = &VCPRegs[(A >> 2) & 3][(A & 0x2) << 1]; + b[0] = (V >> 12) & 0xF; + b[1] = (V >> 8) & 0xF; + b[2] = (V >> 4) & 0xF; + b[3] = (V >> 0) & 0xF; + } + break; + + case 0x20: + BGON = V & 0x1F3F; + break; + + case 0xB2: + RPRCTL[0] = (V >> 0) & 0x7; + RPRCTL[1] = (V >> 8) & 0x7; + break; + + case 0xB6: + KTAOF[0] = (V >> 0) & 0x7; + KTAOF[1] = (V >> 8) & 0x7; + break; + + case 0xBC: + RPTA = (RPTA & 0xFFFF) | ((V & 0x7) << 16); + break; + + case 0xBE: + RPTA = (RPTA & ~0xFFFF) | (V & 0xFFFE); + break; + } +} + +static INLINE uint16 RegsRead(uint32 A) +{ + switch(A & 0x1FE) + { + default: + SS_DBGTI(SS_DBG_WARNING | SS_DBG_VDP2, "[VDP2] Unknown read from 0x%08x", A); + return 0; + + case 0x00: + return (DisplayOn << 15) | (BorderMode << 8) | (InterlaceMode << 6) | (VRes << 4) | (HRes << 0); + + case 0x02: + if(!ExLatchEnable) + { + SS_SetEventNT(&events[SS_EVENT_VDP2], Update(SH7095_mem_timestamp)); + LatchHV(); + } + return (ExLatchEnable << 9) | (ExSyncEnable << 8) | (DispAreaSelect << 1) | (ExBGEnable << 0); + + case 0x04: + SS_SetEventNT(&events[SS_EVENT_VDP2], Update(SH7095_mem_timestamp)); + { + // TODO: EXSYFG + uint16 ret = (HVIsExLatched << 9) | (InternalVB << 3) | ((HPhase > HPHASE_ACTIVE) << 2) | (Odd << 1) | (PAL << 0); + + HVIsExLatched = false; + + return ret; + } + + case 0x06: + return VRAMSize << 15; + + case 0x08: + return Latched_HCNT; + + case 0x0A: + return Latched_VCNT; + + case 0x0E: + return RAMCTL_Raw; + } +} + +template +static INLINE uint32 RW(uint32 A, uint16* DB) +{ + static_assert(IsWrite || sizeof(T) == 2, "Wrong type for read."); + + A &= 0x1FFFFF; + + // + // VRAM + // + if(A < 0x100000) + { + const size_t vri = (A & 0x7FFFF) >> 1; + + if(IsWrite) + { + const unsigned mask = (sizeof(T) == 2) ? 0xFFFF : (0xFF00 >> ((A & 1) << 3)); + + VRAM[vri] = (VRAM[vri] &~ mask) | (*DB & mask); + } + else + *DB = VRAM[vri]; + + return VRAMPenalty[vri >> 16]; + } + + // + // CRAM + // + if(A < 0x180000) + { + const unsigned cri = (A & 0xFFF) >> 1; + + if(IsWrite) + { + switch(CRAM_Mode) + { + case CRAM_MODE_RGB555_1024: + (CRAM + 0x000)[cri & 0x3FF] = *DB; + (CRAM + 0x400)[cri & 0x3FF] = *DB; + break; + + case CRAM_MODE_RGB555_2048: + CRAM[cri] = *DB; + break; + + case CRAM_MODE_RGB888_1024: + case CRAM_MODE_ILLEGAL: + default: + CRAM[((cri >> 1) & 0x3FF) | ((cri & 1) << 10)] = *DB; + break; + } + } + else + { + switch(CRAM_Mode) + { + case CRAM_MODE_RGB555_1024: + case CRAM_MODE_RGB555_2048: + *DB = CRAM[cri]; + break; + + case CRAM_MODE_RGB888_1024: + case CRAM_MODE_ILLEGAL: + default: + *DB = CRAM[((cri >> 1) & 0x3FF) | ((cri & 1) << 10)]; + break; + } + } + + return 0; + } + + // + // Registers + // + if(A < 0x1C0000) + { + if(IsWrite) + { + if(sizeof(T) == 1) + SS_DBGTI(SS_DBG_WARNING | SS_DBG_VDP2, "[VDP2] Byte-write to register at 0x%08x(DB=0x%04x)", A, *DB); + + RegsWrite(A, *DB); + } + else + *DB = RegsRead(A); + + return 0; + } + + if(IsWrite) + { + //SS_DBGTI(SS_DBG_WARNING | SS_DBG_VDP2, "[VDP2] Unknown %zu-byte write to 0x%08x(DB=0x%04x)", sizeof(T), A, *DB); + } + else + { + //SS_DBGTI(SS_DBG_WARNING | SS_DBG_VDP2, "[VDP2] Unknown %zu-byte read from 0x%08x", sizeof(T), A); + *DB = 0; + } + + return 0; +} + +uint16 Read16_DB(uint32 A) +{ + uint16 DB; + + RW(A, &DB); + + return DB; +} + + +uint32 Write8_DB(uint32 A, uint16 DB) +{ + VDP2REND_Write8_DB(A, DB); + + return RW(A, &DB); +} + +uint32 Write16_DB(uint32 A, uint16 DB) +{ + VDP2REND_Write16_DB(A, DB); + + return RW(A, &DB); +} + + +// +// +// + +void AdjustTS(const int32 delta) +{ + lastts += delta; +} + + +void Init(const bool IsPAL) +{ + SurfInterlaceField = -1; + PAL = IsPAL; + lastts = 0; + + SS_SetPhysMemMap(0x05E00000, 0x05EFFFFF, VRAM, 0x80000, true); + AddMemoryDomain("VDP2 Ram", VRAM, sizeof(VRAM), MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_WORDSIZE2); + AddMemoryDomain("VDP2 CRam", CRAM, sizeof(CRAM), MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_WORDSIZE2); + + VDP2REND_Init(IsPAL); +} + +void Reset(bool powering_up) +{ + DisplayOn = false; + BorderMode = false; + ExLatchEnable = false; + ExSyncEnable = false; + ExBGEnable = false; + DispAreaSelect = false; + HRes = 0; + VRes = 0; + InterlaceMode = 0; + + VRAMSize = 0; + + InternalVB = true; + Out_VB = false; + VPhase = VPHASE_ACTIVE; + VCounter = 0; + Odd = true; + + RAMCTL_Raw = 0; + CRAM_Mode = 0; + + BGON = 0; + + memset(VCPRegs, 0, sizeof(VCPRegs)); + + for(unsigned i = 0; i < 2; i++) + { + KTAOF[i] = 0; + RPRCTL[i] = 0; + } + RPTA = 0; + memset(RotParams, 0, sizeof(RotParams)); + + // + // FIXME(init values), also in VDP2REND. + if(powering_up) + { + memset(VRAM, 0, sizeof(VRAM)); + memset(CRAM, 0, sizeof(CRAM)); + } + // + RecalcVRAMPenalty(); + // + // + VDP2REND_Reset(powering_up); +} + +// +// +// +// +uint32 GetRegister(const unsigned id, char* const special, const uint32 special_len) +{ + uint32 ret = 0xDEADBEEF; + + switch(id) + { + case GSREG_LINE: + ret = VCounter; + break; + + case GSREG_DON: + ret = DisplayOn; + break; + + case GSREG_BM: + ret = BorderMode; + break; + + case GSREG_IM: + ret = InterlaceMode; + break; + + case GSREG_VRES: + ret = VRes; + break; + + case GSREG_HRES: + ret = HRes; + break; + } + + return ret; +} + +void SetRegister(const unsigned id, const uint32 value) +{ + +} + +uint8 PeekVRAM(const uint32 addr) +{ + return ne16_rbo_be(VRAM, addr & 0x7FFFF); +} + +void PokeVRAM(const uint32 addr, const uint8 val) +{ + ne16_wbo_be(VRAM, addr & 0x7FFFF, val); + //VDP2REND_Write8_DB(addr, val << (((A & 1) ^ 1) << 3)); +} + +void SetLayerEnableMask(uint64 mask) +{ + VDP2REND_SetLayerEnableMask(mask); +} + +/*void MakeDump(const std::string& path) +{ + FileStream fp(path, FileStream::MODE_WRITE); + + fp.print_format(" { "); + for(unsigned i = 0; i < 0x100; i++) + fp.print_format("0x%04x, ", RawRegs[i]); + fp.print_format(" }, \n"); + + fp.print_format(" { "); + for(unsigned i = 0; i < 2048; i++) + fp.print_format("0x%04x, ", CRAM[i]); + fp.print_format(" }, \n"); + + fp.print_format(" { "); + for(unsigned i = 0; i < 0x40000; i++) + fp.print_format("0x%04x, ", VRAM[i]); + fp.print_format(" }, \n"); + + fp.close(); +}*/ + +} + +} diff --git a/waterbox/ss/vdp2.h b/waterbox/ss/vdp2.h new file mode 100644 index 0000000000..793fe1a90a --- /dev/null +++ b/waterbox/ss/vdp2.h @@ -0,0 +1,69 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* vdp2.h: +** Copyright (C) 2015-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_VDP2_H +#define __MDFN_SS_VDP2_H + +namespace MDFN_IEN_SS +{ +namespace VDP2 +{ + +uint32 Write8_DB(uint32 A, uint16 DB) MDFN_HOT; +uint32 Write16_DB(uint32 A, uint16 DB) MDFN_HOT; +uint16 Read16_DB(uint32 A) MDFN_HOT; + +void Init(const bool IsPAL) MDFN_COLD; + +void Reset(bool powering_up) MDFN_COLD; +void SetLayerEnableMask(uint64 mask) MDFN_COLD; + +sscpu_timestamp_t Update(sscpu_timestamp_t timestamp); +void AdjustTS(const int32 delta); + +void StartFrame(EmulateSpecStruct* espec, const bool clock28m); + +INLINE bool GetVBOut(void) { extern bool VBOut; return VBOut; } +INLINE bool GetHBOut(void) { extern bool HBOut; return HBOut; } + +// +// +enum +{ + GSREG_LINE = 0, + GSREG_DON, + GSREG_BM, + GSREG_IM, + GSREG_VRES, + GSREG_HRES +}; + +uint32 GetRegister(const unsigned id, char* const special, const uint32 special_len); +void SetRegister(const unsigned id, const uint32 value); +uint8 PeekVRAM(const uint32 addr); +void PokeVRAM(const uint32 addr, const uint8 val); +void MakeDump(const std::string& path) MDFN_COLD; + +INLINE uint32 PeekLine(void) { extern int32 VCounter; return VCounter; } +INLINE uint32 PeekHPos(void) { extern int32 HCounter; return HCounter; } +} +} +#endif diff --git a/waterbox/ss/vdp2_common.h b/waterbox/ss/vdp2_common.h new file mode 100644 index 0000000000..c71b4e09e5 --- /dev/null +++ b/waterbox/ss/vdp2_common.h @@ -0,0 +1,30 @@ +#ifndef __MDFN_SS_VDP2_COMMON_H +#define __MDFN_SS_VDP2_COMMON_H + +enum +{ + RDBS_UNUSED = 0x0, + RDBS_COEFF = 0x1, + RDBS_NAME = 0x2, + RDBS_CHAR = 0x3 +}; + +enum +{ + VCP_NBG0_NT = 0x0, + VCP_NBG1_NT = 0x1, + VCP_NBG2_NT = 0x2, + VCP_NBG3_NT = 0x3, + + VCP_NBG0_CG = 0x4, + VCP_NBG1_CG = 0x5, + VCP_NBG2_CG = 0x6, + VCP_NBG3_CG = 0x7, + + VCP_NBG0_VCS = 0xC, + VCP_NBG1_VCS = 0xD, + VCP_CPU = 0xE, + VCP_NOP = 0xF +}; + +#endif diff --git a/waterbox/ss/vdp2_render.cpp b/waterbox/ss/vdp2_render.cpp new file mode 100644 index 0000000000..14112a63a3 --- /dev/null +++ b/waterbox/ss/vdp2_render.cpp @@ -0,0 +1,3353 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* vdp2_render.cpp - VDP2 Rendering +** Copyright (C) 2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +// TODO: 31KHz monitor mode. +// When implementing GetRegister(), remember RPRCTL and window x start and end registers can +// change outside of direct register writes +// Ignore T4-T7 in hires and 31KHz monitor mode. + +#include "ss.h" +// #include +#include "vdp2_common.h" +#include "vdp2_render.h" + +#include +#include +#include + +// "Array" is a bit of a misnomer, but it helps avoid confusion with memset() semantics hopefully. +static INLINE void MDFN_FastArraySet(uint64* const dst, const uint64 value, const size_t count) +{ + #if defined(ARCH_X86) && defined(__x86_64__) + { + uint32 dummy_output0, dummy_output1; + + asm volatile( + "cld\n\t" + "rep stosq\n\t" + : "=D" (dummy_output0), "=c" (dummy_output1) + : "a" (value), "D" (dst), "c" (count) + : "cc", "memory"); + } + #else + + for(uint64 *ai = dst; MDFN_LIKELY(ai != (dst + count)); ai++) + MDFN_ennsb(ai, value); + + #endif +} + +static INLINE void MDFN_FastArraySet(uint32* const dst, const uint32 value, const size_t count) +{ + #if defined(ARCH_X86) && !defined(__x86_64__) + { + uint32 dummy_output0, dummy_output1; + + asm volatile( + "cld\n\t" + "rep stosl\n\t" + : "=D" (dummy_output0), "=c" (dummy_output1) + : "a" (value), "D" (dst), "c"(count) + : "cc", "memory"); + + return; + } + #else + if(0 == ((uintptr_t)dst & (sizeof(uint64) - 1)) && !(count & 1)) + MDFN_FastArraySet((uint64*)dst, value | ((uint64)value << 32), count >> 1); + else + { + for(uint32 *ai = dst; MDFN_LIKELY(ai != (dst + count)); ai++) + MDFN_ennsb(ai, value); + } + #endif +} + +static INLINE void MDFN_FastArraySet(uint16* const dst, const uint16 value, const size_t count) +{ + if(0 == ((uintptr_t)dst & (sizeof(uint32) - 1)) && !(count & 1)) + MDFN_FastArraySet((uint32*)dst, value | (value << 16), count >> 1); + else + { + for(uint16 *ai = dst; MDFN_LIKELY(ai != (dst + count)); ai++) + MDFN_ennsb(ai, value); + } +} + +static INLINE void MDFN_FastArraySet(uint8* const dst, const uint16 value, const size_t count) +{ + if(0 == ((uintptr_t)dst & (sizeof(uint16) - 1)) && !(count & 1)) + MDFN_FastArraySet((uint16*)dst, value | (value << 8), count >> 1); + else + { + for(uint8 *ai = dst; MDFN_LIKELY(ai != (dst + count)); ai++) + *ai = value; + } +} + +namespace MDFN_IEN_SS +{ +//uint8 vdp2rend_prepad_bss + +static EmulateSpecStruct* espec = NULL; +static bool PAL; +bool CorrectAspect; +bool ShowHOverscan; +bool DoHBlend; +int LineVisFirst, LineVisLast; +static uint32 OutLineCounter; +static bool Clock28M; +static unsigned VisibleLines; +static VDP2Rend_LIB LIB[256]; +static uint16 VRAM[262144]; +static uint16 CRAM[2048]; + +static uint8 HRes, VRes; +static bool BorderMode; +static uint8 InterlaceMode; +enum { IM_NONE, IM_ILLEGAL, IM_SINGLE, IM_DOUBLE }; + +static bool CRKTE; +static uint8 CRAM_Mode; +enum +{ + CRAM_MODE_RGB555_1024 = 0, + CRAM_MODE_RGB555_2048 = 1, + CRAM_MODE_RGB888_1024 = 2, + CRAM_MODE_ILLEGAL = 3 +}; +static uint8 VRAM_Mode; +static uint8 RDBS_Mode; + +static uint8 VCPRegs[4][8]; +static const uint16 DummyTileNT[8 * 8 * 4 / sizeof(uint16)] = { 0 }; + +static uint32 UserLayerEnableMask; +// +// +// +static uint16 BGON; +static uint16 MZCTL; +static uint8 MosaicVCount; + +static uint8 SFSEL; +static uint16 SFCODE; + +static uint16 CHCTLA; +static uint16 CHCTLB; + +static uint16 BMPNA; +static uint8 BMPNB; + +static uint16 PNCN[4]; +static uint16 PNCNR; + +static uint16 PLSZ; +static uint16 MPOFN; +static uint16 MPOFR; + +static uint8 MapRegs[4][4]; +static uint8 RotMapRegs[2][16]; +// +static uint16 XScrollI[4], YScrollI[4]; +static uint8 XScrollF[2], YScrollF[2]; + +static uint16 ZMCTL; +static uint16 SCRCTL; +static uint32 LineScrollAddr[2]; +static uint32 VCScrollAddr; +static uint32 VCLast[2]; + +static uint16 XCoordInc[2], YCoordInc[2]; +static uint32 YCoordAccum[2]; +static uint32 MosEff_YCoordAccum[2]; + +static uint32 CurXScrollIF[2]; +static uint32 CurYScrollIF[2]; +static uint16 CurXCoordInc[2]; +static uint32 CurLSA[2]; + +static uint16 NBG23_YCounter[2]; +static uint16 MosEff_NBG23_YCounter[2]; +// +static uint8 RPMD; +static uint8 KTCTL[2]; +static uint16 OVPNR[2]; +// +static uint32 BKTA; +static uint32 CurBackTabAddr; +static uint16 CurBackColor; + +static uint32 LCTA; +static uint32 CurLCTabAddr; +static uint16 CurLCColor; + +static uint8 LineColorEn; + +static uint16 SFPRMD; +static uint16 CCCTL; +static uint16 SFCCMD; +// +static uint8 NBGPrioNum[4]; +static uint8 RBG0PrioNum; + +static uint8 NBGCCRatio[4]; +static uint8 RBG0CCRatio; +static uint8 LineColorCCRatio; +static uint8 BackCCRatio; + +// +static struct +{ + uint16 XStart, XEnd; + uint16 YStart, YEnd; + uint32 LineWinAddr; + bool LineWinEn; + // + bool YMet; + uint16 CurXStart, CurXEnd; + uint32 CurLineWinAddr; +} Window[2]; + +static uint8 WinControl[8]; +enum +{ + WINLAYER_NBG0 = 0, + WINLAYER_NBG1 = 1, + WINLAYER_NBG2 = 2, + WINLAYER_NBG3 = 3, + WINLAYER_RBG0 = 4, + WINLAYER_SPRITE = 5, + WINLAYER_ROTPARAM = 6, + WINLAYER_CC = 7, +}; + +static std::array WinPieces; +// +static uint8 SpriteCCCond; +static uint8 SpriteCCNum; +static uint8 SPCTL_Low; + +static uint16 SDCTL; + +static uint8 SpritePrioNum[8]; +static uint8 SpriteCCRatio[8]; + +static uint8 SpriteCCLUT[8]; // Temp optimization data +static uint8 SpriteCC3Mask; // Temp optimization data + +// +static uint8 CRAMAddrOffs_NBG[4]; +static uint8 CRAMAddrOffs_RBG0; +static uint8 CRAMAddrOffs_Sprite; +// +static uint8 ColorOffsEn; +static uint8 ColorOffsSel; + +//enum +//{ +// COLOFFS_ENSEL_NBG0 = 0, +// COLOFFS_ENSEL_NBG1 = 0, +//}; + +static int32 ColorOffs[2][3]; // [A,B] [R << 0, G << 8, B << 16] + +template +struct TileFetcher +{ + unsigned CRAOffs; + + bool BMSCC; + bool BMSPR; + unsigned BMPalNo; + unsigned BMSize; + + unsigned PlaneSize; + unsigned PlaneOver; + uint16 PlaneOverChar; + bool PNDSize; + bool CharSize; + bool AuxMode; + unsigned Supp; + + // + // + // + unsigned BMOffset; + unsigned BMWShift; + unsigned BMWMask; + unsigned BMHMask; + + uint32 adj_map_regs[IsRot ? 16 : 4]; + uint32 doxm, doym; + + bool nt_ok[4]; + bool cg_ok[4]; + + // n=0...3, NBG0...3 + // n=4, RBG0 + // n=5, RBG1 + INLINE void Start(const unsigned n, const bool bmen, const unsigned map_offset, const uint8* map_regs) + { + BMOffset = map_offset << 16; + BMWShift = ((BMSize & 2) ? 10 : 9); + BMWMask = (1U << BMWShift) - 8; + BMHMask = (BMSize & 1) ? 0x1FF : 0xFF; + + const unsigned psshift = (13 - PNDSize - (CharSize << 1)); + + for(unsigned i = 0; i < (IsRot ? 16 : 4); i++) + { + adj_map_regs[i] = ((map_offset << 6) + (map_regs[i] &~ PlaneSize)) << psshift; + } + + if(IsRot) + { + if(bmen) + { + doxm = ~(BMWMask + 7); + doym = ~BMHMask; + } + else + { + doxm = ~((1U << ((9 + (bool)(PlaneSize & 0x1)) + (IsRot ? 2 : 1))) - 1); + doym = ~((1U << ((9 + (bool)(PlaneSize & 0x2)) + (IsRot ? 2 : 1))) - 1); + } + + if(PlaneOver == 0) + doxm = doym = 0; + else if(PlaneOver == 3) + doxm = doym = ~511; + } + + // Kludgeyness: + for(unsigned bank = 0; bank < 4; bank++) + { + const unsigned esb = bank & (2 | ((VRAM_Mode >> (bank >> 1)) & 1)); + const uint8 rdbs = (RDBS_Mode >> (esb << 1)) & 0x3; + + if(IsRot) + { + if(!(BGON & 0x20) || n == 4) + { + nt_ok[bank] = (rdbs == RDBS_NAME) && (bank < 2 || !(BGON & 0x20)); + cg_ok[bank] = (rdbs == RDBS_CHAR) && (bank < 2 || !(BGON & 0x20)); + } + else + { + nt_ok[bank] = (bank == 3); + cg_ok[bank] = (bank == 2); + } + } + else + { + nt_ok[bank] = false; + cg_ok[bank] = false; + + if(!(BGON & 0x30) || rdbs == RDBS_UNUSED) + { + for(unsigned ac = 0; ac < ((HRes & 0x6) ? 4 : 8); ac++) + { + if(VCPRegs[esb][ac] == (VCP_NBG0_CG + n)) + cg_ok[bank] = true; + + if(VCPRegs[esb][ac] == (VCP_NBG0_NT + n)) + nt_ok[bank] = true; + } + } + } + } + + #if 1 + pcco = 0; + spr = false; + scc = false; + tile_vrb = nullptr; + cellx_xor = 0; + #endif + } + + // + // + // + uint32 pcco; + bool spr; + bool scc; + const uint16* tile_vrb; + uint32 cellx_xor; + + template + INLINE bool Fetch(const bool bmen, const uint32 ix, const uint32 iy) + { + size_t cg_addr; + uint32 palno; + bool is_outside = false; + + if(IsRot) + is_outside = (ix & doxm) | (iy & doym); + + if(bmen) + { + palno = BMPalNo; + spr = BMSPR; + scc = BMSCC; + cellx_xor = (ix &~ 0x7); + cg_addr = (BMOffset + ((((ix & BMWMask) + ((iy & BMHMask) << BMWShift)) * TA_bpp) >> 4)) & 0x3FFFF; + } + else + { + bool vflip, hflip; + uint16 charno; + uint32 mapidx, planeidx, planeoffs, pageoffs; + const uint16* pnd; + uint32 celly; + size_t nt_addr; + + if(IsRot) + mapidx = ((ix >> (9 + (bool)(PlaneSize & 0x1))) & 0x3) | ((iy >> (9 + (bool)(PlaneSize & 0x2) - 2)) & 0xC); + else + mapidx = ((ix >> (9 + (bool)(PlaneSize & 0x1))) & 0x1) | ((iy >> (9 + (bool)(PlaneSize & 0x2) - 1)) & 0x2); + + planeidx = ((ix >> 9) & PlaneSize & 0x1) | ((iy >> (9 - 1)) & PlaneSize & 0x2); + planeoffs = planeidx << (13 - PNDSize - (CharSize << 1)); + pageoffs = ((((ix >> 3) & 0x3F) >> CharSize) + ((((iy >> 3) & 0x3F) >> CharSize) << (6 - CharSize))) << (1 - PNDSize); + nt_addr = (adj_map_regs[mapidx] + planeoffs + pageoffs) & 0x3FFFF; + + pnd = &VRAM[nt_addr]; + if(!nt_ok[nt_addr >> 16]) + pnd = DummyTileNT; + + if(IsRot && is_outside && PlaneOver == 1) + { + pnd = &PlaneOverChar; + goto OverCharCase; + } + + if(!PNDSize) + { + uint16 tmp = pnd[0]; + + palno = tmp & 0x7F; + vflip = (bool)(tmp & 0x8000); + hflip = (bool)(tmp & 0x4000); + spr = (bool)(tmp & 0x2000); + scc = (bool)(tmp & 0x1000); + charno = pnd[1] & 0x7FFF; + } + else + { + OverCharCase:; + uint16 tmp = pnd[0]; + + if(TA_bpp >= 8) + palno = ((tmp >> 12) & 0x7) << 4; + else + palno = ((tmp >> 12) & 0xF) | (((Supp >> 5) & 0x7) << 4); + spr = (bool)(Supp & 0x200); + scc = (bool)(Supp & 0x100); + + if(!AuxMode) + { + vflip = (bool)(tmp & 0x800); + hflip = (bool)(tmp & 0x400); + + if(CharSize) + charno = ((tmp & 0x3FF) << 2) + ((Supp & 0x1C) << 10) + (Supp & 0x3); + else + charno = (tmp & 0x3FF) + ((Supp & 0x1F) << 10); + } + else + { + hflip = vflip = false; + + if(CharSize) + charno = ((tmp & 0xFFF) << 2) + ((Supp & 0x10) << 10) + (Supp & 0x3); + else + charno = (tmp & 0xFFF) + ((Supp & 0x1C) << 10); + } + } + + if(CharSize) + { + uint32 cidx = (((ix >> 3) ^ hflip) & 0x1) + (((iy >> 2) ^ (vflip << 1)) & 0x2); + charno = (charno + cidx * (TA_bpp >> 2)) & 0x7FFF; + } + + cellx_xor = (ix &~ 0x7) | (hflip ? 0x7 : 0x0); + celly = (iy & 0x7) ^ (vflip ? 0x7 : 0); + cg_addr = ((charno << 4) + ((celly * TA_bpp) >> 1)) & 0x3FFFF; + } + tile_vrb = &VRAM[cg_addr]; + + if(!cg_ok[cg_addr >> 16]) + { + //printf("Goop: %08zx, %d %02x, %016llx %016llx %016llx %016llx\n", cg_addr, TA_bpp, VRAM_Mode, MDFN_de64lsb(VCPRegs[0]), MDFN_de64lsb(VCPRegs[1]), MDFN_de64lsb(VCPRegs[2]), MDFN_de64lsb(VCPRegs[3])); + tile_vrb = DummyTileNT; + } + + // + // + // + pcco = ((palno << 4) &~ ((1U << (TA_bpp & 0x1F)) - 1)) + CRAOffs; + + return IsRot && is_outside && (PlaneOver & 2); + } +}; + +struct RotVars +{ + int32 Xsp, Ysp;// .10 + int32 Xp, Yp; // .10 + int32 dX, dY; // .10 + + int32 kx, ky; // .16 + + bool use_coeff; + uint32 base_coeff; + + TileFetcher tf; +}; + +static struct +{ + uint64 spr[704]; + uint64 rbg0[704]; + union + { + uint64 nbg[4][8 + 704 + 8]; + struct + { + uint8 dummy[sizeof(nbg) / 2]; + uint16 vcscr[2][88 + 1 + 1]; // + 1 for fine x scroll != 0, + 1 for pointer shenanigans in FetchVCScroll + }; + struct + { + uint8 rotdummy[sizeof(nbg) / 4]; + uint8 rotabsel[352]; // Also used as a scratch buffer in T_DrawRBG() to handle mosaic-related junk. + RotVars rotv[2]; + uint32 rotcoeff[352]; + }; + }; + alignas(16) uint8 lc[704]; +} LB; + +// ColorOffsEn, etc. ?...hmm, discrepancy with ColorCalcEn and LineColorEn... +enum +{ + LAYER_NBG0 = 0, + //LAYER_RBG1 = 0, + LAYER_NBG1 = 1, + //LAYER_EXBG = 1, + LAYER_NBG2 = 2, + LAYER_NBG3 = 3, + + LAYER_RBG0 = 4, + LAYER_BACK = 5, // Line color? + LAYER_SPRITE = 6, +}; + +// +// +// +static uint32 ColorCache[2048]; +static void CacheCRE(const unsigned cri) +{ + if(CRAM_Mode & CRAM_MODE_RGB888_1024) + { + (ColorCache + 0x000)[cri >> 1] = (ColorCache + 0x400)[cri >> 1] = (((CRAM + 0x000)[(cri >> 1) & 0x3FF] & 0x80FF) << 16) | ((CRAM + 0x400)[(cri >> 1) & 0x3FF] << 0); + } + else + { + const uint16 t = CRAM[cri & ((CRAM_Mode == CRAM_MODE_RGB555_1024) ? 0x3FF : 0x7FF)]; + const uint32 col = ((t << 3) & 0xF8) | ((t << 6) & 0xF800) | ((t << 9) & 0xF80000) | ((t << 16) & 0x80000000); + + if(CRAM_Mode == CRAM_MODE_RGB555_1024) + (ColorCache + 0x000)[cri & 0x3FF] = (ColorCache + 0x400)[cri & 0x3FF] = col; + else + ColorCache[cri] = col; + } +} + +static void RecalcColorCache(void) +{ + if(CRAM_Mode & CRAM_MODE_RGB888_1024) + { + for(unsigned i = 0; i < 2048; i += 2) + CacheCRE(i); + } + else + { + const unsigned count = (CRAM_Mode == CRAM_MODE_RGB555_2048) ? 2048 : 1024; + + for(unsigned i = 0; i < count; i++) + CacheCRE(i); + } +} + +// +// Register writes seem to always be 16-bit +// +static INLINE void RegsWrite(uint32 A, uint16 V) +{ + A &= 0x1FE; + + switch(A) + { + default: + break; + + case 0x00: + //DisplayOn = (V >> 15) & 0x1; + BorderMode = (V >> 8) & 0x1; + InterlaceMode = (V >> 6) & 0x3; + VRes = (V >> 4) & 0x3; + HRes = (V >> 0) & 0x7; + break; + + case 0x02: + //ExLatchEnable = (V >> 9) & 0x1; + //ExSyncEnable = (V >> 8) & 0x1; + + //DispAreaSelect = (V >> 1) & 0x1; + //ExBGEnable = (V >> 0) & 0x1; + break; + + case 0x0E: + { + const unsigned old_CRAM_Mode = CRAM_Mode; + + CRKTE = (V >> 15) & 0x1; + CRAM_Mode = (V >> 12) & 0x3;; + VRAM_Mode = (V >> 8) & 0x3; + RDBS_Mode = V & 0xFF; + + if(old_CRAM_Mode != CRAM_Mode) + RecalcColorCache(); + } + break; + // + case 0x10: + case 0x12: + case 0x14: + case 0x16: + case 0x18: + case 0x1A: + case 0x1C: + case 0x1E: + { + uint8* const b = &VCPRegs[(A >> 2) & 3][(A & 0x2) << 1]; + b[0] = (V >> 12) & 0xF; + b[1] = (V >> 8) & 0xF; + b[2] = (V >> 4) & 0xF; + b[3] = (V >> 0) & 0xF; + } + break; + // + case 0x20: + BGON = V & 0x1F3F; + break; + + case 0x22: + MZCTL = V & 0xFF1F; + break; + + case 0x24: + SFSEL = V & 0x1F; + break; + + case 0x26: + SFCODE = V; + break; + + case 0x28: + CHCTLA = V & 0x3F7F; + break; + + case 0x2A: + CHCTLB = V & 0x7733; + break; + + case 0x2C: + BMPNA = V & 0x3737; + break; + + case 0x2E: + BMPNB = V & 0x37; + break; + + // + case 0x30: + case 0x32: + case 0x34: + case 0x36: + PNCN[(A & 0x6) >> 1] = V & 0xC3FF; + break; + + case 0x38: + PNCNR = V & 0xC3FF; + break; + + // + case 0x3A: + PLSZ = V; // Plane size + break; + + case 0x3C: + MPOFN = V & 0x7777; // Map offset NBG + break; + + case 0x3E: + MPOFR = V & 0x0077; // Map offset RBG + break; + // + case 0x40: + case 0x42: + case 0x44: + case 0x46: + case 0x48: + case 0x4A: + case 0x4C: + case 0x4E: + MapRegs[(A & 0xC) >> 2][(A & 0x2) + 0] = (V >> 0) & 0x3F; + MapRegs[(A & 0xC) >> 2][(A & 0x2) + 1] = (V >> 8) & 0x3F; + break; + + case 0x50: case 0x52: case 0x54: case 0x56: case 0x58: case 0x5A: case 0x5C: case 0x5E: + case 0x60: case 0x62: case 0x64: case 0x66: case 0x68: case 0x6A: case 0x6C: case 0x6E: + RotMapRegs[(bool)(A & 0x20)][(A & 0xE) + 0] = (V >> 0) & 0x3F; + RotMapRegs[(bool)(A & 0x20)][(A & 0xE) + 1] = (V >> 8) & 0x3F; + break; + // + case 0x70: + case 0x80: + XScrollI[A >> 7] = V & 0x7FF; + break; + + case 0x72: + case 0x82: + XScrollF[A >> 7] = (V >> 8) & 0xFF; + break; + + case 0x74: + case 0x84: + YScrollI[A >> 7] = V & 0x7FF; + break; + + case 0x76: + case 0x86: + YScrollF[A >> 7] = (V >> 8) & 0xFF; + break; + + case 0x78: + case 0x88: + XCoordInc[A >> 7] = (XCoordInc[A >> 7] & 0xFF) | ((V & 0x7) << 8); + break; + + case 0x7A: + case 0x8A: + XCoordInc[A >> 7] = (XCoordInc[A >> 7] & 0x700) | ((V >> 8) & 0xFF); + break; + + case 0x7C: + case 0x8C: + YCoordInc[A >> 7] = (YCoordInc[A >> 7] & 0xFF) | ((V & 0x7) << 8); + break; + + case 0x7E: + case 0x8E: + YCoordInc[A >> 7] = (YCoordInc[A >> 7] & 0x700) | ((V >> 8) & 0xFF); + break; + + case 0x90: + case 0x94: + XScrollI[2 + (bool)(A & 0x4)] = V & 0x7FF; + break; + + case 0x92: + case 0x96: + { + const unsigned which = (bool)(A & 0x4); + + NBG23_YCounter[which] = YScrollI[2 + which] = V & 0x7FF; + } + break; + + case 0x98: + ZMCTL = V & 0x0303; + break; + + case 0x9A: + SCRCTL = V & 0x3F3F; + break; + + case 0x9C: + VCScrollAddr = (VCScrollAddr & 0xFFFF) | ((V & 0x7) << 16); + break; + + case 0x9E: + VCScrollAddr = (VCScrollAddr & 0x70000) | (V & 0xFFFE); + break; + + case 0xA0: + LineScrollAddr[0] = (LineScrollAddr[0] & 0xFFFF) | ((V & 0x7) << 16); + break; + + case 0xA2: + LineScrollAddr[0] = (LineScrollAddr[0] & 0x70000) | (V & 0xFFFE); + break; + + case 0xA4: + LineScrollAddr[1] = (LineScrollAddr[1] & 0xFFFF) | ((V & 0x7) << 16); + break; + + case 0xA6: + LineScrollAddr[1] = (LineScrollAddr[1] & 0x70000) | (V & 0xFFFE); + break; + + // + case 0xA8: + LCTA = (LCTA & 0xFFFF) | ((V & 0x8007) << 16); + break; + + case 0xAA: + LCTA = (LCTA & ~0xFFFF) | V; + break; + + case 0xAC: + BKTA = (BKTA & 0xFFFF) | ((V & 0x8007) << 16); + break; + + case 0xAE: + BKTA = (BKTA & ~0xFFFF) | V; + break; + // + case 0xB0: + RPMD = V & 0x3; + break; + + case 0xB4: + KTCTL[0] = (V >> 0) & 0x1F; + KTCTL[1] = (V >> 8) & 0x1F; + break; + + case 0xB8: + OVPNR[0] = V; + break; + + case 0xBA: + OVPNR[1] = V; + break; + + // + case 0xC0: Window[0].XStart = V & 0x3FF; break; + case 0xC2: Window[0].YStart = V & 0x1FF; break; + case 0xC4: Window[0].XEnd = V & 0x3FF; break; + case 0xC6: Window[0].YEnd = V & 0x1FF; break; + + case 0xC8: Window[1].XStart = V & 0x3FF; break; + case 0xCA: Window[1].YStart = V & 0x1FF; break; + case 0xCC: Window[1].XEnd = V & 0x3FF; break; + case 0xCE: Window[1].YEnd = V & 0x1FF; break; + + case 0xD0: + case 0xD2: + case 0xD4: + WinControl[(A & 0x6) + 0] = (V >> 0) & 0xBF; + WinControl[(A & 0x6) + 1] = (V >> 8) & 0xBF; + break; + + case 0xD6: + WinControl[(A & 0x6) + 0] = (V >> 0) & 0x8F; // Rot + WinControl[(A & 0x6) + 1] = (V >> 8) & 0xBF; // CC + break; + + case 0xD8: + case 0xDC: + { + const unsigned w = (A & 0x4) >> 2; + + Window[w].LineWinEn = (bool)(V & 0x8000); + Window[w].LineWinAddr = (Window[w].LineWinAddr & 0xFFFF) | ((V & 0x7) << 16); + } + break; + + case 0xDA: + case 0xDE: + { + const unsigned w = (A & 0x4) >> 2; + + Window[w].LineWinAddr = (Window[w].LineWinAddr & 0x70000) | (V & 0xFFFE); + } + break; + + // + case 0xE0: + SpriteCCCond = (V >> 12) & 0x3; + SpriteCCNum = (V >> 8) & 0x7; + SPCTL_Low = V & 0x3F; + break; + + case 0xE2: + SDCTL = V & 0x13F; + break; + + case 0xE4: + CRAMAddrOffs_NBG[0] = (V >> 0) & 0x7; + CRAMAddrOffs_NBG[1] = (V >> 4) & 0x7; + CRAMAddrOffs_NBG[2] = (V >> 8) & 0x7; + CRAMAddrOffs_NBG[3] = (V >> 12) & 0x7; + break; + + case 0xE6: + CRAMAddrOffs_RBG0 = (V >> 0) & 0x7; + CRAMAddrOffs_Sprite = (V >> 4) & 0x7; + break; + + case 0xE8: + LineColorEn = V & 0x3F; + break; + + case 0xEA: + SFPRMD = V & 0x3FF; + break; + + case 0xEC: + CCCTL = V & 0xF77F; + break; + + case 0xEE: + SFCCMD = V & 0x3FF; + break; + + case 0xF0: + case 0xF2: + case 0xF4: + case 0xF6: + SpritePrioNum[(A & 0x6) + 0] = ((V >> 0) & 0x7); + SpritePrioNum[(A & 0x6) + 1] = ((V >> 8) & 0x7); + break; + + case 0xF8: + NBGPrioNum[0] = (V >> 0) & 0x7; + NBGPrioNum[1] = (V >> 8) & 0x7; + break; + + case 0xFA: + NBGPrioNum[2] = (V >> 0) & 0x7; + NBGPrioNum[3] = (V >> 8) & 0x7; + break; + + case 0xFC: + RBG0PrioNum = (V >> 0) & 0x7; + break; + + case 0x100: + case 0x102: + case 0x104: + case 0x106: + SpriteCCRatio[(A & 0x6) + 0] = (V >> 0) & 0x1F; + SpriteCCRatio[(A & 0x6) + 1] = (V >> 8) & 0x1F; + break; + + case 0x108: + case 0x10A: + NBGCCRatio[(A & 0x2) + 0] = (V >> 0) & 0x1F; + NBGCCRatio[(A & 0x2) + 1] = (V >> 8) & 0x1F; + break; + + case 0x10C: + RBG0CCRatio = V & 0x1F; + break; + + case 0x10E: + LineColorCCRatio = (V >> 0) & 0x1F; + BackCCRatio = (V >> 8) & 0x1F; + break; + + case 0x110: + ColorOffsEn = V & 0x7F; + break; + + case 0x112: + ColorOffsSel = V & 0x7F; + break; + + case 0x114: // A Red + case 0x116: // A Green + case 0x118: // A Blue + case 0x11A: // B Red + case 0x11C: // B Green + case 0x11E: // B Blue + { + const unsigned ab = (A >= 0x11A); + const unsigned wcc = ((A - 0x114) >> 1) % 3; + + ColorOffs[ab][wcc] = (uint32)sign_x_to_s32(9, V) << (wcc << 3); + } + break; + } +} + +template +static INLINE void MemW(uint32 A, const uint16 DB) +{ + A &= 0x1FFFFF; + + // + // VRAM + // + if(A < 0x100000) + { + const size_t vri = (A & 0x7FFFF) >> 1; + const unsigned mask = (sizeof(T) == 2) ? 0xFFFF : (0xFF00 >> ((A & 1) << 3)); + + VRAM[vri] = (VRAM[vri] &~ mask) | (DB & mask); + + return; + } + + // + // CRAM + // + if(A < 0x180000) + { + const unsigned cri = (A & 0xFFF) >> 1; + + switch(CRAM_Mode) + { + case CRAM_MODE_RGB555_1024: + (CRAM + 0x000)[cri & 0x3FF] = DB; + (CRAM + 0x400)[cri & 0x3FF] = DB; + CacheCRE(cri); + break; + + case CRAM_MODE_RGB555_2048: + CRAM[cri] = DB; + CacheCRE(cri); + break; + + case CRAM_MODE_RGB888_1024: + case CRAM_MODE_ILLEGAL: + default: + CRAM[((cri >> 1) & 0x3FF) | ((cri & 1) << 10)] = DB; + CacheCRE(cri); + break; + } + + return; + } + + // + // Registers + // + if(A < 0x1C0000) + { + RegsWrite(A, DB); + + return; + } +} + + +static void Reset(bool powering_up) +{ + if(powering_up) + { + memset(VRAM, 0, sizeof(VRAM)); + memset(CRAM, 0, sizeof(CRAM)); + } + // + // + CRKTE = false; + CRAM_Mode = 0; + VRAM_Mode = 0; + RDBS_Mode = 0; + HRes = 0; + VRes = 0; + BorderMode = false; + InterlaceMode = 0; + // + memset(VCPRegs, 0, sizeof(VCPRegs)); + // + BGON = 0; + MZCTL = 0; + MosaicVCount = 0; + + SFSEL = 0; + SFCODE = 0; + + CHCTLA = 0; + CHCTLB = 0; + + BMPNA = 0; + BMPNB = 0; + + for(unsigned n = 0; n < 4; n++) + PNCN[n] = 0; + + PNCNR = 0; + + PLSZ = 0; + MPOFN = 0; + MPOFR = 0; + + for(unsigned n = 0; n < 4; n++) + { + for(unsigned i = 0; i < 4; i++) + MapRegs[n][i] = 0; + } + + for(unsigned rn = 0; rn < 2; rn++) + { + for(unsigned i = 0; i < 16; i++) + RotMapRegs[rn][i] = 0; + } + + // + for(unsigned n = 0; n < 4; n++) + { + XScrollI[n] = 0; + YScrollI[n] = 0; + + if(n < 2) + { + XScrollF[n] = 0; + YScrollF[n] = 0; + + XCoordInc[n] = 0; + YCoordInc[n] = 0; + YCoordAccum[n] = 0; + MosEff_YCoordAccum[n] = 0; + } + else + { + NBG23_YCounter[n & 1] = 0; + MosEff_NBG23_YCounter[n & 1] = 0; + } + } + + ZMCTL = 0; + SCRCTL = 0; + LineScrollAddr[0] = 0; + LineScrollAddr[1] = 0; + VCScrollAddr = 0; + VCLast[0] = VCLast[1] = 0; + + for(unsigned n = 0; n < 2; n++) + { + CurXScrollIF[n] = 0; + CurYScrollIF[n] = 0; + CurLSA[n] = 0; + CurXCoordInc[n] = 0; + } + + for(unsigned n = 0; n < 4; n++) + NBGPrioNum[n] = 0; + + RBG0PrioNum = 0; + + for(unsigned n = 0; n < 4; n++) + NBGCCRatio[n] = 0; + + RBG0CCRatio = 0; + LineColorCCRatio = 0; + BackCCRatio = 0; + + for(unsigned w = 0; w < 2; w++) + { + Window[w].XStart = 0; + Window[w].XEnd = 0; + Window[w].YStart = 0; + Window[w].YEnd = 0; + Window[w].LineWinAddr = 0; + Window[w].LineWinEn = false; + + Window[w].YMet = false; + Window[w].CurXStart = 0; + Window[w].CurXEnd = 0; + Window[w].CurLineWinAddr = 0; + } + + for(unsigned i = 0; i < 8; i++) + WinControl[i] = 0; + + // + RPMD = 0; + for(unsigned i = 0; i < 2; i++) + { + KTCTL[i] = 0; + OVPNR[i] = 0; + } + // + BKTA = 0; + CurBackTabAddr = 0; + CurBackColor = 0; + + LCTA = 0; + CurLCTabAddr = 0; + CurLCColor = 0; + + LineColorEn = 0; + + SFPRMD = 0; + SFCCMD = 0; + + CCCTL = 0; + // + SpriteCCCond = 0; + SpriteCCNum = 0; + SPCTL_Low = 0; + + SDCTL = 0; + // + for(auto& spn : SpritePrioNum) + spn = 0; + // + for(auto& scr : SpriteCCRatio) + scr = 0; + // + for(auto& ao : CRAMAddrOffs_NBG) + ao = 0; + + CRAMAddrOffs_RBG0 = 0; + + CRAMAddrOffs_Sprite = 0; + // + ColorOffsEn = 0; + ColorOffsSel = 0; + + for(auto& co : ColorOffs) + for(auto& coe : co) + coe = 0; +} + +// Prio(3 bits), color calc(1 bit), layer num(3 bits), 1 bit for palette/rgb format, 1 bit for line color enable, 1 bit for color offs enable, 1 bit for color offs select +// 1 bit for line color screen enable?, 1 bit allow sprite shadow, 1 bit do sprite shadow +// Prio, color calc, layer num + +enum +{ + PIX_ISRGB_SHIFT = 0, // original format, 0 = paletted, 1 = RGB + PIX_LCE_SHIFT = 1, // Line color enable + PIX_COE_SHIFT = 2, // Color offs enable + PIX_COSEL_SHIFT = 3, // Color offset select(which color offset registers to use) + PIX_CCE_SHIFT = 4, // Color calc enable + + // + // Sprite shadow nonsense + // Keep these in this order at these bit positions + PIX_SHADEN_SHIFT = 5, // + PIX_DOSHAD_SHIFT = 6, + PIX_SELFSHAD_SHIFT = 7, + PIX_SHADHALVTEST8_VAL = 0x60, + // + // + // + // + + // 8 ... 15 + PIX_PRIO_TEST_SHIFT = 8, + PIX_PRIO_SHIFT = PIX_PRIO_TEST_SHIFT + 3, + + // + PIX_GRAD_SHIFT = 16, + PIX_LAYER_CCE_SHIFT = 17, // For extended color calculation + + // 24...31 + PIX_CCRATIO_SHIFT = 24, + + // 32 ... 55 + PIX_RGB_SHIFT = 32, + + // + PIX_SWBIT_SHIFT = 56, + + // Reminder that highest bit can be == 1 when RGB data is pulled from ColorCache + //SPECIAL_CCALC_SHIFT = 63 +}; + +static INLINE void GetCWV(const uint8 ctrl, const bool* const xmet, bool* cwv) +{ + const bool logic = (ctrl >> 7) & 1; // 0 = OR, 1 = AND + const bool w_enable[2] = { (bool)(ctrl & 0x02), (bool)(ctrl & 0x08) }; + const bool w_area[2] = { (bool)(ctrl & 0x01), (bool)(ctrl & 0x04) }; + const bool sw_enable = ctrl & 0x20; + const bool sw_area = ctrl & 0x10; + + for(unsigned swinput = 0; swinput < 2; swinput++) + { + bool wval[2]; + bool swval; + + wval[0] = (w_enable[0] ? ((xmet[0] & Window[0].YMet) ^ w_area[0]) : logic); + wval[1] = (w_enable[1] ? ((xmet[1] & Window[1].YMet) ^ w_area[1]) : logic); + + swval = sw_enable ? (swinput ^ sw_area) : logic; + + if(logic) + cwv[swinput] = wval[0] & wval[1] & swval; + else + cwv[swinput] = wval[0] | wval[1] | swval; + } +} + +static void GetWinRotAB(void) +{ + unsigned x = 0; + + for(unsigned piece = 0; piece < WinPieces.size(); piece++) + { + bool xmet[2]; + + xmet[0] = ((x >= Window[0].CurXStart) & (x <= Window[0].CurXEnd)); + xmet[1] = ((x >= Window[1].CurXStart) & (x <= Window[1].CurXEnd)); + // + // + // + bool cwv[2]; + + GetCWV(WinControl[WINLAYER_ROTPARAM], xmet, cwv); + + if(HRes & 0x2) + { + for(; MDFN_LIKELY(x < WinPieces[piece]); x += 2) + LB.rotabsel[x >> 1] = cwv[(LB.spr[x] >> PIX_SWBIT_SHIFT) & 1]; + } + else + { + for(; MDFN_LIKELY(x < WinPieces[piece]); x++) + LB.rotabsel[x] = cwv[(LB.spr[x] >> PIX_SWBIT_SHIFT) & 1]; + } + } +} + +static void ApplyWin(const unsigned wlayer, uint64* buf) +{ + unsigned x = 0; + + //printf("%d %d %d %d %d --- %d %d\n", WinPieces[0], WinPieces[1], WinPieces[2], WinPieces[3], WinPieces[4], Window[0].CurXStart, Window[0].CurXEnd); + + for(unsigned piece = 0; piece < WinPieces.size(); piece++) + { + bool xmet[2]; + + xmet[0] = ((x >= Window[0].CurXStart) & (x <= Window[0].CurXEnd)); + xmet[1] = ((x >= Window[1].CurXStart) & (x <= Window[1].CurXEnd)); + + // + // + // + bool cwv[2]; + bool cc_cwv[2]; + + GetCWV(WinControl[wlayer], xmet, cwv); + GetCWV(WinControl[WINLAYER_CC], xmet, cc_cwv); + + if(!((cwv[0] ^ cwv[1]) | (cc_cwv[0] ^ cc_cwv[1]))) // Fast path(no sprite window, or sprite window wouldn't have an effect in this piece). + { + if(cwv[0]) + { + for(; MDFN_LIKELY(x < WinPieces[piece]); x++) + buf[x] &= ~(uint64)0xFFFFFFFF; + } + else if(cc_cwv[0]) + { + for(; MDFN_LIKELY(x < WinPieces[piece]); x++) + buf[x] &= ~(uint64)(1U << PIX_CCE_SHIFT); + } + x = WinPieces[piece]; + } + else + { + uint64 masks[2]; + + for(unsigned i = 0; i < 2; i++) + { + uint64 m = ~(uint64)0; + + if(cwv[i]) + m = ~(uint64)0xFFFFFFFF; + + if(cc_cwv[i]) + m &= ~(uint64)(1U << PIX_CCE_SHIFT); + + masks[i] = m; + } + + for(; MDFN_LIKELY(x < WinPieces[piece]); x++) + { + buf[x] &= masks[(LB.spr[x] >> PIX_SWBIT_SHIFT) & 1]; + } + } + } +} + +#pragma GCC push_options +#pragma GCC optimize("no-unroll-loops,no-peel-loops,no-crossjumping") +static NO_INLINE void ApplyHMosaic(const unsigned layer, uint64* buf, const unsigned w) +{ + if(!(MZCTL & (1U << layer))) + return; + + const unsigned moz_horiz_param = ((MZCTL >> 8) & 0xF); + const unsigned moz_wmax = w - moz_horiz_param; + unsigned x = 0; + + switch(moz_horiz_param) + { + case 0x0: x = moz_wmax; break; + case 0x1: for(; x < moz_wmax; x += 0x2) { auto b = buf[x]; buf[x + 1] = b; } break; + case 0x2: for(; x < moz_wmax; x += 0x3) { auto b = buf[x]; buf[x + 1] = b; buf[x + 2] = b; } break; + case 0x3: for(; x < moz_wmax; x += 0x4) { auto b = buf[x]; buf[x + 1] = b; buf[x + 2] = b; buf[x + 3] = b; } break; + case 0x4: for(; x < moz_wmax; x += 0x5) { auto b = buf[x]; buf[x + 1] = b; buf[x + 2] = b; buf[x + 3] = b; buf[x + 4] = b; } break; + case 0x5: for(; x < moz_wmax; x += 0x6) { auto b = buf[x]; buf[x + 1] = b; buf[x + 2] = b; buf[x + 3] = b; buf[x + 4] = b; buf[x + 5] = b; } break; + case 0x6: for(; x < moz_wmax; x += 0x7) { auto b = buf[x]; buf[x + 1] = b; buf[x + 2] = b; buf[x + 3] = b; buf[x + 4] = b; buf[x + 5] = b; buf[x + 6] = b; } break; + case 0x7: for(; x < moz_wmax; x += 0x8) { auto b = buf[x]; buf[x + 1] = b; buf[x + 2] = b; buf[x + 3] = b; buf[x + 4] = b; buf[x + 5] = b; buf[x + 6] = b; buf[x + 7] = b; } break; + case 0x8: for(; x < moz_wmax; x += 0x9) { auto b = buf[x]; buf[x + 1] = b; buf[x + 2] = b; buf[x + 3] = b; buf[x + 4] = b; buf[x + 5] = b; buf[x + 6] = b; buf[x + 7] = b; buf[x + 8] = b; } break; + case 0x9: for(; x < moz_wmax; x += 0xA) { auto b = buf[x]; buf[x + 1] = b; buf[x + 2] = b; buf[x + 3] = b; buf[x + 4] = b; buf[x + 5] = b; buf[x + 6] = b; buf[x + 7] = b; buf[x + 8] = b; buf[x + 9] = b; } break; + case 0xA: for(; x < moz_wmax; x += 0xB) { auto b = buf[x]; buf[x + 1] = b; buf[x + 2] = b; buf[x + 3] = b; buf[x + 4] = b; buf[x + 5] = b; buf[x + 6] = b; buf[x + 7] = b; buf[x + 8] = b; buf[x + 9] = b; buf[x + 10] = b; } break; + case 0xB: for(; x < moz_wmax; x += 0xC) { auto b = buf[x]; buf[x + 1] = b; buf[x + 2] = b; buf[x + 3] = b; buf[x + 4] = b; buf[x + 5] = b; buf[x + 6] = b; buf[x + 7] = b; buf[x + 8] = b; buf[x + 9] = b; buf[x + 10] = b; buf[x + 11] = b; } break; + case 0xC: for(; x < moz_wmax; x += 0xD) { auto b = buf[x]; buf[x + 1] = b; buf[x + 2] = b; buf[x + 3] = b; buf[x + 4] = b; buf[x + 5] = b; buf[x + 6] = b; buf[x + 7] = b; buf[x + 8] = b; buf[x + 9] = b; buf[x + 10] = b; buf[x + 11] = b; buf[x + 12] = b; } break; + case 0xD: for(; x < moz_wmax; x += 0xE) { auto b = buf[x]; buf[x + 1] = b; buf[x + 2] = b; buf[x + 3] = b; buf[x + 4] = b; buf[x + 5] = b; buf[x + 6] = b; buf[x + 7] = b; buf[x + 8] = b; buf[x + 9] = b; buf[x + 10] = b; buf[x + 11] = b; buf[x + 12] = b; buf[x + 13] = b; } break; + case 0xE: for(; x < moz_wmax; x += 0xF) { auto b = buf[x]; buf[x + 1] = b; buf[x + 2] = b; buf[x + 3] = b; buf[x + 4] = b; buf[x + 5] = b; buf[x + 6] = b; buf[x + 7] = b; buf[x + 8] = b; buf[x + 9] = b; buf[x + 10] = b; buf[x + 11] = b; buf[x + 12] = b; buf[x + 13] = b; buf[x + 14] = b; } break; + case 0xF: for(; x < moz_wmax; x += 0x10) { auto b = buf[x]; buf[x + 1] = b; buf[x + 2] = b; buf[x + 3] = b; buf[x + 4] = b; buf[x + 5] = b; buf[x + 6] = b; buf[x + 7] = b; buf[x + 8] = b; buf[x + 9] = b; buf[x + 10] = b; buf[x + 11] = b; buf[x + 12] = b; buf[x + 13] = b; buf[x + 14] = b; buf[x + 15] = b;} break; + } + assert(x <= w); + + for(auto b = buf[x]; x < w; x++) + buf[x] = b; +} +#pragma GCC pop_options + +// +// NBG0(HRES=0x1): +// Cycle 0: OK +// Cycle 1: OK +// +// Cycle 2: +// [Entry 0] [Entry 0] [Entry 1] [Entry 2] +// Cycle 3 ... 7: +// [Entry 44] [Entry 44] [Entry 0] [Entry 1] +// + +static void FetchVCScroll(const unsigned w) +{ + const bool vcon[2] = { (bool)(SCRCTL & BGON & !(MZCTL & 0x1)), (bool)((SCRCTL >> 8) & (BGON >> 1) & !(MZCTL & 0x2) & 0x1) }; + const unsigned max_cyc = (HRes & 0x6) ? 4 : 8; + const unsigned tc = (w >> 3) + 1; + uint32 tmp[2] = { VCLast[0], VCLast[1] }; + uint32 vcaddr = VCScrollAddr & 0x3FFFE; + uint32 base[2]; + unsigned inc[8]; + uint8 VRMVCPCache[4][8]; + + for(unsigned bank = 0; bank < 4; bank++) + { + //unsigned brm[4]; + //brm[bank] = bank & (2 | ((VRAM_Mode >> (bank >> 1)) & 1)); + const unsigned esb = bank & (2 | ((VRAM_Mode >> (bank >> 1)) & 1)); + memcpy(VRMVCPCache[bank], VCPRegs[esb], 8); + } + + for(unsigned n = 0; n < 2; n++) + base[n] = CurYScrollIF[n] + YCoordAccum[n]; + + for(unsigned cyc = 0; cyc < max_cyc; cyc++) + { + unsigned do_inc = 0; + + for(unsigned bank = 0; bank < 4; bank++) + { + const unsigned act = VRMVCPCache[bank][cyc]; + + do_inc |= vcon[0] & (act == VCP_NBG0_VCS); + do_inc |= vcon[1] & (act == VCP_NBG1_VCS); + } + + inc[cyc] = do_inc << 1; + } + + for(unsigned tile = 0; MDFN_LIKELY(tile < tc); tile++) + { + for(unsigned cyc = 0; cyc < max_cyc; cyc++) + { + const unsigned act = VRMVCPCache[vcaddr >> 16][cyc]; + + // NBG0 + if(vcon[0]) + { + if(cyc == 3) + LB.vcscr[0][tile] = ((base[0] + tmp[0]) >> 8); + + if(cyc == 3) + tmp[0] = VCLast[0]; + + if(act == VCP_NBG0_VCS) + { + VCLast[0] = (VRAM[vcaddr + 0] << 8) | (VRAM[vcaddr + 1] >> 8); + if(cyc <= (1 + !tile)) + tmp[0] = VCLast[0]; + } + } + + // NBG1 + if(vcon[1]) + { + if(cyc == 4) + LB.vcscr[1][tile] = ((base[1] + tmp[1]) >> 8); + + if(cyc == 4) + tmp[1] = VCLast[1]; + + if(act == VCP_NBG1_VCS) + { + VCLast[1] = (VRAM[vcaddr + 0] << 8) | (VRAM[vcaddr + 1] >> 8); + if(cyc <= 2) //(2 + !tile)) // TODO: Check + tmp[1] = VCLast[1]; + } + } + + vcaddr = (vcaddr + inc[cyc]) & 0x3FFFE; + } + } +} + +template +static INLINE void MakeSFCodeLUT(const unsigned layer, int16* const sfcode_lut) +{ + const uint8 code = SFCODE >> (((SFSEL >> layer) & 1) << 3); + + for(unsigned i = 0; i < 8; i++) + { + uint16 tmp = 0xFFFF; + + if(!((code >> i) & 1)) + { + if(TA_PrioMode & 2) + tmp &= ~(1U << PIX_PRIO_SHIFT); + + if(TA_CCMode == 2) + tmp &= ~(1U << PIX_CCE_SHIFT); + } + + sfcode_lut[i] = tmp; + } +} + +static INLINE uint32 rgb15_to_rgb24(uint16 src) +{ + return ((((src << 3) & 0xF8) | ((src << 6) & 0xF800) | ((src << 9) & 0xF80000) | ((src << 16) & 0x80000000)));; +} + +template +static INLINE uint64 MakeNBGRBGPix(T& tf, const uint32 pix_base_or, const int16* sfcode_lut, const uint32 ix, const uint32 iy) +{ + uint32 cellx = (ix ^ tf.cellx_xor); + const uint16* vrb = &tf.tile_vrb[((cellx * TA_bpp) >> 4)]; + // + // + // + uint32 pbor = pix_base_or; + uint32 rgb24; + bool opaque; + + if(TA_CCMode == 1 || (TA_CCMode == 2 && !TA_isrgb)) + pbor |= (tf.scc << PIX_CCE_SHIFT); + + if(TA_PrioMode == 1 || (TA_PrioMode == 2 && !TA_isrgb)) + pbor |= (tf.spr << PIX_PRIO_SHIFT); + + if(TA_isrgb) + { + if(TA_bpp == 32) + { + uint32 tmp = (vrb[0] << 16) | vrb[1]; + + rgb24 = tmp & 0xFFFFFF; + opaque = (bool)(tmp & 0x80000000); + } + else + { + uint32 tmp = vrb[0]; + + rgb24 = rgb15_to_rgb24(tmp & 0x7FFF); + opaque = (bool)(tmp & 0x8000); + } + + if(TA_CCMode == 3) + pbor |= (1 << PIX_CCE_SHIFT); + } + else + { + uint32 dcc; + uint32 tmp = vrb[0]; //charno ^ (charno << 8); //vrb[0]; + + if(TA_bpp == 16) + dcc = tmp & 0x7FF; + else if(TA_bpp == 8) + dcc = (tmp >> (((cellx & 1) ^ 1) << 3)) & 0xFF; + else + dcc = (tmp >> (((cellx & 3) ^ 3) << 2)) & 0x0F; + + opaque = (bool)dcc; + + rgb24 = ColorCache[(tf.pcco + dcc) & 2047]; + + if(TA_CCMode == 3) + pbor |= ((int32)rgb24 >> 31) & (1 << PIX_CCE_SHIFT); + // + if(TA_PrioMode == 2 || TA_CCMode == 2) + pbor &= *(const int16*)((const uint8*)sfcode_lut + (dcc & 0xE)); + } + + if(!TA_igntp && !opaque) + pbor = 0; + + return pbor | ((uint64)rgb24 << PIX_RGB_SHIFT); +} + +template +static void T_DrawNBG(const unsigned n, uint64* bgbuf, const unsigned w, const uint32 pix_base_or) +{ + assert(n < 2); + // + // + const bool VCSEn = ((SCRCTL >> (n << 3)) & 0x1) && !(MZCTL & (1U << n)); + // + TileFetcher tf; + uint32 xcinc; + uint32 xc; + uint32 iy; + int16 sfcode_lut[8]; + + tf.CRAOffs = CRAMAddrOffs_NBG[n] << 8; + // + tf.BMSCC = ((BMPNA >> (4 + (n << 3))) & 1); + tf.BMSPR = ((BMPNA >> (5 + (n << 3))) & 1); + tf.BMPalNo = ((BMPNA >> (0 + (n << 3))) & 0x7) << 4; + tf.BMSize = ((CHCTLA >> (2 + (n << 3))) & 0x3); + // + tf.PlaneSize = (PLSZ >> (n << 1)) & 0x3; + tf.PNDSize = (PNCN[n] >> 15) & 1; // 0 = 2 words, 1 = 1 word + tf.CharSize = ((CHCTLA >> (0 + (n << 3))) & 1); + tf.AuxMode = (PNCN[n] >> 14) & 1; + tf.Supp = (PNCN[n] & 0x3FF); // Supplement bits when PNDSize == 1 + // + tf.Start(n, TA_bmen, (MPOFN >> (n << 2)) & 0x7, MapRegs[n]); + + MakeSFCodeLUT(n, sfcode_lut); + + xc = CurXScrollIF[n]; + iy = (CurYScrollIF[n] + MosEff_YCoordAccum[n]) >> 8; + xcinc = CurXCoordInc[n]; + + //if(line == 64) + // printf("Mega %d: planesize=0x%1x charsize=%d pndsize=%d(auxmode=%d,supp=0x%04x) bpp=%d/%d ccmode=0x%04x SFSEL=0x%04x SFCODE=0x%04x SFCCMD=0x%04x\n", n, PlaneSize, CharSize, PNDSize, AuxMode, Supp, TA_bpp, TA_isrgb, TA_CCMode, SFSEL, SFCODE, SFCCMD); + + //printf("Mega %d %02x %d --- %04x %04x -- %04x --- lsa=0x%06x vcsa=0x%06x --- imode=0x%01x\n", TA_bpp, BMSize, w, xcinc, ycinc, SCRCTL, LineScrollAddr[n], VCScrollAddr, InterlaceMode); + + // Map: 2x2 planes + // Plane: 1x1, 2x1, or 2x2 pages + // Page: 64x64 cells + // Character: 1x1, 2x2 cells + // Cell: 8x8 dots + uint32 prev_ix = ~0U; + + if(((ZMCTL >> (n << 3)) & 0x3) && VCSEn) + { + for(unsigned i = 0; MDFN_LIKELY(i < w); i++) + { + const uint32 ix = xc >> 8; + iy = LB.vcscr[n][i >> 3]; + tf.Fetch(TA_bmen, ix, iy); + // + // + // + bgbuf[i] = MakeNBGRBGPix(tf, pix_base_or, sfcode_lut, ix, iy); + xc += xcinc; + } + } + else + { + for(unsigned i = 0; MDFN_LIKELY(i < w); i++) + { + const uint32 ix = xc >> 8; + + if((ix >> 3) != prev_ix) + { + prev_ix = ix >> 3; + // + if(VCSEn) + iy = LB.vcscr[n][(i + 7) >> 3]; + + tf.Fetch(TA_bmen, ix, iy); + } + // + // + // + bgbuf[i] = MakeNBGRBGPix(tf, pix_base_or, sfcode_lut, ix, iy); + xc += xcinc; + } + } +} + +static void (*DrawNBG[2 /*bitmap enable*/][5/*col mode*/][2/*igntp*/][3/*priomode*/][4/*ccmode*/])(const unsigned n, uint64* bgbuf, const unsigned w, const uint32 pix_base_or) = +{ + { + { { { T_DrawNBG<0, 4, 0, 0, 0, 0>, T_DrawNBG<0, 4, 0, 0, 0, 1>, T_DrawNBG<0, 4, 0, 0, 0, 2>, T_DrawNBG<0, 4, 0, 0, 0, 3>, }, { T_DrawNBG<0, 4, 0, 0, 1, 0>, T_DrawNBG<0, 4, 0, 0, 1, 1>, T_DrawNBG<0, 4, 0, 0, 1, 2>, T_DrawNBG<0, 4, 0, 0, 1, 3>, }, { T_DrawNBG<0, 4, 0, 0, 2, 0>, T_DrawNBG<0, 4, 0, 0, 2, 1>, T_DrawNBG<0, 4, 0, 0, 2, 2>, T_DrawNBG<0, 4, 0, 0, 2, 3>, }, }, { { T_DrawNBG<0, 4, 0, 1, 0, 0>, T_DrawNBG<0, 4, 0, 1, 0, 1>, T_DrawNBG<0, 4, 0, 1, 0, 2>, T_DrawNBG<0, 4, 0, 1, 0, 3>, }, { T_DrawNBG<0, 4, 0, 1, 1, 0>, T_DrawNBG<0, 4, 0, 1, 1, 1>, T_DrawNBG<0, 4, 0, 1, 1, 2>, T_DrawNBG<0, 4, 0, 1, 1, 3>, }, { T_DrawNBG<0, 4, 0, 1, 2, 0>, T_DrawNBG<0, 4, 0, 1, 2, 1>, T_DrawNBG<0, 4, 0, 1, 2, 2>, T_DrawNBG<0, 4, 0, 1, 2, 3>, }, }, }, + { { { T_DrawNBG<0, 8, 0, 0, 0, 0>, T_DrawNBG<0, 8, 0, 0, 0, 1>, T_DrawNBG<0, 8, 0, 0, 0, 2>, T_DrawNBG<0, 8, 0, 0, 0, 3>, }, { T_DrawNBG<0, 8, 0, 0, 1, 0>, T_DrawNBG<0, 8, 0, 0, 1, 1>, T_DrawNBG<0, 8, 0, 0, 1, 2>, T_DrawNBG<0, 8, 0, 0, 1, 3>, }, { T_DrawNBG<0, 8, 0, 0, 2, 0>, T_DrawNBG<0, 8, 0, 0, 2, 1>, T_DrawNBG<0, 8, 0, 0, 2, 2>, T_DrawNBG<0, 8, 0, 0, 2, 3>, }, }, { { T_DrawNBG<0, 8, 0, 1, 0, 0>, T_DrawNBG<0, 8, 0, 1, 0, 1>, T_DrawNBG<0, 8, 0, 1, 0, 2>, T_DrawNBG<0, 8, 0, 1, 0, 3>, }, { T_DrawNBG<0, 8, 0, 1, 1, 0>, T_DrawNBG<0, 8, 0, 1, 1, 1>, T_DrawNBG<0, 8, 0, 1, 1, 2>, T_DrawNBG<0, 8, 0, 1, 1, 3>, }, { T_DrawNBG<0, 8, 0, 1, 2, 0>, T_DrawNBG<0, 8, 0, 1, 2, 1>, T_DrawNBG<0, 8, 0, 1, 2, 2>, T_DrawNBG<0, 8, 0, 1, 2, 3>, }, }, }, + { { { T_DrawNBG<0, 16, 0, 0, 0, 0>, T_DrawNBG<0, 16, 0, 0, 0, 1>, T_DrawNBG<0, 16, 0, 0, 0, 2>, T_DrawNBG<0, 16, 0, 0, 0, 3>, }, { T_DrawNBG<0, 16, 0, 0, 1, 0>, T_DrawNBG<0, 16, 0, 0, 1, 1>, T_DrawNBG<0, 16, 0, 0, 1, 2>, T_DrawNBG<0, 16, 0, 0, 1, 3>, }, { T_DrawNBG<0, 16, 0, 0, 2, 0>, T_DrawNBG<0, 16, 0, 0, 2, 1>, T_DrawNBG<0, 16, 0, 0, 2, 2>, T_DrawNBG<0, 16, 0, 0, 2, 3>, }, }, { { T_DrawNBG<0, 16, 0, 1, 0, 0>, T_DrawNBG<0, 16, 0, 1, 0, 1>, T_DrawNBG<0, 16, 0, 1, 0, 2>, T_DrawNBG<0, 16, 0, 1, 0, 3>, }, { T_DrawNBG<0, 16, 0, 1, 1, 0>, T_DrawNBG<0, 16, 0, 1, 1, 1>, T_DrawNBG<0, 16, 0, 1, 1, 2>, T_DrawNBG<0, 16, 0, 1, 1, 3>, }, { T_DrawNBG<0, 16, 0, 1, 2, 0>, T_DrawNBG<0, 16, 0, 1, 2, 1>, T_DrawNBG<0, 16, 0, 1, 2, 2>, T_DrawNBG<0, 16, 0, 1, 2, 3>, }, }, }, + { { { T_DrawNBG<0, 16, 1, 0, 0, 0>, T_DrawNBG<0, 16, 1, 0, 0, 1>, T_DrawNBG<0, 16, 1, 0, 0, 2>, T_DrawNBG<0, 16, 1, 0, 0, 3>, }, { T_DrawNBG<0, 16, 1, 0, 1, 0>, T_DrawNBG<0, 16, 1, 0, 1, 1>, T_DrawNBG<0, 16, 1, 0, 1, 2>, T_DrawNBG<0, 16, 1, 0, 1, 3>, }, { T_DrawNBG<0, 16, 1, 0, 2, 0>, T_DrawNBG<0, 16, 1, 0, 2, 1>, T_DrawNBG<0, 16, 1, 0, 2, 2>, T_DrawNBG<0, 16, 1, 0, 2, 3>, }, }, { { T_DrawNBG<0, 16, 1, 1, 0, 0>, T_DrawNBG<0, 16, 1, 1, 0, 1>, T_DrawNBG<0, 16, 1, 1, 0, 2>, T_DrawNBG<0, 16, 1, 1, 0, 3>, }, { T_DrawNBG<0, 16, 1, 1, 1, 0>, T_DrawNBG<0, 16, 1, 1, 1, 1>, T_DrawNBG<0, 16, 1, 1, 1, 2>, T_DrawNBG<0, 16, 1, 1, 1, 3>, }, { T_DrawNBG<0, 16, 1, 1, 2, 0>, T_DrawNBG<0, 16, 1, 1, 2, 1>, T_DrawNBG<0, 16, 1, 1, 2, 2>, T_DrawNBG<0, 16, 1, 1, 2, 3>, }, }, }, + { { { T_DrawNBG<0, 32, 1, 0, 0, 0>, T_DrawNBG<0, 32, 1, 0, 0, 1>, T_DrawNBG<0, 32, 1, 0, 0, 2>, T_DrawNBG<0, 32, 1, 0, 0, 3>, }, { T_DrawNBG<0, 32, 1, 0, 1, 0>, T_DrawNBG<0, 32, 1, 0, 1, 1>, T_DrawNBG<0, 32, 1, 0, 1, 2>, T_DrawNBG<0, 32, 1, 0, 1, 3>, }, { T_DrawNBG<0, 32, 1, 0, 2, 0>, T_DrawNBG<0, 32, 1, 0, 2, 1>, T_DrawNBG<0, 32, 1, 0, 2, 2>, T_DrawNBG<0, 32, 1, 0, 2, 3>, }, }, { { T_DrawNBG<0, 32, 1, 1, 0, 0>, T_DrawNBG<0, 32, 1, 1, 0, 1>, T_DrawNBG<0, 32, 1, 1, 0, 2>, T_DrawNBG<0, 32, 1, 1, 0, 3>, }, { T_DrawNBG<0, 32, 1, 1, 1, 0>, T_DrawNBG<0, 32, 1, 1, 1, 1>, T_DrawNBG<0, 32, 1, 1, 1, 2>, T_DrawNBG<0, 32, 1, 1, 1, 3>, }, { T_DrawNBG<0, 32, 1, 1, 2, 0>, T_DrawNBG<0, 32, 1, 1, 2, 1>, T_DrawNBG<0, 32, 1, 1, 2, 2>, T_DrawNBG<0, 32, 1, 1, 2, 3>, }, }, }, + }, + { + { { { T_DrawNBG<1, 4, 0, 0, 0, 0>, T_DrawNBG<1, 4, 0, 0, 0, 1>, T_DrawNBG<1, 4, 0, 0, 0, 2>, T_DrawNBG<1, 4, 0, 0, 0, 3>, }, { T_DrawNBG<1, 4, 0, 0, 1, 0>, T_DrawNBG<1, 4, 0, 0, 1, 1>, T_DrawNBG<1, 4, 0, 0, 1, 2>, T_DrawNBG<1, 4, 0, 0, 1, 3>, }, { T_DrawNBG<1, 4, 0, 0, 2, 0>, T_DrawNBG<1, 4, 0, 0, 2, 1>, T_DrawNBG<1, 4, 0, 0, 2, 2>, T_DrawNBG<1, 4, 0, 0, 2, 3>, }, }, { { T_DrawNBG<1, 4, 0, 1, 0, 0>, T_DrawNBG<1, 4, 0, 1, 0, 1>, T_DrawNBG<1, 4, 0, 1, 0, 2>, T_DrawNBG<1, 4, 0, 1, 0, 3>, }, { T_DrawNBG<1, 4, 0, 1, 1, 0>, T_DrawNBG<1, 4, 0, 1, 1, 1>, T_DrawNBG<1, 4, 0, 1, 1, 2>, T_DrawNBG<1, 4, 0, 1, 1, 3>, }, { T_DrawNBG<1, 4, 0, 1, 2, 0>, T_DrawNBG<1, 4, 0, 1, 2, 1>, T_DrawNBG<1, 4, 0, 1, 2, 2>, T_DrawNBG<1, 4, 0, 1, 2, 3>, }, }, }, + { { { T_DrawNBG<1, 8, 0, 0, 0, 0>, T_DrawNBG<1, 8, 0, 0, 0, 1>, T_DrawNBG<1, 8, 0, 0, 0, 2>, T_DrawNBG<1, 8, 0, 0, 0, 3>, }, { T_DrawNBG<1, 8, 0, 0, 1, 0>, T_DrawNBG<1, 8, 0, 0, 1, 1>, T_DrawNBG<1, 8, 0, 0, 1, 2>, T_DrawNBG<1, 8, 0, 0, 1, 3>, }, { T_DrawNBG<1, 8, 0, 0, 2, 0>, T_DrawNBG<1, 8, 0, 0, 2, 1>, T_DrawNBG<1, 8, 0, 0, 2, 2>, T_DrawNBG<1, 8, 0, 0, 2, 3>, }, }, { { T_DrawNBG<1, 8, 0, 1, 0, 0>, T_DrawNBG<1, 8, 0, 1, 0, 1>, T_DrawNBG<1, 8, 0, 1, 0, 2>, T_DrawNBG<1, 8, 0, 1, 0, 3>, }, { T_DrawNBG<1, 8, 0, 1, 1, 0>, T_DrawNBG<1, 8, 0, 1, 1, 1>, T_DrawNBG<1, 8, 0, 1, 1, 2>, T_DrawNBG<1, 8, 0, 1, 1, 3>, }, { T_DrawNBG<1, 8, 0, 1, 2, 0>, T_DrawNBG<1, 8, 0, 1, 2, 1>, T_DrawNBG<1, 8, 0, 1, 2, 2>, T_DrawNBG<1, 8, 0, 1, 2, 3>, }, }, }, + { { { T_DrawNBG<1, 16, 0, 0, 0, 0>, T_DrawNBG<1, 16, 0, 0, 0, 1>, T_DrawNBG<1, 16, 0, 0, 0, 2>, T_DrawNBG<1, 16, 0, 0, 0, 3>, }, { T_DrawNBG<1, 16, 0, 0, 1, 0>, T_DrawNBG<1, 16, 0, 0, 1, 1>, T_DrawNBG<1, 16, 0, 0, 1, 2>, T_DrawNBG<1, 16, 0, 0, 1, 3>, }, { T_DrawNBG<1, 16, 0, 0, 2, 0>, T_DrawNBG<1, 16, 0, 0, 2, 1>, T_DrawNBG<1, 16, 0, 0, 2, 2>, T_DrawNBG<1, 16, 0, 0, 2, 3>, }, }, { { T_DrawNBG<1, 16, 0, 1, 0, 0>, T_DrawNBG<1, 16, 0, 1, 0, 1>, T_DrawNBG<1, 16, 0, 1, 0, 2>, T_DrawNBG<1, 16, 0, 1, 0, 3>, }, { T_DrawNBG<1, 16, 0, 1, 1, 0>, T_DrawNBG<1, 16, 0, 1, 1, 1>, T_DrawNBG<1, 16, 0, 1, 1, 2>, T_DrawNBG<1, 16, 0, 1, 1, 3>, }, { T_DrawNBG<1, 16, 0, 1, 2, 0>, T_DrawNBG<1, 16, 0, 1, 2, 1>, T_DrawNBG<1, 16, 0, 1, 2, 2>, T_DrawNBG<1, 16, 0, 1, 2, 3>, }, }, }, + { { { T_DrawNBG<1, 16, 1, 0, 0, 0>, T_DrawNBG<1, 16, 1, 0, 0, 1>, T_DrawNBG<1, 16, 1, 0, 0, 2>, T_DrawNBG<1, 16, 1, 0, 0, 3>, }, { T_DrawNBG<1, 16, 1, 0, 1, 0>, T_DrawNBG<1, 16, 1, 0, 1, 1>, T_DrawNBG<1, 16, 1, 0, 1, 2>, T_DrawNBG<1, 16, 1, 0, 1, 3>, }, { T_DrawNBG<1, 16, 1, 0, 2, 0>, T_DrawNBG<1, 16, 1, 0, 2, 1>, T_DrawNBG<1, 16, 1, 0, 2, 2>, T_DrawNBG<1, 16, 1, 0, 2, 3>, }, }, { { T_DrawNBG<1, 16, 1, 1, 0, 0>, T_DrawNBG<1, 16, 1, 1, 0, 1>, T_DrawNBG<1, 16, 1, 1, 0, 2>, T_DrawNBG<1, 16, 1, 1, 0, 3>, }, { T_DrawNBG<1, 16, 1, 1, 1, 0>, T_DrawNBG<1, 16, 1, 1, 1, 1>, T_DrawNBG<1, 16, 1, 1, 1, 2>, T_DrawNBG<1, 16, 1, 1, 1, 3>, }, { T_DrawNBG<1, 16, 1, 1, 2, 0>, T_DrawNBG<1, 16, 1, 1, 2, 1>, T_DrawNBG<1, 16, 1, 1, 2, 2>, T_DrawNBG<1, 16, 1, 1, 2, 3>, }, }, }, + { { { T_DrawNBG<1, 32, 1, 0, 0, 0>, T_DrawNBG<1, 32, 1, 0, 0, 1>, T_DrawNBG<1, 32, 1, 0, 0, 2>, T_DrawNBG<1, 32, 1, 0, 0, 3>, }, { T_DrawNBG<1, 32, 1, 0, 1, 0>, T_DrawNBG<1, 32, 1, 0, 1, 1>, T_DrawNBG<1, 32, 1, 0, 1, 2>, T_DrawNBG<1, 32, 1, 0, 1, 3>, }, { T_DrawNBG<1, 32, 1, 0, 2, 0>, T_DrawNBG<1, 32, 1, 0, 2, 1>, T_DrawNBG<1, 32, 1, 0, 2, 2>, T_DrawNBG<1, 32, 1, 0, 2, 3>, }, }, { { T_DrawNBG<1, 32, 1, 1, 0, 0>, T_DrawNBG<1, 32, 1, 1, 0, 1>, T_DrawNBG<1, 32, 1, 1, 0, 2>, T_DrawNBG<1, 32, 1, 1, 0, 3>, }, { T_DrawNBG<1, 32, 1, 1, 1, 0>, T_DrawNBG<1, 32, 1, 1, 1, 1>, T_DrawNBG<1, 32, 1, 1, 1, 2>, T_DrawNBG<1, 32, 1, 1, 1, 3>, }, { T_DrawNBG<1, 32, 1, 1, 2, 0>, T_DrawNBG<1, 32, 1, 1, 2, 1>, T_DrawNBG<1, 32, 1, 1, 2, 2>, T_DrawNBG<1, 32, 1, 1, 2, 3>, }, }, }, + } +}; + +template +static INLINE uint64 MakeNBG23Pix(uint32 dcc, uint32 pbor, const int16* sfcode_lut, uint32 colcacheoffs) +{ + uint32 rgb24; + + rgb24 = ColorCache[(colcacheoffs + dcc) & 2047]; + + if(TA_CCMode == 3) + pbor |= ((int32)rgb24 >> 31) & (1 << PIX_CCE_SHIFT); + + if(TA_PrioMode == 2 || TA_CCMode == 2) + pbor &= *(const int16*)((const uint8*)sfcode_lut + (dcc & 0xE)); + + if(!TA_igntp && !dcc) + pbor = 0; + + return pbor + ((uint64)rgb24 << PIX_RGB_SHIFT); +} + +// +// CCMode will be forced to 0 in the effective instantiation if corresponding NBG CCE bit in CCCTL is 0. +// +template +static void T_DrawNBG23(const unsigned n, uint64* bgbuf, const unsigned w, const uint32 pix_base_or) +{ + assert(n >= 2); + TileFetcher tf; + int16 sfcode_lut[8]; + unsigned tc = 1 + (w >> 3); + const unsigned xscr = XScrollI[n]; + const unsigned yscr = MosEff_NBG23_YCounter[n & 1]; + unsigned tx; + + tf.CRAOffs = CRAMAddrOffs_NBG[n] << 8; + // + tf.PlaneSize = (PLSZ >> (n << 1)) & 0x3; + tf.PNDSize = (PNCN[n] >> 15) & 1; // 0 = 2 words, 1 = 1 word + tf.CharSize = ((CHCTLB >> (0 + ((n & 1) << 2))) & 1); + tf.AuxMode = (PNCN[n] >> 14) & 1; + tf.Supp = (PNCN[n] & 0x3FF); // Supplement bits when PNDSize == 1 + // + tf.Start(n, false, (MPOFN >> (n << 2)) & 0x7, MapRegs[n]); + + MakeSFCodeLUT(n, sfcode_lut); + + bgbuf -= xscr & 0x7; + tx = xscr >> 3; + + //if(TA_bpp == 4 && n == 3) + // printf("Goop: %d %d %02x, %016llx %016llx %016llx %016llx\n", n, TA_bpp, VRAM_Mode, MDFN_de64lsb(VCPRegs[0]), MDFN_de64lsb(VCPRegs[1]), MDFN_de64lsb(VCPRegs[2]), MDFN_de64lsb(VCPRegs[3])); + // Kludge for Akumajou Dracula X + if(MDFN_UNLIKELY(TA_bpp == 4 && n == 3 && VRAM_Mode == 0x2 && MDFN_de64lsb(VCPRegs[0]) == 0x0f0f070406060505ULL && MDFN_de64lsb(VCPRegs[2]) == 0x0f0f03000f0f0201ULL && MDFN_de64lsb(VCPRegs[3]) == 0x0f0f0f0f0f0f0f0fULL)) + { + for(unsigned i = 0; i < 8; i++) + *bgbuf++ = 0; + tc--; + } + + while(MDFN_LIKELY(tc--)) + { + uint32 pbor = pix_base_or; + + tf.Fetch(false, tx << 3, yscr); + + if(TA_CCMode == 1 || TA_CCMode == 2) + pbor |= (tf.scc << PIX_CCE_SHIFT); + + if(TA_PrioMode == 1 || TA_PrioMode == 2) + pbor |= (tf.spr << PIX_PRIO_SHIFT); + // + // + auto* const mbp = MakeNBG23Pix; + + if(TA_bpp == 8) + { + if(tf.cellx_xor & 0x7) + { + bgbuf[7] = mbp((uint8)(tf.tile_vrb[0] >> 8), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[6] = mbp((uint8)(tf.tile_vrb[0] >> 0), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[5] = mbp((uint8)(tf.tile_vrb[1] >> 8), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[4] = mbp((uint8)(tf.tile_vrb[1] >> 0), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[3] = mbp((uint8)(tf.tile_vrb[2] >> 8), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[2] = mbp((uint8)(tf.tile_vrb[2] >> 0), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[1] = mbp((uint8)(tf.tile_vrb[3] >> 8), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[0] = mbp((uint8)(tf.tile_vrb[3] >> 0), /**/pbor, sfcode_lut, tf.pcco); + } + else + { + bgbuf[0] = mbp((uint8)(tf.tile_vrb[0] >> 8), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[1] = mbp((uint8)(tf.tile_vrb[0] >> 0), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[2] = mbp((uint8)(tf.tile_vrb[1] >> 8), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[3] = mbp((uint8)(tf.tile_vrb[1] >> 0), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[4] = mbp((uint8)(tf.tile_vrb[2] >> 8), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[5] = mbp((uint8)(tf.tile_vrb[2] >> 0), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[6] = mbp((uint8)(tf.tile_vrb[3] >> 8), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[7] = mbp((uint8)(tf.tile_vrb[3] >> 0), /**/pbor, sfcode_lut, tf.pcco); + } + } + else + { + if(tf.cellx_xor & 0x7) + { + bgbuf[7] = mbp((tf.tile_vrb[0] >> 12), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[6] = mbp((tf.tile_vrb[0] >> 8) & 0xF, /**/pbor, sfcode_lut, tf.pcco); + bgbuf[5] = mbp((tf.tile_vrb[0] >> 4) & 0xF, /**/pbor, sfcode_lut, tf.pcco); + bgbuf[4] = mbp((tf.tile_vrb[0] >> 0) & 0xF, /**/pbor, sfcode_lut, tf.pcco); + bgbuf[3] = mbp((tf.tile_vrb[1] >> 12), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[2] = mbp((tf.tile_vrb[1] >> 8) & 0xF, /**/pbor, sfcode_lut, tf.pcco); + bgbuf[1] = mbp((tf.tile_vrb[1] >> 4) & 0xF, /**/pbor, sfcode_lut, tf.pcco); + bgbuf[0] = mbp((tf.tile_vrb[1] >> 0) & 0xF, /**/pbor, sfcode_lut, tf.pcco); + } + else + { + bgbuf[0] = mbp((tf.tile_vrb[0] >> 12), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[1] = mbp((tf.tile_vrb[0] >> 8) & 0xF, /**/pbor, sfcode_lut, tf.pcco); + bgbuf[2] = mbp((tf.tile_vrb[0] >> 4) & 0xF, /**/pbor, sfcode_lut, tf.pcco); + bgbuf[3] = mbp((tf.tile_vrb[0] >> 0) & 0xF, /**/pbor, sfcode_lut, tf.pcco); + bgbuf[4] = mbp((tf.tile_vrb[1] >> 12), /**/pbor, sfcode_lut, tf.pcco); + bgbuf[5] = mbp((tf.tile_vrb[1] >> 8) & 0xF, /**/pbor, sfcode_lut, tf.pcco); + bgbuf[6] = mbp((tf.tile_vrb[1] >> 4) & 0xF, /**/pbor, sfcode_lut, tf.pcco); + bgbuf[7] = mbp((tf.tile_vrb[1] >> 0) & 0xF, /**/pbor, sfcode_lut, tf.pcco); + } + } + + // + // + // + tx++; + bgbuf += 8; + } +} + +static void (*DrawNBG23[2/*col mode*/][2/*igntp*/][3/*priomode*/][4/*ccmode*/])(const unsigned n, uint64* bgbuf, const unsigned w, const uint32 pix_base_or) = +{ + { + { { T_DrawNBG23<4, 0, 0, 0>, T_DrawNBG23<4, 0, 0, 1>, T_DrawNBG23<4, 0, 0, 2>, T_DrawNBG23<4, 0, 0, 3>, }, { T_DrawNBG23<4, 0, 1, 0>, T_DrawNBG23<4, 0, 1, 1>, T_DrawNBG23<4, 0, 1, 2>, T_DrawNBG23<4, 0, 1, 3>, }, { T_DrawNBG23<4, 0, 2, 0>, T_DrawNBG23<4, 0, 2, 1>, T_DrawNBG23<4, 0, 2, 2>, T_DrawNBG23<4, 0, 2, 3>, }, }, + { { T_DrawNBG23<4, 1, 0, 0>, T_DrawNBG23<4, 1, 0, 1>, T_DrawNBG23<4, 1, 0, 2>, T_DrawNBG23<4, 1, 0, 3>, }, { T_DrawNBG23<4, 1, 1, 0>, T_DrawNBG23<4, 1, 1, 1>, T_DrawNBG23<4, 1, 1, 2>, T_DrawNBG23<4, 1, 1, 3>, }, { T_DrawNBG23<4, 1, 2, 0>, T_DrawNBG23<4, 1, 2, 1>, T_DrawNBG23<4, 1, 2, 2>, T_DrawNBG23<4, 1, 2, 3>, }, }, + }, + { + { { T_DrawNBG23<8, 0, 0, 0>, T_DrawNBG23<8, 0, 0, 1>, T_DrawNBG23<8, 0, 0, 2>, T_DrawNBG23<8, 0, 0, 3>, }, { T_DrawNBG23<8, 0, 1, 0>, T_DrawNBG23<8, 0, 1, 1>, T_DrawNBG23<8, 0, 1, 2>, T_DrawNBG23<8, 0, 1, 3>, }, { T_DrawNBG23<8, 0, 2, 0>, T_DrawNBG23<8, 0, 2, 1>, T_DrawNBG23<8, 0, 2, 2>, T_DrawNBG23<8, 0, 2, 3>, }, }, + { { T_DrawNBG23<8, 1, 0, 0>, T_DrawNBG23<8, 1, 0, 1>, T_DrawNBG23<8, 1, 0, 2>, T_DrawNBG23<8, 1, 0, 3>, }, { T_DrawNBG23<8, 1, 1, 0>, T_DrawNBG23<8, 1, 1, 1>, T_DrawNBG23<8, 1, 1, 2>, T_DrawNBG23<8, 1, 1, 3>, }, { T_DrawNBG23<8, 1, 2, 0>, T_DrawNBG23<8, 1, 2, 1>, T_DrawNBG23<8, 1, 2, 2>, T_DrawNBG23<8, 1, 2, 3>, }, }, + }, +}; + +static INLINE uint32 GetCoeffAddr(const unsigned i, uint32 offset) +{ + const uint32 src_mask = (CRKTE ? 0x3FF : 0x3FFFF); + + offset >>= 10; + offset <<= !(KTCTL[i] & 0x2); + offset &= src_mask; + + return offset; +} + +static INLINE uint32 ReadCoeff(const unsigned i, const uint32 addr) +{ + const uint16* src = (CRKTE ? &CRAM[0x400] : VRAM); + uint32 coeff; + + if(KTCTL[i] & 0x2) + { + const uint16 tmp = src[addr]; + coeff = (sign_x_to_s32(21, tmp << 6) & 0x00FFFFFF) | ((tmp & 0x8000) << 16); + //printf("%d Coeff %08x, %04x -- %08x\n", i, offset, tmp, coeff); + } + else + { + const uint16* ea = &src[addr]; + coeff = (ea[0] << 16) | ea[1]; + } + + return coeff; +} + +// Coefficient table reading can (temporarily) override kx, ky, and/or Xp +// +// When RBG1 is enabled, line color screen uses rotation parameter A coefficient table +// +// RBG1 always uses MSB of coefficient data as transparent bit. +// +// RBG1 requires RPMD == 0, or else bad things happen? + +template +static void SetupRotVars(const T* rs, const unsigned rbg_w) +{ + const uint8 EffRPMD = ((BGON & 0x20) ? 0 : RPMD); + + if(EffRPMD < 2) + { + for(unsigned x = 0; MDFN_LIKELY(x < rbg_w); x++) + LB.rotabsel[x] = RPMD; + } + else if(EffRPMD == 3) + GetWinRotAB(); + + // + // + // + + for(unsigned i = 0; i < 2; i++) + { + auto& r = LB.rotv[i]; + + r.Xsp = rs[i].Xsp; + r.Ysp = rs[i].Ysp; + r.Xp = rs[i].Xp; + r.Yp = rs[i].Yp; + r.dX = rs[i].dX; + r.dY = rs[i].dY; + r.kx = rs[i].kx; + r.ky = rs[i].ky; + + LB.rotv[i].tf.BMSCC = ((BMPNB >> 4) & 1); + LB.rotv[i].tf.BMSPR = ((BMPNB >> 5) & 1); + LB.rotv[i].tf.BMPalNo = ((BMPNB >> 0) & 0x7) << 4; + LB.rotv[i].tf.BMSize = ((CHCTLB >> 10) & 0x1); + + // + // + // + // + // + // + if((BGON & 0x20) && i) + { + LB.rotv[1].tf.CRAOffs = CRAMAddrOffs_NBG[0] << 8; + LB.rotv[1].tf.PNDSize = (PNCN[0] >> 15) & 1; + LB.rotv[1].tf.CharSize = ((CHCTLA >> 0) & 1); + LB.rotv[1].tf.AuxMode = (PNCN[0] >> 14) & 1; + LB.rotv[1].tf.Supp = (PNCN[0] & 0x3FF); + } + else + { + LB.rotv[i].tf.CRAOffs = CRAMAddrOffs_RBG0 << 8; + LB.rotv[i].tf.PNDSize = (PNCNR >> 15) & 1; + LB.rotv[i].tf.CharSize = ((CHCTLB >> 8) & 1); + LB.rotv[i].tf.AuxMode = (PNCNR >> 14) & 1; + LB.rotv[i].tf.Supp = (PNCNR & 0x3FF); + } + LB.rotv[i].tf.PlaneSize = (PLSZ >> ( 8 + (i << 2))) & 0x3; + LB.rotv[i].tf.PlaneOver = (PLSZ >> (10 + (i << 2))) & 0x3; + LB.rotv[i].tf.PlaneOverChar = OVPNR[i]; + LB.rotv[i].tf.Start(4 + i, !i && ((CHCTLB >> 9) & 1), (MPOFR >> (i << 2)) & 0x7, RotMapRegs[i]); + } + + // + // + // + { + bool bank_tab[4]; + + for(unsigned i = 0; i < 4; i++) + bank_tab[i] = ((RDBS_Mode >> (i << 1)) & 0x3) == RDBS_COEFF; + // + if(!(VRAM_Mode & 0x1)) + bank_tab[1] = bank_tab[0]; + + if(!(VRAM_Mode & 0x2)) + bank_tab[3] = bank_tab[2]; + + if(BGON & 0x20) + bank_tab[2] = bank_tab[3] = false; + // + if(CRKTE) + bank_tab[0] = bank_tab[1] = bank_tab[2] = bank_tab[3] = true; + // + // + LB.rotv[0].use_coeff = (bool)(KTCTL[0] & 0x1); + LB.rotv[1].use_coeff = (bool)(KTCTL[1] & 0x1); + + uint32 coeff[2]; + + for(unsigned i = 0; i < 2; i++) + LB.rotv[i].base_coeff = coeff[i] = ReadCoeff(i, GetCoeffAddr(i, rs[i].KAstAccum)); + + //if(grumpus == 120) + // printf("BankTab: %d %d %d %d, UC: %d %d, Coeff: @0x%05x=0x%08x @0x%05x=0x%08x, DKAx: %f %f\n", bank_tab[0], bank_tab[1], bank_tab[2], bank_tab[3], LB.rotv[0].use_coeff, LB.rotv[1].use_coeff, GetCoeffAddr(0, rs[0].KAstAccum), coeff[0], GetCoeffAddr(1, rs[1].KAstAccum), coeff[1], rs[0].DKAx / 1024.0, rs[1].DKAx / 1024.0); + + for(unsigned x = 0; MDFN_LIKELY(x < rbg_w); x++) + { + const unsigned i = ((EffRPMD == 2) ? 0 : LB.rotabsel[x]); + const uint32 addr = GetCoeffAddr(i, rs[i].KAstAccum + (x * rs[i].DKAx)); + + if(bank_tab[addr >> 16]) + coeff[i] = ReadCoeff(i, addr); + + if(KTCTL[i] & 0x10) + LB.lc[x] = (coeff[i] >> 24) & 0x7F; + + if(EffRPMD == 2) + { + uint32 tmp = coeff[0]; + + LB.rotabsel[x] = tmp >> 31; + + if((int32)tmp < 0) + tmp = coeff[1]; + + LB.rotcoeff[x] = tmp; + } + else + LB.rotcoeff[x] = coeff[i]; + } + } +} + +// const bool TA_bmen = ((rn == 1) ? false : ((CHCTLB >> 9) & 1)); +template +static void T_DrawRBG(const bool rn, uint64* bgbuf, const unsigned w, const uint32 pix_base_or) +{ + // Full color format selection for both RBG0 and RBG1 + // Bitmap only allowed for RBG0 + // RBG0 can use rot param A and B, RBG1 is fixed to rot param B + // RBG1 shares setting bitfields with NBG0 + // 16 planes instead of 4 like with NBG* + // Mosaic only has effect in the horizontal direction? + // + int16 sfcode_lut[8]; + + MakeSFCodeLUT((rn ? 0 : 4), sfcode_lut); + + for(unsigned i = 0; MDFN_LIKELY(i < w); i++) + { + const unsigned ab = LB.rotabsel[i]; + auto& r = LB.rotv[ab]; + auto& tf = r.tf; + uint32 Xp = r.Xp; + int32 kx = r.kx; + int32 ky = r.ky; + bool rot_tp = false; + + if(r.use_coeff) + { + const uint32 coeff = (rn ? r.base_coeff : LB.rotcoeff[i]); + + rot_tp = ((int32)coeff < 0); + + const uint32 sext = sign_x_to_s32(24, coeff); + + switch((KTCTL[ab] >> 2) & 0x3) + { + case 0: kx = ky = sext; break; + case 1: kx = sext; break; + case 2: ky = sext; break; + case 3: Xp = sext << 2; break; + } + } + + const uint32 ix = ( Xp + (uint32)(((int64)kx * (int32)(r.Xsp + (r.dX * i))) >> 16)) >> 10; + const uint32 iy = (r.Yp + (uint32)(((int64)ky * (int32)(r.Ysp + (r.dY * i))) >> 16)) >> 10; + + rot_tp |= tf.Fetch(TA_bmen, ix, iy); + + LB.rotabsel[i] = rot_tp; + // + // + // + bgbuf[i] = MakeNBGRBGPix(tf, pix_base_or, sfcode_lut, ix, iy); + } +} + +//template +static void (*DrawRBG[2 /*bitmap enable*/][5/*col mode*/][2/*igntp*/][3/*priomode*/][4/*ccmode*/])(const bool rn, uint64* bgbuf, const unsigned w, const uint32 pix_base_or) = +{ + { + { { { T_DrawRBG<0, 4, 0, 0, 0, 0>, T_DrawRBG<0, 4, 0, 0, 0, 1>, T_DrawRBG<0, 4, 0, 0, 0, 2>, T_DrawRBG<0, 4, 0, 0, 0, 3>, }, { T_DrawRBG<0, 4, 0, 0, 1, 0>, T_DrawRBG<0, 4, 0, 0, 1, 1>, T_DrawRBG<0, 4, 0, 0, 1, 2>, T_DrawRBG<0, 4, 0, 0, 1, 3>, }, { T_DrawRBG<0, 4, 0, 0, 2, 0>, T_DrawRBG<0, 4, 0, 0, 2, 1>, T_DrawRBG<0, 4, 0, 0, 2, 2>, T_DrawRBG<0, 4, 0, 0, 2, 3>, }, }, { { T_DrawRBG<0, 4, 0, 1, 0, 0>, T_DrawRBG<0, 4, 0, 1, 0, 1>, T_DrawRBG<0, 4, 0, 1, 0, 2>, T_DrawRBG<0, 4, 0, 1, 0, 3>, }, { T_DrawRBG<0, 4, 0, 1, 1, 0>, T_DrawRBG<0, 4, 0, 1, 1, 1>, T_DrawRBG<0, 4, 0, 1, 1, 2>, T_DrawRBG<0, 4, 0, 1, 1, 3>, }, { T_DrawRBG<0, 4, 0, 1, 2, 0>, T_DrawRBG<0, 4, 0, 1, 2, 1>, T_DrawRBG<0, 4, 0, 1, 2, 2>, T_DrawRBG<0, 4, 0, 1, 2, 3>, }, }, }, + { { { T_DrawRBG<0, 8, 0, 0, 0, 0>, T_DrawRBG<0, 8, 0, 0, 0, 1>, T_DrawRBG<0, 8, 0, 0, 0, 2>, T_DrawRBG<0, 8, 0, 0, 0, 3>, }, { T_DrawRBG<0, 8, 0, 0, 1, 0>, T_DrawRBG<0, 8, 0, 0, 1, 1>, T_DrawRBG<0, 8, 0, 0, 1, 2>, T_DrawRBG<0, 8, 0, 0, 1, 3>, }, { T_DrawRBG<0, 8, 0, 0, 2, 0>, T_DrawRBG<0, 8, 0, 0, 2, 1>, T_DrawRBG<0, 8, 0, 0, 2, 2>, T_DrawRBG<0, 8, 0, 0, 2, 3>, }, }, { { T_DrawRBG<0, 8, 0, 1, 0, 0>, T_DrawRBG<0, 8, 0, 1, 0, 1>, T_DrawRBG<0, 8, 0, 1, 0, 2>, T_DrawRBG<0, 8, 0, 1, 0, 3>, }, { T_DrawRBG<0, 8, 0, 1, 1, 0>, T_DrawRBG<0, 8, 0, 1, 1, 1>, T_DrawRBG<0, 8, 0, 1, 1, 2>, T_DrawRBG<0, 8, 0, 1, 1, 3>, }, { T_DrawRBG<0, 8, 0, 1, 2, 0>, T_DrawRBG<0, 8, 0, 1, 2, 1>, T_DrawRBG<0, 8, 0, 1, 2, 2>, T_DrawRBG<0, 8, 0, 1, 2, 3>, }, }, }, + { { { T_DrawRBG<0, 16, 0, 0, 0, 0>, T_DrawRBG<0, 16, 0, 0, 0, 1>, T_DrawRBG<0, 16, 0, 0, 0, 2>, T_DrawRBG<0, 16, 0, 0, 0, 3>, }, { T_DrawRBG<0, 16, 0, 0, 1, 0>, T_DrawRBG<0, 16, 0, 0, 1, 1>, T_DrawRBG<0, 16, 0, 0, 1, 2>, T_DrawRBG<0, 16, 0, 0, 1, 3>, }, { T_DrawRBG<0, 16, 0, 0, 2, 0>, T_DrawRBG<0, 16, 0, 0, 2, 1>, T_DrawRBG<0, 16, 0, 0, 2, 2>, T_DrawRBG<0, 16, 0, 0, 2, 3>, }, }, { { T_DrawRBG<0, 16, 0, 1, 0, 0>, T_DrawRBG<0, 16, 0, 1, 0, 1>, T_DrawRBG<0, 16, 0, 1, 0, 2>, T_DrawRBG<0, 16, 0, 1, 0, 3>, }, { T_DrawRBG<0, 16, 0, 1, 1, 0>, T_DrawRBG<0, 16, 0, 1, 1, 1>, T_DrawRBG<0, 16, 0, 1, 1, 2>, T_DrawRBG<0, 16, 0, 1, 1, 3>, }, { T_DrawRBG<0, 16, 0, 1, 2, 0>, T_DrawRBG<0, 16, 0, 1, 2, 1>, T_DrawRBG<0, 16, 0, 1, 2, 2>, T_DrawRBG<0, 16, 0, 1, 2, 3>, }, }, }, + { { { T_DrawRBG<0, 16, 1, 0, 0, 0>, T_DrawRBG<0, 16, 1, 0, 0, 1>, T_DrawRBG<0, 16, 1, 0, 0, 2>, T_DrawRBG<0, 16, 1, 0, 0, 3>, }, { T_DrawRBG<0, 16, 1, 0, 1, 0>, T_DrawRBG<0, 16, 1, 0, 1, 1>, T_DrawRBG<0, 16, 1, 0, 1, 2>, T_DrawRBG<0, 16, 1, 0, 1, 3>, }, { T_DrawRBG<0, 16, 1, 0, 2, 0>, T_DrawRBG<0, 16, 1, 0, 2, 1>, T_DrawRBG<0, 16, 1, 0, 2, 2>, T_DrawRBG<0, 16, 1, 0, 2, 3>, }, }, { { T_DrawRBG<0, 16, 1, 1, 0, 0>, T_DrawRBG<0, 16, 1, 1, 0, 1>, T_DrawRBG<0, 16, 1, 1, 0, 2>, T_DrawRBG<0, 16, 1, 1, 0, 3>, }, { T_DrawRBG<0, 16, 1, 1, 1, 0>, T_DrawRBG<0, 16, 1, 1, 1, 1>, T_DrawRBG<0, 16, 1, 1, 1, 2>, T_DrawRBG<0, 16, 1, 1, 1, 3>, }, { T_DrawRBG<0, 16, 1, 1, 2, 0>, T_DrawRBG<0, 16, 1, 1, 2, 1>, T_DrawRBG<0, 16, 1, 1, 2, 2>, T_DrawRBG<0, 16, 1, 1, 2, 3>, }, }, }, + { { { T_DrawRBG<0, 32, 1, 0, 0, 0>, T_DrawRBG<0, 32, 1, 0, 0, 1>, T_DrawRBG<0, 32, 1, 0, 0, 2>, T_DrawRBG<0, 32, 1, 0, 0, 3>, }, { T_DrawRBG<0, 32, 1, 0, 1, 0>, T_DrawRBG<0, 32, 1, 0, 1, 1>, T_DrawRBG<0, 32, 1, 0, 1, 2>, T_DrawRBG<0, 32, 1, 0, 1, 3>, }, { T_DrawRBG<0, 32, 1, 0, 2, 0>, T_DrawRBG<0, 32, 1, 0, 2, 1>, T_DrawRBG<0, 32, 1, 0, 2, 2>, T_DrawRBG<0, 32, 1, 0, 2, 3>, }, }, { { T_DrawRBG<0, 32, 1, 1, 0, 0>, T_DrawRBG<0, 32, 1, 1, 0, 1>, T_DrawRBG<0, 32, 1, 1, 0, 2>, T_DrawRBG<0, 32, 1, 1, 0, 3>, }, { T_DrawRBG<0, 32, 1, 1, 1, 0>, T_DrawRBG<0, 32, 1, 1, 1, 1>, T_DrawRBG<0, 32, 1, 1, 1, 2>, T_DrawRBG<0, 32, 1, 1, 1, 3>, }, { T_DrawRBG<0, 32, 1, 1, 2, 0>, T_DrawRBG<0, 32, 1, 1, 2, 1>, T_DrawRBG<0, 32, 1, 1, 2, 2>, T_DrawRBG<0, 32, 1, 1, 2, 3>, }, }, }, + }, + { + { { { T_DrawRBG<1, 4, 0, 0, 0, 0>, T_DrawRBG<1, 4, 0, 0, 0, 1>, T_DrawRBG<1, 4, 0, 0, 0, 2>, T_DrawRBG<1, 4, 0, 0, 0, 3>, }, { T_DrawRBG<1, 4, 0, 0, 1, 0>, T_DrawRBG<1, 4, 0, 0, 1, 1>, T_DrawRBG<1, 4, 0, 0, 1, 2>, T_DrawRBG<1, 4, 0, 0, 1, 3>, }, { T_DrawRBG<1, 4, 0, 0, 2, 0>, T_DrawRBG<1, 4, 0, 0, 2, 1>, T_DrawRBG<1, 4, 0, 0, 2, 2>, T_DrawRBG<1, 4, 0, 0, 2, 3>, }, }, { { T_DrawRBG<1, 4, 0, 1, 0, 0>, T_DrawRBG<1, 4, 0, 1, 0, 1>, T_DrawRBG<1, 4, 0, 1, 0, 2>, T_DrawRBG<1, 4, 0, 1, 0, 3>, }, { T_DrawRBG<1, 4, 0, 1, 1, 0>, T_DrawRBG<1, 4, 0, 1, 1, 1>, T_DrawRBG<1, 4, 0, 1, 1, 2>, T_DrawRBG<1, 4, 0, 1, 1, 3>, }, { T_DrawRBG<1, 4, 0, 1, 2, 0>, T_DrawRBG<1, 4, 0, 1, 2, 1>, T_DrawRBG<1, 4, 0, 1, 2, 2>, T_DrawRBG<1, 4, 0, 1, 2, 3>, }, }, }, + { { { T_DrawRBG<1, 8, 0, 0, 0, 0>, T_DrawRBG<1, 8, 0, 0, 0, 1>, T_DrawRBG<1, 8, 0, 0, 0, 2>, T_DrawRBG<1, 8, 0, 0, 0, 3>, }, { T_DrawRBG<1, 8, 0, 0, 1, 0>, T_DrawRBG<1, 8, 0, 0, 1, 1>, T_DrawRBG<1, 8, 0, 0, 1, 2>, T_DrawRBG<1, 8, 0, 0, 1, 3>, }, { T_DrawRBG<1, 8, 0, 0, 2, 0>, T_DrawRBG<1, 8, 0, 0, 2, 1>, T_DrawRBG<1, 8, 0, 0, 2, 2>, T_DrawRBG<1, 8, 0, 0, 2, 3>, }, }, { { T_DrawRBG<1, 8, 0, 1, 0, 0>, T_DrawRBG<1, 8, 0, 1, 0, 1>, T_DrawRBG<1, 8, 0, 1, 0, 2>, T_DrawRBG<1, 8, 0, 1, 0, 3>, }, { T_DrawRBG<1, 8, 0, 1, 1, 0>, T_DrawRBG<1, 8, 0, 1, 1, 1>, T_DrawRBG<1, 8, 0, 1, 1, 2>, T_DrawRBG<1, 8, 0, 1, 1, 3>, }, { T_DrawRBG<1, 8, 0, 1, 2, 0>, T_DrawRBG<1, 8, 0, 1, 2, 1>, T_DrawRBG<1, 8, 0, 1, 2, 2>, T_DrawRBG<1, 8, 0, 1, 2, 3>, }, }, }, + { { { T_DrawRBG<1, 16, 0, 0, 0, 0>, T_DrawRBG<1, 16, 0, 0, 0, 1>, T_DrawRBG<1, 16, 0, 0, 0, 2>, T_DrawRBG<1, 16, 0, 0, 0, 3>, }, { T_DrawRBG<1, 16, 0, 0, 1, 0>, T_DrawRBG<1, 16, 0, 0, 1, 1>, T_DrawRBG<1, 16, 0, 0, 1, 2>, T_DrawRBG<1, 16, 0, 0, 1, 3>, }, { T_DrawRBG<1, 16, 0, 0, 2, 0>, T_DrawRBG<1, 16, 0, 0, 2, 1>, T_DrawRBG<1, 16, 0, 0, 2, 2>, T_DrawRBG<1, 16, 0, 0, 2, 3>, }, }, { { T_DrawRBG<1, 16, 0, 1, 0, 0>, T_DrawRBG<1, 16, 0, 1, 0, 1>, T_DrawRBG<1, 16, 0, 1, 0, 2>, T_DrawRBG<1, 16, 0, 1, 0, 3>, }, { T_DrawRBG<1, 16, 0, 1, 1, 0>, T_DrawRBG<1, 16, 0, 1, 1, 1>, T_DrawRBG<1, 16, 0, 1, 1, 2>, T_DrawRBG<1, 16, 0, 1, 1, 3>, }, { T_DrawRBG<1, 16, 0, 1, 2, 0>, T_DrawRBG<1, 16, 0, 1, 2, 1>, T_DrawRBG<1, 16, 0, 1, 2, 2>, T_DrawRBG<1, 16, 0, 1, 2, 3>, }, }, }, + { { { T_DrawRBG<1, 16, 1, 0, 0, 0>, T_DrawRBG<1, 16, 1, 0, 0, 1>, T_DrawRBG<1, 16, 1, 0, 0, 2>, T_DrawRBG<1, 16, 1, 0, 0, 3>, }, { T_DrawRBG<1, 16, 1, 0, 1, 0>, T_DrawRBG<1, 16, 1, 0, 1, 1>, T_DrawRBG<1, 16, 1, 0, 1, 2>, T_DrawRBG<1, 16, 1, 0, 1, 3>, }, { T_DrawRBG<1, 16, 1, 0, 2, 0>, T_DrawRBG<1, 16, 1, 0, 2, 1>, T_DrawRBG<1, 16, 1, 0, 2, 2>, T_DrawRBG<1, 16, 1, 0, 2, 3>, }, }, { { T_DrawRBG<1, 16, 1, 1, 0, 0>, T_DrawRBG<1, 16, 1, 1, 0, 1>, T_DrawRBG<1, 16, 1, 1, 0, 2>, T_DrawRBG<1, 16, 1, 1, 0, 3>, }, { T_DrawRBG<1, 16, 1, 1, 1, 0>, T_DrawRBG<1, 16, 1, 1, 1, 1>, T_DrawRBG<1, 16, 1, 1, 1, 2>, T_DrawRBG<1, 16, 1, 1, 1, 3>, }, { T_DrawRBG<1, 16, 1, 1, 2, 0>, T_DrawRBG<1, 16, 1, 1, 2, 1>, T_DrawRBG<1, 16, 1, 1, 2, 2>, T_DrawRBG<1, 16, 1, 1, 2, 3>, }, }, }, + { { { T_DrawRBG<1, 32, 1, 0, 0, 0>, T_DrawRBG<1, 32, 1, 0, 0, 1>, T_DrawRBG<1, 32, 1, 0, 0, 2>, T_DrawRBG<1, 32, 1, 0, 0, 3>, }, { T_DrawRBG<1, 32, 1, 0, 1, 0>, T_DrawRBG<1, 32, 1, 0, 1, 1>, T_DrawRBG<1, 32, 1, 0, 1, 2>, T_DrawRBG<1, 32, 1, 0, 1, 3>, }, { T_DrawRBG<1, 32, 1, 0, 2, 0>, T_DrawRBG<1, 32, 1, 0, 2, 1>, T_DrawRBG<1, 32, 1, 0, 2, 2>, T_DrawRBG<1, 32, 1, 0, 2, 3>, }, }, { { T_DrawRBG<1, 32, 1, 1, 0, 0>, T_DrawRBG<1, 32, 1, 1, 0, 1>, T_DrawRBG<1, 32, 1, 1, 0, 2>, T_DrawRBG<1, 32, 1, 1, 0, 3>, }, { T_DrawRBG<1, 32, 1, 1, 1, 0>, T_DrawRBG<1, 32, 1, 1, 1, 1>, T_DrawRBG<1, 32, 1, 1, 1, 2>, T_DrawRBG<1, 32, 1, 1, 1, 3>, }, { T_DrawRBG<1, 32, 1, 1, 2, 0>, T_DrawRBG<1, 32, 1, 1, 2, 1>, T_DrawRBG<1, 32, 1, 1, 2, 2>, T_DrawRBG<1, 32, 1, 1, 2, 3>, }, }, }, + } +}; + +template +static INLINE void Doubleize(T* ptr, const int orig_len) +{ + for(int i = orig_len - 1; MDFN_LIKELY(i >= 0); i--) + { + auto tmp = *(ptr + i); + + *(ptr + (i << 1) + 0) = tmp; + *(ptr + (i << 1) + 1) = tmp; + } +} + +static void RBGPP(const unsigned layer, uint64* buf, const unsigned rbg_w) +{ + ApplyHMosaic(layer, buf, rbg_w); + + for(unsigned i = 0; i < rbg_w; i++) + { + uint64 tmp = buf[i]; + + if(LB.rotabsel[i]) + tmp &= ~(uint64)0xFFFFFFFF; + + buf[i] = tmp; + } + + if(HRes & 0x2) + Doubleize(buf, rbg_w); + + ApplyWin(layer, buf); +} + +// Call before DrawSpriteData() +static INLINE void MakeSpriteCCLUT(void) +{ + const bool cce = ((CCCTL >> 6) & 1); + + for(unsigned pr = 0; pr < 8; pr++) + { + bool mask = false; + + switch(SpriteCCCond) + { + case 0: mask = (SpritePrioNum[pr] <= SpriteCCNum); break; + case 1: mask = (SpritePrioNum[pr] == SpriteCCNum); break; + case 2: mask = (SpritePrioNum[pr] >= SpriteCCNum); break; + } + SpriteCCLUT[pr] = (cce & mask) << PIX_CCE_SHIFT; + } + + SpriteCC3Mask = 0; + if(SpriteCCCond == 3 && cce) + SpriteCC3Mask = 1U << PIX_CCE_SHIFT; +} + +template +static void T_DrawSpriteData(const uint16* vdp1sb, const bool vdp1_hires8, unsigned w) +{ + const unsigned SpriteType = (TA_SPCTL_Low & 0xF); + const bool SpriteWinEn = (TA_SPCTL_Low & 0x10); + const bool SpriteColorMode = (TA_SPCTL_Low & 0x20); + // + const size_t cao = CRAMAddrOffs_Sprite << 8; + uint32 spix_base_or = 0; + + spix_base_or |= ((ColorOffsEn >> 6) & 1) << PIX_COE_SHIFT; + spix_base_or |= ((ColorOffsSel >> 6) & 1) << PIX_COSEL_SHIFT; + spix_base_or |= ((LineColorEn >> 5/*5 here, not 6*/) & 1) << PIX_LCE_SHIFT; + spix_base_or |= (((CCCTL >> 12) & 0x7) == 0x0) << PIX_GRAD_SHIFT; + spix_base_or |= ((CCCTL >> 6) & 1) << PIX_LAYER_CCE_SHIFT; + + for(unsigned i = 0; MDFN_LIKELY(i < w); i++) + { + unsigned src; + unsigned pr = 0, cc = 0; + bool tp = false; + uint64 spix; + + src = vdp1sb[i >> TA_HiRes]; + + if(vdp1_hires8) + { + if(TA_HiRes) + src = 0xFF00 | (src >> (((i & 1) ^ 1) << 3)); + else + src = 0xFF00 | (src >> 8); + } + + if(SpriteColorMode && (src & 0x8000)) + { + spix = (uint64)rgb15_to_rgb24(src) << PIX_RGB_SHIFT; + spix |= 1U << PIX_ISRGB_SHIFT; + spix |= SpriteCC3Mask; + + if(SpriteType & 0x8) + tp = !(src & 0xFF); + else if(SpriteWinEn) + { + if(SpriteType >= 0x2 && SpriteType <= 0x7) + tp = !(src & 0x7FFF); + } + } + else + { + bool nshad = false; + bool sd = false; + unsigned dc; + + if(SpriteType & 0x8) + src &= 0xFF; + + tp = !src; + + switch(SpriteType) + { + case 0x0: + pr = (src >> 14) & 0x3; + cc = (src >> 11) & 0x7; + dc = src & 0x7FF; + nshad = (dc == 0x7FE); + break; + + case 0x1: + pr = (src >> 13) & 0x7; + cc = (src >> 11) & 0x3; + dc = src & 0x7FF; + nshad = (dc == 0x7FE); + break; + + case 0x2: + sd = (src >> 15) & 0x1; + pr = (src >> 14) & 0x1; + cc = (src >> 11) & 0x7; + dc = src & 0x7FF; + nshad = (dc == 0x7FE); + break; + + case 0x3: + sd = (src >> 15) & 0x1; + pr = (src >> 13) & 0x3; + cc = (src >> 11) & 0x3; + dc = src & 0x7FF; + nshad = (dc == 0x7FE); + break; + + case 0x4: + sd = (src >> 15) & 0x1; + pr = (src >> 13) & 0x3; + cc = (src >> 10) & 0x7; + dc = src & 0x3FF; + nshad = (dc == 0x3FE); + break; + + case 0x5: + sd = (src >> 15) & 0x1; + pr = (src >> 12) & 0x7; + cc = (src >> 11) & 0x1; + dc = src & 0x7FF; + nshad = (dc == 0x7FE); + break; + + case 0x6: + sd = (src >> 15) & 0x1; + pr = (src >> 12) & 0x7; + cc = (src >> 10) & 0x3; + dc = src & 0x3FF; + nshad = (dc == 0x3FE); + break; + + case 0x7: + sd = (src >> 15) & 0x1; + pr = (src >> 12) & 0x7; + cc = (src >> 9) & 0x7; + dc = src & 0x1FF; + nshad = (dc == 0x1FE); + break; + // + // + // + case 0x8: + pr = (src >> 7) & 0x1; + dc = src & 0x7F; + nshad = (dc == 0x7E); + break; + + case 0x9: + pr = (src >> 7) & 0x1; + cc = (src >> 6) & 0x1; + dc = src & 0x3F; + nshad = (dc == 0x3E); + break; + + case 0xA: + pr = (src >> 6) & 0x3; + dc = src & 0x3F; + nshad = (dc == 0x3E); + break; + + case 0xB: + cc = (src >> 6) & 0x3; + dc = src & 0x3F; + nshad = (dc == 0x3E); + break; + // + case 0xC: + pr = (src >> 7) & 0x1; + dc = src & 0xFF; + nshad = (dc == 0xFE); + break; + + case 0xD: + pr = (src >> 7) & 0x1; + cc = (src >> 6) & 0x1; + dc = src & 0xFF; + nshad = (dc == 0xFE); + break; + + case 0xE: + pr = (src >> 6) & 0x3; + dc = src & 0xFF; + nshad = (dc == 0xFE); + break; + + case 0xF: + cc = (src >> 6) & 0x3; + dc = src & 0xFF; + nshad = (dc == 0xFE); + break; + } + // + // + // + uint32 rgb24 = ColorCache[(cao + dc) & 0x7FF]; + + spix = (uint64)rgb24 << PIX_RGB_SHIFT; + + spix |= ((int32)rgb24 >> 31) & SpriteCC3Mask; + + if(SpriteWinEn) // Sprite window enable + spix |= ((uint64)sd << PIX_SWBIT_SHIFT); + + if(nshad) + spix |= 1 << PIX_DOSHAD_SHIFT; + else + { + if(SpriteWinEn) + { + if(SpriteType >= 0x2 && SpriteType <= 0x7) + tp = !(src & 0x7FFF); + } + else if(sd) + { + if(src & 0x7FFF) + spix |= 1 << PIX_SELFSHAD_SHIFT; + else if(TA_TPShadSel) + spix |= 1 << PIX_DOSHAD_SHIFT; + else + tp = true; + } + } + } + + spix |= spix_base_or; + spix |= (tp ? 0 : SpritePrioNum[pr]) << PIX_PRIO_SHIFT; + spix |= SpriteCCRatio[cc] << PIX_CCRATIO_SHIFT; + spix |= SpriteCCLUT[pr]; + + LB.spr[i] = spix; + } +} + +static void (*DrawSpriteData[2][2][0x40])(const uint16* vdp1sb, const bool vdp1_hires8, unsigned w) = +{ + { + { T_DrawSpriteData<0, 0, 0x00>, T_DrawSpriteData<0, 0, 0x01>, T_DrawSpriteData<0, 0, 0x02>, T_DrawSpriteData<0, 0, 0x03>, T_DrawSpriteData<0, 0, 0x04>, T_DrawSpriteData<0, 0, 0x05>, T_DrawSpriteData<0, 0, 0x06>, T_DrawSpriteData<0, 0, 0x07>, T_DrawSpriteData<0, 0, 0x08>, T_DrawSpriteData<0, 0, 0x09>, T_DrawSpriteData<0, 0, 0x0a>, T_DrawSpriteData<0, 0, 0x0b>, T_DrawSpriteData<0, 0, 0x0c>, T_DrawSpriteData<0, 0, 0x0d>, T_DrawSpriteData<0, 0, 0x0e>, T_DrawSpriteData<0, 0, 0x0f>, T_DrawSpriteData<0, 0, 0x10>, T_DrawSpriteData<0, 0, 0x11>, T_DrawSpriteData<0, 0, 0x12>, T_DrawSpriteData<0, 0, 0x13>, T_DrawSpriteData<0, 0, 0x14>, T_DrawSpriteData<0, 0, 0x15>, T_DrawSpriteData<0, 0, 0x16>, T_DrawSpriteData<0, 0, 0x17>, T_DrawSpriteData<0, 0, 0x18>, T_DrawSpriteData<0, 0, 0x19>, T_DrawSpriteData<0, 0, 0x1a>, T_DrawSpriteData<0, 0, 0x1b>, T_DrawSpriteData<0, 0, 0x1c>, T_DrawSpriteData<0, 0, 0x1d>, T_DrawSpriteData<0, 0, 0x1e>, T_DrawSpriteData<0, 0, 0x1f>, T_DrawSpriteData<0, 0, 0x20>, T_DrawSpriteData<0, 0, 0x21>, T_DrawSpriteData<0, 0, 0x22>, T_DrawSpriteData<0, 0, 0x23>, T_DrawSpriteData<0, 0, 0x24>, T_DrawSpriteData<0, 0, 0x25>, T_DrawSpriteData<0, 0, 0x26>, T_DrawSpriteData<0, 0, 0x27>, T_DrawSpriteData<0, 0, 0x28>, T_DrawSpriteData<0, 0, 0x29>, T_DrawSpriteData<0, 0, 0x2a>, T_DrawSpriteData<0, 0, 0x2b>, T_DrawSpriteData<0, 0, 0x2c>, T_DrawSpriteData<0, 0, 0x2d>, T_DrawSpriteData<0, 0, 0x2e>, T_DrawSpriteData<0, 0, 0x2f>, T_DrawSpriteData<0, 0, 0x30>, T_DrawSpriteData<0, 0, 0x31>, T_DrawSpriteData<0, 0, 0x32>, T_DrawSpriteData<0, 0, 0x33>, T_DrawSpriteData<0, 0, 0x34>, T_DrawSpriteData<0, 0, 0x35>, T_DrawSpriteData<0, 0, 0x36>, T_DrawSpriteData<0, 0, 0x37>, T_DrawSpriteData<0, 0, 0x38>, T_DrawSpriteData<0, 0, 0x39>, T_DrawSpriteData<0, 0, 0x3a>, T_DrawSpriteData<0, 0, 0x3b>, T_DrawSpriteData<0, 0, 0x3c>, T_DrawSpriteData<0, 0, 0x3d>, T_DrawSpriteData<0, 0, 0x3e>, T_DrawSpriteData<0, 0, 0x3f> }, + { T_DrawSpriteData<0, 1, 0x00>, T_DrawSpriteData<0, 1, 0x01>, T_DrawSpriteData<0, 1, 0x02>, T_DrawSpriteData<0, 1, 0x03>, T_DrawSpriteData<0, 1, 0x04>, T_DrawSpriteData<0, 1, 0x05>, T_DrawSpriteData<0, 1, 0x06>, T_DrawSpriteData<0, 1, 0x07>, T_DrawSpriteData<0, 1, 0x08>, T_DrawSpriteData<0, 1, 0x09>, T_DrawSpriteData<0, 1, 0x0a>, T_DrawSpriteData<0, 1, 0x0b>, T_DrawSpriteData<0, 1, 0x0c>, T_DrawSpriteData<0, 1, 0x0d>, T_DrawSpriteData<0, 1, 0x0e>, T_DrawSpriteData<0, 1, 0x0f>, T_DrawSpriteData<0, 1, 0x10>, T_DrawSpriteData<0, 1, 0x11>, T_DrawSpriteData<0, 1, 0x12>, T_DrawSpriteData<0, 1, 0x13>, T_DrawSpriteData<0, 1, 0x14>, T_DrawSpriteData<0, 1, 0x15>, T_DrawSpriteData<0, 1, 0x16>, T_DrawSpriteData<0, 1, 0x17>, T_DrawSpriteData<0, 1, 0x18>, T_DrawSpriteData<0, 1, 0x19>, T_DrawSpriteData<0, 1, 0x1a>, T_DrawSpriteData<0, 1, 0x1b>, T_DrawSpriteData<0, 1, 0x1c>, T_DrawSpriteData<0, 1, 0x1d>, T_DrawSpriteData<0, 1, 0x1e>, T_DrawSpriteData<0, 1, 0x1f>, T_DrawSpriteData<0, 1, 0x20>, T_DrawSpriteData<0, 1, 0x21>, T_DrawSpriteData<0, 1, 0x22>, T_DrawSpriteData<0, 1, 0x23>, T_DrawSpriteData<0, 1, 0x24>, T_DrawSpriteData<0, 1, 0x25>, T_DrawSpriteData<0, 1, 0x26>, T_DrawSpriteData<0, 1, 0x27>, T_DrawSpriteData<0, 1, 0x28>, T_DrawSpriteData<0, 1, 0x29>, T_DrawSpriteData<0, 1, 0x2a>, T_DrawSpriteData<0, 1, 0x2b>, T_DrawSpriteData<0, 1, 0x2c>, T_DrawSpriteData<0, 1, 0x2d>, T_DrawSpriteData<0, 1, 0x2e>, T_DrawSpriteData<0, 1, 0x2f>, T_DrawSpriteData<0, 1, 0x30>, T_DrawSpriteData<0, 1, 0x31>, T_DrawSpriteData<0, 1, 0x32>, T_DrawSpriteData<0, 1, 0x33>, T_DrawSpriteData<0, 1, 0x34>, T_DrawSpriteData<0, 1, 0x35>, T_DrawSpriteData<0, 1, 0x36>, T_DrawSpriteData<0, 1, 0x37>, T_DrawSpriteData<0, 1, 0x38>, T_DrawSpriteData<0, 1, 0x39>, T_DrawSpriteData<0, 1, 0x3a>, T_DrawSpriteData<0, 1, 0x3b>, T_DrawSpriteData<0, 1, 0x3c>, T_DrawSpriteData<0, 1, 0x3d>, T_DrawSpriteData<0, 1, 0x3e>, T_DrawSpriteData<0, 1, 0x3f> }, + }, + { + { T_DrawSpriteData<1, 0, 0x00>, T_DrawSpriteData<1, 0, 0x01>, T_DrawSpriteData<1, 0, 0x02>, T_DrawSpriteData<1, 0, 0x03>, T_DrawSpriteData<1, 0, 0x04>, T_DrawSpriteData<1, 0, 0x05>, T_DrawSpriteData<1, 0, 0x06>, T_DrawSpriteData<1, 0, 0x07>, T_DrawSpriteData<1, 0, 0x08>, T_DrawSpriteData<1, 0, 0x09>, T_DrawSpriteData<1, 0, 0x0a>, T_DrawSpriteData<1, 0, 0x0b>, T_DrawSpriteData<1, 0, 0x0c>, T_DrawSpriteData<1, 0, 0x0d>, T_DrawSpriteData<1, 0, 0x0e>, T_DrawSpriteData<1, 0, 0x0f>, T_DrawSpriteData<1, 0, 0x10>, T_DrawSpriteData<1, 0, 0x11>, T_DrawSpriteData<1, 0, 0x12>, T_DrawSpriteData<1, 0, 0x13>, T_DrawSpriteData<1, 0, 0x14>, T_DrawSpriteData<1, 0, 0x15>, T_DrawSpriteData<1, 0, 0x16>, T_DrawSpriteData<1, 0, 0x17>, T_DrawSpriteData<1, 0, 0x18>, T_DrawSpriteData<1, 0, 0x19>, T_DrawSpriteData<1, 0, 0x1a>, T_DrawSpriteData<1, 0, 0x1b>, T_DrawSpriteData<1, 0, 0x1c>, T_DrawSpriteData<1, 0, 0x1d>, T_DrawSpriteData<1, 0, 0x1e>, T_DrawSpriteData<1, 0, 0x1f>, T_DrawSpriteData<1, 0, 0x20>, T_DrawSpriteData<1, 0, 0x21>, T_DrawSpriteData<1, 0, 0x22>, T_DrawSpriteData<1, 0, 0x23>, T_DrawSpriteData<1, 0, 0x24>, T_DrawSpriteData<1, 0, 0x25>, T_DrawSpriteData<1, 0, 0x26>, T_DrawSpriteData<1, 0, 0x27>, T_DrawSpriteData<1, 0, 0x28>, T_DrawSpriteData<1, 0, 0x29>, T_DrawSpriteData<1, 0, 0x2a>, T_DrawSpriteData<1, 0, 0x2b>, T_DrawSpriteData<1, 0, 0x2c>, T_DrawSpriteData<1, 0, 0x2d>, T_DrawSpriteData<1, 0, 0x2e>, T_DrawSpriteData<1, 0, 0x2f>, T_DrawSpriteData<1, 0, 0x30>, T_DrawSpriteData<1, 0, 0x31>, T_DrawSpriteData<1, 0, 0x32>, T_DrawSpriteData<1, 0, 0x33>, T_DrawSpriteData<1, 0, 0x34>, T_DrawSpriteData<1, 0, 0x35>, T_DrawSpriteData<1, 0, 0x36>, T_DrawSpriteData<1, 0, 0x37>, T_DrawSpriteData<1, 0, 0x38>, T_DrawSpriteData<1, 0, 0x39>, T_DrawSpriteData<1, 0, 0x3a>, T_DrawSpriteData<1, 0, 0x3b>, T_DrawSpriteData<1, 0, 0x3c>, T_DrawSpriteData<1, 0, 0x3d>, T_DrawSpriteData<1, 0, 0x3e>, T_DrawSpriteData<1, 0, 0x3f> }, + { T_DrawSpriteData<1, 1, 0x00>, T_DrawSpriteData<1, 1, 0x01>, T_DrawSpriteData<1, 1, 0x02>, T_DrawSpriteData<1, 1, 0x03>, T_DrawSpriteData<1, 1, 0x04>, T_DrawSpriteData<1, 1, 0x05>, T_DrawSpriteData<1, 1, 0x06>, T_DrawSpriteData<1, 1, 0x07>, T_DrawSpriteData<1, 1, 0x08>, T_DrawSpriteData<1, 1, 0x09>, T_DrawSpriteData<1, 1, 0x0a>, T_DrawSpriteData<1, 1, 0x0b>, T_DrawSpriteData<1, 1, 0x0c>, T_DrawSpriteData<1, 1, 0x0d>, T_DrawSpriteData<1, 1, 0x0e>, T_DrawSpriteData<1, 1, 0x0f>, T_DrawSpriteData<1, 1, 0x10>, T_DrawSpriteData<1, 1, 0x11>, T_DrawSpriteData<1, 1, 0x12>, T_DrawSpriteData<1, 1, 0x13>, T_DrawSpriteData<1, 1, 0x14>, T_DrawSpriteData<1, 1, 0x15>, T_DrawSpriteData<1, 1, 0x16>, T_DrawSpriteData<1, 1, 0x17>, T_DrawSpriteData<1, 1, 0x18>, T_DrawSpriteData<1, 1, 0x19>, T_DrawSpriteData<1, 1, 0x1a>, T_DrawSpriteData<1, 1, 0x1b>, T_DrawSpriteData<1, 1, 0x1c>, T_DrawSpriteData<1, 1, 0x1d>, T_DrawSpriteData<1, 1, 0x1e>, T_DrawSpriteData<1, 1, 0x1f>, T_DrawSpriteData<1, 1, 0x20>, T_DrawSpriteData<1, 1, 0x21>, T_DrawSpriteData<1, 1, 0x22>, T_DrawSpriteData<1, 1, 0x23>, T_DrawSpriteData<1, 1, 0x24>, T_DrawSpriteData<1, 1, 0x25>, T_DrawSpriteData<1, 1, 0x26>, T_DrawSpriteData<1, 1, 0x27>, T_DrawSpriteData<1, 1, 0x28>, T_DrawSpriteData<1, 1, 0x29>, T_DrawSpriteData<1, 1, 0x2a>, T_DrawSpriteData<1, 1, 0x2b>, T_DrawSpriteData<1, 1, 0x2c>, T_DrawSpriteData<1, 1, 0x2d>, T_DrawSpriteData<1, 1, 0x2e>, T_DrawSpriteData<1, 1, 0x2f>, T_DrawSpriteData<1, 1, 0x30>, T_DrawSpriteData<1, 1, 0x31>, T_DrawSpriteData<1, 1, 0x32>, T_DrawSpriteData<1, 1, 0x33>, T_DrawSpriteData<1, 1, 0x34>, T_DrawSpriteData<1, 1, 0x35>, T_DrawSpriteData<1, 1, 0x36>, T_DrawSpriteData<1, 1, 0x37>, T_DrawSpriteData<1, 1, 0x38>, T_DrawSpriteData<1, 1, 0x39>, T_DrawSpriteData<1, 1, 0x3a>, T_DrawSpriteData<1, 1, 0x3b>, T_DrawSpriteData<1, 1, 0x3c>, T_DrawSpriteData<1, 1, 0x3d>, T_DrawSpriteData<1, 1, 0x3e>, T_DrawSpriteData<1, 1, 0x3f> }, + } +}; + +// Don't change these constants without also updating the template variable +// setup for the call into MixIt(and the contents of MixIt itself...). +enum +{ + MIXIT_SPECIAL_NONE = 0x0, + MIXIT_SPECIAL_GRAD = 0x1, + MIXIT_SPECIAL_EXCC_CRAM0 = 0x2, + MIXIT_SPECIAL_EXCC_CRAM12 = 0x3, + MIXIT_SPECIAL_EXCC_LINE_CRAM0 = 0x4, + MIXIT_SPECIAL_EXCC_LINE_CRAM12 = 0x5 +}; + +template +static void T_MixIt(uint32* target, const unsigned vdp2_line, const unsigned w, const uint32 back_rgb24, const uint64* blursrc) +{ + //printf("MixIt: %d, %d, %d, %d\n", TA_rbg1en, TA_Special, TA_CCRTMD, TA_CCMD); + const uint32* lclut = &ColorCache[CurLCColor &~ 0x7F]; + uint32 blurprev[2]; + + if(TA_Special == MIXIT_SPECIAL_GRAD) + blurprev[0] = blurprev[1] = *blursrc >> PIX_RGB_SHIFT; + + uint32 line_pix_l; + { + line_pix_l = 0U << PIX_ISRGB_SHIFT; + line_pix_l |= LineColorCCRatio << PIX_CCRATIO_SHIFT; + line_pix_l |= ((CCCTL >> 5) & 1) << PIX_CCE_SHIFT; + line_pix_l |= ((CCCTL >> 5) & 1) << PIX_LAYER_CCE_SHIFT; + } + + // + // + uint64 back_pix; + { + back_pix = (uint64)back_rgb24 << PIX_RGB_SHIFT; + back_pix |= 1U << PIX_ISRGB_SHIFT; + back_pix |= ((ColorOffsEn >> 5) & 1) << PIX_COE_SHIFT; + back_pix |= ((ColorOffsSel >> 5) & 1) << PIX_COSEL_SHIFT; + back_pix |= ((SDCTL >> 5) & 1) << PIX_SHADEN_SHIFT; + back_pix |= BackCCRatio << PIX_CCRATIO_SHIFT; + } + + for(uint32 i = 0; MDFN_LIKELY(i < w); i++) + { + uint64 pix = back_pix; + uint32 blurcake; + + // + // Listed from lowest priority to greatest priority when prio levels are equal(back pixel has prio level of 0, + // and should display on "top" of any other layers). + // + uint64 tmp_pix[8] = + { + (TA_rbg1en ? 0 : (LB.nbg[3] + 8)[i]), + (TA_rbg1en ? 0 : (LB.nbg[2] + 8)[i]), + (TA_rbg1en ? 0 : (LB.nbg[1] + 8)[i]), + (LB.nbg[0] + 8)[i], + LB.rbg0[i], + LB.spr[i], + 0/*null pixel*/, + back_pix + }; + uint64 pt; + unsigned st; + + pt = 0x01ULL << (uint8)(tmp_pix[0] >> PIX_PRIO_TEST_SHIFT); + pt |= 0x02ULL << (uint8)(tmp_pix[1] >> PIX_PRIO_TEST_SHIFT); + pt |= 0x04ULL << (uint8)(tmp_pix[2] >> PIX_PRIO_TEST_SHIFT); + pt |= 0x08ULL << (uint8)(tmp_pix[3] >> PIX_PRIO_TEST_SHIFT); + pt |= 0x10ULL << (uint8)(tmp_pix[4] >> PIX_PRIO_TEST_SHIFT); + pt |= 0x20ULL << (uint8)(tmp_pix[5] >> PIX_PRIO_TEST_SHIFT); + pt |= 0xC0ULL; // Back pixel(0x80) and null pixel(0x40) + + st = 63 ^ MDFN_lzcount64_0UD(pt); + pt ^= 1ULL << st; + pt |= 0x40; // Restore the null! + pix = tmp_pix[st & 0x7]; + + if(pix & (1U << PIX_DOSHAD_SHIFT)) + { + st = 63 ^ MDFN_lzcount64_0UD(pt); + pt ^= 1ULL << st; + pt |= 0x40; // Restore the null! + pix = tmp_pix[st & 0x7]; + pix |= (1U << PIX_DOSHAD_SHIFT); + } + + if(TA_Special == MIXIT_SPECIAL_GRAD) + { + const uint32 blurpie = blursrc[i] >> PIX_RGB_SHIFT; + + blurcake = ((blurprev[0] + blurprev[1]) - ((blurprev[0] ^ blurprev[1]) & 0x01010101)) >> 1; + blurcake = ((blurcake + blurpie) - ((blurcake ^ blurpie) & 0x01010101)) >> 1; + blurprev[0] = blurprev[1]; + blurprev[1] = blurpie; + } + + // + // Color calculation + // + if(pix & (1U << PIX_CCE_SHIFT)) + { + uint64 pix2, pix3; + + st = 63 ^ MDFN_lzcount64_0UD(pt); + pt ^= 1ULL << st; + pt |= 0x40; // Restore the null! + pix2 = tmp_pix[st & 0x7]; + + st = 63 ^ MDFN_lzcount64_0UD(pt); + pt ^= 1ULL << st; + pt |= 0x40; // Restore the null! + pix3 = tmp_pix[st & 0x7]; + + if(TA_Special == MIXIT_SPECIAL_GRAD) + { + if((pix | pix2) & (1U << PIX_GRAD_SHIFT)) + pix2 = (uint32)pix2 | ((uint64)blurcake << PIX_RGB_SHIFT); // Be sure to preserve the color calc ratio, at least. + } + else if(pix & (1U << PIX_LCE_SHIFT)) + { + // + // Line color + // + const uint64 pix4 = pix3; + const uint32 line_pix_rgb = lclut[LB.lc[i]]; + pix3 = pix2; + pix2 = line_pix_l | ((uint64)line_pix_rgb << PIX_RGB_SHIFT); + + if(TA_Special == MIXIT_SPECIAL_EXCC_LINE_CRAM0) + { + uint32 sec_rgb = line_pix_rgb; + uint32 third_rgb = (pix3 >> PIX_RGB_SHIFT); + + if(pix3 & (1U << PIX_LAYER_CCE_SHIFT)) + third_rgb = (third_rgb >> 1) & 0x7F7F7F; + + sec_rgb = ((sec_rgb + third_rgb) - ((sec_rgb ^ third_rgb) & 0x01010101)) >> 1; + pix2 = (uint32)pix2 | ((uint64)sec_rgb << PIX_RGB_SHIFT); + } + else if(TA_Special == MIXIT_SPECIAL_EXCC_LINE_CRAM12) + { + uint32 sec_rgb = line_pix_rgb; + uint32 third_rgb = (pix3 >> PIX_RGB_SHIFT); + + if(pix3 & (1U << PIX_ISRGB_SHIFT)) + { + if((pix3 & (1U << PIX_LAYER_CCE_SHIFT)) && (pix4 & (1U << PIX_ISRGB_SHIFT))) + { + const uint32 fourth_rgb = (pix4 >> PIX_RGB_SHIFT); + third_rgb = ((third_rgb + fourth_rgb) - ((third_rgb ^ fourth_rgb) & 0x01010101)) >> 1; + } + + sec_rgb = ((sec_rgb + third_rgb) - ((sec_rgb ^ third_rgb) & 0x01010101)) >> 1; + pix2 = (uint32)pix2 | ((uint64)sec_rgb << PIX_RGB_SHIFT); + } + } + } + else + { + if(TA_Special == MIXIT_SPECIAL_EXCC_CRAM0 || TA_Special == MIXIT_SPECIAL_EXCC_CRAM12 || TA_Special == MIXIT_SPECIAL_EXCC_LINE_CRAM0 || TA_Special == MIXIT_SPECIAL_EXCC_LINE_CRAM12) + { + if(pix2 & (1U << PIX_LAYER_CCE_SHIFT)) + { + if(TA_Special == MIXIT_SPECIAL_EXCC_CRAM0 || TA_Special == MIXIT_SPECIAL_EXCC_LINE_CRAM0 || (pix3 & (1U << PIX_ISRGB_SHIFT))) + { + uint32 sec_rgb = pix2 >> PIX_RGB_SHIFT; + const uint32 third_rgb = (pix3 >> PIX_RGB_SHIFT); + + sec_rgb = ((sec_rgb + third_rgb) - ((sec_rgb ^ third_rgb) & 0x01010101)) >> 1; + pix2 = (uint32)pix2 | ((uint64)sec_rgb << PIX_RGB_SHIFT); + } + } + } + } + + uint32 fore_rgb = pix >> PIX_RGB_SHIFT; + uint32 sec_rgb = pix2 >> PIX_RGB_SHIFT; + uint32 new_rgb; + + if(TA_CCMD) // Ignore ratio, add as-is. + { + new_rgb = std::min(0x0000FF, (fore_rgb & 0x0000FF) + (sec_rgb & 0x0000FF)); + new_rgb |= std::min(0x00FF00, (fore_rgb & 0x00FF00) + (sec_rgb & 0x00FF00)); + new_rgb |= std::min(0xFF0000, (fore_rgb & 0xFF0000) + (sec_rgb & 0xFF0000)); + } + else + { + unsigned fore_ratio = ((uint32)(TA_CCRTMD ? pix2 : pix) >> PIX_CCRATIO_SHIFT) ^ 0x1F; + unsigned sec_ratio = 0x20 - fore_ratio; + + new_rgb = ((((fore_rgb & 0x0000FF) * fore_ratio) + ((sec_rgb & 0x0000FF) * sec_ratio)) >> 5); + new_rgb |= ((((fore_rgb & 0x00FF00) * fore_ratio) + ((sec_rgb & 0x00FF00) * sec_ratio)) >> 5) & 0x00FF00; + new_rgb |= ((((fore_rgb & 0xFF0000) * fore_ratio) + ((sec_rgb & 0xFF0000) * sec_ratio)) >> 5) & 0xFF0000; + } + pix = ((uint64)new_rgb << 32) | (uint32)pix; + } + + // + // Color offset + // + if(pix & (1U << PIX_COE_SHIFT)) + { + const unsigned sel = (pix >> PIX_COSEL_SHIFT) & 1; + const uint32 rgb_tmp = pix >> PIX_RGB_SHIFT; + int32 rt, gt, bt; + + rt = ColorOffs[sel][0] + (rgb_tmp & 0x000000FF); + if(rt < 0) rt = 0; + if(rt & 0x00000100) rt = 0x000000FF; + + gt = ColorOffs[sel][1] + (rgb_tmp & 0x0000FF00); + if(gt < 0) gt = 0; + if(gt & 0x00010000) gt = 0x0000FF00; + + bt = ColorOffs[sel][2] + (rgb_tmp & 0x00FF0000); + if(bt < 0) bt = 0; + if(bt & 0x01000000) bt = 0x00FF0000; + + pix = (uint32)pix | ((uint64)(uint32)(rt | gt | bt) << PIX_RGB_SHIFT); + } + + // + // Sprite shadow + // + if((uint8)pix >= PIX_SHADHALVTEST8_VAL) + pix = (uint32)pix | ((pix >> 1) & 0x7F7F7F00000000ULL); + + target[i] = pix >> PIX_RGB_SHIFT; + } +} + +//template +static void (*MixIt[2][6][2][2])(uint32* target, const unsigned vdp2_line, const unsigned w, const uint32 back_rgb24, const uint64* blursrc) = +{ + { { { T_MixIt<0, 0, 0, 0>, T_MixIt<0, 0, 0, 1>, }, { T_MixIt<0, 0, 1, 0>, T_MixIt<0, 0, 1, 1>, }, }, { { T_MixIt<0, 1, 0, 0>, T_MixIt<0, 1, 0, 1>, }, { T_MixIt<0, 1, 1, 0>, T_MixIt<0, 1, 1, 1>, }, }, { { T_MixIt<0, 2, 0, 0>, T_MixIt<0, 2, 0, 1>, }, { T_MixIt<0, 2, 1, 0>, T_MixIt<0, 2, 1, 1>, }, }, { { T_MixIt<0, 3, 0, 0>, T_MixIt<0, 3, 0, 1>, }, { T_MixIt<0, 3, 1, 0>, T_MixIt<0, 3, 1, 1>, }, }, { { T_MixIt<0, 4, 0, 0>, T_MixIt<0, 4, 0, 1>, }, { T_MixIt<0, 4, 1, 0>, T_MixIt<0, 4, 1, 1>, }, }, { { T_MixIt<0, 5, 0, 0>, T_MixIt<0, 5, 0, 1>, }, { T_MixIt<0, 5, 1, 0>, T_MixIt<0, 5, 1, 1>, }, }, }, + { { { T_MixIt<1, 0, 0, 0>, T_MixIt<1, 0, 0, 1>, }, { T_MixIt<1, 0, 1, 0>, T_MixIt<1, 0, 1, 1>, }, }, { { T_MixIt<1, 1, 0, 0>, T_MixIt<1, 1, 0, 1>, }, { T_MixIt<1, 1, 1, 0>, T_MixIt<1, 1, 1, 1>, }, }, { { T_MixIt<1, 2, 0, 0>, T_MixIt<1, 2, 0, 1>, }, { T_MixIt<1, 2, 1, 0>, T_MixIt<1, 2, 1, 1>, }, }, { { T_MixIt<1, 3, 0, 0>, T_MixIt<1, 3, 0, 1>, }, { T_MixIt<1, 3, 1, 0>, T_MixIt<1, 3, 1, 1>, }, }, { { T_MixIt<1, 4, 0, 0>, T_MixIt<1, 4, 0, 1>, }, { T_MixIt<1, 4, 1, 0>, T_MixIt<1, 4, 1, 1>, }, }, { { T_MixIt<1, 5, 0, 0>, T_MixIt<1, 5, 0, 1>, }, { T_MixIt<1, 5, 1, 0>, T_MixIt<1, 5, 1, 1>, }, }, }, +}; + +static int32 ApplyHBlend(uint32* const target, int32 w) +{ + #define BHALF(m, n) ((((uint64)(m) + (n)) - (((m) ^ (n)) & 0x01010101)) >> 1) + + assert(w >= 4); + +#if 1 + if(!(HRes & 0x2)) + { + target[(w - 1) * 2 + 1] = target[w - 1]; + target[(w - 1) * 2 + 0] = BHALF(BHALF(target[w - 2], target[w - 1]), target[w - 1]); + + for(int32 x = w - 2; x > 0; x--) + { + uint32 ptxm1 = target[x - 1]; + uint32 ptx = target[x]; + uint32 ptxp1 = target[x + 1]; + uint32 ptxm1_ptx = BHALF(ptxm1, ptx); + uint32 ptx_ptxp1 = BHALF(ptx, ptxp1); + + target[x * 2 + 0] = BHALF(ptxm1_ptx, ptx); + target[x * 2 + 1] = BHALF(ptx_ptxp1, ptx); + } + + target[1] = BHALF(BHALF(target[0], target[1]), target[0]); + target[0] = target[0]; + + return w << 1; + } + else +#else + if(!(HRes & 0x2)) + { + for(int32 x = w - 1; x >= 0; x--) + target[x * 2 + 0] = target[x * 2 + 1] = target[x]; + + w <<= 1; + } +#endif + { + uint32 a = target[0]; + for(int32 x = 0; x < w - 1; x++) + { + uint32 b = target[x]; + uint32 c = target[x + 1]; + uint32 ac = BHALF(a, c); + uint32 bac = BHALF(b, ac); + + target[x] = bac; + a = b; + } + return w; + } + #undef BHALF +} + +static void ReorderRGB(uint32* target, const unsigned w) +{ + const unsigned Rshift = 16; + const unsigned Gshift = 8; + const unsigned Bshift = 0; + assert(!(w & 1)); + uint32* const bound = target + w; + + while(MDFN_LIKELY(target != bound)) + { + const uint32 tmp0 = target[0]; + const uint32 tmp1 = target[1]; + + target[0] = ((uint8)(tmp0 >> 0) << Rshift) | + ((uint8)(tmp0 >> 8) << Gshift) | + ((uint8)(tmp0 >> 16) << Bshift); + + target[1] = ((uint8)(tmp1 >> 0) << Rshift) | + ((uint8)(tmp1 >> 8) << Gshift) | + ((uint8)(tmp1 >> 16) << Bshift); + + target += 2; + } +} + +static NO_INLINE void DrawLine(const uint16 out_line, const uint16 vdp2_line, const bool field) +{ + uint32* target; + const int32 tvdw = ((!CorrectAspect || Clock28M) ? 352 : 330) << ((HRes & 0x2) >> 1); + const unsigned rbg_w = ((HRes & 0x1) ? 352 : 320); + const unsigned w = ((HRes & 0x1) ? 352 : 320) << ((HRes & 0x2) >> 1); + const int32 tvxo = std::max(0, (int32)(tvdw - w) >> 1); + uint32 back_rgb24; + uint32 border_ncf; + + target = espec->pixels + out_line * espec->pitch32; + espec->LineWidths[out_line] = tvdw; + + if(!ShowHOverscan) + { + const int32 ntdw = tvdw * 1024 / 1056; + const int32 tadj = std::max(0, espec->x - ((tvdw - ntdw) >> 1)); + + //if(out_line == 100) + // printf("tvdw=%d, ntdw=%d, tadj=%d --- tvdw+tadj=%d\n", tvdw, ntdw, tadj, tvdw + tadj); + + assert((tvdw + tadj) <= 704); + + target += tadj; + espec->LineWidths[out_line] = ntdw; + } + + // + // FIXME: Timing + // + if(vdp2_line == 0) + { + CurBackTabAddr = (BKTA & 0x7FFFF) + ((BKTA & 0x80000000) && InterlaceMode == IM_DOUBLE && field); + CurLCTabAddr = (LCTA & 0x7FFFF) + ((LCTA & 0x80000000) && InterlaceMode == IM_DOUBLE && field); + + for(unsigned n = 0; n < 2; n++) + { + YCoordAccum[n] = (InterlaceMode == IM_DOUBLE && field) ? YCoordInc[n] : 0; + + CurLSA[n] = LineScrollAddr[n]; + + if(InterlaceMode == IM_DOUBLE && field) + { + const uint8 sc = (SCRCTL >> (n << 3)); + + CurLSA[n] += ((bool)(sc & 0x2) + (bool)(sc & 0x4) + (bool)(sc & 0x8)) << 1; + } + // + // + NBG23_YCounter[n & 1] = YScrollI[2 + n]; + } + + for(unsigned d = 0; d < 2; d++) + { + Window[d].CurLineWinAddr = Window[d].LineWinAddr; + + if(InterlaceMode == IM_DOUBLE && field) + Window[d].CurLineWinAddr += 2; + } + + MosaicVCount = 0; + } + + if(vdp2_line != 0xFFFF) + { + CurBackColor = VRAM[CurBackTabAddr & 0x3FFFF] & 0x7FFF; + + if(BKTA & 0x80000000) + CurBackTabAddr += 1 << (InterlaceMode == IM_DOUBLE); + // + CurLCColor = VRAM[CurLCTabAddr & 0x3FFFF] & 0x07FF; + if(LCTA & 0x80000000) + CurLCTabAddr += 1 << (InterlaceMode == IM_DOUBLE); + } + + back_rgb24 = rgb15_to_rgb24(CurBackColor); + + if(BorderMode) + border_ncf = back_rgb24 & 0xff00 | back_rgb24 << 16 && 0xff0000 | back_rgb24 >> 16 & 0xff; + else + border_ncf = 0; + + if(vdp2_line == 0xFFFF) + { + for(int32 i = 0; i < tvdw; i++) + target[i] = border_ncf; + } + else + { + // + // Line scroll + // + unsigned ls_comp_line = vdp2_line; + + for(unsigned n = 0; n < 2; n++) + { + const uint8 sc = (SCRCTL >> (n << 3)); + const uint8 lss = ((sc >> 4) & 0x3); + + if((ls_comp_line & ((1 << lss) - 1)) == 0) + { + if(sc & 0x2) // X + { + CurXScrollIF[n] = (VRAM[CurLSA[n] & 0x3FFFF] & 0x7FF) << 8; + CurLSA[n]++; + CurXScrollIF[n] |= VRAM[CurLSA[n] & 0x3FFFF] >> 8; + CurLSA[n]++; + + CurXScrollIF[n] += (XScrollI[n] << 8) + XScrollF[n]; + } + + if(sc & 0x4) // Y + { + YCoordAccum[n] = 0; // Don't (InterlaceMode == IM_DOUBLE && field) + // + CurYScrollIF[n] = (VRAM[CurLSA[n] & 0x3FFFF] & 0x7FF) << 8; + CurLSA[n]++; + CurYScrollIF[n] |= VRAM[CurLSA[n] & 0x3FFFF] >> 8; + CurLSA[n]++; + + CurYScrollIF[n] += (YScrollI[n] << 8) + YScrollF[n]; + //printf("%d %d %08x: %08x \n", vdp2_line, n, CurLSA[n], CurYScrollIF[n]); + } + + if(sc & 0x8) // X zoom + { + CurXCoordInc[n] = (VRAM[CurLSA[n] & 0x3FFFF] & 0x7) << 8; + CurLSA[n]++; + CurXCoordInc[n] |= VRAM[CurLSA[n] & 0x3FFFF] >> 8; + CurLSA[n]++; + } + + if(InterlaceMode == IM_DOUBLE) + CurLSA[n] += ((bool)(sc & 0x2) + (bool)(sc & 0x4) + (bool)(sc & 0x8)) << 1; + } + + if(!(sc & 0x2)) + CurXScrollIF[n] = (XScrollI[n] << 8) + XScrollF[n]; + + if(!(sc & 0x4)) + CurYScrollIF[n] = (YScrollI[n] << 8) + YScrollF[n]; + + if(!(sc & 0x8)) + CurXCoordInc[n] = XCoordInc[n]; + } + + // + // Line Window + // + { + int32 w_ycomp_line; + + if(InterlaceMode == IM_DOUBLE) + w_ycomp_line = (vdp2_line << 1) + field; + else + w_ycomp_line = vdp2_line; + + for(unsigned d = 0; d < 2; d++) + { + int32 ys = Window[d].YStart, ye = Window[d].YEnd; + + if(Window[d].LineWinEn) + { + const uint16* vrt = &VRAM[Window[d].CurLineWinAddr & 0x3FFFE]; + + Window[d].XStart = vrt[0] & 0x3FF; + Window[d].XEnd = vrt[1] & 0x3FF; + + //printf("LWin %d, %d(%08x): %04x %04x\n", vdp2_line, d, Window[d].CurLineWinAddr & 0x3FFFE, vrt[0], vrt[1]); + } + // + // + // + int32 xs = Window[d].XStart, xe = Window[d].XEnd; + + // FIXME: Kludge, until we can figure out what's going on. + if(xs >= 0x380) + xs = 0; + + // FIXME: Kludge, until we can figure out what's going on. + if(xe >= 0x380) + { + xs = 2; + xe = 0; + } + + if(!(HRes & 0x2)) + { + xs >>= 1; + xe >>= 1; + } + Window[d].CurXStart = xs; + Window[d].CurXEnd = xe; + + Window[d].CurLineWinAddr += 2 << (InterlaceMode == IM_DOUBLE); + + if(InterlaceMode != IM_DOUBLE) + { + ys >>= 1; + ye >>= 1; + } + + Window[d].YMet = (w_ycomp_line >= Window[d].YStart) & (w_ycomp_line <= Window[d].YEnd); + // + // + // + } + + // + // + // + WinPieces[0] = Window[0].CurXStart; + WinPieces[1] = Window[0].CurXEnd + 1; + WinPieces[2] = Window[1].CurXStart; + WinPieces[3] = Window[1].CurXEnd + 1; + WinPieces[4] = w; + + for(unsigned piece = 0; piece < WinPieces.size(); piece++) + WinPieces[piece] = std::min(w, WinPieces[piece]); // Almost forgot to do this... + + std::sort(WinPieces.begin(), WinPieces.end()); + } + + // + // + // + if(vdp2_line == 64) + { + //printf("%d:%d, %d:%d (%d) --- %d:%d, %d:%d (%d)\n", Window[0].XStart, Window[0].YStart, Window[0].XEnd, Window[0].YEnd, Window[0].LineWinEn, Window[1].XStart, Window[1].YStart, Window[1].XEnd, Window[1].YEnd, Window[1].LineWinEn); + //printf("SPCTL_Low: %02x, SDCTL: %03x, SpriteCCCond: %01x, CCNum: %01x -- %01x %01x %01x %01x %01x %01x %01x %01x \n", SPCTL_Low, SDCTL, SpriteCCCond, SpriteCCNum, SpriteCCRatio[0], SpriteCCRatio[1], SpriteCCRatio[2], SpriteCCRatio[3], SpriteCCRatio[4], SpriteCCRatio[5], SpriteCCRatio[6], SpriteCCRatio[7]); + //printf("WinControl[WINLAYER_CC]=%02x\n", WinControl[WINLAYER_CC]); + } + + // + // Process sprite data before NBG0-3 and RBG0-1, but defer applying the window until after NBG and RBG are handled(so the sprite window + // bit in the sprite linebuffer data isn't trashed prematurely). + // + if(MDFN_LIKELY(UserLayerEnableMask & (1U << 6))) + { + MakeSpriteCCLUT(); + DrawSpriteData[(HRes & 0x2) >> 0x1][(SDCTL >> 8) & 0x1][SPCTL_Low](LIB[vdp2_line].vdp1_line, LIB[vdp2_line].vdp1_hires8, w); + } + else + MDFN_FastArraySet(LB.spr, 0, w); + // + // + // + // + // + // + // + if(BGON & 0x30) + { + MDFN_FastArraySet(LB.lc, CurLCColor & 0x7F, rbg_w); + SetupRotVars(LIB[vdp2_line].rv, rbg_w); + if(HRes & 0x2) + Doubleize(LB.lc, rbg_w); + + // RBG0 + if(MDFN_LIKELY(UserLayerEnableMask & 0x10)) + { + const bool igntp = (BGON >> 12) & 1; + const bool bmen = (CHCTLB >> 9) & 1; + const unsigned colornum = std::min(4, (CHCTLB >> 12) & 0x7); // TODO: Test 5 ... 7 + const unsigned priomode = (SFPRMD >> 8) & 0x3; + const unsigned ccmode = (CCCTL & 0x10) ? ((SFCCMD >> 8) & 0x3) : 0; + const uint32 prio = RBG0PrioNum; + uint32 pix_base_or; + + pix_base_or = ((colornum >= 3) << PIX_ISRGB_SHIFT); + pix_base_or |= ((ColorOffsEn >> 4) & 1) << PIX_COE_SHIFT; + pix_base_or |= ((ColorOffsSel >> 4) & 1) << PIX_COSEL_SHIFT; + pix_base_or |= ((LineColorEn >> 4) & 1) << PIX_LCE_SHIFT; + pix_base_or |= RBG0CCRatio << PIX_CCRATIO_SHIFT; + pix_base_or |= (((CCCTL >> 12) & 0x7) == 0x1) << PIX_GRAD_SHIFT; + pix_base_or |= ((CCCTL >> 4) & 1) << PIX_LAYER_CCE_SHIFT; + pix_base_or |= ((SDCTL >> 4) & 1) << PIX_SHADEN_SHIFT; + + if(ccmode == 0) + pix_base_or |= ((CCCTL >> 4) & 1) << PIX_CCE_SHIFT; + + if(priomode >= 1) + pix_base_or |= ((prio &~ 1) << PIX_PRIO_SHIFT); + else + pix_base_or |= (prio << PIX_PRIO_SHIFT); + + DrawRBG[bmen][colornum][igntp][priomode % 3][ccmode](0, LB.rbg0, rbg_w, pix_base_or); + RBGPP(4, LB.rbg0, rbg_w); + } + else + MDFN_FastArraySet(LB.rbg0, 0, w); + + // RBG1 + if(BGON & UserLayerEnableMask & 0x20) + { + const bool igntp = (BGON >> 8) & 1; + const unsigned colornum = std::min(4, (CHCTLA >> 4) & 0x7); // TODO: Test 5 ... 7 + const unsigned priomode = (SFPRMD >> 0) & 0x3; + const unsigned ccmode = (CCCTL & 0x01) ? ((SFCCMD >> 0) & 0x3) : 0; + const uint32 prio = NBGPrioNum[0]; + uint32 pix_base_or; + + pix_base_or = (false << PIX_ISRGB_SHIFT); + pix_base_or |= ((ColorOffsEn >> 0) & 1) << PIX_COE_SHIFT; + pix_base_or |= ((ColorOffsSel >> 0) & 1) << PIX_COSEL_SHIFT; + pix_base_or |= ((LineColorEn >> 0) & 1) << PIX_LCE_SHIFT; + pix_base_or |= NBGCCRatio[0] << PIX_CCRATIO_SHIFT; + pix_base_or |= (((CCCTL >> 12) & 0x7) == 0x2) << PIX_GRAD_SHIFT; + pix_base_or |= ((CCCTL >> 0) & 1) << PIX_LAYER_CCE_SHIFT; + pix_base_or |= ((SDCTL >> 0) & 1) << PIX_SHADEN_SHIFT; + + if(ccmode == 0) + pix_base_or |= ((CCCTL >> 0) & 1) << PIX_CCE_SHIFT; + + if(priomode >= 1) + pix_base_or |= ((prio &~ 1) << PIX_PRIO_SHIFT); + else + pix_base_or |= (prio << PIX_PRIO_SHIFT); + + MDFN_FastArraySet(LB.rotabsel, 1, rbg_w); + DrawRBG[false][colornum][igntp][priomode % 3][ccmode](1, LB.nbg[0] + 8, rbg_w, pix_base_or); + RBGPP(0, LB.nbg[0] + 8, rbg_w); + } + else if(BGON & 0x20) + MDFN_FastArraySet(LB.nbg[0] + 8, 0, w); + } + else + { + MDFN_FastArraySet(LB.lc, CurLCColor & 0x7F, w); + MDFN_FastArraySet(LB.rbg0, 0, w); + } + // + // + // + for(unsigned n = 0; n < 4; n++) + { + if(!MosaicVCount || !(MZCTL & (1U << n))) + { + if(n < 2) + { + MosEff_YCoordAccum[n] = YCoordAccum[n]; // Don't + (InterlaceMode == IM_DOUBLE && field) + } + else + { + MosEff_NBG23_YCounter[n & 1] = NBG23_YCounter[n & 1] + (InterlaceMode == IM_DOUBLE && field); + } + } + } + + if(SCRCTL & 0x0101) + FetchVCScroll(w); // Call after handling line scroll, and before DrawNBG() stuff + + if(!(BGON & 0x20)) + { + for(unsigned n = 0; n < 4; n++) + { + if(((BGON >> n) & 1) && MDFN_LIKELY((UserLayerEnableMask >> n) & 1)) + { + const bool igntp = (BGON >> (n + 8)) & 1; + bool bmen = false; + unsigned colornum; + unsigned priomode; + unsigned ccmode; + + if(n < 2) + { + const unsigned nshift = (n & 1) << 3; + + bmen = (CHCTLA >> (1 + nshift)) & 1; + colornum = (CHCTLA >> (4 + nshift)) & (n ? 0x3 : 0x7); + } + else // n >= 2 + { + const unsigned nshift = (n & 1) << 2; + + colornum = (CHCTLB >> (1 + nshift)) & 1; + } + + if(colornum > 4) // TODO: test 5 ... 7 + colornum = 4; + + priomode = (SFPRMD >> (n << 1)) & 0x3; + ccmode = (SFCCMD >> (n << 1)) & 0x3; + if(!((CCCTL >> n) & 1)) + ccmode = 0; + // + // + const uint32 prio = NBGPrioNum[n]; + uint32 pix_base_or; + + pix_base_or = ((colornum >= 3) << PIX_ISRGB_SHIFT); + pix_base_or |= ((ColorOffsEn >> n) & 1) << PIX_COE_SHIFT; + pix_base_or |= ((ColorOffsSel >> n) & 1) << PIX_COSEL_SHIFT; + pix_base_or |= ((LineColorEn >> n) & 1) << PIX_LCE_SHIFT; + pix_base_or |= NBGCCRatio[n] << PIX_CCRATIO_SHIFT; + pix_base_or |= (((CCCTL >> 12) & 0x7) == (3 + n - !n)) << PIX_GRAD_SHIFT; + pix_base_or |= ((CCCTL >> n) & 1) << PIX_LAYER_CCE_SHIFT; + pix_base_or |= ((SDCTL >> n) & 1) << PIX_SHADEN_SHIFT; + + if(ccmode == 0) + pix_base_or |= ((CCCTL >> n) & 1) << PIX_CCE_SHIFT; + + if(priomode >= 1) + pix_base_or |= ((prio &~ 1) << PIX_PRIO_SHIFT); + else + pix_base_or |= (prio << PIX_PRIO_SHIFT); + + if(n < 2) + DrawNBG[bmen][colornum][igntp][priomode % 3][ccmode](n, LB.nbg[n] + 8, w, pix_base_or); + else + DrawNBG23[colornum][igntp][priomode % 3][ccmode](n, LB.nbg[n] + 8, w, pix_base_or); + + ApplyHMosaic(n, LB.nbg[n] + 8, w); + ApplyWin(n, LB.nbg[n] + 8); + } + else + MDFN_FastArraySet(LB.nbg[n] + 8, 0, w); + } + } + + // + // + // + // + // + // Apply window to sprite linebuffer after BG layers have windows applied. + ApplyWin(WINLAYER_SPRITE, LB.spr); + + // + for(int32 i = 0; i < tvxo; i++) + target[i] = border_ncf; + + for(int32 i = tvxo + w; i < tvdw; i++) + target[i] = border_ncf; + + { + const bool rbg1en = (bool)(BGON & 0x20); + unsigned special = MIXIT_SPECIAL_NONE; + const bool CCRTMD = (bool)(CCCTL & 0x0200); + const bool CCMD = (bool)(CCCTL & 0x0100); + static const uint64* blurremap[8] = { LB.spr, LB.rbg0, LB.nbg[0] + 8, /*Dummy:*/LB.spr, + LB.nbg[1] + 8, LB.nbg[2] + 8, LB.nbg[3] + 8, /*Dummy:*/LB.spr + }; + const uint64* blursrc = blurremap[(CCCTL >> 12) & 0x7]; + + if(!(HRes & 0x6)) + { + if(CCCTL & 0x8000) + { + if(CRAM_Mode == 0) + special = MIXIT_SPECIAL_GRAD; + } + else if(CCCTL & 0x0400) + { + special = 0x2; + special += (bool)CRAM_Mode; + special += (CCCTL >> 4) & 0x2; + } + } + MixIt[rbg1en][special][CCRTMD][CCMD](target + tvxo, vdp2_line, w, back_rgb24, blursrc); + ReorderRGB(target + tvxo, w); + } + + // + // + // + // FIXME: Timing + // + for(unsigned n = 0; n < 2; n++) + { + YCoordAccum[n] += YCoordInc[n] << (InterlaceMode == IM_DOUBLE); + NBG23_YCounter[n & 1] += 1 << (InterlaceMode == IM_DOUBLE); + } + + if(MosaicVCount >= ((MZCTL >> 12) & 0xF)) + MosaicVCount = 0; + else + MosaicVCount++; + } + + // + // + // + if(DoHBlend) + { + espec->LineWidths[out_line] = ApplyHBlend(espec->pixels + out_line * espec->pitch32 + espec->x, espec->LineWidths[out_line]); + + // Kind of late, but meh. ;p + assert((espec->x + espec->LineWidths[out_line]) <= 704); + } +} + +enum +{ + COMMAND_WRITE8 = 0, + COMMAND_WRITE16, + + COMMAND_DRAW_LINE, + + COMMAND_SET_LEM, + COMMAND_RESET, + COMMAND_EXIT +}; + +static int32 LastDrawnLine; + +static INLINE void WWQ(uint16 command, uint32 arg32 = 0, uint16 arg16 = 0) +{ + switch(command) + { + case COMMAND_WRITE8: + MemW(arg32, arg16); + break; + + case COMMAND_WRITE16: + MemW(arg32, arg16); + break; + + case COMMAND_DRAW_LINE: + //for(unsigned i = 0; i < 2; i++) + DrawLine((uint16)arg32, arg32 >> 16, arg16); + // + LastDrawnLine = (uint16)arg32; + break; + + case COMMAND_RESET: + Reset(arg32); + break; + + case COMMAND_SET_LEM: + UserLayerEnableMask = arg32; + break; + } +} + + +// +// +// +// +// +void VDP2REND_Init(const bool IsPAL) +{ + PAL = IsPAL; + VisibleLines = PAL ? 288 : 240; + // + UserLayerEnableMask = ~0U; +} + +void VDP2REND_StartFrame(EmulateSpecStruct* espec_arg, const bool clock28m, const int SurfInterlaceField) +{ + OutLineCounter = 0; + Clock28M = clock28m; + + espec = espec_arg; + + if(SurfInterlaceField >= 0) + { + espec->LineWidths[0] = 0; + espec->InterlaceOn = true; + espec->InterlaceField = SurfInterlaceField; + } + else + espec->InterlaceOn = false; + + espec->x = (ShowHOverscan ? 0 : 10); + espec->y = LineVisFirst << espec->InterlaceOn; + espec->h = (LineVisLast + 1 - LineVisFirst) << espec->InterlaceOn; +} + +void VDP2REND_EndFrame(void) +{ + if(OutLineCounter < VisibleLines) + { + //printf("OutLineCounter(%d) < VisibleLines(%d)\n", OutLineCounter, VisibleLines); + do + { + uint16 out_line = OutLineCounter; + uint32* target; + + if(espec->InterlaceOn) + out_line = (out_line << 1) | espec->InterlaceField; + + target = espec->pixels + out_line * espec->pitch32; + target[0] = target[1] = target[2] = target[3] = 0; + espec->LineWidths[out_line] = 4; + } while(++OutLineCounter < VisibleLines); + } + + espec = NULL; +} + +VDP2Rend_LIB* VDP2REND_GetLIB(unsigned line) +{ + assert(line < (PAL ? 256 : 240)); // NO: VisibleLines); + + return &LIB[line]; +} + +void VDP2REND_DrawLine(int vdp2_line, const bool field) +{ + if(MDFN_LIKELY(OutLineCounter < VisibleLines)) + { + uint16 out_line = OutLineCounter; + + if(espec->InterlaceOn) + out_line = (out_line << 1) | espec->InterlaceField; + + WWQ(COMMAND_DRAW_LINE, ((uint16)vdp2_line << 16) | out_line, field); + OutLineCounter++; + } +} + +void VDP2REND_Reset(bool powering_up) +{ + WWQ(COMMAND_RESET, powering_up); +} + +void VDP2REND_SetLayerEnableMask(uint64 mask) +{ + WWQ(COMMAND_SET_LEM, mask); +} + +void VDP2REND_Write8_DB(uint32 A, uint16 DB) +{ + //if(DrawCounter.load(std::memory_order_acquire) != 0) + WWQ(COMMAND_WRITE8, A, DB); + //else + // MemW(A, DB); +} + +void VDP2REND_Write16_DB(uint32 A, uint16 DB) +{ + //if(DrawCounter.load(std::memory_order_acquire) != 0) + WWQ(COMMAND_WRITE16, A, DB); + //else + // MemW(A, DB); +} + +} diff --git a/waterbox/ss/vdp2_render.h b/waterbox/ss/vdp2_render.h new file mode 100644 index 0000000000..fb4859dff7 --- /dev/null +++ b/waterbox/ss/vdp2_render.h @@ -0,0 +1,57 @@ +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* vdp2_render.h: +** Copyright (C) 2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_SS_VDP2_RENDER_H +#define __MDFN_SS_VDP2_RENDER_H + +namespace MDFN_IEN_SS +{ + +void VDP2REND_Init(const bool IsPAL) MDFN_COLD; +void VDP2REND_StartFrame(EmulateSpecStruct* espec, const bool clock28m, const int SurfInterlaceField); +void VDP2REND_EndFrame(void); +void VDP2REND_Reset(bool powering_up) MDFN_COLD; +void VDP2REND_SetLayerEnableMask(uint64 mask) MDFN_COLD; + +struct VDP2Rend_LIB +{ + struct + { + uint32 Xsp, Ysp;// .10 + uint32 Xp, Yp; // .10 + uint32 dX, dY; // .10 + int32 kx, ky; // .16 + uint32 KAstAccum; + uint32 DKAx; + } rv[2]; + bool vdp1_hires8; + uint16 vdp1_line[352]; +}; + +VDP2Rend_LIB* VDP2REND_GetLIB(unsigned line); +void VDP2REND_DrawLine(int vdp2_line, const bool field); + +void VDP2REND_Write8_DB(uint32 A, uint16 DB); +void VDP2REND_Write16_DB(uint32 A, uint16 DB); + +} + +#endif diff --git a/waterbox/thunk/build.sh b/waterbox/thunk/build.sh new file mode 100644 index 0000000000..e9d1bc1614 --- /dev/null +++ b/waterbox/thunk/build.sh @@ -0,0 +1,2 @@ +#!/bin/sh +gcc test.c -o test.exe -Wall diff --git a/waterbox/thunk/gen.cs b/waterbox/thunk/gen.cs new file mode 100644 index 0000000000..857d049513 --- /dev/null +++ b/waterbox/thunk/gen.cs @@ -0,0 +1,20 @@ +private static readonly byte[][] Depart = +{ + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x20, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x30, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x8b, 0x55, 0xf8, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x48, 0x89, 0xd1, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x30, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x40, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x89, 0x55, 0xe8, 0x48, 0x8b, 0x75, 0xe8, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x49, 0x89, 0xf0, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x40, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x89, 0x55, 0xe8, 0x48, 0x89, 0x4d, 0xe0, 0x48, 0x8b, 0x7d, 0xe0, 0x48, 0x8b, 0x75, 0xe8, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x49, 0x89, 0xf9, 0x49, 0x89, 0xf0, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x60, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x89, 0x55, 0xe8, 0x48, 0x89, 0x4d, 0xe0, 0x4c, 0x89, 0x45, 0xd8, 0x48, 0x8b, 0x7d, 0xe0, 0x48, 0x8b, 0x75, 0xe8, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0x8b, 0x45, 0xd8, 0x48, 0x89, 0x44, 0x24, 0x20, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x49, 0x89, 0xf9, 0x49, 0x89, 0xf0, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x60, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x89, 0x55, 0xe8, 0x48, 0x89, 0x4d, 0xe0, 0x4c, 0x89, 0x45, 0xd8, 0x4c, 0x89, 0x4d, 0xd0, 0x48, 0x8b, 0x7d, 0xe0, 0x48, 0x8b, 0x75, 0xe8, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0x8b, 0x45, 0xd0, 0x48, 0x89, 0x44, 0x24, 0x28, 0x48, 0x8b, 0x45, 0xd8, 0x48, 0x89, 0x44, 0x24, 0x20, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x49, 0x89, 0xf9, 0x49, 0x89, 0xf0, 0xff, 0xd0, 0xc9, 0xc3, }, +}; +private static readonly byte[][] Arrive = +{ + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x20, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x30, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x8b, 0x55, 0xf8, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x48, 0x89, 0xd1, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x30, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x40, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x89, 0x55, 0xe8, 0x48, 0x8b, 0x75, 0xe8, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x49, 0x89, 0xf0, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x40, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x89, 0x55, 0xe8, 0x48, 0x89, 0x4d, 0xe0, 0x48, 0x8b, 0x7d, 0xe0, 0x48, 0x8b, 0x75, 0xe8, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x49, 0x89, 0xf9, 0x49, 0x89, 0xf0, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x60, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x89, 0x55, 0xe8, 0x48, 0x89, 0x4d, 0xe0, 0x4c, 0x89, 0x45, 0xd8, 0x48, 0x8b, 0x7d, 0xe0, 0x48, 0x8b, 0x75, 0xe8, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0x8b, 0x45, 0xd8, 0x48, 0x89, 0x44, 0x24, 0x20, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x49, 0x89, 0xf9, 0x49, 0x89, 0xf0, 0xff, 0xd0, 0xc9, 0xc3, }, + new byte[] { 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x60, 0x48, 0x89, 0x7d, 0xf8, 0x48, 0x89, 0x75, 0xf0, 0x48, 0x89, 0x55, 0xe8, 0x48, 0x89, 0x4d, 0xe0, 0x4c, 0x89, 0x45, 0xd8, 0x4c, 0x89, 0x4d, 0xd0, 0x48, 0x8b, 0x7d, 0xe0, 0x48, 0x8b, 0x75, 0xe8, 0x48, 0x8b, 0x55, 0xf0, 0x48, 0x8b, 0x4d, 0xf8, 0x48, 0x8b, 0x45, 0xd0, 0x48, 0x89, 0x44, 0x24, 0x28, 0x48, 0x8b, 0x45, 0xd8, 0x48, 0x89, 0x44, 0x24, 0x20, 0x48, 0xb8, 0xce, 0xfa, 0xed, 0xfe, 0xef, 0xbe, 0xad, 0xde, 0x49, 0x89, 0xf9, 0x49, 0x89, 0xf0, 0xff, 0xd0, 0xc9, 0xc3, }, +}; diff --git a/waterbox/thunk/test.c b/waterbox/thunk/test.c new file mode 100644 index 0000000000..de5fd11c38 --- /dev/null +++ b/waterbox/thunk/test.c @@ -0,0 +1,103 @@ +#include + +typedef int64_t ll; + +__attribute__((sysv_abi)) ll Depart0(void) +{ + return ((__attribute__((ms_abi)) ll (*)(void))0xdeadbeeffeedface)(); +} + +__attribute__((sysv_abi)) ll Depart1(ll a) +{ + return ((__attribute__((ms_abi)) ll (*)(ll))0xdeadbeeffeedface)(a); +} + +__attribute__((sysv_abi)) ll Depart2(ll a, ll b) +{ + return ((__attribute__((ms_abi)) ll (*)(ll, ll))0xdeadbeeffeedface)(a, b); +} + +__attribute__((sysv_abi)) ll Depart3(ll a, ll b, ll c) +{ + return ((__attribute__((ms_abi)) ll (*)(ll, ll, ll))0xdeadbeeffeedface)(a, b, c); +} + +__attribute__((sysv_abi)) ll Depart4(ll a, ll b, ll c, ll d) +{ + return ((__attribute__((ms_abi)) ll (*)(ll, ll, ll, ll))0xdeadbeeffeedface)(a, b, c, d); +} + +__attribute__((sysv_abi)) ll Depart5(ll a, ll b, ll c, ll d, ll e) +{ + return ((__attribute__((ms_abi)) ll (*)(ll, ll, ll, ll, ll))0xdeadbeeffeedface)(a, b, c, d, e); +} + +__attribute__((sysv_abi)) ll Depart6(ll a, ll b, ll c, ll d, ll e, ll f) +{ + return ((__attribute__((ms_abi)) ll (*)(ll, ll, ll, ll, ll, ll))0xdeadbeeffeedface)(a, b, c, d, e, f); +} + +__attribute__((ms_abi)) ll Arrive0(void) +{ + return ((__attribute__((sysv_abi)) ll (*)(void))0xdeadbeeffeedface)(); +} + +__attribute__((ms_abi)) ll Arrive1(ll a) +{ + return ((__attribute__((sysv_abi)) ll (*)(ll))0xdeadbeeffeedface)(a); +} + +__attribute__((ms_abi)) ll Arrive2(ll a, ll b) +{ + return ((__attribute__((sysv_abi)) ll (*)(ll, ll))0xdeadbeeffeedface)(a, b); +} + +__attribute__((ms_abi)) ll Arrive3(ll a, ll b, ll c) +{ + return ((__attribute__((sysv_abi)) ll (*)(ll, ll, ll))0xdeadbeeffeedface)(a, b, c); +} + +__attribute__((ms_abi)) ll Arrive4(ll a, ll b, ll c, ll d) +{ + return ((__attribute__((sysv_abi)) ll (*)(ll, ll, ll, ll))0xdeadbeeffeedface)(a, b, c, d); +} + +__attribute__((ms_abi)) ll Arrive5(ll a, ll b, ll c, ll d, ll e) +{ + return ((__attribute__((sysv_abi)) ll (*)(ll, ll, ll, ll, ll))0xdeadbeeffeedface)(a, b, c, d, e); +} + +__attribute__((ms_abi)) ll Arrive6(ll a, ll b, ll c, ll d, ll e, ll f) +{ + return ((__attribute__((sysv_abi)) ll (*)(ll, ll, ll, ll, ll, ll))0xdeadbeeffeedface)(a, b, c, d, e, f); +} + +void End(void) +{ +} + +#include +const void* ptrs[] = { Depart0, Depart1, Depart2, Depart3, Depart4, Depart5, Depart6, + Arrive0, Arrive1, Arrive2, Arrive3, Arrive4, Arrive5, Arrive6, End }; + +void print(const char* name, int offs) +{ + printf("private static readonly byte[][] %s =\n{\n", name); + for (int i = offs; i < offs + 7; i++) + { + printf("\tnew byte[] { "); + const uint8_t* start = ptrs[i]; + const uint8_t* end = ptrs[i + 1]; + while (start < end) + printf("0x%02x, ", *start++); + printf("},\n"); + } + printf("};\n"); +} + +int main(void) +{ + print("Depart", 0); + print("Arrive", 0); + return 0; +} diff --git a/waterbox/thunk/test.exe b/waterbox/thunk/test.exe new file mode 100644 index 0000000000..0a0fba4826 Binary files /dev/null and b/waterbox/thunk/test.exe differ diff --git a/waterbox/thunk/test.s b/waterbox/thunk/test.s new file mode 100644 index 0000000000..988fcf43e1 --- /dev/null +++ b/waterbox/thunk/test.s @@ -0,0 +1,682 @@ + .file "test.c" + .text + .globl Depart0 + .def Depart0; .scl 2; .type 32; .endef +Depart0: + pushq %rbp + movq %rsp, %rbp + subq $32, %rsp + movabsq $-2401053088335136050, %rax + call *%rax + leave + ret + .globl Depart1 + .def Depart1; .scl 2; .type 32; .endef +Depart1: + pushq %rbp + movq %rsp, %rbp + subq $48, %rsp + movq %rdi, -8(%rbp) + movq -8(%rbp), %rdx + movabsq $-2401053088335136050, %rax + movq %rdx, %rcx + call *%rax + leave + ret + .globl Depart2 + .def Depart2; .scl 2; .type 32; .endef +Depart2: + pushq %rbp + movq %rsp, %rbp + subq $48, %rsp + movq %rdi, -8(%rbp) + movq %rsi, -16(%rbp) + movq -16(%rbp), %rdx + movq -8(%rbp), %rcx + movabsq $-2401053088335136050, %rax + call *%rax + leave + ret + .globl Depart3 + .def Depart3; .scl 2; .type 32; .endef +Depart3: + pushq %rbp + movq %rsp, %rbp + subq $64, %rsp + movq %rdi, -8(%rbp) + movq %rsi, -16(%rbp) + movq %rdx, -24(%rbp) + movq -24(%rbp), %rsi + movq -16(%rbp), %rdx + movq -8(%rbp), %rcx + movabsq $-2401053088335136050, %rax + movq %rsi, %r8 + call *%rax + leave + ret + .globl Depart4 + .def Depart4; .scl 2; .type 32; .endef +Depart4: + pushq %rbp + movq %rsp, %rbp + subq $64, %rsp + movq %rdi, -8(%rbp) + movq %rsi, -16(%rbp) + movq %rdx, -24(%rbp) + movq %rcx, -32(%rbp) + movq -32(%rbp), %rdi + movq -24(%rbp), %rsi + movq -16(%rbp), %rdx + movq -8(%rbp), %rcx + movabsq $-2401053088335136050, %rax + movq %rdi, %r9 + movq %rsi, %r8 + call *%rax + leave + ret + .globl Depart5 + .def Depart5; .scl 2; .type 32; .endef +Depart5: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + movq %rdi, -8(%rbp) + movq %rsi, -16(%rbp) + movq %rdx, -24(%rbp) + movq %rcx, -32(%rbp) + movq %r8, -40(%rbp) + movq -32(%rbp), %rdi + movq -24(%rbp), %rsi + movq -16(%rbp), %rdx + movq -8(%rbp), %rcx + movq -40(%rbp), %rax + movq %rax, 32(%rsp) + movabsq $-2401053088335136050, %rax + movq %rdi, %r9 + movq %rsi, %r8 + call *%rax + leave + ret + .globl Depart6 + .def Depart6; .scl 2; .type 32; .endef +Depart6: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + movq %rdi, -8(%rbp) + movq %rsi, -16(%rbp) + movq %rdx, -24(%rbp) + movq %rcx, -32(%rbp) + movq %r8, -40(%rbp) + movq %r9, -48(%rbp) + movq -32(%rbp), %rdi + movq -24(%rbp), %rsi + movq -16(%rbp), %rdx + movq -8(%rbp), %rcx + movq -48(%rbp), %rax + movq %rax, 40(%rsp) + movq -40(%rbp), %rax + movq %rax, 32(%rsp) + movabsq $-2401053088335136050, %rax + movq %rdi, %r9 + movq %rsi, %r8 + call *%rax + leave + ret + .globl Arrive0 + .def Arrive0; .scl 2; .type 32; .endef + .seh_proc Arrive0 +Arrive0: + pushq %rbp + .seh_pushreg %rbp + pushq %rdi + .seh_pushreg %rdi + pushq %rsi + .seh_pushreg %rsi + movq %rsp, %rbp + .seh_setframe %rbp, 0 + subq $160, %rsp + .seh_stackalloc 160 + movaps %xmm6, (%rsp) + .seh_savexmm %xmm6, 0 + movaps %xmm7, 16(%rsp) + .seh_savexmm %xmm7, 16 + movaps %xmm8, -128(%rbp) + .seh_savexmm %xmm8, 32 + movaps %xmm9, -112(%rbp) + .seh_savexmm %xmm9, 48 + movaps %xmm10, -96(%rbp) + .seh_savexmm %xmm10, 64 + movaps %xmm11, -80(%rbp) + .seh_savexmm %xmm11, 80 + movaps %xmm12, -64(%rbp) + .seh_savexmm %xmm12, 96 + movaps %xmm13, -48(%rbp) + .seh_savexmm %xmm13, 112 + movaps %xmm14, -32(%rbp) + .seh_savexmm %xmm14, 128 + movaps %xmm15, -16(%rbp) + .seh_savexmm %xmm15, 144 + .seh_endprologue + movabsq $-2401053088335136050, %rax + call *%rax + movaps (%rsp), %xmm6 + movaps 16(%rsp), %xmm7 + movaps -128(%rbp), %xmm8 + movaps -112(%rbp), %xmm9 + movaps -96(%rbp), %xmm10 + movaps -80(%rbp), %xmm11 + movaps -64(%rbp), %xmm12 + movaps -48(%rbp), %xmm13 + movaps -32(%rbp), %xmm14 + movaps -16(%rbp), %xmm15 + addq $160, %rsp + popq %rsi + popq %rdi + popq %rbp + ret + .seh_endproc + .globl Arrive1 + .def Arrive1; .scl 2; .type 32; .endef + .seh_proc Arrive1 +Arrive1: + pushq %rbp + .seh_pushreg %rbp + pushq %rdi + .seh_pushreg %rdi + pushq %rsi + .seh_pushreg %rsi + movq %rsp, %rbp + .seh_setframe %rbp, 0 + subq $160, %rsp + .seh_stackalloc 160 + movaps %xmm6, (%rsp) + .seh_savexmm %xmm6, 0 + movaps %xmm7, 16(%rsp) + .seh_savexmm %xmm7, 16 + movaps %xmm8, -128(%rbp) + .seh_savexmm %xmm8, 32 + movaps %xmm9, -112(%rbp) + .seh_savexmm %xmm9, 48 + movaps %xmm10, -96(%rbp) + .seh_savexmm %xmm10, 64 + movaps %xmm11, -80(%rbp) + .seh_savexmm %xmm11, 80 + movaps %xmm12, -64(%rbp) + .seh_savexmm %xmm12, 96 + movaps %xmm13, -48(%rbp) + .seh_savexmm %xmm13, 112 + movaps %xmm14, -32(%rbp) + .seh_savexmm %xmm14, 128 + movaps %xmm15, -16(%rbp) + .seh_savexmm %xmm15, 144 + .seh_endprologue + movq %rcx, 32(%rbp) + movabsq $-2401053088335136050, %rax + movq 32(%rbp), %rdi + call *%rax + movaps (%rsp), %xmm6 + movaps 16(%rsp), %xmm7 + movaps -128(%rbp), %xmm8 + movaps -112(%rbp), %xmm9 + movaps -96(%rbp), %xmm10 + movaps -80(%rbp), %xmm11 + movaps -64(%rbp), %xmm12 + movaps -48(%rbp), %xmm13 + movaps -32(%rbp), %xmm14 + movaps -16(%rbp), %xmm15 + addq $160, %rsp + popq %rsi + popq %rdi + popq %rbp + ret + .seh_endproc + .globl Arrive2 + .def Arrive2; .scl 2; .type 32; .endef + .seh_proc Arrive2 +Arrive2: + pushq %rbp + .seh_pushreg %rbp + pushq %rdi + .seh_pushreg %rdi + pushq %rsi + .seh_pushreg %rsi + movq %rsp, %rbp + .seh_setframe %rbp, 0 + subq $160, %rsp + .seh_stackalloc 160 + movaps %xmm6, (%rsp) + .seh_savexmm %xmm6, 0 + movaps %xmm7, 16(%rsp) + .seh_savexmm %xmm7, 16 + movaps %xmm8, -128(%rbp) + .seh_savexmm %xmm8, 32 + movaps %xmm9, -112(%rbp) + .seh_savexmm %xmm9, 48 + movaps %xmm10, -96(%rbp) + .seh_savexmm %xmm10, 64 + movaps %xmm11, -80(%rbp) + .seh_savexmm %xmm11, 80 + movaps %xmm12, -64(%rbp) + .seh_savexmm %xmm12, 96 + movaps %xmm13, -48(%rbp) + .seh_savexmm %xmm13, 112 + movaps %xmm14, -32(%rbp) + .seh_savexmm %xmm14, 128 + movaps %xmm15, -16(%rbp) + .seh_savexmm %xmm15, 144 + .seh_endprologue + movq %rcx, 32(%rbp) + movq %rdx, 40(%rbp) + movq 40(%rbp), %rdx + movabsq $-2401053088335136050, %rax + movq %rdx, %rsi + movq 32(%rbp), %rdi + call *%rax + movaps (%rsp), %xmm6 + movaps 16(%rsp), %xmm7 + movaps -128(%rbp), %xmm8 + movaps -112(%rbp), %xmm9 + movaps -96(%rbp), %xmm10 + movaps -80(%rbp), %xmm11 + movaps -64(%rbp), %xmm12 + movaps -48(%rbp), %xmm13 + movaps -32(%rbp), %xmm14 + movaps -16(%rbp), %xmm15 + addq $160, %rsp + popq %rsi + popq %rdi + popq %rbp + ret + .seh_endproc + .globl Arrive3 + .def Arrive3; .scl 2; .type 32; .endef + .seh_proc Arrive3 +Arrive3: + pushq %rbp + .seh_pushreg %rbp + pushq %rdi + .seh_pushreg %rdi + pushq %rsi + .seh_pushreg %rsi + movq %rsp, %rbp + .seh_setframe %rbp, 0 + subq $160, %rsp + .seh_stackalloc 160 + movaps %xmm6, (%rsp) + .seh_savexmm %xmm6, 0 + movaps %xmm7, 16(%rsp) + .seh_savexmm %xmm7, 16 + movaps %xmm8, -128(%rbp) + .seh_savexmm %xmm8, 32 + movaps %xmm9, -112(%rbp) + .seh_savexmm %xmm9, 48 + movaps %xmm10, -96(%rbp) + .seh_savexmm %xmm10, 64 + movaps %xmm11, -80(%rbp) + .seh_savexmm %xmm11, 80 + movaps %xmm12, -64(%rbp) + .seh_savexmm %xmm12, 96 + movaps %xmm13, -48(%rbp) + .seh_savexmm %xmm13, 112 + movaps %xmm14, -32(%rbp) + .seh_savexmm %xmm14, 128 + movaps %xmm15, -16(%rbp) + .seh_savexmm %xmm15, 144 + .seh_endprologue + movq %rcx, 32(%rbp) + movq %rdx, 40(%rbp) + movq %r8, 48(%rbp) + movq 48(%rbp), %rdx + movq 40(%rbp), %rcx + movabsq $-2401053088335136050, %rax + movq %rcx, %rsi + movq 32(%rbp), %rdi + call *%rax + movaps (%rsp), %xmm6 + movaps 16(%rsp), %xmm7 + movaps -128(%rbp), %xmm8 + movaps -112(%rbp), %xmm9 + movaps -96(%rbp), %xmm10 + movaps -80(%rbp), %xmm11 + movaps -64(%rbp), %xmm12 + movaps -48(%rbp), %xmm13 + movaps -32(%rbp), %xmm14 + movaps -16(%rbp), %xmm15 + addq $160, %rsp + popq %rsi + popq %rdi + popq %rbp + ret + .seh_endproc + .globl Arrive4 + .def Arrive4; .scl 2; .type 32; .endef + .seh_proc Arrive4 +Arrive4: + pushq %rbp + .seh_pushreg %rbp + pushq %rdi + .seh_pushreg %rdi + pushq %rsi + .seh_pushreg %rsi + movq %rsp, %rbp + .seh_setframe %rbp, 0 + subq $160, %rsp + .seh_stackalloc 160 + movaps %xmm6, (%rsp) + .seh_savexmm %xmm6, 0 + movaps %xmm7, 16(%rsp) + .seh_savexmm %xmm7, 16 + movaps %xmm8, -128(%rbp) + .seh_savexmm %xmm8, 32 + movaps %xmm9, -112(%rbp) + .seh_savexmm %xmm9, 48 + movaps %xmm10, -96(%rbp) + .seh_savexmm %xmm10, 64 + movaps %xmm11, -80(%rbp) + .seh_savexmm %xmm11, 80 + movaps %xmm12, -64(%rbp) + .seh_savexmm %xmm12, 96 + movaps %xmm13, -48(%rbp) + .seh_savexmm %xmm13, 112 + movaps %xmm14, -32(%rbp) + .seh_savexmm %xmm14, 128 + movaps %xmm15, -16(%rbp) + .seh_savexmm %xmm15, 144 + .seh_endprologue + movq %rcx, 32(%rbp) + movq %rdx, 40(%rbp) + movq %r8, 48(%rbp) + movq %r9, 56(%rbp) + movq 56(%rbp), %rcx + movq 48(%rbp), %rdx + movq 40(%rbp), %r8 + movabsq $-2401053088335136050, %rax + movq %r8, %rsi + movq 32(%rbp), %rdi + call *%rax + movaps (%rsp), %xmm6 + movaps 16(%rsp), %xmm7 + movaps -128(%rbp), %xmm8 + movaps -112(%rbp), %xmm9 + movaps -96(%rbp), %xmm10 + movaps -80(%rbp), %xmm11 + movaps -64(%rbp), %xmm12 + movaps -48(%rbp), %xmm13 + movaps -32(%rbp), %xmm14 + movaps -16(%rbp), %xmm15 + addq $160, %rsp + popq %rsi + popq %rdi + popq %rbp + ret + .seh_endproc + .globl Arrive5 + .def Arrive5; .scl 2; .type 32; .endef + .seh_proc Arrive5 +Arrive5: + pushq %rbp + .seh_pushreg %rbp + pushq %rdi + .seh_pushreg %rdi + pushq %rsi + .seh_pushreg %rsi + movq %rsp, %rbp + .seh_setframe %rbp, 0 + subq $160, %rsp + .seh_stackalloc 160 + movaps %xmm6, (%rsp) + .seh_savexmm %xmm6, 0 + movaps %xmm7, 16(%rsp) + .seh_savexmm %xmm7, 16 + movaps %xmm8, -128(%rbp) + .seh_savexmm %xmm8, 32 + movaps %xmm9, -112(%rbp) + .seh_savexmm %xmm9, 48 + movaps %xmm10, -96(%rbp) + .seh_savexmm %xmm10, 64 + movaps %xmm11, -80(%rbp) + .seh_savexmm %xmm11, 80 + movaps %xmm12, -64(%rbp) + .seh_savexmm %xmm12, 96 + movaps %xmm13, -48(%rbp) + .seh_savexmm %xmm13, 112 + movaps %xmm14, -32(%rbp) + .seh_savexmm %xmm14, 128 + movaps %xmm15, -16(%rbp) + .seh_savexmm %xmm15, 144 + .seh_endprologue + movq %rcx, 32(%rbp) + movq %rdx, 40(%rbp) + movq %r8, 48(%rbp) + movq %r9, 56(%rbp) + movq 64(%rbp), %r8 + movq 56(%rbp), %rcx + movq 48(%rbp), %rdx + movq 40(%rbp), %r9 + movabsq $-2401053088335136050, %rax + movq %r9, %rsi + movq 32(%rbp), %rdi + call *%rax + movaps (%rsp), %xmm6 + movaps 16(%rsp), %xmm7 + movaps -128(%rbp), %xmm8 + movaps -112(%rbp), %xmm9 + movaps -96(%rbp), %xmm10 + movaps -80(%rbp), %xmm11 + movaps -64(%rbp), %xmm12 + movaps -48(%rbp), %xmm13 + movaps -32(%rbp), %xmm14 + movaps -16(%rbp), %xmm15 + addq $160, %rsp + popq %rsi + popq %rdi + popq %rbp + ret + .seh_endproc + .globl Arrive6 + .def Arrive6; .scl 2; .type 32; .endef + .seh_proc Arrive6 +Arrive6: + pushq %rbp + .seh_pushreg %rbp + pushq %rdi + .seh_pushreg %rdi + pushq %rsi + .seh_pushreg %rsi + movq %rsp, %rbp + .seh_setframe %rbp, 0 + subq $160, %rsp + .seh_stackalloc 160 + movaps %xmm6, (%rsp) + .seh_savexmm %xmm6, 0 + movaps %xmm7, 16(%rsp) + .seh_savexmm %xmm7, 16 + movaps %xmm8, -128(%rbp) + .seh_savexmm %xmm8, 32 + movaps %xmm9, -112(%rbp) + .seh_savexmm %xmm9, 48 + movaps %xmm10, -96(%rbp) + .seh_savexmm %xmm10, 64 + movaps %xmm11, -80(%rbp) + .seh_savexmm %xmm11, 80 + movaps %xmm12, -64(%rbp) + .seh_savexmm %xmm12, 96 + movaps %xmm13, -48(%rbp) + .seh_savexmm %xmm13, 112 + movaps %xmm14, -32(%rbp) + .seh_savexmm %xmm14, 128 + movaps %xmm15, -16(%rbp) + .seh_savexmm %xmm15, 144 + .seh_endprologue + movq %rcx, 32(%rbp) + movq %rdx, 40(%rbp) + movq %r8, 48(%rbp) + movq %r9, 56(%rbp) + movq 72(%rbp), %r9 + movq 64(%rbp), %r8 + movq 56(%rbp), %rcx + movq 48(%rbp), %rdx + movq 40(%rbp), %r10 + movabsq $-2401053088335136050, %rax + movq %r10, %rsi + movq 32(%rbp), %rdi + call *%rax + movaps (%rsp), %xmm6 + movaps 16(%rsp), %xmm7 + movaps -128(%rbp), %xmm8 + movaps -112(%rbp), %xmm9 + movaps -96(%rbp), %xmm10 + movaps -80(%rbp), %xmm11 + movaps -64(%rbp), %xmm12 + movaps -48(%rbp), %xmm13 + movaps -32(%rbp), %xmm14 + movaps -16(%rbp), %xmm15 + addq $160, %rsp + popq %rsi + popq %rdi + popq %rbp + ret + .seh_endproc + .globl End + .def End; .scl 2; .type 32; .endef + .seh_proc End +End: + pushq %rbp + .seh_pushreg %rbp + movq %rsp, %rbp + .seh_setframe %rbp, 0 + .seh_endprologue + nop + popq %rbp + ret + .seh_endproc + .globl ptrs + .data + .align 32 +ptrs: + .quad Depart0 + .quad Depart1 + .quad Depart2 + .quad Depart3 + .quad Depart4 + .quad Depart5 + .quad Depart6 + .quad Arrive0 + .quad Arrive1 + .quad Arrive2 + .quad Arrive3 + .quad Arrive4 + .quad Arrive5 + .quad Arrive6 + .quad End + .section .rdata,"dr" + .align 8 +.LC0: + .ascii "private static readonly byte[][] %s =\12{\12\0" +.LC1: + .ascii "\11new byte[] { \0" +.LC2: + .ascii "0x%02x, \0" +.LC3: + .ascii "},\0" +.LC4: + .ascii "};\0" + .text + .globl print + .def print; .scl 2; .type 32; .endef + .seh_proc print +print: + pushq %rbp + .seh_pushreg %rbp + movq %rsp, %rbp + .seh_setframe %rbp, 0 + subq $64, %rsp + .seh_stackalloc 64 + .seh_endprologue + movq %rcx, 16(%rbp) + movl %edx, 24(%rbp) + movq 16(%rbp), %rdx + leaq .LC0(%rip), %rcx + call printf + movl 24(%rbp), %eax + movl %eax, -4(%rbp) + jmp .L31 +.L34: + leaq .LC1(%rip), %rcx + call printf + movl -4(%rbp), %eax + cltq + leaq 0(,%rax,8), %rdx + leaq ptrs(%rip), %rax + movq (%rdx,%rax), %rax + movq %rax, -16(%rbp) + movl -4(%rbp), %eax + addl $1, %eax + cltq + leaq 0(,%rax,8), %rdx + leaq ptrs(%rip), %rax + movq (%rdx,%rax), %rax + movq %rax, -24(%rbp) + jmp .L32 +.L33: + movq -16(%rbp), %rax + leaq 1(%rax), %rdx + movq %rdx, -16(%rbp) + movzbl (%rax), %eax + movzbl %al, %eax + movl %eax, %edx + leaq .LC2(%rip), %rcx + call printf +.L32: + movq -16(%rbp), %rax + cmpq -24(%rbp), %rax + jb .L33 + leaq .LC3(%rip), %rcx + call puts + addl $1, -4(%rbp) +.L31: + movl 24(%rbp), %eax + addl $7, %eax + cmpl -4(%rbp), %eax + jg .L34 + leaq .LC4(%rip), %rcx + call puts + nop + addq $64, %rsp + popq %rbp + ret + .seh_endproc + .def __main; .scl 2; .type 32; .endef + .section .rdata,"dr" +.LC5: + .ascii "Depart\0" +.LC6: + .ascii "Arrive\0" + .text + .globl main + .def main; .scl 2; .type 32; .endef + .seh_proc main +main: + pushq %rbp + .seh_pushreg %rbp + movq %rsp, %rbp + .seh_setframe %rbp, 0 + subq $32, %rsp + .seh_stackalloc 32 + .seh_endprologue + call __main + movl $0, %edx + leaq .LC5(%rip), %rcx + call print + movl $0, %edx + leaq .LC6(%rip), %rcx + call print + movl $0, %eax + addq $32, %rsp + popq %rbp + ret + .seh_endproc + .ident "GCC: (Rev2, Built by MSYS2 project) 5.3.0" + .def printf; .scl 2; .type 32; .endef + .def puts; .scl 2; .type 32; .endef diff --git a/waterbox/vb/.vscode/settings.json b/waterbox/vb/.vscode/settings.json new file mode 100644 index 0000000000..edb0a83e80 --- /dev/null +++ b/waterbox/vb/.vscode/settings.json @@ -0,0 +1,9 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "editor.detectIndentation": false, + "editor.insertSpaces": false, + "files.associations": { + "xiosbase": "cpp", + "xlocale": "cpp" + } +} \ No newline at end of file diff --git a/waterbox/vb/Makefile b/waterbox/vb/Makefile new file mode 100644 index 0000000000..f884193f57 --- /dev/null +++ b/waterbox/vb/Makefile @@ -0,0 +1,44 @@ +CC = x86_64-nt64-midipix-g++ + +CCFLAGS:= -I. -I../emulibc \ + -Wall -Werror=pointer-to-int-cast -Werror=int-to-pointer-cast -Werror=implicit-function-declaration \ + -std=c++0x -fomit-frame-pointer -fvisibility=hidden -fno-exceptions -fno-rtti \ + -DLSB_FIRST \ + -O3 -flto + +TARGET = vb.wbx + +LDFLAGS = -Wl,--dynamicbase,--export-all-symbols + +ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) +SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.cpp') +OBJ_DIR:=$(ROOT_DIR)/obj + +_OBJS:=$(SRCS:.cpp=.o) +OBJS:=$(patsubst $(ROOT_DIR)%,$(OBJ_DIR)%,$(_OBJS)) + +$(OBJ_DIR)/%.o: %.cpp + @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) + +print-%: + @echo $* = $($*) + +#install: +# $(CP) $(TARGET) $(DEST_$(ARCH)) diff --git a/waterbox/vb/blip/Blip_Buffer.cpp b/waterbox/vb/blip/Blip_Buffer.cpp new file mode 100644 index 0000000000..f04a1fc599 --- /dev/null +++ b/waterbox/vb/blip/Blip_Buffer.cpp @@ -0,0 +1,457 @@ +// Blip_Buffer 0.4.1. http://www.slack.net/~ant/ + +#include "Blip_Buffer.h" + +#include +#include +#include +#include +#include +#include + +/* Copyright (C) 2003-2006 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifdef BLARGG_ENABLE_OPTIMIZER + #include BLARGG_ENABLE_OPTIMIZER +#endif + +int const silent_buf_size = 1; // size used for Silent_Blip_Buffer + +Blip_Buffer::Blip_Buffer() +{ + factor_ = (blip_u64)ULLONG_MAX; + offset_ = 0; + buffer_ = 0; + buffer_size_ = 0; + sample_rate_ = 0; + reader_accum_ = 0; + bass_shift_ = 0; + clock_rate_ = 0; + bass_freq_ = 16; + length_ = 0; + + // assumptions code makes about implementation-defined features + #ifndef NDEBUG + // right shift of negative value preserves sign + buf_t_ i = -0x7FFFFFFE; + assert( (i >> 1) == -0x3FFFFFFF ); + + // casting to short truncates to 16 bits and sign-extends + i = 0x18000; + assert( (short) i == -0x8000 ); + #endif +} + +Blip_Buffer::~Blip_Buffer() +{ + if ( buffer_size_ != silent_buf_size ) + free( buffer_ ); +} + +Silent_Blip_Buffer::Silent_Blip_Buffer() +{ + factor_ = 0; + buffer_ = buf; + buffer_size_ = silent_buf_size; + memset( buf, 0, sizeof buf ); // in case machine takes exception for signed overflow +} + +void Blip_Buffer::clear( int entire_buffer ) +{ + offset_ = 0; + reader_accum_ = 0; + modified_ = 0; + if ( buffer_ ) + { + long count = (entire_buffer ? buffer_size_ : samples_avail()); + memset( buffer_, 0, (count + blip_buffer_extra_) * sizeof (buf_t_) ); + } +} + +Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec ) +{ + if ( buffer_size_ == silent_buf_size ) + { + assert( 0 ); + return "Internal (tried to resize Silent_Blip_Buffer)"; + } + + // start with maximum length that resampled time can represent + blip_s64 new_size = (ULLONG_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64; + + // simple safety check, since code elsewhere may not be safe for sizes approaching (2 ^ 31). + if(new_size > ((1LL << 30) - 1)) + new_size = (1LL << 30) - 1; + + if ( msec != blip_max_length ) + { + blip_s64 s = ((blip_s64)new_rate * (msec + 1) + 999) / 1000; + if ( s < new_size ) + new_size = s; + else + assert( 0 ); // fails if requested buffer length exceeds limit + } + + if ( buffer_size_ != new_size ) + { + void* p = realloc( buffer_, (new_size + blip_buffer_extra_) * sizeof *buffer_ ); + if ( !p ) + return "Out of memory"; + + //if(new_size > buffer_size_) + // memset(buffer_ + buffer_size_, 0, (new_size + blip_buffer_extra_) * sizeof *buffer_ + + buffer_ = (buf_t_*) p; + } + + buffer_size_ = new_size; + assert( buffer_size_ != silent_buf_size ); + + // update things based on the sample rate + sample_rate_ = new_rate; + length_ = new_size * 1000 / new_rate - 1; + if ( msec ) + assert( length_ == msec ); // ensure length is same as that passed in + if ( clock_rate_ ) + clock_rate( clock_rate_ ); + bass_freq( bass_freq_ ); + + clear(); + + return 0; // success +} + +blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const +{ + double ratio = (double) sample_rate_ / rate; + blip_s64 factor = (blip_s64) floor( ratio * (1LL << BLIP_BUFFER_ACCURACY) + 0.5 ); + assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio is too large + return (blip_resampled_time_t) factor; +} + +void Blip_Buffer::bass_freq( int freq ) +{ + bass_freq_ = freq; + int shift = 31; + if ( freq > 0 ) + { + shift = 13; + long f = (freq << 16) / sample_rate_; + while ( (f >>= 1) && --shift ) { } + } + bass_shift_ = shift; + //printf("%d\n", bass_shift_); +} + +void Blip_Buffer::end_frame( blip_time_t t ) +{ + offset_ += t * factor_; + assert( samples_avail() <= (long) buffer_size_ ); // time outside buffer length +} + +void Blip_Buffer::remove_silence( long count ) +{ + assert( count <= samples_avail() ); // tried to remove more samples than available + offset_ -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY; +} + +long Blip_Buffer::count_samples( blip_time_t t ) const +{ + unsigned long last_sample = resampled_time( t ) >> BLIP_BUFFER_ACCURACY; + unsigned long first_sample = offset_ >> BLIP_BUFFER_ACCURACY; + return (long) (last_sample - first_sample); +} + +blip_time_t Blip_Buffer::count_clocks( long count ) const +{ + if ( !factor_ ) + { + assert( 0 ); // sample rate and clock rates must be set first + return 0; + } + + if ( count > buffer_size_ ) + count = buffer_size_; + blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY; + return (blip_time_t) ((time - offset_ + factor_ - 1) / factor_); +} + +void Blip_Buffer::remove_samples( long count ) +{ + if ( count ) + { + remove_silence( count ); + + // copy remaining samples to beginning and clear old samples + long remain = samples_avail() + blip_buffer_extra_; + memmove( buffer_, buffer_ + count, remain * sizeof *buffer_ ); + memset( buffer_ + remain, 0, count * sizeof *buffer_ ); + } +} + +// Blip_Synth_ + +Blip_Synth_Fast_::Blip_Synth_Fast_() +{ + buf = 0; + last_amp = 0; + delta_factor = 0; +} + +void Blip_Synth_Fast_::volume_unit( double new_unit ) +{ + delta_factor = int (new_unit * (1L << blip_sample_bits) + 0.5); +} + +#if !BLIP_BUFFER_FAST + +Blip_Synth_::Blip_Synth_( short* p, int w ) : + impulses( p ), + width( w ) +{ + volume_unit_ = 0.0; + kernel_unit = 0; + buf = 0; + last_amp = 0; + delta_factor = 0; +} + +#undef PI +#define PI 3.1415926535897932384626433832795029 + +static void gen_sinc( float* out, int count, double oversample, double treble, double cutoff ) +{ + if ( cutoff >= 0.999 ) + cutoff = 0.999; + + if ( treble < -300.0 ) + treble = -300.0; + if ( treble > 5.0 ) + treble = 5.0; + + double const maxh = 4096.0; + double const rolloff = pow( 10.0, 1.0 / (maxh * 20.0) * treble / (1.0 - cutoff) ); + double const pow_a_n = pow( rolloff, maxh - maxh * cutoff ); + double const to_angle = PI / 2 / maxh / oversample; + for ( int i = 0; i < count; i++ ) + { + double angle = ((i - count) * 2 + 1) * to_angle; + double c = rolloff * cos( (maxh - 1.0) * angle ) - cos( maxh * angle ); + double cos_nc_angle = cos( maxh * cutoff * angle ); + double cos_nc1_angle = cos( (maxh * cutoff - 1.0) * angle ); + double cos_angle = cos( angle ); + + c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle; + double d = 1.0 + rolloff * (rolloff - cos_angle - cos_angle); + double b = 2.0 - cos_angle - cos_angle; + double a = 1.0 - cos_angle - cos_nc_angle + cos_nc1_angle; + + out [i] = (float) ((a * d + c * b) / (b * d)); // a / b + c / d + } +} + +void blip_eq_t::generate( float* out, int count ) const +{ + // lower cutoff freq for narrow kernels with their wider transition band + // (8 points->1.49, 16 points->1.15) + double oversample = blip_res * 2.25 / count + 0.85; + double half_rate = sample_rate * 0.5; + if ( cutoff_freq ) + oversample = half_rate / cutoff_freq; + double cutoff = rolloff_freq * oversample / half_rate; + + gen_sinc( out, count, blip_res * oversample, treble, cutoff ); + + // apply (half of) hamming window + double to_fraction = PI / (count - 1); + for ( int i = count; i--; ) + out [i] *= 0.54f - 0.46f * (float) cos( i * to_fraction ); +} + +void Blip_Synth_::adjust_impulse() +{ + // sum pairs for each phase and add error correction to end of first half + int const size = impulses_size(); + for ( int p = blip_res; p-- >= blip_res / 2; ) + { + int p2 = blip_res - 2 - p; + long error = kernel_unit; + for ( int i = 1; i < size; i += blip_res ) + { + error -= impulses [i + p ]; + error -= impulses [i + p2]; + } + if ( p == p2 ) + error /= 2; // phase = 0.5 impulse uses same half for both sides + impulses [size - blip_res + p] += (short) error; + //printf( "error: %ld\n", error ); + } + + //for ( int i = blip_res; i--; printf( "\n" ) ) + // for ( int j = 0; j < width / 2; j++ ) + // printf( "%5ld,", impulses [j * blip_res + i + 1] ); +} + +void Blip_Synth_::treble_eq( blip_eq_t const& eq ) +{ + float fimpulse [blip_res / 2 * (blip_widest_impulse_ - 1) + blip_res * 2]; + + int const half_size = blip_res / 2 * (width - 1); + eq.generate( &fimpulse [blip_res], half_size ); + + int i; + + // need mirror slightly past center for calculation + for ( i = blip_res; i--; ) + fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i]; + + // starts at 0 + for ( i = 0; i < blip_res; i++ ) + fimpulse [i] = 0.0f; + + // find rescale factor + double total = 0.0; + for ( i = 0; i < half_size; i++ ) + total += fimpulse [blip_res + i]; + + //double const base_unit = 44800.0 - 128 * 18; // allows treble up to +0 dB + //double const base_unit = 37888.0; // allows treble to +5 dB + double const base_unit = 32768.0; // necessary for blip_unscaled to work + double rescale = base_unit / 2 / total; + kernel_unit = (long) base_unit; + + // integrate, first difference, rescale, convert to int + double sum = 0.0; + double next = 0.0; + int const impulses_size_local = this->impulses_size(); + for ( i = 0; i < impulses_size_local; i++ ) + { + impulses [i] = (short) floor( (next - sum) * rescale + 0.5 ); + sum += fimpulse [i]; + next += fimpulse [i + blip_res]; + } + adjust_impulse(); + + // volume might require rescaling + double vol = volume_unit_; + if ( vol ) + { + volume_unit_ = 0.0; + volume_unit( vol ); + } +} + +void Blip_Synth_::volume_unit( double new_unit ) +{ + if ( new_unit != volume_unit_ ) + { + // use default eq if it hasn't been set yet + if ( !kernel_unit ) + treble_eq( -8.0 ); + + volume_unit_ = new_unit; + double factor = new_unit * (1L << blip_sample_bits) / kernel_unit; + + if ( factor > 0.0 ) + { + int shift = 0; + + // if unit is really small, might need to attenuate kernel + while ( factor < 2.0 ) + { + shift++; + factor *= 2.0; + } + + if ( shift ) + { + kernel_unit >>= shift; + assert( kernel_unit > 0 ); // fails if volume unit is too low + + // keep values positive to avoid round-towards-zero of sign-preserving + // right shift for negative values + long offset = 0x8000 + (1 << (shift - 1)); + long offset2 = 0x8000 >> shift; + for ( int i = impulses_size(); i--; ) + impulses [i] = (short) (((impulses [i] + offset) >> shift) - offset2); + adjust_impulse(); + } + } + delta_factor = (int) floor( factor + 0.5 ); + //printf( "delta_factor: %d, kernel_unit: %d\n", delta_factor, kernel_unit ); + } +} +#endif + +long Blip_Buffer::read_samples( blip_sample_t* BLIP_RESTRICT out, long max_samples, int stereo ) +{ + long count = samples_avail(); + if ( count > max_samples ) + count = max_samples; + + if ( count ) + { + int const bass = BLIP_READER_BASS( *this ); + BLIP_READER_BEGIN( reader, *this ); + + if ( !stereo ) + { + for ( blip_long n = count; n; --n ) + { + blip_long s = BLIP_READER_READ( reader ); + if ( (blip_sample_t) s != s ) + s = 0x7FFF - (s >> 24); + *out++ = (blip_sample_t) s; + BLIP_READER_NEXT( reader, bass ); + } + } + else + { + for ( blip_long n = count; n; --n ) + { + blip_long s = BLIP_READER_READ( reader ); + if ( (blip_sample_t) s != s ) + s = 0x7FFF - (s >> 24); + *out = (blip_sample_t) s; + out += 2; + BLIP_READER_NEXT( reader, bass ); + } + } + BLIP_READER_END( reader, *this ); + + remove_samples( count ); + } + return count; +} + +void Blip_Buffer::mix_samples( blip_sample_t const* in, long count ) +{ + if ( buffer_size_ == silent_buf_size ) + { + assert( 0 ); + return; + } + + buf_t_* out = buffer_ + (offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2; + + int const sample_shift = blip_sample_bits - 16; + int prev = 0; + while ( count-- ) + { + blip_long s = (blip_long) *in++ << sample_shift; + *out += s - prev; + prev = s; + ++out; + } + *out -= prev; +} + diff --git a/waterbox/vb/blip/Blip_Buffer.h b/waterbox/vb/blip/Blip_Buffer.h new file mode 100644 index 0000000000..a8e90ee053 --- /dev/null +++ b/waterbox/vb/blip/Blip_Buffer.h @@ -0,0 +1,498 @@ +// Band-limited sound synthesis buffer +// Various changes and hacks for use in Mednafen. + +#ifdef __GNUC__ + #define blip_inline inline __attribute__((always_inline)) +#else + #define blip_inline inline +#endif + +#include +#include + +// Blip_Buffer 0.4.1 +#ifndef BLIP_BUFFER_H +#define BLIP_BUFFER_H + +// Internal +typedef int32_t blip_long; +typedef uint32_t blip_ulong; +typedef int64_t blip_s64; +typedef uint64_t blip_u64; + +// Time unit at source clock rate +typedef blip_long blip_time_t; + +// Output samples are 16-bit signed, with a range of -32768 to 32767 +typedef short blip_sample_t; +enum { blip_sample_max = 32767 }; + +class Blip_Buffer { +public: + typedef const char* blargg_err_t; + + // Set output sample rate and buffer length in milliseconds (1/1000 sec, defaults + // to 1/4 second), then clear buffer. Returns NULL on success, otherwise if there + // isn't enough memory, returns error without affecting current buffer setup. + blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 ); + + // Set number of source time units per second + void clock_rate( long ); + + // End current time frame of specified duration and make its samples available + // (along with any still-unread samples) for reading with read_samples(). Begins + // a new time frame at the end of the current frame. + void end_frame( blip_time_t time ); + + // Read at most 'max_samples' out of buffer into 'dest', removing them from from + // the buffer. Returns number of samples actually read and removed. If stereo is + // true, increments 'dest' one extra time after writing each sample, to allow + // easy interleving of two channels into a stereo output buffer. + long read_samples( blip_sample_t* dest, long max_samples, int stereo = 0 ); + +// Additional optional features + + // Current output sample rate + long sample_rate() const; + + // Length of buffer, in milliseconds + int length() const; + + // Number of source time units per second + long clock_rate() const; + + // Set frequency high-pass filter frequency, where higher values reduce bass more + void bass_freq( int frequency ); + + // Number of samples delay from synthesis to samples read out + int output_latency() const; + + // Remove all available samples and clear buffer to silence. If 'entire_buffer' is + // false, just clears out any samples waiting rather than the entire buffer. + void clear( int entire_buffer = 1 ); + + // Number of samples available for reading with read_samples() + long samples_avail() const; + + // Remove 'count' samples from those waiting to be read + void remove_samples( long count ); + +// Experimental features + + // Count number of clocks needed until 'count' samples will be available. + // If buffer can't even hold 'count' samples, returns number of clocks until + // buffer becomes full. + blip_time_t count_clocks( long count ) const; + + // Number of raw samples that can be mixed within frame of specified duration. + long count_samples( blip_time_t duration ) const; + + // Mix 'count' samples from 'buf' into buffer. + void mix_samples( blip_sample_t const* buf, long count ); + + // not documented yet + void set_modified() { modified_ = 1; } + int clear_modified() { int b = modified_; modified_ = 0; return b; } + typedef blip_u64 blip_resampled_time_t; + void remove_silence( long count ); + blip_resampled_time_t resampled_duration( int t ) const { return t * factor_; } + blip_resampled_time_t resampled_time( blip_time_t t ) const { return t * factor_ + offset_; } + blip_resampled_time_t clock_rate_factor( long clock_rate ) const; +public: + Blip_Buffer(); + ~Blip_Buffer(); + + // Deprecated + typedef blip_resampled_time_t resampled_time_t; + blargg_err_t sample_rate( long r ) { return set_sample_rate( r ); } + blargg_err_t sample_rate( long r, int msec ) { return set_sample_rate( r, msec ); } +private: + // noncopyable + Blip_Buffer( const Blip_Buffer& ); + Blip_Buffer& operator = ( const Blip_Buffer& ); +public: + typedef blip_time_t buf_t_; + blip_u64 factor_; + blip_resampled_time_t offset_; + buf_t_* buffer_; + blip_long buffer_size_; + blip_long reader_accum_; + int bass_shift_; +private: + long sample_rate_; + long clock_rate_; + int bass_freq_; + int length_; + int modified_; + friend class Blip_Reader; +}; + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#define BLIP_BUFFER_ACCURACY 32 +#define BLIP_PHASE_BITS 8 + +// Number of bits in resample ratio fraction. Higher values give a more accurate ratio +// but reduce maximum buffer size. +//#ifndef BLIP_BUFFER_ACCURACY +// #define BLIP_BUFFER_ACCURACY 16 +//#endif + +// Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in +// noticeable broadband noise when synthesizing high frequency square waves. +// Affects size of Blip_Synth objects since they store the waveform directly. +//#ifndef BLIP_PHASE_BITS +// #if BLIP_BUFFER_FAST +// #define BLIP_PHASE_BITS 8 +// #else +// #define BLIP_PHASE_BITS 6 +// #endif +//#endif + + // Internal + typedef blip_u64 blip_resampled_time_t; + int const blip_widest_impulse_ = 16; + int const blip_buffer_extra_ = blip_widest_impulse_ + 2; + int const blip_res = 1 << BLIP_PHASE_BITS; + class blip_eq_t; + + class Blip_Synth_Fast_ { + public: + Blip_Buffer* buf; + int last_amp; + int delta_factor; + + void volume_unit( double ); + Blip_Synth_Fast_(); + void treble_eq( blip_eq_t const& ) { } + }; + + class Blip_Synth_ { + public: + Blip_Buffer* buf; + int last_amp; + int delta_factor; + + void volume_unit( double ); + Blip_Synth_( short* impulses, int width ); + void treble_eq( blip_eq_t const& ); + private: + double volume_unit_; + short* const impulses; + int const width; + blip_long kernel_unit; + int impulses_size() const { return blip_res / 2 * width + 1; } + void adjust_impulse(); + }; + +// Quality level. Start with blip_good_quality. +const int blip_med_quality = 8; +const int blip_good_quality = 12; +const int blip_high_quality = 16; + +// Range specifies the greatest expected change in amplitude. Calculate it +// by finding the difference between the maximum and minimum expected +// amplitudes (max - min). +template +class Blip_Synth { +public: + // Set overall volume of waveform + void volume( double v ) { impl.volume_unit( v * (1.0 / (range < 0 ? -range : range)) ); } + + // Configure low-pass filter (see blip_buffer.txt) + void treble_eq( blip_eq_t const& eq ) { impl.treble_eq( eq ); } + + // Get/set Blip_Buffer used for output + Blip_Buffer* output() const { return impl.buf; } + void output( Blip_Buffer* b ) { impl.buf = b; impl.last_amp = 0; } + + // Update amplitude of waveform at given time. Using this requires a separate + // Blip_Synth for each waveform. + void update( blip_time_t time, int amplitude ); + +// Low-level interface + + // Add an amplitude transition of specified delta, optionally into specified buffer + // rather than the one set with output(). Delta can be positive or negative. + // The actual change in amplitude is delta * (volume / range) + void offset( blip_time_t, int delta, Blip_Buffer* ) const; + void offset( blip_time_t t, int delta ) const { offset( t, delta, impl.buf ); } + + // Works directly in terms of fractional output samples. Contact author for more info. + void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const; + + // Same as offset(), except code is inlined for higher performance + void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const { + offset_resampled( t * buf->factor_ + buf->offset_, delta, buf ); + } + void offset_inline( blip_time_t t, int delta ) const { + offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf ); + } + +private: +#if BLIP_BUFFER_FAST + Blip_Synth_Fast_ impl; +#else + Blip_Synth_ impl; + typedef short imp_t; + imp_t impulses [blip_res * (quality / 2) + 1]; +public: + Blip_Synth() : impl( impulses, quality ) { } +#endif +}; + +// Low-pass equalization parameters +class blip_eq_t { +public: + // Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce + // treble, small positive values (0 to 5.0) increase treble. + blip_eq_t( double treble_db = 0 ); + + // See blip_buffer.txt + blip_eq_t( double treble, long rolloff_freq, long sample_rate, long cutoff_freq = 0 ); + +private: + double treble; + long rolloff_freq; + long sample_rate; + long cutoff_freq; + void generate( float* out, int count ) const; + friend class Blip_Synth_; +}; + +int const blip_sample_bits = 30; + +// Dummy Blip_Buffer to direct sound output to, for easy muting without +// having to stop sound code. +class Silent_Blip_Buffer : public Blip_Buffer { + buf_t_ buf [blip_buffer_extra_ + 1]; +public: + // The following cannot be used (an assertion will fail if attempted): + blargg_err_t set_sample_rate( long samples_per_sec, int msec_length ); + blip_time_t count_clocks( long count ) const; + void mix_samples( blip_sample_t const* buf, long count ); + + Silent_Blip_Buffer(); +}; + + #if defined (__GNUC__) || _MSC_VER >= 1100 + #define BLIP_RESTRICT __restrict + #else + #define BLIP_RESTRICT + #endif + +// Optimized reading from Blip_Buffer, for use in custom sample output + +// Begin reading from buffer. Name should be unique to the current block. +#define BLIP_READER_BEGIN( name, blip_buffer ) \ + const Blip_Buffer::buf_t_* BLIP_RESTRICT name##_reader_buf = (blip_buffer).buffer_;\ + blip_long name##_reader_accum = (blip_buffer).reader_accum_ + +// Get value to pass to BLIP_READER_NEXT() +#define BLIP_READER_BASS( blip_buffer ) ((blip_buffer).bass_shift_) + +// Constant value to use instead of BLIP_READER_BASS(), for slightly more optimal +// code at the cost of having no bass control +int const blip_reader_default_bass = 9; + +// Current sample +#define BLIP_READER_READ( name ) (name##_reader_accum >> (blip_sample_bits - 16)) + +// Current raw sample in full internal resolution +#define BLIP_READER_READ_RAW( name ) (name##_reader_accum) + +// Advance to next sample +#define BLIP_READER_NEXT( name, bass ) \ + (void) (name##_reader_accum += *name##_reader_buf++ - (name##_reader_accum >> (bass))) + +// End reading samples from buffer. The number of samples read must now be removed +// using Blip_Buffer::remove_samples(). +#define BLIP_READER_END( name, blip_buffer ) \ + (void) ((blip_buffer).reader_accum_ = name##_reader_accum) + + +// Compatibility with older version +const long blip_unscaled = 65535; +const int blip_low_quality = blip_med_quality; +const int blip_best_quality = blip_high_quality; + +// Deprecated; use BLIP_READER macros as follows: +// Blip_Reader r; r.begin( buf ); -> BLIP_READER_BEGIN( r, buf ); +// int bass = r.begin( buf ) -> BLIP_READER_BEGIN( r, buf ); int bass = BLIP_READER_BASS( buf ); +// r.read() -> BLIP_READER_READ( r ) +// r.read_raw() -> BLIP_READER_READ_RAW( r ) +// r.next( bass ) -> BLIP_READER_NEXT( r, bass ) +// r.next() -> BLIP_READER_NEXT( r, blip_reader_default_bass ) +// r.end( buf ) -> BLIP_READER_END( r, buf ) +class Blip_Reader { +public: + int begin( Blip_Buffer& ); + blip_long read() const { return accum >> (blip_sample_bits - 16); } + blip_long read_raw() const { return accum; } + void next( int bass_shift = 9 ) { accum += *buf++ - (accum >> bass_shift); } + void end( Blip_Buffer& b ) { b.reader_accum_ = accum; } + +private: + const Blip_Buffer::buf_t_* buf; + blip_long accum; +}; + +// End of public interface + +#include + +template +blip_inline void Blip_Synth::offset_resampled( blip_resampled_time_t time, + int delta, Blip_Buffer* blip_buf ) const +{ + // Fails if time is beyond end of Blip_Buffer, due to a bug in caller code or the + // need for a longer buffer as set by set_sample_rate(). + assert( (blip_long) (time >> BLIP_BUFFER_ACCURACY) < blip_buf->buffer_size_ ); + delta *= impl.delta_factor; + blip_long* BLIP_RESTRICT buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY); + int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1)); + +#if BLIP_BUFFER_FAST + blip_long left = buf [0] + delta; + + // Kind of crappy, but doing shift after multiply results in overflow. + // Alternate way of delaying multiply by delta_factor results in worse + // sub-sample resolution. + blip_long right = (delta >> BLIP_PHASE_BITS) * phase; + left -= right; + right += buf [1]; + + buf [0] = left; + buf [1] = right; +#else + + int const fwd = (blip_widest_impulse_ - quality) / 2; + int const rev = fwd + quality - 2; + int const mid = quality / 2 - 1; + + imp_t const* BLIP_RESTRICT imp = impulses + blip_res - phase; + + #if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \ + defined (__x86_64__) || defined (__ia64__) || defined (__i386__) + + // straight forward implementation resulted in better code on GCC for x86 + + #define ADD_IMP( out, in ) \ + buf [out] += (blip_long) imp [blip_res * (in)] * delta + + #define BLIP_FWD( i ) {\ + ADD_IMP( fwd + i, i );\ + ADD_IMP( fwd + 1 + i, i + 1 );\ + } + #define BLIP_REV( r ) {\ + ADD_IMP( rev - r, r + 1 );\ + ADD_IMP( rev + 1 - r, r );\ + } + + BLIP_FWD( 0 ) + if ( quality > 8 ) BLIP_FWD( 2 ) + if ( quality > 12 ) BLIP_FWD( 4 ) + { + ADD_IMP( fwd + mid - 1, mid - 1 ); + ADD_IMP( fwd + mid , mid ); + imp = impulses + phase; + } + if ( quality > 12 ) BLIP_REV( 6 ) + if ( quality > 8 ) BLIP_REV( 4 ) + BLIP_REV( 2 ) + + ADD_IMP( rev , 1 ); + ADD_IMP( rev + 1, 0 ); + + #else + + // for RISC processors, help compiler by reading ahead of writes + + #define BLIP_FWD( i ) {\ + blip_long t0 = i0 * delta + buf [fwd + i];\ + blip_long t1 = imp [blip_res * (i + 1)] * delta + buf [fwd + 1 + i];\ + i0 = imp [blip_res * (i + 2)];\ + buf [fwd + i] = t0;\ + buf [fwd + 1 + i] = t1;\ + } + #define BLIP_REV( r ) {\ + blip_long t0 = i0 * delta + buf [rev - r];\ + blip_long t1 = imp [blip_res * r] * delta + buf [rev + 1 - r];\ + i0 = imp [blip_res * (r - 1)];\ + buf [rev - r] = t0;\ + buf [rev + 1 - r] = t1;\ + } + + blip_long i0 = *imp; + BLIP_FWD( 0 ) + if ( quality > 8 ) BLIP_FWD( 2 ) + if ( quality > 12 ) BLIP_FWD( 4 ) + { + blip_long t0 = i0 * delta + buf [fwd + mid - 1]; + blip_long t1 = imp [blip_res * mid] * delta + buf [fwd + mid ]; + imp = impulses + phase; + i0 = imp [blip_res * mid]; + buf [fwd + mid - 1] = t0; + buf [fwd + mid ] = t1; + } + if ( quality > 12 ) BLIP_REV( 6 ) + if ( quality > 8 ) BLIP_REV( 4 ) + BLIP_REV( 2 ) + + blip_long t0 = i0 * delta + buf [rev ]; + blip_long t1 = *imp * delta + buf [rev + 1]; + buf [rev ] = t0; + buf [rev + 1] = t1; + #endif + +#endif +} + +#undef BLIP_FWD +#undef BLIP_REV + +template +#if BLIP_BUFFER_FAST + blip_inline +#endif +void Blip_Synth::offset( blip_time_t t, int delta, Blip_Buffer* buf ) const +{ + offset_resampled( t * buf->factor_ + buf->offset_, delta, buf ); +} + +template +#if BLIP_BUFFER_FAST + blip_inline +#endif +void Blip_Synth::update( blip_time_t t, int amp ) +{ + int delta = amp - impl.last_amp; + impl.last_amp = amp; + offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf ); +} + +blip_inline blip_eq_t::blip_eq_t( double t ) : + treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), cutoff_freq( 0 ) { } +blip_inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) : + treble( t ), rolloff_freq( rf ), sample_rate( sr ), cutoff_freq( cf ) { } + +blip_inline int Blip_Buffer::length() const { return length_; } +blip_inline long Blip_Buffer::samples_avail() const { return (long) (offset_ >> BLIP_BUFFER_ACCURACY); } +blip_inline long Blip_Buffer::sample_rate() const { return sample_rate_; } +blip_inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; } +blip_inline long Blip_Buffer::clock_rate() const { return clock_rate_; } +blip_inline void Blip_Buffer::clock_rate( long cps ) { factor_ = clock_rate_factor( clock_rate_ = cps ); } + +blip_inline int Blip_Reader::begin( Blip_Buffer& blip_buf ) +{ + buf = blip_buf.buffer_; + accum = blip_buf.reader_accum_; + return blip_buf.bass_shift_; +} + +int const blip_max_length = 0; +int const blip_default_length = 250; + +#endif diff --git a/waterbox/vb/endian.h b/waterbox/vb/endian.h new file mode 100644 index 0000000000..e78a0c577f --- /dev/null +++ b/waterbox/vb/endian.h @@ -0,0 +1,494 @@ +/******************************************************************************/ +/* Mednafen - Multi-system Emulator */ +/******************************************************************************/ +/* endian.h: +** Copyright (C) 2006-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_ENDIAN_H +#define __MDFN_ENDIAN_H + +void Endian_A16_Swap(void *src, uint32 nelements); +void Endian_A32_Swap(void *src, uint32 nelements); +void Endian_A64_Swap(void *src, uint32 nelements); + +void Endian_A16_NE_LE(void *src, uint32 nelements); +void Endian_A32_NE_LE(void *src, uint32 nelements); +void Endian_A64_NE_LE(void *src, uint32 nelements); + +void Endian_A16_NE_BE(void *src, uint32 nelements); +void Endian_A32_NE_BE(void *src, uint32 nelements); +void Endian_A64_NE_BE(void *src, uint32 nelements); + +void Endian_V_NE_LE(void* p, size_t len); +void Endian_V_NE_BE(void* p, size_t len); + +// +// +// + +static INLINE uint32 BitsExtract(const uint8* ptr, const size_t bit_offset, const size_t bit_count) +{ + uint32 ret = 0; + + for(size_t x = 0; x < bit_count; x++) + { + size_t co = bit_offset + x; + bool b = (ptr[co >> 3] >> (co & 7)) & 1; + + ret |= (uint64)b << x; + } + + return ret; +} + +static INLINE void BitsIntract(uint8* ptr, const size_t bit_offset, const size_t bit_count, uint32 value) +{ + for(size_t x = 0; x < bit_count; x++) + { + size_t co = bit_offset + x; + bool b = (value >> x) & 1; + uint8 tmp = ptr[co >> 3]; + + tmp &= ~(1 << (co & 7)); + tmp |= b << (co & 7); + + ptr[co >> 3] = tmp; + } +} + +/* + Regarding safety of calling MDFN_*sb on dynamically-allocated memory with new uint8[], see C++ standard 3.7.3.1(i.e. it should be + safe provided the offsets into the memory are aligned/multiples of the MDFN_*sb access type). malloc()'d and calloc()'d + memory should be safe as well. + + Statically-allocated arrays/memory should be unioned with a big POD type or C++11 "alignas"'d. (May need to audit code to ensure + this is being done). +*/ + +static INLINE uint16 MDFN_bswap16(uint16 v) +{ + return (v << 8) | (v >> 8); +} + +static INLINE uint32 MDFN_bswap32(uint32 v) +{ + return (v << 24) | ((v & 0xFF00) << 8) | ((v >> 8) & 0xFF00) | (v >> 24); +} + +static INLINE uint64 MDFN_bswap64(uint64 v) +{ + return (v << 56) | (v >> 56) | ((v & 0xFF00) << 40) | ((v >> 40) & 0xFF00) | ((uint64)MDFN_bswap32(v >> 16) << 16); +} + +#ifdef LSB_FIRST + #define MDFN_ENDIANH_IS_BIGENDIAN 0 +#else + #define MDFN_ENDIANH_IS_BIGENDIAN 1 +#endif + +// +// X endian. +// +template +static INLINE T MDFN_deXsb(const void* ptr) +{ + T tmp; + + memcpy(&tmp, MDFN_ASSUME_ALIGNED(ptr, (aligned ? sizeof(T) : 1)), sizeof(T)); + + if(isbigendian != -1 && isbigendian != MDFN_ENDIANH_IS_BIGENDIAN) + { + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Gummy penguins."); + + if(sizeof(T) == 8) + return MDFN_bswap64(tmp); + else if(sizeof(T) == 4) + return MDFN_bswap32(tmp); + else if(sizeof(T) == 2) + return MDFN_bswap16(tmp); + } + + return tmp; +} + +// +// Native endian. +// +template +static INLINE T MDFN_densb(const void* ptr) +{ + return MDFN_deXsb<-1, T, aligned>(ptr); +} + +// +// Little endian. +// +template +static INLINE T MDFN_delsb(const void* ptr) +{ + return MDFN_deXsb<0, T, aligned>(ptr); +} + +template +static INLINE uint16 MDFN_de16lsb(const void* ptr) +{ + return MDFN_delsb(ptr); +} + +static INLINE uint32 MDFN_de24lsb(const void* ptr) +{ + const uint8* ptr_u8 = (const uint8*)ptr; + + return (ptr_u8[0] << 0) | (ptr_u8[1] << 8) | (ptr_u8[2] << 16); +} + +template +static INLINE uint32 MDFN_de32lsb(const void* ptr) +{ + return MDFN_delsb(ptr); +} + +template +static INLINE uint64 MDFN_de64lsb(const void* ptr) +{ + return MDFN_delsb(ptr); +} + +// +// Big endian. +// +template +static INLINE T MDFN_demsb(const void* ptr) +{ + return MDFN_deXsb<1, T, aligned>(ptr); +} + +template +static INLINE uint16 MDFN_de16msb(const void* ptr) +{ + return MDFN_demsb(ptr); +} + +static INLINE uint32 MDFN_de24msb(const void* ptr) +{ + const uint8* ptr_u8 = (const uint8*)ptr; + + return (ptr_u8[0] << 16) | (ptr_u8[1] << 8) | (ptr_u8[2] << 0); +} + +template +static INLINE uint32 MDFN_de32msb(const void* ptr) +{ + return MDFN_demsb(ptr); +} + +template +static INLINE uint64 MDFN_de64msb(const void* ptr) +{ + return MDFN_demsb(ptr); +} + +// +// +// +// +// +// +// +// + +// +// X endian. +// +template +static INLINE void MDFN_enXsb(void* ptr, T value) +{ + T tmp = value; + + if(isbigendian != -1 && isbigendian != MDFN_ENDIANH_IS_BIGENDIAN) + { + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Gummy penguins."); + + if(sizeof(T) == 8) + tmp = MDFN_bswap64(value); + else if(sizeof(T) == 4) + tmp = MDFN_bswap32(value); + else if(sizeof(T) == 2) + tmp = MDFN_bswap16(value); + } + + memcpy(MDFN_ASSUME_ALIGNED(ptr, (aligned ? sizeof(T) : 1)), &tmp, sizeof(T)); +} + +// +// Native endian. +// +template +static INLINE void MDFN_ennsb(void* ptr, T value) +{ + MDFN_enXsb<-1, T, aligned>(ptr, value); +} + +// +// Little endian. +// +template +static INLINE void MDFN_enlsb(void* ptr, T value) +{ + MDFN_enXsb<0, T, aligned>(ptr, value); +} + +template +static INLINE void MDFN_en16lsb(void* ptr, uint16 value) +{ + MDFN_enlsb(ptr, value); +} + +static INLINE void MDFN_en24lsb(void* ptr, uint32 value) +{ + uint8* ptr_u8 = (uint8*)ptr; + + ptr_u8[0] = value >> 0; + ptr_u8[1] = value >> 8; + ptr_u8[2] = value >> 16; +} + +template +static INLINE void MDFN_en32lsb(void* ptr, uint32 value) +{ + MDFN_enlsb(ptr, value); +} + +template +static INLINE void MDFN_en64lsb(void* ptr, uint64 value) +{ + MDFN_enlsb(ptr, value); +} + + +// +// Big endian. +// +template +static INLINE void MDFN_enmsb(void* ptr, T value) +{ + MDFN_enXsb<1, T, aligned>(ptr, value); +} + +template +static INLINE void MDFN_en16msb(void* ptr, uint16 value) +{ + MDFN_enmsb(ptr, value); +} + +static INLINE void MDFN_en24msb(void* ptr, uint32 value) +{ + uint8* ptr_u8 = (uint8*)ptr; + + ptr_u8[0] = value >> 16; + ptr_u8[1] = value >> 8; + ptr_u8[2] = value >> 0; +} + +template +static INLINE void MDFN_en32msb(void* ptr, uint32 value) +{ + MDFN_enmsb(ptr, value); +} + +template +static INLINE void MDFN_en64msb(void* ptr, uint64 value) +{ + MDFN_enmsb(ptr, value); +} + + +// +// +// +// +// +// + +template +static INLINE uint8* ne16_ptr_be(BT* const base, const size_t byte_offset) +{ +#ifdef MSB_FIRST + return (uint8*)base + (byte_offset &~ (sizeof(T) - 1)); +#else + return (uint8*)base + (((byte_offset &~ (sizeof(T) - 1)) ^ (2 - std::min(2, sizeof(T))))); +#endif +} + +template +static INLINE void ne16_wbo_be(uint16* const base, const size_t byte_offset, const T value) +{ + uint8* const ptr = ne16_ptr_be(base, byte_offset); + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size"); + + if(sizeof(T) == 4) + { + uint16* const ptr16 = (uint16*)ptr; + + ptr16[0] = value >> 16; + ptr16[1] = value; + } + else + *(T*)ptr = value; +} + +template +static INLINE T ne16_rbo_be(const uint16* const base, const size_t byte_offset) +{ + uint8* const ptr = ne16_ptr_be(base, byte_offset); + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size"); + + if(sizeof(T) == 4) + { + uint16* const ptr16 = (uint16*)ptr; + T tmp; + + tmp = ptr16[0] << 16; + tmp |= ptr16[1]; + + return tmp; + } + else + return *(T*)ptr; +} + +template +static INLINE void ne16_rwbo_be(uint16* const base, const size_t byte_offset, T* value) +{ + if(IsWrite) + ne16_wbo_be(base, byte_offset, *value); + else + *value = ne16_rbo_be(base, byte_offset); +} + +// +// +// + +template +static INLINE uint8* ne16_ptr_le(BT* const base, const size_t byte_offset) +{ +#ifdef LSB_FIRST + return (uint8*)base + (byte_offset &~ (sizeof(T) - 1)); +#else + return (uint8*)base + (((byte_offset &~ (sizeof(T) - 1)) ^ (2 - std::min(2, sizeof(T))))); +#endif +} + +template +static INLINE void ne16_wbo_le(uint16* const base, const size_t byte_offset, const T value) +{ + uint8* const ptr = ne16_ptr_le(base, byte_offset); + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size"); + + if(sizeof(T) == 4) + { + uint16* const ptr16 = (uint16*)ptr; + + ptr16[0] = value; + ptr16[1] = value >> 16; + } + else + *(T*)ptr = value; +} + +template +static INLINE T ne16_rbo_le(const uint16* const base, const size_t byte_offset) +{ + uint8* const ptr = ne16_ptr_le(base, byte_offset); + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size"); + + if(sizeof(T) == 4) + { + uint16* const ptr16 = (uint16*)ptr; + T tmp; + + tmp = ptr16[0]; + tmp |= ptr16[1] << 16; + + return tmp; + } + else + return *(T*)ptr; +} + + +template +static INLINE void ne16_rwbo_le(uint16* const base, const size_t byte_offset, T* value) +{ + if(IsWrite) + ne16_wbo_le(base, byte_offset, *value); + else + *value = ne16_rbo_le(base, byte_offset); +} + +// +// +// +template +static INLINE uint8* ne64_ptr_be(uint64* const base, const size_t byte_offset) +{ +#ifdef MSB_FIRST + return (uint8*)base + (byte_offset &~ (sizeof(T) - 1)); +#else + return (uint8*)base + (((byte_offset &~ (sizeof(T) - 1)) ^ (8 - sizeof(T)))); +#endif +} + +template +static INLINE void ne64_wbo_be(uint64* const base, const size_t byte_offset, const T value) +{ + uint8* const ptr = ne64_ptr_be(base, byte_offset); + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Unsupported type size"); + + memcpy(MDFN_ASSUME_ALIGNED(ptr, sizeof(T)), &value, sizeof(T)); +} + +template +static INLINE T ne64_rbo_be(uint64* const base, const size_t byte_offset) +{ + uint8* const ptr = ne64_ptr_be(base, byte_offset); + T ret; + + static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "Unsupported type size"); + + memcpy(&ret, MDFN_ASSUME_ALIGNED(ptr, sizeof(T)), sizeof(T)); + + return ret; +} + +template +static INLINE void ne64_rwbo_be(uint64* const base, const size_t byte_offset, T* value) +{ + if(IsWrite) + ne64_wbo_be(base, byte_offset, *value); + else + *value = ne64_rbo_be(base, byte_offset); +} + +#endif diff --git a/waterbox/vb/git.h b/waterbox/vb/git.h new file mode 100644 index 0000000000..d9e8108b3d --- /dev/null +++ b/waterbox/vb/git.h @@ -0,0 +1,130 @@ +#pragma once + +struct MDFN_Surface +{ + uint32 *pixels; + int pitch32; +}; + +struct MDFN_Rect +{ + int x, y, w, h; +}; + +struct EmulateSpecStruct +{ + // Pitch(32-bit) must be equal to width and >= the "fb_width" specified in the MDFNGI struct for the emulated system. + // Height must be >= to the "fb_height" specified in the MDFNGI struct for the emulated system. + // The framebuffer pointed to by surface->pixels is written to by the system emulation code. + uint32 *pixels; + + // Pointer to sound buffer, set by the driver code, that the emulation code should render sound to. + // Guaranteed to be at least 500ms in length, but emulation code really shouldn't exceed 40ms or so. Additionally, if emulation code + // generates >= 100ms, + // DEPRECATED: Emulation code may set this pointer to a sound buffer internal to the emulation module. + int16 *SoundBuf; + + // Number of cycles that this frame consumed, using MDFNGI::MasterClock as a time base. + // Set by emulation code. + int64 MasterCycles; + + // Set by the system emulation code every frame, to denote the horizontal and vertical offsets of the image, and the size + // of the image. If the emulated system sets the elements of LineWidths, then the width(w) of this structure + // is ignored while drawing the image. + MDFN_Rect DisplayRect; + + // Maximum size of the sound buffer, in frames. Set by the driver code. + int32 SoundBufMaxSize; + + // Number of frames currently in internal sound buffer. Set by the system emulation code, to be read by the driver code. + int32 SoundBufSize; + + // 0 UDLR SelectStartBA UDLR(right dpad) LtrigRtrig 13 + int32 Buttons; + + // set by core, true if lagged + int32 Lagged; +}; + +/*typedef struct +{ + + void (*Emulate)(EmulateSpecStruct *espec); + void (*TransformInput)(void); // Called before Emulate, and within MDFN_MidSync(), to implement stuff like setting-controlled PC Engine SEL+RUN button exclusion in a way + // that won't cause desyncs with movies and netplay. + + void (*SetInput)(unsigned port, const char *type, uint8* data); + bool (*SetMedia)(uint32 drive_idx, uint32 state_idx, uint32 media_idx, uint32 orientation_idx); + + + // Called when netplay starts, or the controllers controlled by local players changes during + // an existing netplay session. Called with ~(uint64)0 when netplay ends. + // (For future use in implementing portable console netplay) + void (*NPControlNotif)(uint64 c); + + const MDFNSetting *Settings; + + // Time base for EmulateSpecStruct::MasterCycles + // MasterClock must be >= MDFN_MASTERCLOCK_FIXED(1.0) + // All or part of the fractional component may be ignored in some timekeeping operations in the emulator to prevent integer overflow, + // so it is unwise to have a fractional component when the integral component is very small(less than say, 10000). + #define MDFN_MASTERCLOCK_FIXED(n) ((int64)((double)(n) * (1LL << 32))) + int64 MasterClock; + + // Nominal frames per second * 65536 * 256, truncated. + // May be deprecated in the future due to many systems having slight frame rate programmability. + uint32 fps; + + // multires is a hint that, if set, indicates that the system has fairly programmable video modes(particularly, the ability + // to display multiple horizontal resolutions, such as the PCE, PC-FX, or Genesis). In practice, it will cause the driver + // code to set the linear interpolation on by default. + // + // lcm_width and lcm_height are the least common multiples of all possible + // resolutions in the frame buffer as specified by DisplayRect/LineWidths(Ex for PCE: widths of 256, 341.333333, 512, + // lcm = 1024) + // + // nominal_width and nominal_height specify the resolution that Mednafen should display + // the framebuffer image in at 1x scaling, scaled from the dimensions of DisplayRect, and optionally the LineWidths array + // passed through espec to the Emulate() function. + // + bool multires; + + int lcm_width; + int lcm_height; + + + int nominal_width; + int nominal_height; + + int fb_width; // Width of the framebuffer(not necessarily width of the image). MDFN_Surface width should be >= this. + int fb_height; // Height of the framebuffer passed to the Emulate() function(not necessarily height of the image) + + int soundchan; // Number of output sound channels. Only values of 1 and 2 are currently supported. + + + int rotated; + + std::string name; // Game name, UTF-8 encoding + uint8 MD5[16]; + uint8 GameSetMD5[16]; // A unique ID for the game set this CD belongs to, only used in PC-FX emulation. + bool GameSetMD5Valid; // True if GameSetMD5 is valid. + + VideoSystems VideoSystem; + GameMediumTypes GameType; // Deprecated. + + RMD_Layout* RMD; + + const char *cspecial; // Special cart expansion: DIP switches, barcode reader, etc. + + std::vectorDesiredInput; // Desired input device for the input ports, NULL for don't care + + // For mouse relative motion. + double mouse_sensitivity; + + + // + // For absolute coordinates(IDIT_X_AXIS and IDIT_Y_AXIS), usually mapped to a mouse(hence the naming). + // + float mouse_scale_x, mouse_scale_y; + float mouse_offs_x, mouse_offs_y; +} MDFNGI;*/ diff --git a/waterbox/vb/input.cpp b/waterbox/vb/input.cpp new file mode 100644 index 0000000000..b895f9a5d9 --- /dev/null +++ b/waterbox/vb/input.cpp @@ -0,0 +1,196 @@ +/******************************************************************************/ +/* Mednafen Virtual Boy Emulation Module */ +/******************************************************************************/ +/* input.cpp: +** Copyright (C) 2010-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "vb.h" +#include "input.h" + +namespace MDFN_IEN_VB +{ +static bool InstantReadHack; + +static bool IntPending; + +static uint16 PadData; +static uint16 PadLatched; + +static uint8 SCR; +static uint16 SDR; + +#define SCR_S_ABT_DIS 0x01 +#define SCR_SI_STAT 0x02 +#define SCR_HW_SI 0x04 +#define SCR_SOFT_CLK 0x10 + +#define SCR_PARA_SI 0x20 +#define SCR_K_INT_INH 0x80 + +static uint32 ReadBitPos; +static int32 ReadCounter; + +static v810_timestamp_t last_ts; + +void VBINPUT_Init(void) +{ + InstantReadHack = true; +} + +void VBINPUT_SetInstantReadHack(bool enabled) +{ + InstantReadHack = enabled; +} + +uint8 VBINPUT_Read(v810_timestamp_t ×tamp, uint32 A) +{ + uint8 ret = 0; + + VBINPUT_Update(timestamp); + + //if(((A & 0xFF) == 0x10 || (A & 0xFF) == 0x14)) + // printf("Read %d\n", timestamp); + + //if(((A & 0xFF) == 0x10 || (A & 0xFF) == 0x14) && ReadCounter > 0) + //{ + // printf("Input port read during hardware transfer: %08x %d\n", A, timestamp); + //} + + switch (A & 0xFF) + { + case 0x10: + if (InstantReadHack) + ret = PadData; + else + ret = SDR & 0xFF; + break; + + case 0x14: + if (InstantReadHack) + ret = PadData >> 8; + else + ret = SDR >> 8; + break; + + case 0x28: + ret = SCR | (0x40 | 0x08 | SCR_HW_SI); + if (ReadCounter > 0) + ret |= SCR_SI_STAT; + break; + } + + // printf("Input Read: %08x %02x\n", A, ret); + VB_SetEvent(VB_EVENT_INPUT, (ReadCounter > 0) ? (timestamp + ReadCounter) : VB_EVENT_NONONO); + + return (ret); +} + +void VBINPUT_Write(v810_timestamp_t ×tamp, uint32 A, uint8 V) +{ + VBINPUT_Update(timestamp); + + //printf("Input write: %d, %08x %02x\n", timestamp, A, V); + switch (A & 0xFF) + { + case 0x28: + if ((V & SCR_HW_SI) && !(SCR & SCR_S_ABT_DIS) && ReadCounter <= 0) + { + //printf("Start Read: %d\n", timestamp); + PadLatched = PadData; + ReadBitPos = 0; + ReadCounter = 640; + } + + if (V & SCR_S_ABT_DIS) + { + ReadCounter = 0; + ReadBitPos = 0; + } + + if (V & SCR_K_INT_INH) + { + IntPending = false; + VBIRQ_Assert(VBIRQ_SOURCE_INPUT, IntPending); + } + + SCR = V & (0x80 | 0x20 | 0x10 | 1); + break; + } + + VB_SetEvent(VB_EVENT_INPUT, (ReadCounter > 0) ? (timestamp + ReadCounter) : VB_EVENT_NONONO); +} + +void VBINPUT_Frame(const void* ptr) +{ + PadData = (MDFN_de16lsb(ptr) << 2) | 0x2; +} + +v810_timestamp_t VBINPUT_Update(const v810_timestamp_t timestamp) +{ + int32 clocks = timestamp - last_ts; + + if (ReadCounter > 0) + { + ReadCounter -= clocks; + + while (ReadCounter <= 0) + { + SDR &= ~(1 << ReadBitPos); + SDR |= PadLatched & (1 << ReadBitPos); + + ReadBitPos++; + if (ReadBitPos < 16) + ReadCounter += 640; + else + { + //printf("Read End: %d\n", timestamp); + if (!(SCR & SCR_K_INT_INH)) + { + //printf("Input IRQ: %d\n", timestamp); + IntPending = true; + VBIRQ_Assert(VBIRQ_SOURCE_INPUT, IntPending); + } + break; + } + } + } + + last_ts = timestamp; + + return ((ReadCounter > 0) ? (timestamp + ReadCounter) : VB_EVENT_NONONO); +} + +void VBINPUT_ResetTS(void) +{ + last_ts = 0; +} + +void VBINPUT_Power(void) +{ + last_ts = 0; + PadData = 0; + PadLatched = 0; + SDR = 0; + SCR = 0; + ReadBitPos = 0; + ReadCounter = 0; + IntPending = false; + + VBIRQ_Assert(VBIRQ_SOURCE_INPUT, 0); +} +} diff --git a/waterbox/vb/input.h b/waterbox/vb/input.h new file mode 100644 index 0000000000..1ee57c19d7 --- /dev/null +++ b/waterbox/vb/input.h @@ -0,0 +1,45 @@ +/******************************************************************************/ +/* Mednafen Virtual Boy Emulation Module */ +/******************************************************************************/ +/* input.h: +** Copyright (C) 2010-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __VB_INPUT_H +#define __VB_INPUT_H + +namespace MDFN_IEN_VB +{ + +void VBINPUT_Init(void) MDFN_COLD; +void VBINPUT_SetInstantReadHack(bool); + +void VBINPUT_SetInput(unsigned port, const char *type, uint8 *ptr); + +uint8 VBINPUT_Read(v810_timestamp_t ×tamp, uint32 A); + +void VBINPUT_Write(v810_timestamp_t ×tamp, uint32 A, uint8 V); + +void VBINPUT_Frame(const void* ptr); + +int32 VBINPUT_Update(const int32 timestamp); +void VBINPUT_ResetTS(void); + + +void VBINPUT_Power(void); +} +#endif diff --git a/waterbox/vb/math_ops.h b/waterbox/vb/math_ops.h new file mode 100644 index 0000000000..4154f2d49b --- /dev/null +++ b/waterbox/vb/math_ops.h @@ -0,0 +1,278 @@ +/******************************************************************************/ +/* Mednafen - Multi-system Emulator */ +/******************************************************************************/ +/* math_ops.h: +** Copyright (C) 2007-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +/* +** Some ideas from: +** blargg +** http://graphics.stanford.edu/~seander/bithacks.html +*/ + +#ifndef __MDFN_MATH_OPS_H +#define __MDFN_MATH_OPS_H + +#if defined(_MSC_VER) + #include +#endif + +static INLINE unsigned MDFN_lzcount16_0UD(uint16 v) +{ + #if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER) + return 15 ^ 31 ^ __builtin_clz(v); + #elif defined(_MSC_VER) + unsigned long idx; + + _BitScanReverse(&idx, v); + + return 15 ^ idx; + #else + unsigned ret = 0; + unsigned tmp; + + tmp = !(v & 0xFF00) << 3; v <<= tmp; ret += tmp; + tmp = !(v & 0xF000) << 2; v <<= tmp; ret += tmp; + tmp = !(v & 0xC000) << 1; v <<= tmp; ret += tmp; + tmp = !(v & 0x8000) << 0; ret += tmp; + + return(ret); + #endif +} + +static INLINE unsigned MDFN_lzcount32_0UD(uint32 v) +{ + #if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER) + return __builtin_clz(v); + #elif defined(_MSC_VER) + unsigned long idx; + + _BitScanReverse(&idx, v); + + return 31 ^ idx; + #else + unsigned ret = 0; + unsigned tmp; + + tmp = !(v & 0xFFFF0000) << 4; v <<= tmp; ret += tmp; + tmp = !(v & 0xFF000000) << 3; v <<= tmp; ret += tmp; + tmp = !(v & 0xF0000000) << 2; v <<= tmp; ret += tmp; + tmp = !(v & 0xC0000000) << 1; v <<= tmp; ret += tmp; + tmp = !(v & 0x80000000) << 0; ret += tmp; + + return(ret); + #endif +} + +static INLINE unsigned MDFN_lzcount64_0UD(uint64 v) +{ + #if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER) + return __builtin_clzll(v); + #elif defined(_MSC_VER) + #if defined(_WIN64) + unsigned long idx; + _BitScanReverse64(&idx, v); + return 63 ^ idx; + #else + unsigned long idx0; + unsigned long idx1; + + _BitScanReverse(&idx1, v >> 0); + idx1 -= 32; + if(!_BitScanReverse(&idx0, v >> 32)) + idx0 = idx1; + + idx0 += 32; + + return 63 ^ idx0; + #endif + #else + unsigned ret = 0; + unsigned tmp; + + tmp = !(v & 0xFFFFFFFF00000000ULL) << 5; v <<= tmp; ret += tmp; + tmp = !(v & 0xFFFF000000000000ULL) << 4; v <<= tmp; ret += tmp; + tmp = !(v & 0xFF00000000000000ULL) << 3; v <<= tmp; ret += tmp; + tmp = !(v & 0xF000000000000000ULL) << 2; v <<= tmp; ret += tmp; + tmp = !(v & 0xC000000000000000ULL) << 1; v <<= tmp; ret += tmp; + tmp = !(v & 0x8000000000000000ULL) << 0; ret += tmp; + + return(ret); + #endif +} + +static INLINE unsigned MDFN_tzcount16_0UD(uint16 v) +{ + #if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER) + return __builtin_ctz(v); + #elif defined(_MSC_VER) + unsigned long idx; + + _BitScanForward(&idx, v); + + return idx; + #else + unsigned ret = 0; + unsigned tmp; + + tmp = !( (uint8)v) << 3; v >>= tmp; ret += tmp; + tmp = !(v & 0x000F) << 2; v >>= tmp; ret += tmp; + tmp = !(v & 0x0003) << 1; v >>= tmp; ret += tmp; + tmp = !(v & 0x0001) << 0; ret += tmp; + + return ret; + #endif +} + +static INLINE unsigned MDFN_tzcount32_0UD(uint32 v) +{ + #if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER) + return __builtin_ctz(v); + #elif defined(_MSC_VER) + unsigned long idx; + + _BitScanForward(&idx, v); + + return idx; + #else + unsigned ret = 0; + unsigned tmp; + + tmp = !((uint16)v) << 4; v >>= tmp; ret += tmp; + tmp = !( (uint8)v) << 3; v >>= tmp; ret += tmp; + tmp = !(v & 0x000F) << 2; v >>= tmp; ret += tmp; + tmp = !(v & 0x0003) << 1; v >>= tmp; ret += tmp; + tmp = !(v & 0x0001) << 0; ret += tmp; + + return ret; + #endif +} + +static INLINE unsigned MDFN_tzcount64_0UD(uint64 v) +{ + #if defined(__GNUC__) || defined(__clang__) || defined(__ICC) || defined(__INTEL_COMPILER) + return __builtin_ctzll(v); + #elif defined(_MSC_VER) + #if defined(_WIN64) + unsigned long idx; + _BitScanForward64(&idx, v); + return idx; + #else + unsigned long idx0, idx1; + + _BitScanForward(&idx1, v >> 32); + idx1 += 32; + if(!_BitScanForward(&idx0, v)) + idx0 = idx1; + + return idx0; + #endif + #else + unsigned ret = 0; + unsigned tmp; + + tmp = !((uint32)v) << 5; v >>= tmp; ret += tmp; + tmp = !((uint16)v) << 4; v >>= tmp; ret += tmp; + tmp = !( (uint8)v) << 3; v >>= tmp; ret += tmp; + tmp = !(v & 0x000F) << 2; v >>= tmp; ret += tmp; + tmp = !(v & 0x0003) << 1; v >>= tmp; ret += tmp; + tmp = !(v & 0x0001) << 0; ret += tmp; + + return ret; + #endif +} + +// +// Result is defined for all possible inputs(including 0). +// +static INLINE unsigned MDFN_lzcount16(uint16 v) { return !v ? 16 : MDFN_lzcount16_0UD(v); } +static INLINE unsigned MDFN_lzcount32(uint32 v) { return !v ? 32 : MDFN_lzcount32_0UD(v); } +static INLINE unsigned MDFN_lzcount64(uint64 v) { return !v ? 64 : MDFN_lzcount64_0UD(v); } + +static INLINE unsigned MDFN_tzcount16(uint16 v) { return !v ? 16 : MDFN_tzcount16_0UD(v); } +static INLINE unsigned MDFN_tzcount32(uint32 v) { return !v ? 32 : MDFN_tzcount32_0UD(v); } +static INLINE unsigned MDFN_tzcount64(uint64 v) { return !v ? 64 : MDFN_tzcount64_0UD(v); } + +static INLINE unsigned MDFN_log2(uint32 v) { return 31 ^ MDFN_lzcount32_0UD(v | 1); } +static INLINE unsigned MDFN_log2(uint64 v) { return 63 ^ MDFN_lzcount64_0UD(v | 1); } + +static INLINE unsigned MDFN_log2(int32 v) { return MDFN_log2((uint32)v); } +static INLINE unsigned MDFN_log2(int64 v) { return MDFN_log2((uint64)v); } + +// Rounds up to the nearest power of 2(treats input as unsigned to a degree, but be aware of integer promotion rules). +// Returns 0 on overflow. +static INLINE uint64 round_up_pow2(uint32 v) { uint64 tmp = (uint64)1 << MDFN_log2(v); return tmp << (tmp < v); } +static INLINE uint64 round_up_pow2(uint64 v) { uint64 tmp = (uint64)1 << MDFN_log2(v); return tmp << (tmp < v); } + +static INLINE uint64 round_up_pow2(int32 v) { return round_up_pow2((uint32)v); } +static INLINE uint64 round_up_pow2(int64 v) { return round_up_pow2((uint64)v); } + +// Rounds to the nearest power of 2(treats input as unsigned to a degree, but be aware of integer promotion rules). +static INLINE uint64 round_nearest_pow2(uint32 v, bool round_half_up = true) { uint64 tmp = (uint64)1 << MDFN_log2(v); return tmp << (v && (((v - tmp) << 1) >= (tmp + !round_half_up))); } +static INLINE uint64 round_nearest_pow2(uint64 v, bool round_half_up = true) { uint64 tmp = (uint64)1 << MDFN_log2(v); return tmp << (v && (((v - tmp) << 1) >= (tmp + !round_half_up))); } + +static INLINE uint64 round_nearest_pow2(int32 v, bool round_half_up = true) { return round_nearest_pow2((uint32)v, round_half_up); } +static INLINE uint64 round_nearest_pow2(int64 v, bool round_half_up = true) { return round_nearest_pow2((uint64)v, round_half_up); } + +// Some compilers' optimizers and some platforms might fubar the generated code from these macros, +// so some tests are run in...tests.cpp +#define sign_8_to_s16(_value) ((int16)(int8)(_value)) +#define sign_9_to_s16(_value) (((int16)((unsigned int)(_value) << 7)) >> 7) +#define sign_10_to_s16(_value) (((int16)((uint32)(_value) << 6)) >> 6) +#define sign_11_to_s16(_value) (((int16)((uint32)(_value) << 5)) >> 5) +#define sign_12_to_s16(_value) (((int16)((uint32)(_value) << 4)) >> 4) +#define sign_13_to_s16(_value) (((int16)((uint32)(_value) << 3)) >> 3) +#define sign_14_to_s16(_value) (((int16)((uint32)(_value) << 2)) >> 2) +#define sign_15_to_s16(_value) (((int16)((uint32)(_value) << 1)) >> 1) + +// This obviously won't convert higher-than-32 bit numbers to signed 32-bit ;) +// Also, this shouldn't be used for 8-bit and 16-bit signed numbers, since you can +// convert those faster with typecasts... +#define sign_x_to_s32(_bits, _value) (((int32)((uint32)(_value) << (32 - _bits))) >> (32 - _bits)) + +static INLINE int32 clamp_to_u8(int32 i) +{ + if(i & 0xFFFFFF00) + i = (((~i) >> 30) & 0xFF); + + return(i); +} + +static INLINE int32 clamp_to_u16(int32 i) +{ + if(i & 0xFFFF0000) + i = (((~i) >> 31) & 0xFFFF); + + return(i); +} + +template static INLINE void clamp(T *val, U minimum, V maximum) +{ + if(*val < minimum) + { + //printf("Warning: clamping to minimum(%d)\n", (int)minimum); + *val = minimum; + } + if(*val > maximum) + { + //printf("Warning: clamping to maximum(%d)\n", (int)maximum); + *val = maximum; + } +} + +#endif diff --git a/waterbox/vb/timer.cpp b/waterbox/vb/timer.cpp new file mode 100644 index 0000000000..43cfe5fd45 --- /dev/null +++ b/waterbox/vb/timer.cpp @@ -0,0 +1,233 @@ +/******************************************************************************/ +/* Mednafen Virtual Boy Emulation Module */ +/******************************************************************************/ +/* timer.cpp: +** Copyright (C) 2010-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "vb.h" +#include "timer.h" + +namespace MDFN_IEN_VB +{ + +#define TC_TENABLE 0x01 +#define TC_ZSTAT 0x02 +#define TC_ZSTATCLR 0x04 +#define TC_TIMZINT 0x08 +#define TC_TCLKSEL 0x10 + +static uint8 TimerControl; +static uint16 TimerReloadValue; +static uint16 TimerCounter; +static int32 TimerDivider; +static v810_timestamp_t TimerLastTS; +static bool TimerStatus, TimerStatusShadow; +static bool ReloadPending; + +v810_timestamp_t TIMER_Update(v810_timestamp_t timestamp) +{ + int32 run_time = timestamp - TimerLastTS; + + if (TimerControl & TC_TENABLE) + { + TimerDivider -= run_time; + while (TimerDivider <= 0) + { + if (!TimerCounter || ReloadPending) + { + TimerCounter = TimerReloadValue; + ReloadPending = false; + } + + if (TimerCounter) + TimerCounter--; + + if (!TimerCounter || TimerStatus) + { + TimerStatusShadow = TimerStatus = true; + } + + VBIRQ_Assert(VBIRQ_SOURCE_TIMER, TimerStatusShadow && (TimerControl & TC_TIMZINT)); + TimerDivider += (TimerControl & TC_TCLKSEL) ? 500 : 2000; + } + } + + TimerLastTS = timestamp; + + return ((TimerControl & TC_TENABLE) ? (timestamp + TimerDivider) : VB_EVENT_NONONO); +} + +void TIMER_ResetTS(void) +{ + TimerLastTS = 0; +} + +uint8 TIMER_Read(const v810_timestamp_t ×tamp, uint32 A) +{ + uint8 ret = 0; + + //if(A <= 0x1C) + //printf("Read: %d, %08x\n", timestamp, A); + TIMER_Update(timestamp); + + switch (A & 0xFF) + { + case 0x18: + ret = TimerCounter; + break; + + case 0x1C: + ret = TimerCounter >> 8; + break; + + case 0x20: + ret = TimerControl | (0xE0 | TC_ZSTATCLR) | (TimerStatus ? TC_ZSTAT : 0); + break; + } + + return (ret); +} + +void TIMER_Write(const v810_timestamp_t ×tamp, uint32 A, uint8 V) +{ + if (A & 0x3) + { + puts("HWCtrl Bogus Write?"); + return; + } + + TIMER_Update(timestamp); + + //if((A & 0xFF) <= 0x1C) + //printf("Write: %d, %08x %02x\n", timestamp, A, V); + + switch (A & 0xFF) + { + case 0x18: + TimerReloadValue &= 0xFF00; + TimerReloadValue |= V; + ReloadPending = true; + break; + + case 0x1C: + TimerReloadValue &= 0x00FF; + TimerReloadValue |= V << 8; + ReloadPending = true; + break; + + case 0x20: + if (V & TC_ZSTATCLR) + { + if ((TimerControl & TC_TENABLE) && TimerCounter == 0) + { + //puts("Faulty Z-Stat-Clr"); + } + else + { + TimerStatus = false; + } + TimerStatusShadow = false; + } + if ((V & TC_TENABLE) && !(TimerControl & TC_TENABLE)) + { + //TimerCounter = TimerReloadValue; + TimerDivider = (V & TC_TCLKSEL) ? 500 : 2000; + } + TimerControl = V & (0x10 | 0x08 | 0x01); + + if (!(TimerControl & TC_TIMZINT)) + TimerStatus = TimerStatusShadow = false; + + VBIRQ_Assert(VBIRQ_SOURCE_TIMER, TimerStatusShadow && (TimerControl & TC_TIMZINT)); + + if (TimerControl & TC_TENABLE) + VB_SetEvent(VB_EVENT_TIMER, timestamp + TimerDivider); + break; + } +} + +void TIMER_Power(void) +{ + TimerLastTS = 0; + + TimerCounter = 0xFFFF; + TimerReloadValue = 0; + TimerDivider = 2000; //2150; //2000; + + TimerStatus = false; + TimerStatusShadow = false; + TimerControl = 0; + + ReloadPending = false; + + VBIRQ_Assert(VBIRQ_SOURCE_TIMER, false); +} + +uint32 TIMER_GetRegister(const unsigned int id, char *special, const uint32 special_len) +{ + uint32 ret = 0xDEADBEEF; + + switch (id) + { + case TIMER_GSREG_TCR: + ret = TimerControl; + if (special) + trio_snprintf(special, special_len, "TEnable: %d, TimZInt: %d, TClkSel: %d(%.3f KHz)", + (int)(bool)(ret & TC_TENABLE), + (int)(bool)(ret & TC_TIMZINT), + (int)(bool)(ret & TC_TCLKSEL), + (double)VB_MASTER_CLOCK / ((ret & TC_TCLKSEL) ? 500 : 2000) / 1000); + break; + + case TIMER_GSREG_DIVCOUNTER: + ret = TimerDivider; + break; + + case TIMER_GSREG_RELOAD_VALUE: + ret = TimerReloadValue; + break; + + case TIMER_GSREG_COUNTER: + ret = TimerCounter; + break; + } + return (ret); +} + +void TIMER_SetRegister(const unsigned int id, const uint32 value) +{ + switch (id) + { + case TIMER_GSREG_TCR: + TimerControl = value & (TC_TENABLE | TC_TIMZINT | TC_TCLKSEL); + break; + + case TIMER_GSREG_DIVCOUNTER: + TimerDivider = value % ((TimerControl & TC_TCLKSEL) ? 500 : 2000); + break; + + case TIMER_GSREG_RELOAD_VALUE: + TimerReloadValue = value; + break; + + case TIMER_GSREG_COUNTER: + TimerCounter = value; + break; + } +} +} diff --git a/waterbox/vb/timer.h b/waterbox/vb/timer.h new file mode 100644 index 0000000000..20f0f7e9b6 --- /dev/null +++ b/waterbox/vb/timer.h @@ -0,0 +1,48 @@ +/******************************************************************************/ +/* Mednafen Virtual Boy Emulation Module */ +/******************************************************************************/ +/* timer.h: +** Copyright (C) 2010-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __MDFN_VB_TIMER_H +#define __MDFN_VB_TIMER_H + +namespace MDFN_IEN_VB +{ + +v810_timestamp_t TIMER_Update(v810_timestamp_t timestamp); +void TIMER_ResetTS(void); +uint8 TIMER_Read(const v810_timestamp_t ×tamp, uint32 A); +void TIMER_Write(const v810_timestamp_t ×tamp, uint32 A, uint8 V); + +void TIMER_Power(void) MDFN_COLD; + +enum +{ + TIMER_GSREG_TCR, + TIMER_GSREG_DIVCOUNTER, + TIMER_GSREG_RELOAD_VALUE, + TIMER_GSREG_COUNTER, +}; + +uint32 TIMER_GetRegister(const unsigned int id, char *special, const uint32 special_len); +void TIMER_SetRegister(const unsigned int id, const uint32 value); + +} + +#endif diff --git a/waterbox/vb/v810/v810_cpu.cpp b/waterbox/vb/v810/v810_cpu.cpp new file mode 100644 index 0000000000..4620c3c7e4 --- /dev/null +++ b/waterbox/vb/v810/v810_cpu.cpp @@ -0,0 +1,1363 @@ +/* V810 Emulator + * + * Copyright (C) 2006 David Tucker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* Alternatively, the V810 emulator code(and all V810 emulation header files) can be used/distributed under the following license(you can adopt either + license exclusively for your changes by removing one of these license headers, but it's STRONGLY preferable + to keep your changes dual-licensed as well): + +This Reality Boy emulator is copyright (C) David Tucker 1997-2008, all rights +reserved. You may use this code as long as you make no money from the use of +this code and you acknowledge the original author (Me). I reserve the right to +dictate who can use this code and how (Just so you don't do something stupid +with it). + Most Importantly, this code is swap ware. If you use It send along your new +program (with code) or some other interesting tidbits you wrote, that I might be +interested in. + This code is in beta, there are bugs! I am not responsible for any damage +done to your computer, reputation, ego, dog, or family life due to the use of +this code. All source is provided as is, I make no guaranties, and am not +responsible for anything you do with the code (legal or otherwise). + Virtual Boy is a trademark of Nintendo, and V810 is a trademark of NEC. I am +in no way affiliated with either party and all information contained hear was +found freely through public domain sources. +*/ + +////////////////////////////////////////////////////////// +// CPU routines + +#include "vb.h" +#include + +//#include "pcfx.h" +//#include "debug.h" + +#include +#include + +#include "v810_opt.h" +#include "v810_cpu.h" + +V810::V810() +{ + MemRead8 = NULL; + MemRead16 = NULL; + MemRead32 = NULL; + + IORead8 = NULL; + IORead16 = NULL; + IORead32 = NULL; + + MemWrite8 = NULL; + MemWrite16 = NULL; + MemWrite32 = NULL; + + IOWrite8 = NULL; + IOWrite16 = NULL; + IOWrite32 = NULL; + + FastMap = (uint8**)alloc_sealed((1ULL << 32) / V810_FAST_MAP_PSIZE * sizeof(*FastMap)); + + memset(MemReadBus32, 0, sizeof(MemReadBus32)); + memset(MemWriteBus32, 0, sizeof(MemWriteBus32)); + + v810_timestamp = 0; + next_event_ts = 0x7FFFFFFF; +} + +V810::~V810() +{ +} + +INLINE void V810::RecalcIPendingCache(void) +{ + IPendingCache = 0; + + // Of course don't generate an interrupt if there's not one pending! + if (ilevel < 0) + return; + + // If CPU is halted because of a fatal exception, don't let an interrupt + // take us out of this halted status. + if (Halted == HALT_FATAL_EXCEPTION) + return; + + // If the NMI pending, exception pending, and/or interrupt disabled bit + // is set, don't accept any interrupts. + if (S_REG[PSW] & (PSW_NP | PSW_EP | PSW_ID)) + return; + + // If the interrupt level is lower than the interrupt enable level, don't + // accept it. + if (ilevel < (int)((S_REG[PSW] & PSW_IA) >> 16)) + return; + + IPendingCache = 0xFF; +} + +// TODO: "An interrupt that occurs during restore/dump/clear operation is internally held and is accepted after the +// operation in progress is finished. The maskable interrupt is held internally only when the EP, NP, and ID flags +// of PSW are all 0." +// +// This behavior probably doesn't have any relevance on the PC-FX, unless we're sadistic +// and try to restore cache from an interrupt acknowledge register or dump it to a register +// controlling interrupt masks... I wanna be sadistic~ + +void V810::CacheClear(v810_timestamp_t ×tamp, uint32 start, uint32 count) +{ + //printf("Cache clear: %08x %08x\n", start, count); + for (uint32 i = 0; i < count && (i + start) < 128; i++) + memset(&Cache[i + start], 0, sizeof(V810_CacheEntry_t)); +} + +INLINE void V810::CacheOpMemStore(v810_timestamp_t ×tamp, uint32 A, uint32 V) +{ + if (MemWriteBus32[A >> 24]) + { + timestamp += 2; + MemWrite32(timestamp, A, V); + } + else + { + timestamp += 2; + MemWrite16(timestamp, A, V & 0xFFFF); + + timestamp += 2; + MemWrite16(timestamp, A | 2, V >> 16); + } +} + +INLINE uint32 V810::CacheOpMemLoad(v810_timestamp_t ×tamp, uint32 A) +{ + if (MemReadBus32[A >> 24]) + { + timestamp += 2; + return (MemRead32(timestamp, A)); + } + else + { + uint32 ret; + + timestamp += 2; + ret = MemRead16(timestamp, A); + + timestamp += 2; + ret |= MemRead16(timestamp, A | 2) << 16; + return (ret); + } +} + +void V810::CacheDump(v810_timestamp_t ×tamp, const uint32 SA) +{ + printf("Cache dump: %08x\n", SA); + + for (int i = 0; i < 128; i++) + { + CacheOpMemStore(timestamp, SA + i * 8 + 0, Cache[i].data[0]); + CacheOpMemStore(timestamp, SA + i * 8 + 4, Cache[i].data[1]); + } + + for (int i = 0; i < 128; i++) + { + uint32 icht = Cache[i].tag | ((int)Cache[i].data_valid[0] << 22) | ((int)Cache[i].data_valid[1] << 23); + + CacheOpMemStore(timestamp, SA + 1024 + i * 4, icht); + } +} + +void V810::CacheRestore(v810_timestamp_t ×tamp, const uint32 SA) +{ + printf("Cache restore: %08x\n", SA); + + for (int i = 0; i < 128; i++) + { + Cache[i].data[0] = CacheOpMemLoad(timestamp, SA + i * 8 + 0); + Cache[i].data[1] = CacheOpMemLoad(timestamp, SA + i * 8 + 4); + } + + for (int i = 0; i < 128; i++) + { + uint32 icht; + + icht = CacheOpMemLoad(timestamp, SA + 1024 + i * 4); + + Cache[i].tag = icht & ((1 << 22) - 1); + Cache[i].data_valid[0] = (icht >> 22) & 1; + Cache[i].data_valid[1] = (icht >> 23) & 1; + } +} + +INLINE uint32 V810::RDCACHE(v810_timestamp_t ×tamp, uint32 addr) +{ + const int CI = (addr >> 3) & 0x7F; + const int SBI = (addr & 4) >> 2; + + if (Cache[CI].tag == (addr >> 10)) + { + if (!Cache[CI].data_valid[SBI]) + { + timestamp += 2; // or higher? Penalty for cache miss seems to be higher than having cache disabled. + if (MemReadBus32[addr >> 24]) + Cache[CI].data[SBI] = MemRead32(timestamp, addr & ~0x3); + else + { + timestamp++; + + uint32 tmp; + + tmp = MemRead16(timestamp, addr & ~0x3); + tmp |= MemRead16(timestamp, (addr & ~0x3) | 0x2) << 16; + + Cache[CI].data[SBI] = tmp; + } + Cache[CI].data_valid[SBI] = TRUE; + } + } + else + { + Cache[CI].tag = addr >> 10; + + timestamp += 2; // or higher? Penalty for cache miss seems to be higher than having cache disabled. + if (MemReadBus32[addr >> 24]) + Cache[CI].data[SBI] = MemRead32(timestamp, addr & ~0x3); + else + { + timestamp++; + + uint32 tmp; + + tmp = MemRead16(timestamp, addr & ~0x3); + tmp |= MemRead16(timestamp, (addr & ~0x3) | 0x2) << 16; + + Cache[CI].data[SBI] = tmp; + } + //Cache[CI].data[SBI] = MemRead32(timestamp, addr & ~0x3); + Cache[CI].data_valid[SBI] = TRUE; + Cache[CI].data_valid[SBI ^ 1] = FALSE; + } + + //{ + // // Caution: This can mess up DRAM page change penalty timings + // uint32 dummy_timestamp = 0; + // if(Cache[CI].data[SBI] != mem_rword(addr & ~0x3, dummy_timestamp)) + // { + // printf("Cache/Real Memory Mismatch: %08x %08x/%08x\n", addr & ~0x3, Cache[CI].data[SBI], mem_rword(addr & ~0x3, dummy_timestamp)); + // } + //} + + return (Cache[CI].data[SBI]); +} + +INLINE uint16 V810::RDOP(v810_timestamp_t ×tamp, uint32 addr, uint32 meow) +{ + uint16 ret; + + if (S_REG[CHCW] & 0x2) + { + uint32 d32 = RDCACHE(timestamp, addr); + ret = d32 >> ((addr & 2) * 8); + } + else + { + timestamp += meow; //++; + ret = MemRead16(timestamp, addr); + } + return (ret); +} + +#define BRANCH_ALIGN_CHECK(x) \ + { \ + if ((S_REG[CHCW] & 0x2) && (x & 0x2)) \ + { \ + ADDCLOCK(1); \ + } \ + } + +// Reinitialize the defaults in the CPU +void V810::Reset() +{ + memset(&Cache, 0, sizeof(Cache)); + + memset(P_REG, 0, sizeof(P_REG)); + memset(S_REG, 0, sizeof(S_REG)); + memset(Cache, 0, sizeof(Cache)); + + P_REG[0] = 0x00000000; + SetPC(0xFFFFFFF0); + + S_REG[ECR] = 0x0000FFF0; + S_REG[PSW] = 0x00008000; + + if (VBMode) + S_REG[PIR] = 0x00005346; + else + S_REG[PIR] = 0x00008100; + + S_REG[TKCW] = 0x000000E0; + Halted = HALT_NONE; + ilevel = -1; + + lastop = 0; + + in_bstr = FALSE; + + RecalcIPendingCache(); +} + +bool V810::Init(V810_Emu_Mode mode, bool vb_mode) +{ + EmuMode = mode; + VBMode = vb_mode; + + in_bstr = FALSE; + in_bstr_to = 0; + + if (mode == V810_EMU_MODE_FAST) + { + memset(DummyRegion, 0, V810_FAST_MAP_PSIZE); + + for (unsigned int i = V810_FAST_MAP_PSIZE; i < V810_FAST_MAP_PSIZE + V810_FAST_MAP_TRAMPOLINE_SIZE; i += 2) + { + DummyRegion[i + 0] = 0; + DummyRegion[i + 1] = 0x36 << 2; + } + + for (uint64 A = 0; A < (1ULL << 32); A += V810_FAST_MAP_PSIZE) + FastMap[A / V810_FAST_MAP_PSIZE] = DummyRegion - A; + } + + return (TRUE); +} + +void V810::SetInt(int level) +{ + assert(level >= -1 && level <= 15); + + ilevel = level; + RecalcIPendingCache(); +} + +uint8* V810::SetFastMap(void *(*allocator)(size_t size), uint32 addresses[], uint32 length, unsigned int num_addresses, const char *name) +{ + for (unsigned int i = 0; i < num_addresses; i++) + { + assert((addresses[i] & (V810_FAST_MAP_PSIZE - 1)) == 0); + } + assert((length & (V810_FAST_MAP_PSIZE - 1)) == 0); + + auto ret = (uint8*)allocator(length + V810_FAST_MAP_TRAMPOLINE_SIZE); + + for (unsigned int i = length; i < length + V810_FAST_MAP_TRAMPOLINE_SIZE; i += 2) + { + ret[i + 0] = 0; + ret[i + 1] = 0x36 << 2; + } + + for (unsigned int i = 0; i < num_addresses; i++) + { + for (uint64 addr = addresses[i]; addr != (uint64)addresses[i] + length; addr += V810_FAST_MAP_PSIZE) + { + //printf("%08x, %d, %s\n", addr, length, name); + + FastMap[addr / V810_FAST_MAP_PSIZE] = ret - addresses[i]; + } + } + + return ret; +} + +void V810::SetMemReadBus32(uint8 A, bool value) +{ + MemReadBus32[A] = value; +} + +void V810::SetMemWriteBus32(uint8 A, bool value) +{ + MemWriteBus32[A] = value; +} + +void V810::SetMemReadHandlers(uint8 MDFN_FASTCALL (*read8)(v810_timestamp_t &, uint32), uint16 MDFN_FASTCALL (*read16)(v810_timestamp_t &, uint32), uint32 MDFN_FASTCALL (*read32)(v810_timestamp_t &, uint32)) +{ + MemRead8 = read8; + MemRead16 = read16; + MemRead32 = read32; +} + +void V810::SetMemWriteHandlers(void MDFN_FASTCALL (*write8)(v810_timestamp_t &, uint32, uint8), void MDFN_FASTCALL (*write16)(v810_timestamp_t &, uint32, uint16), void MDFN_FASTCALL (*write32)(v810_timestamp_t &, uint32, uint32)) +{ + MemWrite8 = write8; + MemWrite16 = write16; + MemWrite32 = write32; +} + +void V810::SetIOReadHandlers(uint8 MDFN_FASTCALL (*read8)(v810_timestamp_t &, uint32), uint16 MDFN_FASTCALL (*read16)(v810_timestamp_t &, uint32), uint32 MDFN_FASTCALL (*read32)(v810_timestamp_t &, uint32)) +{ + IORead8 = read8; + IORead16 = read16; + IORead32 = read32; +} + +void V810::SetIOWriteHandlers(void MDFN_FASTCALL (*write8)(v810_timestamp_t &, uint32, uint8), void MDFN_FASTCALL (*write16)(v810_timestamp_t &, uint32, uint16), void MDFN_FASTCALL (*write32)(v810_timestamp_t &, uint32, uint32)) +{ + IOWrite8 = write8; + IOWrite16 = write16; + IOWrite32 = write32; +} + +INLINE void V810::SetFlag(uint32 n, bool condition) +{ + S_REG[PSW] &= ~n; + + if (condition) + S_REG[PSW] |= n; +} + +INLINE void V810::SetSZ(uint32 value) +{ + SetFlag(PSW_Z, !value); + SetFlag(PSW_S, value & 0x80000000); +} + +#define SetPREG(n, val) \ + { \ + P_REG[n] = val; \ + } + +INLINE void V810::SetSREG(v810_timestamp_t ×tamp, unsigned int which, uint32 value) +{ + switch (which) + { + default: // Reserved + printf("LDSR to reserved system register: 0x%02x : 0x%08x\n", which, value); + break; + + case ECR: // Read-only + break; + + case PIR: // Read-only (obviously) + break; + + case TKCW: // Read-only + break; + + case EIPSW: + case FEPSW: + S_REG[which] = value & 0xFF3FF; + break; + + case PSW: + S_REG[which] = value & 0xFF3FF; + RecalcIPendingCache(); + break; + + case EIPC: + case FEPC: + S_REG[which] = value & 0xFFFFFFFE; + break; + + case ADDTRE: + S_REG[ADDTRE] = value & 0xFFFFFFFE; + printf("Address trap(unemulated): %08x\n", value); + break; + + case CHCW: + S_REG[CHCW] = value & 0x2; + + switch (value & 0x31) + { + default: + printf("Undefined cache control bit combination: %08x\n", value); + break; + + case 0x00: + break; + + case 0x01: + CacheClear(timestamp, (value >> 20) & 0xFFF, (value >> 8) & 0xFFF); + break; + + case 0x10: + CacheDump(timestamp, value & ~0xFF); + break; + + case 0x20: + CacheRestore(timestamp, value & ~0xFF); + break; + } + break; + } +} + +INLINE uint32 V810::GetSREG(unsigned int which) +{ + uint32 ret; + + if (which != 24 && which != 25 && which >= 8) + { + printf("STSR from reserved system register: 0x%02x", which); + } + + ret = S_REG[which]; + + return (ret); +} + +#define RB_SETPC(new_pc_raw) \ + { \ + const uint32 new_pc = new_pc_raw; /* So RB_SETPC(RB_GETPC()) won't mess up */ \ + if (RB_AccurateMode) \ + PC = new_pc; \ + else \ + { \ + PC_ptr = &FastMap[(new_pc) >> V810_FAST_MAP_SHIFT][(new_pc)]; \ + PC_base = PC_ptr - (new_pc); \ + } \ + } + +#define RB_PCRELCHANGE(delta) \ + { \ + if (RB_AccurateMode) \ + PC += (delta); \ + else \ + { \ + uint32 PC_tmp = RB_GETPC(); \ + PC_tmp += (delta); \ + RB_SETPC(PC_tmp); \ + } \ + } + +#define RB_INCPCBY2() \ + { \ + if (RB_AccurateMode) \ + PC += 2; \ + else \ + PC_ptr += 2; \ + } +#define RB_INCPCBY4() \ + { \ + if (RB_AccurateMode) \ + PC += 4; \ + else \ + PC_ptr += 4; \ + } + +#define RB_DECPCBY2() \ + { \ + if (RB_AccurateMode) \ + PC -= 2; \ + else \ + PC_ptr -= 2; \ + } +#define RB_DECPCBY4() \ + { \ + if (RB_AccurateMode) \ + PC -= 4; \ + else \ + PC_ptr -= 4; \ + } + +// Define accurate mode defines +#define RB_GETPC() PC +#define RB_RDOP(PC_offset, ...) RDOP(timestamp, PC + PC_offset, ##__VA_ARGS__) + +void V810::Run_Accurate(int32 MDFN_FASTCALL (*event_handler)(const v810_timestamp_t timestamp)) +{ + const bool RB_AccurateMode = true; + +#define RB_ADDBT(n, o, p) +#define RB_CPUHOOK(n) + +#include "v810_oploop.inc" + +#undef RB_CPUHOOK +#undef RB_ADDBT +} + +// +// Undefine accurate mode defines +// +#undef RB_GETPC +#undef RB_RDOP + +// +// Define fast mode defines +// +#define RB_GETPC() ((uint32)(PC_ptr - PC_base)) + +#define RB_RDOP(PC_offset, ...) MDFN_de16lsb(&PC_ptr[PC_offset]) + +void V810::Run_Fast(int32 MDFN_FASTCALL (*event_handler)(const v810_timestamp_t timestamp)) +{ + const bool RB_AccurateMode = false; + +#define RB_ADDBT(n, o, p) +#define RB_CPUHOOK(n) + +#include "v810_oploop.inc" + +#undef RB_CPUHOOK +#undef RB_ADDBT +} + +// +// Undefine fast mode defines +// +#undef RB_GETPC +#undef RB_RDOP + +v810_timestamp_t V810::Run(int32 MDFN_FASTCALL (*event_handler)(const v810_timestamp_t timestamp)) +{ + Running = true; + if (EmuMode == V810_EMU_MODE_FAST) + Run_Fast(event_handler); + else + Run_Accurate(event_handler); + return (v810_timestamp); +} + +void V810::Exit(void) +{ + Running = false; +} + +uint32 V810::GetRegister(unsigned int which, char *special, const uint32 special_len) +{ + if (which >= GSREG_PR && which <= GSREG_PR + 31) + { + return GetPR(which - GSREG_PR); + } + else if (which >= GSREG_SR && which <= GSREG_SR + 31) + { + uint32 val = GetSREG(which - GSREG_SR); + + if (special && which == GSREG_SR + PSW) + { + trio_snprintf(special, special_len, "Z: %d, S: %d, OV: %d, CY: %d, ID: %d, AE: %d, EP: %d, NP: %d, IA: %2d", + (int)(bool)(val & PSW_Z), (int)(bool)(val & PSW_S), (int)(bool)(val & PSW_OV), (int)(bool)(val & PSW_CY), + (int)(bool)(val & PSW_ID), (int)(bool)(val & PSW_AE), (int)(bool)(val & PSW_EP), (int)(bool)(val & PSW_NP), + (val & PSW_IA) >> 16); + } + + return val; + } + else if (which == GSREG_PC) + { + return GetPC(); + } + else if (which == GSREG_TIMESTAMP) + { + return v810_timestamp; + } + + return 0xDEADBEEF; +} + +void V810::SetRegister(unsigned int which, uint32 value) +{ + if (which >= GSREG_PR && which <= GSREG_PR + 31) + { + if (which) + P_REG[which - GSREG_PR] = value; + } + else if (which >= GSREG_SR && which <= GSREG_SR + 31) + { + // SetSREG(timestamp, which - GSREG_SR, value); + } + else if (which == GSREG_PC) + { + SetPC(value & ~1); + } + else if (which == GSREG_TIMESTAMP) + { + //v810_timestamp = value; + } +} + +uint32 V810::GetPC(void) +{ + if (EmuMode == V810_EMU_MODE_ACCURATE) + return (PC); + else + { + return (PC_ptr - PC_base); + } +} + +void V810::SetPC(uint32 new_pc) +{ + if (EmuMode == V810_EMU_MODE_ACCURATE) + PC = new_pc; + else + { + PC_ptr = &FastMap[new_pc >> V810_FAST_MAP_SHIFT][new_pc]; + PC_base = PC_ptr - new_pc; + } +} + +#define BSTR_OP_MOV \ + dst_cache &= ~(1 << dstoff); \ + dst_cache |= ((src_cache >> srcoff) & 1) << dstoff; +#define BSTR_OP_NOT \ + dst_cache &= ~(1 << dstoff); \ + dst_cache |= (((src_cache >> srcoff) & 1) ^ 1) << dstoff; + +#define BSTR_OP_XOR dst_cache ^= ((src_cache >> srcoff) & 1) << dstoff; +#define BSTR_OP_OR dst_cache |= ((src_cache >> srcoff) & 1) << dstoff; +#define BSTR_OP_AND dst_cache &= ~((((src_cache >> srcoff) & 1) ^ 1) << dstoff); + +#define BSTR_OP_XORN dst_cache ^= (((src_cache >> srcoff) & 1) ^ 1) << dstoff; +#define BSTR_OP_ORN dst_cache |= (((src_cache >> srcoff) & 1) ^ 1) << dstoff; +#define BSTR_OP_ANDN dst_cache &= ~(((src_cache >> srcoff) & 1) << dstoff); + +INLINE uint32 V810::BSTR_RWORD(v810_timestamp_t ×tamp, uint32 A) +{ + if (MemReadBus32[A >> 24]) + { + timestamp += 2; + return (MemRead32(timestamp, A)); + } + else + { + uint32 ret; + + timestamp += 2; + ret = MemRead16(timestamp, A); + + timestamp += 2; + ret |= MemRead16(timestamp, A | 2) << 16; + return (ret); + } +} + +INLINE void V810::BSTR_WWORD(v810_timestamp_t ×tamp, uint32 A, uint32 V) +{ + if (MemWriteBus32[A >> 24]) + { + timestamp += 2; + MemWrite32(timestamp, A, V); + } + else + { + timestamp += 2; + MemWrite16(timestamp, A, V & 0xFFFF); + + timestamp += 2; + MemWrite16(timestamp, A | 2, V >> 16); + } +} + +#define DO_BSTR(op) \ + { \ + while (len) \ + { \ + if (!have_src_cache) \ + { \ + have_src_cache = TRUE; \ + src_cache = BSTR_RWORD(timestamp, src); \ + } \ + \ + if (!have_dst_cache) \ + { \ + have_dst_cache = TRUE; \ + dst_cache = BSTR_RWORD(timestamp, dst); \ + } \ + \ + op; \ + srcoff = (srcoff + 1) & 0x1F; \ + dstoff = (dstoff + 1) & 0x1F; \ + len--; \ + \ + if (!srcoff) \ + { \ + src += 4; \ + have_src_cache = FALSE; \ + } \ + \ + if (!dstoff) \ + { \ + BSTR_WWORD(timestamp, dst, dst_cache); \ + dst += 4; \ + have_dst_cache = FALSE; \ + if (timestamp >= next_event_ts) \ + break; \ + } \ + } \ + if (have_dst_cache) \ + BSTR_WWORD(timestamp, dst, dst_cache); \ + } + +INLINE bool V810::Do_BSTR_Search(v810_timestamp_t ×tamp, const int inc_mul, unsigned int bit_test) +{ + uint32 srcoff = (P_REG[27] & 0x1F); + uint32 len = P_REG[28]; + uint32 bits_skipped = P_REG[29]; + uint32 src = (P_REG[30] & 0xFFFFFFFC); + bool found = false; + +#if 0 + // TODO: Better timing. + if(!in_bstr) // If we're just starting the execution of this instruction(kind of spaghetti-code), so FIXME if we change + // bstr handling in v810_oploop.inc + { + timestamp += 13 - 1; + } +#endif + + while (len) + { + if (!have_src_cache) + { + have_src_cache = TRUE; + timestamp++; + src_cache = BSTR_RWORD(timestamp, src); + } + + if (((src_cache >> srcoff) & 1) == bit_test) + { + found = true; + + /* Fix the bit offset and word address to "1 bit before" it was found */ + srcoff -= inc_mul * 1; + if (srcoff & 0x20) /* Handles 0x1F->0x20(0x00) and 0x00->0xFFFF... */ + { + src -= inc_mul * 4; + srcoff &= 0x1F; + } + break; + } + srcoff = (srcoff + inc_mul * 1) & 0x1F; + bits_skipped++; + len--; + + if (!srcoff) + { + have_src_cache = FALSE; + src += inc_mul * 4; + if (timestamp >= next_event_ts) + break; + } + } + + P_REG[27] = srcoff; + P_REG[28] = len; + P_REG[29] = bits_skipped; + P_REG[30] = src; + + if (found) // Set Z flag to 0 if the bit was found + SetFlag(PSW_Z, 0); + else if (!len) // ...and if the search is over, and the bit was not found, set it to 1 + SetFlag(PSW_Z, 1); + + if (found) // Bit found, so don't continue the search. + return (false); + + return ((bool)len); // Continue the search if any bits are left to search. +} + +bool V810::bstr_subop(v810_timestamp_t ×tamp, int sub_op, int arg1) +{ + if ((sub_op >= 0x10) || (!(sub_op & 0x8) && sub_op >= 0x4)) + { + printf("%08x\tBSR Error: %04x\n", PC, sub_op); + + SetPC(GetPC() - 2); + Exception(INVALID_OP_HANDLER_ADDR, ECODE_INVALID_OP); + + return (false); + } + + // printf("BSTR: %02x, %02x %02x; src: %08x, dst: %08x, len: %08x\n", sub_op, P_REG[27], P_REG[26], P_REG[30], P_REG[29], P_REG[28]); + + if (sub_op & 0x08) + { + uint32 dstoff = (P_REG[26] & 0x1F); + uint32 srcoff = (P_REG[27] & 0x1F); + uint32 len = P_REG[28]; + uint32 dst = (P_REG[29] & 0xFFFFFFFC); + uint32 src = (P_REG[30] & 0xFFFFFFFC); + +#if 0 + // Be careful not to cause 32-bit integer overflow, and careful about not shifting by 32. + // TODO: + + // Read src[0], src[4] into shifter. + // Read dest[0]. + DO_BSTR_PROLOGUE(); // if(len) { blah blah blah masking blah } + src_cache = BSTR_RWORD(timestamp, src); + + if((uint64)(srcoff + len) > 0x20) + src_cache |= (uint64)BSTR_RWORD(timestamp, src + 4) << 32; + + dst_cache = BSTR_RWORD(timestamp, dst); + + if(len) + { + uint32 dst_preserve_mask; + uint32 dst_change_mask; + + dst_preserve_mask = (1U << dstoff) - 1; + + if((uint64)(dstoff + len) < 0x20) + dst_preserve_mask |= ((1U << ((0x20 - (dstoff + len)) & 0x1F)) - 1) << (dstoff + len); + + dst_change_mask = ~dst_preserve_mask; + + src_cache = BSTR_RWORD(timestamp, src); + src_cache |= (uint64)BSTR_RWORD(timestamp, src + 4) << 32; + dst_cache = BSTR_RWORD(timestamp, dst); + + dst_cache = (dst_cache & dst_preserve_mask) | ((dst_cache OP_THINGY_HERE (src_cache >> srcoff)) & dst_change_mask); + BSTR_WWORD(timestamp, dst, dst_cache); + + if((uint64)(dstoff + len) < 0x20) + { + srcoff += len; + dstoff += len; + len = 0; + } + else + { + srcoff += (0x20 - dstoff); + dstoff = 0; + len -= (0x20 - dstoff); + dst += 4; + } + + if(srcoff >= 0x20) + { + srcoff &= 0x1F; + src += 4; + + if(len) + { + src_cache >>= 32; + src_cache |= (uint64)BSTR_RWORD(timestamp, src + 4) << 32; + } + } + } + + DO_BSTR_PRIMARY(); // while(len >= 32) (do allow interruption; interrupt and emulator-return - + // they must be handled differently!) + while(len >= 32) + { + dst_cache = BSTR_RWORD(timestamp, dst); + dst_cache = OP_THINGY_HERE(dst_cache, src_cache >> srcoff); + BSTR_WWORD(timestamp, dst, dst_cache); + len -= 32; + dst += 4; + src += 4; + src_cache >>= 32; + src_cache |= (uint64)BSTR_RWORD(timestamp, src + 4) << 32; + } + + DO_BSTR_EPILOGUE(); // if(len) { blah blah blah masking blah } + if(len) + { + uint32 dst_preserve_mask; + uint32 dst_change_mask; + + dst_preserve_mask = (1U << ((0x20 - len) & 0x1F) << len; + dst_change_mask = ~dst_preserve_mask; + + dst_cache = BSTR_RWORD(timestamp, dst); + dst_cache = OP_THINGY_HERE(dst_cache, src_cache >> srcoff); + BSTR_WWORD(timestamp, dst, dst_cache); + dstoff += len; + srcoff += len; + + if(srcoff >= 0x20) + { + srcoff &= 0x1F; + src += 4; + } + len = 0; + } +#endif + + switch (sub_op) + { + case ORBSU: + DO_BSTR(BSTR_OP_OR); + break; + + case ANDBSU: + DO_BSTR(BSTR_OP_AND); + break; + + case XORBSU: + DO_BSTR(BSTR_OP_XOR); + break; + + case MOVBSU: + DO_BSTR(BSTR_OP_MOV); + break; + + case ORNBSU: + DO_BSTR(BSTR_OP_ORN); + break; + + case ANDNBSU: + DO_BSTR(BSTR_OP_ANDN); + break; + + case XORNBSU: + DO_BSTR(BSTR_OP_XORN); + break; + + case NOTBSU: + DO_BSTR(BSTR_OP_NOT); + break; + } + + P_REG[26] = dstoff; + P_REG[27] = srcoff; + P_REG[28] = len; + P_REG[29] = dst; + P_REG[30] = src; + + return ((bool)P_REG[28]); + } + else + { + printf("BSTR Search: %02x\n", sub_op); + return (Do_BSTR_Search(timestamp, ((sub_op & 1) ? -1 : 1), (sub_op & 0x2) >> 1)); + } + assert(0); + return (false); +} + +INLINE void V810::SetFPUOPNonFPUFlags(uint32 result) +{ + // Now, handle flag setting + SetFlag(PSW_OV, 0); + + if (!(result & 0x7FFFFFFF)) // Check to see if exponent and mantissa are 0 + { + // If Z flag is set, S and CY should be clear, even if it's negative 0(confirmed on real thing with subf.s, at least). + SetFlag(PSW_Z, 1); + SetFlag(PSW_S, 0); + SetFlag(PSW_CY, 0); + } + else + { + SetFlag(PSW_Z, 0); + SetFlag(PSW_S, result & 0x80000000); + SetFlag(PSW_CY, result & 0x80000000); + } + //printf("MEOW: %08x\n", S_REG[PSW] & (PSW_S | PSW_CY)); +} + +bool V810::FPU_DoesExceptionKillResult(void) +{ + const uint32 float_exception_flags = fpo.get_flags(); + + if (float_exception_flags & V810_FP_Ops::flag_reserved) + return (true); + + if (float_exception_flags & V810_FP_Ops::flag_invalid) + return (true); + + if (float_exception_flags & V810_FP_Ops::flag_divbyzero) + return (true); + + // Return false here, so that the result of this calculation IS put in the output register. + // Wrap the exponent on overflow, rather than generating an infinity. The wrapping behavior is specified in IEE 754 AFAIK, + // and is useful in cases where you divide a huge number + // by another huge number, and fix the result afterwards based on the number of overflows that occurred. Probably requires some custom assembly code, + // though. And it's the kind of thing you'd see in an engineering or physics program, not in a perverted video game :b). + if (float_exception_flags & V810_FP_Ops::flag_overflow) + return (false); + + return (false); +} + +void V810::FPU_DoException(void) +{ + const uint32 float_exception_flags = fpo.get_flags(); + + if (float_exception_flags & V810_FP_Ops::flag_reserved) + { + S_REG[PSW] |= PSW_FRO; + + SetPC(GetPC() - 4); + Exception(FPU_HANDLER_ADDR, ECODE_FRO); + + return; + } + + if (float_exception_flags & V810_FP_Ops::flag_invalid) + { + S_REG[PSW] |= PSW_FIV; + + SetPC(GetPC() - 4); + Exception(FPU_HANDLER_ADDR, ECODE_FIV); + + return; + } + + if (float_exception_flags & V810_FP_Ops::flag_divbyzero) + { + S_REG[PSW] |= PSW_FZD; + + SetPC(GetPC() - 4); + Exception(FPU_HANDLER_ADDR, ECODE_FZD); + + return; + } + + if (float_exception_flags & V810_FP_Ops::flag_underflow) + { + S_REG[PSW] |= PSW_FUD; + } + + if (float_exception_flags & V810_FP_Ops::flag_inexact) + { + S_REG[PSW] |= PSW_FPR; + } + + // + // FPR can be set along with overflow, so put the overflow exception handling at the end here(for Exception() messes with PSW). + // + if (float_exception_flags & V810_FP_Ops::flag_overflow) + { + S_REG[PSW] |= PSW_FOV; + + SetPC(GetPC() - 4); + Exception(FPU_HANDLER_ADDR, ECODE_FOV); + } +} + +bool V810::IsSubnormal(uint32 fpval) +{ + if (((fpval >> 23) & 0xFF) == 0 && (fpval & ((1 << 23) - 1))) + return (true); + + return (false); +} + +INLINE void V810::FPU_Math_Template(uint32 (V810_FP_Ops::*func)(uint32, uint32), uint32 arg1, uint32 arg2) +{ + uint32 result; + + fpo.clear_flags(); + result = (fpo.*func)(P_REG[arg1], P_REG[arg2]); + + if (!FPU_DoesExceptionKillResult()) + { + SetFPUOPNonFPUFlags(result); + SetPREG(arg1, result); + } + FPU_DoException(); +} + +void V810::fpu_subop(v810_timestamp_t ×tamp, int sub_op, int arg1, int arg2) +{ + //printf("FPU: %02x\n", sub_op); + if (VBMode) + { + switch (sub_op) + { + case XB: + timestamp++; // Unknown + P_REG[arg1] = (P_REG[arg1] & 0xFFFF0000) | ((P_REG[arg1] & 0xFF) << 8) | ((P_REG[arg1] & 0xFF00) >> 8); + return; + + case XH: + timestamp++; // Unknown + P_REG[arg1] = (P_REG[arg1] << 16) | (P_REG[arg1] >> 16); + return; + + // Does REV use arg1 or arg2 for the source register? + case REV: + timestamp++; // Unknown + printf("Revvie bits\n"); + { + // Public-domain code snippet from: http://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel + uint32 v = P_REG[arg2]; // 32-bit word to reverse bit order + + // swap odd and even bits + v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1); + // swap consecutive pairs + v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2); + // swap nibbles ... + v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4); + // swap bytes + v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8); + // swap 2-byte long pairs + v = (v >> 16) | (v << 16); + + P_REG[arg1] = v; + } + return; + + case MPYHW: + timestamp += 9 - 1; // Unknown? + P_REG[arg1] = (int32)(int16)(P_REG[arg1] & 0xFFFF) * (int32)(int16)(P_REG[arg2] & 0xFFFF); + return; + } + } + + switch (sub_op) + { + // Virtual-Boy specific(probably!) + default: + { + SetPC(GetPC() - 4); + Exception(INVALID_OP_HANDLER_ADDR, ECODE_INVALID_OP); + } + break; + + case CVT_WS: + timestamp += 5; + { + uint32 result; + + fpo.clear_flags(); + result = fpo.itof(P_REG[arg2]); + + if (!FPU_DoesExceptionKillResult()) + { + SetPREG(arg1, result); + SetFPUOPNonFPUFlags(result); + } + FPU_DoException(); + } + break; // End CVT.WS + + case CVT_SW: + timestamp += 8; + { + int32 result; + + fpo.clear_flags(); + result = fpo.ftoi(P_REG[arg2], false); + + if (!FPU_DoesExceptionKillResult()) + { + SetPREG(arg1, result); + SetFlag(PSW_OV, 0); + SetSZ(result); + } + FPU_DoException(); + } + break; // End CVT.SW + + case ADDF_S: + timestamp += 8; + FPU_Math_Template(&V810_FP_Ops::add, arg1, arg2); + break; + + case SUBF_S: + timestamp += 11; + FPU_Math_Template(&V810_FP_Ops::sub, arg1, arg2); + break; + + case CMPF_S: + timestamp += 6; + // Don't handle this like subf.s because the flags + // have slightly different semantics(mostly regarding underflow/subnormal results) (confirmed on real V810). + fpo.clear_flags(); + { + int32 result; + + result = fpo.cmp(P_REG[arg1], P_REG[arg2]); + + if (!FPU_DoesExceptionKillResult()) + { + SetFPUOPNonFPUFlags(result); + } + FPU_DoException(); + } + break; + + case MULF_S: + timestamp += 7; + FPU_Math_Template(&V810_FP_Ops::mul, arg1, arg2); + break; + + case DIVF_S: + timestamp += 43; + FPU_Math_Template(&V810_FP_Ops::div, arg1, arg2); + break; + + case TRNC_SW: + timestamp += 7; + { + int32 result; + + fpo.clear_flags(); + result = fpo.ftoi(P_REG[arg2], true); + + if (!FPU_DoesExceptionKillResult()) + { + SetPREG(arg1, result); + SetFlag(PSW_OV, 0); + SetSZ(result); + } + FPU_DoException(); + } + break; // end TRNC.SW + } +} + +// Generate exception +void V810::Exception(uint32 handler, uint16 eCode) +{ +// Exception overhead is unknown. + printf("Exception: %08x %04x\n", handler, eCode); + + // Invalidate our bitstring state(forces the instruction to be re-read, and the r/w buffers reloaded). + in_bstr = FALSE; + have_src_cache = FALSE; + have_dst_cache = FALSE; + + if (S_REG[PSW] & PSW_NP) // Fatal exception + { + printf("Fatal exception; Code: %08x, ECR: %08x, PSW: %08x, PC: %08x\n", eCode, S_REG[ECR], S_REG[PSW], PC); + Halted = HALT_FATAL_EXCEPTION; + IPendingCache = 0; + return; + } + else if (S_REG[PSW] & PSW_EP) //Double Exception + { + S_REG[FEPC] = GetPC(); + S_REG[FEPSW] = S_REG[PSW]; + + S_REG[ECR] = (S_REG[ECR] & 0xFFFF) | (eCode << 16); + S_REG[PSW] |= PSW_NP; + S_REG[PSW] |= PSW_ID; + S_REG[PSW] &= ~PSW_AE; + + SetPC(0xFFFFFFD0); + IPendingCache = 0; + return; + } + else // Regular exception + { + S_REG[EIPC] = GetPC(); + S_REG[EIPSW] = S_REG[PSW]; + S_REG[ECR] = (S_REG[ECR] & 0xFFFF0000) | eCode; + S_REG[PSW] |= PSW_EP; + S_REG[PSW] |= PSW_ID; + S_REG[PSW] &= ~PSW_AE; + + SetPC(handler); + IPendingCache = 0; + return; + } +} diff --git a/waterbox/vb/v810/v810_cpu.h b/waterbox/vb/v810/v810_cpu.h new file mode 100644 index 0000000000..4f3196a5c7 --- /dev/null +++ b/waterbox/vb/v810/v810_cpu.h @@ -0,0 +1,333 @@ +//////////////////////////////////////////////////////////////// +// Defines for the V810 CPU + +#pragma once + +#include + +typedef int32 v810_timestamp_t; + +#define V810_FAST_MAP_SHIFT 16 +#define V810_FAST_MAP_PSIZE (1 << V810_FAST_MAP_SHIFT) +#define V810_FAST_MAP_TRAMPOLINE_SIZE 1024 + +// Exception codes +enum +{ + ECODE_TRAP_BASE = 0xFFA0, + ECODE_INVALID_OP = 0xFF90, + ECODE_ZERO_DIV = 0xFF80, // Integer divide by 0 + ECODE_FIV = 0xFF70, // Floating point invalid operation + ECODE_FZD = 0xFF68, // Floating point zero division + ECODE_FOV = 0xFF64, // Floating point overflow + //#define ECODE_FUD 0xFF62 // Floating point underflow(unused on V810) + //#define ECODE_FPR 0xFF61 // Floating point precision degradation(unused on V810) + ECODE_FRO = 0xFF60 // Floating point reserved operand +}; + +enum +{ + INVALID_OP_HANDLER_ADDR = 0xFFFFFF90, // Invalid opcode/instruction code! + ZERO_DIV_HANDLER_ADDR = 0xFFFFFF80, // Integer divide by 0 exception + FPU_HANDLER_ADDR = 0xFFFFFF60, // FPU exception + TRAP_HANDLER_BASE = 0xFFFFFFA0 // TRAP instruction +}; + +//System Register Defines (these are the only valid system registers!) +#define EIPC 0 //Exeption/Interupt PC +#define EIPSW 1 //Exeption/Interupt PSW + +#define FEPC 2 //Fatal Error PC +#define FEPSW 3 //Fatal Error PSW + +#define ECR 4 //Exception Cause Register +#define PSW 5 //Program Status Word +#define PIR 6 //Processor ID Register +#define TKCW 7 //Task Controll Word +#define CHCW 24 //Cashe Controll Word +#define ADDTRE 25 //ADDTRE + +//PSW Specifics +#define PSW_IA 0xF0000 // All Interupt bits... +#define PSW_I3 0x80000 +#define PSW_I2 0x40000 +#define PSW_I1 0x20000 +#define PSW_I0 0x10000 + +#define PSW_NP 0x08000 +#define PSW_EP 0x04000 + +#define PSW_AE 0x02000 + +#define PSW_ID 0x01000 + +#define PSW_FRO 0x00200 // Floating point reserved operand(set on denormal, NaN, or indefinite) +#define PSW_FIV 0x00100 // Floating point invalid operation(set when trying to convert a number too large to an (un)signed integer) + +#define PSW_FZD 0x00080 // Floating point divide by zero +#define PSW_FOV 0x00040 // Floating point overflow +#define PSW_FUD 0x00020 // Floating point underflow +#define PSW_FPR 0x00010 // Floating point precision degradation + +#define PSW_CY 0x00008 +#define PSW_OV 0x00004 +#define PSW_S 0x00002 +#define PSW_Z 0x00001 + +//condition codes +#define COND_V 0 +#define COND_C 1 +#define COND_Z 2 +#define COND_NH 3 +#define COND_S 4 +#define COND_T 5 +#define COND_LT 6 +#define COND_LE 7 +#define COND_NV 8 +#define COND_NC 9 +#define COND_NZ 10 +#define COND_H 11 +#define COND_NS 12 +#define COND_F 13 +#define COND_GE 14 +#define COND_GT 15 + +#define TESTCOND_V (S_REG[PSW] & PSW_OV) + +#define TESTCOND_L (S_REG[PSW] & PSW_CY) +#define TESTCOND_C TESTCOND_L + +#define TESTCOND_E (S_REG[PSW] & PSW_Z) +#define TESTCOND_Z TESTCOND_E + +#define TESTCOND_NH ((S_REG[PSW] & PSW_Z) || (S_REG[PSW] & PSW_CY)) +#define TESTCOND_N (S_REG[PSW] & PSW_S) +#define TESTCOND_S TESTCOND_N + +#define TESTCOND_LT ((!!(S_REG[PSW] & PSW_S)) ^ (!!(S_REG[PSW] & PSW_OV))) +#define TESTCOND_LE (((!!(S_REG[PSW] & PSW_S)) ^ (!!(S_REG[PSW] & PSW_OV))) || (S_REG[PSW] & PSW_Z)) +#define TESTCOND_NV (!(S_REG[PSW] & PSW_OV)) + +#define TESTCOND_NL (!(S_REG[PSW] & PSW_CY)) +#define TESTCOND_NC TESTCOND_NL + +#define TESTCOND_NE (!(S_REG[PSW] & PSW_Z)) +#define TESTCOND_NZ TESTCOND_NE + +#define TESTCOND_H (!((S_REG[PSW] & PSW_Z) || (S_REG[PSW] & PSW_CY))) +#define TESTCOND_P (!(S_REG[PSW] & PSW_S)) +#define TESTCOND_NS TESTCOND_P + +#define TESTCOND_GE (!((!!(S_REG[PSW] & PSW_S)) ^ (!!(S_REG[PSW] & PSW_OV)))) +#define TESTCOND_GT (!(((!!(S_REG[PSW] & PSW_S)) ^ (!!(S_REG[PSW] & PSW_OV))) || (S_REG[PSW] & PSW_Z))) + +// Tag layout +// Bit 0-21: TAG31-TAG10 +// Bit 22-23: Validity bits(one for each 4-byte subblock) +// Bit 24-27: NECRV("Reserved") +// Bit 28-31: 0 + +typedef enum { + V810_EMU_MODE_FAST = 0, + V810_EMU_MODE_ACCURATE = 1, + _V810_EMU_MODE_COUNT +} V810_Emu_Mode; + +class V810 +{ + public: + V810() + MDFN_COLD; + ~V810() MDFN_COLD; + + // Pass TRUE for vb_mode if we're emulating a VB-specific enhanced V810 CPU core + bool Init(V810_Emu_Mode mode, bool vb_mode) MDFN_COLD; + + void SetInt(int level); + + void SetMemWriteBus32(uint8 A, bool value) MDFN_COLD; + void SetMemReadBus32(uint8 A, bool value) MDFN_COLD; + + void SetMemReadHandlers(uint8 MDFN_FASTCALL (*read8)(v810_timestamp_t &, uint32), uint16 MDFN_FASTCALL (*read16)(v810_timestamp_t &, uint32), uint32 MDFN_FASTCALL (*read32)(v810_timestamp_t &, uint32)) MDFN_COLD; + void SetMemWriteHandlers(void MDFN_FASTCALL (*write8)(v810_timestamp_t &, uint32, uint8), void MDFN_FASTCALL (*write16)(v810_timestamp_t &, uint32, uint16), void MDFN_FASTCALL (*write32)(v810_timestamp_t &, uint32, uint32)) MDFN_COLD; + + void SetIOReadHandlers(uint8 MDFN_FASTCALL (*read8)(v810_timestamp_t &, uint32), uint16 MDFN_FASTCALL (*read16)(v810_timestamp_t &, uint32), uint32 MDFN_FASTCALL (*read32)(v810_timestamp_t &, uint32)) MDFN_COLD; + void SetIOWriteHandlers(void MDFN_FASTCALL (*write8)(v810_timestamp_t &, uint32, uint8), void MDFN_FASTCALL (*write16)(v810_timestamp_t &, uint32, uint16), void MDFN_FASTCALL (*write32)(v810_timestamp_t &, uint32, uint32)) MDFN_COLD; + + // Length specifies the number of bytes to map in, at each location specified by addresses[] (for mirroring) + uint8 *SetFastMap(void *(*allocator)(size_t size), uint32 addresses[], uint32 length, unsigned int num_addresses, const char *name) MDFN_COLD; + + INLINE void ResetTS(v810_timestamp_t new_base_timestamp) + { + assert(next_event_ts > v810_timestamp); + + next_event_ts -= (v810_timestamp - new_base_timestamp); + v810_timestamp = new_base_timestamp; + } + + INLINE void SetEventNT(const v810_timestamp_t timestamp) + { + next_event_ts = timestamp; + } + + INLINE v810_timestamp_t GetEventNT(void) + { + return (next_event_ts); + } + + v810_timestamp_t Run(int32 MDFN_FASTCALL (*event_handler)(const v810_timestamp_t timestamp)); + void Exit(void); + + void Reset(void) MDFN_COLD; + + enum + { + GSREG_PR = 0, + GSREG_SR = 32, + GSREG_PC = 64, + GSREG_TIMESTAMP + }; + + uint32 GetRegister(unsigned int which, char *special, const uint32 special_len); + void SetRegister(unsigned int which, uint32 value); + + uint32 GetPC(void); + void SetPC(uint32); + + INLINE uint32 GetPR(unsigned int which) + { + return which ? P_REG[which] : 0; + } + + private: + // Make sure P_REG[] is the first variable/array in this class, so non-zerfo offset encoding(at assembly level) isn't necessary to access it. + uint32 P_REG[32]; // Program registers pr0-pr31 + uint32 S_REG[32]; // System registers sr0-sr31 + uint32 PC; + uint8 *PC_ptr; + uint8 *PC_base; + + uint32 IPendingCache; + void RecalcIPendingCache(void); + + public: + v810_timestamp_t v810_timestamp; // Will never be less than 0. + + private: + v810_timestamp_t next_event_ts; + + enum + { + LASTOP_NORMAL = 0, + LASTOP_LOAD = 1, + LASTOP_STORE = 2, + LASTOP_IN = 3, + LASTOP_OUT = 4, + LASTOP_HEAVY_MATH = 5 + }; + + V810_Emu_Mode EmuMode; + bool VBMode; + + void Run_Fast(int32 MDFN_FASTCALL (*event_handler)(const v810_timestamp_t timestamp)) NO_INLINE; + void Run_Accurate(int32 MDFN_FASTCALL (*event_handler)(const v810_timestamp_t timestamp)) NO_INLINE; + + uint8 MDFN_FASTCALL (*MemRead8)(v810_timestamp_t ×tamp, uint32 A); + uint16 MDFN_FASTCALL (*MemRead16)(v810_timestamp_t ×tamp, uint32 A); + uint32 MDFN_FASTCALL (*MemRead32)(v810_timestamp_t ×tamp, uint32 A); + + void MDFN_FASTCALL (*MemWrite8)(v810_timestamp_t ×tamp, uint32 A, uint8 V); + void MDFN_FASTCALL (*MemWrite16)(v810_timestamp_t ×tamp, uint32 A, uint16 V); + void MDFN_FASTCALL (*MemWrite32)(v810_timestamp_t ×tamp, uint32 A, uint32 V); + + uint8 MDFN_FASTCALL (*IORead8)(v810_timestamp_t ×tamp, uint32 A); + uint16 MDFN_FASTCALL (*IORead16)(v810_timestamp_t ×tamp, uint32 A); + uint32 MDFN_FASTCALL (*IORead32)(v810_timestamp_t ×tamp, uint32 A); + + void MDFN_FASTCALL (*IOWrite8)(v810_timestamp_t ×tamp, uint32 A, uint8 V); + void MDFN_FASTCALL (*IOWrite16)(v810_timestamp_t ×tamp, uint32 A, uint16 V); + void MDFN_FASTCALL (*IOWrite32)(v810_timestamp_t ×tamp, uint32 A, uint32 V); + + bool MemReadBus32[256]; // Corresponding to the upper 8 bits of the memory address map. + bool MemWriteBus32[256]; + + int32 lastop; // Set to -1 on FP/MUL/DIV, 0x100 on LD, 0x200 on ST, 0x400 on in, 0x800 on out, and the actual opcode * 2(or >= 0) on everything else. + +#define LASTOP_LD 0x100 +#define LASTOP_ST 0x200 +#define LASTOP_IN 0x400 +#define LASTOP_OUT 0x800 + + enum + { + HALT_NONE = 0, + HALT_HALT = 1, + HALT_FATAL_EXCEPTION = 2 + }; + + uint8 Halted; + + bool Running; + + int ilevel; + + bool in_bstr; + uint16 in_bstr_to; + + bool bstr_subop(v810_timestamp_t ×tamp, int sub_op, int arg1); + void fpu_subop(v810_timestamp_t ×tamp, int sub_op, int arg1, int arg2); + + void Exception(uint32 handler, uint16 eCode); + + // Caching-related: + typedef struct + { + uint32 tag; + uint32 data[2]; + bool data_valid[2]; + } V810_CacheEntry_t; + + V810_CacheEntry_t Cache[128]; + + // Bitstring variables. + uint32 src_cache; + uint32 dst_cache; + bool have_src_cache, have_dst_cache; + + uint8** FastMap; + + // For CacheDump and CacheRestore + void CacheOpMemStore(v810_timestamp_t ×tamp, uint32 A, uint32 V); + uint32 CacheOpMemLoad(v810_timestamp_t ×tamp, uint32 A); + + void CacheClear(v810_timestamp_t ×tamp, uint32 start, uint32 count); + void CacheDump(v810_timestamp_t ×tamp, const uint32 SA); + void CacheRestore(v810_timestamp_t ×tamp, const uint32 SA); + + uint32 RDCACHE(v810_timestamp_t ×tamp, uint32 addr); + // + // End caching related + // + + uint16 RDOP(v810_timestamp_t ×tamp, uint32 addr, uint32 meow = 2); + void SetFlag(uint32 n, bool condition); + void SetSZ(uint32 value); + + void SetSREG(v810_timestamp_t ×tamp, unsigned int which, uint32 value); + uint32 GetSREG(unsigned int which); + + bool IsSubnormal(uint32 fpval); + void FPU_Math_Template(uint32 (V810_FP_Ops::*func)(uint32, uint32), uint32 arg1, uint32 arg2); + void FPU_DoException(void); + bool CheckFPInputException(uint32 fpval); + bool FPU_DoesExceptionKillResult(void); + void SetFPUOPNonFPUFlags(uint32 result); + + uint32 BSTR_RWORD(v810_timestamp_t ×tamp, uint32 A); + void BSTR_WWORD(v810_timestamp_t ×tamp, uint32 A, uint32 V); + bool Do_BSTR_Search(v810_timestamp_t ×tamp, const int inc_mul, unsigned int bit_test); + + V810_FP_Ops fpo; + + uint8 DummyRegion[V810_FAST_MAP_PSIZE + V810_FAST_MAP_TRAMPOLINE_SIZE]; +}; diff --git a/waterbox/vb/v810/v810_do_am.h b/waterbox/vb/v810/v810_do_am.h new file mode 100644 index 0000000000..9cc01568d3 --- /dev/null +++ b/waterbox/vb/v810/v810_do_am.h @@ -0,0 +1,72 @@ +#define DO_MOV_AM(); DO_AM_I(); +#define DO_ADD_AM(); DO_AM_I(); +#define DO_SUB_AM(); DO_AM_I(); +#define DO_CMP_AM(); DO_AM_I(); +#define DO_SHL_AM(); DO_AM_I(); +#define DO_SHR_AM(); DO_AM_I(); +#define DO_JMP_AM(); DO_AM_I(); +#define DO_SAR_AM(); DO_AM_I(); +#define DO_MUL_AM(); DO_AM_I(); +#define DO_DIV_AM(); DO_AM_I(); +#define DO_MULU_AM(); DO_AM_I(); +#define DO_DIVU_AM(); DO_AM_I(); +#define DO_OR_AM(); DO_AM_I(); +#define DO_AND_AM(); DO_AM_I(); +#define DO_XOR_AM(); DO_AM_I(); +#define DO_NOT_AM(); DO_AM_I(); +#define DO_MOV_I_AM(); DO_AM_II(); +#define DO_ADD_I_AM(); DO_AM_II(); +#define DO_SETF_AM(); DO_AM_II(); +#define DO_CMP_I_AM(); DO_AM_II(); +#define DO_SHL_I_AM(); DO_AM_II(); +#define DO_SHR_I_AM(); DO_AM_II(); +#define DO_EI_AM(); DO_AM_II(); +#define DO_SAR_I_AM(); DO_AM_II(); +#define DO_TRAP_AM(); DO_AM_II(); +#define DO_RETI_AM(); DO_AM_IX(); +#define DO_HALT_AM(); DO_AM_IX(); +#define DO_LDSR_AM(); DO_AM_II(); +#define DO_STSR_AM(); DO_AM_II(); +#define DO_DI_AM(); DO_AM_II(); +#define DO_BSTR_AM(); DO_AM_BSTR(); +#define DO_MOVEA_AM(); DO_AM_V(); +#define DO_ADDI_AM(); DO_AM_V(); +#define DO_JR_AM(); DO_AM_IV(); +#define DO_JAL_AM(); DO_AM_IV(); +#define DO_ORI_AM(); DO_AM_V(); +#define DO_ANDI_AM(); DO_AM_V(); +#define DO_XORI_AM(); DO_AM_V(); +#define DO_MOVHI_AM(); DO_AM_V(); +#define DO_LD_B_AM(); DO_AM_VIa(); +#define DO_LD_H_AM(); DO_AM_VIa(); +#define DO_LD_W_AM(); DO_AM_VIa(); +#define DO_ST_B_AM(); DO_AM_VIb(); +#define DO_ST_H_AM(); DO_AM_VIb(); +#define DO_ST_W_AM(); DO_AM_VIb(); +#define DO_IN_B_AM(); DO_AM_VIa(); +#define DO_IN_H_AM(); DO_AM_VIa(); +#define DO_CAXI_AM(); DO_AM_VIa(); +#define DO_IN_W_AM(); DO_AM_VIa(); +#define DO_OUT_B_AM(); DO_AM_VIb(); +#define DO_OUT_H_AM(); DO_AM_VIb(); +#define DO_FPP_AM(); DO_AM_FPP(); +#define DO_OUT_W_AM(); DO_AM_VIb(); +#define DO_BV_AM(); DO_AM_III(); +#define DO_BL_AM(); DO_AM_III(); +#define DO_BE_AM(); DO_AM_III(); +#define DO_BNH_AM(); DO_AM_III(); +#define DO_BN_AM(); DO_AM_III(); +#define DO_BR_AM(); DO_AM_III(); +#define DO_BLT_AM(); DO_AM_III(); +#define DO_BLE_AM(); DO_AM_III(); +#define DO_BNV_AM(); DO_AM_III(); +#define DO_BNL_AM(); DO_AM_III(); +#define DO_BNE_AM(); DO_AM_III(); +#define DO_BH_AM(); DO_AM_III(); +#define DO_BP_AM(); DO_AM_III(); +#define DO_NOP_AM(); DO_AM_III(); +#define DO_BGE_AM(); DO_AM_III(); +#define DO_BGT_AM(); DO_AM_III(); + + +#define DO_INVALID_AM(); DO_AM_UDEF(); diff --git a/waterbox/vb/v810/v810_fp_ops.cpp b/waterbox/vb/v810/v810_fp_ops.cpp new file mode 100644 index 0000000000..53aa937fae --- /dev/null +++ b/waterbox/vb/v810/v810_fp_ops.cpp @@ -0,0 +1,405 @@ +/******************************************************************************/ +/* Mednafen - Multi-system Emulator */ +/******************************************************************************/ +/* v810_fp_ops.cpp: +** Copyright (C) 2014-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "vb.h" + +bool V810_FP_Ops::fp_is_zero(uint32 v) +{ + return ((v & 0x7FFFFFFF) == 0); +} + +#if 0 +bool V810_FP_Ops::fp_is_nan(uint32 v) +{ + return((v & 0x7FFFFFFF) > (255 << 23)); +} + +bool V810_FP_Ops::fp_is_inf(uint32 v) +{ + return((v & 0x7FFFFFFF) == (255 << 23)); +} +#endif + +bool V810_FP_Ops::fp_is_inf_nan_sub(uint32 v) +{ + if ((v & 0x7FFFFFFF) == 0) + return (false); + + switch ((v >> 23) & 0xFF) + { + case 0x00: + case 0xff: + return (true); + } + return (false); +} + +void V810_FP_Ops::fpim_decode(fpim *df, uint32 v) +{ + df->exp = ((v >> 23) & 0xFF) - 127; + df->f = (v & 0x7FFFFF) | ((v & 0x7FFFFFFF) ? 0x800000 : 0); + df->sign = v >> 31; +} + +void V810_FP_Ops::fpim_round(fpim *df) +{ + int vbc = 64 - MDFN_lzcount64(df->f); + + if (vbc > 24) + { + const unsigned sa = vbc - 24; + + if (1) // round to nearest + { + uint64 old_f = df->f; + + df->f = (df->f + ((df->f >> sa) & 1) + ((1ULL << (sa - 1)) - 1)) & ~((1ULL << sa) - 1); + + if (df->f != old_f) + { + //printf("Inexact mr\n"); + exception_flags |= flag_inexact; + } + } + else + abort(); + } +} + +void V810_FP_Ops::fpim_round_int(fpim *df, bool truncate) +{ + if (df->exp < 23) + { + const unsigned sa = 23 - df->exp; + uint64 old_f = df->f; + + //if(sa >= 2) + // printf("RI: %lld, %d\n", df->f, sa); + + // round to nearest + if (sa > 24) + df->f = 0; + else + { + if (truncate) + df->f = df->f & ~((1ULL << sa) - 1); + else + df->f = (df->f + ((df->f >> sa) & 1) + ((1ULL << (sa - 1)) - 1)) & ~((1ULL << sa) - 1); + } + + if (df->f != old_f) + { + //printf("Inexact\n"); + exception_flags |= flag_inexact; + } + } +} + +uint32 V810_FP_Ops::fpim_encode(fpim *df) +{ + const int lzc = MDFN_lzcount64(df->f); + int tmp_exp = df->exp - lzc; + uint64 tmp_walrus = df->f << (lzc & 0x3F); + int tmp_sign = df->sign; + + tmp_exp += 40; + tmp_walrus >>= 40; + + if (tmp_walrus == 0) + tmp_exp = -127; + else if (tmp_exp <= -127) + { + exception_flags |= flag_underflow | flag_inexact; + //printf("Subnormal: %lld. %d\n", tmp_walrus, tmp_exp); + if (1) + { + tmp_exp = -127; + tmp_walrus = 0; + } + else + { + tmp_walrus >>= -(tmp_exp + 126); + tmp_exp = -127; + } + } + else if (tmp_exp >= 128) + { + exception_flags |= flag_overflow; + //printf("Overflow!\n"); + + if (1) + tmp_exp -= 192; + else + { + tmp_exp = 128; + tmp_walrus = 0; + } + } + return (tmp_sign << 31) | ((tmp_exp + 127) << 23) | (tmp_walrus & 0x7FFFFF); +} + +uint32 V810_FP_Ops::mul(uint32 a, uint32 b) +{ + fpim ins[2]; + fpim res; + + if (fp_is_inf_nan_sub(a) || fp_is_inf_nan_sub(b)) + { + exception_flags |= flag_reserved; + return (~0U); + } + + fpim_decode(&ins[0], a); + fpim_decode(&ins[1], b); + + //printf("%08x %08x - %d %d %d - %d %d %d\n", a, b, a_exp, a_walrus, a_sign, b_exp, b_walrus, b_sign); + + res.exp = ins[0].exp + ins[1].exp - 23; + res.f = ins[0].f * ins[1].f; + res.sign = ins[0].sign ^ ins[1].sign; + + fpim_round(&res); + + return fpim_encode(&res); +} + +uint32 V810_FP_Ops::add(uint32 a, uint32 b) +{ + fpim ins[2]; + fpim res; + int64 ft[2]; + int64 tr; + int max_exp; + + if (fp_is_inf_nan_sub(a) || fp_is_inf_nan_sub(b)) + { + exception_flags |= flag_reserved; + return (~0U); + } + + if (a == b && !(a & 0x7FFFFFFF)) + { + return (a & 0x80000000); + } + + fpim_decode(&ins[0], a); + fpim_decode(&ins[1], b); + + max_exp = std::max(ins[0].exp, ins[1].exp); + + //printf("%d:%08llx %d:%08llx\n", ins[0].exp, ins[0].f, ins[1].exp, ins[1].f); + + for (unsigned i = 0; i < 2; i++) + { + unsigned sd = (max_exp - ins[i].exp); + + ft[i] = ins[i].f << 24; + + if (sd >= 48) + { + if (ft[i] != 0) + ft[i] = 1; + } + else + { + int64 nft = ft[i] >> sd; + + if (ft[i] != (nft << sd)) + { + nft |= 1; + } + //{ + // puts("FPR"); + // } + + ft[i] = nft; + } + + if (ins[i].sign) + ft[i] = -ft[i]; + } + + //printf("SOON: %08llx %08llx\n", ft[0], ft[1]); + + tr = ft[0] + ft[1]; + if (tr < 0) + { + tr = -tr; + res.sign = true; + } + else + res.sign = false; + + res.f = tr; + res.exp = max_exp - 24; + + fpim_round(&res); + + return fpim_encode(&res); +} + +uint32 V810_FP_Ops::sub(uint32 a, uint32 b) +{ + return add(a, b ^ 0x80000000); +} + +uint32 V810_FP_Ops::div(uint32 a, uint32 b) +{ + fpim ins[2]; + fpim res; + uint64 mtmp; + + if (fp_is_inf_nan_sub(a) || fp_is_inf_nan_sub(b)) + { + exception_flags |= flag_reserved; + return (~0U); + } + + if (fp_is_zero(a) && fp_is_zero(b)) + { + exception_flags |= flag_invalid; + return (~0U); + } + + fpim_decode(&ins[0], a); + fpim_decode(&ins[1], b); + + res.sign = ins[0].sign ^ ins[1].sign; + + if (ins[1].f == 0) + { + //puts("Divide by zero!"); + exception_flags |= flag_divbyzero; + return ((res.sign << 31) | (255 << 23)); + } + else + { + res.exp = ins[0].exp - ins[1].exp - 2 - 1; // + 23 - 2; + res.f = ((ins[0].f << 24) / ins[1].f) << 2; + mtmp = ((ins[0].f << 24) % ins[1].f) << 1; + + //printf("%lld %lld\n", (ins[0].f << 23) % ins[1].f, ins[1].f); + + if (mtmp > ins[1].f) + res.f |= 3; + else if (mtmp == ins[1].f) + res.f |= 2; + else if (mtmp > 0) + res.f |= 1; + } + + fpim_round(&res); + + return fpim_encode(&res); +} + +int V810_FP_Ops::cmp(uint32 a, uint32 b) +{ + fpim ins[2]; + + if (fp_is_inf_nan_sub(a) || fp_is_inf_nan_sub(b)) + { + exception_flags |= flag_reserved; + return (~0U); + } + + fpim_decode(&ins[0], a); + fpim_decode(&ins[1], b); + + if (ins[0].exp > ins[1].exp) + return (ins[0].sign ? -1 : 1); + + if (ins[0].exp < ins[1].exp) + return (ins[1].sign ? 1 : -1); + + if (ins[0].f > ins[1].f) + return (ins[0].sign ? -1 : 1); + + if (ins[0].f < ins[1].f) + return (ins[1].sign ? 1 : -1); + + if ((ins[0].sign ^ ins[1].sign) && ins[0].f != 0) + return (ins[0].sign ? -1 : 1); + + return (0); +} + +uint32 V810_FP_Ops::itof(uint32 v) +{ + fpim res; + + res.sign = (bool)(v & 0x80000000); + res.exp = 23; + res.f = res.sign ? (0x80000000 - (v & 0x7FFFFFFF)) : (v & 0x7FFFFFFF); + + fpim_round(&res); + + return fpim_encode(&res); +} + +uint32 V810_FP_Ops::ftoi(uint32 v, bool truncate) +{ + fpim ins; + int sa; + int ret; + + if (fp_is_inf_nan_sub(v)) + { + exception_flags |= flag_reserved; + return (~0U); + } + + fpim_decode(&ins, v); + fpim_round_int(&ins, truncate); + + sa = ins.exp - 23; + + if (sa < 0) + { + if (sa <= -32) + ret = 0; + else + ret = ins.f >> -sa; + } + else + { + if (sa >= 8) + { + if (sa == 8 && ins.f == 0x800000 && ins.sign) + return (0x80000000); + else + { + ret = ~0U; + exception_flags |= flag_invalid; + } + } + else + { + ret = ins.f << sa; + } + } + //printf("%d\n", sa); + + if (ins.sign) + ret = -ret; + + return (ret); +} diff --git a/waterbox/vb/v810/v810_fp_ops.h b/waterbox/vb/v810/v810_fp_ops.h new file mode 100644 index 0000000000..20c607e7d2 --- /dev/null +++ b/waterbox/vb/v810/v810_fp_ops.h @@ -0,0 +1,74 @@ +/******************************************************************************/ +/* Mednafen - Multi-system Emulator */ +/******************************************************************************/ +/* v810_fp_ops.h: +** Copyright (C) 2014-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#pragma once + +class V810_FP_Ops +{ + public: + uint32 mul(uint32 a, uint32 b); + uint32 div(uint32 a, uint32 b); + uint32 add(uint32 a, uint32 b); + uint32 sub(uint32 a, uint32 b); + int cmp(uint32 a, uint32 b); + + uint32 itof(uint32 v); + uint32 ftoi(uint32 v, bool truncate); + + enum + { + flag_invalid = 0x0001, + flag_divbyzero = 0x0002, + flag_overflow = 0x0004, + flag_underflow = 0x0008, + flag_inexact = 0x0010, + flag_reserved = 0x0020 + }; + + inline uint32 get_flags(void) + { + return exception_flags; + } + + inline void clear_flags(void) + { + exception_flags = 0; + } + + private: + unsigned exception_flags; + + struct fpim + { + uint64 f; + int exp; + bool sign; + }; + + bool fp_is_zero(uint32 v); + bool fp_is_inf_nan_sub(uint32 v); + + unsigned clz64(uint64 v); + void fpim_decode(fpim *df, uint32 v); + void fpim_round(fpim *df); + void fpim_round_int(fpim *df, bool truncate = false); + uint32 fpim_encode(fpim *df); +}; diff --git a/waterbox/vb/v810/v810_oploop.inc b/waterbox/vb/v810/v810_oploop.inc new file mode 100644 index 0000000000..6b5015c744 --- /dev/null +++ b/waterbox/vb/v810/v810_oploop.inc @@ -0,0 +1,1130 @@ +/* V810 Emulator + * + * Copyright (C) 2006 David Tucker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + + // Macro test taken from http://gcc.gnu.org/viewcvs/trunk/gcc/testsuite/gcc.dg/20020919-1.c?view=markup&pathrev=142696 + //#if defined (__powerpc__) || defined (__PPC__) || defined (__ppc__) || defined (__POWERPC__) || defined (PPC) || defined (_IBMR2) + // register v810_timestamp_t timestamp_rl asm("15") = v810_timestamp; + //#elif defined(__x86_64__) + // register v810_timestamp_t timestamp_rl asm("r11") = v810_timestamp; + //#else + register v810_timestamp_t timestamp_rl = v810_timestamp; + //#endif + + uint32 opcode; + uint32 tmp2; + int val = 0; + + + #define ADDCLOCK(__n) { timestamp += __n; } + + #define CHECK_HALTED(); { if(Halted && timestamp < next_event_ts) { timestamp = next_event_ts; } } + + while(Running) + { + #ifdef RB_DEBUGMODE + uint32 old_PC = RB_GETPC(); + #endif + uint32 tmpop; + + assert(timestamp_rl <= next_event_ts); + + if(!IPendingCache) + { + if(Halted) + { + timestamp_rl = next_event_ts; + } + else if(in_bstr) + { + tmpop = in_bstr_to; + opcode = tmpop >> 9; + goto op_BSTR; + } + } + + while(timestamp_rl < next_event_ts) + { + #ifdef RB_DEBUGMODE + old_PC = RB_GETPC(); + #endif + + P_REG[0] = 0; //Zero the Zero Reg!!! + + RB_CPUHOOK(RB_GETPC()); + + { + //printf("%08x\n", RB_GETPC()); + { + v810_timestamp_t timestamp = timestamp_rl; + + tmpop = RB_RDOP(0, 0); + + timestamp_rl = timestamp; + } + + opcode = (tmpop >> 9) | IPendingCache; + + //printf("%02x\n", opcode >> 1); +#if HAVE_COMPUTED_GOTO + #define CGBEGIN static const void *const op_goto_table[256] = { + #define CGE(l) &&l, + #define CGEND }; goto *op_goto_table[opcode]; +#else + /* (uint8) cast for cheaper alternative to generated branch+compare bounds check instructions, but still more + expensive than computed goto which needs no masking nor bounds checking. + */ + #define CGBEGIN { enum { CGESB = 1 + __COUNTER__ }; switch((uint8)opcode) { + #define CGE(l) case __COUNTER__ - CGESB: goto l; + #define CGEND } } +#endif + + CGBEGIN + CGE(op_MOV) CGE(op_MOV) CGE(op_ADD) CGE(op_ADD) CGE(op_SUB) CGE(op_SUB) CGE(op_CMP) CGE(op_CMP) + CGE(op_SHL) CGE(op_SHL) CGE(op_SHR) CGE(op_SHR) CGE(op_JMP) CGE(op_JMP) CGE(op_SAR) CGE(op_SAR) + CGE(op_MUL) CGE(op_MUL) CGE(op_DIV) CGE(op_DIV) CGE(op_MULU) CGE(op_MULU) CGE(op_DIVU) CGE(op_DIVU) + CGE(op_OR) CGE(op_OR) CGE(op_AND) CGE(op_AND) CGE(op_XOR) CGE(op_XOR) CGE(op_NOT) CGE(op_NOT) + CGE(op_MOV_I) CGE(op_MOV_I) CGE(op_ADD_I) CGE(op_ADD_I) CGE(op_SETF) CGE(op_SETF) CGE(op_CMP_I) CGE(op_CMP_I) + CGE(op_SHL_I) CGE(op_SHL_I) CGE(op_SHR_I) CGE(op_SHR_I) CGE(op_EI) CGE(op_EI) CGE(op_SAR_I) CGE(op_SAR_I) + CGE(op_TRAP) CGE(op_TRAP) CGE(op_RETI) CGE(op_RETI) CGE(op_HALT) CGE(op_HALT) CGE(op_INVALID) CGE(op_INVALID) + CGE(op_LDSR) CGE(op_LDSR) CGE(op_STSR) CGE(op_STSR) CGE(op_DI) CGE(op_DI) CGE(op_BSTR) CGE(op_BSTR) + CGE(op_BV) CGE(op_BL) CGE(op_BE) CGE(op_BNH) CGE(op_BN) CGE(op_BR) CGE(op_BLT) CGE(op_BLE) + CGE(op_BNV) CGE(op_BNL) CGE(op_BNE) CGE(op_BH) CGE(op_BP) CGE(op_NOP) CGE(op_BGE) CGE(op_BGT) + CGE(op_MOVEA) CGE(op_MOVEA) CGE(op_ADDI) CGE(op_ADDI) CGE(op_JR) CGE(op_JR) CGE(op_JAL) CGE(op_JAL) + CGE(op_ORI) CGE(op_ORI) CGE(op_ANDI) CGE(op_ANDI) CGE(op_XORI) CGE(op_XORI) CGE(op_MOVHI) CGE(op_MOVHI) + CGE(op_LD_B) CGE(op_LD_B) CGE(op_LD_H) CGE(op_LD_H) CGE(op_INVALID) CGE(op_INVALID) CGE(op_LD_W) CGE(op_LD_W) + CGE(op_ST_B) CGE(op_ST_B) CGE(op_ST_H) CGE(op_ST_H) CGE(op_INVALID) CGE(op_INVALID) CGE(op_ST_W) CGE(op_ST_W) + CGE(op_IN_B) CGE(op_IN_B) CGE(op_IN_H) CGE(op_IN_H) CGE(op_CAXI) CGE(op_CAXI) CGE(op_IN_W) CGE(op_IN_W) + CGE(op_OUT_B) CGE(op_OUT_B) CGE(op_OUT_H) CGE(op_OUT_H) CGE(op_FPP) CGE(op_FPP) CGE(op_OUT_W) CGE(op_OUT_W) + + CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) + CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) + CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) + CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) + CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) + CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) + CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) + CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) + + CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) + CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) + CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) + CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) + CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) + CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) + CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) + CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INVALID) CGE(op_INT_HANDLER) + CGEND + + // Bit string subopcodes + #define DO_AM_BSTR() \ + const uint32 arg1 = (tmpop >> 5) & 0x1F; \ + const uint32 arg2 = (tmpop & 0x1F); \ + RB_INCPCBY2(); + + + #define DO_AM_FPP() \ + const uint32 arg1 = (tmpop >> 5) & 0x1F; \ + const uint32 arg2 = (tmpop & 0x1F); \ + const uint32 arg3 = ((RB_RDOP(2) >> 10)&0x3F); \ + RB_INCPCBY4(); + + + #define DO_AM_UDEF() \ + RB_INCPCBY2(); + + #define DO_AM_I() \ + const uint32 arg1 = tmpop & 0x1F; \ + const uint32 arg2 = (tmpop >> 5) & 0x1F; \ + RB_INCPCBY2(); + + #define DO_AM_II() DO_AM_I(); + + + #define DO_AM_IV() \ + const uint32 arg1 = ((tmpop & 0x000003FF) << 16) | RB_RDOP(2); \ + + + #define DO_AM_V() \ + const uint32 arg3 = (tmpop >> 5) & 0x1F; \ + const uint32 arg2 = tmpop & 0x1F; \ + const uint32 arg1 = RB_RDOP(2); \ + RB_INCPCBY4(); + + + #define DO_AM_VIa() \ + const uint32 arg1 = RB_RDOP(2); \ + const uint32 arg2 = tmpop & 0x1F; \ + const uint32 arg3 = (tmpop >> 5) & 0x1F; \ + RB_INCPCBY4(); \ + + + #define DO_AM_VIb() \ + const uint32 arg1 = (tmpop >> 5) & 0x1F; \ + const uint32 arg2 = RB_RDOP(2); \ + const uint32 arg3 = (tmpop & 0x1F); \ + RB_INCPCBY4(); \ + + #define DO_AM_IX() \ + const uint32 arg1 = (tmpop & 0x1); \ + RB_INCPCBY2(); \ + + #define DO_AM_III() \ + const uint32 arg1 = tmpop & 0x1FE; + + #include "v810_do_am.h" + + #define BEGIN_OP(meowtmpop) { op_##meowtmpop: v810_timestamp_t timestamp = timestamp_rl; DO_##meowtmpop ##_AM(); + #define END_OP() timestamp_rl = timestamp; goto OpFinished; } + #define END_OP_SKIPLO() timestamp_rl = timestamp; goto OpFinishedSkipLO; } + + BEGIN_OP(MOV); + ADDCLOCK(1); + SetPREG(arg2, P_REG[arg1]); + END_OP(); + + + BEGIN_OP(ADD); + ADDCLOCK(1); + uint32 temp = P_REG[arg2] + P_REG[arg1]; + + SetFlag(PSW_OV, ((P_REG[arg2]^(~P_REG[arg1]))&(P_REG[arg2]^temp))&0x80000000); + SetFlag(PSW_CY, temp < P_REG[arg2]); + + SetPREG(arg2, temp); + SetSZ(P_REG[arg2]); + END_OP(); + + + BEGIN_OP(SUB); + ADDCLOCK(1); + uint32 temp = P_REG[arg2] - P_REG[arg1]; + + SetFlag(PSW_OV, ((P_REG[arg2]^P_REG[arg1])&(P_REG[arg2]^temp))&0x80000000); + SetFlag(PSW_CY, temp > P_REG[arg2]); + + SetPREG(arg2, temp); + SetSZ(P_REG[arg2]); + END_OP(); + + + BEGIN_OP(CMP); + ADDCLOCK(1); + uint32 temp = P_REG[arg2] - P_REG[arg1]; + + SetSZ(temp); + SetFlag(PSW_OV, ((P_REG[arg2]^P_REG[arg1])&(P_REG[arg2]^temp))&0x80000000); + SetFlag(PSW_CY, temp > P_REG[arg2]); + END_OP(); + + + BEGIN_OP(SHL); + ADDCLOCK(1); + val = P_REG[arg1] & 0x1F; + + // set CY before we destroy the regisrer info.... + SetFlag(PSW_CY, (val != 0) && ((P_REG[arg2] >> (32 - val))&0x01) ); + SetFlag(PSW_OV, FALSE); + SetPREG(arg2, P_REG[arg2] << val); + SetSZ(P_REG[arg2]); + END_OP(); + + BEGIN_OP(SHR); + ADDCLOCK(1); + val = P_REG[arg1] & 0x1F; + // set CY before we destroy the regisrer info.... + SetFlag(PSW_CY, (val) && ((P_REG[arg2] >> (val-1))&0x01)); + SetFlag(PSW_OV, FALSE); + SetPREG(arg2, P_REG[arg2] >> val); + SetSZ(P_REG[arg2]); + END_OP(); + + BEGIN_OP(JMP); + + (void)arg2; // arg2 is unused. + + ADDCLOCK(3); + RB_SETPC((P_REG[arg1] & 0xFFFFFFFE)); + if(RB_AccurateMode) + { + BRANCH_ALIGN_CHECK(PC); + } + RB_ADDBT(old_PC, RB_GETPC(), 0); + END_OP(); + + BEGIN_OP(SAR); + ADDCLOCK(1); + val = P_REG[arg1] & 0x1F; + + SetFlag(PSW_CY, (val) && ((P_REG[arg2]>>(val-1))&0x01) ); + SetFlag(PSW_OV, FALSE); + + SetPREG(arg2, (uint32) ((int32)P_REG[arg2] >> val)); + + SetSZ(P_REG[arg2]); + END_OP(); + + BEGIN_OP(OR); + ADDCLOCK(1); + SetPREG(arg2, P_REG[arg1] | P_REG[arg2]); + SetFlag(PSW_OV, FALSE); + SetSZ(P_REG[arg2]); + END_OP(); + + BEGIN_OP(AND); + ADDCLOCK(1); + SetPREG(arg2, P_REG[arg1] & P_REG[arg2]); + SetFlag(PSW_OV, FALSE); + SetSZ(P_REG[arg2]); + END_OP(); + + BEGIN_OP(XOR); + ADDCLOCK(1); + SetPREG(arg2, P_REG[arg1] ^ P_REG[arg2]); + SetFlag(PSW_OV, FALSE); + SetSZ(P_REG[arg2]); + END_OP(); + + BEGIN_OP(NOT); + ADDCLOCK(1); + SetPREG(arg2, ~P_REG[arg1]); + SetFlag(PSW_OV, FALSE); + SetSZ(P_REG[arg2]); + END_OP(); + + BEGIN_OP(MOV_I); + ADDCLOCK(1); + SetPREG(arg2,sign_5(arg1)); + END_OP(); + + BEGIN_OP(ADD_I); + ADDCLOCK(1); + uint32 temp = P_REG[arg2] + sign_5(arg1); + + SetFlag(PSW_OV, ((P_REG[arg2]^(~sign_5(arg1)))&(P_REG[arg2]^temp))&0x80000000); + SetFlag(PSW_CY, (uint32)temp < P_REG[arg2]); + + SetPREG(arg2, (uint32)temp); + SetSZ(P_REG[arg2]); + END_OP(); + + + BEGIN_OP(SETF); + ADDCLOCK(1); + + P_REG[arg2] = 0; + + switch (arg1 & 0x0F) + { + case COND_V: + if (TESTCOND_V) P_REG[arg2] = 1; + break; + case COND_C: + if (TESTCOND_C) P_REG[arg2] = 1; + break; + case COND_Z: + if (TESTCOND_Z) P_REG[arg2] = 1; + break; + case COND_NH: + if (TESTCOND_NH) P_REG[arg2] = 1; + break; + case COND_S: + if (TESTCOND_S) P_REG[arg2] = 1; + break; + case COND_T: + P_REG[arg2] = 1; + break; + case COND_LT: + if (TESTCOND_LT) P_REG[arg2] = 1; + break; + case COND_LE: + if (TESTCOND_LE) P_REG[arg2] = 1; + break; + case COND_NV: + if (TESTCOND_NV) P_REG[arg2] = 1; + break; + case COND_NC: + if (TESTCOND_NC) P_REG[arg2] = 1; + break; + case COND_NZ: + if (TESTCOND_NZ) P_REG[arg2] = 1; + break; + case COND_H: + if (TESTCOND_H) P_REG[arg2] = 1; + break; + case COND_NS: + if (TESTCOND_NS) P_REG[arg2] = 1; + break; + case COND_F: + //always false! do nothing more + break; + case COND_GE: + if (TESTCOND_GE) P_REG[arg2] = 1; + break; + case COND_GT: + if (TESTCOND_GT) P_REG[arg2] = 1; + break; + } + END_OP(); + + BEGIN_OP(CMP_I); + ADDCLOCK(1); + uint32 temp = P_REG[arg2] - sign_5(arg1); + + SetSZ(temp); + SetFlag(PSW_OV, ((P_REG[arg2]^(sign_5(arg1)))&(P_REG[arg2]^temp))&0x80000000); + SetFlag(PSW_CY, temp > P_REG[arg2]); + END_OP(); + + BEGIN_OP(SHR_I); + ADDCLOCK(1); + SetFlag(PSW_CY, arg1 && ((P_REG[arg2] >> (arg1-1))&0x01) ); + // set CY before we destroy the regisrer info.... + SetPREG(arg2, P_REG[arg2] >> arg1); + SetFlag(PSW_OV, FALSE); + SetSZ(P_REG[arg2]); + END_OP(); + + BEGIN_OP(SHL_I); + ADDCLOCK(1); + SetFlag(PSW_CY, arg1 && ((P_REG[arg2] >> (32 - arg1))&0x01) ); + // set CY before we destroy the regisrer info.... + + SetPREG(arg2, P_REG[arg2] << arg1); + SetFlag(PSW_OV, FALSE); + SetSZ(P_REG[arg2]); + END_OP(); + + BEGIN_OP(SAR_I); + ADDCLOCK(1); + SetFlag(PSW_CY, arg1 && ((P_REG[arg2]>>(arg1-1))&0x01) ); + + SetPREG(arg2, (uint32) ((int32)P_REG[arg2] >> arg1)); + + SetFlag(PSW_OV, FALSE); + SetSZ(P_REG[arg2]); + END_OP(); + + BEGIN_OP(LDSR); // Loads a Sys Reg with the value in specified PR + ADDCLOCK(1); // ? + + SetSREG(timestamp, arg1 & 0x1F, P_REG[arg2 & 0x1F]); + END_OP(); + + BEGIN_OP(STSR); // Loads a PR with the value in specified Sys Reg + ADDCLOCK(1); // ? + P_REG[arg2 & 0x1F] = GetSREG(arg1 & 0x1F); + END_OP(); + + BEGIN_OP(EI); + (void)arg1; // arg1 is unused. + (void)arg2; // arg2 is unused. + + if(VBMode) + { + ADDCLOCK(1); + S_REG[PSW] = S_REG[PSW] &~ PSW_ID; + RecalcIPendingCache(); + } + else + { + ADDCLOCK(1); + RB_DECPCBY2(); + Exception(INVALID_OP_HANDLER_ADDR, ECODE_INVALID_OP); + CHECK_HALTED(); + } + END_OP(); + + BEGIN_OP(DI); + (void)arg1; // arg1 is unused. + (void)arg2; // arg2 is unused. + + if(VBMode) + { + ADDCLOCK(1); + S_REG[PSW] |= PSW_ID; + IPendingCache = 0; + } + else + { + ADDCLOCK(1); + RB_DECPCBY2(); + Exception(INVALID_OP_HANDLER_ADDR, ECODE_INVALID_OP); + CHECK_HALTED(); + } + END_OP(); + + + #define COND_BRANCH(cond) \ + if(cond) \ + { \ + ADDCLOCK(3); \ + RB_PCRELCHANGE(sign_9(arg1) & 0xFFFFFFFE); \ + if(RB_AccurateMode) \ + { \ + BRANCH_ALIGN_CHECK(PC); \ + } \ + RB_ADDBT(old_PC, RB_GETPC(), 0); \ + } \ + else \ + { \ + ADDCLOCK(1); \ + RB_INCPCBY2(); \ + } + + BEGIN_OP(BV); + COND_BRANCH(TESTCOND_V); + END_OP(); + + + BEGIN_OP(BL); + COND_BRANCH(TESTCOND_L); + END_OP(); + + BEGIN_OP(BE); + COND_BRANCH(TESTCOND_E); + END_OP(); + + BEGIN_OP(BNH); + COND_BRANCH(TESTCOND_NH); + END_OP(); + + BEGIN_OP(BN); + COND_BRANCH(TESTCOND_N); + END_OP(); + + BEGIN_OP(BR); + COND_BRANCH(TRUE); + END_OP(); + + BEGIN_OP(BLT); + COND_BRANCH(TESTCOND_LT); + END_OP(); + + BEGIN_OP(BLE); + COND_BRANCH(TESTCOND_LE); + END_OP(); + + BEGIN_OP(BNV); + COND_BRANCH(TESTCOND_NV); + END_OP(); + + BEGIN_OP(BNL); + COND_BRANCH(TESTCOND_NL); + END_OP(); + + BEGIN_OP(BNE); + COND_BRANCH(TESTCOND_NE); + END_OP(); + + BEGIN_OP(BH); + COND_BRANCH(TESTCOND_H); + END_OP(); + + BEGIN_OP(BP); + COND_BRANCH(TESTCOND_P); + END_OP(); + + BEGIN_OP(BGE); + COND_BRANCH(TESTCOND_GE); + END_OP(); + + BEGIN_OP(BGT); + COND_BRANCH(TESTCOND_GT); + END_OP(); + + BEGIN_OP(JR); + ADDCLOCK(3); + RB_PCRELCHANGE(sign_26(arg1) & 0xFFFFFFFE); + if(RB_AccurateMode) + { + BRANCH_ALIGN_CHECK(PC); + } + RB_ADDBT(old_PC, RB_GETPC(), 0); + END_OP(); + + BEGIN_OP(JAL); + ADDCLOCK(3); + P_REG[31] = RB_GETPC() + 4; + RB_PCRELCHANGE(sign_26(arg1) & 0xFFFFFFFE); + if(RB_AccurateMode) + { + BRANCH_ALIGN_CHECK(PC); + } + RB_ADDBT(old_PC, RB_GETPC(), 0); + END_OP(); + + BEGIN_OP(MOVEA); + ADDCLOCK(1); + SetPREG(arg3, P_REG[arg2] + sign_16(arg1)); + END_OP(); + + BEGIN_OP(ADDI); + ADDCLOCK(1); + uint32 temp = P_REG[arg2] + sign_16(arg1); + + SetFlag(PSW_OV, ((P_REG[arg2]^(~sign_16(arg1)))&(P_REG[arg2]^temp))&0x80000000); + SetFlag(PSW_CY, (uint32)temp < P_REG[arg2]); + + SetPREG(arg3, (uint32)temp); + SetSZ(P_REG[arg3]); + END_OP(); + + BEGIN_OP(ORI); + ADDCLOCK(1); + SetPREG(arg3, arg1 | P_REG[arg2]); + SetFlag(PSW_OV, FALSE); + SetSZ(P_REG[arg3]); + END_OP(); + + BEGIN_OP(ANDI); + ADDCLOCK(1); + SetPREG(arg3, (arg1 & P_REG[arg2])); + SetFlag(PSW_OV, FALSE); + SetSZ(P_REG[arg3]); + END_OP(); + + BEGIN_OP(XORI); + ADDCLOCK(1); + SetPREG(arg3, arg1 ^ P_REG[arg2]); + SetFlag(PSW_OV, FALSE); + SetSZ(P_REG[arg3]); + END_OP(); + + BEGIN_OP(MOVHI); + ADDCLOCK(1); + SetPREG(arg3, (arg1 << 16) + P_REG[arg2]); + END_OP(); + + // LD.B + BEGIN_OP(LD_B); + ADDCLOCK(1); + tmp2 = (sign_16(arg1)+P_REG[arg2])&0xFFFFFFFF; + + SetPREG(arg3, sign_8(MemRead8(timestamp, tmp2))); + + //should be 3 clocks when executed alone, 2 when precedes another LD, or 1 + //when precedes an instruction with many clocks (I'm guessing FP, MUL, DIV, etc) + if(lastop >= 0) + { + if(lastop == LASTOP_LD) + { + ADDCLOCK(1); + } + else + { + ADDCLOCK(2); + } + } + lastop = LASTOP_LD; + END_OP_SKIPLO(); + + // LD.H + BEGIN_OP(LD_H); + ADDCLOCK(1); + tmp2 = (sign_16(arg1)+P_REG[arg2]) & 0xFFFFFFFE; + SetPREG(arg3, sign_16(MemRead16(timestamp, tmp2))); + + if(lastop >= 0) + { + if(lastop == LASTOP_LD) + { + ADDCLOCK(1); + } + else + { + ADDCLOCK(2); + } + } + lastop = LASTOP_LD; + END_OP_SKIPLO(); + + + // LD.W + BEGIN_OP(LD_W); + ADDCLOCK(1); + + tmp2 = (sign_16(arg1)+P_REG[arg2]) & 0xFFFFFFFC; + + if(MemReadBus32[tmp2 >> 24]) + { + SetPREG(arg3, MemRead32(timestamp, tmp2)); + + if(lastop >= 0) + { + if(lastop == LASTOP_LD) + { + ADDCLOCK(1); + } + else + { + ADDCLOCK(2); + } + } + } + else + { + uint32 rv; + + rv = MemRead16(timestamp, tmp2); + rv |= MemRead16(timestamp, tmp2 | 2) << 16; + + SetPREG(arg3, rv); + + if(lastop >= 0) + { + if(lastop == LASTOP_LD) + { + ADDCLOCK(3); + } + else + { + ADDCLOCK(4); + } + } + } + lastop = LASTOP_LD; + END_OP_SKIPLO(); + + // ST.B + BEGIN_OP(ST_B); + ADDCLOCK(1); + MemWrite8(timestamp, sign_16(arg2)+P_REG[arg3], P_REG[arg1] & 0xFF); + + if(lastop == LASTOP_ST) + { + ADDCLOCK(1); + } + lastop = LASTOP_ST; + END_OP_SKIPLO(); + + // ST.H + BEGIN_OP(ST_H); + ADDCLOCK(1); + + MemWrite16(timestamp, (sign_16(arg2)+P_REG[arg3])&0xFFFFFFFE, P_REG[arg1] & 0xFFFF); + + if(lastop == LASTOP_ST) + { + ADDCLOCK(1); + } + lastop = LASTOP_ST; + END_OP_SKIPLO(); + + // ST.W + BEGIN_OP(ST_W); + ADDCLOCK(1); + tmp2 = (sign_16(arg2)+P_REG[arg3]) & 0xFFFFFFFC; + + if(MemWriteBus32[tmp2 >> 24]) + { + MemWrite32(timestamp, tmp2, P_REG[arg1]); + + if(lastop == LASTOP_ST) + { + ADDCLOCK(1); + } + } + else + { + MemWrite16(timestamp, tmp2, P_REG[arg1] & 0xFFFF); + MemWrite16(timestamp, tmp2 | 2, P_REG[arg1] >> 16); + + if(lastop == LASTOP_ST) + { + ADDCLOCK(3); + } + } + lastop = LASTOP_ST; + END_OP_SKIPLO(); + + // IN.B + BEGIN_OP(IN_B); + { + ADDCLOCK(3); + SetPREG(arg3, IORead8(timestamp, sign_16(arg1)+P_REG[arg2])); + } + lastop = LASTOP_IN; + END_OP_SKIPLO(); + + + // IN.H + BEGIN_OP(IN_H); + { + ADDCLOCK(3); + SetPREG(arg3, IORead16(timestamp, (sign_16(arg1)+P_REG[arg2]) & 0xFFFFFFFE)); + } + lastop = LASTOP_IN; + END_OP_SKIPLO(); + + + // IN.W + BEGIN_OP(IN_W); + if(IORead32) + { + ADDCLOCK(3); + SetPREG(arg3, IORead32(timestamp, (sign_16(arg1)+P_REG[arg2]) & 0xFFFFFFFC)); + } + else + { + uint32 eff_addr = (sign_16(arg1) + P_REG[arg2]) & 0xFFFFFFFC; + uint32 rv; + + ADDCLOCK(5); + + rv = IORead16(timestamp, eff_addr); + rv |= IORead16(timestamp, eff_addr | 2) << 16; + + SetPREG(arg3, rv); + } + lastop = LASTOP_IN; + END_OP_SKIPLO(); + + + // OUT.B + BEGIN_OP(OUT_B); + ADDCLOCK(1); + IOWrite8(timestamp, sign_16(arg2)+P_REG[arg3],P_REG[arg1]&0xFF); + + if(lastop == LASTOP_OUT) + { + ADDCLOCK(1); + } + lastop = LASTOP_OUT; + END_OP_SKIPLO(); + + + // OUT.H + BEGIN_OP(OUT_H); + ADDCLOCK(1); + IOWrite16(timestamp, (sign_16(arg2)+P_REG[arg3])&0xFFFFFFFE,P_REG[arg1]&0xFFFF); + + if(lastop == LASTOP_OUT) + { + ADDCLOCK(1); + } + lastop = LASTOP_OUT; + END_OP_SKIPLO(); + + + // OUT.W + BEGIN_OP(OUT_W); + ADDCLOCK(1); + + if(IOWrite32) + IOWrite32(timestamp, (sign_16(arg2)+P_REG[arg3])&0xFFFFFFFC,P_REG[arg1]); + else + { + uint32 eff_addr = (sign_16(arg2)+P_REG[arg3])&0xFFFFFFFC; + IOWrite16(timestamp, eff_addr, P_REG[arg1] & 0xFFFF); + IOWrite16(timestamp, eff_addr | 2, P_REG[arg1] >> 16); + } + + if(lastop == LASTOP_OUT) + { + if(IOWrite32) + { + ADDCLOCK(1); + } + else + { + ADDCLOCK(3); + } + } + lastop = LASTOP_OUT; + END_OP_SKIPLO(); + + BEGIN_OP(NOP); + (void)arg1; // arg1 is unused. + + ADDCLOCK(1); + RB_INCPCBY2(); + END_OP(); + + BEGIN_OP(RETI); + (void)arg1; // arg1 is unused. + + ADDCLOCK(10); + + //Return from Trap/Interupt + if(S_REG[PSW] & PSW_NP) { // Read the FE Reg + RB_SETPC(S_REG[FEPC] & 0xFFFFFFFE); + S_REG[PSW] = S_REG[FEPSW]; + } else { //Read the EI Reg Interupt + RB_SETPC(S_REG[EIPC] & 0xFFFFFFFE); + S_REG[PSW] = S_REG[EIPSW]; + } + RecalcIPendingCache(); + + RB_ADDBT(old_PC, RB_GETPC(), 0); + END_OP(); + + BEGIN_OP(MUL); + ADDCLOCK(13); + + uint64 temp = (int64)(int32)P_REG[arg1] * (int32)P_REG[arg2]; + + SetPREG(30, (uint32)(temp >> 32)); + SetPREG(arg2, temp); + SetSZ(P_REG[arg2]); + SetFlag(PSW_OV, temp != (uint64)(int64)(int32)(uint32)temp); + lastop = -1; + END_OP_SKIPLO(); + + BEGIN_OP(MULU); + ADDCLOCK(13); + uint64 temp = (uint64)P_REG[arg1] * (uint64)P_REG[arg2]; + + SetPREG(30, (uint32)(temp >> 32)); + SetPREG(arg2, (uint32)temp); + + SetSZ(P_REG[arg2]); + SetFlag(PSW_OV, temp != (uint32)temp); + lastop = -1; + END_OP_SKIPLO(); + + BEGIN_OP(DIVU); + ADDCLOCK(36); + if(P_REG[arg1] == 0) // Divide by zero! + { + RB_DECPCBY2(); + Exception(ZERO_DIV_HANDLER_ADDR, ECODE_ZERO_DIV); + CHECK_HALTED(); + } + else + { + // Careful here, since arg2 can be == 30 + uint32 quotient = (uint32)P_REG[arg2] / (uint32)P_REG[arg1]; + uint32 remainder = (uint32)P_REG[arg2] % (uint32)P_REG[arg1]; + + SetPREG(30, remainder); + SetPREG(arg2, quotient); + + SetFlag(PSW_OV, FALSE); + SetSZ(quotient); + } + lastop = -1; + END_OP_SKIPLO(); + + BEGIN_OP(DIV); + //if(P_REG[arg1] & P_REG[arg2] & 0x80000000) + //{ + // printf("Div: %08x %08x\n", P_REG[arg1], P_REG[arg2]); + //} + + ADDCLOCK(38); + if((uint32)P_REG[arg1] == 0) // Divide by zero! + { + RB_DECPCBY2(); + Exception(ZERO_DIV_HANDLER_ADDR, ECODE_ZERO_DIV); + CHECK_HALTED(); + } + else + { + if((P_REG[arg2]==0x80000000)&&(P_REG[arg1]==0xFFFFFFFF)) + { + SetFlag(PSW_OV, TRUE); + P_REG[30]=0; + SetPREG(arg2, 0x80000000); + SetSZ(P_REG[arg2]); + } + else + { + // Careful here, since arg2 can be == 30 + uint32 quotient = (int32)P_REG[arg2] / (int32)P_REG[arg1]; + uint32 remainder = (int32)P_REG[arg2] % (int32)P_REG[arg1]; + + SetPREG(30, remainder); + SetPREG(arg2, quotient); + + SetFlag(PSW_OV, FALSE); + SetSZ(quotient); + } + } + lastop = -1; + END_OP_SKIPLO(); + + BEGIN_OP(FPP); + ADDCLOCK(1); + fpu_subop(timestamp, arg3, arg1, arg2); + lastop = -1; + CHECK_HALTED(); + END_OP_SKIPLO(); + + BEGIN_OP(BSTR); + if(!in_bstr) + { + ADDCLOCK(1); + } + + if(bstr_subop(timestamp, arg2, arg1)) + { + RB_DECPCBY2(); + in_bstr = TRUE; + in_bstr_to = tmpop; + } + else + { + in_bstr = FALSE; + have_src_cache = have_dst_cache = FALSE; + } + END_OP(); + + BEGIN_OP(HALT); + (void)arg1; // arg1 is unused. + + ADDCLOCK(1); + Halted = HALT_HALT; + //printf("Untested opcode: HALT\n"); + END_OP(); + + BEGIN_OP(TRAP); + (void)arg2; // arg2 is unused. + + ADDCLOCK(15); + + Exception(TRAP_HANDLER_BASE + (arg1 & 0x10), ECODE_TRAP_BASE + (arg1 & 0x1F)); + CHECK_HALTED(); + END_OP(); + + BEGIN_OP(CAXI); + //printf("Untested opcode: caxi\n"); + + // Lock bus(N/A) + + ADDCLOCK(26); + + { + uint32 addr, tmp, compare_temp; + uint32 to_write; + + addr = sign_16(arg1) + P_REG[arg2]; + addr &= ~3; + + if(MemReadBus32[addr >> 24]) + tmp = MemRead32(timestamp, addr); + else + { + tmp = MemRead16(timestamp, addr); + tmp |= MemRead16(timestamp, addr | 2) << 16; + } + + compare_temp = P_REG[arg3] - tmp; + + SetSZ(compare_temp); + SetFlag(PSW_OV, ((P_REG[arg3]^tmp)&(P_REG[arg3]^compare_temp))&0x80000000); + SetFlag(PSW_CY, compare_temp > P_REG[arg3]); + + if(!compare_temp) // If they're equal... + to_write = P_REG[30]; + else + to_write = tmp; + + if(MemWriteBus32[addr >> 24]) + MemWrite32(timestamp, addr, to_write); + else + { + MemWrite16(timestamp, addr, to_write & 0xFFFF); + MemWrite16(timestamp, addr | 2, to_write >> 16); + } + P_REG[arg3] = tmp; + } + + // Unlock bus(N/A) + + END_OP(); + + + + op_INT_HANDLER: + { + int iNum = ilevel; + + S_REG[EIPC] = GetPC(); + S_REG[EIPSW] = S_REG[PSW]; + + SetPC(0xFFFFFE00 | (iNum << 4)); + + RB_ADDBT(old_PC, RB_GETPC(), 0xFE00 | (iNum << 4)); + + S_REG[ECR] = 0xFE00 | (iNum << 4); + + S_REG[PSW] |= PSW_EP; + S_REG[PSW] |= PSW_ID; + S_REG[PSW] &= ~PSW_AE; + + // Now, set need to set the interrupt enable level to he level that is being processed + 1, + // saturating at 15. + iNum++; + + if(iNum > 0x0F) + iNum = 0x0F; + + S_REG[PSW] &= ~PSW_IA; + S_REG[PSW] |= iNum << 16; + + // Accepting an interrupt takes us out of normal HALT status, of course! + Halted = HALT_NONE; + + // Invalidate our bitstring state(forces the instruction to be re-read, and the r/w buffers reloaded). + in_bstr = FALSE; + have_src_cache = FALSE; + have_dst_cache = FALSE; + + IPendingCache = 0; + + goto OpFinished; + } + + + BEGIN_OP(INVALID); + RB_DECPCBY2(); + if(!RB_AccurateMode) + { + RB_SETPC(RB_GETPC()); + if((uint32)(RB_RDOP(0, 0) >> 9) != opcode) + { + //printf("Trampoline: %08x %02x\n", RB_GETPC(), opcode >> 1); + } + else + { + ADDCLOCK(1); + Exception(INVALID_OP_HANDLER_ADDR, ECODE_INVALID_OP); + CHECK_HALTED(); + } + } + else + { + ADDCLOCK(1); + Exception(INVALID_OP_HANDLER_ADDR, ECODE_INVALID_OP); + CHECK_HALTED(); + } + END_OP(); + + } + + OpFinished: ; + lastop = opcode; + OpFinishedSkipLO: ; + } // end while(timestamp_rl < next_event_ts) + next_event_ts = event_handler(timestamp_rl); + //printf("Next: %d, Cur: %d\n", next_event_ts, timestamp); + } + +v810_timestamp = timestamp_rl; diff --git a/waterbox/vb/v810/v810_opt.h b/waterbox/vb/v810/v810_opt.h new file mode 100644 index 0000000000..585c50b269 --- /dev/null +++ b/waterbox/vb/v810/v810_opt.h @@ -0,0 +1,170 @@ +/////////////////////////////////////////////////////////////// +// File: v810_opt.h +// +// Description: Defines used in v810_dis.cpp +// + +#ifndef V810_OPT_H_ +#define V810_OPT_H_ + +#define sign_26(num) ((uint32)sign_x_to_s32(26, num)) +#define sign_16(num) ((uint32)(int16)(num)) +#define sign_14(num) ((uint32)sign_x_to_s32(14, num)) +#define sign_12(num) ((uint32)sign_x_to_s32(12, num)) +#define sign_9(num) ((uint32)sign_x_to_s32(9, num)) +#define sign_8(_value) ((uint32)(int8)(_value)) +#define sign_5(num) ((uint32)sign_x_to_s32(5, num)) + +/////////////////////////////////////////////////////////////////// +// Define Modes +#define AM_I 0x01 +#define AM_II 0x02 +#define AM_III 0x03 +#define AM_IV 0x04 +#define AM_V 0x05 +#define AM_VIa 0x06 // Mode6 form1 +#define AM_VIb 0x0A // Mode6 form2 +#define AM_VII 0x07 +#define AM_VIII 0x08 +#define AM_IX 0x09 +#define AM_BSTR 0x0B // Bit String Instructions +#define AM_FPP 0x0C // Floating Point Instructions +#define AM_UDEF 0x0D // Unknown/Undefined Instructions + +/////////////////////////////////////////////////////////////////// +// Table of Instructions Address Modes + +static const int addr_mode[80] = { + AM_I, AM_I, AM_I, AM_I, AM_I, AM_I, AM_I, AM_I, + AM_I, AM_I, AM_I, AM_I, AM_I, AM_I, AM_I, AM_I, + AM_II, AM_II, AM_II, AM_II, AM_II, AM_II, AM_II, AM_II, + AM_II, AM_IX, AM_IX, AM_UDEF, AM_II, AM_II, AM_II, AM_BSTR, + AM_UDEF, AM_UDEF, AM_UDEF, AM_UDEF, AM_UDEF, AM_UDEF, AM_UDEF, AM_UDEF, + AM_V, AM_V, AM_IV, AM_IV, AM_V, AM_V, AM_V, AM_V, + AM_VIa, AM_VIa, AM_UDEF, AM_VIa, AM_VIb, AM_VIb, AM_UDEF, AM_VIb, + AM_VIa, AM_VIa, AM_VIa, AM_VIa, AM_VIb, AM_VIb, AM_FPP, AM_VIb, + AM_III, AM_III, AM_III, AM_III, AM_III, AM_III, AM_III, AM_III, + AM_III, AM_III, AM_III, AM_III, AM_III, AM_III, AM_III, AM_III +}; +// All instructions greater than 0x50 are undefined (this should not be posible of cource) + + +/////////////////////////////////////////////////////////////////// +// Opcodes for V810 Instruction set +#define MOV 0x00 +#define ADD 0x01 +#define SUB 0x02 +#define CMP 0x03 +#define SHL 0x04 +#define SHR 0x05 +#define JMP 0x06 +#define SAR 0x07 +#define MUL 0x08 +#define DIV 0x09 +#define MULU 0x0A +#define DIVU 0x0B +#define OR 0x0C +#define AND 0x0D +#define XOR 0x0E +#define NOT 0x0F +#define MOV_I 0x10 +#define ADD_I 0x11 +#define SETF 0x12 +#define CMP_I 0x13 +#define SHL_I 0x14 +#define SHR_I 0x15 +#define EI 0x16 +#define SAR_I 0x17 +#define TRAP 0x18 +#define RETI 0x19 +#define HALT 0x1A + //0x1B +#define LDSR 0x1C +#define STSR 0x1D +#define DI 0x1E +#define BSTR 0x1F //Special Bit String Inst + //0x20 - 0x27 // Lost to Branch Instructions +#define MOVEA 0x28 +#define ADDI 0x29 +#define JR 0x2A +#define JAL 0x2B +#define ORI 0x2C +#define ANDI 0x2D +#define XORI 0x2E +#define MOVHI 0x2F +#define LD_B 0x30 +#define LD_H 0x31 + //0x32 +#define LD_W 0x33 +#define ST_B 0x34 +#define ST_H 0x35 + //0x36 +#define ST_W 0x37 +#define IN_B 0x38 +#define IN_H 0x39 +#define CAXI 0x3A +#define IN_W 0x3B +#define OUT_B 0x3C +#define OUT_H 0x3D +#define FPP 0x3E //Special Float Inst +#define OUT_W 0x3F + + +// Branch Instructions ( Extended opcode only for Branch command) +// Common instrcutions commented out + +#define BV 0x40 +#define BL 0x41 +#define BE 0x42 +#define BNH 0x43 +#define BN 0x44 +#define BR 0x45 +#define BLT 0x46 +#define BLE 0x47 +#define BNV 0x48 +#define BNL 0x49 +#define BNE 0x4A +#define BH 0x4B +#define BP 0x4C +#define NOP 0x4D +#define BGE 0x4E +#define BGT 0x4F + +//#define BC 0x41 +//#define BZ 0x42 +//#define BNC 0x49 +//#define BNZ 0x4A + +// Bit String Subopcodes +#define SCH0BSU 0x00 +#define SCH0BSD 0x01 +#define SCH1BSU 0x02 +#define SCH1BSD 0x03 + +#define ORBSU 0x08 +#define ANDBSU 0x09 +#define XORBSU 0x0A +#define MOVBSU 0x0B +#define ORNBSU 0x0C +#define ANDNBSU 0x0D +#define XORNBSU 0x0E +#define NOTBSU 0x0F + + +// Floating Point Subopcodes +#define CMPF_S 0x00 + +#define CVT_WS 0x02 +#define CVT_SW 0x03 +#define ADDF_S 0x04 +#define SUBF_S 0x05 +#define MULF_S 0x06 +#define DIVF_S 0x07 +#define XB 0x08 +#define XH 0x09 +#define REV 0x0A +#define TRNC_SW 0x0B +#define MPYHW 0x0C + +#endif //DEFINE_H + diff --git a/waterbox/vb/vb.cpp b/waterbox/vb/vb.cpp new file mode 100644 index 0000000000..82aec1e0fa --- /dev/null +++ b/waterbox/vb/vb.cpp @@ -0,0 +1,795 @@ +/******************************************************************************/ +/* Mednafen Virtual Boy Emulation Module */ +/******************************************************************************/ +/* vb.cpp: +** Copyright (C) 2010-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "vb.h" +#include "../emulibc/emulibc.h" +#include "../emulibc/waterboxcore.h" +#define EXPORT extern "C" ECL_EXPORT + +namespace MDFN_IEN_VB +{ +struct NativeSettings +{ + int InstantReadHack; + int DisableParallax; + int ThreeDeeMode; + int SwapViews; + int AnaglyphPreset; + int AnaglyphCustomLeftColor; + int AnaglyphCustomRightColor; + int NonAnaglyphColor; + int LedOnScale; + int InterlacePrescale; + int SideBySideSeparation; +}; + +static void (*input_callback)(); +static bool lagged; + +enum +{ + ANAGLYPH_PRESET_DISABLED = 0, + ANAGLYPH_PRESET_RED_BLUE, + ANAGLYPH_PRESET_RED_CYAN, + ANAGLYPH_PRESET_RED_ELECTRICCYAN, + ANAGLYPH_PRESET_RED_GREEN, + ANAGLYPH_PRESET_GREEN_MAGENTA, + ANAGLYPH_PRESET_YELLOW_BLUE, +}; + +static const uint32 AnaglyphPreset_Colors[][2] = +{ + {0, 0}, + {0xFF0000, 0x0000FF}, + {0xFF0000, 0x00B7EB}, + {0xFF0000, 0x00FFFF}, + {0xFF0000, 0x00FF00}, + {0x00FF00, 0xFF00FF}, + {0xFFFF00, 0x0000FF}, +}; + +static uint32 VB3DMode; + +static uint8 *WRAM = NULL; + +static uint8 *GPRAM = NULL; +static const uint32 GPRAM_Mask = 0xFFFF; + +static uint8 *GPROM = NULL; +static uint32 GPROM_Mask; + +V810 *VB_V810 = NULL; + +VSU *VB_VSU = NULL; +static uint32 VSU_CycleFix; + +static uint8 WCR; + +static int32 next_vip_ts, next_timer_ts, next_input_ts; + +static uint32 IRQ_Asserted; + +static INLINE void RecalcIntLevel(void) +{ + int ilevel = -1; + + for (int i = 4; i >= 0; i--) + { + if (IRQ_Asserted & (1 << i)) + { + ilevel = i; + break; + } + } + + VB_V810->SetInt(ilevel); +} + +void VBIRQ_Assert(int source, bool assert) +{ + assert(source >= 0 && source <= 4); + + IRQ_Asserted &= ~(1 << source); + + if (assert) + IRQ_Asserted |= 1 << source; + + RecalcIntLevel(); +} + +static MDFN_FASTCALL uint8 HWCTRL_Read(v810_timestamp_t ×tamp, uint32 A) +{ + uint8 ret = 0; + + if (A & 0x3) + { + //puts("HWCtrl Bogus Read?"); + return (ret); + } + + switch (A & 0xFF) + { + default: //printf("Unknown HWCTRL Read: %08x\n", A); + break; + + case 0x18: + case 0x1C: + case 0x20: + ret = TIMER_Read(timestamp, A); + break; + + case 0x24: + ret = WCR | 0xFC; + break; + + case 0x10: + case 0x14: + case 0x28: + lagged = false; + if (input_callback) + input_callback(); + ret = VBINPUT_Read(timestamp, A); + break; + } + + return (ret); +} + +static MDFN_FASTCALL void HWCTRL_Write(v810_timestamp_t ×tamp, uint32 A, uint8 V) +{ + if (A & 0x3) + { + puts("HWCtrl Bogus Write?"); + return; + } + + switch (A & 0xFF) + { + default: //printf("Unknown HWCTRL Write: %08x %02x\n", A, V); + break; + + case 0x18: + case 0x1C: + case 0x20: + TIMER_Write(timestamp, A, V); + break; + + case 0x24: + WCR = V & 0x3; + break; + + case 0x10: + case 0x14: + case 0x28: + VBINPUT_Write(timestamp, A, V); + break; + } +} + +uint8 MDFN_FASTCALL MemRead8(v810_timestamp_t ×tamp, uint32 A) +{ + uint8 ret = 0; + A &= (1 << 27) - 1; + + //if((A >> 24) <= 2) + // printf("Read8: %d %08x\n", timestamp, A); + + switch (A >> 24) + { + case 0: + ret = VIP_Read8(timestamp, A); + break; + + case 1: + break; + + case 2: + ret = HWCTRL_Read(timestamp, A); + break; + + case 3: + break; + case 4: + break; + + case 5: + ret = WRAM[A & 0xFFFF]; + break; + + case 6: + if (GPRAM) + ret = GPRAM[A & GPRAM_Mask]; + break; + + case 7: + ret = GPROM[A & GPROM_Mask]; + break; + } + return (ret); +} + +uint16 MDFN_FASTCALL MemRead16(v810_timestamp_t ×tamp, uint32 A) +{ + uint16 ret = 0; + + A &= (1 << 27) - 1; + + //if((A >> 24) <= 2) + // printf("Read16: %d %08x\n", timestamp, A); + + switch (A >> 24) + { + case 0: + ret = VIP_Read16(timestamp, A); + break; + + case 1: + break; + + case 2: + ret = HWCTRL_Read(timestamp, A); + break; + + case 3: + break; + + case 4: + break; + + case 5: + ret = MDFN_de16lsb(&WRAM[A & 0xFFFF]); + break; + + case 6: + if (GPRAM) + ret = MDFN_de16lsb(&GPRAM[A & GPRAM_Mask]); + break; + + case 7: + ret = MDFN_de16lsb(&GPROM[A & GPROM_Mask]); + break; + } + return ret; +} + +void MDFN_FASTCALL MemWrite8(v810_timestamp_t ×tamp, uint32 A, uint8 V) +{ + A &= (1 << 27) - 1; + + //if((A >> 24) <= 2) + // printf("Write8: %d %08x %02x\n", timestamp, A, V); + + switch (A >> 24) + { + case 0: + VIP_Write8(timestamp, A, V); + break; + + case 1: + VB_VSU->Write((timestamp + VSU_CycleFix) >> 2, A, V); + break; + + case 2: + HWCTRL_Write(timestamp, A, V); + break; + + case 3: + break; + + case 4: + break; + + case 5: + WRAM[A & 0xFFFF] = V; + break; + + case 6: + if (GPRAM) + GPRAM[A & GPRAM_Mask] = V; + break; + + case 7: // ROM, no writing allowed! + break; + } +} + +void MDFN_FASTCALL MemWrite16(v810_timestamp_t ×tamp, uint32 A, uint16 V) +{ + A &= (1 << 27) - 1; + + //if((A >> 24) <= 2) + // printf("Write16: %d %08x %04x\n", timestamp, A, V); + + switch (A >> 24) + { + case 0: + VIP_Write16(timestamp, A, V); + break; + + case 1: + VB_VSU->Write((timestamp + VSU_CycleFix) >> 2, A, V); + break; + + case 2: + HWCTRL_Write(timestamp, A, V); + break; + + case 3: + break; + + case 4: + break; + + case 5: + MDFN_en16lsb(&WRAM[A & 0xFFFF], V); + break; + + case 6: + if (GPRAM) + MDFN_en16lsb(&GPRAM[A & GPRAM_Mask], V); + break; + + case 7: // ROM, no writing allowed! + break; + } +} + +static void FixNonEvents(void) +{ + if (next_vip_ts & 0x40000000) + next_vip_ts = VB_EVENT_NONONO; + + if (next_timer_ts & 0x40000000) + next_timer_ts = VB_EVENT_NONONO; + + if (next_input_ts & 0x40000000) + next_input_ts = VB_EVENT_NONONO; +} + +static void EventReset(void) +{ + next_vip_ts = VB_EVENT_NONONO; + next_timer_ts = VB_EVENT_NONONO; + next_input_ts = VB_EVENT_NONONO; +} + +static INLINE int32 CalcNextTS(void) +{ + int32 next_timestamp = next_vip_ts; + + if (next_timestamp > next_timer_ts) + next_timestamp = next_timer_ts; + + if (next_timestamp > next_input_ts) + next_timestamp = next_input_ts; + + return (next_timestamp); +} + +static void RebaseTS(const v810_timestamp_t timestamp) +{ + //printf("Rebase: %08x %08x %08x\n", timestamp, next_vip_ts, next_timer_ts); + + assert(next_vip_ts > timestamp); + assert(next_timer_ts > timestamp); + assert(next_input_ts > timestamp); + + next_vip_ts -= timestamp; + next_timer_ts -= timestamp; + next_input_ts -= timestamp; +} + +void VB_SetEvent(const int type, const v810_timestamp_t next_timestamp) +{ + //assert(next_timestamp > VB_V810->v810_timestamp); + + if (type == VB_EVENT_VIP) + next_vip_ts = next_timestamp; + else if (type == VB_EVENT_TIMER) + next_timer_ts = next_timestamp; + else if (type == VB_EVENT_INPUT) + next_input_ts = next_timestamp; + + if (next_timestamp < VB_V810->GetEventNT()) + VB_V810->SetEventNT(next_timestamp); +} + +static int32 MDFN_FASTCALL EventHandler(const v810_timestamp_t timestamp) +{ + if (timestamp >= next_vip_ts) + next_vip_ts = VIP_Update(timestamp); + + if (timestamp >= next_timer_ts) + next_timer_ts = TIMER_Update(timestamp); + + if (timestamp >= next_input_ts) + next_input_ts = VBINPUT_Update(timestamp); + + return (CalcNextTS()); +} + +// Called externally from debug.cpp in some cases. +void ForceEventUpdates(const v810_timestamp_t timestamp) +{ + next_vip_ts = VIP_Update(timestamp); + next_timer_ts = TIMER_Update(timestamp); + next_input_ts = VBINPUT_Update(timestamp); + + VB_V810->SetEventNT(CalcNextTS()); + //printf("FEU: %d %d %d\n", next_vip_ts, next_timer_ts, next_input_ts); +} + +static void VB_Power(void) +{ + memset(WRAM, 0, 65536); + + VIP_Power(); + VB_VSU->Power(); + TIMER_Power(); + VBINPUT_Power(); + + EventReset(); + IRQ_Asserted = 0; + RecalcIntLevel(); + VB_V810->Reset(); + + VSU_CycleFix = 0; + WCR = 0; + + ForceEventUpdates(0); //VB_V810->v810_timestamp); +} + +/*struct VB_HeaderInfo +{ + char game_title[256]; + uint32 game_code; + uint16 manf_code; + uint8 version; +};*/ + +/*static void ReadHeader(const uint8 *const rom_data, const uint64 rom_size, VB_HeaderInfo *hi) +{ + iconv_t sjis_ict = iconv_open("UTF-8", "shift_jis"); + + if (sjis_ict != (iconv_t)-1) + { + char *in_ptr, *out_ptr; + size_t ibl, obl; + + ibl = 20; + obl = sizeof(hi->game_title) - 1; + + in_ptr = (char *)rom_data + (0xFFFFFDE0 & (rom_size - 1)); + out_ptr = hi->game_title; + + iconv(sjis_ict, (ICONV_CONST char **)&in_ptr, &ibl, &out_ptr, &obl); + iconv_close(sjis_ict); + + *out_ptr = 0; + + MDFN_zapctrlchars(hi->game_title); + MDFN_trim(hi->game_title); + } + else + hi->game_title[0] = 0; + + hi->game_code = MDFN_de32lsb(rom_data + (0xFFFFFDFB & (rom_size - 1))); + hi->manf_code = MDFN_de16lsb(rom_data + (0xFFFFFDF9 & (rom_size - 1))); + hi->version = rom_data[0xFFFFFDFF & (rom_size - 1)]; +}*/ + +void VB_ExitLoop(void) +{ + VB_V810->Exit(); +} + + +/*MDFNGI EmulatedVB = + { + + PortInfo, + Load, + TestMagic, + NULL, + NULL, + CloseGame, + + SetLayerEnableMask, + NULL, // Layer names, null-delimited + + NULL, + NULL, + + VIP_CPInfo, + 1 << 0, + + CheatInfo_Empty, + + false, + StateAction, + Emulate, + NULL, + VBINPUT_SetInput, + NULL, + DoSimpleCommand, + NULL, + VBSettings, + MDFN_MASTERCLOCK_FIXED(VB_MASTER_CLOCK), + 0, + false, // Multires possible? + + 0, // lcm_width + 0, // lcm_height + NULL, // Dummy + + 384, // Nominal width + 224, // Nominal height + + 384, // Framebuffer width + 256, // Framebuffer height + + 2, // Number of output sound channels +};*/ +} + +using namespace MDFN_IEN_VB; + +EXPORT int Load(const uint8 *rom, int length, const NativeSettings* settings) +{ + const uint64 rom_size = length; + V810_Emu_Mode cpu_mode = V810_EMU_MODE_ACCURATE; + + if (rom_size != round_up_pow2(rom_size)) + { + return 0; + // throw MDFN_Error(0, _("VB ROM image size is not a power of 2.")); + } + + if (rom_size < 256) + { + return 0; + //throw MDFN_Error(0, _("VB ROM image size is too small.")); + } + + if (rom_size > (1 << 24)) + { + return 0; + //throw MDFN_Error(0, _("VB ROM image size is too large.")); + } + + VB_V810 = new V810(); + VB_V810->Init(cpu_mode, true); + + VB_V810->SetMemReadHandlers(MemRead8, MemRead16, NULL); + VB_V810->SetMemWriteHandlers(MemWrite8, MemWrite16, NULL); + + VB_V810->SetIOReadHandlers(MemRead8, MemRead16, NULL); + VB_V810->SetIOWriteHandlers(MemWrite8, MemWrite16, NULL); + + for (int i = 0; i < 256; i++) + { + VB_V810->SetMemReadBus32(i, false); + VB_V810->SetMemWriteBus32(i, false); + } + + std::vector Map_Addresses; + + for (uint64 A = 0; A < 1ULL << 32; A += (1 << 27)) + { + for (uint64 sub_A = 5 << 24; sub_A < (6 << 24); sub_A += 65536) + { + Map_Addresses.push_back(A + sub_A); + } + } + + WRAM = VB_V810->SetFastMap(alloc_plain, &Map_Addresses[0], 65536, Map_Addresses.size(), "WRAM"); + Map_Addresses.clear(); + + // Round up the ROM size to 65536(we mirror it a little later) + GPROM_Mask = (rom_size < 65536) ? (65536 - 1) : (rom_size - 1); + + for (uint64 A = 0; A < 1ULL << 32; A += (1 << 27)) + { + for (uint64 sub_A = 7 << 24; sub_A < (8 << 24); sub_A += GPROM_Mask + 1) + { + Map_Addresses.push_back(A + sub_A); + //printf("%08x\n", (uint32)(A + sub_A)); + } + } + + GPROM = VB_V810->SetFastMap(alloc_sealed, &Map_Addresses[0], GPROM_Mask + 1, Map_Addresses.size(), "Cart ROM"); + Map_Addresses.clear(); + + memcpy(GPROM, rom, rom_size); + + // Mirror ROM images < 64KiB to 64KiB + for (uint64 i = rom_size; i < 65536; i += rom_size) + { + memcpy(GPROM + i, GPROM, rom_size); + } + + /*VB_HeaderInfo hinfo; + + ReadHeader(GPROM, rom_size, &hinfo); + + MDFN_printf(_("Title: %s\n"), hinfo.game_title); + MDFN_printf(_("Game ID Code: %u\n"), hinfo.game_code); + MDFN_printf(_("Manufacturer Code: %d\n"), hinfo.manf_code); + MDFN_printf(_("Version: %u\n"), hinfo.version); + + MDFN_printf(_("ROM: %uKiB\n"), (unsigned)(rom_size / 1024)); + MDFN_printf(_("ROM MD5: 0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str());*/ + + /*MDFN_printf("\n"); + + MDFN_printf(_("V810 Emulation Mode: %s\n"), (cpu_mode == V810_EMU_MODE_ACCURATE) ? _("Accurate") : _("Fast"));*/ + + for (uint64 A = 0; A < 1ULL << 32; A += (1 << 27)) + { + for (uint64 sub_A = 6 << 24; sub_A < (7 << 24); sub_A += GPRAM_Mask + 1) + { + //printf("GPRAM: %08x\n", A + sub_A); + Map_Addresses.push_back(A + sub_A); + } + } + + GPRAM = VB_V810->SetFastMap(alloc_plain, &Map_Addresses[0], GPRAM_Mask + 1, Map_Addresses.size(), "Cart RAM"); + Map_Addresses.clear(); + + memset(GPRAM, 0, GPRAM_Mask + 1); + + VIP_Init(); + VB_VSU = new VSU(); + VBINPUT_Init(); + + VB3DMode = settings->ThreeDeeMode; + uint32 prescale = settings->InterlacePrescale; + uint32 sbs_separation = settings->SideBySideSeparation; + bool reverse = settings->SwapViews; + + VIP_Set3DMode(VB3DMode, reverse, prescale, sbs_separation); + + VIP_SetParallaxDisable(settings->DisableParallax); + + { + auto presetColor = settings->AnaglyphPreset; + + uint32 lcolor = settings->AnaglyphCustomLeftColor; + uint32 rcolor = settings->AnaglyphCustomRightColor; + + if (presetColor != ANAGLYPH_PRESET_DISABLED) + { + lcolor = AnaglyphPreset_Colors[presetColor][0]; + rcolor = AnaglyphPreset_Colors[presetColor][1]; + } + VIP_SetAnaglyphColors(lcolor, rcolor); + VIP_SetDefaultColor(settings->NonAnaglyphColor); + } + + VBINPUT_SetInstantReadHack(settings->InstantReadHack); + + VIP_SetLEDOnScale(settings->LedOnScale / 1000.0); + + VB_Power(); + + /*switch (VB3DMode) + { + default: + break; + + case VB3DMODE_VLI: + MDFNGameInfo->nominal_width = 768 * prescale; + MDFNGameInfo->nominal_height = 224; + MDFNGameInfo->fb_width = 768 * prescale; + MDFNGameInfo->fb_height = 224; + break; + + case VB3DMODE_HLI: + MDFNGameInfo->nominal_width = 384; + MDFNGameInfo->nominal_height = 448 * prescale; + MDFNGameInfo->fb_width = 384; + MDFNGameInfo->fb_height = 448 * prescale; + break; + + case VB3DMODE_CSCOPE: + MDFNGameInfo->nominal_width = 512; + MDFNGameInfo->nominal_height = 384; + MDFNGameInfo->fb_width = 512; + MDFNGameInfo->fb_height = 384; + break; + + case VB3DMODE_SIDEBYSIDE: + MDFNGameInfo->nominal_width = 384 * 2 + sbs_separation; + MDFNGameInfo->nominal_height = 224; + MDFNGameInfo->fb_width = 384 * 2 + sbs_separation; + MDFNGameInfo->fb_height = 224; + break; + } + MDFNGameInfo->lcm_width = MDFNGameInfo->fb_width; + MDFNGameInfo->lcm_height = MDFNGameInfo->fb_height;*/ + + VB_VSU->SetSoundRate(44100); + + return 1; +} + +EXPORT void GetMemoryAreas(MemoryArea* m) +{ + m[0].Data = WRAM; + m[0].Name = "WRAM"; + m[0].Size = 65536; + m[0].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_PRIMARY | MEMORYAREA_FLAGS_WORDSIZE4; + + m[1].Data = GPRAM; + m[1].Name = "CARTRAM"; + m[1].Size = GPRAM_Mask + 1; + m[1].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_SAVERAMMABLE | MEMORYAREA_FLAGS_WORDSIZE4; + + m[2].Data = GPROM; + m[2].Name = "ROM"; + m[2].Size = GPROM_Mask + 1; + m[2].Flags = MEMORYAREA_FLAGS_WORDSIZE4; +} + +EXPORT void FrameAdvance(MyFrameInfo* frame) +{ + v810_timestamp_t v810_timestamp; + lagged = true; + + VBINPUT_Frame(&frame->Buttons); + + VIP_StartFrame(frame); + + v810_timestamp = VB_V810->Run(EventHandler); + + FixNonEvents(); + ForceEventUpdates(v810_timestamp); + + frame->Samples = VB_VSU->EndFrame((v810_timestamp + VSU_CycleFix) >> 2, frame->SoundBuffer, 8192); + + VSU_CycleFix = (v810_timestamp + VSU_CycleFix) & 3; + + frame->Cycles = v810_timestamp; + frame->Lagged = lagged; + + TIMER_ResetTS(); + VBINPUT_ResetTS(); + VIP_ResetTS(); + + RebaseTS(v810_timestamp); + + VB_V810->ResetTS(0); +} + +EXPORT void HardReset() +{ + VB_Power(); +} + +EXPORT void SetInputCallback(void (*callback)()) +{ + input_callback = callback; +} + +int main() +{ + return 0; +} diff --git a/waterbox/vb/vb.h b/waterbox/vb/vb.h new file mode 100644 index 0000000000..8ca976ddaf --- /dev/null +++ b/waterbox/vb/vb.h @@ -0,0 +1,124 @@ +/******************************************************************************/ +/* Mednafen Virtual Boy Emulation Module */ +/******************************************************************************/ +/* vb.h: +** Copyright (C) 2010-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +typedef uint64_t uint64; +typedef int8_t int8; +typedef int16_t int16; +typedef int32_t int32; +typedef int64_t int64; + +#define MDFN_FASTCALL +#define INLINE inline +#define MDFN_COLD +#define NO_INLINE +//#define MDFN_ASSUME_ALIGNED(p, align) ((decltype(p))__builtin_assume_aligned((p), (align))) +#define MDFN_ASSUME_ALIGNED(p, align) (p) +#define trio_snprintf snprintf +#define TRUE true +#define FALSE false +#ifndef __alignas_is_defined +#define alignas(p) +#endif + +struct MyFrameInfo +{ + uint32_t* VideoBuffer; + int16_t* SoundBuffer; + int64_t Cycles; + int32_t Width; + int32_t Height; + int32_t Samples; + int32_t Lagged; + int32_t Buttons; +}; + +#include "endian.h" +#include "math_ops.h" +#include "blip/Blip_Buffer.h" +#include "v810/v810_fp_ops.h" +#include "v810/v810_cpu.h" + +#include "git.h" + +#include "vsu.h" +#include "vip.h" +#include "timer.h" +#include "input.h" + + +namespace MDFN_IEN_VB +{ + +enum +{ + VB3DMODE_ANAGLYPH = 0, + VB3DMODE_CSCOPE = 1, + VB3DMODE_SIDEBYSIDE = 2, + VB3DMODE_OVERUNDER = 3, + VB3DMODE_VLI, + VB3DMODE_HLI +}; + +#define VB_MASTER_CLOCK 20000000.0 + +enum +{ + VB_EVENT_VIP = 0, + VB_EVENT_TIMER, + VB_EVENT_INPUT, + // VB_EVENT_COMM +}; + +#define VB_EVENT_NONONO 0x7fffffff + +void VB_SetEvent(const int type, const v810_timestamp_t next_timestamp); + +#define VBIRQ_SOURCE_INPUT 0 +#define VBIRQ_SOURCE_TIMER 1 +#define VBIRQ_SOURCE_EXPANSION 2 +#define VBIRQ_SOURCE_COMM 3 +#define VBIRQ_SOURCE_VIP 4 + +void VBIRQ_Assert(int source, bool assert); + +void VB_ExitLoop(void); + +void ForceEventUpdates(const v810_timestamp_t timestamp); + +uint8 MDFN_FASTCALL MemRead8(v810_timestamp_t ×tamp, uint32 A); +uint16 MDFN_FASTCALL MemRead16(v810_timestamp_t ×tamp, uint32 A); + +void MDFN_FASTCALL MemWrite8(v810_timestamp_t ×tamp, uint32 A, uint8 V); +void MDFN_FASTCALL MemWrite16(v810_timestamp_t ×tamp, uint32 A, uint16 V); +} diff --git a/waterbox/vb/vip.cpp b/waterbox/vb/vip.cpp new file mode 100644 index 0000000000..4c31a29b2a --- /dev/null +++ b/waterbox/vb/vip.cpp @@ -0,0 +1,1392 @@ +/******************************************************************************/ +/* Mednafen Virtual Boy Emulation Module */ +/******************************************************************************/ +/* vip.cpp: +** Copyright (C) 2010-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "vb.h" +#include + +#define VIP_DBGMSG(format, ...) \ + { \ + } +//#define VIP_DBGMSG(format, ...) printf(format "\n", ## __VA_ARGS__) + +namespace MDFN_IEN_VB +{ + +static uint8 FB[2][2][0x6000]; +static uint16 CHR_RAM[0x8000 / sizeof(uint16)]; +static uint16 DRAM[0x20000 / sizeof(uint16)]; + +#define INT_SCAN_ERR 0x0001 +#define INT_LFB_END 0x0002 +#define INT_RFB_END 0x0004 +#define INT_GAME_START 0x0008 +#define INT_FRAME_START 0x0010 + +#define INT_SB_HIT 0x2000 +#define INT_XP_END 0x4000 +#define INT_TIME_ERR 0x8000 + +static uint16 InterruptPending; +static uint16 InterruptEnable; + +static uint8 BRTA, BRTB, BRTC, REST; +static uint8 Repeat; + +static void CopyFBColumnToTarget_Anaglyph(void) NO_INLINE; +static void CopyFBColumnToTarget_AnaglyphSlow(void) NO_INLINE; +static void CopyFBColumnToTarget_CScope(void) NO_INLINE; +static void CopyFBColumnToTarget_SideBySide(void) NO_INLINE; +static void CopyFBColumnToTarget_VLI(void) NO_INLINE; +static void CopyFBColumnToTarget_HLI(void) NO_INLINE; +static void (*CopyFBColumnToTarget)(void) = NULL; +static float VBLEDOnScale; +static uint32 VB3DMode; +static uint32 VB3DReverse; +static uint32 VBPrescale; +static uint32 VBSBS_Separation; +static uint32 HLILUT[256]; +static uint32 ColorLUT[2][256]; +static int32 BrightnessCache[4]; +static uint32 BrightCLUT[2][4]; + +static float ColorLUTNoGC[2][256][3]; +static uint32 AnaSlowColorLUT[256][256]; + +static bool VidSettingsDirty; +static bool ParallaxDisabled; +static uint32 Anaglyph_Colors[2]; +static uint32 Default_Color; + +static void MakeColorLUT() +{ + for (int lr = 0; lr < 2; lr++) + { + for (int i = 0; i < 256; i++) + { + float r, g, b; + uint32 modcolor_prime; + + if (VB3DMode == VB3DMODE_ANAGLYPH) + modcolor_prime = Anaglyph_Colors[lr ^ VB3DReverse]; + else + modcolor_prime = Default_Color; + + r = g = b = std::min(1.0, i * VBLEDOnScale / 255.0); + + // Modulate. + r = r * pow(((modcolor_prime >> 16) & 0xFF) / 255.0, 2.2 / 1.0); + g = g * pow(((modcolor_prime >> 8) & 0xFF) / 255.0, 2.2 / 1.0); + b = b * pow(((modcolor_prime >> 0) & 0xFF) / 255.0, 2.2 / 1.0); + + ColorLUTNoGC[lr][i][0] = r; + ColorLUTNoGC[lr][i][1] = g; + ColorLUTNoGC[lr][i][2] = b; + + // Apply gamma correction + const float r_prime = pow(r, 1.0 / 2.2); + const float g_prime = pow(g, 1.0 / 2.2); + const float b_prime = pow(b, 1.0 / 2.2); + + ColorLUT[lr][i] = (int)(b_prime * 255) & 0xff | (int)(g_prime * 255) << 8 & 0xff00 | (int)(r_prime * 255) << 16 & 0xff0000 | 0xff000000; + } + } + + // Anaglyph slow-mode LUT calculation + for (int l_b = 0; l_b < 256; l_b++) + { + for (int r_b = 0; r_b < 256; r_b++) + { + float r, g, b; + float r_prime, g_prime, b_prime; + + r = ColorLUTNoGC[0][l_b][0] + ColorLUTNoGC[1][r_b][0]; + g = ColorLUTNoGC[0][l_b][1] + ColorLUTNoGC[1][r_b][1]; + b = ColorLUTNoGC[0][l_b][2] + ColorLUTNoGC[1][r_b][2]; + + if (r > 1.0) + r = 1.0; + if (g > 1.0) + g = 1.0; + if (b > 1.0) + b = 1.0; + + r_prime = pow(r, 1.0 / 2.2); + g_prime = pow(g, 1.0 / 2.2); + b_prime = pow(b, 1.0 / 2.2); + + AnaSlowColorLUT[l_b][r_b] = (int)(b_prime * 255) & 0xff | (int)(g_prime * 255) << 8 & 0xff00 | (int)(r_prime * 255) << 16 & 0xff0000 | 0xff000000; + } + } +} + +static void RecalcBrightnessCache(void) +{ + static const int32 MaxTime = 255; + int32 CumulativeTime = (BRTA + 1 + BRTB + 1 + BRTC + 1 + REST + 1) + 1; + + //printf("BRTA: %d, BRTB: %d, BRTC: %d, Rest: %d --- %d\n", BRTA, BRTB, BRTC, REST, BRTA + 1 + BRTB + 1 + BRTC); + + BrightnessCache[0] = 0; + BrightnessCache[1] = 0; + BrightnessCache[2] = 0; + BrightnessCache[3] = 0; + + for (int i = 0; i < Repeat + 1; i++) + { + int32 btemp[4]; + + if ((i * CumulativeTime) >= MaxTime) + break; + + btemp[1] = (i * CumulativeTime) + BRTA; + if (btemp[1] > MaxTime) + btemp[1] = MaxTime; + btemp[1] -= (i * CumulativeTime); + if (btemp[1] < 0) + btemp[1] = 0; + + btemp[2] = (i * CumulativeTime) + BRTA + 1 + BRTB; + if (btemp[2] > MaxTime) + btemp[2] = MaxTime; + btemp[2] -= (i * CumulativeTime) + BRTA + 1; + if (btemp[2] < 0) + btemp[2] = 0; + + //btemp[3] = (i * CumulativeTime) + BRTA + 1 + BRTB + 1 + BRTC; + //if(btemp[3] > MaxTime) + // btemp[3] = MaxTime; + //btemp[3] -= (i * CumulativeTime); + //if(btemp[3] < 0) + // btemp[3] = 0; + + btemp[3] = (i * CumulativeTime) + BRTA + BRTB + BRTC + 1; + if (btemp[3] > MaxTime) + btemp[3] = MaxTime; + btemp[3] -= (i * CumulativeTime) + 1; + if (btemp[3] < 0) + btemp[3] = 0; + + BrightnessCache[1] += btemp[1]; + BrightnessCache[2] += btemp[2]; + BrightnessCache[3] += btemp[3]; + } + + //printf("BC: %d %d %d %d\n", BrightnessCache[0], BrightnessCache[1], BrightnessCache[2], BrightnessCache[3]); + + for (int lr = 0; lr < 2; lr++) + for (int i = 0; i < 4; i++) + { + BrightCLUT[lr][i] = ColorLUT[lr][BrightnessCache[i]]; + //printf("%d %d, %08x\n", lr, i, BrightCLUT[lr][i]); + } +} + +static void Recalc3DModeStuff(bool non_rgb_output = false) +{ + switch (VB3DMode) + { + default: + if (((Anaglyph_Colors[0] & 0xFF) && (Anaglyph_Colors[1] & 0xFF)) || + ((Anaglyph_Colors[0] & 0xFF00) && (Anaglyph_Colors[1] & 0xFF00)) || + ((Anaglyph_Colors[0] & 0xFF0000) && (Anaglyph_Colors[1] & 0xFF0000)) || + non_rgb_output) + { + CopyFBColumnToTarget = CopyFBColumnToTarget_AnaglyphSlow; + } + else + CopyFBColumnToTarget = CopyFBColumnToTarget_Anaglyph; + break; + + case VB3DMODE_CSCOPE: + CopyFBColumnToTarget = CopyFBColumnToTarget_CScope; + break; + + case VB3DMODE_SIDEBYSIDE: + CopyFBColumnToTarget = CopyFBColumnToTarget_SideBySide; + break; + + case VB3DMODE_VLI: + CopyFBColumnToTarget = CopyFBColumnToTarget_VLI; + break; + + case VB3DMODE_HLI: + CopyFBColumnToTarget = CopyFBColumnToTarget_HLI; + break; + } + RecalcBrightnessCache(); +} + +void VIP_Set3DMode(uint32 mode, bool reverse, uint32 prescale, uint32 sbs_separation) +{ + VB3DMode = mode; + VB3DReverse = reverse ? 1 : 0; + VBPrescale = prescale; + VBSBS_Separation = sbs_separation; + + VidSettingsDirty = true; + + for (uint32 p = 0; p < 256; p++) + { + uint32 v; + uint8 s[4]; + + s[0] = (p >> 0) & 0x3; + s[1] = (p >> 2) & 0x3; + s[2] = (p >> 4) & 0x3; + s[3] = (p >> 6) & 0x3; + + v = 0; + for (unsigned int i = 0, shifty = 0; i < 4; i++) + { + for (unsigned int ps = 0; ps < prescale; ps++) + { + v |= s[i] << shifty; + shifty += 2; + } + } + + HLILUT[p] = v; + } +} + +void VIP_SetParallaxDisable(bool disabled) +{ + ParallaxDisabled = disabled; +} + +void VIP_SetDefaultColor(uint32 default_color) +{ + Default_Color = default_color; + + VidSettingsDirty = true; +} + +void VIP_SetLEDOnScale(float coeff) +{ + VBLEDOnScale = coeff; +} + +void VIP_SetAnaglyphColors(uint32 lcolor, uint32 rcolor) +{ + Anaglyph_Colors[0] = lcolor; + Anaglyph_Colors[1] = rcolor; + + VidSettingsDirty = true; +} + +static uint16 FRMCYC; + +static uint16 DPCTRL; +static bool DisplayActive; + +#define XPCTRL_XP_RST 0x0001 +#define XPCTRL_XP_EN 0x0002 +static uint16 XPCTRL; +static uint16 SBCMP; // Derived from XPCTRL + +static uint16 SPT[4]; // SPT0~SPT3, 5f848~5f84e +static uint16 GPLT[4]; +static uint8 GPLT_Cache[4][4]; + +static INLINE void Recalc_GPLT_Cache(int which) +{ + for (int i = 0; i < 4; i++) + GPLT_Cache[which][i] = (GPLT[which] >> (i * 2)) & 3; +} + +static uint16 JPLT[4]; +static uint8 JPLT_Cache[4][4]; + +static INLINE void Recalc_JPLT_Cache(int which) +{ + for (int i = 0; i < 4; i++) + JPLT_Cache[which][i] = (JPLT[which] >> (i * 2)) & 3; +} + +static uint16 BKCOL; + +// +// +// +static int32 CalcNextEvent(void); + +static int32 last_ts; + +static uint32 Column; +static int32 ColumnCounter; + +static int32 DisplayRegion; +static bool DisplayFB; + +static int32 GameFrameCounter; + +static int32 DrawingCounter; +static bool DrawingActive; +static bool DrawingFB; +static uint32 DrawingBlock; +static int32 SB_Latch; +static int32 SBOUT_InactiveTime; + +//static uint8 CTA_L, CTA_R; + +static void CheckIRQ(void) +{ + VBIRQ_Assert(VBIRQ_SOURCE_VIP, (bool)(InterruptEnable & InterruptPending)); + +#if 0 + printf("%08x\n", InterruptEnable & InterruptPending); + if((bool)(InterruptEnable & InterruptPending)) + puts("IRQ asserted"); + else + puts("IRQ not asserted"); +#endif +} + +void VIP_Init(void) +{ + ParallaxDisabled = false; + Anaglyph_Colors[0] = 0xFF0000; + Anaglyph_Colors[1] = 0x0000FF; + VB3DMode = VB3DMODE_ANAGLYPH; + Default_Color = 0xFFFFFF; + VB3DReverse = 0; + VBPrescale = 1; + VBSBS_Separation = 0; + + VidSettingsDirty = true; +} + +void VIP_Power(void) +{ + Repeat = 0; + SB_Latch = 0; + SBOUT_InactiveTime = -1; + last_ts = 0; + + Column = 0; + ColumnCounter = 259; + + DisplayRegion = 0; + DisplayFB = 0; + + GameFrameCounter = 0; + + DrawingCounter = 0; + DrawingActive = false; + DrawingFB = 0; + DrawingBlock = 0; + + DPCTRL = 2; + DisplayActive = false; + + memset(FB, 0, 0x6000 * 2 * 2); + memset(CHR_RAM, 0, 0x8000); + memset(DRAM, 0, 0x20000); + + InterruptPending = 0; + InterruptEnable = 0; + + BRTA = 0; + BRTB = 0; + BRTC = 0; + REST = 0; + + FRMCYC = 0; + + XPCTRL = 0; + SBCMP = 0; + + for (int i = 0; i < 4; i++) + { + SPT[i] = 0; + GPLT[i] = 0; + JPLT[i] = 0; + + Recalc_GPLT_Cache(i); + Recalc_JPLT_Cache(i); + } + + BKCOL = 0; +} + +static INLINE uint16 ReadRegister(int32 ×tamp, uint32 A) +{ + uint16 ret = 0; //0xFFFF; + + if (A & 1) + VIP_DBGMSG("Misaligned VIP Read: %08x", A); + + switch (A & 0xFE) + { + default: + VIP_DBGMSG("Unknown VIP register read: %08x", A); + break; + + case 0x00: + ret = InterruptPending; + break; + + case 0x02: + ret = InterruptEnable; + break; + + case 0x20: //printf("Read DPSTTS at %d\n", timestamp); + ret = DPCTRL & 0x702; + if ((DisplayRegion & 1) && DisplayActive) + { + unsigned int DPBSY = 1 << ((DisplayRegion >> 1) & 1); + + if (DisplayFB) + DPBSY <<= 2; + + ret |= DPBSY << 2; + } + //if(!(DisplayRegion & 1)) // FIXME? (Had to do it this way for Galactic Pinball...) + ret |= 1 << 6; + break; + + // Note: Upper bits of BRTA, BRTB, BRTC, and REST(?) are 0 when read(on real hardware) + case 0x24: + ret = BRTA; + break; + + case 0x26: + ret = BRTB; + break; + + case 0x28: + ret = BRTC; + break; + + case 0x2A: + ret = REST; + break; + + case 0x30: + ret = 0xFFFF; + break; + + case 0x40: + ret = XPCTRL & 0x2; + if (DrawingActive) + { + ret |= (1 + DrawingFB) << 2; + } + if (timestamp < SBOUT_InactiveTime) + { + ret |= 0x8000; + ret |= /*DrawingBlock*/ SB_Latch << 8; + } + break; // XPSTTS, read-only + + case 0x44: + ret = 2; // VIP version. 2 is a known valid version, while the validity of other numbers is unknown, so we'll just go with 2. + break; + + case 0x48: + case 0x4a: + case 0x4c: + case 0x4e: + ret = SPT[(A >> 1) & 3]; + break; + + case 0x60: + case 0x62: + case 0x64: + case 0x66: + ret = GPLT[(A >> 1) & 3]; + break; + + case 0x68: + case 0x6a: + case 0x6c: + case 0x6e: + ret = JPLT[(A >> 1) & 3]; + break; + + case 0x70: + ret = BKCOL; + break; + } + + return (ret); +} + +static INLINE void WriteRegister(int32 ×tamp, uint32 A, uint16 V) +{ + if (A & 1) + VIP_DBGMSG("Misaligned VIP Write: %08x %04x", A, V); + + switch (A & 0xFE) + { + default: + VIP_DBGMSG("Unknown VIP register write: %08x %04x", A, V); + break; + + case 0x00: + break; // Interrupt pending, read-only + + case 0x02: + { + InterruptEnable = V & 0xE01F; + + VIP_DBGMSG("Interrupt Enable: %04x", V); + + if (V & 0x2000) + VIP_DBGMSG("Warning: VIP SB Hit Interrupt enable: %04x\n", V); + CheckIRQ(); + } + break; + + case 0x04: + InterruptPending &= ~V; + CheckIRQ(); + break; + + case 0x20: + break; // Display control, read-only. + + case 0x22: + DPCTRL = V & (0x703); // Display-control, write-only + if (V & 1) + { + DisplayActive = false; + InterruptPending &= ~(INT_TIME_ERR | INT_FRAME_START | INT_GAME_START | INT_RFB_END | INT_LFB_END | INT_SCAN_ERR); + CheckIRQ(); + } + break; + + case 0x24: + BRTA = V & 0xFF; // BRTA + RecalcBrightnessCache(); + break; + + case 0x26: + BRTB = V & 0xFF; // BRTB + RecalcBrightnessCache(); + break; + + case 0x28: + BRTC = V & 0xFF; // BRTC + RecalcBrightnessCache(); + break; + + case 0x2A: + REST = V & 0xFF; // REST + RecalcBrightnessCache(); + break; + + case 0x2E: + FRMCYC = V & 0xF; // FRMCYC, write-only? + break; + + case 0x30: + break; // CTA, read-only( + + case 0x40: + break; // XPSTTS, read-only + + case 0x42: + XPCTRL = V & 0x0002; // XPCTRL, write-only + SBCMP = (V >> 8) & 0x1F; + + if (V & 1) + { + VIP_DBGMSG("XPRST"); + DrawingActive = 0; + DrawingCounter = 0; + InterruptPending &= ~(INT_SB_HIT | INT_XP_END | INT_TIME_ERR); + CheckIRQ(); + } + break; + + case 0x44: + break; // Version Control, read-only? + + case 0x48: + case 0x4a: + case 0x4c: + case 0x4e: + SPT[(A >> 1) & 3] = V & 0x3FF; + break; + + case 0x60: + case 0x62: + case 0x64: + case 0x66: + GPLT[(A >> 1) & 3] = V & 0xFC; + Recalc_GPLT_Cache((A >> 1) & 3); + break; + + case 0x68: + case 0x6a: + case 0x6c: + case 0x6e: + JPLT[(A >> 1) & 3] = V & 0xFC; + Recalc_JPLT_Cache((A >> 1) & 3); + break; + + case 0x70: + BKCOL = V & 0x3; + break; + } +} + +// +// Don't update the VIP state on reads/writes, the event system will update it with enough precision as far as VB software cares. +// + +MDFN_FASTCALL uint8 VIP_Read8(int32 ×tamp, uint32 A) +{ + uint8 ret = 0; //0xFF; + + //VIP_Update(timestamp); + + switch (A >> 16) + { + case 0x0: + case 0x1: + if ((A & 0x7FFF) >= 0x6000) + { + ret = ne16_rbo_le(CHR_RAM, (A & 0x1FFF) | ((A >> 2) & 0x6000)); + } + else + { + ret = FB[(A >> 15) & 1][(A >> 16) & 1][A & 0x7FFF]; + } + break; + + case 0x2: + case 0x3: + ret = ne16_rbo_le(DRAM, A & 0x1FFFF); + break; + + case 0x4: + case 0x5: + if (A >= 0x5E000) + ret = ReadRegister(timestamp, A); + else + VIP_DBGMSG("Unknown VIP Read: %08x", A); + break; + + case 0x6: + break; + + case 0x7: + if (A >= 0x8000) + { + ret = ne16_rbo_le(CHR_RAM, A & 0x7FFF); + } + else + VIP_DBGMSG("Unknown VIP Read: %08x", A); + break; + + default: + VIP_DBGMSG("Unknown VIP Read: %08x", A); + break; + } + + //VB_SetEvent(VB_EVENT_VIP, timestamp + CalcNextEvent()); + + return (ret); +} + +MDFN_FASTCALL uint16 VIP_Read16(int32 ×tamp, uint32 A) +{ + uint16 ret = 0; //0xFFFF; + + //VIP_Update(timestamp); + + switch (A >> 16) + { + case 0x0: + case 0x1: + if ((A & 0x7FFF) >= 0x6000) + { + ret = ne16_rbo_le(CHR_RAM, (A & 0x1FFF) | ((A >> 2) & 0x6000)); + } + else + { + ret = MDFN_de16lsb(&FB[(A >> 15) & 1][(A >> 16) & 1][A & 0x7FFF]); + } + break; + + case 0x2: + case 0x3: + ret = ne16_rbo_le(DRAM, A & 0x1FFFF); + break; + + case 0x4: + case 0x5: + if (A >= 0x5E000) + ret = ReadRegister(timestamp, A); + else + VIP_DBGMSG("Unknown VIP Read: %08x", A); + break; + + case 0x6: + break; + + case 0x7: + if (A >= 0x8000) + { + ret = ne16_rbo_le(CHR_RAM, A & 0x7FFF); + } + else + VIP_DBGMSG("Unknown VIP Read: %08x", A); + break; + + default: + VIP_DBGMSG("Unknown VIP Read: %08x", A); + break; + } + + //VB_SetEvent(VB_EVENT_VIP, timestamp + CalcNextEvent()); + return (ret); +} + +MDFN_FASTCALL void VIP_Write8(int32 ×tamp, uint32 A, uint8 V) +{ + //VIP_Update(timestamp); + + //if(A >= 0x3DC00 && A < 0x3E000) + // printf("%08x %02x\n", A, V); + + switch (A >> 16) + { + case 0x0: + case 0x1: + if ((A & 0x7FFF) >= 0x6000) + ne16_wbo_le(CHR_RAM, (A & 0x1FFF) | ((A >> 2) & 0x6000), V); + else + FB[(A >> 15) & 1][(A >> 16) & 1][A & 0x7FFF] = V; + break; + + case 0x2: + case 0x3: + ne16_wbo_le(DRAM, A & 0x1FFFF, V); + break; + + case 0x4: + case 0x5: + if (A >= 0x5E000) + WriteRegister(timestamp, A, V); + else + VIP_DBGMSG("Unknown VIP Write: %08x %02x", A, V); + break; + + case 0x6: + VIP_DBGMSG("Unknown VIP Write: %08x %02x", A, V); + break; + + case 0x7: + if (A >= 0x8000) + ne16_wbo_le(CHR_RAM, A & 0x7FFF, V); + else + VIP_DBGMSG("Unknown VIP Write: %08x %02x", A, V); + break; + + default: + VIP_DBGMSG("Unknown VIP Write: %08x %02x", A, V); + break; + } + + //VB_SetEvent(VB_EVENT_VIP, timestamp + CalcNextEvent()); +} + +MDFN_FASTCALL void VIP_Write16(int32 ×tamp, uint32 A, uint16 V) +{ + //VIP_Update(timestamp); + + //if(A >= 0x3DC00 && A < 0x3E000) + // printf("%08x %04x\n", A, V); + + switch (A >> 16) + { + case 0x0: + case 0x1: + if ((A & 0x7FFF) >= 0x6000) + ne16_wbo_le(CHR_RAM, (A & 0x1FFF) | ((A >> 2) & 0x6000), V); + else + MDFN_en16lsb(&FB[(A >> 15) & 1][(A >> 16) & 1][A & 0x7FFF], V); + break; + + case 0x2: + case 0x3: + ne16_wbo_le(DRAM, A & 0x1FFFF, V); + break; + + case 0x4: + case 0x5: + if (A >= 0x5E000) + WriteRegister(timestamp, A, V); + else + VIP_DBGMSG("Unknown VIP Write: %08x %04x", A, V); + break; + + case 0x6: + VIP_DBGMSG("Unknown VIP Write: %08x %04x", A, V); + break; + + case 0x7: + if (A >= 0x8000) + ne16_wbo_le(CHR_RAM, A & 0x7FFF, V); + else + VIP_DBGMSG("Unknown VIP Write: %08x %04x", A, V); + break; + + default: + VIP_DBGMSG("Unknown VIP Write: %08x %04x", A, V); + break; + } + + //VB_SetEvent(VB_EVENT_VIP, timestamp + CalcNextEvent()); +} + +static MDFN_Surface real_surface; +static MDFN_Surface *surface; + +void VIP_StartFrame(MyFrameInfo* frame) +{ + // puts("Start frame"); + + if (VidSettingsDirty) + { + MakeColorLUT(); + Recalc3DModeStuff(); + + VidSettingsDirty = false; + } + + switch (VB3DMode) + { + default: + frame->Width = 384; + frame->Height = 224; + break; + + case VB3DMODE_VLI: + frame->Width = 768 * VBPrescale; + frame->Height = 224; + break; + + case VB3DMODE_HLI: + frame->Width = 384; + frame->Height = 448 * VBPrescale; + break; + + case VB3DMODE_CSCOPE: + frame->Width = 512; + frame->Height = 384; + break; + + case VB3DMODE_SIDEBYSIDE: + frame->Width = 768 + VBSBS_Separation; + frame->Height = 224; + break; + } + + surface = &real_surface; + real_surface.pixels = frame->VideoBuffer; + real_surface.pitch32 = frame->Width; +} + +void VIP_ResetTS(void) +{ + if (SBOUT_InactiveTime >= 0) + SBOUT_InactiveTime -= last_ts; + last_ts = 0; +} + +static int32 CalcNextEvent(void) +{ + return (ColumnCounter); +} + +#include "vip_draw.inc" + +static INLINE void CopyFBColumnToTarget_Anaglyph_BASE(const bool DisplayActive_arg, const int lr) +{ + const int fb = DisplayFB; + uint32 *target = surface->pixels + Column; + const int32 pitch32 = surface->pitch32; + const uint8 *fb_source = &FB[fb][lr][64 * Column]; + + for (int y = 56; y; y--) + { + uint32 source_bits = *fb_source; + + for (int y_sub = 4; y_sub; y_sub--) + { + uint32 pixel = BrightCLUT[lr][source_bits & 3]; + + if (!DisplayActive_arg) + pixel = 0; + + if (lr) + *target |= pixel; + else + *target = pixel; + + source_bits >>= 2; + target += pitch32; + } + fb_source++; + } +} + +static void CopyFBColumnToTarget_Anaglyph(void) +{ + const int lr = (DisplayRegion & 2) >> 1; + + if (!DisplayActive) + { + if (!lr) + CopyFBColumnToTarget_Anaglyph_BASE(0, 0); + else + CopyFBColumnToTarget_Anaglyph_BASE(0, 1); + } + else + { + if (!lr) + CopyFBColumnToTarget_Anaglyph_BASE(1, 0); + else + CopyFBColumnToTarget_Anaglyph_BASE(1, 1); + } +} + +static uint32 AnaSlowBuf[384][224]; + +static INLINE void CopyFBColumnToTarget_AnaglyphSlow_BASE(const bool DisplayActive_arg, const int lr) +{ + const int fb = DisplayFB; + const uint8 *fb_source = &FB[fb][lr][64 * Column]; + + if (!lr) + { + uint32 *target = AnaSlowBuf[Column]; + + for (int y = 56; y; y--) + { + uint32 source_bits = *fb_source; + + for (int y_sub = 4; y_sub; y_sub--) + { + uint32 pixel = BrightnessCache[source_bits & 3]; + + if (!DisplayActive_arg) + pixel = 0; + + *target = pixel; + source_bits >>= 2; + target++; + } + fb_source++; + } + } + else + { + uint32 *target = surface->pixels + Column; + const uint32 *left_src = AnaSlowBuf[Column]; + const int32 pitch32 = surface->pitch32; + + for (int y = 56; y; y--) + { + uint32 source_bits = *fb_source; + + for (int y_sub = 4; y_sub; y_sub--) + { + uint32 pixel = AnaSlowColorLUT[*left_src][DisplayActive_arg ? BrightnessCache[source_bits & 3] : 0]; + + *target = pixel; + + source_bits >>= 2; + target += pitch32; + left_src++; + } + fb_source++; + } + } +} + +static void CopyFBColumnToTarget_AnaglyphSlow(void) +{ + const int lr = (DisplayRegion & 2) >> 1; + + if (!DisplayActive) + { + if (!lr) + CopyFBColumnToTarget_AnaglyphSlow_BASE(0, 0); + else + CopyFBColumnToTarget_AnaglyphSlow_BASE(0, 1); + } + else + { + if (!lr) + CopyFBColumnToTarget_AnaglyphSlow_BASE(1, 0); + else + CopyFBColumnToTarget_AnaglyphSlow_BASE(1, 1); + } +} + +static void CopyFBColumnToTarget_CScope_BASE(const bool DisplayActive_arg, const int lr, const int dest_lr) +{ + const int fb = DisplayFB; + uint32 *target = surface->pixels + (dest_lr ? 512 - 16 - 1 : 16) + (dest_lr ? Column : 383 - Column) * surface->pitch32; + const uint8 *fb_source = &FB[fb][lr][64 * Column]; + + for (int y = 56; y; y--) + { + uint32 source_bits = *fb_source; + + for (int y_sub = 4; y_sub; y_sub--) + { + if (DisplayActive_arg) + *target = BrightCLUT[lr][source_bits & 3]; + else + *target = 0; + + source_bits >>= 2; + if (dest_lr) + target--; + else + target++; + } + fb_source++; + } +} + +static void CopyFBColumnToTarget_CScope(void) +{ + const int lr = (DisplayRegion & 2) >> 1; + + if (!DisplayActive) + { + if (!lr) + CopyFBColumnToTarget_CScope_BASE(0, 0, 0 ^ VB3DReverse); + else + CopyFBColumnToTarget_CScope_BASE(0, 1, 1 ^ VB3DReverse); + } + else + { + if (!lr) + CopyFBColumnToTarget_CScope_BASE(1, 0, 0 ^ VB3DReverse); + else + CopyFBColumnToTarget_CScope_BASE(1, 1, 1 ^ VB3DReverse); + } +} + +static void CopyFBColumnToTarget_SideBySide_BASE(const bool DisplayActive_arg, const int lr, const int dest_lr) +{ + const int fb = DisplayFB; + uint32 *target = surface->pixels + Column + (dest_lr ? (384 + VBSBS_Separation) : 0); + const int32 pitch32 = surface->pitch32; + const uint8 *fb_source = &FB[fb][lr][64 * Column]; + + for (int y = 56; y; y--) + { + uint32 source_bits = *fb_source; + + for (int y_sub = 4; y_sub; y_sub--) + { + if (DisplayActive_arg) + *target = BrightCLUT[lr][source_bits & 3]; + else + *target = 0; + source_bits >>= 2; + target += pitch32; + } + fb_source++; + } +} + +static void CopyFBColumnToTarget_SideBySide(void) +{ + const int lr = (DisplayRegion & 2) >> 1; + + if (!DisplayActive) + { + if (!lr) + CopyFBColumnToTarget_SideBySide_BASE(0, 0, 0 ^ VB3DReverse); + else + CopyFBColumnToTarget_SideBySide_BASE(0, 1, 1 ^ VB3DReverse); + } + else + { + if (!lr) + CopyFBColumnToTarget_SideBySide_BASE(1, 0, 0 ^ VB3DReverse); + else + CopyFBColumnToTarget_SideBySide_BASE(1, 1, 1 ^ VB3DReverse); + } +} + +static INLINE void CopyFBColumnToTarget_VLI_BASE(const bool DisplayActive_arg, const int lr, const int dest_lr) +{ + const int fb = DisplayFB; + uint32 *target = surface->pixels + Column * 2 * VBPrescale + dest_lr; + const int32 pitch32 = surface->pitch32; + const uint8 *fb_source = &FB[fb][lr][64 * Column]; + + for (int y = 56; y; y--) + { + uint32 source_bits = *fb_source; + + for (int y_sub = 4; y_sub; y_sub--) + { + uint32 tv; + + if (DisplayActive_arg) + tv = BrightCLUT[lr][source_bits & 3]; + else + tv = 0; + + for (uint32 ps = 0; ps < VBPrescale; ps++) + target[ps * 2] = tv; + + source_bits >>= 2; + target += pitch32; + } + fb_source++; + } +} + +static void CopyFBColumnToTarget_VLI(void) +{ + const int lr = (DisplayRegion & 2) >> 1; + + if (!DisplayActive) + { + if (!lr) + CopyFBColumnToTarget_VLI_BASE(0, 0, 0 ^ VB3DReverse); + else + CopyFBColumnToTarget_VLI_BASE(0, 1, 1 ^ VB3DReverse); + } + else + { + if (!lr) + CopyFBColumnToTarget_VLI_BASE(1, 0, 0 ^ VB3DReverse); + else + CopyFBColumnToTarget_VLI_BASE(1, 1, 1 ^ VB3DReverse); + } +} + +static INLINE void CopyFBColumnToTarget_HLI_BASE(const bool DisplayActive_arg, const int lr, const int dest_lr) +{ + const int fb = DisplayFB; + const int32 pitch32 = surface->pitch32; + uint32 *target = surface->pixels + Column + dest_lr * pitch32; + const uint8 *fb_source = &FB[fb][lr][64 * Column]; + + if (VBPrescale <= 4) + for (int y = 56; y; y--) + { + uint32 source_bits = HLILUT[*fb_source]; + + for (int y_sub = 4 * VBPrescale; y_sub; y_sub--) + { + if (DisplayActive_arg) + *target = BrightCLUT[lr][source_bits & 3]; + else + *target = 0; + + target += pitch32 * 2; + source_bits >>= 2; + } + fb_source++; + } + else + for (int y = 56; y; y--) + { + uint32 source_bits = *fb_source; + + for (int y_sub = 4; y_sub; y_sub--) + { + for (uint32 ps = 0; ps < VBPrescale; ps++) + { + if (DisplayActive_arg) + *target = BrightCLUT[lr][source_bits & 3]; + else + *target = 0; + + target += pitch32 * 2; + } + + source_bits >>= 2; + } + fb_source++; + } +} + +static void CopyFBColumnToTarget_HLI(void) +{ + const int lr = (DisplayRegion & 2) >> 1; + + if (!DisplayActive) + { + if (!lr) + CopyFBColumnToTarget_HLI_BASE(0, 0, 0 ^ VB3DReverse); + else + CopyFBColumnToTarget_HLI_BASE(0, 1, 1 ^ VB3DReverse); + } + else + { + if (!lr) + CopyFBColumnToTarget_HLI_BASE(1, 0, 0 ^ VB3DReverse); + else + CopyFBColumnToTarget_HLI_BASE(1, 1, 1 ^ VB3DReverse); + } +} + +v810_timestamp_t MDFN_FASTCALL VIP_Update(const v810_timestamp_t timestamp) +{ + int32 clocks = timestamp - last_ts; + int32 running_timestamp = timestamp; + + while (clocks > 0) + { + int32 chunk_clocks = clocks; + + if (DrawingCounter > 0 && chunk_clocks > DrawingCounter) + chunk_clocks = DrawingCounter; + if (chunk_clocks > ColumnCounter) + chunk_clocks = ColumnCounter; + + running_timestamp += chunk_clocks; + + if (DrawingCounter > 0) + { + DrawingCounter -= chunk_clocks; + if (DrawingCounter <= 0) + { + alignas(8) uint8 DrawingBuffers[2][512 * 8]; // Don't decrease this from 512 unless you adjust vip_draw.inc(including areas that draw off-visible >= 384 and >= -7 for speed reasons) + + VIP_DrawBlock(DrawingBlock, DrawingBuffers[0] + 8, DrawingBuffers[1] + 8); + + for (int lr = 0; lr < 2; lr++) + { + uint8 *FB_Target = FB[DrawingFB][lr] + DrawingBlock * 2; + + for (int x = 0; x < 384; x++) + { + FB_Target[64 * x + 0] = (DrawingBuffers[lr][8 + x + 512 * 0] << 0) | (DrawingBuffers[lr][8 + x + 512 * 1] << 2) | (DrawingBuffers[lr][8 + x + 512 * 2] << 4) | (DrawingBuffers[lr][8 + x + 512 * 3] << 6); + FB_Target[64 * x + 1] = (DrawingBuffers[lr][8 + x + 512 * 4] << 0) | (DrawingBuffers[lr][8 + x + 512 * 5] << 2) | (DrawingBuffers[lr][8 + x + 512 * 6] << 4) | (DrawingBuffers[lr][8 + x + 512 * 7] << 6); + } + } + + SBOUT_InactiveTime = running_timestamp + 1120; + SB_Latch = DrawingBlock; // Not exactly correct, but probably doesn't matter. + + DrawingBlock++; + if (DrawingBlock == 28) + { + DrawingActive = false; + + InterruptPending |= INT_XP_END; + CheckIRQ(); + } + else + DrawingCounter += 1120 * 4; + } + } + + ColumnCounter -= chunk_clocks; + if (ColumnCounter == 0) + { + if (DisplayRegion & 1) + { + if (!(Column & 3)) + { + const int lr = (DisplayRegion & 2) >> 1; + uint16 ctdata = ne16_rbo_le(DRAM, 0x1DFFE - ((Column >> 2) * 2) - (lr ? 0 : 0x200)); + + //printf("%02x, repeat: %02x\n", ctdata & 0xFF, ctdata >> 8); + + if ((ctdata >> 8) != Repeat) + { + Repeat = ctdata >> 8; + RecalcBrightnessCache(); + } + } + CopyFBColumnToTarget(); + } + + ColumnCounter = 259; + Column++; + if (Column == 384) + { + Column = 0; + + if (DisplayActive) + { + if (DisplayRegion & 1) // Did we just finish displaying an active region? + { + if (DisplayRegion & 2) // finished displaying right eye + InterruptPending |= INT_RFB_END; + else // Otherwise, left eye + InterruptPending |= INT_LFB_END; + + CheckIRQ(); + } + } + + DisplayRegion = (DisplayRegion + 1) & 3; + + if (DisplayRegion == 0) // New frame start + { + DisplayActive = DPCTRL & 0x2; + + if (DisplayActive) + { + InterruptPending |= INT_FRAME_START; + CheckIRQ(); + } + GameFrameCounter++; + if (GameFrameCounter > FRMCYC) // New game frame start? + { + InterruptPending |= INT_GAME_START; + CheckIRQ(); + + if (XPCTRL & XPCTRL_XP_EN) + { + DisplayFB ^= 1; + + DrawingBlock = 0; + DrawingActive = true; + DrawingCounter = 1120 * 4; + DrawingFB = DisplayFB ^ 1; + } + + GameFrameCounter = 0; + } + + VB_ExitLoop(); + } + } + } + + clocks -= chunk_clocks; + } + + last_ts = timestamp; + + return (timestamp + CalcNextEvent()); +} +} diff --git a/waterbox/vb/vip.h b/waterbox/vb/vip.h new file mode 100644 index 0000000000..c9cb9ab186 --- /dev/null +++ b/waterbox/vb/vip.h @@ -0,0 +1,82 @@ +/******************************************************************************/ +/* Mednafen Virtual Boy Emulation Module */ +/******************************************************************************/ +/* vip.h: +** Copyright (C) 2010-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#pragma once + +namespace MDFN_IEN_VB +{ +void VIP_Init(void) MDFN_COLD; +void VIP_Power(void) MDFN_COLD; + +void VIP_SetInstantDisplayHack(bool) MDFN_COLD; +void VIP_SetAllowDrawSkip(bool) MDFN_COLD; +void VIP_Set3DMode(uint32 mode, bool reverse, uint32 prescale, uint32 sbs_separation) MDFN_COLD; +void VIP_SetParallaxDisable(bool disabled) MDFN_COLD; +void VIP_SetDefaultColor(uint32 default_color) MDFN_COLD; +void VIP_SetAnaglyphColors(uint32 lcolor, uint32 rcolor) MDFN_COLD; // R << 16, G << 8, B << 0 +void VIP_SetLEDOnScale(float coeff) MDFN_COLD; + +v810_timestamp_t MDFN_FASTCALL VIP_Update(const v810_timestamp_t timestamp); +void VIP_ResetTS(void); + +void VIP_StartFrame(MyFrameInfo* frame); + +MDFN_FASTCALL uint8 VIP_Read8(v810_timestamp_t ×tamp, uint32 A); +MDFN_FASTCALL uint16 VIP_Read16(v810_timestamp_t ×tamp, uint32 A); + +MDFN_FASTCALL void VIP_Write8(v810_timestamp_t ×tamp, uint32 A, uint8 V); +MDFN_FASTCALL void VIP_Write16(v810_timestamp_t ×tamp, uint32 A, uint16 V); + +enum +{ + VIP_GSREG_IPENDING = 0, // Current pending interrupt(bits) + VIP_GSREG_IENABLE, + + VIP_GSREG_DPCTRL, + + VIP_GSREG_BRTA, + VIP_GSREG_BRTB, + VIP_GSREG_BRTC, + VIP_GSREG_REST, + VIP_GSREG_FRMCYC, + VIP_GSREG_XPCTRL, + + VIP_GSREG_SPT0, + VIP_GSREG_SPT1, + VIP_GSREG_SPT2, + VIP_GSREG_SPT3, + + VIP_GSREG_GPLT0, + VIP_GSREG_GPLT1, + VIP_GSREG_GPLT2, + VIP_GSREG_GPLT3, + + VIP_GSREG_JPLT0, + VIP_GSREG_JPLT1, + VIP_GSREG_JPLT2, + VIP_GSREG_JPLT3, + + VIP_GSREG_BKCOL, +}; + +uint32 VIP_GetRegister(const unsigned int id, char *special, const uint32 special_len); +void VIP_SetRegister(const unsigned int id, const uint32 value); +} diff --git a/waterbox/vb/vip_draw.inc b/waterbox/vb/vip_draw.inc new file mode 100644 index 0000000000..f7eb222589 --- /dev/null +++ b/waterbox/vb/vip_draw.inc @@ -0,0 +1,493 @@ +/******************************************************************************/ +/* Mednafen Virtual Boy Emulation Module */ +/******************************************************************************/ +/* vip_draw.inc: +** Copyright (C) 2010-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#define BGM_AFFINE 0x2 +#define BGM_OBJ 0x3 + + +static void DrawBG(uint8 *target, uint16 RealY, bool lr, uint8 bgmap_base_raw, bool overplane, uint16 overplane_char, uint32 SourceX, uint32 SourceY, uint32 scx, uint32 scy, uint16 DestX, uint16 DestY, uint16 DestWidth, uint16 DestHeight) +{ + const uint16 *CHR16 = CHR_RAM; + const uint16 *BGMap = DRAM; + uint32 BGMap_Base = bgmap_base_raw << 12; + int32 start_x, final_x; + const uint32 bgsc_overplane = DRAM[overplane_char]; + const uint32 BGMap_XCount = 1 << scx; + const uint32 BGMap_YCount = 1 << scy; + const uint32 SourceX_Size = 512 * BGMap_XCount; + const uint32 SourceY_Size = 512 * BGMap_YCount; + const uint32 SourceX_Mask = overplane ? 0x1FFF : (SourceX_Size - 1); + const uint32 SourceY_Mask = overplane ? 0x1FFF : (SourceY_Size - 1); + + if((uint16)(RealY - DestY) > DestHeight) + return; + + //printf("%d, %d, %d, %d\n", overplane, srcXSize, srcYSize, bgmap_base_raw); + + DestX = sign_10_to_s16(DestX); + + if(DestX & 0x8000) + SourceX -= DestX; + + start_x = (int16)DestX; + final_x = (int16)DestX + DestWidth; + + if(start_x < 0) + start_x = 0; + + if(final_x > 383) + final_x = 383; + + if(start_x > final_x) + return; + + // Optimization: + SourceY &= SourceY_Mask; + BGMap_Base |= (((SourceY >> 3) & 0x3F) * 0x40) | (((SourceY << 3) & ~0xFFF) << scx); + + for(int x = start_x; x <= final_x; x++) + { + uint32 bgsc; + uint32 char_no; + uint32 palette_selector; + uint32 hflip_xor; + uint32 vflip_xor; + + SourceX &= SourceX_Mask; + + bgsc = bgsc_overplane; + + if(SourceX < SourceX_Size && SourceY < SourceY_Size) + bgsc = BGMap[(BGMap_Base | ((SourceX << 3) & ~0xFFF) | ((SourceX >> 3) & 0x3F)) & 0xFFFF]; + + char_no = bgsc & 0x7FF; + palette_selector = bgsc >> 14; + hflip_xor = (bgsc & 0x2000) ? 7 : 0; //(((int32)bgsc << 18) >> 31) & 0x7; + vflip_xor = (bgsc & 0x1000) ? 7 : 0; //(((int32)bgsc << 19) >> 31) & 0x7; + + unsigned int char_sub_y = vflip_xor ^ (SourceY & 0x7); + + if(!(SourceX & 7) && (x + 7) <= final_x) + { + uint32 pixels = CHR16[char_no * 8 + char_sub_y]; + + #if 0 + unsigned int char_sub_x; + uint8 *sub_target = target + x + 8; + + for(int sub_x = -8; sub_x < 0; sub_x++) + { + if(pixels & 3) sub_target[sub_x] = GPLT_Cache[palette_selector][pixels & 3]; + pixels >>= 2; + } + #endif + + if(bgsc & 0x2000) + { + if((pixels >> 14) & 3) target[0 + x] = GPLT_Cache[palette_selector][(pixels >> 14) & 3]; + if((pixels >> 12) & 3) target[1 + x] = GPLT_Cache[palette_selector][(pixels >> 12) & 3]; + if((pixels >> 10) & 3) target[2 + x] = GPLT_Cache[palette_selector][(pixels >> 10) & 3]; + if((pixels >> 8) & 3) target[3 + x] = GPLT_Cache[palette_selector][(pixels >> 8) & 3]; + if((pixels >> 6) & 3) target[4 + x] = GPLT_Cache[palette_selector][(pixels >> 6) & 3]; + if((pixels >> 4) & 3) target[5 + x] = GPLT_Cache[palette_selector][(pixels >> 4) & 3]; + if((pixels >> 2) & 3) target[6 + x] = GPLT_Cache[palette_selector][(pixels >> 2) & 3]; + if((pixels >> 0) & 3) target[7 + x] = GPLT_Cache[palette_selector][(pixels >> 0) & 3]; + } + else + { + if((pixels >> 0) & 3) target[0 + x] = GPLT_Cache[palette_selector][(pixels >> 0) & 3]; + if((pixels >> 2) & 3) target[1 + x] = GPLT_Cache[palette_selector][(pixels >> 2) & 3]; + if((pixels >> 4) & 3) target[2 + x] = GPLT_Cache[palette_selector][(pixels >> 4) & 3]; + if((pixels >> 6) & 3) target[3 + x] = GPLT_Cache[palette_selector][(pixels >> 6) & 3]; + if((pixels >> 8) & 3) target[4 + x] = GPLT_Cache[palette_selector][(pixels >> 8) & 3]; + if((pixels >> 10) & 3) target[5 + x] = GPLT_Cache[palette_selector][(pixels >> 10) & 3]; + if((pixels >> 12) & 3) target[6 + x] = GPLT_Cache[palette_selector][(pixels >> 12) & 3]; + if((pixels >> 14) & 3) target[7 + x] = GPLT_Cache[palette_selector][(pixels >> 14) & 3]; + } + + x += 7; + SourceX += 8; + } + else + { + unsigned int char_sub_x; + + char_sub_x = hflip_xor ^ (SourceX & 0x7); + + uint8 pixel = (CHR16[char_no * 8 + char_sub_y] >> (char_sub_x * 2)) & 0x3; + + if(pixel) + target[x] = GPLT_Cache[palette_selector][pixel]; //target[x] = (GPLT[palette_selector] >> (pixel * 2)) & 0x3; + SourceX++; + } + } +} + +static void DrawAffine(uint8 *target, uint16 RealY, bool lr, uint32 ParamBase, uint32 BGMap_Base, bool OverplaneMode, uint16 OverplaneChar, uint32 scx, uint32 scy, + uint16 DestX, uint16 DestY, uint16 DestWidth, uint16 DestHeight) +{ + const uint16 *CHR16 = CHR_RAM; + const uint16 *BGMap = DRAM; + + const uint32 BGMap_XCount = 1 << scx; + const uint32 BGMap_YCount = 1 << scy; + const uint32 SourceX_Size = 512 * BGMap_XCount; + const uint32 SourceY_Size = 512 * BGMap_YCount; + + const uint16 *param_ptr = &DRAM[(ParamBase + 8 * (RealY - DestY)) & 0xFFFF]; + int16 mx = param_ptr[0], mp = (ParallaxDisabled ? 0 : param_ptr[1]), my = param_ptr[2], dx = param_ptr[3], dy = param_ptr[4]; + + uint32 SourceX, SourceY; + uint32 SourceX_Mask, SourceY_Mask; + + int32 start_x, final_x; + const uint32 bgsc_overplane = DRAM[OverplaneChar]; + + + DestX = sign_10_to_s16(DestX); + + if((uint16)(RealY - DestY) > DestHeight) + return; + + SourceX = (int32)mx << 6; + SourceY = (int32)my << 6; + + if(DestX & 0x8000) + { + SourceX += dx * (65536 - DestX); + SourceY += dy * (65536 - DestX); + } + + if(mp >= 0 && lr) + { + SourceX += dx * mp; + SourceY += dy * mp; + } + else if(mp < 0 && !lr) + { + SourceX += dx * -mp; + SourceY += dy * -mp; + } + + if(OverplaneMode) + { + SourceX_Mask = 0x3FFFFFF; //(((uint32)SourceX_Size << 9) * 2) - 1; + SourceY_Mask = 0x3FFFFFF; //(((uint32)SourceY_Size << 9) * 2) - 1; + } + else + { + SourceX_Mask = ((uint32)SourceX_Size << 9) - 1; + SourceY_Mask = ((uint32)SourceY_Size << 9) - 1; + } + + start_x = (int16)DestX; + final_x = (int16)DestX + DestWidth; + + if(start_x < 0) + start_x = 0; + + if(final_x > 383) + final_x = 383; + +if(dy == 0) // Optimization for no rotation. +{ + SourceY &= SourceY_Mask; + + if(SourceY >= (SourceY_Size << 9)) + return; + + BGMap_Base |= (((SourceY >> 6) & ~0xFFF) << scx) | (((SourceY >> 12) & 0x3F) * 0x40); + for(int x = start_x; x <= final_x; x++) + { + uint32 bgsc; + uint32 hflip_xor; + uint32 vflip_xor; + uint32 pixel = 0; + + SourceX &= SourceX_Mask; + + bgsc = bgsc_overplane; + + if(SourceX < (SourceX_Size << 9)) + bgsc = BGMap[(BGMap_Base | ((SourceX >> 6) & ~0xFFF) | ((SourceX >> 12) & 0x3F)) & 0xFFFF]; + + //hflip_xor = bgsc & 0x2000 ? 0xE : 0; + //vflip_xor = bgsc & 0x1000 ? 0x7 : 0; + hflip_xor = ((int32)(bgsc << 18) >> 30) & 0xE; + vflip_xor = ((int32)(bgsc << 19) >> 31) & 0x7; + + unsigned int char_sub_y = vflip_xor ^ ((SourceY >> 9) & 0x7); + unsigned int char_sub_x = hflip_xor ^ ((SourceX >> 8) & 0xE); + + pixel = (CHR16[((bgsc & 0x7FF) * 8) | char_sub_y] >> char_sub_x) & 0x3; + + if(pixel) + target[x] = GPLT_Cache[bgsc >> 14][pixel]; + + SourceX += dx; + } +} +else + for(int x = start_x; x <= final_x; x++) + { + uint32 bgsc; + uint32 char_no; + uint32 palette_selector; + uint32 hflip_xor; + uint32 vflip_xor; + uint8 pixel = 0; + + SourceX &= SourceX_Mask; + SourceY &= SourceY_Mask; + + bgsc = bgsc_overplane; + + if(SourceX < (SourceX_Size << 9) && SourceY < (SourceY_Size << 9)) + { + uint32 m_index = ((SourceX >> 6) & ~0xFFF) + (((SourceY >> 6) & ~0xFFF) << scx); + uint32 sub_index = ((SourceX >> 12) & 0x3F) + (((SourceY >> 12) & 0x3F) * 0x40); + + bgsc = BGMap[(BGMap_Base | m_index | sub_index) & 0xFFFF]; + + //bgsc = BGMap[(BGMapBase + (SourceX >> 12) + (SourceY >> 12) * (SourceX_Size >> 3)) & 0xFFFF ]; + } + char_no = bgsc & 0x7FF; + palette_selector = bgsc >> 14; + hflip_xor = bgsc & 0x2000 ? 7 : 0; //(((int32)bgsc << 18) >> 31) & 0x7; + vflip_xor = bgsc & 0x1000 ? 7 : 0; //(((int32)bgsc << 19) >> 31) & 0x7; + + unsigned int char_sub_y = vflip_xor ^ ((SourceY >> 9) & 0x7); + unsigned int char_sub_x = hflip_xor ^ ((SourceX >> 9) & 0x7); + + pixel = (CHR16[char_no * 8 + char_sub_y] >> (char_sub_x * 2)) & 0x3; + + if(pixel) + target[x] = GPLT_Cache[palette_selector][pixel]; + + SourceX += dx; + SourceY += dy; + } +} + +static int obj_search_which; + +static void DrawOBJ(uint8 *fb[2], uint16 Y, bool lron[2]) +{ + const uint16 *CHR16 = CHR_RAM; + + int32 start_oam; + int32 end_oam; + + start_oam = SPT[obj_search_which]; + + end_oam = 1023; + if(obj_search_which) + end_oam = SPT[obj_search_which - 1]; + + int32 oam = start_oam; + do + { + const uint16 *oam_ptr = &DRAM[(0x1E000 + (oam * 8)) >> 1]; + const uint32 jy = oam_ptr[2]; + const uint32 tile_y = (Y - jy) & 0xFF; // I think this mask is right. See: http://www.planetvb.com/modules/newbb/viewtopic.php?topic_id=3797&forum=2 + + if(tile_y >= 8) + continue; + + uint32 jx = oam_ptr[0]; + uint32 jp = ParallaxDisabled ? 0 : (oam_ptr[1] & 0x3FFF); + uint32 palette_selector = oam_ptr[3] >> 14; + uint32 vflip_xor = (oam_ptr[3] & 0x1000) ? 7 : 0; + uint32 char_sub_y = vflip_xor ^ tile_y; + bool jlron[2] = { (bool)(oam_ptr[1] & 0x8000), (bool)(oam_ptr[1] & 0x4000) }; + uint32 char_no = oam_ptr[3] & 0x7FF; + const uint32 pixels_save = CHR16[char_no * 8 + char_sub_y]; + + for(int lr = 0; lr < 2; lr++) + { + if(!(jlron[lr] & lron[lr])) + continue; + + uint32 pixels = pixels_save; + int32 x = sign_x_to_s32(10, (jx + (lr ? jp : -jp))); // It may actually be 9, TODO? + + if(x >= -7 && x < 384) // Make sure we always keep the pitch of our 384x8 buffer large enough(with padding before and after the visible space) + { + uint8 *target = &fb[lr][x]; + + if(oam_ptr[3] & 0x2000) + { + target += 7; + + for(int meow = 8; meow; meow--) + { + if(pixels & 3) + *target = JPLT_Cache[palette_selector][pixels & 3]; + target--; + pixels >>= 2; + } + } + else + { + for(int meow = 8; meow; meow--) + { + if(pixels & 3) + *target = JPLT_Cache[palette_selector][pixels & 3]; + target++; + pixels >>= 2; + } + } + #if 0 + if(oam_ptr[3] & 0x2000) + { + if((pixels >> 14) & 3) fb[lr][0 + x] = JPLT_Cache[palette_selector][(pixels >> 14) & 3]; + if((pixels >> 12) & 3) fb[lr][1 + x] = JPLT_Cache[palette_selector][(pixels >> 12) & 3]; + if((pixels >> 10) & 3) fb[lr][2 + x] = JPLT_Cache[palette_selector][(pixels >> 10) & 3]; + if((pixels >> 8) & 3) fb[lr][3 + x] = JPLT_Cache[palette_selector][(pixels >> 8) & 3]; + if((pixels >> 6) & 3) fb[lr][4 + x] = JPLT_Cache[palette_selector][(pixels >> 6) & 3]; + if((pixels >> 4) & 3) fb[lr][5 + x] = JPLT_Cache[palette_selector][(pixels >> 4) & 3]; + if((pixels >> 2) & 3) fb[lr][6 + x] = JPLT_Cache[palette_selector][(pixels >> 2) & 3]; + if((pixels >> 0) & 3) fb[lr][7 + x] = JPLT_Cache[palette_selector][(pixels >> 0) & 3]; + } + else + { + if((pixels >> 0) & 3) fb[lr][0 + x] = JPLT_Cache[palette_selector][(pixels >> 0) & 3]; + if((pixels >> 2) & 3) fb[lr][1 + x] = JPLT_Cache[palette_selector][(pixels >> 2) & 3]; + if((pixels >> 4) & 3) fb[lr][2 + x] = JPLT_Cache[palette_selector][(pixels >> 4) & 3]; + if((pixels >> 6) & 3) fb[lr][3 + x] = JPLT_Cache[palette_selector][(pixels >> 6) & 3]; + if((pixels >> 8) & 3) fb[lr][4 + x] = JPLT_Cache[palette_selector][(pixels >> 8) & 3]; + if((pixels >> 10) & 3) fb[lr][5 + x] = JPLT_Cache[palette_selector][(pixels >> 10) & 3]; + if((pixels >> 12) & 3) fb[lr][6 + x] = JPLT_Cache[palette_selector][(pixels >> 12) & 3]; + if((pixels >> 14) & 3) fb[lr][7 + x] = JPLT_Cache[palette_selector][(pixels >> 14) & 3]; + } +#endif + + } + + } + } while( (oam = (oam - 1) & 1023) != end_oam); + +} + + +void VIP_DrawBlock(uint8 block_no, uint8 *fb_l, uint8 *fb_r) +{ + for(int y = 0; y < 8; y++) + { + memset(fb_l + y * 512, BKCOL, 384); + memset(fb_r + y * 512, BKCOL, 384); + } + + obj_search_which = 3; + + for(int world = 31; world >= 0; world--) + { + const uint16 *world_ptr = &DRAM[(0x1D800 + world * 0x20) >> 1]; + + uint32 bgmap_base = world_ptr[0] & 0xF; + bool end = world_ptr[0] & 0x40; + bool over = world_ptr[0] & 0x80; + uint32 scy = (world_ptr[0] >> 8) & 3; + uint32 scx = (world_ptr[0] >> 10) & 3; + uint32 bgm = (world_ptr[0] >> 12) & 3; + bool lron[2] = { (bool)(world_ptr[0] & 0x8000), (bool)(world_ptr[0] & 0x4000) }; + + uint16 gx = sign_11_to_s16(world_ptr[1]); + uint16 gp = ParallaxDisabled ? 0 : sign_9_to_s16(world_ptr[2]); + uint16 gy = sign_11_to_s16(world_ptr[3]); + uint16 mx = world_ptr[4]; + uint16 mp = ParallaxDisabled ? 0 : sign_9_to_s16(world_ptr[5]); + uint16 my = world_ptr[6]; + uint16 window_width = sign_11_to_s16(world_ptr[7]); + uint16 window_height = (world_ptr[8] & 0x3FF); + uint32 param_base = (world_ptr[9] & 0xFFF0); + uint16 overplane_char = world_ptr[10]; + + if(end) + break; + + if(((512 << scx) + (512 << scy)) > 4096) + { + printf("BG Size too large for world: %d(scx=%d, scy=%d)\n", world, scx, scy); + } + +// if(world != 2) +// continue; + + // if(block_no == 8) + // printf("World: %d; gx: %d, gp: %d, gy: %d, mx: %d, mp: %d, my: %d, window_width: %d, window_height: %d\n", world, gx, gp, gy, mx, mp, my, window_width, window_height); + + for(int y = 0; y < 8; y++) + { + uint8 *fb[2] = { &fb_l[y * 512], &fb_r[y * 512] }; + + if(bgm == BGM_OBJ) + { + if(!lron[0] || !lron[1]) + printf("Bad OBJ World? %d(%d/%d) %d~%d\n", world, lron[0], lron[1], SPT[obj_search_which], obj_search_which ? (SPT[obj_search_which - 1] + 1) : 0); + + DrawOBJ(fb, (block_no * 8) + y, lron); + } + else if(bgm == BGM_AFFINE) + { + //if(((block_no * 8) + y) == 128) + // printf("Draw affine: %d %d\n", gx, gp); + for(int lr = 0; lr < 2; lr++) + { + if(lron[lr]) + { + DrawAffine(fb[lr], (block_no * 8) + y, lr, param_base, bgmap_base * 4096, over, overplane_char, scx, scy, + gx + (lr ? gp : -gp), gy, window_width, window_height); + } + } + } + else + for(int lr = 0; lr < 2; lr++) + { + uint16 srcX, srcY; + uint16 RealY = (block_no * 8) + y; + uint16 DestX; + uint16 DestY; + + srcX = mx + (lr ? mp : -mp); + srcY = my + (RealY - gy); + + DestX = gx + (lr ? gp : -gp); + DestY = gy; + + if(lron[lr]) + { + if(bgm == 1) // HBias + srcX += (int16)DRAM[(param_base + (((RealY - DestY) * 2) | lr)) & 0xFFFF]; + + DrawBG(fb[lr], RealY, lr, bgmap_base, over, overplane_char, (int32)(int16)srcX, (int32)(int16)srcY, scx, scy, DestX, DestY, window_width, window_height); + } + } + } + + if(bgm == BGM_OBJ) + if(obj_search_which) + obj_search_which--; + + } + + +} diff --git a/waterbox/vb/vsu.cpp b/waterbox/vb/vsu.cpp new file mode 100644 index 0000000000..d99b254509 --- /dev/null +++ b/waterbox/vb/vsu.cpp @@ -0,0 +1,498 @@ +/******************************************************************************/ +/* Mednafen Virtual Boy Emulation Module */ +/******************************************************************************/ +/* vsu.cpp: +** Copyright (C) 2010-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "vb.h" + +static const unsigned int Tap_LUT[8] = {15 - 1, 11 - 1, 14 - 1, 5 - 1, 9 - 1, 7 - 1, 10 - 1, 12 - 1}; + +VSU::VSU() +{ + Synth.volume(1.0 / 6 / 2); + + for (int ch = 0; ch < 6; ch++) + { + for (int lr = 0; lr < 2; lr++) + last_output[ch][lr] = 0; + } +} + +VSU::~VSU() +{ +} + +void VSU::SetSoundRate(double rate) +{ + for (int y = 0; y < 2; y++) + { + sbuf[y].set_sample_rate(rate ? rate : 44100, 50); + sbuf[y].clock_rate((long)(VB_MASTER_CLOCK / 4)); + sbuf[y].bass_freq(20); + } +} + +void VSU::Power(void) +{ + SweepControl = 0; + SweepModCounter = 0; + SweepModClockDivider = 1; + + for (int ch = 0; ch < 6; ch++) + { + IntlControl[ch] = 0; + LeftLevel[ch] = 0; + RightLevel[ch] = 0; + Frequency[ch] = 0; + EnvControl[ch] = 0; + RAMAddress[ch] = 0; + + EffFreq[ch] = 0; + Envelope[ch] = 0; + WavePos[ch] = 0; + FreqCounter[ch] = 1; + IntervalCounter[ch] = 0; + EnvelopeCounter[ch] = 1; + + EffectsClockDivider[ch] = 4800; + IntervalClockDivider[ch] = 4; + EnvelopeClockDivider[ch] = 4; + + LatcherClockDivider[ch] = 120; + } + + NoiseLatcherClockDivider = 120; + NoiseLatcher = 0; + + memset(WaveData, 0, sizeof(WaveData)); + memset(ModData, 0, sizeof(ModData)); + + last_ts = 0; +} + +void VSU::Write(int32 timestamp, uint32 A, uint8 V) +{ + A &= 0x7FF; + + Update(timestamp); + + //printf("VSU Write: %d, %08x %02x\n", timestamp, A, V); + + if (A < 0x280) + WaveData[A >> 7][(A >> 2) & 0x1F] = V & 0x3F; + else if (A < 0x400) + { + //if(A >= 0x300) + // printf("Modulation mirror write? %08x %02x\n", A, V); + ModData[(A >> 2) & 0x1F] = V; + } + else if (A < 0x600) + { + int ch = (A >> 6) & 0xF; + + //if(ch < 6) + //printf("Ch: %d, Reg: %d, Value: %02x\n", ch, (A >> 2) & 0xF, V); + + if (ch > 5) + { + if (A == 0x580 && (V & 1)) + { + //puts("STOP, HAMMER TIME"); + for (int i = 0; i < 6; i++) + IntlControl[i] &= ~0x80; + } + } + else + switch ((A >> 2) & 0xF) + { + case 0x0: + IntlControl[ch] = V & ~0x40; + + if (V & 0x80) + { + EffFreq[ch] = Frequency[ch]; + if (ch == 5) + FreqCounter[ch] = 10 * (2048 - EffFreq[ch]); + else + FreqCounter[ch] = 2048 - EffFreq[ch]; + IntervalCounter[ch] = (V & 0x1F) + 1; + EnvelopeCounter[ch] = (EnvControl[ch] & 0x7) + 1; + + if (ch == 4) + { + SweepModCounter = (SweepControl >> 4) & 7; + SweepModClockDivider = (SweepControl & 0x80) ? 8 : 1; + ModWavePos = 0; + } + + WavePos[ch] = 0; + + if (ch == 5) // Not sure if this is correct. + lfsr = 1; + + //if(!(IntlControl[ch] & 0x80)) + // Envelope[ch] = (EnvControl[ch] >> 4) & 0xF; + + EffectsClockDivider[ch] = 4800; + IntervalClockDivider[ch] = 4; + EnvelopeClockDivider[ch] = 4; + } + break; + + case 0x1: + LeftLevel[ch] = (V >> 4) & 0xF; + RightLevel[ch] = (V >> 0) & 0xF; + break; + + case 0x2: + Frequency[ch] &= 0xFF00; + Frequency[ch] |= V << 0; + EffFreq[ch] &= 0xFF00; + EffFreq[ch] |= V << 0; + break; + + case 0x3: + Frequency[ch] &= 0x00FF; + Frequency[ch] |= (V & 0x7) << 8; + EffFreq[ch] &= 0x00FF; + EffFreq[ch] |= (V & 0x7) << 8; + break; + + case 0x4: + EnvControl[ch] &= 0xFF00; + EnvControl[ch] |= V << 0; + + Envelope[ch] = (V >> 4) & 0xF; + break; + + case 0x5: + EnvControl[ch] &= 0x00FF; + if (ch == 4) + EnvControl[ch] |= (V & 0x73) << 8; + else if (ch == 5) + { + EnvControl[ch] |= (V & 0x73) << 8; + lfsr = 1; + } + else + EnvControl[ch] |= (V & 0x03) << 8; + break; + + case 0x6: + RAMAddress[ch] = V & 0xF; + break; + + case 0x7: + if (ch == 4) + { + SweepControl = V; + } + break; + } + } +} + +INLINE void VSU::CalcCurrentOutput(int ch, int &left, int &right) +{ + if (!(IntlControl[ch] & 0x80)) + { + left = right = 0; + return; + } + + int WD; + int l_ol, r_ol; + + if (ch == 5) + WD = NoiseLatcher; //(NoiseLatcher << 6) - NoiseLatcher; + else + { + if (RAMAddress[ch] > 4) + WD = 0; + else + WD = WaveData[RAMAddress[ch]][WavePos[ch]]; // - 0x20; + } + l_ol = Envelope[ch] * LeftLevel[ch]; + if (l_ol) + { + l_ol >>= 3; + l_ol += 1; + } + + r_ol = Envelope[ch] * RightLevel[ch]; + if (r_ol) + { + r_ol >>= 3; + r_ol += 1; + } + + left = WD * l_ol; + right = WD * r_ol; +} + +void VSU::Update(int32 timestamp) +{ + //puts("VSU Start"); + int left, right; + + for (int ch = 0; ch < 6; ch++) + { + int32 clocks = timestamp - last_ts; + int32 running_timestamp = last_ts; + + // Output sound here + CalcCurrentOutput(ch, left, right); + Synth.offset_inline(running_timestamp, left - last_output[ch][0], &sbuf[0]); + Synth.offset_inline(running_timestamp, right - last_output[ch][1], &sbuf[1]); + last_output[ch][0] = left; + last_output[ch][1] = right; + + if (!(IntlControl[ch] & 0x80)) + continue; + + while (clocks > 0) + { + int32 chunk_clocks = clocks; + + if (chunk_clocks > EffectsClockDivider[ch]) + chunk_clocks = EffectsClockDivider[ch]; + + if (ch == 5) + { + if (chunk_clocks > NoiseLatcherClockDivider) + chunk_clocks = NoiseLatcherClockDivider; + } + else + { + if (EffFreq[ch] >= 2040) + { + if (chunk_clocks > LatcherClockDivider[ch]) + chunk_clocks = LatcherClockDivider[ch]; + } + else + { + if (chunk_clocks > FreqCounter[ch]) + chunk_clocks = FreqCounter[ch]; + } + } + + if (ch == 5 && chunk_clocks > NoiseLatcherClockDivider) + chunk_clocks = NoiseLatcherClockDivider; + + FreqCounter[ch] -= chunk_clocks; + while (FreqCounter[ch] <= 0) + { + if (ch == 5) + { + int feedback = ((lfsr >> 7) & 1) ^ ((lfsr >> Tap_LUT[(EnvControl[5] >> 12) & 0x7]) & 1) ^ 1; + lfsr = ((lfsr << 1) & 0x7FFF) | feedback; + + FreqCounter[ch] += 10 * (2048 - EffFreq[ch]); + } + else + { + FreqCounter[ch] += 2048 - EffFreq[ch]; + WavePos[ch] = (WavePos[ch] + 1) & 0x1F; + } + } + + LatcherClockDivider[ch] -= chunk_clocks; + while (LatcherClockDivider[ch] <= 0) + LatcherClockDivider[ch] += 120; + + if (ch == 5) + { + NoiseLatcherClockDivider -= chunk_clocks; + if (!NoiseLatcherClockDivider) + { + NoiseLatcherClockDivider = 120; + NoiseLatcher = ((lfsr & 1) << 6) - (lfsr & 1); + } + } + + EffectsClockDivider[ch] -= chunk_clocks; + while (EffectsClockDivider[ch] <= 0) + { + EffectsClockDivider[ch] += 4800; + + IntervalClockDivider[ch]--; + while (IntervalClockDivider[ch] <= 0) + { + IntervalClockDivider[ch] += 4; + + if (IntlControl[ch] & 0x20) + { + IntervalCounter[ch]--; + if (!IntervalCounter[ch]) + { + IntlControl[ch] &= ~0x80; + } + } + + EnvelopeClockDivider[ch]--; + while (EnvelopeClockDivider[ch] <= 0) + { + EnvelopeClockDivider[ch] += 4; + + if (EnvControl[ch] & 0x0100) // Enveloping enabled? + { + EnvelopeCounter[ch]--; + if (!EnvelopeCounter[ch]) + { + EnvelopeCounter[ch] = (EnvControl[ch] & 0x7) + 1; + + if (EnvControl[ch] & 0x0008) // Grow + { + if (Envelope[ch] < 0xF || (EnvControl[ch] & 0x200)) + Envelope[ch] = (Envelope[ch] + 1) & 0xF; + } + else // Decay + { + if (Envelope[ch] > 0 || (EnvControl[ch] & 0x200)) + Envelope[ch] = (Envelope[ch] - 1) & 0xF; + } + } + } + + } // end while(EnvelopeClockDivider[ch] <= 0) + } // end while(IntervalClockDivider[ch] <= 0) + + if (ch == 4) + { + SweepModClockDivider--; + while (SweepModClockDivider <= 0) + { + SweepModClockDivider += (SweepControl & 0x80) ? 8 : 1; + + if (((SweepControl >> 4) & 0x7) && (EnvControl[ch] & 0x4000)) + { + if (SweepModCounter) + SweepModCounter--; + + if (!SweepModCounter) + { + SweepModCounter = (SweepControl >> 4) & 0x7; + + if (EnvControl[ch] & 0x1000) // Modulation + { + if (ModWavePos < 32 || (EnvControl[ch] & 0x2000)) + { + ModWavePos &= 0x1F; + + EffFreq[ch] = (EffFreq[ch] + (int8)ModData[ModWavePos]); + if (EffFreq[ch] < 0) + { + //puts("Underflow"); + EffFreq[ch] = 0; + } + else if (EffFreq[ch] > 0x7FF) + { + //puts("Overflow"); + EffFreq[ch] = 0x7FF; + } + ModWavePos++; + } + //puts("Mod"); + } + else // Sweep + { + int32 delta = EffFreq[ch] >> (SweepControl & 0x7); + int32 NewFreq = EffFreq[ch] + ((SweepControl & 0x8) ? delta : -delta); + + //printf("Sweep(%d): Old: %d, New: %d\n", ch, EffFreq[ch], NewFreq); + + if (NewFreq < 0) + EffFreq[ch] = 0; + else if (NewFreq > 0x7FF) + { + //EffFreq[ch] = 0x7FF; + IntlControl[ch] &= ~0x80; + } + else + EffFreq[ch] = NewFreq; + } + } + } + } // end while(SweepModClockDivider <= 0) + } // end if(ch == 4) + } // end while(EffectsClockDivider[ch] <= 0) + clocks -= chunk_clocks; + running_timestamp += chunk_clocks; + + // Output sound here too. + CalcCurrentOutput(ch, left, right); + Synth.offset_inline(running_timestamp, left - last_output[ch][0], &sbuf[0]); + Synth.offset_inline(running_timestamp, right - last_output[ch][1], &sbuf[1]); + last_output[ch][0] = left; + last_output[ch][1] = right; + } + } + last_ts = timestamp; + //puts("VSU End"); +} + +int32 VSU::EndFrame(int32 timestamp, int16 *SoundBuf, int32 SoundBufMaxSize) +{ + int32 ret = 0; + + Update(timestamp); + last_ts = 0; + + if (SoundBuf) + { + for (int y = 0; y < 2; y++) + { + sbuf[y].end_frame(timestamp); + ret = sbuf[y].read_samples(SoundBuf + y, SoundBufMaxSize, 1); + } + } + + return ret; +} + +uint8 VSU::PeekWave(const unsigned int which, uint32 Address) +{ + assert(which <= 4); + + Address &= 0x1F; + + return (WaveData[which][Address]); +} + +void VSU::PokeWave(const unsigned int which, uint32 Address, uint8 value) +{ + assert(which <= 4); + + Address &= 0x1F; + + WaveData[which][Address] = value & 0x3F; +} + +uint8 VSU::PeekModWave(uint32 Address) +{ + Address &= 0x1F; + return (ModData[Address]); +} + +void VSU::PokeModWave(uint32 Address, uint8 value) +{ + Address &= 0x1F; + + ModData[Address] = value & 0xFF; +} diff --git a/waterbox/vb/vsu.h b/waterbox/vb/vsu.h new file mode 100644 index 0000000000..c8230beb85 --- /dev/null +++ b/waterbox/vb/vsu.h @@ -0,0 +1,93 @@ +/******************************************************************************/ +/* Mednafen Virtual Boy Emulation Module */ +/******************************************************************************/ +/* vsu.h: +** Copyright (C) 2010-2016 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#pragma once + +class VSU +{ + public: + VSU() + MDFN_COLD; + ~VSU() MDFN_COLD; + + void SetSoundRate(double rate) MDFN_COLD; + + void Power(void) MDFN_COLD; + + void Write(int32 timestamp, uint32 A, uint8 V); + + int32 EndFrame(int32 timestamp, int16 *SoundBuf, int32 SoundBufMaxSize); + + uint8 PeekWave(const unsigned int which, uint32 Address); + void PokeWave(const unsigned int which, uint32 Address, uint8 value); + + uint8 PeekModWave(uint32 Address); + void PokeModWave(uint32 Address, uint8 value); + + private: + void CalcCurrentOutput(int ch, int &left, int &right); + + void Update(int32 timestamp); + + uint8 IntlControl[6]; + uint8 LeftLevel[6]; + uint8 RightLevel[6]; + uint16 Frequency[6]; + uint16 EnvControl[6]; // Channel 5/6 extra functionality tacked on too. + + uint8 RAMAddress[6]; + + uint8 SweepControl; + + uint8 WaveData[5][0x20]; + + uint8 ModData[0x20]; + + int32 EffFreq[6]; + int32 Envelope[6]; + + int32 WavePos[6]; + int32 ModWavePos; + + int32 LatcherClockDivider[6]; + + int32 FreqCounter[6]; + int32 IntervalCounter[6]; + int32 EnvelopeCounter[6]; + int32 SweepModCounter; + + int32 EffectsClockDivider[6]; + int32 IntervalClockDivider[6]; + int32 EnvelopeClockDivider[6]; + int32 SweepModClockDivider; + + int32 NoiseLatcherClockDivider; + uint32 NoiseLatcher; + + uint32 lfsr; + + int32 last_output[6][2]; + int32 last_ts; + + Blip_Buffer sbuf[2]; + Blip_Synth Synth; + Blip_Synth NoiseSynth; +}; diff --git a/wonderswan/mingw/Makefile b/wonderswan/mingw/Makefile index 03e7b90727..da7f3d57cf 100644 --- a/wonderswan/mingw/Makefile +++ b/wonderswan/mingw/Makefile @@ -4,7 +4,7 @@ CP = cp MACHINE = $(shell $(CXX) -dumpmachine) ifneq (,$(findstring i686,$(MACHINE))) - ARCH = 32 + $(error 32 bit build no longer supported) else ifneq (,$(findstring x86_64,$(MACHINE))) ARCH = 64 else @@ -19,7 +19,7 @@ LDFLAGS_64 = LDFLAGS = -shared $(LDFLAGS_$(ARCH)) $(CXXFLAGS) DEST_32 = ../../output/dll -DEST_64 = ../../output64/dll +DEST_64 = ../../output/dll SRCS = \ ../eeprom.cpp \ diff --git a/yabause/AUTHORS b/yabause/AUTHORS deleted file mode 100644 index c9230113fc..0000000000 --- a/yabause/AUTHORS +++ /dev/null @@ -1,36 +0,0 @@ -Current team ------------- -Theo Berkau -Guillaume Duhamel -Filipe Azevedo (pasnox) -Lawrence Sebald (BlueCrab) - -Contributors ------------- -Anders Montonen (antime) -Andrew Church -Ari64 -Michele Balistreri -Richard Dolinsky (menace690) -Lucas Newman (Adam Green) -Joost Peters -Jerome Vernet -Takashi Kiyohara -Weston Yager -Ex-Cyber -Romulo Fernandes (nightz) -pa__ -Fabien Coulon -trap15 -devmiyax - -Translators ------------ -Benjamin Siskoo -Felipe2 - -(people we grabbed code from) ------------- -Stephane Dallongeville - c68k and scsp -Patrick Kooman - profiler -Bart Trzynadlowski - sh2 disassembler diff --git a/yabause/CMakeLists.txt b/yabause/CMakeLists.txt deleted file mode 100644 index c5e3c2d0e6..0000000000 --- a/yabause/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -project(yabause) - -cmake_minimum_required(VERSION 2.8) - -set(YAB_PACKAGE yabause) -set(YAB_VERSION_MAJOR 0) -set(YAB_VERSION_MINOR 9) -set(YAB_VERSION_PATCH 12) -set(YAB_VERSION "${YAB_VERSION_MAJOR}.${YAB_VERSION_MINOR}.${YAB_VERSION_PATCH}") - -set(CPACK_SOURCE_GENERATOR TGZ) -set(CPACK_PACKAGE_VERSION_MAJOR ${YAB_VERSION_MAJOR}) -set(CPACK_PACKAGE_VERSION_MINOR ${YAB_VERSION_MINOR}) -set(CPACK_PACKAGE_VERSION_PATCH ${YAB_VERSION_PATCH}) -set(CPACK_PACKAGE_VENDOR "Yabause team") -set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") -set(CPACK_SOURCE_PACKAGE_FILE_NAME "yabause-${YAB_VERSION}") - -if (APPLE) - set(CPACK_GENERATOR DragNDrop) - set(CPACK_PACKAGE_FILE_NAME yabause-${YAB_VERSION}-mac) -endif () - -if (WIN32) - SET(CPACK_NSIS_INSTALLED_ICON_NAME yabause.exe) - set(CPACK_NSIS_MENU_LINKS yabause.exe;Yabause) - set(CPACK_NSIS_URL_INFO_ABOUT "http://yabause.org") - set(CPACK_NSIS_COMPRESSOR "/SOLID lzma") -endif () - -include(CPack) - -add_subdirectory(doc) -add_subdirectory(l10n) -add_subdirectory(src) diff --git a/yabause/COPYING b/yabause/COPYING deleted file mode 100644 index 41aa952bd8..0000000000 --- a/yabause/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/yabause/ChangeLog b/yabause/ChangeLog deleted file mode 100644 index 14cab09654..0000000000 --- a/yabause/ChangeLog +++ /dev/null @@ -1,924 +0,0 @@ -0.9.11 -> 0.9.12 - general: - - Fixes to the dynamic recompiler (Ari64) - - Added ARMv5 support to the dynarec (Ari64) - - New OSD system (Guillaume) - - Added "built-in" DDK to make it easier to compile on Windows (Guillaume) - sound: - - Improvements / Fixes in both SCSP and SCSP2 (Cwiiis) - video: - - Major improvements to the OpenGL renderer (Devmiyax) - - Major improvements to the software renderer (Guillaume) - - Some fixes to register emulation (Guillaume) - - Improvements to line drawing functions in the software renderer (Cwiiis) - - Fixed endianess bugs (Guillaume) - cocoa port: - - Added "load image" feature (BlueCrab) - - Fixed the resize bug (BlueCrab) - qt port: - - Added shortcuts to toggle vdp2 layers (Benjamin Siskoo) - - Fixed the "mute sound" feature (Guillaume) - - It's now possible to compile the Qt port in "full software" mode (Guillaume) - - Added an autostart option, disabled by default (Guillaume) - - Now using a XDG compliant location for config file (Guillaume) - - Added a debugger to the Qt port (CyberWarriorX) - - DirectX cores can now be used in Qt port (CyberWarriorX) - - Cheat search function (CyberWarriorX) - - Option to show/hide menu and toolbar (Guillaume) - - Close button in pad settings (guillaume) -0.9.10 -> 0.9.11 - general: - - Now using CMake as the default build system. - For now, autotools based build and "custom" build systems are still supported. - - New Cocoa port - - Added a dynamic recompiling SH2 core for x86 and ARM - - New SCSP implementation - - Major update of the software renderer from the yabause-rr team - - Added an option to allow to execute from the cache - - Improvements to the OpenGL renderer - carbon port: - - Improvements - gtk port: - - Added command line option to enable/disable frame skipping / limiting. - - Added frame skipping/limiting configuration in settings. - - Added --autoload command line option - - Vdp2 layers can be toggled from the Vdp2 debug window - psp port: - - Added support for Media Engine CPU - - Improvements to the PSP port - qt port: - - Added command line support - wii port: - - Merged some stuff from the wiibrew fork, mostly related to SH2 emulation - windows port: - - Fixed the XBox controller driver - - Fixed the "open iso then cancel bug" -0.9.9 -> 0.9.10 - scsp/68k: - - Added code to make SCSP emulation frame-accurate (optional, - enabled with --enable-scsp-frame-accurate configure switch). - - Added a new 68000 emulation core. - software video core: - - Added line scroll emulation. - - Improved user clipping. - - Added some basic vertical scroll emulation, enough to get - Sonic Jam working. - gtk port - - Gtk port is now compiling on Mac OS X. - - Fixed full software screenshots. - - Fixed store function in transfer dialog. - windows port: - - Added 12 player support. - - Fixed a bug that was causing the memory transfer dialog - to register the wrong filename after pressing "Browse". - - Fixed bugs in Goto Address dialog. - - Fixed a bug that was causing the vdp2 viewer dialog - to register the wrong filename after pressing "Browse". - - Added MD saving in SCU DSP debug dialog. - - Added new Ram Watch dialog. - - Added video recording feature. - - Added move recording feature. - general: - - Added Lithuanian translation. - - New sound core using OpenAL. - - Added joystick core for Mac OS X. - - Added a joystick core for Linux. - - Added a PSP port. - - Added support for loading ELF binaries. - - Now using gettimeofday when available for better resolution. - - Fixed save states. -0.9.8 -> 0.9.9 - opengl video core: - - Fixed a bug that was causing some games to - crash (albert odyssey, dragon ball, etc.) - gtk port: - - Automatic detection of current locale. - qt port: - - Added support of DESTDIR and --program-prefix - - Automatic detection of current locale. - - Added support for multiple players. - windows port: - - Fixed crash when going into settings. - - Fixed mouse wheel usage in disassembler. - - Rewrote as an unicode application. - - Fixed the key configuration problem. - - Fixed joypad support. - - Partial fix for mouse wheel and slider problem. - - Fixed fullscreen bug. - general: - - Hooks for renaming .desktop on installation. - - .yts file are now installed. - - Fixed parallel builds. - - SDL peripheral core now handles all connected - joysticks. -0.9.7 -> 0.9.8 - vdp2: - - Fixed a bug in software renderer with rotating - backgrounds. - opengl video core: - - Added gouraud shading and mesh processing. - This is not enabled by default. - software video core: - - Fixed user clipping. - gtk port: - - Added mouse support. - - Configuration dialog now displays key names instead - of values. Also made it so each different configuration - is saved. This broke compatibility with old .ini files. - windows port: - - Support for spaces in filenames when using CLI. - - Added mouse support. - - Added cheat search. - general: - - Added mouse emulation. - - Added de, es, it, pt-br and sv translations - - Support for "out of src" build. - - Fixed compilation for non supported platforms. - For instance this should fix compilation on dragonfly bsd. - Fixed compilation on GNU/Hurd too. -0.9.6 -> 0.9.7 - vdp1: - - Added clipping for line-based drawing to software renderer. - vdp2: - - Toggling a screen is now core independent. - - Added per-character priority to software renderer. - gtk port: - - Fixed fullscreen setting and added a keep ratio one. - - Fixed a bug in the vdp2 debugger that was causing the emu to crash. - - Full software mode can be compiled again. - - Fixed segfault when taking screenshots in full software mode. - - Fixed default value for region. - - Window position is now saved and restored when re-opening the emu. - - Fixed a problem when changing input cores. - qt port: - - Improved compilation process: make (un)install now works. - - Fix crash when configuring input while using translated version. - windows port: - - Changed resolution list generation so it adds the resolution to the list, - regardless of whether it supports 60 hz or not. - - Fixed error when trying to add blank cheat code. - - Fixed all code that allowed the user to choose filename for saving so it - automatically places a default extension. - - Save and Clear buttons are now enabled when loading a cheat file. - - Fixed a bug with AR code adding where it was tracking the wrong edit - window. - - Fixed a bug when adding raw cheat codes. - - Fixed bugs in vdp1 debugger. - - Fixed a bug where saving/loading a save state and an error occured would - cause sound looping. - - Scroll bar in memory editor now works properly when you move the thumb - control. - - Added support for x64 builds in Visual Studio. - general: - - Fixed a bug that was causing older save states to fail. -0.9.5 -> 0.9.6 - sdl joystick core: - - Fixed it... - software video core: - - Improvements and bug fixes. - carbon port: - - Added detection of sdk in the build process. - - Changed the cd core so that the first device found is used. - Users shouldn't have anything to set up when using cd device now. - gtk port: - - Tagged more strings to be translatable. - - Fixed bugs when setting a resolution in settings. - - Fixed controller settings so keys can now be configured even if - emulation is not started. - qt port: - - Removed libsjw core. - wii port: - - Updated to use the last devkitppc. - - Added support for classic controller and for wiimote, disabled - keyboard support. - windows port: - - Added command line support. - general: - - Updated copyright for some files where it was missing or - inaccurate. - - Fixes and improvements to the build process: fixed cross compilation - of Qt port, added Wii port support, found a better way to "trigger" - compilation of gen68k, fixed a bug when calling the sub-configure, - .inc files are now cleaned, added MINI18N variable support, forwarded - distclean rule to qt makefiles, configure now make sure the compiler - is a cross compiler when cross compiling - - Added a workaround for the "limits.h" problem... now distros should - fix their headers... - - Fixed the .desktop files for linux (gtk + qt ports) - - Added translation files for fr and pt in the repository. -0.9.4 -> 0.9.5 - 68k: - - Added 1010 and 1111 line emulator support. - cd block: - - Reworked bin/cue support. Reading should be a lot more accurate - now on tracks 2 and greater. - emulated bios: - - Fixed a bug in BupGetDate year calculation. - - Fixed a bug where interrupt mask wasn't being set correctly when - using emulated bios. - smpc: - - Added support for SMPC NMIREQ command. - - Added reset button emulation. - software video core: - - Improved software renderer: window, line scroll, mosaic are now - available and color offset and scroll screen has been fixed. - gtk port: - - Tagged most of gtk port strings to be translatable. - qt port: - - Added ability to specify address where binaries are loaded when - using command line. - - Other bug fixes. - wii port: - - Added support for bios and game loading from sd card. - - Added sound support. - - Added usb keyboard support. - windows port: - - Added pause emulation function. - - Other bug fixes. - dreamcast port: - - Rewrote all of the Dreamcast CD Interface in hand-optimized - assembly. - - Enabled use of the emulated bios if there is no saturn.bin on - the CD. - general: - - Updated peripheral interface so both ports can now be used and - multiple pads can now be connected to each port. - - Added translation support through mini18n library. -0.9.3 -> 0.9.4 - scsp: - - Fixed a timer bug. - - Fixed a bug with mcire word writes. - - Added wave file output core to available sound cores. - - Fixed a bug in total level attenuation. - - Fixed a bug in EG. - gtk port: - - Redesigned memory dump window. - - Redesigned SH2 debug window. - - Other bug fixes. - qt port: - - Added initial support. It should be pretty much on par with the gtk port. - wii port: - - Added initial support. - windows port: - - Fixed a bug where emulation wasn't paused when save/load state as was - selected from the menu. - - Changed disassembler so it can scroll up and down. - - Tweaked error messages so it doesn't report invalid opcode errors when - running the fast interpreter. - - Added SCSP common control register debug info to SCSP debug dialog - - Other bug fixes. - general: - - Added a few internal tweaks that should yield some performance gains. - - Added support for saving and loading cheats. -0.9.2 -> 0.9.3 - cart: - - Fixed a couple of bugs with Netlink emulation. - cd block: - - Tweaked error handling for cue files so it's more helpful to the user. - scu: - - Fixed a bug in DSP MVI instruction. - - Fixed a bug with DSP Program Ram Address. - - Fixed ALU behaviour on NOP. - - Other bug fixes. - vdp2: - - Fixed a bug where coefficient reading wasn't making sure reads weren't - going out of bounds. - - Tweaked frame-skipping so it only skips if frame time is faster/slower - than a 1/2 a frame. The results are much better now. - - Added general VDP2 debug info functionality. - - Added partial end code support to VDP1 texture debugging. - opengl video core: - - Fixed a bug in 16 BPP sprites where pixels 0x0001-0x7FFF weren't - transparent when transparency was enabled. - gtk port: - - Redesigned the window so each part can now be resized. - - Added a toolbar and removed the buttons. - - The sprite list now displays texture thumbnails. - - Added tooltips to "run" and "pause" buttons. - - Redesigned VDP2 debug window. - windows port: - - Fixed a bug that was causing Yabause to crash when run for the first time. - - Added screen capture. - - Reworked Input dialog so it'll allow for more than one peripheral(in the - future). - - Added a bunch of tools tips for basic and input settings. - - Fixed a bug that was causing wrong VDP1 command information to sometimes - be displayed. - - Other bug fixes. - - Fixed a bug that was causing the wrong breakpoint to be removed from the - breakpoint list. - - Text length is now limited correctly in breakpoint edit text controls. - general: - - Tweaked memory breakpoints so that regardless of whether you're using - cached or cache-through addresses variations of an address, it'll still - detect and break when the memory is accessed. - - Other bug fixes. -0.9.1 -> 0.9.2 - cd block: - - Fixed a bug in periodic timing. Most movies should play correctly now. - - Other bug fixes - scsp: - - Fixed a bug that was causing reversed panning. - - Fixed a bug in SCSP slot debug stats. - sh2: - - Fixed a bug that caused Yabause to crash when fetching instructions from - some areas. - vdp2: - - Fixed undocumented plane size setting when debugging vdp2 - - Special Color Calculation mode added to vdp2 debugging - opengl video core: - - Added the eight missing sprite types in Vdp1ReadPriority. - software video core: - - Fixed a bug where Polygons that used non-RGB values had the wrong - priority. - - Fixed a bug that was causing some scrolling issues. - gtk port: - - CD, sound, and video cores can now be changed without restarting the - emulator. - - Added basic support for save states. - windows port: - - Fixed compilation with MSYS. - - Changed SCSP debug dialog so it allows for individual slot saving. - - Fixed a bug when using goto address in memory editor. - - Fixed a bug where Yabause crashed when joystick was unplugged. - - Added memory search support. - - Fixed cheat dialog. Codes should show up after re-opening it. - general: - - Fixed some bugs where vdp1/vdp2 layers wouldn't be drawn after switching - video cores. - - Fixed a bug when switching between opengl and software video cores. - - Added memory search function. -0.9.0 -> 0.9.1 - scsp: - - Fixed slot pitch LFO. Amplitude LFO is probably more accurate now too. - emulated bios: - - Added Backup RAM manager functions. - opengl video core: - - Fixed a bug with VDP2 2x2 plane size rotation screens. - - Optimized tile mode rotation screens - - Added support for VDP1 polyline. - software video core: - - FPS display now working. - - Added support for VDP2 rotation without coefficient tables. - - Fixed a bug in VDP2 24 BPP bitmap mode. - - Fixed several clipping bugs in Normal and Scaled Sprites. - - Fixed a bug with VDP2 2x2 plane size rotation screens. - - Optimized tile mode rotation screens. - linux port: - - Cursor now disappears after 2 seconds of inactivity in the gtk port. - macos port: - - New high resolution icon. - - Add some missing OS X application property list keys. - windows port: - - Fixed window position bug. - - Other bug fixes. - general: - - Tweaked frame timing code so it's more accurate. - - Re-implemented save states. - - Some internal changes do so that sound, video, and cd cores can be changed - at runtime. -0.8.6 -> 0.9.0 - opengl video core: - - Added support for VDP1 line draw. - - Added support for VDP2 Rotation with coefficient tables. - - Other bug fixes. - software video core: - - Added support for VDP1 frame buffer switching. - - Added support for VDP2 Rotation with coefficient tables. - - Fixed a bug in frame buffer erasing. - - Other bug fixes. - linux port: - - Fixed a bug on 64 bits CPU. - - Hanged the location of the ini file to conform to XDG specification. - - Removed some old useless code. - - Added a "subclass" to GtkDrawingArea so sprite textures and screenshots - can now be saved through a popup menu. - macos port: - - Added fullscreen support. - - Added graphics layer toggling. - windows port: - - Fixed a stack corruption bug in DirectInput code. - - Fixed(hopefully this time) the joystick centering bug. -0.8.5 -> 0.8.6 - 68k: - - Fixed a bug which caused the emulator to crash if 68k execution jumped to - an invalid address. - scsp: - - Fixed a bug where the slot buffer pointers weren't set correctly. - - Added a function for debugging SCSP registers - vdp1: - - MODR returns the correct version number now. - - Fixed a bug that caused Local Coordinates, etc. commands to not get executed - correctly. - software video core: - - Added vdp2 horizontal flip for cell mode. - linux port: - - Improved vdp1 window a bit. - - Updated website url. - - Some cleanups - macos port: - - Added browse buttons for some settings. - - Added universal build support. - - Emulation loop was optimized. - - Fixed bug when "Run" is selected from the menu. - - Audio is now muted when emulator is paused. - - Fixed Backup RAM saving. - - Fixed a bug that was causing filenames to be parsed wrong. - - Other bug fixes and cleanups. - windows port: - - msys compiling is now fixed. - - Windows position is now saved when program exits. - - Fixed sound volume adjustment. Should be more accurate now. - - Fixed centering bug on joysticks. - - Fixed POV hat diagonals. - - Sound is now muted in the about dialog. - - Other bug fixes. - general: - - Added COFF file support. -0.8.0 -> 0.8.5 - scsp: - - Added functions for dumping individual slots to wav files. - scu: - - Fixed SCU execution speed - sh2: - - Added DVDNTL/DVDNTH mirrors - - Added overflow interrupt - vdp1: - - Added function for displaying vdp1 textures for debugging - - Other bug fixes - vdp2: - - Added more RBG0 debug info - 68k: - - Added a core system for m68k and a c68k core interface. - - Added a dummy m68k core based on old yabause code, working enough - to boot the bios. - emulated bios: - - Registers are now reset correctly - - Fixed bug in BiosSetSh2Interrupt - - Added Read/Write Save support - - Added undocumented CD Authentication function - opengl video core: - - RBG0 bug fixes - - Rotation Screen improvements - software video core: - - Added 32 BPP cell draw mode - bsd port: - - Added support for OpenBSD - linux port: - - Fixed the segfault that occured when opening the preferences dialog. - - Added texture display in vdp1 debug dialog - - Other GUI improvements - macos port: - - Added browse button for bios setting - - Other bug fixes - windows port: - - Fixed a bug that was causing sound to not work on some people's computers. - - Added texture display in vdp1 debug dialog - - Added window/full screen resizing - - Added full screen on startup - - Settings changed to use tabs instead of what was previously used - - Other bug fixes - - Logging now is done to a logging window when DEBUG is defined while - compiling. - - Added cheat dialog - - Added memory editor - - Added Visual C++ project file - general: - - Added Cheat support. Largely untested. -0.7.2 -> 0.8.0 - cart: - - Moved Netlink code to its own file: netlink.c - - Improved Netlink AT command handling. Most games using the X-Band software - should work now. - - Fixed a number of bugs that were causing strange behaviour in Netlink - emulation. - - Added Modem states. Online Mode is now handled correctly. - - Added Networking code that allows two Yabause instances to communicate - with each other. Still somewhat buggy. - cd block: - - Fixed an issue where games that didn't specify an index along with the - track when playing cd audio didn't work correctly. - vdp1: - - Code cleanups. - vdp2: - - Code cleanups. - - Adjusted frameskip code so it skips up to a maximum of 9 frames at a time. - direct sound core: - - Fixed a bug that was screwing up the buffer position. Now it's almost - perfect(at the very least there's no clicks or pops anymore). - sdl sound core: - - Fixed a bug that was screwing up the buffer position. Now it's almost - perfect(at the very least there's no clicks or pops anymore). - software video core: - - Polygon drawing improvements - - Removed the silly y-axis clipping technique - - Added a filter for clipping detection - - Added vdp1 "end codes" in textures, but didn't find a game that use it - yet, please report bugs. - - Code Cleanups - - Fixed a potential bug in polygons - - Fixed a bug in polygon clipping - linux port: - - Code cleanups - - Changed a few things in configure script to fix compilation problems when - OpenGL and/or gtkglext were not present. - - Added a log popup window. - - Added a screenshot window on gtk port. - - Fixed Pause/Screenshot bug. - - Removed the "Keep ratio" setting as it can't be done in gtk and - replaced it by a "Fullscreen" setting. - - Added a yabause entry in gnome and KDE application menus - - Changed configure script so it fails on linux if --with-opengl is used - and gtlglext is not installed. - dreamcast port: - - Compiles and runs again. - - Added Normal Sprite support. - - Added Distorted Sprite support. - - Added Scaled Sprite support. - - Added in YabauseGetTicks support. - - Ported VDP2 portion of software renderer. - - Added new cd core. - - Added very simple GUI. - - Other bug fixes. - netbsd port: - - Added patch to get yabause working on netbsd with cd support thanks to - Takashi Kyohara. - windows port: - - Added pad configuration(first pad only). - - Added support for gamepads/joysticks. - - Removed duplicate cd code. - - Added a separate thread for cd access. SPTICDGetStatus is the only - function making use of it for now. - - Fixed fullscreen bug - - Added dialog and settings saving/loading for Netlink stuff(disabled for now). - - Other bug fixes. - general: - - Commited mac port fix by Antime. - - Coordinate Increment Registers are now set to 1 when using the quick load - function. It seems there's at least one game out there that doesn't want - to set it. - - Improved Backup Ram bios emulation functions. The only functions that - still aren't functioning correctly are Bup Write, Bup Read, Bup Verify, - and Bup Set/Get Date. So still no saving, but at least there's no errors - when running games now. -0.7.1 -> 0.7.2 - cart: - - A few Netlink changes(still doesn't work). - cd block: - - CD Block play disc command fixes and improvements. Play Modes now handled correctly. - - Added correct Repeat counter support. - - CD audio data is now written to its own buffer, which is then played by the SCSP. - scsp: - - CD audio data is now played by the SCSP. EFSDL and EFPAN support still needs to be added. - opengl video core: - - glutInit is now called before any other glut function(except for on the windows port). - software video core: - - Added normal sprite flipping(copied from scaled sprites). - - Corrected a bug with 8 bpp color calculation in scaled and distorted sprites. - - Fixed a bug that caused duplicated textures in 8 bpp regular sprites. - - Distorted sprites made safer (won't read outside the texture) - - Fixed transparency for distorted sprites. - - Fixed scaled sprites bug in zoom points modes two points mode and C point - upper than A. - - Fixed a bug that was causing sprite priority problems. - linux port: - - Fixed a gtk warning. - - Added Joystick support. - - Added a test in configuration dialog so input tab is displayed only when - emulation is initialized. - - Added NTSC/PAL setting - - Input settings are now disabled when PERCore isn't initialized. - - Added a sound setting tab. - macos port: - - Added code to handle settings (everything should be working now, except - the "browse" buttons). - - Controls are now using the new Per* functions. - - Fixed some bugs in combo boxes. - windows port: - - EC Compatibility list link added to help menu. - - Fixed an issue where default values weren't set correctly when yabause.ini - wasn't present. - - Fixed an issue where Yabause would go into an endless loop if bios path - was incorrect. - - DirectX error messages now return more info when there's an error. - - Fixed an issue where people without hardware sound buffers on their - sound card would have problems trying to run with sound. - - Fixed some inaccurate information in the README.WIN file. - - Fixed cut-off text in Memory Transfer dialog. - - All dialog windows can now be closed using the X icon in the top-right - corner. - general: - - Fixed an issue where in certain cases Yabause would crash when sound - settings were altered. - - Some useless files were removed. - - Moved SDL detection in "global" part of configure script as it may be used - by all ports. - - Fixed a weird issue where a few functions were trying to return a value - when they obviously can't(How come GNU C compilers won't detect this?). - - Fixed a number of things that were causing compilation issues in VC++(VC++ - still doesn't completely compile Yabause yet). - - Configure now checks if c99 variadic macros are available. -0.7.0 -> 0.7.1 - opengl video core: - - Added polygons that use a palette. - software video core: - - Added scaled sprites with clipping and flipping. - - Full screen mode now working correctly. - - Added correct support for vdp2 resolutions other than 320x224. - - Fixed compilation issue on big endian systems. - - Added function to software renderer for fetching width/height of the display buffer - - Memory leak when clearing VDP1 frame buffer fixed. - linux port: - - Added autostart and fullscreen command line switches. - - Fixed a bug that was causing the emulator to sometimes start in using PAL - timing. - - Added an option to choose the peripheral interface at configure time. - - Started to move the gtk controls code into a proper peripheral core. - - Added code so software renderer can be used without OpenGL. - - Added --without-opengl switch to configure script to prevent OpenGL - detection. - - Resizing is now enabled when using software renderer and opengl. - macos port: - - Fixed a bug that was causing the emulator to sometimes start in using PAL - timing. - - Some fixes to carbon interface (preferences should works now). - windows port: - - Fixed a bug that was causing the emulator to sometimes start in using PAL - timing. - - Added shortcuts to the Yabause website, forum, donation page, and the - submit bug page to the main menu. - - Added About dialog. - general: - - Fixed a potential issue when enabling/disabling auto frameskipping. -0.6.0 -> 0.7.0 - cart: - - Added Action Replay flash emulation. - cd block: - - Fixed Read Directory/Change Directory commands. This fixes Duke Nukem 3D - and a few others that have Netlink support. - - Audio data is no longer stored when read by the cd block. This fixes - Guardian Heroes. - - other bug fixes. - scsp: - - Added function that allows developers to get easy to read information on - the requested scsp sound slot. - - Fixed a bug where the phase wasn't getting updated if DISDL was set to 0. - This fixes Falcom Classics, Nadesico, and many other games using ADX. - - Fixed a bug that was causing OCT with a setting of 0x8 to play at the - wrong octave. - - Fixed a bug that was causing King of Fighters 95(and possibly others) to - go into an endless loop. - scu: - - Improved SCU interrupt handling. - sh2: - - Fixed a bug in exts.b opcode. - - Corrected some bugs in sh2idle - - SCI emulation improvements - smpc: - - Added proper DOTSEL reporting. - - Region settings are now properly preserved. - - Changed region autodetection so it defaults to the japanese region if - it can't autodetect. - 68k: - - Fixed a few bugs. - vdp2: - - Debug info bug fixes - - Implemented one mode of external HV latching. This fixes King of Fighters - 95. - - External latch and sync flags are now cleared on TVSTAT reading. - - Added speed throttle(basically skips 6 frame draws). - - Added long writes for VCSTA, LSTA0, and LSTA1 registers. - software video core: - - Rewrote it so it's no longer dependent on SDL. - - Added NBG2/NBG3 support. - - Added tile mode rendering. - - Added frame buffer emulation. - - Added normal sprite drawing. - - Changed Normal Sprite drawing so that Scaled Sprite and Distorted Sprite - functions can use it too. - - Added some support for Scaled/Distorted Sprites. - - Added VDP1 Polyline and Line drawing to Software renderer. - - Fixed a bunch of bugs. - opengl video core: - - Fixed a few issues with OpenGL initialization. - - Fixed a window/fullscreen bug. - - Added a smart Line Scroll/Vertical Cell Scroll interpreter. - - Changed Color Offset so it uses the same method as the Software renderer. - - Fixed Rotation Table reading. - - Fixed a bug in VIDOGLVdp1PolylineDraw where coordinate reads were writing - to invalid areas. - linux port: - - Removed some useless debug messages and fixed the "quit" menu entry. - - Added vdp1 debug dialog in new gtk interface. - - Added dialog for sh2, video core switching. - - Added reset menu entry. - - Added about dialog. - - Added MSH2 and SSH2 debug dialogs to the GTK interface. - - Added transfer dialog to the new gtk ui. - - Added empty Memory Dump dialog. - - Added the dialog box for scsp - - Added shortcut F7 for command Step - - Added support for memory breakpoints in sh2 debug dialog - - Sound is now muted when emulation is paused (in gtk interface). - - The window data is now saved while emulation is paused. - - Screenshot function added. - macos port: - - Added carbon interface - - Can now build .dmg image from .app directory - - Other improvements - windows port: - - Added SCSP Debug Dialog. - - Added Reset option to menu. - - Now uses DirectInput and DirectSound instead of SDL. - - Added dialog for video, sound and input core switching. - - Fixed window/fullscreen switching. - - Added support for memory breakpoints in sh2 debug dialog. - - Sound volume can now be adjusted in the settings dialog. - - Sound is now muted when dialog window has focus. - - Auto frameskip can be be enabled via video settings menu. - - Other bug fixes. - general: - - Better handling of NULL string when opening a file - - Fixed a few memory leaks - - ISO support fixes - - PAL support added - - Fixed v-blank timing - - Added auto frameskipping(still not working correctly) - - Improved sound buffering - - Fixed handling of invalid SH2 opcodes - - Dummy sound core bug fixes - - Fixed some warnings - - Added experimental bios emulation - - Added memory breakpoints - - Added a function to the sound cores for setting the volume. -0.5.0 -> 0.6.0 - cart: - - accesses to Netlink addresses when Netlink was not present was causing - errors, this has been fixed. - scu: - - fixed DSP debugging. - - fixed a Timer 0 bug. Fixes Shining the Holy Ark. - sh2: - - added SH2 idle detection. Speed should be significantly faster. - - separated original core(now the "debug interpreter core") from the core - with idle detection. - - sh2 cores are now selectable. - 68k: - - added 68k disassembler. - - fixed some warnings. - vdp1: - - added debugging functions. - - fixed bug that was causing garbage graphics in Albert Odyssey. - - fixed bug that was causing graphics in Legend of Oasis to not get drawn. - - other bug fixes. - vdp2: - - fixed a few priority bugs. - - added initial special priority emulation. - general: - - added fullscreen and fixed resize in Windows. Still needs quite a bit of - work. - - changed event handling a bit. Gained quite a bit of speed from it. - - fixed some Mac OS X port bugs. - - fixed some Dreamcast port bugs. - - added proper Linux gui. - - Fixed YGL initialization. - - fixed some Windows ports bugs - - other bug fixes. -0.0.7 -> 0.5.0 - cd block: - - bug fixes. - - improved timing. - cart: - - added Action Replay emulation. - - added 8/32 Mbit dram emulation. - - added 4/8/32 Mbit backup ram emulation. - - added 16 Mbit rom emulation. - - added very early Netlink emulation. - scsp: - - added Stephane Dallongeville's SCSP's core. Thanks again Stef! - - fixed a couple of bugs that were causing movies to lock up. - 68k: - - added Stephane Dallongeville's 68k's core. Thanks again Stef! - - fixed a few endian related bugs. - - added debugger(still need disassembler though). - scu: - - added dsp emulation. - - added dsp debugger. - - added indirect dma emulation. - - added timer0 emulation. - - bug fixes. - smpc: - - added very basic SH2 direct peripheral mode. - - added clock change commands. - - added slave sh2 off/on commands. - - fixed intback command timing. - - bug fixes. - sh2: - - added FRT, WDT, and partial UBC emulation. - - fixed a couple of opcode bugs. - - re-added debugger. - - added some early dynarec code. - vdp1: - - added sprite priorities. - - added color offset. - - bug fixes. - vdp2: - - added basic rbg0 emulation(no rotation, etc.). - - added backscreen emulation. - - added caching. - - added color offset. - - added video mode changing. - - added screen scrolling. - - fix caching bug. - - other bug fixes. - - added early software video rendering. It's still pretty much unuseable at this point. -general: - - added binary execution. - - rewrote entire code in C for portability and speed. - - fixed a number of configure bugs, added a few more command-line options. - - fixed code so it's 64-bit friendly. - - added iso and bin/cue files support. - - changed several parts of yabause to allow for multiple implementations of video, sound, and peripheral code.. - - added save states(currently broken unfortunately). - -0.0.6 -> 0.0.7 - cd block: - - added cd interface for porters. - - whole bunch of cd commands were added. Most games should now - start to boot. - - added region auto-detection. - mpeg card: - - added basic emulation. - - added mpeg rom loading support. - scsp: - - bug fixes. - scu: - - bug fixes. - smpc: - - bug fixes. - superh: - - fixed dma. - - lots of other bugfixes. - - opcode optimizations. - vdp1: - - added sprite caching. - - added scaled sprites. - - added sprite color modes 0, 1, 2, 3, 4. - - macosx color bug fixed. - - bug fixes. - vdp2: - - macosx color bug fixed. - - bug fixes. - general: - - added fps counter. - - switched to OpenGL, removed SDL_gfx. - - yui interface added. Now each port should be able to provide - a nice custom ui. - - threads removed, program should be more stable now. - - added save ram loading ability. - -0.0.5 -> 0.0.6 - scu - - added direct dma. - superh - - added division unit. - - fixed endianess issue. - vdp2 - - added NBG3. - - fixed color bug. - -0.0.4 -> 0.0.5 - vdp2: - - lot of work, the vdp2 is now capable of - displaying the set-clock screen of the - bios. - monitor/debugger: - - added memory dump possibility. - -0.0.2 -> 0.0.4 - monitor/debugger: - - added debugging possibility, can now pause/resume emulation - and execute instructions step by step; - - opcodes are disassembled interactively. - general: - - early emulations of different cpu/onchip modules: scu, vdp1 - and dmac; - - translate most of the code from french to english; - - added synchronisation between processors; - - yabause is now using SDL, remove all fork/ipc code and use - SDL_Thread instead. - -0.0.1 -> 0.0.2 - sh2: - - "mull" is now decoded; - - changed the way the opcodes are decoded, now using a table with pointers - to function, should be faster. - intc: - - now tests if the interrupt level is correct before accepting one. - vdp2: - - early emulation, just throws an interrupt every half-frame. - general: - - vdp1 and vdp2 are now synchronized with the master sh; - - fixed some memory bug, all the shared memory allocated is de-allocated; - - now using configure/make, should be more portable; - - modified things to be more c++ and less linux/c. diff --git a/yabause/GOALS b/yabause/GOALS deleted file mode 100644 index e2d43585ac..0000000000 --- a/yabause/GOALS +++ /dev/null @@ -1,8 +0,0 @@ -Goals for a 1.0.0 release --------------------------- --Full "stock" saturn emulation. At the very least it should be "feature complete"(most major bugs should be fixed at this point too) --Any external carts or peripheral do not need to be fully emulated at this point --Switchable SH2 Dynarec/Interpreter cores --Full debugging support --Speed should be high at this point(It's too tough ironing out those bugs with Yabause at its current state) --Save States diff --git a/yabause/INSTALL b/yabause/INSTALL deleted file mode 100644 index a4b34144dc..0000000000 --- a/yabause/INSTALL +++ /dev/null @@ -1,229 +0,0 @@ -Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software -Foundation, Inc. - - This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -Basic Installation -================== - - These are generic installation instructions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. (Caching is -disabled by default to prevent problems with accidental use of stale -cache files.) - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You only need -`configure.ac' if you want to change it or regenerate `configure' using -a newer version of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. - - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' -for details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - If you have to use a `make' that does not support the `VPATH' -variable, you have to compile the package for one architecture at a -time in the source code directory. After you have installed the -package for one architecture, use `make distclean' before reconfiguring -for another architecture. - -Installation Names -================== - - By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PATH'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PATH', the package will use -PATH as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=PATH' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - - There may be some features `configure' cannot figure out -automatically, but needs to determine by the type of machine the package -will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints -a message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the `--target=TYPE' option to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - - Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -will cause the specified gcc to be used as the C compiler (unless it is -overridden in the site shell script). - -`configure' Invocation -====================== - - `configure' recognizes the following options to control how it -operates. - -`--help' -`-h' - Print a summary of the options to `configure', and exit. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. - diff --git a/yabause/Makefile.am b/yabause/Makefile.am deleted file mode 100644 index f6f08ec7c3..0000000000 --- a/yabause/Makefile.am +++ /dev/null @@ -1,2 +0,0 @@ -SUBDIRS = src l10n -EXTRA_DIST = README.DC README.LIN README.MAC README.WIN GOALS README.QT README.WII README.PSP diff --git a/yabause/NEWS b/yabause/NEWS deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/yabause/README b/yabause/README deleted file mode 100644 index 7a7d0c9f98..0000000000 --- a/yabause/README +++ /dev/null @@ -1,103 +0,0 @@ - _ _ - / \_/ \ ___ _ ____ - \ /___ ___ / || | __ / \ ____ - \ // || \ / || | \ \\ \_// \ - / // || // _ || |__\ \\ \ __/ - \_// _ || \\_/ \_||______/ \ \\ \__ - \_/ \_||___/ \____/ \____\ - Yet Another Buggy And Uncomplete Saturn Emulator - - ____________________________________ - Copyright (c) 2002-2011 Yabause team - - -1) Introduction.............................................20 -2) Staff/Thanks.............................................39 -3) Contact information......................................75 -4) Disclaimer...............................................86 - - -1 Introduction________________________________________________ - -Yabause is a Sega Saturn emulator under GNU GPL. - -Yabause can boot Saturn bios and games, some of those games -are playable. - -For installation/how to use information, check the ports -specific README files: - - * README.DC for the dreamcast port - * README.LIN for the linux port - * README.MAC for the mac port - * README.PSP for the PSP port - * README.QT for the crossplatform Qt 4 port - * README.WII for the WII port - * README.WIN for the windows port - - -2 Staff/Thanks________________________________________________ - -See the AUTHORS file for team members list. - -Thanks to: - - * Runik (author of Saturnin), for all his help, especially - on the vdp2. - http://saturnin.consollection.com - - * Fabien Autrel (author of Satourne), - for letting me browse his sources. - http://satourne.consollection.com - - * Chuck Mason (author of semu), - for releasing semu sources and for his handy debugger. - - * Romain Vallet - for winning the "Find a name for my emu" contest, for - his contribution to this README and for this nice web - site he did. - http://romanito.free.fr/ - - * Stefano and all of segadev for their help. - - * Josquin Debaz - for writing the man page. - - * Bart Trzynadlowski - for his disassembler. - - * Charles MacDonald - for his saturn sample programs, docs, and being a major - source for saturn information. - - -3 Contact information_________________________________________ - -E-mail: guillaume@yabause.org -Web: http://yabause.org -IRC: irc://irc.freenode.net/yabause - -Please don't ask for roms, bios files or any other copyrighted -stuff. Please use the forum when you have any questions if -possible. - - -4 Disclaimer__________________________________________________ - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of -the License, or (at your option) any later version. - -This program is distributed in the hope that it will be -useful,but WITHOUT ANY WARRANTY; without even the implied -warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public -License along with this program; if not, write to the Free -Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301 USA - -See the GNU General Public License details in COPYING. diff --git a/yabause/README.DC b/yabause/README.DC deleted file mode 100644 index 87e238d9f8..0000000000 --- a/yabause/README.DC +++ /dev/null @@ -1,85 +0,0 @@ - _ _ - / \_/ \ ___ _ ____ - \ /___ ___ / || | __ / \ ____ - \ // || \ / || | \ \\ \_// \ - / // || // _ || |__\ \\ \ __/ - \_// _ || \\_/ \_||______/ \ \\ \__ - \_/ \_||___/ \____/ \____\ - Yet Another Buggy And Uncomplete Saturn Emulator - - ____________________________________ - Copyright (c) 2002-2011 Yabause team - - -1) Introduction.............................................20 -2) Compiling instructions...................................31 -2) How to use Yabause.......................................48 -4) Final Thoughts...........................................71 - - -1 Introduction________________________________________________ - -This file documents the Dreamcast version only, for general -information check the README file. Note, that if you are just -a casual user, and not a developer, you probably won't have -to worry about the Compiling instructions below. Pick up with -the section "How to use Yabause" to learn how to make a CD -image you can burn to use Yabause (or use a program like -Selfboot). - - -2 Compiling instructions______________________________________ - -Yabause is written in C using KallistiOS. So, in order to -compile it, you need a working sh-elf targetted C compiler, -such as gcc and a working KallistiOS environment: - - * http://gamedev.allusion.net - -Once KallistiOS is set up, you should be ready to build -Yabause. - -Uncompress the Yabause source archive, move to the newly -created directory, type "cd src", then "make -f Makefile.dc", -it will generate one binary: "yabause.bin" in the "src" -directory. - - -3 How to use Yabause__________________________________________ - -Before using Yabause, you need to build a CD with a few files -in the correct places. In order to build a CD with the -compiled binary, you must first scramble the binary. This can -be done with the scramble utility which can be obtained from -http://mc.pp.se/dc/files/scramble.c . This will have to be -compiled with your native compiler. Once you run the scramble -program on the yabause.bin file created in section 2 above, -you will have a binary file suitable for booting on a real -Dreamcast. - -Once you have your scrambled binary, you may choose to include -a Sega Saturn BIOS image on your disc as well. As of 0.9.5, -this is not a requirement for the Dreamcast port, but if you -choose to use an actual BIOS image, it must be put on the -root of the CD and named "saturn.bin". - -From this point, follow your favorite guide for how to build -a selfbooting CD out of plain files. I use the one available -at http://mc.pp.se/dc/cdr.html . - - -4 Final Thoughts______________________________________________ - -The Dreamcast port of Yabause is quite slow. I have done very -little in the way of optimizing any of the core of Yabause -toward the Dreamcast (there is quite a bit that could be done -when time allows). Do not expect the Dreamcast port of -Yabause to run your favorite Sega Saturn games at any sort of -playable speed for now (or the near future). As Yabause -matures, and I have more time to work on it, hopefully speed -will improve. For now, think of it as a fancy tech demo. - -Note that in 0.9.5, a small bit of assembly has appeared in -the Dreamcast port. Hopefully as time goes on more of the -Dreamcast specific code will be rewritten in assembly for at -least some small speed increase. diff --git a/yabause/README.LIN b/yabause/README.LIN deleted file mode 100644 index 0b65079552..0000000000 --- a/yabause/README.LIN +++ /dev/null @@ -1,135 +0,0 @@ - _ _ - / \_/ \ ___ _ ____ - \ /___ ___ / || | __ / \ ____ - \ // || \ / || | \ \\ \_// \ - / // || // _ || |__\ \\ \ __/ - \_// _ || \\_/ \_||______/ \ \\ \__ - \_/ \_||___/ \____/ \____\ - Yet Another Buggy And Uncomplete Saturn Emulator - - ____________________________________ - Copyright (c) 2002-2011 Yabause team - - -1) Introduction.............................................19 -2) Compiling instructions...................................25 -3) How to use Yabause......................................102 - - -1 Introduction________________________________________________ - -This file documents the gtk version only, for general -information check the README file. - - -2 Compiling instructions______________________________________ - -The Gtk+ port of Yabause is written in C and depends on the -Gtk+ library (thus the name). The recommended setup of the -Gtk+ port is to link it against OpenGL and gtkglext libraries, -but this is not mandatory; see "Full Software mode" for -further instructions. - -Yabause currently provides two build system, a legacy build -process using the autotools and a newer build process using -CMake. - - -2.1 Recommended setup_________________________________________ - -You need a working C compiler, such as gcc and the above -libraries runtime and development packages: - - * http://www.gtk.org - - * http://gtkglext.sourceforge.net - - * OpenGL should be included with your compiler, if it isn't, - check on your distribution's website for links. - - * http://www.cmake.org, you'll need a CMake version >= 2.8 - -With those libraries, you'll get a working Yabause, but with -some restrictions: - - * No sound - - * No translations - - * Depending on your OS, keyboard input only - -You may want to install some optional dependencies for a -better experience. - - -2.2 Optional libraries________________________________________ - -Yabause can use a number of optional libraries: - - * SDL: provides sound and joystick support - http://www.libsdl.org/ - - * OpenAL: provides sound support - - * mini18n: provides translation support - - -2.3 Compiling_________________________________________________ - -For the build process, we recommend using two directories: one -for the Yabause sources (SOURCES) and one for the build (BUILD) - -Uncompress the Yabause source archive into the $SOURCES dir -and create the $BUILD directory. - -Move to the build directory and type "cmake $SOURCES" then -"make" it will generate one program: "yabause" in the "src/gtk" -directory. - -You can even type "make install" to install that program on -your system (in /usr/local/ by default), but we don't support -desinstalling it. - - -2.4 Full Software mode________________________________________ - -The Gtk+ supports building without OpenGL support. - -cmake -DYAB_WANT_OPENGL=NO $SOURCES -make - - -3 How to use Yabause__________________________________________ - -Before using Yabause, you need to configure a few things in -the Preferences dialog (Yabause>Preferences). - - -3.1 Configuration_____________________________________________ - -First, set the BIOS path. -Yabause can run some games without a BIOS, but most of them -needs it. If you want to use the emulated BIOS, just let the -BIOS entry blank. - -Next, set the cdrom device. -It can be a cd device, an iso or a cue file. Set the cd type -accordingly. - -The last thing you have to configure is the keys. - -Once eveything is set, you can start emulation with the -"Yabause>run" entry. - - -3.2 Command line arguments____________________________________ - --b (or --bios=) - Specify bios file. --c (or --cdrom=) - Specify cd device. You can know which file is used as cd - device by looking in /etc/fstab. It is commonly something - like /dev/hdc or /dev/hdd for IDE devices and /dev/scd0 - for SCSI devices. --i (or --iso=) - Specify iso file. diff --git a/yabause/README.MAC b/yabause/README.MAC deleted file mode 100644 index bd8b2f25b8..0000000000 --- a/yabause/README.MAC +++ /dev/null @@ -1,98 +0,0 @@ - _ _ - / \_/ \ ___ _ ____ - \ /___ ___ / || | __ / \ ____ - \ // || \ / || | \ \\ \_// \ - / // || // _ || |__\ \\ \ __/ - \_// _ || \\_/ \_||______/ \ \\ \__ - \_/ \_||___/ \____/ \____\ - Yet Another Buggy And Uncomplete Saturn Emulator - - ____________________________________ - Copyright (c) 2002-2012 Yabause team - - -1) Introduction.............................................20 -2) Compiling instructions...................................26 -3) How to use Yabause.......................................46 -4) Known Issues.............................................92 - - -1 Introduction________________________________________________ - -This file documents the mac version only, for general -information check the README file. - - -2 Compiling instructions______________________________________ - -Yabause is written in C and Objective C using the Cocoa, -IOKit, OpenGL, and CoreAudio frameworks. All of these -frameworks should be installed by default on your Mac OS X -system. You must have the Mac OS X 10.6 SDK installed by the -Xcode installer in order to build Yabause. In addition, you -will need at least Xcode 3.2. - -Once you have Xcode installed, you should be ready to build -Yabause. - -Uncompress the Yabause source archive, and open the -Yabause.xcodeproj in the src/cocoa directory. From there it -should be as easy as hitting the Build or Build and Run -button in Xcode. This should generate a Yabause.app file -that can be run just like any other application bundle on -Mac OS X. - - -3 How to use Yabause__________________________________________ - -Before using Yabause, you need to configure a few things in -the Preferences dialog (Yabause > Preferences). - - -3.1 Configuration_____________________________________________ - -First, set the BIOS path. -Yabause can run some games without a BIOS, but many of them -need it. If you want to use the emulated BIOS, select the -checkbox for that. - -Next, set up the video and sound cores. For the video core, -you have 4 options: -1. OpenGL Hardware Video Core - Potentially the fastest video - core choice, at least with a discrete video card. However, - it is also the least accurate. -2. Software Video Core - The most accurate video core you can - use, but also the slowest. -3. Grand Central Dispatch Software Core - A multithreaded - version of the Software Video Core. On a multi-core system - this should be significantly faster than the Software core - with a similar accuracy level. -4. Disable Video - Does exactly what it sounds like. - -For the sound core, you only have two options: -1. Core Audio Sound Core - The default sound core. Select - this one if you want sound. -2. Disable Sound - Does exactly what it sounds like. - -Next, set up keys for input. Go to the Input tab, and -configure each button (at least on Controller 1). For the -moment, this is limited to keyboard input only. - -There are other options you can configure as well in here, -including BRAM (for saving), a MPEG ROM (for games that use -the VideoCD/MPEG card), and a cartridge for the cartridge -port on the Saturn. - -Once eveything is set, you can start emulation with the -"File > Run BIOS", "File > Run CDROM" or "File > Run Image" -menu options. Don't use the Run BIOS entry if you're using -BIOS emulation. - - -4 Known Issues________________________________________________ - -When running in GDB, you should not use fullscreen mode. If -Yabause crashes while running under GDB in fullscreen mode, -you will probably get stuck with no way to exit. This should -only affect developers and shouldn't ever be an issue for -normal users. diff --git a/yabause/README.PSP b/yabause/README.PSP deleted file mode 100644 index 0c85aaf21f..0000000000 --- a/yabause/README.PSP +++ /dev/null @@ -1,802 +0,0 @@ -PSP-Specific Yabause Documentation -================================== - -Important notice ----------------- -PSP support for Yabause is experimental; please be aware that some things -may not work well (or at all). - -Unlike Yabause 0.9.10, this version of Yabause now works on all PSPs, -including the original PSP-1000 ("Phat"). However, some games may run -more slowly on PSP Phats because of the limited amount of memory available -for caching dynamically-translated program code. - - -Installing from a binary distribution -------------------------------------- -The yabause-X.Y.Z.zip archive contains a "PSP" directory (folder); copy -this into the root directory of your Memory Stick. (On Windows, for -example, your Memory Stick might show up as the drive F: -- in this case, -drag the "PSP" folder from the ZIP archive onto the "F:" drive icon in -Windows Explorer.) - -The "PSP" directory contains a directory called "GAME", which in turn -contains a directory called "YABAUSE". Inside the "YABAUSE" directory are -two files named "EBOOT.PBP" and "ME.PRX"; these are the program files used -by Yabause, like .EXE and .DLL files on Windows. You'll also need to copy -your CD image and other data files to this directory on your Memory Stick -(see below). - -Once you've copied Yabause to your Memory Stick, skip to "How to use -Yabause" below. - - -Installing from source ----------------------- -To build Yabause for PSP from the source code, you'll need a recent (at -least SVN r2450(*)) copy of the unofficial PSP SDK from http://ps2dev.org, -along with the toolchain from the same site; Gentoo Linux users can also -download a Portage overlay from http://achurch.org/portage-psp.tar.bz2 and -"emerge pspsdk". Ensure that the PSP toolchain (psp-gcc) and tools -(psp-prxgen, etc.) are in your $PATH, then configure Yabause with: - - ./configure --host=psp [options...] - -(*) Note that the PSP SDK headers and libraries are, at least through - r2493, missing some functions required by Yabause. If you get errors - about the functions sceKernelIcacheInvalidateAll or - sceKernelIcacheInvalidateRange, apply the patch found in - src/psp/icache-funcs-2450.patch to the PSP SDK source, recompile and - reinstall it, then rebuild Yabause. This patch is already included if - you build the SDK from the Gentoo Portage overlay. - -You can ignore the warning about the --build option that appears when you -start the configure script. You may also see a warning about "using cross -tools not prefixed with host triplet"; you can usually ignore this as well, -but if you get strange build errors related to libraries like SDL or -OpenGL, try disabling the optional libraries with the options -"--without-sdl" and "--without-opengl". - -The following additional options can be used when configuring for PSP: - - --enable-psp-debug - Enables printing of debug messages to standard error. - - --enable-psp-profile - Enables printing of profiling statistics to standard error. - By default, statistics are output every 100 frames; edit - src/psp/main.c to change this. Note that profiling has a - significant impact on emulation speed. - - --with-psp-me-test - Builds an additional program, "me-test.prx", which tests the - functionality of the Media Engine access library included with - Yabause. Only useful for debugging or extending the library. - -Note that if you build with optimization disabled (-O0) or at too low a -level, you may get compilation errors in src/psp/satopt-sh2.c. -O3 is -recommended; set this flag in the CFLAGS environment variable before -running the "configure" script. For example, if you use the "bash" shell: - - CFLAGS=-O3 ./configure --host=psp [options...] - -After the configure script completes, run "make" to build Yabause. The -build process will create the EBOOT.PBP and me.prx (note that the latter -is lowercase) files in the src/psp/ subdirectory; create a directory for -Yabause under /PSP/GAME on your memory stick (e.g. /PSP/GAME/YABAUSE) and -copy the files there. - - -How to use Yabause (PSP-specific notes) ---------------------------------------- -All files you intend to use with Yabause (BIOS images, CD images, backup -RAM images) must be stored in the same directory as the EBOOT.PBP and -ME.PRX files mentioned above. The default filenames used by Yabause are -as follows: - - BIOS.BIN -- BIOS image - CD.ISO -- CD image (can also be a *.CUE file) - BACKUP.BIN -- Backup RAM image (will be created if it does not exist) - -You can choose other files from the Yabause configuration menu, which is -displayed the first time you start Yabause and can also be brought up at -any time by pressing the Select button; see below for details. If you do -not already have a backup RAM image, just leave the backup RAM filename at -its default setting, and the file will be created the first time backup RAM -is saved. - -The directional pad and analog stick can both be used to emulate the -Saturn controller's directional pad. The default button controls are as -follows: - - Start -- Start - A -- Cross - B -- Circle - C -- (unassigned) - X -- Square - Y -- Triangle - Z -- (unassigned) - L -- L - R -- R - -Button controls can be changed via the configuration menu. - - -The Yabause PSP configuration menu ----------------------------------- -When you first run Yabause, the configuration menu will be displayed, -allowing you to choose the CD image you want to run and configure other -Yabause options. You can also press Select while the emulator is running -to bring up the menu; the emulator will remain paused while you have the -menu open. - -The main menu contains six options: - - * "Configure general options..." - - This opens a submenu with the following options: - - * "Start emulator immediately" - - When enabled, the emulator will start running immediately when - you load Yabause, instead of showing the configuration menu. - - * "Select BIOS/CD/backup files..." - - This opens a submenu which allows you to select the files - containing the BIOS image, CD image, and backup data you want - to use. Selecting one of the three options will open a file - selector, allowing you to choose any file in the Yabause - directory on your Memory Stick. - - Note that changing any of the files will reset the emulator. - - * "Auto-save backup RAM" - - When enabled, automatically saves the contents of backup RAM to - your Memory Stick whenever you save your game in the emulator. - The emulator will display "Backup RAM saved." on the screen for - a short time when an autosave occurs. Note that the emulator - may pause for a fraction of a second while autosaving. This - option is enabled by default. - - Be aware that backup RAM is _not_ saved to the Memory Stick - when you quit Yabause; if you disable this option, you need to - manually save it using the "Save backup RAM now" option when - appropriate. - - * "Save backup RAM now" - - Immediately saves the contents of backup RAM to your Memory - Stick. If you have auto-save disabled, you should use this - option to save backup RAM before quitting Yabause. - - * "Save backup RAM as..." - - Allows you to enter a new filename (using the PSP's built-in - on-screen keyboard) for the backup RAM save file. This can be - useful if you want to keep separate backup RAM files for - different games, or if you want to save more slots than a game - normally allows. Yabause will immediately save backup RAM to - the filename you enter, and will also use that filename when - later auto-saving backup RAM (or when you manually use "Save - backup RAM now"). However, the new filename will only be used - until you quit Yabause, unless you select "Save options" on the - main menu. - - Note that the emulator will _not_ be reset when you use this - option, so you can feel free to select it while playing a game. - (However, don't select it while the game is in the middle of - loading or saving, as this can corrupt backup RAM -- just as if - you tried to remove the PSP's Memory Stick while saving a game - on your PSP.) - - NOTE: For reasons currently unknown, the top part of the - on-screen keyboard display may flicker or appear corrupted. - However, text can be entered as usual. - - * "Configure controller buttons..." - - This opens a submenu which allows you to configure which PSP button - corresponds to which button on the emulated Saturn controller. - Pressing one of the Circle, Cross, Triangle, or Square buttons on - the PSP will assign that button to the currently selected Saturn - controller button. The PSP's Start, L, and R buttons are always - assigned to the same-named buttons on the Saturn controller, and - cannot be changed. - - Since both the Circle and Cross buttons are used for button - assignment, the Start button is used to return to the main menu. - - * "Configure video options..." - - This opens a submenu with the following options: - - * "Use hardware video renderer" / "Use software video renderer" - - These options allow you to choose between the PSP-specific - hardware renderer and the default software renderer built into - Yabause for displaying Saturn graphics. The hardware renderer - is significantly faster; for simple 2-D graphics, it can run at - a full 60fps without frame skipping (if the game program itself - can be emulated quickly enough). However, a number of more - complex graphics features are not supported, so if a game does - not display correctly, try using the software renderer instead. - - The selected renderer can be changed while the emulator is - running without disturbing your game in progress. However, - changing the renderer may cause the screen to blank out or - display corrupted graphics for a short time. - - * "Configure hardware rendering settings..." - - This option opens another submenu which allows you to change - certain aspects of the hardware video renderer's behavior: - - * "Aggressively cache pixel data" - - When enabled, Yabause will try to store a copy of all - graphic data in the PSP's native pixel format, to speed up - drawing. However, Yabause may not always notice when the - data is changed, causing incorrect graphics to appear. - (This can be fixed by disabling the option, exiting the - menu for a moment, then re-enabling the option.) When - disabled, all graphics are redrawn from the Saturn data - every frame. This option is enabled by default. - - * "Smooth textures and sprites" - - When enabled, smoothing (antialiasing) is applied to all - 3-D textures and sprites drawn on the screen. This can - make 3-D environments look smoother than on a real Saturn, - but it will also cause zoomed sprites to look blurry, which - may not be the game's intended behavior. - - * "Smooth high-resolution graphics" - - When enabled, high-resolution graphics (which ordinarly - would not fit on the PSP's screen) are displayed by - averaging adjacent pixels to give a smoother look to the - display; this can particularly help in reading small text - on a high-resolution screen. However, this smoothing is - significantly slower than the default method of just - skipping every second pixel. - - * "Enable rotated/distorted graphics" - - Selects whether to display rotated or distorted graphics - at all. Most such graphics cannot be rendered by the - PSP's hardware, so Yabause has to draw them in software, - which can be a major source of slowdown. Disabling this - option will turn such graphics off entirely. This option - is enabled by default. - - * "Optimize rotated/distorted graphics" - - When enabled, Yabause will try to detect certain types of - rotated or distorted graphics which can be approximated by - PSP hardware operations such as 3D transformations, and use - the PSP's hardware to draw them quickly. However, this - will often result in graphics that look different from the - game as played on an actual Saturn, so this option can be - used to disable the optimizations and draw the graphcs more - accurately (at the expense of speed). This option is - enabled by default. - - Note that none of the above options have any effect when the - software video renderer is in use. - - * "Configure frame-skip settings..." - - This option opens another submenu which allows you to configure - the hardware renderer's frame-skip behavior: - - * "Frame-skip mode" - - This option is intended to allow you to switch between - manual setting and automatic adjustment of frame-skip - parameters. However, automatic mode is not yet - implemented, so always leave this set on "Manual". - - * "Number of frames to skip" - - In Manual mode, sets the number of frames to skip for every - frame drawn. 0 means "draw every frame", 1 means "draw - every second frame" (skip 1 frame for every frame drawn), - and so on. - - * "Limit to 30fps for interlaced display" - - Always skip at least one frame when drawing interlaced - (high-resolution) screens. Has no effect unless the number - of frames to skip is set to zero. This option is enabled - by default. - - * "Halve framerate for rotated backgrounds" - - Reduce the frame rate by half (in other words, skip every - second frame that would otherwise be drawn) when rotated or - distorted background graphics are displayed. Since rotation - and distortion take a long time to process on the PSP, this - option can help keep games playable even when they make use - of these Saturn hardware features. This option is enabled - by default. - - Note that this option does not apply to rotated or - distorted graphics which are displayed using an optimized - algorithm (see the "Optimize rotated/distorted graphics" - option above). - - Frame skipping is not supported by the software renderer, so - none of these options will have any effect when the software - renderer is in use. - - * "Show FPS" - - When enabled, the emulator's current speed in emulated frames per - second (FPS) will be displayed in the upper-right corner of the - screen as "FPS: XX.X (Y/Z)". The number "XX.X" is the average - frame rate, calculated from the last few seconds of emulation; - "Y" shows the number of Saturn frames emulated since the previous - frame was shown, while "Z" is the actual time that passed in - 60ths of a second. (Thus, the instantaneous frame rate can be - calculated as (Y/Z)*60.) - - This option has no effect when the software renderer is in use. - - * "Configure advanced settings..." - - This opens a submenu with the following options: - - * "Use SH-2 recompiler" - - This option allows you to choose between the default SH-2 core, - which recompiles Saturn SH-2 code into native MIPS code for the - PSP, and the SH-2 interpreter built into Yabause. The SH-2 - interpreter is much slower, often by an order of magnitude or - more, so there is generally no reason to disable this option - unless you suspect a bug in the recompiler. - - Note that changing this option will reset the emulator. As with - "Reset emulator" on the main menu, you must hold L and R while - changing this option to avoid an accidental reset. - - * "Select SH-2 optimizations..." - - This option opens up another submenu which allows you to turn on - or off certain optimizations used by the SH-2 recompiler. These - are shortcuts taken by the recompiler to allow games to run more - quickly, but in rare cases they can cause games to misbehave or - even crash. If a game doesn't work correctly, turning one or - more of these options off may fix it. - - These options can be changed while the emulator is running - without disturbing your game in progress. However, changing them - causes the emulator to clear out any recompiled code it has in - memory, so the game may run slowly for a short time after exiting - the menu as the emulator recompiles SH-2 code using the new - options. - - All optimizations are enabled by default. - - * "Configure Media Engine options..." - - This option opens up another submenu with options for - configuring the Media Engine: - - * "Use Media Engine for emulation" - - Enables the use of the PSP's Media Engine CPU to handle part - of the emulation in parallel with the main CPU. This can - provide a moderate boost to emulation speed; however, since - the Media Engine is not designed for this sort of parallel - processing, some games may behave incorrectly or even crash. - As such, this option is still considered experimental; use - it at your own risk. - - IMPORTANT: It is not currently possible to suspend the PSP - while the Media Engine is in use. If you start Yabause with - the Media Engine enabled, the "suspend" function of the - PSP's power switch will be disabled, so you must save your - game inside the emulator and exit Yabause before putting the - PSP into suspend mode. - - This option only takes effect when Yabause is started, so if - you change it, make sure you select "Save options" in the - main menu and then quit and restart Yabause. - - * "Cache writeback frequency" - - Sets the frequency at which the main CPU and Media Engine - caches are synchronized, relative to the frequency of code - execution on the Media Engine. The default frequency of 1/1 - is safest; lower frequencies (1/2, 1/4, and so on) can - increase emulation speed, but are also more likely to cause - sound glitches, crashes, or other incorrect behavior - depending on the particular game. However, adjusting the - size of the write-through region (see below) can mitigate - these problems for some games. - - Naturally, this option has no effect if the Media Engine is - not being used for emulation. - - * "Sound RAM write-through region" - - Sets the size of the region at the beginning of sound RAM - which is written through the PSP's cache. Writing through - the cache is an order of magnitude slower than normal - operation, so setting this to a large value can slow down - games significantly. However, most games only use a small - portion of sound RAM for communication with the sound CPU, - so by tuning this value appropriately, you may be able to - reduce the cache writeback frequency (see above) while still - getting stable operation. From experimentation, a value of - 2k seems to work well for some games. - - Naturally, this option has no effect if the Media Engine is - not being used for emulation. - - * "Use more precise emulation timing" - - When enabled, the emulator will keep the various parts of the - emulated Saturn hardware more precisely in sync with each other. - This carries a noticeable speed penalty, but some games may - require this more precise timing to work correctly. - - * "Sync audio output to emulation" - - When enabled, the emulator will synchronize audio output with - the rest of the emulation. In general, this improves audio/video - synchronization but causes more frequent audio dropouts (or - "popping") when the emulator runs more slowly than real time. - However, the exact effect of this option can vary: - - - When disabled, the audio can get ahead of the video if the - emulator is running slowly; this can be seen, for example, - in the Saturn BIOS startup animation. On the other hand, - game code that uses the audio output speed for timing (such - as the movie player in Panzer Dragoon Saga) can actually run - faster with synchronization disabled. MIDI-style background - music will also play more smoothly, though of course the - music tempo will slow down depending on the emulation speed. - - - When enabled, the audio output will match the output of a - real Saturn much more closely. In particular, this option - is needed to avoid popping in streamed audio such as Red - Book audio tracks when the emulator runs at full speed - (60fps). On the flip side, the audio will momentarily drop - out (as described above) whenever the emulator takes more - than 1/60th of a second to process an emulated frame. - - This option is enabled by default. - - * "Sync Saturn clock to emulation" - - When enabled, the Saturn's internal clock is synchronized with - the emulation, rather than following real time regardless of - emulation speed. If the emulator is running slow, for example, - this option will slow the Saturn's clock down to match the speed - at which the emulator is running. This option is enabled by - default. - - * "Always start from 1998-01-01 12:00" - - When enabled, the Saturn's internal clock will always be - initialized to 12:00 noon on January 1, 1998, rather than the - current time when the emulator starts. When used with the clock - sync option above, this is useful in debugging because it ensures - a consistent environment each time the emulator is started. - Outside of debugging, however, there is usually no reason to - enable this option. - - * "Save options" - - Save the current settings, so Yabause will use them automatically the - next time you start it up. - - * "Reset emulator" - - Reset the emulator, as though you had pressed the Saturn's RESET - button. To avoid accidentally resetting the emulator, you must hold - the PSP's L and R buttons while selecting this option. - -Pressing Select on any menu screen will exit the menu and return to the -Saturn emulation. - - -Troubleshooting ---------------- -Q: "My game runs too slowly!" - -A: C'est la vie. The PSP is unfortunately just not powerful enough to - emulate the Saturn at full speed (see "Technical notes" below for the - gory details). Here are some things you can do to improve the speed of - the emulator: - - * Make sure you are using the hardware video renderer (in the - "Configure video options" menu) and the SH-2 recompiler (in the - "Configure advanced settings" menu). - - * Under "Configure video options" / "Configure hardware rendering" - settings", turn off "Enable rotated/distorted graphics". A single - distorted background can take the equivalent of 2 to 3 frames at - 60fps to render on the PSP. - - * Under "Configure video options" / "Configure frame-skip settings", - set the frame-skip mode to manual and increase the number of frames - to skip. (Many games only run at 30 frames per second, so using a - frame-skip count of 1 won't actually make a visible difference - compared to a count of 0.) - - * Under "Configure advanced emulation options" / "Select SH-2 - optimizations", make sure all optimizations are enabled. - - * Under "Configure advanced emulation options", if "Use more precise - emulation timing" is disabled, try enabling it. (This may cause - the game to freeze or crash, however.) - - * Try turning on the "Use Media Engine for emulation" option in the - "Configure advanced emulation options" menu, but note that this - option is experimental and may cause your game to misbehave or even - crash. - - * If the Media Engine is enabled, try lowering the cache writeback - frequency in the "advanced emulation options" menu. Typically, - 1/4 to 1/8 will provide a noticeable speed increase over 1/1, while - 1/16 and lower are not likely to have much effect. - -Q: "My game suddenly froze!" - -A: Try pressing Select to open the Yabause menu. - - * If the menu doesn't open, then either you've hit a bug in Yabause, - or the SH-2 optimizer has caused the program to misbehave. Restart - Yabause, then go to the "Configure advanced emulation options" / - "Select SH-2 optimizations" and disable all of the options there. - If that fixes the problem, you can then try turning the options on - one by one to find the one that caused the crash (you may need to - repeat whatever actions you performed in the game in order to - determine whether the crash occurs or not), and disable only that - option to keep the emulator running as fast as possible. - - * If the menu does open, then one likely cause is a timing issue; - this can be seen, for example, when starting Dead or Alive with the - "Use more precise emulation timing" option disabled. Try enabling - this option under the "Configure advanced emulation options" menu - and resetting the emulator to see if it fixes the problem. - - In either of the above cases, it's also possible that the game itself - has a bug. Look in FAQs or other online resources and see if any - similar problems have been reported. - - -Technical notes ---------------- -The Saturn, like the PSOne, is only one step down in power from the PSP -itself, so full-speed emulation is a fairly difficult proposition from the -outset. To make matters worse, the Saturn's architecture is about as -different from the PSP as two modern computer architectures can be: -different primary CPUs (SH-2 versus MIPS Allegrex), big-endian byte order -(Saturn) versus little-endian (PSP), tile-based graphics (Saturn) versus -texture-based graphics (PSP), and so on. As such, Yabause must take a -number of shortcuts to make games even somewhat playable. - -<<< SH-2 emulation >>> - -Emulation of the Saturn's two SH-2 CPUs in particular is problematic. -These processors run at either 26 or 28 MHz, and they use a RISC-like -instruction set in which most instructions execute in one clock cycle, so -in a worst-case scenario Yabause would need to process 56 million SH-2 -instructions per second--on top of sound, video, and other hardware -emulation--to maintain full speed. But the PSP's single(*) Allegrex CPU -runs at a maximum of 333MHz, meaning that the SH-2 emulator must be able to -execute each instruction (including accessing the register file, swapping -byte order in memory accesses, updating the SH-2 clock cycle counter, and -so on) within at most 6 native clock cycles for full-speed emulation. In -fact, the demands of emulating the other Saturn hardware reduce this to -something closer to 4 native clock cycles. - -(*) The PSP actually has a second CPU, the Media Engine, but limitations - of the PSP architecture make it unsuitable for use as a full-fledged - second processor. See below for details. - -With these limitations, interpreted execution of SH-2 code is out of the -question--merely looking up the instruction handler would exhaust the -instruction's quota of execution time. For this reason, the PSP port uses -a dynamic translator to convert blocks of SH-2 code into blocks of native -MIPS code. When the emulator encounters a block of SH-2 code for the first -time, it scans through the block, generating equivalent native code for the -block which is then executed directly on the native CPU. This naturally -causes the emulator to pause for a short time when it encounters a lot of -new code at once, such as when loading a new part of a game from CD; this -is the price that must be paid for the speed of native code execution. - -Even with this dynamic translation, however, there are still a number of -hurdles to fast emulation. For example: - -* Every time the end of a code block is reached, the emulator must look up - the next block to execute. This lookup consumes precious cycles which do - not directly correspond to SH-2 instruction emulation (around 35 cycles - per lookup in the current version). - - In order to streamline code translation and increase the optimizability - of individual blocks, the dynamic translator tends to choose minimally- - sized blocks for translation. Tests showed that this was an improvement - over an older algorithm that used larger blocks, but the resulting - overhead of block lookups imposes a limit on execution speed for certain - types of code, particularly algorithms which rely heavily on subroutine - calls. - - At the other end of the spectrum, one might consider modifying a true - compiler like GCC to accept SH-2 instructions as input, then running - each code block through the compiler itself to generate native code. - This could undoubtedly produce efficient output with larger blocks, but - it would also impose significant additional overhead when translating. - -* The SH-2 is unable to load arbitrary constants into registers, instead - using PC-relative accesses to load values outside the range of a MOV #imm - instruction from memory. However, Saturn programs also use PC-relative - accesses for function-local static variables, meaning that there is no - general way to tell whether a given value is actually a constant or - merely a variable that may be modified elsewhere. - - This presents a particular problem in optimizing memory accesses, since - if a pointer loaded from a PC-relative address is not known to be - constant, the translated code must incur the overhead of checking the - pointer's value every time the block is executed. The SH-2 core includes - an optional optimization, SH2_OPTIMIZE_LOCAL_POINTERS, which takes the - stance that all such pointers either are constant or will always point - within the same memory region (high system RAM, VDP2 RAM, etc.). This - optimization shows a marked improvement in execution speed in some cases, - but any code which violates the assumption above will cause the emulator - to crash. - -* Some games make use of self-modifying code, presumably in an attempt to - increase execution speed; one example can be found in the "light ray" - animation used in Panzer Dragoon Saga when obtaining an item. Naturally, - the use of self-modifying code has a severe impact on execution time in a - dynamic translation environment, as each modification requires every - block containing the modified instruction to be retranslated. (A similar - effect can be seen on modern x86-family CPUs, which internally translate - x86 instructions to native micro-ops for execution; self-modifying code - can slow down the processor by an order of magnitude or more.) - - The SH-2 core attempts to detect frequently modified instructions and - pass them directly to the interpreter to avoid the overhead of repeated - translation, but there is unfortunately no true solution to the problem - other than rewriting the relevant part of the game program itself. - -* Memory accesses are difficult to implement efficiently; in fact, the SH-2 - emulator devotes over 1,000 lines of source code to handling load and - store operations, independently of the memory access handlers in the - Yabause core. The current implementation is able to handle accesses to - true RAM fairly quickly, but any access which falls back to the default - MappedMemory*() handlers incurs a significant access penalty (typically - 20-30 cycles plus any handling needed for the specific address). - - This is most obvious while loading data from the emulated CD, since the - game program must access a hardware register in a loop while waiting for - the CD data to be loaded, and additionally some games read CD data - directly out of the CD data register rather than using DMA to load the - data into memory. Currently, the only way to speed up such code blocks - is through handwritten translation (see src/psp/satopt-sh2.c). - -Patches to either speed up specific games or to improve the translation -algorithm generally are of course welcome. - -<<< Use of the Media Engine >>> - -Aside from the two SH-2 cores, a third major consumer of CPU time is the -SCSP, the Saturn's sound processor, and particularly the MC68EC000 -("68k") CPU used therein. While most games don't run particularly complex -code on the 68k, it is nonetheless a proper CPU in its own right, and -requires a fair amount of time to emulate; multi-channel FM background -music takes time to generate as well. Currently, the PSP port of Yabause -has the ability to make use of the PSP's Media Engine CPU to process 68k -instructions and audio generation in parallel with the rest of the -emulation, but this use of the Media Engine is a considerable departure -from Sony's design and thus a risky endeavor. - -The primary difficulty with using the ME as a "second core" in the sense -of the multi-core processors used in PCs is that of cache coherency. -Unlike generic multiprocessor or multi-core systems, the PSP's two CPUs -do not implement cache coherency; this means that neither CPU knows what -the other CPU has in its cache, and one CPU may inadvertently clobber the -other's changes, causing stores to memory to get lost. As an example, -consider these two simple loops, operating in parallel on a two-element -array initialized to {1,1} that resides in a single cache line: - - Core 1 Core 2 - ------ ------ - for (;;) { for (;;) { - array[0] += array[1]; array[1] += array[0]; - } } - -This illustrates two problems caused by the lack of cache coherency: - -* On a cache-coherent (or single-core) system, the two array elements - will increase unpredictably as each loop sees the updated value stored - by the other loop. On the PSP, however, both elements will increase - monotonically; once each CPU loads the cache line, it never sees any - stores performed by the other CPU, because accesses to the array always - hit the cache. - -* On a cache-coherent system, if the cache line is flushed to memory, it - will always contain the current values of both array elements. On the - PSP, however, the array element _not_ updated by the flushing CPU will - be written with the same value it had when the cache line was loaded - by that CPU. In particular, if the other CPU had already flushed the - cache line, that change will be clobbered--for example (here "SC" is - the main CPU and "ME" is the Media Engine): - - Time Operation SC cache ME cache Memory Desired - ---- ---------- -------- -------- ------ ------- - T1 Initialize {1,1} {1,1} {1,1} {1,1} - T2 SC flush {A,1} {1,B} {A,1} {A,B} - T3 ME flush {C,1} {1,D} {1,D} {C,D} - - Note that at no time after initialization are the contents of memory - correct, and in particular, the value "A" written by the SC is lost - when the ME flushes {1,D} from its cache, even though the ME loop - never actually modified that array element. - -In order for Yabause to have even a hope of stable operation, therefore, -the use of both CPUs' caches must be carefully controlled to avoid data -loss. - -When use of the Media Engine is enabled, the following steps are taken -to avoid data corruption due to the lack of cache coherency: - -* SCSP state variables used for inter-thread communication are divided into - separate, 64-byte (cache-line) aligned data sections, based on which - thread (the main Yabause thread, running on the SC, or the SCSP thread, - running on the ME) writes to them. - -* SCSP state variables are accessed using uncached (0x4nnnnnnn) addresses - in two cases: when _reading_ data written by the other CPU (to avoid an - old value getting stuck in the cache), and when _writing_ data which is - also written by the other CPU (to avoid the cache line clobbering problem - described above). - -* Sound RAM is accessed _with_ caching (except in one case described - below), because forcing every sound RAM access through an uncached - pointer causes significant slowdown. Instead, cached CPU data is written - back to RAM at strategic points. - -* The SC's data cache is flushed (written back and invalidated) immediately - before waiting for the SCSP thread to finish processing, e.g. for - ScspReset(). The data cache is written back on every ScspExec() call - (though the writeback frequency may be reduced through the configuration - menu), but it is _not_ flushed for performance reasons; instead, sound - RAM read accesses from the SC are made through uncached addresses, as - with SCSP state variables above. - -* The ME's data cache is flushed after each iteration of the SCSP thread - loop. This flushing is not coded directly into scsp.c, but instead - takes place in the YabThreadYield() and YabThreadSleep() implementations. - (These functions are naturally meaningless on the ME, but since the SCSP - thread calls one or the other at the end of each loop, it's a convenient - place to flush the cache.) - -* The 68k state block, along with dynamically-generated native code when - dynamic translation is enabled, is stored in a separately allocated pool - and managed with custom memory allocation functions (local_malloc() and - friends in psp-m68k.c), since the standard memory management functions - are not designed to work with the ME and would likely cause a crash due - to cache desynchronization. - -In general, using the ME provides a moderate speed improvement (10-15%) to -overall emulation speed. There are, however, some cases in which the lack -of cache coherency could cause games to misbehave or even crash Yabause: - -* If a game writes (from the SH-2) to a portion of sound RAM containing 68k - program code while the 68k is executing, the 68k may execute incorrect - code, or the dynamic translation memory pool may be corrupted. Normally, - games should only load code while the 68k is stopped, but there may be - cases when the SH-2 writes to a variable in sound RAM which is located in - the same region as 68k code, thus triggering this issue. - -* Games which rely on the precise relative timing of the SH-2 and 68k - processors are likely to fail in any multithreaded emulator, but are more - likely to fail when using the ME due to delays in data being written out - from the data caches. diff --git a/yabause/README.QT b/yabause/README.QT deleted file mode 100644 index d3e813c6cd..0000000000 --- a/yabause/README.QT +++ /dev/null @@ -1,138 +0,0 @@ - _ _ - / \_/ \ ___ _ ____ - \ /___ ___ / || | __ / \ ____ - \ // || \ / || | \ \\ \_// \ - / // || // _ || |__\ \\ \ __/ - \_// _ || \\_/ \_||______/ \ \\ \__ - \_/ \_||___/ \____/ \____\ - Yet Another Buggy And Uncomplete Saturn Emulator - - _________________________________________ - Copyright (c) 2002-2011 Yabause team - - -1) Compiling instructions...................................20 -2) How to use Yabause.......................................82 -3) Contact information.....................................105 -4) Disclaimer..............................................121 - - -1 Compiling instructions______________________________________ - -Yabause is written in C using the OpenGL library, so you need a working C compiler(such as gcc) and -these libraries, runtime and development packages: - - * OpenGL should be included with your compiler, if it isn't, - check on your compiler's website for links. - -Yabause can also use the SDL library: - - * http://www.libsdl.org/ - -Yabause can also use the GLUT library: - - * Check google, I haven't been able to find a good - source for it. - -Once these libraries installed, you should be ready to -install Yabause. - -Building the Qt 4 port require the Qt 4.3.x libraries too, it's a crossplatform C++ library for various all days crossplatform work ( gui, threads ... ). -I used the version 4.3.4 version for the developement and tests, so please don't report bugs if you are not using at least this version. - - * http://www.trolltech.com/products/qt - -Compiling for Windows : using mingw/cygwin__________________________________ - -All you have to do now is now is go into your mingw/cygwin -shell environment, go into the directory where you extracted -yabause, and type: "./configure --enable-newperinterface ---with-port=qt". Once that's done(and there -was no errors), type: "make". It should now take some time to -compile so go grab yourself a sandwich or beer - whatever suits -your fancy and it should be done in a few minutes. Now all you -have to do is type "./src/qt/release/yabause" in order to run it. - -Compiling for Mac OS X : using gcc__________________________________________ - -Uncompress the Yabause source archive, move to the newly -created directory, type "./configure --enable-newperinterface --disable-dependency-tracking --disable-shared --with-port=qt", then "make", -it will generate a bundle: "Yabause.app" in the "src/qt" -directory. -You can then use Yabause by opening the bundle with: -"open Yabause.app" or with the Mac OS X finder. - -Compiling for *Nix/Linux/BSD ? : using gcc__________________________________ - -Uncompress the Yabause source archive, move to the newly -created directory, type "./configure --enable-newperinterface ---with-port=qt", then "make", -it will generate one program: "yabause" in the "src/qt" -directory. - - -You can also pass the --enable-debug option to the configure script, Yabause -will then print debug messages in a special dock window. -(Use the --help flag for a complete list of options.) - -You can even type "make install" to install that program on -your system (in /usr/local/ by default), then uninstalling is -done by typing "make uninstall". - -You can try to read other specific README files for more information. - -2 How to use Yabause__________________________________________ - -Before using Yabause, you need to configure a few things in -the Preferences dialog (File>Settings). - - -2.1 Configuration_____________________________________________ - -First, set the BIOS path. -Yabause can run some games without a BIOS, but most of them -needs it. If you want to use the emulated BIOS, just let the -BIOS entry blank. - -Next, set the cdrom device. -It can be a cd device, an iso or a cue file. Set the cd type -accordingly. - -The last thing you have to configure is the keys. - -Once eveything is set, you can start emulation with the -"Emulation>Run" entry. - - -3 Contact information_________________________________________ - -General inquiries should go to: -E-mail: guillaume.duhamel@gmail.com -E-mail: cwx@cyberwarriorx.com - -Qt Port-related inquiries should go to: -E-mail: pasnox@yabause.org - -Web: http://yabause.org - -Please don't ask for roms, bios files or any other copyrighted -stuff. Please use the forum when you have any questions if -possible. - - -4 Disclaimer__________________________________________________ - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of -the License, or (at your option) any later version. - -This program is distributed in the hope that it will be -useful,but WITHOUT ANY WARRANTY; without even the implied -warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public -License along with this program; if not, write to the Free -Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301 USA - -See the GNU General Public License details in COPYING. diff --git a/yabause/README.WII b/yabause/README.WII deleted file mode 100644 index cc57112344..0000000000 --- a/yabause/README.WII +++ /dev/null @@ -1,88 +0,0 @@ - _ _ - / \_/ \ ___ _ ____ - \ /___ ___ / || | __ / \ ____ - \ // || \ / || | \ \\ \_// \ - / // || // _ || |__\ \\ \ __/ - \_// _ || \\_/ \_||______/ \ \\ \__ - \_/ \_||___/ \____/ \____\ - Yet Another Buggy And Uncomplete Saturn Emulator - - _________________________________________ - Copyright (c) 2002-2011 Yabause team - - -1) Special Notice...........................................21 -2) Compiling instructions...................................28 -3) How to use Yabause.......................................50 -4) Contact information......................................55 -5) Disclaimer...............................................71 - - -1 Special Notice______________________________________________ - -Please note that the Wii port is in alpha status, and won't be -officially supported until a later date. If you would like to -contribute, please contact us(see the contact information -section in README). - -2 Compiling instructions______________________________________ - -Yabause is written in C using the devkitPro packages. You can -download it from: - -http://www.devkitpro.org - -Once this is installed, you should be ready to install Yabause. - -To compile, either use the Makefile.wii file in the src -subdirectory to compile it(e.g. make -f Makefile.wii) or you can -use configure in the main directory as follows: - -./configure --build=i686-pc-linux-gnu --host=powerpc-gekko - -Once that's done, type "make". It should now take some time to -compile so go grab yourself a sandwich or beer - whatever suits -your fancy and it should be done in a few minutes. You should -now have a file called "yabause.elf". Now all you have to do is -load it on your Wii(which is something we won't cover here). - - -3 How to use Yabause__________________________________________ - -To be finished later. - - -4 Contact information_________________________________________ - -General inquiries should go to: -E-mail: guillaume@yabause.org -E-mail: cwx@cyberwarriorx.com - -Windows Port-related inquiries should go to: -E-mail: cwx@cyberwarriorx.com - -Web: http://yabause.org - -Please don't ask for roms, bios files or any other copyrighted -stuff. Please use the forum when you have any questions if -possible. - - -5 Disclaimer__________________________________________________ - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of -the License, or (at your option) any later version. - -This program is distributed in the hope that it will be -useful,but WITHOUT ANY WARRANTY; without even the implied -warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public -License along with this program; if not, write to the Free -Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301 USA - -See the GNU General Public License details in COPYING. diff --git a/yabause/README.WIN b/yabause/README.WIN deleted file mode 100644 index f028197b3d..0000000000 --- a/yabause/README.WIN +++ /dev/null @@ -1,250 +0,0 @@ - _ _ - / \_/ \ ___ _ ____ - \ /___ ___ / || | __ / \ ____ - \ // || \ / || | \ \\ \_// \ - / // || // _ || |__\ \\ \ __/ - \_// _ || \\_/ \_||______/ \ \\ \__ - \_/ \_||___/ \____/ \____\ - Yet Another Buggy And Uncomplete Saturn Emulator - - _________________________________________ - Copyright (c) 2002-2011 Yabause team - - -1) Compiling instructions...................................20 -2) How to use Yabause.......................................68 -3) Contact information.....................................217 -4) Disclaimer..............................................233 - - -1 Compiling instructions______________________________________ - -Yabause is written in C using the DirectX 8.0, OpenGL, GLUT, and -mini18n libraries, so you need a working C compiler(such as gcc) -and these libraries, runtime and development packages: - - * You can find DirectX headers and libraries(for mingw) at - http://alleg.sourceforge.net/wip.html as the file - "dx80_mgw.zip". The actual runtime libraries(or - headers/libraries for Visual C++) can be gotten from - http://www.microsoft.com/DirectX - - * OpenGL should be included with your compiler, if it isn't, - check on your compiler's website for links. - - * Check google for GLUT. I haven't been able to find a good - source for it. - - * You can get mini18n from Yabause's sourceforge download page - here: http://sourceforge.net/project/showfiles.php?group_id=89991&package_id=304859 - -Once these libraries installed, you should be ready to -install Yabause. - -Compiling using mingw/cygwin__________________________________ - -All you have to do now is now is go into your mingw/cygwin -shell environment, go into the directory where you extracted -yabause, and type: "./configure". Once that's done(and there -was no errors), type: "make". It should now take some time to -compile so go grab yourself a sandwich or beer - whatever suits -your fancy and it should be done in a few minutes. Now all you -have to do is type "./src/yabause" in order to run it. - -Compiling using Visual C++____________________________________ - -Make sure you have the latest DirectX SDK and DDK installed. You -can get both of them from Microsoft's website. - -Load up IDE that comes with Visual C++/Visual Studio, go into the -file menu, open an existing project. Go into the yabause's -src/windows directory and open yabause.sln. Now all you have -to do is build it like any other Visual C++ project. - -You can compile for either x86 or x64(for those using Windows XP -x64 or Vista x64. - - -2 How to use Yabause__________________________________________ - -While not necessarily needed, it is recommended you get a Saturn -ROM BIOS image. Please don't ask us where to get one. - -Execute "yabause". The program will open a settings window. - -Basic Settings________________________________________________ - -The Disc Type setting allows you to choose whether you'd like to -use a real cdrom or a cdrom image of the game you're trying to -run. - -The Cue/Iso File setting allows you to specify the location -of your Saturn game's cdrom image. - -The Drive Letter setting is for you to be able to choose which -cdrom drive you want yabause to use when trying to boot a game. - -The SH2 Core setting is for you to be able to choose which SH2 -Core to use. Unless you're a developer, chances are, you should -leave it as the default: "Fast Interpreter". - -The Region setting allows you to choose which region of game -you'll be booting. In most cases, it's best to leave it as -"Auto-detect". - -The Bios ROM File setting allows you to specify the location -of your Saturn ROM BIOS image. If you leave it blank, yabause -will try to emulate the bios instead. It's better to specify -a ROM BIOS image if you can since the emulated bios isn't -100% perfect and may not work with your games. - -The Backup RAM File setting allows you to specify the location -of the Backup RAM file. This file allows yabause to store and -load save games. - -The MPEG ROM File setting allows you to specify the location -of a MPEG Card's ROM image. While not necessary, it does allow -you to test out the saturn's vcd capabilities. - -The Cartridge Type setting allows you to choose which type of -external cartridge to emulate. Some carts also require you to -supply a rom filename, or a new filename for the emulator to -write to. You can enter that information in the field below it. - -When you're done, just click on the "OK" button. If the bios -location was specified correctly, emulation should start and -you will see a brief animation of the saturn logo being formed. - -Special Note: Some settings require a restart of the program. - -There's also settings specifically for video, sound, and input. - -Video Settings________________________________________________ - -If you click on the "Video" tab another list of settings is -displayed. You can set the Video Core to either do hardware -rendering using OpenGL, software renderer(uses OpenGL the final -draw though), or disable drawing completely with the "None" -option. You can also "Enable Auto Frame-skipping" which basically -tries to skip rendering video frames if emulation is lagging in -an attempt to speed things up. - -The Full Screen on startup setting allows you to set Yabause to -run using the full screen when started. You can also change what -resolution is used while in full screen. - -The custom window size setting allows you to set the size of the -video display for yabause. - -Sound Settings________________________________________________ - -If you click on the "Sound" tab another list of settings is -displayed. You can set the Sound Core to either do sound mixing -using DirectX Sound or disable sound completely with the "None" -option. You can also adjust the sound volume using the volume -slider underneath. - -Input Settings________________________________________________ - -If you click on the "Input" tab another list of settings is -displayed. Here you can choose which peripheral(s) emulate. If -you press "Config" another window will pop up. Here can set which -device you'd like to use at the top of the window. Control -settings can be changed by clicking on the equivalent button, and -then when a new window pops up that says "waiting for input..." -press a key/button and that will set the new setting for that -control. - -Log Settings__________________________________________________ - -If you've compiled your own copy of Yabause with the processor -define DEBUG, another tab will be available called "Log". This -allows you to control whether or not the program should be -logging emulation output using the "Enable Logging" setting. Log -Type tells the program whether it should write the output to a -file, or to a separate window so you can monitor the output while -you're running the program. - -Here are the default key mappings(they may be subject to change): -Up arrow - Up -Left arrow - Left -Down arrow - Down -right arrow - Right -k - A button -l - B button -m - C button -u - X button -i - Y button -o - Z button -x - Left Trigger -z - Right Trigger -j - Start button -q - Quit program -F1 - Toggle FPS display -Alt-Enter - Toggle fullscreen/window mode -` - Enable Speed Throttle -1 - Toggle VDP2 NBG0 display -2 - Toggle VDP2 NBG1 display -3 - Toggle VDP2 NBG2 display -4 - Toggle VDP2 NBG3 display -5 - Toggle VDP2 RBG0 display -6 - Toggle VDP1 display -F2 - Load State from slot 1 -F3 - Load State from slot 2 -F4 - Load State from slot 3 -F5 - Load State from slot 4 -F6 - Load State from slot 5 -F7 - Load State from slot 6 -F8 - Load State from slot 7 -F9 - Load State from slot 8 -F10 - Load State from slot 9 -Shift-F2 - Save State to slot 1 -Shift-F3 - Save State to slot 2 -Shift-F4 - Save State to slot 3 -Shift-F5 - Save State to slot 4 -Shift-F6 - Save State to slot 5 -Shift-F7 - Save State to slot 6 -Shift-F8 - Save State to slot 7 -Shift-F9 - Save State to slot 8 -Shift-F10 - Save State to slot 9 - -Command-line Options__________________________________________ - -You can also run the program using command-line options. To see a -full list, run "yabause --help" in the command prompt. - - -3 Contact information_________________________________________ - -General inquiries should go to: -E-mail: guillaume@yabause.org -E-mail: cwx@cyberwarriorx.com - -Windows Port-related inquiries should go to: -E-mail: cwx@cyberwarriorx.com - -Web: http://yabause.org - -Please don't ask for roms, bios files or any other copyrighted -stuff. Please use the forum when you have any questions if -possible. - - -4 Disclaimer__________________________________________________ - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of -the License, or (at your option) any later version. - -This program is distributed in the hope that it will be -useful,but WITHOUT ANY WARRANTY; without even the implied -warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public -License along with this program; if not, write to the Free -Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301 USA - -See the GNU General Public License details in COPYING. diff --git a/yabause/TODO b/yabause/TODO deleted file mode 100644 index ee1f06f2f7..0000000000 --- a/yabause/TODO +++ /dev/null @@ -1 +0,0 @@ -Everything moved to sourceforge trackers. diff --git a/yabause/acinclude.m4 b/yabause/acinclude.m4 deleted file mode 100644 index 099f02511c..0000000000 --- a/yabause/acinclude.m4 +++ /dev/null @@ -1,34 +0,0 @@ -AC_DEFUN([YAB_CHECK_HOST_TOOLS], - [ - AC_CHECK_TOOLS([$1], [$2]) - if test `expr x$[$1] : x$host_alias` -eq 0 ; then - [$1]="" - fi - ]) - -AC_DEFUN([YAB_DEP_DISABLED], - [ - depdisabled=no - for i in $ac_configure_args ; do - if test $i = "'--disable-dependency-tracking'" ; then - depdisabled=yes - fi - done - if test "$depdisabled" = "no" ; then - AC_MSG_ERROR([You must disable dependency tracking -run the configure script again with --disable-dependency-tracking]) - fi - ]) - -AC_DEFUN([YAB_LINK_MINI18N], - [ - AC_ARG_ENABLE(static-mini18n, - AC_HELP_STRING(--enable-static-mini18n, Use a static dependency on mini18n), - [use_static_mini18n=$enableval]) - if test "x$use_static_mini18n" = "xyes" ; then - LIBS="-Wl,-Bstatic -lmini18n -Wl,-Bdynamic $LIBS" - else - LIBS="-lmini18n $LIBS" - fi - AC_DEFINE(HAVE_LIBMINI18N) - ]) diff --git a/yabause/autogen.sh b/yabause/autogen.sh deleted file mode 100644 index 83236d797c..0000000000 --- a/yabause/autogen.sh +++ /dev/null @@ -1,2 +0,0 @@ -aclocal && autoconf && automake --add-missing --copy -cd src/c68k && aclocal && autoconf && automake diff --git a/yabause/autopackage/default.apspec.in b/yabause/autopackage/default.apspec.in deleted file mode 100644 index 84a5d043c8..0000000000 --- a/yabause/autopackage/default.apspec.in +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2006 Guillaume Duhamel -# Copyright 2006 Fabien Coulon -# -# This file is part of Yabause. -# -# Yabause is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# Yabause is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Yabause; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -# -*-shell-script-*- - -[Meta] -RootName: @yabause.org/yabause:$SOFTWAREVERSION -DisplayName: Yabause Sega Saturn Emulator -ShortName: yabause -Maintainer: Guillaume Duhamel -Packager: Guillaume Duhamel -Summary: Yabause is a Sega Saturn emulator. -URL: http://yabause.org/ -License: GNU General Public License, Version 2 -SoftwareVersion: @VERSION@ -AutopackageTarget: 1.0 - -[Description] -This is a Sega Saturn emulator. - -[BuildPrepare] -prepareBuild --enable-static-mini18n CFLAGS='-D_FORTIFY_SOURCE=0' - -[BuildUnprepare] -unprepareBuild - -[Imports] -echo '*' | import - -[Prepare] -# Dependency checking -require @gtk.org/gtk 2.4 - -[Install] -# Put your installation script here -installExe bin/yabause -installDesktop "Game" share/applications/yabause.desktop -installData share/yabause - -[Uninstall] -# Usually just the following line is enough to uninstall everything -uninstallFromLog diff --git a/yabause/configure.in b/yabause/configure.in deleted file mode 100644 index 4777423ece..0000000000 --- a/yabause/configure.in +++ /dev/null @@ -1,616 +0,0 @@ -AC_INIT(yabause, 0.9.10) - -if test "x$host_alias" = "xpowerpc-gekko" ; then - config_guess_sucks=$host_alias - host_alias=powerpc -elif test "x$host_alias" = "xpsp" ; then - config_guess_sucks=$host_alias - host_alias=mips -fi - -AC_CANONICAL_HOST -AC_CANONICAL_TARGET - -if test ! "x$config_guess_sucks" = "x" ; then - host_alias=$config_guess_sucks -fi - -# hack to reset host_alias when we're not cross compiling -if test "x$host_alias" = "x$build_alias"; then - host_alias= -fi - -AM_INIT_AUTOMAKE([1.8.0]) - -AC_PROG_RANLIB - -# Check for --host=psp now because we need to get the PSP SDK directory and -# set linker flags/libraries -if test "x$host_alias" = "xpsp" ; then - AC_MSG_CHECKING([for PSPSDK]) - if test -z "$PSPSDK"; then - saved_IFS=$IFS - IFS=$PATH_SEPARATOR - for dir in $PATH; do - IFS=$saved_IFS - test -z "$dir" && dir=. - if test -x "$dir/psp-config"; then - PSPSDK=`"$dir/psp-config" -p` - test -n "$PSPSDK" && break - fi - done - IFS=$saved_IFS - fi - if test -n "$PSPSDK"; then - AC_MSG_RESULT([$PSPSDK]) - else - AC_MSG_RESULT([not found]) - AC_MSG_ERROR([Please set the PSPSDK variable]) - fi - CFLAGS="-G0 -falign-functions=16 -I$PSPSDK/include -DNO_CLI $CFLAGS" - LDFLAGS="-specs=$PSPSDK/lib/prxspecs -Wl,-q,-T$PSPSDK/lib/linkfile.prx -L$PSPSDK/lib $LDFLAGS" - LIBS="$LIBS -lm -lc -lpspaudio -lpspctrl -lpspdisplay -lpspgu -lpspge -lpsppower -lpsputility -lpspuser" -fi - -AC_PROG_CC - -if test `expr x$CC : x$host_alias` -eq 0 ; then - AC_MSG_ERROR([$CC is not a cross compiler and we're cross-compiling.]) -fi - -AC_PROG_CPP -AC_PROG_INSTALL - -AC_LANG(C) -AC_LANG(C++) - -AC_C_BIGENDIAN - -AM_PROG_CC_C_O -AM_PROG_AS - -# Check what kind of CPU we're running on -case "$target_cpu" in - x86|i?86) yabause_cpu=x86; AC_DEFINE(CPU_X86);; - x86_64|amd64) yabause_cpu=x64; AC_DEFINE(CPU_X64);; - armv7*) yabause_cpu=arm; AC_DEFINE(CPU_ARM);; - *) if test "$host_alias" = psp; then - yabause_cpu=psp; AC_DEFINE(CPU_PSP) - else - yabause_cpu=unknown - fi;; -esac - - -################################################################################# -# # -# phase 1, we're checking for things that could be used by Yabause library # -# # -################################################################################# - -# checking for gettimeofday -AC_CHECK_HEADERS([sys/time.h]) -AC_CHECK_FUNCS([gettimeofday]) - -# checking for floorf (C99 single-precision math) -OLDLIBS="$LIBS" -LIBS="$LIBS -lm" -AC_CHECK_FUNCS([floorf]) -LIBS="$OLDLIBS" - -# checking for mini18n -if test ! "x$MINI18N" = "x" ; then - OLDCPPFLAGS="$CPPFLAGS" - OLDLDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS -I$MINI18N/include" - LDFLAGS="$LDFLAGS -L$MINI18N/lib" - - AC_CHECK_LIB(mini18n, mini18n, [YAB_LINK_MINI18N], [ - CPPFLAGS="$OLDCPPFLAGS" - LDFLAGS="$OLDLDFLAGS" - ]) -else - AC_CHECK_LIB(mini18n, mini18n, [YAB_LINK_MINI18N]) -fi - -# checking for variadic macros -AC_MSG_CHECKING([[whether the compiled supports c99 variadic macros]]) -AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[#define MACRO(...) puts(__VA_ARGS__)]], [[MACRO("foo");]]), - AC_DEFINE(HAVE_C99_VARIADIC_MACROS) - AC_MSG_RESULT(yes), AC_MSG_RESULT(no)) - -# checking for SDL (can be used for sound and input) -use_sdl=yes -AC_ARG_WITH(sdl, AC_HELP_STRING(--without-sdl, don't use SDL), [use_sdl=$withval]) - -if test x$use_sdl = xyes ; then - case $host in - *darwin*) - OLDLDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -framework SDL" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - int t(void) { return 0; } - ]],[[ - int foo = t(); - ]])],[AC_DEFINE(HAVE_LIBSDL) - SDL_LIBS="-framework SDL"], []) - LDFLAGS="$OLDLDFLAGS" - ;; - *) - YAB_CHECK_HOST_TOOLS(HAVE_LIBSDL, [sdl-config sdl11-config]) - - if test ! x$HAVE_LIBSDL = x ; then - SDL_CFLAGS=`$HAVE_LIBSDL --cflags` - SDL_LIBS=`$HAVE_LIBSDL --libs` - AC_DEFINE(HAVE_LIBSDL) - fi - ;; - esac - - CFLAGS="$CFLAGS $SDL_CFLAGS" - LIBS="$LIBS $SDL_LIBS" -fi - -# checking for OpenGL (most ports needs it for video) -use_opengl=yes -AC_ARG_WITH(opengl, AC_HELP_STRING(--without-opengl, don't use OpenGL), [use_opengl=$withval]) - -if test x$use_opengl = xyes ; then - case $host in - *darwin*) - LIBS="$LIBS -framework OpenGL" - AC_DEFINE(HAVE_LIBGL) - ;; - *cygwin* | *mingw32*) - YAB_LIBS="$YAB_LIBS -lopengl32 -lglut32" - AC_DEFINE(HAVE_LIBGL) - ;; - *linux* | *bsd*) - AC_PATH_XTRA - LIBS="$LIBS $X_LIBS" - CFLAGS="$CFLAGS $X_CFLAGS" - - AC_CHECK_LIB(GL, glEnable, [ - LIBS="$LIBS -lGL" - AC_DEFINE(HAVE_LIBGL) - ],, $LIBS) - AC_CHECK_LIB(glut, glutGetModifiers,[ - LIBS="$LIBS -lglut" - AC_DEFINE(HAVE_LIBGLUT)],, $LIBS) - AC_CHECK_FUNC(glXGetProcAddress, AC_DEFINE(HAVE_GLXGETPROCADDRESS)) - ;; - *) - AC_CHECK_LIB(GL, glEnable, [ - LIBS="$LIBS -lGL" - AC_DEFINE(HAVE_LIBGL) - ],, $LIBS) - AC_CHECK_LIB(glut, glutGetModifiers,[ - LIBS="$LIBS -lglut" - AC_DEFINE(HAVE_LIBGLUT)],, $LIBS) - ;; - esac -fi - -# checking for OpenAL (can be used for sound) -use_openal=yes -AC_ARG_WITH(openal, AC_HELP_STRING(--without-openal, "don't use OpenAL"), [use_openal=$withval]) - -if test x$use_openal = xyes ; then - case $host in - *darwin*) - LIBS="$LIBS -framework OpenAL" - AC_DEFINE(HAVE_LIBAL) - ;; - *mingw32*) - # The OpenAL sound code uses Pthreads at the moment, so MinGW - # won't work right now. - ;; - *) - AC_CHECK_LIB(pthread, main) - AC_CHECK_LIB(openal, alBufferData, [ - LIBS="$LIBS -lopenal" - AC_DEFINE(HAVE_LIBAL) - ],, $LIBS) - ;; - esac -fi - -# platform-specific features -case $host in - *darwin*) - yabause_arch=macosx - AC_DEFINE([ARCH_IS_MACOSX]) - LIBS="$LIBS -framework CoreFoundation -framework IOKit" - major=`expr $host_os : "darwin\(@<:@^.@:>@*\)"` - if test $major -ge 7 ; then - sdkversion=0 - sdkfile="" - for i in /Developer/SDKs/MacOSX10.*.sdk; do - j=`expr $i : "/Developer/SDKs/MacOSX10.\(.\).*.sdk"` - if test $j -gt $sdkversion ; then - sdkversion=$j - sdkfile=$i - fi - done - AC_ARG_WITH([sdk], AC_HELP_STRING(--with-sdk, [choose your sdk (macosx only)]), [sdkfile=$withval]) - - YAB_DEP_DISABLED - - CFLAGS="$CFLAGS -mmacosx-version-min=10.3 -isysroot $sdkfile -arch i386 -arch ppc" - LDFLAGS="$LDFLAGS -Wl,-macosx_version_min,10.3 -arch i386 -arch ppc" - AC_DEFINE(MAC_OS_X_VERSION_MAX_ALLOWED, MAC_OS_X_VERSION_10_3) - fi - ;; - *linux*) - yabause_arch=linux - LIBS="$LIBS -lm" - AC_DEFINE([ARCH_IS_LINUX]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int i = CDSL_CURRENT;]])], - [], - [AC_DEFINE(LINUX_CDROM_H_IS_BROKEN)]) - ;; - *cygwin*) - yabause_arch=windows - AC_DEFINE([ARCH_IS_WINDOWS]) - AC_DEFINE(_WIN32_IE, 0x0500) - ;; - *mingw32*) - yabause_arch=windows - AC_DEFINE([ARCH_IS_WINDOWS]) - AC_CHECK_HEADERS("wnaspi32.h", [], [], [#include ]) - AC_DEFINE(_WIN32_IE, 0x0500) - ;; - *freebsd*) - yabause_arch=freebsd - AC_DEFINE([ARCH_IS_FREEBSD]) - ;; - *netbsd* | *openbsd*) - yabause_arch=netbsd - AC_DEFINE([ARCH_IS_NETBSD]) - ;; - *) - case $host_alias in - psp) - yabause_arch=psp - ;; - *) - yabause_arch="." - AC_DEFINE(UNKNOWN_ARCH) - ;; - esac - ;; -esac - -# users can turn c68k compilation off (forced off on PSP) -if test "x$yabause_arch" = "xpsp"; then - compile_c68k=no -else - compile_c68k=yes -fi -AC_ARG_WITH(c68k, AC_HELP_STRING(--without-c68k, don't compile C68k), [compile_c68k=$withval]) -if test x$compile_c68k = xyes ; then - if test "x$yabause_arch" = "xpsp"; then - AC_MSG_ERROR([c68k is not supported on PSP]) - fi - AC_DEFINE(HAVE_C68K) -fi -AM_CONDITIONAL(COMPILE_C68K, test x$compile_c68k = xyes) - -# Q68 emulator is optional (but required on PSP) -if test "x$yabause_arch" = "xpsp"; then - compile_q68=yes -else - compile_q68=no -fi -AC_ARG_WITH(q68, AC_HELP_STRING(--with-q68, [include Q68 68k emulator (requires a C99-compliant compiler like GCC)]), [compile_q68=$withval]) -if test "x$compile_q68" = "xyes"; then - AC_DEFINE(HAVE_Q68) -elif test "x$yabause_arch" = "xpsp"; then - AC_MSG_ERROR([Q68 is required on PSP]) -fi -AM_CONDITIONAL(COMPILE_Q68, test "x$compile_q68" = "xyes") - -# JIT for Q68 can be disabled (and is automatically disabled on unsupported -# systems) -q68_use_jit=maybe -AC_ARG_ENABLE(q68-jit, AC_HELP_STRING(--disable-q68-jit, [disable dynamic (Just-In-Time) translation for Q68]), [q68_use_jit=$enableval]) -case $yabause_cpu in - x86|x64|psp) - if test "x$q68_use_jit" = "xmaybe"; then - q68_use_jit=yes - fi - ;; - *) - if test "x$q68_use_jit" = "xyes"; then - AC_MSG_ERROR([Q68 dynamic translation is not supported on this CPU]); - elif test "x$q68_use_jit" = "xmaybe"; then - AC_MSG_WARN([Disabling Q68 dynamic translation (not supported on this CPU)]); - fi - ;; -esac -if test "x$q68_use_jit" = "xyes"; then - AC_DEFINE(Q68_USE_JIT) -fi -AM_CONDITIONAL([Q68_USE_JIT], test "x$q68_use_jit" = "xyes") - -# Allow disabling of dynarec -AC_ARG_ENABLE(dynarec, AC_HELP_STRING(--disable-dynarec, [Disable dynarec core]), [], [use_dynarec=yes]) - -if test "x$use_dynarec" = "xyes"; then - AC_DEFINE(USE_DYNAREC) -fi - -AM_CONDITIONAL([USE_DYNAREC], test "x$use_dynarec" = "xyes") - -################################################################################# -# # -# phase 2, we're done with Yabause library, now we're tring to configure ports # -# # -################################################################################# - -# qt -AC_PATH_PROGS(HAVE_QMAKE, [qmake-qt4 qmake]) - -if test ! x$HAVE_QMAKE = x ; then - yabause_available_yuis="qt $yabause_available_yuis" -fi - -# gtk -want_gtk=yes -AC_ARG_WITH(gtk, AC_HELP_STRING(--without-gtk, don't try to configure the gtk port), [want_gtk=$withval]) - -YAB_CHECK_HOST_TOOLS(HAVE_PKG, [pkg-config]) -if test ! x$HAVE_PKG = x ; then - if test "x$want_gtk" = "xyes" && `$HAVE_PKG gtk+-2.0` ; then - if test "x$use_opengl" = "xyes" ; then - if `$HAVE_PKG gtkglext-1.0` ; then - yabause_available_yuis="gtk $yabause_available_yuis" - YUI_gtk_CFLAGS=`$HAVE_PKG gtkglext-1.0 --cflags` - YUI_gtk_LIBS=`$HAVE_PKG gtkglext-1.0 --libs` - AC_DEFINE(HAVE_LIBGTKGLEXT) - else - AC_MSG_NOTICE([Found OpenGL and Gtk+ but not libgtkglext.]) - AC_MSG_NOTICE([You can either:]) - AC_MSG_NOTICE([- install libgtkglext to compile a gtk port with OpenGL support]) - AC_MSG_NOTICE([- re-run configure with --without-opengl flag to compile a gtk port without OpenGL support]) - AC_MSG_NOTICE([- re-run configure with --without-gtk flag to disable gtk port compilation]) - AC_MSG_ERROR([Can't go further, please install libgtkglext or re-run configure with --without-opengl or --without-gtk]) - fi - else - yabause_available_yuis="gtk $yabause_available_yuis" - YUI_gtk_CFLAGS=`$HAVE_PKG gtk+-2.0 --cflags` - YUI_gtk_LIBS=`$HAVE_PKG gtk+-2.0 --libs` - fi - fi -fi - -# carbon -OLDLDFLAGS="$LDFLAGS" -LDFLAGS="$LDFLAGS -framework Carbon" -AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - int t(void) { return 0; } - ]],[[ - int foo = t(); - ]])],[YUI_carbon_LIBS="-framework Carbon -framework AGL" - yabause_available_yuis="carbon $yabause_available_yuis"], []) -LDFLAGS="$OLDLDFLAGS" - -# windows -YAB_CHECK_HOST_TOOLS(WINDRES, [windres]) -AC_CHECK_HEADER([windows.h], [yabause_available_yuis="windows $yabause_available_yuis"], []) - -# wii -if test "x$host_alias" = "xpowerpc-gekko" ; then - if test \( "x$LIBOGC" = "x" \) -a \( ! "x$DEVKITPRO" = "x" \) ; then - LIBOGC="$DEVKITPRO/libogc" - fi - if test "x$LIBOGC" = "x" ; then - AC_MSG_ERROR([Please set the LIBOGC variable]) - else - CPPFLAGS="-I$LIBOGC/include $CPPFLAGS" - LDFLAGS="-L$LIBOGC/lib/wii $LDFLAGS" - CFLAGS="-mrvl -mcpu=750 -meabi -mhard-float $CFLAGS" - LIBS="-lfat -lwiiuse -lbte -logc -lm $LIBS" - fi - - AC_DEFINE(GEKKO) - - yabause_available_yuis="wii" -fi - -# PSP -if test "x$host_alias" = "xpsp" ; then - AC_DEFINE(PSP) - yabause_available_yuis="psp" -fi - -# adding . as a fallback when no other port is available -yabause_available_yuis="$yabause_available_yuis ." - -yabause_yui=`echo $yabause_available_yuis | cut -d\ -f1` - -AC_ARG_WITH([port], AC_HELP_STRING(--with-port, choose your port), [yabause_manual_yui=$withval]) -for yabause_available_yui in $yabause_available_yuis; do - if test x$yabause_available_yui = x$yabause_manual_yui; then - yabause_yui=$yabause_manual_yui - fi -done - -if ! test "x$yabause_yui" = "x." ; then - eval YAB_CFLAGS=\$YUI_${yabause_yui}_CFLAGS - eval YAB_LIBS=\$YUI_${yabause_yui}_LIBS - AC_SUBST(YAB_CFLAGS) - AC_SUBST(YAB_LIBS) -fi - -AC_SUBST(yabause_yui) - - -AC_ARG_ENABLE(debug, AC_HELP_STRING(--enable-debug, enable general debug information) , - [if test "x$enableval" = "xyes" ; then - AC_DEFINE(DEBUG) - fi]) -AC_ARG_ENABLE(vdp1-debug, AC_HELP_STRING(--enable-vdp1-debug, enable vdp1 debug information) , - [if test "x$enableval" = "xyes" ; then - AC_DEFINE(VDP1_DEBUG) - fi]) -AC_ARG_ENABLE(vdp2-debug, AC_HELP_STRING(--enable-vdp2-debug, enable vdp2 debug information) , - [if test "x$enableval" = "xyes" ; then - AC_DEFINE(VDP2_DEBUG) - fi]) -AC_ARG_ENABLE(cd-debug, AC_HELP_STRING(--enable-cd-debug, enable cdblock debug information) , - [if test "x$enableval" = "xyes" ; then - AC_DEFINE(CDDEBUG) - fi]) -AC_ARG_ENABLE(smpc-debug, AC_HELP_STRING(--enable-smpc-debug, enable smpc debug information) , - [if test "x$enableval" = "xyes" ; then - AC_DEFINE(SMPC_DEBUG) - fi]) -AC_ARG_ENABLE(scsp-debug, AC_HELP_STRING(--enable-scsp-debug, enable scsp debug information) , - [if test "x$enableval" = "xyes" ; then - AC_DEFINE(SCSP_DEBUG) - fi]) -AC_ARG_ENABLE(idle-debug, AC_HELP_STRING(--enable-idle-debug, enable idle cpu debug information) , - [if test "x$enableval" = "xyes" ; then - AC_DEFINE(IDLE_DETECT_VERBOSE) - fi]) -AC_ARG_ENABLE(mic-shaders, AC_HELP_STRING(--enable-mic-shaders, enable OpenGL shaders for gouraud and mesh) , - [if test "x$enableval" = "xyes" ; then - AC_DEFINE(USEMICSHADERS) - fi]) -AC_ARG_ENABLE(network, AC_HELP_STRING(--enable-network, enable network) , - [if test "x$enableval" = "xyes" ; then - AC_DEFINE(USESOCKET) - fi]) -AC_ARG_ENABLE(perkeyname, AC_HELP_STRING(--enable-perkeyname, use peripheral key name callback) , - [if test "x$enableval" = "xyes" ; then - AC_DEFINE(PERKEYNAME) - fi]) -AC_ARG_ENABLE(exec-from-cache, AC_HELP_STRING(--enable-exec-from-cache, [allow code execution from 0xC0000000]), - [if test "x$enableval" = "xyes" ; then - AC_DEFINE(EXEC_FROM_CACHE) - fi]) -AC_ARG_ENABLE(optimized-dma, AC_HELP_STRING(--enable-optimized-dma, [use optimized DMA when possible]), - [if test "x$enableval" = "xyes" ; then - AC_DEFINE(OPTIMIZED_DMA) - fi]) -AC_ARG_ENABLE(new-scsp, AC_HELP_STRING(--enable-new-scsp, [enable experimental new SCSP implementation]), - [if test "x$enableval" = "xyes" ; then - AC_DEFINE(USE_SCSP2) - fi]) -AM_CONDITIONAL([USE_SCSP2], [test "${enable_new_scsp}" = "yes"]) - - -#### PSP options - -AC_ARG_ENABLE(psp-debug, AC_HELP_STRING(--enable-psp-debug, [enable PSP debugging output]), - [if test "x$enableval" = "xyes" ; then - AC_DEFINE([PSP_DEBUG]) - fi]) - -AC_ARG_ENABLE(psp-profile, AC_HELP_STRING(--enable-psp-profile, [enable profiling on PSP port]), - [if test "x$enableval" = "xyes" ; then - AC_DEFINE([SYS_PROFILE_H], ["psp/profile.h"]) - fi]) - -AC_ARG_WITH(psp-me-test, AC_HELP_STRING(--with-psp-me-test, [build ME library test program])) -AM_CONDITIONAL([BUILD_ME_TEST], [test "${with_psp_me_test}" = "yes"]) - -AC_ARG_ENABLE(debug-psp-sh2, AC_HELP_STRING(--enable-debug-psp-sh2, [include PSP SH-2 core for testing]), - [if test "x$enableval" = "xyes" ; then - AC_DEFINE([TEST_PSP_SH2]) - fi]) -AM_CONDITIONAL([TEST_PSP_SH2], [test "${enable_debug_psp_sh2}" = "yes"]) - -### End PSP options - -AC_CONFIG_FILES([Makefile - l10n/Makefile - doc/Doxyfile - src/Makefile - src/carbon/Makefile - src/dreamcast/Makefile - src/gtk/Makefile - src/gtk/doc/Makefile - src/psp/Makefile - src/qt/Makefile - src/qt/yabause.pro - src/qt/doc/Makefile - src/wii/Makefile - src/windows/Makefile - autopackage/default.apspec -]) -if test x$yabause_yui = xqt ; then - case $host in - *mingw*) - case $build in - *linux*) - qmake_spec="-win32 -spec mkspecs/win32-x11-g++" - ;; - *darwin*) - qmake_spec="-win32 -spec mkspecs/win32-osx-g++" - ;; - *) - if test "x$cross_compiling" = "xyes" ; then - AC_MSG_ERROR([cross-compiling $host port on $build is not supported yet]) - fi - ;; - esac - ;; - *darwin*) - case $build in - *darwin*) - qmake_spec="-spec macx-g++" - ;; - *) - AC_MSG_ERROR([cross-compiling $host port on $build is not supported yet]) - ;; - esac - ;; - *) - if test "x$cross_compiling" = "xyes" ; then - AC_MSG_ERROR([cross-compiling $host port on $build is not supported yet]) - fi - ;; - esac - AC_CONFIG_FILES([src/qt/Makefile.qmake:src/qt/yabause.pro], - [( cd src/qt && $QMAKE yabause.pro $QMAKE_SPEC -o Makefile.qmake )], - [QMAKE=$HAVE_QMAKE QMAKE_SPEC="$qmake_spec"]) -fi - -AC_CONFIG_COMMANDS([src/c68k/Makefile], [( cd src/c68k/ && $CONFIG_SHELL ${ac_srcdir}/configure )]) - -AM_CONDITIONAL([YUI_IS_CARBON], [test ${yabause_yui} = "carbon"]) -AM_CONDITIONAL([YUI_IS_DREAMCAST], [test ${yabause_yui} = "dreamcast"]) -AM_CONDITIONAL([YUI_IS_GTK], [test ${yabause_yui} = "gtk"]) -AM_CONDITIONAL([YUI_IS_PSP], [test ${yabause_yui} = "psp"]) -AM_CONDITIONAL([YUI_IS_QT], [test ${yabause_yui} = "qt"]) -AM_CONDITIONAL([YUI_IS_WII], [test ${yabause_yui} = "wii"]) -AM_CONDITIONAL([YUI_IS_WINDOWS], [test ${yabause_yui} = "windows"]) - -AM_CONDITIONAL([ARCH_IS_FREEBSD], [test ${yabause_arch} = "freebsd"]) -AM_CONDITIONAL([ARCH_IS_LINUX], [test ${yabause_arch} = "linux"]) -AM_CONDITIONAL([ARCH_IS_MACOSX], [test ${yabause_arch} = "macosx"]) -AM_CONDITIONAL([ARCH_IS_NETBSD], [test ${yabause_arch} = "netbsd"]) -AM_CONDITIONAL([ARCH_IS_WINDOWS], [test ${yabause_arch} = "windows"]) - -AM_CONDITIONAL([CPU_IS_ARM], [test ${yabause_cpu} = "arm"]) -AM_CONDITIONAL([CPU_IS_X86], [test ${yabause_cpu} = "x86"]) -AM_CONDITIONAL([CPU_IS_X64], [test ${yabause_cpu} = "x64"]) -AM_CONDITIONAL([CPU_IS_PSP], [test ${yabause_cpu} = "psp"]) - -AC_OUTPUT - -echo "==================" -echo "WARNING" -echo -echo "Compiling Yabause with autootols is deprecated" -echo -echo "Please use CMake instead" -echo -echo "==================" -echo "configure report" -echo -echo "available ports: $yabause_available_yuis" -echo "selected port: $yabause_yui" -echo "==================" diff --git a/yabause/doc/CMakeLists.txt b/yabause/doc/CMakeLists.txt deleted file mode 100644 index ebd9fec1f3..0000000000 --- a/yabause/doc/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -project(yabause-doc) - -find_package(Doxygen) -if(DOXYGEN_FOUND) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) - add_custom_target(doc - ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Generating documentation with Doxygen" VERBATIM - ) -endif(DOXYGEN_FOUND) diff --git a/yabause/doc/Doxyfile.in b/yabause/doc/Doxyfile.in deleted file mode 100644 index 2f1988b034..0000000000 --- a/yabause/doc/Doxyfile.in +++ /dev/null @@ -1,1356 +0,0 @@ -# Doxyfile 1.5.5 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = Yabause - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, -# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, -# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, -# and Ukrainian. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = @CMAKE_CURRENT_SOURCE_DIR@/.. - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = @CMAKE_CURRENT_SOURCE_DIR@/../src - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentstion. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = YES - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = @DOXYGEN_DOT_FOUND@ - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is enabled by default, which results in a transparent -# background. Warning: Depending on the platform used, enabling this option -# may lead to badly anti-aliased labels on the edges of a graph (i.e. they -# become hard to read). - -DOT_TRANSPARENT = YES - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/yabause/l10n/CMakeLists.txt b/yabause/l10n/CMakeLists.txt deleted file mode 100644 index c18f927dbf..0000000000 --- a/yabause/l10n/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -project(yabause-l10n) - -set(LANGS de es fr it lt pt pt_BR sv) - -if (UNIX AND NOT APPLE) - foreach(LANG ${LANGS}) - install(FILES "yabause_${LANG}.yts" DESTINATION "share/yabause/yts" RENAME "${LANG}.yts") - endforeach() -elseif (WIN32) - foreach(LANG ${LANGS}) - install(FILES "yabause_${LANG}.yts" DESTINATION "trans" RENAME "${LANG}.yts") - endforeach() -endif () diff --git a/yabause/l10n/Makefile.am b/yabause/l10n/Makefile.am deleted file mode 100644 index 4375084617..0000000000 --- a/yabause/l10n/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -LANGS=de es fr it lt pt pt_BR sv - -dist-hook: - @for l in $(LANGS) ; do \ - cp -p "$(srcdir)/$(PACKAGE)_$$l.yts" "$(distdir)/$(PACKAGE)_$$l.yts" ; \ - done - -install-data-hook: - test -z "$(DESTDIR)$(datadir)/$(PACKAGE)/yts" || $(MKDIR_P) "$(DESTDIR)$(datadir)/$(PACKAGE)/yts" - @for l in $(LANGS) ; do \ - echo " $(INSTALL_DATA) $(PACKAGE)_$$l.yts $(DESTDIR)$(datadir)/$(PACKAGE)/yts/$$l.yts" ; \ - $(INSTALL_DATA) "$(srcdir)/$(PACKAGE)_$$l.yts" "$(DESTDIR)$(datadir)/$(PACKAGE)/yts/$$l.yts" ; \ - done - -uninstall-hook: - @for l in $(LANGS) ; do \ - echo " rm -f $(DESTDIR)$(datadir)/$(PACKAGE)/yts/$$l.yts" ; \ - rm -f "$(DESTDIR)$(datadir)/$(PACKAGE)/yts/$$l.yts" ; \ - done diff --git a/yabause/l10n/yabause_de.yts b/yabause/l10n/yabause_de.yts deleted file mode 100644 index c75de6a581..0000000000 --- a/yabause/l10n/yabause_de.yts +++ /dev/null @@ -1,195 +0,0 @@ -%1/%2 blocks free|%1/%2 blöcke frei -%1 Images (*.%2)|Bilder %1 (*.%2) -503/512 blocks free|503/512 blöcke frei -510/512 blocks free|510/512 blöcke frei -About...|Über... -&About...|&Ü Über... -About|Über -&Action Replay|&Action Replay -Action Replay Code :|Action Replay Code : -Add Action Replay Code|Action Replay Code zufügen -Add Codes...|Codes zufügen... -Add Raw Memory Code|Raw Memory Code zufügen -Address :|Adresse : -Advanced|Sonstiges -| -Are you sure you want to delete '%1' ?|Sind Sie sicher, dass Sie '%1' löschen möchten ? -Are you sure you want to format '%1' ?|Sind Sie sicher, dass Sie '%1' formatieren möchten ? -Backup Manager|Backup Manager -Backup Manager...|Backup Manager... -&Backup Ram Manager|&Backup Ram Manager -Backup Ram Manager|Backup Ram Manager -Bios|Bios -Block Size :|Blockgröße : -&Browse|&Browse -Browse|Suchen -Byte Write|Byte schreiben -Cancel|Abbrechen -Cannot initialize|Initialisierung fehlgeschlagen -&Capture Screen|&Capture Screen -Cart/Memory|Cartridge/Speicher -Cartridge|Cartridge -CD Images (*.iso *.cue *.bin)|CD Images (*.iso *.cue *.bin) -Cd-Rom|Cd-Rom -&Cheats|&Cheats -Cheats|Cheats -Cheats File|Cheatdatei -&Cheat List|&Cheat List -Cheats List|Cheatliste -Cheats List...|Cheatliste... -Cheat Type|Cheattyp -Choose a cdrom drive/mount point|CD-Rom Laufwerk/Mount-Punkt auswählen -Choose a cheat file to open|Cheatdatei zum öffnen auswählen -Choose a cheat file to save to|Cheatdatei zum speichern auswählen -Choose a file to save your state|Datei zum speichern des Status auswählen -Choose a location for your screenshot|Speicherort für das Bildschirmfoto auswählen -&Clear|&Leeren -Close|Schliessen -Code|Code -Comment :|Kommentar : -Data Size :|Datengrösse : -_Debug|_Debug -&Debug|&Debug -&Delete|&Löschen -Delete|Löschen -Description|Beschreibung -Description :|Beschreibung : -Device List|Geräteliste -Disabled|Deaktiviert -Down|Runter -Download|Herunterladen -Emu-Compatibility|Emu-Kombatibilität -Emulation|Emulation -End Address:|Adressende -Enable|Aktivieren -Enabled|Aktiviert -English|Englisch -&File|&Datei -File|Datei -File :|File : -File Name :|Dateiname : -File transfer|Dateiübertragung -WARNING: Master Codes are NOT supported.|WARNUNG :Mastercodes werden NICHT unterstützt. -Format|Formatieren -FPS|BPS -Frame Skip/Limiter|Frames überspringen/limitieren -French|Französisch -From|Von -From File|Von Datei -From File...|Von Datei... -&Fullscreen|&Vollbild -Fullscreen|Vollbild -General|Allgemein -German|Deutsch -Hard Reset|Hard Reset -Height|Höhe -_Help|_Hilfe -&Help|&Hilfe -http://www.emu-compatibility.com/yabause/index.php?lang=uk|http://www.emu-compatibility.com/yabause/index.php?lang=de -http://www.monkeystudio.org|http://www.monkeystudio.org -Input|Eingabe -Invalid Address|Ungültige Adresse -Invalid Value|Ungültiger Wert -Italian|Italienisch -Japanese|Japanisch -Language :|Sprache : -&Layer|&Schicht -Layer|Schicht -Left|Links -Left trigger|Linker Trigger -Load as executable|Als ausführbar laden -Load|Laden -&Load From File|&Von Datei laden -Load State|Spielstand laden -Load State As|Spielstand laden als -Log|Protokoll -Long Write|Long schreiben -M68K|M68K -Memory dump|Speicherabzug -Memory Dump|Speicherabzug -Memory Editor|Memory Editor -&Memory Transfer|&Memory Transfer -Memory Transfer|Memory Transfer -Memory|Speicher -Mpeg ROM|Mpeg ROM -MSH2|MSH2 -NBG0|NBG0 -NBG1|NBG1 -NBG2|NBG2 -NBG3|NBG3 -Ok|Ok -&OK|&OK -Open CD Rom|CD-Rom öffnen -Open CD Rom...|CD-Rom öffnen... -Open ISO|ISO öffnen -Open ISO...|ISO öffnen... -&Pause|&Pause -Pause|Pause -&Quit|&Schliessen -Quit|Schliessen -&Raw Memory Address|&Raw Speicheradresse -RBG0|RBG0 -Region|Region -&Reset|&Zurücksetzen -Reset|Zurücksetzen -Resolution|Auflösung -Right|Rechts -Right trigger|Rechter Trigger -R&un|S&tarten -Run|Starten -Save Information|Informationen speichern -Save List|Liste speichern -Save|Speichern -Save State|Status speichern -Save State As|Save State As -Save States|Stati speichern -&Save To File|&In Datei speichern -Screenshot|Bilschirmfoto -SCSP|SCSP -SCU-DSP|SCU-DSP -Select a file to load your state|Wählen Sie die Statusdatei aus -Select your iso/cue/bin file|Wählen Sie Ihre iso/cue/bin-Datei -&Settings...|Einstellungen... -Settings|Einstellungen -SH2 Interpreter|SH2 Interpreter -Sound Core|Sound Kern -Sound|Sound -Spanish|Spanisch -SSH2|SSH2 -Start|Start -Start Address:|Adressanfang -Status|Status -Store|Sichern -To File|in Datei -To File...|in Datei... -toolBar|Werkzeugleiste -Tools|Tools -To|zu -Transfer|Transferieren -Translation|Übersetzung -Unable to add code|Code konnte nicht zugefügt werden -Unable to change description|Beschreibung konnte nicht geändert werden -Unable to open file for loading|Datei konnte nicht geöffnet werden -Unable to open file for saving|Datei konnte nicht geschrieben werden -Unable to remove code|Code konnte nicht entfernt werden -Unknow (%1)|Unbekannt (%1) -Up|Hoch -Upload|Upload -Value :|Wert : -Vdp1|Vdp1 -VDP1|VDP1 -Vdp2|Vdp2 -VDP2|VDP2 -Video Core|Video Kern -Video Driver|Video Treiber -Video Format|Video Format -Video|Video -_View|_Sicht -&View|&Sicht -Waiting Input...|Warte auf EIngaben... -Width|Breite -Word Write|Word schreiben -Yabause Cheat Files (*.yct);;All Files (*)|Yabause Cheat Dateien (*ycf);;Alle Dateien (*) -Yabause Qt Gui
    Based on Yabause 0.9.5
    http://yabause.org
    The Yabause Team
    Filipe AZEVEDO|Yabause Qt Gui
    Based on Yabause 0.9.5
    http://yabause.org
    The Yabause Team
    Filipe AZEVEDO -Yabause Qt GUI|Qt Grafik-Interface für Yabause -Yabause Save State (*.yss)|Yabause Speicherstände (*.yss) diff --git a/yabause/l10n/yabause_es.yts b/yabause/l10n/yabause_es.yts deleted file mode 100644 index aa10478704..0000000000 --- a/yabause/l10n/yabause_es.yts +++ /dev/null @@ -1,198 +0,0 @@ -%1/%2 blocks free|%1/%2 bloques libres -%1 Images (*.%2)|%1 Imágenes (*.%2) -503/512 blocks free|503/512 bloques libres -510/512 blocks free|510/512 bloques libres -About...|Acerca de... -&About...|&Acerca de... -About|Acerca de -&Action Replay|&Action Replay -Action Replay Code :|Código de Action Replay -Add Action Replay Code|Añadir Código de Action Replay -Add Codes...|Añadir Códigos... -Add Raw Memory Code|Añadir código dirección de memoria -Address :|Dirección : -Advanced|Avanzado -| -Are you sure you want to delete '%1' ?|¿Estás seguro de borrar '%1' ? -Are you sure you want to format '%1' ?|¿Estás seguro de formatear '%1' ? -Backup Manager|Gestor de memoria de backup -Backup Manager...|Gestor de memoria de backup... -&Backup Ram Manager|Gestor de RAM de &backup -Backup Ram Manager|Gestor de RAM de backup -Bios|Bios -Block Size :|Tamaño de bloque: -&Browse|&Examinar -Browse|Examinar -Byte Write|Escritura de byte -Cancel|Cancelar -Cannot initialize|Imposible iniciar -&Capture Screen|&Capturar pantalla -Cart/Memory|Cartucho/Memoria -Cartridge|Cartucho -CD Images (*.iso *.cue *.bin)|Imágenes de CD (*.iso *.cue *.bin) -Cd-Rom|Cd-Rom -&Cheats|&Trucos -Cheats|Trucos -Cheats File|Archivo de trucos -&Cheat List|Listado de &Trucos -Cheats List|Lista de trucos -Cheats List...|Lista de trucos... -Cheat Type|Tipo de truco -Choose a cdrom drive/mount point|Selecciona una unidad de cdrom/punto de montaje -Choose a cheat file to open|Selecciona un archivo de trucos para abrir -Choose a cheat file to save to|Selecciona el archivo de trucos para guardar -Choose a file to save your state|Selecciona un archivo para guardar tu estado -Choose a location for your screenshot|Selecciona ubicación para tu captura -&Clear|&Limpiar -Close|Cerrar -Code|Código -Comment :|Comentario : -Data Size :|Tamaño de datos : -_Debug|_Debug -&Debug|&Debug -&Delete|&Borrar -Delete|Borrar -Description|Descripción -Description :|Descripción : -Device List|Lista de Dispositivos -Disabled|Desactivado -Down|Abajo -Download|Descargar -Emu-Compatibility|Compatibilidad del emulador -Emulation|Emulación -End Address:|Dirección final: -Enable|Activar -Enabled|Activado -English|Inglés -&File|&Archivo -File|Archivo -File :|Archivo: -File Name :|Nombre de archivo : -File transfer|Transferencia de archivo -WARNING: Master Codes are NOT supported.|AVISO: Códigos Maestros NO soportados. -Format|Formato -FPS|FPS -Frame Skip/Limiter|Salto de cuadros/Limitador -French|Francés -From|De -From File|De archivo -From File...|De archivo... -&Fullscreen|&Pantalla completa -Fullscreen|Pantalla completa -General|General -German|Alemán -Hard Reset|Reiniciar en frío -Height|Altura -_Help|_Ayuda -&Help|&Ayuda -http://www.emu-compatibility.com/yabause/index.php?lang=uk|http://www.emu-compatibility.com/yabause/index.php?lang=uk -http://www.monkeystudio.org|http://www.monkeystudio.org -Input|Entrada -Invalid Address|Dirección inválida -Invalid Value|Valor inválido -Italian|Italiano -Japanese|Japonés -Language :|Idioma : -&Layer|&Capa -Layer|Capa -Left|Izquierda -Left trigger|Gatillo izquierdo -Load as executable|Cargar como ejecutable -Load|Cargar -&Load From File|&Cargar desde archivo -Load State|Cargar estado -Load State As|Cargar estado como -Log|Log -Long Write|Escritura larga -M68K|M68K -Memory dump|Volcado de memoria -Memory Dump|Volcado de Memoria -Memory Editor|Editor de memoria -&Memory Transfer|Transferir &memoria -Memory Transfer|Transferir memoria -Memory|Memoria -Mpeg ROM|ROM Mpeg -Mouse|Ratón -MSH2|MSH2 -NBG0|NBG0 -NBG1|NBG1 -NBG2|NBG2 -NBG3|NBG3 -None|Ninguno -Ok|Ok -&OK|&OK -Open CD Rom|Abrir CD Rom -Open CD Rom...|Abrir CD Rom... -Open ISO|Abrir ISO -Open ISO...|Abrir ISO... -Pad|Pad -&Pause|&Pausar -Pause|Pausar -&Quit|&Sair -Quit|Sair -&Raw Memory Address|&Dirección de memoria Raw -RBG0|RBG0 -Region|Región -&Reset|&Resetear -Reset|Resetear -Resolution|Resolución -Right|Derecha -Right trigger|Gatillo derecho -R&un|E&jecutar -Run|Ejecutar -Save Information|Guardar informes -Save List|Lista de salvaguardados -Save|Salvar -Save State|Guardar Estado -Save State As|Guardar estado como -Save States|Guardar estados -&Save To File|&Guardar a archivo -Screenshot|Captura de pantalla -SCSP|SCSP -SCU-DSP|SCU-DSP -Select a file to load your state|Selecciona el archivo para cargar tu estado -Select your iso/cue/bin file|Selecciona tu archivo iso/cue/bin -&Settings...|&Configuración... -Settings|Configuración -SH2 Interpreter|Intérprete SH2 -Sound Core|Núcleo de sonido -Sound|Sonido -Spanish|Español -SSH2|SSH2 -Start|Iniciar -Start Address:|Dirección inicial: -Status|Estado -Store|Almacenar -To File|A archivo -To File...|A archivo... -toolBar|Barra de herramientas -Tools|Herramientas -To|Para -Transfer|Transferencia -Translation|Traducción -Unable to add code|Imposible añadir código -Unable to change description|Imposible cambiar descripción -Unable to open file for loading|Imposible abrir archivo para cargar -Unable to open file for saving|Imposible abrir archivo para guardar -Unable to remove code|Imposible eliminar código -Unknow (%1)|Desconocido (%1) -Up|Arriba -Upload|Subir -Value :|Valor : -Vdp1|Vdp1 -VDP1|VDP1 -Vdp2|Vdp2 -VDP2|VDP2 -Video Core|Núcleo de Vídeo -Video Driver|Driver de Vídeo -Video Format|Formato de Vídeo -Video|Vídeo -_View|_Ver -&View|&Ver -Waiting Input...|Esperando Entrada de Datos... -Width|Ancho -Word Write|Escribir WORD -Yabause Cheat Files (*.yct);;All Files (*)|Archivos de trucos para Yabause (*.yct);;Todos los archivos (*) -Yabause Qt Gui
    Based on Yabause 0.9.5
    http://yabause.org
    The Yabause Team
    Filipe AZEVEDO|Interfaz gráfica QT
    Basada en Yabause 0.9.5
    http://yabause.org
    El equipo de Yabause
    Filipe AZEVEDO -Yabause Qt GUI|Interfaz gráfica Qt -Yabause Save State (*.yss)|Salvaguardados de Yabause (*.yss) diff --git a/yabause/l10n/yabause_fr.yts b/yabause/l10n/yabause_fr.yts deleted file mode 100644 index 799bd817ed..0000000000 --- a/yabause/l10n/yabause_fr.yts +++ /dev/null @@ -1,276 +0,0 @@ -%1/%2 blocks free|%1/%2 blocs libre -%1 Images (*.%2)|Images %1 (*.%2) -503/512 blocks free|503/512 blocs libre -510/512 blocks free|510/512 blocs libre -About...|A Propos De... -&About...|&A Propos De... -About|A Propos De -&Action Replay|&Action Replay -Action Replay Code :|Code Action Replay : -Add Action Replay Code|Ajouter un Code Action Replay -Add Cheat|Ajouter un Cheat -Add Codes...|Ajouter un Code... -Add Raw Memory Code|Ajouter un Code Mémoire Brut -Address|Adresse -Address :|Adresse : -Advanced|Avancé -Always|Toujours -Asia (NTSC)|Asie (NTSC) -Asia (PAL)|Asie (PAL) -Are you sure you want to delete '%1' ?|Etes vous sûr de vouloir supprimer '%1' ? -Are you sure you want to format '%1' ?|Etes vous sûr de vouloir formater '%1' ? -Auto-detect|Détection Auto -Autostart|Démarrage Automatique -Backup Manager|Gestion des Sauvegardes -&Backup Manager...|&Gestion des Sauvegardes... -Backup Manager...|Gestion des Sauvegardes... -&Backup Ram Manager|&Gestion des Sauvegardes -Backup Ram Manager|Gestion des Sauvegardes -Bios|Bios : -Block Size :|Taille du Bloc : -&Browse|&Parcourir -Browse|Parcourir -Byte Write|Ecrire un Byte -&Cancel|&Annuler -Cancel|Annuler -Cannot initialize|Ne peut pas Initialiser -Cannot initialize Windows SPTI Driver|Ne peut pas initialiser le pilote SPTI -&Capture Screen|&Capture d'Ecran -Cart/Memory|Cartouche/Mémoire -Cartridge|Cartouche : -CD Images (*.iso *.cue *.bin)|Images CD (*.iso *.cue *.bin) -Cd-Rom|CD-Rom : -Central/South America (NTSC)|Amérique du Sud/Centrale (NTSC) -Central/South America (PAL)|Amérique du Sud/Centrale (PAL) -&Cheats|&Cheats -Cheats|Cheats -Cheats File|Fichier Cheat -&Cheat List|Liste de &Cheat -Cheats List|Liste de Cheat -&Cheats List...|Liste de &Cheat... -Cheats List...|Liste de Cheat... -Cheat &Search...|&Rechercher un Cheat... -Cheat Search|Rechercher un Cheat -Cheat Type|Type de Cheat -Choose a cdrom drive/mount point|Choisir un lecteur CD ou un point de montage -Choose a cheat file to open|Choisir un fichier de Cheat à ouvrir -Choose a cheat file to save to|Choisir un fichier de Cheat à enregistrer -Choose a file to save your state|Choisir un fichier où enregistrer l'état -Choose a location for your screenshot|Choisir un nom de fichier pour votre capture d'écran -&Clear|&Effacer -Clear configuration|Vider la Configuration -&Close|&Fermer -Close|Fermer -Code|Code -Comment :|Commentaire : -Compare Type|Type de Comparaison -Data Size|Taille Donnée -Data Size :|Taille des Données : -Data Type|Type Donnée -_Debug|_Débug -&Debug|&Débug -&Delete|&Effacer -Delete|Effacer -Description|Description -Description :|Description : -Device List|Liste des Périphériques -Disabled|Désactivé -Down|Bas -Download|Télécharger -Dummy CD Drive|Lecteur de CD Factice -Dummy Input Interface|Interface Contrôleur Factice -Dummy OSD Interface|Interface OSD Factice -Dummy Sound Interface|Interface Son Factice -Dummy Video Interface|Interface Vidéo Factice -Edit configuration|Editer la Configuration -Emu-Compatibility|Emu-Compatibility -&Emulation|&Emulation -Emulation|Emulation -End Address:|Adresse de Fin : -Enable|Activer -Enable Frame Skip/Limiter|Active le Saut d'Image/Limitateur -Enabled|Activé -English|Anglais -Europe + others (PAL)|Europe + Autres (PAL) -Exact|Identique -&File|&Fichier -File|Fichier -File :|Fichier : -File:|Fichier : -File Name :|Nom du Fichier : -File transfer|Transfert de Fichier -WARNING: Master Codes are NOT supported.|AVERTISSEMENT : Les Codes Maîtres NE SONT PAS supportés. -Format|Formater -FPS|FPS -Frame Skip/Limiter|Saut d'Image/Limitateur -&Frame Skip/Limiter|&Saut d'Image/Limitateur -French|Français -From|A Partir De -From File|A Partir d'un Fichier -From File...|A Partir d'un Fichier... -&Fullscreen|&Plein Ecran -Fullscreen|Plein Ecran -General|Général -German|Allemand -Glut OSD Interface|Interface OSD GLut -Greater then|Plus grand que -Hard Reset|Redémarrage Matériel -Height|Hauteur : -_Help|_Aide -&Help|&Aide -Hide menubar|Cacher la Barre de Menu -Hide toolbar|Cacher la Barre d'Outils -http://www.emu-compatibility.com/yabause/index.php?lang=uk|http://www.emu-compatibility.com/yabause/index.php?lang=fr -http://www.monkeystudio.org|http://www.monkeystudio.org -Information...|Information... -Input|Contrôleur -Invalid Address|Adresse Invalide -Invalid Value|Valeur Invalide -ISO-File Virtual Drive|Lecteur de Fichier ISO Virtuel -Italian|Italien -Japan (NTSC)|Japon (NTSC) -Japanese|Japonais -Korea (NTSC)|Corée (NTSC) -Language :|Langage : -&Layer|&Couche -Layer|Couche -Left|Gauche -Left trigger|Gâchette Gauche -Less than|Moins que -Linux CD Drive|Lecteur CD Linux -Load as executable|Charger en tant qu'Executable -Load|Charger -&Load From File|&Charger à Partir d'un Fichier -L&oad State|&Charger un Etat -Load State|Charger l'Etat -Load State As|Charger l'Etat sous -&Log|&Journal -Log|Journal -Long Write|Ecrire un Long -M68K|M68K -&Master SH2|&Master SH2 -Master SH2|Master SH2 -Memory dump|Copier la mémoire -Memory Dump|Copier la Mémoire -Memory &Editor|&Editeur de Mémoire -Memory Editor|Editeur de Mémoire -&Memory Transfer|&Transfert de Mémoire -Memory Transfer|Transfert de Mémoire -Memory|Mémoire : -Mpeg ROM|ROM MPEG : -Mouse|Souris -MSH2|MSH2 -NBG0|NBG0 -NBG1|NBG1 -NBG2|NBG2 -NBG3|NBG3 -Never|Jamais -None|Aucun -North America (NTSC)|Amérique du Nord (NTSC) -Ok|Ok -&OK|&OK -On fullscreen|Plein Ecran -Open CD Rom|Ouvrir un CD ROM -Open &CD Rom...|Ouvrir un &CD Rom... -Open CD Rom...|Ouvrir un CD ROM... -Open ISO|Ouvrir un Fichier ISO -Open &ISO...|Ouvrir un &ISO... -Open ISO...|Ouvrir un Fichier ISO... -OpenGL Video Interface|Interface Vidéo OpenGL -OSD Core|Noyau OSD -Pad|Manette -Pad Configuration|Configuration de la Manette -&Pause|&Pause -Pause|Pause -Qt Keyboard Input Interface|Interface Qt du Clavier -&Quit|&Quitter -Quit|Quitter -&Raw Memory Address|Adresse Mémoire &Brut -RBG0|RBG0 -Region|Région : -&Reset|&Redémarrer -Reset|Redémarrer -Resolution|Résolution : -Right|Droite -Right trigger|Gâchette Droite -R&un|L&ancer -Run|Lancer -Save Information|Informations sur la Sauvegarde -Save List|Liste des Sauvegardes -Save|Sauvegarder -S&ave State|S&auvegarder un Etat -Save State|Sauvegarder l'Etat -Save State As|Sauvegarder l'Etat sous -Save States|Sauvegarde d'Etat : -&Save To File|&Sauvegarder Vers le Fichier -Sc&reenshot|Copie d'Ec&ran -Screenshot|Capture d'Ecran -SCSP|SCSP -SCU-DSP|SCU-DSP -SDL Joystick Interface|Interface SDL du Joystick -SDL Sound Interface|Interface SDL du Son -Search|Rechercher -Search/Add Cheats|Rechercher/Ajouter un Cheat -Search Value:|Rechercher une Valeur : -Select a file to load your state|Choisissez un fichier pour charger l'état -Select your iso/cue/bin file|Choisissez votre fichier iso/cue/bin -Set PC to Start Address|Sélection PC vers l'Adresse de Démarrage -&Settings...|&Paramétres... -Settings|Paramétres -SH2 Debugger Interpreter|Interpréteur de Débugeur SH2 -SH2 Dynamic Recompiler|Recompileur Dynamique SH2 -SH2 Interpreter|Interpréteur SH2 : -Show FPS|Afficher les FPS -&Slave SH2|&Slave SH2 -Slave SH2|Slave SH2 -Software Video Interface|Interface Vidéo Logiciel -Sound Core|Noyau Son : -Sound|Son -Spanish|Espagnol -SSH2|SSH2 -Signed|Signé -Software OSD Interface|Interface OSD Logiciel -Start|Démarrer -Start Address:|Adresse de Début : -Status|Statut -Store|Stocker -To File|Vers un Fichier -To File...|Vers un Fichier... -toolBar|Barre d'Outils -&Tools|Ou&tils -Tools|Outils -To|Vers -&Transfer|&Transfert -Transfer|Transfert -Translation|Traduction : -Unable to add code|Ne peut pas ajouter de Code -Unable to change description|Ne peut pas changer la Description -Unable to open file for loading|Ne peut pas ouvrir le fichier à Charger -Unable to open file for saving|Ne peut pas ouvrir le fichier à sauvegarder -Unable to remove code|Ne peut pas enlever le Code -Unknow (%1)|Inconnu (%1) -Unsigned|Non Signé -Up|Haut -Upload|Upload -Value|Valeur -Value :|Valeur : -Vdp1|Vdp1 -VDP1|VDP1 -Vdp2|Vdp2 -VDP2|VDP2 -Video Core|Noyau Vidéo : -Video Driver|Pilote Vidéo : -Video Format|Format Vidéo : -Video|Vidéo -_View|_Visualiser -&View|&Visualiser -View|Visualiser -Waiting Input...|En Attente du Contrôleur -Width|Largeur : -Windows SPTI Driver|Pilote Windows SPTI -Word Write|Ecrire un Word -Yabause Cheat Files (*.yct);;All Files (*)|Fichiers de Cheat Yabause (*ycf);;Tous les Fichiers (*) -Yabause is not initialized, can't manage backup ram.|Yabause n'est pas initialisé. Ne peut pas gérer la sauvegarde. -Yabause Qt Gui
    Based on Yabause %1
    http://yabause.org
    The Yabause Team
    Filipe AZEVEDO|Yabause Qt Gui
    Basé sur Yabause %1 :
    http://yabause.org
    L'équipe de Yabause :
    Filipe AZEVEDO -Yabause Qt GUI|Interface Graphique Qt pour Yabause -Yabause Save State (*.yss)|Sauvegarde d'État Yabause (*.yss) diff --git a/yabause/l10n/yabause_it.yts b/yabause/l10n/yabause_it.yts deleted file mode 100644 index 89b201c316..0000000000 --- a/yabause/l10n/yabause_it.yts +++ /dev/null @@ -1,198 +0,0 @@ -%1/%2 blocks free|%1%2 blocchi liberi -%1 Images (*.%2)|%1 Immagini (*.%2) -503/512 blocks free|503/512 blocchi liberi -510/512 blocks free|510/512 blocchi liberi -About...|Informazioni... -&About...|&Informazioni... -About|Informazioni -&Action Replay|&Action Replay -Action Replay Code :|Codice Action Replay -Add Action Replay Code|Aggiungi codice Action Replay -Add Codes...|Aggiungi codici.... -Add Raw Memory Code|Aggiungi Raw Memory Code -Address :|Indirizzo: -Advanced|Avanzate -|http://www.monkeystudio.org"> -Are you sure you want to delete '%1' ?|Sicuro di voler cancellare '%1'? -Are you sure you want to format '%1' ?|Sicuro di voler formattare '%1'? -Backup Manager|Gestione Backup -Backup Manager...|Gestione Backup... -&Backup Ram Manager|&Gestione Backup RAM -Backup Ram Manager|Gestione Backup RAM -Bios|BIOS -Block Size :|Dimensioni Blocco: -&Browse|&Sfoglia -Browse|Sfoglia -Byte Write|Scrivi Byte -Cancel|Annulla -Cannot initialize|Impossibile Inizializzare -&Capture Screen|&Cattura Schermo -Cart/Memory|Cart/Memoria -Cartridge|Cartuccia -CD Images (*.iso *.cue *.bin)|Immagine CD (*.iso *.cue *.bin) -Cd-Rom|Cd-Rom -&Cheats|&Cheats -Cheats|Cheats -Cheats File|File Cheats -&Cheat List|Lista &Cheat -Cheats List|Lista Cheat -Cheats List...|Lista Cheat... -Cheat Type|Tipo di Cheat -Choose a cdrom drive/mount point|Choose a cdrom drive/mount point -Choose a cheat file to open|Selezionare un file cheat da aprire -Choose a cheat file to save to|Selezionare un file cheat per salvare -Choose a file to save your state|Selezionare un file per salvare lo stato -Choose a location for your screenshot|Selezionare una directory per gli screenshoot -&Clear|&Svuota -Close|Chiudi -Code|Codice -Comment :|Commento: -Data Size :|Dimensioni Dati: -_Debug|_Debug -&Debug|&Debug -&Delete|&Elimina -Delete|Elimina -Description|Descrizione -Description :|Descrizione: -Device List|Lista periferiche -Disabled|Disattivo -Down|Giù -Download|Download -Emu-Compatibility|Compatibilità Emulatore -Emulation|Emulazione -End Address:|Indirizzo Finale: -Enable|Abilita -Enabled|Abilitato -English|Inglese -&File|&File -File|File -File :|File: -File Name :|Nome file: -File transfer|Trasferimento file -WARNING: Master Codes are NOT supported.|ATTENZIONE: I Codici Master NON sono supportati. -Format|Formato -FPS|FPS -Frame Skip/Limiter|Limitatore frame -French|Francese -From|Da -From File|Dal file -From File...|Dal file... -&Fullscreen|&Schermo Intero -Fullscreen|Schermo Intero -General|Generale -German|Tedesco -Hard Reset|Hard Reset -Height|Altezza -_Help|_Aiuto -&Help|&Aiuto -http://www.emu-compatibility.com/yabause/index.php?lang=uk|http://www.emu-compatibility.com/yabause/index.php?lang=it -http://www.monkeystudio.org|http://www.monkeystudio.org -Input|Input -Invalid Address|Indirizzo non valido -Invalid Value|Valore non valido -Italian|Italiano -Japanese|Giapponese -Language :|Lingua: -&Layer|&Layer -Layer|Layer -Left|Sinistra -Left trigger|Left trigger -Load as executable|Carica come eseguibile -Load|Carica -&Load From File|Carica da&l file -Load State|Carica stato -Load State As|Carica stato come -Log|Log -Long Write|Scrivi Log -M68K|M68K -Memory dump|Dump Memoria -Memory Dump|Dump Memoria -Memory Editor|Editor Memoria -&Memory Transfer|Trasferimento &Memoria -Memory Transfer|Trasferimento Memoria -Memory|Memoria -Mpeg ROM|Mpeg ROM -Mouse|Mouse -MSH2|MSH2 -NBG0|NBG0 -NBG1|NBG1 -NBG2|NBG2 -NBG3|NBG3 -None|Nessuno -Ok|Ok -&OK|&OK -Open CD Rom|Apri CD Rom -Open CD Rom...|Apri CD Rom... -Open ISO|Apri ISO -Open ISO...|Apri ISO... -Pad|Pad -&Pause|&Pausa -Pause|Pausa -&Quit|&Esci -Quit|Esci -&Raw Memory Address|Indirizzo Grezzo Memoria -RBG0|RBG0 -Region|Regione -&Reset|&Reset -Reset|Reset -Resolution|Risoluzione -Right|Destra -Right trigger|Right trigger -R&un|Eseg&ui -Run|Esegui -Save Information|Salva Informazioni -Save List|Salva lista -Save|Salva -Save State|Salva stato -Save State As|Salva stato come -Save States|Salva stati -&Save To File|$Salva su file -Screenshot|Screenshot -SCSP|SCSP -SCU-DSP|SCU-DSP -Select a file to load your state|Selezionare un file per caricare il tuo stato -Select your iso/cue/bin file|Selezionare un file iso/cue/bin -&Settings...|Impo&stazioni... -Settings|Impostazioni -SH2 Interpreter|Interprete SH2 -Sound Core|Sistema Audio -Sound|Suono -Spanish|Spagnolo -SSH2|SSH2 -Start|Inizia -Start Address:|Indirizzo Iniziale: -Status|Stato -Store|Store -To File|Nel file -To File...|Nel file... -toolBar|Barra degli Strumenti -Tools|Strumenti -To|A -Transfer|Trasferimento -Translation|Traduzione -Unable to add code|Impossibile aggiungere il codice -Unable to change description|Impossibile cambiare la descrizione -Unable to open file for loading|Impossibile aprire il file per il caricamento -Unable to open file for saving|Impossibile aprire il file per il salvataggio -Unable to remove code|Impossibile rimuovere il codice -Unknow (%1)|Sconosciuto (%1) -Up|Su -Upload|Upload -Value :|Valore: -Vdp1|Vdp1 -VDP1|VDP1 -Vdp2|Vdp2 -VDP2|VDP2 -Video Core|Sistema Video -Video Driver|Driver Video -Video Format|Formato Video -Video|Video -_View|_Visualizza -&View|&Visualizza -Waiting Input...|In attesa di input... -Width|Larghezza -Word Write|Word Write -Yabause Cheat Files (*.yct);;All Files (*)|Yabause File Cheat (*.yct);;Tutti i file (*) -Yabause Qt Gui
    Based on Yabause 0.9.5
    http://yabause.org
    The Yabause Team
    Filipe AZEVEDO|Interfaccia Qt Yabause
    Basata su Yabause 0.9.5
    http://yabause.org">http://yabause.org
    Il Team Yabause
    mailto:pasnox@gmail.com">Filipe AZEVEDO -Yabause Qt GUI|Interfaccia Qt Yabause -Yabause Save State (*.yss)|Yabause Salvataggio Stato (*.yss) diff --git a/yabause/l10n/yabause_lt.yts b/yabause/l10n/yabause_lt.yts deleted file mode 100644 index 4679856916..0000000000 --- a/yabause/l10n/yabause_lt.yts +++ /dev/null @@ -1,195 +0,0 @@ -%1/%2 blocks free|%1/%2 blokų laisvų -%1 Images (*.%2)|%1 Images (*.%2) -503/512 blocks free|503/512 blokų laisvų -510/512 blocks free|510/512 blokų laisvų -About...|Apie... -&About...|&Apie... -About|Apie -&Action Replay|&Veiksmo pakartojimas -Action Replay Code :|Veiksmo pakartojimo kodas: -Add Action Replay Code|Pridėti veiksmo pakartojimo kodą: -Add Codes...|Pridėti kodų... -Add Raw Memory Code|Pridėti "Raw" atminties kodą -Address :|Adresas : -Advanced|Papildoma -|http://www.monkeystudio.org"> -Are you sure you want to delete '%1' ?|Ar tu įsitikinęs,kad nori ištrinti '%1' ? -Are you sure you want to format '%1' ?|Ar tu įsitikinęs,kad nori suformatuoti '%1' ? -Backup Manager|Atsarginių failų tvarkyklė -Backup Manager...|Atsarginių failų tvarkyklė... -&Backup Ram Manager|&Atsarginės darbinės atminties tvarkyklė -Backup Ram Manager|Atsarginės darbinės atminties tvarkyklė -Bios|Bios'as -Block Size :|Bloko dydis: -&Browse|&Naršyti -Browse|Browse -Byte Write|Byte Write -Cancel|Atšaukti -Cannot initialize|Negalima pradėti -&Capture Screen|&Nufotografuoti ekraną -Cart/Memory|Darbinė atmintis -Cartridge|Disketė -CD Images (*.iso *.cue *.bin)|CD atvaizdai (*.iso *.cue *.bin) -Cd-Rom|CD-ROM -&Cheats|&Kodai -Cheats|Kodai -Cheats File|Kodų failas -&Cheat List|&Kodų sąrašas -Cheats List|Kodų sąrašas -Cheats List...|Kodų sąrašas... -Cheat Type|Kodų tipas -Choose a cdrom drive/mount point|Pasirink CD-ROM prijungimo tašką -Choose a cheat file to open|Pasirink kodų failą -Choose a cheat file to save to|Pasirink kodų failą išsaugojimui į -Choose a file to save your state|Pasirink failą išsaugoti žaidimui -Choose a location for your screenshot|Pasirink vietą žaidimo ekranvaizdžiui -&Clear|&Išvalyti -Close|Uždaryti -Code|Kodas -Comment :|Komentaras: -Data Size :|Duomenų dydis: -_Debug|_Taisyti klaidas -&Debug|&Klaidų taisymas -&Delete|&Trinti -Delete|Trinti -Description|Aprašymas -Description :|Aprašymas : -Device List|Įrenginių sąrašas -Disabled|Neįgalinta -Down|Žemyn -Download|Atsisiųsti -Emu-Compatibility|Emuliatoriaus suderinamumas -Emulation|Emuliacija -End Address:|End Adress: -Enable|Įgalinti -Enabled|Įgalinta -English|Anglų -&File|&Failas -File|Failas -File :|Failas -File Name :|Failo pavadinimas: -File transfer|Failo perkėlimas -WARNING: Master Codes are NOT supported.|WARNING: Master Codes are NOT supported. -Format|Formatuoti -FPS|KPS -Frame Skip/Limiter|Kadrų praleidimas -French|Prancūzų -From|Iš -From File|Iš failo -From File...|Iš failo... -&Fullscreen|&Pilnas ekranas -Fullscreen|Pilnas ekranas -General|Pagrindiniai -German|Vokiečių -Hard Reset|"Gilus" perkrovimas -Height|Aukštis -_Help|_Pagalba -&Help|&Pagalba -http://www.emu-compatibility.com/yabause/index.php?lang=uk|http://www.emu-compatibility.com/yabause/index.php?lang=uk -http://www.monkeystudio.org|http://www.monkeystudio.org -Input|Įvedimas -Invalid Address|Neteisingas adresas -Invalid Value|Neteisinga vertė -Italian|Italų -Japanese|Japonų -Language :|Kalba : -&Layer|&Sluoksniai -Layer|Sluoksniai -Left|Kairė -Left trigger|Kairysis mygtukas -Load as executable|Įkrauti kaip paleidžiamąjį failą -Load|Įkrauti -&Load From File|&Įkelti iš failo -Load State|Įkelti išsaugotą žaidimą -Load State As|Išsaugoti žaidimą kaip -Log|Log'as -Long Write|Long Write -M68K|M68K -Memory dump|Atminties "išmetimas" -Memory Dump|Atminties "išmetimas" -Memory Editor|Atminties tvarkymas -&Memory Transfer|&Atminties pervedimas -Memory Transfer|Atminties pervedimas -Memory|Atmintis -Mpeg ROM|Mpeg ROM'as -MSH2|MSH2 -NBG0|NBG0 -NBG1|NBG1 -NBG2|NBG2 -NBG3|NBG3 -Ok|Gerai -&OK|&Gerai -Open CD Rom|Atverti CD-ROM'ą -Open CD Rom...|Atverti CD-ROM'ą... -Open ISO|Atverti ISO -Open ISO...|Atverti ISO... -&Pause|&Pauzė -Pause|Pauzė -&Quit|&Išeiti -Quit|Išeiti -&Raw Memory Address|&Priėjimas prie Raw atminties -RBG0|RBG0 -Region|Regionas -&Reset|&Perkrauti -Reset|Perkrauti -Resolution|Raiška -Right|Dešinė -Right trigger|Dešinysis mygtukas -R&un|&Leisti -Run|Leisti -Save Information|Išsaugoti informaciją -Save List|Išsaugojimų sąrašas -Save|Išsaugoti -Save State|Išsaugoti žaidimą -Save State As|Išsaugoti žaidimą kaip -Save States|Žaidimų išsaugojimo failai -&Save To File|&Išsaugoti į failą -Screenshot|Ekrano nuotrauka -SCSP|SCSP -SCU-DSP|SCU-DSP -Select a file to load your state|Pasirink žaidimo išsaugojimo failą įkėlimui -Select your iso/cue/bin file|Pasirink iso/cue/bin failą -&Settings...|&Nuostatos -Settings|Nuostatos -SH2 Interpreter|SH2 Interpretatorius -Sound Core|Garso įranga -Sound|Garsas -Spanish|Ispanų -SSH2|SSH2 -Start|Pradėti -Start Address:|Pradžios adresas: -Status|Statusas -Store|Saugoti -To File|Į failą -To File...|Į failą... -toolBar|Įrankų juosta -Tools|Įrankiai -To|Į -Transfer|Pervedimas -Translation|Vertimas -Unable to add code|Neįmanoma pridėti kodo -Unable to change description|Neįmanoma keisti aprašymo -Unable to open file for loading|Neįmanoma atverti failo įkrovimui -Unable to open file for saving|Neįmanoma atverti failo saugojimui -Unable to remove code|Neįmanoma pašalinti kodo -Unknow (%1)|Nežinoma (%1) -Up|Aukštyn -Upload|Įkrauti -Value :|Vertė: -Vdp1|Vdp1 -VDP1|VDP1 -Vdp2|Vdp2 -VDP2|VDP2 -Video Core|Video įranga -Video Driver|Video tvarkyklė -Video Format|Video formatas -Video|Video -_View|_Žiūrėti -&View|&Žiūrėti -Waiting Input...|Laukiama įvedimo -Width|Plotis -Word Write|Žodžių rašymas -Yabause Cheat Files (*.yct);;All Files (*)|Yabause kodų failai (*.yct);;Visi failai (*) -Yabause Qt Gui
    Based on Yabause 0.9.5
    http://yabause.org
    The Yabause Team
    Filipe AZEVEDO|Yabause Qt Gui
    Paremtas pagal Yabause 0.9.5
    http://yabause.org">http://yabause.org
    Yabause komanda
    mailto:pasnox@gmail.com">Filipe AZEVEDO -Yabause Qt GUI|Yabause Qt grafinė sąsaja -Yabause Save State (*.yss)|Yabause žaidimo išsaugojimo failas (*.yss) diff --git a/yabause/l10n/yabause_pt.yts b/yabause/l10n/yabause_pt.yts deleted file mode 100644 index 634124c088..0000000000 --- a/yabause/l10n/yabause_pt.yts +++ /dev/null @@ -1,195 +0,0 @@ -%1/%2 blocks free|%1/%2 blocos livres -%1 Images (*.%2)|%1 Images (*.%2) -503/512 blocks free|503/512 blocos livres -510/512 blocks free|510/512 blocos livres -About...|Sobre... -&About...|&Sobre... -About|Sobre -&Action Replay|&Action Replay -Action Replay Code :|Código do Action Replay -Add Action Replay Code|Adicionar Código do Action Replay -Add Codes...|Adicionar Códigos... -Add Raw Memory Code|Adicionar o Endereço Original da Memória -Address :|Endereço : -Advanced|Avançado -| -Are you sure you want to delete '%1' ?|Você tem certeza de que deseja excluir '%1' ? -Are you sure you want to format '%1' ?|Você tem certeza de que deseja formatar '%1' ? -Backup Manager|Gerenciador de Backups -Backup Manager...|Gerenciador de Backups... -&Backup Ram Manager|&Gerenciador da Ram de Backup -Backup Ram Manager|Gerenciador da Ram de Backup -Bios|Bios -Block Size :|Tamanho dos Blocos : -&Browse|&Procurar -Browse|Procurar -Byte Write|Gravar Byte -Cancel|Cancelar -Cannot initialize|Não pode inicializar -&Capture Screen|&Capturar Tela -Cart/Memory|Cartucho/Memória -Cartridge|Cartucho -CD Images (*.iso *.cue *.bin)|Imagens de CD (*.iso *.cue *.bin) -Cd-Rom|CD-Rom -&Cheats|&Trapaças -Cheats|Trapaças -Cheats File|Arquivo de Trapaças -&Cheat List|Lista de &Trapaças -Cheats List|Lista de Trapaças -Cheats List...|Lista de Trapaças -Cheat Type|Tipo de Trapaça -Choose a cdrom drive/mount point|Escolha um leitor de CD ou um ponto de montagem -Choose a cheat file to open|Escolha um arquivo de trapaças para abrir -Choose a cheat file to save to|Escolha um arquivo de trapaças para salvar -Choose a file to save your state|Escolha um arquivo para salvar seu estado -Choose a location for your screenshot|Escolha um local para sua captura de tela -&Clear|&Limpar -Close|Fechar -Code|Código -Comment :|Comentário : -Data Size :|Tamanho dos Dados : -_Debug|_Debug -&Debug|&Debug -&Delete|&Excluir -Delete|Excluir -Description|Descrição -Description :|Descrição : -Device List|Lista de Dispositivos -Disabled|Desativado -Down|Para baixo -Download|Baixar -Emu-Compatibility|Compatibilidade com o Emu -Emulation|Emulação -End Address:|Endereço Final: -Enable|Ativar -Enabled|Ativado -English|Inglês -&File|&Arquivo -File|Arquivo -File :|Arquivo : -File Name :|Nome do Arquivo : -File transfer|Transferência de arquivo -WARNING: Master Codes are NOT supported.|AVISO: Códigos Mestres NÃO são suportados. -Format|Formato -FPS|QPS -Frame Skip/Limiter|Pulo de quadros/Limitador -French|Francês -From|De -From File|Do Arquivo -From File...|Do Arquivo... -&Fullscreen|Tela cheia -Fullscreen|Tela cheia -General|Geral -German|Alemão -Hard Reset|Reiniciar Hardware -Height|Altura -_Help|_Ajuda -&Help|&Ajuda -http://www.emu-compatibility.com/yabause/index.php?lang=uk|http://www.emu-compatibility.com/yabause/index.php?lang=uk -http://www.monkeystudio.org|http://www.monkeystudio.org -Input|Controles -Invalid Address|Endereço Inválido -Invalid Value|Valor Inválido -Italian|Italiano -Japanese|Japonês -Language :|Idioma : -&Layer|&Camada -Layer|Camada -Left|Esquerda -Left trigger|Gatilho esquerdo -Load as executable|Carregar como executável -Load|Carregar -&Load From File|&Carregar Do Arquivo -Load State|Carregar Estado -Load State As|Carregar Estado como -Log|Log -Long Write|Escrita Longa -M68K|M68K -Memory dump|Dump de memória -Memory Dump|Dump de Memória -Memory Editor|Editor de Memória -&Memory Transfer|&Transferência de Memória -Memory Transfer|Transferência de Memória -Memory|Memória -Mpeg ROM|ROM Mpeg -MSH2|MSH2 -NBG0|NBG0 -NBG1|NBG1 -NBG2|NBG2 -NBG3|NBG3 -Ok|Ok -&OK|&OK -Open CD Rom|Abrir CD Rom -Open CD Rom...|Abrir CD Rom... -Open ISO|Abrir ISO -Open ISO...|Abrir ISO... -&Pause|&Pausar -Pause|Pausar -&Quit|&Sair -Quit|Sair -&Raw Memory Address|&Endereço Original da Memória -RBG0|RBG0 -Region|Região -&Reset|&Reiniciar -Reset|Reiniciar -Resolution|Resolução -Right|Direita -Right trigger|Gatilho direito -R&un|Exec&utar -Run|Executar -Save Information|Informações sobre os Saves -Save List|Lista dos Saves -Save|Salvar -Save State|Salvar Estado -Save State As|Salvar Estado Como -Save States|Salvar Estado -&Save To File|&Salvar Para Arquivo -Screenshot|Captura de tela -SCSP|SCSP -SCU-DSP|SCU-DSP -Select a file to load your state|Escolha um arquivo para carregar seu estado -Select your iso/cue/bin file|Escolha seu arquivo iso/cue/bin -&Settings...|Configuraçõe&s... -Settings|Configurações -SH2 Interpreter|Interpretador SH2 -Sound Core|Núcleo de Som -Sound|Som -Spanish|Espanhol -SSH2|SSH2 -Start|Iniciar -Start Address:|Endereço Inicial: -Status|Estado -Store|Armazenar -To File|Para Arquivo -To File...|Para arquivo... -toolBar|Barra de ferramentas -Tools|Ferramentas -To|Para -Transfer|Transferência -Translation|Tradução -Unable to add code|Não foi possível adicionar código -Unable to change description|Não foi possível modificar a descrição -Unable to open file for loading|Não foi possível carregar o arquivo -Unable to open file for saving|Não foi possível salvar o arquivo -Unable to remove code|Não foi possível remover o código -Unknow (%1)|Desconh (%1) -Up|Para cima -Upload|Subir -Value :|Valor : -Vdp1|Vdp1 -VDP1|VDP1 -Vdp2|Vdp2 -VDP2|VDP2 -Video Core|Núcleo de Vídeo -Video Driver|Driver de Vídeo -Video Format|Formato do Vídeo -Video|Vídeo -_View|_Visualizar -&View|&Visualizar -Waiting Input...|Aguardando Entrada de Dados... -Width|Largura -Word Write|Escrita Word -Yabause Cheat Files (*.yct);;All Files (*)|Arquivos de trapaça Yabause (*.yct);;Todos os arquivos (*) -Yabause Qt Gui
    Based on Yabause 0.9.5
    http://yabause.org
    The Yabause Team
    Filipe AZEVEDO|Gui Qt do Yabause
    Baseada no Yabause 0.9.5
    http://yabause.org
    O Time do Yabause
    Filipe AZEVEDO -Yabause Qt GUI|Interface Gráfica do Usuário em Qt do Yabause -Yabause Save State (*.yss)|Estado Salvo do Yabause diff --git a/yabause/l10n/yabause_pt_BR.yts b/yabause/l10n/yabause_pt_BR.yts deleted file mode 100644 index 2843809790..0000000000 --- a/yabause/l10n/yabause_pt_BR.yts +++ /dev/null @@ -1,274 +0,0 @@ -%1/%2 blocks free|%1/%2 blocos livres -%1 Images (*.%2)|%1 Imagens (*.%2) -503/512 blocks free|503/512 blocos livres -510/512 blocks free|510/512 blocos livres -About...|Sobre... -&About...|&Sobre... -About|Sobre -&Action Replay|&Action Replay -Action Replay Code :|Código do Action Replay -Add Action Replay Code|Adicionar Código do Action Replay -Add Cheat|Adicionar Trapaça -Add Codes...|Adicionar Códigos... -Add Raw Memory Code|Adicionar o Código da Memória Original -Address|Endereço -Address :|Endereço : -Advanced|Avançado -Always|Sempre -Asia (NTSC)|Ásia (NTSC) -Asia (PAL)|Ásia (PAL) -Are you sure you want to delete '%1' ?|Você tem certeza que você quer apagar '%1' ? -Are you sure you want to format '%1' ?|Você tem certeza que você quer formatar '%1' ? -Auto-detect|Auto-detectar -Autostart|Auto-iniciar -Backup Manager|Gerenciador de Backups -&Backup Manager...|&Gerenciador de Backups... -Backup Manager...|Gerenciador de Backups... -&Backup Ram Manager|&Gerenciador da Ram de Backup -Backup Ram Manager|Gerenciador da Ram de Backup -Bios|Bios -Block Size :|Tamanho dos Blocos : -&Browse|&Explorar -Browse|Explorar -Byte Write|Gravação do Byte -&Cancel|&Cancelar -Cancel|Cancelar -Cannot initialize|Não consegue inicializar -&Capture Screen|&Capturar Tela -Cart/Memory|Cartucho/Memória -Cartridge|Cartucho -CD Images (*.iso *.cue *.bin)|Imagens de CD (*.iso *.cue *.bin) -Cd-Rom|Cd-Rom -Central/South America (NTSC)|América Central/do Sul (NTSC) -Central/South America (PAL)|América Central/do Sul (PAL) -&Cheats|&Códigos -Cheats|Trapaças -Cheats File|Arquivo das Trapaças -&Cheat List|Lista de &Trapaças -Cheats List|Lista de Trapaças -&Cheats List...|&Lista de Trapaças... -Cheats List...|Lista de Trapaças... -Cheat &Search...|Busca de &Trapaças... -Cheat Search|Busca de Trapaças -Cheat Type|Tipo de Trapaça -Choose a cdrom drive/mount point|Escolha um drive de cdrom/ponto de montagem -Choose a cheat file to open|Escolha um arquivo de códigos para abrir -Choose a cheat file to save to|Escolha um arquivo de códigos para salvar -Choose a file to save your state|Escolha um arquivo para salvar seu estado -Choose a location for your screenshot|Escolha um local para seu screenshot -&Clear|&Limpar -Clear configuration|Limpar configuração -&Close|&Fechar -Close|Fechar -Code|Código -Comment :|Comentário : -Compare Type|Tipo de Comparação -Data Size|Tamanho dos Dados -Data Size :|Tamanho dos Dados : -Data Type|Tipo de Dados -_Debug|_Debug -&Debug|&Debug -&Delete|&Apagar -Delete|Apagar -Description|Descrição -Description :|Descrição : -Device List|Lista de Dispositivos -Disabled|Desativado -Down|Pra baixo -Download|Baixar -Dummy CD Drive|Imitação do Drive de CD -Dummy Input Interface|Imitação da Interface de Entrada de Dados -Dummy OSD Interface|Imitação da Interface OSD -Dummy Sound Interface|Imitação da Interface de Som -Dummy Video Interface|Imitação da Interface de Vídeo -Edit configuration|Editar configuração -Emu-Compatibility|Compatibilidade com o Emu -&Emulation|&Emulação -Emulation|Emulação -End Address:|Endereço Final: -Enable|Ativar -Enable Frame Skip/Limiter|Ativar o Frame Skip/Limitador -Enabled|Ativado -English|Inglês -Europe + others (PAL)|Europa + outros (PAL) -Exact|Exato -&File|&Arquivo -File|Arquivo -File :|Arquivo : -File:|Arquivo: -File Name :|Nome do Arquivo : -File transfer|Transferência de arquivo -WARNING: Master Codes are NOT supported.|AVISO: Códigos Mestres NÃO são suportados. -Format|Formato -FPS|FPS -Frame Skip/Limiter|Frame Skip/Limitador -&Frame Skip/Limiter|&Frame Skip/Limitador -French|Francês -From|De -From File|Do Arquivo -From File...|Do Arquivo... -&Fullscreen|&Tela cheia -Fullscreen|Tela cheia -General|Geral -German|Alemão -Glut OSD Interface|Interface OSD do Glut -Greater then|Maior do que -Hard Reset|Reset Rígido -Height|Altura -_Help|_Ajuda -&Help|&Ajuda -Hide menubar|Esconder a barra do menu -Hide toolbar|Esconder a barra de ferramentas -http://www.emu-compatibility.com/yabause/index.php?lang=uk|http://www.emu-compatibility.com/yabause/index.php?lang=uk -http://www.monkeystudio.org|http://www.monkeystudio.org -Information...|Informação... -Input|Controles -Invalid Address|Endereço Inválido -Invalid Value|Valor Inválido -ISO-File Virtual Drive|Drive Virtual do Arquivo-ISO -Italian|Italiano -Japan (NTSC)|Japão (NTSC) -Japanese|Japonês -Korea (NTSC)|Coréia (NTSC) -Language :|Idioma : -&Layer|&Camada -Layer|Camada -Left|Esquerda -Left trigger|Gatilho esquerdo -Less than|Menos do que -Linux CD Drive|Drive de CD do Linux -Load as executable|Carregar como executável -Load|Carregar -&Load From File|&Carregar Do Arquivo -L&oad State|C&arregar o State -Load State|Carregar State -Load State As|Carregar State Como -&Log|&Log -Log|Log -Long Write|Gravação Longa -M68K|M68K -&Master SH2|&SH2 Mestre -Master SH2|SH2 Mestre -Memory dump|Dump da memória -Memory Dump|Dump da Memória -Memory &Editor|Editor de &Memória -Memory Editor|Editor de Memória -&Memory Transfer|&Transferência de Memória -Memory Transfer|Transferência de Memória -Memory|Memória -Mpeg ROM|ROM Mpeg -Mouse|Mouse -MSH2|MSH2 -NBG0|NBG0 -NBG1|NBG1 -NBG2|NBG2 -NBG3|NBG3 -Never|Nunca -None|Nenhum -North America (NTSC)|América do Norte (NTSC) -Ok|Ok -&OK|&OK -On fullscreen|Na tela cheia -Open CD Rom|Abrir o CD Rom -Open &CD Rom...|Abrir &CD Rom... -Open CD Rom...|Abrir o CD Rom... -Open ISO|Abrir a ISO -Open &ISO...|Abrir &ISO... -Open ISO...|Abrir a ISO... -OpenGL Video Interface|Interface de Vídeo do OpenGL -OSD Core|Núcleo do OSD -Pad|Pad -&Pause|&Pausar -Pause|Pausar -Qt Keyboard Input Interface|Interface da Entrada de Dados do Teclado do Qt -&Quit|&Sair -Quit|Sair -&Raw Memory Address|&Endereço da Memória Original -RBG0|RBG0 -Region|Região -&Reset|&Resetar -Reset|Resetar -Resolution|Resolução -Right|Direita -Right trigger|Gatilho direito -R&un|E&xecutar -Run|Executar -Save Information|Informações sobre os Saves -Save List|Lista dos Saves -Save|Salvar -S&ave State|S&ave State -Save State|Salvar o State -Save State As|Salvar o State Como -Save States|Salvar os States -&Save To File|&Salvar para o Arquivo -Sc&reenshot|Sc&reenshot -Screenshot|Screenshot -SCSP|SCSP -SCU-DSP|SCU-DSP -SDL Joystick Interface|Interface SDL do Joystick -SDL Sound Interface|Interface de Som SDL -Search|Busca -Search/Add Cheats|Procurar/Adicionar Trapaças -Search Value:|Procurar Valor: -Select a file to load your state|Selecione um arquivo para carregar seu state -Select your iso/cue/bin file|Selecione seu arquivo iso/cue/bin -Set PC to Start Address|Configurar o PC pra Iniciar no Endereço -&Settings...|&Configurações... -Settings|Configurações -SH2 Debugger Interpreter|Interpretador do Debugger SH2 -SH2 Dynamic Recompiler|Recompilador Dinâmico do SH2 -SH2 Interpreter|Interpretador SH2 -Show FPS|Mostrar FPS -&Slave SH2|&SH2 Escravo -Slave SH2|SH2 Escravo -Software Video Interface|Interface de Vídeo do Software -Sound Core|Núcleo do Som -Sound|Som -Spanish|Espanhol -SSH2|SSH2 -Signed|Assinado -Software OSD Interface|Interface OSD do Software -Start|Iniciar -Start Address:|Endereço Inicial: -Status|Status -Store|Armazenar -To File|Para o Arquivo -To File...|Para o Arquivo... -toolBar|Barra de ferramentas -&Tools|&Ferramentas -Tools|Ferramentas -To|Para -&Transfer|&Transferência -Transfer|Transferência -Translation|Tradução -Unable to add code|Incapaz de adicionar o código -Unable to change description|Incapaz de mudar a descrição -Unable to open file for loading|Incapaz de abrir o arquivo para carregar -Unable to open file for saving|Incapaz de abrir o arquivo para salvar -Unable to remove code|Incapaz de remover o código -Unknow (%1)|(%1) Desconhecido -Unsigned|Não Assinado -Up|Para cima -Upload|Upload -Value|Valor -Value :|Valor : -Vdp1|Vdp1 -VDP1|VDP1 -Vdp2|Vdp2 -VDP2|VDP2 -Video Core|Núcleo do Vídeo -Video Driver|Driver do Vídeo -Video Format|Formato do Vídeo -Video|Vídeo -_View|_Visualizar -&View|&Visualizar -View|Visualizar -Waiting Input...|Esperando a Entrada dos Dados... -Width|Largura -Windows SPTI Driver|Drive SPTI do Windows -Word Write|Gravação das Palavras -Yabause Cheat Files (*.yct);;All Files (*)|Arquivos das Trapaças do Yabause (*.yct);;Todos os Arquivos (*) -Yabause is not initialized, can't manage backup ram.|O Yabause não está inicializado, não pode gerenciar a ram do backup. -Yabause Qt Gui
    Based on Yabause %1
    http://yabause.org
    The Yabause Team
    Filipe AZEVEDO|Gui Qt do Yabause
    Baseada no Yabause %1
    http://yabause.org
    O Time Yabause
    Filipe AZEVEDO -Yabause Qt GUI|GUI Qt do Yabause -Yabause Save State (*.yss)|Save State do Yabause (*.yss) diff --git a/yabause/l10n/yabause_sv.yts b/yabause/l10n/yabause_sv.yts deleted file mode 100644 index f2afe08443..0000000000 --- a/yabause/l10n/yabause_sv.yts +++ /dev/null @@ -1,195 +0,0 @@ -%1/%2 blocks free|%1/%2 block fria -%1 Images (*.%2)|%1 Avbilder (*.%2) -503/512 blocks free|503/512 block fria -510/512 blocks free|510/512 block fria -About...|Om... -&About...|&Om... -About|Om -&Action Replay|&Action Replay -Action Replay Code :|Action Replay-kod -Add Action Replay Code|Lägg till en Action Replay-kod -Add Codes...|Lägg till kod... -Add Raw Memory Code|Lägg till råminneskod -Address :|Adress : -Advanced|Avancerat -| -Are you sure you want to delete '%1' ?|Är du säker på att du vill ta bort '%1' ? -Are you sure you want to format '%1' ?|Är du säker på att du vill formatera '%1' ? -Backup Manager|Backuphanterare -Backup Manager...|Backuphanterare... -&Backup Ram Manager|&Backup Ram Manager -Backup Ram Manager|Backup Ram Manager -Bios|Bios -Block Size :|Blockstorlek -&Browse|&Bläddra -Browse|Bläddra -Byte Write|Byteskrivning -Cancel|Avbryt -Cannot initialize|Kan inte initialisera -&Capture Screen|&Skärmdump -Cart/Memory|Kassett/Minne -Cartridge|Kassett -CD Images (*.iso *.cue *.bin)|CD-avbild (*.iso *.cue *.bin) -Cd-Rom|CD-ROM -&Cheats|&Fusk -Cheats|Fusk -Cheats File|Fuskfil -&Cheat List|&Lista över fusk -Cheats List|Lista över fusk -Cheats List...|Lista över fusk... -Cheat Type|Typ av fusk -Choose a cdrom drive/mount point|Välj en CD-läsare eller en monteringspunkt -Choose a cheat file to open|Välj fuskfil att öppna -Choose a cheat file to save to|Välj fuskfil att spara till -Choose a file to save your state|Välj en fil att spara ditt läge till -Choose a location for your screenshot|Välj plats att spara skärmdump till -&Clear|&Rensa -Close|Stäng -Code|Kod -Comment :|Kommentar : -Data Size :|Datastorlek : -_Debug|_Debug -&Debug|%Debug -&Delete|&Ta bort -Delete|Ta bort -Description|Beskrivning -Description :|Beskrivning : -Device List|Lista över enheter -Disabled|Inaktiverad -Down|Ner -Download|Nerladdning -Emu-Compatibility|Emu-kompatibilitet -Emulation|Emulering -End Address:|Slutadress -Enable|Aktivera -Enabled|Aktiverad -English|Engelska -&File|&Fil -File|Fil -File :|File : -File Name :|Filnamn : -File transfer|Filöverföring -WARNING: Master Codes are NOT supported.|VARNING: Master Codes stöds INTE -Format|Formatera -FPS|FPS -Frame Skip/Limiter|Frame Skip/Limiter -French|Franska -From|Från -From File|Från fil -From File...|Från fil... -&Fullscreen|&Helskärm -Fullscreen|Helskärm -General|Allmänt -German|Tyska -Hard Reset|Hård reset -Height|Höjd -_Help|_Hjälp -&Help|&Hjälp -http://www.emu-compatibility.com/yabause/index.php?lang=uk|http://www.emu-compatibility.com/yabause/index.php?lang=uk -http://www.monkeystudio.org|http://www.monkeystudio.org -Input|Kontroller -Invalid Address|Ogiltig adress -Invalid Value|Ogiltigt värde -Italian|Italienska -Japanese|Japanska -Language :|Språk : -&Layer|&Lager -Layer|Lager -Left|Vänster -Left trigger|Vänster avtryckare -Load as executable|Ladda som exekverbar -Load|Ladda -&Load From File|Ladda från fil -Load State|Ladda läge -Load State As|Ladda läge som -Log|Logg -Long Write|Lång skrivning -M68K|M68K -Memory dump|Minnesdump -Memory Dump|Minnesdump -Memory Editor|Minnesredigerare -&Memory Transfer|&Minnesöverföring -Memory Transfer|Minnesöverföring -Memory|Minne -Mpeg ROM|MPEG ROM -MSH2|MSH2 -NBG0|NBG0 -NBG1|NBG1 -NBG2|NBG2 -NBG3|NBG3 -Ok|OK -&OK|&OK -Open CD Rom|Öppna CD-ROM -Open CD Rom...|Öppna CD-ROM... -Open ISO|Öppna ISO -Open ISO...|Öppna ISO... -&Pause|&Paus -Pause|Paus -&Quit|&Avsluta -Quit|Avsluta -&Raw Memory Address|&Rå minnesadress -RBG0|RBG0 -Region|Region -&Reset|&Reset -Reset|Reset -Resolution|Upplösning -Right|Höger -Right trigger|Höger avtryckare -R&un|&Kör -Run|Kör -Save Information|Spara information -Save List|Spara lista -Save|Spara -Save State|Spara läge -Save State As|Spara läge som -Save States|Spara lägen -&Save To File|&Spara till fil -Screenshot|Skärmdump -SCSP|SCSP -SCU-DSP|SCU-DSP -Select a file to load your state|Välj fil för att ladda ditt läge -Select your iso/cue/bin file|Välj din iso/cue/bin-fil -&Settings...|&Inställningar... -Settings|Inställningar -SH2 Interpreter|SH2-tolkare -Sound Core|Ljudgränssnitt -Sound|Ljud -Spanish|Spanska -SSH2|SSH2 -Start|Start -Start Address:|Startadress -Status|Status -Store|Lagra -To File|Till fil -To File...|Till fil... -toolBar|Verktygsfält -Tools|Verktyg -To|Till -Transfer|Överföring -Translation|Översättning -Unable to add code|Kan inte lägga till kod -Unable to change description|Kan inte ändra beskrivning -Unable to open file for loading|Kan inte öppna fil för att ladda -Unable to open file for saving|Kan inte öppna fil för att spara -Unable to remove code|Kan inte ta bort kod -Unknow (%1)|Okänt (%1) -Up|Upp -Upload|Uppladdning -Value :|Värde : -Vdp1|Vdp1 -VDP1|VDP1 -Vdp2|Vdp2 -VDP2|VDP2 -Video Core|Videogränssnitt -Video Driver|Videodrivrutin -Video Format|Videoformat -Video|Video -_View|_Visa -&View|&Visa -Waiting Input...|Väntar på input... -Width|Bredd -Word Write|Ordskrivning -Yabause Cheat Files (*.yct);;All Files (*)|Yabause fuskfil (*.yct);;Alla filer (*) -Yabause Qt Gui
    Based on Yabause 0.9.5
    http://yabause.org
    The Yabause Team
    Filipe AZEVEDO|Yabause Qt GUI
    Baserat på Yabause 0.9.5
    http://yabause.org
    Yabause-teamet
    Filipe AZEVEDO -Yabause Qt GUI|Yabause Qt GUI -Yabause Save State (*.yss)|Yabause Sparat Läge (*.yss) diff --git a/yabause/src/CMakeLists.txt b/yabause/src/CMakeLists.txt deleted file mode 100644 index a825f2f0a2..0000000000 --- a/yabause/src/CMakeLists.txt +++ /dev/null @@ -1,492 +0,0 @@ -project(yabause) - -include(CheckFunctionExists) -include(CheckIncludeFile) - -set(yabause_SOURCES - bios.c - cdbase.c cheat.c coffelf.c cs0.c cs1.c cs2.c - debug.c - error.c - m68kcore.c m68kd.c memory.c movie.c - netlink.c - osdcore.c - peripheral.c profile.c - scu.c sh2core.c sh2d.c sh2idle.c sh2int.c sh2trace.c smpc.c snddummy.c - titan/titan.c - vdp1.c vdp2.c vdp2debug.c vidogl.c vidshared.c vidsoft.c - yabause.c ygl.c yglshader.c) - -# new SCSP -option(YAB_USE_SCSP2 "Use the new SCSP implementation.") -if (YAB_USE_SCSP2) - add_definitions(-DUSE_SCSP2=1) - set(yabause_SOURCES ${yabause_SOURCES} scsp2.c) -else() - set(yabause_SOURCES ${yabause_SOURCES} scsp.c) -endif() - -# disable strdup warning in MSVC -if (MSVC) - add_definitions(/wd4996) -endif () - -# math library -if (UNIX) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} "m") -endif() - -# Bigendian -include(TestBigEndian) -test_big_endian(WORDS_BIGENDIAN) -if (WORDS_BIGENDIAN) - add_definitions(-DWORDS_BIGENDIAN=1) -endif (WORDS_BIGENDIAN) - -include(CheckCSourceCompiles) - -# variadic macros -check_c_source_compiles("#define MACRO(...) puts(__VA_ARGS__) - int main(int argc, char ** argv) { MACRO(\"foo\"); }" - VARIADIC_MACROS_OK) -if (VARIADIC_MACROS_OK) - add_definitions(-DHAVE_C99_VARIADIC_MACROS=1) -endif (VARIADIC_MACROS_OK) - -# gettimeofday -check_function_exists(gettimeofday GETTIMEOFDAY_OK) -if (GETTIMEOFDAY_OK) - add_definitions(-DHAVE_GETTIMEOFDAY=1) -endif () - -# floorf -set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} "-lm") -check_function_exists(floorf FLOORF_OK) -if (FLOORF_OK) - add_definitions(-DHAVE_FLOORF=1) -endif () - -# sys/time.h -check_include_file("sys/time.h" SYSTIME_OK) -if (SYSTIME_OK) - add_definitions(-DHAVE_SYS_TIME_H=1) -endif() - -# Find stdint.h -check_include_file("stdint.h" STDINT_H_FOUND) -if (STDINT_H_FOUND) - add_definitions(-DHAVE_STDINT_H=1) -endif() - -# OpenGL -option(YAB_WANT_OPENGL "use OpenGL for video output (most ports require it)" ON) -if (YAB_WANT_OPENGL) - include(FindOpenGL) - if (OPENGL_FOUND) - add_definitions(-DHAVE_LIBGL=1) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${OPENGL_LIBRARIES}) - - include(FindGLUT) - if (GLUT_FOUND) - include_directories(${GLUT_INCLUDE_DIR}) - add_definitions(-DHAVE_LIBGLUT=1) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${GLUT_LIBRARIES}) - endif() - - # glXGetProcAddress - set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${OPENGL_LIBRARIES}) - check_function_exists(glXGetProcAddress GLXGETPROCADDRESS_OK) - if (GLXGETPROCADDRESS_OK) - add_definitions(-DHAVE_GLXGETPROCADDRESS=1) - endif() - endif(OPENGL_FOUND) -endif (YAB_WANT_OPENGL) - -# SDL -option(YAB_WANT_SDL "use SDL cores if available" ON) -if (YAB_WANT_SDL) - include(FindSDL) - if (SDL_FOUND) - add_definitions(-DHAVE_LIBSDL=1) - include_directories(${SDL_INCLUDE_DIR}) - set(yabause_SOURCES ${yabause_SOURCES} persdljoy.c sndsdl.c) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${SDL_LIBRARY}) - endif (SDL_FOUND) -endif (YAB_WANT_SDL) - -# OpenAL -option(YAB_WANT_OPENAL "use OpenAL sound core if available" ON) -if (YAB_WANT_OPENAL) - include(FindOpenAL) - if (OPENAL_FOUND) - find_package(Threads) - add_definitions(-DHAVE_LIBAL=1) - include_directories(${OPENAL_INCLUDE_DIR}) - set(yabause_SOURCES ${yabause_SOURCES} sndal.c) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${OPENAL_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) - endif (OPENAL_FOUND) -endif (YAB_WANT_OPENAL) - -# mini18n -find_path(MINI18N_INCLUDE_DIR mini18n.h) -find_library(MINI18N_LIBRARY mini18n) -if (NOT MINI18N_INCLUDE_DIR STREQUAL "MINI18N_INCLUDE_DIR-NOTFOUND" AND NOT MINI18N_LIBRARY STREQUAL "MINI18N_LIBRARY-NOTFOUND") - set(MINI18N_FOUND TRUE) - include_directories(${MINI18N_INCLUDE_DIR}) - add_definitions(-DHAVE_LIBMINI18N=1) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${MINI18N_LIBRARY}) -endif (NOT MINI18N_INCLUDE_DIR STREQUAL "MINI18N_INCLUDE_DIR-NOTFOUND" AND NOT MINI18N_LIBRARY STREQUAL "MINI18N_LIBRARY-NOTFOUND") - -if (MINI18N_FOUND) - if (UNIX) - add_definitions(-DYTSDIR=\"${CMAKE_INSTALL_PREFIX}/share/${YAB_PACKAGE}/yts\") - elseif (WIN32) - add_definitions(-DYTSDIR=\"trans\") - endif() -endif() - -# APPLE // not necessary mac os x, but i don't care ;) -if (APPLE) - FIND_LIBRARY(COREFOUNDATION_LIBRARY NAMES CoreFoundation ) - FIND_LIBRARY(IOKIT_LIBRARY NAMES IOKit ) - set(yabause_SOURCES ${yabause_SOURCES} macjoy.c permacjoy.c cd-macosx.c sndmac.c) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${COREFOUNDATION_LIBRARY} ${IOKIT_LIBRARY}) - - check_function_exists(glBindRenderbuffer HAVE_FBO) - if (HAVE_FBO) - add_definitions(-DHAVE_FBO=1) - endif() -endif (APPLE) - -# Visual Studio -if (MSVC) - # Find DDK - if (EXISTS "$ENV{SYSTEMDRIVE}/WINDDK/3790.1830/") - set(DDK_DIR "$ENV{SYSTEMDRIVE}/WINDDK/3790.1830/") - elseif (EXISTS "$ENV{SYSTEMDRIVE}/WINDDK/6000/") - set(DDK_DIR "$ENV{SYSTEMDRIVE}/WINDDK/6000/") - elseif (EXISTS "$ENV{SYSTEMDRIVE}/WINDDK/7600.16385.0/") - set(DDK_DIR "$ENV{SYSTEMDRIVE}/WINDDK/7600.16385.0/") - endif (EXISTS "$ENV{SYSTEMDRIVE}/WINDDK/3790.1830/") - - add_definitions(-DHAVE_C99_VARIADIC_MACROS -D_CRT_SECURE_NO_WARNINGS -DC68K_NO_JUMP_TABLE - -D_UNICODE -DUNICODE) -endif (MSVC) - -# Windows ddk -if (WIN32) - option(YAB_WANT_DDK "Use the real DDK instead of the built-in one") - if(YAB_WANT_DDK) - # Find ntddcdrm.h - find_path(ntddcdrm_INCLUDE_DIR ntddcdrm.h - PATHS "${DDK_DIR}" "${DDK_DIR}/inc" PATH_SUFFIXES ddk api) - - if (ntddcdrm_INCLUDE_DIR) - include_directories(${ntddcdrm_INCLUDE_DIR}) - message(STATUS "Found ntddcdrm.h: ${ntddcdrm_INCLUDE_DIR}") - add_definitions(-DHAVE_NTDDCDRM=1) - else (ntddcdrm_INCLUDE_DIR) - message(STATUS "Could not find ntddcdrm.h") - endif (ntddcdrm_INCLUDE_DIR) - endif(YAB_WANT_DDK) - - set(yabause_SOURCES ${yabause_SOURCES} cd-windows.c) - - option(YAB_WANT_DIRECTSOUND "use DirectX sound core if available") - option(YAB_WANT_DIRECTINPUT "use DirectX input core if available") - - if (YAB_WANT_DIRECTSOUND OR YAB_WANT_DIRECTINPUT) - find_path(DirectX_INCLUDE_DIR dxerr9.h "$ENV{DXSDK_DIR}/Include") - if (NOT DirectX_INCLUDE_DIR) - find_path(DirectX_INCLUDE_DIR "dxerr.h" "$ENV{DXSDK_DIR}/Include") - if (DirectX_INCLUDE_DIR) - set(DXERRH_IS_BROKEN 1 CACHE INTERNAL "dxerr is broken") - endif (DirectX_INCLUDE_DIR) - endif(NOT DirectX_INCLUDE_DIR) - - find_library(DirectX_GUID_LIBRARY dxguid "$ENV{DXSDK_DIR}/Lib/x86" "$ENV{DXSDK_DIR}/Lib") - if (YAB_WANT_DIRECTINPUT) - find_library(DirectX_INPUT8_LIBRARY dinput8 "$ENV{DXSDK_DIR}/Lib/x86" "$ENV{DXSDK_DIR}/Lib") - endif(YAB_WANT_DIRECTINPUT) - if (YAB_WANT_DIRECTSOUND) - find_library(DirectX_SOUND_LIBRARY dsound "$ENV{DXSDK_DIR}/Lib/x86" "$ENV{DXSDK_DIR}/Lib") - endif(YAB_WANT_DIRECTSOUND) - - if (DXERRH_IS_BROKEN) - find_library(DirectX_ERR_LIBRARY dxerr "$ENV{DXSDK_DIR}/Lib/x86" "$ENV{DXSDK_DIR}/Lib") - elseif(MINGW) - find_library(DirectX_ERR_LIBRARY dxerr8 "$ENV{DXSDK_DIR}/Lib/x86" "$ENV{DXSDK_DIR}/Lib") - else() - find_library(DirectX_ERR_LIBRARY dxerr9 "$ENV{DXSDK_DIR}/Lib/x86" "$ENV{DXSDK_DIR}/Lib") - endif() - - if (DirectX_INCLUDE_DIR AND DirectX_GUID_LIBRARY AND DirectX_ERR_LIBRARY) - set(DIRECTX_FOUND "found") - include_directories(${DirectX_INCLUDE_DIR}) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${DirectX_GUID_LIBRARY} ${DirectX_ERR_LIBRARY}) - - if (DirectX_SOUND_LIBRARY AND DirectX_INPUT8_LIBRARY) - add_definitions(-DHAVE_DIRECTINPUT) - set(yabause_SOURCES ${yabause_SOURCES} snddx.c) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${DirectX_INPUT8_LIBRARY}) - endif (DirectX_SOUND_LIBRARY AND DirectX_INPUT8_LIBRARY) - if (YAB_WANT_DIRECTSOUND AND DirectX_SOUND_LIBRARY) - add_definitions(-DHAVE_DIRECTSOUND) - set(yabause_SOURCES ${yabause_SOURCES} perdx.c) - set(YABAUSE_LIBRARIES ${YABAUSE_LIBRARIES} ${DirectX_SOUND_LIBRARY}) - endif (YAB_WANT_DIRECTSOUND AND DirectX_SOUND_LIBRARY) - - if (DXERRH_IS_BROKEN) - add_definitions(-DDXERRH_IS_BROKEN) - message(STATUS "Using work-around for dxerr.h") - endif(DXERRH_IS_BROKEN) - endif (DirectX_INCLUDE_DIR AND DirectX_GUID_LIBRARY AND DirectX_ERR_LIBRARY) - endif (YAB_WANT_DIRECTSOUND OR YAB_WANT_DIRECTINPUT) -endif (WIN32) - -if (WII) - set(CMAKE_C_FLAGS "-mrvl -mcpu=750 -meabi -mhard-float") - add_definitions(-DGEKKO=1) - # that shouldn't be hardcoded, either use an ENV variable or try to detect it... - include_directories(/opt/devkitpro/libogc/include/) -endif() - -option(YAB_WANT_ARM7 "Build a binary with arm7 support") - -# SH2 dynamic recompiler -message(STATUS "CMAKE_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}") -message(STATUS "CMAKE_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR}") -option(SH2_DYNAREC "SH2 dynamic recompiler" ON) -if (SH2_DYNAREC) - if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") - if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686") - enable_language(ASM-ATT) - set(yabause_SOURCES ${yabause_SOURCES} - sh2_dynarec/sh2_dynarec.c sh2_dynarec/linkage_x86.s) - set_source_files_properties(sh2_dynarec/sh2_dynarec.c PROPERTIES COMPILE_FLAGS "-Wno-pointer-to-int-cast -Wno-int-to-pointer-cast") - add_definitions(-DSH2_DYNAREC=1) - endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686") - if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") - enable_language(ASM-ATT) - set(yabause_SOURCES ${yabause_SOURCES} - sh2_dynarec/sh2_dynarec.c sh2_dynarec/linkage_x64.s) - set_source_files_properties(sh2_dynarec/sh2_dynarec.c PROPERTIES COMPILE_FLAGS "-Wno-pointer-to-int-cast -Wno-int-to-pointer-cast") - add_definitions(-DSH2_DYNAREC=1) - endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") - if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv5tel") - enable_language(ASM-ATT) - set(yabause_SOURCES ${yabause_SOURCES} - sh2_dynarec/sh2_dynarec.c sh2_dynarec/linkage_arm.s) - set_source_files_properties(sh2_dynarec/sh2_dynarec.c PROPERTIES COMPILE_FLAGS "-Wno-pointer-to-int-cast -Wno-int-to-pointer-cast") - add_definitions(-DSH2_DYNAREC=1) - endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv5tel") - if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l") - enable_language(ASM-ATT) - set(yabause_SOURCES ${yabause_SOURCES} - sh2_dynarec/sh2_dynarec.c sh2_dynarec/linkage_arm.s) - set_source_files_properties(sh2_dynarec/sh2_dynarec.c PROPERTIES COMPILE_FLAGS "-Wno-pointer-to-int-cast -Wno-int-to-pointer-cast") - add_definitions(-DSH2_DYNAREC=1 -DHAVE_ARMv6=1 -DHAVE_ARMv7=1) - endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l") - if (ANDROID) - enable_language(ASM-ATT) - set(yabause_SOURCES ${yabause_SOURCES} - sh2_dynarec/sh2_dynarec.c sh2_dynarec/linkage_arm.s) - set_source_files_properties(sh2_dynarec/sh2_dynarec.c PROPERTIES COMPILE_FLAGS "-Wno-pointer-to-int-cast -Wno-int-to-pointer-cast") - add_definitions(-DSH2_DYNAREC=1) - add_definitions(-DANDROID=1) - if (YAB_WANT_ARM7) - add_definitions(-DHAVE_ARMv6=1 -DHAVE_ARMv7=1) - endif() - endif () - endif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") -endif (SH2_DYNAREC) - -# c68k -option(YAB_WANT_C68K "enable c68k compilation" ON) -if (YAB_WANT_C68K) - include(ExternalProject) - ExternalProject_Add(c68kinc - DOWNLOAD_COMMAND "" - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/c68k - CMAKE_GENERATOR "${CMAKE_GENERATOR}" - INSTALL_COMMAND "" - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/c68k - ) - - add_definitions(-DHAVE_C68K=1) - include_directories(${CMAKE_CURRENT_BINARY_DIR}/c68k) - set(yabause_SOURCES ${yabause_SOURCES} c68k/c68kexec.c c68k/c68k.c c68k/gen68k.c m68kc68k.c) - if (MSVC) - set_source_files_properties(c68k/c68kexec.c PROPERTIES COMPILE_FLAGS "/Od /wd4146") - else() - set_source_files_properties(c68k/c68kexec.c PROPERTIES COMPILE_FLAGS "-O0") - endif() -endif(YAB_WANT_C68K) - -# q68 -option(YAB_WANT_Q68 "enable q68 compilation" OFF) -if (YAB_WANT_Q68) - add_definitions(-DHAVE_Q68=1) - set(yabause_SOURCES ${yabause_SOURCES} - m68kq68.c q68/q68.c q68/q68-core.c q68/q68-disasm.c - q68/q68-const.h q68/q68.h q68/q68-internal.h q68/q68-jit.h q68/q68-jit-psp.h q68/q68-jit-x86.h) -endif() - -# *DEBUG -set(YAB_DEBUG "" CACHE STRING "List of enabled debug information") -foreach(DEBUG IN LISTS YAB_DEBUG) - if (${DEBUG} STREQUAL "main") - add_definitions(-DDEBUG=1) - elseif (${DEBUG} STREQUAL "cd") - add_definitions(-DCDDEBUG=1) - elseif (${DEBUG} STREQUAL "idle") - add_definitions(-DIDLE_DETECT_VERBOSE=1) - else (${DEBUG} STREQUAL "main") - string(TOUPPER ${DEBUG} UPDEBUG) - add_definitions(-D${UPDEBUG}_DEBUG=1) - endif (${DEBUG} STREQUAL "main") -endforeach(DEBUG) - -# Network -option(YAB_NETWORK "Enable network") -if (YAB_NETWORK) - add_definitions(-DUSESOCKET=1) -endif() - -# Peripheral key name -option(YAB_PERKEYNAME "Try to display key names instead of cryptic values" OFF) -if (YAB_PERKEYNAME) - add_definitions(-DPERKEYNAME=1) -endif() - -option(YAB_PORT_OSD "Let ports provides their own OSD core list" OFF) -if (YAB_PORT_OSD) - add_definitions(-DYAB_PORT_OSD=1) -endif() - -# Exec from cache -option(YAB_EXEC_FROM_CACHE "Allow code execution from 0xC0000000" OFF) -if (YAB_EXEC_FROM_CACHE) - add_definitions(-DEXEC_FROM_CACHE=1) -endif() - -# Optimized DMA -option(YAB_OPTIMIZED_DMA "Use optimized DMA when possible" OFF) -if (YAB_OPTIMIZED_DMA) - add_definitions(-DOPTIMIZED_DMA=1) -endif() - -# Yabause Arch -if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - add_definitions(-DARCH_IS_MACOSX=1) - set(yabause_SOURCES ${yabause_SOURCES} thr-dummy.c) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") - add_definitions(-DARCH_IS_FREEBSD=1) - set(yabause_SOURCES ${yabause_SOURCES} thr-dummy.c cd-freebsd.c) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - add_definitions(-DARCH_IS_LINUX=1) - set(yabause_SOURCES ${yabause_SOURCES} thr-linux.c cd-linux.c) - - check_include_file("linux/joystick.h" LINUX_HAS_JOYSTICK) - if (LINUX_HAS_JOYSTICK) - set(yabause_SOURCES ${yabause_SOURCES} perlinuxjoy.c) - endif() - - check_c_source_compiles(" - #include - int main(int argc, char ** argv) { int i = CDSL_CURRENT; } - " LINUX_CDROM_H_OK) - if (NOT LINUX_CDROM_H_OK) - add_definitions(-DLINUX_CDROM_H_IS_BROKEN) - endif (NOT LINUX_CDROM_H_OK) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "NetBSD") - add_definitions(-DARCH_IS_NETBSD=1) - set(yabause_SOURCES ${yabause_SOURCES} thr-dummy.c cd-netbsd.c) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") - add_definitions(-DARCH_IS_NETBSD=1) - set(yabause_SOURCES ${yabause_SOURCES} thr-dummy.c cd-netbsd.c) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows") - add_definitions(-DARCH_IS_WINDOWS=1) - set(yabause_SOURCES ${yabause_SOURCES} thr-dummy.c) -else () - add_definitions(-DUNKNOWN_ARCH=1) - set(yabause_SOURCES ${yabause_SOURCES} thr-dummy.c) -endif () - -set(YAB_OPTIMIZATION "-O3" CACHE STRING "Override optimization level") - -if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${YAB_OPTIMIZATION} -march=i686 -msse") -endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686") -if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${YAB_OPTIMIZATION}") -endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") -if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv5tel") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${YAB_OPTIMIZATION}") -endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv5tel") -if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${YAB_OPTIMIZATION}") -endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l") -if(ANDROID) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${YAB_OPTIMIZATION}") -endif() - -# Warnings defined to know when we're breaking compilation with MSVC -if (CMAKE_COMPILER_IS_GNUCC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wdeclaration-after-statement") -endif () - -if (MSVC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4018 /wd4244") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244") -endif () - -add_definitions(-DPACKAGE=\"${YAB_PACKAGE}\") -add_definitions(-DVERSION=\"${YAB_VERSION}\") - -add_library(yabause ${yabause_SOURCES}) - -if (YAB_WANT_C68K) - add_dependencies(yabause c68kinc) -endif(YAB_WANT_C68K) - -macro(yab_port_start) - if (YAB_PORT_BUILT AND NOT YAB_MULTIBUILD) - return() - endif () -endmacro(yab_port_start) - -macro(yab_port_stop) - set(YAB_PORT_BUILT TRUE PARENT_SCOPE) -endmacro(yab_port_stop) - -macro(yab_port_success YAB_TARGET) - if (NOT YAB_MULTIBUILD) - set_target_properties(${YAB_TARGET} PROPERTIES OUTPUT_NAME yabause) - set(YAB_PORT_NAME "yabause") - else () - set(YAB_PORT_NAME ${YAB_TARGET}) - endif () - set(YAB_PORT_BUILT TRUE PARENT_SCOPE) -endmacro(yab_port_success) - -set(YAB_MAN_DIR "share/man") -if (NOT $ENV{PKGMANDIR} STREQUAL "") - set(YAB_MAN_DIR $ENV{PKGMANDIR}) -endif () - -option(YAB_MULTIBUILD "Choose wether to build all ports or only a single one") -set(YAB_PORT_BUILT FALSE) -set(YAB_PORTS "gtk;qt;windows;dreamcast;wii;carbon;cocoa" CACHE STRING "List of ports to build") -foreach(PORT IN LISTS YAB_PORTS) - add_subdirectory(${PORT}) -endforeach(PORT) - -# this is stupid, but CMake automatic definitions are based on variables... -if (YAB_WANT_C68K) - set(HAVE_C68K ON) -endif() -if (YAB_WANT_Q68) - set(HAVE_Q68 ON) -endif() -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) diff --git a/yabause/src/Makefile.am b/yabause/src/Makefile.am deleted file mode 100644 index d7c32ca174..0000000000 --- a/yabause/src/Makefile.am +++ /dev/null @@ -1,117 +0,0 @@ -EXTRA_DIST = Makefile.dc Makefile.mng logo.bmp logo.png Makefile.wii logo.svg - -if COMPILE_C68K -SUBDIRS = c68k . $(YUI_SUBDIR) -else -SUBDIRS = . $(YUI_SUBDIR) -endif -if YUI_IS_CARBON -YUI_SUBDIR=carbon -endif -if YUI_IS_DREAMCAST -YUI_SUBDIR=dreamcast -endif -if YUI_IS_GTK -YUI_SUBDIR=gtk -endif -if YUI_IS_PSP -YUI_SUBDIR=psp -endif -if YUI_IS_QT -YUI_SUBDIR=qt -endif -if YUI_IS_WII -YUI_SUBDIR=wii -endif -if YUI_IS_WINDOWS -YUI_SUBDIR=windows -endif - -noinst_LIBRARIES = libyabause.a -libyabause_a_SOURCES = \ - bios.c bios.h cdbase.c cdbase.h cheat.c cheat.h coffelf.c coffelf.h \ - core.h cs0.c cs0.h cs1.c cs1.h cs2.c cs2.h \ - debug.c debug.h error.c error.h memory.c memory.h \ - m68kcore.c m68kcore.h m68kd.c m68kd.h movie.c movie.h \ - netlink.c netlink.h \ - osdcore.c osdcore.h \ - peripheral.h peripheral.c \ - persdljoy.c persdljoy.h profile.c profile.h \ - scu.c scu.h sh2core.c sh2core.h sh2d.c sh2d.h \ - sh2idle.c sh2idle.h sh2int.c sh2int.h sh2trace.c sh2trace.h \ - smpc.c smpc.h sndal.c sndal.h snddummy.c sndsdl.c sndsdl.h sndwav.c \ - threads.h titan/titan.c titan/titan.h vdp1.c vdp1.h vdp2.c vdp2.h \ - vdp2debug.c vdp2debug.h vidogl.c vidogl.h vidshared.c vidshared.h \ - vidsoft.c vidsoft.h yabause.c yabause.h ygl.h ygl.c yglshader.c yui.h - -if USE_SCSP2 -libyabause_a_SOURCES += scsp2.c scsp2.h -else -libyabause_a_SOURCES += scsp.c scsp.h -endif - -if COMPILE_C68K -libyabause_a_SOURCES += c68k/c68kexec.c c68k/c68k.c c68k/gen68k.c m68kc68k.c m68kc68k.h -c68kexec.o: c68k/c68kexec.c - $(COMPILE) -Ic68k -O0 $(srcdir)/c68k/c68kexec.c -c -o c68kexec.o -endif - -if COMPILE_Q68 -libyabause_a_SOURCES += m68kq68.c q68/q68.c q68/q68-core.c q68/q68-disasm.c \ - q68/q68-const.h q68/q68.h q68/q68-internal.h q68/q68-jit.h q68/q68-jit-psp.h q68/q68-jit-x86.h -if Q68_USE_JIT -libyabause_a_SOURCES += q68/q68-jit.c -if CPU_IS_X86 -libyabause_a_SOURCES += q68/q68-jit-x86.S -endif -if CPU_IS_X64 -libyabause_a_SOURCES += q68/q68-jit-x86.S -endif -if CPU_IS_PSP -libyabause_a_SOURCES += q68/q68-jit-psp.S -endif -endif -endif - -if ARCH_IS_FREEBSD -libyabause_a_SOURCES += cd-freebsd.c thr-dummy.c -endif -if ARCH_IS_LINUX -libyabause_a_SOURCES += cd-linux.c perlinuxjoy.c perlinuxjoy.h thr-linux.c -if USE_DYNAREC -if CPU_IS_X64 -libyabause_a_SOURCES += sh2_dynarec/sh2_dynarec.c sh2_dynarec/linkage_x64.s -AM_CFLAGS = -DSH2_DYNAREC=1 -endif -if CPU_IS_X86 -libyabause_a_SOURCES += sh2_dynarec/sh2_dynarec.c sh2_dynarec/linkage_x86.s -AM_CFLAGS = -DSH2_DYNAREC=1 -endif -if CPU_IS_ARM -libyabause_a_SOURCES += sh2_dynarec/sh2_dynarec.c sh2_dynarec/linkage_arm.s -AM_CFLAGS = -DSH2_DYNAREC=1 -mcpu=cortex-a8 -mfpu=vfp -mfloat-abi=softfp -endif -endif -endif -if ARCH_IS_MACOSX -libyabause_a_SOURCES += cd-macosx.c macjoy.c macjoy.h permacjoy.c permacjoy.h thr-dummy.c -endif -if ARCH_IS_NETBSD -libyabause_a_SOURCES += cd-netbsd.c thr-dummy.c -endif -if ARCH_IS_WINDOWS -libyabause_a_SOURCES += cd-windows.c thr-dummy.c -endif -if YUI_IS_DREAMCAST -libyabause_a_SOURCES += thr-dummy.c -endif -if YUI_IS_WII -libyabause_a_SOURCES += thr-dummy.c -endif - -if TEST_PSP_SH2 -libyabause_a_SOURCES += psp/psp-sh2.c psp/rtl.c psp/rtlexec.c psp/rtlinsn.c \ - psp/rtlopt.c psp/rtlunit.c psp/satopt-sh2.c psp/sh2.c \ - psp/sh2-interpret.c psp/sh2-opcodeinfo.c \ - psp/sh2-optimize.c -endif diff --git a/yabause/src/Makefile.dc b/yabause/src/Makefile.dc deleted file mode 100644 index 5110a387fb..0000000000 --- a/yabause/src/Makefile.dc +++ /dev/null @@ -1,67 +0,0 @@ -# Makefile.dc -# Dreamcast Makefile -# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Lawrence Sebald -# Based on KOS makefiles (C) by Dan Potter -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -# - -all: yabause.bin - -include $(KOS_BASE)/Makefile.rules - -KOS_CFLAGS += -I. -DDEBUG -DNO_CLI -DVERSION="0.9.11" -KOS_ASFLAGS += -g - -OBJS = bios.o cdbase.o cheat.o cs0.o cs1.o cs2.o debug.o error.o m68kd.o \ - memory.o netlink.o peripheral.o profile.o scsp.o scu.o sh2core.o sh2idle.o \ - sh2int.o sh2d.o smpc.o vdp1.o vdp2.o yabause.o m68kcore.o coffelf.o \ - m68kc68k.o movie.o snddummy.o -C68K_OBJS = c68k/c68k.o c68k/c68kexec.o c68k/gen68k.o -ARCH_OBJS = dreamcast/yui.o dreamcast/perdc.o dreamcast/viddc.o \ - dreamcast/localtime.o dreamcast/cd.o dreamcast/sh2rec/sh2rec.o \ - dreamcast/sh2rec/sh2rec_htab.o dreamcast/sh2rec/sh2exec.o \ - dreamcast/sh2rec/sh2rec_mem.o - -c68k/c68kexec.o: c68k/gen68k - -c68k/gen68k: c68k/c68kexec.c c68k/c68k.c c68k/gen68k.c - $(CC) $(CFLAGS) -DC68K_GEN -o $@ $^ - cd c68k && ./gen68k - -yabause.elf: $(OBJS) $(ARCH_OBJS) $(C68K_OBJS) - kos-cc -o $@ $^ -lm - -yabause.bin: yabause.elf - $(KOS_OBJCOPY) -R .stack -O binary yabause.elf yabause.bin - -cdtest.elf: dreamcast/cd.o tools/cdtest.o - kos-cc -o $@ $^ - -cdtest.bin: cdtest.elf - $(KOS_OBJCOPY) -R .stack -O binary cdtest.elf cdtest.bin - -run: yabause.bin - $(KOS_LOADER) yabause.bin - -clean: - rm -f $(OBJS) $(ARCH_OBJS) - rm -f tools/cdtest.o - rm -f yabause.elf - rm -f cdtest.elf - rm -f cdtest.bin - -distclean: clean - rm -f yabause.bin diff --git a/yabause/src/Makefile.mng b/yabause/src/Makefile.mng deleted file mode 100644 index a637e62614..0000000000 --- a/yabause/src/Makefile.mng +++ /dev/null @@ -1,86 +0,0 @@ -# Makefile.mng -# Mingw makefile -# Copyright (C) 2002, 2003, 2004 Lawrence Sebald -# Copyright (C) 2004-2007 Theo Berkau -# Based on KOS makefiles (C) by Dan Potter -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -# - -TARGET = yabause.exe -CC = gcc -RC = windres -#DDEFINES=-DDEBUG -VERSION=0.9.10 -DDEFINES= -VDEFINES=-DPACKAGE=\"yabause-win\" -DVERSION=\"$(VERSION)\" -DHAVE_LIBGLUT -DHAVE_LIBGL \ - -D_WIN32_IE=0x0500 -D_UNICODE -DUNICODE -DHAVE_LIBMINI18N -CFLAGS=$(VDEFINES) $(DDEFINES) -O3 -fomit-frame-pointer -fno-strict-aliasing -Wall -#CFLAGS=$(VDEFINES) $(DDEFINES) -O3 -fno-strict-aliasing -Wall -g -CFLAGS2= -fomit-frame-pointer -fno-strict-aliasing -Wall -#CFLAGS2= -fno-strict-aliasing -Wall -g -LDFLAGS=-lmingw32 -lopengl32 -lglut32 -lkernel32 -lgdi32 -lcomctl32 -lcomdlg32 -lwinmm \ - -lws2_32 -ldxguid -ldinput8 -ldxerr8 -ldsound -lmini18n -lvfw32 -mwindows -mthreads -OBJS = bios.o cdbase.o cheat.o coffelf.o cs0.o cs1.o cs2.o debug.o error.o m68kcore.o \ - m68kc68k.o m68kd.o memory.o movie.o netlink.o peripheral.o profile.o scsp.o scu.o sh2core.o \ - sh2idle.o sh2int.o sh2d.o smpc.o vdp1.o vdp2.o vdp2debug.o vidogl.o vidshared.o \ - vidsoft.o yabause.o ygl.o cd-windows.o c68k/c68k.o c68k/c68kexec.o c68k/gen68k.o \ - windows/perdx.o windows/snddx.o windows/yui.o windows/cheats.o windows/resource.o \ - windows/custctl.o windows/disasm.o windows/hexedit.o windows/cpudebug/yuidebug.o \ - windows/cpudebug/debug-68k.o windows/cpudebug/debug-scsp.o windows/cpudebug/debug-scu.o \ - windows/cpudebug/debug-sh2.o windows/cpudebug/debug-smpc.o windows/cpudebug/debug-vdp1.o \ - windows/cpudebug/debug-vdp2.o windows/settings/settings.o windows/settings/settings-basic.o \ - windows/settings/settings-input.o windows/settings/settings-log.o windows/settings/settings-netlink.o \ - windows/settings/settings-sound.o windows/settings/settings-video.o windows\bup-manager.o windows\aviout.o windows\ramwatch.o - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -.c.o: - $(CC) $(CFLAGS) -c $< -o $@ - -windows/resource.o: windows/resource.rc windows/resource.h - cd windows && $(RC) $(VDEFINES) $(DDEFINES) resource.rc -o resource.o - cd .. -clean: - rm -f $(OBJS) - rm -f $(TARGET) - -installer: - makensis "/XOutFile ..\..\yabause-$(VERSION)-win.exe" windows\installer\installer.nsi - -release: - zip -9 yabause-$(VERSION)-win.zip * -i *.dll -i yabause.exe - cd .. && zip -9 src\yabause-$(VERSION)-win.zip * -i AUTHORS -i Changelog -i COPYING -i README -i README.WIN - -cdbase.o: cdbase.h -cs0.o: cs0.h core.h -cs1.o: cs1.h core.h -debug.o: debug.h -memory.o: debug.h memory.h -scu.o: scu.h debug.h core.h -sh2core.o: sh2core.h core.h -sh2int.o: sh2core.h sh2int.h core.h -vdp1.o: vdp1.h debug.h memory.h -c68k/c68k.o: c68k/c68k.h -c68k/c68kexec.o: c68k/c68k.h c68k/c68k_ini.inc - $(CC) $(CFLAGS2) -c c68k/c68kexec.c -o $@ -c68k/c68k_ini.inc: c68k/gen68k.exe -c68k/gen68k.exe: c68k/c68kexec.c c68k/c68k.c c68k/gen68k.c - $(CC) $(CFLAGS) -DC68K_GEN -o $@ $^ - cd c68k && gen68k - - diff --git a/yabause/src/Makefile.wii b/yabause/src/Makefile.wii deleted file mode 100644 index 028d7c10d9..0000000000 --- a/yabause/src/Makefile.wii +++ /dev/null @@ -1,53 +0,0 @@ -# Makefile.wii -# Wii makefile -# Copyright (C) 2002, 2003, 2004 Lawrence Sebald -# Copyright (C) 2004-2008 Theo Berkau -# Based on KOS makefiles (C) by Dan Potter -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -# - -ifeq ($(strip $(DEVKITPPC)),) -$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC) -endif - -include $(DEVKITPPC)/wii_rules - -TARGET = yabause.elf -DDEFINES= -VDEFINES=-DPACKAGE=\"yabause-wii\" -DVERSION=\"0.9.6\" -DWORDS_BIGENDIAN -DREENTRANT_SYSCALLS_PROVIDED -MACHDEP = -DGEKKO -mcpu=750 -meabi -mhard-float -CFLAGS=$(VDEFINES) $(DDEFINES) -g -O2 -mrvl -Wall $(MACHDEP) -I$(LIBOGC_INC) -LDFLAGS= -g $(MACHDEP) -mrvl -Wl,-Map,$(notdir $@).map -LIBS := -lfat -lwiiuse -lbte -logc -lm -OBJS = bios.o cdbase.o cheat.o coffelf.o cs0.o cs1.o cs2.o debug.o \ -error.o m68kcore.o m68kc68k.o m68kd.o memory.o netlink.o peripheral.o \ -profile.o scsp.o scu.o sh2core.o sh2idle.o sh2int.o sh2d.o smpc.o vdp1.o \ -vdp2.o vidshared.o vidsoft.o yabause.o ygl.o c68k/c68k.o c68k/c68kexec.o \ -wii/yui.o wii/perwii.o wii/sndwii.o -DEPSDIR = $(CURDIR) -export LD := $(CC) -export LIBPATHS := -L$(LIBOGC_LIB) - -all: $(TARGET) - -$(TARGET): $(OBJS) - -clean: - rm -f $(OBJS) - rm -f $(TARGET) - -c68k/c68kexec.o: - $(CC) $(VDEFINES) $(DDEFINES) -mrvl -Wall $(MACHDEP) -I$(LIBOGC_INC) -c c68k/c68kexec.c -o $@ diff --git a/yabause/src/android/AndroidManifest.xml b/yabause/src/android/AndroidManifest.xml deleted file mode 100644 index 15ad60ee95..0000000000 --- a/yabause/src/android/AndroidManifest.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - diff --git a/yabause/src/android/CMakeLists.txt b/yabause/src/android/CMakeLists.txt deleted file mode 100644 index 4e10702f76..0000000000 --- a/yabause/src/android/CMakeLists.txt +++ /dev/null @@ -1,114 +0,0 @@ -find_program(NDK_BUILD ndk-build) - -if(NOT NDK_BUILD) - message(FATAL_ERROR "ndk build not found, bye") -endif() - -find_program(SDK_ANDROID android) - -if(NOT SDK_ANDROID) - message(FATAL_ERROR "sdk android tool not found, bye") -endif() - -if (NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) - set(yabause_android_SHADOW - AndroidManifest.xml - project.properties - jni/yui.c - jni/miniegl.h - jni/sndaudiotrack.c - jni/sndaudiotrack.h - src/org/yabause/android/Yabause.java - src/org/yabause/android/YabauseView.java - res/drawable/pad.png - res/drawable-hdpi/icon.png - res/drawable-ldpi/icon.png - res/drawable-mdpi/icon.png - res/layout/main.xml - res/menu/emulation.xml - res/values/strings.xml - ) - - foreach(item IN LISTS yabause_android_SHADOW) - message(STATUS ${item}) - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${item}" - COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${item}" "${CMAKE_CURRENT_BINARY_DIR}/${item}" - DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${item}" - ) - endforeach() -endif() - -set(YABAUSE_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..") -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/jni/Android.mk.in - ${CMAKE_CURRENT_BINARY_DIR}/jni/Android.mk - @ONLY -) - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/local.properties" - COMMAND ${SDK_ANDROID} update project -p "${CMAKE_CURRENT_BINARY_DIR}" - DEPENDS - "${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml" - "${CMAKE_CURRENT_BINARY_DIR}/project.properties" - "${CMAKE_CURRENT_BINARY_DIR}/jni/Android.mk" -) - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/jni/libyabause.a" - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/../libyabause.a ${CMAKE_CURRENT_BINARY_DIR}/jni/libyabause.a - DEPENDS yabause "${CMAKE_CURRENT_BINARY_DIR}/../config.h" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/local.properties" -) - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libs/armeabi/libyabause.so" - COMMAND "${NDK_BUILD}" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/jni/libyabause.a" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/jni/yui.c" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/jni/miniegl.h" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/jni/sndaudiotrack.c" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/jni/sndaudiotrack.h" - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} -) - -set(yabause_android_RES - "${CMAKE_CURRENT_BINARY_DIR}/res/drawable/pad.png" - "${CMAKE_CURRENT_BINARY_DIR}/res/drawable-hdpi/icon.png" - "${CMAKE_CURRENT_BINARY_DIR}/res/drawable-ldpi/icon.png" - "${CMAKE_CURRENT_BINARY_DIR}/res/drawable-mdpi/icon.png" - "${CMAKE_CURRENT_BINARY_DIR}/res/layout/main.xml" - "${CMAKE_CURRENT_BINARY_DIR}/res/menu/emulation.xml" - "${CMAKE_CURRENT_BINARY_DIR}/res/values/strings.xml" -) -set(yabause_android_SRC - "${CMAKE_CURRENT_BINARY_DIR}/src/org/yabause/android/Yabause.java" - "${CMAKE_CURRENT_BINARY_DIR}/src/org/yabause/android/YabauseView.java" -) - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/bin/Yabause-debug.apk" - COMMAND "ant" ARGS "debug" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libs/armeabi/libyabause.so" - DEPENDS ${yabause_android_SRC} - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml" - DEPENDS ${yabause_android_RES} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} -) - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/bin/Yabause-release-unsigned.apk" - COMMAND "ant" ARGS "release" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libs/armeabi/libyabause.so" - DEPENDS ${yabause_android_SRC} - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml" - DEPENDS ${yabause_android_RES} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} -) - -if(CMAKE_BUILD_TYPE STREQUAL "Release") - add_custom_target(yabause-android ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/bin/Yabause-release-unsigned.apk") -else() - add_custom_target(yabause-android ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/bin/Yabause-debug.apk") -endif() diff --git a/yabause/src/android/android.cmake b/yabause/src/android/android.cmake deleted file mode 100644 index d5640bad92..0000000000 --- a/yabause/src/android/android.cmake +++ /dev/null @@ -1,14 +0,0 @@ -SET(CMAKE_SYSTEM_NAME Linux) -SET(CMAKE_SYSTEM_VERSION 1) - -SET(CMAKE_C_COMPILER arm-linux-androideabi-gcc) -SET(CMAKE_CXX_COMPILER arm-linux-androideabi-g++) -SET(CMAKE_ASM-ATT_COMPILER arm-linux-androideabi-as) - -SET(CMAKE_FIND_ROOT_PATH /home/guillaume/projects/android/toolchain/sysroot/usr/) - -SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) - -SET(ANDROID ON) diff --git a/yabause/src/android/build.xml b/yabause/src/android/build.xml deleted file mode 100644 index ecb9624556..0000000000 --- a/yabause/src/android/build.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/yabause/src/android/jni/Android.mk.in b/yabause/src/android/jni/Android.mk.in deleted file mode 100644 index 6cfe1fbde7..0000000000 --- a/yabause/src/android/jni/Android.mk.in +++ /dev/null @@ -1,14 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := yabause -LOCAL_SRC_FILES := yui.c sndaudiotrack.c -LOCAL_STATIC_LIBRARIES := yabause-prebuilt -LOCAL_LDLIBS := -llog -ljnigraphics -lGLESv1_CM -include $(BUILD_SHARED_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_MODULE := yabause-prebuilt -LOCAL_SRC_FILES := libyabause.a -LOCAL_EXPORT_C_INCLUDES := @YABAUSE_INCLUDE_DIR@ -include $(PREBUILT_STATIC_LIBRARY) diff --git a/yabause/src/android/jni/miniegl.h b/yabause/src/android/jni/miniegl.h deleted file mode 100644 index a1a11b9f75..0000000000 --- a/yabause/src/android/jni/miniegl.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef _MINIEGL_ -#define _MINIEGL_ - -typedef int EGLint; -typedef unsigned int EGLBoolean; -typedef unsigned int EGLenum; -typedef void *EGLConfig; -typedef void *EGLContext; -typedef void *EGLDisplay; -typedef void *EGLSurface; -typedef void *EGLClientBuffer; - -/* EGL aliases */ -#define EGL_FALSE 0 -#define EGL_TRUE 1 - -/* Out-of-band handle values */ -#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) -#define EGL_NO_CONTEXT ((EGLContext)0) -#define EGL_NO_DISPLAY ((EGLDisplay)0) -#define EGL_NO_SURFACE ((EGLSurface)0) - -/* GetCurrentSurface targets */ -#define EGL_DRAW 0x3059 -#define EGL_READ 0x305A - -/* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */ -#define EGL_HEIGHT 0x3056 -#define EGL_WIDTH 0x3057 - -/* QueryString targets */ -#define EGL_VENDOR 0x3053 -#define EGL_VERSION 0x3054 -#define EGL_EXTENSIONS 0x3055 -#define EGL_CLIENT_APIS 0x308D - -EGLContext (*eglGetCurrentContext)(void); -EGLSurface (*eglGetCurrentSurface)(EGLint readdraw); -EGLDisplay (*eglGetCurrentDisplay)(void); -EGLBoolean (*eglQuerySurface)(EGLDisplay dpy, EGLSurface surface,EGLint attribute, EGLint *value); -EGLBoolean (*eglSwapInterval)(EGLDisplay dpy, EGLint interval); -EGLBoolean (*eglMakeCurrent)(EGLDisplay dpy, EGLSurface draw,EGLSurface read, EGLContext ctx); -EGLBoolean (*eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface); -const char * (*eglQueryString)(EGLDisplay dpy, EGLint name); -EGLint (*eglGetError)(void); - - -#endif // _MINIEGL_ \ No newline at end of file diff --git a/yabause/src/android/jni/sndaudiotrack.c b/yabause/src/android/jni/sndaudiotrack.c deleted file mode 100644 index 3232062216..0000000000 --- a/yabause/src/android/jni/sndaudiotrack.c +++ /dev/null @@ -1,221 +0,0 @@ -/* Copyright 2012 Guillaume Duhamel - Copyright 2005-2006 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include "sndaudiotrack.h" -#include "debug.h" - -static int SNDAudioTrackInit(void); -static void SNDAudioTrackDeInit(void); -static int SNDAudioTrackReset(void); -static int SNDAudioTrackChangeVideoFormat(int vertfreq); -static void SNDAudioTrackUpdateAudio(u32 *leftchanbuffer, u32 *rightchanbuffer, u32 num_samples); -static u32 SNDAudioTrackGetAudioSpace(void); -static void SNDAudioTrackMuteAudio(void); -static void SNDAudioTrackUnMuteAudio(void); -static void SNDAudioTrackSetVolume(int volume); - -SoundInterface_struct SNDAudioTrack = { -SNDCORE_AUDIOTRACK, -"Audio Track Sound Interface", -SNDAudioTrackInit, -SNDAudioTrackDeInit, -SNDAudioTrackReset, -SNDAudioTrackChangeVideoFormat, -SNDAudioTrackUpdateAudio, -SNDAudioTrackGetAudioSpace, -SNDAudioTrackMuteAudio, -SNDAudioTrackUnMuteAudio, -SNDAudioTrackSetVolume -}; - -extern JavaVM * yvm; - -jobject gtrack = NULL; - -jclass cAudioTrack = NULL; - -jmethodID mWrite = NULL; - -int mbufferSizeInBytes; - -static u16 *stereodata16; -static u8 soundvolume; -static u8 soundmaxvolume; -static u8 soundbufsize; -static int soundoffset; - -////////////////////////////////////////////////////////////////////////////// - -static int SNDAudioTrackInit(void) -{ - int sampleRateInHz = 44100; - int channelConfig = 12; //AudioFormat.CHANNEL_OUT_STEREO - int audioFormat = 2; //AudioFormat.ENCODING_PCM_16BIT - JNIEnv * env; - jobject mtrack = NULL; - jmethodID mPlay = NULL; - jmethodID mGetMinBufferSize = NULL; - jmethodID mAudioTrack = NULL; - - if ((*yvm)->GetEnv(yvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) - return -1; - - cAudioTrack = (*env)->FindClass(env, "android/media/AudioTrack"); - - mAudioTrack = (*env)->GetMethodID(env, cAudioTrack, "", "(IIIIII)V"); - - mWrite = (*env)->GetMethodID(env, cAudioTrack, "write", "([BII)I"); - - mPlay = (*env)->GetMethodID(env, cAudioTrack, "play", "()V"); - - mGetMinBufferSize = (*env)->GetStaticMethodID(env, cAudioTrack, "getMinBufferSize", "(III)I"); - - mbufferSizeInBytes = (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, sampleRateInHz, channelConfig, audioFormat); - - mtrack = (*env)->NewObject(env, cAudioTrack, mAudioTrack, 3 /* STREAM_MUSIC */, sampleRateInHz, channelConfig, audioFormat, mbufferSizeInBytes, 1 /* MODE_STREAM */); - - gtrack = (*env)->NewGlobalRef(env, mtrack); - - (*env)->CallNonvirtualVoidMethod(env, gtrack, cAudioTrack, mPlay); - - if ((stereodata16 = (u16 *)malloc(2 * mbufferSizeInBytes)) == NULL) - return -1; - memset(stereodata16, 0, soundbufsize); - - soundvolume = 100; - soundmaxvolume = 100; - soundbufsize = 85; - soundoffset = 0; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static void SNDAudioTrackDeInit(void) -{ - JNIEnv * env; - - if ((*yvm)->GetEnv(yvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) - return; - - free(stereodata16); - stereodata16 = NULL; - - (*env)->DeleteGlobalRef(env, gtrack); -} - -////////////////////////////////////////////////////////////////////////////// - -static int SNDAudioTrackReset(void) -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int SNDAudioTrackChangeVideoFormat(int vertfreq) -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static void sdlConvert32uto16s(s32 *srcL, s32 *srcR, s16 *dst, u32 len) { - u32 i; - - for (i = 0; i < len; i++) - { - // Left Channel - *srcL = ( *srcL *soundvolume ) / soundmaxvolume; - if (*srcL > 0x7FFF) *dst = 0x7FFF; - else if (*srcL < -0x8000) *dst = -0x8000; - else *dst = *srcL; - srcL++; - dst++; - // Right Channel - *srcR = ( *srcR *soundvolume ) / soundmaxvolume; - if (*srcR > 0x7FFF) *dst = 0x7FFF; - else if (*srcR < -0x8000) *dst = -0x8000; - else *dst = *srcR; - srcR++; - dst++; - } -} - -static void SNDAudioTrackUpdateAudio(u32 *leftchanbuffer, u32 *rightchanbuffer, u32 num_samples) -{ - u32 copy1size=0; - - copy1size = (num_samples * sizeof(s16) * 2); - - sdlConvert32uto16s((s32 *)leftchanbuffer, (s32 *)rightchanbuffer, (s16 *)(((u8 *)stereodata16)+soundoffset), copy1size / sizeof(s16) / 2); - - soundoffset += copy1size; - - if (soundoffset > mbufferSizeInBytes) { - JNIEnv * env; - if ((*yvm)->GetEnv(yvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) - return; - - jshortArray array = (*env)->NewShortArray(env, soundoffset); - if(array) { - (*env)->SetShortArrayRegion(env, array, 0, soundoffset, stereodata16); - } - - (*env)->CallNonvirtualIntMethod(env, gtrack, cAudioTrack, mWrite, array, 0, soundoffset); - - soundoffset = 0; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 SNDAudioTrackGetAudioSpace(void) -{ - static int i = 0; - i++; - if (i == 55) { - i = 0; - return mbufferSizeInBytes; - } else { - return 0; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void SNDAudioTrackMuteAudio(void) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static void SNDAudioTrackUnMuteAudio(void) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static void SNDAudioTrackSetVolume(int volume) -{ -} diff --git a/yabause/src/android/jni/sndaudiotrack.h b/yabause/src/android/jni/sndaudiotrack.h deleted file mode 100644 index b912d52749..0000000000 --- a/yabause/src/android/jni/sndaudiotrack.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright 2012 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef SNDAUDIOTRACK_H -#define SNDAUDIOTRACK_H - -#define SNDCORE_AUDIOTRACK 4 - -#include "scsp.h" - -extern SoundInterface_struct SNDAudioTrack; -#endif diff --git a/yabause/src/android/jni/yui.c b/yabause/src/android/jni/yui.c deleted file mode 100644 index 2d7dfc806e..0000000000 --- a/yabause/src/android/jni/yui.c +++ /dev/null @@ -1,419 +0,0 @@ -/* Copyright 2011 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include - -#include "../../config.h" -#include "yabause.h" -#include "scsp.h" -#include "vidsoft.h" -#include "peripheral.h" -#include "m68kcore.h" -#include "sh2core.h" -#include "sh2int.h" -#include "cdbase.h" -#include "cs2.h" -#include "debug.h" - -#include -#include - -#define _ANDROID_2_2_ -#ifdef _ANDROID_2_2_ -#include "miniegl.h" -#else -#include -#endif - -#include -#include -#include - -#include "sndaudiotrack.h" - -JavaVM * yvm; -static jobject yabause; -static jobject ybitmap; - -static char biospath[256] = "/mnt/sdcard/jap.rom"; -static char cdpath[256] = "\0"; -static char buppath[256] = "\0"; -static char mpegpath[256] = "\0"; -static char cartpath[256] = "\0"; - -EGLDisplay g_Display = EGL_NO_DISPLAY; -EGLSurface g_Surface = EGL_NO_SURFACE; -EGLContext g_Context = EGL_NO_CONTEXT; -GLuint g_FrameBuffer = 0; -GLuint g_VertexBuffer = 0; -int g_buf_width = -1; -int g_buf_height = -1; -pthread_mutex_t g_mtxGlLock = PTHREAD_MUTEX_INITIALIZER; -float vertices [] = { - 0, 0, 0, 0, - 320, 0, 0, 0, - 320, 224, 0, 0, - 0, 224, 0, 0 -}; - - -M68K_struct * M68KCoreList[] = { -&M68KDummy, -#ifdef HAVE_C68K -&M68KC68K, -#endif -#ifdef HAVE_Q68 -&M68KQ68, -#endif -NULL -}; - -SH2Interface_struct *SH2CoreList[] = { -&SH2Interpreter, -&SH2DebugInterpreter, -#ifdef SH2_DYNAREC -&SH2Dynarec, -#endif -NULL -}; - -PerInterface_struct *PERCoreList[] = { -&PERDummy, -NULL -}; - -CDInterface *CDCoreList[] = { -&DummyCD, -&ISOCD, -NULL -}; - -SoundInterface_struct *SNDCoreList[] = { -&SNDDummy, -&SNDAudioTrack, -NULL -}; - -VideoInterface_struct *VIDCoreList[] = { -&VIDDummy, -&VIDSoft, -NULL -}; - - -#define LOG_TAG "yabause" - -/* Override printf for debug*/ -int printf( const char * fmt, ... ) -{ - va_list ap; - va_start(ap, fmt); - int result = __android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, fmt, ap); - va_end(ap); - return result; -} - -void YuiErrorMsg(const char *string) -{ - jclass yclass; - jmethodID errorMsg; - jstring message; - JNIEnv * env; - if ((*yvm)->GetEnv(yvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) - return; - - yclass = (*env)->GetObjectClass(env, yabause); - errorMsg = (*env)->GetMethodID(env, yclass, "errorMsg", "(Ljava/lang/String;)V"); - message = (*env)->NewStringUTF(env, string); - (*env)->CallVoidMethod(env, yabause, errorMsg, message); -} - -void YuiSwapBuffers(void) -{ - int buf_width, buf_height; - int error; - - - pthread_mutex_lock(&g_mtxGlLock); - if( g_Display == EGL_NO_DISPLAY ) - { - pthread_mutex_unlock(&g_mtxGlLock); - return; - } - - if( eglMakeCurrent(g_Display,g_Surface,g_Surface,g_Context) == EGL_FALSE ) - { - printf( "eglMakeCurrent fail %04x",eglGetError()); - pthread_mutex_unlock(&g_mtxGlLock); - return; - } - - glClearColor( 0.0f,0.0f,0.0f,1.0f); - glClear(GL_COLOR_BUFFER_BIT); - - - if( g_FrameBuffer == 0 ) - { - glEnable(GL_TEXTURE_2D); - glGenTextures(1,&g_FrameBuffer); - glBindTexture(GL_TEXTURE_2D, g_FrameBuffer); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - error = glGetError(); - if( error != GL_NO_ERROR ) - { - printf("gl error %d", error ); - return; - } - }else{ - glBindTexture(GL_TEXTURE_2D, g_FrameBuffer); - } - - - VIDCore->GetGlSize(&buf_width, &buf_height); - glTexSubImage2D(GL_TEXTURE_2D, 0,0,0,buf_width,buf_height,GL_RGBA,GL_UNSIGNED_BYTE,dispbuffer); - - - if( g_VertexBuffer == 0 ) - { - glGenBuffers(1, &g_VertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, g_VertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices,GL_STATIC_DRAW); - error = glGetError(); - if( error != GL_NO_ERROR ) - { - printf("gl error %d", error ); - return; - } - }else{ - glBindBuffer(GL_ARRAY_BUFFER, g_VertexBuffer); - } - - if( buf_width != g_buf_width || buf_height != g_buf_height ) - { - vertices[6]=vertices[10]=(float)buf_width/1024.f; - vertices[11]=vertices[15]=(float)buf_height/1024.f; - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices,GL_STATIC_DRAW); - glVertexPointer(2, GL_FLOAT, sizeof(float)*4, 0); - glTexCoordPointer(2, GL_FLOAT, sizeof(float)*4, (void*)(sizeof(float)*2)); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - g_buf_width = buf_width; - g_buf_height = buf_height; - } - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - eglSwapBuffers(g_Display,g_Surface); - - pthread_mutex_unlock(&g_mtxGlLock); -} - -int Java_org_yabause_android_YabauseRunnable_initViewport( int width, int height) -{ - int swidth; - int sheight; - int error; - char * buf; - - g_Display = eglGetCurrentDisplay(); - g_Surface = eglGetCurrentSurface(EGL_READ); - g_Context = eglGetCurrentContext(); - - eglQuerySurface(g_Display,g_Surface,EGL_WIDTH,&swidth); - eglQuerySurface(g_Display,g_Surface,EGL_HEIGHT,&sheight); - - glViewport(0,0,swidth,sheight); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrthof(0, 320, 224, 0, 1, 0); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - - glDisable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - printf(glGetString(GL_VENDOR)); - printf(glGetString(GL_RENDERER)); - printf(glGetString(GL_VERSION)); - printf(glGetString(GL_EXTENSIONS)); - printf(eglQueryString(g_Display,EGL_EXTENSIONS)); - eglSwapInterval(g_Display,0); - eglMakeCurrent(g_Display,EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT); - return 0; -} - -#ifdef _ANDROID_2_2_ -int initEGLFunc() -{ - void * handle; - char *error; - - handle = dlopen("libEGL.so",RTLD_LAZY); - if( handle == NULL ) - { - printf(dlerror()); - return -1; - } - - eglGetCurrentDisplay = dlsym(handle, "eglGetCurrentDisplay"); - if( eglGetCurrentDisplay == NULL){ printf(dlerror()); return -1; } - - eglGetCurrentSurface = dlsym(handle, "eglGetCurrentSurface"); - if( eglGetCurrentSurface == NULL){ printf(dlerror()); return -1; } - - eglGetCurrentContext = dlsym(handle, "eglGetCurrentContext"); - if( eglGetCurrentContext == NULL){ printf(dlerror()); return -1; } - - eglQuerySurface = dlsym(handle, "eglQuerySurface"); - if( eglQuerySurface == NULL){ printf(dlerror()); return -1; } - - eglSwapInterval = dlsym(handle, "eglSwapInterval"); - if( eglSwapInterval == NULL){ printf(dlerror()); return -1; } - - eglMakeCurrent = dlsym(handle, "eglMakeCurrent"); - if( eglMakeCurrent == NULL){ printf(dlerror()); return -1; } - - eglSwapBuffers = dlsym(handle, "eglSwapBuffers"); - if( eglSwapBuffers == NULL){ printf(dlerror()); return -1; } - - eglQueryString = dlsym(handle, "eglQueryString"); - if( eglQueryString == NULL){ printf(dlerror()); return -1; } - - eglGetError = dlsym(handle, "eglGetError"); - if( eglGetError == NULL){ printf(dlerror()); return -1; } - - return 0; -} -#else -int initEGLFunc() -{ - return 0; -} -#endif - -int Java_org_yabause_android_YabauseRunnable_lockGL() -{ - pthread_mutex_lock(&g_mtxGlLock); -} - -int Java_org_yabause_android_YabauseRunnable_unlockGL() -{ - pthread_mutex_unlock(&g_mtxGlLock); -} - - -jint -Java_org_yabause_android_YabauseRunnable_init( JNIEnv* env, jobject obj, jobject yab, jobject bitmap ) -{ - yabauseinit_struct yinit; - int res; - void * padbits; - - if( initEGLFunc() == -1 ) return -1; - - yabause = (*env)->NewGlobalRef(env, yab); - ybitmap = (*env)->NewGlobalRef(env, bitmap); - - yinit.m68kcoretype = M68KCORE_C68K; - yinit.percoretype = PERCORE_DUMMY; -#ifdef SH2_DYNAREC - yinit.sh2coretype = 2; -#else - yinit.sh2coretype = SH2CORE_DEFAULT; -#endif - yinit.vidcoretype = VIDCORE_SOFT; - yinit.sndcoretype = SNDCORE_AUDIOTRACK; - yinit.cdcoretype = CDCORE_DEFAULT; - yinit.carttype = CART_NONE; - yinit.regionid = 0; - yinit.biospath = biospath; - yinit.cdpath = cdpath; - yinit.buppath = buppath; - yinit.mpegpath = mpegpath; - yinit.cartpath = cartpath; - yinit.videoformattype = VIDEOFORMATTYPE_NTSC; - - res = YabauseInit(&yinit); - - PerPortReset(); - padbits = PerPadAdd(&PORTDATA1); - PerSetKey(1, PERPAD_LEFT, padbits); - PerSetKey(4, PERPAD_UP, padbits); - PerSetKey(6, PERPAD_DOWN, padbits); - PerSetKey(9, PERPAD_RIGHT, padbits); - - ScspSetFrameAccurate(1); - - return res; -} - -void -Java_org_yabause_android_YabauseRunnable_deinit( JNIEnv* env ) -{ - YabauseDeInit(); -} - -void -Java_org_yabause_android_YabauseRunnable_exec( JNIEnv* env ) -{ - YabauseExec(); -} - -void -Java_org_yabause_android_YabauseRunnable_press( JNIEnv* env, jobject obj, jint key ) -{ - PerKeyDown(key); -} - -void -Java_org_yabause_android_YabauseRunnable_release( JNIEnv* env, jobject obj, jint key ) -{ - PerKeyUp(key); -} - -void log_callback(char * message) -{ - __android_log_print(ANDROID_LOG_INFO, "yabause", "%s", message); -} - -jint JNI_OnLoad(JavaVM * vm, void * reserved) -{ - JNIEnv * env; - if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK) - return -1; - - yvm = vm; - - LogStart(); - LogChangeOutput(DEBUG_CALLBACK, (char *) log_callback); - - return JNI_VERSION_1_6; -} - diff --git a/yabause/src/android/project.properties b/yabause/src/android/project.properties deleted file mode 100644 index ea89160e01..0000000000 --- a/yabause/src/android/project.properties +++ /dev/null @@ -1,11 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system use, -# "ant.properties", and override values to adapt the script to your -# project structure. - -# Project target. -target=android-8 diff --git a/yabause/src/android/res/drawable-hdpi/icon.png b/yabause/src/android/res/drawable-hdpi/icon.png deleted file mode 100644 index 8a878c20d7..0000000000 Binary files a/yabause/src/android/res/drawable-hdpi/icon.png and /dev/null differ diff --git a/yabause/src/android/res/drawable-ldpi/icon.png b/yabause/src/android/res/drawable-ldpi/icon.png deleted file mode 100644 index f987e3f090..0000000000 Binary files a/yabause/src/android/res/drawable-ldpi/icon.png and /dev/null differ diff --git a/yabause/src/android/res/drawable-mdpi/icon.png b/yabause/src/android/res/drawable-mdpi/icon.png deleted file mode 100644 index 697e446a93..0000000000 Binary files a/yabause/src/android/res/drawable-mdpi/icon.png and /dev/null differ diff --git a/yabause/src/android/res/drawable/pad.png b/yabause/src/android/res/drawable/pad.png deleted file mode 100644 index 229ee2dabe..0000000000 Binary files a/yabause/src/android/res/drawable/pad.png and /dev/null differ diff --git a/yabause/src/android/res/layout/main.xml b/yabause/src/android/res/layout/main.xml deleted file mode 100644 index ed24490ae9..0000000000 --- a/yabause/src/android/res/layout/main.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - diff --git a/yabause/src/android/res/menu/emulation.xml b/yabause/src/android/res/menu/emulation.xml deleted file mode 100644 index 4bc79a0e2c..0000000000 --- a/yabause/src/android/res/menu/emulation.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - diff --git a/yabause/src/android/res/values/strings.xml b/yabause/src/android/res/values/strings.xml deleted file mode 100644 index a9a427a080..0000000000 --- a/yabause/src/android/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - Yabause - diff --git a/yabause/src/android/src/org/yabause/android/Yabause.java b/yabause/src/android/src/org/yabause/android/Yabause.java deleted file mode 100644 index ec9f5eb6ba..0000000000 --- a/yabause/src/android/src/org/yabause/android/Yabause.java +++ /dev/null @@ -1,265 +0,0 @@ -/* Copyright 2011 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -package org.yabause.android; - -import java.lang.Runnable; - -import android.app.Activity; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.util.Log; -import android.graphics.Bitmap; -import android.view.Menu; -import android.view.MenuItem; -import android.view.MenuInflater; -import android.app.Dialog; -import android.app.AlertDialog; -import android.app.AlertDialog.Builder; -import android.content.DialogInterface; -import org.yabause.android.YabauseView; -import android.widget.ImageView; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.OnTouchListener; - -class InputHandler extends Handler { - private YabauseRunnable yr; - - public InputHandler(YabauseRunnable yr) { - this.yr = yr; - } - - public void handleMessage(Message msg) { - if (msg.arg1 == 1) { - yr.press(msg.arg2); - } else if (msg.arg1 == 2) { - yr.release(msg.arg2); - } - } -} - -class YabauseRunnable implements Runnable -{ - public static native int init(Yabause yabause, Bitmap bitmap); - public static native void deinit(); - public static native void exec(); - public static native void press(int key); - public static native void release(int key); - public static native int initViewport( int width, int hieght); - public static native int drawScreen(); - public static native int lockGL(); - public static native int unlockGL(); - - private boolean inited; - private boolean paused; - public InputHandler handler; - - public YabauseRunnable(Yabause yabause, Bitmap bitmap) - { - handler = new InputHandler(this); - int ok = init(yabause, bitmap); - inited = (ok == 0); - } - - public void pause() - { - Log.v("Yabause", "pause... should really pause emulation now..."); - paused = true; - } - - public void resume() - { - Log.v("Yabause", "resuming emulation..."); - paused = false; - handler.post(this); - } - - public void destroy() - { - Log.v("Yabause", "destroying yabause..."); - inited = false; - deinit(); - } - - public void run() - { - if (inited && (! paused)) - { - exec(); - - handler.post(this); - } - } - - public boolean paused() - { - return paused; - } -} - -class YabauseHandler extends Handler { - private Yabause yabause; - - public YabauseHandler(Yabause yabause) { - this.yabause = yabause; - } - - public void handleMessage(Message msg) { - yabause.showDialog(msg.what, msg.getData()); - } -} - -public class Yabause extends Activity implements OnTouchListener -{ - private static final String TAG = "Yabause"; - private YabauseRunnable yabauseThread; - private YabauseHandler handler; - - /** Called when the activity is first created. */ - @Override - public void onCreate(Bundle savedInstanceState) - { - super.onCreate(savedInstanceState); - - setContentView(R.layout.main); - - YabauseView view = (YabauseView) findViewById(R.id.yabause_view); - handler = new YabauseHandler(this); - yabauseThread = new YabauseRunnable(this,null); - view.setYabauseRunnable(yabauseThread); - - ImageView pad = (ImageView) findViewById(R.id.yabause_pad); - pad.setOnTouchListener(this); - } - - @Override - public void onPause() - { - super.onPause(); - Log.v(TAG, "pause... should pause emulation..."); - yabauseThread.pause(); - } - - @Override - public void onResume() - { - super.onResume(); - Log.v(TAG, "resume... should resume emulation..."); - yabauseThread.resume(); - } - - @Override - public void onDestroy() - { - super.onDestroy(); - Log.v(TAG, "this is the end..."); - yabauseThread.destroy(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.emulation, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.pause: - yabauseThread.pause(); - return true; - case R.id.quit: - this.finish(); - return true; - case R.id.resume: - yabauseThread.resume(); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - if (yabauseThread.paused()) { - menu.setGroupVisible(R.id.paused, true); - menu.setGroupVisible(R.id.running, false); - } else { - menu.setGroupVisible(R.id.paused, false); - menu.setGroupVisible(R.id.running, true); - } - return true; - } - - @Override - public Dialog onCreateDialog(int id, Bundle args) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setMessage(args.getString("message")) - .setCancelable(false) - .setNegativeButton("Exit", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - Yabause.this.finish(); - } - }) - .setPositiveButton("Ignore", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); - AlertDialog alert = builder.create(); - return alert; - } - - public boolean onTouch(View v, MotionEvent event) { - int action = event.getActionMasked(); - float x = event.getX(); - float y = event.getY(); - int keyx = (int) ((x - 10) / 30); - int keyy = (int) ((y - 10) / 30); - int key = (keyx << 2) | keyy; - int keya = 0; - if (action == event.ACTION_DOWN) { - keya = 1; - } else if (action == event.ACTION_UP) { - keya = 2; - } - - Message message = handler.obtainMessage(); - message.arg1 = keya; - message.arg2 = key; - yabauseThread.handler.sendMessage(message); - - return true; - } - - private void errorMsg(String msg) { - Message message = handler.obtainMessage(); - Bundle bundle = new Bundle(); - bundle.putString("message", msg); - message.setData(bundle); - handler.sendMessage(message); - } - - static { - System.loadLibrary("yabause"); - } -} diff --git a/yabause/src/android/src/org/yabause/android/YabauseView.java b/yabause/src/android/src/org/yabause/android/YabauseView.java deleted file mode 100644 index 0b114e7e41..0000000000 --- a/yabause/src/android/src/org/yabause/android/YabauseView.java +++ /dev/null @@ -1,196 +0,0 @@ -/* Copyright 2011 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -package org.yabause.android; - -import java.lang.Runnable; - -import javax.microedition.khronos.egl.EGL10; -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.egl.EGLContext; -import javax.microedition.khronos.egl.EGLDisplay; -import javax.microedition.khronos.egl.EGLSurface; - -import android.content.Context; -import android.util.AttributeSet; -import android.util.Log; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.SurfaceHolder; -import android.view.SurfaceHolder.Callback; -import android.view.SurfaceView; -import android.view.View; - -class YabauseView extends SurfaceView implements Callback, View.OnKeyListener, View.OnTouchListener{ - private static String TAG = "YabauseView"; - private static final boolean DEBUG = false; - - private int axisX = 0; - private int axisY = 0; - - public boolean[] pointers = new boolean[256]; - public int[] pointerX = new int[256]; - public int[] pointerY = new int[256]; - - private YabauseRunnable _Runnable = null; - - private EGLContext mEglContext; - private EGLDisplay mEglDisplay; - private EGLSurface mEglSurface; - private EGLConfig mEglConfig; - - - public YabauseView(Context context, AttributeSet attrs) { - super(context,attrs); - init(false, 0, 0); - } - - public YabauseView(Context context) { - super(context); - init(false, 0, 0); - } - - public YabauseView(Context context, boolean translucent, int depth, int stencil) { - super(context); - init(translucent, depth, stencil); - } - - public void setYabauseRunnable( YabauseRunnable runnable ) - { - _Runnable = runnable; - } - - private void init(boolean translucent, int depth, int stencil) { - - setFocusable( true ); - setFocusableInTouchMode( true ); - requestFocus(); - setOnKeyListener( this ); - setOnTouchListener( this ); - - getHolder().addCallback(this); - getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU); - initGLES(); - - } - - private boolean initGLES(){ - - EGL10 egl = (EGL10)EGLContext.getEGL(); - - mEglDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); - if( mEglDisplay == EGL10.EGL_NO_DISPLAY ){ - Log.e(TAG, "Fail to get Display"); - return false; - } - - int[] version = new int[2]; - if( !egl.eglInitialize(mEglDisplay, version) ){ - Log.e(TAG, "Fail to eglInitialize"); - return false; - } - - int[] configSpec = { - EGL10.EGL_NONE - }; - EGLConfig[] configs = new EGLConfig[1]; - - int[] numConfigs = new int[1]; - if( !egl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, numConfigs) ){ - Log.e(TAG, "Fail to Choose Config"); - return false; - } - mEglConfig = configs[0]; - - mEglContext = egl.eglCreateContext(mEglDisplay, mEglConfig, EGL10.EGL_NO_CONTEXT, null); - if( mEglContext == EGL10.EGL_NO_CONTEXT ){ - Log.e(TAG, "Fail to Create OpenGL Context"); - return false; - } - return true; - } - - - private boolean createSurface(){ - EGL10 egl = (EGL10)EGLContext.getEGL(); - mEglSurface = egl.eglCreateWindowSurface(mEglDisplay, mEglConfig, getHolder(), null); - if( mEglSurface == EGL10.EGL_NO_SURFACE ){ - return false; - } - return true; - } - - private void endGLES(){ - EGL10 egl = (EGL10)EGLContext.getEGL(); - if( mEglSurface != null){ - //レンダリングコンテキストとの結びつけは解除 - egl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); - - egl.eglDestroySurface(mEglDisplay, mEglSurface); - mEglSurface = null; - } - - if( mEglContext != null ){ - egl.eglDestroyContext(mEglDisplay, mEglContext); - mEglContext = null; - } - - if( mEglDisplay != null){ - egl.eglTerminate(mEglDisplay); - mEglDisplay = null; - } - } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - - EGL10 egl = (EGL10)EGLContext.getEGL(); - - YabauseRunnable.lockGL(); - egl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); - YabauseRunnable.initViewport(width, height); - YabauseRunnable.unlockGL(); - - } - - @Override - public void surfaceCreated(SurfaceHolder holder) { - if( !createSurface() ){ - Log.e(TAG, "Fail to Creat4e Surface"); - return ; - } - } - - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - - } - - // Key events - public boolean onKey( View v, int keyCode, KeyEvent event ) - { - return false; - } - - public boolean onTouch( View v, MotionEvent event ) - { - return true; - } - -} diff --git a/yabause/src/bios.c b/yabause/src/bios.c deleted file mode 100644 index 1d7032ab54..0000000000 --- a/yabause/src/bios.c +++ /dev/null @@ -1,1869 +0,0 @@ -/* Copyright 2006-2007 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "memory.h" -#include "cs0.h" -#include "debug.h" -#include "sh2core.h" -#include "bios.h" -#include "smpc.h" - -static u8 sh2masklist[0x20] = { -0xF0, 0xE0, 0xD0, 0xC0, 0xB0, 0xA0, 0x90, 0x80, -0x80, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, -0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, -0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70 -}; - -static u32 scumasklist[0x20] = { -0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFC, 0xFFFFFFF8, -0xFFFFFFF0, 0xFFFFFFE0, 0xFFFFFFC0, 0xFFFFFF80, -0xFFFFFF80, 0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, -0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, -0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, -0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, -0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, -0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00, 0xFFFFFE00 -}; - -u32 interruptlist[2][0x80]; - -////////////////////////////////////////////////////////////////////////////// - -void BiosInit(void) -{ - int i; - - // Setup vectors - MappedMemoryWriteLong(0x06000600, 0x002B0009); // rte, nop - MappedMemoryWriteLong(0x06000604, 0xE0F0600C); // mov #0xF0, r0; extu.b r0, r0 - MappedMemoryWriteLong(0x06000608, 0x400E8BFE); // ldc r0, sr; bf - MappedMemoryWriteLong(0x0600060C, 0x00090009); // nop - MappedMemoryWriteLong(0x06000610, 0x000B0009); // rts, nop - - for (i = 0; i < 0x200; i+=4) - { - MappedMemoryWriteLong(0x06000000+i, 0x06000600); - MappedMemoryWriteLong(0x06000400+i, 0x06000600); - interruptlist[0][i >> 2] = 0x06000600; - interruptlist[1][i >> 2] = 0x06000600; - } - - MappedMemoryWriteLong(0x06000010, 0x06000604); - MappedMemoryWriteLong(0x06000018, 0x06000604); - MappedMemoryWriteLong(0x06000024, 0x06000604); - MappedMemoryWriteLong(0x06000028, 0x06000604); - interruptlist[0][4] = 0x06000604; - interruptlist[0][6] = 0x06000604; - interruptlist[0][9] = 0x06000604; - interruptlist[0][10] = 0x06000604; - - MappedMemoryWriteLong(0x06000410, 0x06000604); - MappedMemoryWriteLong(0x06000418, 0x06000604); - MappedMemoryWriteLong(0x06000424, 0x06000604); - MappedMemoryWriteLong(0x06000428, 0x06000604); - interruptlist[1][4] = 0x06000604; - interruptlist[1][6] = 0x06000604; - interruptlist[1][9] = 0x06000604; - interruptlist[1][10] = 0x06000604; - - // Scu Interrupts - for (i = 0; i < 0x38; i+=4) - { - MappedMemoryWriteLong(0x06000100+i, 0x00000400+i); - interruptlist[0][0x40+(i >> 2)] = 0x00000400+i; - } - - for (i = 0; i < 0x40; i+=4) - { - MappedMemoryWriteLong(0x06000140+i, 0x00000440+i); - interruptlist[0][0x50+(i >> 2)] = 0x00000440+i; - } - - for (i = 0; i < 0x100; i+=4) - MappedMemoryWriteLong(0x06000A00+i, 0x06000610); - - // Setup Bios Functions - MappedMemoryWriteLong(0x06000210, 0x00000210); - MappedMemoryWriteLong(0x0600026C, 0x0000026C); - MappedMemoryWriteLong(0x06000274, 0x00000274); - MappedMemoryWriteLong(0x06000280, 0x00000280); - MappedMemoryWriteLong(0x0600029C, 0x0000029C); - MappedMemoryWriteLong(0x060002DC, 0x000002DC); - MappedMemoryWriteLong(0x06000300, 0x00000300); - MappedMemoryWriteLong(0x06000304, 0x00000304); - MappedMemoryWriteLong(0x06000310, 0x00000310); - MappedMemoryWriteLong(0x06000314, 0x00000314); - MappedMemoryWriteLong(0x06000320, 0x00000320); - MappedMemoryWriteLong(0x06000324, 0x00000000); - MappedMemoryWriteLong(0x06000330, 0x00000330); - MappedMemoryWriteLong(0x06000334, 0x00000334); - MappedMemoryWriteLong(0x06000340, 0x00000340); - MappedMemoryWriteLong(0x06000344, 0x00000344); - MappedMemoryWriteLong(0x06000348, 0xFFFFFFFF); - MappedMemoryWriteLong(0x06000354, 0x00000000); - MappedMemoryWriteLong(0x06000358, 0x00000358); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosSetScuInterrupt(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - -// LOG("BiosSetScuInterrupt. vector = %02X, func = %08X\n", sh->regs.R[4], sh->regs.R[5]); - - if (sh->regs.R[5] == 0) - { - MappedMemoryWriteLong(0x06000900+(sh->regs.R[4] << 2), 0x06000610); - sh->cycles += 8; - } - else - { - MappedMemoryWriteLong(0x06000900+(sh->regs.R[4] << 2), sh->regs.R[5]); - sh->cycles += 9; - } - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosGetScuInterrupt(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - // check me -// LOG("BiosGetScuInterrupt\n"); - - sh->regs.R[0] = MappedMemoryReadLong(0x06000900+(sh->regs.R[4] << 2)); - sh->cycles += 5; - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosSetSh2Interrupt(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - -// LOG("BiosSetSh2Interrupt\n"); - - if (sh->regs.R[5] == 0) - { - MappedMemoryWriteLong(sh->regs.VBR+(sh->regs.R[4] << 2), interruptlist[sh->isslave][sh->regs.R[4]]); - sh->cycles += 8; - } - else - { - MappedMemoryWriteLong(sh->regs.VBR+(sh->regs.R[4] << 2), sh->regs.R[5]); - sh->cycles += 9; - } - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosGetSh2Interrupt(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - // check me -// LOG("BiosGetSh2Interrupt\n"); - - sh->regs.R[0] = MappedMemoryReadLong(sh->regs.VBR+(sh->regs.R[4] << 2)); - sh->cycles += 5; - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosSetScuInterruptMask(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - // check me - LOG("BiosSetScuInterruptMask\n"); - - MappedMemoryWriteLong(0x06000348, sh->regs.R[4]); - MappedMemoryWriteLong(0x25FE00A0, sh->regs.R[4]); // Interrupt Mask Register - - if (!(sh->regs.R[4] & 0x8000)) // double check this - MappedMemoryWriteLong(0x25FE00A8, 1); // A-bus Interrupt Acknowledge - - sh->cycles += 17; - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosChangeScuInterruptMask(SH2_struct * sh) -{ - u32 newmask; - - SH2GetRegisters(sh, &sh->regs); - -// LOG("BiosChangeScuInterruptMask\n"); - - // Read Stored Scu Interrupt Mask, AND it by R4, OR it by R5, then put it back - newmask = (MappedMemoryReadLong(0x06000348) & sh->regs.R[4]) | sh->regs.R[5]; - MappedMemoryWriteLong(0x06000348, newmask); - MappedMemoryWriteLong(0x25FE00A0, newmask); // Interrupt Mask Register - MappedMemoryWriteLong(0x25FE00A4, (u32)(s16)sh->regs.R[4]); // Interrupt Status Register - - if (!(sh->regs.R[4] & 0x8000)) // double check this - MappedMemoryWriteLong(0x25FE00A8, 1); // A-bus Interrupt Acknowledge - - sh->cycles += 20; - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosCDINIT2(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosCDINIT1(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosGetSemaphore(SH2_struct * sh) -{ - u8 temp; - - SH2GetRegisters(sh, &sh->regs); - - // check me - LOG("BiosGetSemaphore\n"); - - if ((temp = MappedMemoryReadByte(0x06000B00 + sh->regs.R[4])) == 0) - sh->regs.R[0] = 1; - else - sh->regs.R[0] = 0; - - temp |= 0x80; - MappedMemoryWriteByte(0x06000B00 + sh->regs.R[4], temp); - - sh->cycles += 11; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosClearSemaphore(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - // check me - LOG("BiosClearSemaphore\n"); - - MappedMemoryWriteByte(0x06000B00 + sh->regs.R[4], 0); - - sh->cycles += 5; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosChangeSystemClock(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosChangeSystemClock\n"); - - MappedMemoryWriteLong(0x06000324, sh->regs.R[4]); - - if (sh->regs.R[4] == 0) - SmpcCKCHG320(); - else - SmpcCKCHG352(); - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosChangeScuInterruptPriority(SH2_struct * sh) -{ - int i; - - SH2GetRegisters(sh, &sh->regs); - - // check me -// LOG("BiosChangeScuInterruptPriority\n"); - - for (i = 0; i < 0x20; i++) - { - scumasklist[i] = MappedMemoryReadLong(sh->regs.R[4]+(i << 2)); - sh2masklist[i] = (scumasklist[i] >> 16); - if (scumasklist[i] & 0x8000) - scumasklist[i] |= 0xFFFF0000; - else - scumasklist[i] &= 0x0000FFFF; - } - - sh->cycles += 186; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosExecuteCDPlayer(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosExecuteCDPlayer\n"); - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosPowerOnMemoryClear(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosPowerOnMemoryClear\n"); - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosCheckMPEGCard(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosCheckMPEGCard\n"); - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 GetDeviceStats(u32 device, u32 *size, u32 *addr, u32 *blocksize) -{ - switch(device) - { - case 0: - *addr = 0x00180000; - *size = 0x8000; - *blocksize = 0x40; - return 0; - case 1: - if ((CartridgeArea->cartid & 0xF0) == 0x20) - { - *addr = 0x04000000; - *size = 0x40000 << (CartridgeArea->cartid & 0x0F); - if (CartridgeArea->cartid == 0x24) - *blocksize = 0x400; - else - *blocksize = 0x200; - - return 0; - } - else - return 1; - default: - *addr = 0; - *size = 0; - *blocksize = 0; - return 1; - } - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -static int CheckHeader(UNUSED u32 device) -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int CalcSaveSize(u32 tableaddr, int blocksize) -{ - int numblocks=0; - - // Now figure out how many blocks this save is - for(;;) - { - u16 block; - block = (MappedMemoryReadByte(tableaddr) << 8) | MappedMemoryReadByte(tableaddr + 2); - if (block == 0) - break; - tableaddr += 4; - if (((tableaddr-1) & ((blocksize << 1) - 1)) == 0) - tableaddr += 8; - numblocks++; - } - - return numblocks; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 GetFreeSpace(UNUSED u32 device, u32 size, u32 addr, u32 blocksize) -{ - u32 i; - u32 usedblocks=0; - - for (i = ((2 * blocksize) << 1); i < (size << 1); i += (blocksize << 1)) - { - // Find a block with the start of a save - if (((s8)MappedMemoryReadByte(addr + i + 1)) < 0) - { - // Now figure out how many blocks this save is - usedblocks += (CalcSaveSize(addr+i+0x45, blocksize) + 1); - } - } - - return ((size / blocksize) - 2 - usedblocks); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FindSave(UNUSED u32 device, u32 stringaddr, u32 blockoffset, u32 size, u32 addr, u32 blocksize) -{ - u32 i; - - for (i = ((blockoffset * blocksize) << 1); i < (size << 1); i += (blocksize << 1)) - { - // Find a block with the start of a save - if (((s8)MappedMemoryReadByte(addr + i + 1)) < 0) - { - int i3; - - // See if string matches, or if there's no string to check, just copy - // the data over - for (i3 = 0; i3 < 11; i3++) - { - u8 data = MappedMemoryReadByte(stringaddr+i3); - - if (MappedMemoryReadByte(addr+i+0x9+(i3*2)) != data) - { - if (data == 0) - // There's no string to match - return ((i / blocksize) >> 1); - else - // No Match, move onto the next block - i3 = 12; - } - else - { - // Match - if (i3 == 10 || data == 0) - return ((i / blocksize) >> 1); - } - } - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FindSave2(UNUSED u32 device, const char *string, u32 blockoffset, u32 size, u32 addr, u32 blocksize) -{ - u32 i; - - for (i = ((blockoffset * blocksize) << 1); i < (size << 1); i += (blocksize << 1)) - { - // Find a block with the start of a save - if (((s8)MappedMemoryReadByte(addr + i + 1)) < 0) - { - int i3; - - // See if string matches, or if there's no string to check, just copy - // the data over - for (i3 = 0; i3 < 11; i3++) - { - if (MappedMemoryReadByte(addr+i+0x9+(i3*2)) != string[i3]) - { - if (string[i3] == 0) - // There's no string to match - return ((i / blocksize) >> 1); - else - // No Match, move onto the next block - i3 = 12; - } - else - { - // Match - if (i3 == 10 || string[i3] == 0) - return ((i / blocksize) >> 1); - } - } - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static void DeleteSave(u32 addr, u32 blockoffset, u32 blocksize) -{ - MappedMemoryWriteByte(addr + (blockoffset * blocksize * 2) + 0x1, 0x00); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 *GetFreeBlocks(u32 addr, u32 blocksize, u32 numblocks, u32 size) -{ - u8 *blocktbl; - u16 *freetbl; - u32 tableaddr; - u32 i; - u32 blockcount=0; - - // Create a table that tells us which blocks are free and used - if ((blocktbl = (u8 *)malloc(sizeof(u8) * (size / blocksize))) == NULL) - return NULL; - - memset(blocktbl, 0, (size / blocksize)); - - for (i = ((2 * blocksize) << 1); i < (size << 1); i += (blocksize << 1)) - { - // Find a block with the start of a save - if (((s8)MappedMemoryReadByte(addr + i + 1)) < 0) - { - tableaddr = addr+i+0x45; - blocktbl[i / (blocksize << 1)] = 1; - - // Now let's figure out which blocks are used - for(;;) - { - u16 block; - block = (MappedMemoryReadByte(tableaddr) << 8) | MappedMemoryReadByte(tableaddr + 2); - if (block == 0) - break; - tableaddr += 4; - if (((tableaddr-1) & ((blocksize << 1) - 1)) == 0) - tableaddr += 8; - // block is used - blocktbl[block] = 1; - } - } - } - - if ((freetbl = (u16 *)malloc(sizeof(u16) * numblocks)) == NULL) - { - free(blocktbl); - return NULL; - } - - // Find some free blocks for us to use - for (i = 2; i < (size / blocksize); i++) - { - if (blocktbl[i] == 0) - { - freetbl[blockcount] = (u16)i; - blockcount++; - - if (blockcount >= numblocks) - break; - } - } - - // Ok, we're all done - free(blocktbl); - - return freetbl; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 *ReadBlockTable(u32 addr, u32 *tableaddr, int block, int blocksize, int *numblocks, int *blocksread) -{ - u16 *blocktbl; - int i=0; - - tableaddr[0] = addr + (block * blocksize * 2) + 0x45; - blocksread[0]=0; - - // First of all figure out how large of buffer we need - numblocks[0] = CalcSaveSize(tableaddr[0], blocksize); - - // Allocate buffer - if ((blocktbl = (u16 *)malloc(sizeof(u16) * numblocks[0])) == NULL) - return NULL; - - // Now read in the table - for(i = 0; i < numblocks[0]; i++) - { - u16 block; - block = (MappedMemoryReadByte(tableaddr[0]) << 8) | MappedMemoryReadByte(tableaddr[0] + 2); - tableaddr[0] += 4; - - if (((tableaddr[0]-1) & ((blocksize << 1) - 1)) == 0) - { - tableaddr[0] = addr + (blocktbl[blocksread[0]] * blocksize * 2) + 9; - blocksread[0]++; - } - blocktbl[i] = block; - } - - tableaddr[0] += 4; - - return blocktbl; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPInit(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - -// LOG("BiosBUPInit. arg1 = %08X, arg2 = %08X, arg3 = %08X\n", sh->regs.R[4], sh->regs.R[5], sh->regs.R[6]); - - // Setup Function table - MappedMemoryWriteLong(0x06000354, sh->regs.R[5]); - MappedMemoryWriteLong(sh->regs.R[5]+0x00, 0x00000380); - MappedMemoryWriteLong(sh->regs.R[5]+0x04, 0x00000384); - MappedMemoryWriteLong(sh->regs.R[5]+0x08, 0x00000388); - MappedMemoryWriteLong(sh->regs.R[5]+0x0C, 0x0000038C); - MappedMemoryWriteLong(sh->regs.R[5]+0x10, 0x00000390); - MappedMemoryWriteLong(sh->regs.R[5]+0x14, 0x00000394); - MappedMemoryWriteLong(sh->regs.R[5]+0x18, 0x00000398); - MappedMemoryWriteLong(sh->regs.R[5]+0x1C, 0x0000039C); - MappedMemoryWriteLong(sh->regs.R[5]+0x20, 0x000003A0); - MappedMemoryWriteLong(sh->regs.R[5]+0x24, 0x000003A4); - MappedMemoryWriteLong(sh->regs.R[5]+0x28, 0x000003A8); - MappedMemoryWriteLong(sh->regs.R[5]+0x2C, 0x000003AC); - - // Setup Device list - - // First Device - MappedMemoryWriteWord(sh->regs.R[6], 1); // ID - MappedMemoryWriteWord(sh->regs.R[6]+0x2, 1); // Number of partitions - - // Second Device - if ((CartridgeArea->cartid & 0xF0) == 0x20) - { - MappedMemoryWriteWord(sh->regs.R[6]+0x4, 2); // ID - MappedMemoryWriteWord(sh->regs.R[6]+0x6, 1); // Number of partitions - } - else - { - MappedMemoryWriteWord(sh->regs.R[6]+0x4, 0); // ID - MappedMemoryWriteWord(sh->regs.R[6]+0x6, 0); // Number of partitions - } - - // Third Device - MappedMemoryWriteWord(sh->regs.R[6]+0x08, 0); // ID - MappedMemoryWriteWord(sh->regs.R[6]+0x0A, 0); // Number of partitions - - // cycles need to be incremented - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPSelectPartition(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosBUPSelectPartition. PR = %08X\n", sh->regs.PR); - - sh->regs.R[0] = 0; // returns 0 if there's no error - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPFormat(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - -// LOG("BiosBUPFormat. PR = %08X\n", sh->regs.PR); - - BupFormat(sh->regs.R[4]); - - sh->regs.R[0] = 0; // returns 0 if there's no error - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPStatus(SH2_struct * sh) -{ - u32 size; - u32 addr; - u32 blocksize; - u32 ret; - u32 freeblocks=0; - - SH2GetRegisters(sh, &sh->regs); - -// LOG("BiosBUPStatus. arg1 = %d, arg2 = %d, arg3 = %08X, PR = %08X\n", sh->regs.R[4], sh->regs.R[5], sh->regs.R[6], sh->regs.PR); - - // Fill in status variables - ret = GetDeviceStats(sh->regs.R[4], &size, &addr, &blocksize); - - // Make sure there's a proper header, and return if there's any other errors - if (ret == 1 || CheckHeader(sh->regs.R[4]) != 0) - { - // Error - sh->regs.R[0] = ret; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - freeblocks = GetFreeSpace(sh->regs.R[4], size, addr, blocksize); - - MappedMemoryWriteLong(sh->regs.R[6], size); // Size of Backup Ram (in bytes) - MappedMemoryWriteLong(sh->regs.R[6]+0x4, size / blocksize); // Size of Backup Ram (in blocks) - MappedMemoryWriteLong(sh->regs.R[6]+0x8, blocksize); // Size of block - MappedMemoryWriteLong(sh->regs.R[6]+0xC, ((blocksize - 6) * freeblocks) - 30); // Free space(in bytes) - MappedMemoryWriteLong(sh->regs.R[6]+0x10, freeblocks); // Free space(in blocks) - MappedMemoryWriteLong(sh->regs.R[6]+0x14, freeblocks); // Not sure, but seems to be the same as Free Space(in blocks) - - // cycles need to be incremented - - sh->regs.R[0] = ret; // returns 0 if there's no error - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPWrite(SH2_struct * sh) -{ - u32 size; - u32 addr; - u32 blocksize; - u32 block; - u32 ret; - u32 savesize; - u16 *blocktbl; - u32 workaddr; - u32 blockswritten=0; - u32 datasize; - u32 i; - - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosBUPWrite. arg1 = %d, arg2 = %08X, arg3 = %08X, arg4 = %d, PR = %08X\n", sh->regs.R[4], sh->regs.R[5], sh->regs.R[6], sh->regs.R[7], sh->regs.PR); - - // Fill in status variables - ret = GetDeviceStats(sh->regs.R[4], &size, &addr, &blocksize); - if (ret == 1) - { - // Error - sh->regs.R[0] = ret; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // See if save exists already - if ((block = FindSave(sh->regs.R[4], sh->regs.R[5], 2, size, addr, blocksize)) != 0) - { - // save exists - - // Should we be overwriting it? - if (sh->regs.R[7] != 0) - { - // Nope, let's bail instead - sh->regs.R[0] = 6; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // Delete old save - DeleteSave(addr, block, blocksize); - } - - // Let's figure out how many blocks will be needed for the save - datasize = MappedMemoryReadLong(sh->regs.R[5]+0x1C); - savesize = (datasize + 0x1D) / (blocksize - 6); - if ((datasize + 0x1D) % (blocksize - 6)) - savesize++; - - // Will it blend? Err... fit - if (savesize > GetFreeSpace(sh->regs.R[4], size, addr, blocksize)) - { - // Nope, time to bail - sh->regs.R[0] = 4; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // Find free blocks for the save - if ((blocktbl = GetFreeBlocks(addr, blocksize, savesize, size)) == NULL) - { - // Just return an error that might make sense - sh->regs.R[0] = 8; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // Create save - workaddr = addr + (blocktbl[0] * blocksize * 2); - - MappedMemoryWriteByte(workaddr+0x1, 0x80); - - // Copy over filename - for (i = workaddr+0x9; i < ((workaddr+0x9) + (11 * 2)); i+=2) - { - MappedMemoryWriteByte(i, MappedMemoryReadByte(sh->regs.R[5])); - sh->regs.R[5]++; - } - - sh->regs.R[5]++; - - // Copy over comment - for (i = workaddr+0x21; i < ((workaddr+0x21) + (10 * 2)); i+=2) - { - MappedMemoryWriteByte(i, MappedMemoryReadByte(sh->regs.R[5])); - sh->regs.R[5]++; - } - - // Copy over language - MappedMemoryWriteByte(workaddr+0x1F, MappedMemoryReadByte(sh->regs.R[5])); - sh->regs.R[5]++; - - sh->regs.R[5]++; - - // Copy over date - for (i = workaddr+0x35; i < ((workaddr+0x35) + (4 * 2)); i+=2) - { - MappedMemoryWriteByte(i, MappedMemoryReadByte(sh->regs.R[5])); - sh->regs.R[5]++; - } - - // Copy over data size - for (i = workaddr+0x3D; i < ((workaddr+0x3D) + (4 * 2)); i+=2) - { - MappedMemoryWriteByte(i, MappedMemoryReadByte(sh->regs.R[5])); - sh->regs.R[5]++; - } - - // write the block table - workaddr += 0x45; - - for (i = 1; i < savesize; i++) - { - MappedMemoryWriteByte(workaddr, (u8)(blocktbl[i] >> 8)); - workaddr+=2; - MappedMemoryWriteByte(workaddr, (u8)blocktbl[i]); - workaddr+=2; - - if (((workaddr-1) & ((blocksize << 1) - 1)) == 0) - { - // Next block - blockswritten++; - workaddr = addr + (blocktbl[blockswritten] * blocksize * 2) + 9; - } - } - - // Write 2 blank bytes so we now how large the table size is next time - MappedMemoryWriteByte(workaddr, 0); - workaddr+=2; - MappedMemoryWriteByte(workaddr, 0); - workaddr+=2; - - // Lastly, write the actual save data - while (datasize > 0) - { - MappedMemoryWriteByte(workaddr, MappedMemoryReadByte(sh->regs.R[6])); - datasize--; - sh->regs.R[6]++; - workaddr+=2; - - if (((workaddr-1) & ((blocksize << 1) - 1)) == 0) - { - // Next block - blockswritten++; - workaddr = addr + (blocktbl[blockswritten] * blocksize * 2) + 9; - } - } - - free(blocktbl); - - sh->regs.R[0] = 0; // returns 0 if there's no error - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPRead(SH2_struct * sh) -{ - u32 size; - u32 addr; - u32 blocksize; - u32 block; - u32 ret; - u32 tableaddr; - u16 *blocktbl; - int numblocks; - int blocksread; - u32 datasize; - - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosBUPRead\n", sh->regs.PR); - - ret = GetDeviceStats(sh->regs.R[4], &size, &addr, &blocksize); - - if (ret == 1) - { - // Error - sh->regs.R[0] = ret; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // See if save exists - if ((block = FindSave(sh->regs.R[4], sh->regs.R[5], 2, size, addr, blocksize)) == 0) - { - // save doesn't exist - sh->regs.R[0] = 5; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - tableaddr = addr + (block * blocksize * 2) + 0x3D; - datasize = (MappedMemoryReadByte(tableaddr) << 24) | (MappedMemoryReadByte(tableaddr + 2) << 16) | - (MappedMemoryReadByte(tableaddr+4) << 8) | MappedMemoryReadByte(tableaddr + 6); - - // Read in Block Table - if ((blocktbl = ReadBlockTable(addr, &tableaddr, block, blocksize, &numblocks, &blocksread)) == NULL) - { - // Just return an error that might make sense - sh->regs.R[0] = 8; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // Now let's read in the data - while (datasize > 0) - { - MappedMemoryWriteByte(sh->regs.R[6], MappedMemoryReadByte(tableaddr)); - datasize--; - sh->regs.R[6]++; - tableaddr+=2; - - if (((tableaddr-1) & ((blocksize << 1) - 1)) == 0) - { - // Load up the next block - tableaddr = addr + (blocktbl[blocksread] * blocksize * 2) + 9; - blocksread++; - } - } - - free(blocktbl); - - sh->regs.R[0] = 0; // returns 0 if there's no error - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPDelete(SH2_struct * sh) -{ - u32 size; - u32 addr; - u32 blocksize; - u32 block; - u32 ret; - - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosBUPDelete. PR = %08X\n", sh->regs.PR); - - // Fill in status variables - ret = GetDeviceStats(sh->regs.R[4], &size, &addr, &blocksize); - if (ret == 1) - { - // Error - sh->regs.R[0] = ret; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // See if save exists - if ((block = FindSave(sh->regs.R[4], sh->regs.R[5], 2, size, addr, blocksize)) == 0) - { - // Since the save doesn't exist, let's bail with an error - - sh->regs.R[0] = 5; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - DeleteSave(addr, block, blocksize); - - sh->regs.R[0] = 0; // returns 0 if there's no error - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPDirectory(SH2_struct * sh) -{ - u32 size; - u32 addr; - u32 blocksize; - u32 ret; - u32 i; - char filename[12]; - u32 blockoffset=2; - - SH2GetRegisters(sh, &sh->regs); - -// int findmatch = MappedMemoryReadByte(sh->regs.R[5]); - - for (i = 0; i < 12; i++) - filename[i] = MappedMemoryReadByte(sh->regs.R[5]+i); - - LOG("BiosBUPDirectory. arg1 = %d, arg2 = %s, arg3 = %08X, arg4 = %08X, PR = %08X\n", sh->regs.R[4], filename, sh->regs.R[6], sh->regs.R[7], sh->regs.PR); - - ret = GetDeviceStats(sh->regs.R[4], &size, &addr, &blocksize); - - if (ret == 1) - { - // Error - sh->regs.R[0] = ret; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - for (i = 0; i < sh->regs.R[6]; i++) - { - u32 i4; - u32 datasize=0; - u32 block = FindSave(sh->regs.R[4], sh->regs.R[5], blockoffset, size, addr, blocksize); - - if (block == 0) - break; - - blockoffset = block+1; - - // Alright, we found a match :) Time to copy over some data - block = addr + (blocksize * block * 2); - - // Copy over filename - for (i4 = block+0x9; i4 < ((block+0x9) + (11 * 2)); i4+=2) - { - MappedMemoryWriteByte(sh->regs.R[7], MappedMemoryReadByte(i4)); - sh->regs.R[7]++; - } - MappedMemoryWriteByte(sh->regs.R[7], 0); - sh->regs.R[7]++; - - // Copy over comment - for (i4 = block+0x21; i4 < ((block+0x21) + (10 * 2)); i4+=2) - { - MappedMemoryWriteByte(sh->regs.R[7], MappedMemoryReadByte(i4)); - sh->regs.R[7]++; - } - - // Copy over language - MappedMemoryWriteByte(sh->regs.R[7], MappedMemoryReadByte(block+0x1F)); - sh->regs.R[7]++; - - MappedMemoryWriteByte(sh->regs.R[7], 0); - sh->regs.R[7]++; - - // Copy over date - for (i4 = block+0x35; i4 < ((block+0x35) + (4 * 2)); i4+=2) - { - MappedMemoryWriteByte(sh->regs.R[7], MappedMemoryReadByte(i4)); - sh->regs.R[7]++; - } - - // Copy over data size - for (i4 = block+0x3D; i4 < ((block+0x3D) + (4 * 2)); i4+=2) - { - u8 data; - datasize <<= 8; - data = MappedMemoryReadByte(i4); - MappedMemoryWriteByte(sh->regs.R[7], data); - datasize |= data; - sh->regs.R[7]++; - } - - // Calculate block size from the data size, and then copy it over - MappedMemoryWriteWord(sh->regs.R[7], (u16)(((datasize + 0x1D) / (blocksize - 6)) + 1)); - sh->regs.R[7] += 4; - } - - sh->regs.R[0] = i; // returns the number of successfully read dir entries - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPVerify(SH2_struct * sh) -{ - u32 size; - u32 addr; - u32 blocksize; - u32 block; - u32 ret; - u32 tableaddr; - u32 datasize; - u16 *blocktbl; - int numblocks; - int blocksread; - - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosBUPVerify. PR = %08X\n", sh->regs.PR); - - ret = GetDeviceStats(sh->regs.R[4], &size, &addr, &blocksize); - - if (ret == 1) - { - // Error - sh->regs.R[0] = ret; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // See if save exists - if ((block = FindSave(sh->regs.R[4], sh->regs.R[5], 2, size, addr, blocksize)) == 0) - { - // Since the save doesn't exist, let's bail with an error - sh->regs.R[0] = 5; // Not found - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - tableaddr = addr + (block * blocksize * 2) + 0x3D; - datasize = (MappedMemoryReadByte(tableaddr) << 24) | (MappedMemoryReadByte(tableaddr + 2) << 16) | - (MappedMemoryReadByte(tableaddr+4) << 8) | MappedMemoryReadByte(tableaddr + 6); - - // Read in Block Table - if ((blocktbl = ReadBlockTable(addr, &tableaddr, block, blocksize, &numblocks, &blocksread)) == NULL) - { - // Just return an error that might make sense - sh->regs.R[0] = 8; // Broken - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - // Now let's read in the data, and check to see if it matches - while (datasize > 0) - { - if (MappedMemoryReadByte(sh->regs.R[6]) != MappedMemoryReadByte(tableaddr)) - { - free(blocktbl); - // Ok, the data doesn't match - sh->regs.R[0] = 7; // No match - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); - return; - } - - datasize--; - sh->regs.R[6]++; - tableaddr+=2; - - if (((tableaddr-1) & ((blocksize << 1) - 1)) == 0) - { - // Load up the next block - tableaddr = addr + (blocktbl[blocksread] * blocksize * 2) + 9; - blocksread++; - } - } - - free(blocktbl); - - sh->regs.R[0] = 0; // returns 0 if there's no error - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void ConvertMonthAndDay(u32 data, u32 monthaddr, u32 dayaddr, int type) -{ - int i; - u16 monthtbl[11] = { 31, 31+28, 31+28+31, 31+28+31+30, 31+28+31+30+31, - 31+28+31+30+31+30, 31+28+31+30+31+30+31, - 31+28+31+30+31+30+31+31, 31+28+31+30+31+30+31+31+30, - 31+28+31+30+31+30+31+31+30+31, - 31+28+31+30+31+30+31+31+30+31+30 }; - - if (data < monthtbl[0]) - { - // Month - MappedMemoryWriteByte(monthaddr, 1); - - // Day - MappedMemoryWriteByte(dayaddr, (u8)(data + 1)); - return; - } - - for (i = 1; i < 11; i++) - { - if (data <= monthtbl[i]) - break; - } - - if (type == 1) - { - // Month - MappedMemoryWriteByte(monthaddr, (u8)(i + 1)); - - // Day - if ((i + 1) == 2) - MappedMemoryWriteByte(dayaddr, (u8)(data - monthtbl[(i - 1)] + 1)); - else - MappedMemoryWriteByte(dayaddr, (u8)(data - monthtbl[(i - 1)])); - } - else - { - // Month - MappedMemoryWriteByte(monthaddr, (u8)(i + 1)); - - // Day - MappedMemoryWriteByte(dayaddr, (u8)(data - monthtbl[(i - 1)] + 1)); - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPGetDate(SH2_struct * sh) -{ - u32 date; - u32 div; - u32 yearoffset; - u32 yearremainder; - - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosBUPGetDate. PR = %08X\n", sh->regs.PR); - - date = sh->regs.R[4]; - - // Time - MappedMemoryWriteByte(sh->regs.R[5]+3, (u8)((date % 0x5A0) / 0x3C)); - - // Minute - MappedMemoryWriteByte(sh->regs.R[5]+4, (u8)(date % 0x3C)); - - div = date / 0x5A0; - - // Week - if (div > 0xAB71) - MappedMemoryWriteByte(sh->regs.R[5]+5, (u8)((div + 1) % 7)); - else - MappedMemoryWriteByte(sh->regs.R[5]+5, (u8)((div + 2) % 7)); - - yearremainder = div % 0x5B5; - - if (yearremainder > 0x16E) - { - yearoffset = (yearremainder - 1) / 0x16D; - ConvertMonthAndDay((yearremainder - 1) % 0x16D, sh->regs.R[5]+1, sh->regs.R[5]+2, 0); - } - else - { - yearoffset = 0; - ConvertMonthAndDay(0, sh->regs.R[5]+1, sh->regs.R[5]+2, 1); - } - - // Year - MappedMemoryWriteByte(sh->regs.R[5], (u8)(((div / 0x5B5) * 4) + yearoffset)); - - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosBUPSetDate(SH2_struct * sh) -{ - u32 date; - u8 data; - u32 remainder; - u16 monthtbl[11] = { 31, 31+28, 31+28+31, 31+28+31+30, 31+28+31+30+31, - 31+28+31+30+31+30, 31+28+31+30+31+30+31, - 31+28+31+30+31+30+31+31, 31+28+31+30+31+30+31+31+30, - 31+28+31+30+31+30+31+31+30+31, - 31+28+31+30+31+30+31+31+30+31+30 }; - - SH2GetRegisters(sh, &sh->regs); - - LOG("BiosBUPSetDate. PR = %08X\n", sh->regs.PR); - - // Year - data = MappedMemoryReadByte(sh->regs.R[4]); - date = (data / 4) * 0x5B5; - remainder = data % 4; - if (remainder) - date += (remainder * 0x16D) + 1; - - // Month - data = MappedMemoryReadByte(sh->regs.R[4]+1); - if (data != 1 && data < 13) - { - date += monthtbl[data - 2]; - if (date > 2 && remainder == 0) - date++; - } - - // Day - date += MappedMemoryReadByte(sh->regs.R[4]+2) - 1; - date *= 0x5A0; - - // Hour - date += (MappedMemoryReadByte(sh->regs.R[4]+3) * 0x3C); - - // Minute - date += MappedMemoryReadByte(sh->regs.R[4]+4); - - sh->regs.R[0] = date; - sh->regs.PC = sh->regs.PR; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosHandleScuInterrupt(SH2_struct * sh, int vector) -{ - SH2GetRegisters(sh, &sh->regs); - - // Save R0-R7, PR, GBR, and old Interrupt mask to stack - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.R[0]); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.R[1]); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.R[2]); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.R[3]); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], MappedMemoryReadLong(0x06000348)); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.R[4]); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.R[5]); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.R[6]); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.R[7]); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.PR); - sh->regs.R[15] -= 4; - MappedMemoryWriteLong(sh->regs.R[15], sh->regs.GBR); - - // Set SR according to vector - sh->regs.SR.all = (u32)sh2masklist[vector - 0x40]; - - // Write new Interrupt mask value - MappedMemoryWriteLong(0x06000348, MappedMemoryReadLong(0x06000348) | scumasklist[vector - 0x40]); - MappedMemoryWriteLong(0x25FE00A0, MappedMemoryReadLong(0x06000348) | scumasklist[vector - 0x40]); - - // Set PR to our Interrupt Return handler - sh->regs.PR = 0x00000480; - - // Now execute the interrupt - sh->regs.PC = MappedMemoryReadLong(0x06000900+(vector << 2)); -// LOG("Interrupt PC = %08X. Read from %08X\n", sh->regs.PC, 0x06000900+(vector << 2)); - - sh->cycles += 33; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosHandleScuInterruptReturn(SH2_struct * sh) -{ - u32 oldmask; - - SH2GetRegisters(sh, &sh->regs); - - // Restore R0-R7, PR, GBR, and old Interrupt mask from stack - sh->regs.GBR = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.PR = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.R[7] = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.R[6] = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.R[5] = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.R[4] = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - // Return SR back to normal - sh->regs.SR.all = 0xF0; - oldmask = MappedMemoryReadLong(sh->regs.R[15]); - MappedMemoryWriteLong(0x06000348, oldmask); - MappedMemoryWriteLong(0x25FE00A0, oldmask); - sh->regs.R[15] += 4; - sh->regs.R[3] = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.R[2] = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.R[1] = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.R[0] = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - - sh->regs.PC = MappedMemoryReadLong(sh->regs.R[15]); - sh->regs.R[15] += 4; - sh->regs.SR.all = MappedMemoryReadLong(sh->regs.R[15]) & 0x000003F3; - sh->regs.R[15] += 4; - - sh->cycles += 24; - SH2SetRegisters(sh, &sh->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -int FASTCALL BiosHandleFunc(SH2_struct * sh) -{ - SH2GetRegisters(sh, &sh->regs); - - // Let's see if it's a bios function - switch((sh->regs.PC - 0x200) >> 2) - { - case 0x04: // 0x06000210 - BiosPowerOnMemoryClear(sh); - break; - case 0x1B: // 0x0600026C - BiosExecuteCDPlayer(sh); - break; - case 0x1D: // 0x06000274 - BiosCheckMPEGCard(sh); - break; - case 0x20: // 0x06000280 - BiosChangeScuInterruptPriority(sh); - break; - case 0x27: // 0x0600029C - BiosCDINIT2(sh); - break; - case 0x37: // 0x060002DC - BiosCDINIT1(sh); - break; - case 0x40: // 0x06000300 - BiosSetScuInterrupt(sh); - break; - case 0x41: // 0x06000304 - BiosGetScuInterrupt(sh); - break; - case 0x44: // 0x06000310 - BiosSetSh2Interrupt(sh); - break; - case 0x45: // 0x06000314 - BiosGetSh2Interrupt(sh); - break; - case 0x48: // 0x06000320 - BiosChangeSystemClock(sh); - break; - case 0x4C: // 0x06000330 - BiosGetSemaphore(sh); - break; - case 0x4D: // 0x06000334 - BiosClearSemaphore(sh); - break; - case 0x50: // 0x06000340 - BiosSetScuInterruptMask(sh); - break; - case 0x51: // 0x06000344 - BiosChangeScuInterruptMask(sh); - break; - case 0x56: // 0x06000358 - BiosBUPInit(sh); - break; - case 0x60: // 0x06000380 - break; - case 0x61: // 0x06000384 - BiosBUPSelectPartition(sh); - break; - case 0x62: // 0x06000388 - BiosBUPFormat(sh); - break; - case 0x63: // 0x0600038C - BiosBUPStatus(sh); - break; - case 0x64: // 0x06000390 - BiosBUPWrite(sh); - break; - case 0x65: // 0x06000394 - BiosBUPRead(sh); - break; - case 0x66: // 0x06000398 - BiosBUPDelete(sh); - break; - case 0x67: // 0x0600039C - BiosBUPDirectory(sh); - break; - case 0x68: // 0x060003A0 - BiosBUPVerify(sh); - break; - case 0x69: // 0x060003A4 - BiosBUPGetDate(sh); - break; - case 0x6A: // 0x060003A8 - BiosBUPSetDate(sh); - break; - case 0x6B: // 0x060003AC - break; - case 0x80: // Interrupt Handler - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: - case 0x86: - case 0x87: - case 0x88: - case 0x89: - case 0x8A: - case 0x8B: - case 0x8C: - case 0x8D: - case 0x90: - case 0x91: - case 0x92: - case 0x93: - case 0x94: - case 0x95: - case 0x96: - case 0x97: - case 0x98: - case 0x99: - case 0x9A: - case 0x9B: - case 0x9C: - case 0x9D: - case 0x9E: - case 0x9F: - BiosHandleScuInterrupt(sh, (sh->regs.PC - 0x300) >> 2); - break; - case 0xA0: // Interrupt Handler Return - BiosHandleScuInterruptReturn(sh); - break; - default: - return 0; - } - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -deviceinfo_struct *BupGetDeviceList(int *numdevices) -{ - deviceinfo_struct *device; - int devicecount=1; - - if ((CartridgeArea->cartid & 0xF0) == 0x20) - devicecount++; - - if ((device = (deviceinfo_struct *)malloc(devicecount * sizeof(deviceinfo_struct))) == NULL) - { - *numdevices = 0; - return NULL; - } - - *numdevices = devicecount; - - device[0].id = 0; - sprintf(device[0].name, "Internal Backup RAM"); - - if ((CartridgeArea->cartid & 0xF0) == 0x20) - { - device[1].id = 1; - sprintf(device[1].name, "%d Mbit Backup RAM Cartridge", 1 << ((CartridgeArea->cartid & 0xF)+1)); - } - - // For now it's only internal backup ram and cartridge, no floppy :( -// device[2].id = 2; -// sprintf(device[1].name, "Floppy Disk Drive"); - - return device; -} - -////////////////////////////////////////////////////////////////////////////// - -int BupGetStats(u32 device, u32 *freespace, u32 *maxspace) -{ - u32 ret; - u32 size; - u32 addr; - u32 blocksize; - - ret = GetDeviceStats(device, &size, &addr, &blocksize); - - // Make sure there's a proper header, and return if there's any other errors - if (ret == 1 || CheckHeader(device) != 0) - return 0; - - *maxspace = size / blocksize; - *freespace = GetFreeSpace(device, size, addr, blocksize); - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -saveinfo_struct *BupGetSaveList(u32 device, int *numsaves) -{ - u32 ret; - u32 size; - u32 addr; - u32 blocksize; - saveinfo_struct *save; - int savecount=0; - u32 i, j; - u32 workaddr; - - ret = GetDeviceStats(device, &size, &addr, &blocksize); - - // Make sure there's a proper header, and return if there's any other errors - if (ret == 1 || CheckHeader(device) != 0) - { - *numsaves = 0; - return NULL; - } - - for (i = ((2 * blocksize) << 1); i < (size << 1); i += (blocksize << 1)) - { - // Find a block with the start of a save - if (((s8)MappedMemoryReadByte(addr + i + 1)) < 0) - savecount++; - } - - if ((save = (saveinfo_struct *)malloc(savecount * sizeof(saveinfo_struct))) == NULL) - { - *numsaves = 0; - return NULL; - } - - *numsaves = savecount; - - savecount = 0; - - for (i = ((2 * blocksize) << 1); i < (size << 1); i += (blocksize << 1)) - { - // Find a block with the start of a save - if (((s8)MappedMemoryReadByte(addr + i + 1)) < 0) - { - workaddr = addr + i; - - // Copy over filename - for (j = 0; j < 11; j++) - save[savecount].filename[j] = MappedMemoryReadByte(workaddr+0x9+(j * 2)); - save[savecount].filename[11] = '\0'; - - // Copy over comment - for (j = 0; j < 10; j++) - save[savecount].comment[j] = MappedMemoryReadByte(workaddr+0x21+(j * 2)); - save[savecount].comment[10] = '\0'; - - // Copy over language - save[savecount].language = MappedMemoryReadByte(workaddr+0x1F); - - // Copy over Date(fix me) - save[savecount].year = 0; - save[savecount].month = 0; - save[savecount].day = 0; - save[savecount].hour = 0; - save[savecount].minute = 0; - save[savecount].week = 0; - - // Copy over data size - save[savecount].datasize = (MappedMemoryReadByte(workaddr+0x3D) << 24) | - (MappedMemoryReadByte(workaddr+0x3F) << 16) | - (MappedMemoryReadByte(workaddr+0x41) << 8) | - MappedMemoryReadByte(workaddr+0x43); - - // Calculate size in blocks - save[savecount].blocksize = CalcSaveSize(workaddr+0x45, blocksize) + 1; - savecount++; - } - } - - return save; -} - -////////////////////////////////////////////////////////////////////////////// - -int BupDeleteSave(u32 device, const char *savename) -{ - u32 ret; - u32 size; - u32 addr; - u32 blocksize; - u32 block; - - ret = GetDeviceStats(device, &size, &addr, &blocksize); - - // Make sure there's a proper header, and return if there's any other errors - if (ret == 1 || CheckHeader(device) != 0) - return -1; - - // Let's find and delete the save game - if ((block = FindSave2(device, savename, 2, size, addr, blocksize)) != 0) - { - // Delete old save - DeleteSave(addr, block, blocksize); - return 0; - } - - return -2; -} - -////////////////////////////////////////////////////////////////////////////// - -void BupFormat(u32 device) -{ - switch (device) - { - case 0: - FormatBackupRam(BupRam, 0x10000); - break; - case 1: - if ((CartridgeArea->cartid & 0xF0) == 0x20) - { - switch (CartridgeArea->cartid & 0xF) - { - case 1: - FormatBackupRam(CartridgeArea->bupram, 0x100000); - break; - case 2: - FormatBackupRam(CartridgeArea->bupram, 0x200000); - break; - case 3: - FormatBackupRam(CartridgeArea->bupram, 0x400000); - break; - case 4: - FormatBackupRam(CartridgeArea->bupram, 0x800000); - break; - default: break; - } - } - break; - case 2: - LOG("Formatting FDD not supported\n"); - default: break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -int BupCopySave(UNUSED u32 srcdevice, UNUSED u32 dstdevice, UNUSED const char *savename) -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int BupImportSave(UNUSED u32 device, const char *filename) -{ - FILE *fp; - u32 filesize; - u8 *buffer; - - if (!filename) - return -1; - - if ((fp = fopen(filename, "rb")) == NULL) - return -1; - - // Calculate file size - fseek(fp, 0, SEEK_END); - filesize = ftell(fp); - fseek(fp, 0, SEEK_SET); - - if ((buffer = (u8 *)malloc(filesize)) == NULL) - { - fclose(fp); - return -2; - } - - fread((void *)buffer, 1, filesize, fp); - fclose(fp); - - // Write save here - - free(buffer); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int BupExportSave(UNUSED u32 device, UNUSED const char *savename, UNUSED const char *filename) -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - diff --git a/yabause/src/bios.h b/yabause/src/bios.h deleted file mode 100644 index fbf21dca61..0000000000 --- a/yabause/src/bios.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright 2006 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef BIOS_H -#define BIOS_H - -#include "sh2core.h" - -typedef struct -{ - char filename[12]; - char comment[11]; - u8 language; - u8 year; - u8 month; - u8 day; - u8 hour; - u8 minute; - u8 week; - u32 datasize; - u16 blocksize; -} saveinfo_struct; - -typedef struct -{ - u8 id; - char name[32]; -} deviceinfo_struct; - -void BiosInit(void); -int FASTCALL BiosHandleFunc(SH2_struct * sh); - -deviceinfo_struct *BupGetDeviceList(int *numdevices); -int BupGetStats(u32 device, u32 *freespace, u32 *maxspace); -saveinfo_struct *BupGetSaveList(u32 device, int *numsaves); -int BupDeleteSave(u32 device, const char *savename); -void BupFormat(u32 device); -int BupCopySave(u32 srcdevice, u32 dstdevice, const char *savename); -int BupImportSave(u32 device, const char *filename); -int BupExportSave(u32 device, const char *savename, const char *filename); -#endif - diff --git a/yabause/src/c68k/CMakeLists.txt b/yabause/src/c68k/CMakeLists.txt deleted file mode 100644 index 6267fd8de1..0000000000 --- a/yabause/src/c68k/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -project(gen68k) - -cmake_minimum_required(VERSION 2.6) - -include(CheckCSourceCompiles) - -# variadic macros -check_c_source_compiles("#define MACRO(...) puts(__VA_ARGS__) - int main(int argc, char ** argv) { MACRO(\"foo\"); }" - VARIADIC_MACROS_OK) -if (VARIADIC_MACROS_OK) - add_definitions(-DHAVE_C99_VARIADIC_MACROS=1) -endif (VARIADIC_MACROS_OK) - -set(gen68k_SOURCES c68kexec.c c68k.c gen68k.c) - -add_definitions(-DC68K_GEN) -if (MSVC) - add_definitions(-DC68K_NO_JUMP_TABLE) -endif (MSVC) - -add_executable(gen68k ${gen68k_SOURCES}) - -execute_process(COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gen68k) - -set(GEN68K_INC c68k_ini.inc c68k_op0.inc c68k_op1.inc c68k_op2.inc c68k_op3.inc c68k_op4.inc c68k_op5.inc c68k_op6.inc c68k_op7.inc c68k_op8.inc c68k_op9.inc c68k_opA.inc c68k_opB.inc c68k_opC.inc c68k_opD.inc c68k_opE.inc c68k_opF.inc) - -add_custom_command(OUTPUT ${GEN68K_INC} COMMAND gen68k DEPENDS gen68k) - -add_custom_target(c68kinc ALL DEPENDS ${GEN68K_INC}) diff --git a/yabause/src/c68k/Makefile.am b/yabause/src/c68k/Makefile.am deleted file mode 100644 index f4519b2048..0000000000 --- a/yabause/src/c68k/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -EXTRA_DIST = c68k.h c68kmac.inc gen68k.h gen68k.inc -noinst_PROGRAMS = gen68k -gen68k_SOURCES = c68kexec.c c68k.c gen68k.c -gen68k_CFLAGS = -DC68K_GEN -gen68k_LDFLAGS = -DC68K_GEN - -all-local: gen68k$(EXEEXT) - ./gen68k$(EXEEXT) - -clean-local: - -rm *_*.inc diff --git a/yabause/src/c68k/c68k.c b/yabause/src/c68k/c68k.c deleted file mode 100644 index eb77fb4605..0000000000 --- a/yabause/src/c68k/c68k.c +++ /dev/null @@ -1,311 +0,0 @@ -/* Copyright 2003-2004 Stephane Dallongeville - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/********************************************************************************* - * - * C68K (68000 CPU emulator) version 0.80 - * Compiled with Dev-C++ - * Copyright 2003-2004 Stephane Dallongeville - * - ********************************************************************************/ - -#include -#include - -#include "c68k.h" - -// shared global variable -////////////////////////// - -c68k_struc C68K; - -// include macro file -////////////////////// - -#include "c68kmac.inc" - -// prototype -///////////// - -u32 FASTCALL C68k_Read_Dummy(const u32 adr); -void FASTCALL C68k_Write_Dummy(const u32 adr, u32 data); - -u32 C68k_Read_Byte(c68k_struc *cpu, u32 adr); -u32 C68k_Read_Word(c68k_struc *cpu, u32 adr); -u32 C68k_Read_Long(c68k_struc *cpu, u32 adr); -void C68k_Write_Byte(c68k_struc *cpu, u32 adr, u32 data); -void C68k_Write_Word(c68k_struc *cpu, u32 adr, u32 data); -void C68k_Write_Long(c68k_struc *cpu, u32 adr, u32 data); - -s32 FASTCALL C68k_Interrupt_Ack_Dummy(s32 level); -void FASTCALL C68k_Reset_Dummy(void); - -// core main functions -/////////////////////// - -void C68k_Init(c68k_struc *cpu, C68K_INT_CALLBACK *int_cb) -{ - memset(cpu, 0, sizeof(c68k_struc)); - - C68k_Set_ReadB(cpu, C68k_Read_Dummy); - C68k_Set_ReadW(cpu, C68k_Read_Dummy); - - C68k_Set_WriteB(cpu, C68k_Write_Dummy); - C68k_Set_WriteW(cpu, C68k_Write_Dummy); - - if (int_cb) cpu->Interrupt_CallBack = int_cb; - else cpu->Interrupt_CallBack = C68k_Interrupt_Ack_Dummy; - cpu->Reset_CallBack = C68k_Reset_Dummy; - - // used to init JumpTable - cpu->Status |= C68K_DISABLE; - C68k_Exec(cpu, 0); - - cpu->Status &= ~C68K_DISABLE; -} - -s32 FASTCALL C68k_Reset(c68k_struc *cpu) -{ - memset(cpu, 0, ((u8 *)&(cpu->dirty1)) - ((u8 *)&(cpu->D[0]))); - - cpu->flag_notZ = 1; - cpu->flag_I = 7; - cpu->flag_S = C68K_SR_S; - - cpu->A[7] = C68k_Read_Long(cpu, 0); - C68k_Set_PC(cpu, C68k_Read_Long(cpu, 4)); - - return cpu->Status; -} - -///////////////////////////////// - -void FASTCALL C68k_Set_IRQ(c68k_struc *cpu, s32 level) -{ - cpu->IRQLine = level; - if (cpu->Status & C68K_RUNNING) - { - cpu->CycleSup = cpu->CycleIO; - cpu->CycleIO = 0; - } - cpu->Status &= ~(C68K_HALTED | C68K_WAITING); -} - -///////////////////////////////// - -s32 FASTCALL C68k_Get_CycleToDo(c68k_struc *cpu) -{ - if (!(cpu->Status & C68K_RUNNING)) return -1; - - return cpu->CycleToDo; -} - -s32 FASTCALL C68k_Get_CycleRemaining(c68k_struc *cpu) -{ - if (!(cpu->Status & C68K_RUNNING)) return -1; - - return (cpu->CycleIO + cpu->CycleSup); -} - -s32 FASTCALL C68k_Get_CycleDone(c68k_struc *cpu) -{ - if (!(cpu->Status & C68K_RUNNING)) return -1; - - return (cpu->CycleToDo - (cpu->CycleIO + cpu->CycleSup)); -} - -void FASTCALL C68k_Release_Cycle(c68k_struc *cpu) -{ - if (cpu->Status & C68K_RUNNING) cpu->CycleIO = cpu->CycleSup = 0; -} - -void FASTCALL C68k_Add_Cycle(c68k_struc *cpu, s32 cycle) -{ - if (cpu->Status & C68K_RUNNING) cpu->CycleIO -= cycle; -} - -// Read / Write dummy functions -//////////////////////////////// - -u32 FASTCALL C68k_Read_Dummy(UNUSED const u32 adr) -{ - return 0; -} - -void FASTCALL C68k_Write_Dummy(UNUSED const u32 adr, UNUSED u32 data) -{ - -} - -s32 FASTCALL C68k_Interrupt_Ack_Dummy(s32 level) -{ - // return vector - return (C68K_INTERRUPT_AUTOVECTOR_EX + level); -} - -void FASTCALL C68k_Reset_Dummy(void) -{ - -} - -// Read / Write core functions -/////////////////////////////// - -u32 C68k_Read_Byte(c68k_struc *cpu, u32 adr) -{ - return cpu->Read_Byte(adr); -} - -u32 C68k_Read_Word(c68k_struc *cpu, u32 adr) -{ - return cpu->Read_Word(adr); -} - -u32 C68k_Read_Long(c68k_struc *cpu, u32 adr) -{ -#ifdef C68K_BIG_ENDIAN - return (cpu->Read_Word(adr) << 16) | (cpu->Read_Word(adr + 2) & 0xFFFF); -#else - return (cpu->Read_Word(adr) << 16) | (cpu->Read_Word(adr + 2) & 0xFFFF); -#endif -} - -void C68k_Write_Byte(c68k_struc *cpu, u32 adr, u32 data) -{ - cpu->Write_Byte(adr, data); -} - -void C68k_Write_Word(c68k_struc *cpu, u32 adr, u32 data) -{ - cpu->Write_Word(adr, data); -} - -void C68k_Write_Long(c68k_struc *cpu, u32 adr, u32 data) -{ -#ifdef C68K_BIG_ENDIAN - cpu->Write_Word(adr, data >> 16); - cpu->Write_Word(adr + 2, data & 0xFFFF); -#else - cpu->Write_Word(adr, data >> 16); - cpu->Write_Word(adr + 2, data & 0xFFFF); -#endif -} - -// setting core functions -////////////////////////// - -void C68k_Set_Fetch(c68k_struc *cpu, u32 low_adr, u32 high_adr, pointer fetch_adr) -{ - u32 i, j; - - i = (low_adr >> C68K_FETCH_SFT) & C68K_FETCH_MASK; - j = (high_adr >> C68K_FETCH_SFT) & C68K_FETCH_MASK; - fetch_adr -= i << C68K_FETCH_SFT; - while (i <= j) cpu->Fetch[i++] = fetch_adr; -} - -void C68k_Set_ReadB(c68k_struc *cpu, C68K_READ *Func) -{ - cpu->Read_Byte = Func; -} - -void C68k_Set_ReadW(c68k_struc *cpu, C68K_READ *Func) -{ - cpu->Read_Word = Func; -} - -void C68k_Set_WriteB(c68k_struc *cpu, C68K_WRITE *Func) -{ - cpu->Write_Byte = Func; -} - -void C68k_Set_WriteW(c68k_struc *cpu, C68K_WRITE *Func) -{ - cpu->Write_Word = Func; -} - -// externals main functions -//////////////////////////// - -u32 C68k_Get_DReg(c68k_struc *cpu, u32 num) -{ - return cpu->D[num]; -} - -u32 C68k_Get_AReg(c68k_struc *cpu, u32 num) -{ - return cpu->A[num]; -} - -u32 C68k_Get_PC(c68k_struc *cpu) -{ - return (cpu->PC - cpu->BasePC); -} - -u32 C68k_Get_SR(c68k_struc *cpu) -{ - c68k_struc *CPU = cpu; - return GET_SR; -} - -u32 C68k_Get_USP(c68k_struc *cpu) -{ - if (cpu->flag_S) return cpu->USP; - else return cpu->A[7]; -} - -u32 C68k_Get_MSP(c68k_struc *cpu) -{ - if (cpu->flag_S) return cpu->A[7]; - else return cpu->USP; -} - -void C68k_Set_DReg(c68k_struc *cpu, u32 num, u32 val) -{ - cpu->D[num] = val; -} - -void C68k_Set_AReg(c68k_struc *cpu, u32 num, u32 val) -{ - cpu->A[num] = val; -} - -void C68k_Set_PC(c68k_struc *cpu, u32 val) -{ - cpu->BasePC = cpu->Fetch[(val >> C68K_FETCH_SFT) & C68K_FETCH_MASK]; - cpu->PC = val + cpu->BasePC; -} - -void C68k_Set_SR(c68k_struc *cpu, u32 val) -{ - c68k_struc *CPU = cpu; - SET_SR(val); -} - -void C68k_Set_USP(c68k_struc *cpu, u32 val) -{ - if (cpu->flag_S) cpu->USP = val; - else cpu->A[7] = val; -} - -void C68k_Set_MSP(c68k_struc *cpu, u32 val) -{ - if (cpu->flag_S) cpu->A[7] = val; - else cpu->USP = val; -} diff --git a/yabause/src/c68k/c68k.h b/yabause/src/c68k/c68k.h deleted file mode 100644 index a8297f4494..0000000000 --- a/yabause/src/c68k/c68k.h +++ /dev/null @@ -1,213 +0,0 @@ -/* Copyright 2003-2004 Stephane Dallongeville - Copyright 2004 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/********************************************************************************* - * C68K.H : - * - * C68K include file - * - ********************************************************************************/ - -#ifndef _C68K_H_ -#define _C68K_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "../core.h" - -// setting -/////////// - -//#define NEOCD_HLE - -//#define C68K_GEN -#define C68K_BYTE_SWAP_OPT - -#ifdef WORDS_BIGENDIAN -#define C68K_BIG_ENDIAN -#endif - -#ifdef C68K_BIG_ENDIAN - #define BYTE_OFF 3 - #define WORD_OFF 1 -#else - #define BYTE_OFF 0 - #define WORD_OFF 0 -#endif - -//#define C68K_NO_JUMP_TABLE -//#define C68K_DEBUG -#define C68K_TAS_CAN_SET_MEMORY -//#define C68K_CONST_JUMP_TABLE -//#define C68K_AUTOVECTOR_CALLBACK - -// 68K core types definitions -////////////////////////////// - -#define C68K_FETCH_BITS 8 // [4-12] default = 8 -#define C68K_ADR_BITS 24 - -#define C68K_FETCH_SFT (C68K_ADR_BITS - C68K_FETCH_BITS) -#define C68K_FETCH_BANK (1 << C68K_FETCH_BITS) -#define C68K_FETCH_MASK (C68K_FETCH_BANK - 1) - -#define C68K_SR_C_SFT 8 -#define C68K_SR_V_SFT 7 -#define C68K_SR_Z_SFT 0 -#define C68K_SR_N_SFT 7 -#define C68K_SR_X_SFT 8 - -#define C68K_SR_S_SFT 13 - -#define C68K_SR_C (1 << C68K_SR_C_SFT) -#define C68K_SR_V (1 << C68K_SR_V_SFT) -#define C68K_SR_Z 0 -#define C68K_SR_N (1 << C68K_SR_N_SFT) -#define C68K_SR_X (1 << C68K_SR_X_SFT) - -#define C68K_SR_S (1 << C68K_SR_S_SFT) - -#define C68K_CCR_MASK 0x1F -#define C68K_SR_MASK (0x2700 | C68K_CCR_MASK) - -// exception defines taken from musashi core -#define C68K_RESET_EX 1 -#define C68K_BUS_ERROR_EX 2 -#define C68K_ADDRESS_ERROR_EX 3 -#define C68K_ILLEGAL_INSTRUCTION_EX 4 -#define C68K_ZERO_DIVIDE_EX 5 -#define C68K_CHK_EX 6 -#define C68K_TRAPV_EX 7 -#define C68K_PRIVILEGE_VIOLATION_EX 8 -#define C68K_TRACE_EX 9 -#define C68K_1010_EX 10 -#define C68K_1111_EX 11 -#define C68K_FORMAT_ERROR_EX 14 -#define C68K_UNINITIALIZED_INTERRUPT_EX 15 -#define C68K_SPURIOUS_INTERRUPT_EX 24 -#define C68K_INTERRUPT_AUTOVECTOR_EX 24 -#define C68K_TRAP_BASE_EX 32 - -#define C68K_INT_ACK_AUTOVECTOR -1 - -#define C68K_RUNNING 0x01 -#define C68K_HALTED 0x02 -#define C68K_WAITING 0x04 -#define C68K_DISABLE 0x10 -#define C68K_FAULTED 0x40 - -typedef u32 FASTCALL C68K_READ(const u32 adr); -typedef void FASTCALL C68K_WRITE(const u32 adr, u32 data); - -typedef s32 FASTCALL C68K_INT_CALLBACK(s32 level); -typedef void FASTCALL C68K_RESET_CALLBACK(void); - -typedef struct { - u32 D[8]; // 32 bytes aligned - u32 A[8]; // 16 bytes aligned - - u32 flag_C; // 32 bytes aligned - u32 flag_V; - u32 flag_notZ; - u32 flag_N; - - u32 flag_X; // 16 bytes aligned - u32 flag_I; - u32 flag_S; - - u32 USP; - - pointer PC; // 32 bytes aligned - pointer BasePC; - u32 Status; - s32 IRQLine; - - s32 CycleToDo; // 16 bytes aligned - s32 CycleIO; - s32 CycleSup; - u32 dirty1; - - C68K_READ *Read_Byte; // 32 bytes aligned - C68K_READ *Read_Word; - - C68K_WRITE *Write_Byte; - C68K_WRITE *Write_Word; - - C68K_INT_CALLBACK *Interrupt_CallBack; // 16 bytes aligned - C68K_RESET_CALLBACK *Reset_CallBack; - - pointer Fetch[C68K_FETCH_BANK]; // 32 bytes aligned -} c68k_struc; - - -// 68K core var declaration -//////////////////////////// - -extern c68k_struc C68K; - - -// 68K core function declaration -///////////////////////////////// - -void C68k_Init(c68k_struc *cpu, C68K_INT_CALLBACK *int_cb); - -s32 FASTCALL C68k_Reset(c68k_struc *cpu); - -// if < 0 --> error (cpu state returned) -// if >= 0 --> number of extras cycles done -s32 FASTCALL C68k_Exec(c68k_struc *cpu, s32 cycle); - -void FASTCALL C68k_Set_IRQ(c68k_struc *cpu, s32 level); - -s32 FASTCALL C68k_Get_CycleToDo(c68k_struc *cpu); -s32 FASTCALL C68k_Get_CycleRemaining(c68k_struc *cpu); -s32 FASTCALL C68k_Get_CycleDone(c68k_struc *cpu); -void FASTCALL C68k_Release_Cycle(c68k_struc *cpu); -void FASTCALL C68k_Add_Cycle(c68k_struc *cpu, s32 cycle); - -void C68k_Set_Fetch(c68k_struc *cpu, u32 low_adr, u32 high_adr, pointer fetch_adr); - -void C68k_Set_ReadB(c68k_struc *cpu, C68K_READ *Func); -void C68k_Set_ReadW(c68k_struc *cpu, C68K_READ *Func); -void C68k_Set_WriteB(c68k_struc *cpu, C68K_WRITE *Func); -void C68k_Set_WriteW(c68k_struc *cpu, C68K_WRITE *Func); - -u32 C68k_Get_DReg(c68k_struc *cpu, u32 num); -u32 C68k_Get_AReg(c68k_struc *cpu, u32 num); -u32 C68k_Get_PC(c68k_struc *cpu); -u32 C68k_Get_SR(c68k_struc *cpu); -u32 C68k_Get_USP(c68k_struc *cpu); -u32 C68k_Get_MSP(c68k_struc *cpu); - -void C68k_Set_DReg(c68k_struc *cpu, u32 num, u32 val); -void C68k_Set_AReg(c68k_struc *cpu, u32 num, u32 val); -void C68k_Set_PC(c68k_struc *cpu, u32 val); -void C68k_Set_SR(c68k_struc *cpu, u32 val); -void C68k_Set_USP(c68k_struc *cpu, u32 val); -void C68k_Set_MSP(c68k_struc *cpu, u32 val); - -#ifdef __cplusplus -} -#endif - -#endif // _C68K_H_ - diff --git a/yabause/src/c68k/c68k_ini.inc b/yabause/src/c68k/c68k_ini.inc deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/yabause/src/c68k/c68k_op0.inc b/yabause/src/c68k/c68k_op0.inc deleted file mode 100644 index 59e79c2169..0000000000 --- a/yabause/src/c68k/c68k_op0.inc +++ /dev/null @@ -1,8330 +0,0 @@ -case 0x0001: -case 0x0002: -case 0x0003: -case 0x0004: -case 0x0005: -case 0x0006: -case 0x0007: - -// ORI -case 0x0000: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0011: -case 0x0012: -case 0x0013: -case 0x0014: -case 0x0015: -case 0x0016: -case 0x0017: - -// ORI -case 0x0010: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0019: -case 0x001A: -case 0x001B: -case 0x001C: -case 0x001D: -case 0x001E: - -// ORI -case 0x0018: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0021: -case 0x0022: -case 0x0023: -case 0x0024: -case 0x0025: -case 0x0026: - -// ORI -case 0x0020: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0029: -case 0x002A: -case 0x002B: -case 0x002C: -case 0x002D: -case 0x002E: -case 0x002F: - -// ORI -case 0x0028: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x0031: -case 0x0032: -case 0x0033: -case 0x0034: -case 0x0035: -case 0x0036: -case 0x0037: - -// ORI -case 0x0030: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// ORI -case 0x0038: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// ORI -case 0x0039: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// ORI -case 0x001F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// ORI -case 0x0027: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0041: -case 0x0042: -case 0x0043: -case 0x0044: -case 0x0045: -case 0x0046: -case 0x0047: - -// ORI -case 0x0040: -{ - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0051: -case 0x0052: -case 0x0053: -case 0x0054: -case 0x0055: -case 0x0056: -case 0x0057: - -// ORI -case 0x0050: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0059: -case 0x005A: -case 0x005B: -case 0x005C: -case 0x005D: -case 0x005E: - -// ORI -case 0x0058: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0061: -case 0x0062: -case 0x0063: -case 0x0064: -case 0x0065: -case 0x0066: - -// ORI -case 0x0060: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0069: -case 0x006A: -case 0x006B: -case 0x006C: -case 0x006D: -case 0x006E: -case 0x006F: - -// ORI -case 0x0068: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x0071: -case 0x0072: -case 0x0073: -case 0x0074: -case 0x0075: -case 0x0076: -case 0x0077: - -// ORI -case 0x0070: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// ORI -case 0x0078: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ORI -case 0x0079: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// ORI -case 0x005F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ORI -case 0x0067: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0081: -case 0x0082: -case 0x0083: -case 0x0084: -case 0x0085: -case 0x0086: -case 0x0087: - -// ORI -case 0x0080: -{ - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(16) -case 0x0091: -case 0x0092: -case 0x0093: -case 0x0094: -case 0x0095: -case 0x0096: -case 0x0097: - -// ORI -case 0x0090: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x0099: -case 0x009A: -case 0x009B: -case 0x009C: -case 0x009D: -case 0x009E: - -// ORI -case 0x0098: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x00A1: -case 0x00A2: -case 0x00A3: -case 0x00A4: -case 0x00A5: -case 0x00A6: - -// ORI -case 0x00A0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x00A9: -case 0x00AA: -case 0x00AB: -case 0x00AC: -case 0x00AD: -case 0x00AE: -case 0x00AF: - -// ORI -case 0x00A8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) -case 0x00B1: -case 0x00B2: -case 0x00B3: -case 0x00B4: -case 0x00B5: -case 0x00B6: -case 0x00B7: - -// ORI -case 0x00B0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(34) - -// ORI -case 0x00B8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// ORI -case 0x00B9: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(36) - -// ORI -case 0x009F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// ORI -case 0x00A7: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// ORICCR -case 0x003C: -{ - u32 res; - res = FETCH_BYTE & C68K_CCR_MASK; - PC += 2; - res |= GET_CCR; - SET_CCR(res) -} -RET(20) - -// ORISR -case 0x007C: -{ - u32 res; - if (CPU->flag_S) - { - res = FETCH_WORD & C68K_SR_MASK; - PC += 2; - res |= GET_SR; - SET_SR(res) - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 20; -goto C68k_Exec_End; -case 0x0201: -case 0x0202: -case 0x0203: -case 0x0204: -case 0x0205: -case 0x0206: -case 0x0207: - -// ANDI -case 0x0200: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0211: -case 0x0212: -case 0x0213: -case 0x0214: -case 0x0215: -case 0x0216: -case 0x0217: - -// ANDI -case 0x0210: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0219: -case 0x021A: -case 0x021B: -case 0x021C: -case 0x021D: -case 0x021E: - -// ANDI -case 0x0218: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0221: -case 0x0222: -case 0x0223: -case 0x0224: -case 0x0225: -case 0x0226: - -// ANDI -case 0x0220: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0229: -case 0x022A: -case 0x022B: -case 0x022C: -case 0x022D: -case 0x022E: -case 0x022F: - -// ANDI -case 0x0228: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x0231: -case 0x0232: -case 0x0233: -case 0x0234: -case 0x0235: -case 0x0236: -case 0x0237: - -// ANDI -case 0x0230: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// ANDI -case 0x0238: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// ANDI -case 0x0239: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// ANDI -case 0x021F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// ANDI -case 0x0227: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0241: -case 0x0242: -case 0x0243: -case 0x0244: -case 0x0245: -case 0x0246: -case 0x0247: - -// ANDI -case 0x0240: -{ - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0251: -case 0x0252: -case 0x0253: -case 0x0254: -case 0x0255: -case 0x0256: -case 0x0257: - -// ANDI -case 0x0250: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0259: -case 0x025A: -case 0x025B: -case 0x025C: -case 0x025D: -case 0x025E: - -// ANDI -case 0x0258: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0261: -case 0x0262: -case 0x0263: -case 0x0264: -case 0x0265: -case 0x0266: - -// ANDI -case 0x0260: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0269: -case 0x026A: -case 0x026B: -case 0x026C: -case 0x026D: -case 0x026E: -case 0x026F: - -// ANDI -case 0x0268: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x0271: -case 0x0272: -case 0x0273: -case 0x0274: -case 0x0275: -case 0x0276: -case 0x0277: - -// ANDI -case 0x0270: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// ANDI -case 0x0278: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ANDI -case 0x0279: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// ANDI -case 0x025F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ANDI -case 0x0267: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0281: -case 0x0282: -case 0x0283: -case 0x0284: -case 0x0285: -case 0x0286: -case 0x0287: - -// ANDI -case 0x0280: -{ - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(16) -case 0x0291: -case 0x0292: -case 0x0293: -case 0x0294: -case 0x0295: -case 0x0296: -case 0x0297: - -// ANDI -case 0x0290: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x0299: -case 0x029A: -case 0x029B: -case 0x029C: -case 0x029D: -case 0x029E: - -// ANDI -case 0x0298: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x02A1: -case 0x02A2: -case 0x02A3: -case 0x02A4: -case 0x02A5: -case 0x02A6: - -// ANDI -case 0x02A0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x02A9: -case 0x02AA: -case 0x02AB: -case 0x02AC: -case 0x02AD: -case 0x02AE: -case 0x02AF: - -// ANDI -case 0x02A8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) -case 0x02B1: -case 0x02B2: -case 0x02B3: -case 0x02B4: -case 0x02B5: -case 0x02B6: -case 0x02B7: - -// ANDI -case 0x02B0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(34) - -// ANDI -case 0x02B8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// ANDI -case 0x02B9: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(36) - -// ANDI -case 0x029F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// ANDI -case 0x02A7: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// ANDICCR -case 0x023C: -{ - u32 res; - res = FETCH_BYTE & C68K_CCR_MASK; - PC += 2; - res &= GET_CCR; - SET_CCR(res) -} -RET(20) - -// ANDISR -case 0x027C: -{ - u32 res; - if (CPU->flag_S) - { - res = FETCH_WORD & C68K_SR_MASK; - PC += 2; - res &= GET_SR; - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 20; -goto C68k_Exec_End; -case 0x0A01: -case 0x0A02: -case 0x0A03: -case 0x0A04: -case 0x0A05: -case 0x0A06: -case 0x0A07: - -// EORI -case 0x0A00: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0A11: -case 0x0A12: -case 0x0A13: -case 0x0A14: -case 0x0A15: -case 0x0A16: -case 0x0A17: - -// EORI -case 0x0A10: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0A19: -case 0x0A1A: -case 0x0A1B: -case 0x0A1C: -case 0x0A1D: -case 0x0A1E: - -// EORI -case 0x0A18: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0A21: -case 0x0A22: -case 0x0A23: -case 0x0A24: -case 0x0A25: -case 0x0A26: - -// EORI -case 0x0A20: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0A29: -case 0x0A2A: -case 0x0A2B: -case 0x0A2C: -case 0x0A2D: -case 0x0A2E: -case 0x0A2F: - -// EORI -case 0x0A28: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x0A31: -case 0x0A32: -case 0x0A33: -case 0x0A34: -case 0x0A35: -case 0x0A36: -case 0x0A37: - -// EORI -case 0x0A30: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// EORI -case 0x0A38: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// EORI -case 0x0A39: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// EORI -case 0x0A1F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// EORI -case 0x0A27: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0A41: -case 0x0A42: -case 0x0A43: -case 0x0A44: -case 0x0A45: -case 0x0A46: -case 0x0A47: - -// EORI -case 0x0A40: -{ - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0A51: -case 0x0A52: -case 0x0A53: -case 0x0A54: -case 0x0A55: -case 0x0A56: -case 0x0A57: - -// EORI -case 0x0A50: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0A59: -case 0x0A5A: -case 0x0A5B: -case 0x0A5C: -case 0x0A5D: -case 0x0A5E: - -// EORI -case 0x0A58: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0A61: -case 0x0A62: -case 0x0A63: -case 0x0A64: -case 0x0A65: -case 0x0A66: - -// EORI -case 0x0A60: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0A69: -case 0x0A6A: -case 0x0A6B: -case 0x0A6C: -case 0x0A6D: -case 0x0A6E: -case 0x0A6F: - -// EORI -case 0x0A68: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x0A71: -case 0x0A72: -case 0x0A73: -case 0x0A74: -case 0x0A75: -case 0x0A76: -case 0x0A77: - -// EORI -case 0x0A70: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// EORI -case 0x0A78: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// EORI -case 0x0A79: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// EORI -case 0x0A5F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// EORI -case 0x0A67: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0A81: -case 0x0A82: -case 0x0A83: -case 0x0A84: -case 0x0A85: -case 0x0A86: -case 0x0A87: - -// EORI -case 0x0A80: -{ - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(16) -case 0x0A91: -case 0x0A92: -case 0x0A93: -case 0x0A94: -case 0x0A95: -case 0x0A96: -case 0x0A97: - -// EORI -case 0x0A90: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x0A99: -case 0x0A9A: -case 0x0A9B: -case 0x0A9C: -case 0x0A9D: -case 0x0A9E: - -// EORI -case 0x0A98: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x0AA1: -case 0x0AA2: -case 0x0AA3: -case 0x0AA4: -case 0x0AA5: -case 0x0AA6: - -// EORI -case 0x0AA0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x0AA9: -case 0x0AAA: -case 0x0AAB: -case 0x0AAC: -case 0x0AAD: -case 0x0AAE: -case 0x0AAF: - -// EORI -case 0x0AA8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) -case 0x0AB1: -case 0x0AB2: -case 0x0AB3: -case 0x0AB4: -case 0x0AB5: -case 0x0AB6: -case 0x0AB7: - -// EORI -case 0x0AB0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(34) - -// EORI -case 0x0AB8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// EORI -case 0x0AB9: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(36) - -// EORI -case 0x0A9F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// EORI -case 0x0AA7: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// EORICCR -case 0x0A3C: -{ - u32 res; - res = FETCH_BYTE & C68K_CCR_MASK; - PC += 2; - res ^= GET_CCR; - SET_CCR(res) -} -RET(20) - -// EORISR -case 0x0A7C: -{ - u32 res; - if (CPU->flag_S) - { - res = FETCH_WORD & C68K_SR_MASK; - PC += 2; - res ^= GET_SR; - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 20; -goto C68k_Exec_End; -case 0x0401: -case 0x0402: -case 0x0403: -case 0x0404: -case 0x0405: -case 0x0406: -case 0x0407: - -// SUBI -case 0x0400: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - dst = (u8)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0411: -case 0x0412: -case 0x0413: -case 0x0414: -case 0x0415: -case 0x0416: -case 0x0417: - -// SUBI -case 0x0410: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0419: -case 0x041A: -case 0x041B: -case 0x041C: -case 0x041D: -case 0x041E: - -// SUBI -case 0x0418: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0421: -case 0x0422: -case 0x0423: -case 0x0424: -case 0x0425: -case 0x0426: - -// SUBI -case 0x0420: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0429: -case 0x042A: -case 0x042B: -case 0x042C: -case 0x042D: -case 0x042E: -case 0x042F: - -// SUBI -case 0x0428: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x0431: -case 0x0432: -case 0x0433: -case 0x0434: -case 0x0435: -case 0x0436: -case 0x0437: - -// SUBI -case 0x0430: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// SUBI -case 0x0438: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// SUBI -case 0x0439: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// SUBI -case 0x041F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// SUBI -case 0x0427: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0441: -case 0x0442: -case 0x0443: -case 0x0444: -case 0x0445: -case 0x0446: -case 0x0447: - -// SUBI -case 0x0440: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - dst = (u16)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0451: -case 0x0452: -case 0x0453: -case 0x0454: -case 0x0455: -case 0x0456: -case 0x0457: - -// SUBI -case 0x0450: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0459: -case 0x045A: -case 0x045B: -case 0x045C: -case 0x045D: -case 0x045E: - -// SUBI -case 0x0458: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0461: -case 0x0462: -case 0x0463: -case 0x0464: -case 0x0465: -case 0x0466: - -// SUBI -case 0x0460: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0469: -case 0x046A: -case 0x046B: -case 0x046C: -case 0x046D: -case 0x046E: -case 0x046F: - -// SUBI -case 0x0468: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x0471: -case 0x0472: -case 0x0473: -case 0x0474: -case 0x0475: -case 0x0476: -case 0x0477: - -// SUBI -case 0x0470: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// SUBI -case 0x0478: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// SUBI -case 0x0479: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// SUBI -case 0x045F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// SUBI -case 0x0467: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0481: -case 0x0482: -case 0x0483: -case 0x0484: -case 0x0485: -case 0x0486: -case 0x0487: - -// SUBI -case 0x0480: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - dst = (u32)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(16) -case 0x0491: -case 0x0492: -case 0x0493: -case 0x0494: -case 0x0495: -case 0x0496: -case 0x0497: - -// SUBI -case 0x0490: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x0499: -case 0x049A: -case 0x049B: -case 0x049C: -case 0x049D: -case 0x049E: - -// SUBI -case 0x0498: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x04A1: -case 0x04A2: -case 0x04A3: -case 0x04A4: -case 0x04A5: -case 0x04A6: - -// SUBI -case 0x04A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x04A9: -case 0x04AA: -case 0x04AB: -case 0x04AC: -case 0x04AD: -case 0x04AE: -case 0x04AF: - -// SUBI -case 0x04A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) -case 0x04B1: -case 0x04B2: -case 0x04B3: -case 0x04B4: -case 0x04B5: -case 0x04B6: -case 0x04B7: - -// SUBI -case 0x04B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(34) - -// SUBI -case 0x04B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// SUBI -case 0x04B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(36) - -// SUBI -case 0x049F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// SUBI -case 0x04A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x0601: -case 0x0602: -case 0x0603: -case 0x0604: -case 0x0605: -case 0x0606: -case 0x0607: - -// ADDI -case 0x0600: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - dst = (u8)CPU->D[(Opcode >> 0) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0611: -case 0x0612: -case 0x0613: -case 0x0614: -case 0x0615: -case 0x0616: -case 0x0617: - -// ADDI -case 0x0610: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0619: -case 0x061A: -case 0x061B: -case 0x061C: -case 0x061D: -case 0x061E: - -// ADDI -case 0x0618: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0621: -case 0x0622: -case 0x0623: -case 0x0624: -case 0x0625: -case 0x0626: - -// ADDI -case 0x0620: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0629: -case 0x062A: -case 0x062B: -case 0x062C: -case 0x062D: -case 0x062E: -case 0x062F: - -// ADDI -case 0x0628: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x0631: -case 0x0632: -case 0x0633: -case 0x0634: -case 0x0635: -case 0x0636: -case 0x0637: - -// ADDI -case 0x0630: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// ADDI -case 0x0638: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// ADDI -case 0x0639: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// ADDI -case 0x061F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// ADDI -case 0x0627: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0641: -case 0x0642: -case 0x0643: -case 0x0644: -case 0x0645: -case 0x0646: -case 0x0647: - -// ADDI -case 0x0640: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - dst = (u16)CPU->D[(Opcode >> 0) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0651: -case 0x0652: -case 0x0653: -case 0x0654: -case 0x0655: -case 0x0656: -case 0x0657: - -// ADDI -case 0x0650: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0659: -case 0x065A: -case 0x065B: -case 0x065C: -case 0x065D: -case 0x065E: - -// ADDI -case 0x0658: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x0661: -case 0x0662: -case 0x0663: -case 0x0664: -case 0x0665: -case 0x0666: - -// ADDI -case 0x0660: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0669: -case 0x066A: -case 0x066B: -case 0x066C: -case 0x066D: -case 0x066E: -case 0x066F: - -// ADDI -case 0x0668: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x0671: -case 0x0672: -case 0x0673: -case 0x0674: -case 0x0675: -case 0x0676: -case 0x0677: - -// ADDI -case 0x0670: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// ADDI -case 0x0678: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ADDI -case 0x0679: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// ADDI -case 0x065F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ADDI -case 0x0667: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x0681: -case 0x0682: -case 0x0683: -case 0x0684: -case 0x0685: -case 0x0686: -case 0x0687: - -// ADDI -case 0x0680: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - dst = (u32)CPU->D[(Opcode >> 0) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(16) -case 0x0691: -case 0x0692: -case 0x0693: -case 0x0694: -case 0x0695: -case 0x0696: -case 0x0697: - -// ADDI -case 0x0690: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x0699: -case 0x069A: -case 0x069B: -case 0x069C: -case 0x069D: -case 0x069E: - -// ADDI -case 0x0698: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x06A1: -case 0x06A2: -case 0x06A3: -case 0x06A4: -case 0x06A5: -case 0x06A6: - -// ADDI -case 0x06A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x06A9: -case 0x06AA: -case 0x06AB: -case 0x06AC: -case 0x06AD: -case 0x06AE: -case 0x06AF: - -// ADDI -case 0x06A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) -case 0x06B1: -case 0x06B2: -case 0x06B3: -case 0x06B4: -case 0x06B5: -case 0x06B6: -case 0x06B7: - -// ADDI -case 0x06B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(34) - -// ADDI -case 0x06B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// ADDI -case 0x06B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(36) - -// ADDI -case 0x069F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// ADDI -case 0x06A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x0C01: -case 0x0C02: -case 0x0C03: -case 0x0C04: -case 0x0C05: -case 0x0C06: -case 0x0C07: - -// CMPI -case 0x0C00: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - dst = (u8)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; -} -RET(8) -case 0x0C11: -case 0x0C12: -case 0x0C13: -case 0x0C14: -case 0x0C15: -case 0x0C16: -case 0x0C17: - -// CMPI -case 0x0C10: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) -case 0x0C19: -case 0x0C1A: -case 0x0C1B: -case 0x0C1C: -case 0x0C1D: -case 0x0C1E: - -// CMPI -case 0x0C18: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) -case 0x0C21: -case 0x0C22: -case 0x0C23: -case 0x0C24: -case 0x0C25: -case 0x0C26: - -// CMPI -case 0x0C20: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(14) -case 0x0C29: -case 0x0C2A: -case 0x0C2B: -case 0x0C2C: -case 0x0C2D: -case 0x0C2E: -case 0x0C2F: - -// CMPI -case 0x0C28: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(16) -case 0x0C31: -case 0x0C32: -case 0x0C33: -case 0x0C34: -case 0x0C35: -case 0x0C36: -case 0x0C37: - -// CMPI -case 0x0C30: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(18) - -// CMPI -case 0x0C38: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(16) - -// CMPI -case 0x0C39: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(20) - -// CMPI -case 0x0C1F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) - -// CMPI -case 0x0C27: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(14) -case 0x0C41: -case 0x0C42: -case 0x0C43: -case 0x0C44: -case 0x0C45: -case 0x0C46: -case 0x0C47: - -// CMPI -case 0x0C40: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - dst = (u16)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; -} -RET(8) -case 0x0C51: -case 0x0C52: -case 0x0C53: -case 0x0C54: -case 0x0C55: -case 0x0C56: -case 0x0C57: - -// CMPI -case 0x0C50: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) -case 0x0C59: -case 0x0C5A: -case 0x0C5B: -case 0x0C5C: -case 0x0C5D: -case 0x0C5E: - -// CMPI -case 0x0C58: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) -case 0x0C61: -case 0x0C62: -case 0x0C63: -case 0x0C64: -case 0x0C65: -case 0x0C66: - -// CMPI -case 0x0C60: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(14) -case 0x0C69: -case 0x0C6A: -case 0x0C6B: -case 0x0C6C: -case 0x0C6D: -case 0x0C6E: -case 0x0C6F: - -// CMPI -case 0x0C68: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(16) -case 0x0C71: -case 0x0C72: -case 0x0C73: -case 0x0C74: -case 0x0C75: -case 0x0C76: -case 0x0C77: - -// CMPI -case 0x0C70: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(18) - -// CMPI -case 0x0C78: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(16) - -// CMPI -case 0x0C79: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(20) - -// CMPI -case 0x0C5F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) - -// CMPI -case 0x0C67: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(14) -case 0x0C81: -case 0x0C82: -case 0x0C83: -case 0x0C84: -case 0x0C85: -case 0x0C86: -case 0x0C87: - -// CMPI -case 0x0C80: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - dst = (u32)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(14) -case 0x0C91: -case 0x0C92: -case 0x0C93: -case 0x0C94: -case 0x0C95: -case 0x0C96: -case 0x0C97: - -// CMPI -case 0x0C90: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0x0C99: -case 0x0C9A: -case 0x0C9B: -case 0x0C9C: -case 0x0C9D: -case 0x0C9E: - -// CMPI -case 0x0C98: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0x0CA1: -case 0x0CA2: -case 0x0CA3: -case 0x0CA4: -case 0x0CA5: -case 0x0CA6: - -// CMPI -case 0x0CA0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(22) -case 0x0CA9: -case 0x0CAA: -case 0x0CAB: -case 0x0CAC: -case 0x0CAD: -case 0x0CAE: -case 0x0CAF: - -// CMPI -case 0x0CA8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(24) -case 0x0CB1: -case 0x0CB2: -case 0x0CB3: -case 0x0CB4: -case 0x0CB5: -case 0x0CB6: -case 0x0CB7: - -// CMPI -case 0x0CB0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(26) - -// CMPI -case 0x0CB8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(24) - -// CMPI -case 0x0CB9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(28) - -// CMPI -case 0x0C9F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) - -// CMPI -case 0x0CA7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(22) -case 0x0801: -case 0x0802: -case 0x0803: -case 0x0804: -case 0x0805: -case 0x0806: -case 0x0807: - -// BTSTn -case 0x0800: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 31); - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_notZ = res & src; -} -RET(10) -case 0x0811: -case 0x0812: -case 0x0813: -case 0x0814: -case 0x0815: -case 0x0816: -case 0x0817: - -// BTSTn -case 0x0810: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(12) -case 0x0819: -case 0x081A: -case 0x081B: -case 0x081C: -case 0x081D: -case 0x081E: - -// BTSTn -case 0x0818: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(12) -case 0x0821: -case 0x0822: -case 0x0823: -case 0x0824: -case 0x0825: -case 0x0826: - -// BTSTn -case 0x0820: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(14) -case 0x0829: -case 0x082A: -case 0x082B: -case 0x082C: -case 0x082D: -case 0x082E: -case 0x082F: - -// BTSTn -case 0x0828: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(16) -case 0x0831: -case 0x0832: -case 0x0833: -case 0x0834: -case 0x0835: -case 0x0836: -case 0x0837: - -// BTSTn -case 0x0830: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(18) - -// BTSTn -case 0x0838: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(16) - -// BTSTn -case 0x0839: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(20) - -// BTSTn -case 0x083A: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(16) - -// BTSTn -case 0x083B: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(18) - -// BTSTn -case 0x081F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(12) - -// BTSTn -case 0x0827: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(14) -case 0x0841: -case 0x0842: -case 0x0843: -case 0x0844: -case 0x0845: -case 0x0846: -case 0x0847: - -// BCHGn -case 0x0840: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 31); - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_notZ = res & src; - res ^= src; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(12) -case 0x0851: -case 0x0852: -case 0x0853: -case 0x0854: -case 0x0855: -case 0x0856: -case 0x0857: - -// BCHGn -case 0x0850: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0859: -case 0x085A: -case 0x085B: -case 0x085C: -case 0x085D: -case 0x085E: - -// BCHGn -case 0x0858: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0861: -case 0x0862: -case 0x0863: -case 0x0864: -case 0x0865: -case 0x0866: - -// BCHGn -case 0x0860: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0869: -case 0x086A: -case 0x086B: -case 0x086C: -case 0x086D: -case 0x086E: -case 0x086F: - -// BCHGn -case 0x0868: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x0871: -case 0x0872: -case 0x0873: -case 0x0874: -case 0x0875: -case 0x0876: -case 0x0877: - -// BCHGn -case 0x0870: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// BCHGn -case 0x0878: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// BCHGn -case 0x0879: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// BCHGn -case 0x085F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// BCHGn -case 0x0867: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0881: -case 0x0882: -case 0x0883: -case 0x0884: -case 0x0885: -case 0x0886: -case 0x0887: - -// BCLRn -case 0x0880: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 31); - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_notZ = res & src; - res &= ~src; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(14) -case 0x0891: -case 0x0892: -case 0x0893: -case 0x0894: -case 0x0895: -case 0x0896: -case 0x0897: - -// BCLRn -case 0x0890: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0899: -case 0x089A: -case 0x089B: -case 0x089C: -case 0x089D: -case 0x089E: - -// BCLRn -case 0x0898: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x08A1: -case 0x08A2: -case 0x08A3: -case 0x08A4: -case 0x08A5: -case 0x08A6: - -// BCLRn -case 0x08A0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x08A9: -case 0x08AA: -case 0x08AB: -case 0x08AC: -case 0x08AD: -case 0x08AE: -case 0x08AF: - -// BCLRn -case 0x08A8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x08B1: -case 0x08B2: -case 0x08B3: -case 0x08B4: -case 0x08B5: -case 0x08B6: -case 0x08B7: - -// BCLRn -case 0x08B0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// BCLRn -case 0x08B8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// BCLRn -case 0x08B9: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// BCLRn -case 0x089F: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// BCLRn -case 0x08A7: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x08C1: -case 0x08C2: -case 0x08C3: -case 0x08C4: -case 0x08C5: -case 0x08C6: -case 0x08C7: - -// BSETn -case 0x08C0: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 31); - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_notZ = res & src; - res |= src; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(12) -case 0x08D1: -case 0x08D2: -case 0x08D3: -case 0x08D4: -case 0x08D5: -case 0x08D6: -case 0x08D7: - -// BSETn -case 0x08D0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x08D9: -case 0x08DA: -case 0x08DB: -case 0x08DC: -case 0x08DD: -case 0x08DE: - -// BSETn -case 0x08D8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x08E1: -case 0x08E2: -case 0x08E3: -case 0x08E4: -case 0x08E5: -case 0x08E6: - -// BSETn -case 0x08E0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x08E9: -case 0x08EA: -case 0x08EB: -case 0x08EC: -case 0x08ED: -case 0x08EE: -case 0x08EF: - -// BSETn -case 0x08E8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x08F1: -case 0x08F2: -case 0x08F3: -case 0x08F4: -case 0x08F5: -case 0x08F6: -case 0x08F7: - -// BSETn -case 0x08F0: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// BSETn -case 0x08F8: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// BSETn -case 0x08F9: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// BSETn -case 0x08DF: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// BSETn -case 0x08E7: -{ - u32 adr; - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - src = 1 << (src & 7); - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0300: -case 0x0500: -case 0x0700: -case 0x0900: -case 0x0B00: -case 0x0D00: -case 0x0F00: -case 0x0101: -case 0x0301: -case 0x0501: -case 0x0701: -case 0x0901: -case 0x0B01: -case 0x0D01: -case 0x0F01: -case 0x0102: -case 0x0302: -case 0x0502: -case 0x0702: -case 0x0902: -case 0x0B02: -case 0x0D02: -case 0x0F02: -case 0x0103: -case 0x0303: -case 0x0503: -case 0x0703: -case 0x0903: -case 0x0B03: -case 0x0D03: -case 0x0F03: -case 0x0104: -case 0x0304: -case 0x0504: -case 0x0704: -case 0x0904: -case 0x0B04: -case 0x0D04: -case 0x0F04: -case 0x0105: -case 0x0305: -case 0x0505: -case 0x0705: -case 0x0905: -case 0x0B05: -case 0x0D05: -case 0x0F05: -case 0x0106: -case 0x0306: -case 0x0506: -case 0x0706: -case 0x0906: -case 0x0B06: -case 0x0D06: -case 0x0F06: -case 0x0107: -case 0x0307: -case 0x0507: -case 0x0707: -case 0x0907: -case 0x0B07: -case 0x0D07: -case 0x0F07: - -// BTST -case 0x0100: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 31); - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_notZ = res & src; -} -RET(6) -case 0x0310: -case 0x0510: -case 0x0710: -case 0x0910: -case 0x0B10: -case 0x0D10: -case 0x0F10: -case 0x0111: -case 0x0311: -case 0x0511: -case 0x0711: -case 0x0911: -case 0x0B11: -case 0x0D11: -case 0x0F11: -case 0x0112: -case 0x0312: -case 0x0512: -case 0x0712: -case 0x0912: -case 0x0B12: -case 0x0D12: -case 0x0F12: -case 0x0113: -case 0x0313: -case 0x0513: -case 0x0713: -case 0x0913: -case 0x0B13: -case 0x0D13: -case 0x0F13: -case 0x0114: -case 0x0314: -case 0x0514: -case 0x0714: -case 0x0914: -case 0x0B14: -case 0x0D14: -case 0x0F14: -case 0x0115: -case 0x0315: -case 0x0515: -case 0x0715: -case 0x0915: -case 0x0B15: -case 0x0D15: -case 0x0F15: -case 0x0116: -case 0x0316: -case 0x0516: -case 0x0716: -case 0x0916: -case 0x0B16: -case 0x0D16: -case 0x0F16: -case 0x0117: -case 0x0317: -case 0x0517: -case 0x0717: -case 0x0917: -case 0x0B17: -case 0x0D17: -case 0x0F17: - -// BTST -case 0x0110: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(8) -case 0x0318: -case 0x0518: -case 0x0718: -case 0x0918: -case 0x0B18: -case 0x0D18: -case 0x0F18: -case 0x0119: -case 0x0319: -case 0x0519: -case 0x0719: -case 0x0919: -case 0x0B19: -case 0x0D19: -case 0x0F19: -case 0x011A: -case 0x031A: -case 0x051A: -case 0x071A: -case 0x091A: -case 0x0B1A: -case 0x0D1A: -case 0x0F1A: -case 0x011B: -case 0x031B: -case 0x051B: -case 0x071B: -case 0x091B: -case 0x0B1B: -case 0x0D1B: -case 0x0F1B: -case 0x011C: -case 0x031C: -case 0x051C: -case 0x071C: -case 0x091C: -case 0x0B1C: -case 0x0D1C: -case 0x0F1C: -case 0x011D: -case 0x031D: -case 0x051D: -case 0x071D: -case 0x091D: -case 0x0B1D: -case 0x0D1D: -case 0x0F1D: -case 0x011E: -case 0x031E: -case 0x051E: -case 0x071E: -case 0x091E: -case 0x0B1E: -case 0x0D1E: -case 0x0F1E: - -// BTST -case 0x0118: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(8) -case 0x0320: -case 0x0520: -case 0x0720: -case 0x0920: -case 0x0B20: -case 0x0D20: -case 0x0F20: -case 0x0121: -case 0x0321: -case 0x0521: -case 0x0721: -case 0x0921: -case 0x0B21: -case 0x0D21: -case 0x0F21: -case 0x0122: -case 0x0322: -case 0x0522: -case 0x0722: -case 0x0922: -case 0x0B22: -case 0x0D22: -case 0x0F22: -case 0x0123: -case 0x0323: -case 0x0523: -case 0x0723: -case 0x0923: -case 0x0B23: -case 0x0D23: -case 0x0F23: -case 0x0124: -case 0x0324: -case 0x0524: -case 0x0724: -case 0x0924: -case 0x0B24: -case 0x0D24: -case 0x0F24: -case 0x0125: -case 0x0325: -case 0x0525: -case 0x0725: -case 0x0925: -case 0x0B25: -case 0x0D25: -case 0x0F25: -case 0x0126: -case 0x0326: -case 0x0526: -case 0x0726: -case 0x0926: -case 0x0B26: -case 0x0D26: -case 0x0F26: - -// BTST -case 0x0120: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(10) -case 0x0328: -case 0x0528: -case 0x0728: -case 0x0928: -case 0x0B28: -case 0x0D28: -case 0x0F28: -case 0x0129: -case 0x0329: -case 0x0529: -case 0x0729: -case 0x0929: -case 0x0B29: -case 0x0D29: -case 0x0F29: -case 0x012A: -case 0x032A: -case 0x052A: -case 0x072A: -case 0x092A: -case 0x0B2A: -case 0x0D2A: -case 0x0F2A: -case 0x012B: -case 0x032B: -case 0x052B: -case 0x072B: -case 0x092B: -case 0x0B2B: -case 0x0D2B: -case 0x0F2B: -case 0x012C: -case 0x032C: -case 0x052C: -case 0x072C: -case 0x092C: -case 0x0B2C: -case 0x0D2C: -case 0x0F2C: -case 0x012D: -case 0x032D: -case 0x052D: -case 0x072D: -case 0x092D: -case 0x0B2D: -case 0x0D2D: -case 0x0F2D: -case 0x012E: -case 0x032E: -case 0x052E: -case 0x072E: -case 0x092E: -case 0x0B2E: -case 0x0D2E: -case 0x0F2E: -case 0x012F: -case 0x032F: -case 0x052F: -case 0x072F: -case 0x092F: -case 0x0B2F: -case 0x0D2F: -case 0x0F2F: - -// BTST -case 0x0128: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(12) -case 0x0330: -case 0x0530: -case 0x0730: -case 0x0930: -case 0x0B30: -case 0x0D30: -case 0x0F30: -case 0x0131: -case 0x0331: -case 0x0531: -case 0x0731: -case 0x0931: -case 0x0B31: -case 0x0D31: -case 0x0F31: -case 0x0132: -case 0x0332: -case 0x0532: -case 0x0732: -case 0x0932: -case 0x0B32: -case 0x0D32: -case 0x0F32: -case 0x0133: -case 0x0333: -case 0x0533: -case 0x0733: -case 0x0933: -case 0x0B33: -case 0x0D33: -case 0x0F33: -case 0x0134: -case 0x0334: -case 0x0534: -case 0x0734: -case 0x0934: -case 0x0B34: -case 0x0D34: -case 0x0F34: -case 0x0135: -case 0x0335: -case 0x0535: -case 0x0735: -case 0x0935: -case 0x0B35: -case 0x0D35: -case 0x0F35: -case 0x0136: -case 0x0336: -case 0x0536: -case 0x0736: -case 0x0936: -case 0x0B36: -case 0x0D36: -case 0x0F36: -case 0x0137: -case 0x0337: -case 0x0537: -case 0x0737: -case 0x0937: -case 0x0B37: -case 0x0D37: -case 0x0F37: - -// BTST -case 0x0130: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(14) -case 0x0338: -case 0x0538: -case 0x0738: -case 0x0938: -case 0x0B38: -case 0x0D38: -case 0x0F38: - -// BTST -case 0x0138: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(12) -case 0x0339: -case 0x0539: -case 0x0739: -case 0x0939: -case 0x0B39: -case 0x0D39: -case 0x0F39: - -// BTST -case 0x0139: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(16) -case 0x033A: -case 0x053A: -case 0x073A: -case 0x093A: -case 0x0B3A: -case 0x0D3A: -case 0x0F3A: - -// BTST -case 0x013A: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(12) -case 0x033B: -case 0x053B: -case 0x073B: -case 0x093B: -case 0x0B3B: -case 0x0D3B: -case 0x0F3B: - -// BTST -case 0x013B: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(14) -case 0x033C: -case 0x053C: -case 0x073C: -case 0x093C: -case 0x0B3C: -case 0x0D3C: -case 0x0F3C: - -// BTST -case 0x013C: -{ - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - res = FETCH_BYTE; - PC += 2; - CPU->flag_notZ = res & src; -} -RET(8) -case 0x031F: -case 0x051F: -case 0x071F: -case 0x091F: -case 0x0B1F: -case 0x0D1F: -case 0x0F1F: - -// BTST -case 0x011F: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(8) -case 0x0327: -case 0x0527: -case 0x0727: -case 0x0927: -case 0x0B27: -case 0x0D27: -case 0x0F27: - -// BTST -case 0x0127: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - POST_IO -} -RET(10) -case 0x0340: -case 0x0540: -case 0x0740: -case 0x0940: -case 0x0B40: -case 0x0D40: -case 0x0F40: -case 0x0141: -case 0x0341: -case 0x0541: -case 0x0741: -case 0x0941: -case 0x0B41: -case 0x0D41: -case 0x0F41: -case 0x0142: -case 0x0342: -case 0x0542: -case 0x0742: -case 0x0942: -case 0x0B42: -case 0x0D42: -case 0x0F42: -case 0x0143: -case 0x0343: -case 0x0543: -case 0x0743: -case 0x0943: -case 0x0B43: -case 0x0D43: -case 0x0F43: -case 0x0144: -case 0x0344: -case 0x0544: -case 0x0744: -case 0x0944: -case 0x0B44: -case 0x0D44: -case 0x0F44: -case 0x0145: -case 0x0345: -case 0x0545: -case 0x0745: -case 0x0945: -case 0x0B45: -case 0x0D45: -case 0x0F45: -case 0x0146: -case 0x0346: -case 0x0546: -case 0x0746: -case 0x0946: -case 0x0B46: -case 0x0D46: -case 0x0F46: -case 0x0147: -case 0x0347: -case 0x0547: -case 0x0747: -case 0x0947: -case 0x0B47: -case 0x0D47: -case 0x0F47: - -// BCHG -case 0x0140: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 31); - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_notZ = res & src; - res ^= src; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x0350: -case 0x0550: -case 0x0750: -case 0x0950: -case 0x0B50: -case 0x0D50: -case 0x0F50: -case 0x0151: -case 0x0351: -case 0x0551: -case 0x0751: -case 0x0951: -case 0x0B51: -case 0x0D51: -case 0x0F51: -case 0x0152: -case 0x0352: -case 0x0552: -case 0x0752: -case 0x0952: -case 0x0B52: -case 0x0D52: -case 0x0F52: -case 0x0153: -case 0x0353: -case 0x0553: -case 0x0753: -case 0x0953: -case 0x0B53: -case 0x0D53: -case 0x0F53: -case 0x0154: -case 0x0354: -case 0x0554: -case 0x0754: -case 0x0954: -case 0x0B54: -case 0x0D54: -case 0x0F54: -case 0x0155: -case 0x0355: -case 0x0555: -case 0x0755: -case 0x0955: -case 0x0B55: -case 0x0D55: -case 0x0F55: -case 0x0156: -case 0x0356: -case 0x0556: -case 0x0756: -case 0x0956: -case 0x0B56: -case 0x0D56: -case 0x0F56: -case 0x0157: -case 0x0357: -case 0x0557: -case 0x0757: -case 0x0957: -case 0x0B57: -case 0x0D57: -case 0x0F57: - -// BCHG -case 0x0150: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x0358: -case 0x0558: -case 0x0758: -case 0x0958: -case 0x0B58: -case 0x0D58: -case 0x0F58: -case 0x0159: -case 0x0359: -case 0x0559: -case 0x0759: -case 0x0959: -case 0x0B59: -case 0x0D59: -case 0x0F59: -case 0x015A: -case 0x035A: -case 0x055A: -case 0x075A: -case 0x095A: -case 0x0B5A: -case 0x0D5A: -case 0x0F5A: -case 0x015B: -case 0x035B: -case 0x055B: -case 0x075B: -case 0x095B: -case 0x0B5B: -case 0x0D5B: -case 0x0F5B: -case 0x015C: -case 0x035C: -case 0x055C: -case 0x075C: -case 0x095C: -case 0x0B5C: -case 0x0D5C: -case 0x0F5C: -case 0x015D: -case 0x035D: -case 0x055D: -case 0x075D: -case 0x095D: -case 0x0B5D: -case 0x0D5D: -case 0x0F5D: -case 0x015E: -case 0x035E: -case 0x055E: -case 0x075E: -case 0x095E: -case 0x0B5E: -case 0x0D5E: -case 0x0F5E: - -// BCHG -case 0x0158: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x0360: -case 0x0560: -case 0x0760: -case 0x0960: -case 0x0B60: -case 0x0D60: -case 0x0F60: -case 0x0161: -case 0x0361: -case 0x0561: -case 0x0761: -case 0x0961: -case 0x0B61: -case 0x0D61: -case 0x0F61: -case 0x0162: -case 0x0362: -case 0x0562: -case 0x0762: -case 0x0962: -case 0x0B62: -case 0x0D62: -case 0x0F62: -case 0x0163: -case 0x0363: -case 0x0563: -case 0x0763: -case 0x0963: -case 0x0B63: -case 0x0D63: -case 0x0F63: -case 0x0164: -case 0x0364: -case 0x0564: -case 0x0764: -case 0x0964: -case 0x0B64: -case 0x0D64: -case 0x0F64: -case 0x0165: -case 0x0365: -case 0x0565: -case 0x0765: -case 0x0965: -case 0x0B65: -case 0x0D65: -case 0x0F65: -case 0x0166: -case 0x0366: -case 0x0566: -case 0x0766: -case 0x0966: -case 0x0B66: -case 0x0D66: -case 0x0F66: - -// BCHG -case 0x0160: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x0368: -case 0x0568: -case 0x0768: -case 0x0968: -case 0x0B68: -case 0x0D68: -case 0x0F68: -case 0x0169: -case 0x0369: -case 0x0569: -case 0x0769: -case 0x0969: -case 0x0B69: -case 0x0D69: -case 0x0F69: -case 0x016A: -case 0x036A: -case 0x056A: -case 0x076A: -case 0x096A: -case 0x0B6A: -case 0x0D6A: -case 0x0F6A: -case 0x016B: -case 0x036B: -case 0x056B: -case 0x076B: -case 0x096B: -case 0x0B6B: -case 0x0D6B: -case 0x0F6B: -case 0x016C: -case 0x036C: -case 0x056C: -case 0x076C: -case 0x096C: -case 0x0B6C: -case 0x0D6C: -case 0x0F6C: -case 0x016D: -case 0x036D: -case 0x056D: -case 0x076D: -case 0x096D: -case 0x0B6D: -case 0x0D6D: -case 0x0F6D: -case 0x016E: -case 0x036E: -case 0x056E: -case 0x076E: -case 0x096E: -case 0x0B6E: -case 0x0D6E: -case 0x0F6E: -case 0x016F: -case 0x036F: -case 0x056F: -case 0x076F: -case 0x096F: -case 0x0B6F: -case 0x0D6F: -case 0x0F6F: - -// BCHG -case 0x0168: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0370: -case 0x0570: -case 0x0770: -case 0x0970: -case 0x0B70: -case 0x0D70: -case 0x0F70: -case 0x0171: -case 0x0371: -case 0x0571: -case 0x0771: -case 0x0971: -case 0x0B71: -case 0x0D71: -case 0x0F71: -case 0x0172: -case 0x0372: -case 0x0572: -case 0x0772: -case 0x0972: -case 0x0B72: -case 0x0D72: -case 0x0F72: -case 0x0173: -case 0x0373: -case 0x0573: -case 0x0773: -case 0x0973: -case 0x0B73: -case 0x0D73: -case 0x0F73: -case 0x0174: -case 0x0374: -case 0x0574: -case 0x0774: -case 0x0974: -case 0x0B74: -case 0x0D74: -case 0x0F74: -case 0x0175: -case 0x0375: -case 0x0575: -case 0x0775: -case 0x0975: -case 0x0B75: -case 0x0D75: -case 0x0F75: -case 0x0176: -case 0x0376: -case 0x0576: -case 0x0776: -case 0x0976: -case 0x0B76: -case 0x0D76: -case 0x0F76: -case 0x0177: -case 0x0377: -case 0x0577: -case 0x0777: -case 0x0977: -case 0x0B77: -case 0x0D77: -case 0x0F77: - -// BCHG -case 0x0170: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x0378: -case 0x0578: -case 0x0778: -case 0x0978: -case 0x0B78: -case 0x0D78: -case 0x0F78: - -// BCHG -case 0x0178: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x0379: -case 0x0579: -case 0x0779: -case 0x0979: -case 0x0B79: -case 0x0D79: -case 0x0F79: - -// BCHG -case 0x0179: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x035F: -case 0x055F: -case 0x075F: -case 0x095F: -case 0x0B5F: -case 0x0D5F: -case 0x0F5F: - -// BCHG -case 0x015F: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x0367: -case 0x0567: -case 0x0767: -case 0x0967: -case 0x0B67: -case 0x0D67: -case 0x0F67: - -// BCHG -case 0x0167: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res ^= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x0380: -case 0x0580: -case 0x0780: -case 0x0980: -case 0x0B80: -case 0x0D80: -case 0x0F80: -case 0x0181: -case 0x0381: -case 0x0581: -case 0x0781: -case 0x0981: -case 0x0B81: -case 0x0D81: -case 0x0F81: -case 0x0182: -case 0x0382: -case 0x0582: -case 0x0782: -case 0x0982: -case 0x0B82: -case 0x0D82: -case 0x0F82: -case 0x0183: -case 0x0383: -case 0x0583: -case 0x0783: -case 0x0983: -case 0x0B83: -case 0x0D83: -case 0x0F83: -case 0x0184: -case 0x0384: -case 0x0584: -case 0x0784: -case 0x0984: -case 0x0B84: -case 0x0D84: -case 0x0F84: -case 0x0185: -case 0x0385: -case 0x0585: -case 0x0785: -case 0x0985: -case 0x0B85: -case 0x0D85: -case 0x0F85: -case 0x0186: -case 0x0386: -case 0x0586: -case 0x0786: -case 0x0986: -case 0x0B86: -case 0x0D86: -case 0x0F86: -case 0x0187: -case 0x0387: -case 0x0587: -case 0x0787: -case 0x0987: -case 0x0B87: -case 0x0D87: -case 0x0F87: - -// BCLR -case 0x0180: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 31); - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_notZ = res & src; - res &= ~src; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(10) -case 0x0390: -case 0x0590: -case 0x0790: -case 0x0990: -case 0x0B90: -case 0x0D90: -case 0x0F90: -case 0x0191: -case 0x0391: -case 0x0591: -case 0x0791: -case 0x0991: -case 0x0B91: -case 0x0D91: -case 0x0F91: -case 0x0192: -case 0x0392: -case 0x0592: -case 0x0792: -case 0x0992: -case 0x0B92: -case 0x0D92: -case 0x0F92: -case 0x0193: -case 0x0393: -case 0x0593: -case 0x0793: -case 0x0993: -case 0x0B93: -case 0x0D93: -case 0x0F93: -case 0x0194: -case 0x0394: -case 0x0594: -case 0x0794: -case 0x0994: -case 0x0B94: -case 0x0D94: -case 0x0F94: -case 0x0195: -case 0x0395: -case 0x0595: -case 0x0795: -case 0x0995: -case 0x0B95: -case 0x0D95: -case 0x0F95: -case 0x0196: -case 0x0396: -case 0x0596: -case 0x0796: -case 0x0996: -case 0x0B96: -case 0x0D96: -case 0x0F96: -case 0x0197: -case 0x0397: -case 0x0597: -case 0x0797: -case 0x0997: -case 0x0B97: -case 0x0D97: -case 0x0F97: - -// BCLR -case 0x0190: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x0398: -case 0x0598: -case 0x0798: -case 0x0998: -case 0x0B98: -case 0x0D98: -case 0x0F98: -case 0x0199: -case 0x0399: -case 0x0599: -case 0x0799: -case 0x0999: -case 0x0B99: -case 0x0D99: -case 0x0F99: -case 0x019A: -case 0x039A: -case 0x059A: -case 0x079A: -case 0x099A: -case 0x0B9A: -case 0x0D9A: -case 0x0F9A: -case 0x019B: -case 0x039B: -case 0x059B: -case 0x079B: -case 0x099B: -case 0x0B9B: -case 0x0D9B: -case 0x0F9B: -case 0x019C: -case 0x039C: -case 0x059C: -case 0x079C: -case 0x099C: -case 0x0B9C: -case 0x0D9C: -case 0x0F9C: -case 0x019D: -case 0x039D: -case 0x059D: -case 0x079D: -case 0x099D: -case 0x0B9D: -case 0x0D9D: -case 0x0F9D: -case 0x019E: -case 0x039E: -case 0x059E: -case 0x079E: -case 0x099E: -case 0x0B9E: -case 0x0D9E: -case 0x0F9E: - -// BCLR -case 0x0198: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x03A0: -case 0x05A0: -case 0x07A0: -case 0x09A0: -case 0x0BA0: -case 0x0DA0: -case 0x0FA0: -case 0x01A1: -case 0x03A1: -case 0x05A1: -case 0x07A1: -case 0x09A1: -case 0x0BA1: -case 0x0DA1: -case 0x0FA1: -case 0x01A2: -case 0x03A2: -case 0x05A2: -case 0x07A2: -case 0x09A2: -case 0x0BA2: -case 0x0DA2: -case 0x0FA2: -case 0x01A3: -case 0x03A3: -case 0x05A3: -case 0x07A3: -case 0x09A3: -case 0x0BA3: -case 0x0DA3: -case 0x0FA3: -case 0x01A4: -case 0x03A4: -case 0x05A4: -case 0x07A4: -case 0x09A4: -case 0x0BA4: -case 0x0DA4: -case 0x0FA4: -case 0x01A5: -case 0x03A5: -case 0x05A5: -case 0x07A5: -case 0x09A5: -case 0x0BA5: -case 0x0DA5: -case 0x0FA5: -case 0x01A6: -case 0x03A6: -case 0x05A6: -case 0x07A6: -case 0x09A6: -case 0x0BA6: -case 0x0DA6: -case 0x0FA6: - -// BCLR -case 0x01A0: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x03A8: -case 0x05A8: -case 0x07A8: -case 0x09A8: -case 0x0BA8: -case 0x0DA8: -case 0x0FA8: -case 0x01A9: -case 0x03A9: -case 0x05A9: -case 0x07A9: -case 0x09A9: -case 0x0BA9: -case 0x0DA9: -case 0x0FA9: -case 0x01AA: -case 0x03AA: -case 0x05AA: -case 0x07AA: -case 0x09AA: -case 0x0BAA: -case 0x0DAA: -case 0x0FAA: -case 0x01AB: -case 0x03AB: -case 0x05AB: -case 0x07AB: -case 0x09AB: -case 0x0BAB: -case 0x0DAB: -case 0x0FAB: -case 0x01AC: -case 0x03AC: -case 0x05AC: -case 0x07AC: -case 0x09AC: -case 0x0BAC: -case 0x0DAC: -case 0x0FAC: -case 0x01AD: -case 0x03AD: -case 0x05AD: -case 0x07AD: -case 0x09AD: -case 0x0BAD: -case 0x0DAD: -case 0x0FAD: -case 0x01AE: -case 0x03AE: -case 0x05AE: -case 0x07AE: -case 0x09AE: -case 0x0BAE: -case 0x0DAE: -case 0x0FAE: -case 0x01AF: -case 0x03AF: -case 0x05AF: -case 0x07AF: -case 0x09AF: -case 0x0BAF: -case 0x0DAF: -case 0x0FAF: - -// BCLR -case 0x01A8: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x03B0: -case 0x05B0: -case 0x07B0: -case 0x09B0: -case 0x0BB0: -case 0x0DB0: -case 0x0FB0: -case 0x01B1: -case 0x03B1: -case 0x05B1: -case 0x07B1: -case 0x09B1: -case 0x0BB1: -case 0x0DB1: -case 0x0FB1: -case 0x01B2: -case 0x03B2: -case 0x05B2: -case 0x07B2: -case 0x09B2: -case 0x0BB2: -case 0x0DB2: -case 0x0FB2: -case 0x01B3: -case 0x03B3: -case 0x05B3: -case 0x07B3: -case 0x09B3: -case 0x0BB3: -case 0x0DB3: -case 0x0FB3: -case 0x01B4: -case 0x03B4: -case 0x05B4: -case 0x07B4: -case 0x09B4: -case 0x0BB4: -case 0x0DB4: -case 0x0FB4: -case 0x01B5: -case 0x03B5: -case 0x05B5: -case 0x07B5: -case 0x09B5: -case 0x0BB5: -case 0x0DB5: -case 0x0FB5: -case 0x01B6: -case 0x03B6: -case 0x05B6: -case 0x07B6: -case 0x09B6: -case 0x0BB6: -case 0x0DB6: -case 0x0FB6: -case 0x01B7: -case 0x03B7: -case 0x05B7: -case 0x07B7: -case 0x09B7: -case 0x0BB7: -case 0x0DB7: -case 0x0FB7: - -// BCLR -case 0x01B0: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x03B8: -case 0x05B8: -case 0x07B8: -case 0x09B8: -case 0x0BB8: -case 0x0DB8: -case 0x0FB8: - -// BCLR -case 0x01B8: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x03B9: -case 0x05B9: -case 0x07B9: -case 0x09B9: -case 0x0BB9: -case 0x0DB9: -case 0x0FB9: - -// BCLR -case 0x01B9: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x039F: -case 0x059F: -case 0x079F: -case 0x099F: -case 0x0B9F: -case 0x0D9F: -case 0x0F9F: - -// BCLR -case 0x019F: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x03A7: -case 0x05A7: -case 0x07A7: -case 0x09A7: -case 0x0BA7: -case 0x0DA7: -case 0x0FA7: - -// BCLR -case 0x01A7: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res &= ~src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x03C0: -case 0x05C0: -case 0x07C0: -case 0x09C0: -case 0x0BC0: -case 0x0DC0: -case 0x0FC0: -case 0x01C1: -case 0x03C1: -case 0x05C1: -case 0x07C1: -case 0x09C1: -case 0x0BC1: -case 0x0DC1: -case 0x0FC1: -case 0x01C2: -case 0x03C2: -case 0x05C2: -case 0x07C2: -case 0x09C2: -case 0x0BC2: -case 0x0DC2: -case 0x0FC2: -case 0x01C3: -case 0x03C3: -case 0x05C3: -case 0x07C3: -case 0x09C3: -case 0x0BC3: -case 0x0DC3: -case 0x0FC3: -case 0x01C4: -case 0x03C4: -case 0x05C4: -case 0x07C4: -case 0x09C4: -case 0x0BC4: -case 0x0DC4: -case 0x0FC4: -case 0x01C5: -case 0x03C5: -case 0x05C5: -case 0x07C5: -case 0x09C5: -case 0x0BC5: -case 0x0DC5: -case 0x0FC5: -case 0x01C6: -case 0x03C6: -case 0x05C6: -case 0x07C6: -case 0x09C6: -case 0x0BC6: -case 0x0DC6: -case 0x0FC6: -case 0x01C7: -case 0x03C7: -case 0x05C7: -case 0x07C7: -case 0x09C7: -case 0x0BC7: -case 0x0DC7: -case 0x0FC7: - -// BSET -case 0x01C0: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 31); - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_notZ = res & src; - res |= src; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x03D0: -case 0x05D0: -case 0x07D0: -case 0x09D0: -case 0x0BD0: -case 0x0DD0: -case 0x0FD0: -case 0x01D1: -case 0x03D1: -case 0x05D1: -case 0x07D1: -case 0x09D1: -case 0x0BD1: -case 0x0DD1: -case 0x0FD1: -case 0x01D2: -case 0x03D2: -case 0x05D2: -case 0x07D2: -case 0x09D2: -case 0x0BD2: -case 0x0DD2: -case 0x0FD2: -case 0x01D3: -case 0x03D3: -case 0x05D3: -case 0x07D3: -case 0x09D3: -case 0x0BD3: -case 0x0DD3: -case 0x0FD3: -case 0x01D4: -case 0x03D4: -case 0x05D4: -case 0x07D4: -case 0x09D4: -case 0x0BD4: -case 0x0DD4: -case 0x0FD4: -case 0x01D5: -case 0x03D5: -case 0x05D5: -case 0x07D5: -case 0x09D5: -case 0x0BD5: -case 0x0DD5: -case 0x0FD5: -case 0x01D6: -case 0x03D6: -case 0x05D6: -case 0x07D6: -case 0x09D6: -case 0x0BD6: -case 0x0DD6: -case 0x0FD6: -case 0x01D7: -case 0x03D7: -case 0x05D7: -case 0x07D7: -case 0x09D7: -case 0x0BD7: -case 0x0DD7: -case 0x0FD7: - -// BSET -case 0x01D0: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x03D8: -case 0x05D8: -case 0x07D8: -case 0x09D8: -case 0x0BD8: -case 0x0DD8: -case 0x0FD8: -case 0x01D9: -case 0x03D9: -case 0x05D9: -case 0x07D9: -case 0x09D9: -case 0x0BD9: -case 0x0DD9: -case 0x0FD9: -case 0x01DA: -case 0x03DA: -case 0x05DA: -case 0x07DA: -case 0x09DA: -case 0x0BDA: -case 0x0DDA: -case 0x0FDA: -case 0x01DB: -case 0x03DB: -case 0x05DB: -case 0x07DB: -case 0x09DB: -case 0x0BDB: -case 0x0DDB: -case 0x0FDB: -case 0x01DC: -case 0x03DC: -case 0x05DC: -case 0x07DC: -case 0x09DC: -case 0x0BDC: -case 0x0DDC: -case 0x0FDC: -case 0x01DD: -case 0x03DD: -case 0x05DD: -case 0x07DD: -case 0x09DD: -case 0x0BDD: -case 0x0DDD: -case 0x0FDD: -case 0x01DE: -case 0x03DE: -case 0x05DE: -case 0x07DE: -case 0x09DE: -case 0x0BDE: -case 0x0DDE: -case 0x0FDE: - -// BSET -case 0x01D8: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x03E0: -case 0x05E0: -case 0x07E0: -case 0x09E0: -case 0x0BE0: -case 0x0DE0: -case 0x0FE0: -case 0x01E1: -case 0x03E1: -case 0x05E1: -case 0x07E1: -case 0x09E1: -case 0x0BE1: -case 0x0DE1: -case 0x0FE1: -case 0x01E2: -case 0x03E2: -case 0x05E2: -case 0x07E2: -case 0x09E2: -case 0x0BE2: -case 0x0DE2: -case 0x0FE2: -case 0x01E3: -case 0x03E3: -case 0x05E3: -case 0x07E3: -case 0x09E3: -case 0x0BE3: -case 0x0DE3: -case 0x0FE3: -case 0x01E4: -case 0x03E4: -case 0x05E4: -case 0x07E4: -case 0x09E4: -case 0x0BE4: -case 0x0DE4: -case 0x0FE4: -case 0x01E5: -case 0x03E5: -case 0x05E5: -case 0x07E5: -case 0x09E5: -case 0x0BE5: -case 0x0DE5: -case 0x0FE5: -case 0x01E6: -case 0x03E6: -case 0x05E6: -case 0x07E6: -case 0x09E6: -case 0x0BE6: -case 0x0DE6: -case 0x0FE6: - -// BSET -case 0x01E0: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x03E8: -case 0x05E8: -case 0x07E8: -case 0x09E8: -case 0x0BE8: -case 0x0DE8: -case 0x0FE8: -case 0x01E9: -case 0x03E9: -case 0x05E9: -case 0x07E9: -case 0x09E9: -case 0x0BE9: -case 0x0DE9: -case 0x0FE9: -case 0x01EA: -case 0x03EA: -case 0x05EA: -case 0x07EA: -case 0x09EA: -case 0x0BEA: -case 0x0DEA: -case 0x0FEA: -case 0x01EB: -case 0x03EB: -case 0x05EB: -case 0x07EB: -case 0x09EB: -case 0x0BEB: -case 0x0DEB: -case 0x0FEB: -case 0x01EC: -case 0x03EC: -case 0x05EC: -case 0x07EC: -case 0x09EC: -case 0x0BEC: -case 0x0DEC: -case 0x0FEC: -case 0x01ED: -case 0x03ED: -case 0x05ED: -case 0x07ED: -case 0x09ED: -case 0x0BED: -case 0x0DED: -case 0x0FED: -case 0x01EE: -case 0x03EE: -case 0x05EE: -case 0x07EE: -case 0x09EE: -case 0x0BEE: -case 0x0DEE: -case 0x0FEE: -case 0x01EF: -case 0x03EF: -case 0x05EF: -case 0x07EF: -case 0x09EF: -case 0x0BEF: -case 0x0DEF: -case 0x0FEF: - -// BSET -case 0x01E8: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x03F0: -case 0x05F0: -case 0x07F0: -case 0x09F0: -case 0x0BF0: -case 0x0DF0: -case 0x0FF0: -case 0x01F1: -case 0x03F1: -case 0x05F1: -case 0x07F1: -case 0x09F1: -case 0x0BF1: -case 0x0DF1: -case 0x0FF1: -case 0x01F2: -case 0x03F2: -case 0x05F2: -case 0x07F2: -case 0x09F2: -case 0x0BF2: -case 0x0DF2: -case 0x0FF2: -case 0x01F3: -case 0x03F3: -case 0x05F3: -case 0x07F3: -case 0x09F3: -case 0x0BF3: -case 0x0DF3: -case 0x0FF3: -case 0x01F4: -case 0x03F4: -case 0x05F4: -case 0x07F4: -case 0x09F4: -case 0x0BF4: -case 0x0DF4: -case 0x0FF4: -case 0x01F5: -case 0x03F5: -case 0x05F5: -case 0x07F5: -case 0x09F5: -case 0x0BF5: -case 0x0DF5: -case 0x0FF5: -case 0x01F6: -case 0x03F6: -case 0x05F6: -case 0x07F6: -case 0x09F6: -case 0x0BF6: -case 0x0DF6: -case 0x0FF6: -case 0x01F7: -case 0x03F7: -case 0x05F7: -case 0x07F7: -case 0x09F7: -case 0x0BF7: -case 0x0DF7: -case 0x0FF7: - -// BSET -case 0x01F0: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x03F8: -case 0x05F8: -case 0x07F8: -case 0x09F8: -case 0x0BF8: -case 0x0DF8: -case 0x0FF8: - -// BSET -case 0x01F8: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x03F9: -case 0x05F9: -case 0x07F9: -case 0x09F9: -case 0x0BF9: -case 0x0DF9: -case 0x0FF9: - -// BSET -case 0x01F9: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x03DF: -case 0x05DF: -case 0x07DF: -case 0x09DF: -case 0x0BDF: -case 0x0DDF: -case 0x0FDF: - -// BSET -case 0x01DF: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x03E7: -case 0x05E7: -case 0x07E7: -case 0x09E7: -case 0x0BE7: -case 0x0DE7: -case 0x0FE7: - -// BSET -case 0x01E7: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - src = 1 << (src & 7); - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_notZ = res & src; - res |= src; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x0308: -case 0x0508: -case 0x0708: -case 0x0908: -case 0x0B08: -case 0x0D08: -case 0x0F08: -case 0x0109: -case 0x0309: -case 0x0509: -case 0x0709: -case 0x0909: -case 0x0B09: -case 0x0D09: -case 0x0F09: -case 0x010A: -case 0x030A: -case 0x050A: -case 0x070A: -case 0x090A: -case 0x0B0A: -case 0x0D0A: -case 0x0F0A: -case 0x010B: -case 0x030B: -case 0x050B: -case 0x070B: -case 0x090B: -case 0x0B0B: -case 0x0D0B: -case 0x0F0B: -case 0x010C: -case 0x030C: -case 0x050C: -case 0x070C: -case 0x090C: -case 0x0B0C: -case 0x0D0C: -case 0x0F0C: -case 0x010D: -case 0x030D: -case 0x050D: -case 0x070D: -case 0x090D: -case 0x0B0D: -case 0x0D0D: -case 0x0F0D: -case 0x010E: -case 0x030E: -case 0x050E: -case 0x070E: -case 0x090E: -case 0x0B0E: -case 0x0D0E: -case 0x0F0E: -case 0x010F: -case 0x030F: -case 0x050F: -case 0x070F: -case 0x090F: -case 0x0B0F: -case 0x0D0F: -case 0x0F0F: - -// MOVEPWaD -case 0x0108: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr + 0, res) - READ_BYTE_F(adr + 2, src) - *(u16*)(&CPU->D[(Opcode >> 9) & 7]) = (res << 8) | src; - POST_IO -} -RET(24) -case 0x0348: -case 0x0548: -case 0x0748: -case 0x0948: -case 0x0B48: -case 0x0D48: -case 0x0F48: -case 0x0149: -case 0x0349: -case 0x0549: -case 0x0749: -case 0x0949: -case 0x0B49: -case 0x0D49: -case 0x0F49: -case 0x014A: -case 0x034A: -case 0x054A: -case 0x074A: -case 0x094A: -case 0x0B4A: -case 0x0D4A: -case 0x0F4A: -case 0x014B: -case 0x034B: -case 0x054B: -case 0x074B: -case 0x094B: -case 0x0B4B: -case 0x0D4B: -case 0x0F4B: -case 0x014C: -case 0x034C: -case 0x054C: -case 0x074C: -case 0x094C: -case 0x0B4C: -case 0x0D4C: -case 0x0F4C: -case 0x014D: -case 0x034D: -case 0x054D: -case 0x074D: -case 0x094D: -case 0x0B4D: -case 0x0D4D: -case 0x0F4D: -case 0x014E: -case 0x034E: -case 0x054E: -case 0x074E: -case 0x094E: -case 0x0B4E: -case 0x0D4E: -case 0x0F4E: -case 0x014F: -case 0x034F: -case 0x054F: -case 0x074F: -case 0x094F: -case 0x0B4F: -case 0x0D4F: -case 0x0F4F: - -// MOVEPLaD -case 0x0148: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res <<= 24; - adr += 2; - READ_BYTE_F(adr, src) - res |= src << 16; - adr += 2; - READ_BYTE_F(adr, src) - res |= src << 8; - adr += 2; - READ_BYTE_F(adr, src) - CPU->D[(Opcode >> 9) & 7] = res | src; - POST_IO -} -RET(32) -case 0x0388: -case 0x0588: -case 0x0788: -case 0x0988: -case 0x0B88: -case 0x0D88: -case 0x0F88: -case 0x0189: -case 0x0389: -case 0x0589: -case 0x0789: -case 0x0989: -case 0x0B89: -case 0x0D89: -case 0x0F89: -case 0x018A: -case 0x038A: -case 0x058A: -case 0x078A: -case 0x098A: -case 0x0B8A: -case 0x0D8A: -case 0x0F8A: -case 0x018B: -case 0x038B: -case 0x058B: -case 0x078B: -case 0x098B: -case 0x0B8B: -case 0x0D8B: -case 0x0F8B: -case 0x018C: -case 0x038C: -case 0x058C: -case 0x078C: -case 0x098C: -case 0x0B8C: -case 0x0D8C: -case 0x0F8C: -case 0x018D: -case 0x038D: -case 0x058D: -case 0x078D: -case 0x098D: -case 0x0B8D: -case 0x0D8D: -case 0x0F8D: -case 0x018E: -case 0x038E: -case 0x058E: -case 0x078E: -case 0x098E: -case 0x0B8E: -case 0x0D8E: -case 0x0F8E: -case 0x018F: -case 0x038F: -case 0x058F: -case 0x078F: -case 0x098F: -case 0x0B8F: -case 0x0D8F: -case 0x0F8F: - -// MOVEPWDa -case 0x0188: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_BYTE_F(adr + 0, res >> 8) - WRITE_BYTE_F(adr + 2, res >> 0) - POST_IO -} -RET(24) -case 0x03C8: -case 0x05C8: -case 0x07C8: -case 0x09C8: -case 0x0BC8: -case 0x0DC8: -case 0x0FC8: -case 0x01C9: -case 0x03C9: -case 0x05C9: -case 0x07C9: -case 0x09C9: -case 0x0BC9: -case 0x0DC9: -case 0x0FC9: -case 0x01CA: -case 0x03CA: -case 0x05CA: -case 0x07CA: -case 0x09CA: -case 0x0BCA: -case 0x0DCA: -case 0x0FCA: -case 0x01CB: -case 0x03CB: -case 0x05CB: -case 0x07CB: -case 0x09CB: -case 0x0BCB: -case 0x0DCB: -case 0x0FCB: -case 0x01CC: -case 0x03CC: -case 0x05CC: -case 0x07CC: -case 0x09CC: -case 0x0BCC: -case 0x0DCC: -case 0x0FCC: -case 0x01CD: -case 0x03CD: -case 0x05CD: -case 0x07CD: -case 0x09CD: -case 0x0BCD: -case 0x0DCD: -case 0x0FCD: -case 0x01CE: -case 0x03CE: -case 0x05CE: -case 0x07CE: -case 0x09CE: -case 0x0BCE: -case 0x0DCE: -case 0x0FCE: -case 0x01CF: -case 0x03CF: -case 0x05CF: -case 0x07CF: -case 0x09CF: -case 0x0BCF: -case 0x0DCF: -case 0x0FCF: - -// MOVEPLDa -case 0x01C8: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_BYTE_F(adr, res >> 24) - adr += 2; - WRITE_BYTE_F(adr, res >> 16) - adr += 2; - WRITE_BYTE_F(adr, res >> 8) - adr += 2; - WRITE_BYTE_F(adr, res >> 0) - POST_IO -} -RET(32) diff --git a/yabause/src/c68k/c68k_op1.inc b/yabause/src/c68k/c68k_op1.inc deleted file mode 100644 index 93694ed9db..0000000000 --- a/yabause/src/c68k/c68k_op1.inc +++ /dev/null @@ -1,5629 +0,0 @@ -case 0x1200: -case 0x1400: -case 0x1600: -case 0x1800: -case 0x1A00: -case 0x1C00: -case 0x1E00: -case 0x1001: -case 0x1201: -case 0x1401: -case 0x1601: -case 0x1801: -case 0x1A01: -case 0x1C01: -case 0x1E01: -case 0x1002: -case 0x1202: -case 0x1402: -case 0x1602: -case 0x1802: -case 0x1A02: -case 0x1C02: -case 0x1E02: -case 0x1003: -case 0x1203: -case 0x1403: -case 0x1603: -case 0x1803: -case 0x1A03: -case 0x1C03: -case 0x1E03: -case 0x1004: -case 0x1204: -case 0x1404: -case 0x1604: -case 0x1804: -case 0x1A04: -case 0x1C04: -case 0x1E04: -case 0x1005: -case 0x1205: -case 0x1405: -case 0x1605: -case 0x1805: -case 0x1A05: -case 0x1C05: -case 0x1E05: -case 0x1006: -case 0x1206: -case 0x1406: -case 0x1606: -case 0x1806: -case 0x1A06: -case 0x1C06: -case 0x1E06: -case 0x1007: -case 0x1207: -case 0x1407: -case 0x1607: -case 0x1807: -case 0x1A07: -case 0x1C07: -case 0x1E07: - -// MOVEB -case 0x1000: -{ - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x1280: -case 0x1480: -case 0x1680: -case 0x1880: -case 0x1A80: -case 0x1C80: -case 0x1E80: -case 0x1081: -case 0x1281: -case 0x1481: -case 0x1681: -case 0x1881: -case 0x1A81: -case 0x1C81: -case 0x1E81: -case 0x1082: -case 0x1282: -case 0x1482: -case 0x1682: -case 0x1882: -case 0x1A82: -case 0x1C82: -case 0x1E82: -case 0x1083: -case 0x1283: -case 0x1483: -case 0x1683: -case 0x1883: -case 0x1A83: -case 0x1C83: -case 0x1E83: -case 0x1084: -case 0x1284: -case 0x1484: -case 0x1684: -case 0x1884: -case 0x1A84: -case 0x1C84: -case 0x1E84: -case 0x1085: -case 0x1285: -case 0x1485: -case 0x1685: -case 0x1885: -case 0x1A85: -case 0x1C85: -case 0x1E85: -case 0x1086: -case 0x1286: -case 0x1486: -case 0x1686: -case 0x1886: -case 0x1A86: -case 0x1C86: -case 0x1E86: -case 0x1087: -case 0x1287: -case 0x1487: -case 0x1687: -case 0x1887: -case 0x1A87: -case 0x1C87: -case 0x1E87: - -// MOVEB -case 0x1080: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x12C0: -case 0x14C0: -case 0x16C0: -case 0x18C0: -case 0x1AC0: -case 0x1CC0: -case 0x10C1: -case 0x12C1: -case 0x14C1: -case 0x16C1: -case 0x18C1: -case 0x1AC1: -case 0x1CC1: -case 0x10C2: -case 0x12C2: -case 0x14C2: -case 0x16C2: -case 0x18C2: -case 0x1AC2: -case 0x1CC2: -case 0x10C3: -case 0x12C3: -case 0x14C3: -case 0x16C3: -case 0x18C3: -case 0x1AC3: -case 0x1CC3: -case 0x10C4: -case 0x12C4: -case 0x14C4: -case 0x16C4: -case 0x18C4: -case 0x1AC4: -case 0x1CC4: -case 0x10C5: -case 0x12C5: -case 0x14C5: -case 0x16C5: -case 0x18C5: -case 0x1AC5: -case 0x1CC5: -case 0x10C6: -case 0x12C6: -case 0x14C6: -case 0x16C6: -case 0x18C6: -case 0x1AC6: -case 0x1CC6: -case 0x10C7: -case 0x12C7: -case 0x14C7: -case 0x16C7: -case 0x18C7: -case 0x1AC7: -case 0x1CC7: - -// MOVEB -case 0x10C0: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x1300: -case 0x1500: -case 0x1700: -case 0x1900: -case 0x1B00: -case 0x1D00: -case 0x1101: -case 0x1301: -case 0x1501: -case 0x1701: -case 0x1901: -case 0x1B01: -case 0x1D01: -case 0x1102: -case 0x1302: -case 0x1502: -case 0x1702: -case 0x1902: -case 0x1B02: -case 0x1D02: -case 0x1103: -case 0x1303: -case 0x1503: -case 0x1703: -case 0x1903: -case 0x1B03: -case 0x1D03: -case 0x1104: -case 0x1304: -case 0x1504: -case 0x1704: -case 0x1904: -case 0x1B04: -case 0x1D04: -case 0x1105: -case 0x1305: -case 0x1505: -case 0x1705: -case 0x1905: -case 0x1B05: -case 0x1D05: -case 0x1106: -case 0x1306: -case 0x1506: -case 0x1706: -case 0x1906: -case 0x1B06: -case 0x1D06: -case 0x1107: -case 0x1307: -case 0x1507: -case 0x1707: -case 0x1907: -case 0x1B07: -case 0x1D07: - -// MOVEB -case 0x1100: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x1340: -case 0x1540: -case 0x1740: -case 0x1940: -case 0x1B40: -case 0x1D40: -case 0x1F40: -case 0x1141: -case 0x1341: -case 0x1541: -case 0x1741: -case 0x1941: -case 0x1B41: -case 0x1D41: -case 0x1F41: -case 0x1142: -case 0x1342: -case 0x1542: -case 0x1742: -case 0x1942: -case 0x1B42: -case 0x1D42: -case 0x1F42: -case 0x1143: -case 0x1343: -case 0x1543: -case 0x1743: -case 0x1943: -case 0x1B43: -case 0x1D43: -case 0x1F43: -case 0x1144: -case 0x1344: -case 0x1544: -case 0x1744: -case 0x1944: -case 0x1B44: -case 0x1D44: -case 0x1F44: -case 0x1145: -case 0x1345: -case 0x1545: -case 0x1745: -case 0x1945: -case 0x1B45: -case 0x1D45: -case 0x1F45: -case 0x1146: -case 0x1346: -case 0x1546: -case 0x1746: -case 0x1946: -case 0x1B46: -case 0x1D46: -case 0x1F46: -case 0x1147: -case 0x1347: -case 0x1547: -case 0x1747: -case 0x1947: -case 0x1B47: -case 0x1D47: -case 0x1F47: - -// MOVEB -case 0x1140: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1380: -case 0x1580: -case 0x1780: -case 0x1980: -case 0x1B80: -case 0x1D80: -case 0x1F80: -case 0x1181: -case 0x1381: -case 0x1581: -case 0x1781: -case 0x1981: -case 0x1B81: -case 0x1D81: -case 0x1F81: -case 0x1182: -case 0x1382: -case 0x1582: -case 0x1782: -case 0x1982: -case 0x1B82: -case 0x1D82: -case 0x1F82: -case 0x1183: -case 0x1383: -case 0x1583: -case 0x1783: -case 0x1983: -case 0x1B83: -case 0x1D83: -case 0x1F83: -case 0x1184: -case 0x1384: -case 0x1584: -case 0x1784: -case 0x1984: -case 0x1B84: -case 0x1D84: -case 0x1F84: -case 0x1185: -case 0x1385: -case 0x1585: -case 0x1785: -case 0x1985: -case 0x1B85: -case 0x1D85: -case 0x1F85: -case 0x1186: -case 0x1386: -case 0x1586: -case 0x1786: -case 0x1986: -case 0x1B86: -case 0x1D86: -case 0x1F86: -case 0x1187: -case 0x1387: -case 0x1587: -case 0x1787: -case 0x1987: -case 0x1B87: -case 0x1D87: -case 0x1F87: - -// MOVEB -case 0x1180: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x11C1: -case 0x11C2: -case 0x11C3: -case 0x11C4: -case 0x11C5: -case 0x11C6: -case 0x11C7: - -// MOVEB -case 0x11C0: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x13C1: -case 0x13C2: -case 0x13C3: -case 0x13C4: -case 0x13C5: -case 0x13C6: -case 0x13C7: - -// MOVEB -case 0x13C0: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1EC1: -case 0x1EC2: -case 0x1EC3: -case 0x1EC4: -case 0x1EC5: -case 0x1EC6: -case 0x1EC7: - -// MOVEB -case 0x1EC0: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x1F01: -case 0x1F02: -case 0x1F03: -case 0x1F04: -case 0x1F05: -case 0x1F06: -case 0x1F07: - -// MOVEB -case 0x1F00: -{ - u32 adr; - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x1208: -case 0x1408: -case 0x1608: -case 0x1808: -case 0x1A08: -case 0x1C08: -case 0x1E08: -case 0x1009: -case 0x1209: -case 0x1409: -case 0x1609: -case 0x1809: -case 0x1A09: -case 0x1C09: -case 0x1E09: -case 0x100A: -case 0x120A: -case 0x140A: -case 0x160A: -case 0x180A: -case 0x1A0A: -case 0x1C0A: -case 0x1E0A: -case 0x100B: -case 0x120B: -case 0x140B: -case 0x160B: -case 0x180B: -case 0x1A0B: -case 0x1C0B: -case 0x1E0B: -case 0x100C: -case 0x120C: -case 0x140C: -case 0x160C: -case 0x180C: -case 0x1A0C: -case 0x1C0C: -case 0x1E0C: -case 0x100D: -case 0x120D: -case 0x140D: -case 0x160D: -case 0x180D: -case 0x1A0D: -case 0x1C0D: -case 0x1E0D: -case 0x100E: -case 0x120E: -case 0x140E: -case 0x160E: -case 0x180E: -case 0x1A0E: -case 0x1C0E: -case 0x1E0E: -case 0x100F: -case 0x120F: -case 0x140F: -case 0x160F: -case 0x180F: -case 0x1A0F: -case 0x1C0F: -case 0x1E0F: - -// MOVEB -case 0x1008: -{ - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x1288: -case 0x1488: -case 0x1688: -case 0x1888: -case 0x1A88: -case 0x1C88: -case 0x1E88: -case 0x1089: -case 0x1289: -case 0x1489: -case 0x1689: -case 0x1889: -case 0x1A89: -case 0x1C89: -case 0x1E89: -case 0x108A: -case 0x128A: -case 0x148A: -case 0x168A: -case 0x188A: -case 0x1A8A: -case 0x1C8A: -case 0x1E8A: -case 0x108B: -case 0x128B: -case 0x148B: -case 0x168B: -case 0x188B: -case 0x1A8B: -case 0x1C8B: -case 0x1E8B: -case 0x108C: -case 0x128C: -case 0x148C: -case 0x168C: -case 0x188C: -case 0x1A8C: -case 0x1C8C: -case 0x1E8C: -case 0x108D: -case 0x128D: -case 0x148D: -case 0x168D: -case 0x188D: -case 0x1A8D: -case 0x1C8D: -case 0x1E8D: -case 0x108E: -case 0x128E: -case 0x148E: -case 0x168E: -case 0x188E: -case 0x1A8E: -case 0x1C8E: -case 0x1E8E: -case 0x108F: -case 0x128F: -case 0x148F: -case 0x168F: -case 0x188F: -case 0x1A8F: -case 0x1C8F: -case 0x1E8F: - -// MOVEB -case 0x1088: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x12C8: -case 0x14C8: -case 0x16C8: -case 0x18C8: -case 0x1AC8: -case 0x1CC8: -case 0x10C9: -case 0x12C9: -case 0x14C9: -case 0x16C9: -case 0x18C9: -case 0x1AC9: -case 0x1CC9: -case 0x10CA: -case 0x12CA: -case 0x14CA: -case 0x16CA: -case 0x18CA: -case 0x1ACA: -case 0x1CCA: -case 0x10CB: -case 0x12CB: -case 0x14CB: -case 0x16CB: -case 0x18CB: -case 0x1ACB: -case 0x1CCB: -case 0x10CC: -case 0x12CC: -case 0x14CC: -case 0x16CC: -case 0x18CC: -case 0x1ACC: -case 0x1CCC: -case 0x10CD: -case 0x12CD: -case 0x14CD: -case 0x16CD: -case 0x18CD: -case 0x1ACD: -case 0x1CCD: -case 0x10CE: -case 0x12CE: -case 0x14CE: -case 0x16CE: -case 0x18CE: -case 0x1ACE: -case 0x1CCE: -case 0x10CF: -case 0x12CF: -case 0x14CF: -case 0x16CF: -case 0x18CF: -case 0x1ACF: -case 0x1CCF: - -// MOVEB -case 0x10C8: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x1308: -case 0x1508: -case 0x1708: -case 0x1908: -case 0x1B08: -case 0x1D08: -case 0x1109: -case 0x1309: -case 0x1509: -case 0x1709: -case 0x1909: -case 0x1B09: -case 0x1D09: -case 0x110A: -case 0x130A: -case 0x150A: -case 0x170A: -case 0x190A: -case 0x1B0A: -case 0x1D0A: -case 0x110B: -case 0x130B: -case 0x150B: -case 0x170B: -case 0x190B: -case 0x1B0B: -case 0x1D0B: -case 0x110C: -case 0x130C: -case 0x150C: -case 0x170C: -case 0x190C: -case 0x1B0C: -case 0x1D0C: -case 0x110D: -case 0x130D: -case 0x150D: -case 0x170D: -case 0x190D: -case 0x1B0D: -case 0x1D0D: -case 0x110E: -case 0x130E: -case 0x150E: -case 0x170E: -case 0x190E: -case 0x1B0E: -case 0x1D0E: -case 0x110F: -case 0x130F: -case 0x150F: -case 0x170F: -case 0x190F: -case 0x1B0F: -case 0x1D0F: - -// MOVEB -case 0x1108: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x1348: -case 0x1548: -case 0x1748: -case 0x1948: -case 0x1B48: -case 0x1D48: -case 0x1F48: -case 0x1149: -case 0x1349: -case 0x1549: -case 0x1749: -case 0x1949: -case 0x1B49: -case 0x1D49: -case 0x1F49: -case 0x114A: -case 0x134A: -case 0x154A: -case 0x174A: -case 0x194A: -case 0x1B4A: -case 0x1D4A: -case 0x1F4A: -case 0x114B: -case 0x134B: -case 0x154B: -case 0x174B: -case 0x194B: -case 0x1B4B: -case 0x1D4B: -case 0x1F4B: -case 0x114C: -case 0x134C: -case 0x154C: -case 0x174C: -case 0x194C: -case 0x1B4C: -case 0x1D4C: -case 0x1F4C: -case 0x114D: -case 0x134D: -case 0x154D: -case 0x174D: -case 0x194D: -case 0x1B4D: -case 0x1D4D: -case 0x1F4D: -case 0x114E: -case 0x134E: -case 0x154E: -case 0x174E: -case 0x194E: -case 0x1B4E: -case 0x1D4E: -case 0x1F4E: -case 0x114F: -case 0x134F: -case 0x154F: -case 0x174F: -case 0x194F: -case 0x1B4F: -case 0x1D4F: -case 0x1F4F: - -// MOVEB -case 0x1148: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1388: -case 0x1588: -case 0x1788: -case 0x1988: -case 0x1B88: -case 0x1D88: -case 0x1F88: -case 0x1189: -case 0x1389: -case 0x1589: -case 0x1789: -case 0x1989: -case 0x1B89: -case 0x1D89: -case 0x1F89: -case 0x118A: -case 0x138A: -case 0x158A: -case 0x178A: -case 0x198A: -case 0x1B8A: -case 0x1D8A: -case 0x1F8A: -case 0x118B: -case 0x138B: -case 0x158B: -case 0x178B: -case 0x198B: -case 0x1B8B: -case 0x1D8B: -case 0x1F8B: -case 0x118C: -case 0x138C: -case 0x158C: -case 0x178C: -case 0x198C: -case 0x1B8C: -case 0x1D8C: -case 0x1F8C: -case 0x118D: -case 0x138D: -case 0x158D: -case 0x178D: -case 0x198D: -case 0x1B8D: -case 0x1D8D: -case 0x1F8D: -case 0x118E: -case 0x138E: -case 0x158E: -case 0x178E: -case 0x198E: -case 0x1B8E: -case 0x1D8E: -case 0x1F8E: -case 0x118F: -case 0x138F: -case 0x158F: -case 0x178F: -case 0x198F: -case 0x1B8F: -case 0x1D8F: -case 0x1F8F: - -// MOVEB -case 0x1188: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x11C9: -case 0x11CA: -case 0x11CB: -case 0x11CC: -case 0x11CD: -case 0x11CE: -case 0x11CF: - -// MOVEB -case 0x11C8: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x13C9: -case 0x13CA: -case 0x13CB: -case 0x13CC: -case 0x13CD: -case 0x13CE: -case 0x13CF: - -// MOVEB -case 0x13C8: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1EC9: -case 0x1ECA: -case 0x1ECB: -case 0x1ECC: -case 0x1ECD: -case 0x1ECE: -case 0x1ECF: - -// MOVEB -case 0x1EC8: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x1F09: -case 0x1F0A: -case 0x1F0B: -case 0x1F0C: -case 0x1F0D: -case 0x1F0E: -case 0x1F0F: - -// MOVEB -case 0x1F08: -{ - u32 adr; - u32 res; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x1210: -case 0x1410: -case 0x1610: -case 0x1810: -case 0x1A10: -case 0x1C10: -case 0x1E10: -case 0x1011: -case 0x1211: -case 0x1411: -case 0x1611: -case 0x1811: -case 0x1A11: -case 0x1C11: -case 0x1E11: -case 0x1012: -case 0x1212: -case 0x1412: -case 0x1612: -case 0x1812: -case 0x1A12: -case 0x1C12: -case 0x1E12: -case 0x1013: -case 0x1213: -case 0x1413: -case 0x1613: -case 0x1813: -case 0x1A13: -case 0x1C13: -case 0x1E13: -case 0x1014: -case 0x1214: -case 0x1414: -case 0x1614: -case 0x1814: -case 0x1A14: -case 0x1C14: -case 0x1E14: -case 0x1015: -case 0x1215: -case 0x1415: -case 0x1615: -case 0x1815: -case 0x1A15: -case 0x1C15: -case 0x1E15: -case 0x1016: -case 0x1216: -case 0x1416: -case 0x1616: -case 0x1816: -case 0x1A16: -case 0x1C16: -case 0x1E16: -case 0x1017: -case 0x1217: -case 0x1417: -case 0x1617: -case 0x1817: -case 0x1A17: -case 0x1C17: -case 0x1E17: - -// MOVEB -case 0x1010: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x1290: -case 0x1490: -case 0x1690: -case 0x1890: -case 0x1A90: -case 0x1C90: -case 0x1E90: -case 0x1091: -case 0x1291: -case 0x1491: -case 0x1691: -case 0x1891: -case 0x1A91: -case 0x1C91: -case 0x1E91: -case 0x1092: -case 0x1292: -case 0x1492: -case 0x1692: -case 0x1892: -case 0x1A92: -case 0x1C92: -case 0x1E92: -case 0x1093: -case 0x1293: -case 0x1493: -case 0x1693: -case 0x1893: -case 0x1A93: -case 0x1C93: -case 0x1E93: -case 0x1094: -case 0x1294: -case 0x1494: -case 0x1694: -case 0x1894: -case 0x1A94: -case 0x1C94: -case 0x1E94: -case 0x1095: -case 0x1295: -case 0x1495: -case 0x1695: -case 0x1895: -case 0x1A95: -case 0x1C95: -case 0x1E95: -case 0x1096: -case 0x1296: -case 0x1496: -case 0x1696: -case 0x1896: -case 0x1A96: -case 0x1C96: -case 0x1E96: -case 0x1097: -case 0x1297: -case 0x1497: -case 0x1697: -case 0x1897: -case 0x1A97: -case 0x1C97: -case 0x1E97: - -// MOVEB -case 0x1090: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x12D0: -case 0x14D0: -case 0x16D0: -case 0x18D0: -case 0x1AD0: -case 0x1CD0: -case 0x10D1: -case 0x12D1: -case 0x14D1: -case 0x16D1: -case 0x18D1: -case 0x1AD1: -case 0x1CD1: -case 0x10D2: -case 0x12D2: -case 0x14D2: -case 0x16D2: -case 0x18D2: -case 0x1AD2: -case 0x1CD2: -case 0x10D3: -case 0x12D3: -case 0x14D3: -case 0x16D3: -case 0x18D3: -case 0x1AD3: -case 0x1CD3: -case 0x10D4: -case 0x12D4: -case 0x14D4: -case 0x16D4: -case 0x18D4: -case 0x1AD4: -case 0x1CD4: -case 0x10D5: -case 0x12D5: -case 0x14D5: -case 0x16D5: -case 0x18D5: -case 0x1AD5: -case 0x1CD5: -case 0x10D6: -case 0x12D6: -case 0x14D6: -case 0x16D6: -case 0x18D6: -case 0x1AD6: -case 0x1CD6: -case 0x10D7: -case 0x12D7: -case 0x14D7: -case 0x16D7: -case 0x18D7: -case 0x1AD7: -case 0x1CD7: - -// MOVEB -case 0x10D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1310: -case 0x1510: -case 0x1710: -case 0x1910: -case 0x1B10: -case 0x1D10: -case 0x1111: -case 0x1311: -case 0x1511: -case 0x1711: -case 0x1911: -case 0x1B11: -case 0x1D11: -case 0x1112: -case 0x1312: -case 0x1512: -case 0x1712: -case 0x1912: -case 0x1B12: -case 0x1D12: -case 0x1113: -case 0x1313: -case 0x1513: -case 0x1713: -case 0x1913: -case 0x1B13: -case 0x1D13: -case 0x1114: -case 0x1314: -case 0x1514: -case 0x1714: -case 0x1914: -case 0x1B14: -case 0x1D14: -case 0x1115: -case 0x1315: -case 0x1515: -case 0x1715: -case 0x1915: -case 0x1B15: -case 0x1D15: -case 0x1116: -case 0x1316: -case 0x1516: -case 0x1716: -case 0x1916: -case 0x1B16: -case 0x1D16: -case 0x1117: -case 0x1317: -case 0x1517: -case 0x1717: -case 0x1917: -case 0x1B17: -case 0x1D17: - -// MOVEB -case 0x1110: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1350: -case 0x1550: -case 0x1750: -case 0x1950: -case 0x1B50: -case 0x1D50: -case 0x1F50: -case 0x1151: -case 0x1351: -case 0x1551: -case 0x1751: -case 0x1951: -case 0x1B51: -case 0x1D51: -case 0x1F51: -case 0x1152: -case 0x1352: -case 0x1552: -case 0x1752: -case 0x1952: -case 0x1B52: -case 0x1D52: -case 0x1F52: -case 0x1153: -case 0x1353: -case 0x1553: -case 0x1753: -case 0x1953: -case 0x1B53: -case 0x1D53: -case 0x1F53: -case 0x1154: -case 0x1354: -case 0x1554: -case 0x1754: -case 0x1954: -case 0x1B54: -case 0x1D54: -case 0x1F54: -case 0x1155: -case 0x1355: -case 0x1555: -case 0x1755: -case 0x1955: -case 0x1B55: -case 0x1D55: -case 0x1F55: -case 0x1156: -case 0x1356: -case 0x1556: -case 0x1756: -case 0x1956: -case 0x1B56: -case 0x1D56: -case 0x1F56: -case 0x1157: -case 0x1357: -case 0x1557: -case 0x1757: -case 0x1957: -case 0x1B57: -case 0x1D57: -case 0x1F57: - -// MOVEB -case 0x1150: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1390: -case 0x1590: -case 0x1790: -case 0x1990: -case 0x1B90: -case 0x1D90: -case 0x1F90: -case 0x1191: -case 0x1391: -case 0x1591: -case 0x1791: -case 0x1991: -case 0x1B91: -case 0x1D91: -case 0x1F91: -case 0x1192: -case 0x1392: -case 0x1592: -case 0x1792: -case 0x1992: -case 0x1B92: -case 0x1D92: -case 0x1F92: -case 0x1193: -case 0x1393: -case 0x1593: -case 0x1793: -case 0x1993: -case 0x1B93: -case 0x1D93: -case 0x1F93: -case 0x1194: -case 0x1394: -case 0x1594: -case 0x1794: -case 0x1994: -case 0x1B94: -case 0x1D94: -case 0x1F94: -case 0x1195: -case 0x1395: -case 0x1595: -case 0x1795: -case 0x1995: -case 0x1B95: -case 0x1D95: -case 0x1F95: -case 0x1196: -case 0x1396: -case 0x1596: -case 0x1796: -case 0x1996: -case 0x1B96: -case 0x1D96: -case 0x1F96: -case 0x1197: -case 0x1397: -case 0x1597: -case 0x1797: -case 0x1997: -case 0x1B97: -case 0x1D97: -case 0x1F97: - -// MOVEB -case 0x1190: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x11D1: -case 0x11D2: -case 0x11D3: -case 0x11D4: -case 0x11D5: -case 0x11D6: -case 0x11D7: - -// MOVEB -case 0x11D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x13D1: -case 0x13D2: -case 0x13D3: -case 0x13D4: -case 0x13D5: -case 0x13D6: -case 0x13D7: - -// MOVEB -case 0x13D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x1ED1: -case 0x1ED2: -case 0x1ED3: -case 0x1ED4: -case 0x1ED5: -case 0x1ED6: -case 0x1ED7: - -// MOVEB -case 0x1ED0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1F11: -case 0x1F12: -case 0x1F13: -case 0x1F14: -case 0x1F15: -case 0x1F16: -case 0x1F17: - -// MOVEB -case 0x1F10: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1218: -case 0x1418: -case 0x1618: -case 0x1818: -case 0x1A18: -case 0x1C18: -case 0x1E18: -case 0x1019: -case 0x1219: -case 0x1419: -case 0x1619: -case 0x1819: -case 0x1A19: -case 0x1C19: -case 0x1E19: -case 0x101A: -case 0x121A: -case 0x141A: -case 0x161A: -case 0x181A: -case 0x1A1A: -case 0x1C1A: -case 0x1E1A: -case 0x101B: -case 0x121B: -case 0x141B: -case 0x161B: -case 0x181B: -case 0x1A1B: -case 0x1C1B: -case 0x1E1B: -case 0x101C: -case 0x121C: -case 0x141C: -case 0x161C: -case 0x181C: -case 0x1A1C: -case 0x1C1C: -case 0x1E1C: -case 0x101D: -case 0x121D: -case 0x141D: -case 0x161D: -case 0x181D: -case 0x1A1D: -case 0x1C1D: -case 0x1E1D: -case 0x101E: -case 0x121E: -case 0x141E: -case 0x161E: -case 0x181E: -case 0x1A1E: -case 0x1C1E: -case 0x1E1E: - -// MOVEB -case 0x1018: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x1298: -case 0x1498: -case 0x1698: -case 0x1898: -case 0x1A98: -case 0x1C98: -case 0x1E98: -case 0x1099: -case 0x1299: -case 0x1499: -case 0x1699: -case 0x1899: -case 0x1A99: -case 0x1C99: -case 0x1E99: -case 0x109A: -case 0x129A: -case 0x149A: -case 0x169A: -case 0x189A: -case 0x1A9A: -case 0x1C9A: -case 0x1E9A: -case 0x109B: -case 0x129B: -case 0x149B: -case 0x169B: -case 0x189B: -case 0x1A9B: -case 0x1C9B: -case 0x1E9B: -case 0x109C: -case 0x129C: -case 0x149C: -case 0x169C: -case 0x189C: -case 0x1A9C: -case 0x1C9C: -case 0x1E9C: -case 0x109D: -case 0x129D: -case 0x149D: -case 0x169D: -case 0x189D: -case 0x1A9D: -case 0x1C9D: -case 0x1E9D: -case 0x109E: -case 0x129E: -case 0x149E: -case 0x169E: -case 0x189E: -case 0x1A9E: -case 0x1C9E: -case 0x1E9E: - -// MOVEB -case 0x1098: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x12D8: -case 0x14D8: -case 0x16D8: -case 0x18D8: -case 0x1AD8: -case 0x1CD8: -case 0x10D9: -case 0x12D9: -case 0x14D9: -case 0x16D9: -case 0x18D9: -case 0x1AD9: -case 0x1CD9: -case 0x10DA: -case 0x12DA: -case 0x14DA: -case 0x16DA: -case 0x18DA: -case 0x1ADA: -case 0x1CDA: -case 0x10DB: -case 0x12DB: -case 0x14DB: -case 0x16DB: -case 0x18DB: -case 0x1ADB: -case 0x1CDB: -case 0x10DC: -case 0x12DC: -case 0x14DC: -case 0x16DC: -case 0x18DC: -case 0x1ADC: -case 0x1CDC: -case 0x10DD: -case 0x12DD: -case 0x14DD: -case 0x16DD: -case 0x18DD: -case 0x1ADD: -case 0x1CDD: -case 0x10DE: -case 0x12DE: -case 0x14DE: -case 0x16DE: -case 0x18DE: -case 0x1ADE: -case 0x1CDE: - -// MOVEB -case 0x10D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1318: -case 0x1518: -case 0x1718: -case 0x1918: -case 0x1B18: -case 0x1D18: -case 0x1119: -case 0x1319: -case 0x1519: -case 0x1719: -case 0x1919: -case 0x1B19: -case 0x1D19: -case 0x111A: -case 0x131A: -case 0x151A: -case 0x171A: -case 0x191A: -case 0x1B1A: -case 0x1D1A: -case 0x111B: -case 0x131B: -case 0x151B: -case 0x171B: -case 0x191B: -case 0x1B1B: -case 0x1D1B: -case 0x111C: -case 0x131C: -case 0x151C: -case 0x171C: -case 0x191C: -case 0x1B1C: -case 0x1D1C: -case 0x111D: -case 0x131D: -case 0x151D: -case 0x171D: -case 0x191D: -case 0x1B1D: -case 0x1D1D: -case 0x111E: -case 0x131E: -case 0x151E: -case 0x171E: -case 0x191E: -case 0x1B1E: -case 0x1D1E: - -// MOVEB -case 0x1118: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1358: -case 0x1558: -case 0x1758: -case 0x1958: -case 0x1B58: -case 0x1D58: -case 0x1F58: -case 0x1159: -case 0x1359: -case 0x1559: -case 0x1759: -case 0x1959: -case 0x1B59: -case 0x1D59: -case 0x1F59: -case 0x115A: -case 0x135A: -case 0x155A: -case 0x175A: -case 0x195A: -case 0x1B5A: -case 0x1D5A: -case 0x1F5A: -case 0x115B: -case 0x135B: -case 0x155B: -case 0x175B: -case 0x195B: -case 0x1B5B: -case 0x1D5B: -case 0x1F5B: -case 0x115C: -case 0x135C: -case 0x155C: -case 0x175C: -case 0x195C: -case 0x1B5C: -case 0x1D5C: -case 0x1F5C: -case 0x115D: -case 0x135D: -case 0x155D: -case 0x175D: -case 0x195D: -case 0x1B5D: -case 0x1D5D: -case 0x1F5D: -case 0x115E: -case 0x135E: -case 0x155E: -case 0x175E: -case 0x195E: -case 0x1B5E: -case 0x1D5E: -case 0x1F5E: - -// MOVEB -case 0x1158: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1398: -case 0x1598: -case 0x1798: -case 0x1998: -case 0x1B98: -case 0x1D98: -case 0x1F98: -case 0x1199: -case 0x1399: -case 0x1599: -case 0x1799: -case 0x1999: -case 0x1B99: -case 0x1D99: -case 0x1F99: -case 0x119A: -case 0x139A: -case 0x159A: -case 0x179A: -case 0x199A: -case 0x1B9A: -case 0x1D9A: -case 0x1F9A: -case 0x119B: -case 0x139B: -case 0x159B: -case 0x179B: -case 0x199B: -case 0x1B9B: -case 0x1D9B: -case 0x1F9B: -case 0x119C: -case 0x139C: -case 0x159C: -case 0x179C: -case 0x199C: -case 0x1B9C: -case 0x1D9C: -case 0x1F9C: -case 0x119D: -case 0x139D: -case 0x159D: -case 0x179D: -case 0x199D: -case 0x1B9D: -case 0x1D9D: -case 0x1F9D: -case 0x119E: -case 0x139E: -case 0x159E: -case 0x179E: -case 0x199E: -case 0x1B9E: -case 0x1D9E: -case 0x1F9E: - -// MOVEB -case 0x1198: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x11D9: -case 0x11DA: -case 0x11DB: -case 0x11DC: -case 0x11DD: -case 0x11DE: - -// MOVEB -case 0x11D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x13D9: -case 0x13DA: -case 0x13DB: -case 0x13DC: -case 0x13DD: -case 0x13DE: - -// MOVEB -case 0x13D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x1ED9: -case 0x1EDA: -case 0x1EDB: -case 0x1EDC: -case 0x1EDD: -case 0x1EDE: - -// MOVEB -case 0x1ED8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1F19: -case 0x1F1A: -case 0x1F1B: -case 0x1F1C: -case 0x1F1D: -case 0x1F1E: - -// MOVEB -case 0x1F18: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1220: -case 0x1420: -case 0x1620: -case 0x1820: -case 0x1A20: -case 0x1C20: -case 0x1E20: -case 0x1021: -case 0x1221: -case 0x1421: -case 0x1621: -case 0x1821: -case 0x1A21: -case 0x1C21: -case 0x1E21: -case 0x1022: -case 0x1222: -case 0x1422: -case 0x1622: -case 0x1822: -case 0x1A22: -case 0x1C22: -case 0x1E22: -case 0x1023: -case 0x1223: -case 0x1423: -case 0x1623: -case 0x1823: -case 0x1A23: -case 0x1C23: -case 0x1E23: -case 0x1024: -case 0x1224: -case 0x1424: -case 0x1624: -case 0x1824: -case 0x1A24: -case 0x1C24: -case 0x1E24: -case 0x1025: -case 0x1225: -case 0x1425: -case 0x1625: -case 0x1825: -case 0x1A25: -case 0x1C25: -case 0x1E25: -case 0x1026: -case 0x1226: -case 0x1426: -case 0x1626: -case 0x1826: -case 0x1A26: -case 0x1C26: -case 0x1E26: - -// MOVEB -case 0x1020: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x12A0: -case 0x14A0: -case 0x16A0: -case 0x18A0: -case 0x1AA0: -case 0x1CA0: -case 0x1EA0: -case 0x10A1: -case 0x12A1: -case 0x14A1: -case 0x16A1: -case 0x18A1: -case 0x1AA1: -case 0x1CA1: -case 0x1EA1: -case 0x10A2: -case 0x12A2: -case 0x14A2: -case 0x16A2: -case 0x18A2: -case 0x1AA2: -case 0x1CA2: -case 0x1EA2: -case 0x10A3: -case 0x12A3: -case 0x14A3: -case 0x16A3: -case 0x18A3: -case 0x1AA3: -case 0x1CA3: -case 0x1EA3: -case 0x10A4: -case 0x12A4: -case 0x14A4: -case 0x16A4: -case 0x18A4: -case 0x1AA4: -case 0x1CA4: -case 0x1EA4: -case 0x10A5: -case 0x12A5: -case 0x14A5: -case 0x16A5: -case 0x18A5: -case 0x1AA5: -case 0x1CA5: -case 0x1EA5: -case 0x10A6: -case 0x12A6: -case 0x14A6: -case 0x16A6: -case 0x18A6: -case 0x1AA6: -case 0x1CA6: -case 0x1EA6: - -// MOVEB -case 0x10A0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x12E0: -case 0x14E0: -case 0x16E0: -case 0x18E0: -case 0x1AE0: -case 0x1CE0: -case 0x10E1: -case 0x12E1: -case 0x14E1: -case 0x16E1: -case 0x18E1: -case 0x1AE1: -case 0x1CE1: -case 0x10E2: -case 0x12E2: -case 0x14E2: -case 0x16E2: -case 0x18E2: -case 0x1AE2: -case 0x1CE2: -case 0x10E3: -case 0x12E3: -case 0x14E3: -case 0x16E3: -case 0x18E3: -case 0x1AE3: -case 0x1CE3: -case 0x10E4: -case 0x12E4: -case 0x14E4: -case 0x16E4: -case 0x18E4: -case 0x1AE4: -case 0x1CE4: -case 0x10E5: -case 0x12E5: -case 0x14E5: -case 0x16E5: -case 0x18E5: -case 0x1AE5: -case 0x1CE5: -case 0x10E6: -case 0x12E6: -case 0x14E6: -case 0x16E6: -case 0x18E6: -case 0x1AE6: -case 0x1CE6: - -// MOVEB -case 0x10E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x1320: -case 0x1520: -case 0x1720: -case 0x1920: -case 0x1B20: -case 0x1D20: -case 0x1121: -case 0x1321: -case 0x1521: -case 0x1721: -case 0x1921: -case 0x1B21: -case 0x1D21: -case 0x1122: -case 0x1322: -case 0x1522: -case 0x1722: -case 0x1922: -case 0x1B22: -case 0x1D22: -case 0x1123: -case 0x1323: -case 0x1523: -case 0x1723: -case 0x1923: -case 0x1B23: -case 0x1D23: -case 0x1124: -case 0x1324: -case 0x1524: -case 0x1724: -case 0x1924: -case 0x1B24: -case 0x1D24: -case 0x1125: -case 0x1325: -case 0x1525: -case 0x1725: -case 0x1925: -case 0x1B25: -case 0x1D25: -case 0x1126: -case 0x1326: -case 0x1526: -case 0x1726: -case 0x1926: -case 0x1B26: -case 0x1D26: - -// MOVEB -case 0x1120: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x1360: -case 0x1560: -case 0x1760: -case 0x1960: -case 0x1B60: -case 0x1D60: -case 0x1F60: -case 0x1161: -case 0x1361: -case 0x1561: -case 0x1761: -case 0x1961: -case 0x1B61: -case 0x1D61: -case 0x1F61: -case 0x1162: -case 0x1362: -case 0x1562: -case 0x1762: -case 0x1962: -case 0x1B62: -case 0x1D62: -case 0x1F62: -case 0x1163: -case 0x1363: -case 0x1563: -case 0x1763: -case 0x1963: -case 0x1B63: -case 0x1D63: -case 0x1F63: -case 0x1164: -case 0x1364: -case 0x1564: -case 0x1764: -case 0x1964: -case 0x1B64: -case 0x1D64: -case 0x1F64: -case 0x1165: -case 0x1365: -case 0x1565: -case 0x1765: -case 0x1965: -case 0x1B65: -case 0x1D65: -case 0x1F65: -case 0x1166: -case 0x1366: -case 0x1566: -case 0x1766: -case 0x1966: -case 0x1B66: -case 0x1D66: -case 0x1F66: - -// MOVEB -case 0x1160: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x13A0: -case 0x15A0: -case 0x17A0: -case 0x19A0: -case 0x1BA0: -case 0x1DA0: -case 0x1FA0: -case 0x11A1: -case 0x13A1: -case 0x15A1: -case 0x17A1: -case 0x19A1: -case 0x1BA1: -case 0x1DA1: -case 0x1FA1: -case 0x11A2: -case 0x13A2: -case 0x15A2: -case 0x17A2: -case 0x19A2: -case 0x1BA2: -case 0x1DA2: -case 0x1FA2: -case 0x11A3: -case 0x13A3: -case 0x15A3: -case 0x17A3: -case 0x19A3: -case 0x1BA3: -case 0x1DA3: -case 0x1FA3: -case 0x11A4: -case 0x13A4: -case 0x15A4: -case 0x17A4: -case 0x19A4: -case 0x1BA4: -case 0x1DA4: -case 0x1FA4: -case 0x11A5: -case 0x13A5: -case 0x15A5: -case 0x17A5: -case 0x19A5: -case 0x1BA5: -case 0x1DA5: -case 0x1FA5: -case 0x11A6: -case 0x13A6: -case 0x15A6: -case 0x17A6: -case 0x19A6: -case 0x1BA6: -case 0x1DA6: -case 0x1FA6: - -// MOVEB -case 0x11A0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x11E1: -case 0x11E2: -case 0x11E3: -case 0x11E4: -case 0x11E5: -case 0x11E6: - -// MOVEB -case 0x11E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x13E1: -case 0x13E2: -case 0x13E3: -case 0x13E4: -case 0x13E5: -case 0x13E6: - -// MOVEB -case 0x13E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) -case 0x1EE1: -case 0x1EE2: -case 0x1EE3: -case 0x1EE4: -case 0x1EE5: -case 0x1EE6: - -// MOVEB -case 0x1EE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x1F21: -case 0x1F22: -case 0x1F23: -case 0x1F24: -case 0x1F25: -case 0x1F26: - -// MOVEB -case 0x1F20: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x1228: -case 0x1428: -case 0x1628: -case 0x1828: -case 0x1A28: -case 0x1C28: -case 0x1E28: -case 0x1029: -case 0x1229: -case 0x1429: -case 0x1629: -case 0x1829: -case 0x1A29: -case 0x1C29: -case 0x1E29: -case 0x102A: -case 0x122A: -case 0x142A: -case 0x162A: -case 0x182A: -case 0x1A2A: -case 0x1C2A: -case 0x1E2A: -case 0x102B: -case 0x122B: -case 0x142B: -case 0x162B: -case 0x182B: -case 0x1A2B: -case 0x1C2B: -case 0x1E2B: -case 0x102C: -case 0x122C: -case 0x142C: -case 0x162C: -case 0x182C: -case 0x1A2C: -case 0x1C2C: -case 0x1E2C: -case 0x102D: -case 0x122D: -case 0x142D: -case 0x162D: -case 0x182D: -case 0x1A2D: -case 0x1C2D: -case 0x1E2D: -case 0x102E: -case 0x122E: -case 0x142E: -case 0x162E: -case 0x182E: -case 0x1A2E: -case 0x1C2E: -case 0x1E2E: -case 0x102F: -case 0x122F: -case 0x142F: -case 0x162F: -case 0x182F: -case 0x1A2F: -case 0x1C2F: -case 0x1E2F: - -// MOVEB -case 0x1028: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x12A8: -case 0x14A8: -case 0x16A8: -case 0x18A8: -case 0x1AA8: -case 0x1CA8: -case 0x1EA8: -case 0x10A9: -case 0x12A9: -case 0x14A9: -case 0x16A9: -case 0x18A9: -case 0x1AA9: -case 0x1CA9: -case 0x1EA9: -case 0x10AA: -case 0x12AA: -case 0x14AA: -case 0x16AA: -case 0x18AA: -case 0x1AAA: -case 0x1CAA: -case 0x1EAA: -case 0x10AB: -case 0x12AB: -case 0x14AB: -case 0x16AB: -case 0x18AB: -case 0x1AAB: -case 0x1CAB: -case 0x1EAB: -case 0x10AC: -case 0x12AC: -case 0x14AC: -case 0x16AC: -case 0x18AC: -case 0x1AAC: -case 0x1CAC: -case 0x1EAC: -case 0x10AD: -case 0x12AD: -case 0x14AD: -case 0x16AD: -case 0x18AD: -case 0x1AAD: -case 0x1CAD: -case 0x1EAD: -case 0x10AE: -case 0x12AE: -case 0x14AE: -case 0x16AE: -case 0x18AE: -case 0x1AAE: -case 0x1CAE: -case 0x1EAE: -case 0x10AF: -case 0x12AF: -case 0x14AF: -case 0x16AF: -case 0x18AF: -case 0x1AAF: -case 0x1CAF: -case 0x1EAF: - -// MOVEB -case 0x10A8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x12E8: -case 0x14E8: -case 0x16E8: -case 0x18E8: -case 0x1AE8: -case 0x1CE8: -case 0x10E9: -case 0x12E9: -case 0x14E9: -case 0x16E9: -case 0x18E9: -case 0x1AE9: -case 0x1CE9: -case 0x10EA: -case 0x12EA: -case 0x14EA: -case 0x16EA: -case 0x18EA: -case 0x1AEA: -case 0x1CEA: -case 0x10EB: -case 0x12EB: -case 0x14EB: -case 0x16EB: -case 0x18EB: -case 0x1AEB: -case 0x1CEB: -case 0x10EC: -case 0x12EC: -case 0x14EC: -case 0x16EC: -case 0x18EC: -case 0x1AEC: -case 0x1CEC: -case 0x10ED: -case 0x12ED: -case 0x14ED: -case 0x16ED: -case 0x18ED: -case 0x1AED: -case 0x1CED: -case 0x10EE: -case 0x12EE: -case 0x14EE: -case 0x16EE: -case 0x18EE: -case 0x1AEE: -case 0x1CEE: -case 0x10EF: -case 0x12EF: -case 0x14EF: -case 0x16EF: -case 0x18EF: -case 0x1AEF: -case 0x1CEF: - -// MOVEB -case 0x10E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1328: -case 0x1528: -case 0x1728: -case 0x1928: -case 0x1B28: -case 0x1D28: -case 0x1129: -case 0x1329: -case 0x1529: -case 0x1729: -case 0x1929: -case 0x1B29: -case 0x1D29: -case 0x112A: -case 0x132A: -case 0x152A: -case 0x172A: -case 0x192A: -case 0x1B2A: -case 0x1D2A: -case 0x112B: -case 0x132B: -case 0x152B: -case 0x172B: -case 0x192B: -case 0x1B2B: -case 0x1D2B: -case 0x112C: -case 0x132C: -case 0x152C: -case 0x172C: -case 0x192C: -case 0x1B2C: -case 0x1D2C: -case 0x112D: -case 0x132D: -case 0x152D: -case 0x172D: -case 0x192D: -case 0x1B2D: -case 0x1D2D: -case 0x112E: -case 0x132E: -case 0x152E: -case 0x172E: -case 0x192E: -case 0x1B2E: -case 0x1D2E: -case 0x112F: -case 0x132F: -case 0x152F: -case 0x172F: -case 0x192F: -case 0x1B2F: -case 0x1D2F: - -// MOVEB -case 0x1128: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1368: -case 0x1568: -case 0x1768: -case 0x1968: -case 0x1B68: -case 0x1D68: -case 0x1F68: -case 0x1169: -case 0x1369: -case 0x1569: -case 0x1769: -case 0x1969: -case 0x1B69: -case 0x1D69: -case 0x1F69: -case 0x116A: -case 0x136A: -case 0x156A: -case 0x176A: -case 0x196A: -case 0x1B6A: -case 0x1D6A: -case 0x1F6A: -case 0x116B: -case 0x136B: -case 0x156B: -case 0x176B: -case 0x196B: -case 0x1B6B: -case 0x1D6B: -case 0x1F6B: -case 0x116C: -case 0x136C: -case 0x156C: -case 0x176C: -case 0x196C: -case 0x1B6C: -case 0x1D6C: -case 0x1F6C: -case 0x116D: -case 0x136D: -case 0x156D: -case 0x176D: -case 0x196D: -case 0x1B6D: -case 0x1D6D: -case 0x1F6D: -case 0x116E: -case 0x136E: -case 0x156E: -case 0x176E: -case 0x196E: -case 0x1B6E: -case 0x1D6E: -case 0x1F6E: -case 0x116F: -case 0x136F: -case 0x156F: -case 0x176F: -case 0x196F: -case 0x1B6F: -case 0x1D6F: -case 0x1F6F: - -// MOVEB -case 0x1168: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x13A8: -case 0x15A8: -case 0x17A8: -case 0x19A8: -case 0x1BA8: -case 0x1DA8: -case 0x1FA8: -case 0x11A9: -case 0x13A9: -case 0x15A9: -case 0x17A9: -case 0x19A9: -case 0x1BA9: -case 0x1DA9: -case 0x1FA9: -case 0x11AA: -case 0x13AA: -case 0x15AA: -case 0x17AA: -case 0x19AA: -case 0x1BAA: -case 0x1DAA: -case 0x1FAA: -case 0x11AB: -case 0x13AB: -case 0x15AB: -case 0x17AB: -case 0x19AB: -case 0x1BAB: -case 0x1DAB: -case 0x1FAB: -case 0x11AC: -case 0x13AC: -case 0x15AC: -case 0x17AC: -case 0x19AC: -case 0x1BAC: -case 0x1DAC: -case 0x1FAC: -case 0x11AD: -case 0x13AD: -case 0x15AD: -case 0x17AD: -case 0x19AD: -case 0x1BAD: -case 0x1DAD: -case 0x1FAD: -case 0x11AE: -case 0x13AE: -case 0x15AE: -case 0x17AE: -case 0x19AE: -case 0x1BAE: -case 0x1DAE: -case 0x1FAE: -case 0x11AF: -case 0x13AF: -case 0x15AF: -case 0x17AF: -case 0x19AF: -case 0x1BAF: -case 0x1DAF: -case 0x1FAF: - -// MOVEB -case 0x11A8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) -case 0x11E9: -case 0x11EA: -case 0x11EB: -case 0x11EC: -case 0x11ED: -case 0x11EE: -case 0x11EF: - -// MOVEB -case 0x11E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x13E9: -case 0x13EA: -case 0x13EB: -case 0x13EC: -case 0x13ED: -case 0x13EE: -case 0x13EF: - -// MOVEB -case 0x13E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) -case 0x1EE9: -case 0x1EEA: -case 0x1EEB: -case 0x1EEC: -case 0x1EED: -case 0x1EEE: -case 0x1EEF: - -// MOVEB -case 0x1EE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1F29: -case 0x1F2A: -case 0x1F2B: -case 0x1F2C: -case 0x1F2D: -case 0x1F2E: -case 0x1F2F: - -// MOVEB -case 0x1F28: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1230: -case 0x1430: -case 0x1630: -case 0x1830: -case 0x1A30: -case 0x1C30: -case 0x1E30: -case 0x1031: -case 0x1231: -case 0x1431: -case 0x1631: -case 0x1831: -case 0x1A31: -case 0x1C31: -case 0x1E31: -case 0x1032: -case 0x1232: -case 0x1432: -case 0x1632: -case 0x1832: -case 0x1A32: -case 0x1C32: -case 0x1E32: -case 0x1033: -case 0x1233: -case 0x1433: -case 0x1633: -case 0x1833: -case 0x1A33: -case 0x1C33: -case 0x1E33: -case 0x1034: -case 0x1234: -case 0x1434: -case 0x1634: -case 0x1834: -case 0x1A34: -case 0x1C34: -case 0x1E34: -case 0x1035: -case 0x1235: -case 0x1435: -case 0x1635: -case 0x1835: -case 0x1A35: -case 0x1C35: -case 0x1E35: -case 0x1036: -case 0x1236: -case 0x1436: -case 0x1636: -case 0x1836: -case 0x1A36: -case 0x1C36: -case 0x1E36: -case 0x1037: -case 0x1237: -case 0x1437: -case 0x1637: -case 0x1837: -case 0x1A37: -case 0x1C37: -case 0x1E37: - -// MOVEB -case 0x1030: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x12B0: -case 0x14B0: -case 0x16B0: -case 0x18B0: -case 0x1AB0: -case 0x1CB0: -case 0x1EB0: -case 0x10B1: -case 0x12B1: -case 0x14B1: -case 0x16B1: -case 0x18B1: -case 0x1AB1: -case 0x1CB1: -case 0x1EB1: -case 0x10B2: -case 0x12B2: -case 0x14B2: -case 0x16B2: -case 0x18B2: -case 0x1AB2: -case 0x1CB2: -case 0x1EB2: -case 0x10B3: -case 0x12B3: -case 0x14B3: -case 0x16B3: -case 0x18B3: -case 0x1AB3: -case 0x1CB3: -case 0x1EB3: -case 0x10B4: -case 0x12B4: -case 0x14B4: -case 0x16B4: -case 0x18B4: -case 0x1AB4: -case 0x1CB4: -case 0x1EB4: -case 0x10B5: -case 0x12B5: -case 0x14B5: -case 0x16B5: -case 0x18B5: -case 0x1AB5: -case 0x1CB5: -case 0x1EB5: -case 0x10B6: -case 0x12B6: -case 0x14B6: -case 0x16B6: -case 0x18B6: -case 0x1AB6: -case 0x1CB6: -case 0x1EB6: -case 0x10B7: -case 0x12B7: -case 0x14B7: -case 0x16B7: -case 0x18B7: -case 0x1AB7: -case 0x1CB7: -case 0x1EB7: - -// MOVEB -case 0x10B0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x12F0: -case 0x14F0: -case 0x16F0: -case 0x18F0: -case 0x1AF0: -case 0x1CF0: -case 0x10F1: -case 0x12F1: -case 0x14F1: -case 0x16F1: -case 0x18F1: -case 0x1AF1: -case 0x1CF1: -case 0x10F2: -case 0x12F2: -case 0x14F2: -case 0x16F2: -case 0x18F2: -case 0x1AF2: -case 0x1CF2: -case 0x10F3: -case 0x12F3: -case 0x14F3: -case 0x16F3: -case 0x18F3: -case 0x1AF3: -case 0x1CF3: -case 0x10F4: -case 0x12F4: -case 0x14F4: -case 0x16F4: -case 0x18F4: -case 0x1AF4: -case 0x1CF4: -case 0x10F5: -case 0x12F5: -case 0x14F5: -case 0x16F5: -case 0x18F5: -case 0x1AF5: -case 0x1CF5: -case 0x10F6: -case 0x12F6: -case 0x14F6: -case 0x16F6: -case 0x18F6: -case 0x1AF6: -case 0x1CF6: -case 0x10F7: -case 0x12F7: -case 0x14F7: -case 0x16F7: -case 0x18F7: -case 0x1AF7: -case 0x1CF7: - -// MOVEB -case 0x10F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x1330: -case 0x1530: -case 0x1730: -case 0x1930: -case 0x1B30: -case 0x1D30: -case 0x1131: -case 0x1331: -case 0x1531: -case 0x1731: -case 0x1931: -case 0x1B31: -case 0x1D31: -case 0x1132: -case 0x1332: -case 0x1532: -case 0x1732: -case 0x1932: -case 0x1B32: -case 0x1D32: -case 0x1133: -case 0x1333: -case 0x1533: -case 0x1733: -case 0x1933: -case 0x1B33: -case 0x1D33: -case 0x1134: -case 0x1334: -case 0x1534: -case 0x1734: -case 0x1934: -case 0x1B34: -case 0x1D34: -case 0x1135: -case 0x1335: -case 0x1535: -case 0x1735: -case 0x1935: -case 0x1B35: -case 0x1D35: -case 0x1136: -case 0x1336: -case 0x1536: -case 0x1736: -case 0x1936: -case 0x1B36: -case 0x1D36: -case 0x1137: -case 0x1337: -case 0x1537: -case 0x1737: -case 0x1937: -case 0x1B37: -case 0x1D37: - -// MOVEB -case 0x1130: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x1370: -case 0x1570: -case 0x1770: -case 0x1970: -case 0x1B70: -case 0x1D70: -case 0x1F70: -case 0x1171: -case 0x1371: -case 0x1571: -case 0x1771: -case 0x1971: -case 0x1B71: -case 0x1D71: -case 0x1F71: -case 0x1172: -case 0x1372: -case 0x1572: -case 0x1772: -case 0x1972: -case 0x1B72: -case 0x1D72: -case 0x1F72: -case 0x1173: -case 0x1373: -case 0x1573: -case 0x1773: -case 0x1973: -case 0x1B73: -case 0x1D73: -case 0x1F73: -case 0x1174: -case 0x1374: -case 0x1574: -case 0x1774: -case 0x1974: -case 0x1B74: -case 0x1D74: -case 0x1F74: -case 0x1175: -case 0x1375: -case 0x1575: -case 0x1775: -case 0x1975: -case 0x1B75: -case 0x1D75: -case 0x1F75: -case 0x1176: -case 0x1376: -case 0x1576: -case 0x1776: -case 0x1976: -case 0x1B76: -case 0x1D76: -case 0x1F76: -case 0x1177: -case 0x1377: -case 0x1577: -case 0x1777: -case 0x1977: -case 0x1B77: -case 0x1D77: -case 0x1F77: - -// MOVEB -case 0x1170: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) -case 0x13B0: -case 0x15B0: -case 0x17B0: -case 0x19B0: -case 0x1BB0: -case 0x1DB0: -case 0x1FB0: -case 0x11B1: -case 0x13B1: -case 0x15B1: -case 0x17B1: -case 0x19B1: -case 0x1BB1: -case 0x1DB1: -case 0x1FB1: -case 0x11B2: -case 0x13B2: -case 0x15B2: -case 0x17B2: -case 0x19B2: -case 0x1BB2: -case 0x1DB2: -case 0x1FB2: -case 0x11B3: -case 0x13B3: -case 0x15B3: -case 0x17B3: -case 0x19B3: -case 0x1BB3: -case 0x1DB3: -case 0x1FB3: -case 0x11B4: -case 0x13B4: -case 0x15B4: -case 0x17B4: -case 0x19B4: -case 0x1BB4: -case 0x1DB4: -case 0x1FB4: -case 0x11B5: -case 0x13B5: -case 0x15B5: -case 0x17B5: -case 0x19B5: -case 0x1BB5: -case 0x1DB5: -case 0x1FB5: -case 0x11B6: -case 0x13B6: -case 0x15B6: -case 0x17B6: -case 0x19B6: -case 0x1BB6: -case 0x1DB6: -case 0x1FB6: -case 0x11B7: -case 0x13B7: -case 0x15B7: -case 0x17B7: -case 0x19B7: -case 0x1BB7: -case 0x1DB7: -case 0x1FB7: - -// MOVEB -case 0x11B0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) -case 0x11F1: -case 0x11F2: -case 0x11F3: -case 0x11F4: -case 0x11F5: -case 0x11F6: -case 0x11F7: - -// MOVEB -case 0x11F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) -case 0x13F1: -case 0x13F2: -case 0x13F3: -case 0x13F4: -case 0x13F5: -case 0x13F6: -case 0x13F7: - -// MOVEB -case 0x13F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(26) -case 0x1EF1: -case 0x1EF2: -case 0x1EF3: -case 0x1EF4: -case 0x1EF5: -case 0x1EF6: -case 0x1EF7: - -// MOVEB -case 0x1EF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x1F31: -case 0x1F32: -case 0x1F33: -case 0x1F34: -case 0x1F35: -case 0x1F36: -case 0x1F37: - -// MOVEB -case 0x1F30: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x1238: -case 0x1438: -case 0x1638: -case 0x1838: -case 0x1A38: -case 0x1C38: -case 0x1E38: - -// MOVEB -case 0x1038: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x12B8: -case 0x14B8: -case 0x16B8: -case 0x18B8: -case 0x1AB8: -case 0x1CB8: -case 0x1EB8: - -// MOVEB -case 0x10B8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x12F8: -case 0x14F8: -case 0x16F8: -case 0x18F8: -case 0x1AF8: -case 0x1CF8: - -// MOVEB -case 0x10F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1338: -case 0x1538: -case 0x1738: -case 0x1938: -case 0x1B38: -case 0x1D38: - -// MOVEB -case 0x1138: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1378: -case 0x1578: -case 0x1778: -case 0x1978: -case 0x1B78: -case 0x1D78: -case 0x1F78: - -// MOVEB -case 0x1178: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x13B8: -case 0x15B8: -case 0x17B8: -case 0x19B8: -case 0x1BB8: -case 0x1DB8: -case 0x1FB8: - -// MOVEB -case 0x11B8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// MOVEB -case 0x11F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// MOVEB -case 0x13F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// MOVEB -case 0x1EF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// MOVEB -case 0x1F38: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x1239: -case 0x1439: -case 0x1639: -case 0x1839: -case 0x1A39: -case 0x1C39: -case 0x1E39: - -// MOVEB -case 0x1039: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x12B9: -case 0x14B9: -case 0x16B9: -case 0x18B9: -case 0x1AB9: -case 0x1CB9: -case 0x1EB9: - -// MOVEB -case 0x10B9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x12F9: -case 0x14F9: -case 0x16F9: -case 0x18F9: -case 0x1AF9: -case 0x1CF9: - -// MOVEB -case 0x10F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x1339: -case 0x1539: -case 0x1739: -case 0x1939: -case 0x1B39: -case 0x1D39: - -// MOVEB -case 0x1139: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x1379: -case 0x1579: -case 0x1779: -case 0x1979: -case 0x1B79: -case 0x1D79: -case 0x1F79: - -// MOVEB -case 0x1179: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) -case 0x13B9: -case 0x15B9: -case 0x17B9: -case 0x19B9: -case 0x1BB9: -case 0x1DB9: -case 0x1FB9: - -// MOVEB -case 0x11B9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(26) - -// MOVEB -case 0x11F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// MOVEB -case 0x13F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(28) - -// MOVEB -case 0x1EF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// MOVEB -case 0x1F39: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x123A: -case 0x143A: -case 0x163A: -case 0x183A: -case 0x1A3A: -case 0x1C3A: -case 0x1E3A: - -// MOVEB -case 0x103A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x12BA: -case 0x14BA: -case 0x16BA: -case 0x18BA: -case 0x1ABA: -case 0x1CBA: -case 0x1EBA: - -// MOVEB -case 0x10BA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x12FA: -case 0x14FA: -case 0x16FA: -case 0x18FA: -case 0x1AFA: -case 0x1CFA: - -// MOVEB -case 0x10FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x133A: -case 0x153A: -case 0x173A: -case 0x193A: -case 0x1B3A: -case 0x1D3A: - -// MOVEB -case 0x113A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x137A: -case 0x157A: -case 0x177A: -case 0x197A: -case 0x1B7A: -case 0x1D7A: -case 0x1F7A: - -// MOVEB -case 0x117A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x13BA: -case 0x15BA: -case 0x17BA: -case 0x19BA: -case 0x1BBA: -case 0x1DBA: -case 0x1FBA: - -// MOVEB -case 0x11BA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// MOVEB -case 0x11FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// MOVEB -case 0x13FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// MOVEB -case 0x1EFA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// MOVEB -case 0x1F3A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x123B: -case 0x143B: -case 0x163B: -case 0x183B: -case 0x1A3B: -case 0x1C3B: -case 0x1E3B: - -// MOVEB -case 0x103B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x12BB: -case 0x14BB: -case 0x16BB: -case 0x18BB: -case 0x1ABB: -case 0x1CBB: -case 0x1EBB: - -// MOVEB -case 0x10BB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x12FB: -case 0x14FB: -case 0x16FB: -case 0x18FB: -case 0x1AFB: -case 0x1CFB: - -// MOVEB -case 0x10FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x133B: -case 0x153B: -case 0x173B: -case 0x193B: -case 0x1B3B: -case 0x1D3B: - -// MOVEB -case 0x113B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x137B: -case 0x157B: -case 0x177B: -case 0x197B: -case 0x1B7B: -case 0x1D7B: -case 0x1F7B: - -// MOVEB -case 0x117B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) -case 0x13BB: -case 0x15BB: -case 0x17BB: -case 0x19BB: -case 0x1BBB: -case 0x1DBB: -case 0x1FBB: - -// MOVEB -case 0x11BB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(24) - -// MOVEB -case 0x11FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// MOVEB -case 0x13FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(26) - -// MOVEB -case 0x1EFB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// MOVEB -case 0x1F3B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x123C: -case 0x143C: -case 0x163C: -case 0x183C: -case 0x1A3C: -case 0x1C3C: -case 0x1E3C: - -// MOVEB -case 0x103C: -{ - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0x12BC: -case 0x14BC: -case 0x16BC: -case 0x18BC: -case 0x1ABC: -case 0x1CBC: -case 0x1EBC: - -// MOVEB -case 0x10BC: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x12FC: -case 0x14FC: -case 0x16FC: -case 0x18FC: -case 0x1AFC: -case 0x1CFC: - -// MOVEB -case 0x10FC: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x133C: -case 0x153C: -case 0x173C: -case 0x193C: -case 0x1B3C: -case 0x1D3C: - -// MOVEB -case 0x113C: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x137C: -case 0x157C: -case 0x177C: -case 0x197C: -case 0x1B7C: -case 0x1D7C: -case 0x1F7C: - -// MOVEB -case 0x117C: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x13BC: -case 0x15BC: -case 0x17BC: -case 0x19BC: -case 0x1BBC: -case 0x1DBC: -case 0x1FBC: - -// MOVEB -case 0x11BC: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// MOVEB -case 0x11FC: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// MOVEB -case 0x13FC: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// MOVEB -case 0x1EFC: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) - -// MOVEB -case 0x1F3C: -{ - u32 adr; - u32 res; - res = FETCH_BYTE; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x121F: -case 0x141F: -case 0x161F: -case 0x181F: -case 0x1A1F: -case 0x1C1F: -case 0x1E1F: - -// MOVEB -case 0x101F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x129F: -case 0x149F: -case 0x169F: -case 0x189F: -case 0x1A9F: -case 0x1C9F: -case 0x1E9F: - -// MOVEB -case 0x109F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x12DF: -case 0x14DF: -case 0x16DF: -case 0x18DF: -case 0x1ADF: -case 0x1CDF: - -// MOVEB -case 0x10DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x131F: -case 0x151F: -case 0x171F: -case 0x191F: -case 0x1B1F: -case 0x1D1F: - -// MOVEB -case 0x111F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x135F: -case 0x155F: -case 0x175F: -case 0x195F: -case 0x1B5F: -case 0x1D5F: -case 0x1F5F: - -// MOVEB -case 0x115F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x139F: -case 0x159F: -case 0x179F: -case 0x199F: -case 0x1B9F: -case 0x1D9F: -case 0x1F9F: - -// MOVEB -case 0x119F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// MOVEB -case 0x11DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// MOVEB -case 0x13DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// MOVEB -case 0x1EDF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) - -// MOVEB -case 0x1F1F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x1227: -case 0x1427: -case 0x1627: -case 0x1827: -case 0x1A27: -case 0x1C27: -case 0x1E27: - -// MOVEB -case 0x1027: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x12A7: -case 0x14A7: -case 0x16A7: -case 0x18A7: -case 0x1AA7: -case 0x1CA7: -case 0x1EA7: - -// MOVEB -case 0x10A7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x12E7: -case 0x14E7: -case 0x16E7: -case 0x18E7: -case 0x1AE7: -case 0x1CE7: - -// MOVEB -case 0x10E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x1327: -case 0x1527: -case 0x1727: -case 0x1927: -case 0x1B27: -case 0x1D27: - -// MOVEB -case 0x1127: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x1367: -case 0x1567: -case 0x1767: -case 0x1967: -case 0x1B67: -case 0x1D67: -case 0x1F67: - -// MOVEB -case 0x1167: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x13A7: -case 0x15A7: -case 0x17A7: -case 0x19A7: -case 0x1BA7: -case 0x1DA7: -case 0x1FA7: - -// MOVEB -case 0x11A7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// MOVEB -case 0x11E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// MOVEB -case 0x13E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(22) - -// MOVEB -case 0x1EE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) - -// MOVEB -case 0x1F27: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) diff --git a/yabause/src/c68k/c68k_op2.inc b/yabause/src/c68k/c68k_op2.inc deleted file mode 100644 index 3228cd2dc4..0000000000 --- a/yabause/src/c68k/c68k_op2.inc +++ /dev/null @@ -1,6254 +0,0 @@ -case 0x2200: -case 0x2400: -case 0x2600: -case 0x2800: -case 0x2A00: -case 0x2C00: -case 0x2E00: -case 0x2001: -case 0x2201: -case 0x2401: -case 0x2601: -case 0x2801: -case 0x2A01: -case 0x2C01: -case 0x2E01: -case 0x2002: -case 0x2202: -case 0x2402: -case 0x2602: -case 0x2802: -case 0x2A02: -case 0x2C02: -case 0x2E02: -case 0x2003: -case 0x2203: -case 0x2403: -case 0x2603: -case 0x2803: -case 0x2A03: -case 0x2C03: -case 0x2E03: -case 0x2004: -case 0x2204: -case 0x2404: -case 0x2604: -case 0x2804: -case 0x2A04: -case 0x2C04: -case 0x2E04: -case 0x2005: -case 0x2205: -case 0x2405: -case 0x2605: -case 0x2805: -case 0x2A05: -case 0x2C05: -case 0x2E05: -case 0x2006: -case 0x2206: -case 0x2406: -case 0x2606: -case 0x2806: -case 0x2A06: -case 0x2C06: -case 0x2E06: -case 0x2007: -case 0x2207: -case 0x2407: -case 0x2607: -case 0x2807: -case 0x2A07: -case 0x2C07: -case 0x2E07: - -// MOVEL -case 0x2000: -{ - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x2280: -case 0x2480: -case 0x2680: -case 0x2880: -case 0x2A80: -case 0x2C80: -case 0x2E80: -case 0x2081: -case 0x2281: -case 0x2481: -case 0x2681: -case 0x2881: -case 0x2A81: -case 0x2C81: -case 0x2E81: -case 0x2082: -case 0x2282: -case 0x2482: -case 0x2682: -case 0x2882: -case 0x2A82: -case 0x2C82: -case 0x2E82: -case 0x2083: -case 0x2283: -case 0x2483: -case 0x2683: -case 0x2883: -case 0x2A83: -case 0x2C83: -case 0x2E83: -case 0x2084: -case 0x2284: -case 0x2484: -case 0x2684: -case 0x2884: -case 0x2A84: -case 0x2C84: -case 0x2E84: -case 0x2085: -case 0x2285: -case 0x2485: -case 0x2685: -case 0x2885: -case 0x2A85: -case 0x2C85: -case 0x2E85: -case 0x2086: -case 0x2286: -case 0x2486: -case 0x2686: -case 0x2886: -case 0x2A86: -case 0x2C86: -case 0x2E86: -case 0x2087: -case 0x2287: -case 0x2487: -case 0x2687: -case 0x2887: -case 0x2A87: -case 0x2C87: -case 0x2E87: - -// MOVEL -case 0x2080: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x22C0: -case 0x24C0: -case 0x26C0: -case 0x28C0: -case 0x2AC0: -case 0x2CC0: -case 0x20C1: -case 0x22C1: -case 0x24C1: -case 0x26C1: -case 0x28C1: -case 0x2AC1: -case 0x2CC1: -case 0x20C2: -case 0x22C2: -case 0x24C2: -case 0x26C2: -case 0x28C2: -case 0x2AC2: -case 0x2CC2: -case 0x20C3: -case 0x22C3: -case 0x24C3: -case 0x26C3: -case 0x28C3: -case 0x2AC3: -case 0x2CC3: -case 0x20C4: -case 0x22C4: -case 0x24C4: -case 0x26C4: -case 0x28C4: -case 0x2AC4: -case 0x2CC4: -case 0x20C5: -case 0x22C5: -case 0x24C5: -case 0x26C5: -case 0x28C5: -case 0x2AC5: -case 0x2CC5: -case 0x20C6: -case 0x22C6: -case 0x24C6: -case 0x26C6: -case 0x28C6: -case 0x2AC6: -case 0x2CC6: -case 0x20C7: -case 0x22C7: -case 0x24C7: -case 0x26C7: -case 0x28C7: -case 0x2AC7: -case 0x2CC7: - -// MOVEL -case 0x20C0: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x2300: -case 0x2500: -case 0x2700: -case 0x2900: -case 0x2B00: -case 0x2D00: -case 0x2101: -case 0x2301: -case 0x2501: -case 0x2701: -case 0x2901: -case 0x2B01: -case 0x2D01: -case 0x2102: -case 0x2302: -case 0x2502: -case 0x2702: -case 0x2902: -case 0x2B02: -case 0x2D02: -case 0x2103: -case 0x2303: -case 0x2503: -case 0x2703: -case 0x2903: -case 0x2B03: -case 0x2D03: -case 0x2104: -case 0x2304: -case 0x2504: -case 0x2704: -case 0x2904: -case 0x2B04: -case 0x2D04: -case 0x2105: -case 0x2305: -case 0x2505: -case 0x2705: -case 0x2905: -case 0x2B05: -case 0x2D05: -case 0x2106: -case 0x2306: -case 0x2506: -case 0x2706: -case 0x2906: -case 0x2B06: -case 0x2D06: -case 0x2107: -case 0x2307: -case 0x2507: -case 0x2707: -case 0x2907: -case 0x2B07: -case 0x2D07: - -// MOVEL -case 0x2100: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x2340: -case 0x2540: -case 0x2740: -case 0x2940: -case 0x2B40: -case 0x2D40: -case 0x2F40: -case 0x2141: -case 0x2341: -case 0x2541: -case 0x2741: -case 0x2941: -case 0x2B41: -case 0x2D41: -case 0x2F41: -case 0x2142: -case 0x2342: -case 0x2542: -case 0x2742: -case 0x2942: -case 0x2B42: -case 0x2D42: -case 0x2F42: -case 0x2143: -case 0x2343: -case 0x2543: -case 0x2743: -case 0x2943: -case 0x2B43: -case 0x2D43: -case 0x2F43: -case 0x2144: -case 0x2344: -case 0x2544: -case 0x2744: -case 0x2944: -case 0x2B44: -case 0x2D44: -case 0x2F44: -case 0x2145: -case 0x2345: -case 0x2545: -case 0x2745: -case 0x2945: -case 0x2B45: -case 0x2D45: -case 0x2F45: -case 0x2146: -case 0x2346: -case 0x2546: -case 0x2746: -case 0x2946: -case 0x2B46: -case 0x2D46: -case 0x2F46: -case 0x2147: -case 0x2347: -case 0x2547: -case 0x2747: -case 0x2947: -case 0x2B47: -case 0x2D47: -case 0x2F47: - -// MOVEL -case 0x2140: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(16) -case 0x2380: -case 0x2580: -case 0x2780: -case 0x2980: -case 0x2B80: -case 0x2D80: -case 0x2F80: -case 0x2181: -case 0x2381: -case 0x2581: -case 0x2781: -case 0x2981: -case 0x2B81: -case 0x2D81: -case 0x2F81: -case 0x2182: -case 0x2382: -case 0x2582: -case 0x2782: -case 0x2982: -case 0x2B82: -case 0x2D82: -case 0x2F82: -case 0x2183: -case 0x2383: -case 0x2583: -case 0x2783: -case 0x2983: -case 0x2B83: -case 0x2D83: -case 0x2F83: -case 0x2184: -case 0x2384: -case 0x2584: -case 0x2784: -case 0x2984: -case 0x2B84: -case 0x2D84: -case 0x2F84: -case 0x2185: -case 0x2385: -case 0x2585: -case 0x2785: -case 0x2985: -case 0x2B85: -case 0x2D85: -case 0x2F85: -case 0x2186: -case 0x2386: -case 0x2586: -case 0x2786: -case 0x2986: -case 0x2B86: -case 0x2D86: -case 0x2F86: -case 0x2187: -case 0x2387: -case 0x2587: -case 0x2787: -case 0x2987: -case 0x2B87: -case 0x2D87: -case 0x2F87: - -// MOVEL -case 0x2180: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(18) -case 0x21C1: -case 0x21C2: -case 0x21C3: -case 0x21C4: -case 0x21C5: -case 0x21C6: -case 0x21C7: - -// MOVEL -case 0x21C0: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(16) -case 0x23C1: -case 0x23C2: -case 0x23C3: -case 0x23C4: -case 0x23C5: -case 0x23C6: -case 0x23C7: - -// MOVEL -case 0x23C0: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2EC1: -case 0x2EC2: -case 0x2EC3: -case 0x2EC4: -case 0x2EC5: -case 0x2EC6: -case 0x2EC7: - -// MOVEL -case 0x2EC0: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x2F01: -case 0x2F02: -case 0x2F03: -case 0x2F04: -case 0x2F05: -case 0x2F06: -case 0x2F07: - -// MOVEL -case 0x2F00: -{ - u32 adr; - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x2208: -case 0x2408: -case 0x2608: -case 0x2808: -case 0x2A08: -case 0x2C08: -case 0x2E08: -case 0x2009: -case 0x2209: -case 0x2409: -case 0x2609: -case 0x2809: -case 0x2A09: -case 0x2C09: -case 0x2E09: -case 0x200A: -case 0x220A: -case 0x240A: -case 0x260A: -case 0x280A: -case 0x2A0A: -case 0x2C0A: -case 0x2E0A: -case 0x200B: -case 0x220B: -case 0x240B: -case 0x260B: -case 0x280B: -case 0x2A0B: -case 0x2C0B: -case 0x2E0B: -case 0x200C: -case 0x220C: -case 0x240C: -case 0x260C: -case 0x280C: -case 0x2A0C: -case 0x2C0C: -case 0x2E0C: -case 0x200D: -case 0x220D: -case 0x240D: -case 0x260D: -case 0x280D: -case 0x2A0D: -case 0x2C0D: -case 0x2E0D: -case 0x200E: -case 0x220E: -case 0x240E: -case 0x260E: -case 0x280E: -case 0x2A0E: -case 0x2C0E: -case 0x2E0E: -case 0x200F: -case 0x220F: -case 0x240F: -case 0x260F: -case 0x280F: -case 0x2A0F: -case 0x2C0F: -case 0x2E0F: - -// MOVEL -case 0x2008: -{ - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x2288: -case 0x2488: -case 0x2688: -case 0x2888: -case 0x2A88: -case 0x2C88: -case 0x2E88: -case 0x2089: -case 0x2289: -case 0x2489: -case 0x2689: -case 0x2889: -case 0x2A89: -case 0x2C89: -case 0x2E89: -case 0x208A: -case 0x228A: -case 0x248A: -case 0x268A: -case 0x288A: -case 0x2A8A: -case 0x2C8A: -case 0x2E8A: -case 0x208B: -case 0x228B: -case 0x248B: -case 0x268B: -case 0x288B: -case 0x2A8B: -case 0x2C8B: -case 0x2E8B: -case 0x208C: -case 0x228C: -case 0x248C: -case 0x268C: -case 0x288C: -case 0x2A8C: -case 0x2C8C: -case 0x2E8C: -case 0x208D: -case 0x228D: -case 0x248D: -case 0x268D: -case 0x288D: -case 0x2A8D: -case 0x2C8D: -case 0x2E8D: -case 0x208E: -case 0x228E: -case 0x248E: -case 0x268E: -case 0x288E: -case 0x2A8E: -case 0x2C8E: -case 0x2E8E: -case 0x208F: -case 0x228F: -case 0x248F: -case 0x268F: -case 0x288F: -case 0x2A8F: -case 0x2C8F: -case 0x2E8F: - -// MOVEL -case 0x2088: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x22C8: -case 0x24C8: -case 0x26C8: -case 0x28C8: -case 0x2AC8: -case 0x2CC8: -case 0x20C9: -case 0x22C9: -case 0x24C9: -case 0x26C9: -case 0x28C9: -case 0x2AC9: -case 0x2CC9: -case 0x20CA: -case 0x22CA: -case 0x24CA: -case 0x26CA: -case 0x28CA: -case 0x2ACA: -case 0x2CCA: -case 0x20CB: -case 0x22CB: -case 0x24CB: -case 0x26CB: -case 0x28CB: -case 0x2ACB: -case 0x2CCB: -case 0x20CC: -case 0x22CC: -case 0x24CC: -case 0x26CC: -case 0x28CC: -case 0x2ACC: -case 0x2CCC: -case 0x20CD: -case 0x22CD: -case 0x24CD: -case 0x26CD: -case 0x28CD: -case 0x2ACD: -case 0x2CCD: -case 0x20CE: -case 0x22CE: -case 0x24CE: -case 0x26CE: -case 0x28CE: -case 0x2ACE: -case 0x2CCE: -case 0x20CF: -case 0x22CF: -case 0x24CF: -case 0x26CF: -case 0x28CF: -case 0x2ACF: -case 0x2CCF: - -// MOVEL -case 0x20C8: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x2308: -case 0x2508: -case 0x2708: -case 0x2908: -case 0x2B08: -case 0x2D08: -case 0x2109: -case 0x2309: -case 0x2509: -case 0x2709: -case 0x2909: -case 0x2B09: -case 0x2D09: -case 0x210A: -case 0x230A: -case 0x250A: -case 0x270A: -case 0x290A: -case 0x2B0A: -case 0x2D0A: -case 0x210B: -case 0x230B: -case 0x250B: -case 0x270B: -case 0x290B: -case 0x2B0B: -case 0x2D0B: -case 0x210C: -case 0x230C: -case 0x250C: -case 0x270C: -case 0x290C: -case 0x2B0C: -case 0x2D0C: -case 0x210D: -case 0x230D: -case 0x250D: -case 0x270D: -case 0x290D: -case 0x2B0D: -case 0x2D0D: -case 0x210E: -case 0x230E: -case 0x250E: -case 0x270E: -case 0x290E: -case 0x2B0E: -case 0x2D0E: -case 0x210F: -case 0x230F: -case 0x250F: -case 0x270F: -case 0x290F: -case 0x2B0F: -case 0x2D0F: - -// MOVEL -case 0x2108: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x2348: -case 0x2548: -case 0x2748: -case 0x2948: -case 0x2B48: -case 0x2D48: -case 0x2F48: -case 0x2149: -case 0x2349: -case 0x2549: -case 0x2749: -case 0x2949: -case 0x2B49: -case 0x2D49: -case 0x2F49: -case 0x214A: -case 0x234A: -case 0x254A: -case 0x274A: -case 0x294A: -case 0x2B4A: -case 0x2D4A: -case 0x2F4A: -case 0x214B: -case 0x234B: -case 0x254B: -case 0x274B: -case 0x294B: -case 0x2B4B: -case 0x2D4B: -case 0x2F4B: -case 0x214C: -case 0x234C: -case 0x254C: -case 0x274C: -case 0x294C: -case 0x2B4C: -case 0x2D4C: -case 0x2F4C: -case 0x214D: -case 0x234D: -case 0x254D: -case 0x274D: -case 0x294D: -case 0x2B4D: -case 0x2D4D: -case 0x2F4D: -case 0x214E: -case 0x234E: -case 0x254E: -case 0x274E: -case 0x294E: -case 0x2B4E: -case 0x2D4E: -case 0x2F4E: -case 0x214F: -case 0x234F: -case 0x254F: -case 0x274F: -case 0x294F: -case 0x2B4F: -case 0x2D4F: -case 0x2F4F: - -// MOVEL -case 0x2148: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(16) -case 0x2388: -case 0x2588: -case 0x2788: -case 0x2988: -case 0x2B88: -case 0x2D88: -case 0x2F88: -case 0x2189: -case 0x2389: -case 0x2589: -case 0x2789: -case 0x2989: -case 0x2B89: -case 0x2D89: -case 0x2F89: -case 0x218A: -case 0x238A: -case 0x258A: -case 0x278A: -case 0x298A: -case 0x2B8A: -case 0x2D8A: -case 0x2F8A: -case 0x218B: -case 0x238B: -case 0x258B: -case 0x278B: -case 0x298B: -case 0x2B8B: -case 0x2D8B: -case 0x2F8B: -case 0x218C: -case 0x238C: -case 0x258C: -case 0x278C: -case 0x298C: -case 0x2B8C: -case 0x2D8C: -case 0x2F8C: -case 0x218D: -case 0x238D: -case 0x258D: -case 0x278D: -case 0x298D: -case 0x2B8D: -case 0x2D8D: -case 0x2F8D: -case 0x218E: -case 0x238E: -case 0x258E: -case 0x278E: -case 0x298E: -case 0x2B8E: -case 0x2D8E: -case 0x2F8E: -case 0x218F: -case 0x238F: -case 0x258F: -case 0x278F: -case 0x298F: -case 0x2B8F: -case 0x2D8F: -case 0x2F8F: - -// MOVEL -case 0x2188: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(18) -case 0x21C9: -case 0x21CA: -case 0x21CB: -case 0x21CC: -case 0x21CD: -case 0x21CE: -case 0x21CF: - -// MOVEL -case 0x21C8: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(16) -case 0x23C9: -case 0x23CA: -case 0x23CB: -case 0x23CC: -case 0x23CD: -case 0x23CE: -case 0x23CF: - -// MOVEL -case 0x23C8: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2EC9: -case 0x2ECA: -case 0x2ECB: -case 0x2ECC: -case 0x2ECD: -case 0x2ECE: -case 0x2ECF: - -// MOVEL -case 0x2EC8: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x2F09: -case 0x2F0A: -case 0x2F0B: -case 0x2F0C: -case 0x2F0D: -case 0x2F0E: -case 0x2F0F: - -// MOVEL -case 0x2F08: -{ - u32 adr; - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(12) -case 0x2210: -case 0x2410: -case 0x2610: -case 0x2810: -case 0x2A10: -case 0x2C10: -case 0x2E10: -case 0x2011: -case 0x2211: -case 0x2411: -case 0x2611: -case 0x2811: -case 0x2A11: -case 0x2C11: -case 0x2E11: -case 0x2012: -case 0x2212: -case 0x2412: -case 0x2612: -case 0x2812: -case 0x2A12: -case 0x2C12: -case 0x2E12: -case 0x2013: -case 0x2213: -case 0x2413: -case 0x2613: -case 0x2813: -case 0x2A13: -case 0x2C13: -case 0x2E13: -case 0x2014: -case 0x2214: -case 0x2414: -case 0x2614: -case 0x2814: -case 0x2A14: -case 0x2C14: -case 0x2E14: -case 0x2015: -case 0x2215: -case 0x2415: -case 0x2615: -case 0x2815: -case 0x2A15: -case 0x2C15: -case 0x2E15: -case 0x2016: -case 0x2216: -case 0x2416: -case 0x2616: -case 0x2816: -case 0x2A16: -case 0x2C16: -case 0x2E16: -case 0x2017: -case 0x2217: -case 0x2417: -case 0x2617: -case 0x2817: -case 0x2A17: -case 0x2C17: -case 0x2E17: - -// MOVEL -case 0x2010: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x2290: -case 0x2490: -case 0x2690: -case 0x2890: -case 0x2A90: -case 0x2C90: -case 0x2E90: -case 0x2091: -case 0x2291: -case 0x2491: -case 0x2691: -case 0x2891: -case 0x2A91: -case 0x2C91: -case 0x2E91: -case 0x2092: -case 0x2292: -case 0x2492: -case 0x2692: -case 0x2892: -case 0x2A92: -case 0x2C92: -case 0x2E92: -case 0x2093: -case 0x2293: -case 0x2493: -case 0x2693: -case 0x2893: -case 0x2A93: -case 0x2C93: -case 0x2E93: -case 0x2094: -case 0x2294: -case 0x2494: -case 0x2694: -case 0x2894: -case 0x2A94: -case 0x2C94: -case 0x2E94: -case 0x2095: -case 0x2295: -case 0x2495: -case 0x2695: -case 0x2895: -case 0x2A95: -case 0x2C95: -case 0x2E95: -case 0x2096: -case 0x2296: -case 0x2496: -case 0x2696: -case 0x2896: -case 0x2A96: -case 0x2C96: -case 0x2E96: -case 0x2097: -case 0x2297: -case 0x2497: -case 0x2697: -case 0x2897: -case 0x2A97: -case 0x2C97: -case 0x2E97: - -// MOVEL -case 0x2090: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x22D0: -case 0x24D0: -case 0x26D0: -case 0x28D0: -case 0x2AD0: -case 0x2CD0: -case 0x20D1: -case 0x22D1: -case 0x24D1: -case 0x26D1: -case 0x28D1: -case 0x2AD1: -case 0x2CD1: -case 0x20D2: -case 0x22D2: -case 0x24D2: -case 0x26D2: -case 0x28D2: -case 0x2AD2: -case 0x2CD2: -case 0x20D3: -case 0x22D3: -case 0x24D3: -case 0x26D3: -case 0x28D3: -case 0x2AD3: -case 0x2CD3: -case 0x20D4: -case 0x22D4: -case 0x24D4: -case 0x26D4: -case 0x28D4: -case 0x2AD4: -case 0x2CD4: -case 0x20D5: -case 0x22D5: -case 0x24D5: -case 0x26D5: -case 0x28D5: -case 0x2AD5: -case 0x2CD5: -case 0x20D6: -case 0x22D6: -case 0x24D6: -case 0x26D6: -case 0x28D6: -case 0x2AD6: -case 0x2CD6: -case 0x20D7: -case 0x22D7: -case 0x24D7: -case 0x26D7: -case 0x28D7: -case 0x2AD7: -case 0x2CD7: - -// MOVEL -case 0x20D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2310: -case 0x2510: -case 0x2710: -case 0x2910: -case 0x2B10: -case 0x2D10: -case 0x2111: -case 0x2311: -case 0x2511: -case 0x2711: -case 0x2911: -case 0x2B11: -case 0x2D11: -case 0x2112: -case 0x2312: -case 0x2512: -case 0x2712: -case 0x2912: -case 0x2B12: -case 0x2D12: -case 0x2113: -case 0x2313: -case 0x2513: -case 0x2713: -case 0x2913: -case 0x2B13: -case 0x2D13: -case 0x2114: -case 0x2314: -case 0x2514: -case 0x2714: -case 0x2914: -case 0x2B14: -case 0x2D14: -case 0x2115: -case 0x2315: -case 0x2515: -case 0x2715: -case 0x2915: -case 0x2B15: -case 0x2D15: -case 0x2116: -case 0x2316: -case 0x2516: -case 0x2716: -case 0x2916: -case 0x2B16: -case 0x2D16: -case 0x2117: -case 0x2317: -case 0x2517: -case 0x2717: -case 0x2917: -case 0x2B17: -case 0x2D17: - -// MOVEL -case 0x2110: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2350: -case 0x2550: -case 0x2750: -case 0x2950: -case 0x2B50: -case 0x2D50: -case 0x2F50: -case 0x2151: -case 0x2351: -case 0x2551: -case 0x2751: -case 0x2951: -case 0x2B51: -case 0x2D51: -case 0x2F51: -case 0x2152: -case 0x2352: -case 0x2552: -case 0x2752: -case 0x2952: -case 0x2B52: -case 0x2D52: -case 0x2F52: -case 0x2153: -case 0x2353: -case 0x2553: -case 0x2753: -case 0x2953: -case 0x2B53: -case 0x2D53: -case 0x2F53: -case 0x2154: -case 0x2354: -case 0x2554: -case 0x2754: -case 0x2954: -case 0x2B54: -case 0x2D54: -case 0x2F54: -case 0x2155: -case 0x2355: -case 0x2555: -case 0x2755: -case 0x2955: -case 0x2B55: -case 0x2D55: -case 0x2F55: -case 0x2156: -case 0x2356: -case 0x2556: -case 0x2756: -case 0x2956: -case 0x2B56: -case 0x2D56: -case 0x2F56: -case 0x2157: -case 0x2357: -case 0x2557: -case 0x2757: -case 0x2957: -case 0x2B57: -case 0x2D57: -case 0x2F57: - -// MOVEL -case 0x2150: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2390: -case 0x2590: -case 0x2790: -case 0x2990: -case 0x2B90: -case 0x2D90: -case 0x2F90: -case 0x2191: -case 0x2391: -case 0x2591: -case 0x2791: -case 0x2991: -case 0x2B91: -case 0x2D91: -case 0x2F91: -case 0x2192: -case 0x2392: -case 0x2592: -case 0x2792: -case 0x2992: -case 0x2B92: -case 0x2D92: -case 0x2F92: -case 0x2193: -case 0x2393: -case 0x2593: -case 0x2793: -case 0x2993: -case 0x2B93: -case 0x2D93: -case 0x2F93: -case 0x2194: -case 0x2394: -case 0x2594: -case 0x2794: -case 0x2994: -case 0x2B94: -case 0x2D94: -case 0x2F94: -case 0x2195: -case 0x2395: -case 0x2595: -case 0x2795: -case 0x2995: -case 0x2B95: -case 0x2D95: -case 0x2F95: -case 0x2196: -case 0x2396: -case 0x2596: -case 0x2796: -case 0x2996: -case 0x2B96: -case 0x2D96: -case 0x2F96: -case 0x2197: -case 0x2397: -case 0x2597: -case 0x2797: -case 0x2997: -case 0x2B97: -case 0x2D97: -case 0x2F97: - -// MOVEL -case 0x2190: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x21D1: -case 0x21D2: -case 0x21D3: -case 0x21D4: -case 0x21D5: -case 0x21D6: -case 0x21D7: - -// MOVEL -case 0x21D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x23D1: -case 0x23D2: -case 0x23D3: -case 0x23D4: -case 0x23D5: -case 0x23D6: -case 0x23D7: - -// MOVEL -case 0x23D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x2ED1: -case 0x2ED2: -case 0x2ED3: -case 0x2ED4: -case 0x2ED5: -case 0x2ED6: -case 0x2ED7: - -// MOVEL -case 0x2ED0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2F11: -case 0x2F12: -case 0x2F13: -case 0x2F14: -case 0x2F15: -case 0x2F16: -case 0x2F17: - -// MOVEL -case 0x2F10: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2218: -case 0x2418: -case 0x2618: -case 0x2818: -case 0x2A18: -case 0x2C18: -case 0x2E18: -case 0x2019: -case 0x2219: -case 0x2419: -case 0x2619: -case 0x2819: -case 0x2A19: -case 0x2C19: -case 0x2E19: -case 0x201A: -case 0x221A: -case 0x241A: -case 0x261A: -case 0x281A: -case 0x2A1A: -case 0x2C1A: -case 0x2E1A: -case 0x201B: -case 0x221B: -case 0x241B: -case 0x261B: -case 0x281B: -case 0x2A1B: -case 0x2C1B: -case 0x2E1B: -case 0x201C: -case 0x221C: -case 0x241C: -case 0x261C: -case 0x281C: -case 0x2A1C: -case 0x2C1C: -case 0x2E1C: -case 0x201D: -case 0x221D: -case 0x241D: -case 0x261D: -case 0x281D: -case 0x2A1D: -case 0x2C1D: -case 0x2E1D: -case 0x201E: -case 0x221E: -case 0x241E: -case 0x261E: -case 0x281E: -case 0x2A1E: -case 0x2C1E: -case 0x2E1E: - -// MOVEL -case 0x2018: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x2298: -case 0x2498: -case 0x2698: -case 0x2898: -case 0x2A98: -case 0x2C98: -case 0x2E98: -case 0x2099: -case 0x2299: -case 0x2499: -case 0x2699: -case 0x2899: -case 0x2A99: -case 0x2C99: -case 0x2E99: -case 0x209A: -case 0x229A: -case 0x249A: -case 0x269A: -case 0x289A: -case 0x2A9A: -case 0x2C9A: -case 0x2E9A: -case 0x209B: -case 0x229B: -case 0x249B: -case 0x269B: -case 0x289B: -case 0x2A9B: -case 0x2C9B: -case 0x2E9B: -case 0x209C: -case 0x229C: -case 0x249C: -case 0x269C: -case 0x289C: -case 0x2A9C: -case 0x2C9C: -case 0x2E9C: -case 0x209D: -case 0x229D: -case 0x249D: -case 0x269D: -case 0x289D: -case 0x2A9D: -case 0x2C9D: -case 0x2E9D: -case 0x209E: -case 0x229E: -case 0x249E: -case 0x269E: -case 0x289E: -case 0x2A9E: -case 0x2C9E: -case 0x2E9E: - -// MOVEL -case 0x2098: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x22D8: -case 0x24D8: -case 0x26D8: -case 0x28D8: -case 0x2AD8: -case 0x2CD8: -case 0x20D9: -case 0x22D9: -case 0x24D9: -case 0x26D9: -case 0x28D9: -case 0x2AD9: -case 0x2CD9: -case 0x20DA: -case 0x22DA: -case 0x24DA: -case 0x26DA: -case 0x28DA: -case 0x2ADA: -case 0x2CDA: -case 0x20DB: -case 0x22DB: -case 0x24DB: -case 0x26DB: -case 0x28DB: -case 0x2ADB: -case 0x2CDB: -case 0x20DC: -case 0x22DC: -case 0x24DC: -case 0x26DC: -case 0x28DC: -case 0x2ADC: -case 0x2CDC: -case 0x20DD: -case 0x22DD: -case 0x24DD: -case 0x26DD: -case 0x28DD: -case 0x2ADD: -case 0x2CDD: -case 0x20DE: -case 0x22DE: -case 0x24DE: -case 0x26DE: -case 0x28DE: -case 0x2ADE: -case 0x2CDE: - -// MOVEL -case 0x20D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2318: -case 0x2518: -case 0x2718: -case 0x2918: -case 0x2B18: -case 0x2D18: -case 0x2119: -case 0x2319: -case 0x2519: -case 0x2719: -case 0x2919: -case 0x2B19: -case 0x2D19: -case 0x211A: -case 0x231A: -case 0x251A: -case 0x271A: -case 0x291A: -case 0x2B1A: -case 0x2D1A: -case 0x211B: -case 0x231B: -case 0x251B: -case 0x271B: -case 0x291B: -case 0x2B1B: -case 0x2D1B: -case 0x211C: -case 0x231C: -case 0x251C: -case 0x271C: -case 0x291C: -case 0x2B1C: -case 0x2D1C: -case 0x211D: -case 0x231D: -case 0x251D: -case 0x271D: -case 0x291D: -case 0x2B1D: -case 0x2D1D: -case 0x211E: -case 0x231E: -case 0x251E: -case 0x271E: -case 0x291E: -case 0x2B1E: -case 0x2D1E: - -// MOVEL -case 0x2118: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2358: -case 0x2558: -case 0x2758: -case 0x2958: -case 0x2B58: -case 0x2D58: -case 0x2F58: -case 0x2159: -case 0x2359: -case 0x2559: -case 0x2759: -case 0x2959: -case 0x2B59: -case 0x2D59: -case 0x2F59: -case 0x215A: -case 0x235A: -case 0x255A: -case 0x275A: -case 0x295A: -case 0x2B5A: -case 0x2D5A: -case 0x2F5A: -case 0x215B: -case 0x235B: -case 0x255B: -case 0x275B: -case 0x295B: -case 0x2B5B: -case 0x2D5B: -case 0x2F5B: -case 0x215C: -case 0x235C: -case 0x255C: -case 0x275C: -case 0x295C: -case 0x2B5C: -case 0x2D5C: -case 0x2F5C: -case 0x215D: -case 0x235D: -case 0x255D: -case 0x275D: -case 0x295D: -case 0x2B5D: -case 0x2D5D: -case 0x2F5D: -case 0x215E: -case 0x235E: -case 0x255E: -case 0x275E: -case 0x295E: -case 0x2B5E: -case 0x2D5E: -case 0x2F5E: - -// MOVEL -case 0x2158: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2398: -case 0x2598: -case 0x2798: -case 0x2998: -case 0x2B98: -case 0x2D98: -case 0x2F98: -case 0x2199: -case 0x2399: -case 0x2599: -case 0x2799: -case 0x2999: -case 0x2B99: -case 0x2D99: -case 0x2F99: -case 0x219A: -case 0x239A: -case 0x259A: -case 0x279A: -case 0x299A: -case 0x2B9A: -case 0x2D9A: -case 0x2F9A: -case 0x219B: -case 0x239B: -case 0x259B: -case 0x279B: -case 0x299B: -case 0x2B9B: -case 0x2D9B: -case 0x2F9B: -case 0x219C: -case 0x239C: -case 0x259C: -case 0x279C: -case 0x299C: -case 0x2B9C: -case 0x2D9C: -case 0x2F9C: -case 0x219D: -case 0x239D: -case 0x259D: -case 0x279D: -case 0x299D: -case 0x2B9D: -case 0x2D9D: -case 0x2F9D: -case 0x219E: -case 0x239E: -case 0x259E: -case 0x279E: -case 0x299E: -case 0x2B9E: -case 0x2D9E: -case 0x2F9E: - -// MOVEL -case 0x2198: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x21D9: -case 0x21DA: -case 0x21DB: -case 0x21DC: -case 0x21DD: -case 0x21DE: - -// MOVEL -case 0x21D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x23D9: -case 0x23DA: -case 0x23DB: -case 0x23DC: -case 0x23DD: -case 0x23DE: - -// MOVEL -case 0x23D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x2ED9: -case 0x2EDA: -case 0x2EDB: -case 0x2EDC: -case 0x2EDD: -case 0x2EDE: - -// MOVEL -case 0x2ED8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2F19: -case 0x2F1A: -case 0x2F1B: -case 0x2F1C: -case 0x2F1D: -case 0x2F1E: - -// MOVEL -case 0x2F18: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2220: -case 0x2420: -case 0x2620: -case 0x2820: -case 0x2A20: -case 0x2C20: -case 0x2E20: -case 0x2021: -case 0x2221: -case 0x2421: -case 0x2621: -case 0x2821: -case 0x2A21: -case 0x2C21: -case 0x2E21: -case 0x2022: -case 0x2222: -case 0x2422: -case 0x2622: -case 0x2822: -case 0x2A22: -case 0x2C22: -case 0x2E22: -case 0x2023: -case 0x2223: -case 0x2423: -case 0x2623: -case 0x2823: -case 0x2A23: -case 0x2C23: -case 0x2E23: -case 0x2024: -case 0x2224: -case 0x2424: -case 0x2624: -case 0x2824: -case 0x2A24: -case 0x2C24: -case 0x2E24: -case 0x2025: -case 0x2225: -case 0x2425: -case 0x2625: -case 0x2825: -case 0x2A25: -case 0x2C25: -case 0x2E25: -case 0x2026: -case 0x2226: -case 0x2426: -case 0x2626: -case 0x2826: -case 0x2A26: -case 0x2C26: -case 0x2E26: - -// MOVEL -case 0x2020: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x22A0: -case 0x24A0: -case 0x26A0: -case 0x28A0: -case 0x2AA0: -case 0x2CA0: -case 0x2EA0: -case 0x20A1: -case 0x22A1: -case 0x24A1: -case 0x26A1: -case 0x28A1: -case 0x2AA1: -case 0x2CA1: -case 0x2EA1: -case 0x20A2: -case 0x22A2: -case 0x24A2: -case 0x26A2: -case 0x28A2: -case 0x2AA2: -case 0x2CA2: -case 0x2EA2: -case 0x20A3: -case 0x22A3: -case 0x24A3: -case 0x26A3: -case 0x28A3: -case 0x2AA3: -case 0x2CA3: -case 0x2EA3: -case 0x20A4: -case 0x22A4: -case 0x24A4: -case 0x26A4: -case 0x28A4: -case 0x2AA4: -case 0x2CA4: -case 0x2EA4: -case 0x20A5: -case 0x22A5: -case 0x24A5: -case 0x26A5: -case 0x28A5: -case 0x2AA5: -case 0x2CA5: -case 0x2EA5: -case 0x20A6: -case 0x22A6: -case 0x24A6: -case 0x26A6: -case 0x28A6: -case 0x2AA6: -case 0x2CA6: -case 0x2EA6: - -// MOVEL -case 0x20A0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x22E0: -case 0x24E0: -case 0x26E0: -case 0x28E0: -case 0x2AE0: -case 0x2CE0: -case 0x20E1: -case 0x22E1: -case 0x24E1: -case 0x26E1: -case 0x28E1: -case 0x2AE1: -case 0x2CE1: -case 0x20E2: -case 0x22E2: -case 0x24E2: -case 0x26E2: -case 0x28E2: -case 0x2AE2: -case 0x2CE2: -case 0x20E3: -case 0x22E3: -case 0x24E3: -case 0x26E3: -case 0x28E3: -case 0x2AE3: -case 0x2CE3: -case 0x20E4: -case 0x22E4: -case 0x24E4: -case 0x26E4: -case 0x28E4: -case 0x2AE4: -case 0x2CE4: -case 0x20E5: -case 0x22E5: -case 0x24E5: -case 0x26E5: -case 0x28E5: -case 0x2AE5: -case 0x2CE5: -case 0x20E6: -case 0x22E6: -case 0x24E6: -case 0x26E6: -case 0x28E6: -case 0x2AE6: -case 0x2CE6: - -// MOVEL -case 0x20E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x2320: -case 0x2520: -case 0x2720: -case 0x2920: -case 0x2B20: -case 0x2D20: -case 0x2121: -case 0x2321: -case 0x2521: -case 0x2721: -case 0x2921: -case 0x2B21: -case 0x2D21: -case 0x2122: -case 0x2322: -case 0x2522: -case 0x2722: -case 0x2922: -case 0x2B22: -case 0x2D22: -case 0x2123: -case 0x2323: -case 0x2523: -case 0x2723: -case 0x2923: -case 0x2B23: -case 0x2D23: -case 0x2124: -case 0x2324: -case 0x2524: -case 0x2724: -case 0x2924: -case 0x2B24: -case 0x2D24: -case 0x2125: -case 0x2325: -case 0x2525: -case 0x2725: -case 0x2925: -case 0x2B25: -case 0x2D25: -case 0x2126: -case 0x2326: -case 0x2526: -case 0x2726: -case 0x2926: -case 0x2B26: -case 0x2D26: - -// MOVEL -case 0x2120: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x2360: -case 0x2560: -case 0x2760: -case 0x2960: -case 0x2B60: -case 0x2D60: -case 0x2F60: -case 0x2161: -case 0x2361: -case 0x2561: -case 0x2761: -case 0x2961: -case 0x2B61: -case 0x2D61: -case 0x2F61: -case 0x2162: -case 0x2362: -case 0x2562: -case 0x2762: -case 0x2962: -case 0x2B62: -case 0x2D62: -case 0x2F62: -case 0x2163: -case 0x2363: -case 0x2563: -case 0x2763: -case 0x2963: -case 0x2B63: -case 0x2D63: -case 0x2F63: -case 0x2164: -case 0x2364: -case 0x2564: -case 0x2764: -case 0x2964: -case 0x2B64: -case 0x2D64: -case 0x2F64: -case 0x2165: -case 0x2365: -case 0x2565: -case 0x2765: -case 0x2965: -case 0x2B65: -case 0x2D65: -case 0x2F65: -case 0x2166: -case 0x2366: -case 0x2566: -case 0x2766: -case 0x2966: -case 0x2B66: -case 0x2D66: -case 0x2F66: - -// MOVEL -case 0x2160: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x23A0: -case 0x25A0: -case 0x27A0: -case 0x29A0: -case 0x2BA0: -case 0x2DA0: -case 0x2FA0: -case 0x21A1: -case 0x23A1: -case 0x25A1: -case 0x27A1: -case 0x29A1: -case 0x2BA1: -case 0x2DA1: -case 0x2FA1: -case 0x21A2: -case 0x23A2: -case 0x25A2: -case 0x27A2: -case 0x29A2: -case 0x2BA2: -case 0x2DA2: -case 0x2FA2: -case 0x21A3: -case 0x23A3: -case 0x25A3: -case 0x27A3: -case 0x29A3: -case 0x2BA3: -case 0x2DA3: -case 0x2FA3: -case 0x21A4: -case 0x23A4: -case 0x25A4: -case 0x27A4: -case 0x29A4: -case 0x2BA4: -case 0x2DA4: -case 0x2FA4: -case 0x21A5: -case 0x23A5: -case 0x25A5: -case 0x27A5: -case 0x29A5: -case 0x2BA5: -case 0x2DA5: -case 0x2FA5: -case 0x21A6: -case 0x23A6: -case 0x25A6: -case 0x27A6: -case 0x29A6: -case 0x2BA6: -case 0x2DA6: -case 0x2FA6: - -// MOVEL -case 0x21A0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x21E1: -case 0x21E2: -case 0x21E3: -case 0x21E4: -case 0x21E5: -case 0x21E6: - -// MOVEL -case 0x21E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x23E1: -case 0x23E2: -case 0x23E3: -case 0x23E4: -case 0x23E5: -case 0x23E6: - -// MOVEL -case 0x23E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x2EE1: -case 0x2EE2: -case 0x2EE3: -case 0x2EE4: -case 0x2EE5: -case 0x2EE6: - -// MOVEL -case 0x2EE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x2F21: -case 0x2F22: -case 0x2F23: -case 0x2F24: -case 0x2F25: -case 0x2F26: - -// MOVEL -case 0x2F20: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x2228: -case 0x2428: -case 0x2628: -case 0x2828: -case 0x2A28: -case 0x2C28: -case 0x2E28: -case 0x2029: -case 0x2229: -case 0x2429: -case 0x2629: -case 0x2829: -case 0x2A29: -case 0x2C29: -case 0x2E29: -case 0x202A: -case 0x222A: -case 0x242A: -case 0x262A: -case 0x282A: -case 0x2A2A: -case 0x2C2A: -case 0x2E2A: -case 0x202B: -case 0x222B: -case 0x242B: -case 0x262B: -case 0x282B: -case 0x2A2B: -case 0x2C2B: -case 0x2E2B: -case 0x202C: -case 0x222C: -case 0x242C: -case 0x262C: -case 0x282C: -case 0x2A2C: -case 0x2C2C: -case 0x2E2C: -case 0x202D: -case 0x222D: -case 0x242D: -case 0x262D: -case 0x282D: -case 0x2A2D: -case 0x2C2D: -case 0x2E2D: -case 0x202E: -case 0x222E: -case 0x242E: -case 0x262E: -case 0x282E: -case 0x2A2E: -case 0x2C2E: -case 0x2E2E: -case 0x202F: -case 0x222F: -case 0x242F: -case 0x262F: -case 0x282F: -case 0x2A2F: -case 0x2C2F: -case 0x2E2F: - -// MOVEL -case 0x2028: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x22A8: -case 0x24A8: -case 0x26A8: -case 0x28A8: -case 0x2AA8: -case 0x2CA8: -case 0x2EA8: -case 0x20A9: -case 0x22A9: -case 0x24A9: -case 0x26A9: -case 0x28A9: -case 0x2AA9: -case 0x2CA9: -case 0x2EA9: -case 0x20AA: -case 0x22AA: -case 0x24AA: -case 0x26AA: -case 0x28AA: -case 0x2AAA: -case 0x2CAA: -case 0x2EAA: -case 0x20AB: -case 0x22AB: -case 0x24AB: -case 0x26AB: -case 0x28AB: -case 0x2AAB: -case 0x2CAB: -case 0x2EAB: -case 0x20AC: -case 0x22AC: -case 0x24AC: -case 0x26AC: -case 0x28AC: -case 0x2AAC: -case 0x2CAC: -case 0x2EAC: -case 0x20AD: -case 0x22AD: -case 0x24AD: -case 0x26AD: -case 0x28AD: -case 0x2AAD: -case 0x2CAD: -case 0x2EAD: -case 0x20AE: -case 0x22AE: -case 0x24AE: -case 0x26AE: -case 0x28AE: -case 0x2AAE: -case 0x2CAE: -case 0x2EAE: -case 0x20AF: -case 0x22AF: -case 0x24AF: -case 0x26AF: -case 0x28AF: -case 0x2AAF: -case 0x2CAF: -case 0x2EAF: - -// MOVEL -case 0x20A8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x22E8: -case 0x24E8: -case 0x26E8: -case 0x28E8: -case 0x2AE8: -case 0x2CE8: -case 0x20E9: -case 0x22E9: -case 0x24E9: -case 0x26E9: -case 0x28E9: -case 0x2AE9: -case 0x2CE9: -case 0x20EA: -case 0x22EA: -case 0x24EA: -case 0x26EA: -case 0x28EA: -case 0x2AEA: -case 0x2CEA: -case 0x20EB: -case 0x22EB: -case 0x24EB: -case 0x26EB: -case 0x28EB: -case 0x2AEB: -case 0x2CEB: -case 0x20EC: -case 0x22EC: -case 0x24EC: -case 0x26EC: -case 0x28EC: -case 0x2AEC: -case 0x2CEC: -case 0x20ED: -case 0x22ED: -case 0x24ED: -case 0x26ED: -case 0x28ED: -case 0x2AED: -case 0x2CED: -case 0x20EE: -case 0x22EE: -case 0x24EE: -case 0x26EE: -case 0x28EE: -case 0x2AEE: -case 0x2CEE: -case 0x20EF: -case 0x22EF: -case 0x24EF: -case 0x26EF: -case 0x28EF: -case 0x2AEF: -case 0x2CEF: - -// MOVEL -case 0x20E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2328: -case 0x2528: -case 0x2728: -case 0x2928: -case 0x2B28: -case 0x2D28: -case 0x2129: -case 0x2329: -case 0x2529: -case 0x2729: -case 0x2929: -case 0x2B29: -case 0x2D29: -case 0x212A: -case 0x232A: -case 0x252A: -case 0x272A: -case 0x292A: -case 0x2B2A: -case 0x2D2A: -case 0x212B: -case 0x232B: -case 0x252B: -case 0x272B: -case 0x292B: -case 0x2B2B: -case 0x2D2B: -case 0x212C: -case 0x232C: -case 0x252C: -case 0x272C: -case 0x292C: -case 0x2B2C: -case 0x2D2C: -case 0x212D: -case 0x232D: -case 0x252D: -case 0x272D: -case 0x292D: -case 0x2B2D: -case 0x2D2D: -case 0x212E: -case 0x232E: -case 0x252E: -case 0x272E: -case 0x292E: -case 0x2B2E: -case 0x2D2E: -case 0x212F: -case 0x232F: -case 0x252F: -case 0x272F: -case 0x292F: -case 0x2B2F: -case 0x2D2F: - -// MOVEL -case 0x2128: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2368: -case 0x2568: -case 0x2768: -case 0x2968: -case 0x2B68: -case 0x2D68: -case 0x2F68: -case 0x2169: -case 0x2369: -case 0x2569: -case 0x2769: -case 0x2969: -case 0x2B69: -case 0x2D69: -case 0x2F69: -case 0x216A: -case 0x236A: -case 0x256A: -case 0x276A: -case 0x296A: -case 0x2B6A: -case 0x2D6A: -case 0x2F6A: -case 0x216B: -case 0x236B: -case 0x256B: -case 0x276B: -case 0x296B: -case 0x2B6B: -case 0x2D6B: -case 0x2F6B: -case 0x216C: -case 0x236C: -case 0x256C: -case 0x276C: -case 0x296C: -case 0x2B6C: -case 0x2D6C: -case 0x2F6C: -case 0x216D: -case 0x236D: -case 0x256D: -case 0x276D: -case 0x296D: -case 0x2B6D: -case 0x2D6D: -case 0x2F6D: -case 0x216E: -case 0x236E: -case 0x256E: -case 0x276E: -case 0x296E: -case 0x2B6E: -case 0x2D6E: -case 0x2F6E: -case 0x216F: -case 0x236F: -case 0x256F: -case 0x276F: -case 0x296F: -case 0x2B6F: -case 0x2D6F: -case 0x2F6F: - -// MOVEL -case 0x2168: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x23A8: -case 0x25A8: -case 0x27A8: -case 0x29A8: -case 0x2BA8: -case 0x2DA8: -case 0x2FA8: -case 0x21A9: -case 0x23A9: -case 0x25A9: -case 0x27A9: -case 0x29A9: -case 0x2BA9: -case 0x2DA9: -case 0x2FA9: -case 0x21AA: -case 0x23AA: -case 0x25AA: -case 0x27AA: -case 0x29AA: -case 0x2BAA: -case 0x2DAA: -case 0x2FAA: -case 0x21AB: -case 0x23AB: -case 0x25AB: -case 0x27AB: -case 0x29AB: -case 0x2BAB: -case 0x2DAB: -case 0x2FAB: -case 0x21AC: -case 0x23AC: -case 0x25AC: -case 0x27AC: -case 0x29AC: -case 0x2BAC: -case 0x2DAC: -case 0x2FAC: -case 0x21AD: -case 0x23AD: -case 0x25AD: -case 0x27AD: -case 0x29AD: -case 0x2BAD: -case 0x2DAD: -case 0x2FAD: -case 0x21AE: -case 0x23AE: -case 0x25AE: -case 0x27AE: -case 0x29AE: -case 0x2BAE: -case 0x2DAE: -case 0x2FAE: -case 0x21AF: -case 0x23AF: -case 0x25AF: -case 0x27AF: -case 0x29AF: -case 0x2BAF: -case 0x2DAF: -case 0x2FAF: - -// MOVEL -case 0x21A8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x21E9: -case 0x21EA: -case 0x21EB: -case 0x21EC: -case 0x21ED: -case 0x21EE: -case 0x21EF: - -// MOVEL -case 0x21E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x23E9: -case 0x23EA: -case 0x23EB: -case 0x23EC: -case 0x23ED: -case 0x23EE: -case 0x23EF: - -// MOVEL -case 0x23E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) -case 0x2EE9: -case 0x2EEA: -case 0x2EEB: -case 0x2EEC: -case 0x2EED: -case 0x2EEE: -case 0x2EEF: - -// MOVEL -case 0x2EE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2F29: -case 0x2F2A: -case 0x2F2B: -case 0x2F2C: -case 0x2F2D: -case 0x2F2E: -case 0x2F2F: - -// MOVEL -case 0x2F28: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2230: -case 0x2430: -case 0x2630: -case 0x2830: -case 0x2A30: -case 0x2C30: -case 0x2E30: -case 0x2031: -case 0x2231: -case 0x2431: -case 0x2631: -case 0x2831: -case 0x2A31: -case 0x2C31: -case 0x2E31: -case 0x2032: -case 0x2232: -case 0x2432: -case 0x2632: -case 0x2832: -case 0x2A32: -case 0x2C32: -case 0x2E32: -case 0x2033: -case 0x2233: -case 0x2433: -case 0x2633: -case 0x2833: -case 0x2A33: -case 0x2C33: -case 0x2E33: -case 0x2034: -case 0x2234: -case 0x2434: -case 0x2634: -case 0x2834: -case 0x2A34: -case 0x2C34: -case 0x2E34: -case 0x2035: -case 0x2235: -case 0x2435: -case 0x2635: -case 0x2835: -case 0x2A35: -case 0x2C35: -case 0x2E35: -case 0x2036: -case 0x2236: -case 0x2436: -case 0x2636: -case 0x2836: -case 0x2A36: -case 0x2C36: -case 0x2E36: -case 0x2037: -case 0x2237: -case 0x2437: -case 0x2637: -case 0x2837: -case 0x2A37: -case 0x2C37: -case 0x2E37: - -// MOVEL -case 0x2030: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0x22B0: -case 0x24B0: -case 0x26B0: -case 0x28B0: -case 0x2AB0: -case 0x2CB0: -case 0x2EB0: -case 0x20B1: -case 0x22B1: -case 0x24B1: -case 0x26B1: -case 0x28B1: -case 0x2AB1: -case 0x2CB1: -case 0x2EB1: -case 0x20B2: -case 0x22B2: -case 0x24B2: -case 0x26B2: -case 0x28B2: -case 0x2AB2: -case 0x2CB2: -case 0x2EB2: -case 0x20B3: -case 0x22B3: -case 0x24B3: -case 0x26B3: -case 0x28B3: -case 0x2AB3: -case 0x2CB3: -case 0x2EB3: -case 0x20B4: -case 0x22B4: -case 0x24B4: -case 0x26B4: -case 0x28B4: -case 0x2AB4: -case 0x2CB4: -case 0x2EB4: -case 0x20B5: -case 0x22B5: -case 0x24B5: -case 0x26B5: -case 0x28B5: -case 0x2AB5: -case 0x2CB5: -case 0x2EB5: -case 0x20B6: -case 0x22B6: -case 0x24B6: -case 0x26B6: -case 0x28B6: -case 0x2AB6: -case 0x2CB6: -case 0x2EB6: -case 0x20B7: -case 0x22B7: -case 0x24B7: -case 0x26B7: -case 0x28B7: -case 0x2AB7: -case 0x2CB7: -case 0x2EB7: - -// MOVEL -case 0x20B0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x22F0: -case 0x24F0: -case 0x26F0: -case 0x28F0: -case 0x2AF0: -case 0x2CF0: -case 0x20F1: -case 0x22F1: -case 0x24F1: -case 0x26F1: -case 0x28F1: -case 0x2AF1: -case 0x2CF1: -case 0x20F2: -case 0x22F2: -case 0x24F2: -case 0x26F2: -case 0x28F2: -case 0x2AF2: -case 0x2CF2: -case 0x20F3: -case 0x22F3: -case 0x24F3: -case 0x26F3: -case 0x28F3: -case 0x2AF3: -case 0x2CF3: -case 0x20F4: -case 0x22F4: -case 0x24F4: -case 0x26F4: -case 0x28F4: -case 0x2AF4: -case 0x2CF4: -case 0x20F5: -case 0x22F5: -case 0x24F5: -case 0x26F5: -case 0x28F5: -case 0x2AF5: -case 0x2CF5: -case 0x20F6: -case 0x22F6: -case 0x24F6: -case 0x26F6: -case 0x28F6: -case 0x2AF6: -case 0x2CF6: -case 0x20F7: -case 0x22F7: -case 0x24F7: -case 0x26F7: -case 0x28F7: -case 0x2AF7: -case 0x2CF7: - -// MOVEL -case 0x20F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x2330: -case 0x2530: -case 0x2730: -case 0x2930: -case 0x2B30: -case 0x2D30: -case 0x2131: -case 0x2331: -case 0x2531: -case 0x2731: -case 0x2931: -case 0x2B31: -case 0x2D31: -case 0x2132: -case 0x2332: -case 0x2532: -case 0x2732: -case 0x2932: -case 0x2B32: -case 0x2D32: -case 0x2133: -case 0x2333: -case 0x2533: -case 0x2733: -case 0x2933: -case 0x2B33: -case 0x2D33: -case 0x2134: -case 0x2334: -case 0x2534: -case 0x2734: -case 0x2934: -case 0x2B34: -case 0x2D34: -case 0x2135: -case 0x2335: -case 0x2535: -case 0x2735: -case 0x2935: -case 0x2B35: -case 0x2D35: -case 0x2136: -case 0x2336: -case 0x2536: -case 0x2736: -case 0x2936: -case 0x2B36: -case 0x2D36: -case 0x2137: -case 0x2337: -case 0x2537: -case 0x2737: -case 0x2937: -case 0x2B37: -case 0x2D37: - -// MOVEL -case 0x2130: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x2370: -case 0x2570: -case 0x2770: -case 0x2970: -case 0x2B70: -case 0x2D70: -case 0x2F70: -case 0x2171: -case 0x2371: -case 0x2571: -case 0x2771: -case 0x2971: -case 0x2B71: -case 0x2D71: -case 0x2F71: -case 0x2172: -case 0x2372: -case 0x2572: -case 0x2772: -case 0x2972: -case 0x2B72: -case 0x2D72: -case 0x2F72: -case 0x2173: -case 0x2373: -case 0x2573: -case 0x2773: -case 0x2973: -case 0x2B73: -case 0x2D73: -case 0x2F73: -case 0x2174: -case 0x2374: -case 0x2574: -case 0x2774: -case 0x2974: -case 0x2B74: -case 0x2D74: -case 0x2F74: -case 0x2175: -case 0x2375: -case 0x2575: -case 0x2775: -case 0x2975: -case 0x2B75: -case 0x2D75: -case 0x2F75: -case 0x2176: -case 0x2376: -case 0x2576: -case 0x2776: -case 0x2976: -case 0x2B76: -case 0x2D76: -case 0x2F76: -case 0x2177: -case 0x2377: -case 0x2577: -case 0x2777: -case 0x2977: -case 0x2B77: -case 0x2D77: -case 0x2F77: - -// MOVEL -case 0x2170: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x23B0: -case 0x25B0: -case 0x27B0: -case 0x29B0: -case 0x2BB0: -case 0x2DB0: -case 0x2FB0: -case 0x21B1: -case 0x23B1: -case 0x25B1: -case 0x27B1: -case 0x29B1: -case 0x2BB1: -case 0x2DB1: -case 0x2FB1: -case 0x21B2: -case 0x23B2: -case 0x25B2: -case 0x27B2: -case 0x29B2: -case 0x2BB2: -case 0x2DB2: -case 0x2FB2: -case 0x21B3: -case 0x23B3: -case 0x25B3: -case 0x27B3: -case 0x29B3: -case 0x2BB3: -case 0x2DB3: -case 0x2FB3: -case 0x21B4: -case 0x23B4: -case 0x25B4: -case 0x27B4: -case 0x29B4: -case 0x2BB4: -case 0x2DB4: -case 0x2FB4: -case 0x21B5: -case 0x23B5: -case 0x25B5: -case 0x27B5: -case 0x29B5: -case 0x2BB5: -case 0x2DB5: -case 0x2FB5: -case 0x21B6: -case 0x23B6: -case 0x25B6: -case 0x27B6: -case 0x29B6: -case 0x2BB6: -case 0x2DB6: -case 0x2FB6: -case 0x21B7: -case 0x23B7: -case 0x25B7: -case 0x27B7: -case 0x29B7: -case 0x2BB7: -case 0x2DB7: -case 0x2FB7: - -// MOVEL -case 0x21B0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) -case 0x21F1: -case 0x21F2: -case 0x21F3: -case 0x21F4: -case 0x21F5: -case 0x21F6: -case 0x21F7: - -// MOVEL -case 0x21F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x23F1: -case 0x23F2: -case 0x23F3: -case 0x23F4: -case 0x23F5: -case 0x23F6: -case 0x23F7: - -// MOVEL -case 0x23F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(34) -case 0x2EF1: -case 0x2EF2: -case 0x2EF3: -case 0x2EF4: -case 0x2EF5: -case 0x2EF6: -case 0x2EF7: - -// MOVEL -case 0x2EF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x2F31: -case 0x2F32: -case 0x2F33: -case 0x2F34: -case 0x2F35: -case 0x2F36: -case 0x2F37: - -// MOVEL -case 0x2F30: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x2238: -case 0x2438: -case 0x2638: -case 0x2838: -case 0x2A38: -case 0x2C38: -case 0x2E38: - -// MOVEL -case 0x2038: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x22B8: -case 0x24B8: -case 0x26B8: -case 0x28B8: -case 0x2AB8: -case 0x2CB8: -case 0x2EB8: - -// MOVEL -case 0x20B8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x22F8: -case 0x24F8: -case 0x26F8: -case 0x28F8: -case 0x2AF8: -case 0x2CF8: - -// MOVEL -case 0x20F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2338: -case 0x2538: -case 0x2738: -case 0x2938: -case 0x2B38: -case 0x2D38: - -// MOVEL -case 0x2138: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2378: -case 0x2578: -case 0x2778: -case 0x2978: -case 0x2B78: -case 0x2D78: -case 0x2F78: - -// MOVEL -case 0x2178: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x23B8: -case 0x25B8: -case 0x27B8: -case 0x29B8: -case 0x2BB8: -case 0x2DB8: -case 0x2FB8: - -// MOVEL -case 0x21B8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// MOVEL -case 0x21F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// MOVEL -case 0x23F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// MOVEL -case 0x2EF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) - -// MOVEL -case 0x2F38: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x2239: -case 0x2439: -case 0x2639: -case 0x2839: -case 0x2A39: -case 0x2C39: -case 0x2E39: - -// MOVEL -case 0x2039: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0x22B9: -case 0x24B9: -case 0x26B9: -case 0x28B9: -case 0x2AB9: -case 0x2CB9: -case 0x2EB9: - -// MOVEL -case 0x20B9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x22F9: -case 0x24F9: -case 0x26F9: -case 0x28F9: -case 0x2AF9: -case 0x2CF9: - -// MOVEL -case 0x20F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x2339: -case 0x2539: -case 0x2739: -case 0x2939: -case 0x2B39: -case 0x2D39: - -// MOVEL -case 0x2139: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x2379: -case 0x2579: -case 0x2779: -case 0x2979: -case 0x2B79: -case 0x2D79: -case 0x2F79: - -// MOVEL -case 0x2179: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) -case 0x23B9: -case 0x25B9: -case 0x27B9: -case 0x29B9: -case 0x2BB9: -case 0x2DB9: -case 0x2FB9: - -// MOVEL -case 0x21B9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(34) - -// MOVEL -case 0x21F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// MOVEL -case 0x23F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(36) - -// MOVEL -case 0x2EF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// MOVEL -case 0x2F39: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x223A: -case 0x243A: -case 0x263A: -case 0x283A: -case 0x2A3A: -case 0x2C3A: -case 0x2E3A: - -// MOVEL -case 0x203A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x22BA: -case 0x24BA: -case 0x26BA: -case 0x28BA: -case 0x2ABA: -case 0x2CBA: -case 0x2EBA: - -// MOVEL -case 0x20BA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x22FA: -case 0x24FA: -case 0x26FA: -case 0x28FA: -case 0x2AFA: -case 0x2CFA: - -// MOVEL -case 0x20FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x233A: -case 0x253A: -case 0x273A: -case 0x293A: -case 0x2B3A: -case 0x2D3A: - -// MOVEL -case 0x213A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x237A: -case 0x257A: -case 0x277A: -case 0x297A: -case 0x2B7A: -case 0x2D7A: -case 0x2F7A: - -// MOVEL -case 0x217A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x23BA: -case 0x25BA: -case 0x27BA: -case 0x29BA: -case 0x2BBA: -case 0x2DBA: -case 0x2FBA: - -// MOVEL -case 0x21BA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// MOVEL -case 0x21FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// MOVEL -case 0x23FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// MOVEL -case 0x2EFA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) - -// MOVEL -case 0x2F3A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x223B: -case 0x243B: -case 0x263B: -case 0x283B: -case 0x2A3B: -case 0x2C3B: -case 0x2E3B: - -// MOVEL -case 0x203B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0x22BB: -case 0x24BB: -case 0x26BB: -case 0x28BB: -case 0x2ABB: -case 0x2CBB: -case 0x2EBB: - -// MOVEL -case 0x20BB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x22FB: -case 0x24FB: -case 0x26FB: -case 0x28FB: -case 0x2AFB: -case 0x2CFB: - -// MOVEL -case 0x20FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x233B: -case 0x253B: -case 0x273B: -case 0x293B: -case 0x2B3B: -case 0x2D3B: - -// MOVEL -case 0x213B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x237B: -case 0x257B: -case 0x277B: -case 0x297B: -case 0x2B7B: -case 0x2D7B: -case 0x2F7B: - -// MOVEL -case 0x217B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x23BB: -case 0x25BB: -case 0x27BB: -case 0x29BB: -case 0x2BBB: -case 0x2DBB: -case 0x2FBB: - -// MOVEL -case 0x21BB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(32) - -// MOVEL -case 0x21FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// MOVEL -case 0x23FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(34) - -// MOVEL -case 0x2EFB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) - -// MOVEL -case 0x2F3B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x223C: -case 0x243C: -case 0x263C: -case 0x283C: -case 0x2A3C: -case 0x2C3C: -case 0x2E3C: - -// MOVEL -case 0x203C: -{ - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(12) -case 0x22BC: -case 0x24BC: -case 0x26BC: -case 0x28BC: -case 0x2ABC: -case 0x2CBC: -case 0x2EBC: - -// MOVEL -case 0x20BC: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x22FC: -case 0x24FC: -case 0x26FC: -case 0x28FC: -case 0x2AFC: -case 0x2CFC: - -// MOVEL -case 0x20FC: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x233C: -case 0x253C: -case 0x273C: -case 0x293C: -case 0x2B3C: -case 0x2D3C: - -// MOVEL -case 0x213C: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x237C: -case 0x257C: -case 0x277C: -case 0x297C: -case 0x2B7C: -case 0x2D7C: -case 0x2F7C: - -// MOVEL -case 0x217C: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x23BC: -case 0x25BC: -case 0x27BC: -case 0x29BC: -case 0x2BBC: -case 0x2DBC: -case 0x2FBC: - -// MOVEL -case 0x21BC: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) - -// MOVEL -case 0x21FC: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) - -// MOVEL -case 0x23FC: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// MOVEL -case 0x2EFC: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) - -// MOVEL -case 0x2F3C: -{ - u32 adr; - u32 res; - res = FETCH_LONG; - PC += 4; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x221F: -case 0x241F: -case 0x261F: -case 0x281F: -case 0x2A1F: -case 0x2C1F: -case 0x2E1F: - -// MOVEL -case 0x201F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x229F: -case 0x249F: -case 0x269F: -case 0x289F: -case 0x2A9F: -case 0x2C9F: -case 0x2E9F: - -// MOVEL -case 0x209F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x22DF: -case 0x24DF: -case 0x26DF: -case 0x28DF: -case 0x2ADF: -case 0x2CDF: - -// MOVEL -case 0x20DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x231F: -case 0x251F: -case 0x271F: -case 0x291F: -case 0x2B1F: -case 0x2D1F: - -// MOVEL -case 0x211F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x235F: -case 0x255F: -case 0x275F: -case 0x295F: -case 0x2B5F: -case 0x2D5F: -case 0x2F5F: - -// MOVEL -case 0x215F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x239F: -case 0x259F: -case 0x279F: -case 0x299F: -case 0x2B9F: -case 0x2D9F: -case 0x2F9F: - -// MOVEL -case 0x219F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) - -// MOVEL -case 0x21DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) - -// MOVEL -case 0x23DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// MOVEL -case 0x2EDF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) - -// MOVEL -case 0x2F1F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x2227: -case 0x2427: -case 0x2627: -case 0x2827: -case 0x2A27: -case 0x2C27: -case 0x2E27: - -// MOVEL -case 0x2027: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x22A7: -case 0x24A7: -case 0x26A7: -case 0x28A7: -case 0x2AA7: -case 0x2CA7: -case 0x2EA7: - -// MOVEL -case 0x20A7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x22E7: -case 0x24E7: -case 0x26E7: -case 0x28E7: -case 0x2AE7: -case 0x2CE7: - -// MOVEL -case 0x20E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x2327: -case 0x2527: -case 0x2727: -case 0x2927: -case 0x2B27: -case 0x2D27: - -// MOVEL -case 0x2127: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x2367: -case 0x2567: -case 0x2767: -case 0x2967: -case 0x2B67: -case 0x2D67: -case 0x2F67: - -// MOVEL -case 0x2167: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x23A7: -case 0x25A7: -case 0x27A7: -case 0x29A7: -case 0x2BA7: -case 0x2DA7: -case 0x2FA7: - -// MOVEL -case 0x21A7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// MOVEL -case 0x21E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) - -// MOVEL -case 0x23E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// MOVEL -case 0x2EE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7]; - CPU->A[7] += 4; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) - -// MOVEL -case 0x2F27: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x2240: -case 0x2440: -case 0x2640: -case 0x2840: -case 0x2A40: -case 0x2C40: -case 0x2E40: -case 0x2041: -case 0x2241: -case 0x2441: -case 0x2641: -case 0x2841: -case 0x2A41: -case 0x2C41: -case 0x2E41: -case 0x2042: -case 0x2242: -case 0x2442: -case 0x2642: -case 0x2842: -case 0x2A42: -case 0x2C42: -case 0x2E42: -case 0x2043: -case 0x2243: -case 0x2443: -case 0x2643: -case 0x2843: -case 0x2A43: -case 0x2C43: -case 0x2E43: -case 0x2044: -case 0x2244: -case 0x2444: -case 0x2644: -case 0x2844: -case 0x2A44: -case 0x2C44: -case 0x2E44: -case 0x2045: -case 0x2245: -case 0x2445: -case 0x2645: -case 0x2845: -case 0x2A45: -case 0x2C45: -case 0x2E45: -case 0x2046: -case 0x2246: -case 0x2446: -case 0x2646: -case 0x2846: -case 0x2A46: -case 0x2C46: -case 0x2E46: -case 0x2047: -case 0x2247: -case 0x2447: -case 0x2647: -case 0x2847: -case 0x2A47: -case 0x2C47: -case 0x2E47: - -// MOVEAL -case 0x2040: -{ - u32 res; - res = (s32)(s32)CPU->D[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(4) -case 0x2248: -case 0x2448: -case 0x2648: -case 0x2848: -case 0x2A48: -case 0x2C48: -case 0x2E48: -case 0x2049: -case 0x2249: -case 0x2449: -case 0x2649: -case 0x2849: -case 0x2A49: -case 0x2C49: -case 0x2E49: -case 0x204A: -case 0x224A: -case 0x244A: -case 0x264A: -case 0x284A: -case 0x2A4A: -case 0x2C4A: -case 0x2E4A: -case 0x204B: -case 0x224B: -case 0x244B: -case 0x264B: -case 0x284B: -case 0x2A4B: -case 0x2C4B: -case 0x2E4B: -case 0x204C: -case 0x224C: -case 0x244C: -case 0x264C: -case 0x284C: -case 0x2A4C: -case 0x2C4C: -case 0x2E4C: -case 0x204D: -case 0x224D: -case 0x244D: -case 0x264D: -case 0x284D: -case 0x2A4D: -case 0x2C4D: -case 0x2E4D: -case 0x204E: -case 0x224E: -case 0x244E: -case 0x264E: -case 0x284E: -case 0x2A4E: -case 0x2C4E: -case 0x2E4E: -case 0x204F: -case 0x224F: -case 0x244F: -case 0x264F: -case 0x284F: -case 0x2A4F: -case 0x2C4F: -case 0x2E4F: - -// MOVEAL -case 0x2048: -{ - u32 res; - res = (s32)(s32)CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(4) -case 0x2250: -case 0x2450: -case 0x2650: -case 0x2850: -case 0x2A50: -case 0x2C50: -case 0x2E50: -case 0x2051: -case 0x2251: -case 0x2451: -case 0x2651: -case 0x2851: -case 0x2A51: -case 0x2C51: -case 0x2E51: -case 0x2052: -case 0x2252: -case 0x2452: -case 0x2652: -case 0x2852: -case 0x2A52: -case 0x2C52: -case 0x2E52: -case 0x2053: -case 0x2253: -case 0x2453: -case 0x2653: -case 0x2853: -case 0x2A53: -case 0x2C53: -case 0x2E53: -case 0x2054: -case 0x2254: -case 0x2454: -case 0x2654: -case 0x2854: -case 0x2A54: -case 0x2C54: -case 0x2E54: -case 0x2055: -case 0x2255: -case 0x2455: -case 0x2655: -case 0x2855: -case 0x2A55: -case 0x2C55: -case 0x2E55: -case 0x2056: -case 0x2256: -case 0x2456: -case 0x2656: -case 0x2856: -case 0x2A56: -case 0x2C56: -case 0x2E56: -case 0x2057: -case 0x2257: -case 0x2457: -case 0x2657: -case 0x2857: -case 0x2A57: -case 0x2C57: -case 0x2E57: - -// MOVEAL -case 0x2050: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x2258: -case 0x2458: -case 0x2658: -case 0x2858: -case 0x2A58: -case 0x2C58: -case 0x2E58: -case 0x2059: -case 0x2259: -case 0x2459: -case 0x2659: -case 0x2859: -case 0x2A59: -case 0x2C59: -case 0x2E59: -case 0x205A: -case 0x225A: -case 0x245A: -case 0x265A: -case 0x285A: -case 0x2A5A: -case 0x2C5A: -case 0x2E5A: -case 0x205B: -case 0x225B: -case 0x245B: -case 0x265B: -case 0x285B: -case 0x2A5B: -case 0x2C5B: -case 0x2E5B: -case 0x205C: -case 0x225C: -case 0x245C: -case 0x265C: -case 0x285C: -case 0x2A5C: -case 0x2C5C: -case 0x2E5C: -case 0x205D: -case 0x225D: -case 0x245D: -case 0x265D: -case 0x285D: -case 0x2A5D: -case 0x2C5D: -case 0x2E5D: -case 0x205E: -case 0x225E: -case 0x245E: -case 0x265E: -case 0x285E: -case 0x2A5E: -case 0x2C5E: -case 0x2E5E: - -// MOVEAL -case 0x2058: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x2260: -case 0x2460: -case 0x2660: -case 0x2860: -case 0x2A60: -case 0x2C60: -case 0x2E60: -case 0x2061: -case 0x2261: -case 0x2461: -case 0x2661: -case 0x2861: -case 0x2A61: -case 0x2C61: -case 0x2E61: -case 0x2062: -case 0x2262: -case 0x2462: -case 0x2662: -case 0x2862: -case 0x2A62: -case 0x2C62: -case 0x2E62: -case 0x2063: -case 0x2263: -case 0x2463: -case 0x2663: -case 0x2863: -case 0x2A63: -case 0x2C63: -case 0x2E63: -case 0x2064: -case 0x2264: -case 0x2464: -case 0x2664: -case 0x2864: -case 0x2A64: -case 0x2C64: -case 0x2E64: -case 0x2065: -case 0x2265: -case 0x2465: -case 0x2665: -case 0x2865: -case 0x2A65: -case 0x2C65: -case 0x2E65: -case 0x2066: -case 0x2266: -case 0x2466: -case 0x2666: -case 0x2866: -case 0x2A66: -case 0x2C66: -case 0x2E66: - -// MOVEAL -case 0x2060: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(14) -case 0x2268: -case 0x2468: -case 0x2668: -case 0x2868: -case 0x2A68: -case 0x2C68: -case 0x2E68: -case 0x2069: -case 0x2269: -case 0x2469: -case 0x2669: -case 0x2869: -case 0x2A69: -case 0x2C69: -case 0x2E69: -case 0x206A: -case 0x226A: -case 0x246A: -case 0x266A: -case 0x286A: -case 0x2A6A: -case 0x2C6A: -case 0x2E6A: -case 0x206B: -case 0x226B: -case 0x246B: -case 0x266B: -case 0x286B: -case 0x2A6B: -case 0x2C6B: -case 0x2E6B: -case 0x206C: -case 0x226C: -case 0x246C: -case 0x266C: -case 0x286C: -case 0x2A6C: -case 0x2C6C: -case 0x2E6C: -case 0x206D: -case 0x226D: -case 0x246D: -case 0x266D: -case 0x286D: -case 0x2A6D: -case 0x2C6D: -case 0x2E6D: -case 0x206E: -case 0x226E: -case 0x246E: -case 0x266E: -case 0x286E: -case 0x2A6E: -case 0x2C6E: -case 0x2E6E: -case 0x206F: -case 0x226F: -case 0x246F: -case 0x266F: -case 0x286F: -case 0x2A6F: -case 0x2C6F: -case 0x2E6F: - -// MOVEAL -case 0x2068: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x2270: -case 0x2470: -case 0x2670: -case 0x2870: -case 0x2A70: -case 0x2C70: -case 0x2E70: -case 0x2071: -case 0x2271: -case 0x2471: -case 0x2671: -case 0x2871: -case 0x2A71: -case 0x2C71: -case 0x2E71: -case 0x2072: -case 0x2272: -case 0x2472: -case 0x2672: -case 0x2872: -case 0x2A72: -case 0x2C72: -case 0x2E72: -case 0x2073: -case 0x2273: -case 0x2473: -case 0x2673: -case 0x2873: -case 0x2A73: -case 0x2C73: -case 0x2E73: -case 0x2074: -case 0x2274: -case 0x2474: -case 0x2674: -case 0x2874: -case 0x2A74: -case 0x2C74: -case 0x2E74: -case 0x2075: -case 0x2275: -case 0x2475: -case 0x2675: -case 0x2875: -case 0x2A75: -case 0x2C75: -case 0x2E75: -case 0x2076: -case 0x2276: -case 0x2476: -case 0x2676: -case 0x2876: -case 0x2A76: -case 0x2C76: -case 0x2E76: -case 0x2077: -case 0x2277: -case 0x2477: -case 0x2677: -case 0x2877: -case 0x2A77: -case 0x2C77: -case 0x2E77: - -// MOVEAL -case 0x2070: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) -case 0x2278: -case 0x2478: -case 0x2678: -case 0x2878: -case 0x2A78: -case 0x2C78: -case 0x2E78: - -// MOVEAL -case 0x2078: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x2279: -case 0x2479: -case 0x2679: -case 0x2879: -case 0x2A79: -case 0x2C79: -case 0x2E79: - -// MOVEAL -case 0x2079: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0x227A: -case 0x247A: -case 0x267A: -case 0x287A: -case 0x2A7A: -case 0x2C7A: -case 0x2E7A: - -// MOVEAL -case 0x207A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x227B: -case 0x247B: -case 0x267B: -case 0x287B: -case 0x2A7B: -case 0x2C7B: -case 0x2E7B: - -// MOVEAL -case 0x207B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) -case 0x227C: -case 0x247C: -case 0x267C: -case 0x287C: -case 0x2A7C: -case 0x2C7C: -case 0x2E7C: - -// MOVEAL -case 0x207C: -{ - u32 res; - res = (s32)(s32)FETCH_LONG; - PC += 4; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(12) -case 0x225F: -case 0x245F: -case 0x265F: -case 0x285F: -case 0x2A5F: -case 0x2C5F: -case 0x2E5F: - -// MOVEAL -case 0x205F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x2267: -case 0x2467: -case 0x2667: -case 0x2867: -case 0x2A67: -case 0x2C67: -case 0x2E67: - -// MOVEAL -case 0x2067: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READSX_LONG_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(14) diff --git a/yabause/src/c68k/c68k_op3.inc b/yabause/src/c68k/c68k_op3.inc deleted file mode 100644 index f1bbdc58ad..0000000000 --- a/yabause/src/c68k/c68k_op3.inc +++ /dev/null @@ -1,6254 +0,0 @@ -case 0x3200: -case 0x3400: -case 0x3600: -case 0x3800: -case 0x3A00: -case 0x3C00: -case 0x3E00: -case 0x3001: -case 0x3201: -case 0x3401: -case 0x3601: -case 0x3801: -case 0x3A01: -case 0x3C01: -case 0x3E01: -case 0x3002: -case 0x3202: -case 0x3402: -case 0x3602: -case 0x3802: -case 0x3A02: -case 0x3C02: -case 0x3E02: -case 0x3003: -case 0x3203: -case 0x3403: -case 0x3603: -case 0x3803: -case 0x3A03: -case 0x3C03: -case 0x3E03: -case 0x3004: -case 0x3204: -case 0x3404: -case 0x3604: -case 0x3804: -case 0x3A04: -case 0x3C04: -case 0x3E04: -case 0x3005: -case 0x3205: -case 0x3405: -case 0x3605: -case 0x3805: -case 0x3A05: -case 0x3C05: -case 0x3E05: -case 0x3006: -case 0x3206: -case 0x3406: -case 0x3606: -case 0x3806: -case 0x3A06: -case 0x3C06: -case 0x3E06: -case 0x3007: -case 0x3207: -case 0x3407: -case 0x3607: -case 0x3807: -case 0x3A07: -case 0x3C07: -case 0x3E07: - -// MOVEW -case 0x3000: -{ - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x3280: -case 0x3480: -case 0x3680: -case 0x3880: -case 0x3A80: -case 0x3C80: -case 0x3E80: -case 0x3081: -case 0x3281: -case 0x3481: -case 0x3681: -case 0x3881: -case 0x3A81: -case 0x3C81: -case 0x3E81: -case 0x3082: -case 0x3282: -case 0x3482: -case 0x3682: -case 0x3882: -case 0x3A82: -case 0x3C82: -case 0x3E82: -case 0x3083: -case 0x3283: -case 0x3483: -case 0x3683: -case 0x3883: -case 0x3A83: -case 0x3C83: -case 0x3E83: -case 0x3084: -case 0x3284: -case 0x3484: -case 0x3684: -case 0x3884: -case 0x3A84: -case 0x3C84: -case 0x3E84: -case 0x3085: -case 0x3285: -case 0x3485: -case 0x3685: -case 0x3885: -case 0x3A85: -case 0x3C85: -case 0x3E85: -case 0x3086: -case 0x3286: -case 0x3486: -case 0x3686: -case 0x3886: -case 0x3A86: -case 0x3C86: -case 0x3E86: -case 0x3087: -case 0x3287: -case 0x3487: -case 0x3687: -case 0x3887: -case 0x3A87: -case 0x3C87: -case 0x3E87: - -// MOVEW -case 0x3080: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x32C0: -case 0x34C0: -case 0x36C0: -case 0x38C0: -case 0x3AC0: -case 0x3CC0: -case 0x30C1: -case 0x32C1: -case 0x34C1: -case 0x36C1: -case 0x38C1: -case 0x3AC1: -case 0x3CC1: -case 0x30C2: -case 0x32C2: -case 0x34C2: -case 0x36C2: -case 0x38C2: -case 0x3AC2: -case 0x3CC2: -case 0x30C3: -case 0x32C3: -case 0x34C3: -case 0x36C3: -case 0x38C3: -case 0x3AC3: -case 0x3CC3: -case 0x30C4: -case 0x32C4: -case 0x34C4: -case 0x36C4: -case 0x38C4: -case 0x3AC4: -case 0x3CC4: -case 0x30C5: -case 0x32C5: -case 0x34C5: -case 0x36C5: -case 0x38C5: -case 0x3AC5: -case 0x3CC5: -case 0x30C6: -case 0x32C6: -case 0x34C6: -case 0x36C6: -case 0x38C6: -case 0x3AC6: -case 0x3CC6: -case 0x30C7: -case 0x32C7: -case 0x34C7: -case 0x36C7: -case 0x38C7: -case 0x3AC7: -case 0x3CC7: - -// MOVEW -case 0x30C0: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x3300: -case 0x3500: -case 0x3700: -case 0x3900: -case 0x3B00: -case 0x3D00: -case 0x3101: -case 0x3301: -case 0x3501: -case 0x3701: -case 0x3901: -case 0x3B01: -case 0x3D01: -case 0x3102: -case 0x3302: -case 0x3502: -case 0x3702: -case 0x3902: -case 0x3B02: -case 0x3D02: -case 0x3103: -case 0x3303: -case 0x3503: -case 0x3703: -case 0x3903: -case 0x3B03: -case 0x3D03: -case 0x3104: -case 0x3304: -case 0x3504: -case 0x3704: -case 0x3904: -case 0x3B04: -case 0x3D04: -case 0x3105: -case 0x3305: -case 0x3505: -case 0x3705: -case 0x3905: -case 0x3B05: -case 0x3D05: -case 0x3106: -case 0x3306: -case 0x3506: -case 0x3706: -case 0x3906: -case 0x3B06: -case 0x3D06: -case 0x3107: -case 0x3307: -case 0x3507: -case 0x3707: -case 0x3907: -case 0x3B07: -case 0x3D07: - -// MOVEW -case 0x3100: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x3340: -case 0x3540: -case 0x3740: -case 0x3940: -case 0x3B40: -case 0x3D40: -case 0x3F40: -case 0x3141: -case 0x3341: -case 0x3541: -case 0x3741: -case 0x3941: -case 0x3B41: -case 0x3D41: -case 0x3F41: -case 0x3142: -case 0x3342: -case 0x3542: -case 0x3742: -case 0x3942: -case 0x3B42: -case 0x3D42: -case 0x3F42: -case 0x3143: -case 0x3343: -case 0x3543: -case 0x3743: -case 0x3943: -case 0x3B43: -case 0x3D43: -case 0x3F43: -case 0x3144: -case 0x3344: -case 0x3544: -case 0x3744: -case 0x3944: -case 0x3B44: -case 0x3D44: -case 0x3F44: -case 0x3145: -case 0x3345: -case 0x3545: -case 0x3745: -case 0x3945: -case 0x3B45: -case 0x3D45: -case 0x3F45: -case 0x3146: -case 0x3346: -case 0x3546: -case 0x3746: -case 0x3946: -case 0x3B46: -case 0x3D46: -case 0x3F46: -case 0x3147: -case 0x3347: -case 0x3547: -case 0x3747: -case 0x3947: -case 0x3B47: -case 0x3D47: -case 0x3F47: - -// MOVEW -case 0x3140: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3380: -case 0x3580: -case 0x3780: -case 0x3980: -case 0x3B80: -case 0x3D80: -case 0x3F80: -case 0x3181: -case 0x3381: -case 0x3581: -case 0x3781: -case 0x3981: -case 0x3B81: -case 0x3D81: -case 0x3F81: -case 0x3182: -case 0x3382: -case 0x3582: -case 0x3782: -case 0x3982: -case 0x3B82: -case 0x3D82: -case 0x3F82: -case 0x3183: -case 0x3383: -case 0x3583: -case 0x3783: -case 0x3983: -case 0x3B83: -case 0x3D83: -case 0x3F83: -case 0x3184: -case 0x3384: -case 0x3584: -case 0x3784: -case 0x3984: -case 0x3B84: -case 0x3D84: -case 0x3F84: -case 0x3185: -case 0x3385: -case 0x3585: -case 0x3785: -case 0x3985: -case 0x3B85: -case 0x3D85: -case 0x3F85: -case 0x3186: -case 0x3386: -case 0x3586: -case 0x3786: -case 0x3986: -case 0x3B86: -case 0x3D86: -case 0x3F86: -case 0x3187: -case 0x3387: -case 0x3587: -case 0x3787: -case 0x3987: -case 0x3B87: -case 0x3D87: -case 0x3F87: - -// MOVEW -case 0x3180: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x31C1: -case 0x31C2: -case 0x31C3: -case 0x31C4: -case 0x31C5: -case 0x31C6: -case 0x31C7: - -// MOVEW -case 0x31C0: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x33C1: -case 0x33C2: -case 0x33C3: -case 0x33C4: -case 0x33C5: -case 0x33C6: -case 0x33C7: - -// MOVEW -case 0x33C0: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3EC1: -case 0x3EC2: -case 0x3EC3: -case 0x3EC4: -case 0x3EC5: -case 0x3EC6: -case 0x3EC7: - -// MOVEW -case 0x3EC0: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x3F01: -case 0x3F02: -case 0x3F03: -case 0x3F04: -case 0x3F05: -case 0x3F06: -case 0x3F07: - -// MOVEW -case 0x3F00: -{ - u32 adr; - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x3208: -case 0x3408: -case 0x3608: -case 0x3808: -case 0x3A08: -case 0x3C08: -case 0x3E08: -case 0x3009: -case 0x3209: -case 0x3409: -case 0x3609: -case 0x3809: -case 0x3A09: -case 0x3C09: -case 0x3E09: -case 0x300A: -case 0x320A: -case 0x340A: -case 0x360A: -case 0x380A: -case 0x3A0A: -case 0x3C0A: -case 0x3E0A: -case 0x300B: -case 0x320B: -case 0x340B: -case 0x360B: -case 0x380B: -case 0x3A0B: -case 0x3C0B: -case 0x3E0B: -case 0x300C: -case 0x320C: -case 0x340C: -case 0x360C: -case 0x380C: -case 0x3A0C: -case 0x3C0C: -case 0x3E0C: -case 0x300D: -case 0x320D: -case 0x340D: -case 0x360D: -case 0x380D: -case 0x3A0D: -case 0x3C0D: -case 0x3E0D: -case 0x300E: -case 0x320E: -case 0x340E: -case 0x360E: -case 0x380E: -case 0x3A0E: -case 0x3C0E: -case 0x3E0E: -case 0x300F: -case 0x320F: -case 0x340F: -case 0x360F: -case 0x380F: -case 0x3A0F: -case 0x3C0F: -case 0x3E0F: - -// MOVEW -case 0x3008: -{ - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x3288: -case 0x3488: -case 0x3688: -case 0x3888: -case 0x3A88: -case 0x3C88: -case 0x3E88: -case 0x3089: -case 0x3289: -case 0x3489: -case 0x3689: -case 0x3889: -case 0x3A89: -case 0x3C89: -case 0x3E89: -case 0x308A: -case 0x328A: -case 0x348A: -case 0x368A: -case 0x388A: -case 0x3A8A: -case 0x3C8A: -case 0x3E8A: -case 0x308B: -case 0x328B: -case 0x348B: -case 0x368B: -case 0x388B: -case 0x3A8B: -case 0x3C8B: -case 0x3E8B: -case 0x308C: -case 0x328C: -case 0x348C: -case 0x368C: -case 0x388C: -case 0x3A8C: -case 0x3C8C: -case 0x3E8C: -case 0x308D: -case 0x328D: -case 0x348D: -case 0x368D: -case 0x388D: -case 0x3A8D: -case 0x3C8D: -case 0x3E8D: -case 0x308E: -case 0x328E: -case 0x348E: -case 0x368E: -case 0x388E: -case 0x3A8E: -case 0x3C8E: -case 0x3E8E: -case 0x308F: -case 0x328F: -case 0x348F: -case 0x368F: -case 0x388F: -case 0x3A8F: -case 0x3C8F: -case 0x3E8F: - -// MOVEW -case 0x3088: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x32C8: -case 0x34C8: -case 0x36C8: -case 0x38C8: -case 0x3AC8: -case 0x3CC8: -case 0x30C9: -case 0x32C9: -case 0x34C9: -case 0x36C9: -case 0x38C9: -case 0x3AC9: -case 0x3CC9: -case 0x30CA: -case 0x32CA: -case 0x34CA: -case 0x36CA: -case 0x38CA: -case 0x3ACA: -case 0x3CCA: -case 0x30CB: -case 0x32CB: -case 0x34CB: -case 0x36CB: -case 0x38CB: -case 0x3ACB: -case 0x3CCB: -case 0x30CC: -case 0x32CC: -case 0x34CC: -case 0x36CC: -case 0x38CC: -case 0x3ACC: -case 0x3CCC: -case 0x30CD: -case 0x32CD: -case 0x34CD: -case 0x36CD: -case 0x38CD: -case 0x3ACD: -case 0x3CCD: -case 0x30CE: -case 0x32CE: -case 0x34CE: -case 0x36CE: -case 0x38CE: -case 0x3ACE: -case 0x3CCE: -case 0x30CF: -case 0x32CF: -case 0x34CF: -case 0x36CF: -case 0x38CF: -case 0x3ACF: -case 0x3CCF: - -// MOVEW -case 0x30C8: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x3308: -case 0x3508: -case 0x3708: -case 0x3908: -case 0x3B08: -case 0x3D08: -case 0x3109: -case 0x3309: -case 0x3509: -case 0x3709: -case 0x3909: -case 0x3B09: -case 0x3D09: -case 0x310A: -case 0x330A: -case 0x350A: -case 0x370A: -case 0x390A: -case 0x3B0A: -case 0x3D0A: -case 0x310B: -case 0x330B: -case 0x350B: -case 0x370B: -case 0x390B: -case 0x3B0B: -case 0x3D0B: -case 0x310C: -case 0x330C: -case 0x350C: -case 0x370C: -case 0x390C: -case 0x3B0C: -case 0x3D0C: -case 0x310D: -case 0x330D: -case 0x350D: -case 0x370D: -case 0x390D: -case 0x3B0D: -case 0x3D0D: -case 0x310E: -case 0x330E: -case 0x350E: -case 0x370E: -case 0x390E: -case 0x3B0E: -case 0x3D0E: -case 0x310F: -case 0x330F: -case 0x350F: -case 0x370F: -case 0x390F: -case 0x3B0F: -case 0x3D0F: - -// MOVEW -case 0x3108: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x3348: -case 0x3548: -case 0x3748: -case 0x3948: -case 0x3B48: -case 0x3D48: -case 0x3F48: -case 0x3149: -case 0x3349: -case 0x3549: -case 0x3749: -case 0x3949: -case 0x3B49: -case 0x3D49: -case 0x3F49: -case 0x314A: -case 0x334A: -case 0x354A: -case 0x374A: -case 0x394A: -case 0x3B4A: -case 0x3D4A: -case 0x3F4A: -case 0x314B: -case 0x334B: -case 0x354B: -case 0x374B: -case 0x394B: -case 0x3B4B: -case 0x3D4B: -case 0x3F4B: -case 0x314C: -case 0x334C: -case 0x354C: -case 0x374C: -case 0x394C: -case 0x3B4C: -case 0x3D4C: -case 0x3F4C: -case 0x314D: -case 0x334D: -case 0x354D: -case 0x374D: -case 0x394D: -case 0x3B4D: -case 0x3D4D: -case 0x3F4D: -case 0x314E: -case 0x334E: -case 0x354E: -case 0x374E: -case 0x394E: -case 0x3B4E: -case 0x3D4E: -case 0x3F4E: -case 0x314F: -case 0x334F: -case 0x354F: -case 0x374F: -case 0x394F: -case 0x3B4F: -case 0x3D4F: -case 0x3F4F: - -// MOVEW -case 0x3148: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3388: -case 0x3588: -case 0x3788: -case 0x3988: -case 0x3B88: -case 0x3D88: -case 0x3F88: -case 0x3189: -case 0x3389: -case 0x3589: -case 0x3789: -case 0x3989: -case 0x3B89: -case 0x3D89: -case 0x3F89: -case 0x318A: -case 0x338A: -case 0x358A: -case 0x378A: -case 0x398A: -case 0x3B8A: -case 0x3D8A: -case 0x3F8A: -case 0x318B: -case 0x338B: -case 0x358B: -case 0x378B: -case 0x398B: -case 0x3B8B: -case 0x3D8B: -case 0x3F8B: -case 0x318C: -case 0x338C: -case 0x358C: -case 0x378C: -case 0x398C: -case 0x3B8C: -case 0x3D8C: -case 0x3F8C: -case 0x318D: -case 0x338D: -case 0x358D: -case 0x378D: -case 0x398D: -case 0x3B8D: -case 0x3D8D: -case 0x3F8D: -case 0x318E: -case 0x338E: -case 0x358E: -case 0x378E: -case 0x398E: -case 0x3B8E: -case 0x3D8E: -case 0x3F8E: -case 0x318F: -case 0x338F: -case 0x358F: -case 0x378F: -case 0x398F: -case 0x3B8F: -case 0x3D8F: -case 0x3F8F: - -// MOVEW -case 0x3188: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x31C9: -case 0x31CA: -case 0x31CB: -case 0x31CC: -case 0x31CD: -case 0x31CE: -case 0x31CF: - -// MOVEW -case 0x31C8: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x33C9: -case 0x33CA: -case 0x33CB: -case 0x33CC: -case 0x33CD: -case 0x33CE: -case 0x33CF: - -// MOVEW -case 0x33C8: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3EC9: -case 0x3ECA: -case 0x3ECB: -case 0x3ECC: -case 0x3ECD: -case 0x3ECE: -case 0x3ECF: - -// MOVEW -case 0x3EC8: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x3F09: -case 0x3F0A: -case 0x3F0B: -case 0x3F0C: -case 0x3F0D: -case 0x3F0E: -case 0x3F0F: - -// MOVEW -case 0x3F08: -{ - u32 adr; - u32 res; - res = (u16)CPU->A[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(8) -case 0x3210: -case 0x3410: -case 0x3610: -case 0x3810: -case 0x3A10: -case 0x3C10: -case 0x3E10: -case 0x3011: -case 0x3211: -case 0x3411: -case 0x3611: -case 0x3811: -case 0x3A11: -case 0x3C11: -case 0x3E11: -case 0x3012: -case 0x3212: -case 0x3412: -case 0x3612: -case 0x3812: -case 0x3A12: -case 0x3C12: -case 0x3E12: -case 0x3013: -case 0x3213: -case 0x3413: -case 0x3613: -case 0x3813: -case 0x3A13: -case 0x3C13: -case 0x3E13: -case 0x3014: -case 0x3214: -case 0x3414: -case 0x3614: -case 0x3814: -case 0x3A14: -case 0x3C14: -case 0x3E14: -case 0x3015: -case 0x3215: -case 0x3415: -case 0x3615: -case 0x3815: -case 0x3A15: -case 0x3C15: -case 0x3E15: -case 0x3016: -case 0x3216: -case 0x3416: -case 0x3616: -case 0x3816: -case 0x3A16: -case 0x3C16: -case 0x3E16: -case 0x3017: -case 0x3217: -case 0x3417: -case 0x3617: -case 0x3817: -case 0x3A17: -case 0x3C17: -case 0x3E17: - -// MOVEW -case 0x3010: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x3290: -case 0x3490: -case 0x3690: -case 0x3890: -case 0x3A90: -case 0x3C90: -case 0x3E90: -case 0x3091: -case 0x3291: -case 0x3491: -case 0x3691: -case 0x3891: -case 0x3A91: -case 0x3C91: -case 0x3E91: -case 0x3092: -case 0x3292: -case 0x3492: -case 0x3692: -case 0x3892: -case 0x3A92: -case 0x3C92: -case 0x3E92: -case 0x3093: -case 0x3293: -case 0x3493: -case 0x3693: -case 0x3893: -case 0x3A93: -case 0x3C93: -case 0x3E93: -case 0x3094: -case 0x3294: -case 0x3494: -case 0x3694: -case 0x3894: -case 0x3A94: -case 0x3C94: -case 0x3E94: -case 0x3095: -case 0x3295: -case 0x3495: -case 0x3695: -case 0x3895: -case 0x3A95: -case 0x3C95: -case 0x3E95: -case 0x3096: -case 0x3296: -case 0x3496: -case 0x3696: -case 0x3896: -case 0x3A96: -case 0x3C96: -case 0x3E96: -case 0x3097: -case 0x3297: -case 0x3497: -case 0x3697: -case 0x3897: -case 0x3A97: -case 0x3C97: -case 0x3E97: - -// MOVEW -case 0x3090: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x32D0: -case 0x34D0: -case 0x36D0: -case 0x38D0: -case 0x3AD0: -case 0x3CD0: -case 0x30D1: -case 0x32D1: -case 0x34D1: -case 0x36D1: -case 0x38D1: -case 0x3AD1: -case 0x3CD1: -case 0x30D2: -case 0x32D2: -case 0x34D2: -case 0x36D2: -case 0x38D2: -case 0x3AD2: -case 0x3CD2: -case 0x30D3: -case 0x32D3: -case 0x34D3: -case 0x36D3: -case 0x38D3: -case 0x3AD3: -case 0x3CD3: -case 0x30D4: -case 0x32D4: -case 0x34D4: -case 0x36D4: -case 0x38D4: -case 0x3AD4: -case 0x3CD4: -case 0x30D5: -case 0x32D5: -case 0x34D5: -case 0x36D5: -case 0x38D5: -case 0x3AD5: -case 0x3CD5: -case 0x30D6: -case 0x32D6: -case 0x34D6: -case 0x36D6: -case 0x38D6: -case 0x3AD6: -case 0x3CD6: -case 0x30D7: -case 0x32D7: -case 0x34D7: -case 0x36D7: -case 0x38D7: -case 0x3AD7: -case 0x3CD7: - -// MOVEW -case 0x30D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3310: -case 0x3510: -case 0x3710: -case 0x3910: -case 0x3B10: -case 0x3D10: -case 0x3111: -case 0x3311: -case 0x3511: -case 0x3711: -case 0x3911: -case 0x3B11: -case 0x3D11: -case 0x3112: -case 0x3312: -case 0x3512: -case 0x3712: -case 0x3912: -case 0x3B12: -case 0x3D12: -case 0x3113: -case 0x3313: -case 0x3513: -case 0x3713: -case 0x3913: -case 0x3B13: -case 0x3D13: -case 0x3114: -case 0x3314: -case 0x3514: -case 0x3714: -case 0x3914: -case 0x3B14: -case 0x3D14: -case 0x3115: -case 0x3315: -case 0x3515: -case 0x3715: -case 0x3915: -case 0x3B15: -case 0x3D15: -case 0x3116: -case 0x3316: -case 0x3516: -case 0x3716: -case 0x3916: -case 0x3B16: -case 0x3D16: -case 0x3117: -case 0x3317: -case 0x3517: -case 0x3717: -case 0x3917: -case 0x3B17: -case 0x3D17: - -// MOVEW -case 0x3110: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3350: -case 0x3550: -case 0x3750: -case 0x3950: -case 0x3B50: -case 0x3D50: -case 0x3F50: -case 0x3151: -case 0x3351: -case 0x3551: -case 0x3751: -case 0x3951: -case 0x3B51: -case 0x3D51: -case 0x3F51: -case 0x3152: -case 0x3352: -case 0x3552: -case 0x3752: -case 0x3952: -case 0x3B52: -case 0x3D52: -case 0x3F52: -case 0x3153: -case 0x3353: -case 0x3553: -case 0x3753: -case 0x3953: -case 0x3B53: -case 0x3D53: -case 0x3F53: -case 0x3154: -case 0x3354: -case 0x3554: -case 0x3754: -case 0x3954: -case 0x3B54: -case 0x3D54: -case 0x3F54: -case 0x3155: -case 0x3355: -case 0x3555: -case 0x3755: -case 0x3955: -case 0x3B55: -case 0x3D55: -case 0x3F55: -case 0x3156: -case 0x3356: -case 0x3556: -case 0x3756: -case 0x3956: -case 0x3B56: -case 0x3D56: -case 0x3F56: -case 0x3157: -case 0x3357: -case 0x3557: -case 0x3757: -case 0x3957: -case 0x3B57: -case 0x3D57: -case 0x3F57: - -// MOVEW -case 0x3150: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3390: -case 0x3590: -case 0x3790: -case 0x3990: -case 0x3B90: -case 0x3D90: -case 0x3F90: -case 0x3191: -case 0x3391: -case 0x3591: -case 0x3791: -case 0x3991: -case 0x3B91: -case 0x3D91: -case 0x3F91: -case 0x3192: -case 0x3392: -case 0x3592: -case 0x3792: -case 0x3992: -case 0x3B92: -case 0x3D92: -case 0x3F92: -case 0x3193: -case 0x3393: -case 0x3593: -case 0x3793: -case 0x3993: -case 0x3B93: -case 0x3D93: -case 0x3F93: -case 0x3194: -case 0x3394: -case 0x3594: -case 0x3794: -case 0x3994: -case 0x3B94: -case 0x3D94: -case 0x3F94: -case 0x3195: -case 0x3395: -case 0x3595: -case 0x3795: -case 0x3995: -case 0x3B95: -case 0x3D95: -case 0x3F95: -case 0x3196: -case 0x3396: -case 0x3596: -case 0x3796: -case 0x3996: -case 0x3B96: -case 0x3D96: -case 0x3F96: -case 0x3197: -case 0x3397: -case 0x3597: -case 0x3797: -case 0x3997: -case 0x3B97: -case 0x3D97: -case 0x3F97: - -// MOVEW -case 0x3190: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x31D1: -case 0x31D2: -case 0x31D3: -case 0x31D4: -case 0x31D5: -case 0x31D6: -case 0x31D7: - -// MOVEW -case 0x31D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x33D1: -case 0x33D2: -case 0x33D3: -case 0x33D4: -case 0x33D5: -case 0x33D6: -case 0x33D7: - -// MOVEW -case 0x33D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x3ED1: -case 0x3ED2: -case 0x3ED3: -case 0x3ED4: -case 0x3ED5: -case 0x3ED6: -case 0x3ED7: - -// MOVEW -case 0x3ED0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3F11: -case 0x3F12: -case 0x3F13: -case 0x3F14: -case 0x3F15: -case 0x3F16: -case 0x3F17: - -// MOVEW -case 0x3F10: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3218: -case 0x3418: -case 0x3618: -case 0x3818: -case 0x3A18: -case 0x3C18: -case 0x3E18: -case 0x3019: -case 0x3219: -case 0x3419: -case 0x3619: -case 0x3819: -case 0x3A19: -case 0x3C19: -case 0x3E19: -case 0x301A: -case 0x321A: -case 0x341A: -case 0x361A: -case 0x381A: -case 0x3A1A: -case 0x3C1A: -case 0x3E1A: -case 0x301B: -case 0x321B: -case 0x341B: -case 0x361B: -case 0x381B: -case 0x3A1B: -case 0x3C1B: -case 0x3E1B: -case 0x301C: -case 0x321C: -case 0x341C: -case 0x361C: -case 0x381C: -case 0x3A1C: -case 0x3C1C: -case 0x3E1C: -case 0x301D: -case 0x321D: -case 0x341D: -case 0x361D: -case 0x381D: -case 0x3A1D: -case 0x3C1D: -case 0x3E1D: -case 0x301E: -case 0x321E: -case 0x341E: -case 0x361E: -case 0x381E: -case 0x3A1E: -case 0x3C1E: -case 0x3E1E: - -// MOVEW -case 0x3018: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x3298: -case 0x3498: -case 0x3698: -case 0x3898: -case 0x3A98: -case 0x3C98: -case 0x3E98: -case 0x3099: -case 0x3299: -case 0x3499: -case 0x3699: -case 0x3899: -case 0x3A99: -case 0x3C99: -case 0x3E99: -case 0x309A: -case 0x329A: -case 0x349A: -case 0x369A: -case 0x389A: -case 0x3A9A: -case 0x3C9A: -case 0x3E9A: -case 0x309B: -case 0x329B: -case 0x349B: -case 0x369B: -case 0x389B: -case 0x3A9B: -case 0x3C9B: -case 0x3E9B: -case 0x309C: -case 0x329C: -case 0x349C: -case 0x369C: -case 0x389C: -case 0x3A9C: -case 0x3C9C: -case 0x3E9C: -case 0x309D: -case 0x329D: -case 0x349D: -case 0x369D: -case 0x389D: -case 0x3A9D: -case 0x3C9D: -case 0x3E9D: -case 0x309E: -case 0x329E: -case 0x349E: -case 0x369E: -case 0x389E: -case 0x3A9E: -case 0x3C9E: -case 0x3E9E: - -// MOVEW -case 0x3098: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x32D8: -case 0x34D8: -case 0x36D8: -case 0x38D8: -case 0x3AD8: -case 0x3CD8: -case 0x30D9: -case 0x32D9: -case 0x34D9: -case 0x36D9: -case 0x38D9: -case 0x3AD9: -case 0x3CD9: -case 0x30DA: -case 0x32DA: -case 0x34DA: -case 0x36DA: -case 0x38DA: -case 0x3ADA: -case 0x3CDA: -case 0x30DB: -case 0x32DB: -case 0x34DB: -case 0x36DB: -case 0x38DB: -case 0x3ADB: -case 0x3CDB: -case 0x30DC: -case 0x32DC: -case 0x34DC: -case 0x36DC: -case 0x38DC: -case 0x3ADC: -case 0x3CDC: -case 0x30DD: -case 0x32DD: -case 0x34DD: -case 0x36DD: -case 0x38DD: -case 0x3ADD: -case 0x3CDD: -case 0x30DE: -case 0x32DE: -case 0x34DE: -case 0x36DE: -case 0x38DE: -case 0x3ADE: -case 0x3CDE: - -// MOVEW -case 0x30D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3318: -case 0x3518: -case 0x3718: -case 0x3918: -case 0x3B18: -case 0x3D18: -case 0x3119: -case 0x3319: -case 0x3519: -case 0x3719: -case 0x3919: -case 0x3B19: -case 0x3D19: -case 0x311A: -case 0x331A: -case 0x351A: -case 0x371A: -case 0x391A: -case 0x3B1A: -case 0x3D1A: -case 0x311B: -case 0x331B: -case 0x351B: -case 0x371B: -case 0x391B: -case 0x3B1B: -case 0x3D1B: -case 0x311C: -case 0x331C: -case 0x351C: -case 0x371C: -case 0x391C: -case 0x3B1C: -case 0x3D1C: -case 0x311D: -case 0x331D: -case 0x351D: -case 0x371D: -case 0x391D: -case 0x3B1D: -case 0x3D1D: -case 0x311E: -case 0x331E: -case 0x351E: -case 0x371E: -case 0x391E: -case 0x3B1E: -case 0x3D1E: - -// MOVEW -case 0x3118: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3358: -case 0x3558: -case 0x3758: -case 0x3958: -case 0x3B58: -case 0x3D58: -case 0x3F58: -case 0x3159: -case 0x3359: -case 0x3559: -case 0x3759: -case 0x3959: -case 0x3B59: -case 0x3D59: -case 0x3F59: -case 0x315A: -case 0x335A: -case 0x355A: -case 0x375A: -case 0x395A: -case 0x3B5A: -case 0x3D5A: -case 0x3F5A: -case 0x315B: -case 0x335B: -case 0x355B: -case 0x375B: -case 0x395B: -case 0x3B5B: -case 0x3D5B: -case 0x3F5B: -case 0x315C: -case 0x335C: -case 0x355C: -case 0x375C: -case 0x395C: -case 0x3B5C: -case 0x3D5C: -case 0x3F5C: -case 0x315D: -case 0x335D: -case 0x355D: -case 0x375D: -case 0x395D: -case 0x3B5D: -case 0x3D5D: -case 0x3F5D: -case 0x315E: -case 0x335E: -case 0x355E: -case 0x375E: -case 0x395E: -case 0x3B5E: -case 0x3D5E: -case 0x3F5E: - -// MOVEW -case 0x3158: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3398: -case 0x3598: -case 0x3798: -case 0x3998: -case 0x3B98: -case 0x3D98: -case 0x3F98: -case 0x3199: -case 0x3399: -case 0x3599: -case 0x3799: -case 0x3999: -case 0x3B99: -case 0x3D99: -case 0x3F99: -case 0x319A: -case 0x339A: -case 0x359A: -case 0x379A: -case 0x399A: -case 0x3B9A: -case 0x3D9A: -case 0x3F9A: -case 0x319B: -case 0x339B: -case 0x359B: -case 0x379B: -case 0x399B: -case 0x3B9B: -case 0x3D9B: -case 0x3F9B: -case 0x319C: -case 0x339C: -case 0x359C: -case 0x379C: -case 0x399C: -case 0x3B9C: -case 0x3D9C: -case 0x3F9C: -case 0x319D: -case 0x339D: -case 0x359D: -case 0x379D: -case 0x399D: -case 0x3B9D: -case 0x3D9D: -case 0x3F9D: -case 0x319E: -case 0x339E: -case 0x359E: -case 0x379E: -case 0x399E: -case 0x3B9E: -case 0x3D9E: -case 0x3F9E: - -// MOVEW -case 0x3198: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x31D9: -case 0x31DA: -case 0x31DB: -case 0x31DC: -case 0x31DD: -case 0x31DE: - -// MOVEW -case 0x31D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x33D9: -case 0x33DA: -case 0x33DB: -case 0x33DC: -case 0x33DD: -case 0x33DE: - -// MOVEW -case 0x33D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x3ED9: -case 0x3EDA: -case 0x3EDB: -case 0x3EDC: -case 0x3EDD: -case 0x3EDE: - -// MOVEW -case 0x3ED8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3F19: -case 0x3F1A: -case 0x3F1B: -case 0x3F1C: -case 0x3F1D: -case 0x3F1E: - -// MOVEW -case 0x3F18: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3220: -case 0x3420: -case 0x3620: -case 0x3820: -case 0x3A20: -case 0x3C20: -case 0x3E20: -case 0x3021: -case 0x3221: -case 0x3421: -case 0x3621: -case 0x3821: -case 0x3A21: -case 0x3C21: -case 0x3E21: -case 0x3022: -case 0x3222: -case 0x3422: -case 0x3622: -case 0x3822: -case 0x3A22: -case 0x3C22: -case 0x3E22: -case 0x3023: -case 0x3223: -case 0x3423: -case 0x3623: -case 0x3823: -case 0x3A23: -case 0x3C23: -case 0x3E23: -case 0x3024: -case 0x3224: -case 0x3424: -case 0x3624: -case 0x3824: -case 0x3A24: -case 0x3C24: -case 0x3E24: -case 0x3025: -case 0x3225: -case 0x3425: -case 0x3625: -case 0x3825: -case 0x3A25: -case 0x3C25: -case 0x3E25: -case 0x3026: -case 0x3226: -case 0x3426: -case 0x3626: -case 0x3826: -case 0x3A26: -case 0x3C26: -case 0x3E26: - -// MOVEW -case 0x3020: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x32A0: -case 0x34A0: -case 0x36A0: -case 0x38A0: -case 0x3AA0: -case 0x3CA0: -case 0x3EA0: -case 0x30A1: -case 0x32A1: -case 0x34A1: -case 0x36A1: -case 0x38A1: -case 0x3AA1: -case 0x3CA1: -case 0x3EA1: -case 0x30A2: -case 0x32A2: -case 0x34A2: -case 0x36A2: -case 0x38A2: -case 0x3AA2: -case 0x3CA2: -case 0x3EA2: -case 0x30A3: -case 0x32A3: -case 0x34A3: -case 0x36A3: -case 0x38A3: -case 0x3AA3: -case 0x3CA3: -case 0x3EA3: -case 0x30A4: -case 0x32A4: -case 0x34A4: -case 0x36A4: -case 0x38A4: -case 0x3AA4: -case 0x3CA4: -case 0x3EA4: -case 0x30A5: -case 0x32A5: -case 0x34A5: -case 0x36A5: -case 0x38A5: -case 0x3AA5: -case 0x3CA5: -case 0x3EA5: -case 0x30A6: -case 0x32A6: -case 0x34A6: -case 0x36A6: -case 0x38A6: -case 0x3AA6: -case 0x3CA6: -case 0x3EA6: - -// MOVEW -case 0x30A0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x32E0: -case 0x34E0: -case 0x36E0: -case 0x38E0: -case 0x3AE0: -case 0x3CE0: -case 0x30E1: -case 0x32E1: -case 0x34E1: -case 0x36E1: -case 0x38E1: -case 0x3AE1: -case 0x3CE1: -case 0x30E2: -case 0x32E2: -case 0x34E2: -case 0x36E2: -case 0x38E2: -case 0x3AE2: -case 0x3CE2: -case 0x30E3: -case 0x32E3: -case 0x34E3: -case 0x36E3: -case 0x38E3: -case 0x3AE3: -case 0x3CE3: -case 0x30E4: -case 0x32E4: -case 0x34E4: -case 0x36E4: -case 0x38E4: -case 0x3AE4: -case 0x3CE4: -case 0x30E5: -case 0x32E5: -case 0x34E5: -case 0x36E5: -case 0x38E5: -case 0x3AE5: -case 0x3CE5: -case 0x30E6: -case 0x32E6: -case 0x34E6: -case 0x36E6: -case 0x38E6: -case 0x3AE6: -case 0x3CE6: - -// MOVEW -case 0x30E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x3320: -case 0x3520: -case 0x3720: -case 0x3920: -case 0x3B20: -case 0x3D20: -case 0x3121: -case 0x3321: -case 0x3521: -case 0x3721: -case 0x3921: -case 0x3B21: -case 0x3D21: -case 0x3122: -case 0x3322: -case 0x3522: -case 0x3722: -case 0x3922: -case 0x3B22: -case 0x3D22: -case 0x3123: -case 0x3323: -case 0x3523: -case 0x3723: -case 0x3923: -case 0x3B23: -case 0x3D23: -case 0x3124: -case 0x3324: -case 0x3524: -case 0x3724: -case 0x3924: -case 0x3B24: -case 0x3D24: -case 0x3125: -case 0x3325: -case 0x3525: -case 0x3725: -case 0x3925: -case 0x3B25: -case 0x3D25: -case 0x3126: -case 0x3326: -case 0x3526: -case 0x3726: -case 0x3926: -case 0x3B26: -case 0x3D26: - -// MOVEW -case 0x3120: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x3360: -case 0x3560: -case 0x3760: -case 0x3960: -case 0x3B60: -case 0x3D60: -case 0x3F60: -case 0x3161: -case 0x3361: -case 0x3561: -case 0x3761: -case 0x3961: -case 0x3B61: -case 0x3D61: -case 0x3F61: -case 0x3162: -case 0x3362: -case 0x3562: -case 0x3762: -case 0x3962: -case 0x3B62: -case 0x3D62: -case 0x3F62: -case 0x3163: -case 0x3363: -case 0x3563: -case 0x3763: -case 0x3963: -case 0x3B63: -case 0x3D63: -case 0x3F63: -case 0x3164: -case 0x3364: -case 0x3564: -case 0x3764: -case 0x3964: -case 0x3B64: -case 0x3D64: -case 0x3F64: -case 0x3165: -case 0x3365: -case 0x3565: -case 0x3765: -case 0x3965: -case 0x3B65: -case 0x3D65: -case 0x3F65: -case 0x3166: -case 0x3366: -case 0x3566: -case 0x3766: -case 0x3966: -case 0x3B66: -case 0x3D66: -case 0x3F66: - -// MOVEW -case 0x3160: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x33A0: -case 0x35A0: -case 0x37A0: -case 0x39A0: -case 0x3BA0: -case 0x3DA0: -case 0x3FA0: -case 0x31A1: -case 0x33A1: -case 0x35A1: -case 0x37A1: -case 0x39A1: -case 0x3BA1: -case 0x3DA1: -case 0x3FA1: -case 0x31A2: -case 0x33A2: -case 0x35A2: -case 0x37A2: -case 0x39A2: -case 0x3BA2: -case 0x3DA2: -case 0x3FA2: -case 0x31A3: -case 0x33A3: -case 0x35A3: -case 0x37A3: -case 0x39A3: -case 0x3BA3: -case 0x3DA3: -case 0x3FA3: -case 0x31A4: -case 0x33A4: -case 0x35A4: -case 0x37A4: -case 0x39A4: -case 0x3BA4: -case 0x3DA4: -case 0x3FA4: -case 0x31A5: -case 0x33A5: -case 0x35A5: -case 0x37A5: -case 0x39A5: -case 0x3BA5: -case 0x3DA5: -case 0x3FA5: -case 0x31A6: -case 0x33A6: -case 0x35A6: -case 0x37A6: -case 0x39A6: -case 0x3BA6: -case 0x3DA6: -case 0x3FA6: - -// MOVEW -case 0x31A0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x31E1: -case 0x31E2: -case 0x31E3: -case 0x31E4: -case 0x31E5: -case 0x31E6: - -// MOVEW -case 0x31E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x33E1: -case 0x33E2: -case 0x33E3: -case 0x33E4: -case 0x33E5: -case 0x33E6: - -// MOVEW -case 0x33E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) -case 0x3EE1: -case 0x3EE2: -case 0x3EE3: -case 0x3EE4: -case 0x3EE5: -case 0x3EE6: - -// MOVEW -case 0x3EE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x3F21: -case 0x3F22: -case 0x3F23: -case 0x3F24: -case 0x3F25: -case 0x3F26: - -// MOVEW -case 0x3F20: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x3228: -case 0x3428: -case 0x3628: -case 0x3828: -case 0x3A28: -case 0x3C28: -case 0x3E28: -case 0x3029: -case 0x3229: -case 0x3429: -case 0x3629: -case 0x3829: -case 0x3A29: -case 0x3C29: -case 0x3E29: -case 0x302A: -case 0x322A: -case 0x342A: -case 0x362A: -case 0x382A: -case 0x3A2A: -case 0x3C2A: -case 0x3E2A: -case 0x302B: -case 0x322B: -case 0x342B: -case 0x362B: -case 0x382B: -case 0x3A2B: -case 0x3C2B: -case 0x3E2B: -case 0x302C: -case 0x322C: -case 0x342C: -case 0x362C: -case 0x382C: -case 0x3A2C: -case 0x3C2C: -case 0x3E2C: -case 0x302D: -case 0x322D: -case 0x342D: -case 0x362D: -case 0x382D: -case 0x3A2D: -case 0x3C2D: -case 0x3E2D: -case 0x302E: -case 0x322E: -case 0x342E: -case 0x362E: -case 0x382E: -case 0x3A2E: -case 0x3C2E: -case 0x3E2E: -case 0x302F: -case 0x322F: -case 0x342F: -case 0x362F: -case 0x382F: -case 0x3A2F: -case 0x3C2F: -case 0x3E2F: - -// MOVEW -case 0x3028: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x32A8: -case 0x34A8: -case 0x36A8: -case 0x38A8: -case 0x3AA8: -case 0x3CA8: -case 0x3EA8: -case 0x30A9: -case 0x32A9: -case 0x34A9: -case 0x36A9: -case 0x38A9: -case 0x3AA9: -case 0x3CA9: -case 0x3EA9: -case 0x30AA: -case 0x32AA: -case 0x34AA: -case 0x36AA: -case 0x38AA: -case 0x3AAA: -case 0x3CAA: -case 0x3EAA: -case 0x30AB: -case 0x32AB: -case 0x34AB: -case 0x36AB: -case 0x38AB: -case 0x3AAB: -case 0x3CAB: -case 0x3EAB: -case 0x30AC: -case 0x32AC: -case 0x34AC: -case 0x36AC: -case 0x38AC: -case 0x3AAC: -case 0x3CAC: -case 0x3EAC: -case 0x30AD: -case 0x32AD: -case 0x34AD: -case 0x36AD: -case 0x38AD: -case 0x3AAD: -case 0x3CAD: -case 0x3EAD: -case 0x30AE: -case 0x32AE: -case 0x34AE: -case 0x36AE: -case 0x38AE: -case 0x3AAE: -case 0x3CAE: -case 0x3EAE: -case 0x30AF: -case 0x32AF: -case 0x34AF: -case 0x36AF: -case 0x38AF: -case 0x3AAF: -case 0x3CAF: -case 0x3EAF: - -// MOVEW -case 0x30A8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x32E8: -case 0x34E8: -case 0x36E8: -case 0x38E8: -case 0x3AE8: -case 0x3CE8: -case 0x30E9: -case 0x32E9: -case 0x34E9: -case 0x36E9: -case 0x38E9: -case 0x3AE9: -case 0x3CE9: -case 0x30EA: -case 0x32EA: -case 0x34EA: -case 0x36EA: -case 0x38EA: -case 0x3AEA: -case 0x3CEA: -case 0x30EB: -case 0x32EB: -case 0x34EB: -case 0x36EB: -case 0x38EB: -case 0x3AEB: -case 0x3CEB: -case 0x30EC: -case 0x32EC: -case 0x34EC: -case 0x36EC: -case 0x38EC: -case 0x3AEC: -case 0x3CEC: -case 0x30ED: -case 0x32ED: -case 0x34ED: -case 0x36ED: -case 0x38ED: -case 0x3AED: -case 0x3CED: -case 0x30EE: -case 0x32EE: -case 0x34EE: -case 0x36EE: -case 0x38EE: -case 0x3AEE: -case 0x3CEE: -case 0x30EF: -case 0x32EF: -case 0x34EF: -case 0x36EF: -case 0x38EF: -case 0x3AEF: -case 0x3CEF: - -// MOVEW -case 0x30E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3328: -case 0x3528: -case 0x3728: -case 0x3928: -case 0x3B28: -case 0x3D28: -case 0x3129: -case 0x3329: -case 0x3529: -case 0x3729: -case 0x3929: -case 0x3B29: -case 0x3D29: -case 0x312A: -case 0x332A: -case 0x352A: -case 0x372A: -case 0x392A: -case 0x3B2A: -case 0x3D2A: -case 0x312B: -case 0x332B: -case 0x352B: -case 0x372B: -case 0x392B: -case 0x3B2B: -case 0x3D2B: -case 0x312C: -case 0x332C: -case 0x352C: -case 0x372C: -case 0x392C: -case 0x3B2C: -case 0x3D2C: -case 0x312D: -case 0x332D: -case 0x352D: -case 0x372D: -case 0x392D: -case 0x3B2D: -case 0x3D2D: -case 0x312E: -case 0x332E: -case 0x352E: -case 0x372E: -case 0x392E: -case 0x3B2E: -case 0x3D2E: -case 0x312F: -case 0x332F: -case 0x352F: -case 0x372F: -case 0x392F: -case 0x3B2F: -case 0x3D2F: - -// MOVEW -case 0x3128: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3368: -case 0x3568: -case 0x3768: -case 0x3968: -case 0x3B68: -case 0x3D68: -case 0x3F68: -case 0x3169: -case 0x3369: -case 0x3569: -case 0x3769: -case 0x3969: -case 0x3B69: -case 0x3D69: -case 0x3F69: -case 0x316A: -case 0x336A: -case 0x356A: -case 0x376A: -case 0x396A: -case 0x3B6A: -case 0x3D6A: -case 0x3F6A: -case 0x316B: -case 0x336B: -case 0x356B: -case 0x376B: -case 0x396B: -case 0x3B6B: -case 0x3D6B: -case 0x3F6B: -case 0x316C: -case 0x336C: -case 0x356C: -case 0x376C: -case 0x396C: -case 0x3B6C: -case 0x3D6C: -case 0x3F6C: -case 0x316D: -case 0x336D: -case 0x356D: -case 0x376D: -case 0x396D: -case 0x3B6D: -case 0x3D6D: -case 0x3F6D: -case 0x316E: -case 0x336E: -case 0x356E: -case 0x376E: -case 0x396E: -case 0x3B6E: -case 0x3D6E: -case 0x3F6E: -case 0x316F: -case 0x336F: -case 0x356F: -case 0x376F: -case 0x396F: -case 0x3B6F: -case 0x3D6F: -case 0x3F6F: - -// MOVEW -case 0x3168: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x33A8: -case 0x35A8: -case 0x37A8: -case 0x39A8: -case 0x3BA8: -case 0x3DA8: -case 0x3FA8: -case 0x31A9: -case 0x33A9: -case 0x35A9: -case 0x37A9: -case 0x39A9: -case 0x3BA9: -case 0x3DA9: -case 0x3FA9: -case 0x31AA: -case 0x33AA: -case 0x35AA: -case 0x37AA: -case 0x39AA: -case 0x3BAA: -case 0x3DAA: -case 0x3FAA: -case 0x31AB: -case 0x33AB: -case 0x35AB: -case 0x37AB: -case 0x39AB: -case 0x3BAB: -case 0x3DAB: -case 0x3FAB: -case 0x31AC: -case 0x33AC: -case 0x35AC: -case 0x37AC: -case 0x39AC: -case 0x3BAC: -case 0x3DAC: -case 0x3FAC: -case 0x31AD: -case 0x33AD: -case 0x35AD: -case 0x37AD: -case 0x39AD: -case 0x3BAD: -case 0x3DAD: -case 0x3FAD: -case 0x31AE: -case 0x33AE: -case 0x35AE: -case 0x37AE: -case 0x39AE: -case 0x3BAE: -case 0x3DAE: -case 0x3FAE: -case 0x31AF: -case 0x33AF: -case 0x35AF: -case 0x37AF: -case 0x39AF: -case 0x3BAF: -case 0x3DAF: -case 0x3FAF: - -// MOVEW -case 0x31A8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) -case 0x31E9: -case 0x31EA: -case 0x31EB: -case 0x31EC: -case 0x31ED: -case 0x31EE: -case 0x31EF: - -// MOVEW -case 0x31E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x33E9: -case 0x33EA: -case 0x33EB: -case 0x33EC: -case 0x33ED: -case 0x33EE: -case 0x33EF: - -// MOVEW -case 0x33E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) -case 0x3EE9: -case 0x3EEA: -case 0x3EEB: -case 0x3EEC: -case 0x3EED: -case 0x3EEE: -case 0x3EEF: - -// MOVEW -case 0x3EE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3F29: -case 0x3F2A: -case 0x3F2B: -case 0x3F2C: -case 0x3F2D: -case 0x3F2E: -case 0x3F2F: - -// MOVEW -case 0x3F28: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3230: -case 0x3430: -case 0x3630: -case 0x3830: -case 0x3A30: -case 0x3C30: -case 0x3E30: -case 0x3031: -case 0x3231: -case 0x3431: -case 0x3631: -case 0x3831: -case 0x3A31: -case 0x3C31: -case 0x3E31: -case 0x3032: -case 0x3232: -case 0x3432: -case 0x3632: -case 0x3832: -case 0x3A32: -case 0x3C32: -case 0x3E32: -case 0x3033: -case 0x3233: -case 0x3433: -case 0x3633: -case 0x3833: -case 0x3A33: -case 0x3C33: -case 0x3E33: -case 0x3034: -case 0x3234: -case 0x3434: -case 0x3634: -case 0x3834: -case 0x3A34: -case 0x3C34: -case 0x3E34: -case 0x3035: -case 0x3235: -case 0x3435: -case 0x3635: -case 0x3835: -case 0x3A35: -case 0x3C35: -case 0x3E35: -case 0x3036: -case 0x3236: -case 0x3436: -case 0x3636: -case 0x3836: -case 0x3A36: -case 0x3C36: -case 0x3E36: -case 0x3037: -case 0x3237: -case 0x3437: -case 0x3637: -case 0x3837: -case 0x3A37: -case 0x3C37: -case 0x3E37: - -// MOVEW -case 0x3030: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x32B0: -case 0x34B0: -case 0x36B0: -case 0x38B0: -case 0x3AB0: -case 0x3CB0: -case 0x3EB0: -case 0x30B1: -case 0x32B1: -case 0x34B1: -case 0x36B1: -case 0x38B1: -case 0x3AB1: -case 0x3CB1: -case 0x3EB1: -case 0x30B2: -case 0x32B2: -case 0x34B2: -case 0x36B2: -case 0x38B2: -case 0x3AB2: -case 0x3CB2: -case 0x3EB2: -case 0x30B3: -case 0x32B3: -case 0x34B3: -case 0x36B3: -case 0x38B3: -case 0x3AB3: -case 0x3CB3: -case 0x3EB3: -case 0x30B4: -case 0x32B4: -case 0x34B4: -case 0x36B4: -case 0x38B4: -case 0x3AB4: -case 0x3CB4: -case 0x3EB4: -case 0x30B5: -case 0x32B5: -case 0x34B5: -case 0x36B5: -case 0x38B5: -case 0x3AB5: -case 0x3CB5: -case 0x3EB5: -case 0x30B6: -case 0x32B6: -case 0x34B6: -case 0x36B6: -case 0x38B6: -case 0x3AB6: -case 0x3CB6: -case 0x3EB6: -case 0x30B7: -case 0x32B7: -case 0x34B7: -case 0x36B7: -case 0x38B7: -case 0x3AB7: -case 0x3CB7: -case 0x3EB7: - -// MOVEW -case 0x30B0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x32F0: -case 0x34F0: -case 0x36F0: -case 0x38F0: -case 0x3AF0: -case 0x3CF0: -case 0x30F1: -case 0x32F1: -case 0x34F1: -case 0x36F1: -case 0x38F1: -case 0x3AF1: -case 0x3CF1: -case 0x30F2: -case 0x32F2: -case 0x34F2: -case 0x36F2: -case 0x38F2: -case 0x3AF2: -case 0x3CF2: -case 0x30F3: -case 0x32F3: -case 0x34F3: -case 0x36F3: -case 0x38F3: -case 0x3AF3: -case 0x3CF3: -case 0x30F4: -case 0x32F4: -case 0x34F4: -case 0x36F4: -case 0x38F4: -case 0x3AF4: -case 0x3CF4: -case 0x30F5: -case 0x32F5: -case 0x34F5: -case 0x36F5: -case 0x38F5: -case 0x3AF5: -case 0x3CF5: -case 0x30F6: -case 0x32F6: -case 0x34F6: -case 0x36F6: -case 0x38F6: -case 0x3AF6: -case 0x3CF6: -case 0x30F7: -case 0x32F7: -case 0x34F7: -case 0x36F7: -case 0x38F7: -case 0x3AF7: -case 0x3CF7: - -// MOVEW -case 0x30F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x3330: -case 0x3530: -case 0x3730: -case 0x3930: -case 0x3B30: -case 0x3D30: -case 0x3131: -case 0x3331: -case 0x3531: -case 0x3731: -case 0x3931: -case 0x3B31: -case 0x3D31: -case 0x3132: -case 0x3332: -case 0x3532: -case 0x3732: -case 0x3932: -case 0x3B32: -case 0x3D32: -case 0x3133: -case 0x3333: -case 0x3533: -case 0x3733: -case 0x3933: -case 0x3B33: -case 0x3D33: -case 0x3134: -case 0x3334: -case 0x3534: -case 0x3734: -case 0x3934: -case 0x3B34: -case 0x3D34: -case 0x3135: -case 0x3335: -case 0x3535: -case 0x3735: -case 0x3935: -case 0x3B35: -case 0x3D35: -case 0x3136: -case 0x3336: -case 0x3536: -case 0x3736: -case 0x3936: -case 0x3B36: -case 0x3D36: -case 0x3137: -case 0x3337: -case 0x3537: -case 0x3737: -case 0x3937: -case 0x3B37: -case 0x3D37: - -// MOVEW -case 0x3130: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x3370: -case 0x3570: -case 0x3770: -case 0x3970: -case 0x3B70: -case 0x3D70: -case 0x3F70: -case 0x3171: -case 0x3371: -case 0x3571: -case 0x3771: -case 0x3971: -case 0x3B71: -case 0x3D71: -case 0x3F71: -case 0x3172: -case 0x3372: -case 0x3572: -case 0x3772: -case 0x3972: -case 0x3B72: -case 0x3D72: -case 0x3F72: -case 0x3173: -case 0x3373: -case 0x3573: -case 0x3773: -case 0x3973: -case 0x3B73: -case 0x3D73: -case 0x3F73: -case 0x3174: -case 0x3374: -case 0x3574: -case 0x3774: -case 0x3974: -case 0x3B74: -case 0x3D74: -case 0x3F74: -case 0x3175: -case 0x3375: -case 0x3575: -case 0x3775: -case 0x3975: -case 0x3B75: -case 0x3D75: -case 0x3F75: -case 0x3176: -case 0x3376: -case 0x3576: -case 0x3776: -case 0x3976: -case 0x3B76: -case 0x3D76: -case 0x3F76: -case 0x3177: -case 0x3377: -case 0x3577: -case 0x3777: -case 0x3977: -case 0x3B77: -case 0x3D77: -case 0x3F77: - -// MOVEW -case 0x3170: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) -case 0x33B0: -case 0x35B0: -case 0x37B0: -case 0x39B0: -case 0x3BB0: -case 0x3DB0: -case 0x3FB0: -case 0x31B1: -case 0x33B1: -case 0x35B1: -case 0x37B1: -case 0x39B1: -case 0x3BB1: -case 0x3DB1: -case 0x3FB1: -case 0x31B2: -case 0x33B2: -case 0x35B2: -case 0x37B2: -case 0x39B2: -case 0x3BB2: -case 0x3DB2: -case 0x3FB2: -case 0x31B3: -case 0x33B3: -case 0x35B3: -case 0x37B3: -case 0x39B3: -case 0x3BB3: -case 0x3DB3: -case 0x3FB3: -case 0x31B4: -case 0x33B4: -case 0x35B4: -case 0x37B4: -case 0x39B4: -case 0x3BB4: -case 0x3DB4: -case 0x3FB4: -case 0x31B5: -case 0x33B5: -case 0x35B5: -case 0x37B5: -case 0x39B5: -case 0x3BB5: -case 0x3DB5: -case 0x3FB5: -case 0x31B6: -case 0x33B6: -case 0x35B6: -case 0x37B6: -case 0x39B6: -case 0x3BB6: -case 0x3DB6: -case 0x3FB6: -case 0x31B7: -case 0x33B7: -case 0x35B7: -case 0x37B7: -case 0x39B7: -case 0x3BB7: -case 0x3DB7: -case 0x3FB7: - -// MOVEW -case 0x31B0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) -case 0x31F1: -case 0x31F2: -case 0x31F3: -case 0x31F4: -case 0x31F5: -case 0x31F6: -case 0x31F7: - -// MOVEW -case 0x31F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) -case 0x33F1: -case 0x33F2: -case 0x33F3: -case 0x33F4: -case 0x33F5: -case 0x33F6: -case 0x33F7: - -// MOVEW -case 0x33F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(26) -case 0x3EF1: -case 0x3EF2: -case 0x3EF3: -case 0x3EF4: -case 0x3EF5: -case 0x3EF6: -case 0x3EF7: - -// MOVEW -case 0x3EF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x3F31: -case 0x3F32: -case 0x3F33: -case 0x3F34: -case 0x3F35: -case 0x3F36: -case 0x3F37: - -// MOVEW -case 0x3F30: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x3238: -case 0x3438: -case 0x3638: -case 0x3838: -case 0x3A38: -case 0x3C38: -case 0x3E38: - -// MOVEW -case 0x3038: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x32B8: -case 0x34B8: -case 0x36B8: -case 0x38B8: -case 0x3AB8: -case 0x3CB8: -case 0x3EB8: - -// MOVEW -case 0x30B8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x32F8: -case 0x34F8: -case 0x36F8: -case 0x38F8: -case 0x3AF8: -case 0x3CF8: - -// MOVEW -case 0x30F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3338: -case 0x3538: -case 0x3738: -case 0x3938: -case 0x3B38: -case 0x3D38: - -// MOVEW -case 0x3138: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3378: -case 0x3578: -case 0x3778: -case 0x3978: -case 0x3B78: -case 0x3D78: -case 0x3F78: - -// MOVEW -case 0x3178: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x33B8: -case 0x35B8: -case 0x37B8: -case 0x39B8: -case 0x3BB8: -case 0x3DB8: -case 0x3FB8: - -// MOVEW -case 0x31B8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// MOVEW -case 0x31F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// MOVEW -case 0x33F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// MOVEW -case 0x3EF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// MOVEW -case 0x3F38: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x3239: -case 0x3439: -case 0x3639: -case 0x3839: -case 0x3A39: -case 0x3C39: -case 0x3E39: - -// MOVEW -case 0x3039: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x32B9: -case 0x34B9: -case 0x36B9: -case 0x38B9: -case 0x3AB9: -case 0x3CB9: -case 0x3EB9: - -// MOVEW -case 0x30B9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x32F9: -case 0x34F9: -case 0x36F9: -case 0x38F9: -case 0x3AF9: -case 0x3CF9: - -// MOVEW -case 0x30F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x3339: -case 0x3539: -case 0x3739: -case 0x3939: -case 0x3B39: -case 0x3D39: - -// MOVEW -case 0x3139: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x3379: -case 0x3579: -case 0x3779: -case 0x3979: -case 0x3B79: -case 0x3D79: -case 0x3F79: - -// MOVEW -case 0x3179: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) -case 0x33B9: -case 0x35B9: -case 0x37B9: -case 0x39B9: -case 0x3BB9: -case 0x3DB9: -case 0x3FB9: - -// MOVEW -case 0x31B9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(26) - -// MOVEW -case 0x31F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// MOVEW -case 0x33F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(28) - -// MOVEW -case 0x3EF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// MOVEW -case 0x3F39: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x323A: -case 0x343A: -case 0x363A: -case 0x383A: -case 0x3A3A: -case 0x3C3A: -case 0x3E3A: - -// MOVEW -case 0x303A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x32BA: -case 0x34BA: -case 0x36BA: -case 0x38BA: -case 0x3ABA: -case 0x3CBA: -case 0x3EBA: - -// MOVEW -case 0x30BA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x32FA: -case 0x34FA: -case 0x36FA: -case 0x38FA: -case 0x3AFA: -case 0x3CFA: - -// MOVEW -case 0x30FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x333A: -case 0x353A: -case 0x373A: -case 0x393A: -case 0x3B3A: -case 0x3D3A: - -// MOVEW -case 0x313A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x337A: -case 0x357A: -case 0x377A: -case 0x397A: -case 0x3B7A: -case 0x3D7A: -case 0x3F7A: - -// MOVEW -case 0x317A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x33BA: -case 0x35BA: -case 0x37BA: -case 0x39BA: -case 0x3BBA: -case 0x3DBA: -case 0x3FBA: - -// MOVEW -case 0x31BA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// MOVEW -case 0x31FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// MOVEW -case 0x33FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// MOVEW -case 0x3EFA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// MOVEW -case 0x3F3A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x323B: -case 0x343B: -case 0x363B: -case 0x383B: -case 0x3A3B: -case 0x3C3B: -case 0x3E3B: - -// MOVEW -case 0x303B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x32BB: -case 0x34BB: -case 0x36BB: -case 0x38BB: -case 0x3ABB: -case 0x3CBB: -case 0x3EBB: - -// MOVEW -case 0x30BB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x32FB: -case 0x34FB: -case 0x36FB: -case 0x38FB: -case 0x3AFB: -case 0x3CFB: - -// MOVEW -case 0x30FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x333B: -case 0x353B: -case 0x373B: -case 0x393B: -case 0x3B3B: -case 0x3D3B: - -// MOVEW -case 0x313B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x337B: -case 0x357B: -case 0x377B: -case 0x397B: -case 0x3B7B: -case 0x3D7B: -case 0x3F7B: - -// MOVEW -case 0x317B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) -case 0x33BB: -case 0x35BB: -case 0x37BB: -case 0x39BB: -case 0x3BBB: -case 0x3DBB: -case 0x3FBB: - -// MOVEW -case 0x31BB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(24) - -// MOVEW -case 0x31FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// MOVEW -case 0x33FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(26) - -// MOVEW -case 0x3EFB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// MOVEW -case 0x3F3B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x323C: -case 0x343C: -case 0x363C: -case 0x383C: -case 0x3A3C: -case 0x3C3C: -case 0x3E3C: - -// MOVEW -case 0x303C: -{ - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0x32BC: -case 0x34BC: -case 0x36BC: -case 0x38BC: -case 0x3ABC: -case 0x3CBC: -case 0x3EBC: - -// MOVEW -case 0x30BC: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x32FC: -case 0x34FC: -case 0x36FC: -case 0x38FC: -case 0x3AFC: -case 0x3CFC: - -// MOVEW -case 0x30FC: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x333C: -case 0x353C: -case 0x373C: -case 0x393C: -case 0x3B3C: -case 0x3D3C: - -// MOVEW -case 0x313C: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x337C: -case 0x357C: -case 0x377C: -case 0x397C: -case 0x3B7C: -case 0x3D7C: -case 0x3F7C: - -// MOVEW -case 0x317C: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x33BC: -case 0x35BC: -case 0x37BC: -case 0x39BC: -case 0x3BBC: -case 0x3DBC: -case 0x3FBC: - -// MOVEW -case 0x31BC: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// MOVEW -case 0x31FC: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// MOVEW -case 0x33FC: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// MOVEW -case 0x3EFC: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// MOVEW -case 0x3F3C: -{ - u32 adr; - u32 res; - res = FETCH_WORD; - PC += 2; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x321F: -case 0x341F: -case 0x361F: -case 0x381F: -case 0x3A1F: -case 0x3C1F: -case 0x3E1F: - -// MOVEW -case 0x301F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x329F: -case 0x349F: -case 0x369F: -case 0x389F: -case 0x3A9F: -case 0x3C9F: -case 0x3E9F: - -// MOVEW -case 0x309F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x32DF: -case 0x34DF: -case 0x36DF: -case 0x38DF: -case 0x3ADF: -case 0x3CDF: - -// MOVEW -case 0x30DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x331F: -case 0x351F: -case 0x371F: -case 0x391F: -case 0x3B1F: -case 0x3D1F: - -// MOVEW -case 0x311F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x335F: -case 0x355F: -case 0x375F: -case 0x395F: -case 0x3B5F: -case 0x3D5F: -case 0x3F5F: - -// MOVEW -case 0x315F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x339F: -case 0x359F: -case 0x379F: -case 0x399F: -case 0x3B9F: -case 0x3D9F: -case 0x3F9F: - -// MOVEW -case 0x319F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// MOVEW -case 0x31DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// MOVEW -case 0x33DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// MOVEW -case 0x3EDF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// MOVEW -case 0x3F1F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x3227: -case 0x3427: -case 0x3627: -case 0x3827: -case 0x3A27: -case 0x3C27: -case 0x3E27: - -// MOVEW -case 0x3027: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x32A7: -case 0x34A7: -case 0x36A7: -case 0x38A7: -case 0x3AA7: -case 0x3CA7: -case 0x3EA7: - -// MOVEW -case 0x30A7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x32E7: -case 0x34E7: -case 0x36E7: -case 0x38E7: -case 0x3AE7: -case 0x3CE7: - -// MOVEW -case 0x30E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x3327: -case 0x3527: -case 0x3727: -case 0x3927: -case 0x3B27: -case 0x3D27: - -// MOVEW -case 0x3127: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x3367: -case 0x3567: -case 0x3767: -case 0x3967: -case 0x3B67: -case 0x3D67: -case 0x3F67: - -// MOVEW -case 0x3167: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x33A7: -case 0x35A7: -case 0x37A7: -case 0x39A7: -case 0x3BA7: -case 0x3DA7: -case 0x3FA7: - -// MOVEW -case 0x31A7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[(Opcode >> 9) & 7]; - DECODE_EXT_WORD - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// MOVEW -case 0x31E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// MOVEW -case 0x33E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = (s32)FETCH_LONG; - PC += 4; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(22) - -// MOVEW -case 0x3EE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7]; - CPU->A[7] += 2; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) - -// MOVEW -case 0x3F27: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x3240: -case 0x3440: -case 0x3640: -case 0x3840: -case 0x3A40: -case 0x3C40: -case 0x3E40: -case 0x3041: -case 0x3241: -case 0x3441: -case 0x3641: -case 0x3841: -case 0x3A41: -case 0x3C41: -case 0x3E41: -case 0x3042: -case 0x3242: -case 0x3442: -case 0x3642: -case 0x3842: -case 0x3A42: -case 0x3C42: -case 0x3E42: -case 0x3043: -case 0x3243: -case 0x3443: -case 0x3643: -case 0x3843: -case 0x3A43: -case 0x3C43: -case 0x3E43: -case 0x3044: -case 0x3244: -case 0x3444: -case 0x3644: -case 0x3844: -case 0x3A44: -case 0x3C44: -case 0x3E44: -case 0x3045: -case 0x3245: -case 0x3445: -case 0x3645: -case 0x3845: -case 0x3A45: -case 0x3C45: -case 0x3E45: -case 0x3046: -case 0x3246: -case 0x3446: -case 0x3646: -case 0x3846: -case 0x3A46: -case 0x3C46: -case 0x3E46: -case 0x3047: -case 0x3247: -case 0x3447: -case 0x3647: -case 0x3847: -case 0x3A47: -case 0x3C47: -case 0x3E47: - -// MOVEAW -case 0x3040: -{ - u32 res; - res = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(4) -case 0x3248: -case 0x3448: -case 0x3648: -case 0x3848: -case 0x3A48: -case 0x3C48: -case 0x3E48: -case 0x3049: -case 0x3249: -case 0x3449: -case 0x3649: -case 0x3849: -case 0x3A49: -case 0x3C49: -case 0x3E49: -case 0x304A: -case 0x324A: -case 0x344A: -case 0x364A: -case 0x384A: -case 0x3A4A: -case 0x3C4A: -case 0x3E4A: -case 0x304B: -case 0x324B: -case 0x344B: -case 0x364B: -case 0x384B: -case 0x3A4B: -case 0x3C4B: -case 0x3E4B: -case 0x304C: -case 0x324C: -case 0x344C: -case 0x364C: -case 0x384C: -case 0x3A4C: -case 0x3C4C: -case 0x3E4C: -case 0x304D: -case 0x324D: -case 0x344D: -case 0x364D: -case 0x384D: -case 0x3A4D: -case 0x3C4D: -case 0x3E4D: -case 0x304E: -case 0x324E: -case 0x344E: -case 0x364E: -case 0x384E: -case 0x3A4E: -case 0x3C4E: -case 0x3E4E: -case 0x304F: -case 0x324F: -case 0x344F: -case 0x364F: -case 0x384F: -case 0x3A4F: -case 0x3C4F: -case 0x3E4F: - -// MOVEAW -case 0x3048: -{ - u32 res; - res = (s32)(s16)CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(4) -case 0x3250: -case 0x3450: -case 0x3650: -case 0x3850: -case 0x3A50: -case 0x3C50: -case 0x3E50: -case 0x3051: -case 0x3251: -case 0x3451: -case 0x3651: -case 0x3851: -case 0x3A51: -case 0x3C51: -case 0x3E51: -case 0x3052: -case 0x3252: -case 0x3452: -case 0x3652: -case 0x3852: -case 0x3A52: -case 0x3C52: -case 0x3E52: -case 0x3053: -case 0x3253: -case 0x3453: -case 0x3653: -case 0x3853: -case 0x3A53: -case 0x3C53: -case 0x3E53: -case 0x3054: -case 0x3254: -case 0x3454: -case 0x3654: -case 0x3854: -case 0x3A54: -case 0x3C54: -case 0x3E54: -case 0x3055: -case 0x3255: -case 0x3455: -case 0x3655: -case 0x3855: -case 0x3A55: -case 0x3C55: -case 0x3E55: -case 0x3056: -case 0x3256: -case 0x3456: -case 0x3656: -case 0x3856: -case 0x3A56: -case 0x3C56: -case 0x3E56: -case 0x3057: -case 0x3257: -case 0x3457: -case 0x3657: -case 0x3857: -case 0x3A57: -case 0x3C57: -case 0x3E57: - -// MOVEAW -case 0x3050: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(8) -case 0x3258: -case 0x3458: -case 0x3658: -case 0x3858: -case 0x3A58: -case 0x3C58: -case 0x3E58: -case 0x3059: -case 0x3259: -case 0x3459: -case 0x3659: -case 0x3859: -case 0x3A59: -case 0x3C59: -case 0x3E59: -case 0x305A: -case 0x325A: -case 0x345A: -case 0x365A: -case 0x385A: -case 0x3A5A: -case 0x3C5A: -case 0x3E5A: -case 0x305B: -case 0x325B: -case 0x345B: -case 0x365B: -case 0x385B: -case 0x3A5B: -case 0x3C5B: -case 0x3E5B: -case 0x305C: -case 0x325C: -case 0x345C: -case 0x365C: -case 0x385C: -case 0x3A5C: -case 0x3C5C: -case 0x3E5C: -case 0x305D: -case 0x325D: -case 0x345D: -case 0x365D: -case 0x385D: -case 0x3A5D: -case 0x3C5D: -case 0x3E5D: -case 0x305E: -case 0x325E: -case 0x345E: -case 0x365E: -case 0x385E: -case 0x3A5E: -case 0x3C5E: -case 0x3E5E: - -// MOVEAW -case 0x3058: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(8) -case 0x3260: -case 0x3460: -case 0x3660: -case 0x3860: -case 0x3A60: -case 0x3C60: -case 0x3E60: -case 0x3061: -case 0x3261: -case 0x3461: -case 0x3661: -case 0x3861: -case 0x3A61: -case 0x3C61: -case 0x3E61: -case 0x3062: -case 0x3262: -case 0x3462: -case 0x3662: -case 0x3862: -case 0x3A62: -case 0x3C62: -case 0x3E62: -case 0x3063: -case 0x3263: -case 0x3463: -case 0x3663: -case 0x3863: -case 0x3A63: -case 0x3C63: -case 0x3E63: -case 0x3064: -case 0x3264: -case 0x3464: -case 0x3664: -case 0x3864: -case 0x3A64: -case 0x3C64: -case 0x3E64: -case 0x3065: -case 0x3265: -case 0x3465: -case 0x3665: -case 0x3865: -case 0x3A65: -case 0x3C65: -case 0x3E65: -case 0x3066: -case 0x3266: -case 0x3466: -case 0x3666: -case 0x3866: -case 0x3A66: -case 0x3C66: -case 0x3E66: - -// MOVEAW -case 0x3060: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(10) -case 0x3268: -case 0x3468: -case 0x3668: -case 0x3868: -case 0x3A68: -case 0x3C68: -case 0x3E68: -case 0x3069: -case 0x3269: -case 0x3469: -case 0x3669: -case 0x3869: -case 0x3A69: -case 0x3C69: -case 0x3E69: -case 0x306A: -case 0x326A: -case 0x346A: -case 0x366A: -case 0x386A: -case 0x3A6A: -case 0x3C6A: -case 0x3E6A: -case 0x306B: -case 0x326B: -case 0x346B: -case 0x366B: -case 0x386B: -case 0x3A6B: -case 0x3C6B: -case 0x3E6B: -case 0x306C: -case 0x326C: -case 0x346C: -case 0x366C: -case 0x386C: -case 0x3A6C: -case 0x3C6C: -case 0x3E6C: -case 0x306D: -case 0x326D: -case 0x346D: -case 0x366D: -case 0x386D: -case 0x3A6D: -case 0x3C6D: -case 0x3E6D: -case 0x306E: -case 0x326E: -case 0x346E: -case 0x366E: -case 0x386E: -case 0x3A6E: -case 0x3C6E: -case 0x3E6E: -case 0x306F: -case 0x326F: -case 0x346F: -case 0x366F: -case 0x386F: -case 0x3A6F: -case 0x3C6F: -case 0x3E6F: - -// MOVEAW -case 0x3068: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x3270: -case 0x3470: -case 0x3670: -case 0x3870: -case 0x3A70: -case 0x3C70: -case 0x3E70: -case 0x3071: -case 0x3271: -case 0x3471: -case 0x3671: -case 0x3871: -case 0x3A71: -case 0x3C71: -case 0x3E71: -case 0x3072: -case 0x3272: -case 0x3472: -case 0x3672: -case 0x3872: -case 0x3A72: -case 0x3C72: -case 0x3E72: -case 0x3073: -case 0x3273: -case 0x3473: -case 0x3673: -case 0x3873: -case 0x3A73: -case 0x3C73: -case 0x3E73: -case 0x3074: -case 0x3274: -case 0x3474: -case 0x3674: -case 0x3874: -case 0x3A74: -case 0x3C74: -case 0x3E74: -case 0x3075: -case 0x3275: -case 0x3475: -case 0x3675: -case 0x3875: -case 0x3A75: -case 0x3C75: -case 0x3E75: -case 0x3076: -case 0x3276: -case 0x3476: -case 0x3676: -case 0x3876: -case 0x3A76: -case 0x3C76: -case 0x3E76: -case 0x3077: -case 0x3277: -case 0x3477: -case 0x3677: -case 0x3877: -case 0x3A77: -case 0x3C77: -case 0x3E77: - -// MOVEAW -case 0x3070: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(14) -case 0x3278: -case 0x3478: -case 0x3678: -case 0x3878: -case 0x3A78: -case 0x3C78: -case 0x3E78: - -// MOVEAW -case 0x3078: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x3279: -case 0x3479: -case 0x3679: -case 0x3879: -case 0x3A79: -case 0x3C79: -case 0x3E79: - -// MOVEAW -case 0x3079: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x327A: -case 0x347A: -case 0x367A: -case 0x387A: -case 0x3A7A: -case 0x3C7A: -case 0x3E7A: - -// MOVEAW -case 0x307A: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x327B: -case 0x347B: -case 0x367B: -case 0x387B: -case 0x3A7B: -case 0x3C7B: -case 0x3E7B: - -// MOVEAW -case 0x307B: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(14) -case 0x327C: -case 0x347C: -case 0x367C: -case 0x387C: -case 0x3A7C: -case 0x3C7C: -case 0x3E7C: - -// MOVEAW -case 0x307C: -{ - u32 res; - res = (s32)(s16)FETCH_WORD; - PC += 2; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(8) -case 0x325F: -case 0x345F: -case 0x365F: -case 0x385F: -case 0x3A5F: -case 0x3C5F: -case 0x3E5F: - -// MOVEAW -case 0x305F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(8) -case 0x3267: -case 0x3467: -case 0x3667: -case 0x3867: -case 0x3A67: -case 0x3C67: -case 0x3E67: - -// MOVEAW -case 0x3067: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READSX_WORD_F(adr, res) - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(10) diff --git a/yabause/src/c68k/c68k_op4.inc b/yabause/src/c68k/c68k_op4.inc deleted file mode 100644 index 156122a392..0000000000 --- a/yabause/src/c68k/c68k_op4.inc +++ /dev/null @@ -1,7508 +0,0 @@ -case 0x4001: -case 0x4002: -case 0x4003: -case 0x4004: -case 0x4005: -case 0x4006: -case 0x4007: - -// NEGX -case 0x4000: -{ - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4011: -case 0x4012: -case 0x4013: -case 0x4014: -case 0x4015: -case 0x4016: -case 0x4017: - -// NEGX -case 0x4010: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4019: -case 0x401A: -case 0x401B: -case 0x401C: -case 0x401D: -case 0x401E: - -// NEGX -case 0x4018: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4021: -case 0x4022: -case 0x4023: -case 0x4024: -case 0x4025: -case 0x4026: - -// NEGX -case 0x4020: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x4029: -case 0x402A: -case 0x402B: -case 0x402C: -case 0x402D: -case 0x402E: -case 0x402F: - -// NEGX -case 0x4028: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x4031: -case 0x4032: -case 0x4033: -case 0x4034: -case 0x4035: -case 0x4036: -case 0x4037: - -// NEGX -case 0x4030: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// NEGX -case 0x4038: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// NEGX -case 0x4039: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// NEGX -case 0x401F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) - -// NEGX -case 0x4027: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x4041: -case 0x4042: -case 0x4043: -case 0x4044: -case 0x4045: -case 0x4046: -case 0x4047: - -// NEGX -case 0x4040: -{ - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4051: -case 0x4052: -case 0x4053: -case 0x4054: -case 0x4055: -case 0x4056: -case 0x4057: - -// NEGX -case 0x4050: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x4059: -case 0x405A: -case 0x405B: -case 0x405C: -case 0x405D: -case 0x405E: - -// NEGX -case 0x4058: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x4061: -case 0x4062: -case 0x4063: -case 0x4064: -case 0x4065: -case 0x4066: - -// NEGX -case 0x4060: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x4069: -case 0x406A: -case 0x406B: -case 0x406C: -case 0x406D: -case 0x406E: -case 0x406F: - -// NEGX -case 0x4068: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x4071: -case 0x4072: -case 0x4073: -case 0x4074: -case 0x4075: -case 0x4076: -case 0x4077: - -// NEGX -case 0x4070: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// NEGX -case 0x4078: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// NEGX -case 0x4079: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// NEGX -case 0x405F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// NEGX -case 0x4067: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x4081: -case 0x4082: -case 0x4083: -case 0x4084: -case 0x4085: -case 0x4086: -case 0x4087: - -// NEGX -case 0x4080: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0x4091: -case 0x4092: -case 0x4093: -case 0x4094: -case 0x4095: -case 0x4096: -case 0x4097: - -// NEGX -case 0x4090: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x4099: -case 0x409A: -case 0x409B: -case 0x409C: -case 0x409D: -case 0x409E: - -// NEGX -case 0x4098: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x40A1: -case 0x40A2: -case 0x40A3: -case 0x40A4: -case 0x40A5: -case 0x40A6: - -// NEGX -case 0x40A0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x40A9: -case 0x40AA: -case 0x40AB: -case 0x40AC: -case 0x40AD: -case 0x40AE: -case 0x40AF: - -// NEGX -case 0x40A8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x40B1: -case 0x40B2: -case 0x40B3: -case 0x40B4: -case 0x40B5: -case 0x40B6: -case 0x40B7: - -// NEGX -case 0x40B0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) - -// NEGX -case 0x40B8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) - -// NEGX -case 0x40B9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// NEGX -case 0x409F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) - -// NEGX -case 0x40A7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = -src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x4201: -case 0x4202: -case 0x4203: -case 0x4204: -case 0x4205: -case 0x4206: -case 0x4207: - -// CLR -case 0x4200: -{ - u32 res; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4211: -case 0x4212: -case 0x4213: -case 0x4214: -case 0x4215: -case 0x4216: -case 0x4217: - -// CLR -case 0x4210: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4219: -case 0x421A: -case 0x421B: -case 0x421C: -case 0x421D: -case 0x421E: - -// CLR -case 0x4218: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4221: -case 0x4222: -case 0x4223: -case 0x4224: -case 0x4225: -case 0x4226: - -// CLR -case 0x4220: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x4229: -case 0x422A: -case 0x422B: -case 0x422C: -case 0x422D: -case 0x422E: -case 0x422F: - -// CLR -case 0x4228: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x4231: -case 0x4232: -case 0x4233: -case 0x4234: -case 0x4235: -case 0x4236: -case 0x4237: - -// CLR -case 0x4230: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// CLR -case 0x4238: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// CLR -case 0x4239: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// CLR -case 0x421F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) - -// CLR -case 0x4227: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x4241: -case 0x4242: -case 0x4243: -case 0x4244: -case 0x4245: -case 0x4246: -case 0x4247: - -// CLR -case 0x4240: -{ - u32 res; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4251: -case 0x4252: -case 0x4253: -case 0x4254: -case 0x4255: -case 0x4256: -case 0x4257: - -// CLR -case 0x4250: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x4259: -case 0x425A: -case 0x425B: -case 0x425C: -case 0x425D: -case 0x425E: - -// CLR -case 0x4258: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x4261: -case 0x4262: -case 0x4263: -case 0x4264: -case 0x4265: -case 0x4266: - -// CLR -case 0x4260: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x4269: -case 0x426A: -case 0x426B: -case 0x426C: -case 0x426D: -case 0x426E: -case 0x426F: - -// CLR -case 0x4268: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x4271: -case 0x4272: -case 0x4273: -case 0x4274: -case 0x4275: -case 0x4276: -case 0x4277: - -// CLR -case 0x4270: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// CLR -case 0x4278: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// CLR -case 0x4279: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// CLR -case 0x425F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// CLR -case 0x4267: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x4281: -case 0x4282: -case 0x4283: -case 0x4284: -case 0x4285: -case 0x4286: -case 0x4287: - -// CLR -case 0x4280: -{ - u32 res; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0x4291: -case 0x4292: -case 0x4293: -case 0x4294: -case 0x4295: -case 0x4296: -case 0x4297: - -// CLR -case 0x4290: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x4299: -case 0x429A: -case 0x429B: -case 0x429C: -case 0x429D: -case 0x429E: - -// CLR -case 0x4298: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x42A1: -case 0x42A2: -case 0x42A3: -case 0x42A4: -case 0x42A5: -case 0x42A6: - -// CLR -case 0x42A0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x42A9: -case 0x42AA: -case 0x42AB: -case 0x42AC: -case 0x42AD: -case 0x42AE: -case 0x42AF: - -// CLR -case 0x42A8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x42B1: -case 0x42B2: -case 0x42B3: -case 0x42B4: -case 0x42B5: -case 0x42B6: -case 0x42B7: - -// CLR -case 0x42B0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) - -// CLR -case 0x42B8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) - -// CLR -case 0x42B9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// CLR -case 0x429F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) - -// CLR -case 0x42A7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - res = 0; - CPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0; - PRE_IO - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x4401: -case 0x4402: -case 0x4403: -case 0x4404: -case 0x4405: -case 0x4406: -case 0x4407: - -// NEG -case 0x4400: -{ - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4411: -case 0x4412: -case 0x4413: -case 0x4414: -case 0x4415: -case 0x4416: -case 0x4417: - -// NEG -case 0x4410: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4419: -case 0x441A: -case 0x441B: -case 0x441C: -case 0x441D: -case 0x441E: - -// NEG -case 0x4418: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4421: -case 0x4422: -case 0x4423: -case 0x4424: -case 0x4425: -case 0x4426: - -// NEG -case 0x4420: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x4429: -case 0x442A: -case 0x442B: -case 0x442C: -case 0x442D: -case 0x442E: -case 0x442F: - -// NEG -case 0x4428: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x4431: -case 0x4432: -case 0x4433: -case 0x4434: -case 0x4435: -case 0x4436: -case 0x4437: - -// NEG -case 0x4430: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// NEG -case 0x4438: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// NEG -case 0x4439: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// NEG -case 0x441F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) - -// NEG -case 0x4427: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = -src; - CPU->flag_V = res & src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x4441: -case 0x4442: -case 0x4443: -case 0x4444: -case 0x4445: -case 0x4446: -case 0x4447: - -// NEG -case 0x4440: -{ - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4451: -case 0x4452: -case 0x4453: -case 0x4454: -case 0x4455: -case 0x4456: -case 0x4457: - -// NEG -case 0x4450: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x4459: -case 0x445A: -case 0x445B: -case 0x445C: -case 0x445D: -case 0x445E: - -// NEG -case 0x4458: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x4461: -case 0x4462: -case 0x4463: -case 0x4464: -case 0x4465: -case 0x4466: - -// NEG -case 0x4460: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x4469: -case 0x446A: -case 0x446B: -case 0x446C: -case 0x446D: -case 0x446E: -case 0x446F: - -// NEG -case 0x4468: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x4471: -case 0x4472: -case 0x4473: -case 0x4474: -case 0x4475: -case 0x4476: -case 0x4477: - -// NEG -case 0x4470: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// NEG -case 0x4478: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// NEG -case 0x4479: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// NEG -case 0x445F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// NEG -case 0x4467: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = -src; - CPU->flag_V = (res & src) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x4481: -case 0x4482: -case 0x4483: -case 0x4484: -case 0x4485: -case 0x4486: -case 0x4487: - -// NEG -case 0x4480: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0x4491: -case 0x4492: -case 0x4493: -case 0x4494: -case 0x4495: -case 0x4496: -case 0x4497: - -// NEG -case 0x4490: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x4499: -case 0x449A: -case 0x449B: -case 0x449C: -case 0x449D: -case 0x449E: - -// NEG -case 0x4498: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x44A1: -case 0x44A2: -case 0x44A3: -case 0x44A4: -case 0x44A5: -case 0x44A6: - -// NEG -case 0x44A0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x44A9: -case 0x44AA: -case 0x44AB: -case 0x44AC: -case 0x44AD: -case 0x44AE: -case 0x44AF: - -// NEG -case 0x44A8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x44B1: -case 0x44B2: -case 0x44B3: -case 0x44B4: -case 0x44B5: -case 0x44B6: -case 0x44B7: - -// NEG -case 0x44B0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) - -// NEG -case 0x44B8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) - -// NEG -case 0x44B9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// NEG -case 0x449F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) - -// NEG -case 0x44A7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = -src; - CPU->flag_notZ = res; - CPU->flag_V = (res & src) >> 24; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x4601: -case 0x4602: -case 0x4603: -case 0x4604: -case 0x4605: -case 0x4606: -case 0x4607: - -// NOT -case 0x4600: -{ - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4611: -case 0x4612: -case 0x4613: -case 0x4614: -case 0x4615: -case 0x4616: -case 0x4617: - -// NOT -case 0x4610: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4619: -case 0x461A: -case 0x461B: -case 0x461C: -case 0x461D: -case 0x461E: - -// NOT -case 0x4618: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4621: -case 0x4622: -case 0x4623: -case 0x4624: -case 0x4625: -case 0x4626: - -// NOT -case 0x4620: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x4629: -case 0x462A: -case 0x462B: -case 0x462C: -case 0x462D: -case 0x462E: -case 0x462F: - -// NOT -case 0x4628: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x4631: -case 0x4632: -case 0x4633: -case 0x4634: -case 0x4635: -case 0x4636: -case 0x4637: - -// NOT -case 0x4630: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// NOT -case 0x4638: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// NOT -case 0x4639: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) - -// NOT -case 0x461F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) - -// NOT -case 0x4627: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_N = res; - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x4641: -case 0x4642: -case 0x4643: -case 0x4644: -case 0x4645: -case 0x4646: -case 0x4647: - -// NOT -case 0x4640: -{ - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4651: -case 0x4652: -case 0x4653: -case 0x4654: -case 0x4655: -case 0x4656: -case 0x4657: - -// NOT -case 0x4650: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x4659: -case 0x465A: -case 0x465B: -case 0x465C: -case 0x465D: -case 0x465E: - -// NOT -case 0x4658: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x4661: -case 0x4662: -case 0x4663: -case 0x4664: -case 0x4665: -case 0x4666: - -// NOT -case 0x4660: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x4669: -case 0x466A: -case 0x466B: -case 0x466C: -case 0x466D: -case 0x466E: -case 0x466F: - -// NOT -case 0x4668: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x4671: -case 0x4672: -case 0x4673: -case 0x4674: -case 0x4675: -case 0x4676: -case 0x4677: - -// NOT -case 0x4670: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// NOT -case 0x4678: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// NOT -case 0x4679: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// NOT -case 0x465F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// NOT -case 0x4667: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res & 0xFFFF; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x4681: -case 0x4682: -case 0x4683: -case 0x4684: -case 0x4685: -case 0x4686: -case 0x4687: - -// NOT -case 0x4680: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0x4691: -case 0x4692: -case 0x4693: -case 0x4694: -case 0x4695: -case 0x4696: -case 0x4697: - -// NOT -case 0x4690: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x4699: -case 0x469A: -case 0x469B: -case 0x469C: -case 0x469D: -case 0x469E: - -// NOT -case 0x4698: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x46A1: -case 0x46A2: -case 0x46A3: -case 0x46A4: -case 0x46A5: -case 0x46A6: - -// NOT -case 0x46A0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x46A9: -case 0x46AA: -case 0x46AB: -case 0x46AC: -case 0x46AD: -case 0x46AE: -case 0x46AF: - -// NOT -case 0x46A8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x46B1: -case 0x46B2: -case 0x46B3: -case 0x46B4: -case 0x46B5: -case 0x46B6: -case 0x46B7: - -// NOT -case 0x46B0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) - -// NOT -case 0x46B8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) - -// NOT -case 0x46B9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) - -// NOT -case 0x469F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) - -// NOT -case 0x46A7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = ~src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x40C1: -case 0x40C2: -case 0x40C3: -case 0x40C4: -case 0x40C5: -case 0x40C6: -case 0x40C7: - -// MOVESRa -case 0x40C0: -{ - u32 res; - res = GET_SR; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0x40D1: -case 0x40D2: -case 0x40D3: -case 0x40D4: -case 0x40D5: -case 0x40D6: -case 0x40D7: - -// MOVESRa -case 0x40D0: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x40D9: -case 0x40DA: -case 0x40DB: -case 0x40DC: -case 0x40DD: -case 0x40DE: - -// MOVESRa -case 0x40D8: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x40E1: -case 0x40E2: -case 0x40E3: -case 0x40E4: -case 0x40E5: -case 0x40E6: - -// MOVESRa -case 0x40E0: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x40E9: -case 0x40EA: -case 0x40EB: -case 0x40EC: -case 0x40ED: -case 0x40EE: -case 0x40EF: - -// MOVESRa -case 0x40E8: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x40F1: -case 0x40F2: -case 0x40F3: -case 0x40F4: -case 0x40F5: -case 0x40F6: -case 0x40F7: - -// MOVESRa -case 0x40F0: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// MOVESRa -case 0x40F8: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// MOVESRa -case 0x40F9: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// MOVESRa -case 0x40DF: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// MOVESRa -case 0x40E7: -{ - u32 adr; - u32 res; - res = GET_SR; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x44C1: -case 0x44C2: -case 0x44C3: -case 0x44C4: -case 0x44C5: -case 0x44C6: -case 0x44C7: - -// MOVEaCCR -case 0x44C0: -{ - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - SET_CCR(res) -} -RET(12) -case 0x44D1: -case 0x44D2: -case 0x44D3: -case 0x44D4: -case 0x44D5: -case 0x44D6: -case 0x44D7: - -// MOVEaCCR -case 0x44D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(16) -case 0x44D9: -case 0x44DA: -case 0x44DB: -case 0x44DC: -case 0x44DD: -case 0x44DE: - -// MOVEaCCR -case 0x44D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(16) -case 0x44E1: -case 0x44E2: -case 0x44E3: -case 0x44E4: -case 0x44E5: -case 0x44E6: - -// MOVEaCCR -case 0x44E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(18) -case 0x44E9: -case 0x44EA: -case 0x44EB: -case 0x44EC: -case 0x44ED: -case 0x44EE: -case 0x44EF: - -// MOVEaCCR -case 0x44E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(20) -case 0x44F1: -case 0x44F2: -case 0x44F3: -case 0x44F4: -case 0x44F5: -case 0x44F6: -case 0x44F7: - -// MOVEaCCR -case 0x44F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(22) - -// MOVEaCCR -case 0x44F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(20) - -// MOVEaCCR -case 0x44F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(24) - -// MOVEaCCR -case 0x44FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(20) - -// MOVEaCCR -case 0x44FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(22) - -// MOVEaCCR -case 0x44FC: -{ - u32 res; - res = FETCH_WORD; - PC += 2; - SET_CCR(res) -} -RET(16) - -// MOVEaCCR -case 0x44DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(16) - -// MOVEaCCR -case 0x44E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - SET_CCR(res) - POST_IO -} -RET(18) -case 0x46C1: -case 0x46C2: -case 0x46C3: -case 0x46C4: -case 0x46C5: -case 0x46C6: -case 0x46C7: - -// MOVEaSR -case 0x46C0: -{ - u32 res; - if (CPU->flag_S) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 12; -goto C68k_Exec_End; -case 0x46D1: -case 0x46D2: -case 0x46D3: -case 0x46D4: -case 0x46D5: -case 0x46D6: -case 0x46D7: - -// MOVEaSR -case 0x46D0: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 16; -goto C68k_Exec_End; -case 0x46D9: -case 0x46DA: -case 0x46DB: -case 0x46DC: -case 0x46DD: -case 0x46DE: - -// MOVEaSR -case 0x46D8: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 16; -goto C68k_Exec_End; -case 0x46E1: -case 0x46E2: -case 0x46E3: -case 0x46E4: -case 0x46E5: -case 0x46E6: - -// MOVEaSR -case 0x46E0: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 18; -goto C68k_Exec_End; -case 0x46E9: -case 0x46EA: -case 0x46EB: -case 0x46EC: -case 0x46ED: -case 0x46EE: -case 0x46EF: - -// MOVEaSR -case 0x46E8: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 20; -goto C68k_Exec_End; -case 0x46F1: -case 0x46F2: -case 0x46F3: -case 0x46F4: -case 0x46F5: -case 0x46F6: -case 0x46F7: - -// MOVEaSR -case 0x46F0: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 22; -goto C68k_Exec_End; - -// MOVEaSR -case 0x46F8: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 20; -goto C68k_Exec_End; - -// MOVEaSR -case 0x46F9: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 24; -goto C68k_Exec_End; - -// MOVEaSR -case 0x46FA: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 20; -goto C68k_Exec_End; - -// MOVEaSR -case 0x46FB: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 22; -goto C68k_Exec_End; - -// MOVEaSR -case 0x46FC: -{ - u32 res; - if (CPU->flag_S) - { - res = FETCH_WORD; - PC += 2; - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 16; -goto C68k_Exec_End; - -// MOVEaSR -case 0x46DF: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 16; -goto C68k_Exec_End; - -// MOVEaSR -case 0x46E7: -{ - u32 adr; - u32 res; - if (CPU->flag_S) - { - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - } - else - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } -} -POST_IO -CCnt -= 18; -goto C68k_Exec_End; -case 0x4801: -case 0x4802: -case 0x4803: -case 0x4804: -case 0x4805: -case 0x4806: -case 0x4807: - -// NBCD -case 0x4800: -{ - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; -} -RET(6) -case 0x4811: -case 0x4812: -case 0x4813: -case 0x4814: -case 0x4815: -case 0x4816: -case 0x4817: - -// NBCD -case 0x4810: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(12) -case 0x4819: -case 0x481A: -case 0x481B: -case 0x481C: -case 0x481D: -case 0x481E: - -// NBCD -case 0x4818: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(12) -case 0x4821: -case 0x4822: -case 0x4823: -case 0x4824: -case 0x4825: -case 0x4826: - -// NBCD -case 0x4820: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(14) -case 0x4829: -case 0x482A: -case 0x482B: -case 0x482C: -case 0x482D: -case 0x482E: -case 0x482F: - -// NBCD -case 0x4828: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(16) -case 0x4831: -case 0x4832: -case 0x4833: -case 0x4834: -case 0x4835: -case 0x4836: -case 0x4837: - -// NBCD -case 0x4830: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(18) - -// NBCD -case 0x4838: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(16) - -// NBCD -case 0x4839: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(20) - -// NBCD -case 0x481F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(12) - -// NBCD -case 0x4827: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - - if (res != 0x9a) - { - if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10; - res &= 0xFF; - WRITE_BYTE_F(adr, res) - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = res; - POST_IO -} -RET(14) -case 0x4851: -case 0x4852: -case 0x4853: -case 0x4854: -case 0x4855: -case 0x4856: -case 0x4857: - -// PEA -case 0x4850: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - PUSH_32_F(adr) - POST_IO -} -RET(12) -case 0x4869: -case 0x486A: -case 0x486B: -case 0x486C: -case 0x486D: -case 0x486E: -case 0x486F: - -// PEA -case 0x4868: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - PUSH_32_F(adr) - POST_IO -} -RET(16) -case 0x4871: -case 0x4872: -case 0x4873: -case 0x4874: -case 0x4875: -case 0x4876: -case 0x4877: - -// PEA -case 0x4870: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - PUSH_32_F(adr) - POST_IO -} -RET(20) - -// PEA -case 0x4878: -{ - u32 adr; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - PUSH_32_F(adr) - POST_IO -} -RET(16) - -// PEA -case 0x4879: -{ - u32 adr; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - PUSH_32_F(adr) - POST_IO -} -RET(20) - -// PEA -case 0x487A: -{ - u32 adr; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - PUSH_32_F(adr) - POST_IO -} -RET(16) - -// PEA -case 0x487B: -{ - u32 adr; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - PUSH_32_F(adr) - POST_IO -} -RET(20) -case 0x4841: -case 0x4842: -case 0x4843: -case 0x4844: -case 0x4845: -case 0x4846: -case 0x4847: - -// SWAP -case 0x4840: -{ - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - res = (res >> 16) | (res << 16); - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4891: -case 0x4892: -case 0x4893: -case 0x4894: -case 0x4895: -case 0x4896: -case 0x4897: - -// MOVEMRa -case 0x4890: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_WORD_F(adr, *(u16*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(12) -case 0x48A1: -case 0x48A2: -case 0x48A3: -case 0x48A4: -case 0x48A5: -case 0x48A6: - -// MOVEMRa -case 0x48A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - src = (pointer)(&CPU->A[7]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - adr -= 2; - WRITE_WORD_F(adr, *(u16*)src) - } - src -= 4; - } while (res >>= 1); - CPU->A[(Opcode >> 0) & 7] = adr; - POST_IO - CCnt -= (dst - adr) * 2; -} -RET(8) -case 0x48A9: -case 0x48AA: -case 0x48AB: -case 0x48AC: -case 0x48AD: -case 0x48AE: -case 0x48AF: - -// MOVEMRa -case 0x48A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_WORD_F(adr, *(u16*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(20) -case 0x48B1: -case 0x48B2: -case 0x48B3: -case 0x48B4: -case 0x48B5: -case 0x48B6: -case 0x48B7: - -// MOVEMRa -case 0x48B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_WORD_F(adr, *(u16*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(24) - -// MOVEMRa -case 0x48B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_WORD_F(adr, *(u16*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(20) - -// MOVEMRa -case 0x48B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_WORD_F(adr, *(u16*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(28) - -// MOVEMRa -case 0x48A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - src = (pointer)(&CPU->A[7]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - adr -= 2; - WRITE_WORD_F(adr, *(u16*)src) - } - src -= 4; - } while (res >>= 1); - CPU->A[7] = adr; - POST_IO - CCnt -= (dst - adr) * 2; -} -RET(8) -case 0x48D1: -case 0x48D2: -case 0x48D3: -case 0x48D4: -case 0x48D5: -case 0x48D6: -case 0x48D7: - -// MOVEMRa -case 0x48D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(16) -case 0x48E1: -case 0x48E2: -case 0x48E3: -case 0x48E4: -case 0x48E5: -case 0x48E6: - -// MOVEMRa -case 0x48E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - src = (pointer)(&CPU->A[7]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - adr -= 4; - WRITE_LONG_DEC_F(adr, *(u32*)src) - } - src -= 4; - } while (res >>= 1); - CPU->A[(Opcode >> 0) & 7] = adr; - POST_IO - CCnt -= (dst - adr) * 2; -} -RET(8) -case 0x48E9: -case 0x48EA: -case 0x48EB: -case 0x48EC: -case 0x48ED: -case 0x48EE: -case 0x48EF: - -// MOVEMRa -case 0x48E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(24) -case 0x48F1: -case 0x48F2: -case 0x48F3: -case 0x48F4: -case 0x48F5: -case 0x48F6: -case 0x48F7: - -// MOVEMRa -case 0x48F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(28) - -// MOVEMRa -case 0x48F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(24) - -// MOVEMRa -case 0x48F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - WRITE_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(32) - -// MOVEMRa -case 0x48E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - src = (pointer)(&CPU->A[7]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - adr -= 4; - WRITE_LONG_DEC_F(adr, *(u32*)src) - } - src -= 4; - } while (res >>= 1); - CPU->A[7] = adr; - POST_IO - CCnt -= (dst - adr) * 2; -} -RET(8) -case 0x4881: -case 0x4882: -case 0x4883: -case 0x4884: -case 0x4885: -case 0x4886: -case 0x4887: - -// EXT -case 0x4880: -{ - u32 res; - res = (s32)(s8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x48C1: -case 0x48C2: -case 0x48C3: -case 0x48C4: -case 0x48C5: -case 0x48C6: -case 0x48C7: - -// EXT -case 0x48C0: -{ - u32 res; - res = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4A01: -case 0x4A02: -case 0x4A03: -case 0x4A04: -case 0x4A05: -case 0x4A06: -case 0x4A07: - -// TST -case 0x4A00: -{ - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; -} -RET(4) -case 0x4A11: -case 0x4A12: -case 0x4A13: -case 0x4A14: -case 0x4A15: -case 0x4A16: -case 0x4A17: - -// TST -case 0x4A10: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(8) -case 0x4A19: -case 0x4A1A: -case 0x4A1B: -case 0x4A1C: -case 0x4A1D: -case 0x4A1E: - -// TST -case 0x4A18: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(8) -case 0x4A21: -case 0x4A22: -case 0x4A23: -case 0x4A24: -case 0x4A25: -case 0x4A26: - -// TST -case 0x4A20: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(10) -case 0x4A29: -case 0x4A2A: -case 0x4A2B: -case 0x4A2C: -case 0x4A2D: -case 0x4A2E: -case 0x4A2F: - -// TST -case 0x4A28: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(12) -case 0x4A31: -case 0x4A32: -case 0x4A33: -case 0x4A34: -case 0x4A35: -case 0x4A36: -case 0x4A37: - -// TST -case 0x4A30: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(14) - -// TST -case 0x4A38: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(12) - -// TST -case 0x4A39: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(16) - -// TST -case 0x4A1F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(8) - -// TST -case 0x4A27: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - POST_IO -} -RET(10) -case 0x4A41: -case 0x4A42: -case 0x4A43: -case 0x4A44: -case 0x4A45: -case 0x4A46: -case 0x4A47: - -// TST -case 0x4A40: -{ - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; -} -RET(4) -case 0x4A51: -case 0x4A52: -case 0x4A53: -case 0x4A54: -case 0x4A55: -case 0x4A56: -case 0x4A57: - -// TST -case 0x4A50: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(8) -case 0x4A59: -case 0x4A5A: -case 0x4A5B: -case 0x4A5C: -case 0x4A5D: -case 0x4A5E: - -// TST -case 0x4A58: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(8) -case 0x4A61: -case 0x4A62: -case 0x4A63: -case 0x4A64: -case 0x4A65: -case 0x4A66: - -// TST -case 0x4A60: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(10) -case 0x4A69: -case 0x4A6A: -case 0x4A6B: -case 0x4A6C: -case 0x4A6D: -case 0x4A6E: -case 0x4A6F: - -// TST -case 0x4A68: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(12) -case 0x4A71: -case 0x4A72: -case 0x4A73: -case 0x4A74: -case 0x4A75: -case 0x4A76: -case 0x4A77: - -// TST -case 0x4A70: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(14) - -// TST -case 0x4A78: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(12) - -// TST -case 0x4A79: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(16) - -// TST -case 0x4A5F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(8) - -// TST -case 0x4A67: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - POST_IO -} -RET(10) -case 0x4A81: -case 0x4A82: -case 0x4A83: -case 0x4A84: -case 0x4A85: -case 0x4A86: -case 0x4A87: - -// TST -case 0x4A80: -{ - u32 res; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; -} -RET(4) -case 0x4A91: -case 0x4A92: -case 0x4A93: -case 0x4A94: -case 0x4A95: -case 0x4A96: -case 0x4A97: - -// TST -case 0x4A90: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(12) -case 0x4A99: -case 0x4A9A: -case 0x4A9B: -case 0x4A9C: -case 0x4A9D: -case 0x4A9E: - -// TST -case 0x4A98: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(12) -case 0x4AA1: -case 0x4AA2: -case 0x4AA3: -case 0x4AA4: -case 0x4AA5: -case 0x4AA6: - -// TST -case 0x4AA0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(14) -case 0x4AA9: -case 0x4AAA: -case 0x4AAB: -case 0x4AAC: -case 0x4AAD: -case 0x4AAE: -case 0x4AAF: - -// TST -case 0x4AA8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) -case 0x4AB1: -case 0x4AB2: -case 0x4AB3: -case 0x4AB4: -case 0x4AB5: -case 0x4AB6: -case 0x4AB7: - -// TST -case 0x4AB0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(18) - -// TST -case 0x4AB8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) - -// TST -case 0x4AB9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) - -// TST -case 0x4A9F: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(12) - -// TST -case 0x4AA7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - POST_IO -} -RET(14) -case 0x4AC1: -case 0x4AC2: -case 0x4AC3: -case 0x4AC4: -case 0x4AC5: -case 0x4AC6: -case 0x4AC7: - -// TAS -case 0x4AC0: -{ - u32 res; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x4AD1: -case 0x4AD2: -case 0x4AD3: -case 0x4AD4: -case 0x4AD5: -case 0x4AD6: -case 0x4AD7: - -// TAS -case 0x4AD0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x4AD9: -case 0x4ADA: -case 0x4ADB: -case 0x4ADC: -case 0x4ADD: -case 0x4ADE: - -// TAS -case 0x4AD8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) -case 0x4AE1: -case 0x4AE2: -case 0x4AE3: -case 0x4AE4: -case 0x4AE5: -case 0x4AE6: - -// TAS -case 0x4AE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(10) -case 0x4AE9: -case 0x4AEA: -case 0x4AEB: -case 0x4AEC: -case 0x4AED: -case 0x4AEE: -case 0x4AEF: - -// TAS -case 0x4AE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x4AF1: -case 0x4AF2: -case 0x4AF3: -case 0x4AF4: -case 0x4AF5: -case 0x4AF6: -case 0x4AF7: - -// TAS -case 0x4AF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) - -// TAS -case 0x4AF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) - -// TAS -case 0x4AF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) - -// TAS -case 0x4ADF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(8) - -// TAS -case 0x4AE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - res |= 0x80; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(10) - -// ILLEGAL -case 0x4AFC: -{ - u32 res; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ILLEGAL_INSTRUCTION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO -} -RET(4) -case 0x4C91: -case 0x4C92: -case 0x4C93: -case 0x4C94: -case 0x4C95: -case 0x4C96: -case 0x4C97: - -// MOVEMaR -case 0x4C90: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(16) -case 0x4C99: -case 0x4C9A: -case 0x4C9B: -case 0x4C9C: -case 0x4C9D: -case 0x4C9E: - -// MOVEMaR -case 0x4C98: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - CPU->A[(Opcode >> 0) & 7] = adr; - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(12) -case 0x4CA9: -case 0x4CAA: -case 0x4CAB: -case 0x4CAC: -case 0x4CAD: -case 0x4CAE: -case 0x4CAF: - -// MOVEMaR -case 0x4CA8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(24) -case 0x4CB1: -case 0x4CB2: -case 0x4CB3: -case 0x4CB4: -case 0x4CB5: -case 0x4CB6: -case 0x4CB7: - -// MOVEMaR -case 0x4CB0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(28) - -// MOVEMaR -case 0x4CB8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(24) - -// MOVEMaR -case 0x4CB9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(32) - -// MOVEMaR -case 0x4CBA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(24) - -// MOVEMaR -case 0x4CBB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(28) - -// MOVEMaR -case 0x4C9F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READSX_WORD_F(adr, *(s32*)src) - adr += 2; - } - src += 4; - } while (res >>= 1); - CPU->A[7] = adr; - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(12) -case 0x4CD1: -case 0x4CD2: -case 0x4CD3: -case 0x4CD4: -case 0x4CD5: -case 0x4CD6: -case 0x4CD7: - -// MOVEMaR -case 0x4CD0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(20) -case 0x4CD9: -case 0x4CDA: -case 0x4CDB: -case 0x4CDC: -case 0x4CDD: -case 0x4CDE: - -// MOVEMaR -case 0x4CD8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - CPU->A[(Opcode >> 0) & 7] = adr; - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(12) -case 0x4CE9: -case 0x4CEA: -case 0x4CEB: -case 0x4CEC: -case 0x4CED: -case 0x4CEE: -case 0x4CEF: - -// MOVEMaR -case 0x4CE8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(28) -case 0x4CF1: -case 0x4CF2: -case 0x4CF3: -case 0x4CF4: -case 0x4CF5: -case 0x4CF6: -case 0x4CF7: - -// MOVEMaR -case 0x4CF0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(32) - -// MOVEMaR -case 0x4CF8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(28) - -// MOVEMaR -case 0x4CF9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (s32)FETCH_LONG; - PC += 4; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(36) - -// MOVEMaR -case 0x4CFA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(28) - -// MOVEMaR -case 0x4CFB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(32) - -// MOVEMaR -case 0x4CDF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - res = FETCH_WORD; - PC += 2; - adr = CPU->A[7]; - src = (pointer)(&CPU->D[0]); - dst = adr; - PRE_IO - do - { - if (res & 1) - { - READ_LONG_F(adr, *(u32*)src) - adr += 4; - } - src += 4; - } while (res >>= 1); - CPU->A[7] = adr; - POST_IO - CCnt -= (adr - dst) * 2; -} -RET(12) -case 0x4E41: -case 0x4E42: -case 0x4E43: -case 0x4E44: -case 0x4E45: -case 0x4E46: -case 0x4E47: -case 0x4E48: -case 0x4E49: -case 0x4E4A: -case 0x4E4B: -case 0x4E4C: -case 0x4E4D: -case 0x4E4E: -case 0x4E4F: - -// TRAP -case 0x4E40: -{ - u32 res; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_TRAP_BASE_EX + (Opcode & 0xF); - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO -} -RET(4) -case 0x4E51: -case 0x4E52: -case 0x4E53: -case 0x4E54: -case 0x4E55: -case 0x4E56: - -// LINK -case 0x4E50: -{ - u32 res; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - PRE_IO - PUSH_32_F(res) - res = CPU->A[7]; - CPU->A[(Opcode >> 0) & 7] = res; - CPU->A[7] += (s32)(s16)FETCH_WORD; - PC += 2; - POST_IO -} -RET(16) - -// LINKA7 -case 0x4E57: -{ - CPU->A[7] -= 4; - PRE_IO - WRITE_LONG_DEC_F(CPU->A[7], CPU->A[7]) - CPU->A[7] += (s32)(s16)FETCH_WORD; - PC += 2; - POST_IO -} -RET(16) -case 0x4E59: -case 0x4E5A: -case 0x4E5B: -case 0x4E5C: -case 0x4E5D: -case 0x4E5E: - -// ULNK -case 0x4E58: -{ - u32 res; - pointer src; - src = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->A[7] = src + 4; - PRE_IO - READ_LONG_F(src, res) - CPU->A[(Opcode >> 0) & 7] = res; - POST_IO -} -RET(12) - -// ULNKA7 -case 0x4E5F: -{ - PRE_IO - READ_LONG_F(CPU->A[7], CPU->A[7]) - POST_IO -} -RET(12) -case 0x4E61: -case 0x4E62: -case 0x4E63: -case 0x4E64: -case 0x4E65: -case 0x4E66: -case 0x4E67: - -// MOVEAUSP -case 0x4E60: -{ - u32 res; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(4) - } - res = (u32)CPU->A[(Opcode >> 0) & 7]; - CPU->USP = res; -} -RET(4) -case 0x4E69: -case 0x4E6A: -case 0x4E6B: -case 0x4E6C: -case 0x4E6D: -case 0x4E6E: -case 0x4E6F: - -// MOVEUSPA -case 0x4E68: -{ - u32 res; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(4) - } - res = CPU->USP; - CPU->A[(Opcode >> 0) & 7] = res; -} -RET(4) - -// RESET -case 0x4E70: -{ - u32 res; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(4) - } - PRE_IO - CPU->Reset_CallBack(); - POST_IO -} -RET(132) - -// NOP -case 0x4E71: -{ -} -RET(4) - -// STOP -case 0x4E72: -{ - u32 res; - if (!CPU->flag_S) - { - PC += 2; - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(4) - } - res = FETCH_WORD & C68K_SR_MASK; - PC += 2; - SET_SR(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } - CPU->Status |= C68K_HALTED; - CCnt = 0; -} -CCnt -= 4; -goto C68k_Exec_End; - -// RTE -case 0x4E73: -{ - u32 res; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - res = C68K_PRIVILEGE_VIOLATION_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(4) - } - PRE_IO - POP_16_F(res) - SET_SR(res) - POP_32_F(res) - SET_PC(res) - if (!CPU->flag_S) - { - res = CPU->A[7]; - CPU->A[7] = CPU->USP; - CPU->USP = res; - } -} -POST_IO -CCnt -= 20; -goto C68k_Exec_End; - -// RTS -case 0x4E75: -{ - u32 res; - PRE_IO - POP_32_F(res) - SET_PC(res) - POST_IO -} -RET(16) - -// TRAPV -case 0x4E76: -{ - u32 res; - if (CPU->flag_V & 0x80) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_TRAPV_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(4) - -// RTR -case 0x4E77: -{ - u32 res; - PRE_IO - POP_16_F(res) - SET_CCR(res) - POP_32_F(res) - SET_PC(res) - POST_IO -} -RET(20) -case 0x4E91: -case 0x4E92: -case 0x4E93: -case 0x4E94: -case 0x4E95: -case 0x4E96: -case 0x4E97: - -// JSR -case 0x4E90: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - SET_PC(adr) - POST_IO -} -RET(16) -case 0x4EA9: -case 0x4EAA: -case 0x4EAB: -case 0x4EAC: -case 0x4EAD: -case 0x4EAE: -case 0x4EAF: - -// JSR -case 0x4EA8: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - SET_PC(adr) - POST_IO -} -RET(18) -case 0x4EB1: -case 0x4EB2: -case 0x4EB3: -case 0x4EB4: -case 0x4EB5: -case 0x4EB6: -case 0x4EB7: - -// JSR -case 0x4EB0: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - SET_PC(adr) - POST_IO -} -RET(22) - -// JSR -case 0x4EB8: -{ - u32 adr; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - SET_PC(adr) - POST_IO -} -RET(18) - -// JSR -case 0x4EB9: -{ - u32 adr; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - SET_PC(adr) - POST_IO -} -RET(20) - -// JSR -case 0x4EBA: -{ - u32 adr; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - SET_PC(adr) - POST_IO -} -RET(18) - -// JSR -case 0x4EBB: -{ - u32 adr; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - SET_PC(adr) - POST_IO -} -RET(22) -case 0x4ED1: -case 0x4ED2: -case 0x4ED3: -case 0x4ED4: -case 0x4ED5: -case 0x4ED6: -case 0x4ED7: - -// JMP -case 0x4ED0: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7]; - SET_PC(adr) -} -RET(8) -case 0x4EE9: -case 0x4EEA: -case 0x4EEB: -case 0x4EEC: -case 0x4EED: -case 0x4EEE: -case 0x4EEF: - -// JMP -case 0x4EE8: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - SET_PC(adr) -} -RET(10) -case 0x4EF1: -case 0x4EF2: -case 0x4EF3: -case 0x4EF4: -case 0x4EF5: -case 0x4EF6: -case 0x4EF7: - -// JMP -case 0x4EF0: -{ - u32 adr; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - SET_PC(adr) -} -RET(14) - -// JMP -case 0x4EF8: -{ - u32 adr; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - SET_PC(adr) -} -RET(10) - -// JMP -case 0x4EF9: -{ - u32 adr; - adr = (s32)FETCH_LONG; - PC += 4; - SET_PC(adr) -} -RET(12) - -// JMP -case 0x4EFA: -{ - u32 adr; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - SET_PC(adr) -} -RET(10) - -// JMP -case 0x4EFB: -{ - u32 adr; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - SET_PC(adr) -} -RET(14) -case 0x4380: -case 0x4580: -case 0x4780: -case 0x4980: -case 0x4B80: -case 0x4D80: -case 0x4F80: -case 0x4181: -case 0x4381: -case 0x4581: -case 0x4781: -case 0x4981: -case 0x4B81: -case 0x4D81: -case 0x4F81: -case 0x4182: -case 0x4382: -case 0x4582: -case 0x4782: -case 0x4982: -case 0x4B82: -case 0x4D82: -case 0x4F82: -case 0x4183: -case 0x4383: -case 0x4583: -case 0x4783: -case 0x4983: -case 0x4B83: -case 0x4D83: -case 0x4F83: -case 0x4184: -case 0x4384: -case 0x4584: -case 0x4784: -case 0x4984: -case 0x4B84: -case 0x4D84: -case 0x4F84: -case 0x4185: -case 0x4385: -case 0x4585: -case 0x4785: -case 0x4985: -case 0x4B85: -case 0x4D85: -case 0x4F85: -case 0x4186: -case 0x4386: -case 0x4586: -case 0x4786: -case 0x4986: -case 0x4B86: -case 0x4D86: -case 0x4F86: -case 0x4187: -case 0x4387: -case 0x4587: -case 0x4787: -case 0x4987: -case 0x4B87: -case 0x4D87: -case 0x4F87: - -// CHK -case 0x4180: -{ - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(10) -case 0x4390: -case 0x4590: -case 0x4790: -case 0x4990: -case 0x4B90: -case 0x4D90: -case 0x4F90: -case 0x4191: -case 0x4391: -case 0x4591: -case 0x4791: -case 0x4991: -case 0x4B91: -case 0x4D91: -case 0x4F91: -case 0x4192: -case 0x4392: -case 0x4592: -case 0x4792: -case 0x4992: -case 0x4B92: -case 0x4D92: -case 0x4F92: -case 0x4193: -case 0x4393: -case 0x4593: -case 0x4793: -case 0x4993: -case 0x4B93: -case 0x4D93: -case 0x4F93: -case 0x4194: -case 0x4394: -case 0x4594: -case 0x4794: -case 0x4994: -case 0x4B94: -case 0x4D94: -case 0x4F94: -case 0x4195: -case 0x4395: -case 0x4595: -case 0x4795: -case 0x4995: -case 0x4B95: -case 0x4D95: -case 0x4F95: -case 0x4196: -case 0x4396: -case 0x4596: -case 0x4796: -case 0x4996: -case 0x4B96: -case 0x4D96: -case 0x4F96: -case 0x4197: -case 0x4397: -case 0x4597: -case 0x4797: -case 0x4997: -case 0x4B97: -case 0x4D97: -case 0x4F97: - -// CHK -case 0x4190: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(14) -case 0x4398: -case 0x4598: -case 0x4798: -case 0x4998: -case 0x4B98: -case 0x4D98: -case 0x4F98: -case 0x4199: -case 0x4399: -case 0x4599: -case 0x4799: -case 0x4999: -case 0x4B99: -case 0x4D99: -case 0x4F99: -case 0x419A: -case 0x439A: -case 0x459A: -case 0x479A: -case 0x499A: -case 0x4B9A: -case 0x4D9A: -case 0x4F9A: -case 0x419B: -case 0x439B: -case 0x459B: -case 0x479B: -case 0x499B: -case 0x4B9B: -case 0x4D9B: -case 0x4F9B: -case 0x419C: -case 0x439C: -case 0x459C: -case 0x479C: -case 0x499C: -case 0x4B9C: -case 0x4D9C: -case 0x4F9C: -case 0x419D: -case 0x439D: -case 0x459D: -case 0x479D: -case 0x499D: -case 0x4B9D: -case 0x4D9D: -case 0x4F9D: -case 0x419E: -case 0x439E: -case 0x459E: -case 0x479E: -case 0x499E: -case 0x4B9E: -case 0x4D9E: -case 0x4F9E: - -// CHK -case 0x4198: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(14) -case 0x43A0: -case 0x45A0: -case 0x47A0: -case 0x49A0: -case 0x4BA0: -case 0x4DA0: -case 0x4FA0: -case 0x41A1: -case 0x43A1: -case 0x45A1: -case 0x47A1: -case 0x49A1: -case 0x4BA1: -case 0x4DA1: -case 0x4FA1: -case 0x41A2: -case 0x43A2: -case 0x45A2: -case 0x47A2: -case 0x49A2: -case 0x4BA2: -case 0x4DA2: -case 0x4FA2: -case 0x41A3: -case 0x43A3: -case 0x45A3: -case 0x47A3: -case 0x49A3: -case 0x4BA3: -case 0x4DA3: -case 0x4FA3: -case 0x41A4: -case 0x43A4: -case 0x45A4: -case 0x47A4: -case 0x49A4: -case 0x4BA4: -case 0x4DA4: -case 0x4FA4: -case 0x41A5: -case 0x43A5: -case 0x45A5: -case 0x47A5: -case 0x49A5: -case 0x4BA5: -case 0x4DA5: -case 0x4FA5: -case 0x41A6: -case 0x43A6: -case 0x45A6: -case 0x47A6: -case 0x49A6: -case 0x4BA6: -case 0x4DA6: -case 0x4FA6: - -// CHK -case 0x41A0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(16) -case 0x43A8: -case 0x45A8: -case 0x47A8: -case 0x49A8: -case 0x4BA8: -case 0x4DA8: -case 0x4FA8: -case 0x41A9: -case 0x43A9: -case 0x45A9: -case 0x47A9: -case 0x49A9: -case 0x4BA9: -case 0x4DA9: -case 0x4FA9: -case 0x41AA: -case 0x43AA: -case 0x45AA: -case 0x47AA: -case 0x49AA: -case 0x4BAA: -case 0x4DAA: -case 0x4FAA: -case 0x41AB: -case 0x43AB: -case 0x45AB: -case 0x47AB: -case 0x49AB: -case 0x4BAB: -case 0x4DAB: -case 0x4FAB: -case 0x41AC: -case 0x43AC: -case 0x45AC: -case 0x47AC: -case 0x49AC: -case 0x4BAC: -case 0x4DAC: -case 0x4FAC: -case 0x41AD: -case 0x43AD: -case 0x45AD: -case 0x47AD: -case 0x49AD: -case 0x4BAD: -case 0x4DAD: -case 0x4FAD: -case 0x41AE: -case 0x43AE: -case 0x45AE: -case 0x47AE: -case 0x49AE: -case 0x4BAE: -case 0x4DAE: -case 0x4FAE: -case 0x41AF: -case 0x43AF: -case 0x45AF: -case 0x47AF: -case 0x49AF: -case 0x4BAF: -case 0x4DAF: -case 0x4FAF: - -// CHK -case 0x41A8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(18) -case 0x43B0: -case 0x45B0: -case 0x47B0: -case 0x49B0: -case 0x4BB0: -case 0x4DB0: -case 0x4FB0: -case 0x41B1: -case 0x43B1: -case 0x45B1: -case 0x47B1: -case 0x49B1: -case 0x4BB1: -case 0x4DB1: -case 0x4FB1: -case 0x41B2: -case 0x43B2: -case 0x45B2: -case 0x47B2: -case 0x49B2: -case 0x4BB2: -case 0x4DB2: -case 0x4FB2: -case 0x41B3: -case 0x43B3: -case 0x45B3: -case 0x47B3: -case 0x49B3: -case 0x4BB3: -case 0x4DB3: -case 0x4FB3: -case 0x41B4: -case 0x43B4: -case 0x45B4: -case 0x47B4: -case 0x49B4: -case 0x4BB4: -case 0x4DB4: -case 0x4FB4: -case 0x41B5: -case 0x43B5: -case 0x45B5: -case 0x47B5: -case 0x49B5: -case 0x4BB5: -case 0x4DB5: -case 0x4FB5: -case 0x41B6: -case 0x43B6: -case 0x45B6: -case 0x47B6: -case 0x49B6: -case 0x4BB6: -case 0x4DB6: -case 0x4FB6: -case 0x41B7: -case 0x43B7: -case 0x45B7: -case 0x47B7: -case 0x49B7: -case 0x4BB7: -case 0x4DB7: -case 0x4FB7: - -// CHK -case 0x41B0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(20) -case 0x43B8: -case 0x45B8: -case 0x47B8: -case 0x49B8: -case 0x4BB8: -case 0x4DB8: -case 0x4FB8: - -// CHK -case 0x41B8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(18) -case 0x43B9: -case 0x45B9: -case 0x47B9: -case 0x49B9: -case 0x4BB9: -case 0x4DB9: -case 0x4FB9: - -// CHK -case 0x41B9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(22) -case 0x43BA: -case 0x45BA: -case 0x47BA: -case 0x49BA: -case 0x4BBA: -case 0x4DBA: -case 0x4FBA: - -// CHK -case 0x41BA: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(18) -case 0x43BB: -case 0x45BB: -case 0x47BB: -case 0x49BB: -case 0x4BBB: -case 0x4DBB: -case 0x4FBB: - -// CHK -case 0x41BB: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(20) -case 0x43BC: -case 0x45BC: -case 0x47BC: -case 0x49BC: -case 0x4BBC: -case 0x4DBC: -case 0x4FBC: - -// CHK -case 0x41BC: -{ - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(14) -case 0x439F: -case 0x459F: -case 0x479F: -case 0x499F: -case 0x4B9F: -case 0x4D9F: -case 0x4F9F: - -// CHK -case 0x419F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(14) -case 0x43A7: -case 0x45A7: -case 0x47A7: -case 0x49A7: -case 0x4BA7: -case 0x4DA7: -case 0x4FA7: - -// CHK -case 0x41A7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - if (((s32)res < 0) || (res > src)) - { - CPU->flag_N = res >> 8; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_CHK_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - } - POST_IO -} -RET(16) -case 0x43D0: -case 0x45D0: -case 0x47D0: -case 0x49D0: -case 0x4BD0: -case 0x4DD0: -case 0x4FD0: -case 0x41D1: -case 0x43D1: -case 0x45D1: -case 0x47D1: -case 0x49D1: -case 0x4BD1: -case 0x4DD1: -case 0x4FD1: -case 0x41D2: -case 0x43D2: -case 0x45D2: -case 0x47D2: -case 0x49D2: -case 0x4BD2: -case 0x4DD2: -case 0x4FD2: -case 0x41D3: -case 0x43D3: -case 0x45D3: -case 0x47D3: -case 0x49D3: -case 0x4BD3: -case 0x4DD3: -case 0x4FD3: -case 0x41D4: -case 0x43D4: -case 0x45D4: -case 0x47D4: -case 0x49D4: -case 0x4BD4: -case 0x4DD4: -case 0x4FD4: -case 0x41D5: -case 0x43D5: -case 0x45D5: -case 0x47D5: -case 0x49D5: -case 0x4BD5: -case 0x4DD5: -case 0x4FD5: -case 0x41D6: -case 0x43D6: -case 0x45D6: -case 0x47D6: -case 0x49D6: -case 0x4BD6: -case 0x4DD6: -case 0x4FD6: -case 0x41D7: -case 0x43D7: -case 0x45D7: -case 0x47D7: -case 0x49D7: -case 0x4BD7: -case 0x4DD7: -case 0x4FD7: - -// LEA -case 0x41D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - res = adr; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(4) -case 0x43E8: -case 0x45E8: -case 0x47E8: -case 0x49E8: -case 0x4BE8: -case 0x4DE8: -case 0x4FE8: -case 0x41E9: -case 0x43E9: -case 0x45E9: -case 0x47E9: -case 0x49E9: -case 0x4BE9: -case 0x4DE9: -case 0x4FE9: -case 0x41EA: -case 0x43EA: -case 0x45EA: -case 0x47EA: -case 0x49EA: -case 0x4BEA: -case 0x4DEA: -case 0x4FEA: -case 0x41EB: -case 0x43EB: -case 0x45EB: -case 0x47EB: -case 0x49EB: -case 0x4BEB: -case 0x4DEB: -case 0x4FEB: -case 0x41EC: -case 0x43EC: -case 0x45EC: -case 0x47EC: -case 0x49EC: -case 0x4BEC: -case 0x4DEC: -case 0x4FEC: -case 0x41ED: -case 0x43ED: -case 0x45ED: -case 0x47ED: -case 0x49ED: -case 0x4BED: -case 0x4DED: -case 0x4FED: -case 0x41EE: -case 0x43EE: -case 0x45EE: -case 0x47EE: -case 0x49EE: -case 0x4BEE: -case 0x4DEE: -case 0x4FEE: -case 0x41EF: -case 0x43EF: -case 0x45EF: -case 0x47EF: -case 0x49EF: -case 0x4BEF: -case 0x4DEF: -case 0x4FEF: - -// LEA -case 0x41E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - res = adr; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(8) -case 0x43F0: -case 0x45F0: -case 0x47F0: -case 0x49F0: -case 0x4BF0: -case 0x4DF0: -case 0x4FF0: -case 0x41F1: -case 0x43F1: -case 0x45F1: -case 0x47F1: -case 0x49F1: -case 0x4BF1: -case 0x4DF1: -case 0x4FF1: -case 0x41F2: -case 0x43F2: -case 0x45F2: -case 0x47F2: -case 0x49F2: -case 0x4BF2: -case 0x4DF2: -case 0x4FF2: -case 0x41F3: -case 0x43F3: -case 0x45F3: -case 0x47F3: -case 0x49F3: -case 0x4BF3: -case 0x4DF3: -case 0x4FF3: -case 0x41F4: -case 0x43F4: -case 0x45F4: -case 0x47F4: -case 0x49F4: -case 0x4BF4: -case 0x4DF4: -case 0x4FF4: -case 0x41F5: -case 0x43F5: -case 0x45F5: -case 0x47F5: -case 0x49F5: -case 0x4BF5: -case 0x4DF5: -case 0x4FF5: -case 0x41F6: -case 0x43F6: -case 0x45F6: -case 0x47F6: -case 0x49F6: -case 0x4BF6: -case 0x4DF6: -case 0x4FF6: -case 0x41F7: -case 0x43F7: -case 0x45F7: -case 0x47F7: -case 0x49F7: -case 0x4BF7: -case 0x4DF7: -case 0x4FF7: - -// LEA -case 0x41F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - res = adr; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(12) -case 0x43F8: -case 0x45F8: -case 0x47F8: -case 0x49F8: -case 0x4BF8: -case 0x4DF8: -case 0x4FF8: - -// LEA -case 0x41F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - res = adr; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(8) -case 0x43F9: -case 0x45F9: -case 0x47F9: -case 0x49F9: -case 0x4BF9: -case 0x4DF9: -case 0x4FF9: - -// LEA -case 0x41F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - res = adr; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(12) -case 0x43FA: -case 0x45FA: -case 0x47FA: -case 0x49FA: -case 0x4BFA: -case 0x4DFA: -case 0x4FFA: - -// LEA -case 0x41FA: -{ - u32 adr; - u32 res; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - res = adr; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(8) -case 0x43FB: -case 0x45FB: -case 0x47FB: -case 0x49FB: -case 0x4BFB: -case 0x4DFB: -case 0x4FFB: - -// LEA -case 0x41FB: -{ - u32 adr; - u32 res; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - res = adr; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(12) diff --git a/yabause/src/c68k/c68k_op5.inc b/yabause/src/c68k/c68k_op5.inc deleted file mode 100644 index f11d085b15..0000000000 --- a/yabause/src/c68k/c68k_op5.inc +++ /dev/null @@ -1,8265 +0,0 @@ -case 0x50C1: -case 0x50C2: -case 0x50C3: -case 0x50C4: -case 0x50C5: -case 0x50C6: -case 0x50C7: - -// STCC -case 0x50C0: -{ - u32 res; - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) -} -case 0x51C1: -case 0x51C2: -case 0x51C3: -case 0x51C4: -case 0x51C5: -case 0x51C6: -case 0x51C7: - -// STCC -case 0x51C0: -{ - u32 res; - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x52C1: -case 0x52C2: -case 0x52C3: -case 0x52C4: -case 0x52C5: -case 0x52C6: -case 0x52C7: - -// STCC -case 0x52C0: -{ - u32 res; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x53C1: -case 0x53C2: -case 0x53C3: -case 0x53C4: -case 0x53C5: -case 0x53C6: -case 0x53C7: - -// STCC -case 0x53C0: -{ - u32 res; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x54C1: -case 0x54C2: -case 0x54C3: -case 0x54C4: -case 0x54C5: -case 0x54C6: -case 0x54C7: - -// STCC -case 0x54C0: -{ - u32 res; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x55C1: -case 0x55C2: -case 0x55C3: -case 0x55C4: -case 0x55C5: -case 0x55C6: -case 0x55C7: - -// STCC -case 0x55C0: -{ - u32 res; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x56C1: -case 0x56C2: -case 0x56C3: -case 0x56C4: -case 0x56C5: -case 0x56C6: -case 0x56C7: - -// STCC -case 0x56C0: -{ - u32 res; - if (CPU->flag_notZ) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x57C1: -case 0x57C2: -case 0x57C3: -case 0x57C4: -case 0x57C5: -case 0x57C6: -case 0x57C7: - -// STCC -case 0x57C0: -{ - u32 res; - if (!CPU->flag_notZ) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x58C1: -case 0x58C2: -case 0x58C3: -case 0x58C4: -case 0x58C5: -case 0x58C6: -case 0x58C7: - -// STCC -case 0x58C0: -{ - u32 res; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x59C1: -case 0x59C2: -case 0x59C3: -case 0x59C4: -case 0x59C5: -case 0x59C6: -case 0x59C7: - -// STCC -case 0x59C0: -{ - u32 res; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x5AC1: -case 0x5AC2: -case 0x5AC3: -case 0x5AC4: -case 0x5AC5: -case 0x5AC6: -case 0x5AC7: - -// STCC -case 0x5AC0: -{ - u32 res; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x5BC1: -case 0x5BC2: -case 0x5BC3: -case 0x5BC4: -case 0x5BC5: -case 0x5BC6: -case 0x5BC7: - -// STCC -case 0x5BC0: -{ - u32 res; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x5CC1: -case 0x5CC2: -case 0x5CC3: -case 0x5CC4: -case 0x5CC5: -case 0x5CC6: -case 0x5CC7: - -// STCC -case 0x5CC0: -{ - u32 res; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x5DC1: -case 0x5DC2: -case 0x5DC3: -case 0x5DC4: -case 0x5DC5: -case 0x5DC6: -case 0x5DC7: - -// STCC -case 0x5DC0: -{ - u32 res; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x5EC1: -case 0x5EC2: -case 0x5EC3: -case 0x5EC4: -case 0x5EC5: -case 0x5EC6: -case 0x5EC7: - -// STCC -case 0x5EC0: -{ - u32 res; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x5FC1: -case 0x5FC2: -case 0x5FC3: -case 0x5FC4: -case 0x5FC5: -case 0x5FC6: -case 0x5FC7: - -// STCC -case 0x5FC0: -{ - u32 res; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(4) -} -case 0x50D1: -case 0x50D2: -case 0x50D3: -case 0x50D4: -case 0x50D5: -case 0x50D6: -case 0x50D7: - -// STCC -case 0x50D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x51D1: -case 0x51D2: -case 0x51D3: -case 0x51D4: -case 0x51D5: -case 0x51D6: -case 0x51D7: - -// STCC -case 0x51D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x52D1: -case 0x52D2: -case 0x52D3: -case 0x52D4: -case 0x52D5: -case 0x52D6: -case 0x52D7: - -// STCC -case 0x52D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x53D1: -case 0x53D2: -case 0x53D3: -case 0x53D4: -case 0x53D5: -case 0x53D6: -case 0x53D7: - -// STCC -case 0x53D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x54D1: -case 0x54D2: -case 0x54D3: -case 0x54D4: -case 0x54D5: -case 0x54D6: -case 0x54D7: - -// STCC -case 0x54D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x55D1: -case 0x55D2: -case 0x55D3: -case 0x55D4: -case 0x55D5: -case 0x55D6: -case 0x55D7: - -// STCC -case 0x55D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x56D1: -case 0x56D2: -case 0x56D3: -case 0x56D4: -case 0x56D5: -case 0x56D6: -case 0x56D7: - -// STCC -case 0x56D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x57D1: -case 0x57D2: -case 0x57D3: -case 0x57D4: -case 0x57D5: -case 0x57D6: -case 0x57D7: - -// STCC -case 0x57D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x58D1: -case 0x58D2: -case 0x58D3: -case 0x58D4: -case 0x58D5: -case 0x58D6: -case 0x58D7: - -// STCC -case 0x58D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x59D1: -case 0x59D2: -case 0x59D3: -case 0x59D4: -case 0x59D5: -case 0x59D6: -case 0x59D7: - -// STCC -case 0x59D0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5AD1: -case 0x5AD2: -case 0x5AD3: -case 0x5AD4: -case 0x5AD5: -case 0x5AD6: -case 0x5AD7: - -// STCC -case 0x5AD0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5BD1: -case 0x5BD2: -case 0x5BD3: -case 0x5BD4: -case 0x5BD5: -case 0x5BD6: -case 0x5BD7: - -// STCC -case 0x5BD0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5CD1: -case 0x5CD2: -case 0x5CD3: -case 0x5CD4: -case 0x5CD5: -case 0x5CD6: -case 0x5CD7: - -// STCC -case 0x5CD0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5DD1: -case 0x5DD2: -case 0x5DD3: -case 0x5DD4: -case 0x5DD5: -case 0x5DD6: -case 0x5DD7: - -// STCC -case 0x5DD0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5ED1: -case 0x5ED2: -case 0x5ED3: -case 0x5ED4: -case 0x5ED5: -case 0x5ED6: -case 0x5ED7: - -// STCC -case 0x5ED0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5FD1: -case 0x5FD2: -case 0x5FD3: -case 0x5FD4: -case 0x5FD5: -case 0x5FD6: -case 0x5FD7: - -// STCC -case 0x5FD0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x50D9: -case 0x50DA: -case 0x50DB: -case 0x50DC: -case 0x50DD: -case 0x50DE: - -// STCC -case 0x50D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x51D9: -case 0x51DA: -case 0x51DB: -case 0x51DC: -case 0x51DD: -case 0x51DE: - -// STCC -case 0x51D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x52D9: -case 0x52DA: -case 0x52DB: -case 0x52DC: -case 0x52DD: -case 0x52DE: - -// STCC -case 0x52D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x53D9: -case 0x53DA: -case 0x53DB: -case 0x53DC: -case 0x53DD: -case 0x53DE: - -// STCC -case 0x53D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x54D9: -case 0x54DA: -case 0x54DB: -case 0x54DC: -case 0x54DD: -case 0x54DE: - -// STCC -case 0x54D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x55D9: -case 0x55DA: -case 0x55DB: -case 0x55DC: -case 0x55DD: -case 0x55DE: - -// STCC -case 0x55D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x56D9: -case 0x56DA: -case 0x56DB: -case 0x56DC: -case 0x56DD: -case 0x56DE: - -// STCC -case 0x56D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x57D9: -case 0x57DA: -case 0x57DB: -case 0x57DC: -case 0x57DD: -case 0x57DE: - -// STCC -case 0x57D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x58D9: -case 0x58DA: -case 0x58DB: -case 0x58DC: -case 0x58DD: -case 0x58DE: - -// STCC -case 0x58D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x59D9: -case 0x59DA: -case 0x59DB: -case 0x59DC: -case 0x59DD: -case 0x59DE: - -// STCC -case 0x59D8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5AD9: -case 0x5ADA: -case 0x5ADB: -case 0x5ADC: -case 0x5ADD: -case 0x5ADE: - -// STCC -case 0x5AD8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5BD9: -case 0x5BDA: -case 0x5BDB: -case 0x5BDC: -case 0x5BDD: -case 0x5BDE: - -// STCC -case 0x5BD8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5CD9: -case 0x5CDA: -case 0x5CDB: -case 0x5CDC: -case 0x5CDD: -case 0x5CDE: - -// STCC -case 0x5CD8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5DD9: -case 0x5DDA: -case 0x5DDB: -case 0x5DDC: -case 0x5DDD: -case 0x5DDE: - -// STCC -case 0x5DD8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5ED9: -case 0x5EDA: -case 0x5EDB: -case 0x5EDC: -case 0x5EDD: -case 0x5EDE: - -// STCC -case 0x5ED8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x5FD9: -case 0x5FDA: -case 0x5FDB: -case 0x5FDC: -case 0x5FDD: -case 0x5FDE: - -// STCC -case 0x5FD8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} -case 0x50E1: -case 0x50E2: -case 0x50E3: -case 0x50E4: -case 0x50E5: -case 0x50E6: - -// STCC -case 0x50E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x51E1: -case 0x51E2: -case 0x51E3: -case 0x51E4: -case 0x51E5: -case 0x51E6: - -// STCC -case 0x51E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x52E1: -case 0x52E2: -case 0x52E3: -case 0x52E4: -case 0x52E5: -case 0x52E6: - -// STCC -case 0x52E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x53E1: -case 0x53E2: -case 0x53E3: -case 0x53E4: -case 0x53E5: -case 0x53E6: - -// STCC -case 0x53E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x54E1: -case 0x54E2: -case 0x54E3: -case 0x54E4: -case 0x54E5: -case 0x54E6: - -// STCC -case 0x54E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x55E1: -case 0x55E2: -case 0x55E3: -case 0x55E4: -case 0x55E5: -case 0x55E6: - -// STCC -case 0x55E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x56E1: -case 0x56E2: -case 0x56E3: -case 0x56E4: -case 0x56E5: -case 0x56E6: - -// STCC -case 0x56E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x57E1: -case 0x57E2: -case 0x57E3: -case 0x57E4: -case 0x57E5: -case 0x57E6: - -// STCC -case 0x57E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x58E1: -case 0x58E2: -case 0x58E3: -case 0x58E4: -case 0x58E5: -case 0x58E6: - -// STCC -case 0x58E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x59E1: -case 0x59E2: -case 0x59E3: -case 0x59E4: -case 0x59E5: -case 0x59E6: - -// STCC -case 0x59E0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x5AE1: -case 0x5AE2: -case 0x5AE3: -case 0x5AE4: -case 0x5AE5: -case 0x5AE6: - -// STCC -case 0x5AE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x5BE1: -case 0x5BE2: -case 0x5BE3: -case 0x5BE4: -case 0x5BE5: -case 0x5BE6: - -// STCC -case 0x5BE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x5CE1: -case 0x5CE2: -case 0x5CE3: -case 0x5CE4: -case 0x5CE5: -case 0x5CE6: - -// STCC -case 0x5CE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x5DE1: -case 0x5DE2: -case 0x5DE3: -case 0x5DE4: -case 0x5DE5: -case 0x5DE6: - -// STCC -case 0x5DE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x5EE1: -case 0x5EE2: -case 0x5EE3: -case 0x5EE4: -case 0x5EE5: -case 0x5EE6: - -// STCC -case 0x5EE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x5FE1: -case 0x5FE2: -case 0x5FE3: -case 0x5FE4: -case 0x5FE5: -case 0x5FE6: - -// STCC -case 0x5FE0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x50E9: -case 0x50EA: -case 0x50EB: -case 0x50EC: -case 0x50ED: -case 0x50EE: -case 0x50EF: - -// STCC -case 0x50E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x51E9: -case 0x51EA: -case 0x51EB: -case 0x51EC: -case 0x51ED: -case 0x51EE: -case 0x51EF: - -// STCC -case 0x51E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x52E9: -case 0x52EA: -case 0x52EB: -case 0x52EC: -case 0x52ED: -case 0x52EE: -case 0x52EF: - -// STCC -case 0x52E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x53E9: -case 0x53EA: -case 0x53EB: -case 0x53EC: -case 0x53ED: -case 0x53EE: -case 0x53EF: - -// STCC -case 0x53E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x54E9: -case 0x54EA: -case 0x54EB: -case 0x54EC: -case 0x54ED: -case 0x54EE: -case 0x54EF: - -// STCC -case 0x54E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x55E9: -case 0x55EA: -case 0x55EB: -case 0x55EC: -case 0x55ED: -case 0x55EE: -case 0x55EF: - -// STCC -case 0x55E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x56E9: -case 0x56EA: -case 0x56EB: -case 0x56EC: -case 0x56ED: -case 0x56EE: -case 0x56EF: - -// STCC -case 0x56E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x57E9: -case 0x57EA: -case 0x57EB: -case 0x57EC: -case 0x57ED: -case 0x57EE: -case 0x57EF: - -// STCC -case 0x57E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x58E9: -case 0x58EA: -case 0x58EB: -case 0x58EC: -case 0x58ED: -case 0x58EE: -case 0x58EF: - -// STCC -case 0x58E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x59E9: -case 0x59EA: -case 0x59EB: -case 0x59EC: -case 0x59ED: -case 0x59EE: -case 0x59EF: - -// STCC -case 0x59E8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x5AE9: -case 0x5AEA: -case 0x5AEB: -case 0x5AEC: -case 0x5AED: -case 0x5AEE: -case 0x5AEF: - -// STCC -case 0x5AE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x5BE9: -case 0x5BEA: -case 0x5BEB: -case 0x5BEC: -case 0x5BED: -case 0x5BEE: -case 0x5BEF: - -// STCC -case 0x5BE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x5CE9: -case 0x5CEA: -case 0x5CEB: -case 0x5CEC: -case 0x5CED: -case 0x5CEE: -case 0x5CEF: - -// STCC -case 0x5CE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x5DE9: -case 0x5DEA: -case 0x5DEB: -case 0x5DEC: -case 0x5DED: -case 0x5DEE: -case 0x5DEF: - -// STCC -case 0x5DE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x5EE9: -case 0x5EEA: -case 0x5EEB: -case 0x5EEC: -case 0x5EED: -case 0x5EEE: -case 0x5EEF: - -// STCC -case 0x5EE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x5FE9: -case 0x5FEA: -case 0x5FEB: -case 0x5FEC: -case 0x5FED: -case 0x5FEE: -case 0x5FEF: - -// STCC -case 0x5FE8: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} -case 0x50F1: -case 0x50F2: -case 0x50F3: -case 0x50F4: -case 0x50F5: -case 0x50F6: -case 0x50F7: - -// STCC -case 0x50F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x51F1: -case 0x51F2: -case 0x51F3: -case 0x51F4: -case 0x51F5: -case 0x51F6: -case 0x51F7: - -// STCC -case 0x51F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x52F1: -case 0x52F2: -case 0x52F3: -case 0x52F4: -case 0x52F5: -case 0x52F6: -case 0x52F7: - -// STCC -case 0x52F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x53F1: -case 0x53F2: -case 0x53F3: -case 0x53F4: -case 0x53F5: -case 0x53F6: -case 0x53F7: - -// STCC -case 0x53F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x54F1: -case 0x54F2: -case 0x54F3: -case 0x54F4: -case 0x54F5: -case 0x54F6: -case 0x54F7: - -// STCC -case 0x54F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x55F1: -case 0x55F2: -case 0x55F3: -case 0x55F4: -case 0x55F5: -case 0x55F6: -case 0x55F7: - -// STCC -case 0x55F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x56F1: -case 0x56F2: -case 0x56F3: -case 0x56F4: -case 0x56F5: -case 0x56F6: -case 0x56F7: - -// STCC -case 0x56F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x57F1: -case 0x57F2: -case 0x57F3: -case 0x57F4: -case 0x57F5: -case 0x57F6: -case 0x57F7: - -// STCC -case 0x57F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x58F1: -case 0x58F2: -case 0x58F3: -case 0x58F4: -case 0x58F5: -case 0x58F6: -case 0x58F7: - -// STCC -case 0x58F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x59F1: -case 0x59F2: -case 0x59F3: -case 0x59F4: -case 0x59F5: -case 0x59F6: -case 0x59F7: - -// STCC -case 0x59F0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x5AF1: -case 0x5AF2: -case 0x5AF3: -case 0x5AF4: -case 0x5AF5: -case 0x5AF6: -case 0x5AF7: - -// STCC -case 0x5AF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x5BF1: -case 0x5BF2: -case 0x5BF3: -case 0x5BF4: -case 0x5BF5: -case 0x5BF6: -case 0x5BF7: - -// STCC -case 0x5BF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x5CF1: -case 0x5CF2: -case 0x5CF3: -case 0x5CF4: -case 0x5CF5: -case 0x5CF6: -case 0x5CF7: - -// STCC -case 0x5CF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x5DF1: -case 0x5DF2: -case 0x5DF3: -case 0x5DF4: -case 0x5DF5: -case 0x5DF6: -case 0x5DF7: - -// STCC -case 0x5DF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x5EF1: -case 0x5EF2: -case 0x5EF3: -case 0x5EF4: -case 0x5EF5: -case 0x5EF6: -case 0x5EF7: - -// STCC -case 0x5EF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} -case 0x5FF1: -case 0x5FF2: -case 0x5FF3: -case 0x5FF4: -case 0x5FF5: -case 0x5FF6: -case 0x5FF7: - -// STCC -case 0x5FF0: -{ - u32 adr; - u32 res; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(18) -} - -// STCC -case 0x50F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x51F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x52F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x53F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x54F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x55F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x56F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x57F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x58F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x59F8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x5AF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x5BF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x5CF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x5DF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x5EF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x5FF8: -{ - u32 adr; - u32 res; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(16) -} - -// STCC -case 0x50F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x51F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x52F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x53F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x54F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x55F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x56F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x57F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x58F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x59F9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x5AF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x5BF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x5CF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x5DF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x5EF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x5FF9: -{ - u32 adr; - u32 res; - adr = (s32)FETCH_LONG; - PC += 4; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(20) -} - -// STCC -case 0x50DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x51DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x52DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x53DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x54DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x55DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x56DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x57DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x58DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x59DF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x5ADF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x5BDF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x5CDF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x5DDF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x5EDF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x5FDF: -{ - u32 adr; - u32 res; - adr = CPU->A[7]; - CPU->A[7] += 2; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(12) -} - -// STCC -case 0x50E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x51E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x52E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x53E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x54E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (!(CPU->flag_C & 0x100)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x55E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (CPU->flag_C & 0x100) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x56E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x57E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (!CPU->flag_notZ) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x58E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (!(CPU->flag_V & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x59E7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (CPU->flag_V & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x5AE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (!(CPU->flag_N & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x5BE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (CPU->flag_N & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x5CE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x5DE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x5EE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} - -// STCC -case 0x5FE7: -{ - u32 adr; - u32 res; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = 0xFF; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) - } - res = 0; - PRE_IO - WRITE_BYTE_F(adr, res) - POST_IO - RET(14) -} -case 0x50C9: -case 0x50CA: -case 0x50CB: -case 0x50CC: -case 0x50CD: -case 0x50CE: -case 0x50CF: - -// DBCC -case 0x50C8: -{ - PC += 2; -} -RET(12) -case 0x51C9: -case 0x51CA: -case 0x51CB: -case 0x51CC: -case 0x51CD: -case 0x51CE: -case 0x51CF: - -// DBCC -case 0x51C8: -{ - u32 res; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(14) -case 0x52C9: -case 0x52CA: -case 0x52CB: -case 0x52CC: -case 0x52CD: -case 0x52CE: -case 0x52CF: - -// DBCC -case 0x52C8: -{ - u32 res; - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x53C9: -case 0x53CA: -case 0x53CB: -case 0x53CC: -case 0x53CD: -case 0x53CE: -case 0x53CF: - -// DBCC -case 0x53C8: -{ - u32 res; - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x54C9: -case 0x54CA: -case 0x54CB: -case 0x54CC: -case 0x54CD: -case 0x54CE: -case 0x54CF: - -// DBCC -case 0x54C8: -{ - u32 res; - if (CPU->flag_C & 0x100) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x55C9: -case 0x55CA: -case 0x55CB: -case 0x55CC: -case 0x55CD: -case 0x55CE: -case 0x55CF: - -// DBCC -case 0x55C8: -{ - u32 res; - if (!(CPU->flag_C & 0x100)) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x56C9: -case 0x56CA: -case 0x56CB: -case 0x56CC: -case 0x56CD: -case 0x56CE: -case 0x56CF: - -// DBCC -case 0x56C8: -{ - u32 res; - if (!CPU->flag_notZ) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x57C9: -case 0x57CA: -case 0x57CB: -case 0x57CC: -case 0x57CD: -case 0x57CE: -case 0x57CF: - -// DBCC -case 0x57C8: -{ - u32 res; - if (CPU->flag_notZ) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x58C9: -case 0x58CA: -case 0x58CB: -case 0x58CC: -case 0x58CD: -case 0x58CE: -case 0x58CF: - -// DBCC -case 0x58C8: -{ - u32 res; - if (CPU->flag_V & 0x80) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x59C9: -case 0x59CA: -case 0x59CB: -case 0x59CC: -case 0x59CD: -case 0x59CE: -case 0x59CF: - -// DBCC -case 0x59C8: -{ - u32 res; - if (!(CPU->flag_V & 0x80)) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x5AC9: -case 0x5ACA: -case 0x5ACB: -case 0x5ACC: -case 0x5ACD: -case 0x5ACE: -case 0x5ACF: - -// DBCC -case 0x5AC8: -{ - u32 res; - if (CPU->flag_N & 0x80) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x5BC9: -case 0x5BCA: -case 0x5BCB: -case 0x5BCC: -case 0x5BCD: -case 0x5BCE: -case 0x5BCF: - -// DBCC -case 0x5BC8: -{ - u32 res; - if (!(CPU->flag_N & 0x80)) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x5CC9: -case 0x5CCA: -case 0x5CCB: -case 0x5CCC: -case 0x5CCD: -case 0x5CCE: -case 0x5CCF: - -// DBCC -case 0x5CC8: -{ - u32 res; - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x5DC9: -case 0x5DCA: -case 0x5DCB: -case 0x5DCC: -case 0x5DCD: -case 0x5DCE: -case 0x5DCF: - -// DBCC -case 0x5DC8: -{ - u32 res; - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x5EC9: -case 0x5ECA: -case 0x5ECB: -case 0x5ECC: -case 0x5ECD: -case 0x5ECE: -case 0x5ECF: - -// DBCC -case 0x5EC8: -{ - u32 res; - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x5FC9: -case 0x5FCA: -case 0x5FCB: -case 0x5FCC: -case 0x5FCD: -case 0x5FCE: -case 0x5FCF: - -// DBCC -case 0x5FC8: -{ - u32 res; - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res--; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - if ((s32)res != -1) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - } - else - { - PC += 2; - RET(12) - } - PC += 2; -} -RET(14) -case 0x5200: -case 0x5400: -case 0x5600: -case 0x5800: -case 0x5A00: -case 0x5C00: -case 0x5E00: -case 0x5001: -case 0x5201: -case 0x5401: -case 0x5601: -case 0x5801: -case 0x5A01: -case 0x5C01: -case 0x5E01: -case 0x5002: -case 0x5202: -case 0x5402: -case 0x5602: -case 0x5802: -case 0x5A02: -case 0x5C02: -case 0x5E02: -case 0x5003: -case 0x5203: -case 0x5403: -case 0x5603: -case 0x5803: -case 0x5A03: -case 0x5C03: -case 0x5E03: -case 0x5004: -case 0x5204: -case 0x5404: -case 0x5604: -case 0x5804: -case 0x5A04: -case 0x5C04: -case 0x5E04: -case 0x5005: -case 0x5205: -case 0x5405: -case 0x5605: -case 0x5805: -case 0x5A05: -case 0x5C05: -case 0x5E05: -case 0x5006: -case 0x5206: -case 0x5406: -case 0x5606: -case 0x5806: -case 0x5A06: -case 0x5C06: -case 0x5E06: -case 0x5007: -case 0x5207: -case 0x5407: -case 0x5607: -case 0x5807: -case 0x5A07: -case 0x5C07: -case 0x5E07: - -// ADDQ -case 0x5000: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u8)CPU->D[(Opcode >> 0) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x5210: -case 0x5410: -case 0x5610: -case 0x5810: -case 0x5A10: -case 0x5C10: -case 0x5E10: -case 0x5011: -case 0x5211: -case 0x5411: -case 0x5611: -case 0x5811: -case 0x5A11: -case 0x5C11: -case 0x5E11: -case 0x5012: -case 0x5212: -case 0x5412: -case 0x5612: -case 0x5812: -case 0x5A12: -case 0x5C12: -case 0x5E12: -case 0x5013: -case 0x5213: -case 0x5413: -case 0x5613: -case 0x5813: -case 0x5A13: -case 0x5C13: -case 0x5E13: -case 0x5014: -case 0x5214: -case 0x5414: -case 0x5614: -case 0x5814: -case 0x5A14: -case 0x5C14: -case 0x5E14: -case 0x5015: -case 0x5215: -case 0x5415: -case 0x5615: -case 0x5815: -case 0x5A15: -case 0x5C15: -case 0x5E15: -case 0x5016: -case 0x5216: -case 0x5416: -case 0x5616: -case 0x5816: -case 0x5A16: -case 0x5C16: -case 0x5E16: -case 0x5017: -case 0x5217: -case 0x5417: -case 0x5617: -case 0x5817: -case 0x5A17: -case 0x5C17: -case 0x5E17: - -// ADDQ -case 0x5010: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x5218: -case 0x5418: -case 0x5618: -case 0x5818: -case 0x5A18: -case 0x5C18: -case 0x5E18: -case 0x5019: -case 0x5219: -case 0x5419: -case 0x5619: -case 0x5819: -case 0x5A19: -case 0x5C19: -case 0x5E19: -case 0x501A: -case 0x521A: -case 0x541A: -case 0x561A: -case 0x581A: -case 0x5A1A: -case 0x5C1A: -case 0x5E1A: -case 0x501B: -case 0x521B: -case 0x541B: -case 0x561B: -case 0x581B: -case 0x5A1B: -case 0x5C1B: -case 0x5E1B: -case 0x501C: -case 0x521C: -case 0x541C: -case 0x561C: -case 0x581C: -case 0x5A1C: -case 0x5C1C: -case 0x5E1C: -case 0x501D: -case 0x521D: -case 0x541D: -case 0x561D: -case 0x581D: -case 0x5A1D: -case 0x5C1D: -case 0x5E1D: -case 0x501E: -case 0x521E: -case 0x541E: -case 0x561E: -case 0x581E: -case 0x5A1E: -case 0x5C1E: -case 0x5E1E: - -// ADDQ -case 0x5018: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x5220: -case 0x5420: -case 0x5620: -case 0x5820: -case 0x5A20: -case 0x5C20: -case 0x5E20: -case 0x5021: -case 0x5221: -case 0x5421: -case 0x5621: -case 0x5821: -case 0x5A21: -case 0x5C21: -case 0x5E21: -case 0x5022: -case 0x5222: -case 0x5422: -case 0x5622: -case 0x5822: -case 0x5A22: -case 0x5C22: -case 0x5E22: -case 0x5023: -case 0x5223: -case 0x5423: -case 0x5623: -case 0x5823: -case 0x5A23: -case 0x5C23: -case 0x5E23: -case 0x5024: -case 0x5224: -case 0x5424: -case 0x5624: -case 0x5824: -case 0x5A24: -case 0x5C24: -case 0x5E24: -case 0x5025: -case 0x5225: -case 0x5425: -case 0x5625: -case 0x5825: -case 0x5A25: -case 0x5C25: -case 0x5E25: -case 0x5026: -case 0x5226: -case 0x5426: -case 0x5626: -case 0x5826: -case 0x5A26: -case 0x5C26: -case 0x5E26: - -// ADDQ -case 0x5020: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x5228: -case 0x5428: -case 0x5628: -case 0x5828: -case 0x5A28: -case 0x5C28: -case 0x5E28: -case 0x5029: -case 0x5229: -case 0x5429: -case 0x5629: -case 0x5829: -case 0x5A29: -case 0x5C29: -case 0x5E29: -case 0x502A: -case 0x522A: -case 0x542A: -case 0x562A: -case 0x582A: -case 0x5A2A: -case 0x5C2A: -case 0x5E2A: -case 0x502B: -case 0x522B: -case 0x542B: -case 0x562B: -case 0x582B: -case 0x5A2B: -case 0x5C2B: -case 0x5E2B: -case 0x502C: -case 0x522C: -case 0x542C: -case 0x562C: -case 0x582C: -case 0x5A2C: -case 0x5C2C: -case 0x5E2C: -case 0x502D: -case 0x522D: -case 0x542D: -case 0x562D: -case 0x582D: -case 0x5A2D: -case 0x5C2D: -case 0x5E2D: -case 0x502E: -case 0x522E: -case 0x542E: -case 0x562E: -case 0x582E: -case 0x5A2E: -case 0x5C2E: -case 0x5E2E: -case 0x502F: -case 0x522F: -case 0x542F: -case 0x562F: -case 0x582F: -case 0x5A2F: -case 0x5C2F: -case 0x5E2F: - -// ADDQ -case 0x5028: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x5230: -case 0x5430: -case 0x5630: -case 0x5830: -case 0x5A30: -case 0x5C30: -case 0x5E30: -case 0x5031: -case 0x5231: -case 0x5431: -case 0x5631: -case 0x5831: -case 0x5A31: -case 0x5C31: -case 0x5E31: -case 0x5032: -case 0x5232: -case 0x5432: -case 0x5632: -case 0x5832: -case 0x5A32: -case 0x5C32: -case 0x5E32: -case 0x5033: -case 0x5233: -case 0x5433: -case 0x5633: -case 0x5833: -case 0x5A33: -case 0x5C33: -case 0x5E33: -case 0x5034: -case 0x5234: -case 0x5434: -case 0x5634: -case 0x5834: -case 0x5A34: -case 0x5C34: -case 0x5E34: -case 0x5035: -case 0x5235: -case 0x5435: -case 0x5635: -case 0x5835: -case 0x5A35: -case 0x5C35: -case 0x5E35: -case 0x5036: -case 0x5236: -case 0x5436: -case 0x5636: -case 0x5836: -case 0x5A36: -case 0x5C36: -case 0x5E36: -case 0x5037: -case 0x5237: -case 0x5437: -case 0x5637: -case 0x5837: -case 0x5A37: -case 0x5C37: -case 0x5E37: - -// ADDQ -case 0x5030: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x5238: -case 0x5438: -case 0x5638: -case 0x5838: -case 0x5A38: -case 0x5C38: -case 0x5E38: - -// ADDQ -case 0x5038: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x5239: -case 0x5439: -case 0x5639: -case 0x5839: -case 0x5A39: -case 0x5C39: -case 0x5E39: - -// ADDQ -case 0x5039: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x521F: -case 0x541F: -case 0x561F: -case 0x581F: -case 0x5A1F: -case 0x5C1F: -case 0x5E1F: - -// ADDQ -case 0x501F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x5227: -case 0x5427: -case 0x5627: -case 0x5827: -case 0x5A27: -case 0x5C27: -case 0x5E27: - -// ADDQ -case 0x5027: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x5240: -case 0x5440: -case 0x5640: -case 0x5840: -case 0x5A40: -case 0x5C40: -case 0x5E40: -case 0x5041: -case 0x5241: -case 0x5441: -case 0x5641: -case 0x5841: -case 0x5A41: -case 0x5C41: -case 0x5E41: -case 0x5042: -case 0x5242: -case 0x5442: -case 0x5642: -case 0x5842: -case 0x5A42: -case 0x5C42: -case 0x5E42: -case 0x5043: -case 0x5243: -case 0x5443: -case 0x5643: -case 0x5843: -case 0x5A43: -case 0x5C43: -case 0x5E43: -case 0x5044: -case 0x5244: -case 0x5444: -case 0x5644: -case 0x5844: -case 0x5A44: -case 0x5C44: -case 0x5E44: -case 0x5045: -case 0x5245: -case 0x5445: -case 0x5645: -case 0x5845: -case 0x5A45: -case 0x5C45: -case 0x5E45: -case 0x5046: -case 0x5246: -case 0x5446: -case 0x5646: -case 0x5846: -case 0x5A46: -case 0x5C46: -case 0x5E46: -case 0x5047: -case 0x5247: -case 0x5447: -case 0x5647: -case 0x5847: -case 0x5A47: -case 0x5C47: -case 0x5E47: - -// ADDQ -case 0x5040: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u16)CPU->D[(Opcode >> 0) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x5248: -case 0x5448: -case 0x5648: -case 0x5848: -case 0x5A48: -case 0x5C48: -case 0x5E48: -case 0x5049: -case 0x5249: -case 0x5449: -case 0x5649: -case 0x5849: -case 0x5A49: -case 0x5C49: -case 0x5E49: -case 0x504A: -case 0x524A: -case 0x544A: -case 0x564A: -case 0x584A: -case 0x5A4A: -case 0x5C4A: -case 0x5E4A: -case 0x504B: -case 0x524B: -case 0x544B: -case 0x564B: -case 0x584B: -case 0x5A4B: -case 0x5C4B: -case 0x5E4B: -case 0x504C: -case 0x524C: -case 0x544C: -case 0x564C: -case 0x584C: -case 0x5A4C: -case 0x5C4C: -case 0x5E4C: -case 0x504D: -case 0x524D: -case 0x544D: -case 0x564D: -case 0x584D: -case 0x5A4D: -case 0x5C4D: -case 0x5E4D: -case 0x504E: -case 0x524E: -case 0x544E: -case 0x564E: -case 0x584E: -case 0x5A4E: -case 0x5C4E: -case 0x5E4E: -case 0x504F: -case 0x524F: -case 0x544F: -case 0x564F: -case 0x584F: -case 0x5A4F: -case 0x5C4F: -case 0x5E4F: - -// ADDQ -case 0x5048: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u32)CPU->A[(Opcode >> 0) & 7]; - res = dst + src; - CPU->A[(Opcode >> 0) & 7] = res; -} -RET(8) -case 0x5250: -case 0x5450: -case 0x5650: -case 0x5850: -case 0x5A50: -case 0x5C50: -case 0x5E50: -case 0x5051: -case 0x5251: -case 0x5451: -case 0x5651: -case 0x5851: -case 0x5A51: -case 0x5C51: -case 0x5E51: -case 0x5052: -case 0x5252: -case 0x5452: -case 0x5652: -case 0x5852: -case 0x5A52: -case 0x5C52: -case 0x5E52: -case 0x5053: -case 0x5253: -case 0x5453: -case 0x5653: -case 0x5853: -case 0x5A53: -case 0x5C53: -case 0x5E53: -case 0x5054: -case 0x5254: -case 0x5454: -case 0x5654: -case 0x5854: -case 0x5A54: -case 0x5C54: -case 0x5E54: -case 0x5055: -case 0x5255: -case 0x5455: -case 0x5655: -case 0x5855: -case 0x5A55: -case 0x5C55: -case 0x5E55: -case 0x5056: -case 0x5256: -case 0x5456: -case 0x5656: -case 0x5856: -case 0x5A56: -case 0x5C56: -case 0x5E56: -case 0x5057: -case 0x5257: -case 0x5457: -case 0x5657: -case 0x5857: -case 0x5A57: -case 0x5C57: -case 0x5E57: - -// ADDQ -case 0x5050: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x5258: -case 0x5458: -case 0x5658: -case 0x5858: -case 0x5A58: -case 0x5C58: -case 0x5E58: -case 0x5059: -case 0x5259: -case 0x5459: -case 0x5659: -case 0x5859: -case 0x5A59: -case 0x5C59: -case 0x5E59: -case 0x505A: -case 0x525A: -case 0x545A: -case 0x565A: -case 0x585A: -case 0x5A5A: -case 0x5C5A: -case 0x5E5A: -case 0x505B: -case 0x525B: -case 0x545B: -case 0x565B: -case 0x585B: -case 0x5A5B: -case 0x5C5B: -case 0x5E5B: -case 0x505C: -case 0x525C: -case 0x545C: -case 0x565C: -case 0x585C: -case 0x5A5C: -case 0x5C5C: -case 0x5E5C: -case 0x505D: -case 0x525D: -case 0x545D: -case 0x565D: -case 0x585D: -case 0x5A5D: -case 0x5C5D: -case 0x5E5D: -case 0x505E: -case 0x525E: -case 0x545E: -case 0x565E: -case 0x585E: -case 0x5A5E: -case 0x5C5E: -case 0x5E5E: - -// ADDQ -case 0x5058: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x5260: -case 0x5460: -case 0x5660: -case 0x5860: -case 0x5A60: -case 0x5C60: -case 0x5E60: -case 0x5061: -case 0x5261: -case 0x5461: -case 0x5661: -case 0x5861: -case 0x5A61: -case 0x5C61: -case 0x5E61: -case 0x5062: -case 0x5262: -case 0x5462: -case 0x5662: -case 0x5862: -case 0x5A62: -case 0x5C62: -case 0x5E62: -case 0x5063: -case 0x5263: -case 0x5463: -case 0x5663: -case 0x5863: -case 0x5A63: -case 0x5C63: -case 0x5E63: -case 0x5064: -case 0x5264: -case 0x5464: -case 0x5664: -case 0x5864: -case 0x5A64: -case 0x5C64: -case 0x5E64: -case 0x5065: -case 0x5265: -case 0x5465: -case 0x5665: -case 0x5865: -case 0x5A65: -case 0x5C65: -case 0x5E65: -case 0x5066: -case 0x5266: -case 0x5466: -case 0x5666: -case 0x5866: -case 0x5A66: -case 0x5C66: -case 0x5E66: - -// ADDQ -case 0x5060: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x5268: -case 0x5468: -case 0x5668: -case 0x5868: -case 0x5A68: -case 0x5C68: -case 0x5E68: -case 0x5069: -case 0x5269: -case 0x5469: -case 0x5669: -case 0x5869: -case 0x5A69: -case 0x5C69: -case 0x5E69: -case 0x506A: -case 0x526A: -case 0x546A: -case 0x566A: -case 0x586A: -case 0x5A6A: -case 0x5C6A: -case 0x5E6A: -case 0x506B: -case 0x526B: -case 0x546B: -case 0x566B: -case 0x586B: -case 0x5A6B: -case 0x5C6B: -case 0x5E6B: -case 0x506C: -case 0x526C: -case 0x546C: -case 0x566C: -case 0x586C: -case 0x5A6C: -case 0x5C6C: -case 0x5E6C: -case 0x506D: -case 0x526D: -case 0x546D: -case 0x566D: -case 0x586D: -case 0x5A6D: -case 0x5C6D: -case 0x5E6D: -case 0x506E: -case 0x526E: -case 0x546E: -case 0x566E: -case 0x586E: -case 0x5A6E: -case 0x5C6E: -case 0x5E6E: -case 0x506F: -case 0x526F: -case 0x546F: -case 0x566F: -case 0x586F: -case 0x5A6F: -case 0x5C6F: -case 0x5E6F: - -// ADDQ -case 0x5068: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x5270: -case 0x5470: -case 0x5670: -case 0x5870: -case 0x5A70: -case 0x5C70: -case 0x5E70: -case 0x5071: -case 0x5271: -case 0x5471: -case 0x5671: -case 0x5871: -case 0x5A71: -case 0x5C71: -case 0x5E71: -case 0x5072: -case 0x5272: -case 0x5472: -case 0x5672: -case 0x5872: -case 0x5A72: -case 0x5C72: -case 0x5E72: -case 0x5073: -case 0x5273: -case 0x5473: -case 0x5673: -case 0x5873: -case 0x5A73: -case 0x5C73: -case 0x5E73: -case 0x5074: -case 0x5274: -case 0x5474: -case 0x5674: -case 0x5874: -case 0x5A74: -case 0x5C74: -case 0x5E74: -case 0x5075: -case 0x5275: -case 0x5475: -case 0x5675: -case 0x5875: -case 0x5A75: -case 0x5C75: -case 0x5E75: -case 0x5076: -case 0x5276: -case 0x5476: -case 0x5676: -case 0x5876: -case 0x5A76: -case 0x5C76: -case 0x5E76: -case 0x5077: -case 0x5277: -case 0x5477: -case 0x5677: -case 0x5877: -case 0x5A77: -case 0x5C77: -case 0x5E77: - -// ADDQ -case 0x5070: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x5278: -case 0x5478: -case 0x5678: -case 0x5878: -case 0x5A78: -case 0x5C78: -case 0x5E78: - -// ADDQ -case 0x5078: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x5279: -case 0x5479: -case 0x5679: -case 0x5879: -case 0x5A79: -case 0x5C79: -case 0x5E79: - -// ADDQ -case 0x5079: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x525F: -case 0x545F: -case 0x565F: -case 0x585F: -case 0x5A5F: -case 0x5C5F: -case 0x5E5F: - -// ADDQ -case 0x505F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x5267: -case 0x5467: -case 0x5667: -case 0x5867: -case 0x5A67: -case 0x5C67: -case 0x5E67: - -// ADDQ -case 0x5067: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x5280: -case 0x5480: -case 0x5680: -case 0x5880: -case 0x5A80: -case 0x5C80: -case 0x5E80: -case 0x5081: -case 0x5281: -case 0x5481: -case 0x5681: -case 0x5881: -case 0x5A81: -case 0x5C81: -case 0x5E81: -case 0x5082: -case 0x5282: -case 0x5482: -case 0x5682: -case 0x5882: -case 0x5A82: -case 0x5C82: -case 0x5E82: -case 0x5083: -case 0x5283: -case 0x5483: -case 0x5683: -case 0x5883: -case 0x5A83: -case 0x5C83: -case 0x5E83: -case 0x5084: -case 0x5284: -case 0x5484: -case 0x5684: -case 0x5884: -case 0x5A84: -case 0x5C84: -case 0x5E84: -case 0x5085: -case 0x5285: -case 0x5485: -case 0x5685: -case 0x5885: -case 0x5A85: -case 0x5C85: -case 0x5E85: -case 0x5086: -case 0x5286: -case 0x5486: -case 0x5686: -case 0x5886: -case 0x5A86: -case 0x5C86: -case 0x5E86: -case 0x5087: -case 0x5287: -case 0x5487: -case 0x5687: -case 0x5887: -case 0x5A87: -case 0x5C87: -case 0x5E87: - -// ADDQ -case 0x5080: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u32)CPU->D[(Opcode >> 0) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x5288: -case 0x5488: -case 0x5688: -case 0x5888: -case 0x5A88: -case 0x5C88: -case 0x5E88: -case 0x5089: -case 0x5289: -case 0x5489: -case 0x5689: -case 0x5889: -case 0x5A89: -case 0x5C89: -case 0x5E89: -case 0x508A: -case 0x528A: -case 0x548A: -case 0x568A: -case 0x588A: -case 0x5A8A: -case 0x5C8A: -case 0x5E8A: -case 0x508B: -case 0x528B: -case 0x548B: -case 0x568B: -case 0x588B: -case 0x5A8B: -case 0x5C8B: -case 0x5E8B: -case 0x508C: -case 0x528C: -case 0x548C: -case 0x568C: -case 0x588C: -case 0x5A8C: -case 0x5C8C: -case 0x5E8C: -case 0x508D: -case 0x528D: -case 0x548D: -case 0x568D: -case 0x588D: -case 0x5A8D: -case 0x5C8D: -case 0x5E8D: -case 0x508E: -case 0x528E: -case 0x548E: -case 0x568E: -case 0x588E: -case 0x5A8E: -case 0x5C8E: -case 0x5E8E: -case 0x508F: -case 0x528F: -case 0x548F: -case 0x568F: -case 0x588F: -case 0x5A8F: -case 0x5C8F: -case 0x5E8F: - -// ADDQ -case 0x5088: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u32)CPU->A[(Opcode >> 0) & 7]; - res = dst + src; - CPU->A[(Opcode >> 0) & 7] = res; -} -RET(8) -case 0x5290: -case 0x5490: -case 0x5690: -case 0x5890: -case 0x5A90: -case 0x5C90: -case 0x5E90: -case 0x5091: -case 0x5291: -case 0x5491: -case 0x5691: -case 0x5891: -case 0x5A91: -case 0x5C91: -case 0x5E91: -case 0x5092: -case 0x5292: -case 0x5492: -case 0x5692: -case 0x5892: -case 0x5A92: -case 0x5C92: -case 0x5E92: -case 0x5093: -case 0x5293: -case 0x5493: -case 0x5693: -case 0x5893: -case 0x5A93: -case 0x5C93: -case 0x5E93: -case 0x5094: -case 0x5294: -case 0x5494: -case 0x5694: -case 0x5894: -case 0x5A94: -case 0x5C94: -case 0x5E94: -case 0x5095: -case 0x5295: -case 0x5495: -case 0x5695: -case 0x5895: -case 0x5A95: -case 0x5C95: -case 0x5E95: -case 0x5096: -case 0x5296: -case 0x5496: -case 0x5696: -case 0x5896: -case 0x5A96: -case 0x5C96: -case 0x5E96: -case 0x5097: -case 0x5297: -case 0x5497: -case 0x5697: -case 0x5897: -case 0x5A97: -case 0x5C97: -case 0x5E97: - -// ADDQ -case 0x5090: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x5298: -case 0x5498: -case 0x5698: -case 0x5898: -case 0x5A98: -case 0x5C98: -case 0x5E98: -case 0x5099: -case 0x5299: -case 0x5499: -case 0x5699: -case 0x5899: -case 0x5A99: -case 0x5C99: -case 0x5E99: -case 0x509A: -case 0x529A: -case 0x549A: -case 0x569A: -case 0x589A: -case 0x5A9A: -case 0x5C9A: -case 0x5E9A: -case 0x509B: -case 0x529B: -case 0x549B: -case 0x569B: -case 0x589B: -case 0x5A9B: -case 0x5C9B: -case 0x5E9B: -case 0x509C: -case 0x529C: -case 0x549C: -case 0x569C: -case 0x589C: -case 0x5A9C: -case 0x5C9C: -case 0x5E9C: -case 0x509D: -case 0x529D: -case 0x549D: -case 0x569D: -case 0x589D: -case 0x5A9D: -case 0x5C9D: -case 0x5E9D: -case 0x509E: -case 0x529E: -case 0x549E: -case 0x569E: -case 0x589E: -case 0x5A9E: -case 0x5C9E: -case 0x5E9E: - -// ADDQ -case 0x5098: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x52A0: -case 0x54A0: -case 0x56A0: -case 0x58A0: -case 0x5AA0: -case 0x5CA0: -case 0x5EA0: -case 0x50A1: -case 0x52A1: -case 0x54A1: -case 0x56A1: -case 0x58A1: -case 0x5AA1: -case 0x5CA1: -case 0x5EA1: -case 0x50A2: -case 0x52A2: -case 0x54A2: -case 0x56A2: -case 0x58A2: -case 0x5AA2: -case 0x5CA2: -case 0x5EA2: -case 0x50A3: -case 0x52A3: -case 0x54A3: -case 0x56A3: -case 0x58A3: -case 0x5AA3: -case 0x5CA3: -case 0x5EA3: -case 0x50A4: -case 0x52A4: -case 0x54A4: -case 0x56A4: -case 0x58A4: -case 0x5AA4: -case 0x5CA4: -case 0x5EA4: -case 0x50A5: -case 0x52A5: -case 0x54A5: -case 0x56A5: -case 0x58A5: -case 0x5AA5: -case 0x5CA5: -case 0x5EA5: -case 0x50A6: -case 0x52A6: -case 0x54A6: -case 0x56A6: -case 0x58A6: -case 0x5AA6: -case 0x5CA6: -case 0x5EA6: - -// ADDQ -case 0x50A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x52A8: -case 0x54A8: -case 0x56A8: -case 0x58A8: -case 0x5AA8: -case 0x5CA8: -case 0x5EA8: -case 0x50A9: -case 0x52A9: -case 0x54A9: -case 0x56A9: -case 0x58A9: -case 0x5AA9: -case 0x5CA9: -case 0x5EA9: -case 0x50AA: -case 0x52AA: -case 0x54AA: -case 0x56AA: -case 0x58AA: -case 0x5AAA: -case 0x5CAA: -case 0x5EAA: -case 0x50AB: -case 0x52AB: -case 0x54AB: -case 0x56AB: -case 0x58AB: -case 0x5AAB: -case 0x5CAB: -case 0x5EAB: -case 0x50AC: -case 0x52AC: -case 0x54AC: -case 0x56AC: -case 0x58AC: -case 0x5AAC: -case 0x5CAC: -case 0x5EAC: -case 0x50AD: -case 0x52AD: -case 0x54AD: -case 0x56AD: -case 0x58AD: -case 0x5AAD: -case 0x5CAD: -case 0x5EAD: -case 0x50AE: -case 0x52AE: -case 0x54AE: -case 0x56AE: -case 0x58AE: -case 0x5AAE: -case 0x5CAE: -case 0x5EAE: -case 0x50AF: -case 0x52AF: -case 0x54AF: -case 0x56AF: -case 0x58AF: -case 0x5AAF: -case 0x5CAF: -case 0x5EAF: - -// ADDQ -case 0x50A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x52B0: -case 0x54B0: -case 0x56B0: -case 0x58B0: -case 0x5AB0: -case 0x5CB0: -case 0x5EB0: -case 0x50B1: -case 0x52B1: -case 0x54B1: -case 0x56B1: -case 0x58B1: -case 0x5AB1: -case 0x5CB1: -case 0x5EB1: -case 0x50B2: -case 0x52B2: -case 0x54B2: -case 0x56B2: -case 0x58B2: -case 0x5AB2: -case 0x5CB2: -case 0x5EB2: -case 0x50B3: -case 0x52B3: -case 0x54B3: -case 0x56B3: -case 0x58B3: -case 0x5AB3: -case 0x5CB3: -case 0x5EB3: -case 0x50B4: -case 0x52B4: -case 0x54B4: -case 0x56B4: -case 0x58B4: -case 0x5AB4: -case 0x5CB4: -case 0x5EB4: -case 0x50B5: -case 0x52B5: -case 0x54B5: -case 0x56B5: -case 0x58B5: -case 0x5AB5: -case 0x5CB5: -case 0x5EB5: -case 0x50B6: -case 0x52B6: -case 0x54B6: -case 0x56B6: -case 0x58B6: -case 0x5AB6: -case 0x5CB6: -case 0x5EB6: -case 0x50B7: -case 0x52B7: -case 0x54B7: -case 0x56B7: -case 0x58B7: -case 0x5AB7: -case 0x5CB7: -case 0x5EB7: - -// ADDQ -case 0x50B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x52B8: -case 0x54B8: -case 0x56B8: -case 0x58B8: -case 0x5AB8: -case 0x5CB8: -case 0x5EB8: - -// ADDQ -case 0x50B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x52B9: -case 0x54B9: -case 0x56B9: -case 0x58B9: -case 0x5AB9: -case 0x5CB9: -case 0x5EB9: - -// ADDQ -case 0x50B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x529F: -case 0x549F: -case 0x569F: -case 0x589F: -case 0x5A9F: -case 0x5C9F: -case 0x5E9F: - -// ADDQ -case 0x509F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x52A7: -case 0x54A7: -case 0x56A7: -case 0x58A7: -case 0x5AA7: -case 0x5CA7: -case 0x5EA7: - -// ADDQ -case 0x50A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x5300: -case 0x5500: -case 0x5700: -case 0x5900: -case 0x5B00: -case 0x5D00: -case 0x5F00: -case 0x5101: -case 0x5301: -case 0x5501: -case 0x5701: -case 0x5901: -case 0x5B01: -case 0x5D01: -case 0x5F01: -case 0x5102: -case 0x5302: -case 0x5502: -case 0x5702: -case 0x5902: -case 0x5B02: -case 0x5D02: -case 0x5F02: -case 0x5103: -case 0x5303: -case 0x5503: -case 0x5703: -case 0x5903: -case 0x5B03: -case 0x5D03: -case 0x5F03: -case 0x5104: -case 0x5304: -case 0x5504: -case 0x5704: -case 0x5904: -case 0x5B04: -case 0x5D04: -case 0x5F04: -case 0x5105: -case 0x5305: -case 0x5505: -case 0x5705: -case 0x5905: -case 0x5B05: -case 0x5D05: -case 0x5F05: -case 0x5106: -case 0x5306: -case 0x5506: -case 0x5706: -case 0x5906: -case 0x5B06: -case 0x5D06: -case 0x5F06: -case 0x5107: -case 0x5307: -case 0x5507: -case 0x5707: -case 0x5907: -case 0x5B07: -case 0x5D07: -case 0x5F07: - -// SUBQ -case 0x5100: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u8)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x5310: -case 0x5510: -case 0x5710: -case 0x5910: -case 0x5B10: -case 0x5D10: -case 0x5F10: -case 0x5111: -case 0x5311: -case 0x5511: -case 0x5711: -case 0x5911: -case 0x5B11: -case 0x5D11: -case 0x5F11: -case 0x5112: -case 0x5312: -case 0x5512: -case 0x5712: -case 0x5912: -case 0x5B12: -case 0x5D12: -case 0x5F12: -case 0x5113: -case 0x5313: -case 0x5513: -case 0x5713: -case 0x5913: -case 0x5B13: -case 0x5D13: -case 0x5F13: -case 0x5114: -case 0x5314: -case 0x5514: -case 0x5714: -case 0x5914: -case 0x5B14: -case 0x5D14: -case 0x5F14: -case 0x5115: -case 0x5315: -case 0x5515: -case 0x5715: -case 0x5915: -case 0x5B15: -case 0x5D15: -case 0x5F15: -case 0x5116: -case 0x5316: -case 0x5516: -case 0x5716: -case 0x5916: -case 0x5B16: -case 0x5D16: -case 0x5F16: -case 0x5117: -case 0x5317: -case 0x5517: -case 0x5717: -case 0x5917: -case 0x5B17: -case 0x5D17: -case 0x5F17: - -// SUBQ -case 0x5110: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x5318: -case 0x5518: -case 0x5718: -case 0x5918: -case 0x5B18: -case 0x5D18: -case 0x5F18: -case 0x5119: -case 0x5319: -case 0x5519: -case 0x5719: -case 0x5919: -case 0x5B19: -case 0x5D19: -case 0x5F19: -case 0x511A: -case 0x531A: -case 0x551A: -case 0x571A: -case 0x591A: -case 0x5B1A: -case 0x5D1A: -case 0x5F1A: -case 0x511B: -case 0x531B: -case 0x551B: -case 0x571B: -case 0x591B: -case 0x5B1B: -case 0x5D1B: -case 0x5F1B: -case 0x511C: -case 0x531C: -case 0x551C: -case 0x571C: -case 0x591C: -case 0x5B1C: -case 0x5D1C: -case 0x5F1C: -case 0x511D: -case 0x531D: -case 0x551D: -case 0x571D: -case 0x591D: -case 0x5B1D: -case 0x5D1D: -case 0x5F1D: -case 0x511E: -case 0x531E: -case 0x551E: -case 0x571E: -case 0x591E: -case 0x5B1E: -case 0x5D1E: -case 0x5F1E: - -// SUBQ -case 0x5118: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x5320: -case 0x5520: -case 0x5720: -case 0x5920: -case 0x5B20: -case 0x5D20: -case 0x5F20: -case 0x5121: -case 0x5321: -case 0x5521: -case 0x5721: -case 0x5921: -case 0x5B21: -case 0x5D21: -case 0x5F21: -case 0x5122: -case 0x5322: -case 0x5522: -case 0x5722: -case 0x5922: -case 0x5B22: -case 0x5D22: -case 0x5F22: -case 0x5123: -case 0x5323: -case 0x5523: -case 0x5723: -case 0x5923: -case 0x5B23: -case 0x5D23: -case 0x5F23: -case 0x5124: -case 0x5324: -case 0x5524: -case 0x5724: -case 0x5924: -case 0x5B24: -case 0x5D24: -case 0x5F24: -case 0x5125: -case 0x5325: -case 0x5525: -case 0x5725: -case 0x5925: -case 0x5B25: -case 0x5D25: -case 0x5F25: -case 0x5126: -case 0x5326: -case 0x5526: -case 0x5726: -case 0x5926: -case 0x5B26: -case 0x5D26: -case 0x5F26: - -// SUBQ -case 0x5120: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x5328: -case 0x5528: -case 0x5728: -case 0x5928: -case 0x5B28: -case 0x5D28: -case 0x5F28: -case 0x5129: -case 0x5329: -case 0x5529: -case 0x5729: -case 0x5929: -case 0x5B29: -case 0x5D29: -case 0x5F29: -case 0x512A: -case 0x532A: -case 0x552A: -case 0x572A: -case 0x592A: -case 0x5B2A: -case 0x5D2A: -case 0x5F2A: -case 0x512B: -case 0x532B: -case 0x552B: -case 0x572B: -case 0x592B: -case 0x5B2B: -case 0x5D2B: -case 0x5F2B: -case 0x512C: -case 0x532C: -case 0x552C: -case 0x572C: -case 0x592C: -case 0x5B2C: -case 0x5D2C: -case 0x5F2C: -case 0x512D: -case 0x532D: -case 0x552D: -case 0x572D: -case 0x592D: -case 0x5B2D: -case 0x5D2D: -case 0x5F2D: -case 0x512E: -case 0x532E: -case 0x552E: -case 0x572E: -case 0x592E: -case 0x5B2E: -case 0x5D2E: -case 0x5F2E: -case 0x512F: -case 0x532F: -case 0x552F: -case 0x572F: -case 0x592F: -case 0x5B2F: -case 0x5D2F: -case 0x5F2F: - -// SUBQ -case 0x5128: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x5330: -case 0x5530: -case 0x5730: -case 0x5930: -case 0x5B30: -case 0x5D30: -case 0x5F30: -case 0x5131: -case 0x5331: -case 0x5531: -case 0x5731: -case 0x5931: -case 0x5B31: -case 0x5D31: -case 0x5F31: -case 0x5132: -case 0x5332: -case 0x5532: -case 0x5732: -case 0x5932: -case 0x5B32: -case 0x5D32: -case 0x5F32: -case 0x5133: -case 0x5333: -case 0x5533: -case 0x5733: -case 0x5933: -case 0x5B33: -case 0x5D33: -case 0x5F33: -case 0x5134: -case 0x5334: -case 0x5534: -case 0x5734: -case 0x5934: -case 0x5B34: -case 0x5D34: -case 0x5F34: -case 0x5135: -case 0x5335: -case 0x5535: -case 0x5735: -case 0x5935: -case 0x5B35: -case 0x5D35: -case 0x5F35: -case 0x5136: -case 0x5336: -case 0x5536: -case 0x5736: -case 0x5936: -case 0x5B36: -case 0x5D36: -case 0x5F36: -case 0x5137: -case 0x5337: -case 0x5537: -case 0x5737: -case 0x5937: -case 0x5B37: -case 0x5D37: -case 0x5F37: - -// SUBQ -case 0x5130: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x5338: -case 0x5538: -case 0x5738: -case 0x5938: -case 0x5B38: -case 0x5D38: -case 0x5F38: - -// SUBQ -case 0x5138: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x5339: -case 0x5539: -case 0x5739: -case 0x5939: -case 0x5B39: -case 0x5D39: -case 0x5F39: - -// SUBQ -case 0x5139: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x531F: -case 0x551F: -case 0x571F: -case 0x591F: -case 0x5B1F: -case 0x5D1F: -case 0x5F1F: - -// SUBQ -case 0x511F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x5327: -case 0x5527: -case 0x5727: -case 0x5927: -case 0x5B27: -case 0x5D27: -case 0x5F27: - -// SUBQ -case 0x5127: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x5340: -case 0x5540: -case 0x5740: -case 0x5940: -case 0x5B40: -case 0x5D40: -case 0x5F40: -case 0x5141: -case 0x5341: -case 0x5541: -case 0x5741: -case 0x5941: -case 0x5B41: -case 0x5D41: -case 0x5F41: -case 0x5142: -case 0x5342: -case 0x5542: -case 0x5742: -case 0x5942: -case 0x5B42: -case 0x5D42: -case 0x5F42: -case 0x5143: -case 0x5343: -case 0x5543: -case 0x5743: -case 0x5943: -case 0x5B43: -case 0x5D43: -case 0x5F43: -case 0x5144: -case 0x5344: -case 0x5544: -case 0x5744: -case 0x5944: -case 0x5B44: -case 0x5D44: -case 0x5F44: -case 0x5145: -case 0x5345: -case 0x5545: -case 0x5745: -case 0x5945: -case 0x5B45: -case 0x5D45: -case 0x5F45: -case 0x5146: -case 0x5346: -case 0x5546: -case 0x5746: -case 0x5946: -case 0x5B46: -case 0x5D46: -case 0x5F46: -case 0x5147: -case 0x5347: -case 0x5547: -case 0x5747: -case 0x5947: -case 0x5B47: -case 0x5D47: -case 0x5F47: - -// SUBQ -case 0x5140: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u16)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0x5348: -case 0x5548: -case 0x5748: -case 0x5948: -case 0x5B48: -case 0x5D48: -case 0x5F48: -case 0x5149: -case 0x5349: -case 0x5549: -case 0x5749: -case 0x5949: -case 0x5B49: -case 0x5D49: -case 0x5F49: -case 0x514A: -case 0x534A: -case 0x554A: -case 0x574A: -case 0x594A: -case 0x5B4A: -case 0x5D4A: -case 0x5F4A: -case 0x514B: -case 0x534B: -case 0x554B: -case 0x574B: -case 0x594B: -case 0x5B4B: -case 0x5D4B: -case 0x5F4B: -case 0x514C: -case 0x534C: -case 0x554C: -case 0x574C: -case 0x594C: -case 0x5B4C: -case 0x5D4C: -case 0x5F4C: -case 0x514D: -case 0x534D: -case 0x554D: -case 0x574D: -case 0x594D: -case 0x5B4D: -case 0x5D4D: -case 0x5F4D: -case 0x514E: -case 0x534E: -case 0x554E: -case 0x574E: -case 0x594E: -case 0x5B4E: -case 0x5D4E: -case 0x5F4E: -case 0x514F: -case 0x534F: -case 0x554F: -case 0x574F: -case 0x594F: -case 0x5B4F: -case 0x5D4F: -case 0x5F4F: - -// SUBQ -case 0x5148: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u32)CPU->A[(Opcode >> 0) & 7]; - res = dst - src; - CPU->A[(Opcode >> 0) & 7] = res; -} -RET(8) -case 0x5350: -case 0x5550: -case 0x5750: -case 0x5950: -case 0x5B50: -case 0x5D50: -case 0x5F50: -case 0x5151: -case 0x5351: -case 0x5551: -case 0x5751: -case 0x5951: -case 0x5B51: -case 0x5D51: -case 0x5F51: -case 0x5152: -case 0x5352: -case 0x5552: -case 0x5752: -case 0x5952: -case 0x5B52: -case 0x5D52: -case 0x5F52: -case 0x5153: -case 0x5353: -case 0x5553: -case 0x5753: -case 0x5953: -case 0x5B53: -case 0x5D53: -case 0x5F53: -case 0x5154: -case 0x5354: -case 0x5554: -case 0x5754: -case 0x5954: -case 0x5B54: -case 0x5D54: -case 0x5F54: -case 0x5155: -case 0x5355: -case 0x5555: -case 0x5755: -case 0x5955: -case 0x5B55: -case 0x5D55: -case 0x5F55: -case 0x5156: -case 0x5356: -case 0x5556: -case 0x5756: -case 0x5956: -case 0x5B56: -case 0x5D56: -case 0x5F56: -case 0x5157: -case 0x5357: -case 0x5557: -case 0x5757: -case 0x5957: -case 0x5B57: -case 0x5D57: -case 0x5F57: - -// SUBQ -case 0x5150: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x5358: -case 0x5558: -case 0x5758: -case 0x5958: -case 0x5B58: -case 0x5D58: -case 0x5F58: -case 0x5159: -case 0x5359: -case 0x5559: -case 0x5759: -case 0x5959: -case 0x5B59: -case 0x5D59: -case 0x5F59: -case 0x515A: -case 0x535A: -case 0x555A: -case 0x575A: -case 0x595A: -case 0x5B5A: -case 0x5D5A: -case 0x5F5A: -case 0x515B: -case 0x535B: -case 0x555B: -case 0x575B: -case 0x595B: -case 0x5B5B: -case 0x5D5B: -case 0x5F5B: -case 0x515C: -case 0x535C: -case 0x555C: -case 0x575C: -case 0x595C: -case 0x5B5C: -case 0x5D5C: -case 0x5F5C: -case 0x515D: -case 0x535D: -case 0x555D: -case 0x575D: -case 0x595D: -case 0x5B5D: -case 0x5D5D: -case 0x5F5D: -case 0x515E: -case 0x535E: -case 0x555E: -case 0x575E: -case 0x595E: -case 0x5B5E: -case 0x5D5E: -case 0x5F5E: - -// SUBQ -case 0x5158: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x5360: -case 0x5560: -case 0x5760: -case 0x5960: -case 0x5B60: -case 0x5D60: -case 0x5F60: -case 0x5161: -case 0x5361: -case 0x5561: -case 0x5761: -case 0x5961: -case 0x5B61: -case 0x5D61: -case 0x5F61: -case 0x5162: -case 0x5362: -case 0x5562: -case 0x5762: -case 0x5962: -case 0x5B62: -case 0x5D62: -case 0x5F62: -case 0x5163: -case 0x5363: -case 0x5563: -case 0x5763: -case 0x5963: -case 0x5B63: -case 0x5D63: -case 0x5F63: -case 0x5164: -case 0x5364: -case 0x5564: -case 0x5764: -case 0x5964: -case 0x5B64: -case 0x5D64: -case 0x5F64: -case 0x5165: -case 0x5365: -case 0x5565: -case 0x5765: -case 0x5965: -case 0x5B65: -case 0x5D65: -case 0x5F65: -case 0x5166: -case 0x5366: -case 0x5566: -case 0x5766: -case 0x5966: -case 0x5B66: -case 0x5D66: -case 0x5F66: - -// SUBQ -case 0x5160: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x5368: -case 0x5568: -case 0x5768: -case 0x5968: -case 0x5B68: -case 0x5D68: -case 0x5F68: -case 0x5169: -case 0x5369: -case 0x5569: -case 0x5769: -case 0x5969: -case 0x5B69: -case 0x5D69: -case 0x5F69: -case 0x516A: -case 0x536A: -case 0x556A: -case 0x576A: -case 0x596A: -case 0x5B6A: -case 0x5D6A: -case 0x5F6A: -case 0x516B: -case 0x536B: -case 0x556B: -case 0x576B: -case 0x596B: -case 0x5B6B: -case 0x5D6B: -case 0x5F6B: -case 0x516C: -case 0x536C: -case 0x556C: -case 0x576C: -case 0x596C: -case 0x5B6C: -case 0x5D6C: -case 0x5F6C: -case 0x516D: -case 0x536D: -case 0x556D: -case 0x576D: -case 0x596D: -case 0x5B6D: -case 0x5D6D: -case 0x5F6D: -case 0x516E: -case 0x536E: -case 0x556E: -case 0x576E: -case 0x596E: -case 0x5B6E: -case 0x5D6E: -case 0x5F6E: -case 0x516F: -case 0x536F: -case 0x556F: -case 0x576F: -case 0x596F: -case 0x5B6F: -case 0x5D6F: -case 0x5F6F: - -// SUBQ -case 0x5168: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x5370: -case 0x5570: -case 0x5770: -case 0x5970: -case 0x5B70: -case 0x5D70: -case 0x5F70: -case 0x5171: -case 0x5371: -case 0x5571: -case 0x5771: -case 0x5971: -case 0x5B71: -case 0x5D71: -case 0x5F71: -case 0x5172: -case 0x5372: -case 0x5572: -case 0x5772: -case 0x5972: -case 0x5B72: -case 0x5D72: -case 0x5F72: -case 0x5173: -case 0x5373: -case 0x5573: -case 0x5773: -case 0x5973: -case 0x5B73: -case 0x5D73: -case 0x5F73: -case 0x5174: -case 0x5374: -case 0x5574: -case 0x5774: -case 0x5974: -case 0x5B74: -case 0x5D74: -case 0x5F74: -case 0x5175: -case 0x5375: -case 0x5575: -case 0x5775: -case 0x5975: -case 0x5B75: -case 0x5D75: -case 0x5F75: -case 0x5176: -case 0x5376: -case 0x5576: -case 0x5776: -case 0x5976: -case 0x5B76: -case 0x5D76: -case 0x5F76: -case 0x5177: -case 0x5377: -case 0x5577: -case 0x5777: -case 0x5977: -case 0x5B77: -case 0x5D77: -case 0x5F77: - -// SUBQ -case 0x5170: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x5378: -case 0x5578: -case 0x5778: -case 0x5978: -case 0x5B78: -case 0x5D78: -case 0x5F78: - -// SUBQ -case 0x5178: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x5379: -case 0x5579: -case 0x5779: -case 0x5979: -case 0x5B79: -case 0x5D79: -case 0x5F79: - -// SUBQ -case 0x5179: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x535F: -case 0x555F: -case 0x575F: -case 0x595F: -case 0x5B5F: -case 0x5D5F: -case 0x5F5F: - -// SUBQ -case 0x515F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x5367: -case 0x5567: -case 0x5767: -case 0x5967: -case 0x5B67: -case 0x5D67: -case 0x5F67: - -// SUBQ -case 0x5167: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x5380: -case 0x5580: -case 0x5780: -case 0x5980: -case 0x5B80: -case 0x5D80: -case 0x5F80: -case 0x5181: -case 0x5381: -case 0x5581: -case 0x5781: -case 0x5981: -case 0x5B81: -case 0x5D81: -case 0x5F81: -case 0x5182: -case 0x5382: -case 0x5582: -case 0x5782: -case 0x5982: -case 0x5B82: -case 0x5D82: -case 0x5F82: -case 0x5183: -case 0x5383: -case 0x5583: -case 0x5783: -case 0x5983: -case 0x5B83: -case 0x5D83: -case 0x5F83: -case 0x5184: -case 0x5384: -case 0x5584: -case 0x5784: -case 0x5984: -case 0x5B84: -case 0x5D84: -case 0x5F84: -case 0x5185: -case 0x5385: -case 0x5585: -case 0x5785: -case 0x5985: -case 0x5B85: -case 0x5D85: -case 0x5F85: -case 0x5186: -case 0x5386: -case 0x5586: -case 0x5786: -case 0x5986: -case 0x5B86: -case 0x5D86: -case 0x5F86: -case 0x5187: -case 0x5387: -case 0x5587: -case 0x5787: -case 0x5987: -case 0x5B87: -case 0x5D87: -case 0x5F87: - -// SUBQ -case 0x5180: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u32)CPU->D[(Opcode >> 0) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0x5388: -case 0x5588: -case 0x5788: -case 0x5988: -case 0x5B88: -case 0x5D88: -case 0x5F88: -case 0x5189: -case 0x5389: -case 0x5589: -case 0x5789: -case 0x5989: -case 0x5B89: -case 0x5D89: -case 0x5F89: -case 0x518A: -case 0x538A: -case 0x558A: -case 0x578A: -case 0x598A: -case 0x5B8A: -case 0x5D8A: -case 0x5F8A: -case 0x518B: -case 0x538B: -case 0x558B: -case 0x578B: -case 0x598B: -case 0x5B8B: -case 0x5D8B: -case 0x5F8B: -case 0x518C: -case 0x538C: -case 0x558C: -case 0x578C: -case 0x598C: -case 0x5B8C: -case 0x5D8C: -case 0x5F8C: -case 0x518D: -case 0x538D: -case 0x558D: -case 0x578D: -case 0x598D: -case 0x5B8D: -case 0x5D8D: -case 0x5F8D: -case 0x518E: -case 0x538E: -case 0x558E: -case 0x578E: -case 0x598E: -case 0x5B8E: -case 0x5D8E: -case 0x5F8E: -case 0x518F: -case 0x538F: -case 0x558F: -case 0x578F: -case 0x598F: -case 0x5B8F: -case 0x5D8F: -case 0x5F8F: - -// SUBQ -case 0x5188: -{ - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - dst = (u32)CPU->A[(Opcode >> 0) & 7]; - res = dst - src; - CPU->A[(Opcode >> 0) & 7] = res; -} -RET(8) -case 0x5390: -case 0x5590: -case 0x5790: -case 0x5990: -case 0x5B90: -case 0x5D90: -case 0x5F90: -case 0x5191: -case 0x5391: -case 0x5591: -case 0x5791: -case 0x5991: -case 0x5B91: -case 0x5D91: -case 0x5F91: -case 0x5192: -case 0x5392: -case 0x5592: -case 0x5792: -case 0x5992: -case 0x5B92: -case 0x5D92: -case 0x5F92: -case 0x5193: -case 0x5393: -case 0x5593: -case 0x5793: -case 0x5993: -case 0x5B93: -case 0x5D93: -case 0x5F93: -case 0x5194: -case 0x5394: -case 0x5594: -case 0x5794: -case 0x5994: -case 0x5B94: -case 0x5D94: -case 0x5F94: -case 0x5195: -case 0x5395: -case 0x5595: -case 0x5795: -case 0x5995: -case 0x5B95: -case 0x5D95: -case 0x5F95: -case 0x5196: -case 0x5396: -case 0x5596: -case 0x5796: -case 0x5996: -case 0x5B96: -case 0x5D96: -case 0x5F96: -case 0x5197: -case 0x5397: -case 0x5597: -case 0x5797: -case 0x5997: -case 0x5B97: -case 0x5D97: -case 0x5F97: - -// SUBQ -case 0x5190: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x5398: -case 0x5598: -case 0x5798: -case 0x5998: -case 0x5B98: -case 0x5D98: -case 0x5F98: -case 0x5199: -case 0x5399: -case 0x5599: -case 0x5799: -case 0x5999: -case 0x5B99: -case 0x5D99: -case 0x5F99: -case 0x519A: -case 0x539A: -case 0x559A: -case 0x579A: -case 0x599A: -case 0x5B9A: -case 0x5D9A: -case 0x5F9A: -case 0x519B: -case 0x539B: -case 0x559B: -case 0x579B: -case 0x599B: -case 0x5B9B: -case 0x5D9B: -case 0x5F9B: -case 0x519C: -case 0x539C: -case 0x559C: -case 0x579C: -case 0x599C: -case 0x5B9C: -case 0x5D9C: -case 0x5F9C: -case 0x519D: -case 0x539D: -case 0x559D: -case 0x579D: -case 0x599D: -case 0x5B9D: -case 0x5D9D: -case 0x5F9D: -case 0x519E: -case 0x539E: -case 0x559E: -case 0x579E: -case 0x599E: -case 0x5B9E: -case 0x5D9E: -case 0x5F9E: - -// SUBQ -case 0x5198: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x53A0: -case 0x55A0: -case 0x57A0: -case 0x59A0: -case 0x5BA0: -case 0x5DA0: -case 0x5FA0: -case 0x51A1: -case 0x53A1: -case 0x55A1: -case 0x57A1: -case 0x59A1: -case 0x5BA1: -case 0x5DA1: -case 0x5FA1: -case 0x51A2: -case 0x53A2: -case 0x55A2: -case 0x57A2: -case 0x59A2: -case 0x5BA2: -case 0x5DA2: -case 0x5FA2: -case 0x51A3: -case 0x53A3: -case 0x55A3: -case 0x57A3: -case 0x59A3: -case 0x5BA3: -case 0x5DA3: -case 0x5FA3: -case 0x51A4: -case 0x53A4: -case 0x55A4: -case 0x57A4: -case 0x59A4: -case 0x5BA4: -case 0x5DA4: -case 0x5FA4: -case 0x51A5: -case 0x53A5: -case 0x55A5: -case 0x57A5: -case 0x59A5: -case 0x5BA5: -case 0x5DA5: -case 0x5FA5: -case 0x51A6: -case 0x53A6: -case 0x55A6: -case 0x57A6: -case 0x59A6: -case 0x5BA6: -case 0x5DA6: -case 0x5FA6: - -// SUBQ -case 0x51A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x53A8: -case 0x55A8: -case 0x57A8: -case 0x59A8: -case 0x5BA8: -case 0x5DA8: -case 0x5FA8: -case 0x51A9: -case 0x53A9: -case 0x55A9: -case 0x57A9: -case 0x59A9: -case 0x5BA9: -case 0x5DA9: -case 0x5FA9: -case 0x51AA: -case 0x53AA: -case 0x55AA: -case 0x57AA: -case 0x59AA: -case 0x5BAA: -case 0x5DAA: -case 0x5FAA: -case 0x51AB: -case 0x53AB: -case 0x55AB: -case 0x57AB: -case 0x59AB: -case 0x5BAB: -case 0x5DAB: -case 0x5FAB: -case 0x51AC: -case 0x53AC: -case 0x55AC: -case 0x57AC: -case 0x59AC: -case 0x5BAC: -case 0x5DAC: -case 0x5FAC: -case 0x51AD: -case 0x53AD: -case 0x55AD: -case 0x57AD: -case 0x59AD: -case 0x5BAD: -case 0x5DAD: -case 0x5FAD: -case 0x51AE: -case 0x53AE: -case 0x55AE: -case 0x57AE: -case 0x59AE: -case 0x5BAE: -case 0x5DAE: -case 0x5FAE: -case 0x51AF: -case 0x53AF: -case 0x55AF: -case 0x57AF: -case 0x59AF: -case 0x5BAF: -case 0x5DAF: -case 0x5FAF: - -// SUBQ -case 0x51A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x53B0: -case 0x55B0: -case 0x57B0: -case 0x59B0: -case 0x5BB0: -case 0x5DB0: -case 0x5FB0: -case 0x51B1: -case 0x53B1: -case 0x55B1: -case 0x57B1: -case 0x59B1: -case 0x5BB1: -case 0x5DB1: -case 0x5FB1: -case 0x51B2: -case 0x53B2: -case 0x55B2: -case 0x57B2: -case 0x59B2: -case 0x5BB2: -case 0x5DB2: -case 0x5FB2: -case 0x51B3: -case 0x53B3: -case 0x55B3: -case 0x57B3: -case 0x59B3: -case 0x5BB3: -case 0x5DB3: -case 0x5FB3: -case 0x51B4: -case 0x53B4: -case 0x55B4: -case 0x57B4: -case 0x59B4: -case 0x5BB4: -case 0x5DB4: -case 0x5FB4: -case 0x51B5: -case 0x53B5: -case 0x55B5: -case 0x57B5: -case 0x59B5: -case 0x5BB5: -case 0x5DB5: -case 0x5FB5: -case 0x51B6: -case 0x53B6: -case 0x55B6: -case 0x57B6: -case 0x59B6: -case 0x5BB6: -case 0x5DB6: -case 0x5FB6: -case 0x51B7: -case 0x53B7: -case 0x55B7: -case 0x57B7: -case 0x59B7: -case 0x5BB7: -case 0x5DB7: -case 0x5FB7: - -// SUBQ -case 0x51B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x53B8: -case 0x55B8: -case 0x57B8: -case 0x59B8: -case 0x5BB8: -case 0x5DB8: -case 0x5FB8: - -// SUBQ -case 0x51B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x53B9: -case 0x55B9: -case 0x57B9: -case 0x59B9: -case 0x5BB9: -case 0x5DB9: -case 0x5FB9: - -// SUBQ -case 0x51B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x539F: -case 0x559F: -case 0x579F: -case 0x599F: -case 0x5B9F: -case 0x5D9F: -case 0x5F9F: - -// SUBQ -case 0x519F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x53A7: -case 0x55A7: -case 0x57A7: -case 0x59A7: -case 0x5BA7: -case 0x5DA7: -case 0x5FA7: - -// SUBQ -case 0x51A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (((Opcode >> 9) - 1) & 7) + 1; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) diff --git a/yabause/src/c68k/c68k_op6.inc b/yabause/src/c68k/c68k_op6.inc deleted file mode 100644 index d5b94b5317..0000000000 --- a/yabause/src/c68k/c68k_op6.inc +++ /dev/null @@ -1,4454 +0,0 @@ -case 0x6202: -case 0x6203: -case 0x6204: -case 0x6205: -case 0x6206: -case 0x6207: -case 0x6208: -case 0x6209: -case 0x620A: -case 0x620B: -case 0x620C: -case 0x620D: -case 0x620E: -case 0x620F: -case 0x6210: -case 0x6211: -case 0x6212: -case 0x6213: -case 0x6214: -case 0x6215: -case 0x6216: -case 0x6217: -case 0x6218: -case 0x6219: -case 0x621A: -case 0x621B: -case 0x621C: -case 0x621D: -case 0x621E: -case 0x621F: -case 0x6220: -case 0x6221: -case 0x6222: -case 0x6223: -case 0x6224: -case 0x6225: -case 0x6226: -case 0x6227: -case 0x6228: -case 0x6229: -case 0x622A: -case 0x622B: -case 0x622C: -case 0x622D: -case 0x622E: -case 0x622F: -case 0x6230: -case 0x6231: -case 0x6232: -case 0x6233: -case 0x6234: -case 0x6235: -case 0x6236: -case 0x6237: -case 0x6238: -case 0x6239: -case 0x623A: -case 0x623B: -case 0x623C: -case 0x623D: -case 0x623E: -case 0x623F: -case 0x6240: -case 0x6241: -case 0x6242: -case 0x6243: -case 0x6244: -case 0x6245: -case 0x6246: -case 0x6247: -case 0x6248: -case 0x6249: -case 0x624A: -case 0x624B: -case 0x624C: -case 0x624D: -case 0x624E: -case 0x624F: -case 0x6250: -case 0x6251: -case 0x6252: -case 0x6253: -case 0x6254: -case 0x6255: -case 0x6256: -case 0x6257: -case 0x6258: -case 0x6259: -case 0x625A: -case 0x625B: -case 0x625C: -case 0x625D: -case 0x625E: -case 0x625F: -case 0x6260: -case 0x6261: -case 0x6262: -case 0x6263: -case 0x6264: -case 0x6265: -case 0x6266: -case 0x6267: -case 0x6268: -case 0x6269: -case 0x626A: -case 0x626B: -case 0x626C: -case 0x626D: -case 0x626E: -case 0x626F: -case 0x6270: -case 0x6271: -case 0x6272: -case 0x6273: -case 0x6274: -case 0x6275: -case 0x6276: -case 0x6277: -case 0x6278: -case 0x6279: -case 0x627A: -case 0x627B: -case 0x627C: -case 0x627D: -case 0x627E: -case 0x627F: -case 0x6280: -case 0x6281: -case 0x6282: -case 0x6283: -case 0x6284: -case 0x6285: -case 0x6286: -case 0x6287: -case 0x6288: -case 0x6289: -case 0x628A: -case 0x628B: -case 0x628C: -case 0x628D: -case 0x628E: -case 0x628F: -case 0x6290: -case 0x6291: -case 0x6292: -case 0x6293: -case 0x6294: -case 0x6295: -case 0x6296: -case 0x6297: -case 0x6298: -case 0x6299: -case 0x629A: -case 0x629B: -case 0x629C: -case 0x629D: -case 0x629E: -case 0x629F: -case 0x62A0: -case 0x62A1: -case 0x62A2: -case 0x62A3: -case 0x62A4: -case 0x62A5: -case 0x62A6: -case 0x62A7: -case 0x62A8: -case 0x62A9: -case 0x62AA: -case 0x62AB: -case 0x62AC: -case 0x62AD: -case 0x62AE: -case 0x62AF: -case 0x62B0: -case 0x62B1: -case 0x62B2: -case 0x62B3: -case 0x62B4: -case 0x62B5: -case 0x62B6: -case 0x62B7: -case 0x62B8: -case 0x62B9: -case 0x62BA: -case 0x62BB: -case 0x62BC: -case 0x62BD: -case 0x62BE: -case 0x62BF: -case 0x62C0: -case 0x62C1: -case 0x62C2: -case 0x62C3: -case 0x62C4: -case 0x62C5: -case 0x62C6: -case 0x62C7: -case 0x62C8: -case 0x62C9: -case 0x62CA: -case 0x62CB: -case 0x62CC: -case 0x62CD: -case 0x62CE: -case 0x62CF: -case 0x62D0: -case 0x62D1: -case 0x62D2: -case 0x62D3: -case 0x62D4: -case 0x62D5: -case 0x62D6: -case 0x62D7: -case 0x62D8: -case 0x62D9: -case 0x62DA: -case 0x62DB: -case 0x62DC: -case 0x62DD: -case 0x62DE: -case 0x62DF: -case 0x62E0: -case 0x62E1: -case 0x62E2: -case 0x62E3: -case 0x62E4: -case 0x62E5: -case 0x62E6: -case 0x62E7: -case 0x62E8: -case 0x62E9: -case 0x62EA: -case 0x62EB: -case 0x62EC: -case 0x62ED: -case 0x62EE: -case 0x62EF: -case 0x62F0: -case 0x62F1: -case 0x62F2: -case 0x62F3: -case 0x62F4: -case 0x62F5: -case 0x62F6: -case 0x62F7: -case 0x62F8: -case 0x62F9: -case 0x62FA: -case 0x62FB: -case 0x62FC: -case 0x62FD: -case 0x62FE: -case 0x62FF: - -// BCC -case 0x6201: -{ - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6302: -case 0x6303: -case 0x6304: -case 0x6305: -case 0x6306: -case 0x6307: -case 0x6308: -case 0x6309: -case 0x630A: -case 0x630B: -case 0x630C: -case 0x630D: -case 0x630E: -case 0x630F: -case 0x6310: -case 0x6311: -case 0x6312: -case 0x6313: -case 0x6314: -case 0x6315: -case 0x6316: -case 0x6317: -case 0x6318: -case 0x6319: -case 0x631A: -case 0x631B: -case 0x631C: -case 0x631D: -case 0x631E: -case 0x631F: -case 0x6320: -case 0x6321: -case 0x6322: -case 0x6323: -case 0x6324: -case 0x6325: -case 0x6326: -case 0x6327: -case 0x6328: -case 0x6329: -case 0x632A: -case 0x632B: -case 0x632C: -case 0x632D: -case 0x632E: -case 0x632F: -case 0x6330: -case 0x6331: -case 0x6332: -case 0x6333: -case 0x6334: -case 0x6335: -case 0x6336: -case 0x6337: -case 0x6338: -case 0x6339: -case 0x633A: -case 0x633B: -case 0x633C: -case 0x633D: -case 0x633E: -case 0x633F: -case 0x6340: -case 0x6341: -case 0x6342: -case 0x6343: -case 0x6344: -case 0x6345: -case 0x6346: -case 0x6347: -case 0x6348: -case 0x6349: -case 0x634A: -case 0x634B: -case 0x634C: -case 0x634D: -case 0x634E: -case 0x634F: -case 0x6350: -case 0x6351: -case 0x6352: -case 0x6353: -case 0x6354: -case 0x6355: -case 0x6356: -case 0x6357: -case 0x6358: -case 0x6359: -case 0x635A: -case 0x635B: -case 0x635C: -case 0x635D: -case 0x635E: -case 0x635F: -case 0x6360: -case 0x6361: -case 0x6362: -case 0x6363: -case 0x6364: -case 0x6365: -case 0x6366: -case 0x6367: -case 0x6368: -case 0x6369: -case 0x636A: -case 0x636B: -case 0x636C: -case 0x636D: -case 0x636E: -case 0x636F: -case 0x6370: -case 0x6371: -case 0x6372: -case 0x6373: -case 0x6374: -case 0x6375: -case 0x6376: -case 0x6377: -case 0x6378: -case 0x6379: -case 0x637A: -case 0x637B: -case 0x637C: -case 0x637D: -case 0x637E: -case 0x637F: -case 0x6380: -case 0x6381: -case 0x6382: -case 0x6383: -case 0x6384: -case 0x6385: -case 0x6386: -case 0x6387: -case 0x6388: -case 0x6389: -case 0x638A: -case 0x638B: -case 0x638C: -case 0x638D: -case 0x638E: -case 0x638F: -case 0x6390: -case 0x6391: -case 0x6392: -case 0x6393: -case 0x6394: -case 0x6395: -case 0x6396: -case 0x6397: -case 0x6398: -case 0x6399: -case 0x639A: -case 0x639B: -case 0x639C: -case 0x639D: -case 0x639E: -case 0x639F: -case 0x63A0: -case 0x63A1: -case 0x63A2: -case 0x63A3: -case 0x63A4: -case 0x63A5: -case 0x63A6: -case 0x63A7: -case 0x63A8: -case 0x63A9: -case 0x63AA: -case 0x63AB: -case 0x63AC: -case 0x63AD: -case 0x63AE: -case 0x63AF: -case 0x63B0: -case 0x63B1: -case 0x63B2: -case 0x63B3: -case 0x63B4: -case 0x63B5: -case 0x63B6: -case 0x63B7: -case 0x63B8: -case 0x63B9: -case 0x63BA: -case 0x63BB: -case 0x63BC: -case 0x63BD: -case 0x63BE: -case 0x63BF: -case 0x63C0: -case 0x63C1: -case 0x63C2: -case 0x63C3: -case 0x63C4: -case 0x63C5: -case 0x63C6: -case 0x63C7: -case 0x63C8: -case 0x63C9: -case 0x63CA: -case 0x63CB: -case 0x63CC: -case 0x63CD: -case 0x63CE: -case 0x63CF: -case 0x63D0: -case 0x63D1: -case 0x63D2: -case 0x63D3: -case 0x63D4: -case 0x63D5: -case 0x63D6: -case 0x63D7: -case 0x63D8: -case 0x63D9: -case 0x63DA: -case 0x63DB: -case 0x63DC: -case 0x63DD: -case 0x63DE: -case 0x63DF: -case 0x63E0: -case 0x63E1: -case 0x63E2: -case 0x63E3: -case 0x63E4: -case 0x63E5: -case 0x63E6: -case 0x63E7: -case 0x63E8: -case 0x63E9: -case 0x63EA: -case 0x63EB: -case 0x63EC: -case 0x63ED: -case 0x63EE: -case 0x63EF: -case 0x63F0: -case 0x63F1: -case 0x63F2: -case 0x63F3: -case 0x63F4: -case 0x63F5: -case 0x63F6: -case 0x63F7: -case 0x63F8: -case 0x63F9: -case 0x63FA: -case 0x63FB: -case 0x63FC: -case 0x63FD: -case 0x63FE: -case 0x63FF: - -// BCC -case 0x6301: -{ - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6402: -case 0x6403: -case 0x6404: -case 0x6405: -case 0x6406: -case 0x6407: -case 0x6408: -case 0x6409: -case 0x640A: -case 0x640B: -case 0x640C: -case 0x640D: -case 0x640E: -case 0x640F: -case 0x6410: -case 0x6411: -case 0x6412: -case 0x6413: -case 0x6414: -case 0x6415: -case 0x6416: -case 0x6417: -case 0x6418: -case 0x6419: -case 0x641A: -case 0x641B: -case 0x641C: -case 0x641D: -case 0x641E: -case 0x641F: -case 0x6420: -case 0x6421: -case 0x6422: -case 0x6423: -case 0x6424: -case 0x6425: -case 0x6426: -case 0x6427: -case 0x6428: -case 0x6429: -case 0x642A: -case 0x642B: -case 0x642C: -case 0x642D: -case 0x642E: -case 0x642F: -case 0x6430: -case 0x6431: -case 0x6432: -case 0x6433: -case 0x6434: -case 0x6435: -case 0x6436: -case 0x6437: -case 0x6438: -case 0x6439: -case 0x643A: -case 0x643B: -case 0x643C: -case 0x643D: -case 0x643E: -case 0x643F: -case 0x6440: -case 0x6441: -case 0x6442: -case 0x6443: -case 0x6444: -case 0x6445: -case 0x6446: -case 0x6447: -case 0x6448: -case 0x6449: -case 0x644A: -case 0x644B: -case 0x644C: -case 0x644D: -case 0x644E: -case 0x644F: -case 0x6450: -case 0x6451: -case 0x6452: -case 0x6453: -case 0x6454: -case 0x6455: -case 0x6456: -case 0x6457: -case 0x6458: -case 0x6459: -case 0x645A: -case 0x645B: -case 0x645C: -case 0x645D: -case 0x645E: -case 0x645F: -case 0x6460: -case 0x6461: -case 0x6462: -case 0x6463: -case 0x6464: -case 0x6465: -case 0x6466: -case 0x6467: -case 0x6468: -case 0x6469: -case 0x646A: -case 0x646B: -case 0x646C: -case 0x646D: -case 0x646E: -case 0x646F: -case 0x6470: -case 0x6471: -case 0x6472: -case 0x6473: -case 0x6474: -case 0x6475: -case 0x6476: -case 0x6477: -case 0x6478: -case 0x6479: -case 0x647A: -case 0x647B: -case 0x647C: -case 0x647D: -case 0x647E: -case 0x647F: -case 0x6480: -case 0x6481: -case 0x6482: -case 0x6483: -case 0x6484: -case 0x6485: -case 0x6486: -case 0x6487: -case 0x6488: -case 0x6489: -case 0x648A: -case 0x648B: -case 0x648C: -case 0x648D: -case 0x648E: -case 0x648F: -case 0x6490: -case 0x6491: -case 0x6492: -case 0x6493: -case 0x6494: -case 0x6495: -case 0x6496: -case 0x6497: -case 0x6498: -case 0x6499: -case 0x649A: -case 0x649B: -case 0x649C: -case 0x649D: -case 0x649E: -case 0x649F: -case 0x64A0: -case 0x64A1: -case 0x64A2: -case 0x64A3: -case 0x64A4: -case 0x64A5: -case 0x64A6: -case 0x64A7: -case 0x64A8: -case 0x64A9: -case 0x64AA: -case 0x64AB: -case 0x64AC: -case 0x64AD: -case 0x64AE: -case 0x64AF: -case 0x64B0: -case 0x64B1: -case 0x64B2: -case 0x64B3: -case 0x64B4: -case 0x64B5: -case 0x64B6: -case 0x64B7: -case 0x64B8: -case 0x64B9: -case 0x64BA: -case 0x64BB: -case 0x64BC: -case 0x64BD: -case 0x64BE: -case 0x64BF: -case 0x64C0: -case 0x64C1: -case 0x64C2: -case 0x64C3: -case 0x64C4: -case 0x64C5: -case 0x64C6: -case 0x64C7: -case 0x64C8: -case 0x64C9: -case 0x64CA: -case 0x64CB: -case 0x64CC: -case 0x64CD: -case 0x64CE: -case 0x64CF: -case 0x64D0: -case 0x64D1: -case 0x64D2: -case 0x64D3: -case 0x64D4: -case 0x64D5: -case 0x64D6: -case 0x64D7: -case 0x64D8: -case 0x64D9: -case 0x64DA: -case 0x64DB: -case 0x64DC: -case 0x64DD: -case 0x64DE: -case 0x64DF: -case 0x64E0: -case 0x64E1: -case 0x64E2: -case 0x64E3: -case 0x64E4: -case 0x64E5: -case 0x64E6: -case 0x64E7: -case 0x64E8: -case 0x64E9: -case 0x64EA: -case 0x64EB: -case 0x64EC: -case 0x64ED: -case 0x64EE: -case 0x64EF: -case 0x64F0: -case 0x64F1: -case 0x64F2: -case 0x64F3: -case 0x64F4: -case 0x64F5: -case 0x64F6: -case 0x64F7: -case 0x64F8: -case 0x64F9: -case 0x64FA: -case 0x64FB: -case 0x64FC: -case 0x64FD: -case 0x64FE: -case 0x64FF: - -// BCC -case 0x6401: -{ - if (!(CPU->flag_C & 0x100)) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6502: -case 0x6503: -case 0x6504: -case 0x6505: -case 0x6506: -case 0x6507: -case 0x6508: -case 0x6509: -case 0x650A: -case 0x650B: -case 0x650C: -case 0x650D: -case 0x650E: -case 0x650F: -case 0x6510: -case 0x6511: -case 0x6512: -case 0x6513: -case 0x6514: -case 0x6515: -case 0x6516: -case 0x6517: -case 0x6518: -case 0x6519: -case 0x651A: -case 0x651B: -case 0x651C: -case 0x651D: -case 0x651E: -case 0x651F: -case 0x6520: -case 0x6521: -case 0x6522: -case 0x6523: -case 0x6524: -case 0x6525: -case 0x6526: -case 0x6527: -case 0x6528: -case 0x6529: -case 0x652A: -case 0x652B: -case 0x652C: -case 0x652D: -case 0x652E: -case 0x652F: -case 0x6530: -case 0x6531: -case 0x6532: -case 0x6533: -case 0x6534: -case 0x6535: -case 0x6536: -case 0x6537: -case 0x6538: -case 0x6539: -case 0x653A: -case 0x653B: -case 0x653C: -case 0x653D: -case 0x653E: -case 0x653F: -case 0x6540: -case 0x6541: -case 0x6542: -case 0x6543: -case 0x6544: -case 0x6545: -case 0x6546: -case 0x6547: -case 0x6548: -case 0x6549: -case 0x654A: -case 0x654B: -case 0x654C: -case 0x654D: -case 0x654E: -case 0x654F: -case 0x6550: -case 0x6551: -case 0x6552: -case 0x6553: -case 0x6554: -case 0x6555: -case 0x6556: -case 0x6557: -case 0x6558: -case 0x6559: -case 0x655A: -case 0x655B: -case 0x655C: -case 0x655D: -case 0x655E: -case 0x655F: -case 0x6560: -case 0x6561: -case 0x6562: -case 0x6563: -case 0x6564: -case 0x6565: -case 0x6566: -case 0x6567: -case 0x6568: -case 0x6569: -case 0x656A: -case 0x656B: -case 0x656C: -case 0x656D: -case 0x656E: -case 0x656F: -case 0x6570: -case 0x6571: -case 0x6572: -case 0x6573: -case 0x6574: -case 0x6575: -case 0x6576: -case 0x6577: -case 0x6578: -case 0x6579: -case 0x657A: -case 0x657B: -case 0x657C: -case 0x657D: -case 0x657E: -case 0x657F: -case 0x6580: -case 0x6581: -case 0x6582: -case 0x6583: -case 0x6584: -case 0x6585: -case 0x6586: -case 0x6587: -case 0x6588: -case 0x6589: -case 0x658A: -case 0x658B: -case 0x658C: -case 0x658D: -case 0x658E: -case 0x658F: -case 0x6590: -case 0x6591: -case 0x6592: -case 0x6593: -case 0x6594: -case 0x6595: -case 0x6596: -case 0x6597: -case 0x6598: -case 0x6599: -case 0x659A: -case 0x659B: -case 0x659C: -case 0x659D: -case 0x659E: -case 0x659F: -case 0x65A0: -case 0x65A1: -case 0x65A2: -case 0x65A3: -case 0x65A4: -case 0x65A5: -case 0x65A6: -case 0x65A7: -case 0x65A8: -case 0x65A9: -case 0x65AA: -case 0x65AB: -case 0x65AC: -case 0x65AD: -case 0x65AE: -case 0x65AF: -case 0x65B0: -case 0x65B1: -case 0x65B2: -case 0x65B3: -case 0x65B4: -case 0x65B5: -case 0x65B6: -case 0x65B7: -case 0x65B8: -case 0x65B9: -case 0x65BA: -case 0x65BB: -case 0x65BC: -case 0x65BD: -case 0x65BE: -case 0x65BF: -case 0x65C0: -case 0x65C1: -case 0x65C2: -case 0x65C3: -case 0x65C4: -case 0x65C5: -case 0x65C6: -case 0x65C7: -case 0x65C8: -case 0x65C9: -case 0x65CA: -case 0x65CB: -case 0x65CC: -case 0x65CD: -case 0x65CE: -case 0x65CF: -case 0x65D0: -case 0x65D1: -case 0x65D2: -case 0x65D3: -case 0x65D4: -case 0x65D5: -case 0x65D6: -case 0x65D7: -case 0x65D8: -case 0x65D9: -case 0x65DA: -case 0x65DB: -case 0x65DC: -case 0x65DD: -case 0x65DE: -case 0x65DF: -case 0x65E0: -case 0x65E1: -case 0x65E2: -case 0x65E3: -case 0x65E4: -case 0x65E5: -case 0x65E6: -case 0x65E7: -case 0x65E8: -case 0x65E9: -case 0x65EA: -case 0x65EB: -case 0x65EC: -case 0x65ED: -case 0x65EE: -case 0x65EF: -case 0x65F0: -case 0x65F1: -case 0x65F2: -case 0x65F3: -case 0x65F4: -case 0x65F5: -case 0x65F6: -case 0x65F7: -case 0x65F8: -case 0x65F9: -case 0x65FA: -case 0x65FB: -case 0x65FC: -case 0x65FD: -case 0x65FE: -case 0x65FF: - -// BCC -case 0x6501: -{ - if (CPU->flag_C & 0x100) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6602: -case 0x6603: -case 0x6604: -case 0x6605: -case 0x6606: -case 0x6607: -case 0x6608: -case 0x6609: -case 0x660A: -case 0x660B: -case 0x660C: -case 0x660D: -case 0x660E: -case 0x660F: -case 0x6610: -case 0x6611: -case 0x6612: -case 0x6613: -case 0x6614: -case 0x6615: -case 0x6616: -case 0x6617: -case 0x6618: -case 0x6619: -case 0x661A: -case 0x661B: -case 0x661C: -case 0x661D: -case 0x661E: -case 0x661F: -case 0x6620: -case 0x6621: -case 0x6622: -case 0x6623: -case 0x6624: -case 0x6625: -case 0x6626: -case 0x6627: -case 0x6628: -case 0x6629: -case 0x662A: -case 0x662B: -case 0x662C: -case 0x662D: -case 0x662E: -case 0x662F: -case 0x6630: -case 0x6631: -case 0x6632: -case 0x6633: -case 0x6634: -case 0x6635: -case 0x6636: -case 0x6637: -case 0x6638: -case 0x6639: -case 0x663A: -case 0x663B: -case 0x663C: -case 0x663D: -case 0x663E: -case 0x663F: -case 0x6640: -case 0x6641: -case 0x6642: -case 0x6643: -case 0x6644: -case 0x6645: -case 0x6646: -case 0x6647: -case 0x6648: -case 0x6649: -case 0x664A: -case 0x664B: -case 0x664C: -case 0x664D: -case 0x664E: -case 0x664F: -case 0x6650: -case 0x6651: -case 0x6652: -case 0x6653: -case 0x6654: -case 0x6655: -case 0x6656: -case 0x6657: -case 0x6658: -case 0x6659: -case 0x665A: -case 0x665B: -case 0x665C: -case 0x665D: -case 0x665E: -case 0x665F: -case 0x6660: -case 0x6661: -case 0x6662: -case 0x6663: -case 0x6664: -case 0x6665: -case 0x6666: -case 0x6667: -case 0x6668: -case 0x6669: -case 0x666A: -case 0x666B: -case 0x666C: -case 0x666D: -case 0x666E: -case 0x666F: -case 0x6670: -case 0x6671: -case 0x6672: -case 0x6673: -case 0x6674: -case 0x6675: -case 0x6676: -case 0x6677: -case 0x6678: -case 0x6679: -case 0x667A: -case 0x667B: -case 0x667C: -case 0x667D: -case 0x667E: -case 0x667F: -case 0x6680: -case 0x6681: -case 0x6682: -case 0x6683: -case 0x6684: -case 0x6685: -case 0x6686: -case 0x6687: -case 0x6688: -case 0x6689: -case 0x668A: -case 0x668B: -case 0x668C: -case 0x668D: -case 0x668E: -case 0x668F: -case 0x6690: -case 0x6691: -case 0x6692: -case 0x6693: -case 0x6694: -case 0x6695: -case 0x6696: -case 0x6697: -case 0x6698: -case 0x6699: -case 0x669A: -case 0x669B: -case 0x669C: -case 0x669D: -case 0x669E: -case 0x669F: -case 0x66A0: -case 0x66A1: -case 0x66A2: -case 0x66A3: -case 0x66A4: -case 0x66A5: -case 0x66A6: -case 0x66A7: -case 0x66A8: -case 0x66A9: -case 0x66AA: -case 0x66AB: -case 0x66AC: -case 0x66AD: -case 0x66AE: -case 0x66AF: -case 0x66B0: -case 0x66B1: -case 0x66B2: -case 0x66B3: -case 0x66B4: -case 0x66B5: -case 0x66B6: -case 0x66B7: -case 0x66B8: -case 0x66B9: -case 0x66BA: -case 0x66BB: -case 0x66BC: -case 0x66BD: -case 0x66BE: -case 0x66BF: -case 0x66C0: -case 0x66C1: -case 0x66C2: -case 0x66C3: -case 0x66C4: -case 0x66C5: -case 0x66C6: -case 0x66C7: -case 0x66C8: -case 0x66C9: -case 0x66CA: -case 0x66CB: -case 0x66CC: -case 0x66CD: -case 0x66CE: -case 0x66CF: -case 0x66D0: -case 0x66D1: -case 0x66D2: -case 0x66D3: -case 0x66D4: -case 0x66D5: -case 0x66D6: -case 0x66D7: -case 0x66D8: -case 0x66D9: -case 0x66DA: -case 0x66DB: -case 0x66DC: -case 0x66DD: -case 0x66DE: -case 0x66DF: -case 0x66E0: -case 0x66E1: -case 0x66E2: -case 0x66E3: -case 0x66E4: -case 0x66E5: -case 0x66E6: -case 0x66E7: -case 0x66E8: -case 0x66E9: -case 0x66EA: -case 0x66EB: -case 0x66EC: -case 0x66ED: -case 0x66EE: -case 0x66EF: -case 0x66F0: -case 0x66F1: -case 0x66F2: -case 0x66F3: -case 0x66F4: -case 0x66F5: -case 0x66F6: -case 0x66F7: -case 0x66F8: -case 0x66F9: -case 0x66FA: -case 0x66FB: -case 0x66FC: -case 0x66FD: -case 0x66FE: -case 0x66FF: - -// BCC -case 0x6601: -{ - if (CPU->flag_notZ) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6702: -case 0x6703: -case 0x6704: -case 0x6705: -case 0x6706: -case 0x6707: -case 0x6708: -case 0x6709: -case 0x670A: -case 0x670B: -case 0x670C: -case 0x670D: -case 0x670E: -case 0x670F: -case 0x6710: -case 0x6711: -case 0x6712: -case 0x6713: -case 0x6714: -case 0x6715: -case 0x6716: -case 0x6717: -case 0x6718: -case 0x6719: -case 0x671A: -case 0x671B: -case 0x671C: -case 0x671D: -case 0x671E: -case 0x671F: -case 0x6720: -case 0x6721: -case 0x6722: -case 0x6723: -case 0x6724: -case 0x6725: -case 0x6726: -case 0x6727: -case 0x6728: -case 0x6729: -case 0x672A: -case 0x672B: -case 0x672C: -case 0x672D: -case 0x672E: -case 0x672F: -case 0x6730: -case 0x6731: -case 0x6732: -case 0x6733: -case 0x6734: -case 0x6735: -case 0x6736: -case 0x6737: -case 0x6738: -case 0x6739: -case 0x673A: -case 0x673B: -case 0x673C: -case 0x673D: -case 0x673E: -case 0x673F: -case 0x6740: -case 0x6741: -case 0x6742: -case 0x6743: -case 0x6744: -case 0x6745: -case 0x6746: -case 0x6747: -case 0x6748: -case 0x6749: -case 0x674A: -case 0x674B: -case 0x674C: -case 0x674D: -case 0x674E: -case 0x674F: -case 0x6750: -case 0x6751: -case 0x6752: -case 0x6753: -case 0x6754: -case 0x6755: -case 0x6756: -case 0x6757: -case 0x6758: -case 0x6759: -case 0x675A: -case 0x675B: -case 0x675C: -case 0x675D: -case 0x675E: -case 0x675F: -case 0x6760: -case 0x6761: -case 0x6762: -case 0x6763: -case 0x6764: -case 0x6765: -case 0x6766: -case 0x6767: -case 0x6768: -case 0x6769: -case 0x676A: -case 0x676B: -case 0x676C: -case 0x676D: -case 0x676E: -case 0x676F: -case 0x6770: -case 0x6771: -case 0x6772: -case 0x6773: -case 0x6774: -case 0x6775: -case 0x6776: -case 0x6777: -case 0x6778: -case 0x6779: -case 0x677A: -case 0x677B: -case 0x677C: -case 0x677D: -case 0x677E: -case 0x677F: -case 0x6780: -case 0x6781: -case 0x6782: -case 0x6783: -case 0x6784: -case 0x6785: -case 0x6786: -case 0x6787: -case 0x6788: -case 0x6789: -case 0x678A: -case 0x678B: -case 0x678C: -case 0x678D: -case 0x678E: -case 0x678F: -case 0x6790: -case 0x6791: -case 0x6792: -case 0x6793: -case 0x6794: -case 0x6795: -case 0x6796: -case 0x6797: -case 0x6798: -case 0x6799: -case 0x679A: -case 0x679B: -case 0x679C: -case 0x679D: -case 0x679E: -case 0x679F: -case 0x67A0: -case 0x67A1: -case 0x67A2: -case 0x67A3: -case 0x67A4: -case 0x67A5: -case 0x67A6: -case 0x67A7: -case 0x67A8: -case 0x67A9: -case 0x67AA: -case 0x67AB: -case 0x67AC: -case 0x67AD: -case 0x67AE: -case 0x67AF: -case 0x67B0: -case 0x67B1: -case 0x67B2: -case 0x67B3: -case 0x67B4: -case 0x67B5: -case 0x67B6: -case 0x67B7: -case 0x67B8: -case 0x67B9: -case 0x67BA: -case 0x67BB: -case 0x67BC: -case 0x67BD: -case 0x67BE: -case 0x67BF: -case 0x67C0: -case 0x67C1: -case 0x67C2: -case 0x67C3: -case 0x67C4: -case 0x67C5: -case 0x67C6: -case 0x67C7: -case 0x67C8: -case 0x67C9: -case 0x67CA: -case 0x67CB: -case 0x67CC: -case 0x67CD: -case 0x67CE: -case 0x67CF: -case 0x67D0: -case 0x67D1: -case 0x67D2: -case 0x67D3: -case 0x67D4: -case 0x67D5: -case 0x67D6: -case 0x67D7: -case 0x67D8: -case 0x67D9: -case 0x67DA: -case 0x67DB: -case 0x67DC: -case 0x67DD: -case 0x67DE: -case 0x67DF: -case 0x67E0: -case 0x67E1: -case 0x67E2: -case 0x67E3: -case 0x67E4: -case 0x67E5: -case 0x67E6: -case 0x67E7: -case 0x67E8: -case 0x67E9: -case 0x67EA: -case 0x67EB: -case 0x67EC: -case 0x67ED: -case 0x67EE: -case 0x67EF: -case 0x67F0: -case 0x67F1: -case 0x67F2: -case 0x67F3: -case 0x67F4: -case 0x67F5: -case 0x67F6: -case 0x67F7: -case 0x67F8: -case 0x67F9: -case 0x67FA: -case 0x67FB: -case 0x67FC: -case 0x67FD: -case 0x67FE: -case 0x67FF: - -// BCC -case 0x6701: -{ - if (!CPU->flag_notZ) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6802: -case 0x6803: -case 0x6804: -case 0x6805: -case 0x6806: -case 0x6807: -case 0x6808: -case 0x6809: -case 0x680A: -case 0x680B: -case 0x680C: -case 0x680D: -case 0x680E: -case 0x680F: -case 0x6810: -case 0x6811: -case 0x6812: -case 0x6813: -case 0x6814: -case 0x6815: -case 0x6816: -case 0x6817: -case 0x6818: -case 0x6819: -case 0x681A: -case 0x681B: -case 0x681C: -case 0x681D: -case 0x681E: -case 0x681F: -case 0x6820: -case 0x6821: -case 0x6822: -case 0x6823: -case 0x6824: -case 0x6825: -case 0x6826: -case 0x6827: -case 0x6828: -case 0x6829: -case 0x682A: -case 0x682B: -case 0x682C: -case 0x682D: -case 0x682E: -case 0x682F: -case 0x6830: -case 0x6831: -case 0x6832: -case 0x6833: -case 0x6834: -case 0x6835: -case 0x6836: -case 0x6837: -case 0x6838: -case 0x6839: -case 0x683A: -case 0x683B: -case 0x683C: -case 0x683D: -case 0x683E: -case 0x683F: -case 0x6840: -case 0x6841: -case 0x6842: -case 0x6843: -case 0x6844: -case 0x6845: -case 0x6846: -case 0x6847: -case 0x6848: -case 0x6849: -case 0x684A: -case 0x684B: -case 0x684C: -case 0x684D: -case 0x684E: -case 0x684F: -case 0x6850: -case 0x6851: -case 0x6852: -case 0x6853: -case 0x6854: -case 0x6855: -case 0x6856: -case 0x6857: -case 0x6858: -case 0x6859: -case 0x685A: -case 0x685B: -case 0x685C: -case 0x685D: -case 0x685E: -case 0x685F: -case 0x6860: -case 0x6861: -case 0x6862: -case 0x6863: -case 0x6864: -case 0x6865: -case 0x6866: -case 0x6867: -case 0x6868: -case 0x6869: -case 0x686A: -case 0x686B: -case 0x686C: -case 0x686D: -case 0x686E: -case 0x686F: -case 0x6870: -case 0x6871: -case 0x6872: -case 0x6873: -case 0x6874: -case 0x6875: -case 0x6876: -case 0x6877: -case 0x6878: -case 0x6879: -case 0x687A: -case 0x687B: -case 0x687C: -case 0x687D: -case 0x687E: -case 0x687F: -case 0x6880: -case 0x6881: -case 0x6882: -case 0x6883: -case 0x6884: -case 0x6885: -case 0x6886: -case 0x6887: -case 0x6888: -case 0x6889: -case 0x688A: -case 0x688B: -case 0x688C: -case 0x688D: -case 0x688E: -case 0x688F: -case 0x6890: -case 0x6891: -case 0x6892: -case 0x6893: -case 0x6894: -case 0x6895: -case 0x6896: -case 0x6897: -case 0x6898: -case 0x6899: -case 0x689A: -case 0x689B: -case 0x689C: -case 0x689D: -case 0x689E: -case 0x689F: -case 0x68A0: -case 0x68A1: -case 0x68A2: -case 0x68A3: -case 0x68A4: -case 0x68A5: -case 0x68A6: -case 0x68A7: -case 0x68A8: -case 0x68A9: -case 0x68AA: -case 0x68AB: -case 0x68AC: -case 0x68AD: -case 0x68AE: -case 0x68AF: -case 0x68B0: -case 0x68B1: -case 0x68B2: -case 0x68B3: -case 0x68B4: -case 0x68B5: -case 0x68B6: -case 0x68B7: -case 0x68B8: -case 0x68B9: -case 0x68BA: -case 0x68BB: -case 0x68BC: -case 0x68BD: -case 0x68BE: -case 0x68BF: -case 0x68C0: -case 0x68C1: -case 0x68C2: -case 0x68C3: -case 0x68C4: -case 0x68C5: -case 0x68C6: -case 0x68C7: -case 0x68C8: -case 0x68C9: -case 0x68CA: -case 0x68CB: -case 0x68CC: -case 0x68CD: -case 0x68CE: -case 0x68CF: -case 0x68D0: -case 0x68D1: -case 0x68D2: -case 0x68D3: -case 0x68D4: -case 0x68D5: -case 0x68D6: -case 0x68D7: -case 0x68D8: -case 0x68D9: -case 0x68DA: -case 0x68DB: -case 0x68DC: -case 0x68DD: -case 0x68DE: -case 0x68DF: -case 0x68E0: -case 0x68E1: -case 0x68E2: -case 0x68E3: -case 0x68E4: -case 0x68E5: -case 0x68E6: -case 0x68E7: -case 0x68E8: -case 0x68E9: -case 0x68EA: -case 0x68EB: -case 0x68EC: -case 0x68ED: -case 0x68EE: -case 0x68EF: -case 0x68F0: -case 0x68F1: -case 0x68F2: -case 0x68F3: -case 0x68F4: -case 0x68F5: -case 0x68F6: -case 0x68F7: -case 0x68F8: -case 0x68F9: -case 0x68FA: -case 0x68FB: -case 0x68FC: -case 0x68FD: -case 0x68FE: -case 0x68FF: - -// BCC -case 0x6801: -{ - if (!(CPU->flag_V & 0x80)) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6902: -case 0x6903: -case 0x6904: -case 0x6905: -case 0x6906: -case 0x6907: -case 0x6908: -case 0x6909: -case 0x690A: -case 0x690B: -case 0x690C: -case 0x690D: -case 0x690E: -case 0x690F: -case 0x6910: -case 0x6911: -case 0x6912: -case 0x6913: -case 0x6914: -case 0x6915: -case 0x6916: -case 0x6917: -case 0x6918: -case 0x6919: -case 0x691A: -case 0x691B: -case 0x691C: -case 0x691D: -case 0x691E: -case 0x691F: -case 0x6920: -case 0x6921: -case 0x6922: -case 0x6923: -case 0x6924: -case 0x6925: -case 0x6926: -case 0x6927: -case 0x6928: -case 0x6929: -case 0x692A: -case 0x692B: -case 0x692C: -case 0x692D: -case 0x692E: -case 0x692F: -case 0x6930: -case 0x6931: -case 0x6932: -case 0x6933: -case 0x6934: -case 0x6935: -case 0x6936: -case 0x6937: -case 0x6938: -case 0x6939: -case 0x693A: -case 0x693B: -case 0x693C: -case 0x693D: -case 0x693E: -case 0x693F: -case 0x6940: -case 0x6941: -case 0x6942: -case 0x6943: -case 0x6944: -case 0x6945: -case 0x6946: -case 0x6947: -case 0x6948: -case 0x6949: -case 0x694A: -case 0x694B: -case 0x694C: -case 0x694D: -case 0x694E: -case 0x694F: -case 0x6950: -case 0x6951: -case 0x6952: -case 0x6953: -case 0x6954: -case 0x6955: -case 0x6956: -case 0x6957: -case 0x6958: -case 0x6959: -case 0x695A: -case 0x695B: -case 0x695C: -case 0x695D: -case 0x695E: -case 0x695F: -case 0x6960: -case 0x6961: -case 0x6962: -case 0x6963: -case 0x6964: -case 0x6965: -case 0x6966: -case 0x6967: -case 0x6968: -case 0x6969: -case 0x696A: -case 0x696B: -case 0x696C: -case 0x696D: -case 0x696E: -case 0x696F: -case 0x6970: -case 0x6971: -case 0x6972: -case 0x6973: -case 0x6974: -case 0x6975: -case 0x6976: -case 0x6977: -case 0x6978: -case 0x6979: -case 0x697A: -case 0x697B: -case 0x697C: -case 0x697D: -case 0x697E: -case 0x697F: -case 0x6980: -case 0x6981: -case 0x6982: -case 0x6983: -case 0x6984: -case 0x6985: -case 0x6986: -case 0x6987: -case 0x6988: -case 0x6989: -case 0x698A: -case 0x698B: -case 0x698C: -case 0x698D: -case 0x698E: -case 0x698F: -case 0x6990: -case 0x6991: -case 0x6992: -case 0x6993: -case 0x6994: -case 0x6995: -case 0x6996: -case 0x6997: -case 0x6998: -case 0x6999: -case 0x699A: -case 0x699B: -case 0x699C: -case 0x699D: -case 0x699E: -case 0x699F: -case 0x69A0: -case 0x69A1: -case 0x69A2: -case 0x69A3: -case 0x69A4: -case 0x69A5: -case 0x69A6: -case 0x69A7: -case 0x69A8: -case 0x69A9: -case 0x69AA: -case 0x69AB: -case 0x69AC: -case 0x69AD: -case 0x69AE: -case 0x69AF: -case 0x69B0: -case 0x69B1: -case 0x69B2: -case 0x69B3: -case 0x69B4: -case 0x69B5: -case 0x69B6: -case 0x69B7: -case 0x69B8: -case 0x69B9: -case 0x69BA: -case 0x69BB: -case 0x69BC: -case 0x69BD: -case 0x69BE: -case 0x69BF: -case 0x69C0: -case 0x69C1: -case 0x69C2: -case 0x69C3: -case 0x69C4: -case 0x69C5: -case 0x69C6: -case 0x69C7: -case 0x69C8: -case 0x69C9: -case 0x69CA: -case 0x69CB: -case 0x69CC: -case 0x69CD: -case 0x69CE: -case 0x69CF: -case 0x69D0: -case 0x69D1: -case 0x69D2: -case 0x69D3: -case 0x69D4: -case 0x69D5: -case 0x69D6: -case 0x69D7: -case 0x69D8: -case 0x69D9: -case 0x69DA: -case 0x69DB: -case 0x69DC: -case 0x69DD: -case 0x69DE: -case 0x69DF: -case 0x69E0: -case 0x69E1: -case 0x69E2: -case 0x69E3: -case 0x69E4: -case 0x69E5: -case 0x69E6: -case 0x69E7: -case 0x69E8: -case 0x69E9: -case 0x69EA: -case 0x69EB: -case 0x69EC: -case 0x69ED: -case 0x69EE: -case 0x69EF: -case 0x69F0: -case 0x69F1: -case 0x69F2: -case 0x69F3: -case 0x69F4: -case 0x69F5: -case 0x69F6: -case 0x69F7: -case 0x69F8: -case 0x69F9: -case 0x69FA: -case 0x69FB: -case 0x69FC: -case 0x69FD: -case 0x69FE: -case 0x69FF: - -// BCC -case 0x6901: -{ - if (CPU->flag_V & 0x80) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6A02: -case 0x6A03: -case 0x6A04: -case 0x6A05: -case 0x6A06: -case 0x6A07: -case 0x6A08: -case 0x6A09: -case 0x6A0A: -case 0x6A0B: -case 0x6A0C: -case 0x6A0D: -case 0x6A0E: -case 0x6A0F: -case 0x6A10: -case 0x6A11: -case 0x6A12: -case 0x6A13: -case 0x6A14: -case 0x6A15: -case 0x6A16: -case 0x6A17: -case 0x6A18: -case 0x6A19: -case 0x6A1A: -case 0x6A1B: -case 0x6A1C: -case 0x6A1D: -case 0x6A1E: -case 0x6A1F: -case 0x6A20: -case 0x6A21: -case 0x6A22: -case 0x6A23: -case 0x6A24: -case 0x6A25: -case 0x6A26: -case 0x6A27: -case 0x6A28: -case 0x6A29: -case 0x6A2A: -case 0x6A2B: -case 0x6A2C: -case 0x6A2D: -case 0x6A2E: -case 0x6A2F: -case 0x6A30: -case 0x6A31: -case 0x6A32: -case 0x6A33: -case 0x6A34: -case 0x6A35: -case 0x6A36: -case 0x6A37: -case 0x6A38: -case 0x6A39: -case 0x6A3A: -case 0x6A3B: -case 0x6A3C: -case 0x6A3D: -case 0x6A3E: -case 0x6A3F: -case 0x6A40: -case 0x6A41: -case 0x6A42: -case 0x6A43: -case 0x6A44: -case 0x6A45: -case 0x6A46: -case 0x6A47: -case 0x6A48: -case 0x6A49: -case 0x6A4A: -case 0x6A4B: -case 0x6A4C: -case 0x6A4D: -case 0x6A4E: -case 0x6A4F: -case 0x6A50: -case 0x6A51: -case 0x6A52: -case 0x6A53: -case 0x6A54: -case 0x6A55: -case 0x6A56: -case 0x6A57: -case 0x6A58: -case 0x6A59: -case 0x6A5A: -case 0x6A5B: -case 0x6A5C: -case 0x6A5D: -case 0x6A5E: -case 0x6A5F: -case 0x6A60: -case 0x6A61: -case 0x6A62: -case 0x6A63: -case 0x6A64: -case 0x6A65: -case 0x6A66: -case 0x6A67: -case 0x6A68: -case 0x6A69: -case 0x6A6A: -case 0x6A6B: -case 0x6A6C: -case 0x6A6D: -case 0x6A6E: -case 0x6A6F: -case 0x6A70: -case 0x6A71: -case 0x6A72: -case 0x6A73: -case 0x6A74: -case 0x6A75: -case 0x6A76: -case 0x6A77: -case 0x6A78: -case 0x6A79: -case 0x6A7A: -case 0x6A7B: -case 0x6A7C: -case 0x6A7D: -case 0x6A7E: -case 0x6A7F: -case 0x6A80: -case 0x6A81: -case 0x6A82: -case 0x6A83: -case 0x6A84: -case 0x6A85: -case 0x6A86: -case 0x6A87: -case 0x6A88: -case 0x6A89: -case 0x6A8A: -case 0x6A8B: -case 0x6A8C: -case 0x6A8D: -case 0x6A8E: -case 0x6A8F: -case 0x6A90: -case 0x6A91: -case 0x6A92: -case 0x6A93: -case 0x6A94: -case 0x6A95: -case 0x6A96: -case 0x6A97: -case 0x6A98: -case 0x6A99: -case 0x6A9A: -case 0x6A9B: -case 0x6A9C: -case 0x6A9D: -case 0x6A9E: -case 0x6A9F: -case 0x6AA0: -case 0x6AA1: -case 0x6AA2: -case 0x6AA3: -case 0x6AA4: -case 0x6AA5: -case 0x6AA6: -case 0x6AA7: -case 0x6AA8: -case 0x6AA9: -case 0x6AAA: -case 0x6AAB: -case 0x6AAC: -case 0x6AAD: -case 0x6AAE: -case 0x6AAF: -case 0x6AB0: -case 0x6AB1: -case 0x6AB2: -case 0x6AB3: -case 0x6AB4: -case 0x6AB5: -case 0x6AB6: -case 0x6AB7: -case 0x6AB8: -case 0x6AB9: -case 0x6ABA: -case 0x6ABB: -case 0x6ABC: -case 0x6ABD: -case 0x6ABE: -case 0x6ABF: -case 0x6AC0: -case 0x6AC1: -case 0x6AC2: -case 0x6AC3: -case 0x6AC4: -case 0x6AC5: -case 0x6AC6: -case 0x6AC7: -case 0x6AC8: -case 0x6AC9: -case 0x6ACA: -case 0x6ACB: -case 0x6ACC: -case 0x6ACD: -case 0x6ACE: -case 0x6ACF: -case 0x6AD0: -case 0x6AD1: -case 0x6AD2: -case 0x6AD3: -case 0x6AD4: -case 0x6AD5: -case 0x6AD6: -case 0x6AD7: -case 0x6AD8: -case 0x6AD9: -case 0x6ADA: -case 0x6ADB: -case 0x6ADC: -case 0x6ADD: -case 0x6ADE: -case 0x6ADF: -case 0x6AE0: -case 0x6AE1: -case 0x6AE2: -case 0x6AE3: -case 0x6AE4: -case 0x6AE5: -case 0x6AE6: -case 0x6AE7: -case 0x6AE8: -case 0x6AE9: -case 0x6AEA: -case 0x6AEB: -case 0x6AEC: -case 0x6AED: -case 0x6AEE: -case 0x6AEF: -case 0x6AF0: -case 0x6AF1: -case 0x6AF2: -case 0x6AF3: -case 0x6AF4: -case 0x6AF5: -case 0x6AF6: -case 0x6AF7: -case 0x6AF8: -case 0x6AF9: -case 0x6AFA: -case 0x6AFB: -case 0x6AFC: -case 0x6AFD: -case 0x6AFE: -case 0x6AFF: - -// BCC -case 0x6A01: -{ - if (!(CPU->flag_N & 0x80)) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6B02: -case 0x6B03: -case 0x6B04: -case 0x6B05: -case 0x6B06: -case 0x6B07: -case 0x6B08: -case 0x6B09: -case 0x6B0A: -case 0x6B0B: -case 0x6B0C: -case 0x6B0D: -case 0x6B0E: -case 0x6B0F: -case 0x6B10: -case 0x6B11: -case 0x6B12: -case 0x6B13: -case 0x6B14: -case 0x6B15: -case 0x6B16: -case 0x6B17: -case 0x6B18: -case 0x6B19: -case 0x6B1A: -case 0x6B1B: -case 0x6B1C: -case 0x6B1D: -case 0x6B1E: -case 0x6B1F: -case 0x6B20: -case 0x6B21: -case 0x6B22: -case 0x6B23: -case 0x6B24: -case 0x6B25: -case 0x6B26: -case 0x6B27: -case 0x6B28: -case 0x6B29: -case 0x6B2A: -case 0x6B2B: -case 0x6B2C: -case 0x6B2D: -case 0x6B2E: -case 0x6B2F: -case 0x6B30: -case 0x6B31: -case 0x6B32: -case 0x6B33: -case 0x6B34: -case 0x6B35: -case 0x6B36: -case 0x6B37: -case 0x6B38: -case 0x6B39: -case 0x6B3A: -case 0x6B3B: -case 0x6B3C: -case 0x6B3D: -case 0x6B3E: -case 0x6B3F: -case 0x6B40: -case 0x6B41: -case 0x6B42: -case 0x6B43: -case 0x6B44: -case 0x6B45: -case 0x6B46: -case 0x6B47: -case 0x6B48: -case 0x6B49: -case 0x6B4A: -case 0x6B4B: -case 0x6B4C: -case 0x6B4D: -case 0x6B4E: -case 0x6B4F: -case 0x6B50: -case 0x6B51: -case 0x6B52: -case 0x6B53: -case 0x6B54: -case 0x6B55: -case 0x6B56: -case 0x6B57: -case 0x6B58: -case 0x6B59: -case 0x6B5A: -case 0x6B5B: -case 0x6B5C: -case 0x6B5D: -case 0x6B5E: -case 0x6B5F: -case 0x6B60: -case 0x6B61: -case 0x6B62: -case 0x6B63: -case 0x6B64: -case 0x6B65: -case 0x6B66: -case 0x6B67: -case 0x6B68: -case 0x6B69: -case 0x6B6A: -case 0x6B6B: -case 0x6B6C: -case 0x6B6D: -case 0x6B6E: -case 0x6B6F: -case 0x6B70: -case 0x6B71: -case 0x6B72: -case 0x6B73: -case 0x6B74: -case 0x6B75: -case 0x6B76: -case 0x6B77: -case 0x6B78: -case 0x6B79: -case 0x6B7A: -case 0x6B7B: -case 0x6B7C: -case 0x6B7D: -case 0x6B7E: -case 0x6B7F: -case 0x6B80: -case 0x6B81: -case 0x6B82: -case 0x6B83: -case 0x6B84: -case 0x6B85: -case 0x6B86: -case 0x6B87: -case 0x6B88: -case 0x6B89: -case 0x6B8A: -case 0x6B8B: -case 0x6B8C: -case 0x6B8D: -case 0x6B8E: -case 0x6B8F: -case 0x6B90: -case 0x6B91: -case 0x6B92: -case 0x6B93: -case 0x6B94: -case 0x6B95: -case 0x6B96: -case 0x6B97: -case 0x6B98: -case 0x6B99: -case 0x6B9A: -case 0x6B9B: -case 0x6B9C: -case 0x6B9D: -case 0x6B9E: -case 0x6B9F: -case 0x6BA0: -case 0x6BA1: -case 0x6BA2: -case 0x6BA3: -case 0x6BA4: -case 0x6BA5: -case 0x6BA6: -case 0x6BA7: -case 0x6BA8: -case 0x6BA9: -case 0x6BAA: -case 0x6BAB: -case 0x6BAC: -case 0x6BAD: -case 0x6BAE: -case 0x6BAF: -case 0x6BB0: -case 0x6BB1: -case 0x6BB2: -case 0x6BB3: -case 0x6BB4: -case 0x6BB5: -case 0x6BB6: -case 0x6BB7: -case 0x6BB8: -case 0x6BB9: -case 0x6BBA: -case 0x6BBB: -case 0x6BBC: -case 0x6BBD: -case 0x6BBE: -case 0x6BBF: -case 0x6BC0: -case 0x6BC1: -case 0x6BC2: -case 0x6BC3: -case 0x6BC4: -case 0x6BC5: -case 0x6BC6: -case 0x6BC7: -case 0x6BC8: -case 0x6BC9: -case 0x6BCA: -case 0x6BCB: -case 0x6BCC: -case 0x6BCD: -case 0x6BCE: -case 0x6BCF: -case 0x6BD0: -case 0x6BD1: -case 0x6BD2: -case 0x6BD3: -case 0x6BD4: -case 0x6BD5: -case 0x6BD6: -case 0x6BD7: -case 0x6BD8: -case 0x6BD9: -case 0x6BDA: -case 0x6BDB: -case 0x6BDC: -case 0x6BDD: -case 0x6BDE: -case 0x6BDF: -case 0x6BE0: -case 0x6BE1: -case 0x6BE2: -case 0x6BE3: -case 0x6BE4: -case 0x6BE5: -case 0x6BE6: -case 0x6BE7: -case 0x6BE8: -case 0x6BE9: -case 0x6BEA: -case 0x6BEB: -case 0x6BEC: -case 0x6BED: -case 0x6BEE: -case 0x6BEF: -case 0x6BF0: -case 0x6BF1: -case 0x6BF2: -case 0x6BF3: -case 0x6BF4: -case 0x6BF5: -case 0x6BF6: -case 0x6BF7: -case 0x6BF8: -case 0x6BF9: -case 0x6BFA: -case 0x6BFB: -case 0x6BFC: -case 0x6BFD: -case 0x6BFE: -case 0x6BFF: - -// BCC -case 0x6B01: -{ - if (CPU->flag_N & 0x80) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6C02: -case 0x6C03: -case 0x6C04: -case 0x6C05: -case 0x6C06: -case 0x6C07: -case 0x6C08: -case 0x6C09: -case 0x6C0A: -case 0x6C0B: -case 0x6C0C: -case 0x6C0D: -case 0x6C0E: -case 0x6C0F: -case 0x6C10: -case 0x6C11: -case 0x6C12: -case 0x6C13: -case 0x6C14: -case 0x6C15: -case 0x6C16: -case 0x6C17: -case 0x6C18: -case 0x6C19: -case 0x6C1A: -case 0x6C1B: -case 0x6C1C: -case 0x6C1D: -case 0x6C1E: -case 0x6C1F: -case 0x6C20: -case 0x6C21: -case 0x6C22: -case 0x6C23: -case 0x6C24: -case 0x6C25: -case 0x6C26: -case 0x6C27: -case 0x6C28: -case 0x6C29: -case 0x6C2A: -case 0x6C2B: -case 0x6C2C: -case 0x6C2D: -case 0x6C2E: -case 0x6C2F: -case 0x6C30: -case 0x6C31: -case 0x6C32: -case 0x6C33: -case 0x6C34: -case 0x6C35: -case 0x6C36: -case 0x6C37: -case 0x6C38: -case 0x6C39: -case 0x6C3A: -case 0x6C3B: -case 0x6C3C: -case 0x6C3D: -case 0x6C3E: -case 0x6C3F: -case 0x6C40: -case 0x6C41: -case 0x6C42: -case 0x6C43: -case 0x6C44: -case 0x6C45: -case 0x6C46: -case 0x6C47: -case 0x6C48: -case 0x6C49: -case 0x6C4A: -case 0x6C4B: -case 0x6C4C: -case 0x6C4D: -case 0x6C4E: -case 0x6C4F: -case 0x6C50: -case 0x6C51: -case 0x6C52: -case 0x6C53: -case 0x6C54: -case 0x6C55: -case 0x6C56: -case 0x6C57: -case 0x6C58: -case 0x6C59: -case 0x6C5A: -case 0x6C5B: -case 0x6C5C: -case 0x6C5D: -case 0x6C5E: -case 0x6C5F: -case 0x6C60: -case 0x6C61: -case 0x6C62: -case 0x6C63: -case 0x6C64: -case 0x6C65: -case 0x6C66: -case 0x6C67: -case 0x6C68: -case 0x6C69: -case 0x6C6A: -case 0x6C6B: -case 0x6C6C: -case 0x6C6D: -case 0x6C6E: -case 0x6C6F: -case 0x6C70: -case 0x6C71: -case 0x6C72: -case 0x6C73: -case 0x6C74: -case 0x6C75: -case 0x6C76: -case 0x6C77: -case 0x6C78: -case 0x6C79: -case 0x6C7A: -case 0x6C7B: -case 0x6C7C: -case 0x6C7D: -case 0x6C7E: -case 0x6C7F: -case 0x6C80: -case 0x6C81: -case 0x6C82: -case 0x6C83: -case 0x6C84: -case 0x6C85: -case 0x6C86: -case 0x6C87: -case 0x6C88: -case 0x6C89: -case 0x6C8A: -case 0x6C8B: -case 0x6C8C: -case 0x6C8D: -case 0x6C8E: -case 0x6C8F: -case 0x6C90: -case 0x6C91: -case 0x6C92: -case 0x6C93: -case 0x6C94: -case 0x6C95: -case 0x6C96: -case 0x6C97: -case 0x6C98: -case 0x6C99: -case 0x6C9A: -case 0x6C9B: -case 0x6C9C: -case 0x6C9D: -case 0x6C9E: -case 0x6C9F: -case 0x6CA0: -case 0x6CA1: -case 0x6CA2: -case 0x6CA3: -case 0x6CA4: -case 0x6CA5: -case 0x6CA6: -case 0x6CA7: -case 0x6CA8: -case 0x6CA9: -case 0x6CAA: -case 0x6CAB: -case 0x6CAC: -case 0x6CAD: -case 0x6CAE: -case 0x6CAF: -case 0x6CB0: -case 0x6CB1: -case 0x6CB2: -case 0x6CB3: -case 0x6CB4: -case 0x6CB5: -case 0x6CB6: -case 0x6CB7: -case 0x6CB8: -case 0x6CB9: -case 0x6CBA: -case 0x6CBB: -case 0x6CBC: -case 0x6CBD: -case 0x6CBE: -case 0x6CBF: -case 0x6CC0: -case 0x6CC1: -case 0x6CC2: -case 0x6CC3: -case 0x6CC4: -case 0x6CC5: -case 0x6CC6: -case 0x6CC7: -case 0x6CC8: -case 0x6CC9: -case 0x6CCA: -case 0x6CCB: -case 0x6CCC: -case 0x6CCD: -case 0x6CCE: -case 0x6CCF: -case 0x6CD0: -case 0x6CD1: -case 0x6CD2: -case 0x6CD3: -case 0x6CD4: -case 0x6CD5: -case 0x6CD6: -case 0x6CD7: -case 0x6CD8: -case 0x6CD9: -case 0x6CDA: -case 0x6CDB: -case 0x6CDC: -case 0x6CDD: -case 0x6CDE: -case 0x6CDF: -case 0x6CE0: -case 0x6CE1: -case 0x6CE2: -case 0x6CE3: -case 0x6CE4: -case 0x6CE5: -case 0x6CE6: -case 0x6CE7: -case 0x6CE8: -case 0x6CE9: -case 0x6CEA: -case 0x6CEB: -case 0x6CEC: -case 0x6CED: -case 0x6CEE: -case 0x6CEF: -case 0x6CF0: -case 0x6CF1: -case 0x6CF2: -case 0x6CF3: -case 0x6CF4: -case 0x6CF5: -case 0x6CF6: -case 0x6CF7: -case 0x6CF8: -case 0x6CF9: -case 0x6CFA: -case 0x6CFB: -case 0x6CFC: -case 0x6CFD: -case 0x6CFE: -case 0x6CFF: - -// BCC -case 0x6C01: -{ - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6D02: -case 0x6D03: -case 0x6D04: -case 0x6D05: -case 0x6D06: -case 0x6D07: -case 0x6D08: -case 0x6D09: -case 0x6D0A: -case 0x6D0B: -case 0x6D0C: -case 0x6D0D: -case 0x6D0E: -case 0x6D0F: -case 0x6D10: -case 0x6D11: -case 0x6D12: -case 0x6D13: -case 0x6D14: -case 0x6D15: -case 0x6D16: -case 0x6D17: -case 0x6D18: -case 0x6D19: -case 0x6D1A: -case 0x6D1B: -case 0x6D1C: -case 0x6D1D: -case 0x6D1E: -case 0x6D1F: -case 0x6D20: -case 0x6D21: -case 0x6D22: -case 0x6D23: -case 0x6D24: -case 0x6D25: -case 0x6D26: -case 0x6D27: -case 0x6D28: -case 0x6D29: -case 0x6D2A: -case 0x6D2B: -case 0x6D2C: -case 0x6D2D: -case 0x6D2E: -case 0x6D2F: -case 0x6D30: -case 0x6D31: -case 0x6D32: -case 0x6D33: -case 0x6D34: -case 0x6D35: -case 0x6D36: -case 0x6D37: -case 0x6D38: -case 0x6D39: -case 0x6D3A: -case 0x6D3B: -case 0x6D3C: -case 0x6D3D: -case 0x6D3E: -case 0x6D3F: -case 0x6D40: -case 0x6D41: -case 0x6D42: -case 0x6D43: -case 0x6D44: -case 0x6D45: -case 0x6D46: -case 0x6D47: -case 0x6D48: -case 0x6D49: -case 0x6D4A: -case 0x6D4B: -case 0x6D4C: -case 0x6D4D: -case 0x6D4E: -case 0x6D4F: -case 0x6D50: -case 0x6D51: -case 0x6D52: -case 0x6D53: -case 0x6D54: -case 0x6D55: -case 0x6D56: -case 0x6D57: -case 0x6D58: -case 0x6D59: -case 0x6D5A: -case 0x6D5B: -case 0x6D5C: -case 0x6D5D: -case 0x6D5E: -case 0x6D5F: -case 0x6D60: -case 0x6D61: -case 0x6D62: -case 0x6D63: -case 0x6D64: -case 0x6D65: -case 0x6D66: -case 0x6D67: -case 0x6D68: -case 0x6D69: -case 0x6D6A: -case 0x6D6B: -case 0x6D6C: -case 0x6D6D: -case 0x6D6E: -case 0x6D6F: -case 0x6D70: -case 0x6D71: -case 0x6D72: -case 0x6D73: -case 0x6D74: -case 0x6D75: -case 0x6D76: -case 0x6D77: -case 0x6D78: -case 0x6D79: -case 0x6D7A: -case 0x6D7B: -case 0x6D7C: -case 0x6D7D: -case 0x6D7E: -case 0x6D7F: -case 0x6D80: -case 0x6D81: -case 0x6D82: -case 0x6D83: -case 0x6D84: -case 0x6D85: -case 0x6D86: -case 0x6D87: -case 0x6D88: -case 0x6D89: -case 0x6D8A: -case 0x6D8B: -case 0x6D8C: -case 0x6D8D: -case 0x6D8E: -case 0x6D8F: -case 0x6D90: -case 0x6D91: -case 0x6D92: -case 0x6D93: -case 0x6D94: -case 0x6D95: -case 0x6D96: -case 0x6D97: -case 0x6D98: -case 0x6D99: -case 0x6D9A: -case 0x6D9B: -case 0x6D9C: -case 0x6D9D: -case 0x6D9E: -case 0x6D9F: -case 0x6DA0: -case 0x6DA1: -case 0x6DA2: -case 0x6DA3: -case 0x6DA4: -case 0x6DA5: -case 0x6DA6: -case 0x6DA7: -case 0x6DA8: -case 0x6DA9: -case 0x6DAA: -case 0x6DAB: -case 0x6DAC: -case 0x6DAD: -case 0x6DAE: -case 0x6DAF: -case 0x6DB0: -case 0x6DB1: -case 0x6DB2: -case 0x6DB3: -case 0x6DB4: -case 0x6DB5: -case 0x6DB6: -case 0x6DB7: -case 0x6DB8: -case 0x6DB9: -case 0x6DBA: -case 0x6DBB: -case 0x6DBC: -case 0x6DBD: -case 0x6DBE: -case 0x6DBF: -case 0x6DC0: -case 0x6DC1: -case 0x6DC2: -case 0x6DC3: -case 0x6DC4: -case 0x6DC5: -case 0x6DC6: -case 0x6DC7: -case 0x6DC8: -case 0x6DC9: -case 0x6DCA: -case 0x6DCB: -case 0x6DCC: -case 0x6DCD: -case 0x6DCE: -case 0x6DCF: -case 0x6DD0: -case 0x6DD1: -case 0x6DD2: -case 0x6DD3: -case 0x6DD4: -case 0x6DD5: -case 0x6DD6: -case 0x6DD7: -case 0x6DD8: -case 0x6DD9: -case 0x6DDA: -case 0x6DDB: -case 0x6DDC: -case 0x6DDD: -case 0x6DDE: -case 0x6DDF: -case 0x6DE0: -case 0x6DE1: -case 0x6DE2: -case 0x6DE3: -case 0x6DE4: -case 0x6DE5: -case 0x6DE6: -case 0x6DE7: -case 0x6DE8: -case 0x6DE9: -case 0x6DEA: -case 0x6DEB: -case 0x6DEC: -case 0x6DED: -case 0x6DEE: -case 0x6DEF: -case 0x6DF0: -case 0x6DF1: -case 0x6DF2: -case 0x6DF3: -case 0x6DF4: -case 0x6DF5: -case 0x6DF6: -case 0x6DF7: -case 0x6DF8: -case 0x6DF9: -case 0x6DFA: -case 0x6DFB: -case 0x6DFC: -case 0x6DFD: -case 0x6DFE: -case 0x6DFF: - -// BCC -case 0x6D01: -{ - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6E02: -case 0x6E03: -case 0x6E04: -case 0x6E05: -case 0x6E06: -case 0x6E07: -case 0x6E08: -case 0x6E09: -case 0x6E0A: -case 0x6E0B: -case 0x6E0C: -case 0x6E0D: -case 0x6E0E: -case 0x6E0F: -case 0x6E10: -case 0x6E11: -case 0x6E12: -case 0x6E13: -case 0x6E14: -case 0x6E15: -case 0x6E16: -case 0x6E17: -case 0x6E18: -case 0x6E19: -case 0x6E1A: -case 0x6E1B: -case 0x6E1C: -case 0x6E1D: -case 0x6E1E: -case 0x6E1F: -case 0x6E20: -case 0x6E21: -case 0x6E22: -case 0x6E23: -case 0x6E24: -case 0x6E25: -case 0x6E26: -case 0x6E27: -case 0x6E28: -case 0x6E29: -case 0x6E2A: -case 0x6E2B: -case 0x6E2C: -case 0x6E2D: -case 0x6E2E: -case 0x6E2F: -case 0x6E30: -case 0x6E31: -case 0x6E32: -case 0x6E33: -case 0x6E34: -case 0x6E35: -case 0x6E36: -case 0x6E37: -case 0x6E38: -case 0x6E39: -case 0x6E3A: -case 0x6E3B: -case 0x6E3C: -case 0x6E3D: -case 0x6E3E: -case 0x6E3F: -case 0x6E40: -case 0x6E41: -case 0x6E42: -case 0x6E43: -case 0x6E44: -case 0x6E45: -case 0x6E46: -case 0x6E47: -case 0x6E48: -case 0x6E49: -case 0x6E4A: -case 0x6E4B: -case 0x6E4C: -case 0x6E4D: -case 0x6E4E: -case 0x6E4F: -case 0x6E50: -case 0x6E51: -case 0x6E52: -case 0x6E53: -case 0x6E54: -case 0x6E55: -case 0x6E56: -case 0x6E57: -case 0x6E58: -case 0x6E59: -case 0x6E5A: -case 0x6E5B: -case 0x6E5C: -case 0x6E5D: -case 0x6E5E: -case 0x6E5F: -case 0x6E60: -case 0x6E61: -case 0x6E62: -case 0x6E63: -case 0x6E64: -case 0x6E65: -case 0x6E66: -case 0x6E67: -case 0x6E68: -case 0x6E69: -case 0x6E6A: -case 0x6E6B: -case 0x6E6C: -case 0x6E6D: -case 0x6E6E: -case 0x6E6F: -case 0x6E70: -case 0x6E71: -case 0x6E72: -case 0x6E73: -case 0x6E74: -case 0x6E75: -case 0x6E76: -case 0x6E77: -case 0x6E78: -case 0x6E79: -case 0x6E7A: -case 0x6E7B: -case 0x6E7C: -case 0x6E7D: -case 0x6E7E: -case 0x6E7F: -case 0x6E80: -case 0x6E81: -case 0x6E82: -case 0x6E83: -case 0x6E84: -case 0x6E85: -case 0x6E86: -case 0x6E87: -case 0x6E88: -case 0x6E89: -case 0x6E8A: -case 0x6E8B: -case 0x6E8C: -case 0x6E8D: -case 0x6E8E: -case 0x6E8F: -case 0x6E90: -case 0x6E91: -case 0x6E92: -case 0x6E93: -case 0x6E94: -case 0x6E95: -case 0x6E96: -case 0x6E97: -case 0x6E98: -case 0x6E99: -case 0x6E9A: -case 0x6E9B: -case 0x6E9C: -case 0x6E9D: -case 0x6E9E: -case 0x6E9F: -case 0x6EA0: -case 0x6EA1: -case 0x6EA2: -case 0x6EA3: -case 0x6EA4: -case 0x6EA5: -case 0x6EA6: -case 0x6EA7: -case 0x6EA8: -case 0x6EA9: -case 0x6EAA: -case 0x6EAB: -case 0x6EAC: -case 0x6EAD: -case 0x6EAE: -case 0x6EAF: -case 0x6EB0: -case 0x6EB1: -case 0x6EB2: -case 0x6EB3: -case 0x6EB4: -case 0x6EB5: -case 0x6EB6: -case 0x6EB7: -case 0x6EB8: -case 0x6EB9: -case 0x6EBA: -case 0x6EBB: -case 0x6EBC: -case 0x6EBD: -case 0x6EBE: -case 0x6EBF: -case 0x6EC0: -case 0x6EC1: -case 0x6EC2: -case 0x6EC3: -case 0x6EC4: -case 0x6EC5: -case 0x6EC6: -case 0x6EC7: -case 0x6EC8: -case 0x6EC9: -case 0x6ECA: -case 0x6ECB: -case 0x6ECC: -case 0x6ECD: -case 0x6ECE: -case 0x6ECF: -case 0x6ED0: -case 0x6ED1: -case 0x6ED2: -case 0x6ED3: -case 0x6ED4: -case 0x6ED5: -case 0x6ED6: -case 0x6ED7: -case 0x6ED8: -case 0x6ED9: -case 0x6EDA: -case 0x6EDB: -case 0x6EDC: -case 0x6EDD: -case 0x6EDE: -case 0x6EDF: -case 0x6EE0: -case 0x6EE1: -case 0x6EE2: -case 0x6EE3: -case 0x6EE4: -case 0x6EE5: -case 0x6EE6: -case 0x6EE7: -case 0x6EE8: -case 0x6EE9: -case 0x6EEA: -case 0x6EEB: -case 0x6EEC: -case 0x6EED: -case 0x6EEE: -case 0x6EEF: -case 0x6EF0: -case 0x6EF1: -case 0x6EF2: -case 0x6EF3: -case 0x6EF4: -case 0x6EF5: -case 0x6EF6: -case 0x6EF7: -case 0x6EF8: -case 0x6EF9: -case 0x6EFA: -case 0x6EFB: -case 0x6EFC: -case 0x6EFD: -case 0x6EFE: -case 0x6EFF: - -// BCC -case 0x6E01: -{ - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) -case 0x6F02: -case 0x6F03: -case 0x6F04: -case 0x6F05: -case 0x6F06: -case 0x6F07: -case 0x6F08: -case 0x6F09: -case 0x6F0A: -case 0x6F0B: -case 0x6F0C: -case 0x6F0D: -case 0x6F0E: -case 0x6F0F: -case 0x6F10: -case 0x6F11: -case 0x6F12: -case 0x6F13: -case 0x6F14: -case 0x6F15: -case 0x6F16: -case 0x6F17: -case 0x6F18: -case 0x6F19: -case 0x6F1A: -case 0x6F1B: -case 0x6F1C: -case 0x6F1D: -case 0x6F1E: -case 0x6F1F: -case 0x6F20: -case 0x6F21: -case 0x6F22: -case 0x6F23: -case 0x6F24: -case 0x6F25: -case 0x6F26: -case 0x6F27: -case 0x6F28: -case 0x6F29: -case 0x6F2A: -case 0x6F2B: -case 0x6F2C: -case 0x6F2D: -case 0x6F2E: -case 0x6F2F: -case 0x6F30: -case 0x6F31: -case 0x6F32: -case 0x6F33: -case 0x6F34: -case 0x6F35: -case 0x6F36: -case 0x6F37: -case 0x6F38: -case 0x6F39: -case 0x6F3A: -case 0x6F3B: -case 0x6F3C: -case 0x6F3D: -case 0x6F3E: -case 0x6F3F: -case 0x6F40: -case 0x6F41: -case 0x6F42: -case 0x6F43: -case 0x6F44: -case 0x6F45: -case 0x6F46: -case 0x6F47: -case 0x6F48: -case 0x6F49: -case 0x6F4A: -case 0x6F4B: -case 0x6F4C: -case 0x6F4D: -case 0x6F4E: -case 0x6F4F: -case 0x6F50: -case 0x6F51: -case 0x6F52: -case 0x6F53: -case 0x6F54: -case 0x6F55: -case 0x6F56: -case 0x6F57: -case 0x6F58: -case 0x6F59: -case 0x6F5A: -case 0x6F5B: -case 0x6F5C: -case 0x6F5D: -case 0x6F5E: -case 0x6F5F: -case 0x6F60: -case 0x6F61: -case 0x6F62: -case 0x6F63: -case 0x6F64: -case 0x6F65: -case 0x6F66: -case 0x6F67: -case 0x6F68: -case 0x6F69: -case 0x6F6A: -case 0x6F6B: -case 0x6F6C: -case 0x6F6D: -case 0x6F6E: -case 0x6F6F: -case 0x6F70: -case 0x6F71: -case 0x6F72: -case 0x6F73: -case 0x6F74: -case 0x6F75: -case 0x6F76: -case 0x6F77: -case 0x6F78: -case 0x6F79: -case 0x6F7A: -case 0x6F7B: -case 0x6F7C: -case 0x6F7D: -case 0x6F7E: -case 0x6F7F: -case 0x6F80: -case 0x6F81: -case 0x6F82: -case 0x6F83: -case 0x6F84: -case 0x6F85: -case 0x6F86: -case 0x6F87: -case 0x6F88: -case 0x6F89: -case 0x6F8A: -case 0x6F8B: -case 0x6F8C: -case 0x6F8D: -case 0x6F8E: -case 0x6F8F: -case 0x6F90: -case 0x6F91: -case 0x6F92: -case 0x6F93: -case 0x6F94: -case 0x6F95: -case 0x6F96: -case 0x6F97: -case 0x6F98: -case 0x6F99: -case 0x6F9A: -case 0x6F9B: -case 0x6F9C: -case 0x6F9D: -case 0x6F9E: -case 0x6F9F: -case 0x6FA0: -case 0x6FA1: -case 0x6FA2: -case 0x6FA3: -case 0x6FA4: -case 0x6FA5: -case 0x6FA6: -case 0x6FA7: -case 0x6FA8: -case 0x6FA9: -case 0x6FAA: -case 0x6FAB: -case 0x6FAC: -case 0x6FAD: -case 0x6FAE: -case 0x6FAF: -case 0x6FB0: -case 0x6FB1: -case 0x6FB2: -case 0x6FB3: -case 0x6FB4: -case 0x6FB5: -case 0x6FB6: -case 0x6FB7: -case 0x6FB8: -case 0x6FB9: -case 0x6FBA: -case 0x6FBB: -case 0x6FBC: -case 0x6FBD: -case 0x6FBE: -case 0x6FBF: -case 0x6FC0: -case 0x6FC1: -case 0x6FC2: -case 0x6FC3: -case 0x6FC4: -case 0x6FC5: -case 0x6FC6: -case 0x6FC7: -case 0x6FC8: -case 0x6FC9: -case 0x6FCA: -case 0x6FCB: -case 0x6FCC: -case 0x6FCD: -case 0x6FCE: -case 0x6FCF: -case 0x6FD0: -case 0x6FD1: -case 0x6FD2: -case 0x6FD3: -case 0x6FD4: -case 0x6FD5: -case 0x6FD6: -case 0x6FD7: -case 0x6FD8: -case 0x6FD9: -case 0x6FDA: -case 0x6FDB: -case 0x6FDC: -case 0x6FDD: -case 0x6FDE: -case 0x6FDF: -case 0x6FE0: -case 0x6FE1: -case 0x6FE2: -case 0x6FE3: -case 0x6FE4: -case 0x6FE5: -case 0x6FE6: -case 0x6FE7: -case 0x6FE8: -case 0x6FE9: -case 0x6FEA: -case 0x6FEB: -case 0x6FEC: -case 0x6FED: -case 0x6FEE: -case 0x6FEF: -case 0x6FF0: -case 0x6FF1: -case 0x6FF2: -case 0x6FF3: -case 0x6FF4: -case 0x6FF5: -case 0x6FF6: -case 0x6FF7: -case 0x6FF8: -case 0x6FF9: -case 0x6FFA: -case 0x6FFB: -case 0x6FFC: -case 0x6FFD: -case 0x6FFE: -case 0x6FFF: - -// BCC -case 0x6F01: -{ - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - PC += (s32)(s8)Opcode; - CCnt -= 2; - } -} -RET(8) - -// BCC16 -case 0x6200: -{ - if (CPU->flag_notZ && (!(CPU->flag_C & 0x100))) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6300: -{ - if ((!CPU->flag_notZ) || (CPU->flag_C & 0x100)) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6400: -{ - if (!(CPU->flag_C & 0x100)) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6500: -{ - if (CPU->flag_C & 0x100) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6600: -{ - if (CPU->flag_notZ) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6700: -{ - if (!CPU->flag_notZ) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6800: -{ - if (!(CPU->flag_V & 0x80)) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6900: -{ - if (CPU->flag_V & 0x80) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6A00: -{ - if (!(CPU->flag_N & 0x80)) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6B00: -{ - if (CPU->flag_N & 0x80) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6C00: -{ - if (!((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6D00: -{ - if ((CPU->flag_N ^ CPU->flag_V) & 0x80) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6E00: -{ - if (CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80))) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) - -// BCC16 -case 0x6F00: -{ - if ((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80)) - { - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); - RET(10) - } - PC += 2; -} -RET(12) -case 0x6002: -case 0x6003: -case 0x6004: -case 0x6005: -case 0x6006: -case 0x6007: -case 0x6008: -case 0x6009: -case 0x600A: -case 0x600B: -case 0x600C: -case 0x600D: -case 0x600E: -case 0x600F: -case 0x6010: -case 0x6011: -case 0x6012: -case 0x6013: -case 0x6014: -case 0x6015: -case 0x6016: -case 0x6017: -case 0x6018: -case 0x6019: -case 0x601A: -case 0x601B: -case 0x601C: -case 0x601D: -case 0x601E: -case 0x601F: -case 0x6020: -case 0x6021: -case 0x6022: -case 0x6023: -case 0x6024: -case 0x6025: -case 0x6026: -case 0x6027: -case 0x6028: -case 0x6029: -case 0x602A: -case 0x602B: -case 0x602C: -case 0x602D: -case 0x602E: -case 0x602F: -case 0x6030: -case 0x6031: -case 0x6032: -case 0x6033: -case 0x6034: -case 0x6035: -case 0x6036: -case 0x6037: -case 0x6038: -case 0x6039: -case 0x603A: -case 0x603B: -case 0x603C: -case 0x603D: -case 0x603E: -case 0x603F: -case 0x6040: -case 0x6041: -case 0x6042: -case 0x6043: -case 0x6044: -case 0x6045: -case 0x6046: -case 0x6047: -case 0x6048: -case 0x6049: -case 0x604A: -case 0x604B: -case 0x604C: -case 0x604D: -case 0x604E: -case 0x604F: -case 0x6050: -case 0x6051: -case 0x6052: -case 0x6053: -case 0x6054: -case 0x6055: -case 0x6056: -case 0x6057: -case 0x6058: -case 0x6059: -case 0x605A: -case 0x605B: -case 0x605C: -case 0x605D: -case 0x605E: -case 0x605F: -case 0x6060: -case 0x6061: -case 0x6062: -case 0x6063: -case 0x6064: -case 0x6065: -case 0x6066: -case 0x6067: -case 0x6068: -case 0x6069: -case 0x606A: -case 0x606B: -case 0x606C: -case 0x606D: -case 0x606E: -case 0x606F: -case 0x6070: -case 0x6071: -case 0x6072: -case 0x6073: -case 0x6074: -case 0x6075: -case 0x6076: -case 0x6077: -case 0x6078: -case 0x6079: -case 0x607A: -case 0x607B: -case 0x607C: -case 0x607D: -case 0x607E: -case 0x607F: -case 0x6080: -case 0x6081: -case 0x6082: -case 0x6083: -case 0x6084: -case 0x6085: -case 0x6086: -case 0x6087: -case 0x6088: -case 0x6089: -case 0x608A: -case 0x608B: -case 0x608C: -case 0x608D: -case 0x608E: -case 0x608F: -case 0x6090: -case 0x6091: -case 0x6092: -case 0x6093: -case 0x6094: -case 0x6095: -case 0x6096: -case 0x6097: -case 0x6098: -case 0x6099: -case 0x609A: -case 0x609B: -case 0x609C: -case 0x609D: -case 0x609E: -case 0x609F: -case 0x60A0: -case 0x60A1: -case 0x60A2: -case 0x60A3: -case 0x60A4: -case 0x60A5: -case 0x60A6: -case 0x60A7: -case 0x60A8: -case 0x60A9: -case 0x60AA: -case 0x60AB: -case 0x60AC: -case 0x60AD: -case 0x60AE: -case 0x60AF: -case 0x60B0: -case 0x60B1: -case 0x60B2: -case 0x60B3: -case 0x60B4: -case 0x60B5: -case 0x60B6: -case 0x60B7: -case 0x60B8: -case 0x60B9: -case 0x60BA: -case 0x60BB: -case 0x60BC: -case 0x60BD: -case 0x60BE: -case 0x60BF: -case 0x60C0: -case 0x60C1: -case 0x60C2: -case 0x60C3: -case 0x60C4: -case 0x60C5: -case 0x60C6: -case 0x60C7: -case 0x60C8: -case 0x60C9: -case 0x60CA: -case 0x60CB: -case 0x60CC: -case 0x60CD: -case 0x60CE: -case 0x60CF: -case 0x60D0: -case 0x60D1: -case 0x60D2: -case 0x60D3: -case 0x60D4: -case 0x60D5: -case 0x60D6: -case 0x60D7: -case 0x60D8: -case 0x60D9: -case 0x60DA: -case 0x60DB: -case 0x60DC: -case 0x60DD: -case 0x60DE: -case 0x60DF: -case 0x60E0: -case 0x60E1: -case 0x60E2: -case 0x60E3: -case 0x60E4: -case 0x60E5: -case 0x60E6: -case 0x60E7: -case 0x60E8: -case 0x60E9: -case 0x60EA: -case 0x60EB: -case 0x60EC: -case 0x60ED: -case 0x60EE: -case 0x60EF: -case 0x60F0: -case 0x60F1: -case 0x60F2: -case 0x60F3: -case 0x60F4: -case 0x60F5: -case 0x60F6: -case 0x60F7: -case 0x60F8: -case 0x60F9: -case 0x60FA: -case 0x60FB: -case 0x60FC: -case 0x60FD: -case 0x60FE: -case 0x60FF: - -// BRA -case 0x6001: -{ - PC += (s32)(s8)Opcode; -} -RET(10) - -// BRA16 -case 0x6000: -{ - PC += (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - SET_PC(PC); -} -RET(10) -case 0x6102: -case 0x6103: -case 0x6104: -case 0x6105: -case 0x6106: -case 0x6107: -case 0x6108: -case 0x6109: -case 0x610A: -case 0x610B: -case 0x610C: -case 0x610D: -case 0x610E: -case 0x610F: -case 0x6110: -case 0x6111: -case 0x6112: -case 0x6113: -case 0x6114: -case 0x6115: -case 0x6116: -case 0x6117: -case 0x6118: -case 0x6119: -case 0x611A: -case 0x611B: -case 0x611C: -case 0x611D: -case 0x611E: -case 0x611F: -case 0x6120: -case 0x6121: -case 0x6122: -case 0x6123: -case 0x6124: -case 0x6125: -case 0x6126: -case 0x6127: -case 0x6128: -case 0x6129: -case 0x612A: -case 0x612B: -case 0x612C: -case 0x612D: -case 0x612E: -case 0x612F: -case 0x6130: -case 0x6131: -case 0x6132: -case 0x6133: -case 0x6134: -case 0x6135: -case 0x6136: -case 0x6137: -case 0x6138: -case 0x6139: -case 0x613A: -case 0x613B: -case 0x613C: -case 0x613D: -case 0x613E: -case 0x613F: -case 0x6140: -case 0x6141: -case 0x6142: -case 0x6143: -case 0x6144: -case 0x6145: -case 0x6146: -case 0x6147: -case 0x6148: -case 0x6149: -case 0x614A: -case 0x614B: -case 0x614C: -case 0x614D: -case 0x614E: -case 0x614F: -case 0x6150: -case 0x6151: -case 0x6152: -case 0x6153: -case 0x6154: -case 0x6155: -case 0x6156: -case 0x6157: -case 0x6158: -case 0x6159: -case 0x615A: -case 0x615B: -case 0x615C: -case 0x615D: -case 0x615E: -case 0x615F: -case 0x6160: -case 0x6161: -case 0x6162: -case 0x6163: -case 0x6164: -case 0x6165: -case 0x6166: -case 0x6167: -case 0x6168: -case 0x6169: -case 0x616A: -case 0x616B: -case 0x616C: -case 0x616D: -case 0x616E: -case 0x616F: -case 0x6170: -case 0x6171: -case 0x6172: -case 0x6173: -case 0x6174: -case 0x6175: -case 0x6176: -case 0x6177: -case 0x6178: -case 0x6179: -case 0x617A: -case 0x617B: -case 0x617C: -case 0x617D: -case 0x617E: -case 0x617F: -case 0x6180: -case 0x6181: -case 0x6182: -case 0x6183: -case 0x6184: -case 0x6185: -case 0x6186: -case 0x6187: -case 0x6188: -case 0x6189: -case 0x618A: -case 0x618B: -case 0x618C: -case 0x618D: -case 0x618E: -case 0x618F: -case 0x6190: -case 0x6191: -case 0x6192: -case 0x6193: -case 0x6194: -case 0x6195: -case 0x6196: -case 0x6197: -case 0x6198: -case 0x6199: -case 0x619A: -case 0x619B: -case 0x619C: -case 0x619D: -case 0x619E: -case 0x619F: -case 0x61A0: -case 0x61A1: -case 0x61A2: -case 0x61A3: -case 0x61A4: -case 0x61A5: -case 0x61A6: -case 0x61A7: -case 0x61A8: -case 0x61A9: -case 0x61AA: -case 0x61AB: -case 0x61AC: -case 0x61AD: -case 0x61AE: -case 0x61AF: -case 0x61B0: -case 0x61B1: -case 0x61B2: -case 0x61B3: -case 0x61B4: -case 0x61B5: -case 0x61B6: -case 0x61B7: -case 0x61B8: -case 0x61B9: -case 0x61BA: -case 0x61BB: -case 0x61BC: -case 0x61BD: -case 0x61BE: -case 0x61BF: -case 0x61C0: -case 0x61C1: -case 0x61C2: -case 0x61C3: -case 0x61C4: -case 0x61C5: -case 0x61C6: -case 0x61C7: -case 0x61C8: -case 0x61C9: -case 0x61CA: -case 0x61CB: -case 0x61CC: -case 0x61CD: -case 0x61CE: -case 0x61CF: -case 0x61D0: -case 0x61D1: -case 0x61D2: -case 0x61D3: -case 0x61D4: -case 0x61D5: -case 0x61D6: -case 0x61D7: -case 0x61D8: -case 0x61D9: -case 0x61DA: -case 0x61DB: -case 0x61DC: -case 0x61DD: -case 0x61DE: -case 0x61DF: -case 0x61E0: -case 0x61E1: -case 0x61E2: -case 0x61E3: -case 0x61E4: -case 0x61E5: -case 0x61E6: -case 0x61E7: -case 0x61E8: -case 0x61E9: -case 0x61EA: -case 0x61EB: -case 0x61EC: -case 0x61ED: -case 0x61EE: -case 0x61EF: -case 0x61F0: -case 0x61F1: -case 0x61F2: -case 0x61F3: -case 0x61F4: -case 0x61F5: -case 0x61F6: -case 0x61F7: -case 0x61F8: -case 0x61F9: -case 0x61FA: -case 0x61FB: -case 0x61FC: -case 0x61FD: -case 0x61FE: -case 0x61FF: - -// BSR -case 0x6101: -{ - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PC += (s32)(s8)Opcode; - POST_IO -} -RET(18) - -// BSR16 -case 0x6100: -{ - u32 res; - res = (s32)(s16)FETCH_WORD; - PC -= CPU->BasePC; - PRE_IO - PUSH_32_F(PC + 2) - PC += (s32) res; - SET_PC(PC); - POST_IO -} -RET(18) diff --git a/yabause/src/c68k/c68k_op7.inc b/yabause/src/c68k/c68k_op7.inc deleted file mode 100644 index ba0b48ba31..0000000000 --- a/yabause/src/c68k/c68k_op7.inc +++ /dev/null @@ -1,2058 +0,0 @@ -case 0x7001: -case 0x7002: -case 0x7003: -case 0x7004: -case 0x7005: -case 0x7006: -case 0x7007: -case 0x7008: -case 0x7009: -case 0x700A: -case 0x700B: -case 0x700C: -case 0x700D: -case 0x700E: -case 0x700F: -case 0x7010: -case 0x7011: -case 0x7012: -case 0x7013: -case 0x7014: -case 0x7015: -case 0x7016: -case 0x7017: -case 0x7018: -case 0x7019: -case 0x701A: -case 0x701B: -case 0x701C: -case 0x701D: -case 0x701E: -case 0x701F: -case 0x7020: -case 0x7021: -case 0x7022: -case 0x7023: -case 0x7024: -case 0x7025: -case 0x7026: -case 0x7027: -case 0x7028: -case 0x7029: -case 0x702A: -case 0x702B: -case 0x702C: -case 0x702D: -case 0x702E: -case 0x702F: -case 0x7030: -case 0x7031: -case 0x7032: -case 0x7033: -case 0x7034: -case 0x7035: -case 0x7036: -case 0x7037: -case 0x7038: -case 0x7039: -case 0x703A: -case 0x703B: -case 0x703C: -case 0x703D: -case 0x703E: -case 0x703F: -case 0x7040: -case 0x7041: -case 0x7042: -case 0x7043: -case 0x7044: -case 0x7045: -case 0x7046: -case 0x7047: -case 0x7048: -case 0x7049: -case 0x704A: -case 0x704B: -case 0x704C: -case 0x704D: -case 0x704E: -case 0x704F: -case 0x7050: -case 0x7051: -case 0x7052: -case 0x7053: -case 0x7054: -case 0x7055: -case 0x7056: -case 0x7057: -case 0x7058: -case 0x7059: -case 0x705A: -case 0x705B: -case 0x705C: -case 0x705D: -case 0x705E: -case 0x705F: -case 0x7060: -case 0x7061: -case 0x7062: -case 0x7063: -case 0x7064: -case 0x7065: -case 0x7066: -case 0x7067: -case 0x7068: -case 0x7069: -case 0x706A: -case 0x706B: -case 0x706C: -case 0x706D: -case 0x706E: -case 0x706F: -case 0x7070: -case 0x7071: -case 0x7072: -case 0x7073: -case 0x7074: -case 0x7075: -case 0x7076: -case 0x7077: -case 0x7078: -case 0x7079: -case 0x707A: -case 0x707B: -case 0x707C: -case 0x707D: -case 0x707E: -case 0x707F: -case 0x7080: -case 0x7081: -case 0x7082: -case 0x7083: -case 0x7084: -case 0x7085: -case 0x7086: -case 0x7087: -case 0x7088: -case 0x7089: -case 0x708A: -case 0x708B: -case 0x708C: -case 0x708D: -case 0x708E: -case 0x708F: -case 0x7090: -case 0x7091: -case 0x7092: -case 0x7093: -case 0x7094: -case 0x7095: -case 0x7096: -case 0x7097: -case 0x7098: -case 0x7099: -case 0x709A: -case 0x709B: -case 0x709C: -case 0x709D: -case 0x709E: -case 0x709F: -case 0x70A0: -case 0x70A1: -case 0x70A2: -case 0x70A3: -case 0x70A4: -case 0x70A5: -case 0x70A6: -case 0x70A7: -case 0x70A8: -case 0x70A9: -case 0x70AA: -case 0x70AB: -case 0x70AC: -case 0x70AD: -case 0x70AE: -case 0x70AF: -case 0x70B0: -case 0x70B1: -case 0x70B2: -case 0x70B3: -case 0x70B4: -case 0x70B5: -case 0x70B6: -case 0x70B7: -case 0x70B8: -case 0x70B9: -case 0x70BA: -case 0x70BB: -case 0x70BC: -case 0x70BD: -case 0x70BE: -case 0x70BF: -case 0x70C0: -case 0x70C1: -case 0x70C2: -case 0x70C3: -case 0x70C4: -case 0x70C5: -case 0x70C6: -case 0x70C7: -case 0x70C8: -case 0x70C9: -case 0x70CA: -case 0x70CB: -case 0x70CC: -case 0x70CD: -case 0x70CE: -case 0x70CF: -case 0x70D0: -case 0x70D1: -case 0x70D2: -case 0x70D3: -case 0x70D4: -case 0x70D5: -case 0x70D6: -case 0x70D7: -case 0x70D8: -case 0x70D9: -case 0x70DA: -case 0x70DB: -case 0x70DC: -case 0x70DD: -case 0x70DE: -case 0x70DF: -case 0x70E0: -case 0x70E1: -case 0x70E2: -case 0x70E3: -case 0x70E4: -case 0x70E5: -case 0x70E6: -case 0x70E7: -case 0x70E8: -case 0x70E9: -case 0x70EA: -case 0x70EB: -case 0x70EC: -case 0x70ED: -case 0x70EE: -case 0x70EF: -case 0x70F0: -case 0x70F1: -case 0x70F2: -case 0x70F3: -case 0x70F4: -case 0x70F5: -case 0x70F6: -case 0x70F7: -case 0x70F8: -case 0x70F9: -case 0x70FA: -case 0x70FB: -case 0x70FC: -case 0x70FD: -case 0x70FE: -case 0x70FF: -case 0x7200: -case 0x7201: -case 0x7202: -case 0x7203: -case 0x7204: -case 0x7205: -case 0x7206: -case 0x7207: -case 0x7208: -case 0x7209: -case 0x720A: -case 0x720B: -case 0x720C: -case 0x720D: -case 0x720E: -case 0x720F: -case 0x7210: -case 0x7211: -case 0x7212: -case 0x7213: -case 0x7214: -case 0x7215: -case 0x7216: -case 0x7217: -case 0x7218: -case 0x7219: -case 0x721A: -case 0x721B: -case 0x721C: -case 0x721D: -case 0x721E: -case 0x721F: -case 0x7220: -case 0x7221: -case 0x7222: -case 0x7223: -case 0x7224: -case 0x7225: -case 0x7226: -case 0x7227: -case 0x7228: -case 0x7229: -case 0x722A: -case 0x722B: -case 0x722C: -case 0x722D: -case 0x722E: -case 0x722F: -case 0x7230: -case 0x7231: -case 0x7232: -case 0x7233: -case 0x7234: -case 0x7235: -case 0x7236: -case 0x7237: -case 0x7238: -case 0x7239: -case 0x723A: -case 0x723B: -case 0x723C: -case 0x723D: -case 0x723E: -case 0x723F: -case 0x7240: -case 0x7241: -case 0x7242: -case 0x7243: -case 0x7244: -case 0x7245: -case 0x7246: -case 0x7247: -case 0x7248: -case 0x7249: -case 0x724A: -case 0x724B: -case 0x724C: -case 0x724D: -case 0x724E: -case 0x724F: -case 0x7250: -case 0x7251: -case 0x7252: -case 0x7253: -case 0x7254: -case 0x7255: -case 0x7256: -case 0x7257: -case 0x7258: -case 0x7259: -case 0x725A: -case 0x725B: -case 0x725C: -case 0x725D: -case 0x725E: -case 0x725F: -case 0x7260: -case 0x7261: -case 0x7262: -case 0x7263: -case 0x7264: -case 0x7265: -case 0x7266: -case 0x7267: -case 0x7268: -case 0x7269: -case 0x726A: -case 0x726B: -case 0x726C: -case 0x726D: -case 0x726E: -case 0x726F: -case 0x7270: -case 0x7271: -case 0x7272: -case 0x7273: -case 0x7274: -case 0x7275: -case 0x7276: -case 0x7277: -case 0x7278: -case 0x7279: -case 0x727A: -case 0x727B: -case 0x727C: -case 0x727D: -case 0x727E: -case 0x727F: -case 0x7280: -case 0x7281: -case 0x7282: -case 0x7283: -case 0x7284: -case 0x7285: -case 0x7286: -case 0x7287: -case 0x7288: -case 0x7289: -case 0x728A: -case 0x728B: -case 0x728C: -case 0x728D: -case 0x728E: -case 0x728F: -case 0x7290: -case 0x7291: -case 0x7292: -case 0x7293: -case 0x7294: -case 0x7295: -case 0x7296: -case 0x7297: -case 0x7298: -case 0x7299: -case 0x729A: -case 0x729B: -case 0x729C: -case 0x729D: -case 0x729E: -case 0x729F: -case 0x72A0: -case 0x72A1: -case 0x72A2: -case 0x72A3: -case 0x72A4: -case 0x72A5: -case 0x72A6: -case 0x72A7: -case 0x72A8: -case 0x72A9: -case 0x72AA: -case 0x72AB: -case 0x72AC: -case 0x72AD: -case 0x72AE: -case 0x72AF: -case 0x72B0: -case 0x72B1: -case 0x72B2: -case 0x72B3: -case 0x72B4: -case 0x72B5: -case 0x72B6: -case 0x72B7: -case 0x72B8: -case 0x72B9: -case 0x72BA: -case 0x72BB: -case 0x72BC: -case 0x72BD: -case 0x72BE: -case 0x72BF: -case 0x72C0: -case 0x72C1: -case 0x72C2: -case 0x72C3: -case 0x72C4: -case 0x72C5: -case 0x72C6: -case 0x72C7: -case 0x72C8: -case 0x72C9: -case 0x72CA: -case 0x72CB: -case 0x72CC: -case 0x72CD: -case 0x72CE: -case 0x72CF: -case 0x72D0: -case 0x72D1: -case 0x72D2: -case 0x72D3: -case 0x72D4: -case 0x72D5: -case 0x72D6: -case 0x72D7: -case 0x72D8: -case 0x72D9: -case 0x72DA: -case 0x72DB: -case 0x72DC: -case 0x72DD: -case 0x72DE: -case 0x72DF: -case 0x72E0: -case 0x72E1: -case 0x72E2: -case 0x72E3: -case 0x72E4: -case 0x72E5: -case 0x72E6: -case 0x72E7: -case 0x72E8: -case 0x72E9: -case 0x72EA: -case 0x72EB: -case 0x72EC: -case 0x72ED: -case 0x72EE: -case 0x72EF: -case 0x72F0: -case 0x72F1: -case 0x72F2: -case 0x72F3: -case 0x72F4: -case 0x72F5: -case 0x72F6: -case 0x72F7: -case 0x72F8: -case 0x72F9: -case 0x72FA: -case 0x72FB: -case 0x72FC: -case 0x72FD: -case 0x72FE: -case 0x72FF: -case 0x7400: -case 0x7401: -case 0x7402: -case 0x7403: -case 0x7404: -case 0x7405: -case 0x7406: -case 0x7407: -case 0x7408: -case 0x7409: -case 0x740A: -case 0x740B: -case 0x740C: -case 0x740D: -case 0x740E: -case 0x740F: -case 0x7410: -case 0x7411: -case 0x7412: -case 0x7413: -case 0x7414: -case 0x7415: -case 0x7416: -case 0x7417: -case 0x7418: -case 0x7419: -case 0x741A: -case 0x741B: -case 0x741C: -case 0x741D: -case 0x741E: -case 0x741F: -case 0x7420: -case 0x7421: -case 0x7422: -case 0x7423: -case 0x7424: -case 0x7425: -case 0x7426: -case 0x7427: -case 0x7428: -case 0x7429: -case 0x742A: -case 0x742B: -case 0x742C: -case 0x742D: -case 0x742E: -case 0x742F: -case 0x7430: -case 0x7431: -case 0x7432: -case 0x7433: -case 0x7434: -case 0x7435: -case 0x7436: -case 0x7437: -case 0x7438: -case 0x7439: -case 0x743A: -case 0x743B: -case 0x743C: -case 0x743D: -case 0x743E: -case 0x743F: -case 0x7440: -case 0x7441: -case 0x7442: -case 0x7443: -case 0x7444: -case 0x7445: -case 0x7446: -case 0x7447: -case 0x7448: -case 0x7449: -case 0x744A: -case 0x744B: -case 0x744C: -case 0x744D: -case 0x744E: -case 0x744F: -case 0x7450: -case 0x7451: -case 0x7452: -case 0x7453: -case 0x7454: -case 0x7455: -case 0x7456: -case 0x7457: -case 0x7458: -case 0x7459: -case 0x745A: -case 0x745B: -case 0x745C: -case 0x745D: -case 0x745E: -case 0x745F: -case 0x7460: -case 0x7461: -case 0x7462: -case 0x7463: -case 0x7464: -case 0x7465: -case 0x7466: -case 0x7467: -case 0x7468: -case 0x7469: -case 0x746A: -case 0x746B: -case 0x746C: -case 0x746D: -case 0x746E: -case 0x746F: -case 0x7470: -case 0x7471: -case 0x7472: -case 0x7473: -case 0x7474: -case 0x7475: -case 0x7476: -case 0x7477: -case 0x7478: -case 0x7479: -case 0x747A: -case 0x747B: -case 0x747C: -case 0x747D: -case 0x747E: -case 0x747F: -case 0x7480: -case 0x7481: -case 0x7482: -case 0x7483: -case 0x7484: -case 0x7485: -case 0x7486: -case 0x7487: -case 0x7488: -case 0x7489: -case 0x748A: -case 0x748B: -case 0x748C: -case 0x748D: -case 0x748E: -case 0x748F: -case 0x7490: -case 0x7491: -case 0x7492: -case 0x7493: -case 0x7494: -case 0x7495: -case 0x7496: -case 0x7497: -case 0x7498: -case 0x7499: -case 0x749A: -case 0x749B: -case 0x749C: -case 0x749D: -case 0x749E: -case 0x749F: -case 0x74A0: -case 0x74A1: -case 0x74A2: -case 0x74A3: -case 0x74A4: -case 0x74A5: -case 0x74A6: -case 0x74A7: -case 0x74A8: -case 0x74A9: -case 0x74AA: -case 0x74AB: -case 0x74AC: -case 0x74AD: -case 0x74AE: -case 0x74AF: -case 0x74B0: -case 0x74B1: -case 0x74B2: -case 0x74B3: -case 0x74B4: -case 0x74B5: -case 0x74B6: -case 0x74B7: -case 0x74B8: -case 0x74B9: -case 0x74BA: -case 0x74BB: -case 0x74BC: -case 0x74BD: -case 0x74BE: -case 0x74BF: -case 0x74C0: -case 0x74C1: -case 0x74C2: -case 0x74C3: -case 0x74C4: -case 0x74C5: -case 0x74C6: -case 0x74C7: -case 0x74C8: -case 0x74C9: -case 0x74CA: -case 0x74CB: -case 0x74CC: -case 0x74CD: -case 0x74CE: -case 0x74CF: -case 0x74D0: -case 0x74D1: -case 0x74D2: -case 0x74D3: -case 0x74D4: -case 0x74D5: -case 0x74D6: -case 0x74D7: -case 0x74D8: -case 0x74D9: -case 0x74DA: -case 0x74DB: -case 0x74DC: -case 0x74DD: -case 0x74DE: -case 0x74DF: -case 0x74E0: -case 0x74E1: -case 0x74E2: -case 0x74E3: -case 0x74E4: -case 0x74E5: -case 0x74E6: -case 0x74E7: -case 0x74E8: -case 0x74E9: -case 0x74EA: -case 0x74EB: -case 0x74EC: -case 0x74ED: -case 0x74EE: -case 0x74EF: -case 0x74F0: -case 0x74F1: -case 0x74F2: -case 0x74F3: -case 0x74F4: -case 0x74F5: -case 0x74F6: -case 0x74F7: -case 0x74F8: -case 0x74F9: -case 0x74FA: -case 0x74FB: -case 0x74FC: -case 0x74FD: -case 0x74FE: -case 0x74FF: -case 0x7600: -case 0x7601: -case 0x7602: -case 0x7603: -case 0x7604: -case 0x7605: -case 0x7606: -case 0x7607: -case 0x7608: -case 0x7609: -case 0x760A: -case 0x760B: -case 0x760C: -case 0x760D: -case 0x760E: -case 0x760F: -case 0x7610: -case 0x7611: -case 0x7612: -case 0x7613: -case 0x7614: -case 0x7615: -case 0x7616: -case 0x7617: -case 0x7618: -case 0x7619: -case 0x761A: -case 0x761B: -case 0x761C: -case 0x761D: -case 0x761E: -case 0x761F: -case 0x7620: -case 0x7621: -case 0x7622: -case 0x7623: -case 0x7624: -case 0x7625: -case 0x7626: -case 0x7627: -case 0x7628: -case 0x7629: -case 0x762A: -case 0x762B: -case 0x762C: -case 0x762D: -case 0x762E: -case 0x762F: -case 0x7630: -case 0x7631: -case 0x7632: -case 0x7633: -case 0x7634: -case 0x7635: -case 0x7636: -case 0x7637: -case 0x7638: -case 0x7639: -case 0x763A: -case 0x763B: -case 0x763C: -case 0x763D: -case 0x763E: -case 0x763F: -case 0x7640: -case 0x7641: -case 0x7642: -case 0x7643: -case 0x7644: -case 0x7645: -case 0x7646: -case 0x7647: -case 0x7648: -case 0x7649: -case 0x764A: -case 0x764B: -case 0x764C: -case 0x764D: -case 0x764E: -case 0x764F: -case 0x7650: -case 0x7651: -case 0x7652: -case 0x7653: -case 0x7654: -case 0x7655: -case 0x7656: -case 0x7657: -case 0x7658: -case 0x7659: -case 0x765A: -case 0x765B: -case 0x765C: -case 0x765D: -case 0x765E: -case 0x765F: -case 0x7660: -case 0x7661: -case 0x7662: -case 0x7663: -case 0x7664: -case 0x7665: -case 0x7666: -case 0x7667: -case 0x7668: -case 0x7669: -case 0x766A: -case 0x766B: -case 0x766C: -case 0x766D: -case 0x766E: -case 0x766F: -case 0x7670: -case 0x7671: -case 0x7672: -case 0x7673: -case 0x7674: -case 0x7675: -case 0x7676: -case 0x7677: -case 0x7678: -case 0x7679: -case 0x767A: -case 0x767B: -case 0x767C: -case 0x767D: -case 0x767E: -case 0x767F: -case 0x7680: -case 0x7681: -case 0x7682: -case 0x7683: -case 0x7684: -case 0x7685: -case 0x7686: -case 0x7687: -case 0x7688: -case 0x7689: -case 0x768A: -case 0x768B: -case 0x768C: -case 0x768D: -case 0x768E: -case 0x768F: -case 0x7690: -case 0x7691: -case 0x7692: -case 0x7693: -case 0x7694: -case 0x7695: -case 0x7696: -case 0x7697: -case 0x7698: -case 0x7699: -case 0x769A: -case 0x769B: -case 0x769C: -case 0x769D: -case 0x769E: -case 0x769F: -case 0x76A0: -case 0x76A1: -case 0x76A2: -case 0x76A3: -case 0x76A4: -case 0x76A5: -case 0x76A6: -case 0x76A7: -case 0x76A8: -case 0x76A9: -case 0x76AA: -case 0x76AB: -case 0x76AC: -case 0x76AD: -case 0x76AE: -case 0x76AF: -case 0x76B0: -case 0x76B1: -case 0x76B2: -case 0x76B3: -case 0x76B4: -case 0x76B5: -case 0x76B6: -case 0x76B7: -case 0x76B8: -case 0x76B9: -case 0x76BA: -case 0x76BB: -case 0x76BC: -case 0x76BD: -case 0x76BE: -case 0x76BF: -case 0x76C0: -case 0x76C1: -case 0x76C2: -case 0x76C3: -case 0x76C4: -case 0x76C5: -case 0x76C6: -case 0x76C7: -case 0x76C8: -case 0x76C9: -case 0x76CA: -case 0x76CB: -case 0x76CC: -case 0x76CD: -case 0x76CE: -case 0x76CF: -case 0x76D0: -case 0x76D1: -case 0x76D2: -case 0x76D3: -case 0x76D4: -case 0x76D5: -case 0x76D6: -case 0x76D7: -case 0x76D8: -case 0x76D9: -case 0x76DA: -case 0x76DB: -case 0x76DC: -case 0x76DD: -case 0x76DE: -case 0x76DF: -case 0x76E0: -case 0x76E1: -case 0x76E2: -case 0x76E3: -case 0x76E4: -case 0x76E5: -case 0x76E6: -case 0x76E7: -case 0x76E8: -case 0x76E9: -case 0x76EA: -case 0x76EB: -case 0x76EC: -case 0x76ED: -case 0x76EE: -case 0x76EF: -case 0x76F0: -case 0x76F1: -case 0x76F2: -case 0x76F3: -case 0x76F4: -case 0x76F5: -case 0x76F6: -case 0x76F7: -case 0x76F8: -case 0x76F9: -case 0x76FA: -case 0x76FB: -case 0x76FC: -case 0x76FD: -case 0x76FE: -case 0x76FF: -case 0x7800: -case 0x7801: -case 0x7802: -case 0x7803: -case 0x7804: -case 0x7805: -case 0x7806: -case 0x7807: -case 0x7808: -case 0x7809: -case 0x780A: -case 0x780B: -case 0x780C: -case 0x780D: -case 0x780E: -case 0x780F: -case 0x7810: -case 0x7811: -case 0x7812: -case 0x7813: -case 0x7814: -case 0x7815: -case 0x7816: -case 0x7817: -case 0x7818: -case 0x7819: -case 0x781A: -case 0x781B: -case 0x781C: -case 0x781D: -case 0x781E: -case 0x781F: -case 0x7820: -case 0x7821: -case 0x7822: -case 0x7823: -case 0x7824: -case 0x7825: -case 0x7826: -case 0x7827: -case 0x7828: -case 0x7829: -case 0x782A: -case 0x782B: -case 0x782C: -case 0x782D: -case 0x782E: -case 0x782F: -case 0x7830: -case 0x7831: -case 0x7832: -case 0x7833: -case 0x7834: -case 0x7835: -case 0x7836: -case 0x7837: -case 0x7838: -case 0x7839: -case 0x783A: -case 0x783B: -case 0x783C: -case 0x783D: -case 0x783E: -case 0x783F: -case 0x7840: -case 0x7841: -case 0x7842: -case 0x7843: -case 0x7844: -case 0x7845: -case 0x7846: -case 0x7847: -case 0x7848: -case 0x7849: -case 0x784A: -case 0x784B: -case 0x784C: -case 0x784D: -case 0x784E: -case 0x784F: -case 0x7850: -case 0x7851: -case 0x7852: -case 0x7853: -case 0x7854: -case 0x7855: -case 0x7856: -case 0x7857: -case 0x7858: -case 0x7859: -case 0x785A: -case 0x785B: -case 0x785C: -case 0x785D: -case 0x785E: -case 0x785F: -case 0x7860: -case 0x7861: -case 0x7862: -case 0x7863: -case 0x7864: -case 0x7865: -case 0x7866: -case 0x7867: -case 0x7868: -case 0x7869: -case 0x786A: -case 0x786B: -case 0x786C: -case 0x786D: -case 0x786E: -case 0x786F: -case 0x7870: -case 0x7871: -case 0x7872: -case 0x7873: -case 0x7874: -case 0x7875: -case 0x7876: -case 0x7877: -case 0x7878: -case 0x7879: -case 0x787A: -case 0x787B: -case 0x787C: -case 0x787D: -case 0x787E: -case 0x787F: -case 0x7880: -case 0x7881: -case 0x7882: -case 0x7883: -case 0x7884: -case 0x7885: -case 0x7886: -case 0x7887: -case 0x7888: -case 0x7889: -case 0x788A: -case 0x788B: -case 0x788C: -case 0x788D: -case 0x788E: -case 0x788F: -case 0x7890: -case 0x7891: -case 0x7892: -case 0x7893: -case 0x7894: -case 0x7895: -case 0x7896: -case 0x7897: -case 0x7898: -case 0x7899: -case 0x789A: -case 0x789B: -case 0x789C: -case 0x789D: -case 0x789E: -case 0x789F: -case 0x78A0: -case 0x78A1: -case 0x78A2: -case 0x78A3: -case 0x78A4: -case 0x78A5: -case 0x78A6: -case 0x78A7: -case 0x78A8: -case 0x78A9: -case 0x78AA: -case 0x78AB: -case 0x78AC: -case 0x78AD: -case 0x78AE: -case 0x78AF: -case 0x78B0: -case 0x78B1: -case 0x78B2: -case 0x78B3: -case 0x78B4: -case 0x78B5: -case 0x78B6: -case 0x78B7: -case 0x78B8: -case 0x78B9: -case 0x78BA: -case 0x78BB: -case 0x78BC: -case 0x78BD: -case 0x78BE: -case 0x78BF: -case 0x78C0: -case 0x78C1: -case 0x78C2: -case 0x78C3: -case 0x78C4: -case 0x78C5: -case 0x78C6: -case 0x78C7: -case 0x78C8: -case 0x78C9: -case 0x78CA: -case 0x78CB: -case 0x78CC: -case 0x78CD: -case 0x78CE: -case 0x78CF: -case 0x78D0: -case 0x78D1: -case 0x78D2: -case 0x78D3: -case 0x78D4: -case 0x78D5: -case 0x78D6: -case 0x78D7: -case 0x78D8: -case 0x78D9: -case 0x78DA: -case 0x78DB: -case 0x78DC: -case 0x78DD: -case 0x78DE: -case 0x78DF: -case 0x78E0: -case 0x78E1: -case 0x78E2: -case 0x78E3: -case 0x78E4: -case 0x78E5: -case 0x78E6: -case 0x78E7: -case 0x78E8: -case 0x78E9: -case 0x78EA: -case 0x78EB: -case 0x78EC: -case 0x78ED: -case 0x78EE: -case 0x78EF: -case 0x78F0: -case 0x78F1: -case 0x78F2: -case 0x78F3: -case 0x78F4: -case 0x78F5: -case 0x78F6: -case 0x78F7: -case 0x78F8: -case 0x78F9: -case 0x78FA: -case 0x78FB: -case 0x78FC: -case 0x78FD: -case 0x78FE: -case 0x78FF: -case 0x7A00: -case 0x7A01: -case 0x7A02: -case 0x7A03: -case 0x7A04: -case 0x7A05: -case 0x7A06: -case 0x7A07: -case 0x7A08: -case 0x7A09: -case 0x7A0A: -case 0x7A0B: -case 0x7A0C: -case 0x7A0D: -case 0x7A0E: -case 0x7A0F: -case 0x7A10: -case 0x7A11: -case 0x7A12: -case 0x7A13: -case 0x7A14: -case 0x7A15: -case 0x7A16: -case 0x7A17: -case 0x7A18: -case 0x7A19: -case 0x7A1A: -case 0x7A1B: -case 0x7A1C: -case 0x7A1D: -case 0x7A1E: -case 0x7A1F: -case 0x7A20: -case 0x7A21: -case 0x7A22: -case 0x7A23: -case 0x7A24: -case 0x7A25: -case 0x7A26: -case 0x7A27: -case 0x7A28: -case 0x7A29: -case 0x7A2A: -case 0x7A2B: -case 0x7A2C: -case 0x7A2D: -case 0x7A2E: -case 0x7A2F: -case 0x7A30: -case 0x7A31: -case 0x7A32: -case 0x7A33: -case 0x7A34: -case 0x7A35: -case 0x7A36: -case 0x7A37: -case 0x7A38: -case 0x7A39: -case 0x7A3A: -case 0x7A3B: -case 0x7A3C: -case 0x7A3D: -case 0x7A3E: -case 0x7A3F: -case 0x7A40: -case 0x7A41: -case 0x7A42: -case 0x7A43: -case 0x7A44: -case 0x7A45: -case 0x7A46: -case 0x7A47: -case 0x7A48: -case 0x7A49: -case 0x7A4A: -case 0x7A4B: -case 0x7A4C: -case 0x7A4D: -case 0x7A4E: -case 0x7A4F: -case 0x7A50: -case 0x7A51: -case 0x7A52: -case 0x7A53: -case 0x7A54: -case 0x7A55: -case 0x7A56: -case 0x7A57: -case 0x7A58: -case 0x7A59: -case 0x7A5A: -case 0x7A5B: -case 0x7A5C: -case 0x7A5D: -case 0x7A5E: -case 0x7A5F: -case 0x7A60: -case 0x7A61: -case 0x7A62: -case 0x7A63: -case 0x7A64: -case 0x7A65: -case 0x7A66: -case 0x7A67: -case 0x7A68: -case 0x7A69: -case 0x7A6A: -case 0x7A6B: -case 0x7A6C: -case 0x7A6D: -case 0x7A6E: -case 0x7A6F: -case 0x7A70: -case 0x7A71: -case 0x7A72: -case 0x7A73: -case 0x7A74: -case 0x7A75: -case 0x7A76: -case 0x7A77: -case 0x7A78: -case 0x7A79: -case 0x7A7A: -case 0x7A7B: -case 0x7A7C: -case 0x7A7D: -case 0x7A7E: -case 0x7A7F: -case 0x7A80: -case 0x7A81: -case 0x7A82: -case 0x7A83: -case 0x7A84: -case 0x7A85: -case 0x7A86: -case 0x7A87: -case 0x7A88: -case 0x7A89: -case 0x7A8A: -case 0x7A8B: -case 0x7A8C: -case 0x7A8D: -case 0x7A8E: -case 0x7A8F: -case 0x7A90: -case 0x7A91: -case 0x7A92: -case 0x7A93: -case 0x7A94: -case 0x7A95: -case 0x7A96: -case 0x7A97: -case 0x7A98: -case 0x7A99: -case 0x7A9A: -case 0x7A9B: -case 0x7A9C: -case 0x7A9D: -case 0x7A9E: -case 0x7A9F: -case 0x7AA0: -case 0x7AA1: -case 0x7AA2: -case 0x7AA3: -case 0x7AA4: -case 0x7AA5: -case 0x7AA6: -case 0x7AA7: -case 0x7AA8: -case 0x7AA9: -case 0x7AAA: -case 0x7AAB: -case 0x7AAC: -case 0x7AAD: -case 0x7AAE: -case 0x7AAF: -case 0x7AB0: -case 0x7AB1: -case 0x7AB2: -case 0x7AB3: -case 0x7AB4: -case 0x7AB5: -case 0x7AB6: -case 0x7AB7: -case 0x7AB8: -case 0x7AB9: -case 0x7ABA: -case 0x7ABB: -case 0x7ABC: -case 0x7ABD: -case 0x7ABE: -case 0x7ABF: -case 0x7AC0: -case 0x7AC1: -case 0x7AC2: -case 0x7AC3: -case 0x7AC4: -case 0x7AC5: -case 0x7AC6: -case 0x7AC7: -case 0x7AC8: -case 0x7AC9: -case 0x7ACA: -case 0x7ACB: -case 0x7ACC: -case 0x7ACD: -case 0x7ACE: -case 0x7ACF: -case 0x7AD0: -case 0x7AD1: -case 0x7AD2: -case 0x7AD3: -case 0x7AD4: -case 0x7AD5: -case 0x7AD6: -case 0x7AD7: -case 0x7AD8: -case 0x7AD9: -case 0x7ADA: -case 0x7ADB: -case 0x7ADC: -case 0x7ADD: -case 0x7ADE: -case 0x7ADF: -case 0x7AE0: -case 0x7AE1: -case 0x7AE2: -case 0x7AE3: -case 0x7AE4: -case 0x7AE5: -case 0x7AE6: -case 0x7AE7: -case 0x7AE8: -case 0x7AE9: -case 0x7AEA: -case 0x7AEB: -case 0x7AEC: -case 0x7AED: -case 0x7AEE: -case 0x7AEF: -case 0x7AF0: -case 0x7AF1: -case 0x7AF2: -case 0x7AF3: -case 0x7AF4: -case 0x7AF5: -case 0x7AF6: -case 0x7AF7: -case 0x7AF8: -case 0x7AF9: -case 0x7AFA: -case 0x7AFB: -case 0x7AFC: -case 0x7AFD: -case 0x7AFE: -case 0x7AFF: -case 0x7C00: -case 0x7C01: -case 0x7C02: -case 0x7C03: -case 0x7C04: -case 0x7C05: -case 0x7C06: -case 0x7C07: -case 0x7C08: -case 0x7C09: -case 0x7C0A: -case 0x7C0B: -case 0x7C0C: -case 0x7C0D: -case 0x7C0E: -case 0x7C0F: -case 0x7C10: -case 0x7C11: -case 0x7C12: -case 0x7C13: -case 0x7C14: -case 0x7C15: -case 0x7C16: -case 0x7C17: -case 0x7C18: -case 0x7C19: -case 0x7C1A: -case 0x7C1B: -case 0x7C1C: -case 0x7C1D: -case 0x7C1E: -case 0x7C1F: -case 0x7C20: -case 0x7C21: -case 0x7C22: -case 0x7C23: -case 0x7C24: -case 0x7C25: -case 0x7C26: -case 0x7C27: -case 0x7C28: -case 0x7C29: -case 0x7C2A: -case 0x7C2B: -case 0x7C2C: -case 0x7C2D: -case 0x7C2E: -case 0x7C2F: -case 0x7C30: -case 0x7C31: -case 0x7C32: -case 0x7C33: -case 0x7C34: -case 0x7C35: -case 0x7C36: -case 0x7C37: -case 0x7C38: -case 0x7C39: -case 0x7C3A: -case 0x7C3B: -case 0x7C3C: -case 0x7C3D: -case 0x7C3E: -case 0x7C3F: -case 0x7C40: -case 0x7C41: -case 0x7C42: -case 0x7C43: -case 0x7C44: -case 0x7C45: -case 0x7C46: -case 0x7C47: -case 0x7C48: -case 0x7C49: -case 0x7C4A: -case 0x7C4B: -case 0x7C4C: -case 0x7C4D: -case 0x7C4E: -case 0x7C4F: -case 0x7C50: -case 0x7C51: -case 0x7C52: -case 0x7C53: -case 0x7C54: -case 0x7C55: -case 0x7C56: -case 0x7C57: -case 0x7C58: -case 0x7C59: -case 0x7C5A: -case 0x7C5B: -case 0x7C5C: -case 0x7C5D: -case 0x7C5E: -case 0x7C5F: -case 0x7C60: -case 0x7C61: -case 0x7C62: -case 0x7C63: -case 0x7C64: -case 0x7C65: -case 0x7C66: -case 0x7C67: -case 0x7C68: -case 0x7C69: -case 0x7C6A: -case 0x7C6B: -case 0x7C6C: -case 0x7C6D: -case 0x7C6E: -case 0x7C6F: -case 0x7C70: -case 0x7C71: -case 0x7C72: -case 0x7C73: -case 0x7C74: -case 0x7C75: -case 0x7C76: -case 0x7C77: -case 0x7C78: -case 0x7C79: -case 0x7C7A: -case 0x7C7B: -case 0x7C7C: -case 0x7C7D: -case 0x7C7E: -case 0x7C7F: -case 0x7C80: -case 0x7C81: -case 0x7C82: -case 0x7C83: -case 0x7C84: -case 0x7C85: -case 0x7C86: -case 0x7C87: -case 0x7C88: -case 0x7C89: -case 0x7C8A: -case 0x7C8B: -case 0x7C8C: -case 0x7C8D: -case 0x7C8E: -case 0x7C8F: -case 0x7C90: -case 0x7C91: -case 0x7C92: -case 0x7C93: -case 0x7C94: -case 0x7C95: -case 0x7C96: -case 0x7C97: -case 0x7C98: -case 0x7C99: -case 0x7C9A: -case 0x7C9B: -case 0x7C9C: -case 0x7C9D: -case 0x7C9E: -case 0x7C9F: -case 0x7CA0: -case 0x7CA1: -case 0x7CA2: -case 0x7CA3: -case 0x7CA4: -case 0x7CA5: -case 0x7CA6: -case 0x7CA7: -case 0x7CA8: -case 0x7CA9: -case 0x7CAA: -case 0x7CAB: -case 0x7CAC: -case 0x7CAD: -case 0x7CAE: -case 0x7CAF: -case 0x7CB0: -case 0x7CB1: -case 0x7CB2: -case 0x7CB3: -case 0x7CB4: -case 0x7CB5: -case 0x7CB6: -case 0x7CB7: -case 0x7CB8: -case 0x7CB9: -case 0x7CBA: -case 0x7CBB: -case 0x7CBC: -case 0x7CBD: -case 0x7CBE: -case 0x7CBF: -case 0x7CC0: -case 0x7CC1: -case 0x7CC2: -case 0x7CC3: -case 0x7CC4: -case 0x7CC5: -case 0x7CC6: -case 0x7CC7: -case 0x7CC8: -case 0x7CC9: -case 0x7CCA: -case 0x7CCB: -case 0x7CCC: -case 0x7CCD: -case 0x7CCE: -case 0x7CCF: -case 0x7CD0: -case 0x7CD1: -case 0x7CD2: -case 0x7CD3: -case 0x7CD4: -case 0x7CD5: -case 0x7CD6: -case 0x7CD7: -case 0x7CD8: -case 0x7CD9: -case 0x7CDA: -case 0x7CDB: -case 0x7CDC: -case 0x7CDD: -case 0x7CDE: -case 0x7CDF: -case 0x7CE0: -case 0x7CE1: -case 0x7CE2: -case 0x7CE3: -case 0x7CE4: -case 0x7CE5: -case 0x7CE6: -case 0x7CE7: -case 0x7CE8: -case 0x7CE9: -case 0x7CEA: -case 0x7CEB: -case 0x7CEC: -case 0x7CED: -case 0x7CEE: -case 0x7CEF: -case 0x7CF0: -case 0x7CF1: -case 0x7CF2: -case 0x7CF3: -case 0x7CF4: -case 0x7CF5: -case 0x7CF6: -case 0x7CF7: -case 0x7CF8: -case 0x7CF9: -case 0x7CFA: -case 0x7CFB: -case 0x7CFC: -case 0x7CFD: -case 0x7CFE: -case 0x7CFF: -case 0x7E00: -case 0x7E01: -case 0x7E02: -case 0x7E03: -case 0x7E04: -case 0x7E05: -case 0x7E06: -case 0x7E07: -case 0x7E08: -case 0x7E09: -case 0x7E0A: -case 0x7E0B: -case 0x7E0C: -case 0x7E0D: -case 0x7E0E: -case 0x7E0F: -case 0x7E10: -case 0x7E11: -case 0x7E12: -case 0x7E13: -case 0x7E14: -case 0x7E15: -case 0x7E16: -case 0x7E17: -case 0x7E18: -case 0x7E19: -case 0x7E1A: -case 0x7E1B: -case 0x7E1C: -case 0x7E1D: -case 0x7E1E: -case 0x7E1F: -case 0x7E20: -case 0x7E21: -case 0x7E22: -case 0x7E23: -case 0x7E24: -case 0x7E25: -case 0x7E26: -case 0x7E27: -case 0x7E28: -case 0x7E29: -case 0x7E2A: -case 0x7E2B: -case 0x7E2C: -case 0x7E2D: -case 0x7E2E: -case 0x7E2F: -case 0x7E30: -case 0x7E31: -case 0x7E32: -case 0x7E33: -case 0x7E34: -case 0x7E35: -case 0x7E36: -case 0x7E37: -case 0x7E38: -case 0x7E39: -case 0x7E3A: -case 0x7E3B: -case 0x7E3C: -case 0x7E3D: -case 0x7E3E: -case 0x7E3F: -case 0x7E40: -case 0x7E41: -case 0x7E42: -case 0x7E43: -case 0x7E44: -case 0x7E45: -case 0x7E46: -case 0x7E47: -case 0x7E48: -case 0x7E49: -case 0x7E4A: -case 0x7E4B: -case 0x7E4C: -case 0x7E4D: -case 0x7E4E: -case 0x7E4F: -case 0x7E50: -case 0x7E51: -case 0x7E52: -case 0x7E53: -case 0x7E54: -case 0x7E55: -case 0x7E56: -case 0x7E57: -case 0x7E58: -case 0x7E59: -case 0x7E5A: -case 0x7E5B: -case 0x7E5C: -case 0x7E5D: -case 0x7E5E: -case 0x7E5F: -case 0x7E60: -case 0x7E61: -case 0x7E62: -case 0x7E63: -case 0x7E64: -case 0x7E65: -case 0x7E66: -case 0x7E67: -case 0x7E68: -case 0x7E69: -case 0x7E6A: -case 0x7E6B: -case 0x7E6C: -case 0x7E6D: -case 0x7E6E: -case 0x7E6F: -case 0x7E70: -case 0x7E71: -case 0x7E72: -case 0x7E73: -case 0x7E74: -case 0x7E75: -case 0x7E76: -case 0x7E77: -case 0x7E78: -case 0x7E79: -case 0x7E7A: -case 0x7E7B: -case 0x7E7C: -case 0x7E7D: -case 0x7E7E: -case 0x7E7F: -case 0x7E80: -case 0x7E81: -case 0x7E82: -case 0x7E83: -case 0x7E84: -case 0x7E85: -case 0x7E86: -case 0x7E87: -case 0x7E88: -case 0x7E89: -case 0x7E8A: -case 0x7E8B: -case 0x7E8C: -case 0x7E8D: -case 0x7E8E: -case 0x7E8F: -case 0x7E90: -case 0x7E91: -case 0x7E92: -case 0x7E93: -case 0x7E94: -case 0x7E95: -case 0x7E96: -case 0x7E97: -case 0x7E98: -case 0x7E99: -case 0x7E9A: -case 0x7E9B: -case 0x7E9C: -case 0x7E9D: -case 0x7E9E: -case 0x7E9F: -case 0x7EA0: -case 0x7EA1: -case 0x7EA2: -case 0x7EA3: -case 0x7EA4: -case 0x7EA5: -case 0x7EA6: -case 0x7EA7: -case 0x7EA8: -case 0x7EA9: -case 0x7EAA: -case 0x7EAB: -case 0x7EAC: -case 0x7EAD: -case 0x7EAE: -case 0x7EAF: -case 0x7EB0: -case 0x7EB1: -case 0x7EB2: -case 0x7EB3: -case 0x7EB4: -case 0x7EB5: -case 0x7EB6: -case 0x7EB7: -case 0x7EB8: -case 0x7EB9: -case 0x7EBA: -case 0x7EBB: -case 0x7EBC: -case 0x7EBD: -case 0x7EBE: -case 0x7EBF: -case 0x7EC0: -case 0x7EC1: -case 0x7EC2: -case 0x7EC3: -case 0x7EC4: -case 0x7EC5: -case 0x7EC6: -case 0x7EC7: -case 0x7EC8: -case 0x7EC9: -case 0x7ECA: -case 0x7ECB: -case 0x7ECC: -case 0x7ECD: -case 0x7ECE: -case 0x7ECF: -case 0x7ED0: -case 0x7ED1: -case 0x7ED2: -case 0x7ED3: -case 0x7ED4: -case 0x7ED5: -case 0x7ED6: -case 0x7ED7: -case 0x7ED8: -case 0x7ED9: -case 0x7EDA: -case 0x7EDB: -case 0x7EDC: -case 0x7EDD: -case 0x7EDE: -case 0x7EDF: -case 0x7EE0: -case 0x7EE1: -case 0x7EE2: -case 0x7EE3: -case 0x7EE4: -case 0x7EE5: -case 0x7EE6: -case 0x7EE7: -case 0x7EE8: -case 0x7EE9: -case 0x7EEA: -case 0x7EEB: -case 0x7EEC: -case 0x7EED: -case 0x7EEE: -case 0x7EEF: -case 0x7EF0: -case 0x7EF1: -case 0x7EF2: -case 0x7EF3: -case 0x7EF4: -case 0x7EF5: -case 0x7EF6: -case 0x7EF7: -case 0x7EF8: -case 0x7EF9: -case 0x7EFA: -case 0x7EFB: -case 0x7EFC: -case 0x7EFD: -case 0x7EFE: -case 0x7EFF: - -// MOVEQ -case 0x7000: -{ - u32 res; - res = (s32)(s8)Opcode; - CPU->flag_C = CPU->flag_V = 0; - CPU->flag_N = CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) diff --git a/yabause/src/c68k/c68k_op8.inc b/yabause/src/c68k/c68k_op8.inc deleted file mode 100644 index 6b0949d7ef..0000000000 --- a/yabause/src/c68k/c68k_op8.inc +++ /dev/null @@ -1,6117 +0,0 @@ -case 0x8200: -case 0x8400: -case 0x8600: -case 0x8800: -case 0x8A00: -case 0x8C00: -case 0x8E00: -case 0x8001: -case 0x8201: -case 0x8401: -case 0x8601: -case 0x8801: -case 0x8A01: -case 0x8C01: -case 0x8E01: -case 0x8002: -case 0x8202: -case 0x8402: -case 0x8602: -case 0x8802: -case 0x8A02: -case 0x8C02: -case 0x8E02: -case 0x8003: -case 0x8203: -case 0x8403: -case 0x8603: -case 0x8803: -case 0x8A03: -case 0x8C03: -case 0x8E03: -case 0x8004: -case 0x8204: -case 0x8404: -case 0x8604: -case 0x8804: -case 0x8A04: -case 0x8C04: -case 0x8E04: -case 0x8005: -case 0x8205: -case 0x8405: -case 0x8605: -case 0x8805: -case 0x8A05: -case 0x8C05: -case 0x8E05: -case 0x8006: -case 0x8206: -case 0x8406: -case 0x8606: -case 0x8806: -case 0x8A06: -case 0x8C06: -case 0x8E06: -case 0x8007: -case 0x8207: -case 0x8407: -case 0x8607: -case 0x8807: -case 0x8A07: -case 0x8C07: -case 0x8E07: - -// ORaD -case 0x8000: -{ - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x8210: -case 0x8410: -case 0x8610: -case 0x8810: -case 0x8A10: -case 0x8C10: -case 0x8E10: -case 0x8011: -case 0x8211: -case 0x8411: -case 0x8611: -case 0x8811: -case 0x8A11: -case 0x8C11: -case 0x8E11: -case 0x8012: -case 0x8212: -case 0x8412: -case 0x8612: -case 0x8812: -case 0x8A12: -case 0x8C12: -case 0x8E12: -case 0x8013: -case 0x8213: -case 0x8413: -case 0x8613: -case 0x8813: -case 0x8A13: -case 0x8C13: -case 0x8E13: -case 0x8014: -case 0x8214: -case 0x8414: -case 0x8614: -case 0x8814: -case 0x8A14: -case 0x8C14: -case 0x8E14: -case 0x8015: -case 0x8215: -case 0x8415: -case 0x8615: -case 0x8815: -case 0x8A15: -case 0x8C15: -case 0x8E15: -case 0x8016: -case 0x8216: -case 0x8416: -case 0x8616: -case 0x8816: -case 0x8A16: -case 0x8C16: -case 0x8E16: -case 0x8017: -case 0x8217: -case 0x8417: -case 0x8617: -case 0x8817: -case 0x8A17: -case 0x8C17: -case 0x8E17: - -// ORaD -case 0x8010: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x8218: -case 0x8418: -case 0x8618: -case 0x8818: -case 0x8A18: -case 0x8C18: -case 0x8E18: -case 0x8019: -case 0x8219: -case 0x8419: -case 0x8619: -case 0x8819: -case 0x8A19: -case 0x8C19: -case 0x8E19: -case 0x801A: -case 0x821A: -case 0x841A: -case 0x861A: -case 0x881A: -case 0x8A1A: -case 0x8C1A: -case 0x8E1A: -case 0x801B: -case 0x821B: -case 0x841B: -case 0x861B: -case 0x881B: -case 0x8A1B: -case 0x8C1B: -case 0x8E1B: -case 0x801C: -case 0x821C: -case 0x841C: -case 0x861C: -case 0x881C: -case 0x8A1C: -case 0x8C1C: -case 0x8E1C: -case 0x801D: -case 0x821D: -case 0x841D: -case 0x861D: -case 0x881D: -case 0x8A1D: -case 0x8C1D: -case 0x8E1D: -case 0x801E: -case 0x821E: -case 0x841E: -case 0x861E: -case 0x881E: -case 0x8A1E: -case 0x8C1E: -case 0x8E1E: - -// ORaD -case 0x8018: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x8220: -case 0x8420: -case 0x8620: -case 0x8820: -case 0x8A20: -case 0x8C20: -case 0x8E20: -case 0x8021: -case 0x8221: -case 0x8421: -case 0x8621: -case 0x8821: -case 0x8A21: -case 0x8C21: -case 0x8E21: -case 0x8022: -case 0x8222: -case 0x8422: -case 0x8622: -case 0x8822: -case 0x8A22: -case 0x8C22: -case 0x8E22: -case 0x8023: -case 0x8223: -case 0x8423: -case 0x8623: -case 0x8823: -case 0x8A23: -case 0x8C23: -case 0x8E23: -case 0x8024: -case 0x8224: -case 0x8424: -case 0x8624: -case 0x8824: -case 0x8A24: -case 0x8C24: -case 0x8E24: -case 0x8025: -case 0x8225: -case 0x8425: -case 0x8625: -case 0x8825: -case 0x8A25: -case 0x8C25: -case 0x8E25: -case 0x8026: -case 0x8226: -case 0x8426: -case 0x8626: -case 0x8826: -case 0x8A26: -case 0x8C26: -case 0x8E26: - -// ORaD -case 0x8020: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x8228: -case 0x8428: -case 0x8628: -case 0x8828: -case 0x8A28: -case 0x8C28: -case 0x8E28: -case 0x8029: -case 0x8229: -case 0x8429: -case 0x8629: -case 0x8829: -case 0x8A29: -case 0x8C29: -case 0x8E29: -case 0x802A: -case 0x822A: -case 0x842A: -case 0x862A: -case 0x882A: -case 0x8A2A: -case 0x8C2A: -case 0x8E2A: -case 0x802B: -case 0x822B: -case 0x842B: -case 0x862B: -case 0x882B: -case 0x8A2B: -case 0x8C2B: -case 0x8E2B: -case 0x802C: -case 0x822C: -case 0x842C: -case 0x862C: -case 0x882C: -case 0x8A2C: -case 0x8C2C: -case 0x8E2C: -case 0x802D: -case 0x822D: -case 0x842D: -case 0x862D: -case 0x882D: -case 0x8A2D: -case 0x8C2D: -case 0x8E2D: -case 0x802E: -case 0x822E: -case 0x842E: -case 0x862E: -case 0x882E: -case 0x8A2E: -case 0x8C2E: -case 0x8E2E: -case 0x802F: -case 0x822F: -case 0x842F: -case 0x862F: -case 0x882F: -case 0x8A2F: -case 0x8C2F: -case 0x8E2F: - -// ORaD -case 0x8028: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x8230: -case 0x8430: -case 0x8630: -case 0x8830: -case 0x8A30: -case 0x8C30: -case 0x8E30: -case 0x8031: -case 0x8231: -case 0x8431: -case 0x8631: -case 0x8831: -case 0x8A31: -case 0x8C31: -case 0x8E31: -case 0x8032: -case 0x8232: -case 0x8432: -case 0x8632: -case 0x8832: -case 0x8A32: -case 0x8C32: -case 0x8E32: -case 0x8033: -case 0x8233: -case 0x8433: -case 0x8633: -case 0x8833: -case 0x8A33: -case 0x8C33: -case 0x8E33: -case 0x8034: -case 0x8234: -case 0x8434: -case 0x8634: -case 0x8834: -case 0x8A34: -case 0x8C34: -case 0x8E34: -case 0x8035: -case 0x8235: -case 0x8435: -case 0x8635: -case 0x8835: -case 0x8A35: -case 0x8C35: -case 0x8E35: -case 0x8036: -case 0x8236: -case 0x8436: -case 0x8636: -case 0x8836: -case 0x8A36: -case 0x8C36: -case 0x8E36: -case 0x8037: -case 0x8237: -case 0x8437: -case 0x8637: -case 0x8837: -case 0x8A37: -case 0x8C37: -case 0x8E37: - -// ORaD -case 0x8030: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x8238: -case 0x8438: -case 0x8638: -case 0x8838: -case 0x8A38: -case 0x8C38: -case 0x8E38: - -// ORaD -case 0x8038: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x8239: -case 0x8439: -case 0x8639: -case 0x8839: -case 0x8A39: -case 0x8C39: -case 0x8E39: - -// ORaD -case 0x8039: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x823A: -case 0x843A: -case 0x863A: -case 0x883A: -case 0x8A3A: -case 0x8C3A: -case 0x8E3A: - -// ORaD -case 0x803A: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x823B: -case 0x843B: -case 0x863B: -case 0x883B: -case 0x8A3B: -case 0x8C3B: -case 0x8E3B: - -// ORaD -case 0x803B: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x823C: -case 0x843C: -case 0x863C: -case 0x883C: -case 0x8A3C: -case 0x8C3C: -case 0x8E3C: - -// ORaD -case 0x803C: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0x821F: -case 0x841F: -case 0x861F: -case 0x881F: -case 0x8A1F: -case 0x8C1F: -case 0x8E1F: - -// ORaD -case 0x801F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x8227: -case 0x8427: -case 0x8627: -case 0x8827: -case 0x8A27: -case 0x8C27: -case 0x8E27: - -// ORaD -case 0x8027: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x8240: -case 0x8440: -case 0x8640: -case 0x8840: -case 0x8A40: -case 0x8C40: -case 0x8E40: -case 0x8041: -case 0x8241: -case 0x8441: -case 0x8641: -case 0x8841: -case 0x8A41: -case 0x8C41: -case 0x8E41: -case 0x8042: -case 0x8242: -case 0x8442: -case 0x8642: -case 0x8842: -case 0x8A42: -case 0x8C42: -case 0x8E42: -case 0x8043: -case 0x8243: -case 0x8443: -case 0x8643: -case 0x8843: -case 0x8A43: -case 0x8C43: -case 0x8E43: -case 0x8044: -case 0x8244: -case 0x8444: -case 0x8644: -case 0x8844: -case 0x8A44: -case 0x8C44: -case 0x8E44: -case 0x8045: -case 0x8245: -case 0x8445: -case 0x8645: -case 0x8845: -case 0x8A45: -case 0x8C45: -case 0x8E45: -case 0x8046: -case 0x8246: -case 0x8446: -case 0x8646: -case 0x8846: -case 0x8A46: -case 0x8C46: -case 0x8E46: -case 0x8047: -case 0x8247: -case 0x8447: -case 0x8647: -case 0x8847: -case 0x8A47: -case 0x8C47: -case 0x8E47: - -// ORaD -case 0x8040: -{ - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x8250: -case 0x8450: -case 0x8650: -case 0x8850: -case 0x8A50: -case 0x8C50: -case 0x8E50: -case 0x8051: -case 0x8251: -case 0x8451: -case 0x8651: -case 0x8851: -case 0x8A51: -case 0x8C51: -case 0x8E51: -case 0x8052: -case 0x8252: -case 0x8452: -case 0x8652: -case 0x8852: -case 0x8A52: -case 0x8C52: -case 0x8E52: -case 0x8053: -case 0x8253: -case 0x8453: -case 0x8653: -case 0x8853: -case 0x8A53: -case 0x8C53: -case 0x8E53: -case 0x8054: -case 0x8254: -case 0x8454: -case 0x8654: -case 0x8854: -case 0x8A54: -case 0x8C54: -case 0x8E54: -case 0x8055: -case 0x8255: -case 0x8455: -case 0x8655: -case 0x8855: -case 0x8A55: -case 0x8C55: -case 0x8E55: -case 0x8056: -case 0x8256: -case 0x8456: -case 0x8656: -case 0x8856: -case 0x8A56: -case 0x8C56: -case 0x8E56: -case 0x8057: -case 0x8257: -case 0x8457: -case 0x8657: -case 0x8857: -case 0x8A57: -case 0x8C57: -case 0x8E57: - -// ORaD -case 0x8050: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x8258: -case 0x8458: -case 0x8658: -case 0x8858: -case 0x8A58: -case 0x8C58: -case 0x8E58: -case 0x8059: -case 0x8259: -case 0x8459: -case 0x8659: -case 0x8859: -case 0x8A59: -case 0x8C59: -case 0x8E59: -case 0x805A: -case 0x825A: -case 0x845A: -case 0x865A: -case 0x885A: -case 0x8A5A: -case 0x8C5A: -case 0x8E5A: -case 0x805B: -case 0x825B: -case 0x845B: -case 0x865B: -case 0x885B: -case 0x8A5B: -case 0x8C5B: -case 0x8E5B: -case 0x805C: -case 0x825C: -case 0x845C: -case 0x865C: -case 0x885C: -case 0x8A5C: -case 0x8C5C: -case 0x8E5C: -case 0x805D: -case 0x825D: -case 0x845D: -case 0x865D: -case 0x885D: -case 0x8A5D: -case 0x8C5D: -case 0x8E5D: -case 0x805E: -case 0x825E: -case 0x845E: -case 0x865E: -case 0x885E: -case 0x8A5E: -case 0x8C5E: -case 0x8E5E: - -// ORaD -case 0x8058: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x8260: -case 0x8460: -case 0x8660: -case 0x8860: -case 0x8A60: -case 0x8C60: -case 0x8E60: -case 0x8061: -case 0x8261: -case 0x8461: -case 0x8661: -case 0x8861: -case 0x8A61: -case 0x8C61: -case 0x8E61: -case 0x8062: -case 0x8262: -case 0x8462: -case 0x8662: -case 0x8862: -case 0x8A62: -case 0x8C62: -case 0x8E62: -case 0x8063: -case 0x8263: -case 0x8463: -case 0x8663: -case 0x8863: -case 0x8A63: -case 0x8C63: -case 0x8E63: -case 0x8064: -case 0x8264: -case 0x8464: -case 0x8664: -case 0x8864: -case 0x8A64: -case 0x8C64: -case 0x8E64: -case 0x8065: -case 0x8265: -case 0x8465: -case 0x8665: -case 0x8865: -case 0x8A65: -case 0x8C65: -case 0x8E65: -case 0x8066: -case 0x8266: -case 0x8466: -case 0x8666: -case 0x8866: -case 0x8A66: -case 0x8C66: -case 0x8E66: - -// ORaD -case 0x8060: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x8268: -case 0x8468: -case 0x8668: -case 0x8868: -case 0x8A68: -case 0x8C68: -case 0x8E68: -case 0x8069: -case 0x8269: -case 0x8469: -case 0x8669: -case 0x8869: -case 0x8A69: -case 0x8C69: -case 0x8E69: -case 0x806A: -case 0x826A: -case 0x846A: -case 0x866A: -case 0x886A: -case 0x8A6A: -case 0x8C6A: -case 0x8E6A: -case 0x806B: -case 0x826B: -case 0x846B: -case 0x866B: -case 0x886B: -case 0x8A6B: -case 0x8C6B: -case 0x8E6B: -case 0x806C: -case 0x826C: -case 0x846C: -case 0x866C: -case 0x886C: -case 0x8A6C: -case 0x8C6C: -case 0x8E6C: -case 0x806D: -case 0x826D: -case 0x846D: -case 0x866D: -case 0x886D: -case 0x8A6D: -case 0x8C6D: -case 0x8E6D: -case 0x806E: -case 0x826E: -case 0x846E: -case 0x866E: -case 0x886E: -case 0x8A6E: -case 0x8C6E: -case 0x8E6E: -case 0x806F: -case 0x826F: -case 0x846F: -case 0x866F: -case 0x886F: -case 0x8A6F: -case 0x8C6F: -case 0x8E6F: - -// ORaD -case 0x8068: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x8270: -case 0x8470: -case 0x8670: -case 0x8870: -case 0x8A70: -case 0x8C70: -case 0x8E70: -case 0x8071: -case 0x8271: -case 0x8471: -case 0x8671: -case 0x8871: -case 0x8A71: -case 0x8C71: -case 0x8E71: -case 0x8072: -case 0x8272: -case 0x8472: -case 0x8672: -case 0x8872: -case 0x8A72: -case 0x8C72: -case 0x8E72: -case 0x8073: -case 0x8273: -case 0x8473: -case 0x8673: -case 0x8873: -case 0x8A73: -case 0x8C73: -case 0x8E73: -case 0x8074: -case 0x8274: -case 0x8474: -case 0x8674: -case 0x8874: -case 0x8A74: -case 0x8C74: -case 0x8E74: -case 0x8075: -case 0x8275: -case 0x8475: -case 0x8675: -case 0x8875: -case 0x8A75: -case 0x8C75: -case 0x8E75: -case 0x8076: -case 0x8276: -case 0x8476: -case 0x8676: -case 0x8876: -case 0x8A76: -case 0x8C76: -case 0x8E76: -case 0x8077: -case 0x8277: -case 0x8477: -case 0x8677: -case 0x8877: -case 0x8A77: -case 0x8C77: -case 0x8E77: - -// ORaD -case 0x8070: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x8278: -case 0x8478: -case 0x8678: -case 0x8878: -case 0x8A78: -case 0x8C78: -case 0x8E78: - -// ORaD -case 0x8078: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x8279: -case 0x8479: -case 0x8679: -case 0x8879: -case 0x8A79: -case 0x8C79: -case 0x8E79: - -// ORaD -case 0x8079: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x827A: -case 0x847A: -case 0x867A: -case 0x887A: -case 0x8A7A: -case 0x8C7A: -case 0x8E7A: - -// ORaD -case 0x807A: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x827B: -case 0x847B: -case 0x867B: -case 0x887B: -case 0x8A7B: -case 0x8C7B: -case 0x8E7B: - -// ORaD -case 0x807B: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x827C: -case 0x847C: -case 0x867C: -case 0x887C: -case 0x8A7C: -case 0x8C7C: -case 0x8E7C: - -// ORaD -case 0x807C: -{ - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0x825F: -case 0x845F: -case 0x865F: -case 0x885F: -case 0x8A5F: -case 0x8C5F: -case 0x8E5F: - -// ORaD -case 0x805F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x8267: -case 0x8467: -case 0x8667: -case 0x8867: -case 0x8A67: -case 0x8C67: -case 0x8E67: - -// ORaD -case 0x8067: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x8280: -case 0x8480: -case 0x8680: -case 0x8880: -case 0x8A80: -case 0x8C80: -case 0x8E80: -case 0x8081: -case 0x8281: -case 0x8481: -case 0x8681: -case 0x8881: -case 0x8A81: -case 0x8C81: -case 0x8E81: -case 0x8082: -case 0x8282: -case 0x8482: -case 0x8682: -case 0x8882: -case 0x8A82: -case 0x8C82: -case 0x8E82: -case 0x8083: -case 0x8283: -case 0x8483: -case 0x8683: -case 0x8883: -case 0x8A83: -case 0x8C83: -case 0x8E83: -case 0x8084: -case 0x8284: -case 0x8484: -case 0x8684: -case 0x8884: -case 0x8A84: -case 0x8C84: -case 0x8E84: -case 0x8085: -case 0x8285: -case 0x8485: -case 0x8685: -case 0x8885: -case 0x8A85: -case 0x8C85: -case 0x8E85: -case 0x8086: -case 0x8286: -case 0x8486: -case 0x8686: -case 0x8886: -case 0x8A86: -case 0x8C86: -case 0x8E86: -case 0x8087: -case 0x8287: -case 0x8487: -case 0x8687: -case 0x8887: -case 0x8A87: -case 0x8C87: -case 0x8E87: - -// ORaD -case 0x8080: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(6) -case 0x8290: -case 0x8490: -case 0x8690: -case 0x8890: -case 0x8A90: -case 0x8C90: -case 0x8E90: -case 0x8091: -case 0x8291: -case 0x8491: -case 0x8691: -case 0x8891: -case 0x8A91: -case 0x8C91: -case 0x8E91: -case 0x8092: -case 0x8292: -case 0x8492: -case 0x8692: -case 0x8892: -case 0x8A92: -case 0x8C92: -case 0x8E92: -case 0x8093: -case 0x8293: -case 0x8493: -case 0x8693: -case 0x8893: -case 0x8A93: -case 0x8C93: -case 0x8E93: -case 0x8094: -case 0x8294: -case 0x8494: -case 0x8694: -case 0x8894: -case 0x8A94: -case 0x8C94: -case 0x8E94: -case 0x8095: -case 0x8295: -case 0x8495: -case 0x8695: -case 0x8895: -case 0x8A95: -case 0x8C95: -case 0x8E95: -case 0x8096: -case 0x8296: -case 0x8496: -case 0x8696: -case 0x8896: -case 0x8A96: -case 0x8C96: -case 0x8E96: -case 0x8097: -case 0x8297: -case 0x8497: -case 0x8697: -case 0x8897: -case 0x8A97: -case 0x8C97: -case 0x8E97: - -// ORaD -case 0x8090: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x8298: -case 0x8498: -case 0x8698: -case 0x8898: -case 0x8A98: -case 0x8C98: -case 0x8E98: -case 0x8099: -case 0x8299: -case 0x8499: -case 0x8699: -case 0x8899: -case 0x8A99: -case 0x8C99: -case 0x8E99: -case 0x809A: -case 0x829A: -case 0x849A: -case 0x869A: -case 0x889A: -case 0x8A9A: -case 0x8C9A: -case 0x8E9A: -case 0x809B: -case 0x829B: -case 0x849B: -case 0x869B: -case 0x889B: -case 0x8A9B: -case 0x8C9B: -case 0x8E9B: -case 0x809C: -case 0x829C: -case 0x849C: -case 0x869C: -case 0x889C: -case 0x8A9C: -case 0x8C9C: -case 0x8E9C: -case 0x809D: -case 0x829D: -case 0x849D: -case 0x869D: -case 0x889D: -case 0x8A9D: -case 0x8C9D: -case 0x8E9D: -case 0x809E: -case 0x829E: -case 0x849E: -case 0x869E: -case 0x889E: -case 0x8A9E: -case 0x8C9E: -case 0x8E9E: - -// ORaD -case 0x8098: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x82A0: -case 0x84A0: -case 0x86A0: -case 0x88A0: -case 0x8AA0: -case 0x8CA0: -case 0x8EA0: -case 0x80A1: -case 0x82A1: -case 0x84A1: -case 0x86A1: -case 0x88A1: -case 0x8AA1: -case 0x8CA1: -case 0x8EA1: -case 0x80A2: -case 0x82A2: -case 0x84A2: -case 0x86A2: -case 0x88A2: -case 0x8AA2: -case 0x8CA2: -case 0x8EA2: -case 0x80A3: -case 0x82A3: -case 0x84A3: -case 0x86A3: -case 0x88A3: -case 0x8AA3: -case 0x8CA3: -case 0x8EA3: -case 0x80A4: -case 0x82A4: -case 0x84A4: -case 0x86A4: -case 0x88A4: -case 0x8AA4: -case 0x8CA4: -case 0x8EA4: -case 0x80A5: -case 0x82A5: -case 0x84A5: -case 0x86A5: -case 0x88A5: -case 0x8AA5: -case 0x8CA5: -case 0x8EA5: -case 0x80A6: -case 0x82A6: -case 0x84A6: -case 0x86A6: -case 0x88A6: -case 0x8AA6: -case 0x8CA6: -case 0x8EA6: - -// ORaD -case 0x80A0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0x82A8: -case 0x84A8: -case 0x86A8: -case 0x88A8: -case 0x8AA8: -case 0x8CA8: -case 0x8EA8: -case 0x80A9: -case 0x82A9: -case 0x84A9: -case 0x86A9: -case 0x88A9: -case 0x8AA9: -case 0x8CA9: -case 0x8EA9: -case 0x80AA: -case 0x82AA: -case 0x84AA: -case 0x86AA: -case 0x88AA: -case 0x8AAA: -case 0x8CAA: -case 0x8EAA: -case 0x80AB: -case 0x82AB: -case 0x84AB: -case 0x86AB: -case 0x88AB: -case 0x8AAB: -case 0x8CAB: -case 0x8EAB: -case 0x80AC: -case 0x82AC: -case 0x84AC: -case 0x86AC: -case 0x88AC: -case 0x8AAC: -case 0x8CAC: -case 0x8EAC: -case 0x80AD: -case 0x82AD: -case 0x84AD: -case 0x86AD: -case 0x88AD: -case 0x8AAD: -case 0x8CAD: -case 0x8EAD: -case 0x80AE: -case 0x82AE: -case 0x84AE: -case 0x86AE: -case 0x88AE: -case 0x8AAE: -case 0x8CAE: -case 0x8EAE: -case 0x80AF: -case 0x82AF: -case 0x84AF: -case 0x86AF: -case 0x88AF: -case 0x8AAF: -case 0x8CAF: -case 0x8EAF: - -// ORaD -case 0x80A8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0x82B0: -case 0x84B0: -case 0x86B0: -case 0x88B0: -case 0x8AB0: -case 0x8CB0: -case 0x8EB0: -case 0x80B1: -case 0x82B1: -case 0x84B1: -case 0x86B1: -case 0x88B1: -case 0x8AB1: -case 0x8CB1: -case 0x8EB1: -case 0x80B2: -case 0x82B2: -case 0x84B2: -case 0x86B2: -case 0x88B2: -case 0x8AB2: -case 0x8CB2: -case 0x8EB2: -case 0x80B3: -case 0x82B3: -case 0x84B3: -case 0x86B3: -case 0x88B3: -case 0x8AB3: -case 0x8CB3: -case 0x8EB3: -case 0x80B4: -case 0x82B4: -case 0x84B4: -case 0x86B4: -case 0x88B4: -case 0x8AB4: -case 0x8CB4: -case 0x8EB4: -case 0x80B5: -case 0x82B5: -case 0x84B5: -case 0x86B5: -case 0x88B5: -case 0x8AB5: -case 0x8CB5: -case 0x8EB5: -case 0x80B6: -case 0x82B6: -case 0x84B6: -case 0x86B6: -case 0x88B6: -case 0x8AB6: -case 0x8CB6: -case 0x8EB6: -case 0x80B7: -case 0x82B7: -case 0x84B7: -case 0x86B7: -case 0x88B7: -case 0x8AB7: -case 0x8CB7: -case 0x8EB7: - -// ORaD -case 0x80B0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(22) -case 0x82B8: -case 0x84B8: -case 0x86B8: -case 0x88B8: -case 0x8AB8: -case 0x8CB8: -case 0x8EB8: - -// ORaD -case 0x80B8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0x82B9: -case 0x84B9: -case 0x86B9: -case 0x88B9: -case 0x8AB9: -case 0x8CB9: -case 0x8EB9: - -// ORaD -case 0x80B9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(24) -case 0x82BA: -case 0x84BA: -case 0x86BA: -case 0x88BA: -case 0x8ABA: -case 0x8CBA: -case 0x8EBA: - -// ORaD -case 0x80BA: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0x82BB: -case 0x84BB: -case 0x86BB: -case 0x88BB: -case 0x8ABB: -case 0x8CBB: -case 0x8EBB: - -// ORaD -case 0x80BB: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(22) -case 0x82BC: -case 0x84BC: -case 0x86BC: -case 0x88BC: -case 0x8ABC: -case 0x8CBC: -case 0x8EBC: - -// ORaD -case 0x80BC: -{ - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(14) -case 0x829F: -case 0x849F: -case 0x869F: -case 0x889F: -case 0x8A9F: -case 0x8C9F: -case 0x8E9F: - -// ORaD -case 0x809F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x82A7: -case 0x84A7: -case 0x86A7: -case 0x88A7: -case 0x8AA7: -case 0x8CA7: -case 0x8EA7: - -// ORaD -case 0x80A7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0x8310: -case 0x8510: -case 0x8710: -case 0x8910: -case 0x8B10: -case 0x8D10: -case 0x8F10: -case 0x8111: -case 0x8311: -case 0x8511: -case 0x8711: -case 0x8911: -case 0x8B11: -case 0x8D11: -case 0x8F11: -case 0x8112: -case 0x8312: -case 0x8512: -case 0x8712: -case 0x8912: -case 0x8B12: -case 0x8D12: -case 0x8F12: -case 0x8113: -case 0x8313: -case 0x8513: -case 0x8713: -case 0x8913: -case 0x8B13: -case 0x8D13: -case 0x8F13: -case 0x8114: -case 0x8314: -case 0x8514: -case 0x8714: -case 0x8914: -case 0x8B14: -case 0x8D14: -case 0x8F14: -case 0x8115: -case 0x8315: -case 0x8515: -case 0x8715: -case 0x8915: -case 0x8B15: -case 0x8D15: -case 0x8F15: -case 0x8116: -case 0x8316: -case 0x8516: -case 0x8716: -case 0x8916: -case 0x8B16: -case 0x8D16: -case 0x8F16: -case 0x8117: -case 0x8317: -case 0x8517: -case 0x8717: -case 0x8917: -case 0x8B17: -case 0x8D17: -case 0x8F17: - -// ORDa -case 0x8110: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x8318: -case 0x8518: -case 0x8718: -case 0x8918: -case 0x8B18: -case 0x8D18: -case 0x8F18: -case 0x8119: -case 0x8319: -case 0x8519: -case 0x8719: -case 0x8919: -case 0x8B19: -case 0x8D19: -case 0x8F19: -case 0x811A: -case 0x831A: -case 0x851A: -case 0x871A: -case 0x891A: -case 0x8B1A: -case 0x8D1A: -case 0x8F1A: -case 0x811B: -case 0x831B: -case 0x851B: -case 0x871B: -case 0x891B: -case 0x8B1B: -case 0x8D1B: -case 0x8F1B: -case 0x811C: -case 0x831C: -case 0x851C: -case 0x871C: -case 0x891C: -case 0x8B1C: -case 0x8D1C: -case 0x8F1C: -case 0x811D: -case 0x831D: -case 0x851D: -case 0x871D: -case 0x891D: -case 0x8B1D: -case 0x8D1D: -case 0x8F1D: -case 0x811E: -case 0x831E: -case 0x851E: -case 0x871E: -case 0x891E: -case 0x8B1E: -case 0x8D1E: -case 0x8F1E: - -// ORDa -case 0x8118: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x8320: -case 0x8520: -case 0x8720: -case 0x8920: -case 0x8B20: -case 0x8D20: -case 0x8F20: -case 0x8121: -case 0x8321: -case 0x8521: -case 0x8721: -case 0x8921: -case 0x8B21: -case 0x8D21: -case 0x8F21: -case 0x8122: -case 0x8322: -case 0x8522: -case 0x8722: -case 0x8922: -case 0x8B22: -case 0x8D22: -case 0x8F22: -case 0x8123: -case 0x8323: -case 0x8523: -case 0x8723: -case 0x8923: -case 0x8B23: -case 0x8D23: -case 0x8F23: -case 0x8124: -case 0x8324: -case 0x8524: -case 0x8724: -case 0x8924: -case 0x8B24: -case 0x8D24: -case 0x8F24: -case 0x8125: -case 0x8325: -case 0x8525: -case 0x8725: -case 0x8925: -case 0x8B25: -case 0x8D25: -case 0x8F25: -case 0x8126: -case 0x8326: -case 0x8526: -case 0x8726: -case 0x8926: -case 0x8B26: -case 0x8D26: -case 0x8F26: - -// ORDa -case 0x8120: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x8328: -case 0x8528: -case 0x8728: -case 0x8928: -case 0x8B28: -case 0x8D28: -case 0x8F28: -case 0x8129: -case 0x8329: -case 0x8529: -case 0x8729: -case 0x8929: -case 0x8B29: -case 0x8D29: -case 0x8F29: -case 0x812A: -case 0x832A: -case 0x852A: -case 0x872A: -case 0x892A: -case 0x8B2A: -case 0x8D2A: -case 0x8F2A: -case 0x812B: -case 0x832B: -case 0x852B: -case 0x872B: -case 0x892B: -case 0x8B2B: -case 0x8D2B: -case 0x8F2B: -case 0x812C: -case 0x832C: -case 0x852C: -case 0x872C: -case 0x892C: -case 0x8B2C: -case 0x8D2C: -case 0x8F2C: -case 0x812D: -case 0x832D: -case 0x852D: -case 0x872D: -case 0x892D: -case 0x8B2D: -case 0x8D2D: -case 0x8F2D: -case 0x812E: -case 0x832E: -case 0x852E: -case 0x872E: -case 0x892E: -case 0x8B2E: -case 0x8D2E: -case 0x8F2E: -case 0x812F: -case 0x832F: -case 0x852F: -case 0x872F: -case 0x892F: -case 0x8B2F: -case 0x8D2F: -case 0x8F2F: - -// ORDa -case 0x8128: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x8330: -case 0x8530: -case 0x8730: -case 0x8930: -case 0x8B30: -case 0x8D30: -case 0x8F30: -case 0x8131: -case 0x8331: -case 0x8531: -case 0x8731: -case 0x8931: -case 0x8B31: -case 0x8D31: -case 0x8F31: -case 0x8132: -case 0x8332: -case 0x8532: -case 0x8732: -case 0x8932: -case 0x8B32: -case 0x8D32: -case 0x8F32: -case 0x8133: -case 0x8333: -case 0x8533: -case 0x8733: -case 0x8933: -case 0x8B33: -case 0x8D33: -case 0x8F33: -case 0x8134: -case 0x8334: -case 0x8534: -case 0x8734: -case 0x8934: -case 0x8B34: -case 0x8D34: -case 0x8F34: -case 0x8135: -case 0x8335: -case 0x8535: -case 0x8735: -case 0x8935: -case 0x8B35: -case 0x8D35: -case 0x8F35: -case 0x8136: -case 0x8336: -case 0x8536: -case 0x8736: -case 0x8936: -case 0x8B36: -case 0x8D36: -case 0x8F36: -case 0x8137: -case 0x8337: -case 0x8537: -case 0x8737: -case 0x8937: -case 0x8B37: -case 0x8D37: -case 0x8F37: - -// ORDa -case 0x8130: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x8338: -case 0x8538: -case 0x8738: -case 0x8938: -case 0x8B38: -case 0x8D38: -case 0x8F38: - -// ORDa -case 0x8138: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x8339: -case 0x8539: -case 0x8739: -case 0x8939: -case 0x8B39: -case 0x8D39: -case 0x8F39: - -// ORDa -case 0x8139: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x831F: -case 0x851F: -case 0x871F: -case 0x891F: -case 0x8B1F: -case 0x8D1F: -case 0x8F1F: - -// ORDa -case 0x811F: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x8327: -case 0x8527: -case 0x8727: -case 0x8927: -case 0x8B27: -case 0x8D27: -case 0x8F27: - -// ORDa -case 0x8127: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x8350: -case 0x8550: -case 0x8750: -case 0x8950: -case 0x8B50: -case 0x8D50: -case 0x8F50: -case 0x8151: -case 0x8351: -case 0x8551: -case 0x8751: -case 0x8951: -case 0x8B51: -case 0x8D51: -case 0x8F51: -case 0x8152: -case 0x8352: -case 0x8552: -case 0x8752: -case 0x8952: -case 0x8B52: -case 0x8D52: -case 0x8F52: -case 0x8153: -case 0x8353: -case 0x8553: -case 0x8753: -case 0x8953: -case 0x8B53: -case 0x8D53: -case 0x8F53: -case 0x8154: -case 0x8354: -case 0x8554: -case 0x8754: -case 0x8954: -case 0x8B54: -case 0x8D54: -case 0x8F54: -case 0x8155: -case 0x8355: -case 0x8555: -case 0x8755: -case 0x8955: -case 0x8B55: -case 0x8D55: -case 0x8F55: -case 0x8156: -case 0x8356: -case 0x8556: -case 0x8756: -case 0x8956: -case 0x8B56: -case 0x8D56: -case 0x8F56: -case 0x8157: -case 0x8357: -case 0x8557: -case 0x8757: -case 0x8957: -case 0x8B57: -case 0x8D57: -case 0x8F57: - -// ORDa -case 0x8150: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x8358: -case 0x8558: -case 0x8758: -case 0x8958: -case 0x8B58: -case 0x8D58: -case 0x8F58: -case 0x8159: -case 0x8359: -case 0x8559: -case 0x8759: -case 0x8959: -case 0x8B59: -case 0x8D59: -case 0x8F59: -case 0x815A: -case 0x835A: -case 0x855A: -case 0x875A: -case 0x895A: -case 0x8B5A: -case 0x8D5A: -case 0x8F5A: -case 0x815B: -case 0x835B: -case 0x855B: -case 0x875B: -case 0x895B: -case 0x8B5B: -case 0x8D5B: -case 0x8F5B: -case 0x815C: -case 0x835C: -case 0x855C: -case 0x875C: -case 0x895C: -case 0x8B5C: -case 0x8D5C: -case 0x8F5C: -case 0x815D: -case 0x835D: -case 0x855D: -case 0x875D: -case 0x895D: -case 0x8B5D: -case 0x8D5D: -case 0x8F5D: -case 0x815E: -case 0x835E: -case 0x855E: -case 0x875E: -case 0x895E: -case 0x8B5E: -case 0x8D5E: -case 0x8F5E: - -// ORDa -case 0x8158: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x8360: -case 0x8560: -case 0x8760: -case 0x8960: -case 0x8B60: -case 0x8D60: -case 0x8F60: -case 0x8161: -case 0x8361: -case 0x8561: -case 0x8761: -case 0x8961: -case 0x8B61: -case 0x8D61: -case 0x8F61: -case 0x8162: -case 0x8362: -case 0x8562: -case 0x8762: -case 0x8962: -case 0x8B62: -case 0x8D62: -case 0x8F62: -case 0x8163: -case 0x8363: -case 0x8563: -case 0x8763: -case 0x8963: -case 0x8B63: -case 0x8D63: -case 0x8F63: -case 0x8164: -case 0x8364: -case 0x8564: -case 0x8764: -case 0x8964: -case 0x8B64: -case 0x8D64: -case 0x8F64: -case 0x8165: -case 0x8365: -case 0x8565: -case 0x8765: -case 0x8965: -case 0x8B65: -case 0x8D65: -case 0x8F65: -case 0x8166: -case 0x8366: -case 0x8566: -case 0x8766: -case 0x8966: -case 0x8B66: -case 0x8D66: -case 0x8F66: - -// ORDa -case 0x8160: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x8368: -case 0x8568: -case 0x8768: -case 0x8968: -case 0x8B68: -case 0x8D68: -case 0x8F68: -case 0x8169: -case 0x8369: -case 0x8569: -case 0x8769: -case 0x8969: -case 0x8B69: -case 0x8D69: -case 0x8F69: -case 0x816A: -case 0x836A: -case 0x856A: -case 0x876A: -case 0x896A: -case 0x8B6A: -case 0x8D6A: -case 0x8F6A: -case 0x816B: -case 0x836B: -case 0x856B: -case 0x876B: -case 0x896B: -case 0x8B6B: -case 0x8D6B: -case 0x8F6B: -case 0x816C: -case 0x836C: -case 0x856C: -case 0x876C: -case 0x896C: -case 0x8B6C: -case 0x8D6C: -case 0x8F6C: -case 0x816D: -case 0x836D: -case 0x856D: -case 0x876D: -case 0x896D: -case 0x8B6D: -case 0x8D6D: -case 0x8F6D: -case 0x816E: -case 0x836E: -case 0x856E: -case 0x876E: -case 0x896E: -case 0x8B6E: -case 0x8D6E: -case 0x8F6E: -case 0x816F: -case 0x836F: -case 0x856F: -case 0x876F: -case 0x896F: -case 0x8B6F: -case 0x8D6F: -case 0x8F6F: - -// ORDa -case 0x8168: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x8370: -case 0x8570: -case 0x8770: -case 0x8970: -case 0x8B70: -case 0x8D70: -case 0x8F70: -case 0x8171: -case 0x8371: -case 0x8571: -case 0x8771: -case 0x8971: -case 0x8B71: -case 0x8D71: -case 0x8F71: -case 0x8172: -case 0x8372: -case 0x8572: -case 0x8772: -case 0x8972: -case 0x8B72: -case 0x8D72: -case 0x8F72: -case 0x8173: -case 0x8373: -case 0x8573: -case 0x8773: -case 0x8973: -case 0x8B73: -case 0x8D73: -case 0x8F73: -case 0x8174: -case 0x8374: -case 0x8574: -case 0x8774: -case 0x8974: -case 0x8B74: -case 0x8D74: -case 0x8F74: -case 0x8175: -case 0x8375: -case 0x8575: -case 0x8775: -case 0x8975: -case 0x8B75: -case 0x8D75: -case 0x8F75: -case 0x8176: -case 0x8376: -case 0x8576: -case 0x8776: -case 0x8976: -case 0x8B76: -case 0x8D76: -case 0x8F76: -case 0x8177: -case 0x8377: -case 0x8577: -case 0x8777: -case 0x8977: -case 0x8B77: -case 0x8D77: -case 0x8F77: - -// ORDa -case 0x8170: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x8378: -case 0x8578: -case 0x8778: -case 0x8978: -case 0x8B78: -case 0x8D78: -case 0x8F78: - -// ORDa -case 0x8178: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x8379: -case 0x8579: -case 0x8779: -case 0x8979: -case 0x8B79: -case 0x8D79: -case 0x8F79: - -// ORDa -case 0x8179: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x835F: -case 0x855F: -case 0x875F: -case 0x895F: -case 0x8B5F: -case 0x8D5F: -case 0x8F5F: - -// ORDa -case 0x815F: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x8367: -case 0x8567: -case 0x8767: -case 0x8967: -case 0x8B67: -case 0x8D67: -case 0x8F67: - -// ORDa -case 0x8167: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x8390: -case 0x8590: -case 0x8790: -case 0x8990: -case 0x8B90: -case 0x8D90: -case 0x8F90: -case 0x8191: -case 0x8391: -case 0x8591: -case 0x8791: -case 0x8991: -case 0x8B91: -case 0x8D91: -case 0x8F91: -case 0x8192: -case 0x8392: -case 0x8592: -case 0x8792: -case 0x8992: -case 0x8B92: -case 0x8D92: -case 0x8F92: -case 0x8193: -case 0x8393: -case 0x8593: -case 0x8793: -case 0x8993: -case 0x8B93: -case 0x8D93: -case 0x8F93: -case 0x8194: -case 0x8394: -case 0x8594: -case 0x8794: -case 0x8994: -case 0x8B94: -case 0x8D94: -case 0x8F94: -case 0x8195: -case 0x8395: -case 0x8595: -case 0x8795: -case 0x8995: -case 0x8B95: -case 0x8D95: -case 0x8F95: -case 0x8196: -case 0x8396: -case 0x8596: -case 0x8796: -case 0x8996: -case 0x8B96: -case 0x8D96: -case 0x8F96: -case 0x8197: -case 0x8397: -case 0x8597: -case 0x8797: -case 0x8997: -case 0x8B97: -case 0x8D97: -case 0x8F97: - -// ORDa -case 0x8190: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x8398: -case 0x8598: -case 0x8798: -case 0x8998: -case 0x8B98: -case 0x8D98: -case 0x8F98: -case 0x8199: -case 0x8399: -case 0x8599: -case 0x8799: -case 0x8999: -case 0x8B99: -case 0x8D99: -case 0x8F99: -case 0x819A: -case 0x839A: -case 0x859A: -case 0x879A: -case 0x899A: -case 0x8B9A: -case 0x8D9A: -case 0x8F9A: -case 0x819B: -case 0x839B: -case 0x859B: -case 0x879B: -case 0x899B: -case 0x8B9B: -case 0x8D9B: -case 0x8F9B: -case 0x819C: -case 0x839C: -case 0x859C: -case 0x879C: -case 0x899C: -case 0x8B9C: -case 0x8D9C: -case 0x8F9C: -case 0x819D: -case 0x839D: -case 0x859D: -case 0x879D: -case 0x899D: -case 0x8B9D: -case 0x8D9D: -case 0x8F9D: -case 0x819E: -case 0x839E: -case 0x859E: -case 0x879E: -case 0x899E: -case 0x8B9E: -case 0x8D9E: -case 0x8F9E: - -// ORDa -case 0x8198: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x83A0: -case 0x85A0: -case 0x87A0: -case 0x89A0: -case 0x8BA0: -case 0x8DA0: -case 0x8FA0: -case 0x81A1: -case 0x83A1: -case 0x85A1: -case 0x87A1: -case 0x89A1: -case 0x8BA1: -case 0x8DA1: -case 0x8FA1: -case 0x81A2: -case 0x83A2: -case 0x85A2: -case 0x87A2: -case 0x89A2: -case 0x8BA2: -case 0x8DA2: -case 0x8FA2: -case 0x81A3: -case 0x83A3: -case 0x85A3: -case 0x87A3: -case 0x89A3: -case 0x8BA3: -case 0x8DA3: -case 0x8FA3: -case 0x81A4: -case 0x83A4: -case 0x85A4: -case 0x87A4: -case 0x89A4: -case 0x8BA4: -case 0x8DA4: -case 0x8FA4: -case 0x81A5: -case 0x83A5: -case 0x85A5: -case 0x87A5: -case 0x89A5: -case 0x8BA5: -case 0x8DA5: -case 0x8FA5: -case 0x81A6: -case 0x83A6: -case 0x85A6: -case 0x87A6: -case 0x89A6: -case 0x8BA6: -case 0x8DA6: -case 0x8FA6: - -// ORDa -case 0x81A0: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x83A8: -case 0x85A8: -case 0x87A8: -case 0x89A8: -case 0x8BA8: -case 0x8DA8: -case 0x8FA8: -case 0x81A9: -case 0x83A9: -case 0x85A9: -case 0x87A9: -case 0x89A9: -case 0x8BA9: -case 0x8DA9: -case 0x8FA9: -case 0x81AA: -case 0x83AA: -case 0x85AA: -case 0x87AA: -case 0x89AA: -case 0x8BAA: -case 0x8DAA: -case 0x8FAA: -case 0x81AB: -case 0x83AB: -case 0x85AB: -case 0x87AB: -case 0x89AB: -case 0x8BAB: -case 0x8DAB: -case 0x8FAB: -case 0x81AC: -case 0x83AC: -case 0x85AC: -case 0x87AC: -case 0x89AC: -case 0x8BAC: -case 0x8DAC: -case 0x8FAC: -case 0x81AD: -case 0x83AD: -case 0x85AD: -case 0x87AD: -case 0x89AD: -case 0x8BAD: -case 0x8DAD: -case 0x8FAD: -case 0x81AE: -case 0x83AE: -case 0x85AE: -case 0x87AE: -case 0x89AE: -case 0x8BAE: -case 0x8DAE: -case 0x8FAE: -case 0x81AF: -case 0x83AF: -case 0x85AF: -case 0x87AF: -case 0x89AF: -case 0x8BAF: -case 0x8DAF: -case 0x8FAF: - -// ORDa -case 0x81A8: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x83B0: -case 0x85B0: -case 0x87B0: -case 0x89B0: -case 0x8BB0: -case 0x8DB0: -case 0x8FB0: -case 0x81B1: -case 0x83B1: -case 0x85B1: -case 0x87B1: -case 0x89B1: -case 0x8BB1: -case 0x8DB1: -case 0x8FB1: -case 0x81B2: -case 0x83B2: -case 0x85B2: -case 0x87B2: -case 0x89B2: -case 0x8BB2: -case 0x8DB2: -case 0x8FB2: -case 0x81B3: -case 0x83B3: -case 0x85B3: -case 0x87B3: -case 0x89B3: -case 0x8BB3: -case 0x8DB3: -case 0x8FB3: -case 0x81B4: -case 0x83B4: -case 0x85B4: -case 0x87B4: -case 0x89B4: -case 0x8BB4: -case 0x8DB4: -case 0x8FB4: -case 0x81B5: -case 0x83B5: -case 0x85B5: -case 0x87B5: -case 0x89B5: -case 0x8BB5: -case 0x8DB5: -case 0x8FB5: -case 0x81B6: -case 0x83B6: -case 0x85B6: -case 0x87B6: -case 0x89B6: -case 0x8BB6: -case 0x8DB6: -case 0x8FB6: -case 0x81B7: -case 0x83B7: -case 0x85B7: -case 0x87B7: -case 0x89B7: -case 0x8BB7: -case 0x8DB7: -case 0x8FB7: - -// ORDa -case 0x81B0: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x83B8: -case 0x85B8: -case 0x87B8: -case 0x89B8: -case 0x8BB8: -case 0x8DB8: -case 0x8FB8: - -// ORDa -case 0x81B8: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x83B9: -case 0x85B9: -case 0x87B9: -case 0x89B9: -case 0x8BB9: -case 0x8DB9: -case 0x8FB9: - -// ORDa -case 0x81B9: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x839F: -case 0x859F: -case 0x879F: -case 0x899F: -case 0x8B9F: -case 0x8D9F: -case 0x8F9F: - -// ORDa -case 0x819F: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x83A7: -case 0x85A7: -case 0x87A7: -case 0x89A7: -case 0x8BA7: -case 0x8DA7: -case 0x8FA7: - -// ORDa -case 0x81A7: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res |= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x8300: -case 0x8500: -case 0x8700: -case 0x8900: -case 0x8B00: -case 0x8D00: -case 0x8F00: -case 0x8101: -case 0x8301: -case 0x8501: -case 0x8701: -case 0x8901: -case 0x8B01: -case 0x8D01: -case 0x8F01: -case 0x8102: -case 0x8302: -case 0x8502: -case 0x8702: -case 0x8902: -case 0x8B02: -case 0x8D02: -case 0x8F02: -case 0x8103: -case 0x8303: -case 0x8503: -case 0x8703: -case 0x8903: -case 0x8B03: -case 0x8D03: -case 0x8F03: -case 0x8104: -case 0x8304: -case 0x8504: -case 0x8704: -case 0x8904: -case 0x8B04: -case 0x8D04: -case 0x8F04: -case 0x8105: -case 0x8305: -case 0x8505: -case 0x8705: -case 0x8905: -case 0x8B05: -case 0x8D05: -case 0x8F05: -case 0x8106: -case 0x8306: -case 0x8506: -case 0x8706: -case 0x8906: -case 0x8B06: -case 0x8D06: -case 0x8F06: -case 0x8107: -case 0x8307: -case 0x8507: -case 0x8707: -case 0x8907: -case 0x8B07: -case 0x8D07: -case 0x8F07: - -// SBCD -case 0x8100: -{ - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = (dst & 0xF) - (src & 0xF) - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res -= 6; - res += (dst & 0xF0) - (src & 0xF0); - if (res > 0x99) - { - res += 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(6) -case 0x8308: -case 0x8508: -case 0x8708: -case 0x8908: -case 0x8B08: -case 0x8D08: -case 0x8109: -case 0x8309: -case 0x8509: -case 0x8709: -case 0x8909: -case 0x8B09: -case 0x8D09: -case 0x810A: -case 0x830A: -case 0x850A: -case 0x870A: -case 0x890A: -case 0x8B0A: -case 0x8D0A: -case 0x810B: -case 0x830B: -case 0x850B: -case 0x870B: -case 0x890B: -case 0x8B0B: -case 0x8D0B: -case 0x810C: -case 0x830C: -case 0x850C: -case 0x870C: -case 0x890C: -case 0x8B0C: -case 0x8D0C: -case 0x810D: -case 0x830D: -case 0x850D: -case 0x870D: -case 0x890D: -case 0x8B0D: -case 0x8D0D: -case 0x810E: -case 0x830E: -case 0x850E: -case 0x870E: -case 0x890E: -case 0x8B0E: -case 0x8D0E: - -// SBCDM -case 0x8108: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_BYTE_F(adr, dst) - res = (dst & 0xF) - (src & 0xF) - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res -= 6; - res += (dst & 0xF0) - (src & 0xF0); - if (res > 0x99) - { - res += 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x830F: -case 0x850F: -case 0x870F: -case 0x890F: -case 0x8B0F: -case 0x8D0F: - -// SBCD7M -case 0x810F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_BYTE_F(adr, dst) - res = (dst & 0xF) - (src & 0xF) - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res -= 6; - res += (dst & 0xF0) - (src & 0xF0); - if (res > 0x99) - { - res += 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x8F09: -case 0x8F0A: -case 0x8F0B: -case 0x8F0C: -case 0x8F0D: -case 0x8F0E: - -// SBCDM7 -case 0x8F08: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_BYTE_F(adr, dst) - res = (dst & 0xF) - (src & 0xF) - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res -= 6; - res += (dst & 0xF0) - (src & 0xF0); - if (res > 0x99) - { - res += 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// SBCD7M7 -case 0x8F0F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_BYTE_F(adr, dst) - res = (dst & 0xF) - (src & 0xF) - ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res -= 6; - res += (dst & 0xF0) - (src & 0xF0); - if (res > 0x99) - { - res += 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x82C0: -case 0x84C0: -case 0x86C0: -case 0x88C0: -case 0x8AC0: -case 0x8CC0: -case 0x8EC0: -case 0x80C1: -case 0x82C1: -case 0x84C1: -case 0x86C1: -case 0x88C1: -case 0x8AC1: -case 0x8CC1: -case 0x8EC1: -case 0x80C2: -case 0x82C2: -case 0x84C2: -case 0x86C2: -case 0x88C2: -case 0x8AC2: -case 0x8CC2: -case 0x8EC2: -case 0x80C3: -case 0x82C3: -case 0x84C3: -case 0x86C3: -case 0x88C3: -case 0x8AC3: -case 0x8CC3: -case 0x8EC3: -case 0x80C4: -case 0x82C4: -case 0x84C4: -case 0x86C4: -case 0x88C4: -case 0x8AC4: -case 0x8CC4: -case 0x8EC4: -case 0x80C5: -case 0x82C5: -case 0x84C5: -case 0x86C5: -case 0x88C5: -case 0x8AC5: -case 0x8CC5: -case 0x8EC5: -case 0x80C6: -case 0x82C6: -case 0x84C6: -case 0x86C6: -case 0x88C6: -case 0x8AC6: -case 0x8CC6: -case 0x8EC6: -case 0x80C7: -case 0x82C7: -case 0x84C7: -case 0x86C7: -case 0x88C7: -case 0x8AC7: -case 0x8CC7: -case 0x8EC7: - -// DIVU -case 0x80C0: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(10) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(70) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(90) -case 0x82D0: -case 0x84D0: -case 0x86D0: -case 0x88D0: -case 0x8AD0: -case 0x8CD0: -case 0x8ED0: -case 0x80D1: -case 0x82D1: -case 0x84D1: -case 0x86D1: -case 0x88D1: -case 0x8AD1: -case 0x8CD1: -case 0x8ED1: -case 0x80D2: -case 0x82D2: -case 0x84D2: -case 0x86D2: -case 0x88D2: -case 0x8AD2: -case 0x8CD2: -case 0x8ED2: -case 0x80D3: -case 0x82D3: -case 0x84D3: -case 0x86D3: -case 0x88D3: -case 0x8AD3: -case 0x8CD3: -case 0x8ED3: -case 0x80D4: -case 0x82D4: -case 0x84D4: -case 0x86D4: -case 0x88D4: -case 0x8AD4: -case 0x8CD4: -case 0x8ED4: -case 0x80D5: -case 0x82D5: -case 0x84D5: -case 0x86D5: -case 0x88D5: -case 0x8AD5: -case 0x8CD5: -case 0x8ED5: -case 0x80D6: -case 0x82D6: -case 0x84D6: -case 0x86D6: -case 0x88D6: -case 0x8AD6: -case 0x8CD6: -case 0x8ED6: -case 0x80D7: -case 0x82D7: -case 0x84D7: -case 0x86D7: -case 0x88D7: -case 0x8AD7: -case 0x8CD7: -case 0x8ED7: - -// DIVU -case 0x80D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(14) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(74) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(94) -case 0x82D8: -case 0x84D8: -case 0x86D8: -case 0x88D8: -case 0x8AD8: -case 0x8CD8: -case 0x8ED8: -case 0x80D9: -case 0x82D9: -case 0x84D9: -case 0x86D9: -case 0x88D9: -case 0x8AD9: -case 0x8CD9: -case 0x8ED9: -case 0x80DA: -case 0x82DA: -case 0x84DA: -case 0x86DA: -case 0x88DA: -case 0x8ADA: -case 0x8CDA: -case 0x8EDA: -case 0x80DB: -case 0x82DB: -case 0x84DB: -case 0x86DB: -case 0x88DB: -case 0x8ADB: -case 0x8CDB: -case 0x8EDB: -case 0x80DC: -case 0x82DC: -case 0x84DC: -case 0x86DC: -case 0x88DC: -case 0x8ADC: -case 0x8CDC: -case 0x8EDC: -case 0x80DD: -case 0x82DD: -case 0x84DD: -case 0x86DD: -case 0x88DD: -case 0x8ADD: -case 0x8CDD: -case 0x8EDD: -case 0x80DE: -case 0x82DE: -case 0x84DE: -case 0x86DE: -case 0x88DE: -case 0x8ADE: -case 0x8CDE: -case 0x8EDE: - -// DIVU -case 0x80D8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(14) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(74) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(94) -case 0x82E0: -case 0x84E0: -case 0x86E0: -case 0x88E0: -case 0x8AE0: -case 0x8CE0: -case 0x8EE0: -case 0x80E1: -case 0x82E1: -case 0x84E1: -case 0x86E1: -case 0x88E1: -case 0x8AE1: -case 0x8CE1: -case 0x8EE1: -case 0x80E2: -case 0x82E2: -case 0x84E2: -case 0x86E2: -case 0x88E2: -case 0x8AE2: -case 0x8CE2: -case 0x8EE2: -case 0x80E3: -case 0x82E3: -case 0x84E3: -case 0x86E3: -case 0x88E3: -case 0x8AE3: -case 0x8CE3: -case 0x8EE3: -case 0x80E4: -case 0x82E4: -case 0x84E4: -case 0x86E4: -case 0x88E4: -case 0x8AE4: -case 0x8CE4: -case 0x8EE4: -case 0x80E5: -case 0x82E5: -case 0x84E5: -case 0x86E5: -case 0x88E5: -case 0x8AE5: -case 0x8CE5: -case 0x8EE5: -case 0x80E6: -case 0x82E6: -case 0x84E6: -case 0x86E6: -case 0x88E6: -case 0x8AE6: -case 0x8CE6: -case 0x8EE6: - -// DIVU -case 0x80E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(16) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(76) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(96) -case 0x82E8: -case 0x84E8: -case 0x86E8: -case 0x88E8: -case 0x8AE8: -case 0x8CE8: -case 0x8EE8: -case 0x80E9: -case 0x82E9: -case 0x84E9: -case 0x86E9: -case 0x88E9: -case 0x8AE9: -case 0x8CE9: -case 0x8EE9: -case 0x80EA: -case 0x82EA: -case 0x84EA: -case 0x86EA: -case 0x88EA: -case 0x8AEA: -case 0x8CEA: -case 0x8EEA: -case 0x80EB: -case 0x82EB: -case 0x84EB: -case 0x86EB: -case 0x88EB: -case 0x8AEB: -case 0x8CEB: -case 0x8EEB: -case 0x80EC: -case 0x82EC: -case 0x84EC: -case 0x86EC: -case 0x88EC: -case 0x8AEC: -case 0x8CEC: -case 0x8EEC: -case 0x80ED: -case 0x82ED: -case 0x84ED: -case 0x86ED: -case 0x88ED: -case 0x8AED: -case 0x8CED: -case 0x8EED: -case 0x80EE: -case 0x82EE: -case 0x84EE: -case 0x86EE: -case 0x88EE: -case 0x8AEE: -case 0x8CEE: -case 0x8EEE: -case 0x80EF: -case 0x82EF: -case 0x84EF: -case 0x86EF: -case 0x88EF: -case 0x8AEF: -case 0x8CEF: -case 0x8EEF: - -// DIVU -case 0x80E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(18) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(78) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(98) -case 0x82F0: -case 0x84F0: -case 0x86F0: -case 0x88F0: -case 0x8AF0: -case 0x8CF0: -case 0x8EF0: -case 0x80F1: -case 0x82F1: -case 0x84F1: -case 0x86F1: -case 0x88F1: -case 0x8AF1: -case 0x8CF1: -case 0x8EF1: -case 0x80F2: -case 0x82F2: -case 0x84F2: -case 0x86F2: -case 0x88F2: -case 0x8AF2: -case 0x8CF2: -case 0x8EF2: -case 0x80F3: -case 0x82F3: -case 0x84F3: -case 0x86F3: -case 0x88F3: -case 0x8AF3: -case 0x8CF3: -case 0x8EF3: -case 0x80F4: -case 0x82F4: -case 0x84F4: -case 0x86F4: -case 0x88F4: -case 0x8AF4: -case 0x8CF4: -case 0x8EF4: -case 0x80F5: -case 0x82F5: -case 0x84F5: -case 0x86F5: -case 0x88F5: -case 0x8AF5: -case 0x8CF5: -case 0x8EF5: -case 0x80F6: -case 0x82F6: -case 0x84F6: -case 0x86F6: -case 0x88F6: -case 0x8AF6: -case 0x8CF6: -case 0x8EF6: -case 0x80F7: -case 0x82F7: -case 0x84F7: -case 0x86F7: -case 0x88F7: -case 0x8AF7: -case 0x8CF7: -case 0x8EF7: - -// DIVU -case 0x80F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(20) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(80) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(100) -case 0x82F8: -case 0x84F8: -case 0x86F8: -case 0x88F8: -case 0x8AF8: -case 0x8CF8: -case 0x8EF8: - -// DIVU -case 0x80F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(18) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(78) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(98) -case 0x82F9: -case 0x84F9: -case 0x86F9: -case 0x88F9: -case 0x8AF9: -case 0x8CF9: -case 0x8EF9: - -// DIVU -case 0x80F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(22) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(82) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(102) -case 0x82FA: -case 0x84FA: -case 0x86FA: -case 0x88FA: -case 0x8AFA: -case 0x8CFA: -case 0x8EFA: - -// DIVU -case 0x80FA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(18) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(78) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(98) -case 0x82FB: -case 0x84FB: -case 0x86FB: -case 0x88FB: -case 0x8AFB: -case 0x8CFB: -case 0x8EFB: - -// DIVU -case 0x80FB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(20) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(80) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(100) -case 0x82FC: -case 0x84FC: -case 0x86FC: -case 0x88FC: -case 0x8AFC: -case 0x8CFC: -case 0x8EFC: - -// DIVU -case 0x80FC: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(14) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(74) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(94) -case 0x82DF: -case 0x84DF: -case 0x86DF: -case 0x88DF: -case 0x8ADF: -case 0x8CDF: -case 0x8EDF: - -// DIVU -case 0x80DF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(14) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(74) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(94) -case 0x82E7: -case 0x84E7: -case 0x86E7: -case 0x88E7: -case 0x8AE7: -case 0x8CE7: -case 0x8EE7: - -// DIVU -case 0x80E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(16) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - { - u32 q, r; - - q = dst / src; - r = dst % src; - - if (q & 0xFFFF0000) - { - CPU->flag_V = C68K_SR_V; - RET(76) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(96) -case 0x83C0: -case 0x85C0: -case 0x87C0: -case 0x89C0: -case 0x8BC0: -case 0x8DC0: -case 0x8FC0: -case 0x81C1: -case 0x83C1: -case 0x85C1: -case 0x87C1: -case 0x89C1: -case 0x8BC1: -case 0x8DC1: -case 0x8FC1: -case 0x81C2: -case 0x83C2: -case 0x85C2: -case 0x87C2: -case 0x89C2: -case 0x8BC2: -case 0x8DC2: -case 0x8FC2: -case 0x81C3: -case 0x83C3: -case 0x85C3: -case 0x87C3: -case 0x89C3: -case 0x8BC3: -case 0x8DC3: -case 0x8FC3: -case 0x81C4: -case 0x83C4: -case 0x85C4: -case 0x87C4: -case 0x89C4: -case 0x8BC4: -case 0x8DC4: -case 0x8FC4: -case 0x81C5: -case 0x83C5: -case 0x85C5: -case 0x87C5: -case 0x89C5: -case 0x8BC5: -case 0x8DC5: -case 0x8FC5: -case 0x81C6: -case 0x83C6: -case 0x85C6: -case 0x87C6: -case 0x89C6: -case 0x8BC6: -case 0x8DC6: -case 0x8FC6: -case 0x81C7: -case 0x83C7: -case 0x85C7: -case 0x87C7: -case 0x89C7: -case 0x8BC7: -case 0x8DC7: -case 0x8FC7: - -// DIVS -case 0x81C0: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(10) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(50) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(80) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(108) -case 0x83D0: -case 0x85D0: -case 0x87D0: -case 0x89D0: -case 0x8BD0: -case 0x8DD0: -case 0x8FD0: -case 0x81D1: -case 0x83D1: -case 0x85D1: -case 0x87D1: -case 0x89D1: -case 0x8BD1: -case 0x8DD1: -case 0x8FD1: -case 0x81D2: -case 0x83D2: -case 0x85D2: -case 0x87D2: -case 0x89D2: -case 0x8BD2: -case 0x8DD2: -case 0x8FD2: -case 0x81D3: -case 0x83D3: -case 0x85D3: -case 0x87D3: -case 0x89D3: -case 0x8BD3: -case 0x8DD3: -case 0x8FD3: -case 0x81D4: -case 0x83D4: -case 0x85D4: -case 0x87D4: -case 0x89D4: -case 0x8BD4: -case 0x8DD4: -case 0x8FD4: -case 0x81D5: -case 0x83D5: -case 0x85D5: -case 0x87D5: -case 0x89D5: -case 0x8BD5: -case 0x8DD5: -case 0x8FD5: -case 0x81D6: -case 0x83D6: -case 0x85D6: -case 0x87D6: -case 0x89D6: -case 0x8BD6: -case 0x8DD6: -case 0x8FD6: -case 0x81D7: -case 0x83D7: -case 0x85D7: -case 0x87D7: -case 0x89D7: -case 0x8BD7: -case 0x8DD7: -case 0x8FD7: - -// DIVS -case 0x81D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(14) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(54) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(84) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(112) -case 0x83D8: -case 0x85D8: -case 0x87D8: -case 0x89D8: -case 0x8BD8: -case 0x8DD8: -case 0x8FD8: -case 0x81D9: -case 0x83D9: -case 0x85D9: -case 0x87D9: -case 0x89D9: -case 0x8BD9: -case 0x8DD9: -case 0x8FD9: -case 0x81DA: -case 0x83DA: -case 0x85DA: -case 0x87DA: -case 0x89DA: -case 0x8BDA: -case 0x8DDA: -case 0x8FDA: -case 0x81DB: -case 0x83DB: -case 0x85DB: -case 0x87DB: -case 0x89DB: -case 0x8BDB: -case 0x8DDB: -case 0x8FDB: -case 0x81DC: -case 0x83DC: -case 0x85DC: -case 0x87DC: -case 0x89DC: -case 0x8BDC: -case 0x8DDC: -case 0x8FDC: -case 0x81DD: -case 0x83DD: -case 0x85DD: -case 0x87DD: -case 0x89DD: -case 0x8BDD: -case 0x8DDD: -case 0x8FDD: -case 0x81DE: -case 0x83DE: -case 0x85DE: -case 0x87DE: -case 0x89DE: -case 0x8BDE: -case 0x8DDE: -case 0x8FDE: - -// DIVS -case 0x81D8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(14) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(54) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(84) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(112) -case 0x83E0: -case 0x85E0: -case 0x87E0: -case 0x89E0: -case 0x8BE0: -case 0x8DE0: -case 0x8FE0: -case 0x81E1: -case 0x83E1: -case 0x85E1: -case 0x87E1: -case 0x89E1: -case 0x8BE1: -case 0x8DE1: -case 0x8FE1: -case 0x81E2: -case 0x83E2: -case 0x85E2: -case 0x87E2: -case 0x89E2: -case 0x8BE2: -case 0x8DE2: -case 0x8FE2: -case 0x81E3: -case 0x83E3: -case 0x85E3: -case 0x87E3: -case 0x89E3: -case 0x8BE3: -case 0x8DE3: -case 0x8FE3: -case 0x81E4: -case 0x83E4: -case 0x85E4: -case 0x87E4: -case 0x89E4: -case 0x8BE4: -case 0x8DE4: -case 0x8FE4: -case 0x81E5: -case 0x83E5: -case 0x85E5: -case 0x87E5: -case 0x89E5: -case 0x8BE5: -case 0x8DE5: -case 0x8FE5: -case 0x81E6: -case 0x83E6: -case 0x85E6: -case 0x87E6: -case 0x89E6: -case 0x8BE6: -case 0x8DE6: -case 0x8FE6: - -// DIVS -case 0x81E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(16) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(56) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(86) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(114) -case 0x83E8: -case 0x85E8: -case 0x87E8: -case 0x89E8: -case 0x8BE8: -case 0x8DE8: -case 0x8FE8: -case 0x81E9: -case 0x83E9: -case 0x85E9: -case 0x87E9: -case 0x89E9: -case 0x8BE9: -case 0x8DE9: -case 0x8FE9: -case 0x81EA: -case 0x83EA: -case 0x85EA: -case 0x87EA: -case 0x89EA: -case 0x8BEA: -case 0x8DEA: -case 0x8FEA: -case 0x81EB: -case 0x83EB: -case 0x85EB: -case 0x87EB: -case 0x89EB: -case 0x8BEB: -case 0x8DEB: -case 0x8FEB: -case 0x81EC: -case 0x83EC: -case 0x85EC: -case 0x87EC: -case 0x89EC: -case 0x8BEC: -case 0x8DEC: -case 0x8FEC: -case 0x81ED: -case 0x83ED: -case 0x85ED: -case 0x87ED: -case 0x89ED: -case 0x8BED: -case 0x8DED: -case 0x8FED: -case 0x81EE: -case 0x83EE: -case 0x85EE: -case 0x87EE: -case 0x89EE: -case 0x8BEE: -case 0x8DEE: -case 0x8FEE: -case 0x81EF: -case 0x83EF: -case 0x85EF: -case 0x87EF: -case 0x89EF: -case 0x8BEF: -case 0x8DEF: -case 0x8FEF: - -// DIVS -case 0x81E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(18) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(58) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(88) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(116) -case 0x83F0: -case 0x85F0: -case 0x87F0: -case 0x89F0: -case 0x8BF0: -case 0x8DF0: -case 0x8FF0: -case 0x81F1: -case 0x83F1: -case 0x85F1: -case 0x87F1: -case 0x89F1: -case 0x8BF1: -case 0x8DF1: -case 0x8FF1: -case 0x81F2: -case 0x83F2: -case 0x85F2: -case 0x87F2: -case 0x89F2: -case 0x8BF2: -case 0x8DF2: -case 0x8FF2: -case 0x81F3: -case 0x83F3: -case 0x85F3: -case 0x87F3: -case 0x89F3: -case 0x8BF3: -case 0x8DF3: -case 0x8FF3: -case 0x81F4: -case 0x83F4: -case 0x85F4: -case 0x87F4: -case 0x89F4: -case 0x8BF4: -case 0x8DF4: -case 0x8FF4: -case 0x81F5: -case 0x83F5: -case 0x85F5: -case 0x87F5: -case 0x89F5: -case 0x8BF5: -case 0x8DF5: -case 0x8FF5: -case 0x81F6: -case 0x83F6: -case 0x85F6: -case 0x87F6: -case 0x89F6: -case 0x8BF6: -case 0x8DF6: -case 0x8FF6: -case 0x81F7: -case 0x83F7: -case 0x85F7: -case 0x87F7: -case 0x89F7: -case 0x8BF7: -case 0x8DF7: -case 0x8FF7: - -// DIVS -case 0x81F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(20) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(60) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(90) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(118) -case 0x83F8: -case 0x85F8: -case 0x87F8: -case 0x89F8: -case 0x8BF8: -case 0x8DF8: -case 0x8FF8: - -// DIVS -case 0x81F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(18) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(58) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(88) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(116) -case 0x83F9: -case 0x85F9: -case 0x87F9: -case 0x89F9: -case 0x8BF9: -case 0x8DF9: -case 0x8FF9: - -// DIVS -case 0x81F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(22) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(62) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(92) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(120) -case 0x83FA: -case 0x85FA: -case 0x87FA: -case 0x89FA: -case 0x8BFA: -case 0x8DFA: -case 0x8FFA: - -// DIVS -case 0x81FA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(18) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(58) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(88) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(116) -case 0x83FB: -case 0x85FB: -case 0x87FB: -case 0x89FB: -case 0x8BFB: -case 0x8DFB: -case 0x8FFB: - -// DIVS -case 0x81FB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(20) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(60) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(90) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(118) -case 0x83FC: -case 0x85FC: -case 0x87FC: -case 0x89FC: -case 0x8BFC: -case 0x8DFC: -case 0x8FFC: - -// DIVS -case 0x81FC: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)FETCH_WORD; - PC += 2; - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(14) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(54) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(84) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(112) -case 0x83DF: -case 0x85DF: -case 0x87DF: -case 0x89DF: -case 0x8BDF: -case 0x8DDF: -case 0x8FDF: - -// DIVS -case 0x81DF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(14) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(54) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(84) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(112) -case 0x83E7: -case 0x85E7: -case 0x87E7: -case 0x89E7: -case 0x8BE7: -case 0x8DE7: -case 0x8FE7: - -// DIVS -case 0x81E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - if (src == 0) - { - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_ZERO_DIVIDE_EX; - POST_IO - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO - RET(16) - } - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - if ((dst == 0x80000000) && (src == -1)) - { - CPU->flag_notZ = CPU->flag_N = 0; - CPU->flag_V = CPU->flag_C = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - RET(56) - } - { - s32 q, r; - - q = (s32)dst / (s32)src; - r = (s32)dst % (s32)src; - - if ((q > 0x7FFF) || (q < -0x8000)) - { - CPU->flag_V = C68K_SR_V; - RET(86) - } - q &= 0x0000FFFF; - CPU->flag_notZ = q; - CPU->flag_N = q >> 8; - CPU->flag_V = CPU->flag_C = 0; - res = q | (r << 16); - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - } -} -RET(114) diff --git a/yabause/src/c68k/c68k_op9.inc b/yabause/src/c68k/c68k_op9.inc deleted file mode 100644 index ef0bdc95c1..0000000000 --- a/yabause/src/c68k/c68k_op9.inc +++ /dev/null @@ -1,5950 +0,0 @@ -case 0x9200: -case 0x9400: -case 0x9600: -case 0x9800: -case 0x9A00: -case 0x9C00: -case 0x9E00: -case 0x9001: -case 0x9201: -case 0x9401: -case 0x9601: -case 0x9801: -case 0x9A01: -case 0x9C01: -case 0x9E01: -case 0x9002: -case 0x9202: -case 0x9402: -case 0x9602: -case 0x9802: -case 0x9A02: -case 0x9C02: -case 0x9E02: -case 0x9003: -case 0x9203: -case 0x9403: -case 0x9603: -case 0x9803: -case 0x9A03: -case 0x9C03: -case 0x9E03: -case 0x9004: -case 0x9204: -case 0x9404: -case 0x9604: -case 0x9804: -case 0x9A04: -case 0x9C04: -case 0x9E04: -case 0x9005: -case 0x9205: -case 0x9405: -case 0x9605: -case 0x9805: -case 0x9A05: -case 0x9C05: -case 0x9E05: -case 0x9006: -case 0x9206: -case 0x9406: -case 0x9606: -case 0x9806: -case 0x9A06: -case 0x9C06: -case 0x9E06: -case 0x9007: -case 0x9207: -case 0x9407: -case 0x9607: -case 0x9807: -case 0x9A07: -case 0x9C07: -case 0x9E07: - -// SUBaD -case 0x9000: -{ - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x9208: -case 0x9408: -case 0x9608: -case 0x9808: -case 0x9A08: -case 0x9C08: -case 0x9E08: -case 0x9009: -case 0x9209: -case 0x9409: -case 0x9609: -case 0x9809: -case 0x9A09: -case 0x9C09: -case 0x9E09: -case 0x900A: -case 0x920A: -case 0x940A: -case 0x960A: -case 0x980A: -case 0x9A0A: -case 0x9C0A: -case 0x9E0A: -case 0x900B: -case 0x920B: -case 0x940B: -case 0x960B: -case 0x980B: -case 0x9A0B: -case 0x9C0B: -case 0x9E0B: -case 0x900C: -case 0x920C: -case 0x940C: -case 0x960C: -case 0x980C: -case 0x9A0C: -case 0x9C0C: -case 0x9E0C: -case 0x900D: -case 0x920D: -case 0x940D: -case 0x960D: -case 0x980D: -case 0x9A0D: -case 0x9C0D: -case 0x9E0D: -case 0x900E: -case 0x920E: -case 0x940E: -case 0x960E: -case 0x980E: -case 0x9A0E: -case 0x9C0E: -case 0x9E0E: -case 0x900F: -case 0x920F: -case 0x940F: -case 0x960F: -case 0x980F: -case 0x9A0F: -case 0x9C0F: -case 0x9E0F: - -// SUBaD -case 0x9008: -{ - u32 res; - pointer dst; - pointer src; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x9210: -case 0x9410: -case 0x9610: -case 0x9810: -case 0x9A10: -case 0x9C10: -case 0x9E10: -case 0x9011: -case 0x9211: -case 0x9411: -case 0x9611: -case 0x9811: -case 0x9A11: -case 0x9C11: -case 0x9E11: -case 0x9012: -case 0x9212: -case 0x9412: -case 0x9612: -case 0x9812: -case 0x9A12: -case 0x9C12: -case 0x9E12: -case 0x9013: -case 0x9213: -case 0x9413: -case 0x9613: -case 0x9813: -case 0x9A13: -case 0x9C13: -case 0x9E13: -case 0x9014: -case 0x9214: -case 0x9414: -case 0x9614: -case 0x9814: -case 0x9A14: -case 0x9C14: -case 0x9E14: -case 0x9015: -case 0x9215: -case 0x9415: -case 0x9615: -case 0x9815: -case 0x9A15: -case 0x9C15: -case 0x9E15: -case 0x9016: -case 0x9216: -case 0x9416: -case 0x9616: -case 0x9816: -case 0x9A16: -case 0x9C16: -case 0x9E16: -case 0x9017: -case 0x9217: -case 0x9417: -case 0x9617: -case 0x9817: -case 0x9A17: -case 0x9C17: -case 0x9E17: - -// SUBaD -case 0x9010: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x9218: -case 0x9418: -case 0x9618: -case 0x9818: -case 0x9A18: -case 0x9C18: -case 0x9E18: -case 0x9019: -case 0x9219: -case 0x9419: -case 0x9619: -case 0x9819: -case 0x9A19: -case 0x9C19: -case 0x9E19: -case 0x901A: -case 0x921A: -case 0x941A: -case 0x961A: -case 0x981A: -case 0x9A1A: -case 0x9C1A: -case 0x9E1A: -case 0x901B: -case 0x921B: -case 0x941B: -case 0x961B: -case 0x981B: -case 0x9A1B: -case 0x9C1B: -case 0x9E1B: -case 0x901C: -case 0x921C: -case 0x941C: -case 0x961C: -case 0x981C: -case 0x9A1C: -case 0x9C1C: -case 0x9E1C: -case 0x901D: -case 0x921D: -case 0x941D: -case 0x961D: -case 0x981D: -case 0x9A1D: -case 0x9C1D: -case 0x9E1D: -case 0x901E: -case 0x921E: -case 0x941E: -case 0x961E: -case 0x981E: -case 0x9A1E: -case 0x9C1E: -case 0x9E1E: - -// SUBaD -case 0x9018: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x9220: -case 0x9420: -case 0x9620: -case 0x9820: -case 0x9A20: -case 0x9C20: -case 0x9E20: -case 0x9021: -case 0x9221: -case 0x9421: -case 0x9621: -case 0x9821: -case 0x9A21: -case 0x9C21: -case 0x9E21: -case 0x9022: -case 0x9222: -case 0x9422: -case 0x9622: -case 0x9822: -case 0x9A22: -case 0x9C22: -case 0x9E22: -case 0x9023: -case 0x9223: -case 0x9423: -case 0x9623: -case 0x9823: -case 0x9A23: -case 0x9C23: -case 0x9E23: -case 0x9024: -case 0x9224: -case 0x9424: -case 0x9624: -case 0x9824: -case 0x9A24: -case 0x9C24: -case 0x9E24: -case 0x9025: -case 0x9225: -case 0x9425: -case 0x9625: -case 0x9825: -case 0x9A25: -case 0x9C25: -case 0x9E25: -case 0x9026: -case 0x9226: -case 0x9426: -case 0x9626: -case 0x9826: -case 0x9A26: -case 0x9C26: -case 0x9E26: - -// SUBaD -case 0x9020: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x9228: -case 0x9428: -case 0x9628: -case 0x9828: -case 0x9A28: -case 0x9C28: -case 0x9E28: -case 0x9029: -case 0x9229: -case 0x9429: -case 0x9629: -case 0x9829: -case 0x9A29: -case 0x9C29: -case 0x9E29: -case 0x902A: -case 0x922A: -case 0x942A: -case 0x962A: -case 0x982A: -case 0x9A2A: -case 0x9C2A: -case 0x9E2A: -case 0x902B: -case 0x922B: -case 0x942B: -case 0x962B: -case 0x982B: -case 0x9A2B: -case 0x9C2B: -case 0x9E2B: -case 0x902C: -case 0x922C: -case 0x942C: -case 0x962C: -case 0x982C: -case 0x9A2C: -case 0x9C2C: -case 0x9E2C: -case 0x902D: -case 0x922D: -case 0x942D: -case 0x962D: -case 0x982D: -case 0x9A2D: -case 0x9C2D: -case 0x9E2D: -case 0x902E: -case 0x922E: -case 0x942E: -case 0x962E: -case 0x982E: -case 0x9A2E: -case 0x9C2E: -case 0x9E2E: -case 0x902F: -case 0x922F: -case 0x942F: -case 0x962F: -case 0x982F: -case 0x9A2F: -case 0x9C2F: -case 0x9E2F: - -// SUBaD -case 0x9028: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x9230: -case 0x9430: -case 0x9630: -case 0x9830: -case 0x9A30: -case 0x9C30: -case 0x9E30: -case 0x9031: -case 0x9231: -case 0x9431: -case 0x9631: -case 0x9831: -case 0x9A31: -case 0x9C31: -case 0x9E31: -case 0x9032: -case 0x9232: -case 0x9432: -case 0x9632: -case 0x9832: -case 0x9A32: -case 0x9C32: -case 0x9E32: -case 0x9033: -case 0x9233: -case 0x9433: -case 0x9633: -case 0x9833: -case 0x9A33: -case 0x9C33: -case 0x9E33: -case 0x9034: -case 0x9234: -case 0x9434: -case 0x9634: -case 0x9834: -case 0x9A34: -case 0x9C34: -case 0x9E34: -case 0x9035: -case 0x9235: -case 0x9435: -case 0x9635: -case 0x9835: -case 0x9A35: -case 0x9C35: -case 0x9E35: -case 0x9036: -case 0x9236: -case 0x9436: -case 0x9636: -case 0x9836: -case 0x9A36: -case 0x9C36: -case 0x9E36: -case 0x9037: -case 0x9237: -case 0x9437: -case 0x9637: -case 0x9837: -case 0x9A37: -case 0x9C37: -case 0x9E37: - -// SUBaD -case 0x9030: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x9238: -case 0x9438: -case 0x9638: -case 0x9838: -case 0x9A38: -case 0x9C38: -case 0x9E38: - -// SUBaD -case 0x9038: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x9239: -case 0x9439: -case 0x9639: -case 0x9839: -case 0x9A39: -case 0x9C39: -case 0x9E39: - -// SUBaD -case 0x9039: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x923A: -case 0x943A: -case 0x963A: -case 0x983A: -case 0x9A3A: -case 0x9C3A: -case 0x9E3A: - -// SUBaD -case 0x903A: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x923B: -case 0x943B: -case 0x963B: -case 0x983B: -case 0x9A3B: -case 0x9C3B: -case 0x9E3B: - -// SUBaD -case 0x903B: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x923C: -case 0x943C: -case 0x963C: -case 0x983C: -case 0x9A3C: -case 0x9C3C: -case 0x9E3C: - -// SUBaD -case 0x903C: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0x921F: -case 0x941F: -case 0x961F: -case 0x981F: -case 0x9A1F: -case 0x9C1F: -case 0x9E1F: - -// SUBaD -case 0x901F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x9227: -case 0x9427: -case 0x9627: -case 0x9827: -case 0x9A27: -case 0x9C27: -case 0x9E27: - -// SUBaD -case 0x9027: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x9240: -case 0x9440: -case 0x9640: -case 0x9840: -case 0x9A40: -case 0x9C40: -case 0x9E40: -case 0x9041: -case 0x9241: -case 0x9441: -case 0x9641: -case 0x9841: -case 0x9A41: -case 0x9C41: -case 0x9E41: -case 0x9042: -case 0x9242: -case 0x9442: -case 0x9642: -case 0x9842: -case 0x9A42: -case 0x9C42: -case 0x9E42: -case 0x9043: -case 0x9243: -case 0x9443: -case 0x9643: -case 0x9843: -case 0x9A43: -case 0x9C43: -case 0x9E43: -case 0x9044: -case 0x9244: -case 0x9444: -case 0x9644: -case 0x9844: -case 0x9A44: -case 0x9C44: -case 0x9E44: -case 0x9045: -case 0x9245: -case 0x9445: -case 0x9645: -case 0x9845: -case 0x9A45: -case 0x9C45: -case 0x9E45: -case 0x9046: -case 0x9246: -case 0x9446: -case 0x9646: -case 0x9846: -case 0x9A46: -case 0x9C46: -case 0x9E46: -case 0x9047: -case 0x9247: -case 0x9447: -case 0x9647: -case 0x9847: -case 0x9A47: -case 0x9C47: -case 0x9E47: - -// SUBaD -case 0x9040: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x9248: -case 0x9448: -case 0x9648: -case 0x9848: -case 0x9A48: -case 0x9C48: -case 0x9E48: -case 0x9049: -case 0x9249: -case 0x9449: -case 0x9649: -case 0x9849: -case 0x9A49: -case 0x9C49: -case 0x9E49: -case 0x904A: -case 0x924A: -case 0x944A: -case 0x964A: -case 0x984A: -case 0x9A4A: -case 0x9C4A: -case 0x9E4A: -case 0x904B: -case 0x924B: -case 0x944B: -case 0x964B: -case 0x984B: -case 0x9A4B: -case 0x9C4B: -case 0x9E4B: -case 0x904C: -case 0x924C: -case 0x944C: -case 0x964C: -case 0x984C: -case 0x9A4C: -case 0x9C4C: -case 0x9E4C: -case 0x904D: -case 0x924D: -case 0x944D: -case 0x964D: -case 0x984D: -case 0x9A4D: -case 0x9C4D: -case 0x9E4D: -case 0x904E: -case 0x924E: -case 0x944E: -case 0x964E: -case 0x984E: -case 0x9A4E: -case 0x9C4E: -case 0x9E4E: -case 0x904F: -case 0x924F: -case 0x944F: -case 0x964F: -case 0x984F: -case 0x9A4F: -case 0x9C4F: -case 0x9E4F: - -// SUBaD -case 0x9048: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->A[(Opcode >> 0) & 7]; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x9250: -case 0x9450: -case 0x9650: -case 0x9850: -case 0x9A50: -case 0x9C50: -case 0x9E50: -case 0x9051: -case 0x9251: -case 0x9451: -case 0x9651: -case 0x9851: -case 0x9A51: -case 0x9C51: -case 0x9E51: -case 0x9052: -case 0x9252: -case 0x9452: -case 0x9652: -case 0x9852: -case 0x9A52: -case 0x9C52: -case 0x9E52: -case 0x9053: -case 0x9253: -case 0x9453: -case 0x9653: -case 0x9853: -case 0x9A53: -case 0x9C53: -case 0x9E53: -case 0x9054: -case 0x9254: -case 0x9454: -case 0x9654: -case 0x9854: -case 0x9A54: -case 0x9C54: -case 0x9E54: -case 0x9055: -case 0x9255: -case 0x9455: -case 0x9655: -case 0x9855: -case 0x9A55: -case 0x9C55: -case 0x9E55: -case 0x9056: -case 0x9256: -case 0x9456: -case 0x9656: -case 0x9856: -case 0x9A56: -case 0x9C56: -case 0x9E56: -case 0x9057: -case 0x9257: -case 0x9457: -case 0x9657: -case 0x9857: -case 0x9A57: -case 0x9C57: -case 0x9E57: - -// SUBaD -case 0x9050: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x9258: -case 0x9458: -case 0x9658: -case 0x9858: -case 0x9A58: -case 0x9C58: -case 0x9E58: -case 0x9059: -case 0x9259: -case 0x9459: -case 0x9659: -case 0x9859: -case 0x9A59: -case 0x9C59: -case 0x9E59: -case 0x905A: -case 0x925A: -case 0x945A: -case 0x965A: -case 0x985A: -case 0x9A5A: -case 0x9C5A: -case 0x9E5A: -case 0x905B: -case 0x925B: -case 0x945B: -case 0x965B: -case 0x985B: -case 0x9A5B: -case 0x9C5B: -case 0x9E5B: -case 0x905C: -case 0x925C: -case 0x945C: -case 0x965C: -case 0x985C: -case 0x9A5C: -case 0x9C5C: -case 0x9E5C: -case 0x905D: -case 0x925D: -case 0x945D: -case 0x965D: -case 0x985D: -case 0x9A5D: -case 0x9C5D: -case 0x9E5D: -case 0x905E: -case 0x925E: -case 0x945E: -case 0x965E: -case 0x985E: -case 0x9A5E: -case 0x9C5E: -case 0x9E5E: - -// SUBaD -case 0x9058: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x9260: -case 0x9460: -case 0x9660: -case 0x9860: -case 0x9A60: -case 0x9C60: -case 0x9E60: -case 0x9061: -case 0x9261: -case 0x9461: -case 0x9661: -case 0x9861: -case 0x9A61: -case 0x9C61: -case 0x9E61: -case 0x9062: -case 0x9262: -case 0x9462: -case 0x9662: -case 0x9862: -case 0x9A62: -case 0x9C62: -case 0x9E62: -case 0x9063: -case 0x9263: -case 0x9463: -case 0x9663: -case 0x9863: -case 0x9A63: -case 0x9C63: -case 0x9E63: -case 0x9064: -case 0x9264: -case 0x9464: -case 0x9664: -case 0x9864: -case 0x9A64: -case 0x9C64: -case 0x9E64: -case 0x9065: -case 0x9265: -case 0x9465: -case 0x9665: -case 0x9865: -case 0x9A65: -case 0x9C65: -case 0x9E65: -case 0x9066: -case 0x9266: -case 0x9466: -case 0x9666: -case 0x9866: -case 0x9A66: -case 0x9C66: -case 0x9E66: - -// SUBaD -case 0x9060: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x9268: -case 0x9468: -case 0x9668: -case 0x9868: -case 0x9A68: -case 0x9C68: -case 0x9E68: -case 0x9069: -case 0x9269: -case 0x9469: -case 0x9669: -case 0x9869: -case 0x9A69: -case 0x9C69: -case 0x9E69: -case 0x906A: -case 0x926A: -case 0x946A: -case 0x966A: -case 0x986A: -case 0x9A6A: -case 0x9C6A: -case 0x9E6A: -case 0x906B: -case 0x926B: -case 0x946B: -case 0x966B: -case 0x986B: -case 0x9A6B: -case 0x9C6B: -case 0x9E6B: -case 0x906C: -case 0x926C: -case 0x946C: -case 0x966C: -case 0x986C: -case 0x9A6C: -case 0x9C6C: -case 0x9E6C: -case 0x906D: -case 0x926D: -case 0x946D: -case 0x966D: -case 0x986D: -case 0x9A6D: -case 0x9C6D: -case 0x9E6D: -case 0x906E: -case 0x926E: -case 0x946E: -case 0x966E: -case 0x986E: -case 0x9A6E: -case 0x9C6E: -case 0x9E6E: -case 0x906F: -case 0x926F: -case 0x946F: -case 0x966F: -case 0x986F: -case 0x9A6F: -case 0x9C6F: -case 0x9E6F: - -// SUBaD -case 0x9068: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x9270: -case 0x9470: -case 0x9670: -case 0x9870: -case 0x9A70: -case 0x9C70: -case 0x9E70: -case 0x9071: -case 0x9271: -case 0x9471: -case 0x9671: -case 0x9871: -case 0x9A71: -case 0x9C71: -case 0x9E71: -case 0x9072: -case 0x9272: -case 0x9472: -case 0x9672: -case 0x9872: -case 0x9A72: -case 0x9C72: -case 0x9E72: -case 0x9073: -case 0x9273: -case 0x9473: -case 0x9673: -case 0x9873: -case 0x9A73: -case 0x9C73: -case 0x9E73: -case 0x9074: -case 0x9274: -case 0x9474: -case 0x9674: -case 0x9874: -case 0x9A74: -case 0x9C74: -case 0x9E74: -case 0x9075: -case 0x9275: -case 0x9475: -case 0x9675: -case 0x9875: -case 0x9A75: -case 0x9C75: -case 0x9E75: -case 0x9076: -case 0x9276: -case 0x9476: -case 0x9676: -case 0x9876: -case 0x9A76: -case 0x9C76: -case 0x9E76: -case 0x9077: -case 0x9277: -case 0x9477: -case 0x9677: -case 0x9877: -case 0x9A77: -case 0x9C77: -case 0x9E77: - -// SUBaD -case 0x9070: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x9278: -case 0x9478: -case 0x9678: -case 0x9878: -case 0x9A78: -case 0x9C78: -case 0x9E78: - -// SUBaD -case 0x9078: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x9279: -case 0x9479: -case 0x9679: -case 0x9879: -case 0x9A79: -case 0x9C79: -case 0x9E79: - -// SUBaD -case 0x9079: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x927A: -case 0x947A: -case 0x967A: -case 0x987A: -case 0x9A7A: -case 0x9C7A: -case 0x9E7A: - -// SUBaD -case 0x907A: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0x927B: -case 0x947B: -case 0x967B: -case 0x987B: -case 0x9A7B: -case 0x9C7B: -case 0x9E7B: - -// SUBaD -case 0x907B: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0x927C: -case 0x947C: -case 0x967C: -case 0x987C: -case 0x9A7C: -case 0x9C7C: -case 0x9E7C: - -// SUBaD -case 0x907C: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0x925F: -case 0x945F: -case 0x965F: -case 0x985F: -case 0x9A5F: -case 0x9C5F: -case 0x9E5F: - -// SUBaD -case 0x905F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0x9267: -case 0x9467: -case 0x9667: -case 0x9867: -case 0x9A67: -case 0x9C67: -case 0x9E67: - -// SUBaD -case 0x9067: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0x9280: -case 0x9480: -case 0x9680: -case 0x9880: -case 0x9A80: -case 0x9C80: -case 0x9E80: -case 0x9081: -case 0x9281: -case 0x9481: -case 0x9681: -case 0x9881: -case 0x9A81: -case 0x9C81: -case 0x9E81: -case 0x9082: -case 0x9282: -case 0x9482: -case 0x9682: -case 0x9882: -case 0x9A82: -case 0x9C82: -case 0x9E82: -case 0x9083: -case 0x9283: -case 0x9483: -case 0x9683: -case 0x9883: -case 0x9A83: -case 0x9C83: -case 0x9E83: -case 0x9084: -case 0x9284: -case 0x9484: -case 0x9684: -case 0x9884: -case 0x9A84: -case 0x9C84: -case 0x9E84: -case 0x9085: -case 0x9285: -case 0x9485: -case 0x9685: -case 0x9885: -case 0x9A85: -case 0x9C85: -case 0x9E85: -case 0x9086: -case 0x9286: -case 0x9486: -case 0x9686: -case 0x9886: -case 0x9A86: -case 0x9C86: -case 0x9E86: -case 0x9087: -case 0x9287: -case 0x9487: -case 0x9687: -case 0x9887: -case 0x9A87: -case 0x9C87: -case 0x9E87: - -// SUBaD -case 0x9080: -{ - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(6) -case 0x9288: -case 0x9488: -case 0x9688: -case 0x9888: -case 0x9A88: -case 0x9C88: -case 0x9E88: -case 0x9089: -case 0x9289: -case 0x9489: -case 0x9689: -case 0x9889: -case 0x9A89: -case 0x9C89: -case 0x9E89: -case 0x908A: -case 0x928A: -case 0x948A: -case 0x968A: -case 0x988A: -case 0x9A8A: -case 0x9C8A: -case 0x9E8A: -case 0x908B: -case 0x928B: -case 0x948B: -case 0x968B: -case 0x988B: -case 0x9A8B: -case 0x9C8B: -case 0x9E8B: -case 0x908C: -case 0x928C: -case 0x948C: -case 0x968C: -case 0x988C: -case 0x9A8C: -case 0x9C8C: -case 0x9E8C: -case 0x908D: -case 0x928D: -case 0x948D: -case 0x968D: -case 0x988D: -case 0x9A8D: -case 0x9C8D: -case 0x9E8D: -case 0x908E: -case 0x928E: -case 0x948E: -case 0x968E: -case 0x988E: -case 0x9A8E: -case 0x9C8E: -case 0x9E8E: -case 0x908F: -case 0x928F: -case 0x948F: -case 0x968F: -case 0x988F: -case 0x9A8F: -case 0x9C8F: -case 0x9E8F: - -// SUBaD -case 0x9088: -{ - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(6) -case 0x9290: -case 0x9490: -case 0x9690: -case 0x9890: -case 0x9A90: -case 0x9C90: -case 0x9E90: -case 0x9091: -case 0x9291: -case 0x9491: -case 0x9691: -case 0x9891: -case 0x9A91: -case 0x9C91: -case 0x9E91: -case 0x9092: -case 0x9292: -case 0x9492: -case 0x9692: -case 0x9892: -case 0x9A92: -case 0x9C92: -case 0x9E92: -case 0x9093: -case 0x9293: -case 0x9493: -case 0x9693: -case 0x9893: -case 0x9A93: -case 0x9C93: -case 0x9E93: -case 0x9094: -case 0x9294: -case 0x9494: -case 0x9694: -case 0x9894: -case 0x9A94: -case 0x9C94: -case 0x9E94: -case 0x9095: -case 0x9295: -case 0x9495: -case 0x9695: -case 0x9895: -case 0x9A95: -case 0x9C95: -case 0x9E95: -case 0x9096: -case 0x9296: -case 0x9496: -case 0x9696: -case 0x9896: -case 0x9A96: -case 0x9C96: -case 0x9E96: -case 0x9097: -case 0x9297: -case 0x9497: -case 0x9697: -case 0x9897: -case 0x9A97: -case 0x9C97: -case 0x9E97: - -// SUBaD -case 0x9090: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x9298: -case 0x9498: -case 0x9698: -case 0x9898: -case 0x9A98: -case 0x9C98: -case 0x9E98: -case 0x9099: -case 0x9299: -case 0x9499: -case 0x9699: -case 0x9899: -case 0x9A99: -case 0x9C99: -case 0x9E99: -case 0x909A: -case 0x929A: -case 0x949A: -case 0x969A: -case 0x989A: -case 0x9A9A: -case 0x9C9A: -case 0x9E9A: -case 0x909B: -case 0x929B: -case 0x949B: -case 0x969B: -case 0x989B: -case 0x9A9B: -case 0x9C9B: -case 0x9E9B: -case 0x909C: -case 0x929C: -case 0x949C: -case 0x969C: -case 0x989C: -case 0x9A9C: -case 0x9C9C: -case 0x9E9C: -case 0x909D: -case 0x929D: -case 0x949D: -case 0x969D: -case 0x989D: -case 0x9A9D: -case 0x9C9D: -case 0x9E9D: -case 0x909E: -case 0x929E: -case 0x949E: -case 0x969E: -case 0x989E: -case 0x9A9E: -case 0x9C9E: -case 0x9E9E: - -// SUBaD -case 0x9098: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x92A0: -case 0x94A0: -case 0x96A0: -case 0x98A0: -case 0x9AA0: -case 0x9CA0: -case 0x9EA0: -case 0x90A1: -case 0x92A1: -case 0x94A1: -case 0x96A1: -case 0x98A1: -case 0x9AA1: -case 0x9CA1: -case 0x9EA1: -case 0x90A2: -case 0x92A2: -case 0x94A2: -case 0x96A2: -case 0x98A2: -case 0x9AA2: -case 0x9CA2: -case 0x9EA2: -case 0x90A3: -case 0x92A3: -case 0x94A3: -case 0x96A3: -case 0x98A3: -case 0x9AA3: -case 0x9CA3: -case 0x9EA3: -case 0x90A4: -case 0x92A4: -case 0x94A4: -case 0x96A4: -case 0x98A4: -case 0x9AA4: -case 0x9CA4: -case 0x9EA4: -case 0x90A5: -case 0x92A5: -case 0x94A5: -case 0x96A5: -case 0x98A5: -case 0x9AA5: -case 0x9CA5: -case 0x9EA5: -case 0x90A6: -case 0x92A6: -case 0x94A6: -case 0x96A6: -case 0x98A6: -case 0x9AA6: -case 0x9CA6: -case 0x9EA6: - -// SUBaD -case 0x90A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0x92A8: -case 0x94A8: -case 0x96A8: -case 0x98A8: -case 0x9AA8: -case 0x9CA8: -case 0x9EA8: -case 0x90A9: -case 0x92A9: -case 0x94A9: -case 0x96A9: -case 0x98A9: -case 0x9AA9: -case 0x9CA9: -case 0x9EA9: -case 0x90AA: -case 0x92AA: -case 0x94AA: -case 0x96AA: -case 0x98AA: -case 0x9AAA: -case 0x9CAA: -case 0x9EAA: -case 0x90AB: -case 0x92AB: -case 0x94AB: -case 0x96AB: -case 0x98AB: -case 0x9AAB: -case 0x9CAB: -case 0x9EAB: -case 0x90AC: -case 0x92AC: -case 0x94AC: -case 0x96AC: -case 0x98AC: -case 0x9AAC: -case 0x9CAC: -case 0x9EAC: -case 0x90AD: -case 0x92AD: -case 0x94AD: -case 0x96AD: -case 0x98AD: -case 0x9AAD: -case 0x9CAD: -case 0x9EAD: -case 0x90AE: -case 0x92AE: -case 0x94AE: -case 0x96AE: -case 0x98AE: -case 0x9AAE: -case 0x9CAE: -case 0x9EAE: -case 0x90AF: -case 0x92AF: -case 0x94AF: -case 0x96AF: -case 0x98AF: -case 0x9AAF: -case 0x9CAF: -case 0x9EAF: - -// SUBaD -case 0x90A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0x92B0: -case 0x94B0: -case 0x96B0: -case 0x98B0: -case 0x9AB0: -case 0x9CB0: -case 0x9EB0: -case 0x90B1: -case 0x92B1: -case 0x94B1: -case 0x96B1: -case 0x98B1: -case 0x9AB1: -case 0x9CB1: -case 0x9EB1: -case 0x90B2: -case 0x92B2: -case 0x94B2: -case 0x96B2: -case 0x98B2: -case 0x9AB2: -case 0x9CB2: -case 0x9EB2: -case 0x90B3: -case 0x92B3: -case 0x94B3: -case 0x96B3: -case 0x98B3: -case 0x9AB3: -case 0x9CB3: -case 0x9EB3: -case 0x90B4: -case 0x92B4: -case 0x94B4: -case 0x96B4: -case 0x98B4: -case 0x9AB4: -case 0x9CB4: -case 0x9EB4: -case 0x90B5: -case 0x92B5: -case 0x94B5: -case 0x96B5: -case 0x98B5: -case 0x9AB5: -case 0x9CB5: -case 0x9EB5: -case 0x90B6: -case 0x92B6: -case 0x94B6: -case 0x96B6: -case 0x98B6: -case 0x9AB6: -case 0x9CB6: -case 0x9EB6: -case 0x90B7: -case 0x92B7: -case 0x94B7: -case 0x96B7: -case 0x98B7: -case 0x9AB7: -case 0x9CB7: -case 0x9EB7: - -// SUBaD -case 0x90B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(22) -case 0x92B8: -case 0x94B8: -case 0x96B8: -case 0x98B8: -case 0x9AB8: -case 0x9CB8: -case 0x9EB8: - -// SUBaD -case 0x90B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0x92B9: -case 0x94B9: -case 0x96B9: -case 0x98B9: -case 0x9AB9: -case 0x9CB9: -case 0x9EB9: - -// SUBaD -case 0x90B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(24) -case 0x92BA: -case 0x94BA: -case 0x96BA: -case 0x98BA: -case 0x9ABA: -case 0x9CBA: -case 0x9EBA: - -// SUBaD -case 0x90BA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0x92BB: -case 0x94BB: -case 0x96BB: -case 0x98BB: -case 0x9ABB: -case 0x9CBB: -case 0x9EBB: - -// SUBaD -case 0x90BB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(22) -case 0x92BC: -case 0x94BC: -case 0x96BC: -case 0x98BC: -case 0x9ABC: -case 0x9CBC: -case 0x9EBC: - -// SUBaD -case 0x90BC: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(14) -case 0x929F: -case 0x949F: -case 0x969F: -case 0x989F: -case 0x9A9F: -case 0x9C9F: -case 0x9E9F: - -// SUBaD -case 0x909F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0x92A7: -case 0x94A7: -case 0x96A7: -case 0x98A7: -case 0x9AA7: -case 0x9CA7: -case 0x9EA7: - -// SUBaD -case 0x90A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0x9310: -case 0x9510: -case 0x9710: -case 0x9910: -case 0x9B10: -case 0x9D10: -case 0x9F10: -case 0x9111: -case 0x9311: -case 0x9511: -case 0x9711: -case 0x9911: -case 0x9B11: -case 0x9D11: -case 0x9F11: -case 0x9112: -case 0x9312: -case 0x9512: -case 0x9712: -case 0x9912: -case 0x9B12: -case 0x9D12: -case 0x9F12: -case 0x9113: -case 0x9313: -case 0x9513: -case 0x9713: -case 0x9913: -case 0x9B13: -case 0x9D13: -case 0x9F13: -case 0x9114: -case 0x9314: -case 0x9514: -case 0x9714: -case 0x9914: -case 0x9B14: -case 0x9D14: -case 0x9F14: -case 0x9115: -case 0x9315: -case 0x9515: -case 0x9715: -case 0x9915: -case 0x9B15: -case 0x9D15: -case 0x9F15: -case 0x9116: -case 0x9316: -case 0x9516: -case 0x9716: -case 0x9916: -case 0x9B16: -case 0x9D16: -case 0x9F16: -case 0x9117: -case 0x9317: -case 0x9517: -case 0x9717: -case 0x9917: -case 0x9B17: -case 0x9D17: -case 0x9F17: - -// SUBDa -case 0x9110: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x9318: -case 0x9518: -case 0x9718: -case 0x9918: -case 0x9B18: -case 0x9D18: -case 0x9F18: -case 0x9119: -case 0x9319: -case 0x9519: -case 0x9719: -case 0x9919: -case 0x9B19: -case 0x9D19: -case 0x9F19: -case 0x911A: -case 0x931A: -case 0x951A: -case 0x971A: -case 0x991A: -case 0x9B1A: -case 0x9D1A: -case 0x9F1A: -case 0x911B: -case 0x931B: -case 0x951B: -case 0x971B: -case 0x991B: -case 0x9B1B: -case 0x9D1B: -case 0x9F1B: -case 0x911C: -case 0x931C: -case 0x951C: -case 0x971C: -case 0x991C: -case 0x9B1C: -case 0x9D1C: -case 0x9F1C: -case 0x911D: -case 0x931D: -case 0x951D: -case 0x971D: -case 0x991D: -case 0x9B1D: -case 0x9D1D: -case 0x9F1D: -case 0x911E: -case 0x931E: -case 0x951E: -case 0x971E: -case 0x991E: -case 0x9B1E: -case 0x9D1E: -case 0x9F1E: - -// SUBDa -case 0x9118: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x9320: -case 0x9520: -case 0x9720: -case 0x9920: -case 0x9B20: -case 0x9D20: -case 0x9F20: -case 0x9121: -case 0x9321: -case 0x9521: -case 0x9721: -case 0x9921: -case 0x9B21: -case 0x9D21: -case 0x9F21: -case 0x9122: -case 0x9322: -case 0x9522: -case 0x9722: -case 0x9922: -case 0x9B22: -case 0x9D22: -case 0x9F22: -case 0x9123: -case 0x9323: -case 0x9523: -case 0x9723: -case 0x9923: -case 0x9B23: -case 0x9D23: -case 0x9F23: -case 0x9124: -case 0x9324: -case 0x9524: -case 0x9724: -case 0x9924: -case 0x9B24: -case 0x9D24: -case 0x9F24: -case 0x9125: -case 0x9325: -case 0x9525: -case 0x9725: -case 0x9925: -case 0x9B25: -case 0x9D25: -case 0x9F25: -case 0x9126: -case 0x9326: -case 0x9526: -case 0x9726: -case 0x9926: -case 0x9B26: -case 0x9D26: -case 0x9F26: - -// SUBDa -case 0x9120: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x9328: -case 0x9528: -case 0x9728: -case 0x9928: -case 0x9B28: -case 0x9D28: -case 0x9F28: -case 0x9129: -case 0x9329: -case 0x9529: -case 0x9729: -case 0x9929: -case 0x9B29: -case 0x9D29: -case 0x9F29: -case 0x912A: -case 0x932A: -case 0x952A: -case 0x972A: -case 0x992A: -case 0x9B2A: -case 0x9D2A: -case 0x9F2A: -case 0x912B: -case 0x932B: -case 0x952B: -case 0x972B: -case 0x992B: -case 0x9B2B: -case 0x9D2B: -case 0x9F2B: -case 0x912C: -case 0x932C: -case 0x952C: -case 0x972C: -case 0x992C: -case 0x9B2C: -case 0x9D2C: -case 0x9F2C: -case 0x912D: -case 0x932D: -case 0x952D: -case 0x972D: -case 0x992D: -case 0x9B2D: -case 0x9D2D: -case 0x9F2D: -case 0x912E: -case 0x932E: -case 0x952E: -case 0x972E: -case 0x992E: -case 0x9B2E: -case 0x9D2E: -case 0x9F2E: -case 0x912F: -case 0x932F: -case 0x952F: -case 0x972F: -case 0x992F: -case 0x9B2F: -case 0x9D2F: -case 0x9F2F: - -// SUBDa -case 0x9128: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x9330: -case 0x9530: -case 0x9730: -case 0x9930: -case 0x9B30: -case 0x9D30: -case 0x9F30: -case 0x9131: -case 0x9331: -case 0x9531: -case 0x9731: -case 0x9931: -case 0x9B31: -case 0x9D31: -case 0x9F31: -case 0x9132: -case 0x9332: -case 0x9532: -case 0x9732: -case 0x9932: -case 0x9B32: -case 0x9D32: -case 0x9F32: -case 0x9133: -case 0x9333: -case 0x9533: -case 0x9733: -case 0x9933: -case 0x9B33: -case 0x9D33: -case 0x9F33: -case 0x9134: -case 0x9334: -case 0x9534: -case 0x9734: -case 0x9934: -case 0x9B34: -case 0x9D34: -case 0x9F34: -case 0x9135: -case 0x9335: -case 0x9535: -case 0x9735: -case 0x9935: -case 0x9B35: -case 0x9D35: -case 0x9F35: -case 0x9136: -case 0x9336: -case 0x9536: -case 0x9736: -case 0x9936: -case 0x9B36: -case 0x9D36: -case 0x9F36: -case 0x9137: -case 0x9337: -case 0x9537: -case 0x9737: -case 0x9937: -case 0x9B37: -case 0x9D37: -case 0x9F37: - -// SUBDa -case 0x9130: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x9338: -case 0x9538: -case 0x9738: -case 0x9938: -case 0x9B38: -case 0x9D38: -case 0x9F38: - -// SUBDa -case 0x9138: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0x9339: -case 0x9539: -case 0x9739: -case 0x9939: -case 0x9B39: -case 0x9D39: -case 0x9F39: - -// SUBDa -case 0x9139: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0x931F: -case 0x951F: -case 0x971F: -case 0x991F: -case 0x9B1F: -case 0x9D1F: -case 0x9F1F: - -// SUBDa -case 0x911F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0x9327: -case 0x9527: -case 0x9727: -case 0x9927: -case 0x9B27: -case 0x9D27: -case 0x9F27: - -// SUBDa -case 0x9127: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0x9350: -case 0x9550: -case 0x9750: -case 0x9950: -case 0x9B50: -case 0x9D50: -case 0x9F50: -case 0x9151: -case 0x9351: -case 0x9551: -case 0x9751: -case 0x9951: -case 0x9B51: -case 0x9D51: -case 0x9F51: -case 0x9152: -case 0x9352: -case 0x9552: -case 0x9752: -case 0x9952: -case 0x9B52: -case 0x9D52: -case 0x9F52: -case 0x9153: -case 0x9353: -case 0x9553: -case 0x9753: -case 0x9953: -case 0x9B53: -case 0x9D53: -case 0x9F53: -case 0x9154: -case 0x9354: -case 0x9554: -case 0x9754: -case 0x9954: -case 0x9B54: -case 0x9D54: -case 0x9F54: -case 0x9155: -case 0x9355: -case 0x9555: -case 0x9755: -case 0x9955: -case 0x9B55: -case 0x9D55: -case 0x9F55: -case 0x9156: -case 0x9356: -case 0x9556: -case 0x9756: -case 0x9956: -case 0x9B56: -case 0x9D56: -case 0x9F56: -case 0x9157: -case 0x9357: -case 0x9557: -case 0x9757: -case 0x9957: -case 0x9B57: -case 0x9D57: -case 0x9F57: - -// SUBDa -case 0x9150: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x9358: -case 0x9558: -case 0x9758: -case 0x9958: -case 0x9B58: -case 0x9D58: -case 0x9F58: -case 0x9159: -case 0x9359: -case 0x9559: -case 0x9759: -case 0x9959: -case 0x9B59: -case 0x9D59: -case 0x9F59: -case 0x915A: -case 0x935A: -case 0x955A: -case 0x975A: -case 0x995A: -case 0x9B5A: -case 0x9D5A: -case 0x9F5A: -case 0x915B: -case 0x935B: -case 0x955B: -case 0x975B: -case 0x995B: -case 0x9B5B: -case 0x9D5B: -case 0x9F5B: -case 0x915C: -case 0x935C: -case 0x955C: -case 0x975C: -case 0x995C: -case 0x9B5C: -case 0x9D5C: -case 0x9F5C: -case 0x915D: -case 0x935D: -case 0x955D: -case 0x975D: -case 0x995D: -case 0x9B5D: -case 0x9D5D: -case 0x9F5D: -case 0x915E: -case 0x935E: -case 0x955E: -case 0x975E: -case 0x995E: -case 0x9B5E: -case 0x9D5E: -case 0x9F5E: - -// SUBDa -case 0x9158: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x9360: -case 0x9560: -case 0x9760: -case 0x9960: -case 0x9B60: -case 0x9D60: -case 0x9F60: -case 0x9161: -case 0x9361: -case 0x9561: -case 0x9761: -case 0x9961: -case 0x9B61: -case 0x9D61: -case 0x9F61: -case 0x9162: -case 0x9362: -case 0x9562: -case 0x9762: -case 0x9962: -case 0x9B62: -case 0x9D62: -case 0x9F62: -case 0x9163: -case 0x9363: -case 0x9563: -case 0x9763: -case 0x9963: -case 0x9B63: -case 0x9D63: -case 0x9F63: -case 0x9164: -case 0x9364: -case 0x9564: -case 0x9764: -case 0x9964: -case 0x9B64: -case 0x9D64: -case 0x9F64: -case 0x9165: -case 0x9365: -case 0x9565: -case 0x9765: -case 0x9965: -case 0x9B65: -case 0x9D65: -case 0x9F65: -case 0x9166: -case 0x9366: -case 0x9566: -case 0x9766: -case 0x9966: -case 0x9B66: -case 0x9D66: -case 0x9F66: - -// SUBDa -case 0x9160: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x9368: -case 0x9568: -case 0x9768: -case 0x9968: -case 0x9B68: -case 0x9D68: -case 0x9F68: -case 0x9169: -case 0x9369: -case 0x9569: -case 0x9769: -case 0x9969: -case 0x9B69: -case 0x9D69: -case 0x9F69: -case 0x916A: -case 0x936A: -case 0x956A: -case 0x976A: -case 0x996A: -case 0x9B6A: -case 0x9D6A: -case 0x9F6A: -case 0x916B: -case 0x936B: -case 0x956B: -case 0x976B: -case 0x996B: -case 0x9B6B: -case 0x9D6B: -case 0x9F6B: -case 0x916C: -case 0x936C: -case 0x956C: -case 0x976C: -case 0x996C: -case 0x9B6C: -case 0x9D6C: -case 0x9F6C: -case 0x916D: -case 0x936D: -case 0x956D: -case 0x976D: -case 0x996D: -case 0x9B6D: -case 0x9D6D: -case 0x9F6D: -case 0x916E: -case 0x936E: -case 0x956E: -case 0x976E: -case 0x996E: -case 0x9B6E: -case 0x9D6E: -case 0x9F6E: -case 0x916F: -case 0x936F: -case 0x956F: -case 0x976F: -case 0x996F: -case 0x9B6F: -case 0x9D6F: -case 0x9F6F: - -// SUBDa -case 0x9168: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x9370: -case 0x9570: -case 0x9770: -case 0x9970: -case 0x9B70: -case 0x9D70: -case 0x9F70: -case 0x9171: -case 0x9371: -case 0x9571: -case 0x9771: -case 0x9971: -case 0x9B71: -case 0x9D71: -case 0x9F71: -case 0x9172: -case 0x9372: -case 0x9572: -case 0x9772: -case 0x9972: -case 0x9B72: -case 0x9D72: -case 0x9F72: -case 0x9173: -case 0x9373: -case 0x9573: -case 0x9773: -case 0x9973: -case 0x9B73: -case 0x9D73: -case 0x9F73: -case 0x9174: -case 0x9374: -case 0x9574: -case 0x9774: -case 0x9974: -case 0x9B74: -case 0x9D74: -case 0x9F74: -case 0x9175: -case 0x9375: -case 0x9575: -case 0x9775: -case 0x9975: -case 0x9B75: -case 0x9D75: -case 0x9F75: -case 0x9176: -case 0x9376: -case 0x9576: -case 0x9776: -case 0x9976: -case 0x9B76: -case 0x9D76: -case 0x9F76: -case 0x9177: -case 0x9377: -case 0x9577: -case 0x9777: -case 0x9977: -case 0x9B77: -case 0x9D77: -case 0x9F77: - -// SUBDa -case 0x9170: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x9378: -case 0x9578: -case 0x9778: -case 0x9978: -case 0x9B78: -case 0x9D78: -case 0x9F78: - -// SUBDa -case 0x9178: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0x9379: -case 0x9579: -case 0x9779: -case 0x9979: -case 0x9B79: -case 0x9D79: -case 0x9F79: - -// SUBDa -case 0x9179: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0x935F: -case 0x955F: -case 0x975F: -case 0x995F: -case 0x9B5F: -case 0x9D5F: -case 0x9F5F: - -// SUBDa -case 0x915F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0x9367: -case 0x9567: -case 0x9767: -case 0x9967: -case 0x9B67: -case 0x9D67: -case 0x9F67: - -// SUBDa -case 0x9167: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0x9390: -case 0x9590: -case 0x9790: -case 0x9990: -case 0x9B90: -case 0x9D90: -case 0x9F90: -case 0x9191: -case 0x9391: -case 0x9591: -case 0x9791: -case 0x9991: -case 0x9B91: -case 0x9D91: -case 0x9F91: -case 0x9192: -case 0x9392: -case 0x9592: -case 0x9792: -case 0x9992: -case 0x9B92: -case 0x9D92: -case 0x9F92: -case 0x9193: -case 0x9393: -case 0x9593: -case 0x9793: -case 0x9993: -case 0x9B93: -case 0x9D93: -case 0x9F93: -case 0x9194: -case 0x9394: -case 0x9594: -case 0x9794: -case 0x9994: -case 0x9B94: -case 0x9D94: -case 0x9F94: -case 0x9195: -case 0x9395: -case 0x9595: -case 0x9795: -case 0x9995: -case 0x9B95: -case 0x9D95: -case 0x9F95: -case 0x9196: -case 0x9396: -case 0x9596: -case 0x9796: -case 0x9996: -case 0x9B96: -case 0x9D96: -case 0x9F96: -case 0x9197: -case 0x9397: -case 0x9597: -case 0x9797: -case 0x9997: -case 0x9B97: -case 0x9D97: -case 0x9F97: - -// SUBDa -case 0x9190: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x9398: -case 0x9598: -case 0x9798: -case 0x9998: -case 0x9B98: -case 0x9D98: -case 0x9F98: -case 0x9199: -case 0x9399: -case 0x9599: -case 0x9799: -case 0x9999: -case 0x9B99: -case 0x9D99: -case 0x9F99: -case 0x919A: -case 0x939A: -case 0x959A: -case 0x979A: -case 0x999A: -case 0x9B9A: -case 0x9D9A: -case 0x9F9A: -case 0x919B: -case 0x939B: -case 0x959B: -case 0x979B: -case 0x999B: -case 0x9B9B: -case 0x9D9B: -case 0x9F9B: -case 0x919C: -case 0x939C: -case 0x959C: -case 0x979C: -case 0x999C: -case 0x9B9C: -case 0x9D9C: -case 0x9F9C: -case 0x919D: -case 0x939D: -case 0x959D: -case 0x979D: -case 0x999D: -case 0x9B9D: -case 0x9D9D: -case 0x9F9D: -case 0x919E: -case 0x939E: -case 0x959E: -case 0x979E: -case 0x999E: -case 0x9B9E: -case 0x9D9E: -case 0x9F9E: - -// SUBDa -case 0x9198: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x93A0: -case 0x95A0: -case 0x97A0: -case 0x99A0: -case 0x9BA0: -case 0x9DA0: -case 0x9FA0: -case 0x91A1: -case 0x93A1: -case 0x95A1: -case 0x97A1: -case 0x99A1: -case 0x9BA1: -case 0x9DA1: -case 0x9FA1: -case 0x91A2: -case 0x93A2: -case 0x95A2: -case 0x97A2: -case 0x99A2: -case 0x9BA2: -case 0x9DA2: -case 0x9FA2: -case 0x91A3: -case 0x93A3: -case 0x95A3: -case 0x97A3: -case 0x99A3: -case 0x9BA3: -case 0x9DA3: -case 0x9FA3: -case 0x91A4: -case 0x93A4: -case 0x95A4: -case 0x97A4: -case 0x99A4: -case 0x9BA4: -case 0x9DA4: -case 0x9FA4: -case 0x91A5: -case 0x93A5: -case 0x95A5: -case 0x97A5: -case 0x99A5: -case 0x9BA5: -case 0x9DA5: -case 0x9FA5: -case 0x91A6: -case 0x93A6: -case 0x95A6: -case 0x97A6: -case 0x99A6: -case 0x9BA6: -case 0x9DA6: -case 0x9FA6: - -// SUBDa -case 0x91A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x93A8: -case 0x95A8: -case 0x97A8: -case 0x99A8: -case 0x9BA8: -case 0x9DA8: -case 0x9FA8: -case 0x91A9: -case 0x93A9: -case 0x95A9: -case 0x97A9: -case 0x99A9: -case 0x9BA9: -case 0x9DA9: -case 0x9FA9: -case 0x91AA: -case 0x93AA: -case 0x95AA: -case 0x97AA: -case 0x99AA: -case 0x9BAA: -case 0x9DAA: -case 0x9FAA: -case 0x91AB: -case 0x93AB: -case 0x95AB: -case 0x97AB: -case 0x99AB: -case 0x9BAB: -case 0x9DAB: -case 0x9FAB: -case 0x91AC: -case 0x93AC: -case 0x95AC: -case 0x97AC: -case 0x99AC: -case 0x9BAC: -case 0x9DAC: -case 0x9FAC: -case 0x91AD: -case 0x93AD: -case 0x95AD: -case 0x97AD: -case 0x99AD: -case 0x9BAD: -case 0x9DAD: -case 0x9FAD: -case 0x91AE: -case 0x93AE: -case 0x95AE: -case 0x97AE: -case 0x99AE: -case 0x9BAE: -case 0x9DAE: -case 0x9FAE: -case 0x91AF: -case 0x93AF: -case 0x95AF: -case 0x97AF: -case 0x99AF: -case 0x9BAF: -case 0x9DAF: -case 0x9FAF: - -// SUBDa -case 0x91A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x93B0: -case 0x95B0: -case 0x97B0: -case 0x99B0: -case 0x9BB0: -case 0x9DB0: -case 0x9FB0: -case 0x91B1: -case 0x93B1: -case 0x95B1: -case 0x97B1: -case 0x99B1: -case 0x9BB1: -case 0x9DB1: -case 0x9FB1: -case 0x91B2: -case 0x93B2: -case 0x95B2: -case 0x97B2: -case 0x99B2: -case 0x9BB2: -case 0x9DB2: -case 0x9FB2: -case 0x91B3: -case 0x93B3: -case 0x95B3: -case 0x97B3: -case 0x99B3: -case 0x9BB3: -case 0x9DB3: -case 0x9FB3: -case 0x91B4: -case 0x93B4: -case 0x95B4: -case 0x97B4: -case 0x99B4: -case 0x9BB4: -case 0x9DB4: -case 0x9FB4: -case 0x91B5: -case 0x93B5: -case 0x95B5: -case 0x97B5: -case 0x99B5: -case 0x9BB5: -case 0x9DB5: -case 0x9FB5: -case 0x91B6: -case 0x93B6: -case 0x95B6: -case 0x97B6: -case 0x99B6: -case 0x9BB6: -case 0x9DB6: -case 0x9FB6: -case 0x91B7: -case 0x93B7: -case 0x95B7: -case 0x97B7: -case 0x99B7: -case 0x9BB7: -case 0x9DB7: -case 0x9FB7: - -// SUBDa -case 0x91B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0x93B8: -case 0x95B8: -case 0x97B8: -case 0x99B8: -case 0x9BB8: -case 0x9DB8: -case 0x9FB8: - -// SUBDa -case 0x91B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0x93B9: -case 0x95B9: -case 0x97B9: -case 0x99B9: -case 0x9BB9: -case 0x9DB9: -case 0x9FB9: - -// SUBDa -case 0x91B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0x939F: -case 0x959F: -case 0x979F: -case 0x999F: -case 0x9B9F: -case 0x9D9F: -case 0x9F9F: - -// SUBDa -case 0x919F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0x93A7: -case 0x95A7: -case 0x97A7: -case 0x99A7: -case 0x9BA7: -case 0x9DA7: -case 0x9FA7: - -// SUBDa -case 0x91A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0x9300: -case 0x9500: -case 0x9700: -case 0x9900: -case 0x9B00: -case 0x9D00: -case 0x9F00: -case 0x9101: -case 0x9301: -case 0x9501: -case 0x9701: -case 0x9901: -case 0x9B01: -case 0x9D01: -case 0x9F01: -case 0x9102: -case 0x9302: -case 0x9502: -case 0x9702: -case 0x9902: -case 0x9B02: -case 0x9D02: -case 0x9F02: -case 0x9103: -case 0x9303: -case 0x9503: -case 0x9703: -case 0x9903: -case 0x9B03: -case 0x9D03: -case 0x9F03: -case 0x9104: -case 0x9304: -case 0x9504: -case 0x9704: -case 0x9904: -case 0x9B04: -case 0x9D04: -case 0x9F04: -case 0x9105: -case 0x9305: -case 0x9505: -case 0x9705: -case 0x9905: -case 0x9B05: -case 0x9D05: -case 0x9F05: -case 0x9106: -case 0x9306: -case 0x9506: -case 0x9706: -case 0x9906: -case 0x9B06: -case 0x9D06: -case 0x9F06: -case 0x9107: -case 0x9307: -case 0x9507: -case 0x9707: -case 0x9907: -case 0x9B07: -case 0x9D07: -case 0x9F07: - -// SUBX -case 0x9100: -{ - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ |= res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x9340: -case 0x9540: -case 0x9740: -case 0x9940: -case 0x9B40: -case 0x9D40: -case 0x9F40: -case 0x9141: -case 0x9341: -case 0x9541: -case 0x9741: -case 0x9941: -case 0x9B41: -case 0x9D41: -case 0x9F41: -case 0x9142: -case 0x9342: -case 0x9542: -case 0x9742: -case 0x9942: -case 0x9B42: -case 0x9D42: -case 0x9F42: -case 0x9143: -case 0x9343: -case 0x9543: -case 0x9743: -case 0x9943: -case 0x9B43: -case 0x9D43: -case 0x9F43: -case 0x9144: -case 0x9344: -case 0x9544: -case 0x9744: -case 0x9944: -case 0x9B44: -case 0x9D44: -case 0x9F44: -case 0x9145: -case 0x9345: -case 0x9545: -case 0x9745: -case 0x9945: -case 0x9B45: -case 0x9D45: -case 0x9F45: -case 0x9146: -case 0x9346: -case 0x9546: -case 0x9746: -case 0x9946: -case 0x9B46: -case 0x9D46: -case 0x9F46: -case 0x9147: -case 0x9347: -case 0x9547: -case 0x9747: -case 0x9947: -case 0x9B47: -case 0x9D47: -case 0x9F47: - -// SUBX -case 0x9140: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0x9380: -case 0x9580: -case 0x9780: -case 0x9980: -case 0x9B80: -case 0x9D80: -case 0x9F80: -case 0x9181: -case 0x9381: -case 0x9581: -case 0x9781: -case 0x9981: -case 0x9B81: -case 0x9D81: -case 0x9F81: -case 0x9182: -case 0x9382: -case 0x9582: -case 0x9782: -case 0x9982: -case 0x9B82: -case 0x9D82: -case 0x9F82: -case 0x9183: -case 0x9383: -case 0x9583: -case 0x9783: -case 0x9983: -case 0x9B83: -case 0x9D83: -case 0x9F83: -case 0x9184: -case 0x9384: -case 0x9584: -case 0x9784: -case 0x9984: -case 0x9B84: -case 0x9D84: -case 0x9F84: -case 0x9185: -case 0x9385: -case 0x9585: -case 0x9785: -case 0x9985: -case 0x9B85: -case 0x9D85: -case 0x9F85: -case 0x9186: -case 0x9386: -case 0x9586: -case 0x9786: -case 0x9986: -case 0x9B86: -case 0x9D86: -case 0x9F86: -case 0x9187: -case 0x9387: -case 0x9587: -case 0x9787: -case 0x9987: -case 0x9B87: -case 0x9D87: -case 0x9F87: - -// SUBX -case 0x9180: -{ - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0x9308: -case 0x9508: -case 0x9708: -case 0x9908: -case 0x9B08: -case 0x9D08: -case 0x9109: -case 0x9309: -case 0x9509: -case 0x9709: -case 0x9909: -case 0x9B09: -case 0x9D09: -case 0x910A: -case 0x930A: -case 0x950A: -case 0x970A: -case 0x990A: -case 0x9B0A: -case 0x9D0A: -case 0x910B: -case 0x930B: -case 0x950B: -case 0x970B: -case 0x990B: -case 0x9B0B: -case 0x9D0B: -case 0x910C: -case 0x930C: -case 0x950C: -case 0x970C: -case 0x990C: -case 0x9B0C: -case 0x9D0C: -case 0x910D: -case 0x930D: -case 0x950D: -case 0x970D: -case 0x990D: -case 0x9B0D: -case 0x9D0D: -case 0x910E: -case 0x930E: -case 0x950E: -case 0x970E: -case 0x990E: -case 0x9B0E: -case 0x9D0E: - -// SUBXM -case 0x9108: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_BYTE_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x9348: -case 0x9548: -case 0x9748: -case 0x9948: -case 0x9B48: -case 0x9D48: -case 0x9149: -case 0x9349: -case 0x9549: -case 0x9749: -case 0x9949: -case 0x9B49: -case 0x9D49: -case 0x914A: -case 0x934A: -case 0x954A: -case 0x974A: -case 0x994A: -case 0x9B4A: -case 0x9D4A: -case 0x914B: -case 0x934B: -case 0x954B: -case 0x974B: -case 0x994B: -case 0x9B4B: -case 0x9D4B: -case 0x914C: -case 0x934C: -case 0x954C: -case 0x974C: -case 0x994C: -case 0x9B4C: -case 0x9D4C: -case 0x914D: -case 0x934D: -case 0x954D: -case 0x974D: -case 0x994D: -case 0x9B4D: -case 0x9D4D: -case 0x914E: -case 0x934E: -case 0x954E: -case 0x974E: -case 0x994E: -case 0x9B4E: -case 0x9D4E: - -// SUBXM -case 0x9148: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_WORD_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x9388: -case 0x9588: -case 0x9788: -case 0x9988: -case 0x9B88: -case 0x9D88: -case 0x9189: -case 0x9389: -case 0x9589: -case 0x9789: -case 0x9989: -case 0x9B89: -case 0x9D89: -case 0x918A: -case 0x938A: -case 0x958A: -case 0x978A: -case 0x998A: -case 0x9B8A: -case 0x9D8A: -case 0x918B: -case 0x938B: -case 0x958B: -case 0x978B: -case 0x998B: -case 0x9B8B: -case 0x9D8B: -case 0x918C: -case 0x938C: -case 0x958C: -case 0x978C: -case 0x998C: -case 0x9B8C: -case 0x9D8C: -case 0x918D: -case 0x938D: -case 0x958D: -case 0x978D: -case 0x998D: -case 0x9B8D: -case 0x9D8D: -case 0x918E: -case 0x938E: -case 0x958E: -case 0x978E: -case 0x998E: -case 0x9B8E: -case 0x9D8E: - -// SUBXM -case 0x9188: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_LONG_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x930F: -case 0x950F: -case 0x970F: -case 0x990F: -case 0x9B0F: -case 0x9D0F: - -// SUBX7M -case 0x910F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_BYTE_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x934F: -case 0x954F: -case 0x974F: -case 0x994F: -case 0x9B4F: -case 0x9D4F: - -// SUBX7M -case 0x914F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_WORD_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x938F: -case 0x958F: -case 0x978F: -case 0x998F: -case 0x9B8F: -case 0x9D8F: - -// SUBX7M -case 0x918F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_LONG_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x9F09: -case 0x9F0A: -case 0x9F0B: -case 0x9F0C: -case 0x9F0D: -case 0x9F0E: - -// SUBXM7 -case 0x9F08: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_BYTE_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0x9F49: -case 0x9F4A: -case 0x9F4B: -case 0x9F4C: -case 0x9F4D: -case 0x9F4E: - -// SUBXM7 -case 0x9F48: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_WORD_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0x9F89: -case 0x9F8A: -case 0x9F8B: -case 0x9F8C: -case 0x9F8D: -case 0x9F8E: - -// SUBXM7 -case 0x9F88: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - READ_LONG_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// SUBX7M7 -case 0x9F0F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_BYTE_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// SUBX7M7 -case 0x9F4F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_WORD_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// SUBX7M7 -case 0x9F8F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - READ_LONG_F(adr, dst) - res = dst - src - ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0x92C0: -case 0x94C0: -case 0x96C0: -case 0x98C0: -case 0x9AC0: -case 0x9CC0: -case 0x9EC0: -case 0x90C1: -case 0x92C1: -case 0x94C1: -case 0x96C1: -case 0x98C1: -case 0x9AC1: -case 0x9CC1: -case 0x9EC1: -case 0x90C2: -case 0x92C2: -case 0x94C2: -case 0x96C2: -case 0x98C2: -case 0x9AC2: -case 0x9CC2: -case 0x9EC2: -case 0x90C3: -case 0x92C3: -case 0x94C3: -case 0x96C3: -case 0x98C3: -case 0x9AC3: -case 0x9CC3: -case 0x9EC3: -case 0x90C4: -case 0x92C4: -case 0x94C4: -case 0x96C4: -case 0x98C4: -case 0x9AC4: -case 0x9CC4: -case 0x9EC4: -case 0x90C5: -case 0x92C5: -case 0x94C5: -case 0x96C5: -case 0x98C5: -case 0x9AC5: -case 0x9CC5: -case 0x9EC5: -case 0x90C6: -case 0x92C6: -case 0x94C6: -case 0x96C6: -case 0x98C6: -case 0x9AC6: -case 0x9CC6: -case 0x9EC6: -case 0x90C7: -case 0x92C7: -case 0x94C7: -case 0x96C7: -case 0x98C7: -case 0x9AC7: -case 0x9CC7: -case 0x9EC7: - -// SUBA -case 0x90C0: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(8) -case 0x92C8: -case 0x94C8: -case 0x96C8: -case 0x98C8: -case 0x9AC8: -case 0x9CC8: -case 0x9EC8: -case 0x90C9: -case 0x92C9: -case 0x94C9: -case 0x96C9: -case 0x98C9: -case 0x9AC9: -case 0x9CC9: -case 0x9EC9: -case 0x90CA: -case 0x92CA: -case 0x94CA: -case 0x96CA: -case 0x98CA: -case 0x9ACA: -case 0x9CCA: -case 0x9ECA: -case 0x90CB: -case 0x92CB: -case 0x94CB: -case 0x96CB: -case 0x98CB: -case 0x9ACB: -case 0x9CCB: -case 0x9ECB: -case 0x90CC: -case 0x92CC: -case 0x94CC: -case 0x96CC: -case 0x98CC: -case 0x9ACC: -case 0x9CCC: -case 0x9ECC: -case 0x90CD: -case 0x92CD: -case 0x94CD: -case 0x96CD: -case 0x98CD: -case 0x9ACD: -case 0x9CCD: -case 0x9ECD: -case 0x90CE: -case 0x92CE: -case 0x94CE: -case 0x96CE: -case 0x98CE: -case 0x9ACE: -case 0x9CCE: -case 0x9ECE: -case 0x90CF: -case 0x92CF: -case 0x94CF: -case 0x96CF: -case 0x98CF: -case 0x9ACF: -case 0x9CCF: -case 0x9ECF: - -// SUBA -case 0x90C8: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(8) -case 0x92D0: -case 0x94D0: -case 0x96D0: -case 0x98D0: -case 0x9AD0: -case 0x9CD0: -case 0x9ED0: -case 0x90D1: -case 0x92D1: -case 0x94D1: -case 0x96D1: -case 0x98D1: -case 0x9AD1: -case 0x9CD1: -case 0x9ED1: -case 0x90D2: -case 0x92D2: -case 0x94D2: -case 0x96D2: -case 0x98D2: -case 0x9AD2: -case 0x9CD2: -case 0x9ED2: -case 0x90D3: -case 0x92D3: -case 0x94D3: -case 0x96D3: -case 0x98D3: -case 0x9AD3: -case 0x9CD3: -case 0x9ED3: -case 0x90D4: -case 0x92D4: -case 0x94D4: -case 0x96D4: -case 0x98D4: -case 0x9AD4: -case 0x9CD4: -case 0x9ED4: -case 0x90D5: -case 0x92D5: -case 0x94D5: -case 0x96D5: -case 0x98D5: -case 0x9AD5: -case 0x9CD5: -case 0x9ED5: -case 0x90D6: -case 0x92D6: -case 0x94D6: -case 0x96D6: -case 0x98D6: -case 0x9AD6: -case 0x9CD6: -case 0x9ED6: -case 0x90D7: -case 0x92D7: -case 0x94D7: -case 0x96D7: -case 0x98D7: -case 0x9AD7: -case 0x9CD7: -case 0x9ED7: - -// SUBA -case 0x90D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x92D8: -case 0x94D8: -case 0x96D8: -case 0x98D8: -case 0x9AD8: -case 0x9CD8: -case 0x9ED8: -case 0x90D9: -case 0x92D9: -case 0x94D9: -case 0x96D9: -case 0x98D9: -case 0x9AD9: -case 0x9CD9: -case 0x9ED9: -case 0x90DA: -case 0x92DA: -case 0x94DA: -case 0x96DA: -case 0x98DA: -case 0x9ADA: -case 0x9CDA: -case 0x9EDA: -case 0x90DB: -case 0x92DB: -case 0x94DB: -case 0x96DB: -case 0x98DB: -case 0x9ADB: -case 0x9CDB: -case 0x9EDB: -case 0x90DC: -case 0x92DC: -case 0x94DC: -case 0x96DC: -case 0x98DC: -case 0x9ADC: -case 0x9CDC: -case 0x9EDC: -case 0x90DD: -case 0x92DD: -case 0x94DD: -case 0x96DD: -case 0x98DD: -case 0x9ADD: -case 0x9CDD: -case 0x9EDD: -case 0x90DE: -case 0x92DE: -case 0x94DE: -case 0x96DE: -case 0x98DE: -case 0x9ADE: -case 0x9CDE: -case 0x9EDE: - -// SUBA -case 0x90D8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x92E0: -case 0x94E0: -case 0x96E0: -case 0x98E0: -case 0x9AE0: -case 0x9CE0: -case 0x9EE0: -case 0x90E1: -case 0x92E1: -case 0x94E1: -case 0x96E1: -case 0x98E1: -case 0x9AE1: -case 0x9CE1: -case 0x9EE1: -case 0x90E2: -case 0x92E2: -case 0x94E2: -case 0x96E2: -case 0x98E2: -case 0x9AE2: -case 0x9CE2: -case 0x9EE2: -case 0x90E3: -case 0x92E3: -case 0x94E3: -case 0x96E3: -case 0x98E3: -case 0x9AE3: -case 0x9CE3: -case 0x9EE3: -case 0x90E4: -case 0x92E4: -case 0x94E4: -case 0x96E4: -case 0x98E4: -case 0x9AE4: -case 0x9CE4: -case 0x9EE4: -case 0x90E5: -case 0x92E5: -case 0x94E5: -case 0x96E5: -case 0x98E5: -case 0x9AE5: -case 0x9CE5: -case 0x9EE5: -case 0x90E6: -case 0x92E6: -case 0x94E6: -case 0x96E6: -case 0x98E6: -case 0x9AE6: -case 0x9CE6: -case 0x9EE6: - -// SUBA -case 0x90E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(14) -case 0x92E8: -case 0x94E8: -case 0x96E8: -case 0x98E8: -case 0x9AE8: -case 0x9CE8: -case 0x9EE8: -case 0x90E9: -case 0x92E9: -case 0x94E9: -case 0x96E9: -case 0x98E9: -case 0x9AE9: -case 0x9CE9: -case 0x9EE9: -case 0x90EA: -case 0x92EA: -case 0x94EA: -case 0x96EA: -case 0x98EA: -case 0x9AEA: -case 0x9CEA: -case 0x9EEA: -case 0x90EB: -case 0x92EB: -case 0x94EB: -case 0x96EB: -case 0x98EB: -case 0x9AEB: -case 0x9CEB: -case 0x9EEB: -case 0x90EC: -case 0x92EC: -case 0x94EC: -case 0x96EC: -case 0x98EC: -case 0x9AEC: -case 0x9CEC: -case 0x9EEC: -case 0x90ED: -case 0x92ED: -case 0x94ED: -case 0x96ED: -case 0x98ED: -case 0x9AED: -case 0x9CED: -case 0x9EED: -case 0x90EE: -case 0x92EE: -case 0x94EE: -case 0x96EE: -case 0x98EE: -case 0x9AEE: -case 0x9CEE: -case 0x9EEE: -case 0x90EF: -case 0x92EF: -case 0x94EF: -case 0x96EF: -case 0x98EF: -case 0x9AEF: -case 0x9CEF: -case 0x9EEF: - -// SUBA -case 0x90E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x92F0: -case 0x94F0: -case 0x96F0: -case 0x98F0: -case 0x9AF0: -case 0x9CF0: -case 0x9EF0: -case 0x90F1: -case 0x92F1: -case 0x94F1: -case 0x96F1: -case 0x98F1: -case 0x9AF1: -case 0x9CF1: -case 0x9EF1: -case 0x90F2: -case 0x92F2: -case 0x94F2: -case 0x96F2: -case 0x98F2: -case 0x9AF2: -case 0x9CF2: -case 0x9EF2: -case 0x90F3: -case 0x92F3: -case 0x94F3: -case 0x96F3: -case 0x98F3: -case 0x9AF3: -case 0x9CF3: -case 0x9EF3: -case 0x90F4: -case 0x92F4: -case 0x94F4: -case 0x96F4: -case 0x98F4: -case 0x9AF4: -case 0x9CF4: -case 0x9EF4: -case 0x90F5: -case 0x92F5: -case 0x94F5: -case 0x96F5: -case 0x98F5: -case 0x9AF5: -case 0x9CF5: -case 0x9EF5: -case 0x90F6: -case 0x92F6: -case 0x94F6: -case 0x96F6: -case 0x98F6: -case 0x9AF6: -case 0x9CF6: -case 0x9EF6: -case 0x90F7: -case 0x92F7: -case 0x94F7: -case 0x96F7: -case 0x98F7: -case 0x9AF7: -case 0x9CF7: -case 0x9EF7: - -// SUBA -case 0x90F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) -case 0x92F8: -case 0x94F8: -case 0x96F8: -case 0x98F8: -case 0x9AF8: -case 0x9CF8: -case 0x9EF8: - -// SUBA -case 0x90F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x92F9: -case 0x94F9: -case 0x96F9: -case 0x98F9: -case 0x9AF9: -case 0x9CF9: -case 0x9EF9: - -// SUBA -case 0x90F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0x92FA: -case 0x94FA: -case 0x96FA: -case 0x98FA: -case 0x9AFA: -case 0x9CFA: -case 0x9EFA: - -// SUBA -case 0x90FA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x92FB: -case 0x94FB: -case 0x96FB: -case 0x98FB: -case 0x9AFB: -case 0x9CFB: -case 0x9EFB: - -// SUBA -case 0x90FB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) -case 0x92FC: -case 0x94FC: -case 0x96FC: -case 0x98FC: -case 0x9AFC: -case 0x9CFC: -case 0x9EFC: - -// SUBA -case 0x90FC: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)FETCH_WORD; - PC += 2; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(12) -case 0x92DF: -case 0x94DF: -case 0x96DF: -case 0x98DF: -case 0x9ADF: -case 0x9CDF: -case 0x9EDF: - -// SUBA -case 0x90DF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0x92E7: -case 0x94E7: -case 0x96E7: -case 0x98E7: -case 0x9AE7: -case 0x9CE7: -case 0x9EE7: - -// SUBA -case 0x90E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(14) -case 0x93C0: -case 0x95C0: -case 0x97C0: -case 0x99C0: -case 0x9BC0: -case 0x9DC0: -case 0x9FC0: -case 0x91C1: -case 0x93C1: -case 0x95C1: -case 0x97C1: -case 0x99C1: -case 0x9BC1: -case 0x9DC1: -case 0x9FC1: -case 0x91C2: -case 0x93C2: -case 0x95C2: -case 0x97C2: -case 0x99C2: -case 0x9BC2: -case 0x9DC2: -case 0x9FC2: -case 0x91C3: -case 0x93C3: -case 0x95C3: -case 0x97C3: -case 0x99C3: -case 0x9BC3: -case 0x9DC3: -case 0x9FC3: -case 0x91C4: -case 0x93C4: -case 0x95C4: -case 0x97C4: -case 0x99C4: -case 0x9BC4: -case 0x9DC4: -case 0x9FC4: -case 0x91C5: -case 0x93C5: -case 0x95C5: -case 0x97C5: -case 0x99C5: -case 0x9BC5: -case 0x9DC5: -case 0x9FC5: -case 0x91C6: -case 0x93C6: -case 0x95C6: -case 0x97C6: -case 0x99C6: -case 0x9BC6: -case 0x9DC6: -case 0x9FC6: -case 0x91C7: -case 0x93C7: -case 0x95C7: -case 0x97C7: -case 0x99C7: -case 0x9BC7: -case 0x9DC7: -case 0x9FC7: - -// SUBA -case 0x91C0: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(6) -case 0x93C8: -case 0x95C8: -case 0x97C8: -case 0x99C8: -case 0x9BC8: -case 0x9DC8: -case 0x9FC8: -case 0x91C9: -case 0x93C9: -case 0x95C9: -case 0x97C9: -case 0x99C9: -case 0x9BC9: -case 0x9DC9: -case 0x9FC9: -case 0x91CA: -case 0x93CA: -case 0x95CA: -case 0x97CA: -case 0x99CA: -case 0x9BCA: -case 0x9DCA: -case 0x9FCA: -case 0x91CB: -case 0x93CB: -case 0x95CB: -case 0x97CB: -case 0x99CB: -case 0x9BCB: -case 0x9DCB: -case 0x9FCB: -case 0x91CC: -case 0x93CC: -case 0x95CC: -case 0x97CC: -case 0x99CC: -case 0x9BCC: -case 0x9DCC: -case 0x9FCC: -case 0x91CD: -case 0x93CD: -case 0x95CD: -case 0x97CD: -case 0x99CD: -case 0x9BCD: -case 0x9DCD: -case 0x9FCD: -case 0x91CE: -case 0x93CE: -case 0x95CE: -case 0x97CE: -case 0x99CE: -case 0x9BCE: -case 0x9DCE: -case 0x9FCE: -case 0x91CF: -case 0x93CF: -case 0x95CF: -case 0x97CF: -case 0x99CF: -case 0x9BCF: -case 0x9DCF: -case 0x9FCF: - -// SUBA -case 0x91C8: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(6) -case 0x93D0: -case 0x95D0: -case 0x97D0: -case 0x99D0: -case 0x9BD0: -case 0x9DD0: -case 0x9FD0: -case 0x91D1: -case 0x93D1: -case 0x95D1: -case 0x97D1: -case 0x99D1: -case 0x9BD1: -case 0x9DD1: -case 0x9FD1: -case 0x91D2: -case 0x93D2: -case 0x95D2: -case 0x97D2: -case 0x99D2: -case 0x9BD2: -case 0x9DD2: -case 0x9FD2: -case 0x91D3: -case 0x93D3: -case 0x95D3: -case 0x97D3: -case 0x99D3: -case 0x9BD3: -case 0x9DD3: -case 0x9FD3: -case 0x91D4: -case 0x93D4: -case 0x95D4: -case 0x97D4: -case 0x99D4: -case 0x9BD4: -case 0x9DD4: -case 0x9FD4: -case 0x91D5: -case 0x93D5: -case 0x95D5: -case 0x97D5: -case 0x99D5: -case 0x9BD5: -case 0x9DD5: -case 0x9FD5: -case 0x91D6: -case 0x93D6: -case 0x95D6: -case 0x97D6: -case 0x99D6: -case 0x9BD6: -case 0x9DD6: -case 0x9FD6: -case 0x91D7: -case 0x93D7: -case 0x95D7: -case 0x97D7: -case 0x99D7: -case 0x9BD7: -case 0x9DD7: -case 0x9FD7: - -// SUBA -case 0x91D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x93D8: -case 0x95D8: -case 0x97D8: -case 0x99D8: -case 0x9BD8: -case 0x9DD8: -case 0x9FD8: -case 0x91D9: -case 0x93D9: -case 0x95D9: -case 0x97D9: -case 0x99D9: -case 0x9BD9: -case 0x9DD9: -case 0x9FD9: -case 0x91DA: -case 0x93DA: -case 0x95DA: -case 0x97DA: -case 0x99DA: -case 0x9BDA: -case 0x9DDA: -case 0x9FDA: -case 0x91DB: -case 0x93DB: -case 0x95DB: -case 0x97DB: -case 0x99DB: -case 0x9BDB: -case 0x9DDB: -case 0x9FDB: -case 0x91DC: -case 0x93DC: -case 0x95DC: -case 0x97DC: -case 0x99DC: -case 0x9BDC: -case 0x9DDC: -case 0x9FDC: -case 0x91DD: -case 0x93DD: -case 0x95DD: -case 0x97DD: -case 0x99DD: -case 0x9BDD: -case 0x9DDD: -case 0x9FDD: -case 0x91DE: -case 0x93DE: -case 0x95DE: -case 0x97DE: -case 0x99DE: -case 0x9BDE: -case 0x9DDE: -case 0x9FDE: - -// SUBA -case 0x91D8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x93E0: -case 0x95E0: -case 0x97E0: -case 0x99E0: -case 0x9BE0: -case 0x9DE0: -case 0x9FE0: -case 0x91E1: -case 0x93E1: -case 0x95E1: -case 0x97E1: -case 0x99E1: -case 0x9BE1: -case 0x9DE1: -case 0x9FE1: -case 0x91E2: -case 0x93E2: -case 0x95E2: -case 0x97E2: -case 0x99E2: -case 0x9BE2: -case 0x9DE2: -case 0x9FE2: -case 0x91E3: -case 0x93E3: -case 0x95E3: -case 0x97E3: -case 0x99E3: -case 0x9BE3: -case 0x9DE3: -case 0x9FE3: -case 0x91E4: -case 0x93E4: -case 0x95E4: -case 0x97E4: -case 0x99E4: -case 0x9BE4: -case 0x9DE4: -case 0x9FE4: -case 0x91E5: -case 0x93E5: -case 0x95E5: -case 0x97E5: -case 0x99E5: -case 0x9BE5: -case 0x9DE5: -case 0x9FE5: -case 0x91E6: -case 0x93E6: -case 0x95E6: -case 0x97E6: -case 0x99E6: -case 0x9BE6: -case 0x9DE6: -case 0x9FE6: - -// SUBA -case 0x91E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) -case 0x93E8: -case 0x95E8: -case 0x97E8: -case 0x99E8: -case 0x9BE8: -case 0x9DE8: -case 0x9FE8: -case 0x91E9: -case 0x93E9: -case 0x95E9: -case 0x97E9: -case 0x99E9: -case 0x9BE9: -case 0x9DE9: -case 0x9FE9: -case 0x91EA: -case 0x93EA: -case 0x95EA: -case 0x97EA: -case 0x99EA: -case 0x9BEA: -case 0x9DEA: -case 0x9FEA: -case 0x91EB: -case 0x93EB: -case 0x95EB: -case 0x97EB: -case 0x99EB: -case 0x9BEB: -case 0x9DEB: -case 0x9FEB: -case 0x91EC: -case 0x93EC: -case 0x95EC: -case 0x97EC: -case 0x99EC: -case 0x9BEC: -case 0x9DEC: -case 0x9FEC: -case 0x91ED: -case 0x93ED: -case 0x95ED: -case 0x97ED: -case 0x99ED: -case 0x9BED: -case 0x9DED: -case 0x9FED: -case 0x91EE: -case 0x93EE: -case 0x95EE: -case 0x97EE: -case 0x99EE: -case 0x9BEE: -case 0x9DEE: -case 0x9FEE: -case 0x91EF: -case 0x93EF: -case 0x95EF: -case 0x97EF: -case 0x99EF: -case 0x9BEF: -case 0x9DEF: -case 0x9FEF: - -// SUBA -case 0x91E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0x93F0: -case 0x95F0: -case 0x97F0: -case 0x99F0: -case 0x9BF0: -case 0x9DF0: -case 0x9FF0: -case 0x91F1: -case 0x93F1: -case 0x95F1: -case 0x97F1: -case 0x99F1: -case 0x9BF1: -case 0x9DF1: -case 0x9FF1: -case 0x91F2: -case 0x93F2: -case 0x95F2: -case 0x97F2: -case 0x99F2: -case 0x9BF2: -case 0x9DF2: -case 0x9FF2: -case 0x91F3: -case 0x93F3: -case 0x95F3: -case 0x97F3: -case 0x99F3: -case 0x9BF3: -case 0x9DF3: -case 0x9FF3: -case 0x91F4: -case 0x93F4: -case 0x95F4: -case 0x97F4: -case 0x99F4: -case 0x9BF4: -case 0x9DF4: -case 0x9FF4: -case 0x91F5: -case 0x93F5: -case 0x95F5: -case 0x97F5: -case 0x99F5: -case 0x9BF5: -case 0x9DF5: -case 0x9FF5: -case 0x91F6: -case 0x93F6: -case 0x95F6: -case 0x97F6: -case 0x99F6: -case 0x9BF6: -case 0x9DF6: -case 0x9FF6: -case 0x91F7: -case 0x93F7: -case 0x95F7: -case 0x97F7: -case 0x99F7: -case 0x9BF7: -case 0x9DF7: -case 0x9FF7: - -// SUBA -case 0x91F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(22) -case 0x93F8: -case 0x95F8: -case 0x97F8: -case 0x99F8: -case 0x9BF8: -case 0x9DF8: -case 0x9FF8: - -// SUBA -case 0x91F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0x93F9: -case 0x95F9: -case 0x97F9: -case 0x99F9: -case 0x9BF9: -case 0x9DF9: -case 0x9FF9: - -// SUBA -case 0x91F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(24) -case 0x93FA: -case 0x95FA: -case 0x97FA: -case 0x99FA: -case 0x9BFA: -case 0x9DFA: -case 0x9FFA: - -// SUBA -case 0x91FA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0x93FB: -case 0x95FB: -case 0x97FB: -case 0x99FB: -case 0x9BFB: -case 0x9DFB: -case 0x9FFB: - -// SUBA -case 0x91FB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(22) -case 0x93FC: -case 0x95FC: -case 0x97FC: -case 0x99FC: -case 0x9BFC: -case 0x9DFC: -case 0x9FFC: - -// SUBA -case 0x91FC: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)FETCH_LONG; - PC += 4; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(14) -case 0x93DF: -case 0x95DF: -case 0x97DF: -case 0x99DF: -case 0x9BDF: -case 0x9DDF: -case 0x9FDF: - -// SUBA -case 0x91DF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0x93E7: -case 0x95E7: -case 0x97E7: -case 0x99E7: -case 0x9BE7: -case 0x9DE7: -case 0x9FE7: - -// SUBA -case 0x91E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) diff --git a/yabause/src/c68k/c68k_opA.inc b/yabause/src/c68k/c68k_opA.inc deleted file mode 100644 index 0bf57ce785..0000000000 --- a/yabause/src/c68k/c68k_opA.inc +++ /dev/null @@ -1,4118 +0,0 @@ -case 0xA001: -case 0xA002: -case 0xA003: -case 0xA004: -case 0xA005: -case 0xA006: -case 0xA007: -case 0xA008: -case 0xA009: -case 0xA00A: -case 0xA00B: -case 0xA00C: -case 0xA00D: -case 0xA00E: -case 0xA00F: -case 0xA010: -case 0xA011: -case 0xA012: -case 0xA013: -case 0xA014: -case 0xA015: -case 0xA016: -case 0xA017: -case 0xA018: -case 0xA019: -case 0xA01A: -case 0xA01B: -case 0xA01C: -case 0xA01D: -case 0xA01E: -case 0xA01F: -case 0xA020: -case 0xA021: -case 0xA022: -case 0xA023: -case 0xA024: -case 0xA025: -case 0xA026: -case 0xA027: -case 0xA028: -case 0xA029: -case 0xA02A: -case 0xA02B: -case 0xA02C: -case 0xA02D: -case 0xA02E: -case 0xA02F: -case 0xA030: -case 0xA031: -case 0xA032: -case 0xA033: -case 0xA034: -case 0xA035: -case 0xA036: -case 0xA037: -case 0xA038: -case 0xA039: -case 0xA03A: -case 0xA03B: -case 0xA03C: -case 0xA03D: -case 0xA03E: -case 0xA03F: -case 0xA040: -case 0xA041: -case 0xA042: -case 0xA043: -case 0xA044: -case 0xA045: -case 0xA046: -case 0xA047: -case 0xA048: -case 0xA049: -case 0xA04A: -case 0xA04B: -case 0xA04C: -case 0xA04D: -case 0xA04E: -case 0xA04F: -case 0xA050: -case 0xA051: -case 0xA052: -case 0xA053: -case 0xA054: -case 0xA055: -case 0xA056: -case 0xA057: -case 0xA058: -case 0xA059: -case 0xA05A: -case 0xA05B: -case 0xA05C: -case 0xA05D: -case 0xA05E: -case 0xA05F: -case 0xA060: -case 0xA061: -case 0xA062: -case 0xA063: -case 0xA064: -case 0xA065: -case 0xA066: -case 0xA067: -case 0xA068: -case 0xA069: -case 0xA06A: -case 0xA06B: -case 0xA06C: -case 0xA06D: -case 0xA06E: -case 0xA06F: -case 0xA070: -case 0xA071: -case 0xA072: -case 0xA073: -case 0xA074: -case 0xA075: -case 0xA076: -case 0xA077: -case 0xA078: -case 0xA079: -case 0xA07A: -case 0xA07B: -case 0xA07C: -case 0xA07D: -case 0xA07E: -case 0xA07F: -case 0xA080: -case 0xA081: -case 0xA082: -case 0xA083: -case 0xA084: -case 0xA085: -case 0xA086: -case 0xA087: -case 0xA088: -case 0xA089: -case 0xA08A: -case 0xA08B: -case 0xA08C: -case 0xA08D: -case 0xA08E: -case 0xA08F: -case 0xA090: -case 0xA091: -case 0xA092: -case 0xA093: -case 0xA094: -case 0xA095: -case 0xA096: -case 0xA097: -case 0xA098: -case 0xA099: -case 0xA09A: -case 0xA09B: -case 0xA09C: -case 0xA09D: -case 0xA09E: -case 0xA09F: -case 0xA0A0: -case 0xA0A1: -case 0xA0A2: -case 0xA0A3: -case 0xA0A4: -case 0xA0A5: -case 0xA0A6: -case 0xA0A7: -case 0xA0A8: -case 0xA0A9: -case 0xA0AA: -case 0xA0AB: -case 0xA0AC: -case 0xA0AD: -case 0xA0AE: -case 0xA0AF: -case 0xA0B0: -case 0xA0B1: -case 0xA0B2: -case 0xA0B3: -case 0xA0B4: -case 0xA0B5: -case 0xA0B6: -case 0xA0B7: -case 0xA0B8: -case 0xA0B9: -case 0xA0BA: -case 0xA0BB: -case 0xA0BC: -case 0xA0BD: -case 0xA0BE: -case 0xA0BF: -case 0xA0C0: -case 0xA0C1: -case 0xA0C2: -case 0xA0C3: -case 0xA0C4: -case 0xA0C5: -case 0xA0C6: -case 0xA0C7: -case 0xA0C8: -case 0xA0C9: -case 0xA0CA: -case 0xA0CB: -case 0xA0CC: -case 0xA0CD: -case 0xA0CE: -case 0xA0CF: -case 0xA0D0: -case 0xA0D1: -case 0xA0D2: -case 0xA0D3: -case 0xA0D4: -case 0xA0D5: -case 0xA0D6: -case 0xA0D7: -case 0xA0D8: -case 0xA0D9: -case 0xA0DA: -case 0xA0DB: -case 0xA0DC: -case 0xA0DD: -case 0xA0DE: -case 0xA0DF: -case 0xA0E0: -case 0xA0E1: -case 0xA0E2: -case 0xA0E3: -case 0xA0E4: -case 0xA0E5: -case 0xA0E6: -case 0xA0E7: -case 0xA0E8: -case 0xA0E9: -case 0xA0EA: -case 0xA0EB: -case 0xA0EC: -case 0xA0ED: -case 0xA0EE: -case 0xA0EF: -case 0xA0F0: -case 0xA0F1: -case 0xA0F2: -case 0xA0F3: -case 0xA0F4: -case 0xA0F5: -case 0xA0F6: -case 0xA0F7: -case 0xA0F8: -case 0xA0F9: -case 0xA0FA: -case 0xA0FB: -case 0xA0FC: -case 0xA0FD: -case 0xA0FE: -case 0xA0FF: -case 0xA100: -case 0xA101: -case 0xA102: -case 0xA103: -case 0xA104: -case 0xA105: -case 0xA106: -case 0xA107: -case 0xA108: -case 0xA109: -case 0xA10A: -case 0xA10B: -case 0xA10C: -case 0xA10D: -case 0xA10E: -case 0xA10F: -case 0xA110: -case 0xA111: -case 0xA112: -case 0xA113: -case 0xA114: -case 0xA115: -case 0xA116: -case 0xA117: -case 0xA118: -case 0xA119: -case 0xA11A: -case 0xA11B: -case 0xA11C: -case 0xA11D: -case 0xA11E: -case 0xA11F: -case 0xA120: -case 0xA121: -case 0xA122: -case 0xA123: -case 0xA124: -case 0xA125: -case 0xA126: -case 0xA127: -case 0xA128: -case 0xA129: -case 0xA12A: -case 0xA12B: -case 0xA12C: -case 0xA12D: -case 0xA12E: -case 0xA12F: -case 0xA130: -case 0xA131: -case 0xA132: -case 0xA133: -case 0xA134: -case 0xA135: -case 0xA136: -case 0xA137: -case 0xA138: -case 0xA139: -case 0xA13A: -case 0xA13B: -case 0xA13C: -case 0xA13D: -case 0xA13E: -case 0xA13F: -case 0xA140: -case 0xA141: -case 0xA142: -case 0xA143: -case 0xA144: -case 0xA145: -case 0xA146: -case 0xA147: -case 0xA148: -case 0xA149: -case 0xA14A: -case 0xA14B: -case 0xA14C: -case 0xA14D: -case 0xA14E: -case 0xA14F: -case 0xA150: -case 0xA151: -case 0xA152: -case 0xA153: -case 0xA154: -case 0xA155: -case 0xA156: -case 0xA157: -case 0xA158: -case 0xA159: -case 0xA15A: -case 0xA15B: -case 0xA15C: -case 0xA15D: -case 0xA15E: -case 0xA15F: -case 0xA160: -case 0xA161: -case 0xA162: -case 0xA163: -case 0xA164: -case 0xA165: -case 0xA166: -case 0xA167: -case 0xA168: -case 0xA169: -case 0xA16A: -case 0xA16B: -case 0xA16C: -case 0xA16D: -case 0xA16E: -case 0xA16F: -case 0xA170: -case 0xA171: -case 0xA172: -case 0xA173: -case 0xA174: -case 0xA175: -case 0xA176: -case 0xA177: -case 0xA178: -case 0xA179: -case 0xA17A: -case 0xA17B: -case 0xA17C: -case 0xA17D: -case 0xA17E: -case 0xA17F: -case 0xA180: -case 0xA181: -case 0xA182: -case 0xA183: -case 0xA184: -case 0xA185: -case 0xA186: -case 0xA187: -case 0xA188: -case 0xA189: -case 0xA18A: -case 0xA18B: -case 0xA18C: -case 0xA18D: -case 0xA18E: -case 0xA18F: -case 0xA190: -case 0xA191: -case 0xA192: -case 0xA193: -case 0xA194: -case 0xA195: -case 0xA196: -case 0xA197: -case 0xA198: -case 0xA199: -case 0xA19A: -case 0xA19B: -case 0xA19C: -case 0xA19D: -case 0xA19E: -case 0xA19F: -case 0xA1A0: -case 0xA1A1: -case 0xA1A2: -case 0xA1A3: -case 0xA1A4: -case 0xA1A5: -case 0xA1A6: -case 0xA1A7: -case 0xA1A8: -case 0xA1A9: -case 0xA1AA: -case 0xA1AB: -case 0xA1AC: -case 0xA1AD: -case 0xA1AE: -case 0xA1AF: -case 0xA1B0: -case 0xA1B1: -case 0xA1B2: -case 0xA1B3: -case 0xA1B4: -case 0xA1B5: -case 0xA1B6: -case 0xA1B7: -case 0xA1B8: -case 0xA1B9: -case 0xA1BA: -case 0xA1BB: -case 0xA1BC: -case 0xA1BD: -case 0xA1BE: -case 0xA1BF: -case 0xA1C0: -case 0xA1C1: -case 0xA1C2: -case 0xA1C3: -case 0xA1C4: -case 0xA1C5: -case 0xA1C6: -case 0xA1C7: -case 0xA1C8: -case 0xA1C9: -case 0xA1CA: -case 0xA1CB: -case 0xA1CC: -case 0xA1CD: -case 0xA1CE: -case 0xA1CF: -case 0xA1D0: -case 0xA1D1: -case 0xA1D2: -case 0xA1D3: -case 0xA1D4: -case 0xA1D5: -case 0xA1D6: -case 0xA1D7: -case 0xA1D8: -case 0xA1D9: -case 0xA1DA: -case 0xA1DB: -case 0xA1DC: -case 0xA1DD: -case 0xA1DE: -case 0xA1DF: -case 0xA1E0: -case 0xA1E1: -case 0xA1E2: -case 0xA1E3: -case 0xA1E4: -case 0xA1E5: -case 0xA1E6: -case 0xA1E7: -case 0xA1E8: -case 0xA1E9: -case 0xA1EA: -case 0xA1EB: -case 0xA1EC: -case 0xA1ED: -case 0xA1EE: -case 0xA1EF: -case 0xA1F0: -case 0xA1F1: -case 0xA1F2: -case 0xA1F3: -case 0xA1F4: -case 0xA1F5: -case 0xA1F6: -case 0xA1F7: -case 0xA1F8: -case 0xA1F9: -case 0xA1FA: -case 0xA1FB: -case 0xA1FC: -case 0xA1FD: -case 0xA1FE: -case 0xA1FF: -case 0xA200: -case 0xA201: -case 0xA202: -case 0xA203: -case 0xA204: -case 0xA205: -case 0xA206: -case 0xA207: -case 0xA208: -case 0xA209: -case 0xA20A: -case 0xA20B: -case 0xA20C: -case 0xA20D: -case 0xA20E: -case 0xA20F: -case 0xA210: -case 0xA211: -case 0xA212: -case 0xA213: -case 0xA214: -case 0xA215: -case 0xA216: -case 0xA217: -case 0xA218: -case 0xA219: -case 0xA21A: -case 0xA21B: -case 0xA21C: -case 0xA21D: -case 0xA21E: -case 0xA21F: -case 0xA220: -case 0xA221: -case 0xA222: -case 0xA223: -case 0xA224: -case 0xA225: -case 0xA226: -case 0xA227: -case 0xA228: -case 0xA229: -case 0xA22A: -case 0xA22B: -case 0xA22C: -case 0xA22D: -case 0xA22E: -case 0xA22F: -case 0xA230: -case 0xA231: -case 0xA232: -case 0xA233: -case 0xA234: -case 0xA235: -case 0xA236: -case 0xA237: -case 0xA238: -case 0xA239: -case 0xA23A: -case 0xA23B: -case 0xA23C: -case 0xA23D: -case 0xA23E: -case 0xA23F: -case 0xA240: -case 0xA241: -case 0xA242: -case 0xA243: -case 0xA244: -case 0xA245: -case 0xA246: -case 0xA247: -case 0xA248: -case 0xA249: -case 0xA24A: -case 0xA24B: -case 0xA24C: -case 0xA24D: -case 0xA24E: -case 0xA24F: -case 0xA250: -case 0xA251: -case 0xA252: -case 0xA253: -case 0xA254: -case 0xA255: -case 0xA256: -case 0xA257: -case 0xA258: -case 0xA259: -case 0xA25A: -case 0xA25B: -case 0xA25C: -case 0xA25D: -case 0xA25E: -case 0xA25F: -case 0xA260: -case 0xA261: -case 0xA262: -case 0xA263: -case 0xA264: -case 0xA265: -case 0xA266: -case 0xA267: -case 0xA268: -case 0xA269: -case 0xA26A: -case 0xA26B: -case 0xA26C: -case 0xA26D: -case 0xA26E: -case 0xA26F: -case 0xA270: -case 0xA271: -case 0xA272: -case 0xA273: -case 0xA274: -case 0xA275: -case 0xA276: -case 0xA277: -case 0xA278: -case 0xA279: -case 0xA27A: -case 0xA27B: -case 0xA27C: -case 0xA27D: -case 0xA27E: -case 0xA27F: -case 0xA280: -case 0xA281: -case 0xA282: -case 0xA283: -case 0xA284: -case 0xA285: -case 0xA286: -case 0xA287: -case 0xA288: -case 0xA289: -case 0xA28A: -case 0xA28B: -case 0xA28C: -case 0xA28D: -case 0xA28E: -case 0xA28F: -case 0xA290: -case 0xA291: -case 0xA292: -case 0xA293: -case 0xA294: -case 0xA295: -case 0xA296: -case 0xA297: -case 0xA298: -case 0xA299: -case 0xA29A: -case 0xA29B: -case 0xA29C: -case 0xA29D: -case 0xA29E: -case 0xA29F: -case 0xA2A0: -case 0xA2A1: -case 0xA2A2: -case 0xA2A3: -case 0xA2A4: -case 0xA2A5: -case 0xA2A6: -case 0xA2A7: -case 0xA2A8: -case 0xA2A9: -case 0xA2AA: -case 0xA2AB: -case 0xA2AC: -case 0xA2AD: -case 0xA2AE: -case 0xA2AF: -case 0xA2B0: -case 0xA2B1: -case 0xA2B2: -case 0xA2B3: -case 0xA2B4: -case 0xA2B5: -case 0xA2B6: -case 0xA2B7: -case 0xA2B8: -case 0xA2B9: -case 0xA2BA: -case 0xA2BB: -case 0xA2BC: -case 0xA2BD: -case 0xA2BE: -case 0xA2BF: -case 0xA2C0: -case 0xA2C1: -case 0xA2C2: -case 0xA2C3: -case 0xA2C4: -case 0xA2C5: -case 0xA2C6: -case 0xA2C7: -case 0xA2C8: -case 0xA2C9: -case 0xA2CA: -case 0xA2CB: -case 0xA2CC: -case 0xA2CD: -case 0xA2CE: -case 0xA2CF: -case 0xA2D0: -case 0xA2D1: -case 0xA2D2: -case 0xA2D3: -case 0xA2D4: -case 0xA2D5: -case 0xA2D6: -case 0xA2D7: -case 0xA2D8: -case 0xA2D9: -case 0xA2DA: -case 0xA2DB: -case 0xA2DC: -case 0xA2DD: -case 0xA2DE: -case 0xA2DF: -case 0xA2E0: -case 0xA2E1: -case 0xA2E2: -case 0xA2E3: -case 0xA2E4: -case 0xA2E5: -case 0xA2E6: -case 0xA2E7: -case 0xA2E8: -case 0xA2E9: -case 0xA2EA: -case 0xA2EB: -case 0xA2EC: -case 0xA2ED: -case 0xA2EE: -case 0xA2EF: -case 0xA2F0: -case 0xA2F1: -case 0xA2F2: -case 0xA2F3: -case 0xA2F4: -case 0xA2F5: -case 0xA2F6: -case 0xA2F7: -case 0xA2F8: -case 0xA2F9: -case 0xA2FA: -case 0xA2FB: -case 0xA2FC: -case 0xA2FD: -case 0xA2FE: -case 0xA2FF: -case 0xA300: -case 0xA301: -case 0xA302: -case 0xA303: -case 0xA304: -case 0xA305: -case 0xA306: -case 0xA307: -case 0xA308: -case 0xA309: -case 0xA30A: -case 0xA30B: -case 0xA30C: -case 0xA30D: -case 0xA30E: -case 0xA30F: -case 0xA310: -case 0xA311: -case 0xA312: -case 0xA313: -case 0xA314: -case 0xA315: -case 0xA316: -case 0xA317: -case 0xA318: -case 0xA319: -case 0xA31A: -case 0xA31B: -case 0xA31C: -case 0xA31D: -case 0xA31E: -case 0xA31F: -case 0xA320: -case 0xA321: -case 0xA322: -case 0xA323: -case 0xA324: -case 0xA325: -case 0xA326: -case 0xA327: -case 0xA328: -case 0xA329: -case 0xA32A: -case 0xA32B: -case 0xA32C: -case 0xA32D: -case 0xA32E: -case 0xA32F: -case 0xA330: -case 0xA331: -case 0xA332: -case 0xA333: -case 0xA334: -case 0xA335: -case 0xA336: -case 0xA337: -case 0xA338: -case 0xA339: -case 0xA33A: -case 0xA33B: -case 0xA33C: -case 0xA33D: -case 0xA33E: -case 0xA33F: -case 0xA340: -case 0xA341: -case 0xA342: -case 0xA343: -case 0xA344: -case 0xA345: -case 0xA346: -case 0xA347: -case 0xA348: -case 0xA349: -case 0xA34A: -case 0xA34B: -case 0xA34C: -case 0xA34D: -case 0xA34E: -case 0xA34F: -case 0xA350: -case 0xA351: -case 0xA352: -case 0xA353: -case 0xA354: -case 0xA355: -case 0xA356: -case 0xA357: -case 0xA358: -case 0xA359: -case 0xA35A: -case 0xA35B: -case 0xA35C: -case 0xA35D: -case 0xA35E: -case 0xA35F: -case 0xA360: -case 0xA361: -case 0xA362: -case 0xA363: -case 0xA364: -case 0xA365: -case 0xA366: -case 0xA367: -case 0xA368: -case 0xA369: -case 0xA36A: -case 0xA36B: -case 0xA36C: -case 0xA36D: -case 0xA36E: -case 0xA36F: -case 0xA370: -case 0xA371: -case 0xA372: -case 0xA373: -case 0xA374: -case 0xA375: -case 0xA376: -case 0xA377: -case 0xA378: -case 0xA379: -case 0xA37A: -case 0xA37B: -case 0xA37C: -case 0xA37D: -case 0xA37E: -case 0xA37F: -case 0xA380: -case 0xA381: -case 0xA382: -case 0xA383: -case 0xA384: -case 0xA385: -case 0xA386: -case 0xA387: -case 0xA388: -case 0xA389: -case 0xA38A: -case 0xA38B: -case 0xA38C: -case 0xA38D: -case 0xA38E: -case 0xA38F: -case 0xA390: -case 0xA391: -case 0xA392: -case 0xA393: -case 0xA394: -case 0xA395: -case 0xA396: -case 0xA397: -case 0xA398: -case 0xA399: -case 0xA39A: -case 0xA39B: -case 0xA39C: -case 0xA39D: -case 0xA39E: -case 0xA39F: -case 0xA3A0: -case 0xA3A1: -case 0xA3A2: -case 0xA3A3: -case 0xA3A4: -case 0xA3A5: -case 0xA3A6: -case 0xA3A7: -case 0xA3A8: -case 0xA3A9: -case 0xA3AA: -case 0xA3AB: -case 0xA3AC: -case 0xA3AD: -case 0xA3AE: -case 0xA3AF: -case 0xA3B0: -case 0xA3B1: -case 0xA3B2: -case 0xA3B3: -case 0xA3B4: -case 0xA3B5: -case 0xA3B6: -case 0xA3B7: -case 0xA3B8: -case 0xA3B9: -case 0xA3BA: -case 0xA3BB: -case 0xA3BC: -case 0xA3BD: -case 0xA3BE: -case 0xA3BF: -case 0xA3C0: -case 0xA3C1: -case 0xA3C2: -case 0xA3C3: -case 0xA3C4: -case 0xA3C5: -case 0xA3C6: -case 0xA3C7: -case 0xA3C8: -case 0xA3C9: -case 0xA3CA: -case 0xA3CB: -case 0xA3CC: -case 0xA3CD: -case 0xA3CE: -case 0xA3CF: -case 0xA3D0: -case 0xA3D1: -case 0xA3D2: -case 0xA3D3: -case 0xA3D4: -case 0xA3D5: -case 0xA3D6: -case 0xA3D7: -case 0xA3D8: -case 0xA3D9: -case 0xA3DA: -case 0xA3DB: -case 0xA3DC: -case 0xA3DD: -case 0xA3DE: -case 0xA3DF: -case 0xA3E0: -case 0xA3E1: -case 0xA3E2: -case 0xA3E3: -case 0xA3E4: -case 0xA3E5: -case 0xA3E6: -case 0xA3E7: -case 0xA3E8: -case 0xA3E9: -case 0xA3EA: -case 0xA3EB: -case 0xA3EC: -case 0xA3ED: -case 0xA3EE: -case 0xA3EF: -case 0xA3F0: -case 0xA3F1: -case 0xA3F2: -case 0xA3F3: -case 0xA3F4: -case 0xA3F5: -case 0xA3F6: -case 0xA3F7: -case 0xA3F8: -case 0xA3F9: -case 0xA3FA: -case 0xA3FB: -case 0xA3FC: -case 0xA3FD: -case 0xA3FE: -case 0xA3FF: -case 0xA400: -case 0xA401: -case 0xA402: -case 0xA403: -case 0xA404: -case 0xA405: -case 0xA406: -case 0xA407: -case 0xA408: -case 0xA409: -case 0xA40A: -case 0xA40B: -case 0xA40C: -case 0xA40D: -case 0xA40E: -case 0xA40F: -case 0xA410: -case 0xA411: -case 0xA412: -case 0xA413: -case 0xA414: -case 0xA415: -case 0xA416: -case 0xA417: -case 0xA418: -case 0xA419: -case 0xA41A: -case 0xA41B: -case 0xA41C: -case 0xA41D: -case 0xA41E: -case 0xA41F: -case 0xA420: -case 0xA421: -case 0xA422: -case 0xA423: -case 0xA424: -case 0xA425: -case 0xA426: -case 0xA427: -case 0xA428: -case 0xA429: -case 0xA42A: -case 0xA42B: -case 0xA42C: -case 0xA42D: -case 0xA42E: -case 0xA42F: -case 0xA430: -case 0xA431: -case 0xA432: -case 0xA433: -case 0xA434: -case 0xA435: -case 0xA436: -case 0xA437: -case 0xA438: -case 0xA439: -case 0xA43A: -case 0xA43B: -case 0xA43C: -case 0xA43D: -case 0xA43E: -case 0xA43F: -case 0xA440: -case 0xA441: -case 0xA442: -case 0xA443: -case 0xA444: -case 0xA445: -case 0xA446: -case 0xA447: -case 0xA448: -case 0xA449: -case 0xA44A: -case 0xA44B: -case 0xA44C: -case 0xA44D: -case 0xA44E: -case 0xA44F: -case 0xA450: -case 0xA451: -case 0xA452: -case 0xA453: -case 0xA454: -case 0xA455: -case 0xA456: -case 0xA457: -case 0xA458: -case 0xA459: -case 0xA45A: -case 0xA45B: -case 0xA45C: -case 0xA45D: -case 0xA45E: -case 0xA45F: -case 0xA460: -case 0xA461: -case 0xA462: -case 0xA463: -case 0xA464: -case 0xA465: -case 0xA466: -case 0xA467: -case 0xA468: -case 0xA469: -case 0xA46A: -case 0xA46B: -case 0xA46C: -case 0xA46D: -case 0xA46E: -case 0xA46F: -case 0xA470: -case 0xA471: -case 0xA472: -case 0xA473: -case 0xA474: -case 0xA475: -case 0xA476: -case 0xA477: -case 0xA478: -case 0xA479: -case 0xA47A: -case 0xA47B: -case 0xA47C: -case 0xA47D: -case 0xA47E: -case 0xA47F: -case 0xA480: -case 0xA481: -case 0xA482: -case 0xA483: -case 0xA484: -case 0xA485: -case 0xA486: -case 0xA487: -case 0xA488: -case 0xA489: -case 0xA48A: -case 0xA48B: -case 0xA48C: -case 0xA48D: -case 0xA48E: -case 0xA48F: -case 0xA490: -case 0xA491: -case 0xA492: -case 0xA493: -case 0xA494: -case 0xA495: -case 0xA496: -case 0xA497: -case 0xA498: -case 0xA499: -case 0xA49A: -case 0xA49B: -case 0xA49C: -case 0xA49D: -case 0xA49E: -case 0xA49F: -case 0xA4A0: -case 0xA4A1: -case 0xA4A2: -case 0xA4A3: -case 0xA4A4: -case 0xA4A5: -case 0xA4A6: -case 0xA4A7: -case 0xA4A8: -case 0xA4A9: -case 0xA4AA: -case 0xA4AB: -case 0xA4AC: -case 0xA4AD: -case 0xA4AE: -case 0xA4AF: -case 0xA4B0: -case 0xA4B1: -case 0xA4B2: -case 0xA4B3: -case 0xA4B4: -case 0xA4B5: -case 0xA4B6: -case 0xA4B7: -case 0xA4B8: -case 0xA4B9: -case 0xA4BA: -case 0xA4BB: -case 0xA4BC: -case 0xA4BD: -case 0xA4BE: -case 0xA4BF: -case 0xA4C0: -case 0xA4C1: -case 0xA4C2: -case 0xA4C3: -case 0xA4C4: -case 0xA4C5: -case 0xA4C6: -case 0xA4C7: -case 0xA4C8: -case 0xA4C9: -case 0xA4CA: -case 0xA4CB: -case 0xA4CC: -case 0xA4CD: -case 0xA4CE: -case 0xA4CF: -case 0xA4D0: -case 0xA4D1: -case 0xA4D2: -case 0xA4D3: -case 0xA4D4: -case 0xA4D5: -case 0xA4D6: -case 0xA4D7: -case 0xA4D8: -case 0xA4D9: -case 0xA4DA: -case 0xA4DB: -case 0xA4DC: -case 0xA4DD: -case 0xA4DE: -case 0xA4DF: -case 0xA4E0: -case 0xA4E1: -case 0xA4E2: -case 0xA4E3: -case 0xA4E4: -case 0xA4E5: -case 0xA4E6: -case 0xA4E7: -case 0xA4E8: -case 0xA4E9: -case 0xA4EA: -case 0xA4EB: -case 0xA4EC: -case 0xA4ED: -case 0xA4EE: -case 0xA4EF: -case 0xA4F0: -case 0xA4F1: -case 0xA4F2: -case 0xA4F3: -case 0xA4F4: -case 0xA4F5: -case 0xA4F6: -case 0xA4F7: -case 0xA4F8: -case 0xA4F9: -case 0xA4FA: -case 0xA4FB: -case 0xA4FC: -case 0xA4FD: -case 0xA4FE: -case 0xA4FF: -case 0xA500: -case 0xA501: -case 0xA502: -case 0xA503: -case 0xA504: -case 0xA505: -case 0xA506: -case 0xA507: -case 0xA508: -case 0xA509: -case 0xA50A: -case 0xA50B: -case 0xA50C: -case 0xA50D: -case 0xA50E: -case 0xA50F: -case 0xA510: -case 0xA511: -case 0xA512: -case 0xA513: -case 0xA514: -case 0xA515: -case 0xA516: -case 0xA517: -case 0xA518: -case 0xA519: -case 0xA51A: -case 0xA51B: -case 0xA51C: -case 0xA51D: -case 0xA51E: -case 0xA51F: -case 0xA520: -case 0xA521: -case 0xA522: -case 0xA523: -case 0xA524: -case 0xA525: -case 0xA526: -case 0xA527: -case 0xA528: -case 0xA529: -case 0xA52A: -case 0xA52B: -case 0xA52C: -case 0xA52D: -case 0xA52E: -case 0xA52F: -case 0xA530: -case 0xA531: -case 0xA532: -case 0xA533: -case 0xA534: -case 0xA535: -case 0xA536: -case 0xA537: -case 0xA538: -case 0xA539: -case 0xA53A: -case 0xA53B: -case 0xA53C: -case 0xA53D: -case 0xA53E: -case 0xA53F: -case 0xA540: -case 0xA541: -case 0xA542: -case 0xA543: -case 0xA544: -case 0xA545: -case 0xA546: -case 0xA547: -case 0xA548: -case 0xA549: -case 0xA54A: -case 0xA54B: -case 0xA54C: -case 0xA54D: -case 0xA54E: -case 0xA54F: -case 0xA550: -case 0xA551: -case 0xA552: -case 0xA553: -case 0xA554: -case 0xA555: -case 0xA556: -case 0xA557: -case 0xA558: -case 0xA559: -case 0xA55A: -case 0xA55B: -case 0xA55C: -case 0xA55D: -case 0xA55E: -case 0xA55F: -case 0xA560: -case 0xA561: -case 0xA562: -case 0xA563: -case 0xA564: -case 0xA565: -case 0xA566: -case 0xA567: -case 0xA568: -case 0xA569: -case 0xA56A: -case 0xA56B: -case 0xA56C: -case 0xA56D: -case 0xA56E: -case 0xA56F: -case 0xA570: -case 0xA571: -case 0xA572: -case 0xA573: -case 0xA574: -case 0xA575: -case 0xA576: -case 0xA577: -case 0xA578: -case 0xA579: -case 0xA57A: -case 0xA57B: -case 0xA57C: -case 0xA57D: -case 0xA57E: -case 0xA57F: -case 0xA580: -case 0xA581: -case 0xA582: -case 0xA583: -case 0xA584: -case 0xA585: -case 0xA586: -case 0xA587: -case 0xA588: -case 0xA589: -case 0xA58A: -case 0xA58B: -case 0xA58C: -case 0xA58D: -case 0xA58E: -case 0xA58F: -case 0xA590: -case 0xA591: -case 0xA592: -case 0xA593: -case 0xA594: -case 0xA595: -case 0xA596: -case 0xA597: -case 0xA598: -case 0xA599: -case 0xA59A: -case 0xA59B: -case 0xA59C: -case 0xA59D: -case 0xA59E: -case 0xA59F: -case 0xA5A0: -case 0xA5A1: -case 0xA5A2: -case 0xA5A3: -case 0xA5A4: -case 0xA5A5: -case 0xA5A6: -case 0xA5A7: -case 0xA5A8: -case 0xA5A9: -case 0xA5AA: -case 0xA5AB: -case 0xA5AC: -case 0xA5AD: -case 0xA5AE: -case 0xA5AF: -case 0xA5B0: -case 0xA5B1: -case 0xA5B2: -case 0xA5B3: -case 0xA5B4: -case 0xA5B5: -case 0xA5B6: -case 0xA5B7: -case 0xA5B8: -case 0xA5B9: -case 0xA5BA: -case 0xA5BB: -case 0xA5BC: -case 0xA5BD: -case 0xA5BE: -case 0xA5BF: -case 0xA5C0: -case 0xA5C1: -case 0xA5C2: -case 0xA5C3: -case 0xA5C4: -case 0xA5C5: -case 0xA5C6: -case 0xA5C7: -case 0xA5C8: -case 0xA5C9: -case 0xA5CA: -case 0xA5CB: -case 0xA5CC: -case 0xA5CD: -case 0xA5CE: -case 0xA5CF: -case 0xA5D0: -case 0xA5D1: -case 0xA5D2: -case 0xA5D3: -case 0xA5D4: -case 0xA5D5: -case 0xA5D6: -case 0xA5D7: -case 0xA5D8: -case 0xA5D9: -case 0xA5DA: -case 0xA5DB: -case 0xA5DC: -case 0xA5DD: -case 0xA5DE: -case 0xA5DF: -case 0xA5E0: -case 0xA5E1: -case 0xA5E2: -case 0xA5E3: -case 0xA5E4: -case 0xA5E5: -case 0xA5E6: -case 0xA5E7: -case 0xA5E8: -case 0xA5E9: -case 0xA5EA: -case 0xA5EB: -case 0xA5EC: -case 0xA5ED: -case 0xA5EE: -case 0xA5EF: -case 0xA5F0: -case 0xA5F1: -case 0xA5F2: -case 0xA5F3: -case 0xA5F4: -case 0xA5F5: -case 0xA5F6: -case 0xA5F7: -case 0xA5F8: -case 0xA5F9: -case 0xA5FA: -case 0xA5FB: -case 0xA5FC: -case 0xA5FD: -case 0xA5FE: -case 0xA5FF: -case 0xA600: -case 0xA601: -case 0xA602: -case 0xA603: -case 0xA604: -case 0xA605: -case 0xA606: -case 0xA607: -case 0xA608: -case 0xA609: -case 0xA60A: -case 0xA60B: -case 0xA60C: -case 0xA60D: -case 0xA60E: -case 0xA60F: -case 0xA610: -case 0xA611: -case 0xA612: -case 0xA613: -case 0xA614: -case 0xA615: -case 0xA616: -case 0xA617: -case 0xA618: -case 0xA619: -case 0xA61A: -case 0xA61B: -case 0xA61C: -case 0xA61D: -case 0xA61E: -case 0xA61F: -case 0xA620: -case 0xA621: -case 0xA622: -case 0xA623: -case 0xA624: -case 0xA625: -case 0xA626: -case 0xA627: -case 0xA628: -case 0xA629: -case 0xA62A: -case 0xA62B: -case 0xA62C: -case 0xA62D: -case 0xA62E: -case 0xA62F: -case 0xA630: -case 0xA631: -case 0xA632: -case 0xA633: -case 0xA634: -case 0xA635: -case 0xA636: -case 0xA637: -case 0xA638: -case 0xA639: -case 0xA63A: -case 0xA63B: -case 0xA63C: -case 0xA63D: -case 0xA63E: -case 0xA63F: -case 0xA640: -case 0xA641: -case 0xA642: -case 0xA643: -case 0xA644: -case 0xA645: -case 0xA646: -case 0xA647: -case 0xA648: -case 0xA649: -case 0xA64A: -case 0xA64B: -case 0xA64C: -case 0xA64D: -case 0xA64E: -case 0xA64F: -case 0xA650: -case 0xA651: -case 0xA652: -case 0xA653: -case 0xA654: -case 0xA655: -case 0xA656: -case 0xA657: -case 0xA658: -case 0xA659: -case 0xA65A: -case 0xA65B: -case 0xA65C: -case 0xA65D: -case 0xA65E: -case 0xA65F: -case 0xA660: -case 0xA661: -case 0xA662: -case 0xA663: -case 0xA664: -case 0xA665: -case 0xA666: -case 0xA667: -case 0xA668: -case 0xA669: -case 0xA66A: -case 0xA66B: -case 0xA66C: -case 0xA66D: -case 0xA66E: -case 0xA66F: -case 0xA670: -case 0xA671: -case 0xA672: -case 0xA673: -case 0xA674: -case 0xA675: -case 0xA676: -case 0xA677: -case 0xA678: -case 0xA679: -case 0xA67A: -case 0xA67B: -case 0xA67C: -case 0xA67D: -case 0xA67E: -case 0xA67F: -case 0xA680: -case 0xA681: -case 0xA682: -case 0xA683: -case 0xA684: -case 0xA685: -case 0xA686: -case 0xA687: -case 0xA688: -case 0xA689: -case 0xA68A: -case 0xA68B: -case 0xA68C: -case 0xA68D: -case 0xA68E: -case 0xA68F: -case 0xA690: -case 0xA691: -case 0xA692: -case 0xA693: -case 0xA694: -case 0xA695: -case 0xA696: -case 0xA697: -case 0xA698: -case 0xA699: -case 0xA69A: -case 0xA69B: -case 0xA69C: -case 0xA69D: -case 0xA69E: -case 0xA69F: -case 0xA6A0: -case 0xA6A1: -case 0xA6A2: -case 0xA6A3: -case 0xA6A4: -case 0xA6A5: -case 0xA6A6: -case 0xA6A7: -case 0xA6A8: -case 0xA6A9: -case 0xA6AA: -case 0xA6AB: -case 0xA6AC: -case 0xA6AD: -case 0xA6AE: -case 0xA6AF: -case 0xA6B0: -case 0xA6B1: -case 0xA6B2: -case 0xA6B3: -case 0xA6B4: -case 0xA6B5: -case 0xA6B6: -case 0xA6B7: -case 0xA6B8: -case 0xA6B9: -case 0xA6BA: -case 0xA6BB: -case 0xA6BC: -case 0xA6BD: -case 0xA6BE: -case 0xA6BF: -case 0xA6C0: -case 0xA6C1: -case 0xA6C2: -case 0xA6C3: -case 0xA6C4: -case 0xA6C5: -case 0xA6C6: -case 0xA6C7: -case 0xA6C8: -case 0xA6C9: -case 0xA6CA: -case 0xA6CB: -case 0xA6CC: -case 0xA6CD: -case 0xA6CE: -case 0xA6CF: -case 0xA6D0: -case 0xA6D1: -case 0xA6D2: -case 0xA6D3: -case 0xA6D4: -case 0xA6D5: -case 0xA6D6: -case 0xA6D7: -case 0xA6D8: -case 0xA6D9: -case 0xA6DA: -case 0xA6DB: -case 0xA6DC: -case 0xA6DD: -case 0xA6DE: -case 0xA6DF: -case 0xA6E0: -case 0xA6E1: -case 0xA6E2: -case 0xA6E3: -case 0xA6E4: -case 0xA6E5: -case 0xA6E6: -case 0xA6E7: -case 0xA6E8: -case 0xA6E9: -case 0xA6EA: -case 0xA6EB: -case 0xA6EC: -case 0xA6ED: -case 0xA6EE: -case 0xA6EF: -case 0xA6F0: -case 0xA6F1: -case 0xA6F2: -case 0xA6F3: -case 0xA6F4: -case 0xA6F5: -case 0xA6F6: -case 0xA6F7: -case 0xA6F8: -case 0xA6F9: -case 0xA6FA: -case 0xA6FB: -case 0xA6FC: -case 0xA6FD: -case 0xA6FE: -case 0xA6FF: -case 0xA700: -case 0xA701: -case 0xA702: -case 0xA703: -case 0xA704: -case 0xA705: -case 0xA706: -case 0xA707: -case 0xA708: -case 0xA709: -case 0xA70A: -case 0xA70B: -case 0xA70C: -case 0xA70D: -case 0xA70E: -case 0xA70F: -case 0xA710: -case 0xA711: -case 0xA712: -case 0xA713: -case 0xA714: -case 0xA715: -case 0xA716: -case 0xA717: -case 0xA718: -case 0xA719: -case 0xA71A: -case 0xA71B: -case 0xA71C: -case 0xA71D: -case 0xA71E: -case 0xA71F: -case 0xA720: -case 0xA721: -case 0xA722: -case 0xA723: -case 0xA724: -case 0xA725: -case 0xA726: -case 0xA727: -case 0xA728: -case 0xA729: -case 0xA72A: -case 0xA72B: -case 0xA72C: -case 0xA72D: -case 0xA72E: -case 0xA72F: -case 0xA730: -case 0xA731: -case 0xA732: -case 0xA733: -case 0xA734: -case 0xA735: -case 0xA736: -case 0xA737: -case 0xA738: -case 0xA739: -case 0xA73A: -case 0xA73B: -case 0xA73C: -case 0xA73D: -case 0xA73E: -case 0xA73F: -case 0xA740: -case 0xA741: -case 0xA742: -case 0xA743: -case 0xA744: -case 0xA745: -case 0xA746: -case 0xA747: -case 0xA748: -case 0xA749: -case 0xA74A: -case 0xA74B: -case 0xA74C: -case 0xA74D: -case 0xA74E: -case 0xA74F: -case 0xA750: -case 0xA751: -case 0xA752: -case 0xA753: -case 0xA754: -case 0xA755: -case 0xA756: -case 0xA757: -case 0xA758: -case 0xA759: -case 0xA75A: -case 0xA75B: -case 0xA75C: -case 0xA75D: -case 0xA75E: -case 0xA75F: -case 0xA760: -case 0xA761: -case 0xA762: -case 0xA763: -case 0xA764: -case 0xA765: -case 0xA766: -case 0xA767: -case 0xA768: -case 0xA769: -case 0xA76A: -case 0xA76B: -case 0xA76C: -case 0xA76D: -case 0xA76E: -case 0xA76F: -case 0xA770: -case 0xA771: -case 0xA772: -case 0xA773: -case 0xA774: -case 0xA775: -case 0xA776: -case 0xA777: -case 0xA778: -case 0xA779: -case 0xA77A: -case 0xA77B: -case 0xA77C: -case 0xA77D: -case 0xA77E: -case 0xA77F: -case 0xA780: -case 0xA781: -case 0xA782: -case 0xA783: -case 0xA784: -case 0xA785: -case 0xA786: -case 0xA787: -case 0xA788: -case 0xA789: -case 0xA78A: -case 0xA78B: -case 0xA78C: -case 0xA78D: -case 0xA78E: -case 0xA78F: -case 0xA790: -case 0xA791: -case 0xA792: -case 0xA793: -case 0xA794: -case 0xA795: -case 0xA796: -case 0xA797: -case 0xA798: -case 0xA799: -case 0xA79A: -case 0xA79B: -case 0xA79C: -case 0xA79D: -case 0xA79E: -case 0xA79F: -case 0xA7A0: -case 0xA7A1: -case 0xA7A2: -case 0xA7A3: -case 0xA7A4: -case 0xA7A5: -case 0xA7A6: -case 0xA7A7: -case 0xA7A8: -case 0xA7A9: -case 0xA7AA: -case 0xA7AB: -case 0xA7AC: -case 0xA7AD: -case 0xA7AE: -case 0xA7AF: -case 0xA7B0: -case 0xA7B1: -case 0xA7B2: -case 0xA7B3: -case 0xA7B4: -case 0xA7B5: -case 0xA7B6: -case 0xA7B7: -case 0xA7B8: -case 0xA7B9: -case 0xA7BA: -case 0xA7BB: -case 0xA7BC: -case 0xA7BD: -case 0xA7BE: -case 0xA7BF: -case 0xA7C0: -case 0xA7C1: -case 0xA7C2: -case 0xA7C3: -case 0xA7C4: -case 0xA7C5: -case 0xA7C6: -case 0xA7C7: -case 0xA7C8: -case 0xA7C9: -case 0xA7CA: -case 0xA7CB: -case 0xA7CC: -case 0xA7CD: -case 0xA7CE: -case 0xA7CF: -case 0xA7D0: -case 0xA7D1: -case 0xA7D2: -case 0xA7D3: -case 0xA7D4: -case 0xA7D5: -case 0xA7D6: -case 0xA7D7: -case 0xA7D8: -case 0xA7D9: -case 0xA7DA: -case 0xA7DB: -case 0xA7DC: -case 0xA7DD: -case 0xA7DE: -case 0xA7DF: -case 0xA7E0: -case 0xA7E1: -case 0xA7E2: -case 0xA7E3: -case 0xA7E4: -case 0xA7E5: -case 0xA7E6: -case 0xA7E7: -case 0xA7E8: -case 0xA7E9: -case 0xA7EA: -case 0xA7EB: -case 0xA7EC: -case 0xA7ED: -case 0xA7EE: -case 0xA7EF: -case 0xA7F0: -case 0xA7F1: -case 0xA7F2: -case 0xA7F3: -case 0xA7F4: -case 0xA7F5: -case 0xA7F6: -case 0xA7F7: -case 0xA7F8: -case 0xA7F9: -case 0xA7FA: -case 0xA7FB: -case 0xA7FC: -case 0xA7FD: -case 0xA7FE: -case 0xA7FF: -case 0xA800: -case 0xA801: -case 0xA802: -case 0xA803: -case 0xA804: -case 0xA805: -case 0xA806: -case 0xA807: -case 0xA808: -case 0xA809: -case 0xA80A: -case 0xA80B: -case 0xA80C: -case 0xA80D: -case 0xA80E: -case 0xA80F: -case 0xA810: -case 0xA811: -case 0xA812: -case 0xA813: -case 0xA814: -case 0xA815: -case 0xA816: -case 0xA817: -case 0xA818: -case 0xA819: -case 0xA81A: -case 0xA81B: -case 0xA81C: -case 0xA81D: -case 0xA81E: -case 0xA81F: -case 0xA820: -case 0xA821: -case 0xA822: -case 0xA823: -case 0xA824: -case 0xA825: -case 0xA826: -case 0xA827: -case 0xA828: -case 0xA829: -case 0xA82A: -case 0xA82B: -case 0xA82C: -case 0xA82D: -case 0xA82E: -case 0xA82F: -case 0xA830: -case 0xA831: -case 0xA832: -case 0xA833: -case 0xA834: -case 0xA835: -case 0xA836: -case 0xA837: -case 0xA838: -case 0xA839: -case 0xA83A: -case 0xA83B: -case 0xA83C: -case 0xA83D: -case 0xA83E: -case 0xA83F: -case 0xA840: -case 0xA841: -case 0xA842: -case 0xA843: -case 0xA844: -case 0xA845: -case 0xA846: -case 0xA847: -case 0xA848: -case 0xA849: -case 0xA84A: -case 0xA84B: -case 0xA84C: -case 0xA84D: -case 0xA84E: -case 0xA84F: -case 0xA850: -case 0xA851: -case 0xA852: -case 0xA853: -case 0xA854: -case 0xA855: -case 0xA856: -case 0xA857: -case 0xA858: -case 0xA859: -case 0xA85A: -case 0xA85B: -case 0xA85C: -case 0xA85D: -case 0xA85E: -case 0xA85F: -case 0xA860: -case 0xA861: -case 0xA862: -case 0xA863: -case 0xA864: -case 0xA865: -case 0xA866: -case 0xA867: -case 0xA868: -case 0xA869: -case 0xA86A: -case 0xA86B: -case 0xA86C: -case 0xA86D: -case 0xA86E: -case 0xA86F: -case 0xA870: -case 0xA871: -case 0xA872: -case 0xA873: -case 0xA874: -case 0xA875: -case 0xA876: -case 0xA877: -case 0xA878: -case 0xA879: -case 0xA87A: -case 0xA87B: -case 0xA87C: -case 0xA87D: -case 0xA87E: -case 0xA87F: -case 0xA880: -case 0xA881: -case 0xA882: -case 0xA883: -case 0xA884: -case 0xA885: -case 0xA886: -case 0xA887: -case 0xA888: -case 0xA889: -case 0xA88A: -case 0xA88B: -case 0xA88C: -case 0xA88D: -case 0xA88E: -case 0xA88F: -case 0xA890: -case 0xA891: -case 0xA892: -case 0xA893: -case 0xA894: -case 0xA895: -case 0xA896: -case 0xA897: -case 0xA898: -case 0xA899: -case 0xA89A: -case 0xA89B: -case 0xA89C: -case 0xA89D: -case 0xA89E: -case 0xA89F: -case 0xA8A0: -case 0xA8A1: -case 0xA8A2: -case 0xA8A3: -case 0xA8A4: -case 0xA8A5: -case 0xA8A6: -case 0xA8A7: -case 0xA8A8: -case 0xA8A9: -case 0xA8AA: -case 0xA8AB: -case 0xA8AC: -case 0xA8AD: -case 0xA8AE: -case 0xA8AF: -case 0xA8B0: -case 0xA8B1: -case 0xA8B2: -case 0xA8B3: -case 0xA8B4: -case 0xA8B5: -case 0xA8B6: -case 0xA8B7: -case 0xA8B8: -case 0xA8B9: -case 0xA8BA: -case 0xA8BB: -case 0xA8BC: -case 0xA8BD: -case 0xA8BE: -case 0xA8BF: -case 0xA8C0: -case 0xA8C1: -case 0xA8C2: -case 0xA8C3: -case 0xA8C4: -case 0xA8C5: -case 0xA8C6: -case 0xA8C7: -case 0xA8C8: -case 0xA8C9: -case 0xA8CA: -case 0xA8CB: -case 0xA8CC: -case 0xA8CD: -case 0xA8CE: -case 0xA8CF: -case 0xA8D0: -case 0xA8D1: -case 0xA8D2: -case 0xA8D3: -case 0xA8D4: -case 0xA8D5: -case 0xA8D6: -case 0xA8D7: -case 0xA8D8: -case 0xA8D9: -case 0xA8DA: -case 0xA8DB: -case 0xA8DC: -case 0xA8DD: -case 0xA8DE: -case 0xA8DF: -case 0xA8E0: -case 0xA8E1: -case 0xA8E2: -case 0xA8E3: -case 0xA8E4: -case 0xA8E5: -case 0xA8E6: -case 0xA8E7: -case 0xA8E8: -case 0xA8E9: -case 0xA8EA: -case 0xA8EB: -case 0xA8EC: -case 0xA8ED: -case 0xA8EE: -case 0xA8EF: -case 0xA8F0: -case 0xA8F1: -case 0xA8F2: -case 0xA8F3: -case 0xA8F4: -case 0xA8F5: -case 0xA8F6: -case 0xA8F7: -case 0xA8F8: -case 0xA8F9: -case 0xA8FA: -case 0xA8FB: -case 0xA8FC: -case 0xA8FD: -case 0xA8FE: -case 0xA8FF: -case 0xA900: -case 0xA901: -case 0xA902: -case 0xA903: -case 0xA904: -case 0xA905: -case 0xA906: -case 0xA907: -case 0xA908: -case 0xA909: -case 0xA90A: -case 0xA90B: -case 0xA90C: -case 0xA90D: -case 0xA90E: -case 0xA90F: -case 0xA910: -case 0xA911: -case 0xA912: -case 0xA913: -case 0xA914: -case 0xA915: -case 0xA916: -case 0xA917: -case 0xA918: -case 0xA919: -case 0xA91A: -case 0xA91B: -case 0xA91C: -case 0xA91D: -case 0xA91E: -case 0xA91F: -case 0xA920: -case 0xA921: -case 0xA922: -case 0xA923: -case 0xA924: -case 0xA925: -case 0xA926: -case 0xA927: -case 0xA928: -case 0xA929: -case 0xA92A: -case 0xA92B: -case 0xA92C: -case 0xA92D: -case 0xA92E: -case 0xA92F: -case 0xA930: -case 0xA931: -case 0xA932: -case 0xA933: -case 0xA934: -case 0xA935: -case 0xA936: -case 0xA937: -case 0xA938: -case 0xA939: -case 0xA93A: -case 0xA93B: -case 0xA93C: -case 0xA93D: -case 0xA93E: -case 0xA93F: -case 0xA940: -case 0xA941: -case 0xA942: -case 0xA943: -case 0xA944: -case 0xA945: -case 0xA946: -case 0xA947: -case 0xA948: -case 0xA949: -case 0xA94A: -case 0xA94B: -case 0xA94C: -case 0xA94D: -case 0xA94E: -case 0xA94F: -case 0xA950: -case 0xA951: -case 0xA952: -case 0xA953: -case 0xA954: -case 0xA955: -case 0xA956: -case 0xA957: -case 0xA958: -case 0xA959: -case 0xA95A: -case 0xA95B: -case 0xA95C: -case 0xA95D: -case 0xA95E: -case 0xA95F: -case 0xA960: -case 0xA961: -case 0xA962: -case 0xA963: -case 0xA964: -case 0xA965: -case 0xA966: -case 0xA967: -case 0xA968: -case 0xA969: -case 0xA96A: -case 0xA96B: -case 0xA96C: -case 0xA96D: -case 0xA96E: -case 0xA96F: -case 0xA970: -case 0xA971: -case 0xA972: -case 0xA973: -case 0xA974: -case 0xA975: -case 0xA976: -case 0xA977: -case 0xA978: -case 0xA979: -case 0xA97A: -case 0xA97B: -case 0xA97C: -case 0xA97D: -case 0xA97E: -case 0xA97F: -case 0xA980: -case 0xA981: -case 0xA982: -case 0xA983: -case 0xA984: -case 0xA985: -case 0xA986: -case 0xA987: -case 0xA988: -case 0xA989: -case 0xA98A: -case 0xA98B: -case 0xA98C: -case 0xA98D: -case 0xA98E: -case 0xA98F: -case 0xA990: -case 0xA991: -case 0xA992: -case 0xA993: -case 0xA994: -case 0xA995: -case 0xA996: -case 0xA997: -case 0xA998: -case 0xA999: -case 0xA99A: -case 0xA99B: -case 0xA99C: -case 0xA99D: -case 0xA99E: -case 0xA99F: -case 0xA9A0: -case 0xA9A1: -case 0xA9A2: -case 0xA9A3: -case 0xA9A4: -case 0xA9A5: -case 0xA9A6: -case 0xA9A7: -case 0xA9A8: -case 0xA9A9: -case 0xA9AA: -case 0xA9AB: -case 0xA9AC: -case 0xA9AD: -case 0xA9AE: -case 0xA9AF: -case 0xA9B0: -case 0xA9B1: -case 0xA9B2: -case 0xA9B3: -case 0xA9B4: -case 0xA9B5: -case 0xA9B6: -case 0xA9B7: -case 0xA9B8: -case 0xA9B9: -case 0xA9BA: -case 0xA9BB: -case 0xA9BC: -case 0xA9BD: -case 0xA9BE: -case 0xA9BF: -case 0xA9C0: -case 0xA9C1: -case 0xA9C2: -case 0xA9C3: -case 0xA9C4: -case 0xA9C5: -case 0xA9C6: -case 0xA9C7: -case 0xA9C8: -case 0xA9C9: -case 0xA9CA: -case 0xA9CB: -case 0xA9CC: -case 0xA9CD: -case 0xA9CE: -case 0xA9CF: -case 0xA9D0: -case 0xA9D1: -case 0xA9D2: -case 0xA9D3: -case 0xA9D4: -case 0xA9D5: -case 0xA9D6: -case 0xA9D7: -case 0xA9D8: -case 0xA9D9: -case 0xA9DA: -case 0xA9DB: -case 0xA9DC: -case 0xA9DD: -case 0xA9DE: -case 0xA9DF: -case 0xA9E0: -case 0xA9E1: -case 0xA9E2: -case 0xA9E3: -case 0xA9E4: -case 0xA9E5: -case 0xA9E6: -case 0xA9E7: -case 0xA9E8: -case 0xA9E9: -case 0xA9EA: -case 0xA9EB: -case 0xA9EC: -case 0xA9ED: -case 0xA9EE: -case 0xA9EF: -case 0xA9F0: -case 0xA9F1: -case 0xA9F2: -case 0xA9F3: -case 0xA9F4: -case 0xA9F5: -case 0xA9F6: -case 0xA9F7: -case 0xA9F8: -case 0xA9F9: -case 0xA9FA: -case 0xA9FB: -case 0xA9FC: -case 0xA9FD: -case 0xA9FE: -case 0xA9FF: -case 0xAA00: -case 0xAA01: -case 0xAA02: -case 0xAA03: -case 0xAA04: -case 0xAA05: -case 0xAA06: -case 0xAA07: -case 0xAA08: -case 0xAA09: -case 0xAA0A: -case 0xAA0B: -case 0xAA0C: -case 0xAA0D: -case 0xAA0E: -case 0xAA0F: -case 0xAA10: -case 0xAA11: -case 0xAA12: -case 0xAA13: -case 0xAA14: -case 0xAA15: -case 0xAA16: -case 0xAA17: -case 0xAA18: -case 0xAA19: -case 0xAA1A: -case 0xAA1B: -case 0xAA1C: -case 0xAA1D: -case 0xAA1E: -case 0xAA1F: -case 0xAA20: -case 0xAA21: -case 0xAA22: -case 0xAA23: -case 0xAA24: -case 0xAA25: -case 0xAA26: -case 0xAA27: -case 0xAA28: -case 0xAA29: -case 0xAA2A: -case 0xAA2B: -case 0xAA2C: -case 0xAA2D: -case 0xAA2E: -case 0xAA2F: -case 0xAA30: -case 0xAA31: -case 0xAA32: -case 0xAA33: -case 0xAA34: -case 0xAA35: -case 0xAA36: -case 0xAA37: -case 0xAA38: -case 0xAA39: -case 0xAA3A: -case 0xAA3B: -case 0xAA3C: -case 0xAA3D: -case 0xAA3E: -case 0xAA3F: -case 0xAA40: -case 0xAA41: -case 0xAA42: -case 0xAA43: -case 0xAA44: -case 0xAA45: -case 0xAA46: -case 0xAA47: -case 0xAA48: -case 0xAA49: -case 0xAA4A: -case 0xAA4B: -case 0xAA4C: -case 0xAA4D: -case 0xAA4E: -case 0xAA4F: -case 0xAA50: -case 0xAA51: -case 0xAA52: -case 0xAA53: -case 0xAA54: -case 0xAA55: -case 0xAA56: -case 0xAA57: -case 0xAA58: -case 0xAA59: -case 0xAA5A: -case 0xAA5B: -case 0xAA5C: -case 0xAA5D: -case 0xAA5E: -case 0xAA5F: -case 0xAA60: -case 0xAA61: -case 0xAA62: -case 0xAA63: -case 0xAA64: -case 0xAA65: -case 0xAA66: -case 0xAA67: -case 0xAA68: -case 0xAA69: -case 0xAA6A: -case 0xAA6B: -case 0xAA6C: -case 0xAA6D: -case 0xAA6E: -case 0xAA6F: -case 0xAA70: -case 0xAA71: -case 0xAA72: -case 0xAA73: -case 0xAA74: -case 0xAA75: -case 0xAA76: -case 0xAA77: -case 0xAA78: -case 0xAA79: -case 0xAA7A: -case 0xAA7B: -case 0xAA7C: -case 0xAA7D: -case 0xAA7E: -case 0xAA7F: -case 0xAA80: -case 0xAA81: -case 0xAA82: -case 0xAA83: -case 0xAA84: -case 0xAA85: -case 0xAA86: -case 0xAA87: -case 0xAA88: -case 0xAA89: -case 0xAA8A: -case 0xAA8B: -case 0xAA8C: -case 0xAA8D: -case 0xAA8E: -case 0xAA8F: -case 0xAA90: -case 0xAA91: -case 0xAA92: -case 0xAA93: -case 0xAA94: -case 0xAA95: -case 0xAA96: -case 0xAA97: -case 0xAA98: -case 0xAA99: -case 0xAA9A: -case 0xAA9B: -case 0xAA9C: -case 0xAA9D: -case 0xAA9E: -case 0xAA9F: -case 0xAAA0: -case 0xAAA1: -case 0xAAA2: -case 0xAAA3: -case 0xAAA4: -case 0xAAA5: -case 0xAAA6: -case 0xAAA7: -case 0xAAA8: -case 0xAAA9: -case 0xAAAA: -case 0xAAAB: -case 0xAAAC: -case 0xAAAD: -case 0xAAAE: -case 0xAAAF: -case 0xAAB0: -case 0xAAB1: -case 0xAAB2: -case 0xAAB3: -case 0xAAB4: -case 0xAAB5: -case 0xAAB6: -case 0xAAB7: -case 0xAAB8: -case 0xAAB9: -case 0xAABA: -case 0xAABB: -case 0xAABC: -case 0xAABD: -case 0xAABE: -case 0xAABF: -case 0xAAC0: -case 0xAAC1: -case 0xAAC2: -case 0xAAC3: -case 0xAAC4: -case 0xAAC5: -case 0xAAC6: -case 0xAAC7: -case 0xAAC8: -case 0xAAC9: -case 0xAACA: -case 0xAACB: -case 0xAACC: -case 0xAACD: -case 0xAACE: -case 0xAACF: -case 0xAAD0: -case 0xAAD1: -case 0xAAD2: -case 0xAAD3: -case 0xAAD4: -case 0xAAD5: -case 0xAAD6: -case 0xAAD7: -case 0xAAD8: -case 0xAAD9: -case 0xAADA: -case 0xAADB: -case 0xAADC: -case 0xAADD: -case 0xAADE: -case 0xAADF: -case 0xAAE0: -case 0xAAE1: -case 0xAAE2: -case 0xAAE3: -case 0xAAE4: -case 0xAAE5: -case 0xAAE6: -case 0xAAE7: -case 0xAAE8: -case 0xAAE9: -case 0xAAEA: -case 0xAAEB: -case 0xAAEC: -case 0xAAED: -case 0xAAEE: -case 0xAAEF: -case 0xAAF0: -case 0xAAF1: -case 0xAAF2: -case 0xAAF3: -case 0xAAF4: -case 0xAAF5: -case 0xAAF6: -case 0xAAF7: -case 0xAAF8: -case 0xAAF9: -case 0xAAFA: -case 0xAAFB: -case 0xAAFC: -case 0xAAFD: -case 0xAAFE: -case 0xAAFF: -case 0xAB00: -case 0xAB01: -case 0xAB02: -case 0xAB03: -case 0xAB04: -case 0xAB05: -case 0xAB06: -case 0xAB07: -case 0xAB08: -case 0xAB09: -case 0xAB0A: -case 0xAB0B: -case 0xAB0C: -case 0xAB0D: -case 0xAB0E: -case 0xAB0F: -case 0xAB10: -case 0xAB11: -case 0xAB12: -case 0xAB13: -case 0xAB14: -case 0xAB15: -case 0xAB16: -case 0xAB17: -case 0xAB18: -case 0xAB19: -case 0xAB1A: -case 0xAB1B: -case 0xAB1C: -case 0xAB1D: -case 0xAB1E: -case 0xAB1F: -case 0xAB20: -case 0xAB21: -case 0xAB22: -case 0xAB23: -case 0xAB24: -case 0xAB25: -case 0xAB26: -case 0xAB27: -case 0xAB28: -case 0xAB29: -case 0xAB2A: -case 0xAB2B: -case 0xAB2C: -case 0xAB2D: -case 0xAB2E: -case 0xAB2F: -case 0xAB30: -case 0xAB31: -case 0xAB32: -case 0xAB33: -case 0xAB34: -case 0xAB35: -case 0xAB36: -case 0xAB37: -case 0xAB38: -case 0xAB39: -case 0xAB3A: -case 0xAB3B: -case 0xAB3C: -case 0xAB3D: -case 0xAB3E: -case 0xAB3F: -case 0xAB40: -case 0xAB41: -case 0xAB42: -case 0xAB43: -case 0xAB44: -case 0xAB45: -case 0xAB46: -case 0xAB47: -case 0xAB48: -case 0xAB49: -case 0xAB4A: -case 0xAB4B: -case 0xAB4C: -case 0xAB4D: -case 0xAB4E: -case 0xAB4F: -case 0xAB50: -case 0xAB51: -case 0xAB52: -case 0xAB53: -case 0xAB54: -case 0xAB55: -case 0xAB56: -case 0xAB57: -case 0xAB58: -case 0xAB59: -case 0xAB5A: -case 0xAB5B: -case 0xAB5C: -case 0xAB5D: -case 0xAB5E: -case 0xAB5F: -case 0xAB60: -case 0xAB61: -case 0xAB62: -case 0xAB63: -case 0xAB64: -case 0xAB65: -case 0xAB66: -case 0xAB67: -case 0xAB68: -case 0xAB69: -case 0xAB6A: -case 0xAB6B: -case 0xAB6C: -case 0xAB6D: -case 0xAB6E: -case 0xAB6F: -case 0xAB70: -case 0xAB71: -case 0xAB72: -case 0xAB73: -case 0xAB74: -case 0xAB75: -case 0xAB76: -case 0xAB77: -case 0xAB78: -case 0xAB79: -case 0xAB7A: -case 0xAB7B: -case 0xAB7C: -case 0xAB7D: -case 0xAB7E: -case 0xAB7F: -case 0xAB80: -case 0xAB81: -case 0xAB82: -case 0xAB83: -case 0xAB84: -case 0xAB85: -case 0xAB86: -case 0xAB87: -case 0xAB88: -case 0xAB89: -case 0xAB8A: -case 0xAB8B: -case 0xAB8C: -case 0xAB8D: -case 0xAB8E: -case 0xAB8F: -case 0xAB90: -case 0xAB91: -case 0xAB92: -case 0xAB93: -case 0xAB94: -case 0xAB95: -case 0xAB96: -case 0xAB97: -case 0xAB98: -case 0xAB99: -case 0xAB9A: -case 0xAB9B: -case 0xAB9C: -case 0xAB9D: -case 0xAB9E: -case 0xAB9F: -case 0xABA0: -case 0xABA1: -case 0xABA2: -case 0xABA3: -case 0xABA4: -case 0xABA5: -case 0xABA6: -case 0xABA7: -case 0xABA8: -case 0xABA9: -case 0xABAA: -case 0xABAB: -case 0xABAC: -case 0xABAD: -case 0xABAE: -case 0xABAF: -case 0xABB0: -case 0xABB1: -case 0xABB2: -case 0xABB3: -case 0xABB4: -case 0xABB5: -case 0xABB6: -case 0xABB7: -case 0xABB8: -case 0xABB9: -case 0xABBA: -case 0xABBB: -case 0xABBC: -case 0xABBD: -case 0xABBE: -case 0xABBF: -case 0xABC0: -case 0xABC1: -case 0xABC2: -case 0xABC3: -case 0xABC4: -case 0xABC5: -case 0xABC6: -case 0xABC7: -case 0xABC8: -case 0xABC9: -case 0xABCA: -case 0xABCB: -case 0xABCC: -case 0xABCD: -case 0xABCE: -case 0xABCF: -case 0xABD0: -case 0xABD1: -case 0xABD2: -case 0xABD3: -case 0xABD4: -case 0xABD5: -case 0xABD6: -case 0xABD7: -case 0xABD8: -case 0xABD9: -case 0xABDA: -case 0xABDB: -case 0xABDC: -case 0xABDD: -case 0xABDE: -case 0xABDF: -case 0xABE0: -case 0xABE1: -case 0xABE2: -case 0xABE3: -case 0xABE4: -case 0xABE5: -case 0xABE6: -case 0xABE7: -case 0xABE8: -case 0xABE9: -case 0xABEA: -case 0xABEB: -case 0xABEC: -case 0xABED: -case 0xABEE: -case 0xABEF: -case 0xABF0: -case 0xABF1: -case 0xABF2: -case 0xABF3: -case 0xABF4: -case 0xABF5: -case 0xABF6: -case 0xABF7: -case 0xABF8: -case 0xABF9: -case 0xABFA: -case 0xABFB: -case 0xABFC: -case 0xABFD: -case 0xABFE: -case 0xABFF: -case 0xAC00: -case 0xAC01: -case 0xAC02: -case 0xAC03: -case 0xAC04: -case 0xAC05: -case 0xAC06: -case 0xAC07: -case 0xAC08: -case 0xAC09: -case 0xAC0A: -case 0xAC0B: -case 0xAC0C: -case 0xAC0D: -case 0xAC0E: -case 0xAC0F: -case 0xAC10: -case 0xAC11: -case 0xAC12: -case 0xAC13: -case 0xAC14: -case 0xAC15: -case 0xAC16: -case 0xAC17: -case 0xAC18: -case 0xAC19: -case 0xAC1A: -case 0xAC1B: -case 0xAC1C: -case 0xAC1D: -case 0xAC1E: -case 0xAC1F: -case 0xAC20: -case 0xAC21: -case 0xAC22: -case 0xAC23: -case 0xAC24: -case 0xAC25: -case 0xAC26: -case 0xAC27: -case 0xAC28: -case 0xAC29: -case 0xAC2A: -case 0xAC2B: -case 0xAC2C: -case 0xAC2D: -case 0xAC2E: -case 0xAC2F: -case 0xAC30: -case 0xAC31: -case 0xAC32: -case 0xAC33: -case 0xAC34: -case 0xAC35: -case 0xAC36: -case 0xAC37: -case 0xAC38: -case 0xAC39: -case 0xAC3A: -case 0xAC3B: -case 0xAC3C: -case 0xAC3D: -case 0xAC3E: -case 0xAC3F: -case 0xAC40: -case 0xAC41: -case 0xAC42: -case 0xAC43: -case 0xAC44: -case 0xAC45: -case 0xAC46: -case 0xAC47: -case 0xAC48: -case 0xAC49: -case 0xAC4A: -case 0xAC4B: -case 0xAC4C: -case 0xAC4D: -case 0xAC4E: -case 0xAC4F: -case 0xAC50: -case 0xAC51: -case 0xAC52: -case 0xAC53: -case 0xAC54: -case 0xAC55: -case 0xAC56: -case 0xAC57: -case 0xAC58: -case 0xAC59: -case 0xAC5A: -case 0xAC5B: -case 0xAC5C: -case 0xAC5D: -case 0xAC5E: -case 0xAC5F: -case 0xAC60: -case 0xAC61: -case 0xAC62: -case 0xAC63: -case 0xAC64: -case 0xAC65: -case 0xAC66: -case 0xAC67: -case 0xAC68: -case 0xAC69: -case 0xAC6A: -case 0xAC6B: -case 0xAC6C: -case 0xAC6D: -case 0xAC6E: -case 0xAC6F: -case 0xAC70: -case 0xAC71: -case 0xAC72: -case 0xAC73: -case 0xAC74: -case 0xAC75: -case 0xAC76: -case 0xAC77: -case 0xAC78: -case 0xAC79: -case 0xAC7A: -case 0xAC7B: -case 0xAC7C: -case 0xAC7D: -case 0xAC7E: -case 0xAC7F: -case 0xAC80: -case 0xAC81: -case 0xAC82: -case 0xAC83: -case 0xAC84: -case 0xAC85: -case 0xAC86: -case 0xAC87: -case 0xAC88: -case 0xAC89: -case 0xAC8A: -case 0xAC8B: -case 0xAC8C: -case 0xAC8D: -case 0xAC8E: -case 0xAC8F: -case 0xAC90: -case 0xAC91: -case 0xAC92: -case 0xAC93: -case 0xAC94: -case 0xAC95: -case 0xAC96: -case 0xAC97: -case 0xAC98: -case 0xAC99: -case 0xAC9A: -case 0xAC9B: -case 0xAC9C: -case 0xAC9D: -case 0xAC9E: -case 0xAC9F: -case 0xACA0: -case 0xACA1: -case 0xACA2: -case 0xACA3: -case 0xACA4: -case 0xACA5: -case 0xACA6: -case 0xACA7: -case 0xACA8: -case 0xACA9: -case 0xACAA: -case 0xACAB: -case 0xACAC: -case 0xACAD: -case 0xACAE: -case 0xACAF: -case 0xACB0: -case 0xACB1: -case 0xACB2: -case 0xACB3: -case 0xACB4: -case 0xACB5: -case 0xACB6: -case 0xACB7: -case 0xACB8: -case 0xACB9: -case 0xACBA: -case 0xACBB: -case 0xACBC: -case 0xACBD: -case 0xACBE: -case 0xACBF: -case 0xACC0: -case 0xACC1: -case 0xACC2: -case 0xACC3: -case 0xACC4: -case 0xACC5: -case 0xACC6: -case 0xACC7: -case 0xACC8: -case 0xACC9: -case 0xACCA: -case 0xACCB: -case 0xACCC: -case 0xACCD: -case 0xACCE: -case 0xACCF: -case 0xACD0: -case 0xACD1: -case 0xACD2: -case 0xACD3: -case 0xACD4: -case 0xACD5: -case 0xACD6: -case 0xACD7: -case 0xACD8: -case 0xACD9: -case 0xACDA: -case 0xACDB: -case 0xACDC: -case 0xACDD: -case 0xACDE: -case 0xACDF: -case 0xACE0: -case 0xACE1: -case 0xACE2: -case 0xACE3: -case 0xACE4: -case 0xACE5: -case 0xACE6: -case 0xACE7: -case 0xACE8: -case 0xACE9: -case 0xACEA: -case 0xACEB: -case 0xACEC: -case 0xACED: -case 0xACEE: -case 0xACEF: -case 0xACF0: -case 0xACF1: -case 0xACF2: -case 0xACF3: -case 0xACF4: -case 0xACF5: -case 0xACF6: -case 0xACF7: -case 0xACF8: -case 0xACF9: -case 0xACFA: -case 0xACFB: -case 0xACFC: -case 0xACFD: -case 0xACFE: -case 0xACFF: -case 0xAD00: -case 0xAD01: -case 0xAD02: -case 0xAD03: -case 0xAD04: -case 0xAD05: -case 0xAD06: -case 0xAD07: -case 0xAD08: -case 0xAD09: -case 0xAD0A: -case 0xAD0B: -case 0xAD0C: -case 0xAD0D: -case 0xAD0E: -case 0xAD0F: -case 0xAD10: -case 0xAD11: -case 0xAD12: -case 0xAD13: -case 0xAD14: -case 0xAD15: -case 0xAD16: -case 0xAD17: -case 0xAD18: -case 0xAD19: -case 0xAD1A: -case 0xAD1B: -case 0xAD1C: -case 0xAD1D: -case 0xAD1E: -case 0xAD1F: -case 0xAD20: -case 0xAD21: -case 0xAD22: -case 0xAD23: -case 0xAD24: -case 0xAD25: -case 0xAD26: -case 0xAD27: -case 0xAD28: -case 0xAD29: -case 0xAD2A: -case 0xAD2B: -case 0xAD2C: -case 0xAD2D: -case 0xAD2E: -case 0xAD2F: -case 0xAD30: -case 0xAD31: -case 0xAD32: -case 0xAD33: -case 0xAD34: -case 0xAD35: -case 0xAD36: -case 0xAD37: -case 0xAD38: -case 0xAD39: -case 0xAD3A: -case 0xAD3B: -case 0xAD3C: -case 0xAD3D: -case 0xAD3E: -case 0xAD3F: -case 0xAD40: -case 0xAD41: -case 0xAD42: -case 0xAD43: -case 0xAD44: -case 0xAD45: -case 0xAD46: -case 0xAD47: -case 0xAD48: -case 0xAD49: -case 0xAD4A: -case 0xAD4B: -case 0xAD4C: -case 0xAD4D: -case 0xAD4E: -case 0xAD4F: -case 0xAD50: -case 0xAD51: -case 0xAD52: -case 0xAD53: -case 0xAD54: -case 0xAD55: -case 0xAD56: -case 0xAD57: -case 0xAD58: -case 0xAD59: -case 0xAD5A: -case 0xAD5B: -case 0xAD5C: -case 0xAD5D: -case 0xAD5E: -case 0xAD5F: -case 0xAD60: -case 0xAD61: -case 0xAD62: -case 0xAD63: -case 0xAD64: -case 0xAD65: -case 0xAD66: -case 0xAD67: -case 0xAD68: -case 0xAD69: -case 0xAD6A: -case 0xAD6B: -case 0xAD6C: -case 0xAD6D: -case 0xAD6E: -case 0xAD6F: -case 0xAD70: -case 0xAD71: -case 0xAD72: -case 0xAD73: -case 0xAD74: -case 0xAD75: -case 0xAD76: -case 0xAD77: -case 0xAD78: -case 0xAD79: -case 0xAD7A: -case 0xAD7B: -case 0xAD7C: -case 0xAD7D: -case 0xAD7E: -case 0xAD7F: -case 0xAD80: -case 0xAD81: -case 0xAD82: -case 0xAD83: -case 0xAD84: -case 0xAD85: -case 0xAD86: -case 0xAD87: -case 0xAD88: -case 0xAD89: -case 0xAD8A: -case 0xAD8B: -case 0xAD8C: -case 0xAD8D: -case 0xAD8E: -case 0xAD8F: -case 0xAD90: -case 0xAD91: -case 0xAD92: -case 0xAD93: -case 0xAD94: -case 0xAD95: -case 0xAD96: -case 0xAD97: -case 0xAD98: -case 0xAD99: -case 0xAD9A: -case 0xAD9B: -case 0xAD9C: -case 0xAD9D: -case 0xAD9E: -case 0xAD9F: -case 0xADA0: -case 0xADA1: -case 0xADA2: -case 0xADA3: -case 0xADA4: -case 0xADA5: -case 0xADA6: -case 0xADA7: -case 0xADA8: -case 0xADA9: -case 0xADAA: -case 0xADAB: -case 0xADAC: -case 0xADAD: -case 0xADAE: -case 0xADAF: -case 0xADB0: -case 0xADB1: -case 0xADB2: -case 0xADB3: -case 0xADB4: -case 0xADB5: -case 0xADB6: -case 0xADB7: -case 0xADB8: -case 0xADB9: -case 0xADBA: -case 0xADBB: -case 0xADBC: -case 0xADBD: -case 0xADBE: -case 0xADBF: -case 0xADC0: -case 0xADC1: -case 0xADC2: -case 0xADC3: -case 0xADC4: -case 0xADC5: -case 0xADC6: -case 0xADC7: -case 0xADC8: -case 0xADC9: -case 0xADCA: -case 0xADCB: -case 0xADCC: -case 0xADCD: -case 0xADCE: -case 0xADCF: -case 0xADD0: -case 0xADD1: -case 0xADD2: -case 0xADD3: -case 0xADD4: -case 0xADD5: -case 0xADD6: -case 0xADD7: -case 0xADD8: -case 0xADD9: -case 0xADDA: -case 0xADDB: -case 0xADDC: -case 0xADDD: -case 0xADDE: -case 0xADDF: -case 0xADE0: -case 0xADE1: -case 0xADE2: -case 0xADE3: -case 0xADE4: -case 0xADE5: -case 0xADE6: -case 0xADE7: -case 0xADE8: -case 0xADE9: -case 0xADEA: -case 0xADEB: -case 0xADEC: -case 0xADED: -case 0xADEE: -case 0xADEF: -case 0xADF0: -case 0xADF1: -case 0xADF2: -case 0xADF3: -case 0xADF4: -case 0xADF5: -case 0xADF6: -case 0xADF7: -case 0xADF8: -case 0xADF9: -case 0xADFA: -case 0xADFB: -case 0xADFC: -case 0xADFD: -case 0xADFE: -case 0xADFF: -case 0xAE00: -case 0xAE01: -case 0xAE02: -case 0xAE03: -case 0xAE04: -case 0xAE05: -case 0xAE06: -case 0xAE07: -case 0xAE08: -case 0xAE09: -case 0xAE0A: -case 0xAE0B: -case 0xAE0C: -case 0xAE0D: -case 0xAE0E: -case 0xAE0F: -case 0xAE10: -case 0xAE11: -case 0xAE12: -case 0xAE13: -case 0xAE14: -case 0xAE15: -case 0xAE16: -case 0xAE17: -case 0xAE18: -case 0xAE19: -case 0xAE1A: -case 0xAE1B: -case 0xAE1C: -case 0xAE1D: -case 0xAE1E: -case 0xAE1F: -case 0xAE20: -case 0xAE21: -case 0xAE22: -case 0xAE23: -case 0xAE24: -case 0xAE25: -case 0xAE26: -case 0xAE27: -case 0xAE28: -case 0xAE29: -case 0xAE2A: -case 0xAE2B: -case 0xAE2C: -case 0xAE2D: -case 0xAE2E: -case 0xAE2F: -case 0xAE30: -case 0xAE31: -case 0xAE32: -case 0xAE33: -case 0xAE34: -case 0xAE35: -case 0xAE36: -case 0xAE37: -case 0xAE38: -case 0xAE39: -case 0xAE3A: -case 0xAE3B: -case 0xAE3C: -case 0xAE3D: -case 0xAE3E: -case 0xAE3F: -case 0xAE40: -case 0xAE41: -case 0xAE42: -case 0xAE43: -case 0xAE44: -case 0xAE45: -case 0xAE46: -case 0xAE47: -case 0xAE48: -case 0xAE49: -case 0xAE4A: -case 0xAE4B: -case 0xAE4C: -case 0xAE4D: -case 0xAE4E: -case 0xAE4F: -case 0xAE50: -case 0xAE51: -case 0xAE52: -case 0xAE53: -case 0xAE54: -case 0xAE55: -case 0xAE56: -case 0xAE57: -case 0xAE58: -case 0xAE59: -case 0xAE5A: -case 0xAE5B: -case 0xAE5C: -case 0xAE5D: -case 0xAE5E: -case 0xAE5F: -case 0xAE60: -case 0xAE61: -case 0xAE62: -case 0xAE63: -case 0xAE64: -case 0xAE65: -case 0xAE66: -case 0xAE67: -case 0xAE68: -case 0xAE69: -case 0xAE6A: -case 0xAE6B: -case 0xAE6C: -case 0xAE6D: -case 0xAE6E: -case 0xAE6F: -case 0xAE70: -case 0xAE71: -case 0xAE72: -case 0xAE73: -case 0xAE74: -case 0xAE75: -case 0xAE76: -case 0xAE77: -case 0xAE78: -case 0xAE79: -case 0xAE7A: -case 0xAE7B: -case 0xAE7C: -case 0xAE7D: -case 0xAE7E: -case 0xAE7F: -case 0xAE80: -case 0xAE81: -case 0xAE82: -case 0xAE83: -case 0xAE84: -case 0xAE85: -case 0xAE86: -case 0xAE87: -case 0xAE88: -case 0xAE89: -case 0xAE8A: -case 0xAE8B: -case 0xAE8C: -case 0xAE8D: -case 0xAE8E: -case 0xAE8F: -case 0xAE90: -case 0xAE91: -case 0xAE92: -case 0xAE93: -case 0xAE94: -case 0xAE95: -case 0xAE96: -case 0xAE97: -case 0xAE98: -case 0xAE99: -case 0xAE9A: -case 0xAE9B: -case 0xAE9C: -case 0xAE9D: -case 0xAE9E: -case 0xAE9F: -case 0xAEA0: -case 0xAEA1: -case 0xAEA2: -case 0xAEA3: -case 0xAEA4: -case 0xAEA5: -case 0xAEA6: -case 0xAEA7: -case 0xAEA8: -case 0xAEA9: -case 0xAEAA: -case 0xAEAB: -case 0xAEAC: -case 0xAEAD: -case 0xAEAE: -case 0xAEAF: -case 0xAEB0: -case 0xAEB1: -case 0xAEB2: -case 0xAEB3: -case 0xAEB4: -case 0xAEB5: -case 0xAEB6: -case 0xAEB7: -case 0xAEB8: -case 0xAEB9: -case 0xAEBA: -case 0xAEBB: -case 0xAEBC: -case 0xAEBD: -case 0xAEBE: -case 0xAEBF: -case 0xAEC0: -case 0xAEC1: -case 0xAEC2: -case 0xAEC3: -case 0xAEC4: -case 0xAEC5: -case 0xAEC6: -case 0xAEC7: -case 0xAEC8: -case 0xAEC9: -case 0xAECA: -case 0xAECB: -case 0xAECC: -case 0xAECD: -case 0xAECE: -case 0xAECF: -case 0xAED0: -case 0xAED1: -case 0xAED2: -case 0xAED3: -case 0xAED4: -case 0xAED5: -case 0xAED6: -case 0xAED7: -case 0xAED8: -case 0xAED9: -case 0xAEDA: -case 0xAEDB: -case 0xAEDC: -case 0xAEDD: -case 0xAEDE: -case 0xAEDF: -case 0xAEE0: -case 0xAEE1: -case 0xAEE2: -case 0xAEE3: -case 0xAEE4: -case 0xAEE5: -case 0xAEE6: -case 0xAEE7: -case 0xAEE8: -case 0xAEE9: -case 0xAEEA: -case 0xAEEB: -case 0xAEEC: -case 0xAEED: -case 0xAEEE: -case 0xAEEF: -case 0xAEF0: -case 0xAEF1: -case 0xAEF2: -case 0xAEF3: -case 0xAEF4: -case 0xAEF5: -case 0xAEF6: -case 0xAEF7: -case 0xAEF8: -case 0xAEF9: -case 0xAEFA: -case 0xAEFB: -case 0xAEFC: -case 0xAEFD: -case 0xAEFE: -case 0xAEFF: -case 0xAF00: -case 0xAF01: -case 0xAF02: -case 0xAF03: -case 0xAF04: -case 0xAF05: -case 0xAF06: -case 0xAF07: -case 0xAF08: -case 0xAF09: -case 0xAF0A: -case 0xAF0B: -case 0xAF0C: -case 0xAF0D: -case 0xAF0E: -case 0xAF0F: -case 0xAF10: -case 0xAF11: -case 0xAF12: -case 0xAF13: -case 0xAF14: -case 0xAF15: -case 0xAF16: -case 0xAF17: -case 0xAF18: -case 0xAF19: -case 0xAF1A: -case 0xAF1B: -case 0xAF1C: -case 0xAF1D: -case 0xAF1E: -case 0xAF1F: -case 0xAF20: -case 0xAF21: -case 0xAF22: -case 0xAF23: -case 0xAF24: -case 0xAF25: -case 0xAF26: -case 0xAF27: -case 0xAF28: -case 0xAF29: -case 0xAF2A: -case 0xAF2B: -case 0xAF2C: -case 0xAF2D: -case 0xAF2E: -case 0xAF2F: -case 0xAF30: -case 0xAF31: -case 0xAF32: -case 0xAF33: -case 0xAF34: -case 0xAF35: -case 0xAF36: -case 0xAF37: -case 0xAF38: -case 0xAF39: -case 0xAF3A: -case 0xAF3B: -case 0xAF3C: -case 0xAF3D: -case 0xAF3E: -case 0xAF3F: -case 0xAF40: -case 0xAF41: -case 0xAF42: -case 0xAF43: -case 0xAF44: -case 0xAF45: -case 0xAF46: -case 0xAF47: -case 0xAF48: -case 0xAF49: -case 0xAF4A: -case 0xAF4B: -case 0xAF4C: -case 0xAF4D: -case 0xAF4E: -case 0xAF4F: -case 0xAF50: -case 0xAF51: -case 0xAF52: -case 0xAF53: -case 0xAF54: -case 0xAF55: -case 0xAF56: -case 0xAF57: -case 0xAF58: -case 0xAF59: -case 0xAF5A: -case 0xAF5B: -case 0xAF5C: -case 0xAF5D: -case 0xAF5E: -case 0xAF5F: -case 0xAF60: -case 0xAF61: -case 0xAF62: -case 0xAF63: -case 0xAF64: -case 0xAF65: -case 0xAF66: -case 0xAF67: -case 0xAF68: -case 0xAF69: -case 0xAF6A: -case 0xAF6B: -case 0xAF6C: -case 0xAF6D: -case 0xAF6E: -case 0xAF6F: -case 0xAF70: -case 0xAF71: -case 0xAF72: -case 0xAF73: -case 0xAF74: -case 0xAF75: -case 0xAF76: -case 0xAF77: -case 0xAF78: -case 0xAF79: -case 0xAF7A: -case 0xAF7B: -case 0xAF7C: -case 0xAF7D: -case 0xAF7E: -case 0xAF7F: -case 0xAF80: -case 0xAF81: -case 0xAF82: -case 0xAF83: -case 0xAF84: -case 0xAF85: -case 0xAF86: -case 0xAF87: -case 0xAF88: -case 0xAF89: -case 0xAF8A: -case 0xAF8B: -case 0xAF8C: -case 0xAF8D: -case 0xAF8E: -case 0xAF8F: -case 0xAF90: -case 0xAF91: -case 0xAF92: -case 0xAF93: -case 0xAF94: -case 0xAF95: -case 0xAF96: -case 0xAF97: -case 0xAF98: -case 0xAF99: -case 0xAF9A: -case 0xAF9B: -case 0xAF9C: -case 0xAF9D: -case 0xAF9E: -case 0xAF9F: -case 0xAFA0: -case 0xAFA1: -case 0xAFA2: -case 0xAFA3: -case 0xAFA4: -case 0xAFA5: -case 0xAFA6: -case 0xAFA7: -case 0xAFA8: -case 0xAFA9: -case 0xAFAA: -case 0xAFAB: -case 0xAFAC: -case 0xAFAD: -case 0xAFAE: -case 0xAFAF: -case 0xAFB0: -case 0xAFB1: -case 0xAFB2: -case 0xAFB3: -case 0xAFB4: -case 0xAFB5: -case 0xAFB6: -case 0xAFB7: -case 0xAFB8: -case 0xAFB9: -case 0xAFBA: -case 0xAFBB: -case 0xAFBC: -case 0xAFBD: -case 0xAFBE: -case 0xAFBF: -case 0xAFC0: -case 0xAFC1: -case 0xAFC2: -case 0xAFC3: -case 0xAFC4: -case 0xAFC5: -case 0xAFC6: -case 0xAFC7: -case 0xAFC8: -case 0xAFC9: -case 0xAFCA: -case 0xAFCB: -case 0xAFCC: -case 0xAFCD: -case 0xAFCE: -case 0xAFCF: -case 0xAFD0: -case 0xAFD1: -case 0xAFD2: -case 0xAFD3: -case 0xAFD4: -case 0xAFD5: -case 0xAFD6: -case 0xAFD7: -case 0xAFD8: -case 0xAFD9: -case 0xAFDA: -case 0xAFDB: -case 0xAFDC: -case 0xAFDD: -case 0xAFDE: -case 0xAFDF: -case 0xAFE0: -case 0xAFE1: -case 0xAFE2: -case 0xAFE3: -case 0xAFE4: -case 0xAFE5: -case 0xAFE6: -case 0xAFE7: -case 0xAFE8: -case 0xAFE9: -case 0xAFEA: -case 0xAFEB: -case 0xAFEC: -case 0xAFED: -case 0xAFEE: -case 0xAFEF: -case 0xAFF0: -case 0xAFF1: -case 0xAFF2: -case 0xAFF3: -case 0xAFF4: -case 0xAFF5: -case 0xAFF6: -case 0xAFF7: -case 0xAFF8: -case 0xAFF9: -case 0xAFFA: -case 0xAFFB: -case 0xAFFC: -case 0xAFFD: -case 0xAFFE: -case 0xAFFF: - -// 1010 -case 0xA000: -{ - u32 res; - PC -= 2; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_1010_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO -} -RET(4) diff --git a/yabause/src/c68k/c68k_opB.inc b/yabause/src/c68k/c68k_opB.inc deleted file mode 100644 index 84175c98a9..0000000000 --- a/yabause/src/c68k/c68k_opB.inc +++ /dev/null @@ -1,5970 +0,0 @@ -case 0xB200: -case 0xB400: -case 0xB600: -case 0xB800: -case 0xBA00: -case 0xBC00: -case 0xBE00: -case 0xB001: -case 0xB201: -case 0xB401: -case 0xB601: -case 0xB801: -case 0xBA01: -case 0xBC01: -case 0xBE01: -case 0xB002: -case 0xB202: -case 0xB402: -case 0xB602: -case 0xB802: -case 0xBA02: -case 0xBC02: -case 0xBE02: -case 0xB003: -case 0xB203: -case 0xB403: -case 0xB603: -case 0xB803: -case 0xBA03: -case 0xBC03: -case 0xBE03: -case 0xB004: -case 0xB204: -case 0xB404: -case 0xB604: -case 0xB804: -case 0xBA04: -case 0xBC04: -case 0xBE04: -case 0xB005: -case 0xB205: -case 0xB405: -case 0xB605: -case 0xB805: -case 0xBA05: -case 0xBC05: -case 0xBE05: -case 0xB006: -case 0xB206: -case 0xB406: -case 0xB606: -case 0xB806: -case 0xBA06: -case 0xBC06: -case 0xBE06: -case 0xB007: -case 0xB207: -case 0xB407: -case 0xB607: -case 0xB807: -case 0xBA07: -case 0xBC07: -case 0xBE07: - -// CMP -case 0xB000: -{ - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; -} -RET(4) -case 0xB208: -case 0xB408: -case 0xB608: -case 0xB808: -case 0xBA08: -case 0xBC08: -case 0xBE08: -case 0xB009: -case 0xB209: -case 0xB409: -case 0xB609: -case 0xB809: -case 0xBA09: -case 0xBC09: -case 0xBE09: -case 0xB00A: -case 0xB20A: -case 0xB40A: -case 0xB60A: -case 0xB80A: -case 0xBA0A: -case 0xBC0A: -case 0xBE0A: -case 0xB00B: -case 0xB20B: -case 0xB40B: -case 0xB60B: -case 0xB80B: -case 0xBA0B: -case 0xBC0B: -case 0xBE0B: -case 0xB00C: -case 0xB20C: -case 0xB40C: -case 0xB60C: -case 0xB80C: -case 0xBA0C: -case 0xBC0C: -case 0xBE0C: -case 0xB00D: -case 0xB20D: -case 0xB40D: -case 0xB60D: -case 0xB80D: -case 0xBA0D: -case 0xBC0D: -case 0xBE0D: -case 0xB00E: -case 0xB20E: -case 0xB40E: -case 0xB60E: -case 0xB80E: -case 0xBA0E: -case 0xBC0E: -case 0xBE0E: -case 0xB00F: -case 0xB20F: -case 0xB40F: -case 0xB60F: -case 0xB80F: -case 0xBA0F: -case 0xBC0F: -case 0xBE0F: - -// CMP -case 0xB008: -{ - u32 res; - pointer dst; - pointer src; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; -} -RET(4) -case 0xB210: -case 0xB410: -case 0xB610: -case 0xB810: -case 0xBA10: -case 0xBC10: -case 0xBE10: -case 0xB011: -case 0xB211: -case 0xB411: -case 0xB611: -case 0xB811: -case 0xBA11: -case 0xBC11: -case 0xBE11: -case 0xB012: -case 0xB212: -case 0xB412: -case 0xB612: -case 0xB812: -case 0xBA12: -case 0xBC12: -case 0xBE12: -case 0xB013: -case 0xB213: -case 0xB413: -case 0xB613: -case 0xB813: -case 0xBA13: -case 0xBC13: -case 0xBE13: -case 0xB014: -case 0xB214: -case 0xB414: -case 0xB614: -case 0xB814: -case 0xBA14: -case 0xBC14: -case 0xBE14: -case 0xB015: -case 0xB215: -case 0xB415: -case 0xB615: -case 0xB815: -case 0xBA15: -case 0xBC15: -case 0xBE15: -case 0xB016: -case 0xB216: -case 0xB416: -case 0xB616: -case 0xB816: -case 0xBA16: -case 0xBC16: -case 0xBE16: -case 0xB017: -case 0xB217: -case 0xB417: -case 0xB617: -case 0xB817: -case 0xBA17: -case 0xBC17: -case 0xBE17: - -// CMP -case 0xB010: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(8) -case 0xB218: -case 0xB418: -case 0xB618: -case 0xB818: -case 0xBA18: -case 0xBC18: -case 0xBE18: -case 0xB019: -case 0xB219: -case 0xB419: -case 0xB619: -case 0xB819: -case 0xBA19: -case 0xBC19: -case 0xBE19: -case 0xB01A: -case 0xB21A: -case 0xB41A: -case 0xB61A: -case 0xB81A: -case 0xBA1A: -case 0xBC1A: -case 0xBE1A: -case 0xB01B: -case 0xB21B: -case 0xB41B: -case 0xB61B: -case 0xB81B: -case 0xBA1B: -case 0xBC1B: -case 0xBE1B: -case 0xB01C: -case 0xB21C: -case 0xB41C: -case 0xB61C: -case 0xB81C: -case 0xBA1C: -case 0xBC1C: -case 0xBE1C: -case 0xB01D: -case 0xB21D: -case 0xB41D: -case 0xB61D: -case 0xB81D: -case 0xBA1D: -case 0xBC1D: -case 0xBE1D: -case 0xB01E: -case 0xB21E: -case 0xB41E: -case 0xB61E: -case 0xB81E: -case 0xBA1E: -case 0xBC1E: -case 0xBE1E: - -// CMP -case 0xB018: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(8) -case 0xB220: -case 0xB420: -case 0xB620: -case 0xB820: -case 0xBA20: -case 0xBC20: -case 0xBE20: -case 0xB021: -case 0xB221: -case 0xB421: -case 0xB621: -case 0xB821: -case 0xBA21: -case 0xBC21: -case 0xBE21: -case 0xB022: -case 0xB222: -case 0xB422: -case 0xB622: -case 0xB822: -case 0xBA22: -case 0xBC22: -case 0xBE22: -case 0xB023: -case 0xB223: -case 0xB423: -case 0xB623: -case 0xB823: -case 0xBA23: -case 0xBC23: -case 0xBE23: -case 0xB024: -case 0xB224: -case 0xB424: -case 0xB624: -case 0xB824: -case 0xBA24: -case 0xBC24: -case 0xBE24: -case 0xB025: -case 0xB225: -case 0xB425: -case 0xB625: -case 0xB825: -case 0xBA25: -case 0xBC25: -case 0xBE25: -case 0xB026: -case 0xB226: -case 0xB426: -case 0xB626: -case 0xB826: -case 0xBA26: -case 0xBC26: -case 0xBE26: - -// CMP -case 0xB020: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(10) -case 0xB228: -case 0xB428: -case 0xB628: -case 0xB828: -case 0xBA28: -case 0xBC28: -case 0xBE28: -case 0xB029: -case 0xB229: -case 0xB429: -case 0xB629: -case 0xB829: -case 0xBA29: -case 0xBC29: -case 0xBE29: -case 0xB02A: -case 0xB22A: -case 0xB42A: -case 0xB62A: -case 0xB82A: -case 0xBA2A: -case 0xBC2A: -case 0xBE2A: -case 0xB02B: -case 0xB22B: -case 0xB42B: -case 0xB62B: -case 0xB82B: -case 0xBA2B: -case 0xBC2B: -case 0xBE2B: -case 0xB02C: -case 0xB22C: -case 0xB42C: -case 0xB62C: -case 0xB82C: -case 0xBA2C: -case 0xBC2C: -case 0xBE2C: -case 0xB02D: -case 0xB22D: -case 0xB42D: -case 0xB62D: -case 0xB82D: -case 0xBA2D: -case 0xBC2D: -case 0xBE2D: -case 0xB02E: -case 0xB22E: -case 0xB42E: -case 0xB62E: -case 0xB82E: -case 0xBA2E: -case 0xBC2E: -case 0xBE2E: -case 0xB02F: -case 0xB22F: -case 0xB42F: -case 0xB62F: -case 0xB82F: -case 0xBA2F: -case 0xBC2F: -case 0xBE2F: - -// CMP -case 0xB028: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) -case 0xB230: -case 0xB430: -case 0xB630: -case 0xB830: -case 0xBA30: -case 0xBC30: -case 0xBE30: -case 0xB031: -case 0xB231: -case 0xB431: -case 0xB631: -case 0xB831: -case 0xBA31: -case 0xBC31: -case 0xBE31: -case 0xB032: -case 0xB232: -case 0xB432: -case 0xB632: -case 0xB832: -case 0xBA32: -case 0xBC32: -case 0xBE32: -case 0xB033: -case 0xB233: -case 0xB433: -case 0xB633: -case 0xB833: -case 0xBA33: -case 0xBC33: -case 0xBE33: -case 0xB034: -case 0xB234: -case 0xB434: -case 0xB634: -case 0xB834: -case 0xBA34: -case 0xBC34: -case 0xBE34: -case 0xB035: -case 0xB235: -case 0xB435: -case 0xB635: -case 0xB835: -case 0xBA35: -case 0xBC35: -case 0xBE35: -case 0xB036: -case 0xB236: -case 0xB436: -case 0xB636: -case 0xB836: -case 0xBA36: -case 0xBC36: -case 0xBE36: -case 0xB037: -case 0xB237: -case 0xB437: -case 0xB637: -case 0xB837: -case 0xBA37: -case 0xBC37: -case 0xBE37: - -// CMP -case 0xB030: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(14) -case 0xB238: -case 0xB438: -case 0xB638: -case 0xB838: -case 0xBA38: -case 0xBC38: -case 0xBE38: - -// CMP -case 0xB038: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) -case 0xB239: -case 0xB439: -case 0xB639: -case 0xB839: -case 0xBA39: -case 0xBC39: -case 0xBE39: - -// CMP -case 0xB039: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(16) -case 0xB23A: -case 0xB43A: -case 0xB63A: -case 0xB83A: -case 0xBA3A: -case 0xBC3A: -case 0xBE3A: - -// CMP -case 0xB03A: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) -case 0xB23B: -case 0xB43B: -case 0xB63B: -case 0xB83B: -case 0xBA3B: -case 0xBC3B: -case 0xBE3B: - -// CMP -case 0xB03B: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(14) -case 0xB23C: -case 0xB43C: -case 0xB63C: -case 0xB83C: -case 0xBA3C: -case 0xBC3C: -case 0xBE3C: - -// CMP -case 0xB03C: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; -} -RET(8) -case 0xB21F: -case 0xB41F: -case 0xB61F: -case 0xB81F: -case 0xBA1F: -case 0xBC1F: -case 0xBE1F: - -// CMP -case 0xB01F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(8) -case 0xB227: -case 0xB427: -case 0xB627: -case 0xB827: -case 0xBA27: -case 0xBC27: -case 0xBE27: - -// CMP -case 0xB027: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(10) -case 0xB240: -case 0xB440: -case 0xB640: -case 0xB840: -case 0xBA40: -case 0xBC40: -case 0xBE40: -case 0xB041: -case 0xB241: -case 0xB441: -case 0xB641: -case 0xB841: -case 0xBA41: -case 0xBC41: -case 0xBE41: -case 0xB042: -case 0xB242: -case 0xB442: -case 0xB642: -case 0xB842: -case 0xBA42: -case 0xBC42: -case 0xBE42: -case 0xB043: -case 0xB243: -case 0xB443: -case 0xB643: -case 0xB843: -case 0xBA43: -case 0xBC43: -case 0xBE43: -case 0xB044: -case 0xB244: -case 0xB444: -case 0xB644: -case 0xB844: -case 0xBA44: -case 0xBC44: -case 0xBE44: -case 0xB045: -case 0xB245: -case 0xB445: -case 0xB645: -case 0xB845: -case 0xBA45: -case 0xBC45: -case 0xBE45: -case 0xB046: -case 0xB246: -case 0xB446: -case 0xB646: -case 0xB846: -case 0xBA46: -case 0xBC46: -case 0xBE46: -case 0xB047: -case 0xB247: -case 0xB447: -case 0xB647: -case 0xB847: -case 0xBA47: -case 0xBC47: -case 0xBE47: - -// CMP -case 0xB040: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; -} -RET(4) -case 0xB248: -case 0xB448: -case 0xB648: -case 0xB848: -case 0xBA48: -case 0xBC48: -case 0xBE48: -case 0xB049: -case 0xB249: -case 0xB449: -case 0xB649: -case 0xB849: -case 0xBA49: -case 0xBC49: -case 0xBE49: -case 0xB04A: -case 0xB24A: -case 0xB44A: -case 0xB64A: -case 0xB84A: -case 0xBA4A: -case 0xBC4A: -case 0xBE4A: -case 0xB04B: -case 0xB24B: -case 0xB44B: -case 0xB64B: -case 0xB84B: -case 0xBA4B: -case 0xBC4B: -case 0xBE4B: -case 0xB04C: -case 0xB24C: -case 0xB44C: -case 0xB64C: -case 0xB84C: -case 0xBA4C: -case 0xBC4C: -case 0xBE4C: -case 0xB04D: -case 0xB24D: -case 0xB44D: -case 0xB64D: -case 0xB84D: -case 0xBA4D: -case 0xBC4D: -case 0xBE4D: -case 0xB04E: -case 0xB24E: -case 0xB44E: -case 0xB64E: -case 0xB84E: -case 0xBA4E: -case 0xBC4E: -case 0xBE4E: -case 0xB04F: -case 0xB24F: -case 0xB44F: -case 0xB64F: -case 0xB84F: -case 0xBA4F: -case 0xBC4F: -case 0xBE4F: - -// CMP -case 0xB048: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->A[(Opcode >> 0) & 7]; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; -} -RET(4) -case 0xB250: -case 0xB450: -case 0xB650: -case 0xB850: -case 0xBA50: -case 0xBC50: -case 0xBE50: -case 0xB051: -case 0xB251: -case 0xB451: -case 0xB651: -case 0xB851: -case 0xBA51: -case 0xBC51: -case 0xBE51: -case 0xB052: -case 0xB252: -case 0xB452: -case 0xB652: -case 0xB852: -case 0xBA52: -case 0xBC52: -case 0xBE52: -case 0xB053: -case 0xB253: -case 0xB453: -case 0xB653: -case 0xB853: -case 0xBA53: -case 0xBC53: -case 0xBE53: -case 0xB054: -case 0xB254: -case 0xB454: -case 0xB654: -case 0xB854: -case 0xBA54: -case 0xBC54: -case 0xBE54: -case 0xB055: -case 0xB255: -case 0xB455: -case 0xB655: -case 0xB855: -case 0xBA55: -case 0xBC55: -case 0xBE55: -case 0xB056: -case 0xB256: -case 0xB456: -case 0xB656: -case 0xB856: -case 0xBA56: -case 0xBC56: -case 0xBE56: -case 0xB057: -case 0xB257: -case 0xB457: -case 0xB657: -case 0xB857: -case 0xBA57: -case 0xBC57: -case 0xBE57: - -// CMP -case 0xB050: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(8) -case 0xB258: -case 0xB458: -case 0xB658: -case 0xB858: -case 0xBA58: -case 0xBC58: -case 0xBE58: -case 0xB059: -case 0xB259: -case 0xB459: -case 0xB659: -case 0xB859: -case 0xBA59: -case 0xBC59: -case 0xBE59: -case 0xB05A: -case 0xB25A: -case 0xB45A: -case 0xB65A: -case 0xB85A: -case 0xBA5A: -case 0xBC5A: -case 0xBE5A: -case 0xB05B: -case 0xB25B: -case 0xB45B: -case 0xB65B: -case 0xB85B: -case 0xBA5B: -case 0xBC5B: -case 0xBE5B: -case 0xB05C: -case 0xB25C: -case 0xB45C: -case 0xB65C: -case 0xB85C: -case 0xBA5C: -case 0xBC5C: -case 0xBE5C: -case 0xB05D: -case 0xB25D: -case 0xB45D: -case 0xB65D: -case 0xB85D: -case 0xBA5D: -case 0xBC5D: -case 0xBE5D: -case 0xB05E: -case 0xB25E: -case 0xB45E: -case 0xB65E: -case 0xB85E: -case 0xBA5E: -case 0xBC5E: -case 0xBE5E: - -// CMP -case 0xB058: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(8) -case 0xB260: -case 0xB460: -case 0xB660: -case 0xB860: -case 0xBA60: -case 0xBC60: -case 0xBE60: -case 0xB061: -case 0xB261: -case 0xB461: -case 0xB661: -case 0xB861: -case 0xBA61: -case 0xBC61: -case 0xBE61: -case 0xB062: -case 0xB262: -case 0xB462: -case 0xB662: -case 0xB862: -case 0xBA62: -case 0xBC62: -case 0xBE62: -case 0xB063: -case 0xB263: -case 0xB463: -case 0xB663: -case 0xB863: -case 0xBA63: -case 0xBC63: -case 0xBE63: -case 0xB064: -case 0xB264: -case 0xB464: -case 0xB664: -case 0xB864: -case 0xBA64: -case 0xBC64: -case 0xBE64: -case 0xB065: -case 0xB265: -case 0xB465: -case 0xB665: -case 0xB865: -case 0xBA65: -case 0xBC65: -case 0xBE65: -case 0xB066: -case 0xB266: -case 0xB466: -case 0xB666: -case 0xB866: -case 0xBA66: -case 0xBC66: -case 0xBE66: - -// CMP -case 0xB060: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(10) -case 0xB268: -case 0xB468: -case 0xB668: -case 0xB868: -case 0xBA68: -case 0xBC68: -case 0xBE68: -case 0xB069: -case 0xB269: -case 0xB469: -case 0xB669: -case 0xB869: -case 0xBA69: -case 0xBC69: -case 0xBE69: -case 0xB06A: -case 0xB26A: -case 0xB46A: -case 0xB66A: -case 0xB86A: -case 0xBA6A: -case 0xBC6A: -case 0xBE6A: -case 0xB06B: -case 0xB26B: -case 0xB46B: -case 0xB66B: -case 0xB86B: -case 0xBA6B: -case 0xBC6B: -case 0xBE6B: -case 0xB06C: -case 0xB26C: -case 0xB46C: -case 0xB66C: -case 0xB86C: -case 0xBA6C: -case 0xBC6C: -case 0xBE6C: -case 0xB06D: -case 0xB26D: -case 0xB46D: -case 0xB66D: -case 0xB86D: -case 0xBA6D: -case 0xBC6D: -case 0xBE6D: -case 0xB06E: -case 0xB26E: -case 0xB46E: -case 0xB66E: -case 0xB86E: -case 0xBA6E: -case 0xBC6E: -case 0xBE6E: -case 0xB06F: -case 0xB26F: -case 0xB46F: -case 0xB66F: -case 0xB86F: -case 0xBA6F: -case 0xBC6F: -case 0xBE6F: - -// CMP -case 0xB068: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) -case 0xB270: -case 0xB470: -case 0xB670: -case 0xB870: -case 0xBA70: -case 0xBC70: -case 0xBE70: -case 0xB071: -case 0xB271: -case 0xB471: -case 0xB671: -case 0xB871: -case 0xBA71: -case 0xBC71: -case 0xBE71: -case 0xB072: -case 0xB272: -case 0xB472: -case 0xB672: -case 0xB872: -case 0xBA72: -case 0xBC72: -case 0xBE72: -case 0xB073: -case 0xB273: -case 0xB473: -case 0xB673: -case 0xB873: -case 0xBA73: -case 0xBC73: -case 0xBE73: -case 0xB074: -case 0xB274: -case 0xB474: -case 0xB674: -case 0xB874: -case 0xBA74: -case 0xBC74: -case 0xBE74: -case 0xB075: -case 0xB275: -case 0xB475: -case 0xB675: -case 0xB875: -case 0xBA75: -case 0xBC75: -case 0xBE75: -case 0xB076: -case 0xB276: -case 0xB476: -case 0xB676: -case 0xB876: -case 0xBA76: -case 0xBC76: -case 0xBE76: -case 0xB077: -case 0xB277: -case 0xB477: -case 0xB677: -case 0xB877: -case 0xBA77: -case 0xBC77: -case 0xBE77: - -// CMP -case 0xB070: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(14) -case 0xB278: -case 0xB478: -case 0xB678: -case 0xB878: -case 0xBA78: -case 0xBC78: -case 0xBE78: - -// CMP -case 0xB078: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) -case 0xB279: -case 0xB479: -case 0xB679: -case 0xB879: -case 0xBA79: -case 0xBC79: -case 0xBE79: - -// CMP -case 0xB079: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(16) -case 0xB27A: -case 0xB47A: -case 0xB67A: -case 0xB87A: -case 0xBA7A: -case 0xBC7A: -case 0xBE7A: - -// CMP -case 0xB07A: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) -case 0xB27B: -case 0xB47B: -case 0xB67B: -case 0xB87B: -case 0xBA7B: -case 0xBC7B: -case 0xBE7B: - -// CMP -case 0xB07B: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(14) -case 0xB27C: -case 0xB47C: -case 0xB67C: -case 0xB87C: -case 0xBA7C: -case 0xBC7C: -case 0xBE7C: - -// CMP -case 0xB07C: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; -} -RET(8) -case 0xB25F: -case 0xB45F: -case 0xB65F: -case 0xB85F: -case 0xBA5F: -case 0xBC5F: -case 0xBE5F: - -// CMP -case 0xB05F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(8) -case 0xB267: -case 0xB467: -case 0xB667: -case 0xB867: -case 0xBA67: -case 0xBC67: -case 0xBE67: - -// CMP -case 0xB067: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(10) -case 0xB280: -case 0xB480: -case 0xB680: -case 0xB880: -case 0xBA80: -case 0xBC80: -case 0xBE80: -case 0xB081: -case 0xB281: -case 0xB481: -case 0xB681: -case 0xB881: -case 0xBA81: -case 0xBC81: -case 0xBE81: -case 0xB082: -case 0xB282: -case 0xB482: -case 0xB682: -case 0xB882: -case 0xBA82: -case 0xBC82: -case 0xBE82: -case 0xB083: -case 0xB283: -case 0xB483: -case 0xB683: -case 0xB883: -case 0xBA83: -case 0xBC83: -case 0xBE83: -case 0xB084: -case 0xB284: -case 0xB484: -case 0xB684: -case 0xB884: -case 0xBA84: -case 0xBC84: -case 0xBE84: -case 0xB085: -case 0xB285: -case 0xB485: -case 0xB685: -case 0xB885: -case 0xBA85: -case 0xBC85: -case 0xBE85: -case 0xB086: -case 0xB286: -case 0xB486: -case 0xB686: -case 0xB886: -case 0xBA86: -case 0xBC86: -case 0xBE86: -case 0xB087: -case 0xB287: -case 0xB487: -case 0xB687: -case 0xB887: -case 0xBA87: -case 0xBC87: -case 0xBE87: - -// CMP -case 0xB080: -{ - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(6) -case 0xB288: -case 0xB488: -case 0xB688: -case 0xB888: -case 0xBA88: -case 0xBC88: -case 0xBE88: -case 0xB089: -case 0xB289: -case 0xB489: -case 0xB689: -case 0xB889: -case 0xBA89: -case 0xBC89: -case 0xBE89: -case 0xB08A: -case 0xB28A: -case 0xB48A: -case 0xB68A: -case 0xB88A: -case 0xBA8A: -case 0xBC8A: -case 0xBE8A: -case 0xB08B: -case 0xB28B: -case 0xB48B: -case 0xB68B: -case 0xB88B: -case 0xBA8B: -case 0xBC8B: -case 0xBE8B: -case 0xB08C: -case 0xB28C: -case 0xB48C: -case 0xB68C: -case 0xB88C: -case 0xBA8C: -case 0xBC8C: -case 0xBE8C: -case 0xB08D: -case 0xB28D: -case 0xB48D: -case 0xB68D: -case 0xB88D: -case 0xBA8D: -case 0xBC8D: -case 0xBE8D: -case 0xB08E: -case 0xB28E: -case 0xB48E: -case 0xB68E: -case 0xB88E: -case 0xBA8E: -case 0xBC8E: -case 0xBE8E: -case 0xB08F: -case 0xB28F: -case 0xB48F: -case 0xB68F: -case 0xB88F: -case 0xBA8F: -case 0xBC8F: -case 0xBE8F: - -// CMP -case 0xB088: -{ - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(6) -case 0xB290: -case 0xB490: -case 0xB690: -case 0xB890: -case 0xBA90: -case 0xBC90: -case 0xBE90: -case 0xB091: -case 0xB291: -case 0xB491: -case 0xB691: -case 0xB891: -case 0xBA91: -case 0xBC91: -case 0xBE91: -case 0xB092: -case 0xB292: -case 0xB492: -case 0xB692: -case 0xB892: -case 0xBA92: -case 0xBC92: -case 0xBE92: -case 0xB093: -case 0xB293: -case 0xB493: -case 0xB693: -case 0xB893: -case 0xBA93: -case 0xBC93: -case 0xBE93: -case 0xB094: -case 0xB294: -case 0xB494: -case 0xB694: -case 0xB894: -case 0xBA94: -case 0xBC94: -case 0xBE94: -case 0xB095: -case 0xB295: -case 0xB495: -case 0xB695: -case 0xB895: -case 0xBA95: -case 0xBC95: -case 0xBE95: -case 0xB096: -case 0xB296: -case 0xB496: -case 0xB696: -case 0xB896: -case 0xBA96: -case 0xBC96: -case 0xBE96: -case 0xB097: -case 0xB297: -case 0xB497: -case 0xB697: -case 0xB897: -case 0xBA97: -case 0xBC97: -case 0xBE97: - -// CMP -case 0xB090: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) -case 0xB298: -case 0xB498: -case 0xB698: -case 0xB898: -case 0xBA98: -case 0xBC98: -case 0xBE98: -case 0xB099: -case 0xB299: -case 0xB499: -case 0xB699: -case 0xB899: -case 0xBA99: -case 0xBC99: -case 0xBE99: -case 0xB09A: -case 0xB29A: -case 0xB49A: -case 0xB69A: -case 0xB89A: -case 0xBA9A: -case 0xBC9A: -case 0xBE9A: -case 0xB09B: -case 0xB29B: -case 0xB49B: -case 0xB69B: -case 0xB89B: -case 0xBA9B: -case 0xBC9B: -case 0xBE9B: -case 0xB09C: -case 0xB29C: -case 0xB49C: -case 0xB69C: -case 0xB89C: -case 0xBA9C: -case 0xBC9C: -case 0xBE9C: -case 0xB09D: -case 0xB29D: -case 0xB49D: -case 0xB69D: -case 0xB89D: -case 0xBA9D: -case 0xBC9D: -case 0xBE9D: -case 0xB09E: -case 0xB29E: -case 0xB49E: -case 0xB69E: -case 0xB89E: -case 0xBA9E: -case 0xBC9E: -case 0xBE9E: - -// CMP -case 0xB098: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) -case 0xB2A0: -case 0xB4A0: -case 0xB6A0: -case 0xB8A0: -case 0xBAA0: -case 0xBCA0: -case 0xBEA0: -case 0xB0A1: -case 0xB2A1: -case 0xB4A1: -case 0xB6A1: -case 0xB8A1: -case 0xBAA1: -case 0xBCA1: -case 0xBEA1: -case 0xB0A2: -case 0xB2A2: -case 0xB4A2: -case 0xB6A2: -case 0xB8A2: -case 0xBAA2: -case 0xBCA2: -case 0xBEA2: -case 0xB0A3: -case 0xB2A3: -case 0xB4A3: -case 0xB6A3: -case 0xB8A3: -case 0xBAA3: -case 0xBCA3: -case 0xBEA3: -case 0xB0A4: -case 0xB2A4: -case 0xB4A4: -case 0xB6A4: -case 0xB8A4: -case 0xBAA4: -case 0xBCA4: -case 0xBEA4: -case 0xB0A5: -case 0xB2A5: -case 0xB4A5: -case 0xB6A5: -case 0xB8A5: -case 0xBAA5: -case 0xBCA5: -case 0xBEA5: -case 0xB0A6: -case 0xB2A6: -case 0xB4A6: -case 0xB6A6: -case 0xB8A6: -case 0xBAA6: -case 0xBCA6: -case 0xBEA6: - -// CMP -case 0xB0A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(18) -case 0xB2A8: -case 0xB4A8: -case 0xB6A8: -case 0xB8A8: -case 0xBAA8: -case 0xBCA8: -case 0xBEA8: -case 0xB0A9: -case 0xB2A9: -case 0xB4A9: -case 0xB6A9: -case 0xB8A9: -case 0xBAA9: -case 0xBCA9: -case 0xBEA9: -case 0xB0AA: -case 0xB2AA: -case 0xB4AA: -case 0xB6AA: -case 0xB8AA: -case 0xBAAA: -case 0xBCAA: -case 0xBEAA: -case 0xB0AB: -case 0xB2AB: -case 0xB4AB: -case 0xB6AB: -case 0xB8AB: -case 0xBAAB: -case 0xBCAB: -case 0xBEAB: -case 0xB0AC: -case 0xB2AC: -case 0xB4AC: -case 0xB6AC: -case 0xB8AC: -case 0xBAAC: -case 0xBCAC: -case 0xBEAC: -case 0xB0AD: -case 0xB2AD: -case 0xB4AD: -case 0xB6AD: -case 0xB8AD: -case 0xBAAD: -case 0xBCAD: -case 0xBEAD: -case 0xB0AE: -case 0xB2AE: -case 0xB4AE: -case 0xB6AE: -case 0xB8AE: -case 0xBAAE: -case 0xBCAE: -case 0xBEAE: -case 0xB0AF: -case 0xB2AF: -case 0xB4AF: -case 0xB6AF: -case 0xB8AF: -case 0xBAAF: -case 0xBCAF: -case 0xBEAF: - -// CMP -case 0xB0A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0xB2B0: -case 0xB4B0: -case 0xB6B0: -case 0xB8B0: -case 0xBAB0: -case 0xBCB0: -case 0xBEB0: -case 0xB0B1: -case 0xB2B1: -case 0xB4B1: -case 0xB6B1: -case 0xB8B1: -case 0xBAB1: -case 0xBCB1: -case 0xBEB1: -case 0xB0B2: -case 0xB2B2: -case 0xB4B2: -case 0xB6B2: -case 0xB8B2: -case 0xBAB2: -case 0xBCB2: -case 0xBEB2: -case 0xB0B3: -case 0xB2B3: -case 0xB4B3: -case 0xB6B3: -case 0xB8B3: -case 0xBAB3: -case 0xBCB3: -case 0xBEB3: -case 0xB0B4: -case 0xB2B4: -case 0xB4B4: -case 0xB6B4: -case 0xB8B4: -case 0xBAB4: -case 0xBCB4: -case 0xBEB4: -case 0xB0B5: -case 0xB2B5: -case 0xB4B5: -case 0xB6B5: -case 0xB8B5: -case 0xBAB5: -case 0xBCB5: -case 0xBEB5: -case 0xB0B6: -case 0xB2B6: -case 0xB4B6: -case 0xB6B6: -case 0xB8B6: -case 0xBAB6: -case 0xBCB6: -case 0xBEB6: -case 0xB0B7: -case 0xB2B7: -case 0xB4B7: -case 0xB6B7: -case 0xB8B7: -case 0xBAB7: -case 0xBCB7: -case 0xBEB7: - -// CMP -case 0xB0B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(22) -case 0xB2B8: -case 0xB4B8: -case 0xB6B8: -case 0xB8B8: -case 0xBAB8: -case 0xBCB8: -case 0xBEB8: - -// CMP -case 0xB0B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0xB2B9: -case 0xB4B9: -case 0xB6B9: -case 0xB8B9: -case 0xBAB9: -case 0xBCB9: -case 0xBEB9: - -// CMP -case 0xB0B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(24) -case 0xB2BA: -case 0xB4BA: -case 0xB6BA: -case 0xB8BA: -case 0xBABA: -case 0xBCBA: -case 0xBEBA: - -// CMP -case 0xB0BA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0xB2BB: -case 0xB4BB: -case 0xB6BB: -case 0xB8BB: -case 0xBABB: -case 0xBCBB: -case 0xBEBB: - -// CMP -case 0xB0BB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(22) -case 0xB2BC: -case 0xB4BC: -case 0xB6BC: -case 0xB8BC: -case 0xBABC: -case 0xBCBC: -case 0xBEBC: - -// CMP -case 0xB0BC: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(14) -case 0xB29F: -case 0xB49F: -case 0xB69F: -case 0xB89F: -case 0xBA9F: -case 0xBC9F: -case 0xBE9F: - -// CMP -case 0xB09F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) -case 0xB2A7: -case 0xB4A7: -case 0xB6A7: -case 0xB8A7: -case 0xBAA7: -case 0xBCA7: -case 0xBEA7: - -// CMP -case 0xB0A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(18) -case 0xB308: -case 0xB508: -case 0xB708: -case 0xB908: -case 0xBB08: -case 0xBD08: -case 0xB109: -case 0xB309: -case 0xB509: -case 0xB709: -case 0xB909: -case 0xBB09: -case 0xBD09: -case 0xB10A: -case 0xB30A: -case 0xB50A: -case 0xB70A: -case 0xB90A: -case 0xBB0A: -case 0xBD0A: -case 0xB10B: -case 0xB30B: -case 0xB50B: -case 0xB70B: -case 0xB90B: -case 0xBB0B: -case 0xBD0B: -case 0xB10C: -case 0xB30C: -case 0xB50C: -case 0xB70C: -case 0xB90C: -case 0xBB0C: -case 0xBD0C: -case 0xB10D: -case 0xB30D: -case 0xB50D: -case 0xB70D: -case 0xB90D: -case 0xBB0D: -case 0xBD0D: -case 0xB10E: -case 0xB30E: -case 0xB50E: -case 0xB70E: -case 0xB90E: -case 0xBB0E: -case 0xBD0E: - -// CMPM -case 0xB108: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) -case 0xB348: -case 0xB548: -case 0xB748: -case 0xB948: -case 0xBB48: -case 0xBD48: -case 0xB149: -case 0xB349: -case 0xB549: -case 0xB749: -case 0xB949: -case 0xBB49: -case 0xBD49: -case 0xB14A: -case 0xB34A: -case 0xB54A: -case 0xB74A: -case 0xB94A: -case 0xBB4A: -case 0xBD4A: -case 0xB14B: -case 0xB34B: -case 0xB54B: -case 0xB74B: -case 0xB94B: -case 0xBB4B: -case 0xBD4B: -case 0xB14C: -case 0xB34C: -case 0xB54C: -case 0xB74C: -case 0xB94C: -case 0xBB4C: -case 0xBD4C: -case 0xB14D: -case 0xB34D: -case 0xB54D: -case 0xB74D: -case 0xB94D: -case 0xBB4D: -case 0xBD4D: -case 0xB14E: -case 0xB34E: -case 0xB54E: -case 0xB74E: -case 0xB94E: -case 0xBB4E: -case 0xBD4E: - -// CMPM -case 0xB148: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) -case 0xB388: -case 0xB588: -case 0xB788: -case 0xB988: -case 0xBB88: -case 0xBD88: -case 0xB189: -case 0xB389: -case 0xB589: -case 0xB789: -case 0xB989: -case 0xBB89: -case 0xBD89: -case 0xB18A: -case 0xB38A: -case 0xB58A: -case 0xB78A: -case 0xB98A: -case 0xBB8A: -case 0xBD8A: -case 0xB18B: -case 0xB38B: -case 0xB58B: -case 0xB78B: -case 0xB98B: -case 0xBB8B: -case 0xBD8B: -case 0xB18C: -case 0xB38C: -case 0xB58C: -case 0xB78C: -case 0xB98C: -case 0xBB8C: -case 0xBD8C: -case 0xB18D: -case 0xB38D: -case 0xB58D: -case 0xB78D: -case 0xB98D: -case 0xBB8D: -case 0xBD8D: -case 0xB18E: -case 0xB38E: -case 0xB58E: -case 0xB78E: -case 0xB98E: -case 0xBB8E: -case 0xBD8E: - -// CMPM -case 0xB188: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0xB30F: -case 0xB50F: -case 0xB70F: -case 0xB90F: -case 0xBB0F: -case 0xBD0F: - -// CMP7M -case 0xB10F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 1; - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) -case 0xB34F: -case 0xB54F: -case 0xB74F: -case 0xB94F: -case 0xBB4F: -case 0xBD4F: - -// CMP7M -case 0xB14F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 2; - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) -case 0xB38F: -case 0xB58F: -case 0xB78F: -case 0xB98F: -case 0xBB8F: -case 0xBD8F: - -// CMP7M -case 0xB18F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] += 4; - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0xBF09: -case 0xBF0A: -case 0xBF0B: -case 0xBF0C: -case 0xBF0D: -case 0xBF0E: - -// CMPM7 -case 0xBF08: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7]; - CPU->A[7] += 2; - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) -case 0xBF49: -case 0xBF4A: -case 0xBF4B: -case 0xBF4C: -case 0xBF4D: -case 0xBF4E: - -// CMPM7 -case 0xBF48: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[7]; - CPU->A[7] += 2; - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) -case 0xBF89: -case 0xBF8A: -case 0xBF8B: -case 0xBF8C: -case 0xBF8D: -case 0xBF8E: - -// CMPM7 -case 0xBF88: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[7]; - CPU->A[7] += 4; - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) - -// CMP7M7 -case 0xBF0F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7]; - CPU->A[7] += 2; - READ_BYTE_F(adr, dst) - res = dst - src; - CPU->flag_N = CPU->flag_C = res; - CPU->flag_V = (src ^ dst) & (res ^ dst); - CPU->flag_notZ = res & 0xFF; - POST_IO -} -RET(12) - -// CMP7M7 -case 0xBF4F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[7]; - CPU->A[7] += 2; - READ_WORD_F(adr, dst) - res = dst - src; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8; - CPU->flag_N = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - POST_IO -} -RET(12) - -// CMP7M7 -case 0xBF8F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[7]; - CPU->A[7] += 4; - READ_LONG_F(adr, dst) - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0xB300: -case 0xB500: -case 0xB700: -case 0xB900: -case 0xBB00: -case 0xBD00: -case 0xBF00: -case 0xB101: -case 0xB301: -case 0xB501: -case 0xB701: -case 0xB901: -case 0xBB01: -case 0xBD01: -case 0xBF01: -case 0xB102: -case 0xB302: -case 0xB502: -case 0xB702: -case 0xB902: -case 0xBB02: -case 0xBD02: -case 0xBF02: -case 0xB103: -case 0xB303: -case 0xB503: -case 0xB703: -case 0xB903: -case 0xBB03: -case 0xBD03: -case 0xBF03: -case 0xB104: -case 0xB304: -case 0xB504: -case 0xB704: -case 0xB904: -case 0xBB04: -case 0xBD04: -case 0xBF04: -case 0xB105: -case 0xB305: -case 0xB505: -case 0xB705: -case 0xB905: -case 0xBB05: -case 0xBD05: -case 0xBF05: -case 0xB106: -case 0xB306: -case 0xB506: -case 0xB706: -case 0xB906: -case 0xBB06: -case 0xBD06: -case 0xBF06: -case 0xB107: -case 0xB307: -case 0xB507: -case 0xB707: -case 0xB907: -case 0xBB07: -case 0xBD07: -case 0xBF07: - -// EORDa -case 0xB100: -{ - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - res = (u8)CPU->D[(Opcode >> 0) & 7]; - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0xB310: -case 0xB510: -case 0xB710: -case 0xB910: -case 0xBB10: -case 0xBD10: -case 0xBF10: -case 0xB111: -case 0xB311: -case 0xB511: -case 0xB711: -case 0xB911: -case 0xBB11: -case 0xBD11: -case 0xBF11: -case 0xB112: -case 0xB312: -case 0xB512: -case 0xB712: -case 0xB912: -case 0xBB12: -case 0xBD12: -case 0xBF12: -case 0xB113: -case 0xB313: -case 0xB513: -case 0xB713: -case 0xB913: -case 0xBB13: -case 0xBD13: -case 0xBF13: -case 0xB114: -case 0xB314: -case 0xB514: -case 0xB714: -case 0xB914: -case 0xBB14: -case 0xBD14: -case 0xBF14: -case 0xB115: -case 0xB315: -case 0xB515: -case 0xB715: -case 0xB915: -case 0xBB15: -case 0xBD15: -case 0xBF15: -case 0xB116: -case 0xB316: -case 0xB516: -case 0xB716: -case 0xB916: -case 0xBB16: -case 0xBD16: -case 0xBF16: -case 0xB117: -case 0xB317: -case 0xB517: -case 0xB717: -case 0xB917: -case 0xBB17: -case 0xBD17: -case 0xBF17: - -// EORDa -case 0xB110: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xB318: -case 0xB518: -case 0xB718: -case 0xB918: -case 0xBB18: -case 0xBD18: -case 0xBF18: -case 0xB119: -case 0xB319: -case 0xB519: -case 0xB719: -case 0xB919: -case 0xBB19: -case 0xBD19: -case 0xBF19: -case 0xB11A: -case 0xB31A: -case 0xB51A: -case 0xB71A: -case 0xB91A: -case 0xBB1A: -case 0xBD1A: -case 0xBF1A: -case 0xB11B: -case 0xB31B: -case 0xB51B: -case 0xB71B: -case 0xB91B: -case 0xBB1B: -case 0xBD1B: -case 0xBF1B: -case 0xB11C: -case 0xB31C: -case 0xB51C: -case 0xB71C: -case 0xB91C: -case 0xBB1C: -case 0xBD1C: -case 0xBF1C: -case 0xB11D: -case 0xB31D: -case 0xB51D: -case 0xB71D: -case 0xB91D: -case 0xBB1D: -case 0xBD1D: -case 0xBF1D: -case 0xB11E: -case 0xB31E: -case 0xB51E: -case 0xB71E: -case 0xB91E: -case 0xBB1E: -case 0xBD1E: -case 0xBF1E: - -// EORDa -case 0xB118: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xB320: -case 0xB520: -case 0xB720: -case 0xB920: -case 0xBB20: -case 0xBD20: -case 0xBF20: -case 0xB121: -case 0xB321: -case 0xB521: -case 0xB721: -case 0xB921: -case 0xBB21: -case 0xBD21: -case 0xBF21: -case 0xB122: -case 0xB322: -case 0xB522: -case 0xB722: -case 0xB922: -case 0xBB22: -case 0xBD22: -case 0xBF22: -case 0xB123: -case 0xB323: -case 0xB523: -case 0xB723: -case 0xB923: -case 0xBB23: -case 0xBD23: -case 0xBF23: -case 0xB124: -case 0xB324: -case 0xB524: -case 0xB724: -case 0xB924: -case 0xBB24: -case 0xBD24: -case 0xBF24: -case 0xB125: -case 0xB325: -case 0xB525: -case 0xB725: -case 0xB925: -case 0xBB25: -case 0xBD25: -case 0xBF25: -case 0xB126: -case 0xB326: -case 0xB526: -case 0xB726: -case 0xB926: -case 0xBB26: -case 0xBD26: -case 0xBF26: - -// EORDa -case 0xB120: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0xB328: -case 0xB528: -case 0xB728: -case 0xB928: -case 0xBB28: -case 0xBD28: -case 0xBF28: -case 0xB129: -case 0xB329: -case 0xB529: -case 0xB729: -case 0xB929: -case 0xBB29: -case 0xBD29: -case 0xBF29: -case 0xB12A: -case 0xB32A: -case 0xB52A: -case 0xB72A: -case 0xB92A: -case 0xBB2A: -case 0xBD2A: -case 0xBF2A: -case 0xB12B: -case 0xB32B: -case 0xB52B: -case 0xB72B: -case 0xB92B: -case 0xBB2B: -case 0xBD2B: -case 0xBF2B: -case 0xB12C: -case 0xB32C: -case 0xB52C: -case 0xB72C: -case 0xB92C: -case 0xBB2C: -case 0xBD2C: -case 0xBF2C: -case 0xB12D: -case 0xB32D: -case 0xB52D: -case 0xB72D: -case 0xB92D: -case 0xBB2D: -case 0xBD2D: -case 0xBF2D: -case 0xB12E: -case 0xB32E: -case 0xB52E: -case 0xB72E: -case 0xB92E: -case 0xBB2E: -case 0xBD2E: -case 0xBF2E: -case 0xB12F: -case 0xB32F: -case 0xB52F: -case 0xB72F: -case 0xB92F: -case 0xBB2F: -case 0xBD2F: -case 0xBF2F: - -// EORDa -case 0xB128: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0xB330: -case 0xB530: -case 0xB730: -case 0xB930: -case 0xBB30: -case 0xBD30: -case 0xBF30: -case 0xB131: -case 0xB331: -case 0xB531: -case 0xB731: -case 0xB931: -case 0xBB31: -case 0xBD31: -case 0xBF31: -case 0xB132: -case 0xB332: -case 0xB532: -case 0xB732: -case 0xB932: -case 0xBB32: -case 0xBD32: -case 0xBF32: -case 0xB133: -case 0xB333: -case 0xB533: -case 0xB733: -case 0xB933: -case 0xBB33: -case 0xBD33: -case 0xBF33: -case 0xB134: -case 0xB334: -case 0xB534: -case 0xB734: -case 0xB934: -case 0xBB34: -case 0xBD34: -case 0xBF34: -case 0xB135: -case 0xB335: -case 0xB535: -case 0xB735: -case 0xB935: -case 0xBB35: -case 0xBD35: -case 0xBF35: -case 0xB136: -case 0xB336: -case 0xB536: -case 0xB736: -case 0xB936: -case 0xBB36: -case 0xBD36: -case 0xBF36: -case 0xB137: -case 0xB337: -case 0xB537: -case 0xB737: -case 0xB937: -case 0xBB37: -case 0xBD37: -case 0xBF37: - -// EORDa -case 0xB130: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xB338: -case 0xB538: -case 0xB738: -case 0xB938: -case 0xBB38: -case 0xBD38: -case 0xBF38: - -// EORDa -case 0xB138: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0xB339: -case 0xB539: -case 0xB739: -case 0xB939: -case 0xBB39: -case 0xBD39: -case 0xBF39: - -// EORDa -case 0xB139: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0xB31F: -case 0xB51F: -case 0xB71F: -case 0xB91F: -case 0xBB1F: -case 0xBD1F: -case 0xBF1F: - -// EORDa -case 0xB11F: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xB327: -case 0xB527: -case 0xB727: -case 0xB927: -case 0xBB27: -case 0xBD27: -case 0xBF27: - -// EORDa -case 0xB127: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0xB340: -case 0xB540: -case 0xB740: -case 0xB940: -case 0xBB40: -case 0xBD40: -case 0xBF40: -case 0xB141: -case 0xB341: -case 0xB541: -case 0xB741: -case 0xB941: -case 0xBB41: -case 0xBD41: -case 0xBF41: -case 0xB142: -case 0xB342: -case 0xB542: -case 0xB742: -case 0xB942: -case 0xBB42: -case 0xBD42: -case 0xBF42: -case 0xB143: -case 0xB343: -case 0xB543: -case 0xB743: -case 0xB943: -case 0xBB43: -case 0xBD43: -case 0xBF43: -case 0xB144: -case 0xB344: -case 0xB544: -case 0xB744: -case 0xB944: -case 0xBB44: -case 0xBD44: -case 0xBF44: -case 0xB145: -case 0xB345: -case 0xB545: -case 0xB745: -case 0xB945: -case 0xBB45: -case 0xBD45: -case 0xBF45: -case 0xB146: -case 0xB346: -case 0xB546: -case 0xB746: -case 0xB946: -case 0xBB46: -case 0xBD46: -case 0xBF46: -case 0xB147: -case 0xB347: -case 0xB547: -case 0xB747: -case 0xB947: -case 0xBB47: -case 0xBD47: -case 0xBF47: - -// EORDa -case 0xB140: -{ - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - res = (u16)CPU->D[(Opcode >> 0) & 7]; - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(4) -case 0xB350: -case 0xB550: -case 0xB750: -case 0xB950: -case 0xBB50: -case 0xBD50: -case 0xBF50: -case 0xB151: -case 0xB351: -case 0xB551: -case 0xB751: -case 0xB951: -case 0xBB51: -case 0xBD51: -case 0xBF51: -case 0xB152: -case 0xB352: -case 0xB552: -case 0xB752: -case 0xB952: -case 0xBB52: -case 0xBD52: -case 0xBF52: -case 0xB153: -case 0xB353: -case 0xB553: -case 0xB753: -case 0xB953: -case 0xBB53: -case 0xBD53: -case 0xBF53: -case 0xB154: -case 0xB354: -case 0xB554: -case 0xB754: -case 0xB954: -case 0xBB54: -case 0xBD54: -case 0xBF54: -case 0xB155: -case 0xB355: -case 0xB555: -case 0xB755: -case 0xB955: -case 0xBB55: -case 0xBD55: -case 0xBF55: -case 0xB156: -case 0xB356: -case 0xB556: -case 0xB756: -case 0xB956: -case 0xBB56: -case 0xBD56: -case 0xBF56: -case 0xB157: -case 0xB357: -case 0xB557: -case 0xB757: -case 0xB957: -case 0xBB57: -case 0xBD57: -case 0xBF57: - -// EORDa -case 0xB150: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xB358: -case 0xB558: -case 0xB758: -case 0xB958: -case 0xBB58: -case 0xBD58: -case 0xBF58: -case 0xB159: -case 0xB359: -case 0xB559: -case 0xB759: -case 0xB959: -case 0xBB59: -case 0xBD59: -case 0xBF59: -case 0xB15A: -case 0xB35A: -case 0xB55A: -case 0xB75A: -case 0xB95A: -case 0xBB5A: -case 0xBD5A: -case 0xBF5A: -case 0xB15B: -case 0xB35B: -case 0xB55B: -case 0xB75B: -case 0xB95B: -case 0xBB5B: -case 0xBD5B: -case 0xBF5B: -case 0xB15C: -case 0xB35C: -case 0xB55C: -case 0xB75C: -case 0xB95C: -case 0xBB5C: -case 0xBD5C: -case 0xBF5C: -case 0xB15D: -case 0xB35D: -case 0xB55D: -case 0xB75D: -case 0xB95D: -case 0xBB5D: -case 0xBD5D: -case 0xBF5D: -case 0xB15E: -case 0xB35E: -case 0xB55E: -case 0xB75E: -case 0xB95E: -case 0xBB5E: -case 0xBD5E: -case 0xBF5E: - -// EORDa -case 0xB158: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xB360: -case 0xB560: -case 0xB760: -case 0xB960: -case 0xBB60: -case 0xBD60: -case 0xBF60: -case 0xB161: -case 0xB361: -case 0xB561: -case 0xB761: -case 0xB961: -case 0xBB61: -case 0xBD61: -case 0xBF61: -case 0xB162: -case 0xB362: -case 0xB562: -case 0xB762: -case 0xB962: -case 0xBB62: -case 0xBD62: -case 0xBF62: -case 0xB163: -case 0xB363: -case 0xB563: -case 0xB763: -case 0xB963: -case 0xBB63: -case 0xBD63: -case 0xBF63: -case 0xB164: -case 0xB364: -case 0xB564: -case 0xB764: -case 0xB964: -case 0xBB64: -case 0xBD64: -case 0xBF64: -case 0xB165: -case 0xB365: -case 0xB565: -case 0xB765: -case 0xB965: -case 0xBB65: -case 0xBD65: -case 0xBF65: -case 0xB166: -case 0xB366: -case 0xB566: -case 0xB766: -case 0xB966: -case 0xBB66: -case 0xBD66: -case 0xBF66: - -// EORDa -case 0xB160: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xB368: -case 0xB568: -case 0xB768: -case 0xB968: -case 0xBB68: -case 0xBD68: -case 0xBF68: -case 0xB169: -case 0xB369: -case 0xB569: -case 0xB769: -case 0xB969: -case 0xBB69: -case 0xBD69: -case 0xBF69: -case 0xB16A: -case 0xB36A: -case 0xB56A: -case 0xB76A: -case 0xB96A: -case 0xBB6A: -case 0xBD6A: -case 0xBF6A: -case 0xB16B: -case 0xB36B: -case 0xB56B: -case 0xB76B: -case 0xB96B: -case 0xBB6B: -case 0xBD6B: -case 0xBF6B: -case 0xB16C: -case 0xB36C: -case 0xB56C: -case 0xB76C: -case 0xB96C: -case 0xBB6C: -case 0xBD6C: -case 0xBF6C: -case 0xB16D: -case 0xB36D: -case 0xB56D: -case 0xB76D: -case 0xB96D: -case 0xBB6D: -case 0xBD6D: -case 0xBF6D: -case 0xB16E: -case 0xB36E: -case 0xB56E: -case 0xB76E: -case 0xB96E: -case 0xBB6E: -case 0xBD6E: -case 0xBF6E: -case 0xB16F: -case 0xB36F: -case 0xB56F: -case 0xB76F: -case 0xB96F: -case 0xBB6F: -case 0xBD6F: -case 0xBF6F: - -// EORDa -case 0xB168: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xB370: -case 0xB570: -case 0xB770: -case 0xB970: -case 0xBB70: -case 0xBD70: -case 0xBF70: -case 0xB171: -case 0xB371: -case 0xB571: -case 0xB771: -case 0xB971: -case 0xBB71: -case 0xBD71: -case 0xBF71: -case 0xB172: -case 0xB372: -case 0xB572: -case 0xB772: -case 0xB972: -case 0xBB72: -case 0xBD72: -case 0xBF72: -case 0xB173: -case 0xB373: -case 0xB573: -case 0xB773: -case 0xB973: -case 0xBB73: -case 0xBD73: -case 0xBF73: -case 0xB174: -case 0xB374: -case 0xB574: -case 0xB774: -case 0xB974: -case 0xBB74: -case 0xBD74: -case 0xBF74: -case 0xB175: -case 0xB375: -case 0xB575: -case 0xB775: -case 0xB975: -case 0xBB75: -case 0xBD75: -case 0xBF75: -case 0xB176: -case 0xB376: -case 0xB576: -case 0xB776: -case 0xB976: -case 0xBB76: -case 0xBD76: -case 0xBF76: -case 0xB177: -case 0xB377: -case 0xB577: -case 0xB777: -case 0xB977: -case 0xBB77: -case 0xBD77: -case 0xBF77: - -// EORDa -case 0xB170: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0xB378: -case 0xB578: -case 0xB778: -case 0xB978: -case 0xBB78: -case 0xBD78: -case 0xBF78: - -// EORDa -case 0xB178: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xB379: -case 0xB579: -case 0xB779: -case 0xB979: -case 0xBB79: -case 0xBD79: -case 0xBF79: - -// EORDa -case 0xB179: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0xB35F: -case 0xB55F: -case 0xB75F: -case 0xB95F: -case 0xBB5F: -case 0xBD5F: -case 0xBF5F: - -// EORDa -case 0xB15F: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xB367: -case 0xB567: -case 0xB767: -case 0xB967: -case 0xBB67: -case 0xBD67: -case 0xBF67: - -// EORDa -case 0xB167: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xB380: -case 0xB580: -case 0xB780: -case 0xB980: -case 0xBB80: -case 0xBD80: -case 0xBF80: -case 0xB181: -case 0xB381: -case 0xB581: -case 0xB781: -case 0xB981: -case 0xBB81: -case 0xBD81: -case 0xBF81: -case 0xB182: -case 0xB382: -case 0xB582: -case 0xB782: -case 0xB982: -case 0xBB82: -case 0xBD82: -case 0xBF82: -case 0xB183: -case 0xB383: -case 0xB583: -case 0xB783: -case 0xB983: -case 0xBB83: -case 0xBD83: -case 0xBF83: -case 0xB184: -case 0xB384: -case 0xB584: -case 0xB784: -case 0xB984: -case 0xBB84: -case 0xBD84: -case 0xBF84: -case 0xB185: -case 0xB385: -case 0xB585: -case 0xB785: -case 0xB985: -case 0xBB85: -case 0xBD85: -case 0xBF85: -case 0xB186: -case 0xB386: -case 0xB586: -case 0xB786: -case 0xB986: -case 0xBB86: -case 0xBD86: -case 0xBF86: -case 0xB187: -case 0xB387: -case 0xB587: -case 0xB787: -case 0xB987: -case 0xBB87: -case 0xBD87: -case 0xBF87: - -// EORDa -case 0xB180: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0xB390: -case 0xB590: -case 0xB790: -case 0xB990: -case 0xBB90: -case 0xBD90: -case 0xBF90: -case 0xB191: -case 0xB391: -case 0xB591: -case 0xB791: -case 0xB991: -case 0xBB91: -case 0xBD91: -case 0xBF91: -case 0xB192: -case 0xB392: -case 0xB592: -case 0xB792: -case 0xB992: -case 0xBB92: -case 0xBD92: -case 0xBF92: -case 0xB193: -case 0xB393: -case 0xB593: -case 0xB793: -case 0xB993: -case 0xBB93: -case 0xBD93: -case 0xBF93: -case 0xB194: -case 0xB394: -case 0xB594: -case 0xB794: -case 0xB994: -case 0xBB94: -case 0xBD94: -case 0xBF94: -case 0xB195: -case 0xB395: -case 0xB595: -case 0xB795: -case 0xB995: -case 0xBB95: -case 0xBD95: -case 0xBF95: -case 0xB196: -case 0xB396: -case 0xB596: -case 0xB796: -case 0xB996: -case 0xBB96: -case 0xBD96: -case 0xBF96: -case 0xB197: -case 0xB397: -case 0xB597: -case 0xB797: -case 0xB997: -case 0xBB97: -case 0xBD97: -case 0xBF97: - -// EORDa -case 0xB190: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xB398: -case 0xB598: -case 0xB798: -case 0xB998: -case 0xBB98: -case 0xBD98: -case 0xBF98: -case 0xB199: -case 0xB399: -case 0xB599: -case 0xB799: -case 0xB999: -case 0xBB99: -case 0xBD99: -case 0xBF99: -case 0xB19A: -case 0xB39A: -case 0xB59A: -case 0xB79A: -case 0xB99A: -case 0xBB9A: -case 0xBD9A: -case 0xBF9A: -case 0xB19B: -case 0xB39B: -case 0xB59B: -case 0xB79B: -case 0xB99B: -case 0xBB9B: -case 0xBD9B: -case 0xBF9B: -case 0xB19C: -case 0xB39C: -case 0xB59C: -case 0xB79C: -case 0xB99C: -case 0xBB9C: -case 0xBD9C: -case 0xBF9C: -case 0xB19D: -case 0xB39D: -case 0xB59D: -case 0xB79D: -case 0xB99D: -case 0xBB9D: -case 0xBD9D: -case 0xBF9D: -case 0xB19E: -case 0xB39E: -case 0xB59E: -case 0xB79E: -case 0xB99E: -case 0xBB9E: -case 0xBD9E: -case 0xBF9E: - -// EORDa -case 0xB198: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xB3A0: -case 0xB5A0: -case 0xB7A0: -case 0xB9A0: -case 0xBBA0: -case 0xBDA0: -case 0xBFA0: -case 0xB1A1: -case 0xB3A1: -case 0xB5A1: -case 0xB7A1: -case 0xB9A1: -case 0xBBA1: -case 0xBDA1: -case 0xBFA1: -case 0xB1A2: -case 0xB3A2: -case 0xB5A2: -case 0xB7A2: -case 0xB9A2: -case 0xBBA2: -case 0xBDA2: -case 0xBFA2: -case 0xB1A3: -case 0xB3A3: -case 0xB5A3: -case 0xB7A3: -case 0xB9A3: -case 0xBBA3: -case 0xBDA3: -case 0xBFA3: -case 0xB1A4: -case 0xB3A4: -case 0xB5A4: -case 0xB7A4: -case 0xB9A4: -case 0xBBA4: -case 0xBDA4: -case 0xBFA4: -case 0xB1A5: -case 0xB3A5: -case 0xB5A5: -case 0xB7A5: -case 0xB9A5: -case 0xBBA5: -case 0xBDA5: -case 0xBFA5: -case 0xB1A6: -case 0xB3A6: -case 0xB5A6: -case 0xB7A6: -case 0xB9A6: -case 0xBBA6: -case 0xBDA6: -case 0xBFA6: - -// EORDa -case 0xB1A0: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0xB3A8: -case 0xB5A8: -case 0xB7A8: -case 0xB9A8: -case 0xBBA8: -case 0xBDA8: -case 0xBFA8: -case 0xB1A9: -case 0xB3A9: -case 0xB5A9: -case 0xB7A9: -case 0xB9A9: -case 0xBBA9: -case 0xBDA9: -case 0xBFA9: -case 0xB1AA: -case 0xB3AA: -case 0xB5AA: -case 0xB7AA: -case 0xB9AA: -case 0xBBAA: -case 0xBDAA: -case 0xBFAA: -case 0xB1AB: -case 0xB3AB: -case 0xB5AB: -case 0xB7AB: -case 0xB9AB: -case 0xBBAB: -case 0xBDAB: -case 0xBFAB: -case 0xB1AC: -case 0xB3AC: -case 0xB5AC: -case 0xB7AC: -case 0xB9AC: -case 0xBBAC: -case 0xBDAC: -case 0xBFAC: -case 0xB1AD: -case 0xB3AD: -case 0xB5AD: -case 0xB7AD: -case 0xB9AD: -case 0xBBAD: -case 0xBDAD: -case 0xBFAD: -case 0xB1AE: -case 0xB3AE: -case 0xB5AE: -case 0xB7AE: -case 0xB9AE: -case 0xBBAE: -case 0xBDAE: -case 0xBFAE: -case 0xB1AF: -case 0xB3AF: -case 0xB5AF: -case 0xB7AF: -case 0xB9AF: -case 0xBBAF: -case 0xBDAF: -case 0xBFAF: - -// EORDa -case 0xB1A8: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0xB3B0: -case 0xB5B0: -case 0xB7B0: -case 0xB9B0: -case 0xBBB0: -case 0xBDB0: -case 0xBFB0: -case 0xB1B1: -case 0xB3B1: -case 0xB5B1: -case 0xB7B1: -case 0xB9B1: -case 0xBBB1: -case 0xBDB1: -case 0xBFB1: -case 0xB1B2: -case 0xB3B2: -case 0xB5B2: -case 0xB7B2: -case 0xB9B2: -case 0xBBB2: -case 0xBDB2: -case 0xBFB2: -case 0xB1B3: -case 0xB3B3: -case 0xB5B3: -case 0xB7B3: -case 0xB9B3: -case 0xBBB3: -case 0xBDB3: -case 0xBFB3: -case 0xB1B4: -case 0xB3B4: -case 0xB5B4: -case 0xB7B4: -case 0xB9B4: -case 0xBBB4: -case 0xBDB4: -case 0xBFB4: -case 0xB1B5: -case 0xB3B5: -case 0xB5B5: -case 0xB7B5: -case 0xB9B5: -case 0xBBB5: -case 0xBDB5: -case 0xBFB5: -case 0xB1B6: -case 0xB3B6: -case 0xB5B6: -case 0xB7B6: -case 0xB9B6: -case 0xBBB6: -case 0xBDB6: -case 0xBFB6: -case 0xB1B7: -case 0xB3B7: -case 0xB5B7: -case 0xB7B7: -case 0xB9B7: -case 0xBBB7: -case 0xBDB7: -case 0xBFB7: - -// EORDa -case 0xB1B0: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0xB3B8: -case 0xB5B8: -case 0xB7B8: -case 0xB9B8: -case 0xBBB8: -case 0xBDB8: -case 0xBFB8: - -// EORDa -case 0xB1B8: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0xB3B9: -case 0xB5B9: -case 0xB7B9: -case 0xB9B9: -case 0xBBB9: -case 0xBDB9: -case 0xBFB9: - -// EORDa -case 0xB1B9: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0xB39F: -case 0xB59F: -case 0xB79F: -case 0xB99F: -case 0xBB9F: -case 0xBD9F: -case 0xBF9F: - -// EORDa -case 0xB19F: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xB3A7: -case 0xB5A7: -case 0xB7A7: -case 0xB9A7: -case 0xBBA7: -case 0xBDA7: -case 0xBFA7: - -// EORDa -case 0xB1A7: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res ^= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0xB2C0: -case 0xB4C0: -case 0xB6C0: -case 0xB8C0: -case 0xBAC0: -case 0xBCC0: -case 0xBEC0: -case 0xB0C1: -case 0xB2C1: -case 0xB4C1: -case 0xB6C1: -case 0xB8C1: -case 0xBAC1: -case 0xBCC1: -case 0xBEC1: -case 0xB0C2: -case 0xB2C2: -case 0xB4C2: -case 0xB6C2: -case 0xB8C2: -case 0xBAC2: -case 0xBCC2: -case 0xBEC2: -case 0xB0C3: -case 0xB2C3: -case 0xB4C3: -case 0xB6C3: -case 0xB8C3: -case 0xBAC3: -case 0xBCC3: -case 0xBEC3: -case 0xB0C4: -case 0xB2C4: -case 0xB4C4: -case 0xB6C4: -case 0xB8C4: -case 0xBAC4: -case 0xBCC4: -case 0xBEC4: -case 0xB0C5: -case 0xB2C5: -case 0xB4C5: -case 0xB6C5: -case 0xB8C5: -case 0xBAC5: -case 0xBCC5: -case 0xBEC5: -case 0xB0C6: -case 0xB2C6: -case 0xB4C6: -case 0xB6C6: -case 0xB8C6: -case 0xBAC6: -case 0xBCC6: -case 0xBEC6: -case 0xB0C7: -case 0xB2C7: -case 0xB4C7: -case 0xB6C7: -case 0xB8C7: -case 0xBAC7: -case 0xBCC7: -case 0xBEC7: - -// CMPA -case 0xB0C0: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(6) -case 0xB2C8: -case 0xB4C8: -case 0xB6C8: -case 0xB8C8: -case 0xBAC8: -case 0xBCC8: -case 0xBEC8: -case 0xB0C9: -case 0xB2C9: -case 0xB4C9: -case 0xB6C9: -case 0xB8C9: -case 0xBAC9: -case 0xBCC9: -case 0xBEC9: -case 0xB0CA: -case 0xB2CA: -case 0xB4CA: -case 0xB6CA: -case 0xB8CA: -case 0xBACA: -case 0xBCCA: -case 0xBECA: -case 0xB0CB: -case 0xB2CB: -case 0xB4CB: -case 0xB6CB: -case 0xB8CB: -case 0xBACB: -case 0xBCCB: -case 0xBECB: -case 0xB0CC: -case 0xB2CC: -case 0xB4CC: -case 0xB6CC: -case 0xB8CC: -case 0xBACC: -case 0xBCCC: -case 0xBECC: -case 0xB0CD: -case 0xB2CD: -case 0xB4CD: -case 0xB6CD: -case 0xB8CD: -case 0xBACD: -case 0xBCCD: -case 0xBECD: -case 0xB0CE: -case 0xB2CE: -case 0xB4CE: -case 0xB6CE: -case 0xB8CE: -case 0xBACE: -case 0xBCCE: -case 0xBECE: -case 0xB0CF: -case 0xB2CF: -case 0xB4CF: -case 0xB6CF: -case 0xB8CF: -case 0xBACF: -case 0xBCCF: -case 0xBECF: - -// CMPA -case 0xB0C8: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(6) -case 0xB2D0: -case 0xB4D0: -case 0xB6D0: -case 0xB8D0: -case 0xBAD0: -case 0xBCD0: -case 0xBED0: -case 0xB0D1: -case 0xB2D1: -case 0xB4D1: -case 0xB6D1: -case 0xB8D1: -case 0xBAD1: -case 0xBCD1: -case 0xBED1: -case 0xB0D2: -case 0xB2D2: -case 0xB4D2: -case 0xB6D2: -case 0xB8D2: -case 0xBAD2: -case 0xBCD2: -case 0xBED2: -case 0xB0D3: -case 0xB2D3: -case 0xB4D3: -case 0xB6D3: -case 0xB8D3: -case 0xBAD3: -case 0xBCD3: -case 0xBED3: -case 0xB0D4: -case 0xB2D4: -case 0xB4D4: -case 0xB6D4: -case 0xB8D4: -case 0xBAD4: -case 0xBCD4: -case 0xBED4: -case 0xB0D5: -case 0xB2D5: -case 0xB4D5: -case 0xB6D5: -case 0xB8D5: -case 0xBAD5: -case 0xBCD5: -case 0xBED5: -case 0xB0D6: -case 0xB2D6: -case 0xB4D6: -case 0xB6D6: -case 0xB8D6: -case 0xBAD6: -case 0xBCD6: -case 0xBED6: -case 0xB0D7: -case 0xB2D7: -case 0xB4D7: -case 0xB6D7: -case 0xB8D7: -case 0xBAD7: -case 0xBCD7: -case 0xBED7: - -// CMPA -case 0xB0D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(10) -case 0xB2D8: -case 0xB4D8: -case 0xB6D8: -case 0xB8D8: -case 0xBAD8: -case 0xBCD8: -case 0xBED8: -case 0xB0D9: -case 0xB2D9: -case 0xB4D9: -case 0xB6D9: -case 0xB8D9: -case 0xBAD9: -case 0xBCD9: -case 0xBED9: -case 0xB0DA: -case 0xB2DA: -case 0xB4DA: -case 0xB6DA: -case 0xB8DA: -case 0xBADA: -case 0xBCDA: -case 0xBEDA: -case 0xB0DB: -case 0xB2DB: -case 0xB4DB: -case 0xB6DB: -case 0xB8DB: -case 0xBADB: -case 0xBCDB: -case 0xBEDB: -case 0xB0DC: -case 0xB2DC: -case 0xB4DC: -case 0xB6DC: -case 0xB8DC: -case 0xBADC: -case 0xBCDC: -case 0xBEDC: -case 0xB0DD: -case 0xB2DD: -case 0xB4DD: -case 0xB6DD: -case 0xB8DD: -case 0xBADD: -case 0xBCDD: -case 0xBEDD: -case 0xB0DE: -case 0xB2DE: -case 0xB4DE: -case 0xB6DE: -case 0xB8DE: -case 0xBADE: -case 0xBCDE: -case 0xBEDE: - -// CMPA -case 0xB0D8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(10) -case 0xB2E0: -case 0xB4E0: -case 0xB6E0: -case 0xB8E0: -case 0xBAE0: -case 0xBCE0: -case 0xBEE0: -case 0xB0E1: -case 0xB2E1: -case 0xB4E1: -case 0xB6E1: -case 0xB8E1: -case 0xBAE1: -case 0xBCE1: -case 0xBEE1: -case 0xB0E2: -case 0xB2E2: -case 0xB4E2: -case 0xB6E2: -case 0xB8E2: -case 0xBAE2: -case 0xBCE2: -case 0xBEE2: -case 0xB0E3: -case 0xB2E3: -case 0xB4E3: -case 0xB6E3: -case 0xB8E3: -case 0xBAE3: -case 0xBCE3: -case 0xBEE3: -case 0xB0E4: -case 0xB2E4: -case 0xB4E4: -case 0xB6E4: -case 0xB8E4: -case 0xBAE4: -case 0xBCE4: -case 0xBEE4: -case 0xB0E5: -case 0xB2E5: -case 0xB4E5: -case 0xB6E5: -case 0xB8E5: -case 0xBAE5: -case 0xBCE5: -case 0xBEE5: -case 0xB0E6: -case 0xB2E6: -case 0xB4E6: -case 0xB6E6: -case 0xB8E6: -case 0xBAE6: -case 0xBCE6: -case 0xBEE6: - -// CMPA -case 0xB0E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(12) -case 0xB2E8: -case 0xB4E8: -case 0xB6E8: -case 0xB8E8: -case 0xBAE8: -case 0xBCE8: -case 0xBEE8: -case 0xB0E9: -case 0xB2E9: -case 0xB4E9: -case 0xB6E9: -case 0xB8E9: -case 0xBAE9: -case 0xBCE9: -case 0xBEE9: -case 0xB0EA: -case 0xB2EA: -case 0xB4EA: -case 0xB6EA: -case 0xB8EA: -case 0xBAEA: -case 0xBCEA: -case 0xBEEA: -case 0xB0EB: -case 0xB2EB: -case 0xB4EB: -case 0xB6EB: -case 0xB8EB: -case 0xBAEB: -case 0xBCEB: -case 0xBEEB: -case 0xB0EC: -case 0xB2EC: -case 0xB4EC: -case 0xB6EC: -case 0xB8EC: -case 0xBAEC: -case 0xBCEC: -case 0xBEEC: -case 0xB0ED: -case 0xB2ED: -case 0xB4ED: -case 0xB6ED: -case 0xB8ED: -case 0xBAED: -case 0xBCED: -case 0xBEED: -case 0xB0EE: -case 0xB2EE: -case 0xB4EE: -case 0xB6EE: -case 0xB8EE: -case 0xBAEE: -case 0xBCEE: -case 0xBEEE: -case 0xB0EF: -case 0xB2EF: -case 0xB4EF: -case 0xB6EF: -case 0xB8EF: -case 0xBAEF: -case 0xBCEF: -case 0xBEEF: - -// CMPA -case 0xB0E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(14) -case 0xB2F0: -case 0xB4F0: -case 0xB6F0: -case 0xB8F0: -case 0xBAF0: -case 0xBCF0: -case 0xBEF0: -case 0xB0F1: -case 0xB2F1: -case 0xB4F1: -case 0xB6F1: -case 0xB8F1: -case 0xBAF1: -case 0xBCF1: -case 0xBEF1: -case 0xB0F2: -case 0xB2F2: -case 0xB4F2: -case 0xB6F2: -case 0xB8F2: -case 0xBAF2: -case 0xBCF2: -case 0xBEF2: -case 0xB0F3: -case 0xB2F3: -case 0xB4F3: -case 0xB6F3: -case 0xB8F3: -case 0xBAF3: -case 0xBCF3: -case 0xBEF3: -case 0xB0F4: -case 0xB2F4: -case 0xB4F4: -case 0xB6F4: -case 0xB8F4: -case 0xBAF4: -case 0xBCF4: -case 0xBEF4: -case 0xB0F5: -case 0xB2F5: -case 0xB4F5: -case 0xB6F5: -case 0xB8F5: -case 0xBAF5: -case 0xBCF5: -case 0xBEF5: -case 0xB0F6: -case 0xB2F6: -case 0xB4F6: -case 0xB6F6: -case 0xB8F6: -case 0xBAF6: -case 0xBCF6: -case 0xBEF6: -case 0xB0F7: -case 0xB2F7: -case 0xB4F7: -case 0xB6F7: -case 0xB8F7: -case 0xBAF7: -case 0xBCF7: -case 0xBEF7: - -// CMPA -case 0xB0F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) -case 0xB2F8: -case 0xB4F8: -case 0xB6F8: -case 0xB8F8: -case 0xBAF8: -case 0xBCF8: -case 0xBEF8: - -// CMPA -case 0xB0F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(14) -case 0xB2F9: -case 0xB4F9: -case 0xB6F9: -case 0xB8F9: -case 0xBAF9: -case 0xBCF9: -case 0xBEF9: - -// CMPA -case 0xB0F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(18) -case 0xB2FA: -case 0xB4FA: -case 0xB6FA: -case 0xB8FA: -case 0xBAFA: -case 0xBCFA: -case 0xBEFA: - -// CMPA -case 0xB0FA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(14) -case 0xB2FB: -case 0xB4FB: -case 0xB6FB: -case 0xB8FB: -case 0xBAFB: -case 0xBCFB: -case 0xBEFB: - -// CMPA -case 0xB0FB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) -case 0xB2FC: -case 0xB4FC: -case 0xB6FC: -case 0xB8FC: -case 0xBAFC: -case 0xBCFC: -case 0xBEFC: - -// CMPA -case 0xB0FC: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)FETCH_WORD; - PC += 2; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(10) -case 0xB2DF: -case 0xB4DF: -case 0xB6DF: -case 0xB8DF: -case 0xBADF: -case 0xBCDF: -case 0xBEDF: - -// CMPA -case 0xB0DF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(10) -case 0xB2E7: -case 0xB4E7: -case 0xB6E7: -case 0xB8E7: -case 0xBAE7: -case 0xBCE7: -case 0xBEE7: - -// CMPA -case 0xB0E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(12) -case 0xB3C0: -case 0xB5C0: -case 0xB7C0: -case 0xB9C0: -case 0xBBC0: -case 0xBDC0: -case 0xBFC0: -case 0xB1C1: -case 0xB3C1: -case 0xB5C1: -case 0xB7C1: -case 0xB9C1: -case 0xBBC1: -case 0xBDC1: -case 0xBFC1: -case 0xB1C2: -case 0xB3C2: -case 0xB5C2: -case 0xB7C2: -case 0xB9C2: -case 0xBBC2: -case 0xBDC2: -case 0xBFC2: -case 0xB1C3: -case 0xB3C3: -case 0xB5C3: -case 0xB7C3: -case 0xB9C3: -case 0xBBC3: -case 0xBDC3: -case 0xBFC3: -case 0xB1C4: -case 0xB3C4: -case 0xB5C4: -case 0xB7C4: -case 0xB9C4: -case 0xBBC4: -case 0xBDC4: -case 0xBFC4: -case 0xB1C5: -case 0xB3C5: -case 0xB5C5: -case 0xB7C5: -case 0xB9C5: -case 0xBBC5: -case 0xBDC5: -case 0xBFC5: -case 0xB1C6: -case 0xB3C6: -case 0xB5C6: -case 0xB7C6: -case 0xB9C6: -case 0xBBC6: -case 0xBDC6: -case 0xBFC6: -case 0xB1C7: -case 0xB3C7: -case 0xB5C7: -case 0xB7C7: -case 0xB9C7: -case 0xBBC7: -case 0xBDC7: -case 0xBFC7: - -// CMPA -case 0xB1C0: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(6) -case 0xB3C8: -case 0xB5C8: -case 0xB7C8: -case 0xB9C8: -case 0xBBC8: -case 0xBDC8: -case 0xBFC8: -case 0xB1C9: -case 0xB3C9: -case 0xB5C9: -case 0xB7C9: -case 0xB9C9: -case 0xBBC9: -case 0xBDC9: -case 0xBFC9: -case 0xB1CA: -case 0xB3CA: -case 0xB5CA: -case 0xB7CA: -case 0xB9CA: -case 0xBBCA: -case 0xBDCA: -case 0xBFCA: -case 0xB1CB: -case 0xB3CB: -case 0xB5CB: -case 0xB7CB: -case 0xB9CB: -case 0xBBCB: -case 0xBDCB: -case 0xBFCB: -case 0xB1CC: -case 0xB3CC: -case 0xB5CC: -case 0xB7CC: -case 0xB9CC: -case 0xBBCC: -case 0xBDCC: -case 0xBFCC: -case 0xB1CD: -case 0xB3CD: -case 0xB5CD: -case 0xB7CD: -case 0xB9CD: -case 0xBBCD: -case 0xBDCD: -case 0xBFCD: -case 0xB1CE: -case 0xB3CE: -case 0xB5CE: -case 0xB7CE: -case 0xB9CE: -case 0xBBCE: -case 0xBDCE: -case 0xBFCE: -case 0xB1CF: -case 0xB3CF: -case 0xB5CF: -case 0xB7CF: -case 0xB9CF: -case 0xBBCF: -case 0xBDCF: -case 0xBFCF: - -// CMPA -case 0xB1C8: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(6) -case 0xB3D0: -case 0xB5D0: -case 0xB7D0: -case 0xB9D0: -case 0xBBD0: -case 0xBDD0: -case 0xBFD0: -case 0xB1D1: -case 0xB3D1: -case 0xB5D1: -case 0xB7D1: -case 0xB9D1: -case 0xBBD1: -case 0xBDD1: -case 0xBFD1: -case 0xB1D2: -case 0xB3D2: -case 0xB5D2: -case 0xB7D2: -case 0xB9D2: -case 0xBBD2: -case 0xBDD2: -case 0xBFD2: -case 0xB1D3: -case 0xB3D3: -case 0xB5D3: -case 0xB7D3: -case 0xB9D3: -case 0xBBD3: -case 0xBDD3: -case 0xBFD3: -case 0xB1D4: -case 0xB3D4: -case 0xB5D4: -case 0xB7D4: -case 0xB9D4: -case 0xBBD4: -case 0xBDD4: -case 0xBFD4: -case 0xB1D5: -case 0xB3D5: -case 0xB5D5: -case 0xB7D5: -case 0xB9D5: -case 0xBBD5: -case 0xBDD5: -case 0xBFD5: -case 0xB1D6: -case 0xB3D6: -case 0xB5D6: -case 0xB7D6: -case 0xB9D6: -case 0xBBD6: -case 0xBDD6: -case 0xBFD6: -case 0xB1D7: -case 0xB3D7: -case 0xB5D7: -case 0xB7D7: -case 0xB9D7: -case 0xBBD7: -case 0xBDD7: -case 0xBFD7: - -// CMPA -case 0xB1D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(14) -case 0xB3D8: -case 0xB5D8: -case 0xB7D8: -case 0xB9D8: -case 0xBBD8: -case 0xBDD8: -case 0xBFD8: -case 0xB1D9: -case 0xB3D9: -case 0xB5D9: -case 0xB7D9: -case 0xB9D9: -case 0xBBD9: -case 0xBDD9: -case 0xBFD9: -case 0xB1DA: -case 0xB3DA: -case 0xB5DA: -case 0xB7DA: -case 0xB9DA: -case 0xBBDA: -case 0xBDDA: -case 0xBFDA: -case 0xB1DB: -case 0xB3DB: -case 0xB5DB: -case 0xB7DB: -case 0xB9DB: -case 0xBBDB: -case 0xBDDB: -case 0xBFDB: -case 0xB1DC: -case 0xB3DC: -case 0xB5DC: -case 0xB7DC: -case 0xB9DC: -case 0xBBDC: -case 0xBDDC: -case 0xBFDC: -case 0xB1DD: -case 0xB3DD: -case 0xB5DD: -case 0xB7DD: -case 0xB9DD: -case 0xBBDD: -case 0xBDDD: -case 0xBFDD: -case 0xB1DE: -case 0xB3DE: -case 0xB5DE: -case 0xB7DE: -case 0xB9DE: -case 0xBBDE: -case 0xBDDE: -case 0xBFDE: - -// CMPA -case 0xB1D8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(14) -case 0xB3E0: -case 0xB5E0: -case 0xB7E0: -case 0xB9E0: -case 0xBBE0: -case 0xBDE0: -case 0xBFE0: -case 0xB1E1: -case 0xB3E1: -case 0xB5E1: -case 0xB7E1: -case 0xB9E1: -case 0xBBE1: -case 0xBDE1: -case 0xBFE1: -case 0xB1E2: -case 0xB3E2: -case 0xB5E2: -case 0xB7E2: -case 0xB9E2: -case 0xBBE2: -case 0xBDE2: -case 0xBFE2: -case 0xB1E3: -case 0xB3E3: -case 0xB5E3: -case 0xB7E3: -case 0xB9E3: -case 0xBBE3: -case 0xBDE3: -case 0xBFE3: -case 0xB1E4: -case 0xB3E4: -case 0xB5E4: -case 0xB7E4: -case 0xB9E4: -case 0xBBE4: -case 0xBDE4: -case 0xBFE4: -case 0xB1E5: -case 0xB3E5: -case 0xB5E5: -case 0xB7E5: -case 0xB9E5: -case 0xBBE5: -case 0xBDE5: -case 0xBFE5: -case 0xB1E6: -case 0xB3E6: -case 0xB5E6: -case 0xB7E6: -case 0xB9E6: -case 0xBBE6: -case 0xBDE6: -case 0xBFE6: - -// CMPA -case 0xB1E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) -case 0xB3E8: -case 0xB5E8: -case 0xB7E8: -case 0xB9E8: -case 0xBBE8: -case 0xBDE8: -case 0xBFE8: -case 0xB1E9: -case 0xB3E9: -case 0xB5E9: -case 0xB7E9: -case 0xB9E9: -case 0xBBE9: -case 0xBDE9: -case 0xBFE9: -case 0xB1EA: -case 0xB3EA: -case 0xB5EA: -case 0xB7EA: -case 0xB9EA: -case 0xBBEA: -case 0xBDEA: -case 0xBFEA: -case 0xB1EB: -case 0xB3EB: -case 0xB5EB: -case 0xB7EB: -case 0xB9EB: -case 0xBBEB: -case 0xBDEB: -case 0xBFEB: -case 0xB1EC: -case 0xB3EC: -case 0xB5EC: -case 0xB7EC: -case 0xB9EC: -case 0xBBEC: -case 0xBDEC: -case 0xBFEC: -case 0xB1ED: -case 0xB3ED: -case 0xB5ED: -case 0xB7ED: -case 0xB9ED: -case 0xBBED: -case 0xBDED: -case 0xBFED: -case 0xB1EE: -case 0xB3EE: -case 0xB5EE: -case 0xB7EE: -case 0xB9EE: -case 0xBBEE: -case 0xBDEE: -case 0xBFEE: -case 0xB1EF: -case 0xB3EF: -case 0xB5EF: -case 0xB7EF: -case 0xB9EF: -case 0xBBEF: -case 0xBDEF: -case 0xBFEF: - -// CMPA -case 0xB1E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(18) -case 0xB3F0: -case 0xB5F0: -case 0xB7F0: -case 0xB9F0: -case 0xBBF0: -case 0xBDF0: -case 0xBFF0: -case 0xB1F1: -case 0xB3F1: -case 0xB5F1: -case 0xB7F1: -case 0xB9F1: -case 0xBBF1: -case 0xBDF1: -case 0xBFF1: -case 0xB1F2: -case 0xB3F2: -case 0xB5F2: -case 0xB7F2: -case 0xB9F2: -case 0xBBF2: -case 0xBDF2: -case 0xBFF2: -case 0xB1F3: -case 0xB3F3: -case 0xB5F3: -case 0xB7F3: -case 0xB9F3: -case 0xBBF3: -case 0xBDF3: -case 0xBFF3: -case 0xB1F4: -case 0xB3F4: -case 0xB5F4: -case 0xB7F4: -case 0xB9F4: -case 0xBBF4: -case 0xBDF4: -case 0xBFF4: -case 0xB1F5: -case 0xB3F5: -case 0xB5F5: -case 0xB7F5: -case 0xB9F5: -case 0xBBF5: -case 0xBDF5: -case 0xBFF5: -case 0xB1F6: -case 0xB3F6: -case 0xB5F6: -case 0xB7F6: -case 0xB9F6: -case 0xBBF6: -case 0xBDF6: -case 0xBFF6: -case 0xB1F7: -case 0xB3F7: -case 0xB5F7: -case 0xB7F7: -case 0xB9F7: -case 0xBBF7: -case 0xBDF7: -case 0xBFF7: - -// CMPA -case 0xB1F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0xB3F8: -case 0xB5F8: -case 0xB7F8: -case 0xB9F8: -case 0xBBF8: -case 0xBDF8: -case 0xBFF8: - -// CMPA -case 0xB1F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(18) -case 0xB3F9: -case 0xB5F9: -case 0xB7F9: -case 0xB9F9: -case 0xBBF9: -case 0xBDF9: -case 0xBFF9: - -// CMPA -case 0xB1F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(22) -case 0xB3FA: -case 0xB5FA: -case 0xB7FA: -case 0xB9FA: -case 0xBBFA: -case 0xBDFA: -case 0xBFFA: - -// CMPA -case 0xB1FA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(18) -case 0xB3FB: -case 0xB5FB: -case 0xB7FB: -case 0xB9FB: -case 0xBBFB: -case 0xBDFB: -case 0xBFFB: - -// CMPA -case 0xB1FB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(20) -case 0xB3FC: -case 0xB5FC: -case 0xB7FC: -case 0xB9FC: -case 0xBBFC: -case 0xBDFC: -case 0xBFFC: - -// CMPA -case 0xB1FC: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)FETCH_LONG; - PC += 4; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; -} -RET(14) -case 0xB3DF: -case 0xB5DF: -case 0xB7DF: -case 0xB9DF: -case 0xBBDF: -case 0xBDDF: -case 0xBFDF: - -// CMPA -case 0xB1DF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(14) -case 0xB3E7: -case 0xB5E7: -case 0xB7E7: -case 0xB9E7: -case 0xBBE7: -case 0xBDE7: -case 0xBFE7: - -// CMPA -case 0xB1E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst - src; - CPU->flag_notZ = res; - CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23; - CPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24; - CPU->flag_N = res >> 24; - POST_IO -} -RET(16) diff --git a/yabause/src/c68k/c68k_opC.inc b/yabause/src/c68k/c68k_opC.inc deleted file mode 100644 index df59c4338d..0000000000 --- a/yabause/src/c68k/c68k_opC.inc +++ /dev/null @@ -1,5383 +0,0 @@ -case 0xC200: -case 0xC400: -case 0xC600: -case 0xC800: -case 0xCA00: -case 0xCC00: -case 0xCE00: -case 0xC001: -case 0xC201: -case 0xC401: -case 0xC601: -case 0xC801: -case 0xCA01: -case 0xCC01: -case 0xCE01: -case 0xC002: -case 0xC202: -case 0xC402: -case 0xC602: -case 0xC802: -case 0xCA02: -case 0xCC02: -case 0xCE02: -case 0xC003: -case 0xC203: -case 0xC403: -case 0xC603: -case 0xC803: -case 0xCA03: -case 0xCC03: -case 0xCE03: -case 0xC004: -case 0xC204: -case 0xC404: -case 0xC604: -case 0xC804: -case 0xCA04: -case 0xCC04: -case 0xCE04: -case 0xC005: -case 0xC205: -case 0xC405: -case 0xC605: -case 0xC805: -case 0xCA05: -case 0xCC05: -case 0xCE05: -case 0xC006: -case 0xC206: -case 0xC406: -case 0xC606: -case 0xC806: -case 0xCA06: -case 0xCC06: -case 0xCE06: -case 0xC007: -case 0xC207: -case 0xC407: -case 0xC607: -case 0xC807: -case 0xCA07: -case 0xCC07: -case 0xCE07: - -// ANDaD -case 0xC000: -{ - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0xC210: -case 0xC410: -case 0xC610: -case 0xC810: -case 0xCA10: -case 0xCC10: -case 0xCE10: -case 0xC011: -case 0xC211: -case 0xC411: -case 0xC611: -case 0xC811: -case 0xCA11: -case 0xCC11: -case 0xCE11: -case 0xC012: -case 0xC212: -case 0xC412: -case 0xC612: -case 0xC812: -case 0xCA12: -case 0xCC12: -case 0xCE12: -case 0xC013: -case 0xC213: -case 0xC413: -case 0xC613: -case 0xC813: -case 0xCA13: -case 0xCC13: -case 0xCE13: -case 0xC014: -case 0xC214: -case 0xC414: -case 0xC614: -case 0xC814: -case 0xCA14: -case 0xCC14: -case 0xCE14: -case 0xC015: -case 0xC215: -case 0xC415: -case 0xC615: -case 0xC815: -case 0xCA15: -case 0xCC15: -case 0xCE15: -case 0xC016: -case 0xC216: -case 0xC416: -case 0xC616: -case 0xC816: -case 0xCA16: -case 0xCC16: -case 0xCE16: -case 0xC017: -case 0xC217: -case 0xC417: -case 0xC617: -case 0xC817: -case 0xCA17: -case 0xCC17: -case 0xCE17: - -// ANDaD -case 0xC010: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xC218: -case 0xC418: -case 0xC618: -case 0xC818: -case 0xCA18: -case 0xCC18: -case 0xCE18: -case 0xC019: -case 0xC219: -case 0xC419: -case 0xC619: -case 0xC819: -case 0xCA19: -case 0xCC19: -case 0xCE19: -case 0xC01A: -case 0xC21A: -case 0xC41A: -case 0xC61A: -case 0xC81A: -case 0xCA1A: -case 0xCC1A: -case 0xCE1A: -case 0xC01B: -case 0xC21B: -case 0xC41B: -case 0xC61B: -case 0xC81B: -case 0xCA1B: -case 0xCC1B: -case 0xCE1B: -case 0xC01C: -case 0xC21C: -case 0xC41C: -case 0xC61C: -case 0xC81C: -case 0xCA1C: -case 0xCC1C: -case 0xCE1C: -case 0xC01D: -case 0xC21D: -case 0xC41D: -case 0xC61D: -case 0xC81D: -case 0xCA1D: -case 0xCC1D: -case 0xCE1D: -case 0xC01E: -case 0xC21E: -case 0xC41E: -case 0xC61E: -case 0xC81E: -case 0xCA1E: -case 0xCC1E: -case 0xCE1E: - -// ANDaD -case 0xC018: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xC220: -case 0xC420: -case 0xC620: -case 0xC820: -case 0xCA20: -case 0xCC20: -case 0xCE20: -case 0xC021: -case 0xC221: -case 0xC421: -case 0xC621: -case 0xC821: -case 0xCA21: -case 0xCC21: -case 0xCE21: -case 0xC022: -case 0xC222: -case 0xC422: -case 0xC622: -case 0xC822: -case 0xCA22: -case 0xCC22: -case 0xCE22: -case 0xC023: -case 0xC223: -case 0xC423: -case 0xC623: -case 0xC823: -case 0xCA23: -case 0xCC23: -case 0xCE23: -case 0xC024: -case 0xC224: -case 0xC424: -case 0xC624: -case 0xC824: -case 0xCA24: -case 0xCC24: -case 0xCE24: -case 0xC025: -case 0xC225: -case 0xC425: -case 0xC625: -case 0xC825: -case 0xCA25: -case 0xCC25: -case 0xCE25: -case 0xC026: -case 0xC226: -case 0xC426: -case 0xC626: -case 0xC826: -case 0xCA26: -case 0xCC26: -case 0xCE26: - -// ANDaD -case 0xC020: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0xC228: -case 0xC428: -case 0xC628: -case 0xC828: -case 0xCA28: -case 0xCC28: -case 0xCE28: -case 0xC029: -case 0xC229: -case 0xC429: -case 0xC629: -case 0xC829: -case 0xCA29: -case 0xCC29: -case 0xCE29: -case 0xC02A: -case 0xC22A: -case 0xC42A: -case 0xC62A: -case 0xC82A: -case 0xCA2A: -case 0xCC2A: -case 0xCE2A: -case 0xC02B: -case 0xC22B: -case 0xC42B: -case 0xC62B: -case 0xC82B: -case 0xCA2B: -case 0xCC2B: -case 0xCE2B: -case 0xC02C: -case 0xC22C: -case 0xC42C: -case 0xC62C: -case 0xC82C: -case 0xCA2C: -case 0xCC2C: -case 0xCE2C: -case 0xC02D: -case 0xC22D: -case 0xC42D: -case 0xC62D: -case 0xC82D: -case 0xCA2D: -case 0xCC2D: -case 0xCE2D: -case 0xC02E: -case 0xC22E: -case 0xC42E: -case 0xC62E: -case 0xC82E: -case 0xCA2E: -case 0xCC2E: -case 0xCE2E: -case 0xC02F: -case 0xC22F: -case 0xC42F: -case 0xC62F: -case 0xC82F: -case 0xCA2F: -case 0xCC2F: -case 0xCE2F: - -// ANDaD -case 0xC028: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xC230: -case 0xC430: -case 0xC630: -case 0xC830: -case 0xCA30: -case 0xCC30: -case 0xCE30: -case 0xC031: -case 0xC231: -case 0xC431: -case 0xC631: -case 0xC831: -case 0xCA31: -case 0xCC31: -case 0xCE31: -case 0xC032: -case 0xC232: -case 0xC432: -case 0xC632: -case 0xC832: -case 0xCA32: -case 0xCC32: -case 0xCE32: -case 0xC033: -case 0xC233: -case 0xC433: -case 0xC633: -case 0xC833: -case 0xCA33: -case 0xCC33: -case 0xCE33: -case 0xC034: -case 0xC234: -case 0xC434: -case 0xC634: -case 0xC834: -case 0xCA34: -case 0xCC34: -case 0xCE34: -case 0xC035: -case 0xC235: -case 0xC435: -case 0xC635: -case 0xC835: -case 0xCA35: -case 0xCC35: -case 0xCE35: -case 0xC036: -case 0xC236: -case 0xC436: -case 0xC636: -case 0xC836: -case 0xCA36: -case 0xCC36: -case 0xCE36: -case 0xC037: -case 0xC237: -case 0xC437: -case 0xC637: -case 0xC837: -case 0xCA37: -case 0xCC37: -case 0xCE37: - -// ANDaD -case 0xC030: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0xC238: -case 0xC438: -case 0xC638: -case 0xC838: -case 0xCA38: -case 0xCC38: -case 0xCE38: - -// ANDaD -case 0xC038: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xC239: -case 0xC439: -case 0xC639: -case 0xC839: -case 0xCA39: -case 0xCC39: -case 0xCE39: - -// ANDaD -case 0xC039: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xC23A: -case 0xC43A: -case 0xC63A: -case 0xC83A: -case 0xCA3A: -case 0xCC3A: -case 0xCE3A: - -// ANDaD -case 0xC03A: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xC23B: -case 0xC43B: -case 0xC63B: -case 0xC83B: -case 0xCA3B: -case 0xCC3B: -case 0xCE3B: - -// ANDaD -case 0xC03B: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0xC23C: -case 0xC43C: -case 0xC63C: -case 0xC83C: -case 0xCA3C: -case 0xCC3C: -case 0xCE3C: - -// ANDaD -case 0xC03C: -{ - u32 res; - pointer src; - src = FETCH_BYTE; - PC += 2; - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0xC21F: -case 0xC41F: -case 0xC61F: -case 0xC81F: -case 0xCA1F: -case 0xCC1F: -case 0xCE1F: - -// ANDaD -case 0xC01F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xC227: -case 0xC427: -case 0xC627: -case 0xC827: -case 0xCA27: -case 0xCC27: -case 0xCE27: - -// ANDaD -case 0xC027: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - res = (u8)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0xC240: -case 0xC440: -case 0xC640: -case 0xC840: -case 0xCA40: -case 0xCC40: -case 0xCE40: -case 0xC041: -case 0xC241: -case 0xC441: -case 0xC641: -case 0xC841: -case 0xCA41: -case 0xCC41: -case 0xCE41: -case 0xC042: -case 0xC242: -case 0xC442: -case 0xC642: -case 0xC842: -case 0xCA42: -case 0xCC42: -case 0xCE42: -case 0xC043: -case 0xC243: -case 0xC443: -case 0xC643: -case 0xC843: -case 0xCA43: -case 0xCC43: -case 0xCE43: -case 0xC044: -case 0xC244: -case 0xC444: -case 0xC644: -case 0xC844: -case 0xCA44: -case 0xCC44: -case 0xCE44: -case 0xC045: -case 0xC245: -case 0xC445: -case 0xC645: -case 0xC845: -case 0xCA45: -case 0xCC45: -case 0xCE45: -case 0xC046: -case 0xC246: -case 0xC446: -case 0xC646: -case 0xC846: -case 0xCA46: -case 0xCC46: -case 0xCE46: -case 0xC047: -case 0xC247: -case 0xC447: -case 0xC647: -case 0xC847: -case 0xCA47: -case 0xCC47: -case 0xCE47: - -// ANDaD -case 0xC040: -{ - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0xC250: -case 0xC450: -case 0xC650: -case 0xC850: -case 0xCA50: -case 0xCC50: -case 0xCE50: -case 0xC051: -case 0xC251: -case 0xC451: -case 0xC651: -case 0xC851: -case 0xCA51: -case 0xCC51: -case 0xCE51: -case 0xC052: -case 0xC252: -case 0xC452: -case 0xC652: -case 0xC852: -case 0xCA52: -case 0xCC52: -case 0xCE52: -case 0xC053: -case 0xC253: -case 0xC453: -case 0xC653: -case 0xC853: -case 0xCA53: -case 0xCC53: -case 0xCE53: -case 0xC054: -case 0xC254: -case 0xC454: -case 0xC654: -case 0xC854: -case 0xCA54: -case 0xCC54: -case 0xCE54: -case 0xC055: -case 0xC255: -case 0xC455: -case 0xC655: -case 0xC855: -case 0xCA55: -case 0xCC55: -case 0xCE55: -case 0xC056: -case 0xC256: -case 0xC456: -case 0xC656: -case 0xC856: -case 0xCA56: -case 0xCC56: -case 0xCE56: -case 0xC057: -case 0xC257: -case 0xC457: -case 0xC657: -case 0xC857: -case 0xCA57: -case 0xCC57: -case 0xCE57: - -// ANDaD -case 0xC050: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xC258: -case 0xC458: -case 0xC658: -case 0xC858: -case 0xCA58: -case 0xCC58: -case 0xCE58: -case 0xC059: -case 0xC259: -case 0xC459: -case 0xC659: -case 0xC859: -case 0xCA59: -case 0xCC59: -case 0xCE59: -case 0xC05A: -case 0xC25A: -case 0xC45A: -case 0xC65A: -case 0xC85A: -case 0xCA5A: -case 0xCC5A: -case 0xCE5A: -case 0xC05B: -case 0xC25B: -case 0xC45B: -case 0xC65B: -case 0xC85B: -case 0xCA5B: -case 0xCC5B: -case 0xCE5B: -case 0xC05C: -case 0xC25C: -case 0xC45C: -case 0xC65C: -case 0xC85C: -case 0xCA5C: -case 0xCC5C: -case 0xCE5C: -case 0xC05D: -case 0xC25D: -case 0xC45D: -case 0xC65D: -case 0xC85D: -case 0xCA5D: -case 0xCC5D: -case 0xCE5D: -case 0xC05E: -case 0xC25E: -case 0xC45E: -case 0xC65E: -case 0xC85E: -case 0xCA5E: -case 0xCC5E: -case 0xCE5E: - -// ANDaD -case 0xC058: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xC260: -case 0xC460: -case 0xC660: -case 0xC860: -case 0xCA60: -case 0xCC60: -case 0xCE60: -case 0xC061: -case 0xC261: -case 0xC461: -case 0xC661: -case 0xC861: -case 0xCA61: -case 0xCC61: -case 0xCE61: -case 0xC062: -case 0xC262: -case 0xC462: -case 0xC662: -case 0xC862: -case 0xCA62: -case 0xCC62: -case 0xCE62: -case 0xC063: -case 0xC263: -case 0xC463: -case 0xC663: -case 0xC863: -case 0xCA63: -case 0xCC63: -case 0xCE63: -case 0xC064: -case 0xC264: -case 0xC464: -case 0xC664: -case 0xC864: -case 0xCA64: -case 0xCC64: -case 0xCE64: -case 0xC065: -case 0xC265: -case 0xC465: -case 0xC665: -case 0xC865: -case 0xCA65: -case 0xCC65: -case 0xCE65: -case 0xC066: -case 0xC266: -case 0xC466: -case 0xC666: -case 0xC866: -case 0xCA66: -case 0xCC66: -case 0xCE66: - -// ANDaD -case 0xC060: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0xC268: -case 0xC468: -case 0xC668: -case 0xC868: -case 0xCA68: -case 0xCC68: -case 0xCE68: -case 0xC069: -case 0xC269: -case 0xC469: -case 0xC669: -case 0xC869: -case 0xCA69: -case 0xCC69: -case 0xCE69: -case 0xC06A: -case 0xC26A: -case 0xC46A: -case 0xC66A: -case 0xC86A: -case 0xCA6A: -case 0xCC6A: -case 0xCE6A: -case 0xC06B: -case 0xC26B: -case 0xC46B: -case 0xC66B: -case 0xC86B: -case 0xCA6B: -case 0xCC6B: -case 0xCE6B: -case 0xC06C: -case 0xC26C: -case 0xC46C: -case 0xC66C: -case 0xC86C: -case 0xCA6C: -case 0xCC6C: -case 0xCE6C: -case 0xC06D: -case 0xC26D: -case 0xC46D: -case 0xC66D: -case 0xC86D: -case 0xCA6D: -case 0xCC6D: -case 0xCE6D: -case 0xC06E: -case 0xC26E: -case 0xC46E: -case 0xC66E: -case 0xC86E: -case 0xCA6E: -case 0xCC6E: -case 0xCE6E: -case 0xC06F: -case 0xC26F: -case 0xC46F: -case 0xC66F: -case 0xC86F: -case 0xCA6F: -case 0xCC6F: -case 0xCE6F: - -// ANDaD -case 0xC068: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xC270: -case 0xC470: -case 0xC670: -case 0xC870: -case 0xCA70: -case 0xCC70: -case 0xCE70: -case 0xC071: -case 0xC271: -case 0xC471: -case 0xC671: -case 0xC871: -case 0xCA71: -case 0xCC71: -case 0xCE71: -case 0xC072: -case 0xC272: -case 0xC472: -case 0xC672: -case 0xC872: -case 0xCA72: -case 0xCC72: -case 0xCE72: -case 0xC073: -case 0xC273: -case 0xC473: -case 0xC673: -case 0xC873: -case 0xCA73: -case 0xCC73: -case 0xCE73: -case 0xC074: -case 0xC274: -case 0xC474: -case 0xC674: -case 0xC874: -case 0xCA74: -case 0xCC74: -case 0xCE74: -case 0xC075: -case 0xC275: -case 0xC475: -case 0xC675: -case 0xC875: -case 0xCA75: -case 0xCC75: -case 0xCE75: -case 0xC076: -case 0xC276: -case 0xC476: -case 0xC676: -case 0xC876: -case 0xCA76: -case 0xCC76: -case 0xCE76: -case 0xC077: -case 0xC277: -case 0xC477: -case 0xC677: -case 0xC877: -case 0xCA77: -case 0xCC77: -case 0xCE77: - -// ANDaD -case 0xC070: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0xC278: -case 0xC478: -case 0xC678: -case 0xC878: -case 0xCA78: -case 0xCC78: -case 0xCE78: - -// ANDaD -case 0xC078: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xC279: -case 0xC479: -case 0xC679: -case 0xC879: -case 0xCA79: -case 0xCC79: -case 0xCE79: - -// ANDaD -case 0xC079: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xC27A: -case 0xC47A: -case 0xC67A: -case 0xC87A: -case 0xCA7A: -case 0xCC7A: -case 0xCE7A: - -// ANDaD -case 0xC07A: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xC27B: -case 0xC47B: -case 0xC67B: -case 0xC87B: -case 0xCA7B: -case 0xCC7B: -case 0xCE7B: - -// ANDaD -case 0xC07B: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0xC27C: -case 0xC47C: -case 0xC67C: -case 0xC87C: -case 0xCA7C: -case 0xCC7C: -case 0xCE7C: - -// ANDaD -case 0xC07C: -{ - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0xC25F: -case 0xC45F: -case 0xC65F: -case 0xC85F: -case 0xCA5F: -case 0xCC5F: -case 0xCE5F: - -// ANDaD -case 0xC05F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xC267: -case 0xC467: -case 0xC667: -case 0xC867: -case 0xCA67: -case 0xCC67: -case 0xCE67: - -// ANDaD -case 0xC067: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0xC280: -case 0xC480: -case 0xC680: -case 0xC880: -case 0xCA80: -case 0xCC80: -case 0xCE80: -case 0xC081: -case 0xC281: -case 0xC481: -case 0xC681: -case 0xC881: -case 0xCA81: -case 0xCC81: -case 0xCE81: -case 0xC082: -case 0xC282: -case 0xC482: -case 0xC682: -case 0xC882: -case 0xCA82: -case 0xCC82: -case 0xCE82: -case 0xC083: -case 0xC283: -case 0xC483: -case 0xC683: -case 0xC883: -case 0xCA83: -case 0xCC83: -case 0xCE83: -case 0xC084: -case 0xC284: -case 0xC484: -case 0xC684: -case 0xC884: -case 0xCA84: -case 0xCC84: -case 0xCE84: -case 0xC085: -case 0xC285: -case 0xC485: -case 0xC685: -case 0xC885: -case 0xCA85: -case 0xCC85: -case 0xCE85: -case 0xC086: -case 0xC286: -case 0xC486: -case 0xC686: -case 0xC886: -case 0xCA86: -case 0xCC86: -case 0xCE86: -case 0xC087: -case 0xC287: -case 0xC487: -case 0xC687: -case 0xC887: -case 0xCA87: -case 0xCC87: -case 0xCE87: - -// ANDaD -case 0xC080: -{ - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(6) -case 0xC290: -case 0xC490: -case 0xC690: -case 0xC890: -case 0xCA90: -case 0xCC90: -case 0xCE90: -case 0xC091: -case 0xC291: -case 0xC491: -case 0xC691: -case 0xC891: -case 0xCA91: -case 0xCC91: -case 0xCE91: -case 0xC092: -case 0xC292: -case 0xC492: -case 0xC692: -case 0xC892: -case 0xCA92: -case 0xCC92: -case 0xCE92: -case 0xC093: -case 0xC293: -case 0xC493: -case 0xC693: -case 0xC893: -case 0xCA93: -case 0xCC93: -case 0xCE93: -case 0xC094: -case 0xC294: -case 0xC494: -case 0xC694: -case 0xC894: -case 0xCA94: -case 0xCC94: -case 0xCE94: -case 0xC095: -case 0xC295: -case 0xC495: -case 0xC695: -case 0xC895: -case 0xCA95: -case 0xCC95: -case 0xCE95: -case 0xC096: -case 0xC296: -case 0xC496: -case 0xC696: -case 0xC896: -case 0xCA96: -case 0xCC96: -case 0xCE96: -case 0xC097: -case 0xC297: -case 0xC497: -case 0xC697: -case 0xC897: -case 0xCA97: -case 0xCC97: -case 0xCE97: - -// ANDaD -case 0xC090: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xC298: -case 0xC498: -case 0xC698: -case 0xC898: -case 0xCA98: -case 0xCC98: -case 0xCE98: -case 0xC099: -case 0xC299: -case 0xC499: -case 0xC699: -case 0xC899: -case 0xCA99: -case 0xCC99: -case 0xCE99: -case 0xC09A: -case 0xC29A: -case 0xC49A: -case 0xC69A: -case 0xC89A: -case 0xCA9A: -case 0xCC9A: -case 0xCE9A: -case 0xC09B: -case 0xC29B: -case 0xC49B: -case 0xC69B: -case 0xC89B: -case 0xCA9B: -case 0xCC9B: -case 0xCE9B: -case 0xC09C: -case 0xC29C: -case 0xC49C: -case 0xC69C: -case 0xC89C: -case 0xCA9C: -case 0xCC9C: -case 0xCE9C: -case 0xC09D: -case 0xC29D: -case 0xC49D: -case 0xC69D: -case 0xC89D: -case 0xCA9D: -case 0xCC9D: -case 0xCE9D: -case 0xC09E: -case 0xC29E: -case 0xC49E: -case 0xC69E: -case 0xC89E: -case 0xCA9E: -case 0xCC9E: -case 0xCE9E: - -// ANDaD -case 0xC098: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xC2A0: -case 0xC4A0: -case 0xC6A0: -case 0xC8A0: -case 0xCAA0: -case 0xCCA0: -case 0xCEA0: -case 0xC0A1: -case 0xC2A1: -case 0xC4A1: -case 0xC6A1: -case 0xC8A1: -case 0xCAA1: -case 0xCCA1: -case 0xCEA1: -case 0xC0A2: -case 0xC2A2: -case 0xC4A2: -case 0xC6A2: -case 0xC8A2: -case 0xCAA2: -case 0xCCA2: -case 0xCEA2: -case 0xC0A3: -case 0xC2A3: -case 0xC4A3: -case 0xC6A3: -case 0xC8A3: -case 0xCAA3: -case 0xCCA3: -case 0xCEA3: -case 0xC0A4: -case 0xC2A4: -case 0xC4A4: -case 0xC6A4: -case 0xC8A4: -case 0xCAA4: -case 0xCCA4: -case 0xCEA4: -case 0xC0A5: -case 0xC2A5: -case 0xC4A5: -case 0xC6A5: -case 0xC8A5: -case 0xCAA5: -case 0xCCA5: -case 0xCEA5: -case 0xC0A6: -case 0xC2A6: -case 0xC4A6: -case 0xC6A6: -case 0xC8A6: -case 0xCAA6: -case 0xCCA6: -case 0xCEA6: - -// ANDaD -case 0xC0A0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0xC2A8: -case 0xC4A8: -case 0xC6A8: -case 0xC8A8: -case 0xCAA8: -case 0xCCA8: -case 0xCEA8: -case 0xC0A9: -case 0xC2A9: -case 0xC4A9: -case 0xC6A9: -case 0xC8A9: -case 0xCAA9: -case 0xCCA9: -case 0xCEA9: -case 0xC0AA: -case 0xC2AA: -case 0xC4AA: -case 0xC6AA: -case 0xC8AA: -case 0xCAAA: -case 0xCCAA: -case 0xCEAA: -case 0xC0AB: -case 0xC2AB: -case 0xC4AB: -case 0xC6AB: -case 0xC8AB: -case 0xCAAB: -case 0xCCAB: -case 0xCEAB: -case 0xC0AC: -case 0xC2AC: -case 0xC4AC: -case 0xC6AC: -case 0xC8AC: -case 0xCAAC: -case 0xCCAC: -case 0xCEAC: -case 0xC0AD: -case 0xC2AD: -case 0xC4AD: -case 0xC6AD: -case 0xC8AD: -case 0xCAAD: -case 0xCCAD: -case 0xCEAD: -case 0xC0AE: -case 0xC2AE: -case 0xC4AE: -case 0xC6AE: -case 0xC8AE: -case 0xCAAE: -case 0xCCAE: -case 0xCEAE: -case 0xC0AF: -case 0xC2AF: -case 0xC4AF: -case 0xC6AF: -case 0xC8AF: -case 0xCAAF: -case 0xCCAF: -case 0xCEAF: - -// ANDaD -case 0xC0A8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0xC2B0: -case 0xC4B0: -case 0xC6B0: -case 0xC8B0: -case 0xCAB0: -case 0xCCB0: -case 0xCEB0: -case 0xC0B1: -case 0xC2B1: -case 0xC4B1: -case 0xC6B1: -case 0xC8B1: -case 0xCAB1: -case 0xCCB1: -case 0xCEB1: -case 0xC0B2: -case 0xC2B2: -case 0xC4B2: -case 0xC6B2: -case 0xC8B2: -case 0xCAB2: -case 0xCCB2: -case 0xCEB2: -case 0xC0B3: -case 0xC2B3: -case 0xC4B3: -case 0xC6B3: -case 0xC8B3: -case 0xCAB3: -case 0xCCB3: -case 0xCEB3: -case 0xC0B4: -case 0xC2B4: -case 0xC4B4: -case 0xC6B4: -case 0xC8B4: -case 0xCAB4: -case 0xCCB4: -case 0xCEB4: -case 0xC0B5: -case 0xC2B5: -case 0xC4B5: -case 0xC6B5: -case 0xC8B5: -case 0xCAB5: -case 0xCCB5: -case 0xCEB5: -case 0xC0B6: -case 0xC2B6: -case 0xC4B6: -case 0xC6B6: -case 0xC8B6: -case 0xCAB6: -case 0xCCB6: -case 0xCEB6: -case 0xC0B7: -case 0xC2B7: -case 0xC4B7: -case 0xC6B7: -case 0xC8B7: -case 0xCAB7: -case 0xCCB7: -case 0xCEB7: - -// ANDaD -case 0xC0B0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(22) -case 0xC2B8: -case 0xC4B8: -case 0xC6B8: -case 0xC8B8: -case 0xCAB8: -case 0xCCB8: -case 0xCEB8: - -// ANDaD -case 0xC0B8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0xC2B9: -case 0xC4B9: -case 0xC6B9: -case 0xC8B9: -case 0xCAB9: -case 0xCCB9: -case 0xCEB9: - -// ANDaD -case 0xC0B9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(24) -case 0xC2BA: -case 0xC4BA: -case 0xC6BA: -case 0xC8BA: -case 0xCABA: -case 0xCCBA: -case 0xCEBA: - -// ANDaD -case 0xC0BA: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0xC2BB: -case 0xC4BB: -case 0xC6BB: -case 0xC8BB: -case 0xCABB: -case 0xCCBB: -case 0xCEBB: - -// ANDaD -case 0xC0BB: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(22) -case 0xC2BC: -case 0xC4BC: -case 0xC6BC: -case 0xC8BC: -case 0xCABC: -case 0xCCBC: -case 0xCEBC: - -// ANDaD -case 0xC0BC: -{ - u32 res; - pointer src; - src = FETCH_LONG; - PC += 4; - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(14) -case 0xC29F: -case 0xC49F: -case 0xC69F: -case 0xC89F: -case 0xCA9F: -case 0xCC9F: -case 0xCE9F: - -// ANDaD -case 0xC09F: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xC2A7: -case 0xC4A7: -case 0xC6A7: -case 0xC8A7: -case 0xCAA7: -case 0xCCA7: -case 0xCEA7: - -// ANDaD -case 0xC0A7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - res = (u32)CPU->D[(Opcode >> 9) & 7]; - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0xC310: -case 0xC510: -case 0xC710: -case 0xC910: -case 0xCB10: -case 0xCD10: -case 0xCF10: -case 0xC111: -case 0xC311: -case 0xC511: -case 0xC711: -case 0xC911: -case 0xCB11: -case 0xCD11: -case 0xCF11: -case 0xC112: -case 0xC312: -case 0xC512: -case 0xC712: -case 0xC912: -case 0xCB12: -case 0xCD12: -case 0xCF12: -case 0xC113: -case 0xC313: -case 0xC513: -case 0xC713: -case 0xC913: -case 0xCB13: -case 0xCD13: -case 0xCF13: -case 0xC114: -case 0xC314: -case 0xC514: -case 0xC714: -case 0xC914: -case 0xCB14: -case 0xCD14: -case 0xCF14: -case 0xC115: -case 0xC315: -case 0xC515: -case 0xC715: -case 0xC915: -case 0xCB15: -case 0xCD15: -case 0xCF15: -case 0xC116: -case 0xC316: -case 0xC516: -case 0xC716: -case 0xC916: -case 0xCB16: -case 0xCD16: -case 0xCF16: -case 0xC117: -case 0xC317: -case 0xC517: -case 0xC717: -case 0xC917: -case 0xCB17: -case 0xCD17: -case 0xCF17: - -// ANDDa -case 0xC110: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xC318: -case 0xC518: -case 0xC718: -case 0xC918: -case 0xCB18: -case 0xCD18: -case 0xCF18: -case 0xC119: -case 0xC319: -case 0xC519: -case 0xC719: -case 0xC919: -case 0xCB19: -case 0xCD19: -case 0xCF19: -case 0xC11A: -case 0xC31A: -case 0xC51A: -case 0xC71A: -case 0xC91A: -case 0xCB1A: -case 0xCD1A: -case 0xCF1A: -case 0xC11B: -case 0xC31B: -case 0xC51B: -case 0xC71B: -case 0xC91B: -case 0xCB1B: -case 0xCD1B: -case 0xCF1B: -case 0xC11C: -case 0xC31C: -case 0xC51C: -case 0xC71C: -case 0xC91C: -case 0xCB1C: -case 0xCD1C: -case 0xCF1C: -case 0xC11D: -case 0xC31D: -case 0xC51D: -case 0xC71D: -case 0xC91D: -case 0xCB1D: -case 0xCD1D: -case 0xCF1D: -case 0xC11E: -case 0xC31E: -case 0xC51E: -case 0xC71E: -case 0xC91E: -case 0xCB1E: -case 0xCD1E: -case 0xCF1E: - -// ANDDa -case 0xC118: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xC320: -case 0xC520: -case 0xC720: -case 0xC920: -case 0xCB20: -case 0xCD20: -case 0xCF20: -case 0xC121: -case 0xC321: -case 0xC521: -case 0xC721: -case 0xC921: -case 0xCB21: -case 0xCD21: -case 0xCF21: -case 0xC122: -case 0xC322: -case 0xC522: -case 0xC722: -case 0xC922: -case 0xCB22: -case 0xCD22: -case 0xCF22: -case 0xC123: -case 0xC323: -case 0xC523: -case 0xC723: -case 0xC923: -case 0xCB23: -case 0xCD23: -case 0xCF23: -case 0xC124: -case 0xC324: -case 0xC524: -case 0xC724: -case 0xC924: -case 0xCB24: -case 0xCD24: -case 0xCF24: -case 0xC125: -case 0xC325: -case 0xC525: -case 0xC725: -case 0xC925: -case 0xCB25: -case 0xCD25: -case 0xCF25: -case 0xC126: -case 0xC326: -case 0xC526: -case 0xC726: -case 0xC926: -case 0xCB26: -case 0xCD26: -case 0xCF26: - -// ANDDa -case 0xC120: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0xC328: -case 0xC528: -case 0xC728: -case 0xC928: -case 0xCB28: -case 0xCD28: -case 0xCF28: -case 0xC129: -case 0xC329: -case 0xC529: -case 0xC729: -case 0xC929: -case 0xCB29: -case 0xCD29: -case 0xCF29: -case 0xC12A: -case 0xC32A: -case 0xC52A: -case 0xC72A: -case 0xC92A: -case 0xCB2A: -case 0xCD2A: -case 0xCF2A: -case 0xC12B: -case 0xC32B: -case 0xC52B: -case 0xC72B: -case 0xC92B: -case 0xCB2B: -case 0xCD2B: -case 0xCF2B: -case 0xC12C: -case 0xC32C: -case 0xC52C: -case 0xC72C: -case 0xC92C: -case 0xCB2C: -case 0xCD2C: -case 0xCF2C: -case 0xC12D: -case 0xC32D: -case 0xC52D: -case 0xC72D: -case 0xC92D: -case 0xCB2D: -case 0xCD2D: -case 0xCF2D: -case 0xC12E: -case 0xC32E: -case 0xC52E: -case 0xC72E: -case 0xC92E: -case 0xCB2E: -case 0xCD2E: -case 0xCF2E: -case 0xC12F: -case 0xC32F: -case 0xC52F: -case 0xC72F: -case 0xC92F: -case 0xCB2F: -case 0xCD2F: -case 0xCF2F: - -// ANDDa -case 0xC128: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0xC330: -case 0xC530: -case 0xC730: -case 0xC930: -case 0xCB30: -case 0xCD30: -case 0xCF30: -case 0xC131: -case 0xC331: -case 0xC531: -case 0xC731: -case 0xC931: -case 0xCB31: -case 0xCD31: -case 0xCF31: -case 0xC132: -case 0xC332: -case 0xC532: -case 0xC732: -case 0xC932: -case 0xCB32: -case 0xCD32: -case 0xCF32: -case 0xC133: -case 0xC333: -case 0xC533: -case 0xC733: -case 0xC933: -case 0xCB33: -case 0xCD33: -case 0xCF33: -case 0xC134: -case 0xC334: -case 0xC534: -case 0xC734: -case 0xC934: -case 0xCB34: -case 0xCD34: -case 0xCF34: -case 0xC135: -case 0xC335: -case 0xC535: -case 0xC735: -case 0xC935: -case 0xCB35: -case 0xCD35: -case 0xCF35: -case 0xC136: -case 0xC336: -case 0xC536: -case 0xC736: -case 0xC936: -case 0xCB36: -case 0xCD36: -case 0xCF36: -case 0xC137: -case 0xC337: -case 0xC537: -case 0xC737: -case 0xC937: -case 0xCB37: -case 0xCD37: -case 0xCF37: - -// ANDDa -case 0xC130: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xC338: -case 0xC538: -case 0xC738: -case 0xC938: -case 0xCB38: -case 0xCD38: -case 0xCF38: - -// ANDDa -case 0xC138: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0xC339: -case 0xC539: -case 0xC739: -case 0xC939: -case 0xCB39: -case 0xCD39: -case 0xCF39: - -// ANDDa -case 0xC139: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0xC31F: -case 0xC51F: -case 0xC71F: -case 0xC91F: -case 0xCB1F: -case 0xCD1F: -case 0xCF1F: - -// ANDDa -case 0xC11F: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xC327: -case 0xC527: -case 0xC727: -case 0xC927: -case 0xCB27: -case 0xCD27: -case 0xCF27: - -// ANDDa -case 0xC127: -{ - u32 adr; - u32 res; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0xC350: -case 0xC550: -case 0xC750: -case 0xC950: -case 0xCB50: -case 0xCD50: -case 0xCF50: -case 0xC151: -case 0xC351: -case 0xC551: -case 0xC751: -case 0xC951: -case 0xCB51: -case 0xCD51: -case 0xCF51: -case 0xC152: -case 0xC352: -case 0xC552: -case 0xC752: -case 0xC952: -case 0xCB52: -case 0xCD52: -case 0xCF52: -case 0xC153: -case 0xC353: -case 0xC553: -case 0xC753: -case 0xC953: -case 0xCB53: -case 0xCD53: -case 0xCF53: -case 0xC154: -case 0xC354: -case 0xC554: -case 0xC754: -case 0xC954: -case 0xCB54: -case 0xCD54: -case 0xCF54: -case 0xC155: -case 0xC355: -case 0xC555: -case 0xC755: -case 0xC955: -case 0xCB55: -case 0xCD55: -case 0xCF55: -case 0xC156: -case 0xC356: -case 0xC556: -case 0xC756: -case 0xC956: -case 0xCB56: -case 0xCD56: -case 0xCF56: -case 0xC157: -case 0xC357: -case 0xC557: -case 0xC757: -case 0xC957: -case 0xCB57: -case 0xCD57: -case 0xCF57: - -// ANDDa -case 0xC150: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xC358: -case 0xC558: -case 0xC758: -case 0xC958: -case 0xCB58: -case 0xCD58: -case 0xCF58: -case 0xC159: -case 0xC359: -case 0xC559: -case 0xC759: -case 0xC959: -case 0xCB59: -case 0xCD59: -case 0xCF59: -case 0xC15A: -case 0xC35A: -case 0xC55A: -case 0xC75A: -case 0xC95A: -case 0xCB5A: -case 0xCD5A: -case 0xCF5A: -case 0xC15B: -case 0xC35B: -case 0xC55B: -case 0xC75B: -case 0xC95B: -case 0xCB5B: -case 0xCD5B: -case 0xCF5B: -case 0xC15C: -case 0xC35C: -case 0xC55C: -case 0xC75C: -case 0xC95C: -case 0xCB5C: -case 0xCD5C: -case 0xCF5C: -case 0xC15D: -case 0xC35D: -case 0xC55D: -case 0xC75D: -case 0xC95D: -case 0xCB5D: -case 0xCD5D: -case 0xCF5D: -case 0xC15E: -case 0xC35E: -case 0xC55E: -case 0xC75E: -case 0xC95E: -case 0xCB5E: -case 0xCD5E: -case 0xCF5E: - -// ANDDa -case 0xC158: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xC360: -case 0xC560: -case 0xC760: -case 0xC960: -case 0xCB60: -case 0xCD60: -case 0xCF60: -case 0xC161: -case 0xC361: -case 0xC561: -case 0xC761: -case 0xC961: -case 0xCB61: -case 0xCD61: -case 0xCF61: -case 0xC162: -case 0xC362: -case 0xC562: -case 0xC762: -case 0xC962: -case 0xCB62: -case 0xCD62: -case 0xCF62: -case 0xC163: -case 0xC363: -case 0xC563: -case 0xC763: -case 0xC963: -case 0xCB63: -case 0xCD63: -case 0xCF63: -case 0xC164: -case 0xC364: -case 0xC564: -case 0xC764: -case 0xC964: -case 0xCB64: -case 0xCD64: -case 0xCF64: -case 0xC165: -case 0xC365: -case 0xC565: -case 0xC765: -case 0xC965: -case 0xCB65: -case 0xCD65: -case 0xCF65: -case 0xC166: -case 0xC366: -case 0xC566: -case 0xC766: -case 0xC966: -case 0xCB66: -case 0xCD66: -case 0xCF66: - -// ANDDa -case 0xC160: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xC368: -case 0xC568: -case 0xC768: -case 0xC968: -case 0xCB68: -case 0xCD68: -case 0xCF68: -case 0xC169: -case 0xC369: -case 0xC569: -case 0xC769: -case 0xC969: -case 0xCB69: -case 0xCD69: -case 0xCF69: -case 0xC16A: -case 0xC36A: -case 0xC56A: -case 0xC76A: -case 0xC96A: -case 0xCB6A: -case 0xCD6A: -case 0xCF6A: -case 0xC16B: -case 0xC36B: -case 0xC56B: -case 0xC76B: -case 0xC96B: -case 0xCB6B: -case 0xCD6B: -case 0xCF6B: -case 0xC16C: -case 0xC36C: -case 0xC56C: -case 0xC76C: -case 0xC96C: -case 0xCB6C: -case 0xCD6C: -case 0xCF6C: -case 0xC16D: -case 0xC36D: -case 0xC56D: -case 0xC76D: -case 0xC96D: -case 0xCB6D: -case 0xCD6D: -case 0xCF6D: -case 0xC16E: -case 0xC36E: -case 0xC56E: -case 0xC76E: -case 0xC96E: -case 0xCB6E: -case 0xCD6E: -case 0xCF6E: -case 0xC16F: -case 0xC36F: -case 0xC56F: -case 0xC76F: -case 0xC96F: -case 0xCB6F: -case 0xCD6F: -case 0xCF6F: - -// ANDDa -case 0xC168: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xC370: -case 0xC570: -case 0xC770: -case 0xC970: -case 0xCB70: -case 0xCD70: -case 0xCF70: -case 0xC171: -case 0xC371: -case 0xC571: -case 0xC771: -case 0xC971: -case 0xCB71: -case 0xCD71: -case 0xCF71: -case 0xC172: -case 0xC372: -case 0xC572: -case 0xC772: -case 0xC972: -case 0xCB72: -case 0xCD72: -case 0xCF72: -case 0xC173: -case 0xC373: -case 0xC573: -case 0xC773: -case 0xC973: -case 0xCB73: -case 0xCD73: -case 0xCF73: -case 0xC174: -case 0xC374: -case 0xC574: -case 0xC774: -case 0xC974: -case 0xCB74: -case 0xCD74: -case 0xCF74: -case 0xC175: -case 0xC375: -case 0xC575: -case 0xC775: -case 0xC975: -case 0xCB75: -case 0xCD75: -case 0xCF75: -case 0xC176: -case 0xC376: -case 0xC576: -case 0xC776: -case 0xC976: -case 0xCB76: -case 0xCD76: -case 0xCF76: -case 0xC177: -case 0xC377: -case 0xC577: -case 0xC777: -case 0xC977: -case 0xCB77: -case 0xCD77: -case 0xCF77: - -// ANDDa -case 0xC170: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0xC378: -case 0xC578: -case 0xC778: -case 0xC978: -case 0xCB78: -case 0xCD78: -case 0xCF78: - -// ANDDa -case 0xC178: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xC379: -case 0xC579: -case 0xC779: -case 0xC979: -case 0xCB79: -case 0xCD79: -case 0xCF79: - -// ANDDa -case 0xC179: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0xC35F: -case 0xC55F: -case 0xC75F: -case 0xC95F: -case 0xCB5F: -case 0xCD5F: -case 0xCF5F: - -// ANDDa -case 0xC15F: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xC367: -case 0xC567: -case 0xC767: -case 0xC967: -case 0xCB67: -case 0xCD67: -case 0xCF67: - -// ANDDa -case 0xC167: -{ - u32 adr; - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 8; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xC390: -case 0xC590: -case 0xC790: -case 0xC990: -case 0xCB90: -case 0xCD90: -case 0xCF90: -case 0xC191: -case 0xC391: -case 0xC591: -case 0xC791: -case 0xC991: -case 0xCB91: -case 0xCD91: -case 0xCF91: -case 0xC192: -case 0xC392: -case 0xC592: -case 0xC792: -case 0xC992: -case 0xCB92: -case 0xCD92: -case 0xCF92: -case 0xC193: -case 0xC393: -case 0xC593: -case 0xC793: -case 0xC993: -case 0xCB93: -case 0xCD93: -case 0xCF93: -case 0xC194: -case 0xC394: -case 0xC594: -case 0xC794: -case 0xC994: -case 0xCB94: -case 0xCD94: -case 0xCF94: -case 0xC195: -case 0xC395: -case 0xC595: -case 0xC795: -case 0xC995: -case 0xCB95: -case 0xCD95: -case 0xCF95: -case 0xC196: -case 0xC396: -case 0xC596: -case 0xC796: -case 0xC996: -case 0xCB96: -case 0xCD96: -case 0xCF96: -case 0xC197: -case 0xC397: -case 0xC597: -case 0xC797: -case 0xC997: -case 0xCB97: -case 0xCD97: -case 0xCF97: - -// ANDDa -case 0xC190: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xC398: -case 0xC598: -case 0xC798: -case 0xC998: -case 0xCB98: -case 0xCD98: -case 0xCF98: -case 0xC199: -case 0xC399: -case 0xC599: -case 0xC799: -case 0xC999: -case 0xCB99: -case 0xCD99: -case 0xCF99: -case 0xC19A: -case 0xC39A: -case 0xC59A: -case 0xC79A: -case 0xC99A: -case 0xCB9A: -case 0xCD9A: -case 0xCF9A: -case 0xC19B: -case 0xC39B: -case 0xC59B: -case 0xC79B: -case 0xC99B: -case 0xCB9B: -case 0xCD9B: -case 0xCF9B: -case 0xC19C: -case 0xC39C: -case 0xC59C: -case 0xC79C: -case 0xC99C: -case 0xCB9C: -case 0xCD9C: -case 0xCF9C: -case 0xC19D: -case 0xC39D: -case 0xC59D: -case 0xC79D: -case 0xC99D: -case 0xCB9D: -case 0xCD9D: -case 0xCF9D: -case 0xC19E: -case 0xC39E: -case 0xC59E: -case 0xC79E: -case 0xC99E: -case 0xCB9E: -case 0xCD9E: -case 0xCF9E: - -// ANDDa -case 0xC198: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xC3A0: -case 0xC5A0: -case 0xC7A0: -case 0xC9A0: -case 0xCBA0: -case 0xCDA0: -case 0xCFA0: -case 0xC1A1: -case 0xC3A1: -case 0xC5A1: -case 0xC7A1: -case 0xC9A1: -case 0xCBA1: -case 0xCDA1: -case 0xCFA1: -case 0xC1A2: -case 0xC3A2: -case 0xC5A2: -case 0xC7A2: -case 0xC9A2: -case 0xCBA2: -case 0xCDA2: -case 0xCFA2: -case 0xC1A3: -case 0xC3A3: -case 0xC5A3: -case 0xC7A3: -case 0xC9A3: -case 0xCBA3: -case 0xCDA3: -case 0xCFA3: -case 0xC1A4: -case 0xC3A4: -case 0xC5A4: -case 0xC7A4: -case 0xC9A4: -case 0xCBA4: -case 0xCDA4: -case 0xCFA4: -case 0xC1A5: -case 0xC3A5: -case 0xC5A5: -case 0xC7A5: -case 0xC9A5: -case 0xCBA5: -case 0xCDA5: -case 0xCFA5: -case 0xC1A6: -case 0xC3A6: -case 0xC5A6: -case 0xC7A6: -case 0xC9A6: -case 0xCBA6: -case 0xCDA6: -case 0xCFA6: - -// ANDDa -case 0xC1A0: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0xC3A8: -case 0xC5A8: -case 0xC7A8: -case 0xC9A8: -case 0xCBA8: -case 0xCDA8: -case 0xCFA8: -case 0xC1A9: -case 0xC3A9: -case 0xC5A9: -case 0xC7A9: -case 0xC9A9: -case 0xCBA9: -case 0xCDA9: -case 0xCFA9: -case 0xC1AA: -case 0xC3AA: -case 0xC5AA: -case 0xC7AA: -case 0xC9AA: -case 0xCBAA: -case 0xCDAA: -case 0xCFAA: -case 0xC1AB: -case 0xC3AB: -case 0xC5AB: -case 0xC7AB: -case 0xC9AB: -case 0xCBAB: -case 0xCDAB: -case 0xCFAB: -case 0xC1AC: -case 0xC3AC: -case 0xC5AC: -case 0xC7AC: -case 0xC9AC: -case 0xCBAC: -case 0xCDAC: -case 0xCFAC: -case 0xC1AD: -case 0xC3AD: -case 0xC5AD: -case 0xC7AD: -case 0xC9AD: -case 0xCBAD: -case 0xCDAD: -case 0xCFAD: -case 0xC1AE: -case 0xC3AE: -case 0xC5AE: -case 0xC7AE: -case 0xC9AE: -case 0xCBAE: -case 0xCDAE: -case 0xCFAE: -case 0xC1AF: -case 0xC3AF: -case 0xC5AF: -case 0xC7AF: -case 0xC9AF: -case 0xCBAF: -case 0xCDAF: -case 0xCFAF: - -// ANDDa -case 0xC1A8: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0xC3B0: -case 0xC5B0: -case 0xC7B0: -case 0xC9B0: -case 0xCBB0: -case 0xCDB0: -case 0xCFB0: -case 0xC1B1: -case 0xC3B1: -case 0xC5B1: -case 0xC7B1: -case 0xC9B1: -case 0xCBB1: -case 0xCDB1: -case 0xCFB1: -case 0xC1B2: -case 0xC3B2: -case 0xC5B2: -case 0xC7B2: -case 0xC9B2: -case 0xCBB2: -case 0xCDB2: -case 0xCFB2: -case 0xC1B3: -case 0xC3B3: -case 0xC5B3: -case 0xC7B3: -case 0xC9B3: -case 0xCBB3: -case 0xCDB3: -case 0xCFB3: -case 0xC1B4: -case 0xC3B4: -case 0xC5B4: -case 0xC7B4: -case 0xC9B4: -case 0xCBB4: -case 0xCDB4: -case 0xCFB4: -case 0xC1B5: -case 0xC3B5: -case 0xC5B5: -case 0xC7B5: -case 0xC9B5: -case 0xCBB5: -case 0xCDB5: -case 0xCFB5: -case 0xC1B6: -case 0xC3B6: -case 0xC5B6: -case 0xC7B6: -case 0xC9B6: -case 0xCBB6: -case 0xCDB6: -case 0xCFB6: -case 0xC1B7: -case 0xC3B7: -case 0xC5B7: -case 0xC7B7: -case 0xC9B7: -case 0xCBB7: -case 0xCDB7: -case 0xCFB7: - -// ANDDa -case 0xC1B0: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0xC3B8: -case 0xC5B8: -case 0xC7B8: -case 0xC9B8: -case 0xCBB8: -case 0xCDB8: -case 0xCFB8: - -// ANDDa -case 0xC1B8: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0xC3B9: -case 0xC5B9: -case 0xC7B9: -case 0xC9B9: -case 0xCBB9: -case 0xCDB9: -case 0xCFB9: - -// ANDDa -case 0xC1B9: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0xC39F: -case 0xC59F: -case 0xC79F: -case 0xC99F: -case 0xCB9F: -case 0xCD9F: -case 0xCF9F: - -// ANDDa -case 0xC19F: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xC3A7: -case 0xC5A7: -case 0xC7A7: -case 0xC9A7: -case 0xCBA7: -case 0xCDA7: -case 0xCFA7: - -// ANDDa -case 0xC1A7: -{ - u32 adr; - u32 res; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, res) - res &= src; - CPU->flag_C = 0; - CPU->flag_V = 0; - CPU->flag_notZ = res; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0xC300: -case 0xC500: -case 0xC700: -case 0xC900: -case 0xCB00: -case 0xCD00: -case 0xCF00: -case 0xC101: -case 0xC301: -case 0xC501: -case 0xC701: -case 0xC901: -case 0xCB01: -case 0xCD01: -case 0xCF01: -case 0xC102: -case 0xC302: -case 0xC502: -case 0xC702: -case 0xC902: -case 0xCB02: -case 0xCD02: -case 0xCF02: -case 0xC103: -case 0xC303: -case 0xC503: -case 0xC703: -case 0xC903: -case 0xCB03: -case 0xCD03: -case 0xCF03: -case 0xC104: -case 0xC304: -case 0xC504: -case 0xC704: -case 0xC904: -case 0xCB04: -case 0xCD04: -case 0xCF04: -case 0xC105: -case 0xC305: -case 0xC505: -case 0xC705: -case 0xC905: -case 0xCB05: -case 0xCD05: -case 0xCF05: -case 0xC106: -case 0xC306: -case 0xC506: -case 0xC706: -case 0xC906: -case 0xCB06: -case 0xCD06: -case 0xCF06: -case 0xC107: -case 0xC307: -case 0xC507: -case 0xC707: -case 0xC907: -case 0xCB07: -case 0xCD07: -case 0xCF07: - -// ABCD -case 0xC100: -{ - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = (dst & 0xF) + (src & 0xF) + ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res += 6; - res += (dst & 0xF0) + (src & 0xF0); - if (res > 0x99) - { - res -= 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(6) -case 0xC308: -case 0xC508: -case 0xC708: -case 0xC908: -case 0xCB08: -case 0xCD08: -case 0xC109: -case 0xC309: -case 0xC509: -case 0xC709: -case 0xC909: -case 0xCB09: -case 0xCD09: -case 0xC10A: -case 0xC30A: -case 0xC50A: -case 0xC70A: -case 0xC90A: -case 0xCB0A: -case 0xCD0A: -case 0xC10B: -case 0xC30B: -case 0xC50B: -case 0xC70B: -case 0xC90B: -case 0xCB0B: -case 0xCD0B: -case 0xC10C: -case 0xC30C: -case 0xC50C: -case 0xC70C: -case 0xC90C: -case 0xCB0C: -case 0xCD0C: -case 0xC10D: -case 0xC30D: -case 0xC50D: -case 0xC70D: -case 0xC90D: -case 0xCB0D: -case 0xCD0D: -case 0xC10E: -case 0xC30E: -case 0xC50E: -case 0xC70E: -case 0xC90E: -case 0xCB0E: -case 0xCD0E: - -// ABCDM -case 0xC108: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_BYTE_F(adr, dst) - res = (dst & 0xF) + (src & 0xF) + ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res += 6; - res += (dst & 0xF0) + (src & 0xF0); - if (res > 0x99) - { - res -= 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xC30F: -case 0xC50F: -case 0xC70F: -case 0xC90F: -case 0xCB0F: -case 0xCD0F: - -// ABCD7M -case 0xC10F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_BYTE_F(adr, dst) - res = (dst & 0xF) + (src & 0xF) + ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res += 6; - res += (dst & 0xF0) + (src & 0xF0); - if (res > 0x99) - { - res -= 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xCF09: -case 0xCF0A: -case 0xCF0B: -case 0xCF0C: -case 0xCF0D: -case 0xCF0E: - -// ABCDM7 -case 0xCF08: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_BYTE_F(adr, dst) - res = (dst & 0xF) + (src & 0xF) + ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res += 6; - res += (dst & 0xF0) + (src & 0xF0); - if (res > 0x99) - { - res -= 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// ABCD7M7 -case 0xCF0F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_BYTE_F(adr, dst) - res = (dst & 0xF) + (src & 0xF) + ((CPU->flag_X >> C68K_SR_X_SFT) & 1); - if (res > 9) res += 6; - res += (dst & 0xF0) + (src & 0xF0); - if (res > 0x99) - { - res -= 0xA0; - CPU->flag_X = CPU->flag_C = C68K_SR_C; - } - else CPU->flag_X = CPU->flag_C = 0; - CPU->flag_notZ |= res & 0xFF; - CPU->flag_N = res; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xC2C0: -case 0xC4C0: -case 0xC6C0: -case 0xC8C0: -case 0xCAC0: -case 0xCCC0: -case 0xCEC0: -case 0xC0C1: -case 0xC2C1: -case 0xC4C1: -case 0xC6C1: -case 0xC8C1: -case 0xCAC1: -case 0xCCC1: -case 0xCEC1: -case 0xC0C2: -case 0xC2C2: -case 0xC4C2: -case 0xC6C2: -case 0xC8C2: -case 0xCAC2: -case 0xCCC2: -case 0xCEC2: -case 0xC0C3: -case 0xC2C3: -case 0xC4C3: -case 0xC6C3: -case 0xC8C3: -case 0xCAC3: -case 0xCCC3: -case 0xCEC3: -case 0xC0C4: -case 0xC2C4: -case 0xC4C4: -case 0xC6C4: -case 0xC8C4: -case 0xCAC4: -case 0xCCC4: -case 0xCEC4: -case 0xC0C5: -case 0xC2C5: -case 0xC4C5: -case 0xC6C5: -case 0xC8C5: -case 0xCAC5: -case 0xCCC5: -case 0xCEC5: -case 0xC0C6: -case 0xC2C6: -case 0xC4C6: -case 0xC6C6: -case 0xC8C6: -case 0xCAC6: -case 0xCCC6: -case 0xCEC6: -case 0xC0C7: -case 0xC2C7: -case 0xC4C7: -case 0xC6C7: -case 0xC8C7: -case 0xCAC7: -case 0xCCC7: -case 0xCEC7: - -// MULU -case 0xC0C0: -{ - u32 res; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(50) -case 0xC2D0: -case 0xC4D0: -case 0xC6D0: -case 0xC8D0: -case 0xCAD0: -case 0xCCD0: -case 0xCED0: -case 0xC0D1: -case 0xC2D1: -case 0xC4D1: -case 0xC6D1: -case 0xC8D1: -case 0xCAD1: -case 0xCCD1: -case 0xCED1: -case 0xC0D2: -case 0xC2D2: -case 0xC4D2: -case 0xC6D2: -case 0xC8D2: -case 0xCAD2: -case 0xCCD2: -case 0xCED2: -case 0xC0D3: -case 0xC2D3: -case 0xC4D3: -case 0xC6D3: -case 0xC8D3: -case 0xCAD3: -case 0xCCD3: -case 0xCED3: -case 0xC0D4: -case 0xC2D4: -case 0xC4D4: -case 0xC6D4: -case 0xC8D4: -case 0xCAD4: -case 0xCCD4: -case 0xCED4: -case 0xC0D5: -case 0xC2D5: -case 0xC4D5: -case 0xC6D5: -case 0xC8D5: -case 0xCAD5: -case 0xCCD5: -case 0xCED5: -case 0xC0D6: -case 0xC2D6: -case 0xC4D6: -case 0xC6D6: -case 0xC8D6: -case 0xCAD6: -case 0xCCD6: -case 0xCED6: -case 0xC0D7: -case 0xC2D7: -case 0xC4D7: -case 0xC6D7: -case 0xC8D7: -case 0xCAD7: -case 0xCCD7: -case 0xCED7: - -// MULU -case 0xC0D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(54) -case 0xC2D8: -case 0xC4D8: -case 0xC6D8: -case 0xC8D8: -case 0xCAD8: -case 0xCCD8: -case 0xCED8: -case 0xC0D9: -case 0xC2D9: -case 0xC4D9: -case 0xC6D9: -case 0xC8D9: -case 0xCAD9: -case 0xCCD9: -case 0xCED9: -case 0xC0DA: -case 0xC2DA: -case 0xC4DA: -case 0xC6DA: -case 0xC8DA: -case 0xCADA: -case 0xCCDA: -case 0xCEDA: -case 0xC0DB: -case 0xC2DB: -case 0xC4DB: -case 0xC6DB: -case 0xC8DB: -case 0xCADB: -case 0xCCDB: -case 0xCEDB: -case 0xC0DC: -case 0xC2DC: -case 0xC4DC: -case 0xC6DC: -case 0xC8DC: -case 0xCADC: -case 0xCCDC: -case 0xCEDC: -case 0xC0DD: -case 0xC2DD: -case 0xC4DD: -case 0xC6DD: -case 0xC8DD: -case 0xCADD: -case 0xCCDD: -case 0xCEDD: -case 0xC0DE: -case 0xC2DE: -case 0xC4DE: -case 0xC6DE: -case 0xC8DE: -case 0xCADE: -case 0xCCDE: -case 0xCEDE: - -// MULU -case 0xC0D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(54) -case 0xC2E0: -case 0xC4E0: -case 0xC6E0: -case 0xC8E0: -case 0xCAE0: -case 0xCCE0: -case 0xCEE0: -case 0xC0E1: -case 0xC2E1: -case 0xC4E1: -case 0xC6E1: -case 0xC8E1: -case 0xCAE1: -case 0xCCE1: -case 0xCEE1: -case 0xC0E2: -case 0xC2E2: -case 0xC4E2: -case 0xC6E2: -case 0xC8E2: -case 0xCAE2: -case 0xCCE2: -case 0xCEE2: -case 0xC0E3: -case 0xC2E3: -case 0xC4E3: -case 0xC6E3: -case 0xC8E3: -case 0xCAE3: -case 0xCCE3: -case 0xCEE3: -case 0xC0E4: -case 0xC2E4: -case 0xC4E4: -case 0xC6E4: -case 0xC8E4: -case 0xCAE4: -case 0xCCE4: -case 0xCEE4: -case 0xC0E5: -case 0xC2E5: -case 0xC4E5: -case 0xC6E5: -case 0xC8E5: -case 0xCAE5: -case 0xCCE5: -case 0xCEE5: -case 0xC0E6: -case 0xC2E6: -case 0xC4E6: -case 0xC6E6: -case 0xC8E6: -case 0xCAE6: -case 0xCCE6: -case 0xCEE6: - -// MULU -case 0xC0E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(56) -case 0xC2E8: -case 0xC4E8: -case 0xC6E8: -case 0xC8E8: -case 0xCAE8: -case 0xCCE8: -case 0xCEE8: -case 0xC0E9: -case 0xC2E9: -case 0xC4E9: -case 0xC6E9: -case 0xC8E9: -case 0xCAE9: -case 0xCCE9: -case 0xCEE9: -case 0xC0EA: -case 0xC2EA: -case 0xC4EA: -case 0xC6EA: -case 0xC8EA: -case 0xCAEA: -case 0xCCEA: -case 0xCEEA: -case 0xC0EB: -case 0xC2EB: -case 0xC4EB: -case 0xC6EB: -case 0xC8EB: -case 0xCAEB: -case 0xCCEB: -case 0xCEEB: -case 0xC0EC: -case 0xC2EC: -case 0xC4EC: -case 0xC6EC: -case 0xC8EC: -case 0xCAEC: -case 0xCCEC: -case 0xCEEC: -case 0xC0ED: -case 0xC2ED: -case 0xC4ED: -case 0xC6ED: -case 0xC8ED: -case 0xCAED: -case 0xCCED: -case 0xCEED: -case 0xC0EE: -case 0xC2EE: -case 0xC4EE: -case 0xC6EE: -case 0xC8EE: -case 0xCAEE: -case 0xCCEE: -case 0xCEEE: -case 0xC0EF: -case 0xC2EF: -case 0xC4EF: -case 0xC6EF: -case 0xC8EF: -case 0xCAEF: -case 0xCCEF: -case 0xCEEF: - -// MULU -case 0xC0E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(58) -case 0xC2F0: -case 0xC4F0: -case 0xC6F0: -case 0xC8F0: -case 0xCAF0: -case 0xCCF0: -case 0xCEF0: -case 0xC0F1: -case 0xC2F1: -case 0xC4F1: -case 0xC6F1: -case 0xC8F1: -case 0xCAF1: -case 0xCCF1: -case 0xCEF1: -case 0xC0F2: -case 0xC2F2: -case 0xC4F2: -case 0xC6F2: -case 0xC8F2: -case 0xCAF2: -case 0xCCF2: -case 0xCEF2: -case 0xC0F3: -case 0xC2F3: -case 0xC4F3: -case 0xC6F3: -case 0xC8F3: -case 0xCAF3: -case 0xCCF3: -case 0xCEF3: -case 0xC0F4: -case 0xC2F4: -case 0xC4F4: -case 0xC6F4: -case 0xC8F4: -case 0xCAF4: -case 0xCCF4: -case 0xCEF4: -case 0xC0F5: -case 0xC2F5: -case 0xC4F5: -case 0xC6F5: -case 0xC8F5: -case 0xCAF5: -case 0xCCF5: -case 0xCEF5: -case 0xC0F6: -case 0xC2F6: -case 0xC4F6: -case 0xC6F6: -case 0xC8F6: -case 0xCAF6: -case 0xCCF6: -case 0xCEF6: -case 0xC0F7: -case 0xC2F7: -case 0xC4F7: -case 0xC6F7: -case 0xC8F7: -case 0xCAF7: -case 0xCCF7: -case 0xCEF7: - -// MULU -case 0xC0F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(60) -case 0xC2F8: -case 0xC4F8: -case 0xC6F8: -case 0xC8F8: -case 0xCAF8: -case 0xCCF8: -case 0xCEF8: - -// MULU -case 0xC0F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(58) -case 0xC2F9: -case 0xC4F9: -case 0xC6F9: -case 0xC8F9: -case 0xCAF9: -case 0xCCF9: -case 0xCEF9: - -// MULU -case 0xC0F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(62) -case 0xC2FA: -case 0xC4FA: -case 0xC6FA: -case 0xC8FA: -case 0xCAFA: -case 0xCCFA: -case 0xCEFA: - -// MULU -case 0xC0FA: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(58) -case 0xC2FB: -case 0xC4FB: -case 0xC6FB: -case 0xC8FB: -case 0xCAFB: -case 0xCCFB: -case 0xCEFB: - -// MULU -case 0xC0FB: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(60) -case 0xC2FC: -case 0xC4FC: -case 0xC6FC: -case 0xC8FC: -case 0xCAFC: -case 0xCCFC: -case 0xCEFC: - -// MULU -case 0xC0FC: -{ - u32 res; - pointer src; - src = FETCH_WORD; - PC += 2; - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(54) -case 0xC2DF: -case 0xC4DF: -case 0xC6DF: -case 0xC8DF: -case 0xCADF: -case 0xCCDF: -case 0xCEDF: - -// MULU -case 0xC0DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(54) -case 0xC2E7: -case 0xC4E7: -case 0xC6E7: -case 0xC8E7: -case 0xCAE7: -case 0xCCE7: -case 0xCEE7: - -// MULU -case 0xC0E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - res = (u16)CPU->D[(Opcode >> 9) & 7]; - res *= src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(56) -case 0xC3C0: -case 0xC5C0: -case 0xC7C0: -case 0xC9C0: -case 0xCBC0: -case 0xCDC0: -case 0xCFC0: -case 0xC1C1: -case 0xC3C1: -case 0xC5C1: -case 0xC7C1: -case 0xC9C1: -case 0xCBC1: -case 0xCDC1: -case 0xCFC1: -case 0xC1C2: -case 0xC3C2: -case 0xC5C2: -case 0xC7C2: -case 0xC9C2: -case 0xCBC2: -case 0xCDC2: -case 0xCFC2: -case 0xC1C3: -case 0xC3C3: -case 0xC5C3: -case 0xC7C3: -case 0xC9C3: -case 0xCBC3: -case 0xCDC3: -case 0xCFC3: -case 0xC1C4: -case 0xC3C4: -case 0xC5C4: -case 0xC7C4: -case 0xC9C4: -case 0xCBC4: -case 0xCDC4: -case 0xCFC4: -case 0xC1C5: -case 0xC3C5: -case 0xC5C5: -case 0xC7C5: -case 0xC9C5: -case 0xCBC5: -case 0xCDC5: -case 0xCFC5: -case 0xC1C6: -case 0xC3C6: -case 0xC5C6: -case 0xC7C6: -case 0xC9C6: -case 0xCBC6: -case 0xCDC6: -case 0xCFC6: -case 0xC1C7: -case 0xC3C7: -case 0xC5C7: -case 0xC7C7: -case 0xC9C7: -case 0xCBC7: -case 0xCDC7: -case 0xCFC7: - -// MULS -case 0xC1C0: -{ - u32 res; - pointer src; - src = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(50) -case 0xC3D0: -case 0xC5D0: -case 0xC7D0: -case 0xC9D0: -case 0xCBD0: -case 0xCDD0: -case 0xCFD0: -case 0xC1D1: -case 0xC3D1: -case 0xC5D1: -case 0xC7D1: -case 0xC9D1: -case 0xCBD1: -case 0xCDD1: -case 0xCFD1: -case 0xC1D2: -case 0xC3D2: -case 0xC5D2: -case 0xC7D2: -case 0xC9D2: -case 0xCBD2: -case 0xCDD2: -case 0xCFD2: -case 0xC1D3: -case 0xC3D3: -case 0xC5D3: -case 0xC7D3: -case 0xC9D3: -case 0xCBD3: -case 0xCDD3: -case 0xCFD3: -case 0xC1D4: -case 0xC3D4: -case 0xC5D4: -case 0xC7D4: -case 0xC9D4: -case 0xCBD4: -case 0xCDD4: -case 0xCFD4: -case 0xC1D5: -case 0xC3D5: -case 0xC5D5: -case 0xC7D5: -case 0xC9D5: -case 0xCBD5: -case 0xCDD5: -case 0xCFD5: -case 0xC1D6: -case 0xC3D6: -case 0xC5D6: -case 0xC7D6: -case 0xC9D6: -case 0xCBD6: -case 0xCDD6: -case 0xCFD6: -case 0xC1D7: -case 0xC3D7: -case 0xC5D7: -case 0xC7D7: -case 0xC9D7: -case 0xCBD7: -case 0xCDD7: -case 0xCFD7: - -// MULS -case 0xC1D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(54) -case 0xC3D8: -case 0xC5D8: -case 0xC7D8: -case 0xC9D8: -case 0xCBD8: -case 0xCDD8: -case 0xCFD8: -case 0xC1D9: -case 0xC3D9: -case 0xC5D9: -case 0xC7D9: -case 0xC9D9: -case 0xCBD9: -case 0xCDD9: -case 0xCFD9: -case 0xC1DA: -case 0xC3DA: -case 0xC5DA: -case 0xC7DA: -case 0xC9DA: -case 0xCBDA: -case 0xCDDA: -case 0xCFDA: -case 0xC1DB: -case 0xC3DB: -case 0xC5DB: -case 0xC7DB: -case 0xC9DB: -case 0xCBDB: -case 0xCDDB: -case 0xCFDB: -case 0xC1DC: -case 0xC3DC: -case 0xC5DC: -case 0xC7DC: -case 0xC9DC: -case 0xCBDC: -case 0xCDDC: -case 0xCFDC: -case 0xC1DD: -case 0xC3DD: -case 0xC5DD: -case 0xC7DD: -case 0xC9DD: -case 0xCBDD: -case 0xCDDD: -case 0xCFDD: -case 0xC1DE: -case 0xC3DE: -case 0xC5DE: -case 0xC7DE: -case 0xC9DE: -case 0xCBDE: -case 0xCDDE: -case 0xCFDE: - -// MULS -case 0xC1D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(54) -case 0xC3E0: -case 0xC5E0: -case 0xC7E0: -case 0xC9E0: -case 0xCBE0: -case 0xCDE0: -case 0xCFE0: -case 0xC1E1: -case 0xC3E1: -case 0xC5E1: -case 0xC7E1: -case 0xC9E1: -case 0xCBE1: -case 0xCDE1: -case 0xCFE1: -case 0xC1E2: -case 0xC3E2: -case 0xC5E2: -case 0xC7E2: -case 0xC9E2: -case 0xCBE2: -case 0xCDE2: -case 0xCFE2: -case 0xC1E3: -case 0xC3E3: -case 0xC5E3: -case 0xC7E3: -case 0xC9E3: -case 0xCBE3: -case 0xCDE3: -case 0xCFE3: -case 0xC1E4: -case 0xC3E4: -case 0xC5E4: -case 0xC7E4: -case 0xC9E4: -case 0xCBE4: -case 0xCDE4: -case 0xCFE4: -case 0xC1E5: -case 0xC3E5: -case 0xC5E5: -case 0xC7E5: -case 0xC9E5: -case 0xCBE5: -case 0xCDE5: -case 0xCFE5: -case 0xC1E6: -case 0xC3E6: -case 0xC5E6: -case 0xC7E6: -case 0xC9E6: -case 0xCBE6: -case 0xCDE6: -case 0xCFE6: - -// MULS -case 0xC1E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(56) -case 0xC3E8: -case 0xC5E8: -case 0xC7E8: -case 0xC9E8: -case 0xCBE8: -case 0xCDE8: -case 0xCFE8: -case 0xC1E9: -case 0xC3E9: -case 0xC5E9: -case 0xC7E9: -case 0xC9E9: -case 0xCBE9: -case 0xCDE9: -case 0xCFE9: -case 0xC1EA: -case 0xC3EA: -case 0xC5EA: -case 0xC7EA: -case 0xC9EA: -case 0xCBEA: -case 0xCDEA: -case 0xCFEA: -case 0xC1EB: -case 0xC3EB: -case 0xC5EB: -case 0xC7EB: -case 0xC9EB: -case 0xCBEB: -case 0xCDEB: -case 0xCFEB: -case 0xC1EC: -case 0xC3EC: -case 0xC5EC: -case 0xC7EC: -case 0xC9EC: -case 0xCBEC: -case 0xCDEC: -case 0xCFEC: -case 0xC1ED: -case 0xC3ED: -case 0xC5ED: -case 0xC7ED: -case 0xC9ED: -case 0xCBED: -case 0xCDED: -case 0xCFED: -case 0xC1EE: -case 0xC3EE: -case 0xC5EE: -case 0xC7EE: -case 0xC9EE: -case 0xCBEE: -case 0xCDEE: -case 0xCFEE: -case 0xC1EF: -case 0xC3EF: -case 0xC5EF: -case 0xC7EF: -case 0xC9EF: -case 0xCBEF: -case 0xCDEF: -case 0xCFEF: - -// MULS -case 0xC1E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(58) -case 0xC3F0: -case 0xC5F0: -case 0xC7F0: -case 0xC9F0: -case 0xCBF0: -case 0xCDF0: -case 0xCFF0: -case 0xC1F1: -case 0xC3F1: -case 0xC5F1: -case 0xC7F1: -case 0xC9F1: -case 0xCBF1: -case 0xCDF1: -case 0xCFF1: -case 0xC1F2: -case 0xC3F2: -case 0xC5F2: -case 0xC7F2: -case 0xC9F2: -case 0xCBF2: -case 0xCDF2: -case 0xCFF2: -case 0xC1F3: -case 0xC3F3: -case 0xC5F3: -case 0xC7F3: -case 0xC9F3: -case 0xCBF3: -case 0xCDF3: -case 0xCFF3: -case 0xC1F4: -case 0xC3F4: -case 0xC5F4: -case 0xC7F4: -case 0xC9F4: -case 0xCBF4: -case 0xCDF4: -case 0xCFF4: -case 0xC1F5: -case 0xC3F5: -case 0xC5F5: -case 0xC7F5: -case 0xC9F5: -case 0xCBF5: -case 0xCDF5: -case 0xCFF5: -case 0xC1F6: -case 0xC3F6: -case 0xC5F6: -case 0xC7F6: -case 0xC9F6: -case 0xCBF6: -case 0xCDF6: -case 0xCFF6: -case 0xC1F7: -case 0xC3F7: -case 0xC5F7: -case 0xC7F7: -case 0xC9F7: -case 0xCBF7: -case 0xCDF7: -case 0xCFF7: - -// MULS -case 0xC1F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(60) -case 0xC3F8: -case 0xC5F8: -case 0xC7F8: -case 0xC9F8: -case 0xCBF8: -case 0xCDF8: -case 0xCFF8: - -// MULS -case 0xC1F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(58) -case 0xC3F9: -case 0xC5F9: -case 0xC7F9: -case 0xC9F9: -case 0xCBF9: -case 0xCDF9: -case 0xCFF9: - -// MULS -case 0xC1F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(62) -case 0xC3FA: -case 0xC5FA: -case 0xC7FA: -case 0xC9FA: -case 0xCBFA: -case 0xCDFA: -case 0xCFFA: - -// MULS -case 0xC1FA: -{ - u32 adr; - u32 res; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(58) -case 0xC3FB: -case 0xC5FB: -case 0xC7FB: -case 0xC9FB: -case 0xCBFB: -case 0xCDFB: -case 0xCFFB: - -// MULS -case 0xC1FB: -{ - u32 adr; - u32 res; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(60) -case 0xC3FC: -case 0xC5FC: -case 0xC7FC: -case 0xC9FC: -case 0xCBFC: -case 0xCDFC: -case 0xCFFC: - -// MULS -case 0xC1FC: -{ - u32 res; - pointer src; - src = (s32)(s16)FETCH_WORD; - PC += 2; - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(54) -case 0xC3DF: -case 0xC5DF: -case 0xC7DF: -case 0xC9DF: -case 0xCBDF: -case 0xCDDF: -case 0xCFDF: - -// MULS -case 0xC1DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(54) -case 0xC3E7: -case 0xC5E7: -case 0xC7E7: -case 0xC9E7: -case 0xCBE7: -case 0xCDE7: -case 0xCFE7: - -// MULS -case 0xC1E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - res = (s32)(s16)CPU->D[(Opcode >> 9) & 7]; - res *= (s32)src; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - CPU->flag_V = CPU->flag_C = 0; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(56) -case 0xC340: -case 0xC540: -case 0xC740: -case 0xC940: -case 0xCB40: -case 0xCD40: -case 0xCF40: -case 0xC141: -case 0xC341: -case 0xC541: -case 0xC741: -case 0xC941: -case 0xCB41: -case 0xCD41: -case 0xCF41: -case 0xC142: -case 0xC342: -case 0xC542: -case 0xC742: -case 0xC942: -case 0xCB42: -case 0xCD42: -case 0xCF42: -case 0xC143: -case 0xC343: -case 0xC543: -case 0xC743: -case 0xC943: -case 0xCB43: -case 0xCD43: -case 0xCF43: -case 0xC144: -case 0xC344: -case 0xC544: -case 0xC744: -case 0xC944: -case 0xCB44: -case 0xCD44: -case 0xCF44: -case 0xC145: -case 0xC345: -case 0xC545: -case 0xC745: -case 0xC945: -case 0xCB45: -case 0xCD45: -case 0xCF45: -case 0xC146: -case 0xC346: -case 0xC546: -case 0xC746: -case 0xC946: -case 0xCB46: -case 0xCD46: -case 0xCF46: -case 0xC147: -case 0xC347: -case 0xC547: -case 0xC747: -case 0xC947: -case 0xCB47: -case 0xCD47: -case 0xCF47: - -// EXGDD -case 0xC140: -{ - u32 res; - pointer src; - res = (u32)CPU->D[(Opcode >> 0) & 7]; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - res = src; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xC348: -case 0xC548: -case 0xC748: -case 0xC948: -case 0xCB48: -case 0xCD48: -case 0xCF48: -case 0xC149: -case 0xC349: -case 0xC549: -case 0xC749: -case 0xC949: -case 0xCB49: -case 0xCD49: -case 0xCF49: -case 0xC14A: -case 0xC34A: -case 0xC54A: -case 0xC74A: -case 0xC94A: -case 0xCB4A: -case 0xCD4A: -case 0xCF4A: -case 0xC14B: -case 0xC34B: -case 0xC54B: -case 0xC74B: -case 0xC94B: -case 0xCB4B: -case 0xCD4B: -case 0xCF4B: -case 0xC14C: -case 0xC34C: -case 0xC54C: -case 0xC74C: -case 0xC94C: -case 0xCB4C: -case 0xCD4C: -case 0xCF4C: -case 0xC14D: -case 0xC34D: -case 0xC54D: -case 0xC74D: -case 0xC94D: -case 0xCB4D: -case 0xCD4D: -case 0xCF4D: -case 0xC14E: -case 0xC34E: -case 0xC54E: -case 0xC74E: -case 0xC94E: -case 0xCB4E: -case 0xCD4E: -case 0xCF4E: -case 0xC14F: -case 0xC34F: -case 0xC54F: -case 0xC74F: -case 0xC94F: -case 0xCB4F: -case 0xCD4F: -case 0xCF4F: - -// EXGAA -case 0xC148: -{ - u32 res; - pointer src; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - src = (u32)CPU->A[(Opcode >> 9) & 7]; - CPU->A[(Opcode >> 9) & 7] = res; - res = src; - CPU->A[(Opcode >> 0) & 7] = res; -} -RET(6) -case 0xC388: -case 0xC588: -case 0xC788: -case 0xC988: -case 0xCB88: -case 0xCD88: -case 0xCF88: -case 0xC189: -case 0xC389: -case 0xC589: -case 0xC789: -case 0xC989: -case 0xCB89: -case 0xCD89: -case 0xCF89: -case 0xC18A: -case 0xC38A: -case 0xC58A: -case 0xC78A: -case 0xC98A: -case 0xCB8A: -case 0xCD8A: -case 0xCF8A: -case 0xC18B: -case 0xC38B: -case 0xC58B: -case 0xC78B: -case 0xC98B: -case 0xCB8B: -case 0xCD8B: -case 0xCF8B: -case 0xC18C: -case 0xC38C: -case 0xC58C: -case 0xC78C: -case 0xC98C: -case 0xCB8C: -case 0xCD8C: -case 0xCF8C: -case 0xC18D: -case 0xC38D: -case 0xC58D: -case 0xC78D: -case 0xC98D: -case 0xCB8D: -case 0xCD8D: -case 0xCF8D: -case 0xC18E: -case 0xC38E: -case 0xC58E: -case 0xC78E: -case 0xC98E: -case 0xCB8E: -case 0xCD8E: -case 0xCF8E: -case 0xC18F: -case 0xC38F: -case 0xC58F: -case 0xC78F: -case 0xC98F: -case 0xCB8F: -case 0xCD8F: -case 0xCF8F: - -// EXGAD -case 0xC188: -{ - u32 res; - pointer src; - res = (u32)CPU->A[(Opcode >> 0) & 7]; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - res = src; - CPU->A[(Opcode >> 0) & 7] = res; -} -RET(6) diff --git a/yabause/src/c68k/c68k_opD.inc b/yabause/src/c68k/c68k_opD.inc deleted file mode 100644 index af269730e8..0000000000 --- a/yabause/src/c68k/c68k_opD.inc +++ /dev/null @@ -1,5950 +0,0 @@ -case 0xD200: -case 0xD400: -case 0xD600: -case 0xD800: -case 0xDA00: -case 0xDC00: -case 0xDE00: -case 0xD001: -case 0xD201: -case 0xD401: -case 0xD601: -case 0xD801: -case 0xDA01: -case 0xDC01: -case 0xDE01: -case 0xD002: -case 0xD202: -case 0xD402: -case 0xD602: -case 0xD802: -case 0xDA02: -case 0xDC02: -case 0xDE02: -case 0xD003: -case 0xD203: -case 0xD403: -case 0xD603: -case 0xD803: -case 0xDA03: -case 0xDC03: -case 0xDE03: -case 0xD004: -case 0xD204: -case 0xD404: -case 0xD604: -case 0xD804: -case 0xDA04: -case 0xDC04: -case 0xDE04: -case 0xD005: -case 0xD205: -case 0xD405: -case 0xD605: -case 0xD805: -case 0xDA05: -case 0xDC05: -case 0xDE05: -case 0xD006: -case 0xD206: -case 0xD406: -case 0xD606: -case 0xD806: -case 0xDA06: -case 0xDC06: -case 0xDE06: -case 0xD007: -case 0xD207: -case 0xD407: -case 0xD607: -case 0xD807: -case 0xDA07: -case 0xDC07: -case 0xDE07: - -// ADDaD -case 0xD000: -{ - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0xD208: -case 0xD408: -case 0xD608: -case 0xD808: -case 0xDA08: -case 0xDC08: -case 0xDE08: -case 0xD009: -case 0xD209: -case 0xD409: -case 0xD609: -case 0xD809: -case 0xDA09: -case 0xDC09: -case 0xDE09: -case 0xD00A: -case 0xD20A: -case 0xD40A: -case 0xD60A: -case 0xD80A: -case 0xDA0A: -case 0xDC0A: -case 0xDE0A: -case 0xD00B: -case 0xD20B: -case 0xD40B: -case 0xD60B: -case 0xD80B: -case 0xDA0B: -case 0xDC0B: -case 0xDE0B: -case 0xD00C: -case 0xD20C: -case 0xD40C: -case 0xD60C: -case 0xD80C: -case 0xDA0C: -case 0xDC0C: -case 0xDE0C: -case 0xD00D: -case 0xD20D: -case 0xD40D: -case 0xD60D: -case 0xD80D: -case 0xDA0D: -case 0xDC0D: -case 0xDE0D: -case 0xD00E: -case 0xD20E: -case 0xD40E: -case 0xD60E: -case 0xD80E: -case 0xDA0E: -case 0xDC0E: -case 0xDE0E: -case 0xD00F: -case 0xD20F: -case 0xD40F: -case 0xD60F: -case 0xD80F: -case 0xDA0F: -case 0xDC0F: -case 0xDE0F: - -// ADDaD -case 0xD008: -{ - u32 res; - pointer dst; - pointer src; - // can't read byte from Ax registers ! - CPU->Status |= C68K_FAULTED; - CCnt = 0; - goto C68k_Exec_Really_End; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0xD210: -case 0xD410: -case 0xD610: -case 0xD810: -case 0xDA10: -case 0xDC10: -case 0xDE10: -case 0xD011: -case 0xD211: -case 0xD411: -case 0xD611: -case 0xD811: -case 0xDA11: -case 0xDC11: -case 0xDE11: -case 0xD012: -case 0xD212: -case 0xD412: -case 0xD612: -case 0xD812: -case 0xDA12: -case 0xDC12: -case 0xDE12: -case 0xD013: -case 0xD213: -case 0xD413: -case 0xD613: -case 0xD813: -case 0xDA13: -case 0xDC13: -case 0xDE13: -case 0xD014: -case 0xD214: -case 0xD414: -case 0xD614: -case 0xD814: -case 0xDA14: -case 0xDC14: -case 0xDE14: -case 0xD015: -case 0xD215: -case 0xD415: -case 0xD615: -case 0xD815: -case 0xDA15: -case 0xDC15: -case 0xDE15: -case 0xD016: -case 0xD216: -case 0xD416: -case 0xD616: -case 0xD816: -case 0xDA16: -case 0xDC16: -case 0xDE16: -case 0xD017: -case 0xD217: -case 0xD417: -case 0xD617: -case 0xD817: -case 0xDA17: -case 0xDC17: -case 0xDE17: - -// ADDaD -case 0xD010: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xD218: -case 0xD418: -case 0xD618: -case 0xD818: -case 0xDA18: -case 0xDC18: -case 0xDE18: -case 0xD019: -case 0xD219: -case 0xD419: -case 0xD619: -case 0xD819: -case 0xDA19: -case 0xDC19: -case 0xDE19: -case 0xD01A: -case 0xD21A: -case 0xD41A: -case 0xD61A: -case 0xD81A: -case 0xDA1A: -case 0xDC1A: -case 0xDE1A: -case 0xD01B: -case 0xD21B: -case 0xD41B: -case 0xD61B: -case 0xD81B: -case 0xDA1B: -case 0xDC1B: -case 0xDE1B: -case 0xD01C: -case 0xD21C: -case 0xD41C: -case 0xD61C: -case 0xD81C: -case 0xDA1C: -case 0xDC1C: -case 0xDE1C: -case 0xD01D: -case 0xD21D: -case 0xD41D: -case 0xD61D: -case 0xD81D: -case 0xDA1D: -case 0xDC1D: -case 0xDE1D: -case 0xD01E: -case 0xD21E: -case 0xD41E: -case 0xD61E: -case 0xD81E: -case 0xDA1E: -case 0xDC1E: -case 0xDE1E: - -// ADDaD -case 0xD018: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xD220: -case 0xD420: -case 0xD620: -case 0xD820: -case 0xDA20: -case 0xDC20: -case 0xDE20: -case 0xD021: -case 0xD221: -case 0xD421: -case 0xD621: -case 0xD821: -case 0xDA21: -case 0xDC21: -case 0xDE21: -case 0xD022: -case 0xD222: -case 0xD422: -case 0xD622: -case 0xD822: -case 0xDA22: -case 0xDC22: -case 0xDE22: -case 0xD023: -case 0xD223: -case 0xD423: -case 0xD623: -case 0xD823: -case 0xDA23: -case 0xDC23: -case 0xDE23: -case 0xD024: -case 0xD224: -case 0xD424: -case 0xD624: -case 0xD824: -case 0xDA24: -case 0xDC24: -case 0xDE24: -case 0xD025: -case 0xD225: -case 0xD425: -case 0xD625: -case 0xD825: -case 0xDA25: -case 0xDC25: -case 0xDE25: -case 0xD026: -case 0xD226: -case 0xD426: -case 0xD626: -case 0xD826: -case 0xDA26: -case 0xDC26: -case 0xDE26: - -// ADDaD -case 0xD020: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0xD228: -case 0xD428: -case 0xD628: -case 0xD828: -case 0xDA28: -case 0xDC28: -case 0xDE28: -case 0xD029: -case 0xD229: -case 0xD429: -case 0xD629: -case 0xD829: -case 0xDA29: -case 0xDC29: -case 0xDE29: -case 0xD02A: -case 0xD22A: -case 0xD42A: -case 0xD62A: -case 0xD82A: -case 0xDA2A: -case 0xDC2A: -case 0xDE2A: -case 0xD02B: -case 0xD22B: -case 0xD42B: -case 0xD62B: -case 0xD82B: -case 0xDA2B: -case 0xDC2B: -case 0xDE2B: -case 0xD02C: -case 0xD22C: -case 0xD42C: -case 0xD62C: -case 0xD82C: -case 0xDA2C: -case 0xDC2C: -case 0xDE2C: -case 0xD02D: -case 0xD22D: -case 0xD42D: -case 0xD62D: -case 0xD82D: -case 0xDA2D: -case 0xDC2D: -case 0xDE2D: -case 0xD02E: -case 0xD22E: -case 0xD42E: -case 0xD62E: -case 0xD82E: -case 0xDA2E: -case 0xDC2E: -case 0xDE2E: -case 0xD02F: -case 0xD22F: -case 0xD42F: -case 0xD62F: -case 0xD82F: -case 0xDA2F: -case 0xDC2F: -case 0xDE2F: - -// ADDaD -case 0xD028: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xD230: -case 0xD430: -case 0xD630: -case 0xD830: -case 0xDA30: -case 0xDC30: -case 0xDE30: -case 0xD031: -case 0xD231: -case 0xD431: -case 0xD631: -case 0xD831: -case 0xDA31: -case 0xDC31: -case 0xDE31: -case 0xD032: -case 0xD232: -case 0xD432: -case 0xD632: -case 0xD832: -case 0xDA32: -case 0xDC32: -case 0xDE32: -case 0xD033: -case 0xD233: -case 0xD433: -case 0xD633: -case 0xD833: -case 0xDA33: -case 0xDC33: -case 0xDE33: -case 0xD034: -case 0xD234: -case 0xD434: -case 0xD634: -case 0xD834: -case 0xDA34: -case 0xDC34: -case 0xDE34: -case 0xD035: -case 0xD235: -case 0xD435: -case 0xD635: -case 0xD835: -case 0xDA35: -case 0xDC35: -case 0xDE35: -case 0xD036: -case 0xD236: -case 0xD436: -case 0xD636: -case 0xD836: -case 0xDA36: -case 0xDC36: -case 0xDE36: -case 0xD037: -case 0xD237: -case 0xD437: -case 0xD637: -case 0xD837: -case 0xDA37: -case 0xDC37: -case 0xDE37: - -// ADDaD -case 0xD030: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0xD238: -case 0xD438: -case 0xD638: -case 0xD838: -case 0xDA38: -case 0xDC38: -case 0xDE38: - -// ADDaD -case 0xD038: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xD239: -case 0xD439: -case 0xD639: -case 0xD839: -case 0xDA39: -case 0xDC39: -case 0xDE39: - -// ADDaD -case 0xD039: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xD23A: -case 0xD43A: -case 0xD63A: -case 0xD83A: -case 0xDA3A: -case 0xDC3A: -case 0xDE3A: - -// ADDaD -case 0xD03A: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xD23B: -case 0xD43B: -case 0xD63B: -case 0xD83B: -case 0xDA3B: -case 0xDC3B: -case 0xDE3B: - -// ADDaD -case 0xD03B: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0xD23C: -case 0xD43C: -case 0xD63C: -case 0xD83C: -case 0xDA3C: -case 0xDC3C: -case 0xDE3C: - -// ADDaD -case 0xD03C: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_BYTE; - PC += 2; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0xD21F: -case 0xD41F: -case 0xD61F: -case 0xD81F: -case 0xDA1F: -case 0xDC1F: -case 0xDE1F: - -// ADDaD -case 0xD01F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xD227: -case 0xD427: -case 0xD627: -case 0xD827: -case 0xDA27: -case 0xDC27: -case 0xDE27: - -// ADDaD -case 0xD027: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0xD240: -case 0xD440: -case 0xD640: -case 0xD840: -case 0xDA40: -case 0xDC40: -case 0xDE40: -case 0xD041: -case 0xD241: -case 0xD441: -case 0xD641: -case 0xD841: -case 0xDA41: -case 0xDC41: -case 0xDE41: -case 0xD042: -case 0xD242: -case 0xD442: -case 0xD642: -case 0xD842: -case 0xDA42: -case 0xDC42: -case 0xDE42: -case 0xD043: -case 0xD243: -case 0xD443: -case 0xD643: -case 0xD843: -case 0xDA43: -case 0xDC43: -case 0xDE43: -case 0xD044: -case 0xD244: -case 0xD444: -case 0xD644: -case 0xD844: -case 0xDA44: -case 0xDC44: -case 0xDE44: -case 0xD045: -case 0xD245: -case 0xD445: -case 0xD645: -case 0xD845: -case 0xDA45: -case 0xDC45: -case 0xDE45: -case 0xD046: -case 0xD246: -case 0xD446: -case 0xD646: -case 0xD846: -case 0xDA46: -case 0xDC46: -case 0xDE46: -case 0xD047: -case 0xD247: -case 0xD447: -case 0xD647: -case 0xD847: -case 0xDA47: -case 0xDC47: -case 0xDE47: - -// ADDaD -case 0xD040: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0xD248: -case 0xD448: -case 0xD648: -case 0xD848: -case 0xDA48: -case 0xDC48: -case 0xDE48: -case 0xD049: -case 0xD249: -case 0xD449: -case 0xD649: -case 0xD849: -case 0xDA49: -case 0xDC49: -case 0xDE49: -case 0xD04A: -case 0xD24A: -case 0xD44A: -case 0xD64A: -case 0xD84A: -case 0xDA4A: -case 0xDC4A: -case 0xDE4A: -case 0xD04B: -case 0xD24B: -case 0xD44B: -case 0xD64B: -case 0xD84B: -case 0xDA4B: -case 0xDC4B: -case 0xDE4B: -case 0xD04C: -case 0xD24C: -case 0xD44C: -case 0xD64C: -case 0xD84C: -case 0xDA4C: -case 0xDC4C: -case 0xDE4C: -case 0xD04D: -case 0xD24D: -case 0xD44D: -case 0xD64D: -case 0xD84D: -case 0xDA4D: -case 0xDC4D: -case 0xDE4D: -case 0xD04E: -case 0xD24E: -case 0xD44E: -case 0xD64E: -case 0xD84E: -case 0xDA4E: -case 0xDC4E: -case 0xDE4E: -case 0xD04F: -case 0xD24F: -case 0xD44F: -case 0xD64F: -case 0xD84F: -case 0xDA4F: -case 0xDC4F: -case 0xDE4F: - -// ADDaD -case 0xD048: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->A[(Opcode >> 0) & 7]; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0xD250: -case 0xD450: -case 0xD650: -case 0xD850: -case 0xDA50: -case 0xDC50: -case 0xDE50: -case 0xD051: -case 0xD251: -case 0xD451: -case 0xD651: -case 0xD851: -case 0xDA51: -case 0xDC51: -case 0xDE51: -case 0xD052: -case 0xD252: -case 0xD452: -case 0xD652: -case 0xD852: -case 0xDA52: -case 0xDC52: -case 0xDE52: -case 0xD053: -case 0xD253: -case 0xD453: -case 0xD653: -case 0xD853: -case 0xDA53: -case 0xDC53: -case 0xDE53: -case 0xD054: -case 0xD254: -case 0xD454: -case 0xD654: -case 0xD854: -case 0xDA54: -case 0xDC54: -case 0xDE54: -case 0xD055: -case 0xD255: -case 0xD455: -case 0xD655: -case 0xD855: -case 0xDA55: -case 0xDC55: -case 0xDE55: -case 0xD056: -case 0xD256: -case 0xD456: -case 0xD656: -case 0xD856: -case 0xDA56: -case 0xDC56: -case 0xDE56: -case 0xD057: -case 0xD257: -case 0xD457: -case 0xD657: -case 0xD857: -case 0xDA57: -case 0xDC57: -case 0xDE57: - -// ADDaD -case 0xD050: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xD258: -case 0xD458: -case 0xD658: -case 0xD858: -case 0xDA58: -case 0xDC58: -case 0xDE58: -case 0xD059: -case 0xD259: -case 0xD459: -case 0xD659: -case 0xD859: -case 0xDA59: -case 0xDC59: -case 0xDE59: -case 0xD05A: -case 0xD25A: -case 0xD45A: -case 0xD65A: -case 0xD85A: -case 0xDA5A: -case 0xDC5A: -case 0xDE5A: -case 0xD05B: -case 0xD25B: -case 0xD45B: -case 0xD65B: -case 0xD85B: -case 0xDA5B: -case 0xDC5B: -case 0xDE5B: -case 0xD05C: -case 0xD25C: -case 0xD45C: -case 0xD65C: -case 0xD85C: -case 0xDA5C: -case 0xDC5C: -case 0xDE5C: -case 0xD05D: -case 0xD25D: -case 0xD45D: -case 0xD65D: -case 0xD85D: -case 0xDA5D: -case 0xDC5D: -case 0xDE5D: -case 0xD05E: -case 0xD25E: -case 0xD45E: -case 0xD65E: -case 0xD85E: -case 0xDA5E: -case 0xDC5E: -case 0xDE5E: - -// ADDaD -case 0xD058: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xD260: -case 0xD460: -case 0xD660: -case 0xD860: -case 0xDA60: -case 0xDC60: -case 0xDE60: -case 0xD061: -case 0xD261: -case 0xD461: -case 0xD661: -case 0xD861: -case 0xDA61: -case 0xDC61: -case 0xDE61: -case 0xD062: -case 0xD262: -case 0xD462: -case 0xD662: -case 0xD862: -case 0xDA62: -case 0xDC62: -case 0xDE62: -case 0xD063: -case 0xD263: -case 0xD463: -case 0xD663: -case 0xD863: -case 0xDA63: -case 0xDC63: -case 0xDE63: -case 0xD064: -case 0xD264: -case 0xD464: -case 0xD664: -case 0xD864: -case 0xDA64: -case 0xDC64: -case 0xDE64: -case 0xD065: -case 0xD265: -case 0xD465: -case 0xD665: -case 0xD865: -case 0xDA65: -case 0xDC65: -case 0xDE65: -case 0xD066: -case 0xD266: -case 0xD466: -case 0xD666: -case 0xD866: -case 0xDA66: -case 0xDC66: -case 0xDE66: - -// ADDaD -case 0xD060: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0xD268: -case 0xD468: -case 0xD668: -case 0xD868: -case 0xDA68: -case 0xDC68: -case 0xDE68: -case 0xD069: -case 0xD269: -case 0xD469: -case 0xD669: -case 0xD869: -case 0xDA69: -case 0xDC69: -case 0xDE69: -case 0xD06A: -case 0xD26A: -case 0xD46A: -case 0xD66A: -case 0xD86A: -case 0xDA6A: -case 0xDC6A: -case 0xDE6A: -case 0xD06B: -case 0xD26B: -case 0xD46B: -case 0xD66B: -case 0xD86B: -case 0xDA6B: -case 0xDC6B: -case 0xDE6B: -case 0xD06C: -case 0xD26C: -case 0xD46C: -case 0xD66C: -case 0xD86C: -case 0xDA6C: -case 0xDC6C: -case 0xDE6C: -case 0xD06D: -case 0xD26D: -case 0xD46D: -case 0xD66D: -case 0xD86D: -case 0xDA6D: -case 0xDC6D: -case 0xDE6D: -case 0xD06E: -case 0xD26E: -case 0xD46E: -case 0xD66E: -case 0xD86E: -case 0xDA6E: -case 0xDC6E: -case 0xDE6E: -case 0xD06F: -case 0xD26F: -case 0xD46F: -case 0xD66F: -case 0xD86F: -case 0xDA6F: -case 0xDC6F: -case 0xDE6F: - -// ADDaD -case 0xD068: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xD270: -case 0xD470: -case 0xD670: -case 0xD870: -case 0xDA70: -case 0xDC70: -case 0xDE70: -case 0xD071: -case 0xD271: -case 0xD471: -case 0xD671: -case 0xD871: -case 0xDA71: -case 0xDC71: -case 0xDE71: -case 0xD072: -case 0xD272: -case 0xD472: -case 0xD672: -case 0xD872: -case 0xDA72: -case 0xDC72: -case 0xDE72: -case 0xD073: -case 0xD273: -case 0xD473: -case 0xD673: -case 0xD873: -case 0xDA73: -case 0xDC73: -case 0xDE73: -case 0xD074: -case 0xD274: -case 0xD474: -case 0xD674: -case 0xD874: -case 0xDA74: -case 0xDC74: -case 0xDE74: -case 0xD075: -case 0xD275: -case 0xD475: -case 0xD675: -case 0xD875: -case 0xDA75: -case 0xDC75: -case 0xDE75: -case 0xD076: -case 0xD276: -case 0xD476: -case 0xD676: -case 0xD876: -case 0xDA76: -case 0xDC76: -case 0xDE76: -case 0xD077: -case 0xD277: -case 0xD477: -case 0xD677: -case 0xD877: -case 0xDA77: -case 0xDC77: -case 0xDE77: - -// ADDaD -case 0xD070: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0xD278: -case 0xD478: -case 0xD678: -case 0xD878: -case 0xDA78: -case 0xDC78: -case 0xDE78: - -// ADDaD -case 0xD078: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xD279: -case 0xD479: -case 0xD679: -case 0xD879: -case 0xDA79: -case 0xDC79: -case 0xDE79: - -// ADDaD -case 0xD079: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xD27A: -case 0xD47A: -case 0xD67A: -case 0xD87A: -case 0xDA7A: -case 0xDC7A: -case 0xDE7A: - -// ADDaD -case 0xD07A: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(12) -case 0xD27B: -case 0xD47B: -case 0xD67B: -case 0xD87B: -case 0xDA7B: -case 0xDC7B: -case 0xDE7B: - -// ADDaD -case 0xD07B: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(14) -case 0xD27C: -case 0xD47C: -case 0xD67C: -case 0xD87C: -case 0xDA7C: -case 0xDC7C: -case 0xDE7C: - -// ADDaD -case 0xD07C: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_WORD; - PC += 2; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0xD25F: -case 0xD45F: -case 0xD65F: -case 0xD85F: -case 0xDA5F: -case 0xDC5F: -case 0xDE5F: - -// ADDaD -case 0xD05F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(8) -case 0xD267: -case 0xD467: -case 0xD667: -case 0xD867: -case 0xDA67: -case 0xDC67: -case 0xDE67: - -// ADDaD -case 0xD067: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(10) -case 0xD280: -case 0xD480: -case 0xD680: -case 0xD880: -case 0xDA80: -case 0xDC80: -case 0xDE80: -case 0xD081: -case 0xD281: -case 0xD481: -case 0xD681: -case 0xD881: -case 0xDA81: -case 0xDC81: -case 0xDE81: -case 0xD082: -case 0xD282: -case 0xD482: -case 0xD682: -case 0xD882: -case 0xDA82: -case 0xDC82: -case 0xDE82: -case 0xD083: -case 0xD283: -case 0xD483: -case 0xD683: -case 0xD883: -case 0xDA83: -case 0xDC83: -case 0xDE83: -case 0xD084: -case 0xD284: -case 0xD484: -case 0xD684: -case 0xD884: -case 0xDA84: -case 0xDC84: -case 0xDE84: -case 0xD085: -case 0xD285: -case 0xD485: -case 0xD685: -case 0xD885: -case 0xDA85: -case 0xDC85: -case 0xDE85: -case 0xD086: -case 0xD286: -case 0xD486: -case 0xD686: -case 0xD886: -case 0xDA86: -case 0xDC86: -case 0xDE86: -case 0xD087: -case 0xD287: -case 0xD487: -case 0xD687: -case 0xD887: -case 0xDA87: -case 0xDC87: -case 0xDE87: - -// ADDaD -case 0xD080: -{ - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(6) -case 0xD288: -case 0xD488: -case 0xD688: -case 0xD888: -case 0xDA88: -case 0xDC88: -case 0xDE88: -case 0xD089: -case 0xD289: -case 0xD489: -case 0xD689: -case 0xD889: -case 0xDA89: -case 0xDC89: -case 0xDE89: -case 0xD08A: -case 0xD28A: -case 0xD48A: -case 0xD68A: -case 0xD88A: -case 0xDA8A: -case 0xDC8A: -case 0xDE8A: -case 0xD08B: -case 0xD28B: -case 0xD48B: -case 0xD68B: -case 0xD88B: -case 0xDA8B: -case 0xDC8B: -case 0xDE8B: -case 0xD08C: -case 0xD28C: -case 0xD48C: -case 0xD68C: -case 0xD88C: -case 0xDA8C: -case 0xDC8C: -case 0xDE8C: -case 0xD08D: -case 0xD28D: -case 0xD48D: -case 0xD68D: -case 0xD88D: -case 0xDA8D: -case 0xDC8D: -case 0xDE8D: -case 0xD08E: -case 0xD28E: -case 0xD48E: -case 0xD68E: -case 0xD88E: -case 0xDA8E: -case 0xDC8E: -case 0xDE8E: -case 0xD08F: -case 0xD28F: -case 0xD48F: -case 0xD68F: -case 0xD88F: -case 0xDA8F: -case 0xDC8F: -case 0xDE8F: - -// ADDaD -case 0xD088: -{ - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(6) -case 0xD290: -case 0xD490: -case 0xD690: -case 0xD890: -case 0xDA90: -case 0xDC90: -case 0xDE90: -case 0xD091: -case 0xD291: -case 0xD491: -case 0xD691: -case 0xD891: -case 0xDA91: -case 0xDC91: -case 0xDE91: -case 0xD092: -case 0xD292: -case 0xD492: -case 0xD692: -case 0xD892: -case 0xDA92: -case 0xDC92: -case 0xDE92: -case 0xD093: -case 0xD293: -case 0xD493: -case 0xD693: -case 0xD893: -case 0xDA93: -case 0xDC93: -case 0xDE93: -case 0xD094: -case 0xD294: -case 0xD494: -case 0xD694: -case 0xD894: -case 0xDA94: -case 0xDC94: -case 0xDE94: -case 0xD095: -case 0xD295: -case 0xD495: -case 0xD695: -case 0xD895: -case 0xDA95: -case 0xDC95: -case 0xDE95: -case 0xD096: -case 0xD296: -case 0xD496: -case 0xD696: -case 0xD896: -case 0xDA96: -case 0xDC96: -case 0xDE96: -case 0xD097: -case 0xD297: -case 0xD497: -case 0xD697: -case 0xD897: -case 0xDA97: -case 0xDC97: -case 0xDE97: - -// ADDaD -case 0xD090: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xD298: -case 0xD498: -case 0xD698: -case 0xD898: -case 0xDA98: -case 0xDC98: -case 0xDE98: -case 0xD099: -case 0xD299: -case 0xD499: -case 0xD699: -case 0xD899: -case 0xDA99: -case 0xDC99: -case 0xDE99: -case 0xD09A: -case 0xD29A: -case 0xD49A: -case 0xD69A: -case 0xD89A: -case 0xDA9A: -case 0xDC9A: -case 0xDE9A: -case 0xD09B: -case 0xD29B: -case 0xD49B: -case 0xD69B: -case 0xD89B: -case 0xDA9B: -case 0xDC9B: -case 0xDE9B: -case 0xD09C: -case 0xD29C: -case 0xD49C: -case 0xD69C: -case 0xD89C: -case 0xDA9C: -case 0xDC9C: -case 0xDE9C: -case 0xD09D: -case 0xD29D: -case 0xD49D: -case 0xD69D: -case 0xD89D: -case 0xDA9D: -case 0xDC9D: -case 0xDE9D: -case 0xD09E: -case 0xD29E: -case 0xD49E: -case 0xD69E: -case 0xD89E: -case 0xDA9E: -case 0xDC9E: -case 0xDE9E: - -// ADDaD -case 0xD098: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xD2A0: -case 0xD4A0: -case 0xD6A0: -case 0xD8A0: -case 0xDAA0: -case 0xDCA0: -case 0xDEA0: -case 0xD0A1: -case 0xD2A1: -case 0xD4A1: -case 0xD6A1: -case 0xD8A1: -case 0xDAA1: -case 0xDCA1: -case 0xDEA1: -case 0xD0A2: -case 0xD2A2: -case 0xD4A2: -case 0xD6A2: -case 0xD8A2: -case 0xDAA2: -case 0xDCA2: -case 0xDEA2: -case 0xD0A3: -case 0xD2A3: -case 0xD4A3: -case 0xD6A3: -case 0xD8A3: -case 0xDAA3: -case 0xDCA3: -case 0xDEA3: -case 0xD0A4: -case 0xD2A4: -case 0xD4A4: -case 0xD6A4: -case 0xD8A4: -case 0xDAA4: -case 0xDCA4: -case 0xDEA4: -case 0xD0A5: -case 0xD2A5: -case 0xD4A5: -case 0xD6A5: -case 0xD8A5: -case 0xDAA5: -case 0xDCA5: -case 0xDEA5: -case 0xD0A6: -case 0xD2A6: -case 0xD4A6: -case 0xD6A6: -case 0xD8A6: -case 0xDAA6: -case 0xDCA6: -case 0xDEA6: - -// ADDaD -case 0xD0A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0xD2A8: -case 0xD4A8: -case 0xD6A8: -case 0xD8A8: -case 0xDAA8: -case 0xDCA8: -case 0xDEA8: -case 0xD0A9: -case 0xD2A9: -case 0xD4A9: -case 0xD6A9: -case 0xD8A9: -case 0xDAA9: -case 0xDCA9: -case 0xDEA9: -case 0xD0AA: -case 0xD2AA: -case 0xD4AA: -case 0xD6AA: -case 0xD8AA: -case 0xDAAA: -case 0xDCAA: -case 0xDEAA: -case 0xD0AB: -case 0xD2AB: -case 0xD4AB: -case 0xD6AB: -case 0xD8AB: -case 0xDAAB: -case 0xDCAB: -case 0xDEAB: -case 0xD0AC: -case 0xD2AC: -case 0xD4AC: -case 0xD6AC: -case 0xD8AC: -case 0xDAAC: -case 0xDCAC: -case 0xDEAC: -case 0xD0AD: -case 0xD2AD: -case 0xD4AD: -case 0xD6AD: -case 0xD8AD: -case 0xDAAD: -case 0xDCAD: -case 0xDEAD: -case 0xD0AE: -case 0xD2AE: -case 0xD4AE: -case 0xD6AE: -case 0xD8AE: -case 0xDAAE: -case 0xDCAE: -case 0xDEAE: -case 0xD0AF: -case 0xD2AF: -case 0xD4AF: -case 0xD6AF: -case 0xD8AF: -case 0xDAAF: -case 0xDCAF: -case 0xDEAF: - -// ADDaD -case 0xD0A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0xD2B0: -case 0xD4B0: -case 0xD6B0: -case 0xD8B0: -case 0xDAB0: -case 0xDCB0: -case 0xDEB0: -case 0xD0B1: -case 0xD2B1: -case 0xD4B1: -case 0xD6B1: -case 0xD8B1: -case 0xDAB1: -case 0xDCB1: -case 0xDEB1: -case 0xD0B2: -case 0xD2B2: -case 0xD4B2: -case 0xD6B2: -case 0xD8B2: -case 0xDAB2: -case 0xDCB2: -case 0xDEB2: -case 0xD0B3: -case 0xD2B3: -case 0xD4B3: -case 0xD6B3: -case 0xD8B3: -case 0xDAB3: -case 0xDCB3: -case 0xDEB3: -case 0xD0B4: -case 0xD2B4: -case 0xD4B4: -case 0xD6B4: -case 0xD8B4: -case 0xDAB4: -case 0xDCB4: -case 0xDEB4: -case 0xD0B5: -case 0xD2B5: -case 0xD4B5: -case 0xD6B5: -case 0xD8B5: -case 0xDAB5: -case 0xDCB5: -case 0xDEB5: -case 0xD0B6: -case 0xD2B6: -case 0xD4B6: -case 0xD6B6: -case 0xD8B6: -case 0xDAB6: -case 0xDCB6: -case 0xDEB6: -case 0xD0B7: -case 0xD2B7: -case 0xD4B7: -case 0xD6B7: -case 0xD8B7: -case 0xDAB7: -case 0xDCB7: -case 0xDEB7: - -// ADDaD -case 0xD0B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(22) -case 0xD2B8: -case 0xD4B8: -case 0xD6B8: -case 0xD8B8: -case 0xDAB8: -case 0xDCB8: -case 0xDEB8: - -// ADDaD -case 0xD0B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0xD2B9: -case 0xD4B9: -case 0xD6B9: -case 0xD8B9: -case 0xDAB9: -case 0xDCB9: -case 0xDEB9: - -// ADDaD -case 0xD0B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(24) -case 0xD2BA: -case 0xD4BA: -case 0xD6BA: -case 0xD8BA: -case 0xDABA: -case 0xDCBA: -case 0xDEBA: - -// ADDaD -case 0xD0BA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(20) -case 0xD2BB: -case 0xD4BB: -case 0xD6BB: -case 0xD8BB: -case 0xDABB: -case 0xDCBB: -case 0xDEBB: - -// ADDaD -case 0xD0BB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(22) -case 0xD2BC: -case 0xD4BC: -case 0xD6BC: -case 0xD8BC: -case 0xDABC: -case 0xDCBC: -case 0xDEBC: - -// ADDaD -case 0xD0BC: -{ - u32 res; - pointer dst; - pointer src; - src = FETCH_LONG; - PC += 4; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(14) -case 0xD29F: -case 0xD49F: -case 0xD69F: -case 0xD89F: -case 0xDA9F: -case 0xDC9F: -case 0xDE9F: - -// ADDaD -case 0xD09F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(16) -case 0xD2A7: -case 0xD4A7: -case 0xD6A7: -case 0xD8A7: -case 0xDAA7: -case 0xDCA7: -case 0xDEA7: - -// ADDaD -case 0xD0A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; - POST_IO -} -RET(18) -case 0xD310: -case 0xD510: -case 0xD710: -case 0xD910: -case 0xDB10: -case 0xDD10: -case 0xDF10: -case 0xD111: -case 0xD311: -case 0xD511: -case 0xD711: -case 0xD911: -case 0xDB11: -case 0xDD11: -case 0xDF11: -case 0xD112: -case 0xD312: -case 0xD512: -case 0xD712: -case 0xD912: -case 0xDB12: -case 0xDD12: -case 0xDF12: -case 0xD113: -case 0xD313: -case 0xD513: -case 0xD713: -case 0xD913: -case 0xDB13: -case 0xDD13: -case 0xDF13: -case 0xD114: -case 0xD314: -case 0xD514: -case 0xD714: -case 0xD914: -case 0xDB14: -case 0xDD14: -case 0xDF14: -case 0xD115: -case 0xD315: -case 0xD515: -case 0xD715: -case 0xD915: -case 0xDB15: -case 0xDD15: -case 0xDF15: -case 0xD116: -case 0xD316: -case 0xD516: -case 0xD716: -case 0xD916: -case 0xDB16: -case 0xDD16: -case 0xDF16: -case 0xD117: -case 0xD317: -case 0xD517: -case 0xD717: -case 0xD917: -case 0xDB17: -case 0xDD17: -case 0xDF17: - -// ADDDa -case 0xD110: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xD318: -case 0xD518: -case 0xD718: -case 0xD918: -case 0xDB18: -case 0xDD18: -case 0xDF18: -case 0xD119: -case 0xD319: -case 0xD519: -case 0xD719: -case 0xD919: -case 0xDB19: -case 0xDD19: -case 0xDF19: -case 0xD11A: -case 0xD31A: -case 0xD51A: -case 0xD71A: -case 0xD91A: -case 0xDB1A: -case 0xDD1A: -case 0xDF1A: -case 0xD11B: -case 0xD31B: -case 0xD51B: -case 0xD71B: -case 0xD91B: -case 0xDB1B: -case 0xDD1B: -case 0xDF1B: -case 0xD11C: -case 0xD31C: -case 0xD51C: -case 0xD71C: -case 0xD91C: -case 0xDB1C: -case 0xDD1C: -case 0xDF1C: -case 0xD11D: -case 0xD31D: -case 0xD51D: -case 0xD71D: -case 0xD91D: -case 0xDB1D: -case 0xDD1D: -case 0xDF1D: -case 0xD11E: -case 0xD31E: -case 0xD51E: -case 0xD71E: -case 0xD91E: -case 0xDB1E: -case 0xDD1E: -case 0xDF1E: - -// ADDDa -case 0xD118: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 1; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xD320: -case 0xD520: -case 0xD720: -case 0xD920: -case 0xDB20: -case 0xDD20: -case 0xDF20: -case 0xD121: -case 0xD321: -case 0xD521: -case 0xD721: -case 0xD921: -case 0xDB21: -case 0xDD21: -case 0xDF21: -case 0xD122: -case 0xD322: -case 0xD522: -case 0xD722: -case 0xD922: -case 0xDB22: -case 0xDD22: -case 0xDF22: -case 0xD123: -case 0xD323: -case 0xD523: -case 0xD723: -case 0xD923: -case 0xDB23: -case 0xDD23: -case 0xDF23: -case 0xD124: -case 0xD324: -case 0xD524: -case 0xD724: -case 0xD924: -case 0xDB24: -case 0xDD24: -case 0xDF24: -case 0xD125: -case 0xD325: -case 0xD525: -case 0xD725: -case 0xD925: -case 0xDB25: -case 0xDD25: -case 0xDF25: -case 0xD126: -case 0xD326: -case 0xD526: -case 0xD726: -case 0xD926: -case 0xDB26: -case 0xDD26: -case 0xDF26: - -// ADDDa -case 0xD120: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0xD328: -case 0xD528: -case 0xD728: -case 0xD928: -case 0xDB28: -case 0xDD28: -case 0xDF28: -case 0xD129: -case 0xD329: -case 0xD529: -case 0xD729: -case 0xD929: -case 0xDB29: -case 0xDD29: -case 0xDF29: -case 0xD12A: -case 0xD32A: -case 0xD52A: -case 0xD72A: -case 0xD92A: -case 0xDB2A: -case 0xDD2A: -case 0xDF2A: -case 0xD12B: -case 0xD32B: -case 0xD52B: -case 0xD72B: -case 0xD92B: -case 0xDB2B: -case 0xDD2B: -case 0xDF2B: -case 0xD12C: -case 0xD32C: -case 0xD52C: -case 0xD72C: -case 0xD92C: -case 0xDB2C: -case 0xDD2C: -case 0xDF2C: -case 0xD12D: -case 0xD32D: -case 0xD52D: -case 0xD72D: -case 0xD92D: -case 0xDB2D: -case 0xDD2D: -case 0xDF2D: -case 0xD12E: -case 0xD32E: -case 0xD52E: -case 0xD72E: -case 0xD92E: -case 0xDB2E: -case 0xDD2E: -case 0xDF2E: -case 0xD12F: -case 0xD32F: -case 0xD52F: -case 0xD72F: -case 0xD92F: -case 0xDB2F: -case 0xDD2F: -case 0xDF2F: - -// ADDDa -case 0xD128: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0xD330: -case 0xD530: -case 0xD730: -case 0xD930: -case 0xDB30: -case 0xDD30: -case 0xDF30: -case 0xD131: -case 0xD331: -case 0xD531: -case 0xD731: -case 0xD931: -case 0xDB31: -case 0xDD31: -case 0xDF31: -case 0xD132: -case 0xD332: -case 0xD532: -case 0xD732: -case 0xD932: -case 0xDB32: -case 0xDD32: -case 0xDF32: -case 0xD133: -case 0xD333: -case 0xD533: -case 0xD733: -case 0xD933: -case 0xDB33: -case 0xDD33: -case 0xDF33: -case 0xD134: -case 0xD334: -case 0xD534: -case 0xD734: -case 0xD934: -case 0xDB34: -case 0xDD34: -case 0xDF34: -case 0xD135: -case 0xD335: -case 0xD535: -case 0xD735: -case 0xD935: -case 0xDB35: -case 0xDD35: -case 0xDF35: -case 0xD136: -case 0xD336: -case 0xD536: -case 0xD736: -case 0xD936: -case 0xDB36: -case 0xDD36: -case 0xDF36: -case 0xD137: -case 0xD337: -case 0xD537: -case 0xD737: -case 0xD937: -case 0xDB37: -case 0xDD37: -case 0xDF37: - -// ADDDa -case 0xD130: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xD338: -case 0xD538: -case 0xD738: -case 0xD938: -case 0xDB38: -case 0xDD38: -case 0xDF38: - -// ADDDa -case 0xD138: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(16) -case 0xD339: -case 0xD539: -case 0xD739: -case 0xD939: -case 0xDB39: -case 0xDD39: -case 0xDF39: - -// ADDDa -case 0xD139: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(20) -case 0xD31F: -case 0xD51F: -case 0xD71F: -case 0xD91F: -case 0xDB1F: -case 0xDD1F: -case 0xDF1F: - -// ADDDa -case 0xD11F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(12) -case 0xD327: -case 0xD527: -case 0xD727: -case 0xD927: -case 0xDB27: -case 0xDD27: -case 0xDF27: - -// ADDDa -case 0xD127: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, dst) - res = dst + src; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ = res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(14) -case 0xD350: -case 0xD550: -case 0xD750: -case 0xD950: -case 0xDB50: -case 0xDD50: -case 0xDF50: -case 0xD151: -case 0xD351: -case 0xD551: -case 0xD751: -case 0xD951: -case 0xDB51: -case 0xDD51: -case 0xDF51: -case 0xD152: -case 0xD352: -case 0xD552: -case 0xD752: -case 0xD952: -case 0xDB52: -case 0xDD52: -case 0xDF52: -case 0xD153: -case 0xD353: -case 0xD553: -case 0xD753: -case 0xD953: -case 0xDB53: -case 0xDD53: -case 0xDF53: -case 0xD154: -case 0xD354: -case 0xD554: -case 0xD754: -case 0xD954: -case 0xDB54: -case 0xDD54: -case 0xDF54: -case 0xD155: -case 0xD355: -case 0xD555: -case 0xD755: -case 0xD955: -case 0xDB55: -case 0xDD55: -case 0xDF55: -case 0xD156: -case 0xD356: -case 0xD556: -case 0xD756: -case 0xD956: -case 0xDB56: -case 0xDD56: -case 0xDF56: -case 0xD157: -case 0xD357: -case 0xD557: -case 0xD757: -case 0xD957: -case 0xDB57: -case 0xDD57: -case 0xDF57: - -// ADDDa -case 0xD150: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xD358: -case 0xD558: -case 0xD758: -case 0xD958: -case 0xDB58: -case 0xDD58: -case 0xDF58: -case 0xD159: -case 0xD359: -case 0xD559: -case 0xD759: -case 0xD959: -case 0xDB59: -case 0xDD59: -case 0xDF59: -case 0xD15A: -case 0xD35A: -case 0xD55A: -case 0xD75A: -case 0xD95A: -case 0xDB5A: -case 0xDD5A: -case 0xDF5A: -case 0xD15B: -case 0xD35B: -case 0xD55B: -case 0xD75B: -case 0xD95B: -case 0xDB5B: -case 0xDD5B: -case 0xDF5B: -case 0xD15C: -case 0xD35C: -case 0xD55C: -case 0xD75C: -case 0xD95C: -case 0xDB5C: -case 0xDD5C: -case 0xDF5C: -case 0xD15D: -case 0xD35D: -case 0xD55D: -case 0xD75D: -case 0xD95D: -case 0xDB5D: -case 0xDD5D: -case 0xDF5D: -case 0xD15E: -case 0xD35E: -case 0xD55E: -case 0xD75E: -case 0xD95E: -case 0xDB5E: -case 0xDD5E: -case 0xDF5E: - -// ADDDa -case 0xD158: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xD360: -case 0xD560: -case 0xD760: -case 0xD960: -case 0xDB60: -case 0xDD60: -case 0xDF60: -case 0xD161: -case 0xD361: -case 0xD561: -case 0xD761: -case 0xD961: -case 0xDB61: -case 0xDD61: -case 0xDF61: -case 0xD162: -case 0xD362: -case 0xD562: -case 0xD762: -case 0xD962: -case 0xDB62: -case 0xDD62: -case 0xDF62: -case 0xD163: -case 0xD363: -case 0xD563: -case 0xD763: -case 0xD963: -case 0xDB63: -case 0xDD63: -case 0xDF63: -case 0xD164: -case 0xD364: -case 0xD564: -case 0xD764: -case 0xD964: -case 0xDB64: -case 0xDD64: -case 0xDF64: -case 0xD165: -case 0xD365: -case 0xD565: -case 0xD765: -case 0xD965: -case 0xDB65: -case 0xDD65: -case 0xDF65: -case 0xD166: -case 0xD366: -case 0xD566: -case 0xD766: -case 0xD966: -case 0xDB66: -case 0xDD66: -case 0xDF66: - -// ADDDa -case 0xD160: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xD368: -case 0xD568: -case 0xD768: -case 0xD968: -case 0xDB68: -case 0xDD68: -case 0xDF68: -case 0xD169: -case 0xD369: -case 0xD569: -case 0xD769: -case 0xD969: -case 0xDB69: -case 0xDD69: -case 0xDF69: -case 0xD16A: -case 0xD36A: -case 0xD56A: -case 0xD76A: -case 0xD96A: -case 0xDB6A: -case 0xDD6A: -case 0xDF6A: -case 0xD16B: -case 0xD36B: -case 0xD56B: -case 0xD76B: -case 0xD96B: -case 0xDB6B: -case 0xDD6B: -case 0xDF6B: -case 0xD16C: -case 0xD36C: -case 0xD56C: -case 0xD76C: -case 0xD96C: -case 0xDB6C: -case 0xDD6C: -case 0xDF6C: -case 0xD16D: -case 0xD36D: -case 0xD56D: -case 0xD76D: -case 0xD96D: -case 0xDB6D: -case 0xDD6D: -case 0xDF6D: -case 0xD16E: -case 0xD36E: -case 0xD56E: -case 0xD76E: -case 0xD96E: -case 0xDB6E: -case 0xDD6E: -case 0xDF6E: -case 0xD16F: -case 0xD36F: -case 0xD56F: -case 0xD76F: -case 0xD96F: -case 0xDB6F: -case 0xDD6F: -case 0xDF6F: - -// ADDDa -case 0xD168: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xD370: -case 0xD570: -case 0xD770: -case 0xD970: -case 0xDB70: -case 0xDD70: -case 0xDF70: -case 0xD171: -case 0xD371: -case 0xD571: -case 0xD771: -case 0xD971: -case 0xDB71: -case 0xDD71: -case 0xDF71: -case 0xD172: -case 0xD372: -case 0xD572: -case 0xD772: -case 0xD972: -case 0xDB72: -case 0xDD72: -case 0xDF72: -case 0xD173: -case 0xD373: -case 0xD573: -case 0xD773: -case 0xD973: -case 0xDB73: -case 0xDD73: -case 0xDF73: -case 0xD174: -case 0xD374: -case 0xD574: -case 0xD774: -case 0xD974: -case 0xDB74: -case 0xDD74: -case 0xDF74: -case 0xD175: -case 0xD375: -case 0xD575: -case 0xD775: -case 0xD975: -case 0xDB75: -case 0xDD75: -case 0xDF75: -case 0xD176: -case 0xD376: -case 0xD576: -case 0xD776: -case 0xD976: -case 0xDB76: -case 0xDD76: -case 0xDF76: -case 0xD177: -case 0xD377: -case 0xD577: -case 0xD777: -case 0xD977: -case 0xDB77: -case 0xDD77: -case 0xDF77: - -// ADDDa -case 0xD170: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0xD378: -case 0xD578: -case 0xD778: -case 0xD978: -case 0xDB78: -case 0xDD78: -case 0xDF78: - -// ADDDa -case 0xD178: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xD379: -case 0xD579: -case 0xD779: -case 0xD979: -case 0xDB79: -case 0xDD79: -case 0xDF79: - -// ADDDa -case 0xD179: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) -case 0xD35F: -case 0xD55F: -case 0xD75F: -case 0xD95F: -case 0xDB5F: -case 0xDD5F: -case 0xDF5F: - -// ADDDa -case 0xD15F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xD367: -case 0xD567: -case 0xD767: -case 0xD967: -case 0xDB67: -case 0xDD67: -case 0xDF67: - -// ADDDa -case 0xD167: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, dst) - res = dst + src; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ = res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xD390: -case 0xD590: -case 0xD790: -case 0xD990: -case 0xDB90: -case 0xDD90: -case 0xDF90: -case 0xD191: -case 0xD391: -case 0xD591: -case 0xD791: -case 0xD991: -case 0xDB91: -case 0xDD91: -case 0xDF91: -case 0xD192: -case 0xD392: -case 0xD592: -case 0xD792: -case 0xD992: -case 0xDB92: -case 0xDD92: -case 0xDF92: -case 0xD193: -case 0xD393: -case 0xD593: -case 0xD793: -case 0xD993: -case 0xDB93: -case 0xDD93: -case 0xDF93: -case 0xD194: -case 0xD394: -case 0xD594: -case 0xD794: -case 0xD994: -case 0xDB94: -case 0xDD94: -case 0xDF94: -case 0xD195: -case 0xD395: -case 0xD595: -case 0xD795: -case 0xD995: -case 0xDB95: -case 0xDD95: -case 0xDF95: -case 0xD196: -case 0xD396: -case 0xD596: -case 0xD796: -case 0xD996: -case 0xDB96: -case 0xDD96: -case 0xDF96: -case 0xD197: -case 0xD397: -case 0xD597: -case 0xD797: -case 0xD997: -case 0xDB97: -case 0xDD97: -case 0xDF97: - -// ADDDa -case 0xD190: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xD398: -case 0xD598: -case 0xD798: -case 0xD998: -case 0xDB98: -case 0xDD98: -case 0xDF98: -case 0xD199: -case 0xD399: -case 0xD599: -case 0xD799: -case 0xD999: -case 0xDB99: -case 0xDD99: -case 0xDF99: -case 0xD19A: -case 0xD39A: -case 0xD59A: -case 0xD79A: -case 0xD99A: -case 0xDB9A: -case 0xDD9A: -case 0xDF9A: -case 0xD19B: -case 0xD39B: -case 0xD59B: -case 0xD79B: -case 0xD99B: -case 0xDB9B: -case 0xDD9B: -case 0xDF9B: -case 0xD19C: -case 0xD39C: -case 0xD59C: -case 0xD79C: -case 0xD99C: -case 0xDB9C: -case 0xDD9C: -case 0xDF9C: -case 0xD19D: -case 0xD39D: -case 0xD59D: -case 0xD79D: -case 0xD99D: -case 0xDB9D: -case 0xDD9D: -case 0xDF9D: -case 0xD19E: -case 0xD39E: -case 0xD59E: -case 0xD79E: -case 0xD99E: -case 0xDB9E: -case 0xDD9E: -case 0xDF9E: - -// ADDDa -case 0xD198: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xD3A0: -case 0xD5A0: -case 0xD7A0: -case 0xD9A0: -case 0xDBA0: -case 0xDDA0: -case 0xDFA0: -case 0xD1A1: -case 0xD3A1: -case 0xD5A1: -case 0xD7A1: -case 0xD9A1: -case 0xDBA1: -case 0xDDA1: -case 0xDFA1: -case 0xD1A2: -case 0xD3A2: -case 0xD5A2: -case 0xD7A2: -case 0xD9A2: -case 0xDBA2: -case 0xDDA2: -case 0xDFA2: -case 0xD1A3: -case 0xD3A3: -case 0xD5A3: -case 0xD7A3: -case 0xD9A3: -case 0xDBA3: -case 0xDDA3: -case 0xDFA3: -case 0xD1A4: -case 0xD3A4: -case 0xD5A4: -case 0xD7A4: -case 0xD9A4: -case 0xDBA4: -case 0xDDA4: -case 0xDFA4: -case 0xD1A5: -case 0xD3A5: -case 0xD5A5: -case 0xD7A5: -case 0xD9A5: -case 0xDBA5: -case 0xDDA5: -case 0xDFA5: -case 0xD1A6: -case 0xD3A6: -case 0xD5A6: -case 0xD7A6: -case 0xD9A6: -case 0xDBA6: -case 0xDDA6: -case 0xDFA6: - -// ADDDa -case 0xD1A0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0xD3A8: -case 0xD5A8: -case 0xD7A8: -case 0xD9A8: -case 0xDBA8: -case 0xDDA8: -case 0xDFA8: -case 0xD1A9: -case 0xD3A9: -case 0xD5A9: -case 0xD7A9: -case 0xD9A9: -case 0xDBA9: -case 0xDDA9: -case 0xDFA9: -case 0xD1AA: -case 0xD3AA: -case 0xD5AA: -case 0xD7AA: -case 0xD9AA: -case 0xDBAA: -case 0xDDAA: -case 0xDFAA: -case 0xD1AB: -case 0xD3AB: -case 0xD5AB: -case 0xD7AB: -case 0xD9AB: -case 0xDBAB: -case 0xDDAB: -case 0xDFAB: -case 0xD1AC: -case 0xD3AC: -case 0xD5AC: -case 0xD7AC: -case 0xD9AC: -case 0xDBAC: -case 0xDDAC: -case 0xDFAC: -case 0xD1AD: -case 0xD3AD: -case 0xD5AD: -case 0xD7AD: -case 0xD9AD: -case 0xDBAD: -case 0xDDAD: -case 0xDFAD: -case 0xD1AE: -case 0xD3AE: -case 0xD5AE: -case 0xD7AE: -case 0xD9AE: -case 0xDBAE: -case 0xDDAE: -case 0xDFAE: -case 0xD1AF: -case 0xD3AF: -case 0xD5AF: -case 0xD7AF: -case 0xD9AF: -case 0xDBAF: -case 0xDDAF: -case 0xDFAF: - -// ADDDa -case 0xD1A8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0xD3B0: -case 0xD5B0: -case 0xD7B0: -case 0xD9B0: -case 0xDBB0: -case 0xDDB0: -case 0xDFB0: -case 0xD1B1: -case 0xD3B1: -case 0xD5B1: -case 0xD7B1: -case 0xD9B1: -case 0xDBB1: -case 0xDDB1: -case 0xDFB1: -case 0xD1B2: -case 0xD3B2: -case 0xD5B2: -case 0xD7B2: -case 0xD9B2: -case 0xDBB2: -case 0xDDB2: -case 0xDFB2: -case 0xD1B3: -case 0xD3B3: -case 0xD5B3: -case 0xD7B3: -case 0xD9B3: -case 0xDBB3: -case 0xDDB3: -case 0xDFB3: -case 0xD1B4: -case 0xD3B4: -case 0xD5B4: -case 0xD7B4: -case 0xD9B4: -case 0xDBB4: -case 0xDDB4: -case 0xDFB4: -case 0xD1B5: -case 0xD3B5: -case 0xD5B5: -case 0xD7B5: -case 0xD9B5: -case 0xDBB5: -case 0xDDB5: -case 0xDFB5: -case 0xD1B6: -case 0xD3B6: -case 0xD5B6: -case 0xD7B6: -case 0xD9B6: -case 0xDBB6: -case 0xDDB6: -case 0xDFB6: -case 0xD1B7: -case 0xD3B7: -case 0xD5B7: -case 0xD7B7: -case 0xD9B7: -case 0xDBB7: -case 0xDDB7: -case 0xDFB7: - -// ADDDa -case 0xD1B0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(26) -case 0xD3B8: -case 0xD5B8: -case 0xD7B8: -case 0xD9B8: -case 0xDBB8: -case 0xDDB8: -case 0xDFB8: - -// ADDDa -case 0xD1B8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(24) -case 0xD3B9: -case 0xD5B9: -case 0xD7B9: -case 0xD9B9: -case 0xDBB9: -case 0xDDB9: -case 0xDFB9: - -// ADDDa -case 0xD1B9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(28) -case 0xD39F: -case 0xD59F: -case 0xD79F: -case 0xD99F: -case 0xDB9F: -case 0xDD9F: -case 0xDF9F: - -// ADDDa -case 0xD19F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(20) -case 0xD3A7: -case 0xD5A7: -case 0xD7A7: -case 0xD9A7: -case 0xDBA7: -case 0xDDA7: -case 0xDFA7: - -// ADDDa -case 0xD1A7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 9) & 7]; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, dst) - res = dst + src; - CPU->flag_notZ = res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(22) -case 0xD300: -case 0xD500: -case 0xD700: -case 0xD900: -case 0xDB00: -case 0xDD00: -case 0xDF00: -case 0xD101: -case 0xD301: -case 0xD501: -case 0xD701: -case 0xD901: -case 0xDB01: -case 0xDD01: -case 0xDF01: -case 0xD102: -case 0xD302: -case 0xD502: -case 0xD702: -case 0xD902: -case 0xDB02: -case 0xDD02: -case 0xDF02: -case 0xD103: -case 0xD303: -case 0xD503: -case 0xD703: -case 0xD903: -case 0xDB03: -case 0xDD03: -case 0xDF03: -case 0xD104: -case 0xD304: -case 0xD504: -case 0xD704: -case 0xD904: -case 0xDB04: -case 0xDD04: -case 0xDF04: -case 0xD105: -case 0xD305: -case 0xD505: -case 0xD705: -case 0xD905: -case 0xDB05: -case 0xDD05: -case 0xDF05: -case 0xD106: -case 0xD306: -case 0xD506: -case 0xD706: -case 0xD906: -case 0xDB06: -case 0xDD06: -case 0xDF06: -case 0xD107: -case 0xD307: -case 0xD507: -case 0xD707: -case 0xD907: -case 0xDB07: -case 0xDD07: -case 0xDF07: - -// ADDX -case 0xD100: -{ - u32 res; - pointer dst; - pointer src; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - dst = (u8)CPU->D[(Opcode >> 9) & 7]; - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ |= res & 0xFF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0xD340: -case 0xD540: -case 0xD740: -case 0xD940: -case 0xDB40: -case 0xDD40: -case 0xDF40: -case 0xD141: -case 0xD341: -case 0xD541: -case 0xD741: -case 0xD941: -case 0xDB41: -case 0xDD41: -case 0xDF41: -case 0xD142: -case 0xD342: -case 0xD542: -case 0xD742: -case 0xD942: -case 0xDB42: -case 0xDD42: -case 0xDF42: -case 0xD143: -case 0xD343: -case 0xD543: -case 0xD743: -case 0xD943: -case 0xDB43: -case 0xDD43: -case 0xDF43: -case 0xD144: -case 0xD344: -case 0xD544: -case 0xD744: -case 0xD944: -case 0xDB44: -case 0xDD44: -case 0xDF44: -case 0xD145: -case 0xD345: -case 0xD545: -case 0xD745: -case 0xD945: -case 0xDB45: -case 0xDD45: -case 0xDF45: -case 0xD146: -case 0xD346: -case 0xD546: -case 0xD746: -case 0xD946: -case 0xDB46: -case 0xDD46: -case 0xDF46: -case 0xD147: -case 0xD347: -case 0xD547: -case 0xD747: -case 0xD947: -case 0xDB47: -case 0xDD47: -case 0xDF47: - -// ADDX -case 0xD140: -{ - u32 res; - pointer dst; - pointer src; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - dst = (u16)CPU->D[(Opcode >> 9) & 7]; - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(4) -case 0xD380: -case 0xD580: -case 0xD780: -case 0xD980: -case 0xDB80: -case 0xDD80: -case 0xDF80: -case 0xD181: -case 0xD381: -case 0xD581: -case 0xD781: -case 0xD981: -case 0xDB81: -case 0xDD81: -case 0xDF81: -case 0xD182: -case 0xD382: -case 0xD582: -case 0xD782: -case 0xD982: -case 0xDB82: -case 0xDD82: -case 0xDF82: -case 0xD183: -case 0xD383: -case 0xD583: -case 0xD783: -case 0xD983: -case 0xDB83: -case 0xDD83: -case 0xDF83: -case 0xD184: -case 0xD384: -case 0xD584: -case 0xD784: -case 0xD984: -case 0xDB84: -case 0xDD84: -case 0xDF84: -case 0xD185: -case 0xD385: -case 0xD585: -case 0xD785: -case 0xD985: -case 0xDB85: -case 0xDD85: -case 0xDF85: -case 0xD186: -case 0xD386: -case 0xD586: -case 0xD786: -case 0xD986: -case 0xDB86: -case 0xDD86: -case 0xDF86: -case 0xD187: -case 0xD387: -case 0xD587: -case 0xD787: -case 0xD987: -case 0xDB87: -case 0xDD87: -case 0xDF87: - -// ADDX -case 0xD180: -{ - u32 res; - pointer dst; - pointer src; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->D[(Opcode >> 9) & 7]; - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - *((u32*)(&CPU->D[(Opcode >> 9) & 7])) = res; -} -RET(8) -case 0xD308: -case 0xD508: -case 0xD708: -case 0xD908: -case 0xDB08: -case 0xDD08: -case 0xD109: -case 0xD309: -case 0xD509: -case 0xD709: -case 0xD909: -case 0xDB09: -case 0xDD09: -case 0xD10A: -case 0xD30A: -case 0xD50A: -case 0xD70A: -case 0xD90A: -case 0xDB0A: -case 0xDD0A: -case 0xD10B: -case 0xD30B: -case 0xD50B: -case 0xD70B: -case 0xD90B: -case 0xDB0B: -case 0xDD0B: -case 0xD10C: -case 0xD30C: -case 0xD50C: -case 0xD70C: -case 0xD90C: -case 0xDB0C: -case 0xDD0C: -case 0xD10D: -case 0xD30D: -case 0xD50D: -case 0xD70D: -case 0xD90D: -case 0xDB0D: -case 0xDD0D: -case 0xD10E: -case 0xD30E: -case 0xD50E: -case 0xD70E: -case 0xD90E: -case 0xDB0E: -case 0xDD0E: - -// ADDXM -case 0xD108: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_BYTE_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xD348: -case 0xD548: -case 0xD748: -case 0xD948: -case 0xDB48: -case 0xDD48: -case 0xD149: -case 0xD349: -case 0xD549: -case 0xD749: -case 0xD949: -case 0xDB49: -case 0xDD49: -case 0xD14A: -case 0xD34A: -case 0xD54A: -case 0xD74A: -case 0xD94A: -case 0xDB4A: -case 0xDD4A: -case 0xD14B: -case 0xD34B: -case 0xD54B: -case 0xD74B: -case 0xD94B: -case 0xDB4B: -case 0xDD4B: -case 0xD14C: -case 0xD34C: -case 0xD54C: -case 0xD74C: -case 0xD94C: -case 0xDB4C: -case 0xDD4C: -case 0xD14D: -case 0xD34D: -case 0xD54D: -case 0xD74D: -case 0xD94D: -case 0xDB4D: -case 0xDD4D: -case 0xD14E: -case 0xD34E: -case 0xD54E: -case 0xD74E: -case 0xD94E: -case 0xDB4E: -case 0xDD4E: - -// ADDXM -case 0xD148: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_WORD_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0xD388: -case 0xD588: -case 0xD788: -case 0xD988: -case 0xDB88: -case 0xDD88: -case 0xD189: -case 0xD389: -case 0xD589: -case 0xD789: -case 0xD989: -case 0xDB89: -case 0xDD89: -case 0xD18A: -case 0xD38A: -case 0xD58A: -case 0xD78A: -case 0xD98A: -case 0xDB8A: -case 0xDD8A: -case 0xD18B: -case 0xD38B: -case 0xD58B: -case 0xD78B: -case 0xD98B: -case 0xDB8B: -case 0xDD8B: -case 0xD18C: -case 0xD38C: -case 0xD58C: -case 0xD78C: -case 0xD98C: -case 0xDB8C: -case 0xDD8C: -case 0xD18D: -case 0xD38D: -case 0xD58D: -case 0xD78D: -case 0xD98D: -case 0xDB8D: -case 0xDD8D: -case 0xD18E: -case 0xD38E: -case 0xD58E: -case 0xD78E: -case 0xD98E: -case 0xDB8E: -case 0xDD8E: - -// ADDXM -case 0xD188: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_LONG_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0xD30F: -case 0xD50F: -case 0xD70F: -case 0xD90F: -case 0xDB0F: -case 0xDD0F: - -// ADDX7M -case 0xD10F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 1; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_BYTE_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xD34F: -case 0xD54F: -case 0xD74F: -case 0xD94F: -case 0xDB4F: -case 0xDD4F: - -// ADDX7M -case 0xD14F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 2; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_WORD_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0xD38F: -case 0xD58F: -case 0xD78F: -case 0xD98F: -case 0xDB8F: -case 0xDD8F: - -// ADDX7M -case 0xD18F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[(Opcode >> 9) & 7] - 4; - CPU->A[(Opcode >> 9) & 7] = adr; - READ_LONG_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0xDF09: -case 0xDF0A: -case 0xDF0B: -case 0xDF0C: -case 0xDF0D: -case 0xDF0E: - -// ADDXM7 -case 0xDF08: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 1; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_BYTE_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) -case 0xDF49: -case 0xDF4A: -case 0xDF4B: -case 0xDF4C: -case 0xDF4D: -case 0xDF4E: - -// ADDXM7 -case 0xDF48: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_WORD_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) -case 0xDF89: -case 0xDF8A: -case 0xDF8B: -case 0xDF8C: -case 0xDF8D: -case 0xDF8E: - -// ADDXM7 -case 0xDF88: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - READ_LONG_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) - -// ADDX7M7 -case 0xDF0F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_BYTE_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_BYTE_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_N = CPU->flag_X = CPU->flag_C = res; - CPU->flag_V = (src ^ res) & (dst ^ res); - CPU->flag_notZ |= res & 0xFF; - WRITE_BYTE_F(adr, res) - POST_IO -} -RET(18) - -// ADDX7M7 -case 0xDF4F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - READ_WORD_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8; - CPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_notZ |= res & 0xFFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// ADDX7M7 -case 0xDF8F: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READ_LONG_F(adr, src) - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - READ_LONG_F(adr, dst) - res = dst + src + ((CPU->flag_X >> 8) & 1); - CPU->flag_notZ |= res; - CPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23; - CPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24; - CPU->flag_N = res >> 24; - WRITE_LONG_F(adr, res) - POST_IO -} -RET(30) -case 0xD2C0: -case 0xD4C0: -case 0xD6C0: -case 0xD8C0: -case 0xDAC0: -case 0xDCC0: -case 0xDEC0: -case 0xD0C1: -case 0xD2C1: -case 0xD4C1: -case 0xD6C1: -case 0xD8C1: -case 0xDAC1: -case 0xDCC1: -case 0xDEC1: -case 0xD0C2: -case 0xD2C2: -case 0xD4C2: -case 0xD6C2: -case 0xD8C2: -case 0xDAC2: -case 0xDCC2: -case 0xDEC2: -case 0xD0C3: -case 0xD2C3: -case 0xD4C3: -case 0xD6C3: -case 0xD8C3: -case 0xDAC3: -case 0xDCC3: -case 0xDEC3: -case 0xD0C4: -case 0xD2C4: -case 0xD4C4: -case 0xD6C4: -case 0xD8C4: -case 0xDAC4: -case 0xDCC4: -case 0xDEC4: -case 0xD0C5: -case 0xD2C5: -case 0xD4C5: -case 0xD6C5: -case 0xD8C5: -case 0xDAC5: -case 0xDCC5: -case 0xDEC5: -case 0xD0C6: -case 0xD2C6: -case 0xD4C6: -case 0xD6C6: -case 0xD8C6: -case 0xDAC6: -case 0xDCC6: -case 0xDEC6: -case 0xD0C7: -case 0xD2C7: -case 0xD4C7: -case 0xD6C7: -case 0xD8C7: -case 0xDAC7: -case 0xDCC7: -case 0xDEC7: - -// ADDA -case 0xD0C0: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(8) -case 0xD2C8: -case 0xD4C8: -case 0xD6C8: -case 0xD8C8: -case 0xDAC8: -case 0xDCC8: -case 0xDEC8: -case 0xD0C9: -case 0xD2C9: -case 0xD4C9: -case 0xD6C9: -case 0xD8C9: -case 0xDAC9: -case 0xDCC9: -case 0xDEC9: -case 0xD0CA: -case 0xD2CA: -case 0xD4CA: -case 0xD6CA: -case 0xD8CA: -case 0xDACA: -case 0xDCCA: -case 0xDECA: -case 0xD0CB: -case 0xD2CB: -case 0xD4CB: -case 0xD6CB: -case 0xD8CB: -case 0xDACB: -case 0xDCCB: -case 0xDECB: -case 0xD0CC: -case 0xD2CC: -case 0xD4CC: -case 0xD6CC: -case 0xD8CC: -case 0xDACC: -case 0xDCCC: -case 0xDECC: -case 0xD0CD: -case 0xD2CD: -case 0xD4CD: -case 0xD6CD: -case 0xD8CD: -case 0xDACD: -case 0xDCCD: -case 0xDECD: -case 0xD0CE: -case 0xD2CE: -case 0xD4CE: -case 0xD6CE: -case 0xD8CE: -case 0xDACE: -case 0xDCCE: -case 0xDECE: -case 0xD0CF: -case 0xD2CF: -case 0xD4CF: -case 0xD6CF: -case 0xD8CF: -case 0xDACF: -case 0xDCCF: -case 0xDECF: - -// ADDA -case 0xD0C8: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(8) -case 0xD2D0: -case 0xD4D0: -case 0xD6D0: -case 0xD8D0: -case 0xDAD0: -case 0xDCD0: -case 0xDED0: -case 0xD0D1: -case 0xD2D1: -case 0xD4D1: -case 0xD6D1: -case 0xD8D1: -case 0xDAD1: -case 0xDCD1: -case 0xDED1: -case 0xD0D2: -case 0xD2D2: -case 0xD4D2: -case 0xD6D2: -case 0xD8D2: -case 0xDAD2: -case 0xDCD2: -case 0xDED2: -case 0xD0D3: -case 0xD2D3: -case 0xD4D3: -case 0xD6D3: -case 0xD8D3: -case 0xDAD3: -case 0xDCD3: -case 0xDED3: -case 0xD0D4: -case 0xD2D4: -case 0xD4D4: -case 0xD6D4: -case 0xD8D4: -case 0xDAD4: -case 0xDCD4: -case 0xDED4: -case 0xD0D5: -case 0xD2D5: -case 0xD4D5: -case 0xD6D5: -case 0xD8D5: -case 0xDAD5: -case 0xDCD5: -case 0xDED5: -case 0xD0D6: -case 0xD2D6: -case 0xD4D6: -case 0xD6D6: -case 0xD8D6: -case 0xDAD6: -case 0xDCD6: -case 0xDED6: -case 0xD0D7: -case 0xD2D7: -case 0xD4D7: -case 0xD6D7: -case 0xD8D7: -case 0xDAD7: -case 0xDCD7: -case 0xDED7: - -// ADDA -case 0xD0D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0xD2D8: -case 0xD4D8: -case 0xD6D8: -case 0xD8D8: -case 0xDAD8: -case 0xDCD8: -case 0xDED8: -case 0xD0D9: -case 0xD2D9: -case 0xD4D9: -case 0xD6D9: -case 0xD8D9: -case 0xDAD9: -case 0xDCD9: -case 0xDED9: -case 0xD0DA: -case 0xD2DA: -case 0xD4DA: -case 0xD6DA: -case 0xD8DA: -case 0xDADA: -case 0xDCDA: -case 0xDEDA: -case 0xD0DB: -case 0xD2DB: -case 0xD4DB: -case 0xD6DB: -case 0xD8DB: -case 0xDADB: -case 0xDCDB: -case 0xDEDB: -case 0xD0DC: -case 0xD2DC: -case 0xD4DC: -case 0xD6DC: -case 0xD8DC: -case 0xDADC: -case 0xDCDC: -case 0xDEDC: -case 0xD0DD: -case 0xD2DD: -case 0xD4DD: -case 0xD6DD: -case 0xD8DD: -case 0xDADD: -case 0xDCDD: -case 0xDEDD: -case 0xD0DE: -case 0xD2DE: -case 0xD4DE: -case 0xD6DE: -case 0xD8DE: -case 0xDADE: -case 0xDCDE: -case 0xDEDE: - -// ADDA -case 0xD0D8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0xD2E0: -case 0xD4E0: -case 0xD6E0: -case 0xD8E0: -case 0xDAE0: -case 0xDCE0: -case 0xDEE0: -case 0xD0E1: -case 0xD2E1: -case 0xD4E1: -case 0xD6E1: -case 0xD8E1: -case 0xDAE1: -case 0xDCE1: -case 0xDEE1: -case 0xD0E2: -case 0xD2E2: -case 0xD4E2: -case 0xD6E2: -case 0xD8E2: -case 0xDAE2: -case 0xDCE2: -case 0xDEE2: -case 0xD0E3: -case 0xD2E3: -case 0xD4E3: -case 0xD6E3: -case 0xD8E3: -case 0xDAE3: -case 0xDCE3: -case 0xDEE3: -case 0xD0E4: -case 0xD2E4: -case 0xD4E4: -case 0xD6E4: -case 0xD8E4: -case 0xDAE4: -case 0xDCE4: -case 0xDEE4: -case 0xD0E5: -case 0xD2E5: -case 0xD4E5: -case 0xD6E5: -case 0xD8E5: -case 0xDAE5: -case 0xDCE5: -case 0xDEE5: -case 0xD0E6: -case 0xD2E6: -case 0xD4E6: -case 0xD6E6: -case 0xD8E6: -case 0xDAE6: -case 0xDCE6: -case 0xDEE6: - -// ADDA -case 0xD0E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(14) -case 0xD2E8: -case 0xD4E8: -case 0xD6E8: -case 0xD8E8: -case 0xDAE8: -case 0xDCE8: -case 0xDEE8: -case 0xD0E9: -case 0xD2E9: -case 0xD4E9: -case 0xD6E9: -case 0xD8E9: -case 0xDAE9: -case 0xDCE9: -case 0xDEE9: -case 0xD0EA: -case 0xD2EA: -case 0xD4EA: -case 0xD6EA: -case 0xD8EA: -case 0xDAEA: -case 0xDCEA: -case 0xDEEA: -case 0xD0EB: -case 0xD2EB: -case 0xD4EB: -case 0xD6EB: -case 0xD8EB: -case 0xDAEB: -case 0xDCEB: -case 0xDEEB: -case 0xD0EC: -case 0xD2EC: -case 0xD4EC: -case 0xD6EC: -case 0xD8EC: -case 0xDAEC: -case 0xDCEC: -case 0xDEEC: -case 0xD0ED: -case 0xD2ED: -case 0xD4ED: -case 0xD6ED: -case 0xD8ED: -case 0xDAED: -case 0xDCED: -case 0xDEED: -case 0xD0EE: -case 0xD2EE: -case 0xD4EE: -case 0xD6EE: -case 0xD8EE: -case 0xDAEE: -case 0xDCEE: -case 0xDEEE: -case 0xD0EF: -case 0xD2EF: -case 0xD4EF: -case 0xD6EF: -case 0xD8EF: -case 0xDAEF: -case 0xDCEF: -case 0xDEEF: - -// ADDA -case 0xD0E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0xD2F0: -case 0xD4F0: -case 0xD6F0: -case 0xD8F0: -case 0xDAF0: -case 0xDCF0: -case 0xDEF0: -case 0xD0F1: -case 0xD2F1: -case 0xD4F1: -case 0xD6F1: -case 0xD8F1: -case 0xDAF1: -case 0xDCF1: -case 0xDEF1: -case 0xD0F2: -case 0xD2F2: -case 0xD4F2: -case 0xD6F2: -case 0xD8F2: -case 0xDAF2: -case 0xDCF2: -case 0xDEF2: -case 0xD0F3: -case 0xD2F3: -case 0xD4F3: -case 0xD6F3: -case 0xD8F3: -case 0xDAF3: -case 0xDCF3: -case 0xDEF3: -case 0xD0F4: -case 0xD2F4: -case 0xD4F4: -case 0xD6F4: -case 0xD8F4: -case 0xDAF4: -case 0xDCF4: -case 0xDEF4: -case 0xD0F5: -case 0xD2F5: -case 0xD4F5: -case 0xD6F5: -case 0xD8F5: -case 0xDAF5: -case 0xDCF5: -case 0xDEF5: -case 0xD0F6: -case 0xD2F6: -case 0xD4F6: -case 0xD6F6: -case 0xD8F6: -case 0xDAF6: -case 0xDCF6: -case 0xDEF6: -case 0xD0F7: -case 0xD2F7: -case 0xD4F7: -case 0xD6F7: -case 0xD8F7: -case 0xDAF7: -case 0xDCF7: -case 0xDEF7: - -// ADDA -case 0xD0F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) -case 0xD2F8: -case 0xD4F8: -case 0xD6F8: -case 0xD8F8: -case 0xDAF8: -case 0xDCF8: -case 0xDEF8: - -// ADDA -case 0xD0F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0xD2F9: -case 0xD4F9: -case 0xD6F9: -case 0xD8F9: -case 0xDAF9: -case 0xDCF9: -case 0xDEF9: - -// ADDA -case 0xD0F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0xD2FA: -case 0xD4FA: -case 0xD6FA: -case 0xD8FA: -case 0xDAFA: -case 0xDCFA: -case 0xDEFA: - -// ADDA -case 0xD0FA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0xD2FB: -case 0xD4FB: -case 0xD6FB: -case 0xD8FB: -case 0xDAFB: -case 0xDCFB: -case 0xDEFB: - -// ADDA -case 0xD0FB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) -case 0xD2FC: -case 0xD4FC: -case 0xD6FC: -case 0xD8FC: -case 0xDAFC: -case 0xDCFC: -case 0xDEFC: - -// ADDA -case 0xD0FC: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s16)FETCH_WORD; - PC += 2; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(12) -case 0xD2DF: -case 0xD4DF: -case 0xD6DF: -case 0xD8DF: -case 0xDADF: -case 0xDCDF: -case 0xDEDF: - -// ADDA -case 0xD0DF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(12) -case 0xD2E7: -case 0xD4E7: -case 0xD6E7: -case 0xD8E7: -case 0xDAE7: -case 0xDCE7: -case 0xDEE7: - -// ADDA -case 0xD0E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READSX_WORD_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(14) -case 0xD3C0: -case 0xD5C0: -case 0xD7C0: -case 0xD9C0: -case 0xDBC0: -case 0xDDC0: -case 0xDFC0: -case 0xD1C1: -case 0xD3C1: -case 0xD5C1: -case 0xD7C1: -case 0xD9C1: -case 0xDBC1: -case 0xDDC1: -case 0xDFC1: -case 0xD1C2: -case 0xD3C2: -case 0xD5C2: -case 0xD7C2: -case 0xD9C2: -case 0xDBC2: -case 0xDDC2: -case 0xDFC2: -case 0xD1C3: -case 0xD3C3: -case 0xD5C3: -case 0xD7C3: -case 0xD9C3: -case 0xDBC3: -case 0xDDC3: -case 0xDFC3: -case 0xD1C4: -case 0xD3C4: -case 0xD5C4: -case 0xD7C4: -case 0xD9C4: -case 0xDBC4: -case 0xDDC4: -case 0xDFC4: -case 0xD1C5: -case 0xD3C5: -case 0xD5C5: -case 0xD7C5: -case 0xD9C5: -case 0xDBC5: -case 0xDDC5: -case 0xDFC5: -case 0xD1C6: -case 0xD3C6: -case 0xD5C6: -case 0xD7C6: -case 0xD9C6: -case 0xDBC6: -case 0xDDC6: -case 0xDFC6: -case 0xD1C7: -case 0xD3C7: -case 0xD5C7: -case 0xD7C7: -case 0xD9C7: -case 0xDBC7: -case 0xDDC7: -case 0xDFC7: - -// ADDA -case 0xD1C0: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)CPU->D[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(6) -case 0xD3C8: -case 0xD5C8: -case 0xD7C8: -case 0xD9C8: -case 0xDBC8: -case 0xDDC8: -case 0xDFC8: -case 0xD1C9: -case 0xD3C9: -case 0xD5C9: -case 0xD7C9: -case 0xD9C9: -case 0xDBC9: -case 0xDDC9: -case 0xDFC9: -case 0xD1CA: -case 0xD3CA: -case 0xD5CA: -case 0xD7CA: -case 0xD9CA: -case 0xDBCA: -case 0xDDCA: -case 0xDFCA: -case 0xD1CB: -case 0xD3CB: -case 0xD5CB: -case 0xD7CB: -case 0xD9CB: -case 0xDBCB: -case 0xDDCB: -case 0xDFCB: -case 0xD1CC: -case 0xD3CC: -case 0xD5CC: -case 0xD7CC: -case 0xD9CC: -case 0xDBCC: -case 0xDDCC: -case 0xDFCC: -case 0xD1CD: -case 0xD3CD: -case 0xD5CD: -case 0xD7CD: -case 0xD9CD: -case 0xDBCD: -case 0xDDCD: -case 0xDFCD: -case 0xD1CE: -case 0xD3CE: -case 0xD5CE: -case 0xD7CE: -case 0xD9CE: -case 0xDBCE: -case 0xDDCE: -case 0xDFCE: -case 0xD1CF: -case 0xD3CF: -case 0xD5CF: -case 0xD7CF: -case 0xD9CF: -case 0xDBCF: -case 0xDDCF: -case 0xDFCF: - -// ADDA -case 0xD1C8: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)CPU->A[(Opcode >> 0) & 7]; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(6) -case 0xD3D0: -case 0xD5D0: -case 0xD7D0: -case 0xD9D0: -case 0xDBD0: -case 0xDDD0: -case 0xDFD0: -case 0xD1D1: -case 0xD3D1: -case 0xD5D1: -case 0xD7D1: -case 0xD9D1: -case 0xDBD1: -case 0xDDD1: -case 0xDFD1: -case 0xD1D2: -case 0xD3D2: -case 0xD5D2: -case 0xD7D2: -case 0xD9D2: -case 0xDBD2: -case 0xDDD2: -case 0xDFD2: -case 0xD1D3: -case 0xD3D3: -case 0xD5D3: -case 0xD7D3: -case 0xD9D3: -case 0xDBD3: -case 0xDDD3: -case 0xDFD3: -case 0xD1D4: -case 0xD3D4: -case 0xD5D4: -case 0xD7D4: -case 0xD9D4: -case 0xDBD4: -case 0xDDD4: -case 0xDFD4: -case 0xD1D5: -case 0xD3D5: -case 0xD5D5: -case 0xD7D5: -case 0xD9D5: -case 0xDBD5: -case 0xDDD5: -case 0xDFD5: -case 0xD1D6: -case 0xD3D6: -case 0xD5D6: -case 0xD7D6: -case 0xD9D6: -case 0xDBD6: -case 0xDDD6: -case 0xDFD6: -case 0xD1D7: -case 0xD3D7: -case 0xD5D7: -case 0xD7D7: -case 0xD9D7: -case 0xDBD7: -case 0xDDD7: -case 0xDFD7: - -// ADDA -case 0xD1D0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0xD3D8: -case 0xD5D8: -case 0xD7D8: -case 0xD9D8: -case 0xDBD8: -case 0xDDD8: -case 0xDFD8: -case 0xD1D9: -case 0xD3D9: -case 0xD5D9: -case 0xD7D9: -case 0xD9D9: -case 0xDBD9: -case 0xDDD9: -case 0xDFD9: -case 0xD1DA: -case 0xD3DA: -case 0xD5DA: -case 0xD7DA: -case 0xD9DA: -case 0xDBDA: -case 0xDDDA: -case 0xDFDA: -case 0xD1DB: -case 0xD3DB: -case 0xD5DB: -case 0xD7DB: -case 0xD9DB: -case 0xDBDB: -case 0xDDDB: -case 0xDFDB: -case 0xD1DC: -case 0xD3DC: -case 0xD5DC: -case 0xD7DC: -case 0xD9DC: -case 0xDBDC: -case 0xDDDC: -case 0xDFDC: -case 0xD1DD: -case 0xD3DD: -case 0xD5DD: -case 0xD7DD: -case 0xD9DD: -case 0xDBDD: -case 0xDDDD: -case 0xDFDD: -case 0xD1DE: -case 0xD3DE: -case 0xD5DE: -case 0xD7DE: -case 0xD9DE: -case 0xDBDE: -case 0xDDDE: -case 0xDFDE: - -// ADDA -case 0xD1D8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0xD3E0: -case 0xD5E0: -case 0xD7E0: -case 0xD9E0: -case 0xDBE0: -case 0xDDE0: -case 0xDFE0: -case 0xD1E1: -case 0xD3E1: -case 0xD5E1: -case 0xD7E1: -case 0xD9E1: -case 0xDBE1: -case 0xDDE1: -case 0xDFE1: -case 0xD1E2: -case 0xD3E2: -case 0xD5E2: -case 0xD7E2: -case 0xD9E2: -case 0xDBE2: -case 0xDDE2: -case 0xDFE2: -case 0xD1E3: -case 0xD3E3: -case 0xD5E3: -case 0xD7E3: -case 0xD9E3: -case 0xDBE3: -case 0xDDE3: -case 0xDFE3: -case 0xD1E4: -case 0xD3E4: -case 0xD5E4: -case 0xD7E4: -case 0xD9E4: -case 0xDBE4: -case 0xDDE4: -case 0xDFE4: -case 0xD1E5: -case 0xD3E5: -case 0xD5E5: -case 0xD7E5: -case 0xD9E5: -case 0xDBE5: -case 0xDDE5: -case 0xDFE5: -case 0xD1E6: -case 0xD3E6: -case 0xD5E6: -case 0xD7E6: -case 0xD9E6: -case 0xDBE6: -case 0xDDE6: -case 0xDFE6: - -// ADDA -case 0xD1E0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 4; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) -case 0xD3E8: -case 0xD5E8: -case 0xD7E8: -case 0xD9E8: -case 0xDBE8: -case 0xDDE8: -case 0xDFE8: -case 0xD1E9: -case 0xD3E9: -case 0xD5E9: -case 0xD7E9: -case 0xD9E9: -case 0xDBE9: -case 0xDDE9: -case 0xDFE9: -case 0xD1EA: -case 0xD3EA: -case 0xD5EA: -case 0xD7EA: -case 0xD9EA: -case 0xDBEA: -case 0xDDEA: -case 0xDFEA: -case 0xD1EB: -case 0xD3EB: -case 0xD5EB: -case 0xD7EB: -case 0xD9EB: -case 0xDBEB: -case 0xDDEB: -case 0xDFEB: -case 0xD1EC: -case 0xD3EC: -case 0xD5EC: -case 0xD7EC: -case 0xD9EC: -case 0xDBEC: -case 0xDDEC: -case 0xDFEC: -case 0xD1ED: -case 0xD3ED: -case 0xD5ED: -case 0xD7ED: -case 0xD9ED: -case 0xDBED: -case 0xDDED: -case 0xDFED: -case 0xD1EE: -case 0xD3EE: -case 0xD5EE: -case 0xD7EE: -case 0xD9EE: -case 0xDBEE: -case 0xDDEE: -case 0xDFEE: -case 0xD1EF: -case 0xD3EF: -case 0xD5EF: -case 0xD7EF: -case 0xD9EF: -case 0xDBEF: -case 0xDDEF: -case 0xDFEF: - -// ADDA -case 0xD1E8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0xD3F0: -case 0xD5F0: -case 0xD7F0: -case 0xD9F0: -case 0xDBF0: -case 0xDDF0: -case 0xDFF0: -case 0xD1F1: -case 0xD3F1: -case 0xD5F1: -case 0xD7F1: -case 0xD9F1: -case 0xDBF1: -case 0xDDF1: -case 0xDFF1: -case 0xD1F2: -case 0xD3F2: -case 0xD5F2: -case 0xD7F2: -case 0xD9F2: -case 0xDBF2: -case 0xDDF2: -case 0xDFF2: -case 0xD1F3: -case 0xD3F3: -case 0xD5F3: -case 0xD7F3: -case 0xD9F3: -case 0xDBF3: -case 0xDDF3: -case 0xDFF3: -case 0xD1F4: -case 0xD3F4: -case 0xD5F4: -case 0xD7F4: -case 0xD9F4: -case 0xDBF4: -case 0xDDF4: -case 0xDFF4: -case 0xD1F5: -case 0xD3F5: -case 0xD5F5: -case 0xD7F5: -case 0xD9F5: -case 0xDBF5: -case 0xDDF5: -case 0xDFF5: -case 0xD1F6: -case 0xD3F6: -case 0xD5F6: -case 0xD7F6: -case 0xD9F6: -case 0xDBF6: -case 0xDDF6: -case 0xDFF6: -case 0xD1F7: -case 0xD3F7: -case 0xD5F7: -case 0xD7F7: -case 0xD9F7: -case 0xDBF7: -case 0xDDF7: -case 0xDFF7: - -// ADDA -case 0xD1F0: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(22) -case 0xD3F8: -case 0xD5F8: -case 0xD7F8: -case 0xD9F8: -case 0xDBF8: -case 0xDDF8: -case 0xDFF8: - -// ADDA -case 0xD1F8: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0xD3F9: -case 0xD5F9: -case 0xD7F9: -case 0xD9F9: -case 0xDBF9: -case 0xDDF9: -case 0xDFF9: - -// ADDA -case 0xD1F9: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(24) -case 0xD3FA: -case 0xD5FA: -case 0xD7FA: -case 0xD9FA: -case 0xDBFA: -case 0xDDFA: -case 0xDFFA: - -// ADDA -case 0xD1FA: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(20) -case 0xD3FB: -case 0xD5FB: -case 0xD7FB: -case 0xD9FB: -case 0xDBFB: -case 0xDDFB: -case 0xDFFB: - -// ADDA -case 0xD1FB: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = PC - CPU->BasePC; - DECODE_EXT_WORD - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(22) -case 0xD3FC: -case 0xD5FC: -case 0xD7FC: -case 0xD9FC: -case 0xDBFC: -case 0xDDFC: -case 0xDFFC: - -// ADDA -case 0xD1FC: -{ - u32 res; - pointer dst; - pointer src; - src = (s32)(s32)FETCH_LONG; - PC += 4; - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; -} -RET(14) -case 0xD3DF: -case 0xD5DF: -case 0xD7DF: -case 0xD9DF: -case 0xDBDF: -case 0xDDDF: -case 0xDFDF: - -// ADDA -case 0xD1DF: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 4; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(16) -case 0xD3E7: -case 0xD5E7: -case 0xD7E7: -case 0xD9E7: -case 0xDBE7: -case 0xDDE7: -case 0xDFE7: - -// ADDA -case 0xD1E7: -{ - u32 adr; - u32 res; - pointer dst; - pointer src; - adr = CPU->A[7] - 4; - CPU->A[7] = adr; - PRE_IO - READSX_LONG_F(adr, src) - dst = (u32)CPU->A[(Opcode >> 9) & 7]; - res = dst + src; - CPU->A[(Opcode >> 9) & 7] = res; - POST_IO -} -RET(18) diff --git a/yabause/src/c68k/c68k_opE.inc b/yabause/src/c68k/c68k_opE.inc deleted file mode 100644 index 29c55772fd..0000000000 --- a/yabause/src/c68k/c68k_opE.inc +++ /dev/null @@ -1,6130 +0,0 @@ -case 0xE200: -case 0xE400: -case 0xE600: -case 0xE800: -case 0xEA00: -case 0xEC00: -case 0xEE00: -case 0xE001: -case 0xE201: -case 0xE401: -case 0xE601: -case 0xE801: -case 0xEA01: -case 0xEC01: -case 0xEE01: -case 0xE002: -case 0xE202: -case 0xE402: -case 0xE602: -case 0xE802: -case 0xEA02: -case 0xEC02: -case 0xEE02: -case 0xE003: -case 0xE203: -case 0xE403: -case 0xE603: -case 0xE803: -case 0xEA03: -case 0xEC03: -case 0xEE03: -case 0xE004: -case 0xE204: -case 0xE404: -case 0xE604: -case 0xE804: -case 0xEA04: -case 0xEC04: -case 0xEE04: -case 0xE005: -case 0xE205: -case 0xE405: -case 0xE605: -case 0xE805: -case 0xEA05: -case 0xEC05: -case 0xEE05: -case 0xE006: -case 0xE206: -case 0xE406: -case 0xE606: -case 0xE806: -case 0xEA06: -case 0xEC06: -case 0xEE06: -case 0xE007: -case 0xE207: -case 0xE407: -case 0xE607: -case 0xE807: -case 0xEA07: -case 0xEC07: -case 0xEE07: - -// ASRk -case 0xE000: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (s32)(s8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = ((s32)src) >> sft; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE240: -case 0xE440: -case 0xE640: -case 0xE840: -case 0xEA40: -case 0xEC40: -case 0xEE40: -case 0xE041: -case 0xE241: -case 0xE441: -case 0xE641: -case 0xE841: -case 0xEA41: -case 0xEC41: -case 0xEE41: -case 0xE042: -case 0xE242: -case 0xE442: -case 0xE642: -case 0xE842: -case 0xEA42: -case 0xEC42: -case 0xEE42: -case 0xE043: -case 0xE243: -case 0xE443: -case 0xE643: -case 0xE843: -case 0xEA43: -case 0xEC43: -case 0xEE43: -case 0xE044: -case 0xE244: -case 0xE444: -case 0xE644: -case 0xE844: -case 0xEA44: -case 0xEC44: -case 0xEE44: -case 0xE045: -case 0xE245: -case 0xE445: -case 0xE645: -case 0xE845: -case 0xEA45: -case 0xEC45: -case 0xEE45: -case 0xE046: -case 0xE246: -case 0xE446: -case 0xE646: -case 0xE846: -case 0xEA46: -case 0xEC46: -case 0xEE46: -case 0xE047: -case 0xE247: -case 0xE447: -case 0xE647: -case 0xE847: -case 0xEA47: -case 0xEC47: -case 0xEE47: - -// ASRk -case 0xE040: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = ((s32)src) >> sft; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE280: -case 0xE480: -case 0xE680: -case 0xE880: -case 0xEA80: -case 0xEC80: -case 0xEE80: -case 0xE081: -case 0xE281: -case 0xE481: -case 0xE681: -case 0xE881: -case 0xEA81: -case 0xEC81: -case 0xEE81: -case 0xE082: -case 0xE282: -case 0xE482: -case 0xE682: -case 0xE882: -case 0xEA82: -case 0xEC82: -case 0xEE82: -case 0xE083: -case 0xE283: -case 0xE483: -case 0xE683: -case 0xE883: -case 0xEA83: -case 0xEC83: -case 0xEE83: -case 0xE084: -case 0xE284: -case 0xE484: -case 0xE684: -case 0xE884: -case 0xEA84: -case 0xEC84: -case 0xEE84: -case 0xE085: -case 0xE285: -case 0xE485: -case 0xE685: -case 0xE885: -case 0xEA85: -case 0xEC85: -case 0xEE85: -case 0xE086: -case 0xE286: -case 0xE486: -case 0xE686: -case 0xE886: -case 0xEA86: -case 0xEC86: -case 0xEE86: -case 0xE087: -case 0xE287: -case 0xE487: -case 0xE687: -case 0xE887: -case 0xEA87: -case 0xEC87: -case 0xEE87: - -// ASRk -case 0xE080: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (s32)(s32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = ((s32)src) >> sft; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0xE208: -case 0xE408: -case 0xE608: -case 0xE808: -case 0xEA08: -case 0xEC08: -case 0xEE08: -case 0xE009: -case 0xE209: -case 0xE409: -case 0xE609: -case 0xE809: -case 0xEA09: -case 0xEC09: -case 0xEE09: -case 0xE00A: -case 0xE20A: -case 0xE40A: -case 0xE60A: -case 0xE80A: -case 0xEA0A: -case 0xEC0A: -case 0xEE0A: -case 0xE00B: -case 0xE20B: -case 0xE40B: -case 0xE60B: -case 0xE80B: -case 0xEA0B: -case 0xEC0B: -case 0xEE0B: -case 0xE00C: -case 0xE20C: -case 0xE40C: -case 0xE60C: -case 0xE80C: -case 0xEA0C: -case 0xEC0C: -case 0xEE0C: -case 0xE00D: -case 0xE20D: -case 0xE40D: -case 0xE60D: -case 0xE80D: -case 0xEA0D: -case 0xEC0D: -case 0xEE0D: -case 0xE00E: -case 0xE20E: -case 0xE40E: -case 0xE60E: -case 0xE80E: -case 0xEA0E: -case 0xEC0E: -case 0xEE0E: -case 0xE00F: -case 0xE20F: -case 0xE40F: -case 0xE60F: -case 0xE80F: -case 0xEA0F: -case 0xEC0F: -case 0xEE0F: - -// LSRk -case 0xE008: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = src >> sft; - CPU->flag_notZ = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE248: -case 0xE448: -case 0xE648: -case 0xE848: -case 0xEA48: -case 0xEC48: -case 0xEE48: -case 0xE049: -case 0xE249: -case 0xE449: -case 0xE649: -case 0xE849: -case 0xEA49: -case 0xEC49: -case 0xEE49: -case 0xE04A: -case 0xE24A: -case 0xE44A: -case 0xE64A: -case 0xE84A: -case 0xEA4A: -case 0xEC4A: -case 0xEE4A: -case 0xE04B: -case 0xE24B: -case 0xE44B: -case 0xE64B: -case 0xE84B: -case 0xEA4B: -case 0xEC4B: -case 0xEE4B: -case 0xE04C: -case 0xE24C: -case 0xE44C: -case 0xE64C: -case 0xE84C: -case 0xEA4C: -case 0xEC4C: -case 0xEE4C: -case 0xE04D: -case 0xE24D: -case 0xE44D: -case 0xE64D: -case 0xE84D: -case 0xEA4D: -case 0xEC4D: -case 0xEE4D: -case 0xE04E: -case 0xE24E: -case 0xE44E: -case 0xE64E: -case 0xE84E: -case 0xEA4E: -case 0xEC4E: -case 0xEE4E: -case 0xE04F: -case 0xE24F: -case 0xE44F: -case 0xE64F: -case 0xE84F: -case 0xEA4F: -case 0xEC4F: -case 0xEE4F: - -// LSRk -case 0xE048: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = src >> sft; - CPU->flag_notZ = res; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE288: -case 0xE488: -case 0xE688: -case 0xE888: -case 0xEA88: -case 0xEC88: -case 0xEE88: -case 0xE089: -case 0xE289: -case 0xE489: -case 0xE689: -case 0xE889: -case 0xEA89: -case 0xEC89: -case 0xEE89: -case 0xE08A: -case 0xE28A: -case 0xE48A: -case 0xE68A: -case 0xE88A: -case 0xEA8A: -case 0xEC8A: -case 0xEE8A: -case 0xE08B: -case 0xE28B: -case 0xE48B: -case 0xE68B: -case 0xE88B: -case 0xEA8B: -case 0xEC8B: -case 0xEE8B: -case 0xE08C: -case 0xE28C: -case 0xE48C: -case 0xE68C: -case 0xE88C: -case 0xEA8C: -case 0xEC8C: -case 0xEE8C: -case 0xE08D: -case 0xE28D: -case 0xE48D: -case 0xE68D: -case 0xE88D: -case 0xEA8D: -case 0xEC8D: -case 0xEE8D: -case 0xE08E: -case 0xE28E: -case 0xE48E: -case 0xE68E: -case 0xE88E: -case 0xEA8E: -case 0xEC8E: -case 0xEE8E: -case 0xE08F: -case 0xE28F: -case 0xE48F: -case 0xE68F: -case 0xE88F: -case 0xEA8F: -case 0xEC8F: -case 0xEE8F: - -// LSRk -case 0xE088: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = src >> sft; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0xE210: -case 0xE410: -case 0xE610: -case 0xE810: -case 0xEA10: -case 0xEC10: -case 0xEE10: -case 0xE011: -case 0xE211: -case 0xE411: -case 0xE611: -case 0xE811: -case 0xEA11: -case 0xEC11: -case 0xEE11: -case 0xE012: -case 0xE212: -case 0xE412: -case 0xE612: -case 0xE812: -case 0xEA12: -case 0xEC12: -case 0xEE12: -case 0xE013: -case 0xE213: -case 0xE413: -case 0xE613: -case 0xE813: -case 0xEA13: -case 0xEC13: -case 0xEE13: -case 0xE014: -case 0xE214: -case 0xE414: -case 0xE614: -case 0xE814: -case 0xEA14: -case 0xEC14: -case 0xEE14: -case 0xE015: -case 0xE215: -case 0xE415: -case 0xE615: -case 0xE815: -case 0xEA15: -case 0xEC15: -case 0xEE15: -case 0xE016: -case 0xE216: -case 0xE416: -case 0xE616: -case 0xE816: -case 0xEA16: -case 0xEC16: -case 0xEE16: -case 0xE017: -case 0xE217: -case 0xE417: -case 0xE617: -case 0xE817: -case 0xEA17: -case 0xEC17: -case 0xEE17: - -// ROXRk -case 0xE010: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - src |= (CPU->flag_X & C68K_SR_X) << 0; - res = (src >> sft) | (src << (9 - sft)); - CPU->flag_X = CPU->flag_C = res >> 0; - CPU->flag_V = 0; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE250: -case 0xE450: -case 0xE650: -case 0xE850: -case 0xEA50: -case 0xEC50: -case 0xEE50: -case 0xE051: -case 0xE251: -case 0xE451: -case 0xE651: -case 0xE851: -case 0xEA51: -case 0xEC51: -case 0xEE51: -case 0xE052: -case 0xE252: -case 0xE452: -case 0xE652: -case 0xE852: -case 0xEA52: -case 0xEC52: -case 0xEE52: -case 0xE053: -case 0xE253: -case 0xE453: -case 0xE653: -case 0xE853: -case 0xEA53: -case 0xEC53: -case 0xEE53: -case 0xE054: -case 0xE254: -case 0xE454: -case 0xE654: -case 0xE854: -case 0xEA54: -case 0xEC54: -case 0xEE54: -case 0xE055: -case 0xE255: -case 0xE455: -case 0xE655: -case 0xE855: -case 0xEA55: -case 0xEC55: -case 0xEE55: -case 0xE056: -case 0xE256: -case 0xE456: -case 0xE656: -case 0xE856: -case 0xEA56: -case 0xEC56: -case 0xEE56: -case 0xE057: -case 0xE257: -case 0xE457: -case 0xE657: -case 0xE857: -case 0xEA57: -case 0xEC57: -case 0xEE57: - -// ROXRk -case 0xE050: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - src |= (CPU->flag_X & C68K_SR_X) << 8; - res = (src >> sft) | (src << (17 - sft)); - CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_V = 0; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE290: -case 0xE490: -case 0xE690: -case 0xE890: -case 0xEA90: -case 0xEC90: -case 0xEE90: -case 0xE091: -case 0xE291: -case 0xE491: -case 0xE691: -case 0xE891: -case 0xEA91: -case 0xEC91: -case 0xEE91: -case 0xE092: -case 0xE292: -case 0xE492: -case 0xE692: -case 0xE892: -case 0xEA92: -case 0xEC92: -case 0xEE92: -case 0xE093: -case 0xE293: -case 0xE493: -case 0xE693: -case 0xE893: -case 0xEA93: -case 0xEC93: -case 0xEE93: -case 0xE094: -case 0xE294: -case 0xE494: -case 0xE694: -case 0xE894: -case 0xEA94: -case 0xEC94: -case 0xEE94: -case 0xE095: -case 0xE295: -case 0xE495: -case 0xE695: -case 0xE895: -case 0xEA95: -case 0xEC95: -case 0xEE95: -case 0xE096: -case 0xE296: -case 0xE496: -case 0xE696: -case 0xE896: -case 0xEA96: -case 0xEC96: -case 0xEE96: -case 0xE097: -case 0xE297: -case 0xE497: -case 0xE697: -case 0xE897: -case 0xEA97: -case 0xEC97: -case 0xEE97: - -// ROXRk -case 0xE090: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - if (sft == 1) res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << (32 - (C68K_SR_X_SFT + 1))); - else res = (src >> sft) | (src << (33 - sft)) | ((CPU->flag_X & C68K_SR_X) << (32 - (C68K_SR_X_SFT + sft))); - CPU->flag_X = CPU->flag_C; - CPU->flag_V = 0; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0xE218: -case 0xE418: -case 0xE618: -case 0xE818: -case 0xEA18: -case 0xEC18: -case 0xEE18: -case 0xE019: -case 0xE219: -case 0xE419: -case 0xE619: -case 0xE819: -case 0xEA19: -case 0xEC19: -case 0xEE19: -case 0xE01A: -case 0xE21A: -case 0xE41A: -case 0xE61A: -case 0xE81A: -case 0xEA1A: -case 0xEC1A: -case 0xEE1A: -case 0xE01B: -case 0xE21B: -case 0xE41B: -case 0xE61B: -case 0xE81B: -case 0xEA1B: -case 0xEC1B: -case 0xEE1B: -case 0xE01C: -case 0xE21C: -case 0xE41C: -case 0xE61C: -case 0xE81C: -case 0xEA1C: -case 0xEC1C: -case 0xEE1C: -case 0xE01D: -case 0xE21D: -case 0xE41D: -case 0xE61D: -case 0xE81D: -case 0xEA1D: -case 0xEC1D: -case 0xEE1D: -case 0xE01E: -case 0xE21E: -case 0xE41E: -case 0xE61E: -case 0xE81E: -case 0xEA1E: -case 0xEC1E: -case 0xEE1E: -case 0xE01F: -case 0xE21F: -case 0xE41F: -case 0xE61F: -case 0xE81F: -case 0xEA1F: -case 0xEC1F: -case 0xEE1F: - -// RORk -case 0xE018: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = (src >> sft) | (src << (8 - sft)); - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE258: -case 0xE458: -case 0xE658: -case 0xE858: -case 0xEA58: -case 0xEC58: -case 0xEE58: -case 0xE059: -case 0xE259: -case 0xE459: -case 0xE659: -case 0xE859: -case 0xEA59: -case 0xEC59: -case 0xEE59: -case 0xE05A: -case 0xE25A: -case 0xE45A: -case 0xE65A: -case 0xE85A: -case 0xEA5A: -case 0xEC5A: -case 0xEE5A: -case 0xE05B: -case 0xE25B: -case 0xE45B: -case 0xE65B: -case 0xE85B: -case 0xEA5B: -case 0xEC5B: -case 0xEE5B: -case 0xE05C: -case 0xE25C: -case 0xE45C: -case 0xE65C: -case 0xE85C: -case 0xEA5C: -case 0xEC5C: -case 0xEE5C: -case 0xE05D: -case 0xE25D: -case 0xE45D: -case 0xE65D: -case 0xE85D: -case 0xEA5D: -case 0xEC5D: -case 0xEE5D: -case 0xE05E: -case 0xE25E: -case 0xE45E: -case 0xE65E: -case 0xE85E: -case 0xEA5E: -case 0xEC5E: -case 0xEE5E: -case 0xE05F: -case 0xE25F: -case 0xE45F: -case 0xE65F: -case 0xE85F: -case 0xEA5F: -case 0xEC5F: -case 0xEE5F: - -// RORk -case 0xE058: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = (src >> sft) | (src << (16 - sft)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE298: -case 0xE498: -case 0xE698: -case 0xE898: -case 0xEA98: -case 0xEC98: -case 0xEE98: -case 0xE099: -case 0xE299: -case 0xE499: -case 0xE699: -case 0xE899: -case 0xEA99: -case 0xEC99: -case 0xEE99: -case 0xE09A: -case 0xE29A: -case 0xE49A: -case 0xE69A: -case 0xE89A: -case 0xEA9A: -case 0xEC9A: -case 0xEE9A: -case 0xE09B: -case 0xE29B: -case 0xE49B: -case 0xE69B: -case 0xE89B: -case 0xEA9B: -case 0xEC9B: -case 0xEE9B: -case 0xE09C: -case 0xE29C: -case 0xE49C: -case 0xE69C: -case 0xE89C: -case 0xEA9C: -case 0xEC9C: -case 0xEE9C: -case 0xE09D: -case 0xE29D: -case 0xE49D: -case 0xE69D: -case 0xE89D: -case 0xEA9D: -case 0xEC9D: -case 0xEE9D: -case 0xE09E: -case 0xE29E: -case 0xE49E: -case 0xE69E: -case 0xE89E: -case 0xEA9E: -case 0xEC9E: -case 0xEE9E: -case 0xE09F: -case 0xE29F: -case 0xE49F: -case 0xE69F: -case 0xE89F: -case 0xEA9F: -case 0xEC9F: -case 0xEE9F: - -// RORk -case 0xE098: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = (src >> sft) | (src << (32 - sft)); - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0xE300: -case 0xE500: -case 0xE700: -case 0xE900: -case 0xEB00: -case 0xED00: -case 0xEF00: -case 0xE101: -case 0xE301: -case 0xE501: -case 0xE701: -case 0xE901: -case 0xEB01: -case 0xED01: -case 0xEF01: -case 0xE102: -case 0xE302: -case 0xE502: -case 0xE702: -case 0xE902: -case 0xEB02: -case 0xED02: -case 0xEF02: -case 0xE103: -case 0xE303: -case 0xE503: -case 0xE703: -case 0xE903: -case 0xEB03: -case 0xED03: -case 0xEF03: -case 0xE104: -case 0xE304: -case 0xE504: -case 0xE704: -case 0xE904: -case 0xEB04: -case 0xED04: -case 0xEF04: -case 0xE105: -case 0xE305: -case 0xE505: -case 0xE705: -case 0xE905: -case 0xEB05: -case 0xED05: -case 0xEF05: -case 0xE106: -case 0xE306: -case 0xE506: -case 0xE706: -case 0xE906: -case 0xEB06: -case 0xED06: -case 0xEF06: -case 0xE107: -case 0xE307: -case 0xE507: -case 0xE707: -case 0xE907: -case 0xEB07: -case 0xED07: -case 0xEF07: - -// ASLk -case 0xE100: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - if (sft < 8) - { - CPU->flag_X = CPU->flag_C = src << (0 + sft); - res = src << sft; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_V = 0; - if ((sft > 7) && (src)) CPU->flag_V = C68K_SR_V; - else - { - u32 msk = (((s32)0x80000000) >> (sft + 24)) & 0x000000FF; - src &= msk; - if ((src) && (src != msk)) CPU->flag_V = C68K_SR_V; - } - RET(6) - } - - if (src) CPU->flag_V = C68K_SR_V; - else CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_N = 0; - CPU->flag_notZ = 0; -} -RET(6) -case 0xE340: -case 0xE540: -case 0xE740: -case 0xE940: -case 0xEB40: -case 0xED40: -case 0xEF40: -case 0xE141: -case 0xE341: -case 0xE541: -case 0xE741: -case 0xE941: -case 0xEB41: -case 0xED41: -case 0xEF41: -case 0xE142: -case 0xE342: -case 0xE542: -case 0xE742: -case 0xE942: -case 0xEB42: -case 0xED42: -case 0xEF42: -case 0xE143: -case 0xE343: -case 0xE543: -case 0xE743: -case 0xE943: -case 0xEB43: -case 0xED43: -case 0xEF43: -case 0xE144: -case 0xE344: -case 0xE544: -case 0xE744: -case 0xE944: -case 0xEB44: -case 0xED44: -case 0xEF44: -case 0xE145: -case 0xE345: -case 0xE545: -case 0xE745: -case 0xE945: -case 0xEB45: -case 0xED45: -case 0xEF45: -case 0xE146: -case 0xE346: -case 0xE546: -case 0xE746: -case 0xE946: -case 0xEB46: -case 0xED46: -case 0xEF46: -case 0xE147: -case 0xE347: -case 0xE547: -case 0xE747: -case 0xE947: -case 0xEB47: -case 0xED47: -case 0xEF47: - -// ASLk -case 0xE140: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_X = CPU->flag_C = src >> (8 - sft); - res = src << sft; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_V = 0; - { - u32 msk = (((s32)0x80000000) >> (sft + 16)) & 0x0000FFFF; - src &= msk; - if ((src) && (src != msk)) CPU->flag_V = C68K_SR_V; - } -} -RET(6) -case 0xE380: -case 0xE580: -case 0xE780: -case 0xE980: -case 0xEB80: -case 0xED80: -case 0xEF80: -case 0xE181: -case 0xE381: -case 0xE581: -case 0xE781: -case 0xE981: -case 0xEB81: -case 0xED81: -case 0xEF81: -case 0xE182: -case 0xE382: -case 0xE582: -case 0xE782: -case 0xE982: -case 0xEB82: -case 0xED82: -case 0xEF82: -case 0xE183: -case 0xE383: -case 0xE583: -case 0xE783: -case 0xE983: -case 0xEB83: -case 0xED83: -case 0xEF83: -case 0xE184: -case 0xE384: -case 0xE584: -case 0xE784: -case 0xE984: -case 0xEB84: -case 0xED84: -case 0xEF84: -case 0xE185: -case 0xE385: -case 0xE585: -case 0xE785: -case 0xE985: -case 0xEB85: -case 0xED85: -case 0xEF85: -case 0xE186: -case 0xE386: -case 0xE586: -case 0xE786: -case 0xE986: -case 0xEB86: -case 0xED86: -case 0xEF86: -case 0xE187: -case 0xE387: -case 0xE587: -case 0xE787: -case 0xE987: -case 0xEB87: -case 0xED87: -case 0xEF87: - -// ASLk -case 0xE180: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_X = CPU->flag_C = src >> (24 - sft); - res = src << sft; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res & 0xFFFFFFFF; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_V = 0; - { - u32 msk = (((s32)0x80000000) >> (sft + 0)) & 0xFFFFFFFF; - src &= msk; - if ((src) && (src != msk)) CPU->flag_V = C68K_SR_V; - } -} -RET(8) -case 0xE308: -case 0xE508: -case 0xE708: -case 0xE908: -case 0xEB08: -case 0xED08: -case 0xEF08: -case 0xE109: -case 0xE309: -case 0xE509: -case 0xE709: -case 0xE909: -case 0xEB09: -case 0xED09: -case 0xEF09: -case 0xE10A: -case 0xE30A: -case 0xE50A: -case 0xE70A: -case 0xE90A: -case 0xEB0A: -case 0xED0A: -case 0xEF0A: -case 0xE10B: -case 0xE30B: -case 0xE50B: -case 0xE70B: -case 0xE90B: -case 0xEB0B: -case 0xED0B: -case 0xEF0B: -case 0xE10C: -case 0xE30C: -case 0xE50C: -case 0xE70C: -case 0xE90C: -case 0xEB0C: -case 0xED0C: -case 0xEF0C: -case 0xE10D: -case 0xE30D: -case 0xE50D: -case 0xE70D: -case 0xE90D: -case 0xEB0D: -case 0xED0D: -case 0xEF0D: -case 0xE10E: -case 0xE30E: -case 0xE50E: -case 0xE70E: -case 0xE90E: -case 0xEB0E: -case 0xED0E: -case 0xEF0E: -case 0xE10F: -case 0xE30F: -case 0xE50F: -case 0xE70F: -case 0xE90F: -case 0xEB0F: -case 0xED0F: -case 0xEF0F: - -// LSLk -case 0xE108: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << (0 + sft); - res = src << sft; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE348: -case 0xE548: -case 0xE748: -case 0xE948: -case 0xEB48: -case 0xED48: -case 0xEF48: -case 0xE149: -case 0xE349: -case 0xE549: -case 0xE749: -case 0xE949: -case 0xEB49: -case 0xED49: -case 0xEF49: -case 0xE14A: -case 0xE34A: -case 0xE54A: -case 0xE74A: -case 0xE94A: -case 0xEB4A: -case 0xED4A: -case 0xEF4A: -case 0xE14B: -case 0xE34B: -case 0xE54B: -case 0xE74B: -case 0xE94B: -case 0xEB4B: -case 0xED4B: -case 0xEF4B: -case 0xE14C: -case 0xE34C: -case 0xE54C: -case 0xE74C: -case 0xE94C: -case 0xEB4C: -case 0xED4C: -case 0xEF4C: -case 0xE14D: -case 0xE34D: -case 0xE54D: -case 0xE74D: -case 0xE94D: -case 0xEB4D: -case 0xED4D: -case 0xEF4D: -case 0xE14E: -case 0xE34E: -case 0xE54E: -case 0xE74E: -case 0xE94E: -case 0xEB4E: -case 0xED4E: -case 0xEF4E: -case 0xE14F: -case 0xE34F: -case 0xE54F: -case 0xE74F: -case 0xE94F: -case 0xEB4F: -case 0xED4F: -case 0xEF4F: - -// LSLk -case 0xE148: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> (8 - sft); - res = src << sft; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE388: -case 0xE588: -case 0xE788: -case 0xE988: -case 0xEB88: -case 0xED88: -case 0xEF88: -case 0xE189: -case 0xE389: -case 0xE589: -case 0xE789: -case 0xE989: -case 0xEB89: -case 0xED89: -case 0xEF89: -case 0xE18A: -case 0xE38A: -case 0xE58A: -case 0xE78A: -case 0xE98A: -case 0xEB8A: -case 0xED8A: -case 0xEF8A: -case 0xE18B: -case 0xE38B: -case 0xE58B: -case 0xE78B: -case 0xE98B: -case 0xEB8B: -case 0xED8B: -case 0xEF8B: -case 0xE18C: -case 0xE38C: -case 0xE58C: -case 0xE78C: -case 0xE98C: -case 0xEB8C: -case 0xED8C: -case 0xEF8C: -case 0xE18D: -case 0xE38D: -case 0xE58D: -case 0xE78D: -case 0xE98D: -case 0xEB8D: -case 0xED8D: -case 0xEF8D: -case 0xE18E: -case 0xE38E: -case 0xE58E: -case 0xE78E: -case 0xE98E: -case 0xEB8E: -case 0xED8E: -case 0xEF8E: -case 0xE18F: -case 0xE38F: -case 0xE58F: -case 0xE78F: -case 0xE98F: -case 0xEB8F: -case 0xED8F: -case 0xEF8F: - -// LSLk -case 0xE188: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> (24 - sft); - res = src << sft; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res & 0xFFFFFFFF; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0xE310: -case 0xE510: -case 0xE710: -case 0xE910: -case 0xEB10: -case 0xED10: -case 0xEF10: -case 0xE111: -case 0xE311: -case 0xE511: -case 0xE711: -case 0xE911: -case 0xEB11: -case 0xED11: -case 0xEF11: -case 0xE112: -case 0xE312: -case 0xE512: -case 0xE712: -case 0xE912: -case 0xEB12: -case 0xED12: -case 0xEF12: -case 0xE113: -case 0xE313: -case 0xE513: -case 0xE713: -case 0xE913: -case 0xEB13: -case 0xED13: -case 0xEF13: -case 0xE114: -case 0xE314: -case 0xE514: -case 0xE714: -case 0xE914: -case 0xEB14: -case 0xED14: -case 0xEF14: -case 0xE115: -case 0xE315: -case 0xE515: -case 0xE715: -case 0xE915: -case 0xEB15: -case 0xED15: -case 0xEF15: -case 0xE116: -case 0xE316: -case 0xE516: -case 0xE716: -case 0xE916: -case 0xEB16: -case 0xED16: -case 0xEF16: -case 0xE117: -case 0xE317: -case 0xE517: -case 0xE717: -case 0xE917: -case 0xEB17: -case 0xED17: -case 0xEF17: - -// ROXLk -case 0xE110: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - src |= (CPU->flag_X & C68K_SR_X) << 0; - res = (src << sft) | (src >> (9 - sft)); - CPU->flag_X = CPU->flag_C = res >> 0; - CPU->flag_V = 0; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE350: -case 0xE550: -case 0xE750: -case 0xE950: -case 0xEB50: -case 0xED50: -case 0xEF50: -case 0xE151: -case 0xE351: -case 0xE551: -case 0xE751: -case 0xE951: -case 0xEB51: -case 0xED51: -case 0xEF51: -case 0xE152: -case 0xE352: -case 0xE552: -case 0xE752: -case 0xE952: -case 0xEB52: -case 0xED52: -case 0xEF52: -case 0xE153: -case 0xE353: -case 0xE553: -case 0xE753: -case 0xE953: -case 0xEB53: -case 0xED53: -case 0xEF53: -case 0xE154: -case 0xE354: -case 0xE554: -case 0xE754: -case 0xE954: -case 0xEB54: -case 0xED54: -case 0xEF54: -case 0xE155: -case 0xE355: -case 0xE555: -case 0xE755: -case 0xE955: -case 0xEB55: -case 0xED55: -case 0xEF55: -case 0xE156: -case 0xE356: -case 0xE556: -case 0xE756: -case 0xE956: -case 0xEB56: -case 0xED56: -case 0xEF56: -case 0xE157: -case 0xE357: -case 0xE557: -case 0xE757: -case 0xE957: -case 0xEB57: -case 0xED57: -case 0xEF57: - -// ROXLk -case 0xE150: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - src |= (CPU->flag_X & C68K_SR_X) << 8; - res = (src << sft) | (src >> (17 - sft)); - CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_V = 0; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE390: -case 0xE590: -case 0xE790: -case 0xE990: -case 0xEB90: -case 0xED90: -case 0xEF90: -case 0xE191: -case 0xE391: -case 0xE591: -case 0xE791: -case 0xE991: -case 0xEB91: -case 0xED91: -case 0xEF91: -case 0xE192: -case 0xE392: -case 0xE592: -case 0xE792: -case 0xE992: -case 0xEB92: -case 0xED92: -case 0xEF92: -case 0xE193: -case 0xE393: -case 0xE593: -case 0xE793: -case 0xE993: -case 0xEB93: -case 0xED93: -case 0xEF93: -case 0xE194: -case 0xE394: -case 0xE594: -case 0xE794: -case 0xE994: -case 0xEB94: -case 0xED94: -case 0xEF94: -case 0xE195: -case 0xE395: -case 0xE595: -case 0xE795: -case 0xE995: -case 0xEB95: -case 0xED95: -case 0xEF95: -case 0xE196: -case 0xE396: -case 0xE596: -case 0xE796: -case 0xE996: -case 0xEB96: -case 0xED96: -case 0xEF96: -case 0xE197: -case 0xE397: -case 0xE597: -case 0xE797: -case 0xE997: -case 0xEB97: -case 0xED97: -case 0xEF97: - -// ROXLk -case 0xE190: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_C = src >> ((32 - C68K_SR_C_SFT) - sft); - if (sft == 1) res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> ((C68K_SR_X_SFT + 1) - 1)); - else res = (src << sft) | (src >> (33 - sft)) | ((CPU->flag_X & C68K_SR_X) >> ((C68K_SR_X_SFT + 1) - sft)); - CPU->flag_X = CPU->flag_C; - CPU->flag_V = 0; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0xE318: -case 0xE518: -case 0xE718: -case 0xE918: -case 0xEB18: -case 0xED18: -case 0xEF18: -case 0xE119: -case 0xE319: -case 0xE519: -case 0xE719: -case 0xE919: -case 0xEB19: -case 0xED19: -case 0xEF19: -case 0xE11A: -case 0xE31A: -case 0xE51A: -case 0xE71A: -case 0xE91A: -case 0xEB1A: -case 0xED1A: -case 0xEF1A: -case 0xE11B: -case 0xE31B: -case 0xE51B: -case 0xE71B: -case 0xE91B: -case 0xEB1B: -case 0xED1B: -case 0xEF1B: -case 0xE11C: -case 0xE31C: -case 0xE51C: -case 0xE71C: -case 0xE91C: -case 0xEB1C: -case 0xED1C: -case 0xEF1C: -case 0xE11D: -case 0xE31D: -case 0xE51D: -case 0xE71D: -case 0xE91D: -case 0xEB1D: -case 0xED1D: -case 0xEF1D: -case 0xE11E: -case 0xE31E: -case 0xE51E: -case 0xE71E: -case 0xE91E: -case 0xEB1E: -case 0xED1E: -case 0xEF1E: -case 0xE11F: -case 0xE31F: -case 0xE51F: -case 0xE71F: -case 0xE91F: -case 0xEB1F: -case 0xED1F: -case 0xEF1F: - -// ROLk -case 0xE118: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_C = src << (0 + sft); - res = (src << sft) | (src >> (8 - sft)); - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE358: -case 0xE558: -case 0xE758: -case 0xE958: -case 0xEB58: -case 0xED58: -case 0xEF58: -case 0xE159: -case 0xE359: -case 0xE559: -case 0xE759: -case 0xE959: -case 0xEB59: -case 0xED59: -case 0xEF59: -case 0xE15A: -case 0xE35A: -case 0xE55A: -case 0xE75A: -case 0xE95A: -case 0xEB5A: -case 0xED5A: -case 0xEF5A: -case 0xE15B: -case 0xE35B: -case 0xE55B: -case 0xE75B: -case 0xE95B: -case 0xEB5B: -case 0xED5B: -case 0xEF5B: -case 0xE15C: -case 0xE35C: -case 0xE55C: -case 0xE75C: -case 0xE95C: -case 0xEB5C: -case 0xED5C: -case 0xEF5C: -case 0xE15D: -case 0xE35D: -case 0xE55D: -case 0xE75D: -case 0xE95D: -case 0xEB5D: -case 0xED5D: -case 0xEF5D: -case 0xE15E: -case 0xE35E: -case 0xE55E: -case 0xE75E: -case 0xE95E: -case 0xEB5E: -case 0xED5E: -case 0xEF5E: -case 0xE15F: -case 0xE35F: -case 0xE55F: -case 0xE75F: -case 0xE95F: -case 0xEB5F: -case 0xED5F: -case 0xEF5F: - -// ROLk -case 0xE158: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_C = src >> (8 - sft); - res = (src << sft) | (src >> (16 - sft)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(6) -case 0xE398: -case 0xE598: -case 0xE798: -case 0xE998: -case 0xEB98: -case 0xED98: -case 0xEF98: -case 0xE199: -case 0xE399: -case 0xE599: -case 0xE799: -case 0xE999: -case 0xEB99: -case 0xED99: -case 0xEF99: -case 0xE19A: -case 0xE39A: -case 0xE59A: -case 0xE79A: -case 0xE99A: -case 0xEB9A: -case 0xED9A: -case 0xEF9A: -case 0xE19B: -case 0xE39B: -case 0xE59B: -case 0xE79B: -case 0xE99B: -case 0xEB9B: -case 0xED9B: -case 0xEF9B: -case 0xE19C: -case 0xE39C: -case 0xE59C: -case 0xE79C: -case 0xE99C: -case 0xEB9C: -case 0xED9C: -case 0xEF9C: -case 0xE19D: -case 0xE39D: -case 0xE59D: -case 0xE79D: -case 0xE99D: -case 0xEB9D: -case 0xED9D: -case 0xEF9D: -case 0xE19E: -case 0xE39E: -case 0xE59E: -case 0xE79E: -case 0xE99E: -case 0xEB9E: -case 0xED9E: -case 0xEF9E: -case 0xE19F: -case 0xE39F: -case 0xE59F: -case 0xE79F: -case 0xE99F: -case 0xEB9F: -case 0xED9F: -case 0xEF9F: - -// ROLk -case 0xE198: -{ - u32 res; - pointer src; - u32 sft; - - sft = (((Opcode >> 9) - 1) & 7) + 1; - CCnt -= sft * 2; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - CPU->flag_V = 0; - CPU->flag_C = src >> (24 - sft); - res = (src << sft) | (src >> (32 - sft)); - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; -} -RET(8) -case 0xE220: -case 0xE420: -case 0xE620: -case 0xE820: -case 0xEA20: -case 0xEC20: -case 0xEE20: -case 0xE021: -case 0xE221: -case 0xE421: -case 0xE621: -case 0xE821: -case 0xEA21: -case 0xEC21: -case 0xEE21: -case 0xE022: -case 0xE222: -case 0xE422: -case 0xE622: -case 0xE822: -case 0xEA22: -case 0xEC22: -case 0xEE22: -case 0xE023: -case 0xE223: -case 0xE423: -case 0xE623: -case 0xE823: -case 0xEA23: -case 0xEC23: -case 0xEE23: -case 0xE024: -case 0xE224: -case 0xE424: -case 0xE624: -case 0xE824: -case 0xEA24: -case 0xEC24: -case 0xEE24: -case 0xE025: -case 0xE225: -case 0xE425: -case 0xE625: -case 0xE825: -case 0xEA25: -case 0xEC25: -case 0xEE25: -case 0xE026: -case 0xE226: -case 0xE426: -case 0xE626: -case 0xE826: -case 0xEA26: -case 0xEC26: -case 0xEE26: -case 0xE027: -case 0xE227: -case 0xE427: -case 0xE627: -case 0xE827: -case 0xEA27: -case 0xEC27: -case 0xEE27: - -// ASRD -case 0xE020: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (s32)(s8)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft < 8) - { - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = ((s32)src) >> sft; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - if (src & (1 << 7)) - { - CPU->flag_N = C68K_SR_N; - CPU->flag_notZ = 1; - CPU->flag_V = 0; - CPU->flag_C = C68K_SR_C; - CPU->flag_X = C68K_SR_X; - res = 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_X = 0; - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; -} -RET(6) -case 0xE260: -case 0xE460: -case 0xE660: -case 0xE860: -case 0xEA60: -case 0xEC60: -case 0xEE60: -case 0xE061: -case 0xE261: -case 0xE461: -case 0xE661: -case 0xE861: -case 0xEA61: -case 0xEC61: -case 0xEE61: -case 0xE062: -case 0xE262: -case 0xE462: -case 0xE662: -case 0xE862: -case 0xEA62: -case 0xEC62: -case 0xEE62: -case 0xE063: -case 0xE263: -case 0xE463: -case 0xE663: -case 0xE863: -case 0xEA63: -case 0xEC63: -case 0xEE63: -case 0xE064: -case 0xE264: -case 0xE464: -case 0xE664: -case 0xE864: -case 0xEA64: -case 0xEC64: -case 0xEE64: -case 0xE065: -case 0xE265: -case 0xE465: -case 0xE665: -case 0xE865: -case 0xEA65: -case 0xEC65: -case 0xEE65: -case 0xE066: -case 0xE266: -case 0xE466: -case 0xE666: -case 0xE866: -case 0xEA66: -case 0xEC66: -case 0xEE66: -case 0xE067: -case 0xE267: -case 0xE467: -case 0xE667: -case 0xE867: -case 0xEA67: -case 0xEC67: -case 0xEE67: - -// ASRD -case 0xE060: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (s32)(s16)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft < 16) - { - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = (src >> (sft - 1)) << C68K_SR_C_SFT; - res = ((s32)src) >> sft; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - if (src & (1 << 15)) - { - CPU->flag_N = C68K_SR_N; - CPU->flag_notZ = 1; - CPU->flag_V = 0; - CPU->flag_C = C68K_SR_C; - CPU->flag_X = C68K_SR_X; - res = 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_X = 0; - res = 0; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; -} -RET(6) -case 0xE2A0: -case 0xE4A0: -case 0xE6A0: -case 0xE8A0: -case 0xEAA0: -case 0xECA0: -case 0xEEA0: -case 0xE0A1: -case 0xE2A1: -case 0xE4A1: -case 0xE6A1: -case 0xE8A1: -case 0xEAA1: -case 0xECA1: -case 0xEEA1: -case 0xE0A2: -case 0xE2A2: -case 0xE4A2: -case 0xE6A2: -case 0xE8A2: -case 0xEAA2: -case 0xECA2: -case 0xEEA2: -case 0xE0A3: -case 0xE2A3: -case 0xE4A3: -case 0xE6A3: -case 0xE8A3: -case 0xEAA3: -case 0xECA3: -case 0xEEA3: -case 0xE0A4: -case 0xE2A4: -case 0xE4A4: -case 0xE6A4: -case 0xE8A4: -case 0xEAA4: -case 0xECA4: -case 0xEEA4: -case 0xE0A5: -case 0xE2A5: -case 0xE4A5: -case 0xE6A5: -case 0xE8A5: -case 0xEAA5: -case 0xECA5: -case 0xEEA5: -case 0xE0A6: -case 0xE2A6: -case 0xE4A6: -case 0xE6A6: -case 0xE8A6: -case 0xEAA6: -case 0xECA6: -case 0xEEA6: -case 0xE0A7: -case 0xE2A7: -case 0xE4A7: -case 0xE6A7: -case 0xE8A7: -case 0xEAA7: -case 0xECA7: -case 0xEEA7: - -// ASRD -case 0xE0A0: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (s32)(s32)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft < 32) - { - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = (src >> (sft - 1)) << C68K_SR_C_SFT; - res = ((s32)src) >> sft; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - if (src & (1 << 31)) - { - CPU->flag_N = C68K_SR_N; - CPU->flag_notZ = 1; - CPU->flag_V = 0; - CPU->flag_C = C68K_SR_C; - CPU->flag_X = C68K_SR_X; - res = 0xFFFFFFFF; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_X = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; -} -RET(8) -case 0xE228: -case 0xE428: -case 0xE628: -case 0xE828: -case 0xEA28: -case 0xEC28: -case 0xEE28: -case 0xE029: -case 0xE229: -case 0xE429: -case 0xE629: -case 0xE829: -case 0xEA29: -case 0xEC29: -case 0xEE29: -case 0xE02A: -case 0xE22A: -case 0xE42A: -case 0xE62A: -case 0xE82A: -case 0xEA2A: -case 0xEC2A: -case 0xEE2A: -case 0xE02B: -case 0xE22B: -case 0xE42B: -case 0xE62B: -case 0xE82B: -case 0xEA2B: -case 0xEC2B: -case 0xEE2B: -case 0xE02C: -case 0xE22C: -case 0xE42C: -case 0xE62C: -case 0xE82C: -case 0xEA2C: -case 0xEC2C: -case 0xEE2C: -case 0xE02D: -case 0xE22D: -case 0xE42D: -case 0xE62D: -case 0xE82D: -case 0xEA2D: -case 0xEC2D: -case 0xEE2D: -case 0xE02E: -case 0xE22E: -case 0xE42E: -case 0xE62E: -case 0xE82E: -case 0xEA2E: -case 0xEC2E: -case 0xEE2E: -case 0xE02F: -case 0xE22F: -case 0xE42F: -case 0xE62F: -case 0xE82F: -case 0xEA2F: -case 0xEC2F: -case 0xEE2F: - -// LSRD -case 0xE028: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft <= 8) - { - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft); - res = src >> sft; - CPU->flag_notZ = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; -} -RET(6) -case 0xE268: -case 0xE468: -case 0xE668: -case 0xE868: -case 0xEA68: -case 0xEC68: -case 0xEE68: -case 0xE069: -case 0xE269: -case 0xE469: -case 0xE669: -case 0xE869: -case 0xEA69: -case 0xEC69: -case 0xEE69: -case 0xE06A: -case 0xE26A: -case 0xE46A: -case 0xE66A: -case 0xE86A: -case 0xEA6A: -case 0xEC6A: -case 0xEE6A: -case 0xE06B: -case 0xE26B: -case 0xE46B: -case 0xE66B: -case 0xE86B: -case 0xEA6B: -case 0xEC6B: -case 0xEE6B: -case 0xE06C: -case 0xE26C: -case 0xE46C: -case 0xE66C: -case 0xE86C: -case 0xEA6C: -case 0xEC6C: -case 0xEE6C: -case 0xE06D: -case 0xE26D: -case 0xE46D: -case 0xE66D: -case 0xE86D: -case 0xEA6D: -case 0xEC6D: -case 0xEE6D: -case 0xE06E: -case 0xE26E: -case 0xE46E: -case 0xE66E: -case 0xE86E: -case 0xEA6E: -case 0xEC6E: -case 0xEE6E: -case 0xE06F: -case 0xE26F: -case 0xE46F: -case 0xE66F: -case 0xE86F: -case 0xEA6F: -case 0xEC6F: -case 0xEE6F: - -// LSRD -case 0xE068: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft <= 16) - { - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = (src >> (sft - 1)) << C68K_SR_C_SFT; - res = src >> sft; - CPU->flag_notZ = res; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - res = 0; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; -} -RET(6) -case 0xE2A8: -case 0xE4A8: -case 0xE6A8: -case 0xE8A8: -case 0xEAA8: -case 0xECA8: -case 0xEEA8: -case 0xE0A9: -case 0xE2A9: -case 0xE4A9: -case 0xE6A9: -case 0xE8A9: -case 0xEAA9: -case 0xECA9: -case 0xEEA9: -case 0xE0AA: -case 0xE2AA: -case 0xE4AA: -case 0xE6AA: -case 0xE8AA: -case 0xEAAA: -case 0xECAA: -case 0xEEAA: -case 0xE0AB: -case 0xE2AB: -case 0xE4AB: -case 0xE6AB: -case 0xE8AB: -case 0xEAAB: -case 0xECAB: -case 0xEEAB: -case 0xE0AC: -case 0xE2AC: -case 0xE4AC: -case 0xE6AC: -case 0xE8AC: -case 0xEAAC: -case 0xECAC: -case 0xEEAC: -case 0xE0AD: -case 0xE2AD: -case 0xE4AD: -case 0xE6AD: -case 0xE8AD: -case 0xEAAD: -case 0xECAD: -case 0xEEAD: -case 0xE0AE: -case 0xE2AE: -case 0xE4AE: -case 0xE6AE: -case 0xE8AE: -case 0xEAAE: -case 0xECAE: -case 0xEEAE: -case 0xE0AF: -case 0xE2AF: -case 0xE4AF: -case 0xE6AF: -case 0xE8AF: -case 0xEAAF: -case 0xECAF: -case 0xEEAF: - -// LSRD -case 0xE0A8: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft < 32) - { - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = (src >> (sft - 1)) << C68K_SR_C_SFT; - res = src >> sft; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - if (sft == 32) CPU->flag_C = src >> (31 - C68K_SR_C_SFT); - else CPU->flag_C = 0; - CPU->flag_X = CPU->flag_C; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; -} -RET(8) -case 0xE230: -case 0xE430: -case 0xE630: -case 0xE830: -case 0xEA30: -case 0xEC30: -case 0xEE30: -case 0xE031: -case 0xE231: -case 0xE431: -case 0xE631: -case 0xE831: -case 0xEA31: -case 0xEC31: -case 0xEE31: -case 0xE032: -case 0xE232: -case 0xE432: -case 0xE632: -case 0xE832: -case 0xEA32: -case 0xEC32: -case 0xEE32: -case 0xE033: -case 0xE233: -case 0xE433: -case 0xE633: -case 0xE833: -case 0xEA33: -case 0xEC33: -case 0xEE33: -case 0xE034: -case 0xE234: -case 0xE434: -case 0xE634: -case 0xE834: -case 0xEA34: -case 0xEC34: -case 0xEE34: -case 0xE035: -case 0xE235: -case 0xE435: -case 0xE635: -case 0xE835: -case 0xEA35: -case 0xEC35: -case 0xEE35: -case 0xE036: -case 0xE236: -case 0xE436: -case 0xE636: -case 0xE836: -case 0xEA36: -case 0xEC36: -case 0xEE36: -case 0xE037: -case 0xE237: -case 0xE437: -case 0xE637: -case 0xE837: -case 0xEA37: -case 0xEC37: -case 0xEE37: - -// ROXRD -case 0xE030: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft %= 9; - - src |= (CPU->flag_X & C68K_SR_X) << 0; - res = (src >> sft) | (src << (9 - sft)); - CPU->flag_X = CPU->flag_C = res >> 0; - CPU->flag_V = 0; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = CPU->flag_X; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; -} -RET(6) -case 0xE270: -case 0xE470: -case 0xE670: -case 0xE870: -case 0xEA70: -case 0xEC70: -case 0xEE70: -case 0xE071: -case 0xE271: -case 0xE471: -case 0xE671: -case 0xE871: -case 0xEA71: -case 0xEC71: -case 0xEE71: -case 0xE072: -case 0xE272: -case 0xE472: -case 0xE672: -case 0xE872: -case 0xEA72: -case 0xEC72: -case 0xEE72: -case 0xE073: -case 0xE273: -case 0xE473: -case 0xE673: -case 0xE873: -case 0xEA73: -case 0xEC73: -case 0xEE73: -case 0xE074: -case 0xE274: -case 0xE474: -case 0xE674: -case 0xE874: -case 0xEA74: -case 0xEC74: -case 0xEE74: -case 0xE075: -case 0xE275: -case 0xE475: -case 0xE675: -case 0xE875: -case 0xEA75: -case 0xEC75: -case 0xEE75: -case 0xE076: -case 0xE276: -case 0xE476: -case 0xE676: -case 0xE876: -case 0xEA76: -case 0xEC76: -case 0xEE76: -case 0xE077: -case 0xE277: -case 0xE477: -case 0xE677: -case 0xE877: -case 0xEA77: -case 0xEC77: -case 0xEE77: - -// ROXRD -case 0xE070: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft %= 17; - - src |= (CPU->flag_X & C68K_SR_X) << 8; - res = (src >> sft) | (src << (17 - sft)); - CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_V = 0; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = CPU->flag_X; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; -} -RET(6) -case 0xE2B0: -case 0xE4B0: -case 0xE6B0: -case 0xE8B0: -case 0xEAB0: -case 0xECB0: -case 0xEEB0: -case 0xE0B1: -case 0xE2B1: -case 0xE4B1: -case 0xE6B1: -case 0xE8B1: -case 0xEAB1: -case 0xECB1: -case 0xEEB1: -case 0xE0B2: -case 0xE2B2: -case 0xE4B2: -case 0xE6B2: -case 0xE8B2: -case 0xEAB2: -case 0xECB2: -case 0xEEB2: -case 0xE0B3: -case 0xE2B3: -case 0xE4B3: -case 0xE6B3: -case 0xE8B3: -case 0xEAB3: -case 0xECB3: -case 0xEEB3: -case 0xE0B4: -case 0xE2B4: -case 0xE4B4: -case 0xE6B4: -case 0xE8B4: -case 0xEAB4: -case 0xECB4: -case 0xEEB4: -case 0xE0B5: -case 0xE2B5: -case 0xE4B5: -case 0xE6B5: -case 0xE8B5: -case 0xEAB5: -case 0xECB5: -case 0xEEB5: -case 0xE0B6: -case 0xE2B6: -case 0xE4B6: -case 0xE6B6: -case 0xE8B6: -case 0xEAB6: -case 0xECB6: -case 0xEEB6: -case 0xE0B7: -case 0xE2B7: -case 0xE4B7: -case 0xE6B7: -case 0xE8B7: -case 0xEAB7: -case 0xECB7: -case 0xEEB7: - -// ROXRD -case 0xE0B0: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft %= 33; - - if (sft != 0) - { - if (sft == 1) res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << (32 - (C68K_SR_X_SFT + 1))); - else res = (src >> sft) | (src << (33 - sft)) | (((CPU->flag_X & C68K_SR_X) << (32 - (C68K_SR_X_SFT + 1))) >> (sft - 1)); - CPU->flag_X = (src >> (32 - sft)) << C68K_SR_X_SFT; - } - else res = src; - CPU->flag_C = CPU->flag_X; - CPU->flag_V = 0; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = CPU->flag_X; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; -} -RET(8) -case 0xE238: -case 0xE438: -case 0xE638: -case 0xE838: -case 0xEA38: -case 0xEC38: -case 0xEE38: -case 0xE039: -case 0xE239: -case 0xE439: -case 0xE639: -case 0xE839: -case 0xEA39: -case 0xEC39: -case 0xEE39: -case 0xE03A: -case 0xE23A: -case 0xE43A: -case 0xE63A: -case 0xE83A: -case 0xEA3A: -case 0xEC3A: -case 0xEE3A: -case 0xE03B: -case 0xE23B: -case 0xE43B: -case 0xE63B: -case 0xE83B: -case 0xEA3B: -case 0xEC3B: -case 0xEE3B: -case 0xE03C: -case 0xE23C: -case 0xE43C: -case 0xE63C: -case 0xE83C: -case 0xEA3C: -case 0xEC3C: -case 0xEE3C: -case 0xE03D: -case 0xE23D: -case 0xE43D: -case 0xE63D: -case 0xE83D: -case 0xEA3D: -case 0xEC3D: -case 0xEE3D: -case 0xE03E: -case 0xE23E: -case 0xE43E: -case 0xE63E: -case 0xE83E: -case 0xEA3E: -case 0xEC3E: -case 0xEE3E: -case 0xE03F: -case 0xE23F: -case 0xE43F: -case 0xE63F: -case 0xE83F: -case 0xEA3F: -case 0xEC3F: -case 0xEE3F: - -// RORD -case 0xE038: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft &= 0x07; - - CPU->flag_C = src << (C68K_SR_C_SFT - ((sft - 1) & 7)); - res = (src >> sft) | (src << (8 - sft)); - CPU->flag_V = 0; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; -} -RET(6) -case 0xE278: -case 0xE478: -case 0xE678: -case 0xE878: -case 0xEA78: -case 0xEC78: -case 0xEE78: -case 0xE079: -case 0xE279: -case 0xE479: -case 0xE679: -case 0xE879: -case 0xEA79: -case 0xEC79: -case 0xEE79: -case 0xE07A: -case 0xE27A: -case 0xE47A: -case 0xE67A: -case 0xE87A: -case 0xEA7A: -case 0xEC7A: -case 0xEE7A: -case 0xE07B: -case 0xE27B: -case 0xE47B: -case 0xE67B: -case 0xE87B: -case 0xEA7B: -case 0xEC7B: -case 0xEE7B: -case 0xE07C: -case 0xE27C: -case 0xE47C: -case 0xE67C: -case 0xE87C: -case 0xEA7C: -case 0xEC7C: -case 0xEE7C: -case 0xE07D: -case 0xE27D: -case 0xE47D: -case 0xE67D: -case 0xE87D: -case 0xEA7D: -case 0xEC7D: -case 0xEE7D: -case 0xE07E: -case 0xE27E: -case 0xE47E: -case 0xE67E: -case 0xE87E: -case 0xEA7E: -case 0xEC7E: -case 0xEE7E: -case 0xE07F: -case 0xE27F: -case 0xE47F: -case 0xE67F: -case 0xE87F: -case 0xEA7F: -case 0xEC7F: -case 0xEE7F: - -// RORD -case 0xE078: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft &= 0x0F; - - CPU->flag_C = (src >> ((sft - 1) & 15)) << C68K_SR_C_SFT; - res = (src >> sft) | (src << (16 - sft)); - CPU->flag_V = 0; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; -} -RET(6) -case 0xE2B8: -case 0xE4B8: -case 0xE6B8: -case 0xE8B8: -case 0xEAB8: -case 0xECB8: -case 0xEEB8: -case 0xE0B9: -case 0xE2B9: -case 0xE4B9: -case 0xE6B9: -case 0xE8B9: -case 0xEAB9: -case 0xECB9: -case 0xEEB9: -case 0xE0BA: -case 0xE2BA: -case 0xE4BA: -case 0xE6BA: -case 0xE8BA: -case 0xEABA: -case 0xECBA: -case 0xEEBA: -case 0xE0BB: -case 0xE2BB: -case 0xE4BB: -case 0xE6BB: -case 0xE8BB: -case 0xEABB: -case 0xECBB: -case 0xEEBB: -case 0xE0BC: -case 0xE2BC: -case 0xE4BC: -case 0xE6BC: -case 0xE8BC: -case 0xEABC: -case 0xECBC: -case 0xEEBC: -case 0xE0BD: -case 0xE2BD: -case 0xE4BD: -case 0xE6BD: -case 0xE8BD: -case 0xEABD: -case 0xECBD: -case 0xEEBD: -case 0xE0BE: -case 0xE2BE: -case 0xE4BE: -case 0xE6BE: -case 0xE8BE: -case 0xEABE: -case 0xECBE: -case 0xEEBE: -case 0xE0BF: -case 0xE2BF: -case 0xE4BF: -case 0xE6BF: -case 0xE8BF: -case 0xEABF: -case 0xECBF: -case 0xEEBF: - -// RORD -case 0xE0B8: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft &= 0x1F; - - CPU->flag_C = (src >> ((sft - 1) & 31)) << C68K_SR_C_SFT; - res = (src >> sft) | (src << (32 - sft)); - CPU->flag_V = 0; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; -} -RET(8) -case 0xE320: -case 0xE520: -case 0xE720: -case 0xE920: -case 0xEB20: -case 0xED20: -case 0xEF20: -case 0xE121: -case 0xE321: -case 0xE521: -case 0xE721: -case 0xE921: -case 0xEB21: -case 0xED21: -case 0xEF21: -case 0xE122: -case 0xE322: -case 0xE522: -case 0xE722: -case 0xE922: -case 0xEB22: -case 0xED22: -case 0xEF22: -case 0xE123: -case 0xE323: -case 0xE523: -case 0xE723: -case 0xE923: -case 0xEB23: -case 0xED23: -case 0xEF23: -case 0xE124: -case 0xE324: -case 0xE524: -case 0xE724: -case 0xE924: -case 0xEB24: -case 0xED24: -case 0xEF24: -case 0xE125: -case 0xE325: -case 0xE525: -case 0xE725: -case 0xE925: -case 0xEB25: -case 0xED25: -case 0xEF25: -case 0xE126: -case 0xE326: -case 0xE526: -case 0xE726: -case 0xE926: -case 0xEB26: -case 0xED26: -case 0xEF26: -case 0xE127: -case 0xE327: -case 0xE527: -case 0xE727: -case 0xE927: -case 0xEB27: -case 0xED27: -case 0xEF27: - -// ASLD -case 0xE120: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft < 8) - { - CPU->flag_X = CPU->flag_C = (src << sft) >> 0; - res = (src << sft) & 0x000000FF; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_V = 0; - { - u32 msk = (((s32)0x80000000) >> (sft + 24)) & 0x000000FF; - src &= msk; - if ((src) && (src != msk)) CPU->flag_V = C68K_SR_V; - } - RET(6) - } - - if (sft == 256) CPU->flag_C = src << C68K_SR_C_SFT; - else CPU->flag_C = 0; - CPU->flag_X = CPU->flag_C; - if (src) CPU->flag_V = C68K_SR_V; - else CPU->flag_V = 0; - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; -} -RET(6) -case 0xE360: -case 0xE560: -case 0xE760: -case 0xE960: -case 0xEB60: -case 0xED60: -case 0xEF60: -case 0xE161: -case 0xE361: -case 0xE561: -case 0xE761: -case 0xE961: -case 0xEB61: -case 0xED61: -case 0xEF61: -case 0xE162: -case 0xE362: -case 0xE562: -case 0xE762: -case 0xE962: -case 0xEB62: -case 0xED62: -case 0xEF62: -case 0xE163: -case 0xE363: -case 0xE563: -case 0xE763: -case 0xE963: -case 0xEB63: -case 0xED63: -case 0xEF63: -case 0xE164: -case 0xE364: -case 0xE564: -case 0xE764: -case 0xE964: -case 0xEB64: -case 0xED64: -case 0xEF64: -case 0xE165: -case 0xE365: -case 0xE565: -case 0xE765: -case 0xE965: -case 0xEB65: -case 0xED65: -case 0xEF65: -case 0xE166: -case 0xE366: -case 0xE566: -case 0xE766: -case 0xE966: -case 0xEB66: -case 0xED66: -case 0xEF66: -case 0xE167: -case 0xE367: -case 0xE567: -case 0xE767: -case 0xE967: -case 0xEB67: -case 0xED67: -case 0xEF67: - -// ASLD -case 0xE160: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft < 16) - { - CPU->flag_X = CPU->flag_C = (src << sft) >> 8; - res = (src << sft) & 0x0000FFFF; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_V = 0; - { - u32 msk = (((s32)0x80000000) >> (sft + 16)) & 0x0000FFFF; - src &= msk; - if ((src) && (src != msk)) CPU->flag_V = C68K_SR_V; - } - RET(6) - } - - if (sft == 65536) CPU->flag_C = src << C68K_SR_C_SFT; - else CPU->flag_C = 0; - CPU->flag_X = CPU->flag_C; - if (src) CPU->flag_V = C68K_SR_V; - else CPU->flag_V = 0; - res = 0; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; -} -RET(6) -case 0xE3A0: -case 0xE5A0: -case 0xE7A0: -case 0xE9A0: -case 0xEBA0: -case 0xEDA0: -case 0xEFA0: -case 0xE1A1: -case 0xE3A1: -case 0xE5A1: -case 0xE7A1: -case 0xE9A1: -case 0xEBA1: -case 0xEDA1: -case 0xEFA1: -case 0xE1A2: -case 0xE3A2: -case 0xE5A2: -case 0xE7A2: -case 0xE9A2: -case 0xEBA2: -case 0xEDA2: -case 0xEFA2: -case 0xE1A3: -case 0xE3A3: -case 0xE5A3: -case 0xE7A3: -case 0xE9A3: -case 0xEBA3: -case 0xEDA3: -case 0xEFA3: -case 0xE1A4: -case 0xE3A4: -case 0xE5A4: -case 0xE7A4: -case 0xE9A4: -case 0xEBA4: -case 0xEDA4: -case 0xEFA4: -case 0xE1A5: -case 0xE3A5: -case 0xE5A5: -case 0xE7A5: -case 0xE9A5: -case 0xEBA5: -case 0xEDA5: -case 0xEFA5: -case 0xE1A6: -case 0xE3A6: -case 0xE5A6: -case 0xE7A6: -case 0xE9A6: -case 0xEBA6: -case 0xEDA6: -case 0xEFA6: -case 0xE1A7: -case 0xE3A7: -case 0xE5A7: -case 0xE7A7: -case 0xE9A7: -case 0xEBA7: -case 0xEDA7: -case 0xEFA7: - -// ASLD -case 0xE1A0: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft < 32) - { - CPU->flag_X = CPU->flag_C = (src >> (32 - sft)) << C68K_SR_C_SFT; - res = src << sft; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_V = 0; - { - u32 msk = (((s32)0x80000000) >> (sft + 0)) & 0xFFFFFFFF; - src &= msk; - if ((src) && (src != msk)) CPU->flag_V = C68K_SR_V; - } - RET(8) - } - - if (sft == 0) CPU->flag_C = src << C68K_SR_C_SFT; - else CPU->flag_C = 0; - CPU->flag_X = CPU->flag_C; - if (src) CPU->flag_V = C68K_SR_V; - else CPU->flag_V = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; -} -RET(8) -case 0xE328: -case 0xE528: -case 0xE728: -case 0xE928: -case 0xEB28: -case 0xED28: -case 0xEF28: -case 0xE129: -case 0xE329: -case 0xE529: -case 0xE729: -case 0xE929: -case 0xEB29: -case 0xED29: -case 0xEF29: -case 0xE12A: -case 0xE32A: -case 0xE52A: -case 0xE72A: -case 0xE92A: -case 0xEB2A: -case 0xED2A: -case 0xEF2A: -case 0xE12B: -case 0xE32B: -case 0xE52B: -case 0xE72B: -case 0xE92B: -case 0xEB2B: -case 0xED2B: -case 0xEF2B: -case 0xE12C: -case 0xE32C: -case 0xE52C: -case 0xE72C: -case 0xE92C: -case 0xEB2C: -case 0xED2C: -case 0xEF2C: -case 0xE12D: -case 0xE32D: -case 0xE52D: -case 0xE72D: -case 0xE92D: -case 0xEB2D: -case 0xED2D: -case 0xEF2D: -case 0xE12E: -case 0xE32E: -case 0xE52E: -case 0xE72E: -case 0xE92E: -case 0xEB2E: -case 0xED2E: -case 0xEF2E: -case 0xE12F: -case 0xE32F: -case 0xE52F: -case 0xE72F: -case 0xE92F: -case 0xEB2F: -case 0xED2F: -case 0xEF2F: - -// LSLD -case 0xE128: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft <= 8) - { - CPU->flag_X = CPU->flag_C = (src << sft) >> 0; - res = (src << sft) & 0x000000FF; - CPU->flag_V = 0; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - res = 0; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; -} -RET(6) -case 0xE368: -case 0xE568: -case 0xE768: -case 0xE968: -case 0xEB68: -case 0xED68: -case 0xEF68: -case 0xE169: -case 0xE369: -case 0xE569: -case 0xE769: -case 0xE969: -case 0xEB69: -case 0xED69: -case 0xEF69: -case 0xE16A: -case 0xE36A: -case 0xE56A: -case 0xE76A: -case 0xE96A: -case 0xEB6A: -case 0xED6A: -case 0xEF6A: -case 0xE16B: -case 0xE36B: -case 0xE56B: -case 0xE76B: -case 0xE96B: -case 0xEB6B: -case 0xED6B: -case 0xEF6B: -case 0xE16C: -case 0xE36C: -case 0xE56C: -case 0xE76C: -case 0xE96C: -case 0xEB6C: -case 0xED6C: -case 0xEF6C: -case 0xE16D: -case 0xE36D: -case 0xE56D: -case 0xE76D: -case 0xE96D: -case 0xEB6D: -case 0xED6D: -case 0xEF6D: -case 0xE16E: -case 0xE36E: -case 0xE56E: -case 0xE76E: -case 0xE96E: -case 0xEB6E: -case 0xED6E: -case 0xEF6E: -case 0xE16F: -case 0xE36F: -case 0xE56F: -case 0xE76F: -case 0xE96F: -case 0xEB6F: -case 0xED6F: -case 0xEF6F: - -// LSLD -case 0xE168: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft <= 16) - { - CPU->flag_X = CPU->flag_C = (src << sft) >> 8; - res = (src << sft) & 0x0000FFFF; - CPU->flag_V = 0; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_X = CPU->flag_C = 0; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - res = 0; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; -} -RET(6) -case 0xE3A8: -case 0xE5A8: -case 0xE7A8: -case 0xE9A8: -case 0xEBA8: -case 0xEDA8: -case 0xEFA8: -case 0xE1A9: -case 0xE3A9: -case 0xE5A9: -case 0xE7A9: -case 0xE9A9: -case 0xEBA9: -case 0xEDA9: -case 0xEFA9: -case 0xE1AA: -case 0xE3AA: -case 0xE5AA: -case 0xE7AA: -case 0xE9AA: -case 0xEBAA: -case 0xEDAA: -case 0xEFAA: -case 0xE1AB: -case 0xE3AB: -case 0xE5AB: -case 0xE7AB: -case 0xE9AB: -case 0xEBAB: -case 0xEDAB: -case 0xEFAB: -case 0xE1AC: -case 0xE3AC: -case 0xE5AC: -case 0xE7AC: -case 0xE9AC: -case 0xEBAC: -case 0xEDAC: -case 0xEFAC: -case 0xE1AD: -case 0xE3AD: -case 0xE5AD: -case 0xE7AD: -case 0xE9AD: -case 0xEBAD: -case 0xEDAD: -case 0xEFAD: -case 0xE1AE: -case 0xE3AE: -case 0xE5AE: -case 0xE7AE: -case 0xE9AE: -case 0xEBAE: -case 0xEDAE: -case 0xEFAE: -case 0xE1AF: -case 0xE3AF: -case 0xE5AF: -case 0xE7AF: -case 0xE9AF: -case 0xEBAF: -case 0xEDAF: -case 0xEFAF: - -// LSLD -case 0xE1A8: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft < 32) - { - CPU->flag_X = CPU->flag_C = (src >> (32 - sft)) << C68K_SR_C_SFT; - res = src << sft; - CPU->flag_V = 0; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - if (sft == 32) CPU->flag_C = src << C68K_SR_C_SFT; - else CPU->flag_C = 0; - CPU->flag_X = CPU->flag_C; - CPU->flag_N = 0; - CPU->flag_notZ = 0; - CPU->flag_V = 0; - res = 0; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; -} -RET(8) -case 0xE330: -case 0xE530: -case 0xE730: -case 0xE930: -case 0xEB30: -case 0xED30: -case 0xEF30: -case 0xE131: -case 0xE331: -case 0xE531: -case 0xE731: -case 0xE931: -case 0xEB31: -case 0xED31: -case 0xEF31: -case 0xE132: -case 0xE332: -case 0xE532: -case 0xE732: -case 0xE932: -case 0xEB32: -case 0xED32: -case 0xEF32: -case 0xE133: -case 0xE333: -case 0xE533: -case 0xE733: -case 0xE933: -case 0xEB33: -case 0xED33: -case 0xEF33: -case 0xE134: -case 0xE334: -case 0xE534: -case 0xE734: -case 0xE934: -case 0xEB34: -case 0xED34: -case 0xEF34: -case 0xE135: -case 0xE335: -case 0xE535: -case 0xE735: -case 0xE935: -case 0xEB35: -case 0xED35: -case 0xEF35: -case 0xE136: -case 0xE336: -case 0xE536: -case 0xE736: -case 0xE936: -case 0xEB36: -case 0xED36: -case 0xEF36: -case 0xE137: -case 0xE337: -case 0xE537: -case 0xE737: -case 0xE937: -case 0xEB37: -case 0xED37: -case 0xEF37: - -// ROXLD -case 0xE130: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft %= 9; - - src |= (CPU->flag_X & C68K_SR_X) << 0; - res = (src << sft) | (src >> (9 - sft)); - CPU->flag_X = CPU->flag_C = res >> 0; - CPU->flag_V = 0; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res & 0x000000FF; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = CPU->flag_X; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; -} -RET(6) -case 0xE370: -case 0xE570: -case 0xE770: -case 0xE970: -case 0xEB70: -case 0xED70: -case 0xEF70: -case 0xE171: -case 0xE371: -case 0xE571: -case 0xE771: -case 0xE971: -case 0xEB71: -case 0xED71: -case 0xEF71: -case 0xE172: -case 0xE372: -case 0xE572: -case 0xE772: -case 0xE972: -case 0xEB72: -case 0xED72: -case 0xEF72: -case 0xE173: -case 0xE373: -case 0xE573: -case 0xE773: -case 0xE973: -case 0xEB73: -case 0xED73: -case 0xEF73: -case 0xE174: -case 0xE374: -case 0xE574: -case 0xE774: -case 0xE974: -case 0xEB74: -case 0xED74: -case 0xEF74: -case 0xE175: -case 0xE375: -case 0xE575: -case 0xE775: -case 0xE975: -case 0xEB75: -case 0xED75: -case 0xEF75: -case 0xE176: -case 0xE376: -case 0xE576: -case 0xE776: -case 0xE976: -case 0xEB76: -case 0xED76: -case 0xEF76: -case 0xE177: -case 0xE377: -case 0xE577: -case 0xE777: -case 0xE977: -case 0xEB77: -case 0xED77: -case 0xEF77: - -// ROXLD -case 0xE170: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft %= 17; - - src |= (CPU->flag_X & C68K_SR_X) << 8; - res = (src << sft) | (src >> (17 - sft)); - CPU->flag_X = CPU->flag_C = res >> 8; - CPU->flag_V = 0; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = CPU->flag_X; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; -} -RET(6) -case 0xE3B0: -case 0xE5B0: -case 0xE7B0: -case 0xE9B0: -case 0xEBB0: -case 0xEDB0: -case 0xEFB0: -case 0xE1B1: -case 0xE3B1: -case 0xE5B1: -case 0xE7B1: -case 0xE9B1: -case 0xEBB1: -case 0xEDB1: -case 0xEFB1: -case 0xE1B2: -case 0xE3B2: -case 0xE5B2: -case 0xE7B2: -case 0xE9B2: -case 0xEBB2: -case 0xEDB2: -case 0xEFB2: -case 0xE1B3: -case 0xE3B3: -case 0xE5B3: -case 0xE7B3: -case 0xE9B3: -case 0xEBB3: -case 0xEDB3: -case 0xEFB3: -case 0xE1B4: -case 0xE3B4: -case 0xE5B4: -case 0xE7B4: -case 0xE9B4: -case 0xEBB4: -case 0xEDB4: -case 0xEFB4: -case 0xE1B5: -case 0xE3B5: -case 0xE5B5: -case 0xE7B5: -case 0xE9B5: -case 0xEBB5: -case 0xEDB5: -case 0xEFB5: -case 0xE1B6: -case 0xE3B6: -case 0xE5B6: -case 0xE7B6: -case 0xE9B6: -case 0xEBB6: -case 0xEDB6: -case 0xEFB6: -case 0xE1B7: -case 0xE3B7: -case 0xE5B7: -case 0xE7B7: -case 0xE9B7: -case 0xEBB7: -case 0xEDB7: -case 0xEFB7: - -// ROXLD -case 0xE1B0: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - sft %= 33; - - if (sft != 0) - { - if (sft == 1) res = (src << 1) | ((CPU->flag_X >> ((C68K_SR_X_SFT + 1) - 1)) & 1); - else res = (src << sft) | (src >> (33 - sft)) | (((CPU->flag_X >> ((C68K_SR_X_SFT + 1) - 1)) & 1) << (sft - 1)); - CPU->flag_X = (src >> (32 - sft)) << C68K_SR_X_SFT; - } - else res = src; - CPU->flag_C = CPU->flag_X; - CPU->flag_V = 0; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = CPU->flag_X; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; -} -RET(8) -case 0xE338: -case 0xE538: -case 0xE738: -case 0xE938: -case 0xEB38: -case 0xED38: -case 0xEF38: -case 0xE139: -case 0xE339: -case 0xE539: -case 0xE739: -case 0xE939: -case 0xEB39: -case 0xED39: -case 0xEF39: -case 0xE13A: -case 0xE33A: -case 0xE53A: -case 0xE73A: -case 0xE93A: -case 0xEB3A: -case 0xED3A: -case 0xEF3A: -case 0xE13B: -case 0xE33B: -case 0xE53B: -case 0xE73B: -case 0xE93B: -case 0xEB3B: -case 0xED3B: -case 0xEF3B: -case 0xE13C: -case 0xE33C: -case 0xE53C: -case 0xE73C: -case 0xE93C: -case 0xEB3C: -case 0xED3C: -case 0xEF3C: -case 0xE13D: -case 0xE33D: -case 0xE53D: -case 0xE73D: -case 0xE93D: -case 0xEB3D: -case 0xED3D: -case 0xEF3D: -case 0xE13E: -case 0xE33E: -case 0xE53E: -case 0xE73E: -case 0xE93E: -case 0xEB3E: -case 0xED3E: -case 0xEF3E: -case 0xE13F: -case 0xE33F: -case 0xE53F: -case 0xE73F: -case 0xE93F: -case 0xEB3F: -case 0xED3F: -case 0xEF3F: - -// ROLD -case 0xE138: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u8)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft &= 0x07) - { - CPU->flag_C = (src << sft) >> 0; - res = ((src << sft) | (src >> (8 - sft))) & 0x000000FF; - CPU->flag_V = 0; - CPU->flag_N = res >> 0; - CPU->flag_notZ = res; - *(BYTE_OFF + (u8*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 0; - CPU->flag_notZ = src; -} -RET(6) -case 0xE378: -case 0xE578: -case 0xE778: -case 0xE978: -case 0xEB78: -case 0xED78: -case 0xEF78: -case 0xE179: -case 0xE379: -case 0xE579: -case 0xE779: -case 0xE979: -case 0xEB79: -case 0xED79: -case 0xEF79: -case 0xE17A: -case 0xE37A: -case 0xE57A: -case 0xE77A: -case 0xE97A: -case 0xEB7A: -case 0xED7A: -case 0xEF7A: -case 0xE17B: -case 0xE37B: -case 0xE57B: -case 0xE77B: -case 0xE97B: -case 0xEB7B: -case 0xED7B: -case 0xEF7B: -case 0xE17C: -case 0xE37C: -case 0xE57C: -case 0xE77C: -case 0xE97C: -case 0xEB7C: -case 0xED7C: -case 0xEF7C: -case 0xE17D: -case 0xE37D: -case 0xE57D: -case 0xE77D: -case 0xE97D: -case 0xEB7D: -case 0xED7D: -case 0xEF7D: -case 0xE17E: -case 0xE37E: -case 0xE57E: -case 0xE77E: -case 0xE97E: -case 0xEB7E: -case 0xED7E: -case 0xEF7E: -case 0xE17F: -case 0xE37F: -case 0xE57F: -case 0xE77F: -case 0xE97F: -case 0xEB7F: -case 0xED7F: -case 0xEF7F: - -// ROLD -case 0xE178: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u16)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft &= 0x0F) - { - CPU->flag_C = (src << sft) >> 8; - res = ((src << sft) | (src >> (16 - sft))) & 0x0000FFFF; - CPU->flag_V = 0; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - *(WORD_OFF + (u16*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; - RET(6) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 8; - CPU->flag_notZ = src; -} -RET(6) -case 0xE3B8: -case 0xE5B8: -case 0xE7B8: -case 0xE9B8: -case 0xEBB8: -case 0xEDB8: -case 0xEFB8: -case 0xE1B9: -case 0xE3B9: -case 0xE5B9: -case 0xE7B9: -case 0xE9B9: -case 0xEBB9: -case 0xEDB9: -case 0xEFB9: -case 0xE1BA: -case 0xE3BA: -case 0xE5BA: -case 0xE7BA: -case 0xE9BA: -case 0xEBBA: -case 0xEDBA: -case 0xEFBA: -case 0xE1BB: -case 0xE3BB: -case 0xE5BB: -case 0xE7BB: -case 0xE9BB: -case 0xEBBB: -case 0xEDBB: -case 0xEFBB: -case 0xE1BC: -case 0xE3BC: -case 0xE5BC: -case 0xE7BC: -case 0xE9BC: -case 0xEBBC: -case 0xEDBC: -case 0xEFBC: -case 0xE1BD: -case 0xE3BD: -case 0xE5BD: -case 0xE7BD: -case 0xE9BD: -case 0xEBBD: -case 0xEDBD: -case 0xEFBD: -case 0xE1BE: -case 0xE3BE: -case 0xE5BE: -case 0xE7BE: -case 0xE9BE: -case 0xEBBE: -case 0xEDBE: -case 0xEFBE: -case 0xE1BF: -case 0xE3BF: -case 0xE5BF: -case 0xE7BF: -case 0xE9BF: -case 0xEBBF: -case 0xEDBF: -case 0xEFBF: - -// ROLD -case 0xE1B8: -{ - u32 res; - pointer src; - u32 sft; - - sft = CPU->D[(Opcode >> 9) & 7] & 0x3F; - src = (u32)CPU->D[(Opcode >> 0) & 7]; - if (sft) - { - CCnt -= sft * 2; - if (sft &= 0x1F) - { - CPU->flag_C = (src >> (32 - sft)) << C68K_SR_C_SFT; - res = (src << sft) | (src >> (32 - sft)); - CPU->flag_V = 0; - CPU->flag_N = res >> 24; - CPU->flag_notZ = res; - *((u32*)(&CPU->D[(Opcode >> 0) & 7])) = res; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; - RET(8) - } - - CPU->flag_V = 0; - CPU->flag_C = 0; - CPU->flag_N = src >> 24; - CPU->flag_notZ = src; -} -RET(8) -case 0xE0D1: -case 0xE0D2: -case 0xE0D3: -case 0xE0D4: -case 0xE0D5: -case 0xE0D6: -case 0xE0D7: - -// ASR -case 0xE0D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE0D9: -case 0xE0DA: -case 0xE0DB: -case 0xE0DC: -case 0xE0DD: -case 0xE0DE: - -// ASR -case 0xE0D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE0E1: -case 0xE0E2: -case 0xE0E3: -case 0xE0E4: -case 0xE0E5: -case 0xE0E6: - -// ASR -case 0xE0E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE0E9: -case 0xE0EA: -case 0xE0EB: -case 0xE0EC: -case 0xE0ED: -case 0xE0EE: -case 0xE0EF: - -// ASR -case 0xE0E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xE0F1: -case 0xE0F2: -case 0xE0F3: -case 0xE0F4: -case 0xE0F5: -case 0xE0F6: -case 0xE0F7: - -// ASR -case 0xE0F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// ASR -case 0xE0F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ASR -case 0xE0F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ASR -case 0xE0DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// ASR -case 0xE0E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src & (1 << 15)); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE2D1: -case 0xE2D2: -case 0xE2D3: -case 0xE2D4: -case 0xE2D5: -case 0xE2D6: -case 0xE2D7: - -// LSR -case 0xE2D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE2D9: -case 0xE2DA: -case 0xE2DB: -case 0xE2DC: -case 0xE2DD: -case 0xE2DE: - -// LSR -case 0xE2D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE2E1: -case 0xE2E2: -case 0xE2E3: -case 0xE2E4: -case 0xE2E5: -case 0xE2E6: - -// LSR -case 0xE2E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE2E9: -case 0xE2EA: -case 0xE2EB: -case 0xE2EC: -case 0xE2ED: -case 0xE2EE: -case 0xE2EF: - -// LSR -case 0xE2E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xE2F1: -case 0xE2F2: -case 0xE2F3: -case 0xE2F4: -case 0xE2F5: -case 0xE2F6: -case 0xE2F7: - -// LSR -case 0xE2F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// LSR -case 0xE2F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// LSR -case 0xE2F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// LSR -case 0xE2DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// LSR -case 0xE2E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_N = CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT; - res = src >> 1; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE4D1: -case 0xE4D2: -case 0xE4D3: -case 0xE4D4: -case 0xE4D5: -case 0xE4D6: -case 0xE4D7: - -// ROXR -case 0xE4D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE4D9: -case 0xE4DA: -case 0xE4DB: -case 0xE4DC: -case 0xE4DD: -case 0xE4DE: - -// ROXR -case 0xE4D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE4E1: -case 0xE4E2: -case 0xE4E3: -case 0xE4E4: -case 0xE4E5: -case 0xE4E6: - -// ROXR -case 0xE4E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE4E9: -case 0xE4EA: -case 0xE4EB: -case 0xE4EC: -case 0xE4ED: -case 0xE4EE: -case 0xE4EF: - -// ROXR -case 0xE4E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xE4F1: -case 0xE4F2: -case 0xE4F3: -case 0xE4F4: -case 0xE4F5: -case 0xE4F6: -case 0xE4F7: - -// ROXR -case 0xE4F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// ROXR -case 0xE4F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ROXR -case 0xE4F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ROXR -case 0xE4DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// ROXR -case 0xE4E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << 7); - CPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE6D1: -case 0xE6D2: -case 0xE6D3: -case 0xE6D4: -case 0xE6D5: -case 0xE6D6: -case 0xE6D7: - -// ROR -case 0xE6D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE6D9: -case 0xE6DA: -case 0xE6DB: -case 0xE6DC: -case 0xE6DD: -case 0xE6DE: - -// ROR -case 0xE6D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE6E1: -case 0xE6E2: -case 0xE6E3: -case 0xE6E4: -case 0xE6E5: -case 0xE6E6: - -// ROR -case 0xE6E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE6E9: -case 0xE6EA: -case 0xE6EB: -case 0xE6EC: -case 0xE6ED: -case 0xE6EE: -case 0xE6EF: - -// ROR -case 0xE6E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xE6F1: -case 0xE6F2: -case 0xE6F3: -case 0xE6F4: -case 0xE6F5: -case 0xE6F6: -case 0xE6F7: - -// ROR -case 0xE6F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// ROR -case 0xE6F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ROR -case 0xE6F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ROR -case 0xE6DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// ROR -case 0xE6E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src << C68K_SR_C_SFT; - res = (src >> 1) | (src << 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE1D1: -case 0xE1D2: -case 0xE1D3: -case 0xE1D4: -case 0xE1D5: -case 0xE1D6: -case 0xE1D7: - -// ASL -case 0xE1D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE1D9: -case 0xE1DA: -case 0xE1DB: -case 0xE1DC: -case 0xE1DD: -case 0xE1DE: - -// ASL -case 0xE1D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE1E1: -case 0xE1E2: -case 0xE1E3: -case 0xE1E4: -case 0xE1E5: -case 0xE1E6: - -// ASL -case 0xE1E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE1E9: -case 0xE1EA: -case 0xE1EB: -case 0xE1EC: -case 0xE1ED: -case 0xE1EE: -case 0xE1EF: - -// ASL -case 0xE1E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xE1F1: -case 0xE1F2: -case 0xE1F3: -case 0xE1F4: -case 0xE1F5: -case 0xE1F6: -case 0xE1F7: - -// ASL -case 0xE1F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// ASL -case 0xE1F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ASL -case 0xE1F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ASL -case 0xE1DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// ASL -case 0xE1E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_V = (src ^ res) >> 8; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE3D1: -case 0xE3D2: -case 0xE3D3: -case 0xE3D4: -case 0xE3D5: -case 0xE3D6: -case 0xE3D7: - -// LSL -case 0xE3D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE3D9: -case 0xE3DA: -case 0xE3DB: -case 0xE3DC: -case 0xE3DD: -case 0xE3DE: - -// LSL -case 0xE3D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE3E1: -case 0xE3E2: -case 0xE3E3: -case 0xE3E4: -case 0xE3E5: -case 0xE3E6: - -// LSL -case 0xE3E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE3E9: -case 0xE3EA: -case 0xE3EB: -case 0xE3EC: -case 0xE3ED: -case 0xE3EE: -case 0xE3EF: - -// LSL -case 0xE3E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xE3F1: -case 0xE3F2: -case 0xE3F3: -case 0xE3F4: -case 0xE3F5: -case 0xE3F6: -case 0xE3F7: - -// LSL -case 0xE3F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// LSL -case 0xE3F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// LSL -case 0xE3F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// LSL -case 0xE3DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// LSL -case 0xE3E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_X = CPU->flag_C = src >> 7; - res = src << 1; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE5D1: -case 0xE5D2: -case 0xE5D3: -case 0xE5D4: -case 0xE5D5: -case 0xE5D6: -case 0xE5D7: - -// ROXL -case 0xE5D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE5D9: -case 0xE5DA: -case 0xE5DB: -case 0xE5DC: -case 0xE5DD: -case 0xE5DE: - -// ROXL -case 0xE5D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE5E1: -case 0xE5E2: -case 0xE5E3: -case 0xE5E4: -case 0xE5E5: -case 0xE5E6: - -// ROXL -case 0xE5E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE5E9: -case 0xE5EA: -case 0xE5EB: -case 0xE5EC: -case 0xE5ED: -case 0xE5EE: -case 0xE5EF: - -// ROXL -case 0xE5E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xE5F1: -case 0xE5F2: -case 0xE5F3: -case 0xE5F4: -case 0xE5F5: -case 0xE5F6: -case 0xE5F7: - -// ROXL -case 0xE5F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// ROXL -case 0xE5F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ROXL -case 0xE5F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ROXL -case 0xE5DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// ROXL -case 0xE5E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> 8); - CPU->flag_X = CPU->flag_C = src >> 7; - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE7D1: -case 0xE7D2: -case 0xE7D3: -case 0xE7D4: -case 0xE7D5: -case 0xE7D6: -case 0xE7D7: - -// ROL -case 0xE7D0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE7D9: -case 0xE7DA: -case 0xE7DB: -case 0xE7DC: -case 0xE7DD: -case 0xE7DE: - -// ROL -case 0xE7D8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - CPU->A[(Opcode >> 0) & 7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) -case 0xE7E1: -case 0xE7E2: -case 0xE7E3: -case 0xE7E4: -case 0xE7E5: -case 0xE7E6: - -// ROL -case 0xE7E0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] - 2; - CPU->A[(Opcode >> 0) & 7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) -case 0xE7E9: -case 0xE7EA: -case 0xE7EB: -case 0xE7EC: -case 0xE7ED: -case 0xE7EE: -case 0xE7EF: - -// ROL -case 0xE7E8: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7] + (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) -case 0xE7F1: -case 0xE7F2: -case 0xE7F3: -case 0xE7F4: -case 0xE7F5: -case 0xE7F6: -case 0xE7F7: - -// ROL -case 0xE7F0: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[(Opcode >> 0) & 7]; - DECODE_EXT_WORD - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(18) - -// ROL -case 0xE7F8: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)(s16)FETCH_WORD; - PC += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(16) - -// ROL -case 0xE7F9: -{ - u32 adr; - u32 res; - pointer src; - adr = (s32)FETCH_LONG; - PC += 4; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(20) - -// ROL -case 0xE7DF: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7]; - CPU->A[7] += 2; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(12) - -// ROL -case 0xE7E7: -{ - u32 adr; - u32 res; - pointer src; - adr = CPU->A[7] - 2; - CPU->A[7] = adr; - PRE_IO - READ_WORD_F(adr, src) - CPU->flag_V = 0; - CPU->flag_C = src >> 7; - res = (src << 1) | (src >> 15); - CPU->flag_N = res >> 8; - CPU->flag_notZ = res & 0x0000FFFF; - WRITE_WORD_F(adr, res) - POST_IO -} -RET(14) diff --git a/yabause/src/c68k/c68k_opF.inc b/yabause/src/c68k/c68k_opF.inc deleted file mode 100644 index 802c9b31b8..0000000000 --- a/yabause/src/c68k/c68k_opF.inc +++ /dev/null @@ -1,4118 +0,0 @@ -case 0xF001: -case 0xF002: -case 0xF003: -case 0xF004: -case 0xF005: -case 0xF006: -case 0xF007: -case 0xF008: -case 0xF009: -case 0xF00A: -case 0xF00B: -case 0xF00C: -case 0xF00D: -case 0xF00E: -case 0xF00F: -case 0xF010: -case 0xF011: -case 0xF012: -case 0xF013: -case 0xF014: -case 0xF015: -case 0xF016: -case 0xF017: -case 0xF018: -case 0xF019: -case 0xF01A: -case 0xF01B: -case 0xF01C: -case 0xF01D: -case 0xF01E: -case 0xF01F: -case 0xF020: -case 0xF021: -case 0xF022: -case 0xF023: -case 0xF024: -case 0xF025: -case 0xF026: -case 0xF027: -case 0xF028: -case 0xF029: -case 0xF02A: -case 0xF02B: -case 0xF02C: -case 0xF02D: -case 0xF02E: -case 0xF02F: -case 0xF030: -case 0xF031: -case 0xF032: -case 0xF033: -case 0xF034: -case 0xF035: -case 0xF036: -case 0xF037: -case 0xF038: -case 0xF039: -case 0xF03A: -case 0xF03B: -case 0xF03C: -case 0xF03D: -case 0xF03E: -case 0xF03F: -case 0xF040: -case 0xF041: -case 0xF042: -case 0xF043: -case 0xF044: -case 0xF045: -case 0xF046: -case 0xF047: -case 0xF048: -case 0xF049: -case 0xF04A: -case 0xF04B: -case 0xF04C: -case 0xF04D: -case 0xF04E: -case 0xF04F: -case 0xF050: -case 0xF051: -case 0xF052: -case 0xF053: -case 0xF054: -case 0xF055: -case 0xF056: -case 0xF057: -case 0xF058: -case 0xF059: -case 0xF05A: -case 0xF05B: -case 0xF05C: -case 0xF05D: -case 0xF05E: -case 0xF05F: -case 0xF060: -case 0xF061: -case 0xF062: -case 0xF063: -case 0xF064: -case 0xF065: -case 0xF066: -case 0xF067: -case 0xF068: -case 0xF069: -case 0xF06A: -case 0xF06B: -case 0xF06C: -case 0xF06D: -case 0xF06E: -case 0xF06F: -case 0xF070: -case 0xF071: -case 0xF072: -case 0xF073: -case 0xF074: -case 0xF075: -case 0xF076: -case 0xF077: -case 0xF078: -case 0xF079: -case 0xF07A: -case 0xF07B: -case 0xF07C: -case 0xF07D: -case 0xF07E: -case 0xF07F: -case 0xF080: -case 0xF081: -case 0xF082: -case 0xF083: -case 0xF084: -case 0xF085: -case 0xF086: -case 0xF087: -case 0xF088: -case 0xF089: -case 0xF08A: -case 0xF08B: -case 0xF08C: -case 0xF08D: -case 0xF08E: -case 0xF08F: -case 0xF090: -case 0xF091: -case 0xF092: -case 0xF093: -case 0xF094: -case 0xF095: -case 0xF096: -case 0xF097: -case 0xF098: -case 0xF099: -case 0xF09A: -case 0xF09B: -case 0xF09C: -case 0xF09D: -case 0xF09E: -case 0xF09F: -case 0xF0A0: -case 0xF0A1: -case 0xF0A2: -case 0xF0A3: -case 0xF0A4: -case 0xF0A5: -case 0xF0A6: -case 0xF0A7: -case 0xF0A8: -case 0xF0A9: -case 0xF0AA: -case 0xF0AB: -case 0xF0AC: -case 0xF0AD: -case 0xF0AE: -case 0xF0AF: -case 0xF0B0: -case 0xF0B1: -case 0xF0B2: -case 0xF0B3: -case 0xF0B4: -case 0xF0B5: -case 0xF0B6: -case 0xF0B7: -case 0xF0B8: -case 0xF0B9: -case 0xF0BA: -case 0xF0BB: -case 0xF0BC: -case 0xF0BD: -case 0xF0BE: -case 0xF0BF: -case 0xF0C0: -case 0xF0C1: -case 0xF0C2: -case 0xF0C3: -case 0xF0C4: -case 0xF0C5: -case 0xF0C6: -case 0xF0C7: -case 0xF0C8: -case 0xF0C9: -case 0xF0CA: -case 0xF0CB: -case 0xF0CC: -case 0xF0CD: -case 0xF0CE: -case 0xF0CF: -case 0xF0D0: -case 0xF0D1: -case 0xF0D2: -case 0xF0D3: -case 0xF0D4: -case 0xF0D5: -case 0xF0D6: -case 0xF0D7: -case 0xF0D8: -case 0xF0D9: -case 0xF0DA: -case 0xF0DB: -case 0xF0DC: -case 0xF0DD: -case 0xF0DE: -case 0xF0DF: -case 0xF0E0: -case 0xF0E1: -case 0xF0E2: -case 0xF0E3: -case 0xF0E4: -case 0xF0E5: -case 0xF0E6: -case 0xF0E7: -case 0xF0E8: -case 0xF0E9: -case 0xF0EA: -case 0xF0EB: -case 0xF0EC: -case 0xF0ED: -case 0xF0EE: -case 0xF0EF: -case 0xF0F0: -case 0xF0F1: -case 0xF0F2: -case 0xF0F3: -case 0xF0F4: -case 0xF0F5: -case 0xF0F6: -case 0xF0F7: -case 0xF0F8: -case 0xF0F9: -case 0xF0FA: -case 0xF0FB: -case 0xF0FC: -case 0xF0FD: -case 0xF0FE: -case 0xF0FF: -case 0xF100: -case 0xF101: -case 0xF102: -case 0xF103: -case 0xF104: -case 0xF105: -case 0xF106: -case 0xF107: -case 0xF108: -case 0xF109: -case 0xF10A: -case 0xF10B: -case 0xF10C: -case 0xF10D: -case 0xF10E: -case 0xF10F: -case 0xF110: -case 0xF111: -case 0xF112: -case 0xF113: -case 0xF114: -case 0xF115: -case 0xF116: -case 0xF117: -case 0xF118: -case 0xF119: -case 0xF11A: -case 0xF11B: -case 0xF11C: -case 0xF11D: -case 0xF11E: -case 0xF11F: -case 0xF120: -case 0xF121: -case 0xF122: -case 0xF123: -case 0xF124: -case 0xF125: -case 0xF126: -case 0xF127: -case 0xF128: -case 0xF129: -case 0xF12A: -case 0xF12B: -case 0xF12C: -case 0xF12D: -case 0xF12E: -case 0xF12F: -case 0xF130: -case 0xF131: -case 0xF132: -case 0xF133: -case 0xF134: -case 0xF135: -case 0xF136: -case 0xF137: -case 0xF138: -case 0xF139: -case 0xF13A: -case 0xF13B: -case 0xF13C: -case 0xF13D: -case 0xF13E: -case 0xF13F: -case 0xF140: -case 0xF141: -case 0xF142: -case 0xF143: -case 0xF144: -case 0xF145: -case 0xF146: -case 0xF147: -case 0xF148: -case 0xF149: -case 0xF14A: -case 0xF14B: -case 0xF14C: -case 0xF14D: -case 0xF14E: -case 0xF14F: -case 0xF150: -case 0xF151: -case 0xF152: -case 0xF153: -case 0xF154: -case 0xF155: -case 0xF156: -case 0xF157: -case 0xF158: -case 0xF159: -case 0xF15A: -case 0xF15B: -case 0xF15C: -case 0xF15D: -case 0xF15E: -case 0xF15F: -case 0xF160: -case 0xF161: -case 0xF162: -case 0xF163: -case 0xF164: -case 0xF165: -case 0xF166: -case 0xF167: -case 0xF168: -case 0xF169: -case 0xF16A: -case 0xF16B: -case 0xF16C: -case 0xF16D: -case 0xF16E: -case 0xF16F: -case 0xF170: -case 0xF171: -case 0xF172: -case 0xF173: -case 0xF174: -case 0xF175: -case 0xF176: -case 0xF177: -case 0xF178: -case 0xF179: -case 0xF17A: -case 0xF17B: -case 0xF17C: -case 0xF17D: -case 0xF17E: -case 0xF17F: -case 0xF180: -case 0xF181: -case 0xF182: -case 0xF183: -case 0xF184: -case 0xF185: -case 0xF186: -case 0xF187: -case 0xF188: -case 0xF189: -case 0xF18A: -case 0xF18B: -case 0xF18C: -case 0xF18D: -case 0xF18E: -case 0xF18F: -case 0xF190: -case 0xF191: -case 0xF192: -case 0xF193: -case 0xF194: -case 0xF195: -case 0xF196: -case 0xF197: -case 0xF198: -case 0xF199: -case 0xF19A: -case 0xF19B: -case 0xF19C: -case 0xF19D: -case 0xF19E: -case 0xF19F: -case 0xF1A0: -case 0xF1A1: -case 0xF1A2: -case 0xF1A3: -case 0xF1A4: -case 0xF1A5: -case 0xF1A6: -case 0xF1A7: -case 0xF1A8: -case 0xF1A9: -case 0xF1AA: -case 0xF1AB: -case 0xF1AC: -case 0xF1AD: -case 0xF1AE: -case 0xF1AF: -case 0xF1B0: -case 0xF1B1: -case 0xF1B2: -case 0xF1B3: -case 0xF1B4: -case 0xF1B5: -case 0xF1B6: -case 0xF1B7: -case 0xF1B8: -case 0xF1B9: -case 0xF1BA: -case 0xF1BB: -case 0xF1BC: -case 0xF1BD: -case 0xF1BE: -case 0xF1BF: -case 0xF1C0: -case 0xF1C1: -case 0xF1C2: -case 0xF1C3: -case 0xF1C4: -case 0xF1C5: -case 0xF1C6: -case 0xF1C7: -case 0xF1C8: -case 0xF1C9: -case 0xF1CA: -case 0xF1CB: -case 0xF1CC: -case 0xF1CD: -case 0xF1CE: -case 0xF1CF: -case 0xF1D0: -case 0xF1D1: -case 0xF1D2: -case 0xF1D3: -case 0xF1D4: -case 0xF1D5: -case 0xF1D6: -case 0xF1D7: -case 0xF1D8: -case 0xF1D9: -case 0xF1DA: -case 0xF1DB: -case 0xF1DC: -case 0xF1DD: -case 0xF1DE: -case 0xF1DF: -case 0xF1E0: -case 0xF1E1: -case 0xF1E2: -case 0xF1E3: -case 0xF1E4: -case 0xF1E5: -case 0xF1E6: -case 0xF1E7: -case 0xF1E8: -case 0xF1E9: -case 0xF1EA: -case 0xF1EB: -case 0xF1EC: -case 0xF1ED: -case 0xF1EE: -case 0xF1EF: -case 0xF1F0: -case 0xF1F1: -case 0xF1F2: -case 0xF1F3: -case 0xF1F4: -case 0xF1F5: -case 0xF1F6: -case 0xF1F7: -case 0xF1F8: -case 0xF1F9: -case 0xF1FA: -case 0xF1FB: -case 0xF1FC: -case 0xF1FD: -case 0xF1FE: -case 0xF1FF: -case 0xF200: -case 0xF201: -case 0xF202: -case 0xF203: -case 0xF204: -case 0xF205: -case 0xF206: -case 0xF207: -case 0xF208: -case 0xF209: -case 0xF20A: -case 0xF20B: -case 0xF20C: -case 0xF20D: -case 0xF20E: -case 0xF20F: -case 0xF210: -case 0xF211: -case 0xF212: -case 0xF213: -case 0xF214: -case 0xF215: -case 0xF216: -case 0xF217: -case 0xF218: -case 0xF219: -case 0xF21A: -case 0xF21B: -case 0xF21C: -case 0xF21D: -case 0xF21E: -case 0xF21F: -case 0xF220: -case 0xF221: -case 0xF222: -case 0xF223: -case 0xF224: -case 0xF225: -case 0xF226: -case 0xF227: -case 0xF228: -case 0xF229: -case 0xF22A: -case 0xF22B: -case 0xF22C: -case 0xF22D: -case 0xF22E: -case 0xF22F: -case 0xF230: -case 0xF231: -case 0xF232: -case 0xF233: -case 0xF234: -case 0xF235: -case 0xF236: -case 0xF237: -case 0xF238: -case 0xF239: -case 0xF23A: -case 0xF23B: -case 0xF23C: -case 0xF23D: -case 0xF23E: -case 0xF23F: -case 0xF240: -case 0xF241: -case 0xF242: -case 0xF243: -case 0xF244: -case 0xF245: -case 0xF246: -case 0xF247: -case 0xF248: -case 0xF249: -case 0xF24A: -case 0xF24B: -case 0xF24C: -case 0xF24D: -case 0xF24E: -case 0xF24F: -case 0xF250: -case 0xF251: -case 0xF252: -case 0xF253: -case 0xF254: -case 0xF255: -case 0xF256: -case 0xF257: -case 0xF258: -case 0xF259: -case 0xF25A: -case 0xF25B: -case 0xF25C: -case 0xF25D: -case 0xF25E: -case 0xF25F: -case 0xF260: -case 0xF261: -case 0xF262: -case 0xF263: -case 0xF264: -case 0xF265: -case 0xF266: -case 0xF267: -case 0xF268: -case 0xF269: -case 0xF26A: -case 0xF26B: -case 0xF26C: -case 0xF26D: -case 0xF26E: -case 0xF26F: -case 0xF270: -case 0xF271: -case 0xF272: -case 0xF273: -case 0xF274: -case 0xF275: -case 0xF276: -case 0xF277: -case 0xF278: -case 0xF279: -case 0xF27A: -case 0xF27B: -case 0xF27C: -case 0xF27D: -case 0xF27E: -case 0xF27F: -case 0xF280: -case 0xF281: -case 0xF282: -case 0xF283: -case 0xF284: -case 0xF285: -case 0xF286: -case 0xF287: -case 0xF288: -case 0xF289: -case 0xF28A: -case 0xF28B: -case 0xF28C: -case 0xF28D: -case 0xF28E: -case 0xF28F: -case 0xF290: -case 0xF291: -case 0xF292: -case 0xF293: -case 0xF294: -case 0xF295: -case 0xF296: -case 0xF297: -case 0xF298: -case 0xF299: -case 0xF29A: -case 0xF29B: -case 0xF29C: -case 0xF29D: -case 0xF29E: -case 0xF29F: -case 0xF2A0: -case 0xF2A1: -case 0xF2A2: -case 0xF2A3: -case 0xF2A4: -case 0xF2A5: -case 0xF2A6: -case 0xF2A7: -case 0xF2A8: -case 0xF2A9: -case 0xF2AA: -case 0xF2AB: -case 0xF2AC: -case 0xF2AD: -case 0xF2AE: -case 0xF2AF: -case 0xF2B0: -case 0xF2B1: -case 0xF2B2: -case 0xF2B3: -case 0xF2B4: -case 0xF2B5: -case 0xF2B6: -case 0xF2B7: -case 0xF2B8: -case 0xF2B9: -case 0xF2BA: -case 0xF2BB: -case 0xF2BC: -case 0xF2BD: -case 0xF2BE: -case 0xF2BF: -case 0xF2C0: -case 0xF2C1: -case 0xF2C2: -case 0xF2C3: -case 0xF2C4: -case 0xF2C5: -case 0xF2C6: -case 0xF2C7: -case 0xF2C8: -case 0xF2C9: -case 0xF2CA: -case 0xF2CB: -case 0xF2CC: -case 0xF2CD: -case 0xF2CE: -case 0xF2CF: -case 0xF2D0: -case 0xF2D1: -case 0xF2D2: -case 0xF2D3: -case 0xF2D4: -case 0xF2D5: -case 0xF2D6: -case 0xF2D7: -case 0xF2D8: -case 0xF2D9: -case 0xF2DA: -case 0xF2DB: -case 0xF2DC: -case 0xF2DD: -case 0xF2DE: -case 0xF2DF: -case 0xF2E0: -case 0xF2E1: -case 0xF2E2: -case 0xF2E3: -case 0xF2E4: -case 0xF2E5: -case 0xF2E6: -case 0xF2E7: -case 0xF2E8: -case 0xF2E9: -case 0xF2EA: -case 0xF2EB: -case 0xF2EC: -case 0xF2ED: -case 0xF2EE: -case 0xF2EF: -case 0xF2F0: -case 0xF2F1: -case 0xF2F2: -case 0xF2F3: -case 0xF2F4: -case 0xF2F5: -case 0xF2F6: -case 0xF2F7: -case 0xF2F8: -case 0xF2F9: -case 0xF2FA: -case 0xF2FB: -case 0xF2FC: -case 0xF2FD: -case 0xF2FE: -case 0xF2FF: -case 0xF300: -case 0xF301: -case 0xF302: -case 0xF303: -case 0xF304: -case 0xF305: -case 0xF306: -case 0xF307: -case 0xF308: -case 0xF309: -case 0xF30A: -case 0xF30B: -case 0xF30C: -case 0xF30D: -case 0xF30E: -case 0xF30F: -case 0xF310: -case 0xF311: -case 0xF312: -case 0xF313: -case 0xF314: -case 0xF315: -case 0xF316: -case 0xF317: -case 0xF318: -case 0xF319: -case 0xF31A: -case 0xF31B: -case 0xF31C: -case 0xF31D: -case 0xF31E: -case 0xF31F: -case 0xF320: -case 0xF321: -case 0xF322: -case 0xF323: -case 0xF324: -case 0xF325: -case 0xF326: -case 0xF327: -case 0xF328: -case 0xF329: -case 0xF32A: -case 0xF32B: -case 0xF32C: -case 0xF32D: -case 0xF32E: -case 0xF32F: -case 0xF330: -case 0xF331: -case 0xF332: -case 0xF333: -case 0xF334: -case 0xF335: -case 0xF336: -case 0xF337: -case 0xF338: -case 0xF339: -case 0xF33A: -case 0xF33B: -case 0xF33C: -case 0xF33D: -case 0xF33E: -case 0xF33F: -case 0xF340: -case 0xF341: -case 0xF342: -case 0xF343: -case 0xF344: -case 0xF345: -case 0xF346: -case 0xF347: -case 0xF348: -case 0xF349: -case 0xF34A: -case 0xF34B: -case 0xF34C: -case 0xF34D: -case 0xF34E: -case 0xF34F: -case 0xF350: -case 0xF351: -case 0xF352: -case 0xF353: -case 0xF354: -case 0xF355: -case 0xF356: -case 0xF357: -case 0xF358: -case 0xF359: -case 0xF35A: -case 0xF35B: -case 0xF35C: -case 0xF35D: -case 0xF35E: -case 0xF35F: -case 0xF360: -case 0xF361: -case 0xF362: -case 0xF363: -case 0xF364: -case 0xF365: -case 0xF366: -case 0xF367: -case 0xF368: -case 0xF369: -case 0xF36A: -case 0xF36B: -case 0xF36C: -case 0xF36D: -case 0xF36E: -case 0xF36F: -case 0xF370: -case 0xF371: -case 0xF372: -case 0xF373: -case 0xF374: -case 0xF375: -case 0xF376: -case 0xF377: -case 0xF378: -case 0xF379: -case 0xF37A: -case 0xF37B: -case 0xF37C: -case 0xF37D: -case 0xF37E: -case 0xF37F: -case 0xF380: -case 0xF381: -case 0xF382: -case 0xF383: -case 0xF384: -case 0xF385: -case 0xF386: -case 0xF387: -case 0xF388: -case 0xF389: -case 0xF38A: -case 0xF38B: -case 0xF38C: -case 0xF38D: -case 0xF38E: -case 0xF38F: -case 0xF390: -case 0xF391: -case 0xF392: -case 0xF393: -case 0xF394: -case 0xF395: -case 0xF396: -case 0xF397: -case 0xF398: -case 0xF399: -case 0xF39A: -case 0xF39B: -case 0xF39C: -case 0xF39D: -case 0xF39E: -case 0xF39F: -case 0xF3A0: -case 0xF3A1: -case 0xF3A2: -case 0xF3A3: -case 0xF3A4: -case 0xF3A5: -case 0xF3A6: -case 0xF3A7: -case 0xF3A8: -case 0xF3A9: -case 0xF3AA: -case 0xF3AB: -case 0xF3AC: -case 0xF3AD: -case 0xF3AE: -case 0xF3AF: -case 0xF3B0: -case 0xF3B1: -case 0xF3B2: -case 0xF3B3: -case 0xF3B4: -case 0xF3B5: -case 0xF3B6: -case 0xF3B7: -case 0xF3B8: -case 0xF3B9: -case 0xF3BA: -case 0xF3BB: -case 0xF3BC: -case 0xF3BD: -case 0xF3BE: -case 0xF3BF: -case 0xF3C0: -case 0xF3C1: -case 0xF3C2: -case 0xF3C3: -case 0xF3C4: -case 0xF3C5: -case 0xF3C6: -case 0xF3C7: -case 0xF3C8: -case 0xF3C9: -case 0xF3CA: -case 0xF3CB: -case 0xF3CC: -case 0xF3CD: -case 0xF3CE: -case 0xF3CF: -case 0xF3D0: -case 0xF3D1: -case 0xF3D2: -case 0xF3D3: -case 0xF3D4: -case 0xF3D5: -case 0xF3D6: -case 0xF3D7: -case 0xF3D8: -case 0xF3D9: -case 0xF3DA: -case 0xF3DB: -case 0xF3DC: -case 0xF3DD: -case 0xF3DE: -case 0xF3DF: -case 0xF3E0: -case 0xF3E1: -case 0xF3E2: -case 0xF3E3: -case 0xF3E4: -case 0xF3E5: -case 0xF3E6: -case 0xF3E7: -case 0xF3E8: -case 0xF3E9: -case 0xF3EA: -case 0xF3EB: -case 0xF3EC: -case 0xF3ED: -case 0xF3EE: -case 0xF3EF: -case 0xF3F0: -case 0xF3F1: -case 0xF3F2: -case 0xF3F3: -case 0xF3F4: -case 0xF3F5: -case 0xF3F6: -case 0xF3F7: -case 0xF3F8: -case 0xF3F9: -case 0xF3FA: -case 0xF3FB: -case 0xF3FC: -case 0xF3FD: -case 0xF3FE: -case 0xF3FF: -case 0xF400: -case 0xF401: -case 0xF402: -case 0xF403: -case 0xF404: -case 0xF405: -case 0xF406: -case 0xF407: -case 0xF408: -case 0xF409: -case 0xF40A: -case 0xF40B: -case 0xF40C: -case 0xF40D: -case 0xF40E: -case 0xF40F: -case 0xF410: -case 0xF411: -case 0xF412: -case 0xF413: -case 0xF414: -case 0xF415: -case 0xF416: -case 0xF417: -case 0xF418: -case 0xF419: -case 0xF41A: -case 0xF41B: -case 0xF41C: -case 0xF41D: -case 0xF41E: -case 0xF41F: -case 0xF420: -case 0xF421: -case 0xF422: -case 0xF423: -case 0xF424: -case 0xF425: -case 0xF426: -case 0xF427: -case 0xF428: -case 0xF429: -case 0xF42A: -case 0xF42B: -case 0xF42C: -case 0xF42D: -case 0xF42E: -case 0xF42F: -case 0xF430: -case 0xF431: -case 0xF432: -case 0xF433: -case 0xF434: -case 0xF435: -case 0xF436: -case 0xF437: -case 0xF438: -case 0xF439: -case 0xF43A: -case 0xF43B: -case 0xF43C: -case 0xF43D: -case 0xF43E: -case 0xF43F: -case 0xF440: -case 0xF441: -case 0xF442: -case 0xF443: -case 0xF444: -case 0xF445: -case 0xF446: -case 0xF447: -case 0xF448: -case 0xF449: -case 0xF44A: -case 0xF44B: -case 0xF44C: -case 0xF44D: -case 0xF44E: -case 0xF44F: -case 0xF450: -case 0xF451: -case 0xF452: -case 0xF453: -case 0xF454: -case 0xF455: -case 0xF456: -case 0xF457: -case 0xF458: -case 0xF459: -case 0xF45A: -case 0xF45B: -case 0xF45C: -case 0xF45D: -case 0xF45E: -case 0xF45F: -case 0xF460: -case 0xF461: -case 0xF462: -case 0xF463: -case 0xF464: -case 0xF465: -case 0xF466: -case 0xF467: -case 0xF468: -case 0xF469: -case 0xF46A: -case 0xF46B: -case 0xF46C: -case 0xF46D: -case 0xF46E: -case 0xF46F: -case 0xF470: -case 0xF471: -case 0xF472: -case 0xF473: -case 0xF474: -case 0xF475: -case 0xF476: -case 0xF477: -case 0xF478: -case 0xF479: -case 0xF47A: -case 0xF47B: -case 0xF47C: -case 0xF47D: -case 0xF47E: -case 0xF47F: -case 0xF480: -case 0xF481: -case 0xF482: -case 0xF483: -case 0xF484: -case 0xF485: -case 0xF486: -case 0xF487: -case 0xF488: -case 0xF489: -case 0xF48A: -case 0xF48B: -case 0xF48C: -case 0xF48D: -case 0xF48E: -case 0xF48F: -case 0xF490: -case 0xF491: -case 0xF492: -case 0xF493: -case 0xF494: -case 0xF495: -case 0xF496: -case 0xF497: -case 0xF498: -case 0xF499: -case 0xF49A: -case 0xF49B: -case 0xF49C: -case 0xF49D: -case 0xF49E: -case 0xF49F: -case 0xF4A0: -case 0xF4A1: -case 0xF4A2: -case 0xF4A3: -case 0xF4A4: -case 0xF4A5: -case 0xF4A6: -case 0xF4A7: -case 0xF4A8: -case 0xF4A9: -case 0xF4AA: -case 0xF4AB: -case 0xF4AC: -case 0xF4AD: -case 0xF4AE: -case 0xF4AF: -case 0xF4B0: -case 0xF4B1: -case 0xF4B2: -case 0xF4B3: -case 0xF4B4: -case 0xF4B5: -case 0xF4B6: -case 0xF4B7: -case 0xF4B8: -case 0xF4B9: -case 0xF4BA: -case 0xF4BB: -case 0xF4BC: -case 0xF4BD: -case 0xF4BE: -case 0xF4BF: -case 0xF4C0: -case 0xF4C1: -case 0xF4C2: -case 0xF4C3: -case 0xF4C4: -case 0xF4C5: -case 0xF4C6: -case 0xF4C7: -case 0xF4C8: -case 0xF4C9: -case 0xF4CA: -case 0xF4CB: -case 0xF4CC: -case 0xF4CD: -case 0xF4CE: -case 0xF4CF: -case 0xF4D0: -case 0xF4D1: -case 0xF4D2: -case 0xF4D3: -case 0xF4D4: -case 0xF4D5: -case 0xF4D6: -case 0xF4D7: -case 0xF4D8: -case 0xF4D9: -case 0xF4DA: -case 0xF4DB: -case 0xF4DC: -case 0xF4DD: -case 0xF4DE: -case 0xF4DF: -case 0xF4E0: -case 0xF4E1: -case 0xF4E2: -case 0xF4E3: -case 0xF4E4: -case 0xF4E5: -case 0xF4E6: -case 0xF4E7: -case 0xF4E8: -case 0xF4E9: -case 0xF4EA: -case 0xF4EB: -case 0xF4EC: -case 0xF4ED: -case 0xF4EE: -case 0xF4EF: -case 0xF4F0: -case 0xF4F1: -case 0xF4F2: -case 0xF4F3: -case 0xF4F4: -case 0xF4F5: -case 0xF4F6: -case 0xF4F7: -case 0xF4F8: -case 0xF4F9: -case 0xF4FA: -case 0xF4FB: -case 0xF4FC: -case 0xF4FD: -case 0xF4FE: -case 0xF4FF: -case 0xF500: -case 0xF501: -case 0xF502: -case 0xF503: -case 0xF504: -case 0xF505: -case 0xF506: -case 0xF507: -case 0xF508: -case 0xF509: -case 0xF50A: -case 0xF50B: -case 0xF50C: -case 0xF50D: -case 0xF50E: -case 0xF50F: -case 0xF510: -case 0xF511: -case 0xF512: -case 0xF513: -case 0xF514: -case 0xF515: -case 0xF516: -case 0xF517: -case 0xF518: -case 0xF519: -case 0xF51A: -case 0xF51B: -case 0xF51C: -case 0xF51D: -case 0xF51E: -case 0xF51F: -case 0xF520: -case 0xF521: -case 0xF522: -case 0xF523: -case 0xF524: -case 0xF525: -case 0xF526: -case 0xF527: -case 0xF528: -case 0xF529: -case 0xF52A: -case 0xF52B: -case 0xF52C: -case 0xF52D: -case 0xF52E: -case 0xF52F: -case 0xF530: -case 0xF531: -case 0xF532: -case 0xF533: -case 0xF534: -case 0xF535: -case 0xF536: -case 0xF537: -case 0xF538: -case 0xF539: -case 0xF53A: -case 0xF53B: -case 0xF53C: -case 0xF53D: -case 0xF53E: -case 0xF53F: -case 0xF540: -case 0xF541: -case 0xF542: -case 0xF543: -case 0xF544: -case 0xF545: -case 0xF546: -case 0xF547: -case 0xF548: -case 0xF549: -case 0xF54A: -case 0xF54B: -case 0xF54C: -case 0xF54D: -case 0xF54E: -case 0xF54F: -case 0xF550: -case 0xF551: -case 0xF552: -case 0xF553: -case 0xF554: -case 0xF555: -case 0xF556: -case 0xF557: -case 0xF558: -case 0xF559: -case 0xF55A: -case 0xF55B: -case 0xF55C: -case 0xF55D: -case 0xF55E: -case 0xF55F: -case 0xF560: -case 0xF561: -case 0xF562: -case 0xF563: -case 0xF564: -case 0xF565: -case 0xF566: -case 0xF567: -case 0xF568: -case 0xF569: -case 0xF56A: -case 0xF56B: -case 0xF56C: -case 0xF56D: -case 0xF56E: -case 0xF56F: -case 0xF570: -case 0xF571: -case 0xF572: -case 0xF573: -case 0xF574: -case 0xF575: -case 0xF576: -case 0xF577: -case 0xF578: -case 0xF579: -case 0xF57A: -case 0xF57B: -case 0xF57C: -case 0xF57D: -case 0xF57E: -case 0xF57F: -case 0xF580: -case 0xF581: -case 0xF582: -case 0xF583: -case 0xF584: -case 0xF585: -case 0xF586: -case 0xF587: -case 0xF588: -case 0xF589: -case 0xF58A: -case 0xF58B: -case 0xF58C: -case 0xF58D: -case 0xF58E: -case 0xF58F: -case 0xF590: -case 0xF591: -case 0xF592: -case 0xF593: -case 0xF594: -case 0xF595: -case 0xF596: -case 0xF597: -case 0xF598: -case 0xF599: -case 0xF59A: -case 0xF59B: -case 0xF59C: -case 0xF59D: -case 0xF59E: -case 0xF59F: -case 0xF5A0: -case 0xF5A1: -case 0xF5A2: -case 0xF5A3: -case 0xF5A4: -case 0xF5A5: -case 0xF5A6: -case 0xF5A7: -case 0xF5A8: -case 0xF5A9: -case 0xF5AA: -case 0xF5AB: -case 0xF5AC: -case 0xF5AD: -case 0xF5AE: -case 0xF5AF: -case 0xF5B0: -case 0xF5B1: -case 0xF5B2: -case 0xF5B3: -case 0xF5B4: -case 0xF5B5: -case 0xF5B6: -case 0xF5B7: -case 0xF5B8: -case 0xF5B9: -case 0xF5BA: -case 0xF5BB: -case 0xF5BC: -case 0xF5BD: -case 0xF5BE: -case 0xF5BF: -case 0xF5C0: -case 0xF5C1: -case 0xF5C2: -case 0xF5C3: -case 0xF5C4: -case 0xF5C5: -case 0xF5C6: -case 0xF5C7: -case 0xF5C8: -case 0xF5C9: -case 0xF5CA: -case 0xF5CB: -case 0xF5CC: -case 0xF5CD: -case 0xF5CE: -case 0xF5CF: -case 0xF5D0: -case 0xF5D1: -case 0xF5D2: -case 0xF5D3: -case 0xF5D4: -case 0xF5D5: -case 0xF5D6: -case 0xF5D7: -case 0xF5D8: -case 0xF5D9: -case 0xF5DA: -case 0xF5DB: -case 0xF5DC: -case 0xF5DD: -case 0xF5DE: -case 0xF5DF: -case 0xF5E0: -case 0xF5E1: -case 0xF5E2: -case 0xF5E3: -case 0xF5E4: -case 0xF5E5: -case 0xF5E6: -case 0xF5E7: -case 0xF5E8: -case 0xF5E9: -case 0xF5EA: -case 0xF5EB: -case 0xF5EC: -case 0xF5ED: -case 0xF5EE: -case 0xF5EF: -case 0xF5F0: -case 0xF5F1: -case 0xF5F2: -case 0xF5F3: -case 0xF5F4: -case 0xF5F5: -case 0xF5F6: -case 0xF5F7: -case 0xF5F8: -case 0xF5F9: -case 0xF5FA: -case 0xF5FB: -case 0xF5FC: -case 0xF5FD: -case 0xF5FE: -case 0xF5FF: -case 0xF600: -case 0xF601: -case 0xF602: -case 0xF603: -case 0xF604: -case 0xF605: -case 0xF606: -case 0xF607: -case 0xF608: -case 0xF609: -case 0xF60A: -case 0xF60B: -case 0xF60C: -case 0xF60D: -case 0xF60E: -case 0xF60F: -case 0xF610: -case 0xF611: -case 0xF612: -case 0xF613: -case 0xF614: -case 0xF615: -case 0xF616: -case 0xF617: -case 0xF618: -case 0xF619: -case 0xF61A: -case 0xF61B: -case 0xF61C: -case 0xF61D: -case 0xF61E: -case 0xF61F: -case 0xF620: -case 0xF621: -case 0xF622: -case 0xF623: -case 0xF624: -case 0xF625: -case 0xF626: -case 0xF627: -case 0xF628: -case 0xF629: -case 0xF62A: -case 0xF62B: -case 0xF62C: -case 0xF62D: -case 0xF62E: -case 0xF62F: -case 0xF630: -case 0xF631: -case 0xF632: -case 0xF633: -case 0xF634: -case 0xF635: -case 0xF636: -case 0xF637: -case 0xF638: -case 0xF639: -case 0xF63A: -case 0xF63B: -case 0xF63C: -case 0xF63D: -case 0xF63E: -case 0xF63F: -case 0xF640: -case 0xF641: -case 0xF642: -case 0xF643: -case 0xF644: -case 0xF645: -case 0xF646: -case 0xF647: -case 0xF648: -case 0xF649: -case 0xF64A: -case 0xF64B: -case 0xF64C: -case 0xF64D: -case 0xF64E: -case 0xF64F: -case 0xF650: -case 0xF651: -case 0xF652: -case 0xF653: -case 0xF654: -case 0xF655: -case 0xF656: -case 0xF657: -case 0xF658: -case 0xF659: -case 0xF65A: -case 0xF65B: -case 0xF65C: -case 0xF65D: -case 0xF65E: -case 0xF65F: -case 0xF660: -case 0xF661: -case 0xF662: -case 0xF663: -case 0xF664: -case 0xF665: -case 0xF666: -case 0xF667: -case 0xF668: -case 0xF669: -case 0xF66A: -case 0xF66B: -case 0xF66C: -case 0xF66D: -case 0xF66E: -case 0xF66F: -case 0xF670: -case 0xF671: -case 0xF672: -case 0xF673: -case 0xF674: -case 0xF675: -case 0xF676: -case 0xF677: -case 0xF678: -case 0xF679: -case 0xF67A: -case 0xF67B: -case 0xF67C: -case 0xF67D: -case 0xF67E: -case 0xF67F: -case 0xF680: -case 0xF681: -case 0xF682: -case 0xF683: -case 0xF684: -case 0xF685: -case 0xF686: -case 0xF687: -case 0xF688: -case 0xF689: -case 0xF68A: -case 0xF68B: -case 0xF68C: -case 0xF68D: -case 0xF68E: -case 0xF68F: -case 0xF690: -case 0xF691: -case 0xF692: -case 0xF693: -case 0xF694: -case 0xF695: -case 0xF696: -case 0xF697: -case 0xF698: -case 0xF699: -case 0xF69A: -case 0xF69B: -case 0xF69C: -case 0xF69D: -case 0xF69E: -case 0xF69F: -case 0xF6A0: -case 0xF6A1: -case 0xF6A2: -case 0xF6A3: -case 0xF6A4: -case 0xF6A5: -case 0xF6A6: -case 0xF6A7: -case 0xF6A8: -case 0xF6A9: -case 0xF6AA: -case 0xF6AB: -case 0xF6AC: -case 0xF6AD: -case 0xF6AE: -case 0xF6AF: -case 0xF6B0: -case 0xF6B1: -case 0xF6B2: -case 0xF6B3: -case 0xF6B4: -case 0xF6B5: -case 0xF6B6: -case 0xF6B7: -case 0xF6B8: -case 0xF6B9: -case 0xF6BA: -case 0xF6BB: -case 0xF6BC: -case 0xF6BD: -case 0xF6BE: -case 0xF6BF: -case 0xF6C0: -case 0xF6C1: -case 0xF6C2: -case 0xF6C3: -case 0xF6C4: -case 0xF6C5: -case 0xF6C6: -case 0xF6C7: -case 0xF6C8: -case 0xF6C9: -case 0xF6CA: -case 0xF6CB: -case 0xF6CC: -case 0xF6CD: -case 0xF6CE: -case 0xF6CF: -case 0xF6D0: -case 0xF6D1: -case 0xF6D2: -case 0xF6D3: -case 0xF6D4: -case 0xF6D5: -case 0xF6D6: -case 0xF6D7: -case 0xF6D8: -case 0xF6D9: -case 0xF6DA: -case 0xF6DB: -case 0xF6DC: -case 0xF6DD: -case 0xF6DE: -case 0xF6DF: -case 0xF6E0: -case 0xF6E1: -case 0xF6E2: -case 0xF6E3: -case 0xF6E4: -case 0xF6E5: -case 0xF6E6: -case 0xF6E7: -case 0xF6E8: -case 0xF6E9: -case 0xF6EA: -case 0xF6EB: -case 0xF6EC: -case 0xF6ED: -case 0xF6EE: -case 0xF6EF: -case 0xF6F0: -case 0xF6F1: -case 0xF6F2: -case 0xF6F3: -case 0xF6F4: -case 0xF6F5: -case 0xF6F6: -case 0xF6F7: -case 0xF6F8: -case 0xF6F9: -case 0xF6FA: -case 0xF6FB: -case 0xF6FC: -case 0xF6FD: -case 0xF6FE: -case 0xF6FF: -case 0xF700: -case 0xF701: -case 0xF702: -case 0xF703: -case 0xF704: -case 0xF705: -case 0xF706: -case 0xF707: -case 0xF708: -case 0xF709: -case 0xF70A: -case 0xF70B: -case 0xF70C: -case 0xF70D: -case 0xF70E: -case 0xF70F: -case 0xF710: -case 0xF711: -case 0xF712: -case 0xF713: -case 0xF714: -case 0xF715: -case 0xF716: -case 0xF717: -case 0xF718: -case 0xF719: -case 0xF71A: -case 0xF71B: -case 0xF71C: -case 0xF71D: -case 0xF71E: -case 0xF71F: -case 0xF720: -case 0xF721: -case 0xF722: -case 0xF723: -case 0xF724: -case 0xF725: -case 0xF726: -case 0xF727: -case 0xF728: -case 0xF729: -case 0xF72A: -case 0xF72B: -case 0xF72C: -case 0xF72D: -case 0xF72E: -case 0xF72F: -case 0xF730: -case 0xF731: -case 0xF732: -case 0xF733: -case 0xF734: -case 0xF735: -case 0xF736: -case 0xF737: -case 0xF738: -case 0xF739: -case 0xF73A: -case 0xF73B: -case 0xF73C: -case 0xF73D: -case 0xF73E: -case 0xF73F: -case 0xF740: -case 0xF741: -case 0xF742: -case 0xF743: -case 0xF744: -case 0xF745: -case 0xF746: -case 0xF747: -case 0xF748: -case 0xF749: -case 0xF74A: -case 0xF74B: -case 0xF74C: -case 0xF74D: -case 0xF74E: -case 0xF74F: -case 0xF750: -case 0xF751: -case 0xF752: -case 0xF753: -case 0xF754: -case 0xF755: -case 0xF756: -case 0xF757: -case 0xF758: -case 0xF759: -case 0xF75A: -case 0xF75B: -case 0xF75C: -case 0xF75D: -case 0xF75E: -case 0xF75F: -case 0xF760: -case 0xF761: -case 0xF762: -case 0xF763: -case 0xF764: -case 0xF765: -case 0xF766: -case 0xF767: -case 0xF768: -case 0xF769: -case 0xF76A: -case 0xF76B: -case 0xF76C: -case 0xF76D: -case 0xF76E: -case 0xF76F: -case 0xF770: -case 0xF771: -case 0xF772: -case 0xF773: -case 0xF774: -case 0xF775: -case 0xF776: -case 0xF777: -case 0xF778: -case 0xF779: -case 0xF77A: -case 0xF77B: -case 0xF77C: -case 0xF77D: -case 0xF77E: -case 0xF77F: -case 0xF780: -case 0xF781: -case 0xF782: -case 0xF783: -case 0xF784: -case 0xF785: -case 0xF786: -case 0xF787: -case 0xF788: -case 0xF789: -case 0xF78A: -case 0xF78B: -case 0xF78C: -case 0xF78D: -case 0xF78E: -case 0xF78F: -case 0xF790: -case 0xF791: -case 0xF792: -case 0xF793: -case 0xF794: -case 0xF795: -case 0xF796: -case 0xF797: -case 0xF798: -case 0xF799: -case 0xF79A: -case 0xF79B: -case 0xF79C: -case 0xF79D: -case 0xF79E: -case 0xF79F: -case 0xF7A0: -case 0xF7A1: -case 0xF7A2: -case 0xF7A3: -case 0xF7A4: -case 0xF7A5: -case 0xF7A6: -case 0xF7A7: -case 0xF7A8: -case 0xF7A9: -case 0xF7AA: -case 0xF7AB: -case 0xF7AC: -case 0xF7AD: -case 0xF7AE: -case 0xF7AF: -case 0xF7B0: -case 0xF7B1: -case 0xF7B2: -case 0xF7B3: -case 0xF7B4: -case 0xF7B5: -case 0xF7B6: -case 0xF7B7: -case 0xF7B8: -case 0xF7B9: -case 0xF7BA: -case 0xF7BB: -case 0xF7BC: -case 0xF7BD: -case 0xF7BE: -case 0xF7BF: -case 0xF7C0: -case 0xF7C1: -case 0xF7C2: -case 0xF7C3: -case 0xF7C4: -case 0xF7C5: -case 0xF7C6: -case 0xF7C7: -case 0xF7C8: -case 0xF7C9: -case 0xF7CA: -case 0xF7CB: -case 0xF7CC: -case 0xF7CD: -case 0xF7CE: -case 0xF7CF: -case 0xF7D0: -case 0xF7D1: -case 0xF7D2: -case 0xF7D3: -case 0xF7D4: -case 0xF7D5: -case 0xF7D6: -case 0xF7D7: -case 0xF7D8: -case 0xF7D9: -case 0xF7DA: -case 0xF7DB: -case 0xF7DC: -case 0xF7DD: -case 0xF7DE: -case 0xF7DF: -case 0xF7E0: -case 0xF7E1: -case 0xF7E2: -case 0xF7E3: -case 0xF7E4: -case 0xF7E5: -case 0xF7E6: -case 0xF7E7: -case 0xF7E8: -case 0xF7E9: -case 0xF7EA: -case 0xF7EB: -case 0xF7EC: -case 0xF7ED: -case 0xF7EE: -case 0xF7EF: -case 0xF7F0: -case 0xF7F1: -case 0xF7F2: -case 0xF7F3: -case 0xF7F4: -case 0xF7F5: -case 0xF7F6: -case 0xF7F7: -case 0xF7F8: -case 0xF7F9: -case 0xF7FA: -case 0xF7FB: -case 0xF7FC: -case 0xF7FD: -case 0xF7FE: -case 0xF7FF: -case 0xF800: -case 0xF801: -case 0xF802: -case 0xF803: -case 0xF804: -case 0xF805: -case 0xF806: -case 0xF807: -case 0xF808: -case 0xF809: -case 0xF80A: -case 0xF80B: -case 0xF80C: -case 0xF80D: -case 0xF80E: -case 0xF80F: -case 0xF810: -case 0xF811: -case 0xF812: -case 0xF813: -case 0xF814: -case 0xF815: -case 0xF816: -case 0xF817: -case 0xF818: -case 0xF819: -case 0xF81A: -case 0xF81B: -case 0xF81C: -case 0xF81D: -case 0xF81E: -case 0xF81F: -case 0xF820: -case 0xF821: -case 0xF822: -case 0xF823: -case 0xF824: -case 0xF825: -case 0xF826: -case 0xF827: -case 0xF828: -case 0xF829: -case 0xF82A: -case 0xF82B: -case 0xF82C: -case 0xF82D: -case 0xF82E: -case 0xF82F: -case 0xF830: -case 0xF831: -case 0xF832: -case 0xF833: -case 0xF834: -case 0xF835: -case 0xF836: -case 0xF837: -case 0xF838: -case 0xF839: -case 0xF83A: -case 0xF83B: -case 0xF83C: -case 0xF83D: -case 0xF83E: -case 0xF83F: -case 0xF840: -case 0xF841: -case 0xF842: -case 0xF843: -case 0xF844: -case 0xF845: -case 0xF846: -case 0xF847: -case 0xF848: -case 0xF849: -case 0xF84A: -case 0xF84B: -case 0xF84C: -case 0xF84D: -case 0xF84E: -case 0xF84F: -case 0xF850: -case 0xF851: -case 0xF852: -case 0xF853: -case 0xF854: -case 0xF855: -case 0xF856: -case 0xF857: -case 0xF858: -case 0xF859: -case 0xF85A: -case 0xF85B: -case 0xF85C: -case 0xF85D: -case 0xF85E: -case 0xF85F: -case 0xF860: -case 0xF861: -case 0xF862: -case 0xF863: -case 0xF864: -case 0xF865: -case 0xF866: -case 0xF867: -case 0xF868: -case 0xF869: -case 0xF86A: -case 0xF86B: -case 0xF86C: -case 0xF86D: -case 0xF86E: -case 0xF86F: -case 0xF870: -case 0xF871: -case 0xF872: -case 0xF873: -case 0xF874: -case 0xF875: -case 0xF876: -case 0xF877: -case 0xF878: -case 0xF879: -case 0xF87A: -case 0xF87B: -case 0xF87C: -case 0xF87D: -case 0xF87E: -case 0xF87F: -case 0xF880: -case 0xF881: -case 0xF882: -case 0xF883: -case 0xF884: -case 0xF885: -case 0xF886: -case 0xF887: -case 0xF888: -case 0xF889: -case 0xF88A: -case 0xF88B: -case 0xF88C: -case 0xF88D: -case 0xF88E: -case 0xF88F: -case 0xF890: -case 0xF891: -case 0xF892: -case 0xF893: -case 0xF894: -case 0xF895: -case 0xF896: -case 0xF897: -case 0xF898: -case 0xF899: -case 0xF89A: -case 0xF89B: -case 0xF89C: -case 0xF89D: -case 0xF89E: -case 0xF89F: -case 0xF8A0: -case 0xF8A1: -case 0xF8A2: -case 0xF8A3: -case 0xF8A4: -case 0xF8A5: -case 0xF8A6: -case 0xF8A7: -case 0xF8A8: -case 0xF8A9: -case 0xF8AA: -case 0xF8AB: -case 0xF8AC: -case 0xF8AD: -case 0xF8AE: -case 0xF8AF: -case 0xF8B0: -case 0xF8B1: -case 0xF8B2: -case 0xF8B3: -case 0xF8B4: -case 0xF8B5: -case 0xF8B6: -case 0xF8B7: -case 0xF8B8: -case 0xF8B9: -case 0xF8BA: -case 0xF8BB: -case 0xF8BC: -case 0xF8BD: -case 0xF8BE: -case 0xF8BF: -case 0xF8C0: -case 0xF8C1: -case 0xF8C2: -case 0xF8C3: -case 0xF8C4: -case 0xF8C5: -case 0xF8C6: -case 0xF8C7: -case 0xF8C8: -case 0xF8C9: -case 0xF8CA: -case 0xF8CB: -case 0xF8CC: -case 0xF8CD: -case 0xF8CE: -case 0xF8CF: -case 0xF8D0: -case 0xF8D1: -case 0xF8D2: -case 0xF8D3: -case 0xF8D4: -case 0xF8D5: -case 0xF8D6: -case 0xF8D7: -case 0xF8D8: -case 0xF8D9: -case 0xF8DA: -case 0xF8DB: -case 0xF8DC: -case 0xF8DD: -case 0xF8DE: -case 0xF8DF: -case 0xF8E0: -case 0xF8E1: -case 0xF8E2: -case 0xF8E3: -case 0xF8E4: -case 0xF8E5: -case 0xF8E6: -case 0xF8E7: -case 0xF8E8: -case 0xF8E9: -case 0xF8EA: -case 0xF8EB: -case 0xF8EC: -case 0xF8ED: -case 0xF8EE: -case 0xF8EF: -case 0xF8F0: -case 0xF8F1: -case 0xF8F2: -case 0xF8F3: -case 0xF8F4: -case 0xF8F5: -case 0xF8F6: -case 0xF8F7: -case 0xF8F8: -case 0xF8F9: -case 0xF8FA: -case 0xF8FB: -case 0xF8FC: -case 0xF8FD: -case 0xF8FE: -case 0xF8FF: -case 0xF900: -case 0xF901: -case 0xF902: -case 0xF903: -case 0xF904: -case 0xF905: -case 0xF906: -case 0xF907: -case 0xF908: -case 0xF909: -case 0xF90A: -case 0xF90B: -case 0xF90C: -case 0xF90D: -case 0xF90E: -case 0xF90F: -case 0xF910: -case 0xF911: -case 0xF912: -case 0xF913: -case 0xF914: -case 0xF915: -case 0xF916: -case 0xF917: -case 0xF918: -case 0xF919: -case 0xF91A: -case 0xF91B: -case 0xF91C: -case 0xF91D: -case 0xF91E: -case 0xF91F: -case 0xF920: -case 0xF921: -case 0xF922: -case 0xF923: -case 0xF924: -case 0xF925: -case 0xF926: -case 0xF927: -case 0xF928: -case 0xF929: -case 0xF92A: -case 0xF92B: -case 0xF92C: -case 0xF92D: -case 0xF92E: -case 0xF92F: -case 0xF930: -case 0xF931: -case 0xF932: -case 0xF933: -case 0xF934: -case 0xF935: -case 0xF936: -case 0xF937: -case 0xF938: -case 0xF939: -case 0xF93A: -case 0xF93B: -case 0xF93C: -case 0xF93D: -case 0xF93E: -case 0xF93F: -case 0xF940: -case 0xF941: -case 0xF942: -case 0xF943: -case 0xF944: -case 0xF945: -case 0xF946: -case 0xF947: -case 0xF948: -case 0xF949: -case 0xF94A: -case 0xF94B: -case 0xF94C: -case 0xF94D: -case 0xF94E: -case 0xF94F: -case 0xF950: -case 0xF951: -case 0xF952: -case 0xF953: -case 0xF954: -case 0xF955: -case 0xF956: -case 0xF957: -case 0xF958: -case 0xF959: -case 0xF95A: -case 0xF95B: -case 0xF95C: -case 0xF95D: -case 0xF95E: -case 0xF95F: -case 0xF960: -case 0xF961: -case 0xF962: -case 0xF963: -case 0xF964: -case 0xF965: -case 0xF966: -case 0xF967: -case 0xF968: -case 0xF969: -case 0xF96A: -case 0xF96B: -case 0xF96C: -case 0xF96D: -case 0xF96E: -case 0xF96F: -case 0xF970: -case 0xF971: -case 0xF972: -case 0xF973: -case 0xF974: -case 0xF975: -case 0xF976: -case 0xF977: -case 0xF978: -case 0xF979: -case 0xF97A: -case 0xF97B: -case 0xF97C: -case 0xF97D: -case 0xF97E: -case 0xF97F: -case 0xF980: -case 0xF981: -case 0xF982: -case 0xF983: -case 0xF984: -case 0xF985: -case 0xF986: -case 0xF987: -case 0xF988: -case 0xF989: -case 0xF98A: -case 0xF98B: -case 0xF98C: -case 0xF98D: -case 0xF98E: -case 0xF98F: -case 0xF990: -case 0xF991: -case 0xF992: -case 0xF993: -case 0xF994: -case 0xF995: -case 0xF996: -case 0xF997: -case 0xF998: -case 0xF999: -case 0xF99A: -case 0xF99B: -case 0xF99C: -case 0xF99D: -case 0xF99E: -case 0xF99F: -case 0xF9A0: -case 0xF9A1: -case 0xF9A2: -case 0xF9A3: -case 0xF9A4: -case 0xF9A5: -case 0xF9A6: -case 0xF9A7: -case 0xF9A8: -case 0xF9A9: -case 0xF9AA: -case 0xF9AB: -case 0xF9AC: -case 0xF9AD: -case 0xF9AE: -case 0xF9AF: -case 0xF9B0: -case 0xF9B1: -case 0xF9B2: -case 0xF9B3: -case 0xF9B4: -case 0xF9B5: -case 0xF9B6: -case 0xF9B7: -case 0xF9B8: -case 0xF9B9: -case 0xF9BA: -case 0xF9BB: -case 0xF9BC: -case 0xF9BD: -case 0xF9BE: -case 0xF9BF: -case 0xF9C0: -case 0xF9C1: -case 0xF9C2: -case 0xF9C3: -case 0xF9C4: -case 0xF9C5: -case 0xF9C6: -case 0xF9C7: -case 0xF9C8: -case 0xF9C9: -case 0xF9CA: -case 0xF9CB: -case 0xF9CC: -case 0xF9CD: -case 0xF9CE: -case 0xF9CF: -case 0xF9D0: -case 0xF9D1: -case 0xF9D2: -case 0xF9D3: -case 0xF9D4: -case 0xF9D5: -case 0xF9D6: -case 0xF9D7: -case 0xF9D8: -case 0xF9D9: -case 0xF9DA: -case 0xF9DB: -case 0xF9DC: -case 0xF9DD: -case 0xF9DE: -case 0xF9DF: -case 0xF9E0: -case 0xF9E1: -case 0xF9E2: -case 0xF9E3: -case 0xF9E4: -case 0xF9E5: -case 0xF9E6: -case 0xF9E7: -case 0xF9E8: -case 0xF9E9: -case 0xF9EA: -case 0xF9EB: -case 0xF9EC: -case 0xF9ED: -case 0xF9EE: -case 0xF9EF: -case 0xF9F0: -case 0xF9F1: -case 0xF9F2: -case 0xF9F3: -case 0xF9F4: -case 0xF9F5: -case 0xF9F6: -case 0xF9F7: -case 0xF9F8: -case 0xF9F9: -case 0xF9FA: -case 0xF9FB: -case 0xF9FC: -case 0xF9FD: -case 0xF9FE: -case 0xF9FF: -case 0xFA00: -case 0xFA01: -case 0xFA02: -case 0xFA03: -case 0xFA04: -case 0xFA05: -case 0xFA06: -case 0xFA07: -case 0xFA08: -case 0xFA09: -case 0xFA0A: -case 0xFA0B: -case 0xFA0C: -case 0xFA0D: -case 0xFA0E: -case 0xFA0F: -case 0xFA10: -case 0xFA11: -case 0xFA12: -case 0xFA13: -case 0xFA14: -case 0xFA15: -case 0xFA16: -case 0xFA17: -case 0xFA18: -case 0xFA19: -case 0xFA1A: -case 0xFA1B: -case 0xFA1C: -case 0xFA1D: -case 0xFA1E: -case 0xFA1F: -case 0xFA20: -case 0xFA21: -case 0xFA22: -case 0xFA23: -case 0xFA24: -case 0xFA25: -case 0xFA26: -case 0xFA27: -case 0xFA28: -case 0xFA29: -case 0xFA2A: -case 0xFA2B: -case 0xFA2C: -case 0xFA2D: -case 0xFA2E: -case 0xFA2F: -case 0xFA30: -case 0xFA31: -case 0xFA32: -case 0xFA33: -case 0xFA34: -case 0xFA35: -case 0xFA36: -case 0xFA37: -case 0xFA38: -case 0xFA39: -case 0xFA3A: -case 0xFA3B: -case 0xFA3C: -case 0xFA3D: -case 0xFA3E: -case 0xFA3F: -case 0xFA40: -case 0xFA41: -case 0xFA42: -case 0xFA43: -case 0xFA44: -case 0xFA45: -case 0xFA46: -case 0xFA47: -case 0xFA48: -case 0xFA49: -case 0xFA4A: -case 0xFA4B: -case 0xFA4C: -case 0xFA4D: -case 0xFA4E: -case 0xFA4F: -case 0xFA50: -case 0xFA51: -case 0xFA52: -case 0xFA53: -case 0xFA54: -case 0xFA55: -case 0xFA56: -case 0xFA57: -case 0xFA58: -case 0xFA59: -case 0xFA5A: -case 0xFA5B: -case 0xFA5C: -case 0xFA5D: -case 0xFA5E: -case 0xFA5F: -case 0xFA60: -case 0xFA61: -case 0xFA62: -case 0xFA63: -case 0xFA64: -case 0xFA65: -case 0xFA66: -case 0xFA67: -case 0xFA68: -case 0xFA69: -case 0xFA6A: -case 0xFA6B: -case 0xFA6C: -case 0xFA6D: -case 0xFA6E: -case 0xFA6F: -case 0xFA70: -case 0xFA71: -case 0xFA72: -case 0xFA73: -case 0xFA74: -case 0xFA75: -case 0xFA76: -case 0xFA77: -case 0xFA78: -case 0xFA79: -case 0xFA7A: -case 0xFA7B: -case 0xFA7C: -case 0xFA7D: -case 0xFA7E: -case 0xFA7F: -case 0xFA80: -case 0xFA81: -case 0xFA82: -case 0xFA83: -case 0xFA84: -case 0xFA85: -case 0xFA86: -case 0xFA87: -case 0xFA88: -case 0xFA89: -case 0xFA8A: -case 0xFA8B: -case 0xFA8C: -case 0xFA8D: -case 0xFA8E: -case 0xFA8F: -case 0xFA90: -case 0xFA91: -case 0xFA92: -case 0xFA93: -case 0xFA94: -case 0xFA95: -case 0xFA96: -case 0xFA97: -case 0xFA98: -case 0xFA99: -case 0xFA9A: -case 0xFA9B: -case 0xFA9C: -case 0xFA9D: -case 0xFA9E: -case 0xFA9F: -case 0xFAA0: -case 0xFAA1: -case 0xFAA2: -case 0xFAA3: -case 0xFAA4: -case 0xFAA5: -case 0xFAA6: -case 0xFAA7: -case 0xFAA8: -case 0xFAA9: -case 0xFAAA: -case 0xFAAB: -case 0xFAAC: -case 0xFAAD: -case 0xFAAE: -case 0xFAAF: -case 0xFAB0: -case 0xFAB1: -case 0xFAB2: -case 0xFAB3: -case 0xFAB4: -case 0xFAB5: -case 0xFAB6: -case 0xFAB7: -case 0xFAB8: -case 0xFAB9: -case 0xFABA: -case 0xFABB: -case 0xFABC: -case 0xFABD: -case 0xFABE: -case 0xFABF: -case 0xFAC0: -case 0xFAC1: -case 0xFAC2: -case 0xFAC3: -case 0xFAC4: -case 0xFAC5: -case 0xFAC6: -case 0xFAC7: -case 0xFAC8: -case 0xFAC9: -case 0xFACA: -case 0xFACB: -case 0xFACC: -case 0xFACD: -case 0xFACE: -case 0xFACF: -case 0xFAD0: -case 0xFAD1: -case 0xFAD2: -case 0xFAD3: -case 0xFAD4: -case 0xFAD5: -case 0xFAD6: -case 0xFAD7: -case 0xFAD8: -case 0xFAD9: -case 0xFADA: -case 0xFADB: -case 0xFADC: -case 0xFADD: -case 0xFADE: -case 0xFADF: -case 0xFAE0: -case 0xFAE1: -case 0xFAE2: -case 0xFAE3: -case 0xFAE4: -case 0xFAE5: -case 0xFAE6: -case 0xFAE7: -case 0xFAE8: -case 0xFAE9: -case 0xFAEA: -case 0xFAEB: -case 0xFAEC: -case 0xFAED: -case 0xFAEE: -case 0xFAEF: -case 0xFAF0: -case 0xFAF1: -case 0xFAF2: -case 0xFAF3: -case 0xFAF4: -case 0xFAF5: -case 0xFAF6: -case 0xFAF7: -case 0xFAF8: -case 0xFAF9: -case 0xFAFA: -case 0xFAFB: -case 0xFAFC: -case 0xFAFD: -case 0xFAFE: -case 0xFAFF: -case 0xFB00: -case 0xFB01: -case 0xFB02: -case 0xFB03: -case 0xFB04: -case 0xFB05: -case 0xFB06: -case 0xFB07: -case 0xFB08: -case 0xFB09: -case 0xFB0A: -case 0xFB0B: -case 0xFB0C: -case 0xFB0D: -case 0xFB0E: -case 0xFB0F: -case 0xFB10: -case 0xFB11: -case 0xFB12: -case 0xFB13: -case 0xFB14: -case 0xFB15: -case 0xFB16: -case 0xFB17: -case 0xFB18: -case 0xFB19: -case 0xFB1A: -case 0xFB1B: -case 0xFB1C: -case 0xFB1D: -case 0xFB1E: -case 0xFB1F: -case 0xFB20: -case 0xFB21: -case 0xFB22: -case 0xFB23: -case 0xFB24: -case 0xFB25: -case 0xFB26: -case 0xFB27: -case 0xFB28: -case 0xFB29: -case 0xFB2A: -case 0xFB2B: -case 0xFB2C: -case 0xFB2D: -case 0xFB2E: -case 0xFB2F: -case 0xFB30: -case 0xFB31: -case 0xFB32: -case 0xFB33: -case 0xFB34: -case 0xFB35: -case 0xFB36: -case 0xFB37: -case 0xFB38: -case 0xFB39: -case 0xFB3A: -case 0xFB3B: -case 0xFB3C: -case 0xFB3D: -case 0xFB3E: -case 0xFB3F: -case 0xFB40: -case 0xFB41: -case 0xFB42: -case 0xFB43: -case 0xFB44: -case 0xFB45: -case 0xFB46: -case 0xFB47: -case 0xFB48: -case 0xFB49: -case 0xFB4A: -case 0xFB4B: -case 0xFB4C: -case 0xFB4D: -case 0xFB4E: -case 0xFB4F: -case 0xFB50: -case 0xFB51: -case 0xFB52: -case 0xFB53: -case 0xFB54: -case 0xFB55: -case 0xFB56: -case 0xFB57: -case 0xFB58: -case 0xFB59: -case 0xFB5A: -case 0xFB5B: -case 0xFB5C: -case 0xFB5D: -case 0xFB5E: -case 0xFB5F: -case 0xFB60: -case 0xFB61: -case 0xFB62: -case 0xFB63: -case 0xFB64: -case 0xFB65: -case 0xFB66: -case 0xFB67: -case 0xFB68: -case 0xFB69: -case 0xFB6A: -case 0xFB6B: -case 0xFB6C: -case 0xFB6D: -case 0xFB6E: -case 0xFB6F: -case 0xFB70: -case 0xFB71: -case 0xFB72: -case 0xFB73: -case 0xFB74: -case 0xFB75: -case 0xFB76: -case 0xFB77: -case 0xFB78: -case 0xFB79: -case 0xFB7A: -case 0xFB7B: -case 0xFB7C: -case 0xFB7D: -case 0xFB7E: -case 0xFB7F: -case 0xFB80: -case 0xFB81: -case 0xFB82: -case 0xFB83: -case 0xFB84: -case 0xFB85: -case 0xFB86: -case 0xFB87: -case 0xFB88: -case 0xFB89: -case 0xFB8A: -case 0xFB8B: -case 0xFB8C: -case 0xFB8D: -case 0xFB8E: -case 0xFB8F: -case 0xFB90: -case 0xFB91: -case 0xFB92: -case 0xFB93: -case 0xFB94: -case 0xFB95: -case 0xFB96: -case 0xFB97: -case 0xFB98: -case 0xFB99: -case 0xFB9A: -case 0xFB9B: -case 0xFB9C: -case 0xFB9D: -case 0xFB9E: -case 0xFB9F: -case 0xFBA0: -case 0xFBA1: -case 0xFBA2: -case 0xFBA3: -case 0xFBA4: -case 0xFBA5: -case 0xFBA6: -case 0xFBA7: -case 0xFBA8: -case 0xFBA9: -case 0xFBAA: -case 0xFBAB: -case 0xFBAC: -case 0xFBAD: -case 0xFBAE: -case 0xFBAF: -case 0xFBB0: -case 0xFBB1: -case 0xFBB2: -case 0xFBB3: -case 0xFBB4: -case 0xFBB5: -case 0xFBB6: -case 0xFBB7: -case 0xFBB8: -case 0xFBB9: -case 0xFBBA: -case 0xFBBB: -case 0xFBBC: -case 0xFBBD: -case 0xFBBE: -case 0xFBBF: -case 0xFBC0: -case 0xFBC1: -case 0xFBC2: -case 0xFBC3: -case 0xFBC4: -case 0xFBC5: -case 0xFBC6: -case 0xFBC7: -case 0xFBC8: -case 0xFBC9: -case 0xFBCA: -case 0xFBCB: -case 0xFBCC: -case 0xFBCD: -case 0xFBCE: -case 0xFBCF: -case 0xFBD0: -case 0xFBD1: -case 0xFBD2: -case 0xFBD3: -case 0xFBD4: -case 0xFBD5: -case 0xFBD6: -case 0xFBD7: -case 0xFBD8: -case 0xFBD9: -case 0xFBDA: -case 0xFBDB: -case 0xFBDC: -case 0xFBDD: -case 0xFBDE: -case 0xFBDF: -case 0xFBE0: -case 0xFBE1: -case 0xFBE2: -case 0xFBE3: -case 0xFBE4: -case 0xFBE5: -case 0xFBE6: -case 0xFBE7: -case 0xFBE8: -case 0xFBE9: -case 0xFBEA: -case 0xFBEB: -case 0xFBEC: -case 0xFBED: -case 0xFBEE: -case 0xFBEF: -case 0xFBF0: -case 0xFBF1: -case 0xFBF2: -case 0xFBF3: -case 0xFBF4: -case 0xFBF5: -case 0xFBF6: -case 0xFBF7: -case 0xFBF8: -case 0xFBF9: -case 0xFBFA: -case 0xFBFB: -case 0xFBFC: -case 0xFBFD: -case 0xFBFE: -case 0xFBFF: -case 0xFC00: -case 0xFC01: -case 0xFC02: -case 0xFC03: -case 0xFC04: -case 0xFC05: -case 0xFC06: -case 0xFC07: -case 0xFC08: -case 0xFC09: -case 0xFC0A: -case 0xFC0B: -case 0xFC0C: -case 0xFC0D: -case 0xFC0E: -case 0xFC0F: -case 0xFC10: -case 0xFC11: -case 0xFC12: -case 0xFC13: -case 0xFC14: -case 0xFC15: -case 0xFC16: -case 0xFC17: -case 0xFC18: -case 0xFC19: -case 0xFC1A: -case 0xFC1B: -case 0xFC1C: -case 0xFC1D: -case 0xFC1E: -case 0xFC1F: -case 0xFC20: -case 0xFC21: -case 0xFC22: -case 0xFC23: -case 0xFC24: -case 0xFC25: -case 0xFC26: -case 0xFC27: -case 0xFC28: -case 0xFC29: -case 0xFC2A: -case 0xFC2B: -case 0xFC2C: -case 0xFC2D: -case 0xFC2E: -case 0xFC2F: -case 0xFC30: -case 0xFC31: -case 0xFC32: -case 0xFC33: -case 0xFC34: -case 0xFC35: -case 0xFC36: -case 0xFC37: -case 0xFC38: -case 0xFC39: -case 0xFC3A: -case 0xFC3B: -case 0xFC3C: -case 0xFC3D: -case 0xFC3E: -case 0xFC3F: -case 0xFC40: -case 0xFC41: -case 0xFC42: -case 0xFC43: -case 0xFC44: -case 0xFC45: -case 0xFC46: -case 0xFC47: -case 0xFC48: -case 0xFC49: -case 0xFC4A: -case 0xFC4B: -case 0xFC4C: -case 0xFC4D: -case 0xFC4E: -case 0xFC4F: -case 0xFC50: -case 0xFC51: -case 0xFC52: -case 0xFC53: -case 0xFC54: -case 0xFC55: -case 0xFC56: -case 0xFC57: -case 0xFC58: -case 0xFC59: -case 0xFC5A: -case 0xFC5B: -case 0xFC5C: -case 0xFC5D: -case 0xFC5E: -case 0xFC5F: -case 0xFC60: -case 0xFC61: -case 0xFC62: -case 0xFC63: -case 0xFC64: -case 0xFC65: -case 0xFC66: -case 0xFC67: -case 0xFC68: -case 0xFC69: -case 0xFC6A: -case 0xFC6B: -case 0xFC6C: -case 0xFC6D: -case 0xFC6E: -case 0xFC6F: -case 0xFC70: -case 0xFC71: -case 0xFC72: -case 0xFC73: -case 0xFC74: -case 0xFC75: -case 0xFC76: -case 0xFC77: -case 0xFC78: -case 0xFC79: -case 0xFC7A: -case 0xFC7B: -case 0xFC7C: -case 0xFC7D: -case 0xFC7E: -case 0xFC7F: -case 0xFC80: -case 0xFC81: -case 0xFC82: -case 0xFC83: -case 0xFC84: -case 0xFC85: -case 0xFC86: -case 0xFC87: -case 0xFC88: -case 0xFC89: -case 0xFC8A: -case 0xFC8B: -case 0xFC8C: -case 0xFC8D: -case 0xFC8E: -case 0xFC8F: -case 0xFC90: -case 0xFC91: -case 0xFC92: -case 0xFC93: -case 0xFC94: -case 0xFC95: -case 0xFC96: -case 0xFC97: -case 0xFC98: -case 0xFC99: -case 0xFC9A: -case 0xFC9B: -case 0xFC9C: -case 0xFC9D: -case 0xFC9E: -case 0xFC9F: -case 0xFCA0: -case 0xFCA1: -case 0xFCA2: -case 0xFCA3: -case 0xFCA4: -case 0xFCA5: -case 0xFCA6: -case 0xFCA7: -case 0xFCA8: -case 0xFCA9: -case 0xFCAA: -case 0xFCAB: -case 0xFCAC: -case 0xFCAD: -case 0xFCAE: -case 0xFCAF: -case 0xFCB0: -case 0xFCB1: -case 0xFCB2: -case 0xFCB3: -case 0xFCB4: -case 0xFCB5: -case 0xFCB6: -case 0xFCB7: -case 0xFCB8: -case 0xFCB9: -case 0xFCBA: -case 0xFCBB: -case 0xFCBC: -case 0xFCBD: -case 0xFCBE: -case 0xFCBF: -case 0xFCC0: -case 0xFCC1: -case 0xFCC2: -case 0xFCC3: -case 0xFCC4: -case 0xFCC5: -case 0xFCC6: -case 0xFCC7: -case 0xFCC8: -case 0xFCC9: -case 0xFCCA: -case 0xFCCB: -case 0xFCCC: -case 0xFCCD: -case 0xFCCE: -case 0xFCCF: -case 0xFCD0: -case 0xFCD1: -case 0xFCD2: -case 0xFCD3: -case 0xFCD4: -case 0xFCD5: -case 0xFCD6: -case 0xFCD7: -case 0xFCD8: -case 0xFCD9: -case 0xFCDA: -case 0xFCDB: -case 0xFCDC: -case 0xFCDD: -case 0xFCDE: -case 0xFCDF: -case 0xFCE0: -case 0xFCE1: -case 0xFCE2: -case 0xFCE3: -case 0xFCE4: -case 0xFCE5: -case 0xFCE6: -case 0xFCE7: -case 0xFCE8: -case 0xFCE9: -case 0xFCEA: -case 0xFCEB: -case 0xFCEC: -case 0xFCED: -case 0xFCEE: -case 0xFCEF: -case 0xFCF0: -case 0xFCF1: -case 0xFCF2: -case 0xFCF3: -case 0xFCF4: -case 0xFCF5: -case 0xFCF6: -case 0xFCF7: -case 0xFCF8: -case 0xFCF9: -case 0xFCFA: -case 0xFCFB: -case 0xFCFC: -case 0xFCFD: -case 0xFCFE: -case 0xFCFF: -case 0xFD00: -case 0xFD01: -case 0xFD02: -case 0xFD03: -case 0xFD04: -case 0xFD05: -case 0xFD06: -case 0xFD07: -case 0xFD08: -case 0xFD09: -case 0xFD0A: -case 0xFD0B: -case 0xFD0C: -case 0xFD0D: -case 0xFD0E: -case 0xFD0F: -case 0xFD10: -case 0xFD11: -case 0xFD12: -case 0xFD13: -case 0xFD14: -case 0xFD15: -case 0xFD16: -case 0xFD17: -case 0xFD18: -case 0xFD19: -case 0xFD1A: -case 0xFD1B: -case 0xFD1C: -case 0xFD1D: -case 0xFD1E: -case 0xFD1F: -case 0xFD20: -case 0xFD21: -case 0xFD22: -case 0xFD23: -case 0xFD24: -case 0xFD25: -case 0xFD26: -case 0xFD27: -case 0xFD28: -case 0xFD29: -case 0xFD2A: -case 0xFD2B: -case 0xFD2C: -case 0xFD2D: -case 0xFD2E: -case 0xFD2F: -case 0xFD30: -case 0xFD31: -case 0xFD32: -case 0xFD33: -case 0xFD34: -case 0xFD35: -case 0xFD36: -case 0xFD37: -case 0xFD38: -case 0xFD39: -case 0xFD3A: -case 0xFD3B: -case 0xFD3C: -case 0xFD3D: -case 0xFD3E: -case 0xFD3F: -case 0xFD40: -case 0xFD41: -case 0xFD42: -case 0xFD43: -case 0xFD44: -case 0xFD45: -case 0xFD46: -case 0xFD47: -case 0xFD48: -case 0xFD49: -case 0xFD4A: -case 0xFD4B: -case 0xFD4C: -case 0xFD4D: -case 0xFD4E: -case 0xFD4F: -case 0xFD50: -case 0xFD51: -case 0xFD52: -case 0xFD53: -case 0xFD54: -case 0xFD55: -case 0xFD56: -case 0xFD57: -case 0xFD58: -case 0xFD59: -case 0xFD5A: -case 0xFD5B: -case 0xFD5C: -case 0xFD5D: -case 0xFD5E: -case 0xFD5F: -case 0xFD60: -case 0xFD61: -case 0xFD62: -case 0xFD63: -case 0xFD64: -case 0xFD65: -case 0xFD66: -case 0xFD67: -case 0xFD68: -case 0xFD69: -case 0xFD6A: -case 0xFD6B: -case 0xFD6C: -case 0xFD6D: -case 0xFD6E: -case 0xFD6F: -case 0xFD70: -case 0xFD71: -case 0xFD72: -case 0xFD73: -case 0xFD74: -case 0xFD75: -case 0xFD76: -case 0xFD77: -case 0xFD78: -case 0xFD79: -case 0xFD7A: -case 0xFD7B: -case 0xFD7C: -case 0xFD7D: -case 0xFD7E: -case 0xFD7F: -case 0xFD80: -case 0xFD81: -case 0xFD82: -case 0xFD83: -case 0xFD84: -case 0xFD85: -case 0xFD86: -case 0xFD87: -case 0xFD88: -case 0xFD89: -case 0xFD8A: -case 0xFD8B: -case 0xFD8C: -case 0xFD8D: -case 0xFD8E: -case 0xFD8F: -case 0xFD90: -case 0xFD91: -case 0xFD92: -case 0xFD93: -case 0xFD94: -case 0xFD95: -case 0xFD96: -case 0xFD97: -case 0xFD98: -case 0xFD99: -case 0xFD9A: -case 0xFD9B: -case 0xFD9C: -case 0xFD9D: -case 0xFD9E: -case 0xFD9F: -case 0xFDA0: -case 0xFDA1: -case 0xFDA2: -case 0xFDA3: -case 0xFDA4: -case 0xFDA5: -case 0xFDA6: -case 0xFDA7: -case 0xFDA8: -case 0xFDA9: -case 0xFDAA: -case 0xFDAB: -case 0xFDAC: -case 0xFDAD: -case 0xFDAE: -case 0xFDAF: -case 0xFDB0: -case 0xFDB1: -case 0xFDB2: -case 0xFDB3: -case 0xFDB4: -case 0xFDB5: -case 0xFDB6: -case 0xFDB7: -case 0xFDB8: -case 0xFDB9: -case 0xFDBA: -case 0xFDBB: -case 0xFDBC: -case 0xFDBD: -case 0xFDBE: -case 0xFDBF: -case 0xFDC0: -case 0xFDC1: -case 0xFDC2: -case 0xFDC3: -case 0xFDC4: -case 0xFDC5: -case 0xFDC6: -case 0xFDC7: -case 0xFDC8: -case 0xFDC9: -case 0xFDCA: -case 0xFDCB: -case 0xFDCC: -case 0xFDCD: -case 0xFDCE: -case 0xFDCF: -case 0xFDD0: -case 0xFDD1: -case 0xFDD2: -case 0xFDD3: -case 0xFDD4: -case 0xFDD5: -case 0xFDD6: -case 0xFDD7: -case 0xFDD8: -case 0xFDD9: -case 0xFDDA: -case 0xFDDB: -case 0xFDDC: -case 0xFDDD: -case 0xFDDE: -case 0xFDDF: -case 0xFDE0: -case 0xFDE1: -case 0xFDE2: -case 0xFDE3: -case 0xFDE4: -case 0xFDE5: -case 0xFDE6: -case 0xFDE7: -case 0xFDE8: -case 0xFDE9: -case 0xFDEA: -case 0xFDEB: -case 0xFDEC: -case 0xFDED: -case 0xFDEE: -case 0xFDEF: -case 0xFDF0: -case 0xFDF1: -case 0xFDF2: -case 0xFDF3: -case 0xFDF4: -case 0xFDF5: -case 0xFDF6: -case 0xFDF7: -case 0xFDF8: -case 0xFDF9: -case 0xFDFA: -case 0xFDFB: -case 0xFDFC: -case 0xFDFD: -case 0xFDFE: -case 0xFDFF: -case 0xFE00: -case 0xFE01: -case 0xFE02: -case 0xFE03: -case 0xFE04: -case 0xFE05: -case 0xFE06: -case 0xFE07: -case 0xFE08: -case 0xFE09: -case 0xFE0A: -case 0xFE0B: -case 0xFE0C: -case 0xFE0D: -case 0xFE0E: -case 0xFE0F: -case 0xFE10: -case 0xFE11: -case 0xFE12: -case 0xFE13: -case 0xFE14: -case 0xFE15: -case 0xFE16: -case 0xFE17: -case 0xFE18: -case 0xFE19: -case 0xFE1A: -case 0xFE1B: -case 0xFE1C: -case 0xFE1D: -case 0xFE1E: -case 0xFE1F: -case 0xFE20: -case 0xFE21: -case 0xFE22: -case 0xFE23: -case 0xFE24: -case 0xFE25: -case 0xFE26: -case 0xFE27: -case 0xFE28: -case 0xFE29: -case 0xFE2A: -case 0xFE2B: -case 0xFE2C: -case 0xFE2D: -case 0xFE2E: -case 0xFE2F: -case 0xFE30: -case 0xFE31: -case 0xFE32: -case 0xFE33: -case 0xFE34: -case 0xFE35: -case 0xFE36: -case 0xFE37: -case 0xFE38: -case 0xFE39: -case 0xFE3A: -case 0xFE3B: -case 0xFE3C: -case 0xFE3D: -case 0xFE3E: -case 0xFE3F: -case 0xFE40: -case 0xFE41: -case 0xFE42: -case 0xFE43: -case 0xFE44: -case 0xFE45: -case 0xFE46: -case 0xFE47: -case 0xFE48: -case 0xFE49: -case 0xFE4A: -case 0xFE4B: -case 0xFE4C: -case 0xFE4D: -case 0xFE4E: -case 0xFE4F: -case 0xFE50: -case 0xFE51: -case 0xFE52: -case 0xFE53: -case 0xFE54: -case 0xFE55: -case 0xFE56: -case 0xFE57: -case 0xFE58: -case 0xFE59: -case 0xFE5A: -case 0xFE5B: -case 0xFE5C: -case 0xFE5D: -case 0xFE5E: -case 0xFE5F: -case 0xFE60: -case 0xFE61: -case 0xFE62: -case 0xFE63: -case 0xFE64: -case 0xFE65: -case 0xFE66: -case 0xFE67: -case 0xFE68: -case 0xFE69: -case 0xFE6A: -case 0xFE6B: -case 0xFE6C: -case 0xFE6D: -case 0xFE6E: -case 0xFE6F: -case 0xFE70: -case 0xFE71: -case 0xFE72: -case 0xFE73: -case 0xFE74: -case 0xFE75: -case 0xFE76: -case 0xFE77: -case 0xFE78: -case 0xFE79: -case 0xFE7A: -case 0xFE7B: -case 0xFE7C: -case 0xFE7D: -case 0xFE7E: -case 0xFE7F: -case 0xFE80: -case 0xFE81: -case 0xFE82: -case 0xFE83: -case 0xFE84: -case 0xFE85: -case 0xFE86: -case 0xFE87: -case 0xFE88: -case 0xFE89: -case 0xFE8A: -case 0xFE8B: -case 0xFE8C: -case 0xFE8D: -case 0xFE8E: -case 0xFE8F: -case 0xFE90: -case 0xFE91: -case 0xFE92: -case 0xFE93: -case 0xFE94: -case 0xFE95: -case 0xFE96: -case 0xFE97: -case 0xFE98: -case 0xFE99: -case 0xFE9A: -case 0xFE9B: -case 0xFE9C: -case 0xFE9D: -case 0xFE9E: -case 0xFE9F: -case 0xFEA0: -case 0xFEA1: -case 0xFEA2: -case 0xFEA3: -case 0xFEA4: -case 0xFEA5: -case 0xFEA6: -case 0xFEA7: -case 0xFEA8: -case 0xFEA9: -case 0xFEAA: -case 0xFEAB: -case 0xFEAC: -case 0xFEAD: -case 0xFEAE: -case 0xFEAF: -case 0xFEB0: -case 0xFEB1: -case 0xFEB2: -case 0xFEB3: -case 0xFEB4: -case 0xFEB5: -case 0xFEB6: -case 0xFEB7: -case 0xFEB8: -case 0xFEB9: -case 0xFEBA: -case 0xFEBB: -case 0xFEBC: -case 0xFEBD: -case 0xFEBE: -case 0xFEBF: -case 0xFEC0: -case 0xFEC1: -case 0xFEC2: -case 0xFEC3: -case 0xFEC4: -case 0xFEC5: -case 0xFEC6: -case 0xFEC7: -case 0xFEC8: -case 0xFEC9: -case 0xFECA: -case 0xFECB: -case 0xFECC: -case 0xFECD: -case 0xFECE: -case 0xFECF: -case 0xFED0: -case 0xFED1: -case 0xFED2: -case 0xFED3: -case 0xFED4: -case 0xFED5: -case 0xFED6: -case 0xFED7: -case 0xFED8: -case 0xFED9: -case 0xFEDA: -case 0xFEDB: -case 0xFEDC: -case 0xFEDD: -case 0xFEDE: -case 0xFEDF: -case 0xFEE0: -case 0xFEE1: -case 0xFEE2: -case 0xFEE3: -case 0xFEE4: -case 0xFEE5: -case 0xFEE6: -case 0xFEE7: -case 0xFEE8: -case 0xFEE9: -case 0xFEEA: -case 0xFEEB: -case 0xFEEC: -case 0xFEED: -case 0xFEEE: -case 0xFEEF: -case 0xFEF0: -case 0xFEF1: -case 0xFEF2: -case 0xFEF3: -case 0xFEF4: -case 0xFEF5: -case 0xFEF6: -case 0xFEF7: -case 0xFEF8: -case 0xFEF9: -case 0xFEFA: -case 0xFEFB: -case 0xFEFC: -case 0xFEFD: -case 0xFEFE: -case 0xFEFF: -case 0xFF00: -case 0xFF01: -case 0xFF02: -case 0xFF03: -case 0xFF04: -case 0xFF05: -case 0xFF06: -case 0xFF07: -case 0xFF08: -case 0xFF09: -case 0xFF0A: -case 0xFF0B: -case 0xFF0C: -case 0xFF0D: -case 0xFF0E: -case 0xFF0F: -case 0xFF10: -case 0xFF11: -case 0xFF12: -case 0xFF13: -case 0xFF14: -case 0xFF15: -case 0xFF16: -case 0xFF17: -case 0xFF18: -case 0xFF19: -case 0xFF1A: -case 0xFF1B: -case 0xFF1C: -case 0xFF1D: -case 0xFF1E: -case 0xFF1F: -case 0xFF20: -case 0xFF21: -case 0xFF22: -case 0xFF23: -case 0xFF24: -case 0xFF25: -case 0xFF26: -case 0xFF27: -case 0xFF28: -case 0xFF29: -case 0xFF2A: -case 0xFF2B: -case 0xFF2C: -case 0xFF2D: -case 0xFF2E: -case 0xFF2F: -case 0xFF30: -case 0xFF31: -case 0xFF32: -case 0xFF33: -case 0xFF34: -case 0xFF35: -case 0xFF36: -case 0xFF37: -case 0xFF38: -case 0xFF39: -case 0xFF3A: -case 0xFF3B: -case 0xFF3C: -case 0xFF3D: -case 0xFF3E: -case 0xFF3F: -case 0xFF40: -case 0xFF41: -case 0xFF42: -case 0xFF43: -case 0xFF44: -case 0xFF45: -case 0xFF46: -case 0xFF47: -case 0xFF48: -case 0xFF49: -case 0xFF4A: -case 0xFF4B: -case 0xFF4C: -case 0xFF4D: -case 0xFF4E: -case 0xFF4F: -case 0xFF50: -case 0xFF51: -case 0xFF52: -case 0xFF53: -case 0xFF54: -case 0xFF55: -case 0xFF56: -case 0xFF57: -case 0xFF58: -case 0xFF59: -case 0xFF5A: -case 0xFF5B: -case 0xFF5C: -case 0xFF5D: -case 0xFF5E: -case 0xFF5F: -case 0xFF60: -case 0xFF61: -case 0xFF62: -case 0xFF63: -case 0xFF64: -case 0xFF65: -case 0xFF66: -case 0xFF67: -case 0xFF68: -case 0xFF69: -case 0xFF6A: -case 0xFF6B: -case 0xFF6C: -case 0xFF6D: -case 0xFF6E: -case 0xFF6F: -case 0xFF70: -case 0xFF71: -case 0xFF72: -case 0xFF73: -case 0xFF74: -case 0xFF75: -case 0xFF76: -case 0xFF77: -case 0xFF78: -case 0xFF79: -case 0xFF7A: -case 0xFF7B: -case 0xFF7C: -case 0xFF7D: -case 0xFF7E: -case 0xFF7F: -case 0xFF80: -case 0xFF81: -case 0xFF82: -case 0xFF83: -case 0xFF84: -case 0xFF85: -case 0xFF86: -case 0xFF87: -case 0xFF88: -case 0xFF89: -case 0xFF8A: -case 0xFF8B: -case 0xFF8C: -case 0xFF8D: -case 0xFF8E: -case 0xFF8F: -case 0xFF90: -case 0xFF91: -case 0xFF92: -case 0xFF93: -case 0xFF94: -case 0xFF95: -case 0xFF96: -case 0xFF97: -case 0xFF98: -case 0xFF99: -case 0xFF9A: -case 0xFF9B: -case 0xFF9C: -case 0xFF9D: -case 0xFF9E: -case 0xFF9F: -case 0xFFA0: -case 0xFFA1: -case 0xFFA2: -case 0xFFA3: -case 0xFFA4: -case 0xFFA5: -case 0xFFA6: -case 0xFFA7: -case 0xFFA8: -case 0xFFA9: -case 0xFFAA: -case 0xFFAB: -case 0xFFAC: -case 0xFFAD: -case 0xFFAE: -case 0xFFAF: -case 0xFFB0: -case 0xFFB1: -case 0xFFB2: -case 0xFFB3: -case 0xFFB4: -case 0xFFB5: -case 0xFFB6: -case 0xFFB7: -case 0xFFB8: -case 0xFFB9: -case 0xFFBA: -case 0xFFBB: -case 0xFFBC: -case 0xFFBD: -case 0xFFBE: -case 0xFFBF: -case 0xFFC0: -case 0xFFC1: -case 0xFFC2: -case 0xFFC3: -case 0xFFC4: -case 0xFFC5: -case 0xFFC6: -case 0xFFC7: -case 0xFFC8: -case 0xFFC9: -case 0xFFCA: -case 0xFFCB: -case 0xFFCC: -case 0xFFCD: -case 0xFFCE: -case 0xFFCF: -case 0xFFD0: -case 0xFFD1: -case 0xFFD2: -case 0xFFD3: -case 0xFFD4: -case 0xFFD5: -case 0xFFD6: -case 0xFFD7: -case 0xFFD8: -case 0xFFD9: -case 0xFFDA: -case 0xFFDB: -case 0xFFDC: -case 0xFFDD: -case 0xFFDE: -case 0xFFDF: -case 0xFFE0: -case 0xFFE1: -case 0xFFE2: -case 0xFFE3: -case 0xFFE4: -case 0xFFE5: -case 0xFFE6: -case 0xFFE7: -case 0xFFE8: -case 0xFFE9: -case 0xFFEA: -case 0xFFEB: -case 0xFFEC: -case 0xFFED: -case 0xFFEE: -case 0xFFEF: -case 0xFFF0: -case 0xFFF1: -case 0xFFF2: -case 0xFFF3: -case 0xFFF4: -case 0xFFF5: -case 0xFFF6: -case 0xFFF7: -case 0xFFF8: -case 0xFFF9: -case 0xFFFA: -case 0xFFFB: -case 0xFFFC: -case 0xFFFD: -case 0xFFFE: -case 0xFFFF: - -// 1111 -case 0xF000: -{ - u32 res; - PC -= 2; - if (!CPU->flag_S) - { - res = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = res; - } - res = C68K_1111_EX; - CCnt -= c68k_exception_cycle_table[res]; - PRE_IO - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - CPU->flag_S = C68K_SR_S; - READ_LONG_F(res * 4, PC) - SET_PC(PC) - POST_IO -} -RET(4) diff --git a/yabause/src/c68k/c68kexec.c b/yabause/src/c68k/c68kexec.c deleted file mode 100644 index c9ad703871..0000000000 --- a/yabause/src/c68k/c68kexec.c +++ /dev/null @@ -1,335 +0,0 @@ -/* Copyright 2003-2004 Stephane Dallongeville - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "../core.h" -#include "c68k.h" - -// #define TRACE_WITH_Q68 // Define to use Q68 tracing code to trace insns - // (requires Q68 built in, of course) - -#ifdef NEOCD_HLE -void cdrom_load_files(void); -void neogeo_cdda_control(void); -void neogeo_prio_switch(void); -void neogeo_upload(void); -#endif - -// exception cycle table (taken from musashi core) -static const s32 c68k_exception_cycle_table[256] = -{ - 4, // 0: Reset - Initial Stack Pointer - 4, // 1: Reset - Initial Program Counter - 50, // 2: Bus Error - 50, // 3: Address Error - 34, // 4: Illegal Instruction - 38, // 5: Divide by Zero - 40, // 6: CHK - 34, // 7: TRAPV - 34, // 8: Privilege Violation - 34, // 9: Trace - 4, // 10: - 4, // 11: - 4, // 12: RESERVED - 4, // 13: Coprocessor Protocol Violation - 4, // 14: Format Error - 44, // 15: Uninitialized Interrupt - 4, // 16: RESERVED - 4, // 17: RESERVED - 4, // 18: RESERVED - 4, // 19: RESERVED - 4, // 20: RESERVED - 4, // 21: RESERVED - 4, // 22: RESERVED - 4, // 23: RESERVED - 44, // 24: Spurious Interrupt - 44, // 25: Level 1 Interrupt Autovector - 44, // 26: Level 2 Interrupt Autovector - 44, // 27: Level 3 Interrupt Autovector - 44, // 28: Level 4 Interrupt Autovector - 44, // 29: Level 5 Interrupt Autovector - 44, // 30: Level 6 Interrupt Autovector - 44, // 31: Level 7 Interrupt Autovector - 34, // 32: TRAP #0 - 34, // 33: TRAP #1 - 34, // 34: TRAP #2 - 34, // 35: TRAP #3 - 34, // 36: TRAP #4 - 34, // 37: TRAP #5 - 34, // 38: TRAP #6 - 34, // 39: TRAP #7 - 34, // 40: TRAP #8 - 34, // 41: TRAP #9 - 34, // 42: TRAP #10 - 34, // 43: TRAP #11 - 34, // 44: TRAP #12 - 34, // 45: TRAP #13 - 34, // 46: TRAP #14 - 34, // 47: TRAP #15 - 4, // 48: FP Branch or Set on Unknown Condition - 4, // 49: FP Inexact Result - 4, // 50: FP Divide by Zero - 4, // 51: FP Underflow - 4, // 52: FP Operand Error - 4, // 53: FP Overflow - 4, // 54: FP Signaling NAN - 4, // 55: FP Unimplemented Data Type - 4, // 56: MMU Configuration Error - 4, // 57: MMU Illegal Operation Error - 4, // 58: MMU Access Level Violation Error - 4, // 59: RESERVED - 4, // 60: RESERVED - 4, // 61: RESERVED - 4, // 62: RESERVED - 4, // 63: RESERVED - // 64-255: User Defined - 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 -}; - -// global variable -/////////////////// - -#ifndef C68K_GEN - -#ifndef C68K_NO_JUMP_TABLE -#ifndef C68K_CONST_JUMP_TABLE -static void *JumpTable[0x10000]; -#endif -#endif - -static u32 C68k_Initialised = 0; - -#endif // C68K_GEN - -#ifdef NEOCD_HLE -extern int img_display; -#endif - -// include macro file -////////////////////// - -#include "c68kmac.inc" - -#ifndef C68K_GEN -# ifdef TRACE_WITH_Q68 -#include "../q68/q68.h" -static c68k_struc *TRACE_CPU; -static uint32_t readw(uint32_t address) { - return TRACE_CPU->Read_Word(address); -} -/* Make our own version of the structure to avoid the overhead of dozens of - * function calls every instruction */ -static struct { - u32 D[8], A[8], PC, SR, USP, SSP, dummy[7]; - void *readb, *readw, *writeb, *writew; -} state = {.readw = readw}; -void TRACE(int PC,c68k_struc *CPU,int Opcode,int CCnt) { - static FILE *f; - if (!f) f = fopen("c68k.log", "w"); - TRACE_CPU = CPU; - memcpy(state.D, CPU->D, 16*4); - state.PC = PC - 2 - CPU->BasePC; - state.SR = GET_SR; - if (f) q68_trace((Q68State *)&state, f, - CPU->CycleToDo - CCnt, CPU->CycleToDo); -} -# endif // TRACE_WITH_Q68 -#endif // !C68K_GEN - -// main exec function -////////////////////// - -s32 FASTCALL C68k_Exec(c68k_struc *cpu, s32 cycle) -{ -#ifndef C68K_GEN -#if 0 - register c68k_struc *CPU asm ("ebx"); - register pointer PC asm ("esi"); - register s32 CCnt asm ("edi"); -// register u32 Opcode asm ("edi"); -// c68k_struc *CPU; -// u32 PC; -// s32 CCnt; - u32 Opcode; -#else -// register c68k_struc *CPU asm ("r10"); -// register u32 PC asm ("r11"); -// register s32 CCnt asm ("r12"); -// register u32 Opcode asm ("r13"); - c68k_struc *CPU; - pointer PC; - s32 CCnt; - u32 Opcode; -#endif -#endif - -#ifndef C68K_GEN - -#ifndef C68K_NO_JUMP_TABLE -#ifdef C68K_CONST_JUMP_TABLE - #include "c68k_ini.inc" -#endif -#else - C68k_Initialised = 1; -#endif - - CPU = cpu; - PC = CPU->PC; - - if (CPU->Status & (C68K_RUNNING | C68K_DISABLE | C68K_FAULTED)) - { -#ifndef C68K_NO_JUMP_TABLE -#ifndef C68K_CONST_JUMP_TABLE - if (!C68k_Initialised) goto C68k_Init; -#endif -#endif - return (CPU->Status | 0x80000000); - } - - if (cycle <= 0) return -cycle; - - CPU->CycleToDo = CCnt = cycle; - -#ifndef C68K_DEBUG - CHECK_INT -#else - { - s32 line, vect; - - line = CPU->IRQLine; - - if ((line == 7) || (line > CPU->flag_I)) - { - PRE_IO - - /* get vector */ - CPU->IRQLine = 0; - vect = CPU->Interrupt_CallBack(line); - if (vect == C68K_INT_ACK_AUTOVECTOR) - vect = C68K_INTERRUPT_AUTOVECTOR_EX + (line & 7); - - /* adjust CCnt */ - CCnt -= c68k_exception_cycle_table[vect]; - - /* swap A7 and USP */ - if (!CPU->flag_S) - { - u32 tmpSP; - - tmpSP = CPU->USP; - CPU->USP = CPU->A[7]; - CPU->A[7] = tmpSP; - } - - /* push PC and SR */ - PUSH_32_F(PC - CPU->BasePC) - PUSH_16_F(GET_SR) - - /* adjust SR */ - CPU->flag_S = C68K_SR_S; - CPU->flag_I = line; - - /* fetch new PC */ - READ_LONG_F(vect * 4, PC) - SET_PC(PC) - - POST_IO - } - } -#endif - - if (CPU->Status & (C68K_HALTED | C68K_WAITING)) return CPU->CycleToDo; - - CPU->CycleSup = 0; - CPU->Status |= C68K_RUNNING; - -#ifndef C68K_DEBUG - NEXT -#else -#ifdef C68K_NO_JUMP_TABLE - NEXT -#else - Opcode = FETCH_WORD; - PC += 2; - goto *JumpTable[Opcode]; -#endif -#endif - -#ifdef C68K_NO_JUMP_TABLE -SwitchTable: - switch(Opcode) - { -#endif - #include "c68k_op0.inc" - #include "c68k_op1.inc" - #include "c68k_op2.inc" - #include "c68k_op3.inc" - #include "c68k_op4.inc" - #include "c68k_op5.inc" - #include "c68k_op6.inc" - #include "c68k_op7.inc" - #include "c68k_op8.inc" - #include "c68k_op9.inc" - #include "c68k_opA.inc" - #include "c68k_opB.inc" - #include "c68k_opC.inc" - #include "c68k_opD.inc" - #include "c68k_opE.inc" - #include "c68k_opF.inc" -#ifdef C68K_NO_JUMP_TABLE - } -#endif - -C68k_Exec_End: - CHECK_INT - if ((CCnt += CPU->CycleSup) > 0) - { - CPU->CycleSup = 0; - NEXT; - } - -C68k_Exec_Really_End: - CPU->Status &= ~C68K_RUNNING; - CPU->PC = PC; - - return (CPU->CycleToDo - CCnt); - -#ifndef C68K_CONST_JUMP_TABLE -#ifndef C68K_NO_JUMP_TABLE -C68k_Init: - { - u32 i, j; - - #include "c68k_ini.inc" - - C68k_Initialised = 1; - } - - return 0; -#endif -#endif -#else - return 0; -#endif -} - diff --git a/yabause/src/c68k/c68kmac.inc b/yabause/src/c68k/c68kmac.inc deleted file mode 100644 index 25767be99b..0000000000 --- a/yabause/src/c68k/c68kmac.inc +++ /dev/null @@ -1,307 +0,0 @@ -/* Copyright 2003-2004 Stephane Dallongeville - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -// internals core macros -///////////////////////// - -#define LSL(A, C) ((A) << (C)) -#define LSR(A, C) ((A) >> (C)) - -#define LSR_32(A, C) ((C) < 32 ? (A) >> (C) : 0) -#define LSL_32(A, C) ((C) < 32 ? (A) << (C) : 0) - -#define ROL_8(A, C) (LSL(A, C) | LSR(A, 8-(C))) -#define ROL_9(A, C) (LSL(A, C) | LSR(A, 9-(C))) -#define ROL_16(A, C) (LSL(A, C) | LSR(A, 16-(C))) -#define ROL_17(A, C) (LSL(A, C) | LSR(A, 17-(C))) -#define ROL_32(A, C) (LSL_32(A, C) | LSR_32(A, 32-(C))) -#define ROL_33(A, C) (LSL_32(A, C) | LSR_32(A, 33-(C))) - -#define ROR_8(A, C) (LSR(A, C) | LSL(A, 8-(C))) -#define ROR_9(A, C) (LSR(A, C) | LSL(A, 9-(C))) -#define ROR_16(A, C) (LSR(A, C) | LSL(A, 16-(C))) -#define ROR_17(A, C) (LSR(A, C) | LSL(A, 17-(C))) -#define ROR_32(A, C) (LSR_32(A, C) | LSL_32(A, 32-(C))) -#define ROR_33(A, C) (LSR_32(A, C) | LSL_32(A, 33-(C))) - - -#ifdef TRACE_WITH_Q68 -extern void TRACE(int,c68k_struc*,int,int); -#else -# define TRACE(a,b,c,d) /*nothing*/ -#endif -#ifndef C68K_NO_JUMP_TABLE -#define NEXT \ - PRE_IO \ - Opcode = FETCH_WORD; \ - PC += 2; \ - TRACE(PC, CPU, Opcode, CCnt); \ - goto *JumpTable[Opcode]; -#else -#define NEXT \ - PRE_IO \ - Opcode = FETCH_WORD; \ - PC += 2; \ - TRACE(PC, CPU, Opcode, CCnt); \ - goto SwitchTable; -#endif - -#define RET(A) \ - CCnt -= (A); \ - if (CCnt <= 0) goto C68k_Exec_End; \ - NEXT - -#define SET_PC(A) \ - CPU->BasePC = CPU->Fetch[((A) >> C68K_FETCH_SFT) & C68K_FETCH_MASK]; \ - CPU->BasePC -= (A) & 0xFF000000; \ - PC = (A) + CPU->BasePC; - -#define PRE_IO \ - CPU->CycleIO = CCnt; - -#define POST_IO \ - CCnt = CPU->CycleIO; - -#define READ_BYTE_F(A, D) \ - D = CPU->Read_Byte(A) & 0xFF; - -#define READ_WORD_F(A, D) \ - D = CPU->Read_Word(A) & 0xFFFF; - -#ifdef C68K_BIG_ENDIAN - #define READ_LONG_F(A, D) \ - D = CPU->Read_Word((A)) << 16; \ - D |= CPU->Read_Word((A) + 2) & 0xFFFF; - - #define READ_LONG_DEC_F(A, D) \ - D = CPU->Read_Word((A) + 2) & 0xFFFF; \ - D |= CPU->Read_Word((A)) << 16; -#else - #define READ_LONG_F(A, D) \ - D = CPU->Read_Word((A)) << 16; \ - D |= CPU->Read_Word((A) + 2) & 0xFFFF; - - #define READ_LONG_DEC_F(A, D) \ - D = CPU->Read_Word((A) + 2) & 0xFFFF; \ - D |= CPU->Read_Word((A)) << 16; -#endif - -#define READSX_BYTE_F(A, D) \ - D = (s32)(s8)CPU->Read_Byte(A); - -#define READSX_WORD_F(A, D) \ - D = (s32)(s16)CPU->Read_Word(A); - -#ifdef C68K_BIG_ENDIAN - #define READSX_LONG_F(A, D) \ - D = CPU->Read_Word((A)) << 16; \ - D |= CPU->Read_Word((A) + 2) & 0xFFFF; - - #define READSX_LONG_DEC_F(A, D) \ - D = CPU->Read_Word((A) + 2) & 0xFFFF; \ - D |= CPU->Read_Word((A)) << 16; -#else - #define READSX_LONG_F(A, D) \ - D = CPU->Read_Word((A)) << 16; \ - D |= CPU->Read_Word((A) + 2) & 0xFFFF; - - #define READSX_LONG_DEC_F(A, D) \ - D = CPU->Read_Word((A) + 2) & 0xFFFF; \ - D |= CPU->Read_Word((A)) << 16; -#endif - -#define WRITE_BYTE_F(A, D) \ - CPU->Write_Byte(A, D); - -#define WRITE_WORD_F(A, D) \ - CPU->Write_Word(A, D); - -#ifdef C68K_BIG_ENDIAN - #define WRITE_LONG_F(A, D) \ - CPU->Write_Word((A), (D) >> 16); \ - CPU->Write_Word((A) + 2, (D) & 0xFFFF); - - #define WRITE_LONG_DEC_F(A, D) \ - CPU->Write_Word((A) + 2, (D) & 0xFFFF); \ - CPU->Write_Word((A), (D) >> 16); -#else - #define WRITE_LONG_F(A, D) \ - CPU->Write_Word((A), (D) >> 16); \ - CPU->Write_Word((A) + 2, (D) & 0xFFFF); - - #define WRITE_LONG_DEC_F(A, D) \ - CPU->Write_Word((A) + 2, (D) & 0xFFFF); \ - CPU->Write_Word((A), (D) >> 16); -#endif - -#define PUSH_16_F(D) \ - CPU->Write_Word(CPU->A[7] -= 2, D); \ - -#define POP_16_F(D) \ - D = (u16)CPU->Read_Word(CPU->A[7]); \ - CPU->A[7] += 2; - -#ifdef C68K_BIG_ENDIAN - #define PUSH_32_F(D) \ - CPU->A[7] -= 4; \ - CPU->Write_Word(CPU->A[7] + 2, (D) & 0xFFFF); \ - CPU->Write_Word(CPU->A[7], (D) >> 16); - - #define POP_32_F(D) \ - D = CPU->Read_Word(CPU->A[7]) << 16; \ - D |= CPU->Read_Word(CPU->A[7] + 2) & 0xFFFF; \ - CPU->A[7] += 4; -#else - #define PUSH_32_F(D) \ - CPU->A[7] -= 4; \ - CPU->Write_Word(CPU->A[7] + 2, (D) & 0xFFFF); \ - CPU->Write_Word(CPU->A[7], (D) >> 16); - - #define POP_32_F(D) \ - D = CPU->Read_Word(CPU->A[7]) << 16; \ - D |= CPU->Read_Word(CPU->A[7] + 2) & 0xFFFF; \ - CPU->A[7] += 4; -#endif - -#define FETCH_BYTE \ -((*(u16*)PC) & 0xFF) - -#define FETCH_WORD \ -(*(u16*)PC) - - -#define FETCH_LONG \ -(*(u32*)PC) - -#define DECODE_EXT_WORD \ -{ \ - u32 ext; \ - \ - ext = (*(u16*)PC); \ - PC += 2; \ - \ - adr += (s32)((s8)(ext)); \ - if (ext & 0x0800) adr += (s32) CPU->D[ext >> 12]; \ - else adr += (s32)((s16)(CPU->D[ext >> 12])); \ -} - -#ifndef C68K_BIG_ENDIAN -#ifdef C68K_BYTE_SWAP_OPT - #undef FETCH_LONG - #define FETCH_LONG \ - ((((u32)(*(u16*)PC)) << 16) | ((u32)(*(u16*)(PC + 2)))) -// ((((u32)(*(u8*)(PC + 2))) | (((u32)(*(u8*)(PC + 3))) << 8) | (((u32)(*(u8*)PC)) << 16) | (((u32)(*(u8*)(PC + 1))) << 24))) -#else - #undef FETCH_BYTE - #define FETCH_BYTE \ - (*(u16*)PC) >> 8) - - #undef FETCH_WORD - #define FETCH_WORD \ - ((((u16)(*(u8*)PC)) << 8) | ((u16)(*(u8*)(PC + 1)))) -// ((((u16)(*(u8*)(PC + 1))) | (((u16)(*(u8*)PC)) << 8))) - - #undef FETCH_LONG - #define FETCH_LONG \ - ((((u32)(*(u8*)PC)) << 24) | (((u32)(*(u8*)(PC + 1))) << 16) | (((u32)(*(u8*)(PC + 2))) << 8) | ((u32)(*(u8*)(PC + 3)))) -// ((((u32)(*(u8*)(PC + 3))) | (((u32)(*(u8*)(PC + 2))) << 8) | (((u32)(*(u8*)(PC + 1))) << 16) | (((u32)(*(u8*)PC)) << 24))) - - #undef DECODE_EXT_WORD - #define DECODE_EXT_WORD \ - { \ - u32 ext; \ - \ - ext = (*(u16*)PC); \ - PC += 2; \ - \ - adr += (s32)((s8)(ext >> 8)); \ - if (ext & 0x0008) adr += (s32) CPU->D[(ext >> 4) & 0x000F]; \ - else adr += (s32)((s16)(CPU->D[(ext >> 4) & 0x000F])); \ - } -#endif -#endif - -#define GET_CCR \ - (((CPU->flag_C >> (C68K_SR_C_SFT - 0)) & 1) | \ - ((CPU->flag_V >> (C68K_SR_V_SFT - 1)) & 2) | \ - (((!CPU->flag_notZ) & 1) << 2) | \ - ((CPU->flag_N >> (C68K_SR_N_SFT - 3)) & 8) | \ - ((CPU->flag_X >> (C68K_SR_X_SFT - 4)) & 0x10)) - -#define GET_SR \ - ((CPU->flag_S << 0) | \ - (CPU->flag_I << 8) | \ - GET_CCR) - -#define SET_CCR(A) \ - CPU->flag_C = (A) << (C68K_SR_C_SFT - 0); \ - CPU->flag_V = (A) << (C68K_SR_V_SFT - 1); \ - CPU->flag_notZ = ~(A) & 4; \ - CPU->flag_N = (A) << (C68K_SR_N_SFT - 3); \ - CPU->flag_X = (A) << (C68K_SR_X_SFT - 4); - -#define SET_SR(A) \ - SET_CCR(A) \ - CPU->flag_I = ((A) >> 8) & 7; \ - CPU->flag_S = (A) & C68K_SR_S; - -#define CHECK_INT \ - { \ - s32 line, vect; \ - \ - line = CPU->IRQLine; \ - \ - if ((line == 7) || (line > CPU->flag_I)) \ - { \ - /* get vector */ \ - CPU->IRQLine = 0; \ - vect = CPU->Interrupt_CallBack(line); \ - if (vect == C68K_INT_ACK_AUTOVECTOR) \ - vect = C68K_INTERRUPT_AUTOVECTOR_EX + (line & 7); \ - \ - /* adjust CCnt */ \ - CCnt -= c68k_exception_cycle_table[vect]; \ - \ - /* swap A7 and USP */ \ - if (!CPU->flag_S) \ - { \ - u32 tmpSP; \ - \ - tmpSP = CPU->USP; \ - CPU->USP = CPU->A[7]; \ - CPU->A[7] = tmpSP; \ - } \ - \ - PRE_IO \ - \ - /* push PC and SR */ \ - PUSH_32_F(PC - CPU->BasePC) \ - PUSH_16_F(GET_SR) \ - \ - /* adjust SR */ \ - CPU->flag_S = C68K_SR_S; \ - CPU->flag_I = line; \ - \ - /* fetch new PC */ \ - READ_LONG_F(vect * 4, PC) \ - SET_PC(PC) \ - \ - POST_IO \ - } \ - } diff --git a/yabause/src/c68k/configure.in b/yabause/src/c68k/configure.in deleted file mode 100644 index ed03d740a2..0000000000 --- a/yabause/src/c68k/configure.in +++ /dev/null @@ -1,18 +0,0 @@ -AC_INIT(gen68k, 0.9.10) - -AC_CANONICAL_HOST -AC_CANONICAL_TARGET - -AM_INIT_AUTOMAKE([1.8.0 foreign]) - -AC_PROG_CC - -AC_LANG(C) - -AC_C_BIGENDIAN - -AM_PROG_CC_C_O - -AC_CONFIG_FILES([Makefile]) - -AC_OUTPUT diff --git a/yabause/src/c68k/gen68k.c b/yabause/src/c68k/gen68k.c deleted file mode 100644 index 1a540598b4..0000000000 --- a/yabause/src/c68k/gen68k.c +++ /dev/null @@ -1,3820 +0,0 @@ -/* Copyright 2003-2004 Stephane Dallongeville - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/********************************************************************************* - * GEN68K.C : - * - * C68K generator source file - * - ********************************************************************************/ - -#include -#ifdef __WIN32__ -#include -#endif - -#include "../core.h" -#include "c68k.h" -#include "gen68k.h" - -#ifdef C68K_GEN - -#include "gen68k.inc" - -// to do : -// need accurate cycles calculations in MUL and DIV instruction -// some bugs to fix - -// opcode generation function -////////////////////////////// - -static void GenLogicI(char op) -{ - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES | GEN_SRC); - else - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - if (current_ea != EA_DREG) current_cycle += 4; - switch (current_size) - { - case SIZE_BYTE: - wf_op("\tsrc = FETCH_BYTE;\n"); - wf_op("\tPC += 2;\n"); - break; - - case SIZE_WORD: - wf_op("\tsrc = FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - break; - - case SIZE_LONG: - wf_op("\tsrc = FETCH_LONG;\n"); - wf_op("\tPC += 4;\n"); - current_cycle += 8; - break; - } - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // op - wf_op("\tres %c= src;\n", op); - // flag calculation - set_logic_flag(); - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenLogicICCR(char op) -{ - // generate jump table & opcode declaration - start_all(GEN_RES); - - wf_op("\tres = FETCH_BYTE & C68K_CCR_MASK;\n"); - wf_op("\tPC += 2;\n"); - wf_op("\tres %c= GET_CCR;\n", op); - wf_op("\tSET_CCR(res)\n"); - - terminate_op(20); -} - -static void GenLogicISR(char op) -{ - // generate jump table & opcode declaration - start_all(GEN_RES); - - wf_op("\tif (CPU->flag_S)\n"); - wf_op("\t{\n"); - wf_op("\t\tres = FETCH_WORD & C68K_SR_MASK;\n"); - wf_op("\t\tPC += 2;\n"); - wf_op("\t\tres %c= GET_SR;\n", op); - wf_op("\t\tSET_SR(res)\n"); - if (op != '|') - { - wf_op("\t\tif (!CPU->flag_S)\n"); - wf_op("\t\t{\n"); - wf_op("\t\t\tres = CPU->A[7];\n"); - wf_op("\t\t\tCPU->A[7] = CPU->USP;\n"); - wf_op("\t\t\tCPU->USP = res;\n"); - wf_op("\t\t}\n"); - } - wf_op("\t}\n"); - wf_op("\telse\n"); - wf_op("\t{\n"); - gen_privilege_exception("\t\t"); - wf_op("\t}\n"); - - // check for interrupt - fterminate_op(20); -} - -static void GenORI() -{ - GenLogicI('|'); -} - -static void GenORICCR() -{ - GenLogicICCR('|'); -} - -static void GenORISR() -{ - GenLogicISR('|'); -} - -static void GenANDI() -{ - GenLogicI('&'); -} - -static void GenANDICCR() -{ - GenLogicICCR('&'); -} - -static void GenANDISR() -{ - GenLogicISR('&'); -} - -static void GenEORI() -{ - GenLogicI('^'); -} - -static void GenEORICCR() -{ - GenLogicICCR('^'); -} - -static void GenEORISR() -{ - GenLogicISR('^'); -} - -static void GenArithI(char op) -{ - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES | GEN_SRC | GEN_DST); - else - start_all(GEN_ALL); - - if ((op != ' ') && (current_ea != EA_DREG)) current_cycle += 4; - switch (current_size) - { - case SIZE_BYTE: - wf_op("\tsrc = FETCH_BYTE;\n"); - wf_op("\tPC += 2;\n"); - break; - - case SIZE_WORD: - wf_op("\tsrc = FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - break; - - case SIZE_LONG: - wf_op("\tsrc = FETCH_LONG;\n"); - wf_op("\tPC += 4;\n"); - if (op == ' ') - { - if (current_ea == EA_DREG) current_cycle += 6; - else current_cycle += 4; - } else current_cycle += 8; - break; - } - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_dst(current_ea, current_op->reg_sft); - if (op == ' ') - { - // op - wf_op("\tres = dst - src;\n"); - // flag calculation - set_cmp_flag(); - } - else - { - // op - wf_op("\tres = dst %c src;\n", op); - // flag calculation - if (op == '+') set_add_flag(); - else set_sub_flag(); - // write - _ea_write(current_ea, current_op->reg_sft); - } - - terminate_op(8); -} - -static void GenSUBI() -{ - GenArithI('-'); -} - -static void GenADDI() -{ - GenArithI('+'); -} - -static void GenCMPI() -{ - GenArithI(' '); -} - -static void GenBitsOp(char op, u32 dyn) -{ - // generate jump table & opcode declaration - if (dyn) current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES | GEN_SRC); - else - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - if (current_ea == EA_DREG) - { - set_current_size(SIZE_LONG); - if ((op == 'c') || (op == ' ')) current_cycle += 2; - } - else set_current_size(SIZE_BYTE); - - // get shift value in src - if (dyn) - { - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_src(current_ea2, current_op->reg2_sft); - } - else - { - wf_op("\tsrc = FETCH_BYTE;\n"); - wf_op("\tPC += 2;\n"); - current_cycle += 4; - } - wf_op("\tsrc = 1 << (src & %d);\n", current_sft_mask); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // flag calculation - wf_op("\tCPU->flag_notZ = res & src;\n"); - // op - switch(op) - { - case 'c': - wf_op("\tres &= ~src;\n"); - break; - - case 'g': - wf_op("\tres ^= src;\n"); - break; - - case 's': - wf_op("\tres |= src;\n"); - break; - } - // write - if (op != ' ') - { - _ea_write(current_ea, current_op->reg_sft); - current_cycle += 4; - } - - terminate_op(4); -} - -static void GenBTSTn() -{ - GenBitsOp(' ', 0); -} - -static void GenBCHGn() -{ - GenBitsOp('g', 0); -} - -static void GenBCLRn() -{ - GenBitsOp('c', 0); -} - -static void GenBSETn() -{ - GenBitsOp('s', 0); -} - -static void GenBTST() -{ - GenBitsOp(' ', 1); -} - -static void GenBCHG() -{ - GenBitsOp('g', 1); -} - -static void GenBCLR() -{ - GenBitsOp('c', 1); -} - -static void GenBSET() -{ - GenBitsOp('s', 1); -} - -static void GenMOVEPWaD() -{ - // generate jump table & opcode declaration - current_ea = EA_D16A; - current_ea2 = EA_DREG; - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - set_current_size(SIZE_BYTE); - _ea_calc(current_ea, current_op->reg_sft); - mem_op("\tREAD_BYTE_F(adr + 0, res)\n"); - mem_op("\tREAD_BYTE_F(adr + 2, src)\n"); - // write - wf_op("\t*(u16*)(&CPU->D[(Opcode >> %d) & 7]) = (res << 8) | src;\n", current_op->reg2_sft); - - terminate_op(16); -} - -static void GenMOVEPLaD() -{ - // generate jump table & opcode declaration - current_ea = EA_D16A; - current_ea2 = EA_DREG; - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - set_current_size(SIZE_BYTE); - _ea_calc(EA_D16A, current_op->reg_sft); - mem_op("\tREAD_BYTE_F(adr, res)\n"); - wf_op("\tres <<= 24;\n"); - wf_op("\tadr += 2;\n"); - mem_op("\tREAD_BYTE_F(adr, src)\n"); - wf_op("\tres |= src << 16;\n"); - wf_op("\tadr += 2;\n"); - mem_op("\tREAD_BYTE_F(adr, src)\n"); - wf_op("\tres |= src << 8;\n"); - wf_op("\tadr += 2;\n"); - mem_op("\tREAD_BYTE_F(adr, src)\n"); - // write - wf_op("\tCPU->D[(Opcode >> %d) & 7] = res | src;\n", current_op->reg2_sft); - - terminate_op(24); -} - -static void GenMOVEPWDa() -{ - // generate jump table & opcode declaration - current_ea = EA_D16A; - current_ea2 = EA_DREG; - start_all(GEN_ADR | GEN_RES); - - // read - set_current_size(SIZE_LONG); - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read(current_ea2, current_op->reg2_sft); - // write - set_current_size(SIZE_BYTE); - _ea_calc(current_ea, current_op->reg_sft); - mem_op("\tWRITE_BYTE_F(adr + 0, res >> 8)\n"); - mem_op("\tWRITE_BYTE_F(adr + 2, res >> 0)\n"); - - terminate_op(16); -} - -static void GenMOVEPLDa() -{ - // generate jump table & opcode declaration - current_ea = EA_D16A; - current_ea2 = EA_DREG; - start_all(GEN_ADR | GEN_RES); - - // read - set_current_size(SIZE_LONG); - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read(current_ea2, current_op->reg2_sft); - // write - set_current_size(SIZE_BYTE); - _ea_calc(current_ea, current_op->reg_sft); - mem_op("\tWRITE_BYTE_F(adr, res >> 24)\n"); - wf_op("\tadr += 2;\n"); - mem_op("\tWRITE_BYTE_F(adr, res >> 16)\n"); - wf_op("\tadr += 2;\n"); - mem_op("\tWRITE_BYTE_F(adr, res >> 8)\n"); - wf_op("\tadr += 2;\n"); - mem_op("\tWRITE_BYTE_F(adr, res >> 0)\n"); - - terminate_op(24); -} - -static void GenMOVE(u32 size) -{ - set_current_size(size); - - // generate jump table & opcode declaration - if (((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) && - ((current_ea2 == EA_AREG) || (current_ea2 == EA_DREG) || (current_ea2 == EA_IMM))) - start_all(GEN_RES); - else - start_all(GEN_ADR | GEN_RES); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // flag calculation - set_logic_flag(); - if ((current_ea2 == EA_ADEC) || (current_ea2 == EA_ADEC7)) current_cycle -= 2; - // write - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(4); -} - -static void GenMOVEB() -{ - GenMOVE(SIZE_BYTE); -} - -static void GenMOVEW() -{ - GenMOVE(SIZE_WORD); -} - -static void GenMOVEL() -{ - GenMOVE(SIZE_LONG); -} - -static void GenMOVEA(u32 size) -{ - set_current_size(size); - - // generate jump table & opcode declaration - current_ea2 = EA_AREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES); - else - start_all(GEN_ADR | GEN_RES); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_sx(current_ea, current_op->reg_sft); - // write (dst = Ax) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(4); -} - -static void GenMOVEAW() -{ - GenMOVEA(SIZE_WORD); -} - -static void GenMOVEAL() -{ - GenMOVEA(SIZE_LONG); -} - -static void GenMOVEQ() -{ - u32 base = get_current_opcode_base(); - - // generate jump table - current_ea = EA_DREG; - gen_opjumptable_ext(base, 0x00, 0xFF, 1, base); - - // generate label & declarations - start_op(base, GEN_RES); - - // read - set_current_size(SIZE_BYTE); - wf_op("\tres = (s32)(s8)Opcode;\n"); - // fast flag calculation for moveQ - wf_op("\tCPU->flag_C = CPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_N = CPU->flag_notZ = res;\n"); - // write - set_current_size(SIZE_LONG); - _ea_calc(current_ea, current_op->reg_sft); - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(4); -} - -static void GenSingle(char op) -{ - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) { - if (op == 'c') - start_all(GEN_RES); - else - start_all(GEN_RES | GEN_SRC); - } else { - if (op == 'c') - start_all(GEN_ADR | GEN_RES); - else - start_all(GEN_ADR | GEN_RES | GEN_SRC); - } - - if (current_size == SIZE_LONG) current_cycle = 6; - else current_cycle= 4; - if (is_ea_memory(current_ea)) current_cycle *= 2; - - // read - _ea_calc(current_ea, current_op->reg_sft); - if (op != 'c') _ea_read_src(current_ea, current_op->reg_sft); - // op - switch (op) - { - case 'x': // negx - wf_op("\tres = -src - ((CPU->flag_X >> 8) & 1);\n"); - break; - - case 'g': // neg - wf_op("\tres = -src;\n"); - break; - - case 'n': // not - wf_op("\tres = ~src;\n"); - break; - - case 'c': // clr - wf_op("\tres = 0;\n"); - break; - } - // flag calculation - switch (op) - { - case 'x': // negx - set_negx_flag(); - break; - - case 'g': // neg - set_neg_flag(); - break; - - case 'n': // not - set_logicl_flag(); - break; - - case 'c': // clr - wf_op("\tCPU->flag_N = CPU->flag_notZ = CPU->flag_V = CPU->flag_C = 0;\n"); - break; - } - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(0); -} - -static void GenCLR() -{ - GenSingle('c'); -} - -static void GenNEGX() -{ - GenSingle('x'); -} - -static void GenNEG() -{ - GenSingle('g'); -} - -static void GenNOT() -{ - GenSingle('n'); -} - -static void GenMOVESRa() -{ - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES); - else - start_all(GEN_ADR | GEN_RES); - - // read - wf_op("\tres = GET_SR;\n"); - // write - set_current_size(SIZE_WORD); - if (is_ea_memory(current_ea)) current_cycle += 2; - _ea_calc(current_ea, current_op->reg_sft); - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenMOVEaSR() -{ - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES); - else - start_all(GEN_ADR | GEN_RES); - - wf_op("\tif (CPU->flag_S)\n"); - wf_op("\t{\n"); - // read - set_current_size(SIZE_WORD); - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - wf_op("\t\tSET_SR(res)\n"); - wf_op("\t\tif (!CPU->flag_S)\n"); - wf_op("\t\t{\n"); - wf_op("\t\t\tres = CPU->A[7];\n"); - wf_op("\t\t\tCPU->A[7] = CPU->USP;\n"); - wf_op("\t\t\tCPU->USP = res;\n"); - wf_op("\t\t}\n"); - wf_op("\t}\n"); - wf_op("\telse\n"); - wf_op("\t{\n"); - gen_privilege_exception("\t\t"); - wf_op("\t}\n"); - - // force terminaison to check for interrupt - fterminate_op(12); -} - -static void GenMOVEaCCR() -{ - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES); - else - start_all(GEN_ADR | GEN_RES); - - // read - set_current_size(SIZE_WORD); - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // write - wf_op("\tSET_CCR(res)\n"); - - terminate_op(12); -} - -static void GenMOVEAUSP() -{ - current_ea = EA_AREG; - - // generate jump table & opcode declaration - start_all(GEN_RES); - - wf_op("\tif (!CPU->flag_S)\n"); - wf_op("\t{\n"); - gen_privilege_exception("\t\t"); - quick_terminate_op(4); - wf_op("\t}\n"); - - // read - set_current_size(SIZE_LONG); - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // write - wf_op("\tCPU->USP = res;\n"); - - terminate_op(4); -} - -static void GenMOVEUSPA() -{ - current_ea = EA_AREG; - - // generate jump table & opcode declaration - start_all(GEN_RES); - - wf_op("\tif (!CPU->flag_S)\n"); - wf_op("\t{\n"); - gen_privilege_exception("\t\t"); - quick_terminate_op(4); - wf_op("\t}\n"); - - // read - wf_op("\tres = CPU->USP;\n"); - // write - set_current_size(SIZE_LONG); - _ea_calc(current_ea, current_op->reg_sft); - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(4); -} - -static void GenPEA() -{ - set_current_size(SIZE_LONG); - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(0); - else - start_all(GEN_ADR); - - _ea_calc_free(current_ea, current_op->reg_sft); - mem_op("\tPUSH_32_F(adr)\n"); - - terminate_op(lea_pea_cycle_table[current_ea] + 12); -} - -static void GenSWAP() -{ - current_ea = EA_DREG; - set_current_size(SIZE_LONG); - // generate jump table & opcode declaration - start_all(GEN_RES); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // op - wf_op("\tres = (res >> 16) | (res << 16);\n"); - // flag calculation - set_logic_flag(); - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(4); -} - -static void GenMOVEMaR() -{ - // generate jump table & opcode declaration - start_all(GEN_ALL); - - // get register mask - wf_op("\tres = FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - // get adr - if (current_ea == EA_AINC) wf_op("\tadr = CPU->A[(Opcode >> %d) & 7];\n", current_op->reg_sft); - else if (current_ea == EA_AINC7) wf_op("\tadr = CPU->A[7];\n"); - else _ea_calc(current_ea, current_op->reg_sft); - wf_op("\tsrc = (pointer)(&CPU->D[0]);\n"); - - wf_op("\tdst = adr;\n"); - do_pre_io(); - - wf_op("\tdo\n"); - wf_op("\t{\n"); - wf_op("\t\tif (res & 1)\n"); - wf_op("\t\t{\n"); - - if (current_size == SIZE_WORD) - { - wf_op("\t\t\tREADSX_WORD_F(adr, *(s32*)src)\n"); - wf_op("\t\t\tadr += 2;\n"); - } - else - { - wf_op("\t\t\tREAD_LONG_F(adr, *(u32*)src)\n"); - wf_op("\t\t\tadr += 4;\n"); - } - wf_op("\t\t}\n"); - wf_op("\t\tsrc += 4;\n"); - wf_op("\t} while (res >>= 1);\n"); - - if (current_ea == EA_AINC) wf_op("\tCPU->A[(Opcode >> %d) & 7] = adr;\n", current_op->reg_sft); - else if (current_ea == EA_AINC7) wf_op("\tCPU->A[7] = adr;\n"); - adds_CCnt("(adr - dst) * 2"); - - terminate_op(movem_cycle_table[current_ea] + 12); -} - -static void GenMOVEMRa() -{ - // generate jump table & opcode declaration - start_all(GEN_ALL); - - // get register mask - wf_op("\tres = FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - // get adr - if (current_ea == EA_ADEC) wf_op("\tadr = CPU->A[(Opcode >> %d) & 7];\n", current_op->reg_sft); - else if (current_ea == EA_ADEC7) wf_op("\tadr = CPU->A[7];\n"); - else _ea_calc(current_ea, current_op->reg_sft); - if ((current_ea == EA_ADEC) || (current_ea == EA_ADEC7)) wf_op("\tsrc = (pointer)(&CPU->A[7]);\n"); - else wf_op("\tsrc = (pointer)(&CPU->D[0]);\n"); - - wf_op("\tdst = adr;\n"); - do_pre_io(); - - wf_op("\tdo\n"); - wf_op("\t{\n"); - wf_op("\t\tif (res & 1)\n"); - wf_op("\t\t{\n"); - - if (current_size == SIZE_WORD) - { - if ((current_ea == EA_ADEC) || (current_ea == EA_ADEC7)) wf_op("\t\t\tadr -= 2;\n"); - wf_op("\t\t\tWRITE_WORD_F(adr, *(u16*)src)\n"); - if (!((current_ea == EA_ADEC) || (current_ea == EA_ADEC7))) wf_op("\t\t\tadr += 2;\n"); - } - else - { - if ((current_ea == EA_ADEC) || (current_ea == EA_ADEC7)) - { - wf_op("\t\t\tadr -= 4;\n"); - wf_op("\t\t\tWRITE_LONG_DEC_F(adr, *(u32*)src)\n"); - } - else - { - wf_op("\t\t\tWRITE_LONG_F(adr, *(u32*)src)\n"); - wf_op("\t\t\tadr += 4;\n"); - } - } - wf_op("\t\t}\n"); - if ((current_ea == EA_ADEC) || (current_ea == EA_ADEC7)) wf_op("\t\tsrc -= 4;\n"); - else wf_op("\t\tsrc += 4;\n"); - wf_op("\t} while (res >>= 1);\n"); - - if (current_ea == EA_ADEC) wf_op("\tCPU->A[(Opcode >> %d) & 7] = adr;\n", current_op->reg_sft); - else if (current_ea == EA_ADEC7) wf_op("\tCPU->A[7] = adr;\n"); - if ((current_ea == EA_ADEC) || (current_ea == EA_ADEC7)) adds_CCnt("(dst - adr) * 2"); - else adds_CCnt("(adr - dst) * 2"); - - terminate_op(movem_cycle_table[current_ea] + 8); -} - -static void GenEXT() -{ - current_ea = EA_DREG; - // generate jump table & opcode declaration - start_all(GEN_RES); - - // read - set_current_size(current_size - 1); - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_sx(current_ea, current_op->reg_sft); - // flag calculation - set_logic_flag(); - // write - set_current_size(current_size + 1); - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(4); -} - -static void GenTST() -{ - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES); - else - start_all(GEN_ADR | GEN_RES); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // flag calculation - set_logic_flag(); - - terminate_op(4); -} - -static void GenTAS() -{ - set_current_size(SIZE_BYTE); - - if (is_ea_memory(current_ea)) current_cycle += 6; - - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES); - else - start_all(GEN_ADR | GEN_RES); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // flag calculation - set_logic_flag(); -#ifndef C68K_TAS_CAN_SET_MEMORY - if (current_ea < EA_AIND) - { -#endif - // flag calculation - wf_op("\tres |= 0x80;\n"); - // write - _ea_write(current_ea, current_op->reg_sft); -#ifndef C68K_TAS_CAN_SET_MEMORY - } -#endif - - terminate_op(4); -} - -static void GenTRAP() -{ - u32 base; - - base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable_ext(base, (0 << 0), (15 << 0), (1 << 0), base); - - // generate label & declarations - start_op(base, GEN_RES); - - gen_exception("\t", "C68K_TRAP_BASE_EX + (Opcode & 0xF)"); - - terminate_op(4); -} - -static void GenTRAPV() -{ - // generate label & declarations - start_all(GEN_RES); - - wf_op("\tif %s\n", get_cond_as_cond(COND_VS, 0)); - wf_op("\t{\n"); - gen_exception("\t\t", "C68K_TRAPV_EX"); - wf_op("\t}\n"); - - terminate_op(4); -} - -static void GenLINK() -{ - current_ea = EA_AREG; - set_current_size(SIZE_LONG); - // generate jump table & opcode declaration - start_all(GEN_RES); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // push - mem_op("\tPUSH_32_F(res)\n"); - wf_op("\tres = CPU->A[7];\n"); - // write - _ea_write(current_ea, current_op->reg_sft); - // update SP - wf_op("\tCPU->A[7] += (s32)(s16)FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - - terminate_op(16); -} - -static void GenLINKA7() -{ - current_ea = EA_AREG; - set_current_size(SIZE_LONG); - // generate jump table & opcode declaration - start_all(0); - - // push A7 - wf_op("\tCPU->A[7] -= 4;\n"); - mem_op("\tWRITE_LONG_DEC_F(CPU->A[7], CPU->A[7])\n"); - // update A7 - wf_op("\tCPU->A[7] += (s32)(s16)FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - - terminate_op(16); -} - -static void GenULNK() -{ - current_ea = EA_AREG; - set_current_size(SIZE_LONG); - // generate jump table & opcode declaration - start_all(GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // pop - wf_op("\tCPU->A[7] = src + 4;\n"); - mem_op("\tREAD_LONG_F(src, res)\n"); - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(12); -} - -static void GenULNKA7() -{ - current_ea = EA_AREG; - set_current_size(SIZE_LONG); - // generate jump table & opcode declaration - start_all(0); - - mem_op("\tREAD_LONG_F(CPU->A[7], CPU->A[7])\n"); - - terminate_op(12); -} - -static void GenRESET() -{ - // generate jump table & opcode declaration - start_all(GEN_RES); - - wf_op("\tif (!CPU->flag_S)\n"); - wf_op("\t{\n"); - gen_privilege_exception("\t\t"); - quick_terminate_op(4); - wf_op("\t}\n"); - - // Reset callback function - mem_op("\tCPU->Reset_CallBack();\n"); - - terminate_op(132); -} - -static void GenLEA() -{ - current_ea2 = EA_AREG; - set_current_size(SIZE_LONG); - // generate jump table & opcode declaration - start_all(GEN_ADR | GEN_RES); - - _ea_calc_free(current_ea, current_op->reg_sft); - wf_op("\tres = adr;\n"); - current_cycle = lea_pea_cycle_table[current_ea]; - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(4); -} - -static void GenNOP() -{ - start_all(0); - terminate_op(4); -} - -static void GenILLEGAL() -{ - start_all(GEN_RES); - - gen_exception("\t\t", "C68K_ILLEGAL_INSTRUCTION_EX"); - - terminate_op(4); -} - -static void GenCHK() -{ - current_ea2 = EA_DREG; - set_current_size(SIZE_WORD); - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES | GEN_SRC); - else - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read Src - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read Dx - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read(current_ea2, current_op->reg2_sft); - - wf_op("\tif (((s32)res < 0) || (res > src))\n"); - wf_op("\t{\n"); - wf_op("\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - gen_exception("\t\t", "C68K_CHK_EX"); - wf_op("\t}\n"); - - terminate_op(10); -} - -static void GenSTOP() -{ - // generate jump table & opcode declaration - start_all(GEN_RES); - - wf_op("\tif (!CPU->flag_S)\n"); - wf_op("\t{\n"); - wf_op("\t\tPC += 2;\n"); - gen_privilege_exception("\t\t"); - quick_terminate_op(4); - wf_op("\t}\n"); - - // read & set SR - wf_op("\tres = FETCH_WORD & C68K_SR_MASK;\n"); - wf_op("\tPC += 2;\n"); - wf_op("\tSET_SR(res)\n"); - - // if S flag not set --> we swap stack pointer - wf_op("\tif (!CPU->flag_S)\n"); - wf_op("\t{\n"); - wf_op("\t\tres = CPU->A[7];\n"); - wf_op("\t\tCPU->A[7] = CPU->USP;\n"); - wf_op("\t\tCPU->USP = res;\n"); - wf_op("\t}\n"); - - wf_op("\tCPU->Status |= C68K_HALTED;\n"); - wf_op("\tCCnt = 0;\n"); - - // force end execution - fterminate_op(4); -} - -static void GenRTE() -{ - start_all(GEN_RES); - - wf_op("\tif (!CPU->flag_S)\n"); - wf_op("\t{\n"); - gen_privilege_exception("\t\t"); - quick_terminate_op(4); - wf_op("\t}\n"); - - // restore SR and PC - mem_op("\tPOP_16_F(res)\n"); - wf_op("\tSET_SR(res)\n"); - mem_op("\tPOP_32_F(res)\n"); - wf_op("\tSET_PC(res)\n"); - - // if S flag not set --> we swap stack pointer - wf_op("\tif (!CPU->flag_S)\n"); - wf_op("\t{\n"); - wf_op("\t\tres = CPU->A[7];\n"); - wf_op("\t\tCPU->A[7] = CPU->USP;\n"); - wf_op("\t\tCPU->USP = res;\n"); - wf_op("\t}\n"); - - // check for interrupt - fterminate_op(20); -} - -static void GenRTS() -{ - start_all(GEN_RES); - - mem_op("\tPOP_32_F(res)\n"); - wf_op("\tSET_PC(res)\n"); - - terminate_op(16); -} - -static void GenRTR() -{ - start_all(GEN_RES); - - mem_op("\tPOP_16_F(res)\n"); - wf_op("\tSET_CCR(res)\n"); - mem_op("\tPOP_32_F(res)\n"); - wf_op("\tSET_PC(res)\n"); - - terminate_op(20); -} - -static void GenJSR() -{ - start_all(GEN_ADR); - - // get adr - _ea_calc_free(current_ea, current_op->reg_sft); - mem_op("\tPUSH_32_F(PC - CPU->BasePC)\n"); - wf_op("\tSET_PC(adr)\n"); - - terminate_op(jmp_jsr_cycle_table[current_ea] + 12); -} - -static void GenJMP() -{ - start_all(GEN_ADR); - - // get adr - _ea_calc_free(current_ea, current_op->reg_sft); - wf_op("\tSET_PC(adr)\n"); - - terminate_op(jmp_jsr_cycle_table[current_ea] + 4); -} - -static void GenSTCC() -{ - u32 base, cond; - - base = get_current_opcode_base(); - - for(cond = 0; cond < 0x10; cond++) - { - // generate jump table - gen_opjumptable(base + (cond << 8)); - // generate label & declarations - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_op(base + (cond << 8), GEN_RES); - else - start_op(base + (cond << 8), GEN_ADR | GEN_RES); - - set_current_size(SIZE_BYTE); - - if (is_ea_memory(current_ea)) current_cycle += 4; - - // op - _ea_calc(current_ea, current_op->reg_sft); - if ((cond != COND_TR) && (cond != COND_FA)) - { - wf_op("\tif %s\n", get_cond_as_cond(cond, 0)); - wf_op("\t{\n"); - } - if (cond != COND_FA) - { - wf_op("\tres = 0xFF;\n"); - // write - _ea_write(current_ea, current_op->reg_sft); - if (!is_ea_memory(current_ea)) quick_terminate_op(6); - else quick_terminate_op(4); - } - if ((cond != COND_TR) && (cond != COND_FA)) - { - wf_op("\t}\n"); - } - if (cond != COND_TR) - { - wf_op("\tres = 0;\n"); - // write - _ea_write(current_ea, current_op->reg_sft); - quick_terminate_op(4); - } - - wf_op("}\n"); - } -} - -static void GenDBCC() -{ - u32 base, cond; - - base = get_current_opcode_base(); - - current_ea = EA_DREG; - set_current_size(SIZE_WORD); - - for(cond = 0; cond < 0x10; cond++) - { - // generate jump table - gen_opjumptable(base + (cond << 8)); - // generate label & declarations - start_op(base + (cond << 8), cond==COND_TR ? 0 : GEN_RES); - - if (cond != COND_TR) - { - if (cond != COND_FA) - { - wf_op("\tif %s\n", get_cond_as_cond(cond, 1)); - wf_op("\t{\n"); - } - - // read Dx - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // dec Dx - wf_op("\tres--;\n"); - // write Dx - _ea_write(current_ea, current_op->reg_sft); - wf_op("\tif ((s32)res != -1)\n"); - wf_op("\t{\n"); - wf_op("\t\tPC += (s32)(s16)FETCH_WORD;\n"); - // unbase PC - wf_op("\t\tPC -= CPU->BasePC;\n"); - // rebase PC - wf_op("\t\tSET_PC(PC);\n"); - quick_terminate_op(10); - wf_op("\t}\n"); - - if (cond != COND_FA) - { - wf_op("\t}\n"); - wf_op("\telse\n"); - wf_op("\t{\n"); - wf_op("\t\tPC += 2;\n"); - quick_terminate_op(12); - wf_op("\t}\n"); - } - } - - wf_op("\tPC += 2;\n"); - - if (cond == COND_TR) terminate_op(12); - else terminate_op(14); - } -} - -static void GenBCC() -{ - u32 base, cond; - - base = get_current_opcode_base(); - - for(cond = 2; cond < 0x10; cond++) - { - // generate jump table - gen_opjumptable_ext(base + (cond << 8), 0x01, 0xFF, 1, base + (cond << 8) + 0x01); - // generate label & declarations - start_op(base + (cond << 8) + 0x01, 0); - - // op - wf_op("\tif %s\n", get_cond_as_cond(cond, 0)); - wf_op("\t{\n"); - wf_op("\t\tPC += (s32)(s8)Opcode;\n"); // no rebase needed for 8 bits deplacement - add_CCnt(2); - wf_op("\t}\n"); - - terminate_op(8); - } -} - -static void GenBCC16() -{ - u32 base, cond; - - base = get_current_opcode_base(); - - for(cond = 2; cond < 0x10; cond++) - { - // generate jump table - gen_opjumptable(base + (cond << 8)); - // generate label & declarations - start_op(base + (cond << 8), 0); - - // op - wf_op("\tif %s\n", get_cond_as_cond(cond, 0)); - wf_op("\t{\n"); - wf_op("\t\tPC += (s32)(s16)FETCH_WORD;\n"); - // unbase PC - wf_op("\t\tPC -= CPU->BasePC;\n"); - // rebase PC - wf_op("\t\tSET_PC(PC);\n"); - quick_terminate_op(10); - wf_op("\t}\n"); - - wf_op("\tPC += 2;\n"); - - terminate_op(12); - } -} - -static void GenBRA() -{ - u32 base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable_ext(base, 0x01, 0xFF, 1, base + 0x01); - // generate label & declarations - start_op(base + 0x01, 0); - - wf_op("\tPC += (s32)(s8)Opcode;\n"); // no rebase needed for 8 bits deplacement - - terminate_op(10); -} - -static void GenBRA16() -{ - u32 base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable(base + 0x00); - // generate label & declarations - start_op(base + 0x00, 0); - - wf_op("\tPC += (s32)(s16)FETCH_WORD;\n"); - // unbase PC - wf_op("\tPC -= CPU->BasePC;\n"); - // rebase PC - wf_op("\tSET_PC(PC);\n"); - - terminate_op(10); -} - -static void GenBSR() -{ - u32 base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable_ext(base, 0x01, 0xFF, 1, base + 0x01); - // generate label & declarations - start_op(base + 0x01, 0); - - mem_op("\tPUSH_32_F(PC - CPU->BasePC)\n"); - wf_op("\tPC += (s32)(s8)Opcode;\n"); // no rebase needed for 8 bits deplacement - - terminate_op(18); -} - -static void GenBSR16() -{ - u32 base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable(base + 0x00); - // generate label & declarations - start_op(base + 0x00, GEN_RES); - - wf_op("\tres = (s32)(s16)FETCH_WORD;\n"); - // unbase PC - wf_op("\tPC -= CPU->BasePC;\n"); - mem_op("\tPUSH_32_F(PC + 2)\n"); - wf_op("\tPC += (s32) res;\n"); - // rebase PC for 16 bits deplacement - wf_op("\tSET_PC(PC);\n"); - - terminate_op(18); -} - -static void GenArithQ(char op) -{ - u32 base; - - if ((current_ea == EA_AREG) && (current_size == SIZE_BYTE)) return; - - base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable_ext(base, (0 << 9), (7 << 9), (1 << 9), base); - - // generate label & declarations - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_op(base, GEN_DST | GEN_RES | GEN_SRC); - else - start_op(base, GEN_ALL); - - if (current_ea == EA_AREG) set_current_size(SIZE_LONG); - - if (is_ea_memory(current_ea)) current_cycle += 4; - if (current_size == SIZE_LONG) current_cycle += 4; - - // read src - wf_op("\tsrc = (((Opcode >> 9) - 1) & 7) + 1;\n"); - // read dst - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_dst(current_ea, current_op->reg_sft); - // op - wf_op("\tres = dst %c src;\n", op); - // flag calculation - if (current_ea != EA_AREG) - { - if (op == '+') set_add_flag(); - else set_sub_flag(); - } - // write dst - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(4); -} - -static void GenADDQ() -{ - GenArithQ('+'); -} - -static void GenSUBQ() -{ - GenArithQ('-'); -} - -static void GenLogicaD(char op) -{ - // generate jump table & opcode declaration - current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES | GEN_SRC); - else - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) - { - if (!is_ea_memory(current_ea)) current_cycle += 2; - else current_cycle += 4; - } - - // read src - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read(current_ea2, current_op->reg2_sft); - // op - wf_op("\tres %c= src;\n", op); - // flag calculation - set_logic_flag(); - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(4); -} - -static void GenLogicDa(char op) -{ - // generate jump table & opcode declaration - current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES | GEN_SRC); - else - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 4; - - // read src (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_src(current_ea2, current_op->reg2_sft); - // read dst - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // op - wf_op("\tres %c= src;\n", op); - // flag calculation - set_logic_flag(); - // write dst - _ea_write(current_ea, current_op->reg_sft); - - if (current_ea == EA_DREG) terminate_op(4); - else terminate_op(8); -} - -static void GenANDaD() -{ - GenLogicaD('&'); -} - -static void GenANDDa() -{ - GenLogicDa('&'); -} - -static void GenORaD() -{ - GenLogicaD('|'); -} - -static void GenORDa() -{ - GenLogicDa('|'); -} - -static void GenEORDa() -{ - GenLogicDa('^'); -} - -static void GenNBCD() -{ - set_current_size(SIZE_BYTE); - - // generate jump table & opcode declaration - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES); - else - start_all(GEN_ADR | GEN_RES); - - if (is_ea_memory(current_ea)) current_cycle += 2; - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - - // op - wf_op("\tres = 0x9a - res - ((CPU->flag_X >> C68K_SR_X_SFT) & 1);\n"); - wf_op("\n"); - wf_op("\tif (res != 0x9a)\n"); - wf_op("\t{\n"); - wf_op("\t\tif ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10;\n"); - wf_op("\t\tres &= 0xFF;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - // flag calculation - wf_op("\t\tCPU->flag_notZ |= res;\n"); - wf_op("\t\tCPU->flag_X = CPU->flag_C = C68K_SR_C;\n"); - - wf_op("\t}\n"); - wf_op("\telse CPU->flag_X = CPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_N = res;\n"); - - terminate_op(6); -} - -static void GenBCD(char op) -{ - // op - wf_op("\tres = (dst & 0xF) %c (src & 0xF) %c ((CPU->flag_X >> C68K_SR_X_SFT) & 1);\n", op, op); - wf_op("\tif (res > 9) res %c= 6;\n", op); - wf_op("\tres += (dst & 0xF0) %c (src & 0xF0);\n", op, op); - - // flag calculation - wf_op("\tif (res > 0x99)\n"); - wf_op("\t{\n"); - switch (op) - { - case '+': - wf_op("\t\tres -= 0xA0;\n"); - break; - - case '-': - wf_op("\t\tres += 0xA0;\n"); - break; - } - wf_op("\t\tCPU->flag_X = CPU->flag_C = C68K_SR_C;\n"); - wf_op("\t}\n"); - wf_op("\telse CPU->flag_X = CPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_notZ |= res & 0xFF;\n"); - wf_op("\tCPU->flag_N = res;\n"); -} - -static void GenxBCD(char op) -{ - set_current_size(SIZE_BYTE); - - // generate jump table & opcode declaration - current_ea = EA_DREG; - current_ea2 = EA_DREG; - start_all(GEN_DST | GEN_RES | GEN_SRC); - - // read src (Dx) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - - // op & flag calculation - GenBCD(op); - - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(6); -} - -static void GenxBCDM(char op) -{ - set_current_size(SIZE_BYTE); - - // generate jump table & opcode declaration - current_ea = EA_ADEC; - current_ea2 = EA_ADEC; - start_all(GEN_ALL); - - // read src (ADEC) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (ADEC) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - - // op & flag calculation - GenBCD(op); - - // write dst (ADEC) - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(6); -} - -static void GenxBCD7M(char op) -{ - set_current_size(SIZE_BYTE); - - // generate jump table & opcode declaration - current_ea = EA_ADEC7; - current_ea2 = EA_ADEC; - start_all(GEN_ALL); - - // read src (ADEC7) - _ea_calc(current_ea, 0); - _ea_read_src(current_ea, 0); - // read dst (ADEC) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - - // op & flag calculation - GenBCD(op); - - // write dst (ADEC) - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(6); -} - -static void GenxBCDM7(char op) -{ - set_current_size(SIZE_BYTE); - - // generate jump table & opcode declaration - current_ea = EA_ADEC; - current_ea2 = EA_ADEC7; - start_all(GEN_ALL); - - // read src (ADEC) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (ADEC7) - _ea_calc(current_ea2, 0); - _ea_read_dst(current_ea2, 0); - - // op & flag calculation - GenBCD(op); - - // write dst (ADEC7) - _ea_write(current_ea2, 0); - - terminate_op(6); -} - -static void GenxBCD7M7(char op) -{ - set_current_size(SIZE_BYTE); - - // generate jump table & opcode declaration - current_ea = EA_ADEC7; - current_ea2 = EA_ADEC7; - start_all(GEN_ALL); - - // read src (ADEC7) - _ea_calc(current_ea, 0); - _ea_read_src(current_ea, 0); - // read dst (ADEC7) - _ea_calc(current_ea2, 0); - _ea_read_dst(current_ea2, 0); - - // op & flag calculation - GenBCD(op); - - // write dst (ADEC7) - _ea_write(current_ea2, 0); - - terminate_op(6); -} - -static void GenABCD() -{ - GenxBCD('+'); -} - -static void GenABCDM() -{ - GenxBCDM('+'); -} - -static void GenABCD7M() -{ - GenxBCD7M('+'); -} - -static void GenABCDM7() -{ - GenxBCDM7('+'); -} - -static void GenABCD7M7() -{ - GenxBCD7M7('+'); -} - -static void GenSBCD() -{ - GenxBCD('-'); -} - -static void GenSBCDM() -{ - GenxBCDM('-'); -} - -static void GenSBCD7M() -{ - GenxBCD7M('-'); -} - -static void GenSBCDM7() -{ - GenxBCDM7('-'); -} - -static void GenSBCD7M7() -{ - GenxBCD7M7('-'); -} - -static void GenDIVU() -{ - // generate jump table & opcode declaration - current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_DST | GEN_RES | GEN_SRC); - else - start_all(GEN_ALL); - - set_current_size(SIZE_WORD); - - // read src - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // division by zero - wf_op("\tif (src == 0)\n"); - wf_op("\t{\n"); - gen_exception("\t\t", "C68K_ZERO_DIVIDE_EX"); - quick_terminate_op(10); - wf_op("\t}\n"); - - set_current_size(SIZE_LONG); - - // read dst (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - - wf_op("\t{\n"); - wf_op("\t\tu32 q, r;\n"); - wf_op("\n"); - wf_op("\t\tq = dst / src;\n"); - wf_op("\t\tr = dst %% src;\n"); - wf_op("\n"); - - wf_op("\t\tif (q & 0xFFFF0000)\n"); - wf_op("\t\t{\n"); - // overflow occured - wf_op("\t\t\tCPU->flag_V = C68K_SR_V;\n"); - quick_terminate_op(70); - wf_op("\t\t}\n"); - - // quotient size = word - set_current_size(SIZE_WORD); - - wf_op("\t\tq &= 0x%.8X;\n", current_bits_mask); - wf_op("\t\tCPU->flag_notZ = q;\n"); - wf_op("\t\tCPU->flag_N = q >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\t\tCPU->flag_V = CPU->flag_C = 0;\n"); - - wf_op("\t\tres = q | (r << 16);\n"); - - set_current_size(SIZE_LONG); - - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - wf_op("\t}\n"); - - // max cycle = 140 - terminate_op(140 - 50); -} - -static void GenDIVS() -{ - // generate jump table & opcode declaration - current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_DST | GEN_RES | GEN_SRC); - else - start_all(GEN_ALL); - - set_current_size(SIZE_WORD); - - // read src - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src_sx(current_ea, current_op->reg_sft); - - // division by zero - wf_op("\tif (src == 0)\n"); - wf_op("\t{\n"); - gen_exception("\t\t", "C68K_ZERO_DIVIDE_EX"); - quick_terminate_op(10); - wf_op("\t}\n"); - - set_current_size(SIZE_LONG); - - // read dst (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - - // division by zero - wf_op("\tif ((dst == 0x80000000) && (src == -1))\n"); - wf_op("\t{\n"); - wf_op("\t\tCPU->flag_notZ = CPU->flag_N = 0;\n"); - wf_op("\t\tCPU->flag_V = CPU->flag_C = 0;\n"); - wf_op("\t\tres = 0;\n"); - - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - - quick_terminate_op(50); - wf_op("\t}\n"); - - wf_op("\t{\n"); - wf_op("\t\ts32 q, r;\n"); - wf_op("\n"); - wf_op("\t\tq = (s32)dst / (s32)src;\n"); - wf_op("\t\tr = (s32)dst %% (s32)src;\n"); - wf_op("\n"); - - wf_op("\t\tif ((q > 0x7FFF) || (q < -0x8000))\n"); - wf_op("\t\t{\n"); - // overflow occured - wf_op("\t\t\tCPU->flag_V = C68K_SR_V;\n"); - quick_terminate_op(80); - wf_op("\t\t}\n"); - - // quotient size = word - set_current_size(SIZE_WORD); - - wf_op("\t\tq &= 0x%.8X;\n", current_bits_mask); - wf_op("\t\tCPU->flag_notZ = q;\n"); - wf_op("\t\tCPU->flag_N = q >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\t\tCPU->flag_V = CPU->flag_C = 0;\n"); - - wf_op("\t\tres = q | (r << 16);\n"); - - set_current_size(SIZE_LONG); - - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - wf_op("\t}\n"); - - // max cycle = 158 - terminate_op(158 - 50); -} - -static void GenMULU() -{ - // generate jump table & opcode declaration - current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES | GEN_SRC); - else - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - set_current_size(SIZE_WORD); - - // read src - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read(current_ea2, current_op->reg2_sft); - - set_current_size(SIZE_LONG); - // op - wf_op("\tres *= src;\n"); - - // flag calculation - wf_op("\tCPU->flag_N = res >> 24;\n"); - wf_op("\tCPU->flag_notZ = res;\n"); - wf_op("\tCPU->flag_V = CPU->flag_C = 0;\n"); - - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - - // min cycle = 38; max cycle = 70 - terminate_op(38 + (2 * 6)); -} - -static void GenMULS() -{ - // generate jump table & opcode declaration - current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_RES | GEN_SRC); - else - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - set_current_size(SIZE_WORD); - // read src signed - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src_sx(current_ea, current_op->reg_sft); - // read dst signed (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_sx(current_ea2, current_op->reg2_sft); - - set_current_size(SIZE_LONG); - // op - //wf_op("\t(s32)res *= (s32)src;\n"); - wf_op("\tres *= (s32)src;\n"); // antime fix - - // flag calculation - wf_op("\tCPU->flag_N = res >> 24;\n"); - wf_op("\tCPU->flag_notZ = res;\n"); - wf_op("\tCPU->flag_V = CPU->flag_C = 0;\n"); - - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - - // min cycle = 38; max cycle = 70 - terminate_op(38 + (2 * 6)); -} - -static void GenArithaD(char op) -{ - // generate jump table & opcode declaration - current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_DST | GEN_RES | GEN_SRC); - else - start_all(GEN_ALL); - - if (current_size == SIZE_LONG) - { - if (!is_ea_memory(current_ea)) current_cycle += 2; - else current_cycle += 4; - } - - // read src - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - if (op == ' ') - { - // op - wf_op("\tres = dst - src;\n"); - // flag calculation - set_cmp_flag(); - } - else - { - // op - wf_op("\tres = dst %c src;\n", op); - // flag calculation - if (op == '+') set_add_flag(); - else set_sub_flag(); - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - } - - terminate_op(4); -} - -static void GenArithDa(char op) -{ - // generate jump table & opcode declaration - current_ea2 = EA_DREG; - start_all(GEN_ALL); - - if (current_size == SIZE_LONG) current_cycle += 4; - - // read src (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_src(current_ea2, current_op->reg2_sft); - // read dst - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_dst(current_ea, current_op->reg_sft); - // op - wf_op("\tres = dst %c src;\n", op); - // flag calculation - if (op == '+') set_add_flag(); - else set_sub_flag(); - // write dst - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenArithA(char op) -{ - // generate jump table & opcode declaration - current_ea2 = EA_AREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_DST | GEN_RES | GEN_SRC); - else - start_all(GEN_ALL); - - if ((op != ' ') && ((current_size == SIZE_WORD) || (is_ea_memory(current_ea)))) current_cycle += 2; - - // read src - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src_sx(current_ea, current_op->reg_sft); - // read dst (Ax) - set_current_size(SIZE_LONG); - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - // op - if (op == ' ') - { - // op - wf_op("\tres = dst - src;\n"); - // flag calculation - set_cmp_flag(); - } - else - { - // op - wf_op("\tres = dst %c src;\n", op); - // write dst (Ax) - _ea_write(current_ea2, current_op->reg2_sft); - } - - terminate_op(6); -} - -static void GenArithX(char op) -{ - // generate jump table & opcode declaration - current_ea = EA_DREG; - current_ea2 = EA_DREG; - if ((current_ea == EA_AREG) || (current_ea == EA_DREG) || (current_ea == EA_IMM)) - start_all(GEN_DST | GEN_RES | GEN_SRC); - else - start_all(GEN_ALL); - - if (current_size == SIZE_LONG) current_cycle += 4; - - // read src (Dx) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (Dx) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - // op - wf_op("\tres = dst %c src %c ((CPU->flag_X >> 8) & 1);\n", op, op); - // flag calculation - if (op == '+') set_addx_flag(); - else set_subx_flag(); - // write dst (Dx) - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(4); -} - -static void GenArithXM(char op) -{ - // generate jump table & opcode declaration - current_ea = EA_ADEC; - current_ea2 = EA_ADEC; - start_all(GEN_ALL); - - if (current_size == SIZE_LONG) current_cycle += 4; - - // read src (ADEC) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (ADEC) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - // op - wf_op("\tres = dst %c src %c ((CPU->flag_X >> 8) & 1);\n", op, op); - // flag calculation - if (op == '+') set_addx_flag(); - else set_subx_flag(); - // write dst (ADEC) - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(6); -} - -static void GenArithX7M(char op) -{ - // generate jump table & opcode declaration - current_ea = EA_ADEC7; - current_ea2 = EA_ADEC; - start_all(GEN_ALL); - - if (current_size == SIZE_LONG) current_cycle += 4; - - // read src (ADEC7) - _ea_calc(current_ea, 0); - _ea_read_src(current_ea, 0); - // read dst (ADEC) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - // op - wf_op("\tres = dst %c src %c ((CPU->flag_X >> 8) & 1);\n", op, op); - // flag calculation - if (op == '+') set_addx_flag(); - else set_subx_flag(); - // write dst (ADEC) - _ea_write(current_ea2, current_op->reg2_sft); - - terminate_op(6); -} - -static void GenArithXM7(char op) -{ - // generate jump table & opcode declaration - current_ea = EA_ADEC; - current_ea2 = EA_ADEC7; - start_all(GEN_ALL); - - if (current_size == SIZE_LONG) current_cycle += 4; - - // read src (ADEC) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (ADEC7) - _ea_calc(current_ea2, 0); - _ea_read_dst(current_ea2, 0); - // op - wf_op("\tres = dst %c src %c ((CPU->flag_X >> 8) & 1);\n", op, op); - // flag calculation - if (op == '+') set_addx_flag(); - else set_subx_flag(); - // write dst (ADEC7) - _ea_write(current_ea2, 0); - - terminate_op(6); -} - -static void GenArithX7M7(char op) -{ - // generate jump table & opcode declaration - current_ea = EA_ADEC7; - current_ea2 = EA_ADEC7; - start_all(GEN_ALL); - - if (current_size == SIZE_LONG) current_cycle += 4; - - // read src (ADEC7) - _ea_calc(current_ea, 0); - _ea_read_src(current_ea, 0); - // read dst (ADEC7) - _ea_calc(current_ea2, 0); - _ea_read_dst(current_ea2, 0); - // op - wf_op("\tres = dst %c src %c ((CPU->flag_X >> 8) & 1);\n", op, op); - // flag calculation - if (op == '+') set_addx_flag(); - else set_subx_flag(); - // write dst (ADEC7) - _ea_write(current_ea2, 0); - - terminate_op(6); -} - -static void GenADDaD() -{ - GenArithaD('+'); -} - -static void GenADDDa() -{ - GenArithDa('+'); -} - -static void GenADDA() -{ - GenArithA('+'); -} - -static void GenADDX() -{ - GenArithX('+'); -} - -static void GenADDXM() -{ - GenArithXM('+'); -} - -static void GenADDX7M() -{ - GenArithX7M('+'); -} - -static void GenADDXM7() -{ - GenArithXM7('+'); -} - -static void GenADDX7M7() -{ - GenArithX7M7('+'); -} - -static void GenSUBaD() -{ - GenArithaD('-'); -} - -static void GenSUBDa() -{ - GenArithDa('-'); -} - -static void GenSUBA() -{ - GenArithA('-'); -} - -static void GenSUBX() -{ - GenArithX('-'); -} - -static void GenSUBXM() -{ - GenArithXM('-'); -} - -static void GenSUBX7M() -{ - GenArithX7M('-'); -} - -static void GenSUBXM7() -{ - GenArithXM7('-'); -} - -static void GenSUBX7M7() -{ - GenArithX7M7('-'); -} - -static void GenCMP() -{ - GenArithaD(' '); -} - -static void GenCMPA() -{ - GenArithA(' '); -} - -static void GenCMPM() -{ - // generate jump table & opcode declaration - current_ea = EA_AINC; - current_ea2 = EA_AINC; - start_all(GEN_ALL); - - // read src (ADEC) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (ADEC) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - // op - wf_op("\tres = dst - src;\n"); - // flag calculation - set_cmp_flag(); - - terminate_op(4); - -} - -static void GenCMP7M() -{ - // generate jump table & opcode declaration - current_ea = EA_AINC7; - current_ea2 = EA_AINC; - start_all(GEN_ALL); - - // read src (ADEC) - _ea_calc(current_ea, 0); - _ea_read_src(current_ea, 0); - // read dst (ADEC) - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_dst(current_ea2, current_op->reg2_sft); - // op - wf_op("\tres = dst - src;\n"); - // flag calculation - set_cmp_flag(); - - terminate_op(4); - -} - -static void GenCMPM7() -{ - // generate jump table & opcode declaration - current_ea = EA_AINC; - current_ea2 = EA_AINC7; - start_all(GEN_ALL); - - // read src (ADEC) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - // read dst (ADEC) - _ea_calc(current_ea2, 0); - _ea_read_dst(current_ea2, 0); - // op - wf_op("\tres = dst - src;\n"); - // flag calculation - set_cmp_flag(); - - terminate_op(4); - -} - -static void GenCMP7M7() -{ - // generate jump table & opcode declaration - current_ea = EA_AINC7; - current_ea2 = EA_AINC7; - start_all(GEN_ALL); - - // read src (ADEC) - _ea_calc(current_ea, 0); - _ea_read_src(current_ea, 0); - // read dst (ADEC) - _ea_calc(current_ea2, 0); - _ea_read_dst(current_ea2, 0); - // op - wf_op("\tres = dst - src;\n"); - // flag calculation - set_cmp_flag(); - - terminate_op(4); - -} - -static void GenEXGDD() -{ - // generate jump table & opcode declaration - set_current_size(SIZE_LONG); - current_ea = EA_DREG; - current_ea2 = EA_DREG; - start_all(GEN_RES | GEN_SRC); - - // read R1 - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // read R2 - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_src(current_ea2, current_op->reg2_sft); - // write R1 - _ea_write(current_ea2, current_op->reg2_sft); - wf_op("\tres = src;\n"); - // write R2 - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenEXGAA() -{ - // generate jump table & opcode declaration - set_current_size(SIZE_LONG); - current_ea = EA_AREG; - current_ea2 = EA_AREG; - start_all(GEN_RES | GEN_SRC); - - // read R1 - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // read R2 - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_src(current_ea2, current_op->reg2_sft); - // write R1 - _ea_write(current_ea2, current_op->reg2_sft); - wf_op("\tres = src;\n"); - // write R2 - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenEXGAD() -{ - // generate jump table & opcode declaration - set_current_size(SIZE_LONG); - current_ea = EA_AREG; - current_ea2 = EA_DREG; - start_all(GEN_RES | GEN_SRC); - - // read R1 - _ea_calc(current_ea, current_op->reg_sft); - _ea_read(current_ea, current_op->reg_sft); - // read R2 - _ea_calc(current_ea2, current_op->reg2_sft); - _ea_read_src(current_ea2, current_op->reg2_sft); - // write R1 - _ea_write(current_ea2, current_op->reg2_sft); - wf_op("\tres = src;\n"); - // write R2 - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenASRk() -{ - u32 base; - - current_ea = EA_DREG; // dst = Dx - - base = get_current_opcode_base(); - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0E00, 0x0200, base); - // generate label & declarations - start_op(base, GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = (((Opcode >> 9) - 1) & 7) + 1;\n"); - adds_CCnt("sft * 2"); - - // read (sign extend) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src_sx(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft);\n"); - wf_op("\tres = ((s32)src) >> sft;\n"); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenLSRk() -{ - u32 base; - - current_ea = EA_DREG; // dst = Dx - - base = get_current_opcode_base(); - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0E00, 0x0200, base); - // generate label & declarations - start_op(base, GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = (((Opcode >> 9) - 1) & 7) + 1;\n"); - adds_CCnt("sft * 2"); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_N = CPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft);\n"); - wf_op("\tres = src >> sft;\n"); - wf_op("\tCPU->flag_notZ = res;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenROXRk() -{ - u32 base; - - current_ea = EA_DREG; // dst = Dx - - base = get_current_opcode_base(); - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0E00, 0x0200, base); - // generate label & declarations - start_op(base, GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = (((Opcode >> 9) - 1) & 7) + 1;\n"); - adds_CCnt("sft * 2"); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & C / X flags calculation - if (current_size != SIZE_LONG) - { - wf_op("\tsrc |= (CPU->flag_X & C68K_SR_X) << %d;\n", (current_sft_mask + 1) - C68K_SR_X_SFT); - wf_op("\tres = (src >> sft) | (src << (%d - sft));\n", current_sft_mask + 2); - wf_op("\tCPU->flag_X = CPU->flag_C = res >> %d;\n", (current_sft_mask + 1) - C68K_SR_X_SFT); - } - else - { - wf_op("\tCPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft);\n"); - wf_op("\tif (sft == 1) res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << (32 - (C68K_SR_X_SFT + 1)));\n"); - wf_op("\telse res = (src >> sft) | (src << (33 - sft)) | ((CPU->flag_X & C68K_SR_X) << (32 - (C68K_SR_X_SFT + sft)));\n"); - wf_op("\tCPU->flag_X = CPU->flag_C;\n"); - } - - // V / N / Z flags calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - if (current_size == SIZE_LONG) wf_op("\tCPU->flag_notZ = res;\n"); - else wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenRORk() -{ - u32 base; - - current_ea = EA_DREG; // dst = Dx - - base = get_current_opcode_base(); - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0E00, 0x0200, base); - // generate label & declarations - start_op(base, GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = (((Opcode >> 9) - 1) & 7) + 1;\n"); - adds_CCnt("sft * 2"); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft);\n"); - wf_op("\tres = (src >> sft) | (src << (%d - sft));\n", current_sft_mask + 1); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - if (current_size == SIZE_LONG) wf_op("\tCPU->flag_notZ = res;\n"); - else wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenASLk() -{ - u32 base; - - current_ea = EA_DREG; // dst = Dx - - base = get_current_opcode_base(); - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0E00, 0x0200, base); - // generate label & declarations - start_op(base, GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = (((Opcode >> 9) - 1) & 7) + 1;\n"); - adds_CCnt("sft * 2"); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // if (shift < size op) ... only for BYTE here - if (current_size == SIZE_BYTE) - { - wf_op("\tif (sft < %d)\n", current_sft_mask + 1); - wf_op("\t{\n"); - } - - // op & flag X, C, N, Z calculation - if (((current_sft_mask + 1) - C68K_SR_C_SFT) < 8) - wf_op("\t\tCPU->flag_X = CPU->flag_C = src << (%d + sft);\n", current_sft_mask + 1 - C68K_SR_C_SFT); - else wf_op("\t\tCPU->flag_X = CPU->flag_C = src >> (%d - sft);\n", current_sft_mask + 1 - C68K_SR_C_SFT); - wf_op("\t\tres = src << sft;\n"); - wf_op("\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\t\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - // we do V flag calculation at end for a better register usage - wf_op("\t\tCPU->flag_V = 0;\n"); - if (current_size == SIZE_BYTE) - { - wf_op("\t\tif ((sft > %d) && (src)) CPU->flag_V = C68K_SR_V;\n", current_sft_mask); - wf_op("\t\telse\n"); - } - wf_op("\t\t{\n"); - wf_op("\t\t\tu32 msk = (((s32)0x80000000) >> (sft + %d)) & 0x%.8X;\n", 31 - current_sft_mask, current_bits_mask); - wf_op("\t\t\tsrc &= msk;\n"); - wf_op("\t\t\tif ((src) && (src != msk)) CPU->flag_V = C68K_SR_V;\n"); - wf_op("\t\t}\n"); - - if (current_size == SIZE_BYTE) - { - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of shift == size op (sft = 8 for byte operation) - wf_op("\tif (src) CPU->flag_V = C68K_SR_V;\n"); - wf_op("\telse CPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT;\n"); - - // write - wf_op("\tres = 0;\n"); - _ea_write(current_ea, current_op->reg_sft); - - // others flags - wf_op("\tCPU->flag_N = 0;\n"); - wf_op("\tCPU->flag_notZ = 0;\n"); - } - - terminate_op(6); -} - -static void GenLSLk() -{ - u32 base; - - current_ea = EA_DREG; // dst = Dx - - base = get_current_opcode_base(); - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0E00, 0x0200, base); - // generate label & declarations - start_op(base, GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = (((Opcode >> 9) - 1) & 7) + 1;\n"); - adds_CCnt("sft * 2"); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - if (((current_sft_mask + 1) - C68K_SR_C_SFT) < 8) - wf_op("\tCPU->flag_X = CPU->flag_C = src << (%d + sft);\n", current_sft_mask + 1 - C68K_SR_C_SFT); - else wf_op("\tCPU->flag_X = CPU->flag_C = src >> (%d - sft);\n", current_sft_mask + 1 - C68K_SR_C_SFT); - wf_op("\tres = src << sft;\n"); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenROXLk() -{ - u32 base; - - current_ea = EA_DREG; // dst = Dx - - base = get_current_opcode_base(); - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0E00, 0x0200, base); - // generate label & declarations - start_op(base, GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = (((Opcode >> 9) - 1) & 7) + 1;\n"); - adds_CCnt("sft * 2"); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & C / X flags calculation - if (current_size != SIZE_LONG) - { - wf_op("\tsrc |= (CPU->flag_X & C68K_SR_X) << %d;\n", (current_sft_mask + 1) - C68K_SR_X_SFT); - wf_op("\tres = (src << sft) | (src >> (%d - sft));\n", current_sft_mask + 2); - wf_op("\tCPU->flag_X = CPU->flag_C = res >> %d;\n", (current_sft_mask + 1) - C68K_SR_X_SFT); - } - else - { - wf_op("\tCPU->flag_C = src >> ((32 - C68K_SR_C_SFT) - sft);\n"); - wf_op("\tif (sft == 1) res = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> ((C68K_SR_X_SFT + 1) - 1));\n"); - wf_op("\telse res = (src << sft) | (src >> (33 - sft)) | ((CPU->flag_X & C68K_SR_X) >> ((C68K_SR_X_SFT + 1) - sft));\n"); - wf_op("\tCPU->flag_X = CPU->flag_C;\n"); - } - - // V / N / Z flags calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - if (current_size == SIZE_LONG) wf_op("\tCPU->flag_notZ = res;\n"); - else wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenROLk() -{ - u32 base; - - current_ea = EA_DREG; // dst = Dx - - base = get_current_opcode_base(); - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0E00, 0x0200, base); - // generate label & declarations - start_op(base, GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = (((Opcode >> 9) - 1) & 7) + 1;\n"); - adds_CCnt("sft * 2"); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - if (((current_sft_mask + 1) - C68K_SR_C_SFT) < 8) - wf_op("\tCPU->flag_C = src << (%d + sft);\n", current_sft_mask + 1 - C68K_SR_C_SFT); - else wf_op("\tCPU->flag_C = src >> (%d - sft);\n", current_sft_mask + 1 - C68K_SR_C_SFT); - wf_op("\tres = (src << sft) | (src >> (%d - sft));\n", current_sft_mask + 1); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - if (current_size == SIZE_LONG) wf_op("\tCPU->flag_notZ = res;\n"); - else wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(6); -} - -static void GenASRD() -{ -// u32 base = get_current_opcode_base(); - - current_ea = EA_DREG; // dst = Dx - - start_all(GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = CPU->D[(Opcode >> %d) & 7] & 0x3F;\n", current_op->reg2_sft); - - // read (sign extend) - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src_sx(current_ea, current_op->reg_sft); - - // if (shift != 0) - wf_op("\tif (sft)\n"); - wf_op("\t{\n"); - - adds_CCnt("sft * 2"); - - // if (shift < size op) - wf_op("\t\tif (sft < %d)\n", current_sft_mask + 1); - wf_op("\t\t{\n"); - - // op & flag calculation - wf_op("\t\t\tCPU->flag_V = 0;\n"); - if (current_size == SIZE_BYTE) wf_op("\t\t\tCPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft);\n"); - else wf_op("\t\t\tCPU->flag_X = CPU->flag_C = (src >> (sft - 1)) << C68K_SR_C_SFT;\n"); - wf_op("\t\t\tres = ((s32)src) >> sft;\n", szcs); - wf_op("\t\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\t\t\tCPU->flag_notZ = res;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t\t}\n"); - wf_op("\n"); - - // special case of shift >= size op - - // if signed - wf_op("\t\tif (src & (1 << %d))\n", current_sft_mask); - wf_op("\t\t{\n"); - - // op & flag calculation - wf_op("\t\t\tCPU->flag_N = C68K_SR_N;\n"); - wf_op("\t\t\tCPU->flag_notZ = 1;\n"); - wf_op("\t\t\tCPU->flag_V = 0;\n"); - wf_op("\t\t\tCPU->flag_C = C68K_SR_C;\n"); - wf_op("\t\t\tCPU->flag_X = C68K_SR_X;\n"); - wf_op("\t\t\tres = 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t\t}\n"); - wf_op("\n"); - - // if not signed - wf_op("\t\tCPU->flag_N = 0;\n"); - wf_op("\t\tCPU->flag_notZ = 0;\n"); - wf_op("\t\tCPU->flag_V = 0;\n"); - wf_op("\t\tCPU->flag_C = 0;\n"); - wf_op("\t\tCPU->flag_X = 0;\n"); - wf_op("\t\tres = 0;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of (shift == 0) - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = src;\n"); - - terminate_op(6); -} - -static void GenLSRD() -{ -// u32 base = get_current_opcode_base(); - - current_ea = EA_DREG; // dst = Dx - - start_all(GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = CPU->D[(Opcode >> %d) & 7] & 0x3F;\n", current_op->reg2_sft); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // if (shift != 0) - wf_op("\tif (sft)\n"); - wf_op("\t{\n"); - - adds_CCnt("sft * 2"); - - // if (shift <= size op) - if (current_size == SIZE_LONG) wf_op("\t\tif (sft < 32)\n"); - else wf_op("\t\tif (sft <= %d)\n", current_sft_mask + 1); - wf_op("\t\t{\n"); - - // op & flag calculation - wf_op("\t\t\tCPU->flag_N = CPU->flag_V = 0;\n"); - if (current_size == SIZE_BYTE) wf_op("\t\t\tCPU->flag_X = CPU->flag_C = src << ((C68K_SR_C_SFT + 1) - sft);\n"); - else wf_op("\t\t\tCPU->flag_X = CPU->flag_C = (src >> (sft - 1)) << C68K_SR_C_SFT;\n"); - wf_op("\t\t\tres = src >> sft;\n", szcs); - wf_op("\t\t\tCPU->flag_notZ = res;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t\t}\n"); - wf_op("\n"); - - // special case of shift > size op - if (current_size == SIZE_LONG) - { - wf_op("\t\tif (sft == 32) CPU->flag_C = src >> (31 - C68K_SR_C_SFT);\n"); - wf_op("\t\telse CPU->flag_C = 0;\n"); - wf_op("\t\tCPU->flag_X = CPU->flag_C;\n"); - } - else wf_op("\t\tCPU->flag_X = CPU->flag_C = 0;\n"); - wf_op("\t\tCPU->flag_N = 0;\n"); - wf_op("\t\tCPU->flag_notZ = 0;\n"); - wf_op("\t\tCPU->flag_V = 0;\n"); - wf_op("\t\tres = 0;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of (shift == 0) - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = src;\n"); - - terminate_op(6); -} - -static void GenROXRD() -{ -// u32 base = get_current_opcode_base(); - - current_ea = EA_DREG; // dst = Dx - - start_all(GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = CPU->D[(Opcode >> %d) & 7] & 0x3F;\n", current_op->reg2_sft); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // if (shift != 0) - wf_op("\tif (sft)\n"); - wf_op("\t{\n"); - - adds_CCnt("sft * 2"); - - wf_op("\t\tsft %%= %d;\n", current_sft_mask + 2); - wf_op("\n"); - - // op & C / X flag calculation - if (current_size != SIZE_LONG) - { - wf_op("\t\tsrc |= (CPU->flag_X & C68K_SR_X) << %d;\n", (current_sft_mask + 1) - C68K_SR_X_SFT); - wf_op("\t\tres = (src >> sft) | (src << (%d - sft));\n", current_sft_mask + 2); - wf_op("\t\tCPU->flag_X = CPU->flag_C = res >> %d;\n", (current_sft_mask + 1) - C68K_SR_X_SFT); - } - else - { - wf_op("\t\tif (sft != 0)\n"); - wf_op("\t\t{\n"); - wf_op("\t\t\tif (sft == 1) res = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << (32 - (C68K_SR_X_SFT + 1)));\n"); - wf_op("\t\t\telse res = (src >> sft) | (src << (33 - sft)) | (((CPU->flag_X & C68K_SR_X) << (32 - (C68K_SR_X_SFT + 1))) >> (sft - 1));\n"); - wf_op("\t\t\tCPU->flag_X = (src >> (32 - sft)) << C68K_SR_X_SFT;\n"); - wf_op("\t\t}\n"); - wf_op("\t\telse res = src;\n"); - wf_op("\t\tCPU->flag_C = CPU->flag_X;\n"); - } - - // V / N / Z flag calculation - wf_op("\t\tCPU->flag_V = 0;\n"); - wf_op("\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - if (current_size == SIZE_LONG) wf_op("\t\tCPU->flag_notZ = res;\n"); - else wf_op("\t\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of (shift == 0) - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = CPU->flag_X;\n"); - wf_op("\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = src;\n"); - - terminate_op(6); -} - -static void GenRORD() -{ -// u32 base = get_current_opcode_base(); - - current_ea = EA_DREG; // dst = Dx - - start_all(GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = CPU->D[(Opcode >> %d) & 7] & 0x3F;\n", current_op->reg2_sft); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // if (shift != 0) - wf_op("\tif (sft)\n"); - wf_op("\t{\n"); - - adds_CCnt("sft * 2"); - - wf_op("\t\tsft &= 0x%.2X;\n", current_sft_mask); - wf_op("\t\t\n"); - - // op & flag calculation - if (current_size == SIZE_BYTE) - wf_op("\t\tCPU->flag_C = src << (C68K_SR_C_SFT - ((sft - 1) & 7));\n"); - else - wf_op("\t\tCPU->flag_C = (src >> ((sft - 1) & %d)) << C68K_SR_C_SFT;\n", current_sft_mask); - wf_op("\t\tres = (src >> sft) | (src << (%d - sft));\n", current_sft_mask + 1); - wf_op("\t\tCPU->flag_V = 0;\n"); - wf_op("\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - if (current_size == SIZE_LONG) wf_op("\t\tCPU->flag_notZ = res;\n"); - else wf_op("\t\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of (shift == 0) - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = src;\n"); - - terminate_op(6); -} - -static void GenASLD() -{ -// u32 base = get_current_opcode_base(); - - current_ea = EA_DREG; // dst = Dx - - start_all(GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = CPU->D[(Opcode >> %d) & 7] & 0x3F;\n", current_op->reg2_sft); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // if (shift != 0) - wf_op("\tif (sft)\n"); - wf_op("\t{\n"); - - adds_CCnt("sft * 2"); - - // if (shift < size op) - wf_op("\t\tif (sft < %d)\n", current_sft_mask + 1); - wf_op("\t\t{\n"); - - // op & flag calculation - if (current_size != SIZE_LONG) - { - wf_op("\t\t\tCPU->flag_X = CPU->flag_C = (src << sft) >> %d;\n", (current_sft_mask + 1) - C68K_SR_C_SFT); - wf_op("\t\t\tres = (src << sft) & 0x%.8X;\n", current_bits_mask); - } - else - { - wf_op("\t\t\tCPU->flag_X = CPU->flag_C = (src >> (32 - sft)) << C68K_SR_C_SFT;\n"); - wf_op("\t\t\tres = src << sft;\n"); - } - wf_op("\t\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\t\t\tCPU->flag_notZ = res;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - // we do V flag calculation at end for a better register usage - wf_op("\t\t\tCPU->flag_V = 0;\n"); - wf_op("\t\t\t{\n"); - wf_op("\t\t\t\tu32 msk = (((s32)0x80000000) >> (sft + %d)) & 0x%.8X;\n", 31 - current_sft_mask, current_bits_mask); - wf_op("\t\t\t\tsrc &= msk;\n"); - wf_op("\t\t\t\tif ((src) && (src != msk)) CPU->flag_V = C68K_SR_V;\n"); - wf_op("\t\t\t}\n"); - - quick_terminate_op(6); - wf_op("\t\t}\n"); - wf_op("\n"); - - // special case of shift >= size op - wf_op("\t\tif (sft == %d) CPU->flag_C = src << C68K_SR_C_SFT;\n", current_bits_mask + 1); - wf_op("\t\telse CPU->flag_C = 0;\n"); - wf_op("\t\tCPU->flag_X = CPU->flag_C;\n"); - wf_op("\t\tif (src) CPU->flag_V = C68K_SR_V;\n"); - wf_op("\t\telse CPU->flag_V = 0;\n"); - - wf_op("\t\tres = 0;\n"); - // write - _ea_write(current_ea, current_op->reg_sft); - - // others flags - wf_op("\t\tCPU->flag_N = 0;\n"); - wf_op("\t\tCPU->flag_notZ = 0;\n"); - - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of (shift == 0) - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = src;\n"); - - terminate_op(6); -} - -static void GenLSLD() -{ -// u32 base = get_current_opcode_base(); - - current_ea = EA_DREG; // dst = Dx - - start_all(GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = CPU->D[(Opcode >> %d) & 7] & 0x3F;\n", current_op->reg2_sft); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // if (shift != 0) - wf_op("\tif (sft)\n"); - wf_op("\t{\n"); - - adds_CCnt("sft * 2"); - - // if (shift <= size op) - if (current_size == SIZE_LONG) wf_op("\t\tif (sft < 32)\n"); - else wf_op("\t\tif (sft <= %d)\n", current_sft_mask + 1); - wf_op("\t\t{\n"); - - // op & flag calculation - if (current_size != SIZE_LONG) - { - wf_op("\t\t\tCPU->flag_X = CPU->flag_C = (src << sft) >> %d;\n", (current_sft_mask + 1) - C68K_SR_C_SFT); - wf_op("\t\t\tres = (src << sft) & 0x%.8X;\n", current_bits_mask); - } - else - { - wf_op("\t\t\tCPU->flag_X = CPU->flag_C = (src >> (32 - sft)) << C68K_SR_C_SFT;\n"); - wf_op("\t\t\tres = src << sft;\n"); - } - wf_op("\t\t\tCPU->flag_V = 0;\n"); - wf_op("\t\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\t\t\tCPU->flag_notZ = res;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t\t}\n"); - wf_op("\n"); - - // special case of shift > size op - if (current_size == SIZE_LONG) - { - wf_op("\t\tif (sft == 32) CPU->flag_C = src << C68K_SR_C_SFT;\n"); - wf_op("\t\telse CPU->flag_C = 0;\n"); - wf_op("\t\tCPU->flag_X = CPU->flag_C;\n"); - } - else wf_op("\t\tCPU->flag_X = CPU->flag_C = 0;\n"); - wf_op("\t\tCPU->flag_N = 0;\n"); - wf_op("\t\tCPU->flag_notZ = 0;\n"); - wf_op("\t\tCPU->flag_V = 0;\n"); - wf_op("\t\tres = 0;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of (shift == 0) - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = src;\n"); - - terminate_op(6); -} - -static void GenROXLD() -{ -// u32 base = get_current_opcode_base(); - - current_ea = EA_DREG; // dst = Dx - - start_all(GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = CPU->D[(Opcode >> %d) & 7] & 0x3F;\n", current_op->reg2_sft); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // if (shift != 0) - wf_op("\tif (sft)\n"); - wf_op("\t{\n"); - - adds_CCnt("sft * 2"); - - wf_op("\t\tsft %%= %d;\n", current_sft_mask + 2); - wf_op("\n"); - - // op & C/X flags calculation - if (current_size != SIZE_LONG) - { - wf_op("\t\tsrc |= (CPU->flag_X & C68K_SR_X) << %d;\n", (current_sft_mask + 1) - C68K_SR_X_SFT); - wf_op("\t\tres = (src << sft) | (src >> (%d - sft));\n", current_sft_mask + 2); - wf_op("\t\tCPU->flag_X = CPU->flag_C = res >> %d;\n", (current_sft_mask + 1) - C68K_SR_X_SFT); - } - else - { - wf_op("\t\tif (sft != 0)\n"); - wf_op("\t\t{\n"); - wf_op("\t\t\tif (sft == 1) res = (src << 1) | ((CPU->flag_X >> ((C68K_SR_X_SFT + 1) - 1)) & 1);\n"); - wf_op("\t\t\telse res = (src << sft) | (src >> (33 - sft)) | (((CPU->flag_X >> ((C68K_SR_X_SFT + 1) - 1)) & 1) << (sft - 1));\n"); - wf_op("\t\t\tCPU->flag_X = (src >> (32 - sft)) << C68K_SR_X_SFT;\n"); - wf_op("\t\t}\n"); - wf_op("\t\telse res = src;\n"); - wf_op("\t\tCPU->flag_C = CPU->flag_X;\n"); - } - - // V / N / Z flags calculation - wf_op("\t\tCPU->flag_V = 0;\n"); - wf_op("\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - if (current_size == SIZE_LONG) wf_op("\t\tCPU->flag_notZ = res;\n"); - else wf_op("\t\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of (shift == 0) - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = CPU->flag_X;\n"); - wf_op("\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = src;\n"); - - terminate_op(6); -} - -static void GenROLD() -{ -// u32 base = get_current_opcode_base(); - - current_ea = EA_DREG; // dst = Dx - - start_all(GEN_RES | GEN_SRC); - - if (current_size == SIZE_LONG) current_cycle += 2; - - wf_op("\tu32 sft;\n"); - wf_op("\n"); - wf_op("\tsft = CPU->D[(Opcode >> %d) & 7] & 0x3F;\n", current_op->reg2_sft); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // if (shift != 0) - wf_op("\tif (sft)\n"); - wf_op("\t{\n"); - - adds_CCnt("sft * 2"); - - // if ((shift & size op) != 0) - wf_op("\t\tif (sft &= 0x%.2X)\n", current_sft_mask); - wf_op("\t\t{\n"); - - // op & flag calculation - if (current_size != SIZE_LONG) - { - wf_op("\t\t\tCPU->flag_C = (src << sft) >> %d;\n", (current_sft_mask + 1) - C68K_SR_C_SFT); - wf_op("\t\t\tres = ((src << sft) | (src >> (%d - sft))) & 0x%.8X;\n", current_sft_mask + 1, current_bits_mask); - } - else - { - wf_op("\t\t\tCPU->flag_C = (src >> (32 - sft)) << C68K_SR_C_SFT;\n"); - wf_op("\t\t\tres = (src << sft) | (src >> (%d - sft));\n", current_sft_mask + 1); - } - wf_op("\t\t\tCPU->flag_V = 0;\n"); - wf_op("\t\t\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\t\t\tCPU->flag_notZ = res;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - quick_terminate_op(6); - wf_op("\t\t}\n"); - wf_op("\n"); - - // special case of ((shift & size op) == 0) - wf_op("\t\tCPU->flag_V = 0;\n"); - wf_op("\t\tCPU->flag_C = src << C68K_SR_C_SFT;\n"); - wf_op("\t\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\t\tCPU->flag_notZ = src;\n"); - - quick_terminate_op(6); - wf_op("\t}\n"); - wf_op("\n"); - - // special case of (shift == 0) - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_N = src >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = src;\n"); - - terminate_op(6); -} - -static void GenASR() -{ - set_current_size(SIZE_WORD); // dst = mem (word operation) - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT;\n"); - wf_op("\tres = (src >> 1) | (src & (1 << %d));\n", current_sft_mask); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenLSR() -{ - set_current_size(SIZE_WORD); // dst = mem (word operation) - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_N = CPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = src << C68K_SR_C_SFT;\n"); - wf_op("\tres = src >> 1;\n"); - wf_op("\tCPU->flag_notZ = res;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenROXR() -{ - set_current_size(SIZE_WORD); // dst = mem (word operation) - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tres = (src >> 1) | ((CPU->flag_X & C68K_SR_X) << %d);\n", current_sft_mask - C68K_SR_X_SFT); - wf_op("\tCPU->flag_C = CPU->flag_X = src << C68K_SR_C_SFT;\n"); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res;\n"); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenROR() -{ - set_current_size(SIZE_WORD); // dst = mem (word operation) - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = src << C68K_SR_C_SFT;\n"); - wf_op("\tres = (src >> 1) | (src << %d);\n", current_sft_mask); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenASL() -{ - set_current_size(SIZE_WORD); // dst = mem (word operation) - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_X = CPU->flag_C = src >> %d;\n", current_sft_mask - C68K_SR_C_SFT); - wf_op("\tres = src << 1;\n"); - wf_op("\tCPU->flag_V = (src ^ res) >> %d;\n", current_sft_mask - C68K_SR_V_SFT); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenLSL() -{ - set_current_size(SIZE_WORD); // dst = mem (word operation) - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = src >> %d;\n", current_sft_mask - C68K_SR_C_SFT); - wf_op("\tres = src << 1;\n"); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenROXL() -{ - set_current_size(SIZE_WORD); // dst = mem (word operation) - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tres = (src << 1) | ((CPU->flag_X & C68K_SR_X) >> %d);\n", C68K_SR_X_SFT); - wf_op("\tCPU->flag_X = CPU->flag_C = src >> %d;\n", current_sft_mask - C68K_SR_C_SFT); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void GenROL() -{ - set_current_size(SIZE_WORD); // dst = mem (word operation) - start_all(GEN_ADR | GEN_RES | GEN_SRC); - - // read - _ea_calc(current_ea, current_op->reg_sft); - _ea_read_src(current_ea, current_op->reg_sft); - - // op & flag calculation - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_C = src >> %d;\n", current_sft_mask - C68K_SR_C_SFT); - wf_op("\tres = (src << 1) | (src >> %d);\n", current_sft_mask); - wf_op("\tCPU->flag_N = res >> %d;\n", current_sft_mask - C68K_SR_N_SFT); - wf_op("\tCPU->flag_notZ = res & 0x%.8X;\n", current_bits_mask); - - // write - _ea_write(current_ea, current_op->reg_sft); - - terminate_op(8); -} - -static void Gen1010() -{ - u32 base; - base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0FFF, 0x1, base); - - // generate label & declarations - start_op(base, GEN_RES); - wf_op("\tPC -= 2;\n"); - gen_exception("\t", "C68K_1010_EX"); - terminate_op(4); -} - -static void Gen1111() -{ - u32 base; - base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable_ext(base, 0x0000, 0x0FFF, 0x1, base); - - // generate label & declarations - start_op(base, GEN_RES); - wf_op("\tPC -= 2;\n"); - gen_exception("\t", "C68K_1111_EX"); - terminate_op(4); -} - -#ifdef NEOCD_HLE -static void Gen0xFABE() -{ - start_all(GEN_ALL); - - wf_op("\tneogeo_exit();\n"); - - terminate_op(0); -} - -static void Gen0xFABF() -{ - start_all(GEN_ALL); - - wf_op("\timg_display = 1;\n"); - wf_op("\tcdrom_load_files();\n"); - - terminate_op(0); -} - -static void Gen0xFAC0() -{ - start_all(GEN_ALL); - - wf_op("\timg_display = 0;\n"); - wf_op("\tcdrom_load_files();\n"); - - terminate_op(0); -} - -static void Gen0xFAC1() -{ - start_all(GEN_ALL); - - wf_op("\tneogeo_upload();\n"); - - terminate_op(0); -} - -static void Gen0xFAC2() -{ - start_all(GEN_ALL); - - wf_op("\tneogeo_prio_switch();\n"); - - terminate_op(0); -} - -static void Gen0xFAC3() -{ - start_all(GEN_ALL); - - wf_op("\tneogeo_cdda_control();\n"); - - terminate_op(0); -} -#endif - - -// main function -///////////////// -int main(void) -{ - u32 i; - u32 s; - u32 smax; - - // clear opcode files - for(i = 0; i < 0x10; i++) - { - char fn[16]; - - sprintf(fn, "c68k_op%.1X.inc", (int)i); - opcode_file = fopen(fn, "wt"); - if (opcode_file != NULL) - { - fclose(opcode_file); - opcode_file = NULL; - } - } - - // init opcode jump table - ini_file = fopen("c68k_ini.inc", "wt"); -#ifndef C68K_NO_JUMP_TABLE -#ifdef C68K_CONST_JUMP_TABLE - for(i = 0; i < 0x10000; i++) op_jump_table[i] = OP_ILLEGAL; -#else - // defaut ILLEGAL instruction - gen_jumptable(0x0000, 0x0000, 0xFFFF, 1, 0, 0, 0, 0, 0, 0, 0x4AFC); -#endif -#endif - // generate opcode files - for(i = 0; i < OP_INFO_TABLE_LEN; i++) - { - current_op = &(op_info_table[i]); - if (prepare_generate()) return 1; - - // s = size to start - current_size = 0; - smax = SIZE_LONG; - if (current_op->size_type == 0) smax = 0; - else if (current_op->size_type == 1) current_size = 1; - - for(s = current_size; s <= smax; s++) - { - if (current_op->eam_sft != -1) - { - for(current_ea = 0; current_ea <= EA_ADEC7; current_ea++) - { - if (!has_ea(current_ea)) continue; - current_eam = _ea_to_eamreg(current_ea) >> 3; - current_reg = _ea_to_eamreg(current_ea) & 7; - - if (op_info_table[i].eam2_sft != -1) - { - for(current_ea2 = 0; current_ea2 <= EA_ADEC7; current_ea2++) - { - if (!has_ea2(current_ea2)) continue; - current_eam2 = _ea_to_eamreg(current_ea2) >> 3; - current_reg2 = _ea_to_eamreg(current_ea2) & 7; - - set_current_size(s); - current_op->genfunc(); - } - } - else - { - current_reg2 = 0; - set_current_size(s); - current_op->genfunc(); - } - } - } - else - { - current_reg = 0; - set_current_size(s); - current_op->genfunc(); - } - } - } - - // generate jumptable file -#ifdef C68K_CONST_JUMP_TABLE - if (ini_file != NULL) - { - fprintf(ini_file, "\tstatic const void *JumpTable[0x10000] =\n"); - fprintf(ini_file, "\t{\n"); - - for(i = 0; i < (0x10000 - 4); i += 4) - fprintf(ini_file, "\t\t&&OP_0x%.4X, &&OP_0x%.4X, &&OP_0x%.4X, &&OP_0x%.4X,\n", op_jump_table[i + 0], op_jump_table[i + 1], op_jump_table[i + 2], op_jump_table[i + 3]); - fprintf(ini_file, "\t\t&&OP_0x%.4X, &&OP_0x%.4X, &&OP_0x%.4X, &&OP_0x%.4X\n", op_jump_table[0xFFFC], op_jump_table[0xFFFD], op_jump_table[0xFFFE], op_jump_table[0xFFFF]); - - fprintf(ini_file, "\t};\n\n"); - } -#endif - - // close handle - if (ini_file != NULL) fclose(ini_file); - if (opcode_file != NULL) fclose(opcode_file); - - return 0; -} -#endif diff --git a/yabause/src/c68k/gen68k.h b/yabause/src/c68k/gen68k.h deleted file mode 100644 index e8b71d83db..0000000000 --- a/yabause/src/c68k/gen68k.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright 2003-2004 Stephane Dallongeville - Copyright 2004 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/********************************************************************************* - * GEN68K.H : - * - * C68K generator include file - * - ********************************************************************************/ - -#ifndef _GEN68K_H_ -#define _GEN68K_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -// setting -/////////// - -// structure definition -//////////////////////// - -typedef struct { - u32 name; - u32 mask; - u32 match; -} c68k_ea_info_struc; - -typedef struct __c68k_op_info_struc { - s8 op_name[8 + 1]; - u16 op_base; - u16 op_mask; - s8 size_type; - s8 size_sft; - s8 eam_sft; - s8 reg_sft; - s8 eam2_sft; - s8 reg2_sft; - s8 ea_supported[12 + 1]; - s8 ea2_supported[12 + 1]; - void (*genfunc)(void); -} c68k_op_info_struc; - - -#ifdef __cplusplus -} -#endif - -#endif // _GEN68K_H_ - diff --git a/yabause/src/c68k/gen68k.inc b/yabause/src/c68k/gen68k.inc deleted file mode 100644 index 483a4f7b07..0000000000 --- a/yabause/src/c68k/gen68k.inc +++ /dev/null @@ -1,1649 +0,0 @@ -/* Copyright 2003-2004 Stephane Dallongeville - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -#define EA_DREG 0 -#define EA_AREG 1 -#define EA_AIND 2 -#define EA_AINC 3 -#define EA_ADEC 4 -#define EA_D16A 5 -#define EA_D8AX 6 -#define EA_A16 7 -#define EA_A32 8 -#define EA_D16P 9 -#define EA_D8PX 10 -#define EA_IMM 11 -#define EA_AINC7 12 -#define EA_ADEC7 13 -#define EA_ILLEGAL 15 - -#define SIZE_BYTE 0 -#define SIZE_WORD 1 -#define SIZE_LONG 2 - -#define COND_TR 0 -#define COND_FA 1 -#define COND_HI 2 -#define COND_LS 3 -#define COND_CC 4 -#define COND_CS 5 -#define COND_NE 6 -#define COND_EQ 7 -#define COND_VC 8 -#define COND_VS 9 -#define COND_PL 10 -#define COND_MI 11 -#define COND_GE 12 -#define COND_LT 13 -#define COND_GT 14 -#define COND_LE 15 - -#define COND_NOT_TR COND_FA -#define COND_NOT_FA COND_TR -#define COND_NOT_HI COND_LS -#define COND_NOT_LS COND_HI -#define COND_NOT_CC COND_CS -#define COND_NOT_CS COND_CC -#define COND_NOT_NE COND_EQ -#define COND_NOT_EQ COND_NE -#define COND_NOT_VC COND_VS -#define COND_NOT_VS COND_VC -#define COND_NOT_PL COND_MI -#define COND_NOT_MI COND_PL -#define COND_NOT_GE COND_LT -#define COND_NOT_LT COND_GE -#define COND_NOT_GT COND_LE -#define COND_NOT_LE COND_GT - -#define OP_ILLEGAL 0x4AFC - -static void GenORI(void); -static void GenORICCR(void); -static void GenORISR(void); -static void GenANDI(void); -static void GenANDICCR(void); -static void GenANDISR(void); -static void GenEORI(void); -static void GenEORICCR(void); -static void GenEORISR(void); -static void GenSUBI(void); -static void GenADDI(void); -static void GenCMPI(void); -static void GenBTSTn(void); -static void GenBCHGn(void); -static void GenBCLRn(void); -static void GenBSETn(void); -static void GenBTST(void); -static void GenBCHG(void); -static void GenBCLR(void); -static void GenBSET(void); -static void GenMOVEPWaD(void); -static void GenMOVEPLaD(void); -static void GenMOVEPWDa(void); -static void GenMOVEPLDa(void); -static void GenMOVEB(void); -static void GenMOVEL(void); -static void GenMOVEW(void); -static void GenMOVEAL(void); -static void GenMOVEAW(void); -static void GenNEGX(void); -static void GenCLR(void); -static void GenNEG(void); -static void GenNOT(void); -static void GenMOVESRa(void); -static void GenMOVEaSR(void); -static void GenMOVEaCCR(void); -static void GenNBCD(void); -static void GenPEA(void); -static void GenSWAP(void); -static void GenMOVEMaR(void); -static void GenEXT(void); -static void GenTST(void); -static void GenTAS(void); -static void GenILLEGAL(void); -static void GenMOVEMRa(void); -static void GenTRAP(void); -static void GenLINK(void); -static void GenLINKA7(void); -static void GenULNK(void); -static void GenULNKA7(void); -static void GenMOVEAUSP(void); -static void GenMOVEUSPA(void); -static void GenRESET(void); -static void GenNOP(void); -static void GenSTOP(void); -static void GenRTE(void); -static void GenRTS(void); -static void GenTRAPV(void); -static void GenRTR(void); -static void GenJSR(void); -static void GenJMP(void); -static void GenCHK(void); -static void GenLEA(void); -static void GenSTCC(void); -static void GenDBCC(void); -static void GenADDQ(void); -static void GenSUBQ(void); -static void GenBCC(void); -static void GenBCC16(void); -static void GenBRA(void); -static void GenBRA16(void); -static void GenBSR(void); -static void GenBSR16(void); -static void GenMOVEQ(void); -static void GenORaD(void); -static void GenORDa(void); -static void GenSBCD(void); -static void GenSBCDM(void); -static void GenSBCD7M(void); -static void GenSBCDM7(void); -static void GenSBCD7M7(void); -static void GenDIVU(void); -static void GenDIVS(void); -static void GenSUBaD(void); -static void GenSUBDa(void); -static void GenSUBX(void); -static void GenSUBXM(void); -static void GenSUBX7M(void); -static void GenSUBXM7(void); -static void GenSUBX7M7(void); -static void GenSUBA(void); -static void GenCMP(void); -static void GenCMPM(void); -static void GenCMP7M(void); -static void GenCMPM7(void); -static void GenCMP7M7(void); -static void GenEORDa(void); -static void GenCMPA(void); -static void GenANDaD(void); -static void GenANDDa(void); -static void GenABCD(void); -static void GenABCDM(void); -static void GenABCD7M(void); -static void GenABCDM7(void); -static void GenABCD7M7(void); -static void GenMULU(void); -static void GenMULS(void); -static void GenEXGDD(void); -static void GenEXGAA(void); -static void GenEXGAD(void); -static void GenADDaD(void); -static void GenADDDa(void); -static void GenADDX(void); -static void GenADDXM(void); -static void GenADDX7M(void); -static void GenADDXM7(void); -static void GenADDX7M7(void); -static void GenADDA(void); -static void GenASRk(void); -static void GenLSRk(void); -static void GenROXRk(void); -static void GenRORk(void); -static void GenASLk(void); -static void GenLSLk(void); -static void GenROXLk(void); -static void GenROLk(void); -static void GenASRD(void); -static void GenLSRD(void); -static void GenROXRD(void); -static void GenRORD(void); -static void GenASLD(void); -static void GenLSLD(void); -static void GenROXLD(void); -static void GenROLD(void); -static void GenASR(void); -static void GenLSR(void); -static void GenROXR(void); -static void GenROR(void); -static void GenASL(void); -static void GenLSL(void); -static void GenROXL(void); -static void GenROL(void); -static void Gen1010(void); -static void Gen1111(void); -#ifdef NEOCD_HLE -static void Gen0xFABE(void); -static void Gen0xFABF(void); -static void Gen0xFAC0(void); -static void Gen0xFAC1(void); -static void Gen0xFAC2(void); -static void Gen0xFAC3(void); -#endif - -#ifdef NEOCD_HLE -#define OP_INFO_TABLE_LEN (142 + 6) -#else -#define OP_INFO_TABLE_LEN 144 -#endif - -static c68k_op_info_struc op_info_table[OP_INFO_TABLE_LEN] = -{ // DAAAAddaaddi DAAAAddaaddi - // iid181318m iid181318m - // siz siz eam ear eam ear nne6A626Pm nne6A626Pm - // opname opbase opmask typ sft 1 1 2 2 dccAX PX dccAX PX GenFunc - { "1010", 0xA000, 0xF000, 0, 0, -1, -1, -1, -1, "------------", "------------", Gen1010 }, - { "1111", 0xF000, 0xF000, 0, 0, -1, -1, -1, -1, "------------", "------------", Gen1111 }, - { "ORI", 0x0000, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenORI }, - { "ORICCR", 0x003C, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenORICCR }, - { "ORISR", 0x007C, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenORISR }, - { "ANDI", 0x0200, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenANDI }, - { "ANDICCR", 0x023C, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenANDICCR }, - { "ANDISR", 0x027C, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenANDISR }, - { "EORI", 0x0A00, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenEORI }, - { "EORICCR", 0x0A3C, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenEORICCR }, - { "EORISR", 0x0A7C, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenEORISR }, - - { "SUBI", 0x0400, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenSUBI }, - { "ADDI", 0x0600, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenADDI }, - { "CMPI", 0x0C00, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenCMPI }, - - { "BTSTn", 0x0800, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-ooooooooo-", "------------", GenBTSTn }, - { "BCHGn", 0x0840, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-ooooooo---", "------------", GenBCHGn }, - { "BCLRn", 0x0880, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-ooooooo---", "------------", GenBCLRn }, - { "BSETn", 0x08C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-ooooooo---", "------------", GenBSETn }, - - { "BTST", 0x0100, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-oooooooooo", "------------", GenBTST }, - { "BCHG", 0x0140, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-ooooooo---", "------------", GenBCHG }, - { "BCLR", 0x0180, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-ooooooo---", "------------", GenBCLR }, - { "BSET", 0x01C0, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-ooooooo---", "------------", GenBSET }, - - { "MOVEPWaD", 0x0108, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenMOVEPWaD }, - { "MOVEPLaD", 0x0148, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenMOVEPLaD }, - { "MOVEPWDa", 0x0188, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenMOVEPWDa }, - { "MOVEPLDa", 0x01C8, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenMOVEPLDa }, - - { "MOVEB", 0x1000, 0xF000, 0, 0, 3, 0, 6, 9, "oooooooooooo", "o-ooooooo---", GenMOVEB }, - { "MOVEL", 0x2000, 0xF000, 0, 0, 3, 0, 6, 9, "oooooooooooo", "o-ooooooo---", GenMOVEL }, - { "MOVEW", 0x3000, 0xF000, 0, 0, 3, 0, 6, 9, "oooooooooooo", "o-ooooooo---", GenMOVEW }, - { "MOVEAL", 0x2040, 0xF1C0, 0, 0, 3, 0, -1, 9, "oooooooooooo", "------------", GenMOVEAL }, - { "MOVEAW", 0x3040, 0xF1C0, 0, 0, 3, 0, -1, 9, "oooooooooooo", "------------", GenMOVEAW }, - - { "NEGX", 0x4000, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenNEGX }, - { "CLR", 0x4200, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenCLR }, - { "NEG", 0x4400, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenNEG }, - { "NOT", 0x4600, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenNOT }, - - { "MOVESRa", 0x40C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-ooooooo---", "------------", GenMOVESRa }, - { "MOVEaCCR", 0x44C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-oooooooooo", "------------", GenMOVEaCCR }, - { "MOVEaSR", 0x46C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-oooooooooo", "------------", GenMOVEaSR }, - - { "NBCD", 0x4800, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-ooooooo---", "------------", GenNBCD }, - { "PEA", 0x4840, 0xFFC0, 0, 0, 3, 0, -1, -1, "--o--oooooo-", "------------", GenPEA }, - { "SWAP", 0x4840, 0xFFF8, 0, 0, -1, 0, -1, -1, "------------", "------------", GenSWAP }, - - { "MOVEMRa", 0x4880, 0xFF80, 1, 6, 3, 0, -1, -1, "--o-ooooo---", "------------", GenMOVEMRa }, - { "EXT", 0x4880, 0xFFB8, 1, 6, -1, 0, -1, -1, "------------", "------------", GenEXT }, - { "TST", 0x4A00, 0xFF00, 2, 6, 3, 0, -1, -1, "o-ooooooo---", "------------", GenTST }, - { "TAS", 0x4AC0, 0xFFC0, 0, 0, 3, 0, -1, -1, "o-ooooooo---", "------------", GenTAS }, - { "ILLEGAL", 0x4AFC, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenILLEGAL }, - { "MOVEMaR", 0x4C80, 0xFF80, 1, 6, 3, 0, -1, -1, "--oo-oooooo-", "------------", GenMOVEMaR }, - - { "TRAP", 0x4E40, 0xFFF0, 0, 0, -1, -1, -1, -1, "------------", "------------", GenTRAP }, - { "LINK", 0x4E50, 0xFFF8, 0, 0, -1, 0, -1, -1, "------------", "------------", GenLINK }, - { "LINKA7", 0x4E57, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenLINKA7 }, - { "ULNK", 0x4E58, 0xFFF8, 0, 0, -1, 0, -1, -1, "------------", "------------", GenULNK }, - { "ULNKA7", 0x4E5F, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenULNKA7 }, - { "MOVEAUSP", 0x4E60, 0xFFF8, 0, 0, -1, 0, -1, -1, "------------", "------------", GenMOVEAUSP }, - { "MOVEUSPA", 0x4E68, 0xFFF8, 0, 0, -1, 0, -1, -1, "------------", "------------", GenMOVEUSPA }, - - { "RESET", 0x4E70, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenRESET }, - { "NOP", 0x4E71, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenNOP }, - { "STOP", 0x4E72, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenSTOP }, - { "RTE", 0x4E73, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenRTE }, - { "RTS", 0x4E75, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenRTS }, - { "TRAPV", 0x4E76, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenTRAPV }, - { "RTR", 0x4E77, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenRTR }, - - { "JSR", 0x4E80, 0xFFC0, 0, 0, 3, 0, -1, -1, "--o--oooooo-", "------------", GenJSR }, - { "JMP", 0x4EC0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--o--oooooo-", "------------", GenJMP }, - - { "CHK", 0x4180, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-oooooooooo", "------------", GenCHK }, - { "LEA", 0x41C0, 0xF1C0, 0, 0, 3, 0, -1, 9, "--o--oooooo-", "------------", GenLEA }, - - { "STCC", 0x50C0, 0xF0C0, 0, 0, 3, 0, -1, -1, "o-ooooooo---", "------------", GenSTCC }, - { "DBCC", 0x50C8, 0xF0F8, 0, 0, -1, 0, -1, -1, "------------", "------------", GenDBCC }, - - { "ADDQ", 0x5000, 0xF100, 2, 6, 3, 0, -1, -1, "ooooooooo---", "------------", GenADDQ }, - { "SUBQ", 0x5100, 0xF100, 2, 6, 3, 0, -1, -1, "ooooooooo---", "------------", GenSUBQ }, - - { "BCC", 0x6000, 0xF000, 0, 0, -1, -1, -1, -1, "------------", "------------", GenBCC }, - { "BCC16", 0x6000, 0xF0FF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenBCC16 }, - { "BRA", 0x6000, 0xFF00, 0, 0, -1, -1, -1, -1, "------------", "------------", GenBRA }, - { "BRA16", 0x6000, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenBRA16 }, - { "BSR", 0x6100, 0xFF00, 0, 0, -1, -1, -1, -1, "------------", "------------", GenBSR }, - { "BSR16", 0x6100, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenBSR16 }, - - { "MOVEQ", 0x7000, 0xF100, 0, 0, -1, 9, -1, -1, "------------", "------------", GenMOVEQ }, - - { "ORaD", 0x8000, 0xF100, 2, 6, 3, 0, -1, 9, "o-oooooooooo", "------------", GenORaD }, - { "ORDa", 0x8100, 0xF100, 2, 6, 3, 0, -1, 9, "--ooooooo---", "------------", GenORDa }, - { "SBCD", 0x8100, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenSBCD }, - { "SBCDM", 0x8108, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenSBCDM }, - { "SBCD7M", 0x810F, 0xF1FF, 0, 0, -1, 0, -1, 9, "------------", "------------", GenSBCD7M }, - { "SBCDM7", 0x8F08, 0xFFF8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenSBCDM7 }, - { "SBCD7M7", 0x8F0F, 0xFFFF, 0, 0, -1, 0, -1, 9, "------------", "------------", GenSBCD7M7 }, - { "DIVU", 0x80C0, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-oooooooooo", "------------", GenDIVU }, - { "DIVS", 0x81C0, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-oooooooooo", "------------", GenDIVS }, - - { "SUBaD", 0x9000, 0xF100, 2, 6, 3, 0, -1, 9, "oooooooooooo", "------------", GenSUBaD }, - { "SUBDa", 0x9100, 0xF100, 2, 6, 3, 0, -1, 9, "--ooooooo---", "------------", GenSUBDa }, - { "SUBX", 0x9100, 0xF138, 2, 6, -1, 0, -1, 9, "------------", "------------", GenSUBX }, - { "SUBXM", 0x9108, 0xF138, 2, 6, -1, 0, -1, 9, "------------", "------------", GenSUBXM }, - { "SUBX7M", 0x910F, 0xF13F, 2, 6, -1, -1, -1, 9, "------------", "------------", GenSUBX7M }, - { "SUBXM7", 0x9F08, 0xFF38, 2, 6, -1, 0, -1, -1, "------------", "------------", GenSUBXM7 }, - { "SUBX7M7", 0x9F0F, 0xFF3F, 2, 6, -1, -1, -1, -1, "------------", "------------", GenSUBX7M7 }, - { "SUBA", 0x90C0, 0xF0C0, 1, 8, 3, 0, -1, 9, "oooooooooooo", "------------", GenSUBA }, - - { "CMP", 0xB000, 0xF100, 2, 6, 3, 0, -1, 9, "oooooooooooo", "------------", GenCMP }, - { "CMPM", 0xB108, 0xF138, 2, 6, -1, 0, -1, 9, "------------", "------------", GenCMPM }, - { "CMP7M", 0xB10F, 0xF13F, 2, 6, -1, -1, -1, 9, "------------", "------------", GenCMP7M }, - { "CMPM7", 0xBF08, 0xFF38, 2, 6, -1, 0, -1, -1, "------------", "------------", GenCMPM7 }, - { "CMP7M7", 0xBF0F, 0xFF3F, 2, 6, -1, -1, -1, -1, "------------", "------------", GenCMP7M7 }, - { "EORDa", 0xB100, 0xF100, 2, 6, 3, 0, -1, 9, "o-ooooooo---", "------------", GenEORDa }, - { "CMPA", 0xB0C0, 0xF0C0, 1, 8, 3, 0, -1, 9, "oooooooooooo", "------------", GenCMPA }, - - { "ANDaD", 0xC000, 0xF100, 2, 6, 3, 0, -1, 9, "o-oooooooooo", "------------", GenANDaD }, - { "ANDDa", 0xC100, 0xF100, 2, 6, 3, 0, -1, 9, "--ooooooo---", "------------", GenANDDa }, - { "ABCD", 0xC100, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenABCD }, - { "ABCDM", 0xC108, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenABCDM }, - { "ABCD7M", 0xC10F, 0xF1FF, 0, 0, -1, -1, -1, 9, "------------", "------------", GenABCD7M }, - { "ABCDM7", 0xCF08, 0xFFF8, 0, 0, -1, 0, -1, -1, "------------", "------------", GenABCDM7 }, - { "ABCD7M7", 0xCF0F, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", GenABCD7M7 }, - { "MULU", 0xC0C0, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-oooooooooo", "------------", GenMULU }, - { "MULS", 0xC1C0, 0xF1C0, 0, 0, 3, 0, -1, 9, "o-oooooooooo", "------------", GenMULS }, - { "EXGDD", 0xC140, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenEXGDD }, - { "EXGAA", 0xC148, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenEXGAA }, - { "EXGAD", 0xC188, 0xF1F8, 0, 0, -1, 0, -1, 9, "------------", "------------", GenEXGAD }, - - { "ADDaD", 0xD000, 0xF100, 2, 6, 3, 0, -1, 9, "oooooooooooo", "------------", GenADDaD }, - { "ADDDa", 0xD100, 0xF100, 2, 6, 3, 0, -1, 9, "--ooooooo---", "------------", GenADDDa }, - { "ADDX", 0xD100, 0xF138, 2, 6, -1, 0, -1, 9, "------------", "------------", GenADDX }, - { "ADDXM", 0xD108, 0xF138, 2, 6, -1, 0, -1, 9, "------------", "------------", GenADDXM }, - { "ADDX7M", 0xD10F, 0xF13F, 2, 6, -1, -1, -1, 9, "------------", "------------", GenADDX7M }, - { "ADDXM7", 0xDF08, 0xFF38, 2, 6, -1, 0, -1, -1, "------------", "------------", GenADDXM7 }, - { "ADDX7M7", 0xDF0F, 0xFF3F, 2, 6, -1, -1, -1, -1, "------------", "------------", GenADDX7M7 }, - { "ADDA", 0xD0C0, 0xF0C0, 1, 8, 3, 0, -1, 9, "oooooooooooo", "------------", GenADDA }, - - { "ASRk", 0xE000, 0xF138, 2, 6, -1, 0, -1, -1, "o-----------", "------------", GenASRk }, - { "LSRk", 0xE008, 0xF138, 2, 6, -1, 0, -1, -1, "o-----------", "------------", GenLSRk }, - { "ROXRk", 0xE010, 0xF138, 2, 6, -1, 0, -1, -1, "o-----------", "------------", GenROXRk }, - { "RORk", 0xE018, 0xF138, 2, 6, -1, 0, -1, -1, "o-----------", "------------", GenRORk }, - { "ASLk", 0xE100, 0xF138, 2, 6, -1, 0, -1, -1, "o-----------", "------------", GenASLk }, - { "LSLk", 0xE108, 0xF138, 2, 6, -1, 0, -1, -1, "o-----------", "------------", GenLSLk }, - { "ROXLk", 0xE110, 0xF138, 2, 6, -1, 0, -1, -1, "o-----------", "------------", GenROXLk }, - { "ROLk", 0xE118, 0xF138, 2, 6, -1, 0, -1, -1, "o-----------", "------------", GenROLk }, - - { "ASRD", 0xE020, 0xF138, 2, 6, -1, 0, -1, 9, "o-----------", "o-----------", GenASRD }, - { "LSRD", 0xE028, 0xF138, 2, 6, -1, 0, -1, 9, "o-----------", "o-----------", GenLSRD }, - { "ROXRD", 0xE030, 0xF138, 2, 6, -1, 0, -1, 9, "o-----------", "o-----------", GenROXRD }, - { "RORD", 0xE038, 0xF138, 2, 6, -1, 0, -1, 9, "o-----------", "o-----------", GenRORD }, - { "ASLD", 0xE120, 0xF138, 2, 6, -1, 0, -1, 9, "o-----------", "o-----------", GenASLD }, - { "LSLD", 0xE128, 0xF138, 2, 6, -1, 0, -1, 9, "o-----------", "o-----------", GenLSLD }, - { "ROXLD", 0xE130, 0xF138, 2, 6, -1, 0, -1, 9, "o-----------", "o-----------", GenROXLD }, - { "ROLD", 0xE138, 0xF138, 2, 6, -1, 0, -1, 9, "o-----------", "o-----------", GenROLD }, - - { "ASR", 0xE0C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--ooooooo---", "------------", GenASR }, - { "LSR", 0xE2C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--ooooooo---", "------------", GenLSR }, - { "ROXR", 0xE4C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--ooooooo---", "------------", GenROXR }, - { "ROR", 0xE6C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--ooooooo---", "------------", GenROR }, - { "ASL", 0xE1C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--ooooooo---", "------------", GenASL }, - { "LSL", 0xE3C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--ooooooo---", "------------", GenLSL }, - { "ROXL", 0xE5C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--ooooooo---", "------------", GenROXL }, - { "ROL", 0xE7C0, 0xFFC0, 0, 0, 3, 0, -1, -1, "--ooooooo---", "------------", GenROL } - -#ifdef NEOCD_HLE - , - { "0xFABE", 0xFABE, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", Gen0xFABE }, - { "0xFABF", 0xFABF, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", Gen0xFABF }, - { "0xFAC0", 0xFAC0, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", Gen0xFAC0 }, - { "0xFAC1", 0xFAC1, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", Gen0xFAC1 }, - { "0xFAC2", 0xFAC2, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", Gen0xFAC2 }, - { "0xFAC3", 0xFAC3, 0xFFFF, 0, 0, -1, -1, -1, -1, "------------", "------------", Gen0xFAC3 } -#endif -}; - -#ifndef C68K_NO_JUMP_TABLE -#ifdef C68K_CONST_JUMP_TABLE -static u16 op_jump_table[0x10000]; -#endif -#endif - -// files where code is generated -static FILE* ini_file = NULL; -static FILE* opcode_file = NULL; - -// current generated instruction infos -static c68k_op_info_struc *current_op; -static u32 current_ea; -static u32 current_eam; -static u32 current_reg; -static u32 current_ea2; -static u32 current_eam2; -static u32 current_reg2; -static u32 current_size; -static u32 current_cycle; -static u32 current_io_sav; - -static char current_cond_char[128]; - -static char szc[20]; -static char szcs[20]; -static char szcf[20]; -static char szcsf[20]; - -static u32 current_bits_mask; -static u8 current_sft_mask; - -#define EA_DREG 0 -#define EA_AREG 1 -#define EA_AIND 2 -#define EA_AINC 3 -#define EA_ADEC 4 -#define EA_D16A 5 -#define EA_D8AX 6 -#define EA_A16 7 -#define EA_A32 8 -#define EA_D16P 9 -#define EA_D8PX 10 -#define EA_IMM 11 -#define EA_AINC7 12 -#define EA_ADEC7 13 -#define EA_ILLEGAL 15 - -static const u32 jmp_jsr_cycle_table[16] = -{ - 0, 0, - 4, - 0, - 0, - 6, - 10, - 6, - 8, - 6, - 10, - 0, 0, 0, 0 -}; - -static const u32 lea_pea_cycle_table[16] = -{ - 0, 0, - 0, - 0, - 0, - 4, - 8, - 4, - 8, - 4, - 8, - 0, 0, 0, 0 -}; - -static const u32 movem_cycle_table[16] = -{ - 0, 0, - 0, - 0, - 0, - 4, - 6, - 4, - 8, - 4, - 6, - 0, 0, 0, 0 -}; - -// general emitter function -//////////////////////////// - -static u32 prepare_generate(void) -{ - char filename[32]; - - sprintf(filename, "c68k_op%.1X.inc", (current_op->op_base >> 12) & 0xF); - if (opcode_file != NULL) - { - fclose(opcode_file); - opcode_file = NULL; - } - opcode_file = fopen(filename, "at"); - if (opcode_file == NULL) - { - printf("Can't open %s\n", filename); - return 1; - } - return 0; -} - -static void wf_op(char* fmt, ...) -{ - va_list args; - - if (opcode_file == NULL) return; - - va_start(args, fmt); - vfprintf(opcode_file, fmt, args); - va_end(args); -} - -static void gen_jumptable(u32 base, u32 start1, u32 end1, u32 step1, u32 start2, u32 end2, u32 step2, u32 start3, u32 end3, u32 step3, u32 op) -{ -#ifdef C68K_CONST_JUMP_TABLE - u32 i, j, k; -#endif -#ifdef C68K_NO_JUMP_TABLE - u32 i, j, k; -#endif - - - base &= 0xFFFF; - start1 &= 0xFFFF; - end1 &= 0xFFFF; - step1 &= 0xFFFF; - if (end1 < start1) end1 = start1; - start2 &= 0xFFFF; - end2 &= 0xFFFF; - step2 &= 0xFFFF; - if (end2 < start2) end2 = start2; - op &= 0xFFFF; - -#ifndef C68K_NO_JUMP_TABLE -#ifdef C68K_CONST_JUMP_TABLE - if (step1 == 0) step1 = 1; - if (step2 == 0) step2 = 1; - if (step3 == 0) step3 = 1; - - for(i = start1; i <= end1; i += step1) - for(j = start2; j <= end2; j += step2) - for(k = start3; k <= end3; k += step3) - op_jump_table[base + i + j + k] = op; - -#else - if (ini_file == NULL) return; - - if (start1 != end1) - { - fprintf(ini_file, "\t\tfor(i = 0x%.4X; i <= 0x%.4X; i += 0x%.4X)\n", (int)start1, (int)end1, (int)step1); - if (start2 != end2) - { - fprintf(ini_file, "\t\t\tfor(j = 0x%.4X; j <= 0x%.4X; j += 0x%.4X)\n\t", (int)start2, (int)end2, (int)step2); - if (start3 != end3) - { - fprintf(ini_file, "\t\t\t\tfor(k = 0x%.4X; k <= 0x%.4X; k += 0x%.4X)\n\t", (int)start3, (int)end3, (int)step3); - fprintf(ini_file, "\t\t\t\t\tJumpTable[0x%.4X + i + j + k] = &&OP_0x%.4X;\n", (int)base, (int)op); - } - else fprintf(ini_file, "\t\t\t\tJumpTable[0x%.4X + i + j] = &&OP_0x%.4X;\n", (int)base, (int)op); - } - else fprintf(ini_file, "\t\t\tJumpTable[0x%.4X + i] = &&OP_0x%.4X;\n", (int)base, (int)op); - } - else fprintf(ini_file, "\t\tJumpTable[0x%.4X] = &&OP_0x%.4X;\n", (int)base, (int)op); -#endif -#else - if (step1 == 0) step1 = 1; - if (step2 == 0) step2 = 1; - if (step3 == 0) step3 = 1; - - for(i = start1; i <= end1; i += step1) - for(j = start2; j <= end2; j += step2) - for(k = start3; k <= end3; k += step3) - { - u32 temp=(base + i + j + k); - if (temp != op && temp != 0x4E57 && temp != 0x4E5F) - wf_op("case 0x%.4X:\n", base + i + j + k); - } -#endif -} - -static void gen_opjumptable_ext(u32 base, u32 start3, u32 end3, u32 step3, u32 op) -{ - u32 start1, end1, step1, start2, end2, step2; - - start1 = end1 = step1 = 0; - start2 = end2 = step2 = 0; - - if ((current_op->reg_sft != -1) && (current_ea < 7)) - { - if ((current_ea == EA_AINC) || (current_ea == EA_ADEC)) end1 = 6 << current_op->reg_sft; - else end1 = 7 << current_op->reg_sft; - step1 = 1 << current_op->reg_sft; - } - if ((current_op->reg2_sft != -1) && (current_ea2 < 7)) - { - if ((current_ea2 == EA_AINC) || (current_ea2 == EA_ADEC)) end2 = 6 << current_op->reg2_sft; - else end2 = 7 << current_op->reg2_sft; - step2 = 1 << current_op->reg2_sft; - } - - if (start1 != end1) - { - if (start2 != end2) gen_jumptable(base, start1, end1, step1, start2, end2, step2, start3, end3, step3, op); - else gen_jumptable(base, start1, end1, step1, start3, end3, step3, start2, end2, step2, op); - } - else if (start2 != end2) gen_jumptable(base, start2, end2, step2, start3, end3, step3, start1, end1, step1, op); - else gen_jumptable(base, start3, end3, step3, start2, end2, step2, start1, end1, step1, op); -} - -static void gen_opjumptable(u32 op) -{ - gen_opjumptable_ext(op, 0, 0, 0, op); -} - -#define GEN_ADR 1 -#define GEN_RES 2 -#define GEN_SRC 4 -#define GEN_DST 8 -#define GEN_ALL 15 - -static void start_op(u32 op, int v) -{ - current_io_sav = 0; - current_cycle = 0; - - wf_op("\n// %s\n", current_op->op_name); -#ifndef C68K_NO_JUMP_TABLE - wf_op("OP_0x%.4X:\n", op & 0xFFFF); -#else - wf_op("case 0x%.4X:\n", op & 0xFFFF); -#endif - wf_op("{\n"); - if (v & GEN_ADR) wf_op("\tu32 adr;\n"); - if (v & GEN_RES) wf_op("\tu32 res;\n"); - if (v & GEN_DST) wf_op("\tpointer dst;\n"); - if (v & GEN_SRC) wf_op("\tpointer src;\n"); -} - -static void add_CCnt(u32 cycle) -{ - if (current_io_sav) wf_op("\tPOST_IO\n"); - current_io_sav = 0; - wf_op("\tCCnt -= %d;\n", cycle); -} - -static void adds_CCnt(char *str) -{ - if (current_io_sav) wf_op("\tPOST_IO\n"); - current_io_sav = 0; - wf_op("\tCCnt -= %s;\n", str); -} - -#if 0 // FIXME: warning removal -static void sub_CCnt(u32 cycle) -{ - if (current_io_sav) wf_op("\tPOST_IO\n"); - current_io_sav = 0; - wf_op("\tCCnt += %d;\n", cycle); -} - -static void subs_CCnt(char *str) -{ - if (current_io_sav) wf_op("\tPOST_IO\n"); - current_io_sav = 0; - wf_op("\tCCnt += %s;\n", str); -} - -static void quick_fterminate_op(u32 cycle) -{ - if (current_io_sav) wf_op("\tPOST_IO\n"); - current_io_sav = 0; - wf_op("\tCCnt -= %d;\n", current_cycle + cycle); - wf_op("\tgoto C68k_Exec_End;\n"); -} -#endif - -static void fterminate_op(u32 cycle) -{ - wf_op("}\n"); - if (current_io_sav) wf_op("POST_IO\n"); - current_io_sav = 0; - wf_op("CCnt -= %d;\n", current_cycle + cycle); - wf_op("goto C68k_Exec_End;\n"); -} - -static void quick_terminate_op(u32 cycle) -{ - if (current_io_sav) wf_op("\tPOST_IO\n"); - current_io_sav = 0; - wf_op("\tRET(%d)\n", current_cycle + cycle); -} - -static void terminate_op(u32 cycle) -{ - if (current_io_sav) wf_op("\tPOST_IO\n"); - wf_op("}\n"); - current_io_sav = 0; - wf_op("RET(%d)\n", current_cycle + cycle); -} - -static void do_pre_io(void) -{ - if (!current_io_sav) fprintf(opcode_file, "\tPRE_IO\n"); - current_io_sav = 1; -} - -static void mem_op(char* fmt, ...) -{ - va_list args; - - if (opcode_file == NULL) return; - - do_pre_io(); - - va_start(args, fmt); - vfprintf(opcode_file, fmt, args); - va_end(args); -} - -// flag emitter function -///////////////////////// - -static void set_logic_flag(void) -{ - wf_op("\tCPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_V = 0;\n"); - wf_op("\tCPU->flag_notZ = res;\n"); - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_N = res;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_N = res >> 8;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static void set_logicl_flag(void) -{ - wf_op("\tCPU->flag_C = 0;\n"); - wf_op("\tCPU->flag_V = 0;\n"); - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_N = res;\n"); - wf_op("\tCPU->flag_notZ = res & 0xFF;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_notZ = res & 0xFFFF;\n"); - wf_op("\tCPU->flag_N = res >> 8;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_notZ = res;\n"); - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static void set_add_flag(void) -{ - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res;\n"); - wf_op("\tCPU->flag_V = (src ^ res) & (dst ^ res);\n"); - wf_op("\tCPU->flag_notZ = res & 0xFF;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8;\n"); - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8;\n"); - wf_op("\tCPU->flag_notZ = res & 0xFFFF;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_notZ = res;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23;\n"); -// wf_op("\tCPU->flag_X = CPU->flag_C = ((src & dst) | (~res & (src | dst))) >> 23;\n"); - wf_op("\tCPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24;\n"); - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static void set_addx_flag(void) -{ - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res;\n"); - wf_op("\tCPU->flag_V = (src ^ res) & (dst ^ res);\n"); - wf_op("\tCPU->flag_notZ |= res & 0xFF;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_V = ((src ^ res) & (dst ^ res)) >> 8;\n"); - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8;\n"); - wf_op("\tCPU->flag_notZ |= res & 0xFFFF;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_notZ |= res;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = ((src & dst & 1) + (src >> 1) + (dst >> 1)) >> 23;\n"); -// wf_op("\tCPU->flag_X = CPU->flag_C = ((src & dst) | (~res & (src | dst))) >> 23;\n"); - wf_op("\tCPU->flag_V = ((src ^ res) & (dst ^ res)) >> 24;\n"); - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static void set_sub_flag(void) -{ - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res;\n"); - wf_op("\tCPU->flag_V = (src ^ dst) & (res ^ dst);\n"); - wf_op("\tCPU->flag_notZ = res & 0xFF;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8;\n"); - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8;\n"); - wf_op("\tCPU->flag_notZ = res & 0xFFFF;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_notZ = res;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23;\n"); -// wf_op("\tCPU->flag_X = CPU->flag_C = ((src & res) | (~dst & (src | res))) >> 23;\n"); - wf_op("\tCPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24;\n"); - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static void set_subx_flag(void) -{ - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res;\n"); - wf_op("\tCPU->flag_V = (src ^ dst) & (res ^ dst);\n"); - wf_op("\tCPU->flag_notZ |= res & 0xFF;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8;\n"); - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8;\n"); - wf_op("\tCPU->flag_notZ |= res & 0xFFFF;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_notZ |= res;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23;\n"); -// wf_op("\tCPU->flag_X = CPU->flag_C = ((src & res) | (~dst & (src | res))) >> 23;\n"); - wf_op("\tCPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24;\n"); - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static void set_cmp_flag(void) -{ - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_N = CPU->flag_C = res;\n"); - wf_op("\tCPU->flag_V = (src ^ dst) & (res ^ dst);\n"); - wf_op("\tCPU->flag_notZ = res & 0xFF;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 8;\n"); - wf_op("\tCPU->flag_N = CPU->flag_C = res >> 8;\n"); - wf_op("\tCPU->flag_notZ = res & 0xFFFF;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_notZ = res;\n"); - wf_op("\tCPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23;\n"); -// wf_op("\tCPU->flag_C = ((src & res) | (~dst & (src | res))) >> 23;\n"); - wf_op("\tCPU->flag_V = ((src ^ dst) & (res ^ dst)) >> 24;\n"); - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static void set_negx_flag(void) -{ - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_V = res & src;\n"); - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res;\n"); - wf_op("\tCPU->flag_notZ |= res & 0xFF;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_V = (res & src) >> 8;\n"); - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8;\n"); - wf_op("\tCPU->flag_notZ |= res & 0xFFFF;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_notZ |= res;\n"); - wf_op("\tCPU->flag_V = (res & src) >> 24;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23;\n"); -// wf_op("\tCPU->flag_X = CPU->flag_C = ((src & res) | (~dst & (src | res))) >> 23;\n"); - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static void set_neg_flag(void) -{ - switch(current_size) - { - case SIZE_BYTE: - wf_op("\tCPU->flag_V = res & src;\n"); - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res;\n"); - wf_op("\tCPU->flag_notZ = res & 0xFF;\n"); - break; - - case SIZE_WORD: - wf_op("\tCPU->flag_V = (res & src) >> 8;\n"); - wf_op("\tCPU->flag_N = CPU->flag_X = CPU->flag_C = res >> 8;\n"); - wf_op("\tCPU->flag_notZ = res & 0xFFFF;\n"); - break; - - case SIZE_LONG: - wf_op("\tCPU->flag_notZ = res;\n"); - wf_op("\tCPU->flag_V = (res & src) >> 24;\n"); - wf_op("\tCPU->flag_X = CPU->flag_C = ((src & res & 1) + (src >> 1) + (res >> 1)) >> 23;\n"); -// wf_op("\tCPU->flag_X = CPU->flag_C = ((src & res) | (~dst & (src | res))) >> 23;\n"); - wf_op("\tCPU->flag_N = res >> 24;\n"); - break; - } -} - -static char* get_cond_as_cond(u32 cond, u32 notvar) -{ - if (notvar) cond ^= 1; - - switch(cond) - { - case COND_TR: - sprintf(current_cond_char, "(1)"); - break; - - case COND_FA: - sprintf(current_cond_char, "(0)"); - break; - - case COND_HI: - sprintf(current_cond_char, "(CPU->flag_notZ && (!(CPU->flag_C & 0x100)))"); - break; - - case COND_LS: - sprintf(current_cond_char, "((!CPU->flag_notZ) || (CPU->flag_C & 0x100))"); - break; - - case COND_CC: - sprintf(current_cond_char, "(!(CPU->flag_C & 0x100))"); - break; - - case COND_CS: - sprintf(current_cond_char, "(CPU->flag_C & 0x100)"); - break; - - case COND_NE: - sprintf(current_cond_char, "(CPU->flag_notZ)"); - break; - - case COND_EQ: - sprintf(current_cond_char, "(!CPU->flag_notZ)"); - break; - - case COND_VC: - sprintf(current_cond_char, "(!(CPU->flag_V & 0x80))"); - break; - - case COND_VS: - sprintf(current_cond_char, "(CPU->flag_V & 0x80)"); - break; - - case COND_PL: - sprintf(current_cond_char, "(!(CPU->flag_N & 0x80))"); - break; - - case COND_MI: - sprintf(current_cond_char, "(CPU->flag_N & 0x80)"); - break; - - case COND_GE: - sprintf(current_cond_char, "(!((CPU->flag_N ^ CPU->flag_V) & 0x80))"); - break; - - case COND_LT: - sprintf(current_cond_char, "((CPU->flag_N ^ CPU->flag_V) & 0x80)"); - break; - - case COND_GT: - sprintf(current_cond_char, "(CPU->flag_notZ && (!((CPU->flag_N ^ CPU->flag_V) & 0x80)))"); - break; - - case COND_LE: - sprintf(current_cond_char, "((!CPU->flag_notZ) || ((CPU->flag_N ^ CPU->flag_V) & 0x80))"); - break; - } - - return current_cond_char; -} - -// effective address related function -////////////////////////////////////// - -static u32 has_ea(u32 ea) -{ - if (ea == EA_AINC7) return (current_op->ea_supported[EA_AINC] == 'o'); - if (ea == EA_ADEC7) return (current_op->ea_supported[EA_ADEC] == 'o'); - if (ea <= EA_IMM) return (current_op->ea_supported[ea] == 'o'); - return 0; -} - -static u32 has_ea2(u32 ea) -{ - if (ea == EA_AINC7) return (current_op->ea2_supported[EA_AINC] == 'o'); - if (ea == EA_ADEC7) return (current_op->ea2_supported[EA_ADEC] == 'o'); - if (ea <= EA_IMM) return (current_op->ea2_supported[ea] == 'o'); - return 0; -} - -#if 0 // FIXME: warning removal -static u32 _eamreg_to_ea(u32 eam, u32 reg) -{ - if ((eam > 7) || (reg > 7)) return EA_ILLEGAL; - if ((eam == 3) && (reg == 7)) return EA_AINC7; - if ((eam == 4) && (reg == 7)) return EA_ADEC7; - if (eam != 7) return eam; - if (reg < 5) return (eam + reg); - return EA_ILLEGAL; -} -#endif - -static u32 _ea_to_eamreg(u32 ea) -{ - if (ea < 7) return (ea << 3) | 0; - if (ea == EA_AINC7) return (EA_AINC << 3) | 7; - if (ea == EA_ADEC7) return (EA_ADEC << 3) | 7; - if (ea <= EA_IMM) return (7 << 3) | (ea - 7); - return (7 << 3) | 7; -} - -static u32 is_ea_memory(u32 ea) -{ - if ((ea > EA_AREG) && (ea != EA_IMM)) return 1; - else return 0; -} - -static void _ea_calc_free(u32 ea, u32 rsft) -{ - u32 step; - - step = 0; - switch (current_size) - { - case SIZE_BYTE: - if ((ea == EA_AINC7) || (ea == EA_ADEC7)) step = 2; - else step = 1; - break; - - case SIZE_WORD: - step = 2; - break; - - case SIZE_LONG: - step = 4; - break; - } - - switch (ea) - { - case EA_DREG: -// wf_op("\tadr = (u32)(&CPU->D[(Opcode >> %d) & 7]);\n", rsft); - break; - - case EA_AREG: -// wf_op("\tadr = (u32)(&CPU->A[(Opcode >> %d) & 7]);\n", rsft); - break; - - case EA_AIND: - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7];\n", rsft); - break; - - case EA_AINC: - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7];\n", rsft); - wf_op("\tCPU->A[(Opcode >> %d) & 7] += %d;\n", rsft, step); - break; - - case EA_AINC7: - wf_op("\tadr = CPU->A[7];\n"); - wf_op("\tCPU->A[7] += %d;\n", step); - break; - - case EA_ADEC: - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7] - %d;\n", rsft, step); - wf_op("\tCPU->A[(Opcode >> %d) & 7] = adr;\n", rsft); - break; - - case EA_ADEC7: - wf_op("\tadr = CPU->A[7] - %d;\n", step); - wf_op("\tCPU->A[7] = adr;\n"); - break; - - case EA_D16A: - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7] + (s32)(s16)FETCH_WORD;\n", rsft); - wf_op("\tPC += 2;\n"); - break; - - case EA_D8AX: - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7];\n", rsft); - wf_op("\tDECODE_EXT_WORD\n"); - break; - - case EA_A16: - wf_op("\tadr = (s32)(s16)FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - break; - - case EA_A32: - wf_op("\tadr = (s32)FETCH_LONG;\n"); - wf_op("\tPC += 4;\n"); - break; - - case EA_D16P: - wf_op("\tadr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - break; - - case EA_D8PX: - wf_op("\tadr = PC - CPU->BasePC;\n"); - wf_op("\tDECODE_EXT_WORD\n"); - break; - } -} - -static void _ea_calc(u32 ea, u32 rsft) -{ - u32 step; - u32 cycle_sft; - - step = 0; - cycle_sft = 0; - switch (current_size) - { - case SIZE_BYTE: - if ((ea == EA_AINC7) || (ea == EA_ADEC7)) step = 2; - else step = 1; - break; - - case SIZE_WORD: - step = 2; - break; - - case SIZE_LONG: - cycle_sft = 1; - step = 4; - break; - } - - switch (ea) - { - case EA_DREG: -// wf_op("\tadr = (u32)(&CPU->D[(Opcode >> %d) & 7]);\n", rsft); - break; - - case EA_AREG: -// wf_op("\tadr = (u32)(&CPU->A[(Opcode >> %d) & 7]);\n", rsft); - break; - - case EA_IMM: - current_cycle += (4 << cycle_sft) + 0; - break; - - case EA_AIND: - current_cycle += (4 << cycle_sft) + 0; - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7];\n", rsft); - break; - - case EA_AINC: - current_cycle += (4 << cycle_sft) + 0; - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7];\n", rsft); - wf_op("\tCPU->A[(Opcode >> %d) & 7] += %d;\n", rsft, step); - break; - - case EA_AINC7: - current_cycle += (4 << cycle_sft) + 0; - wf_op("\tadr = CPU->A[7];\n"); - wf_op("\tCPU->A[7] += %d;\n", step); - break; - - case EA_ADEC: - current_cycle += (4 << cycle_sft) + 2; - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7] - %d;\n", rsft, step); - wf_op("\tCPU->A[(Opcode >> %d) & 7] = adr;\n", rsft); - break; - - case EA_ADEC7: - current_cycle += (4 << cycle_sft) + 2; - wf_op("\tadr = CPU->A[7] - %d;\n", step); - wf_op("\tCPU->A[7] = adr;\n"); - break; - - case EA_D16A: - current_cycle += (4 << cycle_sft) + 4; - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7] + (s32)(s16)FETCH_WORD;\n", rsft); - wf_op("\tPC += 2;\n"); - break; - - case EA_D8AX: - current_cycle += (4 << cycle_sft) + 6; - wf_op("\tadr = CPU->A[(Opcode >> %d) & 7];\n", rsft); - wf_op("\tDECODE_EXT_WORD\n"); - break; - - case EA_A16: - current_cycle += (4 << cycle_sft) + 4; - wf_op("\tadr = (s32)(s16)FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - break; - - case EA_A32: - current_cycle += (4 << cycle_sft) + 8; - wf_op("\tadr = (s32)FETCH_LONG;\n"); - wf_op("\tPC += 4;\n"); - break; - - case EA_D16P: - current_cycle += (4 << cycle_sft) + 4; - wf_op("\tadr = (PC - CPU->BasePC) + (s32)(s16)FETCH_WORD;\n"); - wf_op("\tPC += 2;\n"); - break; - - case EA_D8PX: - current_cycle += (4 << cycle_sft) + 6; - wf_op("\tadr = PC - CPU->BasePC;\n"); - wf_op("\tDECODE_EXT_WORD\n"); - break; - } -} - -static void _ea_read_(u32 ea, u32 rsft, char dest[4]) -{ - char sz[8]; - - switch (current_size) - { - case SIZE_BYTE: - strcpy(sz, "BYTE"); - break; - - case SIZE_WORD: - strcpy(sz, "WORD"); - break; - - case SIZE_LONG: - strcpy(sz, "LONG"); - break; - } - - switch (ea) - { - case EA_DREG: - wf_op("\t%s = (%s)CPU->D[(Opcode >> %d) & 7];\n", dest, szc, rsft); - break; - - case EA_AREG: - if (current_size == SIZE_BYTE) - { - wf_op("\t// can't read byte from Ax registers !\n"); - wf_op("\tCPU->Status |= C68K_FAULTED;\n"); - wf_op("\tCCnt = 0;\n"); - wf_op("\tgoto C68k_Exec_Really_End;\n"); - } - else wf_op("\t%s = (%s)CPU->A[(Opcode >> %d) & 7];\n", dest, szc, rsft); - break; -/* - case EA_DREG: - case EA_AREG: - wf_op("\t%s = %s(adr);\n", dest, szcf); - break; -*/ - case EA_A32: - case EA_D8AX: - case EA_D8PX: - case EA_D16A: - case EA_D16P: - case EA_A16: - case EA_ADEC: - case EA_ADEC7: - case EA_AIND: - case EA_AINC: - case EA_AINC7: - mem_op("\tREAD_%s_F(adr, %s)\n", sz, dest); - break; - - case EA_IMM: - switch (current_size) - { - case SIZE_BYTE: - wf_op("\t%s = FETCH_BYTE;\n", dest); - wf_op("\tPC += 2;\n"); - break; - - case SIZE_WORD: - wf_op("\t%s = FETCH_WORD;\n", dest); - wf_op("\tPC += 2;\n"); - break; - - case SIZE_LONG: - wf_op("\t%s = FETCH_LONG;\n", dest); - wf_op("\tPC += 4;\n"); - break; - } - break; - } -} - -static void _ea_read(u32 ea, u32 rsft) -{ - _ea_read_(ea, rsft, "res"); -} - -static void _ea_read_src(u32 ea, u32 rsft) -{ - _ea_read_(ea, rsft, "src"); -} - -static void _ea_read_dst(u32 ea, u32 rsft) -{ - _ea_read_(ea, rsft, "dst"); -} - -static void _ea_read_sx_(u32 ea, u32 rsft, char dest[4]) -{ - char sz[8]; - - switch (current_size) - { - case SIZE_BYTE: - strcpy(sz, "BYTE"); - break; - - case SIZE_WORD: - strcpy(sz, "WORD"); - break; - - case SIZE_LONG: - strcpy(sz, "LONG"); - break; - } - - switch (ea) - { - case EA_DREG: - wf_op("\t%s = (s32)(%s)CPU->D[(Opcode >> %d) & 7];\n", dest, szcs, rsft); - break; - - case EA_AREG: - if (current_size == SIZE_BYTE) - { - wf_op("\t// can't read byte from Ax registers !\n"); - wf_op("\tCPU->Status |= C68K_FAULTED;\n"); - wf_op("\tCCnt = 0;\n"); - wf_op("\tgoto C68k_Exec_Really_End;\n"); - } - else wf_op("\t%s = (s32)(%s)CPU->A[(Opcode >> %d) & 7];\n", dest, szcs, rsft); - break; -/* - case EA_DREG: - case EA_AREG: - wf_op("\t%s = (s32)(%s(adr));\n", dest, szcsf); - break; -*/ - case EA_A32: - case EA_D8AX: - case EA_D8PX: - case EA_D16A: - case EA_D16P: - case EA_A16: - case EA_ADEC: - case EA_ADEC7: - case EA_AIND: - case EA_AINC: - case EA_AINC7: - mem_op("\tREADSX_%s_F(adr, %s)\n", sz, dest); - break; - - case EA_IMM: - switch (current_size) - { - case SIZE_BYTE: - wf_op("\t%s = (s32)(%s(PC)));\n", dest, szcsf); - wf_op("\tPC += 2;\n"); - break; - - case SIZE_WORD: - wf_op("\t%s = (s32)(%s)FETCH_WORD;\n", dest, szcs); - wf_op("\tPC += 2;\n"); - break; - - case SIZE_LONG: - wf_op("\t%s = (s32)(%s)FETCH_LONG;\n", dest, szcs); - wf_op("\tPC += 4;\n"); - break; - } - break; - } -} - -static void _ea_read_sx(u32 ea, u32 rsft) -{ - _ea_read_sx_(ea, rsft, "res"); -} - -static void _ea_read_src_sx(u32 ea, u32 rsft) -{ - _ea_read_sx_(ea, rsft, "src"); -} - -static void _ea_write(u32 ea, u32 rsft) -{ - char sz[8]; - - switch (current_size) - { - case SIZE_BYTE: - strcpy(sz, "BYTE"); - break; - - case SIZE_WORD: - strcpy(sz, "WORD"); - break; - - case SIZE_LONG: - strcpy(sz, "LONG"); - break; - } - - switch (ea) - { - case EA_DREG: - wf_op("\t%s(&CPU->D[(Opcode >> %d) & 7])) = res;\n", szcf, -rsft); - break; - - case EA_AREG: - // writes in Ax registers are always 32 bits sized - wf_op("\tCPU->A[(Opcode >> %d) & 7] = res;\n", rsft); - break; -/* - case EA_DREG: - case EA_AREG: - wf_op("\t%s(adr) = res;\n", szcf); - break; -*/ - case EA_A32: - case EA_D8AX: - case EA_D8PX: - case EA_D16A: - case EA_D16P: - case EA_A16: - case EA_ADEC: - case EA_ADEC7: - case EA_AIND: - case EA_AINC: - case EA_AINC7: - mem_op("\tWRITE_%s_F(adr, res)\n", sz); - break; - } -} - -// misc function -///////////////// - -static u32 get_current_opcode_base(void) -{ - u32 base; - - base = current_op->op_base; - if (current_op->eam_sft != -1) base += (current_eam & 7) << current_op->eam_sft; - if (current_op->reg_sft != -1) base += (current_reg & 7) << current_op->reg_sft; - if (current_op->eam2_sft != -1) base += (current_eam2 & 7) << current_op->eam2_sft; - if (current_op->reg2_sft != -1) base += (current_reg2 & 7) << current_op->reg2_sft; - if (current_op->size_type == 1) base += (current_size - 1) << current_op->size_sft; - else if (current_op->size_type == 2) base += (current_size & 3) << current_op->size_sft; - - return base; -} - -static void start_all(int v) -{ - u32 base; - - base = get_current_opcode_base(); - - // generate jump table - gen_opjumptable(base); - - // generate label & declarations - start_op(base, v); -} - -static void set_current_size(u32 sz) -{ - current_size = sz; - switch(current_size) - { - case SIZE_BYTE: - current_bits_mask = 0xFF; - current_sft_mask = 7; - strcpy(szc, "u8"); - strcpy(szcf, "*(BYTE_OFF + (u8*)"); - strcpy(szcs, "s8"); - strcpy(szcsf, "*(BYTE_OFF + (s8*)"); - break; - - case SIZE_WORD: - current_bits_mask = 0xFFFF; - current_sft_mask = 15; - strcpy(szc, "u16"); - strcpy(szcf, "*(WORD_OFF + (u16*)"); - strcpy(szcs, "s16"); - strcpy(szcsf, "*(WORD_OFF + (s16*)"); - break; - - case SIZE_LONG: - current_bits_mask = 0xFFFFFFFF; - current_sft_mask = 31; - strcpy(szc, "u32"); - strcpy(szcf, "*((u32*)"); - strcpy(szcs, "s32"); - strcpy(szcsf, "*((s32*)"); - break; - } -} - -// gen privilege exception (happen when S flag is not set) -static void gen_privilege_exception(char *pre) -{ - // swap A7 and USP (because S not set) - wf_op("%sres = CPU->USP;\n", pre); - wf_op("%sCPU->USP = CPU->A[7];\n", pre); - wf_op("%sCPU->A[7] = res;\n", pre); - - // get vector & add cycle - wf_op("%sres = C68K_PRIVILEGE_VIOLATION_EX;\n", pre); - adds_CCnt("c68k_exception_cycle_table[res]"); - - // we will do some mem/io access - do_pre_io(); - - // push PC and SR - mem_op("%sPUSH_32_F(PC - CPU->BasePC)\n", pre); - mem_op("%sPUSH_16_F(GET_SR)\n", pre); - - // adjust SR - wf_op("%sCPU->flag_S = C68K_SR_S;\n", pre); - - // fetch new PC - mem_op("%sREAD_LONG_F(res * 4, PC)\n", pre); - wf_op("%sSET_PC(PC)\n", pre); -} - -static void gen_exception(char *pre, char* exception) -{ - // swap A7 and USP if needed - wf_op("%sif (!CPU->flag_S)\n", pre); - wf_op("%s{\n", pre); - wf_op("%s\tres = CPU->USP;\n", pre); - wf_op("%s\tCPU->USP = CPU->A[7];\n", pre); - wf_op("%s\tCPU->A[7] = res;\n", pre); - wf_op("%s}\n", pre); - - // get vector & add cycle - wf_op("%sres = %s;\n", pre, exception); - adds_CCnt("c68k_exception_cycle_table[res]"); - - // we will do some mem/io access - do_pre_io(); - - // push PC and SR - mem_op("%sPUSH_32_F(PC - CPU->BasePC)\n", pre); - mem_op("%sPUSH_16_F(GET_SR)\n", pre); - - // adjust SR - wf_op("%sCPU->flag_S = C68K_SR_S;\n", pre); - - // fetch new PC - mem_op("%sREAD_LONG_F(res * 4, PC)\n", pre); - wf_op("%sSET_PC(PC)\n", pre); -} - diff --git a/yabause/src/carbon/CMakeLists.txt b/yabause/src/carbon/CMakeLists.txt deleted file mode 100644 index 219de3e075..0000000000 --- a/yabause/src/carbon/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -project(yabause-carbon) - -find_library(CARBON_LIBRARY carbon) - -if (NOT CARBON_LIBRARY) - return() -endif() - -set(yabause_carbon_SOURCES main.c settings.c settings.h cpustatus.c cpustatus.h) - -add_executable(yabause-carbon ${yabause_carbon_SOURCES}) -target_link_libraries(yabause-carbon yabause ${YABAUSE_LIBRARIES} ${CARBON_LIBRARY}) - -if (NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app" - COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/Yabause.app" "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app" - DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/Yabause.app" - ) -endif() - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/MacOS" - COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/MacOS" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app" -) - -add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/MacOS/yabause" - COMMAND ${CMAKE_COMMAND} -E copy $ "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/MacOS/yabause" - DEPENDS yabause-carbon - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/MacOS" -) - -add_custom_target(yabause-carbon-app ALL - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/MacOS/yabause") diff --git a/yabause/src/carbon/Makefile.am b/yabause/src/carbon/Makefile.am deleted file mode 100644 index b2822d2096..0000000000 --- a/yabause/src/carbon/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -EXTRA_DIST = build_dmg.sh Yabause.app/Contents/Info.plist Yabause.app/Contents/Resources/yabause.icns \ - Yabause.app/Contents/Resources/cpustatus.nib/classes.nib Yabause.app/Contents/Resources/cpustatus.nib/info.nib \ - Yabause.app/Contents/Resources/cpustatus.nib/objects.xib \ - Yabause.app/Contents/Resources/menu.nib/classes.nib Yabause.app/Contents/Resources/menu.nib/info.nib \ - Yabause.app/Contents/Resources/menu.nib/objects.xib \ - Yabause.app/Contents/Resources/preferences.nib/classes.nib Yabause.app/Contents/Resources/preferences.nib/info.nib \ - Yabause.app/Contents/Resources/preferences.nib/objects.xib -bin_PROGRAMS = yabause -yabause_SOURCES = main.c settings.c settings.h cpustatus.c cpustatus.h -yabause_CFLAGS = $(YAB_CFLAGS) -yabause_LDADD = $(YAB_LIBS) ../libyabause.a - -all-local: - if [ ! -e Yabause.app/Contents/MacOS ]; then mkdir Yabause.app/Contents/MacOS; fi - cp yabause Yabause.app/Contents/MacOS - if [ ! -e Yabause.app/Contents/Frameworks ]; then mkdir Yabause.app/Contents/Frameworks; fi - if [ ! -e Yabause.app/Contents/Frameworks/SDL.framework ]; then \ - if [ -e /Library/Frameworks/SDL.framework ]; then \ - cp -R /Library/Frameworks/SDL.framework Yabause.app/Contents/Frameworks; \ - elif [ -e ~/Library/Frameworks/SDL.framework ]; then \ - cp -R ~/Library/Frameworks/SDL.framework Yabause.app/Contents/Frameworks; \ - fi; \ - fi diff --git a/yabause/src/carbon/Yabause.app/Contents/Info.plist b/yabause/src/carbon/Yabause.app/Contents/Info.plist deleted file mode 100644 index 9e3e0c781f..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleExecutable - yabause - CFBundleIconFile - yabause.icns - CFBundleIdentifier - org.yabause.Yabause - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Yabause - CFBundlePackageType - APPL - CFBundleShortVersionString - 0.9.10 - CFBundleVersion - 0.9.10 - - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/classes.nib b/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/classes.nib deleted file mode 100644 index ea58db1189..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/classes.nib +++ /dev/null @@ -1,4 +0,0 @@ -{ -IBClasses = (); -IBVersion = 1; -} diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/info.nib b/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/info.nib deleted file mode 100644 index 79be5a82ec..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/info.nib +++ /dev/null @@ -1,67 +0,0 @@ - - - - - IBDocumentLocation - 76 101 356 240 0 0 1280 1002 - IBFramework Version - 446.1 - IBLockedObjects - - 223 - 239 - 240 - 241 - 242 - 243 - 244 - 245 - 232 - 235 - 246 - 247 - 248 - 249 - 250 - 251 - 252 - 253 - 254 - 258 - 259 - 261 - 277 - 296 - 286 - 271 - 267 - 299 - 300 - 306 - 304 - 270 - 308 - 303 - 266 - 298 - 273 - 302 - 274 - 301 - 269 - 311 - 310 - 295 - - IBOldestOS - 1 - IBOpenObjects - - 166 - - IBSystem Version - 8L2127 - targetFramework - IBCarbonFramework - - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/objects.xib b/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/objects.xib deleted file mode 100644 index 025d5f41b5..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/cpustatus.nib/objects.xib +++ /dev/null @@ -1,1229 +0,0 @@ - - - IBCarbonFramework - - NSApplication - - - - 404 468 747 1080 - Processor Status - - 0 0 343 612 - 0 0 612 343 - - - 6 20 323 296 - 20 6 276 317 - - - 36 36 49 73 - 16 30 37 13 - TRUE - 1 - R0 - -2 - - - 57 36 70 73 - 16 51 37 13 - TRUE - 1 - R1 - -2 - - - 78 36 91 73 - 16 72 37 13 - TRUE - 1 - R2 - -2 - - - 99 36 112 73 - 16 93 37 13 - TRUE - 1 - R3 - -2 - - - 120 36 133 73 - 16 114 37 13 - TRUE - 1 - R4 - -2 - - - 141 36 154 73 - 16 135 37 13 - TRUE - 1 - R5 - -2 - - - 162 36 175 73 - 16 156 37 13 - TRUE - 1 - R6 - -2 - - - 183 36 196 73 - 16 177 37 13 - TRUE - 1 - R7 - -2 - - - 36 162 49 199 - 142 30 37 13 - TRUE - 1 - R8 - -2 - - - 57 162 70 199 - 142 51 37 13 - TRUE - 1 - R9 - -2 - - - 78 162 91 199 - 142 72 37 13 - TRUE - 1 - R10 - -2 - - - 99 162 112 199 - 142 93 37 13 - TRUE - 1 - R11 - -2 - - - 120 162 133 199 - 142 114 37 13 - TRUE - 1 - R12 - -2 - - - 141 162 154 199 - 142 135 37 13 - TRUE - 1 - R13 - -2 - - - 162 162 175 199 - 142 156 37 13 - TRUE - 1 - R14 - -2 - - - 183 162 196 199 - 142 177 37 13 - TRUE - 1 - R15 - -2 - - - 38 84 48 151 - 64 32 67 10 - cpus - 1 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 206 36 219 73 - 16 200 37 13 - TRUE - 1 - MACH - -2 - - - 208 84 218 151 - 64 202 67 10 - cpus - 17 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 206 162 219 199 - 142 200 37 13 - TRUE - 1 - MACL - -2 - - - 229 36 242 73 - 16 223 37 13 - TRUE - 1 - GBR - -2 - - - 231 84 241 151 - 64 225 67 10 - cpus - 19 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 229 162 242 199 - 142 223 37 13 - TRUE - 1 - VBR - -2 - - - 252 36 265 73 - 16 246 37 13 - TRUE - 1 - PC - -2 - - - 252 162 265 199 - 142 246 37 13 - TRUE - 1 - PR - -2 - - - 59 84 69 151 - 64 53 67 10 - cpus - 2 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 80 84 90 151 - 64 74 67 10 - cpus - 3 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 101 84 111 151 - 64 95 67 10 - cpus - 4 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 122 84 132 151 - 64 116 67 10 - cpus - 5 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 143 84 153 151 - 64 137 67 10 - cpus - 6 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 164 84 174 151 - 64 158 67 10 - cpus - 7 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 185 84 195 151 - 64 179 67 10 - cpus - 8 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 252 84 262 151 - 64 246 67 10 - cpus - 21 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 38 210 48 277 - 190 32 67 10 - cpus - 9 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 59 210 69 277 - 190 53 67 10 - cpus - 10 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 80 210 90 277 - 190 74 67 10 - cpus - 11 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 101 210 111 277 - 190 95 67 10 - cpus - 12 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 122 210 132 277 - 190 116 67 10 - cpus - 13 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 143 210 153 277 - 190 137 67 10 - cpus - 14 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 164 210 174 277 - 190 158 67 10 - cpus - 15 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 185 210 195 277 - 190 179 67 10 - cpus - 16 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 208 210 218 277 - 190 202 67 10 - cpus - 18 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 231 210 241 277 - 190 225 67 10 - cpus - 20 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 252 210 262 277 - 190 246 67 10 - cpus - 22 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 273 81 286 280 - 61 267 199 13 - TRUE - 1 - Status bits go here - -1 - - - 294 36 307 73 - 16 288 37 13 - TRUE - 1 - SR - -2 - - - 296 84 306 277 - 64 290 193 10 - cpus - 23 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - Master - - - 6 316 323 592 - 316 6 276 317 - - - 36 332 49 369 - 16 30 37 13 - TRUE - 1 - R0 - -2 - - - 57 332 70 369 - 16 51 37 13 - TRUE - 1 - R1 - -2 - - - 78 332 91 369 - 16 72 37 13 - TRUE - 1 - R2 - -2 - - - 99 332 112 369 - 16 93 37 13 - TRUE - 1 - R3 - -2 - - - 120 332 133 369 - 16 114 37 13 - TRUE - 1 - R4 - -2 - - - 141 332 154 369 - 16 135 37 13 - TRUE - 1 - R5 - -2 - - - 162 332 175 369 - 16 156 37 13 - TRUE - 1 - R6 - -2 - - - 183 332 196 369 - 16 177 37 13 - TRUE - 1 - R7 - -2 - - - 36 458 49 495 - 142 30 37 13 - TRUE - 1 - R8 - -2 - - - 57 458 70 495 - 142 51 37 13 - TRUE - 1 - R9 - -2 - - - 78 458 91 495 - 142 72 37 13 - TRUE - 1 - R10 - -2 - - - 99 458 112 495 - 142 93 37 13 - TRUE - 1 - R11 - -2 - - - 120 458 133 495 - 142 114 37 13 - TRUE - 1 - R12 - -2 - - - 141 458 154 495 - 142 135 37 13 - TRUE - 1 - R13 - -2 - - - 162 458 175 495 - 142 156 37 13 - TRUE - 1 - R14 - -2 - - - 183 458 196 495 - 142 177 37 13 - TRUE - 1 - R15 - -2 - - - 38 380 48 447 - 64 32 67 10 - cpus - 31 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 206 332 219 369 - 16 200 37 13 - TRUE - 1 - MACH - -2 - - - 208 380 218 447 - 64 202 67 10 - cpus - 47 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 206 458 219 495 - 142 200 37 13 - TRUE - 1 - MACL - -2 - - - 229 332 242 369 - 16 223 37 13 - TRUE - 1 - GBR - -2 - - - 231 380 241 447 - 64 225 67 10 - cpus - 49 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 229 458 242 495 - 142 223 37 13 - TRUE - 1 - VBR - -2 - - - 252 332 265 369 - 16 246 37 13 - TRUE - 1 - PC - -2 - - - 252 458 265 495 - 142 246 37 13 - TRUE - 1 - PR - -2 - - - 59 380 69 447 - 64 53 67 10 - cpus - 32 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 80 380 90 447 - 64 74 67 10 - cpus - 33 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 101 380 111 447 - 64 95 67 10 - cpus - 34 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 122 380 132 447 - 64 116 67 10 - cpus - 35 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 143 380 153 447 - 64 137 67 10 - cpus - 36 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 164 380 174 447 - 64 158 67 10 - cpus - 37 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 185 380 195 447 - 64 179 67 10 - cpus - 38 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 252 380 262 447 - 64 246 67 10 - cpus - 51 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 38 506 48 573 - 190 32 67 10 - cpus - 39 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 59 506 69 573 - 190 53 67 10 - cpus - 40 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 80 506 90 573 - 190 74 67 10 - cpus - 41 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 101 506 111 573 - 190 95 67 10 - cpus - 42 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 122 506 132 573 - 190 116 67 10 - cpus - 43 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 143 506 153 573 - 190 137 67 10 - cpus - 44 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 164 506 174 573 - 190 158 67 10 - cpus - 45 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 185 506 195 573 - 190 179 67 10 - cpus - 46 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 208 506 218 573 - 190 202 67 10 - cpus - 48 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 231 506 241 573 - 190 225 67 10 - cpus - 50 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 252 506 262 573 - 190 246 67 10 - cpus - 52 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - 273 377 286 576 - 61 267 199 13 - TRUE - 1 - Status bits go here - -1 - - - 294 332 307 369 - 16 288 37 13 - TRUE - 1 - SR - -2 - - - 296 380 306 573 - 64 290 193 10 - cpus - 53 - FALSE - -5 - TRUE - 1 - -1 - TRUE - TRUE - - - Slave - - - - FALSE - FALSE - FALSE - FALSE - FALSE - TRUE - 5 - 5 - FALSE - TRUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - File's Owner - - Window - - - 313 - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/classes.nib b/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/classes.nib deleted file mode 100644 index c4b887e72b..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/classes.nib +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IBVersion - 1 - - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/info.nib b/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/info.nib deleted file mode 100644 index 44cc4f505c..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/info.nib +++ /dev/null @@ -1,18 +0,0 @@ - - - - - IBFramework Version - 740 - IBOldestOS - 6 - IBOpenObjects - - 167 - - IBSystem Version - 10C540 - targetFramework - IBCarbonFramework - - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/objects.xib b/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/objects.xib deleted file mode 100644 index c8fc38239d..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/load_dialog.nib/objects.xib +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - Address - 55 20 71 72 - - - conf - 50 - Browse - 20 239 40 309 - - - conf - 1 - 23 23 39 228 - - - FALSE - FALSE - FALSE - FALSE - 5 - Load - - - - - - conf - 2 - 55 83 71 306 - - - - 0 0 94 329 - - 72 111 166 440 - 60 0 778 1280 - - - - - - - - - - - - - - Dialog - - File's Owner - - - IBCarbonFramework - 320 - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/classes.nib b/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/classes.nib deleted file mode 100644 index c4b887e72b..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/classes.nib +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IBVersion - 1 - - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/info.nib b/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/info.nib deleted file mode 100644 index f17a327dc0..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/info.nib +++ /dev/null @@ -1,18 +0,0 @@ - - - - - IBFramework Version - 740 - IBOldestOS - 6 - IBOpenObjects - - 195 - - IBSystem Version - 10C540 - targetFramework - IBCarbonFramework - - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/objects.xib b/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/objects.xib deleted file mode 100644 index 6c19b8b5ad..0000000000 Binary files a/yabause/src/carbon/Yabause.app/Contents/Resources/menu.nib/objects.xib and /dev/null differ diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/classes.nib b/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/classes.nib deleted file mode 100644 index ea58db1189..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/classes.nib +++ /dev/null @@ -1,4 +0,0 @@ -{ -IBClasses = (); -IBVersion = 1; -} diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/info.nib b/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/info.nib deleted file mode 100644 index 8bec016c9c..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/info.nib +++ /dev/null @@ -1,18 +0,0 @@ - - - - - IBDocumentLocation - 267 126 356 240 0 0 1280 1002 - IBFramework Version - 446.1 - IBOpenObjects - - 166 - - IBSystem Version - 8P2137 - targetFramework - IBCarbonFramework - - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/objects.xib b/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/objects.xib deleted file mode 100644 index 607de62a48..0000000000 --- a/yabause/src/carbon/Yabause.app/Contents/Resources/preferences.nib/objects.xib +++ /dev/null @@ -1,775 +0,0 @@ - - - IBCarbonFramework - - NSApplication - - - - 81 82 409 437 - Yabause preferences - - 0 0 328 355 - - - 12 -1 328 360 - - - 49 -1 328 360 - - - 50 19 116 340 - - - 81 38 97 243 - conf - 1 - - - 79 254 99 324 - conf - 50 - Browse - - - Bios - - - 124 19 218 340 - - - 155 38 171 243 - conf - 2 - - - 153 254 173 324 - conf - 51 - Browse - - - 182 35 202 324 - conf - 3 - - Popup: - - - Dummy CD - - - ISO or CUE file - - - Cdrom device - - - - - - Cdrom - - - 226 19 290 340 - - - 254 35 274 324 - conf - 4 - - Popup: - - - Auto-detect - - - Japan (NTSC) - - - Asia (NTSC) - - - North America (NTSC) - - - Central/South America (NTSC) - - - Korea (NTSC) - - - Asia (PAL) - - - Europe + others (PAL) - - - Central/South America (PAL) - - - - - - Region - - - tabs - 129 - 2 - - - 49 -1 328 360 - - - 50 19 146 340 - - - 78 35 98 324 - conf - 5 - - Popup: - - - TRUE - Dummy Video Interface - - - OpenGL Video Interface - - - Software Video Interface - - - - - - 112 35 130 196 - conf - 11 - Enable auto frameskip - - - Video core - - - 148 19 242 340 - - - 207 98 223 226 - FALSE - 224 - - - 176 35 192 87 - Width - - - 200 35 216 87 - Height - - - 178 237 192 324 - FALSE - Keep ratio - - - 177 98 193 226 - FALSE - 320 - - - Resolution - - - 244 19 308 340 - - - 272 35 292 324 - conf - 6 - - Popup: - - - Dummy Sound Interface - - - SDL Sound Interface - - - - - - Sound core - - - tabs - 130 - 2 - - - 49 -1 328 360 - - - 50 19 144 340 - - - 81 38 97 243 - conf - 7 - - - 79 254 99 324 - conf - 52 - Browse - - - 108 35 128 324 - conf - 8 - - Popup: - - - None - - - Pro Action Replay - - - 4 Mbit Backup Ram - - - 8 Mbit Backup Ram - - - 16 Mbit Backup Ram - - - 32 Mbit Backup Ram - - - 8 Mbit Dram - - - 32 Mbit Dram - - - Netlink - - - 16 Mbit ROM - - - - - - Cartridge - - - 152 19 218 340 - - - 183 38 199 243 - conf - 9 - - - 181 254 201 324 - conf - 53 - Browse - - - Memory - - - 226 19 292 340 - - - 257 38 273 243 - conf - 10 - - - 255 254 275 324 - conf - 54 - Browse - - - Mpeg ROM - - - tabs - 131 - 2 - - - 49 -1 328 360 - - - 64 19 80 115 - Up - - - 65 126 81 167 - conf - 31 - - - 90 19 106 115 - Right - - - 91 126 107 167 - conf - 32 - - - 116 19 132 115 - Down - - - 117 126 133 167 - conf - 33 - - - 142 19 158 115 - Left - - - 143 126 159 167 - conf - 34 - - - 168 19 184 115 - Right trigger - - - 169 126 185 167 - conf - 35 - - - 194 19 210 115 - Left trigger - - - 195 126 211 167 - conf - 36 - - - 220 19 236 115 - Start - - - 221 126 237 167 - conf - 37 - - - 65 296 81 337 - conf - 38 - - - 64 189 80 285 - A - - - 117 296 133 337 - conf - 40 - - - 142 189 158 285 - X - - - 194 189 210 285 - Z - - - 169 296 185 337 - conf - 42 - - - 195 296 211 337 - conf - 43 - - - 90 189 106 285 - B - - - 116 189 132 285 - C - - - 91 296 107 337 - conf - 39 - - - 143 296 159 337 - conf - 41 - - - 168 189 184 285 - Y - - - 54 178 296 179 - - - tabs - 132 - Input - 2 - - - tabs - 128 - - - contentResID - 0 - tabEnabled - 1 - tabName - General - userPane - - - - contentResID - 0 - tabEnabled - 1 - tabName - Video/Sound - userPane - - - - contentResID - 0 - tabEnabled - 1 - tabName - Memory - userPane - - - - contentResID - 0 - tabEnabled - 1 - tabName - Input - userPane - - - - - - - FALSE - 5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 23642 -6178 23658 -6082 - Up - - - 23653 -6048 23649 -6053 - - - 23647 -6173 23663 -6077 - Up - - - 23658 -6043 23654 -6048 - - - - - - - - - 23648 -6053 23644 -6058 - - - 23585 -6183 23601 -6087 - Right - - - 23700 -6053 23696 -6058 - - - 23611 -6183 23627 -6087 - Down - - - 23726 -6053 23722 -6058 - - - 23715 -6183 23731 -6087 - Start - - - 23622 -6053 23618 -6058 - - - 23689 -6183 23705 -6087 - Left trigger - - - 23596 -6053 23592 -6058 - - - 23674 -6053 23670 -6058 - - - 23663 -6183 23679 -6087 - Right trigger - - - 23570 -6053 23566 -6058 - - - 23559 -6183 23575 -6087 - Up - - - 23637 -6183 23653 -6087 - Left - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Dialog - - File's Owner - - NSCustomView2 - - - 313 - diff --git a/yabause/src/carbon/Yabause.app/Contents/Resources/yabause.icns b/yabause/src/carbon/Yabause.app/Contents/Resources/yabause.icns deleted file mode 100644 index a039119928..0000000000 Binary files a/yabause/src/carbon/Yabause.app/Contents/Resources/yabause.icns and /dev/null differ diff --git a/yabause/src/carbon/build_dmg.sh b/yabause/src/carbon/build_dmg.sh deleted file mode 100644 index 3f3e2573bb..0000000000 --- a/yabause/src/carbon/build_dmg.sh +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2006 Guillaume Duhamel -# Copyright 2006 Lawrence Sebald -# Copyright 2007 Anders Montonen -# -# This file is part of Yabause. -# -# Yabause is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# Yabause is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Yabause; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - -hdiutil create -megabytes 20 tmp.dmg -layout NONE -fs HFS+ -volname Yabause -ov -tmp=`hdid tmp.dmg` -disk=`echo $tmp | cut -f 1 -d\ ` -cp -R Yabause.app /Volumes/Yabause/ -cp ../../ChangeLog /Volumes/Yabause/ -cp ../../README /Volumes/Yabause/ -cp ../../README.MAC /Volumes/Yabause/ -cp ../../AUTHORS /Volumes/Yabause/ -cp ../../COPYING /Volumes/Yabause/ -hdiutil eject $disk -hdiutil convert -format UDZO tmp.dmg -o Yabause.dmg -rm tmp.dmg diff --git a/yabause/src/carbon/cpustatus.c b/yabause/src/carbon/cpustatus.c deleted file mode 100644 index e672abea11..0000000000 --- a/yabause/src/carbon/cpustatus.c +++ /dev/null @@ -1,206 +0,0 @@ -/* Copyright 2006 Anders Montonen - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "cpustatus.h" -#include "../sh2core.h" - -/* Dialog field IDs */ - -#define SLAVE_ID_OFFSET 30 - -#define R0_ID 1 -#define R1_ID 2 -#define R2_ID 3 -#define R3_ID 4 -#define R4_ID 5 -#define R5_ID 6 -#define R6_ID 7 -#define R7_ID 8 -#define R8_ID 9 -#define R9_ID 10 -#define R10_ID 11 -#define R11_ID 12 -#define R12_ID 13 -#define R13_ID 14 -#define R14_ID 15 -#define R15_ID 16 -#define MACH_ID 17 -#define MACL_ID 18 -#define GBR_ID 19 -#define VBR_ID 20 -#define PC_ID 21 -#define PR_ID 22 -#define SR_ID 23 - -static WindowRef CPUStatusWindow; - -static OSStatus CPUStatusWindowEventHandler(EventHandlerCallRef myHandler, - EventRef theEvent, - void *userData) -{ - OSStatus result = eventNotHandledErr; - WindowRef window; - MenuRef menu; - - switch(GetEventKind(theEvent)) - { - case kEventWindowClose: - GetEventParameter(theEvent, kEventParamDirectObject, typeWindowRef, - 0, sizeof(typeWindowRef), 0, &window); - DisposeWindow(window); - menu = GetMenuRef(1); - ChangeMenuItemAttributes(menu, 4, 0, kMenuItemAttrHidden); - ChangeMenuItemAttributes(menu, 5, kMenuItemAttrHidden, 0); - - result = noErr; - break; - } - - return result; -} - -void ShowCPUStatusWindow(void) -{ - IBNibRef nib; - - EventTypeSpec eventList[] = { {kEventClassWindow, kEventWindowClose} }; - - CreateNibReference(CFSTR("cpustatus"), &nib); - CreateWindowFromNib(nib, CFSTR("Window"), &CPUStatusWindow); - ShowWindow(CPUStatusWindow); - - InstallWindowEventHandler(CPUStatusWindow, - NewEventHandlerUPP(CPUStatusWindowEventHandler), - GetEventTypeCount(eventList), - eventList, CPUStatusWindow, NULL); - - UpdateCPUStatusWindow(); -} - -void HideCPUStatusWindow(void) -{ - DisposeWindow(CPUStatusWindow); -} - -static void SetSRString(u32 SR, CFMutableStringRef s) -{ - int ii; - - for(ii = 0; ii < 32; ii++) - { - if(SR & 0x80000000) - CFStringAppendCString(s, "1", kCFStringEncodingASCII); - else - CFStringAppendCString(s, "0", kCFStringEncodingASCII); - - SR <<= 1; - } -} - -static void SetRegisterValue(const int controlId, CFStringRef s) -{ - ControlID id; - ControlRef control; - - id.signature = 'cpus'; - id.id = controlId; - GetControlByID(CPUStatusWindow, &id, &control); - SetControlData(control, kControlEditTextPart, - kControlEditTextCFStringTag, sizeof(CFStringRef), &s); - -} - -void UpdateCPUStatusWindow(void) -{ - CFStringRef s; - CFMutableStringRef ms; - sh2regs_struct master = {0}; - sh2regs_struct slave = {0}; - int ii = 0; - int srNumber = 0; - - if(MSH2) - SH2GetRegisters(MSH2, &master); - - if(SSH2) - SH2GetRegisters(SSH2, &slave); - - /* Master registers */ - for(ii = 0; ii < 16; ii++) - { - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), master.R[ii]); - SetRegisterValue(ii+1, s); - } - - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), master.MACH); - SetRegisterValue(MACH_ID, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), master.MACL); - SetRegisterValue(MACL_ID, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), master.GBR); - SetRegisterValue(GBR_ID, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), master.VBR); - SetRegisterValue(VBR_ID, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), master.PC); - SetRegisterValue(PC_ID, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), master.PR); - SetRegisterValue(PR_ID, s); - - ms = CFStringCreateMutable(kCFAllocatorDefault, 32); - SetSRString(master.SR.all, ms); - SetRegisterValue(SR_ID, ms); - - /* Slave registers */ - for(ii = 0; ii < 16; ii++) - { - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), slave.R[ii]); - SetRegisterValue(ii+1+SLAVE_ID_OFFSET, s); - } - - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), slave.MACH); - SetRegisterValue(MACH_ID+SLAVE_ID_OFFSET, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), slave.MACL); - SetRegisterValue(MACL_ID+SLAVE_ID_OFFSET, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), slave.GBR); - SetRegisterValue(GBR_ID+SLAVE_ID_OFFSET, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), slave.VBR); - SetRegisterValue(VBR_ID+SLAVE_ID_OFFSET, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), slave.PC); - SetRegisterValue(PC_ID+SLAVE_ID_OFFSET, s); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%x"), slave.PR); - SetRegisterValue(PR_ID+SLAVE_ID_OFFSET, s); - ms = CFStringCreateMutable(kCFAllocatorDefault, 32); - SetSRString(slave.SR.all, ms); - SetRegisterValue(SR_ID+SLAVE_ID_OFFSET, ms); -} diff --git a/yabause/src/carbon/cpustatus.h b/yabause/src/carbon/cpustatus.h deleted file mode 100644 index 58cb7df205..0000000000 --- a/yabause/src/carbon/cpustatus.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2006 Anders Montonen - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CPUSTATUS_H_ -#define CPUSTATUS_H_ - -void ShowCPUStatusWindow(void); -void HideCPUStatusWindow(void); -void UpdateCPUStatusWindow(void); - -#endif /* CPUSTATUS_H_ */ diff --git a/yabause/src/carbon/main.c b/yabause/src/carbon/main.c deleted file mode 100644 index e89acccf91..0000000000 --- a/yabause/src/carbon/main.c +++ /dev/null @@ -1,609 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2006 Anders Montonen - Copyright 2010 Alex Marshall - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include - -#include "../core.h" -#include "../memory.h" -#include "settings.h" -#include "cpustatus.h" -#include "../yabause.h" - -#define YUI_MENU_EMULATION 1 -#define YUI_MENU_DEBUG 2 - -#define YUI_COMMAND_RESET 1 -#define YUI_COMMAND_PAUSE 2 -#define YUI_COMMAND_RESUME 3 -#define YUI_COMMAND_SHOW_CPU 4 -#define YUI_COMMAND_HIDE_CPU 5 -#define YUI_COMMAND_TOGGLE_NBG0 6 -#define YUI_COMMAND_TOGGLE_NBG1 7 -#define YUI_COMMAND_TOGGLE_NBG2 8 -#define YUI_COMMAND_TOGGLE_NBG3 9 -#define YUI_COMMAND_TOGGLE_RBG0 10 -#define YUI_COMMAND_TOGGLE_VDP1 11 -#define YUI_COMMAND_TOGGLE_FULLSCREEN 12 -#define YUI_COMMAND_LOAD_BINARY 13 -#define YUI_COMMAND_LOAD_AND_EXECUTE 14 -#define YUI_COMMAND_SAVE_BINARY 15 - -AGLContext myAGLContext = NULL; -WindowRef myWindow = NULL; -yabauseinit_struct yinit; - -M68K_struct * M68KCoreList[] = { -&M68KDummy, -#ifdef HAVE_C68K -&M68KC68K, -#endif -#ifdef HAVE_Q68 -&M68KQ68, -#endif -NULL -}; - -SH2Interface_struct *SH2CoreList[] = { -&SH2Interpreter, -&SH2DebugInterpreter, -NULL -}; - -PerInterface_struct *PERCoreList[] = { -&PERDummy, -NULL -}; - -CDInterface *CDCoreList[] = { -&DummyCD, -&ISOCD, -&ArchCD, -NULL -}; - -SoundInterface_struct *SNDCoreList[] = { -&SNDDummy, -#ifdef HAVE_LIBSDL -&SNDSDL, -#endif -NULL -}; - -VideoInterface_struct *VIDCoreList[] = { -&VIDDummy, -&VIDOGL, -&VIDSoft, -NULL -}; - -static EventLoopTimerRef EventTimer; -int load_file_core(char* file, char* addr, int type); - -void YuiIdle(EventLoopTimerRef a, void * b) -{ - PERCore->HandleEvents(); -} - -void read_settings(void) { - PerPad_struct * pad; - int i; - CFStringRef s; - yinit.percoretype = PERCORE_DUMMY; - yinit.sh2coretype = SH2CORE_INTERPRETER; - yinit.vidcoretype = VIDCORE_OGL; - yinit.m68kcoretype = M68KCORE_C68K; - s = CFPreferencesCopyAppValue(CFSTR("VideoCore"), - kCFPreferencesCurrentApplication); - if (s) - yinit.vidcoretype = CFStringGetIntValue(s) - 1; - yinit.sndcoretype = SNDCORE_DUMMY; - s = CFPreferencesCopyAppValue(CFSTR("SoundCore"), - kCFPreferencesCurrentApplication); - if (s) - yinit.sndcoretype = CFStringGetIntValue(s) - 1; - yinit.cdcoretype = CDCORE_ARCH; - s = CFPreferencesCopyAppValue(CFSTR("CDROMCore"), - kCFPreferencesCurrentApplication); - if (s) - yinit.cdcoretype = CFStringGetIntValue(s) - 1; - yinit.carttype = CART_NONE; - s = CFPreferencesCopyAppValue(CFSTR("CartType"), - kCFPreferencesCurrentApplication); - if (s) - yinit.carttype = CFStringGetIntValue(s) - 1; - yinit.regionid = 0; - s = CFPreferencesCopyAppValue(CFSTR("Region"), - kCFPreferencesCurrentApplication); - if (s) - yinit.regionid = CFStringGetIntValue(s) - 1; - - yinit.biospath = 0; - s = CFPreferencesCopyAppValue(CFSTR("BiosPath"), - kCFPreferencesCurrentApplication); - if (s) - yinit.biospath = strdup(CFStringGetCStringPtr(s, 0)); - yinit.cdpath = 0; - s = CFPreferencesCopyAppValue(CFSTR("CDROMDrive"), - kCFPreferencesCurrentApplication); - if (s) - yinit.cdpath = strdup(CFStringGetCStringPtr(s, 0)); - yinit.buppath = 0; - s = CFPreferencesCopyAppValue(CFSTR("BackupRamPath"), - kCFPreferencesCurrentApplication); - if (s) - yinit.buppath = strdup(CFStringGetCStringPtr(s, 0)); - yinit.mpegpath = 0; - s = CFPreferencesCopyAppValue(CFSTR("MpegRomPath"), - kCFPreferencesCurrentApplication); - if (s) - yinit.mpegpath = strdup(CFStringGetCStringPtr(s, 0)); - yinit.cartpath = 0; - s = CFPreferencesCopyAppValue(CFSTR("CartPath"), - kCFPreferencesCurrentApplication); - if (s) - yinit.cartpath = strdup(CFStringGetCStringPtr(s, 0)); - - yinit.videoformattype = VIDEOFORMATTYPE_NTSC; - - s = CFPreferencesCopyAppValue(CFSTR("AutoFrameSkip"), - kCFPreferencesCurrentApplication); - if (s) - yinit.frameskip = CFStringGetIntValue(s); - - PerPortReset(); - pad = PerPadAdd(&PORTDATA1); - - i = 0; - while(PerPadNames[i]) { - s = CFPreferencesCopyAppValue( - CFStringCreateWithCString(0, PerPadNames[i], 0), - kCFPreferencesCurrentApplication); - if (s) - PerSetKey(CFStringGetIntValue(s), i, pad); - i++; - } -} - -static void YuiPause(const int Pause) -{ - EventTimerInterval Interval; - - if(Pause) - { - Interval = kEventDurationForever; - ScspMuteAudio(SCSP_MUTE_SYSTEM); - } - else - { - Interval = 16*kEventDurationMillisecond; - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - } - - SetEventLoopTimerNextFireTime(EventTimer, Interval); -} - -void YuiRun(void) { - static int FirstRun = 1; - EventLoopTimerUPP myFrameUPP; - - if(FirstRun) - { - myFrameUPP = NewEventLoopTimerUPP(YuiIdle); - InstallEventLoopTimer(GetCurrentEventLoop(), kEventDurationNoWait, - 16*kEventDurationMillisecond, myFrameUPP, NULL, &EventTimer); - FirstRun = 0; - } - else - { - YuiPause(0); - YabauseDeInit(); - } - - read_settings(); - YabauseInit(&yinit); -} - -static void TogglePairedMenuItems(MenuRef menu, MenuItemIndex BaseItemIndex) -{ - MenuItemAttributes ItemAttributes; - - GetMenuItemAttributes(menu, BaseItemIndex, &ItemAttributes); - - if(ItemAttributes & kMenuItemAttrHidden) - { - ChangeMenuItemAttributes(menu, BaseItemIndex, 0, kMenuItemAttrHidden); - ChangeMenuItemAttributes(menu, BaseItemIndex+1, kMenuItemAttrHidden, 0); - } - else - { - ChangeMenuItemAttributes(menu, BaseItemIndex, kMenuItemAttrHidden, 0); - ChangeMenuItemAttributes(menu, BaseItemIndex+1, 0, kMenuItemAttrHidden); - } -} - -OSStatus MyWindowEventHandler (EventHandlerCallRef myHandler, EventRef theEvent, void* userData) -{ - OSStatus ret = noErr; - MenuRef menu; - - switch(GetEventClass(theEvent)) { - case kEventClassWindow: - switch (GetEventKind (theEvent)) { - case kEventWindowClose: - - YabauseDeInit(); - QuitApplicationEventLoop(); - break; - - case kEventWindowBoundsChanged: - aglUpdateContext(myAGLContext); - { - Rect bounds; - GetEventParameter(theEvent, kEventParamCurrentBounds, - typeQDRectangle, NULL, sizeof(Rect), NULL, &bounds); - glViewport(0, 0, bounds.right - bounds.left, - bounds.bottom - bounds.top); - } - break; - } - break; - case kEventClassCommand: - { - HICommand command; - GetEventParameter(theEvent, kEventParamDirectObject, - typeHICommand, NULL, sizeof(HICommand), NULL, &command); - switch(command.commandID) { - case kHICommandPreferences: - CreateSettingsWindow(); - break; - case kHICommandQuit: - YabauseDeInit(); - QuitApplicationEventLoop(); - break; - case YUI_COMMAND_RESET: - YabauseReset(); - break; - case YUI_COMMAND_PAUSE: - YuiPause(1); - menu = GetMenuRef(YUI_MENU_EMULATION); - TogglePairedMenuItems(menu, 2); - UpdateCPUStatusWindow(); - break; - case YUI_COMMAND_RESUME: - YuiPause(0); - menu = GetMenuRef(YUI_MENU_EMULATION); - TogglePairedMenuItems(menu, 2); - break; - case YUI_COMMAND_SHOW_CPU: - ShowCPUStatusWindow(); - menu = GetMenuRef(YUI_MENU_DEBUG); - TogglePairedMenuItems(menu, 1); - break; - case YUI_COMMAND_HIDE_CPU: - HideCPUStatusWindow(); - menu = GetMenuRef(YUI_MENU_DEBUG); - TogglePairedMenuItems(menu, 1); - break; - case YUI_COMMAND_TOGGLE_NBG0: - if(VIDCore) - { - menu = GetMenuRef(YUI_MENU_DEBUG); - TogglePairedMenuItems(menu, 4); - ToggleNBG0(); - } - break; - case YUI_COMMAND_TOGGLE_NBG1: - if(VIDCore) - { - menu = GetMenuRef(YUI_MENU_DEBUG); - TogglePairedMenuItems(menu, 6); - ToggleNBG1(); - } - break; - case YUI_COMMAND_TOGGLE_NBG2: - if(VIDCore) - { - menu = GetMenuRef(YUI_MENU_DEBUG); - TogglePairedMenuItems(menu, 8); - ToggleNBG2(); - } - break; - case YUI_COMMAND_TOGGLE_NBG3: - if(VIDCore) - { - menu = GetMenuRef(YUI_MENU_DEBUG); - TogglePairedMenuItems(menu, 10); - ToggleNBG3(); - } - break; - case YUI_COMMAND_TOGGLE_RBG0: - if(VIDCore) - { - menu = GetMenuRef(YUI_MENU_DEBUG); - TogglePairedMenuItems(menu, 12); - ToggleRBG0(); - } - break; - case YUI_COMMAND_TOGGLE_VDP1: - if(VIDCore) - { - menu = GetMenuRef(YUI_MENU_DEBUG); - TogglePairedMenuItems(menu, 14); - ToggleVDP1(); - } - break; - case YUI_COMMAND_TOGGLE_FULLSCREEN: - if(VIDCore) - { - menu = GetMenuRef(YUI_MENU_EMULATION); - TogglePairedMenuItems(menu, 5); - ToggleFullScreen(); - } - break; - case YUI_COMMAND_LOAD_BINARY: - CreateLoadWindow(0); - break; - case YUI_COMMAND_LOAD_AND_EXECUTE: - CreateLoadWindow(1); - break; - case YUI_COMMAND_SAVE_BINARY: -// MappedMemorySave(file, address, size); - break; - default: - ret = eventNotHandledErr; - printf("unhandled command\n"); - break; - } - } - break; - - case kEventClassKeyboard: - switch(GetEventKind(theEvent)) { - int i; - UInt32 key; - case kEventRawKeyDown: - GetEventParameter(theEvent, kEventParamKeyCode, - typeUInt32, NULL, sizeof(UInt32), NULL, &key); - PerKeyDown(key); - break; - case kEventRawKeyUp: - GetEventParameter(theEvent, kEventParamKeyCode, - typeUInt32, NULL, sizeof(UInt32), NULL, &key); - PerKeyUp(key); - break; - } - break; - } - - return ret; -} - -static WindowRef CreateMyWindow() { - - WindowRef myWindow; - Rect contentBounds; - - CFStringRef windowTitle = CFSTR("Yabause"); - WindowClass windowClass = kDocumentWindowClass; - WindowAttributes attributes = - kWindowStandardDocumentAttributes | - kWindowStandardHandlerAttribute | - kWindowLiveResizeAttribute; - - EventTypeSpec eventList[] = { - { kEventClassWindow, kEventWindowClose }, - { kEventClassWindow, kEventWindowBoundsChanged }, - { kEventClassCommand, kEventCommandProcess }, - { kEventClassKeyboard, kEventRawKeyDown }, - { kEventClassKeyboard, kEventRawKeyUp } - }; - - SetRect(&contentBounds, 200, 200, 520, 424); - - CreateNewWindow (windowClass, - attributes, - &contentBounds, - &myWindow); - - SetWindowTitleWithCFString (myWindow, windowTitle); - CFRelease(windowTitle); - ShowWindow(myWindow); - - InstallWindowEventHandler(myWindow, - NewEventHandlerUPP (MyWindowEventHandler), - GetEventTypeCount(eventList), - eventList, myWindow, NULL); - return myWindow; -} - -static OSStatus MyAGLReportError (void) { - GLenum err = aglGetError(); - - if (err == AGL_NO_ERROR) - return noErr; - else - return (OSStatus) err; -} - -static OSStatus MySetWindowAsDrawableObject (WindowRef window) -{ - OSStatus err = noErr; - - GLint attributes[] = { AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_DEPTH_SIZE, 24, - AGL_NONE }; - - AGLPixelFormat myAGLPixelFormat; - - myAGLPixelFormat = aglChoosePixelFormat (NULL, 0, attributes); - - err = MyAGLReportError (); - - if (myAGLPixelFormat) { - myAGLContext = aglCreateContext (myAGLPixelFormat, NULL); - - err = MyAGLReportError (); - aglDestroyPixelFormat(myAGLPixelFormat); - } - - if (! aglSetDrawable (myAGLContext, GetWindowPort (window))) - err = MyAGLReportError (); - - if (!aglSetCurrentContext (myAGLContext)) - err = MyAGLReportError (); - - return err; - -} - -int main(int argc, char* argv[]) { - MenuRef menu; - EventLoopTimerRef nextFrameTimer; - IBNibRef menuNib; - - myWindow = CreateMyWindow(); - MySetWindowAsDrawableObject(myWindow); - - CreateNibReference(CFSTR("menu"), &menuNib); - SetMenuBarFromNib(menuNib, CFSTR("MenuBar")); - - EnableMenuCommand(NULL, kHICommandPreferences); - - read_settings(); - - YuiRun(); - if(argc >= 2) - load_file_core(argv[1], (argc >= 3) ? argv[2] : NULL, 1); - - RunApplicationEventLoop(); - - return 0; -} - -void YuiErrorMsg(const char * string) { - printf("%s\n", string); -} - -void YuiSetVideoAttribute(int type, int val) { -} - -int YuiSetVideoMode(int width, int height, int bpp, int fullscreen) -{ - static CFDictionaryRef oldDisplayMode = 0; - static int oldDisplayModeValid = 0; - - AGLPixelFormat myAGLPixelFormat; - AGLDrawable myDrawable = aglGetDrawable(myAGLContext); - OSStatus err = noErr; - GLint attributesFullscreen[] = { AGL_RGBA, - AGL_FULLSCREEN, - AGL_DOUBLEBUFFER, - AGL_DEPTH_SIZE, 24, - AGL_NONE }; - CGDirectDisplayID displayId = kCGDirectMainDisplay; - - if(myDrawable) - { - if(fullscreen) - { - Rect bounds; - CGPoint point; - CGDisplayCount displayCount; - - GetWindowBounds(myWindow, kWindowGlobalPortRgn, &bounds); - point.x = (float)bounds.left; - point.y = (float)bounds.top; - - CGGetDisplaysWithPoint(point, 1, &displayId, &displayCount); - - CFDictionaryRef refDisplayMode = CGDisplayBestModeForParameters(displayId, - bpp, width, height, NULL); - if(refDisplayMode) - { - GDHandle gdhDisplay; - oldDisplayMode = CGDisplayCurrentMode(displayId); - oldDisplayModeValid = 1; - - aglSetDrawable(myAGLContext, NULL); - aglSetCurrentContext(NULL); - aglDestroyContext(myAGLContext); - myAGLContext = NULL; - - CGCaptureAllDisplays(); - CGDisplaySwitchToMode(displayId, refDisplayMode); - CGDisplayHideCursor(displayId); - - DMGetGDeviceByDisplayID((DisplayIDType)displayId, &gdhDisplay, 0); - - myAGLPixelFormat = aglChoosePixelFormat(&gdhDisplay, 1, attributesFullscreen); - if(myAGLPixelFormat) - { - myAGLContext = aglCreateContext(myAGLPixelFormat, NULL); - if(myAGLContext) - { - aglSetCurrentContext(myAGLContext); - aglSetFullScreen(myAGLContext, width, height, 0, 0); - } - - err = MyAGLReportError(); - aglDestroyPixelFormat(myAGLPixelFormat); - } - else - { - err = MyAGLReportError(); - CGReleaseAllDisplays(); - CGDisplayShowCursor(displayId); - } - } - else - { - err = MyAGLReportError(); - } - } - else - { - if(oldDisplayModeValid) - { - oldDisplayModeValid = 0; - - aglSetDrawable(myAGLContext, NULL); - aglSetCurrentContext(NULL); - aglDestroyContext(myAGLContext); - myAGLContext = NULL; - - CGDisplayShowCursor(displayId); - CGDisplaySwitchToMode(displayId, oldDisplayMode); - CGReleaseAllDisplays(); - - MySetWindowAsDrawableObject(myWindow); - } - } - } - - return !(err == noErr); -} - -void YuiSwapBuffers(void) { - aglSwapBuffers(myAGLContext); -} diff --git a/yabause/src/carbon/settings.c b/yabause/src/carbon/settings.c deleted file mode 100644 index 091dfa05ff..0000000000 --- a/yabause/src/carbon/settings.c +++ /dev/null @@ -1,491 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2006 Anders Montonen - Copyright 2010 Alex Marshall - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include "settings.h" - -#define TAB_ID 128 -#define TAB_SIGNATURE 'tabs' -int tabList[] = {129, 130, 131, 132}; - -int loadtype = 0; -ControlRef oldTab; - -int mystrnlen(char* in, int maxlen) -{ - int len; - for(len = 0; (*in != 0) && (len < maxlen); len++, in++); - return len; -} - -unsigned int mytoi(char* in) -{ - unsigned int out = 0; - int length = 0; - int i; - int format = 0; /* Decimal */ - if((in[0] == '0') && (in[1] == 'x')) { - in += 2; - format = 1; /* Hexadecimal */ - }else if(in[0] == '$') { - in += 1; - format = 1; /* Hexadecimal */ - }else if((in[0] == 'H') && (in[1] == '\'')) { - in += 2; - format = 1; /* Hexadecimal */ - } - length = mystrnlen(in, 11); - for(i = 0; i < length; i++) { - switch(format) { - case 0: /* Decimal */ - out *= 10; - if((in[i] >= '0') && (in[i] <= '9')) - out += in[i] - '0'; - break; - case 1: /* Hexadecimal */ - out <<= 4; - if((in[i] >= '0') && (in[i] <= '9')) - out += in[i] - '0'; - if((in[i] >= 'A') && (in[i] <= 'F')) - out += (in[i] - 'A') + 0xA; - if((in[i] >= 'a') && (in[i] <= 'f')) - out += (in[i] - 'a') + 0xA; - break; - } - } - return out; -} - -void SelectItemOfTabControl(ControlRef tabControl) -{ - ControlRef userPane; - ControlID controlID; - - GetControlID(tabControl, &controlID); - if (controlID.id != TAB_ID) return; - - controlID.signature = TAB_SIGNATURE; - - controlID.id = tabList[GetControlValue(tabControl) - 1]; - GetControlByID(GetControlOwner(tabControl), &controlID, &userPane); - - DisableControl(oldTab); - SetControlVisibility(oldTab, false, false); - EnableControl(userPane); - SetControlVisibility(userPane, true, true); - oldTab = userPane; - - Draw1Control(tabControl); -} - -pascal OSStatus TabEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) -{ - ControlRef control; - - GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, - NULL, sizeof(ControlRef), NULL, &control ); - - SelectItemOfTabControl(control); - - return eventNotHandledErr; -} - -void InstallTabHandler(WindowRef window) -{ - EventTypeSpec controlSpec = { kEventClassControl, kEventControlHit }; - ControlRef tabControl; - ControlID controlID; - int i; - - controlID.signature = TAB_SIGNATURE; - - for(i = 0;i < 4;i++) { - controlID.id = tabList[i]; - GetControlByID(window, &controlID, &tabControl); - DisableControl(tabControl); - SetControlVisibility(tabControl, false, false); - } - - controlID.id = TAB_ID; - GetControlByID(window, &controlID, &tabControl); - - InstallControlEventHandler(tabControl, - NewEventHandlerUPP( TabEventHandler ), - 1, &controlSpec, 0, NULL); - - SetControl32BitValue(tabControl, 1); - - SelectItemOfTabControl(tabControl); -} - -CFStringRef get_settings(WindowRef window, int i) { - ControlID id; - ControlRef control; - CFStringRef s; - - id.signature = 'conf'; - id.id = i; - GetControlByID(window, &id, &control); - GetControlData(control, kControlEditTextPart, - kControlEditTextCFStringTag, sizeof(CFStringRef), &s, NULL); - - return s; -} - -CFStringRef get_settings_c(WindowRef window, int i) { - ControlID id; - ControlRef control; - CFStringRef s; - - id.signature = 'conf'; - id.id = i; - GetControlByID(window, &id, &control); - s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%d"), GetControl32BitValue(control)); - - return s; -} - -void set_settings(WindowRef window, int i, CFStringRef s) { - ControlID id; - ControlRef control; - - if (s) { - id.signature = 'conf'; - id.id = i; - GetControlByID(window, &id, &control); - SetControlData(control, kControlEditTextPart, - kControlEditTextCFStringTag, sizeof(CFStringRef), &s); - } -} - -void set_settings_c(WindowRef window, int i, CFStringRef s) { - ControlID id; - ControlRef control; - - if (s) { - id.signature = 'conf'; - id.id = i; - GetControlByID(window, &id, &control); - SetControl32BitValue(control, CFStringGetIntValue(s)); - } -} - -void save_settings(WindowRef window) { - PerPad_struct * pad; - int i; - CFStringRef s; - - CFPreferencesSetAppValue(CFSTR("BiosPath"), get_settings(window, 1), - kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("CDROMDrive"), get_settings(window, 2), - kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("CDROMCore"), get_settings_c(window, 3), - kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("Region"), get_settings_c(window, 4), - kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("VideoCore"), get_settings_c(window, 5), - kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("SoundCore"), get_settings_c(window, 6), - kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("CartPath"), get_settings(window, 7), - kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("CartType"), get_settings_c(window, 8), - kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("BackupRamPath"), - get_settings(window, 9), kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("MpegRomPath"), - get_settings(window, 10), kCFPreferencesCurrentApplication); - CFPreferencesSetAppValue(CFSTR("AutoFrameSkip"), - get_settings_c(window, 11), kCFPreferencesCurrentApplication); - - PerPortReset(); - pad = PerPadAdd(&PORTDATA1); - - i = 0; - while(PerPadNames[i]) { - s = get_settings(window, 31 + i); - CFPreferencesSetAppValue( - CFStringCreateWithCString(0, PerPadNames[i], 0), - s, kCFPreferencesCurrentApplication); - PerSetKey(CFStringGetIntValue(s), i, pad); - i++; - } - - CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication); -} - -void load_settings(WindowRef window) { - int i; - - set_settings(window, 1, CFPreferencesCopyAppValue(CFSTR("BiosPath"), - kCFPreferencesCurrentApplication)); - set_settings(window, 2, CFPreferencesCopyAppValue(CFSTR("CDROMDrive"), - kCFPreferencesCurrentApplication)); - set_settings_c(window, 3, CFPreferencesCopyAppValue(CFSTR("CDROMCore"), - kCFPreferencesCurrentApplication)); - set_settings_c(window, 4, CFPreferencesCopyAppValue(CFSTR("Region"), - kCFPreferencesCurrentApplication)); - set_settings_c(window, 5, CFPreferencesCopyAppValue(CFSTR("VideoCore"), - kCFPreferencesCurrentApplication)); - set_settings_c(window, 6, CFPreferencesCopyAppValue(CFSTR("SoundCore"), - kCFPreferencesCurrentApplication)); - set_settings(window, 7, CFPreferencesCopyAppValue(CFSTR("CartPath"), - kCFPreferencesCurrentApplication)); - set_settings_c(window, 8, CFPreferencesCopyAppValue(CFSTR("CartType"), - kCFPreferencesCurrentApplication)); - set_settings(window, 9, - CFPreferencesCopyAppValue(CFSTR("BackupRamPath"), - kCFPreferencesCurrentApplication)); - set_settings(window, 10, CFPreferencesCopyAppValue(CFSTR("MpegRomPath"), - kCFPreferencesCurrentApplication)); - set_settings_c(window, 11, CFPreferencesCopyAppValue(CFSTR("AutoFrameSkip"), - kCFPreferencesCurrentApplication)); - - i = 0; - while(PerPadNames[i]) { - set_settings(window, 31 + i, CFPreferencesCopyAppValue( - CFStringCreateWithCString(0, PerPadNames[i], 0), - kCFPreferencesCurrentApplication)); - i++; - } -} - -int load_file_core(char* file, char* addr, int type) -{ - unsigned int adr; - int ret = -1; - if(addr == NULL) - adr = 0; - else - adr = mytoi(addr); - switch(type) { - case 0: - ret = MappedMemoryLoad(file, adr); - break; - case 1: - MappedMemoryLoadExec(file, adr); - ret = 0; - break; - } - return ret; -} - -void load_file(WindowRef window, int type) { - char addrbuf[12]; - char filebuf[256]; - int ret = -1; - CFStringGetCString(get_settings(window, 1), filebuf, 256, kCFStringEncodingUTF8); - CFStringGetCString(get_settings(window, 2), addrbuf, 12, kCFStringEncodingUTF8); - ret = load_file_core(filebuf, addrbuf, type); - (void)(ret); /* We need to do something about bad return values... */ -} - -OSStatus SettingsWindowEventHandler (EventHandlerCallRef myHandler, EventRef theEvent, void* userData) -{ - OSStatus result = eventNotHandledErr; - - switch (GetEventKind (theEvent)) - { - case kEventWindowClose: - { - WindowRef window; - GetEventParameter(theEvent, kEventParamDirectObject, typeWindowRef, - 0, sizeof(typeWindowRef), 0, &window); - - save_settings(window); - - DisposeWindow(window); - } - result = noErr; - break; - - } - - return (result); -} - -OSStatus BrowseHandler(EventHandlerCallRef h, EventRef event, void* data) { - NavDialogRef dialog; - NavDialogCreationOptions options; - - NavGetDefaultDialogCreationOptions(&options); - NavCreateChooseFileDialog(&options, NULL, NULL, NULL, NULL, - NULL, &dialog); - NavDialogRun(dialog); - - if (NavDialogGetUserAction(dialog) == kNavUserActionChoose) { - NavReplyRecord reply; - FSRef fileAsFSRef; - CFURLRef fileAsCFURLRef = NULL; - CFStringRef s; - - NavDialogGetReply(dialog, &reply); - - AEGetNthPtr(&(reply.selection), 1, typeFSRef, - NULL, NULL, &fileAsFSRef, sizeof(FSRef), NULL); - - NavDisposeReply(&reply); - NavDialogDispose(dialog); - - fileAsCFURLRef = CFURLCreateFromFSRef(NULL, &fileAsFSRef); - s = CFURLCopyFileSystemPath(fileAsCFURLRef, kCFURLPOSIXPathStyle); - - CFShow(s); - - SetControlData(data, kControlEditTextPart, - kControlEditTextCFStringTag, sizeof(CFStringRef), &s); - Draw1Control(data); - } - - return noErr; -} - -OSStatus KeyConfigHandler(EventHandlerCallRef h, EventRef event, void* data) { - UInt32 key; - CFStringRef s; - GetEventParameter(event, kEventParamKeyCode, - typeUInt32, NULL, sizeof(UInt32), NULL, &key); - s = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), key); - SetControlData(data, kControlEditTextPart, - kControlEditTextCFStringTag, sizeof(CFStringRef), &s); - Draw1Control(data); - - return noErr; -} - -void InstallBrowseHandler(WindowRef myWindow, const SInt32 ControllerId, - const SInt32 ControlledId) -{ - EventTypeSpec flist[] = { - { kEventClassControl, kEventControlHit } - }; - ControlID Id; - ControlRef Controller, Controlled; - - Id.signature = 'conf'; - Id.id = ControllerId; - GetControlByID(myWindow, &Id, &Controller); - Id.id = ControlledId; - GetControlByID(myWindow, &Id, &Controlled); - InstallControlEventHandler(Controller, NewEventHandlerUPP(BrowseHandler), - GetEventTypeCount(flist), flist, Controlled, NULL); -} - -WindowRef CreateSettingsWindow() { - - WindowRef myWindow; - IBNibRef nib; - - EventTypeSpec eventList[] = { - { kEventClassWindow, kEventWindowClose } - }; - - CreateNibReference(CFSTR("preferences"), &nib); - CreateWindowFromNib(nib, CFSTR("Dialog"), &myWindow); - - load_settings(myWindow); - - InstallTabHandler(myWindow); - - { - int i; - ControlRef control, controlled; - ControlID id; - EventTypeSpec elist[] = { - { kEventClassKeyboard, kEventRawKeyDown }, - { kEventClassKeyboard, kEventRawKeyUp } - }; - - id.signature = 'conf'; - i = 0; - while(PerPadNames[i]) { - id.id = 31 + i; - GetControlByID(myWindow, &id, &control); - - InstallControlEventHandler(control, NewEventHandlerUPP(KeyConfigHandler), - GetEventTypeCount(elist), elist, control, NULL); - i++; - } - - InstallBrowseHandler(myWindow, 50, 1); /* BIOS */ - InstallBrowseHandler(myWindow, 51, 2); /* CDROM */ - InstallBrowseHandler(myWindow, 52, 7); /* Cartridge ROM */ - InstallBrowseHandler(myWindow, 53, 9); /* Memory */ - InstallBrowseHandler(myWindow, 54, 10); /* MPEG ROM */ - } - - ShowWindow(myWindow); - - InstallWindowEventHandler(myWindow, - NewEventHandlerUPP (SettingsWindowEventHandler), - GetEventTypeCount(eventList), - eventList, myWindow, NULL); - - return myWindow; -} - -OSStatus LoadWindowEventHandler (EventHandlerCallRef myHandler, EventRef theEvent, void* userData) -{ - OSStatus result = eventNotHandledErr; - switch (GetEventKind (theEvent)) - { - case kEventWindowClose: - { - WindowRef window; - GetEventParameter(theEvent, kEventParamDirectObject, typeWindowRef, - 0, sizeof(typeWindowRef), 0, &window); - - load_file(window, loadtype); - - DisposeWindow(window); - } - result = noErr; - break; - } - return (result); -} - -WindowRef CreateLoadWindow(int type) { - WindowRef myWindow; - IBNibRef nib; - int* hack; - EventTypeSpec eventList[] = { - { kEventClassWindow, kEventWindowClose } - }; - - CreateNibReference(CFSTR("load_dialog"), &nib); - CreateWindowFromNib(nib, CFSTR("Dialog"), &myWindow); - - InstallTabHandler(myWindow); - hack = malloc(sizeof(int)); - loadtype = type; - InstallBrowseHandler(myWindow, 50, 1); /* File */ - ShowWindow(myWindow); - - InstallWindowEventHandler(myWindow, - NewEventHandlerUPP (LoadWindowEventHandler), - GetEventTypeCount(eventList), - eventList, myWindow, NULL); - return myWindow; -} diff --git a/yabause/src/carbon/settings.h b/yabause/src/carbon/settings.h deleted file mode 100644 index 37f6522522..0000000000 --- a/yabause/src/carbon/settings.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "../yabause.h" -#include "../peripheral.h" -#include "../sh2core.h" -#include "../sh2int.h" -#include "../vidogl.h" -#include "../vidsoft.h" -#include "../scsp.h" -#include "../sndsdl.h" -#include "../cdbase.h" -#include "../cs0.h" -#include "../m68kcore.h" - -extern yabauseinit_struct yinit; - -WindowRef CreateSettingsWindow(); - -typedef struct _YuiAction YuiAction; - -/* -struct _YuiAction { - UInt32 key; - const char * name; - void (*press)(void); - void (*release)(void); -}; - -extern YuiAction key_config[]; -*/ diff --git a/yabause/src/cd-freebsd.c b/yabause/src/cd-freebsd.c deleted file mode 100644 index 9e451b20a0..0000000000 --- a/yabause/src/cd-freebsd.c +++ /dev/null @@ -1,166 +0,0 @@ -/* Copyright 2004-2005 Theo Berkau - Copyright 2004-2006 Guillaume Duhamel - Copyright 2005 Joost Peters - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cdbase.h" -#include "debug.h" - -static int FreeBSDCDInit(const char *); -static void FreeBSDCDDeInit(void); -static s32 FreeBSDCDReadTOC(u32 *); -static int FreeBSDCDGetStatus(void); -static int FreeBSDCDReadSectorFAD(u32, void *); -static void FreeBSDCDReadAheadFAD(u32); - -CDInterface ArchCD = { - CDCORE_ARCH, - "FreeBSD CD Drive", - FreeBSDCDInit, - FreeBSDCDDeInit, - FreeBSDCDGetStatus, - FreeBSDCDReadTOC, - FreeBSDCDReadSectorFAD, - FreeBSDCDReadAheadFAD, -}; - -static int hCDROM; - -static int FreeBSDCDInit(const char * cdrom_name) { - int bsize = 2352; - - if ((hCDROM = open(cdrom_name, O_RDONLY | O_NONBLOCK)) == -1) { - LOG("CDInit (%s) failed\n", cdrom_name); - return -1; - } - - if (ioctl (hCDROM, CDRIOCSETBLOCKSIZE, &bsize) == -1) { - return -1; - } - - LOG("CDInit (%s) OK\n", cdrom_name); - return 0; -} - -static void FreeBSDCDDeInit(void) { - if (hCDROM != -1) { - close(hCDROM); - } - - LOG("CDDeInit OK\n"); -} - - -static s32 FreeBSDCDReadTOC(u32 * TOC) -{ - int success; - struct ioc_toc_header ctTOC; - struct ioc_read_toc_single_entry ctTOCent; - int i, j; - int add150 = 0; - - ctTOCent.address_format = CD_LBA_FORMAT; - - if (hCDROM != -1) - { - memset(TOC, 0xFF, 0xCC * 2); - memset(&ctTOC, 0xFF, sizeof(struct ioc_toc_header)); - - if (ioctl(hCDROM, CDIOREADTOCHEADER, &ctTOC) == -1) { - return 0; - } - - ctTOCent.track = ctTOC.starting_track; - ioctl(hCDROM, CDIOREADTOCENTRY, &ctTOCent); - if (ctTOCent.entry.addr.lba == 0) add150 = 150; - TOC[0] = ((ctTOCent.entry.control << 28) | - (ctTOCent.entry.addr_type << 24) | - ctTOCent.entry.addr.lba + add150); - - // convert TOC to saturn format - for (i = ctTOC.starting_track + 1; i <= ctTOC.ending_track; i++) - { - ctTOCent.track = i; - ioctl(hCDROM, CDIOREADTOCENTRY, &ctTOCent); - TOC[i - 1] = (ctTOCent.entry.control << 28) | - (ctTOCent.entry.addr_type << 24) | - (ctTOCent.entry.addr.lba + add150); - } - - // Do First, Last, and Lead out sections here - - ctTOCent.track = ctTOC.starting_track; - ioctl(hCDROM, CDIOREADTOCENTRY, &ctTOCent); - TOC[99] = (ctTOCent.entry.control << 28) | - (ctTOCent.entry.addr_type << 24) | - (ctTOC.starting_track << 16); - - ctTOCent.track = ctTOC.ending_track; - ioctl(hCDROM, CDIOREADTOCENTRY, &ctTOCent); - TOC[100] = (ctTOCent.entry.control << 28) | - (ctTOCent.entry.addr_type << 24) | - (ctTOC.starting_track << 16); - - ctTOCent.track = 0xAA; - ioctl(hCDROM, CDIOREADTOCENTRY, &ctTOCent); - TOC[101] = (ctTOCent.entry.control << 28) | - (ctTOCent.entry.addr_type << 24) | - (ctTOCent.entry.addr.lba + add150); - - return (0xCC * 2); - } - - return 0; -} - -static int FreeBSDCDGetStatus(void) { - // 0 - CD Present, disc spinning - // 1 - CD Present, disc not spinning - // 2 - CD not present - // 3 - Tray open - // see ../windows/cd.cc for more info - - return 0; -} - -static int FreeBSDCDReadSectorFAD(u32 FAD, void *buffer) { - if (hCDROM != -1) - { - lseek(hCDROM, (FAD - 150) * 2352, SEEK_SET); - read(hCDROM, buffer, 2352); - - return 1; - } - - return 0; -} - -static void FreeBSDCDReadAheadFAD(UNUSED u32 FAD) -{ - // No-op -} diff --git a/yabause/src/cd-linux.c b/yabause/src/cd-linux.c deleted file mode 100644 index e488c64ce8..0000000000 --- a/yabause/src/cd-linux.c +++ /dev/null @@ -1,182 +0,0 @@ -/* Copyright 2004-2005 Theo Berkau - Copyright 2004-2006 Guillaume Duhamel - Copyright 2005 Joost Peters - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include -#include -#ifdef LINUX_CDROM_H_IS_BROKEN -#include -#endif - -#include "cdbase.h" -#include "debug.h" - -static int LinuxCDInit(const char *); -static void LinuxCDDeInit(void); -static s32 LinuxCDReadTOC(u32 *); -static int LinuxCDGetStatus(void); -static int LinuxCDReadSectorFAD(u32, void *); -static void LinuxCDReadAheadFAD(u32); - -CDInterface ArchCD = { - CDCORE_ARCH, - "Linux CD Drive", - LinuxCDInit, - LinuxCDDeInit, - LinuxCDGetStatus, - LinuxCDReadTOC, - LinuxCDReadSectorFAD, - LinuxCDReadAheadFAD, -}; - -static int hCDROM; - -static int LinuxCDInit(const char * cdrom_name) { - if ((hCDROM = open(cdrom_name, O_RDONLY | O_NONBLOCK)) == -1) { - return -1; - } - LOG("CDInit (%s) OK\n", cdrom_name); - return 0; -} - -static void LinuxCDDeInit(void) { - if (hCDROM != -1) { - close(hCDROM); - } - - LOG("CDDeInit OK\n"); -} - - -static s32 LinuxCDReadTOC(u32 * TOC) -{ - struct cdrom_tochdr ctTOC; - struct cdrom_tocentry ctTOCent; - int i; - int add150 = 0; - - ctTOCent.cdte_format = CDROM_LBA; - - if (hCDROM != -1) - { - memset(TOC, 0xFF, 0xCC * 2); - memset(&ctTOC, 0xFF, sizeof(struct cdrom_tochdr)); - - if (ioctl(hCDROM, CDROMREADTOCHDR, &ctTOC) == -1) { - return 0; - } - - ctTOCent.cdte_track = ctTOC.cdth_trk0; - ioctl(hCDROM, CDROMREADTOCENTRY, &ctTOCent); - if (ctTOCent.cdte_addr.lba == 0) add150 = 150; - TOC[0] = ((ctTOCent.cdte_ctrl << 28) | - (ctTOCent.cdte_adr << 24) | - (ctTOCent.cdte_addr.lba + add150)); - - // convert TOC to saturn format - for (i = ctTOC.cdth_trk0 + 1; i <= ctTOC.cdth_trk1; i++) - { - ctTOCent.cdte_track = i; - ioctl(hCDROM, CDROMREADTOCENTRY, &ctTOCent); - TOC[i - 1] = (ctTOCent.cdte_ctrl << 28) | - (ctTOCent.cdte_adr << 24) | - (ctTOCent.cdte_addr.lba + add150); - } - - // Do First, Last, and Lead out sections here - - ctTOCent.cdte_track = ctTOC.cdth_trk0; - ioctl(hCDROM, CDROMREADTOCENTRY, &ctTOCent); - TOC[99] = (ctTOCent.cdte_ctrl << 28) | - (ctTOCent.cdte_adr << 24) | - (ctTOC.cdth_trk0 << 16); - - ctTOCent.cdte_track = ctTOC.cdth_trk1; - ioctl(hCDROM, CDROMREADTOCENTRY, &ctTOCent); - TOC[100] = (ctTOCent.cdte_ctrl << 28) | - (ctTOCent.cdte_adr << 24) | - (ctTOC.cdth_trk1 << 16); - - ctTOCent.cdte_track = CDROM_LEADOUT; - ioctl(hCDROM, CDROMREADTOCENTRY, &ctTOCent); - TOC[101] = (ctTOCent.cdte_ctrl << 28) | - (ctTOCent.cdte_adr << 24) | - (ctTOCent.cdte_addr.lba + add150); - - return (0xCC * 2); - } - - return 0; -} - -static int LinuxCDGetStatus(void) { - // 0 - CD Present, disc spinning - // 1 - CD Present, disc not spinning - // 2 - CD not present - // 3 - Tray open - // see ../windows/cd.cc for more info - - int ret = ioctl(hCDROM, CDROM_DRIVE_STATUS, CDSL_CURRENT); - switch(ret) { - case CDS_DISC_OK: - return 0; - case CDS_NO_DISC: - return 2; - case CDS_TRAY_OPEN: - return 3; - } - - // guess it's ok to say there's no disc here... - return 2; -} - -static int LinuxCDReadSectorFAD(u32 FAD, void *buffer) { - union { - struct cdrom_msf msf; - char bigbuf[2352]; - } position; - - if (hCDROM != -1) - { - position.msf.cdmsf_min0 = FAD / 4500; - position.msf.cdmsf_sec0 = (FAD % 4500) / 75; - position.msf.cdmsf_frame0 = FAD % 75; - - if (ioctl(hCDROM, CDROMREADRAW, &position) == -1) { - return 0; - } - - memcpy(buffer, position.bigbuf, 2352); - - return 1; - } - - return 0; -} - -static void LinuxCDReadAheadFAD(UNUSED u32 FAD) -{ - // No-op -} diff --git a/yabause/src/cd-macosx.c b/yabause/src/cd-macosx.c deleted file mode 100644 index 67916553b4..0000000000 --- a/yabause/src/cd-macosx.c +++ /dev/null @@ -1,227 +0,0 @@ -/* Copyright 2004-2005 Lucas Newman - Copyright 2004-2005 Theo Berkau - Copyright 2005 Weston Yager - Copyright 2006-2008 Guillaume Duhamel - Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cdbase.h" - -static int MacOSXCDInit(const char *); -static void MacOSXCDDeInit(void); -static int MacOSXCDGetStatus(void); -static s32 MacOSXCDReadTOC(u32 *); -static int MacOSXCDReadSectorFAD(u32, void *); -static void MacOSXCDReadAheadFAD(u32); - -CDInterface ArchCD = { -CDCORE_ARCH, -"MacOSX CD Drive", -MacOSXCDInit, -MacOSXCDDeInit, -MacOSXCDGetStatus, -MacOSXCDReadTOC, -MacOSXCDReadSectorFAD, -MacOSXCDReadAheadFAD, -}; - -static int hCDROM; - -static int MacOSXCDInit(const char * useless_for_now) -{ - CFMutableDictionaryRef classesToMatch; - io_iterator_t mediaIterator; - io_object_t media; - char cdrom_name[ MAXPATHLEN ]; - - classesToMatch = IOServiceMatching(kIOCDMediaClass); - CFDictionarySetValue(classesToMatch, CFSTR(kIOMediaEjectableKey), - kCFBooleanTrue); - IOServiceGetMatchingServices(kIOMasterPortDefault, - classesToMatch, &mediaIterator); - - media = IOIteratorNext(mediaIterator); - - if(media) - { - CFTypeRef path; - - path = IORegistryEntryCreateCFProperty(media, - CFSTR(kIOBSDNameKey), - kCFAllocatorDefault, 0); - - if (path) - { - size_t length; - - strcpy(cdrom_name, _PATH_DEV); - strcat(cdrom_name, "r"); - length = strlen(cdrom_name); - - CFStringGetCString(path, cdrom_name + length, - MAXPATHLEN - length, kCFStringEncodingUTF8); - - CFRelease(path); - } - IOObjectRelease(media); - } - - if ((hCDROM = open(cdrom_name, O_RDONLY)) == -1) - { - return -1; - } - - return 0; -} - -static void MacOSXCDDeInit(void) -{ - if (hCDROM != -1) - { - close(hCDROM); - } -} - -static CDTOC * GetTOCFromCDPath(void) -{ - CFMutableDictionaryRef classesToMatch; - io_iterator_t mediaIterator; - io_object_t media; - CDTOC * TOC; - - classesToMatch = IOServiceMatching(kIOCDMediaClass); - CFDictionarySetValue(classesToMatch, CFSTR(kIOMediaEjectableKey), - kCFBooleanTrue); - IOServiceGetMatchingServices(kIOMasterPortDefault, - classesToMatch, &mediaIterator); - - media = IOIteratorNext(mediaIterator); - - if(media) - { - CFDataRef TOCData = IORegistryEntryCreateCFProperty(media, CFSTR(kIOCDMediaTOCKey), kCFAllocatorDefault, 0); - TOC = malloc(CFDataGetLength(TOCData)); - CFDataGetBytes(TOCData,CFRangeMake(0,CFDataGetLength(TOCData)),(UInt8 *)TOC); - CFRelease(TOCData); - IOObjectRelease(media); - } - - return TOC; -} - -static s32 MacOSXCDReadTOC(u32 *TOC) -{ - int add150 = 150, tracks = 0; - u_char track; - int i, fad = 0; - CDTOC *cdTOC = GetTOCFromCDPath(); - CDTOCDescriptor *pTrackDescriptors; - pTrackDescriptors = cdTOC->descriptors; - - memset(TOC, 0xFF, 0xCC * 2); - - /* Convert TOC to Saturn format */ - for( i = 3; i < CDTOCGetDescriptorCount(cdTOC); i++ ) { - track = pTrackDescriptors[i].point; - fad = CDConvertMSFToLBA(pTrackDescriptors[i].p) + add150; - if ((track > 99) || (track < 1)) - continue; - TOC[i-3] = (pTrackDescriptors[i].control << 28 | pTrackDescriptors[i].adr << 24 | fad); - tracks++; - } - - /* First */ - TOC[99] = pTrackDescriptors[0].control << 28 | pTrackDescriptors[0].adr << 24 | 1 << 16; - /* Last */ - TOC[100] = pTrackDescriptors[1].control << 28 | pTrackDescriptors[1].adr << 24 | tracks << 16; - /* Leadout */ - TOC[101] = pTrackDescriptors[2].control << 28 | pTrackDescriptors[2].adr << 24 | CDConvertMSFToLBA(pTrackDescriptors[2].p) + add150; - - //free(cdTOC); Looks like this is not need, will look into that. - return (0xCC * 2); -} - -static int MacOSXCDGetStatus(void) -{ - // 0 - CD Present, disc spinning - // 1 - CD Present, disc not spinning - // 2 - CD not present - // 3 - Tray open - // see ../windows/cd.cc for more info - - //Return that disc is present and spinning. 2 and 3 can't happen in the mac port, i don't understand what "not spinning" is supposed to say - return 0; -} - -static int MacOSXCDReadSectorFAD(u32 FAD, void *buffer) -{ - const int blockSize = 2352; -#ifdef CRAB_REWRITE - const int cacheBlocks = 32; - static u8 cache[blockSize * cacheBlocks]; - static u32 cacheFAD = 0xFFFFFF00; -#endif - - if (hCDROM != -1) - { -#ifdef CRAB_REWRITE - /* See if the block we are looking for is in the cache already... */ - if(FAD < cacheFAD || FAD >= cacheFAD + cacheBlocks) { - /* Cache miss, read some blocks from the cd, then we'll hit the - cache below. */ - if(!pread(hCDROM, cache, blockSize * cacheBlocks, - (FAD - 150) * blockSize)) { - return 0; - } - - cacheFAD = FAD; - } - - /* Cache hit, copy the block out. */ - memcpy(buffer, cache + (blockSize * (FAD - cacheFAD)), blockSize); - return 1; -#else - if (pread(hCDROM, buffer, blockSize, (FAD - 150) * blockSize)) - return true; -#endif - } - - return false; -} - -static void MacOSXCDReadAheadFAD(UNUSED u32 FAD) -{ - // No-op -} diff --git a/yabause/src/cd-netbsd.c b/yabause/src/cd-netbsd.c deleted file mode 100644 index 98a871eb9f..0000000000 --- a/yabause/src/cd-netbsd.c +++ /dev/null @@ -1,167 +0,0 @@ -/* Copyright 2004-2005 Theo Berkau - Copyright 2004-2005 Guillaume Duhamel - Copyright 2005 Joost Peters - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "cdbase.h" -#include "debug.h" - -static int NetBSDCDInit(const char *); -static void NetBSDCDDeInit(void); -static s32 NetBSDCDReadTOC(u32 *); -static int NetBSDCDGetStatus(void); -static int NetBSDCDReadSectorFAD(u32, void *); -static void NetBSDCDReadAheadFAD(u32); - -CDInterface ArchCD = { - CDCORE_ARCH, - "NetBSD CD Drive", - NetBSDCDInit, - NetBSDCDDeInit, - NetBSDCDGetStatus, - NetBSDCDReadTOC, - NetBSDCDReadSectorFAD, - NetBSDCDReadAheadFAD, -}; - -static int hCDROM; - -static int NetBSDCDInit(const char * cdrom_name) { - if ((hCDROM = open(cdrom_name, O_RDONLY | O_NONBLOCK)) == -1) { - LOG("CDInit (%s) failed\n", cdrom_name); - return -1; - } - - LOG("CDInit (%s) OK\n", cdrom_name); - return 0; -} - -static void NetBSDCDDeInit(void) { - if (hCDROM != -1) { - close(hCDROM); - } - - LOG("CDDeInit OK\n"); -} - - -static s32 NetBSDCDReadTOC(u32 * TOC) -{ - int success; - struct ioc_toc_header ctTOC; - struct ioc_read_toc_entry ctTOCent; - struct cd_toc_entry data; - int i, j; - int add150 = 0; - - ctTOCent.address_format = CD_LBA_FORMAT; - ctTOCent.data_len = sizeof (struct cd_toc_entry); - ctTOCent.data = &data; - - if (hCDROM != -1) - { - memset(TOC, 0xFF, 0xCC * 2); - memset(&ctTOC, 0xFF, sizeof(struct ioc_toc_header)); - - if (ioctl(hCDROM, CDIOREADTOCHEADER, &ctTOC) == -1) { - return 0; - } - - ctTOCent.starting_track = ctTOC.starting_track; - ioctl(hCDROM, CDIOREADTOCENTRYS, &ctTOCent); - if (ctTOCent.data->addr.lba == 0) add150 = 150; - TOC[0] = ((ctTOCent.data->control << 28) | - (ctTOCent.data->addr_type << 24) | - ctTOCent.data->addr.lba + add150); - - // convert TOC to saturn format - for (i = ctTOC.starting_track + 1; i <= ctTOC.ending_track; i++) - { - ctTOCent.starting_track = i; - ioctl(hCDROM, CDIOREADTOCENTRYS, &ctTOCent); - TOC[i - 1] = (ctTOCent.data->control << 28) | - (ctTOCent.data->addr_type << 24) | - (ctTOCent.data->addr.lba + add150); - } - - // Do First, Last, and Lead out sections here - - ctTOCent.starting_track = ctTOC.starting_track; - ioctl(hCDROM, CDIOREADTOCENTRYS, &ctTOCent); - TOC[99] = (ctTOCent.data->control << 28) | - (ctTOCent.data->addr_type << 24) | - (ctTOC.starting_track << 16); - - ctTOCent.starting_track = ctTOC.ending_track; - ioctl(hCDROM, CDIOREADTOCENTRYS, &ctTOCent); - TOC[100] = (ctTOCent.data->control << 28) | - (ctTOCent.data->addr_type << 24) | - (ctTOC.starting_track << 16); - - ctTOCent.starting_track = 0xAA; - ioctl(hCDROM, CDIOREADTOCENTRYS, &ctTOCent); - TOC[101] = (ctTOCent.data->control << 28) | - (ctTOCent.data->addr_type << 24) | - (ctTOCent.data->addr.lba + add150); - - return (0xCC * 2); - } - - return 0; -} - -static int NetBSDCDGetStatus(void) { - // 0 - CD Present, disc spinning - // 1 - CD Present, disc not spinning - // 2 - CD not present - // 3 - Tray open - // see ../windows/cd.cc for more info - - return 0; -} - -static int NetBSDCDReadSectorFAD(u32 FAD, void *buffer) { - static const s8 syncHdr[] = { - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - if (hCDROM != -1) - { - memcpy(buffer, syncHdr, sizeof (syncHdr)); - lseek(hCDROM, (FAD - 150) * 2048, SEEK_SET); - read(hCDROM, (char *)buffer + 0x10, 2048); - - return 1; - } - - return 0; -} - -static void NetBSDCDReadAheadFAD(UNUSED u32 FAD) -{ - // No-op -} diff --git a/yabause/src/cd-windows.c b/yabause/src/cd-windows.c deleted file mode 100644 index e80ab7b326..0000000000 --- a/yabause/src/cd-windows.c +++ /dev/null @@ -1,364 +0,0 @@ -/* Copyright 2004-2005 Theo Berkau - Copyright 2005 Joost Peters - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include "windows/cd.h" - -////////////////////////////////////////////////////////////////////////////// - -static HANDLE hCDROM; -static SCSI_PASS_THROUGH_DIRECT sptd; -static int KillCDThread=0; -static HANDLE thread_handle=INVALID_HANDLE_VALUE; -static int drivestatus=0; -static DWORD thread_id; - -CDInterface ArchCD = { -CDCORE_SPTI, -"Windows SPTI Driver", -SPTICDInit, -SPTICDDeInit, -SPTICDGetStatus, -SPTICDReadTOC, -SPTICDReadSectorFAD, -SPTICDReadAheadFAD, -}; - -////////////////////////////////////////////////////////////////////////////// -// SPTI Interface -////////////////////////////////////////////////////////////////////////////// - -DWORD WINAPI __stdcall SPTICDThread(void *b); - -int SPTICDInit(const char *cdrom_name) { - char pipe_name[7]; - - sprintf(pipe_name, "\\\\.\\?:"); - pipe_name[4] = cdrom_name[0]; - - if ((hCDROM = CreateFileA(pipe_name, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, - NULL)) == INVALID_HANDLE_VALUE) - { - return -1; - } - - // Setup a separate thread for handling SPTI commands(that way the emulation - // code doesn't have to wait for a response) - KillCDThread=0; - thread_handle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) SPTICDThread,(void *) &KillCDThread,0,&thread_id); - - // Set it to highest priority to avoid breaks -// SetThreadPriority(thread_handle,THREAD_PRIORITY_HIGHEST); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void SPTICDDeInit() { - if (thread_handle != INVALID_HANDLE_VALUE) - { - // Set the flag telling it to stop - KillCDThread=1; - if (WaitForSingleObject(thread_handle,INFINITE) == WAIT_TIMEOUT) - { - // Couldn't close thread cleanly - TerminateThread(thread_handle,0); - } - CloseHandle(thread_handle); - thread_handle = INVALID_HANDLE_VALUE; - } - - CloseHandle(hCDROM); -} - -////////////////////////////////////////////////////////////////////////////// - -DWORD WINAPI __stdcall SPTICDThread(void *b) -{ - while (KillCDThread != 1) - { - DWORD dwBytesReturned; - unsigned char statusbuf[8]; - BOOL success; - - // Check to see if we have any work to do(for now, let's just do a drive - // status check once a second) - - sptd.Length=sizeof(sptd); - sptd.PathId=0; // - sptd.TargetId=0; // Don't need these, they're automatically generated - sptd.Lun=0; // - sptd.CdbLength=12; - sptd.SenseInfoLength=0; // No sense data - sptd.DataIn=SCSI_IOCTL_DATA_IN; - sptd.TimeOutValue=60; // may need to be changed - sptd.DataBuffer=(PVOID)&(statusbuf); - sptd.SenseInfoOffset=0; - sptd.DataTransferLength=8; // may need to change this - - sptd.Cdb[0]=0xBD; // CDB12 code - sptd.Cdb[1]=0; // Reserved - sptd.Cdb[2]=0; // Reserved - sptd.Cdb[3]=0; // Reserved - sptd.Cdb[4]=0; // Reserved - sptd.Cdb[5]=0; // Reserved - sptd.Cdb[6]=0; // Reserved - sptd.Cdb[7]=0; // Reserved - sptd.Cdb[8]=0; // Allocation Length(byte 1) - sptd.Cdb[9]=8; // Allocation Length(byte 2) (may have to change this) - sptd.Cdb[10]=0; // Reserved - sptd.Cdb[11]=0; // Control - sptd.Cdb[12]=0; - sptd.Cdb[13]=0; - sptd.Cdb[14]=0; - sptd.Cdb[15]=0; - - success=DeviceIoControl(hCDROM, IOCTL_SCSI_PASS_THROUGH_DIRECT, - (PVOID)&sptd, (DWORD)sizeof(SCSI_PASS_THROUGH_DIRECT), - NULL, 0, &dwBytesReturned, NULL); - - if (success) - { - // Figure out drive status - - // Is door open? - if (statusbuf[1] & 0x10) - drivestatus = 3; - else - { - // Ok, so the door is closed, now is there a disc there? - success = DeviceIoControl(hCDROM, IOCTL_STORAGE_CHECK_VERIFY, - NULL, 0, NULL, 0, &dwBytesReturned, NULL); - if (!success) - drivestatus = 2; - else - drivestatus = 0; - } - } - else - drivestatus = 2; - - Sleep(1000); - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int SPTICDGetStatus() { - // This function is called periodically to see what the status of the - // drive is. - // - // Should return one of the following values: - // 0 - CD Present, disc spinning - // 1 - CD Present, disc not spinning - // 2 - CD not present - // 3 - Tray open - // - // If you really don't want to bother too much with this function, just - // return status 0. Though it is kind of nice when the bios's cd player, - // etc. recognizes when you've ejected the tray and popped in another disc. -/* - DWORD dwBytesReturned; - unsigned char statusbuf[8]; - BOOL success; - - sptd.Length=sizeof(sptd); - sptd.PathId=0; // - sptd.TargetId=0; // Don't need these, they're automatically generated - sptd.Lun=0; // - sptd.CdbLength=12; - sptd.SenseInfoLength=0; // No sense data - sptd.DataIn=SCSI_IOCTL_DATA_IN; - sptd.TimeOutValue=60; // may need to be changed - sptd.DataBuffer=(PVOID)&(statusbuf); - sptd.SenseInfoOffset=0; - sptd.DataTransferLength=8; // may need to change this - - sptd.Cdb[0]=0xBD; // CDB12 code - sptd.Cdb[1]=0; // Reserved - sptd.Cdb[2]=0; // Reserved - sptd.Cdb[3]=0; // Reserved - sptd.Cdb[4]=0; // Reserved - sptd.Cdb[5]=0; // Reserved - sptd.Cdb[6]=0; // Reserved - sptd.Cdb[7]=0; // Reserved - sptd.Cdb[8]=0; // Allocation Length(byte 1) - sptd.Cdb[9]=8; // Allocation Length(byte 2) (may have to change this) - sptd.Cdb[10]=0; // Reserved - sptd.Cdb[11]=0; // Control - sptd.Cdb[12]=0; - sptd.Cdb[13]=0; - sptd.Cdb[14]=0; - sptd.Cdb[15]=0; - - success=DeviceIoControl(hCDROM, IOCTL_SCSI_PASS_THROUGH_DIRECT, - (PVOID)&sptd, (DWORD)sizeof(SCSI_PASS_THROUGH_DIRECT), - NULL, 0, &dwBytesReturned, NULL); - - if (success) - { - // Figure out drive status - - // Is door open? - if (statusbuf[1] & 0x10) return 3; - - // Ok, so the door is closed, now is there a disc there? - success = DeviceIoControl(hCDROM, IOCTL_STORAGE_CHECK_VERIFY, - NULL, 0, NULL, 0, &dwBytesReturned, NULL); - if (!success) - return 2; - - return 0; - } - - return 2; -*/ - return drivestatus; -} - -////////////////////////////////////////////////////////////////////////////// - -#define MSF_TO_FAD(m,s,f) ((m * 4500) + (s * 75) + f) - -s32 SPTICDReadTOC(u32 *TOC) { -// FILE *debugfp; - CDROM_TOC ctTOC; - DWORD dwNotUsed; - int i; - - if (hCDROM != INVALID_HANDLE_VALUE) - { - memset(TOC, 0xFF, 0xCC * 2); - memset(&ctTOC, 0xFF, sizeof(CDROM_TOC)); - - if (DeviceIoControl (hCDROM, IOCTL_CDROM_READ_TOC, - NULL, 0, &ctTOC, sizeof(ctTOC), - &dwNotUsed, NULL) == 0) - { - return 0; - } - - // convert TOC to saturn format - for (i = 0; i < ctTOC.LastTrack; i++) - { - TOC[i] = (ctTOC.TrackData[i].Control << 28) | - (ctTOC.TrackData[i].Adr << 24) | - MSF_TO_FAD(ctTOC.TrackData[i].Address[1], ctTOC.TrackData[i].Address[2], ctTOC.TrackData[i].Address[3]); - } - - // Do First, Last, and Lead out sections here - - TOC[99] = (ctTOC.TrackData[0].Control << 28) | - (ctTOC.TrackData[0].Adr << 24) | - (ctTOC.FirstTrack << 16); - - TOC[100] = (ctTOC.TrackData[ctTOC.LastTrack - 1].Control << 28) | - (ctTOC.TrackData[ctTOC.LastTrack - 1].Adr << 24) | - (ctTOC.LastTrack << 16); - - TOC[101] = (ctTOC.TrackData[ctTOC.LastTrack].Control << 28) | - (ctTOC.TrackData[ctTOC.LastTrack].Adr << 24) | - MSF_TO_FAD(ctTOC.TrackData[ctTOC.LastTrack].Address[1], ctTOC.TrackData[ctTOC.LastTrack].Address[2], ctTOC.TrackData[ctTOC.LastTrack].Address[3]); - -// debugfp = fopen("cot2toc.bin", "wb"); -// fwrite((void *)TOC, 1, 0xCC * 2, debugfp); -// fclose(debugfp); - - return (0xCC * 2); - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int SPTICDReadSectorFAD(u32 FAD, void *buffer) { - // This function is supposed to read exactly 1 -RAW- 2352-byte sector at - // the specified FAD address to buffer. Should return true if successful, - // false if there was an error. - // - // Special Note: To convert from FAD to LBA/LSN, minus 150. - // - // The whole process needed to be changed since I need more control over - // sector detection, etc. Not to mention it means less work for the porter - // since they only have to implement raw sector reading as opposed to - // implementing mode 1, mode 2 form1/form2, -and- raw sector reading. - - DWORD dwBytesReturned; - BOOL success; - - sptd.Length=sizeof(sptd); - sptd.PathId=0; // - sptd.TargetId=0; // Don't need these, they're automatically generated - sptd.Lun=0; // - sptd.CdbLength=12; - sptd.SenseInfoLength=0; // No sense data - sptd.DataIn=SCSI_IOCTL_DATA_IN; - sptd.TimeOutValue=60; // may need to be changed - sptd.DataBuffer=(PVOID)buffer; - sptd.SenseInfoOffset=0; - sptd.DataTransferLength=2352; - - sptd.Cdb[0]=0xBE; // CDB12 code - sptd.Cdb[1]=0; // Sector Type, RELADR - FAD -= 150; - sptd.Cdb[2]=(unsigned char)((FAD & 0xFF000000) >> 24); // lba(byte 1) - sptd.Cdb[3]=(unsigned char)((FAD & 0x00FF0000) >> 16); // lba(byte 2) - sptd.Cdb[4]=(unsigned char)((FAD & 0x0000FF00) >> 8); // lba(byte 3) - sptd.Cdb[5]=(unsigned char)(FAD & 0x000000FF); // lba(byte 4) - sptd.Cdb[6]=0; // number of sectors(byte 1) - sptd.Cdb[7]=0; // number of sectors(byte 2) - sptd.Cdb[8]=1; // number of sectors(byte 3) - sptd.Cdb[9]=0xF8; // Sync + All Headers + User data + EDC/ECC - sptd.Cdb[10]=0; - sptd.Cdb[11]=0; - sptd.Cdb[12]=0; - sptd.Cdb[13]=0; - sptd.Cdb[14]=0; - sptd.Cdb[15]=0; - - success=DeviceIoControl(hCDROM, - IOCTL_SCSI_PASS_THROUGH_DIRECT, - (PVOID)&sptd, (DWORD)sizeof(SCSI_PASS_THROUGH_DIRECT), - NULL, 0, - &dwBytesReturned, - NULL); - - if (!success) - { - return 0; - } - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -void SPTICDReadAheadFAD(u32 FAD) { - // No-op -} - -////////////////////////////////////////////////////////////////////////////// diff --git a/yabause/src/cdbase.c b/yabause/src/cdbase.c deleted file mode 100644 index 3e3d0dc8ac..0000000000 --- a/yabause/src/cdbase.c +++ /dev/null @@ -1,512 +0,0 @@ -/* Copyright 2004-2008 Theo Berkau - Copyright 2005 Joost Peters - Copyright 2005-2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include "cdbase.h" -#include "error.h" -#include "debug.h" - -////////////////////////////////////////////////////////////////////////////// - -// Contains the Dummy and ISO CD Interfaces - -static int DummyCDInit(const char *); -static void DummyCDDeInit(void); -static int DummyCDGetStatus(void); -static s32 DummyCDReadTOC(u32 *); -static int DummyCDReadSectorFAD(u32, void *); -static void DummyCDReadAheadFAD(u32); - -CDInterface DummyCD = { -CDCORE_DUMMY, -"Dummy CD Drive", -DummyCDInit, -DummyCDDeInit, -DummyCDGetStatus, -DummyCDReadTOC, -DummyCDReadSectorFAD, -DummyCDReadAheadFAD, -}; - -static int ISOCDInit(const char *); -static void ISOCDDeInit(void); -static int ISOCDGetStatus(void); -static s32 ISOCDReadTOC(u32 *); -static int ISOCDReadSectorFAD(u32, void *); -static void ISOCDReadAheadFAD(u32); - -CDInterface ISOCD = { -CDCORE_ISO, -"ISO-File Virtual Drive", -ISOCDInit, -ISOCDDeInit, -ISOCDGetStatus, -ISOCDReadTOC, -ISOCDReadSectorFAD, -ISOCDReadAheadFAD, -}; - -////////////////////////////////////////////////////////////////////////////// -// Dummy Interface -////////////////////////////////////////////////////////////////////////////// - -static int DummyCDInit(UNUSED const char *cdrom_name) -{ - // Initialization function. cdrom_name can be whatever you want it to - // be. Obviously with some ports(e.g. the dreamcast port) you probably - // won't even use it. - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static void DummyCDDeInit(void) -{ - // Cleanup function. Enough said. -} - -////////////////////////////////////////////////////////////////////////////// - -static int DummyCDGetStatus(void) -{ - // This function is called periodically to see what the status of the - // drive is. - // - // Should return one of the following values: - // 0 - CD Present, disc spinning - // 1 - CD Present, disc not spinning - // 2 - CD not present - // 3 - Tray open - // - // If you really don't want to bother too much with this function, just - // return status 0. Though it is kind of nice when the bios's cd - // player, etc. recognizes when you've ejected the tray and popped in - // another disc. - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static s32 DummyCDReadTOC(UNUSED u32 *TOC) -{ - // The format of TOC is as follows: - // TOC[0] - TOC[98] are meant for tracks 1-99. Each entry has the - // following format: - // bits 0 - 23: track FAD address - // bits 24 - 27: track addr - // bits 28 - 31: track ctrl - // - // Any Unused tracks should be set to 0xFFFFFFFF - // - // TOC[99] - Point A0 information - // Uses the following format: - // bits 0 - 7: PFRAME(should always be 0) - // bits 7 - 15: PSEC(Program area format: 0x00 - CDDA or CDROM, - // 0x10 - CDI, 0x20 - CDROM-XA) - // bits 16 - 23: PMIN(first track's number) - // bits 24 - 27: first track's addr - // bits 28 - 31: first track's ctrl - // - // TOC[100] - Point A1 information - // Uses the following format: - // bits 0 - 7: PFRAME(should always be 0) - // bits 7 - 15: PSEC(should always be 0) - // bits 16 - 23: PMIN(last track's number) - // bits 24 - 27: last track's addr - // bits 28 - 31: last track's ctrl - // - // TOC[101] - Point A2 information - // Uses the following format: - // bits 0 - 23: leadout FAD address - // bits 24 - 27: leadout's addr - // bits 28 - 31: leadout's ctrl - // - // Special Note: To convert from LBA/LSN to FAD, add 150. - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int DummyCDReadSectorFAD(UNUSED u32 FAD, void * buffer) -{ - // This function is supposed to read exactly 1 -RAW- 2352-byte sector - // at the specified FAD address to buffer. Should return true if - // successful, false if there was an error. - // - // Special Note: To convert from FAD to LBA/LSN, minus 150. - // - // The whole process needed to be changed since I need more control - // over sector detection, etc. Not to mention it means less work for - // the porter since they only have to implement raw sector reading as - // opposed to implementing mode 1, mode 2 form1/form2, -and- raw - // sector reading. - - memset(buffer, 0, 2352); - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -static void DummyCDReadAheadFAD(UNUSED u32 FAD) -{ - // This function is called to tell the driver which sector (FAD - // address) is expected to be read next. If the driver supports - // read-ahead, it should start reading the given sector in the - // background while the emulation continues, so that when the - // sector is actually read with ReadSectorFAD() it'll be available - // immediately. (Note that there's no guarantee this sector will - // actually be requested--the emulated CD might be stopped before - // the sector is read, for example.) - // - // This function should NOT block. If the driver can't perform - // asynchronous reads (or you just don't want to bother handling - // them), make this function a no-op and just read sectors - // normally. -} - -////////////////////////////////////////////////////////////////////////////// -// ISO Interface -////////////////////////////////////////////////////////////////////////////// - -static const s8 syncHdr[12] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 }; -static FILE *isofile=NULL; -static int isofilesize=0; -static int bytesPerSector = 0; -static int isbincue = 0; -static u32 isoTOC[102]; -static struct -{ - u32 fadstart; - u32 fileoffset; -} isooffsettbl[100]; - -#define MSF_TO_FAD(m,s,f) ((m * 4500) + (s * 75) + f) - -////////////////////////////////////////////////////////////////////////////// - -static int InitBinCue(const char *cuefilename) -{ - u32 size; - char *tempbuffer, *tempbuffer2; - unsigned int tracknum; - unsigned int indexnum, min, sec, frame; - unsigned int pregap=0; - char *p, *p2; - - fseek(isofile, 0, SEEK_END); - size = ftell(isofile); - fseek(isofile, 0, SEEK_SET); - - // Allocate buffer with enough space for reading cue - if ((tempbuffer = (char *)calloc(size, 1)) == NULL) - return -1; - - // Skip image filename - if (fscanf(isofile, "FILE \"%*[^\"]\" %*s\r\n") == EOF) - { - free(tempbuffer); - return -1; - } - - // Time to generate TOC - for (;;) - { - // Retrieve a line in cue - if (fscanf(isofile, "%s", tempbuffer) == EOF) - break; - - // Figure out what it is - if (strncmp(tempbuffer, "TRACK", 5) == 0) - { - // Handle accordingly - if (fscanf(isofile, "%d %[^\r\n]\r\n", &tracknum, tempbuffer) == EOF) - break; - - if (strncmp(tempbuffer, "MODE1", 5) == 0 || - strncmp(tempbuffer, "MODE2", 5) == 0) - { - // Figure out the track sector size - bytesPerSector = atoi(tempbuffer + 6); - - // Update toc entry - isoTOC[tracknum-1] = 0x41000000; - } - else if (strncmp(tempbuffer, "AUDIO", 5) == 0) - { - // fix me - // Update toc entry - isoTOC[tracknum-1] = 0x01000000; - } - } - else if (strncmp(tempbuffer, "INDEX", 5) == 0) - { - // Handle accordingly - - if (fscanf(isofile, "%d %d:%d:%d\r\n", &indexnum, &min, &sec, &frame) == EOF) - break; - - if (indexnum == 1) - { - // Update toc entry - isoTOC[tracknum-1] = (isoTOC[tracknum-1] & 0xFF000000) | (MSF_TO_FAD(min, sec, frame) + pregap + 150); - - isooffsettbl[tracknum-1].fadstart = MSF_TO_FAD(min, sec, frame) + pregap + 150; - isooffsettbl[tracknum-1].fileoffset = pregap + 150; - } - } - else if (strncmp(tempbuffer, "PREGAP", 5) == 0) - { - if (fscanf(isofile, "%d:%d:%d\r\n", &min, &sec, &frame) == EOF) - break; - - pregap += MSF_TO_FAD(min, sec, frame); - } - else if (strncmp(tempbuffer, "POSTGAP", 5) == 0) - { - if (fscanf(isofile, "%d:%d:%d\r\n", &min, &sec, &frame) == EOF) - break; - } - } - - // Go back, retrieve image filename - fseek(isofile, 0, SEEK_SET); - fscanf(isofile, "FILE \"%[^\"]\" %*s\r\n", tempbuffer); - fclose(isofile); - - // Now go and open up the image file, figure out its size, etc. - if ((isofile = fopen(tempbuffer, "rb")) == NULL) - { - // Ok, exact path didn't work. Let's trim the path and try opening the - // file from the same directory as the cue. - - // find the start of filename - p = tempbuffer; - - for (;;) - { - if (strcspn(p, "/\\") == strlen(p)) - break; - - p += strcspn(p, "/\\") + 1; - } - - // append directory of cue file with bin filename - if ((tempbuffer2 = (char *)calloc(strlen(cuefilename) + strlen(p) + 1, 1)) == NULL) - { - free(tempbuffer); - return -1; - } - - // find end of path - p2 = (char *)cuefilename; - - for (;;) - { - if (strcspn(p2, "/\\") == strlen(p2)) - break; - p2 += strcspn(p2, "/\\") + 1; - } - - // Make sure there was at least some kind of path, otherwise our - // second check is pretty useless - if (cuefilename == p2 && tempbuffer == p) - { - free(tempbuffer); - free(tempbuffer2); - return -1; - } - - strncpy(tempbuffer2, cuefilename, p2 - cuefilename); - strcat(tempbuffer2, p); - - // Let's give it another try - isofile = fopen(tempbuffer2, "rb"); - free(tempbuffer2); - - if (isofile == NULL) - { - YabSetError(YAB_ERR_FILENOTFOUND, tempbuffer); - free(tempbuffer); - return -1; - } - } - - // buffer is no longer needed - free(tempbuffer); - - fseek(isofile, 0, SEEK_END); - isofilesize = ftell(isofile); - fseek(isofile, 0, SEEK_SET); - - // Now then, generate rest of TOC - isoTOC[99] = (isoTOC[0] & 0xFF000000) | 0x010000; - isoTOC[100] = (isoTOC[tracknum - 1] & 0xFF000000) | (tracknum << 16); - isoTOC[101] = (isoTOC[tracknum - 1] & 0xFF000000) | ((isofilesize / bytesPerSector) + pregap + 150); - - isooffsettbl[tracknum].fileoffset = 0; - isooffsettbl[tracknum].fadstart = 0xFFFFFFFF; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int ISOCDInit(const char * iso) { - char header[6]; - - memset(isoTOC, 0xFF, 0xCC * 2); - - if (!iso) - return -1; - - if (!(isofile = fopen(iso, "rb"))) - { - YabSetError(YAB_ERR_FILENOTFOUND, (char *)iso); - return -1; - } - - fread((void *)header, 1, 6, isofile); - - // Figure out what kind of image format we're dealing with - if (strncmp(header, "FILE \"", 6) == 0) - { - // It's a BIN/CUE - isbincue = 1; - - // Generate TOC for bin file - if (InitBinCue(iso) != 0) - { - if (isofile) - free(isofile); - return -1; - } - } - else - { - // Assume it's an ISO file - isbincue = 0; - - fseek(isofile, 0, SEEK_END); - isofilesize = ftell(isofile); - - if (0 == (isofilesize % 2048)) - bytesPerSector = 2048; - else if (0 == (isofilesize % 2352)) - bytesPerSector = 2352; - else - { - YabSetError(YAB_ERR_OTHER, "Unsupported CD image!\n"); - - return -1; - } - - // Generate TOC - isoTOC[0] = 0x41000096; - isoTOC[99] = 0x41010000; - isoTOC[100] = 0x41010000; - isoTOC[101] = (0x41 << 24) | (isofilesize / bytesPerSector); //this isn't fully correct, but it does the job for now. - - isooffsettbl[0].fileoffset = 150; - isooffsettbl[0].fadstart = 150; - isooffsettbl[1].fileoffset = 0; - isooffsettbl[1].fadstart = 0xFFFFFFFF; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static void ISOCDDeInit(void) { - if (isofile) - { - fclose(isofile); - } -} - -////////////////////////////////////////////////////////////////////////////// - -static int ISOCDGetStatus(void) { - return isofile != NULL ? 0 : 2; -} - -////////////////////////////////////////////////////////////////////////////// - -static s32 ISOCDReadTOC(u32 * TOC) { - memcpy(TOC, isoTOC, 0xCC * 2); - - return (0xCC * 2); -} - -////////////////////////////////////////////////////////////////////////////// - -static int ISOCDReadSectorFAD(u32 FAD, void *buffer) { - int sector; - int i; - - assert(isofile); - - memset(buffer, 0, 2352); - - for (i = 1; i < 100; i++) - { - if (FAD < isooffsettbl[i].fadstart) - { - sector = FAD - isooffsettbl[i-1].fileoffset; - break; - } - } - if (i == 100) { - CDLOG("Warning: Sector not found in track list"); - return 0; - } - - if ((sector * bytesPerSector) >= isofilesize) { - CDLOG("Warning: Trying to read beyond end of CD image! (sector: %d)\n", sector); - return 0; - } - - fseek(isofile, sector * bytesPerSector, SEEK_SET); - - if (2048 == bytesPerSector) { - memcpy(buffer, syncHdr, 12); - fread((char *)buffer + 0x10, bytesPerSector, 1, isofile); - } else { //2352 - fread(buffer, bytesPerSector, 1, isofile); - } - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -static void ISOCDReadAheadFAD(UNUSED u32 FAD) -{ - // No-op -} - -////////////////////////////////////////////////////////////////////////////// - diff --git a/yabause/src/cdbase.h b/yabause/src/cdbase.h deleted file mode 100644 index 624716b4ba..0000000000 --- a/yabause/src/cdbase.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright 2004-2005 Theo Berkau - Copyright 2005 Joost Peters - Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CDBASE_H -#define CDBASE_H - -#include -#include "core.h" - -#define CDCORE_DEFAULT -1 -#define CDCORE_DUMMY 0 -#define CDCORE_ISO 1 -#define CDCORE_ARCH 2 - -typedef struct -{ - int id; - const char *Name; - int (*Init)(const char *); - void (*DeInit)(void); - int (*GetStatus)(void); - s32 (*ReadTOC)(u32 *TOC); - int (*ReadSectorFAD)(u32 FAD, void *buffer); - void (*ReadAheadFAD)(u32 FAD); -} CDInterface; - -extern CDInterface DummyCD; - -extern CDInterface ISOCD; - -extern CDInterface ArchCD; - -#endif diff --git a/yabause/src/cheat.c b/yabause/src/cheat.c deleted file mode 100644 index b3e001a715..0000000000 --- a/yabause/src/cheat.c +++ /dev/null @@ -1,383 +0,0 @@ -/* Copyright 2007-2008 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include "cheat.h" -#include "memory.h" -#include "sh2core.h" - -cheatlist_struct *cheatlist=NULL; -int numcheats=0; -int cheatsize; - -#define DoubleWordSwap(x) x = (((x & 0xFF000000) >> 24) + \ - ((x & 0x00FF0000) >> 8) + \ - ((x & 0x0000FF00) << 8) + \ - ((x & 0x000000FF) << 24)); - -////////////////////////////////////////////////////////////////////////////// - -int CheatInit(void) -{ - cheatsize = 10; - if ((cheatlist = (cheatlist_struct *)calloc(cheatsize, sizeof(cheatlist_struct))) == NULL) - return -1; - cheatlist[0].type = CHEATTYPE_NONE; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void CheatDeInit(void) -{ - if (cheatlist) - free(cheatlist); - cheatlist = NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatAddCode(int type, u32 addr, u32 val) -{ - cheatlist[numcheats].type = type; - cheatlist[numcheats].addr = addr; - cheatlist[numcheats].val = val; - cheatlist[numcheats].desc = NULL; - cheatlist[numcheats].enable = 1; - numcheats++; - - // Make sure we still have room - if (numcheats >= cheatsize) - { - cheatlist = realloc(cheatlist, sizeof(cheatlist_struct) * (cheatsize * 2)); - cheatsize *= 2; - } - - cheatlist[numcheats].type = CHEATTYPE_NONE; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatAddARCode(const char *code) -{ - unsigned long addr; - unsigned short val; - sscanf(code, "%08lX %04hX", &addr, &val); - switch (addr >> 28) - { - case 0x0: - // One time word write(fix me) - return -1; - case 0x1: - return CheatAddCode(CHEATTYPE_WORDWRITE, addr & 0x0FFFFFFF, val); - case 0x3: - return CheatAddCode(CHEATTYPE_BYTEWRITE, addr & 0x0FFFFFFF, val); - case 0xD: - return CheatAddCode(CHEATTYPE_ENABLE, addr & 0x0FFFFFFF, val); - default: return -1; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int FindCheat(int type, u32 addr, u32 val) -{ - int i; - - for (i = 0; i < numcheats; i++) - { - if (cheatlist[i].type == type && - cheatlist[i].addr == addr && - cheatlist[i].val == val) - return i; - } - - return -1; -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatChangeDescription(int type, u32 addr, u32 val, char *desc) -{ - int i; - - if ((i = FindCheat(type, addr, val)) == -1) - // There is no matches, so let's bail - return -1; - - return CheatChangeDescriptionByIndex(i, desc); -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatChangeDescriptionByIndex(int i, char *desc) -{ - // Free old description(if existing) - if (cheatlist[i].desc) - free(cheatlist[i].desc); - - cheatlist[i].desc = strdup(desc); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatRemoveCode(int type, u32 addr, u32 val) -{ - int i; - - if ((i = FindCheat(type, addr, val)) == -1) - // There is no matches, so let's bail - return -1; - - return CheatRemoveCodeByIndex(i); -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatRemoveCodeByIndex(int i) -{ - // If there's a description, free the memory. - if (cheatlist[i].desc) - { - free(cheatlist[i].desc); - cheatlist[i].desc = NULL; - } - - // Move all entries one forward - for (; i < numcheats-1; i++) - memcpy(&cheatlist[i], &cheatlist[i+1], sizeof(cheatlist_struct)); - - numcheats--; - - // Set the last one to type none - cheatlist[numcheats].type = CHEATTYPE_NONE; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatRemoveARCode(const char *code) -{ - unsigned long addr; - unsigned short val; - sscanf(code, "%08lX %04hX", &addr, &val); - - switch (addr >> 28) - { - case 0x1: - return CheatRemoveCode(CHEATTYPE_WORDWRITE, addr & 0x0FFFFFFF, val); - case 0x3: - return CheatRemoveCode(CHEATTYPE_BYTEWRITE, addr & 0x0FFFFFFF, val); - case 0xD: - return CheatRemoveCode(CHEATTYPE_ENABLE, addr & 0x0FFFFFFF, val); - default: return -1; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void CheatClearCodes(void) -{ - while (numcheats > 0) - CheatRemoveCodeByIndex(numcheats-1); -} - -////////////////////////////////////////////////////////////////////////////// - -void CheatEnableCode(int index) -{ - cheatlist[index].enable = 1; -} - -////////////////////////////////////////////////////////////////////////////// - -void CheatDisableCode(int index) -{ - cheatlist[index].enable = 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void CheatDoPatches(void) -{ - int i; - - for (i = 0; ; i++) - { - switch (cheatlist[i].type) - { - case CHEATTYPE_NONE: - return; - case CHEATTYPE_ENABLE: - if (cheatlist[i].enable == 0) - continue; - if (MappedMemoryReadWord(cheatlist[i].addr) != cheatlist[i].val) - return; - break; - case CHEATTYPE_BYTEWRITE: - if (cheatlist[i].enable == 0) - continue; - MappedMemoryWriteByte(cheatlist[i].addr, (u8)cheatlist[i].val); - SH2WriteNotify(cheatlist[i].addr, 1); - break; - case CHEATTYPE_WORDWRITE: - if (cheatlist[i].enable == 0) - continue; - MappedMemoryWriteWord(cheatlist[i].addr, (u16)cheatlist[i].val); - SH2WriteNotify(cheatlist[i].addr, 2); - break; - case CHEATTYPE_LONGWRITE: - if (cheatlist[i].enable == 0) - continue; - MappedMemoryWriteLong(cheatlist[i].addr, cheatlist[i].val); - SH2WriteNotify(cheatlist[i].addr, 4); - break; - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -cheatlist_struct *CheatGetList(int *cheatnum) -{ - if (cheatnum == NULL) - return NULL; - - *cheatnum = numcheats; - return cheatlist; -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatSave(const char *filename) -{ - FILE *fp; - int i; - int num; - IOCheck_struct check; - - if (!filename) - return -1; - - if ((fp = fopen(filename, "wb")) == NULL) - return -1; - - fprintf(fp, "YCHT"); - num = numcheats; -#ifndef WORDS_BIGENDIAN - DoubleWordSwap(num); -#endif - ywrite(&check, (void *)&num, sizeof(int), 1, fp); - - for(i = 0; i < numcheats; i++) - { - u8 descsize; - cheatlist_struct cheat; - - memcpy(&cheat, &cheatlist[i], sizeof(cheatlist_struct)); -#ifndef WORDS_BIGENDIAN - DoubleWordSwap(cheat.type); - DoubleWordSwap(cheat.addr); - DoubleWordSwap(cheat.val); - DoubleWordSwap(cheat.enable); -#endif - ywrite(&check, (void *)&cheat.type, sizeof(int), 1, fp); - ywrite(&check, (void *)&cheat.addr, sizeof(u32), 1, fp); - ywrite(&check, (void *)&cheat.val, sizeof(u32), 1, fp); - descsize = (u8)strlen(cheatlist[i].desc)+1; - ywrite(&check, (void *)&descsize, sizeof(u8), 1, fp); - ywrite(&check, (void *)cheatlist[i].desc, sizeof(char), descsize, fp); - ywrite(&check, (void *)&cheat.enable, sizeof(int), 1, fp); - } - - fclose (fp); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int CheatLoad(const char *filename) -{ - FILE *fp; - int i; - char id[4]; - char desc[256]; - IOCheck_struct check; - - if (!filename) - return -1; - - if ((fp = fopen(filename, "rb")) == NULL) - return -1; - - yread(&check, (void *)id, 1, 4, fp); - if (strncmp(id, "YCHT", 4) != 0) - { - fclose(fp); - return -2; - } - - CheatClearCodes(); - - yread(&check, (void *)&numcheats, sizeof(int), 1, fp); -#ifndef WORDS_BIGENDIAN - DoubleWordSwap(numcheats); -#endif - - if (numcheats >= cheatsize) - { - cheatlist = realloc(cheatlist, sizeof(cheatlist_struct) * (cheatsize * 2)); - memset((void *)cheatlist, 0, sizeof(cheatlist_struct) * (cheatsize * 2)); - cheatsize *= 2; - } - - for(i = 0; i < numcheats; i++) - { - u8 descsize; - - yread(&check, (void *)&cheatlist[i].type, sizeof(int), 1, fp); - yread(&check, (void *)&cheatlist[i].addr, sizeof(u32), 1, fp); - yread(&check, (void *)&cheatlist[i].val, sizeof(u32), 1, fp); - yread(&check, (void *)&descsize, sizeof(u8), 1, fp); - yread(&check, (void *)desc, sizeof(char), descsize, fp); - CheatChangeDescriptionByIndex(i, desc); - yread(&check, (void *)&cheatlist[i].enable, sizeof(int), 1, fp); -#ifndef WORDS_BIGENDIAN - DoubleWordSwap(cheatlist[i].type); - DoubleWordSwap(cheatlist[i].addr); - DoubleWordSwap(cheatlist[i].val); - DoubleWordSwap(cheatlist[i].enable); -#endif - } - - fclose (fp); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - diff --git a/yabause/src/cheat.h b/yabause/src/cheat.h deleted file mode 100644 index 009b2b4449..0000000000 --- a/yabause/src/cheat.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright 2007 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CHEAT_H -#define CHEAT_H - -#include "core.h" - -enum -{ - CHEATTYPE_NONE=0, - CHEATTYPE_ENABLE, - CHEATTYPE_BYTEWRITE, - CHEATTYPE_WORDWRITE, - CHEATTYPE_LONGWRITE -}; - -typedef struct -{ - int type; - u32 addr; - u32 val; - char *desc; - int enable; -} cheatlist_struct; - -int CheatInit(void); -void CheatDeInit(void); -int CheatAddCode(int type, u32 addr, u32 val); -int CheatAddARCode(const char *code); -int CheatChangeDescription(int type, u32 addr, u32 val, char *desc); -int CheatChangeDescriptionByIndex(int i, char *desc); -int CheatRemoveCode(int type, u32 addr, u32 val); -int CheatRemoveCodeByIndex(int i); -int CheatRemoveARCode(const char *code); -void CheatClearCodes(void); -void CheatEnableCode(int index); -void CheatDisableCode(int index); -void CheatDoPatches(void); -cheatlist_struct *CheatGetList(int *cheatnum); -int CheatSave(const char *filename); -int CheatLoad(const char *filename); - -#endif diff --git a/yabause/src/cocoa/CMake-Info.plist b/yabause/src/cocoa/CMake-Info.plist deleted file mode 100644 index c045bd04b9..0000000000 --- a/yabause/src/cocoa/CMake-Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - Yabause - CFBundleIconFile - Yabause.icns - CFBundleIdentifier - org.yabause.yabause.cocoa - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Yabause - CFBundlePackageType - APPL - CFBundleSignature - ???? - CFBundleShortVersionString - ${YAB_VERSION} - CFBundleVersion - - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - NSHumanReadableCopyright - Copyright © Yabause Team - - diff --git a/yabause/src/cocoa/CMakeLists.txt b/yabause/src/cocoa/CMakeLists.txt deleted file mode 100644 index 4bfab44374..0000000000 --- a/yabause/src/cocoa/CMakeLists.txt +++ /dev/null @@ -1,73 +0,0 @@ -project(yabause-cocoa) - -yab_port_start() - -find_library(AUDIO_LIBRARY AudioUnit) - -if (NOT AUDIO_LIBRARY) - return() -endif() - -set(yabause_cocoa_SOURCES - main.m - PerCocoa.m - YabauseButtonFormatter.m - YabauseController.m - YabauseGLView.m - YabausePrefsController.m - vidgcd.c - vidgcd.h -) - -set(yabause_cocoa_XIBS English.lproj/MainMenu) - -include_directories("${CMAKE_CURRENT_SOURCE_DIR}/..") - -add_executable(yabause-cocoa MACOSX_BUNDLE ${yabause_cocoa_SOURCES}) -target_link_libraries(yabause-cocoa yabause ${YABAUSE_LIBRARIES} - ${AUDIO_LIBRARY}) - -yab_port_stop() -set_target_properties(yabause-cocoa PROPERTIES OUTPUT_NAME Yabause) - -set_target_properties(yabause-cocoa PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/CMake-Info.plist) - -find_program(IBTOOL ibtool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin") -if (${IBTOOL} STREQUAL "IBTOOL-NOTFOUND") - message(SEND_ERROR "ibtool can not be found and is needed to compile the .xib files. It should have been installed with - the Apple developer tools. The default system paths were searched in addition to ${OSX_DEVELOPER_ROOT}/usr/bin") -endif() - -add_custom_command( - TARGET yabause-cocoa PRE_BUILD - COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/MacOS) - -add_custom_command( - TARGET yabause-cocoa PRE_BUILD - COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/Resources/English.lproj) - -foreach(xib ${yabause_cocoa_XIBS}) - add_custom_command( - TARGET yabause-cocoa POST_BUILD - COMMAND ${IBTOOL} --errors --warnings --notices - --output-format human-readable-text - --compile ${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/Resources/${xib}.nib - ${CMAKE_CURRENT_SOURCE_DIR}/${xib}.xib - COMMENT "Compiling ${CMAKE_CURRENT_SOURCE_DIR}/${xib}.xib") - -endforeach() - -add_custom_command( - TARGET yabause-cocoa POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/Yabause.icns ${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/Resources) - -add_custom_command( - TARGET yabause-cocoa POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/resources/controller.png ${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/Contents/Resources) - -install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Yabause.app/" DESTINATION "Yabause.app" USE_SOURCE_PERMISSIONS) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../AUTHORS DESTINATION ".") -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../ChangeLog DESTINATION ".") -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../COPYING DESTINATION ".") -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../README DESTINATION ".") -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../README.MAC DESTINATION ".") diff --git a/yabause/src/cocoa/English.lproj/InfoPlist.strings b/yabause/src/cocoa/English.lproj/InfoPlist.strings deleted file mode 100644 index b92732c79e..0000000000 --- a/yabause/src/cocoa/English.lproj/InfoPlist.strings +++ /dev/null @@ -1 +0,0 @@ -/* Localized versions of Info.plist keys */ diff --git a/yabause/src/cocoa/English.lproj/MainMenu.xib b/yabause/src/cocoa/English.lproj/MainMenu.xib deleted file mode 100644 index ac87a6f20e..0000000000 --- a/yabause/src/cocoa/English.lproj/MainMenu.xib +++ /dev/null @@ -1,6148 +0,0 @@ - - - - 1060 - 12C54 - 851 - 1187.34 - 625.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 851 - - - YES - - - - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - YES - - NSApplication - - - FirstResponder - - - NSApplication - - - NSFontManager - - - Main Menu - - YES - - - Yabause - - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - submenuAction: - - Yabause - - YES - - - About Yabause - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Preferences… - , - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Services - - 2147483647 - - - submenuAction: - - Services - - YES - - _NSServicesMenu - - - - - YES - YES - - - 2147483647 - - - - - - Hide Yabause - h - 1048576 - 2147483647 - - - - - - Hide Others - h - 1572864 - 2147483647 - - - - - - Show All - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Quit Yabause - q - 1048576 - 2147483647 - - - - - _NSAppleMenu - - - - - File - - 2147483647 - - - submenuAction: - - File - - YES - - - Run CD-ROM - o - 1048576 - 2147483647 - - - - - - Run Image - O - 1048576 - 2147483647 - - - - - - Run BIOS - o - 1572864 - 2147483647 - - - - - - - - - Emulation - - 2147483647 - - - submenuAction: - - Emulation - - YES - - - Pause - p - 1048576 - 2147483647 - - - - - - Reset - r - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Enable Frameskip - - 2147483647 - 1 - - - - - - - - - View - - 2147483647 - - - submenuAction: - - View - - YES - - - Show Framerate - - 2147483647 - - - 7 - - - - Fullscreen - f - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Layers - - 2147483647 - - - submenuAction: - - Layers - - YES - - - VDP1 - - 2147483647 - 1 - - - 1 - - - - NBG0 - - 2147483647 - 1 - - - 2 - - - - NBG1 - - 2147483647 - 1 - - - 3 - - - - NBG2 - - 2147483647 - 1 - - - 4 - - - - NBG3 - - 2147483647 - 1 - - - 5 - - - - RBG0 - - 2147483647 - 1 - - - 6 - - - - - - - - - - Window - - 2147483647 - - - submenuAction: - - Window - - YES - - - Minimize - m - 1048576 - 2147483647 - - - - - - Zoom - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Bring All to Front - - 2147483647 - - - - - _NSWindowsMenu - - - - - Help - - 2147483647 - - - submenuAction: - - Help - - YES - - - Yabause Help - ? - 1048576 - 2147483647 - - - - - _NSHelpMenu - - - - _NSMainMenu - - - 271 - 2 - {{168, 237}, {320, 224}} - 1685585920 - Yabause - NSWindow - - - {1.7976931348623157e+308, 1.7976931348623157e+308} - {320, 224} - - - 274 - - YES - - - 274 - {320, 224} - - YabauseGLView - - - {320, 224} - - {{0, 0}, {1440, 878}} - {320, 246} - {1.7976931348623157e+308, 1.7976931348623157e+308} - YES - - - YabauseController - - - 7 - 2 - {{162, 79}, {484, 400}} - -193462272 - Preferences - NSPanel - - - {1.7976931348623157e+308, 1.7976931348623157e+308} - - - 256 - - YES - - - 12 - {{13, 10}, {458, 384}} - - - YES - - 1 - - - 256 - - YES - - - 12 - - YES - - - 274 - - YES - - - 268 - {{18, 36}, {296, 22}} - - YES - - -1804599231 - 272630784 - - - LucidaGrande - 13 - 1040 - - Not Set - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - 3 - MAA - - - - NO - - - - 268 - {{316, 30}, {96, 32}} - - YES - - 67108864 - 134217728 - Browse - - - -2038284288 - 129 - - - 200 - 25 - - NO - - - - 268 - {{16, 12}, {163, 18}} - - YES - - -2080374784 - 0 - Enable BIOS Emulation - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {{1, 1}, {424, 68}} - - - - {{6, 254}, {426, 84}} - - {0, 0} - - 67108864 - 0 - BIOS - - LucidaGrande - 11 - 3088 - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - - 12 - - YES - - - 274 - - YES - - - 268 - {{10, 10}, {262, 26}} - - YES - - -2076180416 - 2048 - - - 109199360 - 129 - - - 400 - 75 - - - Auto-detect - - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - OtherViews - - YES - - - - Japan (NTSC) - - 2147483647 - - - _popUpItemAction: - 1 - - - - - Asia (NTSC) - - 2147483647 - - - _popUpItemAction: - 2 - - - - - North America (NTSC) - - 2147483647 - - - _popUpItemAction: - 4 - - - - - Central/South America (NTSC) - - 2147483647 - - - _popUpItemAction: - 5 - - - - - Korea (NTSC) - - 2147483647 - - - _popUpItemAction: - 6 - - - - - Asia (PAL) - - 2147483647 - - - _popUpItemAction: - 10 - - - - - Europe/Australia (PAL) - - 2147483647 - - - _popUpItemAction: - 12 - - - - - Central/South America (PAL) - - 2147483647 - - - _popUpItemAction: - 13 - - - - - - 1 - YES - YES - 2 - - NO - - - {{1, 1}, {424, 44}} - - - - {{6, 124}, {426, 60}} - - {0, 0} - - 67108864 - 0 - Region - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - - 12 - - YES - - - 274 - - YES - - - 268 - {{18, 14}, {296, 22}} - - YES - - -1804599231 - 272630784 - - - Not Set - - YES - - - - NO - - - - 268 - {{316, 8}, {96, 32}} - - YES - - 67108864 - 134217728 - Browse - - - -2038284288 - 129 - - - 200 - 25 - - NO - - - {{1, 1}, {424, 46}} - - - - {{6, 188}, {426, 62}} - - {0, 0} - - 67108864 - 0 - MPEG ROM - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - {{10, 33}, {438, 338}} - - - General - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - - - 2 - - - 256 - - YES - - - 12 - - YES - - - 256 - - YES - - - 268 - {{15, 10}, {262, 26}} - - YES - - -2076180416 - 2048 - - - 109199360 - 129 - - - 400 - 75 - - - Software Video Core - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - 2 - - - YES - - OtherViews - - YES - - - OpenGL Hardware Video Core - - 1048576 - 2147483647 - - - _popUpItemAction: - 1 - - - - - - Grand Central Dispatch Software Core - - 2147483647 - - - _popUpItemAction: - 10 - - - - - Disable Video - - 2147483647 - - - _popUpItemAction: - - - - - - 1 - 1 - YES - YES - 2 - - NO - - - {{1, 1}, {424, 44}} - - - - {{6, 278}, {426, 60}} - - {0, 0} - - 67108864 - 0 - Video Core - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - - 12 - - YES - - - 256 - - YES - - - 268 - {{15, 10}, {262, 26}} - - YES - - -2076180416 - 2048 - - - 109199360 - 129 - - - 400 - 75 - - - Core Audio Sound Core - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - 3 - - - YES - - OtherViews - - YES - - - - Disable Sound - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - - 1 - YES - YES - 2 - - NO - - - {{1, 1}, {424, 44}} - - - - {{6, 214}, {426, 60}} - - {0, 0} - - 67108864 - 0 - Sound Core - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - {{10, 33}, {438, 338}} - - Video/Sound - - - - - Item 2 - - - 256 - - YES - - - 12 - - YES - - - 256 - - YES - - - 268 - {{18, 14}, {296, 22}} - - YES - - -1804599231 - 272630784 - - - Not Set - - YES - - - - NO - - - - 268 - {{316, 8}, {96, 32}} - - YES - - 67108864 - 134217728 - Browse - - - -2038284288 - 129 - - - 200 - 25 - - NO - - - {{1, 1}, {424, 46}} - - - - {{6, 276}, {426, 62}} - - {0, 0} - - 67108864 - 0 - Internal Memory (BRAM) - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - - 12 - - YES - - - 256 - - YES - - - 268 - {{15, 52}, {262, 26}} - - YES - - -2076180416 - 2048 - - - 109199360 - 129 - - - 400 - 75 - - - None - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - OtherViews - - YES - - - - Pro Action Replay - - 1048576 - 2147483647 - - - _popUpItemAction: - 1 - - - - - Backup RAM (4 Mbit) - - 1048576 - 2147483647 - - - _popUpItemAction: - 2 - - - - - Backup RAM (8 Mbit) - - 2147483647 - - - _popUpItemAction: - 3 - - - - - Backup RAM (16 Mbit) - - 2147483647 - - - _popUpItemAction: - 4 - - - - - Backup RAM (32 Mbit) - - 2147483647 - - - _popUpItemAction: - 5 - - - - - DRAM (8 Mbit) - - 2147483647 - - - _popUpItemAction: - 6 - - - - - DRAM (32 Mbit) - - 2147483647 - - - _popUpItemAction: - 7 - - - - - Netlink - - 2147483647 - - - _popUpItemAction: - 8 - - - - - ROM (16 Mbit) - - 2147483647 - - - _popUpItemAction: - 9 - - - - - - 1 - YES - YES - 2 - - NO - - - - 268 - {{18, 14}, {296, 22}} - - YES - - -1267728319 - 272630784 - - - No file required for the selected cartridge - - YES - - - - NO - - - - 268 - {{316, 8}, {96, 32}} - - YES - - 603979776 - 134217728 - Browse - - - -2038284288 - 129 - - - 200 - 25 - - NO - - - {{1, 1}, {424, 86}} - - - - {{6, 170}, {426, 102}} - - {0, 0} - - 67108864 - 0 - Cartridge - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - {{10, 33}, {438, 338}} - - Memory - - - - - Item 3 - - - 256 - - YES - - - 12 - {{10, 7}, {418, 324}} - - - YES - - 1 - - - 256 - - YES - - - 268 - - YES - - YES - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - - {{14, 14}, {370, 264}} - - YES - - 0 - 33554432 - - NSImage - controller - - 0 - 0 - 3 - NO - - NO - YES - - - - 268 - {{292, 177}, {17, 18}} - - 12 - YES - - -2080374784 - 134217728 - Z - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{263, 164}, {17, 18}} - - 11 - YES - - -2080374784 - 134217728 - Y - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{237, 145}, {17, 18}} - - 10 - YES - - -2080374784 - 134217728 - X - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{278, 130}, {17, 18}} - - 8 - YES - - -2080374784 - 134217728 - B - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{314, 145}, {17, 18}} - - 9 - YES - - -2080374784 - 134217728 - C - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{248, 210}, {67, 18}} - - 4 - YES - - -2080374784 - 134217728 - R Trigger - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{102, 162}, {21, 18}} - - YES - - -2080374784 - 134217728 - - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{103, 117}, {21, 18}} - - 2 - YES - - -2080374784 - 134217728 - - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{125, 139}, {21, 18}} - - 1 - YES - - -2080374784 - 134217728 - - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{81, 139}, {21, 18}} - - 3 - YES - - -2080374784 - 134217728 - - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{81, 210}, {65, 18}} - - 5 - YES - - -2080374784 - 134217728 - L Trigger - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{180, 111}, {38, 18}} - - 6 - YES - - -2080374784 - 134217728 - Start - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{248, 111}, {17, 18}} - - 7 - YES - - -2080374784 - 134217728 - A - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - {{10, 33}, {398, 278}} - - - Controller 1 - - - - - 2 - - - 256 - - YES - - - 268 - - YES - - YES - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - - {{14, 14}, {370, 264}} - - YES - - 0 - 33554432 - - 0 - 0 - 3 - NO - - NO - YES - - - - 268 - {{292, 177}, {17, 18}} - - 25 - YES - - -2080374784 - 134217728 - Z - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{263, 164}, {17, 18}} - - 24 - YES - - -2080374784 - 134217728 - Y - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{237, 145}, {17, 18}} - - 23 - YES - - -2080374784 - 134217728 - X - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{278, 130}, {17, 18}} - - 21 - YES - - -2080374784 - 134217728 - B - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{314, 145}, {17, 18}} - - 22 - YES - - -2080374784 - 134217728 - C - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{248, 210}, {67, 18}} - - 17 - YES - - -2080374784 - 134217728 - R Trigger - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{102, 162}, {21, 18}} - - 13 - YES - - -2080374784 - 134217728 - - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{103, 117}, {21, 18}} - - 15 - YES - - -2080374784 - 134217728 - - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{125, 139}, {21, 18}} - - 14 - YES - - -2080374784 - 134217728 - - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{81, 139}, {21, 18}} - - 16 - YES - - -2080374784 - 134217728 - - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{81, 210}, {65, 18}} - - 18 - YES - - -2080374784 - 134217728 - L Trigger - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{180, 111}, {38, 18}} - - 19 - YES - - -2080374784 - 134217728 - Start - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - - 268 - {{248, 111}, {17, 18}} - - 20 - YES - - -2080374784 - 134217728 - A - - - -2033434624 - 160 - - - 400 - 75 - - NO - - - {{10, 33}, {398, 278}} - - Controller 2 - - - - - - - 0 - YES - YES - - YES - - - - - {{10, 33}, {438, 338}} - - Input - - - - - - - 0 - YES - YES - - YES - - - - - {484, 400} - - - {{0, 0}, {1440, 878}} - {1.7976931348623157e+308, 1.7976931348623157e+308} - YES - - - YabausePrefsController - - - 17 - 2 - {{162, 364}, {220, 115}} - -461897728 - Button Assignment - NSPanel - - - {1.7976931348623157e+308, 1.7976931348623157e+308} - - - 256 - - YES - - - 268 - {{17, 78}, {186, 17}} - - YES - - 68157504 - 138413056 - Current Assignment: - - - - - 6 - System - controlTextColor - - - - NO - - - - 268 - {{110, 12}, {96, 32}} - - YES - - 67108864 - 134217728 - Cancel - - - -2038284288 - 129 - - Gw - 200 - 25 - - NO - - - - 268 - {{14, 12}, {96, 32}} - - YES - - 67108864 - 134217728 - OK - - - -2038284288 - 129 - - DQ - 200 - 25 - - NO - - - - 268 - {{62, 48}, {96, 22}} - - YES - - -1805647807 - 138414080 - - - - YES - - - - NO - - - {220, 115} - - - {{0, 0}, {1440, 878}} - {1.7976931348623157e+308, 1.7976931348623157e+308} - YES - - - YabauseButtonFormatter - - - - - YES - - - performMiniaturize: - - - - 37 - - - - arrangeInFront: - - - - 39 - - - - orderFrontStandardAboutPanel: - - - - 142 - - - - performZoom: - - - - 240 - - - - showHelp: - - - - 360 - - - - hide: - - - - 367 - - - - hideOtherApplications: - - - - 368 - - - - terminate: - - - - 369 - - - - unhideAllApplications: - - - - 370 - - - - window - - - - 853 - - - - view - - - - 855 - - - - toggleFullscreen: - - - - 858 - - - - toggle: - - - - 875 - - - - toggle: - - - - 876 - - - - toggle: - - - - 877 - - - - toggle: - - - - 878 - - - - toggle: - - - - 879 - - - - toggle: - - - - 880 - - - - toggle: - - - - 881 - - - - toggleFrameskip: - - - - 883 - - - - runCD: - - - - 884 - - - - runBIOS: - - - - 885 - - - - pause: - - - - 893 - - - - reset: - - - - 894 - - - - delegate - - - - 897 - - - - prefsPane - - - - 1048 - - - - showPreferences: - - - - 1049 - - - - region - - - - 1051 - - - - mpegPath - - - - 1052 - - - - biosPath - - - - 1053 - - - - emulateBios - - - - 1054 - - - - videoCore - - - - 1055 - - - - soundCore - - - - 1056 - - - - cartType - - - - 1058 - - - - cartPath - - - - 1059 - - - - cartBrowse - - - - 1060 - - - - regionSelected: - - - - 1061 - - - - videoCoreSelected: - - - - 1062 - - - - soundCoreSelected: - - - - 1063 - - - - cartSelected: - - - - 1064 - - - - prefs - - - - 1065 - - - - bramBrowse: - - - - 1066 - - - - cartBrowse: - - - - 1067 - - - - biosBrowse: - - - - 1068 - - - - mpegBrowse: - - - - 1069 - - - - delegate - - - - 1070 - - - - bramPath - - - - 1072 - - - - frameskip - - - - 1073 - - - - biosToggle: - - - - 1074 - - - - delegate - - - - 1076 - - - - delegate - - - - 1077 - - - - delegate - - - - 1078 - - - - delegate - - - - 1079 - - - - buttonAssignment - - - - 1115 - - - - buttonSelect: - - - - 1120 - - - - prefsPane - - - - 1121 - - - - buttonSetOk: - - - - 1128 - - - - buttonSetCancel: - - - - 1129 - - - - buttonBox - - - - 1134 - - - - formatter - - - - 1136 - - - - delegate - - - - 1137 - - - - buttonSelect: - - - - 1227 - - - - buttonSelect: - - - - 1228 - - - - buttonSelect: - - - - 1229 - - - - buttonSelect: - - - - 1230 - - - - buttonSelect: - - - - 1231 - - - - buttonSelect: - - - - 1232 - - - - buttonSelect: - - - - 1233 - - - - buttonSelect: - - - - 1234 - - - - buttonSelect: - - - - 1235 - - - - buttonSelect: - - - - 1236 - - - - buttonSelect: - - - - 1237 - - - - buttonSelect: - - - - 1238 - - - - buttonSelect: - - - - 1239 - - - - buttonSelect: - - - - 1240 - - - - buttonSelect: - - - - 1241 - - - - buttonSelect: - - - - 1242 - - - - buttonSelect: - - - - 1244 - - - - buttonSelect: - - - - 1245 - - - - buttonSelect: - - - - 1246 - - - - buttonSelect: - - - - 1247 - - - - buttonSelect: - - - - 1248 - - - - buttonSelect: - - - - 1249 - - - - buttonSelect: - - - - 1250 - - - - buttonSelect: - - - - 1251 - - - - buttonSelect: - - - - 1252 - - - - runISO: - - - - 1254 - - - - - YES - - 0 - - YES - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 29 - - - YES - - - - - - - - - - - 19 - - - YES - - - - - - 56 - - - YES - - - - - - 103 - - - YES - - - - - - 83 - - - YES - - - - - - 81 - - - YES - - - - - - - - 72 - - - - - 106 - - - YES - - - - - - 111 - - - - - 57 - - - YES - - - - - - - - - - - - - - - - 58 - - - - - 134 - - - - - 150 - - - - - 136 - - - - - 144 - - - - - 129 - - - - - 143 - - - - - 236 - - - - - 131 - - - YES - - - - - - 149 - - - - - 145 - - - - - 130 - - - - - 24 - - - YES - - - - - - - - - 92 - - - - - 5 - - - - - 239 - - - - - 23 - - - - - 371 - - - - - 843 - - - YES - - - - - - 844 - - - YES - - - - - - 846 - - - - - 847 - - - YES - - - - - - 848 - - - YES - - - - - - - - - 854 - - - - - 882 - - - - - 856 - - - - - 886 - - - YES - - - - - - 887 - - - YES - - - - - - - - - 864 - - - YES - - - - - - 865 - - - YES - - - - - - - - - - - 866 - - - - - 869 - - - - - 870 - - - - - 871 - - - - - 872 - - - - - 873 - - - - - 859 - - - - - 849 - - - - - 889 - - - - - 890 - - - - - 891 - - - - - 892 - - - - - 899 - - - YES - - - - - - 900 - - - YES - - - - - - 901 - - - YES - - - - - - - - - 902 - - - YES - - - - - - 903 - - - YES - - - - - - 904 - - - YES - - - - - - - 905 - - - YES - - - - - - - - 906 - - - YES - - - - - - - - 907 - - - YES - - - - - - 908 - - - - - 909 - - - YES - - - - - - 910 - - - - - 911 - - - YES - - - - - - 912 - - - YES - - - - - - 913 - - - YES - - - - - - 914 - - - YES - - - - - - - - - - - - - - 917 - - - - - 916 - - - - - 915 - - - - - 918 - - - - - 919 - - - - - 920 - - - - - 921 - - - - - 922 - - - - - 923 - - - - - 924 - - - YES - - - - - - 925 - - - - - 926 - - - YES - - - - - - 927 - - - YES - - - - - - 928 - - - YES - - - - - - 929 - - - YES - - - - - - - - - 930 - - - - - 931 - - - - - 933 - - - YES - - - - - - 934 - - - YES - - - - - - 935 - - - YES - - - - - - 936 - - - YES - - - - - - - 937 - - - - - 938 - - - - - 940 - - - - - 941 - - - YES - - - - - - - 942 - - - YES - - - - - - 945 - - - - - 943 - - - YES - - - - - - 944 - - - - - 946 - - - YES - - - - - - 947 - - - YES - - - - - - - 948 - - - YES - - - - - - - 949 - - - YES - - - - - - 952 - - - - - 950 - - - YES - - - - - - 951 - - - - - 953 - - - YES - - - - - - 954 - - - YES - - - - - - 965 - - - YES - - - - - - - 966 - - - YES - - - - - - 967 - - - YES - - - - - - 968 - - - YES - - - - - - - - - - - - - - - - - - - 969 - - - YES - - - - - - - - - - - - - - - - - - - 972 - - - YES - - - - - - 973 - - - - - 974 - - - YES - - - - - - 975 - - - - - 976 - - - YES - - - - - - 977 - - - - - 978 - - - YES - - - - - - 979 - - - - - 980 - - - YES - - - - - - 981 - - - - - 982 - - - YES - - - - - - 983 - - - - - 984 - - - YES - - - - - - 985 - - - - - 986 - - - YES - - - - - - 987 - - - - - 988 - - - YES - - - - - - 989 - - - - - 990 - - - YES - - - - - - 991 - - - - - 992 - - - YES - - - - - - 993 - - - - - 994 - - - YES - - - - - - 995 - - - - - 996 - - - YES - - - - - - 997 - - - - - 998 - - - YES - - - - - - 999 - - - - - 1000 - - - YES - - - - - - 1027 - - - - - 1028 - - - YES - - - - - - - - 1029 - - - YES - - - - - - 1030 - - - YES - - - - - - 1031 - - - YES - - - - - - - - - - - - - - - 1032 - - - - - 1033 - - - - - 1034 - - - - - 1035 - - - - - 1036 - - - - - 1037 - - - - - 1038 - - - - - 1039 - - - - - 1040 - - - - - 1041 - - - - - 1044 - - - YES - - - - - - 1045 - - - YES - - - - - - 1046 - - - - - 1047 - - - - - 1050 - - - - - 1097 - - - - - 1109 - - - YES - - - - - - 1110 - - - YES - - - - - - - - - 1111 - - - YES - - - - - - 1112 - - - - - 1124 - - - YES - - - - - - 1125 - - - - - 1126 - - - YES - - - - - - 1127 - - - - - 1132 - - - YES - - - - - - 1133 - - - - - 1135 - - - - - 1200 - - - YES - - - - - - 1201 - - - YES - - - - - - 1202 - - - YES - - - - - - 1203 - - - YES - - - - - - 1204 - - - YES - - - - - - 1205 - - - YES - - - - - - 1206 - - - YES - - - - - - 1207 - - - YES - - - - - - 1208 - - - YES - - - - - - 1209 - - - YES - - - - - - 1210 - - - YES - - - - - - 1211 - - - YES - - - - - - 1212 - - - YES - - - - - - 1213 - - - - - 1214 - - - - - 1215 - - - - - 1216 - - - - - 1217 - - - - - 1218 - - - - - 1219 - - - - - 1220 - - - - - 1221 - - - - - 1222 - - - - - 1223 - - - - - 1224 - - - - - 1225 - - - - - 1253 - - - - - - - YES - - YES - -3.IBPluginDependency - 1000.IBPluginDependency - 1027.IBPluginDependency - 1028.IBPluginDependency - 1029.IBPluginDependency - 103.IBPluginDependency - 103.ImportedFromIB2 - 1030.IBPluginDependency - 1031.IBEditorWindowLastContentRect - 1031.IBPluginDependency - 1032.IBPluginDependency - 1033.IBPluginDependency - 1034.IBPluginDependency - 1035.IBPluginDependency - 1036.IBPluginDependency - 1037.IBPluginDependency - 1038.IBPluginDependency - 1039.IBPluginDependency - 1040.IBPluginDependency - 1041.IBPluginDependency - 1044.IBPluginDependency - 1045.IBPluginDependency - 1046.IBPluginDependency - 1047.IBPluginDependency - 106.IBEditorWindowLastContentRect - 106.IBPluginDependency - 106.ImportedFromIB2 - 106.editorWindowContentRectSynchronizationRect - 1097.IBPluginDependency - 1109.IBEditorWindowLastContentRect - 1109.IBPluginDependency - 1109.IBWindowTemplateEditedContentRect - 1109.NSWindowTemplate.visibleAtLaunch - 111.IBPluginDependency - 111.ImportedFromIB2 - 1110.IBPluginDependency - 1111.IBPluginDependency - 1111.IBViewBoundsToFrameTransform - 1112.IBPluginDependency - 1124.IBPluginDependency - 1124.IBViewBoundsToFrameTransform - 1125.IBPluginDependency - 1126.IBPluginDependency - 1126.IBViewBoundsToFrameTransform - 1127.IBPluginDependency - 1132.IBPluginDependency - 1132.IBViewBoundsToFrameTransform - 1133.IBPluginDependency - 1135.IBPluginDependency - 1200.IBPluginDependency - 1200.IBViewBoundsToFrameTransform - 1201.IBPluginDependency - 1201.IBViewBoundsToFrameTransform - 1202.IBPluginDependency - 1202.IBViewBoundsToFrameTransform - 1203.IBPluginDependency - 1203.IBViewBoundsToFrameTransform - 1204.IBPluginDependency - 1204.IBViewBoundsToFrameTransform - 1205.IBPluginDependency - 1205.IBViewBoundsToFrameTransform - 1206.IBPluginDependency - 1206.IBViewBoundsToFrameTransform - 1207.IBPluginDependency - 1207.IBViewBoundsToFrameTransform - 1208.IBPluginDependency - 1208.IBViewBoundsToFrameTransform - 1209.IBPluginDependency - 1209.IBViewBoundsToFrameTransform - 1210.IBPluginDependency - 1210.IBViewBoundsToFrameTransform - 1211.IBPluginDependency - 1211.IBViewBoundsToFrameTransform - 1212.IBPluginDependency - 1212.IBViewBoundsToFrameTransform - 1213.IBPluginDependency - 1214.IBPluginDependency - 1215.IBPluginDependency - 1216.IBPluginDependency - 1217.IBPluginDependency - 1218.IBPluginDependency - 1219.IBPluginDependency - 1220.IBPluginDependency - 1221.IBPluginDependency - 1222.IBPluginDependency - 1223.IBPluginDependency - 1224.IBPluginDependency - 1225.IBPluginDependency - 1253.IBPluginDependency - 129.IBPluginDependency - 129.ImportedFromIB2 - 130.IBPluginDependency - 130.ImportedFromIB2 - 130.editorWindowContentRectSynchronizationRect - 131.IBPluginDependency - 131.ImportedFromIB2 - 134.IBPluginDependency - 134.ImportedFromIB2 - 136.IBPluginDependency - 136.ImportedFromIB2 - 143.IBPluginDependency - 143.ImportedFromIB2 - 144.IBPluginDependency - 144.ImportedFromIB2 - 145.IBPluginDependency - 145.ImportedFromIB2 - 149.IBPluginDependency - 149.ImportedFromIB2 - 150.IBPluginDependency - 150.ImportedFromIB2 - 19.IBPluginDependency - 19.ImportedFromIB2 - 23.IBPluginDependency - 23.ImportedFromIB2 - 236.IBPluginDependency - 236.ImportedFromIB2 - 239.IBPluginDependency - 239.ImportedFromIB2 - 24.IBEditorWindowLastContentRect - 24.IBPluginDependency - 24.ImportedFromIB2 - 24.editorWindowContentRectSynchronizationRect - 29.IBEditorWindowLastContentRect - 29.IBPluginDependency - 29.ImportedFromIB2 - 29.WindowOrigin - 29.editorWindowContentRectSynchronizationRect - 5.IBPluginDependency - 5.ImportedFromIB2 - 56.IBPluginDependency - 56.ImportedFromIB2 - 57.IBEditorWindowLastContentRect - 57.IBPluginDependency - 57.ImportedFromIB2 - 57.editorWindowContentRectSynchronizationRect - 58.IBPluginDependency - 58.ImportedFromIB2 - 72.IBPluginDependency - 72.ImportedFromIB2 - 81.IBEditorWindowLastContentRect - 81.IBPluginDependency - 81.ImportedFromIB2 - 81.editorWindowContentRectSynchronizationRect - 83.IBPluginDependency - 83.ImportedFromIB2 - 843.IBEditorWindowLastContentRect - 843.IBPluginDependency - 843.IBWindowTemplateEditedContentRect - 843.NSWindowTemplate.visibleAtLaunch - 843.windowTemplate.hasMinSize - 843.windowTemplate.minSize - 844.IBPluginDependency - 846.IBPluginDependency - 847.IBPluginDependency - 848.IBEditorWindowLastContentRect - 848.IBPluginDependency - 849.IBPluginDependency - 856.IBPluginDependency - 859.IBPluginDependency - 864.IBPluginDependency - 865.IBEditorWindowLastContentRect - 865.IBPluginDependency - 866.IBPluginDependency - 869.IBPluginDependency - 870.IBPluginDependency - 871.IBPluginDependency - 872.IBPluginDependency - 873.IBPluginDependency - 882.IBPluginDependency - 886.IBPluginDependency - 887.IBEditorWindowLastContentRect - 887.IBPluginDependency - 889.IBPluginDependency - 890.IBPluginDependency - 891.IBPluginDependency - 892.IBPluginDependency - 899.IBEditorWindowLastContentRect - 899.IBPluginDependency - 899.IBWindowTemplateEditedContentRect - 899.NSWindowTemplate.visibleAtLaunch - 900.IBPluginDependency - 901.IBAttributePlaceholdersKey - 901.IBPluginDependency - 902.IBPluginDependency - 903.IBPluginDependency - 904.IBPluginDependency - 905.IBPluginDependency - 906.IBPluginDependency - 907.IBPluginDependency - 908.IBPluginDependency - 909.IBPluginDependency - 910.IBPluginDependency - 911.IBPluginDependency - 912.IBPluginDependency - 913.IBPluginDependency - 914.IBEditorWindowLastContentRect - 914.IBPluginDependency - 915.IBPluginDependency - 916.IBPluginDependency - 917.IBPluginDependency - 918.IBPluginDependency - 919.IBPluginDependency - 92.IBPluginDependency - 92.ImportedFromIB2 - 920.IBPluginDependency - 921.IBPluginDependency - 922.IBPluginDependency - 923.IBPluginDependency - 924.IBPluginDependency - 925.IBPluginDependency - 926.IBPluginDependency - 927.IBPluginDependency - 928.IBPluginDependency - 929.IBEditorWindowLastContentRect - 929.IBPluginDependency - 930.IBPluginDependency - 931.IBPluginDependency - 933.IBPluginDependency - 934.IBPluginDependency - 935.IBPluginDependency - 936.IBEditorWindowLastContentRect - 936.IBPluginDependency - 937.IBPluginDependency - 938.IBPluginDependency - 940.IBPluginDependency - 941.IBPluginDependency - 942.IBPluginDependency - 943.IBPluginDependency - 944.IBPluginDependency - 945.IBPluginDependency - 946.IBPluginDependency - 947.IBPluginDependency - 948.IBPluginDependency - 949.IBPluginDependency - 950.IBPluginDependency - 951.IBPluginDependency - 952.IBPluginDependency - 953.IBPluginDependency - 954.IBPluginDependency - 965.IBAttributePlaceholdersKey - 965.IBPluginDependency - 965.IBViewBoundsToFrameTransform - 966.IBPluginDependency - 967.IBPluginDependency - 968.IBPluginDependency - 969.IBPluginDependency - 972.IBPluginDependency - 972.IBViewBoundsToFrameTransform - 973.IBPluginDependency - 974.IBPluginDependency - 974.IBViewBoundsToFrameTransform - 975.IBPluginDependency - 976.IBPluginDependency - 976.IBViewBoundsToFrameTransform - 977.IBPluginDependency - 978.IBPluginDependency - 978.IBViewBoundsToFrameTransform - 979.IBPluginDependency - 980.IBPluginDependency - 980.IBViewBoundsToFrameTransform - 981.IBPluginDependency - 982.IBPluginDependency - 982.IBViewBoundsToFrameTransform - 983.IBPluginDependency - 984.IBPluginDependency - 984.IBViewBoundsToFrameTransform - 985.IBPluginDependency - 986.IBPluginDependency - 986.IBViewBoundsToFrameTransform - 987.IBPluginDependency - 988.IBPluginDependency - 988.IBViewBoundsToFrameTransform - 989.IBPluginDependency - 990.IBPluginDependency - 990.IBViewBoundsToFrameTransform - 991.IBPluginDependency - 992.IBPluginDependency - 992.IBViewBoundsToFrameTransform - 993.IBPluginDependency - 994.IBPluginDependency - 994.IBViewBoundsToFrameTransform - 995.IBPluginDependency - 996.IBPluginDependency - 996.IBViewBoundsToFrameTransform - 997.IBPluginDependency - 998.IBPluginDependency - 998.IBViewBoundsToFrameTransform - 999.IBPluginDependency - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - {{572, 78}, {262, 203}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{768, 368}, {163, 23}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{596, 852}, {216, 23}} - com.apple.InterfaceBuilder.CocoaPlugin - {{477, 639}, {220, 115}} - com.apple.InterfaceBuilder.CocoaPlugin - {{477, 639}, {220, 115}} - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAwswAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDAwAAwigAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABB0AAAwigAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCkAAAwogAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDkoAAw0EAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDhAAAwzQAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDbgAAwyEAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDi4AAwxIAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDnYAAwyEAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDeQAAw2IAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCzgAAwzIAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABC0AAAwwUAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABC/AAAwxsAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCpAAAwxsAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCpAAAw2IAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDNQAAwv4AAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDeQAAwv4AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{436, 809}, {64, 6}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{697, 318}, {194, 73}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{525, 802}, {197, 73}} - {{428, 391}, {401, 20}} - com.apple.InterfaceBuilder.CocoaPlugin - - {74, 862} - {{11, 977}, {478, 20}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{439, 208}, {192, 183}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{23, 794}, {245, 183}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{519, 328}, {181, 63}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{323, 672}, {199, 203}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{257, 623}, {320, 224}} - com.apple.InterfaceBuilder.CocoaPlugin - {{257, 623}, {320, 224}} - - - {320, 224} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{561, 318}, {193, 73}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{828, 218}, {90, 123}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{647, 318}, {182, 73}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{329, 203}, {484, 400}} - com.apple.InterfaceBuilder.CocoaPlugin - {{329, 203}, {484, 400}} - - com.apple.InterfaceBuilder.CocoaPlugin - - InitialTabViewItem - - InitialTabViewItem - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{756, 355}, {262, 183}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{398, 411}, {324, 83}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{608, 620}, {262, 43}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - InitialTabViewItem - - InitialTabViewItem - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBIAAAw6SAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - AUFgAABBYAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCzAAAwzIAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCzgAAwwUAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABC+gAAwxsAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCogAAwxsAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCogAAw2IAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDeAAAw2IAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDNAAAwv4AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDeAAAwv4AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDiwAAwxIAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDnQAAwyEAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDbQAAwyEAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDg4AAwzQAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDkgAAw0EAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - - - YES - - - YES - - - - - YES - - - YES - - - - 1254 - - - - YES - - YabauseButtonFormatter - NSFormatter - - IBProjectSource - YabauseButtonFormatter.h - - - - YabauseController - NSObject - - YES - - YES - pause: - reset: - runBIOS: - runCD: - runISO: - showPreferences: - toggle: - toggleFrameskip: - toggleFullscreen: - - - YES - id - id - id - id - id - id - id - id - id - - - - YES - - YES - pause: - reset: - runBIOS: - runCD: - runISO: - showPreferences: - toggle: - toggleFrameskip: - toggleFullscreen: - - - YES - - pause: - id - - - reset: - id - - - runBIOS: - id - - - runCD: - id - - - runISO: - id - - - showPreferences: - id - - - toggle: - id - - - toggleFrameskip: - id - - - toggleFullscreen: - id - - - - - YES - - YES - frameskip - logView - logWindow - prefs - prefsPane - view - - - YES - NSMenuItem - NSTextView - NSWindow - YabausePrefsController - NSPanel - YabauseGLView - - - - YES - - YES - frameskip - logView - logWindow - prefs - prefsPane - view - - - YES - - frameskip - NSMenuItem - - - logView - NSTextView - - - logWindow - NSWindow - - - prefs - YabausePrefsController - - - prefsPane - NSPanel - - - view - YabauseGLView - - - - - IBProjectSource - YabauseController.h - - - - YabauseGLView - NSOpenGLView - - window - NSWindow - - - window - - window - NSWindow - - - - IBProjectSource - YabauseGLView.h - - - - YabauseGLView - NSOpenGLView - - IBUserSource - - - - - YabausePrefsController - NSObject - - YES - - YES - biosBrowse: - biosToggle: - bramBrowse: - buttonSelect: - buttonSetCancel: - buttonSetOk: - cartBrowse: - cartSelected: - mpegBrowse: - regionSelected: - soundCoreSelected: - videoCoreSelected: - - - YES - id - id - id - id - id - id - id - id - id - id - id - id - - - - YES - - YES - biosBrowse: - biosToggle: - bramBrowse: - buttonSelect: - buttonSetCancel: - buttonSetOk: - cartBrowse: - cartSelected: - mpegBrowse: - regionSelected: - soundCoreSelected: - videoCoreSelected: - - - YES - - biosBrowse: - id - - - biosToggle: - id - - - bramBrowse: - id - - - buttonSelect: - id - - - buttonSetCancel: - id - - - buttonSetOk: - id - - - cartBrowse: - id - - - cartSelected: - id - - - mpegBrowse: - id - - - regionSelected: - id - - - soundCoreSelected: - id - - - videoCoreSelected: - id - - - - - YES - - YES - biosPath - bramPath - buttonAssignment - buttonBox - cartBrowse - cartPath - cartType - emulateBios - mpegPath - prefsPane - region - soundCore - videoCore - - - YES - NSTextField - NSTextField - NSPanel - NSTextField - NSButton - NSTextField - NSPopUpButton - NSButton - NSTextField - NSPanel - NSPopUpButton - NSPopUpButton - NSPopUpButton - - - - YES - - YES - biosPath - bramPath - buttonAssignment - buttonBox - cartBrowse - cartPath - cartType - emulateBios - mpegPath - prefsPane - region - soundCore - videoCore - - - YES - - biosPath - NSTextField - - - bramPath - NSTextField - - - buttonAssignment - NSPanel - - - buttonBox - NSTextField - - - cartBrowse - NSButton - - - cartPath - NSTextField - - - cartType - NSPopUpButton - - - emulateBios - NSButton - - - mpegPath - NSTextField - - - prefsPane - NSPanel - - - region - NSPopUpButton - - - soundCore - NSPopUpButton - - - videoCore - NSPopUpButton - - - - - IBProjectSource - YabausePrefsController.h - - - - YabausePrefsController - NSObject - - IBUserSource - - - - - - YES - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSWindowRestoration.h - - - - NSBox - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSBox.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSLayoutConstraint.h - - - - NSFontManager - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSImageCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSImageCell.h - - - - NSImageView - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSImageView.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSMenuItem - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSMenuItemCell - NSButtonCell - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItemCell.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSOpenGLView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSOpenGLView.h - - - - NSPanel - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSPanel.h - - - - NSPopUpButton - NSButton - - IBFrameworkSource - AppKit.framework/Headers/NSPopUpButton.h - - - - NSPopUpButtonCell - NSMenuItemCell - - IBFrameworkSource - AppKit.framework/Headers/NSPopUpButtonCell.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSResponder - - - - NSTabView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSTabView.h - - - - NSTabViewItem - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTabViewItem.h - - - - NSText - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSText.h - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSTextView - NSText - - IBFrameworkSource - AppKit.framework/Headers/NSTextView.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - - - NSView - - - - NSView - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - ../Yabause.xcodeproj - 3 - - YES - - YES - NSMenuCheckmark - NSMenuMixedState - NSSwitch - controller - - - YES - {11, 11} - {10, 3} - {15, 15} - {621, 376} - - - - diff --git a/yabause/src/cocoa/PerCocoa.h b/yabause/src/cocoa/PerCocoa.h deleted file mode 100644 index 568f4442b2..0000000000 --- a/yabause/src/cocoa/PerCocoa.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright 2010, 2011 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PerCocoa_h -#define PerCocoa_h - -#include "peripheral.h" - -#define PERCORE_COCOA 42 -extern PerInterface_struct PERCocoa; - -/* Update a key mapping */ -void PERCocoaSetKey(u32 key, u8 name, int port); -u32 PERCocoaGetKey(u8 n, int p); - -#endif /* !PerCocoa_h */ diff --git a/yabause/src/cocoa/PerCocoa.m b/yabause/src/cocoa/PerCocoa.m deleted file mode 100644 index dd6890a569..0000000000 --- a/yabause/src/cocoa/PerCocoa.m +++ /dev/null @@ -1,168 +0,0 @@ -/* Copyright 2010, 2011 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "PerCocoa.h" -#include "yabause.h" - -#include -#include -#include - -/* Forward Declarations. */ -static int PERCocoaInit(void); -static void PERCocoaDeInit(void); -static int PERCocoaHandleEvents(void); -static void PERCocoaNothing(void); - -static u32 PERCocoaScan(void); -static void PERCocoaFlush(void); - -static PerPad_struct *c1 = NULL, *c2 = NULL; - -PerInterface_struct PERCocoa = { - PERCORE_COCOA, - "Cocoa Keyboard Input Interface", - &PERCocoaInit, - &PERCocoaDeInit, - &PERCocoaHandleEvents, - &PERCocoaNothing, - &PERCocoaScan, - 0, - &PERCocoaFlush -}; - -/* Utility function to check if everything's set up right for a port */ -static BOOL AllSetForPort(int p) { - int i; - NSString *str; - NSUserDefaults *d = [NSUserDefaults standardUserDefaults]; - id val; - Class c = [NSNumber class]; - - for(i = 0; i < 13; ++i) { - str = [NSString stringWithFormat:@"Keyboard %d %s", p, PerPadNames[i]]; - val = [d objectForKey:str]; - - if(!val || ![val isKindOfClass:c]) { - return NO; - } - } - - return YES; -} - -void PERCocoaSetKey(u32 key, u8 n, int p) { - PerPad_struct *c; - NSString *str; - NSUserDefaults *d = [NSUserDefaults standardUserDefaults]; - NSNumber *val = [NSNumber numberWithUnsignedInt:(unsigned int)key]; - - assert(n <= PERPAD_Z); - - /* Build the string we'll look for, and set the value for that key */ - str = [NSString stringWithFormat:@"Pad %d %s", p, PerPadNames[n]]; - [d setObject:val forKey:str]; - [d synchronize]; - - /* Update the mapping if we're running */ - if(p == 0) { - c = c1; - } - else { - c = c2; - } - - /* This will effectively make sure we don't update until we've started. */ - if(c) { - PerSetKey(key, n, c); - } -} - -u32 PERCocoaGetKey(u8 n, int p) { - NSString *str; - id result; - NSUserDefaults *d = [NSUserDefaults standardUserDefaults]; - - assert(n <= PERPAD_Z); - - /* Fetch the key data */ - str = [NSString stringWithFormat:@"Pad %d %s", p, PerPadNames[n]]; - result = [d objectForKey:str]; - - if(result && [result isKindOfClass:[NSNumber class]]) { - return (u32)[result unsignedIntValue]; - } - else { - return (u32)-1; - } -} -static int PERCocoaInit(void) { - /* Fill in pad 1 */ - c1 = PerPadAdd(&PORTDATA1); - - PerSetKey(PERCocoaGetKey(PERPAD_UP, 0), PERPAD_UP, c1); - PerSetKey(PERCocoaGetKey(PERPAD_DOWN, 0), PERPAD_DOWN, c1); - PerSetKey(PERCocoaGetKey(PERPAD_LEFT, 0), PERPAD_LEFT, c1); - PerSetKey(PERCocoaGetKey(PERPAD_RIGHT, 0), PERPAD_RIGHT, c1); - PerSetKey(PERCocoaGetKey(PERPAD_LEFT_TRIGGER, 0), PERPAD_LEFT_TRIGGER, c1); - PerSetKey(PERCocoaGetKey(PERPAD_RIGHT_TRIGGER, 0), PERPAD_RIGHT_TRIGGER, c1); - PerSetKey(PERCocoaGetKey(PERPAD_START, 0), PERPAD_START, c1); - PerSetKey(PERCocoaGetKey(PERPAD_A, 0), PERPAD_A, c1); - PerSetKey(PERCocoaGetKey(PERPAD_B, 0), PERPAD_B, c1); - PerSetKey(PERCocoaGetKey(PERPAD_C, 0), PERPAD_C, c1); - PerSetKey(PERCocoaGetKey(PERPAD_X, 0), PERPAD_X, c1); - PerSetKey(PERCocoaGetKey(PERPAD_Y, 0), PERPAD_Y, c1); - PerSetKey(PERCocoaGetKey(PERPAD_Z, 0), PERPAD_Z, c1); - - /* Fill in pad 2 */ - c2 = PerPadAdd(&PORTDATA2); - - PerSetKey(PERCocoaGetKey(PERPAD_UP, 1), PERPAD_UP, c2); - PerSetKey(PERCocoaGetKey(PERPAD_DOWN, 1), PERPAD_DOWN, c2); - PerSetKey(PERCocoaGetKey(PERPAD_LEFT, 1), PERPAD_LEFT, c2); - PerSetKey(PERCocoaGetKey(PERPAD_RIGHT, 1), PERPAD_RIGHT, c2); - PerSetKey(PERCocoaGetKey(PERPAD_LEFT_TRIGGER, 1), PERPAD_LEFT_TRIGGER, c2); - PerSetKey(PERCocoaGetKey(PERPAD_RIGHT_TRIGGER, 1), PERPAD_RIGHT_TRIGGER, c2); - PerSetKey(PERCocoaGetKey(PERPAD_START, 1), PERPAD_START, c2); - PerSetKey(PERCocoaGetKey(PERPAD_A, 1), PERPAD_A, c2); - PerSetKey(PERCocoaGetKey(PERPAD_B, 1), PERPAD_B, c2); - PerSetKey(PERCocoaGetKey(PERPAD_C, 1), PERPAD_C, c2); - PerSetKey(PERCocoaGetKey(PERPAD_X, 1), PERPAD_X, c2); - PerSetKey(PERCocoaGetKey(PERPAD_Y, 1), PERPAD_Y, c2); - PerSetKey(PERCocoaGetKey(PERPAD_Z, 1), PERPAD_Z, c2); - - return 0; -} - -static void PERCocoaDeInit(void) { -} - -static int PERCocoaHandleEvents(void) { - return YabauseExec(); -} - -static void PERCocoaNothing(void) { -} - -static u32 PERCocoaScan(void) { - return 0; -} - -static void PERCocoaFlush(void) { -} diff --git a/yabause/src/cocoa/Yabause-Info.plist b/yabause/src/cocoa/Yabause-Info.plist deleted file mode 100644 index d4f860c666..0000000000 --- a/yabause/src/cocoa/Yabause-Info.plist +++ /dev/null @@ -1,34 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIconFile - Yabause.icns - CFBundleIdentifier - org.yabause.yabause.cocoa - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - APPL - CFBundleSignature - ???? - CFBundleShortVersionString - 0.9.12 - LSMinimumSystemVersion - ${MACOSX_DEPLOYMENT_TARGET} - CFBundleVersion - - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - NSHumanReadableCopyright - Copyright © Yabause Team - - diff --git a/yabause/src/cocoa/Yabause.icns b/yabause/src/cocoa/Yabause.icns deleted file mode 100644 index ee74849a60..0000000000 Binary files a/yabause/src/cocoa/Yabause.icns and /dev/null differ diff --git a/yabause/src/cocoa/Yabause.xcodeproj/project.pbxproj b/yabause/src/cocoa/Yabause.xcodeproj/project.pbxproj deleted file mode 100644 index b9bdb37090..0000000000 --- a/yabause/src/cocoa/Yabause.xcodeproj/project.pbxproj +++ /dev/null @@ -1,808 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 42; - objects = { - -/* Begin PBXBuildFile section */ - 2A1145191385E5010087C872 /* YabauseButtonFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1145181385E5010087C872 /* YabauseButtonFormatter.m */; }; - 2A3392711162E100000DA0E9 /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A3392701162E100000DA0E9 /* GLUT.framework */; }; - 2A474DF01163A013006993EA /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A474DEF1163A013006993EA /* AudioUnit.framework */; }; - 2A474DF21163A013006993EA /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A474DF11163A013006993EA /* CoreAudio.framework */; }; - 2A7AB7CC117D1C1B00E47298 /* vidsoft.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7AB7CB117D1C1B00E47298 /* vidsoft.c */; }; - 2A7D39D3115BA16100DE3BD1 /* bios.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3987115BA16100DE3BD1 /* bios.c */; }; - 2A7D39D4115BA16100DE3BD1 /* cd-macosx.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3989115BA16100DE3BD1 /* cd-macosx.c */; }; - 2A7D39D5115BA16100DE3BD1 /* cdbase.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D398A115BA16100DE3BD1 /* cdbase.c */; }; - 2A7D39D6115BA16100DE3BD1 /* cheat.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D398C115BA16100DE3BD1 /* cheat.c */; }; - 2A7D39D7115BA16100DE3BD1 /* coffelf.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D398E115BA16100DE3BD1 /* coffelf.c */; }; - 2A7D39D8115BA16100DE3BD1 /* cs0.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3991115BA16100DE3BD1 /* cs0.c */; }; - 2A7D39D9115BA16100DE3BD1 /* cs1.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3993115BA16100DE3BD1 /* cs1.c */; }; - 2A7D39DA115BA16100DE3BD1 /* cs2.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3995115BA16100DE3BD1 /* cs2.c */; }; - 2A7D39DB115BA16100DE3BD1 /* debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3997115BA16100DE3BD1 /* debug.c */; }; - 2A7D39DC115BA16100DE3BD1 /* error.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3999115BA16100DE3BD1 /* error.c */; }; - 2A7D39DD115BA16100DE3BD1 /* m68kc68k.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D399B115BA16100DE3BD1 /* m68kc68k.c */; }; - 2A7D39DE115BA16100DE3BD1 /* m68kcore.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D399D115BA16100DE3BD1 /* m68kcore.c */; }; - 2A7D39DF115BA16100DE3BD1 /* m68kd.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D399F115BA16100DE3BD1 /* m68kd.c */; }; - 2A7D39E1115BA16100DE3BD1 /* macjoy.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39A2115BA16100DE3BD1 /* macjoy.c */; }; - 2A7D39E2115BA16100DE3BD1 /* memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39A4115BA16100DE3BD1 /* memory.c */; }; - 2A7D39E3115BA16100DE3BD1 /* movie.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39A6115BA16100DE3BD1 /* movie.c */; }; - 2A7D39E4115BA16100DE3BD1 /* netlink.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39A8115BA16100DE3BD1 /* netlink.c */; }; - 2A7D39E5115BA16100DE3BD1 /* peripheral.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39AA115BA16100DE3BD1 /* peripheral.c */; }; - 2A7D39E6115BA16100DE3BD1 /* permacjoy.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39AC115BA16100DE3BD1 /* permacjoy.c */; }; - 2A7D39E7115BA16100DE3BD1 /* profile.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39AE115BA16100DE3BD1 /* profile.c */; }; - 2A7D39E9115BA16100DE3BD1 /* scu.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39B2115BA16100DE3BD1 /* scu.c */; }; - 2A7D39EA115BA16100DE3BD1 /* sh2core.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39B4115BA16100DE3BD1 /* sh2core.c */; }; - 2A7D39EB115BA16100DE3BD1 /* sh2d.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39B6115BA16100DE3BD1 /* sh2d.c */; }; - 2A7D39EC115BA16100DE3BD1 /* sh2idle.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39B8115BA16100DE3BD1 /* sh2idle.c */; }; - 2A7D39ED115BA16100DE3BD1 /* sh2int.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39BA115BA16100DE3BD1 /* sh2int.c */; }; - 2A7D39EE115BA16100DE3BD1 /* sh2trace.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39BC115BA16100DE3BD1 /* sh2trace.c */; }; - 2A7D39EF115BA16100DE3BD1 /* smpc.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39BE115BA16100DE3BD1 /* smpc.c */; }; - 2A7D39F1115BA16100DE3BD1 /* vdp1.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39C2115BA16100DE3BD1 /* vdp1.c */; }; - 2A7D39F2115BA16100DE3BD1 /* vdp2.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39C4115BA16100DE3BD1 /* vdp2.c */; }; - 2A7D39F3115BA16100DE3BD1 /* vdp2debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39C6115BA16100DE3BD1 /* vdp2debug.c */; }; - 2A7D39F4115BA16100DE3BD1 /* vidogl.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39C8115BA16100DE3BD1 /* vidogl.c */; }; - 2A7D39F5115BA16100DE3BD1 /* vidshared.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39CA115BA16100DE3BD1 /* vidshared.c */; }; - 2A7D39F6115BA16100DE3BD1 /* vidgcd.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39CC115BA16100DE3BD1 /* vidgcd.c */; }; - 2A7D39F7115BA16100DE3BD1 /* yabause.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39CE115BA16100DE3BD1 /* yabause.c */; }; - 2A7D39F8115BA16100DE3BD1 /* ygl.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D39D0115BA16100DE3BD1 /* ygl.c */; }; - 2A7D3A1E115BA29F00DE3BD1 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A7D3A1D115BA29F00DE3BD1 /* OpenGL.framework */; }; - 2A7D3A31115BA35200DE3BD1 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A7D3A30115BA35200DE3BD1 /* CoreFoundation.framework */; }; - 2A7D3A33115BA35200DE3BD1 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A7D3A32115BA35200DE3BD1 /* IOKit.framework */; }; - 2A7D3A48115BA3AF00DE3BD1 /* c68k.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3A41115BA3AF00DE3BD1 /* c68k.c */; }; - 2A7D3A49115BA3AF00DE3BD1 /* c68kexec.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3A43115BA3AF00DE3BD1 /* c68kexec.c */; settings = {COMPILER_FLAGS = "-O0"; }; }; - 2A7D3A4B115BA3AF00DE3BD1 /* gen68k.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3A45115BA3AF00DE3BD1 /* gen68k.c */; }; - 2A7D3A5A115BA41200DE3BD1 /* gen68k.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A7D3A45115BA3AF00DE3BD1 /* gen68k.c */; }; - 2A7D3A9B115BAB9E00DE3BD1 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2A7D3A99115BAB9E00DE3BD1 /* MainMenu.xib */; }; - 2A7D3AD5115BB01500DE3BD1 /* Yabause.icns in Resources */ = {isa = PBXBuildFile; fileRef = 2A7D3AD4115BB01500DE3BD1 /* Yabause.icns */; }; - 2A82CCA1116171DB00F15B02 /* PerCocoa.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A82CCA0116171DB00F15B02 /* PerCocoa.m */; }; - 2A9D7600116645D700A580EB /* sndmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A9D75FE116645D700A580EB /* sndmac.c */; }; - 2A9D760E11665F2800A580EB /* controller.png in Resources */ = {isa = PBXBuildFile; fileRef = 2A9D760D11665F2800A580EB /* controller.png */; }; - 2A9D7621116667C300A580EB /* YabausePrefsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A9D761F116667C300A580EB /* YabausePrefsController.m */; }; - 2AD10F9E118BBC850088FB2C /* scsp2.c in Sources */ = {isa = PBXBuildFile; fileRef = 2AD10F97118BBC850088FB2C /* scsp2.c */; }; - 2AD10F9F118BBC850088FB2C /* snddummy.c in Sources */ = {isa = PBXBuildFile; fileRef = 2AD10F99118BBC850088FB2C /* snddummy.c */; }; - 2AD10FA0118BBC850088FB2C /* sndwav.c in Sources */ = {isa = PBXBuildFile; fileRef = 2AD10F9A118BBC850088FB2C /* sndwav.c */; }; - 2AD10FDB118BCFA00088FB2C /* thr-dummy.c in Sources */ = {isa = PBXBuildFile; fileRef = 2AD10F9B118BBC850088FB2C /* thr-dummy.c */; }; - 2AF0CA51116146A400196BED /* YabauseGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AF0CA4F116146A400196BED /* YabauseGLView.m */; }; - 2AF0CA9911614DD500196BED /* YabauseController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AF0CA9811614DD500196BED /* YabauseController.m */; }; - 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; - 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; - 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; - F07BF9E414A1C2C500775818 /* yglshader.c in Sources */ = {isa = PBXBuildFile; fileRef = F07BF9E314A1C2C500775818 /* yglshader.c */; }; - F07E62CB15054DCC00DF8A4E /* titan.c in Sources */ = {isa = PBXBuildFile; fileRef = F07E62CA15054DCC00DF8A4E /* titan.c */; }; - F0E47FAD156C34EC001A1B51 /* osdcore.c in Sources */ = {isa = PBXBuildFile; fileRef = F0E47FAC156C34EC001A1B51 /* osdcore.c */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 2A7D3A7A115BA63900DE3BD1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 2A7D3A54115BA3E700DE3BD1; - remoteInfo = gen68k; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; - 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; - 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; - 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; - 2A1145171385E5010087C872 /* YabauseButtonFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YabauseButtonFormatter.h; sourceTree = ""; }; - 2A1145181385E5010087C872 /* YabauseButtonFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YabauseButtonFormatter.m; sourceTree = ""; }; - 2A3392701162E100000DA0E9 /* GLUT.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLUT.framework; path = System/Library/Frameworks/GLUT.framework; sourceTree = SDKROOT; }; - 2A474DEF1163A013006993EA /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; - 2A474DF11163A013006993EA /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; - 2A7AB7CB117D1C1B00E47298 /* vidsoft.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vidsoft.c; path = ../vidsoft.c; sourceTree = SOURCE_ROOT; }; - 2A7AB7CE117D1CBE00E47298 /* vidsoft.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vidsoft.h; path = ../vidsoft.h; sourceTree = SOURCE_ROOT; }; - 2A7D3987115BA16100DE3BD1 /* bios.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bios.c; path = ../bios.c; sourceTree = SOURCE_ROOT; }; - 2A7D3988115BA16100DE3BD1 /* bios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bios.h; path = ../bios.h; sourceTree = SOURCE_ROOT; }; - 2A7D3989115BA16100DE3BD1 /* cd-macosx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "cd-macosx.c"; path = "../cd-macosx.c"; sourceTree = SOURCE_ROOT; }; - 2A7D398A115BA16100DE3BD1 /* cdbase.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cdbase.c; path = ../cdbase.c; sourceTree = SOURCE_ROOT; }; - 2A7D398B115BA16100DE3BD1 /* cdbase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cdbase.h; path = ../cdbase.h; sourceTree = SOURCE_ROOT; }; - 2A7D398C115BA16100DE3BD1 /* cheat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cheat.c; path = ../cheat.c; sourceTree = SOURCE_ROOT; }; - 2A7D398D115BA16100DE3BD1 /* cheat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cheat.h; path = ../cheat.h; sourceTree = SOURCE_ROOT; }; - 2A7D398E115BA16100DE3BD1 /* coffelf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = coffelf.c; path = ../coffelf.c; sourceTree = SOURCE_ROOT; }; - 2A7D398F115BA16100DE3BD1 /* coffelf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = coffelf.h; path = ../coffelf.h; sourceTree = SOURCE_ROOT; }; - 2A7D3990115BA16100DE3BD1 /* core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = core.h; path = ../core.h; sourceTree = SOURCE_ROOT; }; - 2A7D3991115BA16100DE3BD1 /* cs0.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cs0.c; path = ../cs0.c; sourceTree = SOURCE_ROOT; }; - 2A7D3992115BA16100DE3BD1 /* cs0.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cs0.h; path = ../cs0.h; sourceTree = SOURCE_ROOT; }; - 2A7D3993115BA16100DE3BD1 /* cs1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cs1.c; path = ../cs1.c; sourceTree = SOURCE_ROOT; }; - 2A7D3994115BA16100DE3BD1 /* cs1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cs1.h; path = ../cs1.h; sourceTree = SOURCE_ROOT; }; - 2A7D3995115BA16100DE3BD1 /* cs2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cs2.c; path = ../cs2.c; sourceTree = SOURCE_ROOT; }; - 2A7D3996115BA16100DE3BD1 /* cs2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cs2.h; path = ../cs2.h; sourceTree = SOURCE_ROOT; }; - 2A7D3997115BA16100DE3BD1 /* debug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = debug.c; path = ../debug.c; sourceTree = SOURCE_ROOT; }; - 2A7D3998115BA16100DE3BD1 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = debug.h; path = ../debug.h; sourceTree = SOURCE_ROOT; }; - 2A7D3999115BA16100DE3BD1 /* error.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = error.c; path = ../error.c; sourceTree = SOURCE_ROOT; }; - 2A7D399A115BA16100DE3BD1 /* error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = error.h; path = ../error.h; sourceTree = SOURCE_ROOT; }; - 2A7D399B115BA16100DE3BD1 /* m68kc68k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = m68kc68k.c; path = ../m68kc68k.c; sourceTree = SOURCE_ROOT; }; - 2A7D399C115BA16100DE3BD1 /* m68kc68k.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m68kc68k.h; path = ../m68kc68k.h; sourceTree = SOURCE_ROOT; }; - 2A7D399D115BA16100DE3BD1 /* m68kcore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = m68kcore.c; path = ../m68kcore.c; sourceTree = SOURCE_ROOT; }; - 2A7D399E115BA16100DE3BD1 /* m68kcore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m68kcore.h; path = ../m68kcore.h; sourceTree = SOURCE_ROOT; }; - 2A7D399F115BA16100DE3BD1 /* m68kd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = m68kd.c; path = ../m68kd.c; sourceTree = SOURCE_ROOT; }; - 2A7D39A0115BA16100DE3BD1 /* m68kd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m68kd.h; path = ../m68kd.h; sourceTree = SOURCE_ROOT; }; - 2A7D39A1115BA16100DE3BD1 /* m68kq68.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = m68kq68.c; path = ../m68kq68.c; sourceTree = SOURCE_ROOT; }; - 2A7D39A2115BA16100DE3BD1 /* macjoy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = macjoy.c; path = ../macjoy.c; sourceTree = SOURCE_ROOT; }; - 2A7D39A3115BA16100DE3BD1 /* macjoy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = macjoy.h; path = ../macjoy.h; sourceTree = SOURCE_ROOT; }; - 2A7D39A4115BA16100DE3BD1 /* memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = memory.c; path = ../memory.c; sourceTree = SOURCE_ROOT; }; - 2A7D39A5115BA16100DE3BD1 /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = memory.h; path = ../memory.h; sourceTree = SOURCE_ROOT; }; - 2A7D39A6115BA16100DE3BD1 /* movie.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = movie.c; path = ../movie.c; sourceTree = SOURCE_ROOT; }; - 2A7D39A7115BA16100DE3BD1 /* movie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = movie.h; path = ../movie.h; sourceTree = SOURCE_ROOT; }; - 2A7D39A8115BA16100DE3BD1 /* netlink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = netlink.c; path = ../netlink.c; sourceTree = SOURCE_ROOT; }; - 2A7D39A9115BA16100DE3BD1 /* netlink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = netlink.h; path = ../netlink.h; sourceTree = SOURCE_ROOT; }; - 2A7D39AA115BA16100DE3BD1 /* peripheral.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = peripheral.c; path = ../peripheral.c; sourceTree = SOURCE_ROOT; }; - 2A7D39AB115BA16100DE3BD1 /* peripheral.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = peripheral.h; path = ../peripheral.h; sourceTree = SOURCE_ROOT; }; - 2A7D39AC115BA16100DE3BD1 /* permacjoy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = permacjoy.c; path = ../permacjoy.c; sourceTree = SOURCE_ROOT; }; - 2A7D39AD115BA16100DE3BD1 /* permacjoy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = permacjoy.h; path = ../permacjoy.h; sourceTree = SOURCE_ROOT; }; - 2A7D39AE115BA16100DE3BD1 /* profile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = profile.c; path = ../profile.c; sourceTree = SOURCE_ROOT; }; - 2A7D39AF115BA16100DE3BD1 /* profile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = profile.h; path = ../profile.h; sourceTree = SOURCE_ROOT; }; - 2A7D39B0115BA16100DE3BD1 /* scsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = scsp.c; path = ../scsp.c; sourceTree = SOURCE_ROOT; }; - 2A7D39B1115BA16100DE3BD1 /* scsp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = scsp.h; path = ../scsp.h; sourceTree = SOURCE_ROOT; }; - 2A7D39B2115BA16100DE3BD1 /* scu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = scu.c; path = ../scu.c; sourceTree = SOURCE_ROOT; }; - 2A7D39B3115BA16100DE3BD1 /* scu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = scu.h; path = ../scu.h; sourceTree = SOURCE_ROOT; }; - 2A7D39B4115BA16100DE3BD1 /* sh2core.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sh2core.c; path = ../sh2core.c; sourceTree = SOURCE_ROOT; }; - 2A7D39B5115BA16100DE3BD1 /* sh2core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sh2core.h; path = ../sh2core.h; sourceTree = SOURCE_ROOT; }; - 2A7D39B6115BA16100DE3BD1 /* sh2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sh2d.c; path = ../sh2d.c; sourceTree = SOURCE_ROOT; }; - 2A7D39B7115BA16100DE3BD1 /* sh2d.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sh2d.h; path = ../sh2d.h; sourceTree = SOURCE_ROOT; }; - 2A7D39B8115BA16100DE3BD1 /* sh2idle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sh2idle.c; path = ../sh2idle.c; sourceTree = SOURCE_ROOT; }; - 2A7D39B9115BA16100DE3BD1 /* sh2idle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sh2idle.h; path = ../sh2idle.h; sourceTree = SOURCE_ROOT; }; - 2A7D39BA115BA16100DE3BD1 /* sh2int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sh2int.c; path = ../sh2int.c; sourceTree = SOURCE_ROOT; }; - 2A7D39BB115BA16100DE3BD1 /* sh2int.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sh2int.h; path = ../sh2int.h; sourceTree = SOURCE_ROOT; }; - 2A7D39BC115BA16100DE3BD1 /* sh2trace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sh2trace.c; path = ../sh2trace.c; sourceTree = SOURCE_ROOT; }; - 2A7D39BD115BA16100DE3BD1 /* sh2trace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sh2trace.h; path = ../sh2trace.h; sourceTree = SOURCE_ROOT; }; - 2A7D39BE115BA16100DE3BD1 /* smpc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = smpc.c; path = ../smpc.c; sourceTree = SOURCE_ROOT; }; - 2A7D39BF115BA16100DE3BD1 /* smpc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = smpc.h; path = ../smpc.h; sourceTree = SOURCE_ROOT; }; - 2A7D39C2115BA16100DE3BD1 /* vdp1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vdp1.c; path = ../vdp1.c; sourceTree = SOURCE_ROOT; }; - 2A7D39C3115BA16100DE3BD1 /* vdp1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vdp1.h; path = ../vdp1.h; sourceTree = SOURCE_ROOT; }; - 2A7D39C4115BA16100DE3BD1 /* vdp2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vdp2.c; path = ../vdp2.c; sourceTree = SOURCE_ROOT; }; - 2A7D39C5115BA16100DE3BD1 /* vdp2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vdp2.h; path = ../vdp2.h; sourceTree = SOURCE_ROOT; }; - 2A7D39C6115BA16100DE3BD1 /* vdp2debug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vdp2debug.c; path = ../vdp2debug.c; sourceTree = SOURCE_ROOT; }; - 2A7D39C7115BA16100DE3BD1 /* vdp2debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vdp2debug.h; path = ../vdp2debug.h; sourceTree = SOURCE_ROOT; }; - 2A7D39C8115BA16100DE3BD1 /* vidogl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vidogl.c; path = ../vidogl.c; sourceTree = SOURCE_ROOT; }; - 2A7D39C9115BA16100DE3BD1 /* vidogl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vidogl.h; path = ../vidogl.h; sourceTree = SOURCE_ROOT; }; - 2A7D39CA115BA16100DE3BD1 /* vidshared.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vidshared.c; path = ../vidshared.c; sourceTree = SOURCE_ROOT; }; - 2A7D39CB115BA16100DE3BD1 /* vidshared.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vidshared.h; path = ../vidshared.h; sourceTree = SOURCE_ROOT; }; - 2A7D39CC115BA16100DE3BD1 /* vidgcd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vidgcd.c; sourceTree = ""; }; - 2A7D39CD115BA16100DE3BD1 /* vidgcd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vidgcd.h; sourceTree = ""; }; - 2A7D39CE115BA16100DE3BD1 /* yabause.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = yabause.c; path = ../yabause.c; sourceTree = SOURCE_ROOT; }; - 2A7D39CF115BA16100DE3BD1 /* yabause.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = yabause.h; path = ../yabause.h; sourceTree = SOURCE_ROOT; }; - 2A7D39D0115BA16100DE3BD1 /* ygl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ygl.c; path = ../ygl.c; sourceTree = SOURCE_ROOT; }; - 2A7D39D1115BA16100DE3BD1 /* ygl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ygl.h; path = ../ygl.h; sourceTree = SOURCE_ROOT; }; - 2A7D39D2115BA16100DE3BD1 /* yui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = yui.h; path = ../yui.h; sourceTree = SOURCE_ROOT; }; - 2A7D3A1D115BA29F00DE3BD1 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; - 2A7D3A30115BA35200DE3BD1 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; - 2A7D3A32115BA35200DE3BD1 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; - 2A7D3A41115BA3AF00DE3BD1 /* c68k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = c68k.c; path = ../c68k/c68k.c; sourceTree = SOURCE_ROOT; }; - 2A7D3A42115BA3AF00DE3BD1 /* c68k.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = c68k.h; path = ../c68k/c68k.h; sourceTree = SOURCE_ROOT; }; - 2A7D3A43115BA3AF00DE3BD1 /* c68kexec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = c68kexec.c; path = ../c68k/c68kexec.c; sourceTree = SOURCE_ROOT; }; - 2A7D3A44115BA3AF00DE3BD1 /* c68kmac.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = c68kmac.inc; path = ../c68k/c68kmac.inc; sourceTree = SOURCE_ROOT; }; - 2A7D3A45115BA3AF00DE3BD1 /* gen68k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gen68k.c; path = ../c68k/gen68k.c; sourceTree = SOURCE_ROOT; }; - 2A7D3A46115BA3AF00DE3BD1 /* gen68k.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = gen68k.h; path = ../c68k/gen68k.h; sourceTree = SOURCE_ROOT; }; - 2A7D3A47115BA3AF00DE3BD1 /* gen68k.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = gen68k.inc; path = ../c68k/gen68k.inc; sourceTree = SOURCE_ROOT; }; - 2A7D3A55115BA3E700DE3BD1 /* gen68k */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gen68k; sourceTree = BUILT_PRODUCTS_DIR; }; - 2A7D3A9A115BAB9E00DE3BD1 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = ""; }; - 2A7D3AD4115BB01500DE3BD1 /* Yabause.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Yabause.icns; sourceTree = ""; }; - 2A82CC9F116171DB00F15B02 /* PerCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PerCocoa.h; sourceTree = ""; }; - 2A82CCA0116171DB00F15B02 /* PerCocoa.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PerCocoa.m; sourceTree = ""; }; - 2A9D75FE116645D700A580EB /* sndmac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sndmac.c; path = ../sndmac.c; sourceTree = SOURCE_ROOT; }; - 2A9D75FF116645D700A580EB /* sndmac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sndmac.h; path = ../sndmac.h; sourceTree = SOURCE_ROOT; }; - 2A9D760D11665F2800A580EB /* controller.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = controller.png; path = resources/controller.png; sourceTree = ""; }; - 2A9D761F116667C300A580EB /* YabausePrefsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YabausePrefsController.m; sourceTree = ""; }; - 2A9D7620116667C300A580EB /* YabausePrefsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YabausePrefsController.h; sourceTree = ""; }; - 2AD10F97118BBC850088FB2C /* scsp2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = scsp2.c; path = ../scsp2.c; sourceTree = SOURCE_ROOT; }; - 2AD10F98118BBC850088FB2C /* scsp2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = scsp2.h; path = ../scsp2.h; sourceTree = SOURCE_ROOT; }; - 2AD10F99118BBC850088FB2C /* snddummy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = snddummy.c; path = ../snddummy.c; sourceTree = SOURCE_ROOT; }; - 2AD10F9A118BBC850088FB2C /* sndwav.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sndwav.c; path = ../sndwav.c; sourceTree = SOURCE_ROOT; }; - 2AD10F9B118BBC850088FB2C /* thr-dummy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "thr-dummy.c"; path = "../thr-dummy.c"; sourceTree = SOURCE_ROOT; }; - 2AD10F9C118BBC850088FB2C /* thr-macosx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "thr-macosx.c"; path = "../thr-macosx.c"; sourceTree = SOURCE_ROOT; }; - 2AD10F9D118BBC850088FB2C /* threads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = threads.h; path = ../threads.h; sourceTree = SOURCE_ROOT; }; - 2AF0CA4F116146A400196BED /* YabauseGLView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YabauseGLView.m; sourceTree = ""; }; - 2AF0CA50116146A400196BED /* YabauseGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YabauseGLView.h; sourceTree = ""; }; - 2AF0CA9711614DD500196BED /* YabauseController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YabauseController.h; sourceTree = ""; }; - 2AF0CA9811614DD500196BED /* YabauseController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YabauseController.m; sourceTree = ""; }; - 8D1107310486CEB800E47090 /* Yabause-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Yabause-Info.plist"; sourceTree = ""; }; - 8D1107320486CEB800E47090 /* Yabause.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Yabause.app; sourceTree = BUILT_PRODUCTS_DIR; }; - F07BF9E314A1C2C500775818 /* yglshader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = yglshader.c; path = ../yglshader.c; sourceTree = SOURCE_ROOT; }; - F07E62CA15054DCC00DF8A4E /* titan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = titan.c; path = ../titan/titan.c; sourceTree = SOURCE_ROOT; }; - F07E62CC15054DF500DF8A4E /* titan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = titan.h; path = ../titan/titan.h; sourceTree = SOURCE_ROOT; }; - F0E47FAC156C34EC001A1B51 /* osdcore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = osdcore.c; path = ../osdcore.c; sourceTree = SOURCE_ROOT; }; - F0E47FAE156C34FB001A1B51 /* osdcore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = osdcore.h; path = ../osdcore.h; sourceTree = SOURCE_ROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 2A7D3A53115BA3E700DE3BD1 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8D11072E0486CEB800E47090 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, - 2A7D3A1E115BA29F00DE3BD1 /* OpenGL.framework in Frameworks */, - 2A7D3A31115BA35200DE3BD1 /* CoreFoundation.framework in Frameworks */, - 2A7D3A33115BA35200DE3BD1 /* IOKit.framework in Frameworks */, - 2A3392711162E100000DA0E9 /* GLUT.framework in Frameworks */, - 2A474DF01163A013006993EA /* AudioUnit.framework in Frameworks */, - 2A474DF21163A013006993EA /* CoreAudio.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 080E96DDFE201D6D7F000001 /* Classes */ = { - isa = PBXGroup; - children = ( - 2A1145171385E5010087C872 /* YabauseButtonFormatter.h */, - 2A1145181385E5010087C872 /* YabauseButtonFormatter.m */, - 2AF0CA9711614DD500196BED /* YabauseController.h */, - 2AF0CA9811614DD500196BED /* YabauseController.m */, - 2AF0CA50116146A400196BED /* YabauseGLView.h */, - 2AF0CA4F116146A400196BED /* YabauseGLView.m */, - 2A9D7620116667C300A580EB /* YabausePrefsController.h */, - 2A9D761F116667C300A580EB /* YabausePrefsController.m */, - ); - name = Classes; - sourceTree = ""; - }; - 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { - isa = PBXGroup; - children = ( - 2A3392701162E100000DA0E9 /* GLUT.framework */, - 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, - 2A7D3A1D115BA29F00DE3BD1 /* OpenGL.framework */, - 2A7D3A30115BA35200DE3BD1 /* CoreFoundation.framework */, - 2A7D3A32115BA35200DE3BD1 /* IOKit.framework */, - 2A474DEF1163A013006993EA /* AudioUnit.framework */, - 2A474DF11163A013006993EA /* CoreAudio.framework */, - ); - name = "Linked Frameworks"; - sourceTree = ""; - }; - 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { - isa = PBXGroup; - children = ( - 29B97324FDCFA39411CA2CEA /* AppKit.framework */, - 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */, - 29B97325FDCFA39411CA2CEA /* Foundation.framework */, - ); - name = "Other Frameworks"; - sourceTree = ""; - }; - 19C28FACFE9D520D11CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 8D1107320486CEB800E47090 /* Yabause.app */, - 2A7D3A55115BA3E700DE3BD1 /* gen68k */, - ); - name = Products; - sourceTree = ""; - }; - 29B97314FDCFA39411CA2CEA /* Yabause */ = { - isa = PBXGroup; - children = ( - 2A7D3972115BA0DD00DE3BD1 /* Emulation Core */, - 080E96DDFE201D6D7F000001 /* Classes */, - 29B97315FDCFA39411CA2CEA /* Other Sources */, - 29B97317FDCFA39411CA2CEA /* Resources */, - 29B97323FDCFA39411CA2CEA /* Frameworks */, - 19C28FACFE9D520D11CA2CBB /* Products */, - ); - name = Yabause; - sourceTree = ""; - }; - 29B97315FDCFA39411CA2CEA /* Other Sources */ = { - isa = PBXGroup; - children = ( - 29B97316FDCFA39411CA2CEA /* main.m */, - 2A82CC9F116171DB00F15B02 /* PerCocoa.h */, - 2A82CCA0116171DB00F15B02 /* PerCocoa.m */, - 2A7D39CD115BA16100DE3BD1 /* vidgcd.h */, - 2A7D39CC115BA16100DE3BD1 /* vidgcd.c */, - ); - name = "Other Sources"; - sourceTree = ""; - }; - 29B97317FDCFA39411CA2CEA /* Resources */ = { - isa = PBXGroup; - children = ( - 2A9D760D11665F2800A580EB /* controller.png */, - 2A7D3AD4115BB01500DE3BD1 /* Yabause.icns */, - 8D1107310486CEB800E47090 /* Yabause-Info.plist */, - 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, - 2A7D3A99115BAB9E00DE3BD1 /* MainMenu.xib */, - ); - name = Resources; - sourceTree = ""; - }; - 29B97323FDCFA39411CA2CEA /* Frameworks */ = { - isa = PBXGroup; - children = ( - 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, - 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, - ); - name = Frameworks; - sourceTree = ""; - }; - 2A7D3972115BA0DD00DE3BD1 /* Emulation Core */ = { - isa = PBXGroup; - children = ( - F0E47FAE156C34FB001A1B51 /* osdcore.h */, - F0E47FAC156C34EC001A1B51 /* osdcore.c */, - F07E62CC15054DF500DF8A4E /* titan.h */, - F07E62CA15054DCC00DF8A4E /* titan.c */, - F07BF9E314A1C2C500775818 /* yglshader.c */, - 2A7D3A3E115BA38900DE3BD1 /* C68K */, - 2A7D3987115BA16100DE3BD1 /* bios.c */, - 2A7D3988115BA16100DE3BD1 /* bios.h */, - 2A7D3989115BA16100DE3BD1 /* cd-macosx.c */, - 2A7D398A115BA16100DE3BD1 /* cdbase.c */, - 2A7D398B115BA16100DE3BD1 /* cdbase.h */, - 2A7D398C115BA16100DE3BD1 /* cheat.c */, - 2A7D398D115BA16100DE3BD1 /* cheat.h */, - 2A7D398E115BA16100DE3BD1 /* coffelf.c */, - 2A7D398F115BA16100DE3BD1 /* coffelf.h */, - 2A7D3990115BA16100DE3BD1 /* core.h */, - 2A7D3991115BA16100DE3BD1 /* cs0.c */, - 2A7D3992115BA16100DE3BD1 /* cs0.h */, - 2A7D3993115BA16100DE3BD1 /* cs1.c */, - 2A7D3994115BA16100DE3BD1 /* cs1.h */, - 2A7D3995115BA16100DE3BD1 /* cs2.c */, - 2A7D3996115BA16100DE3BD1 /* cs2.h */, - 2A7D3997115BA16100DE3BD1 /* debug.c */, - 2A7D3998115BA16100DE3BD1 /* debug.h */, - 2A7D3999115BA16100DE3BD1 /* error.c */, - 2A7D399A115BA16100DE3BD1 /* error.h */, - 2A7D399B115BA16100DE3BD1 /* m68kc68k.c */, - 2A7D399C115BA16100DE3BD1 /* m68kc68k.h */, - 2A7D399D115BA16100DE3BD1 /* m68kcore.c */, - 2A7D399E115BA16100DE3BD1 /* m68kcore.h */, - 2A7D399F115BA16100DE3BD1 /* m68kd.c */, - 2A7D39A0115BA16100DE3BD1 /* m68kd.h */, - 2A7D39A1115BA16100DE3BD1 /* m68kq68.c */, - 2A7D39A2115BA16100DE3BD1 /* macjoy.c */, - 2A7D39A3115BA16100DE3BD1 /* macjoy.h */, - 2A7D39A4115BA16100DE3BD1 /* memory.c */, - 2A7D39A5115BA16100DE3BD1 /* memory.h */, - 2A7D39A6115BA16100DE3BD1 /* movie.c */, - 2A7D39A7115BA16100DE3BD1 /* movie.h */, - 2A7D39A8115BA16100DE3BD1 /* netlink.c */, - 2A7D39A9115BA16100DE3BD1 /* netlink.h */, - 2A7D39AA115BA16100DE3BD1 /* peripheral.c */, - 2A7D39AB115BA16100DE3BD1 /* peripheral.h */, - 2A7D39AC115BA16100DE3BD1 /* permacjoy.c */, - 2A7D39AD115BA16100DE3BD1 /* permacjoy.h */, - 2A7D39AE115BA16100DE3BD1 /* profile.c */, - 2A7D39AF115BA16100DE3BD1 /* profile.h */, - 2A7D39B0115BA16100DE3BD1 /* scsp.c */, - 2A7D39B1115BA16100DE3BD1 /* scsp.h */, - 2AD10F97118BBC850088FB2C /* scsp2.c */, - 2AD10F98118BBC850088FB2C /* scsp2.h */, - 2A7D39B2115BA16100DE3BD1 /* scu.c */, - 2A7D39B3115BA16100DE3BD1 /* scu.h */, - 2A7D39B4115BA16100DE3BD1 /* sh2core.c */, - 2A7D39B5115BA16100DE3BD1 /* sh2core.h */, - 2A7D39B6115BA16100DE3BD1 /* sh2d.c */, - 2A7D39B7115BA16100DE3BD1 /* sh2d.h */, - 2A7D39B8115BA16100DE3BD1 /* sh2idle.c */, - 2A7D39B9115BA16100DE3BD1 /* sh2idle.h */, - 2A7D39BA115BA16100DE3BD1 /* sh2int.c */, - 2A7D39BB115BA16100DE3BD1 /* sh2int.h */, - 2A7D39BC115BA16100DE3BD1 /* sh2trace.c */, - 2A7D39BD115BA16100DE3BD1 /* sh2trace.h */, - 2A7D39BE115BA16100DE3BD1 /* smpc.c */, - 2A7D39BF115BA16100DE3BD1 /* smpc.h */, - 2AD10F99118BBC850088FB2C /* snddummy.c */, - 2A9D75FE116645D700A580EB /* sndmac.c */, - 2A9D75FF116645D700A580EB /* sndmac.h */, - 2AD10F9A118BBC850088FB2C /* sndwav.c */, - 2AD10F9B118BBC850088FB2C /* thr-dummy.c */, - 2AD10F9C118BBC850088FB2C /* thr-macosx.c */, - 2AD10F9D118BBC850088FB2C /* threads.h */, - 2A7D39C2115BA16100DE3BD1 /* vdp1.c */, - 2A7D39C3115BA16100DE3BD1 /* vdp1.h */, - 2A7D39C4115BA16100DE3BD1 /* vdp2.c */, - 2A7D39C5115BA16100DE3BD1 /* vdp2.h */, - 2A7D39C6115BA16100DE3BD1 /* vdp2debug.c */, - 2A7D39C7115BA16100DE3BD1 /* vdp2debug.h */, - 2A7D39C8115BA16100DE3BD1 /* vidogl.c */, - 2A7D39C9115BA16100DE3BD1 /* vidogl.h */, - 2A7D39CA115BA16100DE3BD1 /* vidshared.c */, - 2A7D39CB115BA16100DE3BD1 /* vidshared.h */, - 2A7AB7CE117D1CBE00E47298 /* vidsoft.h */, - 2A7AB7CB117D1C1B00E47298 /* vidsoft.c */, - 2A7D39CE115BA16100DE3BD1 /* yabause.c */, - 2A7D39CF115BA16100DE3BD1 /* yabause.h */, - 2A7D39D0115BA16100DE3BD1 /* ygl.c */, - 2A7D39D1115BA16100DE3BD1 /* ygl.h */, - 2A7D39D2115BA16100DE3BD1 /* yui.h */, - ); - name = "Emulation Core"; - sourceTree = ""; - }; - 2A7D3A3E115BA38900DE3BD1 /* C68K */ = { - isa = PBXGroup; - children = ( - 2A7D3A41115BA3AF00DE3BD1 /* c68k.c */, - 2A7D3A42115BA3AF00DE3BD1 /* c68k.h */, - 2A7D3A43115BA3AF00DE3BD1 /* c68kexec.c */, - 2A7D3A44115BA3AF00DE3BD1 /* c68kmac.inc */, - 2A7D3A45115BA3AF00DE3BD1 /* gen68k.c */, - 2A7D3A46115BA3AF00DE3BD1 /* gen68k.h */, - 2A7D3A47115BA3AF00DE3BD1 /* gen68k.inc */, - ); - name = C68K; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 2A7D3A54115BA3E700DE3BD1 /* gen68k */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2A7D3A59115BA40C00DE3BD1 /* Build configuration list for PBXNativeTarget "gen68k" */; - buildPhases = ( - 2A7D3A52115BA3E700DE3BD1 /* Sources */, - 2A7D3A53115BA3E700DE3BD1 /* Frameworks */, - 2A7D3A6F115BA5A200DE3BD1 /* Run gen68k */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = gen68k; - productName = gen68k; - productReference = 2A7D3A55115BA3E700DE3BD1 /* gen68k */; - productType = "com.apple.product-type.tool"; - }; - 8D1107260486CEB800E47090 /* Yabause */ = { - isa = PBXNativeTarget; - buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Yabause" */; - buildPhases = ( - 8D1107290486CEB800E47090 /* Resources */, - 8D11072C0486CEB800E47090 /* Sources */, - 8D11072E0486CEB800E47090 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 2A7D3A7B115BA63900DE3BD1 /* PBXTargetDependency */, - ); - name = Yabause; - productInstallPath = "$(HOME)/Applications"; - productName = Yabause; - productReference = 8D1107320486CEB800E47090 /* Yabause.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 29B97313FDCFA39411CA2CEA /* Project object */ = { - isa = PBXProject; - buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Yabause" */; - compatibilityVersion = "Xcode 2.4"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 29B97314FDCFA39411CA2CEA /* Yabause */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 2A7D3A54115BA3E700DE3BD1 /* gen68k */, - 8D1107260486CEB800E47090 /* Yabause */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 8D1107290486CEB800E47090 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */, - 2A7D3A9B115BAB9E00DE3BD1 /* MainMenu.xib in Resources */, - 2A7D3AD5115BB01500DE3BD1 /* Yabause.icns in Resources */, - 2A9D760E11665F2800A580EB /* controller.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 2A7D3A6F115BA5A200DE3BD1 /* Run gen68k */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "$(PROJECT_DIR)/../gen68k/gen68k.c", - "$(PROJECT_DIR)/../gen68k/gen68k.h", - "$(PROJECT_DIR)/../gen68k/gen68k.inc", - "$(PROJECT_DIR)/../gen68k/c68kmac.inc", - "$(PROJECT_DIR)/../gen68k/c68kexec.c", - "$(PROJECT_DIR)/../gen68k/c68k.c", - "$(PROJECT_DIR)/../gen68k/c68k.h", - ); - name = "Run gen68k"; - outputPaths = ( - "$(PROJECT_DIR)/../gen68k/c68k_op0.inc", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "cd ../c68k\n\"$BUILD_DIR/$CONFIGURATION/gen68k\""; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 2A7D3A52115BA3E700DE3BD1 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2A7D3A5A115BA41200DE3BD1 /* gen68k.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8D11072C0486CEB800E47090 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8D11072D0486CEB800E47090 /* main.m in Sources */, - 2A7D39D3115BA16100DE3BD1 /* bios.c in Sources */, - 2A7D39D4115BA16100DE3BD1 /* cd-macosx.c in Sources */, - 2A7D39D5115BA16100DE3BD1 /* cdbase.c in Sources */, - 2A7D39D6115BA16100DE3BD1 /* cheat.c in Sources */, - 2A7D39D7115BA16100DE3BD1 /* coffelf.c in Sources */, - 2A7D39D8115BA16100DE3BD1 /* cs0.c in Sources */, - 2A7D39D9115BA16100DE3BD1 /* cs1.c in Sources */, - 2A7D39DA115BA16100DE3BD1 /* cs2.c in Sources */, - 2A7D39DB115BA16100DE3BD1 /* debug.c in Sources */, - 2A7D39DC115BA16100DE3BD1 /* error.c in Sources */, - 2A7D39DD115BA16100DE3BD1 /* m68kc68k.c in Sources */, - 2A7D39DE115BA16100DE3BD1 /* m68kcore.c in Sources */, - 2A7D39DF115BA16100DE3BD1 /* m68kd.c in Sources */, - 2A7D39E1115BA16100DE3BD1 /* macjoy.c in Sources */, - 2A7D39E2115BA16100DE3BD1 /* memory.c in Sources */, - 2A7D39E3115BA16100DE3BD1 /* movie.c in Sources */, - 2A7D39E4115BA16100DE3BD1 /* netlink.c in Sources */, - 2A7D39E5115BA16100DE3BD1 /* peripheral.c in Sources */, - 2A7D39E6115BA16100DE3BD1 /* permacjoy.c in Sources */, - 2A7D39E7115BA16100DE3BD1 /* profile.c in Sources */, - 2A7D39E9115BA16100DE3BD1 /* scu.c in Sources */, - 2A7D39EA115BA16100DE3BD1 /* sh2core.c in Sources */, - 2A7D39EB115BA16100DE3BD1 /* sh2d.c in Sources */, - 2A7D39EC115BA16100DE3BD1 /* sh2idle.c in Sources */, - 2A7D39ED115BA16100DE3BD1 /* sh2int.c in Sources */, - 2A7D39EE115BA16100DE3BD1 /* sh2trace.c in Sources */, - 2A7D39EF115BA16100DE3BD1 /* smpc.c in Sources */, - 2A7D39F1115BA16100DE3BD1 /* vdp1.c in Sources */, - 2A7D39F2115BA16100DE3BD1 /* vdp2.c in Sources */, - 2A7D39F3115BA16100DE3BD1 /* vdp2debug.c in Sources */, - 2A7D39F4115BA16100DE3BD1 /* vidogl.c in Sources */, - 2A7D39F5115BA16100DE3BD1 /* vidshared.c in Sources */, - 2A7D39F6115BA16100DE3BD1 /* vidgcd.c in Sources */, - 2A7D39F7115BA16100DE3BD1 /* yabause.c in Sources */, - 2A7D39F8115BA16100DE3BD1 /* ygl.c in Sources */, - 2A7D3A48115BA3AF00DE3BD1 /* c68k.c in Sources */, - 2A7D3A49115BA3AF00DE3BD1 /* c68kexec.c in Sources */, - 2A7D3A4B115BA3AF00DE3BD1 /* gen68k.c in Sources */, - 2AF0CA51116146A400196BED /* YabauseGLView.m in Sources */, - 2AF0CA9911614DD500196BED /* YabauseController.m in Sources */, - 2A82CCA1116171DB00F15B02 /* PerCocoa.m in Sources */, - 2A9D7600116645D700A580EB /* sndmac.c in Sources */, - 2A9D7621116667C300A580EB /* YabausePrefsController.m in Sources */, - 2A7AB7CC117D1C1B00E47298 /* vidsoft.c in Sources */, - 2AD10F9E118BBC850088FB2C /* scsp2.c in Sources */, - 2AD10F9F118BBC850088FB2C /* snddummy.c in Sources */, - 2AD10FA0118BBC850088FB2C /* sndwav.c in Sources */, - 2AD10FDB118BCFA00088FB2C /* thr-dummy.c in Sources */, - 2A1145191385E5010087C872 /* YabauseButtonFormatter.m in Sources */, - F07BF9E414A1C2C500775818 /* yglshader.c in Sources */, - F07E62CB15054DCC00DF8A4E /* titan.c in Sources */, - F0E47FAD156C34EC001A1B51 /* osdcore.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 2A7D3A7B115BA63900DE3BD1 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 2A7D3A54115BA3E700DE3BD1 /* gen68k */; - targetProxy = 2A7D3A7A115BA63900DE3BD1 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 089C165DFE840E0CC02AAC07 /* English */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; - 2A7D3A99115BAB9E00DE3BD1 /* MainMenu.xib */ = { - isa = PBXVariantGroup; - children = ( - 2A7D3A9A115BAB9E00DE3BD1 /* English */, - ); - name = MainMenu.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 2A7D3A57115BA3E800DE3BD1 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = C68K_GEN; - INSTALL_PATH = /usr/local/bin; - PREBINDING = NO; - PRODUCT_NAME = gen68k; - }; - name = Debug; - }; - 2A7D3A58115BA3E800DE3BD1 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_MODEL_TUNING = G5; - GCC_PREPROCESSOR_DEFINITIONS = C68K_GEN; - INSTALL_PATH = /usr/local/bin; - PREBINDING = NO; - PRODUCT_NAME = gen68k; - ZERO_LINK = NO; - }; - name = Release; - }; - C01FCF4B08A954540054247B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(NATIVE_ARCH_ACTUAL)"; - COPY_PHASE_STRIP = NO; - ENABLE_OPENMP_SUPPORT = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 3; - GCC_PRECOMPILE_PREFIX_HEADER = NO; - GCC_PREFIX_HEADER = ""; - GCC_UNROLL_LOOPS = YES; - GCC_VERSION = 4.2; - INFOPLIST_FILE = "Yabause-Info.plist"; - INSTALL_PATH = "$(HOME)/Applications"; - OTHER_CFLAGS = "-fnested-functions"; - PRODUCT_NAME = Yabause; - }; - name = Debug; - }; - C01FCF4C08A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_OPENMP_SUPPORT = NO; - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = NO; - GCC_PREFIX_HEADER = ""; - GCC_UNROLL_LOOPS = YES; - GCC_VERSION = 4.2; - INFOPLIST_FILE = "Yabause-Info.plist"; - INSTALL_PATH = "$(HOME)/Applications"; - ONLY_ACTIVE_ARCH = YES; - OTHER_CFLAGS = "-fnested-functions"; - PRODUCT_NAME = Yabause; - }; - name = Release; - }; - C01FCF4F08A954540054247B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(NATIVE_ARCH_ACTUAL)"; - ENABLE_OPENMP_SUPPORT = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_OPTIMIZATION_LEVEL = 3; - GCC_PREPROCESSOR_DEFINITIONS = ( - "USE_SCSP2=1", - CRAB_REWRITE, - NO_CLI, - HAVE_LIBGL, - HAVE_LIBGLUT, - HAVE_SYS_TIME_H, - HAVE_GETTIMEOFDAY, - "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_1)", - ); - GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_1 = "VERSION=\\\"0.9.10\\\""; - GCC_VERSION = 4.2; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; - OTHER_CFLAGS = ""; - PREBINDING = NO; - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.6.sdk"; - }; - name = Debug; - }; - C01FCF5008A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ONLY_ACTIVE_ARCH_PRE_XCODE_3_1)"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_OPTIMIZATION_LEVEL = 3; - GCC_PREPROCESSOR_DEFINITIONS = ( - "USE_SCSP2=1", - CRAB_REWRITE, - NO_CLI, - HAVE_LIBGL, - HAVE_LIBGLUT, - HAVE_SYS_TIME_H, - HAVE_GETTIMEOFDAY, - "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_1)", - ); - GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_1 = "VERSION=\\\"0.9.10\\\""; - GCC_VERSION = 4.2; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH_PRE_XCODE_3_1 = "$(NATIVE_ARCH_ACTUAL)"; - OTHER_CFLAGS = ""; - PREBINDING = NO; - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.6.sdk"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 2A7D3A59115BA40C00DE3BD1 /* Build configuration list for PBXNativeTarget "gen68k" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2A7D3A57115BA3E800DE3BD1 /* Debug */, - 2A7D3A58115BA3E800DE3BD1 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Yabause" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C01FCF4B08A954540054247B /* Debug */, - C01FCF4C08A954540054247B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Yabause" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C01FCF4F08A954540054247B /* Debug */, - C01FCF5008A954540054247B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; -} diff --git a/yabause/src/cocoa/YabauseButtonFormatter.h b/yabause/src/cocoa/YabauseButtonFormatter.h deleted file mode 100644 index e283c5b424..0000000000 --- a/yabause/src/cocoa/YabauseButtonFormatter.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright 2011 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YabauseButtonFormatter_h -#define YabauseButtonFormatter_h - -#import - - -@interface YabauseButtonFormatter : NSFormatter { -} - -- (NSString *)stringForObjectValue:(id)obj; -- (BOOL)getObjectValue:(id *)obj - forString:(NSString *)str - errorDescription:(NSString **)err; - -- (BOOL)control:(NSControl*)control - textView:(NSTextView*)textView - doCommandBySelector:(SEL)commandSelector; - -@end /* @interface YabauseButtonFormatter */ - -#endif /* !YabauseButtonFormatter_h */ diff --git a/yabause/src/cocoa/YabauseButtonFormatter.m b/yabause/src/cocoa/YabauseButtonFormatter.m deleted file mode 100644 index 258846b893..0000000000 --- a/yabause/src/cocoa/YabauseButtonFormatter.m +++ /dev/null @@ -1,112 +0,0 @@ -/* Copyright 2011 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "YabauseButtonFormatter.h" -#include - -@implementation YabauseButtonFormatter - -- (NSString *)stringForObjectValue:(id)obj -{ - if(![obj isKindOfClass:[NSString class]]) { - return nil; - } - - if([obj length] >= 1) { - return [obj substringToIndex:1]; - } - else { - return [NSString string]; - } -} - -- (BOOL)getObjectValue:(id *)obj - forString:(NSString *)str - errorDescription:(NSString **)err -{ - if(obj) { - if([str length] >= 1) { - *obj = [NSString stringWithString:[str substringToIndex:1]]; - } - else { - *obj = [NSString string]; - } - } - - return YES; -} - -- (BOOL)isPartialStringValid:(NSString **)partialStringPtr - proposedSelectedRange:(NSRangePointer)proposedSelRangePtr - originalString:(NSString *)origString - originalSelectedRange:(NSRange)origSelRange - errorDescription:(NSString **)error -{ - NSString *rs = [[*partialStringPtr substringToIndex:1] uppercaseString]; - - *partialStringPtr = rs; - *proposedSelRangePtr = NSMakeRange(0, [rs length]); - - return NO; -} - -- (BOOL)control:(NSControl*)control - textView:(NSTextView*)textView - doCommandBySelector:(SEL)commandSelector -{ - BOOL result = NO; - - /* handle all the fun special cases... */ - if(commandSelector == @selector(insertNewline:)) { - [textView insertText:@"\u23CE"]; - result = YES; - } - else if(commandSelector == @selector(insertTab:)) { - [textView insertText:@"\u21E5"]; - result = YES; - } - else if(commandSelector == @selector(cancelOperation:)) { - [textView insertText:@"\u241B"]; - result = YES; - } - else if(commandSelector == @selector(deleteBackward:)) { - [textView insertText:@"\u232B"]; - result = YES; - } - else if(commandSelector == @selector(moveLeft:)) { - [textView insertText:@"\u2190"]; - result = YES; - } - else if(commandSelector == @selector(moveUp:)) { - [textView insertText:@"\u2191"]; - result = YES; - } - else if(commandSelector == @selector(moveRight:)) { - [textView insertText:@"\u2192"]; - result = YES; - } - else if(commandSelector == @selector(moveDown:)) { - [textView insertText:@"\u2193"]; - result = YES; - } - - return result; -} - -@end /* @implementation YabauseButtonFormatter */ diff --git a/yabause/src/cocoa/YabauseController.h b/yabause/src/cocoa/YabauseController.h deleted file mode 100644 index 02bebff99e..0000000000 --- a/yabause/src/cocoa/YabauseController.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright 2010, 2012 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YabauseController_h -#define YabauseController_h - -#import - -@class YabauseGLView; -@class YabausePrefsController; - -@interface YabauseController : NSObject { - IBOutlet YabauseGLView *view; - IBOutlet NSPanel *prefsPane; - IBOutlet YabausePrefsController *prefs; - IBOutlet NSMenuItem *frameskip; - IBOutlet NSWindow *logWindow; - IBOutlet NSTextView *logView; - BOOL _running; - BOOL _paused; - NSLock *_runLock; - NSThread *_emuThd; - char *_bramFile; - char *_isoFile; - BOOL _doneExecuting; -} - -- (void)awakeFromNib; -- (void)dealloc; - -/* NSWindow delegate methods */ -- (BOOL)windowShouldClose:(id)sender; - -/* NSApplication delegate methods */ -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app; - -- (IBAction)showPreferences:(id)sender; -- (IBAction)runBIOS:(id)sender; -- (IBAction)runCD:(id)sender; -- (IBAction)runISO:(id)sender; -- (IBAction)toggleFullscreen:(id)sender; -- (IBAction)toggle:(id)sender; -- (IBAction)toggleFrameskip:(id)sender; -- (IBAction)pause:(id)sender; -- (IBAction)reset:(id)sender; - -- (YabauseGLView *)view; - -@end - -extern YabauseController *controller; - -#endif /* !YabauseController_h */ diff --git a/yabause/src/cocoa/YabauseController.m b/yabause/src/cocoa/YabauseController.m deleted file mode 100644 index 313bff1339..0000000000 --- a/yabause/src/cocoa/YabauseController.m +++ /dev/null @@ -1,379 +0,0 @@ -/* Copyright 2010, 2012 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include - -#include "YabauseController.h" -#include "YabauseGLView.h" -#include "YabausePrefsController.h" - -#include "vdp1.h" -#include "vdp2.h" -#include "scsp.h" -#include "peripheral.h" -#include "cdbase.h" -#include "yabause.h" -#include "yui.h" -#include "PerCocoa.h" -#include "m68kc68k.h" -#include "cs0.h" - -YabauseController *controller; - -@interface YabauseController (InternalFunctions) -- (void)startEmulationWithCDCore:(int)cdcore CDPath:(const char *)fn; -- (void)emulationThread:(id)ignored; -- (void)terminateEmulation; -@end - -/* Menu Item tags. */ -enum { - tagVDP1 = 1, - tagNBG0 = 2, - tagNBG1 = 3, - tagNBG2 = 4, - tagNBG3 = 5, - tagRBG0 = 6, - tagFPS = 7 -}; - -static void FlipToggle(NSMenuItem *item) { - if([item state] == NSOffState) { - [item setState:NSOnState]; - } - else { - [item setState:NSOffState]; - } -} - -@implementation YabauseController - -- (void)awakeFromNib -{ - NSUserDefaults *p = [NSUserDefaults standardUserDefaults]; - - controller = self; - _running = NO; - _paused = NO; - _runLock = [[NSLock alloc] init]; - _emuThd = nil; - _bramFile = NULL; - _doneExecuting = NO; - - if([p boolForKey:@"Enable Frameskip"]) { - [frameskip setState:NSOnState]; - EnableAutoFrameSkip(); - } - else { - [frameskip setState:NSOffState]; - DisableAutoFrameSkip(); - } -} - -- (void)dealloc -{ - [_runLock release]; - [super dealloc]; -} - -- (BOOL)windowShouldClose:(id)sender -{ - [self terminateEmulation]; - return YES; -} - -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app -{ - [self terminateEmulation]; - return NSTerminateNow; -} - -- (IBAction)showPreferences:(id)sender -{ - [prefsPane makeKeyAndOrderFront:self]; -} - -- (IBAction)runBIOS:(id)sender -{ - /* This will simply start up the system with the dummy CD core, so there's - no way it'll actually read that there's a disc to be played. */ - [self startEmulationWithCDCore:CDCORE_DUMMY CDPath:NULL]; -} - -- (IBAction)runCD:(id)sender -{ - [self startEmulationWithCDCore:CDCORE_ARCH CDPath:NULL]; -} - -- (IBAction)runISO:(id)sender -{ - NSOpenPanel *p = [NSOpenPanel openPanel]; - NSArray *types = [NSArray arrayWithObjects:@"iso", @"cue", nil]; - - [p setAllowedFileTypes:types]; - if([p runModal] == NSFileHandlingPanelOKButton) { - NSString *fn = [[[p URLs] objectAtIndex:0] path]; - [self startEmulationWithCDCore:CDCORE_ISO - CDPath:[fn fileSystemRepresentation]]; - } -} - -- (IBAction)toggleFullscreen:(id)sender -{ - /* The view handles any heavy lifting here... */ - [view toggleFullscreen]; -} - -- (IBAction)toggle:(id)sender -{ - /* None of these will work unless we're running... */ - if(!_running) { - return; - } - - /* Flip the checkmark on the button. */ - FlipToggle((NSMenuItem *)sender); - - /* Do whatever this toggle is asking us to do. */ - switch([sender tag]) { - case tagVDP1: - ToggleVDP1(); - break; - - case tagNBG0: - ToggleNBG0(); - break; - - case tagNBG1: - ToggleNBG1(); - break; - - case tagNBG2: - ToggleNBG2(); - break; - - case tagNBG3: - ToggleNBG3(); - break; - - case tagRBG0: - ToggleRBG0(); - break; - - case tagFPS: - ToggleFPS(); - break; - } -} - -- (IBAction)toggleFrameskip:(id)sender -{ - NSUserDefaults *p = [NSUserDefaults standardUserDefaults]; - - if([sender state] == NSOnState) { - DisableAutoFrameSkip(); - [sender setState:NSOffState]; - [p setBool:NO forKey:@"Enable Frameskip"]; - } - else { - EnableAutoFrameSkip(); - [sender setState:NSOnState]; - [p setBool:YES forKey:@"Enable Frameskip"]; - } -} - -- (IBAction)pause:(id)sender -{ - if(_running) { - if(!_paused) { - _paused = YES; - - /* Mute the audio before we actually pause otherwise the user might - not like the result... */ - ScspMuteAudio(SCSP_MUTE_SYSTEM); - [_runLock lock]; - [sender setState:NSOnState]; - } - else { - _paused = NO; - [_runLock unlock]; - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - [sender setState:NSOffState]; - } - } -} - -- (IBAction)reset:(id)sender -{ - if(_running) { - /* Act as if the user pressed the reset button on the console. */ - YabauseResetButton(); - } -} - -- (YabauseGLView *)view -{ - return view; -} - -@end /* @implementation YabauseController */ - -@implementation YabauseController (InternalFunctions) - -- (void)startEmulationWithCDCore:(int)cdcore CDPath:(const char *)fn -{ - if(!_running) { - yabauseinit_struct yinit; - int initok; - NSString *bios = [prefs biosPath]; - NSString *mpeg = [prefs mpegPath]; - NSString *bram = [prefs bramPath]; - NSString *cart = [prefs cartPath]; - - yinit.percoretype = PERCORE_COCOA; - yinit.sh2coretype = SH2CORE_DEFAULT; - yinit.vidcoretype = [prefs videoCore]; - yinit.sndcoretype = [prefs soundCore]; - yinit.m68kcoretype = M68KCORE_C68K; - yinit.cdcoretype = cdcore; - yinit.carttype = [prefs cartType]; - yinit.regionid = [prefs region]; - yinit.biospath = ([bios length] > 0 && ![prefs emulateBios]) ? - [bios UTF8String] : NULL; - yinit.cdpath = fn; - yinit.buppath = NULL; - yinit.mpegpath = ([mpeg length] > 0) ? [mpeg UTF8String] : NULL; - yinit.videoformattype = ([prefs region] < 10) ? VIDEOFORMATTYPE_NTSC : - VIDEOFORMATTYPE_PAL; - yinit.frameskip = [frameskip state] == NSOnState; - yinit.clocksync = 0; - yinit.basetime = 0; - yinit.usethreads = 0; - - /* Set up the internal save ram if specified. */ - if([bram length] > 0) { - const char *tmp = [bram UTF8String]; - yinit.buppath = _bramFile = strdup(tmp); - } - - if(fn) - _isoFile = strdup(fn); - - /* Set up the cartridge stuff based on what was selected. */ - if(yinit.carttype == CART_NETLINK) { - yinit.cartpath = NULL; - yinit.netlinksetting = ([cart length] > 0) ? - [cart UTF8String] : NULL; - } - else { - yinit.cartpath = ([cart length] > 0) ? [cart UTF8String] : NULL; - yinit.netlinksetting = NULL; - } - - if(cdcore == CDCORE_DUMMY && !yinit.biospath) { - NSRunAlertPanel(@"Yabause Error", @"You must specify a BIOS file " - "(and have BIOS emulation disabled) in order to " - "run the BIOS.", @"OK", NULL, NULL); - return; - } - - [[view openGLContext] makeCurrentContext]; - initok = YabauseInit(&yinit); - [NSOpenGLContext clearCurrentContext]; - if (initok != 0) { - return; - } - - YabauseSetDecilineMode(1); - - _running = YES; - _doneExecuting = NO; - - [view showWindow]; - - /* The emulation itself takes place in a separate thread from the main - GUI thread. */ - [NSThread detachNewThreadSelector:@selector(emulationThread:) - toTarget:self - withObject:nil]; - } -} - -- (void)emulationThread:(id)ignored -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - CGLContextObj cxt; - - _emuThd = [NSThread currentThread]; - - /* Make the OpenGL context current for this thread, otherwise we will be - drawing to nothingness. */ - [[view openGLContext] makeCurrentContext]; - - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - - while(_running) { - /* If we get paused from the GUI, we'll end up waiting in this lock - here... Maybe not the most clear way to do it, but it works. */ - [_runLock lock]; - - /* Make sure the main thread doesn't attempt to flip the buffer before - this thread is done rendering. */ - cxt = CGLGetCurrentContext(); - CGLLockContext(cxt); - - /* Shortcut a function call here... We should technically be doing a - PERCore->HandleEvents(), but that function simply calls YabauseExec() - anyway... so cut out the middleman. */ - YabauseExec(); - - CGLUnlockContext(cxt); - [_runLock unlock]; - } - - ScspMuteAudio(SCSP_MUTE_SYSTEM); - - _doneExecuting = YES; - [pool release]; -} - -- (void)terminateEmulation -{ - _running = NO; - - /* Wait for the thread to die, and then clean up after it. */ - if(_emuThd) { - while(!_doneExecuting) { - sched_yield(); - } - - YabauseDeInit(); - - free(_bramFile); - _bramFile = NULL; - free(_isoFile); - _isoFile = NULL; - - _emuThd = nil; - } -} - -@end /* @implementation YabauseController (InternalFunctions) */ diff --git a/yabause/src/cocoa/YabauseGLView.h b/yabause/src/cocoa/YabauseGLView.h deleted file mode 100644 index 110d1317a3..0000000000 --- a/yabause/src/cocoa/YabauseGLView.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YabauseGLView_h -#define YabauseGLView_h - -#import -#include -#include - -@interface YabauseGLView : NSOpenGLView { - IBOutlet NSWindow *window; - BOOL _isFullscreen; - NSPoint _mouseLoc; -} - -- (id)initWithFrame:(NSRect)frameRect; - -- (void)toggleFullscreen; - -- (BOOL)acceptsFirstResponder; -- (void)keyDown:(NSEvent *)event; -- (void)keyUp:(NSEvent *)event; - -- (void)showWindow; - -- (void)reshape; -- (void)drawRect:(NSRect)rect; - -@end - -#endif /* !YabauseGLView_h */ diff --git a/yabause/src/cocoa/YabauseGLView.m b/yabause/src/cocoa/YabauseGLView.m deleted file mode 100644 index 3a196ca407..0000000000 --- a/yabause/src/cocoa/YabauseGLView.m +++ /dev/null @@ -1,217 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "YabauseGLView.h" - -#include "peripheral.h" -#include "vdp1.h" - -@interface YabauseGLView (InternalFunctions) -- (NSScreen *)screen; -- (CGDirectDisplayID)screenID; - -/* These are nice to have, but not really necessary to things... */ -- (float)width; -- (float)height; -@end - -@implementation YabauseGLView - -- (id)initWithFrame:(NSRect)frameRect -{ - NSOpenGLPixelFormatAttribute attrs[] = { - NSOpenGLPFAWindow, - NSOpenGLPFANoRecovery, - NSOpenGLPFAColorSize, 32, - NSOpenGLPFADepthSize, 32, - NSOpenGLPFADoubleBuffer, - 0 - }; - - NSOpenGLPixelFormat *fmt; - - fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; - - if(fmt == nil) { - [fmt release]; - return nil; - } - - if(!(self = [super initWithFrame:frameRect pixelFormat:fmt])) { - [fmt release]; - return nil; - } - - _isFullscreen = NO; - - [fmt release]; - - return self; -} - -- (void)toggleFullscreen -{ - CGError err; - CGDisplayFadeReservationToken token; - CGDirectDisplayID d = [self screenID]; - - err = CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, - &token); - - if(err == kCGErrorSuccess) { - CGDisplayFade(token, 0.5, kCGDisplayBlendNormal, - kCGDisplayBlendSolidColor, 0, 0, 0, 1); - } - - if(!_isFullscreen) { - [self enterFullScreenMode:[self screen] withOptions:nil]; - - /* Hide the cursor, but store its location so we can restore it later. - Also, disassociate the mouse and the cursor position. */ - CGDisplayHideCursor(d); - _mouseLoc = [NSEvent mouseLocation]; - CGDisplayMoveCursorToPoint(d, CGPointZero); - CGAssociateMouseAndMouseCursorPosition(FALSE); - } - else { - CGPoint mousePoint; - int height = CGDisplayPixelsHigh(d); - - mousePoint.x = _mouseLoc.x; - mousePoint.y = height - _mouseLoc.y; - - /* Show the mouse pointer, and reassociate it with the mouse. */ - CGAssociateMouseAndMouseCursorPosition(TRUE); - CGDisplayMoveCursorToPoint(d, mousePoint); - CGDisplayShowCursor(d); - - [self exitFullScreenModeWithOptions:nil]; - [[self window] makeFirstResponder:self]; - } - - if(err == kCGErrorSuccess) { - CGDisplayFade(token, 0.5, kCGDisplayBlendNormal, - kCGDisplayBlendSolidColor, 0, 0, 0, 0); - CGReleaseDisplayFadeReservation(token); - } - - if(VIDCore) - VIDCore->Resize([self width], [self height], 0); - - _isFullscreen = !_isFullscreen; -} - -- (BOOL)acceptsFirstResponder -{ - return YES; -} - -- (void)keyDown:(NSEvent *)event -{ - if([[event charactersIgnoringModifiers] length] >= 1) { - PerKeyDown([[event charactersIgnoringModifiers] characterAtIndex:0]); - } -} - -- (void)keyUp:(NSEvent *)event -{ - if([[event charactersIgnoringModifiers] length] >= 1) { - PerKeyUp([[event charactersIgnoringModifiers] characterAtIndex:0]); - } -} - -- (void)showWindow -{ - [window makeKeyAndOrderFront:self]; -} - -- (void)reshape -{ - CGLContextObj cxt = CGLGetCurrentContext(); - - /* Make sure that the emulation thread doesn't attempt to do any OpenGL - calls during the resize event, otherwise one of the two will crash. */ - CGLLockContext(cxt); - - if(VIDCore) - VIDCore->Resize([self width], [self height], 0); - - CGLUnlockContext(cxt); - - [super reshape]; -} - -- (void)drawRect:(NSRect)rect -{ - CGLContextObj cxt = CGLGetCurrentContext(); - - /* Make sure that the emulation thread doesn't attempt to do any OpenGL - calls during the flush to the screen. */ - CGLLockContext(cxt); - [[self openGLContext] flushBuffer]; - CGLUnlockContext(cxt); -} - -@end /* @implementation YabauseGLView */ - -@implementation YabauseGLView (InternalFunctions) - -- (NSScreen *)screen -{ - NSArray *screens = [NSScreen screens]; - NSEnumerator *i = [screens objectEnumerator]; - NSScreen *obj; - NSRect f = [window frame]; - NSRect sf; - - /* Look for the screen that has the main window on it. */ - while((obj = (NSScreen *)[i nextObject])) { - sf = [obj frame]; - - if(f.origin.x >= sf.origin.x && f.origin.y >= sf.origin.y && - f.origin.x <= sf.origin.x + sf.size.width && - f.origin.y <= sf.origin.y + sf.size.height) { - return obj; - } - } - - /* Punt. */ - return [NSScreen mainScreen]; -} - -- (CGDirectDisplayID)screenID -{ - NSScreen *s = [self screen]; - NSDictionary *d = [s deviceDescription]; - NSNumber *n = (NSNumber *)[d objectForKey:@"NSScreenNumber"]; - - return (CGDirectDisplayID)[n unsignedIntValue]; -} - -- (float)width -{ - return [self bounds].size.width; -} - -- (float)height -{ - return [self bounds].size.height; -} - -@end /* @implementation YabauseGLView (InternalFunctions) */ diff --git a/yabause/src/cocoa/YabausePrefsController.h b/yabause/src/cocoa/YabausePrefsController.h deleted file mode 100644 index d82df96eb1..0000000000 --- a/yabause/src/cocoa/YabausePrefsController.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright 2010-2011 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YabausePrefsController_h -#define YabausePrefsController_h - -#import - -@interface YabausePrefsController : NSObject { - IBOutlet NSTextField *biosPath; - IBOutlet NSTextField *bramPath; - IBOutlet NSButton *cartBrowse; - IBOutlet NSTextField *cartPath; - IBOutlet NSPopUpButton *cartType; - IBOutlet NSButton *emulateBios; - IBOutlet NSTextField *mpegPath; - IBOutlet NSPopUpButton *region; - IBOutlet NSPopUpButton *soundCore; - IBOutlet NSPopUpButton *videoCore; - IBOutlet NSPanel *prefsPane; - IBOutlet NSPanel *buttonAssignment; - IBOutlet NSTextField *buttonBox; - - int _cartType; - int _region; - int _soundCore; - int _videoCore; - - NSUserDefaults *_prefs; -} - -- (void)awakeFromNib; -- (void)dealloc; - -/* NSTextField delegate methods */ -- (void)controlTextDidEndEditing:(NSNotification *)notification; - -- (IBAction)cartSelected:(id)sender; -- (IBAction)regionSelected:(id)sender; -- (IBAction)soundCoreSelected:(id)sender; -- (IBAction)videoCoreSelected:(id)sender; -- (IBAction)biosBrowse:(id)sender; -- (IBAction)mpegBrowse:(id)sender; -- (IBAction)bramBrowse:(id)sender; -- (IBAction)cartBrowse:(id)sender; -- (IBAction)biosToggle:(id)sender; -- (IBAction)buttonSelect:(id)sender; - -- (IBAction)buttonSetOk:(id)sender; -- (IBAction)buttonSetCancel:(id)sender; - -- (int)cartType; -- (int)region; -- (int)soundCore; -- (int)videoCore; -- (NSString *)biosPath; -- (BOOL)emulateBios; -- (NSString *)mpegPath; -- (NSString *)bramPath; -- (NSString *)cartPath; - -@end - -#endif /* !YabausePrefsController_h */ diff --git a/yabause/src/cocoa/YabausePrefsController.m b/yabause/src/cocoa/YabausePrefsController.m deleted file mode 100644 index 66692a44af..0000000000 --- a/yabause/src/cocoa/YabausePrefsController.m +++ /dev/null @@ -1,449 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "YabausePrefsController.h" - -#include "cs0.h" -#include "vidogl.h" -#include "vidsoft.h" -#include "scsp.h" -#include "smpc.h" -#include "sndmac.h" -#include "PerCocoa.h" - -@implementation YabausePrefsController - -- (void)awakeFromNib -{ - _cartType = CART_NONE; - _region = REGION_AUTODETECT; - _soundCore = SNDCORE_MAC; - _videoCore = VIDCORE_SOFT; - - _prefs = [[NSUserDefaults standardUserDefaults] retain]; - - /* Fill in all the settings. */ - if([_prefs objectForKey:@"BIOS Path"]) { - [biosPath setStringValue:[_prefs stringForKey:@"BIOS Path"]]; - } - else { - [_prefs setObject:@"" forKey:@"BIOS Path"]; - } - - if([_prefs objectForKey:@"Emulate BIOS"]) { - [emulateBios setState:[_prefs boolForKey:@"Emulate BIOS"] ? - NSOnState : NSOffState]; - } - else { - [_prefs setBool:YES forKey:@"Emulate BIOS"]; - } - - if([_prefs objectForKey:@"MPEG ROM Path"]) { - [mpegPath setStringValue:[_prefs objectForKey:@"MPEG ROM Path"]]; - } - else { - [_prefs setObject:@"" forKey:@"MPEG ROM Path"]; - } - - if([_prefs objectForKey:@"BRAM Path"]) { - [bramPath setStringValue:[_prefs objectForKey:@"BRAM Path"]]; - } - else { - [_prefs setObject:@"" forKey:@"BRAM Path"]; - } - - if([_prefs objectForKey:@"Cartridge Path"]) { - [cartPath setStringValue:[_prefs objectForKey:@"Cartridge Path"]]; - } - else { - [_prefs setObject:@"" forKey:@"Cartridge Path"]; - } - - if([_prefs objectForKey:@"Cartridge Type"]) { - _cartType = [_prefs integerForKey:@"Cartridge Type"]; - - if(_cartType != CART_NONE && _cartType != CART_DRAM8MBIT && - _cartType != CART_DRAM32MBIT) { - [cartPath setEnabled:YES]; - [cartBrowse setEnabled:YES]; - [[cartPath cell] setPlaceholderString:@"Not Set"]; - } - - [cartType selectItemWithTag:_cartType]; - } - else { - [_prefs setInteger:CART_NONE forKey:@"Cartridge Type"]; - } - - if([_prefs objectForKey:@"Region"]) { - _region = [_prefs integerForKey:@"Region"]; - [region selectItemWithTag:_region]; - } - else { - [_prefs setInteger:REGION_AUTODETECT forKey:@"Region"]; - } - - if([_prefs objectForKey:@"Sound Core"]) { - _soundCore = [_prefs integerForKey:@"Sound Core"]; - [soundCore selectItemWithTag:_soundCore]; - } - else { - [_prefs setInteger:SNDCORE_MAC forKey:@"Sound Core"]; - } - - if([_prefs objectForKey:@"Video Core"]) { - _videoCore = [_prefs integerForKey:@"Video Core"]; - [videoCore selectItemWithTag:_videoCore]; - } - else { - [_prefs setInteger:VIDCORE_OGL forKey:@"Video Core"]; - } - - [_prefs synchronize]; -} - -- (void)dealloc -{ - [_prefs release]; - [super dealloc]; -} - -- (void)controlTextDidEndEditing:(NSNotification *)notification -{ - id obj = [notification object]; - - if(obj == biosPath) { - [_prefs setObject:[biosPath stringValue] forKey:@"BIOS Path"]; - } - else if(obj == bramPath) { - [_prefs setObject:[bramPath stringValue] forKey:@"BRAM Path"]; - } - else if(obj == mpegPath) { - [_prefs setObject:[mpegPath stringValue] forKey:@"MPEG ROM Path"]; - } - else if(obj == cartPath) { - [_prefs setObject:[cartPath stringValue] forKey:@"Cartridge Path"]; - } - - [_prefs synchronize]; -} - -- (IBAction)cartSelected:(id)sender -{ - _cartType = [[sender selectedItem] tag]; - - switch(_cartType) { - case CART_NONE: - case CART_DRAM8MBIT: - case CART_DRAM32MBIT: - [cartPath setEnabled:NO]; - [cartPath setStringValue:@""]; - [cartBrowse setEnabled:NO]; - [[cartPath cell] setPlaceholderString: - @"No file required for the selected cartridge"]; - break; - - default: - [cartPath setEnabled:YES]; - [cartBrowse setEnabled:YES]; - [[cartPath cell] setPlaceholderString:@"Not Set"]; - break; - } - - /* Update the preferences file. */ - [_prefs setObject:[cartPath stringValue] forKey:@"Cartridge Path"]; - [_prefs setInteger:_cartType forKey:@"Cartridge Type"]; - [_prefs synchronize]; -} - -- (IBAction)regionSelected:(id)sender -{ - _region = [[sender selectedItem] tag]; - - /* Update the preferences file. */ - [_prefs setInteger:_region forKey:@"Region"]; - [_prefs synchronize]; -} - -- (IBAction)soundCoreSelected:(id)sender -{ - _soundCore = [[sender selectedItem] tag]; - - /* Update the preferences file. */ - [_prefs setInteger:_soundCore forKey:@"Sound Core"]; - [_prefs synchronize]; -} - -- (IBAction)videoCoreSelected:(id)sender -{ - _videoCore = [[sender selectedItem] tag]; - - /* Update the preferences file. */ - [_prefs setInteger:_videoCore forKey:@"Video Core"]; - [_prefs synchronize]; -} - -- (IBAction)biosBrowse:(id)sender -{ - NSOpenPanel *p = [NSOpenPanel openPanel]; - - [p setTitle:@"Select a Saturn BIOS ROM"]; - - if([p runModal] == NSFileHandlingPanelOKButton) { - [biosPath setStringValue:[[[p URLs] objectAtIndex:0] path]]; - - /* Update the preferences file. */ - [_prefs setObject:[biosPath stringValue] forKey:@"BIOS Path"]; - [_prefs synchronize]; - } -} - -- (IBAction)mpegBrowse:(id)sender -{ - NSOpenPanel *p = [NSOpenPanel openPanel]; - - [p setTitle:@"Select a MPEG ROM"]; - - if([p runModal] == NSFileHandlingPanelOKButton) { - [mpegPath setStringValue:[[[p URLs] objectAtIndex:0] path]]; - - /* Update the preferences file. */ - [_prefs setObject:[mpegPath stringValue] forKey:@"MPEG ROM Path"]; - [_prefs synchronize]; - } -} - -- (IBAction)bramBrowse:(id)sender -{ - NSOpenPanel *p = [NSOpenPanel openPanel]; - - [p setTitle:@"Select a BRAM File"]; - - if([p runModal] == NSFileHandlingPanelOKButton) { - [bramPath setStringValue:[[[p URLs] objectAtIndex:0] path]]; - - /* Update the preferences file. */ - [_prefs setObject:[bramPath stringValue] forKey:@"BRAM Path"]; - [_prefs synchronize]; - } -} - -- (IBAction)cartBrowse:(id)sender -{ - NSOpenPanel *p = [NSOpenPanel openPanel]; - - [p setTitle:@"Select the Cartridge File"]; - - if([p runModal] == NSFileHandlingPanelOKButton) { - [cartPath setStringValue:[[[p URLs] objectAtIndex:0] path]]; - - /* Update the preferences file. */ - [_prefs setObject:[cartPath stringValue] forKey:@"Cartridge Path"]; - [_prefs synchronize]; - } -} - -- (IBAction)biosToggle:(id)sender -{ - /* Update the preferences file. */ - [_prefs setBool:([sender state] == NSOnState) forKey:@"Emulate BIOS"]; - [_prefs synchronize]; -} - -- (IBAction)buttonSelect:(id)sender -{ - NSInteger rv; - NSInteger tag = [sender tag]; - int port = tag > 12 ? 1 : 0; - u8 num = tag > 12 ? tag - 13 : tag; - u32 value = PERCocoaGetKey(num, port); - unichar ch; - - /* Fill in current setting from prefs */ - if(value != (u32)-1) { - switch(value) { - case '\r': - ch = 0x23CE; - break; - - case '\t': - ch = 0x21E5; - break; - - case 27: - ch = 0x241B; - break; - - case 127: - ch = 0x232B; - break; - - case NSLeftArrowFunctionKey: - ch = 0x2190; - break; - - case NSUpArrowFunctionKey: - ch = 0x2191; - break; - - case NSRightArrowFunctionKey: - ch = 0x2192; - break; - - case NSDownArrowFunctionKey: - ch = 0x2193; - break; - - default: - ch = toupper(((int)value)); - } - - [buttonBox setStringValue:[NSString stringWithCharacters:&ch length:1]]; - } - else { - [buttonBox setStringValue:@""]; - } - - /* Open up the sheet and ask for the user's input */ - [NSApp beginSheet:buttonAssignment - modalForWindow:prefsPane - modalDelegate:self - didEndSelector:nil - contextInfo:NULL]; - - rv = [NSApp runModalForWindow:buttonAssignment]; - [NSApp endSheet:buttonAssignment]; - [buttonAssignment orderOut:nil]; - - /* Did the user accept what they put in? */ - if(rv == NSOKButton) { - NSString *s = [buttonBox stringValue]; - u32 val; - - /* This shouldn't happen... */ - if([s length] < 1) { - return; - } - - switch([s characterAtIndex:0]) { - case 0x23CE: /* Return */ - val = '\r'; - break; - - case 0x21E5: /* Tab */ - val = '\t'; - break; - - case 0x241B: /* Escape */ - val = 27; - break; - - case 0x232B: /* Backspace */ - val = 127; - break; - - case 0x2190: /* Left */ - val = NSLeftArrowFunctionKey; - break; - - case 0x2191: /* Up */ - val = NSUpArrowFunctionKey; - break; - - case 0x2192: /* Right */ - val = NSRightArrowFunctionKey; - break; - - case 0x2193: /* Down */ - val = NSDownArrowFunctionKey; - break; - - default: - val = tolower([s characterAtIndex:0]); - } - - /* Update the key mapping, if we're already running. This will also save - the key to the preferences. */ - if(tag > 12) { - PERCocoaSetKey(val, tag - 13, 1); - } - else { - PERCocoaSetKey(val, tag, 0); - } - } -} - -- (IBAction)buttonSetOk:(id)sender -{ - [NSApp stopModalWithCode:NSOKButton]; -} - -- (IBAction)buttonSetCancel:(id)sender -{ - [NSApp stopModalWithCode:NSCancelButton]; -} - -- (int)cartType -{ - return _cartType; -} - -- (int)region -{ - return _region; -} - -- (int)soundCore -{ - return _soundCore; -} - -- (int)videoCore -{ - return _videoCore; -} - -- (NSString *)biosPath -{ - return [biosPath stringValue]; -} - -- (BOOL)emulateBios -{ - return [emulateBios state] == NSOnState; -} - -- (NSString *)mpegPath -{ - return [mpegPath stringValue]; -} - -- (NSString *)bramPath -{ - return [bramPath stringValue]; -} - -- (NSString *)cartPath -{ - return [cartPath stringValue]; -} - -@end /* @implementation YabausePrefsController */ diff --git a/yabause/src/cocoa/main.m b/yabause/src/cocoa/main.m deleted file mode 100644 index 56c0be7036..0000000000 --- a/yabause/src/cocoa/main.m +++ /dev/null @@ -1,99 +0,0 @@ -/* Copyright 2010, 2012 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#import -#include - -#include "yui.h" -#include "peripheral.h" -#include "m68kcore.h" -#include "m68kc68k.h" -#include "permacjoy.h" -#include "sndmac.h" -#include "vidogl.h" -#include "vidsoft.h" -#include "vidgcd.h" -#include "cs0.h" -#include "vdp2.h" - -#include "PerCocoa.h" -#include "YabauseController.h" -#include "YabauseGLView.h" - -M68K_struct *M68KCoreList[] = { - &M68KDummy, - &M68KC68K, - NULL -}; - -SH2Interface_struct *SH2CoreList[] = { - &SH2Interpreter, - &SH2DebugInterpreter, - NULL -}; - -PerInterface_struct *PERCoreList[] = { - &PERDummy, - &PERCocoa, - &PERMacJoy, - NULL -}; - -CDInterface *CDCoreList[] = { - &DummyCD, - &ISOCD, - &ArchCD, - NULL -}; - -SoundInterface_struct *SNDCoreList[] = { - &SNDDummy, - &SNDMac, - NULL -}; - -VideoInterface_struct *VIDCoreList[] = { - &VIDDummy, - &VIDOGL, - &VIDSoft, - &VIDGCD, - NULL -}; - -void YuiErrorMsg(const char *string) { - NSString *str = [NSString stringWithUTF8String:string]; - dispatch_async(dispatch_get_main_queue(), ^{ - NSRunAlertPanel(@"Yabause Error", str, @"OK", NULL, NULL); - }); -} - -void YuiSetVideoAttribute(int type, int val) { -} - -int YuiSetVideoMode(int width, int height, int bpp, int fullscreen) { - return 0; -} - -void YuiSwapBuffers(void) { - [[controller view] setNeedsDisplay:YES]; -} - -int main(int argc, char *argv[]) { - return NSApplicationMain(argc, (const char **) argv); -} diff --git a/yabause/src/cocoa/resources/controller.png b/yabause/src/cocoa/resources/controller.png deleted file mode 100644 index 88e2a4344b..0000000000 Binary files a/yabause/src/cocoa/resources/controller.png and /dev/null differ diff --git a/yabause/src/cocoa/vidgcd.c b/yabause/src/cocoa/vidgcd.c deleted file mode 100644 index 311f987123..0000000000 --- a/yabause/src/cocoa/vidgcd.c +++ /dev/null @@ -1,3274 +0,0 @@ -/* Copyright 2003-2004 Guillaume Duhamel - Copyright 2004-2008 Theo Berkau - Copyright 2006 Fabien Coulon - Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "vidgcd.h" -#include "vidshared.h" -#include "debug.h" -#include "vdp2.h" - -#ifdef HAVE_LIBGL -#define USE_OPENGL -#endif - -#ifdef USE_OPENGL -#include "ygl.h" -#endif - -#include "yui.h" - -#include -#include -#include - -#if defined WORDS_BIGENDIAN -static INLINE u32 COLSAT2YAB16(int priority,u32 temp) { return (priority | (temp & 0x7C00) << 1 | (temp & 0x3E0) << 14 | (temp & 0x1F) << 27); } -static INLINE u32 COLSAT2YAB32(int priority,u32 temp) { return (((temp & 0xFF) << 24) | ((temp & 0xFF00) << 8) | ((temp & 0xFF0000) >> 8) | priority); } -static INLINE u32 COLSAT2YAB32_2(int priority,u32 temp1,u32 temp2) { return (((temp2 & 0xFF) << 24) | ((temp2 & 0xFF00) << 8) | ((temp1 & 0xFF) << 8) | priority); } -static INLINE u32 COLSATSTRIPPRIORITY(u32 pixel) { return (pixel | 0xFF); } -#else -static INLINE u32 COLSAT2YAB16(int priority,u32 temp) { return (priority << 24 | (temp & 0x1F) << 3 | (temp & 0x3E0) << 6 | (temp & 0x7C00) << 9); } -static INLINE u32 COLSAT2YAB32(int priority, u32 temp) { return (priority << 24 | (temp & 0xFF0000) | (temp & 0xFF00) | (temp & 0xFF)); } -static INLINE u32 COLSAT2YAB32_2(int priority,u32 temp1,u32 temp2) { return (priority << 24 | ((temp1 & 0xFF) << 16) | (temp2 & 0xFF00) | (temp2 & 0xFF)); } -static INLINE u32 COLSATSTRIPPRIORITY(u32 pixel) { return (0xFF000000 | pixel); } -#endif - -#define COLOR_ADDt(b) (b>0xFF?0xFF:(b<0?0:b)) -#define COLOR_ADDb(b1,b2) COLOR_ADDt((signed) (b1) + (b2)) -#ifdef WORDS_BIGENDIAN -#define COLOR_ADD(l,r,g,b) (COLOR_ADDb(l & 0xFF, r) << 24) | \ - (COLOR_ADDb((l >> 8) & 0xFF, g) << 16) | \ - (COLOR_ADDb((l >> 16) & 0xFF, b) << 8) | \ - ((l >> 24) & 0xFF) -#else -#define COLOR_ADD(l,r,g,b) COLOR_ADDb((l & 0xFF), r) | \ - (COLOR_ADDb((l >> 8) & 0xFF, g) << 8) | \ - (COLOR_ADDb((l >> 16) & 0xFF, b) << 16) | \ - (l & 0xFF000000) -#endif - -static void PushUserClipping(int mode); -static void PopUserClipping(void); - -int VIDGCDInit(void); -void VIDGCDDeInit(void); -void VIDGCDResize(unsigned int, unsigned int, int); -int VIDGCDIsFullscreen(void); -int VIDGCDVdp1Reset(void); -void VIDGCDVdp1DrawStart(void); -void VIDGCDVdp1DrawEnd(void); -void VIDGCDVdp1NormalSpriteDraw(void); -void VIDGCDVdp1ScaledSpriteDraw(void); -void VIDGCDVdp1DistortedSpriteDraw(void); -void VIDGCDVdp1PolygonDraw(void); -void VIDGCDVdp1PolylineDraw(void); -void VIDGCDVdp1LineDraw(void); -void VIDGCDVdp1UserClipping(void); -void VIDGCDVdp1SystemClipping(void); -void VIDGCDVdp1LocalCoordinate(void); -int VIDGCDVdp2Reset(void); -void VIDGCDVdp2DrawStart(void); -void VIDGCDVdp2DrawEnd(void); -void VIDGCDVdp2DrawScreens(void); -void VIDGCDVdp2SetResolution(u16 TVMD); -void FASTCALL VIDGCDVdp2SetPriorityNBG0(int priority); -void FASTCALL VIDGCDVdp2SetPriorityNBG1(int priority); -void FASTCALL VIDGCDVdp2SetPriorityNBG2(int priority); -void FASTCALL VIDGCDVdp2SetPriorityNBG3(int priority); -void FASTCALL VIDGCDVdp2SetPriorityRBG0(int priority); -void VIDGCDOnScreenDebugMessage(char *string, ...); -void VIDGCDGetGlSize(int *width, int *height); -void VIDGCDVdp1SwapFrameBuffer(void); -void VIDGCDVdp1EraseFrameBuffer(void); - -VideoInterface_struct VIDGCD = { -VIDCORE_GCD, -"Grand Central Dispatch Software Video Interface", -VIDGCDInit, -VIDGCDDeInit, -VIDGCDResize, -VIDGCDIsFullscreen, -VIDGCDVdp1Reset, -VIDGCDVdp1DrawStart, -VIDGCDVdp1DrawEnd, -VIDGCDVdp1NormalSpriteDraw, -VIDGCDVdp1ScaledSpriteDraw, -VIDGCDVdp1DistortedSpriteDraw, -//for the actual hardware, polygons are essentially identical to distorted sprites -//the actual hardware draws using diagonal lines, which is why using half-transparent processing -//on distorted sprites and polygons is not recommended since the hardware overdraws to prevent gaps -//thus, with half-transparent processing some pixels will be processed more than once, producing moire patterns in the drawn shapes -VIDGCDVdp1DistortedSpriteDraw, -VIDGCDVdp1PolylineDraw, -VIDGCDVdp1LineDraw, -VIDGCDVdp1UserClipping, -VIDGCDVdp1SystemClipping, -VIDGCDVdp1LocalCoordinate, -VIDGCDVdp2Reset, -VIDGCDVdp2DrawStart, -VIDGCDVdp2DrawEnd, -VIDGCDVdp2DrawScreens, -VIDGCDVdp2SetResolution, -VIDGCDVdp2SetPriorityNBG0, -VIDGCDVdp2SetPriorityNBG1, -VIDGCDVdp2SetPriorityNBG2, -VIDGCDVdp2SetPriorityNBG3, -VIDGCDVdp2SetPriorityRBG0, -VIDGCDOnScreenDebugMessage, -VIDGCDGetGlSize, -}; - -static u32 *dispbuffer=NULL; -static u8 *vdp1framebuffer[2]= { NULL, NULL }; -static u8 *vdp1frontframebuffer; -static u8 *vdp1backframebuffer; -static u32 *vdp2framebuffer=NULL; - -static int vdp1width; -static int vdp1height; -static int vdp1clipxstart; -static int vdp1clipxend; -static int vdp1clipystart; -static int vdp1clipyend; -static int vdp1pixelsize; -static int vdp1spritetype; -int vdp2width; -int vdp2height; -static int nbg0priority=0; -static int nbg1priority=0; -static int nbg2priority=0; -static int nbg3priority=0; -static int rbg0priority=0; -#ifdef USE_OPENGL -static int outputwidth; -static int outputheight; -#endif -static int resxratio; -static int resyratio; - -static char message[512]; -static int msglength; - -typedef struct { s16 x; s16 y; } vdp1vertex; - -typedef struct -{ - int pagepixelwh, pagepixelwh_bits, pagepixelwh_mask; - int planepixelwidth, planepixelwidth_bits, planepixelwidth_mask; - int planepixelheight, planepixelheight_bits, planepixelheight_mask; - int screenwidth; - int screenheight; - int oldcellx, oldcelly, oldcellcheck; - int xmask, ymask; - u32 planetbl[16]; -} screeninfo_struct; - -struct { - vdp2draw_struct info; - u8 prioritytable[8]; - u32 coloroffset; - int islinewindow; - clipping_struct clip[2]; - u32 linewnd0addr, linewnd1addr; - int priosused[8]; -} vdp1draw_info; - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void vdp2putpixel32(s32 x, s32 y, u32 color, int priority) -{ - vdp2framebuffer[(y * vdp2width) + x] = COLSAT2YAB32(priority, color); -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE u8 Vdp2GetPixelPriority(u32 pixel) -{ -#if defined WORDS_BIGENDIAN - return pixel; -#else - return pixel >> 24; -#endif -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void puthline16(s32 x, s32 y, s32 width, u16 color, int priority) -{ - u32 *buffer = vdp2framebuffer + (y * vdp2width) + x; - u32 dot=COLSAT2YAB16(priority, color); - int i; - - for (i = 0; i < width; i++) - buffer[i] = dot; -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE u32 FASTCALL Vdp2ColorRamGetColor(u32 addr) -{ - switch(Vdp2Internal.ColorMode) - { - case 0: - { - u32 tmp; - addr <<= 1; - tmp = T2ReadWord(Vdp2ColorRam, addr & 0xFFF); - return (((tmp & 0x1F) << 3) | ((tmp & 0x03E0) << 6) | ((tmp & 0x7C00) << 9)); - } - case 1: - { - u32 tmp; - addr <<= 1; - tmp = T2ReadWord(Vdp2ColorRam, addr & 0xFFF); - return (((tmp & 0x1F) << 3) | ((tmp & 0x03E0) << 6) | ((tmp & 0x7C00) << 9)); - } - case 2: - { - addr <<= 2; - return T2ReadLong(Vdp2ColorRam, addr & 0xFFF); - } - default: break; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void Vdp2PatternAddr(vdp2draw_struct *info) -{ - switch(info->patterndatasize) - { - case 1: - { - u16 tmp = T1ReadWord(Vdp2Ram, info->addr); - - info->addr += 2; - info->specialfunction = (info->supplementdata >> 9) & 0x1; - - switch(info->colornumber) - { - case 0: // in 16 colors - info->paladdr = ((tmp & 0xF000) >> 8) | ((info->supplementdata & 0xE0) << 3); - break; - default: // not in 16 colors - info->paladdr = (tmp & 0x7000) >> 4; - break; - } - - switch(info->auxmode) - { - case 0: - info->flipfunction = (tmp & 0xC00) >> 10; - - switch(info->patternwh) - { - case 1: - info->charaddr = (tmp & 0x3FF) | ((info->supplementdata & 0x1F) << 10); - break; - case 2: - info->charaddr = ((tmp & 0x3FF) << 2) | (info->supplementdata & 0x3) | ((info->supplementdata & 0x1C) << 10); - break; - } - break; - case 1: - info->flipfunction = 0; - - switch(info->patternwh) - { - case 1: - info->charaddr = (tmp & 0xFFF) | ((info->supplementdata & 0x1C) << 10); - break; - case 2: - info->charaddr = ((tmp & 0xFFF) << 2) | (info->supplementdata & 0x3) | ((info->supplementdata & 0x10) << 10); - break; - } - break; - } - - break; - } - case 2: { - u16 tmp1 = T1ReadWord(Vdp2Ram, info->addr); - u16 tmp2 = T1ReadWord(Vdp2Ram, info->addr+2); - info->addr += 4; - info->charaddr = tmp2 & 0x7FFF; - info->flipfunction = (tmp1 & 0xC000) >> 14; - info->paladdr = (tmp1 & 0x7F) << 4; - info->specialfunction = (tmp1 & 0x2000) >> 13; - break; - } - } - - if (!(Vdp2Regs->VRSIZE & 0x8000)) - info->charaddr &= 0x3FFF; - - info->charaddr *= 0x20; // selon Runik - if (info->specialprimode == 1) { - info->priority = (info->priority & 0xE) | (info->specialfunction & 1); - } -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE u32 FASTCALL DoNothing(UNUSED void *info, u32 pixel) -{ - return pixel; -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE u32 FASTCALL DoColorOffset(void *info, u32 pixel) -{ - return COLOR_ADD(pixel, ((vdp2draw_struct *)info)->cor, - ((vdp2draw_struct *)info)->cog, - ((vdp2draw_struct *)info)->cob); -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE u32 FASTCALL DoColorCalc(void *info, u32 pixel) -{ -#if 0 - u8 oldr, oldg, oldb; - u8 r, g, b; - u32 oldpixel = 0x00FFFFFF; // fix me - - static int topratio[32] = { - 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, - 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 - }; - static int bottomratio[32] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 - }; - - // separate color components for top and second pixel - r = (pixel & 0xFF) * topratio[((vdp2draw_struct *)info)->alpha] >> 5; - g = ((pixel >> 8) & 0xFF) * topratio[((vdp2draw_struct *)info)->alpha] >> 5; - b = ((pixel >> 16) & 0xFF) * topratio[((vdp2draw_struct *)info)->alpha] >> 5; - -#ifdef WORDS_BIGENDIAN - oldr = ((oldpixel >> 24) & 0xFF) * bottomratio[((vdp2draw_struct *)info)->alpha] >> 5; - oldg = ((oldpixel >> 16) & 0xFF) * bottomratio[((vdp2draw_struct *)info)->alpha] >> 5; - oldb = ((oldpixel >> 8) & 0xFF) * bottomratio[((vdp2draw_struct *)info)->alpha] >> 5; -#else - oldr = (oldpixel & 0xFF) * bottomratio[((vdp2draw_struct *)info)->alpha] >> 5; - oldg = ((oldpixel >> 8) & 0xFF) * bottomratio[((vdp2draw_struct *)info)->alpha] >> 5; - oldb = ((oldpixel >> 16) & 0xFF) * bottomratio[((vdp2draw_struct *)info)->alpha] >> 5; -#endif - - // add color components and reform the pixel - pixel = ((b + oldb) << 16) | ((g + oldg) << 8) | (r + oldr); -#endif - return pixel; -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE u32 FASTCALL DoColorCalcWithColorOffset(void *info, u32 pixel) -{ - pixel = DoColorCalc(info, pixel); - - return COLOR_ADD(pixel, ((vdp2draw_struct *)info)->cor, - ((vdp2draw_struct *)info)->cog, - ((vdp2draw_struct *)info)->cob); -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void ReadVdp2ColorOffset(vdp2draw_struct *info, int clofmask, int ccmask) -{ - if (Vdp2Regs->CLOFEN & clofmask) - { - // color offset enable - if (Vdp2Regs->CLOFSL & clofmask) - { - // color offset B - info->cor = Vdp2Regs->COBR & 0xFF; - if (Vdp2Regs->COBR & 0x100) - info->cor |= 0xFFFFFF00; - - info->cog = Vdp2Regs->COBG & 0xFF; - if (Vdp2Regs->COBG & 0x100) - info->cog |= 0xFFFFFF00; - - info->cob = Vdp2Regs->COBB & 0xFF; - if (Vdp2Regs->COBB & 0x100) - info->cob |= 0xFFFFFF00; - } - else - { - // color offset A - info->cor = Vdp2Regs->COAR & 0xFF; - if (Vdp2Regs->COAR & 0x100) - info->cor |= 0xFFFFFF00; - - info->cog = Vdp2Regs->COAG & 0xFF; - if (Vdp2Regs->COAG & 0x100) - info->cog |= 0xFFFFFF00; - - info->cob = Vdp2Regs->COAB & 0xFF; - if (Vdp2Regs->COAB & 0x100) - info->cob |= 0xFFFFFF00; - } - - if (info->cor == 0 && info->cog == 0 && info->cob == 0) - { - if (Vdp2Regs->CCCTL & ccmask) - info->PostPixelFetchCalc = &DoColorCalc; - else - info->PostPixelFetchCalc = &DoNothing; - } - else - { - if (Vdp2Regs->CCCTL & ccmask) - info->PostPixelFetchCalc = &DoColorCalcWithColorOffset; - else - info->PostPixelFetchCalc = &DoColorOffset; - } - } - else // color offset disable - { - if (Vdp2Regs->CCCTL & ccmask) - info->PostPixelFetchCalc = &DoColorCalc; - else - info->PostPixelFetchCalc = &DoNothing; - } - -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE int Vdp2FetchPixel(vdp2draw_struct *info, int x, int y, u32 *color) -{ - u32 dot; - - switch(info->colornumber) - { - case 0: // 4 BPP - dot = T1ReadByte(Vdp2Ram, ((info->charaddr + ((y * info->cellw) + x) / 2) & 0x7FFFF)); - if (!(x & 0x1)) dot >>= 4; - if (!(dot & 0xF) && info->transparencyenable) return 0; - else - { - *color = Vdp2ColorRamGetColor(info->coloroffset + (info->paladdr | (dot & 0xF))); - return 1; - } - case 1: // 8 BPP - dot = T1ReadByte(Vdp2Ram, ((info->charaddr + (y * info->cellw) + x) & 0x7FFFF)); - if (!(dot & 0xFF) && info->transparencyenable) return 0; - else - { - *color = Vdp2ColorRamGetColor(info->coloroffset + (info->paladdr | (dot & 0xFF))); - return 1; - } - case 2: // 16 BPP(palette) - dot = T1ReadWord(Vdp2Ram, ((info->charaddr + ((y * info->cellw) + x) * 2) & 0x7FFFF)); - if ((dot == 0) && info->transparencyenable) return 0; - else - { - *color = Vdp2ColorRamGetColor(info->coloroffset + dot); - return 1; - } - case 3: // 16 BPP(RGB) - dot = T1ReadWord(Vdp2Ram, ((info->charaddr + ((y * info->cellw) + x) * 2) & 0x7FFFF)); - if (!(dot & 0x8000) && info->transparencyenable) return 0; - else - { - *color = COLSAT2YAB16(0, dot); - return 1; - } - case 4: // 32 BPP - dot = T1ReadLong(Vdp2Ram, ((info->charaddr + ((y * info->cellw) + x) * 4) & 0x7FFFF)); - if (!(dot & 0x80000000) && info->transparencyenable) return 0; - else - { - *color = COLSAT2YAB32(0, dot); - return 1; - } - default: - return 0; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE int TestWindow(int wctl, int enablemask, int inoutmask, clipping_struct *clip, int x, int y) -{ - if (wctl & enablemask) - { - if (wctl & inoutmask) - { - // Draw inside of window - if (x < clip->xstart || x > clip->xend || - y < clip->ystart || y > clip->yend) - return 0; - } - else - { - // Draw outside of window - if (x >= clip->xstart && x <= clip->xend && - y >= clip->ystart && y <= clip->yend) - return 0; - - //it seems to overflow vertically on hardware - if(clip->yend > vdp2height && (x >= clip->xstart && x <= clip->xend )) - return 0; - } - } - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void GeneratePlaneAddrTable(vdp2draw_struct *info, u32 *planetbl) -{ - int i; - - for (i = 0; i < (info->mapwh*info->mapwh); i++) - { - info->PlaneAddr(info, i); - planetbl[i] = info->addr; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void FASTCALL Vdp2MapCalcXY(vdp2draw_struct *info, int *x, int *y, - screeninfo_struct *sinfo) -{ - int planenum; - const int pagesize_bits=info->pagewh_bits*2; - const int cellwh=(2 + info->patternwh); - - const int check = ((y[0] >> cellwh) << 16) | (x[0] >> cellwh); - //if ((x[0] >> cellwh) != sinfo->oldcellx || (y[0] >> cellwh) != sinfo->oldcelly) - if(check != sinfo->oldcellcheck) - { - sinfo->oldcellx = x[0] >> cellwh; - sinfo->oldcelly = y[0] >> cellwh; - sinfo->oldcellcheck = (sinfo->oldcelly << 16) | sinfo->oldcellx; - - // Calculate which plane we're dealing with - planenum = ((y[0] >> sinfo->planepixelheight_bits) * info->mapwh) + (x[0] >> sinfo->planepixelwidth_bits); - x[0] = (x[0] & sinfo->planepixelwidth_mask); - y[0] = (y[0] & sinfo->planepixelheight_mask); - - // Fetch and decode pattern name data - info->addr = sinfo->planetbl[planenum]; - - // Figure out which page it's on(if plane size is not 1x1) - info->addr += (( ((y[0] >> sinfo->pagepixelwh_bits) << pagesize_bits) << info->planew_bits) + - ( (x[0] >> sinfo->pagepixelwh_bits) << pagesize_bits) + - (((y[0] & sinfo->pagepixelwh_mask) >> cellwh) << info->pagewh_bits) + - ((x[0] & sinfo->pagepixelwh_mask) >> cellwh)) << (info->patterndatasize_bits+1); - - Vdp2PatternAddr(info); // Heh, this could be optimized - } - - // Figure out which pixel in the tile we want - if (info->patternwh == 1) - { - x[0] &= 8-1; - y[0] &= 8-1; - - switch(info->flipfunction & 0x3) - { - case 0: //none - break; - case 1: //horizontal flip - x[0] = 8 - 1 - x[0]; - break; - case 2: // vertical flip - y[0] = 8 - 1 - y[0]; - break; - case 3: //flip both - x[0] = 8 - 1 - x[0]; - y[0] = 8 - 1 - y[0]; - break; - } - } - else - { - if (info->flipfunction) - { - y[0] &= 16 - 1; - if (info->flipfunction & 0x2) - { - if (!(y[0] & 8)) - y[0] = 8 - 1 - y[0] + 16; - else - y[0] = 16 - 1 - y[0]; - } - else if (y[0] & 8) - y[0] += 8; - - if (info->flipfunction & 0x1) - { - if (!(x[0] & 8)) - y[0] += 8; - - x[0] &= 8-1; - x[0] = 8 - 1 - x[0]; - } - else if (x[0] & 8) - { - y[0] += 8; - x[0] &= 8-1; - } - else - x[0] &= 8-1; - } - else - { - y[0] &= 16 - 1; - - if (y[0] & 8) - y[0] += 8; - if (x[0] & 8) - y[0] += 8; - x[0] &= 8-1; - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void SetupScreenVars(vdp2draw_struct *info, screeninfo_struct *sinfo) -{ - if (!info->isbitmap) - { - sinfo->pagepixelwh=64*8; - sinfo->pagepixelwh_bits = 9; - sinfo->pagepixelwh_mask = 511; - - sinfo->planepixelwidth=info->planew*sinfo->pagepixelwh; - sinfo->planepixelwidth_bits = 8+info->planew; - sinfo->planepixelwidth_mask = (1<<(sinfo->planepixelwidth_bits))-1; - - sinfo->planepixelheight=info->planeh*sinfo->pagepixelwh; - sinfo->planepixelheight_bits = 8+info->planeh; - sinfo->planepixelheight_mask = (1<<(sinfo->planepixelheight_bits))-1; - - sinfo->screenwidth=info->mapwh*sinfo->planepixelwidth; - sinfo->screenheight=info->mapwh*sinfo->planepixelheight; - sinfo->oldcellx=-1; - sinfo->oldcelly=-1; - sinfo->xmask = sinfo->screenwidth-1; - sinfo->ymask = sinfo->screenheight-1; - GeneratePlaneAddrTable(info, sinfo->planetbl); - } - else - { - sinfo->pagepixelwh = 0; - sinfo->pagepixelwh_bits = 0; - sinfo->pagepixelwh_mask = 0; - sinfo->planepixelwidth=0; - sinfo->planepixelwidth_bits=0; - sinfo->planepixelwidth_mask=0; - sinfo->planepixelheight=0; - sinfo->planepixelheight_bits=0; - sinfo->planepixelheight_mask=0; - sinfo->screenwidth=0; - sinfo->screenheight=0; - sinfo->oldcellx=0; - sinfo->oldcelly=0; - sinfo->oldcellcheck=0; - sinfo->xmask = info->cellw-1; - sinfo->ymask = info->cellh-1; - } -} - -////////////////////////////////////////////////////////////////////////////// - -/* FIXME: This function will not work on Big Endian systems. Since its only here - in vidgcd, and the only thing that this vidcore will work on right now is - Mac OS X 10.6 (which is only available for Little Endian systems), its ok for - the time being... */ -static INLINE u32 FASTCALL Vdp2Blend(vdp2draw_struct *info, u32 src, u32 dst) { - u32 alpha, s1, s2, d1, d2, o1, o2, pri; - - pri = Vdp2GetPixelPriority(dst); - - /* If we're not doing color calculation on this plane, then there's no need - to do any blending... */ - if(info->PostPixelFetchCalc != &DoColorCalc && - info->PostPixelFetchCalc != &DoColorCalcWithColorOffset) { - /* If the old pixel is of higher priority, use it. */ - if(pri > info->priority) { - return dst; - } - - return src; - } - - if(pri < info->priority) { - pri = info->priority; - } - - alpha = 255 - (((info->alpha) << 3) + 0x07); - - /* Magic alpha blending! */ - s1 = src & 0x00FF00FF; - s2 = src & 0x0000FF00; - d1 = dst & 0x00FF00FF; - d2 = dst & 0x0000FF00; - - o1 = (d1 + (((s1 - d1) * alpha) >> 8)) & 0x00FF00FF; - o2 = (d2 + (((s2 - d2) * alpha) >> 8)) & 0x0000FF00; - - return o1 | o2 | (pri << 24); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL GCDVdp2DrawScroll(vdp2draw_struct *_info, u32 *_textdata, int width, int height) -{ - int i, j; - clipping_struct _clip[2], _clip1, _clip2; - u32 _linewnd0addr, _linewnd1addr; - screeninfo_struct _sinfo; - int scrollx, scrolly; - int *mosaic_y, *mosaic_x; - int linescrollmult = (_info->islinescroll & 1) + - ((_info->islinescroll & 2) >> 1) + ((_info->islinescroll & 4) >> 2); - - _info->coordincx *= (float)resxratio; - _info->coordincy *= (float)resyratio; - - SetupScreenVars(_info, &_sinfo); - - scrollx = _info->x; - scrolly = _info->y; - - _clip[0].xstart = _clip[0].ystart = _clip[0].xend = _clip[0].yend = 0; - _clip[1].xstart = _clip[1].ystart = _clip[1].xend = _clip[1].yend = 0; - ReadWindowData(_info->wctl, _clip); - _clip1 = _clip[0]; - _clip2 = _clip[1]; - _linewnd0addr = _linewnd1addr = 0; - ReadLineWindowData(&_info->islinewindow, _info->wctl, &_linewnd0addr, &_linewnd1addr); - - { - static int tables_initialized = 0; - static int mosaic_table[16][1024]; - if(!tables_initialized) - { - tables_initialized = 1; - for(i=0;i<16;i++) - { - int m = i+1; - for(j=0;j<1024;j++) - mosaic_table[i][j] = j/m*m; - } - } - mosaic_x = mosaic_table[_info->mosaicxmask-1]; - mosaic_y = mosaic_table[_info->mosaicymask-1]; - } - - dispatch_apply(height, dispatch_get_global_queue(2, 0), ^(size_t j) { - int x, y, i; - u32 *textdata = _textdata + (j * width); - u32 linewnd0addr = _linewnd0addr, linewnd1addr = _linewnd1addr; - screeninfo_struct sinfo = _sinfo; - clipping_struct clip[2] = { _clip1, _clip2 }; - vdp2draw_struct inf = *_info; - vdp2draw_struct *info = &inf; - int Y; - int linescrollx = 0; - - // if line window is enabled, adjust clipping values - if(info->islinewindow) { - // Fetch new xstart and xend values from table - if (info->islinewindow & 0x1) - { - // Window 0 - linewnd0addr = _linewnd0addr + j * 4; - clip[0].xstart = (T1ReadWord(Vdp2Ram, linewnd0addr) & 0x3FF) >> 1; // fix me - linewnd0addr += 2; - clip[0].xend = (T1ReadWord(Vdp2Ram, linewnd0addr) & 0x3FF) >> 1; // fix me - } - if (info->islinewindow & 0x2) - { - // Window 1 - linewnd1addr = _linewnd1addr + j * 4; - clip[1].xstart = (T1ReadWord(Vdp2Ram, linewnd1addr) & 0x3FF) >> 1; // fix me - linewnd1addr += 2; - clip[1].xend = (T1ReadWord(Vdp2Ram, linewnd1addr) & 0x3FF) >> 1; // fix me - } - } - - // precalculate the coordinate for the line(it's faster) and do line - // scroll - if (info->islinescroll) - { - /* Figure out where we actually are in the line scroll table. */ - info->linescrolltbl += linescrollmult * (j << 2); - - if (info->islinescroll & 0x1) - { - linescrollx = (T1ReadLong(Vdp2Ram, info->linescrolltbl) >> 16) & 0x7FF; - info->linescrolltbl += 4; - } - if (info->islinescroll & 0x2) - { - info->y = (T1ReadWord(Vdp2Ram, info->linescrolltbl) & 0x7FF) + scrolly; - info->linescrolltbl += 4; - y = info->y; - } - else - //y = info->y+((int)(info->coordincy *(float)(info->mosaicymask > 1 ? (j / info->mosaicymask * info->mosaicymask) : j))); - y = info->y + info->coordincy*mosaic_y[j]; - if (info->islinescroll & 0x4) - { - info->coordincx = (T1ReadLong(Vdp2Ram, info->linescrolltbl) & 0x7FF00) / (float)65536.0; - info->linescrolltbl += 4; - } - } - else - //y = info->y+((int)(info->coordincy *(float)(info->mosaicymask > 1 ? (j / info->mosaicymask * info->mosaicymask) : j))); - y = info->y + info->coordincy * mosaic_y[j]; - - y &= sinfo.ymask; - - if (info->isverticalscroll) - { - // this is *wrong*, vertical scroll use a different value per cell - // info->verticalscrolltbl should be incremented by info->verticalscrollinc - // each time there's a cell change and reseted at the end of the line... - // or something like that :) - y += T1ReadLong(Vdp2Ram, info->verticalscrolltbl) >> 16; - y &= 0x1FF; - } - - Y=y; - - for (i = 0; i < width; i++) - { - u32 color; - - // See if screen position is clipped, if it isn't, continue - // AND window logic - if(!TestWindow(info->wctl, 0x2, 0x1, &clip[0], i, j) && !TestWindow(info->wctl, 0x8, 0x4, &clip[1], i, j) && (info->wctl & 0x80) == 0x80) - { - textdata++; - continue; - } - //OR window logic - else if ((info->wctl & 0x80) == 0) - { - if (!TestWindow(info->wctl, 0x2, 0x1, &clip[0], i, j)) - { - textdata++; - continue; - } - - // Window 1 - if (!TestWindow(info->wctl, 0x8, 0x4, &clip[1], i,j)) - { - textdata++; - continue; - } - } - - //x = info->x+((int)(info->coordincx*(float)((info->mosaicxmask > 1) ? (i / info->mosaicxmask * info->mosaicxmask) : i))); - x = info->x + mosaic_x[i]*info->coordincx; - x &= sinfo.xmask; - - if (linescrollx) { - x += linescrollx; - x &= 0x3FF; - } - - if (!info->isbitmap) - { - // Tile - y=Y; - // need to calculate this without history! - Vdp2MapCalcXY(info, &x, &y, &sinfo); - } - - // If priority of screen is less than current top pixel and per - // pixel priority isn't used, skip it -#ifndef CRAB_REWRITE - if (Vdp2GetPixelPriority(textdata[0]) > info->priority) - { - textdata++; - continue; - } -#endif - - // Fetch Pixel, if it isn't transparent, continue - if (!Vdp2FetchPixel(info, x, y, &color)) - { - textdata++; - continue; - } - - // check special priority somewhere here - - // Apply color offset and color calculation/special color calculation - // and then continue. - // We almost need to know well ahead of time what the top - // and second pixel is in order to work this. - -#ifndef CRAB_REWRITE - textdata[0] = COLSAT2YAB32(info->priority, info->PostPixelFetchCalc(info, color)); - textdata++; -#else - color = COLSAT2YAB32(info->priority, info->PostPixelFetchCalc(info, color)); - *textdata++ = Vdp2Blend(info, color, *textdata); -#endif - } - }); -} - -////////////////////////////////////////////////////////////////////////////// - -static void SetupRotationInfo(vdp2draw_struct *info, vdp2rotationparameterfp_struct *p) -{ - if (info->rotatenum == 0) - { - Vdp2ReadRotationTableFP(0, p); - info->PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2ParameterAPlaneAddr; - } - else - { - Vdp2ReadRotationTableFP(1, &p[1]); - info->PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2ParameterBPlaneAddr; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL Vdp2DrawRotationFP(vdp2draw_struct *info, vdp2rotationparameterfp_struct *parameter) -{ - int i, j; - int x, y; - screeninfo_struct sinfo; - vdp2rotationparameterfp_struct *p=¶meter[info->rotatenum]; - - SetupRotationInfo(info, parameter); - - if (!p->coefenab) - { - fixed32 xmul, ymul, C, F; - - // Since coefficients aren't being used, we can simplify the drawing process - if (IsScreenRotatedFP(p)) - { - // No rotation - info->x = touint(mulfixed(p->kx, (p->Xst - p->Px)) + p->Px + p->Mx); - info->y = touint(mulfixed(p->ky, (p->Yst - p->Py)) + p->Py + p->My); - info->coordincx = tofloat(p->kx); - info->coordincy = tofloat(p->ky); - } - else - { - u32 *textdata=vdp2framebuffer; - - GenerateRotatedVarFP(p, &xmul, &ymul, &C, &F); - - // Do simple rotation - CalculateRotationValuesFP(p); - - SetupScreenVars(info, &sinfo); - - for (j = 0; j < vdp2height; j++) - { - for (i = 0; i < vdp2width; i++) - { - u32 color; - - x = GenerateRotatedXPosFP(p, i, xmul, ymul, C) & sinfo.xmask; - y = GenerateRotatedYPosFP(p, i, xmul, ymul, F) & sinfo.ymask; - xmul += p->deltaXst; - - // Convert coordinates into graphics - if (!info->isbitmap) - { - // Tile - Vdp2MapCalcXY(info, &x, &y, &sinfo); - } - - // If priority of screen is less than current top pixel and per - // pixel priority isn't used, skip it - if (Vdp2GetPixelPriority(textdata[0]) > info->priority) - { - textdata++; - continue; - } - - // Fetch pixel - if (!Vdp2FetchPixel(info, x, y, &color)) - { - textdata++; - continue; - } - - textdata[0] = COLSAT2YAB32(info->priority, info->PostPixelFetchCalc(info, color)); - textdata++; - } - ymul += p->deltaYst; - } - - return; - } - } - else - { - fixed32 xmul, ymul, C, F; - fixed32 coefx, coefy; - u32 *textdata=vdp2framebuffer; - - GenerateRotatedVarFP(p, &xmul, &ymul, &C, &F); - - // Rotation using Coefficient Tables(now this stuff just gets wacky. It - // has to be done in software, no exceptions) - CalculateRotationValuesFP(p); - - SetupScreenVars(info, &sinfo); - coefx = coefy = 0; - - for (j = 0; j < vdp2height; j++) - { - if (p->deltaKAx == 0) - { - Vdp2ReadCoefficientFP(p, - p->coeftbladdr + - touint(coefy) * - p->coefdatasize); - } - - for (i = 0; i < vdp2width; i++) - { - u32 color; - - if (p->deltaKAx != 0) - { - Vdp2ReadCoefficientFP(p, - p->coeftbladdr + - toint(coefy + coefx) * - p->coefdatasize); - coefx += p->deltaKAx; - } - - if (p->msb) - { - textdata++; - continue; - } - - x = GenerateRotatedXPosFP(p, i, xmul, ymul, C) & sinfo.xmask; - y = GenerateRotatedYPosFP(p, i, xmul, ymul, F) & sinfo.ymask; - xmul += p->deltaXst; - - // Convert coordinates into graphics - if (!info->isbitmap) - { - // Tile - Vdp2MapCalcXY(info, &x, &y, &sinfo); - } - - // If priority of screen is less than current top pixel and per - // pixel priority isn't used, skip it - if (Vdp2GetPixelPriority(textdata[0]) > info->priority) - { - textdata++; - continue; - } - - // Fetch pixel - if (!Vdp2FetchPixel(info, x, y, &color)) - { - textdata++; - continue; - } - - textdata[0] = COLSAT2YAB32(info->priority, info->PostPixelFetchCalc(info, color)); - textdata++; - } - ymul += p->deltaYst; - coefx = 0; - coefy += p->deltaKAst; - } - return; - } - - GCDVdp2DrawScroll(info, vdp2framebuffer, vdp2width, vdp2height); -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawBackScreen(void) -{ - int i; - - // Only draw black if TVMD's DISP and BDCLMD bits are cleared - if ((Vdp2Regs->TVMD & 0x8000) == 0 && (Vdp2Regs->TVMD & 0x100) == 0) - { - // Draw Black - for (i = 0; i < (vdp2width * vdp2height); i++) - vdp2framebuffer[i] = 0; - } - else - { - // Draw Back Screen - u32 scrAddr; - u16 dot; - - if (Vdp2Regs->VRSIZE & 0x8000) - scrAddr = (((Vdp2Regs->BKTAU & 0x7) << 16) | Vdp2Regs->BKTAL) * 2; - else - scrAddr = (((Vdp2Regs->BKTAU & 0x3) << 16) | Vdp2Regs->BKTAL) * 2; - - if (Vdp2Regs->BKTAU & 0x8000) - { - // Per Line - for (i = 0; i < vdp2height; i++) - { - dot = T1ReadWord(Vdp2Ram, scrAddr); - scrAddr += 2; - - puthline16(0, i, vdp2width, dot, 0); - } - } - else - { - // Single Color - dot = T1ReadWord(Vdp2Ram, scrAddr); - - for (i = 0; i < (vdp2width * vdp2height); i++) - vdp2framebuffer[i] = COLSAT2YAB16(0, dot); - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawNBG0(void) -{ - vdp2draw_struct info; - vdp2rotationparameterfp_struct parameter[2]; - - if (Vdp2Regs->BGON & 0x20) - { - // RBG1 mode - info.enable = Vdp2Regs->BGON & 0x20; - - // Read in Parameter B - Vdp2ReadRotationTableFP(1, ¶meter[1]); - - if((info.isbitmap = Vdp2Regs->CHCTLA & 0x2) != 0) - { - // Bitmap Mode - ReadBitmapSize(&info, Vdp2Regs->CHCTLA >> 2, 0x3); - - info.charaddr = (Vdp2Regs->MPOFR & 0x70) * 0x2000; - info.paladdr = (Vdp2Regs->BMPNA & 0x7) << 8; - info.flipfunction = 0; - info.specialfunction = 0; - } - else - { - // Tile Mode - info.mapwh = 4; - ReadPlaneSize(&info, Vdp2Regs->PLSZ >> 12); - ReadPatternData(&info, Vdp2Regs->PNCN0, Vdp2Regs->CHCTLA & 0x1); - } - - info.rotatenum = 1; - info.rotatemode = 0; - info.PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2ParameterBPlaneAddr; - } - else if (Vdp2Regs->BGON & 0x1) - { - // NBG0 mode - info.enable = Vdp2Regs->BGON & 0x1; - - if((info.isbitmap = Vdp2Regs->CHCTLA & 0x2) != 0) - { - // Bitmap Mode - ReadBitmapSize(&info, Vdp2Regs->CHCTLA >> 2, 0x3); - - info.x = Vdp2Regs->SCXIN0 & 0x7FF; - info.y = Vdp2Regs->SCYIN0 & 0x7FF; - - info.charaddr = (Vdp2Regs->MPOFN & 0x7) * 0x20000; - info.paladdr = (Vdp2Regs->BMPNA & 0x7) << 8; - info.flipfunction = 0; - info.specialfunction = 0; - } - else - { - // Tile Mode - info.mapwh = 2; - - ReadPlaneSize(&info, Vdp2Regs->PLSZ); - - info.x = Vdp2Regs->SCXIN0 & 0x7FF; - info.y = Vdp2Regs->SCYIN0 & 0x7FF; - ReadPatternData(&info, Vdp2Regs->PNCN0, Vdp2Regs->CHCTLA & 0x1); - } - - info.coordincx = (Vdp2Regs->ZMXN0.all & 0x7FF00) / (float) 65536; - info.coordincy = (Vdp2Regs->ZMYN0.all & 0x7FF00) / (float) 65536; - info.PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2NBG0PlaneAddr; - } - else - // Not enabled - return; - - info.transparencyenable = !(Vdp2Regs->BGON & 0x100); - info.specialprimode = Vdp2Regs->SFPRMD & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLA & 0x70) >> 4; - - if (Vdp2Regs->CCCTL & 0x1) - info.alpha = Vdp2Regs->CCRNA & 0x1F; - - info.coloroffset = (Vdp2Regs->CRAOFA & 0x7) << 8; - ReadVdp2ColorOffset(&info, 0x1, 0x1); - info.priority = nbg0priority; - - if (!(info.enable & Vdp2External.disptoggle)) - return; - - ReadMosaicData(&info, 0x1); - ReadLineScrollData(&info, Vdp2Regs->SCRCTL & 0xFF, Vdp2Regs->LSTA0.all); - if (Vdp2Regs->SCRCTL & 1) - { - info.isverticalscroll = 1; - info.verticalscrolltbl = (Vdp2Regs->VCSTA.all & 0x7FFFE) << 1; - if (Vdp2Regs->SCRCTL & 0x100) - info.verticalscrollinc = 8; - else - info.verticalscrollinc = 4; - } - else - info.isverticalscroll = 0; - info.wctl = Vdp2Regs->WCTLA; - - if (info.enable == 1) - { - // NBG0 draw - GCDVdp2DrawScroll(&info, vdp2framebuffer, vdp2width, vdp2height); - } - else - { - // RBG1 draw - Vdp2DrawRotationFP(&info, parameter); - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawNBG1(void) -{ - vdp2draw_struct info; - - info.enable = Vdp2Regs->BGON & 0x2; - info.transparencyenable = !(Vdp2Regs->BGON & 0x200); - info.specialprimode = (Vdp2Regs->SFPRMD >> 2) & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLA & 0x3000) >> 12; - - if((info.isbitmap = Vdp2Regs->CHCTLA & 0x200) != 0) - { - ReadBitmapSize(&info, Vdp2Regs->CHCTLA >> 10, 0x3); - - info.x = Vdp2Regs->SCXIN1 & 0x7FF; - info.y = Vdp2Regs->SCYIN1 & 0x7FF; - - info.charaddr = ((Vdp2Regs->MPOFN & 0x70) >> 4) * 0x20000; - info.paladdr = Vdp2Regs->BMPNA & 0x700; - info.flipfunction = 0; - info.specialfunction = 0; - } - else - { - info.mapwh = 2; - - ReadPlaneSize(&info, Vdp2Regs->PLSZ >> 2); - - info.x = Vdp2Regs->SCXIN1 & 0x7FF; - info.y = Vdp2Regs->SCYIN1 & 0x7FF; - - ReadPatternData(&info, Vdp2Regs->PNCN1, Vdp2Regs->CHCTLA & 0x100); - } - - if (Vdp2Regs->CCCTL & 0x2) - info.alpha = (Vdp2Regs->CCRNA >> 8) & 0x1F; - - info.coloroffset = (Vdp2Regs->CRAOFA & 0x70) << 4; - ReadVdp2ColorOffset(&info, 0x2, 0x2); - info.coordincx = (Vdp2Regs->ZMXN1.all & 0x7FF00) / (float) 65536; - info.coordincy = (Vdp2Regs->ZMYN1.all & 0x7FF00) / (float) 65536; - - info.priority = nbg1priority; - info.PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2NBG1PlaneAddr; - - if (!(info.enable & Vdp2External.disptoggle)) - return; - - ReadMosaicData(&info, 0x2); - ReadLineScrollData(&info, Vdp2Regs->SCRCTL >> 8, Vdp2Regs->LSTA1.all); - if (Vdp2Regs->SCRCTL & 0x100) - { - info.isverticalscroll = 1; - if (Vdp2Regs->SCRCTL & 0x1) - { - info.verticalscrolltbl = 4 + ((Vdp2Regs->VCSTA.all & 0x7FFFE) << 1); - info.verticalscrollinc = 8; - } - else - { - info.verticalscrolltbl = (Vdp2Regs->VCSTA.all & 0x7FFFE) << 1; - info.verticalscrollinc = 4; - } - } - else - info.isverticalscroll = 0; - info.wctl = Vdp2Regs->WCTLA >> 8; - - GCDVdp2DrawScroll(&info, vdp2framebuffer, vdp2width, vdp2height); -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawNBG2(void) -{ - vdp2draw_struct info; - - info.enable = Vdp2Regs->BGON & 0x4; - info.transparencyenable = !(Vdp2Regs->BGON & 0x400); - info.specialprimode = (Vdp2Regs->SFPRMD >> 4) & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLB & 0x2) >> 1; - info.mapwh = 2; - - ReadPlaneSize(&info, Vdp2Regs->PLSZ >> 4); - info.x = Vdp2Regs->SCXN2 & 0x7FF; - info.y = Vdp2Regs->SCYN2 & 0x7FF; - ReadPatternData(&info, Vdp2Regs->PNCN2, Vdp2Regs->CHCTLB & 0x1); - - if (Vdp2Regs->CCCTL & 0x4) - info.alpha = Vdp2Regs->CCRNB & 0x1F; - - info.coloroffset = Vdp2Regs->CRAOFA & 0x700; - ReadVdp2ColorOffset(&info, 0x4, 0x4); - info.coordincx = info.coordincy = 1; - - info.priority = nbg2priority; - info.PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2NBG2PlaneAddr; - - if (!(info.enable & Vdp2External.disptoggle)) - return; - - ReadMosaicData(&info, 0x4); - info.islinescroll = 0; - info.isverticalscroll = 0; - info.wctl = Vdp2Regs->WCTLB; - info.isbitmap = 0; - - GCDVdp2DrawScroll(&info, vdp2framebuffer, vdp2width, vdp2height); -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawNBG3(void) -{ - vdp2draw_struct info; - - info.enable = Vdp2Regs->BGON & 0x8; - info.transparencyenable = !(Vdp2Regs->BGON & 0x800); - info.specialprimode = (Vdp2Regs->SFPRMD >> 6) & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLB & 0x20) >> 5; - - info.mapwh = 2; - - ReadPlaneSize(&info, Vdp2Regs->PLSZ >> 6); - info.x = Vdp2Regs->SCXN3 & 0x7FF; - info.y = Vdp2Regs->SCYN3 & 0x7FF; - ReadPatternData(&info, Vdp2Regs->PNCN3, Vdp2Regs->CHCTLB & 0x10); - - if (Vdp2Regs->CCCTL & 0x8) - info.alpha = (Vdp2Regs->CCRNB >> 8) & 0x1F; - - info.coloroffset = (Vdp2Regs->CRAOFA & 0x7000) >> 4; - ReadVdp2ColorOffset(&info, 0x8, 0x8); - info.coordincx = info.coordincy = 1; - - info.priority = nbg3priority; - info.PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2NBG3PlaneAddr; - - if (!(info.enable & Vdp2External.disptoggle)) - return; - - ReadMosaicData(&info, 0x8); - info.islinescroll = 0; - info.isverticalscroll = 0; - info.wctl = Vdp2Regs->WCTLB >> 8; - info.isbitmap = 0; - - GCDVdp2DrawScroll(&info, vdp2framebuffer, vdp2width, vdp2height); -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawRBG0(void) -{ - vdp2draw_struct info; - vdp2rotationparameterfp_struct parameter[2]; - - info.enable = Vdp2Regs->BGON & 0x10; - info.priority = rbg0priority; - if (!(info.enable & Vdp2External.disptoggle)) - return; - info.transparencyenable = !(Vdp2Regs->BGON & 0x1000); - info.specialprimode = (Vdp2Regs->SFPRMD >> 8) & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLB & 0x7000) >> 12; - - // Figure out which Rotation Parameter we're using - switch (Vdp2Regs->RPMD & 0x3) - { - case 0: - // Parameter A - info.rotatenum = 0; - info.rotatemode = 0; - info.PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2ParameterAPlaneAddr; - break; - case 1: - // Parameter B - info.rotatenum = 1; - info.rotatemode = 0; - info.PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2ParameterBPlaneAddr; - break; - case 2: - // Parameter A+B switched via coefficients - case 3: - // Parameter A+B switched via rotation parameter window - default: - info.rotatenum = 0; - info.rotatemode = 1 + (Vdp2Regs->RPMD & 0x1); - info.PlaneAddr = (void FASTCALL (*)(void *, int))&Vdp2ParameterAPlaneAddr; - break; - } - - Vdp2ReadRotationTableFP(info.rotatenum, ¶meter[info.rotatenum]); - - if((info.isbitmap = Vdp2Regs->CHCTLB & 0x200) != 0) - { - // Bitmap Mode - ReadBitmapSize(&info, Vdp2Regs->CHCTLB >> 10, 0x1); - - if (info.rotatenum == 0) - // Parameter A - info.charaddr = (Vdp2Regs->MPOFR & 0x7) * 0x20000; - else - // Parameter B - info.charaddr = (Vdp2Regs->MPOFR & 0x70) * 0x2000; - - info.paladdr = (Vdp2Regs->BMPNB & 0x7) << 8; - info.flipfunction = 0; - info.specialfunction = 0; - } - else - { - // Tile Mode - info.mapwh = 4; - - if (info.rotatenum == 0) - // Parameter A - ReadPlaneSize(&info, Vdp2Regs->PLSZ >> 8); - else - // Parameter B - ReadPlaneSize(&info, Vdp2Regs->PLSZ >> 12); - - ReadPatternData(&info, Vdp2Regs->PNCR, Vdp2Regs->CHCTLB & 0x100); - } - - if (Vdp2Regs->CCCTL & 0x10) - info.alpha = Vdp2Regs->CCRR & 0x1F; - - info.coloroffset = (Vdp2Regs->CRAOFB & 0x7) << 8; - - ReadVdp2ColorOffset(&info, 0x10, 0x10); - info.coordincx = info.coordincy = 1; - - ReadMosaicData(&info, 0x10); - info.islinescroll = 0; - info.isverticalscroll = 0; - info.wctl = Vdp2Regs->WCTLC; - - Vdp2DrawRotationFP(&info, parameter); -} - -////////////////////////////////////////////////////////////////////////////// - -int VIDGCDInit(void) -{ - // Initialize output buffer - if ((dispbuffer = (u32 *)calloc(sizeof(u32), 704 * 512)) == NULL) - return -1; - - // Initialize VDP1 framebuffer 1 - if ((vdp1framebuffer[0] = (u8 *)calloc(sizeof(u8), 0x40000)) == NULL) - return -1; - - // Initialize VDP1 framebuffer 2 - if ((vdp1framebuffer[1] = (u8 *)calloc(sizeof(u8), 0x40000)) == NULL) - return -1; - - // Initialize VDP2 framebuffer - if ((vdp2framebuffer = (u32 *)calloc(sizeof(u32), 704 * 512)) == NULL) - return -1; - - vdp1backframebuffer = vdp1framebuffer[0]; - vdp1frontframebuffer = vdp1framebuffer[1]; - vdp2width = 320; - vdp2height = 224; - -#ifdef USE_OPENGL - YuiSetVideoAttribute(DOUBLEBUFFER, 1); - - if (!YglScreenInit(8, 8, 8, 24)) - { - if (!YglScreenInit(4, 4, 4, 24)) - { - if (!YglScreenInit(5, 6, 5, 16)) - { - YuiErrorMsg("Couldn't set GL mode\n"); - return -1; - } - } - } - - glClear(GL_COLOR_BUFFER_BIT); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, 320, 224, 0, 1, 0); - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glOrtho(-320, 320, -224, 224, 1, 0); - outputwidth = 320; - outputheight = 224; - msglength = 0; -#endif - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDDeInit(void) -{ - if (dispbuffer) - { - free(dispbuffer); - dispbuffer = NULL; - } - - if (vdp1framebuffer[0]) - free(vdp1framebuffer[0]); - - if (vdp1framebuffer[1]) - free(vdp1framebuffer[1]); - - if (vdp2framebuffer) - free(vdp2framebuffer); -} - -////////////////////////////////////////////////////////////////////////////// - -static int IsFullscreen = 0; - -void VIDGCDResize(unsigned int w, unsigned int h, int on) -{ -#ifdef USE_OPENGL - IsFullscreen = on; - - if (on) - YuiSetVideoMode(w, h, 32, 1); - else - YuiSetVideoMode(w, h, 32, 0); - - glClear(GL_COLOR_BUFFER_BIT); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, w, h, 0, 1, 0); - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glOrtho(-w, w, -h, h, 1, 0); - - glViewport(0, 0, w, h); - outputwidth = w; - outputheight = h; -#endif -} - -////////////////////////////////////////////////////////////////////////////// - -int VIDGCDIsFullscreen(void) { - return IsFullscreen; -} - -////////////////////////////////////////////////////////////////////////////// - -int VIDGCDVdp1Reset(void) -{ - vdp1clipxstart = 0; - vdp1clipxend = 512; - vdp1clipystart = 0; - vdp1clipyend = 256; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp1DrawStart(void) -{ - if (Vdp1Regs->TVMR & 0x1) - { - if (Vdp1Regs->TVMR & 0x2) - { - // Rotation 8-bit - vdp1width = 512; - vdp1height = 512; - } - else - { - // Normal 8-bit - vdp1width = 1024; - vdp1width = 256; - } - - vdp1pixelsize = 1; - } - else - { - // Rotation/Normal 16-bit - vdp1width = 512; - vdp1height = 256; - vdp1pixelsize = 2; - } - - VIDGCDVdp1EraseFrameBuffer(); -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp1DrawEnd(void) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE u16 Vdp1ReadPattern16( u32 base, u32 offset ) { - - u16 dot = T1ReadByte(Vdp1Ram, ( base + (offset>>1)) & 0x7FFFF); - if ((offset & 0x1) == 0) dot >>= 4; // Even pixel - else dot &= 0xF; // Odd pixel - return dot; -} - -static INLINE u16 Vdp1ReadPattern64( u32 base, u32 offset ) { - - return T1ReadByte(Vdp1Ram, ( base + offset ) & 0x7FFFF) & 0x3F; -} - -static INLINE u16 Vdp1ReadPattern128( u32 base, u32 offset ) { - - return T1ReadByte(Vdp1Ram, ( base + offset ) & 0x7FFFF) & 0x7F; -} - -static INLINE u16 Vdp1ReadPattern256( u32 base, u32 offset ) { - - return T1ReadByte(Vdp1Ram, ( base + offset ) & 0x7FFFF) & 0xFF; -} - -static INLINE u16 Vdp1ReadPattern64k( u32 base, u32 offset ) { - - return T1ReadWord(Vdp1Ram, ( base + 2*offset) & 0x7FFFF); -} - -//////////////////////////////////////////////////////////////////////////////// - -static INLINE u32 alphablend16(u32 d, u32 s, u32 level) -{ - int r,g,b,sr,sg,sb,dr,dg,db; - - int invlevel = 256-level; - sr = s & 0x001f; dr = d & 0x001f; - r = (sr*level + dr*invlevel)>>8; r&= 0x1f; - sg = s & 0x03e0; dg = d & 0x03e0; - g = (sg*level + dg*invlevel)>>8; g&= 0x03e0; - sb = s & 0x7c00; db = d & 0x7c00; - b = (sb*level + db*invlevel)>>8; b&= 0x7c00; - return r|g|b; -} - -typedef struct _COLOR_PARAMS -{ - double r,g,b; -} COLOR_PARAMS; - -COLOR_PARAMS leftColumnColor; - -vdp1cmd_struct cmd; - -int currentPixel; -int currentPixelIsVisible; -int characterWidth; -int characterHeight; - -static int getpixel(int linenumber, int currentlineindex) { - - u32 characterAddress; - u32 colorlut; - u16 colorbank; - u8 SPD; - int endcode; - int endcodesEnabled; - int untexturedColor = 0; - int isTextured = 1; - int currentShape = cmd.CMDCTRL & 0x7; - int flip; - - characterAddress = cmd.CMDSRCA << 3; - colorbank = cmd.CMDCOLR; - colorlut = (u32)colorbank << 3; - SPD = ((cmd.CMDPMOD & 0x40) != 0);//show the actual color of transparent pixels if 1 (they won't be drawn transparent) - endcodesEnabled = (( cmd.CMDPMOD & 0x80) == 0 )?1:0; - flip = (cmd.CMDCTRL & 0x30) >> 4; - - //4 polygon, 5 polyline or 6 line - if(currentShape == 4 || currentShape == 5 || currentShape == 6) { - isTextured = 0; - untexturedColor = cmd.CMDCOLR; - } - - switch( flip ) { - case 1: - // Horizontal flipping - currentlineindex = characterWidth - currentlineindex-1; - break; - case 2: - // Vertical flipping - linenumber = characterHeight - linenumber-1; - - break; - case 3: - // Horizontal/Vertical flipping - linenumber = characterHeight - linenumber-1; - currentlineindex = characterWidth - currentlineindex-1; - break; - } - - switch ((cmd.CMDPMOD >> 3) & 0x7) - { - case 0x0: //4bpp bank - endcode = 0xf; - currentPixel = Vdp1ReadPattern16( characterAddress + (linenumber*(characterWidth>>1)), currentlineindex ); - if(isTextured && endcodesEnabled && currentPixel == endcode) - return 1; - if (!((currentPixel == 0) && !SPD)) - currentPixel = colorbank | currentPixel; - currentPixelIsVisible = 0xf; - break; - - case 0x1://4bpp lut - endcode = 0xf; - currentPixel = Vdp1ReadPattern16( characterAddress + (linenumber*(characterWidth>>1)), currentlineindex ); - if(isTextured && endcodesEnabled && currentPixel == endcode) - return 1; - if (!(currentPixel == 0 && !SPD)) - currentPixel = T1ReadWord(Vdp1Ram, (currentPixel * 2 + colorlut) & 0x7FFFF); - currentPixelIsVisible = 0xffff; - break; - case 0x2://8pp bank (64 color) - //is there a hardware bug with endcodes in this color mode? - //there are white lines around some characters in scud - //using an endcode of 63 eliminates the white lines - //but also causes some dropout due to endcodes being triggered that aren't triggered on hardware - //the closest thing i can do to match the hardware is make all pixels with color index 63 transparent - //this needs more hardware testing - - endcode = 63; - currentPixel = Vdp1ReadPattern64( characterAddress + (linenumber*(characterWidth)), currentlineindex ); - if(isTextured && endcodesEnabled && currentPixel == endcode) - currentPixel = 0; - // return 1; - if (!((currentPixel == 0) && !SPD)) - currentPixel = colorbank | currentPixel; - currentPixelIsVisible = 0x3f; - break; - case 0x3://128 color - endcode = 0xff; - currentPixel = Vdp1ReadPattern128( characterAddress + (linenumber*characterWidth), currentlineindex ); - if(isTextured && endcodesEnabled && currentPixel == endcode) - return 1; - if (!((currentPixel == 0) && !SPD)) - currentPixel = colorbank | currentPixel; - currentPixelIsVisible = 0x7f; - break; - case 0x4://256 color - endcode = 0xff; - currentPixel = Vdp1ReadPattern256( characterAddress + (linenumber*characterWidth), currentlineindex ); - if(isTextured && endcodesEnabled && currentPixel == endcode) - return 1; - currentPixelIsVisible = 0xff; - if (!((currentPixel == 0) && !SPD)) - currentPixel = colorbank | currentPixel; - break; - case 0x5://16bpp bank - endcode = 0x7fff; - currentPixel = Vdp1ReadPattern64k( characterAddress + (linenumber*characterWidth*2), currentlineindex ); - if(isTextured && endcodesEnabled && currentPixel == endcode) - return 1; - currentPixelIsVisible = 0xffff; - break; - } - - if(!isTextured) - currentPixel = untexturedColor; - - //force the MSB to be on if MSBON is set - currentPixel |= cmd.CMDPMOD & (1 << 15); - - return 0; -} - -static int gouraudAdjust( int color, int tableValue ) -{ - color += (tableValue - 0x10); - - if ( color < 0 ) color = 0; - if ( color > 0x1f ) color = 0x1f; - - return color; -} - -static void putpixel(int x, int y) { - - u16* iPix = &((u16 *)vdp1backframebuffer)[(y * vdp1width) + x]; - int mesh = cmd.CMDPMOD & 0x0100; - int SPD = ((cmd.CMDPMOD & 0x40) != 0);//show the actual color of transparent pixels if 1 (they won't be drawn transparent) - int currentShape = cmd.CMDCTRL & 0x7; - int isTextured=1; - - if(mesh && (x^y)&1) - return; - - if(currentShape == 4 || currentShape == 5 || currentShape == 6) - isTextured = 0; - - if (cmd.CMDPMOD & 0x0400) PushUserClipping((cmd.CMDPMOD >> 9) & 0x1); - - if (x >= vdp1clipxstart && - x < vdp1clipxend && - y >= vdp1clipystart && - y < vdp1clipyend) - {} - else - return; - - if (cmd.CMDPMOD & 0x0400) PopUserClipping(); - - - if ( SPD || (currentPixel & currentPixelIsVisible)) - { - switch( cmd.CMDPMOD & 0x7 )//we want bits 0,1,2 - { - case 0: // replace - if (!((currentPixel == 0) && !SPD)) - *(iPix) = currentPixel; - break; - case 1: // shadow, TODO - *(iPix) = currentPixel; - break; - case 2: // half luminance - *(iPix) = ((currentPixel & ~0x8421) >> 1) | (1 << 15); - break; - case 3: // half transparent - if ( *(iPix) & (1 << 15) )//only if MSB of framebuffer data is set - *(iPix) = alphablend16( *(iPix), currentPixel, (1 << 7) ) | (1 << 15); - else - *(iPix) = currentPixel; - break; - case 4: //gouraud - #define COLOR(r,g,b) (((r)&0x1F)|(((g)&0x1F)<<5)|(((b)&0x1F)<<10) |0x8000 ) - - //handle the special case demonstrated in the sgl chrome demo - //if we are in a paletted bank mode and the other two colors are unused, adjust the index value instead of rgb - if( - (((cmd.CMDPMOD >> 3) & 0x7) != 5) && - (((cmd.CMDPMOD >> 3) & 0x7) != 1) && - (int)leftColumnColor.g == 16 && - (int)leftColumnColor.b == 16) - { - int c = (int)(leftColumnColor.r-0x10); - if(c < 0) c = 0; - currentPixel = currentPixel+c; - *(iPix) = currentPixel; - break; - } - *(iPix) = COLOR( - gouraudAdjust( - currentPixel&0x001F, - (int)leftColumnColor.r), - - gouraudAdjust( - (currentPixel&0x03e0) >> 5, - (int)leftColumnColor.g), - - gouraudAdjust( - (currentPixel&0x7c00) >> 10, - (int)leftColumnColor.b) - ); - break; - default: - *(iPix) = alphablend16( COLOR((int)leftColumnColor.r,(int)leftColumnColor.g, (int)leftColumnColor.b), currentPixel, (1 << 7) ) | (1 << 15); - break; - } - - if(*iPix & 0x8000) { - vdp1draw_info.priosused[vdp1draw_info.prioritytable[0]] = 1; - } - else if(*iPix) { - u16 p = *iPix; - int s, prio, c; - - Vdp1ProcessSpritePixel(vdp1spritetype, &p, &s, &prio, &c); - vdp1draw_info.priosused[prio] = 1; - } - } -} - -//TODO consolidate the following 3 functions -static int bresenham( int x1, int y1, int x2, int y2, int x[], int y[]) -{ - int dx, dy, xf, yf, a, b, c, i; - - if (x2>x1) { - dx = x2-x1; - xf = 1; - } - else { - dx = x1-x2; - xf = -1; - } - - if (y2>y1) { - dy = y2-y1; - yf = 1; - } - else { - dy = y1-y2; - yf = -1; - } - - //burning rangers tries to draw huge shapes - //this will at least let it run - if(dx > 999 || dy > 999) - return INT_MAX; - - if (dx>dy) { - a = dy+dy; - c = a-dx; - b = c-dx; - for (i=0;i<=dx;i++) { - x[i] = x1; y[i] = y1; - x1 += xf; - if (c<0) { - c += a; - } - else { - c += b; - y1 += yf; - } - } - return dx+1; - } - else { - a = dx+dx; - c = a-dy; - b = c-dy; - for (i=0;i<=dy;i++) { - x[i] = x1; y[i] = y1; - y1 += yf; - if (c<0) { - c += a; - } - else { - c += b; - x1 += xf; - } - } - return dy+1; - } -} - -static int DrawLine( int x1, int y1, int x2, int y2, double linenumber, double texturestep, double xredstep, double xgreenstep, double xbluestep) -{ - int dx, dy, xf, yf, a, b, c, i; - int endcodesdetected=0; - int previousStep = 123456789; - - if (x2>x1) { - dx = x2-x1; - xf = 1; - } - else { - dx = x1-x2; - xf = -1; - } - - if (y2>y1) { - dy = y2-y1; - yf = 1; - } - else { - dy = y1-y2; - yf = -1; - } - - if (dx>dy) { - a = dy+dy; - c = a-dx; - b = c-dx; - for (i=0;i<=dx;i++) { - leftColumnColor.r+=xredstep; - leftColumnColor.g+=xgreenstep; - leftColumnColor.b+=xbluestep; - - if(getpixel(linenumber,(int)i*texturestep)) { - if(currentPixel != previousStep) { - previousStep = (int)i*texturestep; - endcodesdetected++; - } - } - else - putpixel(x1,y1); - - previousStep = currentPixel; - - if(endcodesdetected==2) - break; - - x1 += xf; - if (c<0) { - c += a; - } - else { - getpixel(linenumber,(int)i*texturestep); - putpixel(x1,y1); - c += b; - y1 += yf; -/* - //same as sega's way, but just move the code down here instead - //and use the pixel we already have instead of the next one - if(xf>1&&yf>1) putpixel(x1,y1-1); //case 1 - if(xf<1&&yf<1) putpixel(x1,y1+1); //case 2 - if(xf<1&&yf>1) putpixel(x1+1,y1); //case 7 - if(xf>1&&yf<1) putpixel(x1-1,y1); //case 8*/ - } - } - return dx+1; - } - else { - a = dx+dx; - c = a-dy; - b = c-dy; - for (i=0;i<=dy;i++) { - leftColumnColor.r+=xredstep; - leftColumnColor.g+=xgreenstep; - leftColumnColor.b+=xbluestep; - - if(getpixel(linenumber,(int)i*texturestep)) { - if(currentPixel != previousStep) { - previousStep = (int)i*texturestep; - endcodesdetected++; - } - } - else - putpixel(x1,y1); - - previousStep = currentPixel; - - if(endcodesdetected==2) - break; - - y1 += yf; - if (c<0) { - c += a; - } - else { - getpixel(linenumber,(int)i*texturestep); - putpixel(x1,y1); - c += b; - x1 += xf; -/* - if(xf>1&&yf>1) putpixel(x1,y1-1); //case 3 - if(xf<1&&yf<1) putpixel(x1,y1+1); //case 4 - if(xf<1&&yf>1) putpixel(x1+1,y1); //case 5 - if(xf>1&&yf<1) putpixel(x1-1,y1); //case 6*/ - - } - } - return dy+1; - } -} - -static int getlinelength(int x1, int y1, int x2, int y2) { - int dx, dy, xf, yf, a, b, c, i; - - if (x2>x1) { - dx = x2-x1; - xf = 1; - } - else { - dx = x1-x2; - xf = -1; - } - - if (y2>y1) { - dy = y2-y1; - yf = 1; - } - else { - dy = y1-y2; - yf = -1; - } - - if (dx>dy) { - a = dy+dy; - c = a-dx; - b = c-dx; - for (i=0;i<=dx;i++) { - - x1 += xf; - if (c<0) { - c += a; - } - else { - c += b; - y1 += yf; - } - } - return dx+1; - } - else { - a = dx+dx; - c = a-dy; - b = c-dy; - for (i=0;i<=dy;i++) { - y1 += yf; - if (c<0) { - c += a; - } - else { - c += b; - x1 += xf; - } - } - return dy+1; - } -} - -static INLINE double interpolate(double start, double end, int numberofsteps) { - - double stepvalue = 0; - - if(numberofsteps == 0) - return 1; - - stepvalue = (end - start) / numberofsteps; - - return stepvalue; -} - -typedef union _COLOR { // xbgr x555 - struct { -#ifdef WORDS_BIGENDIAN - u16 x:1; - u16 b:5; - u16 g:5; - u16 r:5; -#else - u16 r:5; - u16 g:5; - u16 b:5; - u16 x:1; -#endif - }; - u16 value; -} COLOR; - - -COLOR gouraudA; -COLOR gouraudB; -COLOR gouraudC; -COLOR gouraudD; - -static void gouraudTable(void) -{ - int gouraudTableAddress; - - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - gouraudTableAddress = (((unsigned int)cmd.CMDGRDA) << 3); - - gouraudA.value = T1ReadWord(Vdp1Ram,gouraudTableAddress); - gouraudB.value = T1ReadWord(Vdp1Ram,gouraudTableAddress+2); - gouraudC.value = T1ReadWord(Vdp1Ram,gouraudTableAddress+4); - gouraudD.value = T1ReadWord(Vdp1Ram,gouraudTableAddress+6); -} - -int xleft[1000]; -int yleft[1000]; -int xright[1000]; -int yright[1000]; - -//a real vdp1 draws with arbitrary lines -//this is why endcodes are possible -//this is also the reason why half-transparent shading causes moire patterns -//and the reason why gouraud shading can be applied to a single line draw command -static void drawQuad(s32 tl_x, s32 tl_y, s32 bl_x, s32 bl_y, s32 tr_x, s32 tr_y, s32 br_x, s32 br_y){ - - int totalleft; - int totalright; - int total; - int i; - - COLOR_PARAMS topLeftToBottomLeftColorStep = {0,0,0}, topRightToBottomRightColorStep = {0,0,0}; - - //how quickly we step through the line arrays - double leftLineStep = 1; - double rightLineStep = 1; - - //a lookup table for the gouraud colors - COLOR colors[4]; - - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - characterWidth = ((cmd.CMDSIZE >> 8) & 0x3F) * 8; - characterHeight = cmd.CMDSIZE & 0xFF; - - totalleft = bresenham(tl_x,tl_y,bl_x,bl_y,xleft,yleft); - totalright = bresenham(tr_x,tr_y,br_x,br_y,xright,yright); - - //just for now since burning rangers will freeze up trying to draw huge shapes - if(totalleft == INT_MAX || totalright == INT_MAX) - return; - - total = totalleft > totalright ? totalleft : totalright; - - - if(cmd.CMDPMOD & (1 << 2)) { - - gouraudTable(); - - { colors[0] = gouraudA; colors[1] = gouraudD; colors[2] = gouraudB; colors[3] = gouraudC; } - - topLeftToBottomLeftColorStep.r = interpolate(colors[0].r,colors[1].r,total); - topLeftToBottomLeftColorStep.g = interpolate(colors[0].g,colors[1].g,total); - topLeftToBottomLeftColorStep.b = interpolate(colors[0].b,colors[1].b,total); - - topRightToBottomRightColorStep.r = interpolate(colors[2].r,colors[3].r,total); - topRightToBottomRightColorStep.g = interpolate(colors[2].g,colors[3].g,total); - topRightToBottomRightColorStep.b = interpolate(colors[2].b,colors[3].b,total); - } - - //we have to step the equivalent of less than one pixel on the shorter side - //to make sure textures stretch properly and the shape is correct - if(total == totalleft && totalleft != totalright) { - //left side is larger - leftLineStep = 1; - rightLineStep = (double)totalright / totalleft; - } - else if(totalleft != totalright){ - //right side is larger - rightLineStep = 1; - leftLineStep = (double)totalleft / totalright; - } - - for(i = 0; i < total; i++) { - - int xlinelength; - - double xtexturestep; - double ytexturestep; - - COLOR_PARAMS rightColumnColor; - - COLOR_PARAMS leftToRightStep = {0,0,0}; - - //get the length of the line we are about to draw - xlinelength = getlinelength( - xleft[(int)(i*leftLineStep)], - yleft[(int)(i*leftLineStep)], - xright[(int)(i*rightLineStep)], - yright[(int)(i*rightLineStep)]); - - //so from 0 to the width of the texture / the length of the line is how far we need to step - xtexturestep=interpolate(0,characterWidth,xlinelength); - - //now we need to interpolate the y texture coordinate across multiple lines - ytexturestep=interpolate(0,characterHeight,total); - - //gouraud interpolation - if(cmd.CMDPMOD & (1 << 2)) { - - //for each new line we need to step once more through each column - //and add the orignal color + the number of steps taken times the step value to the bottom of the shape - //to get the current colors to use to interpolate across the line - - leftColumnColor.r = colors[0].r +(topLeftToBottomLeftColorStep.r*i); - leftColumnColor.g = colors[0].g +(topLeftToBottomLeftColorStep.g*i); - leftColumnColor.b = colors[0].b +(topLeftToBottomLeftColorStep.b*i); - - rightColumnColor.r = colors[2].r +(topRightToBottomRightColorStep.r*i); - rightColumnColor.g = colors[2].g +(topRightToBottomRightColorStep.g*i); - rightColumnColor.b = colors[2].b +(topRightToBottomRightColorStep.b*i); - - //interpolate colors across to get the right step values - leftToRightStep.r = interpolate(leftColumnColor.r,rightColumnColor.r,xlinelength); - leftToRightStep.g = interpolate(leftColumnColor.g,rightColumnColor.g,xlinelength); - leftToRightStep.b = interpolate(leftColumnColor.b,rightColumnColor.b,xlinelength); - } - - DrawLine( - xleft[(int)(i*leftLineStep)], - yleft[(int)(i*leftLineStep)], - xright[(int)(i*rightLineStep)], - yright[(int)(i*rightLineStep)], - ytexturestep*i, - xtexturestep, - leftToRightStep.r, - leftToRightStep.g, - leftToRightStep.b - ); - } -} - -void VIDGCDVdp1NormalSpriteDraw() { - - s16 topLeftx,topLefty,topRightx,topRighty,bottomRightx,bottomRighty,bottomLeftx,bottomLefty; - int spriteWidth; - int spriteHeight; - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - topLeftx = cmd.CMDXA + Vdp1Regs->localX; - topLefty = cmd.CMDYA + Vdp1Regs->localY; - spriteWidth = ((cmd.CMDSIZE >> 8) & 0x3F) * 8; - spriteHeight = cmd.CMDSIZE & 0xFF; - - topRightx = topLeftx + (spriteWidth - 1); - topRighty = topLefty; - bottomRightx = topLeftx + (spriteWidth - 1); - bottomRighty = topLefty + (spriteHeight - 1); - bottomLeftx = topLeftx; - bottomLefty = topLefty + (spriteHeight - 1); - - drawQuad(topLeftx,topLefty,bottomLeftx,bottomLefty,topRightx,topRighty,bottomRightx,bottomRighty); -} - -void VIDGCDVdp1ScaledSpriteDraw(){ - - s32 topLeftx,topLefty,topRightx,topRighty,bottomRightx,bottomRighty,bottomLeftx,bottomLefty; - int spriteWidth; - int spriteHeight; - int x0,y0,x1,y1; - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - x0 = cmd.CMDXA + Vdp1Regs->localX; - y0 = cmd.CMDYA + Vdp1Regs->localY; - - switch ((cmd.CMDCTRL >> 8) & 0xF) - { - case 0x0: // Only two coordinates - default: - x1 = ((int)cmd.CMDXC) - x0 + Vdp1Regs->localX + 1; - y1 = ((int)cmd.CMDYC) - y0 + Vdp1Regs->localY + 1; - break; - case 0x5: // Upper-left - x1 = ((int)cmd.CMDXB) + 1; - y1 = ((int)cmd.CMDYB) + 1; - break; - case 0x6: // Upper-Center - x1 = ((int)cmd.CMDXB); - y1 = ((int)cmd.CMDYB); - x0 = x0 - x1/2; - x1++; - y1++; - break; - case 0x7: // Upper-Right - x1 = ((int)cmd.CMDXB); - y1 = ((int)cmd.CMDYB); - x0 = x0 - x1; - x1++; - y1++; - break; - case 0x9: // Center-left - x1 = ((int)cmd.CMDXB); - y1 = ((int)cmd.CMDYB); - y0 = y0 - y1/2; - x1++; - y1++; - break; - case 0xA: // Center-center - x1 = ((int)cmd.CMDXB); - y1 = ((int)cmd.CMDYB); - x0 = x0 - x1/2; - y0 = y0 - y1/2; - x1++; - y1++; - break; - case 0xB: // Center-right - x1 = ((int)cmd.CMDXB); - y1 = ((int)cmd.CMDYB); - x0 = x0 - x1; - y0 = y0 - y1/2; - x1++; - y1++; - break; - case 0xD: // Lower-left - x1 = ((int)cmd.CMDXB); - y1 = ((int)cmd.CMDYB); - y0 = y0 - y1; - x1++; - y1++; - break; - case 0xE: // Lower-center - x1 = ((int)cmd.CMDXB); - y1 = ((int)cmd.CMDYB); - x0 = x0 - x1/2; - y0 = y0 - y1; - x1++; - y1++; - break; - case 0xF: // Lower-right - x1 = ((int)cmd.CMDXB); - y1 = ((int)cmd.CMDYB); - x0 = x0 - x1; - y0 = y0 - y1; - x1++; - y1++; - break; - } - - spriteWidth = ((cmd.CMDSIZE >> 8) & 0x3F) * 8; - spriteHeight = cmd.CMDSIZE & 0xFF; - - topLeftx = x0; - topLefty = y0; - - topRightx = x1 + x0 - 1; - topRighty = topLefty; - - bottomRightx = x1 + x0 - 1; - bottomRighty = y1 + y0 - 1; - - bottomLeftx = topLeftx; - bottomLefty = y1 + y0 - 1; - - drawQuad(topLeftx,topLefty,bottomLeftx,bottomLefty,topRightx,topRighty,bottomRightx,bottomRighty); -} - -void VIDGCDVdp1DistortedSpriteDraw() { - - s32 xa,ya,xb,yb,xc,yc,xd,yd; - - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - xa = (s32)(cmd.CMDXA + Vdp1Regs->localX); - ya = (s32)(cmd.CMDYA + Vdp1Regs->localY); - - xb = (s32)(cmd.CMDXB + Vdp1Regs->localX); - yb = (s32)(cmd.CMDYB + Vdp1Regs->localY); - - xc = (s32)(cmd.CMDXC + Vdp1Regs->localX); - yc = (s32)(cmd.CMDYC + Vdp1Regs->localY); - - xd = (s32)(cmd.CMDXD + Vdp1Regs->localX); - yd = (s32)(cmd.CMDYD + Vdp1Regs->localY); - - drawQuad(xa,ya,xd,yd,xb,yb,xc,yc); -} - -static void gouraudLineSetup(double * redstep, double * greenstep, double * bluestep, int length, COLOR table1, COLOR table2) { - - gouraudTable(); - - *redstep =interpolate(table1.r,table2.r,length); - *greenstep =interpolate(table1.g,table2.g,length); - *bluestep =interpolate(table1.b,table2.b,length); - - leftColumnColor.r = table1.r; - leftColumnColor.g = table1.g; - leftColumnColor.b = table1.b; -} - -void VIDGCDVdp1PolylineDraw(void) -{ - int X[4]; - int Y[4]; - double redstep = 0, greenstep = 0, bluestep = 0; - int length; - - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - X[0] = (int)Vdp1Regs->localX + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0C)); - Y[0] = (int)Vdp1Regs->localY + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0E)); - X[1] = (int)Vdp1Regs->localX + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x10)); - Y[1] = (int)Vdp1Regs->localY + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x12)); - X[2] = (int)Vdp1Regs->localX + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x14)); - Y[2] = (int)Vdp1Regs->localY + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x16)); - X[3] = (int)Vdp1Regs->localX + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x18)); - Y[3] = (int)Vdp1Regs->localY + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x1A)); - - length = getlinelength(X[0], Y[0], X[1], Y[1]); - gouraudLineSetup(&redstep,&greenstep,&bluestep,length, gouraudA, gouraudB); - DrawLine(X[0], Y[0], X[1], Y[1], 0,0,redstep,greenstep,bluestep); - - length = getlinelength(X[1], Y[1], X[2], Y[2]); - gouraudLineSetup(&redstep,&greenstep,&bluestep,length, gouraudB, gouraudC); - DrawLine(X[1], Y[1], X[2], Y[2], 0,0,redstep,greenstep,bluestep); - - length = getlinelength(X[2], Y[2], X[3], Y[3]); - gouraudLineSetup(&redstep,&greenstep,&bluestep,length, gouraudD, gouraudC); - DrawLine(X[3], Y[3], X[2], Y[2], 0,0,redstep,greenstep,bluestep); - - length = getlinelength(X[3], Y[3], X[0], Y[0]); - gouraudLineSetup(&redstep,&greenstep,&bluestep,length, gouraudA,gouraudD); - DrawLine(X[0], Y[0], X[3], Y[3], 0,0,redstep,greenstep,bluestep); -} - -void VIDGCDVdp1LineDraw(void) -{ - int x1, y1, x2, y2; - double redstep = 0, greenstep = 0, bluestep = 0; - int length; - - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - x1 = (int)Vdp1Regs->localX + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0C)); - y1 = (int)Vdp1Regs->localY + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0E)); - x2 = (int)Vdp1Regs->localX + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x10)); - y2 = (int)Vdp1Regs->localY + (int)((s16)T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x12)); - - length = getlinelength(x1, y1, x2, y2); - gouraudLineSetup(&redstep,&bluestep,&greenstep,length, gouraudA, gouraudB); - DrawLine(x1, y1, x2, y2, 0,0,redstep,greenstep,bluestep); -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp1UserClipping(void) -{ - Vdp1Regs->userclipX1 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0xC); - Vdp1Regs->userclipY1 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0xE); - Vdp1Regs->userclipX2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x14); - Vdp1Regs->userclipY2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x16); - -#if 0 - vdp1clipxstart = Vdp1Regs->userclipX1; - vdp1clipxend = Vdp1Regs->userclipX2; - vdp1clipystart = Vdp1Regs->userclipY1; - vdp1clipyend = Vdp1Regs->userclipY2; - - // This needs work - if (vdp1clipxstart > Vdp1Regs->systemclipX1) - vdp1clipxstart = Vdp1Regs->userclipX1; - else - vdp1clipxstart = Vdp1Regs->systemclipX1; - - if (vdp1clipxend < Vdp1Regs->systemclipX2) - vdp1clipxend = Vdp1Regs->userclipX2; - else - vdp1clipxend = Vdp1Regs->systemclipX2; - - if (vdp1clipystart > Vdp1Regs->systemclipY1) - vdp1clipystart = Vdp1Regs->userclipY1; - else - vdp1clipystart = Vdp1Regs->systemclipY1; - - if (vdp1clipyend < Vdp1Regs->systemclipY2) - vdp1clipyend = Vdp1Regs->userclipY2; - else - vdp1clipyend = Vdp1Regs->systemclipY2; -#endif -} - -////////////////////////////////////////////////////////////////////////////// - -static void PushUserClipping(int mode) -{ - if (mode == 1) - { - VDP1LOG("User clipping mode 1 not implemented\n"); - return; - } - - vdp1clipxstart = Vdp1Regs->userclipX1; - vdp1clipxend = Vdp1Regs->userclipX2; - vdp1clipystart = Vdp1Regs->userclipY1; - vdp1clipyend = Vdp1Regs->userclipY2; - - // This needs work - if (vdp1clipxstart > Vdp1Regs->systemclipX1) - vdp1clipxstart = Vdp1Regs->userclipX1; - else - vdp1clipxstart = Vdp1Regs->systemclipX1; - - if (vdp1clipxend < Vdp1Regs->systemclipX2) - vdp1clipxend = Vdp1Regs->userclipX2; - else - vdp1clipxend = Vdp1Regs->systemclipX2; - - if (vdp1clipystart > Vdp1Regs->systemclipY1) - vdp1clipystart = Vdp1Regs->userclipY1; - else - vdp1clipystart = Vdp1Regs->systemclipY1; - - if (vdp1clipyend < Vdp1Regs->systemclipY2) - vdp1clipyend = Vdp1Regs->userclipY2; - else - vdp1clipyend = Vdp1Regs->systemclipY2; -} - -////////////////////////////////////////////////////////////////////////////// - -static void PopUserClipping(void) -{ - vdp1clipxstart = Vdp1Regs->systemclipX1; - vdp1clipxend = Vdp1Regs->systemclipX2; - vdp1clipystart = Vdp1Regs->systemclipY1; - vdp1clipyend = Vdp1Regs->systemclipY2; -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp1SystemClipping(void) -{ - Vdp1Regs->systemclipX1 = 0; - Vdp1Regs->systemclipY1 = 0; - Vdp1Regs->systemclipX2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x14); - Vdp1Regs->systemclipY2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x16); - - vdp1clipxstart = Vdp1Regs->systemclipX1; - vdp1clipxend = Vdp1Regs->systemclipX2; - vdp1clipystart = Vdp1Regs->systemclipY1; - vdp1clipyend = Vdp1Regs->systemclipY2; -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp1LocalCoordinate(void) -{ - Vdp1Regs->localX = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0xC); - Vdp1Regs->localY = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0xE); -} - -////////////////////////////////////////////////////////////////////////////// - -int VIDGCDVdp2Reset(void) -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp2DrawStart(void) -{ - int wctl; - Vdp2DrawBackScreen(); - - vdp1draw_info.prioritytable[0] = Vdp2Regs->PRISA & 0x7; - vdp1draw_info.prioritytable[1] = (Vdp2Regs->PRISA >> 8) & 0x7; - vdp1draw_info.prioritytable[2] = Vdp2Regs->PRISB & 0x7; - vdp1draw_info.prioritytable[3] = (Vdp2Regs->PRISB >> 8) & 0x7; - vdp1draw_info.prioritytable[4] = Vdp2Regs->PRISC & 0x7; - vdp1draw_info.prioritytable[5] = (Vdp2Regs->PRISC >> 8) & 0x7; - vdp1draw_info.prioritytable[6] = Vdp2Regs->PRISD & 0x7; - vdp1draw_info.prioritytable[7] = (Vdp2Regs->PRISD >> 8) & 0x7; - - vdp1draw_info.coloroffset = (Vdp2Regs->CRAOFB & 0x70) << 4; - vdp1spritetype = Vdp2Regs->SPCTL & 0xF; - - if(Vdp2Regs->CLOFEN & 0x40) { - // color offset enable - if(Vdp2Regs->CLOFSL & 0x40) { - // color offset B - vdp1draw_info.info.cor = Vdp2Regs->COBR & 0xFF; - if(Vdp2Regs->COBR & 0x100) - vdp1draw_info.info.cor |= 0xFFFFFF00; - - vdp1draw_info.info.cog = Vdp2Regs->COBG & 0xFF; - if(Vdp2Regs->COBG & 0x100) - vdp1draw_info.info.cog |= 0xFFFFFF00; - - vdp1draw_info.info.cob = Vdp2Regs->COBB & 0xFF; - if(Vdp2Regs->COBB & 0x100) - vdp1draw_info.info.cob |= 0xFFFFFF00; - } - else { - // color offset A - vdp1draw_info.info.cor = Vdp2Regs->COAR & 0xFF; - if(Vdp2Regs->COAR & 0x100) - vdp1draw_info.info.cor |= 0xFFFFFF00; - - vdp1draw_info.info.cog = Vdp2Regs->COAG & 0xFF; - if(Vdp2Regs->COAG & 0x100) - vdp1draw_info.info.cog |= 0xFFFFFF00; - - vdp1draw_info.info.cob = Vdp2Regs->COAB & 0xFF; - if(Vdp2Regs->COAB & 0x100) - vdp1draw_info.info.cob |= 0xFFFFFF00; - } - - if(vdp1draw_info.info.cor == 0 && vdp1draw_info.info.cog == 0 && vdp1draw_info.info.cob == 0) { - if(Vdp2Regs->CCCTL & 0x40) - vdp1draw_info.info.PostPixelFetchCalc = &DoColorCalc; - else - vdp1draw_info.info.PostPixelFetchCalc = &DoNothing; - } - else { - if(Vdp2Regs->CCCTL & 0x40) - vdp1draw_info.info.PostPixelFetchCalc = &DoColorCalcWithColorOffset; - else - vdp1draw_info.info.PostPixelFetchCalc = &DoColorOffset; - } - } - else { // color offset disable - if(Vdp2Regs->CCCTL & 0x40) - vdp1draw_info.info.PostPixelFetchCalc = &DoColorCalc; - else - vdp1draw_info.info.PostPixelFetchCalc = &DoNothing; - } - - wctl = Vdp2Regs->WCTLC >> 8; - vdp1draw_info.clip[0].xstart = vdp1draw_info.clip[0].ystart = 0; - vdp1draw_info.clip[0].xend = vdp1draw_info.clip[0].yend = 0; - vdp1draw_info.clip[1].xstart = vdp1draw_info.clip[1].ystart = 0; - vdp1draw_info.clip[1].xend = vdp1draw_info.clip[1].yend = 0; - ReadWindowData(wctl, vdp1draw_info.clip); - vdp1draw_info.linewnd0addr = vdp1draw_info.linewnd1addr = 0; - ReadLineWindowData(&vdp1draw_info.islinewindow, wctl, &vdp1draw_info.linewnd0addr, &vdp1draw_info.linewnd1addr); -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp2DrawEnd(void) -{ -#ifndef CRAB_REWRITE - int i, i2; - u16 pixel; - u8 prioritytable[8]; - u32 vdp1coloroffset; - int colormode = Vdp2Regs->SPCTL & 0x20; - vdp2draw_struct info; - u32 *dst=dispbuffer; - u32 *vdp2src=vdp2framebuffer; - int islinewindow; - clipping_struct clip[2]; - u32 linewnd0addr, linewnd1addr; - int wctl; - - // Figure out whether to draw vdp1 framebuffer or vdp2 framebuffer pixels - // based on priority - if (Vdp1External.disptoggle) - { - prioritytable[0] = Vdp2Regs->PRISA & 0x7; - prioritytable[1] = (Vdp2Regs->PRISA >> 8) & 0x7; - prioritytable[2] = Vdp2Regs->PRISB & 0x7; - prioritytable[3] = (Vdp2Regs->PRISB >> 8) & 0x7; - prioritytable[4] = Vdp2Regs->PRISC & 0x7; - prioritytable[5] = (Vdp2Regs->PRISC >> 8) & 0x7; - prioritytable[6] = Vdp2Regs->PRISD & 0x7; - prioritytable[7] = (Vdp2Regs->PRISD >> 8) & 0x7; - - vdp1coloroffset = (Vdp2Regs->CRAOFB & 0x70) << 4; - vdp1spritetype = Vdp2Regs->SPCTL & 0xF; - - if (Vdp2Regs->CLOFEN & 0x40) - { - // color offset enable - if (Vdp2Regs->CLOFSL & 0x40) - { - // color offset B - info.cor = Vdp2Regs->COBR & 0xFF; - if (Vdp2Regs->COBR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COBG & 0xFF; - if (Vdp2Regs->COBG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COBB & 0xFF; - if (Vdp2Regs->COBB & 0x100) - info.cob |= 0xFFFFFF00; - } - else - { - // color offset A - info.cor = Vdp2Regs->COAR & 0xFF; - if (Vdp2Regs->COAR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COAG & 0xFF; - if (Vdp2Regs->COAG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COAB & 0xFF; - if (Vdp2Regs->COAB & 0x100) - info.cob |= 0xFFFFFF00; - } - - if (info.cor == 0 && info.cog == 0 && info.cob == 0) - { - if (Vdp2Regs->CCCTL & 0x40) - info.PostPixelFetchCalc = &DoColorCalc; - else - info.PostPixelFetchCalc = &DoNothing; - } - else - { - if (Vdp2Regs->CCCTL & 0x40) - info.PostPixelFetchCalc = &DoColorCalcWithColorOffset; - else - info.PostPixelFetchCalc = &DoColorOffset; - } - } - else // color offset disable - { - if (Vdp2Regs->CCCTL & 0x40) - info.PostPixelFetchCalc = &DoColorCalc; - else - info.PostPixelFetchCalc = &DoNothing; - } - - wctl = Vdp2Regs->WCTLC >> 8; - clip[0].xstart = clip[0].ystart = clip[0].xend = clip[0].yend = 0; - clip[1].xstart = clip[1].ystart = clip[1].xend = clip[1].yend = 0; - ReadWindowData(wctl, clip); - linewnd0addr = linewnd1addr = 0; - ReadLineWindowData(&islinewindow, wctl, &linewnd0addr, &linewnd1addr); - - for (i2 = 0; i2 < vdp2height; i2++) - { - ReadLineWindowClip(islinewindow, clip, &linewnd0addr, &linewnd1addr); - - for (i = 0; i < vdp2width; i++) - { - // See if screen position is clipped, if it isn't, continue - // Window 0 - if (!TestWindow(wctl, 0x2, 0x1, &clip[0], i, i2)) - { - dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - vdp2src++; - dst++; - continue; - } - - // Window 1 - if (!TestWindow(wctl, 0x8, 0x4, &clip[1], i, i2)) - { - vdp2src++; - dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - dst++; - continue; - } - - if (vdp1pixelsize == 2) - { - // 16-bit pixel size - pixel = ((u16 *)vdp1frontframebuffer)[(i2 * vdp1width) + i]; - - if (pixel == 0) - dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - else if (pixel & 0x8000 && colormode) - { - // 16 BPP - if (prioritytable[0] >= Vdp2GetPixelPriority(vdp2src[0])) - { - // if pixel is 0x8000, only draw pixel if sprite window - // is disabled/sprite type 2-7. sprite types 0 and 1 are - // -always- drawn and sprite types 8-F are always - // transparent. - if (pixel != 0x8000 || vdp1spritetype < 2 || (vdp1spritetype < 8 && !(Vdp2Regs->SPCTL & 0x10))) - dst[0] = info.PostPixelFetchCalc(&info, COLSAT2YAB16(0xFF, pixel)); - else - dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - } - else - dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - } - else - { - // Color bank - int priority; - int shadow; - int colorcalc; - priority = 0; // Avoid compiler warning - Vdp1ProcessSpritePixel(vdp1spritetype, &pixel, &shadow, &priority, &colorcalc); - if (prioritytable[priority] >= Vdp2GetPixelPriority(vdp2src[0])) - dst[0] = info.PostPixelFetchCalc(&info, COLSAT2YAB32(0xFF, Vdp2ColorRamGetColor(vdp1coloroffset + pixel))); - else - dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - } - } - else - { - // 8-bit pixel size - pixel = vdp1frontframebuffer[(i2 * vdp1width) + i]; - - if (pixel == 0) - dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - else - { - // Color bank(fix me) - LOG("8-bit Color Bank draw - %02X\n", pixel); - dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - } - } - vdp2src++; - dst++; - } - } - } - else - { - // Render VDP2 only - for (i = 0; i < (vdp2width*vdp2height); i++) - dispbuffer[i] = COLSATSTRIPPRIORITY(vdp2framebuffer[i]); - } -#endif - - VIDGCDVdp1SwapFrameBuffer(); - - if (OSDUseBuffer()) - OSDDisplayMessages(dispbuffer, vdp2width, vdp2height); - -#ifdef USE_OPENGL - glRasterPos2i(0, 0); - glPixelZoom((float)outputwidth / (float)vdp2width, 0 - ((float)outputheight / (float)vdp2height)); -#ifndef CRAB_REWRITE - glDrawPixels(vdp2width, vdp2height, GL_RGBA, GL_UNSIGNED_BYTE, dispbuffer); -#else - glDisable(GL_BLEND); - glDrawPixels(vdp2width, vdp2height, GL_RGBA, GL_UNSIGNED_BYTE, vdp2framebuffer); -#endif - - if (! OSDUseBuffer()) - OSDDisplayMessages(NULL, -1, -1); -#endif - - YuiSwapBuffers(); -} - -/* FIXME: Support Vdp1 8-bit mode sometime... */ -static void Vdp1DrawPriority(int prio) { - int colormode = Vdp2Regs->SPCTL & 0x20; - vdp2draw_struct *info = &vdp1draw_info.info; - int islinewindow = vdp1draw_info.islinewindow; - int wctl= Vdp2Regs->WCTLC >> 8; - - // Figure out whether to draw vdp1 framebuffer or vdp2 framebuffer pixels - // based on priority - if(Vdp1External.disptoggle) { - dispatch_apply(vdp2height, dispatch_get_global_queue(2, 0), ^(size_t i2) { - u16 *fb16 = (u16 *)(vdp1frontframebuffer) + (i2 * vdp1width); - u32 *fb = vdp2framebuffer + (i2 * vdp2width); - int i; - u16 pixel; - u32 linewnd0addr = vdp1draw_info.linewnd0addr; - u32 linewnd1addr = vdp1draw_info.linewnd1addr; - - ReadLineWindowClip(islinewindow, vdp1draw_info.clip, &linewnd0addr, &linewnd1addr); - - for(i = 0; i < vdp2width; ++i, ++fb16, ++fb) { - // See if screen position is clipped, if it isn't, continue - // Window 0 - if(!TestWindow(wctl, 0x2, 0x1, &vdp1draw_info.clip[0], i, i2)) { - continue; - } - - // Window 1 - if(!TestWindow(wctl, 0x8, 0x4, &vdp1draw_info.clip[1], i, i2)) { - continue; - } - - if (vdp1pixelsize == 2) { - // 16-bit pixel size - pixel = *fb16; - - if(pixel & 0x8000 && colormode && vdp1draw_info.prioritytable[0] == prio && - prio >= Vdp2GetPixelPriority(*fb)) { - // 16 BPP - // if pixel is 0x8000, only draw pixel if sprite window - // is disabled/sprite type 2-7. sprite types 0 and 1 are - // -always- drawn and sprite types 8-F are always - // transparent. - if(pixel != 0x8000 || vdp1spritetype < 2 || (vdp1spritetype < 8 && !(Vdp2Regs->SPCTL & 0x10))) - *fb = info->PostPixelFetchCalc(info, COLSAT2YAB16(0xFF, pixel)); - } - else if(pixel) { - // Color bank - int priority; - int shadow; - int colorcalc; - priority = 0; // Avoid compiler warning - Vdp1ProcessSpritePixel(vdp1spritetype, &pixel, &shadow, &priority, &colorcalc); - priority = vdp1draw_info.prioritytable[priority]; - if(priority == prio && priority >= Vdp2GetPixelPriority(*fb)) - *fb = info->PostPixelFetchCalc(info, COLSAT2YAB32(0xFF, Vdp2ColorRamGetColor(vdp1draw_info.coloroffset + pixel))); - } - } - //else - //{ - // // 8-bit pixel size - // pixel = vdp1frontframebuffer[(i2 * vdp1width) + i]; - // - // if (pixel == 0) - // dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - // else - // { - // // Color bank(fix me) - // LOG("8-bit Color Bank draw - %02X\n", pixel); - // dst[0] = COLSATSTRIPPRIORITY(vdp2src[0]); - // } - //} - } - }); - } -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp2DrawScreens(void) -{ - int i; - - /* Draw all the screens, from the lowest priority one forward. */ - for(i = 1; i < 8; ++i) - { - if (nbg3priority == i) - Vdp2DrawNBG3(); - if (nbg2priority == i) - Vdp2DrawNBG2(); - if (nbg1priority == i) - Vdp2DrawNBG1(); - if (nbg0priority == i) - Vdp2DrawNBG0(); - if (rbg0priority == i) - Vdp2DrawRBG0(); - - /* Draw anything in VDP1 that should be shown at this priority level. */ - if(vdp1draw_info.priosused[i]) - Vdp1DrawPriority(i); - vdp1draw_info.priosused[i] = 0; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp2SetResolution(u16 TVMD) -{ - // This needs some work - - // Horizontal Resolution - switch (TVMD & 0x7) - { - case 0: - vdp2width = 320; - resxratio=1; - break; - case 1: - vdp2width = 352; - resxratio=1; - break; - case 2: // 640 - vdp2width = 320; - resxratio=2; - break; - case 3: // 704 - vdp2width = 352; - resxratio=2; - break; - case 4: - vdp2width = 320; - resxratio=1; - break; - case 5: - vdp2width = 352; - resxratio=1; - break; - case 6: // 640 - vdp2width = 320; - resxratio=2; - break; - case 7: // 704 - vdp2width = 352; - resxratio=2; - break; - } - - // Vertical Resolution - switch ((TVMD >> 4) & 0x3) - { - case 0: - vdp2height = 224; - break; - case 1: - vdp2height = 240; - break; - case 2: - vdp2height = 256; - break; - default: break; - } - resyratio=1; - - // Check for interlace - switch ((TVMD >> 6) & 0x3) - { - case 3: // Double-density Interlace -// vdp2height *= 2; - resyratio=2; - break; - case 2: // Single-density Interlace - case 0: // Non-interlace - default: break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL VIDGCDVdp2SetPriorityNBG0(int priority) -{ - nbg0priority = priority; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL VIDGCDVdp2SetPriorityNBG1(int priority) -{ - nbg1priority = priority; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL VIDGCDVdp2SetPriorityNBG2(int priority) -{ - nbg2priority = priority; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL VIDGCDVdp2SetPriorityNBG3(int priority) -{ - nbg3priority = priority; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL VIDGCDVdp2SetPriorityRBG0(int priority) -{ - rbg0priority = priority; -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDOnScreenDebugMessage(char *string, ...) -{ - va_list arglist; - - va_start(arglist, string); - vsprintf(message, string, arglist); - va_end(arglist); - msglength = strlen(message); -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDGetScreenSize(int *width, int *height) -{ - *width = vdp2width; - *height = vdp2height; -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp1SwapFrameBuffer(void) -{ - u8 *temp = vdp1frontframebuffer; - vdp1frontframebuffer = vdp1backframebuffer; - vdp1backframebuffer = temp; -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDVdp1EraseFrameBuffer(void) -{ - int s, s2; - int w,h; - - h = (Vdp1Regs->EWRR & 0x1FF) + 1; - if (h > vdp1height) h = vdp1height; - w = ((Vdp1Regs->EWRR >> 6) & 0x3F8) + 8; - if (w > vdp1width) w = vdp1width; - - s = Vdp1Regs->EWLR & 0x1FF; - s2 = (Vdp1Regs->EWLR >> 6) & 0x1F8; - - dispatch_apply(h - s, dispatch_get_global_queue(2, 0), ^(size_t i2) { - int i; - i2 += s; - for (i = s2; i < w; i++) { - ((u16 *)vdp1backframebuffer)[(i2 * vdp1width) + i] = Vdp1Regs->EWDR; - } - }); -} - -////////////////////////////////////////////////////////////////////////////// - -void VIDGCDGetGlSize(int *width, int *height) -{ -#ifdef USE_OPENGL - *width = outputwidth; - *height = outputheight; -#else - *width = vdp2width; - *height = vdp2height; -#endif -} diff --git a/yabause/src/cocoa/vidgcd.h b/yabause/src/cocoa/vidgcd.h deleted file mode 100644 index 99ada32a99..0000000000 --- a/yabause/src/cocoa/vidgcd.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef VIDGCD_H -#define VIDGCD_H - -#include "vdp1.h" - -#define VIDCORE_GCD 10 - -extern VideoInterface_struct VIDGCD; - -#endif diff --git a/yabause/src/coffelf.c b/yabause/src/coffelf.c deleted file mode 100644 index 54e53c1f3e..0000000000 --- a/yabause/src/coffelf.c +++ /dev/null @@ -1,388 +0,0 @@ -/* Copyright 2007 Theo Berkau - Copyright 2009 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "core.h" -#include "debug.h" -#include "sh2core.h" -#include "yabause.h" -#include "coffelf.h" - -typedef struct -{ - u8 magic[2]; - u16 numsections; - u32 timedate; - u32 symtabptr; - u32 numsymtabs; - u16 optheader; - u16 flags; -} coff_header_struct; - -typedef struct -{ - u8 magic[2]; - u16 versionstamp; - u32 textsize; - u32 datasize; - u32 bsssize; - u32 entrypoint; - u32 textaddr; - u32 dataaddr; -} aout_header_struct; - -typedef struct -{ - s8 name[8]; - u32 physaddr; - u32 virtaddr; - u32 sectionsize; - u32 sectionptr; - u32 relptr; - u32 linenoptr; - u16 numreloc; - u16 numlineno; - u32 flags; -} section_header_struct; - -typedef struct -{ - u8 ident[16]; - u16 type; - u16 machine; - u32 version; - u32 entry; - u32 phdr; - u32 shdr; - u32 flags; - u16 hdrsize; - u16 phdrsize; - u16 phdrcount; - u16 shdrsize; - u16 shdrcount; - u16 shdrstridx; -} elf_header_struct; - -#define ELF_MACHINE_SH 42 - -typedef struct -{ - u32 name; - u32 type; - u32 flags; - u32 addr; - u32 offs; - u32 size; - u32 link; - u32 inf; - u32 align; - u32 esize; -} elf_section_header_struct; - -#define ELF_SECTION_TYPE_NODATA 8 -#define ELF_SECTION_FLAG_ALLOC 2 - -#define WordSwap(x) x = ((x & 0xFF00) >> 8) + ((x & 0x00FF) << 8); -#define DoubleWordSwap(x) x = (((x & 0xFF000000) >> 24) + \ - ((x & 0x00FF0000) >> 8) + \ - ((x & 0x0000FF00) << 8) + \ - ((x & 0x000000FF) << 24)); - -////////////////////////////////////////////////////////////////////////////// - -int MappedMemoryLoadCoff(const char *filename) -{ - coff_header_struct coff_header; - aout_header_struct aout_header; - section_header_struct *section_headers=NULL; - FILE *fp; - u8 *buffer; - u32 i, j; - - if ((fp = fopen(filename, "rb")) == NULL) - return -1; - - fread((void *)&coff_header, sizeof(coff_header), 1, fp); -#ifndef WORDS_BIGENDIAN - WordSwap(coff_header.numsections); - DoubleWordSwap(coff_header.timedate); - DoubleWordSwap(coff_header.timedate); - DoubleWordSwap(coff_header.symtabptr); - DoubleWordSwap(coff_header.numsymtabs); - WordSwap(coff_header.optheader); - WordSwap(coff_header.flags); -#endif - - if (coff_header.magic[0] != 0x05 || coff_header.magic[1] != 0x00 || - coff_header.optheader != sizeof(aout_header)) - { - // Not SH COFF or is missing the optional header - fclose(fp); - return -1; - } - - fread((void *)&aout_header, sizeof(aout_header), 1, fp); -#ifndef WORDS_BIGENDIAN - WordSwap(aout_header.versionstamp); - DoubleWordSwap(aout_header.textsize); - DoubleWordSwap(aout_header.datasize); - DoubleWordSwap(aout_header.bsssize); - DoubleWordSwap(aout_header.entrypoint); - DoubleWordSwap(aout_header.textaddr); - DoubleWordSwap(aout_header.dataaddr); -#endif - - // Read in each section header - if ((section_headers = (section_header_struct *)malloc(sizeof(section_header_struct) * coff_header.numsections)) == NULL) - { - fclose(fp); - return -2; - } - - // read in section headers - for (i = 0; i < coff_header.numsections; i++) - { - fread((void *)§ion_headers[i], sizeof(section_header_struct), 1, fp); -#ifndef WORDS_BIGENDIAN - DoubleWordSwap(section_headers[i].physaddr); - DoubleWordSwap(section_headers[i].virtaddr); - DoubleWordSwap(section_headers[i].sectionsize); - DoubleWordSwap(section_headers[i].sectionptr); - DoubleWordSwap(section_headers[i].relptr); - DoubleWordSwap(section_headers[i].linenoptr); - WordSwap(section_headers[i].numreloc); - WordSwap(section_headers[i].numlineno); - DoubleWordSwap(section_headers[i].flags); -#endif - } - - YabauseResetNoLoad(); - - // Setup the vector table area, etc. - YabauseSpeedySetup(); - - // Read in sections, load them to ram - for (i = 0; i < coff_header.numsections; i++) - { - if (section_headers[i].sectionsize == 0 || - section_headers[i].sectionptr == 0) - // Skip to the next section - continue; - - if ((buffer = (u8 *)malloc(section_headers[i].sectionsize)) == NULL) - { - fclose(fp); - free(section_headers); - return -2; - } - - fseek(fp, section_headers[i].sectionptr, SEEK_SET); - fread((void *)buffer, 1, section_headers[i].sectionsize, fp); - - for (j = 0; j < section_headers[i].sectionsize; j++) - MappedMemoryWriteByte(section_headers[i].physaddr+j, buffer[j]); - SH2WriteNotify(section_headers[i].physaddr, - section_headers[i].sectionsize); - - free(buffer); - } - - // Clean up - free(section_headers); - fclose(fp); - - SH2GetRegisters(MSH2, &MSH2->regs); - MSH2->regs.PC = aout_header.entrypoint; - SH2SetRegisters(MSH2, &MSH2->regs); - return 0; -} - - -////////////////////////////////////////////////////////////////////////////// - -int MappedMemoryLoadElf(const char *filename) -{ - elf_header_struct elf_hdr; - elf_section_header_struct *sections = NULL; - FILE *fp; - u16 i; - u32 j; - u8 *buffer; - - fp = fopen(filename, "rb"); - - if(fp == NULL) - return -1; - - fread(&elf_hdr, sizeof(elf_header_struct), 1, fp); - - if(elf_hdr.ident[0] != 0x7F || elf_hdr.ident[1] != 'E' || - elf_hdr.ident[2] != 'L' || elf_hdr.ident[3] != 'F' || - elf_hdr.ident[4] != 1) - { - /* Doesn't appear to be a valid ELF file. */ - fclose(fp); - return -1; - } - - if(elf_hdr.ident[5] != 2) - { - /* Doesn't appear to be a big-endian file. */ - fclose(fp); - return -1; - } - -#ifndef WORDS_BIGENDIAN - WordSwap(elf_hdr.type); - WordSwap(elf_hdr.machine); - DoubleWordSwap(elf_hdr.version); - DoubleWordSwap(elf_hdr.entry); - DoubleWordSwap(elf_hdr.phdr); - DoubleWordSwap(elf_hdr.shdr); - DoubleWordSwap(elf_hdr.flags); - WordSwap(elf_hdr.hdrsize); - WordSwap(elf_hdr.phdrsize); - WordSwap(elf_hdr.phdrcount); - WordSwap(elf_hdr.shdrsize); - WordSwap(elf_hdr.shdrcount); - WordSwap(elf_hdr.shdrstridx); -#endif - - LOG("Loading ELF file %s\n", filename); - LOG("Type: %d\n", elf_hdr.type); - LOG("Machine code: %d\n", elf_hdr.machine); - LOG("Version: %d\n", elf_hdr.version); - LOG("Entry point: 0x%08X\n", elf_hdr.entry); - LOG("Program header offset: %d\n", elf_hdr.phdr); - LOG("Section header offset: %d\n", elf_hdr.shdr); - LOG("Flags: %d\n", elf_hdr.flags); - LOG("ELF Header Size: %d\n", elf_hdr.hdrsize); - LOG("Program header size: %d\n", elf_hdr.phdrsize); - LOG("Program header count: %d\n", elf_hdr.phdrcount); - LOG("Section header size: %d\n", elf_hdr.shdrsize); - LOG("Section header count: %d\n", elf_hdr.shdrcount); - LOG("String table section: %d\n", elf_hdr.shdrstridx); - - if(elf_hdr.machine != ELF_MACHINE_SH) - { - /* Not a SuperH ELF file. */ - fclose(fp); - return -1; - } - - /* Allocate space for the section headers. */ - sections = - (elf_section_header_struct *)malloc(sizeof(elf_section_header_struct) * - elf_hdr.shdrcount); - if(sections == NULL) - { - fclose(fp); - return -2; - } - - /* Look at the actual section headers. */ - fseek(fp, elf_hdr.shdr, SEEK_SET); - - /* Read in each section header. */ - for(i = 0; i < elf_hdr.shdrcount; ++i) - { - fread(sections + i, sizeof(elf_section_header_struct), 1, fp); -#ifndef WORDS_BIGENDIAN - DoubleWordSwap(sections[i].name); - DoubleWordSwap(sections[i].type); - DoubleWordSwap(sections[i].flags); - DoubleWordSwap(sections[i].addr); - DoubleWordSwap(sections[i].offs); - DoubleWordSwap(sections[i].size); - DoubleWordSwap(sections[i].link); - DoubleWordSwap(sections[i].inf); - DoubleWordSwap(sections[i].align); - DoubleWordSwap(sections[i].esize); -#endif - - LOG("Section header %d:\n", i); - LOG("Name index: %d\n", sections[i].name); - LOG("Type: %d\n", sections[i].type); - LOG("Flags: 0x%X\n", sections[i].flags); - LOG("In-memory address: 0x%08X\n", sections[i].addr); - LOG("In-file offset: %d\n", sections[i].offs); - LOG("Size: %d\n", sections[i].size); - LOG("Link field: %d\n", sections[i].link); - LOG("Info field: %d\n", sections[i].inf); - LOG("Alignment: %d\n", sections[i].align); - LOG("Entry size: %d\n", sections[i].esize); - } - - YabauseResetNoLoad(); - - /* Set up the vector table area, etc. */ - YabauseSpeedySetup(); - - /* Read in the sections and load them to RAM. */ - for(i = 0; i < elf_hdr.shdrcount; ++i) - { - /* Does the header request actual storage for this section? */ - if(sections[i].flags & ELF_SECTION_FLAG_ALLOC) - { - /* Check if the section contains data, or if its just a marker for a - section of zero bytes. */ - if(sections[i].type == ELF_SECTION_TYPE_NODATA) - { - for(j = 0; j < sections[i].size; ++j) - { - MappedMemoryWriteByte(sections[i].addr + j, 0); - } - } - else - { - buffer = (u8 *)malloc(sections[i].size); - - if(buffer == NULL) - { - fclose(fp); - free(sections); - return -2; - } - - fseek(fp, sections[i].offs, SEEK_SET); - fread(buffer, 1, sections[i].size, fp); - - for(j = 0; j < sections[i].size; ++j) - { - MappedMemoryWriteByte(sections[i].addr + j, buffer[j]); - } - - free(buffer); - } - } - } - - /* Clean up. */ - free(sections); - fclose(fp); - - /* Set up our entry point. */ - SH2GetRegisters(MSH2, &MSH2->regs); - MSH2->regs.PC = elf_hdr.entry; - SH2SetRegisters(MSH2, &MSH2->regs); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// diff --git a/yabause/src/coffelf.h b/yabause/src/coffelf.h deleted file mode 100644 index 8085982ba9..0000000000 --- a/yabause/src/coffelf.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2007 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef COFFELF_H -#define COFFELF_H - -int MappedMemoryLoadCoff(const char *filename); -int MappedMemoryLoadElf(const char *filename); - -#endif - diff --git a/yabause/src/config.h.in b/yabause/src/config.h.in deleted file mode 100644 index afea5ec0a2..0000000000 --- a/yabause/src/config.h.in +++ /dev/null @@ -1,3 +0,0 @@ -#cmakedefine HAVE_C68K 1 -#cmakedefine HAVE_Q68 1 -#cmakedefine SH2_DYNAREC 1 diff --git a/yabause/src/core.h b/yabause/src/core.h deleted file mode 100644 index 78a01b6fce..0000000000 --- a/yabause/src/core.h +++ /dev/null @@ -1,298 +0,0 @@ -/* Copyright 2005 Guillaume Duhamel - Copyright 2005-2006 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CORE_H -#define CORE_H - -#include -#include - -#ifndef ALIGNED -#ifdef _MSC_VER -#define ALIGNED(x) __declspec(align(x)) -#else -#define ALIGNED(x) __attribute__((aligned(x))) -#endif -#endif - -#ifndef STDCALL -#ifdef _MSC_VER -#define STDCALL __stdcall -#else -#define STDCALL -#endif -#endif - -#ifndef FASTCALL -#ifdef __MINGW32__ -#define FASTCALL __attribute__((fastcall)) -#elif defined (__i386__) -#define FASTCALL __attribute__((regparm(3))) -#else -#define FASTCALL -#endif -#endif - -/* When building multiple arches on OS X you must use the compiler- - provided endian flags instead of the one provided by autoconf */ -#if defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__) - #undef WORDS_BIGENDIAN - #ifdef __BIG_ENDIAN__ - #define WORDS_BIGENDIAN - #endif -#endif - - -#ifndef INLINE -#ifdef _MSC_VER -#define INLINE _inline -#else -#define INLINE inline -#endif -#endif - -#ifdef GEKKO -/* Wii have both stdint.h and "yabause" definitions of fixed -size types */ -#include -typedef unsigned long pointer; - -#else /* ! GEKKO */ - -#ifdef HAVE_STDINT_H - -#include -typedef uint8_t u8; -typedef int8_t s8; -typedef uint16_t u16; -typedef int16_t s16; -typedef uint32_t u32; -typedef int32_t s32; -typedef uint64_t u64; -typedef int64_t s64; -typedef uintptr_t pointer; - -#else // !HAVE_STDINT_H - -typedef unsigned char u8; -typedef unsigned short u16; - -typedef signed char s8; -typedef signed short s16; - -#if defined(__LP64__) -// Generic 64-bit -typedef unsigned int u32; -typedef unsigned long u64; -typedef unsigned long pointer; - -typedef signed int s32; -typedef signed long s64; - -#elif defined(_MSC_VER) -typedef unsigned long u32; -typedef unsigned __int64 u64; -typedef unsigned long long u64; -#ifdef _WIN64 -typedef __int64 pointer; -#else -typedef unsigned long pointer; -#endif - -typedef signed long s32; -typedef __int64 s64; -typedef signed long long s64; - -#else -// 32-bit Linux GCC/MINGW/etc. -typedef unsigned long u32; -typedef unsigned long long u64; -typedef unsigned long pointer; - -typedef signed long s32; -typedef signed long long s64; -#endif - -#endif // !HAVE_STDINT_H - -#endif // !GEKKO - -typedef struct { - unsigned int size; - unsigned int done; -} IOCheck_struct; - -static INLINE void ywrite(IOCheck_struct * check, void * ptr, size_t size, size_t nmemb, FILE * stream) { - check->done += (unsigned int)fwrite(ptr, size, nmemb, stream); - check->size += (unsigned int)nmemb; -} - -static INLINE void yread(IOCheck_struct * check, void * ptr, size_t size, size_t nmemb, FILE * stream) { - check->done += (unsigned int)fread(ptr, size, nmemb, stream); - check->size += (unsigned int)nmemb; -} - -static INLINE int StateWriteHeader(FILE *fp, const char *name, int version) { - IOCheck_struct check; - fprintf(fp, "%s", name); - check.done = 0; - check.size = 0; - ywrite(&check, (void *)&version, sizeof(version), 1, fp); - ywrite(&check, (void *)&version, sizeof(version), 1, fp); // place holder for size - return (check.done == check.size) ? ftell(fp) : -1; -} - -static INLINE int StateFinishHeader(FILE *fp, int offset) { - /* - IOCheck_struct check; - int size = 0; - size = ftell(fp) - offset; - fseek(fp, offset - 4, SEEK_SET); - check.done = 0; - check.size = 0; - ywrite(&check, (void *)&size, sizeof(size), 1, fp); // write true size - fseek(fp, 0, SEEK_END); - return (check.done == check.size) ? (size + 12) : -1; - */ - return 0; -} - -static INLINE int StateCheckRetrieveHeader(FILE *fp, const char *name, int *version, int *size) { - char id[4]; - size_t ret; - - if ((ret = fread((void *)id, 1, 4, fp)) != 4) - return -1; - - if (strncmp(name, id, 4) != 0) - return -2; - - if ((ret = fread((void *)version, 4, 1, fp)) != 1) - return -1; - - if (fread((void *)size, 4, 1, fp) != 1) - return -1; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -// Terrible, but I'm not sure how to do the equivalent in inline -#ifdef HAVE_C99_VARIADIC_MACROS -#define AddString(s, ...) \ - { \ - sprintf(s, __VA_ARGS__); \ - s += strlen(s); \ - } -#else -#define AddString(s, r...) \ - { \ - sprintf(s, ## r); \ - s += strlen(s); \ - } -#endif - -////////////////////////////////////////////////////////////////////////////// - -#ifdef HAVE_LIBMINI18N -#include "mini18n.h" -#else -#ifndef _ -#define _(a) (a) -#endif -#endif - -////////////////////////////////////////////////////////////////////////////// - -/* Minimum/maximum values */ - -#undef MIN -#undef MAX -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -////////////////////////////////////////////////////////////////////////////// - -/* - * BSWAP16(x) swaps two bytes in a 16-bit value (AABB -> BBAA) or adjacent - * bytes in a 32-bit value (AABBCCDD -> BBAADDCC). - * - * BSWAP32(x) reverses four bytes in a 32-bit value (AABBCCDD -> DDCCBBAA). - * - * WSWAP32(x) swaps two 16-bit words in a 32-bit value (AABBCCDD -> CCDDAABB). - * - * Any of these can be left undefined if there is no platform-specific - * optimization for them; the defaults below will then be used instead. - */ - -#ifdef PSP -# define BSWAP16(x) ((typeof(x)) __builtin_allegrex_wsbh((x))) -# define BSWAP32(x) ((typeof(x)) __builtin_allegrex_wsbw((x))) -# define WSWAP32(x) ((typeof(x)) __builtin_allegrex_rotr((x), 16)) -#endif - -/* Defaults: */ - -#ifndef BSWAP16 -# define BSWAP16(x) (((u32)(x)>>8 & 0x00FF00FF) | ((u32)(x) & 0x00FF00FF) << 8) -#endif -#ifndef BSWAP32 -# define BSWAP32(x) ((u32)(x)>>24 | ((u32)(x)>>8 & 0xFF00) | ((u32)(x) & 0xFF00)<<8 | (u32)(x)<<24) -#endif -#ifndef WSWAP32 -# define WSWAP32(x) ((u32)(x)>>16 | (u32)(x)<<16) -#endif - -////////////////////////////////////////////////////////////////////////////// - -#ifdef __GNUC__ - -#define UNUSED __attribute ((unused)) - -#ifdef DEBUG -#define USED_IF_DEBUG -#else -#define USED_IF_DEBUG __attribute ((unused)) -#endif - -#ifdef SMPC_DEBUG -#define USED_IF_SMPC_DEBUG -#else -#define USED_IF_SMPC_DEBUG __attribute ((unused)) -#endif - -/* LIKELY(x) indicates that x is likely to be true (nonzero); - * UNLIKELY(x) indicates that x is likely to be false (zero). - * Use like: "if (UNLIKELY(a < b)) {...}" */ -#define LIKELY(x) (__builtin_expect(!!(x), 1)) -#define UNLIKELY(x) (__builtin_expect(!!(x), 0)) - -#else - -#define UNUSED -#define USED_IF_DEBUG -#define USED_IF_SMPC_DEBUG -#define LIKELY(x) (x) -#define UNLIKELY(x) (x) - -#endif - -#endif diff --git a/yabause/src/cs0.c b/yabause/src/cs0.c deleted file mode 100644 index d5299f4d7d..0000000000 --- a/yabause/src/cs0.c +++ /dev/null @@ -1,1526 +0,0 @@ -/* Copyright 2004-2005 Theo Berkau - Copyright 2006 Ex-Cyber - Copyright 2005 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include "cs0.h" -#include "error.h" - -cartridge_struct *CartridgeArea; - -////////////////////////////////////////////////////////////////////////////// -// Dummy/No Cart Functions -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL DummyCs0ReadByte(UNUSED u32 addr) -{ - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL DummyCs0ReadWord(UNUSED u32 addr) -{ - return 0xFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL DummyCs0ReadLong(UNUSED u32 addr) -{ - return 0xFFFFFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs0WriteByte(UNUSED u32 addr, UNUSED u8 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs0WriteWord(UNUSED u32 addr, UNUSED u16 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs0WriteLong(UNUSED u32 addr, UNUSED u32 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL DummyCs1ReadByte(UNUSED u32 addr) -{ - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL DummyCs1ReadWord(UNUSED u32 addr) -{ - return 0xFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL DummyCs1ReadLong(UNUSED u32 addr) -{ - return 0xFFFFFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs1WriteByte(UNUSED u32 addr, UNUSED u8 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs1WriteWord(UNUSED u32 addr, UNUSED u16 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs1WriteLong(UNUSED u32 addr, UNUSED u32 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL DummyCs2ReadByte(UNUSED u32 addr) -{ - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL DummyCs2ReadWord(UNUSED u32 addr) -{ - return 0xFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL DummyCs2ReadLong(UNUSED u32 addr) -{ - return 0xFFFFFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs2WriteByte(UNUSED u32 addr, UNUSED u8 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs2WriteWord(UNUSED u32 addr, UNUSED u16 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DummyCs2WriteLong(UNUSED u32 addr, UNUSED u32 val) -{ -} - -////////////////////////////////////////////////////////////////////////////// -// Action Replay 4M Plus funcions -////////////////////////////////////////////////////////////////////////////// - -typedef enum - { - FL_READ, - FL_SDP, - FL_CMD, - FL_ID, - FL_IDSDP, - FL_IDCMD, - FL_WRITEBUF, - FL_WRITEARRAY - } flashstate; - -u8 flreg0 = 0; -u8 flreg1 = 0; - -flashstate flstate0; -flashstate flstate1; - -u8 flbuf0[128]; -u8 flbuf1[128]; - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL FlashCs0ReadByte(u32 addr) -{ - flashstate* state; - u8* reg; - - if (addr & 1) - { - state = &flstate1; - reg = &flreg1; - } - else - { - state = &flstate0; - reg = &flreg0; - } - - switch (*state) - { - case FL_ID: - case FL_IDSDP: - case FL_IDCMD: - if (addr & 2) return 0xD5; - else return 0x1F; - case FL_WRITEARRAY: *reg ^= 0x02; - case FL_WRITEBUF: return *reg; - case FL_SDP: - case FL_CMD: *state = FL_READ; - case FL_READ: - default: return T2ReadByte(CartridgeArea->rom, addr); - } -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL FlashCs0ReadWord(u32 addr) -{ - return ((u16)(FlashCs0ReadByte(addr) << 8) | (u16)(FlashCs0ReadByte(addr+1))); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL FlashCs0ReadLong(u32 addr) -{ - return ((u32)FlashCs0ReadWord(addr) << 16) |(u32) FlashCs0ReadWord(addr + 2); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL FlashCs0WriteByte(u32 addr, u8 val) -{ - flashstate* state; - u8* reg; - u8* buf; - - if (addr & 1) - { - state = &flstate1; - reg = &flreg1; - buf = flbuf1; - } - else - { - state = &flstate0; - reg = &flreg0; - buf = flbuf0; - } - - switch (*state) - { - case FL_READ: - if (((addr & 0xfffe) == 0xaaaa) && (val == 0xaa)) - *state = FL_SDP; - return; - case FL_WRITEBUF: - buf[(addr >> 1) & 0x7f] = val; - if (((addr >> 1) & 0x7f) == 0x7f) - { - int i; - int j = addr & 0x1; - addr &= 0xffffff00; - for (i = 0; i <= 127; i++) - { - T2WriteByte(CartridgeArea->rom, (addr + i*2 + j), buf[i]); - } - *state = FL_READ; - } - return; - case FL_SDP: - if (((addr & 0xfffe) == 0x5554) && (val == 0x55)) - *state = FL_CMD; - else *state = FL_READ; - return; - case FL_ID: - if (((addr & 0xfffe) == 0xaaaa) && (val == 0xaa)) - *state = FL_IDSDP; - else *state = FL_ID; - return; - case FL_IDSDP: - if (((addr & 0xfffe) == 0x5554) && (val == 0x55)) - *state = FL_READ; - else *state=FL_ID; - return; - case FL_IDCMD: - if (((addr & 0xfffe) == 0xaaaa) && (val == 0xf0)) - *state = FL_READ; - else *state = FL_ID; - return; - case FL_CMD: - if ((addr & 0xfffe) != 0xaaaa) - { - *state = FL_READ; - return; - } - - switch (val) - { - case 0xa0: - *state = FL_WRITEBUF; - return; - case 0x90: - *state = FL_ID; - return; - default: - *state = FL_READ; - return; - } - default: break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL FlashCs0WriteWord(u32 addr, u16 val) -{ - FlashCs0WriteByte(addr, (u8)(val >> 8)); - FlashCs0WriteByte(addr + 1, (u8)(val & 0xff)); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL FlashCs0WriteLong(u32 addr, u32 val) -{ - FlashCs0WriteWord(addr, (u16)(val >> 16)); - FlashCs0WriteWord(addr + 2, (u16)(val & 0xffff)); -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL AR4MCs0ReadByte(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x00: - { - if ((addr & 0x80000) == 0) // EEPROM - return FlashCs0ReadByte(addr); -// return biosarea->getByte(addr); -// else // Outport -// fprintf(stderr, "Commlink Outport Byte read\n"); - break; - } - case 0x01: - { -// if ((addr & 0x80000) == 0) // Commlink Status flag -// fprintf(stderr, "Commlink Status Flag read\n"); -// else // Inport for Commlink -// fprintf(stderr, "Commlink Inport Byte read\n"); - break; - } - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Dram area - return T1ReadByte(CartridgeArea->dram, addr & 0x3FFFFF); - default: // The rest doesn't matter - break; - } - - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL AR4MCs0ReadWord(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x00: - { - if ((addr & 0x80000) == 0) // EEPROM - return FlashCs0ReadWord(addr); -// else // Outport -// fprintf(stderr, "Commlink Outport Word read\n"); - break; - } - case 0x01: - { -// if ((addr & 0x80000) == 0) // Commlink Status flag -// fprintf(stderr, "Commlink Status Flag read\n"); -// else // Inport for Commlink -// fprintf(stderr, "Commlink Inport Word read\n"); - break; - } - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - return T1ReadWord(CartridgeArea->dram, addr & 0x3FFFFF); - case 0x12: - case 0x1E: - if (0x80000) - return 0xFFFD; - break; - case 0x13: - case 0x16: - case 0x17: - case 0x1A: - case 0x1B: - case 0x1F: - return 0xFFFD; - default: // The rest doesn't matter - break; - } - - return 0xFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL AR4MCs0ReadLong(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x00: - { - if ((addr & 0x80000) == 0) // EEPROM - return FlashCs0ReadLong(addr); -// else // Outport -// fprintf(stderr, "Commlink Outport Long read\n"); - break; - } - case 0x01: - { -// if ((addr & 0x80000) == 0) // Commlink Status flag -// fprintf(stderr, "Commlink Status Flag read\n"); -// else // Inport for Commlink -// fprintf(stderr, "Commlink Inport Long read\n"); - break; - } - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - return T1ReadLong(CartridgeArea->dram, addr & 0x3FFFFF); - case 0x12: - case 0x1E: - if (0x80000) - return 0xFFFDFFFD; - break; - case 0x13: - case 0x16: - case 0x17: - case 0x1A: - case 0x1B: - case 0x1F: - return 0xFFFDFFFD; - default: // The rest doesn't matter - break; - } - - return 0xFFFFFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL AR4MCs0WriteByte(u32 addr, u8 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x00: - { - if ((addr & 0x80000) == 0) // EEPROM - FlashCs0WriteByte(addr, val); -// else // Outport -// fprintf(stderr, "Commlink Outport byte write\n"); - break; - } - case 0x01: - { -// if ((addr & 0x80000) == 0) // Commlink Status flag -// fprintf(stderr, "Commlink Status Flag write\n"); -// else // Inport for Commlink -// fprintf(stderr, "Commlink Inport Byte write\n"); - break; - } - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - T1WriteByte(CartridgeArea->dram, addr & 0x3FFFFF, val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL AR4MCs0WriteWord(u32 addr, u16 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x00: - { - if ((addr & 0x80000) == 0) // EEPROM - FlashCs0WriteWord(addr, val); -// else // Outport -// fprintf(stderr, "Commlink Outport Word write\n"); - break; - } - case 0x01: - { -// if ((addr & 0x80000) == 0) // Commlink Status flag -// fprintf(stderr, "Commlink Status Flag write\n"); -// else // Inport for Commlink -// fprintf(stderr, "Commlink Inport Word write\n"); - break; - } - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - T1WriteWord(CartridgeArea->dram, addr & 0x3FFFFF, val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL AR4MCs0WriteLong(u32 addr, u32 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x00: - { - if ((addr & 0x80000) == 0) // EEPROM - FlashCs0WriteLong(addr, val); -// else // Outport -// fprintf(stderr, "Commlink Outport Long write\n"); - break; - } - case 0x01: - { -// if ((addr & 0x80000) == 0) // Commlink Status flag -// fprintf(stderr, "Commlink Status Flag write\n"); -// else // Inport for Commlink -// fprintf(stderr, "Commlink Inport Long write\n"); - break; - } - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - T1WriteLong(CartridgeArea->dram, addr & 0x3FFFFF, val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// -// 8 Mbit Dram -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL DRAM8MBITCs0ReadByte(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: // Dram area - return T1ReadByte(CartridgeArea->dram, addr & 0x7FFFF); - case 0x06: // Dram area - return T1ReadByte(CartridgeArea->dram, 0x80000 | (addr & 0x7FFFF)); - default: // The rest doesn't matter - break; - } - - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL DRAM8MBITCs0ReadWord(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: // Dram area - return T1ReadWord(CartridgeArea->dram, addr & 0x7FFFF); - case 0x06: // Dram area - return T1ReadWord(CartridgeArea->dram, 0x80000 | (addr & 0x7FFFF)); - default: // The rest doesn't matter - break; - } - - return 0xFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL DRAM8MBITCs0ReadLong(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: // Dram area - return T1ReadLong(CartridgeArea->dram, addr & 0x7FFFF); - case 0x06: // Dram area - return T1ReadLong(CartridgeArea->dram, 0x80000 | (addr & 0x7FFFF)); - default: // The rest doesn't matter - break; - } - - return 0xFFFFFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DRAM8MBITCs0WriteByte(u32 addr, u8 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: // Dram area - T1WriteByte(CartridgeArea->dram, addr & 0x7FFFF, val); - break; - case 0x06: // Dram area - T1WriteByte(CartridgeArea->dram, 0x80000 | (addr & 0x7FFFF), val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DRAM8MBITCs0WriteWord(u32 addr, u16 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: // Dram area - T1WriteWord(CartridgeArea->dram, addr & 0x7FFFF, val); - break; - case 0x06: // Dram area - T1WriteWord(CartridgeArea->dram, 0x80000 | (addr & 0x7FFFF), val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DRAM8MBITCs0WriteLong(u32 addr, u32 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: // Dram area - T1WriteLong(CartridgeArea->dram, addr & 0x7FFFF, val); - break; - case 0x06: // Dram area - T1WriteLong(CartridgeArea->dram, 0x80000 | (addr & 0x7FFFF), val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// -// 32 Mbit Dram -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL DRAM32MBITCs0ReadByte(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Dram area - return T1ReadByte(CartridgeArea->dram, addr & 0x3FFFFF); - default: // The rest doesn't matter - break; - } - - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL DRAM32MBITCs0ReadWord(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - return T1ReadWord(CartridgeArea->dram, addr & 0x3FFFFF); - default: // The rest doesn't matter - break; - } - - return 0xFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL DRAM32MBITCs0ReadLong(u32 addr) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - return T1ReadLong(CartridgeArea->dram, addr & 0x3FFFFF); - default: // The rest doesn't matter - break; - } - - return 0xFFFFFFFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DRAM32MBITCs0WriteByte(u32 addr, u8 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - T1WriteByte(CartridgeArea->dram, addr & 0x3FFFFF, val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DRAM32MBITCs0WriteWord(u32 addr, u16 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - T1WriteWord(CartridgeArea->dram, addr & 0x3FFFFF, val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL DRAM32MBITCs0WriteLong(u32 addr, u32 val) -{ - addr &= 0x1FFFFFF; - - switch (addr >> 20) - { - case 0x04: - case 0x05: - case 0x06: - case 0x07: // Ram cart area - T1WriteLong(CartridgeArea->dram, addr & 0x3FFFFF, val); - break; - default: // The rest doesn't matter - break; - } -} - -////////////////////////////////////////////////////////////////////////////// -// 4 Mbit Backup Ram -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL BUP4MBITCs1ReadByte(u32 addr) -{ - return T1ReadByte(CartridgeArea->bupram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL BUP4MBITCs1ReadWord(u32 addr) -{ - return T1ReadWord(CartridgeArea->bupram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL BUP4MBITCs1ReadLong(u32 addr) -{ - return T1ReadLong(CartridgeArea->bupram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP4MBITCs1WriteByte(u32 addr, u8 val) -{ - T1WriteByte(CartridgeArea->bupram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP4MBITCs1WriteWord(u32 addr, u16 val) -{ - T1WriteWord(CartridgeArea->bupram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP4MBITCs1WriteLong(u32 addr, u32 val) -{ - T1WriteLong(CartridgeArea->bupram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// -// 8 Mbit Backup Ram -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL BUP8MBITCs1ReadByte(u32 addr) -{ - return T1ReadByte(CartridgeArea->bupram, addr & 0x1FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL BUP8MBITCs1ReadWord(u32 addr) -{ - return T1ReadWord(CartridgeArea->bupram, addr & 0x1FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL BUP8MBITCs1ReadLong(u32 addr) -{ - return T1ReadLong(CartridgeArea->bupram, addr & 0x1FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP8MBITCs1WriteByte(u32 addr, u8 val) -{ - T1WriteByte(CartridgeArea->bupram, addr & 0x1FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP8MBITCs1WriteWord(u32 addr, u16 val) -{ - T1WriteWord(CartridgeArea->bupram, addr & 0x1FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP8MBITCs1WriteLong(u32 addr, u32 val) -{ - T1WriteLong(CartridgeArea->bupram, addr & 0x1FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// -// 16 Mbit Backup Ram -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL BUP16MBITCs1ReadByte(u32 addr) -{ - return T1ReadByte(CartridgeArea->bupram, addr & 0x3FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL BUP16MBITCs1ReadWord(u32 addr) -{ - return T1ReadWord(CartridgeArea->bupram, addr & 0x3FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL BUP16MBITCs1ReadLong(u32 addr) -{ - return T1ReadLong(CartridgeArea->bupram, addr & 0x3FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP16MBITCs1WriteByte(u32 addr, u8 val) -{ - T1WriteByte(CartridgeArea->bupram, addr & 0x3FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP16MBITCs1WriteWord(u32 addr, u16 val) -{ - T1WriteWord(CartridgeArea->bupram, addr & 0x3FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP16MBITCs1WriteLong(u32 addr, u32 val) -{ - T1WriteLong(CartridgeArea->bupram, addr & 0x3FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// -// 32 Mbit Backup Ram -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL BUP32MBITCs1ReadByte(u32 addr) -{ - return T1ReadByte(CartridgeArea->bupram, addr & 0x7FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL BUP32MBITCs1ReadWord(u32 addr) -{ - return T1ReadWord(CartridgeArea->bupram, addr & 0x7FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL BUP32MBITCs1ReadLong(u32 addr) -{ - return T1ReadLong(CartridgeArea->bupram, addr & 0x7FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP32MBITCs1WriteByte(u32 addr, u8 val) -{ - T1WriteByte(CartridgeArea->bupram, addr & 0x7FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP32MBITCs1WriteWord(u32 addr, u16 val) -{ - T1WriteWord(CartridgeArea->bupram, addr & 0x7FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BUP32MBITCs1WriteLong(u32 addr, u32 val) -{ - T1WriteLong(CartridgeArea->bupram, addr & 0x7FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// -// 16 Mbit Rom -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL ROM16MBITCs0ReadByte(u32 addr) -{ - return T1ReadByte(CartridgeArea->rom, addr & 0x1FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL ROM16MBITCs0ReadWord(u32 addr) -{ - return T1ReadWord(CartridgeArea->rom, addr & 0x1FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL ROM16MBITCs0ReadLong(u32 addr) -{ - return T1ReadLong(CartridgeArea->rom, addr & 0x1FFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL ROM16MBITCs0WriteByte(u32 addr, u8 val) -{ - T1WriteByte(CartridgeArea->rom, addr & 0x1FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL ROM16MBITCs0WriteWord(u32 addr, u16 val) -{ - T1WriteWord(CartridgeArea->rom, addr & 0x1FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL ROM16MBITCs0WriteLong(u32 addr, u32 val) -{ - T1WriteLong(CartridgeArea->rom, addr & 0x1FFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// -// Sega Saturn Modem(Japanese) -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL JapModemCs0ReadByte(u32 addr) -{ - if (addr & 0x1) - return 0xA5; - else - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL JapModemCs0ReadWord(UNUSED u32 addr) -{ - return 0xFFA5; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL JapModemCs0ReadLong(UNUSED u32 addr) -{ - return 0xFFA5FFA5; -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL JapModemCs1ReadByte(UNUSED u32 addr) -{ - return 0xA5; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL JapModemCs1ReadWord(UNUSED u32 addr) -{ - return 0xA5A5; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL JapModemCs1ReadLong(UNUSED u32 addr) -{ - return 0xA5A5A5A5; -} - -////////////////////////////////////////////////////////////////////////////// -// General Cart functions -////////////////////////////////////////////////////////////////////////////// - -int CartInit(const char * filename, int type) -{ - if ((CartridgeArea = (cartridge_struct *)calloc(1, sizeof(cartridge_struct))) == NULL) - return -1; - - CartridgeArea->carttype = type; - CartridgeArea->filename = filename; - - switch(type) - { - case CART_PAR: // Action Replay 4M Plus(or equivalent) - { - if ((CartridgeArea->rom = T2MemoryInit(0x40000)) == NULL) - return -1; - - if ((CartridgeArea->dram = T1MemoryInit(0x400000)) == NULL) - return -1; - - // Use 32 Mbit Dram id - CartridgeArea->cartid = 0x5C; - - // Load AR firmware to memory - if (T123Load(CartridgeArea->rom, 0x40000, 2, filename) != 0) - return -1; - flstate0 = FL_READ; - flstate1 = FL_READ; - - // Setup Functions - CartridgeArea->Cs0ReadByte = &AR4MCs0ReadByte; - CartridgeArea->Cs0ReadWord = &AR4MCs0ReadWord; - CartridgeArea->Cs0ReadLong = &AR4MCs0ReadLong; - CartridgeArea->Cs0WriteByte = &AR4MCs0WriteByte; - CartridgeArea->Cs0WriteWord = &AR4MCs0WriteWord; - CartridgeArea->Cs0WriteLong = &AR4MCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &DummyCs1ReadByte; - CartridgeArea->Cs1ReadWord = &DummyCs1ReadWord; - CartridgeArea->Cs1ReadLong = &DummyCs1ReadLong; - CartridgeArea->Cs1WriteByte = &DummyCs1WriteByte; - CartridgeArea->Cs1WriteWord = &DummyCs1WriteWord; - CartridgeArea->Cs1WriteLong = &DummyCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - break; - } - case CART_BACKUPRAM4MBIT: // 4 Mbit Backup Ram - { - if ((CartridgeArea->bupram = T1MemoryInit(0x100000)) == NULL) - return -1; - - CartridgeArea->cartid = 0x21; - - // Load Backup Ram data from file - if (T123Load(CartridgeArea->bupram, 0x100000, 1, filename) != 0) - FormatBackupRam(CartridgeArea->bupram, 0x100000); - - // Setup Functions - CartridgeArea->Cs0ReadByte = &DummyCs0ReadByte; - CartridgeArea->Cs0ReadWord = &DummyCs0ReadWord; - CartridgeArea->Cs0ReadLong = &DummyCs0ReadLong; - CartridgeArea->Cs0WriteByte = &DummyCs0WriteByte; - CartridgeArea->Cs0WriteWord = &DummyCs0WriteWord; - CartridgeArea->Cs0WriteLong = &DummyCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &BUP4MBITCs1ReadByte; - CartridgeArea->Cs1ReadWord = &BUP4MBITCs1ReadWord; - CartridgeArea->Cs1ReadLong = &BUP4MBITCs1ReadLong; - CartridgeArea->Cs1WriteByte = &BUP4MBITCs1WriteByte; - CartridgeArea->Cs1WriteWord = &BUP4MBITCs1WriteWord; - CartridgeArea->Cs1WriteLong = &BUP4MBITCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - - break; - } - case CART_BACKUPRAM8MBIT: // 8 Mbit Backup Ram - { - if ((CartridgeArea->bupram = T1MemoryInit(0x200000)) == NULL) - return -1; - - CartridgeArea->cartid = 0x22; - - // Load Backup Ram data from file - if (T123Load(CartridgeArea->bupram, 0x200000, 1, filename) != 0) - FormatBackupRam(CartridgeArea->bupram, 0x200000); - - // Setup Functions - CartridgeArea->Cs0ReadByte = &DummyCs0ReadByte; - CartridgeArea->Cs0ReadWord = &DummyCs0ReadWord; - CartridgeArea->Cs0ReadLong = &DummyCs0ReadLong; - CartridgeArea->Cs0WriteByte = &DummyCs0WriteByte; - CartridgeArea->Cs0WriteWord = &DummyCs0WriteWord; - CartridgeArea->Cs0WriteLong = &DummyCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &BUP8MBITCs1ReadByte; - CartridgeArea->Cs1ReadWord = &BUP8MBITCs1ReadWord; - CartridgeArea->Cs1ReadLong = &BUP8MBITCs1ReadLong; - CartridgeArea->Cs1WriteByte = &BUP8MBITCs1WriteByte; - CartridgeArea->Cs1WriteWord = &BUP8MBITCs1WriteWord; - CartridgeArea->Cs1WriteLong = &BUP8MBITCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - - break; - } - case CART_BACKUPRAM16MBIT: // 16 Mbit Backup Ram - { - if ((CartridgeArea->bupram = T1MemoryInit(0x400000)) == NULL) - return -1; - - CartridgeArea->cartid = 0x23; - - // Load Backup Ram data from file - if (T123Load(CartridgeArea->bupram, 0x400000, 1, filename) != 0) - FormatBackupRam(CartridgeArea->bupram, 0x400000); - - // Setup Functions - CartridgeArea->Cs0ReadByte = &DummyCs0ReadByte; - CartridgeArea->Cs0ReadWord = &DummyCs0ReadWord; - CartridgeArea->Cs0ReadLong = &DummyCs0ReadLong; - CartridgeArea->Cs0WriteByte = &DummyCs0WriteByte; - CartridgeArea->Cs0WriteWord = &DummyCs0WriteWord; - CartridgeArea->Cs0WriteLong = &DummyCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &BUP16MBITCs1ReadByte; - CartridgeArea->Cs1ReadWord = &BUP16MBITCs1ReadWord; - CartridgeArea->Cs1ReadLong = &BUP16MBITCs1ReadLong; - CartridgeArea->Cs1WriteByte = &BUP16MBITCs1WriteByte; - CartridgeArea->Cs1WriteWord = &BUP16MBITCs1WriteWord; - CartridgeArea->Cs1WriteLong = &BUP16MBITCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - break; - } - case CART_BACKUPRAM32MBIT: // 32 Mbit Backup Ram - { - if ((CartridgeArea->bupram = T1MemoryInit(0x800000)) == NULL) - return -1; - - CartridgeArea->cartid = 0x24; - - // Load Backup Ram data from file - if (T123Load(CartridgeArea->bupram, 0x800000, 1, filename) != 0) - FormatBackupRam(CartridgeArea->bupram, 0x800000); - - // Setup Functions - CartridgeArea->Cs0ReadByte = &DummyCs0ReadByte; - CartridgeArea->Cs0ReadWord = &DummyCs0ReadWord; - CartridgeArea->Cs0ReadLong = &DummyCs0ReadLong; - CartridgeArea->Cs0WriteByte = &DummyCs0WriteByte; - CartridgeArea->Cs0WriteWord = &DummyCs0WriteWord; - CartridgeArea->Cs0WriteLong = &DummyCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &BUP32MBITCs1ReadByte; - CartridgeArea->Cs1ReadWord = &BUP32MBITCs1ReadWord; - CartridgeArea->Cs1ReadLong = &BUP32MBITCs1ReadLong; - CartridgeArea->Cs1WriteByte = &BUP32MBITCs1WriteByte; - CartridgeArea->Cs1WriteWord = &BUP32MBITCs1WriteWord; - CartridgeArea->Cs1WriteLong = &BUP32MBITCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - break; - } - case CART_DRAM8MBIT: // 8 Mbit Dram Cart - { - if ((CartridgeArea->dram = T1MemoryInit(0x100000)) == NULL) - return -1; - - CartridgeArea->cartid = 0x5A; - - // Setup Functions - CartridgeArea->Cs0ReadByte = &DRAM8MBITCs0ReadByte; - CartridgeArea->Cs0ReadWord = &DRAM8MBITCs0ReadWord; - CartridgeArea->Cs0ReadLong = &DRAM8MBITCs0ReadLong; - CartridgeArea->Cs0WriteByte = &DRAM8MBITCs0WriteByte; - CartridgeArea->Cs0WriteWord = &DRAM8MBITCs0WriteWord; - CartridgeArea->Cs0WriteLong = &DRAM8MBITCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &DummyCs1ReadByte; - CartridgeArea->Cs1ReadWord = &DummyCs1ReadWord; - CartridgeArea->Cs1ReadLong = &DummyCs1ReadLong; - CartridgeArea->Cs1WriteByte = &DummyCs1WriteByte; - CartridgeArea->Cs1WriteWord = &DummyCs1WriteWord; - CartridgeArea->Cs1WriteLong = &DummyCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - break; - } - case CART_DRAM32MBIT: // 32 Mbit Dram Cart - { - if ((CartridgeArea->dram = T1MemoryInit(0x400000)) == NULL) - return -1; - - CartridgeArea->cartid = 0x5C; - - // Setup Functions - CartridgeArea->Cs0ReadByte = &DRAM32MBITCs0ReadByte; - CartridgeArea->Cs0ReadWord = &DRAM32MBITCs0ReadWord; - CartridgeArea->Cs0ReadLong = &DRAM32MBITCs0ReadLong; - CartridgeArea->Cs0WriteByte = &DRAM32MBITCs0WriteByte; - CartridgeArea->Cs0WriteWord = &DRAM32MBITCs0WriteWord; - CartridgeArea->Cs0WriteLong = &DRAM32MBITCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &DummyCs1ReadByte; - CartridgeArea->Cs1ReadWord = &DummyCs1ReadWord; - CartridgeArea->Cs1ReadLong = &DummyCs1ReadLong; - CartridgeArea->Cs1WriteByte = &DummyCs1WriteByte; - CartridgeArea->Cs1WriteWord = &DummyCs1WriteWord; - CartridgeArea->Cs1WriteLong = &DummyCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - break; - } - case CART_ROM16MBIT: // 16 Mbit Rom Cart - { - if ((CartridgeArea->rom = T1MemoryInit(0x200000)) == NULL) - return -1; - - CartridgeArea->cartid = 0xFF; // I have no idea what the real id is - - // Load Rom to memory - if (T123Load(CartridgeArea->rom, 0x200000, 1, filename) != 0) - return -1; - - // Setup Functions - CartridgeArea->Cs0ReadByte = &ROM16MBITCs0ReadByte; - CartridgeArea->Cs0ReadWord = &ROM16MBITCs0ReadWord; - CartridgeArea->Cs0ReadLong = &ROM16MBITCs0ReadLong; - CartridgeArea->Cs0WriteByte = &ROM16MBITCs0WriteByte; - CartridgeArea->Cs0WriteWord = &ROM16MBITCs0WriteWord; - CartridgeArea->Cs0WriteLong = &ROM16MBITCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &DummyCs1ReadByte; - CartridgeArea->Cs1ReadWord = &DummyCs1ReadWord; - CartridgeArea->Cs1ReadLong = &DummyCs1ReadLong; - CartridgeArea->Cs1WriteByte = &DummyCs1WriteByte; - CartridgeArea->Cs1WriteWord = &DummyCs1WriteWord; - CartridgeArea->Cs1WriteLong = &DummyCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - break; - } - case CART_JAPMODEM: // Sega Saturn Modem(Japanese) - { - CartridgeArea->cartid = 0xFF; - - CartridgeArea->Cs0ReadByte = &JapModemCs0ReadByte; - CartridgeArea->Cs0ReadWord = &JapModemCs0ReadWord; - CartridgeArea->Cs0ReadLong = &JapModemCs0ReadLong; - CartridgeArea->Cs0WriteByte = &DummyCs0WriteByte; - CartridgeArea->Cs0WriteWord = &DummyCs0WriteWord; - CartridgeArea->Cs0WriteLong = &DummyCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &JapModemCs1ReadByte; - CartridgeArea->Cs1ReadWord = &JapModemCs1ReadWord; - CartridgeArea->Cs1ReadLong = &JapModemCs1ReadLong; - CartridgeArea->Cs1WriteByte = &DummyCs1WriteByte; - CartridgeArea->Cs1WriteWord = &DummyCs1WriteWord; - CartridgeArea->Cs1WriteLong = &DummyCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - break; - } - default: // No Cart - { - CartridgeArea->cartid = 0xFF; - - // Setup Functions - CartridgeArea->Cs0ReadByte = &DummyCs0ReadByte; - CartridgeArea->Cs0ReadWord = &DummyCs0ReadWord; - CartridgeArea->Cs0ReadLong = &DummyCs0ReadLong; - CartridgeArea->Cs0WriteByte = &DummyCs0WriteByte; - CartridgeArea->Cs0WriteWord = &DummyCs0WriteWord; - CartridgeArea->Cs0WriteLong = &DummyCs0WriteLong; - - CartridgeArea->Cs1ReadByte = &DummyCs1ReadByte; - CartridgeArea->Cs1ReadWord = &DummyCs1ReadWord; - CartridgeArea->Cs1ReadLong = &DummyCs1ReadLong; - CartridgeArea->Cs1WriteByte = &DummyCs1WriteByte; - CartridgeArea->Cs1WriteWord = &DummyCs1WriteWord; - CartridgeArea->Cs1WriteLong = &DummyCs1WriteLong; - - CartridgeArea->Cs2ReadByte = &DummyCs2ReadByte; - CartridgeArea->Cs2ReadWord = &DummyCs2ReadWord; - CartridgeArea->Cs2ReadLong = &DummyCs2ReadLong; - CartridgeArea->Cs2WriteByte = &DummyCs2WriteByte; - CartridgeArea->Cs2WriteWord = &DummyCs2WriteWord; - CartridgeArea->Cs2WriteLong = &DummyCs2WriteLong; - break; - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void CartDeInit(void) -{ - if (CartridgeArea) - { - if (CartridgeArea->carttype == CART_PAR) - { - if (CartridgeArea->rom) - { - if (T123Save(CartridgeArea->rom, 0x40000, 2, CartridgeArea->filename) != 0) - YabSetError(YAB_ERR_FILEWRITE, (void *)CartridgeArea->filename); - T2MemoryDeInit(CartridgeArea->rom); - } - } - else - { - if (CartridgeArea->rom) - T1MemoryDeInit(CartridgeArea->rom); - } - - if (CartridgeArea->bupram) - { - u32 size=0; - - switch (CartridgeArea->carttype) - { - case CART_BACKUPRAM4MBIT: // 4 Mbit Backup Ram - { - size = 0x100000; - break; - } - case CART_BACKUPRAM8MBIT: // 8 Mbit Backup Ram - { - size = 0x200000; - break; - } - case CART_BACKUPRAM16MBIT: // 16 Mbit Backup Ram - { - size = 0x400000; - break; - } - case CART_BACKUPRAM32MBIT: // 32 Mbit Backup Ram - { - size = 0x800000; - break; - } - } - - if (size != 0) - { - if (T123Save(CartridgeArea->bupram, size, 1, CartridgeArea->filename) != 0) - YabSetError(YAB_ERR_FILEWRITE, (void *)CartridgeArea->filename); - - T1MemoryDeInit(CartridgeArea->bupram); - } - } - - if (CartridgeArea->dram) - T1MemoryDeInit(CartridgeArea->dram); - - free(CartridgeArea); - } - CartridgeArea = NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -int CartSaveState(FILE * fp) -{ - int offset; - - offset = StateWriteHeader(fp, "CART", 1); - - // Write cart type - fwrite((void *)&CartridgeArea->carttype, 4, 1, fp); - - // Write the areas associated with the cart type here - switch (CartridgeArea->carttype) - { - case CART_DRAM8MBIT: - fwrite(CartridgeArea->dram, 1, 0x100000, fp); - break; - case CART_DRAM32MBIT: - fwrite(CartridgeArea->dram, 1, 0x400000, fp); - break; - } - - return StateFinishHeader(fp, offset); -} - -////////////////////////////////////////////////////////////////////////////// - -int CartLoadState(FILE * fp, UNUSED int version, int size) -{ - int newtype; - - // Read cart type - fread((void *)&newtype, 4, 1, fp); - - // Check to see if old cart type and new cart type match, if they don't, - // reallocate memory areas - if (CartridgeArea->carttype != newtype) - { - // ... - } - switch (CartridgeArea->carttype) - { - case CART_DRAM8MBIT: - fread(CartridgeArea->dram, 1, 0x100000, fp); - break; - case CART_DRAM32MBIT: - fread(CartridgeArea->dram, 1, 0x400000, fp); - break; - } - - // Read the areas associated with the cart type here - - return size; -} - -////////////////////////////////////////////////////////////////////////////// - diff --git a/yabause/src/cs0.h b/yabause/src/cs0.h deleted file mode 100644 index c61edd3774..0000000000 --- a/yabause/src/cs0.h +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright 2004-2005 Theo Berkau - Copyright 2005 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CS0_H -#define CS0_H - -#include "memory.h" - -#define CART_NONE 0 -#define CART_PAR 1 -#define CART_BACKUPRAM4MBIT 2 -#define CART_BACKUPRAM8MBIT 3 -#define CART_BACKUPRAM16MBIT 4 -#define CART_BACKUPRAM32MBIT 5 -#define CART_DRAM8MBIT 6 -#define CART_DRAM32MBIT 7 -#define CART_NETLINK 8 -#define CART_ROM16MBIT 9 -#define CART_JAPMODEM 10 - -typedef struct -{ - int carttype; - int cartid; - const char *filename; - - u8 FASTCALL (*Cs0ReadByte)(u32 addr); - u16 FASTCALL (*Cs0ReadWord)(u32 addr); - u32 FASTCALL (*Cs0ReadLong)(u32 addr); - void FASTCALL (*Cs0WriteByte)(u32 addr, u8 val); - void FASTCALL (*Cs0WriteWord)(u32 addr, u16 val); - void FASTCALL (*Cs0WriteLong)(u32 addr, u32 val); - - u8 FASTCALL (*Cs1ReadByte)(u32 addr); - u16 FASTCALL (*Cs1ReadWord)(u32 addr); - u32 FASTCALL (*Cs1ReadLong)(u32 addr); - void FASTCALL (*Cs1WriteByte)(u32 addr, u8 val); - void FASTCALL (*Cs1WriteWord)(u32 addr, u16 val); - void FASTCALL (*Cs1WriteLong)(u32 addr, u32 val); - - u8 FASTCALL (*Cs2ReadByte)(u32 addr); - u16 FASTCALL (*Cs2ReadWord)(u32 addr); - u32 FASTCALL (*Cs2ReadLong)(u32 addr); - void FASTCALL (*Cs2WriteByte)(u32 addr, u8 val); - void FASTCALL (*Cs2WriteWord)(u32 addr, u16 val); - void FASTCALL (*Cs2WriteLong)(u32 addr, u32 val); - - void *rom; - void *bupram; - void *dram; -} cartridge_struct; - -extern cartridge_struct *CartridgeArea; - -int CartInit(const char *filename, int); -void CartDeInit(void); - -int CartSaveState(FILE *fp); -int CartLoadState(FILE *fp, int version, int size); - -#endif diff --git a/yabause/src/cs1.c b/yabause/src/cs1.c deleted file mode 100644 index 6461d269da..0000000000 --- a/yabause/src/cs1.c +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright 2003-2005 Guillaume Duhamel - Copyright 2005 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include "cs1.h" -#include "cs0.h" - -////////////////////////////////////////////////////////////////////////////// - -u8 FASTCALL Cs1ReadByte(u32 addr) -{ - addr &= 0xFFFFFF; - - if (addr == 0xFFFFFF) - return CartridgeArea->cartid; - - return CartridgeArea->Cs1ReadByte(addr); -} - -////////////////////////////////////////////////////////////////////////////// - -u16 FASTCALL Cs1ReadWord(u32 addr) -{ - addr &= 0xFFFFFF; - - if (addr == 0xFFFFFE) - return (0xFF00 | CartridgeArea->cartid); - - return CartridgeArea->Cs1ReadWord(addr); -} - -////////////////////////////////////////////////////////////////////////////// - -u32 FASTCALL Cs1ReadLong(u32 addr) -{ - addr &= 0xFFFFFF; - - if (addr == 0xFFFFFC) - return (0xFF00FF00 | (CartridgeArea->cartid << 16) | CartridgeArea->cartid); - - return CartridgeArea->Cs1ReadLong(addr); -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL Cs1WriteByte(u32 addr, u8 val) -{ - addr &= 0xFFFFFF; - - if (addr == 0xFFFFFF) - return; - - CartridgeArea->Cs1WriteByte(addr, val); -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL Cs1WriteWord(u32 addr, u16 val) -{ - addr &= 0xFFFFFF; - - if (addr == 0xFFFFFE) - return; - - CartridgeArea->Cs1WriteWord(addr, val); -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL Cs1WriteLong(u32 addr, u32 val) -{ - addr &= 0xFFFFFF; - - if (addr == 0xFFFFFC) - return; - - CartridgeArea->Cs1WriteLong(addr, val); -} - -////////////////////////////////////////////////////////////////////////////// diff --git a/yabause/src/cs1.h b/yabause/src/cs1.h deleted file mode 100644 index 2ebdee2e20..0000000000 --- a/yabause/src/cs1.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright 2003-2005 Guillaume Duhamel - Copyright 2005 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CS1_H -#define CS1_H - -#include "cs0.h" -#include "memory.h" - -u8 FASTCALL Cs1ReadByte(u32); -u16 FASTCALL Cs1ReadWord(u32); -u32 FASTCALL Cs1ReadLong(u32); -void FASTCALL Cs1WriteByte(u32, u8); -void FASTCALL Cs1WriteWord(u32, u16); -void FASTCALL Cs1WriteLong(u32, u32); - -#endif diff --git a/yabause/src/cs2.c b/yabause/src/cs2.c deleted file mode 100644 index 92484ac6de..0000000000 --- a/yabause/src/cs2.c +++ /dev/null @@ -1,3720 +0,0 @@ -/* Copyright 2003 Guillaume Duhamel - Copyright 2004-2006 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include "cs2.h" -#include "debug.h" -#include "error.h" -#include "netlink.h" -#include "scsp.h" -#include "scu.h" -#include "smpc.h" -#include "yui.h" - -#define CDB_HIRQ_CMOK 0x0001 -#define CDB_HIRQ_DRDY 0x0002 -#define CDB_HIRQ_CSCT 0x0004 -#define CDB_HIRQ_BFUL 0x0008 -#define CDB_HIRQ_PEND 0x0010 -#define CDB_HIRQ_DCHG 0x0020 -#define CDB_HIRQ_ESEL 0x0040 -#define CDB_HIRQ_EHST 0x0080 -#define CDB_HIRQ_ECPY 0x0100 -#define CDB_HIRQ_EFLS 0x0200 -#define CDB_HIRQ_SCDQ 0x0400 -#define CDB_HIRQ_MPED 0x0800 -#define CDB_HIRQ_MPCM 0x1000 -#define CDB_HIRQ_MPST 0x2000 - -#define CDB_STAT_BUSY 0x00 -#define CDB_STAT_PAUSE 0x01 -#define CDB_STAT_STANDBY 0x02 -#define CDB_STAT_PLAY 0x03 -#define CDB_STAT_SEEK 0x04 -#define CDB_STAT_SCAN 0x05 -#define CDB_STAT_OPEN 0x06 -#define CDB_STAT_NODISC 0x07 -#define CDB_STAT_RETRY 0x08 -#define CDB_STAT_ERROR 0x09 -#define CDB_STAT_FATAL 0x0A -#define CDB_STAT_PERI 0x20 -#define CDB_STAT_TRNS 0x40 -#define CDB_STAT_WAIT 0x80 -#define CDB_STAT_REJECT 0xFF - -#define CDB_PLAYTYPE_SECTOR 0x01 -#define CDB_PLAYTYPE_FILE 0x02 - -Cs2 * Cs2Area = NULL; -ip_struct *cdip = NULL; - -extern CDInterface *CDCoreList[]; - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void doCDReport(u8 status) -{ - Cs2Area->reg.CR1 = (status << 8) | ((Cs2Area->options & 0xF) << 4) | (Cs2Area->repcnt & 0xF); - Cs2Area->reg.CR2 = (Cs2Area->ctrladdr << 8) | Cs2Area->track; - Cs2Area->reg.CR3 = (u16)((Cs2Area->index << 8) | ((Cs2Area->FAD >> 16) & 0xFF)); - Cs2Area->reg.CR4 = (u16) Cs2Area->FAD; -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void doMPEGReport(u8 status) -{ - Cs2Area->reg.CR1 = (status << 8) | Cs2Area->actionstatus; - Cs2Area->reg.CR2 = Cs2Area->vcounter; - Cs2Area->reg.CR3 = (Cs2Area->pictureinfo << 8) | Cs2Area->mpegaudiostatus; - Cs2Area->reg.CR4 = Cs2Area->mpegvideostatus; -} - -////////////////////////////////////////////////////////////////////////////// - -u8 FASTCALL Cs2ReadByte(u32 addr) -{ - addr &= 0xFFFFF; // fix me(I should really have proper mapping) - - if(Cs2Area->carttype == CART_NETLINK) - return NetlinkReadByte(addr); - else - { - // only netlink seems to use byte-access - switch (addr) - { - case 0x95001: - case 0x95005: - case 0x95009: - case 0x9500D: - case 0x95011: - case 0x95015: - case 0x95019: - case 0x9501D: - return 0xFF; - default: - break; - } - } - - LOG("Unimplemented cs2 byte read: %08X\n", addr); - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL Cs2WriteByte(u32 addr, u8 val) -{ - addr &= 0xFFFFF; // fix me(I should really have proper mapping) - - if(Cs2Area->carttype == CART_NETLINK) - { - NetlinkWriteByte(addr, val); - return; - } - else - { - // only netlink seems to use byte-access - switch (addr) - { - case 0x2503D: - case 0x95011: - case 0x9501D: - return; - default: - break; - } - } - - LOG("Unimplemented cs2 byte write: %08X\n", addr); -} - -////////////////////////////////////////////////////////////////////////////// - -u16 FASTCALL Cs2ReadWord(u32 addr) { - u16 val = 0; - addr &= 0xFFFFF; // fix me(I should really have proper mapping) - - switch(addr) { - case 0x90008: - case 0x9000A: - val = Cs2Area->reg.HIRQ; - - if (Cs2Area->isbufferfull) - val |= CDB_HIRQ_BFUL; - else - val &= ~CDB_HIRQ_BFUL; - - if (Cs2Area->isdiskchanged) - val |= CDB_HIRQ_DCHG; - else - val &= ~CDB_HIRQ_DCHG; - - if (Cs2Area->isonesectorstored) - val |= CDB_HIRQ_CSCT; - else - val &= ~CDB_HIRQ_CSCT; - - Cs2Area->reg.HIRQ = val; - -// CDLOG("cs2\t: Hirq read, Hirq mask = %x - ret: %x\n", Memory::getWord(0x9000C), val); - return val; - case 0x9000C: - case 0x9000E: return Cs2Area->reg.HIRQMASK; - case 0x90018: - case 0x9001A: return Cs2Area->reg.CR1; - case 0x9001C: - case 0x9001E: return Cs2Area->reg.CR2; - case 0x90020: - case 0x90022: return Cs2Area->reg.CR3; - case 0x90024: - case 0x90026: Cs2Area->_command = 0; - return Cs2Area->reg.CR4; - case 0x90028: - case 0x9002A: return Cs2Area->reg.MPEGRGB; - case 0x98000: - // transfer info - switch (Cs2Area->infotranstype) { - case 0: - // Get Toc Data - if (Cs2Area->transfercount % 4 == 0) - val = (u16)((Cs2Area->TOC[Cs2Area->transfercount >> 2] & 0xFFFF0000) >> 16); - else - val = (u16)Cs2Area->TOC[Cs2Area->transfercount >> 2]; - - Cs2Area->transfercount += 2; - Cs2Area->cdwnum += 2; - - if (Cs2Area->transfercount > (0xCC * 2)) - { - Cs2Area->transfercount = 0; - Cs2Area->infotranstype = -1; - } - break; - case 1: - // Get File Info(1 file info) - val = (Cs2Area->transfileinfo[Cs2Area->transfercount] << 8) | - Cs2Area->transfileinfo[Cs2Area->transfercount + 1]; - Cs2Area->transfercount += 2; - Cs2Area->cdwnum += 2; - - if (Cs2Area->transfercount > (0x6 * 2)) - { - Cs2Area->transfercount = 0; - Cs2Area->infotranstype = -1; - } - - break; - case 2: - // Get File Info(254 file info) - - // Do we need to retrieve the next file info? - if (Cs2Area->transfercount % (0x6 * 2) == 0) { - // yes we do - Cs2SetupFileInfoTransfer(2 + (Cs2Area->transfercount / (0x6 * 2))); - } - - val = (Cs2Area->transfileinfo[Cs2Area->transfercount % (0x6 * 2)] << 8) | - Cs2Area->transfileinfo[Cs2Area->transfercount % (0x6 * 2) + 1]; - - Cs2Area->transfercount += 2; - Cs2Area->cdwnum += 2; - - if (Cs2Area->transfercount > (254 * (0x6 * 2))) - { - Cs2Area->transfercount = 0; - Cs2Area->infotranstype = -1; - } - - break; - default: break; - } - break; - default: - LOG("cs2\t: Undocumented register read %08X\n", addr); -// val = T3ReadWord(Cs2Area->mem, addr); - break; - } - - return val; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL Cs2WriteWord(u32 addr, u16 val) { - addr &= 0xFFFFF; // fix me(I should really have proper mapping) - - switch(addr) { - case 0x90008: - case 0x9000A: - Cs2Area->reg.HIRQ &= val; - return; - case 0x9000C: - case 0x9000E: Cs2Area->reg.HIRQMASK = val; - return; - case 0x90018: - case 0x9001A: Cs2Area->status &= ~CDB_STAT_PERI; - Cs2Area->_command = 1; - Cs2Area->reg.CR1 = val; - return; - case 0x9001C: - case 0x9001E: Cs2Area->reg.CR2 = val; - return; - case 0x90020: - case 0x90022: Cs2Area->reg.CR3 = val; - return; - case 0x90024: - case 0x90026: Cs2Area->reg.CR4 = val; - Cs2SetCommandTiming(Cs2Area->reg.CR1 >> 8); - return; - case 0x90028: - case 0x9002A: Cs2Area->reg.MPEGRGB = val; - return; - default: - LOG("cs2\t:Undocumented register write %08X\n", addr); -// T3WriteWord(Cs2Area->mem, addr, val); - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -u32 FASTCALL Cs2ReadLong(u32 addr) { - s32 i; - u32 val = 0; - addr &= 0xFFFFF; // fix me(I should really have proper mapping) - - switch(addr) { - case 0x90008: - val = Cs2Area->reg.HIRQ; - - if (Cs2Area->isbufferfull) - val |= CDB_HIRQ_BFUL; - else - val &= ~CDB_HIRQ_BFUL; - - if (Cs2Area->isdiskchanged) - val |= CDB_HIRQ_DCHG; - else - val &= ~CDB_HIRQ_DCHG; - - if (Cs2Area->isonesectorstored) - val |= CDB_HIRQ_CSCT; - else - val &= ~CDB_HIRQ_CSCT; - - Cs2Area->reg.HIRQ = (u16)val; - - val |= (val << 16); - return val; - case 0x9000C: return ((Cs2Area->reg.HIRQMASK << 16) | Cs2Area->reg.HIRQMASK); - case 0x90018: return ((Cs2Area->reg.CR1 << 16) | Cs2Area->reg.CR1); - case 0x9001C: return ((Cs2Area->reg.CR2 << 16) | Cs2Area->reg.CR2); - case 0x90020: return ((Cs2Area->reg.CR3 << 16) | Cs2Area->reg.CR3); - case 0x90024: Cs2Area->_command = 0; - return ((Cs2Area->reg.CR4 << 16) | Cs2Area->reg.CR4); - case 0x90028: return ((Cs2Area->reg.MPEGRGB << 16) | Cs2Area->reg.MPEGRGB); - case 0x18000: - // transfer data - if (Cs2Area->datatranstype != -1) - { - // get sector - - // Make sure we still have sectors to transfer - if (Cs2Area->datanumsecttrans < Cs2Area->datasectstotrans) - { - // Transfer Data - const u8 *ptr = &Cs2Area->datatranspartition->block[Cs2Area->datanumsecttrans]->data[Cs2Area->datatransoffset]; -#ifdef WORDS_BIGENDIAN - val = *((const u32 *) ptr); -#else - val = BSWAP32(*((const u32 *) ptr)); -#endif - - // increment datatransoffset/cdwnum - Cs2Area->cdwnum += 4; - Cs2Area->datatransoffset += 4; - - // Make sure we're not beyond the sector size boundry - if (Cs2Area->datatransoffset >= Cs2Area->datatranspartition->block[Cs2Area->datanumsecttrans]->size) - { - Cs2Area->datatransoffset = 0; - Cs2Area->datanumsecttrans++; - } - } - else - { - if (Cs2Area->datatranstype == 2) - { - // Ok, so we don't have any more sectors to - // transfer, might as well delete them all. - - Cs2Area->datatranstype = -1; - - // free blocks - for (i = Cs2Area->datatranssectpos; i < (Cs2Area->datatranssectpos+Cs2Area->datasectstotrans); i++) - { - Cs2FreeBlock(Cs2Area->datatranspartition->block[i]); - Cs2Area->datatranspartition->block[i] = NULL; - Cs2Area->datatranspartition->blocknum[i] = 0xFF; - } - - // sort remaining blocks - Cs2SortBlocks(Cs2Area->datatranspartition); - - Cs2Area->datatranspartition->size -= Cs2Area->cdwnum; - Cs2Area->datatranspartition->numblocks -= Cs2Area->datasectstotrans; - - CDLOG("cs2\t: datatranspartition->size = %x\n", Cs2Area->datatranspartition->size); - } - } - } - break; - default: - LOG("cs2\t: Undocumented register read %08X\n", addr); -// val = T3ReadLong(Cs2Area->mem, addr); - break; - } - - return val; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL Cs2WriteLong(UNUSED u32 addr, UNUSED u32 val) { - LOG("cs2\t: Long writing isn't implemented\n"); -// T3WriteLong(Cs2Area->mem, addr, val); -} - -////////////////////////////////////////////////////////////////////////////// - -/* Copy "count" 32-bit words from the CD buffer to type-1 memory "dest" (a - * native pointer), as though 0x25818000 had been read that many times */ - -void FASTCALL Cs2RapidCopyT1(void *dest, u32 count) -{ - u8 *dest8 = (u8 *) dest; - - if (Cs2Area->datatranstype != -1) - { - // Copy as many sectors as we have left, one sector at a time - - while (count > 0 && Cs2Area->datanumsecttrans < Cs2Area->datasectstotrans) - { - const u8 *src = &Cs2Area->datatranspartition->block[Cs2Area->datanumsecttrans]->data[Cs2Area->datatransoffset]; - const u32 size = Cs2Area->datatranspartition->block[Cs2Area->datanumsecttrans]->size; - const u32 max = size - Cs2Area->datatransoffset; - const u32 copy = (max < count*4) ? max : count*4; - memcpy(dest8, src, copy); - dest8 += copy; - count -= copy/4; - Cs2Area->datatransoffset += copy; - Cs2Area->cdwnum += copy; - - // Update the sector index if we reached the end of the sector - if (Cs2Area->datatransoffset >= size) - { - Cs2Area->datatransoffset = 0; - Cs2Area->datanumsecttrans++; - } - } - - // If we're in delete mode and we read through everything in memory, - // delete the sectors - if (Cs2Area->datatranstype == 2 - && Cs2Area->datanumsecttrans >= Cs2Area->datasectstotrans) - { - u32 i; - - Cs2Area->datatranstype = -1; - - for (i = Cs2Area->datatranssectpos; i < (Cs2Area->datatranssectpos+Cs2Area->datasectstotrans); i++) - { - Cs2FreeBlock(Cs2Area->datatranspartition->block[i]); - Cs2Area->datatranspartition->block[i] = NULL; - Cs2Area->datatranspartition->blocknum[i] = 0xFF; - } - - Cs2SortBlocks(Cs2Area->datatranspartition); - - Cs2Area->datatranspartition->size -= Cs2Area->cdwnum; - Cs2Area->datatranspartition->numblocks -= Cs2Area->datasectstotrans; - - CDLOG("cs2\t: datatranspartition->size = %x\n", Cs2Area->datatranspartition->size); - } - } - - if (count > 0) - { - // We tried to copy more data than was stored, so fill the rest of - // the buffer with dummy data - memset(dest8, 0xCD, count*4); - } -} - -////////////////////////////////////////////////////////////////////////////// - -/* Copy "count" 32-bit words from the CD buffer to type-2 memory "dest" (a - * native pointer), as though 0x25818000 had been read that many times */ - -void FASTCALL Cs2RapidCopyT2(void *dest, u32 count) -{ - u32 *dest32 = (u32 *) dest; - - if (Cs2Area->datatranstype != -1) - { - // Copy as many sectors as we have left, one sector at a time; copy - // four words at a time where possible to improve data parallelism - - while (count > 0 && Cs2Area->datanumsecttrans < Cs2Area->datasectstotrans) - { - const u8 *src = &Cs2Area->datatranspartition->block[Cs2Area->datanumsecttrans]->data[Cs2Area->datatransoffset]; - const u32 size = Cs2Area->datatranspartition->block[Cs2Area->datanumsecttrans]->size; - const u32 max = size - Cs2Area->datatransoffset; - const u32 copy = (max < count*4) ? max : count*4; - u32 i = 0; - if (copy >= 16) { - for (; i < copy-12; i += 16, src += 16, dest32 += 4) - { - u32 word0, word1, word2, word3; -#ifdef WORDS_BIGENDIAN - word0 = ((u32 *)src)[0]; - word1 = ((u32 *)src)[1]; - word2 = ((u32 *)src)[2]; - word3 = ((u32 *)src)[3]; -#else - word0 = BSWAP16(((u32 *)src)[0]); - word1 = BSWAP16(((u32 *)src)[1]); - word2 = BSWAP16(((u32 *)src)[2]); - word3 = BSWAP16(((u32 *)src)[3]); -#endif - dest32[0] = word0; - dest32[1] = word1; - dest32[2] = word2; - dest32[3] = word3; - } - } - for (; i < copy; i += 4, src += 4, dest32++) - { -#ifdef WORDS_BIGENDIAN - *dest32 = *(u32 *)src; -#else - *dest32 = BSWAP16(*(u32 *)src); -#endif - } - count -= copy/4; - Cs2Area->datatransoffset += copy; - Cs2Area->cdwnum += copy; - - if (Cs2Area->datatransoffset >= size) - { - Cs2Area->datatransoffset = 0; - Cs2Area->datanumsecttrans++; - } - } - - if (Cs2Area->datatranstype == 2 - && Cs2Area->datanumsecttrans >= Cs2Area->datasectstotrans) - { - u32 i; - - Cs2Area->datatranstype = -1; - - for (i = Cs2Area->datatranssectpos; i < (Cs2Area->datatranssectpos+Cs2Area->datasectstotrans); i++) - { - Cs2FreeBlock(Cs2Area->datatranspartition->block[i]); - Cs2Area->datatranspartition->block[i] = NULL; - Cs2Area->datatranspartition->blocknum[i] = 0xFF; - } - - Cs2SortBlocks(Cs2Area->datatranspartition); - - Cs2Area->datatranspartition->size -= Cs2Area->cdwnum; - Cs2Area->datatranspartition->numblocks -= Cs2Area->datasectstotrans; - - CDLOG("cs2\t: datatranspartition->size = %x\n", Cs2Area->datatranspartition->size); - } - } - - if (count > 0) - { - memset(dest32, 0xCD, count*4); - } -} - -////////////////////////////////////////////////////////////////////////////// - -int Cs2Init(int carttype, int coreid, const char *cdpath, const char *mpegpath, const char *netlinksetting) { - int ret; - - if ((Cs2Area = (Cs2 *) malloc(sizeof(Cs2))) == NULL) - return -1; - memset(Cs2Area, 0, sizeof(*Cs2Area)); - - Cs2Area->carttype = carttype; - Cs2Area->mpegpath = mpegpath; - Cs2Area->cdi=NULL; - - if ((ret = Cs2ChangeCDCore(coreid, cdpath)) != 0) - return ret; - - Cs2Reset(); - - // If Modem is connected, set the registers - if(Cs2Area->carttype == CART_NETLINK) - { - if ((ret = NetlinkInit(netlinksetting)) != 0) - return ret; - } - - if ((cdip = (ip_struct *) calloc(sizeof(ip_struct), 1)) == NULL) - return -1; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int Cs2ChangeCDCore(int coreid, const char *cdpath) -{ - int i; - - // Make sure the old core is freed - if (Cs2Area->cdi != NULL) - Cs2Area->cdi->DeInit(); - - // So which core do we want? - if (coreid == CDCORE_DEFAULT) - coreid = 0; // Assume we want the first one - - // Go through core list and find the id - for (i = 0; CDCoreList[i] != NULL; i++) - { - if (CDCoreList[i]->id == coreid) - { - // Set to current core - Cs2Area->cdi = CDCoreList[i]; - break; - } - } - - if (Cs2Area->cdi == NULL) - { - Cs2Area->cdi = &DummyCD; - return -1; - } - - if (Cs2Area->cdi->Init(cdpath) != 0) - { - // This might be helpful. - YabSetError(YAB_ERR_CANNOTINIT, (void *)Cs2Area->cdi->Name); - - // Since it failed, instead of it being fatal, we'll just use the dummy - // core instead - Cs2Area->cdi = &DummyCD; - } - - Cs2Area->isdiskchanged = 1; - Cs2Area->status = CDB_STAT_PAUSE; - SmpcRecheckRegion(); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2DeInit(void) { - if(Cs2Area != NULL) { - if (Cs2Area->cdi != NULL) { - Cs2Area->cdi->DeInit(); - } - - if(Cs2Area->carttype == CART_NETLINK) - NetlinkDeInit(); - - free(Cs2Area); - } - Cs2Area = NULL; - - if (cdip) - free(cdip); - cdip = NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2Reset(void) { - u32 i, i2; - - switch (Cs2Area->cdi->GetStatus()) - { - case 0: - case 1: - Cs2Area->status = CDB_STAT_PAUSE; - Cs2Area->FAD = 150; - Cs2Area->options = 0; - Cs2Area->repcnt = 0; - Cs2Area->ctrladdr = 0x41; - Cs2Area->track = 1; - Cs2Area->index = 1; - break; - case 2: - Cs2Area->status = CDB_STAT_NODISC; - - Cs2Area->FAD = 0xFFFFFFFF; - Cs2Area->options = 0xFF; - Cs2Area->repcnt = 0xFF; - Cs2Area->ctrladdr = 0xFF; - Cs2Area->track = 0xFF; - Cs2Area->index = 0xFF; - break; - case 3: - Cs2Area->status = CDB_STAT_OPEN; - - Cs2Area->FAD = 0xFFFFFFFF; - Cs2Area->options = 0xFF; - Cs2Area->repcnt = 0xFF; - Cs2Area->ctrladdr = 0xFF; - Cs2Area->track = 0xFF; - Cs2Area->index = 0xFF; - break; - default: break; - } - - Cs2Area->infotranstype = -1; - Cs2Area->datatranstype = -1; - Cs2Area->transfercount = 0; - Cs2Area->cdwnum = 0; - Cs2Area->getsectsize = Cs2Area->putsectsize = 2048; - Cs2Area->isdiskchanged = 1; - Cs2Area->isbufferfull = 0; - Cs2Area->isonesectorstored = 0; - Cs2Area->isaudio = 0; - - Cs2Area->reg.CR1 = ( 0 <<8) | 'C'; - Cs2Area->reg.CR2 = ('D'<<8) | 'B'; - Cs2Area->reg.CR3 = ('L'<<8) | 'O'; - Cs2Area->reg.CR4 = ('C'<<8) | 'K'; - Cs2Area->reg.HIRQ = 0xFFFF; - Cs2Area->reg.HIRQMASK = 0xFFFF; - - Cs2Area->playFAD = 0xFFFFFFFF; - Cs2Area->playendFAD = 0xFFFFFFFF; - Cs2Area->playtype = 0; - Cs2Area->maxrepeat = 0; - - // set authentication variables to 0(not authenticated) - Cs2Area->satauth = 0; - Cs2Area->mpgauth = 0; - - // clear filter conditions - for (i = 0; i < MAX_SELECTORS; i++) - { - Cs2Area->filter[i].FAD = 0; - Cs2Area->filter[i].range = 0xFFFFFFFF; - Cs2Area->filter[i].mode = 0; - Cs2Area->filter[i].chan = 0; - Cs2Area->filter[i].smmask = 0; - Cs2Area->filter[i].cimask = 0; - Cs2Area->filter[i].fid = 0; - Cs2Area->filter[i].smval = 0; - Cs2Area->filter[i].cival = 0; - Cs2Area->filter[i].condtrue = 0; - Cs2Area->filter[i].condfalse = 0xFF; - } - - // clear partitions - for (i = 0; i < MAX_SELECTORS; i++) - { - Cs2Area->partition[i].size = -1; - Cs2Area->partition[i].numblocks = 0; - - for (i2 = 0; i2 < MAX_BLOCKS; i2++) - { - Cs2Area->partition[i].block[i2] = NULL; - Cs2Area->partition[i].blocknum[i2] = 0xFF; - } - } - - // clear blocks - for (i = 0; i < MAX_BLOCKS; i++) - { - Cs2Area->block[i].size = -1; - memset(Cs2Area->block[i].data, 0, 2352); - } - - Cs2Area->blockfreespace = 200; - - // initialize TOC - memset(Cs2Area->TOC, 0xFF, sizeof(Cs2Area->TOC)); - - // clear filesystem stuff - Cs2Area->curdirsect = 0; - Cs2Area->curdirsize = 0; - Cs2Area->curdirfidoffset = 0; - memset(&Cs2Area->fileinfo, 0, sizeof(Cs2Area->fileinfo)); - Cs2Area->numfiles = 0; - - Cs2Area->lastbuffer = 0xFF; - - Cs2Area->_command = 0; - Cs2Area->_periodiccycles = 0; - Cs2Area->_commandtiming = 0; - Cs2SetTiming(0); - - // MPEG specific stuff - Cs2Area->mpegcon[0].audcon = Cs2Area->mpegcon[0].vidcon = 0x00; - Cs2Area->mpegcon[0].audlay = Cs2Area->mpegcon[0].vidlay = 0x00; - Cs2Area->mpegcon[0].audbufdivnum = Cs2Area->mpegcon[0].vidbufdivnum = 0xFF; - Cs2Area->mpegcon[1].audcon = Cs2Area->mpegcon[1].vidcon = 0x00; - Cs2Area->mpegcon[1].audlay = Cs2Area->mpegcon[1].vidlay = 0x00; - Cs2Area->mpegcon[1].audbufdivnum = Cs2Area->mpegcon[1].vidbufdivnum = 0xFF; - - // should verify the following - Cs2Area->mpegstm[0].audstm = Cs2Area->mpegstm[0].vidstm = 0x00; - Cs2Area->mpegstm[0].audstmid = Cs2Area->mpegstm[0].vidstmid = 0x00; - Cs2Area->mpegstm[0].audchannum = Cs2Area->mpegstm[0].vidchannum = 0x00; - Cs2Area->mpegstm[1].audstm = Cs2Area->mpegstm[1].vidstm = 0x00; - Cs2Area->mpegstm[1].audstmid = Cs2Area->mpegstm[1].vidstmid = 0x00; - Cs2Area->mpegstm[1].audchannum = Cs2Area->mpegstm[1].vidchannum = 0x00; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2Exec(u32 timing) { - Cs2Area->_periodiccycles += timing * 3; - - if (Cs2Area->_commandtiming > 0) - { - if (Cs2Area->_commandtiming < timing) - { - Cs2Execute(); - Cs2Area->_commandtiming = 0; - } - else - Cs2Area->_commandtiming -= timing; - } - - if (Cs2Area->_periodiccycles >= Cs2Area->_periodictiming) - { - Cs2Area->_periodiccycles -= Cs2Area->_periodictiming; - - // Get Drive's current status and compare with old status -// switch(cd->getStatus()) // this shouldn't be called every periodic response - switch(0) - { - case 0: - case 1: - if ((Cs2Area->status & 0xF) == CDB_STAT_NODISC || - (Cs2Area->status & 0xF) == CDB_STAT_OPEN) - { - Cs2Area->status = CDB_STAT_PAUSE; - Cs2Area->isdiskchanged = 1; - } - break; - case 2: - // may need to change this - if ((Cs2Area->status & 0xF) != CDB_STAT_NODISC) - Cs2Area->status = CDB_STAT_NODISC; - break; - case 3: - // may need to change this - if ((Cs2Area->status & 0xF) != CDB_STAT_OPEN) - Cs2Area->status = CDB_STAT_OPEN; - break; - default: break; - } - - switch (Cs2Area->status & 0xF) { - case CDB_STAT_PAUSE: - { -// if (FAD >= playFAD && FAD < playendFAD) -// status = CDB_STAT_PLAY; -// else - break; - } - case CDB_STAT_PLAY: - { - partition_struct * playpartition; - int ret = Cs2ReadFilteredSector(Cs2Area->FAD, &playpartition); - - switch (ret) - { - case 0: - // Sector Read OK - Cs2Area->FAD++; - Cs2Area->cdi->ReadAheadFAD(Cs2Area->FAD); - - if (playpartition != NULL) - { - // We can use this sector - CDLOG("partition number = %d blocks = %d blockfreespace = %d fad = %x playpartition->size = %x isbufferfull = %x\n", (playpartition - Cs2Area->partition), playpartition->numblocks, Cs2Area->blockfreespace, Cs2Area->FAD, playpartition->size, Cs2Area->isbufferfull); - - Cs2Area->reg.HIRQ |= CDB_HIRQ_CSCT; - Cs2Area->isonesectorstored = 1; - - if (Cs2Area->FAD >= Cs2Area->playendFAD) { - // Make sure we don't have to do a repeat - if (Cs2Area->repcnt >= Cs2Area->maxrepeat) { - // we're done - Cs2Area->status = CDB_STAT_PAUSE; - Cs2SetTiming(0); - Cs2Area->reg.HIRQ |= CDB_HIRQ_PEND; - - if (Cs2Area->playtype == CDB_PLAYTYPE_FILE) - Cs2Area->reg.HIRQ |= CDB_HIRQ_EFLS; - - CDLOG("PLAY HAS ENDED\n"); - } - else { - - Cs2Area->FAD = Cs2Area->playFAD; - if (Cs2Area->repcnt < 0xE) - Cs2Area->repcnt++; - Cs2Area->track = Cs2FADToTrack(Cs2Area->FAD); - - CDLOG("PLAY HAS REPEATED\n"); - } - } - if (Cs2Area->isbufferfull) { - CDLOG("BUFFER IS FULL\n"); -// status = CDB_STAT_PAUSE; - } - } - else - { - CDLOG("Sector filtered out\n"); - if (Cs2Area->FAD >= Cs2Area->playendFAD) { - // Make sure we don't have to do a repeat - if (Cs2Area->repcnt >= Cs2Area->maxrepeat) { - // we're done - Cs2Area->status = CDB_STAT_PAUSE; - Cs2SetTiming(0); - Cs2Area->reg.HIRQ |= CDB_HIRQ_PEND; - - if (Cs2Area->playtype == CDB_PLAYTYPE_FILE) - Cs2Area->reg.HIRQ |= CDB_HIRQ_EFLS; - - CDLOG("PLAY HAS ENDED\n"); - } - else { - Cs2Area->FAD = Cs2Area->playFAD; - if (Cs2Area->repcnt < 0xE) - Cs2Area->repcnt++; - Cs2Area->track = Cs2FADToTrack(Cs2Area->FAD); - - CDLOG("PLAY HAS REPEATED\n"); - } - } - } - break; - case -1: - // Things weren't setup correctly - break; - case -2: - // Do a read retry - break; - } - - break; - } - case CDB_STAT_SEEK: - break; - case CDB_STAT_SCAN: - break; - case CDB_STAT_RETRY: - break; - default: break; - } - - if (Cs2Area->_command) - return; - - Cs2Area->status |= CDB_STAT_PERI; - - // adjust registers appropriately here(fix me) - doCDReport(Cs2Area->status); - - Cs2Area->reg.HIRQ |= CDB_HIRQ_SCDQ; - } - - if(Cs2Area->carttype == CART_NETLINK) - NetlinkExec(timing); -} - -////////////////////////////////////////////////////////////////////////////// - -/* Returns the number of (emulated) microseconds before the next sector - * will have been completely read in */ -int Cs2GetTimeToNextSector(void) { - if ((Cs2Area->status & 0xF) != CDB_STAT_PLAY) { - return 0; - } else { - // Round up, since the caller wants to know when it'll be safe to check - int time = (Cs2Area->_periodictiming - Cs2Area->_periodiccycles + 2) / 3; - return time<0 ? 0 : time; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2Command(void) { - Cs2Area->_command = 1; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetTiming(int playing) { - if (playing) { - if (Cs2Area->isaudio || Cs2Area->speed1x == 1) - Cs2Area->_periodictiming = 40000; // 13333.333... * 3 - else - Cs2Area->_periodictiming = 20000; // 6666.666... * 3 - } - else { - Cs2Area->_periodictiming = 50000; // 16666.666... * 3 - } -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetCommandTiming(u8 cmd) { - switch(cmd) { - default: - Cs2Area->_commandtiming = 1; - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2Execute(void) { - u16 instruction = Cs2Area->reg.CR1 >> 8; - - Cs2Area->reg.HIRQ &= ~CDB_HIRQ_CMOK; - - switch (instruction) { - case 0x00: - CDLOG("cs2\t: Command: getStatus\n"); - Cs2GetStatus(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x01: - CDLOG("cs2\t: Command: getHardwareInfo\n"); - Cs2GetHardwareInfo(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x02: - CDLOG("cs2\t: Command: getToc\n"); - Cs2GetToc(); - break; - case 0x03: - CDLOG("cs2\t: Command: getSessionInfo\n"); - Cs2GetSessionInfo(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x04: - CDLOG("cs2\t: Command: initializeCDSystem %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2InitializeCDSystem(); - break; - case 0x06: - CDLOG("cs2\t: Command: endDataTransfer %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2EndDataTransfer(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x10: - CDLOG("cs2\t: Command: playDisc %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2PlayDisc(); - break; - case 0x11: - CDLOG("cs2\t: Command: seekDisc %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2SeekDisc(); - break; - case 0x20: - CDLOG("cs2\t: Command: getSubcodeQRW %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2GetSubcodeQRW(); - break; - case 0x30: - CDLOG("cs2\t: Command: setCDDeviceConnection %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2SetCDDeviceConnection(); - break; - case 0x32: - CDLOG("cs2\t: Command: getLastBufferDestination %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2GetLastBufferDestination(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x40: - CDLOG("cs2\t: Command: setFilterRange\n"); - Cs2SetFilterRange(); - break; - case 0x42: - CDLOG("cs2\t: Command: setFilterSubheaderConditions\n"); - Cs2SetFilterSubheaderConditions(); - break; - case 0x43: - CDLOG("cs2\t: Command: getFilterSubheaderConditions\n"); - Cs2GetFilterSubheaderConditions(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x44: - CDLOG("cs2\t: Command: setFilterMode\n"); - Cs2SetFilterMode(); - break; - case 0x45: - CDLOG("cs2\t: Command: getFilterMode\n"); - Cs2GetFilterMode(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x46: - CDLOG("cs2\t: Command: setFilterConnection\n"); - Cs2SetFilterConnection(); - break; - case 0x48: - CDLOG("cs2\t: Command: resetSelector %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2ResetSelector(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x50: - CDLOG("cs2\t: Command: getBufferSize\n"); - Cs2GetBufferSize(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x51: -// CDLOG("cs2\t: Command: getSectorNumber %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2GetSectorNumber(); -// CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x52: - CDLOG("cs2\t: Command: calculateActualSize %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2CalculateActualSize(); - break; - case 0x53: - CDLOG("cs2\t: Command: getActualSize\n"); - Cs2GetActualSize(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x54: - CDLOG("cs2\t: Command: getSectorInfo %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2GetSectorInfo(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x60: - CDLOG("cs2\t: Command: setSectorLength %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2SetSectorLength(); - break; - case 0x61: - CDLOG("cs2\t: Command: getSectorData %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2GetSectorData(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x62: - CDLOG("cs2\t: Command: deleteSectorData %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2DeleteSectorData(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x63: - CDLOG("cs2\t: Command: getThenDeleteSectorData %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2GetThenDeleteSectorData(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x64: - CDLOG("cs2\t: Command: putSectorData %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2PutSectorData(); - break; - case 0x67: - CDLOG("cs2\t: Command: getCopyError\n"); - Cs2GetCopyError(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x70: - CDLOG("cs2\t: Command: changeDirectory %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2ChangeDirectory(); - break; - case 0x71: - CDLOG("cs2\t: Command: readDirectory %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2ReadDirectory(); - break; - case 0x72: - CDLOG("cs2\t: Command: getFileSystemScope\n"); - Cs2GetFileSystemScope(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x73: - CDLOG("cs2\t: Command: getFileInfo %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2GetFileInfo(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x74: - CDLOG("cs2\t: Command: readFile %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2ReadFile(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x75: - CDLOG("cs2\t: Command: abortFile\n"); - Cs2AbortFile(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x90: - CDLOG("cs2\t: Command: mpegGetStatus\n"); - Cs2MpegGetStatus(); - break; - case 0x91: - CDLOG("cs2\t: Command: mpegGetInterrupt\n"); - Cs2MpegGetInterrupt(); - CDLOG("cs2\t: ret: %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - break; - case 0x92: - CDLOG("cs2\t: Command: mpegSetInterruptMask\n"); - Cs2MpegSetInterruptMask(); - break; - case 0x93: - CDLOG("cs2\t: Command: mpegInit\n"); - Cs2MpegInit(); - break; - case 0x94: - CDLOG("cs2\t: Command: mpegSetMode\n"); - Cs2MpegSetMode(); - break; - case 0x95: - CDLOG("cs2\t: Command: mpegPlay\n"); - Cs2MpegPlay(); - break; - case 0x96: - CDLOG("cs2\t: Command: mpegSetDecodingMethod\n"); - Cs2MpegSetDecodingMethod(); - break; - case 0x9A: - CDLOG("cs2\t: Command: mpegSetConnection\n"); - Cs2MpegSetConnection(); - break; - case 0x9B: - CDLOG("cs2\t: Command: mpegGetConnection\n"); - Cs2MpegGetConnection(); - break; - case 0x9D: - CDLOG("cs2\t: Command: mpegSetStream\n"); - Cs2MpegSetStream(); - break; - case 0x9E: - CDLOG("cs2\t: Command: mpegGetStream\n"); - Cs2MpegGetStream(); - break; - case 0xA0: - CDLOG("cs2\t: Command: mpegDisplay\n"); - Cs2MpegDisplay(); - break; - case 0xA1: - CDLOG("cs2\t: Command: mpegSetWindow\n"); - Cs2MpegSetWindow(); - break; - case 0xA2: - CDLOG("cs2\t: Command: mpegSetBorderColor\n"); - Cs2MpegSetBorderColor(); - break; - case 0xA3: - CDLOG("cs2\t: Command: mpegSetFade\n"); - Cs2MpegSetFade(); - break; - case 0xA4: - CDLOG("cs2\t: Command: mpegSetVideoEffects\n"); - Cs2MpegSetVideoEffects(); - break; - case 0xAF: - CDLOG("cs2\t: Command: mpegSetLSI\n"); - Cs2MpegSetLSI(); - break; - case 0xE0: - CDLOG("cs2\t: Command: cmdE0 %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2CmdE0(); - break; - case 0xE1: - CDLOG("cs2\t: Command: cmdE1 %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2CmdE1(); - break; - case 0xE2: - CDLOG("cs2\t: Command: cmdE2 %04x %04x %04x %04x %04x\n", Cs2Area->reg.HIRQ, Cs2Area->reg.CR1, Cs2Area->reg.CR2, Cs2Area->reg.CR3, Cs2Area->reg.CR4); - Cs2CmdE2(); - break; - default: - CDLOG("cs2\t: Command %02x not implemented\n", instruction); - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetStatus(void) { - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetHardwareInfo(void) { - if ((Cs2Area->status & 0xF) != CDB_STAT_OPEN && (Cs2Area->status & 0xF) != CDB_STAT_NODISC) - Cs2Area->isdiskchanged = 0; - - Cs2Area->reg.CR1 = Cs2Area->status << 8; - // hardware flags/CD Version - Cs2Area->reg.CR2 = 0x0201; // mpeg card exists - // mpeg version, it actually is required(at least by the bios) - - if (Cs2Area->mpgauth) - Cs2Area->reg.CR3 = 0x1; - else - Cs2Area->reg.CR3 = 0; - - // drive info/revision - Cs2Area->reg.CR4 = 0x0400; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetToc(void) { - Cs2Area->cdi->ReadTOC(Cs2Area->TOC); - - Cs2Area->transfercount = 0; - Cs2Area->infotranstype = 0; - - Cs2Area->reg.CR1 = Cs2Area->status << 8; - Cs2Area->reg.CR2 = 0xCC; - Cs2Area->reg.CR3 = 0x0; - Cs2Area->reg.CR4 = 0x0; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_DRDY; - Cs2Area->status = CDB_STAT_PAUSE; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetSessionInfo(void) { - - switch (Cs2Area->reg.CR1 & 0xFF) { - case 0: - Cs2Area->reg.CR3 = (u16)(0x0100 | ((Cs2Area->TOC[101] & 0xFF0000) >> 16)); - Cs2Area->reg.CR4 = (u16)Cs2Area->TOC[101]; - break; - case 1: - Cs2Area->reg.CR3 = 0x0100; // return Session number(high byte)/and first byte of Session lba - Cs2Area->reg.CR4 = 0; // lower word of Session lba - break; - default: - Cs2Area->reg.CR3 = 0xFFFF; - Cs2Area->reg.CR4 = 0xFFFF; - break; - } - - Cs2Area->status = CDB_STAT_PAUSE; - Cs2Area->reg.CR1 = Cs2Area->status << 8; - Cs2Area->reg.CR2 = 0; - - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2InitializeCDSystem(void) { - u16 val = 0; - u8 initflag = Cs2Area->reg.CR1 & 0xFF; - - if ((Cs2Area->status & 0xF) != CDB_STAT_OPEN && (Cs2Area->status & 0xF) != CDB_STAT_NODISC) - { - Cs2Area->status = CDB_STAT_PAUSE; - Cs2Area->FAD = 150; - } - - if (initflag & 0x1) - { - // Reset CD block software - } - - if (initflag & 0x2) - { - // Decode RW subcode - } - - if (initflag & 0x4) - { - // Don't confirm Mode 2 subheader - } - - if (initflag & 0x8) - { - // Retry reading Form 2 sectors - } - - if (initflag & 0x10) - Cs2Area->speed1x = 1; - else - Cs2Area->speed1x = 0; - - val = Cs2Area->reg.HIRQ & 0xFFE5; - Cs2Area->isbufferfull = 0; - - if (Cs2Area->isdiskchanged) - val |= CDB_HIRQ_DCHG; - else - val &= ~CDB_HIRQ_DCHG; - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ = val | CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2EndDataTransfer(void) { - s32 i; - if (Cs2Area->cdwnum) - { - Cs2Area->reg.CR1 = (u16)((Cs2Area->status << 8) | ((Cs2Area->cdwnum >> 17) & 0xFF)); - Cs2Area->reg.CR2 = (u16)(Cs2Area->cdwnum >> 1); - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - } - else - { - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | 0xFF; // FIXME - Cs2Area->reg.CR2 = 0xFFFF; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - } - - // stop any transfers that may be going(this is still probably wrong), and - // set/clear the appropriate flags - - switch (Cs2Area->datatranstype) - { - case 0: - // Get Sector Data - Cs2Area->reg.HIRQ |= CDB_HIRQ_EHST; - break; - case 2: - { - // Get Then Delete Sector - - // Make sure we actually have to free something - if (Cs2Area->datatranspartition->size <= 0) break; - - Cs2Area->datatranstype = -1; - - // free blocks - for (i = Cs2Area->datatranssectpos; i < (Cs2Area->datatranssectpos + Cs2Area->datasectstotrans); i++) - { - Cs2FreeBlock(Cs2Area->datatranspartition->block[i]); - Cs2Area->datatranspartition->block[i] = NULL; - Cs2Area->datatranspartition->blocknum[i] = 0xFF; - } - - // sort remaining blocks - Cs2SortBlocks(Cs2Area->datatranspartition); - - Cs2Area->datatranspartition->size -= Cs2Area->cdwnum; - Cs2Area->datatranspartition->numblocks -= Cs2Area->datasectstotrans; - - if (Cs2Area->blockfreespace == 200) Cs2Area->isonesectorstored = 0; - - Cs2Area->reg.HIRQ |= CDB_HIRQ_EHST; - break; - } - default: break; - } - - Cs2Area->cdwnum = 0; - - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2PlayDisc(void) { - u32 pdspos; - u32 pdepos; - u32 pdpmode; - - // Get all the arguments - pdspos = ((Cs2Area->reg.CR1 & 0xFF) << 16) | Cs2Area->reg.CR2; - pdepos = ((Cs2Area->reg.CR3 & 0xFF) << 16) | Cs2Area->reg.CR4; - pdpmode = Cs2Area->reg.CR3 >> 8; - - // Convert Start Position to playFAD - if (pdspos == 0xFFFFFF || pdpmode == 0xFF) // This still isn't right - { - // No Change - } - else if (pdspos & 0x800000) - { - // FAD Mode - Cs2Area->playFAD = (pdspos & 0xFFFFF); - - Cs2SetupDefaultPlayStats(Cs2FADToTrack(Cs2Area->playFAD), 0); - - if (!(pdpmode & 0x80)) - // Move pickup to start position - Cs2Area->FAD = Cs2Area->playFAD; - } - else - { - // Track Mode - - // If track == 0, set it to the first available track, or something like that - if (pdspos == 0) - pdspos = 0x0100; - - if (!(pdpmode & 0x80)) - { - Cs2SetupDefaultPlayStats((u8)(pdspos >> 8), 1); - Cs2Area->playFAD = Cs2Area->FAD; - Cs2Area->track = (u8)(pdspos >> 8); - Cs2Area->index = (u8)pdspos; - } - else - { - // Preserve Pickup Position - Cs2SetupDefaultPlayStats((u8)(pdspos >> 8), 0); - } - } - - pdpmode &= 0x7F; - - // Only update max repeat if bits 0-6 aren't all set - if (pdpmode != 0x7F) - Cs2Area->maxrepeat = pdpmode; - - // Convert End Position to playendFAD - if (pdepos == 0xFFFFFF) - { - // No Change - } - else if (pdepos & 0x800000) - { - // FAD Mode - Cs2Area->playendFAD = Cs2Area->playFAD+(pdepos & 0xFFFFF); - } - else if (pdepos != 0) - { - // Track Mode - if ((pdepos & 0xFF) == 0) - Cs2Area->playendFAD = Cs2TrackToFAD((u16)(pdepos | 0x0063)); - else - Cs2Area->playendFAD = Cs2TrackToFAD((u16)pdepos); - } - else - { - // Default Mode - Cs2Area->playendFAD = Cs2TrackToFAD(0xFFFF); - } - - // setup play mode here -#if CDDEBUG - if (pdpmode != 0) - CDLOG("cs2\t: playDisc: Unsupported play mode = %02X\n", pdpmode); -#endif - - Cs2SetTiming(1); - - Cs2Area->status = CDB_STAT_PLAY; - Cs2Area->playtype = CDB_PLAYTYPE_SECTOR; - Cs2Area->cdi->ReadAheadFAD(Cs2Area->FAD); - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SeekDisc(void) { - if (Cs2Area->reg.CR1 & 0x80) - { - // Seek by FAD - u32 sdFAD; - - sdFAD = ((Cs2Area->reg.CR1 & 0xFF) << 16) | Cs2Area->reg.CR2; - - if (sdFAD == 0xFFFFFF) - Cs2Area->status = CDB_STAT_PAUSE; - else - { - CDLOG("cs2\t: seekDisc - FAD Mode not supported\n"); - } - } - else - { - // Were we given a valid track number? - if (Cs2Area->reg.CR2 >> 8) - { - // Seek by index - Cs2Area->status = CDB_STAT_PAUSE; - Cs2SetupDefaultPlayStats((Cs2Area->reg.CR2 >> 8), 1); - Cs2Area->index = Cs2Area->reg.CR2 & 0xFF; - } - else - { - // Error - Cs2Area->status = CDB_STAT_STANDBY; - Cs2Area->options = 0xFF; - Cs2Area->repcnt = 0xFF; - Cs2Area->ctrladdr = 0xFF; - Cs2Area->track = 0xFF; - Cs2Area->index = 0xFF; - Cs2Area->FAD = 0xFFFFFFFF; - } - } - - Cs2SetTiming(0); - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetSubcodeQRW(void) { - // According to Tyranid's doc, the subcode type is stored in the low byte - // of CR2. However, Sega's CDC library writes the type to the low byte - // of CR1. Somehow I'd sooner believe Sega is right. - switch(Cs2Area->reg.CR1 & 0xFF) { - case 0: - // Get Q Channel - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | 0; - Cs2Area->reg.CR2 = 5; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - - // setup transfer here(fix me) - break; - case 1: - // Get RW Channel - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | 0; - Cs2Area->reg.CR2 = 12; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - - // setup transfer here(fix me) - break; - default: break; - } - - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_DRDY; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetCDDeviceConnection(void) { - u32 scdcfilternum; - - scdcfilternum = (Cs2Area->reg.CR3 >> 8); - - if (scdcfilternum == 0xFF) - Cs2Area->outconcddev = NULL; - else if (scdcfilternum < 0x24) - Cs2Area->outconcddev = Cs2Area->filter + scdcfilternum; - - Cs2Area->outconcddevnum = (u8)scdcfilternum; - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetLastBufferDestination(void) { - Cs2Area->reg.CR1 = (Cs2Area->status << 8); - Cs2Area->reg.CR2 = 0; - Cs2Area->reg.CR3 = Cs2Area->lastbuffer << 8; - Cs2Area->reg.CR4 = 0; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetFilterRange(void) { - u8 sfrfilternum; - - sfrfilternum = Cs2Area->reg.CR3 >> 8; - - Cs2Area->filter[sfrfilternum].FAD = ((Cs2Area->reg.CR1 & 0xFF) << 16) | Cs2Area->reg.CR2; - Cs2Area->filter[sfrfilternum].range = ((Cs2Area->reg.CR3 & 0xFF) << 16) | Cs2Area->reg.CR4; - - // return default cd stats - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetFilterSubheaderConditions(void) { - u8 sfscfilternum; - - sfscfilternum = Cs2Area->reg.CR3 >> 8; - - Cs2Area->filter[sfscfilternum].chan = Cs2Area->reg.CR1 & 0xFF; - Cs2Area->filter[sfscfilternum].smmask = Cs2Area->reg.CR2 >> 8; - Cs2Area->filter[sfscfilternum].cimask = Cs2Area->reg.CR2 & 0xFF; - Cs2Area->filter[sfscfilternum].fid = Cs2Area->reg.CR3 & 0xFF;; - Cs2Area->filter[sfscfilternum].smval = Cs2Area->reg.CR4 >> 8; - Cs2Area->filter[sfscfilternum].cival = Cs2Area->reg.CR4 & 0xFF; - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetFilterSubheaderConditions(void) { - u8 gfscfilternum; - - gfscfilternum = Cs2Area->reg.CR3 >> 8; - - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | Cs2Area->filter[gfscfilternum].chan; - Cs2Area->reg.CR2 = (Cs2Area->filter[gfscfilternum].smmask << 8) | Cs2Area->filter[gfscfilternum].cimask; - Cs2Area->reg.CR3 = Cs2Area->filter[gfscfilternum].fid; - Cs2Area->reg.CR4 = (Cs2Area->filter[gfscfilternum].smval << 8) | Cs2Area->filter[gfscfilternum].cival; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetFilterMode(void) { - u8 sfmfilternum; - - sfmfilternum = Cs2Area->reg.CR3 >> 8; - - Cs2Area->filter[sfmfilternum].mode = Cs2Area->reg.CR1 & 0xFF; - - if (Cs2Area->filter[sfmfilternum].mode & 0x80) - { - // Initialize filter conditions - Cs2Area->filter[sfmfilternum].mode = 0; - Cs2Area->filter[sfmfilternum].FAD = 0; - Cs2Area->filter[sfmfilternum].range = 0; - Cs2Area->filter[sfmfilternum].chan = 0; - Cs2Area->filter[sfmfilternum].smmask = 0; - Cs2Area->filter[sfmfilternum].cimask = 0; - Cs2Area->filter[sfmfilternum].smval = 0; - Cs2Area->filter[sfmfilternum].cival = 0; - } - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetFilterMode(void) { - u8 gfmfilternum; - - gfmfilternum = Cs2Area->reg.CR3 >> 8; - - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | Cs2Area->filter[gfmfilternum].mode; - Cs2Area->reg.CR2 = 0; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetFilterConnection(void) { - u8 sfcfilternum; - - sfcfilternum = Cs2Area->reg.CR3 >> 8; - - if (Cs2Area->reg.CR1 & 0x1) - { - // Set connection for true condition - Cs2Area->filter[sfcfilternum].condtrue = Cs2Area->reg.CR2 >> 8; - } - - if (Cs2Area->reg.CR1 & 0x2) - { - // Set connection for false condition - Cs2Area->filter[sfcfilternum].condfalse = Cs2Area->reg.CR2 & 0xFF; - } - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2ResetSelector(void) { - // still needs a bit of work - u32 i, i2; - - if ((Cs2Area->reg.CR1 & 0xFF) == 0) - { - // Reset specified partition buffer only - u32 rsbufno = Cs2Area->reg.CR3 >> 8; - - // sort remaining blocks - if (rsbufno < MAX_SELECTORS) - { - // clear partition - for (i = 0; i < Cs2Area->partition[rsbufno].numblocks; i++) - { - Cs2FreeBlock(Cs2Area->partition[rsbufno].block[i]); - Cs2Area->partition[rsbufno].block[i] = NULL; - Cs2Area->partition[rsbufno].blocknum[i] = 0xFF; - } - - Cs2Area->partition[rsbufno].size = -1; - Cs2Area->partition[rsbufno].numblocks = 0; - } - - if (Cs2Area->blockfreespace > 0) Cs2Area->isbufferfull = 0; - if (Cs2Area->blockfreespace == 200) Cs2Area->isonesectorstored = 0; - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; - return; - } - - // parse flags and reset the specified area(fix me) - if (Cs2Area->reg.CR1 & 0x80) - { - // reset false filter output connections - for (i = 0; i < MAX_SELECTORS; i++) - Cs2Area->filter[i].condfalse = 0xFF; - } - - if (Cs2Area->reg.CR1 & 0x40) - { - // reset true filter output connections - for (i = 0; i < MAX_SELECTORS; i++) - Cs2Area->filter[i].condtrue = (u8)i; - } - - if (Cs2Area->reg.CR1 & 0x10) - { - // reset filter conditions - for (i = 0; i < MAX_SELECTORS; i++) - { - Cs2Area->filter[i].FAD = 0; - Cs2Area->filter[i].range = 0xFFFFFFFF; - Cs2Area->filter[i].mode = 0; - Cs2Area->filter[i].chan = 0; - Cs2Area->filter[i].smmask = 0; - Cs2Area->filter[i].cimask = 0; - Cs2Area->filter[i].fid = 0; - Cs2Area->filter[i].smval = 0; - Cs2Area->filter[i].cival = 0; - } - } - - if (Cs2Area->reg.CR1 & 0x8) - { - // reset partition output connectors - } - - if (Cs2Area->reg.CR1 & 0x4) - { - // reset partitions buffer data - Cs2Area->isbufferfull = 0; - - // clear partitions - for (i = 0; i < MAX_SELECTORS; i++) - { - Cs2Area->partition[i].size = -1; - Cs2Area->partition[i].numblocks = 0; - - for (i2 = 0; i2 < MAX_BLOCKS; i2++) - { - Cs2Area->partition[i].block[i2] = NULL; - Cs2Area->partition[i].blocknum[i2] = 0xFF; - } - } - - // clear blocks - for (i = 0; i < MAX_BLOCKS; i++) - { - Cs2Area->block[i].size = -1; - memset(Cs2Area->block[i].data, 0, 2352); - } - - Cs2Area->isonesectorstored = 0; - } - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetBufferSize(void) { - Cs2Area->reg.CR1 = Cs2Area->status << 8; - Cs2Area->reg.CR2 = (u16)Cs2Area->blockfreespace; - Cs2Area->reg.CR3 = MAX_SELECTORS << 8; - Cs2Area->reg.CR4 = MAX_BLOCKS; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetSectorNumber(void) { - u32 gsnbufno; - - gsnbufno = Cs2Area->reg.CR3 >> 8; - - if (Cs2Area->partition[gsnbufno].size == -1) - Cs2Area->reg.CR4 = 0; - else - Cs2Area->reg.CR4 = Cs2Area->partition[gsnbufno].numblocks; - - Cs2Area->reg.CR1 = Cs2Area->status << 8; - Cs2Area->reg.CR2 = 0; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_DRDY; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2CalculateActualSize(void) { - u16 i; - u32 casbufno; - u16 cassectoffset; - u16 casnumsect; - - cassectoffset = Cs2Area->reg.CR2; - casbufno = Cs2Area->reg.CR3 >> 8; - casnumsect = Cs2Area->reg.CR4; - - if (Cs2Area->partition[casbufno].size != 0) - { - Cs2Area->calcsize = 0; - - for (i = 0; i < casnumsect; i++) - { - if (Cs2Area->partition[casbufno].block[cassectoffset]) - Cs2Area->calcsize += (Cs2Area->partition[casbufno].block[cassectoffset]->size / 2); - } - } - else - Cs2Area->calcsize = 0; - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetActualSize(void) { - Cs2Area->reg.CR1 = (u16)((Cs2Area->status << 8) | ((Cs2Area->calcsize >> 16) & 0xFF)); - Cs2Area->reg.CR2 = (u16)Cs2Area->calcsize; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetSectorInfo(void) { - u32 gsisctnum; - u32 gsibufno; - - gsisctnum = Cs2Area->reg.CR2 & 0xFF; - gsibufno = Cs2Area->reg.CR3 >> 8; - if (gsibufno < MAX_SELECTORS) { - if (gsisctnum < Cs2Area->partition[gsibufno].numblocks) { - Cs2Area->reg.CR1 = (u16)((Cs2Area->status << 8) | ((Cs2Area->partition[gsibufno].block[gsisctnum]->FAD >> 16) & 0xFF)); - Cs2Area->reg.CR2 = (u16)Cs2Area->partition[gsibufno].block[gsisctnum]->FAD; - Cs2Area->reg.CR3 = (Cs2Area->partition[gsibufno].block[gsisctnum]->fn << 8) | Cs2Area->partition[gsibufno].block[gsisctnum]->cn; - Cs2Area->reg.CR4 = (Cs2Area->partition[gsibufno].block[gsisctnum]->sm << 8) | Cs2Area->partition[gsibufno].block[gsisctnum]->ci; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; - return; - } - else - { - CDLOG("cs2\t: getSectorInfo: Unsupported Partition Number\n"); - } - } - - Cs2Area->reg.CR1 = (CDB_STAT_REJECT << 8) | (Cs2Area->reg.CR1 & 0xFF); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetSectorLength(void) { - switch (Cs2Area->reg.CR1 & 0xFF) { - case 0: - Cs2Area->getsectsize = 2048; - break; - case 1: - Cs2Area->getsectsize = 2336; - break; - case 2: - Cs2Area->getsectsize = 2340; - break; - case 3: - Cs2Area->getsectsize = 2352; - break; - default: break; - } - - switch (Cs2Area->reg.CR2 >> 8) { - case 0: - Cs2Area->putsectsize = 2048; - break; - case 1: - Cs2Area->putsectsize = 2336; - break; - case 2: - Cs2Area->putsectsize = 2340; - break; - case 3: - Cs2Area->putsectsize = 2352; - break; - default: break; - } - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_ESEL; -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE void CalcSectorOffsetNumber(u32 bufno, u32 *sectoffset, u32 *sectnum) -{ - if (*sectoffset == 0xFFFF) - { - // Last sector - CDLOG("FIXME - Sector offset of 0xFFFF not supported\n"); - } - else if (*sectnum == 0xFFFF) - { - // From sectoffset to last sector in partition - *sectnum = Cs2Area->partition[bufno].numblocks - *sectoffset; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetSectorData(void) -{ - u32 gsdsectoffset; - u32 gsdbufno; - u32 gsdsectnum; - - gsdsectoffset = Cs2Area->reg.CR2; - gsdbufno = Cs2Area->reg.CR3 >> 8; - gsdsectnum = Cs2Area->reg.CR4; - - if (gsdbufno >= MAX_SELECTORS) - { - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; - return; - } - - if (Cs2Area->partition[gsdbufno].numblocks == 0) - { - CDLOG("No sectors available\n"); - - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; - return; - } - - CalcSectorOffsetNumber(gsdbufno, &gsdsectoffset, &gsdsectnum); - - // Setup Data Transfer - Cs2Area->cdwnum = 0; - Cs2Area->datatranstype = 0; - Cs2Area->datatranspartition = Cs2Area->partition + gsdbufno; - Cs2Area->datatranspartitionnum = (u8)gsdbufno; - Cs2Area->datatransoffset = 0; - Cs2Area->datanumsecttrans = 0; - Cs2Area->datatranssectpos = (u16)gsdsectoffset; - Cs2Area->datasectstotrans = (u16)gsdsectnum; - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_DRDY | CDB_HIRQ_EHST; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2DeleteSectorData(void) -{ - u32 dsdsectoffset; - u32 dsdbufno; - u32 dsdsectnum; - u32 i; - - dsdsectoffset = Cs2Area->reg.CR2; - dsdbufno = Cs2Area->reg.CR3 >> 8; - dsdsectnum = Cs2Area->reg.CR4; - - if (dsdbufno >= MAX_SELECTORS) - { - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; - return; - } - - if (Cs2Area->partition[dsdbufno].numblocks == 0) - { - CDLOG("No sectors available\n"); - - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; - return; - } - - CalcSectorOffsetNumber(dsdbufno, &dsdsectoffset, &dsdsectnum); - - for (i = dsdsectoffset; i < (dsdsectoffset+dsdsectnum); i++) - { - Cs2Area->partition[dsdbufno].size -= Cs2Area->partition[dsdbufno].block[i]->size; - Cs2FreeBlock(Cs2Area->partition[dsdbufno].block[i]); - Cs2Area->partition[dsdbufno].block[i] = NULL; - Cs2Area->partition[dsdbufno].blocknum[i] = 0xFF; - } - - // sort remaining blocks - Cs2SortBlocks(&Cs2Area->partition[dsdbufno]); - - Cs2Area->partition[dsdbufno].numblocks -= (u8)dsdsectnum; - - if (Cs2Area->blockfreespace == 200) - Cs2Area->isonesectorstored = 0; - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetThenDeleteSectorData(void) -{ - u32 gtdsdsectoffset; - u32 gtdsdbufno; - u32 gtdsdsectnum; - - gtdsdsectoffset = Cs2Area->reg.CR2; - gtdsdbufno = Cs2Area->reg.CR3 >> 8; - gtdsdsectnum = Cs2Area->reg.CR4; - - if (gtdsdbufno >= MAX_SELECTORS) - { - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; - return; - } - - if (Cs2Area->partition[gtdsdbufno].numblocks == 0) - { - CDLOG("No sectors available\n"); - - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; - return; - } - - CalcSectorOffsetNumber(gtdsdbufno, >dsdsectoffset, >dsdsectnum); - - // Setup Data Transfer - Cs2Area->cdwnum = 0; - Cs2Area->datatranstype = 2; - Cs2Area->datatranspartition = Cs2Area->partition + gtdsdbufno; - Cs2Area->datatransoffset = 0; - Cs2Area->datanumsecttrans = 0; - Cs2Area->datatranssectpos = (u16)gtdsdsectoffset; - Cs2Area->datasectstotrans = (u16)gtdsdsectnum; - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_DRDY | CDB_HIRQ_EHST; - - return; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2PutSectorData(void) { - u32 psdfiltno; - - psdfiltno = Cs2Area->reg.CR3 >> 8; - - if (psdfiltno < MAX_SELECTORS) - { - // I'm not really sure what I'm supposed to really be doing or returning - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; - } - else - { - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EHST; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetCopyError(void) { - Cs2Area->reg.CR1 = Cs2Area->status << 8; - Cs2Area->reg.CR2 = 0; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2ChangeDirectory(void) { - u32 cdfilternum; - - cdfilternum = (Cs2Area->reg.CR3 >> 8); - - if (cdfilternum == 0xFF) - { - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EFLS; - return; - } - else if (cdfilternum < 0x24) - { - if (Cs2ReadFileSystem(Cs2Area->filter + cdfilternum, ((Cs2Area->reg.CR3 & 0xFF) << 16) | Cs2Area->reg.CR4, 0) != 0) - { - CDLOG("cs2\t: ReadFileSystem failed\n"); - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EFLS; - return; - } - } - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EFLS; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2ReadDirectory(void) { - u32 rdfilternum; - - rdfilternum = (Cs2Area->reg.CR3 >> 8); - - if (rdfilternum == 0xFF) - { - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EFLS; - return; - } - else if (rdfilternum < 0x24) - { - if (Cs2ReadFileSystem(Cs2Area->filter + rdfilternum, ((Cs2Area->reg.CR3 & 0xFF) << 8) | Cs2Area->reg.CR4, 1) != 0) - { - CDLOG("cs2\t: ReadFileSystem failed\n"); - doCDReport(CDB_STAT_REJECT); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EFLS; - return; - } - } - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EFLS; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetFileSystemScope(void) { - // may need to fix this - Cs2Area->reg.CR1 = Cs2Area->status << 8; - Cs2Area->reg.CR2 = (u16)(Cs2Area->numfiles - 2); - Cs2Area->reg.CR3 = 0x0100; - Cs2Area->reg.CR4 = 0x0002; - - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EFLS; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2GetFileInfo(void) { - u32 gfifid; - - gfifid = ((Cs2Area->reg.CR3 & 0xFF) << 16) | Cs2Area->reg.CR4; - - if (gfifid == 0xFFFFFF) - { - Cs2Area->transfercount = 0; - Cs2Area->infotranstype = 2; - - Cs2Area->reg.CR1 = Cs2Area->status << 8; - Cs2Area->reg.CR2 = 0x05F4; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - } - else - { - Cs2SetupFileInfoTransfer(gfifid); - - Cs2Area->transfercount = 0; - Cs2Area->infotranstype = 1; - - Cs2Area->reg.CR1 = Cs2Area->status << 8; - Cs2Area->reg.CR2 = 0x06; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - } - - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_DRDY; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2ReadFile(void) { - u32 rfoffset, rffilternum, rffid, rfsize; - - rfoffset = ((Cs2Area->reg.CR1 & 0xFF) << 8) | Cs2Area->reg.CR2; - rffilternum = Cs2Area->reg.CR3 >> 8; - rffid = ((Cs2Area->reg.CR3 & 0xFF) << 8) | Cs2Area->reg.CR4; - rfsize = ((Cs2Area->fileinfo[rffid].size + Cs2Area->getsectsize - 1) / - Cs2Area->getsectsize) - rfoffset; - - Cs2SetupDefaultPlayStats(Cs2FADToTrack(Cs2Area->fileinfo[rffid].lba + rfoffset), 0); - Cs2Area->maxrepeat = 0; - - Cs2Area->playFAD = Cs2Area->FAD = Cs2Area->fileinfo[rffid].lba + rfoffset; - Cs2Area->playendFAD = Cs2Area->playFAD + rfsize; - - Cs2Area->options = 0x8; - - Cs2SetTiming(1); - - Cs2Area->outconcddev = Cs2Area->filter + rffilternum; - - Cs2Area->status = CDB_STAT_PLAY; - Cs2Area->playtype = CDB_PLAYTYPE_FILE; - Cs2Area->cdi->ReadAheadFAD(Cs2Area->FAD); - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2AbortFile(void) { - if ((Cs2Area->status & 0xF) != CDB_STAT_OPEN && - (Cs2Area->status & 0xF) != CDB_STAT_NODISC) - Cs2Area->status = CDB_STAT_PAUSE; - Cs2Area->isonesectorstored = 0; - Cs2Area->datatranstype = -1; - Cs2Area->cdwnum = 0; - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_EFLS; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegGetStatus(void) { - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegGetInterrupt(void) { - u32 mgiworkinterrupt; - - // mpeg interrupt should be retrieved here - mgiworkinterrupt = 0; - - // mask interupt - mgiworkinterrupt &= Cs2Area->mpegintmask; - - Cs2Area->reg.CR1 = (u16)((Cs2Area->status << 8) | ((mgiworkinterrupt >> 16) & 0xFF)); - Cs2Area->reg.CR2 = (u16) mgiworkinterrupt; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetInterruptMask(void) { - Cs2Area->mpegintmask = ((Cs2Area->reg.CR1 & 0xFF) << 16) | Cs2Area->reg.CR2; - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegInit(void) { - - if (Cs2Area->mpgauth) - Cs2Area->reg.CR1 = Cs2Area->status << 8; - else - Cs2Area->reg.CR1 = 0xFF00; - - // double-check this - if (Cs2Area->reg.CR2 == 0x0001) // software timer/reset? - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM | CDB_HIRQ_MPED | CDB_HIRQ_MPST; - else - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPED | CDB_HIRQ_MPST; - - Cs2Area->reg.CR2 = 0; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - - // future mpeg-related variables should be initialized here -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetMode(void) { - // fix me - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegPlay(void) { - // fix me - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetDecodingMethod(void) { - // fix me - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetConnection(void) { - int mscnext = (Cs2Area->reg.CR3 >> 8); - - if (mscnext == 0) - { - // Current - Cs2Area->mpegcon[0].audcon = Cs2Area->reg.CR1 & 0xFF; - Cs2Area->mpegcon[0].audlay = Cs2Area->reg.CR2 >> 8; - Cs2Area->mpegcon[0].audbufdivnum = Cs2Area->reg.CR2 & 0xFF; - Cs2Area->mpegcon[0].vidcon = Cs2Area->reg.CR3 & 0xFF; - Cs2Area->mpegcon[0].vidlay = Cs2Area->reg.CR4 >> 8; - Cs2Area->mpegcon[0].vidbufdivnum = Cs2Area->reg.CR4 & 0xFF; - } - else - { - // Next - Cs2Area->mpegcon[1].audcon = Cs2Area->reg.CR1 & 0xFF; - Cs2Area->mpegcon[1].audlay = Cs2Area->reg.CR2 >> 8; - Cs2Area->mpegcon[1].audbufdivnum = Cs2Area->reg.CR2 & 0xFF; - Cs2Area->mpegcon[1].vidcon = Cs2Area->reg.CR3 & 0xFF; - Cs2Area->mpegcon[1].vidlay = Cs2Area->reg.CR4 >> 8; - Cs2Area->mpegcon[1].vidbufdivnum = Cs2Area->reg.CR4 & 0xFF; - } - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegGetConnection(void) { - int mgcnext = (Cs2Area->reg.CR3 >> 8); - - if (mgcnext == 0) - { - // Current - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | Cs2Area->mpegcon[0].audcon; - Cs2Area->reg.CR2 = (Cs2Area->mpegcon[0].audlay << 8) | Cs2Area->mpegcon[0].audbufdivnum; - Cs2Area->reg.CR3 = Cs2Area->mpegcon[0].vidcon; - Cs2Area->reg.CR4 = (Cs2Area->mpegcon[0].vidlay << 8) | Cs2Area->mpegcon[0].vidbufdivnum; - } - else - { - // Next - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | Cs2Area->mpegcon[1].audcon; - Cs2Area->reg.CR2 = (Cs2Area->mpegcon[1].audlay << 8) | Cs2Area->mpegcon[1].audbufdivnum; - Cs2Area->reg.CR3 = Cs2Area->mpegcon[1].vidcon; - Cs2Area->reg.CR4 = (Cs2Area->mpegcon[1].vidlay << 8) | Cs2Area->mpegcon[1].vidbufdivnum; - } - - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetStream(void) { - int mssnext = (Cs2Area->reg.CR3 >> 8); - - if (mssnext == 0) - { - // Current - Cs2Area->mpegstm[0].audstm = Cs2Area->reg.CR1 & 0xFF; - Cs2Area->mpegstm[0].audstmid = Cs2Area->reg.CR2 >> 8; - Cs2Area->mpegstm[0].audchannum = Cs2Area->reg.CR2 & 0xFF; - Cs2Area->mpegstm[0].vidstm = Cs2Area->reg.CR3 & 0xFF; - Cs2Area->mpegstm[0].vidstmid = Cs2Area->reg.CR4 >> 8; - Cs2Area->mpegstm[0].vidchannum = Cs2Area->reg.CR4 & 0xFF; - } - else - { - // Next - Cs2Area->mpegstm[1].audstm = Cs2Area->reg.CR1 & 0xFF; - Cs2Area->mpegstm[1].audstmid = Cs2Area->reg.CR2 >> 8; - Cs2Area->mpegstm[1].audchannum = Cs2Area->reg.CR2 & 0xFF; - Cs2Area->mpegstm[1].vidstm = Cs2Area->reg.CR3 & 0xFF; - Cs2Area->mpegstm[1].vidstmid = Cs2Area->reg.CR4 >> 8; - Cs2Area->mpegstm[1].vidchannum = Cs2Area->reg.CR4 & 0xFF; - } - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegGetStream(void) { - int mgsnext = (Cs2Area->reg.CR3 >> 8); - - if (mgsnext == 0) - { - // Current - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | Cs2Area->mpegstm[0].audstm; - Cs2Area->reg.CR2 = (Cs2Area->mpegstm[0].audstmid << 8) | Cs2Area->mpegstm[0].audchannum; - Cs2Area->reg.CR3 = Cs2Area->mpegstm[0].vidstm; - Cs2Area->reg.CR4 = (Cs2Area->mpegstm[0].vidstmid << 8) | Cs2Area->mpegstm[0].vidchannum; - } - else - { - // Next - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | Cs2Area->mpegstm[1].audstm; - Cs2Area->reg.CR2 = (Cs2Area->mpegstm[1].audstmid << 8) | Cs2Area->mpegstm[1].audchannum; - Cs2Area->reg.CR3 = Cs2Area->mpegstm[1].vidstm; - Cs2Area->reg.CR4 = (Cs2Area->mpegstm[1].vidstmid << 8) | Cs2Area->mpegstm[1].vidchannum; - } - - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegDisplay(void) { - // fix me(should be setting display setting) - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetWindow(void) { - // fix me(should be setting windows settings) - - // return default mpeg stats - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetBorderColor(void) { - // fix me(should be setting border color) - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetFade(void) { - // fix me(should be setting fade setting) - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetVideoEffects(void) { - // fix me(should be setting video effects settings) - - doMPEGReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2MpegSetLSI(void) { - // fix me(should be setting the LSI, among other things) - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPCM; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2CmdE0(void) { - int mpegauth; - - mpegauth = Cs2Area->reg.CR2 & 0xFF; - - - if ((Cs2Area->status & 0xF) != CDB_STAT_NODISC && - (Cs2Area->status & 0xF) != CDB_STAT_OPEN) - { - // Set registers all to invalid values(aside from status) - Cs2Area->status = CDB_STAT_BUSY; - - Cs2Area->reg.CR1 = (Cs2Area->status << 8) | 0xFF; - Cs2Area->reg.CR2 = 0xFFFF; - Cs2Area->reg.CR3 = 0xFFFF; - Cs2Area->reg.CR4 = 0xFFFF; - - if (mpegauth == 1) - { - Cs2Area->reg.HIRQ |= CDB_HIRQ_MPED; - Cs2Area->mpgauth = 2; - } - else - { - // if authentication passes(obviously it always does), CDB_HIRQ_CSCT is set - Cs2Area->isonesectorstored = 1; - Cs2Area->reg.HIRQ |= CDB_HIRQ_EFLS | CDB_HIRQ_CSCT; - Cs2Area->satauth = 4; - } - - // Set registers all back to normal values - - Cs2Area->status = CDB_STAT_PAUSE; - } - else - { - if (mpegauth == 1) - { - Cs2Area->reg.HIRQ |= CDB_HIRQ_MPED; - Cs2Area->mpgauth = 2; - } - else - Cs2Area->reg.HIRQ |= CDB_HIRQ_EFLS | CDB_HIRQ_CSCT; - } - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2CmdE1(void) { - Cs2Area->reg.CR1 = (Cs2Area->status << 8); - if (Cs2Area->reg.CR2) - Cs2Area->reg.CR2 = Cs2Area->mpgauth; - else - Cs2Area->reg.CR2 = Cs2Area->satauth; - Cs2Area->reg.CR3 = 0; - Cs2Area->reg.CR4 = 0; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2CmdE2(void) { - u16 i; - FILE * mpgfp; - partition_struct * mpgpartition; - - // fix me - Cs2Area->mpgauth |= 0x300; - - Cs2Area->outconmpegrom = Cs2Area->filter + 0; - Cs2Area->outconmpegromnum = 0; - - if (Cs2Area->mpegpath && (mpgfp = fopen(Cs2Area->mpegpath, "rb")) != NULL) - { - u32 readoffset = ((Cs2Area->reg.CR1 & 0xFF) << 8) | Cs2Area->reg.CR2; - u16 readsize = Cs2Area->reg.CR4; - - fseek(mpgfp, readoffset * Cs2Area->getsectsize, SEEK_SET); - if ((mpgpartition = Cs2GetPartition(Cs2Area->outconmpegrom)) != NULL && !Cs2Area->isbufferfull) - { - IOCheck_struct check; - mpgpartition->size = 0; - - for (i = 0; i < readsize; i++) - { - mpgpartition->block[mpgpartition->numblocks] = Cs2AllocateBlock(&mpgpartition->blocknum[mpgpartition->numblocks]); - - if (mpgpartition->block[mpgpartition->numblocks] != NULL) { - // read data - yread(&check, (void *)mpgpartition->block[mpgpartition->numblocks]->data, 1, Cs2Area->getsectsize, mpgfp); - - mpgpartition->numblocks++; - mpgpartition->size += Cs2Area->getsectsize; - } - } - - Cs2Area->isonesectorstored = 1; - Cs2Area->reg.HIRQ |= CDB_HIRQ_CSCT; - } - - fclose(mpgfp); - } - - doCDReport(Cs2Area->status); - Cs2Area->reg.HIRQ |= CDB_HIRQ_CMOK | CDB_HIRQ_MPED; -} - -////////////////////////////////////////////////////////////////////////////// - -u8 Cs2FADToTrack(u32 val) { - int i; - for (i = 0; i < 99; i++) - { - if (Cs2Area->TOC[i] == 0xFFFFFFFF) return 0xFF; - - if (val >= (Cs2Area->TOC[i] & 0xFFFFFF) && val < (Cs2Area->TOC[i + 1] & 0xFFFFFF)) - return (i + 1); - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -u32 Cs2TrackToFAD(u16 trackandindex) { - if (trackandindex == 0xFFFF) - // leadout position - return (Cs2Area->TOC[101] & 0x00FFFFFF); - if (trackandindex != 0x0000) - { - // regular track - // (really, we should be fetching subcode q's here) - if ((trackandindex & 0xFF) == 0x01) - // Return Start of Track - return (Cs2Area->TOC[(trackandindex >> 8) - 1] & 0x00FFFFFF); - else if ((trackandindex & 0xFF) == 0x63) - // Return End of Track - return ((Cs2Area->TOC[(trackandindex >> 8)] & 0x00FFFFFF) - 1); - } - - // assume it's leadin - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetupDefaultPlayStats(u8 track_number, int writeFAD) { - if (track_number != 0xFF) - { - Cs2Area->options = 0; - Cs2Area->repcnt = 0; - Cs2Area->ctrladdr = (u8)(Cs2Area->TOC[track_number - 1] >> 24); - Cs2Area->index = 1; - Cs2Area->track = track_number; - if (writeFAD) - Cs2Area->FAD = Cs2Area->TOC[track_number - 1] & 0x00FFFFFF; - } -} - -////////////////////////////////////////////////////////////////////////////// - -block_struct * Cs2AllocateBlock(u8 * blocknum) { - u32 i; - // find a free block - for(i = 0; i < 200; i++) - { - if (Cs2Area->block[i].size == -1) - { - Cs2Area->blockfreespace--; - - if (Cs2Area->blockfreespace <= 0) Cs2Area->isbufferfull = 1; - - Cs2Area->block[i].size = Cs2Area->getsectsize; - - *blocknum = (u8)i; - return (Cs2Area->block + i); - } - } - - Cs2Area->isbufferfull = 1; - - return NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2FreeBlock(block_struct * blk) { - if (blk == NULL) return; - blk->size = -1; - Cs2Area->blockfreespace++; - Cs2Area->isbufferfull = 0; - Cs2Area->reg.HIRQ &= ~CDB_HIRQ_BFUL; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SortBlocks(partition_struct * part) { - unsigned int from, to; - - for (from = to = 0; from < MAX_BLOCKS; from++) - { - if (part->block[from] != NULL) - { - if (to != from) - { - part->block[to] = part->block[from]; - } - to++; - } - } - - for (; to < MAX_BLOCKS; to++) { - part->block[to] = NULL; - } -} - -////////////////////////////////////////////////////////////////////////////// - -partition_struct * Cs2GetPartition(filter_struct * curfilter) -{ - // go through various filter conditions here(fix me) - - return &Cs2Area->partition[curfilter->condtrue]; -} - -////////////////////////////////////////////////////////////////////////////// - -partition_struct * Cs2FilterData(filter_struct * curfilter, int isaudio) -{ - int condresults = 1; - partition_struct * fltpartition = NULL; - - // fix me, this is pretty bad. Though I guess it's a start - - for (;;) - { - // detect which type of sector we're dealing with - // If it's not mode 2, ignore the subheader conditions - if (Cs2Area->workblock.data[0xF] == 0x02 && !isaudio) - { - // Mode 2 - // go through various subheader filter conditions here(fix me) - - if (curfilter->mode & 0x01) - { - // File Number Check - if (Cs2Area->workblock.fn != curfilter->fid) - condresults = 0; - } - - if (curfilter->mode & 0x02) - { - // Channel Number Check - if (Cs2Area->workblock.cn != curfilter->chan) - condresults = 0; - } - - if (curfilter->mode & 0x04) - { - // Sub Mode Check - if ((Cs2Area->workblock.sm & curfilter->smmask) != curfilter->smval) - condresults = 0; - } - - if (curfilter->mode & 0x08) - { - // Coding Information Check - CDLOG("cs2\t: FilterData: Coding Information Check. Coding Information = %02X. Filter's Coding Information Mask = %02X, Coding Information Value = %02X\n", Cs2Area->workblock.ci, curfilter->cimask, curfilter->cival); - if ((Cs2Area->workblock.ci & curfilter->cimask) != curfilter->cival) - condresults = 0; - } - - if (curfilter->mode & 0x10) - { - // Reverse Subheader Conditions - CDLOG("cs2\t: FilterData: Reverse Subheader Conditions\n"); - condresults ^= 1; - } - } - - if (curfilter->mode & 0x40) - { - // FAD Range Check - if (Cs2Area->workblock.FAD < curfilter->FAD || - Cs2Area->workblock.FAD > (curfilter->FAD+curfilter->range)) - condresults = 0; - } - - if (condresults == 1) - { - Cs2Area->lastbuffer = curfilter->condtrue; - fltpartition = &Cs2Area->partition[curfilter->condtrue]; - break; - } - else - { - Cs2Area->lastbuffer = curfilter->condfalse; - - if (curfilter->condfalse == 0xFF) - return NULL; - // loop and try filter that was connected to the false connector - curfilter = &Cs2Area->filter[curfilter->condfalse]; - } - } - - // Allocate block - fltpartition->block[fltpartition->numblocks] = Cs2AllocateBlock(&fltpartition->blocknum[fltpartition->numblocks]); - - if (fltpartition->block[fltpartition->numblocks] == NULL) - return NULL; - - // Copy workblock settings to allocated block - fltpartition->block[fltpartition->numblocks]->size = Cs2Area->workblock.size; - fltpartition->block[fltpartition->numblocks]->FAD = Cs2Area->workblock.FAD; - fltpartition->block[fltpartition->numblocks]->cn = Cs2Area->workblock.cn; - fltpartition->block[fltpartition->numblocks]->fn = Cs2Area->workblock.fn; - fltpartition->block[fltpartition->numblocks]->sm = Cs2Area->workblock.sm; - fltpartition->block[fltpartition->numblocks]->ci = Cs2Area->workblock.ci; - - // convert raw sector to type specified in getsectsize - switch(Cs2Area->workblock.size) - { - case 2048: // user data only - if (Cs2Area->workblock.data[0xF] == 0x02) - // m2f1 - memcpy(fltpartition->block[fltpartition->numblocks]->data, - Cs2Area->workblock.data + 24, Cs2Area->workblock.size); - else - // m1 - memcpy(fltpartition->block[fltpartition->numblocks]->data, - Cs2Area->workblock.data + 16, Cs2Area->workblock.size); - break; - case 2324: // m2f2 user data only - memcpy(fltpartition->block[fltpartition->numblocks]->data, - Cs2Area->workblock.data + 24, Cs2Area->workblock.size); - break; - case 2336: // m2f2 skip sync+header data - memcpy(fltpartition->block[fltpartition->numblocks]->data, - Cs2Area->workblock.data + 16, Cs2Area->workblock.size); - break; - case 2340: // m2f2 skip sync data - memcpy(fltpartition->block[fltpartition->numblocks]->data, - Cs2Area->workblock.data + 12, Cs2Area->workblock.size); - break; - case 2352: // Copy data as is - memcpy(fltpartition->block[fltpartition->numblocks]->data, - Cs2Area->workblock.data, Cs2Area->workblock.size); - break; - default: break; - } - - // Modify Partition values - if (fltpartition->size == -1) fltpartition->size = 0; - fltpartition->size += fltpartition->block[fltpartition->numblocks]->size; - fltpartition->numblocks++; - - return fltpartition; -} - -////////////////////////////////////////////////////////////////////////////// - -int Cs2CopyDirRecord(u8 * buffer, dirrec_struct * dirrec) -{ - u8 * temp_pointer; - - temp_pointer = buffer; - - memcpy(&dirrec->recordsize, buffer, sizeof(dirrec->recordsize)); - buffer += sizeof(dirrec->recordsize); - - memcpy(&dirrec->xarecordsize, buffer, sizeof(dirrec->xarecordsize)); - buffer += sizeof(dirrec->xarecordsize); - -#ifdef WORDS_BIGENDIAN - buffer += sizeof(dirrec->lba); - memcpy(&dirrec->lba, buffer, sizeof(dirrec->lba)); - buffer += sizeof(dirrec->lba); -#else - memcpy(&dirrec->lba, buffer, sizeof(dirrec->lba)); - buffer += (sizeof(dirrec->lba) * 2); -#endif - -#ifdef WORDS_BIGENDIAN - buffer += sizeof(dirrec->size); - memcpy(&dirrec->size, buffer, sizeof(dirrec->size)); - buffer += sizeof(dirrec->size); -#else - memcpy(&dirrec->size, buffer, sizeof(dirrec->size)); - buffer += (sizeof(dirrec->size) * 2); -#endif - - dirrec->dateyear = buffer[0]; - dirrec->datemonth = buffer[1]; - dirrec->dateday = buffer[2]; - dirrec->datehour = buffer[3]; - dirrec->dateminute = buffer[4]; - dirrec->datesecond = buffer[5]; - dirrec->gmtoffset = buffer[6]; - buffer += 7; - - dirrec->flags = buffer[0]; - buffer += sizeof(dirrec->flags); - - dirrec->fileunitsize = buffer[0]; - buffer += sizeof(dirrec->fileunitsize); - - dirrec->interleavegapsize = buffer[0]; - buffer += sizeof(dirrec->interleavegapsize); - -#ifdef WORDS_BIGENDIAN - buffer += sizeof(dirrec->volumesequencenumber); - memcpy(&dirrec->volumesequencenumber, buffer, sizeof(dirrec->volumesequencenumber)); - buffer += sizeof(dirrec->volumesequencenumber); -#else - memcpy(&dirrec->volumesequencenumber, buffer, sizeof(dirrec->volumesequencenumber)); - buffer += (sizeof(dirrec->volumesequencenumber) * 2); -#endif - - dirrec->namelength = buffer[0]; - buffer += sizeof(dirrec->namelength); - - memset(dirrec->name, 0, sizeof(dirrec->name)); - memcpy(dirrec->name, buffer, dirrec->namelength); - buffer += dirrec->namelength; - - // handle padding - buffer += (1 - dirrec->namelength % 2); - - memset(&dirrec->xarecord, 0, sizeof(dirrec->xarecord)); - - // sadily, this is the best way I can think of for detecting XA records - - if ((dirrec->recordsize - (buffer - temp_pointer)) == 14) - { - memcpy(&dirrec->xarecord.groupid, buffer, sizeof(dirrec->xarecord.groupid)); - buffer += sizeof(dirrec->xarecord.groupid); - - memcpy(&dirrec->xarecord.userid, buffer, sizeof(dirrec->xarecord.userid)); - buffer += sizeof(dirrec->xarecord.userid); - - memcpy(&dirrec->xarecord.attributes, buffer, sizeof(dirrec->xarecord.attributes)); - buffer += sizeof(dirrec->xarecord.attributes); - -#ifndef WORDS_BIGENDIAN - // byte swap it - dirrec->xarecord.attributes = ((dirrec->xarecord.attributes & 0xFF00) >> 8) + - ((dirrec->xarecord.attributes & 0x00FF) << 8); -#endif - - memcpy(&dirrec->xarecord.signature, buffer, sizeof(dirrec->xarecord.signature)); - buffer += sizeof(dirrec->xarecord.signature); - - memcpy(&dirrec->xarecord.filenumber, buffer, sizeof(dirrec->xarecord.filenumber)); - buffer += sizeof(dirrec->xarecord.filenumber); - - memcpy(dirrec->xarecord.reserved, buffer, sizeof(dirrec->xarecord.reserved)); - buffer += sizeof(dirrec->xarecord.reserved); - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int Cs2ReadFileSystem(filter_struct * curfilter, u32 fid, int isoffset) -{ - u8 * workbuffer; - u32 i; - dirrec_struct dirrec; - u8 numsectorsleft = 0; - u32 curdirlba = 0; - partition_struct * rfspartition; - u32 blocksectsize = Cs2Area->getsectsize; - - Cs2Area->outconcddev = curfilter; - - if (isoffset) - { - // readDirectory operation - - // make sure we have a valid current directory - if (Cs2Area->curdirsect == 0) - return -1; - - Cs2Area->curdirfidoffset = fid - 2; - curdirlba = Cs2Area->curdirsect; - numsectorsleft = (u8)Cs2Area->curdirsize; - } - else - { - // changeDirectory operation - - if (fid == 0xFFFFFF) - { - // Figure out root directory's location - - // Read sector 16 - if ((rfspartition = Cs2ReadUnFilteredSector(166)) == NULL) - return -2; - - blocksectsize = rfspartition->block[rfspartition->numblocks - 1]->size; - - // Retrieve directory record's lba - Cs2CopyDirRecord(rfspartition->block[rfspartition->numblocks - 1]->data + 0x9C, &dirrec); - - // Free Block - rfspartition->size -= rfspartition->block[rfspartition->numblocks - 1]->size; - Cs2FreeBlock(rfspartition->block[rfspartition->numblocks - 1]); - rfspartition->blocknum[rfspartition->numblocks - 1] = 0xFF; - - // Sort remaining blocks - Cs2SortBlocks(rfspartition); - rfspartition->numblocks -= 1; - - curdirlba = Cs2Area->curdirsect = dirrec.lba; - Cs2Area->curdirsize = (dirrec.size / blocksectsize) - 1; - numsectorsleft = (u8)Cs2Area->curdirsize; - Cs2Area->curdirfidoffset = 0; - } - else - { - // Read in new directory record of specified directory - - // make sure we have a valid current directory - if (Cs2Area->curdirsect == 0) - return -1; - - curdirlba = Cs2Area->curdirsect = Cs2Area->fileinfo[fid - Cs2Area->curdirfidoffset].lba - 150; - Cs2Area->curdirsize = (Cs2Area->fileinfo[fid - Cs2Area->curdirfidoffset].size / blocksectsize) - 1; - numsectorsleft = (u8)Cs2Area->curdirsize; - Cs2Area->curdirfidoffset = 0; - } - } - - // Make sure any old records are cleared - memset(Cs2Area->fileinfo, 0, sizeof(dirrec_struct) * MAX_FILES); - - // now read in first sector of directory record - if ((rfspartition = Cs2ReadUnFilteredSector(curdirlba+150)) == NULL) - return -2; - - curdirlba++; - workbuffer = rfspartition->block[rfspartition->numblocks - 1]->data; - - // Fill in first two entries of fileinfo - for (i = 0; i < 2; i++) - { - Cs2CopyDirRecord(workbuffer, Cs2Area->fileinfo + i); - Cs2Area->fileinfo[i].lba += 150; - workbuffer += Cs2Area->fileinfo[i].recordsize; - - if (workbuffer[0] == 0) - { - Cs2Area->numfiles = i; - break; - } - } - - // If doing a ReadDirectory operation, parse sector entries until we've - // found the fid that matches fid - if (isoffset) - { - for (i = 2; i < fid; i++) - { - Cs2CopyDirRecord(workbuffer, Cs2Area->fileinfo + 2); - workbuffer += Cs2Area->fileinfo[2].recordsize; - - if (workbuffer[0] == 0) - { - if (numsectorsleft > 0) - { - // Free previous read sector - rfspartition->size -= rfspartition->block[rfspartition->numblocks - 1]->size; - Cs2FreeBlock(rfspartition->block[rfspartition->numblocks - 1]); - rfspartition->blocknum[rfspartition->numblocks - 1] = 0xFF; - - // Sort remaining blocks - Cs2SortBlocks(rfspartition); - rfspartition->numblocks -= 1; - - // Read in next sector of directory record - if ((rfspartition = Cs2ReadUnFilteredSector(curdirlba+150)) == NULL) - return -2; - - curdirlba++; - - numsectorsleft--; - workbuffer = rfspartition->block[rfspartition->numblocks - 1]->data; - } - else - { - break; - } - } - } - } - - // Now generate the last 254 entries(the first two should've already been - // generated earlier) - for (i = 2; i < MAX_FILES; i++) - { - Cs2CopyDirRecord(workbuffer, Cs2Area->fileinfo + i); - Cs2Area->fileinfo[i].lba += 150; - workbuffer += Cs2Area->fileinfo[i].recordsize; - - if (workbuffer[0] == 0) - { - if (numsectorsleft > 0) - { - // Free previous read sector - rfspartition->size -= rfspartition->block[rfspartition->numblocks - 1]->size; - Cs2FreeBlock(rfspartition->block[rfspartition->numblocks - 1]); - rfspartition->blocknum[rfspartition->numblocks - 1] = 0xFF; - - // Sort remaining blocks - Cs2SortBlocks(rfspartition); - rfspartition->numblocks -= 1; - - // Read in next sector of directory record - if ((rfspartition = Cs2ReadUnFilteredSector(curdirlba+150)) == NULL) - return -2; - - curdirlba++; - numsectorsleft--; - workbuffer = rfspartition->block[rfspartition->numblocks - 1]->data; - } - else - { - Cs2Area->numfiles = i; - break; - } - } - } - - // Free the remaining sector - rfspartition->size -= rfspartition->block[rfspartition->numblocks - 1]->size; - Cs2FreeBlock(rfspartition->block[rfspartition->numblocks - 1]); - rfspartition->blocknum[rfspartition->numblocks - 1] = 0xFF; - - // Sort remaining blocks - Cs2SortBlocks(rfspartition); - rfspartition->numblocks -= 1; - -//#if CDDEBUG -// for (i = 0; i < MAX_FILES; i++) -// { -// CDLOG("fileinfo[%d].name = %s\n", i, Cs2Area->fileinfo[i].name); -// } -//#endif - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void Cs2SetupFileInfoTransfer(u32 fid) { - Cs2Area->transfileinfo[0] = (u8)(Cs2Area->fileinfo[fid].lba >> 24); - Cs2Area->transfileinfo[1] = (u8)(Cs2Area->fileinfo[fid].lba >> 16); - Cs2Area->transfileinfo[2] = (u8)(Cs2Area->fileinfo[fid].lba >> 8); - Cs2Area->transfileinfo[3] = (u8)Cs2Area->fileinfo[fid].lba; - - Cs2Area->transfileinfo[4] = (u8)(Cs2Area->fileinfo[fid].size >> 24); - Cs2Area->transfileinfo[5] = (u8)(Cs2Area->fileinfo[fid].size >> 16); - Cs2Area->transfileinfo[6] = (u8)(Cs2Area->fileinfo[fid].size >> 8); - Cs2Area->transfileinfo[7] = (u8)Cs2Area->fileinfo[fid].size; - - Cs2Area->transfileinfo[8] = Cs2Area->fileinfo[fid].interleavegapsize; - Cs2Area->transfileinfo[9] = Cs2Area->fileinfo[fid].fileunitsize; - Cs2Area->transfileinfo[10] = (u8) fid; - Cs2Area->transfileinfo[11] = Cs2Area->fileinfo[fid].flags; -} - -////////////////////////////////////////////////////////////////////////////// - -partition_struct * Cs2ReadUnFilteredSector(u32 rufsFAD) { - partition_struct * rufspartition; - char syncheader[12] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0x00}; - - if ((rufspartition = Cs2GetPartition(Cs2Area->outconcddev)) != NULL && !Cs2Area->isbufferfull) - { - // Allocate Block - rufspartition->block[rufspartition->numblocks] = Cs2AllocateBlock(&rufspartition->blocknum[rufspartition->numblocks]); - - if (rufspartition->block[rufspartition->numblocks] == NULL) - return NULL; - - // read a sector using cd interface function - if (!Cs2Area->cdi->ReadSectorFAD(rufsFAD, Cs2Area->workblock.data)) - return NULL; - - // convert raw sector to type specified in getsectsize - switch(Cs2Area->getsectsize) - { - case 2048: // user data only - if (Cs2Area->workblock.data[0xF] == 0x02) - { - // is it form1/form2 data? - if (!(Cs2Area->workblock.data[0x12] & 0x20)) - { - // form 1 - memcpy(rufspartition->block[rufspartition->numblocks]->data, - Cs2Area->workblock.data + 24, 2048); - Cs2Area->workblock.size = Cs2Area->getsectsize; - } - else - { - // form 2 - memcpy(rufspartition->block[rufspartition->numblocks]->data, - Cs2Area->workblock.data + 24, 2324); - Cs2Area->workblock.size = 2324; - } - } - else - { - memcpy(rufspartition->block[rufspartition->numblocks]->data, - Cs2Area->workblock.data + 16, 2048); - Cs2Area->workblock.size = Cs2Area->getsectsize; - } - break; - case 2336: // skip sync+header data - memcpy(rufspartition->block[rufspartition->numblocks]->data, - Cs2Area->workblock.data + 16, 2336); - Cs2Area->workblock.size = Cs2Area->getsectsize; - break; - case 2340: // skip sync data - memcpy(rufspartition->block[rufspartition->numblocks]->data, - Cs2Area->workblock.data + 12, 2340); - Cs2Area->workblock.size = Cs2Area->getsectsize; - break; - case 2352: // no conversion needed - Cs2Area->workblock.size = Cs2Area->getsectsize; - break; - default: break; - } - - // if mode 2 track, setup the subheader values - if (memcmp(syncheader, Cs2Area->workblock.data, 12) == 0 && - Cs2Area->workblock.data[0xF] == 0x02) - { - rufspartition->block[rufspartition->numblocks]->fn = Cs2Area->workblock.data[0x10]; - rufspartition->block[rufspartition->numblocks]->cn = Cs2Area->workblock.data[0x11]; - rufspartition->block[rufspartition->numblocks]->sm = Cs2Area->workblock.data[0x12]; - rufspartition->block[rufspartition->numblocks]->ci = Cs2Area->workblock.data[0x13]; - } - - Cs2Area->workblock.FAD = rufsFAD; - - // Modify Partition values - if (rufspartition->size == -1) rufspartition->size = 0; - rufspartition->size += rufspartition->block[rufspartition->numblocks]->size; - rufspartition->numblocks++; - - return rufspartition; - } - - return NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -int Cs2ReadFilteredSector(u32 rfsFAD, partition_struct **partition) { - char syncheader[12] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0x00}; - int isaudio = 0; - - if (Cs2Area->outconcddev != NULL && !Cs2Area->isbufferfull) - { - // read a sector using cd interface function to workblock.data - if (!Cs2Area->cdi->ReadSectorFAD(rfsFAD, Cs2Area->workblock.data)) - { - *partition = NULL; - return -2; - } - - Cs2Area->workblock.size = Cs2Area->getsectsize; - Cs2Area->workblock.FAD = rfsFAD; - - if (memcmp(syncheader, Cs2Area->workblock.data, 12) != 0) isaudio = 1; - - // force 1x speed if reading from an audio track - Cs2Area->isaudio = isaudio; - Cs2SetTiming(1); - - // if mode 2 track, setup the subheader values - if (isaudio) - { - ScspReceiveCDDA(Cs2Area->workblock.data); - *partition = NULL; - return 0; - } - else if (Cs2Area->workblock.data[0xF] == 0x02) - { - // if it's form 2 data the sector size should be 2324 - if (Cs2Area->workblock.data[0x12] & 0x20) Cs2Area->workblock.size = 2324; - - Cs2Area->workblock.fn = Cs2Area->workblock.data[0x10]; - Cs2Area->workblock.cn = Cs2Area->workblock.data[0x11]; - Cs2Area->workblock.sm = Cs2Area->workblock.data[0x12]; - Cs2Area->workblock.ci = Cs2Area->workblock.data[0x13]; - } - - - // pass workblock to filter function(after it identifies partition, - // it should allocate the partition block, setup/change the partition - // values, and copy workblock to the allocated block) - *partition = Cs2FilterData(Cs2Area->outconcddev, isaudio); - return 0; - } - - *partition = NULL; - return -1; -} - -////////////////////////////////////////////////////////////////////////////// - -u8 Cs2GetIP(int autoregion) { - partition_struct * gripartition; - u8 ret = 0; - - Cs2Area->outconcddev = Cs2Area->filter + 0; - Cs2Area->outconcddevnum = 0; - - // read in lba 0/FAD 150 - if ((gripartition = Cs2ReadUnFilteredSector(150)) != NULL) - { - char *buf=(char*)gripartition->block[gripartition->numblocks - 1]->data; - - // Make sure we're dealing with a saturn game - if (memcmp(buf, "SEGA SEGASATURN", 15) == 0) - { - memcpy(cdip->system, buf, 16); - cdip->system[16]='\0'; - memcpy(cdip->company, buf+0x10, 16); - cdip->company[16]='\0'; - sscanf(buf+0x20, "%s", cdip->itemnum); - memcpy(cdip->version, buf+0x2A, 6); - cdip->version[6]='\0'; - sprintf(cdip->date, "%c%c/%c%c/%c%c%c%c", buf[0x34], buf[0x35], buf[0x36], buf[0x37], buf[0x30], buf[0x31], buf[0x32], buf[0x33]); - sscanf(buf+0x38, "%s", cdip->cdinfo); - sscanf(buf+0x40, "%s", cdip->region); - sscanf(buf+0x50, "%s", cdip->peripheral); - memcpy(cdip->gamename, buf+0x60, 112); - cdip->gamename[112]='\0'; -#ifdef WORDS_BIGENDIAN - memcpy(&cdip->ipsize, buf+0xE0, sizeof(u32)); - memcpy(&cdip->msh2stack, buf+0xE8, sizeof(u32)); - memcpy(&cdip->ssh2stack, buf+0xEC, sizeof(u32)); - memcpy(&cdip->firstprogaddr, buf+0xF0, sizeof(u32)); - memcpy(&cdip->firstprogsize, buf+0xF4, sizeof(u32)); -#else - cdip->ipsize = (buf[0xE0] << 24) | (buf[0xE1] << 16) | - (buf[0xE2] << 8) | buf[0xE3]; - cdip->msh2stack = (buf[0xE8] << 24) | (buf[0xE9] << 16) | - (buf[0xEA] << 8) | buf[0xEB]; - cdip->ssh2stack = (buf[0xEC] << 24) | (buf[0xED] << 16) | - (buf[0xEE] << 8) | buf[0xEF]; - cdip->firstprogaddr = (buf[0xF0] << 24) | (buf[0xF1] << 16) | - (buf[0xF2] << 8) | buf[0xF3]; - cdip->firstprogsize = (buf[0xF4] << 24) | (buf[0xF5] << 16) | - (buf[0xF6] << 8) | buf[0xF7]; -#endif - - if (autoregion) - { - // Read first available region, that'll be what we'll use - switch (cdip->region[0]) - { - case 'J': - ret = 1; - break; - case 'T': - ret = 2; - break; - case 'U': - ret = 4; - break; - case 'B': - ret = 5; - break; - case 'K': - ret = 6; - break; - case 'A': - ret = 0xA; - break; - case 'E': - ret = 0xC; - break; - case 'L': - ret = 0xD; - break; - default: break; - } - } - } - - // Free Block - gripartition->size -= gripartition->block[gripartition->numblocks - 1]->size; - Cs2FreeBlock(gripartition->block[gripartition->numblocks - 1]); - gripartition->blocknum[gripartition->numblocks - 1] = 0xFF; - - // Sort remaining blocks - Cs2SortBlocks(gripartition); - gripartition->numblocks -= 1; - } - - return ret; -} - -////////////////////////////////////////////////////////////////////////////// - -u8 Cs2GetRegionID(void) -{ - return Cs2GetIP(1); -} - -////////////////////////////////////////////////////////////////////////////// - -int Cs2SaveState(FILE * fp) { - int offset, i; - IOCheck_struct check; - - // This is mostly kludge, but it will have to do until I have time to rewrite it all - - offset = StateWriteHeader(fp, "CS2 ", 2); - - // Write cart type - ywrite(&check, (void *) &Cs2Area->carttype, 4, 1, fp); - - // Write cd block registers - ywrite(&check, (void *) &Cs2Area->reg, sizeof(blockregs_struct), 1, fp); - - // Write current Status variables(needs a rewrite) - ywrite(&check, (void *) &Cs2Area->FAD, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->status, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->options, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->repcnt, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->ctrladdr, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->track, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->index, 1, 1, fp); - - // Write other cd block internal variables - ywrite(&check, (void *) &Cs2Area->satauth, 2, 1, fp); - ywrite(&check, (void *) &Cs2Area->mpgauth, 2, 1, fp); - ywrite(&check, (void *) &Cs2Area->transfercount, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->cdwnum, 4, 1, fp); - ywrite(&check, (void *) Cs2Area->TOC, 4, 102, fp); - ywrite(&check, (void *) &Cs2Area->playFAD, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->playendFAD, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->getsectsize, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->putsectsize, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->calcsize, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->infotranstype, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->datatranstype, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->isonesectorstored, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->isdiskchanged, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->isbufferfull, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->speed1x, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->isaudio, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->transfileinfo, 1, 12, fp); - ywrite(&check, (void *) &Cs2Area->lastbuffer, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->_command, 1, 1, fp); - { - u32 temp = (Cs2Area->_periodictiming + 3) / 3; - ywrite(&check, (void *) &temp, 4, 1, fp); - } - ywrite(&check, (void *) &Cs2Area->_commandtiming, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->outconcddevnum, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->outconmpegfbnum, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->outconmpegbufnum, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->outconmpegromnum, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->outconhostnum, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->datatranspartitionnum, 1, 1, fp); - ywrite(&check, (void *) &Cs2Area->datatransoffset, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->datanumsecttrans, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->datatranssectpos, 2, 1, fp); - ywrite(&check, (void *) &Cs2Area->datasectstotrans, 2, 1, fp); - ywrite(&check, (void *) &Cs2Area->blockfreespace, 4, 1, fp); - ywrite(&check, (void *) &Cs2Area->curdirsect, 4, 1, fp); - - // Write CD buffer - ywrite(&check, (void *)Cs2Area->block, sizeof(block_struct), MAX_BLOCKS, fp); - - // Write partition data - for (i = 0; i < MAX_SELECTORS; i++) - { - ywrite(&check, (void *)&Cs2Area->partition[i].size, 4, 1, fp); - ywrite(&check, (void *)Cs2Area->partition[i].blocknum, 1, MAX_BLOCKS, fp); - ywrite(&check, (void *)&Cs2Area->partition[i].numblocks, 1, 1, fp); - } - - // Write filter data - ywrite(&check, (void *)Cs2Area->filter, sizeof(filter_struct), MAX_SELECTORS, fp); - - // Write File Info Table - ywrite(&check, (void *)Cs2Area->fileinfo, sizeof(dirrec_struct), MAX_FILES, fp); - - // Write MPEG card registers here - - // Write current MPEG card status variables - ywrite(&check, (void *)&Cs2Area->actionstatus, 1, 1, fp); - ywrite(&check, (void *)&Cs2Area->pictureinfo, 1, 1, fp); - ywrite(&check, (void *)&Cs2Area->mpegaudiostatus, 1, 1, fp); - ywrite(&check, (void *)&Cs2Area->mpegvideostatus, 2, 1, fp); - ywrite(&check, (void *)&Cs2Area->vcounter, 2, 1, fp); - - // Write other MPEG card internal variables - ywrite(&check, (void *)&Cs2Area->mpegintmask, 4, 1, fp); - ywrite(&check, (void *)Cs2Area->mpegcon, sizeof(mpegcon_struct), 2, fp); - ywrite(&check, (void *)Cs2Area->mpegstm, sizeof(mpegstm_struct), 2, fp); - - return StateFinishHeader(fp, offset); -} - -////////////////////////////////////////////////////////////////////////////// - -int Cs2LoadState(FILE * fp, int version, int size) { - int i, i2; - IOCheck_struct check; - - // This is mostly kludge, but it will have to do until I have time to rewrite it all - - // Read cart type - yread(&check, (void *)&Cs2Area->carttype, 4, 1, fp); - - // Read cd block registers - yread(&check, (void *)&Cs2Area->reg, sizeof(blockregs_struct), 1, fp); - - // Read current Status variables(needs a reRead) - yread(&check, (void *)&Cs2Area->FAD, 4, 1, fp); - yread(&check, (void *)&Cs2Area->status, 1, 1, fp); - yread(&check, (void *)&Cs2Area->options, 1, 1, fp); - yread(&check, (void *)&Cs2Area->repcnt, 1, 1, fp); - yread(&check, (void *)&Cs2Area->ctrladdr, 1, 1, fp); - yread(&check, (void *)&Cs2Area->track, 1, 1, fp); - yread(&check, (void *)&Cs2Area->index, 1, 1, fp); - - // Read other cd block internal variables - yread(&check, (void *)&Cs2Area->satauth, 2, 1, fp); - yread(&check, (void *)&Cs2Area->mpgauth, 2, 1, fp); - yread(&check, (void *)&Cs2Area->transfercount, 4, 1, fp); - yread(&check, (void *)&Cs2Area->cdwnum, 4, 1, fp); - yread(&check, (void *)Cs2Area->TOC, 4, 102, fp); - yread(&check, (void *)&Cs2Area->playFAD, 4, 1, fp); - yread(&check, (void *)&Cs2Area->playendFAD, 4, 1, fp); - yread(&check, (void *)&Cs2Area->getsectsize, 4, 1, fp); - yread(&check, (void *)&Cs2Area->putsectsize, 4, 1, fp); - yread(&check, (void *)&Cs2Area->calcsize, 4, 1, fp); - yread(&check, (void *)&Cs2Area->infotranstype, 4, 1, fp); - yread(&check, (void *)&Cs2Area->datatranstype, 4, 1, fp); - yread(&check, (void *)&Cs2Area->isonesectorstored, 1, 1, fp); - yread(&check, (void *)&Cs2Area->isdiskchanged, 1, 1, fp); - yread(&check, (void *)&Cs2Area->isbufferfull, 1, 1, fp); - yread(&check, (void *)&Cs2Area->speed1x, 1, 1, fp); - if (version > 1) - yread(&check, (void *)&Cs2Area->isaudio, 1, 1, fp); - yread(&check, (void *)&Cs2Area->transfileinfo, 1, 12, fp); - yread(&check, (void *)&Cs2Area->lastbuffer, 1, 1, fp); - yread(&check, (void *)&Cs2Area->_command, 1, 1, fp); - { - u32 temp; - yread(&check, (void *)&temp, 4, 1, fp); - // Derive the actual, accurate value (always a multiple of 10) - Cs2Area->_periodictiming = ((temp * 3) / 10) * 10; - } - yread(&check, (void *)&Cs2Area->_commandtiming, 4, 1, fp); - yread(&check, (void *)&Cs2Area->outconcddevnum, 1, 1, fp); - if (Cs2Area->outconcddevnum == 0xFF) - Cs2Area->outconcddev = NULL; - else - Cs2Area->outconcddev = Cs2Area->filter + Cs2Area->outconcddevnum; - - yread(&check, (void *)&Cs2Area->outconmpegfbnum, 1, 1, fp); - if (Cs2Area->outconmpegfbnum == 0xFF) - Cs2Area->outconmpegfb = NULL; - else - Cs2Area->outconmpegfb = Cs2Area->filter + Cs2Area->outconmpegfbnum; - - yread(&check, (void *)&Cs2Area->outconmpegbufnum, 1, 1, fp); - if (Cs2Area->outconmpegbufnum == 0xFF) - Cs2Area->outconmpegbuf = NULL; - else - Cs2Area->outconmpegbuf = Cs2Area->filter + Cs2Area->outconmpegbufnum; - - yread(&check, (void *)&Cs2Area->outconmpegromnum, 1, 1, fp); - if (Cs2Area->outconmpegromnum == 0xFF) - Cs2Area->outconmpegrom = NULL; - else - Cs2Area->outconmpegrom = Cs2Area->filter + Cs2Area->outconmpegromnum; - - yread(&check, (void *)&Cs2Area->outconhostnum, 1, 1, fp); - if (Cs2Area->outconhostnum == 0xFF) - Cs2Area->outconhost = NULL; - else - Cs2Area->outconhost = Cs2Area->filter + Cs2Area->outconhostnum; - - yread(&check, (void *)&Cs2Area->datatranspartitionnum, 1, 1, fp); - yread(&check, (void *)&Cs2Area->datatransoffset, 4, 1, fp); - yread(&check, (void *)&Cs2Area->datanumsecttrans, 4, 1, fp); - yread(&check, (void *)&Cs2Area->datatranssectpos, 2, 1, fp); - yread(&check, (void *)&Cs2Area->datasectstotrans, 2, 1, fp); - yread(&check, (void *)&Cs2Area->blockfreespace, 4, 1, fp); - yread(&check, (void *)&Cs2Area->curdirsect, 4, 1, fp); - - // Read CD buffer - yread(&check, (void *)Cs2Area->block, sizeof(block_struct), MAX_BLOCKS, fp); - - // Read partition data - for (i = 0; i < MAX_SELECTORS; i++) - { - yread(&check, (void *)&Cs2Area->partition[i].size, 4, 1, fp); - yread(&check, (void *)Cs2Area->partition[i].blocknum, 1, MAX_BLOCKS, fp); - yread(&check, (void *)&Cs2Area->partition[i].numblocks, 1, 1, fp); - - for (i2 = 0; i2 < MAX_BLOCKS; i2++) - { - if (Cs2Area->partition[i].blocknum[i2] == 0xFF) - Cs2Area->partition[i].block[i2] = NULL; - else - Cs2Area->partition[i].block[i2] = Cs2Area->block + Cs2Area->partition[i].blocknum[i2]; - } - } - - // Read filter data - yread(&check, (void *)Cs2Area->filter, sizeof(filter_struct), MAX_SELECTORS, fp); - - // Read File Info Table - yread(&check, (void *)Cs2Area->fileinfo, sizeof(dirrec_struct), MAX_FILES, fp); - - // Read MPEG card registers here - - // Read current MPEG card status variables - yread(&check, (void *)&Cs2Area->actionstatus, 1, 1, fp); - yread(&check, (void *)&Cs2Area->pictureinfo, 1, 1, fp); - yread(&check, (void *)&Cs2Area->mpegaudiostatus, 1, 1, fp); - yread(&check, (void *)&Cs2Area->mpegvideostatus, 2, 1, fp); - yread(&check, (void *)&Cs2Area->vcounter, 2, 1, fp); - - // Read other MPEG card internal variables - yread(&check, (void *)&Cs2Area->mpegintmask, 4, 1, fp); - yread(&check, (void *)Cs2Area->mpegcon, sizeof(mpegcon_struct), 2, fp); - yread(&check, (void *)Cs2Area->mpegstm, sizeof(mpegstm_struct), 2, fp); - - return size; -} - -////////////////////////////////////////////////////////////////////////////// diff --git a/yabause/src/cs2.h b/yabause/src/cs2.h deleted file mode 100644 index 2c0a494242..0000000000 --- a/yabause/src/cs2.h +++ /dev/null @@ -1,359 +0,0 @@ -/* Copyright 2003 Guillaume Duhamel - Copyright 2004-2006 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CS2_H -#define CS2_H - -#include "memory.h" -#include "cdbase.h" -#include "cs0.h" - -#define MAX_BLOCKS 200 -#define MAX_SELECTORS 24 -#define MAX_FILES 256 - -typedef struct -{ - s32 size; - u32 FAD; - u8 cn; - u8 fn; - u8 sm; - u8 ci; - u8 data[2352]; -} block_struct; - -typedef struct -{ - u32 FAD; - u32 range; - u8 mode; - u8 chan; - u8 smmask; - u8 cimask; - u8 fid; - u8 smval; - u8 cival; - u8 condtrue; - u8 condfalse; -} filter_struct; - -typedef struct -{ - s32 size; - block_struct *block[MAX_BLOCKS]; - u8 blocknum[MAX_BLOCKS]; - u8 numblocks; -} partition_struct; - -typedef struct -{ - u16 groupid; - u16 userid; - u16 attributes; - u16 signature; - u8 filenumber; - u8 reserved[5]; -} xarec_struct; - -typedef struct -{ - u8 recordsize; - u8 xarecordsize; - u32 lba; - u32 size; - u8 dateyear; - u8 datemonth; - u8 dateday; - u8 datehour; - u8 dateminute; - u8 datesecond; - u8 gmtoffset; - u8 flags; - u8 fileunitsize; - u8 interleavegapsize; - u16 volumesequencenumber; - u8 namelength; - char name[32]; - xarec_struct xarecord; -} dirrec_struct; - -typedef struct -{ - u8 audcon; - u8 audlay; - u8 audbufdivnum; - u8 vidcon; - u8 vidlay; - u8 vidbufdivnum; -} mpegcon_struct; - -typedef struct -{ - u8 audstm; - u8 audstmid; - u8 audchannum; - u8 vidstm; - u8 vidstmid; - u8 vidchannum; -} mpegstm_struct; - -typedef struct -{ - u32 DTR; - u16 UNKNOWN; - u16 HIRQ; - u16 HIRQMASK; // Masks bits from HIRQ -only- when generating A-bus interrupts - u16 CR1; - u16 CR2; - u16 CR3; - u16 CR4; - u16 MPEGRGB; -} blockregs_struct; - -typedef struct { - blockregs_struct reg; - u32 FAD; - u8 status; - - // cd specific stats - u8 options; - u8 repcnt; - u8 ctrladdr; - u8 track; - u8 index; - - // mpeg specific stats - u8 actionstatus; - u8 pictureinfo; - u8 mpegaudiostatus; - u16 mpegvideostatus; - u16 vcounter; - - // authentication variables - u16 satauth; - u16 mpgauth; - - // internal varaibles - u32 transfercount; - u32 cdwnum; - u32 TOC[102]; - u32 playFAD; - u32 playendFAD; - unsigned int maxrepeat; - u32 getsectsize; - u32 putsectsize; - u32 calcsize; - s32 infotranstype; - s32 datatranstype; - int isonesectorstored; - int isdiskchanged; - int isbufferfull; - int speed1x; - int isaudio; - u8 transfileinfo[12]; - u8 lastbuffer; - - filter_struct filter[MAX_SELECTORS]; - filter_struct *outconcddev; - filter_struct *outconmpegfb; - filter_struct *outconmpegbuf; - filter_struct *outconmpegrom; - filter_struct *outconhost; - u8 outconcddevnum; - u8 outconmpegfbnum; - u8 outconmpegbufnum; - u8 outconmpegromnum; - u8 outconhostnum; - - partition_struct partition[MAX_SELECTORS]; - - partition_struct *datatranspartition; - u8 datatranspartitionnum; - s32 datatransoffset; - u32 datanumsecttrans; - u16 datatranssectpos; - u16 datasectstotrans; - - u32 blockfreespace; - block_struct block[MAX_BLOCKS]; - block_struct workblock; - - u32 curdirsect; - u32 curdirsize; - u32 curdirfidoffset; - dirrec_struct fileinfo[MAX_FILES]; - u32 numfiles; - - const char *mpegpath; - - u32 mpegintmask; - - mpegcon_struct mpegcon[2]; - mpegstm_struct mpegstm[2]; - - int _command; - u32 _periodiccycles; // microseconds * 3 - u32 _periodictiming; // microseconds * 3 - u32 _commandtiming; - CDInterface * cdi; - - int carttype; - int playtype; -} Cs2; - -typedef struct { - char system[17]; - char company[17]; - char itemnum[11]; - char version[7]; - char date[11]; - char cdinfo[9]; - char region[11]; - char peripheral[17]; - char gamename[113]; - u32 ipsize; - u32 msh2stack; - u32 ssh2stack; - u32 firstprogaddr; - u32 firstprogsize; -} ip_struct; - -extern Cs2 * Cs2Area; -extern ip_struct * cdip; - -int Cs2Init(int, int, const char *, const char *, const char *); -int Cs2ChangeCDCore(int coreid, const char *cdpath); -void Cs2DeInit(void); - -u8 FASTCALL Cs2ReadByte(u32); -u16 FASTCALL Cs2ReadWord(u32); -u32 FASTCALL Cs2ReadLong(u32); -void FASTCALL Cs2WriteByte(u32, u8); -void FASTCALL Cs2WriteWord(u32, u16); -void FASTCALL Cs2WriteLong(u32, u32); - -void FASTCALL Cs2RapidCopyT1(void *dest, u32 count); -void FASTCALL Cs2RapidCopyT2(void *dest, u32 count); - -void Cs2Exec(u32); -int Cs2GetTimeToNextSector(void); -void Cs2Execute(void); -void Cs2Reset(void); -void Cs2SetTiming(int); -void Cs2Command(void); -void Cs2SetCommandTiming(u8 cmd); - -// command name command code -void Cs2GetStatus(void); // 0x00 -void Cs2GetHardwareInfo(void); // 0x01 -void Cs2GetToc(void); // 0x02 -void Cs2GetSessionInfo(void); // 0x03 -void Cs2InitializeCDSystem(void); // 0x04 -// Open Tray // 0x05 -void Cs2EndDataTransfer(void); // 0x06 -void Cs2PlayDisc(void); // 0x10 -void Cs2SeekDisc(void); // 0x11 -// Scan Disc // 0x12 -void Cs2GetSubcodeQRW(void); // 0x20 -void Cs2SetCDDeviceConnection(void); // 0x30 -// get CD Device Connection // 0x31 -void Cs2GetLastBufferDestination(void); // 0x32 -void Cs2SetFilterRange(void); // 0x40 -// get Filter Range // 0x41 -void Cs2SetFilterSubheaderConditions(void);// 0x42 -void Cs2GetFilterSubheaderConditions(void);// 0x43 -void Cs2SetFilterMode(void); // 0x44 -void Cs2GetFilterMode(void); // 0x45 -void Cs2SetFilterConnection(void); // 0x46 -// Get Filter Connection // 0x47 -void Cs2ResetSelector(void); // 0x48 -void Cs2GetBufferSize(void); // 0x50 -void Cs2GetSectorNumber(void); // 0x51 -void Cs2CalculateActualSize(void); // 0x52 -void Cs2GetActualSize(void); // 0x53 -void Cs2GetSectorInfo(void); // 0x54 -void Cs2SetSectorLength(void); // 0x60 -void Cs2GetSectorData(void); // 0x61 -void Cs2DeleteSectorData(void); // 0x62 -void Cs2GetThenDeleteSectorData(void); // 0x63 -void Cs2PutSectorData(void); // 0x64 -// Copy Sector Data // 0x65 -// Move Sector Data // 0x66 -void Cs2GetCopyError(void); // 0x67 -void Cs2ChangeDirectory(void); // 0x70 -void Cs2ReadDirectory(void); // 0x71 -void Cs2GetFileSystemScope(void); // 0x72 -void Cs2GetFileInfo(void); // 0x73 -void Cs2ReadFile(void); // 0x74 -void Cs2AbortFile(void); // 0x75 -void Cs2MpegGetStatus(void); // 0x90 -void Cs2MpegGetInterrupt(void); // 0x91 -void Cs2MpegSetInterruptMask(void); // 0x92 -void Cs2MpegInit(void); // 0x93 -void Cs2MpegSetMode(void); // 0x94 -void Cs2MpegPlay(void); // 0x95 -void Cs2MpegSetDecodingMethod(void); // 0x96 -// MPEG Out Decoding Sync // 0x97 -// MPEG Get Timecode // 0x98 -// MPEG Get Pts // 0x99 -void Cs2MpegSetConnection(void); // 0x9A -void Cs2MpegGetConnection(void); // 0x9B -// MPEG Change Connection // 0x9C -void Cs2MpegSetStream(void); // 0x9D -void Cs2MpegGetStream(void); // 0x9E -// MPEG Get Picture Size // 0x9F -void Cs2MpegDisplay(void); // 0xA0 -void Cs2MpegSetWindow(void); // 0xA1 -void Cs2MpegSetBorderColor(void); // 0xA2 -void Cs2MpegSetFade(void); // 0xA3 -void Cs2MpegSetVideoEffects(void); // 0xA4 -// MPEG Get Image // 0xA5 -// MPEG Set Image // 0xA6 -// MPEG Read Image // 0xA7 -// MPEG Write Image // 0xA8 -// MPEG Read Sector // 0xA9 -// MPEG Write Sector // 0xAA -// MPEG Get LSI // 0xAE -void Cs2MpegSetLSI(void); // 0xAF -void Cs2CmdE0(void); // 0xE0 -void Cs2CmdE1(void); // 0xE1 -void Cs2CmdE2(void); // 0xE2 - -u8 Cs2FADToTrack(u32 val); -u32 Cs2TrackToFAD(u16 trackandindex); -void Cs2SetupDefaultPlayStats(u8 track_number, int writeFAD); -block_struct * Cs2AllocateBlock(u8 * blocknum); -void Cs2FreeBlock(block_struct * blk); -void Cs2SortBlocks(partition_struct * part); -partition_struct * Cs2GetPartition(filter_struct * curfilter); -partition_struct * Cs2FilterData(filter_struct * curfilter, int isaudio); -int Cs2CopyDirRecord(u8 * buffer, dirrec_struct * dirrec); -int Cs2ReadFileSystem(filter_struct * curfilter, u32 fid, int isoffset); -void Cs2SetupFileInfoTransfer(u32 fid); -partition_struct * Cs2ReadUnFilteredSector(u32 rufsFAD); -//partition_struct * Cs2ReadFilteredSector(u32 rfsFAD); -int Cs2ReadFilteredSector(u32 rfsFAD, partition_struct **partition); -u8 Cs2GetIP(int autoregion); -u8 Cs2GetRegionID(void); -int Cs2SaveState(FILE *); -int Cs2LoadState(FILE *, int, int); - -#endif diff --git a/yabause/src/debug.c b/yabause/src/debug.c deleted file mode 100644 index 295b21a00e..0000000000 --- a/yabause/src/debug.c +++ /dev/null @@ -1,186 +0,0 @@ -/* Copyright 2005 Guillaume Duhamel - Copyright 2006 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "debug.h" - -#include -#include -#include - -////////////////////////////////////////////////////////////////////////////// - -Debug * DebugInit(const char * n, DebugOutType t, char * s) { - Debug * d; - - if ((d = (Debug *) malloc(sizeof(Debug))) == NULL) - return NULL; - - d->output_type = t; - - if ((d->name = strdup(n)) == NULL) - { - free(d); - return NULL; - } - - switch(t) { - case DEBUG_STREAM: - d->output.stream = fopen(s, "w"); - break; - case DEBUG_STRING: - d->output.string = s; - break; - case DEBUG_STDOUT: - d->output.stream = stdout; - break; - case DEBUG_STDERR: - d->output.stream = stderr; - break; - case DEBUG_CALLBACK: - d->output.callback = (void (*) (char*))s; - break; - } - - return d; -} - -////////////////////////////////////////////////////////////////////////////// - -void DebugDeInit(Debug * d) { - if (d == NULL) - return; - - switch(d->output_type) { - case DEBUG_STREAM: - if (d->output.stream) - fclose(d->output.stream); - break; - case DEBUG_STRING: - case DEBUG_STDOUT: - case DEBUG_STDERR: - case DEBUG_CALLBACK: - break; - } - if (d->name) - free(d->name); - free(d); -} - -////////////////////////////////////////////////////////////////////////////// - -void DebugChangeOutput(Debug * d, DebugOutType t, char * s) { - if (t != d->output_type) { - if (d->output_type == DEBUG_STREAM) - { - if (d->output.stream) - fclose(d->output.stream); - } - d->output_type = t; - } - switch(t) { - case DEBUG_STREAM: - d->output.stream = fopen(s, "w"); - break; - case DEBUG_STRING: - d->output.string = s; - break; - case DEBUG_CALLBACK: - d->output.callback = (void (*) (char*))s; - break; - case DEBUG_STDOUT: - d->output.stream = stdout; - break; - case DEBUG_STDERR: - d->output.stream = stderr; - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void DebugPrintf(Debug * d, const char * file, u32 line, const char * format, ...) { - va_list l; - static char strtmp[512]; - static int strhash; - - if (d == NULL) - return; - - va_start(l, format); - - switch(d->output_type) { - case DEBUG_STDOUT: - case DEBUG_STDERR: - case DEBUG_STREAM: - if (d->output.stream == NULL) - break; - fprintf(d->output.stream, "%s (%s:%ld): ", d->name, file, (long)line); - vfprintf(d->output.stream, format, l); - break; - case DEBUG_STRING: - { - int i; - if (d->output.string == NULL) - break; - - i = sprintf(d->output.string, "%s (%s:%ld): ", d->name, file, (long)line); - vsprintf(d->output.string + i, format, l); - } - break; - case DEBUG_CALLBACK: - { - int i; - int strnewhash = 0; - i = sprintf(strtmp, "%s (%s:%ld): ", d->name, file, (long)line); - i += vsprintf(strtmp + i, format, l); - for ( ; i>0 ; i-- ) strnewhash += (int)(strtmp[i]); - if ( strnewhash != strhash ) d->output.callback( strtmp ); - strhash = strnewhash; - } - break; - } - - va_end(l); -} - -////////////////////////////////////////////////////////////////////////////// - -Debug * MainLog; - -////////////////////////////////////////////////////////////////////////////// - -void LogStart(void) { - MainLog = DebugInit("main", DEBUG_STDOUT, NULL); -// MainLog = DebugInit("main", DEBUG_STREAM, "stdout.txt"); -} - -////////////////////////////////////////////////////////////////////////////// - -void LogStop(void) { - DebugDeInit(MainLog); - MainLog = NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -void LogChangeOutput(DebugOutType t, char * s) { - - DebugChangeOutput( MainLog, t, s ); -} diff --git a/yabause/src/debug.h b/yabause/src/debug.h deleted file mode 100644 index 91935b322e..0000000000 --- a/yabause/src/debug.h +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright 2005-2006 Guillaume Duhamel - Copyright 2005 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef DEBUG_H -#define DEBUG_H - -#include "core.h" -#include - -typedef enum { DEBUG_STRING, DEBUG_STREAM , DEBUG_STDOUT, DEBUG_STDERR, DEBUG_CALLBACK } DebugOutType; - -typedef struct { - DebugOutType output_type; - union { - FILE * stream; - char * string; - void (*callback) (char*); - } output; - char * name; -} Debug; - -Debug * DebugInit(const char *, DebugOutType, char *); -void DebugDeInit(Debug *); - -void DebugChangeOutput(Debug *, DebugOutType, char *); - -void DebugPrintf(Debug *, const char *, u32, const char *, ...); - -extern Debug * MainLog; - -void LogStart(void); -void LogStop(void); -void LogChangeOutput(DebugOutType t, char * s); - -#ifdef DEBUG -#define LOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) -#else -#define LOG(...) -#endif - -#ifdef CDDEBUG -#define CDLOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) -#else -#define CDLOG(...) -#endif - -#ifdef SCSP_DEBUG -#define SCSPLOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) -#else -#define SCSPLOG(...) -#endif - -#ifdef VDP1_DEBUG -#define VDP1LOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) -#else -#define VDP1LOG(...) -#endif - -#ifdef VDP2_DEBUG -#define VDP2LOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) -#else -#define VDP2LOG(...) -#endif - -#ifdef SMPC_DEBUG -#define SMPCLOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) -#else -#define SMPCLOG(...) -#endif - -#endif diff --git a/yabause/src/dreamcast/CMakeLists.txt b/yabause/src/dreamcast/CMakeLists.txt deleted file mode 100644 index e76d009e4c..0000000000 --- a/yabause/src/dreamcast/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -project(yabause-dc) - -if(NOT dreamcast) - return() -endif(NOT dreamcast) - -enable_language(ASM-ATT) -include_directories(${PORT_INCLUDE_DIRS}) -add_definitions(${PORT_CFLAGS}) - -set(yabause_dc_SOURCES - cd.s - localtime.c - perdc.c - viddc.c - yui.c) - -set(yabause_dc_HEADERS - localtime.h - perdc.h - viddc.h) - -link_directories(..) -add_executable(yabause-dc ${yabause_dc_SOURCES}) -set_target_properties(yabause-dc PROPERTIES OUTPUT_NAME yabause.elf) -target_link_libraries(yabause-dc ${YABAUSE_LIBRARIES}) -target_link_libraries(yabause-dc ${PORT_LIBRARIES}) -target_link_libraries(yabause-dc yabause) -target_link_libraries(yabause-dc m) diff --git a/yabause/src/dreamcast/Makefile.am b/yabause/src/dreamcast/Makefile.am deleted file mode 100644 index a0bce0a82d..0000000000 --- a/yabause/src/dreamcast/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -EXTRA_DIST=cd.s localtime.c localtime.h perdc.c perdc.h viddc.c viddc.h yui.c diff --git a/yabause/src/dreamcast/cd.s b/yabause/src/dreamcast/cd.s deleted file mode 100644 index 817d1e93d6..0000000000 --- a/yabause/src/dreamcast/cd.s +++ /dev/null @@ -1,234 +0,0 @@ -! Copyright 2008 Lawrence Sebald -! -! This file is part of Yabause. -! -! Yabause is free software; you can redistribute it and/or modify -! it under the terms of the GNU General Public License as published by -! the Free Software Foundation; either version 2 of the License, or -! (at your option) any later version. -! -! Yabause is distributed in the hope that it will be useful, -! but WITHOUT ANY WARRANTY; without even the implied warranty of -! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -! GNU General Public License for more details. -! -! You should have received a copy of the GNU General Public License -! along with Yabause; if not, write to the Free Software -! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -! Ok, so this is the start of me assemblerizing different parts of the core -! of the Dreamcast port of Yabause. I picked the CD core since its one of the -! parts of the emulator that is least likely to change in the future -! (hopefully anyway), and its somewhat simple to start with. - - .file "cd.s" - .little - .text - .align 2 - -! static int DCCDInit(const char *cdrom_name) -! Initialize the GD drive to read 2352 byte sectors. -DCCDInit: - sts.l pr, @-r15 -.do_reinit: - mov.l .cdrom_exec_cmd, r0 - mov #0, r5 - jsr @r0 - mov #24, r4 ! CMD_INIT - cmp/eq #1, r0 ! ERR_NO_DISC - bt .init_return_success - cmp/eq #3, r0 ! ERR_SYS - bt .init_return_error - mov.l .gdc_syscall_vector, r1 - mova .DCCDInitParams, r0 - mov #10, r7 - mov.l @r1, r1 - mov r0, r4 - mov #0, r6 - jsr @r1 - mov #0, r5 - lds.l @r15+, pr - rts - nop -.init_return_success: - lds.l @r15+, pr - rts - mov #0, r0 -.init_return_error: - lds.l @r15+, pr - rts - mov #-1, r0 - .align 4 -.cdrom_exec_cmd: - .long _cdrom_exec_cmd -.DCCDInitParams: - .long 0 ! 0 = set - .long 4096 ! Magic value for RAW sector reads - .long 0x0400 ! Ditto - .long 2352 ! Sector Size? (Maybe not for RAW though?) - -! static int DCCDGetStatus(void) -! Execute the BIOS syscall of the Dreamcast to get the GD drive status, -! translating that into the format expected by the core of Yabause. -DCCDGetStatus: - sts.l pr, @-r15 -.status_startgame: - mov.l .gdc_syscall_vector, r1 - mova .get_status_scratchpad, r0 - mov #4, r7 - mov.l @r1, r1 - mov #0, r5 - mov r0, r4 - jsr @r1 - mov #0, r6 - cmp/eq #2, r0 ! 2 = Disc change error - bt .status_reinit - cmp/eq #0, r0 - bf .status_error -.status_endgame: ! status in 1st entry in scratchpad - mova .get_status_scratchpad, r0 - mov #0x07, r2 - mov.l @r0, r1 - mova .get_status_return_value, r0 - and r2, r1 - add r1, r0 - lds.l @r15+, pr - rts - mov.b @r0, r0 -.status_reinit: - mov.l .get_status_init_func, r0 - jsr @r0 - mov #0, r4 - cmp/eq #0, r0 - bt .status_startgame -.status_error: - lds.l @r15+, pr - rts - mov #2, r0 - - .align 4 -.gdc_syscall_vector: - .long 0x8c0000bc -.get_status_scratchpad: - .long 0 - .long 0 -.get_status_return_value: - .byte 0, 1, 1, 0, 0, 0, 3, 2 -.get_status_init_func: - .long DCCDInit - -! static int DCCDDeInit(void) -! Deinitialize the CD Drive of the Dreamcast (i.e., undo the odd -! initialization stuff that the code does for Yabause). -DCCDDeInit: - mov.l .cdrom_reinit, r0 - sts.l pr, @-r15 - jsr @r0 - nop - lds.l @r15+, pr - rts - nop ! Leave the return value from cdrom_reinit as the return here. - -! static int DCCDReadSectorFAD(u32 FAD, void *buffer) -! Read a single 2352 byte sector from the given position on the disc. -DCCDReadSectorFAD: - sts.l pr, @-r15 - mov r4, r2 - mov.l r4, @-r15 - mov r5, r4 - mov.l .cdrom_read_sectors, r0 - mov.l r5, @-r15 - mov r2, r5 -.read_sector_start: - jsr @r0 - mov #1, r6 - cmp/eq #2, r0 - bt .read_reinit - cmp/eq #0, r0 - add #8, r15 - bf/s .read_error - lds.l @r15+, pr - rts - mov #1, r0 -.read_reinit: - mov.l .DCCDInit, r0 - jsr @r0 - mov #0, r4 - cmp/eq #0, r0 - mov.l @r15, r4 - mov.l .cdrom_read_sectors, r0 - bt/s .read_sector_start - mov.l @(4, r15), r5 - add #8, r15 -.read_error: - rts - mov #0, r0 - -! static int DCCDReadAheadFAD(u32 FAD) -! No-op (for the moment). -DCCDReadAheadFAD: - rts - nop - -! static s32 DCCDReadTOC(u32 *TOC); -! Read the TOC of the CD inserted in the drive. -! Amusingly enough, I just realized that the format that Yabause expects -! and what the Dreamcast spews out are exactly the same. Go figure! -DCCDReadTOC: - sts.l pr, @-r15 - mov.l .cdrom_read_toc, r0 - mov.l r4, @-r15 -.readtoc_start: - jsr @r0 - mov #0, r5 - cmp/eq #2, r0 - bt .readtoc_reinit - cmp/eq #0, r0 - add #4, r15 - bf/s .readtoc_error - mov #0xCC, r0 - lds.l @r15+, pr - extu.b r0, r0 - rts - shll r0 -.readtoc_reinit: - mov.l .DCCDInit, r0 - jsr @r0 - mov #0, r4 - cmp/eq #0, r0 - mov.l @r15, r4 - bt/s .readtoc_start - mov.l .cdrom_read_toc, r0 - add #4, r15 -.readtoc_error: - rts - mov #0, r0 - - .align 4 -.cdrom_reinit: - .long _cdrom_reinit -.cdrom_read_sectors: - .long _cdrom_read_sectors -.DCCDInit: - .long DCCDInit -.cdrom_read_toc: - .long _cdrom_read_toc - - .section .rodata - .align 2 -.CDInterfaceName: - .string "Dreamcast CD Drive" - - .data - .align 4 - .globl _ArchCD - .size _ArchCD, 32 -_ArchCD: - .long 2 - .long .CDInterfaceName - .long DCCDInit - .long DCCDDeInit - .long DCCDGetStatus - .long DCCDReadTOC - .long DCCDReadSectorFAD - .long DCCDReadAheadFAD diff --git a/yabause/src/dreamcast/dreamcast.cmake b/yabause/src/dreamcast/dreamcast.cmake deleted file mode 100644 index 0c39a1b97f..0000000000 --- a/yabause/src/dreamcast/dreamcast.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# CMake toolchain file for building Yabause on the Dreamcast -set(CMAKE_SYSTEM_NAME Generic) - -# Use the gnu_wrappers for the various GNU utilities -set(CMAKE_C_COMPILER kos-cc) -set(CMAKE_CXX_COMPILER kos-c++) -set(CMAKE_ASM_COMPILER kos-as) - -# KOS Sets this nicely for us. -set(CMAKE_FIND_ROOT_PATH $ENV{KOS_CC_BASE}) - -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) - -# Set some stuff so that it doesn't complain about the lack of a normal looking -# pthreads flag/library for the compiler. -set(THREADS_HAVE_PTHREAD_ARG 1) -set(CMAKE_HAVE_THREADS_LIBRARY 1) - -# Set a flag so we know we're trying to compile for Dreamcast -set(dreamcast 1) diff --git a/yabause/src/dreamcast/localtime.c b/yabause/src/dreamcast/localtime.c deleted file mode 100644 index e13d56a031..0000000000 --- a/yabause/src/dreamcast/localtime.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * localtime_r.c - * Original Author: Adapted from tzcode maintained by Arthur David Olson. - * - * Converts the calendar time pointed to by tim_p into a broken-down time - * expressed as local time. Returns a pointer to a structure containing the - * broken-down time. - */ - -/* This file was taken from newlib , it's a - * modified version of Arthur David Olsons localtime.c from tzcode which - * is under Public Domain */ - -#include -#include -#include "localtime.h" - -#define SECSPERMIN 60L -#define MINSPERHOUR 60L -#define HOURSPERDAY 24L -#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) -#define SECSPERDAY (SECSPERHOUR * HOURSPERDAY) -#define DAYSPERWEEK 7 -#define MONSPERYEAR 12 - -#define YEAR_BASE 1900 -#define EPOCH_YEAR 1970 -#define EPOCH_WDAY 4 - -#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) - -static const int mon_lengths[2][MONSPERYEAR] = { - {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -} ; - -static const int year_lengths[2] = { - 365, - 366 -} ; - -struct tm * internal_localtime_r(const time_t * tim_p, struct tm *res) -{ - long days, rem; - int y; - int yleap; - const int *ip; - - days = ((long) *tim_p) / SECSPERDAY; - rem = ((long) *tim_p) % SECSPERDAY; - while (rem < 0) - { - rem += SECSPERDAY; - --days; - } - while (rem >= SECSPERDAY) - { - rem -= SECSPERDAY; - ++days; - } - - /* compute hour, min, and sec */ - res->tm_hour = (int) (rem / SECSPERHOUR); - rem %= SECSPERHOUR; - res->tm_min = (int) (rem / SECSPERMIN); - res->tm_sec = (int) (rem % SECSPERMIN); - - /* compute day of week */ - if ((res->tm_wday = ((EPOCH_WDAY + days) % DAYSPERWEEK)) < 0) - res->tm_wday += DAYSPERWEEK; - - /* compute year & day of year */ - y = EPOCH_YEAR; - if (days >= 0) - { - for (;;) - { - yleap = isleap(y); - if (days < year_lengths[yleap]) - break; - y++; - days -= year_lengths[yleap]; - } - } - else - { - do - { - --y; - yleap = isleap(y); - days += year_lengths[yleap]; - } while (days < 0); - } - - res->tm_year = y - YEAR_BASE; - res->tm_yday = days; - ip = mon_lengths[yleap]; - for (res->tm_mon = 0; days >= ip[res->tm_mon]; ++res->tm_mon) - days -= ip[res->tm_mon]; - res->tm_mday = days + 1; - - /* set daylight saving time flag */ - res->tm_isdst = -1; - - return (res); -} diff --git a/yabause/src/dreamcast/localtime.h b/yabause/src/dreamcast/localtime.h deleted file mode 100644 index fb894aad44..0000000000 --- a/yabause/src/dreamcast/localtime.h +++ /dev/null @@ -1,3 +0,0 @@ -/* internal_localtime_r() function declaration, included by smpc.c */ - -extern struct tm * internal_localtime_r(const time_t * tim_p, struct tm *res); diff --git a/yabause/src/dreamcast/perdc.c b/yabause/src/dreamcast/perdc.c deleted file mode 100644 index 2ebab80ace..0000000000 --- a/yabause/src/dreamcast/perdc.c +++ /dev/null @@ -1,145 +0,0 @@ -/* Copyright 2005-2008 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "perdc.h" -#include "../yabause.h" -#include "../yui.h" -#include "../vdp2.h" - -#include -#include - -int PERDCInit(void); -void PERDCDeInit(void); -int PERDCHandleEvents(void); -void PERDCNothing(void); -u32 PERDCScan(void); - -static PerPad_struct *pad1; - -PerInterface_struct PERDC = { - PERCORE_DC, - "Dreamcast Input Interface", - PERDCInit, - PERDCDeInit, - PERDCHandleEvents, - PERDCNothing, - PERDCScan, - 0, - PERDCNothing -}; - -int PERDCInit(void) { - PerPortReset(); - pad1 = PerPadAdd(&PORTDATA1); - return 0; -} - -void PERDCDeInit(void) { -} - -int PERDCHandleEvents(void) { - maple_device_t *dev; - - dev = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); - if(dev != NULL) { - cont_state_t *state = (cont_state_t *) maple_dev_status(dev); - - if(state != NULL) { - if(state->buttons & CONT_DPAD_UP) - *pad1->padbits &= 0xEF; - else - *pad1->padbits |= 0x10; - - if(state->buttons & CONT_DPAD_DOWN) - *pad1->padbits &= 0xDF; - else - *pad1->padbits |= 0x20; - - if(state->buttons & CONT_DPAD_RIGHT) - *pad1->padbits &= 0x7F; - else - *pad1->padbits |= 0x80; - - if(state->buttons & CONT_DPAD_LEFT) - *pad1->padbits &= 0xBF; - else - *pad1->padbits |= 0x40; - - if(state->buttons & CONT_START) - *pad1->padbits &= 0xF7; - else - *pad1->padbits |= 0x08; - - if(state->buttons & CONT_A) - *pad1->padbits &= 0xFB; - else - *pad1->padbits |= 0x04; - - if(state->buttons & CONT_B) - *pad1->padbits &= 0xFE; - else - *pad1->padbits |= 0x01; - - if(state->buttons & CONT_X) - *(pad1->padbits + 1) &= 0xBF; - else - *(pad1->padbits + 1) |= 0x40; - - if(state->buttons & CONT_Y) - *(pad1->padbits + 1) &= 0xDF; - else - *(pad1->padbits + 1) |= 0x20; - - if(state->rtrig > 20) - *(pad1->padbits + 1) &= 0x7F; - else - *(pad1->padbits + 1) |= 0x80; - - if(state->ltrig > 20) - *(pad1->padbits + 1) &= 0xF7; - else - *(pad1->padbits + 1) |= 0x08; - - if(state->joyx > 20) - *pad1->padbits &= 0xFD; - else - *pad1->padbits |= 0x02; - - if(state->joyy > 20) - *(pad1->padbits + 1) &= 0xEF; - else - *(pad1->padbits + 1) |= 0x10; - - } - } - - YabauseExec(); - - return 0; -} - -void PERDCNothing(void) { - /* Nothing */ -} - -u32 PERDCScan(void) { - /* Nothing */ - return 0; -} diff --git a/yabause/src/dreamcast/perdc.h b/yabause/src/dreamcast/perdc.h deleted file mode 100644 index 2dcbe64f41..0000000000 --- a/yabause/src/dreamcast/perdc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright 2005 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PERDC_H -#define PERDC_H - -#include "../peripheral.h" - -#define PERCORE_DC 2 - -extern PerInterface_struct PERDC; - -#endif diff --git a/yabause/src/dreamcast/sh2rec/sh2exec.s b/yabause/src/dreamcast/sh2rec/sh2exec.s deleted file mode 100644 index f2ff5f9aaa..0000000000 --- a/yabause/src/dreamcast/sh2rec/sh2exec.s +++ /dev/null @@ -1,100 +0,0 @@ -! Copyright 2010 Lawrence Sebald -! -! This file is part of Yabause. -! -! Yabause is free software; you can redistribute it and/or modify -! it under the terms of the GNU General Public License as published by -! the Free Software Foundation; either version 2 of the License, or -! (at your option) any later version. -! -! Yabause is distributed in the hope that it will be useful, -! but WITHOUT ANY WARRANTY; without even the implied warranty of -! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -! GNU General Public License for more details. -! -! You should have received a copy of the GNU General Public License -! along with Yabause; if not, write to the Free Software -! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -! Code for calling upon the code generated by sh2rec (SuperH). - - .file "sh2exec.s" - .little - .text - .balign 8 - -! void sh2rec_exec(SH2_struct *cxt, u32 cycles) -! Execute the specified number of cycles on the given SH2 context - .globl _sh2rec_exec -_sh2rec_exec: - stc.l gbr, @-r15 ! Save call-preserved stuff - sts.l mach, @-r15 ! Ditto - sts.l macl, @-r15 ! Ditto - mov.l r8, @-r15 ! Ditto - mov r4, r8 ! Put the SH2 struct in r8 - mov.l r9, @-r15 ! More call-preserved stuff - add #76, r4 ! Point at MACH in the SH2 struct - mov.l r10, @-r15 ! More call-preserved stuff - mov.l r11, @-r15 ! Last one for now... - lds.l @r4+, mach ! Load the SH2 MACH into our MACH - lds.l @r4+, macl ! Ditto for MACL - mov.l checkInterrupts, r0 ! We need to check for interrupts... - mov.l sh2memfuncsptr, r9 ! Memory access function pointer table - sts.l pr, @-r15 ! Helps to know where to go back to - mov r5, r11 ! This is important enough to keep here - mov.l r5, @-r15 ! Save this on the stack too - mov r8, r4 ! We need the original SH2_struct back - jsr @r0 ! Call sh2rec_check_interrupts - ldc r8, gbr ! Put the SH2 struct in gbr (delay slot) - mov.l findBlock, r1 ! Grab the sh2rec_find_block function - mov.l @(88, gbr), r0 ! Grab the PC we are at -.exec_loop: ! This is where the fun is! - jsr @r1 ! Call sh2rec_find_block - mov r0, r4 ! Move the PC to argument 1 (delay slot) - mov.l @r0, r2 ! Grab where the code is - mov.l @(8, r0), r1 ! Figure out the number of cycles used - jsr @r2 ! Call the block - sub r1, r11 ! Chop off the cycles (delay slot) - cmp/pl r11 ! Are we done? - mov.l findBlock, r1 ! Grab the sh2rec_find_block function - bt .exec_loop ! Continue on if needed - ! When we are done, we will be here. - mov.l r0, @(88, gbr) ! Save the next PC value - mov.l @r15+, r5 ! Pop the requested number of cycles - mov r8, r4 ! Keep this for sanity for now - add #84, r8 ! Point just after MACL in SH2 struct - sts.l macl, @-r8 ! Store the SH2 MACL back in the struct - sts.l mach, @-r8 ! Ditto for MACH - lds.l @r15+, pr ! Restore stuff from the stack - sub r11, r5 ! Our counter is negitive, so this works - mov.l cycleOffset, r2 ! Where is the cycles member at? - mov.l @r15+, r11 ! More restoring... - add r2, r4 ! Point r4 at the cycles member - mov.l @r15+, r10 - mov.l @r15+, r9 - mov.l @r15+, r8 - lds.l @r15+, macl - lds.l @r15+, mach - mov.l r5, @r4 ! Save the cycles we spent - rts ! Return to the caller - ldc.l @r15+, gbr ! Last thing to restore (delay slot) - - .balign 4 -sh2memfuncsptr: - .long sh2memfuncs -checkInterrupts: - .long _sh2rec_check_interrupts -findBlock: - .long _sh2rec_find_block -cycleOffset: - .long 5516 - - .data - .balign 4 -sh2memfuncs: - .long _MappedMemoryReadByte - .long _MappedMemoryReadWord - .long _MappedMemoryReadLong - .long _MappedMemoryWriteByte - .long _MappedMemoryWriteWord - .long _MappedMemoryWriteLong diff --git a/yabause/src/dreamcast/sh2rec/sh2rec.c b/yabause/src/dreamcast/sh2rec/sh2rec.c deleted file mode 100644 index 2295da27ed..0000000000 --- a/yabause/src/dreamcast/sh2rec/sh2rec.c +++ /dev/null @@ -1,2908 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* SH2 Dynarec Core (for SH4) */ - -#include -#include -#include -#include - -#include "sh2core.h" -#include "sh2rec.h" -#include "sh2rec_htab.h" -#include "sh2int.h" - -/* Registers */ -#define R0 0 -#define R1 1 -#define R2 2 -#define R3 3 -#define R4 4 -#define R5 5 -#define R6 6 -#define R7 7 -#define R8 8 -#define R9 9 -#define R10 10 -#define R11 11 -#define R12 12 -#define R13 13 -#define R14 14 -#define R15 15 - -/* Control Registers (use with emitSTC/emitLDC) */ -#define R_SR 0 -#define R_GBR 1 -#define R_VBR 2 - -/* System Registers (use with emitSTS/emitLDS) */ -#define R_MACH 0 -#define R_MACL 1 -#define R_PR 2 - -/* ALU Ops, to be used with the emitALU function */ -#define OP_ADD 0x300C -#define OP_ADDC 0x300E -#define OP_AND 0x2009 -#define OP_EXTSB 0x600E -#define OP_EXTSW 0x600F -#define OP_EXTUB 0x600C -#define OP_EXTUW 0x600D -#define OP_NEG 0x600B -#define OP_NEGC 0x600A -#define OP_NOT 0x6007 -#define OP_OR 0x200B -#define OP_SUB 0x3008 -#define OP_SUBC 0x300A -#define OP_SWAPB 0x6008 -#define OP_SWAPW 0x6009 -#define OP_XOR 0x200A -#define OP_XTRCT 0x200D - -/* Shift/Rotate Ops, to be used with the emitSHIFT function */ -#define OP_ROTCL 0x4024 -#define OP_ROTCR 0x4025 -#define OP_ROTL 0x4004 -#define OP_ROTR 0x4005 -#define OP_SHAL 0x4020 -#define OP_SHAR 0x4021 -#define OP_SHLL 0x4000 -#define OP_SHLR 0x4001 - -/* Comparison Ops, to be used with the emitALU function */ -#define OP_CMPEQ 0x3000 -#define OP_CMPGE 0x3003 -#define OP_CMPGT 0x3007 -#define OP_CMPHI 0x3006 -#define OP_CMPHS 0x3002 -#define OP_CMPSTR 0x200C -#define OP_TST 0x2008 - -/* Multiplication ops, to be used with the emitALU function */ -#define OP_DMULS 0x300D -#define OP_DMULU 0x3005 -#define OP_MULL 0x0007 -#define OP_MULS 0x200F -#define OP_MULU 0x200E - -#ifdef SH2REC__DEBUG -#define EMIT_INST {\ - printf("%s\n", __PRETTY_FUNCTION__); \ - printf("Emitting %04x at %p\n", inst, (void *)b->ptr); \ - *b->ptr++ = inst; \ -} -#else -#define EMIT_INST *b->ptr++ = inst -#endif - -#ifdef SH2REC__DEBUG -#define EMIT_32 {\ - uint32_t *__ptr = (uint32_t *)b->ptr; \ - printf("%s\n", __PRETTY_FUNCTION__); \ - printf("Emitting %08x at %p\n", (unsigned int)v, (void *)__ptr); \ - *__ptr = v; \ - b->ptr += 2; \ -} -#else -#define EMIT_32 uint32_t *__ptr = (uint32_t *)b->ptr; *__ptr = v; b->ptr += 2 -#endif - -static inline void emit16(sh2rec_block_t *b, uint16_t inst) { - EMIT_INST; -} - -static inline void emit32(sh2rec_block_t *b, uint32_t v) { - EMIT_32; -} - -static inline void emitMOV(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x6003 | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitMOVWI(sh2rec_block_t *b, int d, int n) { - uint16_t inst = 0x9000 | (n << 8) | (d); - EMIT_INST; -} - -static inline void emitMOVLI(sh2rec_block_t *b, int d, int n) { - uint16_t inst = 0xD000 | (n << 8) | (d); - EMIT_INST; -} - -static inline void emitMOVLS(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x2002 | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitMOVLL(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x6002 | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitMOVWM(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x2005 | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitMOVLM(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x2006 | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitMOVLP(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x6006 | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitMOVI(sh2rec_block_t *b, int imm, int n) { - uint16_t inst = 0xE000 | (n << 8) | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitMOVLL4(sh2rec_block_t *b, int m, int d, int n) { - uint16_t inst = 0x5000 | (n << 8) | (m << 4) | (d); - EMIT_INST; -} - -static inline void emitMOVLS4(sh2rec_block_t *b, int m, int d, int n) { - uint16_t inst = 0x1000 | (n << 8) | (m << 4) | (d); - EMIT_INST; -} - -static inline void emitMOVLLG(sh2rec_block_t *b, int imm) { - uint16_t inst = 0xC600 | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitMOVLSG(sh2rec_block_t *b, int imm) { - uint16_t inst = 0xC200 | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitMOVT(sh2rec_block_t *b, int n) { - uint16_t inst = 0x0029 | (n << 8); - EMIT_INST; -} - -static inline void emitALU(sh2rec_block_t *b, int m, int n, uint16_t op) { - uint16_t inst = (n << 8) | (m << 4) | op; - EMIT_INST; -} - -static inline void emitSHIFT(sh2rec_block_t *b, int n, uint16_t op) { - uint16_t inst = (n << 8) | op; - EMIT_INST; -} - -static inline void emitADDI(sh2rec_block_t *b, int imm, int n) { - uint16_t inst = 0x7000 | (n << 8) | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitANDI(sh2rec_block_t *b, int imm) { - uint16_t inst = 0xC900 | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitORI(sh2rec_block_t *b, int imm) { - uint16_t inst = 0xCB00 | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitXORI(sh2rec_block_t *b, int imm) { - uint16_t inst = 0xCA00 | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitSHLL2(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4008 | (n << 8); - EMIT_INST; -} - -static inline void emitSHLL8(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4018 | (n << 8); - EMIT_INST; -} - -static inline void emitSHLL16(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4028 | (n << 8); - EMIT_INST; -} - -static inline void emitSHLR2(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4009 | (n << 8); - EMIT_INST; -} - -static inline void emitSHLR8(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4019 | (n << 8); - EMIT_INST; -} - -static inline void emitSHLR16(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4029 | (n << 8); - EMIT_INST; -} - -static inline void emitCMPIM(sh2rec_block_t *b, int imm) { - uint16_t inst = 0x8800 | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitCMPPL(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4015 | (n << 8); - EMIT_INST; -} - -static inline void emitCMPPZ(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4011 | (n << 8); - EMIT_INST; -} - -static inline void emitADDV(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x300F | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitSUBV(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x300B | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitLDS(sh2rec_block_t *b, int m, int sr) { - uint16_t inst = 0x400A | (m << 8) | (sr << 4); - EMIT_INST; -} - -static inline void emitSTS(sh2rec_block_t *b, int sr, int n) { - uint16_t inst = 0x000A | (n << 8) | (sr << 4); - EMIT_INST; -} - -static inline void emitLDC(sh2rec_block_t *b, int m, int sr) { - uint16_t inst = 0x400E | (m << 8) | (sr << 4); - EMIT_INST; -} - -static inline void emitSTC(sh2rec_block_t *b, int sr, int n) { - uint16_t inst = 0x0002 | (n << 8) | (sr << 4); - EMIT_INST; -} - -static inline void emitDT(sh2rec_block_t *b, int n) { - uint16_t inst = 0x4010 | (n << 8); - EMIT_INST; -} - -static inline void emitTSTI(sh2rec_block_t *b, int imm) { - uint16_t inst = 0xC800 | (imm & 0xFF); - EMIT_INST; -} - -static inline void emitBRA(sh2rec_block_t *b, int d) { - uint16_t inst = 0xA000 | (d); - EMIT_INST; -} - -static inline void emitDIV0S(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x2007 | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitDIV1(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x3004 | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitRTS(sh2rec_block_t *b) { - uint16_t inst = 0x000B; - EMIT_INST; -} - -static inline void emitNOP(sh2rec_block_t *b) { - uint16_t inst = 0x0009; - EMIT_INST; -} - -static inline void emitJSR(sh2rec_block_t *b, int m) { - uint16_t inst = 0x400B | (m << 8); - EMIT_INST; -} - -static inline void emitMACL(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x000F | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitMACW(sh2rec_block_t *b, int m, int n) { - uint16_t inst = 0x400F | (n << 8) | (m << 4); - EMIT_INST; -} - -static inline void emitCLRMAC(sh2rec_block_t *b) { - uint16_t inst = 0x0028; - EMIT_INST; -} - -static inline void emitBF(sh2rec_block_t *b, int disp) { - uint16_t inst = 0x8B00 | (disp & 0xFF); - EMIT_INST; -} - -static inline void emitBT(sh2rec_block_t *b, int disp) { - uint16_t inst = 0x8900 | (disp & 0xFF); - EMIT_INST; -} - -static inline void generateALUOP(uint16_t inst, sh2rec_block_t *b, int op) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitALU(b, R3, R2, op); /* R2 <- R2 o R3 */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ -} - -static inline void generateSHIFT(uint16_t inst, sh2rec_block_t *b, int op) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitSHIFT(b, R2, op); /* R2 <- R2 op */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ -} - -static inline void generateCOMP(uint16_t inst, sh2rec_block_t *b, int op) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitALU(b, R3, R2, op); /* R2 op R3 */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ -} - -static void generateADD(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_ADD); - b->pc += 2; -} - -static void generateADDI(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int imm = INSTRUCTION_CD(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitADDI(b, imm, R2); /* R2 <- R2 + #imm */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateADDC(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitALU(b, R3, R2, OP_ADDC); /* R2 = R2 + R3 + T (carry to T) */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateADDV(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitADDV(b, R3, R2); /* R2 = R2 + R3 (overflow to T Bit) */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateAND(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_AND); - b->pc += 2; -} - -static void generateANDI(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitMOVLL4(b, R8, 0, R0); /* R0 <- sh2[R0] */ - emitANDI(b, imm); /* R0 <- R0 & #imm */ - emitMOVLS4(b, R0, 0, R8); /* sh2[R0] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateANDM(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitMOVLL4(b, R8, 0, R4); /* R4 <- sh2[R0] */ - emitMOVLL4(b, R9, 0, R1); /* R1 <- MappedMemoryReadByte */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitJSR(b, R1); /* Call MappedMemoryReadByte */ - emitMOVLM(b, R4, R15); /* Push R4 on the stack (delay slot) */ - emitMOVLL4(b, R9, 3, R1); /* R1 <- MappedMemoryWriteByte */ - emitANDI(b, imm); /* R0 <- R0 & #imm */ - emitMOVLP(b, R15, R4); /* Pop R4 off the stack */ - emitJSR(b, R1); /* Call MappedMemoryWriteByte */ - emitMOV(b, R0, R5); /* R5 <- R0 (delay slot) */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateBF(uint16_t inst, sh2rec_block_t *b) { - int disp = INSTRUCTION_CD(inst); - uint32_t val = b->pc + 2; - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLI(b, 4, R2); /* R2 <- sh2[PC] + 2 */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitMOVI(b, 0, R0); /* R0 <- 0 */ - emitBT(b, 2); /* Branch around the addition if needed */ - emitMOVI(b, disp, R0); /* R0 <- displacement */ - emitSHIFT(b, R0, OP_SHLL); /* R0 <- R0 << 1 */ - emitADDI(b, 2, R0); /* R0 <- R0 + 2 */ - emitRTS(b); /* Return to sender! */ - emitALU(b, R2, R0, OP_ADD); /* R0 <- R0 + R2 (delay slot) */ - if(((uint32_t)b->ptr) & 0x03) - emit16(b, 0); /* Padding if we need it */ - emit32(b, val); /* The next PC value (if not taken) */ - - b->cycles += 2; /* 2 Cycles (if not taken) */ - /* XXXX: Handle taken case cycle difference */ -} - -static void generateBFS(uint16_t inst, sh2rec_block_t *b) { - int disp = INSTRUCTION_CD(inst); - uint32_t val = b->pc + 4; - int n = (((uint32_t)b->ptr) & 0x03) ? 3 : 4; - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLI(b, n, R2); /* R2 <- sh2[PC] + 4 */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitMOVI(b, 0, R0); /* R0 <- 0 */ - emitBT(b, 1); /* Branch around the addition if needed */ - emitMOVI(b, disp, R0); /* R0 <- displacement */ - emitSHIFT(b, R0, OP_SHLL); /* R0 <- R0 << 1 */ - - if(((uint32_t)b->ptr) & 0x03) { - emitBRA(b, 3); /* Branch around the constant */ - emitALU(b, R2, R0, OP_ADD); /* R0 <- R0 + R2 (delay slot) */ - emit16(b, 0); /* Padding since we need it */ - } - else { - emitBRA(b, 2); /* Branch around the constant */ - emitALU(b, R2, R0, OP_ADD); /* R0 <- R0 + R2 (delay slot) */ - } - - emit32(b, val); /* The next PC value (if not taken) */ - emitMOVLM(b, R0, R15); /* Push the next PC on the stack */ - - /* Deal with the delay slot here */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - ++b->cycles; /* 1 Cycle (if not taken) */ - /* XXXX: Handle taken case cycle difference */ -} - -static void generateBRA(uint16_t inst, sh2rec_block_t *b) { - int disp = INSTRUCTION_BCD(inst); - int32_t val; - - if(disp & 0x00000800) { - disp |= 0xFFFFF000; - } - - val = b->pc + 4 + (disp << 1); - - emitMOVLI(b, 1, R2); /* R2 <- sh2[PC] + 4 + disp */ - - if(((uint32_t)b->ptr) & 0x03) { - emitBRA(b, 3); /* Branch around the constant */ - emitMOVLM(b, R2, R15); /* Push the next PC (delay slot) */ - emit16(b, 0); /* Padding since we need it */ - } - else { - emitBRA(b, 2); /* Branch around the constant */ - emitMOVLM(b, R2, R15); /* Push the next PC (delay slot) */ - } - - emit32(b, (uint32_t )val); /* The next PC */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - b->cycles += 2; /* 2 Cycles */ -} - -static void generateBRAF(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - uint32_t val = b->pc + 4; - - if(((uint32_t)b->ptr) & 0x03) { - emitMOVLI(b, 2, R0); /* R0 <- sh2[PC] + 4 */ - emitMOVLL4(b, R8, regm, R2);/* R2 <- sh2[Rm] */ - emitBRA(b, 3); /* Branch around the constant */ - emitALU(b, R0, R2, OP_ADD); /* R2 <- R0 + R2 (delay slot) */ - emit16(b, 0); /* Padding since we need it */ - } - else { - emitMOVLI(b, 1, R0); /* R0 <- sh2[PC] + 4 */ - emitMOVLL4(b, R8, regm, R2);/* R2 <- sh2[Rm] */ - emitBRA(b, 2); /* Branch around the constant */ - emitALU(b, R0, R2, OP_ADD); /* R2 <- R0 + R2 (delay slot) */ - } - - emit32(b, val); /* The value to use as the base for PC */ - emitMOVLM(b, R2, R15); /* Push the next PC */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - b->cycles += 2; /* 2 Cycles */ -} - -static void generateBSR(uint16_t inst, sh2rec_block_t *b) { - int disp = INSTRUCTION_BCD(inst); - int32_t val; - int32_t val2 = b->pc + 4; - - if(disp & 0x00000800) { - disp |= 0xFFFFF000; - } - - val = b->pc + 4 + (disp << 1); - - if(((uint32_t)b->ptr) & 0x03) { - emitMOVLI(b, 2, R2); /* R2 <- sh2[PC] + 4 + disp */ - emitMOVLI(b, 2, R0); /* R0 <- sh2[PC] + 4 */ - emitBRA(b, 5); /* Branch around the constant */ - emitMOVLM(b, R2, R15); /* Push the next PC (delay slot) */ - emit16(b, 0); /* Padding since we need it */ - } - else { - emitMOVLI(b, 1, R2); /* R2 <- sh2[PC] + 4 + disp */ - emitMOVLI(b, 2, R0); /* R0 <- sh2[PC] + 4 */ - emitBRA(b, 4); /* Branch around the constant */ - emitMOVLM(b, R2, R15); /* Push the next PC (delay slot) */ - } - - emit32(b, (uint32_t)val); /* The next PC */ - emit32(b, (uint32_t)val2); /* The value for PR */ - emitMOVLSG(b, 21); /* sh2[PR] <- R0 */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - b->cycles += 2; /* 2 Cycles */ -} - -static void generateBSRF(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - uint32_t val = b->pc + 4; - - emitMOVLI(b, 1, R0); /* R0 <- sh2[PC] + 4 */ - - if(((uint32_t)b->ptr) & 0x03) { - emitBRA(b, 3); /* Branch around the constant */ - emitMOVLL4(b, R8, regm, R2);/* R2 <- sh2[Rm] (delay slot) */ - emit16(b, 0); /* Padding since we need it */ - } - else { - emitBRA(b, 2); /* Branch around the constant */ - emitMOVLL4(b, R8, regm, R2);/* R2 <- sh2[Rm] (delay slot) */ - } - - emit32(b, val); /* The value to put in PR */ - emitALU(b, R0, R2, OP_ADD); /* R2 <- R0 + R2 (branch target) */ - emitMOVLSG(b, 21); /* sh2[PR] <- R0 */ - emitMOVLM(b, R2, R15); /* Push the next PC */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - b->cycles += 2; /* 2 Cycles */ -} - -static void generateBT(uint16_t inst, sh2rec_block_t *b) { - int disp = INSTRUCTION_CD(inst); - uint32_t val = b->pc + 2; - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLI(b, 4, R2); /* R2 <- sh2[PC] + 4 */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitMOVI(b, 0, R0); /* R0 <- 0 */ - emitBF(b, 2); /* Branch around the addition if needed */ - emitMOVI(b, disp, R0); /* R0 <- displacement */ - emitSHIFT(b, R0, OP_SHLL); /* R0 <- R0 << 1 */ - emitADDI(b, 2, R0); /* R0 <- R0 + 2 */ - emitRTS(b); /* Return to sender! */ - emitALU(b, R2, R0, OP_ADD); /* R0 <- R0 + R2 (delay slot) */ - if(((uint32_t)b->ptr) & 0x03) - emit16(b, 0); /* Padding if we need it */ - emit32(b, val); /* The next PC value (if not taken) */ - - b->cycles += 2; /* 2 Cycles (if not taken) */ - /* XXXX: Handle taken case cycle difference */ -} - -static void generateBTS(uint16_t inst, sh2rec_block_t *b) { - int disp = INSTRUCTION_CD(inst); - uint32_t val = b->pc + 4; - int n = (((uint32_t)b->ptr) & 0x03) ? 3 : 4; - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLI(b, n, R2); /* R2 <- sh2[PC] + 2 */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitMOVI(b, 0, R0); /* R0 <- 0 */ - emitBF(b, 1); /* Branch around the addition if needed */ - emitMOVI(b, disp, R0); /* R0 <- displacement */ - emitSHIFT(b, R0, OP_SHLL); /* R0 <- R0 << 1 */ - - if(((uint32_t)b->ptr) & 0x03) { - emitBRA(b, 3); /* Branch around the constant */ - emitALU(b, R2, R0, OP_ADD); /* R0 <- R0 + R2 (delay slot) */ - emit16(b, 0); /* Padding since we need it */ - } - else { - emitBRA(b, 2); /* Branch around the constant */ - emitALU(b, R2, R0, OP_ADD); /* R0 <- R0 + R2 (delay slot) */ - } - - emit32(b, val); /* The next PC value (if not taken) */ - emitMOVLM(b, R0, R15); /* Push the next PC */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - ++b->cycles; /* 1 Cycle (if not taken) */ - /* XXXX: Handle taken case cycle difference */ -} - -static void generateCLRMAC(uint16_t inst, sh2rec_block_t *b) { - emitCLRMAC(b); /* MACL/MACH <- 0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateCLRT(uint16_t inst, sh2rec_block_t *b) { - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVI(b, 0xFE, R1); /* R1 <- 0xFFFFFFFE */ - emitALU(b, R3, R0, OP_AND); /* Clear T bit */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateCMPEQ(uint16_t inst, sh2rec_block_t *b) { - generateCOMP(inst, b, OP_CMPEQ); - b->pc += 2; -} - -static void generateCMPGE(uint16_t inst, sh2rec_block_t *b) { - generateCOMP(inst, b, OP_CMPGE); - b->pc += 2; -} - -static void generateCMPGT(uint16_t inst, sh2rec_block_t *b) { - generateCOMP(inst, b, OP_CMPGT); - b->pc += 2; -} - -static void generateCMPHI(uint16_t inst, sh2rec_block_t *b) { - generateCOMP(inst, b, OP_CMPHI); - b->pc += 2; -} - -static void generateCMPHS(uint16_t inst, sh2rec_block_t *b) { - generateCOMP(inst, b, OP_CMPHS); - b->pc += 2; -} - -static void generateCMPSTR(uint16_t inst, sh2rec_block_t *b) { - generateCOMP(inst, b, OP_CMPSTR); - b->pc += 2; -} - -static void generateCMPPL(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitCMPPL(b, R2); /* cmp/pl R2 */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateCMPPZ(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitCMPPZ(b, R2); /* cmp/pz R2 */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateCMPIM(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOV(b, R0, R2); /* R2 <- R0 */ - emitMOVLL4(b, R8, 0, R0); /* R0 <- sh2[R0] */ - emitSHIFT(b, R2, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitCMPIM(b, imm); /* cmp/eq R0, #imm */ - emitSHIFT(b, R2, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOV(b, R2, R0); /* R0 <- R2 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateDIV0S(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVI(b, 0x03, R4); /* R4 <- 0x03 */ - emitANDI(b, 0xF2); /* Clear M, Q, and T */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitSHLL8(b, R4); /* R4 <<= 8 */ - emitSHIFT(b, R0, OP_SHLR); /* Chop off the T from the SH2 reg */ - emitDIV0S(b, R3, R2); /* div0s to grab the M, Q, T bits needed */ - emitSTC(b, R_SR, R5); /* Save SR to R5 */ - emitALU(b, R4, R5, OP_AND); /* Grab M, Q from the SR */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitALU(b, R5, R0, OP_OR); /* Save M, Q into the SH2 reg */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateDIV0U(uint16_t inst, sh2rec_block_t *b) { - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitANDI(b, 0xF2); /* Mask off M, Q, and T bits */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateDIV1(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVI(b, 0x03, R4); /* R4 <- 0x03 */ - emitSHLL8(b, R4); /* R4 <<= 8 */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitMOV(b, R4, R6); /* R6 <- R4 */ - emitALU(b, R0, R6, OP_AND); /* Grab SH2 M and Q bits */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T in place */ - emitSTC(b, R_SR, R5); /* Save SR to R5 */ - emitALU(b, R4, R7, OP_NOT); /* Set up the mask to clear M and Q */ - emitALU(b, R7, R5, OP_AND); /* Clear M, Q */ - emitALU(b, R6, R5, OP_OR); /* Put SH2's M and Q in place */ - emitLDC(b, R5, R_SR); /* Put the modified SR in place */ - emitDIV1(b, R3, R2); /* Do the division! */ - emitSTC(b, R_SR, R5); /* Save updated SR to R5 */ - emitALU(b, R4, R5, OP_AND); /* Grab M and Q from the SR */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - emitANDI(b, 0xF3); /* Clear M and Q from the SH2 reg */ - emitALU(b, R5, R0, OP_OR); /* Save M and Q into the SH2 reg */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateDMULS(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitALU(b, R3, R2, OP_DMULS); /* MACH/MACL <- (s32)R2 * (s32)R3 */ - - b->cycles += 2; /* 2 Cycles */ - b->pc += 2; -} - -static void generateDMULU(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitALU(b, R3, R2, OP_DMULU); /* MACH/MACL <- (u32)R2 * (u32)R3 */ - - b->cycles += 2; /* 2 Cycles */ - b->pc += 2; -} - -static void generateDT(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitDT(b, R2); /* R2 = R2 - 1 (T Bit = non-zero) */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateEXTSB(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_EXTSB); - b->pc += 2; -} - -static void generateEXTSW(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_EXTSW); - b->pc += 2; -} - -static void generateEXTUB(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_EXTUB); - b->pc += 2; -} - -static void generateEXTUW(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_EXTUW); - b->pc += 2; -} - -static void generateJMP(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regm, R0); /* Grab the next PC value */ - emitMOVLM(b, R0, R15); /* Push the next PC on the stack */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - b->cycles += 2; /* 2 Cycles */ -} - -static void generateJSR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - uint32_t val = b->pc + 4; - - emitMOVLI(b, 1, R0); /* R0 <- sh2[PC] + 4 */ - - if(((uint32_t)b->ptr) & 0x03) { - emitBRA(b, 3); /* Branch around the constant */ - emitMOVLL4(b, R8, regm, R2);/* R2 <- sh2[Rm] (delay slot) */ - emit16(b, 0); /* Padding since we need it */ - } - else { - emitBRA(b, 2); /* Branch around the constant */ - emitMOVLL4(b, R8, regm, R2);/* R2 <- sh2[Rm] (delay slot) */ - } - - emit32(b, val); /* The value to put in PR */ - emitMOVLM(b, R2, R15); /* Push the next PC */ - emitMOVLSG(b, 21); /* sh2[PR] <- R0 */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - b->cycles += 2; /* 2 Cycles */ -} - -static void generateLDCSR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVWI(b, 2, R2); /* R2 <- 0x03F3 */ - emitMOVLL4(b, R8, regm, R0); /* R0 <- sh2[Rm] */ - emitBRA(b, 1); /* Jump beyond the constant */ - emitALU(b, R2, R0, OP_AND); /* R0 <- R0 & R2 (delay slot) */ - emit16(b, 0x03F3); /* 0x03F3, grabbed by the emitMOVWI */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateLDCGBR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regm, R0); /* R0 <- sh2[Rm] */ - emitMOVLSG(b, 17); /* sh2[GBR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateLDCVBR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regm, R0); /* R0 <- sh2[Rm] */ - emitMOVLSG(b, 18); /* sh2[VBR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateLDCMSR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 4, R1); /* R1 <- 4 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVWI(b, 2, R2); /* R2 <- 0x03F3 */ - emitBRA(b, 1); /* Jump beyond the constant */ - emitALU(b, R2, R0, OP_AND); /* R0 <- R0 & R2 (delay slot) */ - emit16(b, 0x03F3); /* 0x03F3, grabbed by the emitMOVWI */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateLDCMGBR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 4, R1); /* R1 <- 4 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLSG(b, 17); /* sh2[GBR] <- R0 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateLDCMVBR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 4, R1); /* R1 <- 4 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLSG(b, 18); /* sh2[VBR] <- R0 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateLDSMACH(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regm, R0); /* R0 <- sh2[Rm] */ - emitLDS(b, R0, R_MACH); /* MACH <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateLDSMACL(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regm, R0); /* R0 <- sh2[Rm] */ - emitLDS(b, R0, R_MACL); /* MACL <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateLDSPR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regm, R0); /* R0 <- sh2[Rm] */ - emitMOVLSG(b, 21); /* sh2[PR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateLDSMMACH(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 4, R1); /* R1 <- 4 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitLDS(b, R0, R_MACH); /* MACH <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateLDSMMACL(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 4, R1); /* R1 <- 4 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitLDS(b, R0, R_MACL); /* MACL <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateLDSMPR(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_B(inst); - - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 4, R1); /* R1 <- 4 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLSG(b, 21); /* sh2[PR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMACL(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitADDI(b, 4, R4); /* R4 <- R4 + 4 */ - emitMOVLS4(b, R4, regm, R8); /* sh2[Rm] <- R4 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitADDI(b, -4, R4); /* R4 <- R4 - 4 (delay slot) */ - emitMOVLM(b, R0, R15); /* Push R0 onto the stack */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitADDI(b, 4, R4); /* R4 <- R4 + 4 */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitADDI(b, -4, R4); /* R4 <- R4 - 4 (delay slot) */ - emitSTC(b, R_SR, R2); /* R2 <- SR */ - emitMOVI(b, 0xFD, R3); /* R3 <- 0xFFFFFFFD */ - emitMOVLM(b, R0, R15); /* Push R0 onto the stack */ - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitALU(b, R2, R3, OP_AND); /* R3 <- R2 & R3 (Mask out S Bit) */ - emitANDI(b, 0x02); /* R0 <- R0 & 0x02 (S Bit) */ - emitALU(b, R0, R3, OP_OR); /* R3 <- R0 | R3 (Put SH2 S Bit in) */ - emitLDC(b, R3, R_SR); /* SR <- R3 */ - emitMACL(b, R15, R15); /* Perform the MAC.L */ - emitLDC(b, R2, R_SR); /* SR <- R2 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateMACW(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVLL4(b, R9, 1, R0); /* R0 <- MappedMemoryReadWord */ - emitADDI(b, 2, R4); /* R4 <- R4 + 2 */ - emitMOVLS4(b, R4, regm, R8); /* sh2[Rm] <- R4 */ - emitJSR(b, R0); /* Call MappedMemoryReadWord */ - emitADDI(b, -2, R4); /* R4 <- R4 - 2 (delay slot) */ - emitMOVWM(b, R0, R15); /* Push R0 onto the stack */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitMOVLL4(b, R9, 1, R0); /* R0 <- MappedMemoryReadWord */ - emitADDI(b, 2, R4); /* R4 <- R4 + 2 */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitJSR(b, R0); /* Call MappedMemoryReadWord */ - emitADDI(b, -2, R4); /* R4 <- R4 - 2 (delay slot) */ - emitMOVWM(b, R0, R15); /* Push R0 onto the stack */ - emitSTC(b, R_SR, R2); /* R2 <- SR */ - emitMOVI(b, 0xFD, R3); /* R3 <- 0xFFFFFFFD */ - emitMOVLM(b, R0, R15); /* Push R0 onto the stack */ - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitALU(b, R2, R3, OP_AND); /* R3 <- R2 & R3 (Mask out S Bit) */ - emitANDI(b, 0x02); /* R0 <- R0 & 0x02 (S Bit) */ - emitALU(b, R0, R3, OP_OR); /* R3 <- R0 | R3 (Put SH2 S Bit in) */ - emitLDC(b, R3, R_SR); /* SR <- R3 */ - emitMACW(b, R15, R15); /* Perform the MAC.W */ - emitLDC(b, R2, R_SR); /* SR <- R2 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateMOV(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regm, R2); /* R2 <- sh2[Rm] */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBS(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R9, 3, R0); /* R0 <- MappedMemoryWriteByte */ - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryWriteByte */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWS(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R9, 4, R0); /* R0 <- MappedMemoryWriteWord */ - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryWriteWord */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLS(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R9, 5, R0); /* R0 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBL(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R9, 0, R0); /* R0 <- MappedMemoryReadByte */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryReadByte */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitALU(b, R0, R0, OP_EXTSB); /* Sign extend read byte */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read byte */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWL(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R9, 1, R0); /* R0 <- MappedMemoryReadWord */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryReadWord */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitALU(b, R0, R0, OP_EXTSW); /* Sign extend read word */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read word */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLL(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read long */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBM(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitMOVLL4(b, R9, 3, R0); /* R0 <- MappedMemoryWriteByte */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -1, R4); /* R4 -= 1 */ - emitJSR(b, R0); /* Call MappedMemoryWriteByte */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWM(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitMOVLL4(b, R9, 4, R0); /* R0 <- MappedMemoryWriteWord */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -2, R4); /* R4 -= 2 */ - emitJSR(b, R0); /* Call MappedMemoryWriteWord */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLM(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitMOVLL4(b, R9, 5, R0); /* R0 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -4, R4); /* R4 -= 4 */ - emitJSR(b, R0); /* Call MappedMemoryWriteLong */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBP(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 0, R0); /* R0 <- MappedMemoryReadByte */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 1, R1); /* R1 <- 1 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadByte */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitALU(b, R0, R0, OP_EXTSB); /* Sign extend read byte */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read byte */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWP(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 1, R0); /* R0 <- MappedMemoryReadWord */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 2, R1); /* R1 <- 2 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadWord */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitALU(b, R0, R0, OP_EXTSW); /* Sign extend read word */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read word */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLP(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVI(b, 4, R1); /* R1 <- 4 */ - emitALU(b, R4, R1, OP_ADD); /* R1 <- R4 + R1 */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLS4(b, R1, regm, R8); /* sh2[Rm] <- R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read long */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBS0(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitMOVLL4(b, R8, 0, R1); /* R1 <- sh2[R0] */ - emitMOVLL4(b, R9, 3, R0); /* R0 <- MappedMemoryWriteByte */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitJSR(b, R0); /* Call MappedMemoryWriteByte */ - emitALU(b, R1, R4, OP_ADD); /* R4 <- R4 + R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWS0(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitMOVLL4(b, R8, 0, R1); /* R1 <- sh2[R0] */ - emitMOVLL4(b, R9, 4, R0); /* R0 <- MappedMemoryWriteWord */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitJSR(b, R0); /* Call MappedMemoryWriteWord */ - emitALU(b, R1, R4, OP_ADD); /* R4 <- R4 + R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLS0(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitMOVLL4(b, R8, 0, R1); /* R1 <- sh2[R0] */ - emitMOVLL4(b, R9, 5, R0); /* R0 <- MappedMemoryWriteLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitJSR(b, R0); /* Call MappedMemoryWriteLong */ - emitALU(b, R1, R4, OP_ADD); /* R4 <- R4 + R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBL0(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 0, R0); /* R0 <- MappedMemoryReadByte */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVLL4(b, R8, 0, R1); /* R1 <- sh2[R0] */ - emitJSR(b, R0); /* Call MappedMemoryReadByte */ - emitALU(b, R1, R4, OP_ADD); /* R4 <- R4 + R1 */ - emitALU(b, R0, R0, OP_EXTSB); /* Sign extend read byte */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read byte */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWL0(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 1, R0); /* R0 <- MappedMemoryReadWord */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVLL4(b, R8, 0, R1); /* R1 <- sh2[R0] */ - emitJSR(b, R0); /* Call MappedMemoryReadWord */ - emitALU(b, R1, R4, OP_ADD); /* R4 <- R4 + R1 */ - emitALU(b, R0, R0, OP_EXTSW); /* Sign extend read word */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read word */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLL0(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVLL4(b, R8, 0, R1); /* R1 <- sh2[R0] */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitALU(b, R1, R4, OP_ADD); /* R4 <- R4 + R1 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read long */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVI(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int imm = INSTRUCTION_CD(inst); - - emitMOVI(b, imm, R2); /* R2 <- #imm */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWI(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int imm = INSTRUCTION_CD(inst); - uint32_t addr = b->pc + 4 + (imm << 1); - - if(((uint32_t)b->ptr) & 0x03) { - emitMOVLI(b, 1, R4); /* R4 <- calculated effective addr */ - emitBRA(b, 2); /* Jump beyond the constant */ - emitMOVLL4(b, R9, 1, R0); /* R0 <- MappedMemoryReadWord */ - emit32(b, addr); /* MOV.W effective address */ - } - else { - emitMOVLI(b, 1, R4); /* R4 <- calculated effective addr */ - emitBRA(b, 3); /* Jump beyond the constant */ - emitMOVLL4(b, R9, 1, R0); /* R0 <- MappedMemoryReadWord */ - emit16(b, 0); /* Padding, for alignment issues */ - emit32(b, addr); /* MOV.W effective address */ - } - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryReadWord */ - emitNOP(b); /* XXXX: Nothing to put here */ - emitALU(b, R0, R0, OP_EXTSW); /* Sign extend read word */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read word */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLI(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int imm = INSTRUCTION_CD(inst); - uint32_t addr = ((b->pc + 4) & 0xFFFFFFFC) + (imm << 2); - - if(((uint32_t)b->ptr) & 0x03) { - emitMOVLI(b, 1, R4); /* R4 <- calculated effective addr */ - emitBRA(b, 2); /* Jump beyond the constant */ - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emit32(b, addr); /* MOV.L effective address */ - } - else { - emitMOVLI(b, 1, R4); /* R4 <- calculated effective addr */ - emitBRA(b, 3); /* Jump beyond the constant */ - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emit16(b, 0); /* Padding, for alignment issues */ - emit32(b, addr); /* MOV.L effective address */ - } - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitNOP(b); /* XXXX: Nothing to put here */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read long */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBLG(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 0, R1); /* R1 <- MappedMemoryReadByte */ - emitMOVI(b, imm, R4); /* R4 <- Displacement */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitALU(b, R4, R4, OP_EXTUB); /* Zero extend displacement */ - emitJSR(b, R1); /* Call MappedMemoryReadByte */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitALU(b, R0, R0, OP_EXTSB); /* Sign extend read byte */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, 0, R8); /* sh2[R0] <- read byte */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWLG(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVI(b, imm, R4); /* R4 <- Displacement */ - emitMOVLL4(b, R9, 1, R1); /* R1 <- MappedMemoryReadWord */ - emitALU(b, R4, R4, OP_EXTUB); /* Zero extend displacement */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitSHIFT(b, R4, OP_SHLL); /* Double displacement */ - emitJSR(b, R1); /* Call MappedMemoryReadWord */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitALU(b, R0, R0, OP_EXTSW); /* Sign extend read word */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, 0, R8); /* sh2[R0] <- read word */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLLG(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVI(b, imm, R4); /* R4 <- Displacement */ - emitMOVLL4(b, R9, 2, R1); /* R1 <- MappedMemoryReadLong */ - emitALU(b, R4, R4, OP_EXTUB); /* Zero extend displacement */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitSHLL2(b, R4); /* Quadruple displacement */ - emitJSR(b, R1); /* Call MappedMemoryReadLong */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, 0, R8); /* sh2[R0] <- read long */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBSG(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitMOVLL4(b, R8, 0, R5); /* R5 <- sh2[R0] */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 3, R1); /* R1 <- MappedMemoryWriteByte */ - emitMOVI(b, imm, R4); /* R4 <- Displacement */ - emitALU(b, R4, R4, OP_EXTUB); /* Zero extend Displacement */ - emitJSR(b, R1); /* Call MappedMemoryWriteByte */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWSG(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitMOVLL4(b, R8, 0, R5); /* R5 <- sh2[R0] */ - emitMOVI(b, imm, R4); /* R4 <- Displacement */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitALU(b, R4, R4, OP_EXTUB); /* Zero extend Displacement */ - emitMOVLL4(b, R9, 4, R1); /* R1 <- MappedMemoryWriteWord */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitSHIFT(b, R4, OP_SHLL); /* Double displacement */ - emitJSR(b, R1); /* Call MappedMemoryWriteWord */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLSG(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitMOVLL4(b, R8, 0, R5); /* R5 <- sh2[R0] */ - emitMOVI(b, imm, R4); /* R4 <- Displacement */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitALU(b, R4, R4, OP_EXTUB); /* Zero extend Displacement */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MappedMemoryWriteLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitSHLL2(b, R4); /* Quadruple displacement */ - emitJSR(b, R1); /* Call MappedMemoryWriteLong */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBS4(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_C(inst); - int imm = INSTRUCTION_D(inst); - - emitMOVLL4(b, R8, 0, R5); /* R5 <- sh2[R0] */ - emitMOVLL4(b, R9, 3, R1); /* R1 <- MappedMemoryWriteByte */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R1); /* Call MappedMemoryWriteByte */ - emitADDI(b, imm, R4); /* R4 <- R4 + displacement */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWS4(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_C(inst); - int imm = INSTRUCTION_D(inst) << 1; - - emitMOVLL4(b, R8, 0, R5); /* R5 <- sh2[R0] */ - emitMOVLL4(b, R9, 4, R1); /* R1 <- MappedMemoryWriteWord */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R1); /* Call MappedMemoryWriteWord */ - emitADDI(b, imm, R4); /* R4 <- R4 + displacement */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLS4(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - int imm = INSTRUCTION_D(inst) << 2; - - emitMOVLL4(b, R8, regm, R5); /* R5 <- sh2[Rm] */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R1); /* Call MappedMemoryWriteLong */ - emitADDI(b, imm, R4); /* R4 <- R4 + displacement */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVBL4(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_C(inst); - int imm = INSTRUCTION_D(inst); - - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVLL4(b, R9, 0, R1); /* R1 <- MappedMemoryReadByte */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R1); /* Call MappedMemoryReadByte */ - emitADDI(b, imm, R4); /* R4 <- R4 + displacement */ - emitALU(b, R0, R0, OP_EXTSB); /* Sign extend read byte */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, 0, R8); /* sh2[R0] <- read byte */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVWL4(uint16_t inst, sh2rec_block_t *b) { - int regm = INSTRUCTION_C(inst); - int imm = INSTRUCTION_D(inst) << 1; - - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVLL4(b, R9, 1, R1); /* R1 <- MappedMemoryReadWord */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R1); /* Call MappedMemoryReadWord */ - emitADDI(b, imm, R4); /* R4 <- R4 + displacement */ - emitALU(b, R0, R0, OP_EXTSW); /* Sign extend read word */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, 0, R8); /* sh2[R0] <- read word */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVLL4(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - int imm = INSTRUCTION_D(inst) << 2; - - emitMOVLL4(b, R8, regm, R4); /* R4 <- sh2[Rm] */ - emitMOVLL4(b, R9, 2, R1); /* R1 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R1); /* Call MappedMemoryReadLong */ - emitADDI(b, imm, R4); /* R4 <- R4 + displacement */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- read long */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVA(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - uint32_t addr = ((b->pc + 4) & 0xFFFFFFFC) + (imm << 2); - - if(((uint32_t)b->ptr) & 0x03) { - emitMOVLI(b, 1, R2); /* R2 <- calculated effective addr */ - emitBRA(b, 2); /* Jump beyond the constant */ - emitMOVLS4(b, R2, 0, R8); /* sh2[R0] <- R2 */ - emit32(b, addr); /* MOVA effective address */ - } - else { - emitMOVLI(b, 1, R2); /* R2 <- calculated effective addr */ - emitBRA(b, 3); /* Jump beyond the constant */ - emitMOVLS4(b, R2, 0, R8); /* sh2[R0] <- R2 */ - emit16(b, 0); /* Padding, for alignment issues */ - emit32(b, addr); /* MOVA effective address */ - } - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMOVT(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitANDI(b, 0x01); /* Grab T Bit */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- T Bit */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMULL(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitALU(b, R3, R2, OP_MULL); /* MACL <- R2 * R3 */ - - b->cycles += 2; /* 2 Cycles */ - b->pc += 2; -} - -static void generateMULS(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitALU(b, R3, R2, OP_MULS); /* MACL <- (s16)R2 * (s16)R3 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateMULU(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitALU(b, R3, R2, OP_MULU); /* MACL <- (u16)R2 * (u16)R3 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateNEG(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitALU(b, R3, R2, OP_NEG); /* R2 <- 0 - R3 */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateNEGC(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitALU(b, R3, R2, OP_NEGC); /* R2 = 0 - R3 - T (borrow to T) */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateNOP(uint16_t inst, sh2rec_block_t *b) { - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateNOT(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_NOT); - b->pc += 2; -} - -static void generateOR(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_OR); - b->pc += 2; -} - -static void generateORI(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitMOVLL4(b, R8, 0, R0); /* R0 <- sh2[R0] */ - emitORI(b, imm); /* R0 <- R0 | #imm */ - emitMOVLS4(b, R0, 0, R8); /* sh2[R0] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateORM(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitMOVLL4(b, R8, 0, R4); /* R4 <- sh2[R0] */ - emitMOVLL4(b, R9, 0, R1); /* R1 <- MappedMemoryReadByte */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitJSR(b, R1); /* Call MappedMemoryReadByte */ - emitMOVLM(b, R4, R15); /* Push R4 on the stack (delay slot) */ - emitMOVLL4(b, R9, 3, R1); /* R1 <- MappedMemoryWriteByte */ - emitORI(b, imm); /* R0 <- R0 | #imm */ - emitMOVLP(b, R15, R4); /* Pop R4 off the stack */ - emitJSR(b, R1); /* Call MappedMemoryWriteByte */ - emitMOV(b, R0, R5); /* R5 <- R0 (delay slot) */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateROTCL(uint16_t inst, sh2rec_block_t *b) { - generateSHIFT(inst, b, OP_ROTCL); - b->pc += 2; -} - -static void generateROTCR(uint16_t inst, sh2rec_block_t *b) { - generateSHIFT(inst, b, OP_ROTCR); - b->pc += 2; -} - -static void generateROTL(uint16_t inst, sh2rec_block_t *b) { - generateSHIFT(inst, b, OP_ROTL); - b->pc += 2; -} - -static void generateROTR(uint16_t inst, sh2rec_block_t *b) { - generateSHIFT(inst, b, OP_ROTR); - b->pc += 2; -} - -static void generateRTE(uint16_t inst, sh2rec_block_t *b) { - emitMOVLL4(b, R9, 2, R0); /* R0 <- MappedMemoryReadLong */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryReadLong */ - emitMOVLL4(b, R8, 15, R4); /* R4 <- sh2[R15] (delay slot) */ - emitMOVLL4(b, R9, 2, R1); /* R1 <- MappedMemoryReadLong */ - emitMOVLL4(b, R8, 15, R4); /* R4 <- sh2[R15] */ - emitMOVI(b, 4, R2); /* R2 <- 4 */ - emitALU(b, R2, R4, OP_ADD); /* R4 <- R4 + R2 */ - emitMOVLM(b, R0, R15); /* Push the next PC */ - emitALU(b, R4, R2, OP_ADD); /* R2 <- R4 + R2 */ - emitJSR(b, R1); /* Call MappedMemoryReadLong */ - emitMOVLS4(b, R2, 15, R8); /* sh2[R15] <- R2 (delay slot) */ - emitMOVWI(b, 1, R1); /* R1 <- 0x000003F3 */ - emitBRA(b, 1); /* Branch around the constant */ - emitALU(b, R1, R0, OP_AND); /* R0 <- R0 & R1 */ - emit16(b, 0x03F3); /* Mask for SR register */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - b->cycles += 4; /* 4 Cycles */ -} - -static void generateRTS(uint16_t inst, sh2rec_block_t *b) { - emitMOVLLG(b, 21); /* R0 <- sh2[PR] */ - emitMOVLM(b, R0, R15); /* Push the PR on the stack */ - - /* Deal with the delay slot */ - b->pc += 2; - sh2rec_rec_inst(b, 1); - - emitRTS(b); /* Return to sender! */ - emitMOVLP(b, R15, R0); /* Pop the next PC (delay slot) */ - - b->cycles += 2; /* 2 Cycles */ -} - -static void generateSETT(uint16_t inst, sh2rec_block_t *b) { - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitORI(b, 0x01); /* Set T Bit */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSHAL(uint16_t inst, sh2rec_block_t *b) { - generateSHIFT(inst, b, OP_SHAL); - b->pc += 2; -} - -static void generateSHAR(uint16_t inst, sh2rec_block_t *b) { - generateSHIFT(inst, b, OP_SHAR); - b->pc += 2; -} - -static void generateSHLL(uint16_t inst, sh2rec_block_t *b) { - generateSHIFT(inst, b, OP_SHLL); - b->pc += 2; -} - -static void generateSHLL2(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHLL2(b, R2); /* R2 <- R2 << 2 */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSHLL8(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHLL8(b, R2); /* R2 <- R2 << 8 */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSHLL16(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHLL16(b, R2); /* R2 <- R2 << 16 */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSHLR(uint16_t inst, sh2rec_block_t *b) { - generateSHIFT(inst, b, OP_SHLR); - b->pc += 2; -} - -static void generateSHLR2(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHLR2(b, R2); /* R2 <- R2 >> 2 */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSHLR8(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHLR8(b, R2); /* R2 <- R2 >> 8 */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSHLR16(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitSHLR16(b, R2); /* R2 <- R2 >> 16 */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSLEEP(uint16_t inst, sh2rec_block_t *b) { - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateSTCSR(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSTCGBR(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSTCVBR(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 18); /* R0 <- sh2[VBR] */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSTCMSR(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -4, R4); /* R4 -= 4 */ - emitMOV(b, R0, R5); /* R5 <- R0 */ - emitJSR(b, R1); /* Call MappedMemoryWriteLong */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 2; /* 2 Cycles */ - b->pc += 2; -} - -static void generateSTCMGBR(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -4, R4); /* R4 -= 4 */ - emitMOV(b, R0, R5); /* R5 <- R0 */ - emitJSR(b, R1); /* Call MappedMemoryWriteLong */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 2; /* 2 Cycles */ - b->pc += 2; -} - -static void generateSTCMVBR(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 18); /* R0 <- sh2[VBR] */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -4, R4); /* R4 -= 4 */ - emitMOV(b, R0, R5); /* R5 <- R0 */ - emitJSR(b, R1); /* Call MappedMemoryWriteLong */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 2; /* 2 Cycles */ - b->pc += 2; -} - -static void generateSTSMACH(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitSTS(b, R_MACH, R0); /* R0 <- MACH */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSTSMACL(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitSTS(b, R_MACL, R0); /* R0 <- MACL */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSTSPR(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 21); /* R0 <- sh2[PR] */ - emitMOVLS4(b, R0, regn, R8); /* sh2[Rn] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSTSMMACH(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitSTS(b, R_MACH, R5); /* R5 <- MACH */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -4, R4); /* R4 -= 4 */ - emitJSR(b, R1); /* Call MappedMemoryWriteLong */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSTSMMACL(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitSTS(b, R_MACL, R5); /* R5 <- MACL */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -4, R4); /* R4 -= 4 */ - emitJSR(b, R1); /* Call MappedMemoryWriteLong */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSTSMPR(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLLG(b, 21); /* R0 <- sh2[PR] */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MappedMemoryWriteLong */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitADDI(b, -4, R4); /* R4 -= 4 */ - emitMOV(b, R0, R5); /* R5 <- R0 */ - emitJSR(b, R1); /* Call MappedMemoryWriteLong */ - emitMOVLS4(b, R4, regn, R8); /* sh2[Rn] <- R4 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSUB(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_SUB); - b->pc += 2; -} - -static void generateSUBC(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitALU(b, R3, R2, OP_SUBC); /* R2 = R2 - R3 - T (borrow to T) */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLS4(b, R2, regn, R8); /* sh2[Rn] <- R2 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSUBV(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - int regm = INSTRUCTION_C(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVLL4(b, R8, regn, R2); /* R2 <- sh2[Rn] */ - emitMOVLL4(b, R8, regm, R3); /* R3 <- sh2[Rm] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitSUBV(b, R3, R2); /* R2 = R2 - R3 (underflow to T Bit) */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateSWAPB(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_SWAPB); - b->pc += 2; -} - -static void generateSWAPW(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_SWAPW); - b->pc += 2; -} - -static void generateTAS(uint16_t inst, sh2rec_block_t *b) { - int regn = INSTRUCTION_B(inst); - - emitMOVLL4(b, R9, 0, R0); /* R0 <- MappedMemoryReadByte */ - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitJSR(b, R0); /* Call MappedMemoryReadByte */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] (delay slot) */ - emitMOV(b, R0, R5); /* R5 <- R0 (byte read) */ - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOVI(b, 0x80, R2); /* R2 <- 0x80 */ - emitMOVLL4(b, R8, regn, R4); /* R4 <- sh2[Rn] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitALU(b, R5, R5, OP_TST); /* T <- 1 if byte == 0, 0 otherwise */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLL4(b, R9, 3, R1); /* R1 <- MappedMemoryWriteByte */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - emitJSR(b, R1); /* Call MappedMemoryWriteByte */ - emitALU(b, R2, R5, OP_OR); /* R5 <- R5 | 0x80 (delay slot) */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 4; /* 4 Cycles */ - b->pc += 2; -} - -static void generateTRAPA(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - int disp = (((uint32_t)(b->ptr)) & 0x03) ? 5 : 6; - uint32_t val = b->pc + 2; - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R8, 15, R4); /* R4 <- sh2[R15] */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MemoryMappedWriteLong */ - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitADDI(b, -4, R4); /* R4 <- R4 - 4 */ - emitJSR(b, R1); /* Call MemoryMappedWriteLong */ - emitMOV(b, R0, R5); /* R5 <- R0 (delay slot) */ - emitMOVLL4(b, R8, 15, R4); /* R4 <- sh2[R15] */ - emitMOVLL4(b, R9, 5, R1); /* R1 <- MemoryMappedWriteLong */ - emitADDI(b, -8, R4); /* R4 <- R4 - 8 */ - emitMOVLI(b, disp, R5); /* R5 <- Updated PC value (to be stacked) */ - emitJSR(b, R1); /* Call MemoryMappedWriteLong */ - emitMOVLS4(b, R4, 15, R8); /* sh2[R15] <- R4 (delay slot) */ - emitMOVI(b, imm, R4); /* R4 <- immediate data */ - emitALU(b, R4, R4, OP_EXTUB); /* Zero-extend R4 */ - emitMOVLL4(b, R9, 2, R1); /* R1 <- MemoryMappedReadLong */ - emitMOVLLG(b, 18); /* R0 <- sh2[VBR] */ - emitSHLL2(b, R4); /* R4 <- R4 << 2 */ - emitJSR(b, R1); /* Call MemoryMappedReadLong */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 (delay slot) */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - emitRTS(b); /* Return to sender! */ - emitNOP(b); /* XXXX: Nothing here */ - if(((uint32_t)b->ptr) & 0x03) - emit16(b, 0); /* Padding for the alignment */ - emit32(b, val); /* The PC value to be loaded by the MOVLI */ - - b->cycles += 8; /* 8 Cycles */ -} - -static void generateTST(uint16_t inst, sh2rec_block_t *b) { - generateCOMP(inst, b, OP_TST); - b->pc += 2; -} - -static void generateTSTI(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitMOV(b, R0, R2); /* R2 <- R0 */ - emitMOVLL4(b, R8, 0, R0); /* R0 <- sh2[R0] */ - emitSHIFT(b, R2, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitTSTI(b, imm); /* tst #imm, r0 */ - emitSHIFT(b, R2, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOV(b, R2, R0); /* R0 <- R2 */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateTSTM(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLL4(b, R9, 0, R1); /* R1 <- MappedMemoryReadByte */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitMOVLL4(b, R8, 0, R4); /* R4 <- sh2[R0] */ - emitJSR(b, R1); /* Call MappedMemoryReadByte */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 (delay slot) */ - emitMOV(b, R0, R5); /* R5 <- R0 (byte read) */ - emitMOVI(b, imm, R3); /* R3 <- immediate value */ - emitMOVLLG(b, 16); /* R0 <- sh2[SR] */ - emitSHIFT(b, R0, OP_ROTCR); /* Rotate SH2's T Bit in place */ - emitALU(b, R3, R5, OP_TST); /* T <- 1 if (R5 & imm) == 0, 0 otherwise */ - emitSHIFT(b, R0, OP_ROTCL); /* Rotate T back to SH2 reg */ - emitMOVLSG(b, 16); /* sh2[SR] <- R0 */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateXOR(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_XOR); - b->pc += 2; -} - -static void generateXORI(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitMOVLL4(b, R8, 0, R0); /* R0 <- sh2[R0] */ - emitXORI(b, imm); /* R0 <- R0 ^ #imm */ - emitMOVLS4(b, R0, 0, R8); /* sh2[R0] <- R0 */ - - ++b->cycles; /* 1 Cycle */ - b->pc += 2; -} - -static void generateXORM(uint16_t inst, sh2rec_block_t *b) { - int imm = INSTRUCTION_CD(inst); - - emitSTS(b, R_PR, R10); /* R10 <- PR */ - emitMOVLLG(b, 17); /* R0 <- sh2[GBR] */ - emitMOVLL4(b, R8, 0, R4); /* R4 <- sh2[R0] */ - emitMOVLL4(b, R9, 0, R1); /* R1 <- MappedMemoryReadByte */ - emitALU(b, R0, R4, OP_ADD); /* R4 <- R4 + R0 */ - emitJSR(b, R1); /* Call MappedMemoryReadByte */ - emitMOVLM(b, R4, R15); /* Push R4 on the stack (delay slot) */ - emitMOVLL4(b, R9, 3, R1); /* R1 <- MappedMemoryWriteByte */ - emitXORI(b, imm); /* R0 <- R0 ^ #imm */ - emitMOVLP(b, R15, R4); /* Pop R4 off the stack */ - emitJSR(b, R1); /* Call MappedMemoryWriteByte */ - emitMOV(b, R0, R5); /* R5 <- R0 (delay slot) */ - emitLDS(b, R10, R_PR); /* PR <- R10 */ - - b->cycles += 3; /* 3 Cycles */ - b->pc += 2; -} - -static void generateXTRCT(uint16_t inst, sh2rec_block_t *b) { - generateALUOP(inst, b, OP_XTRCT); - b->pc += 2; -} - -int sh2rec_rec_inst(sh2rec_block_t *b, int isdelay) { - uint16_t inst = MappedMemoryReadWord(b->pc); - int done = 0; - - switch(INSTRUCTION_A(inst)) { - case 0: - switch(INSTRUCTION_D(inst)) { - case 2: - switch(INSTRUCTION_C(inst)) { - case 0: generateSTCSR(inst, b); break; - case 1: generateSTCGBR(inst, b); break; - case 2: generateSTCVBR(inst, b); break; - default: return -1; - } - break; - - case 3: - switch(INSTRUCTION_C(inst)) { - case 0: generateBSRF(inst, b); done = 1; break; - case 2: generateBRAF(inst, b); done = 1; break; - default: return -1; - } - break; - - case 4: generateMOVBS0(inst, b); break; - case 5: generateMOVWS0(inst, b); break; - case 6: generateMOVLS0(inst, b); break; - case 7: generateMULL(inst, b); break; - case 8: - switch(INSTRUCTION_C(inst)) { - case 0: generateCLRT(inst, b); break; - case 1: generateSETT(inst, b); break; - case 2: generateCLRMAC(inst, b); break; - default: return -1; - } - break; - - case 9: - switch(INSTRUCTION_C(inst)) { - case 0: generateNOP(inst, b); break; - case 1: generateDIV0U(inst, b); break; - case 2: generateMOVT(inst, b); break; - default: return -1; - } - break; - - case 10: - switch(INSTRUCTION_C(inst)) { - case 0: generateSTSMACH(inst, b); break; - case 1: generateSTSMACL(inst, b); break; - case 2: generateSTSPR(inst, b); break; - default: return -1; - } - break; - - case 11: - switch(INSTRUCTION_C(inst)) { - case 0: generateRTS(inst, b); done = 1; break; - case 1: generateSLEEP(inst, b); break; - case 2: generateRTE(inst, b); done = 1; break; - default: return -1; - } - break; - - case 12: generateMOVBL0(inst, b); break; - case 13: generateMOVWL0(inst, b); break; - case 14: generateMOVLL0(inst, b); break; - case 15: generateMACL(inst, b); break; - default: return -1; - } - break; - - case 1: generateMOVLS4(inst, b); break; - case 2: - switch(INSTRUCTION_D(inst)) { - case 0: generateMOVBS(inst, b); break; - case 1: generateMOVWS(inst, b); break; - case 2: generateMOVLS(inst, b); break; - case 4: generateMOVBM(inst, b); break; - case 5: generateMOVWM(inst, b); break; - case 6: generateMOVLM(inst, b); break; - case 7: generateDIV0S(inst, b); break; - case 8: generateTST(inst, b); break; - case 9: generateAND(inst, b); break; - case 10: generateXOR(inst, b); break; - case 11: generateOR(inst, b); break; - case 12: generateCMPSTR(inst, b); break; - case 13: generateXTRCT(inst, b); break; - case 14: generateMULU(inst, b); break; - case 15: generateMULS(inst, b); break; - default: return -1; - } - break; - - case 3: - switch(INSTRUCTION_D(inst)) { - case 0: generateCMPEQ(inst, b); break; - case 2: generateCMPHS(inst, b); break; - case 3: generateCMPGE(inst, b); break; - case 4: generateDIV1(inst, b); break; - case 5: generateDMULU(inst, b); break; - case 6: generateCMPHI(inst, b); break; - case 7: generateCMPGT(inst, b); break; - case 8: generateSUB(inst, b); break; - case 10: generateSUBC(inst, b); break; - case 11: generateSUBV(inst, b); break; - case 12: generateADD(inst, b); break; - case 13: generateDMULS(inst, b); break; - case 14: generateADDC(inst, b); break; - case 15: generateADDV(inst, b); break; - default: return -1; - } - break; - - case 4: - switch(INSTRUCTION_D(inst)) { - case 0: - switch(INSTRUCTION_C(inst)) { - case 0: generateSHLL(inst, b); break; - case 1: generateDT(inst, b); break; - case 2: generateSHAL(inst, b); break; - default: return -1; - } - break; - - case 1: - switch(INSTRUCTION_C(inst)) { - case 0: generateSHLR(inst, b); break; - case 1: generateCMPPZ(inst, b); break; - case 2: generateSHAR(inst, b); break; - default: return -1; - } - break; - - case 2: - switch(INSTRUCTION_C(inst)) { - case 0: generateSTSMMACH(inst, b); break; - case 1: generateSTSMMACL(inst, b); break; - case 2: generateSTSMPR(inst, b); break; - default: return -1; - } - break; - - case 3: - switch(INSTRUCTION_C(inst)) { - case 0: generateSTCMSR(inst, b); break; - case 1: generateSTCMGBR(inst, b); break; - case 2: generateSTCMVBR(inst, b); break; - default: return -1; - } - break; - - case 4: - switch(INSTRUCTION_C(inst)) { - case 0: generateROTL(inst, b); break; - case 2: generateROTCL(inst, b); break; - default: return -1; - } - break; - - case 5: - switch(INSTRUCTION_C(inst)) { - case 0: generateROTR(inst, b); break; - case 1: generateCMPPL(inst, b); break; - case 2: generateROTCR(inst, b); break; - default: return -1; - } - break; - - case 6: - switch(INSTRUCTION_C(inst)) { - case 0: generateLDSMMACH(inst, b); break; - case 1: generateLDSMMACL(inst, b); break; - case 2: generateLDSMPR(inst, b); break; - default: return -1; - } - break; - - case 7: - switch(INSTRUCTION_C(inst)) { - case 0: generateLDCMSR(inst, b); break; - case 1: generateLDCMGBR(inst, b); break; - case 2: generateLDCMVBR(inst, b); break; - default: return -1; - } - break; - - case 8: - switch(INSTRUCTION_C(inst)) { - case 0: generateSHLL2(inst, b); break; - case 1: generateSHLL8(inst, b); break; - case 2: generateSHLL16(inst, b); break; - default: return -1; - } - break; - - case 9: - switch(INSTRUCTION_C(inst)) { - case 0: generateSHLR2(inst, b); break; - case 1: generateSHLR8(inst, b); break; - case 2: generateSHLR16(inst, b); break; - default: return -1; - } - break; - - case 10: - switch(INSTRUCTION_C(inst)) { - case 0: generateLDSMACH(inst, b); break; - case 1: generateLDSMACL(inst, b); break; - case 2: generateLDSPR(inst, b); break; - default: return -1; - } - break; - - case 11: - switch(INSTRUCTION_C(inst)) { - case 0: generateJSR(inst, b); done = 1; break; - case 1: generateTAS(inst, b); break; - case 2: generateJMP(inst, b); done = 1; break; - default: return -1; - } - break; - - case 14: - switch(INSTRUCTION_C(inst)) { - case 0: generateLDCSR(inst, b); break; - case 1: generateLDCGBR(inst, b); break; - case 2: generateLDCVBR(inst, b); break; - default: return -1; - } - break; - - case 15: generateMACW(inst, b); break; - default: return -1; - } - break; - - case 5: generateMOVLL4(inst, b); break; - - case 6: - switch(INSTRUCTION_D(inst)) { - case 0: generateMOVBL(inst, b); break; - case 1: generateMOVWL(inst, b); break; - case 2: generateMOVLL(inst, b); break; - case 3: generateMOV(inst, b); break; - case 4: generateMOVBP(inst, b); break; - case 5: generateMOVWP(inst, b); break; - case 6: generateMOVLP(inst, b); break; - case 7: generateNOT(inst, b); break; - case 8: generateSWAPB(inst, b); break; - case 9: generateSWAPW(inst, b); break; - case 10: generateNEGC(inst, b); break; - case 11: generateNEG(inst, b); break; - case 12: generateEXTUB(inst, b); break; - case 13: generateEXTUW(inst, b); break; - case 14: generateEXTSB(inst, b); break; - case 15: generateEXTSW(inst, b); break; - } - break; - - case 7: generateADDI(inst, b); break; - - case 8: - switch(INSTRUCTION_B(inst)) { - case 0: generateMOVBS4(inst, b); break; - case 1: generateMOVWS4(inst, b); break; - case 4: generateMOVBL4(inst, b); break; - case 5: generateMOVWL4(inst, b); break; - case 8: generateCMPIM(inst, b); break; - case 9: generateBT(inst, b); done = 1; break; - case 11: generateBF(inst, b); done = 1; break; - case 13: generateBTS(inst, b); done = 1; break; - case 15: generateBFS(inst, b); done = 1; break; - default: return -1; - } - break; - - case 9: generateMOVWI(inst, b); break; - case 10: generateBRA(inst, b); done = 1; break; - case 11: generateBSR(inst, b); done = 1; break; - - case 12: - switch(INSTRUCTION_B(inst)) { - case 0: generateMOVBSG(inst, b); break; - case 1: generateMOVWSG(inst, b); break; - case 2: generateMOVLSG(inst, b); break; - case 3: generateTRAPA(inst, b); done = 1; break; - case 4: generateMOVBLG(inst, b); break; - case 5: generateMOVWLG(inst, b); break; - case 6: generateMOVLLG(inst, b); break; - case 7: generateMOVA(inst, b); break; - case 8: generateTSTI(inst, b); break; - case 9: generateANDI(inst, b); break; - case 10: generateXORI(inst, b); break; - case 11: generateORI(inst, b); break; - case 12: generateTSTM(inst, b); break; - case 13: generateANDM(inst, b); break; - case 14: generateXORM(inst, b); break; - case 15: generateORM(inst, b); break; - } - break; - - case 13: generateMOVLI(inst, b); break; - case 14: generateMOVI(inst, b); break; - default: return -1; - } - - return done; -} - -int sh2rec_rec_block(sh2rec_block_t *b) { - int done = 0; - - while(!done) { - done = sh2rec_rec_inst(b, 0); - } - - /* Flush the icache, so we don't execute stale data */ - icache_flush_range((uint32)b->block, ((u32)b->ptr) - ((u32)b->block)); - - return 0; -} - -/* In sh2exec.s */ -extern void sh2rec_exec(SH2_struct *cxt, u32 cycles); - -static int sh2rec_init(void) { - /* Initialize anything important here */ - sh2rec_htab_init(); - return 0; -} - -static void sh2rec_deinit(void) { - /* Clean stuff up here */ - sh2rec_htab_reset(); -} - -static void sh2rec_reset(void) { - /* Reset to a sane state */ - sh2rec_htab_reset(); -} - -/* This function borrowed from the interpreter core */ -void sh2rec_check_interrupts(SH2_struct *c) { - if(c->NumberOfInterrupts != 0) { - if(c->interrupts[c->NumberOfInterrupts-1].level > c->regs.SR.part.I) { - c->regs.R[15] -= 4; - MappedMemoryWriteLong(c->regs.R[15], c->regs.SR.all); - c->regs.R[15] -= 4; - MappedMemoryWriteLong(c->regs.R[15], c->regs.PC); - c->regs.SR.part.I = c->interrupts[c->NumberOfInterrupts - 1].level; - c->regs.PC = MappedMemoryReadLong(c->regs.VBR + (c->interrupts[c->NumberOfInterrupts-1].vector << 2)); - c->NumberOfInterrupts--; - c->isSleeping = 0; - } - } -} - -sh2rec_block_t *sh2rec_find_block(u32 pc) { - sh2rec_block_t *b = sh2rec_htab_lookup(pc); - - if(!b) { - b = sh2rec_htab_block_create(pc, 4096); - sh2rec_rec_block(b); - } - - return b; -} - -SH2Interface_struct SH2Dynarec = { - SH2CORE_DYNAREC, - "SH2 -> SH4 Dynarec", - - sh2rec_init, /* Init */ - sh2rec_deinit, /* DeInit */ - sh2rec_reset, /* Reset */ - sh2rec_exec, /* Exec */ - - SH2InterpreterGetRegisters, /* GetRegisters */ - SH2InterpreterGetGPR, /* GetGPR */ - SH2InterpreterGetSR, /* GetSR */ - SH2InterpreterGetGBR, /* GetGBR */ - SH2InterpreterGetVBR, /* GetVBR */ - SH2InterpreterGetMACH, /* GetMACH */ - SH2InterpreterGetMACL, /* GetMACL */ - SH2InterpreterGetPR, /* GetPR */ - SH2InterpreterGetPC, /* GetPC */ - - SH2InterpreterSetRegisters, /* SetRegisters */ - SH2InterpreterSetGPR, /* SetGPR */ - SH2InterpreterSetSR, /* SetSR */ - SH2InterpreterSetGBR, /* SetGBR */ - SH2InterpreterSetVBR, /* SetVBR */ - SH2InterpreterSetMACH, /* SetMACH */ - SH2InterpreterSetMACL, /* SetMACL */ - SH2InterpreterSetPR, /* SetPR */ - SH2InterpreterSetPC, /* SetPC */ - - SH2InterpreterSendInterrupt, /* SendInterrupt */ - SH2InterpreterGetInterrupts, /* GetInterrupts */ - SH2InterpreterSetInterrupts, /* SetInterrupts */ - - NULL /* WriteNotify */ -}; diff --git a/yabause/src/dreamcast/sh2rec/sh2rec.h b/yabause/src/dreamcast/sh2rec/sh2rec.h deleted file mode 100644 index cd5a87ac2f..0000000000 --- a/yabause/src/dreamcast/sh2rec/sh2rec.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef SH2REC_H -#define SH2REC_H - -#define SH2CORE_DYNAREC 10 - -#define INSTRUCTION_A(x) ((x & 0xF000) >> 12) -#define INSTRUCTION_B(x) ((x & 0x0F00) >> 8) -#define INSTRUCTION_C(x) ((x & 0x00F0) >> 4) -#define INSTRUCTION_D(x) (x & 0x000F) -#define INSTRUCTION_CD(x) (x & 0x00FF) -#define INSTRUCTION_BCD(x) (x & 0x0FFF) - -typedef struct sh2rec_block { - u16 *block; - u32 start_pc; - int cycles; - int length; - - u16 *ptr; - u32 pc; -} sh2rec_block_t; - -/* Recompile a single instruction */ -int sh2rec_rec_inst(sh2rec_block_t *b, int isdelay); - -/* Recompile a block at the PC specified in the block */ -int sh2rec_rec_block(sh2rec_block_t *b); - -extern SH2Interface_struct SH2Dynarec; - -#endif /* !SH2REC_H */ diff --git a/yabause/src/dreamcast/sh2rec/sh2rec_htab.c b/yabause/src/dreamcast/sh2rec/sh2rec_htab.c deleted file mode 100644 index 1a0e58b091..0000000000 --- a/yabause/src/dreamcast/sh2rec/sh2rec_htab.c +++ /dev/null @@ -1,157 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include - -#include "core.h" -#include "sh2core.h" -#include "sh2rec.h" -#include "sh2rec_htab.h" -#include "sh2rec_mem.h" - -typedef struct htab_entry { - sh2rec_block_t block; - - struct htab_entry *next; -} htab_entry_t; - -/* The actual hash table. It can't be resized dynamically, and is essentially - just an array of singly-linked lists. */ -static htab_entry_t *table[SH2REC_HTAB_ENTRIES]; - -/* Internal functions */ -static void htab_free_chain(htab_entry_t *ent) { - htab_entry_t *i, *tmp; - - i = ent; - while(i) { - tmp = i->next; - free(i->block.block); - free(i); - i = tmp; - } -} - -/* Hash an address into something slightly nicer to work with. The large - constant in here is about 2^32 / phi (where phi is the golden ratio). Why use - the golden ratio? Because its always fun to use in code. */ -static inline int hash_addr(u32 addr) { - return ((addr ^ 2654435761U) >> 2) & (SH2REC_HTAB_ENTRIES - 1); -} - -/* Public functions */ -void sh2rec_htab_init(void) { - memset(table, 0, sizeof(htab_entry_t *) * SH2REC_HTAB_ENTRIES); -} - -void sh2rec_htab_reset(void) { - int i; - - for(i = 0; i < SH2REC_HTAB_ENTRIES; ++i) { - if(table[i]) { - htab_free_chain(table[i]); - } - } - - memset(table, 0, sizeof(htab_entry_t *) * SH2REC_HTAB_ENTRIES); -} - -sh2rec_block_t *sh2rec_htab_lookup(u32 addr) { - htab_entry_t *i = table[hash_addr(addr)]; - - /* Look through the chain for the entry we're after */ - while(i) { - if(i->block.start_pc == addr) { - return &i->block; - } - - i = i->next; - } - - /* Didn't find it, punt. */ - return NULL; -} - -/* Create a new block assuming an old one does not exist. */ -sh2rec_block_t *sh2rec_htab_block_create(u32 addr, int length) { - uint8_t *ptr; - htab_entry_t *ent; - int index = hash_addr(addr); - - ptr = (uint8_t *)sh2rec_mem_alloc(length + sizeof(htab_entry_t)); - -#ifdef DEBUG - if(!ptr) { - return NULL; - } -#endif - - /* Allocate space for the block */ - ent = (htab_entry_t *)ptr; - ent->block.block = (u16 *)(ptr + sizeof(htab_entry_t)); - - /* Fill in the struct */ - ent->block.start_pc = addr; - ent->block.cycles = 0; - ent->block.pc = addr; - ent->block.length = length; - ent->block.ptr = ent->block.block; - - /* Put the item in the list (puts it at the head of the index in the table - where it would go) */ - ent->next = table[index]; - table[index] = ent; - - return &ent->block; -} - -void sh2rec_htab_block_remove(u32 addr) { - int index = hash_addr(addr); - htab_entry_t *i, *tmp, *last; - - i = table[index]; - last = NULL; - - /* Look through everything for the entry we're supposed to remove */ - while(i) { - tmp = i->next; - - /* Is this the entry we're looking for? */ - if(i->block.start_pc == addr) { - /* Unhook the entry from the list */ - if(last) { - last->next = tmp; - } - else { - table[index] = tmp; - } - - /* Free any memory used by the block */ - sh2rec_mem_free(i); - - return; - } - - last = i; - i = tmp; - } -} diff --git a/yabause/src/dreamcast/sh2rec/sh2rec_htab.h b/yabause/src/dreamcast/sh2rec/sh2rec_htab.h deleted file mode 100644 index 11b096f1b1..0000000000 --- a/yabause/src/dreamcast/sh2rec/sh2rec_htab.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef SH2REC_HTAB_H -#define SH2REC_HTAB_H - -/* This MUST be set to a power of two. It is done this way to avoid using a mod - operation to get the entry where the object will go, since division (and thus - modulus) is quite expensive on SuperH. */ -#define SH2REC_HTAB_ENTRIES 4096 - -void sh2rec_htab_init(void); -void sh2rec_htab_reset(void); - -sh2rec_block_t *sh2rec_htab_lookup(u32 addr); -sh2rec_block_t *sh2rec_htab_block_create(u32 addr, int length); -void sh2rec_htab_block_remove(u32 addr); - -#endif /* !SH2REC_HTAB_H */ diff --git a/yabause/src/dreamcast/sh2rec/sh2rec_mem.c b/yabause/src/dreamcast/sh2rec/sh2rec_mem.c deleted file mode 100644 index 8d8c09d47f..0000000000 --- a/yabause/src/dreamcast/sh2rec/sh2rec_mem.c +++ /dev/null @@ -1,222 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include - -#include "sh2rec_mem.h" - -typedef struct block_s { - uint8_t *ptr; - int size; - struct block_s *prev; - struct block_s *next; -} sh2rec_mem_block; - -typedef struct usedblock_s { - sh2rec_mem_block base; - sh2rec_mem_block *freespace; -} sh2rec_mem_usedblock; - -typedef struct allocblock_s { - struct allocblock_s *next; -} sh2rec_mem_allocblock; - -static sh2rec_mem_block *freeblocks = NULL; -static sh2rec_mem_usedblock *usedblocks = NULL; -static sh2rec_mem_usedblock *usedblocks_tail = NULL; -static sh2rec_mem_allocblock *allocblocks = NULL; - -static int cur_allocation = 0; - -#define BSSIZE (sizeof(sh2rec_mem_allocblock) + sizeof(sh2rec_mem_block) + \ - sizeof(sh2rec_mem_usedblock)) - -int sh2rec_mem_init(void) { - sh2rec_mem_block *initblock; - sh2rec_mem_allocblock *allocblock; - uint8_t *block; - - /* Allocate our initial space for storing rec'd instructions in */ - block = (uint8_t *)malloc(SH2REC_MEM_INITIAL); - -#ifdef DEBUG - if(!block) { - return -1; - } -#endif - - /* Carve our structures out of the beginning of the block */ - allocblock = (sh2rec_mem_allocblock *)block; - initblock = (sh2rec_mem_block *)(block + sizeof(sh2rec_mem_allocblock)); - cur_allocation = SH2REC_MEM_INITIAL; - - /* Fill in the rest of the structs */ - initblock->size = SH2REC_MEM_INITIAL - sizeof(sh2rec_mem_allocblock) - - sizeof(sh2rec_mem_block); - initblock->prev = NULL; - initblock->next = NULL; - - allocblock->next = NULL; - allocblocks = allocblock; - - /* The whole block is free, so put it in the free list */ - freeblocks = initblock; - - return 0; -} - -void sh2rec_mem_shutdown(void) { - sh2rec_mem_allocblock *i, *tmp; - - /* Loop through and free any blocks we allocated */ - i = allocblocks; - while(i) { - tmp = i->next; - free(i); - i = tmp; - } - - /* Clean up the stale pointers */ - allocblocks = NULL; - freeblocks = NULL; - usedblocks = NULL; -} - -void *sh2rec_mem_alloc(int sz) { - sh2rec_mem_block *i; - sh2rec_mem_usedblock *rv; - sh2rec_mem_allocblock *b; - int szlook = sz + SH2REC_MEM_FUDGE + sizeof(sh2rec_mem_usedblock); - uint8_t *block; - - /* Look for a free block of enough size */ - i = freeblocks; - while(i) { - if(i->size >= szlook) { - /* We've found a candidate, so, start working with it */ - rv = (sh2rec_mem_usedblock *)i->ptr; - rv->freespace = i; - rv->base.ptr = i->ptr + sizeof(sh2rec_mem_usedblock); - rv->base.size = sz; - rv->base.prev = (sh2rec_mem_block *)usedblocks_tail; - rv->base.next = NULL; - - /* Update the tail */ - if(usedblocks_tail) { - usedblocks_tail->base.next = (sh2rec_mem_block *)rv; - } - - usedblocks_tail = rv; - - /* The freeblock is now smaller, so reflect that */ - i->size -= sz + sizeof(sh2rec_mem_usedblock); - - return rv; - } - - i = i->next; - } - - /* We didn't find one, so allocate a new block */ - block = malloc(SH2REC_MEM_ALLOCSZ); - -#ifdef DEBUG - if(!block) { - return NULL; - } -#endif - - /* Fill in the allocblock */ - b = (sh2rec_mem_allocblock *)block; - b->next = allocblocks; - allocblocks = b; - - /* Now, create a freeblock, and work from that */ - i = (sh2rec_mem_block *)(block + sizeof(sh2rec_mem_allocblock)); - i->ptr = block + BSSIZE + sz; - i->prev = NULL; - i->next = freeblocks; - i->size = SH2REC_MEM_ALLOCSZ - BSSIZE - sz; - freeblocks = i; - - /* Create the usedblock */ - rv = (sh2rec_mem_usedblock *)(i->ptr - sz); - rv->freespace = i; - rv->base.ptr = i->ptr; - rv->base.size = sz; - rv->base.prev = (sh2rec_mem_block *)usedblocks_tail; - rv->base.next = NULL; - - /* Update the tail */ - if(usedblocks_tail) { - usedblocks_tail->base.next = (sh2rec_mem_block *)rv; - } - - usedblocks_tail = rv; - - /* Keep track of our allocation */ - cur_allocation += SH2REC_MEM_ALLOCSZ; - - return rv; -} - -int sh2rec_mem_expand(void *block, int amt) { - sh2rec_mem_usedblock *b = (sh2rec_mem_usedblock *)block; - - /* If the freeblock has space, allow it */ - if(b->freespace->size > amt) { - b->freespace->size -= amt; - b->base.size += amt; - b->freespace->ptr += amt; - return 1; - } - - return 0; -} - -void sh2rec_mem_free(void *block) { - sh2rec_mem_usedblock *b = (sh2rec_mem_usedblock *)block; - - /* Remove the usedblock from the chain */ - if(b->base.next) { - b->base.next->prev = b->base.prev; - } - - if(b->base.prev) { - b->base.prev->next = b->base.next; - } - - if(b == usedblocks) { - usedblocks = (sh2rec_mem_usedblock *)b->base.next; - } - - if(b == usedblocks_tail) { - usedblocks_tail = (sh2rec_mem_usedblock *)b->base.prev; - } - - /* Treat the usedblock like its a freeblock (it is an extension of the - freeblock), and just link it into the free blocks list */ - b->freespace = NULL; - b->base.next = freeblocks; - b->base.prev = NULL; - b->base.size += sizeof(sh2rec_mem_usedblock) - sizeof(sh2rec_mem_block); - freeblocks = (sh2rec_mem_block *)b; -} diff --git a/yabause/src/dreamcast/sh2rec/sh2rec_mem.h b/yabause/src/dreamcast/sh2rec/sh2rec_mem.h deleted file mode 100644 index 7fb679eb12..0000000000 --- a/yabause/src/dreamcast/sh2rec/sh2rec_mem.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright 2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef SH2REC_MEM_H -#define SH2REC_MEM_H - -/* Initial allocation of memory: 1MB */ -#define SH2REC_MEM_INITIAL (1024 * 1024) - -/* Size of future allocations: 256KB */ -#define SH2REC_MEM_ALLOCSZ (256 * 1024) - -/* Maximum allocation of memory: 2MB */ -#define SH2REC_MEM_MAX (2 * 1024 * 1024) - -/* Fudge factor... make sure at least this much is in any block above the - inital request */ -#define SH2REC_MEM_FUDGE 48 - -int sh2rec_mem_init(void); -void sh2rec_mem_shutdown(void); - -void *sh2rec_mem_alloc(int sz); -int sh2rec_mem_expand(void *block, int amt); -void sh2rec_mem_free(void *block); - -#endif /* !SH2REC_MEM_H */ diff --git a/yabause/src/dreamcast/viddc.c b/yabause/src/dreamcast/viddc.c deleted file mode 100644 index 52ea022f35..0000000000 --- a/yabause/src/dreamcast/viddc.c +++ /dev/null @@ -1,2836 +0,0 @@ -/* Copyright 2003-2006 Guillaume Duhamel - Copyright 2004-2009 Lawrence Sebald - Copyright 2004-2006 Theo Berkau - Copyright 2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "viddc.h" -#include "../debug.h" -#include "../vdp2.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#define SAT2YAB1(temp) ((temp & 0x8000) | (temp & 0x1F) << 10 | \ - (temp & 0x3E0) | (temp & 0x7C00) >> 10) -#define SAT2YAB32(alpha, temp) (alpha << 24 | (temp & 0x1F) << 3 | \ - (temp & 0x3E0) << 6 | (temp & 0x7C00) << 9) - -#define SAT2YAB2(dot1, dot2) ((dot1 & 0xF8) << 7 | (dot2 & 0xF800) >> 6 | \ - (dot2 & 0x00F8) >> 3 | 0x8000) -#define SAT2YAB2_32(alpha, dot1, dot2) (alpha << 24 | ((dot1 & 0xFF) << 16) | \ - (dot2 & 0xFF00) | (dot2 & 0xFF)) - -#define COLOR_ADDt32(b) (b > 0xFF ? 0xFF : (b < 0 ? 0 : b)) -#define COLOR_ADDb32(b1,b2) COLOR_ADDt32((signed) (b1) + (b2)) - -#define COLOR_ADD32(l,r,g,b) COLOR_ADDb32((l & 0xFF), r) | \ - (COLOR_ADDb32((l >> 8) & 0xFF, g) << 8) | \ - (COLOR_ADDb32((l >> 16) & 0xFF, b) << 16) | \ - (l & 0xFF000000) - -#define COLOR_ADDt(b) (b > 0xF8 ? 0xF8 : (b < 0x08 ? 0 : b)) -#define COLOR_ADDb(b1,b2) COLOR_ADDt((signed) (b1) + (b2)) -#define COLOR_ADD(l,r,g,b) ((COLOR_ADDb((l >> 7) & 0xF8, \ - r) & 0xF8) << 7) | \ - ((COLOR_ADDb((l >> 2) & 0xF8, \ - g) & 0xF8) << 2) | \ - ((COLOR_ADDb((l << 3) & 0xF8, \ - b) & 0xF8) >> 3) | \ - (l & 0x8000) - - -static pvr_init_params_t pvr_params = { - /* Enable Opaque, Translucent, and Punch-Thru polygons with binsize 16 */ - { PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_16, PVR_BINSIZE_0, - PVR_BINSIZE_16 }, - /* 512KB Vertex Buffer */ - 512 * 1024, - /* DMA Enabled */ - 1, - /* FSAA Disabled */ - 0 -}; - -struct sprite_info { - uint32 pvr_base; - uint32 vdp1_base; - float uf, vf; - int w, h; -}; - -typedef struct { - int cellw, cellh; - int flipfunction; - int priority; - - int mapwh; - int planew, planeh; - int pagewh; - int patternwh; - int patterndatasize; - int specialfunction; - u32 addr, charaddr, paladdr; - int colornumber; - int isbitmap; - u16 supplementdata; - int auxmode; - int enable; - int x, y; - int alpha; - int coloroffset; - int transparencyenable; - int specialprimode; - - s32 cor; - s32 cog; - s32 cob; - - float coordincx, coordincy; - void (* PlaneAddr)(void *, int); - u16 (* PostPixelFetchCalc)(void *, u16); - int patternpixelwh; - int draww; - int drawh; -} vdp2draw_struct; - -static struct sprite_info cur_spr; - -static struct sprite_info cache[1024]; -int cached_spr = 0; - -/* Polygon Headers */ -static pvr_sprite_hdr_t op_poly_hdr; -static pvr_sprite_hdr_t tr_poly_hdr; -static pvr_sprite_hdr_t tr_sprite_hdr; -static pvr_sprite_hdr_t pt_sprite_hdr; - -/* DMA Vertex Buffers 256KB Each */ -static uint8 vbuf_opaque[1024 * 256] __attribute__((aligned(32))); -static uint8 vbuf_translucent[1024 * 256] __attribute__((aligned(32))); -static uint8 vbuf_punchthru[1024 * 256] __attribute__((aligned(32))); - -/* VDP2 Framebuffer */ -static uint16 *vdp2_fb; -static int vdp2_fbnum = 0; -static uint16 vdp2_fbs[2][512 * 256] __attribute__((aligned(32))); -static uint8 vdp2_prio[352][240]; -static semaphore_t *dmadone; - -static pvr_ptr_t vdp2_tex; -static uint32 cur_vdp2; - -/* Priority levels, sprites drawn last get drawn on top */ -static float priority_levels[8]; - -/* Texture space for VDP1 sprites */ -static pvr_ptr_t tex_space; -static uint32 cur_addr; - -/* Misc parameters */ -static int vdp1cor = 0; -static int vdp1cog = 0; -static int vdp1cob = 0; - -static int nbg0priority = 0; -static int nbg1priority = 0; -static int nbg2priority = 0; -static int nbg3priority = 0; -static int rbg0priority = 0; - -static int vdp2width = 320; -static int vdp2height = 224; - -/* Frame counter */ -static time_t lastup; -static int framecount; - -static int power_of_two(int num) { - int ret = 8; - - while(ret < num) - ret <<= 1; - - return ret; -} - -static inline void vdp2putpixel(s32 x, s32 y, u16 color, int priority) { - vdp2_fb[(y * 512) + x] = color; - vdp2_prio[x][y] = (uint8) priority; -} - -static u32 Vdp2ColorRamGetColor32(u32 colorindex, int alpha) { - switch(Vdp2Internal.ColorMode) { - case 0: - case 1: - { - u32 tmp; - colorindex <<= 1; - tmp = T2ReadWord(Vdp2ColorRam, colorindex & 0xFFF); - return SAT2YAB32(alpha, tmp); - } - case 2: - { - u32 tmp1, tmp2; - colorindex <<= 2; - colorindex &= 0xFFF; - tmp1 = T2ReadWord(Vdp2ColorRam, colorindex); - tmp2 = T2ReadWord(Vdp2ColorRam, colorindex+2); - return SAT2YAB2_32(alpha, tmp1, tmp2); - } - default: - break; - } - - return 0; -} - -static uint16 Vdp2ColorRamGetColor(u32 colorindex) { - u16 tmp; - - switch(Vdp2Internal.ColorMode) { - case 0: - case 1: - { - colorindex <<= 1; - tmp = T2ReadWord(Vdp2ColorRam, colorindex & 0xFFF); - return SAT2YAB1(tmp) | 0x8000; - } - case 2: - { - u16 tmp2; - colorindex <<= 2; - colorindex &= 0xFFF; - tmp = T2ReadWord(Vdp2ColorRam, colorindex); - tmp2 = T2ReadWord(Vdp2ColorRam, colorindex+2); - return SAT2YAB2(tmp, tmp2) | 0x8000; - } - default: - break; - } - - return 0; -} - -static int Vdp1ReadTexture(vdp1cmd_struct *cmd, pvr_sprite_hdr_t *hdr) { - u32 charAddr = cmd->CMDSRCA << 3; - uint16 dot, dot2; - int queuepos = 0; - uint32 *store_queue; - uint32 cur_base; - u8 SPD = ((cmd->CMDPMOD & 0x40) != 0); - int k; - - int wi = power_of_two(cur_spr.w); - int he = power_of_two(cur_spr.h); - - for(k = 0; k < cached_spr; ++k) { - if(cache[k].vdp1_base == charAddr) { - if(cache[k].w == cur_spr.w && cache[k].h == cur_spr.h) { - cur_base = cache[k].pvr_base; - goto fillHeader; - } - } - } - - cur_base = cur_addr; - - /* Set up both Store Queues for transfer to VRAM */ - QACR0 = 0x00000004; - QACR1 = 0x00000004; - - switch((cmd->CMDPMOD >> 3) & 0x07) { - case 0: - { - // 4 bpp Bank mode - u16 temp; - u32 colorBank = cmd->CMDCOLR; - u32 colorOffset = (Vdp2Regs->CRAOFB & 0x70) << 4; - int i, j; - - for(i = 0; i < cur_spr.h; ++i) { - store_queue = (uint32 *) (0xE0000000 | - (cur_addr & 0x03FFFFE0)); - - for(j = 0; j < cur_spr.w; j += 2) { - dot = T1ReadByte(Vdp1Ram, charAddr & 0x7FFFF); - - if(((dot & 0xF) == 0) && !SPD) dot2 = 0; - else { - temp = Vdp2ColorRamGetColor(((dot & 0x0F) | colorBank) + - colorOffset); - dot2 = COLOR_ADD(temp, vdp1cor, vdp1cog, vdp1cob); - } - - if(((dot >> 4) == 0) && !SPD) dot = 0; - else { - temp = Vdp2ColorRamGetColor(((dot >> 4) | colorBank) + - colorOffset); - dot = COLOR_ADD(temp, vdp1cor, vdp1cog, vdp1cob); - } - - ++charAddr; - - store_queue[queuepos++] = dot | (dot2 << 16); - - if(queuepos == 8) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - store_queue += 8; - } - } - - if(queuepos) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - } - - cur_addr += wi * 2; - } - break; - } - - case 1: - { - // 4 bpp LUT mode - u16 temp; - u32 colorLut = cmd->CMDCOLR * 8; - int i, j; - - for(i = 0; i < cur_spr.h; ++i) { - store_queue = (uint32 *) (0xE0000000 | - (cur_addr & 0x03FFFFE0)); - - for(j = 0; j < cur_spr.w; j += 2) { - dot = T1ReadByte(Vdp1Ram, charAddr & 0x7FFFF); - - if(((dot & 0xF) == 0) && !SPD) dot2 = 0; - else { - temp = T1ReadWord(Vdp1Ram, ((dot & 0xF) * 2 + - colorLut) & 0x7FFFF); - - if(temp & 0x8000) - dot2 = COLOR_ADD(SAT2YAB1(temp), vdp1cor, vdp1cog, - vdp1cob); - else - dot2 = COLOR_ADD(Vdp2ColorRamGetColor(temp), - vdp1cor, vdp1cog, vdp1cob); - } - - if(((dot >> 4) == 0) && !SPD) dot = 0; - else { - temp = T1ReadWord(Vdp1Ram, ((dot >> 4) * 2 + colorLut) & - 0x7FFFF); - if (temp & 0x8000) - dot = COLOR_ADD(SAT2YAB1(temp), vdp1cor, vdp1cog, - vdp1cob); - else - dot = COLOR_ADD(Vdp2ColorRamGetColor(temp), vdp1cor, - vdp1cog, vdp1cob); - } - - ++charAddr; - - store_queue[queuepos++] = dot | (dot2 << 16); - - if(queuepos == 8) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - store_queue += 8; - } - } - - if(queuepos) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - } - - cur_addr += wi * 2; - } - break; - } - - case 2: - { - // 8 bpp (64 color) Bank mode - int i, j; - u32 colorBank = cmd->CMDCOLR; - u32 colorOffset = (Vdp2Regs->CRAOFB & 0x70) << 4; - u16 temp; - - for(i = 0; i < cur_spr.h; ++i) { - store_queue = (uint32 *) (0xE0000000 | - (cur_addr & 0x03FFFFE0)); - - for(j = 0; j < cur_spr.w; j += 2) { - dot = T1ReadByte(Vdp1Ram, charAddr & 0x7FFFF) & 0x3F; - dot2 = T1ReadByte(Vdp1Ram, (charAddr + 1) & 0x7FFFF) & 0x3F; - charAddr = charAddr + 2; - - if(dot || SPD) { - temp = Vdp2ColorRamGetColor((dot | colorBank) + - colorOffset); - dot = COLOR_ADD(temp, vdp1cor, vdp1cog, vdp1cob); - } - - if(dot2 || SPD) { - temp = Vdp2ColorRamGetColor((dot2 | colorBank) + - colorOffset); - dot2 = COLOR_ADD(temp, vdp1cor, vdp1cog, vdp1cob); - } - - store_queue[queuepos++] = dot | (dot2 << 16); - - if(queuepos == 8) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - store_queue += 8; - } - } - - if(queuepos) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - } - - cur_addr += wi * 2; - } - break; - } - - case 3: - { - // 8 bpp (128 color) Bank mode - int i, j; - u32 colorBank = cmd->CMDCOLR; - u32 colorOffset = (Vdp2Regs->CRAOFB & 0x70) << 4; - u16 temp; - - for(i = 0; i < cur_spr.h; ++i) { - store_queue = (uint32 *) (0xE0000000 | - (cur_addr & 0x03FFFFE0)); - - for(j = 0; j < cur_spr.w; j += 2) { - dot = T1ReadByte(Vdp1Ram, charAddr & 0x7FFFF) & 0x7F; - dot2 = T1ReadByte(Vdp1Ram, (charAddr + 1) & 0x7FFFF) & 0x7F; - charAddr = charAddr + 2; - - if(dot || SPD) { - temp = Vdp2ColorRamGetColor((dot | colorBank) + - colorOffset); - dot = COLOR_ADD(temp, vdp1cor, vdp1cog, vdp1cob); - } - - if(dot2 || SPD) { - temp = Vdp2ColorRamGetColor((dot2 | colorBank) + - colorOffset); - dot2 = COLOR_ADD(temp, vdp1cor, vdp1cog, vdp1cob); - } - - store_queue[queuepos++] = dot | (dot2 << 16); - - if(queuepos == 8) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - store_queue += 8; - } - } - - if(queuepos) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - } - - cur_addr += wi * 2; - } - break; - } - - case 4: - { - // 8 bpp (256 color) Bank mode - int i, j; - u32 colorBank = cmd->CMDCOLR; - u32 colorOffset = (Vdp2Regs->CRAOFB & 0x70) << 4; - u16 temp; - - for(i = 0; i < cur_spr.h; ++i) { - store_queue = (uint32 *) (0xE0000000 | - (cur_addr & 0x03FFFFE0)); - - for(j = 0; j < cur_spr.w; j += 2) { - dot = T1ReadByte(Vdp1Ram, charAddr & 0x7FFFF); - dot2 = T1ReadByte(Vdp1Ram, (charAddr + 1) & 0x7FFFF); - charAddr = charAddr + 2; - - if(dot || SPD) { - temp = Vdp2ColorRamGetColor((dot | colorBank) + - colorOffset); - dot = COLOR_ADD(temp, vdp1cor, vdp1cog, vdp1cob); - } - - if(dot2 || SPD) { - temp = Vdp2ColorRamGetColor((dot2 | colorBank) + - colorOffset); - dot2 = COLOR_ADD(temp, vdp1cor, vdp1cog, vdp1cob); - } - - store_queue[queuepos++] = dot | (dot2 << 16); - - if(queuepos == 8) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - store_queue += 8; - } - } - - if(queuepos) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - } - - cur_addr += wi * 2; - } - break; - } - - case 5: - { - // 16 bpp Bank mode - int i, j; - - for(i = 0; i < cur_spr.h; ++i) { - store_queue = (uint32 *) (0xE0000000 | - (cur_addr & 0x03FFFFE0)); - - for(j = 0; j < cur_spr.w; j += 2) { - dot = T1ReadWord(Vdp1Ram, charAddr & 0x7FFFF); - dot2 = T1ReadWord(Vdp1Ram, (charAddr + 2) & 0x7FFFF); - charAddr = charAddr + 4; - - if(dot || SPD) - dot = COLOR_ADD(SAT2YAB1(dot), vdp1cor, vdp1cog, - vdp1cob); - - if(dot2 || SPD) - dot2 = COLOR_ADD(SAT2YAB1(dot2), vdp1cor, vdp1cog, - vdp1cob); - - store_queue[queuepos++] = dot | (dot2 << 16); - - if(queuepos == 8) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - store_queue += 8; - } - } - - if(queuepos) { - asm("pref @%0" : : "r"(store_queue)); - queuepos = 0; - } - - cur_addr += wi * 2; - } - break; - } - - default: - VDP1LOG("Unimplemented sprite color mode: %X\n", - (cmd->CMDPMOD >> 3) & 0x7); - return 0; - } - - if(cached_spr < 1023) { - cache[cached_spr].vdp1_base = cmd->CMDSRCA << 3; - cache[cached_spr].pvr_base = cur_base; - cache[cached_spr].w = cur_spr.w; - cache[cached_spr].h = cur_spr.h; - - cached_spr++; - } - -fillHeader: - - cur_spr.uf = (float) cur_spr.w / wi; - cur_spr.vf = (float) cur_spr.h / he; - - hdr->mode2 &= (~(PVR_TA_PM2_USIZE_MASK | PVR_TA_PM2_VSIZE_MASK)); - - switch (wi) { - case 8: break; - case 16: hdr->mode2 |= (1 << PVR_TA_PM2_USIZE_SHIFT); break; - case 32: hdr->mode2 |= (2 << PVR_TA_PM2_USIZE_SHIFT); break; - case 64: hdr->mode2 |= (3 << PVR_TA_PM2_USIZE_SHIFT); break; - case 128: hdr->mode2 |= (4 << PVR_TA_PM2_USIZE_SHIFT); break; - case 256: hdr->mode2 |= (5 << PVR_TA_PM2_USIZE_SHIFT); break; - case 512: hdr->mode2 |= (6 << PVR_TA_PM2_USIZE_SHIFT); break; - case 1024: hdr->mode2 |= (7 << PVR_TA_PM2_USIZE_SHIFT); break; - default: assert_msg(0, "Invalid texture U size"); break; - } - - switch (he) { - case 8: break; - case 16: hdr->mode2 |= (1 << PVR_TA_PM2_VSIZE_SHIFT); break; - case 32: hdr->mode2 |= (2 << PVR_TA_PM2_VSIZE_SHIFT); break; - case 64: hdr->mode2 |= (3 << PVR_TA_PM2_VSIZE_SHIFT); break; - case 128: hdr->mode2 |= (4 << PVR_TA_PM2_VSIZE_SHIFT); break; - case 256: hdr->mode2 |= (5 << PVR_TA_PM2_VSIZE_SHIFT); break; - case 512: hdr->mode2 |= (6 << PVR_TA_PM2_VSIZE_SHIFT); break; - case 1024: hdr->mode2 |= (7 << PVR_TA_PM2_VSIZE_SHIFT); break; - default: assert_msg(0, "Invalid texture V size"); break; - } - - hdr->mode3 = ((cur_base & 0x00FFFFF8) >> 3) | (PVR_TXRFMT_NONTWIDDLED); - - /* Make sure everything is aligned nicely... */ - cur_addr = (cur_addr & 0x03FFFFE0) + 0x20; - - return 1; -} - -static u8 Vdp1ReadPriority(vdp1cmd_struct *cmd) { - u8 SPCLMD = Vdp2Regs->SPCTL; - u8 sprite_register; - u8 *sprprilist = (u8 *)&Vdp2Regs->PRISA; - - if ((SPCLMD & 0x20) && (cmd->CMDCOLR & 0x8000)) { - // RGB data, use register 0 - return Vdp2Regs->PRISA & 0x07; - } - else { - u8 sprite_type = SPCLMD & 0x0F; - switch(sprite_type) { - case 0: - sprite_register = ((cmd->CMDCOLR & 0x8000) | - (~cmd->CMDCOLR & 0x4000)) >> 14; - return sprprilist[sprite_register ^ 1] & 0x07; - break; - case 1: - sprite_register = ((cmd->CMDCOLR & 0xC000) | - (~cmd->CMDCOLR & 0x2000)) >> 13; - return sprprilist[sprite_register ^ 1] & 0x07; - break; - case 3: - sprite_register = ((cmd->CMDCOLR & 0x4000) | - (~cmd->CMDCOLR & 0x2000)) >> 13; - return sprprilist[sprite_register ^ 1] & 0x07; - break; - case 4: - sprite_register = ((cmd->CMDCOLR & 0x4000) | - (~cmd->CMDCOLR & 0x2000)) >> 13; - return sprprilist[sprite_register ^ 1] & 0x07; - break; - case 5: - sprite_register = ((cmd->CMDCOLR & 0x6000) | - (~cmd->CMDCOLR & 0x1000)) >> 12; - return sprprilist[sprite_register ^ 1] & 0x07; - break; - case 6: - sprite_register = ((cmd->CMDCOLR & 0x6000) | - (~cmd->CMDCOLR & 0x1000)) >> 12; - return sprprilist[sprite_register ^ 1] & 0x07; - break; - case 7: - sprite_register = ((cmd->CMDCOLR & 0x6000) | - (~cmd->CMDCOLR & 0x1000)) >> 12; - return sprprilist[sprite_register ^ 1] & 0x07; - break; - default: - VDP1LOG("sprite type %d not implemented\n", sprite_type); - return 0x07; - break; - } - } -} - -/* This has all been imported from the vidsoft.c file. It will be updated, - hopefully (roughly) synchronized with updates to it */ - -////////////////////////////////////////////////////////////////////////////// - -typedef struct -{ - int xstart, ystart; - int xend, yend; - int pixeloffset; - int lineincrement; -} clipping_struct; - -static void inline HandleClipping(vdp2draw_struct *info, clipping_struct *clip) -{ - clip->pixeloffset=0; - clip->lineincrement=0; - - // Handle clipping(both window and screen clipping) - if (info->x < 0) - { - clip->xstart = 0; - clip->xend = (info->x+info->cellw); - clip->pixeloffset = 0 - info->x; - clip->lineincrement = 0 - info->x; - } - else - { - clip->xstart = info->x; - - if ((info->x+info->cellw) > vdp2width) - { - clip->xend = vdp2width; - clip->lineincrement = (info->x+info->cellw) - vdp2width; - } - else - clip->xend = (info->x+info->cellw); - } - - if (info->y < 0) - { - clip->ystart = 0; - clip->yend = (info->y+info->cellh); - clip->pixeloffset = (info->cellw * (0 - info->y)) + clip->pixeloffset; - } - else - { - clip->ystart = info->y; - - if ((info->y+info->cellh) >= vdp2height) - clip->yend = vdp2height; - else - clip->yend = (info->y+info->cellh); - } -} - -////////////////////////////////////////////////////////////////////////////// - -void Vdp2DrawScrollBitmap(vdp2draw_struct *info) -{ - int i, i2; - clipping_struct clip; - - HandleClipping(info, &clip); - - switch (info->colornumber) - { - case 0: // 4 BPP(16 colors) - // fix me - printf("vdp2 bitmap 4 bpp draw\n"); - return; - case 1: // 8 BPP(256 colors) - info->charaddr += clip.pixeloffset; - - for (i = clip.ystart; i < clip.yend; i++) - { - for (i2 = clip.xstart; i2 < clip.xend; i2++) - { - u16 color = T1ReadByte(Vdp2Ram, info->charaddr); - info->charaddr++; - - if (color == 0 && info->transparencyenable) { - vdp2putpixel(i2, i, 0, info->priority); - } - else { - color = Vdp2ColorRamGetColor(info->coloroffset + (info->paladdr | color)); - vdp2putpixel(i2, i, info->PostPixelFetchCalc(info, color) | 0x8000, info->priority); - } - } - - info->charaddr += clip.lineincrement; - } - - return; - case 2: - printf("vdp2 bitmap 16bpp palette draw\n"); - break; - case 3: // 15 BPP - clip.pixeloffset *= 2; - clip.lineincrement *= 2; - - info->charaddr += clip.pixeloffset; - - for (i = clip.ystart; i < clip.yend; i++) - { - for (i2 = clip.xstart; i2 < clip.xend; i2++) - { - u16 color = T1ReadWord(Vdp2Ram, info->charaddr); - info->charaddr += 2; - - if ((color & 0x8000) == 0 && info->transparencyenable) - vdp2_fb[(i * vdp2width) + i2] = 0; - else - vdp2_fb[(i * vdp2width) + i2] = info->PostPixelFetchCalc(info, SAT2YAB1(color)) | 0x8000; - - vdp2_prio[i][i2] = info->priority; - } - - info->charaddr += clip.lineincrement; - } - - return; - case 4: // 24 BPP - clip.pixeloffset *= 4; - clip.lineincrement *= 4; - - info->charaddr += clip.pixeloffset; - - for (i = clip.ystart; i < clip.yend; i++) - { - for (i2 = clip.xstart; i2 < clip.xend; i2++) - { - u32 color = T1ReadLong(Vdp2Ram, info->charaddr); - info->charaddr += 4; - - if ((color & 0x80000000) == 0 && info->transparencyenable) - vdp2putpixel(i2, i, 0, info->priority); - else { - u16 dot = ((color & 0xF80000) >> 19 | - (color & 0x00F800) >> 6 | - (color & 0x0000F8) << 7 | 0x8000); - vdp2putpixel(i2, i, info->PostPixelFetchCalc(info, dot), info->priority); - } - } - - info->charaddr += clip.lineincrement; - - } - return; - default: break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -#define Vdp2DrawCell4bpp(mask, shift) \ - if ((dot & mask) == 0 && info->transparencyenable) { \ - vdp2putpixel(i2, i, 0, info->priority); \ - } \ - else \ - { \ - color = Vdp2ColorRamGetColor(info->coloroffset + (info->paladdr | ((dot & mask) >> shift))); \ - vdp2putpixel(i2, i, info->PostPixelFetchCalc(info, color), info->priority); \ - } - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawCell(vdp2draw_struct *info) -{ - u32 color; - int i, i2; - clipping_struct clip; - u32 newcharaddr; - - HandleClipping(info, &clip); - - if (info->flipfunction & 0x1) - { - // Horizontal flip - } - - if (info->flipfunction & 0x2) - { - // Vertical flip - // clip.pixeloffset = (info.w * info.h) - clip.pixeloffset; - // clip.lineincrement = 0 - clip.lineincrement; - } - - switch(info->colornumber) - { - case 0: // 4 BPP - if ((clip.lineincrement | clip.pixeloffset) == 0) - { - for (i = clip.ystart; i < clip.yend; i++) - { - u32 dot; - u16 color; - - i2 = clip.xstart; - - // Fetch Pixel 1/2/3/4/5/6/7/8 - dot = T1ReadLong(Vdp2Ram, info->charaddr); - info->charaddr+=4; - - // Draw 8 Pixels - Vdp2DrawCell4bpp(0xF0000000, 28) - i2++; - Vdp2DrawCell4bpp(0x0F000000, 24) - i2++; - Vdp2DrawCell4bpp(0x00F00000, 20) - i2++; - Vdp2DrawCell4bpp(0x000F0000, 16) - i2++; - Vdp2DrawCell4bpp(0x0000F000, 12) - i2++; - Vdp2DrawCell4bpp(0x00000F00, 8) - i2++; - Vdp2DrawCell4bpp(0x000000F0, 4) - i2++; - Vdp2DrawCell4bpp(0x0000000F, 0) - i2++; - } - } - else - { - u8 dot; - - newcharaddr = info->charaddr + ((info->cellw * info->cellh) >> 1); - - info->charaddr <<= 1; - info->charaddr += clip.pixeloffset; - - for (i = clip.ystart; i < clip.yend; i++) - { - dot = T1ReadByte(Vdp2Ram, info->charaddr >> 1); - info->charaddr++; - - for (i2 = clip.xstart; i2 < clip.xend; i2++) - { - u32 color; - - // Draw two pixels - if(info->charaddr & 0x1) - { - Vdp2DrawCell4bpp(0xF0, 4) - info->charaddr++; - } - else - { - Vdp2DrawCell4bpp(0x0F, 0) - dot = T1ReadByte(Vdp2Ram, info->charaddr >> 1); - info->charaddr++; - } - } - info->charaddr += clip.lineincrement; - } - - info->charaddr = newcharaddr; - } - break; - case 1: // 8 BPP - newcharaddr = info->charaddr + (info->cellw * info->cellh); - info->charaddr += clip.pixeloffset; - - for (i = clip.ystart; i < clip.yend; i++) - { - for (i2 = clip.xstart; i2 < clip.xend; i2++) - { - u16 color = T1ReadByte(Vdp2Ram, info->charaddr); - info->charaddr++; - - if (color == 0 && info->transparencyenable) { - vdp2putpixel(i2, i, 0, info->priority); - } - else { - color = Vdp2ColorRamGetColor(info->coloroffset + (info->paladdr | color)); - vdp2putpixel(i2, i, info->PostPixelFetchCalc(info, color), info->priority); - } - } - - info->charaddr += clip.lineincrement; - } - - info->charaddr = newcharaddr; - - break; - case 2: // 16 BPP(palette) - printf("vdp2 cell draw 16bpp palette\n"); - break; - - case 3: // 16 BPP(RGB) - printf("vdp2 cell draw 16bpp\n"); - break; - case 4: // 32 BPP - newcharaddr = info->charaddr + (info->cellw * info->cellh); - info->charaddr += clip.pixeloffset; - - for (i = clip.ystart; i < clip.yend; i++) - { - for (i2 = clip.xstart; i2 < clip.xend; i2++) - { - u16 dot1, dot2; - dot1 = T1ReadWord(Vdp2Ram, info->charaddr & 0x7FFFF); - info->charaddr += 2; - dot2 = T1ReadWord(Vdp2Ram, info->charaddr & 0x7FFFF); - info->charaddr += 2; - - if (!(dot1 & 0x8000) && info->transparencyenable) - continue; - - color = SAT2YAB2(dot1, dot2); - vdp2putpixel(i2, i, info->PostPixelFetchCalc(info, color), info->priority); - } - - info->charaddr += clip.lineincrement; - } - - info->charaddr = newcharaddr; - - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawPattern(vdp2draw_struct *info) -{ - // if (info->specialprimode == 1) - // tile.priority = (info->priority & 0xFFFFFFFE) | info->specialfunction; - // else - // tile.priority = info->priority; - - switch(info->patternwh) - { - case 1: - Vdp2DrawCell(info); - info->x += 8; - info->y += 8; - break; - case 2: - Vdp2DrawCell(info); - info->x += 8; - Vdp2DrawCell(info); - info->x -= 8; - info->y += 8; - Vdp2DrawCell(info); - info->x += 8; - Vdp2DrawCell(info); - info->x += 8; - info->y += 8; - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2PatternAddr(vdp2draw_struct *info) -{ - switch(info->patterndatasize) - { - case 1: - { - u16 tmp = T1ReadWord(Vdp2Ram, info->addr); - - info->addr += 2; - info->specialfunction = (info->supplementdata >> 9) & 0x1; - - switch(info->colornumber) - { - case 0: // in 16 colors - info->paladdr = ((tmp & 0xF000) >> 8) | ((info->supplementdata & 0xE0) << 3); - break; - default: // not in 16 colors - info->paladdr = (tmp & 0x7000) >> 4; - break; - } - - switch(info->auxmode) - { - case 0: - info->flipfunction = (tmp & 0xC00) >> 10; - - switch(info->patternwh) - { - case 1: - info->charaddr = (tmp & 0x3FF) | ((info->supplementdata & 0x1F) << 10); - break; - case 2: - info->charaddr = ((tmp & 0x3FF) << 2) | (info->supplementdata & 0x3) | ((info->supplementdata & 0x1C) << 10); - break; - } - break; - case 1: - info->flipfunction = 0; - - switch(info->patternwh) - { - case 1: - info->charaddr = (tmp & 0xFFF) | ((info->supplementdata & 0x1C) << 10); - break; - case 2: - info->charaddr = ((tmp & 0xFFF) << 2) | (info->supplementdata & 0x3) | ((info->supplementdata & 0x10) << 10); - break; - } - break; - } - - break; - } - case 2: { - u16 tmp1 = T1ReadWord(Vdp2Ram, info->addr); - u16 tmp2 = T1ReadWord(Vdp2Ram, info->addr+2); - info->addr += 4; - info->charaddr = tmp2 & 0x7FFF; - info->flipfunction = (tmp1 & 0xC000) >> 14; - info->paladdr = (tmp1 & 0x7F) << 4; - info->specialfunction = (tmp1 & 0x2000) >> 13; - break; - } - } - - if (!(Vdp2Regs->VRSIZE & 0x8000)) - info->charaddr &= 0x3FFF; - - info->charaddr *= 0x20; // selon Runik -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawPage(vdp2draw_struct *info) -{ - int X, Y; - int i, j; - - X = info->x; - for(i = 0;i < info->pagewh;i++) - { - Y = info->y; - info->x = X; - for(j = 0;j < info->pagewh;j++) - { - info->y = Y; - if ((info->x >= -info->patternpixelwh) && - (info->y >= -info->patternpixelwh) && - (info->x <= info->draww) && - (info->y <= info->drawh)) - { - Vdp2PatternAddr(info); - Vdp2DrawPattern(info); - } - else - { - info->addr += info->patterndatasize * 2; - info->x += info->patternpixelwh; - info->y += info->patternpixelwh; - } - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawPlane(vdp2draw_struct *info) -{ - int X, Y; - int i, j; - - X = info->x; - for(i = 0;i < info->planeh;i++) - { - Y = info->y; - info->x = X; - for(j = 0;j < info->planew;j++) - { - info->y = Y; - Vdp2DrawPage(info); - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2DrawMap(vdp2draw_struct *info) -{ - int i, j; - int X, Y; - u32 lastplane; - - X = info->x; - lastplane=0xFFFFFFFF; - - info->patternpixelwh = 8 * info->patternwh; - info->draww = (int)((float)vdp2width / info->coordincx); - info->drawh = (int)((float)vdp2height / info->coordincy); - - for(i = 0;i < info->mapwh;i++) - { - Y = info->y; - info->x = X; - for(j = 0;j < info->mapwh;j++) - { - info->y = Y; - info->PlaneAddr(info, info->mapwh * i + j); - if (info->addr != lastplane) - { - Vdp2DrawPlane(info); - lastplane = info->addr; - } - } - } -} - -static int VIDDCInit(void) { - pvr_sprite_cxt_t op_poly_cxt, tr_poly_cxt; - pvr_sprite_cxt_t pt_sprite_cxt, tr_sprite_cxt; - - vid_set_mode(DM_320x240, PM_RGB565); - - if(pvr_init(&pvr_params)) { - fprintf(stderr, "VIDDCInit() - error initializing PVR\n"); - return -1; - } - - dmadone = sem_create(1); - - pvr_set_vertbuf(PVR_LIST_OP_POLY, vbuf_opaque, 1024 * 256); - pvr_set_vertbuf(PVR_LIST_TR_POLY, vbuf_translucent, 1024 * 256); - pvr_set_vertbuf(PVR_LIST_PT_POLY, vbuf_punchthru, 1024 * 256); - - tex_space = pvr_mem_malloc(1024 * 1024 * 2); - vdp2_tex = pvr_mem_malloc(512 * 256 * 4 * 2); - cur_addr = (uint32)tex_space; - - printf("PVR Memory Available: %lu\n", pvr_mem_available()); - - sq_set(tex_space, 0xFF, 1024 * 1024 * 2); - - pvr_sprite_cxt_col(&op_poly_cxt, PVR_LIST_OP_POLY); - pvr_sprite_cxt_col(&tr_poly_cxt, PVR_LIST_TR_POLY); - - op_poly_cxt.gen.culling = PVR_CULLING_NONE; - tr_poly_cxt.gen.culling = PVR_CULLING_NONE; - - pvr_sprite_compile(&op_poly_hdr, &op_poly_cxt); - pvr_sprite_compile(&tr_poly_hdr, &tr_poly_cxt); - - pvr_sprite_cxt_txr(&tr_sprite_cxt, PVR_LIST_TR_POLY, PVR_TXRFMT_ARGB1555 | - PVR_TXRFMT_NONTWIDDLED, 1024, 1024, tex_space, - PVR_FILTER_NONE); - pvr_sprite_cxt_txr(&pt_sprite_cxt, PVR_LIST_PT_POLY, PVR_TXRFMT_ARGB1555 | - PVR_TXRFMT_NONTWIDDLED, 1024, 1024, tex_space, - PVR_FILTER_NONE); - - pt_sprite_cxt.gen.culling = PVR_CULLING_NONE; - tr_sprite_cxt.gen.culling = PVR_CULLING_NONE; - - pvr_sprite_compile(&tr_sprite_hdr, &tr_sprite_cxt); - pvr_sprite_compile(&pt_sprite_hdr, &pt_sprite_cxt); - - tr_sprite_hdr.argb = PVR_PACK_COLOR(0.5f, 1.0f, 1.0f, 1.0f); - - priority_levels[0] = 0.0f; - priority_levels[1] = 1.0f; - priority_levels[2] = 2.0f; - priority_levels[3] = 3.0f; - priority_levels[4] = 4.0f; - priority_levels[5] = 5.0f; - priority_levels[6] = 6.0f; - priority_levels[7] = 7.0f; - - framecount = 0; - lastup = time(NULL); - - return 0; -} - -static void VIDDCDeInit(void) { - pvr_set_vertbuf(PVR_LIST_OP_POLY, NULL, 0); - pvr_set_vertbuf(PVR_LIST_TR_POLY, NULL, 0); - pvr_set_vertbuf(PVR_LIST_PT_POLY, NULL, 0); - - pvr_mem_free(tex_space); - sem_destroy(dmadone); - - pvr_shutdown(); - vid_set_mode(DM_640x480, PM_RGB565); -} - -static void VIDDCResize(unsigned int w, unsigned int h, int unused) { -} - -static int VIDDCIsFullscreen(void) { - return 1; -} - -static int VIDDCVdp1Reset(void) { - return 0; -} - -static void VIDDCVdp1DrawStart(void) { - if(Vdp2Regs->CLOFEN & 0x40) { - // color offset enable - if(Vdp2Regs->CLOFSL & 0x40) { - // color offset B - vdp1cor = Vdp2Regs->COBR & 0xFF; - if(Vdp2Regs->COBR & 0x100) - vdp1cor |= 0xFFFFFF00; - - vdp1cog = Vdp2Regs->COBG & 0xFF; - if(Vdp2Regs->COBG & 0x100) - vdp1cog |= 0xFFFFFF00; - - vdp1cob = Vdp2Regs->COBB & 0xFF; - if(Vdp2Regs->COBB & 0x100) - vdp1cob |= 0xFFFFFF00; - } - else { - // color offset A - vdp1cor = Vdp2Regs->COAR & 0xFF; - if(Vdp2Regs->COAR & 0x100) - vdp1cor |= 0xFFFFFF00; - - vdp1cog = Vdp2Regs->COAG & 0xFF; - if(Vdp2Regs->COAG & 0x100) - vdp1cog |= 0xFFFFFF00; - - vdp1cob = Vdp2Regs->COAB & 0xFF; - if(Vdp2Regs->COAB & 0x100) - vdp1cob |= 0xFFFFFF00; - } - } - else // color offset disable - vdp1cor = vdp1cog = vdp1cob = 0; -} - -static void VIDDCVdp1DrawEnd(void) { - cached_spr = 0; - priority_levels[0] = 0.0f; - priority_levels[1] = 1.0f; - priority_levels[2] = 2.0f; - priority_levels[3] = 3.0f; - priority_levels[4] = 4.0f; - priority_levels[5] = 5.0f; - priority_levels[6] = 6.0f; - priority_levels[7] = 7.0f; -} - -static void VIDDCVdp1NormalSpriteDraw(void) { - int x, y, num; - u8 z; - vdp1cmd_struct cmd; - pvr_sprite_txr_t sprite; - pvr_list_t list; - - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - x = Vdp1Regs->localX + cmd.CMDXA; - y = Vdp1Regs->localY + cmd.CMDYA; - cur_spr.w = ((cmd.CMDSIZE >> 8) & 0x3F) << 3; - cur_spr.h = cmd.CMDSIZE & 0xFF; - - if ((cmd.CMDPMOD & 0x07) == 0x03) { - list = PVR_LIST_TR_POLY; - num = Vdp1ReadTexture(&cmd, &tr_sprite_hdr); - - if(num == 0) - return; - else - pvr_list_prim(PVR_LIST_TR_POLY, &tr_sprite_hdr, - sizeof(pvr_sprite_hdr_t)); - } - else { - num = Vdp1ReadTexture(&cmd, &pt_sprite_hdr); - list = PVR_LIST_PT_POLY; - - if(num == 0) - return; - else - pvr_list_prim(PVR_LIST_PT_POLY, &pt_sprite_hdr, - sizeof(pvr_sprite_hdr_t)); - } - - z = Vdp1ReadPriority(&cmd); - - sprite.flags = PVR_CMD_VERTEX_EOL; - sprite.ax = x; - sprite.ay = y; - sprite.az = priority_levels[z]; - - sprite.bx = x + cur_spr.w; - sprite.by = y; - sprite.bz = priority_levels[z]; - - sprite.cx = x + cur_spr.w; - sprite.cy = y + cur_spr.h; - sprite.cz = priority_levels[z]; - - sprite.dx = x; - sprite.dy = y + cur_spr.h; - - sprite.auv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? cur_spr.uf : 0.0f), - ((cmd.CMDCTRL & 0x0020) ? cur_spr.vf : 0.0f)); - sprite.buv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? 0.0f : cur_spr.uf), - ((cmd.CMDCTRL & 0x0020) ? cur_spr.vf : 0.0f)); - sprite.cuv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? 0.0f : cur_spr.uf), - ((cmd.CMDCTRL & 0x0020) ? 0.0f : cur_spr.vf)); - pvr_list_prim(list, &sprite, sizeof(sprite)); - - priority_levels[z] += 0.000001f; -} - -static void VIDDCVdp1ScaledSpriteDraw(void) { - vdp1cmd_struct cmd; - s16 rw = 0, rh = 0; - s16 x, y; - u8 z; - pvr_sprite_txr_t sprite; - pvr_list_t list; - int num; - - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - x = cmd.CMDXA + Vdp1Regs->localX; - y = cmd.CMDYA + Vdp1Regs->localY; - cur_spr.w = ((cmd.CMDSIZE >> 8) & 0x3F) * 8; - cur_spr.h = cmd.CMDSIZE & 0xFF; - - if((cmd.CMDPMOD & 0x07) == 0x03) { - list = PVR_LIST_TR_POLY; - num = Vdp1ReadTexture(&cmd, &tr_sprite_hdr); - - if(num == 0) - return; - else - pvr_list_prim(PVR_LIST_TR_POLY, &tr_sprite_hdr, - sizeof(pvr_sprite_hdr_t)); - } - else { - num = Vdp1ReadTexture(&cmd, &pt_sprite_hdr); - list = PVR_LIST_PT_POLY; - - if(num == 0) - return; - else - pvr_list_prim(PVR_LIST_PT_POLY, &pt_sprite_hdr, - sizeof(pvr_sprite_hdr_t)); - } - - // Setup Zoom Point - switch ((cmd.CMDCTRL & 0xF00) >> 8) { - case 0x0: // Only two coordinates - rw = cmd.CMDXC - x + Vdp1Regs->localX + 1; - rh = cmd.CMDYC - y + Vdp1Regs->localY + 1; - break; - case 0x5: // Upper-left - rw = cmd.CMDXB + 1; - rh = cmd.CMDYB + 1; - break; - case 0x6: // Upper-Center - rw = cmd.CMDXB; - rh = cmd.CMDYB; - x = x - rw / 2; - ++rw; - ++rh; - break; - case 0x7: // Upper-Right - rw = cmd.CMDXB; - rh = cmd.CMDYB; - x = x - rw; - ++rw; - ++rh; - break; - case 0x9: // Center-left - rw = cmd.CMDXB; - rh = cmd.CMDYB; - y = y - rh / 2; - ++rw; - ++rh; - break; - case 0xA: // Center-center - rw = cmd.CMDXB; - rh = cmd.CMDYB; - x = x - rw / 2; - y = y - rh / 2; - ++rw; - ++rh; - break; - case 0xB: // Center-right - rw = cmd.CMDXB; - rh = cmd.CMDYB; - x = x - rw; - y = y - rh / 2; - ++rw; - ++rh; - break; - case 0xD: // Lower-left - rw = cmd.CMDXB; - rh = cmd.CMDYB; - y = y - rh; - ++rw; - ++rh; - break; - case 0xE: // Lower-center - rw = cmd.CMDXB; - rh = cmd.CMDYB; - x = x - rw / 2; - y = y - rh; - ++rw; - ++rh; - break; - case 0xF: // Lower-right - rw = cmd.CMDXB; - rh = cmd.CMDYB; - x = x - rw; - y = y - rh; - ++rw; - ++rh; - break; - default: - break; - } - - z = Vdp1ReadPriority(&cmd); - - sprite.flags = PVR_CMD_VERTEX_EOL; - sprite.ax = x; - sprite.ay = y; - sprite.az = priority_levels[z]; - - sprite.bx = x + rw; - sprite.by = y; - sprite.bz = priority_levels[z]; - - sprite.cx = x + rw; - sprite.cy = y + rh; - sprite.cz = priority_levels[z]; - - sprite.dx = x; - sprite.dy = y + rh; - - sprite.auv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? cur_spr.uf : 0.0f), - ((cmd.CMDCTRL & 0x0020) ? cur_spr.vf : 0.0f)); - sprite.buv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? 0.0f : cur_spr.uf), - ((cmd.CMDCTRL & 0x0020) ? cur_spr.vf : 0.0f)); - sprite.cuv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? 0.0f : cur_spr.uf), - ((cmd.CMDCTRL & 0x0020) ? 0.0f : cur_spr.vf)); - pvr_list_prim(list, &sprite, sizeof(sprite)); - - priority_levels[z] += 0.000001f; -} - -static void VIDDCVdp1DistortedSpriteDraw(void) { - vdp1cmd_struct cmd; - u8 z; - pvr_sprite_txr_t sprite; - pvr_list_t list; - int num; - - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - cur_spr.w = ((cmd.CMDSIZE >> 8) & 0x3F) * 8; - cur_spr.h = cmd.CMDSIZE & 0xFF; - - if((cmd.CMDPMOD & 0x7) == 0x3) { - list = PVR_LIST_TR_POLY; - num = Vdp1ReadTexture(&cmd, &tr_sprite_hdr); - - if(num == 0) - return; - else - pvr_list_prim(PVR_LIST_TR_POLY, &tr_sprite_hdr, - sizeof(pvr_sprite_hdr_t)); - } - else { - num = Vdp1ReadTexture(&cmd, &pt_sprite_hdr); - list = PVR_LIST_PT_POLY; - - if(num == 0) - return; - else - pvr_list_prim(PVR_LIST_PT_POLY, &pt_sprite_hdr, - sizeof(pvr_sprite_hdr_t)); - } - - z = Vdp1ReadPriority(&cmd); - - sprite.flags = PVR_CMD_VERTEX_EOL; - sprite.ax = cmd.CMDXA + Vdp1Regs->localX; - sprite.ay = cmd.CMDYA + Vdp1Regs->localY; - sprite.az = priority_levels[z]; - - sprite.bx = cmd.CMDXB + Vdp1Regs->localX + 1; - sprite.by = cmd.CMDYB + Vdp1Regs->localY; - sprite.bz = priority_levels[z]; - - sprite.cx = cmd.CMDXC + Vdp1Regs->localX + 1; - sprite.cy = cmd.CMDYC + Vdp1Regs->localY + 1; - sprite.cz = priority_levels[z]; - - sprite.dx = cmd.CMDXD + Vdp1Regs->localX; - sprite.dy = cmd.CMDYD + Vdp1Regs->localY + 1; - - sprite.auv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? cur_spr.uf : 0.0f), - ((cmd.CMDCTRL & 0x0020) ? cur_spr.vf : 0.0f)); - sprite.buv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? 0.0f : cur_spr.uf), - ((cmd.CMDCTRL & 0x0020) ? cur_spr.vf : 0.0f)); - sprite.cuv = PVR_PACK_16BIT_UV(((cmd.CMDCTRL & 0x0010) ? 0.0f : cur_spr.uf), - ((cmd.CMDCTRL & 0x0020) ? 0.0f : cur_spr.vf)); - pvr_list_prim(list, &sprite, sizeof(sprite)); - - priority_levels[z] += 0.000001f; -} - -static void VIDDCVdp1PolygonDraw(void) { - s16 X[4]; - s16 Y[4]; - u16 color; - u16 CMDPMOD; - u8 alpha, z; - pvr_list_t list; - pvr_sprite_col_t spr; - pvr_sprite_hdr_t *hdr; - - X[0] = Vdp1Regs->localX + T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0C); - Y[0] = Vdp1Regs->localY + T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0E); - X[1] = Vdp1Regs->localX + T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x10); - Y[1] = Vdp1Regs->localY + T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x12); - X[2] = Vdp1Regs->localX + T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x14); - Y[2] = Vdp1Regs->localY + T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x16); - X[3] = Vdp1Regs->localX + T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x18); - Y[3] = Vdp1Regs->localY + T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x1A); - - color = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x06); - CMDPMOD = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x04); - - /* Don't bother rendering completely transparent polygons */ - if((!(color & 0x8000) && !(CMDPMOD & 0x0040)) || !color) { - return; - } - - if((CMDPMOD & 0x0007) == 0x0003) { - alpha = 0x80; - list = PVR_LIST_TR_POLY; - hdr = &tr_poly_hdr; - } - else { - alpha = 0xFF; - list = PVR_LIST_OP_POLY; - hdr = &op_poly_hdr; - } - - if(color & 0x8000) { - hdr->argb = COLOR_ADD32(SAT2YAB32(alpha, color), vdp1cor, vdp1cog, - vdp1cob); - } - else { - hdr->argb = COLOR_ADD32(Vdp2ColorRamGetColor32(color, alpha), vdp1cor, - vdp1cog, vdp1cob); - } - - pvr_list_prim(list, hdr, sizeof(pvr_sprite_hdr_t)); - - z = Vdp2Regs->PRISA & 0x07; - - spr.flags = PVR_CMD_VERTEX_EOL; - spr.d1 = spr.d2 = spr.d3 = spr.d4 = 0; - spr.az = spr.bz = spr.cz = priority_levels[z]; - - spr.ax = X[0]; - spr.ay = Y[0]; - spr.bx = X[1]; - spr.by = Y[1]; - spr.cx = X[2]; - spr.cy = Y[2]; - spr.dx = X[3]; - spr.dy = Y[3]; - - pvr_list_prim(list, &spr, sizeof(pvr_sprite_col_t)); - - priority_levels[z] += 0.000001f; -} - -static void VIDDCVdp1PolylineDraw(void) { -} - -static void VIDDCVdp1LineDraw(void) { -} - -static void VIDDCVdp1UserClipping(void) { - Vdp1Regs->userclipX1 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0C); - Vdp1Regs->userclipY1 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0E); - Vdp1Regs->userclipX2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x14); - Vdp1Regs->userclipY2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x16); -} - -static void VIDDCVdp1SystemClipping(void) { - Vdp1Regs->systemclipX1 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0C); - Vdp1Regs->systemclipY1 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0E); - Vdp1Regs->systemclipX2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x14); - Vdp1Regs->systemclipY2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x16); -} - -static void VIDDCVdp1LocalCoordinate(void) { - Vdp1Regs->localX = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0C); - Vdp1Regs->localY = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x0E); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 DoNothing(void *info, u16 pixel) -{ - return pixel; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 DoColorOffset(void *info, u16 pixel) -{ - return COLOR_ADD(pixel, ((vdp2draw_struct *)info)->cor, - ((vdp2draw_struct *)info)->cog, - ((vdp2draw_struct *)info)->cob); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 DoColorCalc(void *info, u16 pixel) -{ - // should be doing color calculation here - return pixel; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 DoColorCalcWithColorOffset(void *info, u16 pixel) -{ - // should be doing color calculation here - - return COLOR_ADD(pixel, ((vdp2draw_struct *)info)->cor, - ((vdp2draw_struct *)info)->cog, - ((vdp2draw_struct *)info)->cob); -} - -static void Vdp2DrawBackScreen() { - u32 scrAddr; - u16 dot; - pvr_sprite_col_t spr; - - if(Vdp2Regs->VRSIZE & 0x8000) - scrAddr = (((Vdp2Regs->BKTAU & 0x07) << 16) | Vdp2Regs->BKTAL) << 1; - else - scrAddr = (((Vdp2Regs->BKTAU & 0x03) << 16) | Vdp2Regs->BKTAL) << 1; - - if(Vdp2Regs->BKTAU & 0x8000) { - int i; - - for(i = 0; i < vdp2height; ++i) { - dot = T1ReadWord(Vdp2Ram, scrAddr); - scrAddr += 2; - - op_poly_hdr.argb = SAT2YAB32(0xFF, dot); - pvr_list_prim(PVR_LIST_OP_POLY, &op_poly_hdr, - sizeof(pvr_sprite_hdr_t)); - - spr.flags = PVR_CMD_VERTEX_EOL; - spr.ax = 0.0f; - spr.ay = i + 1; - spr.az = 0.1f; - spr.bx = 0.0f; - spr.by = i; - spr.bz = 0.1f; - spr.cx = vdp2width; - spr.cy = i; - spr.cz = 0.1f; - spr.dx = vdp2width; - spr.dy = i + 1; - spr.d1 = spr.d2 = spr.d3 = spr.d4 = 0; - pvr_list_prim(PVR_LIST_OP_POLY, &spr, sizeof(pvr_sprite_col_t)); - } - } - else { - dot = T1ReadWord(Vdp2Ram, scrAddr); - - op_poly_hdr.argb = SAT2YAB32(0xFF, dot); - pvr_list_prim(PVR_LIST_OP_POLY, &op_poly_hdr, sizeof(pvr_sprite_hdr_t)); - - spr.flags = PVR_CMD_VERTEX_EOL; - spr.ax = 0.0f; - spr.ay = vdp2height; - spr.az = 0.1f; - spr.bx = 0.0f; - spr.by = 0.0f; - spr.bz = 0.1f; - spr.cx = vdp2width; - spr.cy = 0.0f; - spr.cz = 0.1f; - spr.dx = vdp2width; - spr.dy = vdp2height; - spr.d1 = spr.d2 = spr.d3 = spr.d4 = 0; - pvr_list_prim(PVR_LIST_OP_POLY, &spr, sizeof(pvr_sprite_col_t)); - } -} - -static void Vdp2DrawLineColorScreen() { -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2NBG0PlaneAddr(vdp2draw_struct *info, int i) -{ - u32 offset = (Vdp2Regs->MPOFN & 0x7) << 6; - u32 tmp=0; - int deca; - int multi; - - switch(i) - { - case 0: - tmp = offset | (Vdp2Regs->MPABN0 & 0xFF); - break; - case 1: - tmp = offset | (Vdp2Regs->MPABN0 >> 8); - break; - case 2: - tmp = offset | (Vdp2Regs->MPCDN0 & 0xFF); - break; - case 3: - tmp = offset | (Vdp2Regs->MPCDN0 >> 8); - break; - } - - deca = info->planeh + info->planew - 2; - multi = info->planeh * info->planew; - - //if (Vdp2Regs->VRSIZE & 0x8000) - //{ - if (info->patterndatasize == 1) - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x2000); - else - info->addr = (tmp >> deca) * (multi * 0x800); - } - else - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x4000); - else - info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x1000); - } - /*} - else - { - if (info->patterndatasize == 1) - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x2000); - else - info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x800); - } - else - { - if (info->patternwh == 1) - info->addr = ((tmp & 0xF) >> deca) * (multi * 0x4000); - else - info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x1000); - } - }*/ -} - -////////////////////////////////////////////////////////////////////////////// - -static int Vdp2DrawNBG0(void) -{ - vdp2draw_struct info; - - /* FIXME should start by checking if it's a normal - * or rotate scroll screen - */ - info.enable = Vdp2Regs->BGON & 0x1; - - if (!(info.enable & Vdp2External.disptoggle)) - return 0; - - info.transparencyenable = !(Vdp2Regs->BGON & 0x100); - info.specialprimode = Vdp2Regs->SFPRMD & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLA & 0x70) >> 4; - - if((info.isbitmap = Vdp2Regs->CHCTLA & 0x2) != 0) - { - // Bitmap Mode - - switch((Vdp2Regs->CHCTLA & 0xC) >> 2) - { - case 0: info.cellw = 512; - info.cellh = 256; - break; - case 1: info.cellw = 512; - info.cellh = 512; - break; - case 2: info.cellw = 1024; - info.cellh = 256; - break; - case 3: info.cellw = 1024; - info.cellh = 512; - break; - } - - info.x = - ((Vdp2Regs->SCXIN0 & 0x7FF) % info.cellw); - info.y = - ((Vdp2Regs->SCYIN0 & 0x7FF) % info.cellh); - - info.charaddr = (Vdp2Regs->MPOFN & 0x7) * 0x20000; - info.paladdr = (Vdp2Regs->BMPNA & 0x7) << 8; - info.flipfunction = 0; - info.specialfunction = 0; - } - else - { - // Tile Mode - info.mapwh = 2; - - switch(Vdp2Regs->PLSZ & 0x3) - { - case 0: - info.planew = info.planeh = 1; - break; - case 1: - info.planew = 2; - info.planeh = 1; - break; - case 3: - info.planew = info.planeh = 2; - break; - default: // Not sure what 0x2 does - info.planew = info.planeh = 1; - break; - } - - info.x = - ((Vdp2Regs->SCXIN0 & 0x7FF) % (512 * info.planew)); - info.y = - ((Vdp2Regs->SCYIN0 & 0x7FF) % (512 * info.planeh)); - - if(Vdp2Regs->PNCN0 & 0x8000) - info.patterndatasize = 1; - else - info.patterndatasize = 2; - - if(Vdp2Regs->CHCTLA & 0x1) - info.patternwh = 2; - else - info.patternwh = 1; - - info.pagewh = 64/info.patternwh; - info.cellw = info.cellh = 8; - info.supplementdata = Vdp2Regs->PNCN0 & 0x3FF; - info.auxmode = (Vdp2Regs->PNCN0 & 0x4000) >> 14; - } - - if (Vdp2Regs->CCCTL & 0x1) - info.alpha = ((~Vdp2Regs->CCRNA & 0x1F) << 3) + 0x7; - else - info.alpha = 0xFF; - - info.coloroffset = (Vdp2Regs->CRAOFA & 0x7) << 8; - - if (Vdp2Regs->CLOFEN & 0x1) - { - // color offset enable - if (Vdp2Regs->CLOFSL & 0x1) - { - // color offset B - info.cor = Vdp2Regs->COBR & 0xFF; - if (Vdp2Regs->COBR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COBG & 0xFF; - if (Vdp2Regs->COBG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COBB & 0xFF; - if (Vdp2Regs->COBB & 0x100) - info.cob |= 0xFFFFFF00; - } - else - { - // color offset A - info.cor = Vdp2Regs->COAR & 0xFF; - if (Vdp2Regs->COAR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COAG & 0xFF; - if (Vdp2Regs->COAG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COAB & 0xFF; - if (Vdp2Regs->COAB & 0x100) - info.cob |= 0xFFFFFF00; - } - - if (Vdp2Regs->CCCTL & 0x1) - info.PostPixelFetchCalc = &DoColorCalcWithColorOffset; - else - info.PostPixelFetchCalc = &DoColorOffset; - } - else // color offset disable - { - if (Vdp2Regs->CCCTL & 0x1) - info.PostPixelFetchCalc = &DoColorCalc; - else - info.PostPixelFetchCalc = &DoNothing; - } - - info.coordincx = (float) 65536 / (Vdp2Regs->ZMXN0.all & 0x7FF00); - info.coordincy = (float) 65536 / (Vdp2Regs->ZMYN0.all & 0x7FF00); - - info.priority = nbg0priority; - info.PlaneAddr = (void (*)(void *, int))&Vdp2NBG0PlaneAddr; - - if (info.isbitmap) - Vdp2DrawScrollBitmap(&info); - else - Vdp2DrawMap(&info); - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2NBG1PlaneAddr(vdp2draw_struct *info, int i) -{ - u32 offset = (Vdp2Regs->MPOFN & 0x70) << 2; - u32 tmp=0; - int deca; - int multi; - - switch(i) - { - case 0: - tmp = offset | (Vdp2Regs->MPABN1 & 0xFF); - break; - case 1: - tmp = offset | (Vdp2Regs->MPABN1 >> 8); - break; - case 2: - tmp = offset | (Vdp2Regs->MPCDN1 & 0xFF); - break; - case 3: - tmp = offset | (Vdp2Regs->MPCDN1 >> 8); - break; - } - - deca = info->planeh + info->planew - 2; - multi = info->planeh * info->planew; - - //if (Vdp2Regs->VRSIZE & 0x8000) - //{ - if (info->patterndatasize == 1) - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x2000); - else - info->addr = (tmp >> deca) * (multi * 0x800); - } - else - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x4000); - else - info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x1000); - } - /*} - else - { - if (info->patterndatasize == 1) - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x2000); - else - info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x800); - } - else - { - if (info->patternwh == 1) - info->addr = ((tmp & 0xF) >> deca) * (multi * 0x4000); - else - info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x1000); - } - }*/ -} - -////////////////////////////////////////////////////////////////////////////// - -static int Vdp2DrawNBG1(void) -{ - vdp2draw_struct info; - - info.enable = Vdp2Regs->BGON & 0x2; - - if (!(info.enable & Vdp2External.disptoggle)) - return 0; - - info.transparencyenable = !(Vdp2Regs->BGON & 0x200); - info.specialprimode = (Vdp2Regs->SFPRMD >> 2) & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLA & 0x3000) >> 12; - - if((info.isbitmap = Vdp2Regs->CHCTLA & 0x200) != 0) - { - switch((Vdp2Regs->CHCTLA & 0xC00) >> 10) - { - case 0: info.cellw = 512; - info.cellh = 256; - break; - case 1: info.cellw = 512; - info.cellh = 512; - break; - case 2: info.cellw = 1024; - info.cellh = 256; - break; - case 3: info.cellw = 1024; - info.cellh = 512; - break; - } - - info.x = - ((Vdp2Regs->SCXIN1 & 0x7FF) % info.cellw); - info.y = - ((Vdp2Regs->SCYIN1 & 0x7FF) % info.cellh); - - info.charaddr = ((Vdp2Regs->MPOFN & 0x70) >> 4) * 0x20000; - info.paladdr = Vdp2Regs->BMPNA & 0x700; - info.flipfunction = 0; - info.specialfunction = 0; - } - else - { - info.mapwh = 2; - - switch((Vdp2Regs->PLSZ & 0xC) >> 2) - { - case 0: - info.planew = info.planeh = 1; - break; - case 1: - info.planew = 2; - info.planeh = 1; - break; - case 3: - info.planew = info.planeh = 2; - break; - default: // Not sure what 0x2 does - info.planew = info.planeh = 1; - break; - } - - info.x = - ((Vdp2Regs->SCXIN1 & 0x7FF) % (512 * info.planew)); - info.y = - ((Vdp2Regs->SCYIN1 & 0x7FF) % (512 * info.planeh)); - - if(Vdp2Regs->PNCN1 & 0x8000) - info.patterndatasize = 1; - else - info.patterndatasize = 2; - - if(Vdp2Regs->CHCTLA & 0x100) - info.patternwh = 2; - else - info.patternwh = 1; - - info.pagewh = 64/info.patternwh; - info.cellw = info.cellh = 8; - info.supplementdata = Vdp2Regs->PNCN1 & 0x3FF; - info.auxmode = (Vdp2Regs->PNCN1 & 0x4000) >> 14; - } - - if (Vdp2Regs->CCCTL & 0x2) - info.alpha = ((~Vdp2Regs->CCRNA & 0x1F00) >> 5) + 0x7; - else - info.alpha = 0xFF; - - info.coloroffset = (Vdp2Regs->CRAOFA & 0x70) << 4; - - if (Vdp2Regs->CLOFEN & 0x2) - { - // color offset enable - if (Vdp2Regs->CLOFSL & 0x2) - { - // color offset B - info.cor = Vdp2Regs->COBR & 0xFF; - if (Vdp2Regs->COBR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COBG & 0xFF; - if (Vdp2Regs->COBG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COBB & 0xFF; - if (Vdp2Regs->COBB & 0x100) - info.cob |= 0xFFFFFF00; - } - else - { - // color offset A - info.cor = Vdp2Regs->COAR & 0xFF; - if (Vdp2Regs->COAR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COAG & 0xFF; - if (Vdp2Regs->COAG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COAB & 0xFF; - if (Vdp2Regs->COAB & 0x100) - info.cob |= 0xFFFFFF00; - } - - if (Vdp2Regs->CCCTL & 0x2) - info.PostPixelFetchCalc = &DoColorCalcWithColorOffset; - else - info.PostPixelFetchCalc = &DoColorOffset; - } - else // color offset disable - { - if (Vdp2Regs->CCCTL & 0x2) - info.PostPixelFetchCalc = &DoColorCalc; - else - info.PostPixelFetchCalc = &DoNothing; - } - - info.coordincx = (float) 65536 / (Vdp2Regs->ZMXN1.all & 0x7FF00); - info.coordincy = (float) 65536 / (Vdp2Regs->ZMXN1.all & 0x7FF00); - - info.priority = nbg1priority; - info.PlaneAddr = (void (*)(void *, int))&Vdp2NBG1PlaneAddr; - - if (info.isbitmap) - { - Vdp2DrawScrollBitmap(&info); -/* - // Handle Scroll Wrapping(Let's see if we even need do to it to begin - // with) - if (info.x < (vdp2width - info.cellw)) - { - info.vertices[0] = (info.x+info.cellw) * info.coordincx; - info.vertices[2] = (info.x + (info.cellw<<1)) * info.coordincx; - info.vertices[4] = (info.x + (info.cellw<<1)) * info.coordincx; - info.vertices[6] = (info.x+info.cellw) * info.coordincx; - - YglCachedQuad((YglSprite *)&info, tmp); - - if (info.y < (vdp2height - info.cellh)) - { - info.vertices[1] = (info.y+info.cellh) * info.coordincy; - info.vertices[3] = (info.y + (info.cellh<<1)) * info.coordincy; - info.vertices[5] = (info.y + (info.cellh<<1)) * info.coordincy; - info.vertices[7] = (info.y+info.cellh) * info.coordincy; - - YglCachedQuad((YglSprite *)&info, tmp); - } - } - else if (info.y < (vdp2height - info.cellh)) - { - info.vertices[1] = (info.y+info.cellh) * info.coordincy; - info.vertices[3] = (info.y + (info.cellh<<1)) * info.coordincy; - info.vertices[5] = (info.y + (info.cellh<<1)) * info.coordincy; - info.vertices[7] = (info.y+info.cellh) * info.coordincy; - - YglCachedQuad((YglSprite *)&info, tmp); - } -*/ - } - else - Vdp2DrawMap(&info); - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2NBG2PlaneAddr(vdp2draw_struct *info, int i) -{ - u32 offset = (Vdp2Regs->MPOFN & 0x700) >> 2; - u32 tmp=0; - int deca; - int multi; - - switch(i) - { - case 0: - tmp = offset | (Vdp2Regs->MPABN2 & 0xFF); - break; - case 1: - tmp = offset | (Vdp2Regs->MPABN2 >> 8); - break; - case 2: - tmp = offset | (Vdp2Regs->MPCDN2 & 0xFF); - break; - case 3: - tmp = offset | (Vdp2Regs->MPCDN2 >> 8); - break; - } - - deca = info->planeh + info->planew - 2; - multi = info->planeh * info->planew; - - //if (Vdp2Regs->VRSIZE & 0x8000) - //{ - if (info->patterndatasize == 1) - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x2000); - else - info->addr = (tmp >> deca) * (multi * 0x800); - } - else - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x4000); - else - info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x1000); - } - /*} - else - { - if (info->patterndatasize == 1) - { - if (info->patternwh == 1) - info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x2000); - else - info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x800); - } - else - { - if (info->patternwh == 1) - info->addr = ((tmp & 0xF) >> deca) * (multi * 0x4000); - else - info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x1000); - } - }*/ -} - -////////////////////////////////////////////////////////////////////////////// - -static int Vdp2DrawNBG2(void) -{ - vdp2draw_struct info; - - info.enable = Vdp2Regs->BGON & 0x4; - - if (!(info.enable & Vdp2External.disptoggle)) - return 0; - - info.transparencyenable = !(Vdp2Regs->BGON & 0x400); - info.specialprimode = (Vdp2Regs->SFPRMD >> 4) & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLB & 0x2) >> 1; - info.mapwh = 2; - - switch((Vdp2Regs->PLSZ & 0x30) >> 4) - { - case 0: - info.planew = info.planeh = 1; - break; - case 1: - info.planew = 2; - info.planeh = 1; - break; - case 3: - info.planew = info.planeh = 2; - break; - default: // Not sure what 0x2 does - info.planew = info.planeh = 1; - break; - } - info.x = - ((Vdp2Regs->SCXN2 & 0x7FF) % (512 * info.planew)); - info.y = - ((Vdp2Regs->SCYN2 & 0x7FF) % (512 * info.planeh)); - - if(Vdp2Regs->PNCN2 & 0x8000) - info.patterndatasize = 1; - else - info.patterndatasize = 2; - - if(Vdp2Regs->CHCTLB & 0x1) - info.patternwh = 2; - else - info.patternwh = 1; - - info.pagewh = 64/info.patternwh; - info.cellw = info.cellh = 8; - info.supplementdata = Vdp2Regs->PNCN2 & 0x3FF; - info.auxmode = (Vdp2Regs->PNCN2 & 0x4000) >> 14; - - if (Vdp2Regs->CCCTL & 0x4) - info.alpha = ((~Vdp2Regs->CCRNB & 0x1F) << 3) + 0x7; - else - info.alpha = 0xFF; - - info.coloroffset = Vdp2Regs->CRAOFA & 0x700; - - if (Vdp2Regs->CLOFEN & 0x4) - { - // color offset enable - if (Vdp2Regs->CLOFSL & 0x4) - { - // color offset B - info.cor = Vdp2Regs->COBR & 0xFF; - if (Vdp2Regs->COBR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COBG & 0xFF; - if (Vdp2Regs->COBG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COBB & 0xFF; - if (Vdp2Regs->COBB & 0x100) - info.cob |= 0xFFFFFF00; - } - else - { - // color offset A - info.cor = Vdp2Regs->COAR & 0xFF; - if (Vdp2Regs->COAR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COAG & 0xFF; - if (Vdp2Regs->COAG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COAB & 0xFF; - if (Vdp2Regs->COAB & 0x100) - info.cob |= 0xFFFFFF00; - } - - if (Vdp2Regs->CCCTL & 0x4) - info.PostPixelFetchCalc = &DoColorCalcWithColorOffset; - else - info.PostPixelFetchCalc = &DoColorOffset; - } - else // color offset disable - { - if (Vdp2Regs->CCCTL & 0x4) - info.PostPixelFetchCalc = &DoColorCalc; - else - info.PostPixelFetchCalc = &DoNothing; - } - - info.coordincx = info.coordincy = 1; - - info.priority = nbg2priority; - info.PlaneAddr = (void (*)(void *, int))&Vdp2NBG2PlaneAddr; - - Vdp2DrawMap(&info); - - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -static void Vdp2NBG3PlaneAddr(vdp2draw_struct *info, int i) -{ - u32 offset = (Vdp2Regs->MPOFN & 0x7000) >> 6; - u32 tmp=0; - int deca; - int multi; - - switch(i) - { - case 0: - tmp = offset | (Vdp2Regs->MPABN3 & 0xFF); - break; - case 1: - tmp = offset | (Vdp2Regs->MPABN3 >> 8); - break; - case 2: - tmp = offset | (Vdp2Regs->MPCDN3 & 0xFF); - break; - case 3: - tmp = offset | (Vdp2Regs->MPCDN3 >> 8); - break; - } - - deca = info->planeh + info->planew - 2; - multi = info->planeh * info->planew; - - //if (Vdp2Regs->VRSIZE & 0x8000) { - if (info->patterndatasize == 1) { - if (info->patternwh == 1) - info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x2000); - else - info->addr = (tmp >> deca) * (multi * 0x800); - } - else { - if (info->patternwh == 1) - info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x4000); - else - info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x1000); - } - /*} - else { - if (info->patterndatasize == 1) { - if (info->patternwh == 1) - info->addr = ((tmp & 0x1F) >> deca) * (multi * 0x2000); - else - info->addr = ((tmp & 0x7F) >> deca) * (multi * 0x800); - } - else { - if (info->patternwh == 1) - info->addr = ((tmp & 0xF) >> deca) * (multi * 0x4000); - else - info->addr = ((tmp & 0x3F) >> deca) * (multi * 0x1000); - } - }*/ -} - -////////////////////////////////////////////////////////////////////////////// - -static int Vdp2DrawNBG3(void) -{ - vdp2draw_struct info; - - info.enable = Vdp2Regs->BGON & 0x8; - - if (!(info.enable & Vdp2External.disptoggle)) - return 0; - - info.transparencyenable = !(Vdp2Regs->BGON & 0x800); - info.specialprimode = (Vdp2Regs->SFPRMD >> 6) & 0x3; - - info.colornumber = (Vdp2Regs->CHCTLB & 0x20) >> 5; - - info.mapwh = 2; - - switch((Vdp2Regs->PLSZ & 0xC0) >> 6) - { - case 0: - info.planew = info.planeh = 1; - break; - case 1: - info.planew = 2; - info.planeh = 1; - break; - case 3: - info.planew = info.planeh = 2; - break; - default: // Not sure what 0x2 does - info.planew = info.planeh = 1; - break; - } - info.x = - ((Vdp2Regs->SCXN3 & 0x7FF) % (512 * info.planew)); - info.y = - ((Vdp2Regs->SCYN3 & 0x7FF) % (512 * info.planeh)); - - if(Vdp2Regs->PNCN3 & 0x8000) - info.patterndatasize = 1; - else - info.patterndatasize = 2; - - if(Vdp2Regs->CHCTLB & 0x10) - info.patternwh = 2; - else - info.patternwh = 1; - - info.pagewh = 64/info.patternwh; - info.cellw = info.cellh = 8; - info.supplementdata = Vdp2Regs->PNCN3 & 0x3FF; - info.auxmode = (Vdp2Regs->PNCN3 & 0x4000) >> 14; - - if (Vdp2Regs->CCCTL & 0x8) - info.alpha = ((~Vdp2Regs->CCRNB & 0x1F00) >> 5) + 0x7; - else - info.alpha = 0xFF; - - info.coloroffset = (Vdp2Regs->CRAOFA & 0x7000) >> 4; - - if (Vdp2Regs->CLOFEN & 0x8) - { - // color offset enable - if (Vdp2Regs->CLOFSL & 0x8) - { - // color offset B - info.cor = Vdp2Regs->COBR & 0xFF; - if (Vdp2Regs->COBR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COBG & 0xFF; - if (Vdp2Regs->COBG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COBB & 0xFF; - if (Vdp2Regs->COBB & 0x100) - info.cob |= 0xFFFFFF00; - } - else - { - // color offset A - info.cor = Vdp2Regs->COAR & 0xFF; - if (Vdp2Regs->COAR & 0x100) - info.cor |= 0xFFFFFF00; - - info.cog = Vdp2Regs->COAG & 0xFF; - if (Vdp2Regs->COAG & 0x100) - info.cog |= 0xFFFFFF00; - - info.cob = Vdp2Regs->COAB & 0xFF; - if (Vdp2Regs->COAB & 0x100) - info.cob |= 0xFFFFFF00; - } - - if (Vdp2Regs->CCCTL & 0x8) - info.PostPixelFetchCalc = &DoColorCalcWithColorOffset; - else - info.PostPixelFetchCalc = &DoColorOffset; - } - else // color offset disable - { - if (Vdp2Regs->CCCTL & 0x8) - info.PostPixelFetchCalc = &DoColorCalc; - else - info.PostPixelFetchCalc = &DoNothing; - } - - info.coordincx = info.coordincy = 1; - - info.priority = nbg3priority; - info.PlaneAddr = (void (*)(void *, int))&Vdp2NBG3PlaneAddr; - - Vdp2DrawMap(&info); - - return 1; -} - -static int VIDDCVdp2Reset(void) { - return 0; -} - -static void VIDDCVdp2DrawStart(void) { - cur_addr = (uint32) tex_space; - cur_vdp2 = (uint32) vdp2_tex; - - pvr_wait_ready(); - pvr_scene_begin(); - - Vdp2DrawBackScreen(); - Vdp2DrawLineColorScreen(); -} - -static void VIDDCVdp2DrawEnd(void) { - /* Make sure we don't have any texture dma still going on... */ - sem_wait(dmadone); - sem_signal(dmadone); - - pvr_scene_finish(); - - ++framecount; - - if(lastup + 10 <= time(NULL)) { - printf("%d frames in %d seconds FPS: %f\n", framecount, time(NULL) - - lastup, ((float)(framecount)) / (time(NULL) - lastup)); - framecount = 0; - lastup = time(NULL); - } -} - -static void dma_callback(ptr_t data __attribute__((unused))) { - sem_signal(dmadone); -} - -static void Vdp2Draw(int priority) { - pvr_sprite_txr_t sprite; - - pt_sprite_hdr.mode2 &= (~(PVR_TA_PM2_USIZE_MASK | PVR_TA_PM2_VSIZE_MASK)); - pt_sprite_hdr.mode2 |= (6 << PVR_TA_PM2_USIZE_SHIFT) | - (5 << PVR_TA_PM2_VSIZE_SHIFT); - pt_sprite_hdr.mode3 = ((cur_vdp2 & 0x00FFFFF8) >> 3) | - (PVR_TXRFMT_NONTWIDDLED); - - pvr_list_prim(PVR_LIST_PT_POLY, &pt_sprite_hdr, sizeof(pvr_sprite_hdr_t)); - - sprite.flags = PVR_CMD_VERTEX_EOL; - sprite.ax = 0; - sprite.ay = 0; - sprite.az = priority_levels[priority]; - - sprite.bx = vdp2width; - sprite.by = 0; - sprite.bz = priority_levels[priority]; - - sprite.cx = vdp2width; - sprite.cy = vdp2height; - sprite.cz = priority_levels[priority]; - - sprite.dx = 0; - sprite.dy = vdp2height; - - sprite.auv = PVR_PACK_16BIT_UV(0.0f, 0.0f); - sprite.buv = PVR_PACK_16BIT_UV(vdp2width / 512.0f, 0.0f); - sprite.cuv = PVR_PACK_16BIT_UV(vdp2width / 512.0f, vdp2height / 256.0f); - pvr_list_prim(PVR_LIST_PT_POLY, &sprite, sizeof(pvr_sprite_txr_t)); - - priority_levels[priority] += 0.000001f; -} - -static void VIDDCVdp2DrawScreens(void) { - int i; - - vdp2_fb = vdp2_fbs[0]; - vdp2_fbnum = 0; - - for(i = 1; i < 8; i++) { - if(nbg3priority == i) { - if(Vdp2DrawNBG3()) { - dcache_flush_range((ptr_t)(vdp2_fb), 512 * 256 * 2); - sem_wait(dmadone); - - pvr_txr_load_dma(vdp2_fb, (pvr_ptr_t) cur_vdp2, 512 * 256 * 2, - 0, dma_callback, 0); - - Vdp2Draw(i); - - cur_vdp2 += 512 * 256 * 2; - vdp2_fbnum ^= 1; - vdp2_fb = vdp2_fbs[vdp2_fbnum]; - } - } - if(nbg2priority == i) { - if(Vdp2DrawNBG2()) { - dcache_flush_range((ptr_t)(vdp2_fb), 512 * 256 * 2); - sem_wait(dmadone); - - pvr_txr_load_dma(vdp2_fb, (pvr_ptr_t) cur_vdp2, 512 * 256 * 2, - 0, dma_callback, 0); - - Vdp2Draw(i); - - cur_vdp2 += 512 * 256 * 2; - vdp2_fbnum ^= 1; - vdp2_fb = vdp2_fbs[vdp2_fbnum]; - } - } - if(nbg1priority == i) { - if(Vdp2DrawNBG1()) { - dcache_flush_range((ptr_t)(vdp2_fb), 512 * 256 * 2); - sem_wait(dmadone); - - pvr_txr_load_dma(vdp2_fb, (pvr_ptr_t) cur_vdp2, 512 * 256 * 2, - 0, dma_callback, 0); - - Vdp2Draw(i); - - cur_vdp2 += 512 * 256 * 2; - vdp2_fbnum ^= 1; - vdp2_fb = vdp2_fbs[vdp2_fbnum]; - } - } - if(nbg0priority == i) { - if(Vdp2DrawNBG0()) { - dcache_flush_range((ptr_t)(vdp2_fb), 512 * 256 * 2); - sem_wait(dmadone); - - pvr_txr_load_dma(vdp2_fb, (pvr_ptr_t) cur_vdp2, 512 * 256 * 2, - 0, dma_callback, 0); - - Vdp2Draw(i); - - cur_vdp2 += 512 * 256 * 2; - vdp2_fbnum ^= 1; - vdp2_fb = vdp2_fbs[vdp2_fbnum]; - } - } -// if (rbg0priority == i) -// Vdp2DrawRBG0(); - } -} - -static void VIDDCVdp2SetResolution(u16 TVMD) { - int w = 0, h = 0; - - switch(TVMD & 0x03) { - case 0: - w = 320; - break; - case 1: - w = 352; - break; - case 2: - w = 640; - break; - case 3: - w = 704; - break; - } - - switch((TVMD >> 4) & 0x03) { - case 0: - h = 224; - break; - case 1: - h = 240; - break; - case 2: - h = 256; - break; - } - - switch((TVMD >> 6) & 0x03) { - case 2: - case 3: - h <<= 1; - default: - break; - } - - vdp2width = w; - vdp2height = h; - - if(w > 352 || h > 256) { - printf("Unsupported resolution set %d x %d\n", w, h); - printf("Bailing out!\n"); - exit(-1); - } -} - -static void VIDDCVdp2SetPriorityNBG0(int priority) { - nbg0priority = priority; -} - -static void VIDDCVdp2SetPriorityNBG1(int priority) { - nbg1priority = priority; -} - -static void VIDDCVdp2SetPriorityNBG2(int priority) { - nbg2priority = priority; -} - -static void VIDDCVdp2SetPriorityNBG3(int priority) { - nbg3priority = priority; -} - -static void VIDDCVdp2SetPriorityRBG0(int priority) { - rbg0priority = priority; -} - -VideoInterface_struct VIDDC = { - VIDCORE_DC, - "Dreamcast PVR Video Interface", - VIDDCInit, - VIDDCDeInit, - VIDDCResize, - VIDDCIsFullscreen, - VIDDCVdp1Reset, - VIDDCVdp1DrawStart, - VIDDCVdp1DrawEnd, - VIDDCVdp1NormalSpriteDraw, - VIDDCVdp1ScaledSpriteDraw, - VIDDCVdp1DistortedSpriteDraw, - VIDDCVdp1PolygonDraw, - VIDDCVdp1PolylineDraw, - VIDDCVdp1LineDraw, - VIDDCVdp1UserClipping, - VIDDCVdp1SystemClipping, - VIDDCVdp1LocalCoordinate, - VIDDCVdp2Reset, - VIDDCVdp2DrawStart, - VIDDCVdp2DrawEnd, - VIDDCVdp2DrawScreens, - VIDDCVdp2SetResolution, - VIDDCVdp2SetPriorityNBG0, - VIDDCVdp2SetPriorityNBG1, - VIDDCVdp2SetPriorityNBG2, - VIDDCVdp2SetPriorityNBG3, - VIDDCVdp2SetPriorityRBG0 -}; diff --git a/yabause/src/dreamcast/viddc.h b/yabause/src/dreamcast/viddc.h deleted file mode 100644 index e824200944..0000000000 --- a/yabause/src/dreamcast/viddc.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright 2005 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef VIDDC_H -#define VIDDC_H - -#include "../vdp1.h" - -#define VIDCORE_DC 3 -extern VideoInterface_struct VIDDC; - -#endif diff --git a/yabause/src/dreamcast/yui.c b/yabause/src/dreamcast/yui.c deleted file mode 100644 index 17762e09f2..0000000000 --- a/yabause/src/dreamcast/yui.c +++ /dev/null @@ -1,234 +0,0 @@ -/* Copyright 2003 Guillaume Duhamel - Copyright 2004-2010 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../yui.h" -#include "../peripheral.h" -#include "../cs0.h" -#include "../m68kcore.h" -#include "../m68kc68k.h" -#include "perdc.h" -#include "viddc.h" -#include "sh2rec/sh2rec.h" - -SH2Interface_struct *SH2CoreList[] = { - &SH2Interpreter, - &SH2Dynarec, - NULL -}; - -PerInterface_struct *PERCoreList[] = { - &PERDC, - NULL -}; - -CDInterface *CDCoreList[] = { - &ArchCD, - &DummyCD, - NULL -}; - -SoundInterface_struct *SNDCoreList[] = { - &SNDDummy, - NULL -}; - -VideoInterface_struct *VIDCoreList[] = { - &VIDDummy, - &VIDDC, - NULL -}; - -M68K_struct * M68KCoreList[] = { - &M68KDummy, - &M68KC68K, -#ifdef HAVE_Q68 - &M68KQ68, -#endif - NULL -}; - -static const char *bios = "/ram/saturn.bin"; -static int emulate_bios = 0; - -int YuiInit(int sh2core) { - yabauseinit_struct yinit; - - yinit.percoretype = PERCORE_DC; - yinit.sh2coretype = sh2core; - yinit.vidcoretype = VIDCORE_DC; - yinit.m68kcoretype = M68KCORE_C68K; - yinit.sndcoretype = SNDCORE_DUMMY; - yinit.cdcoretype = CDCORE_ARCH; - yinit.carttype = CART_NONE; - yinit.regionid = REGION_AUTODETECT; - yinit.biospath = emulate_bios ? NULL : bios; - yinit.cdpath = NULL; - yinit.buppath = NULL; - yinit.mpegpath = NULL; - yinit.cartpath = NULL; - yinit.frameskip = 0; - yinit.videoformattype = VIDEOFORMATTYPE_NTSC; - yinit.clocksync = 0; - yinit.basetime = 0; - - if(YabauseInit(&yinit) != 0) - return -1; - - for(;;) { - PERCore->HandleEvents(); - } - - return 0; -} - -void YuiErrorMsg(const char *error_text) { - fprintf(stderr, "Error: %s\n", error_text); - arch_exit(); -} - -void YuiSwapBuffers(void) { - /* Nothing here. */ -} - -int DoGui() { - struct coord { - int x; - int y; - }; - - struct coord snowflakes[1024]; - int i; - int offset; - int start_pressed = 0; - int phase = 0; - int core = SH2CORE_INTERPRETER; - - srand(time(NULL)); - - for(i = 0; i < 1024; ++i) { - snowflakes[i].x = (rand() % 640); - snowflakes[i].y = -(rand() % 480); - } - - while(!start_pressed) { - offset = 64 * 640 + 64; /* 64 pixels in from the left, 64 down */ - - bfont_draw_str(vram_s + offset, 640, 0, "Yabause " VERSION); - offset += 640 * 128; - - if(phase == 0) { - FILE *fp; - - fp = fopen("/cd/saturn.bin", "r"); - if(fp) { - fclose(fp); - - fs_copy("/cd/saturn.bin", bios); - phase = 1; - continue; - } - - bfont_draw_str(vram_s + offset, 640, 0, - "Please insert a CD containing the Saturn BIOS"); - offset += 640 * 24; - bfont_draw_str(vram_s + offset, 640, 0, - "on the root of the disc, named saturn.bin."); - offset += 640 * 48; - bfont_draw_str(vram_s + offset, 640, 0, - "Or, to use the BIOS emulation feature, insert"); - offset += 640 * 24; - bfont_draw_str(vram_s + offset, 640, 0, - "a Sega Saturn CD and press Start."); - } - else { - bfont_draw_str(vram_s + offset, 640, 0, - "Please insert a Sega Saturn CD"); - offset += 640 * 24; - bfont_draw_str(vram_s + offset, 640, 0, "and press start."); - } - - for(i = 0; i < 1024; ++i) { - int dx = 1 - (rand() % 3); - - if(snowflakes[i].y >= 0) - vram_s[640 * snowflakes[i].y + snowflakes[i].x] = 0x0000; - - snowflakes[i].x += dx; - snowflakes[i].y += 1; - - if(snowflakes[i].x < 0) - snowflakes[i].x = 639; - else if(snowflakes[i].x > 639) - snowflakes[i].x = 0; - - if(snowflakes[i].y > 479) - snowflakes[i].y = 0; - - if(snowflakes[i].y >= 0) - vram_s[640 * snowflakes[i].y + snowflakes[i].x] = 0xD555; - } - - MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st) - if(st->buttons & CONT_START) { - if(phase == 0) { - emulate_bios = 1; - } - - start_pressed = 1; - } - - if(st->buttons & CONT_Y) { - core = SH2CORE_DYNAREC; - - if(phase == 0) { - emulate_bios = 1; - } - - start_pressed = 1; - } - MAPLE_FOREACH_END() - - vid_waitvbl(); - vid_flip(1); - } - - return core; -} - -int main(int argc, char *argv[]) { - int core; - - printf("...\n"); - - bfont_set_encoding(BFONT_CODE_ISO8859_1); - core = DoGui(); - YuiInit(core); - - return 0; -} diff --git a/yabause/src/dx.h b/yabause/src/dx.h deleted file mode 100644 index c52e0b4540..0000000000 --- a/yabause/src/dx.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright 2008 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#ifndef DX_H -#define DX_H - -#ifdef __MINGW32__ -// I have to do this because for some reason because the dxerr8.h header is fubared -const char* __stdcall DXGetErrorString8A(HRESULT hr); -#define DXGetErrorString8 DXGetErrorString8A -const char* __stdcall DXGetErrorDescription8A(HRESULT hr); -#define DXGetErrorDescription8 DXGetErrorDescription8A -#else -#ifndef DXERRH_IS_BROKEN -#include - -#define DXGetErrorString8 DXGetErrorString9A -#define DXGetErrorDescription8 DXGetErrorDescription9A -#else -#include - -#define DXGetErrorString8 DXGetErrorStringA -#define DXGetErrorDescription8 DXGetErrorDescriptionA - -#endif -#endif - -#endif diff --git a/yabause/src/error.c b/yabause/src/error.c deleted file mode 100644 index 8dd4beba92..0000000000 --- a/yabause/src/error.c +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright 2005-2006 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include "error.h" -#include "yui.h" - -////////////////////////////////////////////////////////////////////////////// - -static void AllocAmendPrintString(const char *string1, const char *string2) -{ - char *string; - - if ((string = (char *)malloc(strlen(string1) + strlen(string2) + 2)) == NULL) - return; - - sprintf(string, "%s%s\n", string1, string2); - YuiErrorMsg(string); - - free(string); -} - -////////////////////////////////////////////////////////////////////////////// - -void YabSetError(int type, const void *extra) -{ - char tempstr[512]; - SH2_struct *sh; - - switch (type) - { - case YAB_ERR_FILENOTFOUND: - AllocAmendPrintString(_("File not found: "), extra); - break; - case YAB_ERR_MEMORYALLOC: - YuiErrorMsg(_("Error allocating memory\n")); - break; - case YAB_ERR_FILEREAD: - AllocAmendPrintString(_("Error reading file: "), extra); - break; - case YAB_ERR_FILEWRITE: - AllocAmendPrintString(_("Error writing file: "), extra); - break; - case YAB_ERR_CANNOTINIT: - AllocAmendPrintString(_("Cannot initialize "), extra); - break; - case YAB_ERR_SH2INVALIDOPCODE: - sh = (SH2_struct *)extra; - SH2GetRegisters(sh, &sh->regs); - sprintf(tempstr, "%s SH2 invalid opcode\n\n" - "R0 = %08lX\tR12 = %08lX\n" - "R1 = %08lX\tR13 = %08lX\n" - "R2 = %08lX\tR14 = %08lX\n" - "R3 = %08lX\tR15 = %08lX\n" - "R4 = %08lX\tSR = %08lX\n" - "R5 = %08lX\tGBR = %08lX\n" - "R6 = %08lX\tVBR = %08lX\n" - "R7 = %08lX\tMACH = %08lX\n" - "R8 = %08lX\tMACL = %08lX\n" - "R9 = %08lX\tPR = %08lX\n" - "R10 = %08lX\tPC = %08lX\n" - "R11 = %08lX\n", sh->isslave ? "Slave" : "Master", - (long)sh->regs.R[0], (long)sh->regs.R[12], - (long)sh->regs.R[1], (long)sh->regs.R[13], - (long)sh->regs.R[2], (long)sh->regs.R[14], - (long)sh->regs.R[3], (long)sh->regs.R[15], - (long)sh->regs.R[4], (long)sh->regs.SR.all, - (long)sh->regs.R[5], (long)sh->regs.GBR, - (long)sh->regs.R[6], (long)sh->regs.VBR, - (long)sh->regs.R[7], (long)sh->regs.MACH, - (long)sh->regs.R[8], (long)sh->regs.MACL, - (long)sh->regs.R[9], (long)sh->regs.PR, - (long)sh->regs.R[10], (long)sh->regs.PC, - (long)sh->regs.R[11]); - YuiErrorMsg(tempstr); - break; - case YAB_ERR_SH2READ: - YuiErrorMsg(_("SH2 read error\n")); // fix me - break; - case YAB_ERR_SH2WRITE: - YuiErrorMsg(_("SH2 write error\n")); // fix me - break; - case YAB_ERR_SDL: - AllocAmendPrintString(_("SDL Error: "), extra); - break; - case YAB_ERR_OTHER: - YuiErrorMsg((char *)extra); - break; - case YAB_ERR_UNKNOWN: - default: - YuiErrorMsg(_("Unknown error occurred\n")); - break; - } -} - -////////////////////////////////////////////////////////////////////////////// - diff --git a/yabause/src/error.h b/yabause/src/error.h deleted file mode 100644 index 6d18c330e0..0000000000 --- a/yabause/src/error.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright 2005-2006 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef ERROR_H -#define ERROR_H - -#define YAB_ERR_UNKNOWN 0 -#define YAB_ERR_FILENOTFOUND 1 -#define YAB_ERR_MEMORYALLOC 2 -#define YAB_ERR_FILEREAD 3 -#define YAB_ERR_FILEWRITE 4 -#define YAB_ERR_CANNOTINIT 5 - -#define YAB_ERR_SH2INVALIDOPCODE 6 -#define YAB_ERR_SH2READ 7 -#define YAB_ERR_SH2WRITE 8 - -#define YAB_ERR_SDL 9 - -#define YAB_ERR_OTHER 10 - -void YabSetError(int type, const void *extra); -#endif diff --git a/yabause/src/font.h b/yabause/src/font.h deleted file mode 100644 index 7ce4910aa6..0000000000 --- a/yabause/src/font.h +++ /dev/null @@ -1,1301 +0,0 @@ -/* Copyright 2012 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -static const char * font[] = { -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" .. ", -" .##.", -" .##. ", -" .##. ", -" .##. ", -" .##. ", -" .##. ", -" .##. ", -".##. ", -" .. ", -" ..... ", -" .#####. ", -".#######.", -".##...##.", -".##.#.##.", -".##.#.##.", -".##...##.", -".#######.", -" .#####. ", -" ..... ", -" .... ", -" .####. ", -" .####. ", -" ..##. ", -" .##. ", -" .##. ", -" ...##.. ", -".#######.", -".#######.", -" ....... ", -" ...... ", -".######. ", -".#######.", -" .....##.", -".#######.", -".######. ", -".##..... ", -".#######.", -".#######.", -" ....... ", -" ....... ", -".#######.", -".#######.", -" .....##.", -".#######.", -".#######.", -" .....##.", -".#######.", -".#######.", -" ....... ", -" .. ", -".##. ", -".##... ", -".##.##. ", -".##.##.. ", -".#######.", -".#######.", -" ...##.. ", -" .##. ", -" .. ", -" ....... ", -".#######.", -".#######.", -".##..... ", -".######. ", -".#######.", -" .....##.", -".#######.", -".######. ", -" ...... ", -" ...... ", -" .######.", -".#######.", -".##..... ", -".######. ", -".#######.", -".##...##.", -".#######.", -" .#####. ", -" ..... ", -" ....... ", -".#######.", -".#######.", -" .....##.", -" .##.", -" .##.", -" .##.", -" .##.", -" .##.", -" .. ", -" ..... ", -" .#####. ", -".#######.", -".##...##.", -" .######.", -".######. ", -".##...##.", -".#######.", -" .#####. ", -" ..... ", -" ..... ", -" .#####. ", -".#######.", -".##...##.", -".#######.", -" .######.", -" .....##.", -".#######.", -".#######.", -" ....... ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ..... ", -" .#####. ", -".#######.", -".##...##.", -".#######.", -".#######.", -".##...##.", -".##. .##.", -".##. .##.", -" .. .. ", -" ...... ", -".######. ", -".#######.", -".##...##.", -".######. ", -".######. ", -".##...##.", -".#######.", -".######. ", -" ...... ", -" ....... ", -".#######.", -".#######.", -".##..... ", -".##. ", -".##. ", -".##..... ", -".#######.", -".#######.", -" ....... ", -" ...... ", -".######. ", -".#######.", -".##...##.", -".##. .##.", -".##. .##.", -".##...##.", -".#######.", -".######. ", -" ...... ", -" ....... ", -".#######.", -".#######.", -".##..... ", -".####. ", -".####. ", -".##..... ", -".#######.", -".#######.", -" ....... ", -" ....... ", -".#######.", -".#######.", -".##..... ", -".####. ", -".####. ", -".##.. ", -".##. ", -".##. ", -" .. ", -" ....... ", -".#######.", -".#######.", -".##..... ", -".##..###.", -".##..###.", -".##...##.", -".#######.", -".#######.", -" ....... ", -" .. .. ", -".##. .##.", -".##. .##.", -".##...##.", -".#######.", -".#######.", -".##...##.", -".##. .##.", -".##. .##.", -" .. .. ", -" ....... ", -".#######.", -".#######.", -" ..###.. ", -" .###. ", -" .###. ", -" ..###.. ", -".#######.", -".#######.", -" ....... ", -" ....... ", -".#######.", -".#######.", -" ....###.", -" .###.", -" .. .###.", -".##..###.", -".#######.", -" ..####. ", -" .... ", -" .. .. ", -".##. .##.", -".##. .##.", -".##..###.", -".######. ", -".#####. ", -".##.###. ", -".##..###.", -".##. .##.", -" .. .. ", -" .. ", -".##. ", -".##. ", -".##. ", -".##. ", -".##. ", -".##..... ", -".#######.", -".#######.", -" ....... ", -" .. .. ", -".##. .##.", -".###.###.", -".#######.", -".##.#.##.", -".##...##.", -".##. .##.", -".##. .##.", -".##. .##.", -" .. .. ", -" .. .. ", -".##. .##.", -".###..##.", -".####.##.", -".##.####.", -".##..###.", -".##. .##.", -".##. .##.", -".##. .##.", -" .. .. ", -" ... ", -" .###. ", -" .#####. ", -".###.###.", -".##. .##.", -".##. .##.", -".###.###.", -" .#####. ", -" .###. ", -" ... ", -" ...... ", -".######. ", -".#######. ", -".##...##.", -".#######.", -".######. ", -".##.... ", -".##. ", -".##. ", -" .. ", -" ... ", -" .###. ", -" .#####. ", -".##...##.", -".##...##.", -".##.#.##.", -".##..###.", -" .######.", -" .###.#.", -" ... . ", -" ...... ", -".######. ", -".#######.", -".##...##.", -".#######.", -".######. ", -".##..###.", -".##. .##.", -".##. .##.", -" .. .. ", -" ..... ", -" .#####. ", -".######. ", -".##.... ", -".######. ", -".######. ", -" ....##. ", -".######. ", -".#####. ", -" ..... ", -" ....... ", -".#######.", -".#######.", -" ..###.. ", -" .###. ", -" .###. ", -" .###. ", -" .###. ", -" .###. ", -" ... ", -" .. .. ", -".##. .##.", -".##. .##.", -".##. .##.", -".##. .##.", -".##. .##.", -".##...##.", -".#######.", -" .#####. ", -" ..... ", -" .. .. ", -".##. .##.", -".##. .##.", -".##. .##.", -" .##.##. ", -" .##.##. ", -" .##.##. ", -" .###. ", -" .###. ", -" ... ", -" .. .. ", -".##...##.", -".##.#.##.", -".##.#.##.", -" .#####. ", -" .#####. ", -" .#####. ", -" .###. ", -" .#.#. ", -" . . ", -" .. .. ", -".##. .##.", -".##. .##.", -".##. .##.", -" .##.##. ", -" .###. ", -" .##.##. ", -".##. .##.", -".##. .##.", -" .. .. ", -" .. .. ", -".##. .##.", -".##. .##.", -".##...##.", -".#######.", -".#######.", -" .....##.", -".#######.", -".#######.", -" ....... ", -" ....... ", -".#######.", -".#######.", -" ....##. ", -" .##. ", -" .##. ", -" .##.... ", -".#######.", -".#######.", -" ....... ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -}; diff --git a/yabause/src/gameshw/dsplist.txt b/yabause/src/gameshw/dsplist.txt deleted file mode 100644 index b1b5eea808..0000000000 --- a/yabause/src/gameshw/dsplist.txt +++ /dev/null @@ -1,64 +0,0 @@ -Games using SCU dsp --------------------- -Battle Monsters -Blazing Tornado -Blue Chicago Blues - J.B.Harold -Blue Seed -Bubble Symphony -Capcom Generations 1 -Capcom Generations 4 -Cotton Boomerang -Crimewave -Daisuki -Dark Savior -Dead or Alive -Don Pachi -Doom -Dragon Ball Z Shinbuthoden -DX Jinsei Game - The Game of Life -Fatal Fury 3 -Find Love 2 -?Gal Panic SS -Galaxy Force 2(sega ages) -Grandia -Grandia: Digital Museum -GT24 -Guardian Force -Guyferd -Jissen Pachinko Hisshouhou! Twin -Lunar 2: Eternal Blue -Mega Man X4 -Momotaroudouchuuki -Nadesico -Mighty Hits -Planet Joker -Psychic Killer Taromaru -Real Bout FF -Real Bout FF Special -Samurai Shodown RPG -Sega Ages Memorial Selection - Vol. 1 -?Shining Force 3 Scenario 1 -Shining Force 3 Scenario 2 -Shining Force 3 Scenario 3 -Sky Target -Slam Dunk - I love Basketball (heavy usage) -Slayers Royal -Sonic R -Stakes Winner SS -Steeldom -?Street Fighter Collection Disc 1 -Super Real Mahjong P7 -Sword & Sorcery -Tenga Seiha -?Tengai Makyou Dai Yon no Mokujiroku - The Apocalypse IV -Toshinden Ura -The Yakuyaken Special -?Thunderforce Gold Pack 1 -Victory Boxing -Virtua Racing -Virtua Fighter Remix -Winter Heat -Wonder 3 -Worms -Yellow Brick Road -Zero4 Champ DooZy-J Type-R diff --git a/yabause/src/gtk/CMakeLists.txt b/yabause/src/gtk/CMakeLists.txt deleted file mode 100644 index c0d2e4354d..0000000000 --- a/yabause/src/gtk/CMakeLists.txt +++ /dev/null @@ -1,65 +0,0 @@ -project(yabause-gtk) - -yab_port_start() - -find_package(GTK2 2.10 COMPONENTS gtk) - -if (NOT GTK2_FOUND) - return() -endif (NOT GTK2_FOUND) - -set(PORT_INCLUDE_DIRS ${GTK2_INCLUDE_DIRS}) -set(PORT_LIBRARIES ${GTK2_LIBRARIES}) - -if (OPENGL_FOUND) - find_path(GDKGLEXT_CONFIG_INCLUDE_DIR gdkglext-config.h PATHS ${CMAKE_SYSTEM_PREFIX_PATH} PATH_SUFFIXES lib/gtkglext-1.0/include) - find_path(GTKGLEXT_INCLUDE_DIR gtk/gtkgl.h PATH_SUFFIXES gtkglext-1.0) - find_library(GDKGLEXT_LIBRARY gdkglext-x11-1.0) - find_library(GTKGLEXT_LIBRARY gtkglext-x11-1.0) - if (NOT GDKGLEXT_CONFIG_INCLUDE_DIR OR NOT GTKGLEXT_INCLUDE_DIR OR NOT GDKGLEXT_LIBRARY OR NOT GTKGLEXT_LIBRARY) - message(STATUS "Found OpenGL and Gtk+ but not libgtkglext, skipping Gtk+ port.") - return() - endif () - set(PORT_INCLUDE_DIRS ${PORT_INCLUDE_DIRS} ${GTKGLEXT_INCLUDE_DIR} ${GDKGLEXT_CONFIG_INCLUDE_DIR}) - set(PORT_LIBRARIES ${PORT_LIBRARIES} ${GTKGLEXT_LIBRARY} ${GDKGLEXT_LIBRARY}) - add_definitions(-DHAVE_LIBGTKGLEXT=1) -endif (OPENGL_FOUND) -include_directories(${PORT_INCLUDE_DIRS}) - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I/usr/include/gdk-pixbuf-2.0") - -set(yabause_gtk_SOURCES - gtk-compat.c - gtkglwidget.c - main.c - menu.c - pergtk.c - settings.c - yuicheckbutton.c - yuifileentry.c - yuiinputentry.c - yuim68k.c - yuimem.c - yuipage.c - yuirange.c - yuiresolution.c - yuiscreenshot.c - yuiscsp.c - yuiscudsp.c - yuish.c - yuitransfer.c - yuivdp1.c - yuivdp2.c - yuiviewer.c - yuiwindow.c) - -add_executable(yabause-gtk ${yabause_gtk_SOURCES}) -target_link_libraries(yabause-gtk yabause ${YABAUSE_LIBRARIES} ${PORT_LIBRARIES}) - -yab_port_success(yabause-gtk) -configure_file(yabause.desktop.in ${YAB_PORT_NAME}.desktop) - -install(TARGETS yabause-gtk DESTINATION "bin") -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${YAB_PORT_NAME}.desktop DESTINATION "share/applications") -install(FILES "doc/yabause.1" DESTINATION "${YAB_MAN_DIR}/man1" RENAME "${YAB_PORT_NAME}.1") -install(FILES "yabause.png" DESTINATION "share/pixmaps") diff --git a/yabause/src/gtk/Makefile.am b/yabause/src/gtk/Makefile.am deleted file mode 100644 index d1686ebd9f..0000000000 --- a/yabause/src/gtk/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -SUBDIRS = doc -Applicationsdir = $(datadir)/applications -pixmapdir = $(datadir)/pixmaps -pixmap_DATA = yabause.png -bin_PROGRAMS = yabause -EXTRA_DIST = yabause.png - -yabause_SOURCES = gtkglwidget.c gtkglwidget.h main.c settings.c menu.c gtk-compat.c gtk-compat.h \ - yuifileentry.c yuifileentry.h yuirange.c yuirange.h yuiinputentry.c yuiinputentry.h yuipage.c yuipage.h \ - yuiresolution.c yuiresolution.h yuiwindow.c yuiwindow.h yuivdp1.c yuivdp1.h yuivdp2.c yuivdp2.h \ - yuiscsp.c yuiscsp.h pergtk.c pergtk.h yuiscreenshot.c yuiscreenshot.h \ - yuish.c yuish.h yuitransfer.c yuitransfer.h yuim68k.c yuim68k.h yuiscudsp.c yuiscudsp.h yuimem.c yuimem.h \ - yuiviewer.c yuiviewer.h settings.h \ - yuicheckbutton.c yuicheckbutton.h -yabause_CFLAGS = $(YAB_CFLAGS) -yabause_LDADD = ../libyabause.a $(YAB_LIBS) -yabause_CPPFLAGS = -DYTSDIR=\"$(datadir)/$(PACKAGE)/yts\" - -if ARCH_IS_LINUX -if USE_DYNAREC -if CPU_IS_X64 -yabause_CFLAGS += -DSH2_DYNAREC=1 -endif -if CPU_IS_X86 -yabause_CFLAGS += -DSH2_DYNAREC=1 -endif -if CPU_IS_ARM -yabause_CFLAGS += -DSH2_DYNAREC=1 -mcpu=cortex-a8 -mfpu=vfp -mfloat-abi=softfp -endif -endif -endif diff --git a/yabause/src/gtk/doc/Makefile.am b/yabause/src/gtk/doc/Makefile.am deleted file mode 100644 index 327b7de40f..0000000000 --- a/yabause/src/gtk/doc/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -dist_man_MANS = yabause.1 diff --git a/yabause/src/gtk/doc/yabause.1 b/yabause/src/gtk/doc/yabause.1 deleted file mode 100644 index 6d0c781e9d..0000000000 --- a/yabause/src/gtk/doc/yabause.1 +++ /dev/null @@ -1,93 +0,0 @@ -.TH YABAUSE 1 "April 16, 2010" "yabause-0.9.11" -.SH NAME -yabause \- Yet Another Buggy And Uncomplete Saturn Emulator -.SH SYNOPSIS -.B yabause -[ \fB\-afh\fP ] [ \fB\-ns\fP ] [ \fB\-b \fP ] [ \fB\-c \fP ] [ \fB\-i \fP ] -[ \fB\-\-binary=[:
    ]\fP ] -.SH DESCRIPTION -\fBYabause\fP is a Sega Saturn emulator. \fBYabause\fP needs either a bios file, a game or a binary to run. -Games can be loaded from a real cd device or from dump files. -.SH OPTIONS -.TP -.BI \-a -.TP -.BI \-\-autostart -Automatically start emulation. -.TP -.BI \-\-autoframeskip=0|1 -Enable or disable auto frame skipping / limiting. -.TP -.BI \-\-autoload -Automatically start emulation and load a save state. -.TP -.BI \-b -.TP -.BI \-\-bios -Choose a bios file. -.TP -.BI \-\-binary -Use a binary file. Content of the file will be loaded to 0x06004000 and execution will start from that address. -You can provide an alternative address to load and run the binary with the \-\-binary=:
    syntax. -When using this option, emulation is automatically started and you shouldn't use it in cunjunction with \-a. -This option is intended for homebrew developers wanting to test their programs in \fBYabause\fP. -.TP -.BI \-c -.TP -.BI \-\-cdrom -Choose the cdrom device. -.TP -.BI \-f -.TP -.BI \-\-fullscreen -Start the emulator in fullscreen. -.TP -.BI \-h -Display a short help text. -.TP -.BI \-i -.TP -.BI \-\-iso -Choose a dump file. The dump can be either in iso or bin/cue file format. -.TP -.BI \-ns -.TP -.BI \-\-nosound -Turns sound off. This option actually set the sound core to the dummy one. -.SH FILES -.TP -\fB\fR -An executable for the Saturn, usually with a BIN extension. -.TP -\fB\fR -A Saturn ROM BIOS image. -.TP -\fB\fR -A CDROM device file. -.TP -\fB\fR -A Saturn game dump. -.SH AUTHORS -Copyright (c) 2002-2010 Yabause Team - -Web: http://yabause.org - -Please don't ask for roms, bios files or any other -copyrighted stuff. -.SH COPYRIGHT -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of -the License, or (at your option) any later version. - -This program is distributed in the hope that it will be -useful,but WITHOUT ANY WARRANTY; without even the implied -warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public -License along with this program; if not, write to the Free -Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301 USA - -See the GNU General Public License details in COPYING. diff --git a/yabause/src/gtk/gtk-compat.c b/yabause/src/gtk/gtk-compat.c deleted file mode 100644 index 3fa155c3a7..0000000000 --- a/yabause/src/gtk/gtk-compat.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "gtk-compat.h" - -#if !GLIB_CHECK_VERSION(2, 8, 0) -gboolean g_file_set_contents(const gchar * filename, const gchar * contents, gssize len, GError ** error) { - FILE * file = fopen(filename, "w"); - - if (len == -1) - fprintf(file, "%s", contents); - else - fwrite(contents, 1, len, file); - - fclose(file); -} -#endif diff --git a/yabause/src/gtk/gtk-compat.h b/yabause/src/gtk/gtk-compat.h deleted file mode 100644 index f18a74c156..0000000000 --- a/yabause/src/gtk/gtk-compat.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_GTK_COMPAT_H -#define YUI_GTK_COMPAT_H - -#include - -#if ((GLIB_MAJOR_VERSION < 2) || ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION < 8))) -gboolean g_file_set_contents(const gchar *, const gchar *, gssize, GError **); -#endif - -#endif diff --git a/yabause/src/gtk/gtkglwidget.c b/yabause/src/gtk/gtkglwidget.c deleted file mode 100644 index 85cdc2db02..0000000000 --- a/yabause/src/gtk/gtkglwidget.c +++ /dev/null @@ -1,318 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "gtkglwidget.h" -#ifdef HAVE_LIBGTKGLEXT -#include -#endif -#include "../vidsoft.h" -#include "../peripheral.h" - -#define X_NOSCALE 160 -#define Y_NOSCALE 120 - -static void yui_gl_class_init (YuiGlClass * klass); -static void yui_gl_init (YuiGl * yfe); -static gboolean yui_gl_resize (GtkWidget *w,GdkEventConfigure *event, gpointer data); - -void yui_gl_draw(YuiGl * glxarea) { -#ifdef HAVE_LIBGTKGLEXT - GdkGLContext *glcontext = gtk_widget_get_gl_context (GTK_WIDGET(glxarea)); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (GTK_WIDGET(glxarea)); - - if (!gdk_gl_drawable_make_current (gldrawable, glcontext)) { - g_print("Cannot set gl drawable current\n"); - return; - } - - gdk_gl_drawable_swap_buffers(gldrawable); -#else - int buf_width, buf_height; - GdkPixbuf * pixbuf, * scaledpixbuf; - - VIDCore->GetGlSize( &buf_width, &buf_height ); - glxarea->pixels_width = GTK_WIDGET(glxarea)->allocation.width; - glxarea->pixels_height = GTK_WIDGET(glxarea)->allocation.height; - glxarea->pixels_rowstride = glxarea->pixels_width * 4; - glxarea->pixels_rowstride += (glxarea->pixels_rowstride % 4)? (4 - (glxarea->pixels_rowstride % 4)): 0; - - if (dispbuffer == NULL) return; - - pixbuf = gdk_pixbuf_new_from_data((const guchar *) dispbuffer, GDK_COLORSPACE_RGB, TRUE, 8, - buf_width, buf_height, buf_width*4, NULL, NULL); - - if (( glxarea->pixels_width < buf_width + X_NOSCALE )&&( glxarea->pixels_height < buf_height + Y_NOSCALE )) { - - gdk_draw_pixbuf(GTK_WIDGET(glxarea)->window, NULL, pixbuf, 0, 0, - (glxarea->pixels_width-buf_width)/2, (glxarea->pixels_height-buf_height)/2, - buf_width, buf_height, GDK_RGB_DITHER_NONE, 0, 0); - } else { - - scaledpixbuf = gdk_pixbuf_scale_simple(pixbuf, - glxarea->pixels_width, glxarea->pixels_height, GDK_INTERP_NEAREST ); - gdk_draw_pixbuf(GTK_WIDGET(glxarea)->window, NULL, - scaledpixbuf, 0, 0, 0, 0, glxarea->pixels_width, glxarea->pixels_height, - GDK_RGB_DITHER_NONE, 0, 0); - g_object_unref(scaledpixbuf); - } - g_object_unref(pixbuf); -#endif - glxarea->is_init = 1; -} - -void yui_gl_draw_pause(YuiGl * glxarea) { -#ifdef HAVE_LIBGTKGLEXT - if (glxarea->pixels) { - /* The "correct" raster position would be (0, height) but it's not a - * valid position, so I have to use this hack... found here: - * http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/ */ - glRasterPos2i(0, 0); - glBitmap(0, 0, 0, 0, 0, - glxarea->pixels_height, NULL); - glPixelZoom(1, 1); - glDrawPixels(glxarea->pixels_width, glxarea->pixels_height, GL_RGB, GL_UNSIGNED_BYTE, glxarea->pixels); - yui_gl_draw(glxarea); - } else { - gdk_draw_rectangle(GTK_WIDGET(glxarea)->window, GTK_WIDGET(glxarea)->style->bg_gc[GTK_WIDGET_STATE (glxarea)], - TRUE, 0, 0, GTK_WIDGET(glxarea)->allocation.width, GTK_WIDGET(glxarea)->allocation.height); - } -#else - if (dispbuffer) - yui_gl_draw(glxarea); -#endif -} - -static gboolean yui_gl_resize(GtkWidget *w,GdkEventConfigure *event, gpointer data) { -#ifdef HAVE_LIBGTKGLEXT - GdkGLContext *glcontext = gtk_widget_get_gl_context (w); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (w); - - if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) - return FALSE; - - glViewport(0, 0, event->width, event->height); - if ( YUI_GL(w)->is_init ) VIDCore->Resize(event->width, event->height, FALSE ); -#endif - return FALSE; -} - -int beforehiding = 0; - -static gboolean gonna_hide(gpointer data) { - beforehiding--; - - if (beforehiding == 0) { - static char source_data[] = { 0 }; - static char mask_data[] = { 0 }; - - GdkCursor *cursor; - GdkPixmap *source, *mask; - GdkColor fg = { 0, 65535, 65535, 65535 }; - GdkColor bg = { 0, 0, 0, 0 }; - - source = gdk_bitmap_create_from_data(NULL, source_data, 1, 1); - mask = gdk_bitmap_create_from_data(NULL, mask_data, 1, 1); - cursor = gdk_cursor_new_from_pixmap(source, mask, &fg, &bg, 1, 1); - gdk_pixmap_unref(source); - gdk_pixmap_unref(mask); - - gdk_window_set_cursor(GTK_WIDGET(data)->window, cursor); - - return FALSE; - } else { - return TRUE; - } -} - -extern void * padbits; -extern GKeyFile * keyfile; -int oldx = 0; -int oldy = 0; - -static gboolean yui_gl_hide_cursor(GtkWidget * widget, GdkEventMotion * event, gpointer user_data) { - if (PerGetId(padbits) == PERMOUSE) { - int x = event->x; - int y = event->y; - double speed = g_key_file_get_double(keyfile, "General", "MouseSpeed", NULL); - - PerMouseMove(padbits, speed * (x - oldx), -speed * (y - oldy)); - oldx = x; - oldy = y; - } - - if (beforehiding == 0) { - gdk_window_set_cursor(widget->window, NULL); - g_timeout_add(1000, gonna_hide, widget); - } - - beforehiding = 2; - - return FALSE; -} - -static gboolean yui_gl_button_press(GtkWidget * widget, GdkEventButton * event, gpointer user_data) { - if (PerGetId(padbits) == PERMOUSE) { - switch(event->button) { - case 1: - PerMouseLeftPressed(padbits); - break; - case 2: - PerMouseMiddlePressed(padbits); - break; - case 3: - PerMouseRightPressed(padbits); - break; - } - } - return FALSE; -} - -static gboolean yui_gl_button_release(GtkWidget * widget, GdkEventButton * event, gpointer user_data) { - if (PerGetId(padbits) == PERMOUSE) { - switch(event->button) { - case 1: - PerMouseLeftReleased(padbits); - break; - case 2: - PerMouseMiddleReleased(padbits); - break; - case 3: - PerMouseRightReleased(padbits); - break; - } - } - return FALSE; -} - -GtkWidget * yui_gl_new(void) { - GtkWidget * drawingArea; -#ifdef HAVE_LIBGTKGLEXT - int attribs[] = { - GDK_GL_RGBA, - GDK_GL_RED_SIZE, 1, - GDK_GL_GREEN_SIZE, 1, - GDK_GL_BLUE_SIZE, 1, - - GDK_GL_DOUBLEBUFFER, - - GDK_GL_DEPTH_SIZE ,1, - GDK_GL_STENCIL_SIZE ,8, - GDK_GL_ATTRIB_LIST_NONE - }; -#endif - - drawingArea = GTK_WIDGET(g_object_new(yui_gl_get_type(), NULL)); - YUI_GL(drawingArea)->is_init = 0; - -#ifdef HAVE_LIBGTKGLEXT - gtk_widget_set_gl_capability(drawingArea, gdk_gl_config_new(attribs), NULL, TRUE, GDK_GL_RGBA_TYPE); -#endif - - g_signal_connect (GTK_OBJECT(drawingArea),"configure_event", GTK_SIGNAL_FUNC(yui_gl_resize),0); - - gtk_widget_set_events(drawingArea, GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); - - g_signal_connect(GTK_OBJECT(drawingArea), "motion-notify-event", GTK_SIGNAL_FUNC(yui_gl_hide_cursor),0); - g_signal_connect(GTK_OBJECT(drawingArea), "button-press-event", GTK_SIGNAL_FUNC(yui_gl_button_press),0); - g_signal_connect(GTK_OBJECT(drawingArea), "button-release-event", GTK_SIGNAL_FUNC(yui_gl_button_release),0); - - return drawingArea; -} - -void yui_gl_dump_screen(YuiGl * glxarea) { -#ifdef HAVE_LIBGTKGLEXT - int size; - - glxarea->pixels_width = GTK_WIDGET(glxarea)->allocation.width; - glxarea->pixels_height = GTK_WIDGET(glxarea)->allocation.height; - glxarea->pixels_rowstride = glxarea->pixels_width * 3; - glxarea->pixels_rowstride += (glxarea->pixels_rowstride % 4)? (4 - (glxarea->pixels_rowstride % 4)): 0; - - size = glxarea->pixels_rowstride * glxarea->pixels_height; - - if (glxarea->pixels) free(glxarea->pixels); - glxarea->pixels = malloc(sizeof(GLubyte) * size); - if (glxarea->pixels == NULL) return; - - glReadPixels(0, 0, glxarea->pixels_width, glxarea->pixels_height, GL_RGB, GL_UNSIGNED_BYTE, glxarea->pixels); -#else - int buf_width, buf_height; - int i, j; - int size; - int cur = 0; - u8 * pixels; - u8 * buffer; - - VIDCore->GetGlSize( &buf_width, &buf_height ); - size = buf_width * buf_height * 3; - - glxarea->pixels_width = buf_width; - glxarea->pixels_height = buf_height; - glxarea->pixels_rowstride = glxarea->pixels_width * 3; - glxarea->pixels_rowstride += (glxarea->pixels_rowstride % 4)? (4 - (glxarea->pixels_rowstride % 4)): 0; - - if (! glxarea->pixels) glxarea->pixels = malloc(sizeof(u8) * size); - - pixels = (u8 *)glxarea->pixels; - pixels += size - (buf_width * 3); - buffer = (u8 *)dispbuffer; - - for(i = 0;i < buf_height;i++) { - for(j = 0;j < buf_width;j++) { - *pixels++ = buffer[cur]; - *pixels++ = buffer[cur + 1]; - *pixels++ = buffer[cur + 2]; - cur += 4; - } - pixels -= buf_width * 6; - } -#endif -} - -GType yui_gl_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiGlClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_gl_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiGl), - 0, - (GInstanceInitFunc) yui_gl_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_DRAWING_AREA, "YuiGl", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_gl_class_init (UNUSED YuiGlClass * klass) { -} - -static void yui_gl_init (YuiGl * y) { - y->pixels = NULL; -} diff --git a/yabause/src/gtk/gtkglwidget.h b/yabause/src/gtk/gtkglwidget.h deleted file mode 100644 index 481b1844fa..0000000000 --- a/yabause/src/gtk/gtkglwidget.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_GL_H -#define YUI_GL_H - -#include - -#ifdef HAVE_LIBGTKGLEXT -#include -#include -#endif - -G_BEGIN_DECLS - -#define YUI_GL_TYPE (yui_gl_get_type ()) -#define YUI_GL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_GL_TYPE, YuiGl)) -#define YUI_GL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_GL_TYPE, YuiGlClass)) -#define IS_YUI_GL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_GL_TYPE)) -#define IS_YUI_GL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_GL_TYPE)) - -typedef struct _YuiGl YuiGl; -typedef struct _YuiGlClass YuiGlClass; - -struct _YuiGl -{ - GtkDrawingArea hbox; - - guint * pixels; - gint pixels_width; - gint pixels_height; - gint pixels_rowstride; - gint is_init; -}; - -struct _YuiGlClass -{ - GtkDrawingAreaClass parent_class; -}; - -GType yui_gl_get_type (void); -GtkWidget * yui_gl_new (void); - -void yui_gl_draw (YuiGl *); -void yui_gl_draw_pause (YuiGl *); -void yui_gl_dump_screen (YuiGl *); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/main.c b/yabause/src/gtk/main.c deleted file mode 100644 index 3749abfa84..0000000000 --- a/yabause/src/gtk/main.c +++ /dev/null @@ -1,624 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2006 Fabien Coulon - Copyright 2005 Joost Peters - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "gtkglwidget.h" -#include "yuiwindow.h" - -#include "../yabause.h" -#include "../yui.h" -#include "../peripheral.h" -#include "../sh2core.h" -#include "../sh2int.h" -#include "../vidogl.h" -#include "../vidsoft.h" -#include "../cs0.h" -#include "../cs2.h" -#include "../cdbase.h" -#include "../scsp.h" -#include "../sndsdl.h" -#include "../sndal.h" -#include "../persdljoy.h" -#ifdef ARCH_IS_LINUX -#include "../perlinuxjoy.h" -#endif -#include "../debug.h" -#include "../m68kcore.h" -#include "../m68kc68k.h" -#include "pergtk.h" -#include "../psp/psp-sh2.h" - -#include "settings.h" - -static char biospath[256] = "\0"; -static char cdpath[256] = "\0"; -static char buppath[256] = "\0"; -static char mpegpath[256] = "\0"; -static char cartpath[256] = "\0"; - -M68K_struct * M68KCoreList[] = { -&M68KDummy, -#ifdef HAVE_C68K -&M68KC68K, -#endif -#ifdef HAVE_Q68 -&M68KQ68, -#endif -NULL -}; - -SH2Interface_struct *SH2CoreList[] = { -&SH2Interpreter, -&SH2DebugInterpreter, -#ifdef TEST_PSP_SH2 -&SH2PSP, -#endif -#ifdef SH2_DYNAREC -&SH2Dynarec, -#endif -NULL -}; - -PerInterface_struct *PERCoreList[] = { -&PERDummy, -&PERGTK, -#ifdef HAVE_LIBSDL -&PERSDLJoy, -#endif -#ifdef ARCH_IS_LINUX -&PERLinuxJoy, -#endif -NULL -}; - -CDInterface *CDCoreList[] = { -&DummyCD, -&ISOCD, -#ifndef UNKNOWN_ARCH -&ArchCD, -#endif -NULL -}; - -SoundInterface_struct *SNDCoreList[] = { -&SNDDummy, -#ifdef HAVE_LIBSDL -&SNDSDL, -#endif -#ifdef HAVE_LIBAL -&SNDAL, -#endif -NULL -}; - -VideoInterface_struct *VIDCoreList[] = { -&VIDDummy, -#ifdef HAVE_LIBGTKGLEXT -&VIDOGL, -#endif -&VIDSoft, -NULL -}; - -#ifdef YAB_PORT_OSD -OSD_struct *OSDCoreList[] = { -&OSDDummy, -#ifdef HAVE_LIBGLUT -&OSDGlut, -#endif -&OSDSoft, -NULL -}; -#endif - -GtkWidget * yui; -GKeyFile * keyfile; -yabauseinit_struct yinit; - -static int yui_main(gpointer data) { - PERCore->HandleEvents(); - return TRUE; -} - -static GtkWidget * yui_new(void) { - yui = yui_window_new(NULL, G_CALLBACK(YabauseInit), &yinit, yui_main, G_CALLBACK(YabauseReset)); - - gtk_widget_show(yui); - - return yui; -} - -static void yui_settings_init(void) { - yinit.m68kcoretype = M68KCORE_C68K; - yinit.percoretype = PERCORE_GTK; - yinit.sh2coretype = SH2CORE_DEFAULT; -#ifdef HAVE_LIBGTKGLEXT - yinit.vidcoretype = VIDCORE_OGL; -#else - yinit.vidcoretype = VIDCORE_SOFT; -#endif - yinit.sndcoretype = SNDCORE_DUMMY; - yinit.cdcoretype = CDCORE_DEFAULT; - yinit.carttype = CART_NONE; - yinit.regionid = 0; - yinit.biospath = biospath; - yinit.cdpath = cdpath; - yinit.buppath = buppath; - yinit.mpegpath = mpegpath; - yinit.cartpath = cartpath; - yinit.videoformattype = VIDEOFORMATTYPE_NTSC; - yinit.osdcoretype = OSDCORE_DEFAULT; -} - -gchar * inifile; - -static int safe_strcmp(const char * s1, const char * s2) { - if (s1) { - if (s2) { - return strcmp(s1, s2); - } else { - return 1; - } - } else { - if (s2) { - return -1; - } else { - return 0; - } - } -} - -extern void * padbits; -void * padbits; - -static gboolean yui_settings_load(void) { - int i, tmp; - long tmptime; - gchar * stmp; - gboolean mustRestart = FALSE; - - g_key_file_load_from_file(keyfile, inifile, G_KEY_FILE_NONE, 0); - - /* bios */ - stmp = g_key_file_get_value(keyfile, "General", "BiosPath", 0); - if (stmp && !*stmp) stmp = NULL; - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && safe_strcmp(stmp, yinit.biospath)) { - mustRestart = TRUE; - } - if (stmp) { - g_strlcpy(biospath, stmp, 256); - yinit.biospath = biospath; - } - else yinit.biospath = NULL; - - /* cd core */ - stmp = g_key_file_get_value(keyfile, "General", "CDROMDrive", 0); - if (stmp && !*stmp) stmp = NULL; - if((YUI_WINDOW(yui)->state & YUI_IS_INIT) && safe_strcmp(stmp, yinit.cdpath)) { - Cs2ChangeCDCore(yinit.cdcoretype, stmp); - } - if (stmp) g_strlcpy(cdpath, stmp, 256); - - tmp = yinit.cdcoretype; - yinit.cdcoretype = g_key_file_get_integer(keyfile, "General", "CDROMCore", 0); - if((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.cdcoretype)) { - Cs2ChangeCDCore(yinit.cdcoretype, yinit.cdpath); - } - - /* region */ - { - char * region = g_key_file_get_value(keyfile, "General", "Region", 0); - tmp = yinit.regionid; - if ((region == 0) || !strcmp(region, "Auto")) { - yinit.regionid = 0; - } else { - switch(region[0]) { - case 'J': yinit.regionid = 1; break; - case 'T': yinit.regionid = 2; break; - case 'U': yinit.regionid = 4; break; - case 'B': yinit.regionid = 5; break; - case 'K': yinit.regionid = 6; break; - case 'A': yinit.regionid = 0xA; break; - case 'E': yinit.regionid = 0xC; break; - case 'L': yinit.regionid = 0xD; break; - } - } - - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.regionid)) { - mustRestart = TRUE; - } - } - - /* cart */ - stmp = g_key_file_get_value(keyfile, "General", "CartPath", 0); - if (stmp && !*stmp) stmp = NULL; - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && safe_strcmp(stmp, yinit.cartpath)) { - mustRestart = TRUE; - } - if (stmp) { - g_strlcpy(cartpath, stmp, 256); - yinit.cartpath = cartpath; - } - else yinit.cartpath = NULL; - - tmp = yinit.carttype; - yinit.carttype = g_key_file_get_integer(keyfile, "General", "CartType", 0); - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.carttype)) { - mustRestart = TRUE; - } - - /* backup ram */ - stmp = g_key_file_get_value(keyfile, "General", "BackupRamPath", 0); - if (stmp && !*stmp) stmp = NULL; - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && safe_strcmp(stmp, yinit.buppath)) { - mustRestart = TRUE; - } - if (stmp) { - g_strlcpy(buppath, stmp, 256); - yinit.buppath = buppath; - } - else yinit.buppath = NULL; - - /* mpeg rom */ - stmp = g_key_file_get_value(keyfile, "General", "MpegRomPath", 0); - if (stmp && !*stmp) stmp = NULL; - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && safe_strcmp(stmp, yinit.mpegpath)) { - mustRestart = TRUE; - } - if (stmp) { - g_strlcpy(mpegpath, stmp, 256); - yinit.mpegpath = mpegpath; - } - else yinit.mpegpath = NULL; - - /* sh2 */ - tmp = yinit.sh2coretype; - yinit.sh2coretype = g_key_file_get_integer(keyfile, "General", "SH2Int", 0); - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.sh2coretype)) { - mustRestart = TRUE; - } - - /* m68k */ - tmp = yinit.m68kcoretype; - yinit.m68kcoretype = g_key_file_get_integer(keyfile, "General", "M68kInt", 0); - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.m68kcoretype)) { - mustRestart = TRUE; - } - - /* video core */ - tmp = yinit.vidcoretype; - yinit.vidcoretype = g_key_file_get_integer(keyfile, "General", "VideoCore", 0); - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.vidcoretype)) { - VideoChangeCore(yinit.vidcoretype); - VIDCore->Resize( - GTK_WIDGET(YUI_WINDOW(yui)->area)->allocation.width, - GTK_WIDGET(YUI_WINDOW(yui)->area)->allocation.height, - FALSE); - } - - /* osd core */ - tmp = yinit.osdcoretype; - yinit.osdcoretype = g_key_file_get_integer(keyfile, "General", "OSDCore", 0); - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.osdcoretype)) { - OSDChangeCore(yinit.osdcoretype); - } - - /* sound core */ - tmp = yinit.sndcoretype; - yinit.sndcoretype = g_key_file_get_integer(keyfile, "General", "SoundCore", 0); - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.sndcoretype)) { - ScspChangeSoundCore(yinit.sndcoretype); - } - - ScspSetVolume(g_key_file_get_integer(keyfile, "General", "Volume", NULL)); - - /* peripheral core */ - yinit.percoretype = g_key_file_get_integer(keyfile, "General", "PerCore", 0); - - /* audio sync */ - tmp = g_key_file_get_boolean(keyfile, "General", "AudioSync", 0); - ScspSetFrameAccurate(tmp); - - /* clock sync */ - tmp = yinit.clocksync; - yinit.clocksync = g_key_file_get_boolean(keyfile, "General", "ClockSync", 0); - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.clocksync)) { - mustRestart = TRUE; - } - tmptime = yinit.basetime; - tmp = g_key_file_get_boolean(keyfile, "General", "FixedBaseTime", 0); - if (tmp && yinit.clocksync) { - /* Find timestamp of 1998-01-01 12:00 in the local time zone */ - time_t utc = 883656000; // 1998-01-01 12:00 UTC - struct tm tm; - long local, noon; - localtime_r(&utc, &tm); - local = tm.tm_hour*3600 + tm.tm_min*60 + tm.tm_sec; - if (tm.tm_mday == 2) // 1998-01-02 - local += 86400; - else if (tm.tm_mday == 31) // 1997-12-31 - local -= 86400; - noon = 12*3600 + 0*60 + 0; - yinit.basetime = (long)utc + (noon - local); - } else { - yinit.basetime = 0; - } - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmptime != yinit.basetime)) { - mustRestart = TRUE; - } - - /* threads */ - tmp = g_key_file_get_boolean(keyfile, "General", "UseThreads", 0); - if ((YUI_WINDOW(yui)->state & YUI_IS_INIT) && (tmp != yinit.usethreads)) { - mustRestart = TRUE; - } - yinit.usethreads = tmp; - - PerInit(yinit.percoretype); - - PerPortReset(); - switch(g_key_file_get_integer(keyfile, "General", "PerType", NULL)) - { - case PERMOUSE: - padbits = PerMouseAdd(&PORTDATA1); - i = 0; - - while(PerMouseNames[i]) { - char tmp[100]; - u32 key; - sprintf(tmp, "Mouse.%s.1", PerMouseNames[i]); - key = g_key_file_get_integer(keyfile, PERCore->Name, tmp, 0); - PerSetKey(key, i + 13, padbits); - i++; - } - break; - case PERPAD: - default: - padbits = PerPadAdd(&PORTDATA1); - i = 0; - - while(PerPadNames[i]) { - char tmp[100]; - u32 key; - sprintf(tmp, "Pad.%s.1", PerPadNames[i]); - key = g_key_file_get_integer(keyfile, PERCore->Name, tmp, 0); - PerSetKey(key, i, padbits); - i++; - } - } - - yui_resize(g_key_file_get_integer(keyfile, "General", "Width", 0), - g_key_file_get_integer(keyfile, "General", "Height", 0), - g_key_file_get_integer(keyfile, "General", "Fullscreen", 0)); - - yinit.videoformattype = g_key_file_get_integer(keyfile, "General", "VideoFormat", 0); - - yui_window_set_frameskip(YUI_WINDOW(yui), g_key_file_get_integer(keyfile, "General", "Frameskip", NULL)); - - return mustRestart; -} - -void YuiErrorMsg(const char * string) { - GtkWidget* warningDlg = gtk_message_dialog_new (GTK_WINDOW(yui), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, string, NULL); - gtk_dialog_run (GTK_DIALOG(warningDlg)); - gtk_widget_destroy (warningDlg); -} - -int main(int argc, char *argv[]) { -#ifndef NO_CLI - int i; -#endif - LogStart(); - LogChangeOutput( DEBUG_STDERR, NULL ); - inifile = g_build_filename(g_get_user_config_dir(), "yabause", "gtk", "yabause.ini", NULL); - - if (! g_file_test(inifile, G_FILE_TEST_EXISTS)) { - // no inifile found, but it could be in the old location - gchar * oldinifile = g_build_filename(g_get_user_config_dir(), "yabause.ini", NULL); - - // we need to create the directory for the new file anyways - gchar * xdgpath = g_build_filename(g_get_user_config_dir(), "yabause", "gtk", NULL); - - if (! g_file_test(xdgpath, G_FILE_TEST_EXISTS)) - g_mkdir_with_parents(xdgpath, 0755); - g_free(xdgpath); - - if (g_file_test(oldinifile, G_FILE_TEST_EXISTS)) { - // ok, we found an old .ini file, let's copy the content - gchar * data; - - g_file_get_contents(oldinifile, &data, NULL, NULL); - g_file_set_contents(inifile, data, -1, NULL); - } - - g_free(oldinifile); - } - - keyfile = g_key_file_new(); - - gtk_init(&argc, &argv); -#ifdef HAVE_LIBGTKGLEXT - gtk_gl_init(&argc, &argv); -#endif - - yui_settings_init(); - -#ifdef HAVE_LIBMINI18N - mini18n_set_domain(YTSDIR); - g_key_file_load_from_file(keyfile, inifile, G_KEY_FILE_NONE, 0); - mini18n_set_locale(g_key_file_get_value(keyfile, "General", "TranslationPath", NULL)); -#endif - - yui = yui_new(); - - yui_settings_load(); - - gtk_window_move(GTK_WINDOW(yui), g_key_file_get_integer(keyfile, "Gtk", "X", 0), g_key_file_get_integer(keyfile, "Gtk", "Y", 0)); - -#ifndef NO_CLI - //handle command line arguments - for (i = 1; i < argc; ++i) { - if (argv[i]) { - //show usage - if (0 == strcmp(argv[i], "-h") || 0 == strcmp(argv[i], "-?") || 0 == strcmp(argv[i], "--help")) { - print_usage(argv[0]); - return 0; - } - - //set bios - if (0 == strcmp(argv[i], "-b") && argv[i + 1]) { - g_strlcpy(biospath, argv[i + 1], 256); - yinit.biospath = biospath; - } else if (strstr(argv[i], "--bios=")) { - g_strlcpy(biospath, argv[i] + strlen("--bios="), 256); - yinit.biospath = biospath; - } - //set iso - else if (0 == strcmp(argv[i], "-i") && argv[i + 1]) { - g_strlcpy(cdpath, argv[i + 1], 256); - yinit.cdcoretype = 1; - } else if (strstr(argv[i], "--iso=")) { - g_strlcpy(cdpath, argv[i] + strlen("--iso="), 256); - yinit.cdcoretype = 1; - } - //set cdrom - else if (0 == strcmp(argv[i], "-c") && argv[i + 1]) { - g_strlcpy(cdpath, argv[i + 1], 256); - yinit.cdcoretype = 2; - } else if (strstr(argv[i], "--cdrom=")) { - g_strlcpy(cdpath, argv[i] + strlen("--cdrom="), 256); - yinit.cdcoretype = 2; - } - // Set sound - else if (strcmp(argv[i], "-ns") == 0 || strcmp(argv[i], "--nosound") == 0) { - yinit.sndcoretype = 0; - } - // Autoload - else if (strcmp(argv[i], "--autoload") == 0) { - yui_window_start(YUI_WINDOW(yui)); - YuiLoadState(); - yui_window_run(YUI_WINDOW(yui)); - } - // Autostart - else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--autostart") == 0) { - yui_window_run(YUI_WINDOW(yui)); - } - // Fullscreen - else if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--fullscreen") == 0) { - yui_window_set_fullscreen(YUI_WINDOW(yui), TRUE); - } - // Auto frame skip - else if (strstr(argv[i], "--autoframeskip=")) { - int fscount; - int fsenable; - fscount = sscanf(argv[i] + strlen("--autoframeskip="), "%d", &fsenable); - if (fscount > 0) - yui_window_set_frameskip(YUI_WINDOW(yui), fsenable); - } - // Binary - else if (strstr(argv[i], "--binary=")) { - char binname[1024]; - unsigned int binaddress; - int bincount; - - bincount = sscanf(argv[i] + strlen("--binary="), "%[^:]:%x", binname, &binaddress); - if (bincount > 0) { - if (bincount < 2) binaddress = 0x06004000; - - yui_window_run(YUI_WINDOW(yui)); - MappedMemoryLoadExec(binname, binaddress); - } - } - } - } -#endif - - gtk_main (); - - YabauseDeInit(); - LogStop(); - - return 0; -} - -void YuiSetVideoAttribute(int type, int val) { -} - -int YuiSetVideoMode(int width, int height, int bpp, int fullscreen) { - return 0; -} - -void YuiSwapBuffers(void) { - yui_window_update(YUI_WINDOW(yui)); -} - -void yui_conf(void) { - gint result; - GtkWidget * dialog; - - dialog = create_dialog1(); - - result = gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - switch(result) { - case GTK_RESPONSE_OK: - { - gboolean mustRestart; - g_file_set_contents(inifile, g_key_file_to_data(keyfile, 0, 0), -1, 0); - mustRestart = yui_settings_load(); - if (mustRestart) { - GtkWidget* warningDlg = gtk_message_dialog_new (GTK_WINDOW(yui), - GTK_DIALOG_MODAL, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_OK, - "You must restart Yabause before the changes take effect."); - - gtk_dialog_run (GTK_DIALOG(warningDlg)); - gtk_widget_destroy (warningDlg); - } - break; - } - case GTK_RESPONSE_CANCEL: - g_key_file_load_from_file(keyfile, inifile, G_KEY_FILE_NONE, 0); - break; - } -} - -void yui_resize(guint width, guint height, gboolean fullscreen) { - if (width <= 0) width = 320; - if (height <= 0) height = 224; - - if (g_key_file_get_integer(keyfile, "General", "KeepRatio", 0)) - { - GdkGeometry geometry; - geometry.min_aspect = (float) width / height; - geometry.max_aspect = (float) width / height; - gtk_window_set_geometry_hints(GTK_WINDOW(yui), YUI_WINDOW(yui)->area, &geometry, GDK_HINT_ASPECT); - } - else - { - gtk_window_set_geometry_hints(GTK_WINDOW(yui), YUI_WINDOW(yui)->area, NULL, 0); - } - - gtk_window_resize(GTK_WINDOW(yui), width, height + YUI_WINDOW(yui)->menu->allocation.height); - - yui_window_set_fullscreen(YUI_WINDOW(yui), fullscreen); -} diff --git a/yabause/src/gtk/menu.c b/yabause/src/gtk/menu.c deleted file mode 100644 index 8ecd9cffbf..0000000000 --- a/yabause/src/gtk/menu.c +++ /dev/null @@ -1,218 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "settings.h" -#include "yuiwindow.h" -#include "yuivdp1.h" -#include "yuivdp2.h" -#include "yuish.h" -#include "yuitransfer.h" -#include "yuim68k.h" -#include "yuiscudsp.h" -#include "yuiscsp.h" -#include "yuimem.h" -#include "yuiscreenshot.h" - -static void openAboutDialog(GtkWidget * w, gpointer data) { - gtk_show_about_dialog(data, - "name", "Yabause", - "version", VERSION, - "website", "http://yabause.org", - NULL); -} - -void YuiSaveState(void) { - char * dir = g_key_file_get_value(keyfile, "General", "StatePath", NULL); - - YabSaveStateSlot(dir, 1); -} - -void YuiLoadState(void) { - char * dir = g_key_file_get_value(keyfile, "General", "StatePath", NULL); - - YabLoadStateSlot(dir, 1); -} - -GtkWidget* create_menu(YuiWindow * window1) { - GtkWidget *menubar1; - GtkWidget *menuitem1; - GtkWidget *menuitem1_menu; - GtkWidget *new1; - GtkWidget *view1; - GtkWidget *view1_menu; - GtkWidget *fps1; - GtkWidget *frameLimiter; - GtkWidget *layer1; - GtkWidget *layer1_menu; - GtkWidget *log; - GtkWidget *menuitem3; - GtkWidget *menuitem3_menu; - GtkWidget *msh; - GtkWidget *ssh; - GtkWidget *vdp2; - GtkWidget *vdp1; - GtkWidget *m68k; - GtkWidget *scudsp; - GtkWidget *scsp; - GtkWidget *menuitem4; - GtkWidget *menuitem4_menu; - GtkWidget *about1; - GtkWidget *transfer; - GtkWidget *memory; - GtkWidget *screenshot; - - menubar1 = gtk_menu_bar_new (); - - menuitem1 = gtk_menu_item_new_with_mnemonic ("_Yabause"); - gtk_container_add (GTK_CONTAINER (menubar1), menuitem1); - - menuitem1_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem1), menuitem1_menu); - - new1 = gtk_image_menu_item_new_from_stock("gtk-preferences", NULL); - g_signal_connect(new1, "activate", yui_conf, 0); - gtk_container_add (GTK_CONTAINER (menuitem1_menu), new1); - - gtk_container_add(GTK_CONTAINER(menuitem1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "run"))); - gtk_container_add(GTK_CONTAINER(menuitem1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "pause"))); - gtk_container_add(GTK_CONTAINER(menuitem1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "reset"))); - - transfer = gtk_menu_item_new_with_mnemonic (_("Transfer")); - gtk_container_add (GTK_CONTAINER (menuitem1_menu), transfer); - g_signal_connect_swapped(transfer, "activate", G_CALLBACK(yui_transfer_new), window1); - - screenshot = gtk_menu_item_new_with_mnemonic (_("Screenshot")); - gtk_container_add (GTK_CONTAINER (menuitem1_menu), screenshot); - g_signal_connect_swapped(screenshot, "activate", G_CALLBACK(yui_screenshot_new), window1); - - frameLimiter = gtk_check_menu_item_new_with_mnemonic (_("Frame Skip/Limiter")); - { - GtkAction * action = gtk_action_group_get_action(window1->action_group, "frameskip"); - gtk_action_connect_proxy(action, frameLimiter); - } - gtk_container_add (GTK_CONTAINER (menuitem1_menu), frameLimiter); - - { - GtkWidget * savestate_menu; - GtkWidget * savestate; - GtkWidget * savestate_save; - GtkWidget * savestate_load; - - savestate = gtk_menu_item_new_with_mnemonic(_("Save State")); - gtk_container_add(GTK_CONTAINER(menuitem1_menu), savestate); - - savestate_menu = gtk_menu_new(); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(savestate), savestate_menu); - - savestate_save = gtk_menu_item_new_with_mnemonic(_("Save")); - gtk_container_add(GTK_CONTAINER(savestate_menu), savestate_save); - g_signal_connect_swapped(savestate_save, "activate", G_CALLBACK(YuiSaveState), NULL); - - savestate_load = gtk_menu_item_new_with_mnemonic(_("Load")); - gtk_container_add(GTK_CONTAINER(savestate_menu), savestate_load); - g_signal_connect_swapped(savestate_load, "activate", G_CALLBACK(YuiLoadState), NULL); - } - - gtk_container_add (GTK_CONTAINER (menuitem1_menu), gtk_separator_menu_item_new ()); - - gtk_container_add(GTK_CONTAINER(menuitem1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "quit"))); - - view1 = gtk_menu_item_new_with_mnemonic (_("_View")); - gtk_container_add (GTK_CONTAINER (menubar1), view1); - - view1_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (view1), view1_menu); - - fps1 = gtk_check_menu_item_new_with_mnemonic (_("FPS")); - g_signal_connect(fps1, "activate", G_CALLBACK(ToggleFPS), NULL); - gtk_container_add (GTK_CONTAINER (view1_menu), fps1); - - layer1 = gtk_menu_item_new_with_mnemonic (_("Layer")); - gtk_container_add (GTK_CONTAINER (view1_menu), layer1); - - layer1_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (layer1), layer1_menu); - - gtk_container_add(GTK_CONTAINER(layer1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "toggle_vdp1"))); - gtk_container_add(GTK_CONTAINER(layer1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "toggle_nbg0"))); - gtk_container_add(GTK_CONTAINER(layer1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "toggle_nbg1"))); - gtk_container_add(GTK_CONTAINER(layer1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "toggle_nbg2"))); - gtk_container_add(GTK_CONTAINER(layer1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "toggle_nbg3"))); - gtk_container_add(GTK_CONTAINER(layer1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "toggle_rbg0"))); - - gtk_container_add(GTK_CONTAINER(view1_menu), gtk_action_create_menu_item(gtk_action_group_get_action(window1->action_group, "fullscreen"))); - - log = gtk_menu_item_new_with_mnemonic (_("Log")); - g_signal_connect_swapped(log, "activate", G_CALLBACK(yui_window_show_log), window1); - gtk_container_add(GTK_CONTAINER(view1_menu), log); - - menuitem3 = gtk_menu_item_new_with_mnemonic (_("_Debug")); - gtk_container_add (GTK_CONTAINER (menubar1), menuitem3); - - menuitem3_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem3), menuitem3_menu); - - msh = gtk_menu_item_new_with_mnemonic ("MSH2"); - gtk_container_add (GTK_CONTAINER (menuitem3_menu), msh); - g_signal_connect_swapped(msh, "activate", G_CALLBACK(yui_msh_new), window1); - - ssh = gtk_menu_item_new_with_mnemonic ("SSH2"); - gtk_container_add (GTK_CONTAINER (menuitem3_menu), ssh); - g_signal_connect_swapped(ssh, "activate", G_CALLBACK(yui_ssh_new), window1); - - vdp2 = gtk_menu_item_new_with_mnemonic ("Vdp1"); - gtk_container_add (GTK_CONTAINER (menuitem3_menu), vdp2); - g_signal_connect_swapped(vdp2, "activate", G_CALLBACK(yui_vdp1_new), window1); - - vdp1 = gtk_menu_item_new_with_mnemonic ("Vdp2"); - gtk_container_add (GTK_CONTAINER (menuitem3_menu), vdp1); - g_signal_connect_swapped(vdp1, "activate", G_CALLBACK(yui_vdp2_new), window1); - - m68k = gtk_menu_item_new_with_mnemonic ("M68K"); - gtk_container_add (GTK_CONTAINER (menuitem3_menu), m68k); - g_signal_connect_swapped(m68k, "activate", G_CALLBACK(yui_m68k_new), window1); - - scudsp = gtk_menu_item_new_with_mnemonic ("SCU-DSP"); - gtk_container_add (GTK_CONTAINER (menuitem3_menu), scudsp); - g_signal_connect_swapped(scudsp, "activate", G_CALLBACK(yui_scudsp_new), window1); - - scsp = gtk_menu_item_new_with_mnemonic ("SCSP"); - gtk_container_add (GTK_CONTAINER (menuitem3_menu), scsp); - g_signal_connect_swapped(scsp, "activate", G_CALLBACK(yui_scsp_new), window1); - - gtk_container_add (GTK_CONTAINER (menuitem3_menu), gtk_separator_menu_item_new ()); - - memory = gtk_menu_item_new_with_mnemonic (_("Memory dump")); - gtk_container_add (GTK_CONTAINER (menuitem3_menu), memory); - g_signal_connect_swapped(memory, "activate", G_CALLBACK(yui_mem_new), window1); - - menuitem4 = gtk_menu_item_new_with_mnemonic (_("_Help")); - gtk_container_add (GTK_CONTAINER (menubar1), menuitem4); - - menuitem4_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem4), menuitem4_menu); - - about1 = gtk_image_menu_item_new_from_stock ("gtk-about", NULL); - gtk_container_add (GTK_CONTAINER (menuitem4_menu), about1); - g_signal_connect(about1, "activate", G_CALLBACK(openAboutDialog), window1); - - return menubar1; -} - diff --git a/yabause/src/gtk/pergtk.c b/yabause/src/gtk/pergtk.c deleted file mode 100644 index 734674bf14..0000000000 --- a/yabause/src/gtk/pergtk.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright 2005-2006 Guillaume Duhamel - Copyright 2005-2006 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "pergtk.h" -#include -#include "../yabause.h" -#include "../vdp2.h" -#include "../yui.h" - -int PERGTKInit(void); -void PERGTKDeInit(void); -int PERGTKHandleEvents(void); -void PERGTKNothing(void); - -u32 PERGTKScan(void); -void PERGTKFlush(void); -void PERGTKKeyName(u32 key, char * name, int size); - -PerInterface_struct PERGTK = { -PERCORE_GTK, -"GTK Input Interface", -PERGTKInit, -PERGTKDeInit, -PERGTKHandleEvents, -PERGTKNothing, -PERGTKScan, -0, -PERGTKFlush -#ifdef PERKEYNAME -,PERGTKKeyName -#endif -}; - -////////////////////////////////////////////////////////////////////////////// - -int PERGTKInit(void) { - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void PERGTKDeInit(void) { -} - -////////////////////////////////////////////////////////////////////////////// - -void PERGTKNothing(void) { -} - -////////////////////////////////////////////////////////////////////////////// - -int PERGTKHandleEvents(void) { - YabauseExec(); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -u32 PERGTKScan(void) { - g_print("this is wrong, the gtk peripheral can't scan\n"); - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -void PERGTKFlush(void) { -} - -////////////////////////////////////////////////////////////////////////////// - -void PERGTKKeyName(u32 key, char * name, int size) -{ - g_strlcpy(name, gdk_keyval_name(key), size); -} diff --git a/yabause/src/gtk/pergtk.h b/yabause/src/gtk/pergtk.h deleted file mode 100644 index 0d441196f9..0000000000 --- a/yabause/src/gtk/pergtk.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright 2005 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PERGTK_H -#define PERGTK_H - -#include "../peripheral.h" - -#define PERCORE_GTK 2 - -extern PerInterface_struct PERGTK; - -#endif diff --git a/yabause/src/gtk/settings.c b/yabause/src/gtk/settings.c deleted file mode 100644 index 4af555def1..0000000000 --- a/yabause/src/gtk/settings.c +++ /dev/null @@ -1,569 +0,0 @@ -/* Copyright 2006-2011 Guillaume Duhamel - Copyright 2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "settings.h" - -#include "yuicheckbutton.h" -#include "yuifileentry.h" -#include "yuirange.h" -#include "yuipage.h" -#include "yuiinputentry.h" -#include "yuiresolution.h" - -#include "../scsp.h" - -typedef struct { - int id; - const char *Name; -} GenericInterface_struct; - -void cores_to_range(void * pointer, YuiRangeItem ** items) { - GenericInterface_struct ** cores; - GenericInterface_struct * core; - int i; - - if (*items != NULL) return; - - cores = pointer; - - i = 0; - core = cores[i]; - while(core) { - i++; - core = cores[i]; - } - *items = malloc(sizeof(YuiRangeItem) * (i + 1)); - i = 0; - core = cores[i]; - while(core) { - char buffer[1024]; - (*items)[i].name = strdup(core->Name); - sprintf(buffer, "%d", core->id); - (*items)[i].value = strdup(buffer); - i++; - core = cores[i]; - } - (*items)[i].name = NULL; - (*items)[i].value = NULL; -} - -extern CDInterface *SH2CoreList[]; -extern CDInterface *M68KCoreList[]; -extern CDInterface *CDCoreList[]; -extern CDInterface *VIDCoreList[]; -extern CDInterface *OSDCoreList[]; -extern CDInterface *SNDCoreList[]; -extern CDInterface *PERCoreList[]; - -YuiRangeItem * sh2interpreters = NULL; -YuiRangeItem * m68kinterpreters = NULL; -YuiRangeItem * cdcores = NULL; -YuiRangeItem * vidcores = NULL; -YuiRangeItem * osdcores = NULL; -YuiRangeItem * sndcores = NULL; -YuiRangeItem * percores = NULL; - -YuiRangeItem regions[] = { - { "Auto" , "Auto-detect" }, - { "J" , "Japan (NTSC)" }, - { "T", "Asia (NTSC)" }, - { "U", "North America (NTSC)" }, - { "B", "Central/South America (NTSC)" }, - { "K", "Korea (NTSC)" }, - { "A", "Asia (PAL)" }, - { "E", "Europe + others (PAL)" }, - { "L", "Central/South America (PAL)" }, - { 0, 0 } -}; - -YuiRangeItem carttypes[] = { - { "0", "None" }, - { "1", "Pro Action Replay" }, - { "2", "4 Mbit Backup Ram" }, - { "3", "8 Mbit Backup Ram" }, - { "4", "16 Mbit Backup Ram" }, - { "5", "32 Mbit Backup Ram" }, - { "6", "8 Mbit Dram" }, - { "7", "32 Mbit Dram" }, - { "8", "Netlink" }, - { "9", "16 Mbit ROM" }, - { 0, 0 } -}; - -const gchar * keys1[] = { "Up", "Right", "Down", "Left", "R", "L", 0 }; -const gchar * keys2[] = { "A", "B", "C", "X", "Y", "Z", "Start", 0 }; - -YuiRangeItem vidformats[] = { - { "0", "NTSC" }, - { "1", "PAL" }, - { 0, 0 } -}; - -YuiRangeItem mousepercores[] = { - { "2", "Gtk Input Interface" }, - { 0, 0 } -}; - -static void hide_show_cart_path(YuiRange * instance, gpointer data) { - gint i = yui_range_get_active(instance); - - if (i == 8) { - gtk_widget_hide(data); - } else { - gtk_widget_show(data); - } -} - -static void hide_show_netlink(YuiRange * instance, gpointer data) { - gint i = yui_range_get_active(instance); - - if (i != 8) { - gtk_widget_hide(data); - } else { - gtk_widget_show(data); - } -} - -static void percore_changed(GtkWidget * widget, gpointer data) { - const char * core_s = percores[gtk_combo_box_get_active(GTK_COMBO_BOX(widget))].value; - GList * entrylist = data; - int core; - sscanf(core_s, "%d", &core); - - PerDeInit(); - PerInit(core); - - while(entrylist) { - yui_input_entry_update(entrylist->data); - entrylist = g_list_next(entrylist); - } -} - -static void pertype_display_pad(GtkWidget * box) -{ - GtkWidget * table4, * table5; - GtkWidget * box_percore = gtk_vbox_new(FALSE, 10); - GtkWidget * select_percore = yui_range_new(keyfile, "General", "PerCore", percores); - GList * entrylist = NULL; - - gtk_container_set_border_width(GTK_CONTAINER(select_percore), 0); - - gtk_container_set_border_width(GTK_CONTAINER(box_percore), 10); - - gtk_box_pack_start(GTK_BOX (box_percore), select_percore, FALSE, FALSE, 0); - - table4 = yui_input_entry_new(keyfile, "Pad", keys1); - entrylist = g_list_append(entrylist, table4); - - gtk_box_pack_start (GTK_BOX (box_percore), table4, TRUE, TRUE, 0); - - gtk_box_pack_start (GTK_BOX (box), box_percore, TRUE, TRUE, 0); - - gtk_box_pack_start (GTK_BOX (box), gtk_vseparator_new(), TRUE, TRUE, 0); - - table5 = yui_input_entry_new(keyfile, "Pad", keys2); - entrylist = g_list_append(entrylist, table5); - - gtk_container_set_border_width(GTK_CONTAINER(table5), 10); - - gtk_box_pack_start (GTK_BOX (box), table5, TRUE, TRUE, 0); - - g_signal_connect(GTK_COMBO_BOX(YUI_RANGE(select_percore)->combo), "changed", G_CALLBACK(percore_changed), entrylist); - - gtk_widget_show_all(box); -} - -static void mouse_speed_change(GtkWidget * range, gpointer data) -{ - g_key_file_set_double(keyfile, "General", "MouseSpeed", gtk_range_get_value(GTK_RANGE(range))); -} - -static void pertype_display_mouse(GtkWidget * box) -{ - GtkWidget * scale; - GtkWidget * table5; - GtkWidget * box_percore = gtk_vbox_new(FALSE, 10); - GtkWidget * select_percore = yui_range_new(keyfile, "General", "MousePerCore", mousepercores); - GList * entrylist = NULL; - - gtk_container_set_border_width(GTK_CONTAINER(select_percore), 0); - gtk_container_set_border_width(GTK_CONTAINER(box_percore), 10); - gtk_box_pack_start(GTK_BOX (box_percore), select_percore, FALSE, FALSE, 0); - - scale = gtk_hscale_new_with_range(0, 10, 0.1); - gtk_range_set_value(GTK_RANGE(scale), g_key_file_get_double(keyfile, "General", "MouseSpeed", NULL)); - g_signal_connect(scale, "value-changed", G_CALLBACK(mouse_speed_change), NULL); - gtk_box_pack_start(GTK_BOX (box_percore), scale, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (box), box_percore, TRUE, TRUE, 0); - - gtk_box_pack_start (GTK_BOX (box), gtk_vseparator_new(), TRUE, TRUE, 0); - - table5 = yui_input_entry_new(keyfile, "Mouse", PerMouseNames); - entrylist = g_list_append(entrylist, table5); - gtk_container_set_border_width(GTK_CONTAINER(table5), 10); - gtk_box_pack_start (GTK_BOX (box), table5, TRUE, TRUE, 0); - - g_signal_connect(GTK_COMBO_BOX(YUI_RANGE(select_percore)->combo), "changed", G_CALLBACK(percore_changed), entrylist); - gtk_widget_show_all(box); -} - -static void pertype_changed(GtkWidget * widget, gpointer data) { - GtkTreePath * path; - gchar * strpath; - int i; - GtkWidget * box = data; - GList * children; - GtkWidget * child; - - children = gtk_container_get_children(GTK_CONTAINER(box)); - for(i = 1;i < 4;i++) { - child = g_list_nth_data(children, i); - if (child != NULL) gtk_widget_destroy(child); - } - - gtk_tree_view_get_cursor(GTK_TREE_VIEW(widget), &path, NULL); - - if (path) { - int i; - - strpath = gtk_tree_path_to_string(path); - sscanf(strpath, "%d", &i); - - switch(i) { - case 0: - g_key_file_set_integer(keyfile, "General", "PerType", PERPAD); - pertype_display_pad(box); - break; - case 1: - g_key_file_set_integer(keyfile, "General", "PerType", PERMOUSE); - pertype_display_mouse(box); - break; - } - - g_free(strpath); - gtk_tree_path_free(path); - } -} - -static void frameskip_toggled(GtkWidget * widget, gpointer data) { - g_key_file_set_integer(keyfile, "General", "Frameskip", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))); -} - -static void disable_enable_audio_sync(YuiCheckButton *audiosync) { - ScspSetFrameAccurate(yui_check_button_get_active(audiosync)); -} - -static void disable_enable_fixed_base_time(YuiCheckButton *clocksync, YuiCheckButton *fixedbasetime) { - gtk_widget_set_sensitive(GTK_WIDGET(fixedbasetime), - yui_check_button_get_active(clocksync)); -} - -static void volume_changed(GtkRange * range, gpointer data) { - g_key_file_set_integer(keyfile, "General", "Volume", (int) gtk_range_get_value(range)); -} - -GtkWidget* create_dialog1(void) { - GtkWidget *dialog1; - GtkWidget *notebook1; - GtkWidget *vbox17; - GtkWidget *hbox22; - GtkWidget *button11; - GtkWidget *button12; - GtkWidget * general, * video_sound, * cart_memory, *advanced, * sound; - GtkWidget * box; - u8 perid; - - cores_to_range(SH2CoreList, &sh2interpreters); - cores_to_range(M68KCoreList, &m68kinterpreters); - cores_to_range(CDCoreList, &cdcores); - cores_to_range(VIDCoreList, &vidcores); - cores_to_range(OSDCoreList, &osdcores); - cores_to_range(SNDCoreList, &sndcores); - cores_to_range(PERCoreList, &percores); - - dialog1 = gtk_dialog_new (); - gtk_window_set_title (GTK_WINDOW (dialog1), "Yabause configuration"); - gtk_window_set_icon_name (GTK_WINDOW (dialog1), "gtk-preferences"); - gtk_window_set_type_hint (GTK_WINDOW (dialog1), GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_resizable(GTK_WINDOW(dialog1), FALSE); - - notebook1 = gtk_notebook_new (); - gtk_widget_show(notebook1); - - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog1)->vbox), notebook1, TRUE, TRUE, 0); - - /* - * General configuration - */ - general = yui_page_new(keyfile); - - box = yui_page_add(YUI_PAGE(general), _("Bios")); - gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "BiosPath", YUI_FILE_ENTRY_BROWSE, NULL)); - - box = yui_page_add(YUI_PAGE(general), _("Cdrom")); - gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "CDROMCore", cdcores)); - gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "CDROMDrive", YUI_FILE_ENTRY_BROWSE, NULL)); - - box = yui_page_add(YUI_PAGE(general), _("Save States")); - gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "StatePath", YUI_FILE_ENTRY_BROWSE | YUI_FILE_ENTRY_DIRECTORY, NULL)); - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), general, gtk_label_new (_("General"))); - gtk_widget_show_all(general); - - /* - * Video configuration - */ - video_sound = yui_page_new(keyfile); - - box = yui_page_add(YUI_PAGE(video_sound), _("Video Core")); - gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "VideoCore", vidcores)); - -#ifdef YAB_PORT_OSD - box = yui_page_add(YUI_PAGE(video_sound), _("OSD Core")); - gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "OSDCore", osdcores)); -#endif - - box = yui_page_add(YUI_PAGE(video_sound), _("Resolution")); - gtk_container_add(GTK_CONTAINER(box), yui_resolution_new(keyfile, "General")); - - box = yui_page_add(YUI_PAGE(video_sound), _("Video Format")); - gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "VideoFormat", vidformats)); - - box = yui_page_add(YUI_PAGE(video_sound), _("Frame Skip/Limiter")); - { - GtkWidget * frameskip = gtk_check_button_new_with_label("Enable frame skipping/limiting"); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frameskip), g_key_file_get_integer(keyfile, "General", "Frameskip", NULL)); - gtk_container_set_border_width(GTK_CONTAINER(frameskip), 10); - g_signal_connect(frameskip, "toggled", G_CALLBACK(frameskip_toggled), NULL); - gtk_container_add(GTK_CONTAINER(box), frameskip); - } - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), video_sound, gtk_label_new (_("Video"))); - gtk_widget_show_all(video_sound); - - /* - * Sound configuration - */ - sound = yui_page_new(keyfile); - - box = yui_page_add(YUI_PAGE(sound), _("Sound Core")); - gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "SoundCore", sndcores)); - - { - GtkWidget * volume; - - box = yui_page_add(YUI_PAGE(sound), _("Volume")); - gtk_container_set_border_width(GTK_CONTAINER(box), 10); - volume = gtk_hscale_new_with_range(0, 100, 1); - gtk_range_set_value(GTK_RANGE(volume), g_key_file_get_integer(keyfile, "General", "Volume", NULL)); - g_signal_connect(volume, "value-changed", G_CALLBACK(volume_changed), NULL); - gtk_container_add(GTK_CONTAINER(box), volume); - } - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), sound, gtk_label_new (_("Sound"))); - gtk_widget_show_all(sound); - - /* - * Cart/Memory configuration - */ - cart_memory = yui_page_new(keyfile); - - box = yui_page_add(YUI_PAGE(cart_memory), _("Cartridge")); - { - GtkWidget * w1, * w2, * w3; - - w1 = yui_range_new(keyfile, "General", "CartType", carttypes); - gtk_container_add(GTK_CONTAINER(box), w1); - - w2 = yui_file_entry_new(keyfile, "General", "CartPath", YUI_FILE_ENTRY_BROWSE, NULL); - gtk_container_add(GTK_CONTAINER(box), w2); - - w3 = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(w3), yui_file_entry_new(keyfile, "General", "NetlinkHost", 0, "Host"), TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(w3), yui_file_entry_new(keyfile, "General", "NetlinkPort", 0, "Port"), TRUE, TRUE, 0); - gtk_container_add(GTK_CONTAINER(box), w3); - - g_signal_connect(w1, "changed", G_CALLBACK(hide_show_cart_path), w2); - g_signal_connect(w1, "changed", G_CALLBACK(hide_show_netlink), w3); - - box = yui_page_add(YUI_PAGE(cart_memory), _("Memory")); - gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "BackupRamPath", YUI_FILE_ENTRY_BROWSE, NULL)); - - box = yui_page_add(YUI_PAGE(cart_memory), _("Mpeg ROM")); - gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "MpegRomPath", YUI_FILE_ENTRY_BROWSE, NULL)); - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), cart_memory, gtk_label_new (_("Cart/Memory"))); - gtk_widget_show_all(cart_memory); - - if (yui_range_get_active(YUI_RANGE(w1)) == 8) gtk_widget_hide(w2); - else gtk_widget_hide(w3); - } - - /* - * Input Configuration - */ - vbox17 = gtk_vbox_new (FALSE, 0); - - hbox22 = gtk_hbox_new (FALSE, 0); - - { - GtkWidget * controllerscroll; - GtkTreeStore * controllerlist; - GtkWidget * controllerlistview; - GtkCellRenderer * controllerrenderer; - GtkTreeViewColumn * controllercolumn; - GtkTreeIter iter; - GtkTreePath * path; - - controllerscroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(controllerscroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - - controllerlist = gtk_tree_store_new(1, G_TYPE_STRING); - controllerlistview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(controllerlist)); - gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(controllerlistview), FALSE); - - controllerrenderer = gtk_cell_renderer_text_new(); - controllercolumn = gtk_tree_view_column_new_with_attributes("Controller", controllerrenderer, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (controllerlistview), controllercolumn); - - gtk_tree_store_append(controllerlist, &iter, NULL); - gtk_tree_store_set(controllerlist, &iter, 0, "Pad", -1); - - gtk_tree_store_append(controllerlist, &iter, NULL); - gtk_tree_store_set(controllerlist, &iter, 0, "Mouse", -1); - - gtk_container_add(GTK_CONTAINER(controllerscroll), controllerlistview); - gtk_box_pack_start (GTK_BOX (hbox22), controllerscroll, TRUE, TRUE, 0); - - gtk_tree_view_expand_all(GTK_TREE_VIEW(controllerlistview)); - - g_signal_connect(controllerlistview, "cursor-changed", G_CALLBACK(pertype_changed), hbox22); - perid = g_key_file_get_integer(keyfile, "General", "PerType", NULL); - switch(perid) - { - case PERMOUSE: - path = gtk_tree_path_new_from_string("1"); - break; - case PERPAD: - default: - path = gtk_tree_path_new_from_string("0"); - break; - } - - gtk_tree_view_set_cursor(GTK_TREE_VIEW(controllerlistview), path, NULL, FALSE); - gtk_tree_path_free(path); - } - - gtk_box_pack_start (GTK_BOX (vbox17), hbox22, TRUE, TRUE, 0); - - //pertype_display_pad(hbox22); - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), vbox17, gtk_label_new (_("Input"))); - gtk_widget_show_all(vbox17); - - /* - * Advanced configuration - */ - - advanced = yui_page_new(keyfile); - - box = yui_page_add(YUI_PAGE(advanced), _("Region")); - gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "Region", regions)); - - box = yui_page_add(YUI_PAGE(advanced), _("SH2 Interpreter")); - gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "SH2Int", sh2interpreters)); - - box = yui_page_add(YUI_PAGE(advanced), _("M68k Interpreter")); - gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "M68kInt", m68kinterpreters)); - - box = yui_page_add(YUI_PAGE(advanced), _("Audio Sync")); - { - GtkWidget *button = yui_check_button_new( - _("Synchronize audio output with emulation"), - keyfile, "General", "AudioSync" - ); - gtk_container_add(GTK_CONTAINER(box), button); - g_signal_connect(button, "changed", - G_CALLBACK(disable_enable_audio_sync), NULL); - } - - box = yui_page_add(YUI_PAGE(advanced), _("Clock Sync")); - { - GtkWidget *button1, *button2; - - button1 = yui_check_button_new( - _("Synchronize internal clock with emulation"), - keyfile, "General", "ClockSync" - ); - gtk_container_add(GTK_CONTAINER(box), button1); - - button2 = yui_check_button_new( - _("Always start from 1998-01-01 12:00"), - keyfile, "General", "FixedBaseTime" - ); - gtk_container_add(GTK_CONTAINER(box), button2); - if (!yui_check_button_get_active(YUI_CHECK_BUTTON(button1))) - gtk_widget_set_sensitive(button2, FALSE); - - g_signal_connect(button1, "changed", - G_CALLBACK(disable_enable_fixed_base_time), button2); - } - - box = yui_page_add(YUI_PAGE(advanced), _("Threads")); - { - GtkWidget *button = yui_check_button_new( - _("Use multithreaded emulation (EXPERIMENTAL!)"), - keyfile, "General", "UseThreads" - ); - gtk_container_add(GTK_CONTAINER(box), button); - } - -#ifdef HAVE_LIBMINI18N - box = yui_page_add(YUI_PAGE(advanced), _("Translation")); - gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "TranslationPath", YUI_FILE_ENTRY_BROWSE, NULL)); -#endif - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), advanced, gtk_label_new (_("Advanced"))); - gtk_widget_show_all(advanced); - - /* - * Dialog buttons - */ - button11 = gtk_button_new_from_stock ("gtk-cancel"); - - gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), button11, GTK_RESPONSE_CANCEL); - GTK_WIDGET_SET_FLAGS (button11, GTK_CAN_DEFAULT); - gtk_widget_show(button11); - - button12 = gtk_button_new_from_stock ("gtk-ok"); - - gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), button12, GTK_RESPONSE_OK); - GTK_WIDGET_SET_FLAGS (button12, GTK_CAN_DEFAULT); - gtk_widget_show(button12); - - gtk_widget_show(dialog1); - - return dialog1; -} - -void yui_texture_free(guchar *pixels, gpointer data) { - free(pixels); -} diff --git a/yabause/src/gtk/settings.h b/yabause/src/gtk/settings.h deleted file mode 100644 index a36f146045..0000000000 --- a/yabause/src/gtk/settings.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_SETTINGS_H -#define YUI_SETTINGS_H - -#include - -#include "../vdp1.h" -#include "../vdp2.h" -#include "../scsp.h" -#include "../yabause.h" -#include "../cdbase.h" -#include "../peripheral.h" - -#include "yuiwindow.h" - -extern GKeyFile * keyfile; -extern yabauseinit_struct yinit; - -extern void YuiSaveState(void); -extern void YuiLoadState(void); - -GtkWidget* create_dialog1(void); -GtkWidget* create_menu(YuiWindow *); - -void yui_conf(void); -void yui_resize(guint, guint, gboolean); - -void gtk_yui_toggle_fullscreen(void); - -void yui_texture_free(guchar *pixels, gpointer data); - -#endif diff --git a/yabause/src/gtk/yabause.desktop.in b/yabause/src/gtk/yabause.desktop.in deleted file mode 100644 index 2da69a2a6f..0000000000 --- a/yabause/src/gtk/yabause.desktop.in +++ /dev/null @@ -1,8 +0,0 @@ -[Desktop Entry] -Type=Application -Name=Yabause (Gtk port) -Comment=Sega Saturn emulator -TryExec=yabause -Exec=@YAB_PORT_NAME@ -Icon=yabause -Categories=GNOME;GTK;Game; diff --git a/yabause/src/gtk/yabause.png b/yabause/src/gtk/yabause.png deleted file mode 100644 index bfa6208a0c..0000000000 Binary files a/yabause/src/gtk/yabause.png and /dev/null differ diff --git a/yabause/src/gtk/yuicheckbutton.c b/yabause/src/gtk/yuicheckbutton.c deleted file mode 100644 index 93d6673df1..0000000000 --- a/yabause/src/gtk/yuicheckbutton.c +++ /dev/null @@ -1,132 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "yuicheckbutton.h" - -static void yui_check_button_class_init(YuiCheckButtonClass * klass); -static void yui_check_button_init (YuiCheckButton * ycb); -static void yui_check_button_toggled (GtkToggleButton * button, YuiCheckButton * ycb); - -GType yui_check_button_get_type (void) { - static GType ycb_type = 0; - - if (!ycb_type) - { - static const GTypeInfo ycb_info = - { - sizeof (YuiCheckButtonClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_check_button_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiCheckButton), - 0, - (GInstanceInitFunc) yui_check_button_init, - NULL, - }; - - ycb_type = g_type_register_static(GTK_TYPE_CHECK_BUTTON, "YuiCheckButton", &ycb_info, 0); - } - - return ycb_type; -} - -#define PROP_KEYFILE 1 -#define PROP_GROUP 2 -#define PROP_KEY 3 - -static void yui_check_button_set_property(GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) { - switch(property_id) { - case PROP_KEYFILE: - YUI_CHECK_BUTTON(object)->keyfile = g_value_get_pointer(value); - break; - case PROP_GROUP: - YUI_CHECK_BUTTON(object)->group = g_value_get_pointer(value); - break; - case PROP_KEY: - YUI_CHECK_BUTTON(object)->key = g_value_get_pointer(value); - break; - } -} - -static void yui_check_button_get_property(GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) { -} - -enum { YUI_CHECK_BUTTON_CHANGED_SIGNAL, LAST_SIGNAL }; - -static guint yui_check_button_signals[LAST_SIGNAL] = { 0 }; - -static void yui_check_button_class_init (YuiCheckButtonClass * klass) { - GParamSpec * param; - - G_OBJECT_CLASS(klass)->set_property = yui_check_button_set_property; - G_OBJECT_CLASS(klass)->get_property = yui_check_button_get_property; - - param = g_param_spec_pointer("key-file", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEYFILE, param); - - param = g_param_spec_pointer("group", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_GROUP, param); - - param = g_param_spec_pointer("key", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEY, param); - - yui_check_button_signals[YUI_CHECK_BUTTON_CHANGED_SIGNAL] = g_signal_new ("changed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET(YuiCheckButtonClass, yui_check_button_change), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); -} - -static void yui_check_button_init (YuiCheckButton * ycb) { -} - -GtkWidget * yui_check_button_new(const gchar * label, GKeyFile * keyfile, const gchar * group, const gchar * key) { - GtkWidget * button; - YuiCheckButton * ycb; - gboolean current; - - button = GTK_WIDGET(g_object_new(yui_check_button_get_type(), - "label", label, - "key-file", keyfile, "group", group, "key", key, NULL)); - ycb = YUI_CHECK_BUTTON(button); - - gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(ycb), TRUE); - - current = g_key_file_get_boolean(ycb->keyfile, ycb->group, ycb->key, NULL); - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ycb), current); - - g_signal_connect(GTK_TOGGLE_BUTTON(ycb), "toggled", G_CALLBACK(yui_check_button_toggled), ycb); - - return button; -} - -static void yui_check_button_toggled(GtkToggleButton * button, YuiCheckButton * ycb) { - g_key_file_set_boolean(ycb->keyfile, ycb->group, ycb->key, - gtk_toggle_button_get_active(button)); - g_signal_emit(G_OBJECT(ycb), yui_check_button_signals[YUI_CHECK_BUTTON_CHANGED_SIGNAL], 0); -} - -gboolean yui_check_button_get_active(YuiCheckButton * ycb) { - return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ycb)); -} diff --git a/yabause/src/gtk/yuicheckbutton.h b/yabause/src/gtk/yuicheckbutton.h deleted file mode 100644 index 3a468bcb41..0000000000 --- a/yabause/src/gtk/yuicheckbutton.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_CHECK_BUTTON_H -#define YUI_CHECK_BUTTON_H - -#include -#include -#include - -G_BEGIN_DECLS - -#define YUI_CHECK_BUTTON_TYPE (yui_check_button_get_type ()) -#define YUI_CHECK_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_CHECK_BUTTON_TYPE, YuiCheckButton)) -#define YUI_CHECK_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_CHECK_BUTTON_TYPE, YuiCheckButtonClass)) -#define IS_YUI_CHECK_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_CHECK_BUTTON_TYPE)) -#define IS_YUI_CHECK_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_CHECK_BUTTON_TYPE)) - -typedef struct _YuiCheckButton YuiCheckButton; -typedef struct _YuiCheckButtonClass YuiCheckButtonClass; - -struct _YuiCheckButton -{ - GtkCheckButton button; - - GKeyFile * keyfile; - gchar * group; - gchar * key; -}; - -struct _YuiCheckButtonClass -{ - GtkCheckButtonClass parent_class; - - void (* yui_check_button_change) (YuiCheckButton * ycb); -}; - -GType yui_check_button_get_type (void); -GtkWidget * yui_check_button_new (const gchar * label, GKeyFile * keyfile, const gchar * group, const gchar * key); -gboolean yui_check_button_get_active (YuiCheckButton * ycb); - -G_END_DECLS - -#endif /* YUI_CHECK_BUTTON_H */ diff --git a/yabause/src/gtk/yuifileentry.c b/yabause/src/gtk/yuifileentry.c deleted file mode 100644 index 11385d7b94..0000000000 --- a/yabause/src/gtk/yuifileentry.c +++ /dev/null @@ -1,167 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "yuifileentry.h" - -static void yui_file_entry_class_init (YuiFileEntryClass * klass); -static void yui_file_entry_init (YuiFileEntry * yfe); -static void yui_file_entry_browse (GtkWidget * widget, gpointer user_data); -static void yui_file_entry_changed (GtkWidget * widget, YuiFileEntry * yfe); - -GType yui_file_entry_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiFileEntryClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_file_entry_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiFileEntry), - 0, - (GInstanceInitFunc) yui_file_entry_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_HBOX, "YuiFileEntry", &yfe_info, 0); - } - - return yfe_type; -} - -#define PROP_KEYFILE 1 -#define PROP_GROUP 2 -#define PROP_KEY 3 - -static void yui_file_entry_set_property(GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) { - switch(property_id) { - case PROP_KEYFILE: - YUI_FILE_ENTRY(object)->keyfile = g_value_get_pointer(value); - break; - case PROP_GROUP: - YUI_FILE_ENTRY(object)->group = g_value_get_pointer(value); - break; - case PROP_KEY: - YUI_FILE_ENTRY(object)->key = g_value_get_pointer(value); - break; - } -} - -static void yui_file_entry_get_property(GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) { -} - -static void yui_file_entry_class_init (YuiFileEntryClass * klass) { - GParamSpec * param; - - G_OBJECT_CLASS(klass)->set_property = yui_file_entry_set_property; - G_OBJECT_CLASS(klass)->get_property = yui_file_entry_get_property; - - param = g_param_spec_pointer("key-file", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEYFILE, param); - - param = g_param_spec_pointer("group", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_GROUP, param); - - param = g_param_spec_pointer("key", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEY, param); -} - -static void yui_file_entry_init (YuiFileEntry * yfe) { - gtk_container_set_border_width(GTK_CONTAINER(yfe), 10); -} - -GtkWidget * yui_file_entry_new(GKeyFile * keyfile, const gchar * group, const gchar * key, gint flags, const gchar * label) { - GtkWidget * entry; - YuiFileEntry * yfe; - gchar * entryText; - - entry = GTK_WIDGET(g_object_new(yui_file_entry_get_type(), "spacing", 10, - "key-file", keyfile, "group", group, "key", key, NULL)); - yfe = YUI_FILE_ENTRY(entry); - - yfe->flags = flags; - - if (label) { - gtk_box_pack_start(GTK_BOX(yfe), gtk_label_new_with_mnemonic(label), FALSE, FALSE, 0); - } - - yfe->entry = gtk_entry_new (); - gtk_box_pack_start(GTK_BOX(yfe), yfe->entry, TRUE, TRUE, 0); - - if (flags & YUI_FILE_ENTRY_BROWSE) { - yfe->button = gtk_button_new_with_mnemonic ("Browse"); - g_signal_connect(yfe->button, "clicked", G_CALLBACK(yui_file_entry_browse), yfe); - gtk_box_pack_start(GTK_BOX(yfe), yfe->button, FALSE, FALSE, 0); - } - - entryText = g_key_file_get_value(yfe->keyfile, yfe->group, yfe->key, 0); - if ( !entryText ) entryText = ""; - gtk_entry_set_text(GTK_ENTRY(yfe->entry), entryText ); - g_signal_connect(GTK_ENTRY(yfe->entry), "changed", G_CALLBACK(yui_file_entry_changed), yfe); - - return entry; -} - -static void yui_file_entry_browse(GtkWidget * widget, gpointer user_data) { - GtkWidget * file_selector; - gint result; - const gchar * filename; - YuiFileEntry * yfe = user_data; - GtkFileChooserAction action; - - if (yfe->flags & YUI_FILE_ENTRY_DIRECTORY) { - action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; - } else { - action = GTK_FILE_CHOOSER_ACTION_OPEN; - } - - file_selector = gtk_file_chooser_dialog_new ("Please choose a file", NULL, action, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); - filename = gtk_entry_get_text(GTK_ENTRY(yfe->entry)); - if (filename[0] != '\0') - gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(file_selector), filename); - - gtk_widget_show(file_selector); - - result = gtk_dialog_run(GTK_DIALOG(file_selector)); - - switch(result) { - case GTK_RESPONSE_ACCEPT: - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_selector)); - gtk_entry_set_text(GTK_ENTRY(yfe->entry), filename); - break; - case GTK_RESPONSE_CANCEL: - break; - } - - gtk_widget_destroy(file_selector); -} - -static void yui_file_entry_changed(GtkWidget * entry, YuiFileEntry * yfe) { - g_key_file_set_value(yfe->keyfile, yfe->group, yfe->key, gtk_entry_get_text(GTK_ENTRY(yfe->entry))); -} diff --git a/yabause/src/gtk/yuifileentry.h b/yabause/src/gtk/yuifileentry.h deleted file mode 100644 index f223d8851f..0000000000 --- a/yabause/src/gtk/yuifileentry.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_FILE_ENTRY_H -#define YUI_FILE_ENTRY_H - -#include -#include -#include - -G_BEGIN_DECLS - -#define YUI_FILE_ENTRY_TYPE (yui_file_entry_get_type ()) -#define YUI_FILE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_FILE_ENTRY_TYPE, YuiFileEntry)) -#define YUI_FILE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_FILE_ENTRY_TYPE, YuiFileEntryClass)) -#define IS_YUI_FILE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_FILE_ENTRY_TYPE)) -#define IS_YUI_FILE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_FILE_ENTRY_TYPE)) - -#define YUI_FILE_ENTRY_BROWSE 1 -#define YUI_FILE_ENTRY_DIRECTORY 2 - -typedef struct _YuiFileEntry YuiFileEntry; -typedef struct _YuiFileEntryClass YuiFileEntryClass; - -struct _YuiFileEntry -{ - GtkHBox hbox; - - GtkWidget * entry; - GtkWidget * button; - - GKeyFile * keyfile; - gchar * group; - gchar * key; - - int flags; -}; - -struct _YuiFileEntryClass -{ - GtkHBoxClass parent_class; - - void (* yui_file_entry) (YuiFileEntry * yfe); -}; - -GType yui_file_entry_get_type (void); -GtkWidget* yui_file_entry_new (GKeyFile *, const gchar *, const gchar *, gint flags, const gchar * label); - -G_END_DECLS - -#endif /* YUI_FILE_ENTRY_H */ diff --git a/yabause/src/gtk/yuiinputentry.c b/yabause/src/gtk/yuiinputentry.c deleted file mode 100644 index 03a49579e4..0000000000 --- a/yabause/src/gtk/yuiinputentry.c +++ /dev/null @@ -1,244 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include "yuiinputentry.h" -#include "settings.h" - -static void yui_input_entry_class_init (YuiInputEntryClass *klass); -static void yui_input_entry_init (YuiInputEntry *yie); -gboolean yui_input_entry_keypress(GtkWidget * widget, GdkEventKey * event, gpointer name); -gboolean yui_input_entry_focus_in(GtkWidget * widget, GdkEventFocus * event, gpointer user_data); -gboolean yui_input_entry_focus_out(GtkWidget * widget, GdkEventFocus * event, gpointer user_data); - -GType yui_input_entry_get_type (void) { - static GType yie_type = 0; - - if (!yie_type) { - static const GTypeInfo yie_info = { - sizeof (YuiInputEntryClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_input_entry_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiInputEntry), - 0, - (GInstanceInitFunc) yui_input_entry_init, - NULL, - }; - - yie_type = g_type_register_static (GTK_TYPE_TABLE, "YuiInputEntry", &yie_info, 0); - } - - return yie_type; -} - -#define PROP_KEYFILE 1 -#define PROP_GROUP 2 - -static void yui_input_entry_set_property(GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) { - switch(property_id) { - case PROP_KEYFILE: - YUI_INPUT_ENTRY(object)->keyfile = g_value_get_pointer(value); - break; - case PROP_GROUP: - YUI_INPUT_ENTRY(object)->group = g_value_get_pointer(value); - break; - } -} - -static void yui_input_entry_get_property(GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) { -} - -static void yui_input_entry_class_init (YuiInputEntryClass *klass) { - GParamSpec * param; - - G_OBJECT_CLASS(klass)->set_property = yui_input_entry_set_property; - G_OBJECT_CLASS(klass)->get_property = yui_input_entry_get_property; - - param = g_param_spec_pointer("key-file", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEYFILE, param); - - param = g_param_spec_pointer("group", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_GROUP, param); -} - -static void yui_input_entry_init(YuiInputEntry *yie) { - gtk_container_set_border_width(GTK_CONTAINER(yie), 0); - gtk_table_set_row_spacings(GTK_TABLE(yie), 10); - gtk_table_set_col_spacings(GTK_TABLE(yie), 10); -} - -GtkWidget* yui_input_entry_new(GKeyFile * keyfile, const gchar * group, const gchar * keys[]) { - GtkWidget * widget; - GtkWidget * label; - GtkWidget * entry; - guint keyName; - int row = 0; - - widget = GTK_WIDGET(g_object_new(yui_input_entry_get_type(), "key-file", keyfile, "group", group, NULL)); - - while(keys[row]) { - char tmp[100]; - gtk_table_resize(GTK_TABLE(widget), row + 1, 2); - label = gtk_label_new(keys[row]); - - gtk_table_attach(GTK_TABLE(widget), label, 0, 1, row , row + 1, - (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - - entry = gtk_entry_new (); - gtk_entry_set_width_chars(GTK_ENTRY(entry), 10); - - sprintf(tmp, "%s.%s.1", group, keys[row]); - keyName = g_key_file_get_integer(keyfile, PERCore->Name, tmp, 0); - if (keyName > 0) { - char buffer[50]; -#ifdef PERKEYNAME - PERCore->KeyName(keyName, buffer, 50); -#else - sprintf(buffer, "%x", keyName); -#endif - gtk_entry_set_text(GTK_ENTRY(entry), buffer); - } - - if (PERCore) { - //if (PERCore->canScan) - g_signal_connect(entry, "focus-in-event", G_CALLBACK(yui_input_entry_focus_in), (gpointer) keys[row]); - g_signal_connect(entry, "focus-out-event", G_CALLBACK(yui_input_entry_focus_out), NULL); - //else - g_signal_connect(entry, "key-press-event", G_CALLBACK(yui_input_entry_keypress), (gpointer) keys[row]); - } else { - gtk_widget_set_sensitive(entry, FALSE); - } - - gtk_table_attach(GTK_TABLE(widget), entry, 1, 2, row, row + 1, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); - row++; - } - - return widget; -} - -gboolean yui_input_entry_keypress(GtkWidget * widget, GdkEventKey * event, gpointer name) { - char tmp[100]; - - if (PERCore->canScan) return FALSE; - -#ifdef PERKEYNAME - PERCore->KeyName(event->keyval, tmp, 100); -#else - sprintf(tmp, "%x", event->keyval); -#endif - gtk_entry_set_text(GTK_ENTRY(widget), tmp); - sprintf(tmp, "%s.%s.1", YUI_INPUT_ENTRY(gtk_widget_get_parent(widget))->group, (char *)name); - g_key_file_set_integer(YUI_INPUT_ENTRY(gtk_widget_get_parent(widget))->keyfile, - PERCore->Name, tmp, event->keyval); - - return TRUE; -} - -gboolean is_watching = FALSE; -GtkEntry * entry_hack = NULL; - -static gboolean watch_joy(gpointer name) { - u32 i; - - if (! is_watching) return TRUE; - - if (! PERCore->canScan) { - is_watching = FALSE; - return TRUE; - } - - i = PERCore->Scan(); - - if (i == 0) { - return TRUE; - } else { - char tmp[100]; - - sprintf(tmp, "Pad.%s.1", (char *)name); // should be group.name - g_key_file_set_integer(keyfile, PERCore->Name, tmp, i); -#ifdef PERKEYNAME - PERCore->KeyName(i, tmp, 100); -#else - sprintf(tmp, "%x", (int)i); -#endif - gtk_entry_set_text(entry_hack, tmp); - is_watching = FALSE; - return FALSE; - } -} - -gboolean yui_input_entry_focus_in(GtkWidget * widget, GdkEventFocus * event, gpointer name) { - if (! PERCore->canScan) return TRUE; - - PERCore->Flush(); - entry_hack = GTK_ENTRY(widget); - - if (!is_watching) { - g_timeout_add(100, watch_joy, name); - is_watching = TRUE; - } - - return FALSE; -} - -gboolean yui_input_entry_focus_out(GtkWidget * widget, GdkEventFocus * event, gpointer name) { - is_watching = FALSE; - - return FALSE; -} - -void yui_input_entry_update(YuiInputEntry * yie) { - GList * wlist = gtk_container_get_children(GTK_CONTAINER(yie)); - u32 key; - GtkEntry * entry = NULL; - char tmp[100]; - - while(wlist) { - if (strcmp(gtk_widget_get_name(wlist->data), "GtkEntry") == 0) { - entry = wlist->data; - } - if (strcmp(gtk_widget_get_name(wlist->data), "GtkLabel") == 0) { - sprintf(tmp, "%s.%s.1", yie->group, gtk_label_get_text(wlist->data)); - key = g_key_file_get_integer(yie->keyfile, PERCore->Name, tmp, 0); - if (key > 0) { -#ifdef PERKEYNAME - PERCore->KeyName(key, tmp, 100); -#else - sprintf(tmp, "%x", (int)key); -#endif - gtk_entry_set_text(entry, tmp); - } else { - gtk_entry_set_text(entry, ""); - } - } - wlist = g_list_next(wlist); - } -} diff --git a/yabause/src/gtk/yuiinputentry.h b/yabause/src/gtk/yuiinputentry.h deleted file mode 100644 index 99d391b9f2..0000000000 --- a/yabause/src/gtk/yuiinputentry.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_INPUT_ENTRY_H -#define YUI_INPUT_ENTRY_H - -#include -#include -#include - -G_BEGIN_DECLS - -#define YUI_INPUT_ENTRY_TYPE (yui_input_entry_get_type ()) -#define YUI_INPUT_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_INPUT_ENTRY_TYPE, YuiInputEntry)) -#define YUI_INPUT_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_INPUT_ENTRY_TYPE, YuiInputEntryClass)) -#define IS_YUI_INPUT_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_INPUT_ENTRY_TYPE)) -#define IS_YUI_INPUT_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_INPUT_ENTRY_TYPE)) - -typedef struct _YuiInputEntry YuiInputEntry; -typedef struct _YuiInputEntryClass YuiInputEntryClass; - -struct _YuiInputEntry -{ - GtkTable table; - - GKeyFile * keyfile; - gchar * group; -}; - -struct _YuiInputEntryClass { - GtkTableClass parent_class; - - void (* yui_input_entry) (YuiInputEntry *yie); -}; - -GType yui_input_entry_get_type (void); -GtkWidget* yui_input_entry_new (GKeyFile * keyfile, const gchar * group, const gchar * keys[]); -void yui_input_entry_update (YuiInputEntry *yie); - -G_END_DECLS - -#endif /* __YUI_INPUT_ENTRY_H__ */ diff --git a/yabause/src/gtk/yuim68k.c b/yabause/src/gtk/yuim68k.c deleted file mode 100644 index 1d92d1af8e..0000000000 --- a/yabause/src/gtk/yuim68k.c +++ /dev/null @@ -1,382 +0,0 @@ -/* Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -#include "yuim68k.h" -#include "../m68kd.h" -#include "../yabause.h" -#include "settings.h" - -static void yui_m68k_class_init (YuiM68kClass * klass); -static void yui_m68k_init (YuiM68k * yfe); -static void yui_m68k_clear(YuiM68k * m68k); -static void yui_m68k_editedReg( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiM68k *m68k); -static void yui_m68k_editedBp( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiM68k *m68k); -static void yui_m68k_step( GtkWidget* widget, YuiM68k * m68k ); -static void yui_m68k_breakpoint_handler(u32 addr); - -static YuiM68k *yui_m68k; -static YuiWindow * yui; - -GType yui_m68k_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiM68kClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_m68k_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiM68k), - 0, - (GInstanceInitFunc) yui_m68k_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiM68k", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_m68k_class_init (UNUSED YuiM68kClass * klass) { -} - -static void yui_m68k_init (YuiM68k * m68k) { - gtk_window_set_title(GTK_WINDOW(m68k), "M68K"); - gtk_window_set_resizable( GTK_WINDOW(m68k), FALSE ); - - m68k->vbox = gtk_vbox_new(FALSE, 2); - gtk_container_set_border_width( GTK_CONTAINER( m68k->vbox ),4 ); - gtk_container_add (GTK_CONTAINER (m68k), m68k->vbox); - - m68k->hboxmain = gtk_hbox_new(FALSE, 2); - gtk_container_set_border_width( GTK_CONTAINER( m68k->hboxmain ),4 ); - gtk_box_pack_start( GTK_BOX( m68k->vbox ), m68k->hboxmain, FALSE, FALSE, 4 ); - - m68k->hbox = gtk_hbutton_box_new(); - gtk_container_set_border_width( GTK_CONTAINER( m68k->hbox ),4 ); - gtk_box_pack_start( GTK_BOX( m68k->vbox ), m68k->hbox, FALSE, FALSE, 4 ); - - m68k->vboxmain = gtk_vbox_new(FALSE, 2); - gtk_container_set_border_width( GTK_CONTAINER( m68k->vboxmain ),4 ); - gtk_box_pack_start( GTK_BOX( m68k->hboxmain ), m68k->vboxmain, FALSE, FALSE, 4 ); - - /* unassembler frame */ - - m68k->uFrame = gtk_frame_new("Disassembled code"); - gtk_box_pack_start( GTK_BOX( m68k->vboxmain ), m68k->uFrame, FALSE, FALSE, 4 ); - - m68k->uLabel = gtk_label_new(NULL); - gtk_container_add (GTK_CONTAINER (m68k->uFrame), m68k->uLabel ); - - /* Register list */ - - m68k->regListStore = gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_STRING); - m68k->regList = gtk_tree_view_new_with_model( GTK_TREE_MODEL(m68k->regListStore) ); - m68k->regListRenderer1 = gtk_cell_renderer_text_new(); - m68k->regListRenderer2 = gtk_cell_renderer_text_new(); - g_object_set(G_OBJECT(m68k->regListRenderer2), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL ); - m68k->regListColumn1 = gtk_tree_view_column_new_with_attributes("Register", m68k->regListRenderer1, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(m68k->regList), m68k->regListColumn1); - m68k->regListColumn2 = gtk_tree_view_column_new_with_attributes("Value", m68k->regListRenderer2, "text", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(m68k->regList), m68k->regListColumn2); - gtk_box_pack_start( GTK_BOX( m68k->hboxmain ), m68k->regList, FALSE, FALSE, 4 ); - g_signal_connect(G_OBJECT(m68k->regListRenderer2), "edited", GTK_SIGNAL_FUNC(yui_m68k_editedReg), m68k ); - - /* breakpoint list */ - - m68k->bpListStore = gtk_list_store_new(1,G_TYPE_STRING); - m68k->bpList = gtk_tree_view_new_with_model( GTK_TREE_MODEL(m68k->bpListStore) ); - m68k->bpListRenderer = gtk_cell_renderer_text_new(); - g_object_set(G_OBJECT(m68k->bpListRenderer), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL ); - m68k->bpListColumn = gtk_tree_view_column_new_with_attributes("Breakpoints", m68k->bpListRenderer, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(m68k->bpList), m68k->bpListColumn); - gtk_box_pack_start( GTK_BOX( m68k->hboxmain ), m68k->bpList, FALSE, FALSE, 4 ); - g_signal_connect(G_OBJECT(m68k->bpListRenderer), "edited", GTK_SIGNAL_FUNC(yui_m68k_editedBp), m68k ); - - g_signal_connect(G_OBJECT(m68k), "delete-event", GTK_SIGNAL_FUNC(yui_m68k_destroy), NULL); -} - - -GtkWidget * yui_m68k_new(YuiWindow * y) { - GtkWidget * dialog; - GClosure *closureF7; - GtkAccelGroup *accelGroup; - const m68kcodebreakpoint_struct *cbp; - gint i; - yui = y; - - if ( yui_m68k ) return GTK_WIDGET(yui_m68k); - - dialog = GTK_WIDGET(g_object_new(yui_m68k_get_type(), NULL)); - yui_m68k = YUI_M68K(dialog); - - if (!( yui->state & YUI_IS_INIT )) { - yui_window_run(yui); - yui_window_pause(yui); - } - - M68KSetBreakpointCallBack(&yui_m68k_breakpoint_handler); - - for (i = 0; i < 23 ; i++) { - - GtkTreeIter iter; - gtk_list_store_append( GTK_LIST_STORE( yui_m68k->regListStore ), &iter ); - } - - cbp = M68KGetBreakpointList(); - - for (i = 0; i < MAX_BREAKPOINTS ; i++) { - - GtkTreeIter iter; - yui_m68k->cbp[i] = cbp[i].addr; - gtk_list_store_append( GTK_LIST_STORE( yui_m68k->bpListStore ), &iter ); - if (cbp[i].addr != 0xFFFFFFFF) { - - gchar tempstr[20]; - sprintf(tempstr, "%08X", (int)cbp[i].addr); - gtk_list_store_set( GTK_LIST_STORE( yui_m68k->bpListStore ), &iter, 0, tempstr, -1 ); - } else gtk_list_store_set( GTK_LIST_STORE( yui_m68k->bpListStore ), &iter, 0, "", -1 ); - } - - { - GtkWidget * but2, * but3, * but4; - - yui_m68k->buttonStep = gtk_button_new_with_label( "Step [F7]" ); - gtk_box_pack_start( GTK_BOX( yui_m68k->hbox ), yui_m68k->buttonStep, FALSE, FALSE, 2 ); - g_signal_connect( yui_m68k->buttonStep, "clicked", G_CALLBACK(yui_m68k_step), yui_m68k ); - - but2 = gtk_button_new(); - gtk_action_connect_proxy(gtk_action_group_get_action(yui->action_group, "run"), but2); - gtk_box_pack_start(GTK_BOX(yui_m68k->hbox), but2, FALSE, FALSE, 2); - - but3 = gtk_button_new(); - gtk_action_connect_proxy(gtk_action_group_get_action(yui->action_group, "pause"), but3); - gtk_box_pack_start(GTK_BOX(yui_m68k->hbox), but3, FALSE, FALSE, 2); - - but4 = gtk_button_new_from_stock("gtk-close"); - g_signal_connect_swapped(but4, "clicked", G_CALLBACK(yui_m68k_destroy), dialog); - gtk_box_pack_start(GTK_BOX(yui_m68k->hbox), but4, FALSE, FALSE, 2); - } - yui_m68k->paused_handler = g_signal_connect_swapped(yui, "paused", G_CALLBACK(yui_m68k_update), yui_m68k); - yui_m68k->running_handler = g_signal_connect_swapped(yui, "running", G_CALLBACK(yui_m68k_clear), yui_m68k); - accelGroup = gtk_accel_group_new (); - closureF7 = g_cclosure_new (G_CALLBACK (yui_m68k_step), yui_m68k, NULL); - gtk_accel_group_connect( accelGroup, GDK_F7, 0, 0, closureF7 ); - gtk_window_add_accel_group( GTK_WINDOW( dialog ), accelGroup ); - - yui_m68k_update(yui_m68k); - if ( yui->state & YUI_IS_RUNNING ) yui_m68k_clear(yui_m68k); - - gtk_widget_show_all(GTK_WIDGET(yui_m68k)); - - return dialog; -} - -static void yui_m68k_update_reglist( YuiM68k *m68k, m68kregs_struct *regs) { - /* refresh the registery list */ - - GtkTreeIter iter; - char regstr[32]; - char valuestr[32]; - int i; - - for ( i = 0 ; i < 8 ; i++ ) { - - if ( i==0 ) gtk_tree_model_get_iter_first( GTK_TREE_MODEL( yui_m68k->regListStore ), &iter ); - else gtk_tree_model_iter_next( GTK_TREE_MODEL( yui_m68k->regListStore ), &iter ); - sprintf(regstr, "D%d", i ); - sprintf(valuestr, "%08x", (int)regs->D[i]); - gtk_list_store_set( GTK_LIST_STORE( yui_m68k->regListStore ), &iter, 0, regstr, 1, valuestr, -1 ); - } - for ( i = 0 ; i < 8 ; i++ ) { - - gtk_tree_model_iter_next( GTK_TREE_MODEL( yui_m68k->regListStore ), &iter ); - sprintf(regstr, "A%d", i ); - sprintf(valuestr, "%08x", (int)regs->A[i]); - gtk_list_store_set( GTK_LIST_STORE( yui_m68k->regListStore ), &iter, 0, regstr, 1, valuestr, -1 ); - } - - gtk_tree_model_iter_next( GTK_TREE_MODEL( yui_m68k->regListStore ), &iter ); - sprintf(valuestr, "%08x", (int)regs->SR); - gtk_list_store_set( GTK_LIST_STORE( yui_m68k->regListStore ), &iter, 0, "SR", 1, valuestr, -1 ); - - gtk_tree_model_iter_next( GTK_TREE_MODEL( yui_m68k->regListStore ), &iter ); - sprintf(valuestr, "%08x", (int)regs->PC); - gtk_list_store_set( GTK_LIST_STORE( yui_m68k->regListStore ), &iter, 0, "PC", 1, valuestr, -1 ); -} - -static void m68ksetRegister( YuiM68k *m68k, int nReg, u32 value ) { - /* set register number to value in proc */ - - m68kregs_struct m68kregs; - M68KGetRegisters(&m68kregs); - - if ( nReg < 8 ) m68kregs.D[nReg] = value; - else if ( nReg < 16 ) m68kregs.A[nReg-8] = value; - if ( nReg == 16 ) m68kregs.SR = value; - if ( nReg == 17 ) m68kregs.PC = value; - - M68KSetRegisters(&m68kregs); -} - -static void yui_m68k_update_codelist( YuiM68k *m68k, u32 addr) { - /* refrem68k the assembler view. points the line to be highlighted. */ - - int i; - static char tagPC[] = ""; - static char tagEnd[] = "\n"; - char buf[64*24+40]; - char *curs = buf; - char lineBuf[64]; - u8 bOnPC = 0; - u32 offset; - - if ( addr - m68k->lastCode >= 22 ) offset = addr; - else offset = m68k->lastCode; - m68k->lastCode = offset; - - for (i=0; i < 24; i++) { - - if ( offset == addr ) { bOnPC = 1; strcpy( curs, tagPC ); curs += strlen(tagPC); } - offset = M68KDisasm(offset, lineBuf); - strcpy( curs, lineBuf ); - curs += strlen(lineBuf); - if ( bOnPC ) { bOnPC = 0; strcpy( curs, tagEnd ); curs += strlen(tagEnd); } - else { strcpy( curs, "\n" ); curs += 1;} - } - *curs = 0; - gtk_label_set_markup( GTK_LABEL(m68k->uLabel), buf ); -} - -static void yui_m68k_step( GtkWidget* widget, YuiM68k * m68k ) { - - M68KStep(); - yui_window_invalidate( yui ); /* update all dialogs, including us */ -} - -static void yui_m68k_editedReg( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiM68k *m68k) { - /* registry number value has been set to */ - - GtkTreeIter iter; - char bptext[10]; - char *endptr; - int i = atoi(arg1); - u32 addr; - - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( m68k->regListStore ), &iter, arg1 ); - addr = strtoul(arg2, &endptr, 16 ); - if ( endptr - arg2 == strlen(arg2) ) { - - sprintf(bptext, "%08X", (int)addr); - m68ksetRegister( m68k, i, addr ); - gtk_list_store_set( GTK_LIST_STORE( m68k->regListStore ), &iter, 1, bptext, -1 ); - } - yui_window_invalidate( yui ); -} - -static void yui_m68k_editedBp( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiM68k *m68k) { - /* breakpoint has been set to address */ - - GtkTreeIter iter; - char bptext[10]; - char *endptr; - int i = atoi(arg1); - u32 addr; - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( m68k->bpListStore ), &iter, arg1 ); - addr = strtoul(arg2, &endptr, 16 ); - if ((endptr - arg2 < strlen(arg2)) || (!addr)) addr = 0xFFFFFFFF; - if ( m68k->cbp[i] != 0xFFFFFFFF) M68KDelCodeBreakpoint(m68k->cbp[i]); - m68k->cbp[i] = 0xFFFFFFFF; - - if ((addr!=0xFFFFFFFF)&&(M68KAddCodeBreakpoint(addr) == 0)) { - - sprintf(bptext, "%08X", (int)addr); - m68k->cbp[i] = addr; - } else strcpy(bptext,""); - gtk_list_store_set( GTK_LIST_STORE( m68k->bpListStore ), &iter, 0, bptext, -1 ); -} - -static void debugPauseLoop(void) { /* secondary gtk event loop for the "breakpoint pause" state */ - - while ( !(yui->state & YUI_IS_RUNNING) ) - if ( gtk_main_iteration() ) return; -} - -static void yui_m68k_breakpoint_handler (u32 addr) { - - yui_window_pause(yui); - { - m68kregs_struct regs; - YuiM68k* m68k = YUI_M68K(yui_m68k_new( yui )); - - M68KGetRegisters(®s); - yui_m68k_update_codelist(m68k,regs.PC); - yui_m68k_update_reglist(m68k,®s); - } - debugPauseLoop(); /* execution is suspended inside a normal cycle - enter secondary gtk loop */ -} - - -void yui_m68k_update(YuiM68k * m68k) { - m68kregs_struct m68kregs; - M68KGetRegisters(&m68kregs); - yui_m68k_update_codelist(m68k,m68kregs.PC); - yui_m68k_update_reglist(m68k, &m68kregs); - gtk_widget_set_sensitive(m68k->uLabel, TRUE); - gtk_widget_set_sensitive(m68k->bpList, TRUE); - gtk_widget_set_sensitive(m68k->regList, TRUE); - gtk_widget_set_sensitive(m68k->buttonStep, TRUE); -} - -void yui_m68k_destroy(YuiM68k * m68k) { - g_signal_handler_disconnect(yui, m68k->running_handler); - g_signal_handler_disconnect(yui, m68k->paused_handler); - - yui_m68k = NULL; - - gtk_widget_destroy(GTK_WIDGET(m68k)); -} - -static void yui_m68k_clear(YuiM68k * m68k) { - - gtk_widget_set_sensitive(m68k->uLabel, FALSE); - gtk_widget_set_sensitive(m68k->bpList, FALSE); - gtk_widget_set_sensitive(m68k->regList, FALSE); - gtk_widget_set_sensitive(m68k->buttonStep, FALSE); -} diff --git a/yabause/src/gtk/yuim68k.h b/yabause/src/gtk/yuim68k.h deleted file mode 100644 index 6b1fae9030..0000000000 --- a/yabause/src/gtk/yuim68k.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_M68K_H -#define YUI_M68K_H - -#include -#include -#include - -#include "../scsp.h" -#include "yuiwindow.h" - -G_BEGIN_DECLS - -#define YUI_M68K_TYPE (yui_m68k_get_type ()) -#define YUI_M68K(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_M68K_TYPE, YuiM68k)) -#define YUI_M68K_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_M68K_TYPE, YuiM68kClass)) -#define IS_YUI_M68K(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_M68K_TYPE)) -#define IS_YUI_M68K_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_M68K_TYPE)) - -typedef struct _YuiM68k YuiM68k; -typedef struct _YuiM68kClass YuiM68kClass; - -struct _YuiM68k -{ - GtkWindow dialog; - - GtkWidget *vbox, *vboxmain; - GtkWidget *hbox, *hboxmain; - GtkWidget * buttonStep, * buttonStepOver; - GtkWidget * bpList, *regList, *uLabel, *uFrame; - GtkListStore *bpListStore, *regListStore; - GtkCellRenderer *bpListRenderer, *regListRenderer1, *regListRenderer2; - GtkTreeViewColumn *bpListColumn, *regListColumn1, *regListColumn2; - u32 cbp[MAX_BREAKPOINTS]; /* the list of breakpoint positions, as they can be found in the list widget */ - u32 lastCode; /* offset of last unassembly. Try to reuse it to prevent sliding. */ - gulong paused_handler; - gulong running_handler; -}; - -struct _YuiM68kClass -{ - GtkWindowClass parent_class; - - void (* yui_m68k) (YuiM68k * yv); -}; - -GType yui_m68k_get_type (void); -GtkWidget* yui_m68k_new(YuiWindow * y); -void yui_m68k_update (YuiM68k * m68k); -void yui_m68k_destroy (YuiM68k * sh); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuimem.c b/yabause/src/gtk/yuimem.c deleted file mode 100644 index 6100ca387d..0000000000 --- a/yabause/src/gtk/yuimem.c +++ /dev/null @@ -1,301 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -#include "yuimem.h" -#include "settings.h" - -static void yui_mem_class_init (YuiMemClass * klass); -static void yui_mem_init (YuiMem * yfe); -static void yui_mem_clear (YuiMem * vdp1); -static void yui_mem_address_changed (GtkWidget * w, YuiMem * ym); -static void yui_mem_content_changed ( GtkCellRendererText *cellrenderertext, gchar *arg1, gchar *arg2, YuiMem *ym); -static gboolean yui_mem_pagedown_pressed (GtkWidget *w, gpointer func, gpointer data, gpointer data2, YuiMem *ym); -static gboolean yui_mem_pageup_pressed (GtkWidget *w, gpointer func, gpointer data, gpointer data2, YuiMem *ym); -static void yui_mem_update (YuiMem * ym); -static void yui_mem_combo_changed(GtkWidget * w, YuiMem * ym); -static void yui_mem_pagedown_clicked (GtkToolButton * button, YuiMem * ym); -static void yui_mem_pageup_clicked (GtkToolButton * button, YuiMem * ym); - -struct { gchar* name; u32 address; } quickAddress[] = - { {"VDP2_VRAM_A0", 0x25E00000 }, - {"VDP2_VRAM_A1", 0x25E20000 }, - {"VDP2_VRAM_B0", 0x25E40000 }, - {"VDP2_VRAM_B1", 0x25E60000 }, - {"VDP2_CRAM", 0x25F00000 }, - {"LWRAM", 0x20200000 }, - {"HWRAM", 0x26000000 }, - {"SpriteVRAM", 0x25C00000 }, - {0, 0 } }; - -GType yui_mem_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiMemClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_mem_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiMem), - 0, - (GInstanceInitFunc) yui_mem_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiMem", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_mem_class_init (UNUSED YuiMemClass * klass) { -} - -static void yui_mem_init (YuiMem * yv) { - GtkWidget * view; - GtkCellRenderer * renderer; - GtkTreeViewColumn * column; - GtkAccelGroup *accelGroup; - GtkToolItem * comboItem, * upbutton, * downbutton; - GtkWidget * testbox, * vbox; - gint i; - - gtk_window_set_title(GTK_WINDOW(yv), "Memory dump"); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(yv), vbox); - - yv->toolbar = gtk_toolbar_new(); - gtk_toolbar_set_style(GTK_TOOLBAR(yv->toolbar), GTK_TOOLBAR_ICONS); - gtk_box_pack_start(GTK_BOX(vbox), yv->toolbar, FALSE, FALSE, 0); - - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), gtk_separator_tool_item_new(), 0); - - comboItem = gtk_tool_item_new(); - gtk_tool_item_set_expand(comboItem, FALSE); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), comboItem, 1); - - downbutton = gtk_tool_button_new_from_stock(GTK_STOCK_GO_DOWN); - g_signal_connect(downbutton, "clicked", G_CALLBACK(yui_mem_pagedown_clicked), yv); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), downbutton, 2); - - upbutton = gtk_tool_button_new_from_stock(GTK_STOCK_GO_UP); - g_signal_connect(upbutton, "clicked", G_CALLBACK(yui_mem_pageup_clicked), yv); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), upbutton, 3); - - yv->quickCombo = gtk_combo_box_entry_new_text(); - - gtk_entry_set_width_chars(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(yv->quickCombo))), 8); - - for ( i = 0 ; quickAddress[i].name ; i++ ) - gtk_combo_box_insert_text( GTK_COMBO_BOX( yv->quickCombo ), i, quickAddress[i].name ); - gtk_combo_box_set_active( GTK_COMBO_BOX(yv->quickCombo), 0 ); - g_signal_connect(yv->quickCombo, "changed", G_CALLBACK(yui_mem_combo_changed), yv ); - g_signal_connect(gtk_bin_get_child(GTK_BIN(yv->quickCombo)), "activate", G_CALLBACK(yui_mem_address_changed), yv ); - - testbox = gtk_vbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(testbox), yv->quickCombo, TRUE, FALSE, 0); - gtk_container_add(GTK_CONTAINER(comboItem), testbox); - - yv->store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); - view = gtk_tree_view_new_with_model(GTK_TREE_MODEL (yv->store)); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes("Address", renderer, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (view), column); - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes("Dump", renderer, "text", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (view), column); - g_object_set(G_OBJECT(renderer), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL ); - g_signal_connect(G_OBJECT(renderer), "edited", GTK_SIGNAL_FUNC(yui_mem_content_changed), yv ); - gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 0); - - g_signal_connect(G_OBJECT(yv), "delete-event", GTK_SIGNAL_FUNC(yui_mem_destroy), NULL); - - accelGroup = gtk_accel_group_new (); - gtk_accel_group_connect( accelGroup, GDK_Page_Up, 0, 0, - g_cclosure_new (G_CALLBACK(yui_mem_pageup_pressed), yv, NULL) ); - gtk_accel_group_connect( accelGroup, GDK_Page_Down, 0, 0, - g_cclosure_new (G_CALLBACK(yui_mem_pagedown_pressed), yv, NULL) ); - gtk_window_add_accel_group( GTK_WINDOW( yv ), accelGroup ); - - yv->address = 0; - yv->wLine = 8; - - gtk_window_set_default_size(GTK_WINDOW(yv), 300, -1); -} - -GtkWidget * yui_mem_new(YuiWindow * y) { - GtkWidget * dialog; - YuiMem * yv; - - dialog = GTK_WIDGET(g_object_new(yui_mem_get_type(), NULL)); - yv = YUI_MEM(dialog); - - yv->yui = y; - - if (!( yv->yui->state & YUI_IS_INIT )) { - yui_window_run(yv->yui); - yui_window_pause(yv->yui); - } - - { - GtkToolItem * play_button, * pause_button; - - play_button = gtk_tool_button_new_from_stock("run"); - gtk_action_connect_proxy(gtk_action_group_get_action(yv->yui->action_group, "run"), GTK_WIDGET(play_button)); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), GTK_TOOL_ITEM(play_button), 0); - - pause_button = gtk_tool_button_new_from_stock("pause"); - gtk_action_connect_proxy(gtk_action_group_get_action(yv->yui->action_group, "pause"), GTK_WIDGET(pause_button)); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), GTK_TOOL_ITEM(pause_button), 1); - } - - yv->paused_handler = g_signal_connect_swapped(yv->yui, "paused", G_CALLBACK(yui_mem_update), yv); - yv->running_handler = g_signal_connect_swapped(yv->yui, "running", G_CALLBACK(yui_mem_clear), yv); - - if ((yv->yui->state & (YUI_IS_RUNNING | YUI_IS_INIT)) == YUI_IS_INIT) - yui_mem_update(yv); - - gtk_widget_show_all(GTK_WIDGET(yv)); - - return dialog; -} - -void yui_mem_destroy(YuiMem * ym) { - g_signal_handler_disconnect(ym->yui, ym->running_handler); - g_signal_handler_disconnect(ym->yui, ym->paused_handler); - - gtk_widget_destroy(GTK_WIDGET(ym)); -} - -static void yui_mem_clear(YuiMem * vdp1) { -} - -static void yui_mem_address_changed(GtkWidget * w, YuiMem * ym) { - sscanf(gtk_entry_get_text(GTK_ENTRY(w)), "%x", &ym->address); - yui_mem_update(ym); -} - -static void yui_mem_combo_changed(GtkWidget * w, YuiMem * ym) { - - gint i = gtk_combo_box_get_active( GTK_COMBO_BOX(w) ); - - if (i > -1) { - ym->address = quickAddress[i].address; - yui_mem_update(ym); - } -} - -static gint hexaDigitToInt( gchar c ) { - - if (( c >= '0' )&&( c <= '9' )) return c-'0'; - if (( c >= 'a' )&&( c <= 'f' )) return c-'a' + 0xA; - if (( c >= 'A' )&&( c <= 'F' )) return c-'A' + 0xA; - return -1; -} - -static gboolean yui_mem_pageup_pressed(GtkWidget *w, gpointer func, gpointer data, gpointer data2, YuiMem *ym) { - - ym->address -= 2*ym->wLine; - yui_mem_update(ym); - - return TRUE; -} - -static gboolean yui_mem_pagedown_pressed(GtkWidget *w, gpointer func, gpointer data, gpointer data2, YuiMem *ym) { - - ym->address += 2*ym->wLine; - yui_mem_update(ym); - - return TRUE; -} - -static void yui_mem_pagedown_clicked (GtkToolButton * button, YuiMem * ym) { - ym->address += 2*ym->wLine; - yui_mem_update(ym); -} - -static void yui_mem_pageup_clicked (GtkToolButton * button, YuiMem * ym) { - ym->address -= 2*ym->wLine; - yui_mem_update(ym); -} - -static void yui_mem_content_changed( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiMem *ym) { - /* dump line has been modified - new content is */ - - GtkTreeIter iter; - gint i = atoi(arg1); - gint j,k; - gchar *curs; - u32 addr = ym->address + i*ym->wLine; - - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( ym->store ), &iter, arg1 ); - - /* check the format : wLine*2 hexa digits */ - for ( curs = arg2, j=0 ; *curs ; curs++ ) - if ( hexaDigitToInt( *curs ) != -1 ) j++; - - if ( j != ym->wLine * 2 ) return; - - /* convert */ - for ( curs = arg2, k=-1 ; *curs ; curs++ ) { - - if ( hexaDigitToInt( *curs )!=-1 ) { - - if ( k==-1 ) k = hexaDigitToInt( *curs ); - else { MappedMemoryWriteByte( addr++, 16*k + hexaDigitToInt( *curs ) ); k = -1; - } - } - } - yui_window_invalidate(ym->yui); -} - -static void yui_mem_update(YuiMem * ym) { - int i, j; - GtkTreeIter iter; - char address[10]; - char dump[30]; - - gtk_list_store_clear(ym->store); - - for(i = 0;i < 6;i++) { - sprintf(address, "%08x", ym->address + (8 * i)); - for(j = 0;j < 8;j++) { - sprintf(dump + (j * 3), "%02x ", MappedMemoryReadByte(ym->address + (8 * i) + j)); - } - - gtk_list_store_append(ym->store, &iter); - gtk_list_store_set(GTK_LIST_STORE(ym->store ), &iter, 0, address, 1, dump, -1); - } - - sprintf( address, "%08X", ym->address ); - gtk_entry_set_text( GTK_ENTRY(gtk_bin_get_child(GTK_BIN(ym->quickCombo))), address ); -} diff --git a/yabause/src/gtk/yuimem.h b/yabause/src/gtk/yuimem.h deleted file mode 100644 index c597070b43..0000000000 --- a/yabause/src/gtk/yuimem.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_MEM_H -#define YUI_MEM_H - -#include -#include -#include - -#include "yuiwindow.h" - -G_BEGIN_DECLS - -#define YUI_MEM_TYPE (yui_mem_get_type ()) -#define YUI_MEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_MEM_TYPE, YuiMem)) -#define YUI_MEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_MEM_TYPE, YuiMemClass)) -#define IS_YUI_MEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_MEM_TYPE)) -#define IS_YUI_MEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_MEM_TYPE)) - -typedef struct _YuiMem YuiMem; -typedef struct _YuiMemClass YuiMemClass; - -struct _YuiMem -{ - GtkWindow dialog; - - GtkWidget * toolbar; - - GtkListStore * store; - GtkWidget * quickCombo; - - guint wLine; - guint32 address; - gulong paused_handler; - gulong running_handler; - - YuiWindow * yui; -}; - -struct _YuiMemClass -{ - GtkWindowClass parent_class; - - void (* yui_mem) (YuiMem * yv); -}; - -GType yui_mem_get_type(void); -GtkWidget * yui_mem_new (YuiWindow * yui); -void yui_mem_fill (YuiMem * vdp1); -void yui_mem_destroy (YuiMem * vdp1); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuipage.c b/yabause/src/gtk/yuipage.c deleted file mode 100644 index 2259ed956c..0000000000 --- a/yabause/src/gtk/yuipage.c +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "yuifileentry.h" -#include "yuirange.h" -#include "yuiresolution.h" -#include "yuipage.h" -#include "../core.h" - -static void yui_page_class_init (YuiPageClass * klass); -static void yui_page_init (YuiPage * yfe); - -GType yui_page_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiPageClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_page_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiPage), - 0, - (GInstanceInitFunc) yui_page_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_VBOX, "YuiPage", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_page_class_init (UNUSED YuiPageClass * klass) { -} - -static void yui_page_init (UNUSED YuiPage * yp) { -} - -GtkWidget * yui_page_new(GKeyFile * keyfile) { - GtkWidget * widget; - YuiPage * yp; - - widget = GTK_WIDGET(g_object_new(yui_page_get_type(), NULL)); - yp = YUI_PAGE(widget); - - yp->keyfile = keyfile; - - return widget; -} - -GtkWidget * yui_page_add(YuiPage * yp, const gchar * name) { - GtkWidget * label; - GtkWidget * frame; - GtkWidget * box; - gchar buffer[1024]; - - frame = gtk_frame_new(NULL); - - gtk_box_pack_start(GTK_BOX(yp), frame, FALSE, TRUE, 0); - gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); - - box = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(frame), box); - - sprintf(buffer, "%s", name); - - label = gtk_label_new(buffer); - gtk_frame_set_label_widget(GTK_FRAME(frame), label); - gtk_label_set_use_markup(GTK_LABEL(label), TRUE); - - return box; -} diff --git a/yabause/src/gtk/yuipage.h b/yabause/src/gtk/yuipage.h deleted file mode 100644 index 8bd767e7d6..0000000000 --- a/yabause/src/gtk/yuipage.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_PAGE_H -#define YUI_PAGE_H - -#include -#include -#include - -G_BEGIN_DECLS - -#define YUI_PAGE_TYPE (yui_page_get_type ()) -#define YUI_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_PAGE_TYPE, YuiPage)) -#define YUI_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_PAGE_TYPE, YuiPageClass)) -#define IS_YUI_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_PAGE_TYPE)) -#define IS_YUI_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_PAGE_TYPE)) - -#define YUI_FILE_SETTING 1 -#define YUI_RANGE_SETTING 2 -#define YUI_RESOLUTION_SETTING 3 - -typedef struct _YuiPage YuiPage; -typedef struct _YuiPageClass YuiPageClass; - -struct _YuiPage -{ - GtkVBox vbox; - - GKeyFile * keyfile; -}; - -struct _YuiPageClass -{ - GtkHBoxClass parent_class; - - void (* yui_page) (YuiPage * yfe); -}; - -GType yui_page_get_type (void); -GtkWidget * yui_page_new (GKeyFile * keyfile); - -GtkWidget * yui_page_add (YuiPage * yp, const gchar * name); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuirange.c b/yabause/src/gtk/yuirange.c deleted file mode 100644 index dc8efeba7d..0000000000 --- a/yabause/src/gtk/yuirange.c +++ /dev/null @@ -1,152 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -#include "yuirange.h" - -static void yui_range_class_init (YuiRangeClass * klass); -static void yui_range_init (YuiRange * yfe); -static void yui_range_changed (GtkWidget * widget, YuiRange * yfe); - -GType yui_range_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiRangeClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_range_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiRange), - 0, - (GInstanceInitFunc) yui_range_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_HBOX, "YuiRange", &yfe_info, 0); - } - - return yfe_type; -} - -#define PROP_KEYFILE 1 -#define PROP_GROUP 2 -#define PROP_KEY 3 -#define PROP_ITEMS 4 - -static void yui_range_set_property(GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) { - switch(property_id) { - case PROP_KEYFILE: - YUI_RANGE(object)->keyfile = g_value_get_pointer(value); - break; - case PROP_GROUP: - YUI_RANGE(object)->group = g_value_get_pointer(value); - break; - case PROP_KEY: - YUI_RANGE(object)->key = g_value_get_pointer(value); - break; - case PROP_ITEMS: - YUI_RANGE(object)->items = g_value_get_pointer(value); - break; - } -} - -static void yui_range_get_property(GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) { -} - -enum { YUI_RANGE_CHANGED_SIGNAL, LAST_SIGNAL }; - -static guint yui_range_signals[LAST_SIGNAL] = { 0 }; - -static void yui_range_class_init (YuiRangeClass * klass) { - GParamSpec * param; - - G_OBJECT_CLASS(klass)->set_property = yui_range_set_property; - G_OBJECT_CLASS(klass)->get_property = yui_range_get_property; - - param = g_param_spec_pointer("key-file", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEYFILE, param); - - param = g_param_spec_pointer("group", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_GROUP, param); - - param = g_param_spec_pointer("key", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEY, param); - - param = g_param_spec_pointer("items", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_ITEMS, param); - - yui_range_signals[YUI_RANGE_CHANGED_SIGNAL] = g_signal_new ("changed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET(YuiRangeClass, yui_range_change), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); -} - -static void yui_range_init (YuiRange * yfe) { - gtk_container_set_border_width(GTK_CONTAINER(yfe), 10); - - yfe->combo = gtk_combo_box_new_text(); - - gtk_box_pack_start(GTK_BOX(yfe), yfe->combo, TRUE, TRUE, 0); -} - -GtkWidget * yui_range_new(GKeyFile * keyfile, const gchar * group, const gchar * key, YuiRangeItem * items) { - GtkWidget * entry; - YuiRange * yfe; - gchar * current; - guint i; - - entry = GTK_WIDGET(g_object_new(yui_range_get_type(), "spacing", 10, - "key-file", keyfile, "group", group, "key", key, "items", items, NULL)); - yfe = YUI_RANGE(entry); - - current = g_key_file_get_value(yfe->keyfile, yfe->group, yfe->key, 0); - i = 0; - while(yfe->items[i].name) { - gtk_combo_box_append_text(GTK_COMBO_BOX(yfe->combo), yfe->items[i].name); - if (current && !strcmp(yfe->items[i].value, current)) - gtk_combo_box_set_active(GTK_COMBO_BOX(yfe->combo), i); - i++; - } - if ( !current ) { - gtk_combo_box_set_active(GTK_COMBO_BOX(yfe->combo), 0); - g_key_file_set_value(yfe->keyfile, yfe->group, yfe->key, items[0].value); - } - - g_signal_connect(GTK_COMBO_BOX(yfe->combo), "changed", G_CALLBACK(yui_range_changed), yfe); - - return entry; -} - -static void yui_range_changed(GtkWidget * entry, YuiRange * yfe) { - g_key_file_set_value(yfe->keyfile, yfe->group, yfe->key, - yfe->items[gtk_combo_box_get_active(GTK_COMBO_BOX(yfe->combo))].value); - g_signal_emit(G_OBJECT(yfe), yui_range_signals[YUI_RANGE_CHANGED_SIGNAL], 0); -} - -gint yui_range_get_active(YuiRange * range) { - return gtk_combo_box_get_active(GTK_COMBO_BOX(range->combo)); -} diff --git a/yabause/src/gtk/yuirange.h b/yabause/src/gtk/yuirange.h deleted file mode 100644 index f973c87e4b..0000000000 --- a/yabause/src/gtk/yuirange.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_RANGE_H -#define YUI_RANGE_H - -#include -#include -#include - -G_BEGIN_DECLS - -#define YUI_RANGE_TYPE (yui_range_get_type ()) -#define YUI_RANGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_RANGE_TYPE, YuiRange)) -#define YUI_RANGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_RANGE_TYPE, YuiRangeClass)) -#define IS_YUI_RANGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_RANGE_TYPE)) -#define IS_YUI_RANGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_RANGE_TYPE)) - -typedef struct _YuiRangeItem YuiRangeItem; -typedef struct _YuiRange YuiRange; -typedef struct _YuiRangeClass YuiRangeClass; - -struct _YuiRangeItem -{ - const gchar * value; - const gchar * name; -}; - -struct _YuiRange -{ - GtkHBox hbox; - - GtkWidget * combo; - - GKeyFile * keyfile; - gchar * group; - gchar * key; - - YuiRangeItem * items; -}; - -struct _YuiRangeClass -{ - GtkHBoxClass parent_class; - - void (* yui_range_change) (YuiRange * yfe); -}; - -GType yui_range_get_type (void); -GtkWidget * yui_range_new (GKeyFile * keyfile, const gchar * group, const gchar * key, YuiRangeItem * items); -gint yui_range_get_active (YuiRange * range); - -G_END_DECLS - -#endif /* YUI_RANGE_H */ diff --git a/yabause/src/gtk/yuiresolution.c b/yabause/src/gtk/yuiresolution.c deleted file mode 100644 index 41a7afa6c5..0000000000 --- a/yabause/src/gtk/yuiresolution.c +++ /dev/null @@ -1,170 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include -#include -#include "yuiresolution.h" - -static void yui_resolution_class_init (YuiResolutionClass *klass); -static void yui_resolution_init (YuiResolution *yie); -static void yui_resolution_width_changed (GtkWidget * w, YuiResolution * yr); -static void yui_resolution_height_changed (GtkWidget * w, YuiResolution * yr); -static void yui_resolution_options_changed (GtkWidget * w, YuiResolution * yr); - -GType yui_resolution_get_type (void) { - static GType yie_type = 0; - - if (!yie_type) { - static const GTypeInfo yie_info = { - sizeof (YuiResolutionClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_resolution_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiResolution), - 0, - (GInstanceInitFunc) yui_resolution_init, - NULL, - }; - - yie_type = g_type_register_static (GTK_TYPE_HBOX, "YuiResolution", &yie_info, 0); - } - - return yie_type; -} - -#define PROP_KEYFILE 1 -#define PROP_GROUP 2 - -static void yui_resolution_set_property(GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) { - switch(property_id) { - case PROP_KEYFILE: - YUI_RESOLUTION(object)->keyfile = g_value_get_pointer(value); - break; - case PROP_GROUP: - YUI_RESOLUTION(object)->group = g_value_get_pointer(value); - break; - } -} - -static void yui_resolution_get_property(GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) { -} - -static void yui_resolution_class_init (YuiResolutionClass *klass) { - GParamSpec * param; - - G_OBJECT_CLASS(klass)->set_property = yui_resolution_set_property; - G_OBJECT_CLASS(klass)->get_property = yui_resolution_get_property; - - param = g_param_spec_pointer("key-file", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEYFILE, param); - - param = g_param_spec_pointer("group", 0, 0, G_PARAM_READABLE | G_PARAM_WRITABLE); - g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_GROUP, param); -} - -static void yui_resolution_init(YuiResolution * yr) { - GtkWidget * label_w; - GtkWidget * label_h; - - gtk_container_set_border_width (GTK_CONTAINER (yr), 10); - - label_w = gtk_label_new ("Width"); - gtk_box_pack_start(GTK_BOX(yr), label_w, TRUE, TRUE, 0); - - yr->entry_w = gtk_entry_new (); - gtk_entry_set_width_chars(GTK_ENTRY(yr->entry_w), 8); - gtk_box_pack_start(GTK_BOX(yr), yr->entry_w, TRUE, TRUE, 0); - - label_h = gtk_label_new ("Height"); - gtk_box_pack_start(GTK_BOX(yr), label_h, TRUE, TRUE, 0); - - yr->entry_h = gtk_entry_new (); - gtk_entry_set_width_chars(GTK_ENTRY(yr->entry_h), 8); - gtk_box_pack_start(GTK_BOX(yr), yr->entry_h, TRUE, TRUE, 0); - - yr->options = gtk_combo_box_new_text(); - gtk_combo_box_append_text(GTK_COMBO_BOX(yr->options), "Window"); - gtk_combo_box_append_text(GTK_COMBO_BOX(yr->options), "Fullscreen"); - gtk_combo_box_append_text(GTK_COMBO_BOX(yr->options), "Keep ratio"); - gtk_box_pack_start(GTK_BOX(yr), yr->options, TRUE, TRUE, 0); - - g_signal_connect(yr->entry_w, "changed", G_CALLBACK(yui_resolution_width_changed), yr); - g_signal_connect(yr->entry_h, "changed", G_CALLBACK(yui_resolution_height_changed), yr); - g_signal_connect(yr->options, "changed", G_CALLBACK(yui_resolution_options_changed), yr); -} - -GtkWidget* yui_resolution_new(GKeyFile * keyfile, const gchar * group) { - GtkWidget * widget; - YuiResolution * yr; - gchar *widthText, *heightText; - - widget = GTK_WIDGET(g_object_new(yui_resolution_get_type(), "key-file", keyfile, "group", group, NULL)); - yr = YUI_RESOLUTION(widget); - - widthText = g_key_file_get_value(yr->keyfile, yr->group, "Width", 0); - if ( !widthText ) widthText = ""; - heightText = g_key_file_get_value(yr->keyfile, yr->group, "Height", 0); - if ( !heightText ) heightText = ""; - gtk_entry_set_text(GTK_ENTRY(yr->entry_w), widthText ); - gtk_entry_set_text(GTK_ENTRY(yr->entry_h), heightText ); - if (g_key_file_get_integer(yr->keyfile, yr->group, "Fullscreen", 0) == 1) - gtk_combo_box_set_active(GTK_COMBO_BOX(yr->options), 1); - else if (g_key_file_get_integer(yr->keyfile, yr->group, "KeepRatio", 0) == 1) - gtk_combo_box_set_active(GTK_COMBO_BOX(yr->options), 2); - else - gtk_combo_box_set_active(GTK_COMBO_BOX(yr->options), 0); - - return widget; -} - -static void yui_resolution_width_changed(GtkWidget * w, YuiResolution * yr) { - g_key_file_set_value(yr->keyfile, yr->group, "Width", gtk_entry_get_text(GTK_ENTRY(w))); -} - -static void yui_resolution_height_changed(GtkWidget * w, YuiResolution * yr) { - g_key_file_set_value(yr->keyfile, yr->group, "Height", gtk_entry_get_text(GTK_ENTRY(w))); -} - -static void yui_resolution_options_changed(GtkWidget * w, YuiResolution * yr) { - gint active = gtk_combo_box_get_active(GTK_COMBO_BOX(yr->options)); - switch(active) { - case 0: - g_key_file_set_integer(yr->keyfile, yr->group, "Fullscreen", 0); - g_key_file_set_integer(yr->keyfile, yr->group, "KeepRatio", 0); - break; - case 1: - g_key_file_set_integer(yr->keyfile, yr->group, "Fullscreen", 1); - g_key_file_set_integer(yr->keyfile, yr->group, "KeepRatio", 0); - break; - case 2: - g_key_file_set_integer(yr->keyfile, yr->group, "Fullscreen", 0); - g_key_file_set_integer(yr->keyfile, yr->group, "KeepRatio", 1); - break; - } -} diff --git a/yabause/src/gtk/yuiresolution.h b/yabause/src/gtk/yuiresolution.h deleted file mode 100644 index ae9088e3e8..0000000000 --- a/yabause/src/gtk/yuiresolution.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_RESOLUTION_H -#define YUI_RESOLUTION_H - -#include -#include -#include - -G_BEGIN_DECLS - -#define YUI_RESOLUTION_TYPE (yui_resolution_get_type ()) -#define YUI_RESOLUTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_RESOLUTION_TYPE, YuiResolution)) -#define YUI_RESOLUTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_RESOLUTION_TYPE, YuiResolutionClass)) -#define IS_YUI_RESOLUTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_RESOLUTION_TYPE)) -#define IS_YUI_RESOLUTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_RESOLUTION_TYPE)) - - -typedef struct _YuiResolution YuiResolution; -typedef struct _YuiResolutionClass YuiResolutionClass; - -struct _YuiResolution -{ - GtkHBox table; - - GtkWidget * entry_w; - GtkWidget * entry_h; - GtkWidget * options; - - GKeyFile * keyfile; - gchar * group; -}; - -struct _YuiResolutionClass { - GtkHBoxClass parent_class; - - void (* yui_resolution) (YuiResolution *yie); -}; - -GType yui_resolution_get_type (void); -GtkWidget* yui_resolution_new (GKeyFile * keyfile, const gchar * group); - -G_END_DECLS - -#endif /* YUI_RESOLUTION_H */ diff --git a/yabause/src/gtk/yuiscreenshot.c b/yabause/src/gtk/yuiscreenshot.c deleted file mode 100644 index 5f53f1ea24..0000000000 --- a/yabause/src/gtk/yuiscreenshot.c +++ /dev/null @@ -1,127 +0,0 @@ -/* Copyright 2006-2007 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "yuiscreenshot.h" -#include "gtkglwidget.h" -#include "yuiviewer.h" -#include "../core.h" - -static void yui_screenshot_class_init (YuiScreenshotClass * klass); -static void yui_screenshot_init (YuiScreenshot * yfe); -static void yui_screenshot_update (YuiScreenshot * ys, gpointer data); -static gboolean yui_screenshot_draw(YuiScreenshot * ys); - -GType yui_screenshot_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiScreenshotClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_screenshot_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiScreenshot), - 0, - (GInstanceInitFunc) yui_screenshot_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiScreenshot", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_screenshot_class_init (UNUSED YuiScreenshotClass * klass) { -} - -static YuiWindow * yui; - -static void yui_screenshot_init (YuiScreenshot * yv) { - GtkWidget * box; - GtkWidget * button_box; - GtkWidget * button; - - gtk_window_set_title(GTK_WINDOW(yv), "Screenshot"); - gtk_container_set_border_width(GTK_CONTAINER(yv), 4); - - box = gtk_vbox_new(FALSE, 4); - gtk_container_add(GTK_CONTAINER(yv), box); - - yv->image = yui_viewer_new(); - gtk_box_pack_start(GTK_BOX(box), yv->image, FALSE, FALSE, 0); - gtk_widget_set_size_request(GTK_WIDGET(yv->image), 320, 224); - - button_box = gtk_hbutton_box_new(); - gtk_box_pack_start(GTK_BOX(box), button_box, FALSE, FALSE, 0); - - button = gtk_button_new_from_stock(GTK_STOCK_REFRESH); - gtk_box_pack_start(GTK_BOX(button_box), button, FALSE, FALSE, 0); - g_signal_connect_swapped(button, "clicked", G_CALLBACK(yui_screenshot_update), yv); - - button = gtk_button_new_from_stock(GTK_STOCK_SAVE); - gtk_box_pack_start(GTK_BOX(button_box), button, FALSE, FALSE, 0); - g_signal_connect_swapped(button, "clicked", G_CALLBACK(yui_viewer_save), yv->image); - - button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); - gtk_box_pack_start(GTK_BOX(button_box), button, FALSE, FALSE, 0); - g_signal_connect_swapped(button, "clicked", G_CALLBACK(gtk_widget_destroy), yv); -} - -GtkWidget * yui_screenshot_new(YuiWindow * y) { - GtkWidget * dialog; - YuiScreenshot * yv; - - yui = y; - - dialog = GTK_WIDGET(g_object_new(yui_screenshot_get_type(), NULL)); - yv = YUI_SCREENSHOT(dialog); - - gtk_widget_show_all(dialog); - - yui_gl_dump_screen(YUI_GL(yui->area)); - yui_screenshot_draw(yv); - - return dialog; -} - -static void yui_screenshot_update(YuiScreenshot * ys, UNUSED gpointer data) { - yui_gl_dump_screen(YUI_GL(yui->area)); - yui_screenshot_draw(ys); -} - -static gboolean yui_screenshot_draw(YuiScreenshot * ys) { - GdkPixbuf * pixbuf, * correct; - - pixbuf = gdk_pixbuf_new_from_data((const guchar *) YUI_GL(yui->area)->pixels, GDK_COLORSPACE_RGB, FALSE, 8, - YUI_GL(yui->area)->pixels_width, YUI_GL(yui->area)->pixels_height, YUI_GL(yui->area)->pixels_rowstride, NULL, NULL); - correct = gdk_pixbuf_flip(pixbuf, FALSE); - - yui_viewer_draw_pixbuf(YUI_VIEWER(ys->image), correct, YUI_GL(yui->area)->pixels_width, YUI_GL(yui->area)->pixels_height); - - g_object_unref(pixbuf); - g_object_unref(correct); - - return TRUE; -} diff --git a/yabause/src/gtk/yuiscreenshot.h b/yabause/src/gtk/yuiscreenshot.h deleted file mode 100644 index 8a820f727d..0000000000 --- a/yabause/src/gtk/yuiscreenshot.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_SCREENSHOT_H -#define YUI_SCREENSHOT_H - -#include - -#include "yuiwindow.h" - -G_BEGIN_DECLS - -#define YUI_SCREENSHOT_TYPE (yui_screenshot_get_type ()) -#define YUI_SCREENSHOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_SCREENSHOT_TYPE, YuiScreenshot)) -#define YUI_SCREENSHOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_SCREENSHOT_TYPE, YuiScreenshotClass)) -#define IS_YUI_SCREENSHOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_SCREENSHOT_TYPE)) -#define IS_YUI_SCREENSHOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_SCREENSHOT_TYPE)) - -typedef struct _YuiScreenshot YuiScreenshot; -typedef struct _YuiScreenshotClass YuiScreenshotClass; - -struct _YuiScreenshot -{ - GtkWindow dialog; - - GtkWidget * image; -}; - -struct _YuiScreenshotClass -{ - GtkWindowClass parent_class; -}; - -GType yui_screenshot_get_type (void); -GtkWidget * yui_screenshot_new (YuiWindow * yui); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuiscsp.c b/yabause/src/gtk/yuiscsp.c deleted file mode 100644 index fd74c9f30a..0000000000 --- a/yabause/src/gtk/yuiscsp.c +++ /dev/null @@ -1,159 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "yuiscsp.h" -#include "../scsp.h" -#include "../yabause.h" -#include "settings.h" - -static void yui_scsp_class_init (YuiScspClass * klass); -static void yui_scsp_init (YuiScsp * yfe); -static void yui_scsp_spin_cursor_changed(GtkWidget * spin, YuiScsp * scsp); -static void yui_scsp_clear(YuiScsp * scsp); - -GType yui_scsp_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiScspClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_scsp_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiScsp), - 0, - (GInstanceInitFunc) yui_scsp_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiScsp", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_scsp_class_init (UNUSED YuiScspClass * klass) { -} - -static void yui_scsp_init (YuiScsp * yv) { - gtk_window_set_title(GTK_WINDOW(yv), "SCSP"); - - yv->vbox = gtk_vbox_new(FALSE, 2); - gtk_container_set_border_width(GTK_CONTAINER(yv->vbox), 4); - gtk_container_add(GTK_CONTAINER(yv), yv->vbox); - - yv->spin = gtk_spin_button_new_with_range(0, 31, 1); - gtk_spin_button_set_range(GTK_SPIN_BUTTON(yv->spin), 0, 31); - gtk_box_pack_start(GTK_BOX(yv->vbox), yv->spin, FALSE, FALSE, 4); - g_signal_connect(G_OBJECT(yv->spin), "value-changed", GTK_SIGNAL_FUNC(yui_scsp_spin_cursor_changed), yv); - - g_signal_connect(G_OBJECT(yv), "delete-event", GTK_SIGNAL_FUNC(yui_scsp_destroy), NULL); - - { - GtkWidget * scroll = gtk_scrolled_window_new(NULL, NULL); - GtkWidget * text = gtk_text_view_new(); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE); - gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(text), FALSE); - yv->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)); - gtk_container_add(GTK_CONTAINER(scroll), text); - gtk_box_pack_start(GTK_BOX(yv->vbox), scroll, TRUE, TRUE, 4); - } - - yv->hbox = gtk_hbutton_box_new(); - gtk_box_set_spacing(GTK_BOX(yv->hbox), 4); - gtk_box_pack_start(GTK_BOX(yv->vbox ), yv->hbox, FALSE, FALSE, 4); - - yv->cursor = 0; -} - -static gulong paused_handler; -static gulong running_handler; -static YuiWindow * yui; - -GtkWidget * yui_scsp_new(YuiWindow * y) { - GtkWidget * dialog; - YuiScsp * yv; - - yui = y; - - dialog = GTK_WIDGET(g_object_new(yui_scsp_get_type(), NULL)); - yv = YUI_SCSP(dialog); - - { - GtkWidget * but2, * but3, * but4; - but2 = gtk_button_new(); - gtk_action_connect_proxy(gtk_action_group_get_action(yui->action_group, "run"), but2); - gtk_box_pack_start(GTK_BOX(yv->hbox), but2, FALSE, FALSE, 2); - - but3 = gtk_button_new(); - gtk_action_connect_proxy(gtk_action_group_get_action(yui->action_group, "pause"), but3); - gtk_box_pack_start(GTK_BOX(yv->hbox), but3, FALSE, FALSE, 2); - - but4 = gtk_button_new_from_stock("gtk-close"); - g_signal_connect_swapped(but4, "clicked", G_CALLBACK(yui_scsp_destroy), dialog); - gtk_box_pack_start(GTK_BOX(yv->hbox), but4, FALSE, FALSE, 2); - } - paused_handler = g_signal_connect_swapped(yui, "paused", G_CALLBACK(yui_scsp_update), yv); - running_handler = g_signal_connect_swapped(yui, "running", G_CALLBACK(yui_scsp_clear), yv); - - if ((yui->state & (YUI_IS_RUNNING | YUI_IS_INIT)) == YUI_IS_INIT) - yui_scsp_update(yv); - - gtk_widget_show_all(GTK_WIDGET(yv)); - - return dialog; -} - -void yui_scsp_fill(YuiScsp * scsp) { - gchar nameTemp[1024]; - - yui_scsp_clear(scsp); - - ScspSlotDebugStats(scsp->cursor, nameTemp ); - - gtk_text_buffer_set_text(scsp->buffer, g_strstrip(nameTemp), -1); -} - -static void yui_scsp_spin_cursor_changed(GtkWidget * spin, YuiScsp * scsp) { - scsp->cursor = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin)); - yui_scsp_fill(scsp); -} - -void yui_scsp_update(YuiScsp * scsp) { - yui_scsp_fill(scsp); -} - -void yui_scsp_destroy(YuiScsp * scsp) { - g_signal_handler_disconnect(yui, running_handler); - g_signal_handler_disconnect(yui, paused_handler); - - gtk_widget_destroy(GTK_WIDGET(scsp)); -} - -static void yui_scsp_clear(YuiScsp * scsp) { - gtk_text_buffer_set_text(scsp->buffer, "", -1); -} diff --git a/yabause/src/gtk/yuiscsp.h b/yabause/src/gtk/yuiscsp.h deleted file mode 100644 index 1c2cb82f54..0000000000 --- a/yabause/src/gtk/yuiscsp.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_SCSP_H -#define YUI_SCSP_H - -#include -#include -#include - -#include "yuiwindow.h" - -G_BEGIN_DECLS - -#define YUI_SCSP_TYPE (yui_scsp_get_type ()) -#define YUI_SCSP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_SCSP_TYPE, YuiScsp)) -#define YUI_SCSP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_SCSP_TYPE, YuiScspClass)) -#define IS_YUI_SCSP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_SCSP_TYPE)) -#define IS_YUI_SCSP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_SCSP_TYPE)) - -typedef struct _YuiScsp YuiScsp; -typedef struct _YuiScspClass YuiScspClass; - -struct _YuiScsp -{ - GtkWindow dialog; - - GtkWidget * vbox; - GtkWidget * hbox; - GtkWidget * commName; - GtkWidget * commDesc; - GtkWidget * spin; - - GtkTextBuffer * buffer; - - gint cursor; -}; - -struct _YuiScspClass -{ - GtkWindowClass parent_class; - - void (* yui_scsp) (YuiScsp * yv); -}; - -GType yui_scsp_get_type (void); -GtkWidget * yui_scsp_new (YuiWindow * yui); -void yui_scsp_fill (YuiScsp * scsp); -void yui_scsp_update (YuiScsp * scsp); -void yui_scsp_destroy (YuiScsp * scsp); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuiscudsp.c b/yabause/src/gtk/yuiscudsp.c deleted file mode 100644 index 3a8f311a50..0000000000 --- a/yabause/src/gtk/yuiscudsp.c +++ /dev/null @@ -1,425 +0,0 @@ -/* Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -#include "yuiscudsp.h" -#include "../scu.h" -#include "../yabause.h" -#include "settings.h" - -static void yui_scudsp_class_init (YuiScudspClass * klass); -static void yui_scudsp_init (YuiScudsp * yfe); -static void yui_scudsp_clear(YuiScudsp * scudsp); -static void yui_scudsp_editedReg( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiScudsp *scudsp); -static void yui_scudsp_editedBp( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiScudsp *scudsp); -static void yui_scudsp_step( GtkWidget* widget, YuiScudsp * scudsp ); -static void yui_scudsp_breakpoint_handler (u32 addr); - -static YuiScudsp *yui_scudsp; -static YuiWindow * yui; - -GType yui_scudsp_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiScudspClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_scudsp_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiScudsp), - 0, - (GInstanceInitFunc) yui_scudsp_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiScudsp", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_scudsp_class_init (UNUSED YuiScudspClass * klass) { -} - -static void yui_scudsp_init (YuiScudsp * scudsp) { - gtk_window_set_title(GTK_WINDOW(scudsp), "SCU-DSP"); - gtk_window_set_resizable( GTK_WINDOW(scudsp), FALSE ); - - scudsp->vbox = gtk_vbox_new(FALSE, 2); - gtk_container_set_border_width( GTK_CONTAINER( scudsp->vbox ),4 ); - gtk_container_add (GTK_CONTAINER (scudsp), scudsp->vbox); - - scudsp->hboxmain = gtk_hbox_new(FALSE, 2); - gtk_container_set_border_width( GTK_CONTAINER( scudsp->hboxmain ),4 ); - gtk_box_pack_start( GTK_BOX( scudsp->vbox ), scudsp->hboxmain, FALSE, FALSE, 4 ); - - scudsp->hbox = gtk_hbutton_box_new(); - gtk_container_set_border_width( GTK_CONTAINER( scudsp->hbox ),4 ); - gtk_box_pack_start( GTK_BOX( scudsp->vbox ), scudsp->hbox, FALSE, FALSE, 4 ); - - scudsp->vboxmain = gtk_vbox_new(FALSE, 2); - gtk_container_set_border_width( GTK_CONTAINER( scudsp->vboxmain ),4 ); - gtk_box_pack_start( GTK_BOX( scudsp->hboxmain ), scudsp->vboxmain, FALSE, FALSE, 4 ); - - /* unassembler frame */ - - scudsp->uFrame = gtk_frame_new("Disassembled code"); - gtk_box_pack_start( GTK_BOX( scudsp->vboxmain ), scudsp->uFrame, FALSE, FALSE, 4 ); - - scudsp->uLabel = gtk_label_new(NULL); - gtk_container_add (GTK_CONTAINER (scudsp->uFrame), scudsp->uLabel ); - - /* Register list */ - - scudsp->regListStore = gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_STRING); - scudsp->regList = gtk_tree_view_new_with_model( GTK_TREE_MODEL(scudsp->regListStore) ); - scudsp->regListRenderer1 = gtk_cell_renderer_text_new(); - scudsp->regListRenderer2 = gtk_cell_renderer_text_new(); - g_object_set(G_OBJECT(scudsp->regListRenderer2), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL ); - scudsp->regListColumn1 = gtk_tree_view_column_new_with_attributes("Register", scudsp->regListRenderer1, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(scudsp->regList), scudsp->regListColumn1); - scudsp->regListColumn2 = gtk_tree_view_column_new_with_attributes("Value", scudsp->regListRenderer2, "text", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(scudsp->regList), scudsp->regListColumn2); - gtk_box_pack_start( GTK_BOX( scudsp->hboxmain ), scudsp->regList, FALSE, FALSE, 4 ); - g_signal_connect(G_OBJECT(scudsp->regListRenderer2), "edited", GTK_SIGNAL_FUNC(yui_scudsp_editedReg), scudsp ); - - /* breakpoint list */ - - scudsp->bpListStore = gtk_list_store_new(1,G_TYPE_STRING); - scudsp->bpList = gtk_tree_view_new_with_model( GTK_TREE_MODEL(scudsp->bpListStore) ); - scudsp->bpListRenderer = gtk_cell_renderer_text_new(); - g_object_set(G_OBJECT(scudsp->bpListRenderer), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL ); - scudsp->bpListColumn = gtk_tree_view_column_new_with_attributes("Breakpoints", scudsp->bpListRenderer, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(scudsp->bpList), scudsp->bpListColumn); - gtk_box_pack_start( GTK_BOX( scudsp->hboxmain ), scudsp->bpList, FALSE, FALSE, 4 ); - g_signal_connect(G_OBJECT(scudsp->bpListRenderer), "edited", GTK_SIGNAL_FUNC(yui_scudsp_editedBp), scudsp ); - - g_signal_connect(G_OBJECT(scudsp), "delete-event", GTK_SIGNAL_FUNC(yui_scudsp_destroy), NULL); -} - - -GtkWidget * yui_scudsp_new(YuiWindow * y) { - GtkWidget * dialog; - GClosure *closureF7; - GtkAccelGroup *accelGroup; - const scucodebreakpoint_struct *cbp; - gint i; - yui = y; - - if ( yui_scudsp ) return GTK_WIDGET(yui_scudsp); - - dialog = GTK_WIDGET(g_object_new(yui_scudsp_get_type(), NULL)); - yui_scudsp = YUI_SCUDSP(dialog); - - if (!( yui->state & YUI_IS_INIT )) { - yui_window_run(yui); - yui_window_pause(yui); - } - - ScuDspSetBreakpointCallBack(&yui_scudsp_breakpoint_handler); - - for (i = 0; i < 23 ; i++) { - - GtkTreeIter iter; - gtk_list_store_append( GTK_LIST_STORE( yui_scudsp->regListStore ), &iter ); - } - - cbp = ScuDspGetBreakpointList(); - - for (i = 0; i < MAX_BREAKPOINTS; i++) { - - GtkTreeIter iter; - yui_scudsp->cbp[i] = cbp[i].addr; - gtk_list_store_append( GTK_LIST_STORE( yui_scudsp->bpListStore ), &iter ); - if (cbp[i].addr != 0xFFFFFFFF) { - - gchar tempstr[20]; - sprintf(tempstr, "%08X", (int)cbp[i].addr); - gtk_list_store_set( GTK_LIST_STORE( yui_scudsp->bpListStore ), &iter, 0, tempstr, -1 ); - } else gtk_list_store_set( GTK_LIST_STORE( yui_scudsp->bpListStore ), &iter, 0, "", -1 ); - } - - { - GtkWidget * but2, * but3, * but4; - - yui_scudsp->buttonStep = gtk_button_new_with_label( "Step [F7]" ); - gtk_box_pack_start( GTK_BOX( yui_scudsp->hbox ), yui_scudsp->buttonStep, FALSE, FALSE, 2 ); - g_signal_connect( yui_scudsp->buttonStep, "clicked", G_CALLBACK(yui_scudsp_step), yui_scudsp ); - - but2 = gtk_button_new(); - gtk_action_connect_proxy(gtk_action_group_get_action(yui->action_group, "run"), but2); - gtk_box_pack_start(GTK_BOX(yui_scudsp->hbox), but2, FALSE, FALSE, 2); - - but3 = gtk_button_new(); - gtk_action_connect_proxy(gtk_action_group_get_action(yui->action_group, "pause"), but3); - gtk_box_pack_start(GTK_BOX(yui_scudsp->hbox), but3, FALSE, FALSE, 2); - - but4 = gtk_button_new_from_stock("gtk-close"); - g_signal_connect_swapped(but4, "clicked", G_CALLBACK(yui_scudsp_destroy), dialog); - gtk_box_pack_start(GTK_BOX(yui_scudsp->hbox), but4, FALSE, FALSE, 2); - } - yui_scudsp->paused_handler = g_signal_connect_swapped(yui, "paused", G_CALLBACK(yui_scudsp_update), yui_scudsp); - yui_scudsp->running_handler = g_signal_connect_swapped(yui, "running", G_CALLBACK(yui_scudsp_clear), yui_scudsp); - accelGroup = gtk_accel_group_new (); - closureF7 = g_cclosure_new (G_CALLBACK (yui_scudsp_step), yui_scudsp, NULL); - gtk_accel_group_connect( accelGroup, GDK_F7, 0, 0, closureF7 ); - gtk_window_add_accel_group( GTK_WINDOW( dialog ), accelGroup ); - - yui_scudsp_update(yui_scudsp); - if ( yui->state & YUI_IS_RUNNING ) yui_scudsp_clear(yui_scudsp); - - gtk_widget_show_all(GTK_WIDGET(yui_scudsp)); - - return dialog; -} - - -static void yui_scudsp_update_reglist( YuiScudsp *scudsp, scudspregs_struct *regs) { - /* refrescudsp the registery list */ - - GtkTreeIter iter; - char valuestr[32]; - - gtk_tree_model_get_iter_first( GTK_TREE_MODEL( scudsp->regListStore ), &iter ); - sprintf(valuestr, "%d", regs->ProgControlPort.part.PR); - gtk_list_store_set( GTK_LIST_STORE( scudsp->regListStore ), &iter, 0, "PR", 1, valuestr, -1 ); - - #define SCUDSPUPDATEREGLISTp(rreg,format) \ - gtk_tree_model_iter_next( GTK_TREE_MODEL( scudsp->regListStore ), &iter ); \ - sprintf(valuestr, #format, (int)regs->ProgControlPort.part.rreg); \ - gtk_list_store_set( GTK_LIST_STORE( scudsp->regListStore ), &iter, 0, #rreg, 1, valuestr, -1 ); - #define SCUDSPUPDATEREGLIST(rreg,format) \ - gtk_tree_model_iter_next( GTK_TREE_MODEL( scudsp->regListStore ), &iter ); \ - sprintf(valuestr, #format, (int)regs->rreg); \ - gtk_list_store_set( GTK_LIST_STORE( scudsp->regListStore ), &iter, 0, #rreg, 1, valuestr, -1 ); - #define SCUDSPUPDATEREGLISTx(rreg,vreg,format) \ - gtk_tree_model_iter_next( GTK_TREE_MODEL( scudsp->regListStore ), &iter ); \ - sprintf(valuestr, #format, (int)(vreg)); \ - gtk_list_store_set( GTK_LIST_STORE( scudsp->regListStore ), &iter, 0, #rreg, 1, valuestr, -1 ); - - SCUDSPUPDATEREGLISTp(EP,%d); - SCUDSPUPDATEREGLISTp(T0,%d); - SCUDSPUPDATEREGLISTp(S,%d); - SCUDSPUPDATEREGLISTp(Z,%d); - SCUDSPUPDATEREGLISTp(C,%d); - SCUDSPUPDATEREGLISTp(V,%d); - SCUDSPUPDATEREGLISTp(E,%d); - SCUDSPUPDATEREGLISTp(ES,%d); - SCUDSPUPDATEREGLISTp(EX,%d); - SCUDSPUPDATEREGLISTp(LE,%d); - SCUDSPUPDATEREGLISTp(P,%02X); - SCUDSPUPDATEREGLIST(TOP,%02X); - SCUDSPUPDATEREGLIST(LOP,%02X); - gtk_tree_model_iter_next( GTK_TREE_MODEL( scudsp->regListStore ), &iter ); - sprintf(valuestr, "%08X", (int)(((u32)(regs->CT[0]))<<24 | ((u32)(regs->CT[1]))<<16 | ((u32)(regs->CT[2]))<<8 | ((u32)(regs->CT[3]))) ); - gtk_list_store_set( GTK_LIST_STORE( scudsp->regListStore ), &iter, 0, "CT", 1, valuestr, -1 ); - SCUDSPUPDATEREGLISTx(RA,regs->RA0,%08X); - SCUDSPUPDATEREGLISTx(WA,regs->WA0,%08X); - SCUDSPUPDATEREGLIST(RX,%08X); - SCUDSPUPDATEREGLIST(RY,%08X); - SCUDSPUPDATEREGLISTx(PH,regs->P.part.H & 0xFFFF,%04X); - SCUDSPUPDATEREGLISTx(PL,regs->P.part.L & 0xFFFFFFFF,%08X); - SCUDSPUPDATEREGLISTx(ACH,regs->AC.part.H & 0xFFFF,%04X); - SCUDSPUPDATEREGLISTx(ACL,regs->AC.part.L & 0xFFFFFFFF,%08X); -} - -static void scudspsetRegister( YuiScudsp *scudsp, int nReg, u32 value ) { - /* set register number to value in proc */ - - scudspregs_struct scudspregs; - ScuDspGetRegisters(&scudspregs); - - switch ( nReg ) { - case 0: scudspregs.ProgControlPort.part.PR = value; break; - case 1: scudspregs.ProgControlPort.part.EP = value; break; - case 2: scudspregs.ProgControlPort.part.T0 = value; break; - case 3: scudspregs.ProgControlPort.part.S = value; break; - case 4: scudspregs.ProgControlPort.part.Z = value; break; - case 5: scudspregs.ProgControlPort.part.C = value; break; - case 6: scudspregs.ProgControlPort.part.V = value; break; - case 7: scudspregs.ProgControlPort.part.E = value; break; - case 8: scudspregs.ProgControlPort.part.ES = value; break; - case 9: scudspregs.ProgControlPort.part.EX = value; break; - case 10: scudspregs.ProgControlPort.part.LE = value; break; - case 11: scudspregs.ProgControlPort.part.P = value; break; - case 12: scudspregs.TOP = value; break; - case 13: scudspregs.LOP = value; break; - case 14: - scudspregs.CT[0] = (value>>24) & 0xff; - scudspregs.CT[1] = (value>>16) & 0xff; - scudspregs.CT[2] = (value>>8) & 0xff; - scudspregs.CT[3] = (value) & 0xff; - break; - case 15: scudspregs.RA0 = value; break; - case 16: scudspregs.WA0 = value; break; - case 17: scudspregs.RX = value; break; - case 18: scudspregs.RY = value; break; - case 19: scudspregs.P.part.H = value; break; - case 20: scudspregs.P.part.L = value; break; - case 21: scudspregs.AC.part.H = value; break; - case 22: scudspregs.AC.part.L = value; break; - } - - ScuDspSetRegisters(&scudspregs); -} - -static void yui_scudsp_update_codelist( YuiScudsp *scudsp, u32 addr) { - /* refresh the assembler view. points the line to be highlighted. */ - - int i; - static char tagPC[] = ""; - static char tagEnd[] = "\n"; - char buf[100*24+40]; - char *curs = buf; - char lineBuf[100]; - u32 offset; - - if ( addr - scudsp->lastCode >= 20 ) offset = addr - 8; - else offset = scudsp->lastCode; - scudsp->lastCode = offset; - - for (i=0; i < 24; i++) { - - if ( offset + i == addr ) { strcpy( curs, tagPC ); curs += strlen(tagPC); } - ScuDspDisasm(offset+i, lineBuf); - strcpy( curs, lineBuf ); - curs += strlen(lineBuf); - if ( offset + i == addr ) { strcpy( curs, tagEnd ); curs += strlen(tagEnd); } - else { strcpy( curs, "\n" ); curs += 1;} - } - *curs = 0; - - gtk_label_set_markup( GTK_LABEL(scudsp->uLabel), buf ); -} - -static void yui_scudsp_step( GtkWidget* widget, YuiScudsp * scudsp ) { - - ScuDspStep(); - yui_window_invalidate( yui ); /* update all dialogs, including us */ -} - -static void yui_scudsp_editedReg( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiScudsp *scudsp) { - /* registry number value has been set to */ - - GtkTreeIter iter; - char bptext[10]; - char *endptr; - int i = atoi(arg1); - u32 addr; - - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( scudsp->regListStore ), &iter, arg1 ); - addr = strtoul(arg2, &endptr, 16 ); - if ( endptr - arg2 == strlen(arg2) ) { - - sprintf(bptext, "%08X", (int)addr); - scudspsetRegister( scudsp, i, addr ); - gtk_list_store_set( GTK_LIST_STORE( scudsp->regListStore ), &iter, 1, bptext, -1 ); - } - yui_window_invalidate( yui ); -} - -static void yui_scudsp_editedBp( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiScudsp *scudsp) { - /* breakpoint has been set to address */ - - GtkTreeIter iter; - char bptext[10]; - char *endptr; - int i = atoi(arg1); - u32 addr; - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( scudsp->bpListStore ), &iter, arg1 ); - addr = strtoul(arg2, &endptr, 16 ); - if ((endptr - arg2 < strlen(arg2)) || (!addr)) addr = 0xFFFFFFFF; - if ( scudsp->cbp[i] != 0xFFFFFFFF) ScuDspDelCodeBreakpoint(scudsp->cbp[i]); - scudsp->cbp[i] = 0xFFFFFFFF; - - if ((addr!=0xFFFFFFFF)&&(ScuDspAddCodeBreakpoint(addr) == 0)) { - - sprintf(bptext, "%08X", (int)addr); - scudsp->cbp[i] = addr; - } else strcpy(bptext,""); - gtk_list_store_set( GTK_LIST_STORE( scudsp->bpListStore ), &iter, 0, bptext, -1 ); -} - -static void debugPauseLoop(void) { /* secondary gtk event loop for the "breakpoint pause" state */ - - while ( !(yui->state & YUI_IS_RUNNING) ) - if ( gtk_main_iteration() ) return; -} - -static void yui_scudsp_breakpoint_handler (u32 addr) { - - yui_window_pause(yui); - { - scudspregs_struct scudspregs; - YuiScudsp* scudsp = YUI_SCUDSP(yui_scudsp_new( yui )); - - ScuDspGetRegisters(&scudspregs); - yui_scudsp_update_reglist(scudsp, &scudspregs); - yui_scudsp_update_codelist(scudsp, scudspregs.PC); - } - debugPauseLoop(); /* execution is suspended inside a normal cycle - enter secondary gtk loop */ -} - - -void yui_scudsp_update(YuiScudsp * scudsp) { - scudspregs_struct scudspregs; - ScuDspGetRegisters(&scudspregs); - yui_scudsp_update_codelist(scudsp,scudspregs.PC); - yui_scudsp_update_reglist(scudsp, &scudspregs); - gtk_widget_set_sensitive(scudsp->uLabel, TRUE); - gtk_widget_set_sensitive(scudsp->bpList, TRUE); - gtk_widget_set_sensitive(scudsp->regList, TRUE); - gtk_widget_set_sensitive(scudsp->buttonStep, TRUE); -} - -void yui_scudsp_destroy(YuiScudsp * scudsp) { - g_signal_handler_disconnect(yui, scudsp->running_handler); - g_signal_handler_disconnect(yui, scudsp->paused_handler); - - yui_scudsp = NULL; - - gtk_widget_destroy(GTK_WIDGET(scudsp)); -} - -static void yui_scudsp_clear(YuiScudsp * scudsp) { - - gtk_widget_set_sensitive(scudsp->uLabel, FALSE); - gtk_widget_set_sensitive(scudsp->bpList, FALSE); - gtk_widget_set_sensitive(scudsp->regList, FALSE); - gtk_widget_set_sensitive(scudsp->buttonStep, FALSE); -} diff --git a/yabause/src/gtk/yuiscudsp.h b/yabause/src/gtk/yuiscudsp.h deleted file mode 100644 index 7cdc285264..0000000000 --- a/yabause/src/gtk/yuiscudsp.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_SCUDSP_H -#define YUI_SCUDSP_H - -#include -#include -#include - -#include "../scu.h" -#include "yuiwindow.h" - -G_BEGIN_DECLS - -#define YUI_SCUDSP_TYPE (yui_scudsp_get_type ()) -#define YUI_SCUDSP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_SCUDSP_TYPE, YuiScudsp)) -#define YUI_SCUDSP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_SCUDSP_TYPE, YuiScudspClass)) -#define IS_YUI_SCUDSP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_SCUDSP_TYPE)) -#define IS_YUI_SCUDSP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_SCUDSP_TYPE)) - -typedef struct _YuiScudsp YuiScudsp; -typedef struct _YuiScudspClass YuiScudspClass; - -struct _YuiScudsp -{ - GtkWindow dialog; - - GtkWidget *vbox, *vboxmain; - GtkWidget *hbox, *hboxmain; - GtkWidget * buttonStep, * buttonStepOver; - GtkWidget * bpList, *regList, *uLabel, *uFrame; - GtkListStore *bpListStore, *regListStore; - GtkCellRenderer *bpListRenderer, *regListRenderer1, *regListRenderer2; - GtkTreeViewColumn *bpListColumn, *regListColumn1, *regListColumn2; - u32 cbp[MAX_BREAKPOINTS]; /* the list of breakpoint positions, as they can be found in the list widget */ - u32 lastCode; /* offset of last unassembly. Try to reuse it to prevent sliding. */ - gulong paused_handler; - gulong running_handler; -}; - -struct _YuiScudspClass -{ - GtkWindowClass parent_class; - - void (* yui_scudsp) (YuiScudsp * yv); -}; - -GType yui_scudsp_get_type (void); -GtkWidget * yui_scudsp_new(YuiWindow * y); -void yui_scudsp_update(YuiScudsp * scudsp); -void yui_scudsp_destroy(YuiScudsp * scudsp); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuish.c b/yabause/src/gtk/yuish.c deleted file mode 100644 index 0c8dc3cc3e..0000000000 --- a/yabause/src/gtk/yuish.c +++ /dev/null @@ -1,1102 +0,0 @@ -/* Copyright 2005-2006 Fabien Coulon - Copyright 2008 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -#include "yuish.h" -#include "../sh2core.h" -#include "../sh2d.h" -#include "../yabause.h" -#include "settings.h" - -static void yui_sh_class_init (YuiShClass * klass); -static void yui_sh_init (YuiSh * yfe); -static void yui_sh_clear(YuiSh * sh); -static void yui_sh_editedReg( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiSh *sh2); -static void yui_sh_editedBp( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiSh *sh2); -static void yui_sh_editedMbp( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiSh *sh2); -static void yui_sh_editedMbpFlags( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiSh *sh2); -static void yui_sh_step( GtkWidget* widget, YuiSh * sh2 ); -static void SH2BreakpointHandler (SH2_struct *context, u32 addr); -static gint yui_sh_popup(GtkWidget * widget, GdkEvent * event, gpointer data); -static gint yui_sh_bp_popup(GtkWidget * widget, GdkEventButton * event, gpointer data); -static gint yui_sh_mbp_popup(GtkWidget * widget, GdkEventButton * event, gpointer data); -static void yui_sh_popup_add_bp(GtkMenuItem * menuitem, gpointer user_data); -static void yui_sh_popup_del_bp(GtkMenuItem * menuitem, gpointer user_data); -static void SH2UpdateBreakpointList(YuiSh * sh2); -static void SH2UpdateMemoryBreakpointList(YuiSh * sh2); -static void yui_sh_bp_add(GtkEntry * entry, gpointer user_data); -static void yui_sh_button_bp_add(GtkWidget * widget, gpointer user_data); -static void yui_sh_mbp_add(GtkEntry * entry, gpointer user_data); -static void yui_sh_mbp_toggle_flag(GtkWidget * menuitem, gpointer user_data); -static void yui_sh_mbp_remove(GtkWidget * menuitem, gpointer user_data); -static void yui_sh_mbp_clear(GtkWidget * menuitem, gpointer user_data); -static void yui_sh_bp_remove(GtkWidget * menuitem, gpointer user_data); -static void yui_sh_bp_clear(GtkWidget * menuitem, gpointer user_data); - -static YuiSh *yui_msh, *yui_ssh; -static YuiWindow * yui; - -GType yui_sh_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiShClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_sh_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiSh), - 0, - (GInstanceInitFunc) yui_sh_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiSh", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_sh_class_init (UNUSED YuiShClass * klass) { -} - -static void yui_sh_init (YuiSh * sh2) { - //GtkWidget *vboxBp; - - sh2->breakpointEnabled = MSH2->breakpointEnabled; - - gtk_window_set_title(GTK_WINDOW(sh2), "SH"); - - sh2->vbox = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width( GTK_CONTAINER( sh2->vbox ), 0); - gtk_container_add (GTK_CONTAINER (sh2), sh2->vbox); - - sh2->toolbar = gtk_toolbar_new(); - gtk_toolbar_set_style(GTK_TOOLBAR(sh2->toolbar), GTK_TOOLBAR_ICONS); - gtk_box_pack_start(GTK_BOX(sh2->vbox), sh2->toolbar, FALSE, FALSE, 0); - - sh2->hboxmain = gtk_hbox_new(FALSE, 4); - gtk_box_pack_start( GTK_BOX( sh2->vbox ), sh2->hboxmain, FALSE, FALSE, 0); - - /* Register list */ - - sh2->regListStore = gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_STRING); - sh2->regList = gtk_tree_view_new_with_model( GTK_TREE_MODEL(sh2->regListStore) ); - sh2->regListRenderer1 = gtk_cell_renderer_text_new(); - sh2->regListRenderer2 = gtk_cell_renderer_text_new(); - g_object_set(G_OBJECT(sh2->regListRenderer2), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL ); - sh2->regListColumn1 = gtk_tree_view_column_new_with_attributes(_("Register"), sh2->regListRenderer1, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(sh2->regList), sh2->regListColumn1); - sh2->regListColumn2 = gtk_tree_view_column_new_with_attributes(_("Value"), sh2->regListRenderer2, "text", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(sh2->regList), sh2->regListColumn2); - gtk_box_pack_start( GTK_BOX( sh2->hboxmain ), sh2->regList, FALSE, FALSE, 0); - g_signal_connect(G_OBJECT(sh2->regListRenderer2), "edited", GTK_SIGNAL_FUNC(yui_sh_editedReg), sh2 ); - - sh2->store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); - sh2->view = gtk_tree_view_new_with_model(GTK_TREE_MODEL (sh2->store)); - gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(sh2->view), FALSE); - { - GtkWidget * scroll; - GtkCellRenderer *renderer; - GtkCellRenderer *icon; - GtkTreeViewColumn *column; - - scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - - icon = gtk_cell_renderer_pixbuf_new(); - g_object_set(icon, "xalign", 0, NULL); - column = gtk_tree_view_column_new_with_attributes("Icon", icon, "stock-id", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (sh2->view), column); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes("Address", renderer, "text", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (sh2->view), column); - - column = gtk_tree_view_column_new_with_attributes("Command", renderer, "text", 2, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (sh2->view), column); - - gtk_container_add(GTK_CONTAINER(scroll), sh2->view); - gtk_box_pack_start(GTK_BOX(sh2->hboxmain), scroll, TRUE, TRUE, 0); - } - - if (sh2->breakpointEnabled) { - GtkWidget * menu = gtk_menu_new(); - GtkWidget * item; - - item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD, NULL); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - g_signal_connect(item, "activate", G_CALLBACK(yui_sh_popup_add_bp), sh2); - - item = gtk_image_menu_item_new_from_stock(GTK_STOCK_REMOVE, NULL); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - g_signal_connect(item, "activate", G_CALLBACK(yui_sh_popup_del_bp), sh2); - - gtk_widget_show_all(menu); - - g_signal_connect(sh2->view, "button-press-event", G_CALLBACK(yui_sh_popup), menu); - } - - /* breakpoint list */ - - sh2->vboxBp = gtk_vbox_new(FALSE, 0); - gtk_box_pack_start( GTK_BOX( sh2->hboxmain ), sh2->vboxBp, FALSE, FALSE, 0 ); - - sh2->bpListStore = gtk_list_store_new(1,G_TYPE_STRING); - sh2->bpList = gtk_tree_view_new_with_model( GTK_TREE_MODEL(sh2->bpListStore) ); - sh2->bpListRenderer = gtk_cell_renderer_text_new(); - g_object_set(G_OBJECT(sh2->bpListRenderer), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL ); - sh2->bpListColumn = gtk_tree_view_column_new_with_attributes("Code breaks", sh2->bpListRenderer, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(sh2->bpList), sh2->bpListColumn); - gtk_box_pack_start( GTK_BOX( sh2->vboxBp ), sh2->bpList, TRUE, TRUE, 0 ); - g_signal_connect(G_OBJECT(sh2->bpListRenderer), "edited", GTK_SIGNAL_FUNC(yui_sh_editedBp), sh2 ); - - { - GtkWidget * bp_form_box; - GtkWidget * bp_input; - GtkWidget * bp_add; - - bp_form_box = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(sh2->vboxBp), bp_form_box, FALSE, FALSE, 0); - - bp_input = gtk_entry_new(); - gtk_entry_set_width_chars(GTK_ENTRY(bp_input), 8); - g_signal_connect(bp_input, "activate", G_CALLBACK(yui_sh_bp_add), sh2); - gtk_box_pack_start(GTK_BOX(bp_form_box), bp_input, TRUE, TRUE, 0); - - bp_add = gtk_button_new(); - gtk_container_add(GTK_CONTAINER(bp_add), gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON)); - gtk_button_set_relief(GTK_BUTTON(bp_add), GTK_RELIEF_NONE); - g_signal_connect(bp_add, "clicked", G_CALLBACK(yui_sh_button_bp_add), bp_input); - gtk_box_pack_start(GTK_BOX(bp_form_box), bp_add, FALSE, FALSE, 0); - } - - { - GtkWidget * bp_item; - sh2->bp_menu = gtk_menu_new(); - - bp_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_REMOVE, NULL); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->bp_menu), bp_item); - g_signal_connect(bp_item, "activate", G_CALLBACK(yui_sh_bp_remove), sh2); - - bp_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_CLEAR, NULL); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->bp_menu), bp_item); - g_signal_connect(bp_item, "activate", G_CALLBACK(yui_sh_bp_clear), sh2); - - gtk_widget_show_all(sh2->bp_menu); - - g_signal_connect(sh2->bpList, "button-press-event", G_CALLBACK(yui_sh_bp_popup), sh2); - } - - /* memory breakpoint list */ - - sh2->mbpListStore = gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_STRING); - sh2->mbpList = gtk_tree_view_new_with_model( GTK_TREE_MODEL(sh2->mbpListStore) ); - sh2->mbpListRenderer = gtk_cell_renderer_text_new(); - g_object_set(G_OBJECT(sh2->mbpListRenderer), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL ); - sh2->mbpListColumn = gtk_tree_view_column_new_with_attributes("Memory breaks", sh2->mbpListRenderer, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(sh2->mbpList), sh2->mbpListColumn); - - { - GtkCellRenderer * flags_renderer; - GtkTreeViewColumn * flags_column; - - flags_renderer = gtk_cell_renderer_text_new(); - g_object_set(G_OBJECT(flags_renderer), "editable", TRUE, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL); - g_signal_connect(G_OBJECT(flags_renderer), "edited", GTK_SIGNAL_FUNC(yui_sh_editedMbpFlags), sh2 ); - - flags_column = gtk_tree_view_column_new_with_attributes("Flags", flags_renderer, "text", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(sh2->mbpList), flags_column); - } - - gtk_box_pack_start( GTK_BOX( sh2->vboxBp ), sh2->mbpList, TRUE, TRUE, 0 ); - g_signal_connect(G_OBJECT(sh2->mbpListRenderer), "edited", GTK_SIGNAL_FUNC(yui_sh_editedMbp), sh2 ); - - { - GtkWidget * mbp_item; - - sh2->mbp_menu = gtk_menu_new(); - - sh2->mbp_menu_item[0] = gtk_check_menu_item_new_with_label("Byte read"); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), sh2->mbp_menu_item[0]); - g_signal_connect(sh2->mbp_menu_item[0], "activate", G_CALLBACK(yui_sh_mbp_toggle_flag), sh2); - - sh2->mbp_menu_item[1] = gtk_check_menu_item_new_with_label("Word read"); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), sh2->mbp_menu_item[1]); - g_signal_connect(sh2->mbp_menu_item[1], "activate", G_CALLBACK(yui_sh_mbp_toggle_flag), sh2); - - sh2->mbp_menu_item[2] = gtk_check_menu_item_new_with_label("Long read"); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), sh2->mbp_menu_item[2]); - g_signal_connect(sh2->mbp_menu_item[2], "activate", G_CALLBACK(yui_sh_mbp_toggle_flag), sh2); - - sh2->mbp_menu_item[3] = gtk_check_menu_item_new_with_label("Byte write"); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), sh2->mbp_menu_item[3]); - g_signal_connect(sh2->mbp_menu_item[3], "activate", G_CALLBACK(yui_sh_mbp_toggle_flag), sh2); - - sh2->mbp_menu_item[4] = gtk_check_menu_item_new_with_label("Word write"); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), sh2->mbp_menu_item[4]); - g_signal_connect(sh2->mbp_menu_item[4], "activate", G_CALLBACK(yui_sh_mbp_toggle_flag), sh2); - - sh2->mbp_menu_item[5] = gtk_check_menu_item_new_with_label("Long write"); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), sh2->mbp_menu_item[5]); - g_signal_connect(sh2->mbp_menu_item[5], "activate", G_CALLBACK(yui_sh_mbp_toggle_flag), sh2); - - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), gtk_separator_menu_item_new()); - - mbp_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_REMOVE, NULL); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), mbp_item); - g_signal_connect(mbp_item, "activate", G_CALLBACK(yui_sh_mbp_remove), sh2); - - mbp_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_CLEAR, NULL); - gtk_menu_shell_append(GTK_MENU_SHELL(sh2->mbp_menu), mbp_item); - g_signal_connect(mbp_item, "activate", G_CALLBACK(yui_sh_mbp_clear), sh2); - - gtk_widget_show_all(sh2->mbp_menu); - - g_signal_connect(sh2->mbpList, "button-press-event", G_CALLBACK(yui_sh_mbp_popup), sh2); - } - - { - GtkWidget * bp_form_box; - GtkWidget * bp_input; - GtkWidget * bp_add; - - bp_form_box = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(sh2->vboxBp), bp_form_box, FALSE, FALSE, 0); - - bp_input = gtk_entry_new(); - gtk_entry_set_width_chars(GTK_ENTRY(bp_input), 8); - g_signal_connect(bp_input, "activate", G_CALLBACK(yui_sh_mbp_add), sh2); - gtk_box_pack_start(GTK_BOX(bp_form_box), bp_input, TRUE, TRUE, 0); - - bp_add = gtk_button_new(); - gtk_container_add(GTK_CONTAINER(bp_add), gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON)); - gtk_button_set_relief(GTK_BUTTON(bp_add), GTK_RELIEF_NONE); - g_signal_connect(bp_add, "clicked", G_CALLBACK(yui_sh_button_bp_add), bp_input); - gtk_box_pack_start(GTK_BOX(bp_form_box), bp_add, FALSE, FALSE, 0); - } - - g_signal_connect(G_OBJECT(sh2), "delete-event", GTK_SIGNAL_FUNC(yui_sh_destroy), NULL); - - gtk_window_set_default_size(GTK_WINDOW(sh2), 650, -1); -} - - -static GtkWidget * yui_sh_new(YuiWindow * y, gboolean bMaster) { - GtkWidget * dialog; - GClosure *closureF7; //, *closureF8; - GtkAccelGroup *accelGroup; - YuiSh * sh2; - gint i; - yui = y; - - if (!( yui->state & YUI_IS_INIT )) { - yui_window_run(yui); - yui_window_pause(yui); - } - - if ( bMaster && yui_msh ) return GTK_WIDGET(yui_msh); - if ( !bMaster && yui_ssh ) return GTK_WIDGET(yui_ssh); - - dialog = GTK_WIDGET(g_object_new(yui_sh_get_type(), NULL)); - sh2 = YUI_SH(dialog); - - //sh2->breakpointEnabled = MSH2->breakpointEnabled; -/* - if ( !sh2->breakpointEnabled ) - gtk_box_pack_start( GTK_BOX( sh2->vboxmain ), - gtk_label_new("Breakpoints are disabled (fast interpreter)"), FALSE, FALSE, 4 ); -*/ - - sh2->bMaster = bMaster; - sh2->debugsh = bMaster ? MSH2 : SSH2; - - SH2SetBreakpointCallBack(sh2->debugsh, (void (*)(void *, u32))SH2BreakpointHandler); - - gtk_window_set_title(GTK_WINDOW(sh2), bMaster?"Master SH2":"Slave SH2"); - - for (i = 0; i < 23 ; i++) { - - GtkTreeIter iter; - gtk_list_store_append( GTK_LIST_STORE( sh2->regListStore ), &iter ); - } - - SH2UpdateBreakpointList(sh2); - - SH2UpdateMemoryBreakpointList(sh2); - - { - GtkToolItem * play_button, * pause_button; - - play_button = gtk_tool_button_new_from_stock("run"); - gtk_action_connect_proxy(gtk_action_group_get_action(yui->action_group, "run"), GTK_WIDGET(play_button)); - gtk_toolbar_insert(GTK_TOOLBAR(sh2->toolbar), GTK_TOOL_ITEM(play_button), 0); - - pause_button = gtk_tool_button_new_from_stock("pause"); - gtk_action_connect_proxy(gtk_action_group_get_action(yui->action_group, "pause"), GTK_WIDGET(pause_button)); - gtk_toolbar_insert(GTK_TOOLBAR(sh2->toolbar), GTK_TOOL_ITEM(pause_button), 1); - - sh2->buttonStep = gtk_tool_button_new_from_stock(GTK_STOCK_GO_DOWN); - g_signal_connect(sh2->buttonStep, "clicked", G_CALLBACK(yui_sh_step), sh2); - gtk_toolbar_insert(GTK_TOOLBAR(sh2->toolbar), GTK_TOOL_ITEM(sh2->buttonStep), 2); -#if GTK_CHECK_VERSION(2,12,0) - gtk_widget_set_tooltip_text(GTK_WIDGET(sh2->buttonStep), "step"); -#endif - } - - sh2->paused_handler = g_signal_connect_swapped(yui, "paused", G_CALLBACK(yui_sh_update), sh2); - sh2->running_handler = g_signal_connect_swapped(yui, "running", G_CALLBACK(yui_sh_clear), sh2); - accelGroup = gtk_accel_group_new (); - closureF7 = g_cclosure_new (G_CALLBACK (yui_sh_step), sh2, NULL); - gtk_accel_group_connect( accelGroup, GDK_F7, 0, 0, closureF7 ); - gtk_window_add_accel_group( GTK_WINDOW( dialog ), accelGroup ); - - yui_sh_update(sh2); - if ( yui->state & YUI_IS_RUNNING ) yui_sh_clear(sh2); - - gtk_widget_show_all(GTK_WIDGET(sh2)); - if ( !sh2->breakpointEnabled ) { -/* - gtk_widget_hide( sh2->bpList ); - gtk_widget_hide( sh2->mbpList ); -*/ - gtk_widget_hide(sh2->vboxBp); - } - - return dialog; -} - -GtkWidget * yui_msh_new(YuiWindow * y) { - return GTK_WIDGET( yui_msh = YUI_SH(yui_sh_new( y, TRUE )) ); -} - -GtkWidget * yui_ssh_new(YuiWindow * y) { - return GTK_WIDGET( yui_ssh = YUI_SH(yui_sh_new( y, FALSE )) ); -} - -static void SH2UpdateRegList( YuiSh *sh2, sh2regs_struct *regs) { - /* refresh the registery list */ - - GtkTreeIter iter; - char regstr[32]; - char valuestr[32]; - int i; - - for (i = 0; i < 16; i++) { - sprintf(regstr, "R%02d", i); - sprintf(valuestr, "%08X", (int)regs->R[i] ); - if ( !i ) gtk_tree_model_get_iter_first( GTK_TREE_MODEL( sh2->regListStore ), &iter ); - else gtk_tree_model_iter_next( GTK_TREE_MODEL( sh2->regListStore ), &iter ); - gtk_list_store_set( GTK_LIST_STORE( sh2->regListStore ), &iter, 0, regstr, 1, valuestr, -1 ); - } - - #define SH2UPDATEREGLIST(rreg) \ - gtk_tree_model_iter_next( GTK_TREE_MODEL( sh2->regListStore ), &iter ); \ - sprintf(valuestr, "%08X", (int)regs->rreg); \ - gtk_list_store_set( GTK_LIST_STORE( sh2->regListStore ), &iter, 0, #rreg, 1, valuestr, -1 ); - - SH2UPDATEREGLIST(SR.all); - SH2UPDATEREGLIST(GBR); - SH2UPDATEREGLIST(VBR); - SH2UPDATEREGLIST(MACH); - SH2UPDATEREGLIST(MACL); - SH2UPDATEREGLIST(PR); - SH2UPDATEREGLIST(PC); -} - -static void sh2setRegister( YuiSh *sh2, int nReg, u32 value ) { - /* set register number to value in proc */ - - sh2regs_struct sh2regs; - SH2GetRegisters(sh2->debugsh, &sh2regs); - - if ( nReg < 16 ) sh2regs.R[nReg] = value; - switch ( nReg ) { - case 16: sh2regs.SR.all = value; break; - case 17: sh2regs.GBR = value; break; - case 18: sh2regs.VBR = value; break; - case 19: sh2regs.MACH = value; break; - case 20: sh2regs.MACL = value; break; - case 21: sh2regs.PR = value; break; - case 22: sh2regs.PC = value; break; - } - - SH2SetRegisters(sh2->debugsh, &sh2regs); -} - -void SH2UpdateBreakpointList(YuiSh * sh2) { - const codebreakpoint_struct *cbp; - int i; - - gtk_list_store_clear(GTK_LIST_STORE( sh2->bpListStore )); - - cbp = SH2GetBreakpointList(sh2->debugsh); - - for (i = 0; i < MAX_BREAKPOINTS-1; i++) { - - if (cbp[i].addr != 0xFFFFFFFF) { - gchar tempstr[20]; - GtkTreeIter iter; - gtk_list_store_append( GTK_LIST_STORE( sh2->bpListStore ), &iter ); - - sprintf(tempstr, "%08X", (int)cbp[i].addr); - gtk_list_store_set( GTK_LIST_STORE( sh2->bpListStore ), &iter, 0, tempstr, -1 ); - } - } -} - -void SH2UpdateMemoryBreakpointList(YuiSh * sh2) { - const memorybreakpoint_struct *cmbp; - int i; - - gtk_list_store_clear( sh2->mbpListStore ); - - cmbp = SH2GetMemoryBreakpointList(sh2->debugsh); - - for (i = 0; i < MAX_BREAKPOINTS; i++) { - - if (cmbp[i].addr != 0xFFFFFFFF) { - gchar tempstr[30]; - gchar flagstr[30]; - gchar *curs = flagstr; - u32 flags = cmbp[i].flags; - - GtkTreeIter iter; - gtk_list_store_append( GTK_LIST_STORE( sh2->mbpListStore ), &iter ); - - sprintf(tempstr, "%08X", (int)cmbp[i].addr); - if ( flags & BREAK_BYTEREAD ) *(curs++) = 'b'; - if ( flags & BREAK_WORDREAD ) *(curs++) = 'w'; - if ( flags & BREAK_LONGREAD ) *(curs++) = 'l'; - if ( flags & BREAK_BYTEWRITE ) *(curs++) = 'B'; - if ( flags & BREAK_WORDWRITE ) *(curs++) = 'W'; - if ( flags & BREAK_LONGWRITE ) *(curs++) = 'L'; - *curs = 0; - - gtk_list_store_set( GTK_LIST_STORE( sh2->mbpListStore ), &iter, 0, tempstr, -1 ); - gtk_list_store_set( GTK_LIST_STORE( sh2->mbpListStore ), &iter, 1, flagstr, -1 ); - } - } -} - -static void SH2UpdateCodeList( YuiSh *sh2, u32 addr) { - /* refresh the assembler view. points the line to be highlighted. */ - - int i, j; - char lineBuf[64]; - u32 offset; - GtkTreeIter iter; - unsigned int address; - char address_s[20]; - char command_s[64]; - codebreakpoint_struct *cbp; - - gtk_list_store_clear(sh2->store); - - if ( addr - sh2->lastCode >= 20*2 ) offset = addr - (8*2); - else offset = sh2->lastCode; - sh2->lastCode = offset; - - cbp = SH2GetBreakpointList(sh2->debugsh); - - for (i = 0; i < 24; i++) { - SH2Disasm(offset+2*i, MappedMemoryReadWord(offset+2*i), 0, lineBuf); - - sscanf(lineBuf, "0x%8X: %[^\n]", &address, command_s); - sprintf(address_s, "0x%08X", address); - - gtk_list_store_append(sh2->store, &iter); - if ( offset + 2*i == addr ) { - gtk_list_store_set(sh2->store, &iter, 0, GTK_STOCK_GO_FORWARD, -1); - } else { - for (j = 0;j < MAX_BREAKPOINTS - 1;j++) { - if (cbp[j].addr == address) { - gtk_list_store_set(sh2->store, &iter, 0, GTK_STOCK_STOP, -1); - } - } - } - - gtk_list_store_set(sh2->store, &iter, 1, address_s, -1); - - gtk_list_store_set(sh2->store, &iter, 2, command_s, -1); - } -} - -static void yui_sh_step( GtkWidget* widget, YuiSh * sh2 ) { - - SH2Step(sh2->debugsh); - yui_window_invalidate( yui ); /* update all dialogs, including us */ -} - -static void yui_sh_editedReg( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiSh *sh2) { - /* registry number value has been set to */ - - GtkTreeIter iter; - char bptext[10]; - char *endptr; - int i = atoi(arg1); - u32 addr; - - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( sh2->regListStore ), &iter, arg1 ); - addr = strtoul(arg2, &endptr, 16 ); - if ( endptr - arg2 == strlen(arg2) ) { - - sprintf(bptext, "%08X", (int)addr); - sh2setRegister( sh2, i, addr ); - gtk_list_store_set( GTK_LIST_STORE( sh2->regListStore ), &iter, 1, bptext, -1 ); - } - yui_window_invalidate( yui ); -} - -static void yui_sh_editedBp( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiSh *sh2) { - /* breakpoint has been set to address */ - - GtkTreeIter iter; - char *endptr; - unsigned int addr; - gchar * oldaddr_s; - unsigned int oldaddr; - - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( sh2->bpListStore ), &iter, arg1 ); - - gtk_tree_model_get(GTK_TREE_MODEL( sh2->bpListStore ), &iter, 0, &oldaddr_s, -1); - sscanf(oldaddr_s, "%8X", &oldaddr); - g_free(oldaddr_s); - - SH2DelCodeBreakpoint(sh2->debugsh, oldaddr); - - addr = strtoul(arg2, &endptr, 16 ); - if ((endptr - arg2 < strlen(arg2)) || (!addr)) addr = 0xFFFFFFFF; - - if (addr != 0xFFFFFFFF) { - SH2AddCodeBreakpoint(sh2->debugsh, addr); - } - - { - sh2regs_struct sh2regs; - SH2GetRegisters(sh2->debugsh, &sh2regs); - SH2UpdateCodeList(sh2,sh2regs.PC); - SH2UpdateBreakpointList(sh2); - } -} - -static void yui_sh_editedMbp( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiSh *sh2) { - /* breakpoint has been set to address */ - - GtkTreeIter iter; - gchar *endptr; - unsigned int addr; - gchar * oldaddr_s, * flags_s; - unsigned int oldaddr; - u32 flags; - - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( sh2->mbpListStore ), &iter, arg1 ); - - gtk_tree_model_get(GTK_TREE_MODEL( sh2->mbpListStore ), &iter, 0, &oldaddr_s, -1); - sscanf(oldaddr_s, "%8X", &oldaddr); - g_free(oldaddr_s); - - gtk_tree_model_get(GTK_TREE_MODEL( sh2->mbpListStore ), &iter, 1, &flags_s, -1); - - SH2DelMemoryBreakpoint(sh2->debugsh, oldaddr); - - addr = strtoul(arg2, &endptr, 16 ); - if (!addr) addr = 0xFFFFFFFF; - - if (addr!=0xFFFFFFFF) { - - flags = 0; - endptr = flags_s; - while ( *endptr ) { - - switch (*endptr) { - - case 'b': flags |= BREAK_BYTEREAD; break; - case 'w': flags |= BREAK_WORDREAD; break; - case 'l': flags |= BREAK_LONGREAD; break; - case 'B': flags |= BREAK_BYTEWRITE; break; - case 'W': flags |= BREAK_WORDWRITE; break; - case 'L': flags |= BREAK_LONGWRITE; break; - } - endptr++; - } - - if ( !flags ) flags = BREAK_BYTEREAD|BREAK_WORDREAD|BREAK_LONGREAD|BREAK_BYTEWRITE|BREAK_WORDWRITE|BREAK_LONGWRITE; - SH2AddMemoryBreakpoint(sh2->debugsh, addr, flags); - } - - SH2UpdateMemoryBreakpointList(sh2); -} - -static void yui_sh_editedMbpFlags( GtkCellRendererText *cellrenderertext, - gchar *arg1, - gchar *arg2, - YuiSh *sh2) { - /* breakpoint has been set to address */ - - GtkTreeIter iter; - gchar *endptr; - unsigned int addr; - gchar * addr_s; - u32 flags = 0; - - gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL( sh2->mbpListStore ), &iter, arg1 ); - - gtk_tree_model_get(GTK_TREE_MODEL( sh2->mbpListStore ), &iter, 0, &addr_s, -1); - sscanf(addr_s, "%8X", &addr); - g_free(addr_s); - - SH2DelMemoryBreakpoint(sh2->debugsh, addr); - - endptr = arg2; - - while ( *endptr ) { - - switch (*endptr) { - - case 'b': flags |= BREAK_BYTEREAD; break; - case 'w': flags |= BREAK_WORDREAD; break; - case 'l': flags |= BREAK_LONGREAD; break; - case 'B': flags |= BREAK_BYTEWRITE; break; - case 'W': flags |= BREAK_WORDWRITE; break; - case 'L': flags |= BREAK_LONGWRITE; break; - } - endptr++; - } - - SH2AddMemoryBreakpoint(sh2->debugsh, addr, flags); - - SH2UpdateMemoryBreakpointList(sh2); -} - -static void debugPauseLoop(void) { /* secondary gtk event loop for the "breakpoint pause" state */ - - while ( !(yui->state & YUI_IS_RUNNING) ) - if ( gtk_main_iteration() ) return; -} - -static void SH2BreakpointHandler (SH2_struct *context, u32 addr) { - - yui_window_pause(yui); - { - sh2regs_struct sh2regs; - YuiSh* sh2 = YUI_SH(yui_sh_new( yui, context == MSH2 )); - - SH2GetRegisters(sh2->debugsh, &sh2regs); - SH2UpdateRegList(sh2, &sh2regs); - SH2UpdateCodeList(sh2, sh2regs.PC); - } - debugPauseLoop(); /* execution is suspended inside a normal cycle - enter secondary gtk loop */ -} - - -void yui_sh_update(YuiSh * sh) { - sh2regs_struct sh2regs; - SH2GetRegisters(sh->debugsh, &sh2regs); - SH2UpdateCodeList(sh,sh2regs.PC); - SH2UpdateRegList(sh, &sh2regs); - gtk_widget_set_sensitive(sh->bpList, TRUE); - gtk_widget_set_sensitive(sh->mbpList, TRUE); - gtk_widget_set_sensitive(sh->regList, TRUE); - gtk_widget_set_sensitive(GTK_WIDGET(sh->buttonStep), - !sh->debugsh->isIdle && !(( sh->debugsh == SSH2 )&&( !yabsys.IsSSH2Running ))); -} - -void yui_sh_destroy(YuiSh * sh) { - g_signal_handler_disconnect(yui, sh->running_handler); - g_signal_handler_disconnect(yui, sh->paused_handler); - - if ( sh->bMaster ) yui_msh = NULL; - else yui_ssh = NULL; - - gtk_widget_destroy(GTK_WIDGET(sh)); -} - -static void yui_sh_clear(YuiSh * sh) { - - gtk_widget_set_sensitive(sh->bpList, FALSE); - gtk_widget_set_sensitive(sh->mbpList, FALSE); - gtk_widget_set_sensitive(sh->regList, FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(sh->buttonStep), FALSE); - - gtk_list_store_clear(sh->store); -} - -gint yui_sh_popup(GtkWidget * widget, GdkEvent * event, gpointer data) -{ - GtkMenu *menu; - GdkEventButton *event_button; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (GTK_IS_MENU (data), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - menu = GTK_MENU(data); - - if (event->type == GDK_BUTTON_PRESS) { - event_button = (GdkEventButton *) event; - if (event_button->button == 3) { - gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event_button->button, event_button->time); - } - } - - return FALSE; -} - -void yui_sh_popup_add_bp(GtkMenuItem * menuitem, gpointer user_data) { - YuiSh * sh2 = user_data; - GtkTreeView * view = GTK_TREE_VIEW(sh2->view); - GtkTreeSelection * selection; - GtkTreeModel * model; - GtkTreeIter iter; - gchar * address_s; - unsigned int address; - - selection = gtk_tree_view_get_selection(view); - - gtk_tree_selection_get_selected(selection, &model, &iter); - - gtk_tree_model_get(model, &iter, 1, &address_s, -1); - - sscanf(address_s, "0x%08X", &address); - - SH2AddCodeBreakpoint(sh2->debugsh, address); - - g_free(address_s); - - { - sh2regs_struct sh2regs; - SH2GetRegisters(sh2->debugsh, &sh2regs); - SH2UpdateCodeList(sh2,sh2regs.PC); - SH2UpdateBreakpointList(sh2); - } -} - -void yui_sh_popup_del_bp(GtkMenuItem * menuitem, gpointer user_data) { - YuiSh * sh2 = user_data; - GtkTreeView * view = GTK_TREE_VIEW(sh2->view); - GtkTreeSelection * selection; - GtkTreeModel * model; - GtkTreeIter iter; - gchar * address_s; - unsigned int address; - - selection = gtk_tree_view_get_selection(view); - - gtk_tree_selection_get_selected(selection, &model, &iter); - - gtk_tree_model_get(model, &iter, 1, &address_s, -1); - - sscanf(address_s, "0x%08X", &address); - - SH2DelCodeBreakpoint(sh2->debugsh, address); - - g_free(address_s); - - { - sh2regs_struct sh2regs; - SH2GetRegisters(sh2->debugsh, &sh2regs); - SH2UpdateCodeList(sh2,sh2regs.PC); - SH2UpdateBreakpointList(sh2); - } -} - -static void yui_sh_bp_add(GtkEntry * entry, gpointer user_data) { - YuiSh * sh2 = user_data; - const gchar * address_s; - unsigned int address; - - address_s = gtk_entry_get_text(entry); - - if (*address_s == 0) return; - - sscanf(address_s, "%8X", &address); - - SH2AddCodeBreakpoint(sh2->debugsh, address); - - gtk_entry_set_text(entry, ""); - - { - sh2regs_struct sh2regs; - SH2GetRegisters(sh2->debugsh, &sh2regs); - SH2UpdateCodeList(sh2,sh2regs.PC); - SH2UpdateBreakpointList(sh2); - } -} - -static void yui_sh_button_bp_add(GtkWidget * widget, gpointer user_data) { - g_signal_emit_by_name(user_data, "activate"); -} - -static void yui_sh_mbp_add(GtkEntry * entry, gpointer user_data) { - YuiSh * sh2 = user_data; - const gchar * address_s; - unsigned int address; - - address_s = gtk_entry_get_text(entry); - - if (*address_s == 0) return; - - sscanf(address_s, "%8X", &address); - - SH2AddMemoryBreakpoint(sh2->debugsh, address, BREAK_BYTEREAD|BREAK_WORDREAD|BREAK_LONGREAD|BREAK_BYTEWRITE|BREAK_WORDWRITE|BREAK_LONGWRITE); - - gtk_entry_set_text(entry, ""); - - SH2UpdateMemoryBreakpointList(sh2); -} - -gint yui_sh_mbp_popup(GtkWidget * widget, GdkEventButton * event, gpointer data) -{ - GtkMenu *menu; - GdkEventButton *event_button; - YuiSh * sh2 = data; - GtkTreeView * view; - GtkTreeSelection * selection; - GtkTreeIter iter; - GtkTreeModel * model; - gchar * flags_s; - char *endptr; - int i; - guint signal_id; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - view = GTK_TREE_VIEW(sh2->mbpList); - menu = GTK_MENU(sh2->mbp_menu); - - if (event->type == GDK_BUTTON_PRESS) { - event_button = (GdkEventButton *) event; - if (event_button->button == 3) { - - GtkTreePath *path; - - selection = gtk_tree_view_get_selection(view); - - if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(view), event->x, event->y, &path, NULL, NULL, NULL)) { - gtk_tree_selection_unselect_all(selection); - gtk_tree_selection_select_path(selection, path); - gtk_tree_path_free(path); - } - - gtk_tree_selection_get_selected(selection, &model, &iter); - - if (gtk_tree_selection_count_selected_rows(selection) == 0) return FALSE; - - gtk_tree_model_get(model, &iter, 1, &flags_s, -1); - - signal_id = g_signal_lookup("activate", GTK_TYPE_CHECK_MENU_ITEM); - - for(i = 0;i < 6;i++) g_signal_handlers_block_matched(sh2->mbp_menu_item[i], G_SIGNAL_MATCH_DATA, signal_id, 0, NULL, NULL, sh2); - - for(i = 0;i < 6;i++) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(sh2->mbp_menu_item[i]), FALSE); - - endptr = flags_s; - while ( *endptr ) { - switch (*endptr) { - - case 'b': gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(sh2->mbp_menu_item[0]), TRUE); break; - case 'w': gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(sh2->mbp_menu_item[1]), TRUE); break; - case 'l': gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(sh2->mbp_menu_item[2]), TRUE); break; - case 'B': gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(sh2->mbp_menu_item[3]), TRUE); break; - case 'W': gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(sh2->mbp_menu_item[4]), TRUE); break; - case 'L': gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(sh2->mbp_menu_item[5]), TRUE); break; - } - endptr++; - } - - for(i = 0;i < 6;i++) g_signal_handlers_unblock_matched(sh2->mbp_menu_item[i], G_SIGNAL_MATCH_DATA, signal_id, 0, NULL, NULL, sh2); - - gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event_button->button, event_button->time); - } - } - - return FALSE; -} - -void yui_sh_mbp_toggle_flag(GtkWidget * menuitem, gpointer user_data) { - GtkTreeSelection * selection; - YuiSh * sh2 = user_data; - GtkTreeIter iter; - GtkTreeModel * model; - gchar * address_s, * flags_s; - unsigned int address; - u32 flags; - GtkTreeView * view; - char *endptr; - - view = GTK_TREE_VIEW(sh2->mbpList); - - selection = gtk_tree_view_get_selection(view); - - gtk_tree_selection_get_selected(selection, &model, &iter); - - gtk_tree_model_get(model, &iter, 0, &address_s, -1); - gtk_tree_model_get(model, &iter, 1, &flags_s, -1); - sscanf(address_s, "%8X", &address); - - SH2DelMemoryBreakpoint(sh2->debugsh, address); - - flags = 0; - endptr = flags_s; - while ( *endptr ) { - switch (*endptr) { - case 'b': flags |= BREAK_BYTEREAD; break; - case 'w': flags |= BREAK_WORDREAD; break; - case 'l': flags |= BREAK_LONGREAD; break; - case 'B': flags |= BREAK_BYTEWRITE; break; - case 'W': flags |= BREAK_WORDWRITE; break; - case 'L': flags |= BREAK_LONGWRITE; break; - } - endptr++; - } - - if (menuitem == sh2->mbp_menu_item[0]) flags = (flags & ~BREAK_BYTEREAD) | (~flags & BREAK_BYTEREAD); - if (menuitem == sh2->mbp_menu_item[1]) flags = (flags & ~BREAK_WORDREAD) | (~flags & BREAK_WORDREAD); - if (menuitem == sh2->mbp_menu_item[2]) flags = (flags & ~BREAK_LONGREAD) | (~flags & BREAK_LONGREAD); - if (menuitem == sh2->mbp_menu_item[3]) flags = (flags & ~BREAK_BYTEWRITE) | (~flags & BREAK_BYTEWRITE); - if (menuitem == sh2->mbp_menu_item[4]) flags = (flags & ~BREAK_WORDWRITE) | (~flags & BREAK_WORDWRITE); - if (menuitem == sh2->mbp_menu_item[5]) flags = (flags & ~BREAK_LONGWRITE) | (~flags & BREAK_LONGWRITE); - - SH2AddMemoryBreakpoint(sh2->debugsh, address, flags); - - SH2UpdateMemoryBreakpointList(sh2); -} - -void yui_sh_mbp_remove(GtkWidget * menuitem, gpointer user_data) { - GtkTreeSelection * selection; - YuiSh * sh2 = user_data; - GtkTreeIter iter; - GtkTreeModel * model; - gchar * address_s; - unsigned int address; - GtkTreeView * view; - - view = GTK_TREE_VIEW(sh2->mbpList); - - selection = gtk_tree_view_get_selection(view); - - gtk_tree_selection_get_selected(selection, &model, &iter); - - gtk_tree_model_get(model, &iter, 0, &address_s, -1); - sscanf(address_s, "%8X", &address); - - SH2DelMemoryBreakpoint(sh2->debugsh, address); - - SH2UpdateMemoryBreakpointList(sh2); -} - -void yui_sh_mbp_clear(GtkWidget * menuitem, gpointer user_data) { - YuiSh * sh2 = user_data; - - SH2ClearMemoryBreakpoints(sh2->debugsh); - - SH2UpdateMemoryBreakpointList(sh2); -} - -gint yui_sh_bp_popup(GtkWidget * widget, GdkEventButton * event, gpointer data) -{ - GtkMenu *menu; - GdkEventButton *event_button; - YuiSh * sh2 = data; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - menu = GTK_MENU(sh2->bp_menu); - - if (event->type == GDK_BUTTON_PRESS) { - event_button = (GdkEventButton *) event; - if (event_button->button == 3) { - gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event_button->button, event_button->time); - } - } - - return FALSE; -} - -void yui_sh_bp_remove(GtkWidget * menuitem, gpointer user_data) { - GtkTreeSelection * selection; - YuiSh * sh2 = user_data; - GtkTreeIter iter; - GtkTreeModel * model; - gchar * address_s; - unsigned int address; - GtkTreeView * view; - - view = GTK_TREE_VIEW(sh2->bpList); - - selection = gtk_tree_view_get_selection(view); - - gtk_tree_selection_get_selected(selection, &model, &iter); - - gtk_tree_model_get(model, &iter, 0, &address_s, -1); - sscanf(address_s, "%8X", &address); - - SH2DelCodeBreakpoint(sh2->debugsh, address); - - { - sh2regs_struct sh2regs; - SH2GetRegisters(sh2->debugsh, &sh2regs); - SH2UpdateCodeList(sh2,sh2regs.PC); - SH2UpdateBreakpointList(sh2); - } -} - -void yui_sh_bp_clear(GtkWidget * menuitem, gpointer user_data) { - YuiSh * sh2 = user_data; - - SH2ClearCodeBreakpoints(sh2->debugsh); - - { - sh2regs_struct sh2regs; - SH2GetRegisters(sh2->debugsh, &sh2regs); - SH2UpdateCodeList(sh2,sh2regs.PC); - SH2UpdateBreakpointList(sh2); - } -} diff --git a/yabause/src/gtk/yuish.h b/yabause/src/gtk/yuish.h deleted file mode 100644 index 60b8fe72bd..0000000000 --- a/yabause/src/gtk/yuish.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Copyright 2005-2006 Fabien Coulon - Copyright 2008 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_SH_H -#define YUI_SH_H - -#include -#include -#include - -#include "../sh2core.h" -#include "yuiwindow.h" - -G_BEGIN_DECLS - -#define YUI_SH_TYPE (yui_sh_get_type ()) -#define YUI_SH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_SH_TYPE, YuiSh)) -#define YUI_SH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_SH_TYPE, YuiShClass)) -#define IS_YUI_SH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_SH_TYPE)) -#define IS_YUI_SH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_SH_TYPE)) - -typedef struct _YuiSh YuiSh; -typedef struct _YuiShClass YuiShClass; - -struct _YuiSh -{ - GtkWindow dialog; - - GtkWidget * view; - GtkWidget * toolbar; - GtkWidget *vbox; - GtkWidget *hboxmain; - GtkToolItem * buttonStep; - GtkWidget *bpList, *mbpList, *regList; //, *uLabel, *uFrame; - GtkListStore *bpListStore, *mbpListStore, *regListStore; - GtkCellRenderer *bpListRenderer, *mbpListRenderer, *regListRenderer1, *regListRenderer2; - GtkTreeViewColumn *bpListColumn, *mbpListColumn, *regListColumn1, *regListColumn2; - //u32 cbp[MAX_BREAKPOINTS]; /* the list of breakpoint positions, as they can be found in the list widget */ - //u32 cmbp[MAX_BREAKPOINTS]; /* the list of memory breakpoint positions, as they can be found in the list widget */ - //u32 mbpFlags[MAX_BREAKPOINTS]; - u32 lastCode; /* offset of last unassembly. Try to reuse it to prevent sliding. */ - SH2_struct *debugsh; - gboolean bMaster; - gboolean breakpointEnabled; - gulong paused_handler; - gulong running_handler; - - GtkListStore * store; - - GtkWidget * bp_menu; - GtkWidget * mbp_menu; - GtkWidget * mbp_menu_item[6]; - - GtkWidget * vboxBp; -}; - -struct _YuiShClass -{ - GtkWindowClass parent_class; - - void (* yui_sh) (YuiSh * yv); -}; - -GType yui_sh_get_type (void); -GtkWidget * yui_msh_new(YuiWindow * y); -GtkWidget * yui_ssh_new(YuiWindow * y); -void yui_sh_fill (YuiSh * sh); -void yui_sh_update (YuiSh * sh); -void yui_sh_destroy (YuiSh * sh); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuitransfer.c b/yabause/src/gtk/yuitransfer.c deleted file mode 100644 index 9373101907..0000000000 --- a/yabause/src/gtk/yuitransfer.c +++ /dev/null @@ -1,284 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "yuitransfer.h" -#include "../core.h" -#include "../memory.h" - -static void yui_transfer_class_init (YuiTransferClass * klass); -static void yui_transfer_init (YuiTransfer * yfe); -static void yui_transfer_browse (GtkWidget * widget, gpointer user_data); -static void yui_transfer_exec (GtkWidget * widget, YuiTransfer * yt); -static void yui_transfer_load (GtkWidget * entry, YuiTransfer * yt); -static void yui_transfer_load_exec (GtkWidget * entry, YuiTransfer * yt); -static void yui_transfer_store (GtkWidget * entry, YuiTransfer * yt); -static void yui_transfer_check (YuiTransfer * yt); - -GType yui_transfer_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiTransferClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_transfer_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiTransfer), - 0, - (GInstanceInitFunc) yui_transfer_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiTransfer", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_transfer_class_init (UNUSED YuiTransferClass * klass) { -} - -static void yui_transfer_init (YuiTransfer * yt) { - GtkWidget *vbox1; - GtkWidget *hbox1; - GtkWidget *label4; - GtkWidget *button1; - GtkWidget *hbox2; - GtkWidget *label2; - GtkWidget *hbuttonbox1; - GtkWidget *button5; - GtkWidget *hbox3; - GSList *radiobutton1_group = NULL; - GtkWidget *radiobutton1; - GtkWidget *radiobutton2; - GtkWidget *radiobutton3; - const char * tmp; - - gtk_window_set_title (GTK_WINDOW (yt), _("File transfer")); - - vbox1 = gtk_vbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (yt), vbox1); - - hbox1 = gtk_hbox_new (FALSE, 10); - gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, TRUE, 0); - gtk_container_set_border_width (GTK_CONTAINER (hbox1), 10); - - tmp = _("File"); - label4 = gtk_label_new (tmp); - gtk_box_pack_start (GTK_BOX (hbox1), label4, FALSE, FALSE, 0); - gtk_misc_set_alignment (GTK_MISC (label4), 0, 0.5); - gtk_label_set_width_chars (GTK_LABEL (label4), strlen(tmp)); - - yt->file_entry = gtk_entry_new (); - g_signal_connect_swapped(yt->file_entry, "changed", G_CALLBACK(yui_transfer_check), yt); - gtk_box_pack_start (GTK_BOX (hbox1), yt->file_entry, TRUE, TRUE, 0); - - button1 = gtk_button_new_with_mnemonic (_("Browse")); - g_signal_connect(button1, "clicked", G_CALLBACK(yui_transfer_browse), yt->file_entry); - gtk_box_pack_start (GTK_BOX (hbox1), button1, FALSE, FALSE, 0); - - hbox3 = gtk_hbox_new (FALSE, 10); - gtk_box_pack_start (GTK_BOX (vbox1), hbox3, FALSE, FALSE, 0); - gtk_container_set_border_width (GTK_CONTAINER (hbox3), 10); - - radiobutton1 = gtk_radio_button_new_with_mnemonic (NULL, _("Load as executable")); - g_signal_connect(radiobutton1, "toggled", G_CALLBACK(yui_transfer_load_exec), yt); - gtk_box_pack_start (GTK_BOX (hbox3), radiobutton1, FALSE, FALSE, 0); - gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton1), radiobutton1_group); - radiobutton1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton1)); - - radiobutton2 = gtk_radio_button_new_with_mnemonic (NULL, _("Load")); - g_signal_connect(radiobutton2, "toggled", G_CALLBACK(yui_transfer_load), yt); - gtk_box_pack_start (GTK_BOX (hbox3), radiobutton2, FALSE, FALSE, 0); - gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton2), radiobutton1_group); - radiobutton1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton2)); - - radiobutton3 = gtk_radio_button_new_with_mnemonic (NULL, _("Store")); - g_signal_connect(radiobutton3, "toggled", G_CALLBACK(yui_transfer_store), yt); - gtk_box_pack_start (GTK_BOX (hbox3), radiobutton3, FALSE, FALSE, 0); - gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton3), radiobutton1_group); - radiobutton1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton3)); - - hbox2 = gtk_hbox_new (FALSE, 10); - gtk_box_pack_start (GTK_BOX (vbox1), hbox2, FALSE, TRUE, 0); - gtk_container_set_border_width (GTK_CONTAINER (hbox2), 10); - - tmp = _("From"); - label2 = gtk_label_new (tmp); - gtk_box_pack_start (GTK_BOX (hbox2), label2, FALSE, FALSE, 0); - gtk_misc_set_alignment (GTK_MISC (label2), 0, 0.5); - gtk_label_set_width_chars (GTK_LABEL (label2), strlen(tmp)); - - yt->from_entry = gtk_entry_new (); - g_signal_connect_swapped(yt->from_entry, "changed", G_CALLBACK(yui_transfer_check), yt); - gtk_box_pack_start (GTK_BOX (hbox2), yt->from_entry, TRUE, TRUE, 0); - - tmp = _("To"); - yt->to_label = gtk_label_new (tmp); - gtk_box_pack_start (GTK_BOX (hbox2), yt->to_label, FALSE, FALSE, 0); - gtk_misc_set_alignment (GTK_MISC (yt->to_label), 0, 0.5); - gtk_label_set_width_chars (GTK_LABEL (yt->to_label), strlen(tmp)); - - yt->to_entry = gtk_entry_new (); - g_signal_connect_swapped(yt->to_entry, "changed", G_CALLBACK(yui_transfer_check), yt); - gtk_box_pack_start (GTK_BOX (hbox2), yt->to_entry, TRUE, TRUE, 0); - - hbuttonbox1 = gtk_hbutton_box_new (); - gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, FALSE, TRUE, 0); - gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox1), 10); - - yt->transfer_button = gtk_button_new_with_mnemonic (_("Transfer")); - gtk_container_add (GTK_CONTAINER (hbuttonbox1), yt->transfer_button); - g_signal_connect(yt->transfer_button, "clicked", G_CALLBACK(yui_transfer_exec), yt); - GTK_WIDGET_SET_FLAGS (yt->transfer_button, GTK_CAN_DEFAULT); - - button5 = gtk_button_new_from_stock ("gtk-cancel"); - gtk_container_add (GTK_CONTAINER (hbuttonbox1), button5); - g_signal_connect_swapped(button5, "clicked", G_CALLBACK(gtk_widget_destroy), yt); - GTK_WIDGET_SET_FLAGS (button5, GTK_CAN_DEFAULT); - - gtk_widget_show_all (GTK_WIDGET(yt)); - - gtk_widget_set_sensitive(GTK_WIDGET(yt->to_label), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(yt->to_entry), FALSE); - - yt->mode = YUI_TRANSFER_LOAD_EXEC; - -} - -GtkWidget * yui_transfer_new(YuiWindow * yw) { - GtkWidget * entry; - YuiTransfer * yfe; - - entry = GTK_WIDGET(g_object_new(yui_transfer_get_type(), NULL)); - yfe = YUI_TRANSFERT(entry); - - gtk_widget_show_all(entry); - - yui_transfer_check(yfe); - - yui_window_start(yw); - - return entry; -} - -static void yui_transfer_browse(UNUSED GtkWidget * widget, gpointer user_data) { - GtkWidget * file_selector; - gint result; - const gchar * filename; - - file_selector = gtk_file_chooser_dialog_new (_("Please choose a file"), NULL, GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); - filename = gtk_entry_get_text(GTK_ENTRY(user_data)); - if (filename[0] != '\0') - gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(file_selector), filename); - - gtk_widget_show(file_selector); - - result = gtk_dialog_run(GTK_DIALOG(file_selector)); - - switch(result) { - case GTK_RESPONSE_ACCEPT: - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_selector)); - gtk_entry_set_text(GTK_ENTRY(user_data), filename); - break; - case GTK_RESPONSE_CANCEL: - break; - } - - gtk_widget_destroy(file_selector); -} - -static void yui_transfer_exec(UNUSED GtkWidget * widget, YuiTransfer * yt) { - guint32 from, to; - - switch(yt->mode) { - case YUI_TRANSFER_LOAD: - sscanf(gtk_entry_get_text(GTK_ENTRY(yt->from_entry)), "%x", &from); - MappedMemoryLoad(gtk_entry_get_text(GTK_ENTRY(yt->file_entry)), from); - break; - case YUI_TRANSFER_LOAD_EXEC: - sscanf(gtk_entry_get_text(GTK_ENTRY(yt->from_entry)), "%x", &from); - MappedMemoryLoadExec(gtk_entry_get_text(GTK_ENTRY(yt->file_entry)), from); - break; - case YUI_TRANSFER_STORE: - sscanf(gtk_entry_get_text(GTK_ENTRY(yt->from_entry)), "%x", &from); - sscanf(gtk_entry_get_text(GTK_ENTRY(yt->to_entry)), "%x", &to); - MappedMemorySave(gtk_entry_get_text(GTK_ENTRY(yt->file_entry)), from, to - from); - break; - } - - gtk_widget_destroy(GTK_WIDGET(yt)); -} - -static void yui_transfer_load(GtkWidget * entry, YuiTransfer * yt) { - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(entry))) { - yt->mode = YUI_TRANSFER_LOAD; - gtk_widget_set_sensitive(GTK_WIDGET(yt->to_label), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(yt->to_entry), FALSE); - yui_transfer_check(yt); - } -} - -static void yui_transfer_load_exec(GtkWidget * entry, YuiTransfer * yt) { - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(entry))) { - yt->mode = YUI_TRANSFER_LOAD_EXEC; - gtk_widget_set_sensitive(GTK_WIDGET(yt->to_label), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(yt->to_entry), FALSE); - yui_transfer_check(yt); - } -} - -static void yui_transfer_store(GtkWidget * entry, YuiTransfer * yt) { - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(entry))) { - yt->mode = YUI_TRANSFER_STORE; - gtk_widget_set_sensitive(GTK_WIDGET(yt->to_label), TRUE); - gtk_widget_set_sensitive(GTK_WIDGET(yt->to_entry), TRUE); - yui_transfer_check(yt); - } -} - -static void yui_transfer_check(YuiTransfer * yt) { - gboolean ok = FALSE; - - if (*gtk_entry_get_text(GTK_ENTRY(yt->file_entry)) != '\0') { - switch(yt->mode) { - case YUI_TRANSFER_LOAD: - case YUI_TRANSFER_LOAD_EXEC: - if (*gtk_entry_get_text(GTK_ENTRY(yt->from_entry)) != '\0') { - ok = TRUE; - } - break; - case YUI_TRANSFER_STORE: - if ((*gtk_entry_get_text(GTK_ENTRY(yt->from_entry)) != '\0') && (*gtk_entry_get_text(GTK_ENTRY(yt->to_entry)) != '\0')) { - ok = TRUE; - } - break; - } - } - - gtk_widget_set_sensitive(yt->transfer_button, ok); -} diff --git a/yabause/src/gtk/yuitransfer.h b/yabause/src/gtk/yuitransfer.h deleted file mode 100644 index e6af1f1759..0000000000 --- a/yabause/src/gtk/yuitransfer.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_TRANSFERT_H -#define YUI_TRANSFERT_H - -#include -#include -#include - -#include "yuiwindow.h" - -G_BEGIN_DECLS - -#define YUI_TRANSFERT_TYPE (yui_transfer_get_type ()) -#define YUI_TRANSFERT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_TRANSFERT_TYPE, YuiTransfer)) -#define YUI_TRANSFERT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_TRANSFERT_TYPE, YuiTransferClass)) -#define IS_YUI_TRANSFERT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_TRANSFERT_TYPE)) -#define IS_YUI_TRANSFERT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_TRANSFERT_TYPE)) - -#define YUI_TRANSFER_LOAD 1 -#define YUI_TRANSFER_LOAD_EXEC 2 -#define YUI_TRANSFER_STORE 3 - -typedef struct _YuiTransfer YuiTransfer; -typedef struct _YuiTransferClass YuiTransferClass; - -struct _YuiTransfer -{ - GtkWindow window; - - GtkWidget * file_entry; - GtkWidget * from_entry; - GtkWidget * to_label; - GtkWidget * to_entry; - GtkWidget * transfer_button; - - int mode; -}; - -struct _YuiTransferClass -{ - GtkWindowClass parent_class; - - void (* yui_transfer) (YuiTransfer * yfe); -}; - -GType yui_transfer_get_type (void); -GtkWidget* yui_transfer_new (YuiWindow * yw); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuivdp1.c b/yabause/src/gtk/yuivdp1.c deleted file mode 100644 index 4b1e3ea5fa..0000000000 --- a/yabause/src/gtk/yuivdp1.c +++ /dev/null @@ -1,289 +0,0 @@ -/* Copyright 2006-2007 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "yuiviewer.h" -#include "yuivdp1.h" -#include "../vdp1.h" -#include "../yabause.h" -#include "settings.h" - -static void yui_vdp1_class_init (YuiVdp1Class * klass); -static void yui_vdp1_init (YuiVdp1 * yfe); -static void yui_vdp1_view_cursor_changed(GtkWidget * view, YuiVdp1 * vdp1); -static void yui_vdp1_clear(YuiVdp1 * vdp1); -static void yui_vdp1_draw(YuiVdp1 * vdp1); - -GType yui_vdp1_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiVdp1Class), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_vdp1_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiVdp1), - 0, - (GInstanceInitFunc) yui_vdp1_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiVdp1", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_vdp1_class_init (UNUSED YuiVdp1Class * klass) { -} - -static void yui_vdp1_init (YuiVdp1 * yv) { - GtkWidget * hbox, * vbox, * vbox2, * view; - - gtk_window_set_title(GTK_WINDOW(yv), "VDP1"); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 0); - gtk_container_add(GTK_CONTAINER(yv), vbox); - - yv->toolbar = gtk_toolbar_new(); - - gtk_toolbar_set_style(GTK_TOOLBAR(yv->toolbar), GTK_TOOLBAR_ICONS); - - gtk_box_pack_start(GTK_BOX(vbox), yv->toolbar, FALSE, FALSE, 0); - - hbox = gtk_hpaned_new(); - gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 4); - - yv->store = gtk_list_store_new(2, G_TYPE_STRING, GDK_TYPE_PIXBUF); - view = gtk_tree_view_new_with_model(GTK_TREE_MODEL (yv->store)); - gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE); - { - GtkWidget * scroll; - GtkCellRenderer *renderer; - GtkCellRenderer *icon; - GtkTreeViewColumn *column; - - scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes("Command", renderer, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (view), column); - - icon = gtk_cell_renderer_pixbuf_new(); - g_object_set(icon, "xalign", 0, NULL); - column = gtk_tree_view_column_new_with_attributes("Icon", icon, "pixbuf", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (view), column); - - gtk_container_add(GTK_CONTAINER(scroll), view); - gtk_paned_pack1(GTK_PANED(hbox), scroll, FALSE, TRUE); - } - g_signal_connect(view, "cursor-changed", G_CALLBACK(yui_vdp1_view_cursor_changed), yv); - - g_signal_connect(G_OBJECT(yv), "delete-event", GTK_SIGNAL_FUNC(yui_vdp1_destroy), NULL); - - vbox2 = gtk_vpaned_new(); - gtk_paned_pack2(GTK_PANED(hbox), vbox2, TRUE, TRUE); - { - GtkWidget * scroll = gtk_scrolled_window_new(NULL, NULL); - GtkWidget * text = gtk_text_view_new(); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE); - gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(text), FALSE); - yv->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text)); - gtk_container_add(GTK_CONTAINER(scroll), text); - gtk_paned_pack1(GTK_PANED(vbox2), scroll, FALSE, TRUE); - } - yv->image = yui_viewer_new(); - { - GtkWidget * scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), yv->image); - gtk_paned_pack2(GTK_PANED(vbox2), scroll, TRUE, TRUE); - } - - yv->cursor = 0; - yv->texture = NULL; - - gtk_window_set_default_size(GTK_WINDOW(yv), 500, 450); - - gtk_paned_set_position(GTK_PANED(hbox), 250); - - gtk_paned_set_position(GTK_PANED(vbox2), 200); -} - -GtkWidget * yui_vdp1_new(YuiWindow * y) { - GtkWidget * dialog; - YuiVdp1 * yv; - - dialog = GTK_WIDGET(g_object_new(yui_vdp1_get_type(), NULL)); - yv = YUI_VDP1(dialog); - - yv->yui = y; - - if (!( yv->yui->state & YUI_IS_INIT )) { - yui_window_run(yv->yui); - yui_window_pause(yv->yui); - } - - { - GtkToolItem * play_button, * pause_button; - - play_button = gtk_tool_button_new_from_stock("run"); - gtk_action_connect_proxy(gtk_action_group_get_action(yv->yui->action_group, "run"), GTK_WIDGET(play_button)); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), GTK_TOOL_ITEM(play_button), -1); - - pause_button = gtk_tool_button_new_from_stock("pause"); - gtk_action_connect_proxy(gtk_action_group_get_action(yv->yui->action_group, "pause"), GTK_WIDGET(pause_button)); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), GTK_TOOL_ITEM(pause_button), -1); - } - yv->paused_handler = g_signal_connect_swapped(yv->yui, "paused", G_CALLBACK(yui_vdp1_update), yv); - yv->running_handler = g_signal_connect_swapped(yv->yui, "running", G_CALLBACK(yui_vdp1_clear), yv); - - if ((yv->yui->state & (YUI_IS_RUNNING | YUI_IS_INIT)) == YUI_IS_INIT) - yui_vdp1_update(yv); - - gtk_widget_show_all(GTK_WIDGET(yv)); - - return dialog; -} - -void yui_vdp1_fill(YuiVdp1 * vdp1) { - gint j; - gchar * string; - gchar nameTemp[1024]; - GtkTreeIter iter; - - yui_vdp1_clear(vdp1); - - j = 0; - - string = Vdp1DebugGetCommandNumberName(j); - while(string && (j < MAX_VDP1_COMMAND)) { - gtk_list_store_append(vdp1->store, &iter); - gtk_list_store_set(vdp1->store, &iter, 0, string, -1); - - { - u32 * icontext; - int wtext, htext; - int rowstride; - GdkPixbuf * pixbuftext, * resized; - float ratio; - - icontext = Vdp1DebugTexture(j, &wtext, &htext); - - if ((icontext != NULL) && (wtext > 0) && (htext > 0)) { - rowstride = wtext * 4; - rowstride += (rowstride % 4)? (4 - (rowstride % 4)): 0; - pixbuftext = gdk_pixbuf_new_from_data((const guchar *) icontext, GDK_COLORSPACE_RGB, TRUE, 8, - wtext, htext, rowstride, yui_texture_free, NULL); - - ratio = (float) 16 / htext; - if (htext > 16) { - resized = gdk_pixbuf_scale_simple(pixbuftext, wtext * ratio, 16, GDK_INTERP_BILINEAR); - } else { - resized = gdk_pixbuf_scale_simple(pixbuftext, wtext, htext, GDK_INTERP_BILINEAR); - } - - gtk_list_store_set(vdp1->store, &iter, 1, resized, -1); - - g_object_unref(pixbuftext); - g_object_unref(resized); - } - } - - j++; - string = Vdp1DebugGetCommandNumberName(j); - } - - Vdp1DebugCommand(vdp1->cursor, nameTemp); - gtk_text_buffer_set_text(vdp1->buffer, g_strstrip(nameTemp), -1); - vdp1->texture = Vdp1DebugTexture(vdp1->cursor, &vdp1->w, &vdp1->h); - yui_vdp1_draw(vdp1); -} - -static void yui_vdp1_view_cursor_changed(GtkWidget * view, YuiVdp1 * vdp1) { - GtkTreePath * path; - gchar * strpath; - int i; - - gtk_tree_view_get_cursor(GTK_TREE_VIEW(view), &path, NULL); - - if (path) { - gchar nameTemp[1024]; - - yui_viewer_clear(YUI_VIEWER(vdp1->image)); - - strpath = gtk_tree_path_to_string(path); - - sscanf(strpath, "%i", &i); - - vdp1->cursor = i; - - Vdp1DebugCommand(i, nameTemp); - gtk_text_buffer_set_text(vdp1->buffer, g_strstrip(nameTemp), -1); - vdp1->texture = Vdp1DebugTexture(i, &vdp1->w, &vdp1->h); - yui_vdp1_draw(vdp1); - - g_free(strpath); - gtk_tree_path_free(path); - } -} - -void yui_vdp1_update(YuiVdp1 * vdp1) { - gint i; - for(i = 0 ; i < MAX_VDP1_COMMAND ; i++ ) if ( !Vdp1DebugGetCommandNumberName(i)) break; - vdp1->cursor = 0; - yui_vdp1_fill(vdp1); -} - -void yui_vdp1_destroy(YuiVdp1 * vdp1) { - g_signal_handler_disconnect(vdp1->yui, vdp1->running_handler); - g_signal_handler_disconnect(vdp1->yui, vdp1->paused_handler); - - gtk_widget_destroy(GTK_WIDGET(vdp1)); -} - -static void yui_vdp1_clear(YuiVdp1 * vdp1) { - gtk_list_store_clear(vdp1->store); - gtk_text_buffer_set_text(vdp1->buffer, "", -1); - yui_viewer_clear(YUI_VIEWER(vdp1->image)); -} - -static void yui_vdp1_draw(YuiVdp1 * vdp1) { - GdkPixbuf * pixbuf; - int rowstride; - - if ((vdp1->texture != NULL) && (vdp1->w > 0) && (vdp1->h > 0)) { - rowstride = vdp1->w * 4; - rowstride += (rowstride % 4)? (4 - (rowstride % 4)): 0; - pixbuf = gdk_pixbuf_new_from_data((const guchar *) vdp1->texture, GDK_COLORSPACE_RGB, TRUE, 8, - vdp1->w, vdp1->h, rowstride, yui_texture_free, NULL); - - yui_viewer_draw_pixbuf(YUI_VIEWER(vdp1->image), pixbuf, vdp1->w, vdp1->h); - - g_object_unref(pixbuf); - } -} diff --git a/yabause/src/gtk/yuivdp1.h b/yabause/src/gtk/yuivdp1.h deleted file mode 100644 index 0ecc246595..0000000000 --- a/yabause/src/gtk/yuivdp1.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_VDP1_H -#define YUI_VDP1_H - -#include - -#include "yuiwindow.h" -#include "../core.h" - -G_BEGIN_DECLS - -#define YUI_VDP1_TYPE (yui_vdp1_get_type ()) -#define YUI_VDP1(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_VDP1_TYPE, YuiVdp1)) -#define YUI_VDP1_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_VDP1_TYPE, YuiVdp1Class)) -#define IS_YUI_VDP1(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_VDP1_TYPE)) -#define IS_YUI_VDP1_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_VDP1_TYPE)) - -#define MAX_VDP1_COMMAND 4000 - -typedef struct _YuiVdp1 YuiVdp1; -typedef struct _YuiVdp1Class YuiVdp1Class; - -struct _YuiVdp1 -{ - GtkWindow dialog; - - GtkWidget * image; - GtkWidget * toolbar; - - GtkListStore * store; - GtkTextBuffer * buffer; - - gint cursor; - u32 * texture; - int w; - int h; - - gulong paused_handler; - gulong running_handler; - YuiWindow * yui; -}; - -struct _YuiVdp1Class -{ - GtkWindowClass parent_class; - - void (* yui_vdp1) (YuiVdp1 * yv); -}; - -GType yui_vdp1_get_type (void); -GtkWidget * yui_vdp1_new (YuiWindow * yui); -void yui_vdp1_fill (YuiVdp1 * vdp1); -void yui_vdp1_update (YuiVdp1 * vdp1); -void yui_vdp1_destroy (YuiVdp1 * vdp1); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuivdp2.c b/yabause/src/gtk/yuivdp2.c deleted file mode 100644 index 46bdc82c54..0000000000 --- a/yabause/src/gtk/yuivdp2.c +++ /dev/null @@ -1,318 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "yuivdp2.h" -#include "../vdp2.h" -#include "../yabause.h" -#include "settings.h" -#include "../vdp2debug.h" -#include "yuiviewer.h" - -static void yui_vdp2_sync(GtkAction * action, YuiVdp2 * yv); -static const char * yui_vdp2_action_names[] = { NULL, "toggle_nbg0", "toggle_nbg1", "toggle_nbg2", "toggle_nbg3", "toggle_rbg0" }; - -static void yui_vdp2_class_init (YuiVdp2Class * klass); -static void yui_vdp2_init (YuiVdp2 * yfe); -static void yui_vdp2_clear(YuiVdp2 * vdp2); -static void yui_vdp2_view_cursor_changed(GtkWidget * view, YuiVdp2 * vdp2); -static void yui_vdp2_draw(YuiVdp2 * vdp2, u32 * texture, int w, int h); - -GType yui_vdp2_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiVdp2Class), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_vdp2_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiVdp2), - 0, - (GInstanceInitFunc) yui_vdp2_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiVdp2", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_vdp2_class_init (UNUSED YuiVdp2Class * klass) { -} - -static void yui_vdp2_toggle(GtkCellRendererToggle * crt, const gchar * path, YuiVdp2 * yv) { - int val; - GtkAction * action = NULL; - - sscanf(path, "%d", &val); - if (! yui_vdp2_action_names[val]) return; - - action = gtk_action_group_get_action(yv->yui->action_group, yui_vdp2_action_names[val]); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), ! gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action))); -} - -static void yui_vdp2_sync(GtkAction * action, YuiVdp2 * yv) { - GtkTreeIter iter; - const gchar * name; - - name = gtk_action_get_name(action) + 7; - - if (!strcmp("nbg0", name)) - gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(yv->store), &iter, "1"); - else if (!strcmp("nbg1", name)) - gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(yv->store), &iter, "2"); - else if (!strcmp("nbg2", name)) - gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(yv->store), &iter, "3"); - else if (!strcmp("nbg3", name)) - gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(yv->store), &iter, "4"); - else if (!strcmp("rbg0", name)) - gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(yv->store), &iter, "5"); - - gtk_list_store_set(yv->store, &iter, 1, gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)), -1); -} - -static void yui_vdp2_init (YuiVdp2 * yv) { - GtkWidget * text; - GtkWidget * scroll; - GtkWidget * box, * box2; - GtkWidget * hpane; - GtkWidget * view; - const char * screens[] = { "General", "NBG0/RBG1", "NBG1", "NBG2", "NBG3", "RBG0" }; - unsigned int i; - - gtk_window_set_title(GTK_WINDOW(yv), "VDP2"); - - box = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(box), 0); - gtk_container_add(GTK_CONTAINER(yv), box); - - yv->toolbar = gtk_toolbar_new(); - gtk_toolbar_set_style(GTK_TOOLBAR(yv->toolbar), GTK_TOOLBAR_ICONS); - gtk_box_pack_start(GTK_BOX(box), yv->toolbar, FALSE, FALSE, 0); - - hpane = gtk_hpaned_new(); - gtk_container_add(GTK_CONTAINER(box), hpane); - - yv->store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN); - view = gtk_tree_view_new_with_model(GTK_TREE_MODEL (yv->store)); - gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE); - { - GtkWidget * scroll; - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - - scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes("Command", renderer, "text", 0, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (view), column); - - renderer = gtk_cell_renderer_toggle_new(); - gtk_cell_renderer_toggle_set_activatable(GTK_CELL_RENDERER_TOGGLE(renderer), TRUE); - g_signal_connect(renderer, "toggled", G_CALLBACK(yui_vdp2_toggle), yv); - column = gtk_tree_view_column_new_with_attributes("Command", renderer, "active", 1, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW (view), column); - - gtk_container_add(GTK_CONTAINER(scroll), view); - gtk_paned_pack1(GTK_PANED(hpane), scroll, FALSE, TRUE); - } - g_signal_connect(view, "cursor-changed", G_CALLBACK(yui_vdp2_view_cursor_changed), yv); - - scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_paned_pack2(GTK_PANED(hpane), scroll, TRUE, TRUE); - box2 = gtk_vpaned_new(); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), box2); - - for(i = 0;i < (sizeof(screens) / sizeof(screens[0]));i++) { - GtkTreeIter iter; - gtk_list_store_append(yv->store, &iter); - gtk_list_store_set(yv->store, &iter, 0, screens[i], -1); - } - - text = gtk_text_view_new(); - gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE); - gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(text), FALSE); - { - GtkWidget * scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), text); - gtk_paned_pack1(GTK_PANED(box2), scroll, FALSE, TRUE); - } - - yv->buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)); - - yv->image = yui_viewer_new(); - { - GtkWidget * scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), yv->image); - gtk_paned_pack2(GTK_PANED(box2), scroll, TRUE, TRUE); - } - - gtk_window_set_default_size(GTK_WINDOW(yv), 500, 450); - - gtk_paned_set_position(GTK_PANED(hpane), 120); - - g_signal_connect(G_OBJECT(yv), "delete-event", GTK_SIGNAL_FUNC(yui_vdp2_destroy), NULL); -} - -GtkWidget * yui_vdp2_new(YuiWindow * y) { - GtkWidget * dialog; - YuiVdp2 * yv; - int i; - - dialog = GTK_WIDGET(g_object_new(yui_vdp2_get_type(), NULL)); - yv = YUI_VDP2(dialog); - - yv->yui = y; - - if (!( yv->yui->state & YUI_IS_INIT )) { - yui_window_run(yv->yui); - yui_window_pause(yv->yui); - } - - { - GtkToolItem * play_button, * pause_button; - - play_button = gtk_tool_button_new_from_stock("run"); - gtk_action_connect_proxy(gtk_action_group_get_action(yv->yui->action_group, "run"), GTK_WIDGET(play_button)); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), GTK_TOOL_ITEM(play_button), -1); - - pause_button = gtk_tool_button_new_from_stock("pause"); - gtk_action_connect_proxy(gtk_action_group_get_action(yv->yui->action_group, "pause"), GTK_WIDGET(pause_button)); - gtk_toolbar_insert(GTK_TOOLBAR(yv->toolbar), GTK_TOOL_ITEM(pause_button), -1); - } - yv->paused_handler = g_signal_connect_swapped(yv->yui, "paused", G_CALLBACK(yui_vdp2_update), yv); - yv->running_handler = g_signal_connect_swapped(yv->yui, "running", G_CALLBACK(yui_vdp2_clear), yv); - - for(i = 0;i < (sizeof(yui_vdp2_action_names) / sizeof(yui_vdp2_action_names[0]));i++) { - GtkAction * action; - - if (! yui_vdp2_action_names[i]) continue; - - action = gtk_action_group_get_action(yv->yui->action_group, yui_vdp2_action_names[i]); - yui_vdp2_sync(action, yv); - g_signal_connect(action, "toggled", G_CALLBACK(yui_vdp2_sync), yv); - } - - if ((yv->yui->state & (YUI_IS_RUNNING | YUI_IS_INIT)) == YUI_IS_INIT) - yui_vdp2_update(yv); - - gtk_widget_show_all(GTK_WIDGET(yv)); - - return dialog; -} - -void yui_vdp2_update(YuiVdp2 * vdp2) { - gchar nameTemp[VDP2_DEBUG_STRING_SIZE]; - gboolean isscrenabled; - - yui_viewer_clear(YUI_VIEWER(vdp2->image)); - - switch(vdp2->cursor) { - case 0: - Vdp2DebugStatsGeneral(nameTemp, &isscrenabled); - break; - case 1: - Vdp2DebugStatsNBG0(nameTemp, &isscrenabled); - break; - case 2: - Vdp2DebugStatsNBG1(nameTemp, &isscrenabled); - break; - case 3: - Vdp2DebugStatsNBG2(nameTemp, &isscrenabled); - break; - case 4: - Vdp2DebugStatsNBG3(nameTemp, &isscrenabled); - break; - case 5: - Vdp2DebugStatsRBG0(nameTemp, &isscrenabled); - break; - } - - if (vdp2->cursor > 0) { - u32 * texture; - int w, h; - texture = Vdp2DebugTexture(vdp2->cursor - 1, &w, &h); - yui_vdp2_draw(vdp2, texture, w, h); - } - - if (isscrenabled) { - gtk_text_buffer_set_text(vdp2->buffer, nameTemp, -1); - } else { - gtk_text_buffer_set_text(vdp2->buffer, "", -1); - } -} - -void yui_vdp2_destroy(YuiVdp2 * vdp2) { - g_signal_handler_disconnect(vdp2->yui, vdp2->paused_handler); - g_signal_handler_disconnect(vdp2->yui, vdp2->running_handler); - gtk_widget_destroy(GTK_WIDGET(vdp2)); -} - -static void yui_vdp2_clear(YuiVdp2 * vdp2) { - gtk_text_buffer_set_text(vdp2->buffer, "", -1); -} - -void yui_vdp2_view_cursor_changed(GtkWidget * view, YuiVdp2 * vdp2) { - GtkTreePath * path; - gchar * strpath; - int i; - - gtk_tree_view_get_cursor(GTK_TREE_VIEW(view), &path, NULL); - - if (path) { - strpath = gtk_tree_path_to_string(path); - - sscanf(strpath, "%i", &i); - - vdp2->cursor = i; - - yui_vdp2_update(vdp2); - - g_free(strpath); - gtk_tree_path_free(path); - } -} - -static void yui_vdp2_draw(YuiVdp2 * vdp2, u32 * texture, int w, int h) { - GdkPixbuf * pixbuf; - int rowstride; - - if ((texture != NULL) && (w > 0) && (h > 0)) { - rowstride = w * 4; - rowstride += (rowstride % 4)? (4 - (rowstride % 4)): 0; - pixbuf = gdk_pixbuf_new_from_data((const guchar *) texture, GDK_COLORSPACE_RGB, TRUE, 8, - w, h, rowstride, yui_texture_free, NULL); - - yui_viewer_draw_pixbuf(YUI_VIEWER(vdp2->image), pixbuf, w, h); - - g_object_unref(pixbuf); - } -} diff --git a/yabause/src/gtk/yuivdp2.h b/yabause/src/gtk/yuivdp2.h deleted file mode 100644 index 710d7f4068..0000000000 --- a/yabause/src/gtk/yuivdp2.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_VDP2_H -#define YUI_VDP2_H - -#include -#include -#include - -#include "yuiwindow.h" - -G_BEGIN_DECLS - -#define YUI_VDP2_TYPE (yui_vdp2_get_type ()) -#define YUI_VDP2(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_VDP2_TYPE, YuiVdp2)) -#define YUI_VDP2_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_VDP2_TYPE, YuiVdp2Class)) -#define IS_YUI_VDP2(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_VDP2_TYPE)) -#define IS_YUI_VDP2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_VDP2_TYPE)) - -typedef struct _YuiVdp2 YuiVdp2; -typedef struct _YuiVdp2Class YuiVdp2Class; - -struct _YuiVdp2 -{ - GtkWindow dialog; - - GtkWidget * image; - GtkTextBuffer * buffer; - GtkWidget * toolbar; - - GtkListStore * store; - - gint cursor; - - gulong paused_handler; - gulong running_handler; - - YuiWindow * yui; -}; - -struct _YuiVdp2Class -{ - GtkWindowClass parent_class; -}; - -GType yui_vdp2_get_type (void); -GtkWidget * yui_vdp2_new (YuiWindow * yui); -void yui_vdp2_fill (YuiVdp2 * vdp2); -void yui_vdp2_update (YuiVdp2 * vdp2); -void yui_vdp2_destroy (YuiVdp2 * vdp2); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuiviewer.c b/yabause/src/gtk/yuiviewer.c deleted file mode 100644 index e8ac5a07ea..0000000000 --- a/yabause/src/gtk/yuiviewer.c +++ /dev/null @@ -1,166 +0,0 @@ -/* Copyright 2006-2007 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "yuiviewer.h" -#include "gtkglwidget.h" -#include "../core.h" - -static void yui_viewer_class_init (YuiViewerClass * klass); -static void yui_viewer_init (YuiViewer * yfe); -static void yui_viewer_expose (GtkWidget * widget, GdkEventExpose *event, gpointer data); - -GType yui_viewer_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiViewerClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_viewer_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiViewer), - 0, - (GInstanceInitFunc) yui_viewer_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_DRAWING_AREA, "YuiViewer", &yfe_info, 0); - } - - return yfe_type; -} - -static void yui_viewer_class_init (UNUSED YuiViewerClass * klass) { -} - -static gint -my_popup_handler (GtkWidget *widget, GdkEvent *event) -{ - GtkMenu *menu; - GdkEventButton *event_button; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_MENU (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - /* The "widget" is the menu that was supplied when - * * g_signal_connect_swapped() was called. - * */ - menu = GTK_MENU (widget); - - if (event->type == GDK_BUTTON_PRESS) - { - event_button = (GdkEventButton *) event; - if (event_button->button == 3) - { - gtk_menu_popup (menu, NULL, NULL, NULL, NULL, - event_button->button, event_button->time); - return TRUE; - } - } - - return FALSE; -} - -static void yui_viewer_init (YuiViewer * yv) { - GtkWidget * menu; - GtkWidget * item; - - gtk_widget_set_events(GTK_WIDGET(yv), GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); - - menu = gtk_menu_new(); - item = gtk_image_menu_item_new_from_stock(GTK_STOCK_SAVE, NULL); - - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - - gtk_widget_show_all(menu); - - g_signal_connect_swapped(yv, "button-press-event", G_CALLBACK(my_popup_handler), menu); - g_signal_connect(yv, "expose-event", G_CALLBACK(yui_viewer_expose), NULL); - g_signal_connect_swapped(item, "activate", G_CALLBACK(yui_viewer_save), yv); - - yv->pixbuf = NULL; -} - -GtkWidget * yui_viewer_new(void) { - GtkWidget * dialog; - - dialog = GTK_WIDGET(g_object_new(yui_viewer_get_type(), NULL)); - - return dialog; -} - -static void yui_viewer_expose(GtkWidget * widget, GdkEventExpose *event, gpointer data) { - YuiViewer * yv = YUI_VIEWER(widget); - - if (yv->pixbuf != NULL) { - gdk_draw_pixbuf(widget->window, NULL, yv->pixbuf, 0, 0, 0, 0, yv->w, yv->h, GDK_RGB_DITHER_NONE, 0, 0); - } -} - -void yui_viewer_save(YuiViewer * yv) { - GtkWidget * file_selector; - gint result; - char * filename; - int rowstride; - - file_selector = gtk_file_chooser_dialog_new ("Please choose a file", NULL, GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); - - gtk_widget_show(file_selector); - - result = gtk_dialog_run(GTK_DIALOG(file_selector)); - - switch(result) { - case GTK_RESPONSE_ACCEPT: - rowstride = yv->w * 4; - rowstride += (rowstride % 4)? (4 - (rowstride % 4)): 0; - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_selector)); - - gdk_pixbuf_save(yv->pixbuf, filename, "png", NULL, NULL); - - break; - case GTK_RESPONSE_CANCEL: - break; - } - - gtk_widget_destroy(file_selector); -} - -void yui_viewer_draw_pixbuf(YuiViewer * yv, GdkPixbuf * pixbuf, int w, int h) { - if (yv->pixbuf) { - g_object_unref(yv->pixbuf); - } - yv->pixbuf = g_object_ref(pixbuf); - yv->w = w; - yv->h = h; - gdk_window_clear(GTK_WIDGET(yv)->window); - gtk_widget_queue_draw_area(GTK_WIDGET(yv), 0, 0, w, h); -} - -void yui_viewer_clear(YuiViewer * yv) { - if (GTK_WIDGET(yv)->window != NULL) { - gdk_window_clear(GTK_WIDGET(yv)->window); - } -} diff --git a/yabause/src/gtk/yuiviewer.h b/yabause/src/gtk/yuiviewer.h deleted file mode 100644 index 35b2e92f30..0000000000 --- a/yabause/src/gtk/yuiviewer.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - Copyright 2005-2006 Fabien Coulon - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_VIEWER_H -#define YUI_VIEWER_H - -#include - -G_BEGIN_DECLS - -#define YUI_VIEWER_TYPE (yui_viewer_get_type ()) -#define YUI_VIEWER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_VIEWER_TYPE, YuiViewer)) -#define YUI_VIEWER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_VIEWER_TYPE, YuiViewerClass)) -#define IS_YUI_VIEWER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_VIEWER_TYPE)) -#define IS_YUI_VIEWER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_VIEWER_TYPE)) - -typedef struct _YuiViewer YuiViewer; -typedef struct _YuiViewerClass YuiViewerClass; - -struct _YuiViewer -{ - GtkDrawingArea parent; - - int w; - int h; - GdkPixbuf * pixbuf; -}; - -struct _YuiViewerClass -{ - GtkDrawingAreaClass parent_class; -}; - -GType yui_viewer_get_type (void); -GtkWidget * yui_viewer_new (void); -void yui_viewer_draw_pixbuf(YuiViewer * yv, GdkPixbuf * pixbuf, int w, int h); -void yui_viewer_save (YuiViewer * yv); -void yui_viewer_clear (YuiViewer * yv); - -G_END_DECLS - -#endif diff --git a/yabause/src/gtk/yuiwindow.c b/yabause/src/gtk/yuiwindow.c deleted file mode 100644 index 694484f599..0000000000 --- a/yabause/src/gtk/yuiwindow.c +++ /dev/null @@ -1,373 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -#include "yuiwindow.h" -#include "gtkglwidget.h" -#include "../yabause.h" - -#include "settings.h" - -static void yui_window_class_init (YuiWindowClass * klass); -static void yui_window_init (YuiWindow * yfe); -static gboolean yui_window_keypress(GtkWidget *widget, GdkEventKey *event, gpointer user_data); -static gboolean yui_window_keyrelease(GtkWidget *widget, GdkEventKey *event, gpointer user_data); -static void yui_window_keep_clean(GtkWidget * widget, GdkEventExpose * event, YuiWindow * yui); -static void yui_window_toggle_fullscreen(GtkWidget * w, YuiWindow * yui); -static void yui_window_toggle_frameskip(GtkWidget * w, YuiWindow * yui); - -static void yui_window_create_actions(YuiWindow * yw) { - GtkAction * action; - GtkToggleAction * taction; - - action = gtk_action_new("run", _("Run"), _("start emulation"), "gtk-media-play"); - gtk_action_group_add_action_with_accel(yw->action_group, action, "r"); - g_signal_connect_swapped(action, "activate", G_CALLBACK(yui_window_run), yw); - - action = gtk_action_new("pause", _("Pause"), _("pause emulation"), "gtk-media-pause"); - gtk_action_group_add_action_with_accel(yw->action_group, action, "p"); - g_signal_connect_swapped(action, "activate", G_CALLBACK(yui_window_pause), yw); - - action = gtk_action_new("reset", _("Reset"), _("reset emulation"), NULL); - gtk_action_group_add_action_with_accel(yw->action_group, action, NULL); - g_signal_connect_swapped(action, "activate", G_CALLBACK(yui_window_reset), yw); - - taction = gtk_toggle_action_new("fullscreen", _("Fullscreen"), NULL, "gtk-fullscreen"); - gtk_action_group_add_action_with_accel(yw->action_group, GTK_ACTION(taction), "f"); - g_signal_connect(taction, "activate", G_CALLBACK(yui_window_toggle_fullscreen), yw); - - taction = gtk_toggle_action_new("frameskip", _("Frame Skip/Limiter"), NULL, NULL); - gtk_action_group_add_action_with_accel(yw->action_group, GTK_ACTION(taction), NULL); - g_signal_connect(taction, "activate", G_CALLBACK(yui_window_toggle_frameskip), yw); - - action = gtk_action_new("quit", _("Quit"), NULL, "gtk-quit"); - gtk_action_group_add_action_with_accel(yw->action_group, action, "q"); - g_signal_connect(action, "activate", G_CALLBACK(gtk_main_quit), yw); - - taction = gtk_toggle_action_new("toggle_vdp1", _("VDP1"), NULL, NULL); - gtk_toggle_action_set_active(taction, TRUE); - gtk_action_group_add_action_with_accel(yw->action_group, GTK_ACTION(taction), NULL); - g_signal_connect(taction, "activate", G_CALLBACK(ToggleVDP1), NULL); - - taction = gtk_toggle_action_new("toggle_nbg0", _("NBG0"), NULL, NULL); - gtk_toggle_action_set_active(taction, TRUE); - gtk_action_group_add_action_with_accel(yw->action_group, GTK_ACTION(taction), NULL); - g_signal_connect(taction, "activate", G_CALLBACK(ToggleNBG0), NULL); - - taction = gtk_toggle_action_new("toggle_nbg1", _("NBG1"), NULL, NULL); - gtk_toggle_action_set_active(taction, TRUE); - gtk_action_group_add_action_with_accel(yw->action_group, GTK_ACTION(taction), NULL); - g_signal_connect(taction, "activate", G_CALLBACK(ToggleNBG1), NULL); - - taction = gtk_toggle_action_new("toggle_nbg2", _("NBG2"), NULL, NULL); - gtk_toggle_action_set_active(taction, TRUE); - gtk_action_group_add_action_with_accel(yw->action_group, GTK_ACTION(taction), NULL); - g_signal_connect(taction, "activate", G_CALLBACK(ToggleNBG2), NULL); - - taction = gtk_toggle_action_new("toggle_nbg3", _("NBG3"), NULL, NULL); - gtk_toggle_action_set_active(taction, TRUE); - gtk_action_group_add_action_with_accel(yw->action_group, GTK_ACTION(taction), NULL); - g_signal_connect(taction, "activate", G_CALLBACK(ToggleNBG3), NULL); - - taction = gtk_toggle_action_new("toggle_rbg0", _("RBG0"), NULL, NULL); - gtk_toggle_action_set_active(taction, TRUE); - gtk_action_group_add_action_with_accel(yw->action_group, GTK_ACTION(taction), NULL); - g_signal_connect(taction, "activate", G_CALLBACK(ToggleRBG0), NULL); -} - -GType yui_window_get_type (void) { - static GType yfe_type = 0; - - if (!yfe_type) - { - static const GTypeInfo yfe_info = - { - sizeof (YuiWindowClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) yui_window_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (YuiWindow), - 0, - (GInstanceInitFunc) yui_window_init, - NULL, - }; - - yfe_type = g_type_register_static(GTK_TYPE_WINDOW, "YuiWindow", &yfe_info, 0); - } - - return yfe_type; -} - -enum { YUI_WINDOW_RUNNING_SIGNAL, YUI_WINDOW_PAUSED_SIGNAL, LAST_SIGNAL }; - -static guint yui_window_signals[LAST_SIGNAL] = { 0, 0 }; - -static void yui_window_class_init (YuiWindowClass * klass) { - yui_window_signals[YUI_WINDOW_RUNNING_SIGNAL] = g_signal_new ("running", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET(YuiWindowClass, yui_window_running), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - yui_window_signals[YUI_WINDOW_PAUSED_SIGNAL] = g_signal_new ("paused", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET(YuiWindowClass, yui_window_paused), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); -} - -static void yui_set_accel_group(gpointer action, gpointer group) { - gtk_action_set_accel_group(action, group); -} - -static gboolean yui_window_log_delete(GtkWidget *widget, GdkEvent *event, YuiWindow *yw ) { - - yui_window_show_log( yw ); - - return TRUE; /* hide instead of killing */ -} - -extern gchar * inifile; - -static void yui_window_destroy(GtkWidget * window) { - gint x, y; - char buffer[512]; - - gtk_window_get_position(GTK_WINDOW(window), &x, &y); - - sprintf(buffer, "%d", x); - g_key_file_set_value(keyfile, "Gtk", "X", buffer); - sprintf(buffer, "%d", y); - g_key_file_set_value(keyfile, "Gtk", "Y", buffer); - - g_file_set_contents(inifile, g_key_file_to_data(keyfile, 0, 0), -1, 0); - gtk_main_quit(); -} - -static void yui_window_init (YuiWindow * yw) { - GtkAccelGroup * accel_group = gtk_accel_group_new(); - GtkWidget * scroll; - - yw->action_group = gtk_action_group_new("yui"); - yui_window_create_actions(yw); - gtk_action_set_sensitive(gtk_action_group_get_action(yw->action_group, "pause"), FALSE); - gtk_action_set_sensitive(gtk_action_group_get_action(yw->action_group, "reset"), FALSE); - { - GList * list = gtk_action_group_list_actions(yw->action_group); - g_list_foreach(list, yui_set_accel_group, accel_group); - } - gtk_window_add_accel_group(GTK_WINDOW(yw), accel_group); - - { - const gchar * const * data_dir; - gboolean pngfound = FALSE; - gchar * pngfile; - - data_dir = g_get_system_data_dirs(); - while (!pngfound && (*data_dir != NULL)) { - pngfile = g_build_filename(*data_dir, "pixmaps", "yabause.png", NULL); - if (g_file_test(pngfile, G_FILE_TEST_EXISTS)) { - gtk_window_set_icon(GTK_WINDOW(yw), gdk_pixbuf_new_from_file(pngfile, NULL)); - pngfound = TRUE; - } - data_dir++; - } - - if (!pngfound) { - gtk_window_set_icon(GTK_WINDOW(yw), gdk_pixbuf_new_from_file("yabause.png", NULL)); - } - } - - gtk_window_set_title (GTK_WINDOW(yw), "Yabause"); - - yw->box = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(yw), yw->box); - - yw->menu = create_menu(yw); - gtk_box_pack_start(GTK_BOX(yw->box), yw->menu, FALSE, FALSE, 0); - - yw->area = yui_gl_new(); - gtk_box_pack_start(GTK_BOX(yw->box), yw->area, TRUE, TRUE, 0); - gtk_widget_set_size_request(GTK_WIDGET(yw->area), 320, 224); - - g_signal_connect(G_OBJECT(yw), "delete-event", G_CALLBACK(yui_window_destroy), NULL); - g_signal_connect(G_OBJECT(yw), "key-press-event", G_CALLBACK(yui_window_keypress), yw); - g_signal_connect(G_OBJECT(yw), "key-release-event", G_CALLBACK(yui_window_keyrelease), yw); - - yw->logpopup = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title( GTK_WINDOW( yw->logpopup ), "Yabause Logs" ); - gtk_widget_set_size_request( yw->logpopup, 500, 300 ); - scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_container_add(GTK_CONTAINER(yw->logpopup), scroll); - g_signal_connect(G_OBJECT(yw->logpopup), "delete-event", G_CALLBACK(yui_window_log_delete), yw); - - yw->log = gtk_text_view_new(); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), yw->log); - - gtk_widget_show(yw->box); - gtk_widget_show_all(yw->menu); - gtk_widget_show(yw->area); - - yw->clean_handler = g_signal_connect(yw->area, "expose-event", G_CALLBACK(yui_window_keep_clean), yw); - yw->state = 0; -} - -GtkWidget * yui_window_new(YuiAction * act, GCallback ifunc, gpointer idata, - GSourceFunc rfunc, GCallback resetfunc) { - GtkWidget * widget; - YuiWindow * yw; - - widget = GTK_WIDGET(g_object_new(yui_window_get_type(), NULL)); - yw = YUI_WINDOW(widget); - - yw->actions = act; - yw->init_func = ifunc; - yw->init_data = idata; - yw->run_func = rfunc; - yw->reset_func = resetfunc; - - return widget; -} - -void yui_window_toggle_fullscreen(GtkWidget * w, YuiWindow * yui) { - GtkAction * action = gtk_action_group_get_action(yui->action_group, "fullscreen"); - static unsigned int beforefswidth = 1; - static unsigned int beforefsheight = 1; - - if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action))) { - beforefswidth = GTK_WIDGET(yui)->allocation.width; - beforefsheight = GTK_WIDGET(yui)->allocation.height; - gtk_widget_hide(yui->menu); - gtk_window_fullscreen(GTK_WINDOW(yui)); - } else { - gtk_window_unfullscreen(GTK_WINDOW(yui)); - gtk_widget_show(yui->menu); - gtk_window_resize(GTK_WINDOW(yui), beforefswidth, beforefsheight); - } -} - -void yui_window_toggle_frameskip(GtkWidget * w, YuiWindow * yui) { - GtkAction * action = gtk_action_group_get_action(yui->action_group, "frameskip"); - gboolean active = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)); - - if (active) - EnableAutoFrameSkip (); - else - DisableAutoFrameSkip (); -} - -static gboolean yui_window_keypress(GtkWidget *widget, GdkEventKey *event, gpointer user_data) { - PerKeyDown(event->keyval); - - return FALSE; -} - -static gboolean yui_window_keyrelease(GtkWidget *widget, GdkEventKey *event, gpointer user_data) { - PerKeyUp(event->keyval); - - return FALSE; -} - -void yui_window_update(YuiWindow * yui) { - - if (!(yui->state & YUI_IS_RUNNING)) yui_gl_draw_pause(YUI_GL(yui->area)); - else yui_gl_draw(YUI_GL(yui->area)); -} - -void yui_window_log(YuiWindow * yui, const char * message) { - GtkTextBuffer * buffer; - GtkTextIter iter; - - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(yui->log)); - gtk_text_buffer_get_start_iter(buffer, &iter); - gtk_text_buffer_insert(buffer, &iter, message, -1); -} - -void yui_window_show_log(YuiWindow * yui) { - static int i = 0; - if (i) - gtk_widget_hide(yui->logpopup); - else - gtk_widget_show_all(yui->logpopup); - i = !i; -} - -static void yui_window_keep_clean(GtkWidget * widget, GdkEventExpose * event, YuiWindow * yui) { -#ifdef HAVE_LIBGTKGLEXT - glClear(GL_COLOR_BUFFER_BIT); -#endif - yui_window_update(yui); -} - -void yui_window_start(YuiWindow * yui) { - if ((yui->state & YUI_IS_INIT) == 0) { - if (((int (*)(gpointer)) yui->init_func)(yui->init_data) == 0) { - yui->state |= YUI_IS_INIT; - gtk_action_set_sensitive(gtk_action_group_get_action(yui->action_group, "reset"), TRUE); - VIDCore->Resize(GTK_WIDGET(yui->area)->allocation.width, GTK_WIDGET(yui->area)->allocation.height, FALSE); - } - } -} - -void yui_window_run(YuiWindow * yui) { - yui_window_start(yui); - - if ((yui->state & YUI_IS_INIT) && ((yui->state & YUI_IS_RUNNING) == 0)) { - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - g_idle_add(yui->run_func, GINT_TO_POINTER(1)); - g_signal_emit(G_OBJECT(yui), yui_window_signals[YUI_WINDOW_RUNNING_SIGNAL], 0); - yui->state |= YUI_IS_RUNNING; - gtk_action_set_sensitive(gtk_action_group_get_action(yui->action_group, "run"), FALSE); - gtk_action_set_sensitive(gtk_action_group_get_action(yui->action_group, "pause"), TRUE); - } -} - -void yui_window_pause(YuiWindow * yui) { - if (yui->state & YUI_IS_RUNNING) { - yui_gl_dump_screen(YUI_GL(yui->area)); - ScspMuteAudio(SCSP_MUTE_SYSTEM); - g_idle_remove_by_data(GINT_TO_POINTER(1)); - g_signal_emit(G_OBJECT(yui), yui_window_signals[YUI_WINDOW_PAUSED_SIGNAL], 0); - yui->state &= ~YUI_IS_RUNNING; - gtk_action_set_sensitive(gtk_action_group_get_action(yui->action_group, "run"), TRUE); - gtk_action_set_sensitive(gtk_action_group_get_action(yui->action_group, "pause"), FALSE); - } -} - -void yui_window_reset(YuiWindow * yui) { - if (yui->state & YUI_IS_INIT) { - yui->reset_func(); - } -} - -void yui_window_invalidate(YuiWindow * yui) { - - /* Emit a pause signal while already in pause means refresh all debug views */ - - if ( !(yui->state & YUI_IS_RUNNING )) - g_signal_emit(G_OBJECT(yui), yui_window_signals[YUI_WINDOW_PAUSED_SIGNAL], 0); -} - -void yui_window_set_fullscreen(YuiWindow * yui, gboolean f) { - GtkAction * action = gtk_action_group_get_action(yui->action_group, "fullscreen"); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), f); -} - -void yui_window_set_frameskip(YuiWindow * yui, gboolean f) { - GtkAction * action = gtk_action_group_get_action(yui->action_group, "frameskip"); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), f); -} diff --git a/yabause/src/gtk/yuiwindow.h b/yabause/src/gtk/yuiwindow.h deleted file mode 100644 index c0aa0da364..0000000000 --- a/yabause/src/gtk/yuiwindow.h +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef YUI_WINDOW_H -#define YUI_WINDOW_H - -#include -#include -#include -#include - -G_BEGIN_DECLS - -#define YUI_WINDOW_TYPE (yui_window_get_type ()) -#define YUI_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), YUI_WINDOW_TYPE, YuiWindow)) -#define YUI_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), YUI_WINDOW_TYPE, YuiWindowClass)) -#define IS_YUI_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YUI_WINDOW_TYPE)) -#define IS_YUI_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YUI_WINDOW_TYPE)) - -typedef struct _YuiAction YuiAction; -typedef struct _YuiWindow YuiWindow; -typedef struct _YuiWindowClass YuiWindowClass; - -struct _YuiAction { - guint key; - const char * name; - void (*press)(void); - void (*release)(void); -}; - -#define YUI_IS_INIT 1 -#define YUI_IS_RUNNING 2 - -struct _YuiWindow { - GtkWindow hbox; - - GtkWidget * logpopup; - GtkWidget * box; - GtkWidget * menu; - GtkWidget * area; - GtkWidget * log; - - YuiAction * actions; - gulong clean_handler; - GCallback init_func; - gpointer init_data; - GSourceFunc run_func; - GCallback reset_func; - - guint state; - - GtkActionGroup * action_group; -}; - -struct _YuiWindowClass { - GtkWindowClass parent_class; - - void (* yui_window_running) (YuiWindow * yw); - void (* yui_window_paused) (YuiWindow * yw); -}; - -GType yui_window_get_type (void); -GtkWidget * yui_window_new (YuiAction * act, GCallback ifunc, gpointer idata, - GSourceFunc rfunc, GCallback resetfunc); -void yui_window_update (YuiWindow * yui); -void yui_window_log (YuiWindow * yui, const char * message); -void yui_window_show_log (YuiWindow * yui); -void yui_window_start (YuiWindow * yui); -void yui_window_run (YuiWindow * yui); -void yui_window_pause (YuiWindow * yui); -void yui_window_reset (YuiWindow * yui); -void yui_window_invalidate (YuiWindow * yui); -void yui_window_set_fullscreen(YuiWindow * yui, gboolean f); -void yui_window_set_frameskip(YuiWindow * yui, gboolean f); - -G_END_DECLS - -#endif /* YUI_WINDOW_H */ diff --git a/yabause/src/libyabause/libyabause.sln b/yabause/src/libyabause/libyabause.sln deleted file mode 100644 index db264d091b..0000000000 --- a/yabause/src/libyabause/libyabause.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libyabause", "libyabause.vcxproj", "{88FB48B5-EA33-4CA9-B585-C23992C061A8}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {88FB48B5-EA33-4CA9-B585-C23992C061A8}.Debug|Win32.ActiveCfg = Debug|Win32 - {88FB48B5-EA33-4CA9-B585-C23992C061A8}.Debug|Win32.Build.0 = Debug|Win32 - {88FB48B5-EA33-4CA9-B585-C23992C061A8}.Release|Win32.ActiveCfg = Release|Win32 - {88FB48B5-EA33-4CA9-B585-C23992C061A8}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/yabause/src/libyabause/libyabause.vcxproj b/yabause/src/libyabause/libyabause.vcxproj deleted file mode 100644 index 5891c41d48..0000000000 --- a/yabause/src/libyabause/libyabause.vcxproj +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {88FB48B5-EA33-4CA9-B585-C23992C061A8} - Win32Proj - libyabause - - - - DynamicLibrary - true - Unicode - - - DynamicLibrary - false - true - Unicode - - - - - - - - - - - - - true - - - false - - - - - - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBYABAUSE_EXPORTS;HAVE_C99_VARIADIC_MACROS;VERSION="LIB";C68K_NO_JUMP_TABLE;HAVE_LIBGL;%(PreprocessorDefinitions) - 4244;4996;4018;4146 - true - false - - - Windows - true - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;opengl32.lib;%(AdditionalDependencies) - - - copy /y $(TargetDir)$(TargetFileName) $(ProjectDir)..\..\..\output\dll\$(TargetFileName) - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBYABAUSE_EXPORTS;HAVE_C99_VARIADIC_MACROS;VERSION="LIB";C68K_NO_JUMP_TABLE;HAVE_LIBGL;%(PreprocessorDefinitions) - 4244;4996;4018;4146 - true - - - Windows - true - true - true - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;opengl32.lib;%(AdditionalDependencies) - - - copy /y $(TargetDir)$(TargetFileName) $(ProjectDir)..\..\..\output\dll\$(TargetFileName) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/yabause/src/libyabause/libyabause.vcxproj.filters b/yabause/src/libyabause/libyabause.vcxproj.filters deleted file mode 100644 index 3c30dacc79..0000000000 --- a/yabause/src/libyabause/libyabause.vcxproj.filters +++ /dev/null @@ -1,270 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/yabause/src/libyabause/yui.cpp b/yabause/src/libyabause/yui.cpp deleted file mode 100644 index df2b049671..0000000000 --- a/yabause/src/libyabause/yui.cpp +++ /dev/null @@ -1,610 +0,0 @@ -//bizhawk -#define HEADLESS - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include "../windows/glext.h" - -extern "C" { -#include "../cs0.h" -#include "../m68kcore.h" -#include "../peripheral.h" -#include "../vidsoft.h" -#include "../vdp2.h" -#include "../yui.h" -#include "../movie.h" -#include "../vidogl.h" -} - -void (*inputcallback)(void) = NULL; - -extern "C" __declspec(dllexport) void libyabause_setinputcallback(void (*cb)(void)) -{ - inputcallback = cb; -} - -void (*tracecallback)(const char* dis, const char* regs) = NULL; - -extern "C" __declspec(dllexport) void libyabause_settracecallback(void (*cb)(const char* dis, const char* regs)) -{ - tracecallback = cb; -} - -CDInterface FECD = -{ - 2, - "FECD", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -}; - -SoundInterface_struct FESND; - - -extern "C" SH2Interface_struct *SH2CoreList[] = { -&SH2Interpreter, -&SH2DebugInterpreter, -NULL -}; - -extern "C" PerInterface_struct *PERCoreList[] = { -&PERDummy, -NULL -}; - -extern "C" CDInterface *CDCoreList[] = { -&DummyCD, -&ISOCD, -&FECD, -NULL -}; - -extern "C" SoundInterface_struct *SNDCoreList[] = { -&SNDDummy, -&FESND, -NULL -}; - -extern "C" VideoInterface_struct *VIDCoreList[] = { -&VIDDummy, -&VIDOGL, -&VIDSoft, -NULL -}; - -extern "C" M68K_struct *M68KCoreList[] = { -&M68KDummy, -&M68KC68K, -#ifdef HAVE_Q68 -&M68KQ68, -#endif -NULL -}; - -/* If Yabause encounters any fatal errors, it sends the error text to this function */ -void YuiErrorMsg(const char *string) -{ - MessageBoxA(NULL, string, "Yabooze dun goofed", 0); -} - - -int red_size; -int green_size; -int blue_size; -int depth_size; - -PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; -PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; -PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; -PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; -PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; -PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; -PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; -PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; -PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; - -int LoadExtensions() -{ - glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)wglGetProcAddress("glBindRenderbufferEXT"); - if( glBindRenderbuffer == NULL ) return 0; - glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)wglGetProcAddress("glDeleteRenderbuffersEXT"); - if(glDeleteRenderbuffers==NULL) return 0; - glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)wglGetProcAddress("glGenRenderbuffersEXT"); - if( glGenRenderbuffers == NULL ) return 0; - glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)wglGetProcAddress("glRenderbufferStorageEXT"); - if( glRenderbufferStorage == NULL ) return 0; - glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebufferEXT"); - if( glBindFramebuffer==NULL) return 0; - glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress("glDeleteFramebuffersEXT"); - if( glDeleteFramebuffers==NULL) return 0; - glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffersEXT"); - if( glGenFramebuffers == NULL ) return 0; - glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress("glCheckFramebufferStatusEXT"); - if( glCheckFramebufferStatus == NULL ) return 0; - glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)wglGetProcAddress("glFramebufferRenderbufferEXT"); - if( glFramebufferRenderbuffer == NULL ) return 0; - - return 1; -} - -/* Sets attribute for the Video display. The values passed to this function - depends on what Video core is being used at the time. This may end up - being moved to the Video Core. */ -void YuiSetVideoAttribute(int type, int val) -{ - // only called in GL mode - switch (type) - { - case RED_SIZE: - red_size = val; - break; - case GREEN_SIZE: - green_size = val; - break; - case BLUE_SIZE: - blue_size = val; - break; - case DEPTH_SIZE: - depth_size = val; - break; - case DOUBLEBUFFER: - break; - } -} - - -GLuint fbuff = 0; -GLuint color = 0; -GLuint depth = 0; - -int glwidth, glheight; - -u8 *glbuff = NULL; - -/* Tells the yui it wants to setup the display to display the specified video - format. It's up to the yui to setup the actual display. This may end - up being moved to the Video Core. */ -int YuiSetVideoMode(int width, int height, int bpp, int fullscreen) -{ - // only called in GL mode - if (bpp != 32 || red_size != 8 || green_size != 8 || blue_size != 8 || depth_size != 24) - return -1; // failure - - if (fbuff) - glDeleteFramebuffers(1, &fbuff); - if (color) - glDeleteRenderbuffers(1, &color); - if (depth) - glDeleteRenderbuffers(1, &depth); - glGenFramebuffers(1, &fbuff); - glGenRenderbuffers(1, &color); - glGenRenderbuffers(1, &depth); - - glBindFramebuffer(GL_FRAMEBUFFER, fbuff); - - glBindRenderbuffer(GL_RENDERBUFFER, depth); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height); - glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth); - - glBindRenderbuffer(GL_RENDERBUFFER, color); - glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8, width, height); - glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color); - - //glBindRenderbuffer(GL_RENDERBUFFER, 0); - - if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - return -1; - - glwidth = width; - glheight = height; - - if (glbuff) - free(glbuff); - glbuff = (u8*) malloc(glwidth * glheight * 4); - - return 0; // success -} - -int usinggl = 0; -HWND glWND; -HDC glDC; -HGLRC glRC; - -void KillGLContext() -{ - wglMakeCurrent(NULL, NULL); - wglDeleteContext(glRC); - ReleaseDC(glWND, glDC); - DestroyWindow(glWND); -} - -int StartGLContext() -{ - PIXELFORMATDESCRIPTOR pfd; - memset(&pfd,0, sizeof(PIXELFORMATDESCRIPTOR)); - pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); - pfd.nVersion = 1; - pfd.dwFlags = PFD_SUPPORT_OPENGL; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = 24; - pfd.cAlphaBits = 8; - pfd.cDepthBits = 24; - pfd.cStencilBits = 8; - pfd.iLayerType = PFD_MAIN_PLANE; - - glWND = CreateWindow(L"EDIT", 0, 0, 0, 0, 512, 512, 0, 0, 0, 0); - if (!glWND) - return 0; - glDC = GetDC(glWND); - if (!glDC) - { - DestroyWindow(glWND); - return 0; - } - int PixelFormat = ChoosePixelFormat(glDC, &pfd); - if (!PixelFormat) - { - ReleaseDC(glWND, glDC); - DestroyWindow(glWND); - return 0; - } - if (!SetPixelFormat(glDC, PixelFormat, &pfd)) - { - ReleaseDC(glWND, glDC); - DestroyWindow(glWND); - return 0; - } - glRC = wglCreateContext(glDC); - if (!glRC) - { - ReleaseDC(glWND, glDC); - DestroyWindow(glWND); - return 0; - } - if (!wglMakeCurrent(glDC, glRC)) - { - wglDeleteContext(glRC); - ReleaseDC(glWND, glDC); - DestroyWindow(glWND); - return 0; - } - return 1; -} - - - -s16 *sndbuff = NULL; -int sndbuffpos = 0; -u32 *vidbuff = NULL; - -PerPad_struct *ctrl1; -PerPad_struct *ctrl2; - -extern "C" int vdp2height; -extern "C" int vdp2width; -extern "C" GLuint FboTexture; - -/* Tells the yui to exchange front and back video buffers. This may end - up being moved to the Video Core. */ -void YuiSwapBuffers(void) -{ - if (vidbuff) - { - if (!usinggl) - { - u8 *src = (u8*)dispbuffer; - u8 *dst = (u8*)vidbuff; - - for (int j = 0; j < vdp2height; j++) - for (int i = 0; i < vdp2width; i++) - { - dst[0] = src[2]; - dst[1] = src[1]; - dst[2] = src[0]; - dst[3] = 0xff; - src += 4; - dst += 4; - } - } - else - { - #ifdef CAN_RETURN_TEXTURE_IDS - //simply write the FboTexture into the videobuffer for later magic detection in frontend - memcpy(vidbuff,&FboTexture,4); - #else - glReadPixels(0, 0, glwidth, glheight, GL_BGRA, GL_UNSIGNED_BYTE, glbuff); - - u32 *src = (u32*)glbuff; - u32 *dst = (u32*)vidbuff; - - dst += glwidth * (glheight - 1); - - for (int j = 0; j < glheight; j++) - { - memcpy(dst, src, glwidth * 4); - src += glwidth; - dst -= glwidth; - } - #endif - } - } -} - -static void FESNDUpdateAudio(UNUSED u32 *leftchanbuffer, UNUSED u32 *rightchanbuffer, UNUSED u32 num_samples) -{ - /* - static s16 stereodata16[44100 / 50]; - ScspConvert32uto16s((s32 *)leftchanbuffer, (s32 *)rightchanbuffer, (s16 *)stereodata16, num_samples); - */ -} - -static u32 FESNDGetAudioSpace(void) -{ - return 44100; -} -// some garbage from the sound system, we'll have to fix this all up -extern "C" void DRV_AviSoundUpdate(void* soundData, int soundLen) -{ - // soundLen should be number of sample pairs (4 byte units) - if (sndbuff) - { - s16 *src = (s16*)soundData; - s16 *dst = sndbuff; - dst += sndbuffpos * 2; - memcpy (dst, src, soundLen * 4); - sndbuffpos += soundLen; - } -} - -// must hold at least 704x512 pixels -extern "C" __declspec(dllexport) void libyabause_setvidbuff(u32 *buff) -{ - vidbuff = buff; -} - -extern "C" __declspec(dllexport) void libyabause_setsndbuff(s16 *buff) -{ - sndbuff = buff; -} - -extern "C" __declspec(dllexport) void libyabause_softreset() -{ - YabauseResetButton(); -} - -extern "C" __declspec(dllexport) void libyabause_hardreset() -{ - YabauseReset(); -} - -extern "C" __declspec(dllexport) int libyabause_loadstate(const char *fn) -{ - return !YabLoadState(fn); -} - -extern "C" __declspec(dllexport) int libyabause_savestate(const char *fn) -{ - return !YabSaveState(fn); -} - -extern "C" __declspec(dllexport) int libyabause_savesaveram(const char *fn) -{ - return !T123Save(BupRam, 0x10000, 1, fn); -} - -extern "C" __declspec(dllexport) int libyabause_loadsaveram(const char *fn) -{ - return !T123Load(BupRam, 0x10000, 1, fn); -} - -extern "C" __declspec(dllexport) int libyabause_saveramodified() -{ - return BupRamWritten; -} - -extern "C" __declspec(dllexport) void libyabause_clearsaveram() -{ - FormatBackupRam(BupRam, 0x10000); -} - -typedef struct -{ - void *data; - const char *name; - int length; -} memoryarea; - -memoryarea normmemareas[] = -{ - {NULL, "Boot Rom", 512 * 1024}, - {NULL, "Backup Ram", 64 * 1024}, - {NULL, "Work Ram Low", 1024 * 1024}, - {NULL, "Sound Ram", 512 * 1024}, - {NULL, "VDP1 Ram", 512 * 1024}, - {NULL, "VDP1 Framebuffer", 512 * 1024}, - {NULL, "VDP2 Ram", 512 * 1024}, - {NULL, "VDP2 CRam", 4 * 1024}, - {NULL, "Work Ram High", 1024 * 1024}, - {NULL, NULL, 0} -}; - -extern "C" __declspec(dllexport) memoryarea *libyabause_getmemoryareas() -{ - normmemareas[0].data = BiosRom; - normmemareas[1].data = BupRam; - normmemareas[2].data = LowWram; - normmemareas[3].data = SoundRam; - normmemareas[4].data = Vdp1Ram; - normmemareas[5].data = Vdp1FrameBuffer; - normmemareas[6].data = Vdp2Ram; - normmemareas[7].data = Vdp2ColorRam; - normmemareas[8].data = HighWram; - return &normmemareas[0]; -} - -extern "C" __declspec(dllexport) int libyabause_frameadvance(int *w, int *h, int *nsamp) -{ - LagFrameFlag = 1; - sndbuffpos = 0; - YabauseEmulate(); - if (usinggl) - { - *w = glwidth; - *h = glheight; - } - else - { - *w = vdp2width; - *h = vdp2height; - } - *nsamp = sndbuffpos; - return LagFrameFlag; -} - -extern "C" __declspec(dllexport) void libyabause_deinit() -{ - PerPortReset(); - YabauseDeInit(); - if (usinggl) - { - KillGLContext(); - usinggl = 0; - } - if (glbuff) - { - free(glbuff); - glbuff = NULL; - } -} - -extern "C" __declspec(dllexport) void libyabause_setpads(u8 p11, u8 p12, u8 p21, u8 p22) -{ - ctrl1->padbits[0] = p11; - ctrl1->padbits[1] = p12; - ctrl2->padbits[0] = p21; - ctrl2->padbits[1] = p22; -} - -int glnativefactor = 0; - -extern "C" __declspec(dllexport) void libyabause_glresize(int w, int h) -{ - if (usinggl && !glnativefactor) - VIDCore->Resize(w, h, 0); -} - -extern "C" __declspec(dllexport) void libyabause_glsetnativefactor(int n) -{ - if (!usinggl) - return; - if (n > 4) - n = 4; - if (n < 0) - n = 0; - glnativefactor = n; - if (n) - VIDCore->Resize(vdp2width_gl * n, vdp2height_gl * n, 0); -} - -void (*vdp2hookfcn)(u16 v) = NULL; - -void vdp2newhook(u16 v) -{ - vdp2hookfcn(v); - if (glnativefactor) - { - if (glwidth != vdp2width_gl * glnativefactor || glheight != vdp2height_gl * glnativefactor) - VIDCore->Resize(vdp2width_gl * glnativefactor, vdp2height_gl * glnativefactor, 0); - } -} - -extern "C" __declspec(dllexport) int libyabause_init -( - CDInterface *_CD, - const char *biosfn, - int usegl, - int carttype, - int quickload, - int clocksync, - int clockbase -) -{ - usinggl = usegl; - - if (usegl) - { - //headless cores should not create GL contexts, but use the one from the invoking frontend - #ifndef HEADLESS - if(!StartGLContext()) - return 0; - #endif - if(!LoadExtensions()) - return 0; - } - - FECD.DeInit = _CD->DeInit; - FECD.GetStatus = _CD->GetStatus; - FECD.Init = _CD->Init; - FECD.ReadAheadFAD = _CD->ReadAheadFAD; - FECD.ReadSectorFAD = _CD->ReadSectorFAD; - FECD.ReadTOC = _CD->ReadTOC; - - // only overwrite a few SNDDummy functions - memcpy(&FESND, &SNDDummy, sizeof(FESND)); - FESND.id = 2; - FESND.Name = "FESND"; - FESND.GetAudioSpace = FESNDGetAudioSpace; - FESND.UpdateAudio = FESNDUpdateAudio; - - yabauseinit_struct yinit; - memset(&yinit, 0, sizeof(yabauseinit_struct)); - yinit.percoretype = PERCORE_DUMMY; - yinit.sh2coretype = SH2CORE_INTERPRETER; - if (usegl) - yinit.vidcoretype = VIDCORE_OGL; - else - yinit.vidcoretype = VIDCORE_SOFT; - yinit.sndcoretype = 2; //SNDCORE_DUMMY; - yinit.cdcoretype = 2; // CDCORE_ISO; //CDCORE_DUMMY; - yinit.m68kcoretype = M68KCORE_C68K; - yinit.cartpath = CART_NONE; - yinit.regionid = REGION_AUTODETECT; - yinit.biospath = biosfn; - yinit.cdpath = "Saturnus"; //NULL; - yinit.buppath = NULL; - yinit.mpegpath = NULL; - yinit.carttype = carttype; - yinit.netlinksetting = NULL; - yinit.videoformattype = VIDEOFORMATTYPE_NTSC; - yabsys.usequickload = quickload; - yinit.usethreads = 0; - yinit.frameskip = 0; - yinit.clocksync = clocksync; - yinit.basetime = clockbase; // same format as return from time(); 0 to use time() - - if (usegl && !vdp2hookfcn) - { - // hook vdp2setresolution - vdp2hookfcn = VIDOGL.Vdp2SetResolution; - VIDOGL.Vdp2SetResolution = vdp2newhook; - } - - if (YabauseInit(&yinit) != 0) - return 0; - - SpeedThrottleDisable(); - DisableAutoFrameSkip(); - ScspSetFrameAccurate(1); - - OSDChangeCore(OSDCORE_DUMMY); - - ctrl1 = PerPadAdd(&PORTDATA1); - ctrl2 = PerPadAdd(&PORTDATA2); - - return 1; -} diff --git a/yabause/src/logo.bmp b/yabause/src/logo.bmp deleted file mode 100644 index 5fc521042a..0000000000 Binary files a/yabause/src/logo.bmp and /dev/null differ diff --git a/yabause/src/logo.png b/yabause/src/logo.png deleted file mode 100644 index bfa6208a0c..0000000000 Binary files a/yabause/src/logo.png and /dev/null differ diff --git a/yabause/src/logo.svg b/yabause/src/logo.svg deleted file mode 100644 index 68062d74e2..0000000000 --- a/yabause/src/logo.svg +++ /dev/null @@ -1,201 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - Yabause Logo - - - - - - - - - - - - - - - - - - - diff --git a/yabause/src/m68kc68k.c b/yabause/src/m68kc68k.c deleted file mode 100644 index 5ab05390f5..0000000000 --- a/yabause/src/m68kc68k.c +++ /dev/null @@ -1,190 +0,0 @@ -/* Copyright 2007 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "m68kc68k.h" -#include "c68k/c68k.h" -#include "memory.h" -#include "yabause.h" - -/** - * PROFILE_68K: Perform simple profiling of the 68000 emulation, reporting - * the average time per 68000 clock cycle. (Realtime execution would be - * around 88.5 nsec/cycle.) - */ -// #define PROFILE_68K - - -static u8 *SoundDummy=NULL; - -static int M68KC68KInit(void) { - int i; - - // Setup a 64k buffer filled with invalid 68k instructions to serve - // as a default map - if ((SoundDummy = T2MemoryInit(0x10000)) != NULL) - memset(SoundDummy, 0xFF, 0x10000); - - C68k_Init(&C68K, NULL); // not sure if I need the int callback or not - - for (i = 0x10; i < 0x100; i++) - M68K->SetFetch(i << 16, (i << 16) + 0xFFFF, (pointer)SoundDummy); - - return 0; -} - -static void M68KC68KDeInit(void) { - if (SoundDummy) - T2MemoryDeInit(SoundDummy); - SoundDummy = NULL; -} - -static void M68KC68KReset(void) { - C68k_Reset(&C68K); -} - -static s32 FASTCALL M68KC68KExec(s32 cycle) { -#ifdef PROFILE_68K - static u32 tot_cycles = 0, tot_usec = 0, tot_ticks = 0, last_report = 0; - u32 start, end; - start = (u32) YabauseGetTicks(); - int retval = C68k_Exec(&C68K, cycle); - end = (u32) YabauseGetTicks(); - tot_cycles += cycle; - tot_ticks += end - start; - if (tot_cycles/1000000 > last_report) { - tot_usec += (u64)tot_ticks * 1000000 / yabsys.tickfreq; - tot_ticks = 0; - fprintf(stderr, "%ld cycles in %.3f sec = %.3f nsec/cycle\n", - (long)tot_cycles, (double)tot_usec/1000000, - ((double)tot_usec / (double)tot_cycles) * 1000); - last_report = tot_cycles/1000000; - } - return retval; -#else - return C68k_Exec(&C68K, cycle); -#endif -} - -static void M68KC68KSync(void) { -} - -static u32 M68KC68KGetDReg(u32 num) { - return C68k_Get_DReg(&C68K, num); -} - -static u32 M68KC68KGetAReg(u32 num) { - return C68k_Get_AReg(&C68K, num); -} - -static u32 M68KC68KGetPC(void) { - return C68k_Get_PC(&C68K); -} - -static u32 M68KC68KGetSR(void) { - return C68k_Get_SR(&C68K); -} - -static u32 M68KC68KGetUSP(void) { - return C68k_Get_USP(&C68K); -} - -static u32 M68KC68KGetMSP(void) { - return C68k_Get_MSP(&C68K); -} - -static void M68KC68KSetDReg(u32 num, u32 val) { - C68k_Set_DReg(&C68K, num, val); -} - -static void M68KC68KSetAReg(u32 num, u32 val) { - C68k_Set_AReg(&C68K, num, val); -} - -static void M68KC68KSetPC(u32 val) { - C68k_Set_PC(&C68K, val); -} - -static void M68KC68KSetSR(u32 val) { - C68k_Set_SR(&C68K, val); -} - -static void M68KC68KSetUSP(u32 val) { - C68k_Set_USP(&C68K, val); -} - -static void M68KC68KSetMSP(u32 val) { - C68k_Set_MSP(&C68K, val); -} - -static void M68KC68KSetFetch(u32 low_adr, u32 high_adr, pointer fetch_adr) { - C68k_Set_Fetch(&C68K, low_adr, high_adr, fetch_adr); -} - -static void FASTCALL M68KC68KSetIRQ(s32 level) { - C68k_Set_IRQ(&C68K, level); -} - -static void FASTCALL M68KC68KWriteNotify(u32 address, u32 size) { - /* nothing to do */ -} - -static void M68KC68KSetReadB(M68K_READ *Func) { - C68k_Set_ReadB(&C68K, Func); -} - -static void M68KC68KSetReadW(M68K_READ *Func) { - C68k_Set_ReadW(&C68K, Func); -} - -static void M68KC68KSetWriteB(M68K_WRITE *Func) { - C68k_Set_WriteB(&C68K, Func); -} - -static void M68KC68KSetWriteW(M68K_WRITE *Func) { - C68k_Set_WriteW(&C68K, Func); -} - -M68K_struct M68KC68K = { - 1, - "C68k Interface", - M68KC68KInit, - M68KC68KDeInit, - M68KC68KReset, - M68KC68KExec, - M68KC68KSync, - M68KC68KGetDReg, - M68KC68KGetAReg, - M68KC68KGetPC, - M68KC68KGetSR, - M68KC68KGetUSP, - M68KC68KGetMSP, - M68KC68KSetDReg, - M68KC68KSetAReg, - M68KC68KSetPC, - M68KC68KSetSR, - M68KC68KSetUSP, - M68KC68KSetMSP, - M68KC68KSetFetch, - M68KC68KSetIRQ, - M68KC68KWriteNotify, - M68KC68KSetReadB, - M68KC68KSetReadW, - M68KC68KSetWriteB, - M68KC68KSetWriteW -}; diff --git a/yabause/src/m68kc68k.h b/yabause/src/m68kc68k.h deleted file mode 100644 index a179715918..0000000000 --- a/yabause/src/m68kc68k.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2007 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef M68KC68K_H -#define M68KC68K_H - -#include "m68kcore.h" - -extern M68K_struct M68KC68K; - -#endif diff --git a/yabause/src/m68kcore.c b/yabause/src/m68kcore.c deleted file mode 100644 index 614c8e3562..0000000000 --- a/yabause/src/m68kcore.c +++ /dev/null @@ -1,167 +0,0 @@ -/* Copyright 2007 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "m68kcore.h" -#include "m68kc68k.h" -#include "memory.h" - -extern u8 * SoundRam; - -M68K_struct * M68K = NULL; - -extern M68K_struct * M68KCoreList[]; - -int M68KInit(int coreid) { - int i; - - M68K = &M68KDummy; - - // Go through core list and find the id - for (i = 0; M68KCoreList[i] != NULL; i++) - { - if (M68KCoreList[i]->id == coreid) - { - // Set to current core - M68K = M68KCoreList[i]; - break; - } - } - - return 0; -} - -static int M68KDummyInit(void) { - return 0; -} - -static void M68KDummyDeInit(void) { -} - -static void M68KDummyReset(void) { -} - -static s32 FASTCALL M68KDummyExec(UNUSED s32 cycle) { - T2WriteWord(SoundRam, 0x700, 0); - T2WriteWord(SoundRam, 0x710, 0); - T2WriteWord(SoundRam, 0x720, 0); - T2WriteWord(SoundRam, 0x730, 0); - T2WriteWord(SoundRam, 0x740, 0); - T2WriteWord(SoundRam, 0x750, 0); - T2WriteWord(SoundRam, 0x760, 0); - T2WriteWord(SoundRam, 0x770, 0); - - T2WriteWord(SoundRam, 0x790, 0); - T2WriteWord(SoundRam, 0x792, 0); - return 0; -} - -static void M68KDummySync(void) { -} - -static u32 M68KDummyGetDReg(UNUSED u32 num) { - return 0; -} - -static u32 M68KDummyGetAReg(UNUSED u32 num) { - return 0; -} - -static u32 M68KDummyGetPC(void) { - return 0; -} - -static u32 M68KDummyGetSR(void) { - return 0; -} - -static u32 M68KDummyGetUSP(void) { - return 0; -} - -static u32 M68KDummyGetMSP(void) { - return 0; -} - -static void M68KDummySetDReg(UNUSED u32 num, UNUSED u32 val) { -} - -static void M68KDummySetAReg(UNUSED u32 num, UNUSED u32 val) { -} - -static void M68KDummySetPC(UNUSED u32 val) { -} - -static void M68KDummySetSR(UNUSED u32 val) { -} - -static void M68KDummySetUSP(UNUSED u32 val) { -} - -static void M68KDummySetMSP(UNUSED u32 val) { -} - -static void M68KDummySetFetch(UNUSED u32 low_adr, UNUSED u32 high_adr, UNUSED pointer fetch_adr) { -} - -static void FASTCALL M68KDummySetIRQ(UNUSED s32 level) { -} - -static void FASTCALL M68KDummyWriteNotify(u32 address, u32 size) { -} - -static void M68KDummySetReadB(UNUSED M68K_READ *Func) { -} - -static void M68KDummySetReadW(UNUSED M68K_READ *Func) { -} - -static void M68KDummySetWriteB(UNUSED M68K_WRITE *Func) { -} - -static void M68KDummySetWriteW(UNUSED M68K_WRITE *Func) { -} - -M68K_struct M68KDummy = { - 0, - "Dummy 68k Interface", - M68KDummyInit, - M68KDummyDeInit, - M68KDummyReset, - M68KDummyExec, - M68KDummySync, - M68KDummyGetDReg, - M68KDummyGetAReg, - M68KDummyGetPC, - M68KDummyGetSR, - M68KDummyGetUSP, - M68KDummyGetMSP, - M68KDummySetDReg, - M68KDummySetAReg, - M68KDummySetPC, - M68KDummySetSR, - M68KDummySetUSP, - M68KDummySetMSP, - M68KDummySetFetch, - M68KDummySetIRQ, - M68KDummyWriteNotify, - M68KDummySetReadB, - M68KDummySetReadW, - M68KDummySetWriteB, - M68KDummySetWriteW -}; diff --git a/yabause/src/m68kcore.h b/yabause/src/m68kcore.h deleted file mode 100644 index e20f88ab3c..0000000000 --- a/yabause/src/m68kcore.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright 2007 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef M68KCORE_H -#define M68KCORE_H - -#include "core.h" - -#define M68KCORE_DEFAULT -1 -#define M68KCORE_DUMMY 0 -#define M68KCORE_C68K 1 -#define M68KCORE_Q68 2 - -typedef u32 FASTCALL M68K_READ(const u32 adr); -typedef void FASTCALL M68K_WRITE(const u32 adr, u32 data); - -typedef struct { - int id; - const char *Name; - - int (*Init)(void); - void (*DeInit)(void); - void (*Reset)(void); - - s32 FASTCALL (*Exec)(s32 cycle); - void (*Sync)(void); - - u32 (*GetDReg)(u32 num); - u32 (*GetAReg)(u32 num); - u32 (*GetPC)(void); - u32 (*GetSR)(void); - u32 (*GetUSP)(void); - u32 (*GetMSP)(void); - - void (*SetDReg)(u32 num, u32 val); - void (*SetAReg)(u32 num, u32 val); - void (*SetPC)(u32 val); - void (*SetSR)(u32 val); - void (*SetUSP)(u32 val); - void (*SetMSP)(u32 val); - - void (*SetFetch)(u32 low_adr, u32 high_adr, pointer fetch_adr); - void FASTCALL (*SetIRQ)(s32 level); - void FASTCALL (*WriteNotify)(u32 address, u32 size); - - void (*SetReadB)(M68K_READ *Func); - void (*SetReadW)(M68K_READ *Func); - void (*SetWriteB)(M68K_WRITE *Func); - void (*SetWriteW)(M68K_WRITE *Func); -} M68K_struct; - -extern M68K_struct * M68K; - -int M68KInit(int coreid); - -extern M68K_struct M68KDummy; -extern M68K_struct M68KC68K; -extern M68K_struct M68KQ68; - -#endif diff --git a/yabause/src/m68kd.c b/yabause/src/m68kd.c deleted file mode 100644 index 735c2315a6..0000000000 --- a/yabause/src/m68kd.c +++ /dev/null @@ -1,1327 +0,0 @@ -/* Copyright 2005 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "core.h" -#include "m68kd.h" -#include "scsp.h" // for c68k_word_read() - -typedef struct -{ - u16 mask; - u16 inst; - const char *name; - int (*disasm)(u32, u16, char *); -} m68kdis_struct; - -////////////////////////////////////////////////////////////////////////////// - -static int setsizestr(u16 size, char *outstring) -{ - switch (size & 0x3) - { - case 0x1: - return sprintf(outstring, ".b "); - case 0x3: - return sprintf(outstring, ".w "); - case 0x2: - return sprintf(outstring, ".l "); - default: - return sprintf(outstring, " "); - } -} - -////////////////////////////////////////////////////////////////////////////// - -static int setsizestr2(u16 size, char *outstring) -{ - switch (size & 0x3) - { - case 0x0: - return sprintf(outstring, ".b "); - case 0x1: - return sprintf(outstring, ".w "); - case 0x2: - return sprintf(outstring, ".l "); - default: - return sprintf(outstring, " "); - } -} - -////////////////////////////////////////////////////////////////////////////// - -static int setimmstr(u32 addr, u16 size, int *addsize, char *outstring) -{ - switch (size & 0x3) - { - case 0x0: - *addsize+=2; - return sprintf(outstring, "#0x%X", (unsigned int)(c68k_word_read(addr) & 0xFF)); - case 0x1: - *addsize+=2; - return sprintf(outstring, "#0x%X", (unsigned int)c68k_word_read(addr)); - case 0x2: - *addsize+=4; - return sprintf(outstring, "#0x%X", (unsigned int)((c68k_word_read(addr) << 16) | c68k_word_read(addr+2))); - default: - return 0; - } -} - -////////////////////////////////////////////////////////////////////////////// - -static int seteafieldstr(u32 addr, u16 modereg, int *addsize, char *outstring) -{ - switch ((modereg >> 3) & 0x7) - { - case 0x0: - // Dn - return sprintf(outstring, "d%d", modereg & 0x7); - case 0x1: - // An - return sprintf(outstring, "a%d", modereg & 0x7); - case 0x2: - // (An) - return sprintf(outstring, "(a%d)", modereg & 0x7); - case 0x3: - // (An)+ - return sprintf(outstring, "(a%d)+", modereg & 0x7); - case 0x4: - // -(An) - return sprintf(outstring, "-(a%d)", modereg & 0x7); - case 0x5: - // (d16, An) - *addsize += 2; - return sprintf(outstring, "0x%X(a%d)", (unsigned int)c68k_word_read(addr), modereg & 0x7); - case 0x6: - // (d8,An,Xn) - // fix me - *addsize += 2; - return sprintf(outstring, "0x%X(a%d, Xn)", (unsigned int)(c68k_word_read(addr) & 0xFF), modereg & 0x7); - case 0x7: - switch (modereg & 0x7) - { - case 0x0: - // (xxx).W - *addsize += 2; // fix me? - return sprintf(outstring, "(0x%X).w", (unsigned int)c68k_word_read(addr)); - case 0x1: - // (xxx).L - *addsize += 4; // fix me? - return sprintf(outstring, "(0x%X).l", (unsigned int)((c68k_word_read(addr) << 16) | c68k_word_read(addr+2))); - case 0x4: - // # - *addsize += 2; // fix me? - return sprintf(outstring, "#0x%X", (unsigned int)c68k_word_read(addr)); - case 0x2: - // (d16,PC) - *addsize += 2; - return sprintf(outstring, "0x%X(PC)", (unsigned int)c68k_word_read(addr)); - case 0x3: - // (d8,PC,Xn) - // fix me - return 0; - default: break; - } - default: break; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int setcondstr(u16 cond, char *outstring) -{ - switch (cond & 0xF) - { - case 0x0: - // True - return sprintf(outstring, "t "); - case 0x1: - // False - return sprintf(outstring, "f "); - case 0x2: - // High - return sprintf(outstring, "hi"); - case 0x3: - // Low or Same - return sprintf(outstring, "ls"); - case 0x4: - // Carry Clear - return sprintf(outstring, "cc"); - case 0x5: - // Carry Set - return sprintf(outstring, "cs"); - case 0x6: - // Not Equal - return sprintf(outstring, "ne"); - case 0x7: - // Equal - return sprintf(outstring, "eq"); - case 0x8: - // Overflow Clear - return sprintf(outstring, "vc"); - case 0x9: - // Overflow Set - return sprintf(outstring, "vs"); - case 0xA: - // Plus - return sprintf(outstring, "pl"); - case 0xB: - // Minus - return sprintf(outstring, "mi"); - case 0xC: - // Greater or Equal - return sprintf(outstring, "ge"); - case 0xD: - // Less Than - return sprintf(outstring, "lt"); - case 0xE: - // Greater Than - return sprintf(outstring, "gt"); - case 0xF: - // Less or Equal - return sprintf(outstring, "le"); - default: break; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int setbranchdispstr(u32 addr, u16 op, int *addsize, char *outstring) -{ - if ((op & 0xFF) == 0xFF) - { - // 32-bit displacement - *addsize += 4; - return sprintf(outstring, ".l %X", (unsigned int)(addr + ((c68k_word_read(addr) << 16) | c68k_word_read(addr+2)))); - } - else if ((op & 0xFF) == 0x00) - { - // 16-bit displacement - *addsize += 2; - return sprintf(outstring, ".w %X", (unsigned int)((s32)addr + (s32)(s16)c68k_word_read(addr))); - } - - // 8-bit displacement - return sprintf(outstring, ".s %X", (unsigned int)((s32)addr + (s32)(s8)(op & 0xFF))); -} - -////////////////////////////////////////////////////////////////////////////// - -static int disabcd(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "abcd"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disadd(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "add"); - outstring += setsizestr2(op >> 6, outstring); - outstring += sprintf(outstring, " "); - - if (op & 0x100) - { - // Dn, - outstring += sprintf(outstring, "d%d, ", (op >> 9) & 7); - seteafieldstr(addr+size, op, &size, outstring); - } - else - { - // , Dn - outstring += seteafieldstr(addr+size, op, &size, outstring); - sprintf(outstring, ", d%d", (op >> 9) & 7); - } - - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disadda(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "adda"); - if ((op & 0x1C0) == 0xC0) - outstring += sprintf(outstring, ".w "); - else - outstring += sprintf(outstring, ".l "); - outstring += seteafieldstr(addr+size, op, &size, outstring); - outstring += sprintf(outstring, ", a%d", (op >> 9) & 0x7); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disaddi(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "addi"); - outstring += setsizestr2(op >> 6, outstring); - outstring += setimmstr(addr+size, op >> 6, &size, outstring); - outstring += sprintf(outstring, ", "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disaddq(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "addq"); - outstring += setsizestr2(op >> 6, outstring); - outstring += sprintf(outstring, " "); - outstring += sprintf(outstring, "#%d, ", (op >> 9) & 7); // fix me - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disaddx(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "addx"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disand(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "and"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disandi(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "andi"); - outstring += setsizestr2(op >> 6, outstring); - outstring += sprintf(outstring, " "); - outstring += setimmstr(addr+size, op >> 6, &size, outstring); - outstring += sprintf(outstring, ", "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disanditoccr(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "andi to CCR"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disasl(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "asl"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disasr(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "asr"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbcc(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "b"); - outstring += setcondstr(op >> 8, outstring); - setbranchdispstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbkpt(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "bkpt"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbra(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "bra"); - setbranchdispstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbchg(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "bchg"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbclrd(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "bclr"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbclrs(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "bclr "); - outstring += setimmstr(addr+size, 0, &size, outstring); - outstring += sprintf(outstring, ", "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbsetd(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "bset"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbsets(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "bset "); - outstring += setimmstr(addr+size, 0, &size, outstring); - outstring += sprintf(outstring, ", "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbtstd(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "btst"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbtsts(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "btst "); - outstring += setimmstr(addr+size, 0, &size, outstring); - outstring += sprintf(outstring, ", "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disbsr(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "bsr"); - setbranchdispstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dischk(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "chk"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disclr(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "clr"); - outstring += setsizestr2((op >> 6), outstring); - outstring += sprintf(outstring, " "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disdbcc(u32 addr, u16 op, char *outstring) -{ - outstring += sprintf(outstring, "db"); - outstring += setcondstr(op >> 8, outstring); - outstring += sprintf(outstring, " "); - sprintf(outstring, " d%d, %X", op & 0x7, (unsigned int)((s32)addr+2+(s32)(s16)c68k_word_read(addr+2))); - return 4; -} - -////////////////////////////////////////////////////////////////////////////// - -static int discmpb(u32 addr, u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "cmp.b "); - outstring += seteafieldstr(addr+size, op, &size, outstring); - outstring += sprintf(outstring, ", d%d", (op >> 9) & 0x7); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int discmpw(u32 addr, u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "cmp.w "); - outstring += seteafieldstr(addr+size, op, &size, outstring); - outstring += sprintf(outstring, ", d%d", (op >> 9) & 0x7); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int discmpl(u32 addr, u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "cmp.l "); - outstring += seteafieldstr(addr+size, op, &size, outstring); - outstring += sprintf(outstring, ", d%d", (op >> 9) & 0x7); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int discmpaw(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "cmpa.w"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int discmpal(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "cmpa.l"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int discmpi(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "cmpi"); - outstring += setsizestr2((op >> 6), outstring); - outstring += sprintf(outstring, " "); - outstring += setimmstr(addr+size, op >> 6, &size, outstring); - outstring += sprintf(outstring, ", "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disdivs(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "divs.w"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disdivu(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "divu.w"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int discmpm(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "cmpm"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int diseorb(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "eor.b"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int diseorw(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "eor.w"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int diseorl(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "eor.l"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int diseori(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "eori"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int diseoritoccr(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "eori to ccr"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disexg(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "exg"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disext(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "ext"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disillegal(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - sprintf(outstring, "illegal"); - return 2; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disjmp(u32 addr, u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "jmp "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disjsr(u32 addr, u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "jsr "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dislea(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "lea "); - outstring += seteafieldstr(addr+size, op, &size, outstring); - outstring += sprintf(outstring, ", a%d", (op >> 9) & 0x7); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dislink(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "link"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dislsl(UNUSED u32 addr, u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "lsl"); - outstring += setsizestr2(op >> 6, outstring); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dislsr(UNUSED u32 addr, u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "lsr"); - outstring += setsizestr2(op >> 6, outstring); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismove(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "move"); - outstring += setsizestr((op >> 12), outstring); - outstring += sprintf(outstring, " "); - outstring += seteafieldstr(addr+size, op, &size, outstring); - outstring += sprintf(outstring, ", "); - seteafieldstr(addr+size, ((op >> 3) & 0x38) | ((op >> 9) & 0x7), &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismovea(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "movea"); - outstring += setsizestr((op >> 12), outstring); - outstring += seteafieldstr(addr+size, op, &size, outstring); - outstring += sprintf(outstring, ", a%d", (op >> 9) & 0x7); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismovetoccr(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "move to ccr"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismovefromsr(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "move from sr"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismovetosr(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "move "); - outstring += seteafieldstr(addr+size, op, &size, outstring); - sprintf(outstring, ", sr"); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismovem(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - outstring += sprintf(outstring, "movem"); - // fix me - return 4; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismovep(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "movep"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismoveq(UNUSED u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "moveq #0x%X, d%d", op & 0xFF, (op >> 9) & 0x7); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismuls(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "muls"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dismulu(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "mulu"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disnbcd(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "nbcd"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disneg(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "neg"); - outstring += setsizestr2((op >> 6), outstring); - outstring += sprintf(outstring, " "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disnegx(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "negx"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disnop(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - sprintf(outstring, "nop"); - return 2; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disnot(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "not"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disor(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "ori to CCR"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disori(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "ori"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disoritoccr(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "ori to CCR"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dispea(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "pea"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disrol(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "rol"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disror(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "ror"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disroxl(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "roxl"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disroxr(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "roxr"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disrtr(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - sprintf(outstring, "rtr"); - return 2; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disrts(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - sprintf(outstring, "rts"); - return 2; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dissbcd(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "sbcd"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disscc(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "scc"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dissub(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "sub"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dissuba(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "suba"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dissubi(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "subi"); - outstring += setsizestr2(op >> 6, outstring); - outstring += sprintf(outstring, " "); - outstring += setimmstr(addr+size, op >> 6, &size, outstring); - outstring += sprintf(outstring, ", "); - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dissubq(u32 addr, u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "subq"); - outstring += setsizestr2(op >> 6, outstring); - outstring += sprintf(outstring, " #%d, ", (op >> 9) & 7); // fix me - seteafieldstr(addr+size, op, &size, outstring); - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int dissubx(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "subx"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disswap(UNUSED u32 addr, u16 op, char *outstring) -{ - sprintf(outstring, "swap d%d", op & 0x7); - return 2; -} - -////////////////////////////////////////////////////////////////////////////// - -static int distas(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "tas"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int distrap(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "trap"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int distrapv(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - sprintf(outstring, "trapv"); - return 2; -} - -////////////////////////////////////////////////////////////////////////////// - -static int distst(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - - outstring += sprintf(outstring, "tst"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static int disunlk(UNUSED u32 addr, UNUSED u16 op, char *outstring) -{ - int size=2; - outstring += sprintf(outstring, "unlk"); - // fix me - return size; -} - -////////////////////////////////////////////////////////////////////////////// - -static m68kdis_struct instruction[] = { - { 0xFFFF, 0x023C, "andi #??, CCR", disanditoccr }, - { 0xFFFF, 0x0A3C, "eori #??, CCR", diseoritoccr }, - { 0xFFFF, 0x4AFC, "illegal", disillegal }, - { 0xFFFF, 0x4E71, "nop", disnop }, - { 0xFFFF, 0x003C, "ori #??, CCR", disoritoccr }, - { 0xFFFF, 0x4E77, "rtr", disrtr }, - { 0xFFFF, 0x4E75, "rts", disrts }, - { 0xFFFF, 0x4E76, "trapv", distrapv }, - { 0xFFF8, 0x4848, "bkpt", disbkpt }, - { 0xFFF8, 0x4E50, "link", dislink }, - { 0xFFF8, 0x4840, "swap", disswap }, - { 0xFFF8, 0x4E58, "unlk", disunlk }, - { 0xFFF0, 0x4E40, "trap", distrap }, - { 0xF1F8, 0xD100, "addx.b", disaddx }, - { 0xF1F8, 0xD140, "addx.w", disaddx }, - { 0xF1F8, 0xD180, "addx.l", disaddx }, - { 0xF1F8, 0xB108, "cmpm.b", discmpm }, - { 0xF1F8, 0xB148, "cmpm.w", discmpm }, - { 0xF1F8, 0xB188, "cmpm.l", discmpm }, - { 0xFFC0, 0xE1C0, "asl", disasl }, - { 0xFFC0, 0xE0C0, "asr", disasr }, - { 0xFFC0, 0x0880, "bclr", disbclrs }, - { 0xFFC0, 0x08C0, "bset", disbsets }, - { 0xFFC0, 0x0800, "btst", disbtsts }, - { 0xFFC0, 0x4EC0, "jmp", disjmp }, - { 0xFFC0, 0x4E80, "jsr", disjsr }, - { 0xFFC0, 0x44C0, "move ??, CCR", dismovetoccr }, - { 0xFFC0, 0x40C0, "move SR, ??", dismovefromsr }, - { 0xFFC0, 0x46C0, "move ??, SR", dismovetosr }, - { 0xFFC0, 0x4800, "nbcd", disnbcd }, - { 0xFFC0, 0x4840, "pea", dispea }, - { 0xFFC0, 0x4AC0, "tas", distas }, - { 0xFE38, 0x4800, "ext", disext }, - { 0xF1F0, 0xC100, "abcd", disabcd }, - { 0xF1F0, 0x8100, "sbcd", dissbcd }, - { 0xF0F8, 0x50C8, "dbcc", disdbcc }, - { 0xFB80, 0x4880, "movem", dismovem }, - { 0xFF00, 0x0600, "addi", disaddi }, - { 0xFF00, 0x0200, "andi", disandi }, - { 0xFF00, 0x6000, "bra", disbra }, - { 0xFF00, 0x6100, "bsr", disbsr }, - { 0xFF00, 0x4200, "clr", disclr }, - { 0xFF00, 0x0C00, "cmpi", discmpi }, - { 0xFF00, 0x0A00, "eori", diseori }, - { 0xFF00, 0x4400, "neg", disneg }, - { 0xFF00, 0x4000, "negx", disnegx }, - { 0xFF00, 0x4600, "not", disnot }, - { 0xFF00, 0x0000, "ori", disori }, - { 0xFF00, 0x0400, "subi", dissubi }, - { 0xFF00, 0x4A00, "tst", distst }, - { 0xF118, 0xE108, "lsl", dislsl }, - { 0xF118, 0xE008, "lsr", dislsr }, - { 0xF118, 0xE118, "rol", disrol }, - { 0xF118, 0xE018, "ror", disror }, - { 0xF118, 0xE110, "roxl", disroxl }, - { 0xF118, 0xE010, "roxr", disroxr }, - { 0xF1C0, 0xD0C0, "adda.w", disadda }, - { 0xF1C0, 0xD1C0, "adda.l", disadda }, - { 0xF1C0, 0x0140, "bchg", disbchg }, - { 0xF1C0, 0x0180, "bclr", disbclrd }, - { 0xF1C0, 0x01C0, "bset", disbsetd }, - { 0xF1C0, 0x0100, "btst", disbtstd }, - { 0xF1C0, 0xB000, "cmp.b", discmpb }, - { 0xF1C0, 0xB040, "cmp.w", discmpw }, - { 0xF1C0, 0xB080, "cmp.l", discmpl }, - { 0xF1C0, 0xB0C0, "cmpa.w", discmpaw }, - { 0xF1C0, 0xB1C0, "cmpa.l", discmpal }, - { 0xF1C0, 0x81C0, "divs.w", disdivs }, - { 0xF1C0, 0x80C0, "divu.w", disdivu }, - { 0xF1C0, 0xB100, "eor.b", diseorb }, - { 0xF1C0, 0xB140, "eor.w", diseorw }, - { 0xF1C0, 0xB180, "eor.l", diseorl }, - { 0xF1C0, 0x41C0, "lea", dislea }, - { 0xF1C0, 0xC1C0, "muls", dismuls }, - { 0xF1C0, 0xC0C0, "mulu", dismulu }, - { 0xF130, 0x9100, "subx", dissubx }, - { 0xF038, 0x0008, "movep", dismovep }, - { 0xF0C0, 0x50C0, "scc", disscc }, - { 0xC1C0, 0x0040, "movea", dismovea }, - { 0xF040, 0x4000, "chk", dischk }, - { 0xF100, 0x5000, "addq", disaddq }, - { 0xF100, 0xC100, "exg", disexg }, - { 0xF100, 0x7000, "moveq", dismoveq }, - { 0xF100, 0x5100, "subq", dissubq }, - { 0xF000, 0xD000, "add", disadd }, // fix me - { 0xF000, 0xC000, "and", disand }, - { 0xF000, 0x6000, "bcc", disbcc }, - { 0xF000, 0x8000, "or", disor }, - { 0xF000, 0x9000, "sub", dissub }, // fix me - { 0xF000, 0x9000, "suba", dissuba }, // fix me - { 0xC000, 0x0000, "move", dismove }, - { 0x0000, 0x0000, NULL, NULL } -}; - -////////////////////////////////////////////////////////////////////////////// - -u32 M68KDisasm(u32 addr, char *outstring) -{ - int i; - - outstring += sprintf(outstring, "%05X: ", (unsigned int)addr); - - for (i = 0; instruction[i].name != NULL; i++) - { - u16 op = (u16)c68k_word_read(addr); - - if ((op & instruction[i].mask) == instruction[i].inst) - { - addr += instruction[i].disasm(addr, op, outstring); - return addr; - } - } - - sprintf(outstring, "unknown"); - return (addr+2); -} - -////////////////////////////////////////////////////////////////////////////// diff --git a/yabause/src/m68kd.h b/yabause/src/m68kd.h deleted file mode 100644 index 16383e901e..0000000000 --- a/yabause/src/m68kd.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2004 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef M68KD_H -#define M68KD_H - -#include "core.h" - -u32 M68KDisasm(u32 addr, char *outstring); - -#endif diff --git a/yabause/src/m68kq68.c b/yabause/src/m68kq68.c deleted file mode 100644 index 0f1605112f..0000000000 --- a/yabause/src/m68kq68.c +++ /dev/null @@ -1,534 +0,0 @@ -/* src/m68kpsp.c: Q68 emulator interface - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "yabause.h" -#include "m68kcore.h" - -#include "q68/q68.h" - -/*************************************************************************/ - -/** - * NEED_TRAMPOLINE: Defined on platforms where we need trampoline - * functions to convert read/write calls from the native format to the - * FASTCALL format used by Yabause. - */ -#ifdef CPU_X86 -# define NEED_TRAMPOLINE -#endif - -/** - * PROFILE_68K: Perform simple profiling of the 68000 emulation, reporting - * the average time per 68000 clock cycle. (Realtime execution would be - * around 88.5 nsec/cycle.) - * - * Note that this profiling has an overhead of two YabauseGetTicks() calls - * for each M68K->Exec() call; on PSP, this amounts to about 3.8 usec per - * Exec(), or 52.8 nsec/cycle at 72 cycles/call. - */ -// #define PROFILE_68K - -// #define COUNT_OPCODES // see COUNT_OPCODES in q68-core.c - -/*************************************************************************/ - -/* Interface function declarations (must come before interface definition) */ - -static int m68kq68_init(void); -static void m68kq68_deinit(void); -static void m68kq68_reset(void); - -static FASTCALL s32 m68kq68_exec(s32 cycles); -static void m68kq68_sync(void); - -static u32 m68kq68_get_dreg(u32 num); -static u32 m68kq68_get_areg(u32 num); -static u32 m68kq68_get_pc(void); -static u32 m68kq68_get_sr(void); -static u32 m68kq68_get_usp(void); -static u32 m68kq68_get_ssp(void); - -static void m68kq68_set_dreg(u32 num, u32 val); -static void m68kq68_set_areg(u32 num, u32 val); -static void m68kq68_set_pc(u32 val); -static void m68kq68_set_sr(u32 val); -static void m68kq68_set_usp(u32 val); -static void m68kq68_set_ssp(u32 val); - -static FASTCALL void m68kq68_set_irq(s32 level); -static FASTCALL void m68kq68_write_notify(u32 address, u32 size); - -static void m68kq68_set_fetch(u32 low_addr, u32 high_addr, pointer fetch_addr); -static void m68kq68_set_readb(M68K_READ *func); -static void m68kq68_set_readw(M68K_READ *func); -static void m68kq68_set_writeb(M68K_WRITE *func); -static void m68kq68_set_writew(M68K_WRITE *func); - -static uint32_t dummy_read(uint32_t address); -static void dummy_write(uint32_t address, uint32_t data); - -#ifdef NEED_TRAMPOLINE -static uint32_t readb_trampoline(uint32_t address); -static uint32_t readw_trampoline(uint32_t address); -static void writeb_trampoline(uint32_t address, uint32_t data); -static void writew_trampoline(uint32_t address, uint32_t data); -#endif - -/*-----------------------------------------------------------------------*/ - -/* Module interface definition */ - -M68K_struct M68KQ68 = { - .id = M68KCORE_Q68, - .Name = "Q68 68k Emulator Interface", - - .Init = m68kq68_init, - .DeInit = m68kq68_deinit, - .Reset = m68kq68_reset, - - .Exec = m68kq68_exec, - .Sync = m68kq68_sync, - - .GetDReg = m68kq68_get_dreg, - .GetAReg = m68kq68_get_areg, - .GetPC = m68kq68_get_pc, - .GetSR = m68kq68_get_sr, - .GetUSP = m68kq68_get_usp, - .GetMSP = m68kq68_get_ssp, - - .SetDReg = m68kq68_set_dreg, - .SetAReg = m68kq68_set_areg, - .SetPC = m68kq68_set_pc, - .SetSR = m68kq68_set_sr, - .SetUSP = m68kq68_set_usp, - .SetMSP = m68kq68_set_ssp, - - .SetIRQ = m68kq68_set_irq, - .WriteNotify = m68kq68_write_notify, - - .SetFetch = m68kq68_set_fetch, - .SetReadB = m68kq68_set_readb, - .SetReadW = m68kq68_set_readw, - .SetWriteB = m68kq68_set_writeb, - .SetWriteW = m68kq68_set_writew, -}; - -/*-----------------------------------------------------------------------*/ - -/* Virtual processor state block */ - -static Q68State *state; - - -#ifdef NEED_TRAMPOLINE - -/* Read/write functions passed to Set{Read,Write}[BW], called via the - * trampolines */ -static M68K_READ *real_readb, *real_readw; -static M68K_WRITE *real_writeb, *real_writew; - -#endif - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * m68kq68_init: Initialize the virtual processpr. - * - * [Parameters] - * None - * [Return value] - * Zero on success, negative on failure - */ -static int m68kq68_init(void) -{ - if (!(state = q68_create())) { - return -1; - } - q68_set_irq(state, 0); - q68_set_readb_func(state, dummy_read); - q68_set_readw_func(state, dummy_read); - q68_set_writeb_func(state, dummy_write); - q68_set_writew_func(state, dummy_write); - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * m68kq68_deinit: Destroy the virtual processor. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void m68kq68_deinit(void) -{ - q68_destroy(state); - state = NULL; -} - -/*-----------------------------------------------------------------------*/ - -/** - * m68kq68_reset: Reset the virtual processor. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void m68kq68_reset(void) -{ - q68_reset(state); -} - -/*************************************************************************/ - -/** - * m68kq68_exec: Execute instructions for the given number of clock cycles. - * - * [Parameters] - * cycles: Number of clock cycles to execute - * [Return value] - * Number of clock cycles actually executed - */ -static FASTCALL s32 m68kq68_exec(s32 cycles) -{ -#ifdef PROFILE_68K - static uint32_t tot_cycles = 0, tot_usec = 0, tot_ticks = 0; - static uint32_t last_report = 0; - uint32_t start, end; - start = (uint32_t) YabauseGetTicks(); - int retval = q68_run(state, cycles); - end = (uint32_t) YabauseGetTicks(); - tot_cycles += cycles; - tot_ticks += end - start; - if (tot_cycles/1000000 > last_report) { - tot_usec += (uint64_t)tot_ticks * 1000000 / yabsys.tickfreq; - tot_ticks = 0; - fprintf(stderr, "%ld cycles in %.3f sec = %.3f nsec/cycle\n", - (long)tot_cycles, (double)tot_usec/1000000, - ((double)tot_usec / (double)tot_cycles) * 1000); - last_report = tot_cycles/1000000; -# ifdef COUNT_OPCODES - if (last_report % 100 == 0) { - extern uint32_t q68_ops[128], q68_4xxx_ops[32]; - int i; - fprintf(stderr, "Opcodes per 1M cycles:\n"); - for (i = 0; i < 128; i++) { - fprintf(stderr, "%s%8ld%s", i%8==0 ? " " : "", - (long)((q68_ops[i] + last_report/2) / last_report), - i%8==7 ? "\n" : ""); - } - fprintf(stderr, "$4xxx opcodes per 1M cycles:\n"); - for (i = 0; i < 32; i++) { - fprintf(stderr, "%s%8ld%s", i%8==0 ? " " : "", - (long)((q68_4xxx_ops[i] + last_report/2) / last_report), - i%8==7 ? "\n" : ""); - } - } -# endif // COUNT_OPCODES - } - return retval; -#else // !PROFILE_68K - return q68_run(state, cycles); -#endif -} - -/*-----------------------------------------------------------------------*/ - -/** - * m68kq68_sync: Wait for background execution to finish. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void m68kq68_sync(void) -{ - /* Nothing to do */ -} - -/*************************************************************************/ - -/** - * m68kq68_get_{dreg,areg,pc,sr,usp,ssp}: Return the current value of - * the specified register. - * - * [Parameters] - * num: Register number (m68kq68_get_dreg(), m68kq68_get_areg() only) - * [Return value] - * None - */ - -static u32 m68kq68_get_dreg(u32 num) -{ - return q68_get_dreg(state, num); -} - -static u32 m68kq68_get_areg(u32 num) -{ - return q68_get_areg(state, num); -} - -static u32 m68kq68_get_pc(void) -{ - return q68_get_pc(state); -} - -static u32 m68kq68_get_sr(void) -{ - return q68_get_sr(state); -} - -static u32 m68kq68_get_usp(void) -{ - return q68_get_usp(state); -} - -static u32 m68kq68_get_ssp(void) -{ - return q68_get_ssp(state); -} - -/*-----------------------------------------------------------------------*/ - -/** - * m68kq68_set_{dreg,areg,pc,sr,usp,ssp}: Set the value of the specified - * register. - * - * [Parameters] - * num: Register number (m68kq68_set_dreg(), m68kq68_set_areg() only) - * val: Value to set - * [Return value] - * None - */ - -static void m68kq68_set_dreg(u32 num, u32 val) -{ - q68_set_dreg(state, num, val); -} - -static void m68kq68_set_areg(u32 num, u32 val) -{ - q68_set_areg(state, num, val); -} - -static void m68kq68_set_pc(u32 val) -{ - q68_set_pc(state, val); -} - -static void m68kq68_set_sr(u32 val) -{ - q68_set_sr(state, val); -} - -static void m68kq68_set_usp(u32 val) -{ - q68_set_usp(state, val); -} - -static void m68kq68_set_ssp(u32 val) -{ - q68_set_ssp(state, val); -} - -/*************************************************************************/ - -/** - * m68kq68_set_irq: Deliver an interrupt to the processor. - * - * [Parameters] - * level: Interrupt level (0-7) - * [Return value] - * None - */ -static FASTCALL void m68kq68_set_irq(s32 level) -{ - q68_set_irq(state, level); -} - -/*-----------------------------------------------------------------------*/ - -/** - * m68kq68_write_notify: Inform the 68k emulator that the given address - * range has been modified. - * - * [Parameters] - * address: 68000 address of modified data - * size: Size of modified data in bytes - * [Return value] - * None - */ -static FASTCALL void m68kq68_write_notify(u32 address, u32 size) -{ - q68_touch_memory(state, address, size); -} - -/*************************************************************************/ - -/** - * m68kq68_set_fetch: Set the instruction fetch pointer for a region of - * memory. Not used by Q68. - * - * [Parameters] - * low_addr: Low address of memory region to set - * high_addr: High address of memory region to set - * fetch_addr: Pointer to corresponding memory region (NULL to disable) - * [Return value] - * None - */ -static void m68kq68_set_fetch(u32 low_addr, u32 high_addr, pointer fetch_addr) -{ -} - -/*-----------------------------------------------------------------------*/ - -/** - * m68kq68_set_{readb,readw,writeb,writew}: Set functions for reading or - * writing bytes or words in memory. - * - * [Parameters] - * func: Function to set - * [Return value] - * None - */ - -static void m68kq68_set_readb(M68K_READ *func) -{ -#ifdef NEED_TRAMPOLINE - real_readb = func; - q68_set_readb_func(state, readb_trampoline); -#else - q68_set_readb_func(state, (Q68ReadFunc *)func); -#endif -} - -static void m68kq68_set_readw(M68K_READ *func) -{ -#ifdef NEED_TRAMPOLINE - real_readw = func; - q68_set_readw_func(state, readw_trampoline); -#else - q68_set_readw_func(state, (Q68ReadFunc *)func); -#endif -} - -static void m68kq68_set_writeb(M68K_WRITE *func) -{ -#ifdef NEED_TRAMPOLINE - real_writeb = func; - q68_set_writeb_func(state, writeb_trampoline); -#else - q68_set_writeb_func(state, (Q68WriteFunc *)func); -#endif -} - -static void m68kq68_set_writew(M68K_WRITE *func) -{ -#ifdef NEED_TRAMPOLINE - real_writew = func; - q68_set_writew_func(state, writew_trampoline); -#else - q68_set_writew_func(state, (Q68WriteFunc *)func); -#endif -} - -/*************************************************************************/ - -/** - * dummy_read: Default read function, always returning 0 for any address. - * - * [Parameters] - * address: Address to read from - * [Return value] - * Value read (always zero) - */ -static uint32_t dummy_read(uint32_t address) -{ - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * dummy_write: Default write function, ignoring all writes. - * - * [Parameters] - * address: Address to write to - * data: Value to write - * [Return value] - * None - */ -static void dummy_write(uint32_t address, uint32_t data) -{ -} - -/*-----------------------------------------------------------------------*/ - -#ifdef NEED_TRAMPOLINE - -/** - * read[bw]_trampoline, write[bw]_trampoline: Adjust calling conventions - * between the M68k emulator and Yabause's M68k core. - * - * [Parameters] - * address: Address to read from - * data: Value to write (only for write_trampoline) - * [Return value] - * Value read (only for read_trampoline) - */ - -static uint32_t readb_trampoline(uint32_t address) { - return (*real_readb)(address); -} - -static uint32_t readw_trampoline(uint32_t address) { - return (*real_readw)(address); -} - -static void writeb_trampoline(uint32_t address, uint32_t data) { - return (*real_writeb)(address, data); -} - -static void writew_trampoline(uint32_t address, uint32_t data) { - return (*real_writew)(address, data); -} - -#endif // NEED_TRAMPOLINE - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/macjoy.c b/yabause/src/macjoy.c deleted file mode 100644 index 0d202a50ae..0000000000 --- a/yabause/src/macjoy.c +++ /dev/null @@ -1,516 +0,0 @@ -/* This file was imported form CrabEmu ( http://crabemu.sourceforge.net/ ) -- - A Sega Master System emulator for Mac OS X (among other targets). The rest - of the file is left intact from CrabEmu to make things easier if this were - to be upgraded in the future. */ - -/* - This file is part of CrabEmu. - - Copyright (C) 2008 Lawrence Sebald - - CrabEmu is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 - as published by the Free Software Foundation. - - CrabEmu is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with CrabEmu; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "macjoy.h" - -static int joy_count = 0; -static joydata_t *joys = NULL; - -static void joy_find_elements(CFMutableDictionaryRef prop, joydata_t *joy); - -/* Compare two buttons for sorting. */ -static int joy_cmp_buttons(const void *e1, const void *e2) { - const joy_elemdata_t *b1 = (const joy_elemdata_t *)e1; - const joy_elemdata_t *b2 = (const joy_elemdata_t *)e2; - - return b1->number < b2->number ? -1 : - (b1->number > b2->number ? 1 : 0); -} - -/* Get the io_iterator_t object needed to iterate through the list of HID - devices. */ -static void joy_get_iterator(mach_port_t port, io_iterator_t *iter) { - CFMutableDictionaryRef d; - IOReturn rv; - - /* Create a matching dictionary that will be used to search the device - tree. */ - if(!(d = IOServiceMatching(kIOHIDDeviceKey))) { - return; - } - - /* Get all matching devices from IOKit. */ - rv = IOServiceGetMatchingServices(port, d, iter); - - if(rv != kIOReturnSuccess || !(*iter)) { - return; - } -} - -/* Create the interface needed to do stuff with the device. */ -static int joy_create_interface(io_object_t hidDevice, joydata_t *joy) { - IOCFPlugInInterface **plugin; - SInt32 score = 0; - - /* Create the plugin that we will use to actually get the device interface - that is needed. */ - if(IOCreatePlugInInterfaceForService(hidDevice, - kIOHIDDeviceUserClientTypeID, - kIOCFPlugInInterfaceID, &plugin, - &score) != kIOReturnSuccess) { - return 0; - } - - /* Grab the device interface from the plugin. */ - if((*plugin)->QueryInterface(plugin, - CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), - (LPVOID)&joy->iface) != S_OK) { - return 0; - } - - /* The plugin has done all it needs to, release it. */ - (*plugin)->Release(plugin); - - return 1; -} - -/* Fill in a elemdata_t structure with information about the given physical - element. */ -static void joy_fill_elem(CFTypeRef elem, joy_elemdata_t *ptr) { - CFTypeRef ref; - int num; - - memset(ptr, 0, sizeof(joy_elemdata_t)); - - /* Grab the element cookie. */ - if((ref = CFDictionaryGetValue(elem, CFSTR(kIOHIDElementCookieKey)))) { - if(CFNumberGetValue(ref, kCFNumberIntType, &num)) { - ptr->cookie = (IOHIDElementCookie)num; - } - } - - /* Grab the element's minimum value. */ - if((ref = CFDictionaryGetValue(elem, CFSTR(kIOHIDElementMinKey)))) { - if(CFNumberGetValue(ref, kCFNumberIntType, &num)) { - ptr->min = num; - } - } - - /* Grab the element's maximum value. */ - if((ref = CFDictionaryGetValue(elem, CFSTR(kIOHIDElementMaxKey)))) { - if(CFNumberGetValue(ref, kCFNumberIntType, &num)) { - ptr->max = num; - } - } -} - -/* Callback function to handle each sub-element of the controller class. */ -static void joy_elem_array_hnd(const void *value, void *parameter) { - CFTypeRef elem = (CFTypeRef)value; - CFTypeID t = CFGetTypeID(value); - joydata_t *joy = (joydata_t *)parameter; - long elemType, elemPage, elemUsage; - CFTypeRef type, page, usage; - void *ptr; - int et; - - /* Make sure we're dealing with a dictionary. */ - if(t == CFDictionaryGetTypeID()) { - /* Grab the type of the element. */ - type = CFDictionaryGetValue(elem, CFSTR(kIOHIDElementTypeKey)); - - if(!type) { - return; - } - - /* Grab the HID usage page. */ - page = CFDictionaryGetValue(elem, CFSTR(kIOHIDElementUsagePageKey)); - - if(!page) { - return; - } - - /* Grab the HID usage type. */ - usage = CFDictionaryGetValue(elem, CFSTR(kIOHIDElementUsageKey)); - - if(!usage) { - return; - } - - /* Get the integer values from the data grabbed above. */ - if(!CFNumberGetValue(type, kCFNumberLongType, &elemType)) { - return; - } - - if(!CFNumberGetValue(page, kCFNumberLongType, &elemPage)) { - return; - } - - if(!CFNumberGetValue(usage, kCFNumberLongType, &elemUsage)) { - return; - } - - /* If the element is listed as a button, axis, or misc input, check - what it actually is. */ - if(elemType == kIOHIDElementTypeInput_Button || - elemType == kIOHIDElementTypeInput_Axis || - elemType == kIOHIDElementTypeInput_Misc) { - switch(elemPage) { - case kHIDPage_Button: - ptr = realloc(joy->buttons, (joy->buttons_count + 1) * - sizeof(joy_elemdata_t)); - - if(ptr) { - joy->buttons = (joy_elemdata_t *)ptr; - joy_fill_elem(elem, joy->buttons + joy->buttons_count); - joy->buttons[joy->buttons_count].number = elemUsage; - ++joy->buttons_count; - } - break; - - case kHIDPage_GenericDesktop: - switch(elemUsage) { - case kHIDUsage_GD_X: - et = JOY_TYPE_X_AXIS; - goto axis; - - case kHIDUsage_GD_Y: - et = JOY_TYPE_Y_AXIS; - goto axis; - - case kHIDUsage_GD_Z: - et = JOY_TYPE_Z_AXIS; - goto axis; - - case kHIDUsage_GD_Rx: - et = JOY_TYPE_X2_AXIS; - goto axis; - - case kHIDUsage_GD_Ry: - et = JOY_TYPE_Y2_AXIS; - goto axis; - - case kHIDUsage_GD_Rz: - et = JOY_TYPE_Z2_AXIS; -axis: - ptr = realloc(joy->axes, (joy->axes_count + 1) * - sizeof(joy_elemdata_t)); - - if(ptr) { - joy->axes = (joy_elemdata_t *)ptr; - joy_fill_elem(elem, joy->axes + - joy->axes_count); - joy->axes[joy->axes_count].type = et; - ++joy->axes_count; - } - break; - - case kHIDUsage_GD_Hatswitch: - ptr = realloc(joy->hats, (joy->hats_count + 1) * - sizeof(joy_elemdata_t)); - - if(ptr) { - joy->hats = (joy_elemdata_t *)ptr; - joy_fill_elem(elem, joy->hats + - joy->hats_count); - ++joy->hats_count; - } - break; - } - break; - } - - } - /* If we've found another element array, effectively recurse. */ - else if(elemType == kIOHIDElementTypeCollection) { - joy_find_elements((CFMutableDictionaryRef)elem, joy); - } - } -} - -/* Process all the sub-elements of a given property list. */ -static void joy_find_elements(CFMutableDictionaryRef prop, joydata_t *joy) { - CFTypeRef elem; - CFTypeID type; - - if((elem = CFDictionaryGetValue(prop, CFSTR(kIOHIDElementKey)))) { - type = CFGetTypeID(elem); - - if(type == CFArrayGetTypeID()) { - /* Call our function on each element of the array. */ - CFRange r = { 0, CFArrayGetCount(elem) }; - CFArrayApplyFunction(elem, r, &joy_elem_array_hnd, (void *)joy); - } - } -} - -/* Read the device passed in, and add it to our joystick list if appropriate. */ -static void joy_read_device(io_object_t dev) { - CFMutableDictionaryRef props = 0; - - /* Create a dictionary to read the device's properties. */ - if(IORegistryEntryCreateCFProperties(dev, &props, kCFAllocatorDefault, - kNilOptions) == KERN_SUCCESS) { - CFTypeRef inf; - SInt32 page, usage; - void *ptr; - - /* Grab the primary usage page of the device. */ - inf = CFDictionaryGetValue(props, CFSTR(kIOHIDPrimaryUsagePageKey)); - - if(!inf || !CFNumberGetValue((CFNumberRef)inf, kCFNumberSInt32Type, - &page)) { - goto out; - } - - /* Ignore devices that are not in the Generic Desktop page. */ - if(page != kHIDPage_GenericDesktop) { - goto out; - } - - /* Grab the primary device usage. */ - inf = CFDictionaryGetValue(props, CFSTR(kIOHIDPrimaryUsageKey)); - - if(!inf || !CFNumberGetValue((CFNumberRef)inf, kCFNumberSInt32Type, - &usage)) { - goto out; - } - - /* Ignore devices that are not either a Game Pad or Joystick. */ - if(usage != kHIDUsage_GD_GamePad && usage != kHIDUsage_GD_Joystick) { - goto out; - } - - /* Allocate space for the new joystick structure. */ - ptr = realloc(joys, (joy_count + 1) * sizeof(joydata_t)); - - if(ptr == NULL) { - goto out; - } - - joys = (joydata_t *)ptr; - memset(joys + joy_count, 0, sizeof(joydata_t)); - - /* Grab and store the name of the device. */ - inf = CFDictionaryGetValue(props, CFSTR(kIOHIDProductKey)); - - if(!CFStringGetCString((CFStringRef)inf, joys[joy_count].name, 256, - kCFStringEncodingUTF8)) { - goto out; - } - - /* Create the device interface needed to interact with the device. */ - if(!joy_create_interface(dev, joys + joy_count)) { - goto out; - } - - /* Find all elements of the device. */ - joy_find_elements(props, joys + joy_count); - - qsort(joys[joy_count].buttons, joys[joy_count].buttons_count, - sizeof(joy_elemdata_t), &joy_cmp_buttons); - - ++joy_count; - } - -out: - CFRelease(props); -} - -/* Release the given joystick's interface and clean up any memory used by it. */ -static void joy_release_joystick(joydata_t *joy) { - (*joy->iface)->Release(joy->iface); - - joy->iface = NULL; - - if(joy->buttons) - free(joy->buttons); - - if(joy->axes) - free(joy->axes); - - if(joy->hats) - free(joy->hats); -} - -/* Scan the system for any joysticks connected. */ -int joy_scan_joysticks(void) { - io_iterator_t iter = 0; - io_object_t dev; - - if(joys != NULL) { - return -1; - } - - /* Get the iterator needed for going through the list of devices. */ - joy_get_iterator(kIOMasterPortDefault, &iter); - - if(iter != 0) { - while((dev = IOIteratorNext(iter))) { - joy_read_device(dev); - IOObjectRelease(dev); - } - - /* Release the iterator. */ - IOObjectRelease(iter); - } - - return joy_count; -} - -/* Clean up any data allocated by the program for joysticks. */ -void joy_release_joysticks(void) { - int i; - - for(i = 0; i < joy_count; ++i) { - joy_close_joystick(joys + i); - joy_release_joystick(joys + i); - } - - if(joys != NULL) { - free(joys); - joys = NULL; - } - - joy_count = 0; -} - -/* Get the joystick at a given index in our list of joysticks. */ -joydata_t *joy_get_joystick(int index) { - if(index < 0 || index >= joy_count) { - return NULL; - } - - return &joys[index]; -} - -/* Grab the device for exclusive use by this program. The device must be closed - properly (with the joy_close_joystick function, or you may need to - unplug/replug the joystick to get it to work again). */ -int joy_open_joystick(joydata_t *joy) { - if((*joy->iface)->open(joy->iface, 0)) { - return 0; - } - - joy->open = 1; - - return 1; -} - -/* Close the device and return its resources to the system. */ -int joy_close_joystick(joydata_t *joy) { - IOReturn rv; - - if(!joy->open) { - return 1; - } - - rv = (*joy->iface)->close(joy->iface); - - if(rv == kIOReturnNotOpen) { - /* The device wasn't open so it can't be closed. */ - return 1; - } - else if(rv != kIOReturnSuccess) { - return 0; - } - - joy->open = 0; - - return 1; -} - -/* Read a given element from the joystick. The joystick must be open for this - function to actually do anything useful. */ -int joy_read_element(joydata_t *joy, joy_elemdata_t *elem) { - IOHIDEventStruct ev; - - memset(&ev, 0, sizeof(IOHIDEventStruct)); - - (*joy->iface)->getElementValue(joy->iface, elem->cookie, &ev); - - return ev.value; -} - -/* Read the value of a given button. Returns -1 on failure. */ -int joy_read_button(joydata_t *joy, int num) { - /* Subtract 1 from the number to get the index. */ - --num; - - if(num >= joy->buttons_count) { - return -1; - } - - return joy_read_element(joy, joy->buttons + num); -} - -/* Read the value of a given axis. Returns 0 on failure (or if the axis reports - that its value is 0). */ -int joy_read_axis(joydata_t *joy, int index) { - float value; - - if(index >= joy->axes_count) { - return 0; - } - - value = joy_read_element(joy, joy->axes + index) / - (float)(joy->axes[index].max + 1); - - return (int)(value * 32768); -} - -/* Read the value of a given hat. Returns -1 on failure. */ -int joy_read_hat(joydata_t *joy, int index) { - int value; - - if(index >= joy->hats_count) { - return -1; - } - - value = joy_read_element(joy, joy->hats + index) - joy->hats[index].min; - - /* 4-position hat switch -- Make it look like an 8-position one. */ - if(joy->hats[index].max - joy->hats[index].min + 1 == 4) { - value <<= 1; - } - - switch(value) { - case 0: - return JOY_HAT_UP; - case 1: - return JOY_HAT_UP | JOY_HAT_RIGHT; - case 2: - return JOY_HAT_RIGHT; - case 3: - return JOY_HAT_RIGHT | JOY_HAT_DOWN; - case 4: - return JOY_HAT_DOWN; - case 5: - return JOY_HAT_DOWN | JOY_HAT_LEFT; - case 6: - return JOY_HAT_LEFT; - case 7: - return JOY_HAT_LEFT | JOY_HAT_UP; - default: - return JOY_HAT_CENTER; - } -} diff --git a/yabause/src/macjoy.h b/yabause/src/macjoy.h deleted file mode 100644 index 837296185a..0000000000 --- a/yabause/src/macjoy.h +++ /dev/null @@ -1,101 +0,0 @@ -/* This file was imported form CrabEmu ( http://crabemu.sourceforge.net/ ) -- - A Sega Master System emulator for Mac OS X (among other targets). The rest - of the file is left intact from CrabEmu to make things easier if this were - to be upgraded in the future. */ - -/* - This file is part of CrabEmu. - - Copyright (C) 2008 Lawrence Sebald - - CrabEmu is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 - as published by the Free Software Foundation. - - CrabEmu is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with CrabEmu; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef JOYSTICK_H -#define JOYSTICK_H - -#include - -/* Values for the joy_elemdata_t type element. */ -#define JOY_TYPE_NOT_APPLICABLE 0 -#define JOY_TYPE_X_AXIS 1 -#define JOY_TYPE_Y_AXIS 2 -#define JOY_TYPE_Z_AXIS 3 -#define JOY_TYPE_X2_AXIS 4 -#define JOY_TYPE_Y2_AXIS 5 -#define JOY_TYPE_Z2_AXIS 6 - -/* Structure for holding basic information about each element. */ -typedef struct joy_elemdata_s { - IOHIDElementCookie cookie; - int type; - int number; - int min; - int max; -} joy_elemdata_t; - -/* Structure for holding information about each joystick connected. */ -typedef struct joydata_s { - IOHIDDeviceInterface **iface; - int open; - int buttons_count; - int axes_count; - int hats_count; - - joy_elemdata_t *buttons; - joy_elemdata_t *axes; - joy_elemdata_t *hats; - - char name[256]; -} joydata_t; - -/* Values for hat switches. ORed together and returned from joy_read_hat. */ -#define JOY_HAT_CENTER 0 -#define JOY_HAT_UP (1 << 0) -#define JOY_HAT_DOWN (1 << 1) -#define JOY_HAT_RIGHT (1 << 2) -#define JOY_HAT_LEFT (1 << 3) - -/* Scan the system for any joysticks connected. */ -int joy_scan_joysticks(void); - -/* Clean up any data allocated by the program for joysticks. */ -void joy_release_joysticks(void); - -/* Get the joystick at a given index in our list of joysticks. */ -joydata_t *joy_get_joystick(int index); - -/* Grab the device for exclusive use by this program. The device must be closed - properly (with the joy_close_joystick function, or you may need to - unplug/replug the joystick to get it to work again). */ -int joy_open_joystick(joydata_t *joy); - -/* Close the device and return its resources to the system. */ -int joy_close_joystick(joydata_t *joy); - -/* Read a given element from the joystick. The joystick must be open for this - function to actually do anything useful. */ -int joy_read_element(joydata_t *joy, joy_elemdata_t *elem); - -/* Read the value of a given button. Returns -1 on failure. */ -int joy_read_button(joydata_t *joy, int num); - -/* Read the value of a given axis. Returns 0 on failure (or if the axis reports - that its value is 0). */ -int joy_read_axis(joydata_t *joy, int index); - -/* Read the value of a given hat. Returns -1 on failure. */ -int joy_read_hat(joydata_t *joy, int index); - -#endif /* !JOYSTICK_H */ diff --git a/yabause/src/memory.c b/yabause/src/memory.c deleted file mode 100644 index 2318154264..0000000000 --- a/yabause/src/memory.c +++ /dev/null @@ -1,1685 +0,0 @@ -/* Copyright 2005 Guillaume Duhamel - Copyright 2005-2006 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifdef PSP // see FIXME in T1MemoryInit() -# include -#endif -#include -#include -#include -#include - -#include "memory.h" -#include "coffelf.h" -#include "cs0.h" -#include "cs1.h" -#include "cs2.h" -#include "debug.h" -#include "error.h" -#include "sh2core.h" -#include "scsp.h" -#include "scu.h" -#include "smpc.h" -#include "vdp1.h" -#include "vdp2.h" -#include "yabause.h" -#include "yui.h" -#include "movie.h" - -#ifdef HAVE_LIBGL -#define USE_OPENGL -#endif - -#ifdef USE_OPENGL -#include "ygl.h" -#endif - -#include "vidsoft.h" -#include "vidogl.h" - -////////////////////////////////////////////////////////////////////////////// - -writebytefunc WriteByteList[0x1000]; -writewordfunc WriteWordList[0x1000]; -writelongfunc WriteLongList[0x1000]; - -readbytefunc ReadByteList[0x1000]; -readwordfunc ReadWordList[0x1000]; -readlongfunc ReadLongList[0x1000]; - -u8 *HighWram; -u8 *LowWram; -u8 *BiosRom; -u8 *BupRam; - -/* This flag is set to 1 on every write to backup RAM. Ports can freely - * check or clear this flag to determine when backup RAM has been written, - * e.g. for implementing autosave of backup RAM. */ -u8 BupRamWritten; - -////////////////////////////////////////////////////////////////////////////// - -u8 * T1MemoryInit(u32 size) -{ -#ifdef PSP // FIXME: could be ported to all arches, but requires stdint.h - // for uintptr_t - u8 * base; - u8 * mem; - - if ((base = calloc((size * sizeof(u8)) + sizeof(u8 *) + 64, 1)) == NULL) - return NULL; - - mem = base + sizeof(u8 *); - mem = mem + (64 - ((uintptr_t) mem & 63)); - *(u8 **)(mem - sizeof(u8 *)) = base; // Save base pointer below memory block - - return mem; -#else - return calloc(size, sizeof(u8)); -#endif -} - -////////////////////////////////////////////////////////////////////////////// - -void T1MemoryDeInit(u8 * mem) -{ -#ifdef PSP - if (mem) - free(*(u8 **)(mem - sizeof(u8 *))); -#else - free(mem); -#endif -} - -////////////////////////////////////////////////////////////////////////////// - -T3Memory * T3MemoryInit(u32 size) -{ - T3Memory * mem; - - if ((mem = (T3Memory *) calloc(1, sizeof(T3Memory))) == NULL) - return NULL; - - if ((mem->base_mem = (u8 *) calloc(size, sizeof(u8))) == NULL) - return NULL; - - mem->mem = mem->base_mem + size; - - return mem; -} - -////////////////////////////////////////////////////////////////////////////// - -void T3MemoryDeInit(T3Memory * mem) -{ - free(mem->base_mem); - free(mem); -} - -////////////////////////////////////////////////////////////////////////////// - -Dummy * DummyInit(UNUSED u32 s) -{ - return NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -void DummyDeInit(UNUSED Dummy * d) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL UnhandledMemoryReadByte(USED_IF_DEBUG u32 addr) -{ - LOG("Unhandled byte read %08X\n", (unsigned int)addr); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL UnhandledMemoryReadWord(USED_IF_DEBUG u32 addr) -{ - LOG("Unhandled word read %08X\n", (unsigned int)addr); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL UnhandledMemoryReadLong(USED_IF_DEBUG u32 addr) -{ - LOG("Unhandled long read %08X\n", (unsigned int)addr); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL UnhandledMemoryWriteByte(USED_IF_DEBUG u32 addr, UNUSED u8 val) -{ - LOG("Unhandled byte write %08X\n", (unsigned int)addr); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL UnhandledMemoryWriteWord(USED_IF_DEBUG u32 addr, UNUSED u16 val) -{ - LOG("Unhandled word write %08X\n", (unsigned int)addr); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL UnhandledMemoryWriteLong(USED_IF_DEBUG u32 addr, UNUSED u32 val) -{ - LOG("Unhandled long write %08X\n", (unsigned int)addr); -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL HighWramMemoryReadByte(u32 addr) -{ - return T2ReadByte(HighWram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL HighWramMemoryReadWord(u32 addr) -{ - return T2ReadWord(HighWram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL HighWramMemoryReadLong(u32 addr) -{ - return T2ReadLong(HighWram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL HighWramMemoryWriteByte(u32 addr, u8 val) -{ - T2WriteByte(HighWram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL HighWramMemoryWriteWord(u32 addr, u16 val) -{ - T2WriteWord(HighWram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL HighWramMemoryWriteLong(u32 addr, u32 val) -{ - T2WriteLong(HighWram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL LowWramMemoryReadByte(u32 addr) -{ - return T2ReadByte(LowWram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL LowWramMemoryReadWord(u32 addr) -{ - return T2ReadWord(LowWram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL LowWramMemoryReadLong(u32 addr) -{ - return T2ReadLong(LowWram, addr & 0xFFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL LowWramMemoryWriteByte(u32 addr, u8 val) -{ - T2WriteByte(LowWram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL LowWramMemoryWriteWord(u32 addr, u16 val) -{ - T2WriteWord(LowWram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL LowWramMemoryWriteLong(u32 addr, u32 val) -{ - T2WriteLong(LowWram, addr & 0xFFFFF, val); -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL BiosRomMemoryReadByte(u32 addr) -{ - return T2ReadByte(BiosRom, addr & 0x7FFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL BiosRomMemoryReadWord(u32 addr) -{ - return T2ReadWord(BiosRom, addr & 0x7FFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL BiosRomMemoryReadLong(u32 addr) -{ - return T2ReadLong(BiosRom, addr & 0x7FFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosRomMemoryWriteByte(UNUSED u32 addr, UNUSED u8 val) -{ - // read-only -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosRomMemoryWriteWord(UNUSED u32 addr, UNUSED u16 val) -{ - // read-only -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BiosRomMemoryWriteLong(UNUSED u32 addr, UNUSED u32 val) -{ - // read-only -} - -////////////////////////////////////////////////////////////////////////////// - -static u8 FASTCALL BupRamMemoryReadByte(u32 addr) -{ - return T1ReadByte(BupRam, addr & 0xFFFF); -} - -////////////////////////////////////////////////////////////////////////////// - -static u16 FASTCALL BupRamMemoryReadWord(USED_IF_DEBUG u32 addr) -{ - LOG("bup\t: BackupRam read word - %08X\n", addr); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static u32 FASTCALL BupRamMemoryReadLong(USED_IF_DEBUG u32 addr) -{ - LOG("bup\t: BackupRam read long - %08X\n", addr); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BupRamMemoryWriteByte(u32 addr, u8 val) -{ - T1WriteByte(BupRam, (addr & 0xFFFF) | 0x1, val); - BupRamWritten = 1; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BupRamMemoryWriteWord(USED_IF_DEBUG u32 addr, UNUSED u16 val) -{ - LOG("bup\t: BackupRam write word - %08X\n", addr); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL BupRamMemoryWriteLong(USED_IF_DEBUG u32 addr, UNUSED u32 val) -{ - LOG("bup\t: BackupRam write long - %08X\n", addr); -} - -////////////////////////////////////////////////////////////////////////////// - -static void FillMemoryArea(unsigned short start, unsigned short end, - readbytefunc r8func, readwordfunc r16func, - readlongfunc r32func, writebytefunc w8func, - writewordfunc w16func, writelongfunc w32func) -{ - int i; - - for (i=start; i < (end+1); i++) - { - ReadByteList[i] = r8func; - ReadWordList[i] = r16func; - ReadLongList[i] = r32func; - WriteByteList[i] = w8func; - WriteWordList[i] = w16func; - WriteLongList[i] = w32func; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void MappedMemoryInit() -{ - // Initialize everyting to unhandled to begin with - FillMemoryArea(0x000, 0xFFF, &UnhandledMemoryReadByte, - &UnhandledMemoryReadWord, - &UnhandledMemoryReadLong, - &UnhandledMemoryWriteByte, - &UnhandledMemoryWriteWord, - &UnhandledMemoryWriteLong); - - // Fill the rest - FillMemoryArea(0x000, 0x00F, &BiosRomMemoryReadByte, - &BiosRomMemoryReadWord, - &BiosRomMemoryReadLong, - &BiosRomMemoryWriteByte, - &BiosRomMemoryWriteWord, - &BiosRomMemoryWriteLong); - FillMemoryArea(0x010, 0x017, &SmpcReadByte, - &SmpcReadWord, - &SmpcReadLong, - &SmpcWriteByte, - &SmpcWriteWord, - &SmpcWriteLong); - FillMemoryArea(0x018, 0x01F, &BupRamMemoryReadByte, - &BupRamMemoryReadWord, - &BupRamMemoryReadLong, - &BupRamMemoryWriteByte, - &BupRamMemoryWriteWord, - &BupRamMemoryWriteLong); - FillMemoryArea(0x020, 0x02F, &LowWramMemoryReadByte, - &LowWramMemoryReadWord, - &LowWramMemoryReadLong, - &LowWramMemoryWriteByte, - &LowWramMemoryWriteWord, - &LowWramMemoryWriteLong); - FillMemoryArea(0x100, 0x17F, &UnhandledMemoryReadByte, - &UnhandledMemoryReadWord, - &UnhandledMemoryReadLong, - &UnhandledMemoryWriteByte, - &SSH2InputCaptureWriteWord, - &UnhandledMemoryWriteLong); - FillMemoryArea(0x180, 0x1FF, &UnhandledMemoryReadByte, - &UnhandledMemoryReadWord, - &UnhandledMemoryReadLong, - &UnhandledMemoryWriteByte, - &MSH2InputCaptureWriteWord, - &UnhandledMemoryWriteLong); - FillMemoryArea(0x200, 0x3FF, CartridgeArea->Cs0ReadByte, - CartridgeArea->Cs0ReadWord, - CartridgeArea->Cs0ReadLong, - CartridgeArea->Cs0WriteByte, - CartridgeArea->Cs0WriteWord, - CartridgeArea->Cs0WriteLong); - FillMemoryArea(0x400, 0x4FF, &Cs1ReadByte, - &Cs1ReadWord, - &Cs1ReadLong, - &Cs1WriteByte, - &Cs1WriteWord, - &Cs1WriteLong); - FillMemoryArea(0x580, 0x58F, &Cs2ReadByte, - &Cs2ReadWord, - &Cs2ReadLong, - &Cs2WriteByte, - &Cs2WriteWord, - &Cs2WriteLong); - FillMemoryArea(0x5A0, 0x5AF, &SoundRamReadByte, - &SoundRamReadWord, - &SoundRamReadLong, - &SoundRamWriteByte, - &SoundRamWriteWord, - &SoundRamWriteLong); - FillMemoryArea(0x5B0, 0x5BF, &scsp_r_b, - &scsp_r_w, - &scsp_r_d, - &scsp_w_b, - &scsp_w_w, - &scsp_w_d); - FillMemoryArea(0x5C0, 0x5C7, &Vdp1RamReadByte, - &Vdp1RamReadWord, - &Vdp1RamReadLong, - &Vdp1RamWriteByte, - &Vdp1RamWriteWord, - &Vdp1RamWriteLong); - FillMemoryArea(0x5C8, 0x5CF, &Vdp1FrameBufferReadByte, - &Vdp1FrameBufferReadWord, - &Vdp1FrameBufferReadLong, - &Vdp1FrameBufferWriteByte, - &Vdp1FrameBufferWriteWord, - &Vdp1FrameBufferWriteLong); - FillMemoryArea(0x5D0, 0x5D7, &Vdp1ReadByte, - &Vdp1ReadWord, - &Vdp1ReadLong, - &Vdp1WriteByte, - &Vdp1WriteWord, - &Vdp1WriteLong); - FillMemoryArea(0x5E0, 0x5EF, &Vdp2RamReadByte, - &Vdp2RamReadWord, - &Vdp2RamReadLong, - &Vdp2RamWriteByte, - &Vdp2RamWriteWord, - &Vdp2RamWriteLong); - FillMemoryArea(0x5F0, 0x5F7, &Vdp2ColorRamReadByte, - &Vdp2ColorRamReadWord, - &Vdp2ColorRamReadLong, - &Vdp2ColorRamWriteByte, - &Vdp2ColorRamWriteWord, - &Vdp2ColorRamWriteLong); - FillMemoryArea(0x5F8, 0x5FB, &Vdp2ReadByte, - &Vdp2ReadWord, - &Vdp2ReadLong, - &Vdp2WriteByte, - &Vdp2WriteWord, - &Vdp2WriteLong); - FillMemoryArea(0x5FE, 0x5FE, &ScuReadByte, - &ScuReadWord, - &ScuReadLong, - &ScuWriteByte, - &ScuWriteWord, - &ScuWriteLong); - FillMemoryArea(0x600, 0x7FF, &HighWramMemoryReadByte, - &HighWramMemoryReadWord, - &HighWramMemoryReadLong, - &HighWramMemoryWriteByte, - &HighWramMemoryWriteWord, - &HighWramMemoryWriteLong); -} - -////////////////////////////////////////////////////////////////////////////// - -u8 FASTCALL MappedMemoryReadByte(u32 addr) -{ - switch (addr >> 29) - { - case 0x0: - case 0x1: - case 0x5: - { - // Cache/Non-Cached - return ReadByteList[(addr >> 16) & 0xFFF](addr); - } -/* - case 0x2: - { - // Purge Area - break; - } -*/ - case 0x4: - case 0x6: - // Data Array - return DataArrayReadByte(addr); - case 0x7: - { - if (addr >= 0xFFFFFE00) - { - // Onchip modules - addr &= 0x1FF; - return OnchipReadByte(addr); - } - else if (addr >= 0xFFFF8000 && addr < 0xFFFFC000) - { - // ??? - } - else - { - // Garbage data - } - break; - } - default: - { - return UnhandledMemoryReadByte(addr); - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -u16 FASTCALL MappedMemoryReadWord(u32 addr) -{ - switch (addr >> 29) - { - case 0x0: - case 0x1: - case 0x5: - { - // Cache/Non-Cached - return ReadWordList[(addr >> 16) & 0xFFF](addr); - } -/* - case 0x2: - { - // Purge Area - break; - } -*/ - case 0x4: - case 0x6: - // Data Array - return DataArrayReadWord(addr); - case 0x7: - { - if (addr >= 0xFFFFFE00) - { - // Onchip modules - addr &= 0x1FF; - return OnchipReadWord(addr); - } - else if (addr >= 0xFFFF8000 && addr < 0xFFFFC000) - { - // ??? - } - else - { - // Garbage data - } - break; - } - default: - { - return UnhandledMemoryReadWord(addr); - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -u32 FASTCALL MappedMemoryReadLong(u32 addr) -{ - switch (addr >> 29) - { - case 0x0: - case 0x1: - case 0x5: - { - // Cache/Non-Cached - return ReadLongList[(addr >> 16) & 0xFFF](addr); - } -/* - case 0x2: - { - // Purge Area - break; - } -*/ - case 0x3: - { - // Address Array - return AddressArrayReadLong(addr); - } - case 0x4: - case 0x6: - // Data Array - return DataArrayReadLong(addr); - case 0x7: - { - if (addr >= 0xFFFFFE00) - { - // Onchip modules - addr &= 0x1FF; - return OnchipReadLong(addr); - } - else if (addr >= 0xFFFF8000 && addr < 0xFFFFC000) - { - // ??? - } - else - { - // Garbage data - } - break; - } - default: - { - return UnhandledMemoryReadLong(addr); - } - } - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL MappedMemoryWriteByte(u32 addr, u8 val) -{ - switch (addr >> 29) - { - case 0x0: - case 0x1: - case 0x5: - { - // Cache/Non-Cached - WriteByteList[(addr >> 16) & 0xFFF](addr, val); - return; - } -/* - case 0x2: - { - // Purge Area - return; - } -*/ - case 0x4: - case 0x6: - // Data Array - DataArrayWriteByte(addr, val); - return; - case 0x7: - { - if (addr >= 0xFFFFFE00) - { - // Onchip modules - addr &= 0x1FF; - OnchipWriteByte(addr, val); - return; - } - else if (addr >= 0xFFFF8000 && addr < 0xFFFFC000) - { - // ??? - } - else - { - // Garbage data - } - return; - } - default: - { - UnhandledMemoryWriteByte(addr, val); - return; - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL MappedMemoryWriteWord(u32 addr, u16 val) -{ - switch (addr >> 29) - { - case 0x0: - case 0x1: - case 0x5: - { - // Cache/Non-Cached - WriteWordList[(addr >> 16) & 0xFFF](addr, val); - return; - } -/* - case 0x2: - { - // Purge Area - return; - } -*/ - case 0x4: - case 0x6: - // Data Array - DataArrayWriteWord(addr, val); - return; - case 0x7: - { - if (addr >= 0xFFFFFE00) - { - // Onchip modules - addr &= 0x1FF; - OnchipWriteWord(addr, val); - return; - } - else if (addr >= 0xFFFF8000 && addr < 0xFFFFC000) - { - // ??? - } - else - { - // Garbage data - } - return; - } - default: - { - UnhandledMemoryWriteWord(addr, val); - return; - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL MappedMemoryWriteLong(u32 addr, u32 val) -{ - switch (addr >> 29) - { - case 0x0: - case 0x1: - case 0x5: - { - // Cache/Non-Cached - WriteLongList[(addr >> 16) & 0xFFF](addr, val); - return; - } - case 0x2: - { - // Purge Area - return; - } - case 0x3: - { - // Address Array - AddressArrayWriteLong(addr, val); - return; - } - case 0x4: - case 0x6: - // Data Array - DataArrayWriteLong(addr, val); - return; - case 0x7: - { - if (addr >= 0xFFFFFE00) - { - // Onchip modules - addr &= 0x1FF; - OnchipWriteLong(addr, val); - return; - } - else if (addr >= 0xFFFF8000 && addr < 0xFFFFC000) - { - // ??? - } - else - { - // Garbage data - } - return; - } - default: - { - UnhandledMemoryWriteLong(addr, val); - return; - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -int MappedMemoryLoad(const char *filename, u32 addr) -{ - FILE *fp; - u32 filesize; - u8 *buffer; - u32 i; - - if (!filename) - return -1; - - if ((fp = fopen(filename, "rb")) == NULL) - return -1; - - // Calculate file size - fseek(fp, 0, SEEK_END); - filesize = ftell(fp); - fseek(fp, 0, SEEK_SET); - - if ((buffer = (u8 *)malloc(filesize)) == NULL) - { - fclose(fp); - return -2; - } - - fread((void *)buffer, 1, filesize, fp); - fclose(fp); - - for (i = 0; i < filesize; i++) - MappedMemoryWriteByte(addr+i, buffer[i]); - - free(buffer); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int MappedMemorySave(const char *filename, u32 addr, u32 size) -{ - FILE *fp; - u8 *buffer; - u32 i; - - if (!filename) - return -1; - - if ((fp = fopen(filename, "wb")) == NULL) - return -1; - - if ((buffer = (u8 *)malloc(size)) == NULL) - { - fclose(fp); - return -2; - } - - for (i = 0; i < size; i++) - buffer[i] = MappedMemoryReadByte(addr+i); - - fwrite((void *)buffer, 1, size, fp); - fclose(fp); - free(buffer); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void MappedMemoryLoadExec(const char *filename, u32 pc) -{ - char *p; - size_t i; - - if ((p = strrchr(filename, '.'))) - { - p = strdup(p); - for (i = 0; i < strlen(p); i++) - p[i] = toupper(p[i]); - if (strcmp(p, ".COF") == 0 || strcmp(p, ".COFF") == 0) - { - MappedMemoryLoadCoff(filename); - free(p); - return; - } - else if(strcmp(p, ".ELF") == 0) - { - MappedMemoryLoadElf(filename); - free(p); - return; - } - - free(p); - } - - YabauseResetNoLoad(); - - // Setup the vector table area, etc. - YabauseSpeedySetup(); - - MappedMemoryLoad(filename, pc); - SH2GetRegisters(MSH2, &MSH2->regs); - MSH2->regs.PC = pc; - SH2SetRegisters(MSH2, &MSH2->regs); -} - -////////////////////////////////////////////////////////////////////////////// - -int LoadBios(const char *filename) -{ - return T123Load(BiosRom, 0x80000, 2, filename); -} - -////////////////////////////////////////////////////////////////////////////// - -int LoadBackupRam(const char *filename) -{ - return T123Load(BupRam, 0x10000, 1, filename); -} - -////////////////////////////////////////////////////////////////////////////// - -void FormatBackupRam(void *mem, u32 size) -{ - int i, i2; - u32 i3; - u8 header[32] = { - 0xFF, 'B', 0xFF, 'a', 0xFF, 'c', 0xFF, 'k', - 0xFF, 'U', 0xFF, 'p', 0xFF, 'R', 0xFF, 'a', - 0xFF, 'm', 0xFF, ' ', 0xFF, 'F', 0xFF, 'o', - 0xFF, 'r', 0xFF, 'm', 0xFF, 'a', 0xFF, 't' - }; - - // Fill in header - for(i2 = 0; i2 < 4; i2++) - for(i = 0; i < 32; i++) - T1WriteByte(mem, (i2 * 32) + i, header[i]); - - // Clear the rest - for(i3 = 0x80; i3 < size; i3+=2) - { - T1WriteByte(mem, i3, 0xFF); - T1WriteByte(mem, i3+1, 0x00); - } -} - -////////////////////////////////////////////////////////////////////////////// - -// FIXME: Here's a (possibly incomplete) list of data that should be added -// to the next version of the save state file: -// yabsys.DecilineStop (new format) -// yabsys.SH2CycleFrac (new field) -// yabsys.DecilineUSed (new field) -// yabsys.UsecFrac (new field) -// [scsp2.c] It would be nice to redo the format entirely because so -// many fields have changed format/size from the old scsp.c -// [scsp2.c] scsp_clock, scsp_clock_frac, ScspState.sample_timer (timing) -// [scsp2.c] cdda_buf, cdda_next_in, cdda_next_out (CDDA buffer) -// [sh2core.c] frc.div changed to frc.shift -// [sh2core.c] wdt probably needs to be written as well - -int YabSaveState(const char *filename) -{ - u32 i; - FILE *fp; - int offset; - IOCheck_struct check; - u8 *buf; - int totalsize; - int outputwidth; - int outputheight; - int movieposition; - int temp; - u32 temp32; - - check.done = 0; - check.size = 0; - - //use a second set of savestates for movies - filename = MakeMovieStateName(filename); - if (!filename) - return -1; - - if ((fp = fopen(filename, "wb")) == NULL) - return -1; - - // Write signature - fprintf(fp, "YSS"); - - // Write endianness byte -#ifdef WORDS_BIGENDIAN - fputc(0x00, fp); -#else - fputc(0x01, fp); -#endif - - // Write version(fix me) - i = 1;//2; - ywrite(&check, (void *)&i, sizeof(i), 1, fp); - - // Skip the next 4 bytes for now - i = 0; - ywrite(&check, (void *)&i, sizeof(i), 1, fp); - - //write frame number - //ywrite(&check, (void *)&framecounter, 4, 1, fp); - - //this will be updated with the movie position later - //ywrite(&check, (void *)&framecounter, 4, 1, fp); - - // Go through each area and write each state - i += CartSaveState(fp); - i += Cs2SaveState(fp); - i += SH2SaveState(MSH2, fp); - i += SH2SaveState(SSH2, fp); - i += SoundSaveState(fp); - i += ScuSaveState(fp); - i += SmpcSaveState(fp); - i += Vdp1SaveState(fp); - i += Vdp2SaveState(fp); - - offset = StateWriteHeader(fp, "OTHR", 1); - - // Other data - ywrite(&check, (void *)BupRam, 0x10000, 1, fp); // do we really want to save this? - ywrite(&check, (void *)HighWram, 0x100000, 1, fp); - ywrite(&check, (void *)LowWram, 0x100000, 1, fp); - - ywrite(&check, (void *)&yabsys.DecilineCount, sizeof(int), 1, fp); - ywrite(&check, (void *)&yabsys.LineCount, sizeof(int), 1, fp); - ywrite(&check, (void *)&yabsys.VBlankLineCount, sizeof(int), 1, fp); - ywrite(&check, (void *)&yabsys.MaxLineCount, sizeof(int), 1, fp); - temp = yabsys.DecilineStop >> YABSYS_TIMING_BITS; - ywrite(&check, (void *)&temp, sizeof(int), 1, fp); - temp = (yabsys.CurSH2FreqType == CLKTYPE_26MHZ) ? 268 : 286; - ywrite(&check, (void *)&temp, sizeof(int), 1, fp); - //temp32 = (yabsys.UsecFrac * temp / 10) >> YABSYS_TIMING_BITS; - ywrite(&check, (void *)&yabsys.UsecFrac, sizeof(u32), 1, fp); - ywrite(&check, (void *)&yabsys.CurSH2FreqType, sizeof(int), 1, fp); - ywrite(&check, (void *)&yabsys.IsPal, sizeof(int), 1, fp); - /* - VIDCore->GetGlSize(&outputwidth, &outputheight); - - totalsize=outputwidth * outputheight * sizeof(u32); - - if ((buf = (u8 *)malloc(totalsize)) == NULL) - { - return -2; - } - - YuiSwapBuffers(); - #ifdef USE_OPENGL - glPixelZoom(1,1); - glReadBuffer(GL_BACK); - glReadPixels(0, 0, outputwidth, outputheight, GL_RGBA, GL_UNSIGNED_BYTE, buf); - #endif - YuiSwapBuffers(); - - ywrite(&check, (void *)&outputwidth, sizeof(outputwidth), 1, fp); - ywrite(&check, (void *)&outputheight, sizeof(outputheight), 1, fp); - - ywrite(&check, (void *)buf, totalsize, 1, fp); - - movieposition=ftell(fp); - //write the movie to the end of the savestate - SaveMovieInState(fp, check); - */ - i += StateFinishHeader(fp, offset); - /* - // Go back and update size - fseek(fp, 8, SEEK_SET); - ywrite(&check, (void *)&i, sizeof(i), 1, fp); - fseek(fp, 16, SEEK_SET); - ywrite(&check, (void *)&movieposition, sizeof(movieposition), 1, fp); - */ - fclose(fp); - - OSDPushMessage(OSDMSG_STATUS, 150, "STATE SAVED"); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int YabLoadState(const char *filename) -{ - FILE *fp; - char id[3]; - u8 endian; - int headerversion, version, size, chunksize, headersize; - IOCheck_struct check; - u8* buf; - int totalsize; - int outputwidth; - int outputheight; - int curroutputwidth; - int curroutputheight; - int movieposition; - int temp; - u32 temp32; - - filename = MakeMovieStateName(filename); - if (!filename) - return -1; - - if ((fp = fopen(filename, "rb")) == NULL) - return -1; - - headersize = 0xC; - - // Read signature - yread(&check, (void *)id, 1, 3, fp); - - if (strncmp(id, "YSS", 3) != 0) - { - fclose(fp); - return -2; - } - - // Read header - yread(&check, (void *)&endian, 1, 1, fp); - yread(&check, (void *)&headerversion, 4, 1, fp); - yread(&check, (void *)&size, 4, 1, fp); - switch(headerversion) - { - case 1: - /* This is the "original" version of the format */ - break; - case 2: - /* version 2 adds video recording */ - yread(&check, (void *)&framecounter, 4, 1, fp); - movieposition=ftell(fp); - yread(&check, (void *)&movieposition, 4, 1, fp); - headersize = 0x14; - break; - default: - /* we're trying to open a save state using a future version - * of the YSS format, that won't work, sorry :) */ - fclose(fp); - return -3; - break; - } - -#ifdef WORDS_BIGENDIAN - if (endian == 1) -#else - if (endian == 0) -#endif - { - // should setup reading so it's byte-swapped - YabSetError(YAB_ERR_OTHER, (void *)"Load State byteswapping not supported"); - fclose(fp); - return -3; - } - - // Make sure size variable matches actual size minus header - //fseek(fp, 0, SEEK_END); - - //if (size != (ftell(fp) - headersize)) - //{ - // fclose(fp); - // return -2; - //} - //fseek(fp, headersize, SEEK_SET); - - // Verify version here - - ScspMuteAudio(SCSP_MUTE_SYSTEM); - - if (StateCheckRetrieveHeader(fp, "CART", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - CartLoadState(fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "CS2 ", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - Cs2LoadState(fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "MSH2", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - SH2LoadState(MSH2, fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "SSH2", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - SH2LoadState(SSH2, fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "SCSP", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - SoundLoadState(fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "SCU ", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - ScuLoadState(fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "SMPC", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - SmpcLoadState(fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "VDP1", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - Vdp1LoadState(fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "VDP2", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - Vdp2LoadState(fp, version, chunksize); - - if (StateCheckRetrieveHeader(fp, "OTHR", &version, &chunksize) != 0) - { - fclose(fp); - // Revert back to old state here - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - return -3; - } - // Other data - yread(&check, (void *)BupRam, 0x10000, 1, fp); - yread(&check, (void *)HighWram, 0x100000, 1, fp); - yread(&check, (void *)LowWram, 0x100000, 1, fp); - - yread(&check, (void *)&yabsys.DecilineCount, sizeof(int), 1, fp); - yread(&check, (void *)&yabsys.LineCount, sizeof(int), 1, fp); - yread(&check, (void *)&yabsys.VBlankLineCount, sizeof(int), 1, fp); - yread(&check, (void *)&yabsys.MaxLineCount, sizeof(int), 1, fp); - yread(&check, (void *)&temp, sizeof(int), 1, fp); - yread(&check, (void *)&temp, sizeof(int), 1, fp); - yread(&check, (void *)&yabsys.UsecFrac, sizeof(u32), 1, fp); - yread(&check, (void *)&yabsys.CurSH2FreqType, sizeof(int), 1, fp); - yread(&check, (void *)&yabsys.IsPal, sizeof(int), 1, fp); - //YabauseChangeTiming(yabsys.CurSH2FreqType); - //yabsys.UsecFrac = (temp32 << YABSYS_TIMING_BITS) * temp / 10; - - /* - if (headerversion > 1) { - - yread(&check, (void *)&outputwidth, sizeof(outputwidth), 1, fp); - yread(&check, (void *)&outputheight, sizeof(outputheight), 1, fp); - - totalsize=outputwidth * outputheight * sizeof(u32); - - if ((buf = (u8 *)malloc(totalsize)) == NULL) - { - return -2; - } - - yread(&check, (void *)buf, totalsize, 1, fp); - - YuiSwapBuffers(); - - #ifdef USE_OPENGL - if(VIDCore->id == VIDCORE_SOFT) - glRasterPos2i(0, outputheight); - if(VIDCore->id == VIDCORE_OGL) - glRasterPos2i(0, outputheight/2); - #endif - - VIDCore->GetGlSize(&curroutputwidth, &curroutputheight); - #ifdef USE_OPENGL - glPixelZoom((float)curroutputwidth / (float)outputwidth, ((float)curroutputheight / (float)outputheight)); - glDrawPixels(outputwidth, outputheight, GL_RGBA, GL_UNSIGNED_BYTE, buf); - #endif - YuiSwapBuffers(); - - fseek(fp, movieposition, SEEK_SET); - MovieReadState(fp, filename); - } - */ - fclose(fp); - - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - - OSDPushMessage(OSDMSG_STATUS, 150, "STATE LOADED"); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int YabSaveStateSlot(const char *dirpath, u8 slot) -{ - char filename[512]; - - if (cdip == NULL) - return -1; - -#ifdef WIN32 - sprintf(filename, "%s\\%s_%03d.yss", dirpath, cdip->itemnum, slot); -#else - sprintf(filename, "%s/%s_%03d.yss", dirpath, cdip->itemnum, slot); -#endif - return YabSaveState(filename); -} - -////////////////////////////////////////////////////////////////////////////// - -int YabLoadStateSlot(const char *dirpath, u8 slot) -{ - char filename[512]; - - if (cdip == NULL) - return -1; - -#ifdef WIN32 - sprintf(filename, "%s\\%s_%03d.yss", dirpath, cdip->itemnum, slot); -#else - sprintf(filename, "%s/%s_%03d.yss", dirpath, cdip->itemnum, slot); -#endif - return YabLoadState(filename); -} - -////////////////////////////////////////////////////////////////////////////// - -static int MappedMemoryAddMatch(u32 addr, u32 val, int searchtype, result_struct *result, u32 *numresults) -{ - result[numresults[0]].addr = addr; - result[numresults[0]].val = val; - numresults[0]++; - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static INLINE int SearchIncrementAndCheckBounds(result_struct *prevresults, - u32 *maxresults, - u32 numresults, u32 *i, - u32 inc, u32 *newaddr, - u32 endaddr) -{ - if (prevresults) - { - if (i[0] >= maxresults[0]) - { - maxresults[0] = numresults; - return 1; - } - newaddr[0] = prevresults[i[0]].addr; - i[0]++; - } - else - { - newaddr[0] = inc; - - if (newaddr[0] > endaddr || numresults >= maxresults[0]) - { - maxresults[0] = numresults; - return 1; - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int SearchString(u32 startaddr, u32 endaddr, int searchtype, - const char *searchstr, result_struct *results, - u32 *maxresults) -{ - u8 *buf=NULL; - u32 *buf32=NULL; - u32 buflen=0; - u32 counter; - u32 addr; - u32 numresults=0; - - buflen=(u32)strlen(searchstr); - - if ((buf32=(u32 *)malloc(buflen*sizeof(u32))) == NULL) - return 0; - - buf = (u8 *)buf32; - - // Copy string to buffer - switch (searchtype & 0x70) - { - case SEARCHSTRING: - strcpy((char *)buf, searchstr); - break; - case SEARCHREL8BIT: - case SEARCHREL16BIT: - { - char *text; - char *searchtext=strdup(searchstr); - - // Calculate buffer length and read values into table - buflen = 0; - for (text=strtok((char *)searchtext, " ,"); text != NULL; text=strtok(NULL, " ,")) - { - buf32[buflen] = strtoul(text, NULL, 0); - buflen++; - } - free(searchtext); - - break; - } - } - - addr = startaddr; - counter = 0; - - for (;;) - { - // Fetch byte/word/etc. - switch (searchtype & 0x70) - { - case SEARCHSTRING: - { - u8 val = MappedMemoryReadByte(addr); - addr++; - - if (val == buf[counter]) - { - counter++; - if (counter == buflen) - MappedMemoryAddMatch(addr-buflen, val, searchtype, results, &numresults); - } - else - counter = 0; - break; - } - case SEARCHREL8BIT: - { - int diff; - u32 j; - u8 val2; - u8 val = MappedMemoryReadByte(addr); - - for (j = 1; j < buflen; j++) - { - // grab the next value - val2 = MappedMemoryReadByte(addr+j); - - // figure out the diff - diff = (int)val2 - (int)val; - - // see if there's a match - if (((int)buf32[j] - (int)buf32[j-1]) != diff) - break; - - if (j == (buflen - 1)) - MappedMemoryAddMatch(addr, val, searchtype, results, &numresults); - - val = val2; - } - - addr++; - - break; - } - case SEARCHREL16BIT: - { - int diff; - u32 j; - u16 val2; - u16 val = MappedMemoryReadWord(addr); - - for (j = 1; j < buflen; j++) - { - // grab the next value - val2 = MappedMemoryReadWord(addr+(j*2)); - - // figure out the diff - diff = (int)val2 - (int)val; - - // see if there's a match - if (((int)buf32[j] - (int)buf32[j-1]) != diff) - break; - - if (j == (buflen - 1)) - MappedMemoryAddMatch(addr, val, searchtype, results, &numresults); - - val = val2; - } - - addr+=2; - break; - } - } - - if (addr > endaddr || numresults >= maxresults[0]) - break; - } - - free(buf); - maxresults[0] = numresults; - return 1; -} - -////////////////////////////////////////////////////////////////////////////// - -result_struct *MappedMemorySearch(u32 startaddr, u32 endaddr, int searchtype, - const char *searchstr, - result_struct *prevresults, u32 *maxresults) -{ - u32 i=0; - result_struct *results; - u32 numresults=0; - unsigned long searchval; - int issigned=0; - u32 addr; - - if ((results = (result_struct *)malloc(sizeof(result_struct) * maxresults[0])) == NULL) - return NULL; - - switch (searchtype & 0x70) - { - case SEARCHSTRING: - case SEARCHREL8BIT: - case SEARCHREL16BIT: - { - // String/8-bit relative/16-bit relative search(not supported, yet) - if (SearchString(startaddr, endaddr, searchtype, searchstr, - results, maxresults) == 0) - { - maxresults[0] = 0; - free(results); - return NULL; - } - - return results; - } - case SEARCHHEX: - sscanf(searchstr, "%08lx", &searchval); - break; - case SEARCHUNSIGNED: - searchval = (unsigned long)atoi(searchstr); - issigned = 0; - break; - case SEARCHSIGNED: - searchval = (unsigned long)atoi(searchstr); - issigned = 1; - break; - } - - if (prevresults) - { - addr = prevresults[i].addr; - i++; - } - else - addr = startaddr; - - // Regular value search - for (;;) - { - u32 val=0; - u32 newaddr; - - // Fetch byte/word/etc. - switch (searchtype & 0x3) - { - case SEARCHBYTE: - val = MappedMemoryReadByte(addr); - // sign extend if neccessary - if (issigned) - val = (s8)val; - - if (SearchIncrementAndCheckBounds(prevresults, maxresults, numresults, &i, addr+1, &newaddr, endaddr)) - return results; - break; - case SEARCHWORD: - val = MappedMemoryReadWord(addr); - // sign extend if neccessary - if (issigned) - val = (s16)val; - - if (SearchIncrementAndCheckBounds(prevresults, maxresults, numresults, &i, addr+2, &newaddr, endaddr)) - return results; - break; - case SEARCHLONG: - val = MappedMemoryReadLong(addr); - - if (SearchIncrementAndCheckBounds(prevresults, maxresults, numresults, &i, addr+4, &newaddr, endaddr)) - return results; - break; - default: - maxresults[0] = 0; - if (results) - free(results); - return NULL; - } - - // Do a comparison - switch (searchtype & 0xC) - { - case SEARCHEXACT: - if (val == searchval) - MappedMemoryAddMatch(addr, val, searchtype, results, &numresults); - break; - case SEARCHLESSTHAN: - if ((!issigned && val < searchval) || (issigned && (signed)val < (signed)searchval)) - MappedMemoryAddMatch(addr, val, searchtype, results, &numresults); - break; - case SEARCHGREATERTHAN: - if ((!issigned && val > searchval) || (issigned && (signed)val > (signed)searchval)) - MappedMemoryAddMatch(addr, val, searchtype, results, &numresults); - break; - default: - maxresults[0] = 0; - if (results) - free(results); - return NULL; - } - - addr = newaddr; - } - - maxresults[0] = numresults; - return results; -} diff --git a/yabause/src/memory.h b/yabause/src/memory.h deleted file mode 100644 index 7cab523ea7..0000000000 --- a/yabause/src/memory.h +++ /dev/null @@ -1,409 +0,0 @@ -/* Copyright 2005-2006 Guillaume Duhamel - Copyright 2005 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef MEMORY_H -#define MEMORY_H - -#include -#include "core.h" - -/* Type 1 Memory, faster for byte (8 bits) accesses */ - -u8 * T1MemoryInit(u32); -void T1MemoryDeInit(u8 *); - -static INLINE u8 T1ReadByte(u8 * mem, u32 addr) -{ - return mem[addr]; -} - -static INLINE u16 T1ReadWord(u8 * mem, u32 addr) -{ -#ifdef WORDS_BIGENDIAN - return *((u16 *) (mem + addr)); -#else - return BSWAP16(*((u16 *) (mem + addr))); -#endif -} - -static INLINE u32 T1ReadLong(u8 * mem, u32 addr) -{ -#ifdef WORDS_BIGENDIAN - return *((u32 *) (mem + addr)); -#else - return BSWAP32(*((u32 *) (mem + addr))); -#endif -} - -static INLINE void T1WriteByte(u8 * mem, u32 addr, u8 val) -{ - mem[addr] = val; -} - -static INLINE void T1WriteWord(u8 * mem, u32 addr, u16 val) -{ -#ifdef WORDS_BIGENDIAN - *((u16 *) (mem + addr)) = val; -#else - *((u16 *) (mem + addr)) = BSWAP16(val); -#endif -} - -static INLINE void T1WriteLong(u8 * mem, u32 addr, u32 val) -{ -#ifdef WORDS_BIGENDIAN - *((u32 *) (mem + addr)) = val; -#else - *((u32 *) (mem + addr)) = BSWAP32(val); -#endif -} - -/* Type 2 Memory, faster for word (16 bits) accesses */ - -#define T2MemoryInit(x) (T1MemoryInit(x)) -#define T2MemoryDeInit(x) (T1MemoryDeInit(x)) - -static INLINE u8 T2ReadByte(u8 * mem, u32 addr) -{ -#ifdef WORDS_BIGENDIAN - return mem[addr]; -#else - return mem[addr ^ 1]; -#endif -} - -static INLINE u16 T2ReadWord(u8 * mem, u32 addr) -{ - return *((u16 *) (mem + addr)); -} - -static INLINE u32 T2ReadLong(u8 * mem, u32 addr) -{ -#ifdef WORDS_BIGENDIAN - return *((u32 *) (mem + addr)); -#else - return WSWAP32(*((u32 *) (mem + addr))); -#endif -} - -static INLINE void T2WriteByte(u8 * mem, u32 addr, u8 val) -{ -#ifdef WORDS_BIGENDIAN - mem[addr] = val; -#else - mem[addr ^ 1] = val; -#endif -} - -static INLINE void T2WriteWord(u8 * mem, u32 addr, u16 val) -{ - *((u16 *) (mem + addr)) = val; -} - -static INLINE void T2WriteLong(u8 * mem, u32 addr, u32 val) -{ -#ifdef WORDS_BIGENDIAN - *((u32 *) (mem + addr)) = val; -#else - *((u32 *) (mem + addr)) = WSWAP32(val); -#endif -} - -/* Type 3 Memory, faster for long (32 bits) accesses */ - -typedef struct -{ - u8 * base_mem; - u8 * mem; -} T3Memory; - -T3Memory * T3MemoryInit(u32); -void T3MemoryDeInit(T3Memory *); - -static INLINE u8 T3ReadByte(T3Memory * mem, u32 addr) -{ -#ifdef WORDS_BIGENDIAN - return mem->mem[addr]; -#else - return (mem->mem - addr - 1)[0]; -#endif -} - -static INLINE u16 T3ReadWord(T3Memory * mem, u32 addr) -{ -#ifdef WORDS_BIGENDIAN - return *((u16 *) (mem->mem + addr)); -#else - return ((u16 *) (mem->mem - addr - 2))[0]; -#endif -} - -static INLINE u32 T3ReadLong(T3Memory * mem, u32 addr) -{ -#ifdef WORDS_BIGENDIAN - return *((u32 *) (mem->mem + addr)); -#else - return ((u32 *) (mem->mem - addr - 4))[0]; -#endif -} - -static INLINE void T3WriteByte(T3Memory * mem, u32 addr, u8 val) -{ -#ifdef WORDS_BIGENDIAN - mem->mem[addr] = val; -#else - (mem->mem - addr - 1)[0] = val; -#endif -} - -static INLINE void T3WriteWord(T3Memory * mem, u32 addr, u16 val) -{ -#ifdef WORDS_BIGENDIAN - *((u16 *) (mem->mem + addr)) = val; -#else - ((u16 *) (mem->mem - addr - 2))[0] = val; -#endif -} - -static INLINE void T3WriteLong(T3Memory * mem, u32 addr, u32 val) -{ -#ifdef WORDS_BIGENDIAN - *((u32 *) (mem->mem + addr)) = val; -#else - ((u32 *) (mem->mem - addr - 4))[0] = val; -#endif -} - -static INLINE int T123Load(void * mem, u32 size, int type, const char *filename) -{ - FILE *fp; - u32 filesizecheck; - u8 *buffer; - u32 i; - - if (!filename) - return -1; - - if ((fp = fopen(filename, "rb")) == NULL) - return -1; - - // Calculate file size - //fseek(fp, 0, SEEK_END); - //filesize = ftell(fp); - //fseek(fp, 0, SEEK_SET); - - //if (filesize > size) - // return -1; - - if ((buffer = (u8 *)malloc(size)) == NULL) - { - fclose(fp); - return -1; - } - - filesizecheck = (u32)fread((void *)buffer, 1, size, fp); - // make sure there are no bytes left in the file - if (filesizecheck != size || fgetc(fp) != EOF) - { - free(buffer); - fclose(fp); - return -1; - } - - fclose(fp); - - switch (type) - { - case 1: - { - for (i = 0; i < size; i++) - T1WriteByte((u8 *) mem, i, buffer[i]); - break; - } - case 2: - { - for (i = 0; i < size; i++) - T2WriteByte((u8 *) mem, i, buffer[i]); - break; - } - case 3: - { - for (i = 0; i < size; i++) - T3WriteByte((T3Memory *) mem, i, buffer[i]); - break; - } - default: - { - free(buffer); - return -1; - } - } - - free(buffer); - - return 0; -} - -static INLINE int T123Save(void * mem, u32 size, int type, const char *filename) -{ - FILE *fp; - u8 *buffer; - u32 i; - u32 sizecheck; - - if (filename == NULL) - return 0; - - if (filename[0] == 0x00) - return 0; - - if ((buffer = (u8 *)malloc(size)) == NULL) - return -1; - - switch (type) - { - case 1: - { - for (i = 0; i < size; i++) - buffer[i] = T1ReadByte((u8 *) mem, i); - break; - } - case 2: - { - for (i = 0; i < size; i++) - buffer[i] = T2ReadByte((u8 *) mem, i); - break; - } - case 3: - { - for (i = 0; i < size; i++) - buffer[i] = T3ReadByte((T3Memory *) mem, i); - break; - } - default: - { - free(buffer); - return -1; - } - } - - if ((fp = fopen(filename, "wb")) == NULL) - { - free(buffer); - return -1; - } - - sizecheck = (u32)fwrite((void *)buffer, 1, size, fp); - fclose(fp); - free(buffer); - - if (sizecheck != size) return -1; - - return 0; -} - -/* Dummy memory, always returns 0 */ - -typedef void Dummy; - -Dummy * DummyInit(u32); -void DummyDeInit(Dummy *); - -static INLINE u8 DummyReadByte(Dummy UNUSED * d, u32 UNUSED a) { return 0; } -static INLINE u16 DummyReadWord(Dummy UNUSED * d, u32 UNUSED a) { return 0; } -static INLINE u32 DummyReadLong(Dummy UNUSED * d, u32 UNUSED a) { return 0; } - -static INLINE void DummyWriteByte(Dummy UNUSED * d, u32 UNUSED a, u8 UNUSED v) {} -static INLINE void DummyWriteWord(Dummy UNUSED * d, u32 UNUSED a, u16 UNUSED v) {} -static INLINE void DummyWriteLong(Dummy UNUSED * d, u32 UNUSED a, u32 UNUSED v) {} - -void MappedMemoryInit(void); -u8 FASTCALL MappedMemoryReadByte(u32 addr); -u16 FASTCALL MappedMemoryReadWord(u32 addr); -u32 FASTCALL MappedMemoryReadLong(u32 addr); -void FASTCALL MappedMemoryWriteByte(u32 addr, u8 val); -void FASTCALL MappedMemoryWriteWord(u32 addr, u16 val); -void FASTCALL MappedMemoryWriteLong(u32 addr, u32 val); -#ifdef __cplusplus -extern "C" { -#endif -extern u8 *HighWram; -#ifdef __cplusplus -} -#endif -extern u8 *LowWram; -extern u8 *BiosRom; -extern u8 *BupRam; -extern u8 BupRamWritten; - -typedef void (FASTCALL *writebytefunc)(u32, u8); -typedef void (FASTCALL *writewordfunc)(u32, u16); -typedef void (FASTCALL *writelongfunc)(u32, u32); - -typedef u8 (FASTCALL *readbytefunc)(u32); -typedef u16 (FASTCALL *readwordfunc)(u32); -typedef u32 (FASTCALL *readlongfunc)(u32); - -extern writebytefunc WriteByteList[0x1000]; -extern writewordfunc WriteWordList[0x1000]; -extern writelongfunc WriteLongList[0x1000]; - -extern readbytefunc ReadByteList[0x1000]; -extern readwordfunc ReadWordList[0x1000]; -extern readlongfunc ReadLongList[0x1000]; - -typedef struct { -u32 addr; -u32 val; -} result_struct; - -#define SEARCHBYTE 0 -#define SEARCHWORD 1 -#define SEARCHLONG 2 - -#define SEARCHEXACT (0 << 2) -#define SEARCHLESSTHAN (1 << 2) -#define SEARCHGREATERTHAN (2 << 2) - -#define SEARCHUNSIGNED (0 << 4) -#define SEARCHSIGNED (1 << 4) -#define SEARCHHEX (2 << 4) -#define SEARCHSTRING (3 << 4) -#define SEARCHREL8BIT (6 << 4) -#define SEARCHREL16BIT (7 << 4) - -result_struct *MappedMemorySearch(u32 startaddr, u32 endaddr, int searchtype, - const char *searchstr, - result_struct *prevresults, u32 *maxresults); - -int MappedMemoryLoad(const char *filename, u32 addr); -int MappedMemorySave(const char *filename, u32 addr, u32 size); -void MappedMemoryLoadExec(const char *filename, u32 pc); - -int LoadBios(const char *filename); -int LoadBackupRam(const char *filename); -void FormatBackupRam(void *mem, u32 size); - -int YabSaveState(const char *filename); -int YabLoadState(const char *filename); -int YabSaveStateSlot(const char *dirpath, u8 slot); -int YabLoadStateSlot(const char *dirpath, u8 slot); - -#endif diff --git a/yabause/src/movie.c b/yabause/src/movie.c deleted file mode 100644 index 5ca936c116..0000000000 --- a/yabause/src/movie.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#include "peripheral.h" -#include "scsp.h" -#include "movie.h" -#include "cs2.h" -#include "vdp2.h" // for DisplayMessage() prototype -#include "yabause.h" - -int RecordingFileOpened; -int PlaybackFileOpened; - -struct MovieStruct Movie; - -char MovieStatus[40]; -int movieLoaded = 0; //Boolean value, 1 if a movie is playing or recording - -//Counting -int framecounter; -int lagframecounter; -int LagFrameFlag; -int FrameAdvanceVariable=0; - -int headersize=512; - -////////////////////////////////////////////////////////////////////////////// - -static void ReadHeader(FILE* fp) { - - fseek(fp, 0, SEEK_SET); - - fseek(fp, 172, SEEK_SET); - fread(&Movie.Rerecords, sizeof(Movie.Rerecords), 1, fp); - - fseek(fp, headersize, SEEK_SET); -} - -////////////////////////////////////////////////////////////////////////////// - -static void WriteHeader(FILE* fp) { - - fseek(fp, 0, SEEK_SET); - - fwrite("YMV", sizeof("YMV"), 1, fp); - fwrite(VERSION, sizeof(VERSION), 1, fp); - fwrite(cdip->cdinfo, sizeof(cdip->cdinfo), 1, fp); - fwrite(cdip->itemnum, sizeof(cdip->itemnum), 1, fp); - fwrite(cdip->version, sizeof(cdip->version), 1, fp); - fwrite(cdip->date, sizeof(cdip->date), 1, fp); - fwrite(cdip->gamename, sizeof(cdip->gamename), 1, fp); - fwrite(cdip->region, sizeof(cdip->region), 1, fp); - fwrite(&Movie.Rerecords, sizeof(Movie.Rerecords), 1, fp); - fwrite(&yabsys.emulatebios, sizeof(yabsys.emulatebios), 1, fp); - fwrite(&yabsys.IsPal, sizeof(yabsys.IsPal), 1, fp); - - fseek(fp, headersize, SEEK_SET); -} - -////////////////////////////////////////////////////////////////////////////// - -static void ClearInput(void) { - - //do something.... -} - -////////////////////////////////////////////////////////////////////////////// - -const char* Buttons[8] = {"B", "C", "A", "S", "U", "D", "R", "L"}; -const char* Spaces[8] = {" ", " ", " ", " ", " ", " ", " ", " "}; -const char* Buttons2[8] = {"", "", "", "L", "Z", "Y", "X", "R"}; -const char* Spaces2[8] = {"", "", "", " ", " ", " ", " ", " "}; - -char str[40]; -char InputDisplayString[40]; - -static void SetInputDisplayCharacters(void) { - - int x; - - strcpy(str, ""); - - for (x = 0; x < 8; x++) { - - if(PORTDATA1.data[2] & (1 << x)) { - strcat(str, Spaces[x]); - } - else - strcat(str, Buttons[x]); - - } - - for (x = 0; x < 8; x++) { - - if(PORTDATA1.data[3] & (1 << x)) { - strcat(str, Spaces2[x]); - } - else - strcat(str, Buttons2[x]); - - } - - strcpy(InputDisplayString, str); -} - -////////////////////////////////////////////////////////////////////////////// - -static void IncrementLagAndFrameCounter(void) -{ - if(LagFrameFlag == 1) - lagframecounter++; - - framecounter++; -} - -////////////////////////////////////////////////////////////////////////////// - -int framelength=16; - -void DoMovie(void) { - - int x; - - IncrementLagAndFrameCounter(); - LagFrameFlag=1; - SetInputDisplayCharacters(); - - //Read/Write Controller Data - if(Movie.Status == Recording) { - for (x = 0; x < 8; x++) { - fwrite(&PORTDATA1.data[x], 1, 1, Movie.fp); - } - for (x = 0; x < 8; x++) { - fwrite(&PORTDATA2.data[x], 1, 1, Movie.fp); - } - } - - if(Movie.Status == Playback) { - for (x = 0; x < 8; x++) { - fread(&PORTDATA1.data[x], 1, 1, Movie.fp); - } - for (x = 0; x < 8; x++) { - fread(&PORTDATA2.data[x], 1, 1, Movie.fp); - } - - //if we get to the end of the movie - if(((ftell(Movie.fp)-headersize)/framelength) >= Movie.Frames) { - fclose(Movie.fp); - PlaybackFileOpened=0; - Movie.Status = Stopped; - ClearInput(); - strcpy(MovieStatus, "Playback Stopped"); - } - } - - //Stop Recording/Playback - if(Movie.Status != Recording && RecordingFileOpened) { - fclose(Movie.fp); - RecordingFileOpened=0; - Movie.Status = Stopped; - strcpy(MovieStatus, "Recording Stopped"); - } - - if(Movie.Status != Playback && PlaybackFileOpened && Movie.ReadOnly != 0) { - fclose(Movie.fp); - PlaybackFileOpened=0; - Movie.Status = Stopped; - strcpy(MovieStatus, "Playback Stopped"); - } -} - -////////////////////////////////////////////////////////////////////////////// - -void MovieLoadState(const char * filename) { - - - if (Movie.ReadOnly == 1 && Movie.Status == Playback) { - //Movie.Status = Playback; - fseek (Movie.fp,headersize+(framecounter * framelength),SEEK_SET); - } - - if(Movie.Status == Recording) { - fseek (Movie.fp,headersize+(framecounter * framelength),SEEK_SET); - Movie.Rerecords++; - } - - if(Movie.Status == Playback && Movie.ReadOnly == 0) { - Movie.Status = Recording; - RecordingFileOpened=1; - strcpy(MovieStatus, "Recording Resumed"); - TruncateMovie(Movie); - fseek (Movie.fp,headersize+(framecounter * framelength),SEEK_SET); - Movie.Rerecords++; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void TruncateMovie(struct MovieStruct Movie) { - - //when we resume recording, shorten the movie so that there isn't - //potential garbage data at the end - -/*//TODO - struct MovieBufferStruct tempbuffer; - fseek(Movie.fp,0,SEEK_SET); - tempbuffer=ReadMovieIntoABuffer(Movie.fp); - fclose(Movie.fp); - - //clear the file and write it again - Movie.fp=fopen(Movie.filename,"wb"); - fwrite(tempbuffer.data,framelength,framecounter,Movie.fp); - fclose(Movie.fp); - - Movie.fp=fopen(Movie.filename,"r+b"); -*/ -} - -////////////////////////////////////////////////////////////////////////////// - -static int MovieGetSize(FILE* fp) { - int size; - int fpos; - - fpos = ftell(fp);//save current pos - - fseek (fp,0,SEEK_END); - size=ftell(fp); - - Movie.Frames=(size-headersize)/ framelength; - - fseek(fp, fpos, SEEK_SET); //reset back to correct pos - return(size); -} - -////////////////////////////////////////////////////////////////////////////// - -void MovieToggleReadOnly(void) { - - if(Movie.Status == Playback) { - - if(Movie.ReadOnly == 1) - { - Movie.ReadOnly=0; - DisplayMessage("Movie is now read+write."); - } - else - { - Movie.ReadOnly=1; - DisplayMessage("Movie is now read only."); - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -void StopMovie(void) { - - if(Movie.Status == Recording && RecordingFileOpened) { - WriteHeader(Movie.fp); - fclose(Movie.fp); - RecordingFileOpened=0; - Movie.Status = Stopped; - ClearInput(); - strcpy(MovieStatus, "Recording Stopped"); - } - - if(Movie.Status == Playback && PlaybackFileOpened && Movie.ReadOnly != 0) { - fclose(Movie.fp); - PlaybackFileOpened=0; - Movie.Status = Stopped; - ClearInput(); - strcpy(MovieStatus, "Playback Stopped"); - } -} - -////////////////////////////////////////////////////////////////////////////// - -int SaveMovie(const char *filename) { - - char* str=malloc(1024); - - if(Movie.Status == Playback) - StopMovie(); - - if ((Movie.fp = fopen(filename, "w+b")) == NULL) - return -1; - - strcpy(str, filename); - Movie.filename=str; - RecordingFileOpened=1; - framecounter=0; - Movie.Status=Recording; - strcpy(MovieStatus, "Recording Started"); - Movie.Rerecords=0; - WriteHeader(Movie.fp); - YabauseReset(); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -int PlayMovie(const char *filename) { - - char* str=malloc(1024); - - if(Movie.Status == Recording) - StopMovie(); - - - if ((Movie.fp = fopen(filename, "r+b")) == NULL) - return -1; - - strcpy(str, filename); - Movie.filename=str; - PlaybackFileOpened=1; - framecounter=0; - Movie.ReadOnly = 1; - Movie.Status=Playback; - Movie.Size = MovieGetSize(Movie.fp); - strcpy(MovieStatus, "Playback Started"); - ReadHeader(Movie.fp); - YabauseReset(); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void SaveMovieInState(FILE* fp, IOCheck_struct check) { - - struct MovieBufferStruct tempbuffer; - - fseek(fp, 0, SEEK_END); - - if(Movie.Status == Recording || Movie.Status == Playback) { - tempbuffer=ReadMovieIntoABuffer(Movie.fp); - - fwrite(&tempbuffer.size, 4, 1, fp); - fwrite(tempbuffer.data, tempbuffer.size, 1, fp); - } -} - -////////////////////////////////////////////////////////////////////////////// - -void MovieReadState(FILE* fp, const char * filename) { - - ReadMovieInState(fp); - MovieLoadState(filename);//file pointer and truncation - -} - -void ReadMovieInState(FILE* fp) { - - struct MovieBufferStruct tempbuffer; - int fpos; - - //overwrite the main movie on disk if we are recording or read+write playback - if(Movie.Status == Recording || (Movie.Status == Playback && Movie.ReadOnly == 0)) { - - fpos=ftell(fp);//where we are in the savestate - fread(&tempbuffer.size, 4, 1, fp);//size - if ((tempbuffer.data = (char *)malloc(tempbuffer.size)) == NULL) - { - return; - } - fread(tempbuffer.data, 1, tempbuffer.size, fp);//movie - fseek(fp, fpos, SEEK_SET);//reset savestate position - - rewind(Movie.fp); - fwrite(tempbuffer.data, 1, tempbuffer.size, Movie.fp); - rewind(Movie.fp); - } -} - -////////////////////////////////////////////////////////////////////////////// - -struct MovieBufferStruct ReadMovieIntoABuffer(FILE* fp) { - - int fpos; - struct MovieBufferStruct tempbuffer; - - fpos = ftell(fp);//save current pos - - fseek (fp,0,SEEK_END); - tempbuffer.size=ftell(fp); //get size - rewind(fp); - - tempbuffer.data = (char*) malloc (sizeof(char)*tempbuffer.size); - fread (tempbuffer.data, 1, tempbuffer.size, fp); - - fseek(fp, fpos, SEEK_SET); //reset back to correct pos - return(tempbuffer); -} - -////////////////////////////////////////////////////////////////////////////// - -const char *MakeMovieStateName(const char *filename) { - - static char *retbuf = NULL; // Save the pointer to avoid memory leaks - if(Movie.Status == Recording || Movie.Status == Playback) { - const unsigned long newsize = strlen(filename) + 5 + 1; - free(retbuf); - retbuf = malloc(newsize); - if (!retbuf) { - return NULL; // out of memory - } - sprintf(retbuf, "%smovie", filename); - return retbuf; - } else { - return filename; // unchanged - } - -} - -////////////////////////////////////////////////////////////////////////////// - -//debugging only -void TestWrite(struct MovieBufferStruct tempbuffer) { - - FILE* tempbuffertest; - - tempbuffertest=fopen("rmiab.txt", "wb"); - fwrite (tempbuffer.data, 1, tempbuffer.size, tempbuffertest); - fclose(tempbuffertest); -} - -////////////////////////////////////////////////////////////////////////////// - -void PauseOrUnpause(void) { - - if(FrameAdvanceVariable == RunNormal) { - FrameAdvanceVariable=Paused; - ScspMuteAudio(SCSP_MUTE_SYSTEM); - } - else { - FrameAdvanceVariable=RunNormal; - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - } -} - -////////////////////////////////////////////////////////////////////////////// - -int IsMovieLoaded(void) -{ - if (RecordingFileOpened || PlaybackFileOpened) - return 1; - else - return 0; -} - -////////////////////////////////////////////////////////////////////////////// diff --git a/yabause/src/movie.h b/yabause/src/movie.h deleted file mode 100644 index ccb70f54cb..0000000000 --- a/yabause/src/movie.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef MOVIE_H -#define MOVIE_H - -#include "core.h" - -#define Stopped 1 -#define Recording 2 -#define Playback 3 - -#define RunNormal 0 -#define Paused 1 -#define NeedAdvance 2 - -void DoMovie(void); - -struct MovieStruct -{ - int Status; - FILE *fp; - int ReadOnly; - int Rerecords; - int Size; - int Frames; - const char* filename; -}; - -extern struct MovieStruct Movie; - -struct MovieBufferStruct -{ - int size; - char* data; -}; - -struct MovieBufferStruct ReadMovieIntoABuffer(FILE* fp); - -void MovieLoadState(const char * filename); - -void SaveMovieInState(FILE* fp, IOCheck_struct check); -void ReadMovieInState(FILE* fp); - -void TestWrite(struct MovieBufferStruct tempbuffer); - -void MovieToggleReadOnly(void); - -void TruncateMovie(struct MovieStruct Movie); - -void DoFrameAdvance(void); - -int SaveMovie(const char *filename); -int PlayMovie(const char *filename); -void StopMovie(void); - -const char *MakeMovieStateName(const char *filename); - -void MovieReadState(FILE* fp, const char * filename); - -void PauseOrUnpause(void); - -int IsMovieLoaded(void); - -extern int framecounter; -extern int LagFrameFlag; -extern int lagframecounter; -extern char MovieStatus[40]; -extern char InputDisplayString[40]; -extern int FrameAdvanceVariable; -#endif diff --git a/yabause/src/netlink.c b/yabause/src/netlink.c deleted file mode 100644 index 5d857fab85..0000000000 --- a/yabause/src/netlink.c +++ /dev/null @@ -1,854 +0,0 @@ -/* Copyright 2006 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifdef USESOCKET -#ifdef __MINGW32__ -// I blame mingw for this -#define _WIN32_WINNT 0x501 -#endif -#endif - -#include -#ifdef USESOCKET -#ifdef WIN32 -#include -#include -#else -#include -#include -#include -#include -#include -#include -#endif -#endif -#include "cs2.h" -#include "error.h" -#include "netlink.h" -#include "debug.h" -#include "scu.h" - -Netlink *NetlinkArea = NULL; - -#define NL_RESULTCODE_OK 0 -#define NL_RESULTCODE_CONNECT 1 -#define NL_RESULTCODE_RING 2 -#define NL_RESULTCODE_NOCARRIER 3 -#define NL_RESULTCODE_ERROR 4 -#define NL_RESULTCODE_CONNECT1200 5 -#define NL_RESULTCODE_NODIALTONE 6 -#define NL_RESULTCODE_BUSY 7 -#define NL_RESULTCODE_NOANSWER 8 - -#define CONNECTTYPE_SERVER 0 -#define CONNECTTYPE_CLIENT 1 - -#define CONNECTSTATUS_IDLE 0 -#define CONNECTSTATUS_WAIT 1 -#define CONNECTSTATUS_CONNECT 2 -#define CONNECTSTATUS_CONNECTED 3 - -#define MODEMSTATE_COMMAND 0 -#define MODEMSTATE_ONLINE 1 - -#ifdef USESOCKET -static int NetworkInit(void); -static void NetworkDeInit(void); -static int NetworkConnect(const char *ip, const char *port); -static int NetworkWaitForConnect(const char *port); -static int NetworkSend(const void *buffer, int length); -static int NetworkReceive(void *buffer, int maxlength); - -#ifndef WIN32 -#define closesocket close -#endif -#endif - -////////////////////////////////////////////////////////////////////////////// - -UNUSED static void NetlinkLSRChange(u8 val) -{ - // If IER bit 2 is set and if any of the error or alarms bits are set(and - // they weren't previously), trigger an interrupt - if ((NetlinkArea->reg.IER & 0x4) && ((NetlinkArea->reg.LSR ^ val) & val & 0x1E)) - { - NetlinkArea->reg.IIR = (NetlinkArea->reg.IIR & 0xF0) | 0x6; - ScuSendExternalInterrupt12(); - } - - NetlinkArea->reg.LSR = val; -} - -////////////////////////////////////////////////////////////////////////////// - -#ifndef USESOCKET -UNUSED -#endif -static void NetlinkMSRChange(u8 set, u8 clear) -{ - u8 change; - - change = ((NetlinkArea->reg.MSR >> 4) ^ set) & set; - change |= (((NetlinkArea->reg.MSR >> 4) ^ 0xFF) ^ clear) & clear; - - // If IER bit 3 is set and CTS/DSR/RI/RLSD changes, trigger interrupt - if ((NetlinkArea->reg.IER & 0x8) && change) - { - NetlinkArea->reg.IIR = NetlinkArea->reg.IIR & 0xF0; - ScuSendExternalInterrupt12(); - } - - NetlinkArea->reg.MSR &= ~(clear << 4); - NetlinkArea->reg.MSR |= (set << 4) | change; -} - -////////////////////////////////////////////////////////////////////////////// - -u8 FASTCALL NetlinkReadByte(u32 addr) -{ - u8 ret; - - switch (addr) - { - case 0x95001: // Receiver Buffer/Divisor Latch Low Byte - { - if (NetlinkArea->reg.LCR & 0x80) // Divisor Latch Low Byte - return NetlinkArea->reg.DLL; - else // Receiver Buffer - { - if (NetlinkArea->outbuffersize == 0) - return 0x00; - - ret = NetlinkArea->outbuffer[NetlinkArea->outbufferstart]; - NetlinkArea->outbufferstart++; - NetlinkArea->outbuffersize--; - - // If the buffer is empty now, make sure the data available - // bit in LSR is cleared - if (NetlinkArea->outbuffersize == 0) - { - NetlinkArea->outbufferstart = NetlinkArea->outbufferend = 0; - NetlinkArea->reg.LSR &= ~0x01; - } - - // If interrupt has been triggered because of RBR having data, reset it - if ((NetlinkArea->reg.IER & 0x1) && (NetlinkArea->reg.IIR & 0xF) == 0x4) - NetlinkArea->reg.IIR = (NetlinkArea->reg.IIR & 0xF0) | 0x1; - - return ret; - } - - return 0; - } - case 0x95009: // Interrupt Identification Register - { - // If interrupt has been triggered because THB is empty, reset it - if ((NetlinkArea->reg.IER & 0x2) && (NetlinkArea->reg.IIR & 0xF) == 0x2) - NetlinkArea->reg.IIR = (NetlinkArea->reg.IIR & 0xF0) | 0x1; - return NetlinkArea->reg.IIR; - } - case 0x9500D: // Line Control Register - { - return NetlinkArea->reg.LCR; - } - case 0x95011: // Modem Control Register - { - return NetlinkArea->reg.MCR; - } - case 0x95015: // Line Status Register - { - return NetlinkArea->reg.LSR; - } - case 0x95019: // Modem Status Register - { - // If interrupt has been triggered because of MSR change, reset it - if ((NetlinkArea->reg.IER & 0x8) && (NetlinkArea->reg.IIR & 0xF) == 0) - NetlinkArea->reg.IIR = (NetlinkArea->reg.IIR & 0xF0) | 0x1; - ret = NetlinkArea->reg.MSR; - NetlinkArea->reg.MSR &= 0xF0; - return ret; - } - case 0x9501D: // Scratch - { - return NetlinkArea->reg.SCR; - } - default: - break; - } - - LOG("Unimplemented Netlink byte read: %08X\n", addr); - return 0xFF; -} - -////////////////////////////////////////////////////////////////////////////// - -static void FASTCALL NetlinkDoATResponse(const char *string) -{ - strcpy((char *)&NetlinkArea->outbuffer[NetlinkArea->outbufferend], string); - NetlinkArea->outbufferend += (u32)strlen(string); - NetlinkArea->outbuffersize += (u32)strlen(string); -} - -////////////////////////////////////////////////////////////////////////////// - -static int FASTCALL NetlinkFetchATParameter(u8 val, u32 *offset) -{ - if (val >= '0' && val <= '9') - { - (*offset)++; - return (val - 0x30); - } - else - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void FASTCALL NetlinkWriteByte(u32 addr, u8 val) -{ - switch (addr) - { - case 0x2503D: // ??? - { - return; - } - case 0x95001: // Transmitter Holding Buffer/Divisor Latch Low Byte - { - if (NetlinkArea->reg.LCR & 0x80) // Divisor Latch Low Byte - { - NetlinkArea->reg.DLL = val; - } - else // Transmitter Holding Buffer - { - NetlinkArea->inbuffer[NetlinkArea->inbufferend] = val; - NetlinkArea->inbufferend++; - NetlinkArea->inbuffersize++; - - // If interrupt has been triggered because THB is empty, reset it - if ((NetlinkArea->reg.IER & 0x2) && (NetlinkArea->reg.IIR & 0xF) == 0x2) - NetlinkArea->reg.IIR = (NetlinkArea->reg.IIR & 0xF0) | 0x1; - - if (NetlinkArea->modemstate == MODEMSTATE_COMMAND) - { - - if (val == 0x0D && - (strncmp((char *)&NetlinkArea->inbuffer[NetlinkArea->inbufferstart], "AT", 2) == 0 || - strncmp((char *)&NetlinkArea->inbuffer[NetlinkArea->inbufferstart], "at", 2) == 0)) // fix me - { - u32 i=NetlinkArea->inbufferstart+2; - int resultcode=NL_RESULTCODE_OK; - int parameter; - - LOG("Program issued %s\n", NetlinkArea->inbuffer); - - // If echo is enabled, do it - if (NetlinkArea->isechoenab) - NetlinkDoATResponse((char *)NetlinkArea->inbuffer); - - // Handle AT command - while(NetlinkArea->inbuffer[i] != 0xD) - { - switch (toupper(NetlinkArea->inbuffer[i])) - { - case '%': - break; - case '&': - // Figure out second part of command - i++; - - switch (toupper(NetlinkArea->inbuffer[i])) - { - case 'C': - // Data Carrier Detect Options - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - case 'D': - // Data Terminal Ready Options - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - case 'F': - // Factory reset - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - case 'K': - // Local Flow Control Options - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - case 'Q': - // Communications Mode Options - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - case 'S': - // Data Set Ready Options - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - default: break; - } - break; - case ')': - case '*': - case ':': - case '?': - case '@': - case '\\': - break; - case 'A': - // Answer Command(no other commands should follow) - break; - case 'D': - // Dial Command - NetlinkArea->connectstatus = CONNECTSTATUS_CONNECT; - - i = NetlinkArea->inbufferend-1; // fix me - break; - case 'E': - // Command State Character Echo Selection - - parameter = NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - - // Parameter can only be 0 or 1 - if (parameter < 2) - NetlinkArea->isechoenab = parameter; - else - resultcode = NL_RESULTCODE_ERROR; - - break; - case 'I': - // Internal Memory Tests - switch(NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i)) - { - case 0: - NetlinkDoATResponse("\r\n28800\r\n"); - break; - default: break; - } - break; - case 'L': - // Speaker Volume Level Selection - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - case 'M': - // Speaker On/Off Selection - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - case 'V': - // Result Code Format Options - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - case 'W': - // Negotiation Progress Message Selection - NetlinkFetchATParameter(NetlinkArea->inbuffer[i+1], &i); - break; - default: break; - } - - i++; - } - - switch (resultcode) - { - case NL_RESULTCODE_OK: // OK - NetlinkDoATResponse("\r\nOK\r\n"); - break; - case NL_RESULTCODE_CONNECT: // CONNECT - NetlinkDoATResponse("\r\nCONNECT\r\n"); - break; - case NL_RESULTCODE_RING: // RING - NetlinkDoATResponse("\r\nRING\r\n"); - break; - case NL_RESULTCODE_NOCARRIER: // NO CARRIER - NetlinkDoATResponse("\r\nNO CARRIER\r\n"); - break; - case NL_RESULTCODE_ERROR: // ERROR - NetlinkDoATResponse("\r\nERROR\r\n"); - break; - case NL_RESULTCODE_CONNECT1200: // CONNECT 1200 - NetlinkDoATResponse("\r\nCONNECT 1200\r\n"); - break; - case NL_RESULTCODE_NODIALTONE: // NO DIALTONE - NetlinkDoATResponse("\r\nNO DIALTONE\r\n"); - break; - case NL_RESULTCODE_BUSY: // BUSY - NetlinkDoATResponse("\r\nBUSY\r\n"); - break; - case NL_RESULTCODE_NOANSWER: // NO ANSWER - NetlinkDoATResponse("\r\nNO ANSWER\r\n"); - break; - default: break; - } - - memset(NetlinkArea->inbuffer, 0, NetlinkArea->inbuffersize); - NetlinkArea->inbufferstart = NetlinkArea->inbufferend = NetlinkArea->inbuffersize = 0; - - if (NetlinkArea->outbuffersize > 0) - { - // Set Data available bit in LSR - NetlinkArea->reg.LSR |= 0x01; - - // Trigger Interrrupt - NetlinkArea->reg.IIR = 0x4; - ScuSendExternalInterrupt12(); - } - } - } - } - - return; - } - case 0x95005: // Interrupt Enable Register/Divisor Latch High Byte - { - if (NetlinkArea->reg.LCR & 0x80) // Divisor Latch High Byte - { - NetlinkArea->reg.DLM = val; - } - else // Interrupt Enable Register - { - NetlinkArea->reg.IER = val; - } - - return; - } - case 0x95009: // FIFO Control Register - { - NetlinkArea->reg.FCR = val; - - if (val & 0x1) - // set FIFO enabled bits - NetlinkArea->reg.IIR |= 0xC0; - else - // clear FIFO enabled bits - NetlinkArea->reg.IIR &= ~0xC0; - - return; - } - case 0x9500D: // Line Control Register - { - NetlinkArea->reg.LCR = val; - return; - } - case 0x95011: // Modem Control Register - { - NetlinkArea->reg.MCR = val; - return; - } - case 0x95019: // Modem Status Register(read-only) - return; - case 0x9501D: // Scratch - { - NetlinkArea->reg.SCR = val; - return; - } - default: - break; - } - - LOG("Unimplemented Netlink byte write: %08X\n", addr); -} - -////////////////////////////////////////////////////////////////////////////// - -int NetlinkInit(const char *setting) -{ - if ((NetlinkArea = malloc(sizeof(Netlink))) == NULL) - { - Cs2Area->carttype = CART_NONE; - YabSetError(YAB_ERR_CANNOTINIT, (void *)"Netlink"); - return 0; - } - - memset(NetlinkArea->inbuffer, 0, NETLINK_BUFFER_SIZE); - memset(NetlinkArea->outbuffer, 0, NETLINK_BUFFER_SIZE); - - NetlinkArea->inbufferstart = NetlinkArea->inbufferend = NetlinkArea->inbuffersize = 0; - NetlinkArea->outbufferstart = NetlinkArea->outbufferend = NetlinkArea->outbuffersize = 0; - - NetlinkArea->isechoenab = 1; - NetlinkArea->cycles = 0; - NetlinkArea->modemstate = MODEMSTATE_COMMAND; - - NetlinkArea->reg.RBR = 0x00; - NetlinkArea->reg.IER = 0x00; - NetlinkArea->reg.DLL = 0x00; - NetlinkArea->reg.DLM = 0x00; - NetlinkArea->reg.IIR = 0x01; -// NetlinkArea->reg.FCR = 0x??; // have no idea - NetlinkArea->reg.LCR = 0x00; - NetlinkArea->reg.MCR = 0x00; - NetlinkArea->reg.LSR = 0x60; - NetlinkArea->reg.MSR = 0x30; - NetlinkArea->reg.SCR = 0x01; - - if (setting == NULL || strcmp(setting, "") == 0) - { - // Use Loopback ip and port 1337 - sprintf(NetlinkArea->ipstring, "127.0.0.1"); - sprintf(NetlinkArea->portstring, "1337"); - } - else - { - char *p; - p = strchr(setting, '\n'); - if (p == NULL) - { - strcpy(NetlinkArea->ipstring, setting); - sprintf(NetlinkArea->portstring, "1337"); - } - else - { - memcpy(NetlinkArea->ipstring, setting, (int)(p - setting)); - NetlinkArea->ipstring[(p - setting)] = '\0'; - if (strlen(p+1) == 0) - sprintf(NetlinkArea->portstring, "1337"); - else - strcpy(NetlinkArea->portstring, p+1); - } - } - -#ifdef USESOCKET - return NetworkInit(); -#else - return 0; -#endif -} - -////////////////////////////////////////////////////////////////////////////// - -void NetlinkDeInit(void) -{ -#ifdef USESOCKET - NetworkDeInit(); -#endif - - if (NetlinkArea) - free(NetlinkArea); -} - -////////////////////////////////////////////////////////////////////////////// - -void NetlinkExec(u32 timing) -{ - NetlinkArea->cycles += timing; - - if (NetlinkArea->cycles >= 20000) - { - NetlinkArea->cycles -= 20000; - - switch(NetlinkArea->connectstatus) - { - case CONNECTSTATUS_IDLE: - { -#ifdef USESOCKET - if (NetworkWaitForConnect(NetlinkArea->portstring) == 0) - { - NetlinkArea->connectstatus = CONNECTSTATUS_CONNECTED; - NetlinkArea->modemstate = MODEMSTATE_ONLINE; - - // This is probably wrong, but let's give it a try anyways - NetlinkDoATResponse("\r\nRING\r\n\r\nCONNECT\r\n"); - NetlinkMSRChange(0x08, 0x00); - - // Set Data available bit in LSR - NetlinkArea->reg.LSR |= 0x01; - - // Trigger Interrrupt - NetlinkArea->reg.IIR = 0x4; - ScuSendExternalInterrupt12(); - LOG("Connected via idle\n"); - } -#endif - break; - } - case CONNECTSTATUS_CONNECT: - { -#ifdef USESOCKET - if (NetworkConnect(NetlinkArea->ipstring, NetlinkArea->portstring) == 0) - { - NetlinkArea->connectstatus = CONNECTSTATUS_CONNECTED; - NetlinkArea->modemstate = MODEMSTATE_ONLINE; - - NetlinkDoATResponse("\r\nCONNECT\r\n"); - NetlinkMSRChange(0x08, 0x00); - - // Set Data available bit in LSR - NetlinkArea->reg.LSR |= 0x01; - - // Trigger Interrrupt - NetlinkArea->reg.IIR = 0x4; - ScuSendExternalInterrupt12(); - LOG("Connected via connect\n"); - } -#endif - break; - } - case CONNECTSTATUS_CONNECTED: - { -#ifdef USESOCKET - int bytes; - fd_set read_fds; - fd_set write_fds; - struct timeval tv; - - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - - // Let's see if we can even connect at this point - FD_SET(NetlinkArea->connectsocket, &read_fds); - FD_SET(NetlinkArea->connectsocket, &write_fds); - tv.tv_sec = 0; - tv.tv_usec = 0; - - if (select(NetlinkArea->connectsocket+1, &read_fds, &write_fds, NULL, &tv) < 1) - { - LOG("select failed\n"); - return; - } - - if (NetlinkArea->modemstate == MODEMSTATE_ONLINE && NetlinkArea->inbuffersize > 0 && FD_ISSET(NetlinkArea->connectsocket, &write_fds)) - { - LOG("Sending to external source..."); - - // Send via network connection - if ((bytes = NetworkSend(&NetlinkArea->inbuffer[NetlinkArea->inbufferstart], NetlinkArea->inbufferend-NetlinkArea->inbufferstart)) >= 0) - { - LOG("Successfully sent %d byte(s)\n", bytes); - if (NetlinkArea->inbufferend > bytes) - { - NetlinkArea->inbufferstart += bytes; - NetlinkArea->inbuffersize -= bytes; - } - else - NetlinkArea->inbufferstart = NetlinkArea->inbufferend = NetlinkArea->inbuffersize = 0; - } - else - { - LOG("failed.\n"); - } - } - - if (FD_ISSET(NetlinkArea->connectsocket, &read_fds)) - { -// if ((bytes = NetworkReceive(&NetlinkArea->outbuffer[NetlinkArea->outbufferend], NETLINK_BUFFER_SIZE-NetlinkArea->outbufferend)) > 0) - if ((bytes = NetworkReceive(&NetlinkArea->outbuffer[NetlinkArea->outbufferend], 8)) > 0) - { - NetlinkArea->outbufferend += bytes; - NetlinkArea->outbuffersize += bytes; - - NetlinkMSRChange(0x08, 0x00); - - // Set Data available bit in LSR - NetlinkArea->reg.LSR |= 0x01; - - // Trigger Interrrupt - NetlinkArea->reg.IIR = 0x4; - ScuSendExternalInterrupt12(); - LOG("Received %d byte(s) from external source\n", bytes); - } - } -#endif - break; - } - default: break; - } - } -} - -////////////////////////////////////////////////////////////////////////////// -#ifdef USESOCKET - -static int NetworkInit(void) -{ -#ifdef WIN32 - WSADATA wsaData; - - if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) - return -1; -#endif - - NetlinkArea->connectsocket = -1; - NetlinkArea->connectstatus = CONNECTSTATUS_IDLE; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int NetworkConnect(const char *ip, const char *port) -{ - struct addrinfo *result = NULL, - hints; - - memset(&hints, 0, sizeof(hints)); - - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - if (getaddrinfo(ip, port, &hints, &result) != 0) - return -1; - - // Create a Socket - if ((NetlinkArea->connectsocket = socket(result->ai_family, result->ai_socktype, - result->ai_protocol)) == -1) - { - freeaddrinfo(result); - return -1; - } - - // Connect to the socket - if (connect(NetlinkArea->connectsocket, result->ai_addr, (int)result->ai_addrlen) == -1) - { - freeaddrinfo(result); - closesocket(NetlinkArea->connectsocket); - NetlinkArea->connectsocket = -1; - return -1; - } - - freeaddrinfo(result); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int NetworkWaitForConnect(const char *port) -{ - struct addrinfo *result = NULL, - hints; - int ListenSocket = -1; - fd_set read_fds; - struct timeval tv; - - memset(&hints, 0, sizeof(hints)); - - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_flags = AI_PASSIVE; - - if (getaddrinfo(NULL, port, &hints, &result) != 0) - return -1; - - // Create a socket that the client can connect to - if ((ListenSocket = socket(result->ai_family, result->ai_socktype, - result->ai_protocol)) == -1) - { - freeaddrinfo(result); - return -1; - } - - // Setup the listening socket - if (bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen) == -1) - { - freeaddrinfo(result); - closesocket(ListenSocket); - return -1; - } - - freeaddrinfo(result); - - // Shhh... Let's listen - if (listen(ListenSocket, SOMAXCONN) == -1) - { - closesocket(ListenSocket); - return -1; - } - - FD_ZERO(&read_fds); - - // Let's see if we can even connect at this point - FD_SET(ListenSocket, &read_fds); - tv.tv_sec = 0; - tv.tv_usec = 0; - - if (select(ListenSocket+1, &read_fds, NULL, NULL, &tv) < 1) - { - closesocket(ListenSocket); - return -1; - } - - if (FD_ISSET(ListenSocket, &read_fds)) - { - // Good, time to connect - if ((NetlinkArea->connectsocket = accept(ListenSocket, NULL, NULL)) == -1) - { - closesocket(ListenSocket); - return -1; - } - - // We don't need the listen socket anymore - closesocket(ListenSocket); - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -static int NetworkSend(const void *buffer, int length) -{ - int bytessent; - - if ((bytessent = send(NetlinkArea->connectsocket, buffer, length, 0)) == -1) - { - // Fix me, better error handling is needed -// closesocket(NetlinkArea->connectsocket); -// NetlinkArea->connectsocket = -1; - return -1; - } - - return bytessent; -} - -////////////////////////////////////////////////////////////////////////////// - -static int NetworkReceive(void *buffer, int maxlength) -{ - int bytesreceived; - - bytesreceived = recv(NetlinkArea->connectsocket, buffer, maxlength, 0); - - if (bytesreceived == 0) - { - // Fix me, better handling is needed - LOG("Connection closed\n"); - return -1; - } - else if (bytesreceived < 0) - { - // Fix me, better error handling is needed - return -1; - } - - return bytesreceived; -} - -////////////////////////////////////////////////////////////////////////////// - -static void NetworkDeInit(void) -{ - if (NetlinkArea->connectsocket != -1) - closesocket(NetlinkArea->connectsocket); -#ifdef WIN32 - WSACleanup(); -#endif -} - -////////////////////////////////////////////////////////////////////////////// - -#endif diff --git a/yabause/src/netlink.h b/yabause/src/netlink.h deleted file mode 100644 index 38c85aed60..0000000000 --- a/yabause/src/netlink.h +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright 2006 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef NETLINK_H -#define NETLINK_H - -#define NETLINK_BUFFER_SIZE 1024 - -typedef struct -{ - u8 RBR; - u8 THR; - u8 IER; - u8 DLL; - u8 DLM; - u8 IIR; - u8 FCR; - u8 LCR; - u8 MCR; - u8 LSR; - u8 MSR; - u8 SCR; -} netlinkregs_struct; - -typedef struct { - u8 inbuffer[NETLINK_BUFFER_SIZE]; - u8 outbuffer[NETLINK_BUFFER_SIZE]; - u32 inbufferstart, inbufferend, inbuffersize; - u32 outbufferstart, outbufferend, outbuffersize; - netlinkregs_struct reg; - int isechoenab; - int connectsocket; - int connectstatus; - u32 cycles; - int modemstate; - char ipstring[16]; - char portstring[6]; -} Netlink; - -extern Netlink *NetlinkArea; - -u8 FASTCALL NetlinkReadByte(u32 addr); -void FASTCALL NetlinkWriteByte(u32 addr, u8 val); -int NetlinkInit(const char *settingstring); -void NetlinkDeInit(void); -void NetlinkExec(u32 timing); - -#endif diff --git a/yabause/src/osdcore.c b/yabause/src/osdcore.c deleted file mode 100644 index 5f16d04c23..0000000000 --- a/yabause/src/osdcore.c +++ /dev/null @@ -1,399 +0,0 @@ -/* Copyright 2012 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "osdcore.h" -#include "vdp1.h" -#include "font.h" - -#include -#include - -#ifndef YAB_PORT_OSD -/* -Heya fellow port developper :) -If you're reading this, that may be because you want to -use your own OSD core in your port and you're about to -do it here... -Don't. -Please define the CPP constant YAB_PORT_OSD and define -your own list of OSD cores in your port. -This definition was added here to avoid breaking "everything" -when we the new OSD system was added. -*/ -OSD_struct *OSDCoreList[] = { -&OSDDummy, -#ifdef HAVE_LIBGLUT -&OSDGlut, -#endif -&OSDSoft, -NULL -}; -#else -extern OSD_struct * OSDCoreList[]; -#endif - -static OSD_struct * OSD = NULL; -static OSDMessage_struct osdmessages[OSDMSG_COUNT]; - -int OSDInit(int coreid) -{ - int i; - - for (i = 0; OSDCoreList[i] != NULL; i++) - { - if (OSDCoreList[i]->id == coreid) - { - OSD = OSDCoreList[i]; - break; - } - } - - if (OSD == NULL) - return -1; - - if (OSD->Init() != 0) - return -1; - - memset(osdmessages, 0, sizeof(osdmessages)); - osdmessages[OSDMSG_FPS].hidden = 1; - osdmessages[OSDMSG_DEBUG].hidden = 1; - - return 0; -} - -void OSDDeInit() { - if (OSD) - OSD->DeInit(); - OSD = NULL; -} - -int OSDChangeCore(int coreid) -{ - int preservefps, fpshidden, dbghidden; - - preservefps = (OSD != NULL); - fpshidden = osdmessages[OSDMSG_FPS].hidden; - dbghidden = osdmessages[OSDMSG_DEBUG].hidden; - - OSDDeInit(); - OSDInit(coreid); - - if (preservefps) - { - osdmessages[OSDMSG_FPS].hidden = fpshidden; - osdmessages[OSDMSG_DEBUG].hidden = dbghidden; - } - - return 0; -} - -void OSDPushMessage(int msgtype, int ttl, const char * format, ...) -{ - va_list arglist; - char message[1024]; - - if (ttl == 0) return; - - va_start(arglist, format); - vsprintf(message, format, arglist); - va_end(arglist); - - osdmessages[msgtype].type = msgtype; - osdmessages[msgtype].message = strdup(message); - osdmessages[msgtype].timetolive = ttl; - osdmessages[msgtype].timeleft = ttl; -} - -int OSDDisplayMessages(u32 * buffer, int w, int h) -{ - int i = 0; - int somethingnew = 0; - - if (OSD == NULL) return somethingnew; - - for(i = 0;i < OSDMSG_COUNT;i++) - if (osdmessages[i].timeleft > 0) - { - if (osdmessages[i].hidden == 0) - { - somethingnew = 1; - OSD->DisplayMessage(osdmessages + i, buffer, w, h); - } - osdmessages[i].timeleft--; - if (osdmessages[i].timeleft == 0) free(osdmessages[i].message); - } - - return somethingnew; -} - -void OSDToggle(int what) -{ - if ((what < 0) || (what >= OSDMSG_COUNT)) return; - - osdmessages[what].hidden = 1 - osdmessages[what].hidden; -} - -int OSDIsVisible(int what) -{ - if ((what < 0) || (what >= OSDMSG_COUNT)) return -1; - - return 1 - osdmessages[what].hidden; -} - -void OSDSetVisible(int what, int visible) -{ - if ((what < 0) || (what >= OSDMSG_COUNT)) return; - - visible = visible == 0 ? 0 : 1; - osdmessages[what].hidden = 1 - visible; -} - -int OSDUseBuffer(void) -{ - if (OSD == NULL) return 0; - - return OSD->UseBuffer(); -} - -void ToggleFPS() -{ - OSDToggle(OSDMSG_FPS); -} - -int GetOSDToggle(void) -{ - return OSDIsVisible(OSDMSG_FPS); -} - -void SetOSDToggle(int toggle) -{ - OSDSetVisible(OSDMSG_FPS, toggle); -} - -void DisplayMessage(const char* str) -{ - OSDPushMessage(OSDMSG_STATUS, 120, str); -} - -static int OSDDummyInit(void); -static void OSDDummyDeInit(void); -static void OSDDummyReset(void); -static void OSDDummyDisplayMessage(OSDMessage_struct * message, u32 * buffer, int w, int h); -static int OSDDummyUseBuffer(void); - -OSD_struct OSDDummy = { - OSDCORE_DUMMY, - "Dummy OSD Interface", - OSDDummyInit, - OSDDummyDeInit, - OSDDummyReset, - OSDDummyDisplayMessage, - OSDDummyUseBuffer, -}; - -int OSDDummyInit(void) -{ - return 0; -} - -void OSDDummyDeInit(void) -{ -} - -void OSDDummyReset(void) -{ -} - -void OSDDummyDisplayMessage(OSDMessage_struct * message, u32 * buffer, int w, int h) -{ -} - -int OSDDummyUseBuffer(void) -{ - return 0; -} - -#ifdef HAVE_LIBGLUT -#ifdef __APPLE__ - #include -#else - #include -#endif - -static int OSDGlutInit(void); -static void OSDGlutDeInit(void); -static void OSDGlutReset(void); -static void OSDGlutDisplayMessage(OSDMessage_struct * message, u32 * buffer, int w, int h); -static int OSDGlutUseBuffer(void); - -OSD_struct OSDGlut = { - OSDCORE_GLUT, - "Glut OSD Interface", - OSDGlutInit, - OSDGlutDeInit, - OSDGlutReset, - OSDGlutDisplayMessage, - OSDGlutUseBuffer -}; - -int OSDGlutInit(void) -{ - int fake_argc = 1; - char * fake_argv[] = { "yabause" }; - static int glutinited = 0; - - if (!glutinited) - { - glutInit(&fake_argc, fake_argv); - glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_STENCIL); - glutinited = 1; - } - - return 0; -} - -void OSDGlutDeInit(void) -{ -} - -void OSDGlutReset(void) -{ -} - -void OSDGlutDisplayMessage(OSDMessage_struct * message, u32 * buffer, int w, int h) -{ - int LeftX=9; - int Width=500; - int TxtY=11; - int Height=13; - int i, msglength; - int vidwidth, vidheight; - - VIDCore->GetGlSize(&vidwidth, &vidheight); - Width = vidwidth - 2 * LeftX; - - switch(message->type) { - case OSDMSG_STATUS: - TxtY = vidheight - (Height + TxtY); - break; - } - - msglength = strlen(message->message); - - glBegin(GL_POLYGON); - glColor3f(0, 0, 0); - glVertex2i(LeftX, TxtY); - glVertex2i(LeftX + Width, TxtY); - glVertex2i(LeftX + Width, TxtY + Height); - glVertex2i(LeftX, TxtY + Height); - glEnd(); - - glColor3f(1.0f, 1.0f, 1.0f); - glRasterPos2i(10, TxtY + 11); - for (i = 0; i < msglength; i++) { - glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, message->message[i]); - } - glColor3f(1, 1, 1); -} - -int OSDGlutUseBuffer(void) -{ - return 0; -} -#endif - -static int OSDSoftInit(void); -static void OSDSoftDeInit(void); -static void OSDSoftReset(void); -static void OSDSoftDisplayMessage(OSDMessage_struct * message, u32 * buffer, int w, int h); -static int OSDSoftUseBuffer(void); - -OSD_struct OSDSoft = { - OSDCORE_SOFT, - "Software OSD Interface", - OSDSoftInit, - OSDSoftDeInit, - OSDSoftReset, - OSDSoftDisplayMessage, - OSDSoftUseBuffer -}; - -int OSDSoftInit(void) -{ - return 0; -} - -void OSDSoftDeInit(void) -{ -} - -void OSDSoftReset(void) -{ -} - -void OSDSoftDisplayMessage(OSDMessage_struct * message, u32 * buffer, int w, int h) -{ - int i; - u32 * dot; - char * c; - int loffset = 0; - - if (buffer == NULL) return; - - switch (message->type) - { - case OSDMSG_STATUS: - loffset = h - 48; - break; - } - - c = message->message; - i = 0; - while(*c) - { - if (*c >= 47) - { - int first_line, l, p; - first_line = *c * 10; - for(l = 0;l < 10;l++) - { - for(p = 0;p < 9;p++) - { - if (font[first_line + l][p] == '.') - { - dot = buffer + 20 + ((loffset + l + 20) * w) + (i * 8) + p; - *dot = 0xFF000000; - } - else if (font[first_line + l][p] == '#') - { - dot = buffer + 20 + ((loffset + l + 20) * w) + (i * 8) + p; - *dot = 0xFFFFFFFF; - } - } - } - } - c++; - i++; - } -} - -int OSDSoftUseBuffer(void) -{ - return 1; -} diff --git a/yabause/src/osdcore.h b/yabause/src/osdcore.h deleted file mode 100644 index d13a633561..0000000000 --- a/yabause/src/osdcore.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright 2012 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef OSDCORE_H -#define OSDCORE_H - -#include "core.h" - -#define OSDCORE_DUMMY 0 -#define OSDCORE_GLUT 1 -#define OSDCORE_SOFT 2 - -#ifdef HAVE_LIBGLUT - #define OSDCORE_DEFAULT OSDCORE_GLUT -#else - #define OSDCORE_DEFAULT OSDCORE_SOFT -#endif - -#define OSDMSG_FPS 0 -#define OSDMSG_STATUS 1 -#define OSDMSG_DEBUG 2 -#define OSDMSG_COUNT 3 - -typedef struct { - int type; - char * message; - int timetolive; - int timeleft; - int hidden; -} OSDMessage_struct; - -typedef struct { - int id; - const char *Name; - - int (*Init)(void); - void (*DeInit)(void); - void (*Reset)(void); - - void (*DisplayMessage)(OSDMessage_struct * message, u32 * buffer, int w, int h); - int (*UseBuffer)(void); -} OSD_struct; - -int OSDInit(int coreid); -int OSDChangeCore(int coreid); - -void OSDPushMessage(int msgtype, int ttl, const char * message, ...); -int OSDDisplayMessages(u32 * buffer, int w, int h); -void OSDToggle(int what); -int OSDIsVisible(int what); -void OSDSetVisible(int what, int visible); -int OSDUseBuffer(void); - -extern OSD_struct OSDDummy; -#ifdef HAVE_LIBGLUT -extern OSD_struct OSDGlut; -#endif -extern OSD_struct OSDSoft; - -/* defined for backward compatibility (used to be in vdp2.h) */ -void ToggleFPS(void); -int GetOSDToggle(void); -void SetOSDToggle(int toggle); -void DisplayMessage(const char* str); - -#endif diff --git a/yabause/src/perdx.c b/yabause/src/perdx.c deleted file mode 100644 index b7baa67d7b..0000000000 --- a/yabause/src/perdx.c +++ /dev/null @@ -1,1301 +0,0 @@ -/* Copyright 2006 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include "debug.h" -#include "peripheral.h" -#include "perdx.h" -#include "vdp1.h" -#include "vdp2.h" -#include "yui.h" -#include "movie.h" - -#define IDD_BUTTONCONFIG 123 -#define IDC_WAITINPUT 1001 -#define IDC_DXDEVICECB 1010 -#define IDC_UPTEXT 1024 -#define IDC_RIGHTTEXT 1025 -#define IDC_DOWNTEXT 1026 -#define IDC_LEFTTEXT 1027 -#define IDC_RTEXT 1028 -#define IDC_LTEXT 1029 -#define IDC_STARTTEXT 1030 -#define IDC_ATEXT 1031 -#define IDC_BTEXT 1032 -#define IDC_CTEXT 1033 -#define IDC_XTEXT 1034 -#define IDC_YTEXT 1035 -#define IDC_ZTEXT 1036 -#define IDC_CUSTOMCANCEL 1037 - -enum { - EMUTYPE_NONE=0, - EMUTYPE_STANDARDPAD, - EMUTYPE_ANALOGPAD, - EMUTYPE_STUNNER, - EMUTYPE_MOUSE, - EMUTYPE_KEYBOARD -}; - -int PERDXInit(void); -void PERDXDeInit(void); -int PERDXHandleEvents(void); -int Check_Skip_Key(); - -PerInterface_struct PERDIRECTX = { -PERCORE_DIRECTX, -"DirectX Input Interface", -PERDXInit, -PERDXDeInit, -PERDXHandleEvents -}; - -LPDIRECTINPUT8 lpDI8 = NULL; -LPDIRECTINPUTDEVICE8 lpDIDevice[256]; // I hope that's enough -GUID GUIDDevice[256]; // I hope that's enough -u32 numguids=0; -u32 numdevices=0; - -u32 numpads=12; -PerPad_struct *pad[12]; -padconf_struct paddevice[12]; -int porttype[2]; - -const char *mouse_names[] = { -"A", -"B", -"C", -"Start", -NULL -}; - -#define TYPE_KEYBOARD 0 -#define TYPE_JOYSTICK 1 -#define TYPE_MOUSE 2 - -#define PAD_DIR_AXISLEFT 0 -#define PAD_DIR_AXISRIGHT 1 -#define PAD_DIR_AXISUP 2 -#define PAD_DIR_AXISDOWN 3 -#define PAD_DIR_POVUP 4 -#define PAD_DIR_POVRIGHT 5 -#define PAD_DIR_POVDOWN 6 -#define PAD_DIR_POVLEFT 7 - -HWND DXGetWindow (); - -////////////////////////////////////////////////////////////////////////////// - -BOOL CALLBACK EnumPeripheralsCallback (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) -{ - if (GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_GAMEPAD || - GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_JOYSTICK || - GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_KEYBOARD) - { - if (SUCCEEDED(IDirectInput8_CreateDevice(lpDI8, &lpddi->guidInstance, &lpDIDevice[numdevices], - NULL) )) - numdevices++; - } - - return DIENUM_CONTINUE; -} - -////////////////////////////////////////////////////////////////////////////// - -void LoadDefaultPort1A(void) -{ - porttype[0] = 1; - porttype[1] = 0; - - pad[0] = PerPadAdd(&PORTDATA1); - - PerSetKey(DIK_UP, PERPAD_UP, pad[0]); - PerSetKey(DIK_DOWN, PERPAD_DOWN, pad[0]); - PerSetKey(DIK_LEFT, PERPAD_LEFT, pad[0]); - PerSetKey(DIK_RIGHT, PERPAD_RIGHT, pad[0]); - PerSetKey(DIK_K, PERPAD_A, pad[0]); - PerSetKey(DIK_L, PERPAD_B, pad[0]); - PerSetKey(DIK_M, PERPAD_C, pad[0]); - PerSetKey(DIK_U, PERPAD_X, pad[0]); - PerSetKey(DIK_I, PERPAD_Y, pad[0]); - PerSetKey(DIK_O, PERPAD_Z, pad[0]); - PerSetKey(DIK_X, PERPAD_LEFT_TRIGGER, pad[0]); - PerSetKey(DIK_Z, PERPAD_RIGHT_TRIGGER, pad[0]); - PerSetKey(DIK_J, PERPAD_START, pad[0]); -} - -////////////////////////////////////////////////////////////////////////////// - -int PERDXInit(void) -{ - DIPROPDWORD dipdw; - char tempstr[512]; - HRESULT ret; - - memset(pad, 0, sizeof(pad)); - memset(paddevice, 0, sizeof(paddevice)); - - if (FAILED((ret = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, - &IID_IDirectInput8, (LPVOID *)&lpDI8, NULL)) )) - { - sprintf(tempstr, "DirectInput8Create error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); - MessageBox (NULL, _16(tempstr), _16("Error"), MB_OK | MB_ICONINFORMATION); - return -1; - } - - IDirectInput8_EnumDevices(lpDI8, DI8DEVCLASS_ALL, EnumPeripheralsCallback, - NULL, DIEDFL_ATTACHEDONLY); - - if (FAILED((ret = IDirectInput8_CreateDevice(lpDI8, &GUID_SysKeyboard, &lpDIDevice[0], - NULL)) )) - { - sprintf(tempstr, "IDirectInput8_CreateDevice error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); - MessageBox (NULL, _16(tempstr), _16("Error"), MB_OK | MB_ICONINFORMATION); - return -1; - } - - if (FAILED((ret = IDirectInputDevice8_SetDataFormat(lpDIDevice[0], &c_dfDIKeyboard)) )) - { - sprintf(tempstr, "IDirectInputDevice8_SetDataFormat error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); - MessageBox (NULL, _16(tempstr), _16("Error"), MB_OK | MB_ICONINFORMATION); - return -1; - } - - if (FAILED((ret = IDirectInputDevice8_SetCooperativeLevel(lpDIDevice[0], DXGetWindow(), - DISCL_FOREGROUND | DISCL_NONEXCLUSIVE | DISCL_NOWINKEY)) )) - { - sprintf(tempstr, "IDirectInputDevice8_SetCooperativeLevel error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); - MessageBox (NULL, _16(tempstr), _16("Error"), MB_OK | MB_ICONINFORMATION); - return -1; - } - - dipdw.diph.dwSize = sizeof(DIPROPDWORD); - dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = 8; // should be enough - - // Setup Buffered input - if (FAILED((ret = IDirectInputDevice8_SetProperty(lpDIDevice[0], DIPROP_BUFFERSIZE, &dipdw.diph)) )) - { - sprintf(tempstr, "IDirectInputDevice8_SetProperty error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); - MessageBox (NULL, _16(tempstr), _16("Error"), MB_OK | MB_ICONINFORMATION); - return -1; - } - - // Make sure Keyboard is acquired already - IDirectInputDevice8_Acquire(lpDIDevice[0]); - - paddevice[0].lpDIDevice = lpDIDevice[0]; - paddevice[0].type = TYPE_KEYBOARD; - paddevice[0].emulatetype = 1; - - PerPortReset(); - LoadDefaultPort1A(); - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void StringToGUID(const char *string, GUID *guid) -{ - int data4[8]; - int i; - - sscanf(string, "%08lX-%04hX-%04hX-%02X%02X%02X%02X%02X%02X%02X%02X", (int *)&guid->Data1, (int *)&guid->Data2, (int *)&guid->Data3, &data4[0], &data4[1], &data4[2], &data4[3], &data4[4], &data4[5], &data4[6], &data4[7]); - for (i = 0; i < 8; i++) - guid->Data4[i] = (BYTE)data4[i]; -} - -////////////////////////////////////////////////////////////////////////////// - -void PERDXLoadDevices(char *inifilename) -{ - char tempstr[MAX_PATH]; - char string1[20]; - char string2[20]; - GUID guid; - DIDEVCAPS didc; - u32 i; - int j, i2; - int buttonid; - DIPROPDWORD dipdw; - int id; - DWORD coopflags=DISCL_FOREGROUND | DISCL_NONEXCLUSIVE; - BOOL loaddefault=TRUE; - int numpads; - HRESULT hr; - - if (!PERCore) - return; - PerPortReset(); - memset(pad, 0, sizeof(pad)); - - // Check Connection Type - if (GetPrivateProfileStringA("Input", "Port1Type", "", tempstr, MAX_PATH, inifilename) == 0) - { - // Check if it's using the old ini settings for peripherals - if (GetPrivateProfileStringA("Peripheral1", "GUID", "", tempstr, MAX_PATH, inifilename) != 0) - { - // Convert to the newer type of settings - for (i = 0; i < 2; i++) - { - sprintf(string1, "Port%dType", (int)i+1); - WritePrivateProfileStringA("Input", string1, "1", inifilename); - - sprintf(string1, "Peripheral%d", (int)i+1); - sprintf(string2, "Peripheral%dA", (int)i+1); - - if (GetPrivateProfileStringA(string1, "GUID", "", tempstr, MAX_PATH, inifilename)) - WritePrivateProfileStringA(string2, "GUID", tempstr, inifilename); - - if (GetPrivateProfileStringA(string1, "EmulateType", "", tempstr, MAX_PATH, inifilename)) - WritePrivateProfileStringA(string2, "EmulateType", tempstr, inifilename); - - for (i2 = 0; i2 < 13; i2++) - { - if (GetPrivateProfileStringA(string1, PerPadNames[i2], "", tempstr, MAX_PATH, inifilename)) - WritePrivateProfileStringA(string2, PerPadNames[i2], tempstr, inifilename); - } - } - - // Remove old ini entries - for (i = 0; i < 12; i++) - { - sprintf(string1, "Peripheral%d", (int)i+1); - WritePrivateProfileStringA(string1, NULL, NULL, inifilename); - } - - loaddefault = FALSE; - } - } - else - loaddefault = FALSE; - - if (loaddefault) - { - LoadDefaultPort1A(); - return; - } - - // Load new type settings - for (i = 0; i < 2; i++) - { - sprintf(string1, "Port%dType", (int)i+1); - - if (GetPrivateProfileStringA("Input", string1, "", tempstr, MAX_PATH, inifilename) != 0) - { - porttype[i] = atoi(tempstr); - - switch(porttype[i]) - { - case 1: - numpads = 1; - break; - case 2: - numpads = 6; - break; - default: - numpads = 0; - break; - } - - // Load new type settings - for (j = 0; j < numpads; j++) - { - int padindex=(6*i)+j; - padconf_struct *curdevice=&paddevice[padindex]; - sprintf(string1, "Peripheral%d%C", (int)i+1, 'A' + j); - - // Let's first fetch the guid of the device - if (GetPrivateProfileStringA(string1, "GUID", "", tempstr, MAX_PATH, inifilename) == 0) - continue; - - if (GetPrivateProfileStringA(string1, "EmulateType", "0", string2, MAX_PATH, inifilename)) - { - curdevice->emulatetype = atoi(string2); - if (curdevice->emulatetype == 0) - continue; - } - - if (curdevice->lpDIDevice) - { - // Free the default keyboard, etc. - IDirectInputDevice8_Unacquire(curdevice->lpDIDevice); - IDirectInputDevice8_Release(curdevice->lpDIDevice); - } - - StringToGUID(tempstr, &guid); - - // Ok, now that we've got the GUID of the device, let's set it up - if (FAILED(IDirectInput8_CreateDevice(lpDI8, &guid, &lpDIDevice[padindex], - NULL) )) - { - curdevice->lpDIDevice = NULL; - curdevice->emulatetype = 0; - continue; - } - - curdevice->lpDIDevice = lpDIDevice[padindex]; - - didc.dwSize = sizeof(DIDEVCAPS); - - if (FAILED(IDirectInputDevice8_GetCapabilities(lpDIDevice[padindex], &didc) )) - continue; - - if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_KEYBOARD) - { - if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevice[padindex], &c_dfDIKeyboard) )) - continue; - curdevice->type = TYPE_KEYBOARD; - coopflags |= DISCL_NOWINKEY; - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_GAMEPAD || - GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_JOYSTICK) - { - if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevice[padindex], &c_dfDIJoystick2) )) - continue; - curdevice->type = TYPE_JOYSTICK; - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_MOUSE) - { - if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevice[padindex], &c_dfDIMouse2) )) - continue; - curdevice->type = TYPE_MOUSE; - coopflags = DISCL_FOREGROUND | DISCL_EXCLUSIVE; - } - - hr = IDirectInputDevice8_SetCooperativeLevel(lpDIDevice[i], DXGetWindow(), coopflags); - if (FAILED(hr)) - continue; - - dipdw.diph.dwSize = sizeof(DIPROPDWORD); - dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = 8; // should be enough - - // Setup Buffered input - if (FAILED(IDirectInputDevice8_SetProperty(lpDIDevice[padindex], DIPROP_BUFFERSIZE, &dipdw.diph))) - continue; - - IDirectInputDevice8_Acquire(lpDIDevice[padindex]); - - switch(curdevice->emulatetype) - { - case 1: // Standard Pad - id = PERPAD; - break; - case 2: // Analog Pad - case 3: // Stunner - case 5: // Keyboard - id = 0; - break; - case 4: // Mouse - id = PERMOUSE; - break; - default: break; - } - - // Make sure we're added to the smpc list - if (i == 0) - pad[padindex] = PerAddPeripheral(&PORTDATA1, id); - else - pad[padindex] = PerAddPeripheral(&PORTDATA2, id); - - // Now that we're all setup, let's fetch the controls from the ini - if (curdevice->emulatetype != 3 && - curdevice->emulatetype != 4) - { - for (i2 = 0; i2 < 13; i2++) - { - buttonid = GetPrivateProfileIntA(string1, PerPadNames[i2], 0, inifilename); - PerSetKey(buttonid, i2, pad[padindex]); - } - } - else if (curdevice->emulatetype == 4) - { - for (i2 = 0; i2 < 4; i2++) - { - buttonid = GetPrivateProfileIntA(string1, mouse_names[i2], 0, inifilename); - PerSetKey(buttonid, PERMOUSE_LEFT+i2, pad[padindex]); - } - } - } - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -void PERDXDeInit(void) -{ - u32 i; - - for (i = 0; i < numdevices; i++) - { - if (lpDIDevice[i]) - { - IDirectInputDevice8_Unacquire(lpDIDevice[i]); - IDirectInputDevice8_Release(lpDIDevice[i]); - lpDIDevice[i] = NULL; - } - } - - if (lpDI8) - { - IDirectInput8_Release(lpDI8); - lpDI8 = NULL; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void PollKeys(void) -{ - u32 i; - DWORD i2; - DWORD size=8; - DIDEVICEOBJECTDATA didod[8]; - HRESULT hr; - - for (i = 0; i < numpads; i++) - { - if (paddevice[i].lpDIDevice == NULL) - continue; - - hr = IDirectInputDevice8_Poll(paddevice[i].lpDIDevice); - - if (FAILED(hr)) - { - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - // Make sure device is acquired - while(IDirectInputDevice8_Acquire(paddevice[i].lpDIDevice) == DIERR_INPUTLOST) {} - continue; - } - } - - size = 8; - - // Poll events - if (FAILED(IDirectInputDevice8_GetDeviceData(paddevice[i].lpDIDevice, - sizeof(DIDEVICEOBJECTDATA), didod, &size, 0))) - { - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - // Make sure device is acquired - while(IDirectInputDevice8_Acquire(paddevice[i].lpDIDevice) == DIERR_INPUTLOST) {} - continue; - } - } - - if (size == 0) - continue; - - switch (paddevice[i].type) - { - case TYPE_KEYBOARD: - // This probably could be optimized - for (i2 = 0; i2 < size; i2++) - { - if (didod[i2].dwData & 0x80) - PerKeyDown(didod[i2].dwOfs); - else - PerKeyUp(didod[i2].dwOfs); - } - break; - case TYPE_JOYSTICK: - { - // This probably could be optimized - for (i2 = 0; i2 < size; i2++) - { - // X Axis - if (didod[i2].dwOfs == DIJOFS_X) - { - if (didod[i2].dwData < 0x3FFF) - { - PerKeyDown(PAD_DIR_AXISLEFT); - PerKeyUp(PAD_DIR_AXISRIGHT); - } - else if (didod[i2].dwData > 0xBFFF) - { - PerKeyDown(PAD_DIR_AXISRIGHT); - PerKeyUp(PAD_DIR_AXISLEFT); - } - else - { - PerKeyUp(PAD_DIR_AXISLEFT); - PerKeyUp(PAD_DIR_AXISRIGHT); - } - } - // Y Axis - else if (didod[i2].dwOfs == DIJOFS_Y) - { - if (didod[i2].dwData < 0x3FFF) - { - PerKeyDown(PAD_DIR_AXISUP); - PerKeyUp(PAD_DIR_AXISDOWN); - } - else if (didod[i2].dwData > 0xBFFF) - { - PerKeyDown(PAD_DIR_AXISDOWN); - PerKeyUp(PAD_DIR_AXISUP); - } - else - { - PerKeyUp(PAD_DIR_AXISUP); - PerKeyUp(PAD_DIR_AXISDOWN); - } - } - else if (didod[i2].dwOfs == DIJOFS_POV(0)) - { - // POV Center - if (LOWORD(didod[i2].dwData) == 0xFFFF) - { - PerKeyUp(PAD_DIR_POVUP); - PerKeyUp(PAD_DIR_POVRIGHT); - PerKeyUp(PAD_DIR_POVDOWN); - PerKeyUp(PAD_DIR_POVLEFT); - } - // POV Up - else if (didod[i2].dwData < 4500) - { - PerKeyDown(PAD_DIR_POVUP); - PerKeyUp(PAD_DIR_POVRIGHT); - PerKeyUp(PAD_DIR_POVLEFT); - } - // POV Up-right - else if (didod[i2].dwData < 9000) - { - PerKeyDown(PAD_DIR_POVUP); - PerKeyDown(PAD_DIR_POVRIGHT); - } - // POV Right - else if (didod[i2].dwData < 13500) - { - PerKeyDown(PAD_DIR_POVRIGHT); - PerKeyUp(PAD_DIR_POVDOWN); - PerKeyUp(PAD_DIR_POVUP); - } - // POV Right-down - else if (didod[i2].dwData < 18000) - { - PerKeyDown(PAD_DIR_POVRIGHT); - PerKeyDown(PAD_DIR_POVDOWN); - } - // POV Down - else if (didod[i2].dwData < 22500) - { - PerKeyDown(PAD_DIR_POVDOWN); - PerKeyUp(PAD_DIR_POVLEFT); - PerKeyUp(PAD_DIR_POVRIGHT); - } - // POV Down-left - else if (didod[i2].dwData < 27000) - { - PerKeyDown(PAD_DIR_POVDOWN); - PerKeyDown(PAD_DIR_POVLEFT); - } - // POV Left - else if (didod[i2].dwData < 31500) - { - PerKeyDown(PAD_DIR_POVLEFT); - PerKeyUp(PAD_DIR_POVUP); - PerKeyUp(PAD_DIR_POVDOWN); - } - // POV Left-up - else if (didod[i2].dwData < 36000) - { - PerKeyDown(PAD_DIR_POVLEFT); - PerKeyDown(PAD_DIR_POVUP); - } - } - else if (didod[i2].dwOfs >= DIJOFS_BUTTON(0) && didod[i2].dwOfs <= DIJOFS_BUTTON(127)) - { - if (didod[i2].dwData & 0x80) - PerKeyDown(didod[i2].dwOfs); - else - PerKeyUp(didod[i2].dwOfs); - } - } - break; - } - case TYPE_MOUSE: - for (i2 = 0; i2 < size; i2++) - { - if (didod[i2].dwOfs == DIMOFS_X) - // X Axis - PerMouseMove((PerMouse_struct *)pad[i], (s32)didod[i2].dwData, 0); - else if (didod[i2].dwOfs == DIMOFS_Y) - // Y Axis - PerMouseMove((PerMouse_struct *)pad[i], 0, 0-(s32)didod[i2].dwData); - else if (didod[i2].dwOfs >= DIMOFS_BUTTON0 && didod[i2].dwOfs <= DIMOFS_BUTTON7) - { - // Mouse Buttons - if (didod[i2].dwData & 0x80) - PerKeyDown(didod[i2].dwOfs-DIMOFS_BUTTON0); - else - PerKeyUp(didod[i2].dwOfs-DIMOFS_BUTTON0); - } - } - break; - default: break; - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -int PERDXHandleEvents(void) -{ - PollKeys(); - - if (YabauseExec() != 0) - return -1; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -BOOL CALLBACK EnumPeripheralsCallbackGamepad (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) -{ - if (GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_GAMEPAD || - GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_JOYSTICK || - GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_KEYBOARD) - { - SendMessage((HWND)pvRef, CB_ADDSTRING, 0, (LPARAM)lpddi->tszInstanceName); - memcpy(&GUIDDevice[numguids], &lpddi->guidInstance, sizeof(GUID)); - numguids++; - } - - return DIENUM_CONTINUE; -} - -////////////////////////////////////////////////////////////////////////////// - -BOOL CALLBACK EnumPeripheralsCallbackKeyboard (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) -{ - if (GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_KEYBOARD) - { - SendMessage((HWND)pvRef, CB_ADDSTRING, 0, (LPARAM)lpddi->tszInstanceName); - memcpy(&GUIDDevice[numguids], &lpddi->guidInstance, sizeof(GUID)); - numguids++; - } - - return DIENUM_CONTINUE; -} - -////////////////////////////////////////////////////////////////////////////// - -BOOL CALLBACK EnumPeripheralsCallbackMouse (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) -{ - if (GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_MOUSE) - { - SendMessage((HWND)pvRef, CB_ADDSTRING, 0, (LPARAM)lpddi->tszInstanceName); - memcpy(&GUIDDevice[numguids], &lpddi->guidInstance, sizeof(GUID)); - numguids++; - } - - return DIENUM_CONTINUE; -} - -////////////////////////////////////////////////////////////////////////////// - -void PERDXListDevices(HWND control, int emulatetype) -{ - LPDIRECTINPUT8 lpDI8temp = NULL; - - if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, - &IID_IDirectInput8, (LPVOID *)&lpDI8temp, NULL))) - return; - - numguids = 0; - - SendMessage(control, CB_RESETCONTENT, 0, 0); - SendMessage(control, CB_ADDSTRING, 0, (LPARAM)_16("None")); - - switch(emulatetype) - { - case EMUTYPE_STANDARDPAD: - case EMUTYPE_ANALOGPAD: - IDirectInput8_EnumDevices(lpDI8temp, DI8DEVCLASS_ALL, EnumPeripheralsCallbackGamepad, - (LPVOID)control, DIEDFL_ATTACHEDONLY); - break; - case EMUTYPE_STUNNER: - case EMUTYPE_MOUSE: - IDirectInput8_EnumDevices(lpDI8temp, DI8DEVCLASS_ALL, EnumPeripheralsCallbackMouse, - (LPVOID)control, DIEDFL_ATTACHEDONLY); - break; - case EMUTYPE_KEYBOARD: - IDirectInput8_EnumDevices(lpDI8temp, DI8DEVCLASS_ALL, EnumPeripheralsCallbackKeyboard, - (LPVOID)control, DIEDFL_ATTACHEDONLY); - break; - default: break; - } - - IDirectInput8_Release(lpDI8temp); -} - -////////////////////////////////////////////////////////////////////////////// - -void ConvertKBIDToName(int buttonid, char *string) -{ - memset(string, 0, MAX_PATH); - - // This fixes some strange inconsistencies - if (buttonid == DIK_PAUSE) - buttonid = DIK_NUMLOCK; - else if (buttonid == DIK_NUMLOCK) - buttonid = DIK_PAUSE; - if (buttonid & 0x80) - buttonid += 0x80; - - GetKeyNameTextA(buttonid << 16, string, MAX_PATH); -} - -////////////////////////////////////////////////////////////////////////////// - -void ConvertJoyIDToName(int buttonid, char *string) -{ - switch (buttonid) - { - case 0x00: - sprintf(string, "Axis Left"); - break; - case 0x01: - sprintf(string, "Axis Right"); - break; - case 0x02: - sprintf(string, "Axis Up"); - break; - case 0x03: - sprintf(string, "Axis Down"); - break; - case 0x04: - sprintf(string, "POV Up"); - break; - case 0x05: - sprintf(string, "POV Right"); - break; - case 0x06: - sprintf(string, "POV Down"); - break; - case 0x07: - sprintf(string, "POV Left"); - break; - default: - if (buttonid >= 0x30) - sprintf(string, "Button %d", buttonid - 0x2F); - break; - } - -} - -////////////////////////////////////////////////////////////////////////////// - -void ConvertMouseIDToName(int buttonid, char *string) -{ - sprintf(string, "Button %d", buttonid+1); -} - -////////////////////////////////////////////////////////////////////////////// - -int PERDXInitControlConfig(HWND hWnd, u8 padnum, int *controlmap, const char *inifilename) -{ - char tempstr[MAX_PATH]; - char string1[20]; - GUID guid; - u32 i; - int idlist[] = { IDC_UPTEXT, IDC_RIGHTTEXT, IDC_DOWNTEXT, IDC_LEFTTEXT, - IDC_RTEXT, IDC_LTEXT, IDC_STARTTEXT, - IDC_ATEXT, IDC_BTEXT, IDC_CTEXT, - IDC_XTEXT, IDC_YTEXT, IDC_ZTEXT - }; - - sprintf(string1, "Peripheral%d%C", ((padnum/6)+1), 'A'+(padnum%6)); - - // Let's first fetch the guid of the device and see if we can get a match - if (GetPrivateProfileStringA(string1, "GUID", "", tempstr, MAX_PATH, inifilename) == 0) - { - if (padnum == 0) - { - // Let's use default values - SendDlgItemMessage(hWnd, IDC_DXDEVICECB, CB_SETCURSEL, 1, 0); - - controlmap[0] = DIK_UP; - controlmap[1] = DIK_RIGHT; - controlmap[2] = DIK_DOWN; - controlmap[3] = DIK_LEFT; - controlmap[4] = DIK_Z; - controlmap[5] = DIK_X; - controlmap[6] = DIK_J; - controlmap[7] = DIK_K; - controlmap[8] = DIK_L; - controlmap[9] = DIK_M; - controlmap[10] = DIK_U; - controlmap[11] = DIK_I; - controlmap[12] = DIK_O; - for (i = 0; i < 13; i++) - { - ConvertKBIDToName(controlmap[i], tempstr); - SetDlgItemText(hWnd, idlist[i], _16(tempstr)); - } - } - else - { - SendDlgItemMessage(hWnd, IDC_DXDEVICECB, CB_SETCURSEL, 0, 0); - return -1; - } - } - else - { - LPDIRECTINPUT8 lpDI8temp = NULL; - LPDIRECTINPUTDEVICE8 lpDIDevicetemp; - DIDEVCAPS didc; - int buttonid; - - StringToGUID(tempstr, &guid); - - // Let's find a match - for (i = 0; i < numguids; i++) - { - if (memcmp(&guid, &GUIDDevice[i], sizeof(GUID)) == 0) - { - SendDlgItemMessage(hWnd, IDC_DXDEVICECB, CB_SETCURSEL, i+1, 0); - break; - } - } - - if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, - &IID_IDirectInput8, (LPVOID *)&lpDI8temp, NULL))) - return -1; - - if (FAILED(IDirectInput8_CreateDevice(lpDI8temp, &GUIDDevice[i], &lpDIDevicetemp, - NULL))) - { - IDirectInput8_Release(lpDI8temp); - return -1; - } - - didc.dwSize = sizeof(DIDEVCAPS); - - if (FAILED(IDirectInputDevice8_GetCapabilities(lpDIDevicetemp, &didc))) - { - IDirectInputDevice8_Release(lpDIDevicetemp); - IDirectInput8_Release(lpDI8temp); - return -1; - } - - if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_KEYBOARD) - { - sprintf(string1, "Peripheral%d%C", ((padnum/6)+1), 'A'+(padnum%6)); - - for (i = 0; i < 13; i++) - { - buttonid = GetPrivateProfileIntA(string1, PerPadNames[i], 0, inifilename); - printf("%2d: %d\n", i, buttonid); - controlmap[i] = buttonid; - ConvertKBIDToName(buttonid, tempstr); - SetDlgItemText(hWnd, idlist[i], _16(tempstr)); - } - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_GAMEPAD || - GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_JOYSTICK) - { - sprintf(string1, "Peripheral%d%C", ((padnum/6)+1), 'A'+(padnum%6)); - - for (i = 0; i < 13; i++) - { - buttonid = GetPrivateProfileIntA(string1, PerPadNames[i], 0, inifilename); - controlmap[i] = buttonid; - ConvertJoyIDToName(buttonid, tempstr); - SetDlgItemText(hWnd, idlist[i], _16(tempstr)); - } - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_MOUSE) - { - for (i = 0; i < 13; i++) - { - buttonid = GetPrivateProfileIntA(string1, PerPadNames[i], 0, inifilename); - controlmap[i] = buttonid; - ConvertMouseIDToName(buttonid, tempstr); - SetDlgItemText(hWnd, idlist[i], _16(tempstr)); - } - } - - IDirectInputDevice8_Release(lpDIDevicetemp); - IDirectInput8_Release(lpDI8temp); - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -DIDEVICEOBJECTDATA nextpress; - -int PERDXFetchNextPress(HWND hWnd, u32 guidnum, char *buttonname) -{ - LPDIRECTINPUT8 lpDI8temp = NULL; - LPDIRECTINPUTDEVICE8 lpDIDevicetemp; - DIDEVCAPS didc; - int buttonid=-1; - - if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, - &IID_IDirectInput8, (LPVOID *)&lpDI8temp, NULL))) - return -1; - - if (FAILED(IDirectInput8_CreateDevice(lpDI8temp, &GUIDDevice[guidnum], &lpDIDevicetemp, - NULL))) - { - IDirectInput8_Release(lpDI8temp); - return -1; - } - - didc.dwSize = sizeof(DIDEVCAPS); - - if (FAILED(IDirectInputDevice8_GetCapabilities(lpDIDevicetemp, &didc))) - { - IDirectInputDevice8_Release(lpDIDevicetemp); - IDirectInput8_Release(lpDI8temp); - return -1; - } - - if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_KEYBOARD) - { - if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevicetemp, &c_dfDIKeyboard))) - { - IDirectInputDevice8_Release(lpDIDevicetemp); - IDirectInput8_Release(lpDI8temp); - return -1; - } - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_GAMEPAD || - GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_JOYSTICK) - { - if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevicetemp, &c_dfDIJoystick))) - { - IDirectInputDevice8_Release(lpDIDevicetemp); - IDirectInput8_Release(lpDI8temp); - return -1; - } - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_MOUSE) - { - if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevicetemp, &c_dfDIMouse2))) - { - IDirectInputDevice8_Release(lpDIDevicetemp); - IDirectInput8_Release(lpDI8temp); - return -1; - } - } - - if (DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_BUTTONCONFIG), hWnd, (DLGPROC)ButtonConfigDlgProc, (LPARAM)lpDIDevicetemp) == TRUE) - { - // Figure out what kind of code to generate - if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_KEYBOARD) - { - memset(buttonname, 0, MAX_PATH); - buttonid = nextpress.dwOfs; - // This fixes some strange inconsistencies - if (buttonid == DIK_PAUSE) - buttonid = DIK_NUMLOCK; - else if (buttonid == DIK_NUMLOCK) - buttonid = DIK_PAUSE; - if (buttonid & 0x80) - buttonid += 0x80; - - GetKeyNameTextA(buttonid << 16, buttonname, MAX_PATH); - buttonid = nextpress.dwOfs; - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_GAMEPAD || - GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_JOYSTICK) - { - if (nextpress.dwOfs == DIJOFS_X) - { - if (nextpress.dwData <= 0x8000) - { - sprintf(buttonname, "Axis Left"); - buttonid = 0x00; - } - else - { - sprintf(buttonname, "Axis Right"); - buttonid = 0x01; - } - } - else if (nextpress.dwOfs == DIJOFS_Y) - { - if (nextpress.dwData <= 0x8000) - { - sprintf(buttonname, "Axis Up"); - buttonid = 0x02; - } - else - { - sprintf(buttonname, "Axis Down"); - buttonid = 0x03; - } - } - else if (nextpress.dwOfs == DIJOFS_POV(0)) - { - if (nextpress.dwData < 9000) - { - sprintf(buttonname, "POV Up"); - buttonid = 0x04; - } - else if (nextpress.dwData < 18000) - { - sprintf(buttonname, "POV Right"); - buttonid = 0x05; - } - else if (nextpress.dwData < 27000) - { - sprintf(buttonname, "POV Down"); - buttonid = 0x06; - } - else - { - sprintf(buttonname, "POV Left"); - buttonid = 0x07; - } - } - else if (nextpress.dwOfs >= DIJOFS_BUTTON(0) && nextpress.dwOfs <= DIJOFS_BUTTON(127)) - { - sprintf(buttonname, "Button %d", (int)(nextpress.dwOfs - 0x2F)); - buttonid = nextpress.dwOfs; - } - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_MOUSE) - { - buttonid = nextpress.dwOfs-DIMOFS_BUTTON0; - sprintf(buttonname, "Button %d", buttonid+1); - } - } - - IDirectInputDevice8_Unacquire(lpDIDevicetemp); - IDirectInputDevice8_Release(lpDIDevicetemp); - IDirectInput8_Release(lpDI8temp); - - return buttonid; -} - -////////////////////////////////////////////////////////////////////////////// - -HHOOK hook; - -LRESULT CALLBACK KeyboardHook(int code, WPARAM wParam, LPARAM lParam) -{ - if (code >= HC_ACTION) - return TRUE; - - return CallNextHookEx(hook, code, wParam, lParam); -} - -////////////////////////////////////////////////////////////////////////////// - -LRESULT CALLBACK ButtonConfigDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, - LPARAM lParam) -{ - static LPDIRECTINPUTDEVICE8 lpDIDevicetemp; - DIPROPDWORD dipdw; - HRESULT hr; - DWORD size; - DIDEVICEOBJECTDATA didod[8]; - DWORD i; - DIDEVCAPS didc; - - switch (uMsg) - { - case WM_INITDIALOG: - { - lpDIDevicetemp = (LPDIRECTINPUTDEVICE8)lParam; - - if (FAILED(IDirectInputDevice8_SetCooperativeLevel(lpDIDevicetemp, hDlg, - DISCL_FOREGROUND | DISCL_NONEXCLUSIVE | DISCL_NOWINKEY))) - return FALSE; - - dipdw.diph.dwSize = sizeof(DIPROPDWORD); - dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = 8; // should be enough - - // Setup Buffered input - if (FAILED((hr = IDirectInputDevice8_SetProperty(lpDIDevicetemp, DIPROP_BUFFERSIZE, &dipdw.diph)))) - return FALSE; - - if (!SetTimer(hDlg, 1, 100, NULL)) - return FALSE; - - PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, IDC_WAITINPUT), TRUE); - hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardHook, GetModuleHandle(NULL), GetCurrentThreadId()); - return TRUE; - } - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case IDC_CUSTOMCANCEL: - { - EndDialog(hDlg, FALSE); - return TRUE; - } - default: break; - } - - break; - } - case WM_TIMER: - { - size = 8; - - if (wParam == 1) - { - memset(&didod, 0, sizeof(DIDEVICEOBJECTDATA) * 8); - - // Let's see if there's any data waiting - hr = IDirectInputDevice8_Poll(lpDIDevicetemp); - - if (FAILED(hr)) - { - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - // Make sure device is acquired - while(IDirectInputDevice8_Acquire(lpDIDevicetemp) == DIERR_INPUTLOST) {} - return TRUE; - } - } - - // Poll events - if (FAILED(IDirectInputDevice8_GetDeviceData(lpDIDevicetemp, - sizeof(DIDEVICEOBJECTDATA), didod, &size, 0))) - { - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - // Make sure device is acquired - while(IDirectInputDevice8_Acquire(lpDIDevicetemp) == DIERR_INPUTLOST) {} - return TRUE; - } - } - - didc.dwSize = sizeof(DIDEVCAPS); - - if (FAILED(IDirectInputDevice8_GetCapabilities(lpDIDevicetemp, &didc))) - return TRUE; - - if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_KEYBOARD) - { - for (i = 0; i < size; i++) - { - if (didod[i].dwData & 0x80) - { - // We're done. time to bail - EndDialog(hDlg, TRUE); - memcpy(&nextpress, &didod[i], sizeof(DIDEVICEOBJECTDATA)); - break; - } - } - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_GAMEPAD || - GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_JOYSTICK) - { - for (i = 0; i < size; i++) - { - if (didod[i].dwOfs == 0 || - didod[i].dwOfs == 4) - { - if (didod[i].dwData <= 0x1000 || - didod[i].dwData >= 0xF000) - { - // We're done. time to bail - EndDialog(hDlg, TRUE); - memcpy(&nextpress, &didod[i], sizeof(DIDEVICEOBJECTDATA)); - break; - } - } - else if (didod[i].dwOfs == 0x20) - { - if (((int)didod[i].dwData) >= 0) - { - // We're done. time to bail - EndDialog(hDlg, TRUE); - memcpy(&nextpress, &didod[i], sizeof(DIDEVICEOBJECTDATA)); - } - } - else if (didod[i].dwOfs >= 0x30) - { - if (didod[i].dwData & 0x80) - { - // We're done. time to bail - EndDialog(hDlg, TRUE); - memcpy(&nextpress, &didod[i], sizeof(DIDEVICEOBJECTDATA)); - break; - } - } - } - } - else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_MOUSE) - { - for (i = 0; i < size; i++) - { - // Make sure it's a button press - if (didod[i].dwOfs >= DIMOFS_BUTTON0 && didod[i].dwOfs <= DIMOFS_BUTTON7) - { - if (didod[i].dwData & 0x80) - { - EndDialog(hDlg, TRUE); - memcpy(&nextpress, &didod[i], sizeof(DIDEVICEOBJECTDATA)); - break; - } - } - } - } - - return TRUE; - } - - return FALSE; - } - case WM_DESTROY: - { - KillTimer(hDlg, 1); - UnhookWindowsHookEx(hook); - break; - } - } - - return FALSE; -} - -////////////////////////////////////////////////////////////////////////////// - -BOOL PERDXWriteGUID(u32 guidnum, u8 padnum, LPCSTR inifilename) -{ - char string1[20]; - char string2[40]; - sprintf(string1, "Peripheral%d%C", ((padnum/6)+1), 'A'+(padnum%6)); - sprintf(string2, "%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X", (int)GUIDDevice[guidnum].Data1, (int)GUIDDevice[guidnum].Data2, (int)GUIDDevice[guidnum].Data3, (int)GUIDDevice[guidnum].Data4[0], (int)GUIDDevice[guidnum].Data4[1], (int)GUIDDevice[guidnum].Data4[2], (int)GUIDDevice[guidnum].Data4[3], (int)GUIDDevice[guidnum].Data4[4], (int)GUIDDevice[guidnum].Data4[5], (int)GUIDDevice[guidnum].Data4[6], (int)GUIDDevice[guidnum].Data4[7]); - return WritePrivateProfileStringA(string1, "GUID", string2, inifilename); -} - -////////////////////////////////////////////////////////////////////////////// - diff --git a/yabause/src/perdx.h b/yabause/src/perdx.h deleted file mode 100644 index 245ad7d360..0000000000 --- a/yabause/src/perdx.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2006 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PERDX_H -#define PERDX_H - -#define DIRECTINPUT_VERSION 0x0800 -#include -#include "dx.h" -#include "peripheral.h" - -#define PERCORE_DIRECTX 2 - -extern PerInterface_struct PERDIRECTX; - -extern GUID GUIDDevice[256]; -extern u32 numguids; -extern const char * pad_names[]; -extern PerPad_struct *pad[12]; -extern u32 numpads; -extern int porttype[2]; - -typedef struct -{ - LPDIRECTINPUTDEVICE8 lpDIDevice; - int type; - int emulatetype; -} padconf_struct; - -extern padconf_struct paddevice[12]; - -LRESULT CALLBACK ButtonConfigDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, - LPARAM lParam); - -void KeyStub(PerPad_struct *pad); -void SetupControlUpDown(u8 padnum, u8 controlcode, void (*downfunc)(PerPad_struct *), void (*upfunc)(PerPad_struct *)); - -void PERDXLoadDevices(char *inifilename); -void PERDXListDevices(HWND control, int emulatetype); -int PERDXInitControlConfig(HWND hWnd, u8 padnum, int *controlmap, const char *inifilename); -int PERDXFetchNextPress(HWND hWnd, u32 guidnum, char *buttonname); -BOOL PERDXWriteGUID(u32 guidnum, u8 padnum, LPCSTR inifilename); -#endif diff --git a/yabause/src/peripheral.c b/yabause/src/peripheral.c deleted file mode 100644 index e10d1fbbed..0000000000 --- a/yabause/src/peripheral.c +++ /dev/null @@ -1,724 +0,0 @@ -/* Copyright 2005 Guillaume Duhamel - Copyright 2005-2006 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "debug.h" -#include "peripheral.h" - -const char * PerPadNames[] = -{ -"Up", -"Right", -"Down", -"Left", -"R", -"L", -"Start", -"A", -"B", -"C", -"X", -"Y", -"Z", -NULL -}; - -const char * PerMouseNames[] = -{ -"A", -"B", -"C", -"Start", -NULL -}; - -PortData_struct PORTDATA1; -PortData_struct PORTDATA2; - -PerInterface_struct * PERCore = NULL; -extern PerInterface_struct * PERCoreList[]; - -typedef struct { - u8 name; - void (*Press)(void *); - void (*Release)(void *); -} PerBaseConfig_struct; - -typedef struct { - u32 key; - PerBaseConfig_struct * base; - void * controller; -} PerConfig_struct; - -#define PERCALLBACK(func) ((void (*) (void *)) func) - -PerBaseConfig_struct perkeybaseconfig[] = { - { PERPAD_UP, PERCALLBACK(PerPadUpPressed), PERCALLBACK(PerPadUpReleased) }, - { PERPAD_RIGHT, PERCALLBACK(PerPadRightPressed), PERCALLBACK(PerPadRightReleased) }, - { PERPAD_DOWN, PERCALLBACK(PerPadDownPressed), PERCALLBACK(PerPadDownReleased) }, - { PERPAD_LEFT, PERCALLBACK(PerPadLeftPressed), PERCALLBACK(PerPadLeftReleased) }, - { PERPAD_RIGHT_TRIGGER, PERCALLBACK(PerPadRTriggerPressed), PERCALLBACK(PerPadRTriggerReleased) }, - { PERPAD_LEFT_TRIGGER, PERCALLBACK(PerPadLTriggerPressed), PERCALLBACK(PerPadLTriggerReleased) }, - { PERPAD_START, PERCALLBACK(PerPadStartPressed), PERCALLBACK(PerPadStartReleased) }, - { PERPAD_A, PERCALLBACK(PerPadAPressed), PERCALLBACK(PerPadAReleased) }, - { PERPAD_B, PERCALLBACK(PerPadBPressed), PERCALLBACK(PerPadBReleased) }, - { PERPAD_C, PERCALLBACK(PerPadCPressed), PERCALLBACK(PerPadCReleased) }, - { PERPAD_X, PERCALLBACK(PerPadXPressed), PERCALLBACK(PerPadXReleased) }, - { PERPAD_Y, PERCALLBACK(PerPadYPressed), PERCALLBACK(PerPadYReleased) }, - { PERPAD_Z, PERCALLBACK(PerPadZPressed), PERCALLBACK(PerPadZReleased) }, -}; - -PerBaseConfig_struct permousebaseconfig[] = { - { PERMOUSE_LEFT, PERCALLBACK(PerMouseLeftPressed), PERCALLBACK(PerMouseLeftReleased) }, - { PERMOUSE_MIDDLE, PERCALLBACK(PerMouseMiddlePressed), PERCALLBACK(PerMouseMiddleReleased) }, - { PERMOUSE_RIGHT, PERCALLBACK(PerMouseRightPressed), PERCALLBACK(PerMouseRightReleased) }, - { PERMOUSE_START, PERCALLBACK(PerMouseStartPressed), PERCALLBACK(PerMouseStartReleased) }, -}; - -static u32 perkeyconfigsize = 0; -static PerConfig_struct * perkeyconfig = NULL; - -static void PerUpdateConfig(PerBaseConfig_struct * baseconfig, int nelems, void * controller); - -////////////////////////////////////////////////////////////////////////////// - -int PerInit(int coreid) { - int i; - - // So which core do we want? - if (coreid == PERCORE_DEFAULT) - coreid = 0; // Assume we want the first one - - // Go through core list and find the id - for (i = 0; PERCoreList[i] != NULL; i++) - { - if (PERCoreList[i]->id == coreid) - { - // Set to current core - PERCore = PERCoreList[i]; - break; - } - } - - if (PERCore == NULL) - return -1; - - if (PERCore->Init() != 0) - return -1; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerDeInit(void) { - if (PERCore) - PERCore->DeInit(); - PERCore = NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadUpPressed(PerPad_struct * pad) { - *pad->padbits &= 0xEF; - SMPCLOG("Up\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadUpReleased(PerPad_struct * pad) { - *pad->padbits |= ~0xEF; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadDownPressed(PerPad_struct * pad) { - *pad->padbits &= 0xDF; - SMPCLOG("Down\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadDownReleased(PerPad_struct * pad) { - *pad->padbits |= ~0xDF; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadRightPressed(PerPad_struct * pad) { - *pad->padbits &= 0x7F; - SMPCLOG("Right\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadRightReleased(PerPad_struct * pad) { - *pad->padbits |= ~0x7F; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadLeftPressed(PerPad_struct * pad) { - *pad->padbits &= 0xBF; - SMPCLOG("Left\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadLeftReleased(PerPad_struct * pad) { - *pad->padbits |= ~0xBF; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadStartPressed(PerPad_struct * pad) { - *pad->padbits &= 0xF7; - SMPCLOG("Start\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadStartReleased(PerPad_struct * pad) { - *pad->padbits |= ~0xF7; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadAPressed(PerPad_struct * pad) { - *pad->padbits &= 0xFB; - SMPCLOG("A\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadAReleased(PerPad_struct * pad) { - *pad->padbits |= ~0xFB; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadBPressed(PerPad_struct * pad) { - *pad->padbits &= 0xFE; - SMPCLOG("B\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadBReleased(PerPad_struct * pad) { - *pad->padbits |= ~0xFE; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadCPressed(PerPad_struct * pad) { - *pad->padbits &= 0xFD; - SMPCLOG("C\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadCReleased(PerPad_struct * pad) { - *pad->padbits |= ~0xFD; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadXPressed(PerPad_struct * pad) { - *(pad->padbits + 1) &= 0xBF; - SMPCLOG("X\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadXReleased(PerPad_struct * pad) { - *(pad->padbits + 1) |= ~0xBF; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadYPressed(PerPad_struct * pad) { - *(pad->padbits + 1) &= 0xDF; - SMPCLOG("Y\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadYReleased(PerPad_struct * pad) { - *(pad->padbits + 1) |= ~0xDF; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadZPressed(PerPad_struct * pad) { - *(pad->padbits + 1) &= 0xEF; - SMPCLOG("Z\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadZReleased(PerPad_struct * pad) { - *(pad->padbits + 1) |= ~0xEF; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadRTriggerPressed(PerPad_struct * pad) { - *(pad->padbits + 1) &= 0x7F; - SMPCLOG("Right Trigger\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadRTriggerReleased(PerPad_struct * pad) { - *(pad->padbits + 1) |= ~0x7F; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadLTriggerPressed(PerPad_struct * pad) { - *(pad->padbits + 1) &= 0xF7; - SMPCLOG("Left Trigger\n"); -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPadLTriggerReleased(PerPad_struct * pad) { - *(pad->padbits + 1) |= ~0xF7; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseLeftPressed(PerMouse_struct * mouse) { - *(mouse->mousebits) |= 1; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseLeftReleased(PerMouse_struct * mouse) { - *(mouse->mousebits) &= 0xFFFE; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseMiddlePressed(PerMouse_struct * mouse) { - *(mouse->mousebits) |= 4; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseMiddleReleased(PerMouse_struct * mouse) { - *(mouse->mousebits) &= 0xFFFB; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseRightPressed(PerMouse_struct * mouse) { - *(mouse->mousebits) |= 2; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseRightReleased(PerMouse_struct * mouse) { - *(mouse->mousebits) &= 0xFFFD; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseStartPressed(PerMouse_struct * mouse) { - *(mouse->mousebits) |= 8; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseStartReleased(PerMouse_struct * mouse) { - *(mouse->mousebits) &= 0xFFF7; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerMouseMove(PerMouse_struct * mouse, s32 dispx, s32 dispy) -{ - int negx, negy, overflowx, overflowy; - u8 diffx, diffy; - - negx = ((mouse->mousebits[0] >> 4) & 1); - negy = ((mouse->mousebits[0] >> 5) & 1); - overflowx = ((mouse->mousebits[0] >> 6) & 1); - overflowy = ((mouse->mousebits[0] >> 7) & 1); - - if (negx) diffx = ~(mouse->mousebits[1]) & 0xFF; - else diffx = mouse->mousebits[1]; - if (negy) diffy = ~(mouse->mousebits[2]) & 0xFF; - else diffy = mouse->mousebits[2]; - - if (dispx > 0) - { - if (negx) - { - if (dispx - diffx > 0) - { - diffx = dispx - diffx; - negx = 0; - } - else diffx -= -dispx; - } - else diffx += dispx; - } - else - { - if (negx) diffx += -dispx; - else - { - if (diffx + dispx > 0) diffx += dispx; - else - { - diffx = -dispx - diffx; - negx = 1; - } - } - } - - if (dispy > 0) - { - if (negy) - { - if (dispy - diffy > 0) - { - diffy = dispy - diffy; - negy = 0; - } - else diffy -= -dispy; - } - else diffy += dispy; - } - else - { - if (negy) diffy += -dispy; - else - { - if (diffy + dispy > 0) diffy += dispy; - else - { - diffy = -dispy - diffy; - negy = 1; - } - } - } - - mouse->mousebits[0] = (overflowy << 7) | (overflowx << 6) | (negy << 5) | (negx << 4) | (mouse->mousebits[0] & 0x0F); - if (negx) mouse->mousebits[1] = ~(diffx); - else mouse->mousebits[1] = diffx; - if (negy) mouse->mousebits[2] = ~(diffy); - else mouse->mousebits[2] = diffy; -} - -////////////////////////////////////////////////////////////////////////////// - -void * PerAddPeripheral(PortData_struct *port, int perid) -{ - int pernum = port->data[0] & 0xF; - int i; - int peroffset=1; - u8 size; - int current = 1; - void * controller; - - if (pernum == 0xF) - return NULL; - - // if only one peripheral is connected use 0xF0, otherwise use 0x00 or 0x10 - if (pernum == 0) - { - pernum = 1; - port->data[0] = 0xF1; - } - else - { - if (pernum == 1) - { - u8 tmp = peroffset; - tmp += (port->data[peroffset] & 0xF) + 1; - - for(i = 0;i < 5;i++) - port->data[tmp + i] = 0xFF; - } - pernum = 6; - port->data[0] = 0x16; - - // figure out where we're at, then add peripheral id + 1 - current = 0; - size = port->data[peroffset] & 0xF; - while ((current < pernum) && (size != 0xF)) - { - peroffset += size + 1; - current++; - size = port->data[peroffset] & 0xF; - } - - if (current == pernum) - { - return NULL; - } - current++; - } - - port->data[peroffset] = perid; - peroffset++; - - // set peripheral data for peripheral to default values and adjust size - // of port data - switch (perid) - { - case PERPAD: - port->data[peroffset] = 0xFF; - port->data[peroffset+1] = 0xFF; - port->size = peroffset+2; - break; - case PERMOUSE: - port->data[peroffset] = 0; - port->data[peroffset + 1] = 0; - port->data[peroffset + 2] = 0; - port->size = peroffset + 3; - break; - default: break; - } - - { - u8 tmp = peroffset; - tmp += (perid & 0xF); - for(i = 0;i < (pernum - current);i++) - { - port->data[tmp + i] = 0xFF; - port->size++; - } - } - - controller = (port->data + (peroffset - 1)); - switch (perid) - { - case PERPAD: - PerUpdateConfig(perkeybaseconfig, 13, controller); - break; - case PERMOUSE: - PerUpdateConfig(permousebaseconfig, 4, controller); - break; - } - return controller; -} - -////////////////////////////////////////////////////////////////////////////// - -int PerGetId(void * peripheral) -{ - u8 * id = peripheral; - return *id; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerRemovePeripheral(UNUSED PortData_struct *port, UNUSED int removeoffset) -{ - // stub -} - -////////////////////////////////////////////////////////////////////////////// - -void PerFlush(PortData_struct * port) -{ - /* FIXME this function only flush data if there's a mouse connected as - * first peripheral */ - u8 perid = port->data[1]; - if (perid == 0xE3) - { - PerMouse_struct * mouse = (PerMouse_struct *) (port->data + 1); - - mouse->mousebits[0] &= 0x0F; - mouse->mousebits[1] = 0; - mouse->mousebits[2] = 0; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void PerKeyDown(u32 key) -{ - unsigned int i = 0; - - while(i < perkeyconfigsize) - { - if (key == perkeyconfig[i].key) - { - perkeyconfig[i].base->Press(perkeyconfig[i].controller); - } - i++; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void PerKeyUp(u32 key) -{ - unsigned int i = 0; - - while(i < perkeyconfigsize) - { - if (key == perkeyconfig[i].key) - { - perkeyconfig[i].base->Release(perkeyconfig[i].controller); - } - i++; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void PerSetKey(u32 key, u8 name, void * controller) -{ - unsigned int i = 0; - - while(i < perkeyconfigsize) - { - if ((name == perkeyconfig[i].base->name) && (controller == perkeyconfig[i].controller)) - { - perkeyconfig[i].key = key; - } - i++; - } -} - -////////////////////////////////////////////////////////////////////////////// - -void PerPortReset(void) -{ - PORTDATA1.data[0] = 0xF0; - PORTDATA1.size = 1; - PORTDATA2.data[0] = 0xF0; - PORTDATA2.size = 1; - - perkeyconfigsize = 0; - if (perkeyconfig) - free(perkeyconfig); - perkeyconfig = NULL; -} - -////////////////////////////////////////////////////////////////////////////// - -void PerUpdateConfig(PerBaseConfig_struct * baseconfig, int nelems, void * controller) -{ - u32 oldsize = perkeyconfigsize; - u32 i, j; - - perkeyconfigsize += nelems; - perkeyconfig = realloc(perkeyconfig, perkeyconfigsize * sizeof(PerConfig_struct)); - j = 0; - for(i = oldsize;i < perkeyconfigsize;i++) - { - perkeyconfig[i].base = baseconfig + j; - perkeyconfig[i].controller = controller; - j++; - } -} - -////////////////////////////////////////////////////////////////////////////// - -PerPad_struct * PerPadAdd(PortData_struct * port) -{ - return PerAddPeripheral(port, PERPAD); -} - -////////////////////////////////////////////////////////////////////////////// - -PerMouse_struct * PerMouseAdd(PortData_struct * port) -{ - return PerAddPeripheral(port, PERMOUSE); -} - -////////////////////////////////////////////////////////////////////////////// -// Dummy Interface -////////////////////////////////////////////////////////////////////////////// - -int PERDummyInit(void); -void PERDummyDeInit(void); -int PERDummyHandleEvents(void); -void PERDummyNothing(void); - -//static PortData_struct port1; -//static PortData_struct port2; - -u32 PERDummyScan(void); -void PERDummyFlush(void); -void PERDummyKeyName(u32 key, char * name, int size); - -PerInterface_struct PERDummy = { -PERCORE_DUMMY, -"Dummy Input Interface", -PERDummyInit, -PERDummyDeInit, -PERDummyHandleEvents, -PERDummyNothing, -PERDummyScan, -0, -PERDummyFlush -#ifdef PERKEYNAME -,PERDummyKeyName -#endif -}; - -////////////////////////////////////////////////////////////////////////////// - -int PERDummyInit(void) { - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void PERDummyDeInit(void) { -} - -////////////////////////////////////////////////////////////////////////////// - -void PERDummyNothing(void) { -} - -////////////////////////////////////////////////////////////////////////////// - -int PERDummyHandleEvents(void) { - if (YabauseExec() != 0) - return -1; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -u32 PERDummyScan(void) { - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void PERDummyFlush(void) { -} - -////////////////////////////////////////////////////////////////////////////// - -void PERDummyKeyName(UNUSED u32 key, char * name, UNUSED int size) { - *name = 0; -} diff --git a/yabause/src/peripheral.h b/yabause/src/peripheral.h deleted file mode 100644 index e5737c87fd..0000000000 --- a/yabause/src/peripheral.h +++ /dev/null @@ -1,221 +0,0 @@ -/* Copyright 2005 Guillaume Duhamel - Copyright 2005-2006 Theo Berkau - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PERIPHERAL_H -#define PERIPHERAL_H - -#include "core.h" -#include "smpc.h" -#include "yabause.h" - -/** @defgroup peripheral Peripheral - * - * @brief This module provides two kind of functions - * - peripheral core management functions - * - controller ports management functions - * - * @{ - */ - -#define PERPAD 0x02 -#define PERMOUSE 0xE3 - -#define PERCORE_DEFAULT -1 -#define PERCORE_DUMMY 0 - -extern PortData_struct PORTDATA1; -extern PortData_struct PORTDATA2; - -typedef struct -{ - int id; - const char * Name; - int (*Init)(void); - void (*DeInit)(void); - int (*HandleEvents)(void); - void (*PerSetButtonMapping)(void); - u32 (*Scan)(void); - int canScan; - void (*Flush)(void); -#ifdef PERKEYNAME - void (*KeyName)(u32 key, char * name, int size); -#endif -} PerInterface_struct; - -/** @brief Pointer to the current peripheral core. - * - * You should not set this manually but use - * PerInit() and PerDeInit() instead. */ -extern PerInterface_struct * PERCore; - -extern PerInterface_struct PERDummy; - -/** - * @brief Init a peripheral core - * - * Searches through the PERCoreList array for the given coreid. - * If found, PERCore is set to the address of that core and - * the core's Init function is called. - * - * @param coreid the peripheral core to be used - * @return 0 if core has been inited, -1 otherwise - */ -int PerInit(int coreid); -/** - * @brief De-init a peripheral core - * - * Calls the core's DeInit callback and set PERCore to NULL. - */ -void PerDeInit(void); - -/** @brief Adds a peripheral - * - * You shouldn't directly use this function but - * PerPadAdd() or PerMouseAdd() instead. - */ -void * PerAddPeripheral(PortData_struct *port, int perid); -int PerGetId(void * peripheral); -void PerRemovePeripheral(PortData_struct *port, int removeoffset); -void PerPortReset(void); -/** - * Iterate the list of peripherals connected to a port - * and flush them if necesseray. This is needed for mouses. - */ -void PerFlush(PortData_struct * port); - -void PerKeyDown(u32 key); -void PerKeyUp(u32 key); -void PerSetKey(u32 key, u8 name, void * controller); - -/** @defgroup pad Pad - * - * @{ - */ -#define PERPAD_UP 0 -#define PERPAD_RIGHT 1 -#define PERPAD_DOWN 2 -#define PERPAD_LEFT 3 -#define PERPAD_RIGHT_TRIGGER 4 -#define PERPAD_LEFT_TRIGGER 5 -#define PERPAD_START 6 -#define PERPAD_A 7 -#define PERPAD_B 8 -#define PERPAD_C 9 -#define PERPAD_X 10 -#define PERPAD_Y 11 -#define PERPAD_Z 12 - -extern const char * PerPadNames[14]; - -typedef struct -{ - u8 perid; - u8 padbits[2]; -} PerPad_struct; - -/** @brief Adds a pad to one of the controller ports. - * - * @param port can be either &PORTDATA1 or &PORTDATA2 - * @return pointer to a PerPad_struct or NULL if it fails - * */ -PerPad_struct * PerPadAdd(PortData_struct * port); - -void PerPadUpPressed(PerPad_struct * pad); -void PerPadUpReleased(PerPad_struct * pad); - -void PerPadDownPressed(PerPad_struct * pad); -void PerPadDownReleased(PerPad_struct * pad); - -void PerPadRightPressed(PerPad_struct * pad); -void PerPadRightReleased(PerPad_struct * pad); - -void PerPadLeftPressed(PerPad_struct * pad); -void PerPadLeftReleased(PerPad_struct * pad); - -void PerPadStartPressed(PerPad_struct * pad); -void PerPadStartReleased(PerPad_struct * pad); - -void PerPadAPressed(PerPad_struct * pad); -void PerPadAReleased(PerPad_struct * pad); - -void PerPadBPressed(PerPad_struct * pad); -void PerPadBReleased(PerPad_struct * pad); - -void PerPadCPressed(PerPad_struct * pad); -void PerPadCReleased(PerPad_struct * pad); - -void PerPadXPressed(PerPad_struct * pad); -void PerPadXReleased(PerPad_struct * pad); - -void PerPadYPressed(PerPad_struct * pad); -void PerPadYReleased(PerPad_struct * pad); - -void PerPadZPressed(PerPad_struct * pad); -void PerPadZReleased(PerPad_struct * pad); - -void PerPadRTriggerPressed(PerPad_struct * pad); -void PerPadRTriggerReleased(PerPad_struct * pad); - -void PerPadLTriggerPressed(PerPad_struct * pad); -void PerPadLTriggerReleased(PerPad_struct * pad); -/** @} */ - -/** @defgroup mouse Mouse - * - * @{ - * */ -#define PERMOUSE_LEFT 13 -#define PERMOUSE_MIDDLE 14 -#define PERMOUSE_RIGHT 15 -#define PERMOUSE_START 16 - -extern const char * PerMouseNames[5]; - -typedef struct -{ - u8 perid; - u8 mousebits[3]; -} PerMouse_struct; - -/** @brief Adds a mouse to one of the controller ports. - * - * @param port can be either &PORTDATA1 or &PORTDATA2 - * @return pointer to a PerMouse_struct or NULL if it fails - * */ -PerMouse_struct * PerMouseAdd(PortData_struct * port); - -void PerMouseLeftPressed(PerMouse_struct * mouse); -void PerMouseLeftReleased(PerMouse_struct * mouse); - -void PerMouseMiddlePressed(PerMouse_struct * mouse); -void PerMouseMiddleReleased(PerMouse_struct * mouse); - -void PerMouseRightPressed(PerMouse_struct * mouse); -void PerMouseRightReleased(PerMouse_struct * mouse); - -void PerMouseStartPressed(PerMouse_struct * mouse); -void PerMouseStartReleased(PerMouse_struct * mouse); - -void PerMouseMove(PerMouse_struct * mouse, s32 dispx, s32 dispy); -/** @} */ - -/** @} */ - -#endif diff --git a/yabause/src/perlinuxjoy.c b/yabause/src/perlinuxjoy.c deleted file mode 100644 index cc0c984acc..0000000000 --- a/yabause/src/perlinuxjoy.c +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright 2009 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "debug.h" -#include "perlinuxjoy.h" -#include -#include -#include -#include - -int PERLinuxJoyInit(void); -void PERLinuxJoyDeInit(void); -int PERLinuxJoyHandleEvents(void); -void PERLinuxJoyNothing(void); -u32 PERLinuxJoyScan(void); -void PERLinuxJoyFlush(void); -void PERLinuxKeyName(u32 key, char * name, int size); - -PerInterface_struct PERLinuxJoy = { -PERCORE_LINUXJOY, -"Linux Joystick Interface", -PERLinuxJoyInit, -PERLinuxJoyDeInit, -PERLinuxJoyHandleEvents, -PERLinuxJoyNothing, -PERLinuxJoyScan, -1, -PERLinuxJoyFlush -#ifdef PERKEYNAME -,PERLinuxKeyName -#endif -}; - -static int hJOY = -1; - -#define PACKEVENT(evt) ((evt.value < 0 ? 0x10000 : 0) | (evt.type << 8) | (evt.number)) - -////////////////////////////////////////////////////////////////////////////// - -int PERLinuxJoyInit(void) -{ - hJOY = open("/dev/input/js0", O_RDONLY | O_NONBLOCK); - - if (hJOY == -1) return -1; - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void PERLinuxJoyDeInit(void) -{ - if (hJOY != -1) close(hJOY); -} - -////////////////////////////////////////////////////////////////////////////// - -void PERLinuxJoyNothing(void) -{ -} - -////////////////////////////////////////////////////////////////////////////// - -int PERLinuxJoyHandleEvents(void) -{ - struct js_event evt; - - if (hJOY == -1) return -1; - - while (read(hJOY, &evt, sizeof(struct js_event)) > 0) - { - if (evt.value != 0) - { - PerKeyDown(PACKEVENT(evt)); - } - else - { - PerKeyUp(PACKEVENT(evt)); - PerKeyUp(0x10000 | PACKEVENT(evt)); - } - } - - // execute yabause - if ( YabauseExec() != 0 ) - { - return -1; - } - - // return success - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -u32 PERLinuxJoyScan(void) { - struct js_event evt; - - if (hJOY == -1) return 0; - - if (read(hJOY, &evt, sizeof(struct js_event)) <= 0) return 0; - - return PACKEVENT(evt); -} - -////////////////////////////////////////////////////////////////////////////// - -void PERLinuxJoyFlush(void) { - struct js_event evt; - - if (hJOY == -1) return; - - while (read(hJOY, &evt, sizeof(struct js_event)) > 0); -} - -////////////////////////////////////////////////////////////////////////////// - -void PERLinuxKeyName(u32 key, char * name, UNUSED int size) -{ - sprintf(name, "%x", (int)key); -} diff --git a/yabause/src/perlinuxjoy.h b/yabause/src/perlinuxjoy.h deleted file mode 100644 index 282eacbab4..0000000000 --- a/yabause/src/perlinuxjoy.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright 2009 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef PERLINUXJOY_H -#define PERLINUXJOY_H - -#include "peripheral.h" - -/** @addtogroup peripheral - * @{ */ -#define PERCORE_LINUXJOY 4 - -extern PerInterface_struct PERLinuxJoy; -/** @} */ - -#endif - diff --git a/yabause/src/permacjoy.c b/yabause/src/permacjoy.c deleted file mode 100644 index 3073bdb6db..0000000000 --- a/yabause/src/permacjoy.c +++ /dev/null @@ -1,245 +0,0 @@ -/* Copyright 2009 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "macjoy.h" -#include "permacjoy.h" -#include "debug.h" - -int PERMacJoyInit(void); -void PERMacJoyDeInit(void); -int PERMacJoyHandleEvents(void); -void PERMacJoyNothing(void); - -u32 PERMacJoyScan(void); -void PERMacJoyFlush(void); -void PERMacJoyKeyName(u32 key, char *name, int size); - -PerInterface_struct PERMacJoy = { - PERCORE_MACJOY, - "Mac OS X (IOKit) Joystick Interface", - PERMacJoyInit, - PERMacJoyDeInit, - PERMacJoyHandleEvents, - PERMacJoyNothing, - PERMacJoyScan, - 1, - PERMacJoyFlush -#ifdef PERKEYNAME - ,PERMacJoyKeyName -#endif -}; - -static int initted = 0; -static int joycount = 0; -static joydata_t **joys = NULL; - -#define AXIS_POSITIVE_VALUE 0x800000 -#define AXIS_NEGATIVE_VALUE 0xC00000 -#define HAT_VALUE 0xA00000 - -#define MIDDLE(x, y) (((x) + (y)) / 2) - -int PERMacJoyInit(void) { - int i; - - /* Don't bother trying to init the thing again. */ - if(initted) - return 0; - - /* Grab the number of joysticks connected to the system. */ - joycount = joy_scan_joysticks(); - if(joycount == -1) { - joycount = 0; - return -1; - } - - joys = (joydata_t **)malloc(sizeof(joydata_t *) * joycount); - if(!joys) { - joycount = 0; - return -1; - } - - /* Grab each joystick and open it. */ - for(i = 0; i < joycount; ++i) { - joys[i] = joy_get_joystick(i); - - if(joys[i] == NULL) - continue; - - if(!joy_open_joystick(joys[i])) { - joys[i] = NULL; - continue; - } - } - - initted = 1; - - return 0; -} - -void PERMacJoyDeInit(void) { - int i; - - if(!initted) - return; - - /* Close each joystick. */ - for(i = 0; i < joycount; ++i) { - joy_close_joystick(joys[i]); - } - - free(joys); - joys = NULL; - joycount = 0; - initted = 0; -} - -int PERMacJoyHandleEvents(void) { - int i, j, k, data; - joydata_t *joy; - - /* Check each joystick. */ - for(i = 0; i < joycount; ++i) { - joy = joys[i]; - - if(!joy) { - continue; - } - - /* Handle each axis. */ - for(j = 0; j < joy->axes_count; ++j) { - int midpoint = MIDDLE(joy->axes[j].min, joy->axes[j].max); - - data = joy_read_axis(joy, j); - - if(joy->axes[j].max > 0 && - data > MIDDLE(midpoint, joy->axes[j].max)) { - PerKeyDown((i << 24) | AXIS_POSITIVE_VALUE | j); - PerKeyUp((i << 24) | AXIS_NEGATIVE_VALUE | j); - } - else if(joy->axes[j].min < 0 && - data < MIDDLE(midpoint, joy->axes[j].min)) { - PerKeyUp((i << 24) | AXIS_POSITIVE_VALUE | j); - PerKeyDown((i << 24) | AXIS_NEGATIVE_VALUE | j); - } - else { - PerKeyUp((i << 24) | AXIS_POSITIVE_VALUE | j); - PerKeyUp((i << 24) | AXIS_NEGATIVE_VALUE | j); - } - } - - /* Handle each button. */ - for(j = 1; j <= joy->buttons_count; ++j) { - data = joy_read_button(joy, j); - - if(data > joy->buttons[j].min) { - PerKeyDown((i << 24) | j); - } - else { - PerKeyUp((i << 24) | j); - } - } - - /* Handle any hats. */ - for(j = 0; j < joy->hats_count; ++j) { - data = joy_read_element(joy, joy->hats + j); - - for(k = joy->hats[j].min; k < joy->hats[j].max; ++k) { - if(data == k) { - PerKeyDown((i << 24) | HAT_VALUE | (k << 8) | j); - } - else { - PerKeyUp((i << 24) | HAT_VALUE | (k << 8) | j); - } - } - } - } - - if(YabauseExec() != 0) { - return -1; - } - - return 0; -} - -void PERMacJoyNothing(void) { - /* Nothing. */ -} - -u32 PERMacJoyScan(void) { - int i, j, k, data; - joydata_t *joy; - - /* Check each joystick. */ - for(i = 0; i < joycount; ++i) { - joy = joys[i]; - - if(!joy) { - continue; - } - - /* Handle each axis. */ - for(j = 0; j < joy->axes_count; ++j) { - int midpoint = MIDDLE(joy->axes[j].min, joy->axes[j].max); - - data = joy_read_axis(joy, j); - - if(joy->axes[j].max > 0 && - data > MIDDLE(midpoint, joy->axes[j].max)) { - return ((i << 24) | AXIS_POSITIVE_VALUE | j); - } - else if(joy->axes[j].min < 0 && - data < MIDDLE(midpoint, joy->axes[j].min)) { - return ((i << 24) | AXIS_NEGATIVE_VALUE | j); - } - } - - /* Handle each button. */ - for(j = 1; j <= joy->buttons_count; ++j) { - data = joy_read_button(joy, j); - - if(data > joy->buttons[j].min) { - return ((i << 24) | j); - } - } - - /* Handle any hats. */ - for(j = 0; j < joy->hats_count; ++j) { - data = joy_read_element(joy, joy->hats + j); - - for(k = joy->hats[j].min; k < joy->hats[j].max; ++k) { - if(data == k) { - return ((i << 24) | HAT_VALUE | (k << 8) | j); - } - } - } - } - - return 0; -} - -void PERMacJoyFlush(void) { - /* Nothing. */ -} - -void PERMacJoyKeyName(u32 key, char *name, int size) { - snprintf(name, size, "%x", (unsigned int)key); -} diff --git a/yabause/src/permacjoy.h b/yabause/src/permacjoy.h deleted file mode 100644 index 91e11591fd..0000000000 --- a/yabause/src/permacjoy.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright 2009 Lawrence Sebald - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PERMACJOY_H -#define PERMACJOY_H - -#include "peripheral.h" - -#define PERCORE_MACJOY 5 - -extern PerInterface_struct PERMacJoy; - -#endif /* !PERMACJOY_H */ diff --git a/yabause/src/persdljoy.c b/yabause/src/persdljoy.c deleted file mode 100644 index 701fdfe778..0000000000 --- a/yabause/src/persdljoy.c +++ /dev/null @@ -1,279 +0,0 @@ -/* Copyright 2005 Guillaume Duhamel - Copyright 2005-2006 Theo Berkau - Copyright 2008 Filipe Azevedo - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifdef HAVE_LIBSDL -#ifdef __APPLE__ - #include -#else - #include "SDL.h" -#endif - -#include "debug.h" -#include "persdljoy.h" - -#define SDL_MAX_AXIS_VALUE 0x110000 -#define SDL_MIN_AXIS_VALUE 0x100000 -#define SDL_MEDIUM_AXIS_VALUE (int)(32768 / 2) -#define SDL_BUTTON_PRESSED 1 -#define SDL_BUTTON_RELEASED 0 - -int PERSDLJoyInit(void); -void PERSDLJoyDeInit(void); -int PERSDLJoyHandleEvents(void); -void PERSDLJoyNothing(void); - -u32 PERSDLJoyScan(void); -void PERSDLJoyFlush(void); -void PERSDLKeyName(u32 key, char * name, int size); - -PerInterface_struct PERSDLJoy = { -PERCORE_SDLJOY, -"SDL Joystick Interface", -PERSDLJoyInit, -PERSDLJoyDeInit, -PERSDLJoyHandleEvents, -PERSDLJoyNothing, -PERSDLJoyScan, -1, -PERSDLJoyFlush -#ifdef PERKEYNAME -,PERSDLKeyName -#endif -}; - -typedef struct { - SDL_Joystick* mJoystick; - s16* mScanStatus; -} PERSDLJoystick; - -unsigned int SDL_PERCORE_INITIALIZED = 0; -unsigned int SDL_PERCORE_JOYSTICKS_INITIALIZED = 0; -PERSDLJoystick* SDL_PERCORE_JOYSTICKS = 0; - -////////////////////////////////////////////////////////////////////////////// - -int PERSDLJoyInit(void) { - int i, j; - - // does not need init if already done - if ( SDL_PERCORE_INITIALIZED ) - { - return 0; - } - - // init joysticks - if ( SDL_InitSubSystem( SDL_INIT_JOYSTICK ) == -1 ) - { - return -1; - } - - // ignore joysticks event in sdl event loop - SDL_JoystickEventState( SDL_IGNORE ); - - // open joysticks - SDL_PERCORE_JOYSTICKS_INITIALIZED = SDL_NumJoysticks(); - SDL_PERCORE_JOYSTICKS = malloc(sizeof(PERSDLJoystick) * SDL_PERCORE_JOYSTICKS_INITIALIZED); - for ( i = 0; i < SDL_PERCORE_JOYSTICKS_INITIALIZED; i++ ) - { - SDL_Joystick* joy = SDL_JoystickOpen( i ); - - SDL_JoystickUpdate(); - - SDL_PERCORE_JOYSTICKS[ i ].mJoystick = joy; - SDL_PERCORE_JOYSTICKS[ i ].mScanStatus = joy ? malloc(sizeof(s16) * SDL_JoystickNumAxes( joy )) : 0; - - if ( joy ) - { - for ( j = 0; j < SDL_JoystickNumAxes( joy ); j++ ) - { - SDL_PERCORE_JOYSTICKS[ i ].mScanStatus[ j ] = SDL_JoystickGetAxis( joy, j ); - } - } - } - - // success - SDL_PERCORE_INITIALIZED = 1; - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -void PERSDLJoyDeInit(void) { - // close joysticks - if ( SDL_PERCORE_INITIALIZED == 1 ) - { - int i; - for ( i = 0; i < SDL_PERCORE_JOYSTICKS_INITIALIZED; i++ ) - { - if ( SDL_JoystickOpened( i ) ) - { - SDL_JoystickClose( SDL_PERCORE_JOYSTICKS[ i ].mJoystick ); - free( SDL_PERCORE_JOYSTICKS[ i ].mScanStatus ); - } - } - free( SDL_PERCORE_JOYSTICKS ); - } - - SDL_PERCORE_JOYSTICKS_INITIALIZED = 0; - SDL_PERCORE_INITIALIZED = 0; - - // close sdl joysticks - SDL_QuitSubSystem( SDL_INIT_JOYSTICK ); -} - -////////////////////////////////////////////////////////////////////////////// - -void PERSDLJoyNothing(void) { -} - -////////////////////////////////////////////////////////////////////////////// - -int PERSDLJoyHandleEvents(void) { - int joyId; - int i; - SDL_Joystick* joy; - Sint16 cur; - Uint8 buttonState; - - // update joysticks states - SDL_JoystickUpdate(); - - // check each joysticks - for ( joyId = 0; joyId < SDL_PERCORE_JOYSTICKS_INITIALIZED; joyId++ ) - { - joy = SDL_PERCORE_JOYSTICKS[ joyId ].mJoystick; - - if ( !joy ) - { - continue; - } - - // check axis - for ( i = 0; i < SDL_JoystickNumAxes( joy ); i++ ) - { - cur = SDL_JoystickGetAxis( joy, i ); - - if ( cur < -SDL_MEDIUM_AXIS_VALUE ) - { - PerKeyUp( (joyId << 18) | SDL_MAX_AXIS_VALUE | i ); - PerKeyDown( (joyId << 18) | SDL_MIN_AXIS_VALUE | i ); - } - else if ( cur > SDL_MEDIUM_AXIS_VALUE ) - { - PerKeyUp( (joyId << 18) | SDL_MIN_AXIS_VALUE | i ); - PerKeyDown( (joyId << 18) | SDL_MAX_AXIS_VALUE | i ); - } - else - { - PerKeyUp( (joyId << 18) | SDL_MIN_AXIS_VALUE | i ); - PerKeyUp( (joyId << 18) | SDL_MAX_AXIS_VALUE | i ); - } - } - - // check buttons - for ( i = 0; i < SDL_JoystickNumButtons( joy ); i++ ) - { - buttonState = SDL_JoystickGetButton( joy, i ); - - if ( buttonState == SDL_BUTTON_PRESSED ) - { - PerKeyDown( (joyId << 18) | (i +1) ); - } - else if ( buttonState == SDL_BUTTON_RELEASED ) - { - PerKeyUp( (joyId << 18) | (i +1) ); - } - } - } - - // execute yabause - if ( YabauseExec() != 0 ) - { - return -1; - } - - // return success - return 0; -} - -////////////////////////////////////////////////////////////////////////////// - -u32 PERSDLJoyScan( void ) { - // init vars - int joyId; - int i; - SDL_Joystick* joy; - Sint16 cur; - - // update joysticks states - SDL_JoystickUpdate(); - - // check each joysticks - for ( joyId = 0; joyId < SDL_PERCORE_JOYSTICKS_INITIALIZED; joyId++ ) - { - joy = SDL_PERCORE_JOYSTICKS[ joyId ].mJoystick; - - if ( !joy ) - { - continue; - } - - // check axis - for ( i = 0; i < SDL_JoystickNumAxes( joy ); i++ ) - { - cur = SDL_JoystickGetAxis( joy, i ); - - if ( cur != SDL_PERCORE_JOYSTICKS[ joyId ].mScanStatus[ i ] ) - { - if ( cur < -SDL_MEDIUM_AXIS_VALUE ) - { - return (joyId << 18) | SDL_MIN_AXIS_VALUE | i; - } - else if ( cur > SDL_MEDIUM_AXIS_VALUE ) - { - return (joyId << 18) | SDL_MAX_AXIS_VALUE | i; - } - } - } - - // check buttons - for ( i = 0; i < SDL_JoystickNumButtons( joy ); i++ ) - { - if ( SDL_JoystickGetButton( joy, i ) == SDL_BUTTON_PRESSED ) - { - return (joyId << 18) | (i +1); - break; - } - } - } - - return 0; -} - -void PERSDLJoyFlush(void) { -} - -void PERSDLKeyName(u32 key, char * name, UNUSED int size) -{ - sprintf(name, "%x", (int)key); -} - -#endif diff --git a/yabause/src/persdljoy.h b/yabause/src/persdljoy.h deleted file mode 100644 index 0a4aecc336..0000000000 --- a/yabause/src/persdljoy.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright 2006 Guillaume Duhamel - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PERSDLJOY_H -#define PERSDLJOY_H - -#include "peripheral.h" - -/** @addtogroup peripheral - * @{ */ -#define PERCORE_SDLJOY 3 - -extern PerInterface_struct PERSDLJoy; -/** @} */ - -#endif diff --git a/yabause/src/profile.c b/yabause/src/profile.c deleted file mode 100644 index 6b67e99ba6..0000000000 --- a/yabause/src/profile.c +++ /dev/null @@ -1,188 +0,0 @@ -/* copyright Patrick Kooman, 2002 - - Lightweight C & C++ profiler. Works both in - debug- and release mode. For more info, read: - - http://www.2dgame-tutorial.com/sdl/profile.htm - - You are free to use / modify / re-distribute this code. - - */ -#if !defined(SYS_PROFILE_H) && !defined(DONT_PROFILE) - -#include "profile.h" - -/* The time when the profiler initializes */ -clock_t g_init_time ; -/* Entries */ -entry_t g_tag [NUM_TAGS] ; -/* "high-water-mark" */ -int g_i_hwm = 0 ; -/* Is ProfileInit called? */ -int g_init = 0 ; - -/* Looks up given tag and returns the name, - of 0 if not found. */ -static entry_t* LookupTag (char* str_tag) { - int i ; - for (i = 0; i < g_i_hwm; ++i) { - if (strcmp (g_tag [i].str_name, str_tag) == 0) { - return &g_tag [i] ; - } - } - return 0 ; -} - -/* Checks whether the given tag is already started (nesting). - This is true when an entry with the given name is found, - for which the start_time_t is not 0. */ -static int Nested (char* str_tag) { - int i ; - for (i = 0; i < g_i_hwm; ++i) { - if (strcmp (g_tag [i].str_name, str_tag) == 0 && g_tag [i].start_time > -1) { - /* Already 'running': nested*/ - return 1 ; - } - } - /* Not running: not nested */ - return 0 ; -} - -/* Adds the given tag and return the entry it is stored into */ -static entry_t* AddTag (char* str_tag) { - if (g_i_hwm + 1 == NUM_TAGS) { - /* Full */ - return 0 ; - } - /* Copy the name */ - strcpy (g_tag [g_i_hwm].str_name, str_tag) ; - g_tag [g_i_hwm].start_time = -1 ; - /* Increase the high-water-mark but return the current index */ - return &g_tag [g_i_hwm++] ; -} - -/* Compare function for 'qsort' */ -static int CompareEntries (const void* p_1, const void* p_2) { - entry_t* p_entry1, *p_entry2 ; - /* Cast elements to entry_t type */ - p_entry1 = (entry_t*) p_1 ; - p_entry2 = (entry_t*) p_2 ; - /* Compare */ - return p_entry2->l_total_ms - p_entry1->l_total_ms ; -} - -/* Called on the first start-call. It receives the start-time */ -static void Init (void) { - memset (g_tag, 0, sizeof (g_tag)) ; - /* Retreive the time */ - g_init_time = clock () ; - /* Flag that this function has been called */ - g_init = 1 ; - g_i_hwm = 0 ; -} - -/* Prints profiling statistice to stdout, -sorted by percentage (descending) */ -void ProfilePrint (void) { - int i ; - long l_prof_time ; - if (g_i_hwm == 0) { - fprintf (stdout, "ProfilePrint: nothing to print.\n") ; - return ; - } - /* Retreive the time */ - l_prof_time = clock () - g_init_time ; - if (l_prof_time == 0) { - /* Avoid division by 0 */ - fprintf (stdout, "Warning: nothing to show because timer ran for less than 1 clock-tick.") ; - } - /* Print warnings for tags which are not stopped. */ - for (i = 0; i < g_i_hwm; ++i) { - if (g_tag [i].i_stopped == 0) { - g_tag [i].l_total_ms += clock () - g_tag [i].start_time ; - fprintf (stdout, "Warning: \"%s\" started but not stopped. (Done now, but result may be over-expensive!)\n", g_tag [i].str_name) ; - } - } - /* Sort the array desending */ - qsort (&g_tag, g_i_hwm, sizeof (entry_t), CompareEntries) ; - fprintf (stdout, "Profiler results (descending by percentage):\n\n") ; - for (i = 0; i < g_i_hwm; ++i) { - /* Print statistics */ - fprintf (stdout, "< calls: %2d, total ms: %3d, percentage: %3.1f%% > - \"%s\"\n", - g_tag [i].i_calls, - (int) ((double) g_tag [i].l_total_ms / CLOCKS_PER_SEC * 1000), - (double) g_tag [i].l_total_ms / l_prof_time * 100, - g_tag [i].str_name) ; - } -} - -/* Starts timer for given tag. If it does not exist yet, - it is added. - - Note: 1. The tag may not be nested with the same name - 2. The tag may not equal "" */ -void ProfileStart (char* str_tag) { - entry_t* p_entry ; - /* One the first call, we must initialize the profiler. */ - if (!g_init) { - Init () ; - } - /* Test for "" */ - if (*str_tag == '\0') { - fprintf (stdout, "ERROR in ProfileStart: a tag may not be \"\". Call is denied.") ; - return ; - } - /* Search the entry with the given name */ - p_entry = LookupTag (str_tag) ; - if (!p_entry) { - /* New tag, add it*/ - p_entry = AddTag (str_tag) ; - if (!p_entry) { - fprintf (stdout, "WARNING in ProfileStart: no more space to store the tag (\"%s\"). Increase NUM_TAGS in \"profile.h\". Call is denied.\n", str_tag) ; - return ; - } - } - /* Check for nesting of equal tag.*/ - if (Nested (str_tag)) { - fprintf (stdout, "ERROR in ProfileStart: nesting of equal tags not allowed (\"%s\"). Call is denied.\n", str_tag) ; - return ; - } - /* Increase the number of hits */ - ++p_entry->i_calls ; - /* Set the start time */ - p_entry->start_time = clock () ; - p_entry->i_stopped = 0 ; -} - -/* Stops timer for given tag. Checks for existence. - Adds the time between now and the Start call to the - total time.*/ -void ProfileStop (char* str_tag) { - clock_t end_time ; - entry_t* p_entry ; - /* Test for "" */ - if (*str_tag == '\0') { - fprintf (stdout, "ERROR in ProfileStop: a tag may not be \"\". Call is denied.") ; - return ; - } - /* Check for a existing name */ - p_entry = LookupTag (str_tag) ; - if (!p_entry) { - fprintf (stdout, "WARNING in ProfileStop: tag \"%s\" was never started. Call is denied.\n", str_tag) ; - return ; - } - /* Get the time */ - end_time = clock () ; - p_entry->l_total_ms += end_time - p_entry->start_time ; - /* Reset */ - p_entry->start_time = -1 ; - p_entry->i_stopped = 1 ; -} - -/* Resets the profiler. */ -void ProfileReset (void) { - Init () ; -} - -#endif /* !SYS_PROFILE_H && !DONT_PROFILE */ - diff --git a/yabause/src/profile.h b/yabause/src/profile.h deleted file mode 100644 index c89529f39c..0000000000 --- a/yabause/src/profile.h +++ /dev/null @@ -1,65 +0,0 @@ -/* copyright Patrick Kooman, 2002 - - Lightweight C & C++ profiler. Works both in - debug- and release mode. For more info, read: - - http://www.2dgame-tutorial.com/sdl/profile.htm - - You are free to use / modify / re-distribute this code. - - */ -#ifndef _PROFILE_H_ -#define _PROFILE_H_ - -#include -#include -#include -#include -#include - -#ifdef DONT_PROFILE -/* Profiling disabled: compiler won't generate machine instructions now. */ -#define PROFILE_START(t) -#define PROFILE_STOP(t) -#define PROFILE_PRINT() -#define PROFILE_RESET() -#else -/* Profiling enabled */ -#define MAX_TAG_LEN 100 -#define NUM_TAGS 100 - -typedef struct { - char str_name [MAX_TAG_LEN] ; - int i_calls ; - clock_t start_time ; - int i_stopped ; - long l_total_ms ; -} entry_t ; - -/* Compiler calls functions now. */ -#define PROFILE_START(t) ProfileStart (t) -#define PROFILE_STOP(t) ProfileStop (t) -#define PROFILE_PRINT() ProfilePrint () -#define PROFILE_RESET() ProfileReset () - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Start timer for given tag */ -void ProfileStart (char* str_tag) ; -/* Stops timer for given tag and add time to total time for this tag */ -void ProfileStop (char* str_tag) ; -/* Prints result to stdout */ -void ProfilePrint (void) ; -/* Resets the profiler. */ -void ProfileReset (void) ; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* NO_PROFILE */ - -#endif /* _PROFILE_H_ */ - diff --git a/yabause/src/psp/Makefile.am b/yabause/src/psp/Makefile.am deleted file mode 100644 index 5d95fbd291..0000000000 --- a/yabause/src/psp/Makefile.am +++ /dev/null @@ -1,82 +0,0 @@ -EXTRA_DIST = icache-funcs-2450.patch me-sectstart.c me-sectend.c \ - psp-logo.png sh2-core.i -CLEANFILES = me.elf me.prx me-exp.c me-test.elf me-test.prx melib.S \ - yabause.elf yabause.prx yabause.sfo EBOOT.PBP - -# yabause.{elf,prx} are only intermediate targets; the final target is -# EBOOT.PBP (but we keep the ELF/PRX files around for testing purposes). -if BUILD_ME_TEST -me_test=me-test.prx -else -me_test= -endif -all-local: EBOOT.PBP me.prx $(me_test) -.SECONDARY: yabause.elf yabause.prx me.elf me-test.elf - -######## - -noinst_PROGRAMS = yabause.elf me.elf me-test.elf - -yabause_elf_SOURCES = config.c control.c display.c filesel.c font.c gu.c \ - init.c localtime.c main.c menu.c misc.c osk.c profile.c \ - psp-cd.c psp-m68k.c psp-per.c psp-sh2.c psp-sound.c \ - psp-video.c psp-video-bitmap.c psp-video-rotate.c \ - psp-video-tilemap.c psp-video-tweaks.c \ - rtl.c rtl-mips.c rtlexec.c rtlinsn.c rtlopt.c rtlunit.c \ - satopt-sh2.c \ - sh2.c sh2-interpret.c sh2-opcodeinfo.c sh2-optimize.c \ - sys.c texcache.c threads.c timing.c yui.c \ - me-utility.c \ - \ - common.h config.h control.h display.h filesel.h font.h \ - gu.h init.h localtime.h menu.h misc.h osk.h profile.h \ - psp-cd.h psp-m68k.h psp-per.h psp-sh2.h psp-sound.h \ - psp-video.h psp-video-internal.h \ - rtl.h rtl-internal.h rtl-mips.h \ - satopt-sh2.h \ - sh2.h sh2-internal.h \ - sys.h texcache.h timing.h \ - me-utility.h -yabause_elf_DEPENDENCIES = me-sectstart.$(OBJEXT) me-sectend.$(OBJEXT) -nodist_yabause_elf_SOURCES = melib.S -yabause_elf_CFLAGS = $(YAB_CFLAGS) -Wpointer-arith -Wshadow -yabause_elf_LDADD = ../libyabause.a $(YAB_LIBS) -lpspsdk -yabause.elf: $(yabause_elf_OBJECTS) $(yabause_elf_DEPENDENCIES) ../libyabause.a - $(yabause_elf_LINK) \ - me-sectstart.$(OBJEXT) \ - $(yabause_elf_OBJECTS) \ - $(yabause_elf_LDADD) \ - $(LIBS) \ - me-sectend.$(OBJEXT) - -me_elf_SOURCES = me.c me.h -nodist_me_elf_SOURCES = me-exp.c -me_elf_CFLAGS = -Wpointer-arith -Wshadow -me_elf_LDFLAGS = -nostartfiles -me_elf_LIBS = -lpspkernel -me.elf: $(me_elf_OBJECTS) - $(me_elf_LINK) $(me_elf_OBJECTS) $(me_elf_LDADD) $(me_elf_LIBS) - -me_test_elf_SOURCES = me-test.c me-utility.c me-utility.h -nodist_me_test_elf_SOURCES = melib.S -me_test_elf_CFLAGS = -Wpointer-arith -Wshadow -me_test_elf_LIBS = -lc -lpspuser -me-test.elf: $(me_test_elf_OBJECTS) - $(me_test_elf_LINK) $(me_test_elf_OBJECTS) $(me_test_elf_LDADD) $(me_test_elf_LIBS) - -######## - -.elf.prx: - psp-fixup-imports $< - psp-prxgen $< $@ - -me-exp.c: me.exp - psp-build-exports -b $< >$@ -melib.S: me.exp - psp-build-exports -s $< - -yabause.sfo: - mksfoex -d MEMSIZE=1 "Yabause $(PACKAGE_VERSION)" $@ - -EBOOT.PBP: psp-logo.png yabause.prx yabause.sfo - pack-pbp $@ yabause.sfo $< NULL NULL NULL NULL yabause.prx NULL diff --git a/yabause/src/psp/common.h b/yabause/src/psp/common.h deleted file mode 100644 index c3ad5886d0..0000000000 --- a/yabause/src/psp/common.h +++ /dev/null @@ -1,258 +0,0 @@ -/* src/psp/common.h: Common header for PSP source files - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_COMMON_H -#define PSP_COMMON_H - -/**************************************************************************/ - -/* Various system headers */ - -#include -#include -#include -#define abs builtin_abs // Avoid shadowing warnings for common identifiers -#define div builtin_div -#include -#undef abs -#undef div -#define index builtin_index -#include -#undef index -#define remainder builtin_remainder -#define y0 builtin_y0 -#define y1 builtin_y1 -#include -#undef remainder -#undef y0 -#undef y1 - - -#define u8 pspsdk_u8 // Avoid type collisions with ../core.h -#define s8 pspsdk_s8 -#define u16 pspsdk_u16 -#define s16 pspsdk_s16 -#define u32 pspsdk_u32 -#define s32 pspsdk_s32 -#define u64 pspsdk_u64 -#define s64 pspsdk_s64 - -#ifdef PSP -# include -# include -# include -# include -# include -# include -# include -# include -# define PSP_SYSTEMPARAM_ID_INT_X_IS_CONFIRM 9 // Presumably, anyway -#endif - -#undef u8 -#undef s8 -#undef u16 -#undef s16 -#undef u32 -#undef s32 -#undef u64 -#undef s64 - -/* Helpful hints for GCC */ -#if defined(__GNUC__) && defined(PSP) -extern void sceKernelExitGame(void) __attribute__((noreturn)); -extern int sceKernelExitThread(int status) __attribute__((noreturn)); -extern int sceKernelExitDeleteThread(int status) __attribute__((noreturn)); -#endif - -/**************************************************************************/ - -/* Thread priority constants */ -enum { - THREADPRI_MAIN = 32, - THREADPRI_CD_READ = 25, - THREADPRI_UTILITY = 21, - THREADPRI_SOUND = 20, - THREADPRI_SYSTEM_CB = 15, -}; - -/*----------------------------------*/ - -/* Program directory (determined from argv[0]) */ -extern char progpath[256]; - -/* Saturn control pad handle (set at initialization time, and used by menu - * code to change button assignments) */ -extern void *padbits; - -/* Flag indicating whether the ME is available for use */ -extern int me_available; - -/* Have we successfully initialized the Yabause core? */ -extern int yabause_initted; - -/**************************************************************************/ - -/* Convenience macros (not PSP-related, except DSTART/DEND) */ - -/*----------------------------------*/ - -/* Get the length of an array */ -#define lenof(a) (sizeof((a)) / sizeof((a)[0])) -/* Bound a value between two limits (inclusive) */ -#define bound(x,low,high) __extension__({ \ - typeof(x) __x = (x); \ - typeof(low) __low = (low); \ - typeof(high) __high = (high); \ - __x < __low ? __low : __x > __high ? __high : __x; \ -}) - -/* Get offset of a structure member */ -#undef offsetof -#ifdef __GNUC__ -# define offsetof(type,member) __builtin_offsetof(type,member) -#else -# define offsetof(type,member) ((uintptr_t)&(((type *)0)->member)) -#endif - -/* Declare a function to be constant (i.e. not touching memory) */ -#undef CONST_FUNCTION -#ifdef __GNUC__ -# define CONST_FUNCTION __attribute__((const)) -#else -# define CONST_FUNCTION /*nothing*/ -#endif - -/* Force a function to be inlined if possible (use in place of "inline") */ -#ifdef __GNUC__ -# define ALWAYS_INLINE inline __attribute__((always_inline)) -#else -# define ALWAYS_INLINE inline -#endif - -/* Prevent a function from being inlined */ -#ifdef __GNUC__ -# define NOINLINE __attribute__((noinline)) -#else -# define NOINLINE /*nothing*/ -#endif - -/*----------------------------------*/ - -/* Convert a float to an int (optimized for PSP, but with alternate - * versions for testing on other systems) */ - -#ifdef PSP - -#define DEFINE_IFUNC(name,insn) \ -static inline CONST_FUNCTION int32_t name(const float x) { \ - float dummy; \ - int32_t result; \ - asm(insn : [result] "=r" (result), [dummy] "=f" (dummy) : [x] "f" (x)); \ - return result; \ -} - -DEFINE_IFUNC(ifloorf, "floor.w.s %[dummy],%[x]; mfc1 %[result],%[dummy]") -DEFINE_IFUNC(iceilf, "ceil.w.s %[dummy],%[x]; mfc1 %[result],%[dummy]") -DEFINE_IFUNC(itruncf, "trunc.w.s %[dummy],%[x]; mfc1 %[result],%[dummy]") -DEFINE_IFUNC(iroundf, "round.w.s %[dummy],%[x]; mfc1 %[result],%[dummy]") - -#elif HAVE_FLOORF - -static inline CONST_FUNCTION int ifloorf(float x) {return (int)floorf(x);} -static inline CONST_FUNCTION int iceilf (float x) {return (int)ceilf(x);} -static inline CONST_FUNCTION int itruncf(float x) {return (int)truncf(x);} -static inline CONST_FUNCTION int iroundf(float x) {return (int)roundf(x);} - -#else // !PSP && !HAVE_FLOORF --> use double-precision floor() and ceil() - -static inline CONST_FUNCTION int ifloorf(float x) {return (int)floor(x);} -static inline CONST_FUNCTION int iceilf (float x) {return (int)ceil(x);} -static inline CONST_FUNCTION int itruncf(float x) - {return (x)<0 ? (int)-floor(-x) : (int)floor(x);} -static inline CONST_FUNCTION int iroundf(float x) {return (int)floor(x+0.5f);} - -#endif - -/*----------------------------------*/ - -#ifdef PSP_DEBUG - -/* Debug/error message macro. DMSG("message",...) prints to stderr a line - * in the form: - * func_name(file:line): message - * printf()-style format tokens and arguments are allowed, and no newline - * is required at the end. The format string must be a literal string - * constant. Note that we sprintf() into a buffer and write the buffer - * rather than calling fprintf() directly because fprintf() makes multiple - * low-level write calls, which can slow the program down significantly - * depending on PSPlink's responsiveness on the PC host. */ -/* global shared */ char DMSG_buffer[10000]; -#define DMSG(msg,...) do { \ - snprintf(DMSG_buffer, sizeof(DMSG_buffer), "%s(%s:%d): " msg "\n", \ - __FUNCTION__, __FILE__, __LINE__ , ## __VA_ARGS__); \ - fputs(DMSG_buffer, stderr); \ -} while (0) - -/* Timing macro. Start timing with DSTART(); DEND() will then print the - * elapsed time in microseconds. Both must occur at the same level of - * block nesting. */ -#define DSTART() { const uint32_t __start = sceKernelGetSystemTimeLow() -#define DEND() DMSG("time=%u", sceKernelGetSystemTimeLow() - __start); } - -#else // !PSP_DEBUG - -/* Disable debug output */ -#define DMSG(msg,...) /*nothing*/ -#define DSTART() /*nothing*/ -#define DEND() /*nothing*/ - -#endif - -/*----------------------------------*/ - -/* Test a precondition, and perform the given action if it fails */ - -#define PRECOND(condition,fail_action) do { \ - if (UNLIKELY(!(condition))) { \ - DMSG("PRECONDITION FAILED: %s", #condition); \ - fail_action; \ - } \ -} while (0) - -/**************************************************************************/ - -/* Include the Yabause core header for other common definitions/declarations */ - -#include "../core.h" - -/**************************************************************************/ - -#endif // PSP_COMMON_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/config.c b/yabause/src/psp/config.c deleted file mode 100644 index 3fdf998e98..0000000000 --- a/yabause/src/psp/config.c +++ /dev/null @@ -1,842 +0,0 @@ -/* src/psp/config.c: Configuration data management for PSP - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "config.h" -#include "psp-sh2.h" -#include "psp-video.h" -#include "sh2.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Configuration file name (always stored in program directory) */ -#define PATH_INI "yabause.ini" - -/* Data file paths */ -static char path_bios[256] = "bios.bin"; -static char path_cd[256] = "cd.iso"; -static char path_bup[256] = "backup.bin"; - -/* General settings */ -static int start_in_emu = 0; -static int use_me = 0; -static uint32_t me_writeback_period = 1; -static uint32_t me_uncached_boundary = 0x800; -static int bup_autosave = 1; - -/* Button configuration */ -static uint32_t button[6] = { - [CONFIG_BUTTON_A] = PSP_CTRL_CROSS, - [CONFIG_BUTTON_B] = PSP_CTRL_CIRCLE, - [CONFIG_BUTTON_C] = 0, - [CONFIG_BUTTON_X] = PSP_CTRL_SQUARE, - [CONFIG_BUTTON_Y] = PSP_CTRL_TRIANGLE, - [CONFIG_BUTTON_Z] = 0, -}; - -/* Module selections */ -static int module_sh2 = SH2CORE_PSP; -static int module_video = VIDCORE_PSP; - -/* Display settings */ -static int cache_textures = 1; -static int smooth_textures = 0; -static int smooth_hires = 0; -static int enable_rotate = 1; -static int optimize_rotate = 1; -static int frameskip_auto = 0; -static int frameskip_num = 0; -static int frameskip_interlace = 1; -static int frameskip_rotate = 1; -static int show_fps = 0; - -static uint32_t sh2_optimizations = SH2_OPTIMIZE_ASSUME_SAFE_DIVISION - | SH2_OPTIMIZE_BRANCH_TO_RTS - | SH2_OPTIMIZE_FOLD_SUBROUTINES - | SH2_OPTIMIZE_LOCAL_ACCESSES - | SH2_OPTIMIZE_LOCAL_POINTERS - | SH2_OPTIMIZE_MAC_NOSAT - | SH2_OPTIMIZE_POINTERS - | SH2_OPTIMIZE_POINTERS_MAC - | SH2_OPTIMIZE_STACK; -/* All known optimization flags (so we can leave newly-implemented flags at - * their default values when loading the config file) */ -#define SH2_KNOWN_OPTIMIZATIONS (SH2_OPTIMIZE_ASSUME_SAFE_DIVISION \ - | SH2_OPTIMIZE_BRANCH_TO_RTS \ - | SH2_OPTIMIZE_FOLD_SUBROUTINES \ - | SH2_OPTIMIZE_LOCAL_ACCESSES \ - | SH2_OPTIMIZE_LOCAL_POINTERS \ - | SH2_OPTIMIZE_MAC_NOSAT \ - | SH2_OPTIMIZE_POINTERS \ - | SH2_OPTIMIZE_POINTERS_MAC \ - | SH2_OPTIMIZE_STACK) - -/* Deciline (precise timing) mode flag */ -static int deciline_mode = 0; -/* Audio sync flag */ -static int audio_sync = 1; -/* Clock sync flag */ -static int clock_sync = 1; -/* Start-from-fixed-time flag */ -static int clock_fixed_time = 0; - -/*-----------------------------------------------------------------------*/ - -/* Local function declarations */ - -static int parse_string(const char *file, int line, const char *name, - const char *text, char *buffer, unsigned int bufsize); -static int parse_int(const char *file, int line, const char *name, - const char *text, int *value_ret); -static int parse_uint32(const char *file, int line, const char *name, - const char *text, uint32_t *value_ret); - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * config_load: Load configuration data from the configuration file. - * Invalid data is ignored, and options not specified in the configuration - * file are left unchanged. - * - * [Parameters] - * None - * [Return value] - * None - */ -void config_load(void) -{ - /* Open the configuration file, aborting if it's not available */ - FILE *f = fopen(PATH_INI, "r"); - if (!f) { - perror("fopen(" PATH_INI ")"); - return; - } - - /* Read the entire file in at once and close the file pointer */ - char *filebuf; - if (fseek(f, 0, SEEK_END) < 0) { - perror("fseek(SEEK_END)"); - close_and_return: - fclose(f); - return; - } - long filesize = ftell(f); - if (filesize < 0) { - perror("ftell()"); - goto close_and_return; - } - if (fseek(f, 0, SEEK_SET) < 0) { - perror("fseek(SEEK_SET)"); - goto close_and_return; - } - filebuf = malloc(filesize+1); // Leave space for a trailing \0 - if (!filebuf) { - fprintf(stderr, "No memory for config file buffer (%ld bytes)\n", - filesize); - goto close_and_return; - } - if (fread(filebuf, filesize, 1, f) != 1) { - fprintf(stderr, "Failed to read config file\n"); - free(filebuf); - goto close_and_return; - } - fclose(f); - filebuf[filesize] = 0; - - /* Parse each line of the configuration file; lines are of the form - * name=value - * with no spaces permitted on either side of the "=". We take care - * to treat names as case-insensitive and to support any of "\r", - * "\r\n" or "\n" as a line terminator, in case people edit the file - * on their own. */ - - char *s, *eol; - int line; - for (s = filebuf, line = 1; *s; s = eol, line++) { - - eol = s + strcspn(s, "\r\n"); - if (*eol == '\r') { - *eol++ = 0; - } - if (*eol == '\n') { - *eol++ = 0; - } - char *name = s; - char *value = strchr(s, '='); - if (!value) { - fprintf(stderr, "%s:%d: Missing `='\n", PATH_INI, line); - continue; - } - *value++ = 0; - - if (stricmp(name, "path_bios") == 0) { - parse_string(PATH_INI, line, name, value, - path_bios, sizeof(path_bios)); - - } else if (stricmp(name, "path_cd") == 0) { - parse_string(PATH_INI, line, name, value, - path_cd, sizeof(path_cd)); - - } else if (stricmp(name, "path_bup") == 0) { - parse_string(PATH_INI, line, name, value, - path_bup, sizeof(path_bup)); - - } else if (stricmp(name, "start_in_emu") == 0) { - parse_int(PATH_INI, line, name, value, &start_in_emu); - - } else if (stricmp(name, "use_me") == 0) { - parse_int(PATH_INI, line, name, value, &use_me); - - } else if (stricmp(name, "me_writeback_period") == 0) { - parse_uint32(PATH_INI, line, name, value, &me_writeback_period); - if (!me_writeback_period - || (me_writeback_period & (me_writeback_period - 1)) - ) { - fprintf(stderr, "config_load(): Invalid value %u for" - " me_writeback_period (must be a power of 2)\n", - me_writeback_period); - me_writeback_period = 1; - } - - } else if (stricmp(name, "me_uncached_boundary") == 0) { - parse_uint32(PATH_INI, line, name, value, &me_uncached_boundary); - if (me_uncached_boundary > 0x80000) { - me_uncached_boundary = 0x80000; - } - - } else if (stricmp(name, "bup_autosave") == 0) { - parse_int(PATH_INI, line, name, value, &bup_autosave); - - } else if (stricmp(name, "button.A") == 0) { - parse_uint32(PATH_INI, line, name, value,&button[CONFIG_BUTTON_A]); - - } else if (stricmp(name, "button.B") == 0) { - parse_uint32(PATH_INI, line, name, value,&button[CONFIG_BUTTON_B]); - - } else if (stricmp(name, "button.C") == 0) { - parse_uint32(PATH_INI, line, name, value,&button[CONFIG_BUTTON_C]); - - } else if (stricmp(name, "button.X") == 0) { - parse_uint32(PATH_INI, line, name, value,&button[CONFIG_BUTTON_X]); - - } else if (stricmp(name, "button.Y") == 0) { - parse_uint32(PATH_INI, line, name, value,&button[CONFIG_BUTTON_Y]); - - } else if (stricmp(name, "button.Z") == 0) { - parse_uint32(PATH_INI, line, name, value,&button[CONFIG_BUTTON_Z]); - - } else if (stricmp(name, "module_sh2") == 0) { - parse_int(PATH_INI, line, name, value, &module_sh2); - - } else if (stricmp(name, "module_video") == 0) { - parse_int(PATH_INI, line, name, value, &module_video); - - } else if (stricmp(name, "cache_textures") == 0) { - parse_int(PATH_INI, line, name, value, &cache_textures); - - } else if (stricmp(name, "smooth_textures") == 0) { - parse_int(PATH_INI, line, name, value, &smooth_textures); - - } else if (stricmp(name, "smooth_hires") == 0) { - parse_int(PATH_INI, line, name, value, &smooth_hires); - - } else if (stricmp(name, "enable_rotate") == 0) { - parse_int(PATH_INI, line, name, value, &enable_rotate); - - } else if (stricmp(name, "optimize_rotate") == 0) { - parse_int(PATH_INI, line, name, value, &optimize_rotate); - - } else if (stricmp(name, "frameskip_auto") == 0) { - parse_int(PATH_INI, line, name, value, &frameskip_auto); - - } else if (stricmp(name, "frameskip_num") == 0) { - parse_int(PATH_INI, line, name, value, &frameskip_num); - if (frameskip_num < 0) { - frameskip_num = 0; - } else if (frameskip_num > 9) { - frameskip_num = 9; - } - - } else if (stricmp(name, "frameskip_interlace") == 0) { - parse_int(PATH_INI, line, name, value, &frameskip_interlace); - - } else if (stricmp(name, "frameskip_rotate") == 0) { - parse_int(PATH_INI, line, name, value, &frameskip_rotate); - - } else if (stricmp(name, "show_fps") == 0) { - parse_int(PATH_INI, line, name, value, &show_fps); - - } else if (stricmp(name, "sh2_optimizations") == 0) { - uint32_t newval = strtoul(value, &s, 10); - if (*s != '/') { - fprintf(stderr, "%s:%d: Bad format for `%s' value\n", - PATH_INI, line, name); - continue; - } - uint32_t mask = strtoul(s+1, &s, 10); - if (*s) { - fprintf(stderr, "%s:%d: Bad format for `%s' value\n", - PATH_INI, line, name); - continue; - } - sh2_optimizations &= ~mask; - sh2_optimizations |= newval & mask; - - } else if (stricmp(name, "deciline_mode") == 0) { - parse_int(PATH_INI, line, name, value, &deciline_mode); - - } else if (stricmp(name, "audio_sync") == 0) { - parse_int(PATH_INI, line, name, value, &audio_sync); - - } else if (stricmp(name, "clock_sync") == 0) { - parse_int(PATH_INI, line, name, value, &clock_sync); - - } else if (stricmp(name, "clock_fixed_time") == 0) { - parse_int(PATH_INI, line, name, value, &clock_fixed_time); - - } else { - fprintf(stderr, "%s:%d: Unknown configuration variable `%s'\n", - PATH_INI, line, name); - - } - - } // for (s = filebuf, line = 1; *s; s = eol, line++) -} - -/*-----------------------------------------------------------------------*/ - -/** - * config_save: Save the current configuration to the configuration file. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on error - */ -int config_save(void) -{ - FILE *f = fopen(PATH_INI, "w"); - if (!f) { - perror("fopen(" PATH_INI ")"); - return 0; - } - - if (fprintf(f, "path_bios=%s\n", path_bios ) < 0 - || fprintf(f, "path_cd=%s\n", path_cd ) < 0 - || fprintf(f, "path_bup=%s\n", path_bup ) < 0 - || fprintf(f, "start_in_emu=%d\n", start_in_emu ) < 0 - || fprintf(f, "use_me=%d\n", use_me ) < 0 - || fprintf(f, "me_writeback_period=%u\n", me_writeback_period ) < 0 - || fprintf(f, "me_uncached_boundary=%u\n", me_uncached_boundary ) < 0 - || fprintf(f, "bup_autosave=%d\n", bup_autosave ) < 0 - || fprintf(f, "button.A=%u\n", button[CONFIG_BUTTON_A]) < 0 - || fprintf(f, "button.B=%u\n", button[CONFIG_BUTTON_B]) < 0 - || fprintf(f, "button.C=%u\n", button[CONFIG_BUTTON_C]) < 0 - || fprintf(f, "button.X=%u\n", button[CONFIG_BUTTON_X]) < 0 - || fprintf(f, "button.Y=%u\n", button[CONFIG_BUTTON_Y]) < 0 - || fprintf(f, "button.Z=%u\n", button[CONFIG_BUTTON_Z]) < 0 - || fprintf(f, "module_sh2=%d\n", module_sh2 ) < 0 - || fprintf(f, "module_video=%d\n", module_video ) < 0 - || fprintf(f, "cache_textures=%d\n", cache_textures ) < 0 - || fprintf(f, "smooth_textures=%d\n", smooth_textures ) < 0 - || fprintf(f, "smooth_hires=%d\n", smooth_hires ) < 0 - || fprintf(f, "enable_rotate=%d\n", enable_rotate ) < 0 - || fprintf(f, "optimize_rotate=%d\n", optimize_rotate ) < 0 - || fprintf(f, "frameskip_auto=%d\n", frameskip_auto ) < 0 - || fprintf(f, "frameskip_num=%d\n", frameskip_num ) < 0 - || fprintf(f, "frameskip_interlace=%d\n", frameskip_interlace ) < 0 - || fprintf(f, "frameskip_rotate=%d\n", frameskip_rotate ) < 0 - || fprintf(f, "show_fps=%d\n", show_fps ) < 0 - || fprintf(f, "sh2_optimizations=%u/%u\n", sh2_optimizations, - SH2_KNOWN_OPTIMIZATIONS) < 0 - || fprintf(f, "deciline_mode=%d\n", deciline_mode ) < 0 - || fprintf(f, "audio_sync=%d\n", audio_sync ) < 0 - || fprintf(f, "clock_sync=%d\n", clock_sync ) < 0 - || fprintf(f, "clock_fixed_time=%d\n", clock_fixed_time ) < 0 - ) { - perror("fprintf(" PATH_INI ",...)"); - fclose(f); - return 0; - } - - if (fclose(f) < 0) { - perror("fclose(" PATH_INI ")"); - return 0; - } - - return 1; -} - -/*************************************************************************/ - -/** - * config_get_*: Retrieve the current value of a configuration variable. - * - * [Parameters] - * id: Button ID (only for config_get_button()) - * [Return value] - * Current value of configuration variable - */ - -const char *config_get_path_bios(void) -{ - return path_bios; -} - -const char *config_get_path_cd(void) -{ - return path_cd; -} - -const char *config_get_path_bup(void) -{ - return path_bup; -} - -int config_get_start_in_emu(void) -{ - return start_in_emu; -} - -int config_get_use_me(void) -{ - return use_me; -} - -uint32_t config_get_me_writeback_period(void) -{ - return me_writeback_period; -} - -uint32_t config_get_me_uncached_boundary(void) -{ - return me_uncached_boundary; -} - -int config_get_bup_autosave(void) -{ - return bup_autosave; -} - -uint32_t config_get_button(ConfigButtonID id) -{ - PRECOND(id >= CONFIG_BUTTON_A && id <= CONFIG_BUTTON_Z, return 0); - return button[id]; -} - -int config_get_module_sh2(void) -{ - return module_sh2; -} - -int config_get_module_video(void) -{ - return module_video; -} - -int config_get_cache_textures(void) -{ - return cache_textures; -} - -int config_get_smooth_textures(void) -{ - return smooth_textures; -} - -int config_get_smooth_hires(void) -{ - return smooth_hires; -} - -int config_get_enable_rotate(void) -{ - return enable_rotate; -} - -int config_get_optimize_rotate(void) -{ - return optimize_rotate; -} - -int config_get_frameskip_auto(void) -{ - return frameskip_auto; -} - -int config_get_frameskip_num(void) -{ - return frameskip_num; -} - -int config_get_frameskip_interlace(void) -{ - return frameskip_interlace; -} - -int config_get_frameskip_rotate(void) -{ - return frameskip_rotate; -} - -int config_get_show_fps(void) -{ - return show_fps; -} - -uint32_t config_get_sh2_optimizations(void) -{ - return sh2_optimizations; -} - -int config_get_deciline_mode(void) -{ - return deciline_mode; -} - -int config_get_audio_sync(void) -{ - return audio_sync; -} - -int config_get_clock_sync(void) -{ - return clock_sync; -} - -int config_get_clock_fixed_time(void) -{ - return clock_fixed_time; -} - -/*-----------------------------------------------------------------------*/ - -/** - * config_set_*: Set the value of a configuration variable. - * - * [Parameters] - * id: Button ID (only for config_get_button()) - * value: New value for configuration variable - * [Return value] - * Nonzero on success, zero on error - */ - -int config_set_path_bios(const char *value) -{ - PRECOND(value != NULL, return 0); - if (strlen(value) > sizeof(path_bios) - 1) { - fprintf(stderr, "config_set_path_bios(): Value too long (max %d" - " characters): %s\n", sizeof(path_bios) - 1, value); - return 0; - } - strcpy(path_bios, value); // Safe - return 1; -} - -int config_set_path_cd(const char *value) -{ - PRECOND(value != NULL, return 0); - if (strlen(value) > sizeof(path_cd) - 1) { - fprintf(stderr, "config_set_path_cd(): Value too long (max %d" - " characters): %s\n", sizeof(path_cd) - 1, value); - return 0; - } - strcpy(path_cd, value); // Safe - return 1; -} - -int config_set_path_bup(const char *value) -{ - PRECOND(value != NULL, return 0); - if (strlen(value) > sizeof(path_bup) - 1) { - fprintf(stderr, "config_set_path_bup(): Value too long (max %d" - " characters): %s\n", sizeof(path_bup) - 1, value); - return 0; - } - strcpy(path_bup, value); // Safe - return 1; -} - -int config_set_start_in_emu(int value) -{ - start_in_emu = value ? 1 : 0; - return 1; -} - -int config_set_use_me(int value) -{ - use_me = value ? 1 : 0; - return 1; -} - -int config_set_me_writeback_period(uint32_t value) -{ - if (value == 0 || (value & (value-1))) { - fprintf(stderr, "config_set_me_writeback_period(): Invalid period %u" - " (must be a power of 2)\n", value); - return 0; - } - me_writeback_period = value; - return 1; -} - -int config_set_me_uncached_boundary(uint32_t value) -{ - if (value > 0x80000) { - fprintf(stderr, "config_set_me_uncached_boundary(): Invalid boundary" - " %u (maximum %u)\n", value, 0x80000); - return 0; - } - me_uncached_boundary = value; - return 1; -} - -int config_set_bup_autosave(int value) -{ - bup_autosave = value ? 1 : 0; - return 1; -} - -int config_set_button(ConfigButtonID id, uint32_t value) -{ - PRECOND(id >= CONFIG_BUTTON_A && id <= CONFIG_BUTTON_Z, return 0); - button[id] = value; - return 1; -} - -int config_set_module_sh2(int value) -{ - module_sh2 = value; - return 1; -} - -int config_set_module_video(int value) -{ - module_video = value; - return 1; -} - -int config_set_cache_textures(int value) -{ - cache_textures = value ? 1 : 0; - return 1; -} - -int config_set_smooth_textures(int value) -{ - smooth_textures = value ? 1 : 0; - return 1; -} - -int config_set_smooth_hires(int value) -{ - smooth_hires = value ? 1 : 0; - return 1; -} - -int config_set_enable_rotate(int value) -{ - enable_rotate = value ? 1 : 0; - return 1; -} - -int config_set_optimize_rotate(int value) -{ - optimize_rotate = value ? 1 : 0; - return 1; -} - -int config_set_frameskip_auto(int value) -{ - frameskip_auto = value ? 1 : 0; - return 1; -} - -int config_set_frameskip_num(int value) -{ - if (value < 0) { - frameskip_num = 0; - } else if (value > 9) { - frameskip_num = 9; - } else { - frameskip_num = value; - } - return 1; -} - -int config_set_frameskip_interlace(int value) -{ - frameskip_interlace = value ? 1 : 0; - return 1; -} - -int config_set_frameskip_rotate(int value) -{ - frameskip_rotate = value ? 1 : 0; - return 1; -} - -int config_set_show_fps(int value) -{ - show_fps = value ? 1 : 0; - return 1; -} - -int config_set_sh2_optimizations(uint32_t value) -{ - sh2_optimizations = value & SH2_KNOWN_OPTIMIZATIONS; - return 1; -} - -int config_set_deciline_mode(int value) -{ - deciline_mode = value ? 1 : 0; - return 1; -} - -int config_set_audio_sync(int value) -{ - audio_sync = value ? 1 : 0; - return 1; -} - -int config_set_clock_sync(int value) -{ - clock_sync = value ? 1 : 0; - return 1; -} - -int config_set_clock_fixed_time(int value) -{ - clock_fixed_time = value ? 1 : 0; - return 1; -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * parse_string: Parse a string-type configuration entry. - * - * [Parameters] - * file: Name of configuration file (for error messages) - * line: Line number in configuration file (for error messages) - * name: Configuration entry name (for error messages) - * text: Configuration value text - * buffer: Buffer into which to store string value - * bufsize: Size of buffer (maximum string length + 1) - * [Return value] - * Nonzero on success, zero on error - */ -static int parse_string(const char *file, int line, const char *name, - const char *text, char *buffer, unsigned int bufsize) -{ - PRECOND(text != NULL, return 0); - PRECOND(buffer != NULL, return 0); - - if (strlen(text) > bufsize - 1) { - fprintf(stderr, "%s:%d: String for `%s' too long (max %d" - " characters)\n", file, line, name, bufsize - 1); - return 0; - } - strcpy(buffer, text); // Safe - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * parse_int: Parse an integer-type configuration entry. - * - * [Parameters] - * file: Name of configuration file (for error messages) - * line: Line number in configuration file (for error messages) - * name: Configuration entry name (for error messages) - * text: Configuration value text - * value_ret: Pointer to variable into which to store integer value - * [Return value] - * Nonzero on success, zero on error - */ -static int parse_int(const char *file, int line, const char *name, - const char *text, int *value_ret) -{ - PRECOND(text != NULL, return 0); - PRECOND(value_ret != NULL, return 0); - - char *s; - int newval = strtol(text, &s, 10); - if (*s) { - fprintf(stderr, "%s:%d: Value for `%s' must be a number\n", - file, line, name); - return 0; - } - *value_ret = newval; - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * parse_uint32: Parse a 32-bit unsigned integer configuration entry. - * - * [Parameters] - * file: Name of configuration file (for error messages) - * line: Line number in configuration file (for error messages) - * name: Configuration entry name (for error messages) - * text: Configuration value text - * value_ret: Pointer to variable into which to store integer value - * [Return value] - * Nonzero on success, zero on error - */ -static int parse_uint32(const char *file, int line, const char *name, - const char *text, uint32_t *value_ret) -{ - PRECOND(text != NULL, return 0); - PRECOND(value_ret != NULL, return 0); - - char *s; - uint32_t newval = strtoul(text, &s, 10); - if (*s) { - fprintf(stderr, "%s:%d: Value for `%s' must be a nonnegative number\n", - file, line, name); - return 0; - } - *value_ret = newval; - return 1; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/config.h b/yabause/src/psp/config.h deleted file mode 100644 index 9b55bdbe05..0000000000 --- a/yabause/src/psp/config.h +++ /dev/null @@ -1,144 +0,0 @@ -/* src/psp/config.h: Header for configuration data management for PSP - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_CONFIG_H -#define PSP_CONFIG_H - -/*************************************************************************/ - -/** - * CONFIG_BUTTON_*: Constants identifying Saturn controller buttons which - * are passed to the config_get_button() and config_set_button() functions. - */ -typedef enum ConfigButtonID_ { - CONFIG_BUTTON_A = 0, - CONFIG_BUTTON_B, - CONFIG_BUTTON_C, - CONFIG_BUTTON_X, - CONFIG_BUTTON_Y, - CONFIG_BUTTON_Z, -} ConfigButtonID; - -/** - * config_load: Load configuration data from the configuration file. - * Invalid data is ignored, and options not specified in the configuration - * file are left unchanged. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void config_load(void); - -/** - * config_save: Save the current configuration to the configuration file. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on error - */ -extern int config_save(void); - -/** - * config_get_*: Retrieve the current value of a configuration variable. - * - * [Parameters] - * id: Button ID (only for config_get_button()) - * [Return value] - * Current value of configuration variable - */ -extern const char *config_get_path_bios(void); -extern const char *config_get_path_cd(void); -extern const char *config_get_path_bup(void); -extern int config_get_start_in_emu(void); -extern int config_get_use_me(void); -extern uint32_t config_get_me_writeback_period(void); -extern uint32_t config_get_me_uncached_boundary(void); -extern int config_get_bup_autosave(void); -extern uint32_t config_get_button(ConfigButtonID id); -extern int config_get_module_sh2(void); -extern int config_get_module_video(void); -extern int config_get_cache_textures(void); -extern int config_get_smooth_textures(void); -extern int config_get_smooth_hires(void); -extern int config_get_enable_rotate(void); -extern int config_get_optimize_rotate(void); -extern int config_get_frameskip_auto(void); -extern int config_get_frameskip_num(void); -extern int config_get_frameskip_interlace(void); -extern int config_get_frameskip_rotate(void); -extern int config_get_show_fps(void); -extern uint32_t config_get_sh2_optimizations(void); -extern int config_get_deciline_mode(void); -extern int config_get_audio_sync(void); -extern int config_get_clock_sync(void); -extern int config_get_clock_fixed_time(void); - -/** - * config_set_*: Set the value of a configuration variable. - * - * [Parameters] - * id: Button ID (only for config_get_button()) - * value: New value for configuration variable - * [Return value] - * Nonzero on success, zero on error - */ -extern int config_set_path_bios(const char *value); -extern int config_set_path_cd(const char *value); -extern int config_set_path_bup(const char *value); -extern int config_set_start_in_emu(int value); -extern int config_set_use_me(int value); -extern int config_set_me_writeback_period(uint32_t value); -extern int config_set_me_uncached_boundary(uint32_t value); -extern int config_set_bup_autosave(int value); -extern int config_set_button(ConfigButtonID id, uint32_t value); -extern int config_set_module_sh2(int value); -extern int config_set_module_video(int value); -extern int config_set_cache_textures(int value); -extern int config_set_smooth_textures(int value); -extern int config_set_smooth_hires(int value); -extern int config_set_enable_rotate(int value); -extern int config_set_optimize_rotate(int value); -extern int config_set_frameskip_auto(int value); -extern int config_set_frameskip_num(int value); -extern int config_set_frameskip_interlace(int value); -extern int config_set_frameskip_rotate(int value); -extern int config_set_show_fps(int value); -extern int config_set_sh2_optimizations(uint32_t value); -extern int config_set_deciline_mode(int value); -extern int config_set_audio_sync(int value); -extern int config_set_clock_sync(int value); -extern int config_set_clock_fixed_time(int value); - -/*************************************************************************/ - -#endif // PSP_CONFIG_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/control.c b/yabause/src/psp/control.c deleted file mode 100644 index 74867344aa..0000000000 --- a/yabause/src/psp/control.c +++ /dev/null @@ -1,139 +0,0 @@ -/* src/psp/control.c: PSP controller input management routines - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "control.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Current bitmask of buttons pressed */ -static uint32_t buttons; - -/* Previous value of "buttons" */ -static uint32_t last_buttons; - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * control_init: Initialize the controller input management code. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on error - */ -int control_init(void) -{ - sceCtrlSetSamplingCycle(0); - sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); - buttons = last_buttons = 0; - - return 1; -} - -/*************************************************************************/ - -/** - * control_update: Update the current controller status. - * - * [Parameters] - * None - * [Return value] - * None - */ -void control_update(void) -{ - SceCtrlData pad_data; - sceCtrlPeekBufferPositive(&pad_data, 1); - - last_buttons = buttons; - buttons = pad_data.Buttons; - - /* If the directional pad isn't being used, check the analog pad instead */ - if (!(buttons & 0x00F0)) { - if (pad_data.Lx < 32) { - buttons |= PSP_CTRL_LEFT; - } else if (pad_data.Lx >= 224) { - buttons |= PSP_CTRL_RIGHT; - } - if (pad_data.Ly < 32) { - buttons |= PSP_CTRL_UP; - } else if (pad_data.Ly >= 224) { - buttons |= PSP_CTRL_DOWN; - } - } - - /* The OS doesn't seem to reset the screensaver timeout when the - * analog pad is moved, so take care of that ourselves */ - if (pad_data.Lx < 32 || pad_data.Lx >= 224 - || pad_data.Ly < 32 || pad_data.Ly >= 224 - ) { - scePowerTick(0); - } -} - -/*************************************************************************/ - -/** - * control_state: Return the current controller state. - * - * [Parameters] - * None - * [Return value] - * Current controller state (PSP_CTRL_* bitmask of buttons held down) - */ -uint32_t control_state(void) -{ - return buttons; -} - -/*-----------------------------------------------------------------------*/ - -/** - * control_new_buttons: Return any buttons newly pressed in the last call - * to control_update(). - * - * [Parameters] - * None - * [Return value] - * Newly pressed buttons (PSP_CTRL_* bitmask) - */ -uint32_t control_new_buttons(void) -{ - return buttons & ~last_buttons; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/control.h b/yabause/src/psp/control.h deleted file mode 100644 index e99e84d731..0000000000 --- a/yabause/src/psp/control.h +++ /dev/null @@ -1,79 +0,0 @@ -/* src/psp/control.c: PSP controller input management routines - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_CONTROL_H -#define PSP_CONTROL_H - -/*************************************************************************/ - -/** - * control_init: Initialize the controller input management code. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on error - */ -extern int control_init(void); - -/** - * control_update: Update the current controller status. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void control_update(void); - -/** - * control_state: Return the current controller status. - * - * [Parameters] - * None - * [Return value] - * Current controller status (PSP_CTRL_* bitmask of buttons held down) - */ -extern uint32_t control_state(void); - -/** - * control_new_buttons: Return any buttons newly pressed in the last call - * to control_update(). - * - * [Parameters] - * None - * [Return value] - * Newly pressed buttons (PSP_CTRL_* bitmask) - */ -extern uint32_t control_new_buttons(void); - -/*************************************************************************/ - -#endif // PSP_CONTROL_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/display.c b/yabause/src/psp/display.c deleted file mode 100644 index 701461a555..0000000000 --- a/yabause/src/psp/display.c +++ /dev/null @@ -1,603 +0,0 @@ -/* src/psp/display.c: PSP display management functions - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "display.h" -#include "gu.h" -#include "sys.h" - -/*************************************************************************/ - -/* Effective display size */ -static unsigned int display_width, display_height; - -/* Display mode (pixel format) and bits per pixel */ -static uint8_t display_mode; -static uint8_t display_bpp; - -/* Currently displayed (front) buffer index */ -static uint8_t displayed_surface; - -/* Work (back) buffer index */ -static uint8_t work_surface; - -/* Pointers into VRAM */ -static void *surfaces[2]; // Display buffers -static uint8_t *vram_spare_ptr; // Spare VRAM (above display buffers) -static uint8_t *vram_next_alloc; // Next spare address to allocate -static uint8_t *vram_top; // Top of VRAM - -/* Display list */ -/* Size note: A single VDP2 background layer, if at resolution 704x512, - * can take up to 500k of display list memory to render. */ -static uint8_t __attribute__((aligned(64))) display_list[3*1024*1024]; - -/* Semaphore flag to indicate whether there is a buffer swap pending; while - * true, the main thread must not access any other variables */ -static int swap_pending; - -/* System clock after the sceDisplayWaitVblankStart() starting the last frame*/ -static uint32_t last_frame_start; - -/* Number of frames between the last two calls to sceDisplayWaitVblankStart()*/ -static unsigned int last_frame_length; - -/*************************************************************************/ - -/* Local routine declarations */ - -__attribute__((noreturn)) - static int buffer_swap_thread(SceSize args, void *argp); - -static void do_buffer_swap(void); - -/*************************************************************************/ -/*************************************************************************/ - -/** - * display_init: Initialize the PSP display. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on error - */ -int display_init(void) -{ - /* Have we already initialized? */ - static int initted = 0; - if (initted) { - return 1; - } - - /* Clear out VRAM */ - memset(sceGeEdramGetAddr(), 0, sceGeEdramGetSize()); - sceKernelDcacheWritebackInvalidateAll(); - - /* Set display mode */ - int32_t res = sceDisplaySetMode(0, DISPLAY_WIDTH, DISPLAY_HEIGHT); - if (res < 0) { - DMSG("sceDisplaySetMode() failed: %s", psp_strerror(res)); - return 0; - } - display_width = DISPLAY_WIDTH; - display_height = DISPLAY_HEIGHT; - display_mode = PSP_DISPLAY_PIXEL_FORMAT_8888; - display_bpp = 32; - - /* Initialize VRAM pointers */ - uint8_t *vram_addr = sceGeEdramGetAddr(); - uint32_t vram_size = sceGeEdramGetSize(); - const uint32_t frame_size = - DISPLAY_STRIDE * DISPLAY_HEIGHT * (display_bpp/8); - int i; - for (i = 0; i < lenof(surfaces); i++) { - surfaces[i] = vram_addr + i*frame_size; - } - vram_spare_ptr = (uint8_t *)(vram_addr + lenof(surfaces)*frame_size); - vram_next_alloc = vram_spare_ptr; - vram_top = vram_addr + vram_size; - displayed_surface = 0; - work_surface = 1; - swap_pending = 0; - - /* Set the currently-displayed buffer */ - sceDisplaySetFrameBuf(surfaces[displayed_surface], DISPLAY_STRIDE, - display_mode, PSP_DISPLAY_SETBUF_IMMEDIATE); - - /* Set up the GU library */ - guInit(); - guStart(GU_DIRECT, display_list); - guDispBuffer(DISPLAY_WIDTH, DISPLAY_HEIGHT, - surfaces[displayed_surface], DISPLAY_STRIDE); - guFinish(); - guSync(0, 0); - - /* Success */ - initted = 1; - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * display_set_size: Set the effective display size. The display will - * be centered on the PSP's screen. - * - * This routine should not be called while drawing a frame (i.e. between - * display_begin_frame() and display_end_frame()). - * - * [Parameters] - * width: Effective display width (pixels) - * height: Effective display height (pixels) - * [Return value] - * None - */ -void display_set_size(int width, int height) -{ - display_width = width; - display_height = height; -} - -/*-----------------------------------------------------------------------*/ - -/** - * display_disp_buffer: Return a pointer to the current displayed (front) - * buffer. - * - * [Parameters] - * None - * [Return value] - * Pointer to the current work buffer - */ -uint32_t *display_disp_buffer(void) -{ - return (uint32_t *)surfaces[displayed_surface] - + ((DISPLAY_HEIGHT - display_height) / 2) * DISPLAY_STRIDE - + ((DISPLAY_WIDTH - display_width ) / 2); -} - -/*-----------------------------------------------------------------------*/ - -/** - * display_work_buffer: Return a pointer to the current work (back) - * buffer. - * - * [Parameters] - * None - * [Return value] - * Pointer to the current work buffer - */ -uint32_t *display_work_buffer(void) -{ - return (uint32_t *)surfaces[work_surface] - + ((DISPLAY_HEIGHT - display_height) / 2) * DISPLAY_STRIDE - + ((DISPLAY_WIDTH - display_width ) / 2); -} - -/*-----------------------------------------------------------------------*/ - -/** - * display_spare_vram: Return a pointer to the VRAM spare area. - * - * [Parameters] - * None - * [Return value] - * Pointer to the VRAM spare area - */ -void *display_spare_vram(void) -{ - return vram_spare_ptr; -} - -/*-----------------------------------------------------------------------*/ - -/** - * display_spare_vram_size: Return the size of the VRAM spare area. - * - * [Parameters] - * None - * [Return value] - * Size of the VRAM spare area, in bytes - */ -uint32_t display_spare_vram_size(void) -{ - return vram_top - vram_spare_ptr; -} - -/*************************************************************************/ - -/** - * display_alloc_vram: Allocate memory from the spare VRAM area, aligned - * to a multiple of 64 bytes. All allocated VRAM will be automatically - * freed at the next call to display_begin_frame(). - * - * [Parameters] - * size: Amount of memory to allocate, in bytes - * [Return value] - * Pointer to allocated memory, or NULL on failure (out of memory) - */ -void *display_alloc_vram(uint32_t size) -{ - if (vram_next_alloc + size > vram_top) { - return NULL; - } - void *ptr = vram_next_alloc; - vram_next_alloc += size; - if ((uintptr_t)vram_next_alloc & 0x3F) { // Make sure it stays aligned - vram_next_alloc += 0x40 - ((uintptr_t)vram_next_alloc & 0x3F); - } - return ptr; -} - -/*************************************************************************/ - -/** - * display_begin_frame: Begin processing for a frame. - * - * [Parameters] - * None - * [Return value] - * None - */ -void display_begin_frame(void) -{ - sceKernelDelayThread(0); // Seems to be needed for the buffer swap to work - while (swap_pending) { - sceKernelDelayThread(100); // 0.1ms - } - - vram_next_alloc = vram_spare_ptr; - - guStart(GU_DIRECT, display_list); - - /* We don't use a depth buffer, so disable depth buffer writing */ - guDepthMask(GU_TRUE); - - /* Clear the work surface--make sure to use the base pointer here, not - * the effective pointer, lest we stomp on spare VRAM while using the - * second buffer */ - guDrawBuffer(GU_PSM_8888, surfaces[work_surface], DISPLAY_STRIDE); - guDisable(GU_SCISSOR_TEST); - guClear(GU_COLOR_BUFFER_BIT); - guCommit(); - - /* Register the effective work surface pointer */ - guDrawBuffer(GU_PSM_8888, display_work_buffer(), DISPLAY_STRIDE); - - /* Set up drawing area parameters (we set the depth parameters too, - * just in case a custom drawing routine wants to use 3D coordinates) */ - guViewport(2048, 2048, display_width, display_height); - guOffset(2048 - display_width/2, 2048 - display_height/2); - guScissor(0, 0, display_width, display_height); - guEnable(GU_SCISSOR_TEST); - guDepthRange(65535, 0); - guDisable(GU_DEPTH_TEST); - -} - -/*-----------------------------------------------------------------------*/ - -/** - * display_end_frame: End processing for the current frame, then swap the - * displayed buffer and work buffer. The current frame will not actually - * be shown until the next vertical blank. - * - * [Parameters] - * None - * [Return value] - * None - */ -void display_end_frame(void) -{ - guFinish(); - swap_pending = 1; - /* Give the new thread a slightly higher priority than us, or else it - * won't actually get a chance to run. */ - if (sys_start_thread("YabauseBufferSwapThread", buffer_swap_thread, - sceKernelGetThreadCurrentPriority() - 1, - 0x1000, 0, NULL) < 0) { - DMSG("Failed to start buffer swap thread"); - swap_pending = 0; - do_buffer_swap(); // Do it ourselves - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * display_last_frame_length: Returns the length of time the last frame - * was displayed, in hardware frame (1/59.94sec) units. Only valid between - * display_begin_frame() and display_end_frame(). - * - * [Parameters] - * None - * [Return value] - * Length of time the last frame was displayed - */ -unsigned int display_last_frame_length(void) -{ - return last_frame_length; -} - -/*************************************************************************/ - -/** - * display_blit: Draw an image to the display. The image must be in - * native 32bpp format. - * - * [Parameters] - * src: Source image data pointer - * src_width: Width of the source image, in pixels - * src_height: Height of the source image, in pixels - * src_stride: Line length of source image, in pixels - * dest_x: X coordinate at which to display image - * dest_y: Y coordinate at which to display image - * [Return value] - * None - */ -void display_blit(const void *src, int src_width, int src_height, - int src_stride, int dest_x, int dest_y) -{ -#if 1 // Method 1: DMA the data into VRAM (fastest) - - /* Pointer must be 64-byte aligned, so if it's not, adjust the pointer - * and add an offset to the X coordinate */ - const unsigned int xofs = ((uintptr_t)src & 0x3F) / 4; - const uint32_t * const src_aligned = (const uint32_t *)src - xofs; - - guCopyImage(GU_PSM_8888, xofs, 0, src_width, src_height, src_stride, - src_aligned, dest_x, dest_y, DISPLAY_STRIDE, - display_work_buffer()); - -#elif 1 // Method 2: Draw as a texture (slower, but more general) - - /* Pointer must be 64-byte aligned, so if it's not, adjust the pointer - * and add an offset to the X coordinate */ - const unsigned int xofs = ((uintptr_t)src & 0x3F) / 4; - const uint32_t * const src_aligned = (const uint32_t *)src - xofs; - - /* Set up the vertex array (it's faster to draw multiple vertical - * strips than try to blit the whole thing at once) */ - const int nstrips = (src_width + 15) / 16; - struct { - uint16_t u, v; - int16_t x, y, z; - } *vertices = guGetMemory(sizeof(*vertices) * (2*nstrips)); - /* Note that guGetMemory() never fails, so we don't check for failure */ - int i, x; - for (i = 0, x = 0; x < src_width; i += 2, x += 16) { - int thiswidth = 16; - if (x+16 > src_width) { - thiswidth = src_width - x; - } - vertices[i+0].u = xofs + x; - vertices[i+0].v = 0; - vertices[i+0].x = dest_x + x; - vertices[i+0].y = dest_y; - vertices[i+0].z = 0; - vertices[i+1].u = xofs + x + thiswidth; - vertices[i+1].v = src_height; - vertices[i+1].x = dest_x + x + thiswidth; - vertices[i+1].y = dest_y + src_height; - vertices[i+1].z = 0; - } - - /* Draw the array */ - guEnable(GU_TEXTURE_2D); - guTexFilter(GU_NEAREST, GU_NEAREST); - guTexWrap(GU_CLAMP, GU_CLAMP); - guTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); - /* Always use a 512x512 texture size (the GE can only handle sizes that - * are powers of 2, and the size itself doesn't seem to affect speed) */ - guTexFlush(); - guTexMode(GU_PSM_8888, 0, 0, 0); - guTexImage(0, 512, 512, src_stride, src_aligned); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 2*nstrips, NULL, vertices); - guDisable(GU_TEXTURE_2D); - -#else // Method 3: Copy using the CPU (slowest) - - const uint32_t *src32 = (const uint32_t *)src; - uint32_t *dest32 = display_work_buffer() + dest_y*DISPLAY_STRIDE + dest_x; - int y; - for (y = 0; y < src_height; - y++, src32 += src_stride, dest32 += DISPLAY_STRIDE - ) { - memcpy(dest32, src32, src_width*4); - } - -#endif -} - -/*-----------------------------------------------------------------------*/ - -/** - * display_blit_scaled: Scale and draw an image to the display. The image - * must be in native 32bpp format. - * - * [Parameters] - * src: Source image data pointer - * src_width: Width of the source image, in pixels - * src_height: Height of the source image, in pixels - * src_stride: Line length of source image, in pixels - * dest_x: X coordinate at which to display image - * dest_y: Y coordinate at which to display image - * dest_width: Width of the displayed image, in pixels - * dest_height: Height of the displayed image, in pixels - * [Return value] - * None - */ -void display_blit_scaled(const void *src, int src_width, int src_height, - int src_stride, int dest_x, int dest_y, - int dest_width, int dest_height) -{ - /* Pointer must be 64-byte aligned, so if it's not, adjust the pointer - * and add an offset to the X coordinate */ - const unsigned int xofs = ((uintptr_t)src & 0x3F) / 4; - const uint32_t * const src_aligned = (const uint32_t *)src - xofs; - - /* Set up the vertex array (4 vertices for a 2-triangle strip) */ - struct { - uint16_t u, v; - int16_t x, y, z; - } *vertices = guGetMemory(sizeof(*vertices) * 4); - vertices[0].u = xofs; - vertices[0].v = 0; - vertices[0].x = dest_x; - vertices[0].y = dest_y; - vertices[0].z = 0; - vertices[1].u = xofs; - vertices[1].v = src_height; - vertices[1].x = dest_x; - vertices[1].y = dest_y + dest_height; - vertices[1].z = 0; - vertices[2].u = xofs + src_width; - vertices[2].v = 0; - vertices[2].x = dest_x + dest_width; - vertices[2].y = dest_y; - vertices[2].z = 0; - vertices[3].u = xofs + src_width; - vertices[3].v = src_height; - vertices[3].x = dest_x + dest_width; - vertices[3].y = dest_y + dest_height; - vertices[3].z = 0; - - /* Draw the array */ - guEnable(GU_TEXTURE_2D); - guTexFilter(GU_LINEAR, GU_LINEAR); - guTexWrap(GU_CLAMP, GU_CLAMP); - guTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); - guTexFlush(); - guTexMode(GU_PSM_8888, 0, 0, 0); - guTexImage(0, 512, 512, src_stride, src_aligned); - guDrawArray(GU_TRIANGLE_STRIP, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 4, NULL, vertices); - guDisable(GU_TEXTURE_2D); -} - -/*************************************************************************/ - -/** - * display_fill_box: Draw a filled box with a specified color. - * - * [Parameters] - * x1, y1: Upper-left coordinates of box - * x2, y2: Lower-right coordinates of box - * color: Color to fill with (0xAABBGGRR) - * [Return value] - * None - */ -void display_fill_box(int x1, int y1, int x2, int y2, uint32_t color) -{ - struct { - uint32_t color; - int16_t x, y, z, pad; - } *vertices = guGetMemory(sizeof(*vertices) * 2); - vertices[0].color = color; - vertices[0].x = x1; - vertices[0].y = y1; - vertices[0].z = 0; - vertices[1].color = color; - vertices[1].x = x2 + 1; - vertices[1].y = y2 + 1; - vertices[1].z = 0; - - guDrawArray(GU_SPRITES, - GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 2, NULL, vertices); -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * buffer_swap_thread: Perform a buffer swap and clear the "swap_pending" - * variable to false. Designed to run as a background thread while the - * main emulation proceeds. - * - * [Parameters] - * args, argp: Thread argument size and pointer (unused) - * [Return value] - * Does not return - */ -static int buffer_swap_thread(SceSize args, void *argp) -{ - do_buffer_swap(); - swap_pending = 0; - sceKernelExitDeleteThread(0); -} - -/*----------------------------------*/ - -/** - * do_buffer_swap: Perform a display buffer swap (call guSync(), swap the - * display and work surfaces, wait for the following vertical blank, and - * calculate the length of time between this newly displayed frame and the - * previous one). Called either from the buffer swap thread or (if the - * swap thread fails to start) from the main thread. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void do_buffer_swap(void) -{ - guSync(0, 0); - sceDisplaySetFrameBuf(surfaces[work_surface], DISPLAY_STRIDE, - display_mode, PSP_DISPLAY_SETBUF_NEXTFRAME); - displayed_surface = work_surface; - work_surface = (work_surface + 1) % lenof(surfaces); - sceDisplayWaitVblankStart(); - - /* Update the frame length variables. If this is the first frame - * we've drawn (signaled by last_frame_start == 0), just set a frame - * length of 1 (1/60 sec) since we have nothing to compare it against. */ - const uint32_t now = sceKernelGetSystemTimeLow(); - const uint32_t last_frame_time = now - last_frame_start; - const uint32_t time_unit = (1001000+30)/60; - if (last_frame_start != 0) { - last_frame_length = (last_frame_time + time_unit/2) / time_unit; - } else { - last_frame_length = 1; - } - /* Make sure we don't accidentally signal the next frame as the - * first frame drawn. */ - last_frame_start = (now != 0) ? now : 1; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/display.h b/yabause/src/psp/display.h deleted file mode 100644 index 7aa113205e..0000000000 --- a/yabause/src/psp/display.h +++ /dev/null @@ -1,213 +0,0 @@ -/* src/psp/display.h: PSP display management header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_DISPLAY_H -#define PSP_DISPLAY_H - -/*************************************************************************/ - -/* Physical screen layout */ -#define DISPLAY_WIDTH 480 -#define DISPLAY_HEIGHT 272 -#define DISPLAY_STRIDE 512 - -/*-----------------------------------------------------------------------*/ - -/** - * display_init: Initialize the PSP display. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on error - */ -extern int display_init(void); - -/** - * display_set_size: Set the effective display size. The display will - * be centered on the PSP's screen. - * - * This routine should not be called while drawing a frame (i.e. between - * display_begin_frame() and display_end_frame()). - * - * [Parameters] - * width: Effective display width (pixels) - * height: Effective display height (pixels) - * [Return value] - * None - */ -extern void display_set_size(int width, int height); - -/** - * display_disp_buffer: Return a pointer to the current displayed (front) - * buffer. - * - * [Parameters] - * None - * [Return value] - * Pointer to the current work buffer - */ -extern uint32_t *display_disp_buffer(void); - -/** - * display_work_buffer: Return a pointer to the current work (back) - * buffer. - * - * [Parameters] - * None - * [Return value] - * Pointer to the current work buffer - */ -extern uint32_t *display_work_buffer(void); - -/** - * display_spare_vram: Return a pointer to the VRAM spare area. - * - * [Parameters] - * None - * [Return value] - * Pointer to the VRAM spare area - */ -extern void *display_spare_vram(void); - -/** - * display_spare_vram_size: Return the size of the VRAM spare area. - * - * [Parameters] - * None - * [Return value] - * Size of the VRAM spare area, in bytes - */ -extern uint32_t display_spare_vram_size(void); - -/*----------------------------------*/ - -/** - * display_alloc_vram: Allocate memory from the spare VRAM area, aligned - * to a multiple of 64 bytes. All allocated VRAM will be automatically - * freed at the next call to display_begin_frame(). - * - * [Parameters] - * size: Amount of memory to allocate, in bytes - * [Return value] - * Pointer to allocated memory, or NULL on failure (out of memory) - */ -extern void *display_alloc_vram(uint32_t size); - -/*----------------------------------*/ - -/** - * display_begin_frame: Begin processing for a frame. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void display_begin_frame(void); - -/** - * display_end_frame: End processing for the current frame, then swap the - * displayed buffer and work buffer. The current frame will not actually - * be shown until the next vertical blank. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void display_end_frame(void); - -/** - * display_last_frame_length: Returns the length of time the last frame - * was displayed, in hardware frame (1/59.94sec) units. Only valid between - * display_begin_frame() and display_end_frame(). - * - * [Parameters] - * None - * [Return value] - * Length of time the last frame was displayed - */ -extern unsigned int display_last_frame_length(void); - -/*----------------------------------*/ - -/** - * display_blit: Draw an image to the display. The image must be in - * native 32bpp format. - * - * [Parameters] - * src: Source image data pointer - * src_width: Width of the source image, in pixels - * src_height: Height of the source image, in pixels - * src_stride: Line length of source image, in pixels - * dest_x: X coordinate at which to display image - * dest_y: Y coordinate at which to display image - * [Return value] - * None - */ -extern void display_blit(const void *src, int src_width, int src_height, - int src_stride, int dest_x, int dest_y); - -/** - * display_blit_scaled: Scale and draw an image to the display. The image - * must be in native 32bpp format. - * - * [Parameters] - * src: Source image data pointer - * src_width: Width of the source image, in pixels - * src_height: Height of the source image, in pixels - * src_stride: Line length of source image, in pixels - * dest_x: X coordinate at which to display image - * dest_y: Y coordinate at which to display image - * dest_width: Width of the displayed image, in pixels - * dest_height: Height of the displayed image, in pixels - * [Return value] - * None - */ -extern void display_blit_scaled(const void *src, int src_width, int src_height, - int src_stride, int dest_x, int dest_y, - int dest_width, int dest_height); - -/** - * display_fill_box: Draw a filled box with a specified color. - * - * [Parameters] - * x1, y1: Upper-left coordinates of box - * x2, y2: Lower-right coordinates of box - * color: Color to fill with (0xAABBGGRR) - * [Return value] - * None - */ -extern void display_fill_box(int x1, int y1, int x2, int y2, uint32_t color); - -/*************************************************************************/ - -#endif // PSP_DISPLAY_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/filesel.c b/yabause/src/psp/filesel.c deleted file mode 100644 index 6e60710242..0000000000 --- a/yabause/src/psp/filesel.c +++ /dev/null @@ -1,521 +0,0 @@ -/* src/psp/filesel.c: Simple file selector for use with PSP menu - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "display.h" -#include "filesel.h" -#include "font.h" -#include "sys.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* File selector data structure (exported as opaque type FileSelector) */ - -struct FileSelector_ { - char *title; // Window title - - char *dir; // Current directory (note that we don't support - // changing directories at present) - SceUID scandir_thread; // If nonzero, thread ID of directory scan thread; - // if zero, indicates that scan is complete. - /* The file list MUST NOT be accessed by the main thread while - * scandir_thread is nonzero */ - char **file_list; // List of files in the current directory (each - // entry is malloc'd) - int num_files; // Number of files in file_list[]; negative - // indicates an error scanning the directory - - int top_file; // Index of top file shown in window - int selected_file; // Selected file index (negative = cancelled) - int num_lines; // Number of lines visible in file selector window - // (set after first filesel_draw() call) - uint8_t cursor_timer; // Frame counter for cursor flashing - - uint8_t done; // Nonzero when user selects a file or cancels -}; - -/*************************************************************************/ - -/* Display parameters */ - -/* Window size */ -#define WINDOW_WIDTH 360 -#define WINDOW_HEIGHT 208 - -/* Window colors */ -#define BGCOLOR_TITLE 0xFF804060 // Title bar -#define BGCOLOR_LIST 0xFF604040 // File list area -#define BORDER_COLOR_HI 0xFFFFECEC // Border lines (bright) -#define BORDER_COLOR_LO 0xFF000000 // Border lines (shadow) - -/* Cursor parameters */ -#define CURSOR_COLOR 0x80FFECEC -#define CURSOR_PERIOD 60 // frames - -/* Text colors */ -#define TEXTCOLOR_TITLE 0xFFFFECEC -#define TEXTCOLOR_FILE 0xFFFFECEC -#define TEXTCOLOR_DISABLED 0xFF807474 // "Scanning directory...", etc. -#define TEXTCOLOR_ERROR 0xFF5540FF - -/*************************************************************************/ - -/* Local function declarations */ - -static void scandir_thread(SceSize args, void *argp); - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * filesel_create: Create a new file selector. - * - * [Parameters] - * title: File selector window title - * dir: Directory to select file from - * [Return value] - * Newly-created file selector, or NULL on error - */ -FileSelector *filesel_create(const char *title, const char *dir) -{ - PRECOND(title != NULL, goto error_return); - PRECOND(dir != NULL, goto error_return); - - FileSelector *filesel = malloc(sizeof(*filesel)); - if (UNLIKELY(!filesel)) { - DMSG("No memory for FileSelector"); - goto error_return; - } - filesel->title = strdup(title); - if (UNLIKELY(!filesel->title)) { - DMSG("No memory for title"); - goto error_free_filesel; - } - filesel->dir = strdup(dir); - if (UNLIKELY(!filesel->dir)) { - DMSG("No memory for current directory"); - goto error_free_title; - } - filesel->scandir_thread = 0; - filesel->file_list = NULL; - filesel->num_files = 0; - filesel->top_file = 0; - filesel->selected_file = 0; - filesel->num_lines = 0; - filesel->cursor_timer = 0; - filesel->done = 0; - - /* We only ever have one file selector open at once, so we just use a - * static thread name */ - int32_t thread = sys_start_thread("YabauseScanDirThread", scandir_thread, - THREADPRI_MAIN+1, 0x1000, - sizeof(filesel), &filesel); - if (thread & 0x80000000) { - DMSG("Failed to start scandir thread: %s", psp_strerror(thread)); - goto error_free_dir; - } - - filesel->scandir_thread = thread; - return filesel; - - error_free_dir: - free(filesel->dir); - error_free_title: - free(filesel->title); - error_free_filesel: - free(filesel); - error_return: - return NULL; -} - -/*************************************************************************/ - -/** - * filesel_process: Process input for a file selector. - * - * [Parameters] - * filesel: File selector - * buttons: Newly-pressed (or repeating) buttons (PSP_CTRL_* bitmask) - * [Return value] - * None - */ -void filesel_process(FileSelector *filesel, uint32_t buttons) -{ - PRECOND(filesel != NULL, return); - - /* If the user wants to cancel, give that top priority */ - if (buttons & PSP_CTRL_CROSS) { - filesel->selected_file = -1; - filesel->done = 1; - return; - } - - /* If the scanning thread is still running, there's nothing to do */ - if (filesel->scandir_thread) { - return; - } - - /* Update the cursor timer (assume we're called once per frame) */ - filesel->cursor_timer = (filesel->cursor_timer + 1) % CURSOR_PERIOD; - - /* If we have a file list, let the user move the cursor around or - * select a file; note that scrolling is handled at drawing time, when - * we know how many lines will fit in the file list display area */ - if (filesel->num_files > 0) { - if (buttons & PSP_CTRL_UP) { - if (filesel->selected_file > 0) { - filesel->selected_file--; - filesel->cursor_timer = 0; - } - } else if (buttons & PSP_CTRL_DOWN) { - if (filesel->selected_file < filesel->num_files - 1) { - filesel->selected_file++; - filesel->cursor_timer = 0; - } - } else if (buttons & PSP_CTRL_LEFT) { - /* Use the number of visible lines calculated in filesel_draw(). - * If we get here on the very first filesel_process() call, - * filesel->num_lines will be zero, so this becomes a no-op. */ - int num_to_scroll = filesel->num_lines; - if (num_to_scroll > filesel->top_file) { - num_to_scroll = filesel->top_file; - } - filesel->top_file -= num_to_scroll; - filesel->selected_file -= num_to_scroll; - filesel->cursor_timer = 0; - } else if (buttons & PSP_CTRL_RIGHT) { - int max_top = filesel->num_files - filesel->num_lines; - if (max_top < 0) { - max_top = 0; - } - int num_to_scroll = filesel->num_lines; - if (num_to_scroll > max_top - filesel->top_file) { - num_to_scroll = max_top - filesel->top_file; - } - filesel->top_file += num_to_scroll; - filesel->selected_file += num_to_scroll; - filesel->cursor_timer = 0; - } else if (buttons & PSP_CTRL_CIRCLE) { - filesel->done = 1; - } - } -} - -/*************************************************************************/ - -/** - * filesel_draw: Draw a file selector. - * - * [Parameters] - * filesel: File selector - * [Return value] - * None - */ -void filesel_draw(FileSelector *filesel) -{ - PRECOND(filesel != NULL, return); - - const int x1 = DISPLAY_WIDTH/2 - WINDOW_WIDTH/2; - const int y1 = DISPLAY_HEIGHT/2 - WINDOW_HEIGHT/2; - const int x2 = x1 + (WINDOW_WIDTH - 1); - const int y2 = y1 + (WINDOW_HEIGHT - 1); - - /* Draw the outside border */ - - display_fill_box(x1, y1, x2-1, y1, BORDER_COLOR_HI); - display_fill_box(x1+1, y1+1, x2, y1+1, BORDER_COLOR_LO); - display_fill_box(x1, y1+1, x1, y2-1, BORDER_COLOR_HI); - display_fill_box(x1+1, y1+2, x1+1, y2, BORDER_COLOR_LO); - display_fill_box(x2-1, y1+1, x2-1, y2-1, BORDER_COLOR_HI); - display_fill_box(x2, y2+2, x2, y2, BORDER_COLOR_LO); - display_fill_box(x1+1, y2-1, x2-2, y2-1, BORDER_COLOR_HI); - display_fill_box(x1, y2, x2-1, y2, BORDER_COLOR_LO); - - /* Draw the title bar */ - - const int title_text_y = y1+4; - const int title_y2 = title_text_y + FONT_HEIGHT + 2; - display_fill_box(x1+1, title_y2, x2-2, title_y2, BORDER_COLOR_HI); - display_fill_box(x1+2, title_y2+1, x2-1, title_y2+1, BORDER_COLOR_LO); - display_fill_box(x1+2, y1+2, x2-2, title_y2-2, BGCOLOR_TITLE); - font_printf((x1+x2)/2, title_text_y, 0, TEXTCOLOR_TITLE, - "%s", filesel->title); - - /* Draw the file list */ - - display_fill_box(x1+2, title_y2+2, x2-2, y2-2, BGCOLOR_LIST); - const int list_x1 = x1 + 4; - const int list_y1 = title_y2 + 4; - const int list_x2 = x2 - 4; - const int list_y2 = y2 - 4; - const int line_height = FONT_HEIGHT + 2; - const int num_lines = ((list_y2+1) - list_y1) / line_height; - filesel->num_lines = num_lines; // Save for reference in filesel_process() - int y = list_y1 + (((list_y2+1)-list_y1) - (num_lines*line_height)) / 2; - if (filesel->scandir_thread) { - font_printf(list_x1, y, -1, TEXTCOLOR_DISABLED, - "(Scanning directory...)"); - } else if (filesel->num_files < 0) { - font_printf(list_x1, y, -1, TEXTCOLOR_ERROR, - "(Error scanning directory!)"); - } else if (filesel->num_files == 0) { - font_printf(list_x1, y, -1, TEXTCOLOR_DISABLED, - "(No files found.)"); - } else { - /* Scroll the list if needed */ - if (filesel->selected_file < filesel->top_file) { - filesel->top_file = filesel->selected_file; - } else if (filesel->selected_file >= filesel->top_file + num_lines) { - filesel->top_file = filesel->selected_file - (num_lines-1); - } - /* List as many files as will fit in the window */ - int i; - for (i = filesel->top_file; - i < filesel->num_files && i < filesel->top_file + num_lines; - i++, y += line_height - ) { - // FIXME: handle overlength filenames in a more general way - const int maxlen = ((list_x2+1) - list_x1) / 6; - if (strlen(filesel->file_list[i]) > maxlen) { - font_printf(list_x1, y, -1, TEXTCOLOR_FILE, - "%.*s...", maxlen-3, filesel->file_list[i]); - } else { - font_printf(list_x1, y, -1, TEXTCOLOR_FILE, - "%s", filesel->file_list[i]); - } - if (filesel->selected_file == i) { - const float cursor_alpha = - (sinf((filesel->cursor_timer / (float)CURSOR_PERIOD) - * (float)M_TWOPI) + 1) / 2; - const uint32_t cursor_alpha_byte = - floorf((CURSOR_COLOR>>24 & 0xFF) * cursor_alpha + 0.5f); - display_fill_box(list_x1-1, y-1, list_x2+1, y+FONT_HEIGHT, - cursor_alpha_byte<<24 - | (CURSOR_COLOR & 0x00FFFFFF)); - } - } - } -} - -/*************************************************************************/ - -/** - * filesel_done: Return whether a file selector's work is done (i.e., - * whether the user has either selected a file or cancelled the selector). - * - * [Parameters] - * filesel: File selector - * [Return value] - * True (nonzero) if any of the following are true: - * - The user selected a file - * - The user cancelled the file selector - * - An error occurred which prevents the file selector's - * processing from continuing normally - * False (zero) if none of the above are true - */ -int filesel_done(FileSelector *filesel) -{ - PRECOND(filesel != NULL, return 1); - - return filesel->done; -} - -/*-----------------------------------------------------------------------*/ - -/** - * filesel_selected_file: Return the name of the file selected by the - * user, if any. - * - * [Parameters] - * filesel: File selector - * [Return value] - * The name of the file selected by the user, or NULL if the user has - * not selected a file (including if the user has cancelled the file - * selector) - */ -const char *filesel_selected_file(FileSelector *filesel) -{ - PRECOND(filesel != NULL, return NULL); - - if (filesel->done && filesel->selected_file >= 0) { - return filesel->file_list[filesel->selected_file]; - } else { - return NULL; - } -} - -/*************************************************************************/ - -/** - * filesel_destroy: Destroy a file selector. Does nothing if filesel==NULL. - * - * [Parameters] - * filesel: File selector to destroy - * [Return value] - * None - */ -void filesel_destroy(FileSelector *filesel) -{ - if (filesel) { - if (filesel->scandir_thread) { - sceKernelTerminateDeleteThread(filesel->scandir_thread); - } - int i; - for (i = 0; i < filesel->num_files; i++) { - free(filesel->file_list[i]); - } - free(filesel->file_list); - free(filesel->dir); - free(filesel->title); - free(filesel); - } -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * scandir_thread: Thread used to scan a directory for files. Updates the - * file_list[] and num_files fields of the passed-in FileSelector structure. - * - * [Parameters] - * args: Parameter size (must be sizeof(FileSelector *)) - * argp: Parameter pointer (must point to a valid FileSelector pointer) - * [Return value] - * Does not return (terminates and deletes thread when finished) - */ -static void scandir_thread(SceSize args, void *argp) -{ - PRECOND(args == sizeof(FileSelector *), goto exit_thread); - PRECOND(argp != NULL, goto exit_thread); - - FileSelector * const filesel = *(FileSelector **)argp; - - - int dirfd = sceIoDopen(filesel->dir); - if (dirfd < 0) { - DMSG("sceIoDopen(%s): %s", filesel->dir, psp_strerror(dirfd)); - goto signal_error; - } - - SceIoDirent dirent; - memset(&dirent, 0, sizeof(dirent)); - int res; - while ((res = sceIoDread(dirfd, &dirent)) > 0) { - - /* Ignore . (current directory) and .. (parent directory) entries */ - if (strcmp(dirent.d_name,".") == 0 || strcmp(dirent.d_name,"..") == 0){ - continue; - } - - /* Ignore all directories, since we don't support changing directory - * (we could subsume the above test into this one, but we leave them - * separate for clarity) */ - char pathbuf[1000]; - if (UNLIKELY(snprintf(pathbuf, sizeof(pathbuf), "%s/%s", filesel->dir, - dirent.d_name) >= sizeof(pathbuf))) { - DMSG("Pathname buffer overflow: %s/%s", filesel->dir, - dirent.d_name); - continue; - } - struct SceIoStat st; - memset(&st, 0, sizeof(st)); - res = sceIoGetstat(pathbuf, &st); - if (UNLIKELY(res < 0)) { - DMSG("sceIoGetstat(%s): %s", pathbuf, psp_strerror(res)); - continue; - } - if (FIO_S_ISDIR(st.st_mode)) { - continue; - } - - /* Make room for the new file in the array */ - char **new_file_list = - realloc(filesel->file_list, - sizeof(*filesel->file_list) * (filesel->num_files + 1)); - if (UNLIKELY(!new_file_list)) { - DMSG("No memory to expand file list to %d files", - filesel->num_files + 1); - goto clear_file_list; - } - filesel->file_list = new_file_list; - char *new_file = strdup(dirent.d_name); - if (UNLIKELY(!new_file)) { - DMSG("No memory to copy filename: %s", dirent.d_name); - goto clear_file_list; - } - - /* Insert the new file into the file list, keeping the list sorted. - * We don't expect to see very many files in a directory, so we - * don't bother with anything more complex than a linear search. */ - int i; - for (i = 0; i < filesel->num_files; i++) { - if (stricmp(new_file, filesel->file_list[i]) < 0) { - break; - } - } - if (i < filesel->num_files) { - memmove(&filesel->file_list[i+1], &filesel->file_list[i], - sizeof(*filesel->file_list) * (filesel->num_files - i)); - } - filesel->file_list[i] = new_file; - filesel->num_files++; - } - - res = sceIoDclose(dirfd); - if (res != 0) { - DMSG("sceIoDclose(%s): %s", filesel->dir, psp_strerror(dirfd)); - /* Not a critical error, so just let it slide */ - } - - filesel->scandir_thread = 0; - goto exit_thread; - - clear_file_list:; - int i; - for (i = 0; i < filesel->num_files; i++) { - free(filesel->file_list[i]); - } - free(filesel->file_list); - filesel->file_list = NULL; - signal_error: - filesel->num_files = -1; - filesel->scandir_thread = 0; - exit_thread: - sceKernelExitDeleteThread(0); -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/filesel.h b/yabause/src/psp/filesel.h deleted file mode 100644 index 9175866090..0000000000 --- a/yabause/src/psp/filesel.h +++ /dev/null @@ -1,114 +0,0 @@ -/* src/psp/filesel.h: PSP file selector header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_FILESEL_H -#define PSP_FILESEL_H - -/*************************************************************************/ - -/* Data type of a file selector instance (contents are opaque) */ -typedef struct FileSelector_ FileSelector; - -/*-----------------------------------------------------------------------*/ - -/** - * filesel_create: Create a new file selector. - * - * [Parameters] - * title: File selector window title - * dir: Directory to select file from - * [Return value] - * Newly-created file selector, or NULL on error - */ -extern FileSelector *filesel_create(const char *title, const char *dir); - -/** - * filesel_process: Process input for a file selector. - * - * [Parameters] - * filesel: File selector - * buttons: Newly-pressed (or repeating) buttons (PSP_CTRL_* bitmask) - * [Return value] - * None - */ -extern void filesel_process(FileSelector *filesel, uint32_t buttons); - -/** - * filesel_draw: Draw a file selector. - * - * [Parameters] - * filesel: File selector - * [Return value] - * None - */ -extern void filesel_draw(FileSelector *filesel); - -/** - * filesel_done: Return whether a file selector's work is done (i.e., - * whether the user has either selected a file or cancelled the selector). - * - * [Parameters] - * filesel: File selector - * [Return value] - * True (nonzero) if any of the following are true: - * - The user selected a file - * - The user cancelled the file selector - * - An error occurred which prevents the file selector's - * processing from continuing normally - * False (zero) if none of the above are true - */ -extern int filesel_done(FileSelector *filesel); - -/** - * filesel_selected_file: Return the name of the file selected by the - * user, if any. - * - * [Parameters] - * filesel: File selector - * [Return value] - * The name of the file selected by the user, or NULL if the user has - * not selected a file (including if the user has cancelled the file - * selector) - */ -extern const char *filesel_selected_file(FileSelector *filesel); - -/** - * filesel_destroy: Destroy a file selector. Does nothing if filesel==NULL. - * - * [Parameters] - * filesel: File selector to destroy - * [Return value] - * None - */ -extern void filesel_destroy(FileSelector *filesel); - -/*************************************************************************/ - -#endif // PSP_FILESEL_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/font.c b/yabause/src/psp/font.c deleted file mode 100644 index 4bf141f0fd..0000000000 --- a/yabause/src/psp/font.c +++ /dev/null @@ -1,389 +0,0 @@ -/* src/psp/font.c: Simple font used for PSP menu (public-domain 6x13 font - from X.Org) - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "font.h" -#include "gu.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Character width (the font is fixed-width) */ -#define CHAR_WIDTH 6 - -/* First and last characters in font data */ -#define FONTDATA_FIRSTCHAR 32 -#define FONTDATA_LASTCHAR 127 - -/* Characters (not pixels!) in one row of font data */ -#define FONTDATA_STRIDE 32 - -/* Default character to use for out-of-range characters */ -#define FONTDATA_DEFCHAR '?' - -/* Font data definition (1 byte per pixel, 32 6x13 characters per row). - * This wastes 6 bits per pixel, but it's only 7k anyway so no big deal. */ - -static const __attribute__((aligned(64))) uint8_t fontdata[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1, - 0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,2,0,0,0,1,0,0,0,0,0,1,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,1,0,0,0,0,0,1,0,0,0,0,1,1,1,0,0,1,1,1,1,1,0,0,0,0,1,0,0,1,1, - 1,1,1,0,0,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,0,0, - 0,0,0,0,0,0,0,0,1,2,0,0,0,1,2,1,2,0,0,1,0,1,0,0,0,1,1,1,1,0,1,0, - 1,0,1,2,0,1,0,0,0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,1,2,0,0,1,0,1,2, - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2, - 0,1,0,1,0,0,0,1,1,2,0,0,1,0,2,2,1,0,0,2,2,2,1,2,0,0,0,1,2,0,1,2, - 2,2,2,2,1,0,2,2,1,0,0,2,2,2,1,2,1,0,2,2,1,0,1,0,2,2,1,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,1,0,0,0,0,1,0,2,2,1,0, - 0,0,0,0,0,0,0,0,1,2,0,0,0,1,2,1,2,0,0,1,2,1,2,0,1,0,1,2,2,2,0,1, - 0,1,0,2,1,0,1,0,0,0,0,0,1,2,0,0,0,1,0,2,0,0,0,0,0,1,0,0,0,1,1,1, - 0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2, - 1,0,2,0,1,0,1,0,1,2,0,0,1,2,0,0,1,2,0,0,0,1,0,2,0,0,1,1,2,0,1,2, - 0,0,0,0,1,2,0,0,0,2,0,0,0,1,0,2,1,2,0,0,1,2,1,2,0,0,1,2,0,0,1,0, - 0,0,0,0,1,0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,1,2,0,0,1,2, - 0,0,0,0,0,0,0,0,1,2,0,0,0,0,2,0,2,0,1,1,1,1,1,0,1,2,1,2,0,0,0,0, - 2,1,2,0,1,2,1,2,0,0,0,0,0,2,0,0,0,1,2,0,0,0,0,0,0,1,2,0,1,0,1,2, - 1,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0, - 1,2,0,0,1,2,0,2,1,2,0,0,0,2,0,0,1,2,0,0,1,0,2,0,0,1,0,1,2,0,1,2, - 1,1,0,0,1,2,0,0,0,0,0,0,0,1,2,0,1,2,0,0,1,2,1,2,0,0,1,2,0,1,1,1, - 0,0,0,1,1,1,0,0,0,1,0,2,0,0,1,1,1,1,1,0,0,0,0,1,0,0,0,2,0,0,1,2, - 0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,1,2,1,2,2,0,1,1,1,0,0,0,0, - 1,0,2,0,0,1,0,2,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,1,2,0,0,2,1,2, - 0,2,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,2,0, - 1,2,0,0,1,2,0,0,1,2,0,0,0,0,0,1,0,2,0,1,1,1,0,0,0,1,2,1,2,0,1,1, - 0,2,1,0,1,1,1,1,0,0,0,0,1,0,2,0,0,1,1,1,0,2,0,1,1,1,1,2,0,0,1,2, - 2,0,0,0,1,2,2,0,1,0,2,0,0,0,0,2,2,2,2,2,0,0,0,0,1,0,0,0,0,1,0,2, - 0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,2,1,0,0,1, - 0,2,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,1,2,0,0,0,0,2, - 0,0,0,2,1,2,2,2,0,0,0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,0,0,1,0,2,0,0, - 1,2,0,0,1,2,0,0,1,2,0,0,0,0,1,0,2,0,0,0,2,2,1,0,1,0,2,1,2,0,0,2, - 2,0,1,2,1,2,2,2,1,0,0,0,1,2,0,0,1,0,2,2,1,0,0,0,2,2,1,2,0,0,0,2, - 0,0,0,0,0,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,0,1,0,2,0, - 0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,1,2,1,2,2,0,0,1,2,1,2,0,1, - 2,1,0,0,1,2,0,1,1,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,1,2,0,0,0,0,0, - 0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0,0, - 1,2,0,0,1,2,0,0,1,2,0,0,0,1,0,2,0,0,0,0,0,0,1,2,1,1,1,1,1,0,0,0, - 0,0,1,2,1,2,0,0,1,2,0,1,0,2,0,0,1,2,0,0,1,2,0,0,0,0,1,2,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,1,1,1,0,0,0,1,0,2,0,0,0,1,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,2,1,2,0,1,1,1,1,0,2,1,0, - 1,0,1,0,1,2,0,1,2,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,2,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,2,0,0,0, - 0,1,0,1,0,2,0,0,1,2,0,0,1,0,2,0,0,0,1,0,0,0,1,2,0,2,2,1,2,2,1,0, - 0,0,1,2,1,2,0,0,1,2,0,1,2,0,0,0,1,2,0,0,1,2,1,0,0,0,1,2,0,0,1,0, - 0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,2,2,2,2,2,0,1,0,2,0,0,0,0,0,2,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,2,1,2,2,0,1,2, - 0,1,0,2,0,1,1,0,1,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,0,0,0,0,1,1,1,0,0,1,2,0,0,0,0, - 0,0,1,0,2,0,1,1,1,1,1,0,1,1,1,1,1,0,0,1,1,1,0,2,0,0,0,1,2,0,0,1, - 1,1,0,2,0,1,1,1,0,2,0,1,2,0,0,0,0,1,1,1,0,2,0,1,1,1,0,2,0,1,1,1, - 0,0,0,0,1,2,2,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,2,0,0,0,0,0,1,0,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2, - 0,0,2,0,0,0,2,2,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,2,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,2,0,0,0,0, - 0,0,0,2,0,0,0,2,2,2,2,2,0,2,2,2,2,2,0,0,2,2,2,0,0,0,0,0,2,0,0,0, - 2,2,2,0,0,0,2,2,2,0,0,0,2,0,0,0,0,0,2,2,2,0,0,0,2,2,2,0,0,0,1,2, - 2,0,0,1,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,1,1,1,0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,0,0,1,1, - 1,1,1,0,1,1,1,1,1,0,0,1,1,1,0,0,1,0,0,0,1,0,0,1,1,1,0,0,0,0,1,1, - 1,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,1,1,1,0,0, - 1,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,1,0,1,0, - 0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,1,1,1, - 1,0,0,1,2,2,2,0,1,0,0,0,0,0,0,0,2,1,2,0,0,0,1,0,0,0,0,0,0,0,0,0, - 1,0,2,2,1,0,0,1,0,1,0,0,0,1,2,2,1,0,1,0,2,2,1,0,0,1,2,2,1,0,1,2, - 2,2,2,2,1,2,2,2,2,2,1,0,2,2,1,0,1,2,0,0,1,2,0,0,1,2,2,0,0,0,0,1, - 2,2,1,2,0,0,1,2,1,2,0,0,0,0,1,2,0,0,1,2,1,1,0,0,1,2,1,0,2,2,1,0, - 1,2,2,2,1,0,1,0,2,2,1,0,1,2,2,2,1,0,1,0,2,2,1,0,0,2,1,2,2,2,1,2, - 0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2,0,2,2,2, - 1,2,0,1,2,0,0,0,1,2,0,0,0,0,0,0,0,1,2,0,0,1,0,1,0,0,0,0,0,0,0,0, - 1,2,0,0,1,2,1,0,2,0,1,0,0,1,2,0,1,2,1,2,0,0,0,2,0,1,2,0,1,2,1,2, - 0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,2,1,2,0,0,1,2,0,0,1,2,0,0,0,0,0,1, - 2,0,1,2,0,1,0,2,1,2,0,0,0,0,1,1,0,1,1,2,1,1,2,0,1,2,1,2,0,0,1,2, - 1,2,0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2,1,2,0,0,0,2,0,0,1,2,0,0,1,2, - 0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2,0,1,0,1,0,2,0,1,0,1,0,2,0,0,0,1, - 0,2,0,1,2,0,0,0,0,1,0,0,0,0,0,0,0,1,2,0,1,0,2,0,1,0,0,0,0,0,0,0, - 1,2,0,1,1,2,1,2,0,0,1,2,0,1,2,0,1,2,1,2,0,0,0,0,0,1,2,0,1,2,1,2, - 0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,1,2,0,0,1,2,0,0,1,2,0,0,0,0,0,1, - 2,0,1,2,1,0,2,0,1,2,0,0,0,0,1,2,1,0,1,2,1,2,1,0,1,2,1,2,0,0,1,2, - 1,2,0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2,1,2,0,0,0,0,0,0,1,2,0,0,1,2, - 0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2,0,1,2,1,2,0,0,1,2,1,2,0,0,0,0,1, - 2,0,0,1,2,0,0,0,0,1,2,0,0,0,0,0,0,1,2,0,0,2,0,0,0,2,0,0,0,0,0,0, - 1,2,1,0,1,2,1,2,0,0,1,2,0,1,1,1,0,2,1,2,0,0,0,0,0,1,2,0,1,2,1,1, - 1,1,0,0,1,1,1,1,0,0,1,2,0,0,0,0,1,1,1,1,1,2,0,0,1,2,0,0,0,0,0,1, - 2,0,1,1,0,2,0,0,1,2,0,0,0,0,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,1,2, - 1,1,1,1,0,2,1,2,0,0,1,2,1,1,1,1,0,2,0,1,1,1,0,0,0,0,1,2,0,0,1,2, - 0,0,1,2,0,1,0,1,0,2,1,2,1,0,1,2,0,0,1,0,2,0,0,0,1,0,2,0,0,0,1,0, - 2,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,2,1,2,1,2,1,1,1,1,1,2,0,1,2,2,1,0,1,2,0,0,0,0,0,1,2,0,1,2,1,2, - 2,2,2,0,1,2,2,2,2,0,1,2,0,1,1,0,1,2,2,2,1,2,0,0,1,2,0,0,0,0,0,1, - 2,0,1,2,1,0,0,0,1,2,0,0,0,0,1,2,0,2,1,2,1,2,0,1,1,2,1,2,0,0,1,2, - 1,2,2,2,2,0,1,2,0,0,1,2,1,2,1,2,2,0,0,0,2,2,1,0,0,0,1,2,0,0,1,2, - 0,0,1,2,0,1,2,1,2,0,1,2,1,2,1,2,0,1,0,1,0,0,0,0,1,2,0,0,0,1,0,2, - 0,0,0,1,2,0,0,0,0,0,0,1,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,2,1,1,0,2,1,2,2,2,1,2,0,1,2,0,1,2,1,2,0,0,0,0,0,1,2,0,1,2,1,2, - 0,0,0,0,1,2,0,0,0,0,1,2,0,0,1,2,1,2,0,0,1,2,0,0,1,2,0,0,0,0,0,1, - 2,0,1,2,0,1,0,0,1,2,0,0,0,0,1,2,0,0,1,2,1,2,0,1,1,2,1,2,0,0,1,2, - 1,2,0,0,0,0,1,2,0,0,1,2,1,2,0,1,0,0,0,0,0,0,1,2,0,0,1,2,0,0,1,2, - 0,0,1,2,0,1,2,1,2,0,1,2,1,2,1,2,0,1,2,1,2,0,0,0,1,2,0,0,0,1,2,0, - 0,0,0,1,2,0,0,0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,2,0,2,2,0,1,2,0,0,1,2,0,1,2,0,1,2,1,2,0,0,1,0,0,1,2,0,1,2,1,2, - 0,0,0,0,1,2,0,0,0,0,1,2,0,0,1,2,1,2,0,0,1,2,0,0,1,2,0,0,1,0,0,1, - 2,0,1,2,0,0,1,0,1,2,0,0,0,0,1,2,0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2, - 1,2,0,0,0,0,1,2,1,0,1,2,1,2,0,0,1,0,1,0,0,0,1,2,0,0,1,2,0,0,1,2, - 0,0,1,2,0,0,1,0,2,0,1,2,1,2,1,2,1,0,2,0,1,0,0,0,1,2,0,0,1,0,2,0, - 0,0,0,1,2,0,0,0,0,0,0,0,1,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,1,1,1,1,0,1,2,0,0,1,2,1,1,1,1,0,2,0,1,1,1,0,2,1,1,1,1,0,2,1,1, - 1,1,1,0,1,2,0,0,0,0,0,1,1,1,0,2,1,2,0,0,1,2,0,1,1,1,0,0,0,1,1,0, - 2,0,1,2,0,0,1,2,1,1,1,1,1,0,1,2,0,0,1,2,1,2,0,0,1,2,0,1,1,1,0,2, - 1,2,0,0,0,0,0,1,1,1,0,2,1,2,0,0,1,2,0,1,1,1,0,2,0,0,1,2,0,0,0,1, - 1,1,0,2,0,0,1,2,0,0,0,1,0,1,0,2,1,2,0,0,1,2,0,0,1,2,0,0,1,1,1,1, - 1,0,0,1,2,0,0,0,0,0,0,0,1,2,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,2,2,2,2,0,2,0,0,0,2,0,2,2,2,2,0,0,0,2,2,2,0,0,2,2,2,2,0,0,2, - 2,2,2,2,0,2,0,0,0,0,0,0,2,2,2,0,0,2,0,0,0,2,0,0,2,2,2,0,0,0,2,2, - 0,0,0,2,0,0,0,2,0,2,2,2,2,2,0,2,0,0,0,2,0,2,0,0,0,2,0,0,2,2,2,0, - 0,2,0,0,0,0,0,0,2,2,1,0,0,2,0,0,0,2,0,0,2,2,2,0,0,0,0,2,0,0,0,0, - 2,2,2,0,0,0,0,2,0,0,0,0,2,0,2,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,2,2, - 2,2,0,1,1,1,0,0,0,0,0,0,0,2,0,1,1,1,2,0,0,0,0,0,0,0,1,1,1,1,1,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,2,2,2,2,2, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,1,0,2,2,0,0,1,0,0,0,0,2,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0, - 0,0,0,0,2,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0, - 0,0,0,0,0,1,0,2,1,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,1,0,0,0,0,0,0,1, - 0,0,1,2,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,1,2,0,0,1,0,1,0,1,2,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0, - 0,0,0,0,0,1,2,0,0,2,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0, - 2,0,1,2,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,1,2,0,0,1,2,0,1,0,2,0,0,0,0,0,0, - 0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,2,0,1, - 1,1,0,0,0,1,2,0,0,0,0,1,1,1,0,0,1,2,1,1,0,0,0,1,1,0,0,0,0,0,1,1, - 0,0,1,2,0,1,0,0,0,0,1,2,0,0,1,1,0,1,0,0,1,0,1,1,0,0,0,1,1,1,0,0, - 1,1,1,1,0,0,0,1,1,1,1,0,1,0,1,1,0,0,0,1,1,1,0,0,1,1,1,1,0,0,1,0, - 0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,1,1,1, - 1,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,2,0,0,2,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,2,2,1,0,1,2,2,2,1,0,1,0,2,2,1,0,1,0,2,2,1,2,1,0, - 2,2,1,0,1,1,1,1,0,0,1,0,2,2,1,0,1,1,0,2,1,0,0,0,1,2,0,0,0,0,0,1, - 2,0,1,2,1,0,2,0,0,0,1,2,0,0,1,2,1,0,1,0,1,1,0,2,1,0,1,0,2,2,1,0, - 1,2,2,2,1,0,1,0,2,2,1,2,1,1,0,2,1,0,1,0,2,2,1,0,0,1,2,2,2,0,1,2, - 0,0,1,2,1,2,0,0,1,2,1,2,0,0,1,2,0,1,0,1,0,2,1,2,0,0,1,2,0,2,2,1, - 2,2,1,1,0,2,0,0,0,0,1,2,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,1,1,1,1,2,1,2,0,0,1,2,1,2,0,0,0,2,1,2,0,0,1,2,1,1, - 1,1,1,2,0,1,2,2,2,0,1,2,0,0,1,2,1,2,2,0,1,2,0,0,1,2,0,0,0,0,0,1, - 2,0,1,1,0,2,0,0,0,0,1,2,0,0,1,2,1,2,1,2,1,2,2,0,1,2,1,2,0,0,1,2, - 1,2,0,0,1,2,1,2,0,0,1,2,1,2,2,0,0,2,0,1,1,0,0,2,0,1,2,0,0,0,1,2, - 0,0,1,2,1,2,0,0,1,2,1,2,1,0,1,2,0,0,1,0,2,0,1,2,0,0,1,2,0,0,1,0, - 2,0,0,2,1,0,0,0,0,0,1,2,0,0,0,0,1,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,1,0,2,2,1,2,1,2,0,0,1,2,1,2,0,0,0,0,1,2,0,0,1,2,1,2, - 2,2,2,2,0,1,2,0,0,0,1,2,0,0,1,2,1,2,0,0,1,2,0,0,1,2,0,0,0,0,0,1, - 2,0,1,2,1,0,0,0,0,0,1,2,0,0,1,2,1,2,1,2,1,2,0,0,1,2,1,2,0,0,1,2, - 1,2,0,0,1,2,1,2,0,0,1,2,1,2,0,0,0,0,0,0,2,1,0,0,0,1,2,0,0,0,1,2, - 0,0,1,2,0,1,0,1,0,2,1,2,1,2,1,2,0,0,1,2,0,0,1,2,0,1,1,2,0,1,0,2, - 0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,1,2,0,1,1,2,1,2,0,0,1,2,1,2,0,0,1,0,1,2,0,0,1,2,1,2, - 0,0,1,0,0,1,2,0,0,0,0,1,1,1,1,2,1,2,0,0,1,2,0,0,1,2,0,0,0,0,0,1, - 2,0,1,2,0,1,0,0,0,0,1,2,0,0,1,2,1,2,1,2,1,2,0,0,1,2,1,2,0,0,1,2, - 1,1,1,1,0,2,0,1,1,1,1,2,1,2,0,0,0,0,1,0,0,0,1,0,0,1,2,0,1,0,1,2, - 0,1,1,2,0,1,2,1,2,0,1,2,1,2,1,2,0,1,0,1,0,0,0,1,1,0,1,2,1,0,2,0, - 0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,1,1,0,1,2,1,1,1,1,0,2,0,1,1,1,0,2,0,1,1,1,1,2,0,1, - 1,1,0,2,0,1,2,0,0,0,0,0,2,2,1,2,1,2,0,0,1,2,0,1,1,1,0,0,1,0,0,1, - 2,0,1,2,0,0,1,0,0,1,1,1,0,0,1,2,0,2,1,2,1,2,0,0,1,2,0,1,1,1,0,2, - 1,2,2,2,2,0,0,0,2,2,1,2,1,2,0,0,0,0,0,1,1,1,0,2,0,0,1,1,0,2,0,1, - 1,0,1,2,0,0,1,0,2,0,0,1,0,1,0,2,1,0,2,0,1,0,0,0,2,2,1,2,1,1,1,1, - 1,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,2,2,0,2,0,2,2,2,2,0,0,0,2,2,2,0,0,0,2,2,2,2,0,0, - 2,2,2,0,0,0,2,0,0,0,1,0,0,0,1,2,0,2,0,0,0,2,0,0,2,2,2,0,1,2,0,1, - 2,0,0,2,0,0,0,2,0,0,2,2,2,0,0,2,0,0,0,2,0,2,0,0,0,2,0,0,2,2,2,0, - 1,2,0,0,0,0,0,0,0,0,1,2,0,2,0,0,0,0,0,0,2,2,2,0,0,0,0,2,2,0,0,0, - 2,2,0,2,0,0,0,2,0,0,0,0,2,0,2,0,0,2,0,0,0,2,1,0,0,0,1,2,0,2,2,2, - 2,2,0,0,0,1,1,0,0,0,0,2,0,0,1,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0, - 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,2,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,2,0,0,0,0, - 0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -}; - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * font_printf: Draw text to the screen at the given position and with the - * given color. The string can contain printf()-style format specifiers. - * - * It is assumed that a display list has been started with guStart() - * before calling this function. - * - * [Parameters] - * x, y: Upper-left coordinates of first character - * align: Horizontal alignment (<0: left, 0: center, >0: right) - * color: Text color (0xAABBGGRR) - * format: Format string for text - * ...: Arguments for format string - * [Return value] - * X coordinate immediately following the last character printed - */ -int font_printf(int x, int y, int align, uint32_t color, - const char *format, ...) -{ - PRECOND(format != NULL, return x); - - /* Generate the text string to output */ - char buf[1000]; // Plenty long enough even if we start offscreen - va_list args; - va_start(args, format); - vsnprintf(buf, sizeof(buf), format, args); - va_end(args); - const int nchars = strlen(buf); - - /* Adjust the starting X coordinate based on the alignment */ - if (align == 0) { - x -= (nchars * CHAR_WIDTH + 1) / 2; - } else if (align > 0) { - x -= nchars * CHAR_WIDTH; - } - - /* Generate vertices for each character of the string */ - struct { - uint16_t u, v; - int16_t x, y, z; - } *vertices = guGetMemory(sizeof(*vertices) * (2*nchars)); - int i; - for (i = 0; i < nchars; i++, x += CHAR_WIDTH) { - uint8_t ch = buf[i]; - if (ch < FONTDATA_FIRSTCHAR || ch > FONTDATA_LASTCHAR) { - ch = FONTDATA_DEFCHAR; - } - const unsigned int index = ch - FONTDATA_FIRSTCHAR; - vertices[i*2+0].u = (index % FONTDATA_STRIDE) * CHAR_WIDTH; - vertices[i*2+0].v = (index / FONTDATA_STRIDE) * FONT_HEIGHT; - vertices[i*2+0].x = x; - vertices[i*2+0].y = y; - vertices[i*2+0].z = 0; - vertices[i*2+1].u = (index % FONTDATA_STRIDE + 1) * CHAR_WIDTH; - vertices[i*2+1].v = (index / FONTDATA_STRIDE + 1) * FONT_HEIGHT; - vertices[i*2+1].x = x + CHAR_WIDTH; - vertices[i*2+1].y = y + FONT_HEIGHT; - vertices[i*2+1].z = 0; - } - sceKernelDcacheWritebackInvalidateRange(vertices, - sizeof(*vertices) * (2*nchars)); - - /* Set up drawing parameters and draw the string. Unfortunately, color - * lookup tables have to be 64-byte aligned, so we can potentially - * waste a lot of memory here for just 3 color table entries... */ - uint32_t *clut = guGetMemory(3*4 + 60); - clut = (uint32_t *)(((uintptr_t)clut + 63) & -64); - clut[0] = 0x00000000; - clut[1] = color; - clut[2] = color & 0xFF000000; // Shadow pixels - guClutMode(GU_PSM_8888, 0, 0xFF, 0); - guClutLoad(8/8, clut); // We only use 3 of the 8 colors, but we have to - // send in a whole block - guEnable(GU_TEXTURE_2D); - guTexFlush(); - guTexMode(GU_PSM_T8, 0, 0, 0); - guTexImage(0, 512, 512, (FONTDATA_STRIDE * CHAR_WIDTH), fontdata); - guTexFilter(GU_NEAREST, GU_NEAREST); - guTexWrap(GU_CLAMP, GU_CLAMP); - guTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); - guAmbientColor(0xFFFFFFFF); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 2*nchars, NULL, vertices); - guDisable(GU_TEXTURE_2D); - - /* Return the next X coordinate for potential further drawing */ - return x; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/font.h b/yabause/src/psp/font.h deleted file mode 100644 index 217132f9d0..0000000000 --- a/yabause/src/psp/font.h +++ /dev/null @@ -1,64 +0,0 @@ -/* src/psp/font.h: Header for PSP menu font - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_FONT_H -#define PSP_FONT_H - -/*************************************************************************/ - -/* Height of the font, in pixels */ - -#define FONT_HEIGHT 13 - -/*-----------------------------------------------------------------------*/ - -/** - * font_printf: Draw text to the screen at the given position and with the - * given color. The string can contain printf()-style format specifiers. - * - * It is assumed that a display list has been started with sceGuStart() - * before calling this function. - * - * [Parameters] - * x, y: Upper-left coordinates of first character - * align: Horizontal alignment (<0: left, 0: center, >0: right) - * color: Text color (0xAABBGGRR) - * format: Format string for text - * ...: Arguments for format string - * [Return value] - * X coordinate immediately following the last character printed - */ -extern int font_printf(int x, int y, int align, uint32_t color, - const char *format, ...) - __attribute__((format(printf,5,6))); - -/*************************************************************************/ - -#endif // PSP_FONT_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/gu.c b/yabause/src/psp/gu.c deleted file mode 100644 index 936b15093c..0000000000 --- a/yabause/src/psp/gu.c +++ /dev/null @@ -1,488 +0,0 @@ -/* src/psp/gu.c: sceGu substitute library - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "gu.h" - -/*************************************************************************/ - -#ifndef USE_SCEGU // To the end of the file - -/*************************************************************************/ -/************************** Library-local data ***************************/ -/*************************************************************************/ - -/**** Data exported to inline functions in gu.h ****/ - -/* Current display list pointer */ -uint32_t *gu_list; - -/* Scissor status flag and test region (in GE command form) */ -uint32_t gu_scissorcmd_min, gu_scissorcmd_max; -uint8_t gu_scissor_enabled; - -/* Color/stencil (combined) value and depth value for clear operations */ -uint16_t gu_clear_depth; -uint32_t gu_clear_color_stencil; - -/*----------------------------------*/ - -/**** Data used only within this file ****/ - -/* Nonzero if we're writing a sublist, zero if we're writing the main list */ -static uint8_t gu_is_sublist; - -/* Saved display list pointer (during sublist generation, the main list - * pointer is pushed here) */ -static uint32_t *gu_saved_list; - -/* sceGe ID for current display list */ -static uint32_t gu_list_id; - -/*************************************************************************/ -/*********** Library functions (which aren't defined in gu.h) ************/ -/*************************************************************************/ - -/** - * guInit: Initialize the GU library. - * - * [Parameters] - * None - * [Return value] - * None - */ -void guInit(void) -{ - static const uint32_t ge_init_list[] = { - GECMD_VERTEX_POINTER<<24 | 0x000000, - GECMD_INDEX_POINTER <<24 | 0x000000, - GECMD_ADDRESS_BASE <<24 | 0x000000, - GECMD_VERTEX_FORMAT <<24 | 0x000000, - GECMD_UNKNOWN_13 <<24 | 0x000000, - GECMD_DRAWAREA_LOW <<24 | 0x000000, - GECMD_DRAWAREA_HIGH <<24 | 0x000000, - GECMD_ENA_LIGHTING <<24 | 0x000000, - GECMD_ENA_LIGHT0 <<24 | 0x000000, - GECMD_ENA_LIGHT1 <<24 | 0x000000, - GECMD_ENA_LIGHT2 <<24 | 0x000000, - GECMD_ENA_LIGHT3 <<24 | 0x000000, - GECMD_ENA_ZCLIP <<24 | 0x000000, - GECMD_ENA_FACE_CULL <<24 | 0x000000, - GECMD_ENA_TEXTURE <<24 | 0x000000, - GECMD_ENA_FOG <<24 | 0x000000, - GECMD_ENA_DITHER <<24 | 0x000000, - GECMD_ENA_BLEND <<24 | 0x000000, - GECMD_ENA_ALPHA_TEST<<24 | 0x000000, - GECMD_ENA_DEPTH_TEST<<24 | 0x000000, - GECMD_ENA_STENCIL <<24 | 0x000000, - GECMD_ENA_ANTIALIAS <<24 | 0x000000, - GECMD_ENA_PATCH_CULL<<24 | 0x000000, - GECMD_ENA_COLOR_TEST<<24 | 0x000000, - GECMD_ENA_LOGIC_OP <<24 | 0x000000, - GECMD_BONE_OFFSET <<24 | 0x000000, - GECMD_BONE_UPLOAD <<24 | 0x000000, - GECMD_MORPH_0 <<24 | 0x000000, - GECMD_MORPH_1 <<24 | 0x000000, - GECMD_MORPH_2 <<24 | 0x000000, - GECMD_MORPH_3 <<24 | 0x000000, - GECMD_MORPH_4 <<24 | 0x000000, - GECMD_MORPH_5 <<24 | 0x000000, - GECMD_MORPH_6 <<24 | 0x000000, - GECMD_MORPH_7 <<24 | 0x000000, - GECMD_PATCH_SUBDIV <<24 | 0x000000, - GECMD_PATCH_PRIM <<24 | 0x000000, - GECMD_PATCH_FRONT <<24 | 0x000000, - GECMD_MODEL_START <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x3F8000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x3F8000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x3F8000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_MODEL_UPLOAD <<24 | 0x000000, - GECMD_VIEW_START <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x3F8000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x3F8000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x3F8000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_VIEW_UPLOAD <<24 | 0x000000, - GECMD_PROJ_START <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x3F8000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x3F8000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x3F8000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x000000, - GECMD_PROJ_UPLOAD <<24 | 0x3F8000, - GECMD_TEXTURE_START <<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x3F8000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x3F8000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x3F8000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_TEXTURE_UPLOAD<<24 | 0x000000, - GECMD_XSCALE <<24 | 0x000000, - GECMD_YSCALE <<24 | 0x000000, - GECMD_ZSCALE <<24 | 0x000000, - GECMD_XPOS <<24 | 0x000000, - GECMD_YPOS <<24 | 0x000000, - GECMD_ZPOS <<24 | 0x000000, - GECMD_USCALE <<24 | 0x3F8000, - GECMD_VSCALE <<24 | 0x3F8000, - GECMD_UOFFSET <<24 | 0x000000, - GECMD_VOFFSET <<24 | 0x000000, - GECMD_XOFFSET <<24 | 0x000000, - GECMD_YOFFSET <<24 | 0x000000, - GECMD_SHADE_MODE <<24 | 0x000000, - GECMD_REV_NORMALS <<24 | 0x000000, - GECMD_COLOR_MATERIAL<<24 | 0x000000, - GECMD_EMISSIVE_COLOR<<24 | 0x000000, - GECMD_AMBIENT_COLOR <<24 | 0x000000, - GECMD_DIFFUSE_COLOR <<24 | 0x000000, - GECMD_SPECULAR_COLOR<<24 | 0x000000, - GECMD_AMBIENT_ALPHA <<24 | 0x000000, - GECMD_SPECULAR_POWER<<24 | 0x000000, - GECMD_LIGHT_AMBCOLOR<<24 | 0x000000, - GECMD_LIGHT_AMBALPHA<<24 | 0x000000, - GECMD_LIGHT_MODEL <<24 | 0x000000, - GECMD_LIGHT0_TYPE <<24 | 0x000000, - GECMD_LIGHT1_TYPE <<24 | 0x000000, - GECMD_LIGHT2_TYPE <<24 | 0x000000, - GECMD_LIGHT3_TYPE <<24 | 0x000000, - GECMD_LIGHT0_XPOS <<24 | 0x000000, - GECMD_LIGHT0_YPOS <<24 | 0x000000, - GECMD_LIGHT0_ZPOS <<24 | 0x000000, - GECMD_LIGHT1_XPOS <<24 | 0x000000, - GECMD_LIGHT1_YPOS <<24 | 0x000000, - GECMD_LIGHT1_ZPOS <<24 | 0x000000, - GECMD_LIGHT2_XPOS <<24 | 0x000000, - GECMD_LIGHT2_YPOS <<24 | 0x000000, - GECMD_LIGHT2_ZPOS <<24 | 0x000000, - GECMD_LIGHT3_XPOS <<24 | 0x000000, - GECMD_LIGHT3_YPOS <<24 | 0x000000, - GECMD_LIGHT3_ZPOS <<24 | 0x000000, - GECMD_LIGHT0_XDIR <<24 | 0x000000, - GECMD_LIGHT0_YDIR <<24 | 0x000000, - GECMD_LIGHT0_ZDIR <<24 | 0x000000, - GECMD_LIGHT1_XDIR <<24 | 0x000000, - GECMD_LIGHT1_YDIR <<24 | 0x000000, - GECMD_LIGHT1_ZDIR <<24 | 0x000000, - GECMD_LIGHT2_XDIR <<24 | 0x000000, - GECMD_LIGHT2_YDIR <<24 | 0x000000, - GECMD_LIGHT2_ZDIR <<24 | 0x000000, - GECMD_LIGHT3_XDIR <<24 | 0x000000, - GECMD_LIGHT3_YDIR <<24 | 0x000000, - GECMD_LIGHT3_ZDIR <<24 | 0x000000, - GECMD_LIGHT0_CATT <<24 | 0x000000, - GECMD_LIGHT0_LATT <<24 | 0x000000, - GECMD_LIGHT0_QATT <<24 | 0x000000, - GECMD_LIGHT1_CATT <<24 | 0x000000, - GECMD_LIGHT1_LATT <<24 | 0x000000, - GECMD_LIGHT1_QATT <<24 | 0x000000, - GECMD_LIGHT2_CATT <<24 | 0x000000, - GECMD_LIGHT2_LATT <<24 | 0x000000, - GECMD_LIGHT2_QATT <<24 | 0x000000, - GECMD_LIGHT3_CATT <<24 | 0x000000, - GECMD_LIGHT3_LATT <<24 | 0x000000, - GECMD_LIGHT3_QATT <<24 | 0x000000, - GECMD_LIGHT0_SPOTEXP<<24 | 0x000000, - GECMD_LIGHT1_SPOTEXP<<24 | 0x000000, - GECMD_LIGHT2_SPOTEXP<<24 | 0x000000, - GECMD_LIGHT3_SPOTEXP<<24 | 0x000000, - GECMD_LIGHT0_SPOTLIM<<24 | 0x000000, - GECMD_LIGHT1_SPOTLIM<<24 | 0x000000, - GECMD_LIGHT2_SPOTLIM<<24 | 0x000000, - GECMD_LIGHT3_SPOTLIM<<24 | 0x000000, - GECMD_LIGHT0_ACOL <<24 | 0x000000, - GECMD_LIGHT0_DCOL <<24 | 0x000000, - GECMD_LIGHT0_SCOL <<24 | 0x000000, - GECMD_LIGHT1_ACOL <<24 | 0x000000, - GECMD_LIGHT1_DCOL <<24 | 0x000000, - GECMD_LIGHT1_SCOL <<24 | 0x000000, - GECMD_LIGHT2_ACOL <<24 | 0x000000, - GECMD_LIGHT2_DCOL <<24 | 0x000000, - GECMD_LIGHT2_SCOL <<24 | 0x000000, - GECMD_LIGHT3_ACOL <<24 | 0x000000, - GECMD_LIGHT3_DCOL <<24 | 0x000000, - GECMD_LIGHT3_SCOL <<24 | 0x000000, - GECMD_FACE_ORDER <<24 | 0x000000, - GECMD_DRAW_ADDRESS <<24 | 0x000000, - GECMD_DRAW_STRIDE <<24 | 0x000000, - GECMD_DEPTH_ADDRESS <<24 | 0x000000, - GECMD_DEPTH_STRIDE <<24 | 0x000000, - GECMD_TEX0_ADDRESS <<24 | 0x000000, - GECMD_TEX1_ADDRESS <<24 | 0x000000, - GECMD_TEX2_ADDRESS <<24 | 0x000000, - GECMD_TEX3_ADDRESS <<24 | 0x000000, - GECMD_TEX4_ADDRESS <<24 | 0x000000, - GECMD_TEX5_ADDRESS <<24 | 0x000000, - GECMD_TEX6_ADDRESS <<24 | 0x000000, - GECMD_TEX7_ADDRESS <<24 | 0x000000, - GECMD_TEX0_STRIDE <<24 | 0x040004, - GECMD_TEX1_STRIDE <<24 | 0x000000, - GECMD_TEX2_STRIDE <<24 | 0x000000, - GECMD_TEX3_STRIDE <<24 | 0x000000, - GECMD_TEX4_STRIDE <<24 | 0x000000, - GECMD_TEX5_STRIDE <<24 | 0x000000, - GECMD_TEX6_STRIDE <<24 | 0x000000, - GECMD_TEX7_STRIDE <<24 | 0x000000, - GECMD_CLUT_ADDRESS_L<<24 | 0x000000, - GECMD_CLUT_ADDRESS_H<<24 | 0x000000, - GECMD_COPY_S_ADDRESS<<24 | 0x000000, - GECMD_COPY_S_STRIDE <<24 | 0x000000, - GECMD_COPY_D_ADDRESS<<24 | 0x000000, - GECMD_COPY_D_STRIDE <<24 | 0x000000, - GECMD_TEX0_SIZE <<24 | 0x000101, - GECMD_TEX1_SIZE <<24 | 0x000000, - GECMD_TEX2_SIZE <<24 | 0x000000, - GECMD_TEX3_SIZE <<24 | 0x000000, - GECMD_TEX4_SIZE <<24 | 0x000000, - GECMD_TEX5_SIZE <<24 | 0x000000, - GECMD_TEX6_SIZE <<24 | 0x000000, - GECMD_TEX7_SIZE <<24 | 0x000000, - GECMD_TEXTURE_MAP <<24 | 0x000000, - GECMD_TEXTURE_ENVMAP<<24 | 0x000000, - GECMD_TEXTURE_MODE <<24 | 0x000000, - GECMD_TEXTURE_PIXFMT<<24 | 0x000000, - GECMD_CLUT_LOAD <<24 | 0x000000, - GECMD_CLUT_MODE <<24 | 0x000000, - GECMD_TEXTURE_FILTER<<24 | 0x000000, - GECMD_TEXTURE_WRAP <<24 | 0x000000, - GECMD_TEXTURE_BIAS <<24 | 0x000000, - GECMD_TEXTURE_FUNC <<24 | 0x000000, - GECMD_TEXTURE_COLOR <<24 | 0x000000, - GECMD_TEXTURE_FLUSH <<24 | 0x000000, - GECMD_COPY_SYNC <<24 | 0x000000, - GECMD_FOG_LIMIT <<24 | 0x000000, - GECMD_FOG_RANGE <<24 | 0x000000, - GECMD_FOG_COLOR <<24 | 0x000000, - GECMD_TEXTURE_SLOPE <<24 | 0x000000, - GECMD_FRAME_PIXFMT <<24 | 0x000000, - GECMD_CLEAR_MODE <<24 | 0x000000, - GECMD_CLIP_MIN <<24 | 0x000000, - GECMD_CLIP_MAX <<24 | 0x000000, - GECMD_CLIP_NEAR <<24 | 0x000000, - GECMD_CLIP_FAR <<24 | 0x000000, - GECMD_COLORTEST_FUNC<<24 | 0x000000, - GECMD_COLORTEST_REF <<24 | 0x000000, - GECMD_COLORTEST_MASK<<24 | 0x000000, - GECMD_ALPHATEST <<24 | 0x000000, - GECMD_STENCILTEST <<24 | 0x000000, - GECMD_STENCIL_OP <<24 | 0x000000, - GECMD_DEPTHTEST <<24 | 0x000000, - GECMD_BLEND_FUNC <<24 | 0x000000, - GECMD_BLEND_SRCFIX <<24 | 0x000000, - GECMD_BLEND_DSTFIX <<24 | 0x000000, - GECMD_DITHER0 <<24 | 0x000000, - GECMD_DITHER1 <<24 | 0x000000, - GECMD_DITHER2 <<24 | 0x000000, - GECMD_DITHER3 <<24 | 0x000000, - GECMD_LOGIC_OP <<24 | 0x000000, - GECMD_DEPTH_MASK <<24 | 0x000000, - GECMD_COLOR_MASK <<24 | 0x000000, - GECMD_ALPHA_MASK <<24 | 0x000000, - GECMD_COPY_S_POS <<24 | 0x000000, - GECMD_COPY_D_POS <<24 | 0x000000, - GECMD_COPY_SIZE <<24 | 0x000000, - GECMD_UNKNOWN_F0 <<24 | 0x000000, - GECMD_UNKNOWN_F1 <<24 | 0x000000, - GECMD_UNKNOWN_F2 <<24 | 0x000000, - GECMD_UNKNOWN_F3 <<24 | 0x000000, - GECMD_UNKNOWN_F4 <<24 | 0x000000, - GECMD_UNKNOWN_F5 <<24 | 0x000000, - GECMD_UNKNOWN_F6 <<24 | 0x000000, - GECMD_UNKNOWN_F7 <<24 | 0x000000, - GECMD_UNKNOWN_F8 <<24 | 0x000000, - GECMD_UNKNOWN_F9 <<24 | 0x000000, - GECMD_FINISH <<24 | 0x000000, - GECMD_END <<24 | 0x000000, - GECMD_NOP <<24 | 0x000000, - GECMD_NOP <<24 | 0x000000, - }; - - int listid = sceGeListEnQueue(ge_init_list, NULL, 0, 0); - sceGeListSync(listid, PSP_GE_LIST_DONE); -} - -/*************************************************************************/ - -/** - * guStart: Start a new display list. - * - * [Parameters] - * type: List type (GU_DIRECT or GU_CALL) - * list: List pointer - */ -void guStart(const int type, void * const list) -{ - if (type == GU_CALL) { - gu_saved_list = gu_list; - gu_is_sublist = 1; - } else { - gu_is_sublist = 0; - gu_list_id = sceGeListEnQueue(list, list, 0, 0); - } - gu_list = list; -} - -/*-----------------------------------------------------------------------*/ - -/** - * guFinish: End the current display list. - * - * [Parameters] - * None - * [Return value] - * None - */ -void guFinish(void) -{ - if (gu_is_sublist) { - *gu_list = GECMD_RETURN<<24; - gu_list = gu_saved_list; - gu_saved_list = NULL; - gu_is_sublist = 0; - } else { - *gu_list++ = GECMD_FINISH<<24; - *gu_list++ = GECMD_END<<24; - guCommit(); - gu_list = NULL; - } -} - -/*************************************************************************/ - -/** - * guCommit: Commit all previously-added commands to memory and start - * GE processing. Does nothing if the current display list is not a - * GU_DIRECT list. - * - * [Parameters] - * None - * [Return value] - * None - */ -void guCommit(void) -{ - if (gu_list && !gu_is_sublist) { - /* If a partially-used cache line hangs around until the next frame - * and the next frame's display list is different, we could end up - * clobbering the display list with old data, so invalidate all the - * cache lines we touched in addition to writing them back to - * memory. */ - sceKernelDcacheWritebackInvalidateAll(); - sceGeListUpdateStallAddr(gu_list_id, gu_list); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * guSync: Wait for GE processing to complete. - * - * [Parameters] - * mode: Synchronization mode (GU_SYNC_*) - * target: Synchronization target (GU_SYNC_WHAT_*) - * [Return value] - * None - */ -void guSync(const int mode, const int target) -{ - if (gu_list_id) { - if (mode != GU_SYNC_FINISH || target != GU_SYNC_WHAT_DONE) { - return; - } - sceGeDrawSync(PSP_GE_LIST_DONE); - sceGeListDeQueue(gu_list_id); - gu_list_id = 0; - } -} - -/*************************************************************************/ - -/** - * guGetMemory: Allocate a block of memory from the current GU_DIRECT - * list. The allocation size will automatically be rounded up to a - * multiple of 4 bytes. - * - * This function may not be called unless there is a current GU_DIRECT - * list. - * - * [Parameters] - * size: Number of bytes to allocate - */ -void *guGetMemory(const uint32_t size) -{ - uint32_t **list_ref = (gu_is_sublist ? &gu_saved_list : &gu_list); - const uint32_t alloc_words = (size + 3) / 4; - uint32_t * const alloc_ptr = (*list_ref) + 2; - uint32_t * const target = alloc_ptr + alloc_words; - (*list_ref)[0] = GECMD_ADDRESS_BASE<<24 - | ((uint32_t)target & 0xFF000000) >> 8; - (*list_ref)[1] = GECMD_JUMP<<24 - | ((uint32_t)target & 0x00FFFFFF); - (*list_ref) = target; - return alloc_ptr; -} - -/*************************************************************************/ - -#endif // USE_SCEGU - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/gu.h b/yabause/src/psp/gu.h deleted file mode 100644 index 87e42cd178..0000000000 --- a/yabause/src/psp/gu.h +++ /dev/null @@ -1,1006 +0,0 @@ -/* src/psp/gu.h: sceGu substitute library header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_GU_H -#define PSP_GU_H - -/* - * This library defines a substitute set of functions for the sceGu library - * used for manipulating display lists. These substitute functions are - * designed for maximum efficiency when dynamically generating display - * lists, and improve on the sceGu library in the following ways: - * - * - The sceGu library functions (at least as implemented in PSPSDK r2450) - * are designed to be robust against data corruption by using uncached - * memory accesses, but such accesses naturally slow the program down - * significantly. The functions defined here avoid this slowdown by - * making judicious use of the CPU's cache, allowing the CPU to access - * memory in cache line units instead of individual words. - * - * - The sceGuDrawArray() function triggers the GE to resume processing - * after writing instructions to the display list. In theory, this can - * improve performance by maximizing parallelism between the GE and the - * main Allegrex CPU; however, when constructing dynamic display lists - * which may by necessity include frequent DrawArray() calls, the - * overhead of synchronization far outweighs any performance gain. This - * library defines a guCommit() function allowing the caller to specify - * exactly when to trigger the GE, and does not do so on its own (except - * when calling guFinish() on a GU_DIRECT display list). - * - * - The sceGuDrawArray also requires the vertex type, vertex pointer, - * vertex count, and primitive type to all be specified in a single - * call. This can waste a significant amount of space when generating - * dynamic vertex arrays in which the vertex type is constant but the - * number of vertices cannot be easily computed or stored. This library - * defines guVertexFormat(), guVertexPointer(), and guDrawPrimitive() - * functions which implement each of the separate functions of - * guDrawArray(), so only the necessary functions need to be called. - * - * - Many of the texture-related functions internally call sceGuTexFlush() - * to flush the texture cache. While robust, this can cause significant - * bloat of the resulting display list. This library never calls - * guTexFlush() automatically; it is thus up to the caller to flush the - * texture cache at appropriate points. - * - * - Most of the substitute functions are defined as inline functions in - * this file, allowing the compiler to avoid the overhead of calling a - * subroutine for each graphics operation and to fold constant parameters - * when computing GE instruction words. GCC, at least, can also optimize - * out the updates of the list pointer variable after each instruction, - * saving a significant amount of code. In an optimal case where all - * function parameters are constant, such as - * sceGuTexFilter(GU_NEAREST, GU_NEAREST); - * execution time can be reduced from >20 cycles to 3 (or even 2) cycles - * per call. - * - * Note that this library is only implemented to the extent necessary for - * Yabause, and needs more work to be usable as a general-purpose library. - */ - -/*************************************************************************/ -/*************************************************************************/ - -/** - * USE_SCEGU: When defined, the guXxx() functions declared in this file - * will instead be aliased to the standard sceGuXxx() library functions, - * and custom functions not defined in the sceGu library such as guCommit() - * are turned into no-ops. The sceGu functions are slower than our custom - * functions, so there is normally no reason to define this symbol except - * for benchmarking or testing. - */ -// #define USE_SCEGU - -/*************************************************************************/ -/************************ GE command definitions *************************/ -/*************************************************************************/ - -typedef enum GECommand_ { - GECMD_NOP = 0x00, - GECMD_VERTEX_POINTER= 0x01, - GECMD_INDEX_POINTER = 0x02, - // 0x03 undefined - GECMD_DRAW_PRIMITIVE= 0x04, - GECMD_DRAW_BEZIER = 0x05, - GECMD_DRAW_SPLINE = 0x06, - GECMD_TEST_BBOX = 0x07, - GECMD_JUMP = 0x08, - GECMD_COND_JUMP = 0x09, - GECMD_CALL = 0x0A, - GECMD_RETURN = 0x0B, - GECMD_END = 0x0C, - // 0x0D undefined - GECMD_SIGNAL = 0x0E, - GECMD_FINISH = 0x0F, - - GECMD_ADDRESS_BASE = 0x10, - // 0x11 undefined - GECMD_VERTEX_FORMAT = 0x12, - GECMD_UNKNOWN_13 = 0x13, // psp_doc: Offset Address (BASE) - GECMD_UNKNOWN_14 = 0x14, // psp_doc: Origin Address (BASE) - GECMD_DRAWAREA_LOW = 0x15, - GECMD_DRAWAREA_HIGH = 0x16, - GECMD_ENA_LIGHTING = 0x17, - GECMD_ENA_LIGHT0 = 0x18, - GECMD_ENA_LIGHT1 = 0x19, - GECMD_ENA_LIGHT2 = 0x1A, - GECMD_ENA_LIGHT3 = 0x1B, - GECMD_ENA_ZCLIP = 0x1C, - GECMD_ENA_FACE_CULL = 0x1D, - GECMD_ENA_TEXTURE = 0x1E, - GECMD_ENA_FOG = 0x1F, - - GECMD_ENA_DITHER = 0x20, - GECMD_ENA_BLEND = 0x21, - GECMD_ENA_ALPHA_TEST= 0x22, - GECMD_ENA_DEPTH_TEST= 0x23, - GECMD_ENA_STENCIL = 0x24, - GECMD_ENA_ANTIALIAS = 0x25, - GECMD_ENA_PATCH_CULL= 0x26, - GECMD_ENA_COLOR_TEST= 0x27, - GECMD_ENA_LOGIC_OP = 0x28, - // 0x29 undefined - GECMD_BONE_OFFSET = 0x2A, - GECMD_BONE_UPLOAD = 0x2B, - GECMD_MORPH_0 = 0x2C, - GECMD_MORPH_1 = 0x2D, - GECMD_MORPH_2 = 0x2E, - GECMD_MORPH_3 = 0x2F, - - GECMD_MORPH_4 = 0x30, - GECMD_MORPH_5 = 0x31, - GECMD_MORPH_6 = 0x32, - GECMD_MORPH_7 = 0x33, - // 0x34 undefined - // 0x35 undefined - GECMD_PATCH_SUBDIV = 0x36, - GECMD_PATCH_PRIM = 0x37, - GECMD_PATCH_FRONT = 0x38, - // 0x39 undefined - GECMD_MODEL_START = 0x3A, - GECMD_MODEL_UPLOAD = 0x3B, - GECMD_VIEW_START = 0x3C, - GECMD_VIEW_UPLOAD = 0x3D, - GECMD_PROJ_START = 0x3E, - GECMD_PROJ_UPLOAD = 0x3F, - - GECMD_TEXTURE_START = 0x40, - GECMD_TEXTURE_UPLOAD= 0x41, - GECMD_XSCALE = 0x42, - GECMD_YSCALE = 0x43, - GECMD_ZSCALE = 0x44, - GECMD_XPOS = 0x45, - GECMD_YPOS = 0x46, - GECMD_ZPOS = 0x47, - GECMD_USCALE = 0x48, - GECMD_VSCALE = 0x49, - GECMD_UOFFSET = 0x4A, - GECMD_VOFFSET = 0x4B, - GECMD_XOFFSET = 0x4C, - GECMD_YOFFSET = 0x4D, - // 0x4E undefined - // 0x4F undefined - - GECMD_SHADE_MODE = 0x50, - GECMD_REV_NORMALS = 0x51, - // 0x52 undefined - GECMD_COLOR_MATERIAL= 0x53, - GECMD_EMISSIVE_COLOR= 0x54, - GECMD_AMBIENT_COLOR = 0x55, - GECMD_DIFFUSE_COLOR = 0x56, - GECMD_SPECULAR_COLOR= 0x57, - GECMD_AMBIENT_ALPHA = 0x58, - // 0x59 undefined - // 0x5A undefined - GECMD_SPECULAR_POWER= 0x5B, - GECMD_LIGHT_AMBCOLOR= 0x5C, - GECMD_LIGHT_AMBALPHA= 0x5D, - GECMD_LIGHT_MODEL = 0x5E, - GECMD_LIGHT0_TYPE = 0x5F, - - GECMD_LIGHT1_TYPE = 0x60, - GECMD_LIGHT2_TYPE = 0x61, - GECMD_LIGHT3_TYPE = 0x62, - GECMD_LIGHT0_XPOS = 0x63, - GECMD_LIGHT0_YPOS = 0x64, - GECMD_LIGHT0_ZPOS = 0x65, - GECMD_LIGHT1_XPOS = 0x66, - GECMD_LIGHT1_YPOS = 0x67, - GECMD_LIGHT1_ZPOS = 0x68, - GECMD_LIGHT2_XPOS = 0x69, - GECMD_LIGHT2_YPOS = 0x6A, - GECMD_LIGHT2_ZPOS = 0x6B, - GECMD_LIGHT3_XPOS = 0x6C, - GECMD_LIGHT3_YPOS = 0x6D, - GECMD_LIGHT3_ZPOS = 0x6E, - GECMD_LIGHT0_XDIR = 0x6F, - - GECMD_LIGHT0_YDIR = 0x70, - GECMD_LIGHT0_ZDIR = 0x71, - GECMD_LIGHT1_XDIR = 0x72, - GECMD_LIGHT1_YDIR = 0x73, - GECMD_LIGHT1_ZDIR = 0x74, - GECMD_LIGHT2_XDIR = 0x75, - GECMD_LIGHT2_YDIR = 0x76, - GECMD_LIGHT2_ZDIR = 0x77, - GECMD_LIGHT3_XDIR = 0x78, - GECMD_LIGHT3_YDIR = 0x79, - GECMD_LIGHT3_ZDIR = 0x7A, - GECMD_LIGHT0_CATT = 0x7B, - GECMD_LIGHT0_LATT = 0x7C, - GECMD_LIGHT0_QATT = 0x7D, - GECMD_LIGHT1_CATT = 0x7E, - GECMD_LIGHT1_LATT = 0x7F, - - GECMD_LIGHT1_QATT = 0x80, - GECMD_LIGHT2_CATT = 0x81, - GECMD_LIGHT2_LATT = 0x82, - GECMD_LIGHT2_QATT = 0x83, - GECMD_LIGHT3_CATT = 0x84, - GECMD_LIGHT3_LATT = 0x85, - GECMD_LIGHT3_QATT = 0x86, - GECMD_LIGHT0_SPOTEXP= 0x87, - GECMD_LIGHT1_SPOTEXP= 0x88, - GECMD_LIGHT2_SPOTEXP= 0x89, - GECMD_LIGHT3_SPOTEXP= 0x8A, - GECMD_LIGHT0_SPOTLIM= 0x8B, - GECMD_LIGHT1_SPOTLIM= 0x8C, - GECMD_LIGHT2_SPOTLIM= 0x8D, - GECMD_LIGHT3_SPOTLIM= 0x8E, - GECMD_LIGHT0_ACOL = 0x8F, - - GECMD_LIGHT0_DCOL = 0x90, - GECMD_LIGHT0_SCOL = 0x91, - GECMD_LIGHT1_ACOL = 0x92, - GECMD_LIGHT1_DCOL = 0x93, - GECMD_LIGHT1_SCOL = 0x94, - GECMD_LIGHT2_ACOL = 0x95, - GECMD_LIGHT2_DCOL = 0x96, - GECMD_LIGHT2_SCOL = 0x97, - GECMD_LIGHT3_ACOL = 0x98, - GECMD_LIGHT3_DCOL = 0x99, - GECMD_LIGHT3_SCOL = 0x9A, - GECMD_FACE_ORDER = 0x9B, - GECMD_DRAW_ADDRESS = 0x9C, - GECMD_DRAW_STRIDE = 0x9D, - GECMD_DEPTH_ADDRESS = 0x9E, - GECMD_DEPTH_STRIDE = 0x9F, - - GECMD_TEX0_ADDRESS = 0xA0, - GECMD_TEX1_ADDRESS = 0xA1, - GECMD_TEX2_ADDRESS = 0xA2, - GECMD_TEX3_ADDRESS = 0xA3, - GECMD_TEX4_ADDRESS = 0xA4, - GECMD_TEX5_ADDRESS = 0xA5, - GECMD_TEX6_ADDRESS = 0xA6, - GECMD_TEX7_ADDRESS = 0xA7, - GECMD_TEX0_STRIDE = 0xA8, - GECMD_TEX1_STRIDE = 0xA9, - GECMD_TEX2_STRIDE = 0xAA, - GECMD_TEX3_STRIDE = 0xAB, - GECMD_TEX4_STRIDE = 0xAC, - GECMD_TEX5_STRIDE = 0xAD, - GECMD_TEX6_STRIDE = 0xAE, - GECMD_TEX7_STRIDE = 0xAF, - - GECMD_CLUT_ADDRESS_L= 0xB0, - GECMD_CLUT_ADDRESS_H= 0xB1, - GECMD_COPY_S_ADDRESS= 0xB2, - GECMD_COPY_S_STRIDE = 0xB3, - GECMD_COPY_D_ADDRESS= 0xB4, - GECMD_COPY_D_STRIDE = 0xB5, - // 0xB6 undefined - // 0xB7 undefined - GECMD_TEX0_SIZE = 0xB8, - GECMD_TEX1_SIZE = 0xB9, - GECMD_TEX2_SIZE = 0xBA, - GECMD_TEX3_SIZE = 0xBB, - GECMD_TEX4_SIZE = 0xBC, - GECMD_TEX5_SIZE = 0xBD, - GECMD_TEX6_SIZE = 0xBE, - GECMD_TEX7_SIZE = 0xBF, - - GECMD_TEXTURE_MAP = 0xC0, - GECMD_TEXTURE_ENVMAP= 0xC1, - GECMD_TEXTURE_MODE = 0xC2, - GECMD_TEXTURE_PIXFMT= 0xC3, - GECMD_CLUT_LOAD = 0xC4, - GECMD_CLUT_MODE = 0xC5, - GECMD_TEXTURE_FILTER= 0xC6, - GECMD_TEXTURE_WRAP = 0xC7, - GECMD_TEXTURE_BIAS = 0xC8, - GECMD_TEXTURE_FUNC = 0xC9, - GECMD_TEXTURE_COLOR = 0xCA, - GECMD_TEXTURE_FLUSH = 0xCB, - GECMD_COPY_SYNC = 0xCC, - GECMD_FOG_LIMIT = 0xCD, - GECMD_FOG_RANGE = 0xCE, - GECMD_FOG_COLOR = 0xCF, - - GECMD_TEXTURE_SLOPE = 0xD0, - // 0xD1 undefined - GECMD_FRAME_PIXFMT = 0xD2, - GECMD_CLEAR_MODE = 0xD3, - GECMD_CLIP_MIN = 0xD4, - GECMD_CLIP_MAX = 0xD5, - GECMD_CLIP_NEAR = 0xD6, - GECMD_CLIP_FAR = 0xD7, - GECMD_COLORTEST_FUNC= 0xD8, - GECMD_COLORTEST_REF = 0xD9, - GECMD_COLORTEST_MASK= 0xDA, - GECMD_ALPHATEST = 0xDB, - GECMD_STENCILTEST = 0xDC, - GECMD_STENCIL_OP = 0xDD, - GECMD_DEPTHTEST = 0xDE, - GECMD_BLEND_FUNC = 0xDF, - - GECMD_BLEND_SRCFIX = 0xE0, - GECMD_BLEND_DSTFIX = 0xE1, - GECMD_DITHER0 = 0xE2, - GECMD_DITHER1 = 0xE3, - GECMD_DITHER2 = 0xE4, - GECMD_DITHER3 = 0xE5, - GECMD_LOGIC_OP = 0xE6, - GECMD_DEPTH_MASK = 0xE7, - GECMD_COLOR_MASK = 0xE8, - GECMD_ALPHA_MASK = 0xE9, - GECMD_COPY = 0xEA, - GECMD_COPY_S_POS = 0xEB, - GECMD_COPY_D_POS = 0xEC, - // 0xED undefined - GECMD_COPY_SIZE = 0xEE, - // 0xEF undefined - - GECMD_UNKNOWN_F0 = 0xF0, - GECMD_UNKNOWN_F1 = 0xF1, - GECMD_UNKNOWN_F2 = 0xF2, - GECMD_UNKNOWN_F3 = 0xF3, - GECMD_UNKNOWN_F4 = 0xF4, - GECMD_UNKNOWN_F5 = 0xF5, - GECMD_UNKNOWN_F6 = 0xF6, - GECMD_UNKNOWN_F7 = 0xF7, - GECMD_UNKNOWN_F8 = 0xF8, - GECMD_UNKNOWN_F9 = 0xF9, - // 0xFA..0xFF undefined -} GECommand; - -/*************************************************************************/ -/*********************** Custom library functions ************************/ -/*************************************************************************/ - -#ifndef USE_SCEGU - -/*************************************************************************/ - -/* Force these functions to be inlined to avoid function call overhead */ -#ifdef __GNUC__ -# define inline inline __attribute__((always_inline)) -#endif - -/* Note: we declare "extern uint32_t *gu_list" within each function rather - * than here so that we don't export the declaration to the caller. */ - -/* Macros for splitting an address into high and low parts */ -#define ADDRESS_HI(ptr) (((uint32_t)(ptr) & 0x3F000000) >> 8) -#define ADDRESS_LO(ptr) ((uint32_t)(ptr) & 0x00FFFFFF) - -/* Helper function to extract the high 24 bits of a float */ -static inline uint32_t trim_float(const float value) { - uint32_t result; - asm(".set push; .set noreorder\n" - "mfc1 %[result], %[value]\n" - "nop\n" - "srl %[result], %[result], 8\n" - ".set pop" - : [result] "=r" (result) - : [value] "f" (value) - ); - return result; -} - -/*************************************************************************/ - -/**** Functions defined in gu.c ****/ - -/* Custom function to commit cached data and start GE processing */ -extern void guCommit(void); - -extern void guFinish(void); -extern void *guGetMemory(const uint32_t size); -extern void guInit(void); -extern void guStart(const int type, void * const list); -extern void guSync(const int mode, const int target); - -/*************************************************************************/ - -/**** Inline functions ****/ - -static inline void guAlphaFunc(const int func, const int value, const int mask) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_ALPHATEST<<24 | mask<<16 | value<<8 | func; -} - -static inline void guAmbientColor(const uint32_t color) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_AMBIENT_COLOR<<24 | (color & 0xFFFFFF); - *gu_list++ = GECMD_AMBIENT_ALPHA<<24 | color>>24; -} - -static inline void guBlendFunc(const int func, const int src, const int dest, - const uint32_t srcfix, const uint32_t destfix) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_BLEND_FUNC<<24 | func<<8 | dest<<4 | src; - if (src == GU_FIX) { - *gu_list++ = GECMD_BLEND_SRCFIX<<24 | srcfix; - } - if (dest == GU_FIX) { - *gu_list++ = GECMD_BLEND_DSTFIX<<24 | destfix; - } -} - -static inline void guCallList(const void * const list) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_ADDRESS_BASE<<24 | ADDRESS_HI(list); - *gu_list++ = GECMD_CALL<<24 | ADDRESS_LO(list); -} - -static inline void guClear(const int mode) -{ - extern uint32_t *gu_list; - extern uint32_t gu_clear_color_stencil; - extern uint16_t gu_clear_depth; - struct {uint32_t color, xy, z;} *vertices; - vertices = guGetMemory(sizeof(*vertices) * 2); - vertices[0].color = 0; - vertices[0].xy = 0; - vertices[0].z = gu_clear_depth; - vertices[1].color = gu_clear_color_stencil; - vertices[1].xy = 480 | 272<<16; - vertices[1].z = 0; - *gu_list++ = GECMD_CLEAR_MODE<<24 | mode<<8 | 1; - *gu_list++ = GECMD_ENA_BLEND<<24 | 0; - *gu_list++ = GECMD_VERTEX_FORMAT<<24 - | GU_TRANSFORM_2D | GU_COLOR_8888 | GU_VERTEX_16BIT; - *gu_list++ = GECMD_ADDRESS_BASE<<24 | ADDRESS_HI(vertices); - *gu_list++ = GECMD_VERTEX_POINTER<<24 | ADDRESS_LO(vertices); - *gu_list++ = GECMD_DRAW_PRIMITIVE<<24 | GU_SPRITES<<16 | 2; - *gu_list++ = GECMD_CLEAR_MODE<<24 | 0; -} - -static inline void guClearColor(const uint32_t color) -{ - extern uint32_t gu_clear_color_stencil; - gu_clear_color_stencil = (gu_clear_color_stencil & 0xFF000000) - | (color & 0x00FFFFFF); -} - -static inline void guClearDepth(const unsigned int depth) -{ - extern uint16_t gu_clear_depth; - gu_clear_depth = depth; -} - -static inline void guClearStencil(const unsigned int stencil) -{ - extern uint32_t gu_clear_color_stencil; - gu_clear_color_stencil = (gu_clear_color_stencil & 0xFFFFFF) | stencil<<24; -} - -static inline void guClutLoad(const int count, const void * const address) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_CLUT_ADDRESS_L<<24 | ADDRESS_LO(address); - *gu_list++ = GECMD_CLUT_ADDRESS_H<<24 | ADDRESS_HI(address); - *gu_list++ = GECMD_CLUT_LOAD<<24 | count; -} - -static inline void guClutMode(const int format, const int shift, - const int mask, const int unknown) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_CLUT_MODE<<24 | format | shift<<2 | mask<<8; -} - -static inline void guCopyImage(const int mode, - const int src_x, const int src_y, - const int src_w, const int src_h, - const int src_stride, - const void * const src_ptr, - const int dest_x, const int dest_y, - const int dest_stride, - const void * const dest_ptr) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_COPY_S_ADDRESS<<24 | ADDRESS_LO(src_ptr); - *gu_list++ = GECMD_COPY_S_STRIDE<<24 | ADDRESS_HI(src_ptr) | src_stride; - *gu_list++ = GECMD_COPY_S_POS<<24 | src_y<<10 | src_x; - *gu_list++ = GECMD_COPY_D_ADDRESS<<24 | ADDRESS_LO(dest_ptr); - *gu_list++ = GECMD_COPY_D_STRIDE<<24 | ADDRESS_HI(dest_ptr) | dest_stride; - *gu_list++ = GECMD_COPY_D_POS<<24 | dest_y<<10 | dest_x; - *gu_list++ = GECMD_COPY_SIZE<<24 | (src_h-1)<<10 | (src_w-1); - *gu_list++ = GECMD_COPY<<24 | (mode==GU_PSM_8888 ? 1 : 0); -} - -static inline void guDepthBuffer(const void * const address, const int stride) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_DEPTH_ADDRESS<<24 | ADDRESS_LO(address); - *gu_list++ = GECMD_DEPTH_STRIDE<<24 | ADDRESS_HI(address) | stride; -} - -static inline void guDepthFunc(const int function) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_DEPTHTEST<<24 | function; -} - -static inline void guDepthMask(const int mask) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_DEPTH_MASK<<24 | mask; -} - -static inline void guDepthRange(const int near, const int far) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_ZSCALE<<24 | trim_float((far - near) / 2.0f); - *gu_list++ = GECMD_ZPOS<<24 | trim_float((far + near) / 2.0f); - *gu_list++ = GECMD_CLIP_NEAR<<24 | (near>24; -} - -static inline void guScissor(const int left, const int top, - const int width, const int height) -{ - extern uint32_t *gu_list; - extern uint32_t gu_scissorcmd_min, gu_scissorcmd_max; - extern uint8_t gu_scissor_enabled; - gu_scissorcmd_min = GECMD_CLIP_MIN<<24 | top<<10 | left; - gu_scissorcmd_max = GECMD_CLIP_MAX<<24 | (top+height-1)<<10 - | (left+width-1); - if (gu_scissor_enabled) { - *gu_list++ = gu_scissorcmd_min; - *gu_list++ = gu_scissorcmd_max; - } -} - -/* - * Note: As with sceGuSetMatrix(), 4x3 matrices are laid out in a 4x4 - * array as follows: - * { {_11, _12, _13, _ignored}, - * {_21, _22, _23, _ignored}, - * {_31, _32, _33, _ignored}, - * {_41, _42, _43, _ignored} } - */ -static inline void guSetMatrix(int type, const float *matrix) -{ - extern uint32_t *gu_list; - if (type == GU_MODEL) { - *gu_list++ = GECMD_MODEL_START<<24; - unsigned int i; - for (i = 0; i < 4; i++) { - unsigned int j; - for (j = 0; j < 3; j++) { - *gu_list++ = GECMD_MODEL_UPLOAD<<24 - | trim_float(matrix[i*4+j]); - } - } - } else if (type == GU_VIEW) { - *gu_list++ = GECMD_VIEW_START<<24; - unsigned int i; - for (i = 0; i < 4; i++) { - unsigned int j; - for (j = 0; j < 3; j++) { - *gu_list++ = GECMD_VIEW_UPLOAD<<24 - | trim_float(matrix[i*4+j]); - } - } - } else if (type == GU_PROJECTION) { - *gu_list++ = GECMD_PROJ_START<<24; - unsigned int i; - for (i = 0; i < 4; i++) { - unsigned int j; - for (j = 0; j < 4; j++) { - *gu_list++ = GECMD_PROJ_UPLOAD<<24 - | trim_float(matrix[i*4+j]); - } - } - } else if (type == GU_TEXTURE) { - *gu_list++ = GECMD_TEXTURE_START<<24; - unsigned int i; - for (i = 0; i < 4; i++) { - unsigned int j; - for (j = 0; j < 3; j++) { - *gu_list++ = GECMD_TEXTURE_UPLOAD<<24 - | trim_float(matrix[i*4+j]); - } - } - } -} - -static inline void guShadeModel(const int mode) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_SHADE_MODE<<24 | mode; -} - -static inline void guStencilFunc(const int func, const int ref, const int mask) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_STENCILTEST<<24 | mask<<16 | ref<<8 | func; -} - -static inline void guStencilOp(const int fail, const int zfail, const int zpass) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_STENCIL_OP<<24 | zpass<<16 | zfail<<8 | fail; -} - -static inline void guTexFilter(const int min, const int mag) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_TEXTURE_FILTER<<24 | mag<<8 | min; -} - -static inline void guTexFlush(void) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_TEXTURE_FLUSH<<24; -} - -static inline void guTexFunc(const int func, const int alpha) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_TEXTURE_FUNC<<24 | alpha<<8 | func; -} - -static inline void guTexImage(const int level, const int width, - const int height, const int stride, - const void * const address) -{ - extern uint32_t *gu_list; - const int log2_width = 31 - __builtin_clz(width); - const int log2_height = 31 - __builtin_clz(height); - *gu_list++ = (GECMD_TEX0_ADDRESS+level)<<24 | ADDRESS_LO(address); - *gu_list++ = (GECMD_TEX0_STRIDE+level)<<24 | ADDRESS_HI(address) | stride; - *gu_list++ = (GECMD_TEX0_SIZE+level)<<24 | log2_height<<8 | log2_width; -} - -static inline void guTexLevelMode(const int mode, const float bias) -{ - extern uint32_t *gu_list; - const int bias_int = (int)(bias*16 + 0.5f) & 0xFF; - *gu_list++ = GECMD_TEXTURE_BIAS<<24 | bias_int<<16 | mode; -} - -static inline void guTexMode(const int format, const int mipmaps, - const int unknown, const int swizzle) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_TEXTURE_MODE<<24 | (mipmaps ? mipmaps-1 : 0) << 16 - | swizzle; - *gu_list++ = GECMD_TEXTURE_PIXFMT<<24 | format; -} - -static inline void guTexSlope(const float slope) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_TEXTURE_SLOPE<<24 | trim_float(slope); -} - -static inline void guTexWrap(const int u_mode, const int v_mode) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_TEXTURE_WRAP<<24 | v_mode<<8 | u_mode; -} - -/* Custom function to set vertex format independently of guDrawArray() */ -static inline void guVertexFormat(const uint32_t format) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_VERTEX_FORMAT<<24 | format; -} - -/* Custom function to set vertex pointer independently of guDrawArray() */ -static inline void guVertexPointer(const void * const address) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_ADDRESS_BASE<<24 | ADDRESS_HI(address); - *gu_list++ = GECMD_VERTEX_POINTER<<24 | ADDRESS_LO(address); -} - -static inline void guViewport(const int cx, const int cy, - const int width, const int height) -{ - extern uint32_t *gu_list; - *gu_list++ = GECMD_XPOS<<24 | trim_float(cx); - *gu_list++ = GECMD_YPOS<<24 | trim_float(cy); - *gu_list++ = GECMD_XSCALE<<24 | trim_float(width/2); - *gu_list++ = GECMD_YSCALE<<24 | trim_float(-height/2); -} - -/*************************************************************************/ - -#undef ADDRESS_HI -#undef ADDRESS_LO - -#ifdef __GNUC__ -# undef inline // Cancel the always_inline definition above -#endif - -#endif // !USE_SCEGU - -/*************************************************************************/ -/************************* sceGu library aliases *************************/ -/*************************************************************************/ - -#ifdef USE_SCEGU - -#define guAlphaFunc(func,value,mask) \ - sceGuAlphaFunc((func), (value), (mask)) -#define guAmbientColor(color) \ - sceGuAmbientColor((color)) -#define guBlendFunc(func,src,dest,srcfix,destfix) \ - sceGuBlendFunc((func), (src), (dest), (srcfix), (destfix)) -#define guCallList(list) \ - sceGuCallList((list)) -#define guClear(mode) \ - sceGuClear((mode)) -#define guClearColor(color) \ - sceGuClearColor((color)) -#define guClearDepth(depth) \ - sceGuClearDepth((depth)) -#define guClearStencil(stencil) \ - sceGuClearStencil((stencil)) -#define guClutLoad(count,address) \ - sceGuClutLoad((count), (address)) -#define guClutMode(format,shift,mask,unknown) \ - sceGuClutMode((format), (shift), (mask), (unknown)) -#define guCopyImage(mode,src_x,src_y,src_w,src_h,src_stride,src_ptr,dest_x,dest_y,dest_stride,dest_ptr) \ - sceGuCopyImage((mode), (src_x), (src_y), (src_w), (src_h), (src_stride), \ - (src_ptr), (dest_x), (dest_y), (dest_stride), (dest_ptr)) -#define guDepthBuffer(address,stride) \ - sceGuDepthBuffer((address), (stride)) -#define guDepthFunc(function) \ - sceGuDepthFunc((function)) -#define guDepthMask(mask) \ - sceGuDepthMask((mask)) -#define guDepthRange(near,far) \ - sceGuDepthRange((near), (far)) -#define guDisable(mode) \ - sceGuDisable((mode)) -#define guDispBuffer(width,height,address,stride) \ - sceGuDispBuffer((width), (height), (address), (stride)) -#define guDrawArray(primitive,vertexfmt,count,indexptr,vertexptr) \ - sceGuDrawArray((primitive), (vertexfmt), (count), (indexptr), (vertexptr)) -#define guDrawBuffer(format,address,stride) \ - sceGuDrawBuffer((format), (address), (stride)) -#define guEnable(mode) \ - sceGuEnable((mode)) -#define guFinish() \ - sceGuFinish() -#define guGetMemory(size) \ - sceGuGetMemory((size)) -#define guInit() \ - sceGuInit() -#define guLogicalOp(op) \ - sceGuLogicalOp((op)) -#define guOffset(xofs,yofs) \ - sceGuOffset((xofs), (yofs)) -#define guPixelMask(mask) \ - sceGuPixelMask((mask)) -#define guScissor(left,top,width,height) \ - sceGuScissor((left), (top), (width), (height)) -#define guSetMatrix(type,matrix) \ - sceGuSetMatrix((type), (const ScePspFMatrix4 *)(matrix)) -#define guShadeModel(mode) \ - sceGuShadeModel((mode)) -#define guStart(type,list) \ - sceGuStart((type), (list)) -#define guStencilFunc(func,ref,mask) \ - sceGuStencilFunc((func), (ref), (mask)) -#define guStencilOp(fail,zfail,zpass) \ - sceGuStencilOp((fail), (zfail), (zpass)) -#define guSync(mode,target) \ - sceGuSync((mode), (target)) -#define guTexFilter(min,mag) \ - sceGuTexFilter((min), (mag)) -#define guTexFlush() \ - sceGuTexFlush() -#define guTexFunc(func,alpha) \ - sceGuTexFunc((func), (alpha)) -#define guTexImage(level,width,height,stride,address) \ - sceGuTexImage((level), (width), (height), (stride), (address)) -#define guTexLevelMode(mode, bias) \ - sceGuTexLevelMode((mode), (bias)) -#define guTexMode(format,mipmaps,unknown,swizzle) \ - sceGuTexMode((format), (mipmaps), (unknown), (swizzle)) -#define guTexSlope(slope) \ - sceGuTexSlope((slope)) -#define guTexWrap(u_mode,v_mode) \ - sceGuTexWrap((u_mode), (v_mode)) -#define guViewport(cx,cy,width,height) \ - sceGuViewport((cx), (cy), (width), (height)) - -/* Custom functions */ -#define guCommit() /* no-op */ -#define guDrawPrimitive(primitive,count) \ - sceGuSendCommandi(GECMD_DRAW_PRIMITIVE, (primitive)<<16 | (count)) -#define guVertexFormat(format) \ - sceGuSendCommandi(GECMD_VERTEX_FORMAT, (format)) -#define guVertexPointer(address) do { \ - const uint32_t __address = (uint32_t)(address); \ - sceGuSendCommandi(GECMD_ADDRESS_BASE, (__address & 0xFF000000) >> 8); \ - sceGuSendCommandi(GECMD_VERTEX_POINTER, __address & 0x00FFFFFF); \ -} while (0) - -#endif // USE_SCEGU - -/*************************************************************************/ -/*************************************************************************/ - -#endif // PSP_GU_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/icache-funcs-2450.patch b/yabause/src/psp/icache-funcs-2450.patch deleted file mode 100644 index d928c52648..0000000000 --- a/yabause/src/psp/icache-funcs-2450.patch +++ /dev/null @@ -1,60 +0,0 @@ -diff -urN a/pspsdk-2450/src/user/Makefile.am b/pspsdk-2450/src/user/Makefile.am ---- a/pspsdk-2450/src/user/Makefile.am 2009-01-09 03:15:40 +0900 -+++ b/pspsdk-2450/src/user/Makefile.am 2009-02-10 16:24:00 +0900 -@@ -24,7 +24,7 @@ - - THREADMAN_OBJS = ThreadManForUser_0000.o ThreadManForUser_0001.o ThreadManForUser_0002.o ThreadManForUser_0003.o ThreadManForUser_0004.o ThreadManForUser_0005.o ThreadManForUser_0006.o ThreadManForUser_0007.o ThreadManForUser_0008.o ThreadManForUser_0009.o ThreadManForUser_0010.o ThreadManForUser_0011.o ThreadManForUser_0012.o ThreadManForUser_0013.o ThreadManForUser_0014.o ThreadManForUser_0015.o ThreadManForUser_0016.o ThreadManForUser_0017.o ThreadManForUser_0018.o ThreadManForUser_0019.o ThreadManForUser_0020.o ThreadManForUser_0021.o ThreadManForUser_0022.o ThreadManForUser_0023.o ThreadManForUser_0024.o ThreadManForUser_0025.o ThreadManForUser_0026.o ThreadManForUser_0027.o ThreadManForUser_0028.o ThreadManForUser_0029.o ThreadManForUser_0030.o ThreadManForUser_0031.o ThreadManForUser_0032.o ThreadManForUser_0033.o ThreadManForUser_0034.o ThreadManForUser_0035.o ThreadManForUser_0036.o ThreadManForUser_0037.o ThreadManForUser_0038.o ThreadManForUser_0039.o ThreadManForUser_0040.o ThreadManForUser_0041.o ThreadManForUser_0042.o ThreadManForUser_0043.o ThreadManForUser_0044.o ThreadManForUser_0045.o ThreadManForUser_0046.o ThreadManForUser_0047.o ThreadManForUser_0048.o ThreadManForUser_0049.o ThreadManForUser_0050.o ThreadManForUser_0051.o ThreadManForUser_0052.o ThreadManForUser_0053.o ThreadManForUser_0054.o ThreadManForUser_0055.o ThreadManForUser_0056.o ThreadManForUser_0057.o ThreadManForUser_0058.o ThreadManForUser_0059.o ThreadManForUser_0060.o ThreadManForUser_0061.o ThreadManForUser_0062.o ThreadManForUser_0063.o ThreadManForUser_0064.o ThreadManForUser_0065.o ThreadManForUser_0066.o ThreadManForUser_0067.o ThreadManForUser_0068.o ThreadManForUser_0069.o ThreadManForUser_0070.o ThreadManForUser_0071.o ThreadManForUser_0072.o ThreadManForUser_0073.o ThreadManForUser_0074.o ThreadManForUser_0075.o ThreadManForUser_0076.o ThreadManForUser_0077.o ThreadManForUser_0078.o ThreadManForUser_0079.o ThreadManForUser_0080.o ThreadManForUser_0081.o ThreadManForUser_0082.o ThreadManForUser_0083.o ThreadManForUser_0084.o ThreadManForUser_0085.o ThreadManForUser_0086.o ThreadManForUser_0087.o ThreadManForUser_0088.o ThreadManForUser_0089.o ThreadManForUser_0090.o ThreadManForUser_0091.o ThreadManForUser_0092.o ThreadManForUser_0093.o ThreadManForUser_0094.o ThreadManForUser_0095.o ThreadManForUser_0096.o ThreadManForUser_0097.o ThreadManForUser_0098.o ThreadManForUser_0099.o ThreadManForUser_0100.o ThreadManForUser_0101.o ThreadManForUser_0102.o ThreadManForUser_0103.o ThreadManForUser_0104.o ThreadManForUser_0105.o ThreadManForUser_0106.o ThreadManForUser_0107.o ThreadManForUser_0108.o ThreadManForUser_0109.o ThreadManForUser_0110.o ThreadManForUser_0111.o ThreadManForUser_0112.o ThreadManForUser_0113.o ThreadManForUser_0114.o ThreadManForUser_0115.o ThreadManForUser_0116.o ThreadManForUser_0117.o ThreadManForUser_0118.o ThreadManForUser_0119.o ThreadManForUser_0120.o ThreadManForUser_0121.o ThreadManForUser_0122.o ThreadManForUser_0123.o ThreadManForUser_0124.o ThreadManForUser_0125.o ThreadManForUser_0126.o - --UTILS_OBJS = UtilsForUser_0000.o UtilsForUser_0001.o UtilsForUser_0002.o UtilsForUser_0003.o UtilsForUser_0004.o UtilsForUser_0005.o UtilsForUser_0006.o UtilsForUser_0007.o UtilsForUser_0008.o UtilsForUser_0009.o UtilsForUser_0010.o UtilsForUser_0011.o UtilsForUser_0012.o UtilsForUser_0013.o UtilsForUser_0014.o UtilsForUser_0015.o UtilsForUser_0016.o UtilsForUser_0017.o UtilsForUser_0018.o UtilsForUser_0019.o UtilsForUser_0020.o UtilsForUser_0021.o UtilsForUser_0022.o UtilsForUser_0023.o UtilsForUser_0024.o -+UTILS_OBJS = UtilsForUser_0000.o UtilsForUser_0001.o UtilsForUser_0002.o UtilsForUser_0003.o UtilsForUser_0004.o UtilsForUser_0005.o UtilsForUser_0006.o UtilsForUser_0007.o UtilsForUser_0008.o UtilsForUser_0009.o UtilsForUser_0010.o UtilsForUser_0011.o UtilsForUser_0012.o UtilsForUser_0013.o UtilsForUser_0014.o UtilsForUser_0015.o UtilsForUser_0016.o UtilsForUser_0017.o UtilsForUser_0018.o UtilsForUser_0019.o UtilsForUser_0020.o UtilsForUser_0021.o UtilsForUser_0022.o UtilsForUser_0023.o UtilsForUser_0024.o UtilsForUser_0025.o UtilsForUser_0026.o - - INTERRUPT_OBJS = InterruptManager_0000.o InterruptManager_0001.o InterruptManager_0002.o InterruptManager_0003.o InterruptManager_0004.o InterruptManager_0005.o InterruptManager_0006.o InterruptManager_0007.o InterruptManager_0008.o InterruptManager_0009.o - -diff -urN a/pspsdk-2450/src/user/UtilsForUser.S b/pspsdk-2450/src/user/UtilsForUser.S ---- a/pspsdk-2450/src/user/UtilsForUser.S 2009-01-09 03:15:40 +0900 -+++ b/pspsdk-2450/src/user/UtilsForUser.S 2009-02-10 16:23:29 +0900 -@@ -77,3 +77,9 @@ - #ifdef F_UtilsForUser_0024 - IMPORT_FUNC "UtilsForUser",0xFB05FAD0,sceKernelIcacheReadTag - #endif -+#ifdef F_UtilsForUser_0025 -+ IMPORT_FUNC "UtilsForUser",0x920F104A,sceKernelIcacheInvalidateAll -+#endif -+#ifdef F_UtilsForUser_0026 -+ IMPORT_FUNC "UtilsForUser",0xC2DF770E,sceKernelIcacheInvalidateRange -+#endif -diff -urN a/pspsdk-2450/src/user/psputils.h b/pspsdk-2450/src/user/psputils.h ---- a/pspsdk-2450/src/user/psputils.h 2009-01-09 03:15:40 +0900 -+++ b/pspsdk-2450/src/user/psputils.h 2009-02-10 16:27:07 +0900 -@@ -58,12 +58,12 @@ - void sceKernelDcacheWritebackInvalidateAll(void); - - /** -- * Write back a range of addresses from data cache to memory -+ * Write back a range of addresses from the data cache to memory - */ - void sceKernelDcacheWritebackRange(const void *p, unsigned int size); - - /** -- * Write back and invalidate a range of addresses in data cache -+ * Write back and invalidate a range of addresses in the data cache - */ - void sceKernelDcacheWritebackInvalidateRange(const void *p, unsigned int size); - -@@ -72,6 +72,16 @@ - */ - void sceKernelDcacheInvalidateRange(const void *p, unsigned int size); - -+/** -+ * Invalidate the instruction cache -+ */ -+void sceKernelIcacheInvalidateAll(void); -+ -+/** -+ * Invalidate a range of addresses in the instruction cache -+ */ -+void sceKernelIcacheInvalidateRange(const void *p, unsigned int size); -+ - /** Structure for holding a mersenne twister context */ - typedef struct _SceKernelUtilsMt19937Context { - unsigned int count; diff --git a/yabause/src/psp/init.c b/yabause/src/psp/init.c deleted file mode 100644 index 92c38ac08c..0000000000 --- a/yabause/src/psp/init.c +++ /dev/null @@ -1,281 +0,0 @@ -/* src/psp/init.c: PSP initialization routines - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" -#include // For struct tm definition - -#include "../cdbase.h" -#include "../cs0.h" -#include "../m68kcore.h" -#include "../peripheral.h" -#include "../scsp.h" -#include "../sh2core.h" -#include "../sh2int.h" -#include "../vidsoft.h" - -#include "config.h" -#include "control.h" -#include "display.h" -#include "init.h" -#include "localtime.h" -#include "menu.h" -#include "sys.h" -#include "psp-cd.h" -#include "psp-m68k.h" -#include "psp-per.h" -#include "psp-sh2.h" -#include "psp-sound.h" -#include "psp-video.h" - -#include "me.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Interface lists */ - -M68K_struct *M68KCoreList[] = { - /* We only support the ME-enabled Q68 interface */ - &M68KPSP, - NULL -}; - -SH2Interface_struct *SH2CoreList[] = { - &SH2Interpreter, - &SH2DebugInterpreter, - &SH2PSP, - NULL -}; - -PerInterface_struct *PERCoreList[] = { - /* We only support the native interface */ - &PERPSP, - NULL -}; - -CDInterface *CDCoreList[] = { - /* We only support the native interface */ - &CDPSP, - NULL -}; - -SoundInterface_struct *SNDCoreList[] = { - /* We only support the native interface */ - &SNDPSP, - NULL -}; - -VideoInterface_struct *VIDCoreList[] = { - &VIDPSP, - &VIDSoft, - NULL -}; - -/*-----------------------------------------------------------------------*/ - -/* Local routine declarations */ - -static void get_base_directory(const char *argv0, char *buffer, int bufsize); - -/*************************************************************************/ -/************************** Interface routines ***************************/ -/*************************************************************************/ - -/** - * init_psp: Perform PSP-related initialization and command-line option - * parsing. Aborts the program if an error occurs. - * - * [Parameters] - * argc: Command line argument count - * argv: Command line argument vector - * [Return value] - * None - */ -void init_psp(int argc, char **argv) -{ - /* Set the CPU to maximum speed, because boy, do we need it */ - scePowerSetClockFrequency(333, 333, 166); - - /* Determine the program's base directory and change to it */ - get_base_directory(argv[0], progpath, sizeof(progpath)); - if (*progpath) { - sceIoChdir(progpath); - } - - /* Start the system callback monitoring thread */ - if (!sys_setup_callbacks()) { - sceKernelExitGame(); - } - - /* Initialize controller input management */ - if (!control_init()) { - DMSG("Failed to initialize controller"); - sceKernelExitGame(); - } - - /* Initialize the display hardware */ - if (!display_init()) { - DMSG("Failed to initialize display"); - sceKernelExitGame(); - } - - /* Initialize localtime() */ - localtime_init(); - - /* Load the ME access library (if possible) */ - int res = sys_load_module("me.prx", PSP_MEMORY_PARTITION_KERNEL); - if (res < 0) { - DMSG("Failed to load me.prx: %s", psp_strerror(res)); - me_available = 0; - } else { - me_available = 1; - } -} - -/*************************************************************************/ - -/** - * init_yabause: Initialize the emulator core. On error, an appropriate - * error message is registered via menu_set_error(). - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on failure - */ -int init_yabause(void) -{ - yabauseinit_struct yinit; - - /* Set a default error message in case the core doesn't set one */ - menu_set_error("Failed to initialize the emulator!"); - - /* Set up general defaults */ - memset(&yinit, 0, sizeof(yinit)); - yinit.m68kcoretype = M68KCORE_PSP; - yinit.percoretype = PERCORE_PSP; - yinit.sh2coretype = config_get_module_sh2(); - yinit.vidcoretype = config_get_module_video(); - yinit.sndcoretype = SNDCORE_PSP; - yinit.cdcoretype = CDCORE_PSP; - yinit.carttype = CART_NONE; - yinit.regionid = 0; - yinit.biospath = config_get_path_bios(); - yinit.cdpath = config_get_path_cd(); - yinit.buppath = config_get_path_bup(); - yinit.mpegpath = NULL; - yinit.cartpath = NULL; - yinit.videoformattype = VIDEOFORMATTYPE_NTSC; - yinit.clocksync = config_get_clock_sync(); - const time_t basetime = 883656000; // 1998-01-01 12:00 UTC - yinit.basetime = config_get_clock_fixed_time() - ? basetime - localtime_utc_offset() - : 0; - yinit.usethreads = 1; - - /* Initialize controller settings */ - PerInit(yinit.percoretype); - PerPortReset(); - padbits = PerPadAdd(&PORTDATA1); - static const struct { - uint8_t key; // Key index from peripheral.h - uint16_t button; // PSP button index (PSP_CTRL_*) - } buttons[] = { - {PERPAD_UP, PSP_CTRL_UP}, - {PERPAD_RIGHT, PSP_CTRL_RIGHT}, - {PERPAD_DOWN, PSP_CTRL_DOWN}, - {PERPAD_LEFT, PSP_CTRL_LEFT}, - {PERPAD_RIGHT_TRIGGER, PSP_CTRL_RTRIGGER}, - {PERPAD_LEFT_TRIGGER, PSP_CTRL_LTRIGGER}, - {PERPAD_START, PSP_CTRL_START}, - }; - int i; - for (i = 0; i < lenof(buttons); i++) { - PerSetKey(buttons[i].button, buttons[i].key, padbits); - } - PerSetKey(config_get_button(CONFIG_BUTTON_A), PERPAD_A, padbits); - PerSetKey(config_get_button(CONFIG_BUTTON_B), PERPAD_B, padbits); - PerSetKey(config_get_button(CONFIG_BUTTON_C), PERPAD_C, padbits); - PerSetKey(config_get_button(CONFIG_BUTTON_X), PERPAD_X, padbits); - PerSetKey(config_get_button(CONFIG_BUTTON_Y), PERPAD_Y, padbits); - PerSetKey(config_get_button(CONFIG_BUTTON_Z), PERPAD_Z, padbits); - - /* Initialize emulator state */ - if (YabauseInit(&yinit) != 0) { - DMSG("YabauseInit() failed!"); - return 0; - } - YabauseSetDecilineMode(config_get_deciline_mode()); - ScspSetFrameAccurate(config_get_audio_sync()); - ScspUnMuteAudio(SCSP_MUTE_SYSTEM); - - /* Success */ - menu_set_error(NULL); - return 1; -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * get_base_directory: Extract the program's base directory from argv[0]. - * Stores the empty string in the destination buffer if the base directory - * cannot be determined. - * - * [Parameters] - * argv0: Value of argv[0] - * buffer: Buffer to store directory path into - * bufsize: Size of buffer - * [Return value] - * None - */ -static void get_base_directory(const char *argv0, char *buffer, int bufsize) -{ - *buffer = 0; - if (argv0) { - const char *s = strrchr(argv0, '/'); - if (s != NULL) { - int n = snprintf(buffer, bufsize, "%.*s", s - argv0, argv0); - if (n >= bufsize) { - DMSG("argv[0] too long: %s", argv0); - *buffer = 0; - } - } else { - DMSG("argv[0] has no directory: %s", argv0); - } - } else { - DMSG("argv[0] is NULL!"); - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/init.h b/yabause/src/psp/init.h deleted file mode 100644 index 5ecf1c47ef..0000000000 --- a/yabause/src/psp/init.h +++ /dev/null @@ -1,60 +0,0 @@ -/* src/psp/init.h: PSP initialization routine header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_INIT_H -#define PSP_INIT_H - -/*************************************************************************/ - -/** - * init_psp: Perform PSP-related initialization and command-line option - * parsing. Aborts the program if an error occurs. - * - * [Parameters] - * argc: Command line argument count - * argv: Command line argument vector - * [Return value] - * None - */ -extern void init_psp(int argc, char **argv); - -/** - * init_yabause: Initialize the emulator core. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on failure - */ -extern int init_yabause(void); - -/*************************************************************************/ - -#endif // PSP_INIT_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/localtime.c b/yabause/src/psp/localtime.c deleted file mode 100644 index b037ac1a0a..0000000000 --- a/yabause/src/psp/localtime.c +++ /dev/null @@ -1,157 +0,0 @@ -/* src/psp/localtime.c: PSP implementation of localtime() - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" -#include // For struct tm definition - -#include "localtime.h" -#include "sys.h" - -/*************************************************************************/ - -/* Time zone offset from UTC (amount to add to time() result) */ -static int32_t utc_offset; - -/*************************************************************************/ -/*************************************************************************/ - -/** - * localtime_init: Perform initialization required for localtime(). - * Called by PSP initialization code at program startup. - * - * [Parameters] - * None - * [Return value] - * None - */ -void localtime_init(void) -{ - /* Find the PSP's time zone */ - int utc_offset_min; - int32_t result = sceUtilityGetSystemParamInt( - PSP_SYSTEMPARAM_ID_INT_TIMEZONE, &utc_offset_min - ); - if (result == 0) { - utc_offset = utc_offset_min * 60; - } else { - DMSG("Failed to get time zone: %s", psp_strerror(result)); - utc_offset = 0; - } - - /* Check whether daylight saving time is in use */ - int dst; - result = sceUtilityGetSystemParamInt( - PSP_SYSTEMPARAM_ID_INT_DAYLIGHTSAVINGS, &dst - ); - if (result == 0) { - if (dst) { - utc_offset += 60*60; - } - } else { - DMSG("Failed to get DST status: %s", psp_strerror(result)); - } - -} - -/*************************************************************************/ - -/** - * localtime_utc_offset: Return the UTC offset of the current time zone in - * seconds (for example, GMT-1 has a UTC offset of -3600 seconds). - * - * [Parameters] - * None - * [Return value] - * UTC offset in seconds - */ -int32_t localtime_utc_offset(void) -{ - return utc_offset; -} - -/*************************************************************************/ - -/** - * internal_localtime_r: Local, reentrant version of localtime() used by - * ../smpc.c. Breaks down a timestamp integer into Y/M/D h:m:s - * representation. - * - * [Parameters] - * timep: Timestamp to break down - * result: Broken-down time - * [Return value] - * result, or NULL on error - */ -struct tm *internal_localtime_r(const time_t *timep, struct tm *result) -{ - static const uint8_t mdays[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; - - PRECOND(timep != NULL, return NULL); - PRECOND(result != NULL, return NULL); - time_t t = *timep + utc_offset; - - /* Weekday is simple: ((days since 1970/1/1) + Thursday) % 7 */ - result->tm_wday = (t/86400 + 4) % 7; - - /* Calculate year */ - result->tm_year = 70; - int32_t yearsecs = 365*86400; - while (t >= yearsecs) { - t -= yearsecs; - result->tm_year++; - /* Careful here -- tm_year starts at 1900, not 0 */ - int isleap = (result->tm_year%4 == 0 - && (result->tm_year%100 != 0 - || result->tm_year%400 == 100)); - yearsecs = isleap ? 366*86400 : 365*86400; - } - - /* Calculate month */ - int month = 0; - while (t >= mdays[month] * 86400) { - t -= mdays[month] * 86400; - month++; - } - result->tm_mon = month; - - /* The rest is straightforward */ - result->tm_sec = t % 60; - t /= 60; - result->tm_min = t % 60; - t /= 60; - result->tm_hour = t % 24; - t /= 24; - result->tm_mday = t + 1; - - return result; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/localtime.h b/yabause/src/psp/localtime.h deleted file mode 100644 index e8bf653a48..0000000000 --- a/yabause/src/psp/localtime.h +++ /dev/null @@ -1,76 +0,0 @@ -/* src/psp/localtime.h: PSP localtime() header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_LOCALTIME_H -#define PSP_LOCALTIME_H - -#include -#include // For struct tm declaration - -/*************************************************************************/ - -/** - * localtime_init: Perform initialization required for localtime(). - * Called by PSP initialization code at program startup. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void localtime_init(void); - -/** - * localtime_utc_offset: Return the UTC offset of the current time zone in - * seconds (for example, GMT-1 has a UTC offset of -3600 seconds). - * - * [Parameters] - * None - * [Return value] - * UTC offset in seconds - */ -extern int32_t localtime_utc_offset(void); - -/** - * internal_localtime_r: Local, reentrant version of localtime() used by - * ../smpc.c. Breaks down a timestamp integer into Y/M/D h:m:s - * representation. - * - * [Parameters] - * timep: Timestamp to break down - * result: Broken-down time - * [Return value] - * result, or NULL on error - */ -extern struct tm *internal_localtime_r(const time_t *timep, struct tm *result); - -/*************************************************************************/ - -#endif // PSP_LOCALTIME_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/main.c b/yabause/src/psp/main.c deleted file mode 100644 index 7e6be65bb1..0000000000 --- a/yabause/src/psp/main.c +++ /dev/null @@ -1,265 +0,0 @@ -/* src/psp/main.c: PSP entry point and main loop - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../memory.h" -#include "../peripheral.h" - -#include "config.h" -#include "control.h" -#include "init.h" -#include "menu.h" -#include "misc.h" -#include "osk.h" -#include "psp-video.h" -#include "timing.h" - -#ifdef SYS_PROFILE_H -# include "profile.h" // Can only be ours -#endif - -/*************************************************************************/ -/************************ PSP module information *************************/ -/*************************************************************************/ - -#define MODULE_FLAGS 0 -#define MODULE_VERSION 0 -#define MODULE_REVISION 9 - -PSP_MODULE_INFO("Yabause", MODULE_FLAGS, MODULE_VERSION, MODULE_REVISION); -const PSP_MAIN_THREAD_PRIORITY(THREADPRI_MAIN); -const PSP_MAIN_THREAD_STACK_SIZE_KB(128); -const PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER); -const PSP_HEAP_SIZE_KB(-64); // Leave 64k for thread stacks - -/*************************************************************************/ -/****************************** Global data ******************************/ -/*************************************************************************/ - -/* Program directory (determined from argv[0], and exported) */ -char progpath[256]; - -/* Saturn control pad handle (set at initialization time, and used by menu - * code to change button assignments) */ -void *padbits; - -/* Flag indicating whether the ME is available for use */ -int me_available; - -/* Have we successfully initialized the Yabause core? */ -int yabause_initted; - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Flag indicating whether the menu is currently displayed */ -static int in_menu; - -/* Delay timer for backup RAM autosave */ -static int bup_autosave_timer; -#define BUP_AUTOSAVE_DELAY 60 // frames - -/* Timer for autosave overlay message */ -static int bup_autosave_info_timer; -#define BUP_AUTOSAVE_INFO_TIME 300 // frames - -/* Text and color for autosave overlay message */ -#define BUP_AUTOSAVE_INFO_TEXT "Backup RAM saved." -#define BUP_AUTOSAVE_INFO_COLOR 0xFF55FF40 // TEXT_COLOR_OK from menu.c - -/*-----------------------------------------------------------------------*/ - -/* Local routine declarations */ - -static void iterate_main_loop(void); -static void emulate_one_frame(void); -static void check_autosave(void); - -/*************************************************************************/ -/************************** Program entry point **************************/ -/*************************************************************************/ - -/** - * main: Program entry point. Performs initialization and then loops - * indefinitely, running the emulator. - * - * [Parameters] - * argc: Command line argument count - * argv: Command line argument vector - * [Return value] - * Does not return - */ -int main(int argc, char **argv) -{ - in_menu = 0; - bup_autosave_timer = 0; - bup_autosave_info_timer = 0; - - init_psp(argc, argv); - config_load(); - if (!config_get_start_in_emu()) { - /* Don't initialize yet -- the user may need to set filenames first. */ - menu_open(); - in_menu = 1; - } else { - if (init_yabause()) { - yabause_initted = 1; - } else { - /* Start in the menu so the user sees the error message. */ - menu_open(); - in_menu = 1; - } - } - - timing_init(); - for (;;) { - iterate_main_loop(); - } -} - -/*************************************************************************/ -/*********** Main loop iteration routine and helper functions ************/ -/*************************************************************************/ - -/** - * iterate_main_loop: Run one iteration of the main loop. Either emulates - * one Saturn frame or runs the menu for one PSP frame. - * - * [Parameters] - * buttons: Current state of PSP control buttons - * [Return value] - * None - */ -static void iterate_main_loop(void) -{ - timing_sync(); - control_update(); - - if (control_new_buttons() & PSP_CTRL_SELECT) { - if (in_menu) { - if (osk_status()) { - /* If the OSK is active, SELECT is used to switch character - * sets, so we shouldn't respond to it. */ - } else if (!yabause_initted && !init_yabause()) { - /* We failed to start the emulator, so stay in the menu. */ - } else { - yabause_initted = 1; // In case we just successfully initted - menu_close(); - in_menu = 0; - } - } else { - menu_open(); - in_menu = 1; - } - } - - if (in_menu) { - menu_run(); - } else { - emulate_one_frame(); - } -} - -/*************************************************************************/ - -/** - * emulate_one_frame: Run the emulator for one frame. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void emulate_one_frame(void) -{ - PERCore->HandleEvents(); // Also runs the actual emulation - - check_autosave(); - - /* Reset the screensaver timeout, so people don't have to deal with - * the backlight dimming during FMV */ - scePowerTick(0); - -#ifdef SYS_PROFILE_H // Print out profiling info every 100 frames - static unsigned int frame = 0; - frame++; - if (frame % 100 == 0) { - printf("Profiling statistics at frame %u:\n", frame); - PROFILE_PRINT(); - PROFILE_RESET(); - } -#endif -} - -/*-----------------------------------------------------------------------*/ - -/** - * check_autosave: Check whether to autosave backup RAM and/or display the - * autosave message. Should be called exactly once per emulated frame. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void check_autosave(void) -{ - if (BupRamWritten) { - /* Wait BUP_AUTOSAVE_DELAY frames from the last write before we - * update the file, so we don't update on every frame while the - * emulated game is saving its data. */ - bup_autosave_timer = BUP_AUTOSAVE_DELAY; - BupRamWritten = 0; - } else if (bup_autosave_timer > 0) { - bup_autosave_timer--; - if (bup_autosave_timer == 0) { - save_backup_ram(); - bup_autosave_info_timer = BUP_AUTOSAVE_INFO_TIME; - } - } - - if (bup_autosave_info_timer > 0) { - uint32_t color; - if (bup_autosave_info_timer >= BUP_AUTOSAVE_INFO_TIME / 2) { - color = BUP_AUTOSAVE_INFO_COLOR; - } else { - const uint32_t alpha = - (255 * bup_autosave_info_timer) / (BUP_AUTOSAVE_INFO_TIME / 2); - color = alpha<<24 | (BUP_AUTOSAVE_INFO_COLOR & 0x00FFFFFF); - } - psp_video_infoline(color, BUP_AUTOSAVE_INFO_TEXT); - bup_autosave_info_timer--; - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/me-sectend.c b/yabause/src/psp/me-sectend.c deleted file mode 100644 index 348897b726..0000000000 --- a/yabause/src/psp/me-sectend.c +++ /dev/null @@ -1,5 +0,0 @@ -// Define section end symbols for ../scsp.c -__attribute__((section(".meshared.scsp.sc_write"), aligned(64))) - volatile char __scsp_sectend_sc_write; -__attribute__((section(".meshared.scsp.me_write"), aligned(64))) - volatile char __scsp_sectend_me_write; diff --git a/yabause/src/psp/me-sectstart.c b/yabause/src/psp/me-sectstart.c deleted file mode 100644 index 13d3232a09..0000000000 --- a/yabause/src/psp/me-sectstart.c +++ /dev/null @@ -1,5 +0,0 @@ -// Define section start symbols for ../scsp.c -__attribute__((section(".meshared.scsp.sc_write"), aligned(64))) - volatile char __scsp_sectstart_sc_write[64]; -__attribute__((section(".meshared.scsp.me_write"), aligned(64))) - volatile char __scsp_sectstart_me_write[64]; diff --git a/yabause/src/psp/me-test.c b/yabause/src/psp/me-test.c deleted file mode 100644 index 2ea1ee3b49..0000000000 --- a/yabause/src/psp/me-test.c +++ /dev/null @@ -1,1468 +0,0 @@ -/* src/psp/me-test.c: Test program for PSP Media Engine access library - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -#include -/* Helpful hint for GCC */ -extern void sceKernelExitGame(void) __attribute__((noreturn)); - -#include "me.h" -#include "me-utility.h" - -/* Macro to get the length of an array */ -#define lenof(a) (sizeof((a)) / sizeof((a)[0])) - -/* Size of the ME's data cache, in bytes */ -#define ME_DCACHE_SIZE (256*64) // 256 cache lines of 64 bytes each - -/*************************************************************************/ -/************************ PSP module information *************************/ -/*************************************************************************/ - -#define MODULE_FLAGS \ - (PSP_MODULE_USER | PSP_MODULE_SINGLE_LOAD | PSP_MODULE_SINGLE_START) -#define MODULE_VERSION 1 -#define MODULE_REVISION 0 - -PSP_MODULE_INFO("me-test", MODULE_FLAGS, MODULE_VERSION, MODULE_REVISION); -const PSP_MAIN_THREAD_PRIORITY(32); -const PSP_MAIN_THREAD_STACK_SIZE_KB(64); -const PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER); -const PSP_HEAP_SIZE_KB(-64); - -/*************************************************************************/ -/******************* Forward declarations of routines ********************/ -/*************************************************************************/ - -static int test_meStart(void); -static int test_meCall(void); -static int test_mePoll(void); -static int test_meWait(void); -static int test_meResult(void); -static int test_meException(void); -static int test_meStop(void); -static int test_restart(void); -static int test_meIsME_SC(void); -static int test_meIsME_ME(void); -static int test_meInterruptWait(void); -static int test_meInterruptPoll(void); -static int test_meInterruptClear(void); -static int test_icache(void); -static int test_icache_inval(void); -static int test_dcache_read(void); -static int test_dcache_write(void); -static int test_dcache_inval(void); -static int test_dcache_wbinv(void); - -static int mefunc_return_123(void *param); -static int mefunc_store_456(void *param); -static int mefunc_delay_and_store_789(void *param); -static int mefunc_count_forever(void *param); -static int mefunc_address_error(void *param); -static int mefunc_return_IsME(void *param); -static int mefunc_send_interrupt(void *param); -static int mefunc_dcache_read(void *param); -static int mefunc_dcache_write(void *param); -static int mefunc_dcache_inval(void *param); -static int mefunc_dcache_wbinv(void *param); - -static __attribute__((always_inline)) void delay(const unsigned int cycles); - -/*************************************************************************/ -/***************************** List of tests *****************************/ -/*************************************************************************/ - -typedef struct TestInfo_ { - /* Name of this test */ - const char * const name; - - /* Name of a previous test which must have passed in order to run this - * test (or NULL if none) */ - const char * const precondition; - - /* Routine implementing test */ - int (* const routine)(void); - - /* Result of test (nonzero = passed, zero = failed or not executed) */ - int passed; -} TestInfo; - -static TestInfo tests[] = { - {"meStart", NULL, test_meStart}, - {"meCall", "meStart", test_meCall}, - {"mePoll", "meStart", test_mePoll}, - {"meWait", "meStart", test_meWait}, - {"meResult", "meWait", test_meResult}, - {"meException", "meWait", test_meException}, - {"meStop", "meResult", test_meStop}, - {"restart", "meStop", test_restart}, - - {"meIsME-SC", "restart", test_meIsME_SC}, - {"meIsME-ME", "meIsME-SC", test_meIsME_ME}, - - {"meInterruptWait", "restart", test_meInterruptWait}, - {"meInterruptPoll", "meInterruptWait", test_meInterruptPoll}, - {"meInterruptClear", "meInterruptPoll", test_meInterruptClear}, - - {"icache", "restart", test_icache}, - {"icache-inval", "restart", test_icache_inval}, - {"dcache-read", "restart", test_dcache_read}, - {"dcache-write", "restart", test_dcache_write}, - {"dcache-inval", "restart", test_dcache_inval}, - {"dcache-wbinv", "restart", test_dcache_wbinv}, -}; - -/*************************************************************************/ -/****************************** Entry point ******************************/ -/*************************************************************************/ - -/** - * main: Program entry point. Calls each of the individual tests and - * reports on their success or failure. - * - * [Parameters] - * None - * [Return value] - * Does not return - */ -int main(void) -{ - /* Don't buffer stdout (since we print partial lines as we test). */ - setbuf(stdout, NULL); - - /* Wait a moment to let PSPlink print its "module started" line before - * we start outputting anything, and output a blank line so the first - * line doesn't follow the PSPlink prompt. */ - sceKernelDelayThread(100000); - printf("\n"); - - /* Load the ME library. */ - SceKernelLMOption lmopts; - memset(&lmopts, 0, sizeof(lmopts)); - lmopts.size = sizeof(lmopts); - lmopts.mpidtext = PSP_MEMORY_PARTITION_KERNEL; - lmopts.mpiddata = PSP_MEMORY_PARTITION_KERNEL; - lmopts.position = 0; - lmopts.access = 1; - SceUID modid = sceKernelLoadModule("me.prx", 0, &lmopts); - if (modid < 0) { - fprintf(stderr, "Failed to load me.prx: %08X\n", modid); - sceKernelExitGame(); - } - int dummy; - int res = sceKernelStartModule(modid, strlen("me.prx")+1, "me.prx", - &dummy, NULL); - if (res < 0) { - fprintf(stderr, "Failed to start me.prx: %08X\n", res); - sceKernelUnloadModule(modid); - sceKernelExitGame(); - } - - /* Run all tests in order. */ - unsigned int num_passed = 0, num_skipped = 0; - unsigned int i; - for (i = 0; i < lenof(tests); i++) { - printf("%s...", tests[i].name); - int can_run = 1; - if (tests[i].precondition) { - unsigned int precond_index; - for (precond_index = 0; precond_index < i; precond_index++) { - if (strcmp(tests[i].precondition, - tests[precond_index].name) == 0) { - break; - } - } - if (precond_index >= i) { - printf("skipped (precondition \"%s\" not found or not yet" - " run)\n", tests[i].precondition); - can_run = 0; - } else if (!tests[precond_index].passed) { - printf("skipped (precondition \"%s\" failed or was skipped)", - tests[i].precondition); - can_run = 0; - } - } - if (can_run) { - tests[i].passed = (*tests[i].routine)(); - if (tests[i].passed) { - num_passed++; - printf("passed\n"); - } else { - printf("FAILED\n"); - } - } else { - num_skipped++; - } - } - - /* Print a summary of all results. */ - printf("\n"); - if (num_passed == lenof(tests)) { - printf("All tests passed.\n"); - } else { - printf("%u/%u tests passed (%u failed, %u skipped).\n", - num_passed, lenof(tests), - lenof(tests) - num_passed - num_skipped, num_skipped); - } - printf("\n"); - - /* All done. */ - sceKernelExitGame(); -} - -/*************************************************************************/ -/***************************** Test routines *****************************/ -/*************************************************************************/ - -/** - * test_meStart: Test that the meStart() function succeeds on both the - * first call and a subsequent call. - * - * If the test passes, the ME has been started and can be used in - * subsequent tests. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meStart(void) -{ - int res; - - if ((res = meStart()) != 0) { - fprintf(stderr, "meStart() #1 failed: %08X\n", res); - return 0; - } - - /* Wait for the ME to become ready (done with a manual delay loop since - * we don't assume that any other library functions work yet). */ - delay(1000000); - - if ((res = meStart()) != 0) { - fprintf(stderr, "meStart() #2 failed: %08X\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_meCall: Test that the meCall() function can be used to execute a - * routine on the ME. - * - * Assumes that test_meStart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meCall(void) -{ - static __attribute__((aligned(64))) int buffer; - volatile int *bufptr = (volatile int *)((uintptr_t)&buffer | 0x40000000); - int res; - - *bufptr = 0; - if ((res = meCall(mefunc_store_456, (void *)bufptr)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - /* Since we don't yet assume meWait() to work properly, delay long - * enough for the function to finish executing before we check whether - * it successfully ran. */ - delay(1000000); - if ((res = *bufptr) != 456) { - fprintf(stderr, "Bad value in buffer (expected 456, got %d)", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_mePoll: Test that the mePoll() function can be used to check - * whether the ME is idle. - * - * Assumes that test_meStart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_mePoll(void) -{ - static __attribute__((aligned(64))) int buffer; - volatile int *bufptr = (volatile int *)((uintptr_t)&buffer | 0x40000000); - int res; - - *bufptr = 0; - if ((res = meCall(mefunc_delay_and_store_789, (void *)bufptr)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - if ((res = *bufptr) != 0) { - fprintf(stderr, "Bad value in buffer (expected 0, got %d)", res); - return 0; - } - - if ((res = mePoll()) != ME_ERROR_BUSY) { - if (res == 0) { - fprintf(stderr, "mePoll() #1 returned idle\n"); - } else { - fprintf(stderr, "mePoll() #1 failed: %08X\n", res); - } - return 0; - } - - delay(2000000); - if ((res = *bufptr) != 789) { - fprintf(stderr, "Bad value in buffer (expected 789, got %d)", res); - return 0; - } - - if ((res = mePoll()) != 0) { - fprintf(stderr, "mePoll() #2 failed: %08X\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_meWait: Test that the meWait() function can be used to wait for - * the ME to become idle. - * - * Assumes that test_meStart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meWait(void) -{ - static __attribute__((aligned(64))) int buffer; - volatile int *bufptr = (volatile int *)((uintptr_t)&buffer | 0x40000000); - int res; - - *bufptr = 0; - if ((res = meCall(mefunc_delay_and_store_789, (void *)bufptr)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - if ((res = *bufptr) != 0) { - fprintf(stderr, "Bad value in buffer (expected 0, got %d)", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #1 failed: %08X\n", res); - return 0; - } - - if ((res = *bufptr) != 789) { - fprintf(stderr, "Bad value in buffer (expected 789, got %d)", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #2 failed: %08X\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_meResult: Test that the meResult() function can be used to - * retrieve the result of a routine executed on the ME. - * - * Assumes that test_meWait() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meResult(void) -{ - int res; - - if ((res = meCall(mefunc_return_123, NULL)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - - if ((res = meResult()) != 123) { - fprintf(stderr, "meResult() gave wrong result (expected 123, got" - " %d)\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_meException: Test that the meException() function can be used to - * retrieve the exception status of a routine executed on the ME. - * - * Assumes that test_meWait() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meException(void) -{ - int res; - - if ((res = meCall(mefunc_return_123, NULL)) != 0) { - fprintf(stderr, "meCall() #1 failed: %08X\n", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #1 failed: %08X\n", res); - return 0; - } - - if ((res = meException()) != 0) { - fprintf(stderr, "meException() #1 gave wrong result (expected 0, got" - " %d)\n", res); - return 0; - } - - if ((res = meCall(mefunc_address_error, NULL)) != 0) { - fprintf(stderr, "meCall() #2 failed: %08X\n", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #2 failed: %08X\n", res); - return 0; - } - - if ((res = meException()) == 0) { - fprintf(stderr, "meException() #2 gave wrong result (expected" - " nonzero, got zero)\n"); - return 0; - } - - uint32_t BadVAddr = 0, Status = 0, Cause = 0, EPC = 0, ErrorEPC = 0; - meExceptionGetData(&BadVAddr, &Status, &Cause, &EPC, &ErrorEPC); - fprintf(stderr, "Exception data:\n"); - fprintf(stderr, " BadVAddr = %08X\n", BadVAddr); - fprintf(stderr, " Status = %08X\n", Status); - fprintf(stderr, " Cause = %08X\n", Cause); - fprintf(stderr, " EPC = %08X\n", EPC); - fprintf(stderr, " ErrorEPC = %08X\n", ErrorEPC); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_meStop: Test that the meStop() function can be used to halt the ME. - * - * Assumes that test_meResult() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meStop(void) -{ - static __attribute__((aligned(64))) int buffer; - volatile int *bufptr = (volatile int *)((uintptr_t)&buffer | 0x40000000); - int res; - - *bufptr = 0; - if ((res = meCall(mefunc_count_forever, (void *)bufptr)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - delay(1000000); // Let the counter run for a bit - - /* Stopping the ME while a function is executing is technically an - * undefined operation, but since all the function does is increment a - * counter, we assume it's safe. */ - meStop(); - - delay(1000000); // The ME should be stopped already, but wait to be sure - - int last_count = *bufptr; - delay(1000000); - if ((res = *bufptr) != last_count) { - fprintf(stderr, "meStop() failed to stop ME (counter changed from" - " %d to %d)", last_count, res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_restart: Test that the ME can be safely stopped and restarted - * using the meStop() and meStart() functions. - * - * Assumes that test_meStop() has passed and the ME is currently stopped. - * If the test passes, the ME has been restarted and can be used in - * subsequent tests. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_restart(void) -{ - int res; - - if ((res = meStart()) != 0) { - fprintf(stderr, "meStart() #1 failed: %08X\n", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #1A failed: %08X\n", res); - return 0; - } - - if ((res = meCall(mefunc_return_123, NULL)) != 0) { - fprintf(stderr, "meCall() #1 failed: %08X\n", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #1B failed: %08X\n", res); - return 0; - } - - if ((res = meResult()) != 123) { - fprintf(stderr, "meResult() #1 gave wrong result (expected 123, got" - " %d)\n", res); - return 0; - } - - meStop(); - delay(1000000); // Wait for the system to settle (just in case) - - if ((res = meStart()) != 0) { - fprintf(stderr, "meStart() #2 failed: %08X\n", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #2A failed: %08X\n", res); - return 0; - } - - if ((res = meCall(mefunc_return_123, NULL)) != 0) { - fprintf(stderr, "meCall() #2 failed: %08X\n", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #2B failed: %08X\n", res); - return 0; - } - - if ((res = meResult()) != 123) { - fprintf(stderr, "meResult() #2 gave wrong result (expected 123, got" - " %d)\n", res); - return 0; - } - - return 1; -} - -/*************************************************************************/ - -/** - * test_meIsME_SC: Test that meUtilityIsME() properly returns zero when - * executing on the SC. - * - * Assumes that test_restart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meIsME_SC(void) -{ - int res = meUtilityIsME(); - - if (res != 0) { - fprintf(stderr, "meUtilityIsME() returned nonzero (%d) on SC\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_meIsME_ME: Test that meUtilityIsME() properly returns nonzero when - * executing on the ME. - * - * Assumes that test_meIsME() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meIsME_ME(void) -{ - int res; - - if ((res = meCall(mefunc_return_IsME, NULL)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - - if ((res = meResult()) == 0) { - fprintf(stderr, "meResult() gave wrong result (expected nonzero," - " got 0)\n"); - return 0; - } - - return 1; -} - -/*************************************************************************/ - -/** - * test_meInterruptWait: Test that meUtilitySendInterrupt() can be used by - * ME code to send an interrupt to the main CPU, and that meInterruptWait() - * can be used to wait until the interrupt is received. - * - * Assumes that test_restart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meInterruptWait(void) -{ - static __attribute__((aligned(64))) int buffer; - volatile int *bufptr = (volatile int *)((uintptr_t)&buffer | 0x40000000); - int res; - - *bufptr = 0; - if ((res = meCall(mefunc_send_interrupt, (void *)bufptr)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - if ((res = *bufptr) != 0) { - fprintf(stderr, "Bad value in buffer (expected 0, got %d)", res); - return 0; - } - - if ((res = meInterruptWait()) != 0) { - fprintf(stderr, "meInterruptWait() failed: %08X\n", res); - return 0; - } - - if ((res = *bufptr) != 654) { - fprintf(stderr, "Bad value in buffer (expected 654, got %d)", res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_meInterruptPoll: Test that meInterruptPoll() can be used to check - * whether an ME interrupt is pending without clearing the interrupt. Also - * check that meInterruptWait() clears the interrupt after waiting for it. - * - * Assumes that test_meInterruptWait() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meInterruptPoll(void) -{ - static __attribute__((aligned(64))) int buffer; - volatile int *bufptr = (volatile int *)((uintptr_t)&buffer | 0x40000000); - int res; - - *bufptr = 0; - if ((res = meCall(mefunc_send_interrupt, (void *)bufptr)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - if ((res = meInterruptPoll()) != ME_ERROR_NO_INTERRUPT) { - fprintf(stderr, "meInterruptPoll() #1 returned bad value (expected" - " %08X, got %08X)\n", ME_ERROR_NO_INTERRUPT, res); - return 0; - } - - delay(2000000); - - if ((res = meInterruptPoll()) != 0) { - fprintf(stderr, "meInterruptPoll() #2 failed: %08X\n", res); - return 0; - } - - if ((res = meInterruptWait()) != 0) { - fprintf(stderr, "meInterruptWait() failed: %08X\n", res); - return 0; - } - - if ((res = meInterruptPoll()) != ME_ERROR_NO_INTERRUPT) { - fprintf(stderr, "meInterruptPoll() #3 returned bad value (expected" - " %08X, got %08X)\n", ME_ERROR_NO_INTERRUPT, res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_meInterruptClear: Test that meInterruptClear() can be used to - * clear a pending ME interrupt. - * - * Assumes that test_meInterruptPoll() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_meInterruptClear(void) -{ - static __attribute__((aligned(64))) int buffer; - volatile int *bufptr = (volatile int *)((uintptr_t)&buffer | 0x40000000); - int res; - - *bufptr = 0; - if ((res = meCall(mefunc_send_interrupt, (void *)bufptr)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - if ((res = meInterruptPoll()) != ME_ERROR_NO_INTERRUPT) { - fprintf(stderr, "meInterruptPoll() #1 returned bad value (expected" - " %08X, got %08X)\n", ME_ERROR_NO_INTERRUPT, res); - return 0; - } - - delay(2000000); - - if ((res = meInterruptPoll()) != 0) { - fprintf(stderr, "meInterruptPoll() #2 failed: %08X\n", res); - return 0; - } - - meInterruptClear(); - - if ((res = meInterruptPoll()) != ME_ERROR_NO_INTERRUPT) { - fprintf(stderr, "meInterruptPoll() #3 returned bad value (expected" - " %08X, got %08X)\n", ME_ERROR_NO_INTERRUPT, res); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - - return 1; -} - -/*************************************************************************/ - -/** - * test_icache: Test that the ME's instruction cache operates as expected. - * - * Assumes that test_restart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_icache(void) -{ - static __attribute__((aligned(64))) uint32_t insn_buf[2]; - volatile uint32_t *insn_ptr = - (volatile uint32_t *)((uintptr_t)&insn_buf[0] | 0x40000000); - int res; - - insn_ptr[0] = 0x03E00008; // jr $ra - insn_ptr[1] = 0x34021234; // li $v0, 0x1234 - - /* Note that we use insn_buf (the cacheable version) rather than - * insn_ptr (the uncacheable one), because we want the ME to cache the - * instructions and therefore _not_ pick up our subsequent change. */ - if ((res = meCall((void *)insn_buf, NULL)) != 0) { - fprintf(stderr, "meCall() #1 failed: %08X\n", res); - return 0; - } - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #1 failed: %08X\n", res); - return 0; - } - if ((res = meResult()) != 0x1234) { - fprintf(stderr, "meResult() #1 gave wrong result (expected 0x1234," - " got 0x%X)\n", res); - return 0; - } - - insn_ptr[1] = 0x34025678; // li $v0, 0x5678 (not seen by ME) - - if ((res = meCall((void *)insn_buf, NULL)) != 0) { - fprintf(stderr, "meCall() #2 failed: %08X\n", res); - return 0; - } - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #2 failed: %08X\n", res); - return 0; - } - if ((res = meResult()) != 0x1234) { - fprintf(stderr, "meResult() #2 gave wrong result (expected 0x1234," - " got 0x%X)\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_icache_inval: Test that meUtilityIcacheInvalidateAll() can be used - * to invalidate the ME's instruction cache. - * - * Assumes that test_restart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_icache_inval(void) -{ - static __attribute__((aligned(64))) uint32_t insn_buf[8]; - volatile uint32_t *insn_ptr = - (volatile uint32_t *)((uintptr_t)insn_buf | 0x40000000); - int res; - - insn_ptr[0] = 0x27BDFFF8; // addiu $sp, $sp, -8 - insn_ptr[1] = 0xAFBF0004; // sw $ra, 4($sp) - insn_ptr[2] = 0x0080F809; // jalr $a0 - insn_ptr[3] = 0x00000000; // nop - insn_ptr[4] = 0x8FBF0004; // lw $ra, 4($sp) - insn_ptr[5] = 0x34024321; // li $v0, 0x4321 - insn_ptr[6] = 0x03E00008; // jr $ra - insn_ptr[7] = 0x27BD0008; // addiu $sp, $sp, 8 - - /* Use mefunc_return_123() as a do-nothing function to take the place of - * meUtilityIcacheInvalidateAll(). */ - if ((res = meCall((void *)insn_buf, mefunc_return_123)) != 0) { - fprintf(stderr, "meCall() #1 failed: %08X\n", res); - return 0; - } - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #1 failed: %08X\n", res); - return 0; - } - if ((res = meResult()) != 0x4321) { - fprintf(stderr, "meResult() #1 gave wrong result (expected 0x4321," - " got 0x%X)\n", res); - return 0; - } - - /* Change the load instruction from the main CPU, but don't flush the - * ME's cache. */ - - insn_ptr[5] = 0x34025432; // li $v0, 0x5432 (not seen by ME) - - if ((res = meCall((void *)insn_buf, mefunc_return_123)) != 0) { - fprintf(stderr, "meCall() #2 failed: %08X\n", res); - return 0; - } - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #2 failed: %08X\n", res); - return 0; - } - if ((res = meResult()) != 0x4321) { - fprintf(stderr, "meResult() #2 gave wrong result (expected 0x4321," - " got 0x%X)\n", res); - return 0; - } - - /* Change the load instruction and flush the ME's cache. */ - - insn_ptr[5] = 0x34026543; // li $v0, 0x6543 - - if ((res = meCall((void *)insn_buf, meUtilityIcacheInvalidateAll)) != 0) { - fprintf(stderr, "meCall() #3 failed: %08X\n", res); - return 0; - } - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #3 failed: %08X\n", res); - return 0; - } - if ((res = meResult()) != 0x6543) { - fprintf(stderr, "meResult() #3 gave wrong result (expected 0x6543," - " got 0x%X)\n", res); - return 0; - } - - /* Test once more to make sure the new instruction is properly cached. */ - - insn_ptr[5] = 0x34027654; // li $v0, 0x7654 (not seen by ME) - - if ((res = meCall((void *)insn_buf, mefunc_return_123)) != 0) { - fprintf(stderr, "meCall() #4 failed: %08X\n", res); - return 0; - } - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() #4 failed: %08X\n", res); - return 0; - } - if ((res = meResult()) != 0x6543) { - fprintf(stderr, "meResult() #4 gave wrong result (expected 0x6543," - " got 0x%X)\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_dcache_read: Test that the ME's data cache operates as expected - * when reading from the cache. - * - * Assumes that test_restart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_dcache_read(void) -{ - static __attribute__((aligned(64))) int buffer[ME_DCACHE_SIZE/4]; - volatile int *bufptr = (volatile int *)((uintptr_t)buffer | 0x40000000); - int res, i; - - for (i = 0; i < lenof(buffer); i++) { - bufptr[i] = 0; - } - - if ((res = meCall(mefunc_dcache_read, buffer)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - /* Wait long enough for the ME to finish reading from the buffer before - * we update it. */ - delay(ME_DCACHE_SIZE*4); // Experimentally determined to be sufficient - for (i = 0; i < lenof(buffer); i++) { - bufptr[i] = 0xFFFFFFFF; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - if ((res = meResult()) != 0) { - fprintf(stderr, "meResult() gave wrong result (expected 0, got %d)\n", - res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_dcache_write: Test that the ME's data cache operates as expected - * when writing to the cache. - * - * Assumes that test_restart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_dcache_write(void) -{ - static __attribute__((aligned(64))) int buffer[ME_DCACHE_SIZE/4]; - volatile int *bufptr = (volatile int *)((uintptr_t)buffer | 0x40000000); - int res, i; - - for (i = 0; i < lenof(buffer); i++) { - bufptr[i] = -1; - } - - if ((res = meCall(mefunc_dcache_write, buffer)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - - /* Wait long enough for the ME to finish writing to the buffer before - * we read from it. We don't use meWait() because allowing the - * function to return will flush some lines from the cache when the - * library updates its internal state. */ - delay(ME_DCACHE_SIZE*4); - - res = -1; - for (i = 0; i < lenof(buffer); i++) { - res &= bufptr[i]; - } - if (res != -1) { - fprintf(stderr, "Bad buffer contents (expected -1, got %d)\n", res); - meWait(); - return 0; - } - - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_dcache_inval: Test that meUtilityDcacheInvalidateAll() can be used - * to invalidate the ME's data cache. - * - * Assumes that test_restart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_dcache_inval(void) -{ - static __attribute__((aligned(64))) int buffer[ME_DCACHE_SIZE/4]; - volatile int *bufptr = (volatile int *)((uintptr_t)buffer | 0x40000000); - int res, i; - - for (i = 0; i < lenof(buffer); i++) { - bufptr[i] = 0xFFFFFFFF; - } - - if ((res = meCall(mefunc_dcache_inval, buffer)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - - res = -1; - for (i = 0; i < lenof(buffer); i++) { - res &= bufptr[i]; - } - if (res != -1) { - fprintf(stderr, "Bad buffer contents (expected -1, got %d)\n", res); - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * test_dcache_wbinv: Test that meUtilityDcacheWritebackInvalidateAll() - * can be used to flush (write back and invalidate) the ME's data cache. - * - * Assumes that test_restart() has passed. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the test passes, zero if it fails - */ -static int test_dcache_wbinv(void) -{ - static __attribute__((aligned(64))) int buffer[ME_DCACHE_SIZE/4]; - volatile int *bufptr = (volatile int *)((uintptr_t)buffer | 0x40000000); - int res, i; - - for (i = 0; i < lenof(buffer); i++) { - bufptr[i] = 0xFFFFFFFF; - } - - if ((res = meCall(mefunc_dcache_wbinv, buffer)) != 0) { - fprintf(stderr, "meCall() failed: %08X\n", res); - return 0; - } - if ((res = meWait()) != 0) { - fprintf(stderr, "meWait() failed: %08X\n", res); - return 0; - } - - res = 0; - for (i = 0; i < lenof(buffer); i++) { - res |= bufptr[i]; - } - if (res != 0) { - fprintf(stderr, "Bad buffer contents (expected 0, got %d)\n", res); - return 0; - } - - - return 1; -} - -/*************************************************************************/ -/********************** Routines executed on the ME **********************/ -/*************************************************************************/ - -/** - * mefunc_return_123: Return 123 to the caller. - * - * [Parameters] - * param: Unused - * [Return value] - * 123 - */ -static int mefunc_return_123(void *param) -{ - return 123; -} - -/*-----------------------------------------------------------------------*/ - -/** - * mefunc_store_456: Store 456 in the location pointed to by the parameter. - * - * [Parameters] - * param: Pointer to an int variable to receive 456. - * [Return value] - * 0 - */ -static int mefunc_store_456(void *param) -{ - *(int *)param = 456; - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * mefunc_delay_and_store_789: Delay for 1M cycles, then Store 789 in the - * location pointed to by the parameter. - * - * [Parameters] - * param: Pointer to an int variable to receive 789 - * [Return value] - * 0 - */ -static int mefunc_delay_and_store_789(void *param) -{ - delay(1000000); - *(int *)param = 789; - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * mefunc_count_forever: Loop indefinitely, continuously incrementing the - * location pointed to by the parameter. - * - * [Parameters] - * param: Pointer to an int variable to be continuously incremented - * [Return value] - * Does not return - */ -static int mefunc_count_forever(void *param) -{ - volatile int *ptr = (volatile int *)param; - for (;;) { - (*ptr)++; - } - return 0; // Not reached, but avoid a compiler warning -} - -/*************************************************************************/ - -/** - * mefunc_address_error: Trigger an address error by accessing an - * unaligned value. - * - * [Parameters] - * param: Unused - * [Return value] - * Does not return - */ -static int mefunc_address_error(void *param) -{ - int dummy = 321; - return *(int *)((uintptr_t)&dummy | 1); -} - -/*************************************************************************/ - -/** - * mefunc_return_IsME(): Return the value returned by meUtilityIsME(). - * - * [Parameters] - * param: Unused - * [Return value] - * Nonzero - */ -static int mefunc_return_IsME(void *param) -{ - return meUtilityIsME(); -} - -/*************************************************************************/ - -/** - * mefunc_send_interrupt: Wait 1M cycles, then store 654 in the location - * pointed to by the parameter and send an interrupt to the main CPU. - * - * [Parameters] - * param: Pointer to an int variable to receive 654 - * [Return value] - * 0 - */ -static int mefunc_send_interrupt(void *param) -{ - delay(1000000); - *(int *)param = 654; - meUtilitySendInterrupt(); - return 0; -} - -/*************************************************************************/ - -/** - * mefunc_dcache_read: Read ME_DCACHE_SIZE/4 words of memory starting at - * the location pointed to by the parameter, wait 1M cycles, then read the - * same words and return their combined bitwise OR. - * - * [Parameters] - * param: Pointer to a buffer of ME_DCACHE_SIZE/4 32-bit words - * [Return value] - * Bitwise OR of all words in buffer - */ -static int mefunc_dcache_read(void *param) -{ - volatile uint32_t *ptr = (volatile uint32_t *)param; - uint32_t res; - int i; - - for (i = 0; i < ME_DCACHE_SIZE/4; i++) { - (void) ptr[i]; - } - - delay(1000000); - - res = 0; - for (i = 0; i < ME_DCACHE_SIZE/4; i++) { - res |= ptr[i]; - } - return res; -} - -/*-----------------------------------------------------------------------*/ - -/** - * mefunc_dcache_write: Write all zeroes to ME_DCACHE_SIZE/4 words of - * memory starting at the location pointed to by the parameter, then wait - * 1M cycles before returning. - * - * [Parameters] - * param: Pointer to a buffer of ME_DCACHE_SIZE/4 32-bit words - * [Return value] - * 0 - */ -static int mefunc_dcache_write(void *param) -{ - volatile uint32_t *ptr = (volatile uint32_t *)param; - int i; - - for (i = 0; i < ME_DCACHE_SIZE/4; i++) { - ptr[i] = 0; - } - - delay(1000000); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * mefunc_dcache_inval: Write all zeroes to ME_DCACHE_SIZE/4 words of - * memory starting at the location pointed to by the parameter, then - * invalidate the data cache (thus nullifying the writes) and return. - * - * [Parameters] - * param: Pointer to a buffer of ME_DCACHE_SIZE/4 32-bit words - * [Return value] - * 0 - */ -static int mefunc_dcache_inval(void *param) -{ - volatile uint32_t *ptr = (volatile uint32_t *)param; - int i; - - /* Normally, we would have to flush the data cache once to ensure that - * values pushed to the stack (like $ra) were properly stored to memory - * before the invalidate call. In this case, however, we completely - * replace the cache set, so any cached stack values will be implicitly - * flushed by the time we're done. */ - - for (i = 0; i < ME_DCACHE_SIZE/4; i++) { - ptr[i] = 0; - } - - meUtilityDcacheInvalidateAll(); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * mefunc_dcache_wbinv: Write all zeroes to ME_DCACHE_SIZE/4 words of - * memory starting at the location pointed to by the parameter, then flush - * the data cache and return. - * - * [Parameters] - * param: Pointer to a buffer of ME_DCACHE_SIZE/4 32-bit words - * [Return value] - * 0 - */ -static int mefunc_dcache_wbinv(void *param) -{ - volatile uint32_t *ptr = (volatile uint32_t *)param; - int i; - - for (i = 0; i < ME_DCACHE_SIZE/4; i++) { - ptr[i] = 0; - } - - meUtilityDcacheWritebackInvalidateAll(); - return 0; -} - -/*************************************************************************/ -/************************ Other utility routines *************************/ -/*************************************************************************/ - -/** - * delay: Delay the calling function for approximately the given number of - * CPU clock cycles. The actual length of the delay may differ from the - * requested length by up to four cycles. - * - * [Parameters] - * cycles: Cycles to delay - * [Return value] - * None - */ -static __attribute__((always_inline)) void delay(const unsigned int cycles) -{ - unsigned int iterations = cycles/4; - asm volatile(" .set push; .set noreorder\n" - "1: bnez %[iterations], 1b\n" - " addiu %[iterations], %[iterations], -1\n" - " .set pop" - : [iterations] "=r" (iterations) - : "0" (iterations) - ); -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/me-utility.c b/yabause/src/psp/me-utility.c deleted file mode 100644 index 8731520ffe..0000000000 --- a/yabause/src/psp/me-utility.c +++ /dev/null @@ -1,136 +0,0 @@ -/* src/psp/me-utility.c: PSP Media Engine utility routines - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include "me.h" -#include "me-utility.h" - -/*************************************************************************/ -/*************************************************************************/ - -/** - * meUtilityIcacheInvalidateAll: Invalidate all entries in the Media - * Engine's instruction cache. - * - * This routine may only be called from code executing on the Media Engine. - * - * [Parameters] - * None - * [Return value] - * None - */ -void meUtilityIcacheInvalidateAll(void) -{ - unsigned int cachesize_bits; - asm volatile("mfc0 %0, $16; ext %0, %0, 9, 3" : "=r" (cachesize_bits)); - const unsigned int cachesize = 4096 << cachesize_bits; - - asm volatile("mtc0 $zero, $28"); // TagLo - asm volatile("mtc0 $zero, $29"); // TagHi - unsigned int i; - for (i = 0; i < cachesize; i += 64) { - asm volatile("cache 0x1, 0(%0)" : : "r" (i)); - asm volatile("cache 0x3, 0(%0)" : : "r" (i)); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * meUtilityDcacheInvalidateAll: Invalidate all entries in the Media - * Engine's data cache. - * - * This routine may only be called from code executing on the Media Engine. - * - * [Parameters] - * None - * [Return value] - * None - */ -void meUtilityDcacheInvalidateAll(void) -{ - unsigned int cachesize_bits; - asm volatile("mfc0 %0, $16; ext %0, %0, 6, 3" : "=r" (cachesize_bits)); - const unsigned int cachesize = 4096 << cachesize_bits; - - asm volatile("mtc0 $zero, $28"); // TagLo - asm volatile("mtc0 $zero, $29"); // TagHi - unsigned int i; - for (i = 0; i < cachesize; i += 64) { - asm volatile("cache 0x11, 0(%0)" : : "r" (i)); - asm volatile("cache 0x13, 0(%0)" : : "r" (i)); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * meUtilityDcacheWritebackInvalidateAll: Write back and then invalidate - * all entries in the Media Engine's data cache. - * - * This routine may only be called from code executing on the Media Engine. - * - * [Parameters] - * None - * [Return value] - * None - */ -void meUtilityDcacheWritebackInvalidateAll(void) -{ - unsigned int cachesize_bits; - asm volatile("mfc0 %0, $16; ext %0, %0, 6, 3" : "=r" (cachesize_bits)); - const unsigned int cachesize = 4096 << cachesize_bits; - - unsigned int i; - for (i = 0; i < cachesize; i += 64) { - asm volatile("cache 0x14, 0(%0)" : : "r" (i)); - } - asm volatile("sync"); -} - -/*************************************************************************/ - -/** - * meUtilitySendInterrupt: Send an interrupt to the main CPU. - * - * [Parameters] - * None - * [Return value] - * None - */ -void meUtilitySendInterrupt(void) -{ - asm volatile("sync"); - asm volatile("sw %0, 0x44(%1)" : : "r" (1), "r" (0xBC100000)); - asm volatile("sync"); -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/me-utility.h b/yabause/src/psp/me-utility.h deleted file mode 100644 index 460f0a60d6..0000000000 --- a/yabause/src/psp/me-utility.h +++ /dev/null @@ -1,105 +0,0 @@ -/* src/psp/me-utility.h: PSP Media Engine utility routine header - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef ME_UTILITY_H -#define ME_UTILITY_H - -/*************************************************************************/ - -/** - * meUtilityIsME: Return whether the current CPU is the ME (nonzero) or - * the SC (zero). - * - * [Parameters] - * None - * [Return value] - * Nonzero if executing on the ME, zero if executing on the SC - */ -static inline int meUtilityIsME(void) -{ - int test; - asm("xor %0, $k0, %1" : "=r" (test) : "r" (ME_K0_MAGIC)); - return test == 0; -} - -/*----------------------------------*/ - -/** - * meUtilityIcacheInvalidateAll: Invalidate all entries in the Media - * Engine's instruction cache. - * - * This routine may only be called from code executing on the Media Engine. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void meUtilityIcacheInvalidateAll(void); - -/** - * meUtilityDcacheInvalidateAll: Invalidate all entries in the Media - * Engine's data cache. - * - * This routine may only be called from code executing on the Media Engine. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void meUtilityDcacheInvalidateAll(void); - -/** - * meUtilityDcacheWritebackInvalidateAll: Write back and then invalidate - * all entries in the Media Engine's data cache. - * - * This routine may only be called from code executing on the Media Engine. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void meUtilityDcacheWritebackInvalidateAll(void); - -/** - * meUtilitySendInterrupt: Send an interrupt to the main CPU. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void meUtilitySendInterrupt(void); - -/*************************************************************************/ - -#endif // ME_UTILITY_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/me.c b/yabause/src/psp/me.c deleted file mode 100644 index df81d811e3..0000000000 --- a/yabause/src/psp/me.c +++ /dev/null @@ -1,936 +0,0 @@ -/* src/psp/me.c: PSP Media Engine access library - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* - * This library provides simple, low-level access to the Media Engine CPU. - * Typical usage is as follows (error checks are omitted): - * - * init() { - * meStart(); - * } - * - * main() { - * meCall(function, parameter); - * meWait(); // or use mePoll() in a loop - * if (meException()) { - * // An exception (address error, etc.) occurred - * } else { - * result = meResult(); - * } - * } - * - * Code running on the Media Engine cannot call any external library - * functions which are gated through the syscall interface (which naturally - * includes all firmware functions). However, a few utility functions are - * available in me-utility.[ch] for operations such as cache management. - * - * This library trusts the caller completely, and runs code on the ME in - * kernel mode. Callers must therefore be careful about errors in the - * functions they execute, since improper writes to hardware registers - * could destroy flash or Memory Stick data or have other catastrophic - * results. - * - * Naturally, this library cannot be used alongside any firmware functions - * which make use of the ME, such as audio or video decoding. It is also - * currently impossible to suspend the PSP with the power switch after - * calling meStart(), even if meStop() is later called to halt ME - * processing. (Further investigation is needed to determine why this - * occurs.) - */ - -#include -extern int sceSysregAvcResetEnable(void); // Missing from pspsysreg.h - -#include "me.h" - -/*************************************************************************/ -/************************ PSP module information *************************/ -/*************************************************************************/ - -#define MODULE_FLAGS \ - (PSP_MODULE_KERNEL | PSP_MODULE_SINGLE_LOAD | PSP_MODULE_SINGLE_START) -#define MODULE_VERSION 1 -#define MODULE_REVISION 1 - -PSP_MODULE_INFO("melib", MODULE_FLAGS, MODULE_VERSION, MODULE_REVISION); - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Local function declarations */ - -static void maybe_raise_exception(void); - -static int interrupt_handler(void); - -extern void me_init, me_init_end; -__attribute__((section(".text.me"), noreturn)) void me_loop(void); -__attribute__((section(".text.me"), noreturn)) void me_exception_finish(void); - -/*************************************************************************/ - -/* Has the ME been started? */ - -static int me_started; - -/* Should ME exceptions be fatal to the caller? */ - -static int exceptions_are_fatal; - -/*----------------------------------*/ - -/* Message block for signaling between the main CPU and Media Engine */ - -typedef struct MEMessageBlock_ { - /* ME idle flag; nonzero indicates that the Media Engine is idle and - * ready to accept a new execute request. Set only by the ME; cleared - * only by the main CPU. */ - int idle; - - /* Execute request flag; nonzero indicates that the execute request - * fields below have been filled in and the ME should start executing - * the given function. Set only by the main CPU; cleared only by the - * ME (except when cleared by the main CPU before starting the ME). */ - int request; - - /* Function to be executed. Written only by the main CPU. */ - int (*function)(void *); - - /* Argument to be passed to function. Written only by the main CPU. */ - void *argument; - - /* Return value of last function executed. Written only by the ME. */ - int result; - - /* Exception flag; nonzero indicates that the last function executed on - * the ME triggered an exception. Set only by the ME; cleared only by - * the main CPU. */ - int exception; -} MEMessageBlock; - -static volatile __attribute__((aligned(64))) - MEMessageBlock message_block_buffer; - -/*----------------------------------*/ - -/* Buffer for storing registers on an ME exception (buffer size must be a - * multiple of the cache line size) */ - -typedef struct MEExceptionRegs_ { - uint32_t r[32]; - uint32_t hi, lo; - uint32_t BadVAddr; - uint32_t Status; - uint32_t Cause; - uint32_t EPC; - uint32_t ErrorEPC; - uint32_t pad[9]; -} MEExceptionRegs; - -static __attribute__((aligned(64),used)) MEExceptionRegs exception_registers; - -/*----------------------------------*/ - -/* Event flag used for catching ME interrupts */ - -static SceUID interrupt_flag; - -/*************************************************************************/ -/************************** Module entry points **************************/ -/*************************************************************************/ - -/** - * module_start: Entry point called when the module is started. - * - * [Parameters] - * None - * [Return value] - * Zero on success, otherwise an error code (negative) - */ -extern int module_start(void); -int module_start(void) -{ - /* Create an event flag for receiving interrupts from the ME. */ - interrupt_flag = sceKernelCreateEventFlag("meInterruptFlag", - PSP_EVENT_WAITMULTIPLE, 0, 0); - if (interrupt_flag < 0) { - return interrupt_flag; - } - - /* Install our interrupt handler (overwriting any handler installed - * by the firmware). */ - sceKernelReleaseIntrHandler(31); - int res = - sceKernelRegisterIntrHandler(31, 2, interrupt_handler, NULL, NULL); - if (res < 0) { - sceKernelDeleteEventFlag(interrupt_flag); - interrupt_flag = 0; - return res; - } - sceKernelEnableIntr(31); - - return 0; -} - -/*************************************************************************/ - -/** - * module_stop: Entry point called when the module is stopped. - * - * [Parameters] - * None - * [Return value] - * Zero on success, otherwise an error code (negative) - */ -extern int module_stop(void); -int module_stop(void) -{ - if (me_started) { - meStop(); - } - - sceKernelDisableIntr(31); - sceKernelReleaseIntrHandler(31); - - sceKernelDeleteEventFlag(interrupt_flag); - interrupt_flag = 0; - - return 0; -} - -/*************************************************************************/ -/************************** Interface routines ***************************/ -/*************************************************************************/ - -/** - * meStart: Start up the Media Engine. This function must be called - * before any other Media Engine operations are performed. - * - * [Parameters] - * None - * [Return value] - * Zero on success, otherwise an error code (negative) - */ -int meStart(void) -{ - uint32_t old_k1; - asm volatile("move %0, $k1; move $k1, $zero" : "=r" (old_k1)); - - if (me_started) { - asm volatile("move $k1, %0" : : "r" (old_k1)); - return 0; - } - - /* We generate this pointer on the fly rather than storing it in a - * static variable because attempting to access that static variable - * would pull in the cache line, which is exactly what we're trying - * to avoid. */ - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - - message_block->idle = 0; - message_block->request = 0; - meInterruptClear(); - - /* Roll our own memcpy() to avoid an unneeded libc reference. */ - const uint32_t *src = (const uint32_t *)&me_init; - const uint32_t *src_top = (const uint32_t *)&me_init_end; - uint32_t *dest = (uint32_t *)0xBFC00040; - for (; src < src_top; src++, dest++) { - *dest = *src; - } - - /* Flush the data cache, just to be safe. */ - sceKernelDcacheWritebackInvalidateAll(); - - int res; - if ((res = sceSysregMeResetEnable()) < 0 - || (res = sceSysregMeBusClockEnable()) < 0 - || (res = sceSysregMeResetDisable()) < 0 - ) { - asm volatile("move $k1, %0" : : "r" (old_k1)); - return res; - } - - me_started = 1; - - asm volatile("move $k1, %0" : : "r" (old_k1)); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * meStop: Stop the Media Engine. No other Media Engine functions except - * meStart() may be called after this function returns. - * - * If code is currently executing on the Media Engine when this function is - * called, the effect on system state is undefined. - * - * [Parameters] - * None - * [Return value] - * None - */ -void meStop(void) -{ - uint32_t old_k1; - asm volatile("move %0, $k1; move $k1, $zero" : "=r" (old_k1)); - - sceSysregVmeResetEnable(); - sceSysregAvcResetEnable(); - sceSysregMeResetEnable(); - sceSysregMeBusClockDisable(); - - me_started = 0; - - asm volatile("move $k1, %0" : : "r" (old_k1)); -} - -/*************************************************************************/ - -/** - * meCall: Begin executing the given function on the Media Engine. The - * function must not call any firmware functions, whether directly or - * indirectly. This routine may only be called when the Media Engine is - * idle (i.e., when mePoll() returns zero). - * - * [Parameters] - * function: Function pointer - * argument: Optional argument to function - * [Return value] - * Zero on success, otherwise an error code (negative) - */ -int meCall(int (*function)(void *), void *argument) -{ - if (!me_started) { - return ME_ERROR_NOT_STARTED; - } - - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - - if (!message_block->idle || message_block->request) { - return ME_ERROR_BUSY; - } - - message_block->exception = 0; - message_block->function = function; - message_block->argument = argument; - message_block->request = 1; - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * mePoll: Check whether the Media Engine is idle. - * - * [Parameters] - * None - * [Return value] - * Zero if the Media Engine is idle, otherwise an error code (negative) - */ -int mePoll(void) -{ - if (!me_started) { - return ME_ERROR_NOT_STARTED; - } - - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - - if (!message_block->idle || message_block->request) { - return ME_ERROR_BUSY; - } - maybe_raise_exception(); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * meWait: Wait for the Media Engine to become idle. - * - * [Parameters] - * None - * [Return value] - * Zero if the Media Engine has become (or was already) idle, - * otherwise an error code (negative) - */ -int meWait(void) -{ - if (!me_started) { - return ME_ERROR_NOT_STARTED; - } - - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - - while (!message_block->idle || message_block->request) { /*spin*/ } - maybe_raise_exception(); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * meResult: Return the result (return value) of the most recently - * executed function. The result is undefined if the Media Engine has not - * been started or is not idle, if the most recently executed function did - * not return a result (i.e. had a return type of void), or if the most - * recently executed function triggered an exception. - * - * [Parameters] - * None - * [Return value] - * Result of the most recently executed function - */ -int meResult(void) -{ - if (!me_started) { - return ME_ERROR_NOT_STARTED; - } - - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - - return message_block->result; -} - -/*************************************************************************/ - -/** - * meException: Return whether the most recently executed function - * triggered an exception. The result is undefined if the Media Engine has - * not been started or is not idle. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the most recently executed function triggered an - * exception, else zero - */ -int meException(void) -{ - if (!me_started) { - return ME_ERROR_NOT_STARTED; - } - - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - - return message_block->exception; -} - -/*-----------------------------------------------------------------------*/ - -/** - * meExceptionGetData: Retrieve CPU status register values related to the - * most recent exception. The values retrieved are undefined in any case - * where meException() returns zero or has an undefined return value. - * - * NULL can be passed for any unneeded register values. - * - * [Parameters] - * BadVAddr_ret: Pointer to variable to receive BadVAddr register value - * Status_ret: Pointer to variable to receive Status register value - * Cause_ret: Pointer to variable to receive Cause register value - * EPC_ret: Pointer to variable to receive EPC register value - * ErrorEPC_ret: Pointer to variable to receive ErrorEPC register value - * [Return value] - * None - */ -void meExceptionGetData(uint32_t *BadVAddr_ret, uint32_t *Status_ret, - uint32_t *Cause_ret, uint32_t *EPC_ret, - uint32_t *ErrorEPC_ret) -{ - if (!me_started) { - return; - } - - if (BadVAddr_ret) { - *BadVAddr_ret = exception_registers.BadVAddr; - } - if (Status_ret) { - *Status_ret = exception_registers.Status; - } - if (Cause_ret) { - *Cause_ret = exception_registers.Cause; - } - if (EPC_ret) { - *EPC_ret = exception_registers.EPC; - } - if (ErrorEPC_ret) { - *ErrorEPC_ret = exception_registers.ErrorEPC; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * meExceptionSetFatal: Set whether an exception on the Media Engine - * should automatically trigger an exception on the main CPU. If enabled, - * any call to mePoll() or meWait() when an exception is pending will cause - * an address error exception to be generated on the main CPU, with - * exception status information stored in a buffer pointed to by $gp: - * 0($gp) = Status - * 4($gp) = Cause - * 8($gp)= EPC or ErrorEPC (depending on the exception type) - * 12($gp) = BadVAddr - * 16($gp) = Media Engine's $sp - * 20($gp) = Media Engine's $gp - * All general-purpose registers other than $sp and $gp, as well as $hi and - * $lo, are copied from the Media Engine. - * - * Unlike other functions in this library, this function can be called even - * when the ME is not running, and it will always succeed. - * - * By default, exceptions are not fatal. - * - * [Parameters] - * fatal: Nonzero to make exceptions fatal, zero to make them nonfatal - * [Return value] - * None - */ -void meExceptionSetFatal(int fatal) -{ - exceptions_are_fatal = (fatal != 0); -} - -/*************************************************************************/ - -/** - * meInterruptPoll: Return whether an interrupt from the Media Engine is - * pending. Any pending interrupt is _not_ cleared. - * - * [Parameters] - * None - * [Return value] - * Zero if an interrupt from the Media Engine is pending, otherwise an - * error code (negative) - */ -int meInterruptPoll(void) -{ - if (!me_started) { - return ME_ERROR_NOT_STARTED; - } - - uint32_t old_k1; - asm volatile("move %0, $k1; move $k1, $zero" : "=r" (old_k1)); - int res = sceKernelPollEventFlag(interrupt_flag, 1, 0, NULL); - asm volatile("move $k1, %0" : : "r" (old_k1)); - - if (res == SCE_KERNEL_ERROR_EVF_COND) { - return ME_ERROR_NO_INTERRUPT; - } else if (res < 0) { - return res; - } - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * meInterruptWait: Wait for an interrupt from the Media Engine if none is - * already pending, then clear the interrupt and return. - * - * [Parameters] - * None - * [Return value] - * Zero if an interrupt was received from the Media Engine, otherwise - * an error code (negative) - */ -int meInterruptWait(void) -{ - if (!me_started) { - return ME_ERROR_NOT_STARTED; - } - - uint32_t old_k1; - asm volatile("move %0, $k1; move $k1, $zero" : "=r" (old_k1)); - int res = sceKernelWaitEventFlag(interrupt_flag, 1, - PSP_EVENT_WAITCLEAR, NULL, NULL); - asm volatile("move $k1, %0" : : "r" (old_k1)); - - if (res < 0) { - return res; - } - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * meInterruptClear: Clear any pending Media Engine interrupt. - * - * [Parameters] - * None - * [Return value] - * None - */ -void meInterruptClear(void) -{ - uint32_t old_k1; - asm volatile("move %0, $k1; move $k1, $zero" : "=r" (old_k1)); - /* This function is slightly misnamed--it doesn't clear the bits - * specified by the second parameter, but simply performs a bitwise - * AND between the current flag value and the second parameter. */ - sceKernelClearEventFlag(interrupt_flag, 0); - asm volatile("move $k1, %0" : : "r" (old_k1)); -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * maybe_raise_exception: If fatal exceptions have been requested via - * meExceptionSetFatal() and an ME exception is pending, load registers as - * described in the meExceptionSetFatal() documentation and generate an - * address error exception. - * - * Assumes that the ME is currently idle. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void maybe_raise_exception(void) -{ - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - static uint32_t exception_info[6]; - - if (exceptions_are_fatal && message_block->exception) { - asm volatile(".set push; .set noreorder; .set noat\n" - "move $at, %[exception_registers]\n" - "move $gp, %[exception_info]\n" - "lw $t8, %[Status]($at)\n" - "lw $t9, %[Cause]($at)\n" - "lw $k0, %[EPC]($at)\n" - "andi $v0, $t8, 4\n" - "bnezl $v0, 1f\n" - "lw $k0, %[ErrorEPC]($at)\n" - "1:\n" - "lw $k1, %[BadVAddr]($at)\n" - "lw $v0, 120($at)\n" - "lw $v1, 116($at)\n" - "sw $t8, 0($gp)\n" - "sw $t9, 4($gp)\n" - "sw $k0, 8($gp)\n" - "sw $k1, 12($gp)\n" - "sw $v0, 16($gp)\n" - "sw $v1, 20($gp)\n" - "lw $v0, 128($at)\n" - "lw $v1, 132($at)\n" - "mthi $v0\n" - "mtlo $v1\n" - "lw $v0, 8($at)\n" - "lw $v1, 12($at)\n" - "lw $a0, 16($at)\n" - "lw $a1, 20($at)\n" - "lw $a2, 24($at)\n" - "lw $a3, 28($at)\n" - "lw $t0, 32($at)\n" - "lw $t1, 36($at)\n" - "lw $t2, 40($at)\n" - "lw $t3, 44($at)\n" - "lw $t4, 48($at)\n" - "lw $t5, 52($at)\n" - "lw $t6, 56($at)\n" - "lw $t7, 60($at)\n" - "lw $s0, 64($at)\n" - "lw $s1, 68($at)\n" - "lw $s2, 72($at)\n" - "lw $s3, 76($at)\n" - "lw $s4, 80($at)\n" - "lw $s5, 84($at)\n" - "lw $s6, 88($at)\n" - "lw $s7, 92($at)\n" - "lw $t8, 96($at)\n" - "lw $t9, 100($at)\n" - "lw $k0, 104($at)\n" - "lw $k1, 108($at)\n" - "lw $fp, 120($at)\n" - "lw $ra, 124($at)\n" - "lw $at, 4($at)\n" - "sw $zero, -16162($zero)\n" - ".set pop" - : "=m" (exception_info) - : [exception_info] "r" (&exception_info), - [exception_registers] "r" (&exception_registers), - "m" (exception_registers), - [Status] "i" (offsetof(MEExceptionRegs,Status)), - [Cause] "i" (offsetof(MEExceptionRegs,Cause)), - [BadVAddr] "i" (offsetof(MEExceptionRegs,BadVAddr)), - [EPC] "i" (offsetof(MEExceptionRegs,EPC)), - [ErrorEPC] "i" (offsetof(MEExceptionRegs,ErrorEPC)) - ); - } -} - -/*************************************************************************/ - -/** - * interrupt_handler: Handler for Media Engine interrupts. - * - * [Parameters] - * None - * [Return value] - * Always -1 - */ -static int interrupt_handler(void) -{ - sceKernelSetEventFlag(interrupt_flag, 1); - return -1; -} - -/*************************************************************************/ - -/** - * me_init: Initialization code for the Media Engine. Copied to - * 0xBFC00040 in shared memory space. - */ -asm("\ - .set push; .set noreorder \n\ - \n\ - .globl me_init \n\ - .type me_init, @function \n\ -me_init: \n\ - \n\ - # Set up hardware registers. \n\ - li $k0, 0xBC100000 \n\ - li $v0, 7 \n\ - sw $v0, 0x50($k0) # Enable bus clock \n\ - li $v0, -1 \n\ - sw $v0, 0x04($k0) # Clear pending interrupts \n\ - li $v0, 2 # Assume 64MB for now (watch your pointers!) \n\ - sw $v0, 0x40($k0) # Set memory size \n\ - \n\ - # Clear the caches \n\ - mtc0 $zero, $28 # TagLo \n\ - mtc0 $zero, $29 # TagHi \n\ - mfc0 $v1, $16 # Config \n\ - ext $v0, $v1, 9, 3 # Instruction cache size \n\ - li $a0, 2048 \n\ - sllv $a0, $a0, $v0 \n\ - ext $v0, $v1, 6, 3 # Data cache size \n\ - li $a1, 2048 \n\ - sllv $a1, $a1, $v0 \n\ -1: addiu $a0, $a0, -64 \n\ - bnez $a0, 1b \n\ - cache 0x01, 0($a0) # Shouldn't this be 0x00? \n\ -1: addiu $a1, $a1, -64 \n\ - bnez $a1, 1b \n\ - cache 0x11, 0($a1) \n\ - \n\ - # Enable the FPU (COP1) and clear the interrupt-pending flag. \n\ - li $v0, 0x20000000 \n\ - mtc0 $v0, $12 # Status \n\ - mtc0 $zero, $13 # Cause \n\ - \n\ - # Wait for the hardware to become ready. \n\ - li $k0, 0xBCC00000 \n\ - li $v0, 1 \n\ - sw $v0, 0x10($k0) \n\ -1: lw $v0, 0x10($k0) \n\ - andi $v0, $v0, 1 \n\ - bnez $v0, 1b \n\ - nop \n\ - \n\ - # Set up more hardware registers. \n\ - li $v0, 1 \n\ - sw $v0, 0x70($k0) \n\ - li $v0, 8 \n\ - sw $v0, 0x30($k0) \n\ - li $v0, 2 # Assume 64MB for now (watch your pointers!) \n\ - sw $v0, 0x40($k0) \n\ - sync \n\ - \n\ - # Start the internal clock counter running, in case someone \n\ - # wants to access it. (No Compare interrupts will be generated \n\ - # by default, since Status.IM[7] is cleared above.) \n\ - mtc0 $zero, $9 # Count \n\ - \n\ - # Set the exception handler address. \n\ - lui $v0, %hi(me_exception) \n\ - addiu $v0, %lo(me_exception) \n\ - mtc0 $v0, $25 \n\ - \n\ - # Initialize the stack pointer and call the main loop. \n\ - li $sp, 0x80200000 \n\ - lui $ra, %hi(me_loop) \n\ - addiu $ra, %lo(me_loop) \n\ - jr $ra \n\ - nop \n\ - \n\ - .globl me_init_end \n\ -me_init_end: \n\ - \n\ - .set pop \n\ -"); - -/*-----------------------------------------------------------------------*/ - -/** - * me_loop: Media Engine main loop. Infinitely repeats the cycle of - * waiting for an execute request from the main CPU, then executing the - * requested function. - * - * [Parameters] - * None - * [Return value] - * Does not return - * [Notes] - * This is not declared "static" because the address must be referenced - * by the assembly code in me_init(). - */ -__attribute__((section(".text.me"), noreturn)) void me_loop(void) -{ - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - - asm("move $k0, %0" : : "r" (ME_K0_MAGIC)); - - for (;;) { - message_block->idle = 1; - while (!message_block->request) { /*spin*/ } - message_block->idle = 0; - int (*function)(void *) = message_block->function; - void *argument = message_block->argument; - message_block->request = 0; - message_block->result = (*function)(argument); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * me_exception: Media Engine exception handler. Stores exception data in - * the local buffer, then clears the ME stack and restarts the main loop. - */ -asm("\ - .set push; .set noreorder; .set noat \n\ - .pushsection .text.me,\"ax\",@progbits \n\ - .balign 64 \n\ - \n\ - .globl me_exception \n\ - .type me_exception, @function \n\ -me_exception: \n\ - \n\ - # Save $v0 and $v1 so we have some work registers available. \n\ - ctc0 $v0, $4 \n\ - ctc0 $v1, $5 \n\ - \n\ - # Save all registers to the exception register buffer. \n\ - lui $v1, %hi(exception_registers) \n\ - addiu $v1, %lo(exception_registers) \n\ - cache 0x18, 0($v1) \n\ - cache 0x18, 64($v1) \n\ - cache 0x18, 128($v1) \n\ - sw $zero, 0($v1) \n\ - sw $at, 4($v1) \n\ - sw $v0, 8($v1) \n\ - cfc0 $v0, $5 \n\ - sw $v0, 12($v1) \n\ - sw $a0, 16($v1) \n\ - sw $a1, 20($v1) \n\ - sw $a2, 24($v1) \n\ - sw $a3, 28($v1) \n\ - sw $t0, 32($v1) \n\ - sw $t1, 36($v1) \n\ - sw $t2, 40($v1) \n\ - sw $t3, 44($v1) \n\ - sw $t4, 48($v1) \n\ - sw $t5, 52($v1) \n\ - sw $t6, 56($v1) \n\ - sw $t7, 60($v1) \n\ - sw $s0, 64($v1) \n\ - sw $s1, 68($v1) \n\ - sw $s2, 72($v1) \n\ - sw $s3, 76($v1) \n\ - sw $s4, 80($v1) \n\ - sw $s5, 84($v1) \n\ - sw $s6, 88($v1) \n\ - sw $s7, 92($v1) \n\ - sw $t8, 96($v1) \n\ - sw $t9, 100($v1) \n\ - sw $k0, 104($v1) \n\ - sw $k1, 108($v1) \n\ - sw $gp, 112($v1) \n\ - sw $sp, 116($v1) \n\ - sw $fp, 120($v1) \n\ - sw $ra, 124($v1) \n\ - mfhi $v0 \n\ - sw $v0, 128($v1) \n\ - mflo $v0 \n\ - sw $v0, 132($v1) \n\ - mfc0 $v0, $8 \n\ - sw $v0, 136($v1) \n\ - mfc0 $v0, $12 \n\ - sw $v0, 140($v1) \n\ - mfc0 $v0, $13 \n\ - sw $v0, 144($v1) \n\ - mfc0 $v0, $14 \n\ - sw $v0, 148($v1) \n\ - mfc0 $v0, $30 \n\ - sw $v0, 152($v1) \n\ - cache 0x1A, 0($v1) \n\ - cache 0x1A, 64($v1) \n\ - cache 0x1A, 128($v1) \n\ - \n\ - # Run the remainder of the handler (compiled C code). \n\ - j me_exception_finish \n\ - nop \n\ - \n\ - .popsection \n\ - .set pop \n\ -"); - -__attribute__((section(".text.me"), noreturn)) void me_exception_finish(void) -{ - volatile MEMessageBlock * const message_block = (volatile MEMessageBlock *) - ((uintptr_t)&message_block_buffer | 0xA0000000); - - message_block->exception = 1; - asm volatile("li $sp, 0x80200000"); - asm volatile("mtc0 %0, $14; " - "mtc0 %0, $30" : : "r" (me_loop)); - asm volatile("eret"); - for (;;) {} // Unreachable, but tell the compiler we don't return -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/me.exp b/yabause/src/psp/me.exp deleted file mode 100644 index 326592b16d..0000000000 --- a/yabause/src/psp/me.exp +++ /dev/null @@ -1,19 +0,0 @@ -PSP_EXPORT_START(syslib, 0, 0x8000) -PSP_EXPORT_FUNC_HASH(module_start) -PSP_EXPORT_VAR_HASH(module_info) -PSP_EXPORT_END - -PSP_EXPORT_START(melib, 0, 0x4001) -PSP_EXPORT_FUNC_HASH(meStart) -PSP_EXPORT_FUNC_HASH(meStop) -PSP_EXPORT_FUNC_HASH(meCall) -PSP_EXPORT_FUNC_HASH(mePoll) -PSP_EXPORT_FUNC_HASH(meWait) -PSP_EXPORT_FUNC_HASH(meResult) -PSP_EXPORT_FUNC_HASH(meException) -PSP_EXPORT_FUNC_HASH(meExceptionGetData) -PSP_EXPORT_FUNC_HASH(meExceptionSetFatal) -PSP_EXPORT_FUNC_HASH(meInterruptPoll) -PSP_EXPORT_FUNC_HASH(meInterruptWait) -PSP_EXPORT_FUNC_HASH(meInterruptClear) -PSP_EXPORT_END diff --git a/yabause/src/psp/me.h b/yabause/src/psp/me.h deleted file mode 100644 index 4194350296..0000000000 --- a/yabause/src/psp/me.h +++ /dev/null @@ -1,231 +0,0 @@ -/* src/psp/me.h: PSP Media Engine access library header - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef ME_H -#define ME_H - -/*************************************************************************/ - -/* Error codes specific to Media Engine routines */ - -enum { - /* Media Engine has not been successfully started with meStart() */ - ME_ERROR_NOT_STARTED = 0x90000001, - /* Media Engine is currently executing a function */ - ME_ERROR_BUSY = 0x90000002, - /* No Media Engine interrupt is pending */ - ME_ERROR_NO_INTERRUPT = 0x90000003, -}; - -/*----------------------------------*/ - -/* Magic value stored in $k0 to indicate that code is running on the ME */ - -#define ME_K0_MAGIC 0x3E3E3E3E - -/*************************************************************************/ - -/** - * meStart: Start up the Media Engine. This function must be called - * before any other Media Engine operations are performed. - * - * [Parameters] - * None - * [Return value] - * Zero on success, otherwise an error code (negative) - */ -extern int meStart(void); - -/** - * meStop: Stop the Media Engine. No other Media Engine functions except - * meStart() may be called after this function returns. - * - * If code is currently executing on the Media Engine when this function is - * called, the effect on system state is undefined. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void meStop(void); - -/*----------------------------------*/ - -/** - * meCall: Begin executing the given function on the Media Engine. The - * function must not call any firmware functions, whether directly or - * indirectly. This routine may only be called when the Media Engine is - * idle (i.e., when mePoll() returns zero). - * - * [Parameters] - * function: Function pointer - * argument: Optional argument to function - * [Return value] - * Zero on success, otherwise an error code (negative) - */ -extern int meCall(int (*function)(void *), void *argument); - -/** - * mePoll: Check whether the Media Engine is idle. - * - * [Parameters] - * None - * [Return value] - * Zero if the Media Engine is idle, otherwise an error code (negative) - */ -extern int mePoll(void); - -/** - * meWait: Wait for the Media Engine to become idle. - * - * [Parameters] - * None - * [Return value] - * Zero if the Media Engine has become (or was already) idle, - * otherwise an error code (negative) - */ -extern int meWait(void); - -/** - * meResult: Return the result (return value) of the most recently - * executed function. The result is undefined if the Media Engine has not - * been started or is not idle, if the most recently executed function did - * not return a result (i.e. had a return type of void), or if the most - * recently executed function triggered an exception. - * - * [Parameters] - * None - * [Return value] - * Result of the most recently executed function - */ -extern int meResult(void); - -/*----------------------------------*/ - -/** - * meException: Return whether the most recently executed function - * triggered an exception. The result is undefined if the Media Engine has - * not been started or is not idle. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the most recently executed function triggered an - * exception, else zero - */ -extern int meException(void); - -/** - * meExceptionGetData: Retrieve CPU status register values related to the - * most recent exception. The values retrieved are undefined in any case - * where meException() returns zero or has an undefined return value. - * - * NULL can be passed for any unneeded register values. - * - * [Parameters] - * BadVAddr_ret: Pointer to variable to receive BadVAddr register value - * Status_ret: Pointer to variable to receive Status register value - * Cause_ret: Pointer to variable to receive Cause register value - * EPC_ret: Pointer to variable to receive EPC register value - * ErrorEPC_ret: Pointer to variable to receive ErrorEPC register value - * [Return value] - * None - */ -extern void meExceptionGetData(uint32_t *BadVAddr_ret, uint32_t *Status_ret, - uint32_t *Cause_ret, uint32_t *EPC_ret, - uint32_t *ErrorEPC_ret); - -/** - * meExceptionSetFatal: Set whether an exception on the Media Engine - * should automatically trigger an exception on the main CPU. If enabled, - * any call to mePoll() or meWait() when an exception is pending will cause - * an address error exception to be generated on the main CPU, with - * exception status information stored in a buffer pointed to by $gp: - * 0($gp) = Status - * 4($gp) = Cause - * 8($gp)= EPC or ErrorEPC (depending on the exception type) - * 12($gp) = BadVAddr - * 16($gp) = Media Engine's $sp - * 20($gp) = Media Engine's $gp - * All general-purpose registers other than $sp and $gp, as well as $hi and - * $lo, are copied from the Media Engine. - * - * Unlike other functions in this library, this function can be called even - * when the ME is not running, and it will always succeed. - * - * By default, exceptions are not fatal. - * - * [Parameters] - * fatal: Nonzero to make exceptions fatal, zero to make them nonfatal - * [Return value] - * None - */ -extern void meExceptionSetFatal(int fatal); - -/*----------------------------------*/ - -/** - * meInterruptPoll: Return whether an interrupt from the Media Engine is - * pending. Any pending interrupt is _not_ cleared. - * - * [Parameters] - * None - * [Return value] - * Zero if an interrupt from the Media Engine is pending, otherwise an - * error code (negative) - */ -extern int meInterruptPoll(void); - -/** - * meInterruptWait: Wait for an interrupt from the Media Engine if none is - * already pending, then clear the interrupt and return. - * - * [Parameters] - * None - * [Return value] - * Zero if an interrupt was received from the Media Engine, otherwise - * an error code (negative) - */ -extern int meInterruptWait(void); - -/** - * meInterruptClear: Clear any pending Media Engine interrupt. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void meInterruptClear(void); - -/*************************************************************************/ - -#endif // ME_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/menu.c b/yabause/src/psp/menu.c deleted file mode 100644 index 8bc7d5f2d7..0000000000 --- a/yabause/src/psp/menu.c +++ /dev/null @@ -1,2527 +0,0 @@ -/* src/psp/menu.c: PSP menu interface - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../cs2.h" -#include "../memory.h" -#include "../peripheral.h" -#include "../scsp.h" -#include "../sh2core.h" -#include "../sh2int.h" -#include "../vdp1.h" -#include "../vidsoft.h" -#include "../yabause.h" - -#include "config.h" -#include "control.h" -#include "display.h" -#include "filesel.h" -#include "font.h" -#include "gu.h" -#include "menu.h" -#include "misc.h" -#include "osk.h" -#include "psp-sh2.h" -#include "psp-video.h" -#include "sh2.h" -#include "sys.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Button input state from the last frame */ -static uint32_t last_buttons; - -/* Repeat delay, rate, and status */ -#define REPEAT_DELAY 30 // frames -#define REPEAT_RATE 3 // frames -static uint32_t repeat_buttons; // Button(s) to repeat -static uint8_t repeating; // Nonzero = repeat started -static uint8_t repeat_timer; // Counts down from REPEAT_{DELAY,RATE} - -/*----------------------------------*/ - -/* FIXME: This menu stuff is all messy and copy-pastey because I'm too - lazy to do it properly at the moment. I hate writing UIs. */ - -/* Currently selected menu and menu option */ - -typedef enum MenuIndex_ { - MENU_MAIN = 0, - MENU_GENERAL, - MENU_FILES, - MENU_BUTTON, - MENU_VIDEO, - MENU_RENDER, - MENU_FRAME_SKIP, - MENU_ADVANCED, - MENU_OPTIMIZE, - MENU_MEDIA_ENGINE, - MENU_YESNO, // A yes/no dialog implemented as a "menu" -} MenuIndex; - -static uint8_t cur_menu; - - -typedef enum MainMenuOption_ { - OPT_MAIN_GENERAL = 0, - OPT_MAIN_BUTTON, - OPT_MAIN_VIDEO, - OPT_MAIN_ADVANCED, - OPT_MAIN_SAVE, - OPT_MAIN_RESET, -} MainMenuOption; -#define OPT_MAIN__MAX OPT_MAIN_RESET - -typedef enum GeneralMenuOption_ { - OPT_GENERAL_START_IN_EMU = 0, - OPT_GENERAL_FILES, - OPT_GENERAL_BUP_AUTOSAVE, - OPT_GENERAL_BUP_SAVE_NOW, - OPT_GENERAL_BUP_SAVE_AS, -} GeneralMenuOption; -#define OPT_GENERAL__MAX OPT_GENERAL_BUP_SAVE_AS - -typedef enum FilesMenuOption_ { - OPT_FILES_PATH_BIOS = 0, - OPT_FILES_PATH_CD, - OPT_FILES_PATH_BUP, -} FilesMenuOption; -#define OPT_FILES__MAX OPT_FILES_PATH_BUP - -typedef enum ButtonMenuOption_ { - OPT_BUTTON_A, - OPT_BUTTON_B, - OPT_BUTTON_C, - OPT_BUTTON_X, - OPT_BUTTON_Y, - OPT_BUTTON_Z, -} ButtonMenuOption; -#define OPT_BUTTON__MAX OPT_BUTTON_Z - -typedef enum VideoMenuOption_ { - OPT_VIDEO_HW = 0, - OPT_VIDEO_SW, - OPT_VIDEO_RENDER, - OPT_VIDEO_FRAME_SKIP, - OPT_VIDEO_SHOW_FPS, -} VideoMenuOption; -#define OPT_VIDEO__MAX OPT_VIDEO_SHOW_FPS - -typedef enum RenderMenuOption_ { - OPT_RENDER_CACHE_TEXTURES = 0, - OPT_RENDER_SMOOTH_TEXTURES, - OPT_RENDER_SMOOTH_HIRES, - OPT_RENDER_ENABLE_ROTATE, - OPT_RENDER_OPTIMIZE_ROTATE, -} RenderMenuOption; -#define OPT_RENDER__MAX OPT_RENDER_OPTIMIZE_ROTATE - -typedef enum FrameSkipMenuOption_ { - OPT_FRAME_SKIP_AUTO = 0, - OPT_FRAME_SKIP_NUM, - OPT_FRAME_SKIP_INTERLACE, - OPT_FRAME_SKIP_ROTATE, -} FrameSkipMenuOption; -#define OPT_FRAME_SKIP__MAX OPT_FRAME_SKIP_ROTATE - -typedef enum AdvancedMenuOption_ { - OPT_ADVANCED_SH2_RECOMPILER = 0, - OPT_ADVANCED_SH2_OPTIMIZE, - OPT_ADVANCED_MEDIA_ENGINE, - OPT_ADVANCED_DECILINE_MODE, - OPT_ADVANCED_AUDIO_SYNC, - OPT_ADVANCED_CLOCK_SYNC, - OPT_ADVANCED_CLOCK_FIXED_TIME, -} AdvancedMenuOption; -#define OPT_ADVANCED__MAX OPT_ADVANCED_CLOCK_FIXED_TIME - -typedef enum OptimizeMenuOption_ { - OPT_OPTIMIZE_ASSUME_SAFE_DIVISION = 0, - OPT_OPTIMIZE_FOLD_SUBROUTINES, - OPT_OPTIMIZE_BRANCH_TO_RTS, - OPT_OPTIMIZE_LOCAL_ACCESSES, - OPT_OPTIMIZE_POINTERS, - OPT_OPTIMIZE_POINTERS_MAC, - OPT_OPTIMIZE_LOCAL_POINTERS, - OPT_OPTIMIZE_STACK, -#if 0 // FIXME: out of space on the screen; this should be the least dangerous - OPT_OPTIMIZE_MAC_NOSAT, -#endif -} OptimizeMenuOption; -#define OPT_OPTIMIZE__MAX OPT_OPTIMIZE_STACK - -typedef enum MediaEngineMenuOption_ { - OPT_MEDIA_ENGINE_USE_ME = 0, - OPT_MEDIA_ENGINE_WRITEBACK_PERIOD, - OPT_MEDIA_ENGINE_UNCACHED_BOUNDARY, -} MediaEngineMenuOption; -#define OPT_MEDIA_ENGINE__MAX OPT_MEDIA_ENGINE_UNCACHED_BOUNDARY - -typedef enum YesNoMenuOption_ { - OPT_YESNO_YES = 0, - OPT_YESNO_NO, -} YesNoMenuOption; -#define OPT_YESNO__MAX OPT_YESNO_NO - -static uint8_t cur_option; - - -/* Maximum menu option index for current menu (OPT_*__MAX) */ -static uint8_t max_option; - -/* File selector, if a file selector is currently open */ -static FileSelector *filesel; - -/*----------------------------------*/ - -/* Previous menu and option (and max_option value) for the yes/no dialog */ -static uint8_t yesno_menu, yesno_option, yesno_maxopt; - -/* Prompt string for the yes/no dialog (may include newlines) */ -static char yesno_prompt[1000]; - -/*----------------------------------*/ - -/* Saved pathname for "Save backup RAM as..." option */ -static char *save_as_path; - -/*----------------------------------*/ - -/* Flag: Is X the confirm button? */ -static int x_is_confirm; - -/*----------------------------------*/ - - -/* Background image buffer */ -static void *bgimage; -static void *bgimage_base; // Base (unaligned) pointer for later free()ing - -/* Background color for the menu, overlaid on the current emulation screen - * (0xAABBGGRR) */ -#define MENU_BGCOLOR 0xC0332C2C - -/* Flag indicating whether we should draw the background image (cleared - * when the user requests an emulator reset, to show visually that the - * emulator has in fact been reset) */ -static uint8_t draw_bgimage; - -/* Cursor color, flashing period, and timer */ -#define CURSOR_COLOR 0x80FFECEC -#define CURSOR_PERIOD 60 // frames -static uint8_t cursor_timer; - -/* Default text color */ -#define TEXT_COLOR 0xFFFFECEC - -/* Text color for informational messages */ -#define TEXT_COLOR_INFO 0xFFFF8040 - -/* Text color for "Saved"/"Failed" responses to "Save settings" */ -#define TEXT_COLOR_OK 0xFF55FF40 // Also used for "Reset the emulator" -#define TEXT_COLOR_NG 0xFF5540FF // Also used for warning text - -/* Text color for disabled menu options */ -#define TEXT_COLOR_DISABLED 0xFF807676 - -/* Status line current text, text color, display time, and timer */ -static const char *status_text; -static uint32_t status_color; -#define STATUS_DISPTIME 300 // frames -static uint16_t status_timer; - -/*************************************************************************/ - -/* Local function declarations */ - -static void gen_menu_bg(void); - -static void do_reset(void); - -static uint32_t get_new_buttons(const uint32_t buttons); -static void process_input_menu(const uint32_t buttons, - const uint32_t new_buttons); -static void process_option_main(const uint32_t buttons); -static void process_option_general(const uint32_t buttons); -static void process_option_files(const uint32_t buttons); -static void process_option_button(const uint32_t buttons); -static void process_option_video(const uint32_t buttons); -static void process_option_render(const uint32_t buttons); -static void process_option_frame_skip(const uint32_t buttons); -static void process_option_advanced(const uint32_t buttons); -static void process_option_optimize(const uint32_t buttons); -static void process_option_media_engine(const uint32_t buttons); -static void process_option_yesno(const uint32_t buttons); -static void process_input_filesel(const uint32_t new_buttons); -static void process_osk_result(void); - -static void draw_menu(void); -static const char *cur_option_confirm_text(void); -static void draw_menu_option(int option, int x, int y, const char *format, ...) - __attribute__((format(printf,4,5))); -static void draw_disabled_menu_option(int option, int x, int y, - const char *format, ...) - __attribute__((format(printf,4,5))); - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * menu_open: Open the menu interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -void menu_open(void) -{ - last_buttons = control_state(); - repeat_buttons = 0; - - cur_menu = MENU_MAIN; - cur_option = 0; - max_option = OPT_MAIN__MAX; - filesel = NULL; - - int res = sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_X_IS_CONFIRM, - &x_is_confirm); - if (res < 0) { - DMSG("Failed to get X_IS_CONFIRM: %s", psp_strerror(res)); - x_is_confirm = 0; // Default to O - } - draw_bgimage = 1; - cursor_timer = 0; - - display_set_size(DISPLAY_WIDTH, DISPLAY_HEIGHT); - gen_menu_bg(); -} - -/*************************************************************************/ - -/** - * menu_run: Perform a single frame's processing for the menu interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -void menu_run(void) -{ - const uint32_t buttons = control_state(); - - /* Update timers */ - cursor_timer = (cursor_timer + 1) % CURSOR_PERIOD; - if (status_timer > 0) { - status_timer--; - } - - /* Update the on-screen keyboard in case it's active */ - osk_update(); - - /* Check for and process input */ - const uint32_t new_buttons = get_new_buttons(buttons); - if (osk_status()) { - process_osk_result(); - } else { - if (filesel) { - process_input_filesel(new_buttons); - } else { - process_input_menu(buttons, new_buttons); - } - } - - /* Draw the menu (and dim the display if the OSK is active) */ - display_begin_frame(); - draw_menu(); - if (osk_status()) { - display_fill_box(0, 0, DISPLAY_WIDTH-1, DISPLAY_HEIGHT-1, 0xAA000000); - } - display_end_frame(); - sceDisplayWaitVblankStart(); -} - -/*************************************************************************/ - -/** - * menu_close: Close the menu interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -void menu_close(void) -{ - /* If the on-screen keyboard is active, close it */ - - if (osk_status()) { - osk_close(); - while (osk_status()) { - osk_update(); - sceDisplayWaitVblankStart(); - } - } - - /* If there's a file selector running, kill it */ - - if (filesel) { - filesel_destroy(filesel); - filesel = NULL; - } - - /* Make sure to clear both display buffers */ - - display_begin_frame(); - if (draw_bgimage) { - guCopyImage(GU_PSM_8888, 0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_STRIDE, bgimage, - 0, 0, DISPLAY_STRIDE, display_work_buffer()); - } else { - display_fill_box(0, 0, DISPLAY_WIDTH-1, DISPLAY_HEIGHT-1, 0xFF000000); - } - display_end_frame(); - sceDisplayWaitVblankStart(); - - display_begin_frame(); - if (draw_bgimage) { - guCopyImage(GU_PSM_8888, 0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_STRIDE, bgimage, - 0, 0, DISPLAY_STRIDE, display_work_buffer()); - } else { - display_fill_box(0, 0, DISPLAY_WIDTH-1, DISPLAY_HEIGHT-1, 0xFF000000); - } - display_end_frame(); - sceDisplayWaitVblankStart(); - - /* Free the background image buffer */ - - free(bgimage_base); - bgimage = bgimage_base = NULL; - - /* Clear the status line so any current message doesn't get held over */ - - status_text = ""; - status_timer = 0; -} - -/*************************************************************************/ - -/** - * menu_set_error: Set an error message to be displayed on the menu - * screen. If message is NULL, any message currently displayed is cleared. - * - * [Parameters] - * message: Message text (NULL to clear current message) - * [Return value] - * None - */ -void menu_set_error(const char *message) -{ - static char buf[100]; // Just in case the message is in a local buffer - - if (message) { - snprintf(buf, sizeof(buf), "%s", message); - status_text = buf; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } else { - status_text = NULL; - status_timer = 0; - } -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * gen_menu_bg: Generate the background image for the menu (a copy of the - * currently-displayed image). - * - * [Parameters] - * None - * [Return value] - * None - */ -static void gen_menu_bg(void) -{ - bgimage_base = malloc((DISPLAY_STRIDE * DISPLAY_HEIGHT * 4) + 63); - if (UNLIKELY(!bgimage_base)) { - DMSG("Out of memory for bgimage"); - bgimage = NULL; - return; - } - bgimage = (void *)(((uintptr_t)bgimage_base + 63) & -64); - memcpy(bgimage, display_disp_buffer(), - DISPLAY_STRIDE * DISPLAY_HEIGHT * 4); -} - -/*************************************************************************/ - -/** - * do_reset: Reset the emulator in response to a user action. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void do_reset(void) -{ - YabauseReset(); - status_text = "Resetting the emulator."; - status_color = TEXT_COLOR_OK; - status_timer = STATUS_DISPTIME; - draw_bgimage = 0; -} - -/*************************************************************************/ - -/** - * get_new_buttons: Return which controller buttons were pressed this - * frame. This may include fake button presses generated by auto-repeat. - * - * If the on-screen keyboard is open, this function always returns zero; - * however, it should still be called every frame to ensure proper - * behavior when the OSK is closed. - * - * [Parameters] - * buttons: Buttons which are currently held down (PSP_CTRL_* bitmask) - * [Return value] - * Buttons which were newly pressed this frame (PSP_CTRL_* bitmask) - */ -static uint32_t get_new_buttons(const uint32_t buttons) -{ - uint32_t new_buttons = ~last_buttons & buttons; - - if (osk_status()) { - new_buttons = 0; - repeat_buttons = 0; - } - - if (new_buttons) { - /* Only allow repeat of up/down/left/right */ - repeat_buttons = new_buttons & (PSP_CTRL_UP | PSP_CTRL_DOWN - | PSP_CTRL_LEFT | PSP_CTRL_RIGHT); - repeating = 0; - repeat_timer = REPEAT_DELAY; - } else if ((buttons & repeat_buttons) != repeat_buttons) { - repeat_buttons = 0; - } - if (repeat_buttons != 0) { - repeat_timer--; - if (repeat_timer == 0) { - new_buttons = repeat_buttons; - repeating = 1; - repeat_timer = REPEAT_RATE; - } - } - - last_buttons = buttons; - return new_buttons; -} - -/*-----------------------------------------------------------------------*/ - -/** - * process_input_menu: Process input directed to the menu (i.e. not a file - * selector. - * - * [Parameters] - * buttons: Buttons which are currently held down (PSP_CTRL_* bitmask) - * new_buttons: Buttons which were pressed this frame (PSP_CTRL_* bitmask) - * [Return value] - * None - */ -static void process_input_menu(const uint32_t buttons, - const uint32_t new_buttons) -{ - const uint32_t confirm_button = - x_is_confirm ? PSP_CTRL_CROSS : PSP_CTRL_CIRCLE; - const uint32_t cancel_button = - x_is_confirm ? PSP_CTRL_CIRCLE : PSP_CTRL_CROSS; - - if (new_buttons & PSP_CTRL_UP) { - if (cur_menu != MENU_YESNO && cur_option > 0) { - cur_option--; - cursor_timer = 0; - } - - } else if (new_buttons & PSP_CTRL_DOWN) { - if (cur_menu != MENU_YESNO && cur_option < max_option) { - cur_option++; - cursor_timer = 0; - } - - } else if (new_buttons & (PSP_CTRL_LEFT | PSP_CTRL_RIGHT)) { - const int dir = (new_buttons & PSP_CTRL_RIGHT) ? 1 : -1; - - if (cur_menu == MENU_FRAME_SKIP - && cur_option == OPT_FRAME_SKIP_NUM - ) { - const int new_num = config_get_frameskip_num() + dir; - if (!config_set_frameskip_num(new_num)) { - status_text = "Failed to change fixed frame skip count!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - - } else if (cur_menu == MENU_MEDIA_ENGINE - && cur_option == OPT_MEDIA_ENGINE_WRITEBACK_PERIOD - ) { - if (me_available && config_get_use_me()) { - const unsigned int period = config_get_me_writeback_period(); - unsigned int new_period = (dir > 0) ? period<<1 : period>>1; - if (new_period < 1) { - new_period = 1; - } else if (new_period > 64) { // Should be more than enough - new_period = 64; - } - if (!config_set_me_writeback_period(new_period)) { - status_text = "Failed to change ME writeback frequency!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - } - - } else if (cur_menu == MENU_MEDIA_ENGINE - && cur_option == OPT_MEDIA_ENGINE_UNCACHED_BOUNDARY - ) { - if (me_available && config_get_use_me()) { - const unsigned int value = config_get_me_uncached_boundary(); - unsigned int new_value = (dir > 0) - ? (value==0 ? 0x400 : value<<1) - : value>>1; - if (new_value < 0x400) { // Shouldn't need to deal with - new_value = 0; // fractions of a kilobyte - } else if (new_value > 0x80000) { - new_value = 0x80000; - } - if (!config_set_me_uncached_boundary(new_value)) { - status_text = "Failed to change uncached boundary address!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - } - - } else if (cur_menu == MENU_YESNO) { - if (dir < 0) { - if (cur_option == OPT_YESNO_NO) { - cur_option = OPT_YESNO_YES; - cursor_timer = 0; - } - } else { - if (cur_option == OPT_YESNO_YES) { - cur_option = OPT_YESNO_NO; - cursor_timer = 0; - } - } - } - - } else if (new_buttons != 0 && cur_menu == MENU_BUTTON) { - if (new_buttons & (PSP_CTRL_CIRCLE | PSP_CTRL_CROSS - | PSP_CTRL_TRIANGLE | PSP_CTRL_SQUARE)) { - process_option_button(buttons); - } else if (new_buttons & PSP_CTRL_START) { - cur_menu = MENU_MAIN; - cur_option = OPT_MAIN_BUTTON; - max_option = OPT_MAIN__MAX; - } - - } else if (new_buttons & confirm_button) { - switch ((MenuIndex)cur_menu) { - case MENU_MAIN: process_option_main(buttons); break; - case MENU_GENERAL: process_option_general(buttons); break; - case MENU_FILES: process_option_files(buttons); break; - case MENU_BUTTON: /* impossible (handled above) */ break; - case MENU_VIDEO: process_option_video(buttons); break; - case MENU_RENDER: process_option_render(buttons); break; - case MENU_FRAME_SKIP: process_option_frame_skip(buttons); break; - case MENU_ADVANCED: process_option_advanced(buttons); break; - case MENU_OPTIMIZE: process_option_optimize(buttons); break; - case MENU_MEDIA_ENGINE:process_option_media_engine(buttons); break; - case MENU_YESNO: process_option_yesno(buttons); break; - } - - } else if (new_buttons & cancel_button) { - if (cur_menu != MENU_MAIN) { - switch ((MenuIndex)cur_menu) { - case MENU_MAIN: - case MENU_BUTTON: - /* Impossible, but included to avoid a compiler warning */ - break; - case MENU_GENERAL: - cur_menu = MENU_MAIN; - cur_option = OPT_MAIN_GENERAL; - max_option = OPT_MAIN__MAX; - break; - case MENU_FILES: - cur_menu = MENU_GENERAL; - cur_option = OPT_GENERAL_FILES; - max_option = OPT_GENERAL__MAX; - break; - case MENU_VIDEO: - cur_menu = MENU_MAIN; - cur_option = OPT_MAIN_VIDEO; - max_option = OPT_MAIN__MAX; - break; - case MENU_RENDER: - cur_menu = MENU_VIDEO; - cur_option = OPT_VIDEO_RENDER; - max_option = OPT_VIDEO__MAX; - break; - case MENU_FRAME_SKIP: - cur_menu = MENU_VIDEO; - cur_option = OPT_VIDEO_FRAME_SKIP; - max_option = OPT_VIDEO__MAX; - break; - case MENU_ADVANCED: - cur_menu = MENU_MAIN; - cur_option = OPT_MAIN_ADVANCED; - max_option = OPT_MAIN__MAX; - break; - case MENU_OPTIMIZE: - cur_menu = MENU_ADVANCED; - cur_option = OPT_ADVANCED_SH2_OPTIMIZE; - max_option = OPT_ADVANCED__MAX; - break; - case MENU_MEDIA_ENGINE: - cur_menu = MENU_ADVANCED; - cur_option = OPT_ADVANCED_MEDIA_ENGINE; - max_option = OPT_ADVANCED__MAX; - break; - case MENU_YESNO: - cur_option = OPT_YESNO_NO; - process_option_yesno(confirm_button); - break; - } - } - - } -} - -/*----------------------------------*/ - -/** - * process_option_*: Process a "confirm" button press on the currently - * selected menu option. Each menu has its own handler function. - * - * [Parameters] - * buttons: Buttons which are currently held down (PSP_CTRL_* bitmask) - * [Return value] - * None - */ - -static void process_option_main(const uint32_t buttons) -{ - switch ((MainMenuOption)cur_option) { - - case OPT_MAIN_GENERAL: - cur_menu = MENU_GENERAL; - cur_option = 0; - max_option = OPT_GENERAL__MAX; - break; - - case OPT_MAIN_BUTTON: - cur_menu = MENU_BUTTON; - cur_option = 0; - max_option = OPT_BUTTON__MAX; - break; - - case OPT_MAIN_VIDEO: - cur_menu = MENU_VIDEO; - cur_option = 0; - max_option = OPT_VIDEO__MAX; - break; - - case OPT_MAIN_ADVANCED: - cur_menu = MENU_ADVANCED; - cur_option = 0; - max_option = OPT_ADVANCED__MAX; - break; - - case OPT_MAIN_SAVE: - if (config_save()) { - status_text = "Settings saved."; - status_color = TEXT_COLOR_OK; - } else { - status_text = "Failed to save settings!"; - status_color = TEXT_COLOR_NG; - } - status_timer = STATUS_DISPTIME; - break; - - case OPT_MAIN_RESET: - if (yabause_initted - && (buttons & PSP_CTRL_LTRIGGER) - && (buttons & PSP_CTRL_RTRIGGER) - ) { - do_reset(); - } - - } -} - -/*----------------------------------*/ - -static void process_option_general(const uint32_t buttons) -{ - switch ((GeneralMenuOption)cur_option) { - - case OPT_GENERAL_START_IN_EMU: - if (!config_set_start_in_emu(!config_get_start_in_emu())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_GENERAL_FILES: - cur_menu = MENU_FILES; - cur_option = 0; - max_option = OPT_FILES__MAX; - break; - - case OPT_GENERAL_BUP_AUTOSAVE: - if (!config_set_bup_autosave(!config_get_bup_autosave())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_GENERAL_BUP_SAVE_NOW: { - if (!yabause_initted) { - break; - } - const char *path = config_get_path_bup(); - if (!path || !*path) { // Check this early just in case - status_text = "No backup RAM file configured!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } else if (!save_backup_ram()) { - status_text = "Error saving backup RAM!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } else { - status_text = "Backup RAM saved."; - status_color = TEXT_COLOR_OK; - status_timer = STATUS_DISPTIME; - } - break; - } // case OPT_GENERAL_BUP_SAVE_NOW - - case OPT_GENERAL_BUP_SAVE_AS: { - if (!yabause_initted) { - break; - } - const unsigned int maxlen = 100; // Reasonable limit - const char *path = config_get_path_bup(); - if (!path) { - path = "backup.bin"; // Just in case - } - if (!osk_open("Enter new backup RAM filename.", path, maxlen)) { - status_text = "Unable to open on-screen keyboard!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - break; - } - /* process_osk_result() will take care of handling the result from - * the OSK and saving the new file. */ - break; - } // case OPT_GENERAL_BUP_SAVE_AS - - } -} - -/*----------------------------------*/ - -static void process_option_files(const uint32_t buttons) -{ - switch ((FilesMenuOption)cur_option) { - - case OPT_FILES_PATH_BIOS: - filesel = filesel_create("Select BIOS image file", progpath); - if (!filesel) { - status_text = "Failed to open file selector!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_FILES_PATH_CD: - filesel = filesel_create("Select CD image file (ISO or CUE)", - progpath); - if (!filesel) { - status_text = "Failed to open file selector!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_FILES_PATH_BUP: - filesel = filesel_create("Select backup RAM image file", - progpath); - if (!filesel) { - status_text = "Failed to open file selector!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - } -} - -/*----------------------------------*/ - -static void process_option_button(const uint32_t buttons) -{ - static const uint8_t perkey_map[] = { - [CONFIG_BUTTON_A] = PERPAD_A, - [CONFIG_BUTTON_B] = PERPAD_B, - [CONFIG_BUTTON_C] = PERPAD_C, - [CONFIG_BUTTON_X] = PERPAD_X, - [CONFIG_BUTTON_Y] = PERPAD_Y, - [CONFIG_BUTTON_Z] = PERPAD_Z, - }; - - if (buttons & (buttons-1)) { - status_text = "Press only one button at a time."; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - return; - } - - const unsigned int saturn_button = - CONFIG_BUTTON_A + (cur_option - OPT_BUTTON_A); - const uint32_t psp_button = buttons; - - /* If this button is currently assigned to something else, swap the - * buttons around. */ - unsigned int other_button; - for (other_button = CONFIG_BUTTON_A; other_button <= CONFIG_BUTTON_Z; - other_button++ - ) { - if (config_get_button(other_button) == psp_button) { - break; - } - } - if (other_button <= CONFIG_BUTTON_Z) { - if (!config_set_button(other_button,config_get_button(saturn_button))){ - status_text = "Failed to reassign button!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - return; - } - PerSetKey(config_get_button(other_button), perkey_map[other_button], - padbits); - } - - if (!config_set_button(saturn_button, psp_button)) { - status_text = "Failed to assign button!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - return; - } - PerSetKey(psp_button, perkey_map[saturn_button], padbits); -} - -/*----------------------------------*/ - -static void process_option_video(const uint32_t buttons) -{ - switch ((VideoMenuOption)cur_option) { - - case OPT_VIDEO_HW: - if (config_get_module_video() != VIDCORE_PSP) { - if (VideoChangeCore(VIDCORE_PSP) < 0 - || !config_set_module_video(VIDCORE_PSP) - ) { - status_text = "Failed to change video interface!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - } - break; - - case OPT_VIDEO_SW: - if (config_get_module_video() != VIDCORE_SOFT) { - if (VideoChangeCore(VIDCORE_SOFT) < 0 - || !config_set_module_video(VIDCORE_SOFT) - ) { - status_text = "Failed to change video interface!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - } - break; - - case OPT_VIDEO_RENDER: - cur_menu = MENU_RENDER; - cur_option = 0; - max_option = OPT_RENDER__MAX; - break; - - case OPT_VIDEO_FRAME_SKIP: - cur_menu = MENU_FRAME_SKIP; - cur_option = 0; - max_option = OPT_FRAME_SKIP__MAX; - break; - - case OPT_VIDEO_SHOW_FPS: - if (!config_set_show_fps(!config_get_show_fps())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - } -} - -/*----------------------------------*/ - -static void process_option_render(const uint32_t buttons) -{ - switch ((RenderMenuOption)cur_option) { - - case OPT_RENDER_CACHE_TEXTURES: - if (!config_set_cache_textures(!config_get_cache_textures())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_RENDER_SMOOTH_TEXTURES: - if (!config_set_smooth_textures(!config_get_smooth_textures())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_RENDER_SMOOTH_HIRES: - if (!config_set_smooth_hires(!config_get_smooth_hires())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_RENDER_ENABLE_ROTATE: - if (!config_set_enable_rotate(!config_get_enable_rotate())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_RENDER_OPTIMIZE_ROTATE: - if (!config_set_optimize_rotate(!config_get_optimize_rotate())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - } -} - -/*----------------------------------*/ - -static void process_option_frame_skip(const uint32_t buttons) -{ - switch ((FrameSkipMenuOption)cur_option) { - - case OPT_FRAME_SKIP_AUTO: - if (!config_set_frameskip_auto(!config_get_frameskip_auto())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_FRAME_SKIP_NUM: - /* Don't do anything for the confirm button */ - break; - - case OPT_FRAME_SKIP_INTERLACE: - if (!config_set_frameskip_interlace(!config_get_frameskip_interlace())){ - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_FRAME_SKIP_ROTATE: - if (!config_set_frameskip_rotate(!config_get_frameskip_rotate())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - } -} - -/*----------------------------------*/ - -static void process_option_advanced(const uint32_t buttons) -{ - switch ((AdvancedMenuOption)cur_option) { - - case OPT_ADVANCED_SH2_RECOMPILER: - if ((buttons & PSP_CTRL_LTRIGGER) && (buttons & PSP_CTRL_RTRIGGER)) { - int new_module; - if (config_get_module_sh2() == SH2CORE_PSP) { - new_module = SH2CORE_INTERPRETER; - } else { - new_module = SH2CORE_PSP; - } - if (!config_set_module_sh2(new_module)) { - status_text = "Failed to change SH-2 core!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - if (yabause_initted) { - SH2DeInit(); - SH2Init(new_module); - do_reset(); - } - } - break; - - case OPT_ADVANCED_SH2_OPTIMIZE: - cur_menu = MENU_OPTIMIZE; - cur_option = 0; - max_option = OPT_OPTIMIZE__MAX; - break; - - case OPT_ADVANCED_MEDIA_ENGINE: - if (me_available) { - cur_menu = MENU_MEDIA_ENGINE; - cur_option = 0; - max_option = OPT_MEDIA_ENGINE__MAX; - } - break; - - case OPT_ADVANCED_DECILINE_MODE: - if (!config_set_deciline_mode(!config_get_deciline_mode())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - YabauseSetDecilineMode(config_get_deciline_mode()); - break; - - case OPT_ADVANCED_AUDIO_SYNC: - if (!config_set_audio_sync(!config_get_audio_sync())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - ScspSetFrameAccurate(config_get_audio_sync()); - break; - - case OPT_ADVANCED_CLOCK_SYNC: - if (!config_set_clock_sync(!config_get_clock_sync())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - case OPT_ADVANCED_CLOCK_FIXED_TIME: - if (!config_set_clock_fixed_time(!config_get_clock_fixed_time())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - break; - - } -} - -/*----------------------------------*/ - -static void process_option_optimize(const uint32_t buttons) -{ - uint32_t optflags = config_get_sh2_optimizations(); - - switch ((OptimizeMenuOption)cur_option) { - case OPT_OPTIMIZE_ASSUME_SAFE_DIVISION: - optflags ^= SH2_OPTIMIZE_ASSUME_SAFE_DIVISION; - break; - case OPT_OPTIMIZE_FOLD_SUBROUTINES: - optflags ^= SH2_OPTIMIZE_FOLD_SUBROUTINES; - break; - case OPT_OPTIMIZE_BRANCH_TO_RTS: - optflags ^= SH2_OPTIMIZE_BRANCH_TO_RTS; - break; - case OPT_OPTIMIZE_LOCAL_ACCESSES: - optflags ^= SH2_OPTIMIZE_LOCAL_ACCESSES; - break; - case OPT_OPTIMIZE_POINTERS: - optflags ^= SH2_OPTIMIZE_POINTERS; - break; - case OPT_OPTIMIZE_POINTERS_MAC: - optflags ^= SH2_OPTIMIZE_POINTERS_MAC; - break; - case OPT_OPTIMIZE_LOCAL_POINTERS: - optflags ^= SH2_OPTIMIZE_LOCAL_POINTERS; - break; - case OPT_OPTIMIZE_STACK: - optflags ^= SH2_OPTIMIZE_STACK; - break; -#if 0 // FIXME: out of space on the screen - case OPT_OPTIMIZE_MAC_NOSAT: - optflags ^= SH2_OPTIMIZE_MAC_NOSAT; - break; -#endif - } - - if (!config_set_sh2_optimizations(optflags)) { - status_text = "Failed to set optimization flags!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - return; - } - sh2_set_optimizations(optflags); -} - -/*----------------------------------*/ - -static void process_option_media_engine(const uint32_t buttons) -{ - switch ((MediaEngineMenuOption)cur_option) { - case OPT_MEDIA_ENGINE_USE_ME: - if (me_available) { - if (!config_set_use_me(!config_get_use_me())) { - status_text = "Failed to change option!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } - } - break; - - case OPT_MEDIA_ENGINE_WRITEBACK_PERIOD: - case OPT_MEDIA_ENGINE_UNCACHED_BOUNDARY: - /* Don't do anything for the confirm button */ - break; - } -} - -/*----------------------------------*/ - -static void process_option_yesno(const uint32_t buttons) -{ - if (yesno_menu == MENU_GENERAL && yesno_option == OPT_GENERAL_BUP_SAVE_AS) { - if (cur_option == OPT_YESNO_YES) { - if (!config_set_path_bup(save_as_path)) { - status_text = "Failed to store new backup RAM filename!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } else if (!save_backup_ram()) { - status_text = "Error saving backup RAM!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - } else { - static char buf[50]; - snprintf(buf, sizeof(buf), "Backup RAM saved to: %.25s%s", - save_as_path, strlen(save_as_path) > 25 ? "..." : ""); - status_text = buf; - status_color = TEXT_COLOR_OK; - status_timer = STATUS_DISPTIME; - } - } - free(save_as_path); - - } else { - DMSG("Invalid previous menu/option: %u/%u", yesno_menu, yesno_option); - } - - cur_menu = yesno_menu; - cur_option = yesno_option; - max_option = yesno_maxopt; -} - -/*-----------------------------------------------------------------------*/ - -/** - * process_input_filesel: Process input directed to a file selector. - * - * [Parameters] - * new_buttons: Buttons which were pressed this frame (PSP_CTRL_* bitmask) - * [Return value] - * None - */ -static void process_input_filesel(const uint32_t new_buttons) -{ - filesel_process(filesel, new_buttons); - - if (filesel_done(filesel)) { - - const char *filename = filesel_selected_file(filesel); - - if (filename) { - - /* We only need to reset if the emulator has already been - * started */ - int need_reset = yabause_initted; - - /* We can only come here from the "Files" menu, so there's no - * need to check cur_menu */ - - switch ((FilesMenuOption)cur_option) { - - case OPT_FILES_PATH_BIOS: - if (strcmp(config_get_path_bios(), filename) == 0) { - need_reset = 0; - } - if (!config_set_path_bios(filename)) { - status_text = "Failed to set BIOS image filename!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - need_reset = 0; - } - if (yabause_initted) { - if (LoadBios(filename) != 0) { - status_text = "Failed to load BIOS image!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - need_reset = 0; - } - } - break; - - case OPT_FILES_PATH_CD: - if (strcmp(config_get_path_cd(), filename) == 0) { - need_reset = 0; - } - if (!config_set_path_cd(filename)) { - status_text = "Failed to set CD image filename!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - need_reset = 0; - } - if (yabause_initted) { - /* Unfortunately, Cs2ChangeCDCore() doesn't return an error - * if the load fails, so we'll just hope it worked. */ - Cs2ChangeCDCore(CDCORE_ISO, filename); - } - break; - - case OPT_FILES_PATH_BUP: - if (strcmp(config_get_path_bup(), filename) == 0) { - need_reset = 0; - } - if (!config_set_path_bup(filename)) { - status_text = - "Failed to set backup RAM image filename!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - need_reset = 0; - } - if (yabause_initted) { - if (LoadBackupRam(filename) != 0) { - status_text = "Failed to load backup RAM image!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - need_reset = 0; - } - } - break; - - default: // impossible - break; - - } - - if (need_reset) { - do_reset(); - } - - } // if (filename) - - filesel_destroy(filesel); - filesel = NULL; - - } // if (filesel_done(filesel)) -} - -/*-----------------------------------------------------------------------*/ - -/** - * process_osk_result: Process the result of input to the on-screen - * keyboard. Assumes the OSK is currently active. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void process_osk_result(void) -{ - PRECOND(osk_status(), return); - - /* The OSK is currently only used for OPT_GENERAL_BUP_SAVE_AS, so we - * don't need to check the current menu or option index. */ - - switch (osk_result()) { - case OSK_RESULT_NONE: - /* We've already requested a close, so nothing else to do. */ - break; - - case OSK_RESULT_ERROR: - status_text = "An error occurred during on-screen keyboard input!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - osk_close(); - break; - - case OSK_RESULT_RUNNING: - break; - - case OSK_RESULT_CANCELLED: - osk_close(); - break; - - case OSK_RESULT_UNCHANGED: - case OSK_RESULT_CHANGED: { - char *path = osk_get_text(); - osk_close(); - if (!path) { - status_text = "An error occurred during on-screen keyboard input!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - break; - } else if (!*path) { - status_text = "No filename was entered!"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - free(path); - break; - } else if (path[strcspn(path,":/\\")]) { - status_text = "These characters cannot be used in a filename: / \\ :"; - status_color = TEXT_COLOR_NG; - status_timer = STATUS_DISPTIME; - free(path); - break; - } - - /* Confirm the action with the user. Default to "Yes" if the file - * does not exist, "No" if it already exists. */ - save_as_path = path; - yesno_menu = cur_menu; - yesno_option = cur_option; - yesno_maxopt = max_option; - cur_menu = MENU_YESNO; - max_option = OPT_YESNO__MAX; - FILE *test = fopen(path, "r"); - if (test) { - fclose(test); - cur_option = OPT_YESNO_NO; - snprintf(yesno_prompt, sizeof(yesno_prompt), - "The file \"%.25s%s\" already exists!\n" - "Do you want to overwrite this file?\n", - path, strlen(path) > 25 ? "..." : ""); - } else { - cur_option = OPT_YESNO_YES; - snprintf(yesno_prompt, sizeof(yesno_prompt), - "Save backup RAM to the file%s\"%.50s%s\"?\n", - strlen(path) < 20 ? " " : "\n", - path, strlen(path) > 50 ? "..." : ""); - } - break; - } - } -} - -/*************************************************************************/ - -/** - * draw_menu: Draw the menu interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void draw_menu(void) -{ - /* Set up basic settings */ - - guDisable(GU_TEXTURE_2D); - guEnable(GU_BLEND); - guBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); - - /* Draw the background image, if appropriate, and overlay color */ - - if (bgimage && draw_bgimage) { - guCopyImage(GU_PSM_8888, 0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_STRIDE, bgimage, - 0, 0, DISPLAY_STRIDE, display_work_buffer()); - } - display_fill_box(0, 0, DISPLAY_WIDTH-1, DISPLAY_HEIGHT-1, MENU_BGCOLOR); - - /* Draw the upper and lower info bars */ - - font_printf(DISPLAY_WIDTH/2, 5, 0, TEXT_COLOR_INFO, - "Yabause %s", PACKAGE_VERSION); - display_fill_box(0, 21, DISPLAY_WIDTH - 1, 21, TEXT_COLOR_INFO); - display_fill_box(0, 22, DISPLAY_WIDTH - 1, 22, 0xFF000000); - - const char *confirm_text = - (filesel != NULL) - ? "U/D/L/R: Move cursor O: Select file X: Previous menu" - : cur_option_confirm_text(); - if (x_is_confirm) { - static char swapbuf[100]; - unsigned int i; - for (i = 0; i < sizeof(swapbuf)-1 && confirm_text[i]; i++) { - if (confirm_text[i] == 'O' && confirm_text[i+1] == ':') { - swapbuf[i] = 'X'; - } else if (confirm_text[i] == 'X' && confirm_text[i+1] == ':') { - swapbuf[i] = 'O'; - } else { - swapbuf[i] = confirm_text[i]; - } - } - swapbuf[i] = 0; - confirm_text = swapbuf; - } - font_printf(DISPLAY_WIDTH/2, DISPLAY_HEIGHT - 16, 0, TEXT_COLOR_INFO, - "Select: Exit menu %s", confirm_text); - display_fill_box(0, DISPLAY_HEIGHT - 22, - DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 22, TEXT_COLOR_INFO); - display_fill_box(0, DISPLAY_HEIGHT - 21, - DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 21, 0xFF000000); - if (status_timer > 0) { - const float alpha = status_timer >= STATUS_DISPTIME/2 ? 1.0f : - (status_timer / (float)(STATUS_DISPTIME/2)); - const uint32_t alpha_byte = - floorf((status_color>>24 & 0xFF) * alpha + 0.5f); - font_printf(DISPLAY_WIDTH/2, DISPLAY_HEIGHT - 27 - FONT_HEIGHT, 0, - alpha_byte<<24 | (status_color & 0x00FFFFFF), - "%s", status_text); - } - - /* Draw the menu options and cursor */ - - const int menu_left_edge = 130; - const int line_height = FONT_HEIGHT*5/4; - const int menu_title_y = (DISPLAY_HEIGHT/2 - line_height/2) - - (7*line_height + FONT_HEIGHT) / 2 - 2*line_height; - const int menu_help_y = (DISPLAY_HEIGHT/2 - line_height/2) - - (7*line_height + FONT_HEIGHT) / 2 + 7*line_height; - const int menu_center_y = (menu_title_y + menu_help_y) / 2 + FONT_HEIGHT/2; - int x, y; - - switch ((MenuIndex)cur_menu) { - - case MENU_MAIN: - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Yabause Main Menu"); - y = menu_center_y - (5*line_height + line_height/2 + FONT_HEIGHT) / 2; - draw_menu_option(OPT_MAIN_GENERAL, menu_left_edge, y, - "Configure general options..."); - y += line_height; - draw_menu_option(OPT_MAIN_BUTTON, menu_left_edge, y, - "Configure controller buttons..."); - y += line_height; - draw_menu_option(OPT_MAIN_VIDEO, menu_left_edge, y, - "Configure video options..."); - y += line_height; - draw_menu_option(OPT_MAIN_ADVANCED, menu_left_edge, y, - "Configure advanced settings..."); - y += line_height*3/2; - draw_menu_option(OPT_MAIN_SAVE, menu_left_edge, y, "Save settings"); - y += line_height; - if (yabause_initted) { - draw_menu_option(OPT_MAIN_RESET, menu_left_edge, y, - "Reset emulator"); - } else { - draw_disabled_menu_option(OPT_MAIN_RESET, menu_left_edge, y, - "Reset emulator"); - } - y = menu_help_y; - switch ((MainMenuOption)cur_option) { - case OPT_MAIN_GENERAL: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Select data files" - " for use with the emulator, or change"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "other general" - " settings."); - y += line_height; - break; - case OPT_MAIN_BUTTON: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Choose which PSP" - " controls to use for the Saturn"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "controller buttons."); - y += line_height; - break; - case OPT_MAIN_VIDEO: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Choose between" - " hardware and software video rendering,"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "or configure display" - " settings."); - y += line_height; - break; - case OPT_MAIN_ADVANCED: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Configure advanced" - " emulation options."); - y += line_height; - break; - case OPT_MAIN_SAVE: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Save the current" - " settings, so Yabause will use them"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "automatically the" - " next time you start it up."); - y += line_height; - break; - case OPT_MAIN_RESET: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Reset the emulator," - " as though you had pressed the"); - y += line_height; - x = font_printf(75, y, -1, TEXT_COLOR_INFO, "Saturn's RESET" - " button. "); - font_printf(x, y, -1, TEXT_COLOR_NG, "Hold the L and R buttons"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "while selecting this" - " option."); - break; - } - break; - - case MENU_GENERAL: - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Configure general options"); - y = menu_center_y - (5*line_height + FONT_HEIGHT) / 2; - draw_menu_option(OPT_GENERAL_START_IN_EMU, menu_left_edge, y, - "[%c] Start emulator immediately", - config_get_start_in_emu() ? '*' : ' '); - y += line_height*3/2; - draw_menu_option(OPT_GENERAL_FILES, menu_left_edge, y, - " Select BIOS/CD/backup files..."); - y += line_height*3/2; - draw_menu_option(OPT_GENERAL_BUP_AUTOSAVE, menu_left_edge, y, - "[%c] Auto-save backup RAM", - config_get_bup_autosave() ? '*' : ' '); - y += line_height; - if (yabause_initted) { - draw_menu_option(OPT_GENERAL_BUP_SAVE_NOW, menu_left_edge, y, - " Save backup RAM now"); - } else { - draw_disabled_menu_option(OPT_GENERAL_BUP_SAVE_NOW, menu_left_edge, - y, " Save backup RAM now"); - } - y += line_height; - if (yabause_initted) { - draw_menu_option(OPT_GENERAL_BUP_SAVE_AS, menu_left_edge, y, - " Save backup RAM as..."); - } else { - draw_disabled_menu_option(OPT_GENERAL_BUP_SAVE_AS, menu_left_edge, - y, " Save backup RAM as..."); - } - y = menu_help_y; - switch ((GeneralMenuOption)cur_option) { - case OPT_GENERAL_START_IN_EMU: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Start the Saturn" - " emulation immediately when you start"); - y += line_height; - x = font_printf(75, y, -1, TEXT_COLOR_INFO, "Yabause, rather" - " than displaying this menu. "); - font_printf(x, y, -1, TEXT_COLOR_NG, "Remember"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "to \"Save settings\"" - " after changing this option!"); - y += line_height; - break; - case OPT_GENERAL_FILES: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Select the files" - " containing the BIOS image, CD image,"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "and backup data you" - " want to use."); - y += line_height; - break; - case OPT_GENERAL_BUP_AUTOSAVE: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Save the contents of" - " backup RAM whenever you save your"); - y += line_height; - x = font_printf(75, y, -1, TEXT_COLOR_INFO, "game in the" - " emulator. "); - font_printf(x, y, -1, TEXT_COLOR_NG, "Even if this option is" - " enabled,"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "backup RAM is NOT saved" - " when you quit Yabause."); - y += line_height; - break; - case OPT_GENERAL_BUP_SAVE_NOW: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Save the current" - " contents of backup RAM to your"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "Memory Stick."); - y += line_height; - break; - case OPT_GENERAL_BUP_SAVE_AS: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Save the current" - " contents of backup RAM in a new file"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "on your Memory Stick." - " The new file will be used for"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "automatic and manual" - " saves until you quit Yabause."); - y += line_height; - break; - } - break; - - case MENU_FILES: - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Select BIOS/CD/backup files"); - y = menu_center_y - (2*line_height + FONT_HEIGHT) / 2; - draw_menu_option(OPT_FILES_PATH_BIOS, menu_left_edge, y, - "Select BIOS image (%s)", config_get_path_bios()); - y += line_height; - draw_menu_option(OPT_FILES_PATH_CD, menu_left_edge, y, - "Select CD image (%s)", config_get_path_cd()); - y += line_height; - draw_menu_option(OPT_FILES_PATH_BUP, menu_left_edge, y, - "Select backup RAM file (%s)", config_get_path_bup()); - y = menu_help_y; - switch ((FilesMenuOption)cur_option) { - case OPT_FILES_PATH_BIOS: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Select the file" - " containing the Saturn BIOS image."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "Changing this file" - " will reset the emulator."); - y += line_height; - break; - case OPT_FILES_PATH_CD: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Select the file" - " containing the CD image you want to"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "use. This can be either" - " an ISO file or a CUE file."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "Changing this file" - " will reset the emulator."); - y += line_height; - break; - case OPT_FILES_PATH_BUP: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Select the file" - " containing your backup RAM data."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "Changing this file" - " will reset the emulator."); - y += line_height; - break; - } - break; - - case MENU_BUTTON: { - static const char saturn_buttons[] = { - [OPT_BUTTON_A] = 'A', - [OPT_BUTTON_B] = 'B', - [OPT_BUTTON_C] = 'C', - [OPT_BUTTON_X] = 'X', - [OPT_BUTTON_Y] = 'Y', - [OPT_BUTTON_Z] = 'Z', - }; - auto inline const char *psp_button_name(const uint32_t bitmask); - auto inline const char *psp_button_name(const uint32_t bitmask) { - static const char * const psp_button_names[] = { - [31 - __builtin_clz(PSP_CTRL_CIRCLE )] = "Circle", - [31 - __builtin_clz(PSP_CTRL_CROSS )] = "Cross", - [31 - __builtin_clz(PSP_CTRL_TRIANGLE)] = "Triangle", - [31 - __builtin_clz(PSP_CTRL_SQUARE )] = "Square", - }; - const unsigned int index = 31 - __builtin_clz(bitmask); - return (index < lenof(psp_button_names) && psp_button_names[index]) - ? psp_button_names[index] : "(None)"; - } - - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Configure controller buttons"); - y = menu_center_y - (5*line_height + FONT_HEIGHT) / 2; - unsigned int i; - for (i = OPT_BUTTON_A; i <= OPT_BUTTON_Z; i++) { - const uint32_t psp_button = - config_get_button(CONFIG_BUTTON_A + (i - OPT_BUTTON_A)); - draw_menu_option(i, menu_left_edge, y, "%c --- %s", - saturn_buttons[i], psp_button_name(psp_button)); - y += line_height; - } - y = menu_help_y; - font_printf(75, y, -1, TEXT_COLOR_INFO, "Press one of the" - " Circle/Cross/Triangle/Square buttons"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "to assign that PSP button" - " to the Saturn controller's"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "%c button. (L, R, and Start" - " cannot be reassigned.)", saturn_buttons[cur_option]); - y += line_height; - break; - } // case MENU_BUTTON - - case MENU_VIDEO: - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Configure video options"); - y = menu_center_y - (4*line_height + line_height/2 + FONT_HEIGHT) / 2; - draw_menu_option(OPT_VIDEO_HW, menu_left_edge, y, - "(%c) Use hardware video renderer", - config_get_module_video()==VIDCORE_PSP ? '*' : ' '); - y += line_height; - draw_menu_option(OPT_VIDEO_SW, menu_left_edge, y, - "(%c) Use software video renderer", - config_get_module_video()==VIDCORE_SOFT ? '*' : ' '); - y += line_height*3/2; - draw_menu_option(OPT_VIDEO_RENDER, menu_left_edge, y, - " Configure hardware rendering settings..."); - y += line_height; - draw_menu_option(OPT_VIDEO_FRAME_SKIP, menu_left_edge, y, - " Configure frame-skip settings..."); - y += line_height; - draw_menu_option(OPT_VIDEO_SHOW_FPS, menu_left_edge, y, - "[%c] Show FPS", config_get_show_fps() ? '*' : ' '); - y = menu_help_y; - switch ((VideoMenuOption)cur_option) { - case OPT_VIDEO_HW: - font_printf(75, y, -1, TEXT_COLOR_INFO, "The hardware video" - " renderer is fast, but may not always"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "display accurate" - " graphics."); - y += line_height; - break; - case OPT_VIDEO_SW: - font_printf(75, y, -1, TEXT_COLOR_INFO, "The software video" - " renderer is slow, but more faithful"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "to the actual Saturn" - " display."); - y += line_height; - break; - case OPT_VIDEO_RENDER: - font_printf(75, y, -1, TEXT_COLOR_INFO, "This submenu lets you" - " change certain aspects of the"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "hardware video" - " renderer's behavior. The options do not"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "affect the software" - " video renderer."); - y += line_height; - break; - case OPT_VIDEO_FRAME_SKIP: - font_printf(75, y, -1, TEXT_COLOR_INFO, "The hardware renderer" - " can be configured to skip drawing"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "some frames to speed" - " up the emulation. This submenu lets"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "you choose whether to" - " skip frames and how many to skip."); - y += line_height; - break; - case OPT_VIDEO_SHOW_FPS: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Display the emulator's" - " current speed in frames per second"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "in the upper-right" - " corner of the screen."); - y += line_height; - break; - } - break; - - case MENU_RENDER: - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Configure hardware rendering settings"); - y = menu_center_y - (4*line_height + FONT_HEIGHT) / 2; - draw_menu_option(OPT_RENDER_CACHE_TEXTURES, menu_left_edge, y, - "[%c] Aggressively cache pixel data", - config_get_cache_textures() ? '*' : ' '); - y += line_height; - draw_menu_option(OPT_RENDER_SMOOTH_TEXTURES, menu_left_edge, y, - "[%c] Smooth textures and sprites", - config_get_smooth_textures() ? '*' : ' '); - y += line_height; - draw_menu_option(OPT_RENDER_SMOOTH_HIRES, menu_left_edge, y, - "[%c] Smooth high-resolution graphics", - config_get_smooth_hires() ? '*' : ' '); - y += line_height; - draw_menu_option(OPT_RENDER_ENABLE_ROTATE, menu_left_edge, y, - "[%c] Enable rotated/distorted graphics", - config_get_enable_rotate() ? '*' : ' '); - y += line_height; - draw_menu_option(OPT_RENDER_OPTIMIZE_ROTATE, menu_left_edge, y, - "[%c] Optimize rotated/distorted graphics", - config_get_optimize_rotate() ? '*' : ' '); - y = menu_help_y; - switch ((RenderMenuOption)cur_option) { - case OPT_RENDER_CACHE_TEXTURES: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Try to cache native" - " pixel data to speed up drawing."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "This may cause the" - " wrong graphics to be shown in"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "rare cases."); - y += line_height; - break; - case OPT_RENDER_SMOOTH_TEXTURES: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Apply smoothing" - " (antialiasing) to textures and sprites."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "This can reduce" - " jaggedness in 3-D environments, but may"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "also blur images" - " originally intended to look pixelated."); - y += line_height; - break; - case OPT_RENDER_SMOOTH_HIRES: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Apply smoothing to" - " high-resolution background graphics."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "This can make high" - "-resolution screens look clearer, but"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "may also slow down" - " the emulator."); - y += line_height; - break; - case OPT_RENDER_ENABLE_ROTATE: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Rotated or distorted" - " background graphics can slow down"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "the emulator" - " significantly. Disable this option to"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "turn them off."); - y += line_height; - break; - case OPT_RENDER_OPTIMIZE_ROTATE: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Some types of rotated" - " graphics can be drawn quickly,"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "at the expense of" - " accuracy. Disable this option to"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "always use the" - " accurate (but slow) drawing method."); - y += line_height; - break; - } - break; - - case MENU_FRAME_SKIP: - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Configure frame-skip settings"); - y = menu_center_y - (3*line_height + FONT_HEIGHT) / 2; - draw_menu_option(OPT_FRAME_SKIP_AUTO, menu_left_edge, y, - " Frame-skip mode: [%s]", - config_get_frameskip_auto() ? " Auto " : "Manual"); - y += line_height; - draw_menu_option(OPT_FRAME_SKIP_NUM, menu_left_edge, y, - " Number of frames to skip: [%d]", - config_get_frameskip_num()); - y += line_height; - draw_menu_option(OPT_FRAME_SKIP_INTERLACE, menu_left_edge, y, - "[%c] Limit to 30fps for interlaced display", - config_get_frameskip_interlace() ? '*' : ' '); - y += line_height; - draw_menu_option(OPT_FRAME_SKIP_ROTATE, menu_left_edge, y, - "[%c] Halve framerate for rotated backgrounds", - config_get_frameskip_rotate() ? '*' : ' '); - y = menu_help_y; - switch ((FrameSkipMenuOption)cur_option) { - case OPT_FRAME_SKIP_AUTO: - if (config_get_frameskip_auto()) { - font_printf(75, y, -1, TEXT_COLOR_INFO, "In Auto mode, the" - " emulator will automatically choose the"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "number of frames to" - " skip depending on the emulation speed."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "Note: Auto mode is" - " not currently implemented."); - y += line_height; - } else { - font_printf(75, y, -1, TEXT_COLOR_INFO, "In Manual mode, the" - " emulator will always skip the number"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "of frames set in" - " this menu."); - y += line_height; - } - break; - case OPT_FRAME_SKIP_NUM: - font_printf(75, y, -1, TEXT_COLOR_INFO, "The number of frames" - " to skip for every frame drawn when"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "Manual mode is" - " selected. 0 means \"draw every frame\","); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "1 means \"draw every" - " second frame\", and so on."); - y += line_height; - break; - case OPT_FRAME_SKIP_INTERLACE: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Always skip at least" - " one frame when drawing interlaced"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "(high-resolution)" - " screens. Has no effect unless the"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "\"number of frames" - " to skip\" is set to zero."); - y += line_height; - break; - case OPT_FRAME_SKIP_ROTATE: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Reduce the frame rate" - " by half when rotated or distorted"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "background graphics are" - " displayed."); - y += line_height; - break; - } - break; - - case MENU_ADVANCED: - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Configure advanced emulation options"); - y = menu_center_y - (6*(line_height-2) + 2*((line_height-2)/2) + FONT_HEIGHT) / 2; - draw_menu_option(OPT_ADVANCED_SH2_RECOMPILER, menu_left_edge, y, - "[%c] Use SH-2 recompiler", - config_get_module_sh2()==SH2CORE_PSP ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_ADVANCED_SH2_OPTIMIZE, menu_left_edge, y, - " Select SH-2 optimizations..."); - y += (line_height-2)*3/2; - if (me_available) { - draw_menu_option(OPT_ADVANCED_MEDIA_ENGINE, menu_left_edge, y, - " Configure Media Engine options..."); - } else { - draw_disabled_menu_option(OPT_ADVANCED_MEDIA_ENGINE, - menu_left_edge, y, - " Configure Media Engine options..."); - } - y += (line_height-2)*3/2; - draw_menu_option(OPT_ADVANCED_DECILINE_MODE, menu_left_edge, y, - "[%c] Use more precise emulation timing", - config_get_deciline_mode() ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_ADVANCED_AUDIO_SYNC, menu_left_edge, y, - "[%c] Sync audio output to emulation", - config_get_audio_sync() ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_ADVANCED_CLOCK_SYNC, menu_left_edge, y, - "[%c] Sync Saturn clock to emulation", - config_get_clock_sync() ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_ADVANCED_CLOCK_FIXED_TIME, menu_left_edge, y, - "[%c] Always start from 1998-01-01 12:00", - config_get_clock_fixed_time() ? '*' : ' '); - y = menu_help_y; - switch ((AdvancedMenuOption)cur_option) { - case OPT_ADVANCED_SH2_RECOMPILER: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Use the SH-2 recompiler" - " instead of the much slower"); - y += line_height; - x = font_printf(75, y, -1, TEXT_COLOR_INFO, "interpreter. "); - font_printf(x, y, -1, TEXT_COLOR_NG, "Changing this option will" - " reset the emulator."); - y += line_height; - break; - case OPT_ADVANCED_SH2_OPTIMIZE: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Enable or disable" - " specific optimizations used by the"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "SH-2 recompiler."); - y += line_height; - break; - case OPT_ADVANCED_MEDIA_ENGINE: - if (me_available) { - font_printf(75, y, -1, TEXT_COLOR_INFO, "Enable or disable" - " use of the PSP's Media Engine for"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "emulation, and" - " configure various parameters used by"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "the Media Engine."); - y += line_height; - } else { - font_printf(75, y, -1, TEXT_COLOR_NG, "The Media Engine access" - " library (me.prx) was not found,"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "so the Media Engine" - " cannot be used for emulation."); - y += line_height; - } - break; - case OPT_ADVANCED_DECILINE_MODE: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Increase the precision" - " of the emulator's execution timing."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "This slows down the" - " emulation, but may be required for"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "some games to work" - " correctly."); - y += line_height; - break; - case OPT_ADVANCED_AUDIO_SYNC: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Synchronize the" - " generated audio data with the emulation."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "This keeps the audio" - " and video in sync, but causes audio"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "dropouts when the" - " emulator runs slower than real time."); - y += line_height; - break; - case OPT_ADVANCED_CLOCK_SYNC: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Synchronize the" - " Saturn's internal clock with the"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "emulation, rather" - " than following real time regardless"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "of emulation speed."); - y += line_height; - break; - case OPT_ADVANCED_CLOCK_FIXED_TIME: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Start the Saturn's" - " internal clock at 1998-01-01 12:00"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "every time the" - " emulator is reset. Generally only"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "useful for debugging."); - y += line_height; - break; - } - break; - - case MENU_OPTIMIZE: { - const uint32_t optflags = config_get_sh2_optimizations(); - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Select SH-2 emulation optimizations"); - y = menu_center_y - (7*(line_height-2) + FONT_HEIGHT) / 2; - draw_menu_option(OPT_OPTIMIZE_ASSUME_SAFE_DIVISION, menu_left_edge, y, - "[%c] Assume safe division operations", - optflags & SH2_OPTIMIZE_ASSUME_SAFE_DIVISION ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_OPTIMIZE_FOLD_SUBROUTINES, menu_left_edge, y, - "[%c] Fold short subroutines into callers", - optflags & SH2_OPTIMIZE_FOLD_SUBROUTINES ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_OPTIMIZE_BRANCH_TO_RTS, menu_left_edge, y, - "[%c] Optimize branch/return pairs", - optflags & SH2_OPTIMIZE_BRANCH_TO_RTS ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_OPTIMIZE_LOCAL_ACCESSES, menu_left_edge, y, - "[%c] Optimize accesses to local data", - optflags & SH2_OPTIMIZE_LOCAL_ACCESSES ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_OPTIMIZE_POINTERS, menu_left_edge, y, - "[%c] Optimize pointer register accesses", - optflags & SH2_OPTIMIZE_POINTERS ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_OPTIMIZE_POINTERS_MAC, menu_left_edge, y, - " [%c] Try harder for MAC instructions", - optflags & SH2_OPTIMIZE_POINTERS_MAC ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_OPTIMIZE_LOCAL_POINTERS, menu_left_edge, y, - " [%c] Assume consistent local pointers", - optflags & SH2_OPTIMIZE_LOCAL_ACCESSES ? '*' : ' '); - y += line_height-2; - draw_menu_option(OPT_OPTIMIZE_STACK, menu_left_edge, y, - "[%c] Optimize stack accesses", - optflags & SH2_OPTIMIZE_STACK ? '*' : ' '); -#if 0 // FIXME: out of space on the screen - y += line_height-2; - draw_menu_option(OPT_OPTIMIZE_MAC_NOSAT, menu_left_edge, y, - "[%c] Optimize unsaturated multiplication", - optflags & SH2_OPTIMIZE_MAC_NOSAT ? '*' : ' '); -#endif - y = menu_help_y; - switch ((OptimizeMenuOption)cur_option) { - case OPT_OPTIMIZE_ASSUME_SAFE_DIVISION: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Speed up division" - " operations by assuming that quotients"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "will not overflow" - " and division by zero will not occur."); - y += line_height; - break; - case OPT_OPTIMIZE_FOLD_SUBROUTINES: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Fold (inline) short," - " simple subroutines into the"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "routines which call" - " them. May cause crashes"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "with games that use" - " self-modifying code."); - y += line_height; - break; - case OPT_OPTIMIZE_BRANCH_TO_RTS: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Speed up branches" - " which target RTS instructions."); - y += line_height; - break; - case OPT_OPTIMIZE_LOCAL_ACCESSES: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Detect and speed up" - " accesses to function-local data."); - y += line_height; - break; - case OPT_OPTIMIZE_POINTERS: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Detect SH-2 registers" - " which are used as data pointers,"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "and speed up memory" - " accesses through those registers."); - y += line_height; - break; - case OPT_OPTIMIZE_POINTERS_MAC: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Try harder to optimize" - " pointers to MAC (multiply-and-"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "accumulate) instructions." - " Ineffective unless pointer"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "optimizations are also" - " enabled."); - y += line_height; - break; - case OPT_OPTIMIZE_LOCAL_POINTERS: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Assume that pointers" - " loaded from local data or with a"); - y += line_height-2; - font_printf(75, y, -1, TEXT_COLOR_INFO, "MOVA instruction will" - " always access the same region of"); - y += line_height-2; - font_printf(75, y, -1, TEXT_COLOR_INFO, "memory. Ineffective" - " unless pointer and local data"); - y += line_height-2; - font_printf(75, y, -1, TEXT_COLOR_INFO, "optimizations are also" - " enabled."); - y += line_height-2; - break; - case OPT_OPTIMIZE_STACK: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Speed up accesses to" - " the SH-2 stack."); - y += line_height; - break; -#if 0 // FIXME: out of space on the screen - case OPT_OPTIMIZE_MAC_NOSAT: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Speed up multiply-and" - "-accumulate operations which are"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "known not to use" - " saturation."); - y += line_height; -#endif - } - break; - } - - case MENU_MEDIA_ENGINE: { - font_printf(DISPLAY_WIDTH/2, menu_title_y, 0, TEXT_COLOR_INFO, - "Configure Media Engine options"); - y = menu_center_y - (2*line_height + FONT_HEIGHT) / 2; - draw_menu_option(OPT_MEDIA_ENGINE_USE_ME, menu_left_edge, y, - "[%c] Use Media Engine for emulation", - config_get_use_me() ? '*' : ' '); - y += line_height; - draw_menu_option(OPT_MEDIA_ENGINE_WRITEBACK_PERIOD, menu_left_edge, y, - " Cache writeback frequency: [1/%-2u]", - config_get_me_writeback_period()); - y += line_height; - draw_menu_option(OPT_MEDIA_ENGINE_UNCACHED_BOUNDARY, menu_left_edge, y, - " Sound RAM write-through region: [%3uk]", - config_get_me_uncached_boundary() / 1024); - y = menu_help_y; - switch ((MediaEngineMenuOption)cur_option) { - case OPT_MEDIA_ENGINE_USE_ME: - font_printf(75, y, -1, TEXT_COLOR_INFO, "Use the Media Engine" - " CPU for emulation. This option"); - y += line_height; - x = font_printf(75, y, -1, TEXT_COLOR_INFO, "is "); - x = font_printf(x, y, -1, TEXT_COLOR_NG, "EXPERIMENTAL"); - font_printf(x, y, -1, TEXT_COLOR_INFO, "; see the manual" - " for details."); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_NG, "You must restart" - " Yabause after changing this option."); - y += line_height; - break; - case OPT_MEDIA_ENGINE_WRITEBACK_PERIOD: - font_printf(75, y, -1, TEXT_COLOR_INFO, "The relative" - " frequency of data cache synchronization when"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "using the Media" - " Engine for emulation. 1/1 is safest;"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "lower frequencies" - " may run faster, but may also crash."); - y += line_height; - break; - case OPT_MEDIA_ENGINE_UNCACHED_BOUNDARY: - font_printf(75, y, -1, TEXT_COLOR_INFO, "The size of the" - " region at the beginning of sound RAM"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "which is written" - " through the PSP's cache. Larger values"); - y += line_height; - font_printf(75, y, -1, TEXT_COLOR_INFO, "are safer but slower;" - " 2k should be good for most games."); - y += line_height; - break; - } - break; - } - - case MENU_YESNO: { - int nlines; - char buf[100]; - const char *s, *eol; - for (s = yesno_prompt; *s; s = eol+1) { - eol = s + strcspn(s, "\n"); - nlines++; - } - y = DISPLAY_HEIGHT/2 - ((nlines+1) * line_height + FONT_HEIGHT) / 2; - for (s = yesno_prompt; *s; s = eol+1, y += line_height) { - eol = s + strcspn(s, "\n"); - snprintf(buf, sizeof(buf), "%.*s", eol - s, s); - font_printf(DISPLAY_WIDTH/2, y, 0, TEXT_COLOR_INFO, buf); - } - y += line_height; - draw_menu_option(OPT_YESNO_YES, DISPLAY_WIDTH/2 - 45, y, "Yes"); - draw_menu_option(OPT_YESNO_NO, DISPLAY_WIDTH/2 + 30, y, "No"); - } - - } // switch (cur_menu) - - /* If a file selector is open, draw it */ - - if (filesel) { - filesel_draw(filesel); - } -} - -/*----------------------------------*/ - -/** - * cur_option_confirm_text: Return the text to be displayed for the - * "confirm" button help. - * - * [Parameters] - * None - * [Return value] - * String to display for the "confirm" button help - */ -static const char *cur_option_confirm_text(void) -{ - switch ((MenuIndex)cur_menu) { - case MENU_MAIN: - switch ((MainMenuOption)cur_option) { - case OPT_MAIN_SAVE: - return "O: Save settings"; - case OPT_MAIN_RESET: - return yabause_initted ? "L+R+O: Reset emulator" : ""; - default: - return "O: Enter submenu"; - } - case MENU_GENERAL: - switch ((GeneralMenuOption)cur_option) { - case OPT_GENERAL_FILES: - return "O: Enter submenu X: Return to previous menu"; - case OPT_GENERAL_BUP_SAVE_NOW: - case OPT_GENERAL_BUP_SAVE_AS: - if (yabause_initted) { - return "O: Save backup RAM X: Return to previous menu"; - } else { - return "X: Return to previous menu"; - } - default: - return "O: Toggle on/off X: Return to previous menu"; - } - case MENU_FILES: - return "O: Select file X: Return to previous menu"; - case MENU_BUTTON: - return "O/X/Triangle/Square: Assign button Start: Previous menu"; - case MENU_VIDEO: - switch ((VideoMenuOption)cur_option) { - case OPT_VIDEO_RENDER: - case OPT_VIDEO_FRAME_SKIP: - return "O: Enter submenu X: Return to previous menu"; - case OPT_VIDEO_SHOW_FPS: - return "O: Toggle on/off X: Return to previous menu"; - default: - return "O: Select X: Return to previous menu"; - } - case MENU_RENDER: - return "O: Toggle on/off X: Return to previous menu"; - case MENU_FRAME_SKIP: - switch ((FrameSkipMenuOption)cur_option) { - case OPT_FRAME_SKIP_AUTO: - return "O: Change setting X: Return to previous menu"; - case OPT_FRAME_SKIP_NUM: - return "Left/Right: Change setting X: Return to previous menu"; - default: - return "O: Toggle on/off X: Return to previous menu"; - } - case MENU_ADVANCED: - switch ((AdvancedMenuOption)cur_option) { - case OPT_ADVANCED_SH2_RECOMPILER: - return "L+R+O: Toggle on/off X: Return to previous menu"; - case OPT_ADVANCED_SH2_OPTIMIZE: - return "O: Enter submenu X: Return to previous menu"; - case OPT_ADVANCED_MEDIA_ENGINE: - if (me_available) { - return "O: Enter submenu X: Return to previous menu"; - } else { - return "X: Return to previous menu"; - } - default: - return "O: Toggle on/off X: Return to previous menu"; - } - case MENU_OPTIMIZE: - return "O: Toggle on/off X: Return to previous menu"; - case MENU_MEDIA_ENGINE: - switch ((FrameSkipMenuOption)cur_option) { - case OPT_MEDIA_ENGINE_USE_ME: - return "O: Change setting X: Return to previous menu"; - default: - return "Left/Right: Change setting X: Return to previous menu"; - } - case MENU_YESNO: - return "O: Confirm selection X: Cancel"; - } - DMSG("Invalid menu/option %d/%d", cur_menu, cur_option); - return "O: Confirm"; -} - -/*----------------------------------*/ - -/** - * draw_menu_option: Draw a single menu option. If the option is - * currently selected, also draws the menu cursor. - * - * [Parameters] - * option: Option ID (OPT_*) - * x, y: Text position - * format: Format string for option text - * ...: Format arguments - * [Return value] - * None - */ -static void draw_menu_option(int option, int x, int y, const char *format, ...) -{ - PRECOND(format != NULL, return); - - char buf[1000]; - va_list args; - va_start(args, format); - vsnprintf(buf, sizeof(buf), format, args); - va_end(args); - int x2 = font_printf(x, y, -1, TEXT_COLOR, "%s", buf); - - if (cur_option == option) { - const float cursor_alpha = - (sinf((cursor_timer / (float)CURSOR_PERIOD) * (float)M_TWOPI) + 1) - / 2; - const uint32_t cursor_alpha_byte = - floorf((CURSOR_COLOR>>24 & 0xFF) * cursor_alpha + 0.5f); - display_fill_box(x-2, y-2, x2+1, (y+FONT_HEIGHT)+1, - cursor_alpha_byte<<24 | (CURSOR_COLOR & 0x00FFFFFF)); - } -} - -/*----------------------------------*/ - -/** - * draw_disabled_menu_option: Draw a single disabled menu option. If the - * option is currently selected, also draws the menu cursor. - * - * [Parameters] - * option: Option ID (OPT_*) - * x, y: Text position - * format: Format string for option text - * ...: Format arguments - * [Return value] - * None - */ -static void draw_disabled_menu_option(int option, int x, int y, - const char *format, ...) -{ - PRECOND(format != NULL, return); - - char buf[1000]; - va_list args; - va_start(args, format); - vsnprintf(buf, sizeof(buf), format, args); - va_end(args); - int x2 = font_printf(x, y, -1, TEXT_COLOR_DISABLED, "%s", buf); - - if (cur_option == option) { - const float cursor_alpha = - (sinf((cursor_timer / (float)CURSOR_PERIOD) * (float)M_TWOPI) + 1) - / 2; - const uint32_t cursor_alpha_byte = - floorf((CURSOR_COLOR>>24 & 0xFF) * cursor_alpha + 0.5f); - display_fill_box(x-2, y-2, x2+1, (y+FONT_HEIGHT)+1, - cursor_alpha_byte<<24 | (CURSOR_COLOR & 0x00FFFFFF)); - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/menu.h b/yabause/src/psp/menu.h deleted file mode 100644 index 936f685b7a..0000000000 --- a/yabause/src/psp/menu.h +++ /dev/null @@ -1,79 +0,0 @@ -/* src/psp/menu.h: PSP menu interface header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_MENU_H -#define PSP_MENU_H - -/*************************************************************************/ - -/** - * menu_open: Open the menu interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void menu_open(void); - -/** - * menu_run: Perform a single frame's processing for the menu interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void menu_run(void); - -/** - * menu_close: Close the menu interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void menu_close(void); - -/** - * menu_set_error: Set an error message to be displayed on the menu - * screen. If message is NULL, any message currently displayed is cleared. - * - * [Parameters] - * message: Message text (NULL to clear current message) - * [Return value] - * None - */ -extern void menu_set_error(const char *message); - -/*************************************************************************/ - -#endif // PSP_MENU_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/misc.c b/yabause/src/psp/misc.c deleted file mode 100644 index efe5c7a81a..0000000000 --- a/yabause/src/psp/misc.c +++ /dev/null @@ -1,119 +0,0 @@ -/* src/psp/misc.c: PSP support routines - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../memory.h" - -#include "config.h" -#include "misc.h" -#include "sys.h" - -/*************************************************************************/ -/************************** Interface routines ***************************/ -/*************************************************************************/ - -/** - * save_backup_ram: Save the contents of backup RAM to the configured - * file. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on failure - */ -extern int save_backup_ram(void) -{ - const char *path = config_get_path_bup(); - if (!path || !*path) { - DMSG("No backup RAM file configured!"); - goto error_return; - } - - /* Lock the power switch while writing so the user (hopefully) can't - * shut the PSP off on us. */ - scePowerLock(0); - - int fd = sceIoOpen(path, PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0600); - if (fd < 0) { - DMSG("open(%s): %s", path, psp_strerror(fd)); - goto error_unlock_power; - } - - int res = sceIoWrite(fd, BupRam, 0x10000); - if (res != 0x10000) { - DMSG("write(%s): %s", path, psp_strerror(fd)); - sceIoClose(fd); - goto error_unlock_power; - } - - res = sceIoClose(fd); - if (res != 0) { - DMSG("close(%s): %s", path, psp_strerror(fd)); - goto error_unlock_power; - } - - /* All done--don't forget to unlock the power switch before returning! */ - scePowerUnlock(0); - return 1; - - error_unlock_power: - scePowerUnlock(0); - error_return: - return 0; -} - -/*************************************************************************/ - -/** - * psp_writeback_cache_for_scsp: Write back all dirty data from the SC's - * cache for an ScspExec() call, depending on the writeback frequency - * selected by the user. - * - * [Parameters] - * None - * [Return value] - * Nonzero if writeback was executed, zero if writeback was skipped - */ -int psp_writeback_cache_for_scsp(void) -{ - static uint32_t counter; - - counter++; - if (!(counter & (config_get_me_writeback_period() - 1))) { - sceKernelDcacheWritebackAll(); - return 1; - } else { - return 0; - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/misc.h b/yabause/src/psp/misc.h deleted file mode 100644 index 8918620ab5..0000000000 --- a/yabause/src/psp/misc.h +++ /dev/null @@ -1,104 +0,0 @@ -/* src/psp/misc.h: PSP support routine header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_MISC_H -#define PSP_MISC_H - -/*************************************************************************/ - -/** - * save_backup_ram: Save the contents of backup RAM to the configured - * file. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on failure - */ -extern int save_backup_ram(void); - -/** - * psp_writeback_cache_for_scsp: Write back all dirty data from the SC's - * cache for an ScspExec() call, depending on the writeback frequency - * selected by the user. - * - * [Parameters] - * None - * [Return value] - * Nonzero if writeback was skipped, zero if writeback was executed - */ -extern int psp_writeback_cache_for_scsp(void); - -/*-----------------------------------------------------------------------*/ - -/** - * checksum_fast16, checksum_fast32: Perform a fast checksum of 16-bit or - * 32-bit words in a block by simply summing all words and returning the - * cumulative 32-bit total. - * - * [Parameters] - * ptr: Pointer to memory block to checksum - * count: Number of 16-bit or 32-bit words in block - * [Return value] - * Block checksum - */ -static inline uint32_t checksum_fast16(const uint16_t *ptr, unsigned int count) -{ - uint32_t sum = 0; - for (; count >= 4; count -= 4) { - sum += *ptr++; - sum += *ptr++; - sum += *ptr++; - sum += *ptr++; - } - while (count--) { - sum += *ptr++; - } - return sum; -} - -static inline uint32_t checksum_fast32(const uint32_t *ptr, unsigned int count) -{ - uint32_t sum = 0; - for (; count >= 4; count -= 4) { - sum += *ptr++; - sum += *ptr++; - sum += *ptr++; - sum += *ptr++; - } - while (count--) { - sum += *ptr++; - } - return sum; -} - -/*************************************************************************/ - -#endif // PSP_MISC_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/osk.c b/yabause/src/psp/osk.c deleted file mode 100644 index 0e352d5190..0000000000 --- a/yabause/src/psp/osk.c +++ /dev/null @@ -1,479 +0,0 @@ -/* src/psp/osk.c: PSP on-screen keyboard management - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "osk.h" -#include "sys.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Is the on-screen keyboard active? */ -static uint8_t osk_active; - -/* Has a close been requested? */ -static uint8_t osk_closing; - -/* Parameter block pointer (only valid when osk_active != 0). Pointers to - * subsidiary data structures such as string buffers are stored within the - * appropriate parent data structure. */ -static SceUtilityOskParams *osk_params; - -/*-----------------------------------------------------------------------*/ - -/* Local function declarations. */ -static void reset_osk(void); -static uint16_t *utf8to16(const char *str); -static char *utf16to8(const uint16_t *str); - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * osk_open: Open the on-screen keyboard with the given prompt string and - * default text. - * - * [Parameters] - * prompt: Prompt string - * deftext: Default text - * maxlen: Maximum length (number of _characters_, not bytes) of - * entered text, not including the trailing null - * [Return value] - * Nonzero on success, zero on failure - */ -int osk_open(const char *prompt, const char *deftext, unsigned int maxlen) -{ - PRECOND(prompt != NULL, goto error_return); - PRECOND(deftext != NULL, goto error_return); - PRECOND(maxlen > 0, goto error_return); - PRECOND(strlen(deftext) <= maxlen, goto error_return); - - if (osk_active) { - DMSG("Tried to start a second OSK while one was already active!"); - goto error_return; - } - - osk_params = calloc(1, sizeof(*osk_params)); - if (!osk_params) { - DMSG("No memory for osk_params"); - goto error_return; - } - osk_params->base.size = sizeof(*osk_params); - osk_params->base.graphicsThread = THREADPRI_UTILITY + 1; - osk_params->base.accessThread = THREADPRI_UTILITY + 3; - osk_params->base.fontThread = THREADPRI_UTILITY + 2; - osk_params->base.soundThread = THREADPRI_UTILITY; - osk_params->datacount = 1; - - osk_params->data = calloc(1, sizeof(*osk_params->data)); - if (!osk_params->data) { - DMSG("No memory for data"); - goto error_free_osk_params; - } - osk_params->data->language = PSP_UTILITY_OSK_LANGUAGE_ENGLISH; - osk_params->data->inputtype = PSP_UTILITY_OSK_INPUTTYPE_LATIN_UPPERCASE - | PSP_UTILITY_OSK_INPUTTYPE_LATIN_LOWERCASE - | PSP_UTILITY_OSK_INPUTTYPE_LATIN_DIGIT - | PSP_UTILITY_OSK_INPUTTYPE_LATIN_SYMBOL; - osk_params->data->lines = 1; - /* The order of these field names is apparently reversed in the current - * (r2493) PSPSDK. Set both to maxlen+1 just to be safe; the null - * terminator in "deftext" will keep the OSK from overrunning the end - * of the default text. */ - osk_params->data->outtextlength = maxlen + 1; - osk_params->data->outtextlimit = maxlen + 1; - - osk_params->data->desc = utf8to16(prompt); - if (!osk_params->data->desc) { - DMSG("No memory for prompt buffer"); - goto error_free_data; - } - - osk_params->data->intext = utf8to16(deftext); - if (!osk_params->data->intext) { - DMSG("No memory for default text buffer"); - goto error_free_desc; - } - - osk_params->data->outtext = malloc(2 * (maxlen + 1)); - if (!osk_params->data->outtext) { - DMSG("No memory for output text buffer"); - goto error_free_intext; - } - - int res = sceUtilityOskInitStart(osk_params); - if (res < 0) { - DMSG("sceUtilityOskInitStart() failed: %s", psp_strerror(res)); - return 0; - } - - osk_active = 1; - osk_closing = 0; - return 1; - - error_free_intext: - free(osk_params->data->intext); - error_free_desc: - free(osk_params->data->desc); - error_free_data: - free(osk_params->data); - error_free_osk_params: - free(osk_params); - osk_params = NULL; - error_return: - return 0; -} - -/*************************************************************************/ - -/** - * osk_update: Update the on-screen keyboard if it is active. Must be - * called once per frame while the on-screen keyboard is active; may be - * called at any other time (the function does nothing in that case). - * - * [Parameters] - * None - * [Return value] - * None - */ -void osk_update(void) -{ - if (osk_active) { - const int status = sceUtilityOskGetStatus(); - if (status == PSP_UTILITY_DIALOG_VISIBLE) { - int res = sceUtilityOskUpdate(1); - if (res < 0) { - DMSG("sceUtilityOskUpdate() failed: %s", psp_strerror(res)); - } - } else if (sceUtilityOskGetStatus() == PSP_UTILITY_DIALOG_QUIT) { - sceUtilityOskShutdownStart(); - } else if (sceUtilityOskGetStatus() == PSP_UTILITY_DIALOG_FINISHED) { - if (osk_closing) { - reset_osk(); - } - } - } -} - -/*************************************************************************/ - -/** - * osk_status: Return whether the on-screen keyboard is currently active. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the on-screen keyboard is active, else zero - */ -int osk_status(void) -{ - return osk_active; -} - -/*************************************************************************/ - -/** - * osk_result: Return the result status from the on-screen keyboard. - * - * [Parameters] - * None - * [Return value] - * Result status (OSK_RESULT_*) - */ -OSKResult osk_result(void) -{ - if (!osk_active || osk_closing) { - return OSK_RESULT_NONE; - } else if (sceUtilityOskGetStatus() != PSP_UTILITY_DIALOG_FINISHED) { - return OSK_RESULT_RUNNING; - } else if (osk_params->data->result == PSP_UTILITY_OSK_RESULT_UNCHANGED) { - return OSK_RESULT_UNCHANGED; - } else if (osk_params->data->result == PSP_UTILITY_OSK_RESULT_CHANGED) { - return OSK_RESULT_CHANGED; - } else if (osk_params->data->result == PSP_UTILITY_OSK_RESULT_CANCELLED) { - return OSK_RESULT_CANCELLED; - } else { - DMSG("Weird result value %d from OSK", osk_params->data->result); - return OSK_RESULT_ERROR; - } -} - -/*************************************************************************/ - -/** - * osk_get_text: Return the text entered by the user from the on-screen - * keyboard in a newly malloc()ed buffer. - * - * [Parameters] - * None - * [Return value] - * Entered text, or NULL if not available (e.g., if the OSK was cancelled) - */ -char *osk_get_text(void) -{ - int result = osk_result(); - if (result != OSK_RESULT_UNCHANGED && result != OSK_RESULT_CHANGED) { - return NULL; - } - - char *text = utf16to8(osk_params->data->outtext); - if (!text) { - DMSG("Failed to convert entered text to UTF-8"); - return NULL; - } - - return text; -} - -/*************************************************************************/ - -/** - * osk_close: Close the on-screen keyboard and discard all associated - * resources (including the entered text). If the on-screen keyboard is - * not active, this function does nothing. - * - * Even after calling this function, the caller MUST continue to call - * osk_update() once per frame until osk_status() returns zero. - * - * [Parameters] - * None - * [Return value] - * None - */ -void osk_close(void) -{ - if (osk_active) { - if (sceUtilityOskGetStatus() == PSP_UTILITY_DIALOG_FINISHED) { - /* Free all resources immediately. */ - reset_osk(); - } else { - /* Request a close, and free resources when the OS is done. */ - sceUtilityOskShutdownStart(); - osk_closing = 1; - } - } -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * reset_osk: Free all local resources and reset the OSK to the inactive - * state. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void reset_osk(void) -{ - PRECOND(osk_active, return); - - free(osk_params->data->outtext); - free(osk_params->data->intext); - free(osk_params->data->desc); - free(osk_params->data); - free(osk_params); - osk_params = NULL; - osk_closing = 0; - osk_active = 0; -} - -/*************************************************************************/ - -/** - * utf8to16, utf16to8: Convert a string between 8-bit and 16-bit Unicode - * formats. The returned string is stored in a newly malloc()ed buffer. - * - * [Parameters] - * str: String to convert - * [Return value] - * Converted string, or NULL on error - * [Notes] - * These functions only support Unicode characters with codepoints in - * the range 0-65535 (16-bit characters). - */ -static uint16_t *utf8to16(const char *str) -{ - /* Allocate a buffer big enough for the longest possible result; we'll - * shrink it if necessary when we're done. */ - const uint32_t bufsize = (strlen(str) + 1) * 2; - uint16_t *out = malloc(bufsize); - if (!out) { - DMSG("Can't allocate %u bytes", bufsize); - return NULL; - } - - /* Convert the string, character by character. */ - uint32_t pos = 0, len = 0; - while (str[pos] != 0) { - const uint8_t ch = (uint8_t)str[pos++]; - if (ch < 0x80) { - out[len++] = ch; - } else if (ch < 0xC0) { - /* Continuation bytes are invalid as the first byte of a UTF-8 - * sequence. */ - DMSG("Invalid continuation byte 0x%02X at offset %u", ch, pos-1); - goto fail; - } else if (ch < 0xE0) { - const uint8_t ch_1 = (uint8_t)str[pos++]; - if (ch_1 < 0x80 || ch_1 >= 0xC0) { - /* The required continuation byte is missing, so treat this - * character as unknown and restart processing on the - * second byte (which we just checked). */ - DMSG("Missing continuation byte at offset %u (got 0x%02X)", - pos-1, ch_1); - goto fail; - } else if (ch < 0xC2) { - /* Characters with codepoints less than 128 must be coded - * using the single-byte format; for example, C1 9C for the - * backslash character (U+005C) is invalid. This is a - * common attack vector against security vulnerabilities, - * so we explicitly disallow such invalid forms. */ - DMSG("Invalid extended form 0x%02X 0x%02X at offset %u", - pos-2, ch, ch_1); - goto fail; - } else { - out[len++] = (ch & 0x1F) << 6 - | (ch_1 & 0x3F) << 0; - } - } else if (ch < 0xF0) { - const uint8_t ch_1 = (uint8_t)str[pos++]; - const uint8_t ch_2 = (uint8_t)str[pos++]; - if (ch_1 < 0x80 || ch_1 >= 0xC0) { - DMSG("Missing continuation byte at offset %u (got 0x%02X)", - pos-2, ch_1); - goto fail; - } else if (ch_2 < 0x80 || ch_2 >= 0xC0) { - DMSG("Missing continuation byte at offset %u (got 0x%02X)", - pos-1, ch_2); - goto fail; - } else if (ch == 0xE0 && ch_1 < 0xA0) { - DMSG("Invalid extended form 0x%02X 0x%02X 0x%02X at offset %u", - pos-3, ch, ch_1, ch_2); - goto fail; - } else { - out[len++] = (ch & 0x0F) << 12 - | (ch_1 & 0x3F) << 6 - | (ch_2 & 0x3F) << 0; - if (out[len-1] >= 0xD800 && out[len-1] < 0xE000) { - DMSG("Invalid surrogate 0x%04X at offset %u", - out[len-1], pos-3); - goto fail; - } - } - } else { - DMSG("Out-of-range codepoint with first byte 0x%02X at offset %u", - ch, pos-1); - goto fail; - } - } - - /* Append a terminating null. */ - out[len++] = 0; - - /* If we ended up with fewer characters than we allocated space for, - * shrink the output buffer before returning it. */ - if (len*2 < bufsize) { - /* This should never fail, but just in case, save the result in a - * temporary variable and check for NULL first. */ - uint16_t *new_out = realloc(out, len*2); - if (new_out) { - out = new_out; - } - } - - return out; - - fail: - free(out); - return NULL; -} - -/*----------------------------------*/ - -static char *utf16to8(const uint16_t *str) -{ - /* strlen() only works on byte streams, so we have to calculate the - * input string length manually. */ - uint32_t str_len = 0; - while (str[str_len] != 0) { - str_len++; - } - - const uint32_t bufsize = str_len*3 + 1; - char *out = malloc(bufsize); - if (!out) { - DMSG("Can't allocate %u bytes", bufsize); - return NULL; - } - - uint32_t pos = 0, len = 0; - while (str[pos] != 0) { - const uint16_t ch = str[pos++]; - if (ch < 0x80) { - out[len++] = ch; - } else if (ch < 0x800) { - out[len++] = 0xC0 | (ch>>6 & 0x1F); - out[len++] = 0x80 | (ch>>0 & 0x3F); - } else if (ch >= 0xD800 && ch < 0xE000) { - DMSG("Surrogate 0x%04X found at offset %u (not supported)", - ch, pos-1); - goto fail; - } else { - out[len++] = 0xE0 | (ch>>12 & 0x0F); - out[len++] = 0x80 | (ch>> 6 & 0x3F); - out[len++] = 0x80 | (ch>> 0 & 0x3F); - } - } - - out[len++] = 0; - - if (len < bufsize) { - char *new_out = realloc(out, len); - if (new_out) { - out = new_out; - } - } - - return out; - - fail: - free(out); - return NULL; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/osk.h b/yabause/src/psp/osk.h deleted file mode 100644 index 342a04fcc5..0000000000 --- a/yabause/src/psp/osk.h +++ /dev/null @@ -1,124 +0,0 @@ -/* src/psp/osk.h: PSP on-screen keyboard management header - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_OSK_H -#define PSP_OSK_H - -/*************************************************************************/ - -/* Result codes returned from osk_result(). */ - -typedef enum OSKResult_ { - OSK_RESULT_NONE = 0, - OSK_RESULT_RUNNING, - OSK_RESULT_UNCHANGED, - OSK_RESULT_CHANGED, - OSK_RESULT_CANCELLED, - OSK_RESULT_ERROR, -} OSKResult; - -/*-----------------------------------------------------------------------*/ - -/** - * osk_open: Open the on-screen keyboard with the given prompt string and - * default text. - * - * [Parameters] - * prompt: Prompt string - * deftext: Default text - * maxlen: Maximum length (number of _characters_, not bytes) of - * entered text, not including the trailing null - * [Return value] - * Nonzero on success, zero on failure - */ -extern int osk_open(const char *prompt, const char *deftext, - unsigned int maxlen); - -/** - * osk_update: Update the on-screen keyboard if it is active. Must be - * called once per frame while the on-screen keyboard is active; may be - * called at any other time (the function does nothing in that case). - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void osk_update(void); - -/** - * osk_status: Return whether the on-screen keyboard is currently active. - * - * [Parameters] - * None - * [Return value] - * Nonzero if the on-screen keyboard is active, else zero - */ -extern int osk_status(void); - -/** - * osk_result: Return the result status from the on-screen keyboard. - * - * [Parameters] - * None - * [Return value] - * Result status (OSK_RESULT_*) - */ -extern OSKResult osk_result(void); - -/** - * osk_get_text: Return the text entered by the user from the on-screen - * keyboard in a newly malloc()ed buffer. - * - * [Parameters] - * None - * [Return value] - * Entered text, or NULL if not available (e.g., if the OSK was cancelled) - */ -extern char *osk_get_text(void); - -/** - * osk_close: Close the on-screen keyboard and discard all associated - * resources (including the entered text). If the on-screen keyboard is - * not active, this function does nothing. - * - * Even after calling this function, the caller MUST continue to call - * osk_update() once per frame until osk_status() returns zero. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void osk_close(void); - -/*************************************************************************/ - -#endif // PSP_OSK_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/profile.c b/yabause/src/psp/profile.c deleted file mode 100644 index 0e5e4b8746..0000000000 --- a/yabause/src/psp/profile.c +++ /dev/null @@ -1,233 +0,0 @@ -/* src/psp/profile.c: Profiling support for Yabause core - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifdef SYS_PROFILE_H // i.e. profiling enabled -- continues to end of file - -#include -#include -#include -#include "profile.h" - -/*************************************************************************/ - -/* Names for each tracking slot */ -const char * const prof_names[PROF__END] = { - [PROF__UNKNOWN ] = "(unknown)", - [PROF_Total_Emulation] = "Total Emulation", - [PROF_MSH2 ] = "MSH2", - [PROF_68K ] = "68K", - [PROF_SCSP ] = "SCSP", - [PROF_SCU ] = "SCU", - [PROF_SSH2 ] = "SSH2", - [PROF_CDB ] = "CDB", - [PROF_CDIO ] = "CDIO", - [PROF_SMPC ] = "SMPC", - [PROF_hblankin ] = "hblankin", - [PROF_hblankout ] = "hblankout", - [PROF_VDP1_VDP2 ] = "VDP1/VDP2", - [PROF_vblankin ] = "vblankin", - [PROF__OVERHEAD ] = "(profiling overhead)", -}; - -/* Latest start time for each tracking slot */ -static uint32_t prof_start[PROF__END]; - -/* Total run time (microseconds) for each tracking slot */ -static uint64_t prof_total[PROF__END]; - -/* Number of calls for each tracking slot */ -static uint32_t prof_calls[PROF__END]; - -/* Approximate profiling overhead per call (microseconds) */ -static double prof_overhead = 0; -/* Profiling overhead per call that appears in slot totals (microseconds) */ -static double visible_overhead = 0; - -/*************************************************************************/ -/*************************************************************************/ - -/** - * psp_profile_reset: Reset all profiling counters. - * - * [Parameters] - * None - * [Return value] - * None - */ -void psp_profile_reset(void) -{ - memset(prof_start, 0, sizeof(prof_start)); - memset(prof_total, 0, sizeof(prof_total)); - memset(prof_calls, 0, sizeof(prof_calls)); -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_profile_start: Start the profile timer for the given slot with the - * given timestamp. - * - * [Parameters] - * slot: Tracking slot (0..PROF__END-1) - * timestamp: 32-bit system timestamp from sceKernelGetSystemTimeLow() - * [Return value] - * None - */ -__attribute__((noinline)) // To avoid throwing off overhead measurements -void psp_profile_start(int slot, uint32_t timestamp) -{ - /* Make sure this runs quickly, since it counts against the slot's run - * time */ - prof_start[slot] = timestamp; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_profile_stop: Stop the profile timer for the given slot, and update - * the call count and total run time. - * - * [Parameters] - * slot: Tracking slot (0..PROF__END-1) - * timestamp: 32-bit system timestamp from sceKernelGetSystemTimeLow() - * [Return value] - * None - * [Notes] - * The run time for a single call must not exceed 2^32-1 microseconds - * (about 71.5 minutes), or the profiling totals will be inaccurate. - */ -__attribute__((noinline)) -void psp_profile_stop(int slot, uint32_t timestamp) -{ - const uint32_t run_time = timestamp - prof_start[slot]; - prof_total[slot] += run_time; - prof_calls[slot]++; -} - -/*************************************************************************/ - -/** - * psp_profile_print: Print profiling statistics. Information for each slot - * with a nonzero call count is printed on one line, sorted in descending - * order by total run time. - * - * [Parameters] - * None - * [Return value] - * None - */ -void psp_profile_print(void) -{ - int order[PROF__END]; - double usec[PROF__END]; - int num_slots = 0; - int i, j; - - /* First calculate the approximate profiling overhead per call, if we - * haven't done so already */ - if (!prof_overhead) { - uint32_t start = sceKernelGetSystemTimeLow(); - for (i = 0; i < 1000; i++) { - psp_profile_start(PROF__OVERHEAD, sceKernelGetSystemTimeLow()); - psp_profile_stop(PROF__OVERHEAD, sceKernelGetSystemTimeLow()); - } - uint32_t end = sceKernelGetSystemTimeLow(); - prof_overhead = (end - start) / 1000.0; - - uint32_t visible_sum = 0; - for (i = 0; i < 1000; i++) { - uint32_t this_time = sceKernelGetSystemTimeLow(); - psp_profile_start(PROF__OVERHEAD, this_time); - visible_sum += sceKernelGetSystemTimeLow() - this_time; - } - visible_overhead = visible_sum / 1000.0; - } - - /* Find which slots need to be printed, and calculate their data along - * with total overhead */ - uint32_t total_calls = 0; - double total_overhead = 0; - for (i = 0; i < PROF__OVERHEAD; i++) { - if (prof_calls[i] > 0) { - order[num_slots++] = i; - if (i == PROF_Total_Emulation) { - /* We'll subtract the total overhead from this value once - * we know it */ - usec[i] = (double)prof_total[i]; - } else { - const double overhead = visible_overhead * prof_calls[i]; - usec[i] = (double)prof_total[i] - overhead; - } - } - total_calls += prof_calls[i]; - total_overhead += prof_overhead * prof_calls[i]; - } - /* Invisible overhead from the PROF_Total_Emulation slot isn't included - * in the first place, so don't try to subtract it out */ - total_overhead -= (prof_overhead - visible_overhead) - * prof_calls[PROF_Total_Emulation]; - usec[PROF_Total_Emulation] -= total_overhead; - - /* Sort the slots by total run time. There aren't many slots, so a - * selection sort will do fine */ - for (i = 0; i < num_slots-1; i++) { - int best = i; - for (j = i+1; j < num_slots; j++) { - if (usec[order[j]] > usec[order[best]]) { - best = j; - } - } - if (best != i) { - const int tmp = order[i]; - order[i] = order[best]; - order[best] = tmp; - } - } - - /* Print out the sorted info, adjusting for overhead */ - printf(" Calls Total (s) usec/call %% of max Name\n"); - const double max_usec = usec[order[0]]; - for (i = 0; i < num_slots; i++) { - const double sec = usec[order[i]] / 1000000.0; - const double avg = (sec / prof_calls[order[i]]) * 1000000.0; - const double pct= (usec[order[i]] / max_usec) * 100.0; - printf("%8u %9.3f %9.2f %5.1f%% %s\n", - prof_calls[order[i]], sec, avg, pct, prof_names[order[i]]); - } - printf("%8u %9.3f %9.2f %5.1f%% %s\n", - total_calls, total_overhead / 1000000.0, - (total_overhead / total_calls), - (total_overhead / max_usec) * 100.0, "(profiling overhead)"); -} - -/*************************************************************************/ -/*************************************************************************/ - -#endif // #ifdef SYS_PROFILE_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/profile.h b/yabause/src/psp/profile.h deleted file mode 100644 index 3a0bc8460f..0000000000 --- a/yabause/src/psp/profile.h +++ /dev/null @@ -1,106 +0,0 @@ -/* src/psp/profile.h: Profiling header for Yabause core - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_PROFILE_H -#define PSP_PROFILE_H - -#include // for sceKernelGetSystemTimeLow() - -/*************************************************************************/ - -/* Tracking slots */ -enum { - PROF__UNKNOWN = 0, // For any non-matching name - PROF_Total_Emulation, - PROF_MSH2, - PROF_68K, - PROF_SCSP, - PROF_SCU, - PROF_SSH2, - PROF_CDB, - PROF_CDIO, - PROF_SMPC, - PROF_hblankin, - PROF_hblankout, - PROF_VDP1_VDP2, - PROF_vblankin, - PROF__OVERHEAD, // Internal use only (for calculating profiling overhead) - PROF__END -}; - -/*-----------------------------------------------------------------------*/ - -/* Helper macro that converts string parameters to PROFILE_{START,STOP}() - * into PROF_* indices. Note that as long as the parameter is a string - * literal, compiler optimization will convert the whole thing into a - * single compile-time constant. */ - -#define PROFILE_INDEX(name) \ - (strcmp((name),"Total Emulation") == 0 ? PROF_Total_Emulation : \ - strcmp((name),"MSH2" ) == 0 ? PROF_MSH2 : \ - strcmp((name),"68K" ) == 0 ? PROF_68K : \ - strcmp((name),"SCSP" ) == 0 ? PROF_SCSP : \ - strcmp((name),"SCU" ) == 0 ? PROF_SCU : \ - strcmp((name),"SSH2" ) == 0 ? PROF_SSH2 : \ - strcmp((name),"CDB" ) == 0 ? PROF_CDB : \ - strcmp((name),"CDIO" ) == 0 ? PROF_CDIO : \ - strcmp((name),"SMPC" ) == 0 ? PROF_SMPC : \ - strcmp((name),"hblankin" ) == 0 ? PROF_hblankin : \ - strcmp((name),"hblankout" ) == 0 ? PROF_hblankout : \ - strcmp((name),"VDP1/VDP2" ) == 0 ? PROF_VDP1_VDP2 : \ - strcmp((name),"vblankin" ) == 0 ? PROF_vblankin : \ - PROF__UNKNOWN) - -/*-----------------------------------------------------------------------*/ - -/* Macros called by the Yabause core. */ - -#define PROFILE_START(name) \ - psp_profile_start(PROFILE_INDEX((name)), sceKernelGetSystemTimeLow()) - -#define PROFILE_STOP(name) \ - psp_profile_stop(PROFILE_INDEX((name)), sceKernelGetSystemTimeLow()) - -#define PROFILE_PRINT() psp_profile_print() - -#define PROFILE_RESET() psp_profile_reset() - -/*-----------------------------------------------------------------------*/ - -/* Function declarations */ - -extern void psp_profile_reset(void); -extern void psp_profile_start(int slot, uint32_t timestamp); -extern void psp_profile_stop(int slot, uint32_t timestamp); -extern void psp_profile_print(void); - -/*************************************************************************/ - -#endif // PSP_PROFILE_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-cd.c b/yabause/src/psp/psp-cd.c deleted file mode 100644 index da56e64c64..0000000000 --- a/yabause/src/psp/psp-cd.c +++ /dev/null @@ -1,952 +0,0 @@ -/* src/psp/psp-cd.c: PSP virtual CD interface module - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../cdbase.h" - -#include "psp-cd.h" -#include "sys.h" - -#ifdef SYS_PROFILE_H -# include "profile.h" // Can only be our own -#else -# define DONT_PROFILE -# include "../profile.h" -#endif - -/*************************************************************************/ -/************************* Interface definition **************************/ -/*************************************************************************/ - -/* Interface function declarations (must come before interface definition) */ - -static int psp_cd_init(const char *path); -static void psp_cd_deinit(void); -static int psp_cd_get_status(void); -static s32 psp_cd_read_toc(u32 *toc_buffer); -static int psp_cd_read_sector(u32 sector, void *buffer); -static void psp_cd_read_ahead(u32 sector); - -/*-----------------------------------------------------------------------*/ - -/* Module interface definition */ - -CDInterface CDPSP = { - .id = CDCORE_PSP, - .Name = "PSP Virtual CD Interface", - .Init = psp_cd_init, - .DeInit = psp_cd_deinit, - .GetStatus = psp_cd_get_status, - .ReadTOC = psp_cd_read_toc, - .ReadSectorFAD = psp_cd_read_sector, - .ReadAheadFAD = psp_cd_read_ahead, -}; - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* File descriptor for ISO image (0 = none open) */ -static int iso_fd; - -/* Table-of-contents data for ISO image */ -static uint32_t iso_toc[102]; - -/* Sector indices and corresponding file offsets for each track */ -static struct { - uint32_t first_sector; // First sector in track (0 = nonexistent track) - uint32_t last_sector; // Last sector in track (inclusive) - uint32_t file_offset; // File offset of first sector, in bytes - uint32_t sector_size; // Size of each sector in the track, in bytes -} tracks[99]; // tracks[0] = track 1, tracks[1] = track 2, etc. - -/*----------------------------------*/ - -/* Read-ahead buffers and sectors loaded into them. We read multiple - * sectors at once to minimize the overhead from system calls. */ - -#define READ_UNIT 8 // Number of sectors to read at once - -static __attribute__((aligned(16))) - uint8_t readahead_buffer[READ_UNIT*2][2352]; -static uint32_t readahead_sector[READ_UNIT*2]; - -/*----------------------------------*/ - -/* CD read thread ID */ -static int cd_read_thid; - -/* Variables for communication with CD read thread (see cd_read_thread() - * documentation for details) */ -static volatile uint8_t cd_read_idle; -static volatile uint8_t cd_read_requested; -static volatile uint8_t cd_read_terminate; -static volatile uint8_t cd_read_index; -static volatile uint32_t cd_read_sector; - -/*-----------------------------------------------------------------------*/ - -/* Local function declarations */ - -static int examine_iso(int fd); -static int examine_cue(int fd); -static int32_t msf_to_sector(const char *msf); - -static void cd_read_thread(void); - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * psp_cd_init: Initialize the virtual CD interface. - * - * [Parameters] - * path: Pathname for physical device to associate with virtual CD drive - * [Return value] - * Zero on success, negative on error - */ -static int psp_cd_init(const char *path) -{ - if (!path || !*path) { - DMSG("No file given, behaving like an empty drive"); - goto error_return; - } - - /* Open the requested file. */ - iso_fd = sceIoOpen(path, PSP_O_RDONLY, 0); - if (iso_fd < 0) { - DMSG("Failed to open %s: %s", path, psp_strerror(iso_fd)); - goto error_return; - } - - /* Is it a CUE file? */ - char buf[4]; - if (sceIoRead(iso_fd, buf, 4) != 4) { - DMSG("Failed to read 4 bytes from %s", path); - goto error_close_iso; - } - const int is_cue = (memcmp(buf, "FILE", 4) == 0); - - /* Record information about the ISO image. */ - memset(iso_toc, 0xFF, sizeof(iso_toc)); - memset(tracks, 0, sizeof(tracks)); - if (is_cue) { - int new_fd = examine_cue(iso_fd); - if (new_fd) { - sceIoClose(iso_fd); - iso_fd = new_fd; - } else { - DMSG("Failed to parse CUE file %s", path); - goto error_close_iso; - } - } else { - if (!examine_iso(iso_fd)) { - DMSG("Failed to examine ISO file %s", path); - goto error_close_iso; - } - } - - /* Start up the CD-reading thread. */ - memset(readahead_sector, 0, sizeof(readahead_sector)); - cd_read_idle = 0; - cd_read_requested = 0; - cd_read_terminate = 0; - cd_read_sector = 0; - cd_read_index = 0; - cd_read_thid = sys_start_thread("YabauseCDReader", cd_read_thread, - THREADPRI_CD_READ, 0x1000, 0, NULL); - if (cd_read_thid < 0) { - DMSG("Failed to start CD reader thread: %s", - psp_strerror(cd_read_thid)); - goto error_close_iso; - } - - /* Success! */ - return 0; - - /* On error, we return success and behave like an empty drive. */ - error_close_iso: - sceIoClose(iso_fd); - error_return: - iso_fd = 0; - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_cd_deinit: Shut down the virtual CD interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_cd_deinit(void) -{ - if (iso_fd) { - cd_read_terminate = 1; - sceKernelWakeupThread(cd_read_thid); - unsigned int tries = 0; - while (!sys_delete_thread_if_stopped(cd_read_thid, NULL)) { - if (++tries > 100) { - DMSG("CD reader thread failed to terminate, killing it"); - sceKernelTerminateDeleteThread(cd_read_thid); - break; - } - sceKernelDelayThread(1000); // 1ms - } - cd_read_thid = 0; - sceIoClose(iso_fd); - iso_fd = 0; - } -} - -/*************************************************************************/ - -/** - * psp_cd_get_status: Return the status of the physical device associated - * with the virtual CD drive. - * - * [Parameters] - * None - * [Return value] - * 0: CD present, disc spinning - * 1: CD present, disc not spinning - * 2: CD not present - * 3: Tray open - */ -static int psp_cd_get_status(void) -{ - return iso_fd ? 0 : 2; -} - -/*************************************************************************/ - -/** - * psp_cd_read_toc: Return the TOC (table of contents) data for the disc - * currently inserted in the virtual CD drive. - * - * [Parameters] - * toc_buffer: Buffer into which TOC data is to be stored - * [Return value] - * Number of bytes returned - */ -static s32 psp_cd_read_toc(u32 *toc) -{ - if (!iso_fd) { - return 0; - } - - memcpy(toc, iso_toc, sizeof(iso_toc)); - return sizeof(iso_toc); -} - -/*************************************************************************/ - -/** - * psp_cd_read_sector: Read a 2352-byte raw sector from the virtual CD. - * - * [Parameters] - * sector: Linear sector number to read - * buffer: Buffer into which sector data is to be stored - * [Return value] - * Nonzero on success, zero on failure - */ -static int psp_cd_read_sector(u32 sector, void *buffer) -{ - if (!iso_fd) { - return 0; - } - - /* If the requested sector is already loaded, just return it. */ - unsigned int index; - for (index = 0; index < lenof(readahead_sector); index++) { - if (readahead_sector[index] == sector) { - memcpy(buffer, readahead_buffer[index], 2352); - return 1; - } - } - - /* The sector might have been in the middle of being read in, so wait - * for any pending read operation to complete and check again. */ - unsigned int tries = 0; - while (!cd_read_idle) { - if (++tries > 100) { - DMSG("Timeout waiting for CD reader to become idle"); - break; - } - sceKernelDelayThread(100); // 0.1ms - } - for (index = 0; index < lenof(readahead_sector); index++) { - if (readahead_sector[index] == sector) { - memcpy(buffer, readahead_buffer[index], 2352); - return 1; - } - } - - /* The sector isn't available after all, so start a new read request - * and wait for it to complete. */ - while (cd_read_requested) { - if (++tries > 100) { - DMSG("Timeout waiting for request"); - return 0; - } - sceKernelDelayThread(100); // 0.1ms - } - cd_read_sector = sector; - cd_read_index = 0; - cd_read_requested = 1; - sceKernelWakeupThread(cd_read_thid); - tries = 0; - while (cd_read_requested || !cd_read_idle) { - if (++tries > 1000) { - DMSG("Timeout waiting for read"); - return 0; - } - sceKernelDelayThread(100); // 0.1ms - } - - /* Ensure the sector was actually loaded, and return it. */ - if (readahead_sector[0] != sector) { - DMSG("Failed to read sector %u", (unsigned int)sector); - return 0; - } - memcpy(buffer, readahead_buffer[0], 2352); - return 1; -} - -/*************************************************************************/ - -/** - * psp_cd_read_ahead: Start an asynchronous read of the given sector from - * the virtual CD. - * - * [Parameters] - * sector: Linear sector number to read - * [Return value] - * 1 on success, 0 on failure - */ -static void psp_cd_read_ahead(u32 sector) -{ - if (!iso_fd) { - return; - } - - /* See whether the requested sector has already been read in. */ - unsigned int index; - for (index = 0; index < lenof(readahead_sector); index++) { - if (readahead_sector[index] == sector) { - break; - } - } - - uint32_t req_sector; // Sector to request - unsigned int req_index; // Target buffer index to request - - if (index < lenof(readahead_sector)) { - /* If the sector has already been read in, we normally don't need - * do anything. But if we're approaching the end of the current - * group of READ_UNIT sector buffers and the following sectors - * haven't yet been read in, start that read now. */ - if (index % READ_UNIT < READ_UNIT/2) { - return; - } - const unsigned int group_index = (index / READ_UNIT) * READ_UNIT; - const unsigned int next_group = - (group_index + READ_UNIT) % lenof(readahead_sector); - const uint32_t next_group_sector = - readahead_sector[group_index + (READ_UNIT-1)]; - if (!next_group_sector) { - return; // We must have reached the end of the track - } - if (readahead_sector[next_group] == next_group_sector) { - return; // Following sectors are already read in - } - req_sector = next_group_sector; - req_index = next_group; - } else { - /* The sector wasn't available, so start a new read operation. */ - req_sector = sector; - req_index = 0; - } - - /* If there's a pending read request, we can't do anything (so as not - * to block). */ - if (cd_read_requested) { - DMSG("Async read in progress, skipping readahead"); - return; - } - - /* Pass the requested sector and buffer index to the read thread. */ - cd_read_sector = req_sector; - cd_read_index = req_index; - cd_read_requested = 1; - sceKernelWakeupThread(cd_read_thid); -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * examine_iso: Examine a raw ISO image and fill in the iso_toc[] and - * tracks[] arrays with its information. - * - * [Parameters] - * fd: File descriptor for ISO image - * [Return value] - * Nonzero on success, zero on error - */ -static int examine_iso(int fd) -{ - /* Retrieve the size of the ISO image. */ - - const uint32_t file_size = sceIoLseek(fd, 0, PSP_SEEK_END); - if ((int32_t)file_size < 0) { - DMSG("Failed to retrieve ISO file size: %s", psp_strerror(file_size)); - return 0; - } else if (file_size == 0) { - DMSG("ISO file is empty!"); - return 0; - } - - /* Guess at the sector size based on the file size. */ - - unsigned int sector_size; - if (file_size % 2048 == 0 && file_size % 2352 == 0) { - /* It could be either 2048 or 2352 bytes per sector. Try and find - * an ISO filesystem header to tell which it is. */ - char buf[8]; - sceIoLseek(fd, 2048*16, PSP_SEEK_SET); - if (sceIoRead(fd, buf, 8) != 8) { - DMSG("Failed to read 8 bytes from offset 2048*16"); - return 0; - } - if (memcmp(buf, "\1CD001\1"/*\0*/, 8) == 0) { - sector_size = 2048; - } else { - sceIoLseek(fd, 2352*16+16, PSP_SEEK_SET); - if (sceIoRead(fd, buf, 8) != 8) { - DMSG("Failed to read 8 bytes from offset 2352*16+16"); - return 0; - } - if (memcmp(buf, "\1CD001\1"/*\0*/, 8) == 0) { - sector_size = 2352; - } else { - DMSG("Can't find an ISO9660 header, assuming 2048-byte" - " sectors"); - sector_size = 2048; - } - } - } else if (file_size % 2048 == 0) { - /* Not a multiple of 2352 bytes, so presumably 2048-byte sectors. */ - sector_size = 2048; - } else if (file_size % 2352 == 0) { - /* Not a multiple of 2048 bytes, so presumably 2352-byte sectors. */ - sector_size = 2352; - } else { - DMSG("Can't figure out sector size, assuming 2048-byte sectors"); - sector_size = 2048; - } - - /* Fill in the TOC and track table. */ - - const uint32_t num_sectors = file_size / sector_size; - - iso_toc[ 0] = 0x41000000 | 150; - iso_toc[ 99] = 0x41010000; - iso_toc[100] = 0x41010100; - iso_toc[101] = 0x41000000 | num_sectors; - - tracks[0].first_sector = 150; - tracks[0].last_sector = 150 + num_sectors - 1; - tracks[0].file_offset = 0; - tracks[0].sector_size = sector_size; - - /* All done! */ - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * examine_cue: Examine a CUE file, open the corresponding ISO image file, - * and fill in the iso_toc[] and tracks[] arrays with the image information. - * - * [Parameters] - * fd: File descriptor for CUE file - * [Return value] - * File descriptor for ISO image (nonzero) on success, zero on error - */ -static int examine_cue(int fd) -{ - /* Load the entire CUE file into memory. */ - - const uint32_t file_size = sceIoLseek(fd, 0, PSP_SEEK_END); - if ((int32_t)file_size < 0) { - DMSG("Failed to retrieve CUE file size: %s", psp_strerror(file_size)); - goto error_return; - } else if (file_size == 0) { - /* This should be impossible, since we read from the file to - * determine that it's a CUE file, but let's play it safe anyway... */ - DMSG("CUE file is empty!"); - goto error_return; - } else if (file_size > 1000000) { - /* Way too big to be a CUE file, so give up rather than trying to - * load tons of data into memory just to find out that it's bad. */ - DMSG("CUE file is too big! (%u bytes)", file_size); - goto error_return; - } - - char *cue_buffer = malloc(file_size); - if (!cue_buffer) { - DMSG("Failed to allocate buffer for CUE file (%u bytes)", file_size); - goto error_return; - } - sceIoLseek(fd, 0, PSP_SEEK_SET); - if (sceIoRead(fd, cue_buffer, file_size) != file_size) { - DMSG("Failed to read CUE file into memory"); - goto error_free_cue_buffer; - } - - /* The first line should be FILE "image-file" [...], giving the - * filename of the corresponding disc image. Strip any directory name - * from the image and attempt to open the file. */ - - char *s, *eol; - int new_fd; - uint32_t image_size; - - eol = cue_buffer + strcspn(cue_buffer, "\r\n"); - if (*eol) { - *eol++ = 0; - } - eol += strspn(eol, "\r\n"); - if (strncmp(cue_buffer, "FILE \"", 6) != 0) { - DMSG("Invalid CUE format: File does not begin with `FILE \"'"); - goto error_free_cue_buffer; - } - char *path = cue_buffer + 6; - s = strchr(path, '"'); - if (!s) { - DMSG("Invalid CUE format: FILE path missing closing quote"); - goto error_free_cue_buffer; - } - *s = 0; - - new_fd = sceIoOpen(path, PSP_O_RDONLY, 0); - if (new_fd < 0) { - DMSG("Failed to open image file %s: %s", path, psp_strerror(new_fd)); - goto error_free_cue_buffer; - } - - image_size = sceIoLseek(new_fd, 0, PSP_SEEK_END); - if ((int32_t)image_size < 0) { - DMSG("Failed to retrieve size of image file %s: %s", path, - psp_strerror(image_size)); - goto error_close_new_fd; - } - - /* Process each remaining line in the CUE file. */ - - int linenum = 1; - unsigned int current_track = 0; - uint32_t pregap_accum = 150; // Accumulated pregap sectors - - while (*eol) { - char *line = eol; - linenum++; - eol += strcspn(eol, "\r\n"); - if (*eol) { - *eol++ = 0; - } - eol += strspn(eol, "\r\n"); - - /* Get the tag, skipping leading spaces; if it's an empty line, - * just skip to the next one. */ - - line += strspn(line, " \t"); - if (!*line) { - continue; - } - char *tag = line; - line += strcspn(line, " \t"); - if (*line) { - *line++ = 0; - } - line += strspn(line, " \t"); - - /* Parse remaining parameters based on the tag type. */ - - if (strcmp(tag, "TRACK") == 0) { - - char *track_str = line; - line += strcspn(line, " \t"); - if (*line) { - *line++ = 0; - } - line += strspn(line, " \t"); - current_track = strtoul(track_str, &s, 10); - if (*s || current_track < 1 || current_track > 99) { - DMSG("Invalid CUE format (line %u): Bad track number %s", - linenum, track_str); - goto error_close_new_fd; - } - - char *mode = line; - if (strcmp(mode, "AUDIO") == 0) { - iso_toc[current_track-1] = 0x01000000; // Sector # comes later - tracks[current_track-1].sector_size = 2352; - } else if (strcmp(mode, "MODE1/2352") == 0 - || strcmp(mode, "MODE2/2352") == 0 - ) { - iso_toc[current_track-1] = 0x41000000; - tracks[current_track-1].sector_size = 2352; - } else if (strcmp(mode, "MODE1/2048") == 0 - || strcmp(mode, "MODE2/2048") == 0 - ) { - iso_toc[current_track-1] = 0x41000000; - tracks[current_track-1].sector_size = 2048; - } - - } else if (strcmp(tag, "INDEX") == 0) { - - if (!current_track) { - DMSG("Invalid CUE format (line %u): INDEX tag with no" - " current track", linenum); - goto error_close_new_fd; - } - - char *index_str = line; - line += strcspn(line, " \t"); - if (*line) { - *line++ = 0; - } - line += strspn(line, " \t"); - const unsigned int index = strtoul(index_str, &s, 10); - if (*s) { - DMSG("Invalid CUE format (line %u): Bad index number %s", - linenum, index_str); - goto error_close_new_fd; - } - if (index != 1) { - continue; // We only care about index #1 - } - - char *msf = line; - const int32_t sector = msf_to_sector(msf); - if (sector < 0) { - DMSG("Invalid CUE format (line %u): Bad MSF string %s", - linenum, msf); - goto error_close_new_fd; - } - - iso_toc[current_track-1] |= sector + pregap_accum; - tracks[current_track-1].first_sector = sector + pregap_accum; - /* Temporarily store the accumulated pregap in last_sector */ - tracks[current_track-1].last_sector = pregap_accum; - - } else if (strcmp(tag, "PREGAP") == 0) { - - if (!current_track) { - DMSG("Invalid CUE format (line %u): PREGAP tag with no" - " current track", linenum); - goto error_close_new_fd; - } - - char *msf = line; - const int32_t pregap_sectors = msf_to_sector(msf); - if (pregap_sectors < 0) { - DMSG("Invalid CUE format (line %u): Bad MSF string %s", - linenum, msf); - goto error_close_new_fd; - } - - pregap_accum += pregap_sectors; - - } else { - - /* Either an invalid tag or one we don't care about, so skip it. */ - - } - - } // while (*eol) - - if (!tracks[0].first_sector) { - DMSG("Invalid CUE file: Track 1 missing"); - goto error_close_new_fd; - } - - /* Fill in the remaining fields in the track table. */ - - if (tracks[0].first_sector != tracks[0].last_sector) { - DMSG("First track does not start at file offset 0, assuming sector" - " size %u for skipped sectors", tracks[0].sector_size); - const uint32_t track1_skipped = - tracks[0].first_sector - tracks[0].last_sector; - tracks[0].file_offset = track1_skipped * tracks[0].sector_size; - } else { - tracks[0].file_offset = 0; - } - - unsigned int track; - for (track = 2; track <= current_track; track++) { - if (!tracks[track-1].first_sector) { - DMSG("Invalid CUE file: Intermediate track %u missing", track); - goto error_close_new_fd; - } - const uint32_t pregap = tracks[track-1].last_sector; - const uint32_t added_pregap = pregap - tracks[track-2].last_sector; - tracks[track-2].last_sector = - tracks[track-1].first_sector - added_pregap - 1; - const uint32_t last_track_sectors = - tracks[track-2].last_sector - tracks[track-2].first_sector + 1; - tracks[track-1].file_offset = - tracks[track-2].file_offset - + (last_track_sectors * tracks[track-2].sector_size); - } - - const uint32_t last_track_size = image_size - tracks[track-2].file_offset; - const uint32_t last_track_sectors = - last_track_size / tracks[track-2].sector_size; - tracks[track-2].last_sector = - tracks[track-2].first_sector + last_track_sectors - 1; - - /* Generate the final TOC entries. */ - - iso_toc[ 99] = (iso_toc[0] & 0xFF000000) | 0x00010000; - iso_toc[100] = (iso_toc[current_track-1] & 0xFF000000) - | (current_track << 16); - iso_toc[101] = (iso_toc[current_track-1] & 0xFF000000) - | (tracks[current_track-1].last_sector + 1); - - /* All done! */ - - free(cue_buffer); - return new_fd; - - - /* Error handling. */ - - error_close_new_fd: - sceIoClose(new_fd); - error_free_cue_buffer: - free(cue_buffer); - error_return: - return 0; -} - -/*----------------------------------*/ - -/** - * msf_to_sector: Convert a time (Minutes:Seconds:Frames) string to the - * corresponding sector index. Helper function for examine_cue(). - * - * [Parameters] - * msf: Time string (MM:SS:FF) - * [Return value] - * Corresponding sector index (nonzero), or negative if string is invalid - */ -static int32_t msf_to_sector(const char *msf) -{ - uint32_t minutes, seconds, frames; - const char *s; - - if (!msf - || (minutes = strtoul(msf, (char **)&s, 10)) > 99 - || *s++ != ':' - || (seconds = strtoul(s, (char **)&s, 10)) > 59 - || *s++ != ':' - || (frames = strtoul(s, (char **)&s, 10)) > 74 - || *s != 0 - ) { - return -1; - } - - return (minutes*60 + seconds)*75 + frames; -} - -/*************************************************************************/ -/**************************** CD read thread *****************************/ -/*************************************************************************/ - -/** - * cd_read_thread: Thread which performs reads from the CD image file as - * requested by the main program. - * - * The main program should follow these steps to request a read: - * 1) Wait for cd_read_requested to become zero. - * 2) Store the desired sector address (150-...) in cd_read_sector. - * 3) Store the desired target readahead buffer index in cd_read_index. - * This value must be a multiple of READ_UNIT. - * 4) Store 1 in cd_read_requested. - * 5) Call sceKernelWakeupThread() to wake up the read thread. - * The main program can determine whether all pending requests have been - * completed by checking cd_read_idle for a nonzero value. - * - * Sectors which have been read in are stored in the read-ahead buffer; - * for any nonzero entry in readahead_sector[], the corresponding entry in - * readahead_buffer[] contains the raw data for that sector (converted, if - * necessary, from the format in the file--i.e., 2048-byte sectors in the - * file are filled out to 2352-byte sectors in readahead_buffer[]). - * - * To terminate the thread, the main program should store 1 in - * cd_read_terminate and wake up the thread. - * - * The file descriptor (iso_fd) and track table (tracks[]) must not be - * modified while the thread is running. - * - * [Parameters] - * None - * [Return value] - * Does not return - */ -static void cd_read_thread(void) -{ - PROFILE_START("CDIO"); - - while (!cd_read_terminate) { - - /* Wait for a trigger write from the main program. */ - while (!cd_read_requested && !cd_read_terminate) { - cd_read_idle = 1; - /* Since the read thread runs at a higher priority than the - * main program thread, there is (barring an OS bug) no danger - * of a race condition causing the read thread to be - * interrupted by the main thread between the while() test and - * this sleep call. */ - PROFILE_STOP("CDIO"); - sceKernelSleepThread(); - PROFILE_START("CDIO"); - } - if (cd_read_terminate) { - break; - } - cd_read_idle = 0; - - /* Save the requested sector number, then clear the request trigger. */ - const uint32_t sector = cd_read_sector; - const unsigned int index = cd_read_index; - cd_read_requested = 0; - - /* Figure out which track the sector is in and retrieve the track - * information. */ - unsigned int track; - for (track = 0; track < lenof(tracks); track++) { - if (sector >= tracks[track].first_sector - && sector <= tracks[track].last_sector - ) { - break; - } - } - if (track >= lenof(tracks)) { - DMSG("Failed to find track for sector %u", (unsigned int)sector); - continue; - } - const uint32_t first_sector = tracks[track].first_sector; - const uint32_t file_offset = tracks[track].file_offset; - const uint32_t sector_size = tracks[track].sector_size; - - /* Clear out all sector information previously stored in this group - * of buffers. */ - unsigned int i; - for (i = index; i < index + READ_UNIT; i++) { - readahead_sector[i] = 0; - } - - /* Check how many sectors we should read from this location (avoid - * reading beyond the end of the track). */ - unsigned int sectors_to_read = READ_UNIT; - if (sectors_to_read > (tracks[track].last_sector+1) - sector) { - sectors_to_read = (tracks[track].last_sector+1) - sector; - } - - /* Seek to the proper location in the disc image. */ - const uint32_t relative_sector = sector - first_sector; - const uint32_t relative_offset = relative_sector * sector_size; - const uint32_t absolute_offset = file_offset + relative_offset; - uint32_t res = sceIoLseek(iso_fd, absolute_offset, PSP_SEEK_SET); - if (res != absolute_offset) { - DMSG("sceIoLseek(%u, %u, SEEK_SET): %s", iso_fd, absolute_offset, - psp_strerror(res)); - continue; - } - - /* Read the sector data from the disc image. */ - if (sector_size == 2352) { - PROFILE_STOP("CDIO"); - res = sceIoRead(iso_fd, readahead_buffer[index], - 2352 * sectors_to_read); - PROFILE_START("CDIO"); - } else if (sector_size == 2048) { - static const uint8_t sector_header[16] = - {0, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 0, 0, 0, 0, 0}; - memcpy(readahead_buffer[index], sector_header, 16); - PROFILE_STOP("CDIO"); - res = sceIoRead(iso_fd, (uint8_t *)readahead_buffer[index] + 16, - 2048 * sectors_to_read); - PROFILE_START("CDIO"); - for (i = sectors_to_read-1; i >= 1; i--) { - /* We have to move the data first, or the sector header - * could overwrite part of the sector we're moving. */ - memmove((uint8_t *)readahead_buffer[index+i] + 16, - (uint8_t *)readahead_buffer[index] + 16 + 2048*i, - 2048); - memcpy(readahead_buffer[index+i], sector_header, 16); - } - } else { - DMSG("IMPOSSIBLE: bad sector_size %u for track %u", - sector_size, track); - continue; - } - if (res != sector_size * sectors_to_read) { - DMSG("sceIoRead(%u, buffer[%u], %u): %s", iso_fd, index, - sector_size, res < 0 ? psp_strerror(res) : "Short read"); - continue; - } - - /* Fill in readahead_sector[] with the newly-read-in sectors. */ - for (i = 0; i < sectors_to_read; i++) { - readahead_sector[index+i] = sector+i; - } - - } // while (!cd_read_terminate) - - PROFILE_STOP("CDIO"); - sceKernelExitThread(0); -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-cd.h b/yabause/src/psp/psp-cd.h deleted file mode 100644 index fc801aac53..0000000000 --- a/yabause/src/psp/psp-cd.h +++ /dev/null @@ -1,46 +0,0 @@ -/* src/psp/psp-cd.h: PSP virtual CD interface module header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_CD_H -#define PSP_CD_H - -#include "../cdbase.h" // for CDInterface - -/*************************************************************************/ - -/* Module interface definition */ -extern CDInterface CDPSP; - -/* Unique module ID (must be different from any in ../cdbase.h) */ -#define CDCORE_PSP 0x5CE // "SCE" - -/*************************************************************************/ - -#endif // PSP_CD_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-logo.png b/yabause/src/psp/psp-logo.png deleted file mode 100644 index c7af604add..0000000000 Binary files a/yabause/src/psp/psp-logo.png and /dev/null differ diff --git a/yabause/src/psp/psp-m68k.c b/yabause/src/psp/psp-m68k.c deleted file mode 100644 index 4de2d692d7..0000000000 --- a/yabause/src/psp/psp-m68k.c +++ /dev/null @@ -1,630 +0,0 @@ -/* src/psp/psp-m68k.c: PSP M68k emulator interface (uses Q68) - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "../core.h" -#include "../error.h" -#include "../m68kcore.h" -#include "../memory.h" -#include "../scsp.h" - -#include "../q68/q68.h" -#include "../q68/q68-const.h" // for Q68_JIT_PAGE_BITS - -#include "common.h" -#include "config.h" -#include "psp-m68k.h" -#include "sys.h" - -#include "me.h" -#include "me-utility.h" - -/*************************************************************************/ -/************************* Interface definition **************************/ -/*************************************************************************/ - -/* Interface function declarations (must come before interface definition) */ - -static int psp_m68k_init(void); -static void psp_m68k_deinit(void); -static void psp_m68k_reset(void); - -static FASTCALL s32 psp_m68k_exec(s32 cycles); -static void psp_m68k_sync(void); - -static u32 psp_m68k_get_dreg(u32 num); -static u32 psp_m68k_get_areg(u32 num); -static u32 psp_m68k_get_pc(void); -static u32 psp_m68k_get_sr(void); -static u32 psp_m68k_get_usp(void); -static u32 psp_m68k_get_ssp(void); - -static void psp_m68k_set_dreg(u32 num, u32 val); -static void psp_m68k_set_areg(u32 num, u32 val); -static void psp_m68k_set_pc(u32 val); -static void psp_m68k_set_sr(u32 val); -static void psp_m68k_set_usp(u32 val); -static void psp_m68k_set_ssp(u32 val); - -static FASTCALL void psp_m68k_set_irq(s32 level); -static FASTCALL void psp_m68k_write_notify(u32 address, u32 size); - -static void psp_m68k_set_fetch(u32 low_addr, u32 high_addr, pointer fetch_addr); -static void psp_m68k_set_readb(M68K_READ *func); -static void psp_m68k_set_readw(M68K_READ *func); -static void psp_m68k_set_writeb(M68K_WRITE *func); -static void psp_m68k_set_writew(M68K_WRITE *func); - -/*-----------------------------------------------------------------------*/ - -/* Module interface definition */ - -M68K_struct M68KPSP = { - .id = M68KCORE_PSP, - .Name = "PSP M68k Emulator Interface", - - .Init = psp_m68k_init, - .DeInit = psp_m68k_deinit, - .Reset = psp_m68k_reset, - - .Exec = psp_m68k_exec, - .Sync = psp_m68k_sync, - - .GetDReg = psp_m68k_get_dreg, - .GetAReg = psp_m68k_get_areg, - .GetPC = psp_m68k_get_pc, - .GetSR = psp_m68k_get_sr, - .GetUSP = psp_m68k_get_usp, - .GetMSP = psp_m68k_get_ssp, - - .SetDReg = psp_m68k_set_dreg, - .SetAReg = psp_m68k_set_areg, - .SetPC = psp_m68k_set_pc, - .SetSR = psp_m68k_set_sr, - .SetUSP = psp_m68k_set_usp, - .SetMSP = psp_m68k_set_ssp, - - .SetIRQ = psp_m68k_set_irq, - .WriteNotify = psp_m68k_write_notify, - - .SetFetch = psp_m68k_set_fetch, - .SetReadB = psp_m68k_set_readb, - .SetReadW = psp_m68k_set_readw, - .SetWriteB = psp_m68k_set_writeb, - .SetWriteW = psp_m68k_set_writew, -}; - -/*************************************************************************/ - -/* Virtual processor state block */ -static Q68State *q68_state; - -/* JIT code arena block pointer (for free() on cleanup) */ -void *jit_arena_base; - -/*----------------------------------*/ - -/* Local function declarations */ - -static void flush_cache(void); - -static void local_malloc_init(void *base, uint32_t size); -static void *local_malloc(size_t size); -static void *local_realloc(void *ptr, size_t size); -static void local_free(void *ptr); - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * psp_m68k_init: Initialize the virtual processpr. - * - * [Parameters] - * None - * [Return value] - * Zero on success, negative on failure - */ -static int psp_m68k_init(void) -{ - /* Allocate a memory block for the Q68 memory pool; make sure it's - * 64-byte aligned to avoid cache line collisions */ - const uint32_t jit_arena_size = 2 * 1024 * 1024; - jit_arena_base = malloc(jit_arena_size + (64*2-1)); - if (!jit_arena_base) { - DMSG("Failed to allocate memory arena for JIT code"); - q68_destroy(q68_state); - q68_state = NULL; - return -1; - } - local_malloc_init((void *)(((uintptr_t)jit_arena_base + 0x3F) & -0x40), - jit_arena_size); - - if (!(q68_state = q68_create_ex(local_malloc, local_realloc, local_free))) { - DMSG("Failed to create Q68 state block"); - return -1; - } - q68_set_irq(q68_state, 0); - q68_set_jit_flush_func(q68_state, flush_cache); - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_m68k_deinit: Destroy the virtual processor. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_m68k_deinit(void) -{ - free(jit_arena_base); - jit_arena_base = NULL; - q68_destroy(q68_state); - q68_state = NULL; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_m68k_reset: Reset the virtual processor. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_m68k_reset(void) -{ - q68_reset(q68_state); -} - -/*************************************************************************/ - -/** - * psp_m68k_exec: Execute instructions for the given number of clock cycles. - * - * [Parameters] - * cycles: Number of clock cycles to execute - * [Return value] - * Number of clock cycles actually executed - */ -static FASTCALL s32 psp_m68k_exec(s32 cycles) -{ - return q68_run(q68_state, cycles); -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_m68k_sync: Wait for background execution to finish. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_m68k_sync(void) -{ - /* No-op */ -} - -/*************************************************************************/ - -/** - * psp_m68k_get_{dreg,areg,pc,sr,usp,ssp}: Return the current value of - * the specified register. - * - * [Parameters] - * num: Register number (psp_m68k_get_dreg(), psp_m68k_get_areg() only) - * [Return value] - * None - */ - -static u32 psp_m68k_get_dreg(u32 num) -{ - return q68_get_dreg(q68_state, num); -} - -static u32 psp_m68k_get_areg(u32 num) -{ - return q68_get_areg(q68_state, num); -} - -static u32 psp_m68k_get_pc(void) -{ - return q68_get_pc(q68_state); -} - -static u32 psp_m68k_get_sr(void) -{ - return q68_get_sr(q68_state); -} - -static u32 psp_m68k_get_usp(void) -{ - return q68_get_usp(q68_state); -} - -static u32 psp_m68k_get_ssp(void) -{ - return q68_get_ssp(q68_state); -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_m68k_set_{dreg,areg,pc,sr,usp,ssp}: Set the value of the specified - * register. - * - * [Parameters] - * num: Register number (psp_m68k_set_dreg(), psp_m68k_set_areg() only) - * val: Value to set - * [Return value] - * None - */ - -static void psp_m68k_set_dreg(u32 num, u32 val) -{ - q68_set_dreg(q68_state, num, val); -} - -static void psp_m68k_set_areg(u32 num, u32 val) -{ - q68_set_areg(q68_state, num, val); -} - -static void psp_m68k_set_pc(u32 val) -{ - q68_set_pc(q68_state, val); -} - -static void psp_m68k_set_sr(u32 val) -{ - q68_set_sr(q68_state, val); -} - -static void psp_m68k_set_usp(u32 val) -{ - q68_set_usp(q68_state, val); -} - -static void psp_m68k_set_ssp(u32 val) -{ - q68_set_ssp(q68_state, val); -} - -/*************************************************************************/ - -/** - * psp_m68k_set_irq: Deliver an interrupt to the processor. - * - * [Parameters] - * level: Interrupt level (0-7) - * [Return value] - * None - */ -static FASTCALL void psp_m68k_set_irq(s32 level) -{ - q68_set_irq(q68_state, level); -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_m68k_write_notify: Inform the 68k emulator that the given address - * range has been modified. - * - * [Parameters] - * address: 68000 address of modified data - * size: Size of modified data in bytes - * [Return value] - * None - */ -static FASTCALL void psp_m68k_write_notify(u32 address, u32 size) -{ - /* NOTE: If the SCSP/M68k is running in a separate thread, and the - * main thread calls this function with the result of freeing an - * allocated JIT block at the same time the M68k tries to allocate - * or free a JIT block in its thread, a crash is likely. Hopefully - * there are no actual games that try writing to M68k code space - * while the M68k is running. */ - q68_touch_memory(q68_state, address, size); -} - -/*************************************************************************/ - -/** - * psp_m68k_set_fetch: Set the instruction fetch pointer for a region of - * memory. Not used by Q68. - * - * [Parameters] - * low_addr: Low address of memory region to set - * high_addr: High address of memory region to set - * fetch_addr: Pointer to corresponding memory region (NULL to disable) - * [Return value] - * None - */ -static void psp_m68k_set_fetch(u32 low_addr, u32 high_addr, pointer fetch_addr) -{ -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_m68k_set_{readb,readw,writeb,writew}: Set functions for reading or - * writing bytes or words in memory. - * - * [Parameters] - * func: Function to set - * [Return value] - * None - */ - -static void psp_m68k_set_readb(M68K_READ *func) -{ - q68_set_readb_func(q68_state, (Q68ReadFunc *)func); -} - -static void psp_m68k_set_readw(M68K_READ *func) -{ - q68_set_readw_func(q68_state, (Q68ReadFunc *)func); -} - -static void psp_m68k_set_writeb(M68K_WRITE *func) -{ - q68_set_writeb_func(q68_state, (Q68WriteFunc *)func); -} - -static void psp_m68k_set_writew(M68K_WRITE *func) -{ - q68_set_writew_func(q68_state, (Q68WriteFunc *)func); -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * flush_cache: Flush the data and instruction caches of the current CPU. - * Called by Q68 after a new block of code has been translated. - */ -static void flush_cache(void) -{ - if (meUtilityIsME()) { - meUtilityDcacheWritebackInvalidateAll(); - meUtilityIcacheInvalidateAll(); - } else { - sceKernelDcacheWritebackInvalidateAll(); - sceKernelIcacheInvalidateAll(); - } -} - -/*************************************************************************/ - -/* For the moment, we use a very simplistic memory allocator to manage JIT - * memory. Since we only allocate or free during 68k code translation, - * this should hopefully be good enough. */ - -/* Memory management structure prefixed to each block */ -typedef struct BlockInfo_ BlockInfo; -struct BlockInfo_ { - BlockInfo *next, *prev; // Next and previous blocks sorted by address - uint32_t size; // Size of this block (excluding this structure) - int free; // Nonzero if this is a free block - uint32_t pad[12]; // Pad to 1 cache line (64 bytes) -}; - -/* Base of memory region used for local_malloc() and friends */ -static BlockInfo *local_malloc_base; - -/*-----------------------------------------------------------------------*/ - -/** - * local_malloc_init: Initialize the memory arena used by local_malloc() - * and friends. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void local_malloc_init(void *base, uint32_t size) -{ - local_malloc_base = base; - local_malloc_base->next = NULL; - local_malloc_base->prev = NULL; - local_malloc_base->size = size - sizeof(BlockInfo); - local_malloc_base->free = 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * local_malloc: Allocate a block of local memory. - * - * [Parameters] - * size: Size of memory block to allocate - * [Return value] - * Allocated memory block, or NULL on failure - */ -static void *local_malloc(size_t size) -{ - /* Round the size up to a multiple of sizeof(BlockInfo) for simplicity */ - size = (size + sizeof(BlockInfo)-1) - / sizeof(BlockInfo) * sizeof(BlockInfo); - - /* Find a free block of sufficient size and return it, splitting the - * block if appropriate */ - BlockInfo *block; - for (block = local_malloc_base; block; block = block->next) { - if (!block->free) { - continue; - } - if (block->size >= size) { - void *ptr = (void *)((uintptr_t)block + sizeof(BlockInfo)); - if (block->size > size) { - BlockInfo *split_block = (BlockInfo *)((uintptr_t)ptr + size); - split_block->next = block->next; - if (split_block->next) { - split_block->next->prev = split_block; - } - split_block->prev = block; - block->next = split_block; - split_block->size = block->size - (size + sizeof(BlockInfo)); - split_block->free = 1; - } - block->size = size; - block->free = 0; - return ptr; - } - } - - return NULL; -} - -/*-----------------------------------------------------------------------*/ - -/** - * local_realloc: Adjust the size of a block of local memory. - * - * [Parameters] - * ptr: Pointer to memory block to adjust - * size: New size of memory block - * [Return value] - * Allocated memory block, or NULL on failure - */ -static void *local_realloc(void *ptr, size_t size) -{ - if (size == 0) { - local_free(ptr); - return NULL; - } - - if (ptr == NULL) { - return local_malloc(size); - } - - BlockInfo *block = (BlockInfo *)((uintptr_t)ptr - sizeof(BlockInfo)); - const size_t oldsize = block->size; - size = (size + sizeof(BlockInfo)-1) - / sizeof(BlockInfo) * sizeof(BlockInfo); - if (size < oldsize - sizeof(BlockInfo)) { - /* Adjust the block size downward and split off the remaining space - * into a new free block (or add it to the next block, if the next - * block is a free block) */ - block->size = size; - BlockInfo *newblock = (BlockInfo *) - ((uintptr_t)block + sizeof(BlockInfo) + size); - if (block->next && block->next->free) { - newblock->next = block->next->next; - newblock->prev = block; - newblock->size = block->next->size; - newblock->free = 1; - if (newblock->next) { - newblock->next->prev = newblock; - } - block->next = newblock; - newblock->size += oldsize - size; - } else { - newblock->next = block->next; - newblock->prev = block; - if (block->next) { - block->next->prev = newblock; - } - block->next = newblock; - newblock->size = oldsize - size - sizeof(BlockInfo); - newblock->free = 1; - } - return ptr; - } else if (size <= sizeof(BlockInfo)) { - /* No need to adjust anything; just return the same block */ - return ptr; - } else if (block->next && block->next->free - && (sizeof(BlockInfo) + block->next->size) >= size - oldsize) { - /* Append the next block to this one, then resize downward with a - * recursive call */ - block->size += sizeof(BlockInfo) + block->next->size; - block->next = block->next->next; - if (block->next) { - block->next->prev = block; - } - return local_realloc(ptr, size); - } else { - /* No simple path, so alloc/copy/free */ - void *newptr = local_malloc(size); - if (!newptr) { - return NULL; - } - const size_t copysize = (oldsize < size) ? oldsize : size; - memcpy(newptr, ptr, copysize); - local_free(ptr); - return newptr; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * local_free: Free a block of local memory. - * - * [Parameters] - * ptr: Pointer to memory block to free - * [Return value] - * None - */ -static void local_free(void *ptr) -{ - if (ptr != NULL) { - BlockInfo *block = (BlockInfo *)((uintptr_t)ptr - sizeof(BlockInfo)); - block->free = 1; - if (block->prev && block->prev->free) { - block->prev->next = block->next; - if (block->next) { - block->next->prev = block->prev; - } - block->prev->size += block->size + sizeof(BlockInfo); - block = block->prev; - } - if (block->next && block->next->free) { - block->size += block->next->size + sizeof(BlockInfo); - block->next = block->next->next; - if (block->next) { - block->next->prev = block; - } - } - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-m68k.h b/yabause/src/psp/psp-m68k.h deleted file mode 100644 index 86662b676b..0000000000 --- a/yabause/src/psp/psp-m68k.h +++ /dev/null @@ -1,46 +0,0 @@ -/* src/psp/psp-m68k.h: PSP M68k emulator interface module header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_M68K_H -#define PSP_M68K_H - -#include "../m68kcore.h" // for M68K_struct - -/*************************************************************************/ - -/* Module interface definition */ -extern M68K_struct M68KPSP; - -/* Unique module ID (must be different from any in ../m68kcore.h) */ -#define M68KCORE_PSP 0x5CE // "SCE" - -/*************************************************************************/ - -#endif // PSP_M68K_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-per.c b/yabause/src/psp/psp-per.c deleted file mode 100644 index 8560e7816a..0000000000 --- a/yabause/src/psp/psp-per.c +++ /dev/null @@ -1,162 +0,0 @@ -/* src/psp/psp-per.c: PSP peripheral interface module - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../peripheral.h" - -#include "control.h" -#include "psp-per.h" - -/*************************************************************************/ -/************************* Interface definition **************************/ -/*************************************************************************/ - -/* Interface function declarations (must come before interface definition) */ - -static int psp_per_init(void); -static void psp_per_deinit(void); -static int psp_per_handle_events(void); -#ifdef PERKEYNAME -static void psp_per_key_name(u32 key, char *name, int size); -#endif - -/*-----------------------------------------------------------------------*/ - -/* Module interface definition */ - -PerInterface_struct PERPSP = { - .id = PERCORE_PSP, - .Name = "PSP Peripheral Interface", - .Init = psp_per_init, - .DeInit = psp_per_deinit, - .HandleEvents = psp_per_handle_events, - .canScan = 0, -#ifdef PERKEYNAME - .KeyName = psp_per_key_name, -#endif -}; - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * psp_per_init: Initialize the peripheral interface. - * - * [Parameters] - * None - * [Return value] - * Zero on success, negative on error - */ -static int psp_per_init(void) -{ - /* Nothing to do */ - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_per_deinit: Shut down the peripheral interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_per_deinit(void) -{ - /* Nothing to do */ -} - -/*************************************************************************/ - -/** - * psp_per_handle_events: Process pending peripheral events, and run one - * iteration of the emulation. - * - * For the PSP, the main loop is located in main.c; we only update the - * current button status here. - * - * [Parameters] - * None - * [Return value] - * Zero on success, negative on error - */ -static int psp_per_handle_events(void) -{ - static uint32_t last_buttons; - - const uint32_t buttons = control_state(); - const uint32_t changed_buttons = buttons ^ last_buttons; - last_buttons = buttons; - - int i; - for (i = 0; i < 16; i++) { - const uint32_t button = 1 << i; - if (changed_buttons & button) { - if (buttons & button) { - PerKeyDown(button); - } else { - PerKeyUp(button); - } - } - } - - YabauseExec(); - return 0; -} - -/*************************************************************************/ - -#ifdef PERKEYNAME - -/** - * psp_per_key_name: Return the name corresponding to a system-dependent - * key value. - * - * [Parameters] - * key: Key value to return name for - * name: Buffer into which name is to be stored - * size: Size of buffer in bytes - * [Return value] - * None - */ -static void psp_per_key_name(u32 key, char *name, int size) -{ - /* Not supported on PSP */ - *name = 0; -} - -#endif // PERKEYNAME - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-per.h b/yabause/src/psp/psp-per.h deleted file mode 100644 index fa274574b6..0000000000 --- a/yabause/src/psp/psp-per.h +++ /dev/null @@ -1,46 +0,0 @@ -/* src/psp/psp-per.h: PSP peripheral interface module header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_PER_H -#define PSP_PER_H - -#include "../peripheral.h" // for PerInterface_struct - -/*************************************************************************/ - -/* Module interface definition */ -extern PerInterface_struct PERPSP; - -/* Unique module ID (must be different from any in ../peripheral.h) */ -#define PERCORE_PSP 0x5CE // "SCE" - -/*************************************************************************/ - -#endif // PSP_PER_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-sh2.c b/yabause/src/psp/psp-sh2.c deleted file mode 100644 index ac972cde01..0000000000 --- a/yabause/src/psp/psp-sh2.c +++ /dev/null @@ -1,670 +0,0 @@ -/* src/psp/psp-sh2.c: Yabause interface for PSP SH-2 emulator - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../bios.h" -#include "../error.h" -#include "../memory.h" -#include "../sh2core.h" -#include "../sh2trace.h" -#include "../vdp1.h" -#include "../vdp2.h" - -#include "config.h" -#include "psp-sh2.h" -#include "rtl.h" -#include "sh2.h" -#include "sh2-internal.h" // For TRACE, etc. (so we don't call sh2_trace_add_cycles() if not needed) - -#include "satopt-sh2.h" - -/*************************************************************************/ -/************************* Interface definition **************************/ -/*************************************************************************/ - -/* Interface function declarations (must come before interface definition) */ - -static int psp_sh2_init(void); -static void psp_sh2_deinit(void); -static void psp_sh2_reset(void); -static FASTCALL void psp_sh2_exec(SH2_struct *state, u32 cycles); - -static void psp_sh2_get_registers(SH2_struct *yabause_state, - sh2regs_struct *regs); -static u32 psp_sh2_get_GPR(SH2_struct *yabause_state, int num); -static u32 psp_sh2_get_SR(SH2_struct *yabause_state); -static u32 psp_sh2_get_GBR(SH2_struct *yabause_state); -static u32 psp_sh2_get_VBR(SH2_struct *yabause_state); -static u32 psp_sh2_get_MACH(SH2_struct *yabause_state); -static u32 psp_sh2_get_MACL(SH2_struct *yabause_state); -static u32 psp_sh2_get_PR(SH2_struct *yabause_state); -static u32 psp_sh2_get_PC(SH2_struct *yabause_state); - -static void psp_sh2_set_registers(SH2_struct *yabause_state, - const sh2regs_struct *regs); -static void psp_sh2_set_GPR(SH2_struct *yabause_state, int num, u32 value); -static void psp_sh2_set_SR(SH2_struct *yabause_state, u32 value); -static void psp_sh2_set_GBR(SH2_struct *yabause_state, u32 value); -static void psp_sh2_set_VBR(SH2_struct *yabause_state, u32 value); -static void psp_sh2_set_MACH(SH2_struct *yabause_state, u32 value); -static void psp_sh2_set_MACL(SH2_struct *yabause_state, u32 value); -static void psp_sh2_set_PR(SH2_struct *yabause_state, u32 value); -static void psp_sh2_set_PC(SH2_struct *yabause_state, u32 value); - -static void psp_sh2_send_interrupt(SH2_struct *yabause_state, - u8 vector, u8 level); -static int psp_sh2_get_interrupts(SH2_struct *yabause_state, - interrupt_struct interrupts[MAX_INTERRUPTS]); -static void psp_sh2_set_interrupts(SH2_struct *yabause_state, - int num_interrupts, - const interrupt_struct interrupts[MAX_INTERRUPTS]); - -static void psp_sh2_write_notify(u32 start, u32 length); - - -/* Module interface definition */ - -SH2Interface_struct SH2PSP = { - .id = SH2CORE_PSP, - .Name = "PSP SH-2 Core", - - .Init = psp_sh2_init, - .DeInit = psp_sh2_deinit, - .Reset = psp_sh2_reset, - .Exec = psp_sh2_exec, - - .GetRegisters = psp_sh2_get_registers, - .GetGPR = psp_sh2_get_GPR, - .GetSR = psp_sh2_get_SR, - .GetGBR = psp_sh2_get_GBR, - .GetVBR = psp_sh2_get_VBR, - .GetMACH = psp_sh2_get_MACH, - .GetMACL = psp_sh2_get_MACL, - .GetPR = psp_sh2_get_PR, - .GetPC = psp_sh2_get_PC, - - .SetRegisters = psp_sh2_set_registers, - .SetGPR = psp_sh2_set_GPR, - .SetSR = psp_sh2_set_SR, - .SetGBR = psp_sh2_set_GBR, - .SetVBR = psp_sh2_set_VBR, - .SetMACH = psp_sh2_set_MACH, - .SetMACL = psp_sh2_set_MACL, - .SetPR = psp_sh2_set_PR, - .SetPC = psp_sh2_set_PC, - - .SendInterrupt = psp_sh2_send_interrupt, - .GetInterrupts = psp_sh2_get_interrupts, - .SetInterrupts = psp_sh2_set_interrupts, - - .WriteNotify = psp_sh2_write_notify, -}; - -/*************************************************************************/ -/************************ Local data definitions *************************/ -/*************************************************************************/ - -/* Master and slave SH-2 state blocks */ -static SH2State *master_SH2, *slave_SH2; - -/* Write buffers for low and high RAM */ -static void *write_buffer_lram, *write_buffer_hram; - -/*-----------------------------------------------------------------------*/ - -/* Local function declarations */ -static void flush_caches(void *start, uint32_t length); -static void invalid_opcode_handler(SH2State *state, uint32_t PC, - uint16_t opcode); -static FASTCALL void trace_insn_handler(SH2State *state, uint32_t address); - -/*************************************************************************/ -/********************** External interface routines **********************/ -/*************************************************************************/ - -/** - * psp_sh2_init: Initialize the SH-2 core. - * - * [Parameters] - * None - * [Return value] - * Zero on success, negative on error - */ -static int psp_sh2_init(void) -{ - master_SH2 = sh2_create(); - slave_SH2 = sh2_create(); - if (!master_SH2 || !slave_SH2) { - return -1; - } - master_SH2->userdata = MSH2; - slave_SH2->userdata = SSH2; - - write_buffer_lram = sh2_alloc_direct_write_buffer(0x100000); - write_buffer_hram = sh2_alloc_direct_write_buffer(0x100000); - if (UNLIKELY(!write_buffer_lram) || UNLIKELY(!write_buffer_hram)) { - DMSG("WARNING: Failed to allocate RAM write buffers, performance" - " will suffer"); - } - - if (UNLIKELY(!sh2_init())) { - return -1; - } -#ifdef PSP - sh2_set_optimizations(config_get_sh2_optimizations()); - /* If we can allocate >24MB of memory, we must be on a PSP-2000 (Slim) - * or newer model; otherwise, assume we're on a PSP-1000 (Phat) and - * reduce the JIT data size limit to avoid crowding out other data. */ - void *memsize_test = malloc(24*1024*1024 + 1); - if (memsize_test) { - free(memsize_test); - sh2_set_jit_data_limit(20*1000000); - } else { - sh2_set_jit_data_limit(8*1000000); - } -#else // !PSP - sh2_set_optimizations(SH2_OPTIMIZE_ASSUME_SAFE_DIVISION - | SH2_OPTIMIZE_BRANCH_TO_RTS - | SH2_OPTIMIZE_FOLD_SUBROUTINES - | SH2_OPTIMIZE_LOCAL_ACCESSES - | SH2_OPTIMIZE_LOCAL_POINTERS - | SH2_OPTIMIZE_MAC_NOSAT - | SH2_OPTIMIZE_POINTERS - | SH2_OPTIMIZE_POINTERS_MAC - | SH2_OPTIMIZE_STACK); - /* Give the SH-2 core some breathing room for saving RTL blocks */ - sh2_set_jit_data_limit(200*1000000); -#endif - sh2_set_manual_optimization_callback(saturn_optimize_sh2); - sh2_set_cache_flush_callback(flush_caches); - sh2_set_invalid_opcode_callback(invalid_opcode_handler); - sh2_set_trace_insn_callback(trace_insn_handler); - sh2_set_trace_storeb_callback(sh2_trace_writeb); - sh2_set_trace_storew_callback(sh2_trace_writew); - sh2_set_trace_storel_callback(sh2_trace_writel); - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sh2_deinit: Perform cleanup for the SH-2 core. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_sh2_deinit(void) -{ - sh2_destroy(master_SH2); - sh2_destroy(slave_SH2); - - free(write_buffer_lram); - free(write_buffer_hram); - write_buffer_lram = write_buffer_hram = NULL; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sh2_reset: Reset the SH-2 core. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_sh2_reset(void) -{ - /* Sanity checks on pointers -- none of these are actually possible - * on the PSP, but it couldn't hurt to have them for testing this code - * on other platforms. */ - if ((uintptr_t)BiosRom == 0x00000000UL - || (uintptr_t)BiosRom == 0x00080000UL - || (uintptr_t)BiosRom == 0x20000000UL - || (uintptr_t)BiosRom == 0x20080000UL - || (uintptr_t)BiosRom == 0xA0000000UL - || (uintptr_t)BiosRom == 0xA0080000UL - || (uintptr_t)LowWram == 0x00200000UL - || (uintptr_t)LowWram == 0x20200000UL - || (uintptr_t)LowWram == 0xA0200000UL - || ((uintptr_t)HighWram & 0xFE0FFFFF) == 0x06000000UL - || ((uintptr_t)HighWram & 0xFE0FFFFF) == 0x26000000UL - || ((uintptr_t)HighWram & 0xFE0FFFFF) == 0xA6000000UL - ) { - DMSG("WARNING: ROM/RAM located at an inconvenient place;" - " performance will suffer!\nROM=%p LRAM=%p HRAM=%p", - BiosRom, LowWram, HighWram); - } - -#define SET_PAGE(sh2_addr,psp_addr,size,writebuf) do { \ - if (!(psp_addr)) { \ - DMSG("WARNING: %s == NULL", #psp_addr); \ - } else { \ - sh2_set_direct_access((sh2_addr) | 0x00000000, (psp_addr), \ - (size), 1, (writebuf)); \ - sh2_set_direct_access((sh2_addr) | 0x20000000, (psp_addr), \ - (size), 1, (writebuf)); \ - sh2_set_direct_access((sh2_addr) | 0xA0000000, (psp_addr), \ - (size), 1, (writebuf)); \ - } \ -} while (0) -#define SET_EXEC_PAGE(sh2_addr,psp_addr,size) do { \ - if (!(psp_addr)) { \ - DMSG("WARNING: %s == NULL", #psp_addr); \ - } else { \ - sh2_set_direct_access((sh2_addr) | 0x00000000, (psp_addr), \ - (size), 0, 0); \ - sh2_set_direct_access((sh2_addr) | 0x20000000, (psp_addr), \ - (size), 0, 0); \ - sh2_set_direct_access((sh2_addr) | 0xA0000000, (psp_addr), \ - (size), 0, 0); \ - } \ -} while (0) -#define SET_BYTE_PAGE(sh2_addr,psp_addr,size) do { \ - if (!(psp_addr)) { \ - DMSG("WARNING: %s == NULL", #psp_addr); \ - } else { \ - sh2_set_byte_direct_access((sh2_addr) | 0x00000000, (psp_addr), \ - (size)); \ - sh2_set_byte_direct_access((sh2_addr) | 0x20000000, (psp_addr), \ - (size)); \ - sh2_set_byte_direct_access((sh2_addr) | 0xA0000000, (psp_addr), \ - (size)); \ - } \ -} while (0) - - SET_EXEC_PAGE(0x00000000, BiosRom, 0x80000); - SET_EXEC_PAGE(0x00080000, BiosRom, 0x80000); - if (write_buffer_lram) { - SET_PAGE(0x00200000, LowWram, 0x100000, write_buffer_lram); - } - if (write_buffer_hram) { - uint32_t base; - for (base = 0x06000000; base < 0x08000000; base += 0x00100000) { - SET_PAGE(base, HighWram, 0x100000, write_buffer_hram); - } - } - SET_BYTE_PAGE(0x05C00000, Vdp1Ram, 0x80000); - SET_BYTE_PAGE(0x05E00000, Vdp2Ram, 0x80000); - SET_BYTE_PAGE(0x05E80000, Vdp2Ram, 0x80000); - -#undef SET_PAGE -#undef SET_EXEC_PAGE -#undef SET_BYTE_PAGE - - sh2_reset(master_SH2); - sh2_reset(slave_SH2); -} - -/*************************************************************************/ - -/** - * psp_sh2_exec: Execute instructions for the given number of clock cycles. - * - * [Parameters] - * yabause_state: Yabause SH-2 context structure - * cycles: Number of clock cycles to execute - * [Return value] - * None - */ -static FASTCALL void psp_sh2_exec(SH2_struct *yabause_state, u32 cycles) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - - state->cycles = yabause_state->cycles; - -#if defined(TRACE) || defined(TRACE_STEALTH) || defined(TRACE_LITE) - /* Avoid accumulating leftover cycles multiple times, since the trace - * code automatically adds state->cycles to the cycle accumulator when - * printing a trace line */ - sh2_trace_add_cycles(-(state->cycles)); -#endif - sh2_run(state, cycles); -#if defined(TRACE) || defined(TRACE_STEALTH) || defined(TRACE_LITE) - sh2_trace_add_cycles(state->cycles); -#endif - - yabause_state->cycles = state->cycles; -} - -/*************************************************************************/ - -/** - * psp_sh2_get_registers: Retrieve the values of all SH-2 registers. - * - * [Parameters] - * yabause_state: Yabause SH-2 context structure - * regs: Structure to receive register values - * [Return value] - * None - */ -static void psp_sh2_get_registers(SH2_struct *yabause_state, - sh2regs_struct *regs) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - memcpy(regs, state, sizeof(*regs)); -} - -/*----------------------------------*/ - -/** - * psp_sh2_get_{GPR,SR,GBR,VBR,MACH,MACL,PR,PC}: Return the value of the - * named register. - * - * [Parameters] - * yabause_state: Yabause SH-2 context structure - * num: General purpose register number to get (get_GPR() only) - * [Return value] - * Register's value - */ -static u32 psp_sh2_get_GPR(SH2_struct *yabause_state, int num) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - return state->R[num]; -} - -static u32 psp_sh2_get_SR(SH2_struct *yabause_state) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - return state->SR; -} - -static u32 psp_sh2_get_GBR(SH2_struct *yabause_state) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - return state->GBR; -} - -static u32 psp_sh2_get_VBR(SH2_struct *yabause_state) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - return state->VBR; -} - -static u32 psp_sh2_get_MACH(SH2_struct *yabause_state) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - return state->MACH; -} - -static u32 psp_sh2_get_MACL(SH2_struct *yabause_state) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - return state->MACL; -} - -static u32 psp_sh2_get_PR(SH2_struct *yabause_state) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - return state->PR; -} - -static u32 psp_sh2_get_PC(SH2_struct *yabause_state) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - return state->PC; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sh2_set_registers: Set the values of all SH-2 registers. - * - * [Parameters] - * yabause_state: Yabause SH-2 context structure - * regs: Structure containing new values for registers - * [Return value] - * None - */ -static void psp_sh2_set_registers(SH2_struct *yabause_state, - const sh2regs_struct *regs) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - memcpy(state, regs, sizeof(*regs)); -} - -/*----------------------------------*/ - -/** - * psp_sh2_set_{GPR,SR,GBR,VBR,MACH,MACL,PR,PC}: Set the value of the - * named register. - * - * [Parameters] - * yabause_state: Yabause SH-2 context structure - * num: General purpose register number to get (get_GPR() only) - * value: New value for register - * [Return value] - * None - */ -static void psp_sh2_set_GPR(SH2_struct *yabause_state, int num, u32 value) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->R[num] = value; -} - -static void psp_sh2_set_SR(SH2_struct *yabause_state, u32 value) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->SR = value; -} - -static void psp_sh2_set_GBR(SH2_struct *yabause_state, u32 value) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->GBR = value; -} - -static void psp_sh2_set_VBR(SH2_struct *yabause_state, u32 value) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->VBR = value; -} - -static void psp_sh2_set_MACH(SH2_struct *yabause_state, u32 value) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->MACH = value; -} - -static void psp_sh2_set_MACL(SH2_struct *yabause_state, u32 value) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->MACL = value; -} - -static void psp_sh2_set_PR(SH2_struct *yabause_state, u32 value) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->PR = value; -} - -static void psp_sh2_set_PC(SH2_struct *yabause_state, u32 value) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->PC = value; -} - -/*************************************************************************/ - -/** - * psp_sh2_send_interrupt: Send an interrupt to the given SH-2 processor. - * - * [Parameters] - * yabause_state: Yabause SH-2 context structure - * [Return value] - * None - */ -static void psp_sh2_send_interrupt(SH2_struct *yabause_state, - u8 vector, u8 level) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - if (UNLIKELY(vector > 127)) { - return; - } - sh2_signal_interrupt(state, vector, level); -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sh2_set_interrupts: Set the state of the interrupt stack. - * - * [Parameters] - * yabause_state: Yabause SH-2 context structure - * interrupts: Array to receive interrupt data - * [Return value] - * Number of pending interrupts - */ -static int psp_sh2_get_interrupts(SH2_struct *yabause_state, - interrupt_struct interrupts[MAX_INTERRUPTS]) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - int i; - for (i = 0; i < state->interrupt_stack_top && i < MAX_INTERRUPTS; i++) { - interrupts[i].level = state->interrupt_stack[i].level; - interrupts[i].vector = state->interrupt_stack[i].vector; - } - return state->interrupt_stack_top; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sh2_set_interrupts: Set the state of the interrupt stack. - * - * [Parameters] - * yabause_state: Yabause SH-2 context structure - * num_interrupts: Number of pending interrupts - * interrupts: Array of pending interrupts - * [Return value] - * None - */ -static void psp_sh2_set_interrupts(SH2_struct *yabause_state, - int num_interrupts, - const interrupt_struct interrupts[MAX_INTERRUPTS]) -{ - SH2State *state = (yabause_state == MSH2) ? master_SH2 : slave_SH2; - state->interrupt_stack_top = 0; - int i; - for (i = 0; i < num_interrupts; i++) { - if (UNLIKELY(interrupts[i].vector > 127)) { - return; - } - sh2_signal_interrupt(state, interrupts[i].vector, interrupts[i].level); - } -} - -/*************************************************************************/ - -/** - * psp_sh2_write_notify: Called when an external agent modifies memory. - * - * [Parameters] - * address: Beginning of address range to which data was written - * size: Size of address range to which data was written (in bytes) - * [Return value] - * None - */ -static void psp_sh2_write_notify(u32 address, u32 size) -{ - sh2_write_notify(address, size); -} - -/*************************************************************************/ -/**************************** Local functions ****************************/ -/*************************************************************************/ - -/** - * flush_caches: Callback function to flush the native CPU's caches. - * - * [Parameters] - * start: Pointer to start of range - * length: Length of range in bytes - * [Return value] - * None - */ -static void flush_caches(void *start, uint32_t length) -{ -#ifdef PSP // Protect so we can test this SH-2 core on other platforms - sceKernelDcacheWritebackInvalidateRange(start, length); - sceKernelIcacheInvalidateRange(start, length); -#endif -} - -/*-----------------------------------------------------------------------*/ - -/** - * invalid_opcode_handler: Callback function for invalid opcodes detected - * in the instruction stream. - * - * [Parameters] - * state: Processor state block pointer - * PC: PC at which the invalid instruction was found - * opcode: The invalid opcode itself - * [Return value] - * None - */ -static void invalid_opcode_handler(SH2State *state, uint32_t PC, - uint16_t opcode) -{ - SH2_struct *yabause_state = (SH2_struct *)(state->userdata); - uint32_t saved_PC = state->PC; - state->PC = PC; // Show the proper PC in the error message - yabause_state->instruction = opcode; - YabSetError(YAB_ERR_SH2INVALIDOPCODE, yabause_state); - state->PC = saved_PC; -} - -/*-----------------------------------------------------------------------*/ - -/** - * trace_insn_handler: Callback function for tracing instructions. - * Updates the appropriate Yabause SH2_struct's registers and cycle count, - * then calls out to the common SH-2 tracing functionality. - * - * [Parameters] - * state: Processor state block pointer - * address: Address of instruction to trace - * [Return value] - * None - */ -static FASTCALL void trace_insn_handler(SH2State *state, uint32_t address) -{ - SH2_struct *yabause_state = (SH2_struct *)(state->userdata); - yabause_state->cycles = state->cycles; - sh2_trace(yabause_state, address); -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-sh2.h b/yabause/src/psp/psp-sh2.h deleted file mode 100644 index e69dbddaf0..0000000000 --- a/yabause/src/psp/psp-sh2.h +++ /dev/null @@ -1,46 +0,0 @@ -/* src/psp/psp-sh2.h: Header for SH-2 emulator for PSP - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_SH2_H -#define PSP_SH2_H - -#include "../sh2core.h" // for SH2Interface_struct - -/*************************************************************************/ - -/* Module interface definition */ -extern SH2Interface_struct SH2PSP; - -/* Unique module ID (must be different from any in ../sh2{core,int}.h) */ -#define SH2CORE_PSP 0x5CE // "SCE" - -/*************************************************************************/ - -#endif // PSP_SH2_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-sound.c b/yabause/src/psp/psp-sound.c deleted file mode 100644 index c01982266a..0000000000 --- a/yabause/src/psp/psp-sound.c +++ /dev/null @@ -1,720 +0,0 @@ -/* src/psp/psp-sound.c: PSP sound output module - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../memory.h" -#include "../scsp.h" - -#include "config.h" -#include "me.h" -#include "me-utility.h" -#include "sys.h" -#include "psp-sound.h" - -/* Macro for uncached access to variables / structure fields */ -#define UNCACHED(var) (*((typeof(&var))((uint32_t)(&var) | 0x40000000))) - -/*************************************************************************/ -/************************* Configuration options *************************/ -/*************************************************************************/ - -/** - * DUMP_AUDIO: When defined, the program will write a dump of all audio - * data sent to the hardware (except filler data sent when the emulator - * falls behind real time) to "audio.pcm" in the current directory. - */ -// #define DUMP_AUDIO - -/*************************************************************************/ -/************************* Interface definition **************************/ -/*************************************************************************/ - -/* Interface function declarations (must come before interface definition) */ - -static int psp_sound_init(void); -static void psp_sound_deinit(void); -static int psp_sound_reset(void); -static int psp_sound_change_video_format(int vertfreq); -static void psp_sound_update_audio(u32 *leftchanbuffer, u32 *rightchanbuffer, - u32 num_samples); -static u32 psp_sound_get_audio_space(void); -static void psp_sound_mute_audio(void); -static void psp_sound_unmute_audio(void); -static void psp_sound_set_volume(int volume); - -/*-----------------------------------------------------------------------*/ - -/* Module interface definition */ - -SoundInterface_struct SNDPSP = { - .id = SNDCORE_PSP, - .Name = "PSP Sound Interface", - .Init = psp_sound_init, - .DeInit = psp_sound_deinit, - .Reset = psp_sound_reset, - .ChangeVideoFormat = psp_sound_change_video_format, - .UpdateAudio = psp_sound_update_audio, - .GetAudioSpace = psp_sound_get_audio_space, - .MuteAudio = psp_sound_mute_audio, - .UnMuteAudio = psp_sound_unmute_audio, - .SetVolume = psp_sound_set_volume, -}; - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Playback rate in Hz (unchangeable) */ -#define PLAYBACK_RATE 44100 - -/* Playback buffer size in samples (larger values = less chance of skipping - * but greater lag) */ -#define BUFFER_SIZE 256 - -/* Number of BUFFER_SIZE-sized audio buffers in the playback buffer (see - * description below) */ -#define NUM_BUFFERS 8 - -/* - * Playback buffer descriptor, implementing a lockless ring buffer with the - * following semantics: - * WRITER (main program): - * (1) Waits for .write_ready[.next_write] to become nonzero. - * (2) Writes BUFFER_SIZE samples of data into .buffer[.next_write]. - * (3) Sets .write_ready[.next_write] to zero. - * (4) Increments .next_write to point to the next audio buffer. - * READER (playback thread): - * (1) Waits for .write_ready[.next_play] to become zero. - * (2) Submits .buffer[.next_play] to the OS (which blocks until the - * previous buffer finishes playing). - * (3) Sets .write_ready[.cur_play] to nonzero. - * (4) Sets .cur_play to .next_play. - * (5) Increments .next_play to point to the next audio buffer. - * - * Note that at least three audio buffers are required in the ring buffer: - * - One currently being played by the hardware. - * - One queued for playback by the hardware. - * - One into which the main program is writing. - * A minimum of at least four buffers is recommended to allow overflow - * room, since the sample generation rate will typically not be locked to - * the hardware playback rate. - */ -typedef struct PSPSoundBufferDesc_ { - __attribute__((aligned(64))) int16_t buffer[NUM_BUFFERS][BUFFER_SIZE*2]; - /* Keep this on its own cache line for uncached access by both SC and ME */ - __attribute__((aligned(64))) - volatile uint8_t write_ready[NUM_BUFFERS]; - // When nonzero, data can be stored in buffer[next_write] - /* Start a new cache line here (these are written by the ME) */ - __attribute__((aligned(64))) - unsigned int next_write; - // Index of next buffer to store data into - unsigned int saved_samples; - // Number of samples accumulated in next_write buffer - /* Start another new cache line here (these are written by the SC) */ - __attribute__((aligned(64))) - int started; // Nonzero if channel is playing - int channel; // Channel number allocated for this buffer - unsigned int cur_play; - // Index of buffer currently being played by the hardware - unsigned int next_play; - // Index of next buffer to submit for playback - /* Internal use: */ - SceUID thread; // Playback thread handle - int stop; // Flag to tell thread to terminate -} PSPSoundBufferDesc; -static PSPSoundBufferDesc stereo_buffer; - -/* Mute flag (used by Mute and UnMute methods) */ -static int muted = 1; - -#ifdef DUMP_AUDIO -/* Audio output file */ -static int dump_fd; -#endif - -/*----------------------------------*/ - -/* Uncached pointer to sound RAM (to save generating it on every access) */ -static uint8_t *SoundRam_uncached; - -/*-----------------------------------------------------------------------*/ - -/* Local function declarations */ - -static FASTCALL u8 psp_SoundRamReadByte(u32 address); -static FASTCALL u16 psp_SoundRamReadWord(u32 address); -static FASTCALL u32 psp_SoundRamReadLong(u32 address); -static FASTCALL void psp_SoundRamWriteByte(u32 address, u8 data); -static FASTCALL void psp_SoundRamWriteWord(u32 address, u16 data); -static FASTCALL void psp_SoundRamWriteLong(u32 address, u32 data); - -static int start_channel(PSPSoundBufferDesc *buffer_desc); -void stop_channel(PSPSoundBufferDesc *buffer_desc); -static int playback_thread(SceSize args, void *argp); - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * psp_sound_init: Initialize the sound interface. - * - * [Parameters] - * None - * [Return value] - * Zero on success, negative on error - */ -static int psp_sound_init(void) -{ - if (stereo_buffer.started) { - /* Already initialized! */ - return 0; - } - -#ifdef DUMP_AUDIO - dump_fd = sceIoOpen("audio.pcm", - PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0600); - if (dump_fd < 0) { - DMSG("open(audio.pcm): %s", psp_strerror(dump_fd)); - dump_fd = 0; - } -#endif - - if (!start_channel(&stereo_buffer)) { - DMSG("Failed to start playback"); - return -1; - } - - /* If the Media Engine is in use, reassign the sound RAM access - * functions so we read/write through the cache as appropriate. */ - if (me_available && config_get_use_me()) { - SoundRam_uncached = (uint8_t *)((uintptr_t)SoundRam | 0x40000000); - unsigned int i; - for (i = 0x5A0; i < 0x5B0; i++) { - ReadByteList [i] = psp_SoundRamReadByte; - ReadWordList [i] = psp_SoundRamReadWord; - ReadLongList [i] = psp_SoundRamReadLong; - WriteByteList[i] = psp_SoundRamWriteByte; - WriteWordList[i] = psp_SoundRamWriteWord; - WriteLongList[i] = psp_SoundRamWriteLong; - } - } - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_deinit: Shut down the sound interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_sound_deinit(void) -{ - stop_channel(&stereo_buffer); - - unsigned int i; - for (i = 0x5A0; i < 0x5B0; i++) { - ReadByteList [i] = SoundRamReadByte; - ReadWordList [i] = SoundRamReadWord; - ReadLongList [i] = SoundRamReadLong; - WriteByteList[i] = SoundRamWriteByte; - WriteWordList[i] = SoundRamWriteWord; - WriteLongList[i] = SoundRamWriteLong; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_reset: Reset the sound interface. - * - * [Parameters] - * None - * [Return value] - * Zero on success, negative on error - */ -static int psp_sound_reset(void) -{ - /* Nothing to do */ - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_change_video_format: Handle a change in the video refresh - * frequency. - * - * [Parameters] - * vertfreq: New refresh frequency (Hz) - * [Return value] - * Zero on success, negative on error - */ -static int psp_sound_change_video_format(int vertfreq) -{ - /* Nothing to do */ - return 0; -} - -/*************************************************************************/ - -/** - * psp_sound_update_audio: Output audio data. - * - * [Parameters] - * leftchanbuffer: Left channel sample array, as _signed_ 16-bit samples - * rightchanbuffer: Right channel sample array, as _signed_ 16-bit samples - * num_samples: Number of samples in sample arrays - * [Return value] - * None - */ -static void psp_sound_update_audio(u32 *leftchanbuffer, u32 *rightchanbuffer, - u32 num_samples) -{ - const unsigned int next_write = stereo_buffer.next_write; - - if (!leftchanbuffer || !rightchanbuffer - || !UNCACHED(stereo_buffer.write_ready[next_write]) - || num_samples == 0 - || num_samples > BUFFER_SIZE - stereo_buffer.saved_samples - ) { - if (!meUtilityIsME()) { // Can't write to stderr on the ME - DMSG("Invalid parameters: %p %p %u (status: wr=%d ss=%d)", - leftchanbuffer, rightchanbuffer, (unsigned int)num_samples, - UNCACHED(stereo_buffer.write_ready[next_write]), - stereo_buffer.saved_samples); - } - return; - } - - const int32_t *in_l = (int32_t *)leftchanbuffer; - const int32_t *in_r = (int32_t *)rightchanbuffer; - int16_t *out = - &stereo_buffer.buffer[next_write][stereo_buffer.saved_samples * 2]; - - uint32_t i; - for (i = 0; i < num_samples; i++) { - const int32_t lval = *in_l++; - const int32_t rval = *in_r++; - *out++ = bound(lval, -0x8000, 0x7FFF); - *out++ = bound(rval, -0x8000, 0x7FFF); - } - - stereo_buffer.saved_samples += num_samples; - if (stereo_buffer.saved_samples >= BUFFER_SIZE) { - if (meUtilityIsME()) { - /* Make sure the playback thread sees all the audio data */ - meUtilityDcacheWritebackInvalidateAll(); - } - UNCACHED(stereo_buffer.write_ready[next_write]) = 0; - stereo_buffer.saved_samples = 0; - stereo_buffer.next_write = (next_write + 1) % NUM_BUFFERS; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_get_audio_space: Return the number of samples immediately - * available for outputting audio data. - * - * [Parameters] - * None - * [Return value] - * Number of samples available - */ -static u32 psp_sound_get_audio_space(void) -{ - if (UNCACHED(stereo_buffer.write_ready[stereo_buffer.next_write])) { - return BUFFER_SIZE - stereo_buffer.saved_samples; - } else { - return 0; - } -} - -/*************************************************************************/ - -/** - * psp_sound_mute_audio: Disable audio output. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_sound_mute_audio(void) -{ - muted = 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_mute_audio: Enable audio output. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_sound_unmute_audio(void) -{ - muted = 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_set_volume: Set the audio output volume. - * - * [Parameters] - * volume: New volume (0-100, 100 = full volume) - * [Return value] - * None - */ -static void psp_sound_set_volume(int volume) -{ - const int pspvol = (PSP_AUDIO_VOLUME_MAX * volume + 50) / 100; - if (stereo_buffer.started) { - sceAudioChangeChannelVolume(stereo_buffer.channel, pspvol, pspvol); - } -} - -/*************************************************************************/ -/********************* PSP-local interface functions *********************/ -/*************************************************************************/ - -/** - * psp_sound_pause: Stop audio output. Called when the system is being - * suspended. - * - * [Parameters] - * None - * [Return value] - * None - */ -void psp_sound_pause(void) -{ - if (stereo_buffer.started) { - sceKernelSuspendThread(stereo_buffer.thread); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_unpause: Resume audio output. Called when the system is - * resuming from a suspend. - * - * [Parameters] - * None - * [Return value] - * None - */ -void psp_sound_unpause(void) -{ - if (stereo_buffer.started) { - sceKernelResumeThread(stereo_buffer.thread); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_exit: Terminate all playback in preparation for exiting. - * - * [Parameters] - * None - * [Return value] - * None - */ -void psp_sound_exit(void) -{ - if (stereo_buffer.started) { - stop_channel(&stereo_buffer); - } -} - -/*************************************************************************/ -/* Sound RAM access functions (for use when the 68k is running on the ME) */ -/*************************************************************************/ - -/** - * psp_SoundRamRead{Byte,Word,Long}: Sound RAM read access functions for - * use when the sound CPU is being emulated on the Media Engine. These - * functions access sound RAM using uncached pointers. - * - * 2Mbit mode (MEM4MB == 0) is not supported by these functions. - * - * [Parameters] - * address: Address to read from - * [Return value] - * Data loaded from given address - */ -static FASTCALL u8 psp_SoundRamReadByte(u32 address) -{ - address &= 0x7FFFF; - return T2ReadByte(SoundRam_uncached, address); -} - -static FASTCALL u16 psp_SoundRamReadWord(u32 address) -{ - address &= 0x7FFFF; - return T2ReadWord(SoundRam_uncached, address); -} - -static FASTCALL u32 psp_SoundRamReadLong(u32 address) -{ - address &= 0x7FFFF; - return T2ReadLong(SoundRam_uncached, address); -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_SoundRamWrite{Byte,Word,Long}: Sound RAM write access functions for - * use when the sound CPU is being emulated on the Media Engine. These - * functions do _not_ access sound RAM using uncached pointers; data is - * assumed to be flushed by the SCSP at periodic intervals. - * - * 2Mbit mode (MEM4MB == 0) is not supported by these functions. - * - * [Parameters] - * address: Address to write to - * data: Data to store - * [Return value] - * None - */ -static FASTCALL void psp_SoundRamWriteByte(u32 address, u8 data) -{ - address &= 0x7FFFF; - if (address < config_get_me_uncached_boundary()) { - T2WriteByte(SoundRam_uncached, address, data); - } else { - T2WriteByte(SoundRam, address, data); - } - M68KWriteNotify(address, 1); -} - -static FASTCALL void psp_SoundRamWriteWord(u32 address, u16 data) -{ - address &= 0x7FFFF; - if (address < config_get_me_uncached_boundary()) { - T2WriteWord(SoundRam_uncached, address, data); - } else { - T2WriteWord(SoundRam, address, data); - } - M68KWriteNotify(address, 2); -} - -static FASTCALL void psp_SoundRamWriteLong(u32 address, u32 data) -{ - address &= 0x7FFFF; - if (address < config_get_me_uncached_boundary()) { - T2WriteLong(SoundRam_uncached, address, data); - } else { - T2WriteLong(SoundRam, address, data); - } - M68KWriteNotify(address, 4); -} - -/*************************************************************************/ -/****************** Low-level audio channel management *******************/ -/*************************************************************************/ - -/** - * start_channel: Allocate a new channel and starts playback. - * - * [Parameters] - * buffer_desc: Playback buffer descriptor - * [Return value] - * Nonzero on success, zero on error - */ -static int start_channel(PSPSoundBufferDesc *buffer_desc) -{ - if (!buffer_desc) { - DMSG("buffer_desc == NULL"); - return 0; - } - if (buffer_desc->started) { - DMSG("Buffer is already started!"); - return 0; - } - - /* Allocate a hardware channel */ - buffer_desc->channel = sceAudioChReserve( - PSP_AUDIO_NEXT_CHANNEL, BUFFER_SIZE, PSP_AUDIO_FORMAT_STEREO - ); - if (buffer_desc->channel < 0) { - DMSG("Failed to allocate channel: %s", - psp_strerror(buffer_desc->channel)); - return 0; - } - - /* Initialize the ring buffer */ - buffer_desc->cur_play = NUM_BUFFERS - 1; - buffer_desc->next_play = 0; - buffer_desc->next_write = 0; - int i; - for (i = 0; i < NUM_BUFFERS; i++) { - buffer_desc->write_ready[i] = 1; - } - buffer_desc->stop = 0; - /* Also write everything out of the cache so it's ready for the ME */ - sceKernelDcacheWritebackAll(); - - /* Start the playback thread */ - char thname[100]; - snprintf(thname, sizeof(thname), "YabauseSoundCh%d", buffer_desc->channel); - SceUID handle = sys_start_thread(thname, playback_thread, - THREADPRI_SOUND, 0x1000, - sizeof(buffer_desc), &buffer_desc); - if (handle < 0) { - DMSG("Failed to create thread: %s", psp_strerror(handle)); - sceAudioChRelease(buffer_desc->channel); - return 0; - } - buffer_desc->thread = handle; - - /* Success */ - buffer_desc->started = 1; - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * stop_channel: Stop playback from the given playback buffer. - * - * [Parameters] - * buffer_desc: Playback buffer descriptor - * [Return value] - * None - */ -void stop_channel(PSPSoundBufferDesc *buffer_desc) -{ - if (!buffer_desc) { - DMSG("buffer_desc == NULL"); - return; - } - if (!buffer_desc->started) { - DMSG("Buffer has not been started!"); - return; - } - - /* Signal the thread to stop, then wait for it (if we try to stop the - * thread in the middle of an audio write, we won't be able to free - * the hardware channel) */ - buffer_desc->stop = 1; - int tries; - for (tries = (1000 * (2*BUFFER_SIZE)/PLAYBACK_RATE); tries > 0; tries--) { - if (sys_delete_thread_if_stopped(buffer_desc->thread, NULL)) { - break; - } - sceKernelDelayThread(1000); // Wait for 1ms before trying again - } - - if (!tries) { - /* The thread didn't stop on its own, so terminate it with - * extreme prejudice */ - sceKernelTerminateDeleteThread(buffer_desc->thread); - sceAudioChRelease(buffer_desc->channel); - memset(buffer_desc, 0, sizeof(*buffer_desc)); - } -} - -/*************************************************************************/ - -/** - * playback_thread: Sound playback thread. Continually sends the ring - * buffer data to the OS until signaled to stop. - * - * [Parameters] - * args: Thread argument size - * argp: Thread argument pointer - * [Return value] - * Always zero - */ -static int playback_thread(SceSize args, void *argp) -{ - PSPSoundBufferDesc * const buffer_desc = *(PSPSoundBufferDesc **)argp; - - /* Temporary buffer for dummy audio data when the emulator falls behind - * real time (filled with the last sample sent to avoid clicks). This - * thread is only launched once, so "static" is safe. */ - static uint32_t dummy_buffer[BUFFER_SIZE]; // 1 stereo sample = 32 bits - static uint32_t last_sample; // Last stereo sample played - - while (!buffer_desc->stop) { - const unsigned int next_play = buffer_desc->next_play; -//static int x;int now=sceKernelGetSystemTimeLow();if(now-x>100000){printf("--- audio stat: %u %u %u %u cp=%u np=%u nw=%u\n",UNCACHED(buffer_desc->write_ready[0]),UNCACHED(buffer_desc->write_ready[1]),UNCACHED(buffer_desc->write_ready[2]),UNCACHED(buffer_desc->write_ready[3]),buffer_desc->cur_play,next_play,UNCACHED(buffer_desc->next_write));x=now;} - if (!UNCACHED(buffer_desc->write_ready[next_play])) { // i.e., ready for playback - const void *buffer = buffer_desc->buffer[next_play]; - last_sample = ((const uint32_t *)buffer)[BUFFER_SIZE - 1]; - sceAudioOutputBlocking(buffer_desc->channel, muted ? 0 : 0x8000, - buffer); -#ifdef DUMP_AUDIO - sceIoWrite(dump_fd, buffer, BUFFER_SIZE*4); -#endif - UNCACHED(buffer_desc->write_ready[buffer_desc->cur_play]) = 1; - buffer_desc->cur_play = next_play; - buffer_desc->next_play = (next_play + 1) % NUM_BUFFERS; - } else { - const uint32_t sample = last_sample; // Help out optimizer - uint32_t *ptr32 = dummy_buffer; - unsigned int i; - for (i = 0; i < BUFFER_SIZE; i += 8) { - ptr32[i+0] = sample; - ptr32[i+1] = sample; - ptr32[i+2] = sample; - ptr32[i+3] = sample; - ptr32[i+4] = sample; - ptr32[i+5] = sample; - ptr32[i+6] = sample; - ptr32[i+7] = sample; - } - sceAudioOutputBlocking(buffer_desc->channel, muted ? 0 : 0x8000, - dummy_buffer); - } - } - - sceAudioChRelease(buffer_desc->channel); - memset(buffer_desc, 0, sizeof(*buffer_desc)); - return 0; -} - -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-sound.h b/yabause/src/psp/psp-sound.h deleted file mode 100644 index 89b46495d1..0000000000 --- a/yabause/src/psp/psp-sound.h +++ /dev/null @@ -1,80 +0,0 @@ -/* src/psp/psp-sound.h: PSP sound output module header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_SOUND_H -#define PSP_SOUND_H - -#include "../scsp.h" // for SoundInterface_struct - -/*************************************************************************/ - -/* Module interface definition */ -extern SoundInterface_struct SNDPSP; - -/* Unique module ID (must be different from any in scsp.h) */ -#define SNDCORE_PSP 0x5CE // "SCE" - -/*-----------------------------------------------------------------------*/ - -/** - * psp_sound_pause: Stop audio output. Called when the system is being - * suspended. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void psp_sound_pause(void); - -/** - * psp_sound_unpause: Resume audio output. Called when the system is - * resuming from a suspend. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void psp_sound_unpause(void); - -/** - * psp_sound_exit: Terminate all playback in preparation for exiting. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void psp_sound_exit(void); - -/*************************************************************************/ - -#endif // PSP_SOUND_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-video-bitmap.c b/yabause/src/psp/psp-video-bitmap.c deleted file mode 100644 index 1083865437..0000000000 --- a/yabause/src/psp/psp-video-bitmap.c +++ /dev/null @@ -1,314 +0,0 @@ -/* src/psp/psp-video-bitmap.c: Bitmapped background graphics handling for - PSP video module - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../vidshared.h" - -#include "display.h" -#include "gu.h" -#include "psp-video.h" -#include "psp-video-internal.h" -#include "texcache.h" - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * vdp2_draw_bitmap: Draw a graphics layer bitmap. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -void vdp2_draw_bitmap(vdp2draw_struct *info, const clipping_struct *clip) -{ - /* Set up vertices */ - VertexUVXYZ *vertices = pspGuGetMemoryMerge(sizeof(*vertices) * 2); - vertices[0].u = 0; - vertices[0].v = 0; - vertices[0].x = info->x * info->coordincx; - vertices[0].y = info->y * info->coordincy; - vertices[0].z = 0; - vertices[1].u = info->cellw; - vertices[1].v = info->cellh; - vertices[1].x = (info->x + info->cellw) * info->coordincx; - vertices[1].y = (info->y + info->cellh) * info->coordincy; - vertices[1].z = 0; - - /* FIXME: only very basic clipping processing at the moment; see - * vidsoft.c for more details on how this works */ - if ((info->wctl & 0x3) == 0x3) { - vertices[0].x = clip[0].xstart; - vertices[0].y = clip[0].ystart; - vertices[1].x = clip[0].xend + 1; - vertices[1].y = clip[0].yend + 1; - vertices[1].u = (vertices[1].x - vertices[0].x) / info->coordincx; - vertices[1].v = (vertices[1].y - vertices[0].y) / info->coordincy; - /* Offset the bitmap address appropriately */ - const int bpp = (info->colornumber==4 ? 32 : - info->colornumber>=2 ? 16 : - info->colornumber==1 ? 8 : 4); - const int xofs = clip[0].xstart - info->x; - const int yofs = clip[0].ystart - info->y; - info->charaddr += (yofs * info->cellw + xofs) * bpp / 8; - } - - /* Draw the bitmap */ - texcache_load_bitmap( - info->charaddr, - (vertices[1].u - vertices[0].u + 7) & -8, - vertices[1].v - vertices[0].v, - info->cellw, info->colornumber, info->transparencyenable, - info->coloroffset, info->paladdr << 4, - info->cor, info->cog, info->cob, - 0 // Bitmaps are likely to change, so don't cache them persistently - ); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 2, NULL, vertices); -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp2_draw_bitmap_t8: Draw an 8-bit indexed graphics layer bitmap. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -void vdp2_draw_bitmap_t8(vdp2draw_struct *info, const clipping_struct *clip) -{ - /* Set up vertices */ - // FIXME: this will break with a final (clipped) width above 512; - // need to split the texture in half in that case - VertexUVXYZ *vertices = pspGuGetMemoryMerge(sizeof(*vertices) * 2); - vertices[0].u = 0; - vertices[0].v = 0; - vertices[0].x = info->x * info->coordincx; - vertices[0].y = info->y * info->coordincy; - vertices[0].z = 0; - vertices[1].u = info->cellw; - vertices[1].v = info->cellh; - vertices[1].x = (info->x + info->cellw) * info->coordincx; - vertices[1].y = (info->y + info->cellh) * info->coordincy; - vertices[1].z = 0; - - /* FIXME: only very basic clipping processing at the moment; see - * vidsoft.c for more details on how this works */ - if ((info->wctl & 0x3) == 0x3) { - vertices[0].x = clip[0].xstart; - vertices[0].y = clip[0].ystart; - vertices[1].x = clip[0].xend + 1; - vertices[1].y = clip[0].yend + 1; - vertices[1].u = (vertices[1].x - vertices[0].x) / info->coordincx; - vertices[1].v = (vertices[1].y - vertices[0].y) / info->coordincy; - /* Offset the bitmap address appropriately */ - const int bpp = (info->colornumber==4 ? 32 : - info->colornumber>=2 ? 16 : - info->colornumber==1 ? 8 : 4); - const int xofs = clip[0].xstart - info->x; - const int yofs = clip[0].ystart - info->y; - info->charaddr += (yofs * info->cellw + xofs) * bpp / 8; - } - - /* Set up the color table */ - guClutMode(GU_PSM_8888, 0, 0xFF, 0); - void *ptr = vdp2_gen_t8_clut( - info->coloroffset, info->paladdr<<4, - info->transparencyenable, info->cor, info->cog, info->cob - ); - if (LIKELY(ptr)) { - guClutLoad(256/8, ptr); - } - - /* Draw the bitmap */ - guTexMode(GU_PSM_8888, 0, 0, 0); - guTexMode(GU_PSM_T8, 0, 0, 0); - guTexImage(0, 512, 512, info->cellw, &Vdp2Ram[info->charaddr & 0x7FFFF]); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 2, NULL, vertices); -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp2_draw_bitmap_32: Draw a 32-bit ARGB1888 unscaled graphics layer - * bitmap. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -void vdp2_draw_bitmap_32(vdp2draw_struct *info, const clipping_struct *clip) -{ - /* Determine the area to be drawn */ - unsigned int x0, y0, width, height; - /* FIXME: only very basic clipping processing at the moment; see - * vidsoft.c for more details on how this works */ - if ((info->wctl & 0x3) == 0x3) { - x0 = clip[0].xstart; - y0 = clip[0].ystart; - width = (clip[0].xend + 1) - x0; - height = (clip[0].yend + 1) - y0; - /* Offset the bitmap address appropriately */ - const int xofs = clip[0].xstart - info->x; - const int yofs = clip[0].ystart - info->y; - info->charaddr += (yofs * info->cellw + xofs) * 4; - } else { - x0 = info->x; - y0 = info->y; - width = info->cellw; - height = info->cellh; - } - - /* Set up vertices (using optimized 64-byte-wide strips) */ - // FIXME: this will work incorrectly on bitmaps wider than 512 pixels, - // if there are any such (VDP2 RAM is only big enough for 512x256) - const uint32_t nverts = ((width+15) / 16) * 2; - VertexUVXYZ *vertices = pspGuGetMemoryMerge(sizeof(*vertices) * nverts); - unsigned int x, i; - for (x = i = 0; x < width; x += 16, i += 2) { - const unsigned int thisw = (width-x > 16 ? 16 : width-x); - vertices[i+0].u = x; - vertices[i+0].v = 0; - vertices[i+0].x = x0 + x; - vertices[i+0].y = y0; - vertices[i+0].z = 0; - vertices[i+1].u = x + thisw; - vertices[i+1].v = height; - vertices[i+1].x = x0 + x + thisw; - vertices[i+1].y = y0 + height; - vertices[i+1].z = 0; - } - - /* Set up GE parameters for drawing */ - guTexFlush(); - guTexMode(GU_PSM_T32, 0, 0, 0); - guTexImage(0, 512, 512, info->cellw, &Vdp2Ram[info->charaddr & 0x7FFFF]); - guAmbientColor(0xFFFFFFFF); - guTexFunc(GU_TFX_REPLACE, 1); - guDisable(GU_BLEND); - - /* If transparency is enabled, set up an offscreen buffer for - * rendering; if we can't (not enough spare VRAM), just draw with - * transparency disabled */ - uint32_t *offscreen_buffer = NULL; - uint32_t offscreen_stride = 0; - if (info->transparencyenable) { - offscreen_stride = (width + 3) & -4; - offscreen_buffer = display_alloc_vram(offscreen_stride * height); - if (offscreen_buffer) { - /* Adjust the draw buffer pointer so we don't have to mess - * with the vertex coordinates */ - const uint32_t offset = - vertices[0].y * offscreen_stride + vertices[0].x; - guDrawBuffer(GU_PSM_8888, - offscreen_buffer - offset, offscreen_stride); - } - } - - /* Draw each of the RGB components independently */ - unsigned int rgb; - for (rgb = 0; rgb < 3; rgb++) { - /* Set up the color table for this component */ - const int ofs = (rgb==0 ? info->cor : rgb==1 ? info->cog : info->cob); - void *clut = vdp2_gen_32_clut(ofs); - if (clut) { - guClutMode(GU_PSM_8888, (3-rgb)*8, 0xFF, 0); - guClutLoad(256/8, clut); - } - - /* Blit this component to the screen. If we're using transparency, - * also clear the alpha byte on the first blit so we only need a - * single "set" operation later. */ - if (offscreen_buffer && rgb == 0) { - guStencilOp(GU_ZERO, GU_ZERO, GU_ZERO); // Clear alpha bytes - guEnable(GU_STENCIL_TEST); - } - guPixelMask(~(0xFF0000FF << (rgb*8))); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - nverts, NULL, vertices); - if (offscreen_buffer && rgb == 0) { - guDisable(GU_STENCIL_TEST); - } - } - guPixelMask(0); - - /* Mask off transparent pixels and blit back to the display buffer - * if appropriate */ - if (offscreen_buffer) { - static const __attribute__((aligned(64))) uint32_t mask_clut[8] = - {0, ~0}; - guClutMode(GU_PSM_8888, 7, 0x1, 0); - guClutLoad(1, mask_clut); - guAlphaFunc(GU_EQUAL, 0xFF, 0xFF); // Only pass non-transparent pixels - guEnable(GU_ALPHA_TEST); - guStencilFunc(GU_ALWAYS, 0xFF, 0xFF); // Set drawn alpha bytes to 255 - guStencilOp(GU_REPLACE, GU_REPLACE, GU_REPLACE); - guEnable(GU_STENCIL_TEST); - guPixelMask(0xFFFFFF); // Only modify the alpha byte - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - nverts, NULL, vertices); - guPixelMask(0); - guStencilOp(GU_KEEP, GU_KEEP, GU_KEEP); - guDisable(GU_STENCIL_TEST); - guDisable(GU_ALPHA_TEST); - - guDrawBuffer(GU_PSM_8888, display_work_buffer(), DISPLAY_STRIDE); - guTexFlush(); - guTexMode(GU_PSM_8888, 0, 0, 0); - guTexImage(0, 512, 512, offscreen_stride, offscreen_buffer); - guTexFunc(GU_TFX_REPLACE, 1); - guEnable(GU_BLEND); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - nverts, NULL, vertices); - } - - /* Turn blending back on before returning (in case we didn't do so for - * transparency handling), since everyone else expects it to be on */ - guEnable(GU_BLEND); -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-video-internal.h b/yabause/src/psp/psp-video-internal.h deleted file mode 100644 index 5fc4120ffe..0000000000 --- a/yabause/src/psp/psp-video-internal.h +++ /dev/null @@ -1,431 +0,0 @@ -/* src/psp/psp-video-internal.h: Internal header for PSP video module - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_VIDEO_INTERNAL_H -#define PSP_VIDEO_INTERNAL_H - -#include "../vdp1.h" -#include "../vdp2.h" -#include "../vidshared.h" - -/*************************************************************************/ -/************************** Internal constants ***************************/ -/*************************************************************************/ - -/* Graphics layer identifiers. */ - -enum {BG_NBG0 = 0, BG_NBG1, BG_NBG2, BG_NBG3, BG_RBG0}; - -/*************************************************************************/ -/******************* Map drawing routine declarations ********************/ -/*************************************************************************/ - -/** - * vdp2_draw_bitmap: Draw a graphics layer bitmap. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -extern void vdp2_draw_bitmap(vdp2draw_struct *info, - const clipping_struct *clip); - -/** - * vdp2_draw_bitmap_t8: Draw an 8-bit indexed graphics layer bitmap. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -extern void vdp2_draw_bitmap_t8(vdp2draw_struct *info, - const clipping_struct *clip); - -/** - * vdp2_draw_bitmap_32: Draw a 32-bit ARGB1888 unscaled graphics layer - * bitmap. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -extern void vdp2_draw_bitmap_32(vdp2draw_struct *info, - const clipping_struct *clip); - -/*----------------------------------*/ - -/** - * vdp2_draw_map_rotated: Draw a rotated graphics layer. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -extern void vdp2_draw_map_rotated(vdp2draw_struct *info, - const clipping_struct *clip); - -/*----------------------------------*/ - -/** - * vdp2_draw_map_8x8: Draw a graphics layer composed of 8x8 patterns of - * any format. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -extern void vdp2_draw_map_8x8(vdp2draw_struct *info, - const clipping_struct *clip); - -/** - * vdp2_draw_map_8x8_t8: Draw a graphics layer composed of 8-bit indexed - * color 8x8 patterns. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -extern void vdp2_draw_map_8x8_t8(vdp2draw_struct *info, - const clipping_struct *clip); - -/** - * vdp2_draw_map_16x16: Draw a graphics layer composed of 16x16 patterns - * of any format. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -extern void vdp2_draw_map_16x16(vdp2draw_struct *info, - const clipping_struct *clip); - -/** - * vdp2_draw_map_16x16_t8: Draw a graphics layer composed of 8-bit indexed - * color 16x16 patterns. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -extern void vdp2_draw_map_16x16_t8(vdp2draw_struct *info, - const clipping_struct *clip); - -/*************************************************************************/ -/**************** Game-specific optimizations and tweaks *****************/ -/*************************************************************************/ - -/** - * psp_video_apply_tweaks: Apply game-specific optimizations and tweaks - * for faster/better PSP video output. Called at the beginning of drawing - * each frame. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void psp_video_apply_tweaks(void); - -/*************************************************************************/ - -/** - * CustomDrawRoutine: Type of a custom drawing routine for a graphics - * layer, used with psp_video_set_draw_routine(). - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * Nonzero if the graphics layer was drawn, zero if not - */ -typedef int CustomDrawRoutine(vdp2draw_struct *info, - const clipping_struct *clip); - -/** - * psp_video_set_draw_routine: Set a custom drawing routine for a specific - * graphics layer. If "is_fast" is true when setting a routine for RBG0, - * the frame rate will not be halved regardless of the related setting in - * the configuration menu. - * - * [Parameters] - * layer: Graphics layer (BG_*) - * func: Drawing routine (NULL to clear any previous setting) - * is_fast: For BG_RBG0, indicates whether the routine is fast enough - * to be considered a non-distorted layer for the purposes - * of frame rate adjustment; ignored for other layers - * [Return value] - * None - */ -extern void psp_video_set_draw_routine(int layer, CustomDrawRoutine *func, - int is_fast); - -/*************************************************************************/ -/**************** Other utility routines and declarations ****************/ -/*************************************************************************/ - -/* Displayed width and height */ -extern unsigned int disp_width, disp_height; - -/* Scale (right-shift) applied to X and Y coordinates */ -extern unsigned int disp_xscale, disp_yscale; - -/* Total number of frames to skip before we draw the next one */ -extern unsigned int frames_to_skip; - -/* Number of frames skipped so far since we drew the last one */ -extern unsigned int frames_skipped; - -/* VDP1 color component offset values (-0xFF...+0xFF) */ -extern int32_t vdp1_rofs, vdp1_gofs, vdp1_bofs; - -/*************************************************************************/ - -/** - * vdp2_is_persistent: Return whether the tile at the given address in - * VDP2 RAM is persistently cacheable. - * - * [Parameters] - * address: Tile address in VDP2 RAM - * [Return value] - * Nonzero if tile texture can be persistently cached, else zero - */ -extern int vdp2_is_persistent(uint32_t address); - -/*************************************************************************/ - -/** - * vdp2_calc_pattern_address, vdp2_calc_pattern_address_8x8, - * vdp2_calc_pattern_address_16x16: Calculate the address and associated - * data of the next pattern. The _8x8 and _16x16 versions are for use when - * the size of the pattern (8x8 or 16x16 pixels) is known at calling time. - * - * [Parameters] - * info: Graphics layer data - * [Return value] - * None - */ -static inline void vdp2_calc_pattern_address(vdp2draw_struct *info) -{ - if (info->patterndatasize == 1) { - const uint16_t data = T1ReadWord(Vdp2Ram, info->addr); - /* We don't support per-pixel priority, so don't waste time - * parsing this bit */ - //info->specialfunction = (info->supplementdata >> 9) & 1; - if (info->colornumber == 0) { // 4bpp - info->paladdr = ((data >> 12) & 0xF) - | ((info->supplementdata >> 1) & 0x70); - } else { // >=8bpp - info->paladdr = (data >> 8) & 0x70; - } - if (!info->auxmode) { - info->flipfunction = (data >> 10) & 0x3; - if (info->patternwh == 1) { - info->charaddr = (info->supplementdata & 0x1F) << 10 - | (data & 0x3FF); - } else { - info->charaddr = (info->supplementdata & 0x1C) << 10 - | (data & 0x3FF) << 2 - | (info->supplementdata & 0x3); - } - } else { - info->flipfunction = 0; - if (info->patternwh == 1) { - info->charaddr = (info->supplementdata & 0x1C) << 10 - | (data & 0xFFF); - } else { - info->charaddr = (info->supplementdata & 0x10) << 10 - | (data & 0xFFF) << 2 - | (info->supplementdata & 0x3); - } - } - } else { // patterndatasize == 2 - const uint32_t data = T1ReadLong(Vdp2Ram, info->addr); - info->charaddr = data & 0x7FFF; - info->flipfunction = data >> 30; - info->paladdr = (data >> 16) & 0x007F; - /* Ignored, as above */ - //info->specialfunction = (data1 >> 29) & 1; - } - - /* We don't support 1MB of VDP2 RAM, so always mask off the high bit */ - //if (!(Vdp2Regs->VRSIZE & 0x8000)) { - info->charaddr &= 0x3FFF; - //} - - info->charaddr <<= 5; -} - -/*----------------------------------*/ - -static inline void vdp2_calc_pattern_address_8x8(vdp2draw_struct *info) -{ - if (info->patterndatasize == 1) { - const uint16_t data = T1ReadWord(Vdp2Ram, info->addr); - //info->specialfunction = (info->supplementdata >> 9) & 1; - if (info->colornumber == 0) { // 4bpp - info->paladdr = ((data >> 12) & 0xF) - | ((info->supplementdata >> 1) & 0x70); - } else { // >=8bpp - info->paladdr = (data >> 8) & 0x70; - } - if (!info->auxmode) { - info->flipfunction = (data >> 10) & 0x3; - info->charaddr = (info->supplementdata & 0xF) << 10 - | (data & 0x3FF); - } else { - info->flipfunction = 0; - info->charaddr = (info->supplementdata & 0xC) << 10 - | (data & 0xFFF); - } - } else { // patterndatasize == 2 - const uint32_t data = T1ReadLong(Vdp2Ram, info->addr); - info->charaddr = data & 0x3FFF; - info->flipfunction = data >> 30; - info->paladdr = (data >> 16) & 0x007F; - /* Ignored, as above */ - //info->specialfunction = (data1 >> 29) & 1; - } - - info->charaddr <<= 5; -} - -/*----------------------------------*/ - -static inline void vdp2_calc_pattern_address_16x16(vdp2draw_struct *info) -{ - if (info->patterndatasize == 1) { - const uint16_t data = T1ReadWord(Vdp2Ram, info->addr); - //info->specialfunction = (info->supplementdata >> 9) & 1; - if (info->colornumber == 0) { // 4bpp - info->paladdr = ((data >> 12) & 0xF) - | ((info->supplementdata >> 1) & 0x70); - } else { // >=8bpp - info->paladdr = (data >> 8) & 0x70; - } - if (!info->auxmode) { - info->flipfunction = (data >> 10) & 0x3; - info->charaddr = (info->supplementdata & 0xC) << 10 - | (data & 0x3FF) << 2 - | (info->supplementdata & 0x3); - } else { - info->flipfunction = 0; - info->charaddr = (data & 0xFFF) << 2 - | (info->supplementdata & 0x3); - } - } else { // patterndatasize == 2 - const uint32_t data = T1ReadLong(Vdp2Ram, info->addr); - info->charaddr = data & 0x3FFF; - info->flipfunction = data >> 30; - info->paladdr = (data >> 16) & 0x007F; - /* Ignored, as above */ - //info->specialfunction = (data1 >> 29) & 1; - } - - info->charaddr <<= 5; -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp2_gen_t8_clut: Generate a 256-color color table for an 8-bit indexed - * tile given the base color index and color offset values. Helper routine - * for the T8 map drawing functions. - * - * [Parameters] - * color_base: Base color index - * color_ofs: Color offset (ORed with pixel value) - * transparent: Nonzero if color index 0 should be transparent - * rofs, gofs, bofs: Red/green/blue adjustment values - * [Return value] - * Allocated color table pointer - */ -static inline uint32_t *vdp2_gen_t8_clut( - int color_base, int color_ofs, int transparent, - int rofs, int gofs, int bofs) -{ - uint32_t *clut = pspGuGetMemoryMerge(256*4 + 60); - clut = (uint32_t *)(((uintptr_t)clut + 63) & -64); // Must be aligned - int i; - for (i = 0; i < 256; i++) { - clut[i] = adjust_color_32_32( - global_clut_32[color_base + (color_ofs | i)], rofs, gofs, bofs - ); - } - if (transparent) { - clut[0] = 0x00000000; - } - return clut; -} - -/*----------------------------------*/ - -/** - * vdp2_gen_32_clut: Generate a 256-color color table for one color - * component of a 32-bit pixel given the color offset value. Helper - * routine for the 32bpp bitmap drawing function. - * - * [Parameters] - * color_base: Base color index - * color_ofs: Color offset (ORed with pixel value) - * transparent: Nonzero if color index 0 should be transparent - * rofs, gofs, bofs: Red/green/blue adjustment values - * [Return value] - * Allocated color table pointer - */ -static inline uint32_t *vdp2_gen_32_clut(int ofs) -{ - uint32_t *clut = pspGuGetMemoryMerge(256*4 + 60); - clut = (uint32_t *)(((uintptr_t)clut + 63) & -64); // Must be aligned - int i; - for (i = 0; i < 256; i++) { - clut[i] = 0xFF000000 | (bound(i+ofs, 0, 255) * 0x010101); - } - return clut; -} - -/*************************************************************************/ -/*************************************************************************/ - -#endif // PSP_VIDEO_INTERNAL_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-video-rotate.c b/yabause/src/psp/psp-video-rotate.c deleted file mode 100644 index 348e6e2e8e..0000000000 --- a/yabause/src/psp/psp-video-rotate.c +++ /dev/null @@ -1,1688 +0,0 @@ -/* src/psp/psp-video-rotate.c: Rotated background graphics handling for - PSP video module - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../vidshared.h" - -#include "config.h" -#include "gu.h" -#include "psp-video.h" -#include "psp-video-internal.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/** - * USE_FIXED_POINT: If defined, floating-point operations will be replaced - * by signed 16.16 fixed-point operations. This may slightly change - * behavior due to the differing precision of computations. - * - * This currently (2010/3/9) gives an improvement of 5-10% with multiple - * coefficients per row or 3-5% with one coefficient per row. - */ -#define USE_FIXED_POINT - -/*************************************************************************/ - -/**** Floating-point / fixed-point operations ****/ - -#ifdef USE_FIXED_POINT - -# define FIXEDFLOAT int32_t -# define UFIXEDFLOAT uint32_t -# define FIXED_MULT(a,b) ((int32_t)(((int64_t)(a) * (int64_t)(b)) >> 16)) -# define FIXED_TOINT(n) ((n) >> 16) -# define FIXED_TOFLOAT(n) ((n) / 65536.0f) - -#else // !USE_FIXED_POINT - -# define FIXEDFLOAT float -# define UFIXEDFLOAT float -# define FIXED_MULT(a,b) ((a) * (b)) -# define FIXED_TOINT(n) ifloorf((n)) -# define FIXED_TOFLOAT(n) ((n)) - -#endif // USE_FIXED_POINT - -/**** Coordinate transformation parameter structure ****/ - -typedef struct RotationParams_ RotationParams; -struct RotationParams_ { - /* Transformation parameters read from VDP2 RAM (arranged for easy - * VFPU loading, in case that ever becomes useful) */ - __attribute__((aligned(16))) FIXEDFLOAT Xst; - FIXEDFLOAT Yst, Zst, pad0w; - FIXEDFLOAT deltaXst, deltaYst, pad1z, pad1w; - FIXEDFLOAT deltaX, deltaY, pad2z, pad2w; - FIXEDFLOAT A, B, C, pad3w; - FIXEDFLOAT D, E, F, pad4w; - FIXEDFLOAT Px, Py, Pz, pad5w; - FIXEDFLOAT Cx, Cy, Cz, pad6w; - FIXEDFLOAT Mx, My, pad7z, pad7w; - FIXEDFLOAT kx, ky, pad8z, pad8w; //May be updated in coefficient table mode - - /* Computed transformation parameters */ - FIXEDFLOAT Xp, Yp, pad9z, pad9w; //May be updated in coefficient table mode - FIXEDFLOAT mat11, mat12, mat13, mat1_pad; - FIXEDFLOAT mat21, mat22, mat23, mat2_pad; - - /* Coefficient table parameters read from VDP2 RAM */ - UFIXEDFLOAT KAst; - FIXEDFLOAT deltaKAst; - FIXEDFLOAT deltaKAx; - - /* Coefficient table base address and flags */ - uint32_t coeftbladdr; - uint8_t coefenab; - uint8_t coefmode; - uint8_t coefdatasize; // Size of a single coefficient in bytes (2 or 4) - uint8_t coefdatashift; // log2(coefdatasize) - - /* Miscellaneous parameters */ - uint8_t screenover; // FIXME: What is this for? -}; - -/*************************************************************************/ - -/**** Macros for pixel address calculation and pixel getting ****/ - -/** - * INIT_CALC_PIXELNUM: Precompute values used by the CALC_PIXELNUM macro. - */ -#define INIT_CALC_PIXELNUM \ - const int srcx_mask = info->isbitmap \ - ? info->cellw - 1 \ - : (8 * 64 * info->planew * 4) - 1; \ - const int srcy_mask = info->isbitmap \ - ? info->cellh - 1 \ - : (8 * 64 * info->planeh * 4) - 1; \ - const int page_shift = 3 + 6; \ - const int page_mask = (1 << page_shift) - 1; \ - const int tile_shift = (info->patternwh==2) ? 4 : 3; \ - /* Remember the last tile seen, to save the time of looking it up \ - * while we're on nearby pixels */ \ - int last_tilex = -1, last_tiley = -1 - -/*----------------------------------*/ - -/** - * INIT_PAGEMAP: Initialize a page map array for the given parameter - * set (either 0 or 1). pagemap should be declared as: - * uint32_t pagemap[8][8]; - */ -#define INIT_PAGEMAP(pagemap,set) do { \ - int plane_aoffset = ((Vdp2Regs->MPOFR >> ((set) * 4)) & 7) << 6; \ - const uint8_t *plane_map = set ? (const uint8_t *)&Vdp2Regs->MPABRB \ - : (const uint8_t *)&Vdp2Regs->MPABRA;\ - const int plane_bits = info->planew_bits + info->planeh_bits; \ - const int plane_ashift = 11 + (info->patternwh==1 ? 2 : 0) \ - + (info->patterndatasize==2 ? 1 : 0); \ - const int plane_amask = (0xFF >> (plane_ashift - 11)) \ - ^ ((1 << plane_bits) - 1); \ - unsigned int planenum = 0; \ - unsigned int plane_y; \ - for (plane_y = 0; plane_y < 4; plane_y++) { \ - unsigned int plane_x; \ - for (plane_x = 0; plane_x < 4; plane_x++, planenum++) { \ - uint32_t address = \ - ((plane_aoffset | plane_map[planenum]) & plane_amask) \ - << plane_ashift; \ - unsigned int pagenum = 0; \ - unsigned int page_y; \ - for (page_y = 0; page_y < info->planeh; page_y++) { \ - unsigned int page_x; \ - for (page_x = 0; page_x < info->planew; page_x++, pagenum++) {\ - const int tilenum = \ - pagenum << (2*(page_shift-tile_shift)); \ - pagemap[plane_y*info->planeh + page_y] \ - [plane_x*info->planew + page_x] = \ - address + (tilenum << (info->patterndatasize_bits+1));\ - } \ - } \ - } \ - } \ -} while (0) - -/*----------------------------------*/ - -/** - * CALC_TILEADDR_8x8, CALC_TILEADDR_16x16: Calculate the tile data address - * associated with the tile coordinate (tilex,tiley) for 8x8 or 16x16 tiles. - * Helper macros for CALC_PIXELNUM. - */ -#define CALC_TILEADDR_8x8(tilex,tiley,pagemap) do { \ - const int page_x = srcx >> page_shift; \ - const int page_y = srcy >> page_shift; \ - info->addr = pagemap[page_y][page_x]; \ - const int tile_x = (srcx & page_mask) >> 3; \ - const int tile_y = (srcy & page_mask) >> 3; \ - const int tilenum = tile_y << (page_shift - 3) | tile_x; \ - info->addr += tilenum << (info->patterndatasize_bits + 1); \ -} while (0) - -#define CALC_TILEADDR_16x16(tilex,tiley,pagemap) do { \ - const int page_x = srcx >> page_shift; \ - const int page_y = srcy >> page_shift; \ - info->addr = pagemap[page_y][page_x]; \ - const int tile_x = (srcx & page_mask) >> 4; \ - const int tile_y = (srcy & page_mask) >> 4; \ - const int tilenum = tile_y << (page_shift - 4) | tile_x; \ - info->addr += tilenum << (info->patterndatasize_bits + 1); \ -} while (0) - -/*----------------------------------*/ - -/** - * CALC_PIXELNUM: Calculate the pixel index associated with the - * transformed coordinates (srcx,srcy), store it in the variable - * "pixelnum", and update the "info" structure's fields as necessary for - * the associated tile (if the graphics layer is in tilemap mode). - * - * This is implemented as a macro so it can make use of precomputed - * constant values within the calling routine. - * - * Optimization note: The use of nearly identical code in the - * if(tile_shift==4) and else branches may look awkward, but it allows the - * compiler to use known values rather than having to repeatedly check and - * branch on the tile size, giving a speed increase of 3-5%. Greater - * optimization could be achieved by pulling such tests further out of the - * critical path, at the cost of code size explosion; one alternative - * would be dynamic compilation/assembly of rotation code based on the - * graphics layer's parameters. - */ -#define CALC_PIXELNUM(pagemap) do { \ - srcx &= srcx_mask; \ - srcy &= srcy_mask; \ - if (info->isbitmap) { \ - pixelnum = srcy << info->cellw_bits | srcx; \ - } else if (tile_shift == 4) { \ - const int tilex = srcx >> 4; \ - const int tiley = srcy >> 4; \ - if (tilex != last_tilex || tiley != last_tiley) { \ - last_tilex = tilex; \ - last_tiley = tiley; \ - CALC_TILEADDR_16x16(tilex, tiley, pagemap); \ - vdp2_calc_pattern_address_16x16(info); \ - } \ - srcx &= 15; \ - srcy &= 15; \ - if (info->flipfunction & 1) { \ - srcx ^= 15; \ - } \ - if (info->flipfunction & 2) { \ - srcy ^= 15; \ - } \ - pixelnum = (srcy & 8) << (7-3) \ - | (srcx & 8) << (6-3) \ - | (srcy & 7) << 3 \ - | (srcx & 7); \ - } else { /* tile_shift == 3 */ \ - const int tilex = srcx >> 3; \ - const int tiley = srcy >> 3; \ - if (tilex != last_tilex || tiley != last_tiley) { \ - last_tilex = tilex; \ - last_tiley = tiley; \ - CALC_TILEADDR_8x8(tilex, tiley, pagemap); \ - vdp2_calc_pattern_address_8x8(info); \ - } \ - srcx &= 7; \ - srcy &= 7; \ - if (info->flipfunction & 1) { \ - srcx ^= 7; \ - } \ - if (info->flipfunction & 2) { \ - srcy ^= 7; \ - } \ - pixelnum = srcy << 3 | srcx; \ - } \ -} while (0) - -/*-----------------------------------------------------------------------*/ - -/** - * SELECT_GET_PIXEL: Declares "get_pixel" as a function pointer to an - * appropriate pixel-getting function based on the graphics layer's - * parameters. - */ - -#define SELECT_GET_PIXEL \ - const int need_adjust = \ - (info->alpha != 0xFF) || info->cor || info->cog || info->cob; \ - uint32_t (*get_pixel)(vdp2draw_struct *, unsigned int); \ - switch (info->colornumber) { \ - case 0: \ - get_pixel = need_adjust \ - ? rotation_get_pixel_t4_adjust \ - : info->transparencyenable \ - ? rotation_get_pixel_t4_transparent \ - : rotation_get_pixel_t4; \ - break; \ - case 1: \ - get_pixel = need_adjust \ - ? rotation_get_pixel_t8_adjust \ - : info->transparencyenable \ - ? rotation_get_pixel_t8_transparent \ - : rotation_get_pixel_t8; \ - break; \ - case 2: \ - get_pixel = need_adjust \ - ? rotation_get_pixel_t16_adjust \ - : info->transparencyenable \ - ? rotation_get_pixel_t16_transparent \ - : rotation_get_pixel_t16; \ - break; \ - case 3: \ - get_pixel = need_adjust \ - ? rotation_get_pixel_16_adjust \ - : info->transparencyenable \ - ? rotation_get_pixel_16_transparent \ - : rotation_get_pixel_16; \ - break; \ - case 4: \ - get_pixel = need_adjust \ - ? rotation_get_pixel_32_adjust \ - : info->transparencyenable \ - ? rotation_get_pixel_32_transparent \ - : rotation_get_pixel_32; \ - break; \ - default: \ - DMSG("Invalid pixel format %d", info->colornumber); \ - return; \ - } - -/*************************************************************************/ - -/**** Local function declarations ****/ - -static void render_mode0(uint32_t *pixelbuf, vdp2draw_struct *info, - const clipping_struct *clip, - RotationParams param_set[2], int which); -static void render_mode0_region(uint32_t *pixelbuf, vdp2draw_struct *info, - RotationParams param_set[2], int which, - unsigned int x0, unsigned int y0, - unsigned int xlim, unsigned int ylim); - -static void render_mode1(uint32_t *pixelbuf, vdp2draw_struct *info, - const clipping_struct *clip, - RotationParams param_set[2]); -static int mode1_is_split_screen(const RotationParams param_set[2], - int *top_set_ret, int *switch_y_ret); - -static void render_mode2(uint32_t *pixelbuf, vdp2draw_struct *info, - const clipping_struct *clip, - RotationParams param_set[2]); - -static void get_rotation_parameters(vdp2draw_struct *info, int which, - RotationParams *param_ret); - -__attribute__((unused)) -static int get_rotation_coefficient(RotationParams *param, uint32_t address); -static int get_rotation_coefficient_size2_mode0(RotationParams *param, - const void *address); -static int get_rotation_coefficient_size2_mode1(RotationParams *param, - const void *address); -static int get_rotation_coefficient_size2_mode2(RotationParams *param, - const void *address); -static int get_rotation_coefficient_size2_mode3(RotationParams *param, - const void *address); -static int get_rotation_coefficient_size4_mode0(RotationParams *param, - const void *address); -static int get_rotation_coefficient_size4_mode1(RotationParams *param, - const void *address); -static int get_rotation_coefficient_size4_mode2(RotationParams *param, - const void *address); -static int get_rotation_coefficient_size4_mode3(RotationParams *param, - const void *address); - -static void transform_coordinates(const RotationParams *param, int x, int y, - FIXEDFLOAT *srcx_ret, FIXEDFLOAT *srcy_ret); - -static uint32_t rotation_get_pixel_t4(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_t8(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_t16(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_16(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_32(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_t4_transparent(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_t8_transparent(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_t16_transparent(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_16_transparent(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_32_transparent(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_t4_adjust(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_t8_adjust(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_t16_adjust(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_16_adjust(vdp2draw_struct *info, - unsigned int pixelnum); -static uint32_t rotation_get_pixel_32_adjust(vdp2draw_struct *info, - unsigned int pixelnum); - -/*-----------------------------------------------------------------------*/ - -/* Table of coefficient-reading functions, indexed by - * [param.coefdatasize==4][param.coefmode] */ - -static int (*get_coef_table[2][4])(RotationParams *, const void *) = { - {get_rotation_coefficient_size2_mode0, - get_rotation_coefficient_size2_mode1, - get_rotation_coefficient_size2_mode2, - get_rotation_coefficient_size2_mode3}, - {get_rotation_coefficient_size4_mode0, - get_rotation_coefficient_size4_mode1, - get_rotation_coefficient_size4_mode2, - get_rotation_coefficient_size4_mode3} -}; - -/*************************************************************************/ -/************************** Interface function ***************************/ -/*************************************************************************/ - -/** - * vdp2_draw_map_rotated: Draw a rotated graphics layer. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -void vdp2_draw_map_rotated(vdp2draw_struct *info, const clipping_struct *clip) -{ - /* Parse rotation parameters. */ - - static __attribute__((aligned(16))) RotationParams param_set[2]; - get_rotation_parameters(info, 0, ¶m_set[0]); - get_rotation_parameters(info, 1, ¶m_set[1]); - - /* Allocate a buffer for drawing the texture. Note that we swizzle - * the texture for faster drawing, since it's allocated in system - * RAM (which the GE is slow at accessing). */ - - uint32_t *pixelbuf = guGetMemory(disp_width * disp_height * 4 + 60); - pixelbuf = (uint32_t *)(((uintptr_t)pixelbuf + 63) & -64); - - /* Render all pixels. */ - - switch (info->rotatemode) { - case 0: - render_mode0(pixelbuf, info, clip, param_set, info->rotatenum); - break; - case 1: - render_mode1(pixelbuf, info, clip, param_set); - break; - case 2: - render_mode2(pixelbuf, info, clip, param_set); - break; - } - - /* Set up vertices for optimized GE drawing. */ - - const unsigned int nverts = (disp_width / 16) * 2; - VertexUVXYZ *vertices = guGetMemory(sizeof(*vertices) * nverts); - VertexUVXYZ *vptr; - unsigned int x; - for (x = 0, vptr = vertices; x < disp_width; x += 16, vptr += 2) { - vptr[0].u = x; - vptr[0].v = 0; - vptr[0].x = x >> disp_xscale; - vptr[0].y = 0; - vptr[0].z = 0; - vptr[1].u = x + 16; - vptr[1].v = disp_height; - vptr[1].x = (x + 16) >> disp_xscale; - vptr[1].y = disp_height >> disp_yscale; - vptr[1].z = 0; - } - - /* Send the texture to the GE. */ - - guTexFlush(); - guTexMode(GU_PSM_8888, 0, 0, 1 /*swizzled*/); - if (disp_width <= 512) { - guTexImage(0, 512, 512, disp_width, pixelbuf); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - nverts, NULL, vertices); - } else { - guTexImage(0, 512, 512, disp_width, pixelbuf); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - nverts/2, NULL, vertices); - for (x = disp_width/2, vptr = vertices + nverts/2; x < disp_width; - x += 16, vptr += 2 - ) { - vptr[0].u = x - disp_width/2; - vptr[1].u = (x + 16) - disp_width/2; - } - guTexImage(0, 512, 512, disp_width, pixelbuf + (disp_width/2) * 8); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - nverts/2, NULL, vertices + nverts/2); - } - guCommit(); -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * render_mode0: Render a rotated/distorted graphics layer in mode 0 - * (fixed parameter set). - * - * [Parameters] - * pixelbuf: Pointer to output pixel buffer - * info: Graphics layer data - * clip: Clipping window data - * param_set: Array of rotation parameter sets - * which: Which parameter set to use (0 or 1) - * [Return value] - * None - */ -static void render_mode0(uint32_t *pixelbuf, vdp2draw_struct *info, - const clipping_struct *clip, - RotationParams param_set[2], int which) -{ - /* - * If the parameter set uses a fixed transformation matrix that doesn't - * actually perform any rotation, we can just call the regular map - * drawing functions with appropriately scaled parameters: - * - * [srcX] ( [screenX]) [kx] [Xp] - * [srcY] = (M [screenY]) * [ky] + [Yp] - * ( [ 1 ]) - * - * [srcX] ([mat11 0 mat13] [screenX]) [kx] [Xp] - * [srcY] = ([ 0 mat22 mat23] [screenY]) * [ky] + [Yp] - * ( [ 1 ]) - * - * srcX = (mat11*screenX + mat13) * kx + Xp - * srcY = (mat22*screenY + mat23) * ky + Yp - * - * srcX = (mat11*kx)*screenX + (mat13*kx + Xp) - * srcY = (mat22*ky)*screenY + (mat23*ky + Yp) - * - * (srcX - (mat13*kx + Xp)) / (mat11*kx) = screenX - * (srcY - (mat23*ky + Yp)) / (mat22*ky) = screenX - * - * screenX = (1/(mat11*kx))*srcX - ((mat13*kx + Xp) / (mat11*kx)) - * screenY = (1/(mat22*ky))*srcX - ((mat23*ky + Yp) / (mat22*ky)) - */ - - RotationParams *param = ¶m_set[which]; - if (!param->coefenab && param->mat12 == 0.0f && param->mat21 == 0.0f) { - const float xmul = - 1 / FIXED_TOFLOAT(FIXED_MULT(param->mat11, param->kx)); - const float ymul = - 1 / FIXED_TOFLOAT(FIXED_MULT(param->mat22, param->ky)); - info->coordincx = xmul; - info->coordincy = ymul; - info->x = -FIXED_TOFLOAT(FIXED_MULT(param->mat13, param->kx) + param->Xp) * xmul; - info->y = -FIXED_TOFLOAT(FIXED_MULT(param->mat23, param->ky) + param->Yp) * ymul; - void (*draw_func)(vdp2draw_struct *info, const clipping_struct *clip); - if (info->isbitmap) { - draw_func = &vdp2_draw_bitmap; - } else if (info->patternwh == 2) { - draw_func = &vdp2_draw_map_16x16; - } else { - draw_func = &vdp2_draw_map_8x8; - } - return (*draw_func)(info, clip); - } - - /* - * There's rotation and/or distortion going on, so we'll have to render - * the image manually. (Sadly, the PSP doesn't have shaders, so we - * can't translate the coefficients into a texture coordinate map and - * render that way.) - */ - - render_mode0_region(pixelbuf, info, param_set, which, - 0, 0, disp_width, disp_height); -} - -/*----------------------------------*/ - -/** - * render_mode0_region: Render the given portion of a rotated/distorted - * graphics layer in mode 0 (fixed parameter set). - * - * [Parameters] - * pixelbuf: Pointer to output pixel buffer - * info: Graphics layer data - * param_set: Array of rotation parameter sets - * which: Which parameter set to use (0 or 1) - * x0, y0: Top-left coordinates of region to render - * xlim, ylim: Bottom-right coordinates of region to render plus one - * [Return value] - * None - */ -static void render_mode0_region(uint32_t *pixelbuf, vdp2draw_struct *info, - RotationParams param_set[2], int which, - unsigned int x0, unsigned int y0, - unsigned int xlim, unsigned int ylim) -{ - RotationParams *param = ¶m_set[which]; - - /* Precalculate tilemap/bitmap coordinate masks, shift counts, and - * tile page addresses. */ - - INIT_CALC_PIXELNUM; - uint32_t pagemap[8][8]; - if (!info->isbitmap) { - INIT_PAGEMAP(pagemap, which); - } - - /* Choose appropriate coefficient-read and pixel-read functions. */ - - int (*get_coef)(RotationParams *, const void *) = - get_coef_table[param->coefdatasize==4][param->coefmode]; - SELECT_GET_PIXEL; - - /* Actually render the graphics layer. */ - - /* These two variables are intentionally float rather than FIXEDFLOAT - * because coef_y can exceed the range of a fixed-point value. */ - float coef_dy = FIXED_TOFLOAT(param->deltaKAst); - float coef_y = y0 * coef_dy; - unsigned int y; - - for (y = y0; y < ylim; y++, coef_y += coef_dy) { - - const uint32_t coef_base = param->coeftbladdr - + (ifloorf(coef_y) << param->coefdatashift); - const uint8_t *coef_baseptr = Vdp2Ram + (coef_base & 0x7FFFF); - uint32_t * const dest_base = pixelbuf + (y/8)*(disp_width*8) + (y%8)*4; - - if (!param->coefenab) { - - /* Constant parameters for the whole screen (FIXME: we could - * draw this in hardware if we had code to rotate vertices) */ - FIXEDFLOAT srcx_f, srcy_f; - transform_coordinates(param, x0, y, &srcx_f, &srcy_f); - const FIXEDFLOAT delta_srcx = FIXED_MULT(param->mat11, param->kx); - const FIXEDFLOAT delta_srcy = FIXED_MULT(param->mat21, param->ky); - unsigned int x; - for (x = x0; x < xlim; - x++, srcx_f += delta_srcx, srcy_f += delta_srcy - ) { - uint32_t *dest = dest_base + (x/4)*32 + x%4; - int srcx = FIXED_TOINT(srcx_f); - int srcy = FIXED_TOINT(srcy_f); - unsigned int pixelnum; - CALC_PIXELNUM(pagemap); - *dest = (*get_pixel)(info, pixelnum); - } - - } else if (param->deltaKAx == 0) { - - /* One coefficient for the whole row */ - if (!(*get_coef)(param, coef_baseptr)) { - /* Empty row */ - uint32_t *dest = dest_base + (x0/4)*32; - unsigned int x = x0; - if (UNLIKELY(x & 3)) { - for (; x & 3; x++) { - dest[x & 3] = 0; - } - dest += 32; - } - for (; x < (xlim & ~3); x += 4, dest += 32) { - dest[0] = dest[1] = dest[2] = dest[3] = 0; - } - for (; x < xlim; x++) { - dest[x & 3] = 0; - } - continue; - } - FIXEDFLOAT srcx_f, srcy_f; - transform_coordinates(param, x0, y, &srcx_f, &srcy_f); - const FIXEDFLOAT delta_srcx = FIXED_MULT(param->mat11, param->kx); - const FIXEDFLOAT delta_srcy = FIXED_MULT(param->mat21, param->ky); - unsigned int x; - for (x = x0; x < xlim; - x++, srcx_f += delta_srcx, srcy_f += delta_srcy - ) { - uint32_t *dest = dest_base + (x/4)*32 + x%4; - int srcx = FIXED_TOINT(srcx_f); - int srcy = FIXED_TOINT(srcy_f); - unsigned int pixelnum; - CALC_PIXELNUM(pagemap); - *dest = (*get_pixel)(info, pixelnum); - } - - } else { // param->coefenab && param->deltaKAx != 0 - - /* Multiple coefficients per row */ - const FIXEDFLOAT coef_dx = param->deltaKAx; - FIXEDFLOAT coef_x = 0; - int last_coef_x = -1; - int empty_pixel = 0; - unsigned int x; - for (x = x0; x < xlim; x++, coef_x += coef_dx) { - uint32_t *dest = dest_base + (x/4)*32 + x%4; - if (FIXED_TOINT(coef_x) != last_coef_x) { - last_coef_x = FIXED_TOINT(coef_x); - const uint8_t *coef_ptr = - coef_baseptr + (last_coef_x << param->coefdatashift); - empty_pixel = !(*get_coef)(param, coef_ptr); - } - if (empty_pixel) { - *dest = 0; - } else { - FIXEDFLOAT srcx_f, srcy_f; - transform_coordinates(param, x, y, &srcx_f, &srcy_f); - int srcx = FIXED_TOINT(srcx_f); - int srcy = FIXED_TOINT(srcy_f); - unsigned int pixelnum; - CALC_PIXELNUM(pagemap); - *dest = (*get_pixel)(info, pixelnum); - } - } - - } // if (!param->coefenab) - - } // for (y = y0; y < ylim; y++, coef_y += coef_dy) -} - -/*-----------------------------------------------------------------------*/ - -/** - * render_mode1: Render a rotated/distorted graphics layer in mode 1 - * (parameter set selected by top bit of coefficient). - * - * [Parameters] - * pixelbuf: Pointer to output pixel buffer - * info: Graphics layer data - * clip: Clipping window data - * param_set: Array of rotation parameter sets - * [Return value] - * None - */ -static void render_mode1(uint32_t *pixelbuf, vdp2draw_struct *info, - const clipping_struct *clip, - RotationParams param_set[2]) -{ - /* Set up a second vdp2draw_struct for the second parameter set. */ - - vdp2draw_struct *info0 = info; - vdp2draw_struct info1_buf = *info; - vdp2draw_struct *info1 = &info1_buf; - info1->charaddr = ((Vdp2Regs->MPOFR >> 4) & 7) << 17; - info1->planew_bits = (Vdp2Regs->PLSZ >> 12) & 1; - info1->planeh_bits = (Vdp2Regs->PLSZ >> 13) & 1; - info1->planew = 1 << info->planew_bits; - info1->planeh = 1 << info->planeh_bits; - if (info1->planew != info0->planew || info1->planeh != info0->planeh) { - DMSG("WARNING: mixed plane sizes not supported for RPMD=2" - " (set A: %dx%d, set B: %dx%d)", info0->planew, info0->planeh, - info1->planew, info1->planeh); - } - - /* If set A has one coefficient per row, it might simply be splitting - * the screen into two differently-rendered regions (such as sky and - * ground). We can potentially draw that more efficiently as mode 0. */ - - int top_set, switch_y; - if (mode1_is_split_screen(param_set, &top_set, &switch_y)) { - if (switch_y < 0) { - return render_mode0(pixelbuf, info, clip, param_set, top_set); - } else { - render_mode0_region(pixelbuf, top_set==0 ? info0 : info1, - param_set, top_set, - 0, 0, disp_width, switch_y); - return render_mode0_region(pixelbuf, top_set==0 ? info1 : info0, - param_set, top_set ^ 1, - 0, switch_y, disp_width, disp_height); - } - } - - /* Precalculate tilemap/bitmap coordinate masks, shift counts, and - * tile page addresses. */ - - INIT_CALC_PIXELNUM; - uint32_t pagemap[2][8][8]; - if (!info->isbitmap) { - INIT_PAGEMAP(pagemap[0], 0); - INIT_PAGEMAP(pagemap[1], 1); - } - - /* Choose appropriate coefficient-read and pixel-read functions. */ - - int (*get_coef0)(RotationParams *, const void *) = - get_coef_table[param_set[0].coefdatasize==4][param_set[0].coefmode]; - int (*get_coef1)(RotationParams *, const void *) = - get_coef_table[param_set[1].coefdatasize==4][param_set[1].coefmode]; - SELECT_GET_PIXEL; - - /* Actually render the graphics layer. */ - - /* These are intentionally float rather than FIXEDFLOAT, as in - * render_mode0_region(). */ - float coef0_dy = FIXED_TOFLOAT(param_set[0].deltaKAst); - float coef0_y = 0; - float coef1_dy = FIXED_TOFLOAT(param_set[1].deltaKAst); - float coef1_y = 0; - unsigned int y; - - for (y = 0; y < disp_height; - y++, coef0_y += coef0_dy, coef1_y += coef1_dy - ) { - - const uint32_t coef0_base = param_set[0].coeftbladdr - + (ifloorf(coef0_y) << param_set[0].coefdatashift); - const uint8_t *coef0_baseptr = Vdp2Ram + (coef0_base & 0x7FFFF); - const uint32_t coef1_base = param_set[1].coeftbladdr - + (ifloorf(coef1_y) << param_set[1].coefdatashift); - const uint8_t *coef1_baseptr = Vdp2Ram + (coef1_base & 0x7FFFF); - uint32_t * const dest_base = pixelbuf + (y/8)*(disp_width*8) + (y%8)*4; - - if (param_set[0].deltaKAx == 0 - && (!param_set[1].coefenab || param_set[1].deltaKAx == 0) - ) { - - /* One coefficient for the whole row in both sets */ - int which; - if ((*get_coef0)(¶m_set[0], coef0_baseptr)) { - which = 0; - info = info0; - } else if (!param_set[1].coefenab - || (*get_coef1)(¶m_set[1], coef1_baseptr)) { - which = 1; - info = info1; - } else { - /* Empty row */ - uint32_t *dest = dest_base; - unsigned int x; - for (x = 0; x < disp_width; x += 4, dest += 32) { - dest[0] = dest[1] = dest[2] = dest[3] = 0; - } - continue; - } - RotationParams *param = ¶m_set[which]; - FIXEDFLOAT srcx_f, srcy_f; - transform_coordinates(param, 0, y, &srcx_f, &srcy_f); - const FIXEDFLOAT delta_srcx = FIXED_MULT(param->mat11, param->kx); - const FIXEDFLOAT delta_srcy = FIXED_MULT(param->mat21, param->ky); - unsigned int x; - for (x = 0; x < disp_width; - x++, srcx_f += delta_srcx, srcy_f += delta_srcy - ) { - uint32_t *dest = dest_base + (x/4)*32 + x%4; - int srcx = FIXED_TOINT(srcx_f); - int srcy = FIXED_TOINT(srcy_f); - unsigned int pixelnum; - CALC_PIXELNUM(pagemap[which]); - *dest = (*get_pixel)(info, pixelnum); - } - - } else { - - /* Multiple coefficients per row in one or both sets */ - const FIXEDFLOAT coef0_dx = param_set[0].deltaKAx; - FIXEDFLOAT coef0_x = 0; - const FIXEDFLOAT coef1_dx = param_set[1].deltaKAx; - FIXEDFLOAT coef1_x = 0; - int last_coef0_x = -1; - int last_coef1_x = (param_set[1].coefenab ? -1 : 0); - int have_coef0 = 1; - int have_coef1 = 1; - unsigned int x; - for (x = 0; x < disp_width; - x++, coef0_x += coef0_dx, coef1_x += coef1_dx - ) { - uint32_t *dest = dest_base + (x/4)*32 + x%4; - if (FIXED_TOINT(coef0_x) != last_coef0_x) { - last_coef0_x = FIXED_TOINT(coef0_x); - const uint8_t *coef0_ptr = coef0_baseptr - + (last_coef0_x << param_set[0].coefdatashift); - have_coef0 = (*get_coef0)(¶m_set[0], coef0_ptr); - } - if (FIXED_TOINT(coef1_x) != last_coef1_x) { - last_coef1_x = FIXED_TOINT(coef1_x); - const uint8_t *coef1_ptr = coef1_baseptr - + (last_coef1_x << param_set[1].coefdatashift); - have_coef1 = (*get_coef1)(¶m_set[1], coef1_ptr); - } - int which; - if (have_coef0) { - which = 0; - info = info0; - } else if (have_coef1) { - which = 1; - info = info1; - } else { // Empty pixel - *dest = 0; - continue; - } - RotationParams *param = ¶m_set[which]; - FIXEDFLOAT srcx_f, srcy_f; - transform_coordinates(param, x, y, &srcx_f, &srcy_f); - int srcx = FIXED_TOINT(srcx_f); - int srcy = FIXED_TOINT(srcy_f); - unsigned int pixelnum; - CALC_PIXELNUM(pagemap[which]); - *dest = (*get_pixel)(info, pixelnum); - } - - } - - } // for (y = 0; y < disp_height; y++, coef_y += coef_dy) -} - -/*----------------------------------*/ - -/** - * mode1_is_split_screen: Return whether the parameters and coefficients - * for a mode 1 rotated/distorted graphics layer have the effect of - * splitting the screen into a top and bottom region, each with one of the - * two parameter sets. Parameters which specify a single parameter set for - * the entire screen are considered to be a split screen with an empty - * bottom portion for the purposes of this function. - * - * If this function returns true, *top_set_ret will be set to the index of - * the parameter set used for the top line of the screen, and *switch_y_ret - * will be set to the first line at which the other parameter set is used. - * If the entire screen uses a single parameter set (effectively mode 0), - * *switch_y_ret will be set to -1. - * - * [Parameters] - * param_set: Array of rotation parameter sets - * top_set_ret: Pointer to variable to receive the index of the - * parameter set used on screen line 0 - * switch_y_ret: Pointer to variable to receive the first line at which - * the alternate parameter set is used - * [Return value] - * True (nonzero) if the rotation parameters have the effect of - * splitting the screen, else false (zero) - */ -static int mode1_is_split_screen(const RotationParams param_set[2], - int *top_set_ret, int *switch_y_ret) -{ - /* If parameter set A doesn't have coefficients enabled, set B can - * never be selected, so this is just the same as mode 0 with set A. */ - - if (!param_set[0].coefenab) { - *top_set_ret = 0; - *switch_y_ret = -1; - return 1; - } - - /* If there is more than one coefficient per line, assume that the - * rotation operation is more complex than a simple split-screen effect. */ - - if (param_set[0].deltaKAx != 0) { - return 0; - } - - /* Scan over the set A coefficients (now known to be one per line) and - * see how many times the selected set changes. */ - - int cur_set = -1; - *top_set_ret = -1; - *switch_y_ret = -1; - - /* These are intentionally float rather than FIXEDFLOAT, as in - * render_mode0_region(). */ - float coef0_dy = FIXED_TOFLOAT(param_set[0].deltaKAst); - float coef0_y = 0; - int y; - - for (y = 0; y < disp_height; y++, coef0_y += coef0_dy) { - - const uint32_t coef0_addr = param_set[0].coeftbladdr - + (ifloorf(coef0_y) << param_set[0].coefdatashift); - const uint8_t * const coef0_ptr = Vdp2Ram + (coef0_addr & 0x7FFFF); - /* VDP memory is organized by bytes, so coef0_ptr is now pointing - * to the top byte of the coefficient value regardless of the data - * size setting. */ - const int set = (*(int8_t *)coef0_ptr < 0) ? 1 : 0; - - if (y == 0) { - *top_set_ret = cur_set = set; - } else if (set != cur_set) { - if (*switch_y_ret < 0) { - *switch_y_ret = y; - } else { - /* This is the second change we've seen, so it's not a - * split-screen effect. */ -printf("set change 2 at %d\n",y); - return 0; - } - cur_set = set; - } - - } - - /* If we got this far, it must be a split-screen effect. */ - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * render_mode2: Render a rotated/distorted graphics layer in mode 2 - * (parameter set selected by clipping window). - * - * [Parameters] - * pixelbuf: Pointer to output pixel buffer - * info: Graphics layer data - * clip: Clipping window data - * param_set: Array of rotation parameter sets - * [Return value] - * None - */ -static void render_mode2(uint32_t *pixelbuf, vdp2draw_struct *info, - const clipping_struct *clip, - RotationParams param_set[2]) -{ - /* - * FIXME: This logic gets the Panzer Dragoon Saga name entry screen's - * background to display properly, but since PDS is the only example - * of this mode to which I have access, I have no clue whether this is - * the Right Thing To Do. I'm using the height of the clip window (set - * as <0,0>-<352,224> by the game) based on vidsoft.c comments, but it - * could also be just a top-half/bottom-half-of-screen thing. - */ - - render_mode0_region(pixelbuf, info, param_set, 0, - 0, 0, disp_width, clip[0].yend / 2); - - info->charaddr = ((Vdp2Regs->MPOFR >> 4) & 7) << 17; - info->planew_bits = (Vdp2Regs->PLSZ >> 12) & 1; - info->planeh_bits = (Vdp2Regs->PLSZ >> 13) & 1; - info->planew = 1 << info->planew_bits; - info->planeh = 1 << info->planeh_bits; - render_mode0_region(pixelbuf, info, param_set, 1, - 0, clip[0].yend / 2, disp_width, disp_height); -} - -/*************************************************************************/ - -/** - * get_rotation_parameters: Retrieve the rotation parameters for a rotated - * graphics layer and perform necessary precalculations. - * - * [Parameters] - * info: Graphics layer data - * which: Which parameter set to retrieve (0 or 1) - * param_ret: Pointer to structure to receive parsed parameters - * [Return value] - * None - */ -static void get_rotation_parameters(vdp2draw_struct *info, int which, - RotationParams *param_ret) -{ - uint32_t addr = (Vdp2Regs->RPTA.all << 1) & 0x7FF7C; - unsigned int KTCTL, KTAOF; - if (which == 0) { - KTCTL = Vdp2Regs->KTCTL & 0xFF; - KTAOF = Vdp2Regs->KTAOF & 0xFF; - param_ret->screenover = (Vdp2Regs->PLSZ >> 10) & 3; - } else { - addr |= 0x80; - KTCTL = (Vdp2Regs->KTCTL >> 8) & 0xFF; - KTAOF = (Vdp2Regs->KTAOF >> 8) & 0xFF; - param_ret->screenover = (Vdp2Regs->PLSZ >> 14) & 3; - } - param_ret->coefenab = KTCTL & 1; - param_ret->coefdatashift = (KTCTL & 2) ? 1 : 2; - param_ret->coefdatasize = 1 << param_ret->coefdatashift; - param_ret->coefmode = (KTCTL >> 2) & 3; - param_ret->coeftbladdr = ((KTAOF & 7) << param_ret->coefdatashift) << 16; - -#ifdef USE_FIXED_POINT - #define GET_SHORT(nbits) \ - (addr += 2, (int32_t)((int16_t)T1ReadWord(Vdp2Ram,addr-2) \ - << (16-nbits)) << nbits) - #define GET_SIGNED_FLOAT(nbits) \ - (addr += 4, ((((int32_t)T1ReadLong(Vdp2Ram,addr-4) \ - << (32-nbits)) >> (32-nbits)) & ~0x3F)) - #define GET_UNSIGNED_FLOAT(nbits) \ - (addr += 4, (((uint32_t)T1ReadLong(Vdp2Ram,addr-4) \ - & (0xFFFFFFFFU >> (32-nbits))) & ~0x3F)) -#else // !USE_FIXED_POINT - #define GET_SHORT(nbits) \ - (addr += 2, ((int16_t)T1ReadWord(Vdp2Ram,addr-2) \ - << (16-nbits)) >> (16-nbits)) - #define GET_SIGNED_FLOAT(nbits) \ - (addr += 4, ((((int32_t)T1ReadLong(Vdp2Ram,addr-4) \ - << (32-nbits)) >> (32-nbits)) & ~0x3F) / 65536.0f) - #define GET_UNSIGNED_FLOAT(nbits) \ - (addr += 4, (((uint32_t)T1ReadLong(Vdp2Ram,addr-4) \ - & (0xFFFFFFFFU >> (32-nbits))) & ~0x3F) / 65536.0f) -#endif // !USE_FIXED_POINT - - param_ret->Xst = GET_SIGNED_FLOAT(29); - param_ret->Yst = GET_SIGNED_FLOAT(29); - param_ret->Zst = GET_SIGNED_FLOAT(29); - param_ret->deltaXst = GET_SIGNED_FLOAT(19); - param_ret->deltaYst = GET_SIGNED_FLOAT(19); - param_ret->deltaX = GET_SIGNED_FLOAT(19); - param_ret->deltaY = GET_SIGNED_FLOAT(19); - param_ret->A = GET_SIGNED_FLOAT(20); - param_ret->B = GET_SIGNED_FLOAT(20); - param_ret->C = GET_SIGNED_FLOAT(20); - param_ret->D = GET_SIGNED_FLOAT(20); - param_ret->E = GET_SIGNED_FLOAT(20); - param_ret->F = GET_SIGNED_FLOAT(20); - param_ret->Px = GET_SHORT(14); - param_ret->Py = GET_SHORT(14); - param_ret->Pz = GET_SHORT(14); - addr += 2; - param_ret->Cx = GET_SHORT(14); - param_ret->Cy = GET_SHORT(14); - param_ret->Cz = GET_SHORT(14); - addr += 2; - param_ret->Mx = GET_SIGNED_FLOAT(30); - param_ret->My = GET_SIGNED_FLOAT(30); - param_ret->kx = GET_SIGNED_FLOAT(24); - param_ret->ky = GET_SIGNED_FLOAT(24); - if (param_ret->coefenab) { - param_ret->KAst = GET_UNSIGNED_FLOAT(32); - param_ret->deltaKAst = GET_SIGNED_FLOAT(26); - param_ret->deltaKAx = GET_SIGNED_FLOAT(26); - param_ret->coeftbladdr += - FIXED_TOINT(param_ret->KAst) * param_ret->coefdatasize; - } else { - param_ret->KAst = 0; - param_ret->deltaKAst = 0; - param_ret->deltaKAx = 0; - } - - #undef GET_SHORT - #undef GET_SIGNED_FLOAT - #undef GET_UNSIGNED_FLOAT - - /* - * The coordinate transformation performed for rotated graphics layers - * works out to the following: - * - * [srcX] ( [screenX]) [kx] [Xp] - * [srcY] = (M [screenY]) * [ky] + [Yp] - * ( [ 1 ]) - * - * where the "*" operator is multiplication by components (not matrix - * multiplication), M is the 2x3 constant matrix product: - * - * [A B C] [deltaX deltaXst (Xst - Px)] - * M = [D E F] [deltaY deltaYst (Yst - Py)] - * [ 0 0 (Zst - Pz)] - * - * and is a constant vector computed as: - * - * [Xp] ([A B C] [Px - Cx]) [Cx] [Mx] - * [Yp] = ([D E F] [Py - Cy]) + [Cy] + [My] - * ( [Pz - Cz]) - */ - - param_ret->mat11 = FIXED_MULT(param_ret->A, param_ret->deltaX) - + FIXED_MULT(param_ret->B, param_ret->deltaY); - param_ret->mat12 = FIXED_MULT(param_ret->A, param_ret->deltaXst) - + FIXED_MULT(param_ret->B, param_ret->deltaYst); - param_ret->mat13 = FIXED_MULT(param_ret->A, (param_ret->Xst - param_ret->Px)) - + FIXED_MULT(param_ret->B, (param_ret->Yst - param_ret->Py)) - + FIXED_MULT(param_ret->C, (param_ret->Zst - param_ret->Pz)); - param_ret->mat21 = FIXED_MULT(param_ret->D, param_ret->deltaX) - + FIXED_MULT(param_ret->E, param_ret->deltaY); - param_ret->mat22 = FIXED_MULT(param_ret->D, param_ret->deltaXst) - + FIXED_MULT(param_ret->E, param_ret->deltaYst); - param_ret->mat23 = FIXED_MULT(param_ret->D, (param_ret->Xst - param_ret->Px)) - + FIXED_MULT(param_ret->E, (param_ret->Yst - param_ret->Py)) - + FIXED_MULT(param_ret->F, (param_ret->Zst - param_ret->Pz)); - param_ret->Xp = FIXED_MULT(param_ret->A, (param_ret->Px - param_ret->Cx)) - + FIXED_MULT(param_ret->B, (param_ret->Py - param_ret->Cy)) - + FIXED_MULT(param_ret->C, (param_ret->Pz - param_ret->Cz)) - + param_ret->Cx - + param_ret->Mx; - param_ret->Yp = FIXED_MULT(param_ret->D, (param_ret->Px - param_ret->Cx)) - + FIXED_MULT(param_ret->E, (param_ret->Py - param_ret->Cy)) - + FIXED_MULT(param_ret->F, (param_ret->Pz - param_ret->Cz)) - + param_ret->Cy - + param_ret->My; -} - -/*-----------------------------------------------------------------------*/ - -/** - * get_rotation_coefficient: Retrieve a single rotation coefficient for a - * rotated graphics layer and update the rotation parameter set accordingly. - * - * This function is only to demonstrate the behavior of coefficient - * processing, and is not actually called; the per-mode-and-size optimized - * versions below are used instead. - * - * [Parameters] - * param: Rotation parameter set - * address: Address in VDP2 RAM of coefficient - * [Return value] - * Zero if this pixel is blank, else nonzero - */ -__attribute__((unused)) -static int get_rotation_coefficient(RotationParams *param, uint32_t address) -{ - FIXEDFLOAT value; - if (param->coefdatasize == 2) { - const int16_t data = T1ReadWord(Vdp2Ram, address & 0x7FFFE); - if (data < 0) { - return 0; - } -#ifdef USE_FIXED_POINT - value = (int32_t)(data << 1) << 5; -#else - value = (float)((data << 1) >> 1) / 1024.0f; -#endif - } else { - const int32_t data = T1ReadLong(Vdp2Ram, address & 0x7FFFC); - if (data < 0) { - return 0; - } -#ifdef USE_FIXED_POINT - value = (data << 8) >> 8; -#else - value = (float)((data << 8) >> 8) / 65536.0f; -#endif - } - switch (param->coefmode) { - case 0: param->kx = param->ky = value; break; - case 1: param->kx = value; break; - case 2: param->ky = value; break; - case 3: -#ifdef USE_FIXED_POINT - param->Xp = value << 8; -#else - param->Xp = value * 256.0f; -#endif - break; - } - return 1; -} - -/*----------------------------------*/ - -/** - * get_rotation_coefficient_sizeX_modeY: Retrieve a single rotation - * coefficient for a rotated graphics layer and update the rotation - * parameter set accordingly. Each routine is optimized for the specific - * case of param->coefdatasize == X and param->coefmode == Y. - * - * [Parameters] - * param: Rotation parameter set - * address: Native address of coefficient - * [Return value] - * Zero if this pixel is blank, else nonzero - */ - -static int get_rotation_coefficient_size2_mode0(RotationParams *param, - const void *address) -{ - const int16_t data = BSWAP16(*(const int16_t *)address); - if (data < 0) { - return 0; - } - param->kx = param->ky = -#ifdef USE_FIXED_POINT - (int32_t)(data << 1) << 5; -#else - (float)(data << 1) / 2048.0f; -#endif - return 1; -} - -static int get_rotation_coefficient_size2_mode1(RotationParams *param, - const void *address) -{ - const int16_t data = BSWAP16(*(const int16_t *)address); - if (data < 0) { - return 0; - } - param->kx = -#ifdef USE_FIXED_POINT - (int32_t)(data << 1) << 5; -#else - (float)(data << 1) / 2048.0f; -#endif - return 1; -} - -static int get_rotation_coefficient_size2_mode2(RotationParams *param, - const void *address) -{ - const int16_t data = BSWAP16(*(const int16_t *)address); - if (data < 0) { - return 0; - } - param->ky = -#ifdef USE_FIXED_POINT - (int32_t)(data << 1) << 5; -#else - (float)(data << 1) / 2048.0f; -#endif - return 1; -} - -static int get_rotation_coefficient_size2_mode3(RotationParams *param, - const void *address) -{ - const int16_t data = BSWAP16(*(const int16_t *)address); - if (data < 0) { - return 0; - } - param->Xp = -#ifdef USE_FIXED_POINT - (int32_t)(data << 1) << 13; -#else - (float)(data << 1) / 8.0f; -#endif - return 1; -} - -static int get_rotation_coefficient_size4_mode0(RotationParams *param, - const void *address) -{ - const int32_t data = BSWAP32(*(const int32_t *)address); - if (data < 0) { - return 0; - } - param->kx = param->ky = -#ifdef USE_FIXED_POINT - (data << 8) >> 8; -#else - (float)(data << 8) / 16777216.0f; -#endif - return 1; -} - -static int get_rotation_coefficient_size4_mode1(RotationParams *param, - const void *address) -{ - const int32_t data = BSWAP32(*(const int32_t *)address); - if (data < 0) { - return 0; - } - param->kx = -#ifdef USE_FIXED_POINT - (data << 8) >> 8; -#else - (float)(data << 8) / 16777216.0f; -#endif - return 1; -} - -static int get_rotation_coefficient_size4_mode2(RotationParams *param, - const void *address) -{ - const int32_t data = BSWAP32(*(const int32_t *)address); - if (data < 0) { - return 0; - } - param->ky = -#ifdef USE_FIXED_POINT - (data << 8) >> 8; -#else - (float)(data << 8) / 16777216.0f; -#endif - return 1; -} - -static int get_rotation_coefficient_size4_mode3(RotationParams *param, - const void *address) -{ - const int32_t data = BSWAP32(*(const int32_t *)address); - if (data < 0) { - return 0; - } - param->Xp = -#ifdef USE_FIXED_POINT - data << 8; -#else - (float)(data << 8) / 65536.0f; -#endif - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * transform_coordinates: Transform screen coordinates to source - * coordinates based on the current rotation parameters. - * - * [Parameters] - * param: Rotation parameter set - * x, y: Screen coordinates - * srcx_ret, srcy_ret: Pointers to variables to receive source coordinates - * [Return value] - * None - */ -static void transform_coordinates(const RotationParams *param, int x, int y, - FIXEDFLOAT *srcx_ret, FIXEDFLOAT *srcy_ret) -{ - *srcx_ret = FIXED_MULT(param->mat11*x + param->mat12*y + param->mat13, - param->kx) + param->Xp; - *srcy_ret = FIXED_MULT(param->mat21*x + param->mat22*y + param->mat23, - param->ky) + param->Yp; -} - -/*************************************************************************/ - -/** - * rotation_get_pixel_*: Retrieve a pixel from tiles or bitmaps of various - * pixel formats, with transparency disabled. info->charaddr is assumed to - * contain the offset of the tile or bitmap in VDP2 RAM. - * - * [Parameters] - * info: Graphics layer data - * pixelnum: Index of pixel to retrieve (y*w+x) - * [Return value] - * Pixel value as 0xAABBGGRR - */ - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t4(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum/2; - /* For speed, we assume the tile/bitmap won't wrap around the end of - * VDP2 RAM */ - const uint8_t *ptr = (const uint8_t *)(Vdp2Ram + address); - const uint8_t byte = *ptr; - const uint8_t pixel = (pixelnum & 1) ? byte & 0x0F : byte >> 4; - const unsigned int colornum = - info->coloroffset + (info->paladdr<<4 | pixel); - return global_clut_32[colornum & 0x7FF]; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t8(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum; - const uint8_t *ptr = (const uint8_t *)(Vdp2Ram + address); - const uint8_t pixel = *ptr; - const unsigned int colornum = - info->coloroffset + (info->paladdr<<4 | pixel); - return global_clut_32[colornum & 0x7FF]; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t16(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*2; - const uint16_t *ptr = (const uint16_t *)(Vdp2Ram + address); - const uint16_t pixel = BSWAP16(*ptr); - const unsigned int colornum = info->coloroffset + pixel; - return global_clut_32[colornum & 0x7FF]; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_16(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*2; - const uint16_t *ptr = (const uint16_t *)(Vdp2Ram + address); - const uint16_t pixel = BSWAP16(*ptr); - return 0xFF000000 - | (pixel & 0x7C00) << 9 - | (pixel & 0x03E0) << 6 - | (pixel & 0x001F) << 3; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_32(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*4; - const uint32_t *ptr = (const uint32_t *)(Vdp2Ram + address); - const uint32_t pixel = BSWAP32(*ptr); - return 0xFF000000 | pixel; -} - -/*-----------------------------------------------------------------------*/ - -/** - * rotation_get_pixel_*_transparent: Retrieve a pixel from tiles or - * bitmaps of various pixel formats, with transparency enabled. - * info->charaddr is assumed to contain the offset of the tile or bitmap in - * VDP2 RAM. - * - * [Parameters] - * info: Graphics layer data - * pixelnum: Index of pixel to retrieve (y*w+x) - * [Return value] - * Pixel value as 0xAABBGGRR - */ - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t4_transparent(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum/2; - /* For speed, we assume the tile/bitmap won't wrap around the end of - * VDP2 RAM */ - const uint8_t *ptr = (const uint8_t *)(Vdp2Ram + address); - const uint8_t byte = *ptr; - const uint8_t pixel = (pixelnum & 1) ? byte & 0x0F : byte >> 4; - if (!pixel) { - return 0x00000000; - } - const unsigned int colornum = - info->coloroffset + (info->paladdr<<4 | pixel); - return global_clut_32[colornum & 0x7FF]; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t8_transparent(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum; - const uint8_t *ptr = (const uint8_t *)(Vdp2Ram + address); - const uint8_t pixel = *ptr; - if (!pixel) { - return 0x00000000; - } - const unsigned int colornum = - info->coloroffset + (info->paladdr<<4 | pixel); - return global_clut_32[colornum & 0x7FF]; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t16_transparent(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*2; - const uint16_t *ptr = (const uint16_t *)(Vdp2Ram + address); - const uint16_t pixel = BSWAP16(*ptr); - if (!pixel) { - return 0x00000000; - } - const unsigned int colornum = info->coloroffset + pixel; - return global_clut_32[colornum & 0x7FF]; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_16_transparent(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*2; - const uint16_t *ptr = (const uint16_t *)(Vdp2Ram + address); - const uint16_t pixel = BSWAP16(*ptr); - if (!(pixel & 0x8000)) { - return 0x00000000; - } - return 0xFF000000 - | (pixel & 0x7C00) << 9 - | (pixel & 0x03E0) << 6 - | (pixel & 0x001F) << 3; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_32_transparent(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*4; - const uint32_t *ptr = (const uint32_t *)(Vdp2Ram + address); - const uint32_t pixel = BSWAP32(*ptr); - if (!(pixel & 0x80000000)) { - return 0x00000000; - } - return 0xFF000000 | pixel; -} - -/*-----------------------------------------------------------------------*/ - -/** - * rotation_get_pixel_*_adjust: Retrieve a pixel from tiles or bitmaps of - * various pixel formats, and apply alpha and color adjustments. - * info->charaddr is assumed to contain the offset of the tile or bitmap in - * VDP2 RAM. - * - * [Parameters] - * info: Graphics layer data - * pixelnum: Index of pixel to retrieve (y*w+x) - * [Return value] - * Pixel value as 0xAABBGGRR - */ - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t4_adjust(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum/2; - /* For speed, we assume the tile/bitmap won't wrap around the end of - * VDP2 RAM */ - const uint8_t *ptr = (const uint8_t *)(Vdp2Ram + address); - const uint8_t byte = *ptr; - const uint8_t pixel = (pixelnum & 1) ? byte & 0x0F : byte >> 4; - if (!pixel && info->transparencyenable) { - return 0x00000000; - } - const unsigned int colornum = - info->coloroffset + (info->paladdr<<4 | pixel); - return (adjust_color_32_32(global_clut_32[colornum & 0x7FF], - info->cor, info->cog, info->cob) & 0xFFFFFF) - | info->alpha << 24; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t8_adjust(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum; - const uint8_t *ptr = (const uint8_t *)(Vdp2Ram + address); - const uint8_t pixel = *ptr; - if (!pixel && info->transparencyenable) { - return 0x00000000; - } - const unsigned int colornum = - info->coloroffset + (info->paladdr<<4 | pixel); - return (adjust_color_32_32(global_clut_32[colornum & 0x7FF], - info->cor, info->cog, info->cob) & 0xFFFFFF) - | info->alpha << 24; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_t16_adjust(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*2; - const uint16_t *ptr = (const uint16_t *)(Vdp2Ram + address); - const uint16_t pixel = BSWAP16(*ptr); - if (!pixel && info->transparencyenable) { - return 0x00000000; - } - const unsigned int colornum = info->coloroffset + pixel; - return (adjust_color_32_32(global_clut_32[colornum & 0x7FF], - info->cor, info->cog, info->cob) & 0xFFFFFF) - | info->alpha << 24; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_16_adjust(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*2; - const uint16_t *ptr = (const uint16_t *)(Vdp2Ram + address); - const uint16_t pixel = BSWAP16(*ptr); - if (!(pixel & 0x8000) && info->transparencyenable) { - return 0x00000000; - } - return (adjust_color_16_32(pixel, - info->cor, info->cog, info->cob) & 0xFFFFFF) - | info->alpha << 24; -} - -/*----------------------------------*/ - -static uint32_t rotation_get_pixel_32_adjust(vdp2draw_struct *info, - unsigned int pixelnum) -{ - const uint32_t address = info->charaddr + pixelnum*4; - const uint32_t *ptr = (const uint32_t *)(Vdp2Ram + address); - const uint32_t pixel = BSWAP32(*ptr); - if (!(pixel & 0x80000000) && info->transparencyenable) { - return 0x00000000; - } - return (adjust_color_32_32(pixel, - info->cor, info->cog, info->cob) & 0xFFFFFF) - | info->alpha << 24; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-video-tilemap.c b/yabause/src/psp/psp-video-tilemap.c deleted file mode 100644 index 2a83c1b9b9..0000000000 --- a/yabause/src/psp/psp-video-tilemap.c +++ /dev/null @@ -1,551 +0,0 @@ -/* src/psp/psp-video-tilemap.c: Tile-mapped background graphics handling - for PSP video module - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../vidshared.h" - -#include "display.h" -#include "gu.h" -#include "psp-video.h" -#include "psp-video-internal.h" -#include "texcache.h" - -/*************************************************************************/ -/************************** Tile-drawing macros **************************/ -/*************************************************************************/ - -/* - * Macros to work through the Saturn's remarkably nested tile layout (used - * in map drawing routines). Use like: - * - * TILE_LOOP_BEGIN(tilesize) { - * ... // Draw a single tile based on "info" and "vertices" - * } TILE_LOOP_END; - * - * where "tilesize" is 8 or 16 (info->patternwh * 8). Note that we iterate - * over the highest-level "maps" twice to handle wraparound. - */ - -#define TILE_LOOP_BEGIN(tilesize) \ - int x1start = info->x; \ - unsigned int y1; \ - for (y1 = 0; y1 < info->mapwh*2 && info->y < info->drawh; y1++) { \ - int y2start = info->y; \ - info->x = x1start; \ - unsigned int x1; \ - for (x1 = 0; x1 < info->mapwh*2 && info->x < info->draww; x1++) {\ - info->PlaneAddr(info, ((y1 % info->mapwh) * info->mapwh) \ - + (x1 % info->mapwh)); \ - int x2start = info->x; \ - info->y = y2start; \ - unsigned int y2; \ - for (y2 = 0; y2 < info->planeh; y2++) { \ - int y3start = info->y; \ - info->x = x2start; \ - unsigned int x2; \ - for (x2 = 0; x2 < info->planew; x2++) { \ - int x3start = info->x; \ - info->y = y3start; \ - unsigned int y3; \ - for (y3 = 0; y3 < info->pagewh; \ - y3++, info->y += (tilesize) \ - ) { \ - if (UNLIKELY(info->y <= -(tilesize) \ - || info->y >= info->drawh)) { \ - info->addr += info->patterndatasize * 2 \ - * info->pagewh; \ - continue; \ - } \ - info->x = x3start; \ - unsigned int x3; \ - for (x3 = 0; x3 < info->pagewh; \ - x3++, info->x += (tilesize), \ - info->addr += info->patterndatasize * 2 \ - ) { \ - if (UNLIKELY(info->x <= -(tilesize) \ - || info->x >= info->draww)) { \ - continue; \ - } \ - vdp2_calc_pattern_address(info); - -#define TILE_LOOP_END \ - } /* Inner (pattern) X */ \ - } /* Inner (pattern) Y */ \ - } /* Middle (page) X */ \ - } /* Middle (page) Y */ \ - } /* Outer (plane) X */ \ - } /* Outer (plane) Y */ - -/*-----------------------------------------------------------------------*/ - -/* Additional macros used by tile map drawing routines */ - -/*----------------------------------*/ - -/* Set up the clipping region for the graphics layer; half_height should be - * 1 when rendering T8 tiles with the double-stride, two-pass optimization */ -#define SET_CLIP_REGION(half_height) \ - guScissor(clip->xstart, \ - half_height ? clip->ystart/2 : clip->ystart, \ - clip->xend - clip->xstart, \ - half_height ? clip->yend/2 - clip->ystart/2 \ - : clip->yend - clip->ystart) - -/* Reset the clipping region to default */ -#define UNSET_CLIP_REGION \ - guScissor(0, 0, disp_width, disp_height) - -/*----------------------------------*/ - -/* Declare tiledatasize as the size of a single tile's data in bytes. */ -#define GET_TILEDATASIZE \ - int tiledatasize; \ - switch (info->colornumber) { \ - case 0: /* 4bpp */ tiledatasize = 8*8/2; break; \ - case 1: /* 8bpp */ tiledatasize = 8*8*1; break; \ - case 2: /* 16bpp */ tiledatasize = 8*8*2; break; \ - case 3: /* 16bpp */ tiledatasize = 8*8*2; break; \ - case 4: /* 32bpp */ tiledatasize = 8*8*4; break; \ - default: DMSG("Bad tile pixel type %d", info->colornumber); \ - tiledatasize = 0; break; \ - } - -/* Allocate memory for "vertspertile" vertices per "size"x"size" tile. */ -#define GET_VERTICES(size,vertspertile) \ - /* We add 4 here to handle up to 15 pixels of partial tiles \ - * on each edge of the display area */ \ - const int tilew = info->draww / (size) + 4; \ - const int tileh = info->drawh / (size) + 4; \ - const int nvertices = tilew * tileh * (vertspertile); \ - VertexUVXYZ *vertices = pspGuGetMemoryMerge(sizeof(*vertices) * nvertices); - -/* Initialize variables for 8-bit indexed tile palette handling. There can - * be up to 128 different palettes, selectable on a per-tile basis, so to - * save time, we only create (on the fly) those which are actually used. */ -#define INIT_T8_PALETTE \ - uint32_t *palettes[128]; \ - memset(palettes, 0, sizeof(palettes)); \ - int cur_palette = -1; /* So it's always set the first time */ \ - guClutMode(GU_PSM_8888, 0, 0xFF, 0); - -/* Set the texture pixel format for 8-bit indexed tiles. 16-byte-wide - * textures are effectively swizzled already, so set the swizzled flag for - * whatever speed boost it gives us. */ -#define INIT_T8_TEXTURE \ - guTexMode(GU_PSM_T8, 0, 0, 1); - -/* Set the vertex type for 8-bit indexed tiles. */ -#define INIT_T8_VERTEX \ - guVertexFormat(GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D); - -/* Initialize the work buffer pointers for 8-bit indexed tiles. */ -#define INIT_T8_WORK_BUFFER \ - uint32_t * const work_buffer_0 = display_work_buffer(); \ - uint32_t * const work_buffer_1 = work_buffer_0 + DISPLAY_STRIDE; - -/* Initialize a variable for tracking empty tiles (initialize with an - * impossible address so it matches nothing by default). */ -#define INIT_EMPTY_TILE \ - uint32_t empty_tile_addr = 1; - -/*----------------------------------*/ - -/* Check whether this is a known empty tile, and skip the loop body if so. */ -static const uint8_t CHECK_EMPTY_TILE_bppshift_lut[8] = {2,3,4,4,5,5,5,5}; -#define CHECK_EMPTY_TILE(tilesize) \ - if (info->charaddr == empty_tile_addr) { \ - continue; \ - } \ - if (info->transparencyenable && empty_tile_addr == 1) { \ - const uint32_t bppshift = \ - CHECK_EMPTY_TILE_bppshift_lut[info->colornumber]; \ - const uint32_t tile_nwords = ((tilesize)*(tilesize)/32) << bppshift; \ - empty_tile_addr = info->charaddr; \ - const uint32_t *ptr = (const uint32_t *)&Vdp2Ram[info->charaddr]; \ - const uint32_t *top = ptr + tile_nwords; \ - for (; ptr < top; ptr++) { \ - if (*ptr != 0) { \ - empty_tile_addr = 1; \ - break; \ - } \ - } \ - if (empty_tile_addr != 1) { \ - /* The tile was empty, so we don't need to draw anything */ \ - continue; \ - } \ - } - -/* Declare flip_* and priority with the proper values for "size"x"size" - * tiles (either 8x8 or 16x16). */ -#define GET_FLIP_PRI(size) \ - const int flip_u0 = (info->flipfunction & 1) << ((size)==16 ? 4 : 3); \ - const int flip_u1 = flip_u0 ^ (size); \ - const int flip_v0 = (info->flipfunction & 2) << ((size)==16 ? 3 : 2); \ - const int flip_v1 = flip_v0 ^ (size); \ - int priority; \ - if (info->specialprimode == 1) { \ - priority = (info->priority & ~1) | info->specialfunction; \ - } else { \ - priority = info->priority; \ - } - -/* Declare flip_* and priority for 8-bit indexed tiles. */ -static const int flip_t8_u[4][4] = - { {0,8,8,16}, {8,0,16,8}, {8,16,0,8}, {16,8,8,0} }; -#define GET_FLIP_PRI_T8 \ - const int flip_u0 = flip_t8_u[info->flipfunction][0]; \ - const int flip_u1 = flip_t8_u[info->flipfunction][1]; \ - const int flip_u2 = flip_t8_u[info->flipfunction][2]; \ - const int flip_u3 = flip_t8_u[info->flipfunction][3]; \ - const int flip_v0 = (info->flipfunction & 2) << 1; \ - const int flip_v1 = flip_v0 ^ 4; \ - int priority; \ - if (info->specialprimode == 1) { \ - priority = (info->priority & ~1) | info->specialfunction; \ - } else { \ - priority = info->priority; \ - } - -/* Update the current palette for an 8-bit indexed tile, if necessary. */ -#define UPDATE_T8_PALETTE \ - if (info->paladdr != cur_palette) { \ - cur_palette = info->paladdr; \ - if (UNLIKELY(!palettes[cur_palette])) { \ - palettes[cur_palette] = vdp2_gen_t8_clut( \ - info->coloroffset, info->paladdr<<4, \ - info->transparencyenable, info->cor, info->cog, info->cob \ - ); \ - } \ - if (LIKELY(palettes[cur_palette])) { \ - const uint32_t * const clut = palettes[cur_palette];\ - guClutLoad(256/8, clut); \ - } \ - } - -/* Define 2 vertices for a generic 8x8 or 16x16 tile. */ -#define SET_VERTICES(tilex,tiley,xsize,ysize) \ - vertices[0].u = flip_u0; \ - vertices[0].v = flip_v0; \ - vertices[0].x = (tilex); \ - vertices[0].y = (tiley); \ - vertices[0].z = 0; \ - vertices[1].u = flip_u1; \ - vertices[1].v = flip_v1; \ - vertices[1].x = (tilex) + (xsize); \ - vertices[1].y = (tiley) + (ysize); \ - vertices[1].z = 0; - -/* Define 2 vertices for the even lines of an 8-bit indexed 8x8 tile. */ -#define SET_VERTICES_T8_EVEN(tilex,tiley,xsize,ysize) \ - vertices[0].u = flip_u0; \ - vertices[0].v = yofs + flip_v0; \ - vertices[0].x = (tilex); \ - vertices[0].y = (tiley) / 2; \ - vertices[0].z = 0; \ - vertices[1].u = flip_u1; \ - vertices[1].v = yofs + flip_v1; \ - vertices[1].x = (tilex) + (xsize); \ - vertices[1].y = ((tiley) + (ysize)) / 2; \ - vertices[1].z = 0; - -/* Define 2 vertices for the odd lines of an 8-bit indexed 8x8 tile. */ -#define SET_VERTICES_T8_ODD(tilex,tiley,xsize,ysize) \ - vertices[2].u = flip_u2; \ - vertices[2].v = flip_v0; \ - vertices[2].x = (tilex); \ - vertices[2].y = (tiley) / 2; \ - vertices[2].z = 0; \ - vertices[3].u = flip_u3; \ - vertices[3].v = flip_v1; \ - vertices[3].x = (tilex) + (xsize); \ - vertices[3].y = ((tiley) + (ysize)) / 2; \ - vertices[3].z = 0; - -/* Load the texture pointer for an 8-bit indexed 8x8 tile. */ -#define LOAD_T8_TILE \ - guTexFlush(); \ - guTexImage(0, 512, 512, 16, src); - -/* Set the even-lines work buffer for 8-bit indexed 8x8 tiles. */ -#define SET_T8_BUFFER_0 \ - guDrawBuffer(GU_PSM_8888, work_buffer_0, DISPLAY_STRIDE*2); - -/* Draw the even lines of an 8-bit indexed 8x8 tile */ -#define RENDER_T8_EVEN \ - guVertexPointer(vertices); \ - guDrawPrimitive(GU_SPRITES, 2); - -/* Set the odd-lines work buffer for 8-bit indexed 8x8 tiles. */ -#define SET_T8_BUFFER_1 \ - guDrawBuffer(GU_PSM_8888, work_buffer_1, DISPLAY_STRIDE*2); - -/* Draw the odd lines of an 8-bit indexed 8x8 tile. */ -#define RENDER_T8_ODD \ - guVertexPointer(vertices+2); \ - guDrawPrimitive(GU_SPRITES, 2); - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * vdp2_draw_map_8x8: Draw a graphics layer composed of 8x8 patterns of - * any format. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -void vdp2_draw_map_8x8(vdp2draw_struct *info, const clipping_struct *clip) -{ - /* Allocate vertex memory and perform other initialization */ - SET_CLIP_REGION(0); - GET_VERTICES(8, 2); - INIT_EMPTY_TILE; - - /* Loop through tiles */ - TILE_LOOP_BEGIN(8) { - CHECK_EMPTY_TILE(8); - GET_FLIP_PRI(8); - SET_VERTICES(info->x * info->coordincx, info->y * info->coordincy, - 8 * info->coordincx, 8 * info->coordincy); - texcache_load_tile(8, info->charaddr, info->colornumber, - info->transparencyenable, - info->coloroffset, info->paladdr << 4, - info->cor, info->cog, info->cob, - vdp2_is_persistent(info->charaddr)); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 2, NULL, vertices); - vertices += 2; - } TILE_LOOP_END; - - /* Reset locally-changed GE settings */ - UNSET_CLIP_REGION; -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp2_draw_map_8x8_t8: Draw a graphics layer composed of 8-bit indexed - * color 8x8 patterns. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -void vdp2_draw_map_8x8_t8(vdp2draw_struct *info, const clipping_struct *clip) -{ - /* Check the current screen mode; if we're in interlaced mode, we can - * cheat by treating each 8x8 tile as a 16x4 texture and drawing only - * the left or right half, thus omitting alternate lines for free. */ - const int interlaced = (disp_height > 272); - - /* Allocate vertex memory and perform other initialization. Note that - * we need 2 sprites to draw each tile if we're not optimizing - * interlaced graphics. */ - SET_CLIP_REGION(!interlaced); - GET_VERTICES(8, interlaced ? 2 : 4); - INIT_T8_PALETTE; - INIT_T8_TEXTURE; - INIT_T8_VERTEX; - INIT_T8_WORK_BUFFER; - INIT_EMPTY_TILE; - - /* Loop through tiles */ - TILE_LOOP_BEGIN(8) { - CHECK_EMPTY_TILE(8); - GET_FLIP_PRI_T8; - UPDATE_T8_PALETTE; - - /* Set up vertices and draw the tile */ - const uint8_t *src = &Vdp2Ram[info->charaddr]; - int yofs = ((uintptr_t)src & 63) / 16; - src = (const uint8_t *)((uintptr_t)src & ~63); - SET_VERTICES_T8_EVEN(info->x * info->coordincx, - info->y * info->coordincy, - 8 * info->coordincx, 8 * info->coordincy); - if (!interlaced) { - SET_VERTICES_T8_ODD(info->x * info->coordincx, - info->y * info->coordincy, - 8 * info->coordincx, 8 * info->coordincy); - } else { - /* We don't modify the work buffer stride in this case, so double - * the Y coordinates (which were set assuming a doubled stride) */ - vertices[0].y *= 2; - vertices[1].y *= 2; - } - LOAD_T8_TILE; - if (!interlaced) { - SET_T8_BUFFER_0; - } - RENDER_T8_EVEN; - if (!interlaced) { - SET_T8_BUFFER_1; - RENDER_T8_ODD; - vertices += 4; - } else { - /* Interlaced, so drop odd lines of tile */ - vertices += 2; - } - } TILE_LOOP_END; - - /* Reset locally-changed GE settings */ - UNSET_CLIP_REGION; - if (!interlaced) { - guDrawBuffer(GU_PSM_8888, work_buffer_0, DISPLAY_STRIDE); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp2_draw_map_16x16: Draw a graphics layer composed of 16x16 patterns - * of any format. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -void vdp2_draw_map_16x16(vdp2draw_struct *info, const clipping_struct *clip) -{ - /* Determine tile data size */ - GET_TILEDATASIZE; - - /* Allocate vertex memory and perform other initialization */ - SET_CLIP_REGION(0); - GET_VERTICES(16, 2); - INIT_EMPTY_TILE; - - /* Loop through tiles */ - TILE_LOOP_BEGIN(16) { - CHECK_EMPTY_TILE(16); - GET_FLIP_PRI(16); - - SET_VERTICES(info->x * info->coordincx, info->y * info->coordincy, - 16 * info->coordincx, 16 * info->coordincy); - texcache_load_tile(16, info->charaddr, info->colornumber, - info->transparencyenable, - info->coloroffset, info->paladdr << 4, - info->cor, info->cog, info->cob, - vdp2_is_persistent(info->charaddr)); - guDrawArray(GU_SPRITES, - GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 2, NULL, vertices); - vertices += 2; - } TILE_LOOP_END; - - /* Reset locally-changed GE settings */ - UNSET_CLIP_REGION; -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp2_draw_map_16x16_t8: Draw a graphics layer composed of 8-bit indexed - * color 16x16 patterns. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * None - */ -void vdp2_draw_map_16x16_t8(vdp2draw_struct *info, const clipping_struct *clip) -{ - /* Check the current screen mode */ - const int interlaced = (disp_height > 272); - - /* Allocate vertex memory and perform other initialization */ - SET_CLIP_REGION(!interlaced); - GET_VERTICES(8, interlaced ? 2 : 4); - INIT_T8_PALETTE; - INIT_T8_TEXTURE; - INIT_T8_VERTEX; - INIT_T8_WORK_BUFFER; - INIT_EMPTY_TILE; - - /* Loop through tiles */ - TILE_LOOP_BEGIN(16) { - CHECK_EMPTY_TILE(16); - GET_FLIP_PRI_T8; - UPDATE_T8_PALETTE; - - const uint8_t *src = &Vdp2Ram[info->charaddr]; - int yofs = ((uintptr_t)src & 63) / 16; - src = (const uint8_t *)((uintptr_t)src & ~63); - int tilenum; - for (tilenum = 0; tilenum < 4; tilenum++, src += 8*8*1) { - const int tilex = info->x + (8 * ((tilenum % 2) ^ (info->flipfunction & 1))); - const int tiley = info->y + (8 * ((tilenum / 2) ^ ((info->flipfunction & 2) >> 1))); - SET_VERTICES_T8_EVEN(tilex * info->coordincx, - tiley * info->coordincy, - 8 * info->coordincx, 8 * info->coordincy); - if (!interlaced) { - SET_VERTICES_T8_ODD(tilex * info->coordincx, - tiley * info->coordincy, - 8 * info->coordincx, 8 * info->coordincy); - } else { - vertices[0].y *= 2; - vertices[1].y *= 2; - } - - LOAD_T8_TILE; - if (!interlaced) { - SET_T8_BUFFER_0; - } - RENDER_T8_EVEN; - if (!interlaced) { - SET_T8_BUFFER_1; - RENDER_T8_ODD; - vertices += 4; - } else { - vertices += 2; - } - } - } TILE_LOOP_END; - - /* Reset locally-changed GE settings */ - UNSET_CLIP_REGION; - if (!interlaced) { - guDrawBuffer(GU_PSM_8888, work_buffer_0, DISPLAY_STRIDE); - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-video-tweaks.c b/yabause/src/psp/psp-video-tweaks.c deleted file mode 100644 index 615d005495..0000000000 --- a/yabause/src/psp/psp-video-tweaks.c +++ /dev/null @@ -1,1884 +0,0 @@ -/* src/psp/psp-video-tweaks.c: Game-specific tweaks for PSP video module - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../memory.h" -#include "../vdp2.h" -#include "../vidshared.h" - -#include "config.h" -#include "gu.h" -#include "psp-video.h" -#include "psp-video-internal.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Local routine declarations (internal helpers are declared in their - * respective sections) */ - -static void Azel_fix_registers(void); -static int Azel_draw_NBG1(vdp2draw_struct *info, - const clipping_struct *clip); -static void Azel_reset_cache(void); -static void Azel_cache_RBG0(void); -static int Azel_draw_RBG0(vdp2draw_struct *info, - const clipping_struct *clip); - -/*************************************************************************/ -/************************** Interface function ***************************/ -/*************************************************************************/ - -/** - * psp_video_apply_tweaks: Apply game-specific optimizations and tweaks - * for faster/better PSP video output. Called at the beginning of drawing - * each frame. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void psp_video_apply_tweaks(void) -{ - /**** Azel: Panzer Dragoon RPG (JP) ****/ - - if (memcmp(HighWram+0x42F34, "APDNAR\0003", 8) == 0) { - - /* For reasons unknown (but possibly an emulator bug), VDP1 and - * RBG0 are one frame out of sync, with RBG0 lagging behind. - * However, if the game is in 30fps mode and we're also skipping - * one frame (or in fact any number of odd frames) per frame drawn, - * we can hide this lag by always skipping the frame in which the - * VDP1 command table is updated. The game finalizes the command - * list by updating the jump target at VDP1 address 0x00082, so we - * watch for changes and use that to sync the frame skipper. */ - static uint8_t just_adjusted = 0; // Avoid infinite loops, just in case - static uint16_t last_00082 = 0xFFFF; // Impossible value - const uint16_t this_00082 = T1ReadWord(Vdp1Ram, 0x00082); - const int game_framerate = T2ReadLong(HighWram, 0x4BC94); - if (!just_adjusted - && game_framerate == 2 - && this_00082 != last_00082 - && frames_to_skip % 2 == 1 - && frames_skipped % 2 == 1 - ) { - frames_skipped--; - just_adjusted = 1; - } else { - just_adjusted = 0; - } - last_00082 = this_00082; - - /* Fix bogus/suboptimal register settings. */ - Azel_fix_registers(); - - /* Apply the top/bottom black border to NBG1 implemented using - * line scrolling. */ - psp_video_set_draw_routine(BG_NBG1, Azel_draw_NBG1, 0); - - /* Draw sky/ground RBG0 graphics more efficiently, if requested. */ - if (config_get_optimize_rotate() && (Vdp2Regs->BGON & 0x0010)) { - Azel_cache_RBG0(); - psp_video_set_draw_routine(BG_RBG0, Azel_draw_RBG0, 1); - } else { - Azel_reset_cache(); - psp_video_set_draw_routine(BG_RBG0, NULL, 0); - } - - } -} - -/*************************************************************************/ -/**************************** Local functions ****************************/ -/*************************************************************************/ - -/**** Azel: Panzer Dragoon RPG (JP) optimizers ****/ - -/*-----------------------------------------------------------------------*/ - -/* Exported variables for RBG0 slope and first coefficient reciprocal, - * set by the optimized RBG0 coefficient generator in satopt-sh2.c. */ -#define SLOPE_UNSET 1e10f -float psp_video_tweaks_Azel_RBG0_slope = SLOPE_UNSET; -float psp_video_tweaks_Azel_RBG0_first_recip; - -/*----------------------------------*/ - -/* Do we have data for RBG0 cached? */ -static uint8_t Azel_RBG0_cached; - -/* Palette indices (0-7) for sky (flat) and ground (scaled) planes. */ -static uint8_t Azel_sky_palette, Azel_ground_palette; - -/* Does the sky wrap vertically? */ -static uint8_t Azel_sky_wrap_v; - -/* Is the ground texture already reduced by half? */ -static uint8_t Azel_ground_reduced; - -/* VDP2 plane addresses for sky and ground planes. */ -static uint32_t Azel_sky_plane_address, Azel_ground_plane_address; - -/* Checksum for plane data. */ -static uint32_t Azel_plane_data_checksum; - -/* Pixel buffers for cached plane data. */ -static uint8_t *Azel_sky_cache, *Azel_ground_cache; - -/* Data structure used for coordinate calculation. */ -struct Azel_RBG0_coord {int x, y, overdraw_x, overdraw_y;}; - -/*----------------------------------*/ - -static void Azel_cache_plane(uint32_t plane_address, uint32_t tile_base, - uint8_t *dest); -static void Azel_make_mipmap(const uint8_t *in, unsigned int size, - uint8_t *out, unsigned int stride); -static void Azel_get_rotation_matrix(uint32_t address, float matrix[2][3], - float *kx_ret, float *ky_ret, - float *Xp_ret, float *Yp_ret); -static void Azel_transform_coordinates(const float x, const float y, - float *u_ret, float *v_ret, - float M[2][3], - const float kx, const float ky, - const float Xp, const float Yp); -static inline void Azel_compute_switch( - uint32_t coef_base, uint32_t coef_switch_index, - const uint32_t coef_index_UL, const uint32_t coef_index_UR, - const uint32_t coef_index_LL, const uint32_t coef_index_LR, - float coef_dx, float coef_dy, - int *switch_x0, int *switch_y0, int *switch_x1, int *switch_y1); -static inline void Azel_compute_vertices( - int UL_is_sky, int UR_is_sky, int LL_is_sky, int LR_is_sky, - int switch_x0, int switch_y0, int switch_x1, int switch_y1, - struct Azel_RBG0_coord coord[2][5], unsigned int nverts[2]); - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_fix_registers: Fix VDP2 registers which are set improperly (but do - * not exhibit problems on a real Saturn due to hardware idiosyncrasies) or - * inefficiently (so that they waste more resources than necessary). - * - * [Parameters] - * None - * [Return value] - * None - */ -static void Azel_fix_registers(void) -{ - /* Fix bogus sprite alpha setting in the Uru underwater tunnel. */ - if (Vdp2Regs->PNCN1 == 0xC100 - && Vdp2Regs->MPABN1 == 0x0B0B - && Vdp2Regs->MPCDN1 == 0x0B0B - && Vdp2Regs->RPTA.all == 0x14000 - && T1ReadLong(Vdp2Ram, 0x28054) == 0x80640000 - && T1ReadLong(Vdp2Ram, 0x28058) == 0x10000 - && (int32_t)T1ReadLong(Vdp2Ram, 0x20190 + 223*4) < 0 - && Vdp2Regs->SPCTL == 0x1523 - && Vdp2Regs->CCCTL == 0x0053 - && Vdp2Regs->SFCCMD == 0x0008 - && Vdp2Regs->PRISA == 0x0405 - && Vdp2Regs->PRINA == 0x0604 - && Vdp2Regs->CCRSA == 0x000C - && Vdp2Regs->CCRNA == 0x101F - ) { - Vdp2Regs->CCRSA &= 0xFF00; - } - - /* Fix bogus sprite alpha setting in the imperial base. */ - if (Vdp2Regs->BGON == 0x011B - && Vdp2Regs->SFSEL == 0x0002 - && Vdp2Regs->CHCTLA == 0x0101 - && Vdp2Regs->CHCTLB == 0x1100 - && Vdp2Regs->PNCN0 == 0x8080 - && Vdp2Regs->PNCN1 == 0xC100 - && Vdp2Regs->PLSZ == 0x0000 - && Vdp2Regs->MPABN0 == 0x3E3E - && Vdp2Regs->MPABN0 == 0x3E3E - && Vdp2Regs->MPABN1 == 0x0B0B - && Vdp2Regs->MPCDN1 == 0x0B0B - && T1ReadLong(Vdp2Ram, 0x1F000) == 0x02010202 - && T1ReadLong(Vdp2Ram, 0x1008C) == 0x99889999 - && Vdp2Regs->SPCTL == 0x1423 - && (Vdp2Regs->CCCTL & ~0x0010) == 0x0143 - && Vdp2Regs->SFCCMD == 0x0008 - && Vdp2Regs->PRISA == 0x0404 - && (Vdp2Regs->PRINA & ~0x0001) == 0x0604 - && (Vdp2Regs->PRINA & 0xF) == (Vdp2Regs->CCCTL>>4 & 0xF) - && Vdp2Regs->CCRSA == 0x180D - && Vdp2Regs->CCRNA == 0x1017 - ) { - Vdp2Regs->CCRSA &= 0xFF00; - } - - /* Fix missing(?) alpha setting for the NBG0 cloud overlay used in - * Mel-Kava and in Atolm battles. (NBG0 is at the third-highest - * priority level; how does it get color calculation enabled in the - * first place?) */ - if ((Vdp2Regs->BGON & ~0x0100) == 0x001B - && Vdp2Regs->SFSEL == 0x0002 - && Vdp2Regs->CHCTLA == 0x0101 - && Vdp2Regs->CHCTLB == 0x1100 - && (Vdp2Regs->PNCN0 & ~0x0020) == 0x8080 - && Vdp2Regs->PNCN1 == 0xC100 - && Vdp2Regs->PLSZ == 0x0000 - && Vdp2Regs->MPABN0 == 0x3C3C - && Vdp2Regs->MPABN0 == 0x3C3C - && Vdp2Regs->MPABN1 == 0x0B0B - && Vdp2Regs->MPCDN1 == 0x0B0B - && T1ReadLong(Vdp2Ram, 0x1E000) == 0x02010202 - && T1ReadLong(Vdp2Ram, 0x100F8) == 0x11111222 - && (Vdp2Regs->CCCTL & ~0x0010) == 0x0103 - && Vdp2Regs->SFCCMD == 0x0008 - && (Vdp2Regs->PRINA & ~0x0001) == 0x0604 - && (Vdp2Regs->PRINA & 0x1) == (Vdp2Regs->CCCTL>>4 & 0x1) - && Vdp2Regs->CCRNA == 0x1000 - ) { - Vdp2Regs->CCRNA |= 0x0017; - } - - /* Display movies with transparency disabled to improve draw speed. */ - if ((Vdp2Regs->CHCTLA & 0x0070) == 0x0040) { - Vdp2Regs->BGON |= 0x0100; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_draw_NBG1: Draw NBG1, along with any black borders specified by - * the line scroll table. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * Nonzero if the graphics layer was drawn, zero if not - */ -static int Azel_draw_NBG1(vdp2draw_struct *info, - const clipping_struct *clip) -{ - /* First check whether this is an optimizable case, and punt back to - * the default if not. */ - - if ((Vdp2Regs->SCRCTL & 0x3F00) != 0x400) { - return 0; // No black bars to draw - } - if (UNLIKELY(info->isbitmap || info->patternwh != 2)) { - DMSG("Bad NBG1 parameters: isbitmap=%d patternwh=%d", - info->isbitmap, info->patternwh); - return 0; - } - - /* Draw the screen itself as usual. */ - - vdp2_draw_map_16x16(info, clip); - - /* Render black bars for lines scrolled off the screen (i.e., to black) - * in the line scroll table. */ - - const uint32_t address = (Vdp2Regs->LSTA1.all & 0x3FFFE) << 1; - const uint8_t *table = &Vdp2Ram[address]; - - guDisable(GU_TEXTURE_2D); - - int in_black_bar = 0; - unsigned int black_bar_top = 0; - unsigned int y; - for (y = 0; y <= disp_height; y++, table += 4) { // Deliberately "<=" - if (y < disp_height && *table != 0) { - if (!in_black_bar) { - black_bar_top = y; - in_black_bar = 1; - } - } else { - if (in_black_bar) { - struct {uint32_t color; int16_t x, y, z, pad;} *vertices; - vertices = guGetMemory(sizeof(*vertices) * 2); - vertices[0].color = 0xFF000000; - vertices[0].x = 0; - vertices[0].y = black_bar_top >> disp_yscale; - vertices[0].z = 0; - vertices[1].color = 0xFF000000; - vertices[1].x = disp_width >> disp_xscale; - vertices[1].y = y >> disp_yscale; - vertices[1].z = 0; - guDrawArray(GU_SPRITES, - GU_TRANSFORM_2D | GU_COLOR_8888 | GU_VERTEX_16BIT, - 2, NULL, vertices); - in_black_bar = 0; - } - } - } - - guEnable(GU_TEXTURE_2D); - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_reset_cache: Clear all cached RBG0 data. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void Azel_reset_cache(void) -{ - Azel_RBG0_cached = 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_cache_RBG0: Check whether the current RBG0 data matches the cached - * data, and cache it if not. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void Azel_cache_RBG0(void) -{ - /* Look up the graphics layer format and make sure it's what we're - * looking for. */ - - const unsigned int colornumber = Vdp2Regs->CHCTLB>>12 & 0x7; - const unsigned int patternwh = Vdp2Regs->CHCTLB & 0x100 ? 2 : 1; - const unsigned int patterndatasize = Vdp2Regs->PNCR & 0x8000 ? 2 : 4; - const unsigned int auxmode = Vdp2Regs->PNCR & 0x4000 ? 1 : 0; - const unsigned int supplementdata = Vdp2Regs->PNCR & 0x3FF; - const unsigned int planewh_A = Vdp2Regs->PLSZ>>8 & 0x3; - const unsigned int planewh_B = Vdp2Regs->PLSZ>>12 & 0x3; - const unsigned int rpmd = Vdp2Regs->RPMD & 0x3; - const unsigned int raovr = Vdp2Regs->PLSZ>>10 & 0x3; - const unsigned int raopn = Vdp2Regs->OVPNRA; - if (colornumber != 1 || patternwh != 2 || patterndatasize != 2 - || auxmode || planewh_A != 0 || planewh_B != 0 - || (rpmd != 2 && !(rpmd == 0 && raovr == 1 && raopn == 0x5000)) - ) { - DMSG("Wrong RBG0 format for cache: colornumber=%u patternwh=%u" - " patterndatasize=%u auxmode=%u planewh=%u/%u rpmd=%u", - colornumber, patternwh, patterndatasize, auxmode, planewh_A, - planewh_B, rpmd); - Azel_RBG0_cached = 0; - return; - } - - /* Calculate the plane data addresses for the sky and ground planes, - * and check that they haven't changed from the cached values. */ - - const unsigned int plane_size = - (64/patternwh) * (64/patternwh) * patterndatasize; - const unsigned int sky_plane = - (Vdp2Regs->MPOFR>>4 & 7) << 6 | (Vdp2Regs->MPABRB & 0xFF); - const unsigned int ground_plane = - (Vdp2Regs->MPOFR>>0 & 7) << 6 | (Vdp2Regs->MPABRA & 0xFF); - const unsigned int sky_plane_address = sky_plane * plane_size; - const unsigned int ground_plane_address = ground_plane * plane_size; - if (Azel_RBG0_cached - && (sky_plane_address != Azel_sky_plane_address - || ground_plane_address != Azel_ground_plane_address) - ) { - DMSG("Plane addresses changed, now sky=%05X ground=%05X", - sky_plane_address, ground_plane_address); - Azel_RBG0_cached = 0; - } - - /* Calculate a checksum for the plane data and check it against the - * cached checksum. If the plane data matches, we assume the tile - * (pixel) data matches as well. */ - - uint16_t sum1 = 1, sum2 = 0; - const uint16_t *ptr, *top; - for (ptr = (const uint16_t *)&Vdp2Ram[sky_plane_address], - top = ptr + plane_size/2; ptr < top; ptr++ - ) { - const uint16_t data = BSWAP16(*ptr); - sum1 += data; - sum2 += sum1; - } - for (ptr = (const uint16_t *)&Vdp2Ram[ground_plane_address], - top = ptr + plane_size/2; ptr < top; ptr++ - ) { - const uint16_t data = BSWAP16(*ptr); - sum1 += data; - sum2 += sum1; - } - const uint32_t checksum = sum1 | sum2<<16; - if (checksum != Azel_plane_data_checksum) { - DMSG("Plane data checksum changed, now 0x%08X", checksum); - Azel_RBG0_cached = 0; - } - - /* If Azel_RBG0_cached is still set, the current RBG0 data already - * matches the cache, so we don't have to do anything else. */ - - if (Azel_RBG0_cached) { - return; - } - - /* Allocate a cache buffer if we haven't done so yet. (We don't free - * the buffers once we allocate them, on the assumption that only one - * game will be played per Yabause boot.) */ - - if (!Azel_sky_cache) { - uint8_t *base = malloc(63 + 512*512 - + 512*512 + 256*256 + 128*128 + 64*64); - if (!base) { - DMSG("No memory for sky/ground pixel buffers"); - return; - } - uintptr_t base_aligned = ((uintptr_t)base + 63) & -64; - Azel_sky_cache = (uint8_t *)base_aligned; - Azel_ground_cache = (uint8_t *)(base_aligned + 512*512); - } - - /* Cache the graphics data (two 512x512-pixel planes) in - * Azel_{sky,ground}_cache as 512x512 T8 swizzled textures. Also add - * mipmaps for the ground texture to improve drawing performance for - * distant regions. */ - - Azel_cache_plane(sky_plane_address, - (supplementdata & 0xC) << 15 | (supplementdata & 3) << 5, - Azel_sky_cache); - if ((Vdp2Regs->RPMD & 3) == 0 - && Vdp2Regs->MPABRA == 0x0100 - && Vdp2Regs->MPEFRA == 0x0203 - ) { - /* Special case for the dome area of the Uru underground dungeon, - * which is a shrunken 1024x1024 map. We reduce it to 512x512 and - * adjust the scale factors appropriately when drawing. */ - Azel_ground_reduced = 1; - uint8_t *temp = malloc(512*512); - if (!temp) { - DMSG("No temporary memory for reducing dome RBG0"); - return; - } - Azel_cache_plane(ground_plane_address, - (supplementdata & 0xC)<<15 | (supplementdata & 3)<<5, - temp); - Azel_make_mipmap(temp, 512, Azel_ground_cache, 512); - Azel_cache_plane(ground_plane_address + 0x800, - (supplementdata & 0xC)<<15 | (supplementdata & 3)<<5, - temp); - Azel_make_mipmap(temp, 512, Azel_ground_cache + 256*8, 512); - Azel_cache_plane(ground_plane_address + 0x1800, - (supplementdata & 0xC)<<15 | (supplementdata & 3)<<5, - temp); - Azel_make_mipmap(temp, 512, Azel_ground_cache + 512*256, 512); - Azel_cache_plane(ground_plane_address + 0x1000, - (supplementdata & 0xC)<<15 | (supplementdata & 3)<<5, - temp); - Azel_make_mipmap(temp, 512, Azel_ground_cache + 512*256 + 256*8, 512); - free(temp); - } else { - Azel_ground_reduced = 0; - Azel_cache_plane(ground_plane_address, - (supplementdata & 0xC)<<15 | (supplementdata & 3)<<5, - Azel_ground_cache); - } - Azel_make_mipmap(Azel_ground_cache, 512, - Azel_ground_cache + 512*512, 256); - Azel_make_mipmap(Azel_ground_cache + 512*512, 256, - Azel_ground_cache + 512*512 + 256*256, 128); - Azel_make_mipmap(Azel_ground_cache + 512*512 + 256*256, 128, - Azel_ground_cache + 512*512 + 256*256 + 128*128, 64); - - /* Record other data in relevant variables and set the cached flag. */ - - Azel_sky_palette = Vdp2Ram[sky_plane_address] >> 4; - Azel_ground_palette = Vdp2Ram[ground_plane_address] >> 4; - Azel_sky_wrap_v = (Vdp2Regs->MPEFRB == Vdp2Regs->MPABRB); - Azel_sky_plane_address = sky_plane_address; - Azel_ground_plane_address = ground_plane_address; - Azel_plane_data_checksum = checksum; - Azel_RBG0_cached = 1; - psp_video_tweaks_Azel_RBG0_slope = SLOPE_UNSET; -} - -/*----------------------------------*/ - -/** - * Azel_cache_plane: Cache a single plane of graphics data as a 512x512 - * T8-format swizzled texture. - * - * [Parameters] - * plane_address: Address of plane data in VDP2 RAM - * tile_base: Base address of tile (pixel) data in VDP2 RAM - * dest: Pointer to output buffer (512*512 bytes) - * [Return value] - * None - */ -static void Azel_cache_plane(uint32_t plane_address, uint32_t tile_base, - uint8_t *dest) -{ - const uint16_t *src = (const uint16_t *)&Vdp2Ram[plane_address]; - - unsigned int tile_y; - for (tile_y = 0; tile_y < 32; tile_y++) { - uint8_t *out_ptr = &dest[(tile_y * 16) * 512]; - unsigned int tile_x; - for (tile_x = 0; tile_x < 32; tile_x++, src++, out_ptr += 128) { - const uint16_t data = BSWAP16(*src); - unsigned int tile_index = (data & 0x3FF) << 2; - unsigned int flip_x = (data & 0x400) ? 8 : 0; - unsigned int flip_y = (data & 0x800) ? 15 : 0; - const uint8_t *tile_data = &Vdp2Ram[tile_base + (tile_index<<5)]; - unsigned int char_y; - for (char_y = 0; char_y < 2; char_y++) { - unsigned int char_x; - for (char_x = 0; char_x < 2; char_x++) { - unsigned int pixel_y; - for (pixel_y = 0; pixel_y < 8; pixel_y++, tile_data += 8) { - const unsigned int y = (char_y*8 + pixel_y) ^ flip_y; - uint8_t * const y_ptr = - &out_ptr[((y/8) * (512*8)) + ((y%8) * 16) - + ((char_x*8) ^ flip_x)]; - const uint32_t pix0_3 = - ((const uint32_t *)tile_data)[0]; - const uint32_t pix4_7 = - ((const uint32_t *)tile_data)[1]; - if (flip_x) { - ((uint32_t *)y_ptr)[0] = BSWAP32(pix4_7); - ((uint32_t *)y_ptr)[1] = BSWAP32(pix0_3); - } else { - ((uint32_t *)y_ptr)[0] = pix0_3; - ((uint32_t *)y_ptr)[1] = pix4_7; - } - } // pixel_y - } // char_x - } // char_y - } // tile_x - } // tile_y -} - -/*----------------------------------*/ - -/** - * Azel_make_mipmap: Create a half-size mipmap from the given pixel buffer - * by dropping every second pixel. - * - * [Parameters] - * in: Input pixel buffer - * size: Size (width and height) of input pixel buffer - * out: Output pixel buffer - * stride: Line length of output buffer (normally size/2) - * [Return value] - * None - */ -static void Azel_make_mipmap(const uint8_t *in, unsigned int size, - uint8_t *out, unsigned int stride) -{ -#define SHRINK \ - asm(".set push; .set noreorder\n" \ - "srl %[temp], %[a], 16\n" \ - "ins %[a], %[temp], 8, 8\n" \ - "ins %[a], %[b], 16, 8\n" \ - "srl %[b], %[b], 16\n" \ - "ins %[a], %[b], 24, 8\n" \ - "srl %[temp], %[c], 16\n" \ - "ins %[c], %[temp], 8, 8\n" \ - "ins %[c], %[d], 16, 8\n" \ - "srl %[d], %[d], 16\n" \ - "ins %[c], %[d], 24, 8\n" \ - ".set pop" \ - : [a] "=r" (a), [b] "=r" (b), [c] "=r" (c), [d] "=r" (d), \ - [temp] "=&r" (temp) \ - : "0" (a), "1" (b), "2" (c), "3" (d) \ - ) - - unsigned int y; - for (y = 0; y < size; y += 16, in += size*8, out += (stride - size/2)*8) { - unsigned int x; - for (x = 0; x < size; x += 32, in += 128, out += 64) { - unsigned int line; - for (line = 0; line < 4; line++, in += 32, out += 16) { - uint32_t a, b, c, d, temp; - - a = ((const uint32_t *)in)[0]; - b = ((const uint32_t *)in)[1]; - c = ((const uint32_t *)in)[2]; - d = ((const uint32_t *)in)[3]; - SHRINK; - ((uint32_t *)out)[0] = a; - ((uint32_t *)out)[1] = c; - - a = ((const uint32_t *)in)[32]; - b = ((const uint32_t *)in)[33]; - c = ((const uint32_t *)in)[34]; - d = ((const uint32_t *)in)[35]; - SHRINK; - ((uint32_t *)out)[2] = a; - ((uint32_t *)out)[3] = c; - - a = ((const uint32_t *)in)[size*2+0]; - b = ((const uint32_t *)in)[size*2+1]; - c = ((const uint32_t *)in)[size*2+2]; - d = ((const uint32_t *)in)[size*2+3]; - SHRINK; - ((uint32_t *)out)[16] = a; - ((uint32_t *)out)[17] = c; - - a = ((const uint32_t *)in)[size*2+32]; - b = ((const uint32_t *)in)[size*2+33]; - c = ((const uint32_t *)in)[size*2+34]; - d = ((const uint32_t *)in)[size*2+35]; - SHRINK; - ((uint32_t *)out)[18] = a; - ((uint32_t *)out)[19] = c; - } - } - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_draw_RBG0: Draw a sky/ground RBG0 layer from cached data. - * - * [Parameters] - * info: Graphics layer data - * clip: Clipping window data - * [Return value] - * Nonzero if the graphics layer was drawn, zero if not - */ -static int Azel_draw_RBG0(vdp2draw_struct *info, - const clipping_struct *clip) -{ - /* Define a macro to read a coefficient as a signed value, given its - * index (longword offset into VDP2 RAM). coef_mask is defined below. */ - #define READ_COEF(index) \ - ((int32_t)T1ReadLong(Vdp2Ram, (index)*4) & coef_mask) - - if (!Azel_RBG0_cached) { - return 0; - } - - /* Make sure it's an RPMD mode 2 layer with 4-byte, mode-0 coefficients - * for the ground (set A) and no coefficients for the sky (set B). - * However, also allow mode 0 with certain parameter settings used in - * the Uru underground dungeon. */ - - if ((Vdp2Regs->RPMD & 3) != 2 - && !((Vdp2Regs->RPMD & 3) == 0 - && (Vdp2Regs->PLSZ>>10 & 3) == 1 - && Vdp2Regs->OVPNRA == 0x5000) - ) { - DMSG("Can't optimize RBG0 (bad rotatemode=%d)", info->rotatemode); - return 0; - } - const int has_sky = ((Vdp2Regs->RPMD & 3) == 2); - const uint32_t param_address = (Vdp2Regs->RPTA.all << 1) & 0x7FF7C; - const uint32_t coef_base_high = (Vdp2Regs->KTAOF & 1) << 18; - if ((Vdp2Regs->KTCTL & 0x0F0F) != 0x0001) { - DMSG("Can't optimize RBG0 (bad KTCTL=%04X)", Vdp2Regs->KTCTL); - return 0; - } - - /* Load rotation matrix parameters. */ - - float sky_M[2][3], sky_kx, sky_ky, sky_Xp, sky_Yp; - float ground_M[2][3], ground_Xp, ground_Yp; - Azel_get_rotation_matrix(param_address + 0x80, - sky_M, &sky_kx, &sky_ky, &sky_Xp, &sky_Yp); - Azel_get_rotation_matrix(param_address, - ground_M, NULL, NULL, &ground_Xp, &ground_Yp); - - const float coef_base = coef_base_high/4 - + (uint32_t)T1ReadLong(Vdp2Ram, param_address+0x54) / 65536.0f; - const float coef_dy = - ((int32_t)T1ReadLong(Vdp2Ram, param_address+0x58) << 6) / 4194304.0f; - const float coef_dx = - ((int32_t)T1ReadLong(Vdp2Ram, param_address+0x5C) << 6) / 4194304.0f; - const float coef_right_offset = (disp_width - 1) * coef_dx; - - /* Find the beginning and end of the coefficient table, and determine - * where the sky/ground boundary is. For a non-rotated background, - * the table length will simply be the number of lines on the screen, - * but when the background is rotated, we need to check all four - * corners of the screen to find the table's extent. - * - * Coefficient values are treated as signed 8.16 bit fixed point, but - * the program does not clamp its coefficient values properly; as a - * result, the coefficient value can spill over into the sign bit or - * the ignored high bits for lines very close to the horizon. We treat - * these as sky lines in order to avoid mathematical trouble when - * drawing. Due to this, we optimize the (data > 0 && data < 0x800000) - * test into ((unsigned)data < 0x800000) for more efficient processing. - * However, there are some areas (such as Mel-Kava) which intentionally - * store data into the upper 8 bits, which we detect by finding four - * consecutive coefficients with upper 8 bits between 0x01-0x7F and - * lower 24 bits less than 0x800000; in that case we mask off bits - * 24-30 when reading the coefficients. - * - * We also check to see whether the ground coefficients are zero (as - * seems to happen sometimes during a scene change) in order to avoid - * division by zero when rendering. We assume that either all or no - * coefficients are zero, so we only check the first one in the ground - * region. */ - - const float coef_index_UL = coef_base; - const float coef_index_UR = coef_index_UL + coef_right_offset; - const float coef_index_LL = coef_base + (disp_height - 1) * coef_dy; - const float coef_index_LR = coef_index_LL + coef_right_offset; - const uint32_t first_coef_index = - MIN(MIN(ifloorf(coef_index_UL), ifloorf(coef_index_UR)), - MIN(ifloorf(coef_index_LL), ifloorf(coef_index_LR))); - const uint32_t last_coef_index = - MAX(MAX(ifloorf(coef_index_UL), ifloorf(coef_index_UR)), - MAX(ifloorf(coef_index_LL), ifloorf(coef_index_LR))); - const uint32_t num_coefs = last_coef_index + first_coef_index - 1; - - int high_bits_used_count = 0; - int32_t coef_mask = -1; - int ground_is_zero; - unsigned int coef_switch_index; - - retry_coef_scan: - - if ((uint32_t)READ_COEF(first_coef_index) >= 0x800000) { - - ground_is_zero = 0; - unsigned int offset; - for (offset = 0; offset < num_coefs; offset++) { - const uint32_t data = READ_COEF(first_coef_index + offset); - if (coef_mask == -1) { - if ((data>>24 >= 0x01 && data>>24 <= 0x7F) - && (data & 0xFFFFFF) < 0x800000 - ) { - high_bits_used_count++; - if (high_bits_used_count >= 4) { - coef_mask = (int32_t)0x80FFFFFF; - goto retry_coef_scan; - } - } else { - high_bits_used_count = 0; - } - } - if (data < 0x800000) { - ground_is_zero = (data == 0); - break; - } - } - coef_switch_index = first_coef_index + offset; - - } else { - - ground_is_zero = (READ_COEF(first_coef_index) == 0); - unsigned int offset; - for (offset = 0; offset < num_coefs; offset++) { - const uint32_t data = READ_COEF(first_coef_index + offset); - if (data >= 0x800000) { - break; - } - } - coef_switch_index = first_coef_index + offset; - - } - - /* Determine the endpoints of the sky/ground dividing line, if any. */ - - const int has_switch = (coef_switch_index <= last_coef_index); - int switch_x0, switch_y0, switch_x1, switch_y1; - - if (has_switch) { - Azel_compute_switch(coef_base, coef_switch_index, coef_index_UL, - coef_index_UR, coef_index_LL, coef_index_LR, - coef_dx, coef_dy, &switch_x0, &switch_y0, - &switch_x1, &switch_y1); - if (UNLIKELY(switch_x0 < 0 || switch_x1 < 0)) { - DMSG("Failed to find swith line endpoints (base=%05X dx=%.3f" - " dy=%.3f", ifloorf(coef_base)*4, coef_dx, coef_dy); - return 0; - } - } else { // !has_switch - /* Set the switch line at the bottom of the screen for simplicity. */ - switch_x0 = 0; - switch_y0 = disp_height; - switch_x1 = disp_width; - switch_y1 = disp_height; - } // if (has_switch) - - /* Work out the vertex coordinates of the sky and ground regions. - * Depending on where the switch line falls, these could be three-, - * four-, or five-sided polygons. To avoid unnecessary code - * duplication, we first compute the vertices themselves, then choose - * which vertex set (coord[0] or coord[1]) to use for the sky and - * ground regions. - * - * The "overdraw_x" and "overdraw_y" fields are set to either +1 or - * -1 to indicate the direction each coordinate should be shifted for - * overdrawing when rendering the sky region. */ - - struct Azel_RBG0_coord coord[2][5]; - unsigned int nverts[2]; - - const int UL_is_sky = - ((uint32_t)READ_COEF(ifloorf(coef_index_UL)) >= 0x800000); - const int UR_is_sky = - ((uint32_t)READ_COEF(ifloorf(coef_index_UR)) >= 0x800000); - const int LL_is_sky = - ((uint32_t)READ_COEF(ifloorf(coef_index_LL)) >= 0x800000); - const int LR_is_sky = - ((uint32_t)READ_COEF(ifloorf(coef_index_LR)) >= 0x800000); - - Azel_compute_vertices(UL_is_sky, UR_is_sky, LL_is_sky, LR_is_sky, - switch_x0, switch_y0, switch_x1, switch_y1, - coord, nverts); - - const unsigned int sky_coord_set = UL_is_sky ? 0 : 1; - unsigned int ground_coord_set = sky_coord_set ^ 1; // May be changed later - - /* Generate color tables for the two background portions. */ - - void *sky_clut, *ground_clut; - sky_clut = vdp2_gen_t8_clut(Azel_sky_palette << 8, 0, - info->transparencyenable, - info->cor, info->cog, info->cob); - if (!sky_clut) { - DMSG("Failed to generate sky CLUT (palette %u)", Azel_sky_palette); - return 0; - } - ground_clut = vdp2_gen_t8_clut(Azel_ground_palette << 8, 0, - info->transparencyenable, - info->cor, info->cog, info->cob); - if (!ground_clut) { - DMSG("Failed to generate ground CLUT (palette %u)", - Azel_ground_palette); - return 0; - } - - /* Set up a vertex structure for rendering. */ - - struct {float u, v, x, y, z;} *vertices; - const uint32_t vertex_type = GU_TEXTURE_32BITF | GU_VERTEX_32BITF; - - /* Draw the sky (flat) portion of the background. We overdraw by one - * pixel in each direction to avoid the possibility of undrawn pixels - * along the switch (horizon) line, since the ground coordinates are - * adjusted by the Z factor and may end up slightly different from the - * original values in the coord[] array. */ - - if (has_sky && nverts[sky_coord_set] > 0) { - - vertices = guGetMemory(sizeof(*vertices) * nverts[sky_coord_set]); - unsigned int i; - for (i = 0; i < nverts[sky_coord_set]; i++) { - vertices[i].x = - coord[sky_coord_set][i].x + coord[sky_coord_set][i].overdraw_x; - vertices[i].y = - coord[sky_coord_set][i].y + coord[sky_coord_set][i].overdraw_y; - vertices[i].z = 0; - Azel_transform_coordinates(vertices[i].x, vertices[i].y, - &vertices[i].u, &vertices[i].v, - sky_M, sky_kx, sky_ky, sky_Xp, sky_Yp); - /* We deliberately shift the "sky" portion 2 pixels in the - * overdraw direction because there are occasionally - * transparent gaps where the background color shows through - * (e.g. 禁止区域). */ - if (UL_is_sky || UR_is_sky) { - vertices[i].v -= 2; - } else { - vertices[i].v += 2; - } - } - - guClutMode(GU_PSM_8888, 0, 255, 0); - guClutLoad(32, sky_clut); - guTexMode(GU_PSM_T8, 0, 0, 1); - guTexImage(0, 512, 512, 512, Azel_sky_cache); - guTexWrap(GU_REPEAT, Azel_sky_wrap_v ? GU_REPEAT : GU_CLAMP); - guTexFlush(); - guDrawArray(GU_TRIANGLE_STRIP, GU_TRANSFORM_2D | vertex_type, - nverts[sky_coord_set], NULL, vertices); - - } // if (nverts[sky_coord_set] > 0) - - /* Draw the ground (scaled) portion of the background. The scale - * factors in the coefficient table are essentially distance (Z) - * values, so we set up a projection matrix that allows us to draw - * a small number of 3D triangles instead of rendering each line - * individually. For ease of coordinate handling, the projection - * matrix maps 3D coordinate (x,y,1) directly to screen coordinate - * (x+disp_width/2,y+disp_height/2). */ - - guClutMode(GU_PSM_8888, 0, 255, 0); - guClutLoad(32, ground_clut); - guTexMode(GU_PSM_T8, 0, 0, 1); - if ((Vdp2Regs->PLSZ>>10 & 3) == 0) { - guTexWrap(GU_REPEAT, GU_REPEAT); - } else { - guTexWrap(GU_CLAMP, GU_CLAMP); - } - - float Mproj[4][4]; - Mproj[0][0] = 2.0f / disp_width; - Mproj[0][1] = 0; - Mproj[0][2] = 0; - Mproj[0][3] = 0; - Mproj[1][0] = 0; - Mproj[1][1] = -2.0f / disp_height; - Mproj[1][2] = 0; - Mproj[1][3] = 0; - Mproj[2][0] = 0; - Mproj[2][1] = 0; - Mproj[2][2] = 1.0f / 128; // Coefficient value range is [0,128). - Mproj[2][3] = 1; - Mproj[3][0] = 0; - Mproj[3][1] = 0; - Mproj[3][2] = 0; - Mproj[3][3] = 0; - guSetMatrix(GU_PROJECTION, &Mproj[0][0]); - - if (nverts[ground_coord_set] == 0) { - - /* Nothing to do. */ - - } else if (ground_is_zero) { - - /* Degenerate case: ground coefficients are all zero. This - * should only happen while changing scenes, so we don't bother - * drawing anything. */ - - } else if (coef_switch_index == last_coef_index) { - - /* Degenerate case: only one ground coefficient (we also come here - * if we detect a slope of zero). We can't compute appropriate 3D - * coordinates for this case, but since it's effectively flat like - * the sky, just draw it that way. */ - - draw_as_flat:; - const int32_t data = READ_COEF(coef_switch_index); - const float kx = data / 65536.0f; - const float ky = kx; - - vertices = guGetMemory(sizeof(*vertices) * nverts[ground_coord_set]); - unsigned int i; - for (i = 0; i < nverts[ground_coord_set]; i++) { - vertices[i].x = coord[ground_coord_set][i].x; - vertices[i].y = coord[ground_coord_set][i].y; - vertices[i].z = 0; - Azel_transform_coordinates(vertices[i].x, vertices[i].y, - &vertices[i].u, &vertices[i].v, - ground_M, kx, ky, ground_Xp, ground_Yp); - } - if (kx >= 6.0f) { - guTexImage(0, 64, 64, 64, - Azel_ground_cache + 512*512 + 256*256 + 128*128); - } else if (kx >= 3.0f) { - guTexImage(0, 128, 128, 128, Azel_ground_cache + 512*512 + 256*256); - } else if (kx >= 1.5f) { - guTexImage(0, 256, 256, 256, Azel_ground_cache + 512*512); - } else { - guTexImage(0, 512, 512, 512, Azel_ground_cache); - } - guTexFlush(); - guDrawArray(GU_TRIANGLE_STRIP, GU_TRANSFORM_2D | vertex_type, - nverts[ground_coord_set], NULL, vertices); - - } else { - - /* Determine the indices of the first and last ground coefficients. */ - - uint32_t first_ground_index, last_ground_index; - if ((uint32_t)READ_COEF(first_coef_index) < 0x800000) { - first_ground_index = first_coef_index; - if (has_switch) { - last_ground_index = coef_switch_index - 1; - } else { - last_ground_index = last_coef_index; - } - } else { - first_ground_index = coef_switch_index; - last_ground_index = last_coef_index; - } - - /* Compute the approximate plane slope from the average of the - * slopes from the first coefficient to all other coefficients. - * (For certain "ground" textures, like water, the actual - * coefficients are modulated by a small amount to produce a - * "shimmering" effect, so they won't give a single, consistent - * result from one coefficient to the next; thus we take the - * average and use that instead.) - * - * If we have a hint from the satopt-sh2.c optimizer, we use that - * instead; however, it seems to be delayed by a frame, so we use - * a local static variable to accomplish the same thing. */ - - static float slope_hint_delayed = SLOPE_UNSET; - static float first_recip_hint_delayed; - const float slope_hint = slope_hint_delayed; - const float first_recip_hint = first_recip_hint_delayed; - slope_hint_delayed = psp_video_tweaks_Azel_RBG0_slope; - first_recip_hint_delayed = psp_video_tweaks_Azel_RBG0_first_recip; - - float slope = 0; - const int32_t first_data = READ_COEF(first_ground_index); - float first_recip; - if (slope_hint != SLOPE_UNSET && slope_hint_delayed != SLOPE_UNSET) { - slope = slope_hint; - first_recip = first_recip_hint; - if (slope != 0) { - /* This may be slightly off (e.g. due to an out-of-range - * coefficient), so adjust as necessary. */ - float diff; - if (slope > 0) { - diff = first_recip - 65536.0f/first_data; - } else { - const float last_recip = - first_recip + slope * (last_ground_index - first_ground_index); - const float recip_test = - 65536.0f / READ_COEF(last_ground_index); - diff = last_recip - recip_test; - } - if (fabsf(diff) > (slope/2)) { - first_recip -= roundf(diff / fabsf(slope)) * fabsf(slope); - } - } - } else { - first_recip = 65536.0f / first_data; - uint32_t i; - for (i = first_ground_index + 1; i <= last_ground_index; i++) { - const int32_t data = READ_COEF(i); - const float recip = 65536.0f / data; - slope += (recip - first_recip) / (i - first_ground_index); - } - slope /= last_ground_index - first_ground_index; - } - - if (slope == 0) { // Avoid division by zero below. - goto draw_as_flat; - } - - /* Go over the coefficient list and find the variance from the - * linear slope we just derived, to determine whether or not we - * need to apply our own "shimmering" effect. */ - - float variance = 0; - uint32_t index; - for (index = first_ground_index; index <= last_ground_index; index++) { - const int32_t data = READ_COEF(index); - const float recip = 65536.0f / data; - const float expected = - first_recip + slope * (index - first_ground_index); - const float error = (recip - expected) / slope; - variance += error * error; - } - variance /= last_ground_index - first_ground_index + 1; - const int do_shimmer = (variance > 0.01f); - const float shimmer_step = - (sceKernelGetSystemTimeLow() & 0x7FFFFF) / (float)0x800000; - - /* If the entire screen is "ground" and the slope is positive, - * move the switch line to the top of the screen so we draw - * the proper portion as mipmapped. */ - - if (switch_y0 == disp_height && slope > 0) { - switch_y0 = switch_y1 = 0; - } - - /* If the ground plane needs to be split into separate mipmapped - * and normal regions, first draw the distant (mipmapped) part of - * the plane. - * FIXME: This section is making me nauseous, which is a sign that - * it's poorly written and desperately needs refactoring--or perhaps - * a complete rethinking... - */ - - index = (slope > 0) ? first_ground_index : last_ground_index + 1; - int32_t mipmap_scale; - for (mipmap_scale = 8; - mipmap_scale > 1 && (slope > 0 ? index <= last_ground_index - : index > first_ground_index); - mipmap_scale /= 2 - ) { - - /* Find the index of the coefficient at which the mipmap scale - * switches. We normally use mipmaps only at scales above the - * mipmap's level, but we're more aggressive about using - * mipmaps in water areas because we need the speed in Uru. */ - - const float mipmap_scale_recip = - (do_shimmer ? 2.0f : 1.0f) / mipmap_scale; - const int32_t mipmap_switch_offset = - iceilf((mipmap_scale_recip - first_recip) / slope); - if (mipmap_switch_offset < 0) { - continue; - } - uint32_t mipmap_switch_index = - first_ground_index + mipmap_switch_offset; - if (mipmap_switch_index > last_ground_index + 1) { - mipmap_switch_index = last_ground_index + 1; - } - if (slope > 0) { - /* If there's only a small section to draw for this mipmap - * level, skip this iteration and draw it as part of the - * next, since we'll probably get better use of the GE's - * texture cache that way. */ - if (mipmap_switch_index <= index + 4) { - continue; - } - /* If we've covered the entire region with this mipmap - * level--or if this would leave only a small amount to - * draw with the next level, which again would make poor - * use of the texture cache, break out of the loop and let - * the last pass handle it with the already-computed - * vertices. Note that we explicitly don't update "index" - * in this case so the last pass is not skipped. */ - if (mipmap_switch_index > last_ground_index - 4) { - break; - } - } else { // slope < 0 - if (mipmap_switch_index >= index - 4) { - continue; - } - if (index <= first_ground_index + 4) { - index--; - } - } - index = mipmap_switch_index; // Save it for next time around. - - /* Compute switch line coordinates for the mipmap line. */ - - int mipmap_x0, mipmap_y0, mipmap_x1, mipmap_y1; - Azel_compute_switch(coef_base, mipmap_switch_index, coef_index_UL, - coef_index_UR, coef_index_LL, coef_index_LR, - coef_dx, coef_dy, &mipmap_x0, &mipmap_y0, - &mipmap_x1, &mipmap_y1); - - /* Compute vertices for the mipmapped region. This is a - * rectangle if the horizon line is horizontal or vertical, but - * may be a four-, five-, or six-sided polygon if the horizon - * is tilted. */ - - struct {int x, y;} mipmap_coords[6]; - unsigned int mipmap_nverts; - if (coef_dx == 0 || coef_dy == 0) { - mipmap_coords[0].x = switch_x0; - mipmap_coords[0].y = switch_y0; - mipmap_coords[1].x = switch_x1; - mipmap_coords[1].y = switch_y1; - mipmap_coords[2].x = mipmap_x0; - mipmap_coords[2].y = mipmap_y0; - mipmap_coords[3].x = mipmap_x1; - mipmap_coords[3].y = mipmap_y1; - mipmap_nverts = 4; - } else { - /* First determine which line is on top (has smaller - * Y coordinates), to simplify computations. We make use - * of the knowledge that Azel_compute_switch() assigns - * coordinates in the preference order top > left > right - * > bottom edge. Also swap the lower line's coordinates - * if necessary so they are in the same order as the upper - * line; depending on the position of the lines, the - * preference order may result in coordinates being - * swapped. */ - int switch_is_top, invert_second; - if (switch_y0 == 0) { - if (mipmap_y0 != 0) { - switch_is_top = 1; - invert_second = (switch_x1 < switch_x0 - && mipmap_x0 == 0); - } else if (switch_x1 < switch_x0) { - switch_is_top = (switch_x0 < mipmap_x0); - invert_second = 0; - } else { - switch_is_top = (switch_x0 > mipmap_x0); - invert_second = 0; - } - } else if (mipmap_y0 == 0) { - switch_is_top = 0; - invert_second = (mipmap_x1 < mipmap_x0 - && switch_x0 == 0); - } else if (switch_x0 == mipmap_x0) { - switch_is_top = (switch_y0 < mipmap_y0); - invert_second = 0; - } else { - /* One line connects the left and right edges, while - * the other runs from the right edge to the bottom. - * The line connecting the left and right edges is on - * top, and the coordinate order is switched. */ - switch_is_top = (switch_x0 == 0); - invert_second = 1; - } - const int x0 = switch_is_top ? switch_x0 : mipmap_x0; - const int y0 = switch_is_top ? switch_y0 : mipmap_y0; - const int x1 = switch_is_top ? switch_x1 : mipmap_x1; - const int y1 = switch_is_top ? switch_y1 : mipmap_y1; - const int x2 = (invert_second - ? (switch_is_top ? mipmap_x1 : switch_x1) - : (switch_is_top ? mipmap_x0 : switch_x0)); - const int y2 = (invert_second - ? (switch_is_top ? mipmap_y1 : switch_y1) - : (switch_is_top ? mipmap_y0 : switch_y0)); - const int x3 = (invert_second - ? (switch_is_top ? mipmap_x0 : switch_x0) - : (switch_is_top ? mipmap_x1 : switch_x1)); - const int y3 = (invert_second - ? (switch_is_top ? mipmap_y0 : switch_y0) - : (switch_is_top ? mipmap_y1 : switch_y1)); - /* The first two vertices are always the endpoints of the - * top line. Depending on where the region is located on - * the screen, one or two corners may also be included; we - * insert either a corner or an endpoint of the lower line - * as vertices 2 and 3, then add any remaining endpoints as - * vertices 4 and 5 if necessary. */ - mipmap_nverts = 4; - mipmap_coords[0].x = x0; - mipmap_coords[0].y = y0; - mipmap_coords[1].x = x1; - mipmap_coords[1].y = y1; - if ((y0 == 0 && x0 != 0 && x0 != disp_width) && y2 != 0) { - /* Region includes the upper-left or upper-right corner. */ - mipmap_coords[2].y = 0; - if (x2 == 0) { - mipmap_coords[2].x = 0; - } else { - mipmap_coords[2].x = disp_width; - } - mipmap_coords[mipmap_nverts].x = x2; - mipmap_coords[mipmap_nverts].y = y2; - mipmap_nverts++; - if (x1 == 0 && y1 != disp_height && x3 != 0) { - /* Region also includes the lower-left corner. */ - mipmap_coords[3].x = 0; - mipmap_coords[3].y = disp_height; - mipmap_coords[mipmap_nverts].x = x3; - mipmap_coords[mipmap_nverts].y = y3; - mipmap_nverts++; - } else if (x1 == disp_width && y1 != disp_height - && x3 != disp_width) { - /* Region also includes the lower-right corner. */ - mipmap_coords[3].x = disp_width; - mipmap_coords[3].y = disp_height; - mipmap_coords[mipmap_nverts].x = x3; - mipmap_coords[mipmap_nverts].y = y3; - mipmap_nverts++; - } else { - mipmap_coords[3].x = x3; - mipmap_coords[3].y = y3; - } - } else if ((x0 == 0 && y0 != 0 && y0 != disp_height) && x2 != 0) { - /* Region includes the lower-left corner. (In this - * case, the top line slants up-and-right and ends on - * the right edge of the screen.) */ - mipmap_coords[2].x = 0; - mipmap_coords[2].y = disp_height; - mipmap_coords[mipmap_nverts].x = x2; - mipmap_coords[mipmap_nverts].y = y2; - mipmap_nverts++; - mipmap_coords[3].x = x3; - mipmap_coords[3].y = y3; - } else { - /* Endpoint 0 of the horizon and mipmap lines are on - * the same edge of the screen. */ - mipmap_coords[2].x = x2; - mipmap_coords[2].y = y2; - if ((y0 == 0 || x0 == disp_width) - && (x1 == 0 && y1 != disp_height) - && x3 != 0 - ) { - /* Region includes the lower-left corner. */ - mipmap_coords[3].x = 0; - mipmap_coords[3].y = disp_height; - mipmap_coords[mipmap_nverts].x = x3; - mipmap_coords[mipmap_nverts].y = y3; - mipmap_nverts++; - } else if ((y0 == 0 || x0 == 0) - && (x1 == disp_width && y1 != disp_height) - && x3 != disp_width - ) { - /* Region includes the lower-right corner. */ - mipmap_coords[3].x = disp_width; - mipmap_coords[3].y = disp_height; - mipmap_coords[mipmap_nverts].x = x3; - mipmap_coords[mipmap_nverts].y = y3; - mipmap_nverts++; - } else { - mipmap_coords[3].x = x3; - mipmap_coords[3].y = y3; - } - } - } - - /* Draw the mipmapped region computed above. */ - - vertices = guGetMemory(sizeof(*vertices) * mipmap_nverts); - unsigned int i; - for (i = 0; i < mipmap_nverts; i++) { - vertices[i].x = mipmap_coords[i].x; - vertices[i].y = mipmap_coords[i].y; - const float coef_offset = coef_base - + vertices[i].x * coef_dx - + vertices[i].y * coef_dy - - first_ground_index; - vertices[i].z = - 1 / MAX(first_recip + coef_offset * slope, 1/127.5f); - Azel_transform_coordinates(vertices[i].x, vertices[i].y, - &vertices[i].u, &vertices[i].v, - ground_M, - vertices[i].z, vertices[i].z, - ground_Xp, ground_Yp); - vertices[i].u /= 512; - vertices[i].v /= 512; - if (do_shimmer) { - vertices[i].v += 0.01f * sinf(shimmer_step * (2*(float)M_PI)); - } - vertices[i].x = (vertices[i].x - disp_width/2) * vertices[i].z; - vertices[i].y = (vertices[i].y - disp_height/2) * vertices[i].z; - } - const unsigned int texture_size = 512 / mipmap_scale; - const uint8_t *texture_data = Azel_ground_cache; - for (i = 512; i > texture_size; i /= 2) { - texture_data += i * i; - } - guTexImage(0, texture_size, texture_size, texture_size, - texture_data); - guTexFlush(); - guDrawArray(GU_TRIANGLE_STRIP, GU_TRANSFORM_3D | vertex_type, - mipmap_nverts, NULL, vertices); - - /* Recompute the vertex sets based on the mipmap line, so the - * final render iteration (with the full-size ground texture) - * skips the part we just drew. Since Azel_compute_vertices() - * uses the *_is_sky variables to determine whether the top or - * bottom portion is "ground", we need to tweak those variables - * in case the entire screen is "ground" so we get the proper - * region registered. Note that we don't check the actual - * coefficients, because that may give incorrect results due to - * the "shimmering" effect; instead, we compare the coefficient - * indices to the mipmap switch index. */ - - int UL_sky_2, UR_sky_2, LL_sky_2, LR_sky_2; - if (slope > 0) { - UL_sky_2 = (coef_index_UL < mipmap_switch_index); - UR_sky_2 = (coef_index_UR < mipmap_switch_index); - LL_sky_2 = (coef_index_LL < mipmap_switch_index); - LR_sky_2 = (coef_index_LR < mipmap_switch_index); - } else { - UL_sky_2 = (coef_index_UL >= mipmap_switch_index); - UR_sky_2 = (coef_index_UR >= mipmap_switch_index); - LL_sky_2 = (coef_index_LL >= mipmap_switch_index); - LR_sky_2 = (coef_index_LR >= mipmap_switch_index); - } - Azel_compute_vertices(UL_sky_2, UR_sky_2, LL_sky_2, LR_sky_2, - mipmap_x0, mipmap_y0, mipmap_x1, mipmap_y1, - coord, nverts); - ground_coord_set = (UL_sky_2 ? 1 : 0); - - /* Copy the mipmap line coordinates to switch_* for the next - * mipmap loop. */ - - switch_x0 = mipmap_x0; - switch_y0 = mipmap_y0; - switch_x1 = mipmap_x1; - switch_y1 = mipmap_y1; - - } // if using mipmap - - /* Generate and render vertices for the lowest-scale portion of the - * the plane, if any. */ - - if (slope > 0 ? index <= last_ground_index - : index > first_ground_index) { - vertices = guGetMemory(sizeof(*vertices) * nverts[ground_coord_set]); - unsigned int i; - for (i = 0; i < nverts[ground_coord_set]; i++) { - vertices[i].x = coord[ground_coord_set][i].x; - vertices[i].y = coord[ground_coord_set][i].y; - const float coef_offset = coef_base - + vertices[i].x * coef_dx - + vertices[i].y * coef_dy - - first_ground_index; - vertices[i].z = - 1 / MAX(first_recip + coef_offset * slope, 1/127.5f); - Azel_transform_coordinates(vertices[i].x, vertices[i].y, - &vertices[i].u, &vertices[i].v, - ground_M, - vertices[i].z, vertices[i].z, - ground_Xp, ground_Yp); - vertices[i].u /= (Azel_ground_reduced ? 1024 : 512); - vertices[i].v /= (Azel_ground_reduced ? 1024 : 512); - if (do_shimmer) { - /* Fake the "shimmering" effect with a simple sinusoidal - * offset. The PSP doesn't have enough hardware operators - * to do what we really want (which is multiply each - * texture coordinate by a*sin(b*y/z), where a and b are - * constants). */ - vertices[i].v += 0.01f * sinf(shimmer_step * (2*(float)M_PI)); - } - vertices[i].x = (vertices[i].x - disp_width/2) * vertices[i].z; - vertices[i].y = (vertices[i].y - disp_height/2) * vertices[i].z; - } - const unsigned int texture_size = 512 / mipmap_scale; - const uint8_t *texture_data = Azel_ground_cache; - for (i = 512; i > texture_size; i /= 2) { - texture_data += i * i; - } - guTexImage(0, texture_size, texture_size, texture_size, - texture_data); - guTexFlush(); - guDrawArray(GU_TRIANGLE_STRIP, GU_TRANSFORM_3D | vertex_type, - nverts[ground_coord_set], NULL, vertices); - } - - } // if (ground_min == ground_max) - - /* All done. Make sure to reset the wrapping flags since other code - * will expect wraparound to be disabled. */ - - guTexWrap(GU_CLAMP, GU_CLAMP); - return 1; - - #undef READ_COEF -} - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_get_rotation_matrix: Calculate the rotation matrix and scaling - * parameters for a sky or ground parameter set. Helper function for - * Azel_draw_RBG0(). - * - * [Parameters] - * address: Address of parameter set in VDP2 RAM - * M: Pointer to 2x3 array to receive rotation matrix values - * kx_ret: Pointer to variable to receive X scale value (NULL allowed) - * ky_ret: Pointer to variable to receive Y scale value (NULL allowed) - * Xp_ret: Pointer to variable to receive X offset value - * Yp_ret: Pointer to variable to receive Y offset value - * [Return value] - * None - */ -static void Azel_get_rotation_matrix(uint32_t address, float M[2][3], - float *kx_ret, float *ky_ret, - float *Xp_ret, float *Yp_ret) -{ - /* The GET_* macros are borrowed from psp-video-rotate.c. */ - - #define GET_SHORT(nbits) \ - (address += 2, (int32_t)((int16_t)T1ReadWord(Vdp2Ram,address-2) \ - << (16-nbits)) >> (16-nbits)) - #define GET_SIGNED_FLOAT(nbits) \ - (address += 4, ((((int32_t)T1ReadLong(Vdp2Ram,address-4) \ - << (32-nbits)) >> (32-nbits)) & ~0x3F) / 65536.0f) - #define GET_UNSIGNED_FLOAT(nbits) \ - (address += 4, (((uint32_t)T1ReadLong(Vdp2Ram,address-4) \ - & (0xFFFFFFFFU >> (32-nbits))) & ~0x3F) / 65536.0f) - - const float Xst = GET_SIGNED_FLOAT(29); - const float Yst = GET_SIGNED_FLOAT(29); - const float Zst = GET_SIGNED_FLOAT(29); - const float deltaXst = GET_SIGNED_FLOAT(19); - const float deltaYst = GET_SIGNED_FLOAT(19); - const float deltaX = GET_SIGNED_FLOAT(19); - const float deltaY = GET_SIGNED_FLOAT(19); - const float A = GET_SIGNED_FLOAT(20); - const float B = GET_SIGNED_FLOAT(20); - const float C = GET_SIGNED_FLOAT(20); - const float D = GET_SIGNED_FLOAT(20); - const float E = GET_SIGNED_FLOAT(20); - const float F = GET_SIGNED_FLOAT(20); - const float Px = GET_SHORT(14); - const float Py = GET_SHORT(14); - const float Pz = GET_SHORT(14); - address += 2; - const float Cx = GET_SHORT(14); - const float Cy = GET_SHORT(14); - const float Cz = GET_SHORT(14); - address += 2; - const float Mx = GET_SIGNED_FLOAT(30); - const float My = GET_SIGNED_FLOAT(30); - const float kx = GET_SIGNED_FLOAT(24); - const float ky = GET_SIGNED_FLOAT(24); - - #undef GET_SHORT - #undef GET_SIGNED_FLOAT - #undef GET_UNSIGNED_FLOAT - - M[0][0] = (A * deltaX) + (B * deltaY); - M[0][1] = (A * deltaXst) + (B * deltaYst); - M[0][2] = (A * (Xst - Px)) + (B * (Yst - Py)) + (C * (Zst - Pz)); - M[1][0] = (D * deltaX) + (E * deltaY); - M[1][1] = (D * deltaXst) + (E * deltaYst); - M[1][2] = (D * (Xst - Px)) + (E * (Yst - Py)) + (F * (Zst - Pz)); - *Xp_ret = (A * (Px - Cx)) + (B * (Py - Cy)) + (C * (Pz - Cz)) + Cx + Mx; - *Yp_ret = (D * (Px - Cx)) + (E * (Py - Cy)) + (F * (Pz - Cz)) + Cy + My; - - if (kx_ret) { - *kx_ret = kx; - } - if (ky_ret) { - *ky_ret = ky; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_transform_coordinates: Transform screen to texture coordinates - * given the rotation matrix and scaling parameters for a sky or ground - * parameter set. Helper function for Azel_draw_RBG0(). - * - * [Parameters] - * x, y: Screen coordinates to transform - * u_ret, v_ret: Pointers to variables to receive transformed coordinates - * M: Pointer to 2x3 array containing rotation matrix values - * kx, ky: X/Y scale values - * Xp, Yp: X/Y offset values - * [Return value] - * None - */ -static void Azel_transform_coordinates(const float x, const float y, - float *u_ret, float *v_ret, - float M[2][3], - const float kx, const float ky, - const float Xp, const float Yp) -{ - *u_ret = (M[0][0]*x + M[0][1]*y + M[0][2]) * kx + Xp; - *v_ret = (M[1][0]*x + M[1][1]*y + M[1][2]) * ky + Yp; -} - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_compute_switch: Compute the endpoints of the switch (horizon) line - * between sky and ground. Helper function for Azel_draw_RBG0(). - * - * [Parameters] - * All parameters are local variables or pointers thereto passed from - * Azel_draw_RBG0() - * [Return value] - * None - */ -static inline void Azel_compute_switch( - uint32_t coef_base, uint32_t coef_switch_index, - const uint32_t coef_index_UL, const uint32_t coef_index_UR, - const uint32_t coef_index_LL, const uint32_t coef_index_LR, - float coef_dx, float coef_dy, - int *switch_x0, int *switch_y0, int *switch_x1, int *switch_y1) -{ - *switch_x0 = *switch_y0 = *switch_x1 = *switch_y1 = -1; - - if (coef_dx == 0) { - - *switch_x0 = 0; - *switch_y0 = iceilf((coef_switch_index - coef_base) / coef_dy); - *switch_x1 = disp_width; - *switch_y1 = *switch_y0; - - } else if (coef_dy == 0) { - - *switch_x0 = iceilf((coef_switch_index - coef_base) / coef_dx); - *switch_y0 = 0; - *switch_x1 = *switch_x0; - *switch_y1 = disp_height; - - } else { // coef_dx != 0 && coef_dy != 0 - - const float top_x = - (int32_t)(coef_switch_index - coef_index_UL) / coef_dx; - if (top_x > -1 && top_x <= disp_width) { - *switch_x0 = iceilf(top_x); - *switch_y0 = 0; - } - const float bottom_x = - (int32_t)(coef_switch_index - coef_index_LL) / coef_dx; - if (bottom_x > -1 && bottom_x <= disp_width) { - *switch_x1 = iceilf(bottom_x); - *switch_y1 = disp_height; - } - const float left_y = - (int32_t)(coef_switch_index - coef_index_UL) / coef_dy; - if (left_y > -1 && left_y <= disp_height) { - if (*switch_x0 < 0) { - *switch_x0 = 0; - *switch_y0 = iceilf(left_y); - } else if (*switch_x1 < 0) { - *switch_x1 = 0; - *switch_y1 = iceilf(left_y); - } - } - const float right_y = - (int32_t)(coef_switch_index - coef_index_UR) / coef_dy; - if (right_y > -1 && right_y <= disp_height) { - if (*switch_x0 < 0) { - *switch_x0 = disp_width; - *switch_y0 = iceilf(right_y); - } else if (*switch_x1 < 0) { - *switch_x1 = disp_width; - *switch_y1 = iceilf(right_y); - } - } - - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * Azel_compute_vertices: Compute the two sets of vertices for drawing - * sky and ground sections of an RBG0 layer. Helper function for - * Azel_draw_RBG0(). - * - * [Parameters] - * All parameters are local variables/arrays passed from Azel_draw_RBG0() - * [Return value] - * None - */ -static inline void Azel_compute_vertices( - int UL_is_sky, int UR_is_sky, int LL_is_sky, int LR_is_sky, - int switch_x0, int switch_y0, int switch_x1, int switch_y1, - struct Azel_RBG0_coord coord[2][5], unsigned int nverts[2]) -{ - coord[0][0].x = 0; - coord[0][0].y = 0; - coord[0][0].overdraw_x = -1; - coord[0][0].overdraw_y = -1; - - if (UR_is_sky == UL_is_sky) { - - coord[0][1].x = disp_width; - coord[0][1].y = 0; - coord[0][1].overdraw_x = +1; - coord[0][1].overdraw_y = -1; - - if (LL_is_sky == LR_is_sky) { - - coord[0][2].x = switch_x0; - coord[0][2].y = switch_y0; - coord[0][2].overdraw_x = -1; - coord[0][2].overdraw_y = +1; - coord[0][3].x = switch_x1; - coord[0][3].y = switch_y1; - coord[0][3].overdraw_x = +1; - coord[0][3].overdraw_y = +1; - nverts[0] = 4; - - if (LL_is_sky == UL_is_sky) { - nverts[1] = 0; - } else { - coord[1][0].x = switch_x0; - coord[1][0].y = switch_y0; - coord[1][0].overdraw_x = -1; - coord[1][0].overdraw_y = -1; - coord[1][1].x = switch_x1; - coord[1][1].y = switch_y1; - coord[1][1].overdraw_x = +1; - coord[1][1].overdraw_y = -1; - coord[1][2].x = 0; - coord[1][2].y = disp_height; - coord[1][2].overdraw_x = -1; - coord[1][2].overdraw_y = +1; - coord[1][3].x = disp_width; - coord[1][3].y = disp_height; - coord[1][3].overdraw_x = +1; - coord[1][3].overdraw_y = +1; - nverts[1] = 4; - } - - } else if (LL_is_sky == UL_is_sky) { - - coord[0][2].x = 0; - coord[0][2].y = disp_height; - coord[0][2].overdraw_x = -1; - coord[0][2].overdraw_y = +1; - coord[0][3].x = switch_x0; - coord[0][3].y = switch_y0; - coord[0][3].overdraw_x = +1; - coord[0][3].overdraw_y = +1; - coord[0][4].x = switch_x1; - coord[0][4].y = switch_y1; - coord[0][4].overdraw_x = +1; - coord[0][4].overdraw_y = +1; - nverts[0] = 5; - - coord[1][0].x = switch_x0; - coord[1][0].y = switch_y0; - coord[1][0].overdraw_x = +1; - coord[1][0].overdraw_y = -1; - coord[1][1].x = switch_x1; - coord[1][1].y = switch_y1; - coord[1][1].overdraw_x = -1; - coord[1][1].overdraw_y = +1; - coord[1][2].x = disp_width; - coord[1][2].y = disp_height; - coord[1][3].overdraw_x = +1; - coord[1][3].overdraw_y = +1; - nverts[1] = 3; - - } else { // LR_is_sky == UL_is_sky - - coord[0][2].x = switch_x0; - coord[0][2].y = switch_y0; - coord[0][2].overdraw_x = -1; - coord[0][2].overdraw_y = +1; - coord[0][3].x = disp_width; - coord[0][3].y = disp_height; - coord[0][3].overdraw_x = +1; - coord[0][3].overdraw_y = +1; - coord[0][4].x = switch_x1; - coord[0][4].y = switch_y1; - coord[0][4].overdraw_x = -1; - coord[0][4].overdraw_y = +1; - nverts[0] = 5; - - coord[1][0].x = switch_x0; - coord[1][0].y = switch_y0; - coord[1][0].overdraw_x = -1; - coord[1][0].overdraw_y = -1; - coord[1][1].x = switch_x1; - coord[1][1].y = switch_y1; - coord[1][1].overdraw_x = +1; - coord[1][1].overdraw_y = +1; - coord[1][2].x = 0; - coord[1][2].y = disp_height; - coord[1][2].overdraw_x = -1; - coord[1][2].overdraw_y = +1; - nverts[1] = 3; - - } - - } else if (LL_is_sky == UL_is_sky) { - - coord[0][1].x = 0; - coord[0][1].y = disp_height; - coord[0][1].overdraw_x = -1; - coord[0][1].overdraw_y = +1; - - if (LR_is_sky != UL_is_sky) { - - coord[0][2].x = switch_x0; - coord[0][2].y = switch_y0; - coord[0][2].overdraw_x = +1; - coord[0][2].overdraw_y = -1; - coord[0][3].x = switch_x1; - coord[0][3].y = switch_y1; - coord[0][3].overdraw_x = +1; - coord[0][3].overdraw_y = +1; - nverts[0] = 4; - - coord[1][0].x = switch_x0; - coord[1][0].y = switch_y0; - coord[1][0].overdraw_x = -1; - coord[1][0].overdraw_y = -1; - coord[1][1].x = switch_x1; - coord[1][1].y = switch_y1; - coord[1][1].overdraw_x = -1; - coord[1][1].overdraw_y = +1; - coord[1][2].x = disp_width; - coord[1][2].y = 0; - coord[1][2].overdraw_x = +1; - coord[1][2].overdraw_y = -1; - coord[1][3].x = disp_width; - coord[1][3].y = disp_height; - coord[1][3].overdraw_x = +1; - coord[1][3].overdraw_y = +1; - nverts[1] = 4; - - } else { // LR_is_sky == UL_is_sky - - coord[0][2].x = switch_x0; - coord[0][2].y = switch_y0; - coord[0][2].overdraw_x = +1; - coord[0][2].overdraw_y = -1; - coord[0][3].x = disp_width; - coord[0][3].y = disp_height; - coord[0][3].overdraw_x = +1; - coord[0][3].overdraw_y = +1; - coord[0][4].x = switch_x1; - coord[0][4].y = switch_y1; - coord[0][4].overdraw_x = +1; - coord[0][4].overdraw_y = -1; - nverts[0] = 5; - - coord[1][0].x = switch_x0; - coord[1][0].y = switch_y0; - coord[1][0].overdraw_x = -1; - coord[1][0].overdraw_y = -1; - coord[1][1].x = switch_x1; - coord[1][1].y = switch_y1; - coord[1][1].overdraw_x = +1; - coord[1][1].overdraw_y = +1; - coord[1][2].x = disp_width; - coord[1][2].y = 0; - coord[1][2].overdraw_x = +1; - coord[1][2].overdraw_y = -1; - nverts[1] = 3; - - } - - } else { - - coord[0][1].x = switch_x0; - coord[0][1].y = switch_y0; - coord[0][1].overdraw_x = +1; - coord[0][1].overdraw_y = -1; - coord[0][2].x = switch_x1; - coord[0][2].y = switch_y1; - coord[0][2].overdraw_x = -1; - coord[0][2].overdraw_y = +1; - nverts[0] = 3; - - coord[1][0].x = switch_x0; - coord[1][0].y = switch_y0; - coord[1][0].overdraw_x = -1; - coord[1][0].overdraw_y = -1; - coord[1][1].x = disp_width; - coord[1][1].y = 0; - coord[1][1].overdraw_x = +1; - coord[1][1].overdraw_y = -1; - coord[1][2].x = switch_x1; - coord[1][2].y = switch_y1; - coord[1][2].overdraw_x = -1; - coord[1][2].overdraw_y = -1; - coord[1][3].x = disp_width; - coord[1][3].y = disp_height; - coord[1][3].overdraw_x = +1; - coord[1][3].overdraw_y = +1; - coord[1][4].x = 0; - coord[1][4].y = disp_height; - coord[1][4].overdraw_x = -1; - coord[1][4].overdraw_y = +1; - nverts[1] = 5; - - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-video.c b/yabause/src/psp/psp-video.c deleted file mode 100644 index de30aaa4e3..0000000000 --- a/yabause/src/psp/psp-video.c +++ /dev/null @@ -1,2160 +0,0 @@ -/* src/psp/psp-video.c: PSP video interface module - Copyright 2009-2010 Andrew Church - Based on src/vidogl.c by Guillaume Duhamel and others - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../vdp1.h" -#include "../vdp2.h" -#include "../vidshared.h" - -#include "config.h" -#include "display.h" -#include "font.h" -#include "gu.h" -#include "misc.h" -#include "psp-video.h" -#include "psp-video-internal.h" -#include "texcache.h" -#include "timing.h" - -/*************************************************************************/ -/************************* Interface definition **************************/ -/*************************************************************************/ - -/* Interface function declarations (must come before interface definition) */ - -static int psp_video_init(void); -static void psp_video_deinit(void); -static void psp_video_resize(unsigned int width, unsigned int height, - int fullscreen); -static int psp_video_is_fullscreen(void); -static void psp_video_debug_message(char *format, ...); - -static int psp_vdp1_reset(void); -static void psp_vdp1_draw_start(void); -static void psp_vdp1_draw_end(void); -static void psp_vdp1_normal_sprite_draw(void); -static void psp_vdp1_scaled_sprite_draw(void); -static void psp_vdp1_distorted_sprite_draw(void); -static void psp_vdp1_polygon_draw(void); -static void psp_vdp1_polyline_draw(void); -static void psp_vdp1_line_draw(void); -static void psp_vdp1_user_clipping(void); -static void psp_vdp1_system_clipping(void); -static void psp_vdp1_local_coordinate(void); - -static int psp_vdp2_reset(void); -static void psp_vdp2_draw_start(void); -static void psp_vdp2_draw_end(void); -static void psp_vdp2_draw_screens(void); -static void psp_vdp2_set_resolution(u16 TVMD); -static void FASTCALL psp_vdp2_set_priority_NBG0(int priority); -static void FASTCALL psp_vdp2_set_priority_NBG1(int priority); -static void FASTCALL psp_vdp2_set_priority_NBG2(int priority); -static void FASTCALL psp_vdp2_set_priority_NBG3(int priority); -static void FASTCALL psp_vdp2_set_priority_RBG0(int priority); - -/*-----------------------------------------------------------------------*/ - -/* Module interface definition */ - -VideoInterface_struct VIDPSP = { - .id = VIDCORE_PSP, - .Name = "PSP Video Interface", - .Init = psp_video_init, - .DeInit = psp_video_deinit, - .Resize = psp_video_resize, - .IsFullscreen = psp_video_is_fullscreen, - .OnScreenDebugMessage = psp_video_debug_message, - - .Vdp1Reset = psp_vdp1_reset, - .Vdp1DrawStart = psp_vdp1_draw_start, - .Vdp1DrawEnd = psp_vdp1_draw_end, - .Vdp1NormalSpriteDraw = psp_vdp1_normal_sprite_draw, - .Vdp1ScaledSpriteDraw = psp_vdp1_scaled_sprite_draw, - .Vdp1DistortedSpriteDraw = psp_vdp1_distorted_sprite_draw, - .Vdp1PolygonDraw = psp_vdp1_polygon_draw, - .Vdp1PolylineDraw = psp_vdp1_polyline_draw, - .Vdp1LineDraw = psp_vdp1_line_draw, - .Vdp1UserClipping = psp_vdp1_user_clipping, - .Vdp1SystemClipping = psp_vdp1_system_clipping, - .Vdp1LocalCoordinate = psp_vdp1_local_coordinate, - - .Vdp2Reset = psp_vdp2_reset, - .Vdp2DrawStart = psp_vdp2_draw_start, - .Vdp2DrawEnd = psp_vdp2_draw_end, - .Vdp2DrawScreens = psp_vdp2_draw_screens, - .Vdp2SetResolution = psp_vdp2_set_resolution, - .Vdp2SetPriorityNBG0 = psp_vdp2_set_priority_NBG0, - .Vdp2SetPriorityNBG1 = psp_vdp2_set_priority_NBG1, - .Vdp2SetPriorityNBG2 = psp_vdp2_set_priority_NBG2, - .Vdp2SetPriorityNBG3 = psp_vdp2_set_priority_NBG3, - .Vdp2SetPriorityRBG0 = psp_vdp2_set_priority_RBG0, -}; - -/*************************************************************************/ -/************************* Global and local data *************************/ -/*************************************************************************/ - -/**** Exported data ****/ - -/* Color table generated from VDP2 color RAM */ -__attribute__((aligned(64))) uint16_t global_clut_16[0x800]; -__attribute__((aligned(64))) uint32_t global_clut_32[0x800]; - -/* Displayed width and height */ -unsigned int disp_width, disp_height; - -/* Scale (right-shift) applied to X and Y coordinates */ -unsigned int disp_xscale, disp_yscale; - -/* Total number of frames to skip before we draw the next one */ -unsigned int frames_to_skip; - -/* Number of frames skipped so far since we drew the last one */ -unsigned int frames_skipped; - -/* VDP1 color component offset values (-0xFF...+0xFF) */ -int32_t vdp1_rofs, vdp1_gofs, vdp1_bofs; - -/*-----------------------------------------------------------------------*/ - -/**** Internal data ****/ - -/*----------------------------------*/ - -/* Pending infoline text (malloc()ed, or NULL if none) and color */ -static char *infoline_text; -static uint32_t infoline_color; - -/*----------------------------------*/ - -/* Current average frame rate (rolling average) */ -static float average_fps; - -/* Flag indicating whether graphics should be drawn this frame */ -static uint8_t draw_graphics; - -/* Background priorities (NBG0, NBG1, NBG2, NBG3, RBG0) */ -static uint8_t bg_priority[5]; - -/*----------------------------------*/ - -/* Custom drawing function specified for each background layer */ -static CustomDrawRoutine *custom_draw_func[5]; - -/* Is the RBG0 drawing function fast enough to consider it a normal layer - * for timing purposes? */ -static uint8_t RBG0_draw_func_is_fast; - -/* Did we draw a slow RBG0 this frame? */ -static uint8_t drew_slow_RBG0; - -/*----------------------------------*/ - -/* Rendering data for sprites, polygons, and lines (a copy of all - * parameters except priority passed to vdp1_render_queue() */ -typedef struct VDP1RenderData_ { - uint32_t texture_key; - int primitive; - int vertex_type; - int count; - const void *indices; - const void *vertices; -} VDP1RenderData; - -/* VDP1 render queues (one for each priority level) */ -typedef struct VDP1RenderQueue_ { - VDP1RenderData *queue; // Array of entries (dynamically expanded) - int size; // Size of queue array, in entries - int len; // Number of entries currently in array -} VDP1RenderQueue; -static VDP1RenderQueue vdp1_queue[8]; - -/* Amount to expand a queue's array when it gets full */ -#define VDP1_QUEUE_EXPAND_SIZE 1000 - -/*----------------------------------*/ - -/* Flags indicating whether each 4k page of VDP1/2 RAM contains any - * persistently-cached texture data */ -static uint8_t vdp1_page_cached[0x80], vdp2_page_cached[0x80]; - -/* Checksum of each VDP1/2 RAM page containing cached texture data */ -static uint32_t vdp1_page_checksum[0x80], vdp2_page_checksum[0x80]; - -/* State of color offset settings at last cache reset */ -static uint32_t vdp1_cached_cofs; -static uint32_t vdp2_cached_cofs_regs; // CLOFEN<<16 | CLOFSL -static uint32_t vdp2_cached_cofs_A, vdp2_cached_cofs_B; - -/*************************************************************************/ - -/**** Local function declarations ****/ - -static int vdp1_is_persistent(vdp1cmd_struct *cmd); -static void vdp1_draw_lines(vdp1cmd_struct *cmd, int poly); -static void vdp1_draw_quad(vdp1cmd_struct *cmd, int textured); -static uint32_t vdp1_convert_color(uint16_t color16, int textured, - unsigned int CMDPMOD); -static uint32_t vdp1_get_cmd_color(vdp1cmd_struct *cmd); -static uint32_t vdp1_get_cmd_color_pri(vdp1cmd_struct *cmd, int textured, - int *priority_ret); -static uint16_t vdp1_process_sprite_color(uint16_t color16, int *priority_ret, - int *alpha_ret); -static uint32_t vdp1_cache_sprite_texture( - vdp1cmd_struct *cmd, int width, int height, int *priority_ret, - int *alpha_ret); -static inline void vdp1_queue_render( - int priority, uint32_t texture_key, int primitive, - int vertex_type, int count, const void *indices, const void *vertices); -static void vdp1_run_queue(int priority); - -static inline void vdp2_get_color_offsets(uint16_t mask, int32_t *rofs_ret, - int32_t *gofs_ret, int32_t *bofs_ret); - -static void vdp2_draw_bg(void); -static void vdp2_draw_graphics(int layer); - -/*************************************************************************/ -/********************** General interface functions **********************/ -/*************************************************************************/ - -/** - * psp_video_init: Initialize the peripheral interface. - * - * [Parameters] - * None - * [Return value] - * Zero on success, negative on error - */ -static int psp_video_init(void) -{ - /* Set some reasonable defaults. */ - disp_width = 320; - disp_height = 224; - disp_xscale = 0; - disp_yscale = 0; - - /* Always draw the first frame. */ - frames_to_skip = 0; - frames_skipped = 0; - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * psp_video_deinit: Shut down the peripheral interface. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_video_deinit(void) -{ - /* We don't implement shutting down, so nothing to do. */ -} - -/*************************************************************************/ - -/** - * psp_video_resize: Resize the display window. A no-op on PSP. - * - * [Parameters] - * width: New window width - * height: New window height - * fullscreen: Nonzero to use fullscreen mode, else zero - * [Return value] - * None - */ -static void psp_video_resize(unsigned int width, unsigned int height, - int fullscreen) -{ -} - -/*************************************************************************/ - -/** - * psp_video_is_fullscreen: Return whether the display is currently in - * fullscreen mode. Always returns true (nonzero) on PSP. - * - * [Parameters] - * None - * [Return value] - * Nonzero if in fullscreen mode, else zero - */ -static int psp_video_is_fullscreen(void) -{ - return 1; -} - -/*************************************************************************/ - -/** - * psp_video_debug_message: Display a debug message on the screen. - * - * [Parameters] - * format: printf()-style format string - * [Return value] - * None - */ -static void psp_video_debug_message(char *format, ...) -{ - /* Not implemented */ -} - -/*************************************************************************/ -/********************* PSP-only interface functions **********************/ -/*************************************************************************/ - -/** - * psp_video_infoline: Display an information line on the bottom of the - * screen. The text will be displayed for one frame only; call this - * function every frame to keep the text visible. - * - * [Parameters] - * color: Text color (0xAABBGGRR) - * text: Text string - * [Return value] - * None - */ -void psp_video_infoline(uint32_t color, const char *text) -{ - infoline_text = strdup(text); - if (UNLIKELY(!infoline_text)) { - DMSG("Failed to strdup(%s)", text); - } - infoline_color = color; -} - -/*************************************************************************/ - -/** - * psp_video_set_draw_routine: Set a custom drawing routine for a specific - * graphics layer. If "is_fast" is true when setting a routine for RBG0, - * the frame rate will not be halved regardless of the related setting in - * the configuration menu. - * - * [Parameters] - * layer: Graphics layer (BG_*) - * func: Drawing routine (NULL to clear any previous setting) - * is_fast: For BG_RBG0, indicates whether the routine is fast enough - * to be considered a non-distorted layer for the purposes - * of frame rate adjustment; ignored for other layers - * [Return value] - * None - */ -void psp_video_set_draw_routine(int layer, CustomDrawRoutine *func, - int is_fast) -{ - PRECOND(layer >= BG_NBG0 && layer <= BG_RBG0, return); - custom_draw_func[layer] = func; - if (layer == BG_RBG0) { - RBG0_draw_func_is_fast = is_fast; - } -} - -/*************************************************************************/ - -/** - * vdp2_is_persistent: Return whether the tile at the given address in - * VDP2 RAM is persistently cacheable. - * - * [Parameters] - * address: Tile address in VDP2 RAM - * [Return value] - * Nonzero if tile texture can be persistently cached, else zero - */ -int vdp2_is_persistent(uint32_t address) -{ - const unsigned int page = address >> 12; - if (!vdp2_page_cached[page]) { - vdp2_page_checksum[page] = - checksum_fast32((const uint32_t *)(Vdp2Ram + (page<<12)), 1024); - vdp2_page_cached[page] = 1; - } - return 1; -} - -/*************************************************************************/ -/******************* VDP1-specific interface functions *******************/ -/*************************************************************************/ - -/** - * psp_vdp1_reset: Reset the VDP1 state. - * - * [Parameters] - * None - * [Return value] - * Unknown (always zero) - */ -static int psp_vdp1_reset(void) -{ - /* Nothing to do. */ - return 0; -} - -/*************************************************************************/ - -/** - * psp_vdp1_draw_start: Prepare for VDP1 drawing. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_draw_start(void) -{ - if (frames_skipped < frames_to_skip) { - return; - } - - /* Clear out all the rendering queues (just to be safe). */ - int priority; - for (priority = 0; priority < 8; priority++) { - vdp1_queue[priority].len = 0; - } - - /* Get the color offsets. */ - vdp2_get_color_offsets(1<<6, &vdp1_rofs, &vdp1_gofs, &vdp1_bofs); -} - -/*************************************************************************/ - - -/** - * psp_vdp1_draw_end: Finish VDP1 drawing. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_draw_end(void) -{ - /* Nothing to do */ -} - -/*************************************************************************/ - - -/** - * psp_vdp1_normal_sprite_draw: Draw an unscaled rectangular sprite. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_normal_sprite_draw(void) -{ - if (frames_skipped < frames_to_skip) { - return; - } - - vdp1cmd_struct cmd; - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - int width = ((cmd.CMDSIZE >> 8) & 0x3F) * 8; - int height = cmd.CMDSIZE & 0xFF; - cmd.CMDXB = cmd.CMDXA + width; cmd.CMDYB = cmd.CMDYA; - cmd.CMDXC = cmd.CMDXA + width; cmd.CMDYC = cmd.CMDYA + height; - cmd.CMDXD = cmd.CMDXA; cmd.CMDYD = cmd.CMDYA + height; - - vdp1_draw_quad(&cmd, 1); -} - -/*************************************************************************/ - -/** - * psp_vdp1_scaled_sprite_draw: Draw a scaled rectangular sprite. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_scaled_sprite_draw(void) -{ - if (frames_skipped < frames_to_skip) { - return; - } - - vdp1cmd_struct cmd; - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - - if (!(cmd.CMDCTRL & 0x0F00)) { - /* Size is directly specified. */ - cmd.CMDXC++; cmd.CMDYC++; - cmd.CMDXB = cmd.CMDXC; cmd.CMDYB = cmd.CMDYA; - cmd.CMDXD = cmd.CMDXA; cmd.CMDYD = cmd.CMDYC; - } else { - /* Scale around a particular point (left/top, center, right/bottom). */ - int new_w = cmd.CMDXB + 1; - int new_h = cmd.CMDYB + 1; - if ((cmd.CMDCTRL & 0x300) == 0x200) { - cmd.CMDXA -= cmd.CMDXB / 2; - } else if ((cmd.CMDCTRL & 0x300) == 0x300) { - cmd.CMDXA -= cmd.CMDXB; - } - if ((cmd.CMDCTRL & 0xC00) == 0x800) { - cmd.CMDYA -= cmd.CMDYB / 2; - } else if ((cmd.CMDCTRL & 0xC00) == 0xC00) { - cmd.CMDYA -= cmd.CMDYB; - } - cmd.CMDXB = cmd.CMDXA + new_w; cmd.CMDYB = cmd.CMDYA; - cmd.CMDXC = cmd.CMDXA + new_w; cmd.CMDYC = cmd.CMDYA + new_h; - cmd.CMDXD = cmd.CMDXA; cmd.CMDYD = cmd.CMDYA + new_h; - } - - vdp1_draw_quad(&cmd, 1); -} - -/*************************************************************************/ - -/** - * psp_vdp1_distorted_sprite_draw: Draw a sprite on an arbitrary - * quadrilateral. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_distorted_sprite_draw(void) -{ - if (frames_skipped < frames_to_skip) { - return; - } - - vdp1cmd_struct cmd; - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - vdp1_draw_quad(&cmd, 1); -} - -/*************************************************************************/ - -/** - * psp_vdp1_polygon_draw: Draw an untextured quadrilateral. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_polygon_draw(void) -{ - if (frames_skipped < frames_to_skip) { - return; - } - - vdp1cmd_struct cmd; - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - vdp1_draw_quad(&cmd, 0); -} - -/*************************************************************************/ - -/** - * psp_vdp1_polyline_draw: Draw four connected lines. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_polyline_draw(void) -{ - if (frames_skipped < frames_to_skip) { - return; - } - - vdp1cmd_struct cmd; - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - vdp1_draw_lines(&cmd, 1); -} - -/*************************************************************************/ - -/** - * psp_vdp1_line_draw: Draw a single line. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_line_draw(void) -{ - if (frames_skipped < frames_to_skip) { - return; - } - - vdp1cmd_struct cmd; - Vdp1ReadCommand(&cmd, Vdp1Regs->addr); - vdp1_draw_lines(&cmd, 0); -} - -/*************************************************************************/ - -/** - * psp_vdp1_user_clipping: Set the user clipping coordinates. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_user_clipping(void) -{ - Vdp1Regs->userclipX1 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0xC); - Vdp1Regs->userclipY1 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0xE); - Vdp1Regs->userclipX2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x14); - Vdp1Regs->userclipY2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x16); -} - -/*************************************************************************/ - -/** - * psp_vdp1_system_clipping: Set the system clipping coordinates. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_system_clipping(void) -{ - Vdp1Regs->systemclipX1 = 0; - Vdp1Regs->systemclipY1 = 0; - Vdp1Regs->systemclipX2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x14); - Vdp1Regs->systemclipY2 = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0x16); -} - -/*************************************************************************/ - -/** - * psp_vdp1_local_coordinate: Set coordinate offset values used in drawing - * primitives. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp1_local_coordinate(void) -{ - Vdp1Regs->localX = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0xC); - Vdp1Regs->localY = T1ReadWord(Vdp1Ram, Vdp1Regs->addr + 0xE); -} - -/*************************************************************************/ -/******************* VDP2-specific interface functions *******************/ -/*************************************************************************/ - -/** - * psp_vdp2_reset: Reset the VDP2 state. - * - * [Parameters] - * None - * [Return value] - * Unknown (always zero) - */ -static int psp_vdp2_reset(void) -{ - /* Nothing to do */ - return 0; -} - -/*************************************************************************/ - -/** - * psp_vdp2_draw_start: Begin drawing a video frame. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp2_draw_start(void) -{ - /* Apply any game-specific optimizations or tweaks. (This may involve - * adjusting the frame-skip variables, so we call it before the - * frame-skip check.) */ - psp_video_apply_tweaks(); - - /* If we're skipping this frame, we don't do anything, not even start - * a new output frame (because that forces a VBlank sync, which may - * waste time if the previous frame completed quickly). */ - if (frames_skipped < frames_to_skip) { - return; - } - - /* Load the global color lookup tables from VDP2 color RAM. */ - const uint16_t *cram = (const uint16_t *)Vdp2ColorRam; - if (Vdp2Internal.ColorMode == 2) { // 32-bit color table - int i; - for (i = 0; i < 0x400; i++) { - uint16_t xb = cram[i*2+0]; - uint16_t gr = cram[i*2+1]; - uint16_t color16 = 0x8000 | (xb<<7 & 0x7C00) - | (gr<<2 & 0x3E0) | (gr>>3 & 0x1F); - uint32_t color32 = 0xFF000000 | xb<<16 | gr; - global_clut_16[i] = color16; - global_clut_16[i+0x400] = color16; - global_clut_32[i] = color32; - global_clut_32[i+0x400] = color32; - } - } else { // 16-bit color table - int i; - for (i = 0; i < 0x800; i++) { - uint16_t color16 = 0x8000 | cram[i]; - uint32_t color32 = 0xFF000000 | (color16 & 0x7C00) << 9 - | (color16 & 0x03E0) << 6 - | (color16 & 0x001F) << 3; - global_clut_16[i] = color16; - global_clut_32[i] = color32; - } - } - - /* Start a new frame. */ - display_set_size(disp_width >> disp_xscale, disp_height >> disp_yscale); - display_begin_frame(); - - /* Clear the texture cache of transient data; also clear persistent - * data if any source RAM or color offsets were changed, or if - * persistent caching is disabled in the first place. */ - const uint32_t vdp1_cofs = (vdp1_rofs & 0x1FF) << 18 - | (vdp1_gofs & 0x1FF) << 9 - | (vdp1_bofs & 0x1FF) << 0; - const uint32_t vdp2_cofs_regs = Vdp2Regs->CLOFEN << 16 | Vdp2Regs->CLOFSL; - const uint32_t vdp2_cofs_A = (Vdp2Regs->COAR & 0x1FF) << 18 - | (Vdp2Regs->COAG & 0x1FF) << 9 - | (Vdp2Regs->COAB & 0x1FF) << 0; - const uint32_t vdp2_cofs_B = (Vdp2Regs->COBR & 0x1FF) << 18 - | (Vdp2Regs->COBG & 0x1FF) << 9 - | (Vdp2Regs->COBB & 0x1FF) << 0; - int need_reset = 0; - if (!config_get_cache_textures()) { - need_reset = 1; - } else if (vdp1_cofs != vdp1_cached_cofs - || vdp2_cofs_regs != vdp2_cached_cofs_regs - || vdp2_cofs_A != vdp2_cached_cofs_A - || vdp2_cofs_B != vdp2_cached_cofs_B) { - DMSG("Color offsets changed, clearing cache"); - need_reset = 1; - } else { - unsigned int page; - for (page = 0; page < 0x80; page++) { - if (vdp1_page_cached[page]) { - const uint32_t sum = - checksum_fast32((const uint32_t *)(Vdp1Ram + (page<<12)), 1024); - if (sum != vdp1_page_checksum[page]) { - DMSG("VDP1 page 0x%05X checksum changed (%08X -> %08X)," - " clearing cache", - page<<12, vdp1_page_checksum[page], sum); - need_reset = 1; - break; - } - } - if (vdp2_page_cached[page]) { - const uint32_t sum = - checksum_fast32((const uint32_t *)(Vdp2Ram + (page<<12)), 1024); - if (sum != vdp2_page_checksum[page]) { - DMSG("VDP2 page 0x%05X checksum changed (%08X -> %08X)," - " clearing cache", - page<<12, vdp2_page_checksum[page], sum); - need_reset = 1; - break; - } - } - } - } - if (need_reset) { - texcache_reset(); - memset(vdp1_page_cached, 0, sizeof(vdp1_page_cached)); - memset(vdp2_page_cached, 0, sizeof(vdp2_page_cached)); - } else { - texcache_clean(); - } - vdp1_cached_cofs = vdp1_cofs; - vdp2_cached_cofs_regs = vdp2_cofs_regs; - vdp2_cached_cofs_A = vdp2_cofs_A; - vdp2_cached_cofs_B = vdp2_cofs_B; - - /* Initialize the render state. */ - guTexFilter(GU_NEAREST, GU_NEAREST); - guTexWrap(GU_CLAMP, GU_CLAMP); - guTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); - guBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); - guEnable(GU_BLEND); // We treat everything as alpha-enabled - - /* Reset the draw-graphics flag (it will be set by draw_screens() if - * graphics are active). */ - draw_graphics = 0; -} - -/*************************************************************************/ - -/** - * psp_vdp2_draw_end: Finish drawing a video frame. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp2_draw_end(void) -{ - if (frames_skipped >= frames_to_skip) { - - /* Draw all graphics by priority. */ - int priority; - for (priority = 0; priority < 8; priority++) { - /* Draw background graphics first... */ - if (draw_graphics && priority > 0) { - if (bg_priority[BG_NBG3] == priority) { - vdp2_draw_graphics(BG_NBG3); - } - if (bg_priority[BG_NBG2] == priority) { - vdp2_draw_graphics(BG_NBG2); - } - if (bg_priority[BG_NBG1] == priority) { - vdp2_draw_graphics(BG_NBG1); - } - if (bg_priority[BG_NBG0] == priority) { - vdp2_draw_graphics(BG_NBG0); - } - if (bg_priority[BG_RBG0] == priority) { - vdp2_draw_graphics(BG_RBG0); - } - } - /* Then draw sprites on top... */ - vdp1_run_queue(priority); - /* And clear the rendering queue. */ - vdp1_queue[priority].len = 0; - } - - /* Always compute average FPS (even if we're not showing it), so - * the value is accurate as soon as the display is turned on. - * We use a rolling average that decays by 50% every second. */ - unsigned int frame_length = display_last_frame_length(); - if (frame_length == 0) { - frame_length = 1; // Just in case (avoid division by 0) - } - unsigned int frame_count = 1 + frames_skipped; - const float fps = (frame_count*60.0f) / frame_length; - if (!average_fps) { - /* When first starting up, just set the average to the first - * frame's frame rate. */ - average_fps = fps; - } else { - const float weight = powf(2.0f, -(1/fps)); - average_fps = (average_fps * weight) + (fps * (1-weight)); - } - if (config_get_show_fps()) { - unsigned int show_fps = iroundf(average_fps*10); - if (show_fps > 600) { - /* FPS may momentarily exceed 60.0 due to timing jitter, - * but we never show more than 60.0. */ - show_fps = 600; - } - font_printf((disp_width >> disp_xscale) - 2, 2, 1, 0xAAFF8040, - "FPS: %2d.%d (%d/%2d)", show_fps/10, show_fps%10, - frame_count, frame_length); - } - - if (infoline_text) { - font_printf((disp_width >> disp_xscale) / 2, - (disp_height >> disp_yscale) - FONT_HEIGHT - 2, 0, - infoline_color, "%s", infoline_text); - free(infoline_text); - infoline_text = NULL; - } - - display_end_frame(); - - } // if (frames_skipped >= frames_to_skip) - - if (frames_skipped < frames_to_skip) { - frames_skipped++; - timing_skip_next_sync(); // Let the emulation continue uninterrupted - } else { - frames_skipped = 0; - if (config_get_frameskip_auto()) { - // FIXME: auto frame skipping not yet implemented - frames_to_skip = 0; - } else { - frames_to_skip = config_get_frameskip_num(); - } - if (drew_slow_RBG0) { - frames_to_skip += 1 + frames_to_skip; - } - if (disp_height > 272 && frames_to_skip == 0 - && config_get_frameskip_interlace() - ) { - frames_to_skip = 1; - } - drew_slow_RBG0 = 0; - } -} - -/*************************************************************************/ - -/** - * psp_vdp2_draw_screens: Draw the VDP2 background and graphics layers. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void psp_vdp2_draw_screens(void) -{ - if (frames_skipped < frames_to_skip) { - return; - } - - /* Draw the background color(s). */ - vdp2_draw_bg(); - - /* Flag the background graphics to be drawn. */ - draw_graphics = 1; -} - -/*************************************************************************/ - -/** - * psp_vdp2_set_resolution: Change the resolution of the Saturn display. - * - * [Parameters] - * TVMD: New value of the VDP2 TVMD register - * [Return value] - * None - */ -static void psp_vdp2_set_resolution(u16 TVMD) -{ - /* Set the display width from bits 0-1. */ - disp_width = (TVMD & 1) ? 352 : 320; - if (TVMD & 2) { - disp_width *= 2; - } - - /* Set the display height from bits 4-5. Note that 0x30 is an invalid - * value for these bits and should not occur in practice; valid heights - * are 0x00=224, 0x10=240, and (for PAL) 0x20=256. */ - disp_height = 224 + (TVMD & 0x30); - if ((TVMD & 0xC0) == 0xC0) { - disp_height *= 2; // Interlaced mode - } - - /* Hi-res or interlaced displays won't fit on the PSP screen, so cut - * everything in half when using them. */ - disp_xscale = (disp_width > 352); - disp_yscale = (disp_height > 256); -} - -/*************************************************************************/ - -/** - * psp_vdp2_set_priority_{NBG[0-3],RBG0}: Set the priority of the given - * background graphics layer. - * - * [Parameters] - * priority: Priority to set - * [Return value] - * None - */ -static void FASTCALL psp_vdp2_set_priority_NBG0(int priority) -{ - bg_priority[BG_NBG0] = priority; -} - -static void FASTCALL psp_vdp2_set_priority_NBG1(int priority) -{ - bg_priority[BG_NBG1] = priority; -} - -static void FASTCALL psp_vdp2_set_priority_NBG2(int priority) -{ - bg_priority[BG_NBG2] = priority; -} - -static void FASTCALL psp_vdp2_set_priority_NBG3(int priority) -{ - bg_priority[BG_NBG3] = priority; -} - -static void FASTCALL psp_vdp2_set_priority_RBG0(int priority) -{ - bg_priority[BG_RBG0] = priority; -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * vdp1_is_persistent: Return whether the given sprite drawing command - * identifies a texture in a persistently-cacheable area of VDP1 RAM. - * - * [Parameters] - * cmd: VDP1 command structure - * [Return value] - * Nonzero if texture can be persistently cached, else zero - */ -static int vdp1_is_persistent(vdp1cmd_struct *cmd) -{ - const unsigned int first_page = cmd->CMDSRCA >> 9; - const unsigned int width_8 = (cmd->CMDSIZE >> 8) & 0x3F; - const unsigned int height = cmd->CMDSIZE & 0xFF; - const unsigned int last_page = (cmd->CMDSRCA + (width_8 * height)) >> 9; - unsigned int page; - for (page = first_page; page <= last_page; page++) { - if (!vdp1_page_cached[page]) { - vdp1_page_checksum[page] = - checksum_fast32((const uint32_t *)(Vdp1Ram + (page<<12)), 1024); - vdp1_page_cached[page] = 1; - } - } - if ((cmd->CMDPMOD>>3 & 7) == 1) { - page = cmd->CMDCOLR >> 9; - if (!vdp1_page_cached[page]) { - vdp1_page_checksum[page] = - checksum_fast32((const uint32_t *)(Vdp1Ram + (page<<12)), 1024); - vdp1_page_cached[page] = 1; - } - } - return 1; -} - -/*************************************************************************/ - -/** - * vdp1_draw_lines: Draw one or four lines based on the given VDP1 command. - * - * [Parameters] - * cmd: VDP1 command pointer - * poly: Nonzero = draw four connected lines, zero = draw a single line - * [Return value] - * None - */ -static void vdp1_draw_lines(vdp1cmd_struct *cmd, int poly) -{ - /* Get the line color and priority. */ - // FIXME: vidogl.c suggests that the priority processing done for - // sprites and polygons is not done here; is that correct? - const uint32_t color32 = vdp1_get_cmd_color(cmd); - const int priority = Vdp2Regs->PRISA & 0x7; - - /* If it's Gouraud-shaded, pick up the four endpoint colors. (Only - * the first two of these are used for single lines.) */ - uint32_t color_A, color_B, color_C, color_D; - if (cmd->CMDPMOD & 4) { // Gouraud shading bit - const uint32_t alpha = color32 & 0xFF000000; - if (vdp1_rofs | vdp1_gofs | vdp1_bofs) { - unsigned int temp_A, temp_B, temp_C, temp_D; - temp_A = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + 0); - temp_B = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + 2); - temp_C = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + 4); - temp_D = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + 6); - color_A = alpha | (adjust_color_16_32(temp_A, vdp1_rofs, vdp1_gofs, - vdp1_bofs) & 0x00FFFFFF); - color_B = alpha | (adjust_color_16_32(temp_B, vdp1_rofs, vdp1_gofs, - vdp1_bofs) & 0x00FFFFFF); - color_C = alpha | (adjust_color_16_32(temp_C, vdp1_rofs, vdp1_gofs, - vdp1_bofs) & 0x00FFFFFF); - color_D = alpha | (adjust_color_16_32(temp_D, vdp1_rofs, vdp1_gofs, - vdp1_bofs) & 0x00FFFFFF); - } else { - unsigned int temp_A, temp_B, temp_C, temp_D; - temp_A = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + 0); - temp_B = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + 2); - temp_C = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + 4); - temp_D = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + 6); - color_A = alpha | (temp_A & 0x7C00) << 9 - | (temp_A & 0x03E0) << 6 - | (temp_A & 0x001F) << 3; - color_B = alpha | (temp_B & 0x7C00) << 9 - | (temp_B & 0x03E0) << 6 - | (temp_B & 0x001F) << 3; - color_C = alpha | (temp_C & 0x7C00) << 9 - | (temp_C & 0x03E0) << 6 - | (temp_C & 0x001F) << 3; - color_D = alpha | (temp_D & 0x7C00) << 9 - | (temp_D & 0x03E0) << 6 - | (temp_D & 0x001F) << 3; - } - } else { - color_A = color_B = color_C = color_D = color32; - } - - /* Set up the vertex array. */ - int nvertices = poly ? 5 : 2; - struct {uint32_t color; int16_t x, y, z, pad;} *vertices; - vertices = pspGuGetMemoryMerge(sizeof(*vertices) * nvertices); - vertices[0].color = color_A; - vertices[0].x = (cmd->CMDXA + Vdp1Regs->localX) >> disp_xscale; - vertices[0].y = (cmd->CMDYA + Vdp1Regs->localY) >> disp_yscale; - vertices[0].z = 0; - vertices[1].color = color_B; - vertices[1].x = (cmd->CMDXB + Vdp1Regs->localX) >> disp_xscale; - vertices[1].y = (cmd->CMDYB + Vdp1Regs->localY) >> disp_xscale; - vertices[1].z = 0; - if (poly) { - vertices[2].color = color_C; - vertices[2].x = (cmd->CMDXC + Vdp1Regs->localX) >> disp_xscale; - vertices[2].y = (cmd->CMDYC + Vdp1Regs->localY) >> disp_yscale; - vertices[2].z = 0; - vertices[3].color = color_D; - vertices[3].x = (cmd->CMDXD + Vdp1Regs->localX) >> disp_xscale; - vertices[3].y = (cmd->CMDYD + Vdp1Regs->localY) >> disp_yscale; - vertices[3].z = 0; - vertices[4] = vertices[0]; - } - - /* Queue the line(s). */ - vdp1_queue_render(priority, 0, GU_LINE_STRIP, - GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - nvertices, NULL, vertices); -} - -/*************************************************************************/ - -/** - * vdp1_draw_quad: Draw a quadrilateral based on the given VDP1 command. - * - * [Parameters] - * cmd: VDP1 command pointer - * textured: Nonzero if the quadrilateral is textured (i.e. a sprite) - * [Return value] - * None - */ -static void vdp1_draw_quad(vdp1cmd_struct *cmd, int textured) -{ - /* Get the width, height, and flip arguments for sprites (unused for - * untextured polygons). */ - - int width, height; - unsigned int gouraud_flip = 0; // XOR bitmask for Gouraud color addresses - if (textured) { - width = ((cmd->CMDSIZE >> 8) & 0x3F) * 8; - height = cmd->CMDSIZE & 0xFF; - if (width == 0 || height == 0) { - return; - } - /* If flipping is specified, swap the relevant coordinates in the - * "cmd" structure; this helps avoid texture glitches when the - * vertex order of a texture is changed (e.g. Panzer Dragoon Saga). - * We use inline assembly so we can load and store in 32-bit units - * without GCC complaining about strict aliasing violations. */ - switch (cmd->CMDCTRL & 0x30) { - case 0x10: { // Flip horizontally - gouraud_flip = 2; - uint32_t tempA, tempB, tempC, tempD; - asm(".set push; .set noreorder\n" - "lw %[tempA], 12(%[cmd])\n" - "lw %[tempB], 16(%[cmd])\n" - "lw %[tempC], 20(%[cmd])\n" - "lw %[tempD], 24(%[cmd])\n" - "sw %[tempA], 16(%[cmd])\n" - "sw %[tempB], 12(%[cmd])\n" - "sw %[tempC], 24(%[cmd])\n" - "sw %[tempD], 20(%[cmd])\n" - ".set pop" - : [tempA] "=&r" (tempA), [tempB] "=&r" (tempB), - [tempC] "=&r" (tempC), [tempD] "=&r" (tempD), - "=m" (cmd->CMDXA), "=m" (cmd->CMDYA), "=m" (cmd->CMDXB), - "=m" (cmd->CMDYB), "=m" (cmd->CMDXC), "=m" (cmd->CMDYC), - "=m" (cmd->CMDXD), "=m" (cmd->CMDYD) - : [cmd] "r" (cmd) - ); - break; - } // case 0x10 - case 0x20: { // Flip vertically - gouraud_flip = 6; - uint32_t tempA, tempB, tempC, tempD; - asm(".set push; .set noreorder\n" - "lw %[tempA], 12(%[cmd])\n" - "lw %[tempB], 16(%[cmd])\n" - "lw %[tempC], 20(%[cmd])\n" - "lw %[tempD], 24(%[cmd])\n" - "sw %[tempA], 24(%[cmd])\n" - "sw %[tempB], 20(%[cmd])\n" - "sw %[tempC], 16(%[cmd])\n" - "sw %[tempD], 12(%[cmd])\n" - ".set pop" - : [tempA] "=&r" (tempA), [tempB] "=&r" (tempB), - [tempC] "=&r" (tempC), [tempD] "=&r" (tempD), - "=m" (cmd->CMDXA), "=m" (cmd->CMDYA), "=m" (cmd->CMDXB), - "=m" (cmd->CMDYB), "=m" (cmd->CMDXC), "=m" (cmd->CMDYC), - "=m" (cmd->CMDXD), "=m" (cmd->CMDYD) - : [cmd] "r" (cmd) - ); - break; - } // case 0x20 - case 0x30: { // Flip horizontally and vertically - gouraud_flip = 4; - uint32_t tempA, tempB, tempC, tempD; - asm(".set push; .set noreorder\n" - "lw %[tempA], 12(%[cmd])\n" - "lw %[tempB], 16(%[cmd])\n" - "lw %[tempC], 20(%[cmd])\n" - "lw %[tempD], 24(%[cmd])\n" - "sw %[tempA], 20(%[cmd])\n" - "sw %[tempB], 24(%[cmd])\n" - "sw %[tempC], 12(%[cmd])\n" - "sw %[tempD], 16(%[cmd])\n" - ".set pop" - : [tempA] "=&r" (tempA), [tempB] "=&r" (tempB), - [tempC] "=&r" (tempC), [tempD] "=&r" (tempD), - "=m" (cmd->CMDXA), "=m" (cmd->CMDYA), "=m" (cmd->CMDXB), - "=m" (cmd->CMDYB), "=m" (cmd->CMDXC), "=m" (cmd->CMDYC), - "=m" (cmd->CMDXD), "=m" (cmd->CMDYD) - : [cmd] "r" (cmd) - ); - break; - } // case 0x30 - } // switch (cmd->CMDCTRL & 0x30) - } else { - width = height = 0; - } - - - /* Get the polygon color and priority, and load the texture if it's - * a sprite. */ - - int priority, sprite_alpha; - uint32_t color32 = vdp1_get_cmd_color_pri(cmd, textured, &priority); - uint32_t texture_key; - if (textured) { - texture_key = vdp1_cache_sprite_texture(cmd, width, height, - &priority, &sprite_alpha); - if (UNLIKELY(!texture_key)) { - DMSG("WARNING: failed to cache texture for A=(%d,%d) B=(%d,%d)" - " C=(%d,%d) D=(%d,%d)", - cmd->CMDXA + Vdp1Regs->localX, cmd->CMDYA + Vdp1Regs->localY, - cmd->CMDXB + Vdp1Regs->localX, cmd->CMDYB + Vdp1Regs->localY, - cmd->CMDXC + Vdp1Regs->localX, cmd->CMDYC + Vdp1Regs->localY, - cmd->CMDXD + Vdp1Regs->localX, cmd->CMDYD + Vdp1Regs->localY); - } - /* Convert alpha to 0-255 */ - sprite_alpha = (sprite_alpha << 3) | (sprite_alpha >> 2); - } else { - texture_key = 0; - sprite_alpha = 0xFF; - } - - /* Apply alpha depending on the color calculation settings. */ - - if (Vdp2Regs->CCCTL & 0x40) { - const unsigned int ref_priority = Vdp2Regs->SPCTL>>8 & 0x7; - switch (Vdp2Regs->SPCTL>>12 & 0x3) { - case 0: - if (priority <= ref_priority) { - color32 = (sprite_alpha << 24) | (color32 & 0x00FFFFFF); - } - break; - case 1: - if (priority == ref_priority) { - color32 = (sprite_alpha << 24) | (color32 & 0x00FFFFFF); - } - break; - case 2: - if (priority >= ref_priority) { - color32 = (sprite_alpha << 24) | (color32 & 0x00FFFFFF); - } - break; - case 3: - /* Alpha blending enabled based on high bit of color value - * (not supported in this renderer) */ - break; - } - } - - /* We don't support mesh shading; treat it as half-alpha instead. */ - - if (cmd->CMDPMOD & 0x100) { // Mesh shading bit - const unsigned int alpha = color32 >> 24; - color32 = ((alpha+1)/2) << 24 | (color32 & 0x00FFFFFF); - } - - /* If it's a Gouraud-shaded polygon, pick up the four corner colors. */ - - uint32_t color_A, color_B, color_C, color_D; - if (cmd->CMDPMOD & 4) { // Gouraud shading bit - const uint32_t alpha = color32 & 0xFF000000; - if (vdp1_rofs | vdp1_gofs | vdp1_bofs) { - unsigned int temp_A, temp_B, temp_C, temp_D; - temp_A = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + (0^gouraud_flip)); - temp_B = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + (2^gouraud_flip)); - temp_C = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + (4^gouraud_flip)); - temp_D = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + (6^gouraud_flip)); - color_A = alpha | (adjust_color_16_32(temp_A, vdp1_rofs, vdp1_gofs, - vdp1_bofs) & 0x00FFFFFF); - color_B = alpha | (adjust_color_16_32(temp_B, vdp1_rofs, vdp1_gofs, - vdp1_bofs) & 0x00FFFFFF); - color_C = alpha | (adjust_color_16_32(temp_C, vdp1_rofs, vdp1_gofs, - vdp1_bofs) & 0x00FFFFFF); - color_D = alpha | (adjust_color_16_32(temp_D, vdp1_rofs, vdp1_gofs, - vdp1_bofs) & 0x00FFFFFF); - } else { - unsigned int temp_A, temp_B, temp_C, temp_D; - temp_A = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + (0^gouraud_flip)); - temp_B = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + (2^gouraud_flip)); - temp_C = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + (4^gouraud_flip)); - temp_D = T1ReadWord(Vdp1Ram, (cmd->CMDGRDA<<3) + (6^gouraud_flip)); - color_A = alpha | (temp_A & 0x7C00) << 9 - | (temp_A & 0x03E0) << 6 - | (temp_A & 0x001F) << 3; - color_B = alpha | (temp_B & 0x7C00) << 9 - | (temp_B & 0x03E0) << 6 - | (temp_B & 0x001F) << 3; - color_C = alpha | (temp_C & 0x7C00) << 9 - | (temp_C & 0x03E0) << 6 - | (temp_C & 0x001F) << 3; - color_D = alpha | (temp_D & 0x7C00) << 9 - | (temp_D & 0x03E0) << 6 - | (temp_D & 0x001F) << 3; - } - } else { - color_A = color_B = color_C = color_D = color32; - } - - /* Set up the vertex array using a strip of 2 triangles. The Saturn - * coordinate order is A,B,C,D clockwise around the texture, so we flip - * around C and D in our vertex array. For simplicity, we assign both - * the color and U/V coordinates regardless of whether the polygon is - * textured or not; the GE is fast enough that it can handle all the - * processing in time. */ - - struct {int16_t u, v; uint32_t color; int16_t x, y, z, pad;} *vertices; - vertices = pspGuGetMemoryMerge(sizeof(*vertices) * 4); - vertices[0].u = 0; - vertices[0].v = 0; - vertices[0].color = color_A; - vertices[0].x = (cmd->CMDXA + Vdp1Regs->localX) >> disp_xscale; - vertices[0].y = (cmd->CMDYA + Vdp1Regs->localY) >> disp_yscale; - vertices[0].z = 0; - vertices[1].u = width; - vertices[1].v = 0; - vertices[1].color = color_B; - vertices[1].x = (cmd->CMDXB + Vdp1Regs->localX) >> disp_xscale; - vertices[1].y = (cmd->CMDYB + Vdp1Regs->localY) >> disp_yscale; - vertices[1].z = 0; - vertices[2].u = 0; - vertices[2].v = height; - vertices[2].color = color_D; - vertices[2].x = (cmd->CMDXD + Vdp1Regs->localX) >> disp_xscale; - vertices[2].y = (cmd->CMDYD + Vdp1Regs->localY) >> disp_yscale; - vertices[2].z = 0; - vertices[3].u = width; - vertices[3].v = height; - vertices[3].color = color_C; - vertices[3].x = (cmd->CMDXC + Vdp1Regs->localX) >> disp_xscale; - vertices[3].y = (cmd->CMDYC + Vdp1Regs->localY) >> disp_yscale; - vertices[3].z = 0; - - /* Queue the draw operation. */ - - vdp1_queue_render(priority, texture_key, - GU_TRIANGLE_STRIP, GU_TEXTURE_16BIT | GU_COLOR_8888 - | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 4, NULL, vertices); -} - -/*************************************************************************/ - -/** - * vdp1_convert_color: Convert a VDP1 16-bit color value and pixel mode to - * a 32-bit color value. Helper function for vdp1_get_cmd_color() and - * vdp1_get_cmd_color_pri(). - * - * [Parameters] - * color16: 16-bit color value - * textured: Nonzero if a textured polygon command, else zero - * CMDPMOD: Value of CMDPMOD field in VDP1 command - * [Return value] - * 32-bit color value - */ -static uint32_t vdp1_convert_color(uint16_t color16, int textured, - unsigned int CMDPMOD) -{ - uint32_t color32; - if (textured) { - color32 = 0xFFFFFF; - } else if (color16 == 0) { - color32 = adjust_color_16_32(0x0000, vdp1_rofs, vdp1_gofs, vdp1_bofs); - return color32 & 0x00FFFFFF; // Transparent regardless of CMDPMOD - } else if (color16 & 0x8000) { - color32 = adjust_color_16_32(color16, vdp1_rofs, vdp1_gofs, vdp1_bofs); - } else { - color32 = adjust_color_32_32(global_clut_32[color16 & 0x7FF], - vdp1_rofs, vdp1_gofs, vdp1_bofs); - } - - switch (CMDPMOD & 7) { - default: // Impossible, but avoid a "function may not return" warning - case 1: // Shadow - return 0x80000000; - case 4 ... 7: // Gouraud shading (handled separately) - case 0: // Replace - return 0xFF000000 | color32; - case 2: // 50% luminance - /* Clever, quick way to divide each component by 2 in one step - * (borrowed from vidsoft.c) */ - return 0xFF000000 | ((color32 & 0xFEFEFE) >> 1); - case 3: // 50% transparency - return 0x80000000 | color32; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp1_get_cmd_color: Return the 32-bit color value specified by a VDP1 - * line command. - * - * [Parameters] - * cmd: VDP1 command pointer - * [Return value] - * 32-bit color value - */ -static uint32_t vdp1_get_cmd_color(vdp1cmd_struct *cmd) -{ - return vdp1_convert_color(cmd->CMDCOLR, 0, cmd->CMDPMOD); -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp1_get_cmd_color_pri: Return the 32-bit color value and priority - * specified by a VDP1 polygon command. - * - * [Parameters] - * cmd: VDP1 command pointer - * textured: Nonzero if the polygon is textured, else zero - * priority_ret: Pointer to variable to receive priority value - * [Return value] - * 32-bit color value - */ -static uint32_t vdp1_get_cmd_color_pri(vdp1cmd_struct *cmd, int textured, - int *priority_ret) -{ - uint16_t color16 = cmd->CMDCOLR; - if (cmd->CMDCOLR & 0x8000) { - *priority_ret = Vdp2Regs->PRISA & 7; - } else { - *priority_ret = 0; // Default if not set by SPCTL - int alpha_unused; // FIXME: is this used by non-sprite quads as well? - vdp1_process_sprite_color(color16, priority_ret, &alpha_unused); - } - return vdp1_convert_color(color16, textured, cmd->CMDPMOD); -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp1_process_sprite_color: Return the color index mask, priority index, - * and alpha (color calculation) index selected by the given color register - * value and the VDP2 SPCTL register. - * - * [Parameters] - * color16: 16-bit color register value - * priority_ret: Pointer to variable to receive priority value - * [Return value] - * Mask to apply to CMDCOLR register - */ -static uint16_t vdp1_process_sprite_color(uint16_t color16, int *priority_ret, - int *alpha_ret) -{ - static const uint8_t priority_shift[16] = - { 14, 13, 14, 13, 13, 12, 12, 12, 7, 7, 6, 0, 7, 7, 6, 0 }; - static const uint8_t priority_mask[16] = - { 3, 7, 1, 3, 3, 7, 7, 7, 1, 1, 3, 0, 1, 1, 3, 0 }; - static const uint8_t alpha_shift[16] = - { 11, 11, 11, 11, 10, 11, 10, 9, 0, 6, 0, 6, 0, 6, 0, 6 }; - static const uint8_t alpha_mask[16] = - { 7, 3, 7, 3, 7, 1, 3, 7, 0, 1, 0, 3, 0, 1, 0, 3 }; - static const uint16_t color_mask[16] = - { 0x7FF, 0x7FF, 0x7FF, 0x7FF, 0x3FF, 0x7FF, 0x3FF, 0x1FF, - 0x7F, 0x3F, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF }; - - const unsigned int type = Vdp2Regs->SPCTL & 0xF; - *priority_ret = (color16 >> priority_shift[type]) & priority_mask[type]; - *alpha_ret = (color16 >> alpha_shift[type]) & alpha_mask[type]; - return color_mask[type]; -} - -/*************************************************************************/ - -/** - * vdp1_cache_sprite_texture: Cache the sprite texture designated by the - * given VDP1 command. - * - * [Parameters] - * cmd: VDP1 command pointer - * width: Sprite width (pixels; passed in to avoid recomputation) - * height: Sprite height (pixels; passed in to avoid recomputation) - * priority_ret: Pointer to variable to receive priority value - * alpha_ret: Pointer to variable to receive alpha value (0-31) - * [Return value] - * Cached texture key, or zero on error - */ -static uint32_t vdp1_cache_sprite_texture( - vdp1cmd_struct *cmd, int width, int height, int *priority_ret, - int *alpha_ret) -{ - uint16_t pixel_mask = 0xFFFF; - int pri_reg = 0, alpha_reg = 0; // Default value - - int is_indexed = 1; - uint16_t color16 = cmd->CMDCOLR; - const int pixfmt = cmd->CMDPMOD>>3 & 7; - if (pixfmt == 5) { - is_indexed = 0; - } else if (pixfmt == 1) { - /* Indirect T4 texture; see whether the first pixel references - * color RAM or uses raw RGB values. */ - const uint32_t addr = cmd->CMDSRCA << 3; - const uint8_t pixel = T1ReadByte(Vdp1Ram, addr) >> 4; - const uint32_t colortable = cmd->CMDCOLR << 3; - const uint16_t value = T1ReadWord(Vdp1Ram, colortable + pixel*2); - if (value & 0x8000) { - is_indexed = 0; - } else { - color16 = value; - } - } - if (is_indexed) { - pixel_mask = vdp1_process_sprite_color(color16, &pri_reg, &alpha_reg); - } - - *priority_ret = ((uint8_t *)&Vdp2Regs->PRISA)[pri_reg] & 0x7; - *alpha_ret = 0x1F - (((uint8_t *)&Vdp2Regs->CCRSA)[alpha_reg] & 0x1F); - - /* Cache the texture data and return the key. */ - - return texcache_cache_sprite(cmd, pixel_mask, width, height, - vdp1_is_persistent(cmd)); -} - -/*************************************************************************/ - -/** - * vdp1_queue_render: Queue a render operation from a VDP1 command. - * - * [Parameters] - * priority: Saturn display priority (0-7) - * texture_key: Texture key for sprites, zero for untextured operations - * primitive, - * vertex_type, - * count, - * indices, - * vertices: Parameters to pass to guDrawArray() - * [Return value] - * None - */ -static inline void vdp1_queue_render( - int priority, uint32_t texture_key, int primitive, - int vertex_type, int count, const void *indices, const void *vertices) -{ - /* Expand the queue if necessary. */ - if (UNLIKELY(vdp1_queue[priority].len >= vdp1_queue[priority].size)) { - const int newsize = vdp1_queue[priority].size + VDP1_QUEUE_EXPAND_SIZE; - VDP1RenderData * const newqueue = realloc(vdp1_queue[priority].queue, - newsize * sizeof(*newqueue)); - if (UNLIKELY(!newqueue)) { - DMSG("Failed to expand priority %d queue to %d entries", - priority, newsize); - return; - } - vdp1_queue[priority].queue = newqueue; - vdp1_queue[priority].size = newsize; - } - - /* Record the data passed in. */ - const int index = vdp1_queue[priority].len++; - VDP1RenderData * const entry = &vdp1_queue[priority].queue[index]; - entry->texture_key = texture_key; - entry->primitive = primitive; - entry->vertex_type = vertex_type; - entry->count = count; - entry->indices = indices; - entry->vertices = vertices; -} - -/*-----------------------------------------------------------------------*/ - -/** - * vdp1_run_queue: Run the rendering queue for the given priority level. - * - * [Parameters] - * priority: Priority level to run - * [Return value] - * None - */ -static void vdp1_run_queue(int priority) -{ - int in_texture_mode; // Remember which mode we're in - VDP1RenderData *entry = vdp1_queue[priority].queue; - VDP1RenderData * const queue_top = entry + vdp1_queue[priority].len; - - if (vdp1_queue[priority].len == 0) { - return; // Nothing to do - } - - guShadeModel(GU_SMOOTH); - guAmbientColor(0xFFFFFFFF); - guTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); - if (config_get_smooth_textures()) { - guTexFilter(GU_LINEAR, GU_LINEAR); - } - if (entry->texture_key) { - guEnable(GU_TEXTURE_2D); - in_texture_mode = 1; - } else { - guDisable(GU_TEXTURE_2D); - in_texture_mode = 0; - } - for (; entry < queue_top; entry++) { - if (entry->texture_key) { - texcache_load_sprite(entry->texture_key); - if (!in_texture_mode) { - guEnable(GU_TEXTURE_2D); - in_texture_mode = 1; - } - } else { - if (in_texture_mode) { - guDisable(GU_TEXTURE_2D); - in_texture_mode = 0; - } - } - guDrawArray(entry->primitive, entry->vertex_type, - entry->count, entry->indices, entry->vertices); - } - if (in_texture_mode) { - guDisable(GU_TEXTURE_2D); - } - if (config_get_smooth_textures()) { - guTexFilter(GU_NEAREST, GU_NEAREST); - } - guShadeModel(GU_FLAT); - - guCommit(); -} - -/*************************************************************************/ -/*************************************************************************/ - -/** - * vdp2_get_color_offset: Calculate the color offsets to use for the - * specified CLOFEN/CLOFSL bit. - * - * [Parameters] - * mask: 1 << bit number to check - * rofs_ret: Pointer to variable to store red offset in - * gofs_ret: Pointer to variable to store green offset in - * bofs_ret: Pointer to variable to store blue offset in - * [Return value] - * None - */ -static inline void vdp2_get_color_offsets(uint16_t mask, int32_t *rofs_ret, - int32_t *gofs_ret, int32_t *bofs_ret) -{ - if (Vdp2Regs->CLOFEN & mask) { // CoLor OFfset ENable - /* Offsets are 9-bit signed values */ - if (Vdp2Regs->CLOFSL & mask) { // CoLor OFfset SeLect - *rofs_ret = ((int32_t)Vdp2Regs->COBR << 23) >> 23; - *gofs_ret = ((int32_t)Vdp2Regs->COBG << 23) >> 23; - *bofs_ret = ((int32_t)Vdp2Regs->COBB << 23) >> 23; - } else { - *rofs_ret = ((int32_t)Vdp2Regs->COAR << 23) >> 23; - *gofs_ret = ((int32_t)Vdp2Regs->COAG << 23) >> 23; - *bofs_ret = ((int32_t)Vdp2Regs->COAB << 23) >> 23; - } - } else { - /* No color offset */ - *rofs_ret = *gofs_ret = *bofs_ret = 0; - } -} - -/*************************************************************************/ - -/** - * vdp2_draw_bg: Draw the screen background. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void vdp2_draw_bg(void) -{ - uint32_t address = ((Vdp2Regs->BKTAU & 7) << 16 | Vdp2Regs->BKTAL) << 1; - if (!(Vdp2Regs->VRSIZE & 0x8000)) { - address &= 0x7FFFF; - } - - int rofs, gofs, bofs; - vdp2_get_color_offsets(1<<6, &rofs, &gofs, &bofs); - - struct {uint32_t color; int16_t x, y, z, pad;} *vertices; - - if (Vdp2Regs->BKTAU & 0x8000) { - /* Distinct color for each line */ - int num_vertices, y; - if (disp_height > 272) { - /* For interlaced screens, we average the colors of each two - * adjacent lines */ - num_vertices = 2*(disp_height/2); - vertices = pspGuGetMemoryMerge(sizeof(*vertices) * num_vertices); - for (y = 0; y+1 < disp_height; y += 2, address += 4) { - uint16_t rgb0 = T1ReadWord(Vdp2Ram, address); - uint32_t r0 = (rgb0 & 0x001F) << 3; - uint32_t g0 = (rgb0 & 0x03E0) >> 2; - uint32_t b0 = (rgb0 & 0x7C00) >> 7; - uint16_t rgb1 = T1ReadWord(Vdp2Ram, address); - uint32_t r1 = (rgb1 & 0x001F) << 3; - uint32_t g1 = (rgb1 & 0x03E0) >> 2; - uint32_t b1 = (rgb1 & 0x7C00) >> 7; - uint32_t color = bound(((r0+r1+1)/2) + rofs, 0, 255) << 0 - | bound(((g0+g1+1)/2) + gofs, 0, 255) << 8 - | bound(((b0+b1+1)/2) + bofs, 0, 255) << 16 - | 0xFF000000; - vertices[y+0].color = color; - vertices[y+0].x = 0; - vertices[y+0].y = y/2; - vertices[y+0].z = 0; - vertices[y+1].color = color; - vertices[y+1].x = disp_width >> disp_xscale; - vertices[y+1].y = y/2; - vertices[y+1].z = 0; - } - } else { - num_vertices = 2*disp_height; - vertices = pspGuGetMemoryMerge(sizeof(*vertices) * num_vertices); - for (y = 0; y < disp_height; y++, address += 2) { - uint16_t rgb = T1ReadWord(Vdp2Ram, address); - uint32_t r = bound(((rgb & 0x001F) << 3) + rofs, 0, 255); - uint32_t g = bound(((rgb & 0x03E0) >> 2) + gofs, 0, 255); - uint32_t b = bound(((rgb & 0x7C00) >> 7) + bofs, 0, 255); - vertices[y*2+0].color = 0xFF000000 | r | g<<8 | b<<16; - vertices[y*2+0].x = 0; - vertices[y*2+0].y = y; - vertices[y*2+0].z = 0; - vertices[y*2+1].color = 0xFF000000 | r | g<<8 | b<<16; - vertices[y*2+1].x = disp_width >> disp_xscale; - vertices[y*2+1].y = y; - vertices[y*2+1].z = 0; - } - } - guDrawArray(GU_LINES, - GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - num_vertices, NULL, vertices); - guCommit(); - } else { - /* Single color for the whole screen */ - vertices = pspGuGetMemoryMerge(sizeof(*vertices) * 2); - uint16_t rgb = T1ReadWord(Vdp2Ram, address); - uint32_t r = bound(((rgb & 0x001F) << 3) + rofs, 0, 255); - uint32_t g = bound(((rgb & 0x03E0) >> 2) + gofs, 0, 255); - uint32_t b = bound(((rgb & 0x7C00) >> 7) + bofs, 0, 255); - vertices[0].color = 0xFF000000 | r | g<<8 | b<<16; - vertices[0].x = 0; - vertices[0].y = 0; - vertices[0].z = 0; - vertices[1].color = 0xFF000000 | r | g<<8 | b<<16; - vertices[1].x = disp_width >> disp_xscale; - vertices[1].y = disp_height >> disp_yscale; - vertices[1].z = 0; - guDrawArray(GU_SPRITES, - GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, - 2, NULL, vertices); - guCommit(); - } -} - -/*************************************************************************/ - -/** - * vdp2_draw_graphics: Draw a single VDP2 background graphics layer. - * - * [Parameters] - * layer: Background graphics layer (BG_* constant) - * [Return value] - * None - */ -static void vdp2_draw_graphics(int layer) -{ - vdp2draw_struct info; - clipping_struct clip[2]; - - /* Is this background layer enabled? */ - if (!(Vdp2Regs->BGON & Vdp2External.disptoggle & (1 << layer))) { - return; - } - if (layer == BG_RBG0 && !config_get_enable_rotate()) { - return; - } - - /* Check whether we should smooth the graphics. */ - const int smooth_hires = - (disp_width > 352 || disp_height > 272) && config_get_smooth_hires(); - - /* Find out whether it's a bitmap or not. */ - switch (layer) { - case BG_NBG0: info.isbitmap = Vdp2Regs->CHCTLA & 0x0002; break; - case BG_NBG1: info.isbitmap = Vdp2Regs->CHCTLA & 0x0200; break; - case BG_RBG0: info.isbitmap = Vdp2Regs->CHCTLB & 0x0200; break; - default: info.isbitmap = 0; break; - } - - /* Determine color-related data. */ - info.transparencyenable = !(Vdp2Regs->BGON & (0x100 << layer)); - /* FIXME: specialprimode is not actually supported by the map drawing - * functions */ - info.specialprimode = (Vdp2Regs->SFPRMD >> (2*layer)) & 3; - switch (layer) { - case BG_NBG0: - info.colornumber = (Vdp2Regs->CHCTLA & 0x0070) >> 4; - break; - case BG_NBG1: - info.colornumber = (Vdp2Regs->CHCTLA & 0x3000) >> 12; - break; - case BG_NBG2: - info.colornumber = (Vdp2Regs->CHCTLB & 0x0002) >> 1; - break; - case BG_NBG3: - info.colornumber = (Vdp2Regs->CHCTLB & 0x0020) >> 5; - break; - case BG_RBG0: - info.colornumber = (Vdp2Regs->CHCTLB & 0x7000) >> 12; - break; - } - if (Vdp2Regs->CCCTL & (1 << layer)) { - const uint8_t *ptr = (const uint8_t *)&Vdp2Regs->CCRNA; - info.alpha = ((~ptr[layer] & 0x1F) << 3) + 7; - } else { - info.alpha = 0xFF; - } - if (layer == BG_RBG0) { - info.coloroffset = (Vdp2Regs->CRAOFB & 7) << 8; - } else { - info.coloroffset = ((Vdp2Regs->CRAOFA >> (4*layer)) & 7) << 8; - } - vdp2_get_color_offsets(1 << layer, (int32_t *)&info.cor, - (int32_t *)&info.cog, (int32_t *)&info.cob); - - /* Extract rotation information for RBG0. */ - if (layer == BG_RBG0) { - switch (Vdp2Regs->RPMD & 3) { - case 0: - info.rotatenum = 0; - info.rotatemode = 0; - break; - case 1: - info.rotatenum = 1; - info.rotatemode = 0; - break; - case 2: - info.rotatenum = 0; - info.rotatemode = 1; - break; - case 3: - info.rotatenum = 0; - info.rotatemode = 2; - break; - } - } - - /* Determine tilemap/bitmap size and display offset. */ - if (info.isbitmap) { - if (layer == BG_RBG0) { - ReadBitmapSize(&info, Vdp2Regs->CHCTLB >> 10, 0x3); - info.charaddr = ((Vdp2Regs->MPOFR >> (4*info.rotatenum)) & 7) << 17; - info.paladdr = (Vdp2Regs->BMPNB & 0x7) << 4; - } else { - ReadBitmapSize(&info, Vdp2Regs->CHCTLA >> (2 + layer*8), 0x3); - info.charaddr = ((Vdp2Regs->MPOFN >> (4*layer)) & 7) << 17; - info.paladdr = ((Vdp2Regs->BMPNA >> (8*layer)) & 7) << 4; - } - info.flipfunction = 0; - info.specialfunction = 0; - switch (layer) { - case BG_NBG0: - info.x = - ((Vdp2Regs->SCXIN0 & 0x7FF) % info.cellw); - info.y = - ((Vdp2Regs->SCYIN0 & 0x7FF) % info.cellh); - break; - case BG_NBG1: - info.x = - ((Vdp2Regs->SCXIN1 & 0x7FF) % info.cellw); - info.y = - ((Vdp2Regs->SCYIN1 & 0x7FF) % info.cellh); - break; - case BG_RBG0: - /* Transformation is handled separately; nothing to do here. */ - break; - default: - DMSG("info.isbitmap set for invalid layer %d", layer); - return; - } - } else { - if (layer == BG_RBG0) { - info.mapwh = 4; - ReadPlaneSize(&info, Vdp2Regs->PLSZ >> (8 + 4*info.rotatenum)); - } else { - info.mapwh = 2; - ReadPlaneSize(&info, Vdp2Regs->PLSZ >> (2*layer)); - } - const int scx_mask = (512 * info.planew * info.mapwh) - 1; - const int scy_mask = (512 * info.planeh * info.mapwh) - 1; - switch (layer) { - case BG_NBG0: - info.x = - (Vdp2Regs->SCXIN0 & scx_mask); - info.y = - (Vdp2Regs->SCYIN0 & scy_mask); - ReadPatternData(&info, Vdp2Regs->PNCN0, Vdp2Regs->CHCTLA & 0x0001); - break; - case BG_NBG1: - info.x = - (Vdp2Regs->SCXIN1 & scx_mask); - info.y = - (Vdp2Regs->SCYIN1 & scy_mask); - ReadPatternData(&info, Vdp2Regs->PNCN1, Vdp2Regs->CHCTLA & 0x0100); - break; - case BG_NBG2: - info.x = - (Vdp2Regs->SCXN2 & scx_mask); - info.y = - (Vdp2Regs->SCYN2 & scy_mask); - ReadPatternData(&info, Vdp2Regs->PNCN2, Vdp2Regs->CHCTLB & 0x0001); - break; - case BG_NBG3: - info.x = - (Vdp2Regs->SCXN3 & scx_mask); - info.y = - (Vdp2Regs->SCYN3 & scy_mask); - ReadPatternData(&info, Vdp2Regs->PNCN3, Vdp2Regs->CHCTLB & 0x0010); - break; - case BG_RBG0: - ReadPatternData(&info, Vdp2Regs->PNCR, Vdp2Regs->CHCTLB & 0x0100); - break; - } - } - - /* Determine coordinate scaling. */ - // FIXME: scaled graphics may be distorted because integers are used - // for vertex coordinates - switch (layer) { - case BG_NBG0: - info.coordincx = 65536.0f / (Vdp2Regs->ZMXN0.all & 0x7FF00 ?: 65536); - info.coordincy = 65536.0f / (Vdp2Regs->ZMYN0.all & 0x7FF00 ?: 65536); - break; - case BG_NBG1: - info.coordincx = 65536.0f / (Vdp2Regs->ZMXN1.all & 0x7FF00 ?: 65536); - info.coordincy = 65536.0f / (Vdp2Regs->ZMYN1.all & 0x7FF00 ?: 65536); - break; - default: - info.coordincx = info.coordincy = 1; - break; - } - if (disp_xscale == 1) { - info.coordincx /= 2; - } - if (disp_yscale == 1) { - info.coordincy /= 2; - } - - /* Get clipping data. */ - info.wctl = ((uint8_t *)&Vdp2Regs->WCTLA)[layer]; - clip[0].xstart = 0; clip[0].xend = disp_width; - clip[0].ystart = 0; clip[0].yend = disp_height; - clip[1].xstart = 0; clip[1].xend = disp_width; - clip[1].ystart = 0; clip[1].yend = disp_height; - ReadWindowData(info.wctl, clip); - - /* Check for a zero-size clip window, which some games seem to use to - * temporarily disable a screen. */ - if (clip[0].xstart >= clip[0].xend - || clip[0].ystart >= clip[0].yend - || clip[1].xstart >= clip[1].xend - || clip[1].ystart >= clip[1].yend - ) { - return; - } - - info.priority = bg_priority[layer]; - switch (layer) { - case BG_NBG0: info.PlaneAddr = (void *)Vdp2NBG0PlaneAddr; break; - case BG_NBG1: info.PlaneAddr = (void *)Vdp2NBG1PlaneAddr; break; - case BG_NBG2: info.PlaneAddr = (void *)Vdp2NBG2PlaneAddr; break; - case BG_NBG3: info.PlaneAddr = (void *)Vdp2NBG3PlaneAddr; break; - case BG_RBG0: if (info.rotatenum == 0) { - info.PlaneAddr = (void *)Vdp2ParameterAPlaneAddr; - } else { - info.PlaneAddr = (void *)Vdp2ParameterBPlaneAddr; - } - break; - default: DMSG("No PlaneAddr for layer %d", layer); return; - } - info.patternpixelwh = 8 * info.patternwh; - info.draww = (int)((float)(disp_width >> disp_xscale) / info.coordincx); - info.drawh = (int)((float)(disp_height >> disp_yscale) / info.coordincy); - - /* Set up for rendering. */ - guEnable(GU_TEXTURE_2D); - guAmbientColor(info.alpha<<24 | 0xFFFFFF); - if (smooth_hires) { - guTexFilter(GU_LINEAR, GU_LINEAR); - } - - /* If a custom drawing function has been specified for this layer, call - * it first. */ - int custom_draw_succeeded = 0; - if (custom_draw_func[layer]) { - custom_draw_succeeded = (*custom_draw_func[layer])(&info, clip); - if (custom_draw_succeeded && layer == BG_RBG0) { - drew_slow_RBG0 = !RBG0_draw_func_is_fast; - } - } - - if (!custom_draw_succeeded) { - - /* Select a rendering function based on the tile layout and format. */ - void (*draw_map_func)(vdp2draw_struct *info, - const clipping_struct *clip); - if (layer == BG_RBG0) { - draw_map_func = &vdp2_draw_map_rotated; - } else if (info.isbitmap) { - switch (layer) { - case BG_NBG0: - if ((Vdp2Regs->SCRCTL & 7) == 7) { - DMSG("WARNING: line scrolling not supported"); - } - /* fall through */ - case BG_NBG1: - if (info.colornumber == 1 && !smooth_hires) { - draw_map_func = &vdp2_draw_bitmap_t8; - } else if (info.colornumber == 4 && !smooth_hires - && info.coordincx == 1 && info.coordincy == 1) { - draw_map_func = &vdp2_draw_bitmap_32; - } else { - draw_map_func = &vdp2_draw_bitmap; - } - break; - default: - DMSG("info.isbitmap set for invalid layer %d", layer); - return; - } - } else if (info.patternwh == 2) { - if (info.colornumber == 1 && !smooth_hires) { - draw_map_func = &vdp2_draw_map_16x16_t8; - } else { - draw_map_func = &vdp2_draw_map_16x16; - } - } else { - if (info.colornumber == 1 && !smooth_hires) { - draw_map_func = &vdp2_draw_map_8x8_t8; - } else { - draw_map_func = &vdp2_draw_map_8x8; - } - } - - /* Render the graphics. */ - (*draw_map_func)(&info, clip); - if (layer == BG_RBG0) { - drew_slow_RBG0 = 1; - } - - } // if (!custom_draw_succeeded) - - /* All done. */ - if (smooth_hires) { - guTexFilter(GU_NEAREST, GU_NEAREST); - } - guAmbientColor(0xFFFFFFFF); - guDisable(GU_TEXTURE_2D); - guCommit(); -} - -/*************************************************************************/ -/***** Utility routines exported to background graphics drawing code *****/ -/*************************************************************************/ - -/* Last block allocated with pspGuGetMemoryMerge() */ -static void *merge_last_ptr; -static uint32_t merge_last_size; - -/*-----------------------------------------------------------------------*/ - -/** - * pspGuGetMemoryMerge: Acquire a block of memory from the GE display - * list. Similar to sceGuGetMemory(), but if the most recent display list - * operation was also a pspGuGetMemoryMerge() call, merge the two blocks - * together to avoid long chains of jump instructions in the display list. - * - * [Parameters] - * size: Size of block to allocate, in bytes - * [Return value] - * Allocated block - */ -void *pspGuGetMemoryMerge(uint32_t size) -{ - /* Make sure size is 32-bit aligned. */ - size = (size + 3) & -4; - - /* Start off by allocating the block normally. Ideally, we'd check - * first whether the current list pointer is immediately past the last - * block allocated, but since there's apparently no interface for - * either getting the current pointer or deleting the last instruction, - * we're out of luck and can't save the 8 bytes taken by the jump, even - * if we end up not needing it. */ - void *ptr = guGetMemory(size); - - /* If the pointer we got back is equal to the end of the previously - * allocated block plus 8 bytes (2 GU instructions), we can merge. */ - if ((uint8_t *)ptr == (uint8_t *)merge_last_ptr + merge_last_size + 8) { - /* Make sure the instruction before the last block really is a - * jump instruction before we update it. */ - uint32_t *jump_ptr = (uint32_t *)merge_last_ptr - 1; - if (*jump_ptr >> 24 == 0x08) { - void *block_end = (uint8_t *)ptr + size; - *jump_ptr = 0x08<<24 | ((uintptr_t)block_end & 0xFFFFFF); - merge_last_size = (uint8_t *)block_end - (uint8_t *)merge_last_ptr; - return ptr; - } - } - - /* We couldn't merge, so reset the last-block-allocated variables and - * return the block we allocated above. */ - merge_last_ptr = ptr; - merge_last_size = size; - return ptr; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/psp-video.h b/yabause/src/psp/psp-video.h deleted file mode 100644 index a9629c5848..0000000000 --- a/yabause/src/psp/psp-video.h +++ /dev/null @@ -1,154 +0,0 @@ -/* src/psp/psp-video.h: PSP video interface module header - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_VIDEO_H -#define PSP_VIDEO_H - -#include "../vdp1.h" // for VideoInterface_struct - -/*************************************************************************/ -/********* Module interface and global-use routine declarations **********/ -/*************************************************************************/ - -/* Module interface definition */ -extern VideoInterface_struct VIDPSP; - -/* Unique module ID (must be different from any in ../{vdp1,vid*}.h) */ -#define VIDCORE_PSP 0x5CE // "SCE" - -/*************************************************************************/ - -/** - * psp_video_infoline: Display an information line on the bottom of the - * screen. The text will be displayed for one frame only; call this - * function every frame to keep the text visible. - * - * [Parameters] - * color: Text color (0xAABBGGRR) - * text: Text string - * [Return value] - * None - */ -extern void psp_video_infoline(uint32_t color, const char *text); - -/*************************************************************************/ -/************ Internal utility data and routine declarations *************/ -/*************************************************************************/ - -/* Vertex data structure for GU drawing */ - -typedef struct VertexUVXYZ_ { - int16_t u, v; - int16_t x, y, z; -} VertexUVXYZ; - -/*************************************************************************/ - -/** - * global_clut_16, global_clut_32: Global color lookup table (from VDP2 - * color RAM), in 16- and 32-bit formats. Each array is indexed by the - * color index value used in sprites and tiles; when the VDP2 is in 32-bit - * color mode (Vdp2Internal.ColorMode == 2), indices 0x400-0x7FF are a - * copy of 0x000-0x3FF. In all cases, the alpha values are set to full - * (1 or 0xFF). - */ -extern uint16_t global_clut_16[0x800]; -extern uint32_t global_clut_32[0x800]; - -/*-----------------------------------------------------------------------*/ - -/** - * adjust_color_16_32: Adjust the components of a 16-bit color value, - * returning it as a 32-bit color value. - * - * [Parameters] - * color: 16-bit color value (A1B5G5R5) - * rofs: Red component offset - * gofs: Green component offset - * bofs: Blue component offset - * [Return value] - * Converted and djusted 32-bit color value - */ -static inline uint32_t adjust_color_16_32(uint16_t color, int32_t rofs, - int32_t gofs, int32_t bofs) -{ - int32_t r = color<<3 & 0xF8; - int32_t g = color>>2 & 0xF8; - int32_t b = color>>7 & 0xF8; - return bound(r+rofs, 0, 255) << 0 - | bound(g+gofs, 0, 255) << 8 - | bound(b+bofs, 0, 255) << 16 - | (color>>15 ? 0xFF000000 : 0); -} - -/*-----------------------------------------------------------------------*/ - -/** - * adjust_color_32_32: Adjust the components of a 32-bit color value. - * - * [Parameters] - * color: 32-bit color value (ABGR) - * rofs: Red component offset - * gofs: Green component offset - * bofs: Blue component offset - * [Return value] - * Adjusted 32-bit color value - */ -static inline uint32_t adjust_color_32_32(uint32_t color, int32_t rofs, - int32_t gofs, int32_t bofs) -{ - int32_t r = color>> 0 & 0xFF; - int32_t g = color>> 8 & 0xFF; - int32_t b = color>>16 & 0xFF; - return bound(r+rofs, 0, 255) << 0 - | bound(g+gofs, 0, 255) << 8 - | bound(b+bofs, 0, 255) << 16 - | (color & 0xFF000000); -} - -/*************************************************************************/ - -/** - * pspGuGetMemoryMerge: Acquire a block of memory from the GE display - * list. Similar to sceGuGetMemory(), but if the most recent display list - * operation was also a pspGuGetMemoryMerge() call, merge the two blocks - * together to avoid long chains of jump instructions in the display list. - * - * [Parameters] - * size: Size of block to allocate, in bytes - * [Return value] - * Allocated block - */ -void *pspGuGetMemoryMerge(uint32_t size); - -/*************************************************************************/ -/*************************************************************************/ - -#endif // PSP_VIDEO_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/rtl-internal.h b/yabause/src/psp/rtl-internal.h deleted file mode 100644 index f08bc6ccce..0000000000 --- a/yabause/src/psp/rtl-internal.h +++ /dev/null @@ -1,712 +0,0 @@ -/* src/psp/rtl-internal.h: Internal-use declarations for RTL - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef RTL_INTERNAL_H -#define RTL_INTERNAL_H - -/*************************************************************************/ -/************************* Configuration options *************************/ -/*************************************************************************/ - -/*============ General options ============*/ - -/** - * INSNS_EXPAND_SIZE: Specifies the number of instructions by which to - * expand a block's instruction array when the array is full. This value - * is also used for the initial size of the array. - */ -#define INSNS_EXPAND_SIZE 1000 - -/** - * UNITS_EXPAND_SIZE: Specifies the number of instructions by which to - * expand a block's instruction array when the array is full. This value - * is also used for the initial size of the array. - */ -#define UNITS_EXPAND_SIZE 100 - -/** - * REGS_EXPAND_SIZE: Specifies the number of register entries by which to - * expand a block's register array when the array is full. This value is - * also used for the initial size of the array. - */ -#define REGS_EXPAND_SIZE 1000 - -/** - * REGS_LIMIT: Specifies the maximum number of registers allowed for a - * single block. Must be no greater than 65535 (because this value must - * fit into a uint16_t). The actual number of available registers is one - * less than this value, since register 0 is never used. - */ -#define REGS_LIMIT 65535 - -/** - * LABELS_EXPAND_SIZE: Specifies the number of entries by which to expand - * a block's label-to-unit mapping array when the array is full. This - * value is also used for the initial size of the array. - */ -#define LABELS_EXPAND_SIZE 100 - -/** - * LABELS_LIMIT: Specifies the maximum number of labels allowed for a - * single block. Must be no greater than 65535 (because this value must - * fit into a uint16_t). The actual number of available labels is one less - * than this value, since label 0 is never used. - */ -#define LABELS_LIMIT 65535 - -/** - * NATIVE_EXPAND_SIZE: Specifies the block size (in bytes) by which to - * expand the native code buffer as necessary when translating. - */ -#define NATIVE_EXPAND_SIZE 8192 - -/*============ MIPS-specific options ============*/ - -/** - * MIPS_FRAME_SIZE: The stack frame size to use in generated native code, - * in bytes. This does not include space reserved for saving registers in - * the function prologue. - */ -#define MIPS_FRAME_SIZE 64 - -/** - * MIPS_OPTIMIZE_MERGE_CONSTANTS: When defined, RTL registers with - * identical constant values whose live ranges overlap will share the same - * hardware register. Hardware registers will also be reused if a value - * loaded for a previously-used constant is still available after the - * constant has died. - */ -#define MIPS_OPTIMIZE_MERGE_CONSTANTS - -/** - * MIPS_OPTIMIZE_IMMEDIATE: When defined, the translator will optimize a - * LOAD_IMM instruction followed by one of: - * ADD, SUB, AND, OR, XOR, SLL, SRL, SRA, SLTU, SLTS - * which uses the LOAD_IMM target as its second operand into the equivalent - * MIPS immediate instruction if the immediate operand is within range and - * is not used elsewhere. Similarly, LOAD_NATIVEADDR followed by a memory - * load or store operation will be optimized if possible to insert the low - * 16 bits of the address into the load/store instruction, allowing the - * base register to be loaded with a single MIPS LUI instruction. - */ -#define MIPS_OPTIMIZE_IMMEDIATE - -/** - * MIPS_OPTIMIZE_ABSOLUTE_CALL: When defined, the translator will optimize - * a LOAD_NATIVEADDR instruction followed by a CALL_NATIVE instruction into - * a MIPS JAL instruction to the address specified by the constant register. - * - * ==== PORTABILITY WARNING ==== - * - * This optimization is NOT guaranteed to be portable across different - * platforms! The MIPS JAL instruction only allows the low 28 bits of the - * target address to be specified, and takes the high bits from the current - * PC. We could theoretically check the target address against the address - * of the JAL instruction when we add it, but since the address of the - * native code block may change as it is expanded, we cannot guarantee at - * the time we add the JAL instruction that the target address is reachable. - * - * That said, on (at least current iterations of) the PSP, the upper bits - * of addresses for both code and data are always zero, so we can safely - * optimize jumps to constant addresses. - */ -#define MIPS_OPTIMIZE_ABSOLUTE_CALL - -/** - * MIPS_OPTIMIZE_DELAY_SLOT: When defined, the translator will move the - * instruction preceding a branch or jump instruction into the branch's - * delay slot, if possible. - */ -#define MIPS_OPTIMIZE_DELAY_SLOT - -/** - * MIPS_OPTIMIZE_BRANCHES: When defined, the translator will perform the - * following optimizations on branches: - * - * - A branch to another (unconditional) branch will be chained through to - * the final branch target, unless that target would be outside the range - * of a branch instruction. - * - * - When a branch has a NOP instruction in its delay slot, the instruction - * at the target address will be copied over the NOP, the branch will be - * changed to a Likely branch if it is conditional (e.g. BEQ becomes - * BEQL), and the branch target will be incremented by one instruction. - * (The optimization is not performed if the branch target is already at - * the positive branch offset limit.) - */ -#define MIPS_OPTIMIZE_BRANCHES - -/** - * MIPS_OPTIMIZE_SCHEDULING: When defined, the translator will attempt to - * reschedule load, multiply, and divide instructions to avoid stalls. - */ -#define MIPS_OPTIMIZE_SCHEDULING - -/** - * MIPS_OPTIMIZE_SEX: When defined, the translator will optimize SLL/SRA - * pairs to SEB or SEH when possible: - * - * LOAD_IMM rD,24 - * SLL rB,rA,rD - * LOAD_IMM rE,24 - * SRA rC,rB,rE --> seb $rC,$rA [assuming rB is otherwise unused] - * - * LOAD_IMM rD,16 - * SLL rB,rA,rD - * LOAD_IMM rE,16 - * SRA rC,rB,rE --> seh $rC,$rA [assuming rB is otherwise unused] - * - * SLLI/SRAI pairs are similarly optimized. - */ -#define MIPS_OPTIMIZE_SEX - -/** - * MIPS_OPTIMIZE_MIN_MAX: When defined, the translator will optimize - * SLTS/SELECT pairs to MIN or MAX when possible: - * - * SLTS rC, rA, rB - * SELECT rD, rA, rB, rC --> min $rD, $rA, $rB - * - * SLTS rC, rA, rB - * SELECT rD, rB, rA, rC --> max $rD, $rA, $rB - * - * (both assuming register rC is otherwise unused). - */ -#define MIPS_OPTIMIZE_MIN_MAX - -/*============ Debugging options ============*/ - -/** - * OPERAND_SANITY_CHECKS: If defined, causes rtl_add_insn() to check that - * register and label operands are within allowable ranges. - * - * This option is meaningless if CHECK_PRECONDITIONS is not defined. - */ -#define OPERAND_SANITY_CHECKS - -/** - * CHECK_PRECONDITIONS: If defined, causes functions to check that their - * preconditions are satisfied and return (with an error if appropriate) - * if not. This can add a significant amount of overhead. - */ -// #define CHECK_PRECONDITIONS - -/** - * RTL_TRACE_GENERATE: Trace the generation of RTL blocks and instructions. - */ -// #define RTL_TRACE_GENERATE - -/** - * RTL_TRACE_EXECUTE: Trace the execution of RTL instructions in - * rtl_execute_block(). - */ -// #define RTL_TRACE_EXECUTE - -/** - * RTL_TRACE_STEALTH_FOR_SH2: Enable SH-2 stealth tracing (see the - * documentation for TRACE_STEALTH in sh2.c). - */ -#define RTL_TRACE_STEALTH_FOR_SH2 - -/*************************************************************************/ -/*************************** Type declarations ***************************/ -/*************************************************************************/ - -#undef mips // Avoid namespace pollution from the compiler on MIPS machines - -/*-----------------------------------------------------------------------*/ - -/** - * RTLInsn: A single platform-neutral (more or less) operation. SH-2 - * instructions are translated into sequences of RTLInsns, which are then - * optimized and retranslated into MIPS instructions. - */ -typedef struct RTLInsn_ { - uint8_t opcode; // Operation code (RTLOpcode) - uint16_t dest; // Destination register - uint16_t src1, src2; // Source registers - union { - uint16_t dest2; // Second output register (for MULU_64, etc.) - uint16_t cond; // Condition register for SELECT - struct { - uint8_t start; // First (lowest) bit number for a bitfield - uint8_t count; // Number of bits for a bitfield - } bitfield; - int16_t offset; // Byte offset for load/store instructions - uint16_t label; // GOTO target label - uint16_t target; // CALL_NATIVE branch target register - uint32_t src_imm; // Source immediate value - uintptr_t src_addr; // Source native address value - }; -} RTLInsn; - -/*----------------------------------*/ - -/** - * RTLRegType: The type (source information) of a register used in an RTL - * block. - */ -typedef enum RTLRegType_ { - RTLREG_UNDEFINED = 0, // Not yet defined to anything - RTLREG_CONSTANT, // Constant value (RTLRegister.value) - RTLREG_PARAMETER, // Function parameter (.param_index) - RTLREG_MEMORY, // Memory reference - RTLREG_RESULT, // Result of an operation on other registers - RTLREG_RESULT_NOFOLD, // Result of an operation (not constant foldable) - RTLREG_UNKNOWN, // Source unknown (e.g. due to reassignment) -} RTLRegType; - -/** - * RTLRegister: Data about registers used in an RTL block. All registers - * are 32 bits wide. - */ -typedef struct RTLRegister_ RTLRegister; -struct RTLRegister_ { - /* Basic register information */ - uint8_t source; // Register source (RTLRegType) - uint8_t live; // Nonzero if this register has been referenced - // (this field is never cleared once set) - uint16_t live_link; // Next register in live list (sorted by birth) - uint32_t birth; // First RTL insn index when register is live - // (if SSA, insn index where it's assigned) - uint32_t death; // Last RTL insn index when register is live - - /* Unique pointer information. The "unique_pointer" field has the - * property that all registers with the same nonzero value for - * "unique_pointer" are native addresses which point to the same region - * of memory, and that region of memory will only be accessed through - * a register with the same "unique_pointer" value. */ - uint16_t unique_pointer; - - /* Register value information */ - union { - uintptr_t value; // Value of register for RTLREG_CONSTANT; - // also used during interpreted execution - unsigned int param_index;// Function parameter idx for RTLREG_PARAMETER - struct { - uint16_t addr_reg; // Register holding address for RTLREG_MEMORY - int16_t offset; // Access offset - uint8_t size; // Access size in bytes (1, 2, 4; or 8 if a - // pointer, regardless of actual size) - uint8_t is_signed; // Nonzero if a signed load, zero if unsigned - } memory; - struct { - uint8_t opcode; // Operation code for RTLREG_RESULT - uint8_t second_res:1; // "Second result" flag (high word of - // MUL[US]_64, remainder of DIVMOD[US]) - uint8_t is_imm:1; // Nonzero if a register-immediate operation - uint16_t src1; // Operand 1 - union { - struct { - uint16_t src2; // Op 2 for register-register operations - union { - uint16_t cond; // Condition register for SELECT - struct { - uint8_t start; // Start bit for bitfields - uint8_t count; // Bit count for bitfields - }; - }; - }; - uint32_t imm; // Operand 2 for register-immediate operations - }; - } result; - }; - - /* The following fields are for use by RTL-to-native translators: */ - uint32_t last_used; // Last insn index where this register was used - uint8_t native_allocated; // Nonzero if a native reg has been allocated - uint8_t native_reg; // Native register allocated for this register - uint8_t frame_allocated; // Nonzero if a frame slot has been allocated - uint8_t frame_slot; // Frame slot allocated for this register - int16_t stack_offset; // Stack offset of this register's frame slot - RTLRegister *next_merged; // Next register in merge chain, or NULL - union { - struct { - /* If nonzero, this field contains the opcode to retrieve the - * register's value from the MIPS HI or LO register (either - * MIPS_MFHI(0) or MIPS_MFLO(0)) */ - uint32_t is_in_hilo; - } mips; - }; -}; - -/*----------------------------------*/ - -/** - * RTLUnit: Information about an basic unit of code (a sequence of - * instructions with one entry point and one exit point). Note that a unit - * can be empty, denoted by last_insn < first_insn, and that last_insn can - * be negative, if first_insn is 0 and the unit is empty. - */ -typedef struct RTLUnit_ { - int32_t first_insn; // block->insns[] index of first insn in unit - int32_t last_insn; // block->insns[] index of last insn in unit - int16_t next_unit; // block->units[] index of next unit in code - // stream (may not be the sequentially next - // unit in the array due to optimization); - // -1 indicates the end of the code stream - int16_t prev_unit; // block->units[] index of previous unit in - // code stream - int16_t entries[8]; // block->units[] indices of dominating units; - // -1 indicates an unused slot. Holes in - // the list are not permitted; for more - // than 8 slots, add a dummy unit on top - // (rtlunit_*() functions handle all this) - int16_t exits[2]; // block->units[] indices of postdominating - // units. A terminating insn can go at - // most two places (conditional GOTO). - - /* These fields are provided as hints to RTL-to-native translators: */ - int16_t next_call_unit; // Next unit with a CALL_NATIVE insn (-1=none) - int16_t prev_call_unit; // Prev. unit with a CALL_NATIVE insn (-1=none) - - /* The following fields are used only by RTL-to-native translators: */ - union { - struct { - /* Register and stack frame state at the beginning of the unit */ - RTLRegister *reg_map[32]; // MIPS-to-RTL register map - RTLRegister *frame_map[MIPS_FRAME_SIZE/4]; // Stack frame reg map - } mips; - }; -} RTLUnit; - -/*----------------------------------*/ - -/** - * RTLBlock: State information used in translating a block of code. The - * RTLBlock type itself is defined in rtl.h. - */ -struct RTLBlock_ { - RTLInsn *insns; // Instruction array - int16_t *insn_unitmap; // Insn-to-unit mapping (used by interpreter) - uint32_t insns_size; // Size of instruction array (entries) - uint32_t num_insns; // Number of instructions actually in array - - RTLUnit *units; // Basic unit array - uint16_t units_size; // Size of unit array (entries) - uint16_t num_units; // Number of units actually in array - uint8_t have_unit; // Nonzero if there is a currently active unit - uint16_t cur_unit; // Current unit index if have_unit != 0 - - int16_t *label_unitmap; // Label-to-unit-index mapping (-1 = unset) - uint16_t labels_size; // Size of label-to-unit map array (entries) - uint16_t next_label; // Next label number to allocate - - RTLRegister *regs; // Register array - uint16_t regs_size; // Size of register array (entries) - uint16_t next_reg; // Next register number to allocate - uint16_t first_live_reg; // First register in live range list - uint16_t last_live_reg; // Last register in live range list - uint16_t unique_pointer_index; // Next value for RTLRegister.unique_pointer - - uint8_t finalized; // Nonzero if block has been finalized - - /* These fields are provided as hints to RTL-to-native translators: */ - int16_t first_call_unit; // First unit with a CALL_NATIVE insn (-1=none) - int16_t last_call_unit; // Last unit with a CALL_NATIVE insn (-1=none) - - /* The following fields are used only by optimization routines: */ - uint8_t *unit_seen; // Array of "seen" flags for all units - // (used by rtlopt_drop_dead_units()) - - /* The following fields are used only by RTL-to-native translators: */ - void *native_buffer; // Native code buffer - uint32_t native_bufsize; // Allocated size of native code buffer - uint32_t native_length; // Length of native code - uint32_t *label_offsets; // Array of native offsets for labels - union { - struct { - uint8_t need_save_ra; // Nonzero = need to save/restore $ra - uint8_t need_chain_at; // Nonzero = need chain-to-$at epilogue - uint8_t frame_used; // Nonzero = 1 or more frame slots used - uint32_t sreg_used; // Bitmask of $sN registers used - uint32_t total_frame_size; // Frame size incl. space for $sN/$ra - RTLRegister *reg_map[32]; // MIPS-to-RTL register map - uint32_t reg_free; // Bitmask of free MIPS registers - uint32_t hi_reg, lo_reg; // RTL registers cached in HI and LO - RTLRegister *frame_map[MIPS_FRAME_SIZE/4]; // Stack frame reg map - uint32_t frame_free[((MIPS_FRAME_SIZE/4)+31)/32]; // Free slot mask - uint32_t unit_start; // Offset of first insn in current unit - struct { - uint8_t is_frame; // 0 = MIPS reg, 1 = frame slot - uint8_t index; // Register or frame slot index - int16_t next; // Next entry index or -1 for EOL - } active_list[32 + MIPS_FRAME_SIZE/4]; - int first_active; // First active entry, or -1 if none - int16_t next_call_unit; // Current position in call_unit chain - uint32_t epilogue_offset; // Start offset of epilogue code - uint32_t chain_offset; // Start offset of chain epilogue code - // (only valid if need_chain_at!=0) - } mips; - }; - -#ifdef RTL_TRACE_STEALTH_FOR_SH2 - uint32_t sh2_regcache[23]; // Cached values of SH-2 registers - uint32_t sh2_regcache_mask; // Bitmask of cached registers -#endif -}; - -/*************************************************************************/ -/***************************** Miscellaneous *****************************/ -/*************************************************************************/ - -/* We use the PRECOND() macro from common.h for precondition checking; if - * CHECK_PRECONDITIONS is _not_ defined, then redefine PRECOND() here to do - * nothing. */ - -#ifndef CHECK_PRECONDITIONS -# undef PRECOND -# define PRECOND(condition,fail_action) /*nothing*/ -#endif - -/*************************************************************************/ -/**************** Library-internal function declarations *****************/ -/*************************************************************************/ - -/**** Instruction encoding function declarations ****/ - -/* Internal table used by rtlinsn_make() */ -extern int (* const makefunc_table[])(RTLBlock *, RTLInsn *, unsigned int, - uintptr_t, uint32_t, uint32_t); - -/** - * rtlinsn_make: Fill in an RTLInsn structure based on the opcode stored - * in the structure and the parameters passed to the function. - * - * [Parameters] - * block: RTLBlock containing instruction - * insn: RTLInsn structure to fill in (insn->opcode must be set by caller) - * dest: Destination register for instruction - * src1: First source register or immediate value for instruction - * src2: Second source register or immediate value for instruction - * other: Extra register for instruction - * [Return value] - * Nonzero on success, zero on error - */ -static inline int rtlinsn_make(RTLBlock *block, RTLInsn *insn, - unsigned int dest, uintptr_t src1, - uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(insn->opcode >= RTLOP__FIRST && insn->opcode <= RTLOP__LAST, - return 0); - - /* Keep this check out of PRECOND() to try and avoid crashes even when - * CHECK_PRECONDITIONS is disabled; also, invert the sense and call the - * table function first so the parameter registers or stack frame - * aren't spilled by the DMSG() call in debug mode. */ - if (LIKELY(makefunc_table[insn->opcode])) { - return (*makefunc_table[insn->opcode])(block, insn, - dest, src1, src2, other); - } - DMSG("BUG: missing function for opcode %u", insn->opcode); - return 0; -} - - -/*-----------------------------------------------------------------------*/ - -/**** Optimization function declarations ****/ - -/** - * rtlopt_fold_constants: Perform constant folding on the given RTL block, - * converting instructions that operate on constant operands into load- - * immediate instructions that load the result of the operation. If such - * an operand is not used by any other instruction, the instruction that - * loaded it is changed to a NOP. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -extern int rtlopt_fold_constants(RTLBlock *block); - -/** - * rtlopt_decondition: Perform "deconditioning" of conditional branches - * with constant conditions. For "GOTO_IF_Z (GOTO_IF_NZ) label, rN" where - * rN is type RTLREG_CONSTANT, the instruction is changed to GOTO if the - * value of rN is zero (nonzero) and changed to NOP otherwise. As with - * constant folding, if the condition register is not used anywhere else, - * the register is eliminated and the instruction that loaded it is - * changed to a NOP. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -extern int rtlopt_decondition(RTLBlock *block); - -/** - * rtlopt_drop_dead_units: Search an RTL block for basic units which are - * unreachable via any path from the initial unit and remove them from the - * code stream. All units dominated only by such dead units are - * recursively removed as well. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -extern int rtlopt_drop_dead_units(RTLBlock *block); - -/** - * rtlopt_drop_dead_branches: Search an RTL block for branch instructions - * which branch to the next instruction in the code stream and replace them - * with NOPs. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -extern int rtlopt_drop_dead_branches(RTLBlock *block); - -/*-----------------------------------------------------------------------*/ - -/**** Basic unit processing function declarations ****/ - -/** - * rtlunit_add: Add a new, empty basic unit to the given block - * at the end of the block->units[] array. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on failure - */ -extern int rtlunit_add(RTLBlock *block); - -/** - * rtlunit_add_edge: Add a new edge between two basic units. - * - * [Parameters] - * block: RTL block - * from_index: Index of dominating basic unit (in block->units[]) - * to_index: Index of postdominating basic unit (in block->units[]) - * [Return value] - * Nonzero on success, zero on failure - */ -extern int rtlunit_add_edge(RTLBlock *block, unsigned int from_index, - unsigned int to_index); - -/** - * rtlunit_remove_edge: Remove an edge between two basic units. - * - * [Parameters] - * block: RTL block - * from_index: Index of dominating basic unit (in block->units[]) - * exit_index: Index of exit edge to remove (in units[from_index].exits[]) - * [Return value] - * None - */ -extern void rtlunit_remove_edge(RTLBlock *block, const unsigned int from_index, - unsigned int exit_index); - -/** - * rtlunit_dump_all: Dump a list of all basic units in the block to - * stderr. Intended for debugging. - * - * [Parameters] - * block: RTL block - * tag: Tag to prepend to all lines, or NULL for none - * [Return value] - * None - */ -extern void rtlunit_dump_all(const RTLBlock * const block, const char * const tag); - -/*-----------------------------------------------------------------------*/ - -/**** Architecture-specific translation function declarations ****/ - -/** - * rtl_translate_block_XXX: Translate the given block into native code for - * a particular architecture. - * - * [Parameters] - * block: RTLBlock to translate - * code_ret: Pointer to variable to receive code buffer pointer - * size_ret: Pointer to variable to receive code buffer size (in bytes) - * [Return value] - * Nonzero on success, zero on error - * [Notes] - * On error, *code_ret and *size_ret are not modified. - */ -extern int rtl_translate_block_mips(RTLBlock *block, void **code_ret, - uint32_t *size_ret); - -/*-----------------------------------------------------------------------*/ - -/**** Debugging-related functions ****/ - -#if defined(RTL_TRACE_GENERATE) || defined(RTL_TRACE_EXECUTE) - -/** - * rtl_decode_insn: Decode an RTL instruction into a human-readable - * string. - * - * [Parameters] - * block: RTLBlock containing instruction to decode - * index: Index of instruction to decode - * is_exec: Nonzero if being called from interpreted execution, else zero - * [Return value] - * Human-readable string describing the instruction - * [Notes] - * The returned string is stored in a static buffer which is - * overwritten on each call. - */ -extern const char *rtl_decode_insn(const RTLBlock *block, uint32_t index, int is_exec); - -/** - * rtl_describe_register: Generate a string describing the contents of the - * given RTL register. - * - * [Parameters] - * reg: Register to describe - * is_exec: Nonzero if being called from interpreted execution, else zero - * [Return value] - * Human-readable string describing the register - * [Notes] - * The returned string is stored in a static buffer which is - * overwritten on each call. - */ -extern const char *rtl_describe_register(const RTLRegister *reg, int is_exec); - -#endif // RTL_TRACE_GENERATE || RTL_TRACE_EXECUTE - -/*************************************************************************/ -/*************************************************************************/ - -#endif // RTL_INTERNAL_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/rtl-mips.c b/yabause/src/psp/rtl-mips.c deleted file mode 100644 index c8025b456c..0000000000 --- a/yabause/src/psp/rtl-mips.c +++ /dev/null @@ -1,4819 +0,0 @@ -/* src/psp/rtl-mips.c: RTL->MIPS translator used in dynamic translation - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ -/*************************** Required headers ****************************/ -/*************************************************************************/ - -#include "common.h" - -#include "rtl.h" -#include "rtl-internal.h" -#include "rtl-mips.h" - -#ifdef RTL_TRACE_STEALTH_FOR_SH2 -# include "sh2.h" -# include "sh2-internal.h" -#endif - -/*************************************************************************/ -/************************** Local declarations ***************************/ -/*************************************************************************/ - -/* Magic MIPS register index indicating that an RTL register is located in - * the stack frame and has no hardware register assigned */ -#define MIPS_noreg 32 - -/* List of caller-saved and callee-saved registers specified by the MIPS ABI. - * Note that we omit $at and $v1 from the caller-saved register list because - * we never assign them to RTL registers (they're only used to load values - * from the stack frame for use as instruction operands) */ -static const uint8_t caller_saved_regs[] = { - MIPS_v0, - MIPS_a0, MIPS_a1, MIPS_a2, MIPS_a3, - MIPS_t0, MIPS_t1, MIPS_t2, MIPS_t3, MIPS_t4, MIPS_t5, MIPS_t6, MIPS_t7, - MIPS_t8, MIPS_t9, -}; -static const uint8_t callee_saved_regs[] = { - MIPS_s0, MIPS_s1, MIPS_s2, MIPS_s3, MIPS_s4, MIPS_s5, MIPS_s6, - MIPS_s7, MIPS_s8, -}; - -/* Array of flags indicating which registers are caller-saved or callee-saved*/ -static const uint8_t reg_is_caller_saved[] = { - [MIPS_v1] = 1, - [MIPS_a0] = 1, [MIPS_a1] = 1, [MIPS_a2] = 1, [MIPS_a3] = 1, - [MIPS_t0] = 1, [MIPS_t1] = 1, [MIPS_t2] = 1, [MIPS_t3] = 1, - [MIPS_t4] = 1, [MIPS_t5] = 1, [MIPS_t6] = 1, [MIPS_t7] = 1, - [MIPS_t8] = 1, [MIPS_t9] = 1, -}; -static const uint8_t reg_is_callee_saved[] = { - [MIPS_s0] = 1, [MIPS_s1] = 1, [MIPS_s2] = 1, [MIPS_s3] = 1, - [MIPS_s4] = 1, [MIPS_s5] = 1, [MIPS_s6] = 1, [MIPS_s7] = 1, - [MIPS_s8] = 1, -}; - -/* Fake opcodes for branching to labels (to be resolved later) */ -#define __OP_BEQ_LABEL 074 // __OP_BEQ + 070 -#define __OP_BNE_LABEL 075 // __OP_BNE + 070 -#define MIPS_BEQ_LABEL(rs,rt,label) \ - __MIPS_INSN_IMM(BEQ_LABEL, (rs), (rt), (label)) -#define MIPS_BNE_LABEL(rs,rt,label) \ - __MIPS_INSN_IMM(BNE_LABEL, (rs), (rt), (label)) -#define MIPS_BEQZ_LABEL(reg,label) MIPS_BEQ_LABEL((reg), MIPS_zero, (label)) -#define MIPS_BNEZ_LABEL(reg,label) MIPS_BNE_LABEL((reg), MIPS_zero, (label)) -#define MIPS_B_LABEL(label) MIPS_BEQZ_LABEL(MIPS_zero, (label)) - -/* Fake opcode for jumping to the epilogue, returning a constant in $v0 */ -#define MIPS_B_EPILOGUE_RET_CONST __MIPS_SPECIAL(0, 0, 0, 1, JALR) - -/* Fake opcode for jumping to the epilogue, then chaining to the address - * in $at */ -#define MIPS_B_EPILOGUE_CHAIN_AT __MIPS_SPECIAL(0, 0, 0, 2, JALR) - -/*-----------------------------------------------------------------------*/ - -static int allocate_registers(RTLBlock * const block); -static inline int allocate_regs_unit(RTLBlock * const block, - const unsigned int unit_index); -static inline int allocate_regs_insn(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index); -static void add_to_active_list(RTLBlock * const block, const int is_frame, - const unsigned int index); -static void remove_from_active_list(RTLBlock * const block, const int is_frame, - const unsigned int index); -static void clean_active_list(RTLBlock * const block, - const uint32_t clean_insn); -static int allocate_one_register(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index, - const unsigned int reg_index); -static int allocate_one_register_prefer(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index, - const unsigned int reg_index, - const unsigned int prefer_mips); -static int merge_constant_register(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index, - const unsigned int reg_index); -static int allocate_frame_slot(RTLBlock * const block, - const uint32_t insn_index, - const unsigned int reg_index); -#ifdef MIPS_OPTIMIZE_IMMEDIATE -static int optimize_immediate(RTLBlock * const block, - const uint32_t insn_index); -#endif -#ifdef RTL_TRACE_GENERATE -static void print_regmap(RTLBlock * const block); -#endif - -/*----------------------------------*/ - -static int translate_block(RTLBlock * const block); -static inline int translate_unit(RTLBlock * const block, - const unsigned int unit_index); -static inline unsigned int translate_insn(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index); -static int append_alu_1op(RTLBlock * const block, const RTLInsn * const insn, - const uint32_t opcode); -static int append_alu_reg(RTLBlock * const block, const RTLInsn * const insn, - const uint32_t opcode); -static int append_shift_reg(RTLBlock * const block, const RTLInsn * const insn, - const uint32_t opcode); -static int append_mult_div(RTLBlock * const block, const RTLInsn * const insn, - const uint32_t opcode, const int accumulate, - const uint32_t insn_index); - -static int flush_for_call(RTLBlock * const block, const uint32_t insn_index); -static int reload_after_call(RTLBlock * const block, - const uint32_t insn_index); -static int flush_hilo(RTLBlock * const block, const uint32_t insn_index); - -#ifdef MIPS_OPTIMIZE_MIN_MAX -static int optimize_min_max(RTLBlock * const block, const uint32_t insn_index); -#endif - -#ifdef RTL_TRACE_STEALTH_FOR_SH2 -static unsigned int sh2_stealth_trace_insn(RTLBlock * const block, - const uint32_t insn_index); -static unsigned int sh2_stealth_cache_reg(RTLBlock * const block, - const uint32_t insn_index); -static unsigned int sh2_stealth_trace_store(RTLBlock * const block, - const uint32_t insn_index); -#endif - -static int resolve_branches(RTLBlock * const block); - -/*----------------------------------*/ - -static inline int append_insn(RTLBlock * const block, const uint32_t insn); -static int expand_block(RTLBlock * const block); -static uint32_t last_insn(const RTLBlock * const block); -static uint32_t pop_insn(RTLBlock * const block); - -static int append_float(RTLBlock * const block, const uint32_t insn, - const int latency); -static int append_branch(RTLBlock * const block, const uint32_t insn); - -static int append_prologue(RTLBlock * const block); -static int append_epilogue(RTLBlock * const block); - -/*----------------------------------*/ - -#ifdef __GNUC__ -# define CONST_FUNC __attribute__((const)) -#else -# define CONST_FUNC /*nothing*/ -#endif - -static CONST_FUNC inline int insn_rs(const uint32_t opcode); -static CONST_FUNC inline int insn_rt(const uint32_t opcode); -static CONST_FUNC inline int insn_rd(const uint32_t opcode); -static CONST_FUNC inline int insn_imm(const uint32_t opcode); - -static CONST_FUNC inline int insn_is_load(const uint32_t opcode); -static CONST_FUNC inline int insn_is_store(const uint32_t opcode); -static CONST_FUNC inline int insn_is_jump(const uint32_t opcode); -static CONST_FUNC inline int insn_is_branch(const uint32_t opcode); -static CONST_FUNC inline int insn_is_imm(const uint32_t opcode); -static CONST_FUNC inline int insn_is_imm_alu(const uint32_t opcode); -static CONST_FUNC inline int insn_is_special(const uint32_t opcode); -static CONST_FUNC inline int insn_is_regimm(const uint32_t opcode); -static CONST_FUNC inline int insn_is_allegrex(const uint32_t opcode); - -static CONST_FUNC inline uint32_t insn_regs_used(const uint32_t opcode); -static CONST_FUNC inline uint32_t insn_regs_set(const uint32_t opcode); - -/*************************************************************************/ - -#ifdef RTL_TRACE_STEALTH_FOR_SH2 - -/* Array for caching unflushed SH-2 register values (this assumes - * singlethreaded execution, but since this is only for debugging anyway - * let's not worry too hard about it) */ - -static uint32_t sh2_regcache[23]; - -/*----------------------------------*/ - -/* Set up common code blocks as constant arrays so we don't bloat the code - * too badly */ - -/* Save all caller-saved MIPS registers and the current state block - * register values on the stack; the state block pointer is assumed to be - * in $at */ -static const uint32_t code_save_regs_state[] = { - /* Add stack space for saving registers */ - MIPS_ADDIU(MIPS_sp, MIPS_sp, -(4*(18+24))), - /* First save all MIPS caller-saved registers */ - MIPS_SW(MIPS_v0, 0, MIPS_sp), - MIPS_SW(MIPS_v1, 4, MIPS_sp), - MIPS_SW(MIPS_a0, 8, MIPS_sp), - MIPS_SW(MIPS_a1, 12, MIPS_sp), - MIPS_SW(MIPS_a2, 16, MIPS_sp), - MIPS_SW(MIPS_a3, 20, MIPS_sp), - MIPS_SW(MIPS_t0, 24, MIPS_sp), - MIPS_SW(MIPS_t1, 28, MIPS_sp), - MIPS_SW(MIPS_t2, 32, MIPS_sp), - MIPS_SW(MIPS_t3, 36, MIPS_sp), - MIPS_SW(MIPS_t4, 40, MIPS_sp), - MIPS_SW(MIPS_t5, 44, MIPS_sp), - MIPS_SW(MIPS_t6, 48, MIPS_sp), - MIPS_SW(MIPS_t7, 52, MIPS_sp), - MIPS_SW(MIPS_t8, 56, MIPS_sp), - MIPS_SW(MIPS_t9, 60, MIPS_sp), - MIPS_MFLO(MIPS_v1), - MIPS_SW(MIPS_v1, 64, MIPS_sp), - MIPS_MFHI(MIPS_v1), - MIPS_SW(MIPS_v1, 68, MIPS_sp), - /* Copy the current register values in the SH-2 state block (which may - * not be up to date) to the stack */ - MIPS_MOVE(MIPS_a0, MIPS_at), - MIPS_ADDIU(MIPS_a1, MIPS_sp, 4*18), - MIPS_ADDIU(MIPS_a2, MIPS_a0, 4*23), - MIPS_LW(MIPS_v1, 0, MIPS_a0), - MIPS_ADDIU(MIPS_a0, MIPS_a0, 4), - MIPS_ADDIU(MIPS_a1, MIPS_a1, 4), - MIPS_BNE(MIPS_a0, MIPS_a2, -4), - MIPS_SW(MIPS_v1, -4, MIPS_a1), - /* Copy the current cycle count to the stack (leaving a copy in $v1) - * and return */ - MIPS_LW(MIPS_v1, offsetof(SH2State,cycles), MIPS_at), - MIPS_JR(MIPS_ra), - MIPS_SW(MIPS_v1, 0, MIPS_a1), -}; - -/* Restore all caller-saved MIPS registers and the current state block - * register values from the stack; the state block pointer is assumed to be - * in $at */ -static const uint32_t code_restore_regs_state[] = { - /* Restore values to the SH-2 state block */ - MIPS_MOVE(MIPS_a0, MIPS_at), - MIPS_ADDIU(MIPS_a1, MIPS_sp, 4*18), - MIPS_ADDIU(MIPS_a2, MIPS_a0, 4*23), - MIPS_LW(MIPS_v1, 0, MIPS_a1), - MIPS_ADDIU(MIPS_a0, MIPS_a0, 4), - MIPS_ADDIU(MIPS_a1, MIPS_a1, 4), - MIPS_BNE(MIPS_a0, MIPS_a2, -4), - MIPS_SW(MIPS_v1, -4, MIPS_a0), - MIPS_LW(MIPS_v1, 0, MIPS_a1), - MIPS_SW(MIPS_v1, offsetof(SH2State,cycles), MIPS_at), - /* Restore all MIPS caller-saved registers */ - MIPS_LW(MIPS_v1, 64, MIPS_sp), - MIPS_MTLO(MIPS_v1), - MIPS_LW(MIPS_v1, 68, MIPS_sp), - MIPS_MTHI(MIPS_v1), - MIPS_LW(MIPS_v0, 0, MIPS_sp), - MIPS_LW(MIPS_v1, 4, MIPS_sp), - MIPS_LW(MIPS_a0, 8, MIPS_sp), - MIPS_LW(MIPS_a1, 12, MIPS_sp), - MIPS_LW(MIPS_a2, 16, MIPS_sp), - MIPS_LW(MIPS_a3, 20, MIPS_sp), - MIPS_LW(MIPS_t0, 24, MIPS_sp), - MIPS_LW(MIPS_t1, 28, MIPS_sp), - MIPS_LW(MIPS_t2, 32, MIPS_sp), - MIPS_LW(MIPS_t3, 36, MIPS_sp), - MIPS_LW(MIPS_t4, 40, MIPS_sp), - MIPS_LW(MIPS_t5, 44, MIPS_sp), - MIPS_LW(MIPS_t6, 48, MIPS_sp), - MIPS_LW(MIPS_t7, 52, MIPS_sp), - MIPS_LW(MIPS_t8, 56, MIPS_sp), - MIPS_LW(MIPS_t9, 60, MIPS_sp), - /* Restore the stack pointer and return */ - MIPS_JR(MIPS_ra), - MIPS_ADDIU(MIPS_sp, MIPS_sp, 4*(18+24)), -}; - -/* Save all caller-saved MIPS registers on the stack */ -static const uint32_t code_save_regs[] = { - /* Add stack space for saving registers */ - MIPS_ADDIU(MIPS_sp, MIPS_sp, -(4*16)), - MIPS_SW(MIPS_v0, 0, MIPS_sp), - MIPS_SW(MIPS_v1, 4, MIPS_sp), - MIPS_SW(MIPS_a0, 8, MIPS_sp), - MIPS_SW(MIPS_a1, 12, MIPS_sp), - MIPS_SW(MIPS_a2, 16, MIPS_sp), - MIPS_SW(MIPS_a3, 20, MIPS_sp), - MIPS_SW(MIPS_t0, 24, MIPS_sp), - MIPS_SW(MIPS_t1, 28, MIPS_sp), - MIPS_SW(MIPS_t2, 32, MIPS_sp), - MIPS_SW(MIPS_t3, 36, MIPS_sp), - MIPS_SW(MIPS_t4, 40, MIPS_sp), - MIPS_SW(MIPS_t5, 44, MIPS_sp), - MIPS_SW(MIPS_t6, 48, MIPS_sp), - MIPS_SW(MIPS_t7, 52, MIPS_sp), - MIPS_SW(MIPS_t8, 56, MIPS_sp), - MIPS_SW(MIPS_t9, 60, MIPS_sp), - MIPS_MFLO(MIPS_v1), - MIPS_SW(MIPS_v1, 64, MIPS_sp), - MIPS_MFHI(MIPS_v1), - MIPS_JR(MIPS_ra), - MIPS_SW(MIPS_v1, 68, MIPS_sp), -}; - -/* Restore all caller-saved MIPS registers from the stack */ -static const uint32_t code_restore_regs[] = { - MIPS_LW(MIPS_v1, 64, MIPS_sp), - MIPS_MTLO(MIPS_v1), - MIPS_LW(MIPS_v1, 68, MIPS_sp), - MIPS_MTHI(MIPS_v1), - MIPS_LW(MIPS_v0, 0, MIPS_sp), - MIPS_LW(MIPS_v1, 4, MIPS_sp), - MIPS_LW(MIPS_a0, 8, MIPS_sp), - MIPS_LW(MIPS_a1, 12, MIPS_sp), - MIPS_LW(MIPS_a2, 16, MIPS_sp), - MIPS_LW(MIPS_a3, 20, MIPS_sp), - MIPS_LW(MIPS_t0, 24, MIPS_sp), - MIPS_LW(MIPS_t1, 28, MIPS_sp), - MIPS_LW(MIPS_t2, 32, MIPS_sp), - MIPS_LW(MIPS_t3, 36, MIPS_sp), - MIPS_LW(MIPS_t4, 40, MIPS_sp), - MIPS_LW(MIPS_t5, 44, MIPS_sp), - MIPS_LW(MIPS_t6, 48, MIPS_sp), - MIPS_LW(MIPS_t7, 52, MIPS_sp), - MIPS_LW(MIPS_t8, 56, MIPS_sp), - MIPS_LW(MIPS_t9, 60, MIPS_sp), - MIPS_JR(MIPS_ra), - MIPS_ADDIU(MIPS_sp, MIPS_sp, 4*16), -}; - -#endif // RTL_TRACE_STEALTH_FOR_SH2 - -/*************************************************************************/ -/*********************** Main translation routine ************************/ -/*************************************************************************/ - -/** - * rtl_translate_block_mips: Translate the given block into MIPS code. - * - * [Parameters] - * block: RTLBlock to translate - * code_ret: Pointer to variable to receive code buffer pointer - * size_ret: Pointer to variable to receive code buffer size (in bytes) - * [Return value] - * Nonzero on success, zero on error - * [Notes] - * On error, *code_ret and *size_ret are not modified. - */ -int rtl_translate_block_mips(RTLBlock *block, void **code_ret, - uint32_t *size_ret) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(code_ret != NULL, return 0); - PRECOND(size_ret != NULL, return 0); - - /* Handle manually-optimized cases specially for increased efficiency */ - if (block->num_insns == 4 - && block->insns[0].opcode == RTLOP_LOAD_PARAM - && block->insns[0].src_imm == 0 - && block->insns[1].opcode == RTLOP_LOAD_ADDR - && block->insns[2].opcode == RTLOP_CALL - && block->insns[2].src1 == block->insns[0].dest - && block->insns[2].target == block->insns[1].dest - && block->insns[3].opcode == RTLOP_RETURN - ) { - const unsigned int length = 16; - uint32_t *code = malloc(length); - if (!code) { - DMSG("No memory for native buffer (%u bytes)", length); - return 0; - } - if ((uintptr_t)code >> 28 == block->insns[1].src_addr >> 28) { - code[0] = MIPS_J((block->insns[1].src_addr & 0x0FFFFFFF) >> 2); - code[1] = MIPS_NOP(); - } else { - code[0] = MIPS_LUI(MIPS_at, block->insns[1].src_addr >> 16); - code[1] = MIPS_ORI(MIPS_at, MIPS_at, - block->insns[1].src_addr & 0xFFFF); - code[2] = MIPS_JR(MIPS_at); - code[3] = MIPS_NOP(); - } - *code_ret = code; - *size_ret = length; - return 1; - } - - /* Initialize translation-specific fields */ - block->native_buffer = NULL; - block->native_bufsize = 0; - block->native_length = 0; - block->label_offsets = NULL; - block->mips.need_save_ra = 0; - block->mips.need_chain_at = 0; - block->mips.frame_used = 0; - block->mips.sreg_used = 0; - - /* Check that the number of labels won't cause problems for our fake - * MIPS instructions */ - if (UNLIKELY(block->next_label > 1<<16)) { - DMSG("%p: Too many labels (%u, max %u)", block, (1<<16) - 1, - block->next_label - 1); - } - - /* Allocate the label map */ - if (block->next_label > 0) { // Should always be true, but just in case - block->label_offsets = - malloc(sizeof(*block->label_offsets) * block->next_label); - if (UNLIKELY(!block->label_offsets)) { - DMSG("No memory for block label offsets (%u bytes)", - sizeof(*block->label_offsets) * block->next_label); - goto fail; - } - memset(block->label_offsets, -1, - sizeof(*block->label_offsets) * block->next_label); - } - - /* Allocate an initial native code buffer for the block */ - block->native_bufsize = NATIVE_EXPAND_SIZE; - block->native_buffer = malloc(block->native_bufsize); - if (UNLIKELY(!block->native_buffer)) { - DMSG("No memory for native buffer (%u bytes)", block->native_bufsize); - goto fail; - } - - /* Allocate MIPS registers (and possibly stack frame locations) for all - * RTL registers, and perform other pre-translation scanning and - * optimization */ - if (UNLIKELY(!allocate_registers(block))) { - goto fail; - } -#ifdef RTL_TRACE_GENERATE - print_regmap(block); -#endif - - /* Translate the RTL instructions into MIPS code */ -#ifdef RTL_TRACE_STEALTH_FOR_SH2 - block->sh2_regcache_mask = 0; -#endif - if (UNLIKELY(!translate_block(block))) { - goto fail; - } - - /* Free the branch label offset table */ - free(block->label_offsets); - block->label_offsets = NULL; - - /* Shrink the buffer down to the actual length before returning it */ - *code_ret = realloc(block->native_buffer, block->native_length); - if (UNLIKELY(!*code_ret)) { - DMSG("realloc() to a smaller size failed?!"); - *code_ret = block->native_buffer; - } - *size_ret = block->native_length; - - /* Make sure we don't accidentally free the native code buffer while - * the caller is using it */ - block->native_buffer = NULL; - block->native_bufsize = 0; - block->native_length = 0; - - /* Success */ - free(block->label_offsets); - block->label_offsets = NULL; - return 1; - - fail: - free(block->native_buffer); - free(block->label_offsets); - block->native_buffer = NULL; - block->native_bufsize = 0; - block->native_length = 0; - block->label_offsets = NULL; - return 0; -} - -/*************************************************************************/ -/************************** Register allocation **************************/ -/*************************************************************************/ - -/** - * allocate_registers: Allocate MIPS registers (and, if necessary, stack - * frame locations) for all RTL registers in the block. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -static int allocate_registers(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - - int unit_index; - - /* - * The basic algorithm used for allocating registers is linear scan, as - * described by Poletto and Sarkar. However, since we do not have a - * sorted list of live intervals, we instead iterate through the - * instruction stream, allocating a hardware register (or frame slot) - * for each RTL register the first time it is encountered. - * - * Since live intervals calculated by the core RTL code do not take - * into account backward branches, the register allocation code checks - * each basic unit for entering edges from later units in the code - * stream, and if such a unit is found, updates the live intervals of - * all live registers to extend through the end of that unit (the - * latest unit in code stream order if there is more than one). - * - * The basic algorithm is tweaked as follows for the MIPS CPU: - * - * - Registers which are live over multiple basic units including a - * unit with a subroutine call are preferentially assigned callee- - * saved registers $s0-$s8, while registers which are only live - * within a single basic unit or which do not cross a subroutine - * call are preferentially assigned caller-saved registers $v1, - * $a0-$a3, and $t0-$t9. ($at and $v1 are reserved for loading - * values from the stack frame to be used as instruction - * operands.) However, constants are always assigned caller-saved - * registers, since it is often faster (and never slower) to - * reload them with addiu/ori/lui instructions than to save and - * restore another register on the stack. - * - * - Among caller-saved registers, preference is given to registers - * whose last use was longer ago. This assists instruction - * rescheduling by providing a larger live window for each - * hardware register. Callee-saved registers are allocated in - * numerical order regardless of last use to minimize the number - * of such registers which need to be saved and restored. - * - * - When spilling registers, the register with the shortest usage - * interval is spilled, rather than the one with the longest. - * (Spilling the longest interval first would cause the SH-2 state - * block pointer to be spilled, significantly impacting - * performance.) - * [FIXME: Currently, we always spill the new register.] - */ - - /* Clear the register map, stack frame map, and active register list */ - memset(block->mips.reg_map, 0, sizeof(block->mips.reg_map)); - block->mips.reg_free = ~0; - memset(block->mips.frame_map, 0, sizeof(block->mips.frame_map)); - memset(block->mips.frame_free, ~0, sizeof(block->mips.frame_free)); - block->mips.first_active = -1; - - /* Pick up the first unit with a CALL instruction, so we know where - * we'll need to use callee-saved registers */ - block->mips.next_call_unit = block->first_call_unit; - - /* Allocate registers for each basic unit in code stream order */ - for (unit_index = 0; unit_index >= 0; - unit_index = block->units[unit_index].next_unit - ) { - if (UNLIKELY(!allocate_regs_unit(block, unit_index))) { - return 0; - } - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * allocate_regs_unit: Allocate MIPS registers for an RTL basic unit. - * - * [Parameters] - * block: RTL block - * unit: Index of basic unit - * [Return value] - * Nonzero on success, zero on error - */ -static int allocate_regs_unit(RTLBlock * const block, - const unsigned int unit_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - - RTLUnit * const unit = &block->units[unit_index]; - - /* Copy the current register and stack frame map to the unit structure */ - - memcpy(unit->mips.reg_map, block->mips.reg_map, - sizeof(block->mips.reg_map)); - memcpy(unit->mips.frame_map, block->mips.frame_map, - sizeof(block->mips.frame_map)); - - /* Move to the next call unit if we reached the current one */ - - while (block->mips.next_call_unit >= 0 - && block->mips.next_call_unit <= unit_index - ) { - block->mips.next_call_unit = - block->units[block->mips.next_call_unit].next_call_unit; - } - - /* Scan through RTL instructions and allocate MIPS registers */ - - int32_t insn_index; // Signed so we catch last_insn==-1 properly - for (insn_index = unit->first_insn; insn_index <= unit->last_insn; - insn_index++ - ) { - if (UNLIKELY(!allocate_regs_insn(block, unit_index, insn_index))) { - return 0; - } - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * allocate_regs_insn: Perform register allocation for registers used in a - * single RTL instruction. - * - * [Parameters] - * block: RTL block - * unit_index: Index of current RTL unit - * insn_index: Index of RTL instruction to allocate registers for - * [Return value] - * Nonzero on success, zero on error - */ -static inline int allocate_regs_insn(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(unit_index < block->num_units, return 0); - PRECOND(insn_index < block->num_insns, return 0); - - RTLInsn * const insn = &block->insns[insn_index]; - - retry: - switch ((RTLOpcode)insn->opcode) { - - case RTLOP_NOP: -#ifdef RTL_TRACE_STEALTH_FOR_SH2 - if (insn->src_imm & 0x80000000) { - /* If we have stealth trace NOPs, we'll be calling subroutines, - * so ensure $ra is saved */ - block->mips.need_save_ra = 1; - } -#endif - return 1; - - case RTLOP_LABEL: - case RTLOP_GOTO: - case RTLOP_RETURN: - return 1; - - case RTLOP_LOAD_IMM: - case RTLOP_LOAD_ADDR: - /* If this register is unused elsewhere, kill the instruction */ - if (UNLIKELY(block->regs[insn->dest].birth == block->regs[insn->dest].death)) { - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - return 1; - } -#ifdef MIPS_OPTIMIZE_IMMEDIATE - /* Try to optimize this and the following instruction into a single - * immediate instruction (but only if it's part of the same unit) */ - if (insn_index < block->units[unit_index].last_insn - && optimize_immediate(block, insn_index) - ) { - if (insn->opcode != RTLOP_LOAD_IMM - && insn->opcode != RTLOP_LOAD_ADDR - ) { - goto retry; // Instruction was altered - } - } -#endif - block->regs[insn->dest].last_used = insn_index; - clean_active_list(block, insn_index); - if (!block->regs[insn->dest].native_allocated - && merge_constant_register(block, unit_index, insn_index, - insn->dest) - ) { - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - return 1; - } - return allocate_one_register(block, unit_index, insn_index, - insn->dest); - - case RTLOP_LOAD_PARAM: - if (UNLIKELY(block->regs[insn->dest].birth == block->regs[insn->dest].death)) { - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - return 1; - } - block->regs[insn->dest].last_used = insn_index; - clean_active_list(block, insn_index); - /* If it's a long-lived register, let allocate_one_register() - * select a callee-saved register; otherwise, try to allocate the - * appropriate parameter register to avoid an unnecessary MOVE */ - if (block->mips.next_call_unit >= 0 - && block->regs[insn->dest].death - >= block->units[block->mips.next_call_unit].first_insn - ) { - return allocate_one_register(block, unit_index, insn_index, - insn->dest); - } else { - return allocate_one_register_prefer( - block, unit_index, insn_index, insn->dest, - MIPS_a0 + block->regs[insn->dest].param_index - ); - } - - case RTLOP_MOVE: - case RTLOP_NOT: - case RTLOP_CLZ: - case RTLOP_CLO: - case RTLOP_BSWAPH: - case RTLOP_BSWAPW: - case RTLOP_HSWAPW: - case RTLOP_ADDI: - case RTLOP_ANDI: - case RTLOP_ORI: - case RTLOP_XORI: - case RTLOP_SLLI: - case RTLOP_SRLI: - case RTLOP_SRAI: - case RTLOP_RORI: - case RTLOP_SLTUI: - case RTLOP_SLTSI: - case RTLOP_BFEXT: - case RTLOP_LOAD_BU: - case RTLOP_LOAD_BS: - case RTLOP_LOAD_HU: - case RTLOP_LOAD_HS: - case RTLOP_LOAD_W: - case RTLOP_LOAD_PTR: - if (UNLIKELY(block->regs[insn->dest].birth == block->regs[insn->dest].death)) { - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - return 1; - } - block->regs[insn->src1].last_used = insn_index; - block->regs[insn->dest].last_used = insn_index; - clean_active_list(block, insn_index); - if (UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src1))) { - return 0; - } - /* Source registers can be reused as destination registers */ - clean_active_list(block, insn_index+1); - if (insn->opcode == RTLOP_ANDI && insn->src_imm > 0xFFFF - && block->regs[insn->src1].native_reg != MIPS_noreg - ) { - /* This might be handled as "ins dest,$zero,...", so try to - * make the destination use the same register as the source */ - return allocate_one_register_prefer( - block, unit_index, insn_index, insn->dest, - block->regs[insn->src1].native_reg - ); - } else { - return allocate_one_register(block, unit_index, insn_index, - insn->dest); - } - - case RTLOP_STORE_B: - case RTLOP_STORE_H: - case RTLOP_STORE_W: - case RTLOP_STORE_PTR: - block->regs[insn->src1].last_used = insn_index; - block->regs[insn->dest].last_used = insn_index; - clean_active_list(block, insn_index); - return allocate_one_register(block, unit_index, insn_index, - insn->src1) - && allocate_one_register(block, unit_index, insn_index, - insn->dest); - - case RTLOP_ADD: - case RTLOP_SUB: - case RTLOP_AND: - case RTLOP_OR: - case RTLOP_XOR: - case RTLOP_SLL: - case RTLOP_SRL: - case RTLOP_SRA: - case RTLOP_ROR: - case RTLOP_SLTU: - case RTLOP_SLTS: - if (UNLIKELY(block->regs[insn->dest].birth == block->regs[insn->dest].death)) { - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - return 1; - } - block->regs[insn->src1].last_used = insn_index; - block->regs[insn->src2].last_used = insn_index; - block->regs[insn->dest].last_used = insn_index; - clean_active_list(block, insn_index); - if (UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src1)) - || UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src2)) - ) { - return 0; - } - clean_active_list(block, insn_index+1); - return allocate_one_register(block, unit_index, insn_index, - insn->dest); - - case RTLOP_SELECT: { - if (UNLIKELY(block->regs[insn->dest].birth == block->regs[insn->dest].death)) { - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - return 1; - } - block->regs[insn->src1].last_used = insn_index; - block->regs[insn->src2].last_used = insn_index; - block->regs[insn->cond].last_used = insn_index; - block->regs[insn->dest].last_used = insn_index; - clean_active_list(block, insn_index); - if (UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src1)) - || UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src2)) - || UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->cond)) - ) { - return 0; - } - clean_active_list(block, insn_index+1); - /* We implement SELECT with a MOVE/MOVZ pair in the general case. - * If the target shares a hardware register with either of the - * source operands, we can drop the MOVE and use a single MOVZ or - * MOVN instead, so try to do that. */ - int desired_reg; - if (((desired_reg = block->regs[insn->src1].native_reg) != MIPS_noreg - && desired_reg != MIPS_zero - && (block->mips.reg_free & (1 << desired_reg))) - || ((desired_reg = block->regs[insn->src2].native_reg) != MIPS_noreg - && desired_reg != MIPS_zero - && (block->mips.reg_free & (1 << desired_reg))) - ) { - return allocate_one_register_prefer(block, unit_index, insn_index, - insn->dest, desired_reg); - } else { - return allocate_one_register(block, unit_index, insn_index, - insn->dest); - } - } - - case RTLOP_BFINS: { - if (UNLIKELY(block->regs[insn->dest].birth == block->regs[insn->dest].death)) { - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - return 1; - } - block->regs[insn->src1].last_used = insn_index; - block->regs[insn->src2].last_used = insn_index; - block->regs[insn->dest].last_used = insn_index; - clean_active_list(block, insn_index); - if (UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src1)) - || UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src2)) - ) { - return 0; - } - clean_active_list(block, insn_index+1); - /* The INS instruction treats its destination (rt) as read-write, - * so try to allocate the destination in the same register as src1. - * If we fail, we'll have to MOVE(dest,src1) at translation time. */ - if (block->regs[insn->src1].native_reg == MIPS_noreg - || block->regs[insn->src1].native_reg == MIPS_zero - ) { - return allocate_one_register(block, unit_index, insn_index, - insn->dest); - } else { - const int desired_reg = block->regs[insn->src1].native_reg; - return allocate_one_register_prefer(block, unit_index, insn_index, - insn->dest, desired_reg); - } - } - - case RTLOP_MULU: - case RTLOP_MULS: - case RTLOP_MADDU: - case RTLOP_MADDS: - case RTLOP_DIVMODU: - case RTLOP_DIVMODS: - if (UNLIKELY((!insn->dest || block->regs[insn->dest].birth == block->regs[insn->dest].death) - && (!insn->dest2 || block->regs[insn->dest2].birth == block->regs[insn->dest2].death)) - ) { - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - return 1; - } - block->regs[insn->src1].last_used = insn_index; - block->regs[insn->src2].last_used = insn_index; - block->regs[insn->dest].last_used = insn_index; - block->regs[insn->dest2].last_used = insn_index; - clean_active_list(block, insn_index); - if (UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src1)) - || UNLIKELY(!allocate_one_register(block, unit_index, insn_index, - insn->src2)) - ) { - return 0; - } - clean_active_list(block, insn_index+1); - return (!insn->dest - || allocate_one_register(block, unit_index, insn_index, - insn->dest)) - && (!insn->dest2 - || allocate_one_register(block, unit_index, insn_index, - insn->dest2)); - - case RTLOP_GOTO_IF_Z: - case RTLOP_GOTO_IF_NZ: - block->regs[insn->src1].last_used = insn_index; - clean_active_list(block, insn_index); - return allocate_one_register(block, unit_index, insn_index, - insn->src1); - - case RTLOP_GOTO_IF_E: - case RTLOP_GOTO_IF_NE: - block->regs[insn->src1].last_used = insn_index; - block->regs[insn->src2].last_used = insn_index; - clean_active_list(block, insn_index); - return allocate_one_register(block, unit_index, insn_index, - insn->src1) - && allocate_one_register(block, unit_index, insn_index, - insn->src2); - - case RTLOP_CALL: { - if (UNLIKELY(block->regs[insn->dest].birth == block->regs[insn->dest].death)) { - insn->dest = 0; - /* Execute the call anyway, because it may have side effects */ - } - if (insn->src1) { - block->regs[insn->src1].last_used = insn_index; - } - if (insn->src2) { - block->regs[insn->src2].last_used = insn_index; - } - block->regs[insn->target].last_used = insn_index; - if (insn->dest) { - block->regs[insn->dest].last_used = insn_index; - } - clean_active_list(block, insn_index); - if ((insn->src1 - && UNLIKELY(!allocate_one_register_prefer(block, unit_index, insn_index, insn->src1, MIPS_a0))) - || (insn->src2 - && UNLIKELY(!allocate_one_register_prefer(block, unit_index, insn_index, insn->src2, MIPS_a1))) - || UNLIKELY(!allocate_one_register_prefer(block, unit_index, insn_index, insn->target, MIPS_t9)) - ) { - return 0; - } - clean_active_list(block, insn_index+1); - /* Null out any free caller-saved registers because they'll have - * been clobbered by the call (otherwise we might try to reuse a - * constant value that's no longer valid) */ - unsigned int i; - for (i = 0; i < lenof(caller_saved_regs); i++) { - const unsigned int mips_reg = caller_saved_regs[i]; - if (block->mips.reg_free & (1 << mips_reg)) { - block->mips.reg_map[mips_reg] = NULL; - } - } - if (insn->dest - && UNLIKELY(!allocate_one_register_prefer(block, unit_index, insn_index, insn->dest, MIPS_v0)) - ) { - return 0; - } - /* We'll need to save $ra now */ - block->mips.need_save_ra = 1; - return 1; - } // case RTLOP_CALL - - case RTLOP_RETURN_TO: - block->regs[insn->target].last_used = insn_index; - clean_active_list(block, insn_index); - return allocate_one_register(block, unit_index, insn_index, - insn->target); - - } // switch (insn->opcode) - - DMSG("%p/%u: Invalid RTL opcode %u", block, insn_index, insn->opcode); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * add_to_active_list: Add a register to the active list. - * - * [Parameters] - * block: RTL block - * is_frame: Nonzero if the register is in a frame slot, zero if in a - * hardware register - * index: MIPS register index or frame slot index - * [Return value] - * None - */ -static void add_to_active_list(RTLBlock * const block, const int is_frame, - const unsigned int index) -{ - PRECOND(block != NULL, return); - - const unsigned int list_index = is_frame ? 32+index : index; - block->mips.active_list[list_index].is_frame = is_frame ? 1 : 0; - block->mips.active_list[list_index].index = index; - const uint32_t death = is_frame ? block->mips.frame_map[index]->death - : block->mips.reg_map[index]->death; - - int insert_at = -1; - int next = block->mips.first_active; - while (next >= 0 - && (block->mips.active_list[next].is_frame - ? block->mips.frame_map[block->mips.active_list[next].index]->death - : block->mips.reg_map[block->mips.active_list[next].index]->death) - < death - ) { - insert_at = next; - next = block->mips.active_list[next].next; - } - if (insert_at < 0) { - block->mips.first_active = list_index; - } else { - block->mips.active_list[insert_at].next = list_index; - } - block->mips.active_list[list_index].next = next; -} - -/*----------------------------------*/ - -/** - * remove_from_active_list: Explicitly remove a register from the active - * list. Used when merging constants or updating the death time of an - * active register. This function does NOT set the "free" bit for the - * freed register or frame slot. - * - * [Parameters] - * block: RTL block - * is_frame: Nonzero if the register is in a frame slot, zero if in a - * hardware register - * index: MIPS register index or frame slot index - * [Return value] - * None - */ -static void remove_from_active_list(RTLBlock * const block, const int is_frame, - const unsigned int index) -{ - PRECOND(block != NULL, return); - - const unsigned int list_index = is_frame ? 32+index : index; - - int prev = -1; - int next = block->mips.first_active; - while (next >= 0 && next != list_index) { - prev = next; - next = block->mips.active_list[next].next; - } - if (next >= 0) { - next = block->mips.active_list[next].next; - if (prev < 0) { - block->mips.first_active = next; - } else { - block->mips.active_list[prev].next = next; - } - } -} - -/*----------------------------------*/ - -/** - * clean_active_list: Clean all dead registers from the active list. - * - * [Parameters] - * block: RTL block - * clean_insn: Instruction index for cleaning registers (any register - * with death < clean_insn is cleaned) - * [Return value] - * None - */ -static void clean_active_list(RTLBlock * const block, - const uint32_t clean_insn) -{ - PRECOND(block != NULL, return); - - int first_active = block->mips.first_active; - while (first_active >= 0 - && (block->mips.active_list[first_active].is_frame - ? block->mips.frame_map[block->mips.active_list[first_active].index]->death - : block->mips.reg_map[block->mips.active_list[first_active].index]->death) - < clean_insn - ) { - const unsigned int index = block->mips.active_list[first_active].index; - if (block->mips.active_list[first_active].is_frame) { - block->mips.frame_free[index/32] |= 1 << (index%32); - } else { - block->mips.reg_free |= 1 << index; - } - first_active = block->mips.active_list[first_active].next; - block->mips.first_active = first_active; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * allocate_one_register: Allocate a MIPS register for the given RTL - * register, if it does not have one allocated already, and update the - * current register map. - * - * [Parameters] - * block: RTL block - * unit_index: Index of current basic unit - * insn_index: Index of current instruction - * reg_index: Index of RTL register - * [Return value] - * Nonzero on success, zero on error - * [Notes] - * This routine only maps into the available caller-saved registers, - * $3-$15 and $24-$25 ($v1, $a0-$a3, and $t0-$t9); the callee-saved - * registers ($s0-$s8) are only used when renaming. - */ -static int allocate_one_register(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index, - const unsigned int reg_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(reg_index < block->next_reg, return 0); - - RTLRegister * const reg = &block->regs[reg_index]; - - /* If it's already allocated, just return */ - if (reg->native_allocated) { - return 1; - } - - /* If it's a constant zero value, just use $zero */ - if (reg->source == RTLREG_CONSTANT && reg->value == 0) { - reg->native_allocated = 1; - reg->native_reg = MIPS_zero; - /* We don't mark it in the register map or add it to the active - * list since $zero can be shared */ - return 1; - } - - /* Macro to select a register if its last use is the oldest so far */ - #define SELECT_REG_BY_AGE(mips_reg) { \ - const int __mips_reg = (mips_reg); \ - if (block->mips.reg_free & (1 << __mips_reg)) { \ - if (!block->mips.reg_map[__mips_reg]) { \ - best_mips = __mips_reg; \ - break; \ - } else if (block->mips.reg_map[__mips_reg]->death < oldest) { \ - best_mips = __mips_reg; \ - oldest = block->mips.reg_map[__mips_reg]->death; \ - } \ - } \ - } - /* Macro to select a register unconditionally if it's free */ - #define SELECT_REG_BY_FREE(mips_reg) { \ - const int __mips_reg = (mips_reg); \ - if (block->mips.reg_free & (1 << __mips_reg)) { \ - best_mips = __mips_reg; \ - break; \ - } \ - } - - int best_mips = -1; - uint32_t oldest = insn_index; // Last use of best_$mips - unsigned int i; - if (reg->source != RTLREG_CONSTANT - && block->mips.next_call_unit >= 0 - && reg->death >= block->units[block->mips.next_call_unit].first_insn - ) { - /* Prefer a callee-saved register for non-constant, long-lived - * registers */ - for (i = 0; i < lenof(callee_saved_regs); i++) { - SELECT_REG_BY_FREE(callee_saved_regs[i]); - } - if (best_mips < 0) { - for (i = 0; i < lenof(caller_saved_regs); i++) { - SELECT_REG_BY_AGE(caller_saved_regs[i]); - } - } - } else { - /* Prefer a caller-saved register for short-lived registers */ - for (i = 0; i < lenof(caller_saved_regs); i++) { - SELECT_REG_BY_AGE(caller_saved_regs[i]); - } - if (best_mips < 0) { - for (i = 0; i < lenof(callee_saved_regs); i++) { - SELECT_REG_BY_FREE(callee_saved_regs[i]); - } - } - } - - #undef SELECT_REG_BY_AGE - #undef SELECT_REG_BY_FREE - - if (best_mips < 0) { - /* No free registers, so give it a frame slot instead */ - reg->native_allocated = 1; - reg->native_reg = MIPS_noreg; - return allocate_frame_slot(block, insn_index, reg_index); - } - - reg->native_allocated = 1; - reg->native_reg = best_mips; - block->mips.reg_map[best_mips] = &block->regs[reg_index]; - block->mips.reg_free &= ~(1 << best_mips); - if (reg_is_callee_saved[best_mips]) { - block->mips.sreg_used |= 1 << best_mips; - } - add_to_active_list(block, 0, best_mips); - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * allocate_one_register_prefer: Allocate a MIPS register for the given - * RTL register, like allocate_one_register(), but use MIPS register - * "prefer_mips" if possible. (If a MIPS register has already been - * allocated, the allocation is left unchanged.) - * - * [Parameters] - * block: RTL block - * unit_index: Index of current basic unit - * insn_index: Index of current instruction - * reg_index: Index of RTL register - * prefer_mips: MIPS register to prefer - * [Return value] - * Nonzero on success, zero on error - */ -static int allocate_one_register_prefer(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index, - const unsigned int reg_index, - const unsigned int prefer_mips) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(reg_index < block->next_reg, return 0); - PRECOND(prefer_mips < 32, return 0); - - RTLRegister * const reg = &block->regs[reg_index]; - - if (!reg->native_allocated && (block->mips.reg_free & (1<native_allocated = 1; - reg->native_reg = prefer_mips; - block->mips.reg_map[prefer_mips] = &block->regs[reg_index]; - block->mips.reg_free &= ~(1 << prefer_mips); - if (reg_is_callee_saved[prefer_mips]) { - block->mips.sreg_used |= 1 << prefer_mips; - } - add_to_active_list(block, 0, prefer_mips); - return 1; - } - - /* We couldn't get the preferred register, so just allocate as usual */ - return allocate_one_register(block, unit_index, insn_index, reg_index); -} - -/*-----------------------------------------------------------------------*/ - -/** - * merge_constant_register: Look for a MIPS hardware register holding the - * same constant value as the given RTL register; if found, assign that - * MIPS register to the given RTL register as well. - * - * When MIPS_OPTIMIZE_MERGE_CONSTANTS is disabled, this function will not - * search for generic constant registers, but will still assign $zero to - * RTL registers with the constant value 0. - * - * [Parameters] - * block: RTL block - * unit_index: Index of current basic unit - * insn_index: Index of current instruction - * reg_index: Index of RTL register - * [Return value] - * Nonzero if the register was successfully merged with another, else zero - */ -static int merge_constant_register(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index, - const unsigned int reg_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(unit_index < block->num_units, return 0); - PRECOND(reg_index < block->next_reg, return 0); - PRECOND(!block->regs[reg_index].native_allocated, return 0); - - RTLRegister * const reg = &block->regs[reg_index]; - - /* If it's a constant zero value, just use $zero */ - if (reg->source == RTLREG_CONSTANT && reg->value == 0) { - reg->native_allocated = 1; - reg->native_reg = MIPS_zero; - /* We don't mark it in the register map or add it to the active - * list since $zero can be shared */ - return 1; - } - - /* If it's a constant that has the same value as another constant - * that's already been loaded (and if MIPS_OPTIMIZE_MERGE_CONSTANTS - * is enabled), reuse the same hardware register. But don't reuse a - * register that died in a previous basic unit, since it may be on a - * different code path */ -#ifdef MIPS_OPTIMIZE_MERGE_CONSTANTS - if (reg->source == RTLREG_CONSTANT) { - unsigned int mips_reg; - for (mips_reg = MIPS_v1; mips_reg <= MIPS_s8; mips_reg++) { - if (block->mips.reg_map[mips_reg] - && block->mips.reg_map[mips_reg]->death - >= block->units[unit_index].first_insn - && block->mips.reg_map[mips_reg]->source == RTLREG_CONSTANT - && block->mips.reg_map[mips_reg]->value == reg->value - ) { - /* Found a match--assign this MIPS register to the - * current RTL register, and ensure the MIPS register - * stays allocated until all merged registers are dead */ - reg->native_allocated = 1; - reg->native_reg = mips_reg; - if (reg->death < block->mips.reg_map[mips_reg]->death) { - reg->death = block->mips.reg_map[mips_reg]->death; - } - reg->next_merged = block->mips.reg_map[mips_reg]; - block->mips.reg_map[mips_reg] = &block->regs[reg_index]; - RTLRegister *merged_reg = reg; - while ((merged_reg = merged_reg->next_merged) != NULL) { - merged_reg->death = reg->death; - } - if (!(block->mips.reg_free & (1 << mips_reg))) { - /* The register's live interval has changed, so remove - * it from the active list (we'll re-add it below) */ - remove_from_active_list(block, 0, mips_reg); - } - block->mips.reg_free &= ~(1 << mips_reg); - add_to_active_list(block, 0, mips_reg); - return 1; - } - } - } -#endif - - /* Couldn't merge this register into another */ - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * allocate_frame_slot: Allocate a frame slot for the given RTL register, - * if it does not have one allocated already. - * - * [Parameters] - * block: RTL block - * insn_index: Index of current instruction - * reg_index: Index of RTL register - * [Return value] - * Nonzero on success, zero on error - */ -static int allocate_frame_slot(RTLBlock * const block, - const uint32_t insn_index, - const unsigned int reg_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(reg_index < block->next_reg, return 0); - - RTLRegister * const reg = &block->regs[reg_index]; - - if (reg->frame_allocated) { - return 1; - } - - const unsigned int num_slots = MIPS_FRAME_SIZE/4; - unsigned int slot; - for (slot = 0; slot < num_slots; slot++) { - if (block->mips.frame_free[slot/32] & (1 << (slot%32))) { - break; - } - } - if (slot >= num_slots) { - DMSG("%p/%u: No free frame slots for RTL register %u", - block, insn_index, reg_index); - return 0; - } - - reg->frame_allocated = 1; - reg->frame_slot = slot; - reg->stack_offset = slot * 4; - block->mips.frame_map[slot] = &block->regs[reg_index]; - block->mips.frame_free[slot/32] &= ~(1 << (slot%32)); - block->mips.frame_used = 1; - add_to_active_list(block, 1, slot); - return 1; -} - -/*-----------------------------------------------------------------------*/ - -#ifdef MIPS_OPTIMIZE_IMMEDIATE - -/** - * optimize_immediate: Attempt to optimize a sequence of LOAD_IMM or - * LOAD_ADDR followed by an instruction using the loaded constant into a - * sequence which uses fewer MIPS instructions. On success, the RTL - * instruction (and possibly following instructions) will be altered - * appropriately. - * - * The following optimizations are performed when r1 is not used beyond - * the second instruction and (for ALU instructions) the constant value is - * within range of the particular instruction: - * - * LOAD_IMM r1, constant; ALUOP r2, r3, r1 - * --> NOP; ALUOPI r2, r3, constant - * - * LOAD_ADDR r1, address; LOAD_{BU,BS,HU,HS,W} r2, offset(r1) - * --> LOAD_ADDR r1, %hi(address+offset); - * l{bu,b,hu,h,w} r2, %lo(address+offset)(r1) - * - * LOAD_ADDR r1, address; STORE_{B,H,W} offset(r1), r2 - * --> LOAD_ADDR r1, %hi(address+offset); - * s{b,h,w} r2, %lo(address+offset)(r1) - * - * where ALUOP is one of ADD, SUB, AND, OR, XOR, SLL, SRL, SRA, ROR, SLTU, - * or SLTS. - * - * [Parameters] - * block: RTL block being translated - * unit_index: Index of current basic unit - * insn_index: Index of RTL LOAD_IMM or LOAD_ADDR instruction - * [Return value] - * Nonzero if the given RTL instruction was successfully optimized, - * else zero - */ -static int optimize_immediate(RTLBlock * const block, - const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn_index < block->num_insns, return 0); - PRECOND(block->insns[insn_index].opcode == RTLOP_LOAD_IMM - || block->insns[insn_index].opcode == RTLOP_LOAD_ADDR, - return 0); - PRECOND(block->insns[insn_index].dest != 0 - && block->insns[insn_index].dest < block->next_reg, return 0); - - RTLInsn *insn = &block->insns[insn_index]; - const uint32_t imm_index = insn[0].dest; - const uintptr_t value = block->regs[imm_index].value; - - if (block->regs[imm_index].death > insn_index+1) { - /* Register is used later, so we can't optimize the load out */ - return 0; - } - - switch ((RTLOpcode)insn[1].opcode) { - - case RTLOP_ADD: - if (value + 0x8000 <= 0xFFFF) { - if (insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_ADDI; - insn[1].src_imm = value; - return 1; - } else if (insn[1].src1 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_ADDI; - insn[1].src1 = insn[1].src2; - insn[1].src_imm = value; - return 1; - } - } - return 0; - - case RTLOP_SUB: - if (value + 0x7FFF <= 0xFFFF && insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_ADDI; - insn[1].src_imm = -value; - return 1; - } - return 0; - - case RTLOP_AND: { - int is_insable = 0; // Can we turn it into "ins reg,$zero,..."? - if (value & 1) { - /* Must be 0b000...111 */ - is_insable = ((value & (value+1)) == 0); - } else { - /* Must be 0b111...000 */ - is_insable = ((~value & (~value+1)) == 0); - } - if (value <= 0xFFFF || is_insable) { - if (insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_ANDI; - insn[1].src_imm = value; - return 1; - } else if (insn[1].src1 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_ANDI; - insn[1].src1 = insn[1].src2; - insn[1].src_imm = value; - return 1; - } - } - return 0; - } // case RTLOP_AND - - case RTLOP_OR: - if (value <= 0xFFFF) { - if (insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_ORI; - insn[1].src_imm = value; - return 1; - } else if (insn[1].src1 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_ORI; - insn[1].src1 = insn[1].src2; - insn[1].src_imm = value; - return 1; - } - } - return 0; - - case RTLOP_XOR: - if (value <= 0xFFFF) { - if (insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_XORI; - insn[1].src_imm = value; - return 1; - } else if (insn[1].src1 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_XORI; - insn[1].src1 = insn[1].src2; - insn[1].src_imm = value; - return 1; - } - } - return 0; - - case RTLOP_SLL: - if (insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_SLLI; - insn[1].src_imm = value; - return 1; - } - return 0; - - case RTLOP_SRL: - if (insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_SRLI; - insn[1].src_imm = value; - return 1; - } - return 0; - - case RTLOP_SRA: - if (insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_SRAI; - insn[1].src_imm = value; - return 1; - } - return 0; - - case RTLOP_ROR: - if (insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_RORI; - insn[1].src_imm = value; - return 1; - } - return 0; - - case RTLOP_SLTU: - if (value + 0x8000 <= 0xFFFF && insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_SLTUI; - insn[1].src_imm = value; - return 1; - } - return 0; - - case RTLOP_SLTS: - if (value + 0x8000 <= 0xFFFF && insn[1].src2 == imm_index) { - insn[0].opcode = RTLOP_NOP; - insn[0].src_imm = 0; - insn[1].opcode = RTLOP_SLTSI; - insn[1].src_imm = value; - return 1; - } - return 0; - - /*----------------------------*/ - - case RTLOP_LOAD_BU: - case RTLOP_LOAD_BS: - case RTLOP_LOAD_HU: - case RTLOP_LOAD_HS: - case RTLOP_LOAD_W: - case RTLOP_LOAD_PTR: - if (insn[1].src1 == imm_index) { - const uint32_t address = value + insn[1].offset; - insn[0].src_imm = (address + 0x8000) & 0xFFFF0000; - block->regs[imm_index].value = insn[0].src_imm; - insn[1].offset = (int16_t)(address & 0xFFFF); - return 1; - } - return 0; - - case RTLOP_STORE_B: - case RTLOP_STORE_H: - case RTLOP_STORE_W: - case RTLOP_STORE_PTR: - if (insn[1].dest == imm_index) { - const uint32_t address = value + insn[1].offset; - insn[0].src_imm = (address + 0x8000) & 0xFFFF0000; - block->regs[imm_index].value = insn[0].src_imm; - insn[1].offset = (int16_t)(address & 0xFFFF); - return 1; - } - return 0; - - /*----------------------------*/ - - case RTLOP_NOP: - case RTLOP_MOVE: - case RTLOP_SELECT: - case RTLOP_MULU: - case RTLOP_MULS: - case RTLOP_MADDU: - case RTLOP_MADDS: - case RTLOP_DIVMODU: - case RTLOP_DIVMODS: - case RTLOP_NOT: - case RTLOP_CLZ: - case RTLOP_CLO: - case RTLOP_BSWAPH: - case RTLOP_BSWAPW: - case RTLOP_HSWAPW: - case RTLOP_ADDI: - case RTLOP_ANDI: - case RTLOP_ORI: - case RTLOP_XORI: - case RTLOP_SLLI: - case RTLOP_SRLI: - case RTLOP_SRAI: - case RTLOP_RORI: - case RTLOP_SLTUI: - case RTLOP_SLTSI: - case RTLOP_BFEXT: - case RTLOP_BFINS: - case RTLOP_LOAD_IMM: - case RTLOP_LOAD_ADDR: - case RTLOP_LOAD_PARAM: - case RTLOP_LABEL: - case RTLOP_GOTO: - case RTLOP_GOTO_IF_Z: - case RTLOP_GOTO_IF_NZ: - case RTLOP_GOTO_IF_E: - case RTLOP_GOTO_IF_NE: - case RTLOP_CALL: - case RTLOP_RETURN: - case RTLOP_RETURN_TO: - return 0; - - } // switch (insn[1].opcode) - - DMSG("%p/%u: Invalid RTL opcode %u", block, insn_index, insn[1].opcode); - return 0; -} - -#endif // MIPS_OPTIMIZE_IMMEDIATE - -/*-----------------------------------------------------------------------*/ - -#ifdef RTL_TRACE_GENERATE - -/* Helper macro for print_regmap() to check the status of an instruction - * operand and update the line buffer and register map accordingly */ - -# define CHECK_REG(which) do { \ - const uint32_t __rtl_reg = insn->which; \ - if (__rtl_reg > 0 && __rtl_reg < block->next_reg \ - && block->regs[__rtl_reg].native_allocated \ - && block->regs[__rtl_reg].native_reg != MIPS_noreg \ - ) { \ - const uint32_t __mips_reg = block->regs[__rtl_reg].native_reg; \ - const unsigned int __column = columns[__mips_reg]; \ - if (!__column) { \ - break; \ - } \ - if (block->regs[__rtl_reg].birth == insn_index) { \ - block->mips.reg_map[__mips_reg] = &block->regs[__rtl_reg]; \ - unsigned int __value = __rtl_reg; \ - int __pos = 3; \ - do { \ - linebuf[__column+__pos] = '0' + (__value % 10); \ - __value /= 10; \ - __pos--; \ - } while (__value > 0 && __pos >= 0); \ - if (__pos >= 0) { \ - linebuf[__column+__pos] = 'r'; \ - } \ - print_line = 1; \ - } \ - } \ -} while (0) - -/*----------------------------------*/ - -/** - * print_regmap: Print the state of the RTL-to-MIPS register map over the - * course of the block. - * - * [Parameters] - * block: RTL block - * [Return value] - * None - */ -static void print_regmap(RTLBlock * const block) -{ - PRECOND(block != NULL, return); - - fprintf(stderr, "%p: MIPS register allocation:\n", block); - fprintf(stderr, " | v0 v1: a0 a1 a2 a3:" - " t0 t1 t2 t3: t4 t5 t6 t7: t8 t9\n"); - fprintf(stderr, "-----+--------+----------------+" - "----------------+----------------+--------\n"); - static const char template[75] = - " | : :" - " : : \n"; - static const unsigned int columns[32] = { - 0, 0, 6,10, 15,19,23,27, 32,36,40,44, 49,53,57,61, - 0, 0, 0, 0, 0, 0, 0, 0, 66,70, 0, 0, 0, 0, 0, 0, - }; - - char linebuf[75]; - memcpy(linebuf, template, sizeof(template)); - memset(block->mips.reg_map, 0, sizeof(block->mips.reg_map)); - - uint32_t insn_index; - for (insn_index = 0; insn_index < block->num_insns; insn_index++) { - const RTLInsn * const insn = &block->insns[insn_index]; - - /* Only print lines where registers are born or die */ - int print_line = 0; - - /* Fill in active registers first */ - unsigned int mips_reg; - for (mips_reg = MIPS_v0; mips_reg <= MIPS_t9; - mips_reg = (mips_reg==MIPS_t7 ? MIPS_t8 : mips_reg+1) - ) { - if (block->mips.reg_map[mips_reg] - && block->mips.reg_map[mips_reg]->death >= insn_index - ) { - unsigned int column = columns[mips_reg]; - if (column) { - if (block->mips.reg_map[mips_reg]->death == insn_index) { - block->mips.reg_map[mips_reg] = NULL; - linebuf[column+1] = '-'; - linebuf[column+2] = '-'; - linebuf[column+3] = '-'; - print_line = 1; - } else { - linebuf[column+2] = '|'; - } - } - } - } - - /* For simplicity, don't bother checking opcodes; just look at any - * register index that's in range and report it if it's become live */ - CHECK_REG(dest); - CHECK_REG(src1); - CHECK_REG(src2); - CHECK_REG(dest2); - - /* Print the line (with instruction index) if appropriate */ - if (print_line) { - unsigned int value = insn_index; - int pos = 4; - do { - linebuf[pos] = '0' + (value % 10); - value /= 10; - pos--; - } while (value > 0 && pos >= 0); - fwrite(linebuf, sizeof(linebuf), 1, stderr); - } - - /* Reset for the next line */ - memcpy(linebuf, template, sizeof(template)); - - } // for (insn_index) -} - -#undef CHECK_REG - -#endif // RTL_TRACE_GENERATE - -/*************************************************************************/ -/************************ Instruction translation ************************/ -/*************************************************************************/ - -/** - * APPEND: Append a MIPS instruction word to the native code buffer. - */ -#define APPEND(insn) do { \ - if (UNLIKELY(!append_insn(block, (insn)))) { \ - return 0; \ - } \ -} while (0) - -/** - * APPEND_FLOAT: Append a high-latency instruction (load, multiply or - * divide) to the native code buffer. If possible (and if rescheduling is - * enabled), the instruction is floated up by at most "latency" - * instructions to avoid a stall. - */ -#define APPEND_FLOAT(insn,latency) do { \ - if (UNLIKELY(!append_float(block, (insn), (latency)))) { \ - return 0; \ - } \ -} while (0) - -/** - * APPEND_BRANCH: Append a MIPS branch instruction to the native code buffer. - */ -#define APPEND_BRANCH(insn) do { \ - if (UNLIKELY(!append_branch(block, (insn)))) { \ - return 0; \ - } \ -} while (0) - -/** - * IS_SPILLED: Return nonzero if the given register (by index) is spilled, - * else zero. Assumes the variable "insn_index" is available and valid, - * and assumes that the register has been allocated a MIPS register. - * - * Under the current allocation scheme, simply returns nonzero iff the - * given register is live and does not have a hardware register allocated. - */ -#define IS_SPILLED(reg_index) \ - (block->regs[(reg_index)].birth < insn_index \ - && block->regs[(reg_index)].native_reg == MIPS_noreg) - -/** - * MAP_REGISTER: Look up the MIPS register mapped to the given RTL - * register and store it in a local variable. Pass one of the identifiers - * "dest", "src1", "src2", "dest2", or "target" as the "which" parameter; - * the MIPS register will be stored in the corresponding variable ("dest2" - * and "target" must be declared in any blocks that use them). If the RTL - * register does not have an assigned MIPS register, it is loaded into a - * temporary register. - * - * If the MIPS register must not collide with another register used by the - * same instruction, pass the RTL register index of that register as the - * "avoid" parameter (e.g. insn->src1 or insn->src2). If the register to - * be mapped is currently spilled and loading it would cause the "avoid" - * register to be spilled, it is loaded into $at and left spilled. If - * there is no register to avoid, pass 0 as the "avoid" parameter. - * - * The "reload" parameter indicates whether the register should be reloaded - * if it is not currently active. At the moment, this only applies to - * registers located on the stack. - */ -#define MAP_REGISTER(which,reload,avoid) do { \ - which = __MAP_REGISTER(block, insn->which, (reload), (avoid)); \ - if (UNLIKELY(which < 0)) { \ - return 0; \ - } \ -} while (0) -static int __MAP_REGISTER(RTLBlock * const block, const unsigned int reg_index, - const int reload, const uint32_t avoid_index) -{ - RTLRegister * const reg = &block->regs[reg_index]; - PRECOND(reg->native_allocated, return -1); - int mips_reg = reg->native_reg; - if (mips_reg == MIPS_noreg) { - mips_reg = MIPS_at; - if (block->mips.reg_map[mips_reg] == &block->regs[(avoid_index)]) { - mips_reg = MIPS_v1; - } - PRECOND(reg->frame_allocated, return -1); - if (reload - && UNLIKELY(!append_insn(block, MIPS_LW(mips_reg, reg->stack_offset, - MIPS_sp))) - ) { - return -1; - } - } - /* If it's in HI or LO, pull it out */ - if (reg->mips.is_in_hilo) { - APPEND(reg->mips.is_in_hilo | mips_reg<<11); - reg->mips.is_in_hilo = 0; - /* We don't clear the register from block->mips.{hi,lo}_reg, in - * case a subsequent madd/maddu instruction can make use of it */ - } - /* Update the register map unless we're using $zero */ - if (mips_reg != MIPS_zero) { - block->mips.reg_map[mips_reg] = reg; - } - /* Update the stack frame map if this register has a frame slot */ - if (reg->frame_allocated) { - block->mips.frame_map[reg->frame_slot] = reg; - } - return mips_reg; -} - -/** - * MAYBE_SAVE: Save the given register ("dest" or "dest2") to its frame - * slot if one is assigned. - */ -#define MAYBE_SAVE(reg) do { \ - RTLRegister * const regptr = &block->regs[insn->reg]; \ - if (regptr->frame_allocated) { \ - APPEND(MIPS_SW(reg, regptr->stack_offset, MIPS_sp)); \ - } \ -} while (0) - -/*************************************************************************/ - -/** - * translate_block: Perform the actual translation of an RTL block. - * - * [Parameters] - * block: RTL block to translate - * [Return value] - * Nonzero on success, zero on error - */ -static int translate_block(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(block->label_offsets != NULL, return 0); - - int32_t i; - - /* Clear translation state */ - memset(block->mips.reg_map, 0, sizeof(block->mips.reg_map)); - block->mips.hi_reg = 0; - block->mips.lo_reg = 0; - memset(block->mips.frame_map, 0, sizeof(block->mips.frame_map)); - - /* Determine the total frame size, including space for saving and - * restoring callee-saved registers on entry/exit as well as for - * saving caller-saved registers around a CALL instruction */ - if (block->mips.need_save_ra || block->mips.frame_used) { - block->mips.total_frame_size = - MIPS_FRAME_SIZE + 4*16 // 16 caller-saved regs (not $at/$v1) - + 4; // $ra - } else { - block->mips.total_frame_size = 0; // No space needed for CALLs - } - for (i = 0; i < lenof(callee_saved_regs); i++) { - const unsigned int mips_reg = callee_saved_regs[i]; - if (block->mips.sreg_used & (1 << mips_reg)) { - block->mips.total_frame_size += 4; - } - } - block->mips.total_frame_size = - (block->mips.total_frame_size + 4) & -8; // Must be a multiple of 8 - - /* Start with the function prologue */ - if (UNLIKELY(!append_prologue(block))) { - return 0; - } - - /* Translate code a unit at a time */ - for (i = 0; i >= 0; i = block->units[i].next_unit) { - if (UNLIKELY(!translate_unit(block, i))) { - return 0; - } - } - - /* Append the function epilogue */ - if (UNLIKELY(!append_epilogue(block))) { - return 0; - } - - /* Resolve branches to labels */ - if (UNLIKELY(!resolve_branches(block))) { - return 0; - } - - /* Finished */ - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * translate_unit: Translate an RTL basic unit into MIPS code. - * - * [Parameters] - * block: RTL block being translated - * unit_index: Index of basic unit to translate - * [Return value] - * Nonzero on success, zero on error - */ -static inline int translate_unit(RTLBlock * const block, - const unsigned int unit_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(block->label_offsets != NULL, return 0); - PRECOND(unit_index < block->num_units, return 0); - - RTLUnit * const unit = &block->units[unit_index]; - uint32_t i; - - /* Reset the current register map to that at the beginning of the unit - * as determined by flow analysis during register allocation */ - memcpy(block->mips.reg_map, unit->mips.reg_map, sizeof(unit->mips.reg_map)); - - /* Translate each RTL instruction in the unit */ - block->mips.unit_start = block->native_length; - i = unit->first_insn; - while ((int32_t)i <= unit->last_insn) { - const unsigned int num_processed = translate_insn(block, unit_index, i); - if (UNLIKELY(!num_processed)) { - return 0; - } - i += num_processed; - } - - /* Flush out any values cached in HI/LO for safety */ - if (UNLIKELY(!flush_hilo(block, unit->last_insn+1))) { - return 0; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * translate_insn: Translate a single RTL instruction into MIPS code. - * Optimization may result in multiple RTL instructions being parsed. - * - * [Parameters] - * block: RTL block being translated - * unit_index: Index of basic unit being translated - * insn_index: Index of RTL instruction to translate - * [Return value] - * Number of RTL instructions processed (nonzero) on success, zero on error - */ -static inline unsigned int translate_insn(RTLBlock * const block, - const unsigned int unit_index, - const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(block->label_offsets != NULL, return 0); - PRECOND(insn_index < block->num_insns, return 0); - - const RTLInsn *insn = &block->insns[insn_index]; - int dest, src1, src2; // MIPS register indices (mapped only when needed) - - block->mips.reg_map[MIPS_at] = NULL; // For MAP_REGISTER() - - /*------------------------------*/ - - switch ((RTLOpcode)insn->opcode) { - - case RTLOP_NOP: -#ifdef RTL_TRACE_STEALTH_FOR_SH2 - if (insn->src_imm >> 28 == 0x8 || insn->src_imm >> 28 == 0xA) { - return sh2_stealth_trace_insn(block, insn_index); - } else if (insn->src_imm >> 28 == 0xB) { - return sh2_stealth_cache_reg(block, insn_index); - } else if (insn->src_imm >> 28 == 0xC) { - return sh2_stealth_trace_store(block, insn_index); - } -#endif // RTL_TRACE_STEALTH_FOR_SH2 - if (insn->src_imm != 0) { - /* Debugging stuff from JIT_DEBUG_INSERT_PC (sh2.c) */ - const uint32_t addr = insn->src_imm; - APPEND(MIPS_LUI(MIPS_zero, addr>>16)); - APPEND(MIPS_ORI(MIPS_zero, MIPS_zero, addr & 0xFFFF)); - } - return 1; - - /*----------------------------*/ - - case RTLOP_MOVE: - if (block->regs[insn->src1].mips.is_in_hilo - && block->regs[insn->src1].death == insn_index - ) { - /* Handle this case specially--if we did it the usual way, - * we'd waste a cycle with MFHI/MFLO to src1 followed by a - * MOVE from src1 to dest. */ - MAP_REGISTER(dest, 0, 0); - APPEND(block->regs[insn->src1].mips.is_in_hilo | dest<<11); - block->regs[insn->src1].mips.is_in_hilo = 0; - } else { - MAP_REGISTER(src1, 1, 0); - /* Note: we have to map the output operand _after_ all the input - * operands, or else the output operand will get spilled if it - * shares a hardware register with an input operand. (This isn't - * actually true with the current allocation scheme, since we never - * share hardware registers between multiple live RTL registers, - * but it's applicable in general, and it doesn't hurt anything to - * do it this way.) */ - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_MOVE(dest, src1)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_SELECT: { - int cond; - int spilled_v1 = 0; - if (block->regs[insn->src1].native_reg != MIPS_noreg) { - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(src2, 1, insn->cond); - MAP_REGISTER(cond, 1, insn->src2); - } else if (block->regs[insn->src2].native_reg != MIPS_noreg) { - MAP_REGISTER(src1, 1, insn->cond); - MAP_REGISTER(src2, 1, 0); - MAP_REGISTER(cond, 1, insn->src1); - } else if (block->regs[insn->cond].native_reg != MIPS_noreg) { - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(src2, 1, insn->src1); - MAP_REGISTER(cond, 1, 0); - } else { - DMSG("%p/%u: WARNING: spilling $v1 to reload all 3 SELECT" - " operands", block, insn_index); - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(src2, 1, insn->src1); - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, -8)); - APPEND(MIPS_SW(MIPS_v1, 0, MIPS_sp)); - APPEND(MIPS_LW(MIPS_v1, - 8 + block->regs[insn->cond].stack_offset, MIPS_sp)); - cond = MIPS_v1; - spilled_v1 = 1; - } - MAP_REGISTER(dest, 0, 0); - if (dest == src1) { - APPEND(MIPS_MOVZ(dest, src2, cond)); - } else if (dest == src2) { - APPEND(MIPS_MOVN(dest, src1, cond)); - } else if (dest == cond) { - DMSG("%p/%u: WARNING: dest==cond ($%u) for SELECT, using slow" - " register swap", block, insn_index, dest); - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, -8)); - APPEND(MIPS_SW(cond, 0, MIPS_sp)); - APPEND(MIPS_SW(src1, 4, MIPS_sp)); - APPEND(MIPS_MOVE(dest, src1)); - APPEND(MIPS_LW(src1, 0, MIPS_sp)); - APPEND(MIPS_MOVZ(dest, src2, src1)); - APPEND(MIPS_LW(src1, 4, MIPS_sp)); - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, 8)); - } else { - APPEND(MIPS_MOVE(dest, src1)); - APPEND(MIPS_MOVZ(dest, src2, cond)); - } - if (spilled_v1) { - APPEND(MIPS_LW(MIPS_v1, 0, MIPS_sp)); - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, 8)); - } - MAYBE_SAVE(dest); - return 1; - } - - case RTLOP_ADD: - return append_alu_reg(block, insn, MIPS_ADDU(0, 0, 0)); - - case RTLOP_SUB: - return append_alu_reg(block, insn, MIPS_SUBU(0, 0, 0)); - - case RTLOP_MULU: - return append_mult_div(block, insn, MIPS_MULTU(0, 0), 0, insn_index); - - case RTLOP_MULS: - return append_mult_div(block, insn, MIPS_MULT(0, 0), 0, insn_index); - - case RTLOP_MADDU: - return append_mult_div(block, insn, MIPS_MADDU(0, 0), 1, insn_index); - - case RTLOP_MADDS: - return append_mult_div(block, insn, MIPS_MADD(0, 0), 1, insn_index); - - case RTLOP_DIVMODU: - return append_mult_div(block, insn, MIPS_DIVU(0, 0), 0, insn_index); - - case RTLOP_DIVMODS: - return append_mult_div(block, insn, MIPS_DIV(0, 0), 0, insn_index); - - case RTLOP_AND: - return append_alu_reg(block, insn, MIPS_AND(0, 0, 0)); - - case RTLOP_OR: - return append_alu_reg(block, insn, MIPS_OR(0, 0, 0)); - - case RTLOP_XOR: - return append_alu_reg(block, insn, MIPS_XOR(0, 0, 0)); - - case RTLOP_NOT: - return append_alu_1op(block, insn, MIPS_NOR(0, 0, MIPS_zero)); - - case RTLOP_SLL: - return append_shift_reg(block, insn, MIPS_SLLV(0, 0, 0)); - - case RTLOP_SRL: - return append_shift_reg(block, insn, MIPS_SRLV(0, 0, 0)); - - case RTLOP_SRA: - return append_shift_reg(block, insn, MIPS_SRAV(0, 0, 0)); - - case RTLOP_ROR: - return append_shift_reg(block, insn, MIPS_RORV(0, 0, 0)); - - case RTLOP_CLZ: - return append_alu_1op(block, insn, MIPS_CLZ(0, 0)); - - case RTLOP_CLO: - return append_alu_1op(block, insn, MIPS_CLZ(0, 0)); - - case RTLOP_SLTU: - return append_alu_reg(block, insn, MIPS_SLTU(0, 0, 0)); - - case RTLOP_SLTS: -#ifdef MIPS_OPTIMIZE_MIN_MAX - { - const int num_insns = optimize_min_max(block, insn_index); - if (num_insns) { - return num_insns; - } - } -#endif - return append_alu_reg(block, insn, MIPS_SLT(0, 0, 0)); - - case RTLOP_BSWAPH: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_WSBH(dest, src1)); - MAYBE_SAVE(dest); - return 1; - - case RTLOP_BSWAPW: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_WSBW(dest, src1)); - MAYBE_SAVE(dest); - return 1; - - case RTLOP_HSWAPW: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_ROR(dest, src1, 16)); - MAYBE_SAVE(dest); - return 1; - - /*----------------------------*/ - - case RTLOP_ADDI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm + 0x8000 < 0x10000) { - APPEND(MIPS_ADDIU(dest, src1, insn->src_imm & 0xFFFF)); - } else { - if (insn->src_imm < 0x10000) { - APPEND(MIPS_ORI(MIPS_v1, MIPS_zero, insn->src_imm & 0xFFFF)); - } else { - APPEND(MIPS_LUI(MIPS_v1, insn->src_imm>>16 & 0xFFFF)); - APPEND(MIPS_ORI(MIPS_v1, MIPS_v1, insn->src_imm & 0xFFFF)); - } - APPEND(MIPS_ADDU(dest, src1, MIPS_v1)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_ANDI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm < 0x10000) { - APPEND(MIPS_ANDI(dest, src1, insn->src_imm & 0xFFFF)); - } else if (insn->src_imm == 0xFFFFFFFF) { - if (dest != src1) { - APPEND(MIPS_MOVE(dest, src1)); - } - } else if (((insn->src_imm & 1) - && !(insn->src_imm & (insn->src_imm+1))) - || (!(insn->src_imm & 1) - && !(~insn->src_imm & (~insn->src_imm+1))) - ) { - unsigned int start, count; - if (insn->src_imm & 1) { - count = __builtin_clz(insn->src_imm); - start = 32 - count; - } else { - count = 32 - __builtin_allegrex_clo(insn->src_imm); - start = 0; - } - if (dest != src1) { - APPEND(MIPS_MOVE(dest, src1)); - } - APPEND(MIPS_INS(dest, MIPS_zero, start, count)); - } else { - if (insn->src_imm >= 0xFFFF8000) { - APPEND(MIPS_ADDIU(MIPS_v1, MIPS_zero, insn->src_imm & 0xFFFF)); - } else { - APPEND(MIPS_LUI(MIPS_v1, insn->src_imm>>16 & 0xFFFF)); - APPEND(MIPS_ORI(MIPS_v1, MIPS_v1, insn->src_imm & 0xFFFF)); - } - APPEND(MIPS_AND(dest, src1, MIPS_v1)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_ORI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm < 0x10000) { - APPEND(MIPS_ORI(dest, src1, insn->src_imm & 0xFFFF)); - } else { - if (insn->src_imm >= 0xFFFF8000) { - APPEND(MIPS_ADDIU(MIPS_v1, MIPS_zero, insn->src_imm & 0xFFFF)); - } else { - APPEND(MIPS_LUI(MIPS_v1, insn->src_imm>>16 & 0xFFFF)); - APPEND(MIPS_ORI(MIPS_v1, MIPS_v1, insn->src_imm & 0xFFFF)); - } - APPEND(MIPS_OR(dest, src1, MIPS_v1)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_XORI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm < 0x10000) { - APPEND(MIPS_XORI(dest, src1, insn->src_imm & 0xFFFF)); - } else { - if (insn->src_imm >= 0xFFFF8000) { - APPEND(MIPS_ADDIU(MIPS_v1, MIPS_zero, insn->src_imm & 0xFFFF)); - } else { - APPEND(MIPS_LUI(MIPS_v1, insn->src_imm>>16 & 0xFFFF)); - APPEND(MIPS_ORI(MIPS_v1, MIPS_v1, insn->src_imm & 0xFFFF)); - } - APPEND(MIPS_XOR(dest, src1, MIPS_v1)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_SLLI: - MAP_REGISTER(src1, 1, 0); -#ifdef MIPS_OPTIMIZE_SEX - if ((insn->src_imm == 16 || insn->src_imm == 24) - && block->regs[insn->dest].death == insn_index+1 - && insn[1].opcode == RTLOP_SRAI - && insn[1].src1 == insn->dest - && insn[1].src_imm == insn->src_imm - ) { - insn++; - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm == 16) { - APPEND(MIPS_SEH(dest, src1)); - } else { - APPEND(MIPS_SEB(dest, src1)); - } - MAYBE_SAVE(dest); - return 2; - } -#endif - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm < 32) { - APPEND(MIPS_SLL(dest, src1, insn->src_imm)); - } else { - APPEND(MIPS_MOVE(dest, MIPS_zero)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_SRLI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm < 32) { - APPEND(MIPS_SRL(dest, src1, insn->src_imm)); - } else { - APPEND(MIPS_MOVE(dest, MIPS_zero)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_SRAI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm < 32) { - APPEND(MIPS_SRA(dest, src1, insn->src_imm)); - } else { - APPEND(MIPS_SRA(dest, src1, 31)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_RORI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_ROR(dest, src1, insn->src_imm & 31)); - MAYBE_SAVE(dest); - return 1; - - case RTLOP_SLTUI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm + 0x8000 < 0x10000) { - APPEND(MIPS_SLTIU(dest, src1, insn->src_imm & 0xFFFF)); - } else { - if (insn->src_imm < 0x10000) { - APPEND(MIPS_ORI(MIPS_v1, MIPS_zero, insn->src_imm & 0xFFFF)); - } else { - APPEND(MIPS_LUI(MIPS_v1, insn->src_imm>>16 & 0xFFFF)); - APPEND(MIPS_ORI(MIPS_v1, MIPS_v1, insn->src_imm & 0xFFFF)); - } - APPEND(MIPS_SLTU(dest, src1, MIPS_v1)); - } - MAYBE_SAVE(dest); - return 1; - - case RTLOP_SLTSI: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - if (insn->src_imm + 0x8000 < 0x10000) { - APPEND(MIPS_SLTI(dest, src1, insn->src_imm & 0xFFFF)); - } else { - if (insn->src_imm < 0x10000) { - APPEND(MIPS_ORI(MIPS_v1, MIPS_zero, insn->src_imm & 0xFFFF)); - } else { - APPEND(MIPS_LUI(MIPS_v1, insn->src_imm>>16 & 0xFFFF)); - APPEND(MIPS_ORI(MIPS_v1, MIPS_v1, insn->src_imm & 0xFFFF)); - } - APPEND(MIPS_SLT(dest, src1, MIPS_v1)); - } - MAYBE_SAVE(dest); - return 1; - - /*----------------------------*/ - - case RTLOP_BFEXT: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_EXT(dest, src1, - insn->bitfield.start, insn->bitfield.count)); - MAYBE_SAVE(dest); - return 1; - - case RTLOP_BFINS: - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(dest, 0, 0); - if (dest != src1) { - APPEND(MIPS_MOVE(dest, src1)); - } - MAP_REGISTER(src2, 1, insn->dest); - APPEND(MIPS_INS(dest, src2, - insn->bitfield.start, insn->bitfield.count)); - MAYBE_SAVE(dest); - return 1; - - /*----------------------------*/ - - case RTLOP_LOAD_IMM: { - const uint32_t value = insn->src_imm; - MAP_REGISTER(dest, 0, 0); - if (value + 0x8000 < 0x10000) { - APPEND(MIPS_ADDIU(dest, MIPS_zero, value)); - } else if (value < 0x10000) { - APPEND(MIPS_ORI(dest, MIPS_zero, value)); - } else { - APPEND(MIPS_LUI(dest, value>>16)); - if (value & 0xFFFF) { - APPEND(MIPS_ORI(dest, dest, value & 0xFFFF)); - } - } - MAYBE_SAVE(dest); - return 1; - } - - case RTLOP_LOAD_ADDR: { - const uint32_t value = insn->src_addr; -#ifdef MIPS_OPTIMIZE_ABSOLUTE_CALL - if (block->regs[insn->dest].source == RTLREG_CONSTANT - && block->regs[insn->dest].birth == insn_index - && block->regs[insn->dest].death == insn_index+1 - && insn[1].opcode == RTLOP_CALL - && insn[1].target == insn->dest - ) { - /* Just skip the instruction; CALL will detect the constant and - * handle it properly */ - return 1; - } -#endif - MAP_REGISTER(dest, 0, 0); - if (value + 0x8000 < 0x10000) { - APPEND(MIPS_ADDIU(dest, MIPS_zero, value)); - } else if (value < 0x10000) { - APPEND(MIPS_ORI(dest, MIPS_zero, value)); - } else { - APPEND(MIPS_LUI(dest, value>>16)); - if (value & 0xFFFF) { - APPEND(MIPS_ORI(dest, dest, value & 0xFFFF)); - } - } - MAYBE_SAVE(dest); - return 1; - } - - case RTLOP_LOAD_PARAM: { - const uint32_t param_index = insn->src_imm; - if (UNLIKELY(param_index > 8)) { - DMSG("Only 8 function parameters supported, index %u is invalid", - param_index); - return 0; - } - const unsigned int param_reg = MIPS_a0 + param_index; - MAP_REGISTER(dest, 0, 0); - if (dest != param_reg) { - APPEND(MIPS_MOVE(dest, param_reg)); - } - MAYBE_SAVE(dest); - return 1; - } - - case RTLOP_LOAD_BU: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND_FLOAT(MIPS_LBU(dest, insn->offset, src1), 3); - MAYBE_SAVE(dest); - return 1; - - case RTLOP_LOAD_BS: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND_FLOAT(MIPS_LB(dest, insn->offset, src1), 3); - MAYBE_SAVE(dest); - return 1; - - case RTLOP_LOAD_HU: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND_FLOAT(MIPS_LHU(dest, insn->offset, src1), 3); - MAYBE_SAVE(dest); - return 1; - - case RTLOP_LOAD_HS: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND_FLOAT(MIPS_LH(dest, insn->offset, src1), 3); - MAYBE_SAVE(dest); - return 1; - - case RTLOP_LOAD_W: - case RTLOP_LOAD_PTR: - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND_FLOAT(MIPS_LW(dest, insn->offset, src1), 3); - MAYBE_SAVE(dest); - return 1; - - /*----------------------------*/ - - case RTLOP_STORE_B: - /* "dest" is actually a source operand here */ - MAP_REGISTER(src1, 1, insn->dest); - MAP_REGISTER(dest, 1, insn->src1); - APPEND(MIPS_SB(src1, insn->offset, dest)); - return 1; - - case RTLOP_STORE_H: - MAP_REGISTER(src1, 1, insn->dest); - MAP_REGISTER(dest, 1, insn->src1); - APPEND(MIPS_SH(src1, insn->offset, dest)); - return 1; - - case RTLOP_STORE_W: - case RTLOP_STORE_PTR: - MAP_REGISTER(src1, 1, insn->dest); - MAP_REGISTER(dest, 1, insn->src1); - APPEND(MIPS_SW(src1, insn->offset, dest)); - return 1; - - /*----------------------------*/ - - case RTLOP_LABEL: - block->label_offsets[insn->label] = block->native_length; - return 1; - - case RTLOP_GOTO: - /* A branch to the following unit is in effect a no-op, so just - * skip it entirely */ - if (block->label_unitmap[insn->label] == block->units[unit_index].next_unit) { - return 1; - } - /* Flush any cached values out of HI or LO */ - if (UNLIKELY(!flush_hilo(block, insn_index))) { - return 0; - } - /* Fill in a fake opcode for now; this will be replaced later with - * a real branch instruction once the offset is known */ - APPEND_BRANCH(MIPS_B_LABEL(insn->label)); - return 1; - - case RTLOP_GOTO_IF_Z: - case RTLOP_GOTO_IF_NZ: { - if (block->label_unitmap[insn->label] == block->units[unit_index].next_unit) { - return 1; - } - MAP_REGISTER(src1, 1, 0); - /* Make sure it doesn't collide with anything we're about to - * reload, and move to $at if so */ - unsigned int target_unit = block->label_unitmap[insn->label]; - if (block->units[target_unit].first_insn < insn_index) { - RTLRegister * const target_reg = - block->units[target_unit].mips.reg_map[src1]; - if (target_reg && target_reg != &block->regs[insn->src1] - && target_reg->death >= insn_index - ) { - APPEND(MIPS_MOVE(MIPS_at, src1)); - src1 = MIPS_at; - } - } - if (UNLIKELY(!flush_hilo(block, insn_index))) { - return 0; - } - if (insn->opcode == RTLOP_GOTO_IF_Z) { - APPEND_BRANCH(MIPS_BEQZ_LABEL(src1, insn->label)); - } else { - APPEND_BRANCH(MIPS_BNEZ_LABEL(src1, insn->label)); - } - return 1; - } // case RTLOP_GOTO_IF_{Z,NZ} - - case RTLOP_GOTO_IF_E: - case RTLOP_GOTO_IF_NE: { - if (block->label_unitmap[insn->label] == block->units[unit_index].next_unit) { - return 1; - } - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(src2, 1, insn->src1); - unsigned int target_unit = block->label_unitmap[insn->label]; - if (block->units[target_unit].first_insn < insn_index) { - RTLRegister * const target_reg1 = - block->units[target_unit].mips.reg_map[src1]; - if (target_reg1 && target_reg1 != &block->regs[insn->src1] - && target_reg1->death >= insn_index - ) { - if (src2 == MIPS_at) { - APPEND(MIPS_MOVE(MIPS_v1, src1)); - src1 = MIPS_v1; - } else { - APPEND(MIPS_MOVE(MIPS_at, src1)); - src1 = MIPS_at; - } - } - RTLRegister * const target_reg2 = - block->units[target_unit].mips.reg_map[src2]; - if (target_reg2 && target_reg2 != &block->regs[insn->src2] - && target_reg2->death >= insn_index - ) { - if (src1 == MIPS_at) { - APPEND(MIPS_MOVE(MIPS_v1, src2)); - src2 = MIPS_v1; - } else { - APPEND(MIPS_MOVE(MIPS_at, src2)); - src2 = MIPS_at; - } - } - } - if (UNLIKELY(!flush_hilo(block, insn_index))) { - return 0; - } - if (insn->opcode == RTLOP_GOTO_IF_E) { - APPEND_BRANCH(MIPS_BEQ_LABEL(src1, src2, insn->label)); - } else { - APPEND_BRANCH(MIPS_BNE_LABEL(src1, src2, insn->label)); - } - return 1; - } // case RTLOP_GOTO_IF_{E,NE} - - /*----------------------------*/ - - case RTLOP_CALL: { - - /* Map the argument registers, if any */ - src1 = src2 = 0; // Avoid a compiler warning (not actually needed) - if (insn->src1) { - MAP_REGISTER(src1, 1, insn->src2); - if (insn->src2) { - MAP_REGISTER(src2, 1, insn->src1); - } - } - - /* Flush any cached values out of HI or LO */ - if (UNLIKELY(!flush_hilo(block, insn_index))) { - return 0; - } - - /* Flush all live caller-saved registers to the stack */ - if (UNLIKELY(!flush_for_call(block, insn_index))) { - return 0; - } - - /* Map the function address, if necessary */ - int target; -#ifdef MIPS_OPTIMIZE_ABSOLUTE_CALL - if (block->regs[insn->target].source == RTLREG_CONSTANT) { - target = -1; - } else { -#endif - /* Need to avoid collision with both src1 and src2; the - * MAP_REGISTER macro can't handle avoiding two registers at - * once, so we do it manually here, taking advantage of the - * registers reed up by flush_for_call(). This won't actually - * occur in practice as long as MIPS_OPTIMIZE_ABSOLUTE_CALL is - * enabled, since all the calls we make are to known addresses. */ - RTLRegister * const target_reg = &block->regs[insn->target]; - if (target_reg->native_reg == MIPS_noreg - && (src1 == MIPS_v1 || src2 == MIPS_v1) - ) { - PRECOND(target_reg->frame_allocated, return 0); - if (src1 == MIPS_v1) { // Impossible, but just for completeness - if (src2 == MIPS_a0) { - APPEND(MIPS_MOVE(MIPS_a2, src1)); - src1 = MIPS_a2; - } else { - APPEND(MIPS_MOVE(MIPS_a2, src1)); - src1 = MIPS_a2; - } - } else if (src2 == MIPS_v1) { - if (src1 == MIPS_a1) { - APPEND(MIPS_MOVE(MIPS_a2, src2)); - src2 = MIPS_a2; - } else { - APPEND(MIPS_MOVE(MIPS_a1, src2)); - src2 = MIPS_a1; - } - } - APPEND(MIPS_LW(MIPS_v1, target_reg->stack_offset, MIPS_sp)); - target = MIPS_v1; - } else { // No collision - MAP_REGISTER(target, 1, 0); - } -#ifdef MIPS_OPTIMIZE_ABSOLUTE_CALL - } -#endif - - /* Move any parameters to $a0-$a1 */ - if (insn->src1) { - if (insn->src2) { - if (src1 == MIPS_a1) { - if (src2 == MIPS_a0) { - /* Arguments are reversed, so use $at as a - * temporary to exchange them */ - APPEND(MIPS_MOVE(MIPS_at, MIPS_a1)); - src1 = MIPS_at; - } else { - APPEND(MIPS_MOVE(MIPS_a0, MIPS_a1)); - src1 = MIPS_a0; - } - } - if (src2 != MIPS_a1) { - APPEND(MIPS_MOVE(MIPS_a1, src2)); - } - } - if (src1 != MIPS_a0) { - APPEND(MIPS_MOVE(MIPS_a0, src1)); - } - } - - /* Actually call the routine */ -#ifdef MIPS_OPTIMIZE_ABSOLUTE_CALL - if (block->regs[insn->target].source == RTLREG_CONSTANT) { - const uint32_t address = block->regs[insn->target].value; - APPEND_BRANCH(MIPS_JAL((address & 0x0FFFFFFC) >> 2)); - } else { -#endif - APPEND_BRANCH(MIPS_JALR(MIPS_t9)); -#ifdef MIPS_OPTIMIZE_ABSOLUTE_CALL - } -#endif - - /* Copy the return value to the target register, if there is one */ - if (insn->dest) { - MAP_REGISTER(dest, 0, 0); - if (dest != MIPS_v0) { - APPEND(MIPS_MOVE(dest, MIPS_v0)); - } - MAYBE_SAVE(dest); - } - - /* Reload all flushed registers */ - if (UNLIKELY(!reload_after_call(block, insn_index))) { - return 0; - } - - return 1; - } // case RTLOP_CALL - - case RTLOP_RETURN: - if (insn_index == block->units[unit_index].last_insn - && block->units[unit_index].next_unit == -1 - ) { - /* This is the last instruction, so we can just fall through */ - } else { - APPEND_BRANCH(MIPS_B_EPILOGUE_RET_CONST); - } - return 1; - - case RTLOP_RETURN_TO: { - int target; - MAP_REGISTER(target, 1, 0); - if (target != MIPS_at) { - APPEND(MIPS_MOVE(MIPS_at, target)); - } - /* Don't forget to reload parameters. (Since we only use this for - * predicted static branches to other native code, we know that we - * can just pass the first parameter, i.e. the state block pointer, - * along; for a more general implementation, we'd treat this like - * CALL and take parameters.) */ - if (UNLIKELY(block->regs[1].source != RTLREG_PARAMETER) - || UNLIKELY(block->regs[1].param_index != 0) - ) { - DMSG("r1 is not state block, can't handle"); - return 0; - } - if (block->regs[1].native_reg != MIPS_a0) { - APPEND(MIPS_MOVE(MIPS_a0, block->regs[1].native_reg)); - } - APPEND_BRANCH(MIPS_B_EPILOGUE_CHAIN_AT); - block->mips.need_chain_at = 1; - return 1; - } // case RTLOP_RETURN_TO - - } // switch (insn->opcode) - - /*------------------------------*/ - - DMSG("%p/%u: Invalid RTL opcode %u", block, insn_index, insn->opcode); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * append_alu_1op: Append a 1-register-operand ALU instruction to the - * instruction stream. - * - * [Parameters] - * block: RTL block being translated - * insn: RTL instruction being translated - * opcode: Instruction word to add (with rs/rd set to zero) - * [Return value] - * 1 on success, 0 on error - */ -static int append_alu_1op(RTLBlock * const block, const RTLInsn * const insn, - const uint32_t opcode) -{ - PRECOND(block != NULL, return 0); - - int src1, dest; - MAP_REGISTER(src1, 1, 0); - MAP_REGISTER(dest, 0, 0); - APPEND(opcode | src1<<21 | dest<<11); - MAYBE_SAVE(dest); - return 1; -} - -/*----------------------------------*/ - -/** - * append_alu_reg: Append a 2-register-operand ALU instruction (other than - * a shift insturction) to the instruction stream. - * - * [Parameters] - * block: RTL block being translated - * insn: RTL instruction being translated - * opcode: Instruction word to add (with rs/rt/rd set to zero) - * [Return value] - * 1 on success, 0 on error - */ -static int append_alu_reg(RTLBlock * const block, const RTLInsn * const insn, - const uint32_t opcode) -{ - PRECOND(block != NULL, return 0); - - int src1, src2, dest; - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(src2, 1, insn->src1); - MAP_REGISTER(dest, 0, 0); - APPEND(opcode | src1<<21 | src2<<16 | dest<<11); - MAYBE_SAVE(dest); - return 1; -} - -/*----------------------------------*/ - -/** - * append_shift_reg: Append a variable-count shift instruction to the - * instruction stream. - * - * [Parameters] - * block: RTL block being translated - * insn: RTL instruction being translated - * opcode: Instruction word to add (with rs/rt/rd set to zero) - * [Return value] - * 1 on success, 0 on error - */ -static int append_shift_reg(RTLBlock * const block, const RTLInsn * const insn, - const uint32_t opcode) -{ - PRECOND(block != NULL, return 0); - - int src1, src2, dest; - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(src2, 1, insn->src1); - MAP_REGISTER(dest, 0, 0); - /* Register order is reversed from regular ALU insns: SLLV rd,rt,rs - * (as opposed to ADDU rd,rs,rt) */ - APPEND(opcode | src2<<21 | src1<<16 | dest<<11); - MAYBE_SAVE(dest); - return 1; -} - -/*----------------------------------*/ - -/** - * append_mult_div: Append a multiply or divide instruction to the - * instruction stream. - * - * [Parameters] - * block: RTL block being translated - * insn: RTL instruction being translated - * opcode: Instruction word to add (with rs/rt set to zero) - * accumulate: Nonzero if this is an accumulating instruction (madd/maddu) - * insn_index: Index of instruction being translated - * [Return value] - * 1 on success, 0 on error - */ -static int append_mult_div(RTLBlock * const block, const RTLInsn * const insn, - const uint32_t opcode, const int accumulate, - const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - - if (accumulate) { - /* If the proper registers are already in HI and LO, we don't need - * to do anything here */ - if (block->mips.hi_reg != insn->dest2 - || block->mips.lo_reg != insn->dest - ) { - /* Need to reload HI and/or LO; don't bother with the case - * where one of the two is correctly loaded, since normally - * both will be preloaded properly */ - flush_hilo(block, insn_index); - int dest2; - MAP_REGISTER(dest2, 1, 0); - APPEND(MIPS_MTHI(dest2)); - int dest; - MAP_REGISTER(dest, 1, 0); - APPEND(MIPS_MTLO(dest)); - } - } else { - /* Make sure anything currently in HI/LO is flushed out before we - * overwrite them */ - flush_hilo(block, insn_index); - } - - int src1, src2; - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(src2, 1, insn->src1); - const int float_distance = ((opcode & 0x3E) == __SP_DIV) ? 35 : 6; - APPEND_FLOAT(opcode | src1<<21 | src2<<16, float_distance); - if (insn->dest) { - if (block->regs[insn->dest].frame_allocated) { - /* We have to save it to the stack, so it can't stay in LO */ - int dest; - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_MFLO(dest)); - MAYBE_SAVE(dest); - } else { - /* Leave it in LO for now; we'll extract it when we need it */ - block->regs[insn->dest].mips.is_in_hilo = MIPS_MFLO(0); - block->mips.lo_reg = insn->dest; - } - } - if (insn->dest2) { - if (block->regs[insn->dest2].frame_allocated) { - int dest2; - MAP_REGISTER(dest2, 0, 0); - APPEND(MIPS_MFHI(dest2)); - MAYBE_SAVE(dest2); - } else { - block->regs[insn->dest2].mips.is_in_hilo = MIPS_MFHI(0); - block->mips.hi_reg = insn->dest2; - } - } - return 1; -} - -/*************************************************************************/ - -/** - * flush_for_call: Flush all caller-saved registers to the stack frame in - * preparation for a subroutine call. Registers which are born on or die - * with the current instruction are not saved; the destination register is - * also not saved (normally the destination register will be born with this - * instruction, but if the code is not SSA-form, it may already be live). - * - * [Parameters] - * block: RTL block being translated - * insn_index: Index of instruction being translated - * [Return value] - * Nonzero on success, zero on error - */ -static int flush_for_call(RTLBlock * const block, const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(insn_index < block->num_insns, return 0); - - const uint32_t dest = block->insns[insn_index].dest; - - unsigned int push_offset = MIPS_FRAME_SIZE; - unsigned int i; - for (i = 0; i < lenof(caller_saved_regs); i++) { - const unsigned int mips_reg = caller_saved_regs[i]; - RTLRegister * const reg = block->mips.reg_map[mips_reg]; - if (reg - && reg->birth < insn_index - && reg->death > insn_index - && !(dest && reg == &block->regs[dest]) - && reg->source != RTLREG_CONSTANT - ) { - APPEND(MIPS_SW(mips_reg, push_offset, MIPS_sp)); - push_offset += 4; - } - } - - return 1; -} - -/*----------------------------------*/ - -/** - * reload_after_call: Reload necessary caller-saved registers after a - * subroutine call. - * - * [Parameters] - * block: RTL block being translated - * insn_index: Index of instruction being translated - * [Return value] - * Nonzero on success, zero on error - */ -static int reload_after_call(RTLBlock * const block, - const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(insn_index < block->num_insns, return 0); - - const uint32_t dest = block->insns[insn_index].dest; - - unsigned int pop_offset = MIPS_FRAME_SIZE; - unsigned int i; - for (i = 0; i < lenof(caller_saved_regs); i++) { - const unsigned int mips_reg = caller_saved_regs[i]; - RTLRegister * const reg = block->mips.reg_map[mips_reg]; - if (reg - && reg->birth < insn_index - && reg->death > insn_index - && !(dest && reg == &block->regs[dest]) - ) { - if (reg->source == RTLREG_CONSTANT) { - const uint32_t value = reg->value; - if (value + 0x8000 < 0x10000) { - APPEND(MIPS_ADDIU(mips_reg, MIPS_zero, value)); - } else if (value < 0x10000) { - APPEND(MIPS_ORI(mips_reg, MIPS_zero, value)); - } else { - APPEND(MIPS_LUI(mips_reg, value>>16)); - if (value & 0xFFFF) { - APPEND(MIPS_ORI(mips_reg, mips_reg, value & 0xFFFF)); - } - } - } else { - APPEND(MIPS_LW(mips_reg, pop_offset, MIPS_sp)); - pop_offset += 4; - } - } - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * flush_hilo: Flush any values cached in the MIPS HI or LO registers to - * the appropriate general-purpose register. - * - * [Parameters] - * block: RTL block being translated - * insn_index: Index of RTL instruction being translated (if between - * instructions, next instruction to be translated) - * [Return value] - * Nonzero on success, zero on error - */ -static int flush_hilo(RTLBlock * const block, const uint32_t insn_index) -{ - if (block->mips.hi_reg) { - RTLRegister * const reg = &block->regs[block->mips.hi_reg]; - /* If the register was already updated, its is_in_hilo field will - * be zero, so we don't need to update the register ourselves in - * that case; we just clear the register reference from hi_reg. - * Also make sure that we don't try to update a register that's - * already dead. */ - if (reg->mips.is_in_hilo && reg->death >= insn_index) { - PRECOND(reg->mips.is_in_hilo == MIPS_MFHI(0), return 0); - PRECOND(reg->native_allocated, return 0); - PRECOND(reg->native_reg != MIPS_noreg, return 0); - PRECOND(reg->native_reg != MIPS_zero, return 0); - APPEND(reg->mips.is_in_hilo | reg->native_reg<<11); - reg->mips.is_in_hilo = 0; - block->mips.reg_map[reg->native_reg] = reg; - } - block->mips.hi_reg = 0; - } - if (block->mips.lo_reg) { - RTLRegister * const reg = &block->regs[block->mips.lo_reg]; - if (reg->mips.is_in_hilo && reg->death >= insn_index) { - PRECOND(reg->mips.is_in_hilo == MIPS_MFLO(0), return 0); - PRECOND(reg->native_allocated, return 0); - PRECOND(reg->native_reg != MIPS_noreg, return 0); - PRECOND(reg->native_reg != MIPS_zero, return 0); - APPEND(reg->mips.is_in_hilo | reg->native_reg<<11); - reg->mips.is_in_hilo = 0; - block->mips.reg_map[reg->native_reg] = reg; - } - block->mips.lo_reg = 0; - } - return 1; -} - -/*************************************************************************/ - -#ifdef MIPS_OPTIMIZE_MIN_MAX - -/** - * optimize_min_max: Attempt to optimize an SLTS instruction followed by a - * SELECT instruction into a MIPS MIN or MAX instruction. - * - * [Parameters] - * block: RTL block being translated - * insn_index: Index of RTL instruction to optimize (must be SLTS) - * [Return value] - * Number of RTL instructions processed (nonzero) if the given RTL - * instruction was successfully optimized into a MIPS MIN or MAX - * instruction, else zero - */ -static int optimize_min_max(RTLBlock * const block, const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn_index < block->num_insns, return 0); - PRECOND(block->insns[insn_index].opcode == RTLOP_SLTS, return 0); - - const RTLInsn *insn = &block->insns[insn_index]; - - if (block->regs[insn->dest].death != insn_index+1 - || insn[1].opcode != RTLOP_SELECT - || insn[1].cond != insn->dest - ) { - return 0; - } else if (insn[1].src1 == insn->src1 && insn[1].src2 == insn->src2) { - insn++; - int src1, src2, dest; - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(src2, 1, insn->src1); - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_MIN(dest, src1, src2)); - return 2; - } else if (insn[1].src1 == insn->src2 && insn[1].src2 == insn->src1) { - insn++; - int src1, src2, dest; - MAP_REGISTER(src1, 1, insn->src2); - MAP_REGISTER(src2, 1, insn->src1); - MAP_REGISTER(dest, 0, 0); - APPEND(MIPS_MAX(dest, src1, src2)); - return 2; - } else { - return 0; - } -} - -#endif // MIPS_OPTIMIZE_MIN_MAX - -/*************************************************************************/ - -#ifdef RTL_TRACE_STEALTH_FOR_SH2 - -/*----------------------------------*/ - -/** - * sh2_stealth_trace_insn: Add MIPS code to trace an instruction for SH-2 - * TRACE_STEALTH mode. - * - * [Parameters] - * block: RTL block being translated - * insn_index: Index of RTL instruction to translate - * [Return value] - * Number of RTL instructions processed (nonzero) on success, zero on error - */ -static unsigned int sh2_stealth_trace_insn(RTLBlock * const block, - const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(block->label_offsets != NULL, return 0); - PRECOND(insn_index < block->num_insns, return 0); - - if (block->regs[1].source != RTLREG_PARAMETER - || block->regs[1].param_index != 0 - ) { - DMSG("r1 is not state block, can't handle"); - return 0; - } - - const RTLInsn *insn = &block->insns[insn_index]; - unsigned int num_insns = 1; // Number of RTL instructions consumed - unsigned int cond_reg = 0; - unsigned int test_bit = 0; - uint32_t op = insn[num_insns++].src_imm; - if (op>>24 == 0x9F) { // Conditional execution - cond_reg = op & 0xFFFF; - test_bit = op>>16 & 1; - op = insn[num_insns++].src_imm; - } - uint32_t cached_cycles = op; - PRECOND(cached_cycles>>24 == 0x98, return 1); - cached_cycles &= 0xFFFF; - uint32_t cached_cycle_reg = insn[num_insns++].src_imm; - PRECOND(cached_cycles>>24 == 0x90, return 1); - cached_cycle_reg &= 0xFFFF; - - /* First save all registers; load the state block pointer into $at in - * the delay slot */ - APPEND(MIPS_JAL(((uintptr_t)code_save_regs_state & 0x0FFFFFFC) >> 2)); - if (IS_SPILLED(1)) { - APPEND(MIPS_LW(MIPS_at, block->regs[1].stack_offset, MIPS_sp)); - } else { - APPEND(MIPS_MOVE(MIPS_at, block->regs[1].native_reg)); - } - - /* Update the state block with cached register values */ - uint32_t mask = block->sh2_regcache_mask; - if (mask) { - const uintptr_t cache_ptr = (uintptr_t)sh2_regcache; - APPEND(MIPS_LUI(MIPS_a0, cache_ptr >> 16)); - APPEND(MIPS_ORI(MIPS_a0, MIPS_a0, cache_ptr & 0xFFFF)); - } - unsigned int sh2_reg; - for (sh2_reg = 0; mask != 0; mask >>= 1, sh2_reg++) { - if (mask & 1) { - APPEND(MIPS_LW(MIPS_v1, 4*sh2_reg, MIPS_a0)); - APPEND(MIPS_SW(MIPS_v1, 4*sh2_reg, MIPS_at)); - } - } - - /* Update the state block's cached cycle count */ - if (cached_cycle_reg) { - RTLRegister * const reg = &block->regs[cached_cycle_reg]; - if (IS_SPILLED(cached_cycle_reg)) { - APPEND(MIPS_LW(MIPS_v1, 4*(18+24) + reg->stack_offset, MIPS_sp)); - } else if (reg->native_reg >= MIPS_v0 && reg->native_reg <= MIPS_t7) { - APPEND(MIPS_LW(MIPS_v1, 4*(reg->native_reg - MIPS_v0), MIPS_sp)); - } else if (reg->native_reg >= MIPS_t8 && reg->native_reg <= MIPS_t9) { - APPEND(MIPS_LW(MIPS_v1, - 4*(reg->native_reg - MIPS_t8 + 14), MIPS_sp)); - } else { - APPEND(MIPS_MOVE(MIPS_v1, reg->native_reg)); - } - } - APPEND(MIPS_ADDI(MIPS_v1, MIPS_v1, cached_cycles)); - APPEND(MIPS_SW(MIPS_v1, offsetof(SH2State,cycles), MIPS_at)); - - /* Call the trace routine (if the instruction isn't nulled out) */ - if (cond_reg) { - if (IS_SPILLED(cond_reg)) { - APPEND(MIPS_LW(MIPS_v1, 4*(18+24) + block->regs[cond_reg].stack_offset, MIPS_sp)); - } else if (block->regs[cond_reg].native_reg >= MIPS_v0 - && block->regs[cond_reg].native_reg <= MIPS_t7) { - APPEND(MIPS_LW(MIPS_v1, 4*(block->regs[cond_reg].native_reg - MIPS_v0), MIPS_sp)); - } else if (block->regs[cond_reg].native_reg >= MIPS_t8 - && block->regs[cond_reg].native_reg <= MIPS_t9) { - APPEND(MIPS_LW(MIPS_v1, 4*(block->regs[cond_reg].native_reg - MIPS_t8 + 14), MIPS_sp)); - } else { - APPEND(MIPS_MOVE(MIPS_v1, block->regs[cond_reg].native_reg)); - } - APPEND(MIPS_XORI(MIPS_v1, MIPS_v1, test_bit)); - APPEND(MIPS_BNEZ(MIPS_v1, 4)); - } - APPEND(MIPS_LUI(MIPS_a1, (insn->src_imm & 0x7FFF0000) >> 16)); - APPEND(MIPS_ORI(MIPS_a1, MIPS_a1, insn->src_imm & 0xFFFF)); - APPEND(MIPS_JAL(((uintptr_t)trace_insn_callback & 0x0FFFFFFC) >> 2)); - APPEND(MIPS_MOVE(MIPS_a0, MIPS_at)); - - /* Restore everything back the way it was */ - APPEND(MIPS_JAL(((uintptr_t)code_restore_regs_state & 0x0FFFFFFC) >> 2)); - if (IS_SPILLED(1)) { - APPEND(MIPS_LW(MIPS_at, - 4*(18+24) + block->regs[1].stack_offset, MIPS_sp)); - } else if (block->regs[1].native_reg >= MIPS_v0 - && block->regs[1].native_reg <= MIPS_t7) { - APPEND(MIPS_LW(MIPS_at, - 4*(block->regs[1].native_reg - MIPS_v0), MIPS_sp)); - } else if (block->regs[1].native_reg >= MIPS_t8 - && block->regs[1].native_reg <= MIPS_t9) { - APPEND(MIPS_LW(MIPS_at, - 4*(block->regs[1].native_reg - MIPS_t8 + 14), MIPS_sp)); - } else { - APPEND(MIPS_MOVE(MIPS_at, block->regs[1].native_reg)); - } - - return num_insns; -} - -/*----------------------------------*/ - -/** - * sh2_stealth_cache_reg: Add MIPS code to cache a register value for - * SH-2 TRACE_STEALTH mode. - * - * [Parameters] - * block: RTL block being translated - * insn_index: Index of RTL instruction to translate - * [Return value] - * Number of RTL instructions processed (nonzero) on success, zero on error - */ -static unsigned int sh2_stealth_cache_reg(RTLBlock * const block, - const uint32_t insn_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(block->label_offsets != NULL, return 0); - PRECOND(insn_index < block->num_insns, return 0); - - const RTLInsn *insn = &block->insns[insn_index]; - unsigned int num_insns = 1; - uint32_t op = insn->src_imm; - uint32_t offset = 0; - - /* Get the offset if we have one */ - if (op & 0x08000000) { - PRECOND(op>>24 == 0xB8, return 1); - offset = (op & 0xFFFF) << 16; - op = insn[num_insns++].src_imm; - PRECOND(op>>24 == 0xBC, return 1); - offset |= op & 0xFFFF; - op = insn[num_insns++].src_imm; - PRECOND(op>>24 == 0xB0, return 1); - } - - unsigned int sh2_reg = (op >> 16) & 0xFF; - unsigned int rtl_reg = op & 0xFFFF; - - if (rtl_reg) { - /* Store a new value into the cache */ - - const RTLRegister * const reg = &block->regs[rtl_reg]; - unsigned int mips_reg; - if (reg->native_allocated - && reg == block->mips.reg_map[reg->native_reg] - ) { - if (IS_SPILLED(rtl_reg)) { - APPEND(MIPS_LW(MIPS_at, reg->stack_offset, MIPS_sp)); - mips_reg = MIPS_at; - } else if (reg->mips.is_in_hilo) { - APPEND(reg->mips.is_in_hilo | MIPS_at<<11); - mips_reg = MIPS_at; - } else if (reg->native_reg == MIPS_a0) { - APPEND(MIPS_MOVE(MIPS_at, MIPS_a0)); - mips_reg = MIPS_at; - } else { - mips_reg = reg->native_reg; - } - } else { - /* Either the register is already dead and got clobbered, or it - * got eliminated perhaps because the corresponding SH-2 - * register was later overwritten. This is a pain if the - * dead/eliminated register is a result register, but what can - * we do... */ - switch (reg->source) { - - case RTLREG_CONSTANT: - APPEND(MIPS_LUI(MIPS_at, reg->value >> 16)); - APPEND(MIPS_ORI(MIPS_at, MIPS_at, reg->value & 0xFFFF)); - break; - - case RTLREG_MEMORY: { - const RTLRegister * const addr_reg = - &block->regs[reg->memory.addr_reg]; - unsigned int base_reg; - if (addr_reg->native_allocated - && addr_reg==block->mips.reg_map[addr_reg->native_reg] - ) { - base_reg = addr_reg->native_reg; - } else if (addr_reg->source == RTLREG_CONSTANT) { - APPEND(MIPS_LUI(MIPS_at, addr_reg->value>>16 & 0xFFFF)); - APPEND(MIPS_ORI(MIPS_at, MIPS_at, addr_reg->value&0xFFFF)); - base_reg = MIPS_at; - } else { - DMSG("%p/%u: Address register r%u not available for r%u", - block, insn_index, reg->memory.addr_reg, rtl_reg); - break; - } - if (reg->memory.size == 1) { // 8 bits - if (reg->memory.is_signed) { - APPEND(MIPS_LB(MIPS_at, reg->memory.offset, base_reg)); - } else { - APPEND(MIPS_LBU(MIPS_at, reg->memory.offset, base_reg)); - } - } else if (reg->memory.size == 2) { // 16 bits - if (reg->memory.is_signed) { - APPEND(MIPS_LH(MIPS_at, reg->memory.offset, base_reg)); - } else { - APPEND(MIPS_LHU(MIPS_at, reg->memory.offset, base_reg)); - } - } else { // 32 bits - APPEND(MIPS_LW(MIPS_at, reg->memory.offset, base_reg)); - } - break; - } // case RTLREG_MEMORY - - case RTLREG_RESULT: - case RTLREG_RESULT_NOFOLD: { - static const uint32_t mips_opcodes[] = { - [RTLOP_ADD ] = MIPS_ADDU (MIPS_at, 0, 0), - [RTLOP_ADDI ] = MIPS_ADDU (MIPS_at, 0, 0), - [RTLOP_SUB ] = MIPS_SUBU (MIPS_at, 0, 0), - [RTLOP_MULU ] = MIPS_MULTU(0, 0), - [RTLOP_MULS ] = MIPS_MULT (0, 0), - [RTLOP_DIVMODU] = MIPS_DIVU (0, 0), - [RTLOP_DIVMODS] = MIPS_DIV (0, 0), - [RTLOP_AND ] = MIPS_AND (MIPS_at, 0, 0), - [RTLOP_ANDI ] = MIPS_AND (MIPS_at, 0, 0), - [RTLOP_OR ] = MIPS_OR (MIPS_at, 0, 0), - [RTLOP_ORI ] = MIPS_OR (MIPS_at, 0, 0), - [RTLOP_XOR ] = MIPS_XOR (MIPS_at, 0, 0), - [RTLOP_XORI ] = MIPS_XOR (MIPS_at, 0, 0), - [RTLOP_NOT ] = MIPS_NOR (MIPS_at, 0, MIPS_zero), - [RTLOP_SLL ] = MIPS_SLLV (MIPS_at, 0, 0), - [RTLOP_SLLI ] = MIPS_SLLV (MIPS_at, 0, 0), - [RTLOP_SRL ] = MIPS_SRLV (MIPS_at, 0, 0), - [RTLOP_SRLI ] = MIPS_SRLV (MIPS_at, 0, 0), - [RTLOP_SRA ] = MIPS_SRAV (MIPS_at, 0, 0), - [RTLOP_SRAI ] = MIPS_SRAV (MIPS_at, 0, 0), - [RTLOP_ROR ] = MIPS_RORV (MIPS_at, 0, 0), - [RTLOP_RORI ] = MIPS_RORV (MIPS_at, 0, 0), - [RTLOP_CLZ ] = MIPS_CLZ (MIPS_at, 0), - [RTLOP_CLO ] = MIPS_CLO (MIPS_at, 0), - [RTLOP_SLTU ] = MIPS_SLTU (MIPS_at, 0, 0), - [RTLOP_SLTUI ] = MIPS_SLTU (MIPS_at, 0, 0), - [RTLOP_SLTS ] = MIPS_SLT (MIPS_at, 0, 0), - [RTLOP_SLTSI ] = MIPS_SLT (MIPS_at, 0, 0), - [RTLOP_BSWAPH ] = MIPS_WSBH (MIPS_at, 0), - [RTLOP_BSWAPW ] = MIPS_WSBW (MIPS_at, 0), - [RTLOP_HSWAPW ] = MIPS_ROR (MIPS_at, 0, 16), - }; - const RTLRegister *src1_reg, *src2_reg; - src1_reg = &block->regs[reg->result.src1]; - src2_reg = &block->regs[reg->result.src2]; - switch (reg->result.opcode) { - - case RTLOP_MOVE: - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_at, - src1_reg->stack_offset, MIPS_sp)); - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_at<<11); - } else { - APPEND(MIPS_MOVE(MIPS_at, src1_reg->native_reg)); - } - break; - - case RTLOP_NOT: - case RTLOP_CLZ: - case RTLOP_CLO: { - int rs; - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_at, - src1_reg->stack_offset, MIPS_sp)); - rs = MIPS_at; - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_at<<11); - rs = MIPS_at; - } else { - rs = src1_reg->native_reg; - } - APPEND(mips_opcodes[reg->result.opcode] | rs<<21); - break; - } - - case RTLOP_BSWAPH: - case RTLOP_BSWAPW: - case RTLOP_HSWAPW: { - int rt; - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_at, - src1_reg->stack_offset, MIPS_sp)); - rt = MIPS_at; - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_at<<11); - rt = MIPS_at; - } else { - rt = src1_reg->native_reg; - } - APPEND(mips_opcodes[reg->result.opcode] | rt<<16); - break; - } - - case RTLOP_ADD: - case RTLOP_SUB: - case RTLOP_AND: - case RTLOP_OR: - case RTLOP_XOR: - case RTLOP_SLL: - case RTLOP_SRL: - case RTLOP_SRA: - case RTLOP_ROR: - case RTLOP_SLTU: - case RTLOP_SLTS: { - unsigned int rs, rt; // src1/src2 MIPS registers - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_at, src1_reg->stack_offset, MIPS_sp)); - rs = MIPS_at; - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_at<<11); - rs = MIPS_at; - } else { - rs = src1_reg->native_reg; - } - if (IS_SPILLED(reg->result.src2)) { - APPEND(MIPS_LW(MIPS_v1, src2_reg->stack_offset, MIPS_sp)); - rt = MIPS_v1; - } else if (src2_reg->mips.is_in_hilo) { - APPEND(src2_reg->mips.is_in_hilo | MIPS_v1<<11); - rt = MIPS_v1; - } else { - rt = src2_reg->native_reg; - } - if ((mips_opcodes[reg->result.opcode] & 0xFC00003F) < 010){ - /* For SLLV/SRLV/SRAV/RORV, rt is the source and - * rs is the shift amount */ - APPEND(mips_opcodes[reg->result.opcode] | rt<<21 | rs<<16); - } else { - APPEND(mips_opcodes[reg->result.opcode] | rs<<21 | rt<<16); - } - break; - } - - case RTLOP_ADDI: - case RTLOP_ANDI: - case RTLOP_ORI: - case RTLOP_XORI: - case RTLOP_SLLI: - case RTLOP_SRLI: - case RTLOP_SRAI: - case RTLOP_RORI: - case RTLOP_SLTUI: - case RTLOP_SLTSI: { - unsigned int rs, rt; // src1/src2 MIPS registers - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_at, - src1_reg->stack_offset, MIPS_sp)); - rs = MIPS_at; - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_at<<11); - rs = MIPS_at; - } else { - rs = src1_reg->native_reg; - } - rt = MIPS_v1; - APPEND(MIPS_LUI(rt, reg->result.imm>>16 & 0xFFFF)); - APPEND(MIPS_ORI(rt, rt, reg->result.imm & 0xFFFF)); - if ((mips_opcodes[reg->result.opcode] & 0xFC00003F) < 010){ - APPEND(mips_opcodes[reg->result.opcode] | rt<<21 | rs<<16); - } else { - APPEND(mips_opcodes[reg->result.opcode] | rs<<21 | rt<<16); - } - break; - } - - case RTLOP_MULU: - case RTLOP_MULS: - case RTLOP_DIVMODU: - case RTLOP_DIVMODS: { - unsigned int rs, rt; - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, -8)); - APPEND(MIPS_MFHI(MIPS_v1)); - APPEND(MIPS_SW(MIPS_v1, 0, MIPS_sp)); - APPEND(MIPS_MFLO(MIPS_v1)); - APPEND(MIPS_SW(MIPS_v1, 4, MIPS_sp)); - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_at, src1_reg->stack_offset, MIPS_sp)); - rs = MIPS_at; - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_at<<11); - rs = MIPS_at; - } else { - rs = src1_reg->native_reg; - } - if (IS_SPILLED(reg->result.src2)) { - APPEND(MIPS_LW(MIPS_v1, src2_reg->stack_offset, MIPS_sp)); - rt = MIPS_v1; - } else if (src2_reg->mips.is_in_hilo) { - APPEND(src2_reg->mips.is_in_hilo | MIPS_v1<<11); - rt = MIPS_v1; - } else { - rt = src2_reg->native_reg; - } - APPEND(mips_opcodes[reg->result.opcode] | rs<<21 | rt<<16); - if (reg->result.second_res) { - APPEND(MIPS_MFHI(MIPS_at)); - } else { - APPEND(MIPS_MFLO(MIPS_at)); - } - APPEND(MIPS_LW(MIPS_v1, 0, MIPS_sp)); - APPEND(MIPS_MTHI(MIPS_v1)); - APPEND(MIPS_LW(MIPS_v1, 4, MIPS_sp)); - APPEND(MIPS_MTLO(MIPS_v1)); - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, 8)); - break; - } - - case RTLOP_SELECT: { - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, -8)); - APPEND(MIPS_SW(MIPS_v0, 0, MIPS_sp)); - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_at, - src1_reg->stack_offset, MIPS_sp)); - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_at<<11); - } else { - APPEND(MIPS_MOVE(MIPS_at, src1_reg->native_reg)); - } - int reg_src2, reg_cond; - if (IS_SPILLED(reg->result.src2)) { - APPEND(MIPS_LW(MIPS_v0, - src2_reg->stack_offset, MIPS_sp)); - reg_src2 = MIPS_v0; - } else if (src2_reg->mips.is_in_hilo) { - APPEND(src2_reg->mips.is_in_hilo | MIPS_v0<<11); - reg_src2 = MIPS_v0; - } else { - reg_src2 = src2_reg->native_reg; - } - if (IS_SPILLED(reg->result.cond)) { - APPEND(MIPS_LW(MIPS_v1, block->regs[reg->result.cond].stack_offset, MIPS_sp)); - reg_cond = MIPS_v1; - } else if (block->regs[reg->result.cond].mips.is_in_hilo) { - APPEND(block->regs[reg->result.cond].mips.is_in_hilo - | MIPS_at<<11); - } else { - reg_cond = block->regs[reg->result.cond].native_reg; - } - APPEND(MIPS_MOVZ(MIPS_at, reg_src2, reg_cond)); - APPEND(MIPS_LW(MIPS_v0, 0, MIPS_sp)); - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, 8)); - break; - } - - case RTLOP_BFEXT: - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_at, - src1_reg->stack_offset, MIPS_sp)); - APPEND(MIPS_EXT(MIPS_at, MIPS_at, - insn->bitfield.start, - insn->bitfield.count)); - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_at<<11); - } else { - APPEND(MIPS_EXT(MIPS_at, src1_reg->native_reg, - insn->bitfield.start, - insn->bitfield.count)); - } - break; - - case RTLOP_BFINS: { - unsigned int rs; - if (IS_SPILLED(reg->result.src2)) { - APPEND(MIPS_LW(MIPS_at, - src2_reg->stack_offset, MIPS_sp)); - } else if (src2_reg->mips.is_in_hilo) { - APPEND(src2_reg->mips.is_in_hilo | MIPS_at<<11); - } else { - APPEND(MIPS_MOVE(MIPS_at, src2_reg->native_reg)); - } - if (IS_SPILLED(reg->result.src1)) { - APPEND(MIPS_LW(MIPS_v1, src1_reg->stack_offset, MIPS_sp)); - rs = MIPS_v1; - } else if (src1_reg->mips.is_in_hilo) { - APPEND(src1_reg->mips.is_in_hilo | MIPS_v1<<11); - rs = MIPS_v1; - } else { - rs = src1_reg->native_reg; - } - APPEND(MIPS_INS(MIPS_at, rs, insn->bitfield.start, - insn->bitfield.count)); - break; - } - - default: - DMSG("%p/%u: Don't know how to emulate result opcode %u" - " for r%u", block, insn_index, reg->result.opcode, - rtl_reg); -#ifdef PSP_DEBUG - return 0; // This is a bug, so abort -#else - break; -#endif - } - break; - } // case RTLREG_RESULT{,_NOFOLD} - - default: - DMSG("%p/%u: Don't know how to emulate register source %u" - " for r%u", block, insn_index, reg->source, rtl_reg); - /* Let it slide, because there's nothing we can do about it */ - break; - - } // switch (reg->source) - mips_reg = MIPS_at; - } // if live - - if (offset) { - if (offset+0x8000 < 0x10000) { - APPEND(MIPS_ADDIU(MIPS_at, mips_reg, offset)); - } else { - if (offset < 0x10000) { - APPEND(MIPS_ORI(MIPS_v1, MIPS_zero, offset)); - } else { - APPEND(MIPS_LUI(MIPS_v1, offset >> 16)); - APPEND(MIPS_ORI(MIPS_v1, MIPS_v1, offset & 0xFFFF)); - } - APPEND(MIPS_ADDU(MIPS_at, mips_reg, MIPS_v1)); - } - mips_reg = MIPS_at; - } - - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, -8)); - APPEND(MIPS_SW(MIPS_a0, 0, MIPS_sp)); - if (sh2_reg & 0x80) { // Used for SR.T - const uintptr_t cache_ptr = (uintptr_t)&sh2_regcache[16]; - APPEND(MIPS_LUI(MIPS_a0, (cache_ptr + 0x8000) >> 16)); - if (!(block->sh2_regcache_mask & 1<<16)) { - if (block->regs[1].source != RTLREG_PARAMETER - || block->regs[1].param_index != 0 - ) { - DMSG("r1 is not state block, can't handle"); - return 0; - } - if (IS_SPILLED(1)) { - APPEND(MIPS_LW(MIPS_v1, - block->regs[1].stack_offset, MIPS_sp)); - APPEND(MIPS_LW(MIPS_v1, offsetof(SH2State,SR), MIPS_v1)); - } else { - APPEND(MIPS_LW(MIPS_v1, offsetof(SH2State,SR), - block->regs[1].native_reg)); - } - block->sh2_regcache_mask |= 1<<16; - } else { - APPEND(MIPS_LW(MIPS_v1, cache_ptr & 0xFFFF, MIPS_a0)); - } - APPEND(MIPS_INS(MIPS_v1, mips_reg, SR_T_SHIFT, 1)); - APPEND(MIPS_SW(MIPS_v1, cache_ptr & 0xFFFF, MIPS_a0)); - APPEND(MIPS_LW(MIPS_a0, 0, MIPS_sp)); - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, 8)); - } else { - const uintptr_t cache_ptr = (uintptr_t)&sh2_regcache[sh2_reg]; - APPEND(MIPS_LUI(MIPS_a0, (cache_ptr + 0x8000) >> 16)); - APPEND(MIPS_SW(mips_reg, cache_ptr & 0xFFFF, MIPS_a0)); - APPEND(MIPS_LW(MIPS_a0, 0, MIPS_sp)); - APPEND(MIPS_ADDIU(MIPS_sp, MIPS_sp, 8)); - block->sh2_regcache_mask |= 1<>16 & 0xFFFF)); - APPEND(MIPS_ORI(MIPS_at, MIPS_at, offset & 0xFFFF)); - const uintptr_t cache_ptr = (uintptr_t)&sh2_regcache[sh2_reg]; - APPEND(MIPS_LUI(MIPS_v1, (cache_ptr + 0x8000) >> 16)); - APPEND(MIPS_SW(MIPS_at, cache_ptr & 0xFFFF, MIPS_v1)); - block->sh2_regcache_mask |= 1<sh2_regcache_mask &= ~(1<insns != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(block->label_offsets != NULL, return 0); - PRECOND(insn_index < block->num_insns, return 0); - - const RTLInsn *insn = &block->insns[insn_index]; - unsigned int num_insns = 1; - - APPEND(MIPS_JAL(((uintptr_t)code_save_regs & 0x0FFFFFFC) >> 2)); - APPEND(MIPS_NOP()); - - uintptr_t funcptr; - switch (insn->src_imm & 0xFFFF) { - case 1: funcptr = (uintptr_t)trace_storeb_callback; break; - case 2: funcptr = (uintptr_t)trace_storew_callback; break; - case 4: funcptr = (uintptr_t)trace_storel_callback; break; - default: - DMSG("Invalid store trace type %u", insn->src_imm & 0xFF); - return 0; - } - - uint32_t op = insn[num_insns++].src_imm; - PRECOND(op>>28 == 0xD, return 1); - if (op & 0x08000000) { - PRECOND(op>>24 == 0xD8, return 0); - APPEND(MIPS_LUI(MIPS_a0, op & 0xFFFF)); - op = insn[num_insns++].src_imm; - PRECOND(op>>24 == 0xDC, return 0); - APPEND(MIPS_ORI(MIPS_a0, MIPS_a0, op & 0xFFFF)); - } else { - const uint32_t address_reg = op & 0xFFFF; - const RTLRegister *reg = &block->regs[address_reg]; - if (IS_SPILLED(address_reg)) { - APPEND(MIPS_LW(MIPS_a0, 4*18 + reg->stack_offset, MIPS_sp)); - } else if (reg->mips.is_in_hilo) { - APPEND(reg->mips.is_in_hilo | MIPS_a0<<11); - } else if (reg->native_reg != MIPS_a0) { - APPEND(MIPS_MOVE(MIPS_a0, reg->native_reg)); - } - op = insn[num_insns++].src_imm; - PRECOND(op>>24 == 0xD4, return 1); - APPEND(MIPS_LUI(MIPS_at, op & 0xFFFF)); - op = insn[num_insns++].src_imm; - PRECOND(op>>24 == 0xD6, return 1); - APPEND(MIPS_ORI(MIPS_at, MIPS_at, op & 0xFFFF)); - APPEND(MIPS_ADD(MIPS_a0, MIPS_a0, MIPS_at)); - } - - op = insn[num_insns++].src_imm; - PRECOND(op>>28 == 0xE, return 1); - const uint32_t src_reg = op & 0xFFFF; - const RTLRegister *reg = &block->regs[src_reg]; - APPEND(MIPS_JAL((funcptr & 0x0FFFFFFC) >> 2)); - if (IS_SPILLED(src_reg)) { - APPEND(MIPS_LW(MIPS_a1, 4*18 + reg->stack_offset, MIPS_sp)); - } else if (reg->mips.is_in_hilo) { - APPEND(reg->mips.is_in_hilo | MIPS_a1<<11); - } else if (reg->native_reg == MIPS_a0) { - APPEND(MIPS_LW(MIPS_a1, 8, MIPS_sp)); - } else if (reg->native_reg != MIPS_a1) { - APPEND(MIPS_MOVE(MIPS_a1, reg->native_reg)); - } else { // Don't forget to fill the delay slot! - APPEND(MIPS_NOP()); - } - - APPEND(MIPS_JAL(((uintptr_t)code_restore_regs & 0x0FFFFFFC) >> 2)); - APPEND(MIPS_NOP()); - - return num_insns; -} - -/*----------------------------------*/ - -#endif // RTL_TRACE_STEALTH_FOR_SH2 - -/*************************************************************************/ - -/** - * resolve_branches: Resolve branches to RTL labels and jumps to the - * epilogue within MIPS code. If MIPS_OPTIMIZE_BRANCHES is defined, also - * perform optimizations on branches. - * - * [Parameters] - * block: RTL block to translate - * [Return value] - * Nonzero on success, zero on error - */ -static int resolve_branches(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->label_offsets != NULL, return 0); - - uint32_t *native_ptr = (uint32_t *)block->native_buffer; - uint32_t * const native_top = - (uint32_t *)((uintptr_t)native_ptr + block->native_length); - const uint32_t * const epilogue_ptr = - (uint32_t *)((uintptr_t)native_ptr + block->mips.epilogue_offset); - const uint32_t * const chain_ptr = - (uint32_t *)((uintptr_t)native_ptr + block->mips.chain_offset); - - for (; native_ptr < native_top; native_ptr++) { - uint32_t opcode = *native_ptr; - - if (opcode>>27 == __OP_BEQ_LABEL>>1 /*covers both opcodes*/) { - const unsigned int label = opcode & ((1<<16) - 1); - const uint32_t delay_offset = - (uintptr_t)native_ptr - (uintptr_t)block->native_buffer + 4; - if (UNLIKELY((int32_t)block->label_offsets[label] < 0)) { - DMSG("%p: Label %u not defined at native offset %u", - block, label, delay_offset-4); - return 0; - } - int32_t disp = (block->label_offsets[label] - delay_offset); - if (disp < -0x8000<<2 || disp > 0x7FFF<<2) { - /* FIXME: Technically, we could resolve this by flipping - * the sense of the branch and inserting a jump - * instruction, but that would require another pass after - * the final buffer pointer was known to fill in absolute - * addresses; we could also do a BAL and calculate the - * target address manually. But in any case, the chance - * of hitting this is so slim that we don't worry about it - * for now. */ - DMSG("%p: Displacement to label %u (+0x%X) from +0x%X too" - " large, can't resolve", block, label, - block->label_offsets[label], delay_offset); - return 0; - } - *native_ptr = ((__OP_BEQ>>1) << 27) - | (opcode & 0x07FF0000) // Include the EQ/NE bit - | ((disp>>2) & 0xFFFF); - - } else if (opcode == MIPS_B_EPILOGUE_RET_CONST) { - const int32_t offset = epilogue_ptr - (native_ptr+1); - if (LIKELY(offset <= 0x7FFF)) { // Always positive - *native_ptr = MIPS_B(offset); - } else { - DMSG("WARNING: block too large, using nonportable J"); - const uint32_t j_addr = (uintptr_t)epilogue_ptr & 0x0FFFFFFC; - *native_ptr = MIPS_J(j_addr >> 2); - } - - } else if (opcode == MIPS_B_EPILOGUE_CHAIN_AT) { - const int32_t offset = chain_ptr - (native_ptr+1); - if (LIKELY(offset <= 0x7FFF)) { // Always positive - *native_ptr = MIPS_B(offset); - } else { - DMSG("WARNING: block too large, using nonportable J"); - const uint32_t j_addr = (uintptr_t)chain_ptr & 0x0FFFFFFC; - *native_ptr = MIPS_J(j_addr >> 2); - } - - } - -#ifdef MIPS_OPTIMIZE_BRANCHES - opcode = *native_ptr; // It may have been updated above - if (opcode>>28 == __OP_BEQ>>2 - || (opcode>>26 == __OP_REGIMM - && (insn_rt(opcode) & ~021) == __RI_BLTZ) - ) { - uint32_t likely_opcode; - if (opcode>>16 == MIPS_B(0)>>16) { - /* Unconditional branch, so no need for Likely bit */ - likely_opcode = opcode; - } else if (opcode>>28 == __OP_BEQ>>2) { - likely_opcode = opcode | (uint32_t)020<<26; - } else { // REGIMM insns - likely_opcode = opcode | (uint32_t)002<<16; - } - int32_t offset = (int16_t)(opcode & 0xFFFF); - const uint32_t *target = native_ptr + (1+offset); - unsigned int limit = 16; // Watch out for infinite loops - while ((*target>>16 == MIPS_B(0)>>16 - || *target>>16 == MIPS_B_LABEL(0)>>16 - || *target == MIPS_B_EPILOGUE_RET_CONST) - && (native_ptr[1] == MIPS_NOP() || target[1] == MIPS_NOP()) - && limit > 0 - ) { - limit--; - if (target[1] != MIPS_NOP()) { - native_ptr[1] = target[1]; // Must have been a NOP - opcode = likely_opcode; - } - int32_t new_offset; - if (*target == MIPS_B_EPILOGUE_RET_CONST) { - const uint32_t delay_pos = - (native_ptr+1) - (uint32_t *)block->native_buffer; - new_offset = block->mips.epilogue_offset/4 - delay_pos; - } else if (*target>>16 == MIPS_B_LABEL(0)>>16) { - const unsigned int label = *target & 0xFFFF; - if (UNLIKELY((int32_t)block->label_offsets[label] < 0)) { - /* Just skip out here; the Bxx_LABEL processing - * code will report the error */ - break; - } - const uint32_t delay_pos = - (native_ptr+1) - (uint32_t *)block->native_buffer; - new_offset = block->label_offsets[label]/4 - delay_pos; - } else { - new_offset = offset + (1 + (int16_t)(*target & 0xFFFF)); - } - if (new_offset < -0x8000 || new_offset > 0x7FFF) { - break; - } - offset = new_offset; - *native_ptr = (opcode & 0xFFFF0000) | (offset & 0xFFFF); - target = native_ptr + (1+offset); - } - if (*native_ptr>>16 == MIPS_B(0)>>16 - && (*target>>26 == MIPS_J(0) - || (*target & 0xFC00003F) == MIPS_JR(0)) - && (native_ptr[1] == MIPS_NOP() || target[1] == MIPS_NOP()) - ) { - /* Chain an unconditional branch through to a jump (but not - * JAL/JALR, since we'd get the wrong return address) */ - if (target[1] != MIPS_NOP()) { - native_ptr[1] = target[1]; - } - *native_ptr = *target; - } else if (offset != 0x7FFF - && native_ptr[1] == MIPS_NOP() - && !insn_is_jump(*target) - && !insn_is_branch(*target) - ) { - *native_ptr = - (likely_opcode & 0xFFFF0000) | ((offset+1) & 0xFFFF); - native_ptr[1] = *target; - } - } -#endif - - } // for (; native_ptr < native_top; native_ptr++) - - return 1; -} - -/*************************************************************************/ - -#undef MAP_REGISTER -#undef APPEND - -/*************************************************************************/ -/*********************** Low-level helper routines ***********************/ -/*************************************************************************/ - -/** - * append_insn: Append a MIPS instruction word to the given block. - * - * [Parameters] - * block: RTL block to append to - * insn: MIPS instruction word to append - * [Return value] - * Nonzero on success, zero on error - */ -static inline int append_insn(RTLBlock * const block, const uint32_t insn) -{ - PRECOND(block != NULL, return 0); - - if (UNLIKELY(block->native_length >= block->native_bufsize)) { - if (UNLIKELY(!expand_block(block))) { - return 0; - } - } - - *(uint32_t *)((uint8_t *)block->native_buffer + block->native_length) - = insn; - block->native_length += 4; - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * expand_block: Expand the current native code buffer. - * - * [Parameters] - * block: RTL block to expand - * [Return value] - * Nonzero on success, zero on error - */ -static int expand_block(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - - block->native_bufsize = block->native_length + NATIVE_EXPAND_SIZE; - void *new_buffer = realloc(block->native_buffer, block->native_bufsize); - if (UNLIKELY(!new_buffer)) { - DMSG("No memory to expand native buffer to %u bytes", - block->native_bufsize); - return 0; - } - block->native_buffer = new_buffer; - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * last_insn: Return the last 32-bit instruction word added to the given - * block. If the block is empty, returns MIPS_NOP(). - * - * [Parameters] - * block: RTL block - * [Return value] - * Last instruction word added - */ -static uint32_t last_insn(const RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->native_buffer != NULL, return 0); - - if (UNLIKELY(block->native_length == 0)) { - return MIPS_NOP(); - } - return *(uint32_t *)((uint8_t *)block->native_buffer - + (block->native_length - 4)); -} - -/*-----------------------------------------------------------------------*/ - -/** - * pop_insn: Return the last 32-bit instruction word added to the given - * block, and remove that word from the end of the block. If the block is - * empty, returns MIPS_NOP() without modifying the block. - * - * [Parameters] - * block: RTL block - * [Return value] - * Last instruction word added - */ -static uint32_t pop_insn(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->native_buffer != NULL, return 0); - - if (UNLIKELY(block->native_length == 0)) { - return MIPS_NOP(); - } - block->native_length -= 4; - return *(uint32_t *)((uint8_t *)block->native_buffer - + block->native_length); -} - -/*************************************************************************/ - -/** - * append_float: Append a high-latency instruction (a load, multiply, or - * divide instruction) to the given block. If possible (and if - * MIPS_OPTIMIZE_SCHEDULING is enabled), float the instruction upwards to - * obtain a distance of at least "latency" instructions before the next - * instruction. Preceding instructions in the same dependency chain are - * also floated upwards to preserve correctness. - * - * [Parameters] - * block: RTL block to append to - * insn: Instruction word to append - * latency: Desired distance to next instruction - * [Return value] - * Nonzero on success, zero on error - */ -static int append_float(RTLBlock * const block, const uint32_t insn, - const int latency) -{ -#ifndef MIPS_OPTIMIZE_SCHEDULING - return append_insn(block, insn); -#else - - PRECOND(block != NULL, return 0); - PRECOND(insn_is_load(insn) - || (insn & 0xFC00003C) == __SP_MULT - || (insn & 0xFC00003E) == __SP_MADD - || (insn & 0xFC00003E) == __SP_MSUB, return 0); - - /* Does the dependency chain ending with the new instruction have a - * load or store instruction? If so, do we know where it points? */ - - int has_mem; - unsigned int unique_pointer; - uint32_t unique_pointer_birth; - if (insn_is_load(insn)) { // We're never called for stores - has_mem = 1; - PRECOND(block->mips.reg_map[insn_rs(insn)] != NULL, return 0); - unique_pointer = block->mips.reg_map[insn_rs(insn)]->unique_pointer; - unique_pointer_birth = block->mips.reg_map[insn_rs(insn)]->birth; - } else { - has_mem = 0; - unique_pointer = 0; - } - - /* First add the instruction to the block. */ - - if (UNLIKELY(!append_insn(block, insn))) { - return 0; - } - - /* Extract registers used and set by this instruction; we'll add to - * these sets all registers used by preceding instructions in the - * dependency chain. */ - - uint32_t regs_used = insn_regs_used(insn); - uint32_t regs_set = insn_regs_set(insn); - - /* Scan backwards, up to the beginning of the unit or preceding branch - * delay slot, to find instructions that can be placed below this one, - * and move them below the current instruction. */ - - uint32_t * const unit_start = (uint32_t *) - ((uint8_t *)block->native_buffer + block->mips.unit_start); - uint32_t *insn_ptr = (uint32_t *) - ((uint8_t *)block->native_buffer + (block->native_length - 4)); - uint32_t * const target = insn_ptr - (latency-1); - uint32_t *search; - - for (search = insn_ptr - 1; search >= unit_start; search--) { - - /* If the preceding instruction is a jump or branch, stop here. - * If this is the first instruction in the unit, the preceding - * instruction can't be a jump or branch (if it was, a delay slot - * instruction would have been added after it at the end of the - * unit). */ - - if (search > unit_start - && (insn_is_jump(search[-1]) || insn_is_branch(search[-1])) - ) { - break; - } - - /* An instruction is independent of a following sequence of - * instructions if that instruction: - * 1) Does not set a register used in the following sequence - * (i.e., the sequence does not depend on the result of the - * instruction). - * 2) Does not set a register set in the following sequence - * (i.e., the sequence does not reuse the instruction's - * result register). - * 3) Does not use a register set in the following sequence - * (i.e., the sequence does not clobber an operand of the - * instruction). - * We explicitly do not move load or store instructions across - * other load or store instructions, so as to maintain ordering of - * memory accesses (otherwise, we might try to load from an address - * before the store that updates it) and to avoid introducing a - * stall by shifting a previous load farther down the code stream. - * However, we _do_ float a load above a preceding store if we know - * that the store and load point to different addresses; i.e., if - * at least one of the registers is a unique pointer, and they do - * not reference the same unique address. */ - - const uint32_t this_used = insn_regs_used(*search); - const uint32_t this_set = insn_regs_set(*search); - int this_is_mem; - if (insn_is_load(*search)) { - this_is_mem = 1; - } else if (insn_is_store(*search)) { - // FIXME: We don't currently save unique pointer data with the - // generated MIPS instructions, so for now we assume that the - // current register is the only one pointing to this unique - // region. This works at the moment because the state block - // pointer is the only register we mark as a unique pointer, - // but could break in other cases. - if (unique_pointer == 0 || insn_rs(insn) != insn_rs(*search)) { - this_is_mem = 1; - } else { - PRECOND(block->mips.reg_map[insn_rs(*search)] != NULL, - return 0); - this_is_mem = (insn_imm(insn) == insn_imm(*search)); - } - } else { - this_is_mem = 0; - } - if ((this_set & (regs_used | regs_set)) != 0 - || (this_used & regs_set) != 0 - || (has_mem && this_is_mem) - ) { - /* Add this register's used and set registers to the dependency - * chain's cumulative set. */ - regs_used |= this_used; - regs_set |= this_set; - /* If it was a load or store instruction, record that fact. */ - if (insn_is_load(*search) || insn_is_store(*search)) { - has_mem = 1; - /* Register assignments may have changed, so we don't know - * for certain what the register pointed to at the time, so - * play it safe. */ - unique_pointer = 0; - } - } else { - /* Move this instruction immediately below the one we added. */ - const uint32_t move_insn = *search; - uint32_t *move_ptr; - for (move_ptr = search; move_ptr < insn_ptr; move_ptr++) { - *move_ptr = *(move_ptr + 1); - } - *move_ptr = move_insn; - /* The instruction we added has now moved one word up. */ - insn_ptr--; - /* If we've achieved the requested distance, stop. */ - if (insn_ptr <= target) { - break; - } - } - - } // for (search = insn_ptr - 1; search >= unit_start; search--) - - return 1; - -#endif // MIPS_OPTIMIZE_SCHEDULING -} - -/*-----------------------------------------------------------------------*/ - -/** - * append_branch: Append a branch instruction to the given block. If - * possible (and if MIPS_OPTIMIZE_DELAY_SLOT is enabled), place the current - * last instruction of the block into the branch's delay slot. - * - * [Parameters] - * block: RTL block to append to - * insn: Branch instruction word to append - * [Return value] - * Nonzero on success, zero on error - */ -static int append_branch(RTLBlock * const block, const uint32_t insn) -{ - PRECOND(block != NULL, return 0); - - uint32_t delay_slot = MIPS_NOP(); - -#ifdef MIPS_OPTIMIZE_DELAY_SLOT - if (block->native_length - 4 >= block->mips.unit_start) { - int can_swap_insns = 0; - const uint32_t prev1_insn = pop_insn(block); - uint32_t prev2_insn; - if (block->native_length - 4 >= block->mips.unit_start) { - prev2_insn = last_insn(block); - } else { - prev2_insn = MIPS_NOP(); - } - if (!insn_is_jump(prev2_insn) && !insn_is_branch(prev2_insn)) { - if (insn == MIPS_B_EPILOGUE_RET_CONST - || insn == MIPS_B_EPILOGUE_CHAIN_AT - || !(insn_regs_set(prev1_insn) & insn_regs_used(insn)) - ) { - can_swap_insns = 1; - } - } - if (can_swap_insns) { - delay_slot = prev1_insn; - } else { - if (UNLIKELY(!append_insn(block, prev1_insn))) { - // Just to be safe... - DMSG("Failed to re-append insn"); - return 0; - } - } - } -#endif - - return append_insn(block, insn) && append_insn(block, delay_slot); -} - -/*************************************************************************/ - -/** - * append_prologue: Append a function prologue to the given block. - * - * [Parameters] - * block: RTL block to append to - * [Return value] - * Nonzero on success, zero on error - */ -static int append_prologue(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - - /* Set up the stack frame (if we need one) */ - if (block->mips.total_frame_size) { - if (UNLIKELY(!append_insn(block, MIPS_ADDIU(MIPS_sp, MIPS_sp, -(block->mips.total_frame_size))))) { - DMSG("Failed to append prologue (stack frame)"); - return 0; - } - } - - /* Save $ra if necessary */ - if (block->mips.need_save_ra - && UNLIKELY(!append_insn(block, MIPS_SW(MIPS_ra, block->mips.total_frame_size - 4, MIPS_sp))) - ) { - DMSG("Failed to append prologue ($ra)"); - return 0; - } - - /* Save all callee-saved registers that we use */ - uint32_t offset = block->mips.total_frame_size - 8; - unsigned int i; - for (i = 0; i < lenof(callee_saved_regs); i++) { - const unsigned int mips_reg = callee_saved_regs[i]; - if (block->mips.sreg_used & (1 << mips_reg)) { - if (UNLIKELY(!append_insn(block, - MIPS_SW(mips_reg, offset, MIPS_sp)))) { - DMSG("Failed to append prologue ($%u)", mips_reg); - return 0; - } - offset -= 4; - } - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * append_epilogue: Append a function epilogue to the given block. - * - * [Parameters] - * block: RTL block to append to - * [Return value] - * Nonzero on success, zero on error - */ -static int append_epilogue(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - - /* Save the offset to the epilogue code for branch resolution */ - block->mips.epilogue_offset = block->native_length; - - /* Restore the original values of saved registers ($ra and $sN) */ - if (block->mips.need_save_ra - && UNLIKELY(!append_insn(block, MIPS_LW(MIPS_ra, block->mips.total_frame_size - 4, MIPS_sp))) - ) { - DMSG("Failed to append epilogue ($ra)"); - return 0; - } - uint32_t offset = block->mips.total_frame_size - 8; - unsigned int i; - for (i = 0; i < lenof(callee_saved_regs); i++) { - const unsigned int mips_reg = callee_saved_regs[i]; - if (block->mips.sreg_used & (1 << mips_reg)) { - if (UNLIKELY(!append_insn(block, - MIPS_LW(mips_reg, offset, MIPS_sp)))) { - DMSG("Failed to append epilogue ($%u)", mips_reg); - return 0; - } - offset -= 4; - } - } - - /* Free the stack frame (if we allocated one) and return */ - uint32_t final_insn; - if (block->mips.total_frame_size) { - final_insn = - MIPS_ADDIU(MIPS_sp, MIPS_sp, block->mips.total_frame_size); - } else { - final_insn = MIPS_NOP(); - } - if (UNLIKELY(!append_insn(block, MIPS_JR(MIPS_ra))) - || UNLIKELY(!append_insn(block, final_insn)) - ) { - DMSG("Failed to append epilogue (return)"); - return 0; - } - - /* If we need a chain-to-$at epilogue as well, generate that */ - if (block->mips.need_chain_at) { - block->mips.chain_offset = block->native_length; - if (block->mips.need_save_ra - && UNLIKELY(!append_insn(block, MIPS_LW(MIPS_ra, block->mips.total_frame_size - 4, MIPS_sp))) - ) { - DMSG("Failed to append chain epilogue ($ra)"); - return 0; - } - offset = block->mips.total_frame_size - 8; - for (i = 0; i < lenof(callee_saved_regs); i++) { - const unsigned int mips_reg = callee_saved_regs[i]; - if (block->mips.sreg_used & (1 << mips_reg)) { - if (UNLIKELY(!append_insn(block, - MIPS_LW(mips_reg, offset, MIPS_sp)))) { - DMSG("Failed to append chain epilogue ($%u)", mips_reg); - return 0; - } - offset -= 4; - } - } - if (block->mips.total_frame_size) { - final_insn = - MIPS_ADDIU(MIPS_sp, MIPS_sp, block->mips.total_frame_size); - } else { - final_insn = MIPS_NOP(); - } - if (UNLIKELY(!append_insn(block, MIPS_JR(MIPS_at))) - || UNLIKELY(!append_insn(block, final_insn)) - ) { - DMSG("Failed to append chain epilogue (return)"); - return 0; - } - } // if (block->mips.need_chain_at) - - return 1; -} - -/*************************************************************************/ -/****************** MIPS opcode informational functions ******************/ -/*************************************************************************/ - -/** - * insn_rs, insn_rt, insn_rd: Return the register number specified in the - * rs, rt, or rd field of the given instruction, respectively. - * - * [Parameters] - * opcode: Instruction opcode - * [Return value] - * rs, rt, or rd register number (0-31) - */ -static inline int insn_rs(const uint32_t opcode) -{ - return (opcode >> 21) & 0x1F; -} - -static inline int insn_rt(const uint32_t opcode) -{ - return (opcode >> 16) & 0x1F; -} - -static inline int insn_rd(const uint32_t opcode) -{ - return (opcode >> 11) & 0x1F; -} - -/*----------------------------------*/ - -/** - * insn_imm: Return the 16-bit immediate value specified in the given - * instruction. - * - * [Parameters] - * opcode: Instruction opcode - * [Return value] - * 16-bit immediate value as a signed integer - */ -static inline int insn_imm(const uint32_t opcode) -{ - return (int)(int16_t)opcode; -} - -/*************************************************************************/ - -/** - * insn_is_*: Return whether the given instruction is of the type - * specified by the function name: - * insn_is_load -- a load instruction - * insn_is_store -- a store instruction - * insn_is_jump -- a JUMP class instruction (J or JAL) - * insn_is_branch -- an IMM/REGIMM class branch instruction (BEQ, etc.) - * insn_is_imm -- an IMM class instruction - * insn_is_imm_alu -- an IMM class ALU instruction (ADDI, etc.) - * insn_is_special -- a SPECIAL class instruction - * insn_is_regimm -- a REGIMM class instruction (BLTZ, etc.) - * insn_is_allegrex -- an Allegrex-specific instruction (INS, SEB, etc.) - * - * [Parameters] - * opcode: Instruction opcode - * [Return value] - * Nonzero if the instruction is of the named type, else zero - */ -static inline int insn_is_load(const uint32_t opcode) -{ - return opcode>>29 == 4; // We don't use LL, so we don't check for it -} - -static inline int insn_is_store(const uint32_t opcode) -{ - return opcode>>29 == 5; // We don't use SC, so we don't check for it -} - -static inline int insn_is_jump(const uint32_t opcode) -{ - return opcode>>27 == __OP_J>>1 - || (insn_is_special(opcode) && (opcode & 0x3E) == __SP_JR); // JR/JALR -} - -static inline int insn_is_branch(const uint32_t opcode) -{ - return opcode>>28 == __OP_BEQ>>2 - || opcode>>28 == __OP_BEQL>>2 - || opcode>>27 == __OP_BEQ_LABEL>>1 - || insn_is_regimm(opcode); -} - -static inline int insn_is_imm(const uint32_t opcode) -{ - return (opcode>>26 >= __OP_BEQ && opcode>>26 <= __OP_BGTZL) - || (opcode>>27 == __OP_BEQ_LABEL>>1); -} - -static inline int insn_is_imm_alu(const uint32_t opcode) -{ - return opcode>>29 == 1; -} - -static inline int insn_is_special(const uint32_t opcode) -{ - return opcode>>26 == __OP_SPECIAL; -} - -static inline int insn_is_regimm(const uint32_t opcode) -{ - return opcode>>26 == __OP_REGIMM; -} - -static inline int insn_is_allegrex(const uint32_t opcode) -{ - return opcode>>26 == __OP_ALLEGREX; -} - -/*************************************************************************/ - -/** - * insn_regs_used: Return a bitmask of MIPS registers used by the given - * instruction (i.e. the instruction's source registers). $zero is never - * included in the set; bit 0 instead reflects the HI and LO registers. - * - * [Parameters] - * opcode: Instruction opcode - * [Return value] - * Bitmask of registers used by the instruction - */ -static inline uint32_t insn_regs_used(const uint32_t opcode) -{ - uint32_t regs; - int hilo = 0; - - if (insn_is_load(opcode) || insn_is_regimm(opcode) - || insn_is_imm_alu(opcode) - ) { - regs = 1<>26 == __OP_JAL - || (insn_is_regimm(opcode) - && insn_rt(opcode)>>2 == __RI_BLTZAL>>2) - ) { - regs = 1<insns = NULL; - block->insn_unitmap = NULL; - block->insns_size = INSNS_EXPAND_SIZE; - block->num_insns = 0; - - block->units = NULL; - block->units_size = UNITS_EXPAND_SIZE; - block->num_units = 0; - block->have_unit = 0; - block->cur_unit = 0; - - block->label_unitmap = NULL; - block->labels_size = LABELS_EXPAND_SIZE; - block->next_label = 1; - - block->regs = NULL; - block->regs_size = REGS_EXPAND_SIZE; - block->next_reg = 1; - block->first_live_reg = 0; - block->last_live_reg = 0; - block->unique_pointer_index = 1; - - block->finalized = 0; - - block->first_call_unit = -1; - block->last_call_unit = -1; - - block->insns = malloc(sizeof(*block->insns) * block->insns_size); - if (!block->insns) { - DMSG("No memory for %d RTLInsns", block->insns_size); - goto fail; - } - - block->units = malloc(sizeof(*block->units) * block->units_size); - if (!block->units) { - DMSG("No memory for %d RTLUnits", block->units_size); - goto fail; - } - - block->regs = malloc(sizeof(*block->regs) * block->regs_size); - if (!block->regs) { - DMSG("No memory for %d RTLRegisters", block->regs_size); - goto fail; - } - memset(&block->regs[0], 0, sizeof(*block->regs)); - - block->label_unitmap = - malloc(sizeof(*block->label_unitmap) * block->labels_size); - if (!block->label_unitmap) { - DMSG("No memory for %d labels", block->labels_size); - goto fail; - } - block->label_unitmap[0] = -1; - -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] Created new block at %p\n", block); -#endif - return block; - - fail: - free(block->insns); - free(block->units); - free(block->regs); - free(block->label_unitmap); - free(block); - return NULL; -} - -/*************************************************************************/ - -/* rtl_add_insn() helpers -- these move function calls like realloc() out - * of rtl_add_insn() to help the compiler optimize the fast path, by - * avoiding register spillage when it's not necessary. Note that GCC (at - * least version 4.3) will inline these by default, but that actually slows - * down the fast path on at least MIPS due to spillage of the function - * parameter registers, so we force these to be generated as separate - * functions. */ -#ifdef __GNUC__ -__attribute__((noinline)) -#endif -static int rtl_add_insn_with_extend(RTLBlock *block, RTLOpcode opcode, - uint32_t dest, uintptr_t src1, - uint32_t src2, uint32_t other); -#ifdef __GNUC__ -__attribute__((noinline)) -#endif -static int rtl_add_insn_with_new_unit(RTLBlock *block, RTLOpcode opcode, - uint32_t dest, uintptr_t src1, - uint32_t src2, uint32_t other); - -/*----------------------------------*/ - -/** - * rtl_add_insn: Append an instruction to the given block. The meaning of - * each operand depends on the instruction. - * - * [Parameters] - * block: RTLBlock to append to - * opcode: Instruction opcode (RTLOP_*) - * dest: Destination register for instruction - * src1: First source register or immediate value for instruction - * src2: Second source register or immediate value for instruction - * other: Extra register for instruction - * [Return value] - * Nonzero on success, zero on error - */ -int rtl_add_insn(RTLBlock *block, RTLOpcode opcode, uint32_t dest, - uintptr_t src1, uint32_t src2, uint32_t other) -{ - PRECOND(block != NULL, return 0); - PRECOND(!block->finalized, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(opcode >= RTLOP__FIRST && opcode <= RTLOP__LAST, return 0); - - /* Extend the instruction array if necessary */ - if (UNLIKELY(block->num_insns >= block->insns_size)) { - return rtl_add_insn_with_extend(block, opcode, - dest, src1, src2, other); - } - - /* Create a new basic unit if there's no active one */ - if (UNLIKELY(!block->have_unit)) { - return rtl_add_insn_with_new_unit(block, opcode, - dest, src1, src2, other); - } - - /* Fill in the instruction data */ - RTLInsn * const insn = &block->insns[block->num_insns]; - insn->opcode = opcode; - if (UNLIKELY(!rtlinsn_make(block, insn, dest, src1, src2, other))) { - return 0; - } - -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] %p/%5u: %s\n", block, block->num_insns, - rtl_decode_insn(block, block->num_insns, 0)); -#endif - block->num_insns++; - return 1; -} - -/*----------------------------------*/ - -/** - * rtl_add_insn_with_extend: Extend the instruction array and then add a - * new instruction. Called by rtl_add_insn() when the instruction array is - * full upon entry. - */ -static int rtl_add_insn_with_extend(RTLBlock *block, RTLOpcode opcode, - uint32_t dest, uintptr_t src1, - uint32_t src2, uint32_t other) -{ - uint32_t new_insns_size = block->num_insns + INSNS_EXPAND_SIZE; - RTLInsn *new_insns = realloc(block->insns, - sizeof(*block->insns) * new_insns_size); - if (UNLIKELY(!new_insns)) { - DMSG("No memory to expand block %p to %d insns", block, - new_insns_size); - return 0; - } - block->insns = new_insns; - block->insns_size = new_insns_size; - - /* Run back through rtl_add_insn() to handle the rest */ - return rtl_add_insn(block, opcode, dest, src1, src2, other); -} - -/*----------------------------------*/ - -/** - * rtl_add_insn_with_new_unit: Start a new basic unit and then add a new - * instruction. Called by rtl_add_insn() when there is no current basic - * unit upon entry. - */ -static int rtl_add_insn_with_new_unit(RTLBlock *block, RTLOpcode opcode, - uint32_t dest, uintptr_t src1, - uint32_t src2, uint32_t other) -{ - if (UNLIKELY(!rtlunit_add(block))) { - return 0; - } - block->have_unit = 1; - block->cur_unit = block->num_units - 1; - block->units[block->cur_unit].first_insn = block->num_insns; - - /* Run back through rtl_add_insn() to handle the rest */ - return rtl_add_insn(block, opcode, dest, src1, src2, other); -} - -/*-----------------------------------------------------------------------*/ - -/** - * rtl_alloc_register: Allocate a new register for use in the given block. - * The register's value is undefined until it has been used as the - * destination of an instruction. - * - * [Parameters] - * block: RTLBlock to allocate a register for - * [Return value] - * Register number (nonzero) on success, zero on error - */ -unsigned int rtl_alloc_register(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - PRECOND(!block->finalized, return 0); - PRECOND(block->regs != NULL, return 0); - - if (UNLIKELY(block->next_reg >= block->regs_size)) { - if (block->regs_size >= REGS_LIMIT) { - DMSG("Too many registers in block %p (limit %u)", - block, REGS_LIMIT); - return 0; - } - unsigned int new_regs_size; - /* Avoid 16-bit overflow (not that there are any modern machines - * where int is 16 bits, but let's follow the rules anyway) */ - if (block->regs_size > REGS_LIMIT - REGS_EXPAND_SIZE) { - new_regs_size = REGS_LIMIT; - } else { - new_regs_size = block->next_reg + REGS_EXPAND_SIZE; - } - RTLRegister * const new_regs = - realloc(block->regs, sizeof(*block->regs) * new_regs_size); - if (UNLIKELY(!new_regs)) { - DMSG("No memory to expand block %p to %d registers", - block, new_regs_size); - return 0; - } - block->regs = new_regs; - block->regs_size = new_regs_size; - } - - const unsigned int reg_index = block->next_reg++; - memset(&block->regs[reg_index], 0, sizeof(block->regs[reg_index])); - return reg_index; -} - -/*-----------------------------------------------------------------------*/ - -/** - * rtl_register_set_unique_pointer: Mark the given register as being a - * "unique pointer", which points to a region of memory which will never - * be accessed except through this register (or another register copied - * from it). This function must be called after adding the instruction - * which sets the register, and if the register's value is subsequently - * modified, its "unique pointer" status will be cancelled. - * - * [Parameters] - * block: RTLBlock containing register to mark - * regnum: Register number to mark - * [Return value] - * Nonzero on success, zero on error - */ -int rtl_register_set_unique_pointer(RTLBlock *block, uint32_t regnum) -{ - PRECOND(block != NULL, return 0); - PRECOND(!block->finalized, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(regnum != 0 && regnum < block->next_reg, return 0); - - if (block->unique_pointer_index == 0) { // i.e. it wrapped around - DMSG("Unique pointer index overflow at register r%u", regnum); - return 0; - } - block->regs[regnum].unique_pointer = block->unique_pointer_index++; - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * rtl_alloc_label: Allocate a new label for use in the given block. - * - * [Parameters] - * block: RTLBlock to allocate a label for - * [Return value] - * Label number (nonzero) on success, zero on error - */ -unsigned int rtl_alloc_label(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - PRECOND(!block->finalized, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - - if (UNLIKELY(block->next_label >= block->labels_size)) { - if (block->labels_size >= LABELS_LIMIT) { - DMSG("Too many labels in block %p (limit %u)", - block, LABELS_LIMIT); - return 0; - } - unsigned int new_labels_size; - if (block->labels_size > LABELS_LIMIT - LABELS_EXPAND_SIZE) { - new_labels_size = LABELS_LIMIT; - } else { - new_labels_size = block->next_label + LABELS_EXPAND_SIZE; - } - int16_t * const new_label_unitmap = - realloc(block->label_unitmap, - sizeof(*block->label_unitmap) * new_labels_size); - if (UNLIKELY(!new_label_unitmap)) { - DMSG("No memory to expand block %p to %d labels", block, - new_labels_size); - return 0; - } - block->label_unitmap = new_label_unitmap; - block->labels_size = new_labels_size; - } - - const unsigned int label = block->next_label++; - block->label_unitmap[label] = -1; - return label; -} - -/*************************************************************************/ - -/** - * rtl_finalize_block: Perform housekeeping at the end of the given - * block's translation. rtl_add_insn(), rtl_alloc_register(), and - * rtl_alloc_label() may not be called for a block after calling this - * function on the block. - * - * [Parameters] - * block: RTLBlock to finalize - * [Return value] - * Nonzero on success, zero on error - */ -int rtl_finalize_block(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - PRECOND(!block->finalized, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - - /* Terminate the last unit (if there is one) */ - if (block->have_unit) { - block->units[block->cur_unit].last_insn = block->num_insns - 1; - block->have_unit = 0; - } - - /* Add execution graph edges for GOTO instructions */ - if (UNLIKELY(!add_unit_edges(block))) { - return 0; - } - - /* Update live ranges for registers used in loops */ - if (UNLIKELY(!update_live_ranges(block))) { - return 0; - } - - block->finalized = 1; -#ifdef RTL_TRACE_GENERATE - rtlunit_dump_all(block, NULL); - fprintf(stderr, "[RTL] Finalized block at %p\n", block); -#endif - return 1; -} - -/*************************************************************************/ - -/** - * rtl_optimize_block: Perform target-independent optimization on the - * given block. Before calling this function, rtl_finalize_block() must be - * called for the block. - * - * [Parameters] - * block: RTLBlock to optimize - * flags: RTLOPT_* flags indicating which optimizations to perform - * [Return value] - * Nonzero on success, zero on error - */ -int rtl_optimize_block(RTLBlock *block, uint32_t flags) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->finalized, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - - if (flags & RTLOPT_FOLD_CONSTANTS) { - if (UNLIKELY(!rtlopt_fold_constants(block))) { - DMSG("Constant folding failed"); - return 0; - } - } - - if (flags & RTLOPT_DECONDITION) { - if (UNLIKELY(!rtlopt_decondition(block))) { - DMSG("Deconditioning failed"); - return 0; - } - } - - if (flags & RTLOPT_DECONDITION) { - if (UNLIKELY(!rtlopt_drop_dead_units(block))) { - DMSG("Dead unit dropping failed"); - return 0; - } - } - -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] Optimized block at %p\n", block); - dump_block(block, "optimize"); -#endif - return 1; -} - -/*************************************************************************/ - -/** - * rtl_translate_block: Translate the given block into native machine code. - * - * [Parameters] - * block: RTLBlock to translate - * code_ret: Pointer to variable to receive code buffer pointer - * size_ret: Pointer to variable to receive code buffer size (in bytes) - * [Return value] - * Nonzero on success, zero on error - * [Notes] - * On error, *code_ret and *size_ret are not modified. - */ -int rtl_translate_block(RTLBlock *block, void **code_ret, uint32_t *size_ret) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->finalized, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(code_ret != NULL, return 0); - PRECOND(size_ret != NULL, return 0); - - int retval; - -#if defined(PSP) - retval = rtl_translate_block_mips(block, code_ret, size_ret); -#else - DMSG("Native code generation is not implemented for this platform"); - retval = 0; -#endif - -#ifdef RTL_TRACE_GENERATE - if (retval) { - fprintf(stderr, "[RTL] Translated block at %p to native code at %p" - " (size %u)\n", block, *code_ret, *size_ret); - } else { - fprintf(stderr, "[RTL] FAILED to translate block at %p\n", block); - } -#endif - return retval; -} - -/*************************************************************************/ - -/** - * rtl_destroy_block: Destroy the given block, freeing any resources it - * used. - * - * [Parameters] - * block: RTLBlock to destroy (if NULL, this function does nothing) - * [Return value] - * None - */ -void rtl_destroy_block(RTLBlock *block) -{ - if (block) { -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] Destroying block at %p\n", block); -#endif - free(block->insns); - free(block->insn_unitmap); - free(block->units); - free(block->regs); - free(block->label_unitmap); - free(block); - } -} - -/*************************************************************************/ -/*********************** Library-internal routines ***********************/ -/*************************************************************************/ - -#if defined(RTL_TRACE_GENERATE) || defined(RTL_TRACE_EXECUTE) - -/** - * rtl_decode_insn: Decode an RTL instruction into a human-readable - * string. - * - * [Parameters] - * block: RTLBlock containing instruction to decode - * index: Index of instruction to decode - * is_exec: Nonzero if being called from interpreted execution, else zero - * [Return value] - * Human-readable string describing the instruction - * [Notes] - * The returned string is stored in a static buffer which is - * overwritten on each call. - */ -const char *rtl_decode_insn(const RTLBlock *block, uint32_t index, int is_exec) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - /* We don't check the index because it'll be out of range when tracing - * code generation */ - - static const char * const opcode_names[] = { - [RTLOP_NOP ] = "NOP", - [RTLOP_MOVE ] = "MOVE", - [RTLOP_SELECT ] = "SELECT", - [RTLOP_ADD ] = "ADD", - [RTLOP_SUB ] = "SUB", - [RTLOP_MULU ] = "MULU", - [RTLOP_MULS ] = "MULS", - [RTLOP_MADDU ] = "MADDU", - [RTLOP_MADDS ] = "MADDS", - [RTLOP_DIVMODU ] = "DIVMODU", - [RTLOP_DIVMODS ] = "DIVMODS", - [RTLOP_AND ] = "AND", - [RTLOP_OR ] = "OR", - [RTLOP_XOR ] = "XOR", - [RTLOP_NOT ] = "NOT", - [RTLOP_SLL ] = "SLL", - [RTLOP_SRL ] = "SRL", - [RTLOP_SRA ] = "SRA", - [RTLOP_ROR ] = "ROR", - [RTLOP_CLZ ] = "CLZ", - [RTLOP_CLO ] = "CLO", - [RTLOP_SLTU ] = "SLTU", - [RTLOP_SLTS ] = "SLTS", - [RTLOP_BSWAPH ] = "BSWAPH", - [RTLOP_BSWAPW ] = "BSWAPW", - [RTLOP_HSWAPW ] = "HSWAPW", - [RTLOP_ADDI ] = "ADDI", - [RTLOP_ANDI ] = "ANDI", - [RTLOP_ORI ] = "ORI", - [RTLOP_XORI ] = "XORI", - [RTLOP_SLLI ] = "SLLI", - [RTLOP_SRLI ] = "SRLI", - [RTLOP_SRAI ] = "SRAI", - [RTLOP_RORI ] = "RORI", - [RTLOP_SLTUI ] = "SLTUI", - [RTLOP_SLTSI ] = "SLTSI", - [RTLOP_BFEXT ] = "BFEXT", - [RTLOP_BFINS ] = "BFINS", - [RTLOP_LOAD_IMM ] = "LOAD_IMM", - [RTLOP_LOAD_ADDR ] = "LOAD_ADDR", - [RTLOP_LOAD_PARAM ] = "LOAD_PARAM", - [RTLOP_LOAD_BS ] = "LOAD_BS", - [RTLOP_LOAD_BU ] = "LOAD_BU", - [RTLOP_LOAD_HS ] = "LOAD_HS", - [RTLOP_LOAD_HU ] = "LOAD_HU", - [RTLOP_LOAD_W ] = "LOAD_W", - [RTLOP_LOAD_PTR ] = "LOAD_PTR", - [RTLOP_STORE_B ] = "STORE_B", - [RTLOP_STORE_H ] = "STORE_H", - [RTLOP_STORE_W ] = "STORE_W", - [RTLOP_STORE_PTR ] = "STORE_PTR", - [RTLOP_LABEL ] = "LABEL", - [RTLOP_GOTO ] = "GOTO", - [RTLOP_GOTO_IF_Z ] = "GOTO_IF_Z", - [RTLOP_GOTO_IF_NZ ] = "GOTO_IF_NZ", - [RTLOP_GOTO_IF_E ] = "GOTO_IF_E", - [RTLOP_GOTO_IF_NE ] = "GOTO_IF_NE", - [RTLOP_CALL ] = "CALL", - [RTLOP_RETURN ] = "RETURN", - [RTLOP_RETURN_TO ] = "RETURN_TO", - }; - - static char buf[500]; - - const RTLInsn * const insn = &block->insns[index]; - const char * const name = opcode_names[insn->opcode]; - const unsigned int dest = insn->dest; - const unsigned int src1 = insn->src1; - const unsigned int src2 = insn->src2; - -#define APPEND_REG_DESC(regnum) \ - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "\n r%u: %s", \ - (regnum), rtl_describe_register(&block->regs[(regnum)], is_exec)); - - switch ((RTLOpcode)insn->opcode) { - - case RTLOP_NOP: - if (insn->src_imm) { - snprintf(buf, sizeof(buf), "%-11s 0x%X", name, insn->src_imm); - } else { - snprintf(buf, sizeof(buf), "%s", name); - } - return buf; - - case RTLOP_MOVE: - case RTLOP_NOT: - case RTLOP_CLZ: - case RTLOP_CLO: - case RTLOP_BSWAPH: - case RTLOP_BSWAPW: - case RTLOP_HSWAPW: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u", name, dest, src1); - APPEND_REG_DESC(src1); - return buf; - - case RTLOP_SELECT: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, r%u, r%u", name, - dest, src1, src2, insn->cond); - APPEND_REG_DESC(src1); - APPEND_REG_DESC(src2); - APPEND_REG_DESC(insn->cond); - return buf; - - case RTLOP_ADD: - case RTLOP_SUB: - case RTLOP_AND: - case RTLOP_OR: - case RTLOP_XOR: - case RTLOP_SLL: - case RTLOP_SRL: - case RTLOP_SRA: - case RTLOP_ROR: - case RTLOP_SLTU: - case RTLOP_SLTS: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, r%u", name, dest, src1, - src2); - APPEND_REG_DESC(src1); - APPEND_REG_DESC(src2); - return buf; - - case RTLOP_ADDI: - case RTLOP_SLTSI: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, %d", name, dest, src1, - insn->src_imm); - APPEND_REG_DESC(src1); - return buf; - - case RTLOP_SLLI: - case RTLOP_SRLI: - case RTLOP_SRAI: - case RTLOP_RORI: - case RTLOP_SLTUI: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, %u", name, dest, src1, - insn->src_imm); - APPEND_REG_DESC(src1); - return buf; - - case RTLOP_ANDI: - case RTLOP_ORI: - case RTLOP_XORI: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, 0x%X", name, dest, src1, - insn->src_imm); - APPEND_REG_DESC(src1); - return buf; - - case RTLOP_MULU: - case RTLOP_MULS: - case RTLOP_DIVMODU: - case RTLOP_DIVMODS: - if (dest == 0) { - if (insn->dest2 == 0) { - snprintf(buf, sizeof(buf), "%-11s ---, r%u, r%u, ---", name, - src1, src2); - } else { - snprintf(buf, sizeof(buf), "%-11s ---, r%u, r%u, r%u", name, - src1, src2, insn->dest2); - } - } else { - if (insn->dest2 == 0) { - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, r%u, ---", name, - dest, src1, src2); - } else { - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, r%u, r%u", name, - dest, src1, src2, insn->dest2); - } - } - APPEND_REG_DESC(src1); - APPEND_REG_DESC(src2); - return buf; - - case RTLOP_MADDU: - case RTLOP_MADDS: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, r%u, r%u", name, - dest, src1, src2, insn->dest2); - APPEND_REG_DESC(dest); - APPEND_REG_DESC(src1); - APPEND_REG_DESC(src2); - APPEND_REG_DESC(insn->dest2); - return buf; - - case RTLOP_BFEXT: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, %u, %u", name, dest, - src1, insn->bitfield.start, insn->bitfield.count); - APPEND_REG_DESC(src1); - return buf; - - case RTLOP_BFINS: - snprintf(buf, sizeof(buf), "%-11s r%u, r%u, r%u, %u, %u", name, dest, - src1, src2, insn->bitfield.start, insn->bitfield.count); - APPEND_REG_DESC(src1); - APPEND_REG_DESC(src2); - return buf; - - case RTLOP_LOAD_IMM: - if (insn->src_imm >= 0x10000 && insn->src_imm < 0xFFFF0000) { - snprintf(buf, sizeof(buf), "%-11s r%u, 0x%X", name, dest, - insn->src_imm); - } else { - snprintf(buf, sizeof(buf), "%-11s r%u, %d", name, dest, - (int32_t)insn->src_imm); - } - return buf; - - case RTLOP_LOAD_ADDR: - snprintf(buf, sizeof(buf), "%-11s r%u, 0x%lX", name, dest, - (unsigned long)insn->src_addr); - return buf; - - case RTLOP_LOAD_PARAM: - snprintf(buf, sizeof(buf), "%-11s r%u, params[%u]", name, dest, - insn->src_imm); - return buf; - - case RTLOP_LOAD_BU: - case RTLOP_LOAD_BS: - case RTLOP_LOAD_HU: - case RTLOP_LOAD_HS: - case RTLOP_LOAD_W: - case RTLOP_LOAD_PTR: - snprintf(buf, sizeof(buf), "%-11s r%u, %d(r%u)", name, dest, - insn->offset, src1); - APPEND_REG_DESC(src1); - return buf; - - case RTLOP_STORE_B: - case RTLOP_STORE_H: - case RTLOP_STORE_W: - case RTLOP_STORE_PTR: - snprintf(buf, sizeof(buf), "%-11s %d(r%u), r%u", name, - insn->offset, dest, src1); - APPEND_REG_DESC(src1); - APPEND_REG_DESC(dest); - return buf; - - case RTLOP_LABEL: - case RTLOP_GOTO: - snprintf(buf, sizeof(buf), "%-11s L%u", name, insn->label); - return buf; - - case RTLOP_GOTO_IF_Z: - case RTLOP_GOTO_IF_NZ: - snprintf(buf, sizeof(buf), "%-11s L%u, r%u", name, insn->label, src1); - APPEND_REG_DESC(src1); - return buf; - - case RTLOP_GOTO_IF_E: - case RTLOP_GOTO_IF_NE: - snprintf(buf, sizeof(buf), "%-11s L%u, r%u, r%u", name, insn->label, - src1, src2); - APPEND_REG_DESC(src1); - APPEND_REG_DESC(src2); - return buf; - - case RTLOP_CALL: - if (insn->dest) { - int len = snprintf(buf, sizeof(buf), "%-11s r%u = r%u(", - name, dest, insn->target); - if (src1) { - len += snprintf(buf+len, sizeof(buf)-len, "r%u", src1); - if (src2) { - len += snprintf(buf+len, sizeof(buf)-len, ", r%u", src2); - } - } - snprintf(buf+len, sizeof(buf)-len, ")"); - } else { - int len = snprintf(buf, sizeof(buf), "%-11s r%u(", - name, insn->target); - if (src1) { - len += snprintf(buf+len, sizeof(buf)-len, "r%u", src1); - if (src2) { - len += snprintf(buf+len, sizeof(buf)-len, ", r%u", src2); - } - } - snprintf(buf+len, sizeof(buf)-len, ")"); - } - if (src1) { - APPEND_REG_DESC(src1); - if (src2) { - APPEND_REG_DESC(src2); - } - } - APPEND_REG_DESC(insn->target); - return buf; - - case RTLOP_RETURN: - snprintf(buf, sizeof(buf), "%-11s", name); - return buf; - - case RTLOP_RETURN_TO: - snprintf(buf, sizeof(buf), "%-11s r%u", name, insn->target); - APPEND_REG_DESC(insn->target); - return buf; - - } // switch (insn->opcode) - - snprintf(buf, sizeof(buf), "???"); - return buf; - -#undef APPEND_REG_DESC -} - -/*-----------------------------------------------------------------------*/ - -/** - * rtl_describe_register: Generate a string describing the contents of the - * given RTL register. - * - * [Parameters] - * reg: Register to describe - * is_exec: Nonzero if being called from interpreted execution, else zero - * [Return value] - * Human-readable string describing the register - * [Notes] - * The returned string is stored in a static buffer which is - * overwritten on each call. - */ -const char *rtl_describe_register(const RTLRegister *reg, int is_exec) -{ - PRECOND(reg != NULL, return ""); - - static char buf[100]; - if (is_exec || reg->source == RTLREG_CONSTANT) { - if ((intptr_t)reg->value >= 0x10000 - || (intptr_t)reg->value < -0x10000 - ) { - snprintf(buf, sizeof(buf), "0x%lX", (unsigned long)reg->value); - } else { - snprintf(buf, sizeof(buf), "%d", (int32_t)reg->value); - } - } else if (reg->source == RTLREG_PARAMETER) { - snprintf(buf, sizeof(buf), "param[%u]", reg->param_index); - } else if (reg->source == RTLREG_MEMORY) { - snprintf(buf, sizeof(buf), "(%ssigned) @(%d,r%u).%s", - reg->memory.is_signed ? "" : "un", reg->memory.offset, - reg->memory.addr_reg, - reg->memory.size==1 ? "b" : - reg->memory.size==2 ? "w" : - reg->memory.size==4 ? "l" : "ptr"); - } else if (reg->source == RTLREG_RESULT - || reg->source == RTLREG_RESULT_NOFOLD) { - static const char * const operators[] = { - [RTLOP_ADD ] = "+", - [RTLOP_SUB ] = "-", - [RTLOP_AND ] = "&", - [RTLOP_OR ] = "|", - [RTLOP_XOR ] = "^", - [RTLOP_SLL ] = "<<", - [RTLOP_SRL ] = ">>", - [RTLOP_SRA ] = ">>", - [RTLOP_ROR ] = "ROR", - [RTLOP_CLZ ] = "CLZ", - [RTLOP_CLO ] = "CLO", - [RTLOP_SLTU ] = "<", - [RTLOP_SLTS ] = "<", - [RTLOP_BSWAPH] = "BSWAPH", - [RTLOP_BSWAPW] = "BSWAPW", - [RTLOP_HSWAPW] = "HSWAPW", - [RTLOP_ADDI ] = "+", - [RTLOP_ANDI ] = "&", - [RTLOP_ORI ] = "|", - [RTLOP_XORI ] = "^", - [RTLOP_SLLI ] = "<<", - [RTLOP_SRLI ] = ">>", - [RTLOP_SRAI ] = ">>", - [RTLOP_RORI ] = "ROR", - [RTLOP_SLTUI ] = "<", - [RTLOP_SLTSI ] = "<", - }; - // 0x01: immediate operand is signed, 0x02: display "(signed)" - static const uint8_t is_signed[] = { - [RTLOP_SRA ] = 2, - [RTLOP_SLTS ] = 2, - [RTLOP_ADDI ] = 1, - [RTLOP_SRAI ] = 2, - [RTLOP_SLTSI] = 3, - [RTLOP_SLTUI] = 1, - }; - switch (reg->result.opcode) { - case RTLOP_MOVE: - snprintf(buf, sizeof(buf), "r%u", reg->result.src1); - break; - case RTLOP_SELECT: - snprintf(buf, sizeof(buf), "r%u ? r%u : r%u", reg->result.cond, - reg->result.src1, reg->result.src2); - break; - case RTLOP_NOT: - snprintf(buf, sizeof(buf), "~r%u", reg->result.src1); - break; - case RTLOP_CLZ: - case RTLOP_CLO: - case RTLOP_BSWAPH: - case RTLOP_BSWAPW: - case RTLOP_HSWAPW: - snprintf(buf, sizeof(buf), "%s(r%u)", - operators[reg->result.opcode], reg->result.src1); - break; - case RTLOP_ADD: - case RTLOP_SUB: - case RTLOP_AND: - case RTLOP_OR: - case RTLOP_XOR: - case RTLOP_SLL: - case RTLOP_SRL: - case RTLOP_SRA: - case RTLOP_ROR: - case RTLOP_SLTU: - case RTLOP_SLTS: - snprintf(buf, sizeof(buf), "%sr%u %s r%u", - is_signed[reg->result.opcode] & 2 ? "(signed) " : "", - reg->result.src1, operators[reg->result.opcode], - reg->result.src2); - break; - case RTLOP_ADDI: - case RTLOP_ANDI: - case RTLOP_ORI: - case RTLOP_XORI: - case RTLOP_SLLI: - case RTLOP_SRLI: - case RTLOP_SRAI: - case RTLOP_RORI: - case RTLOP_SLTUI: - case RTLOP_SLTSI: - snprintf(buf, sizeof(buf), "%sr%u %s ", - is_signed[reg->result.opcode] & 2 ? "(signed) " : "", - reg->result.src1, operators[reg->result.opcode]); - if ((is_signed[reg->result.opcode] & 1) - && (int32_t)reg->result.imm >= -0x8000 - && (int32_t)reg->result.imm <= 0xFFFF - ) { - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%d", - (int)reg->result.imm); - } else { - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "0x%X", - (int)reg->result.imm); - } - break; - case RTLOP_MULU: - case RTLOP_MULS: - snprintf(buf, sizeof(buf), "%s%sr%u * r%u%s", - reg->result.opcode == RTLOP_MULS ? "(signed) " : "", - reg->result.second_res ? "(" : "", - reg->result.src1, reg->result.src2, - reg->result.second_res ? ") >> 32" : ""); - break; - case RTLOP_DIVMODU: - case RTLOP_DIVMODS: - snprintf(buf, sizeof(buf), "%sr%u %c r%u", - reg->result.opcode == RTLOP_DIVMODS ? "(signed) " : "", - reg->result.src1, reg->result.second_res ? '%' : '/', - reg->result.src2); - break; - case RTLOP_BFEXT: - snprintf(buf, sizeof(buf), "BFEXT(r%u, %u, %u)", - reg->result.src1, reg->result.start, reg->result.count); - break; - case RTLOP_BFINS: - snprintf(buf, sizeof(buf), "BFINS(r%u, r%u, %u, %u)", - reg->result.src1, reg->result.src2, - reg->result.start, reg->result.count); - break; - default: - snprintf(buf, sizeof(buf), "???"); - break; - } // switch (reg->result.opcode) - } else { - snprintf(buf, sizeof(buf), "???"); - } - return buf; -} - -#endif // RTL_TRACE_GENERATE || RTL_TRACE_EXECUTE - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * add_unit_edges: Add edges between basic units for GOTO instructions. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - * [Notes] - * Execution time is O(n) in the number of basic units. - */ -static int add_unit_edges(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - - unsigned int unit_index; - for (unit_index = 0; unit_index < block->num_units; unit_index++) { - RTLUnit * const unit = &block->units[unit_index]; - if (unit->first_insn <= unit->last_insn) { - const RTLInsn * const insn = &block->insns[unit->last_insn]; - if (insn->opcode == RTLOP_GOTO - || insn->opcode == RTLOP_GOTO_IF_Z - || insn->opcode == RTLOP_GOTO_IF_NZ - || insn->opcode == RTLOP_GOTO_IF_E - || insn->opcode == RTLOP_GOTO_IF_NE - ) { - const unsigned int label = insn->label; - if (UNLIKELY(block->label_unitmap[label] < 0)) { - DMSG("%p/%u: GOTO to unknown label %u", block, - unit->last_insn, label); - return 0; - } else if (UNLIKELY(!rtlunit_add_edge(block, unit_index, block->label_unitmap[label]))) { - DMSG("%p: Failed to add edge %u->%u for %s L%u", block, - unit_index, block->label_unitmap[label], - insn->opcode == RTLOP_GOTO ? "GOTO" : - insn->opcode == RTLOP_GOTO_IF_Z ? "GOTO_IF_Z" : - insn->opcode == RTLOP_GOTO_IF_NZ ? "GOTO_IF_NZ" : - insn->opcode == RTLOP_GOTO_IF_E ? "GOTO_IF_E" : - "GOTO_IF_NE", - label); - return 0; - } - } - } - } - - return 1; -} - -/*************************************************************************/ - -/** - * update_live_ranges: Update the live range of any register live at the - * beginning unit targeted by a backward branch so that the register is - * live through all branches that target the unit. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - * [Notes] - * Worst-case execution time is O(n*m) in the number of units (n) and - * the number of registers (m). However, the register scan is only - * required for units targeted by backward branches, and terminates at - * the first register born within or after the targeted unit. - */ -static int update_live_ranges(RTLBlock * const block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - - int unit_index; - for (unit_index = 0; unit_index < block->num_units; unit_index++) { - const RTLUnit * const unit = &block->units[unit_index]; - int latest_entry_unit = -1; - unsigned int i; - for (i = 0; i < lenof(unit->entries) && unit->entries[i] >= 0; i++) { - if (unit->entries[i] > latest_entry_unit) { - latest_entry_unit = unit->entries[i]; - } - } - if (latest_entry_unit >= unit_index - && block->units[latest_entry_unit].last_insn >= 0 // Just in case - ) { - const uint32_t birth_limit = unit->first_insn; - const uint32_t min_death = - block->units[latest_entry_unit].last_insn; - unsigned int reg; - for (reg = block->first_live_reg; - reg != 0 && block->regs[reg].birth < birth_limit; - reg = block->regs[reg].live_link - ) { - if (block->regs[reg].death >= birth_limit - && block->regs[reg].death < min_death - ) { - block->regs[reg].death = min_death; - } - } - } - } - - return 1; -} - -/*************************************************************************/ -/*************************************************************************/ - -#ifdef RTL_TRACE_GENERATE - -/** - * dump_block: Dump the contents of an RTL block to stderr. - * - * [Parameters] - * block: RTL block - * tag: Tag to prepend to all lines, or NULL for none - * [Return value] - * None - */ -static void dump_block(const RTLBlock * const block, const char * const tag) -{ - PRECOND(block != NULL, return); - - uint32_t insn_index; - for (insn_index = 0; insn_index < block->num_insns; insn_index++) { - fprintf(stderr, "[RTL] %s%s%s%p/%5u: %s\n", - tag ? "[" : "", tag ? tag : "", tag ? "] " : "", - block, insn_index, rtl_decode_insn(block, insn_index, 0)); - } - - rtlunit_dump_all(block, tag); -} - -#endif // RTL_TRACE_GENERATE - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/rtl.h b/yabause/src/psp/rtl.h deleted file mode 100644 index aed1d5fabb..0000000000 --- a/yabause/src/psp/rtl.h +++ /dev/null @@ -1,314 +0,0 @@ -/* src/psp/rtl.h: Declarations for register transfer language used in - dynamic translation - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef RTL_H -#define RTL_H - -/*************************************************************************/ - -/** - * RTLBlock: State information used in translating a block of code. - * Opaque to callers. - */ -typedef struct RTLBlock_ RTLBlock; - -/*-----------------------------------------------------------------------*/ - -/** - * RTLOpcode: Enumeration of operations, used as the value of the - * RTLInsn.op field. - */ -typedef enum RTLOpcode_ { - /* Zero is invalid */ - - /* No operation */ - RTLOP_NOP = 1, // [No operation -- note that a value can be given - // in src1 for debugging purposes] - - /* Register-register operations */ - RTLOP_MOVE, // dest = src1 - RTLOP_SELECT, // dest = other ? src1 : src2 - RTLOP_ADD, // dest = src1 + src2 - RTLOP_SUB, // dest = src1 - src2 - RTLOP_MULU, // (uint64_t){other,dest} = - // (unsigned)src1 * (unsigned)src2 - // [upper 32 bits of result stored in "other", - // lower 32 bits of result stored in "dest"; - // either dest or other may be zero = omitted] - RTLOP_MULS, // (int64_t){other,dest} = (signed)src1 * (signed)src2 - // [either dest or other may be zero = omitted] - RTLOP_MADDU, // (uint64_t){other,dest} += - // (unsigned)src1 * (unsigned)src2 - // [other/dest are both inputs and outputs; for - // optimal performance, they should be the same - // registers used as outputs of a MULU/MULS or - // previous MADDU/MADDS insn] - RTLOP_MADDS, // (int64_t){other,dest} += (signed)src1 * (signed)src2 - RTLOP_DIVMODU, // dest = (unsigned)src1 / (unsigned)src2; - // other = (unsigned)src1 % (unsigned)src2 - // [both undefined if src2 == 0] - // [either dest or other may be zero = omitted] - RTLOP_DIVMODS, // dest = (signed)src1 / (signed)src2; - // other = (signed)src1 % (signed)src2 - // [both undefined if src2 == 0] - // [either dest or other may be zero = omitted] - RTLOP_AND, // dest = src1 & src2 - RTLOP_OR, // dest = src1 | src2 - RTLOP_XOR, // dest = src1 ^ src2 - RTLOP_NOT, // dest = ~src1 - RTLOP_SLL, // dest = src1 << src2 [undefined when src2 >= 32] - RTLOP_SRL, // dest = (unsigned)src1 >> src2 - // [undefined when src2 >= 32] - RTLOP_SRA, // dest = (signed)src1 >> src2 - // [undefined when src2 >= 32] - RTLOP_ROR, // dest = src1 ROR (src2 % 32) [in 32 bits] - RTLOP_CLZ, // dest = [number of leading zeros in src1] - RTLOP_CLO, // dest = [number of leading ones in src1] - RTLOP_SLTU, // dest = (unsigned)src1 < (unsigned)src2 ? 1 : 0 - RTLOP_SLTS, // dest = (signed)src1 < (signed)src2 ? 1 : 0 - RTLOP_BSWAPH, // dest = [swap adjacent pairs of bytes in src1] - RTLOP_BSWAPW, // dest = [reverse order of sets of 4 bytes in src1] - RTLOP_HSWAPW, // dest = [swap adjacent pairs of halfword in src1] - - /* Register-immediate operations */ - RTLOP_ADDI, // dest = src1 + IMMEDIATE(src2) - RTLOP_ANDI, // dest = src1 & IMMEDIATE(src2) - RTLOP_ORI, // dest = src1 | IMMEDIATE(src2) - RTLOP_XORI, // dest = src1 ^ IMMEDIATE(src2) - RTLOP_SLLI, // dest = src1 << IMMEDIATE(src2) - RTLOP_SRLI, // dest = (unsigned)src1 >> IMMEDIATE(src2) - RTLOP_SRAI, // dest = (signed)src1 << IMMEDIATE(src2) - RTLOP_RORI, // dest = src1 ROR IMMEDIATE(src2) [in 32 bits] - RTLOP_SLTUI, // dest = (unsigned)src1 < (unsigned)IMMEDIATE(src2) - // ? 1 : 0 - RTLOP_SLTSI, // dest = (signed)src1 < (signed)IMMEDIATE(src2) - // ? 1 : 0 - - /* Bitfield operations ("start" and "count" are encoded in the "other" - * parameter as: other = start | count<<8) */ - RTLOP_BFEXT, // dest = (src1 >> start) & ((1<finalized, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(state != NULL, return 0); - - /* Create the instruction-to-unit lookup table if it hasn't been - * created yet */ - if (UNLIKELY(!block->insn_unitmap)) { - if (UNLIKELY(!create_insn_unitmap(block))) { - DMSG("%p: Failed to create insn-to-unit lookup table", block); - return 0; - } - } - -#ifdef RTL_TRACE_STEALTH_FOR_SH2 - /* Clear the SH-2 register cache bitmask */ - block->sh2_regcache_mask = 0; -#endif - - /* Actually execute instructions */ - uint32_t insn_count = 0; - uint32_t index = 0; - while (index < block->num_insns) { - insn_count++; - if (!rtl_execute_insn(block, &index, state)) { - break; - } - } - return insn_count; -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * create_insn_unitmap: Create a lookup table mapping instruction indices to - * unit indices, used by rtl_execute_block() to find the unit containing - * the first instruction to execute. - * - * [Parameters] - * block: RTLBlock to create table for - * [Return value] - * Nonzero on success, zero on error - */ -static int create_insn_unitmap(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->units != NULL, return 0); - - block->insn_unitmap = - malloc(sizeof(*block->insn_unitmap) * block->num_insns); - if (UNLIKELY(!block->insn_unitmap)) { - DMSG("No memory for insn-to-unit lookup table (%lu bytes)", - (unsigned long)(sizeof(*block->insn_unitmap) * block->num_insns)); - return 0; - } - memset(block->insn_unitmap, -1, - sizeof(*block->insn_unitmap) * block->num_insns); - - unsigned int unit_index; - for (unit_index = 0; unit_index < block->num_units; unit_index++) { - uint32_t insn_index; - for (insn_index = block->units[unit_index].first_insn; - (int32_t)insn_index <= block->units[unit_index].last_insn; - insn_index++ - ) { - block->insn_unitmap[insn_index] = unit_index; - } - } - - return 1; -} - -/*************************************************************************/ - -/** - * rtl_execute_insn: Execute a single RTL instruction from the given - * block. - * - * [Parameters] - * block: RTLBlock to execute - * index_ptr: Pointer to variable holding index of instruction to - * execute; incremented on return to indicate the next - * instruction to execute - * state: SH-2 state block - * [Return value] - * Nonzero to continue execution, zero to terminate execution - */ -static inline int rtl_execute_insn(RTLBlock *block, uint32_t *index_ptr, - void *state) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(index_ptr != NULL, return 0); - PRECOND(*index_ptr < block->num_insns, return 0); - PRECOND(state != NULL, return 0); - -#ifdef RTL_TRACE_EXECUTE - fprintf(stderr, "%p/%u: %s\n", block, *index_ptr, - rtl_decode_insn(block, *index_ptr, 1)); -#endif - - const RTLInsn * const insn = &block->insns[*index_ptr]; - const RTLUnit * const unit = &block->units[block->insn_unitmap[*index_ptr]]; - if (*index_ptr < unit->last_insn) { - (*index_ptr)++; - } else { - int next_unit = unit->next_unit; - while (next_unit >= 0 && block->units[next_unit].first_insn - > block->units[next_unit].last_insn) { - next_unit = block->units[next_unit].next_unit; - } - if (next_unit >= 0) { - *index_ptr = block->units[next_unit].first_insn; - } else { - *index_ptr = block->num_insns; // Terminate execution - } - } - - RTLRegister * const dest = &block->regs[insn->dest]; - const RTLRegister * const src1 = &block->regs[insn->src1]; - const RTLRegister * const src2 = &block->regs[insn->src2]; - - /*------------------------------*/ - - switch ((RTLOpcode)insn->opcode) { - - case RTLOP_NOP: -#ifdef RTL_TRACE_STEALTH_FOR_SH2 - if (insn->src_imm >> 28 == 0x8 || insn->src_imm >> 28 == 0xA) { - /* Trace an instruction */ - - SH2State *sh2 = (SH2State *)state; - uint32_t *sh2_regs = (uint32_t *)&sh2; - uint32_t saveregs[23]; - memcpy(saveregs, sh2_regs, sizeof(saveregs)); - uint32_t mask = block->sh2_regcache_mask; - unsigned int sh2_reg; - for (sh2_reg = 0; mask != 0; mask >>= 1, sh2_reg++) { - if (mask & 1) { - sh2_regs[sh2_reg] = block->sh2_regcache[sh2_reg]; - } - } - uint32_t op = block->insns[(*index_ptr)++].src_imm; - unsigned int do_trace = 1; - if (op>>24 == 0x9F) { // Conditional execution - const unsigned int cond_reg = op & 0xFFFF; - const unsigned int test_bit = op>>16 & 1; - do_trace = (block->regs[cond_reg].value == test_bit); - op = block->insns[(*index_ptr)++].src_imm; - } - uint32_t cached_cycles = op; - PRECOND(cached_cycles>>24 == 0x98, return 1); - cached_cycles &= 0xFFFF; - uint32_t cached_cycle_reg = block->insns[(*index_ptr)++].src_imm; - PRECOND(cached_cycles>>24 == 0x90, return 1); - cached_cycle_reg &= 0xFFFF; - if (cached_cycle_reg) { - cached_cycles += block->regs[cached_cycle_reg].value; - } else { - cached_cycles += sh2->cycles; - } - const uint32_t old_cycles = sh2->cycles; - sh2->cycles = cached_cycles; - if (do_trace) { - (*trace_insn_callback)(sh2, insn->src_imm & 0x7FFFFFFF); - } - sh2->cycles = old_cycles; - memcpy(sh2_regs, saveregs, sizeof(saveregs)); - - } else if (insn->src_imm >> 28 == 0xB) { - /* Record a cached SH-2 register value */ - - uint32_t op = insn->src_imm; - uint32_t offset = 0; - if (op & 0x08000000) { - PRECOND(op>>24 == 0xB8, return 1); - offset = (op & 0xFFFF) << 16; - op = block->insns[(*index_ptr)++].src_imm; - PRECOND(op>>24 == 0xBC, return 1); - offset |= op & 0xFFFF; - op = block->insns[(*index_ptr)++].src_imm; - PRECOND(op>>24 == 0xB0, return 1); - } - unsigned int sh2_reg = (op >> 16) & 0xFF; - unsigned int rtl_reg = op & 0xFFFF; - if (rtl_reg) { - if (sh2_reg & 0x80) { // Used for SR.T - if (!(block->sh2_regcache_mask & 1<<16)) { - SH2State *sh2 = (SH2State *)state; - block->sh2_regcache[16] = sh2->SR & ~SR_T; - block->sh2_regcache_mask |= 1<<16; - } else { - block->sh2_regcache[16] &= ~SR_T; - } - block->sh2_regcache[16] |= block->regs[rtl_reg].value; - } else { - block->sh2_regcache[sh2_reg] = - block->regs[rtl_reg].value + offset; - block->sh2_regcache_mask |= 1<sh2_regcache[sh2_reg] = offset; - block->sh2_regcache_mask |= 1<sh2_regcache_mask &= ~(1<src_imm >> 28 == 0xC) { - /* Trace a store operation */ - - uint32_t op; - op = block->insns[(*index_ptr)++].src_imm; - PRECOND(op>>28 == 0xD, return 1); - uint32_t address; - if (op & 0x08000000) { - PRECOND(op>>24 == 0xD8, return 1); - address = (op & 0xFFFF) << 16; - op = block->insns[(*index_ptr)++].src_imm; - PRECOND(op>>24 == 0xDC, return 1); - address |= op & 0xFFFF; - } else { - address = block->regs[op & 0xFFFF].value; - op = block->insns[(*index_ptr)++].src_imm; - PRECOND(op>>24 == 0xD4, return 1); - address += (op & 0xFFFF) << 16; - op = block->insns[(*index_ptr)++].src_imm; - PRECOND(op>>24 == 0xD6, return 1); - address += op & 0xFFFF; - } - op = block->insns[(*index_ptr)++].src_imm; - PRECOND(op>>28 == 0xE, return 1); - const uint32_t src = block->regs[op & 0xFFFF].value; - switch (insn->src_imm & 0xFFFF) { - case 1: (*trace_storeb_callback)(address, src); break; - case 2: (*trace_storew_callback)(address, src); break; - case 4: (*trace_storel_callback)(address, src); break; - default: - DMSG("Invalid store trace type %u", insn->src_imm & 0xFF); - break; - } - - } -#endif // RTL_TRACE_STEALTH_FOR_SH2 - return 1; - - /*----------------------------*/ - - case RTLOP_MOVE: - dest->value = src1->value; - return 1; - - case RTLOP_SELECT: - dest->value = - block->regs[insn->cond].value ? src1->value : src2->value; - return 1; - - case RTLOP_ADD: - dest->value = src1->value + (intptr_t)(int32_t)src2->value; - return 1; - - case RTLOP_SUB: - dest->value = src1->value - (intptr_t)(int32_t)src2->value; - return 1; - - case RTLOP_MULU: { - RTLRegister * const dest2 = &block->regs[insn->dest2]; - dest->value = (uint32_t)(src1->value * src2->value); - dest2->value = (uint64_t)((uint64_t)(uint32_t)src1->value - * (uint64_t)(uint32_t)src2->value) >> 32; - return 1; - } - - case RTLOP_MULS: { - RTLRegister * const dest2 = &block->regs[insn->dest2]; - dest->value = (uint32_t)(src1->value * src2->value); - dest2->value = (int64_t)((int64_t)(int32_t)src1->value - * (int64_t)(int32_t)src2->value) >> 32; - return 1; - } - - case RTLOP_MADDU: { - RTLRegister * const dest2 = &block->regs[insn->dest2]; - uint64_t initial = (uint64_t)(uint32_t)dest2->value << 32 - | (uint64_t)(uint32_t)dest->value; - uint64_t product = (uint64_t)(uint32_t)src1->value - * (uint64_t)(uint32_t)src2->value; - uint64_t result = initial + product; - dest->value = (uint32_t)result; - dest2->value = (uint32_t)(result >> 32); - return 1; - } - - case RTLOP_MADDS: { - RTLRegister * const dest2 = &block->regs[insn->dest2]; - int64_t initial = (int64_t)(int32_t)dest2->value << 32 - | (int64_t)(uint32_t)dest->value; // unsigned! - int64_t product = (int64_t)(int32_t)src1->value - * (int64_t)(int32_t)src2->value; - int64_t result = initial + product; - dest->value = (uint32_t)result; - dest2->value = (uint32_t)(result >> 32); - return 1; - } - - case RTLOP_DIVMODU: - if (src2->value) { - RTLRegister * const dest2 = &block->regs[insn->dest2]; - dest->value = (uint32_t)src1->value / (uint32_t)src2->value; - dest2->value = (uint32_t)src1->value % (uint32_t)src2->value; - } - return 1; - - case RTLOP_DIVMODS: - if (src2->value) { - RTLRegister * const dest2 = &block->regs[insn->dest2]; - dest->value = (int32_t)src1->value / (int32_t)src2->value; - dest2->value = (int32_t)src1->value % (int32_t)src2->value; - } - return 1; - - case RTLOP_AND: - dest->value = src1->value & (intptr_t)(int32_t)src2->value; - return 1; - - case RTLOP_OR: - dest->value = src1->value | (uintptr_t)(uint32_t)src2->value; - return 1; - - case RTLOP_XOR: - dest->value = src1->value ^ (uintptr_t)(uint32_t)src2->value; - return 1; - - case RTLOP_NOT: - dest->value = (uint32_t)(~src1->value); - return 1; - - case RTLOP_SLL: - if (src2->value < 32) { - dest->value = (uint32_t)(src1->value << src2->value); - } else { - dest->value = 0; - } - return 1; - - case RTLOP_SRL: - if (src2->value < 32) { - dest->value = (uint32_t)src1->value >> src2->value; - } else { - dest->value = 0; - } - return 1; - - case RTLOP_SRA: - if (src2->value < 32) { - dest->value = (int32_t)src1->value >> src2->value; - } else { - dest->value = (int32_t)src1->value >> 31; - } - return 1; - - case RTLOP_ROR: - if ((src2->value & 31) != 0) { - dest->value = (uint32_t)src1->value >> (src2->value & 31) - | (uint32_t)src1->value << (32 - (src2->value & 31)); - } else { - dest->value = (uint32_t)src1->value; - } - return 1; - - case RTLOP_CLZ: { -#ifdef __GNUC__ - dest->value = __builtin_clz(src1->value); -#else - uint32_t temp = src1->value; - dest->value = 32; - while (temp) { - temp >>= 1; - dest->value--; - } -#endif - return 1; - } - - case RTLOP_CLO: { - uint32_t temp = src1->value; - dest->value = 0; - while ((int32_t)temp < 0) { - temp <<= 1; - dest->value++; - } - return 1; - } - - case RTLOP_SLTU: - dest->value = ((uint32_t)src1->value < (uint32_t)src2->value) ? 1 : 0; - return 1; - - case RTLOP_SLTS: - dest->value = ((int32_t)src1->value < (int32_t)src2->value) ? 1 : 0; - return 1; - - case RTLOP_BSWAPH: - dest->value = ((uint32_t)src1->value & 0xFF00FF00) >> 8 - | ((uint32_t)src1->value & 0x00FF00FF) << 8; - return 1; - - case RTLOP_BSWAPW: - dest->value = ((uint32_t)src1->value & 0xFF000000) >> 24 - | ((uint32_t)src1->value & 0x00FF0000) >> 8 - | ((uint32_t)src1->value & 0x0000FF00) << 8 - | ((uint32_t)src1->value & 0x000000FF) << 24; - return 1; - - case RTLOP_HSWAPW: - dest->value = ((uint32_t)src1->value & 0xFFFF0000) >> 16 - | ((uint32_t)src1->value & 0x0000FFFF) << 16; - return 1; - - /*----------------------------*/ - - case RTLOP_ADDI: - dest->value = src1->value + (intptr_t)(int32_t)insn->src_imm; - return 1; - - case RTLOP_ANDI: - dest->value = src1->value & (intptr_t)(int32_t)insn->src_imm; - return 1; - - case RTLOP_ORI: - dest->value = src1->value | (uintptr_t)(uint32_t)insn->src_imm; - return 1; - - case RTLOP_XORI: - dest->value = src1->value ^ (uintptr_t)(uint32_t)insn->src_imm; - return 1; - - case RTLOP_SLLI: - if (insn->src_imm < 32) { - dest->value = (uint32_t)(src1->value << insn->src_imm); - } else { - dest->value = 0; - } - return 1; - - case RTLOP_SRLI: - if (insn->src_imm < 32) { - dest->value = (uint32_t)src1->value >> insn->src_imm; - } else { - dest->value = 0; - } - return 1; - - case RTLOP_SRAI: - if (insn->src_imm < 32) { - dest->value = (int32_t)src1->value >> insn->src_imm; - } else { - dest->value = (int32_t)src1->value >> 31; - } - return 1; - - case RTLOP_RORI: - if ((insn->src_imm & 31) != 0) { - dest->value = (uint32_t)src1->value >> (insn->src_imm & 31) - | (uint32_t)src1->value << (32 - (insn->src_imm & 31)); - } else { - dest->value = (uint32_t)src1->value; - } - return 1; - - case RTLOP_SLTUI: - dest->value = ((uint32_t)src1->value < (uint32_t)insn->src_imm) ? 1 : 0; - return 1; - - case RTLOP_SLTSI: - dest->value = ((int32_t)src1->value < (int32_t)insn->src_imm) ? 1 : 0; - return 1; - - /*----------------------------*/ - - case RTLOP_BFEXT: - dest->value = ((uint32_t)src1->value >> insn->bitfield.start) - & ((1 << insn->bitfield.count) - 1); - return 1; - - case RTLOP_BFINS: - dest->value = ((uint32_t)src1->value - & ~(((1 << insn->bitfield.count) - 1) - << insn->bitfield.start)) - | (((uint32_t)src2->value - & ((1 << insn->bitfield.count) - 1)) - << insn->bitfield.start); - return 1; - - /*----------------------------*/ - - case RTLOP_LOAD_IMM: - dest->value = insn->src_imm; - return 1; - - case RTLOP_LOAD_ADDR: - dest->value = insn->src_addr; - return 1; - - case RTLOP_LOAD_PARAM: - if (insn->src_imm == 0) { - dest->value = (uintptr_t)state; - } else { - DMSG("LOAD_PARAM for undefined parameter %u", - (unsigned int)insn->src_imm); - dest->value = 0xDEADF00D; - } - return 1; - - case RTLOP_LOAD_BU: - dest->value = *(uint8_t *)(src1->value + insn->offset); - return 1; - - case RTLOP_LOAD_BS: - dest->value = *(int8_t *)(src1->value + insn->offset); - return 1; - - case RTLOP_LOAD_HU: - dest->value = *(uint16_t *)(src1->value + insn->offset); - return 1; - - case RTLOP_LOAD_HS: - dest->value = *(int16_t *)(src1->value + insn->offset); - return 1; - - case RTLOP_LOAD_W: - dest->value = *(uint32_t *)(src1->value + insn->offset); - return 1; - - case RTLOP_LOAD_PTR: - dest->value = *(uintptr_t *)(src1->value + insn->offset); - return 1; - - /*----------------------------*/ - - case RTLOP_STORE_B: - *(uint8_t *)(dest->value + insn->offset) = src1->value; - return 1; - - case RTLOP_STORE_H: - *(uint16_t *)(dest->value + insn->offset) = src1->value; - return 1; - - case RTLOP_STORE_W: - *(uint32_t *)(dest->value + insn->offset) = src1->value; - return 1; - - case RTLOP_STORE_PTR: - *(uintptr_t *)(dest->value + insn->offset) = src1->value; - return 1; - - /*----------------------------*/ - - case RTLOP_LABEL: - return 1; - - case RTLOP_GOTO: - do_goto: - if (insn->label < 1 || insn->label > block->next_label) { - DMSG("%p/%u: label %u out of range", - block, (int)(insn - block->insns), insn->label); - } else if (block->label_unitmap[insn->label] < 0) { - DMSG("%p/%u: label %u not defined", - block, (int)(insn - block->insns), insn->label); - } else { - *index_ptr = - block->units[block->label_unitmap[insn->label]].first_insn; - } - return 1; - - case RTLOP_GOTO_IF_Z: - if (src1->value == 0) { - goto do_goto; - } - return 1; - - case RTLOP_GOTO_IF_NZ: - if (src1->value != 0) { - goto do_goto; - } - return 1; - - case RTLOP_GOTO_IF_E: - if (src1->value == src2->value) { - goto do_goto; - } - return 1; - - case RTLOP_GOTO_IF_NE: - if (src1->value != src2->value) { - goto do_goto; - } - return 1; - - /*----------------------------*/ - - case RTLOP_CALL: { - /* The called function must take pointer-sized parameters and - * return a pointer-sized value. */ - const void *funcptr = (const void *)block->regs[insn->target].value; - if (insn->dest) { - if (insn->src1) { - if (insn->src2) { - FASTCALL uintptr_t (*func)(uintptr_t, uintptr_t) = funcptr; - dest->value = (*func)(src1->value, src2->value); - } else { - FASTCALL uintptr_t (*func)(uintptr_t) = funcptr; - dest->value = (*func)(src1->value); - } - } else { - FASTCALL uintptr_t (*func)(void) = funcptr; - dest->value = (*func)(); - } - } else { - if (insn->src1) { - if (insn->src2) { - FASTCALL void (*func)(uintptr_t, uintptr_t) = funcptr; - (*func)(src1->value, src2->value); - } else { - FASTCALL void (*func)(uintptr_t) = funcptr; - (*func)(src1->value); - } - } else { - FASTCALL void (*func)(void) = funcptr; - (*func)(); - } - } - return 1; - } - - /*----------------------------*/ - - case RTLOP_RETURN: - return 0; - - case RTLOP_RETURN_TO: { - RTLBlock *newblock = (RTLBlock *)block->regs[insn->target].value; - /* Assume we won't fill up the stack doing this... */ - rtl_execute_block(newblock, state); - return 0; - } - - } // switch (insn->opcode) - - /*------------------------------*/ - - DMSG("Block %p index %u: invalid opcode %u", block, *index_ptr, - insn->opcode); - return 1; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/rtlinsn.c b/yabause/src/psp/rtlinsn.c deleted file mode 100644 index e11dcfb9e4..0000000000 --- a/yabause/src/psp/rtlinsn.c +++ /dev/null @@ -1,935 +0,0 @@ -/* src/psp/rtlinsn.c: Instruction encoding routines for RTL - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ - -/* - * This source file defines functions for encoding RTL instructions into - * the RTLInsn structure based on the type of instruction (2-operand ALU, - * memory load, and so on). These functions are not exported directly, but - * are instead called through a lookup table by rtlinsn_make(), an inline - * function defined in rtl-internal.h. - * - * Both the inlining of rtlinsn_make() and the requirement of preloading - * the opcode into insn->opcode (and then taking the RTLInsn pointer in - * place of the opcode parameter to rtl_add_insn()) are to help - * optimization of the fast path; for example, on MIPS architectures, - * rtl_add_insn() can directly call the encoding function in this file - * without having to pass through a call to rtlinsn_make() or reload the - * parameter registers ($a0-$t1). - */ - -/*************************************************************************/ -/*************************** Required headers ****************************/ -/*************************************************************************/ - -#include "common.h" - -#include "rtl.h" -#include "rtl-internal.h" - -/*************************************************************************/ -/************************** Local declarations ***************************/ -/*************************************************************************/ - -/* Encoding functions for specific opcode groups */ - -static int make_nop(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_alu_1op(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_alu_2op(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_alui_2op(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_alu_2op_2dest(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_select(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_madd(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_bitfield(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_load_imm(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_load_addr(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_load_param(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_load(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_store(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_label(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_goto(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_goto_cond(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_goto_cond2(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_call(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_return(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); -static int make_return_to(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other); - - -/* Encoding function table */ - -int (* const makefunc_table[])(RTLBlock *, RTLInsn *, unsigned int, - uintptr_t, uint32_t, unsigned int) = { - [RTLOP_NOP ] = make_nop, - [RTLOP_MOVE ] = make_alu_1op, - [RTLOP_SELECT ] = make_select, - [RTLOP_ADD ] = make_alu_2op, - [RTLOP_SUB ] = make_alu_2op, - [RTLOP_MULU ] = make_alu_2op_2dest, - [RTLOP_MULS ] = make_alu_2op_2dest, - [RTLOP_MADDU ] = make_madd, - [RTLOP_MADDS ] = make_madd, - [RTLOP_DIVMODU ] = make_alu_2op_2dest, - [RTLOP_DIVMODS ] = make_alu_2op_2dest, - [RTLOP_AND ] = make_alu_2op, - [RTLOP_OR ] = make_alu_2op, - [RTLOP_XOR ] = make_alu_2op, - [RTLOP_NOT ] = make_alu_1op, - [RTLOP_SLL ] = make_alu_2op, - [RTLOP_SRL ] = make_alu_2op, - [RTLOP_SRA ] = make_alu_2op, - [RTLOP_ROR ] = make_alu_2op, - [RTLOP_CLZ ] = make_alu_1op, - [RTLOP_CLO ] = make_alu_1op, - [RTLOP_SLTU ] = make_alu_2op, - [RTLOP_SLTS ] = make_alu_2op, - [RTLOP_BSWAPH ] = make_alu_1op, - [RTLOP_BSWAPW ] = make_alu_1op, - [RTLOP_HSWAPW ] = make_alu_1op, - [RTLOP_ADDI ] = make_alui_2op, - [RTLOP_ANDI ] = make_alui_2op, - [RTLOP_ORI ] = make_alui_2op, - [RTLOP_XORI ] = make_alui_2op, - [RTLOP_SLLI ] = make_alui_2op, - [RTLOP_SRLI ] = make_alui_2op, - [RTLOP_SRAI ] = make_alui_2op, - [RTLOP_RORI ] = make_alui_2op, - [RTLOP_SLTUI ] = make_alui_2op, - [RTLOP_SLTSI ] = make_alui_2op, - [RTLOP_BFEXT ] = make_bitfield, - [RTLOP_BFINS ] = make_bitfield, - [RTLOP_LOAD_IMM ] = make_load_imm, - [RTLOP_LOAD_ADDR ] = make_load_addr, - [RTLOP_LOAD_PARAM ] = make_load_param, - [RTLOP_LOAD_BS ] = make_load, - [RTLOP_LOAD_BU ] = make_load, - [RTLOP_LOAD_HS ] = make_load, - [RTLOP_LOAD_HU ] = make_load, - [RTLOP_LOAD_W ] = make_load, - [RTLOP_LOAD_PTR ] = make_load, - [RTLOP_STORE_B ] = make_store, - [RTLOP_STORE_H ] = make_store, - [RTLOP_STORE_W ] = make_store, - [RTLOP_STORE_PTR ] = make_store, - [RTLOP_LABEL ] = make_label, - [RTLOP_GOTO ] = make_goto, - [RTLOP_GOTO_IF_Z ] = make_goto_cond, - [RTLOP_GOTO_IF_NZ ] = make_goto_cond, - [RTLOP_GOTO_IF_E ] = make_goto_cond2, - [RTLOP_GOTO_IF_NE ] = make_goto_cond2, - [RTLOP_CALL ] = make_call, - [RTLOP_RETURN ] = make_return, - [RTLOP_RETURN_TO ] = make_return_to, -}; - -/*-----------------------------------------------------------------------*/ - -/* Macro to mark a given register live, updating birth/death fields too - * (requires block and insn_index to be separately defined) */ -#define MARK_LIVE(reg,index) do { \ - RTLRegister * const __reg = (reg); \ - const unsigned int __index = (index); \ - if (!__reg->live) { \ - __reg->live = 1; \ - __reg->birth = insn_index; \ - if (!block->last_live_reg) { \ - block->first_live_reg = __index; \ - } else { \ - block->regs[block->last_live_reg].live_link = __index; \ - } \ - block->last_live_reg = __index; \ - reg->live_link = 0; \ - } \ - __reg->death = insn_index; \ -} while (0) - -/*************************************************************************/ -/************************** Routine definitions **************************/ -/*************************************************************************/ - -/** - * make_nop: Encode a NOP instruction. - */ -static int make_nop(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(insn != NULL, return 0); - - insn->src_imm = src1; - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_alu_1op: Encode a 1-operand ALU instruction. - */ -static int make_alu_1op(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); -#endif - - insn->dest = dest; - // FIXME: why does GCC waste time with an ANDI temp,arg,0xFFFF for - // stores like this src1 (but not with dest)? - insn->src1 = src1; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_RESULT; - if (insn->opcode == RTLOP_MOVE) { - destreg->unique_pointer = src1reg->unique_pointer; - } else { - destreg->unique_pointer = 0; - } - destreg->result.opcode = insn->opcode; - destreg->result.second_res = 0; - destreg->result.is_imm = 0; - destreg->result.src1 = src1; - destreg->result.src2 = 0; - MARK_LIVE(destreg, dest); - MARK_LIVE(src1reg, src1); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_alu_2op: Encode a 2-operand ALU instruction. - */ -static int make_alu_2op(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND(src2 != 0 && src2 < block->next_reg, return 0); -#endif - - insn->dest = dest; - insn->src1 = src1; - insn->src2 = src2; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - RTLRegister * const src2reg = &block->regs[src2]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_RESULT; - destreg->unique_pointer = 0; - destreg->result.opcode = insn->opcode; - destreg->result.second_res = 0; - destreg->result.is_imm = 0; - destreg->result.src1 = src1; - destreg->result.src2 = src2; - MARK_LIVE(destreg, dest); - MARK_LIVE(src1reg, src1); - MARK_LIVE(src2reg, src2); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_alui_2op: Encode a 2-operand register-immediate ALU instruction. - */ -static int make_alui_2op(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); -#endif - - insn->dest = dest; - insn->src1 = src1; - insn->src_imm = src2; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_RESULT; - destreg->unique_pointer = 0; - destreg->result.opcode = insn->opcode; - destreg->result.second_res = 0; - destreg->result.is_imm = 1; - destreg->result.src1 = src1; - destreg->result.imm = src2; - MARK_LIVE(destreg, dest); - MARK_LIVE(src1reg, src1); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_alu_2op_2dest: Encode a 2-operand, 2-destination ALU instruction. - */ -static int make_alu_2op_2dest(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND(src2 != 0 && src2 < block->next_reg, return 0); - PRECOND(other < block->next_reg, return 0); -#endif - - insn->dest = dest; - insn->src1 = src1; - insn->src2 = src2; - insn->dest2 = other; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - RTLRegister * const src2reg = &block->regs[src2]; - RTLRegister * const dest2reg = &block->regs[other]; - const uint32_t insn_index = block->num_insns; - if (dest != 0) { - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_RESULT; - destreg->unique_pointer = 0; - destreg->result.opcode = insn->opcode; - destreg->result.second_res = 0; - destreg->result.is_imm = 0; - destreg->result.src1 = src1; - destreg->result.src2 = src2; - MARK_LIVE(destreg, dest); - } - if (other != 0) { - dest2reg->source = dest2reg->source ? RTLREG_UNKNOWN : RTLREG_RESULT; - dest2reg->unique_pointer = 0; - dest2reg->result.opcode = insn->opcode; - dest2reg->result.second_res = 1; - dest2reg->result.is_imm = 0; - dest2reg->result.src1 = src1; - dest2reg->result.src2 = src2; - MARK_LIVE(dest2reg, other); - } - MARK_LIVE(src1reg, src1); - MARK_LIVE(src2reg, src2); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_select: Encode a SELECT instruction. - */ -static int make_select(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND(src2 != 0 && src2 < block->next_reg, return 0); - PRECOND(other != 0 && other < block->next_reg, return 0); -#endif - - insn->dest = dest; - insn->src1 = src1; - insn->src2 = src2; - insn->cond = other; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - RTLRegister * const src2reg = &block->regs[src2]; - RTLRegister * const condreg = &block->regs[other]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_RESULT; - destreg->unique_pointer = 0; - destreg->result.opcode = insn->opcode; - destreg->result.second_res = 0; - destreg->result.is_imm = 0; - destreg->result.src1 = src1; - destreg->result.src2 = src2; - destreg->result.cond = other; - MARK_LIVE(destreg, dest); - MARK_LIVE(src1reg, src1); - MARK_LIVE(src2reg, src2); - MARK_LIVE(condreg, other); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_madd: Encode an MADDU or MADDS instruction. - */ -static int make_madd(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND(src2 != 0 && src2 < block->next_reg, return 0); - PRECOND(other != 0 && other < block->next_reg, return 0); -#endif - - insn->dest = dest; - insn->src1 = src1; - insn->src2 = src2; - insn->dest2 = other; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - RTLRegister * const src2reg = &block->regs[src2]; - RTLRegister * const dest2reg = &block->regs[other]; - const uint32_t insn_index = block->num_insns; - destreg->source = RTLREG_UNKNOWN; // Always UNKNOWN, since we modify it - destreg->unique_pointer = 0; - MARK_LIVE(destreg, dest); - dest2reg->source = RTLREG_UNKNOWN; - dest2reg->unique_pointer = 0; - MARK_LIVE(dest2reg, other); - MARK_LIVE(src1reg, src1); - MARK_LIVE(src2reg, src2); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_bitfield: Encode a bitfield instruction. - */ -static int make_bitfield(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); - const int start = other & 0xFF; - const int count = (other >> 8) & 0xFF; -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND((insn->opcode != RTLOP_BFINS || src2 != 0) && src2 < block->next_reg, return 0); - PRECOND(start < 32, return 0); - PRECOND(count <= 32 - start, return 0); -#endif - - insn->dest = dest; - insn->src1 = src1; - insn->src2 = src2; - insn->bitfield.start = start; - insn->bitfield.count = count; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - RTLRegister * const src2reg = &block->regs[src2]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_RESULT; - destreg->unique_pointer = 0; - destreg->result.opcode = insn->opcode; - destreg->result.second_res = 0; - destreg->result.is_imm = 0; - destreg->result.src1 = src1; - destreg->result.src2 = src2; - destreg->result.start = start; - destreg->result.count = count; - MARK_LIVE(destreg, dest); - MARK_LIVE(src1reg, src1); - if (src2) { - MARK_LIVE(src2reg, src2); - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_load_imm: Encode a LOAD_IMM instruction. - */ -static int make_load_imm(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); -#endif - - insn->dest = dest; - insn->src_imm = src1; - - RTLRegister * const destreg = &block->regs[dest]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_CONSTANT; - destreg->unique_pointer = 0; - destreg->value = src1; - MARK_LIVE(destreg, dest); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_load_addr: Encode a LOAD_ADDR instruction. - */ -static int make_load_addr(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); -#endif - - insn->dest = dest; - insn->src_addr = src1; - - RTLRegister * const destreg = &block->regs[dest]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_CONSTANT; - destreg->unique_pointer = 0; - destreg->value = src1; - MARK_LIVE(destreg, dest); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_load_param: Encode a LOAD_PARAM instruction. - */ -static int make_load_param(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); -#endif - - insn->dest = dest; - insn->src_imm = src1; - - RTLRegister * const destreg = &block->regs[dest]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_PARAMETER; - destreg->unique_pointer = 0; - destreg->param_index = src1; - MARK_LIVE(destreg, dest); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_load: Encode a memory load instruction. - */ -static int make_load(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND((int)other >= -0x8000 && (int)other <= 0x7FFF, return 0); -#endif - - /* Lookup tables for destreg->memory.{size,is_signed} */ - static const uint8_t size_lookup[] = { - [RTLOP_LOAD_BU ] = 1, [RTLOP_LOAD_BS] = 1, - [RTLOP_LOAD_HU ] = 2, [RTLOP_LOAD_HS] = 2, - [RTLOP_LOAD_W ] = 4, - [RTLOP_LOAD_PTR] = sizeof(void *), - }; - static const uint8_t is_signed_lookup[] = { - [RTLOP_LOAD_BS] = 1, - [RTLOP_LOAD_HS] = 1, - }; - - insn->dest = dest; - insn->src1 = src1; - insn->offset = other; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - const uint32_t insn_index = block->num_insns; - destreg->source = destreg->source ? RTLREG_UNKNOWN : RTLREG_MEMORY; - destreg->unique_pointer = 0; - destreg->memory.addr_reg = src1; - destreg->memory.offset = other; - const unsigned int opcode = insn->opcode; - destreg->memory.size = size_lookup[opcode]; - destreg->memory.is_signed = is_signed_lookup[opcode]; - MARK_LIVE(destreg, dest); - MARK_LIVE(src1reg, src1); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_store: Encode a memory store instruction. - */ -static int make_store(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest != 0 && dest < block->next_reg, return 0); - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND((int)other >= -0x8000 && (int)other <= 0x7FFF, return 0); -#endif - - insn->dest = dest; - insn->src1 = src1; - insn->offset = other; - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - const uint32_t insn_index = block->num_insns; - MARK_LIVE(destreg, dest); - MARK_LIVE(src1reg, src1); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_label: Encode a LABEL instruction. - */ -static int make_label(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->cur_unit >= 0 && block->cur_unit < block->num_units, - return 0); - PRECOND(block->label_unitmap != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(other != 0 && other < block->next_label, return 0); -#endif - - insn->label = other; - - /* If this is _not_ the first instruction in the current basic - * unit, end it and create a new basic unit starting here, since - * there could potentially be a branch to this location. */ - if (block->units[block->cur_unit].first_insn != block->num_insns) { - block->units[block->cur_unit].last_insn = block->num_insns - 1; - if (UNLIKELY(!rtlunit_add(block))) { - DMSG("%p/%u: Failed to start a new basic unit", - block, block->num_insns); - return 0; - } - const uint32_t new_unit = block->num_units - 1; - if (UNLIKELY(!rtlunit_add_edge(block, block->cur_unit, new_unit))){ - DMSG("%p/%u: Failed to add edge %u->%u", block, - block->num_insns, block->cur_unit, new_unit); - return 0; - } - block->cur_unit = new_unit; - block->units[block->cur_unit].first_insn = block->num_insns; - } - - /* Save the label's unit number in the label-to-unit map */ - block->label_unitmap[insn->label] = block->cur_unit; - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_goto: Encode a GOTO instruction. - */ -static int make_goto(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(other != 0 && other < block->next_label, return 0); -#endif - - insn->label = other; - - /* Terminate the current basic unit after this instruction */ - block->units[block->cur_unit].last_insn = block->num_insns; - block->have_unit = 0; - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_goto_cond: Encode a GOTO_IF_Z or GOTO_IF_NZ instruction. - */ -static int make_goto_cond(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND(other != 0 && other < block->next_label, return 0); -#endif - - insn->src1 = src1; - insn->label = other; - - RTLRegister * const src1reg = &block->regs[src1]; - const uint32_t insn_index = block->num_insns; - MARK_LIVE(src1reg, src1); - - /* Terminate the current basic unit after this instruction, and - * start a new basic unit with an edge connecting from this one */ - block->units[block->cur_unit].last_insn = block->num_insns; - if (UNLIKELY(!rtlunit_add(block))) { - DMSG("%p/%u: Failed to start a new basic unit", - block, block->num_insns); - return 0; - } - const unsigned int new_unit = block->num_units - 1; - if (UNLIKELY(!rtlunit_add_edge(block, block->cur_unit, new_unit))) { - DMSG("%p/%u: Failed to add edge %u->%u", block, block->num_insns, - block->cur_unit, new_unit); - return 0; - } - block->cur_unit = new_unit; - block->units[block->cur_unit].first_insn = block->num_insns + 1; - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_goto_cond2: Encode a GOTO_IF_E or GOTO_IF_NE instruction. - */ -static int make_goto_cond2(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(src1 != 0 && src1 < block->next_reg, return 0); - PRECOND(src2 != 0 && src2 < block->next_reg, return 0); - PRECOND(other != 0 && other < block->next_label, return 0); -#endif - - insn->src1 = src1; - insn->src2 = src2; - insn->label = other; - - RTLRegister * const src1reg = &block->regs[src1]; - RTLRegister * const src2reg = &block->regs[src2]; - const uint32_t insn_index = block->num_insns; - MARK_LIVE(src1reg, src1); - MARK_LIVE(src2reg, src2); - - block->units[block->cur_unit].last_insn = block->num_insns; - if (UNLIKELY(!rtlunit_add(block))) { - DMSG("%p/%u: Failed to start a new basic unit", - block, block->num_insns); - return 0; - } - const unsigned int new_unit = block->num_units - 1; - if (UNLIKELY(!rtlunit_add_edge(block, block->cur_unit, new_unit))) { - DMSG("%p/%u: Failed to add edge %u->%u", block, block->num_insns, - block->cur_unit, new_unit); - return 0; - } - block->cur_unit = new_unit; - block->units[block->cur_unit].first_insn = block->num_insns + 1; - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_call: Encode a CALL instruction. - */ -static int make_call(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); -#ifdef OPERAND_SANITY_CHECKS - PRECOND(dest < block->next_reg, return 0); - PRECOND(!(src1 == 0 && src2 != 0) && src1 < block->next_reg, return 0); - PRECOND(src2 < block->next_reg, return 0); - PRECOND(other != 0 && other < block->next_reg, return 0); -#endif - - RTLRegister * const destreg = &block->regs[dest]; - RTLRegister * const src1reg = &block->regs[src1]; - RTLRegister * const src2reg = &block->regs[src2]; - RTLRegister * const targetreg = &block->regs[other]; - const uint32_t insn_index = block->num_insns; - insn->dest = dest; - insn->src1 = src1; - insn->src2 = src2; - insn->target = other; - if (dest) { - destreg->source = RTLREG_UNKNOWN; - destreg->unique_pointer = 0; - MARK_LIVE(destreg, dest); - } - if (src1) { - MARK_LIVE(src1reg, src1); - } - if (src2) { - MARK_LIVE(src2reg, src2); - } - MARK_LIVE(targetreg, other); - - const int cur_unit = block->cur_unit; - if (block->first_call_unit < 0) { - block->first_call_unit = cur_unit; - } - if (block->last_call_unit < cur_unit) { - if (block->last_call_unit >= 0) { - block->units[block->last_call_unit].next_call_unit = cur_unit; - block->units[cur_unit].prev_call_unit = block->last_call_unit; - } else { - block->units[cur_unit].prev_call_unit = -1; - } - block->last_call_unit = cur_unit; - } - block->units[cur_unit].next_call_unit = -1; - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_return: Encode a RETURN instruction. - */ -static int make_return(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); - - /* Terminate the current basic unit, like GOTO */ - block->units[block->cur_unit].last_insn = block->num_insns; - block->have_unit = 0; - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * make_return_to: Encode a RETURN_TO instruction. - */ -static int make_return_to(RTLBlock *block, RTLInsn *insn, unsigned int dest, - uintptr_t src1, uint32_t src2, unsigned int other) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(insn != NULL, return 0); - - RTLRegister * const targetreg = &block->regs[other]; - const uint32_t insn_index = block->num_insns; - insn->target = other; - MARK_LIVE(targetreg, other); - - /* Terminate the current basic unit, like GOTO */ - block->units[block->cur_unit].last_insn = block->num_insns; - block->have_unit = 0; - - return 1; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/rtlopt.c b/yabause/src/psp/rtlopt.c deleted file mode 100644 index 1b17745fc8..0000000000 --- a/yabause/src/psp/rtlopt.c +++ /dev/null @@ -1,897 +0,0 @@ -/* src/psp/rtlopt.c: Optimization processing for RTL - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ - -/* - * This source file contains code for the various transformations applied - * to RTL code to produce more optimized instruction streams. The - * currently implemented transformations are: - * - * Constant folding/propagation (rtlopt_fold_constants) - * ---------------------------------------------------- - * Replaces instructions that operate on constant operands with LOAD_IMM - * (load immediate) instructions that load the result of the operation - * directly into the target register, eliminating the operation itself and - * allowing the constant result to be propagated further. Source operands - * that are not used elsewhere are eliminated entirely, with the - * instructions that loaded them converted to NOPs. - * - * While most constant expressions will be resolved by the source - * translator at RTL generation time, this optimization step allows macros - * in particular to take faster paths when they are called with constant - * parameters. - * - * Deconditioning (rtlopt_decondition) - * ---------------------------------- - * Converts conditional jumps (GOTO_IF_Z, GOTO_IF_NZ, GOTO_IF_E, GOTO_IF_NE) - * whose test result is a constant to either unconditional jumps (GOTO) or - * NOPs, depending on the instruction and the result of the test. - * - * Dead unit removal (rtlopt_drop_dead_units) - * ------------------------------------------ - * Removes unreachable basic units from the RTL code stream. - * - * Useless branch removal (rtlopt_drop_dead_branches) - * -------------------------------------------------- - * Replaces branch instructions that branch to the next instruction in the - * code stream with NOPs. - */ - -/*************************************************************************/ -/*************************** Required headers ****************************/ -/*************************************************************************/ - -#include "common.h" - -#include "rtl.h" -#include "rtl-internal.h" - -/*************************************************************************/ -/************************** Local declarations ***************************/ -/*************************************************************************/ - -static inline int fold_one_register(RTLBlock * const block, - RTLRegister * const reg); -static void maybe_eliminate_folded_register(RTLBlock * const block, - RTLRegister * const reg, - const unsigned int reg_index); - -static void drop_dead_unit(RTLBlock * const block, - const unsigned int unit_index); - -/*************************************************************************/ -/*********************** Library-internal routines ***********************/ -/*************************************************************************/ - -/** - * rtlopt_fold_constants: Perform constant folding on the given RTL block, - * converting instructions that operate on constant operands into load- - * immediate instructions that load the result of the operation. If such - * an operand is not used by any other instruction, the instruction that - * loaded it is changed to a NOP. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -int rtlopt_fold_constants(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - - unsigned int reg_index; - for (reg_index = 1; reg_index < block->next_reg; reg_index++) { - RTLRegister * const reg = &block->regs[reg_index]; - if (reg->live && reg->source == RTLREG_RESULT) { - fold_one_register(block, reg); - } - } - - return 1; -} - -/*************************************************************************/ - -/** - * rtlopt_decondition: Perform "deconditioning" of conditional branches - * with constant conditions. For "GOTO_IF_Z (GOTO_IF_NZ) label, rN" where - * rN is type RTLREG_CONSTANT, the instruction is changed to GOTO if the - * value of rN is zero (nonzero) and changed to NOP otherwise; similarly - * for "GOTO_IF_E (GOTO_IF_NE) label, rX, rY". As with constant folding, - * if a condition register is not used anywhere else, the register is - * eliminated and the instruction that loaded it is changed to a NOP. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -int rtlopt_decondition(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - - /* A conditional branch always ends an basic unit and has two targets, - * so we only need to check the last instruction of each unit with two - * exit edges. */ - - unsigned int unit_index; - for (unit_index = 0; unit_index < block->num_units; unit_index++) { - RTLUnit * const unit = &block->units[unit_index]; - if (unit->exits[1] != -1) { - RTLInsn * const insn = &block->insns[unit->last_insn]; - const RTLOpcode opcode = insn->opcode; - - if (opcode == RTLOP_GOTO_IF_Z || opcode == RTLOP_GOTO_IF_NZ) { - const unsigned int reg_index = insn->src1; - RTLRegister * const condition_reg = &block->regs[reg_index]; - if (condition_reg->source == RTLREG_CONSTANT) { - const uintptr_t condition = condition_reg->value; - const int fallthrough_index = - (unit->exits[0] == unit_index+1) ? 0 : 1; - if ((opcode == RTLOP_GOTO_IF_Z && condition == 0) - || (opcode == RTLOP_GOTO_IF_NZ && condition != 0) - ) { - /* Branch always taken: convert to GOTO */ -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] %p/%u: Branch always taken," - " convert to GOTO and drop edge %u->%u\n", - block, unit->last_insn, unit_index, - unit->exits[fallthrough_index]); -#endif - insn->opcode = RTLOP_GOTO; - rtlunit_remove_edge(block, unit_index, - fallthrough_index); - } else { - /* Branch never taken: convert to NOP */ -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] %p/%u: Branch never taken," - " convert to NOP and drop edge %u->%u\n", - block, unit->last_insn, unit_index, - unit->exits[fallthrough_index ^ 1]); -#endif - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - rtlunit_remove_edge(block, unit_index, - fallthrough_index ^ 1); - } - if (condition_reg->death == unit->last_insn) { - maybe_eliminate_folded_register(block, condition_reg, - reg_index); - } - } - - } else if (opcode == RTLOP_GOTO_IF_E || opcode == RTLOP_GOTO_IF_NE){ - const unsigned int src1_index = insn->src1; - const unsigned int src2_index = insn->src1; - RTLRegister * const src1_reg = &block->regs[src1_index]; - RTLRegister * const src2_reg = &block->regs[src2_index]; - if (src1_reg->source == RTLREG_CONSTANT - && src2_reg->source == RTLREG_CONSTANT - ) { - const uintptr_t condition = - src1_reg->value - src2_reg->value; - const int fallthrough_index = - (unit->exits[0] == unit_index+1) ? 0 : 1; - if ((opcode == RTLOP_GOTO_IF_Z && condition == 0) - || (opcode == RTLOP_GOTO_IF_NZ && condition != 0) - ) { - /* Branch always taken: convert to GOTO */ -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] %p/%u: Branch always taken," - " convert to GOTO and drop edge %u->%u\n", - block, unit->last_insn, unit_index, - unit->exits[fallthrough_index]); -#endif - insn->opcode = RTLOP_GOTO; - rtlunit_remove_edge(block, unit_index, - fallthrough_index); - } else { - /* Branch never taken: convert to NOP */ -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] %p/%u: Branch never taken," - " convert to NOP and drop edge %u->%u\n", - block, unit->last_insn, unit_index, - unit->exits[fallthrough_index ^ 1]); -#endif - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - rtlunit_remove_edge(block, unit_index, - fallthrough_index ^ 1); - } - if (src1_reg->death == unit->last_insn) { - maybe_eliminate_folded_register(block, src1_reg, - src1_index); - } - if (src2_reg->death == unit->last_insn) { - maybe_eliminate_folded_register(block, src2_reg, - src2_index); - } - } - - } - } // if (unit->exits[1] != -1) - } // for (unit_index = 0; unit_index < block->num_units; unit_index++) - - return 1; -} - -/*************************************************************************/ - -/** - * rtlopt_drop_dead_units: Search an RTL block for basic units which are - * unreachable via any path from the initial unit and remove them from the - * code stream. All units dominated only by such dead units are - * recursively removed as well. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -int rtlopt_drop_dead_units(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - - /* Allocate and clear a buffer for "seen" flags */ - block->unit_seen = calloc(block->num_units, sizeof(*block->unit_seen)); - if (UNLIKELY(!block->unit_seen)) { - DMSG("Failed to allocate units_seen (%u bytes)", block->num_units); - return 0; - } - - /* Check each unit in sequence (except the initial unit, which is never - * dead even if it has no entry edges) */ - unsigned int unit_index; - for (unit_index = 1; unit_index < block->num_units; unit_index++) { - if (block->units[unit_index].entries[0] < 0) { - drop_dead_unit(block, unit_index); - } - block->unit_seen[unit_index] = 1; - } - - /* Free the "seen" flag buffer before returning (since the core doesn't - * touch this field) */ - free(block->unit_seen); - block->unit_seen = NULL; // Just for safety - - return 1; -} - -/*************************************************************************/ - -/** - * rtlopt_drop_dead_branches: Search an RTL block for branch instructions - * which branch to the next instruction in the code stream and replace them - * with NOPs. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on error - */ -int rtlopt_drop_dead_branches(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->insns != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(block->regs != NULL, return 0); - PRECOND(block->label_unitmap != NULL, return 0); - - unsigned int unit_index; - for (unit_index = 0; unit_index < block->num_units; unit_index++) { - RTLUnit * const unit = &block->units[unit_index]; - if (unit->last_insn >= unit->first_insn) { - RTLInsn * const insn = &block->insns[unit->last_insn]; - const RTLOpcode opcode = insn->opcode; - if ((opcode == RTLOP_GOTO - || opcode == RTLOP_GOTO_IF_Z - || opcode == RTLOP_GOTO_IF_NZ - || opcode == RTLOP_GOTO_IF_E - || opcode == RTLOP_GOTO_IF_NE) - && block->label_unitmap[insn->label] == unit->next_unit - ) { -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] %p/%u: Dropping branch to next insn\n", - block, unit->last_insn); -#endif - if (opcode == RTLOP_GOTO_IF_Z || opcode == RTLOP_GOTO_IF_NZ) { - RTLRegister *src1_reg = &block->regs[insn->src1]; - if (src1_reg->death == unit->last_insn) { - maybe_eliminate_folded_register(block, src1_reg, - insn->src1); - } - } else if (opcode == RTLOP_GOTO_IF_E || opcode == RTLOP_GOTO_IF_NE) { - RTLRegister *src1_reg = &block->regs[insn->src1]; - if (src1_reg->death == unit->last_insn) { - maybe_eliminate_folded_register(block, src1_reg, - insn->src1); - } - RTLRegister *src2_reg = &block->regs[insn->src2]; - if (src2_reg->death == unit->last_insn) { - maybe_eliminate_folded_register(block, src2_reg, - insn->src2); - } - } - insn->opcode = RTLOP_NOP; - insn->src_imm = 0; - } - } - } - - return 1; -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * fold_one_register: Attempt to perform constant folding on a register. - * The register must be of type RTLREG_RESULT. - * - * [Parameters] - * block: RTL block - * reg: Register on which to perform constant folding - * [Return value] - * Nonzero if constant folding was performed, zero otherwise - * [Notes] - * This routine calls itself recursively, but it is declared inline - * anyway to optimize the outer loop in rtlopt_fold_constants(). - */ -static inline int fold_one_register(RTLBlock * const block, - RTLRegister * const reg) -{ - PRECOND(block != NULL, return 0); - PRECOND(reg != NULL, return 0); - PRECOND(reg->live, return 0); - PRECOND(reg->source == RTLREG_RESULT, return 0); - - /* Flag the register as not foldable for the moment (to avoid infinite - * recursion in case invalid code creates register dependency loops */ - - reg->source = RTLREG_RESULT_NOFOLD; - - /* See if the operands are constant, folding them if necessary */ - - RTLRegister * const src1 = &block->regs[reg->result.src1]; - RTLRegister * const src2 = &block->regs[reg->result.src2]; - if (src1->source != RTLREG_CONSTANT - && !(src1->source == RTLREG_RESULT - && fold_one_register(block, src1)) - ) { - return 0; // Operand 1 wasn't constant - } - if (!reg->result.is_imm - && reg->result.src2 != 0 // In case it's a 1-operand instruction - && src2->source != RTLREG_CONSTANT - && !(src2->source == RTLREG_RESULT - && fold_one_register(block, src2)) - ) { - return 0; // Operand 2 wasn't constant - } - if (reg->result.opcode == RTLOP_SELECT) { - RTLRegister * const cond = &block->regs[reg->result.cond]; - if (cond->source != RTLREG_CONSTANT - && !(cond->source == RTLREG_RESULT - && fold_one_register(block, cond)) - ) { - return 0; // Condition operand wasn't constant - } - } - - /* All operands are constants, so perform the operation now and convert - * the register to a constant */ - - uintptr_t result = 0; - switch (reg->result.opcode) { - - case RTLOP_MOVE: - result = src1->value; - break; - - case RTLOP_SELECT: - result = - block->regs[reg->result.cond].value ? src1->value : src2->value; - break; - - case RTLOP_ADD: - result = src1->value + (intptr_t)(int32_t)src2->value; - break; - - case RTLOP_SUB: - result = src1->value - (intptr_t)(int32_t)src2->value; - break; - - case RTLOP_MULU: - if (reg->result.second_res) { - result = ((uint64_t)src1->value * (uint64_t)src2->value) >> 32; - } else { - result = src1->value * src2->value; - } - break; - - case RTLOP_MULS: - if (reg->result.second_res) { - result = ((int64_t)(int32_t)src1->value - * (int64_t)(int32_t)src2->value) >> 32; - } else { - result = src1->value * src2->value; - } - break; - - case RTLOP_DIVMODU: - if (reg->result.second_res) { - result = src2->value ? src1->value % src2->value : 0; - } else { - result = src2->value ? src1->value / src2->value : 0; - } - break; - - case RTLOP_DIVMODS: - if (reg->result.second_res) { - result = src2->value ? (int32_t)src1->value % (int32_t)src2->value - : 0; - } else { - result = src2->value ? (int32_t)src1->value / (int32_t)src2->value - : 0; - } - break; - - case RTLOP_AND: - result = src1->value & (intptr_t)(int32_t)src2->value; - break; - - case RTLOP_OR: - result = src1->value | (uintptr_t)(uint32_t)src2->value; - break; - - case RTLOP_XOR: - result = src1->value ^ (uintptr_t)(uint32_t)src2->value; - break; - - case RTLOP_NOT: - result = ~src1->value; - break; - - case RTLOP_SLL: - result = src1->value << src2->value; - break; - - case RTLOP_SRL: - result = (uint32_t)src1->value >> src2->value; - break; - - case RTLOP_SRA: - result = (int32_t)src1->value >> src2->value; - break; - - case RTLOP_ROR: - if ((src2->value & 31) != 0) { - result = (uint32_t)src1->value >> (src2->value & 31) - | (uint32_t)src1->value << (32 - (src2->value & 31)); - } else { - result = (uint32_t)src1->value; - } - break; - - case RTLOP_CLZ: { -#ifdef __GNUC__ - result = __builtin_clz(src1->value); -#else - uint32_t temp = src1->value; - result = 32; - while (temp) { - temp >>= 1; - result--; - } -#endif // __GNUC__ - break; - } - - case RTLOP_CLO: { - uint32_t temp = src1->value; - result = 0; - while ((int32_t)temp < 0) { - temp <<= 1; - result++; - } - break; - } - - case RTLOP_SLTU: - result = ((uint32_t)src1->value < (uint32_t)src2->value) ? 1 : 0; - break; - - case RTLOP_SLTS: - result = ((int32_t)src1->value < (int32_t)src2->value) ? 1 : 0; - break; - - case RTLOP_BSWAPH: - result = ((uint32_t)src1->value & 0xFF00FF00) >> 8 - | ((uint32_t)src1->value & 0x00FF00FF) << 8; - break; - - case RTLOP_BSWAPW: - result = ((uint32_t)src1->value & 0xFF000000) >> 24 - | ((uint32_t)src1->value & 0x00FF0000) >> 8 - | ((uint32_t)src1->value & 0x0000FF00) << 8 - | ((uint32_t)src1->value & 0x000000FF) << 24; - break; - - case RTLOP_HSWAPW: - result = ((uint32_t)src1->value & 0xFFFF0000) >> 16 - | ((uint32_t)src1->value & 0x0000FFFF) << 16; - break; - - case RTLOP_ADDI: - result = src1->value + reg->result.imm; - break; - - case RTLOP_ANDI: - result = src1->value & reg->result.imm; - break; - - case RTLOP_ORI: - result = src1->value | reg->result.imm; - break; - - case RTLOP_XORI: - result = src1->value ^ reg->result.imm; - break; - - case RTLOP_SLLI: - result = src1->value << reg->result.imm; - break; - - case RTLOP_SRLI: - result = (uint32_t)src1->value >> reg->result.imm; - break; - - case RTLOP_SRAI: - result = (int32_t)src1->value >> reg->result.imm; - break; - - case RTLOP_RORI: - if ((reg->result.imm & 31) != 0) { - result = (uint32_t)src1->value >> (reg->result.imm & 31) - | (uint32_t)src1->value << (32 - (reg->result.imm & 31)); - } else { - result = (uint32_t)src1->value; - } - break; - - case RTLOP_SLTUI: - result = ((uint32_t)src1->value < (uint32_t)reg->result.imm) ? 1 : 0; - break; - - case RTLOP_SLTSI: - result = ((int32_t)src1->value < (int32_t)reg->result.imm) ? 1 : 0; - break; - - case RTLOP_BFEXT: - result = ((uint32_t)src1->value >> reg->result.start) - & ((1 << reg->result.count) - 1); - return 1; - - case RTLOP_BFINS: - result = ((uint32_t)src1->value - & ~(((1 << reg->result.count) - 1) << reg->result.start)) - | (((uint32_t)src2->value & ((1 << reg->result.count) - 1)) - << reg->result.start); - return 1; - - /* The remainder will never appear, but list them individually - * rather than using a default case so the compiler will warn us if - * we add a new opcode but don't include it here */ - case RTLOP_NOP: - case RTLOP_MADDU: - case RTLOP_MADDS: - case RTLOP_LOAD_IMM: - case RTLOP_LOAD_ADDR: - case RTLOP_LOAD_PARAM: - case RTLOP_LOAD_BU: - case RTLOP_LOAD_BS: - case RTLOP_LOAD_HU: - case RTLOP_LOAD_HS: - case RTLOP_LOAD_W: - case RTLOP_LOAD_PTR: - case RTLOP_STORE_B: - case RTLOP_STORE_H: - case RTLOP_STORE_W: - case RTLOP_STORE_PTR: - case RTLOP_LABEL: - case RTLOP_GOTO: - case RTLOP_GOTO_IF_Z: - case RTLOP_GOTO_IF_NZ: - case RTLOP_GOTO_IF_E: - case RTLOP_GOTO_IF_NE: - case RTLOP_CALL: - case RTLOP_RETURN: - case RTLOP_RETURN_TO: - DMSG("impossible: opcode %u on RESULT register %u", - reg->result.opcode, (unsigned int)(reg - block->regs)); - return 0; - - } // switch (insn->opcode) - -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] Folded r%u to constant value 0x%lX at insn %u\n", - (unsigned int)(reg - block->regs), (unsigned long)result, - reg->birth); -#endif - - /* Update the instruction that set this register (use LOAD_ADDR in case - * the original value was an address) */ - - block->insns[reg->birth].opcode = RTLOP_LOAD_ADDR; - block->insns[reg->birth].src_addr = result; - - /* See whether the source register(s) are used anywhere else, and - * eliminate them if not */ - - if (src1->death == reg->birth) { - maybe_eliminate_folded_register(block, src1, reg->result.src1); - } - if ((!reg->result.is_imm && reg->result.src2 != 0) - && src2->death == reg->birth - ) { - maybe_eliminate_folded_register(block, src2, reg->result.src2); - } - - /* Constant folding was successful */ - - reg->source = RTLREG_CONSTANT; - reg->value = result; - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * maybe_eliminate_folded_register: See whether the given register is no - * longer used after being eliminated from the instruction indexed by - * reg->death. If so, eliminate the register and change the instruction - * indexed by reg->birth to a NOP; otherwise, update reg->death to point to - * the last instruction that still uses the register. - * - * It is assumed that the register is only assigned once, at the - * instruction indexed by reg->birth. - * - * [Parameters] - * block: RTL block - * reg: Register to attempt to eliminate - * reg_index: Index of register in block->regs[] - * [Return value] - * None - */ -static void maybe_eliminate_folded_register(RTLBlock * const block, - RTLRegister * const reg, - const unsigned int reg_index) -{ - PRECOND(block != NULL, return); - PRECOND(reg != NULL, return); - PRECOND(reg->live, return); - - uint32_t insn_index; - for (insn_index = reg->death-1; insn_index > reg->birth; insn_index--) { - const RTLInsn * const insn = &block->insns[insn_index]; - switch (insn->opcode) { - - case RTLOP_NOP: - case RTLOP_LOAD_IMM: - case RTLOP_LOAD_ADDR: - case RTLOP_LOAD_PARAM: - case RTLOP_LABEL: - case RTLOP_GOTO: - case RTLOP_RETURN: - break; - - case RTLOP_MOVE: - case RTLOP_NOT: - case RTLOP_CLZ: - case RTLOP_CLO: - case RTLOP_BSWAPH: - case RTLOP_BSWAPW: - case RTLOP_HSWAPW: - case RTLOP_ADDI: - case RTLOP_ANDI: - case RTLOP_ORI: - case RTLOP_XORI: - case RTLOP_SLLI: - case RTLOP_SRLI: - case RTLOP_SRAI: - case RTLOP_RORI: - case RTLOP_SLTUI: - case RTLOP_SLTSI: - case RTLOP_BFEXT: - case RTLOP_LOAD_BU: - case RTLOP_LOAD_BS: - case RTLOP_LOAD_HU: - case RTLOP_LOAD_HS: - case RTLOP_LOAD_W: - case RTLOP_LOAD_PTR: - case RTLOP_STORE_B: - case RTLOP_STORE_H: - case RTLOP_STORE_W: - case RTLOP_STORE_PTR: - case RTLOP_GOTO_IF_Z: - case RTLOP_GOTO_IF_NZ: - if (insn->src1 == reg_index) { - still_used: -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] maybe_eliminate_folded_register: r%u" - " still used at insn %u\n", reg_index, insn_index); -#endif - reg->death = insn_index; - return; - } - break; - - case RTLOP_ADD: - case RTLOP_SUB: - case RTLOP_MULU: - case RTLOP_MULS: - case RTLOP_DIVMODU: - case RTLOP_DIVMODS: - case RTLOP_AND: - case RTLOP_OR: - case RTLOP_XOR: - case RTLOP_SLL: - case RTLOP_SRL: - case RTLOP_SRA: - case RTLOP_ROR: - case RTLOP_SLTU: - case RTLOP_SLTS: - case RTLOP_BFINS: - case RTLOP_GOTO_IF_E: - case RTLOP_GOTO_IF_NE: - if (insn->src1 == reg_index || insn->src2 == reg_index) { - goto still_used; - } - break; - - case RTLOP_MADDU: - case RTLOP_MADDS: - if (insn->src1 == reg_index || insn->src2 == reg_index - || insn->dest == reg_index || insn->dest2 == reg_index - ) { - goto still_used; - } - break; - - case RTLOP_SELECT: - if (insn->src1 == reg_index || insn->src2 == reg_index - || insn->cond == reg_index - ) { - goto still_used; - } - break; - - case RTLOP_CALL: - if (insn->src1 == reg_index || insn->src2 == reg_index - || insn->target == reg_index - ) { - goto still_used; - } - break; - - case RTLOP_RETURN_TO: - if (insn->target == reg_index) { - goto still_used; - } - break; - - } // switch (opcode) - } // for (insn_index) - - /* If we got this far, nothing else uses the register, so nuke it */ -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] maybe_eliminate_folded_register: r%u no longer" - " used, eliminating\n", reg_index); -#endif - block->insns[reg->birth].opcode = RTLOP_NOP; - block->insns[reg->birth].src_imm = 0; - reg->live = 0; -} - -/*************************************************************************/ - -/** - * drop_dead_unit: Drop a dead basic unit from an RTL block. Recursive - * helper function for rtlopt_drop_dead_units(). - * - * [Parameters] - * block: RTL block - * unit_index: Index of unit in block->units[] - * [Return value] - * None - */ -static void drop_dead_unit(RTLBlock * const block, - const unsigned int unit_index) -{ - PRECOND(block != NULL, return); - PRECOND(block->units != NULL, return); - PRECOND(block->unit_seen != NULL, return); - PRECOND(unit_index < block->num_units, return); - PRECOND(block->units[unit_index].entries[0] < 0, return); - PRECOND(block->units[unit_index].prev_unit >= 0, return); - - RTLUnit * const unit = &block->units[unit_index]; -#ifdef RTL_TRACE_GENERATE - fprintf(stderr, "[RTL] %p: Dropping dead unit %u", block, unit_index); - if (unit->exits[0] < 0) { - fprintf(stderr, " (no exits)\n"); - } else if (unit->exits[1] < 0) { - fprintf(stderr, " (exits: %d)\n", unit->exits[0]); - } else { - fprintf(stderr, " (exits: %d, %d)\n", unit->exits[0], unit->exits[1]); - } -#endif - - block->units[unit->prev_unit].next_unit = unit->next_unit; - if (unit->next_unit >= 0) { - block->units[unit->next_unit].prev_unit = unit->prev_unit; - } - if (unit->prev_call_unit >= 0) { - block->units[unit->prev_call_unit].next_call_unit = - unit->next_call_unit; - } - if (unit->next_call_unit >= 0) { - block->units[unit->next_call_unit].prev_call_unit = - unit->prev_call_unit; - } - - while (unit->exits[0] >= 0) { - const unsigned int to_index = unit->exits[0]; - rtlunit_remove_edge(block, unit_index, 0); - if (block->unit_seen[to_index]) { - /* We already saw this unit and (presumably) skipped it because - * it wasn't dead. Check again now that we've removed this - * edge, and if it's now dead, recursively drop it. There's no - * danger of infinite recursion since any dead block has no - * edges entering into it by definition. */ - if (block->units[to_index].entries[0] < 0) { - drop_dead_unit(block, to_index); - } - } - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/rtlunit.c b/yabause/src/psp/rtlunit.c deleted file mode 100644 index 2eae2fc7be..0000000000 --- a/yabause/src/psp/rtlunit.c +++ /dev/null @@ -1,287 +0,0 @@ -/* src/psp/rtlunit.c: Basic unit processing for RTL - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ - -/* - * This source file contains the logic used to divide a stream of RTL - * instructions into basic units (so-called "basic blocks"--we use the - * term "block" to refer to a sequence of source instructions translated - * into RTL as a group, so the term "units" is used here to differentiate). - * Each basic unit has exactly one entry point and one exit point, though - * there may be multiple paths into or out of the unit. As such, the unit - * can be optimized and translated to native code without the necessity of - * tracking every possible path for reaching each instruction. - */ - -/*************************************************************************/ -/*************************** Required headers ****************************/ -/*************************************************************************/ - -#include "common.h" - -#include "rtl.h" -#include "rtl-internal.h" - -/*************************************************************************/ -/********************** External interface routines **********************/ -/*************************************************************************/ - -/** - * rtlunit_add: Add a new, empty basic unit to the given block - * at the end of the block->units[] array. - * - * [Parameters] - * block: RTL block - * [Return value] - * Nonzero on success, zero on failure - */ -int rtlunit_add(RTLBlock *block) -{ - PRECOND(block != NULL, return 0); - - if (UNLIKELY(block->num_units >= block->units_size)) { - unsigned int new_units_size = block->num_units + UNITS_EXPAND_SIZE; - RTLUnit *new_units = realloc(block->units, - sizeof(*block->units) * new_units_size); - if (UNLIKELY(!new_units)) { - DMSG("No memory to expand block %p to %d units", block, - new_units_size); - return 0; - } - block->units = new_units; - block->units_size = new_units_size; - } - - const unsigned int index = block->num_units++; - if (index > 0) { - block->units[index-1].next_unit = index; - } - block->units[index].first_insn = 0; - block->units[index].last_insn = -1; - block->units[index].next_unit = -1; - block->units[index].prev_unit = index-1; - unsigned int i; - for (i = 0; i < lenof(block->units[index].entries); i++) { - block->units[index].entries[i] = -1; - } - for (i = 0; i < lenof(block->units[index].exits); i++) { - block->units[index].exits[i] = -1; - } - block->units[index].next_call_unit = -1; - block->units[index].prev_call_unit = -1; - - return 1; -} - -/*************************************************************************/ - -/** - * rtlunit_add_edge: Add a new edge between two basic units. - * - * [Parameters] - * block: RTL block - * from_index: Index of dominating basic unit (in block->units[]) - * to_index: Index of postdominating basic unit (in block->units[]) - * [Return value] - * Nonzero on success, zero on failure - */ -int rtlunit_add_edge(RTLBlock *block, unsigned int from_index, - unsigned int to_index) -{ - PRECOND(block != NULL, return 0); - PRECOND(block->units != NULL, return 0); - PRECOND(from_index < block->num_units, return 0); - PRECOND(to_index < block->num_units, return 0); - - unsigned int i; - - /* Find an empty exit slot; also check whether this edge already exists, - * and return successfully (without adding a duplicate edge) if so. - * A unit can never have more than two exits, so bail if we try to add - * a third. */ - for (i = 0; i < lenof(block->units[from_index].exits); i++) { - if (block->units[from_index].exits[i] < 0) { - break; - } else if (block->units[from_index].exits[i] == to_index) { - return 1; - } - } - if (UNLIKELY(i >= lenof(block->units[from_index].exits))) { - DMSG("%p: Too many exits from unit %u", block, from_index); - } - block->units[from_index].exits[i] = to_index; - - /* If we overflow the entry list, add a dummy unit to take some of the - * entries out */ - for (i = 0; i < lenof(block->units[to_index].entries); i++) { - if (block->units[to_index].entries[i] < 0) { - break; - } - } - if (UNLIKELY(i >= lenof(block->units[to_index].entries))) { - /* No room in the entry list, so we need to create a dummy unit */ - if (UNLIKELY(!rtlunit_add(block))) { - DMSG("%p: Failed to add dummy unit", block); - return 0; - } - const unsigned int dummy_unit = block->num_units - 1; - /* Move all the current edges over to the dummy unit */ - for (i = 0; i < lenof(block->units[to_index].entries); i++) { - const unsigned int other_unit = block->units[to_index].entries[i]; - unsigned int j; - for (j = 0; j < lenof(block->units[other_unit].exits); j++) { - if (block->units[other_unit].exits[j] == to_index) { - break; - } - } - if (UNLIKELY(j >= lenof(block->units[other_unit].exits))) { - DMSG("%p: Internal compiler error: edge to unit %u missing" - " from unit %u", block, to_index, other_unit); - return 0; - } - block->units[other_unit].exits[j] = dummy_unit; - block->units[dummy_unit].entries[i] = other_unit; - } - /* Link to the original unit */ - block->units[dummy_unit].exits[0] = to_index; - block->units[dummy_unit].exits[1] = -1; - block->units[to_index].entries[0] = dummy_unit; - /* The new entry will go into the second slot; clear out all - * other edges */ - for (i = lenof(block->units[to_index].entries) - 1; i > 1; i--) { - block->units[to_index].entries[i] = -1; - } - } - block->units[to_index].entries[i] = from_index; - - return 1; -} - -/*************************************************************************/ - -/** - * rtlunit_remove_edge: Remove an edge between two basic units. - * - * [Parameters] - * block: RTL block - * from_index: Index of dominating basic unit (in block->units[]) - * exit_index: Index of exit edge to remove (in units[from_index].exits[]) - * [Return value] - * None - */ -void rtlunit_remove_edge(RTLBlock *block, const unsigned int from_index, - unsigned int exit_index) -{ - PRECOND(block != NULL, return); - PRECOND(block->units != NULL, return); - PRECOND(from_index < block->num_units, return); - PRECOND(exit_index < lenof(block->units[from_index].exits), return); - PRECOND(block->units[from_index].exits[exit_index] >= 0, return); - - RTLUnit * const from_unit = &block->units[from_index]; - const unsigned int to_index = from_unit->exits[exit_index]; - RTLUnit * const to_unit = &block->units[to_index]; - unsigned int entry_index; - - for (; exit_index < lenof(from_unit->exits) - 1; exit_index++) { - from_unit->exits[exit_index] = from_unit->exits[exit_index + 1]; - } - from_unit->exits[lenof(from_unit->exits) - 1] = -1; - - for (entry_index = 0; entry_index < lenof(to_unit->entries); - entry_index++ - ) { - if (to_unit->entries[entry_index] == from_index) { - break; - } - } - if (UNLIKELY(entry_index >= lenof(to_unit->entries))) { - DMSG("BUG: edge %u->%u missing from %u.entries!", - from_index, to_index, to_index); - return; - } - - for (; entry_index < lenof(to_unit->entries) - 1; entry_index++) { - to_unit->entries[entry_index] = to_unit->entries[entry_index + 1]; - } - to_unit->entries[lenof(to_unit->entries) - 1] = -1; -} - -/*************************************************************************/ - -/** - * rtlunit_dump_all: Dump a list of all basic units in the block to - * stderr. Intended for debugging. - * - * [Parameters] - * block: RTL block - * tag: Tag to prepend to all lines, or NULL for none - * [Return value] - * None - */ -void rtlunit_dump_all(const RTLBlock * const block, const char * const tag) -{ - PRECOND(block != NULL, return); - PRECOND(block->units != NULL, return); - - unsigned int i; - for (i = 0; i < block->num_units; i++) { - const RTLUnit * const unit = &block->units[i]; - fprintf(stderr, "[RTL] %s%s%sUnit %4u: ", - tag ? "[" : "", tag ? tag : "", tag ? "] " : "", i); - if (unit->entries[0] < 0) { - fprintf(stderr, ""); - } else { - unsigned int j; - for (j = 0; j < lenof(unit->entries) && unit->entries[j]>=0; j++) { - fprintf(stderr, "%s%u", j==0 ? "" : ",", unit->entries[j]); - } - } - if (unit->first_insn <= unit->last_insn) { - fprintf(stderr, " --> [%d,%d] --> ", - unit->first_insn, unit->last_insn); - } else { - fprintf(stderr, " --> [empty] --> "); - } - if (unit->exits[0] < 0) { - fprintf(stderr, ""); - } else { - unsigned int j; - for (j = 0; j < lenof(unit->exits) && unit->exits[j] >= 0; j++) { - fprintf(stderr, "%s%u", j==0 ? "" : ",", unit->exits[j]); - } - } - fprintf(stderr, "\n"); - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/satopt-sh2.c b/yabause/src/psp/satopt-sh2.c deleted file mode 100644 index 5d123adb20..0000000000 --- a/yabause/src/psp/satopt-sh2.c +++ /dev/null @@ -1,4019 +0,0 @@ -/* src/psp/satopt-sh2.c: Saturn-specific SH-2 optimization routines - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ -/*************************** Required headers ****************************/ -/*************************************************************************/ - -#include "common.h" - -#include "../core.h" -#include "../cs2.h" -#include "../memory.h" -#include "../scsp.h" -#include "../scu.h" -#include "../sh2core.h" -#include "../vdp1.h" -#include "../vdp2.h" -#include "../yabause.h" - -#include "sh2.h" -#include "sh2-internal.h" - -#include "misc.h" -#include "satopt-sh2.h" - -#ifdef JIT_DEBUG_TRACE -# include "../sh2d.h" -#endif - -/*************************************************************************/ - -/* Shorthand macros for memory access, both saving us from having to write - * out 0xFFFFF all over the place and allowing optimized memory access - * using constant offsets where possible (we assume small constant offsets - * don't fall outside the relevant memory region). Note that offsetted - * byte accesses to 16-bit-organized memory generally will not be optimized - * on little-endian systems, because the XOR has to be applied after adding - * the offset to the base; if the base is known to be 16-bit aligned, it - * may be faster to load a 16-bit word and mask or shift as appropriate. */ - -#define HRAM_PTR(base) ((uint8_t *)&HighWram[(base) & 0xFFFFF]) -#define HRAM_LOADB(base,offset) \ - T2ReadByte(HighWram, ((base) + (offset)) & 0xFFFFF) -#define HRAM_LOADW(base,offset) \ - T2ReadWord(HighWram, ((base) & 0xFFFFF) + (offset)) -#define HRAM_LOADL(base,offset) \ - T2ReadLong(HighWram, ((base) & 0xFFFFF) + (offset)) -#define HRAM_STOREB(base,offset,data) \ - T2WriteByte(HighWram, ((base) + (offset)) & 0xFFFFF, (data)) -#define HRAM_STOREW(base,offset,data) \ - T2WriteWord(HighWram, ((base) & 0xFFFFF) + (offset), (data)) -#define HRAM_STOREL(base,offset,data) \ - T2WriteLong(HighWram, ((base) & 0xFFFFF) + (offset), (data)) - -#define LRAM_PTR(base) ((uint8_t *)&LowWram[(base) & 0xFFFFF]) -#define LRAM_LOADB(base,offset) \ - T2ReadByte(LowWram, ((base) + (offset)) & 0xFFFFF) -#define LRAM_LOADW(base,offset) \ - T2ReadWord(LowWram, ((base) & 0xFFFFF) + (offset)) -#define LRAM_LOADL(base,offset) \ - T2ReadLong(LowWram, ((base) & 0xFFFFF) + (offset)) -#define LRAM_STOREB(base,offset,data) \ - T2WriteByte(LowWram, ((base) + (offset)) & 0xFFFFF, (data)) -#define LRAM_STOREW(base,offset,data) \ - T2WriteWord(LowWram, ((base) & 0xFFFFF) + (offset), (data)) -#define LRAM_STOREL(base,offset,data) \ - T2WriteLong(LowWram, ((base) & 0xFFFFF) + (offset), (data)) - -#define VDP1_PTR(base) ((uint8_t *)&Vdp1Ram[(base) & 0x7FFFF]) -#define VDP1_LOADB(base,offset) \ - T1ReadByte(Vdp1Ram, ((base) & 0x7FFFF) + (offset)) -#define VDP1_LOADW(base,offset) \ - T1ReadWord(Vdp1Ram, ((base) & 0x7FFFF) + (offset)) -#define VDP1_LOADL(base,offset) \ - T1ReadLong(Vdp1Ram, ((base) & 0x7FFFF) + (offset)) -#define VDP1_STOREB(base,offset,data) \ - T1WriteByte(Vdp1Ram, ((base) & 0x7FFFF) + (offset), (data)) -#define VDP1_STOREW(base,offset,data) \ - T1WriteWord(Vdp1Ram, ((base) & 0x7FFFF) + (offset), (data)) -#define VDP1_STOREL(base,offset,data) \ - T1WriteLong(Vdp1Ram, ((base) & 0x7FFFF) + (offset), (data)) - -#define VDP2_PTR(base) ((uint8_t *)&Vdp2Ram[(base) & 0x7FFFF]) -#define VDP2_LOADB(base,offset) \ - T1ReadByte(Vdp2Ram, ((base) & 0x7FFFF) + (offset)) -#define VDP2_LOADW(base,offset) \ - T1ReadWord(Vdp2Ram, ((base) & 0x7FFFF) + (offset)) -#define VDP2_LOADL(base,offset) \ - T1ReadLong(Vdp2Ram, ((base) & 0x7FFFF) + (offset)) -#define VDP2_STOREB(base,offset,data) \ - T1WriteByte(Vdp2Ram, ((base) & 0x7FFFF) + (offset), (data)) -#define VDP2_STOREW(base,offset,data) \ - T1WriteWord(Vdp2Ram, ((base) & 0x7FFFF) + (offset), (data)) -#define VDP2_STOREL(base,offset,data) \ - T1WriteLong(Vdp2Ram, ((base) & 0x7FFFF) + (offset), (data)) - -/* Use these macros instead of [BW]SWAP{16,32} when loading from or - * storing to work RAM or VDP memory, to avoid breaking things on - * big-endian systems. RAM_VDP_SWAPL is for copying longwords directly - * between work RAM and VDP memory, and is one operation faster on - * little-endian machines than VDP_SWAPL(RAM_SWAPL(x)). */ - -#ifdef WORDS_BIGENDIAN -# define RAM_SWAPL(x) (x) -# define VDP_SWAPW(x) (x) -# define VDP_SWAPL(x) (x) -# define RAM_VDP_SWAPL(x) (x) -#else -# define RAM_SWAPL(x) WSWAP32(x) -# define VDP_SWAPW(x) BSWAP16(x) -# define VDP_SWAPL(x) BSWAP32(x) -# define RAM_VDP_SWAPL(x) BSWAP16(x) // BSWAP32(WSWAP32(x)) == BSWAP16(x) -#endif - -/*************************************************************************/ -/********************** Optimization routine table ***********************/ -/*************************************************************************/ - -#ifdef ENABLE_JIT // Through end of file - -/*************************************************************************/ - -/* List of detection and translation routines for special-case blocks */ - -#ifdef PSP -# define ALIGN_OPTIMIZER __attribute__((aligned(64))) -#else -# define ALIGN_OPTIMIZER /*nothing*/ -#endif - -#define DECLARE_OPTIMIZER(name) \ - ALIGN_OPTIMIZER static FASTCALL void name(SH2State *state) - -#define DECLARE_OPTIMIZER_WITH_DETECT(name) \ - static int name##_detect(SH2State *state, uint32_t address, \ - const uint16_t *fetch); \ - DECLARE_OPTIMIZER(name) - -/*----------------------------------*/ - -DECLARE_OPTIMIZER_WITH_DETECT(BIOS_000025AC); -DECLARE_OPTIMIZER_WITH_DETECT(BIOS_00002EFA); -DECLARE_OPTIMIZER (BIOS_00003BC6); -DECLARE_OPTIMIZER (BIOS_06001670); -DECLARE_OPTIMIZER_WITH_DETECT(BIOS_06010D22); -DECLARE_OPTIMIZER (BIOS_060115A4); -DECLARE_OPTIMIZER_WITH_DETECT(BIOS_060115B6); -DECLARE_OPTIMIZER_WITH_DETECT(BIOS_060115D4); -DECLARE_OPTIMIZER (BIOS_0602E364); -DECLARE_OPTIMIZER_WITH_DETECT(BIOS_0602E630); - -/*----------------------------------*/ - -DECLARE_OPTIMIZER_WITH_DETECT(Azel_0600614C); -DECLARE_OPTIMIZER (Azel_060061F0); -DECLARE_OPTIMIZER (Azel_0600C4DC); -DECLARE_OPTIMIZER (Azel_0600C59C); -DECLARE_OPTIMIZER_WITH_DETECT(Azel_0600C5B4); -DECLARE_OPTIMIZER (Azel_0600C5F8); -DECLARE_OPTIMIZER (Azel_0600C690); -DECLARE_OPTIMIZER_WITH_DETECT(Azel_06010F24); -DECLARE_OPTIMIZER (Azel_06014274); -DECLARE_OPTIMIZER (Azel_0601E330); -DECLARE_OPTIMIZER (Azel_0601E910); -DECLARE_OPTIMIZER (Azel_0601E95A); -DECLARE_OPTIMIZER (Azel_0601EC20); -DECLARE_OPTIMIZER (Azel_0601EC3C); -DECLARE_OPTIMIZER (Azel_0601EE60); -DECLARE_OPTIMIZER (Azel_0601EEE8); -DECLARE_OPTIMIZER (Azel_0601F240); -DECLARE_OPTIMIZER (Azel_0601F24C); -DECLARE_OPTIMIZER (Azel_0601F2D6); -DECLARE_OPTIMIZER (Azel_0601F2F2); -DECLARE_OPTIMIZER (Azel_0601F30E); -DECLARE_OPTIMIZER (Azel_0601F3F4); -DECLARE_OPTIMIZER (Azel_0601FB70); -DECLARE_OPTIMIZER (Azel_06022E18); -DECLARE_OPTIMIZER (Azel_06035530); -DECLARE_OPTIMIZER (Azel_06035552); -DECLARE_OPTIMIZER (Azel_0603556C); -DECLARE_OPTIMIZER (Azel_06035A8C); -DECLARE_OPTIMIZER (Azel_06035A9C); -DECLARE_OPTIMIZER (Azel_06035AA0); -DECLARE_OPTIMIZER (Azel_06035B14); -DECLARE_OPTIMIZER (Azel_06035C18); -DECLARE_OPTIMIZER (Azel_06035C3C); -DECLARE_OPTIMIZER (Azel_06035C60); -DECLARE_OPTIMIZER (Azel_06035C84); -DECLARE_OPTIMIZER (Azel_06035C90); -DECLARE_OPTIMIZER (Azel_06035C96); -DECLARE_OPTIMIZER (Azel_06035D24); -DECLARE_OPTIMIZER (Azel_06035D30); -DECLARE_OPTIMIZER (Azel_06035D36); -DECLARE_OPTIMIZER (Azel_06035DD4); -DECLARE_OPTIMIZER (Azel_06035DE0); -DECLARE_OPTIMIZER (Azel_06035DE6); -DECLARE_OPTIMIZER (Azel_06035E70); -DECLARE_OPTIMIZER (Azel_06035EA0); -DECLARE_OPTIMIZER (Azel_06035ED0); -DECLARE_OPTIMIZER (Azel_06035F00); -DECLARE_OPTIMIZER (Azel_06035F04); -DECLARE_OPTIMIZER (Azel_060360F0); -DECLARE_OPTIMIZER_WITH_DETECT(Azel_0603A22C); -DECLARE_OPTIMIZER (Azel_0603A242); -DECLARE_OPTIMIZER (Azel_0603ABE0); -DECLARE_OPTIMIZER (Azel_0603DD6E); - -/*----------------------------------*/ - -static const struct { - - /* Start address applicable to this translation. */ - uint32_t address; - - /* Routine that implements the SH-2 code. If NULL, no optimized - * translation is generated; instead, the hints specified in the - * .hint_* fields are applied to the current block. */ - FASTCALL void (*execute)(SH2State *state); - - /* Routine to detect whether to use this translation; returns the - * number of 16-bit words processed (nonzero) to use it, else zero. - * If NULL, the checksum is checked instead. */ - int (*detect)(SH2State *state, uint32_t address, const uint16_t *fetch); - - /* Checksum and block length (in instructions) if detect == NULL. */ - uint32_t sum; - unsigned int length; - - /* Nonzero if this function is foldable (i.e. does not modify any - * registers other than R0-R7, MACH/MACL, and PC). If not set, the - * function is never folded even if it is detected to be a candidate - * for folding. */ - uint8_t foldable; - - /* Bitmask indicating which general purpose registers should be hinted - * as having a constant value at block start. */ - uint16_t hint_constant_reg; - - /* Bitmask indicating which general purpose registers should be hinted - * as containing a data pointer at block start. */ - uint16_t hint_data_pointer_reg; - - /* Bitmask indicating which of the first 32 instructions in the block - * should be hinted as loading a data pointer. */ - uint32_t hint_data_pointer_load; - -} hand_tuned_table[] = { - - /******** BIOS startup animation ********/ - - {0x00001CFC, BIOS_000025AC, BIOS_000025AC_detect}, // 1.00 JP - {0x000025AC, BIOS_000025AC, BIOS_000025AC_detect}, // 1.01 JP / UE - {0x00002658, BIOS_00002EFA, BIOS_00002EFA_detect}, // 1.00 JP - {0x00002EFA, BIOS_00002EFA, BIOS_00002EFA_detect}, // 1.01 JP / UE - {0x00002D44, BIOS_00003BC6, .sum = 0x1A6ECE, .length = 70}, // 1.00 JP - {0x00003BC6, BIOS_00003BC6, .sum = 0x1A40C9, .length = 71}, // 1.01 JP / UE - {0x06001664, BIOS_06001670, .sum = 0x04A2D6, .length = 13}, // 1.00 JP - {0x06001670, BIOS_06001670, .sum = 0x04A2D6, .length = 13}, // 1.01 JP - {0x06001674, BIOS_06001670, .sum = 0x04A2D6, .length = 13}, // UE - {0x06010D22, BIOS_06010D22, BIOS_06010D22_detect}, // JP - {0x06010D36, BIOS_06010D22, BIOS_06010D22_detect}, // UE - {0x060115C0, BIOS_060115A4, .sum = 0x032D22, .length = 9}, // 1.00 JP - {0x060115A4, BIOS_060115A4, .sum = 0x032D22, .length = 9}, // 1.01 JP - {0x06011654, BIOS_060115A4, .sum = 0x032D22, .length = 9}, // UE - {0x060115D2, BIOS_060115B6, BIOS_060115B6_detect}, // 1.00 JP - {0x060115B6, BIOS_060115B6, BIOS_060115B6_detect}, // 1.01 JP - {0x06011666, BIOS_060115B6, BIOS_060115B6_detect}, // UE - {0x060115F0, BIOS_060115D4, BIOS_060115D4_detect}, // 1.00 JP - {0x060115D4, BIOS_060115D4, BIOS_060115D4_detect}, // 1.01 JP - {0x06011684, BIOS_060115D4, BIOS_060115D4_detect}, // UE - {0x0602DA80, NULL, .sum = 0x0A6FD6, .length = 31, // JP - .hint_data_pointer_load = 1<<20}, - {0x06039A80, NULL, .sum = 0x0A6FD6, .length = 31, // UE - .hint_data_pointer_load = 1<<20}, - {0x0602DABE, NULL, .sum = 0x016AF5, .length = 3, // JP - .hint_data_pointer_reg = 1<<12}, - {0x06039ABE, NULL, .sum = 0x016AF5, .length = 3, // UE - .hint_data_pointer_reg = 1<<12}, - {0x0602DAC4, NULL, .sum = 0x016AF5, .length = 3, // JP - .hint_data_pointer_reg = 1<<12}, - {0x06039AC4, NULL, .sum = 0x016AF5, .length = 3, // UE - .hint_data_pointer_reg = 1<<12}, - {0x0602DACA, NULL, .sum = 0x016AF6, .length = 3, // JP - .hint_data_pointer_reg = 1<<12}, - {0x06039ACA, NULL, .sum = 0x016AF6, .length = 3, // UE - .hint_data_pointer_reg = 1<<12}, - {0x0602DF10, NULL, .sum = 0x04634B, .length = 13, // 1.00 JP - .hint_data_pointer_load = 1<<2}, - {0x0602DF30, NULL, .sum = 0x04634B, .length = 13, // 1.01 JP - .hint_data_pointer_load = 1<<2}, - {0x06039F30, NULL, .sum = 0x04634B, .length = 13, // UE - .hint_data_pointer_load = 1<<2}, - {0x0602E364, BIOS_0602E364, .sum = 0x074A3C, .length = 20, // JP - .foldable = 1}, - {0x0603A364, BIOS_0602E364, .sum = 0x074A3C, .length = 20, // UE - .foldable = 1}, - {0x0602E3B0, NULL, .sum = 0x02AAF2, .length = 7, // JP - .hint_data_pointer_load = 1<<6}, - {0x0603A3B0, NULL, .sum = 0x02AAF2, .length = 7, // UE - .hint_data_pointer_load = 1<<6}, - {0x0602E410, NULL, .sum = 0x0298A3, .length = 5, // JP - .hint_data_pointer_load = 1<<4}, - {0x0603A410, NULL, .sum = 0x0298A3, .length = 5, // UE - .hint_data_pointer_load = 1<<4}, - {0x0602E4B8, NULL, .sum = 0x02984F, .length = 5, // JP - .hint_data_pointer_load = 1<<4}, - {0x0603A4B8, NULL, .sum = 0x02984F, .length = 5, // UE - .hint_data_pointer_load = 1<<4}, - {0x0602E560, NULL, .sum = 0x0297FB, .length = 5, // JP - .hint_data_pointer_load = 1<<4}, - {0x0603A560, NULL, .sum = 0x0297FB, .length = 5, // UE - .hint_data_pointer_load = 1<<4}, - {0x0602E38C, NULL, .sum = 0x04E94B, .length = 18, // JP - .hint_data_pointer_load = 1<<0 | 1<<7}, - {0x0603A38C, NULL, .sum = 0x07294B, .length = 18, // UE - .hint_data_pointer_load = 1<<0 | 1<<7}, - {0x0602E630, BIOS_0602E630, BIOS_0602E630_detect}, // JP - {0x0603A630, BIOS_0602E630, BIOS_0602E630_detect}, // UE - - /******** Azel: Panzer Dragoon RPG (JP) ********/ - - {0x0600614C, Azel_0600614C, Azel_0600614C_detect}, - {0x060061F0, Azel_060061F0, .sum = 0x2FB438, .length = 167, .foldable = 1}, - {0x0600C4DC, Azel_0600C4DC, .sum = 0x155D7C, .length = 64, .foldable = 1}, - {0x0600C59C, Azel_0600C59C, .sum = 0x0C1C5C, .length = 30}, - {0x0600C5B4, Azel_0600C5B4, Azel_0600C5B4_detect}, - {0x0600C5F8, Azel_0600C5F8, .sum = 0x085791, .length = 22, .foldable = 1}, - {0x0600C690, Azel_0600C690, .sum = 0x05E193, .length = 15, .foldable = 1}, - {0x06010F24, Azel_06010F24, Azel_06010F24_detect}, - {0x06010F52, Azel_06010F24, Azel_06010F24_detect}, - {0x06014274, Azel_06014274, .sum = 0x23F1EA, .length = 140, .foldable = 1}, - {0x0601E330, Azel_0601E330, .sum = 0x1F9402, .length = 68}, - {0x0601E910, Azel_0601E910, .sum = 0x0EDD5D, .length = 37}, - {0x0601E95A, Azel_0601E95A, .sum = 0x0EDD2D, .length = 37}, - {0x0601EC20, Azel_0601EC20, .sum = 0x05F967, .length = 14}, - {0x0601EC3C, Azel_0601EC3C, .sum = 0x05F97D, .length = 14}, - {0x0601EE60, Azel_0601EE60, .sum = 0x0958CD, .length = 39}, // MOV R0,R1 - {0x0601EE60, Azel_0601EE60, .sum = 0x0998AD, .length = 39}, // BRA 601F02C - {0x0601EEAE, NULL, .sum = 0x05CD03, .length = 17, - .hint_data_pointer_load = 1<<3}, - {0x0601EED6, NULL, .sum = 0x01C56B, .length = 7, - .hint_data_pointer_reg = 1<<0 | 1<<1}, - {0x0601EEE8, Azel_0601EEE8, .sum = 0x075BB7, .length = 20, .foldable = 1}, - {0x0601F120, NULL, .sum = 0x0988A3, .length = 24, - .hint_data_pointer_load = 1<<17}, - {0x0601F140, NULL, .sum = 0x02D776, .length = 8, - .hint_data_pointer_load = 1<<1}, - {0x0601F150, NULL, .sum = 0x034F6E, .length = 7, - .hint_data_pointer_load = 1<<0 | 1<<1 | 1<<2}, - {0x0601F15E, NULL, .sum = 0x034F70, .length = 7, - .hint_data_pointer_load = 1<<0 | 1<<1 | 1<<2}, - {0x0601F16C, NULL, .sum = 0x029E99, .length = 7, - .hint_data_pointer_load = 1<<0 | 1<<1 | 1<<2}, - {0x0601F190, NULL, .sum = 0x01C56B, .length = 7, - .hint_data_pointer_reg = 1<<0 | 1<<1}, - {0x0601F240, Azel_0601F240, .sum = 0x13322C, .length = 75}, - {0x0601F24C, Azel_0601F24C, .sum = 0x11E92D, .length = 69}, - {0x0601F2D6, Azel_0601F2D6, .sum = 0x05F6D3, .length = 14}, - {0x0601F2F2, Azel_0601F2F2, .sum = 0x05F6E9, .length = 14}, - {0x0601F30E, Azel_0601F30E, .sum = 0x250327, .length = 115}, - {0x0601F3F4, Azel_0601F3F4, .sum = 0x1A4DA5, .length = 84}, - {0x0601FB70, Azel_0601FB70, .sum = 0x095941, .length = 39}, // MOV R0,R1 - {0x0601FB70, Azel_0601FB70, .sum = 0x09995B, .length = 39}, // BRA 601FDB0 - {0x0601FBBE, NULL, .sum = 0x049C2B, .length = 14, - .hint_data_pointer_load = 1<<0}, - {0x0601FC3A, NULL, .sum = 0x060C32, .length = 18, - .hint_data_pointer_reg = 1<<4}, - {0x0601FC6C, Azel_0601EEE8, .sum = 0x075BB7, .length = 20, .foldable = 1}, - {0x0601FDB8, NULL, .sum = 0x091C0C, .length = 55, - .hint_data_pointer_reg = 1<<1}, - {0x0601FEA4, NULL, .sum = 0x084DF0, .length = 20, - .hint_data_pointer_load = 1<<17}, - {0x0601FEC4, NULL, .sum = 0x01822F, .length = 4, - .hint_data_pointer_load = 1<<1}, - {0x0601FECC, NULL, .sum = 0x034F73, .length = 7, - .hint_data_pointer_load = 1<<0 | 1<<1 | 1<<2}, - {0x0601FEDA, NULL, .sum = 0x034F75, .length = 7, - .hint_data_pointer_load = 1<<0 | 1<<1 | 1<<2}, - {0x0601FEE8, NULL, .sum = 0x029E9A, .length = 7, - .hint_data_pointer_load = 1<<0 | 1<<1 | 1<<2}, - {0x06021FA2, NULL, .sum = 0x2A12AF, .length = 136, - .hint_constant_reg = 1<<13}, - {0x06022E18, Azel_06022E18, .sum = 0x09ABCB, .length = 33, .foldable = 1}, - {0x06028EE8, NULL, .sum = 0x1F09D1, .length = 103, - .hint_constant_reg = 1<<10}, - {0x0602F834, NULL, .sum = 0x0676B0, .length = 16, - .hint_data_pointer_load = 1<<11}, - {0x06035530, Azel_06035530, .sum = 0x05ABFA, .length = 17, .foldable = 1}, - {0x06035552, Azel_06035552, .sum = 0x0358EB, .length = 13, .foldable = 1}, - {0x0603556C, Azel_0603556C, .sum = 0x0332E9, .length = 11, .foldable = 1}, - {0x06035A8C, Azel_06035A8C, .sum = 0x0A1ECF, .length = 36, .foldable = 1}, - {0x06035A9C, Azel_06035A9C, .sum = 0x065B51, .length = 28, .foldable = 1}, - {0x06035AA0, Azel_06035AA0, .sum = 0x052642, .length = 26, .foldable = 1}, - {0x06035B14, Azel_06035B14, .sum = 0x05CBE1, .length = 37, .foldable = 1}, - {0x06035C18, Azel_06035C18, .sum = 0x085E83, .length = 18, .foldable = 1}, - {0x06035C3C, Azel_06035C3C, .sum = 0x08595C, .length = 18, .foldable = 1}, - {0x06035C60, Azel_06035C60, .sum = 0x085DB6, .length = 18, .foldable = 1}, - {0x06035C84, Azel_06035C84, .sum = 0x0F24AE, .length = 80, .foldable = 1}, - {0x06035C90, Azel_06035C90, .sum = 0x0C95AD, .length = 74, .foldable = 1}, - {0x06035C96, Azel_06035C96, .sum = 0x0B1711, .length = 71, .foldable = 1}, - {0x06035D24, Azel_06035D24, .sum = 0x12CFBE, .length = 88, .foldable = 1}, - {0x06035D30, Azel_06035D30, .sum = 0x1040BD, .length = 82, .foldable = 1}, - {0x06035D36, Azel_06035D36, .sum = 0x0EC21D, .length = 79, .foldable = 1}, - {0x06035DD4, Azel_06035DD4, .sum = 0x0EAFA6, .length = 78, .foldable = 1}, - {0x06035DE0, Azel_06035DE0, .sum = 0x0C20A5, .length = 72, .foldable = 1}, - {0x06035DE6, Azel_06035DE6, .sum = 0x0AA20A, .length = 69, .foldable = 1}, - {0x06035E70, Azel_06035E70, .sum = 0x042E91, .length = 24, .foldable = 1}, - {0x06035EA0, Azel_06035EA0, .sum = 0x042E97, .length = 24, .foldable = 1}, - {0x06035ED0, Azel_06035ED0, .sum = 0x042E9D, .length = 24, .foldable = 1}, - {0x06035F00, Azel_06035F00, .sum = 0x04AC41, .length = 35, .foldable = 1}, - {0x06035F04, Azel_06035F04, .sum = 0x036FCE, .length = 33, .foldable = 1}, - {0x060360F0, Azel_060360F0, .sum = 0x00D021, .length = 4, .foldable = 1}, - {0x0603A22C, Azel_0603A22C, Azel_0603A22C_detect}, - {0x0603A242, Azel_0603A242, .sum = 0x11703E, .length = 49}, - {0x0603ABE0, Azel_0603ABE0, .sum = 0x0BABA4, .length = 35}, - {0x0603DD6E, Azel_0603DD6E, .sum = 0x0BB96E, .length = 31}, - {0x0605444C, NULL, .sum = 0x102906, .length = 56, - .hint_constant_reg = 1<<12}, - {0x06057450, NULL, .sum = 0x0D4F8B, .length = 37, - .hint_constant_reg = 1<<12}, - {0x06058910, NULL, .sum = 0x0F2F81, .length = 52, - .hint_constant_reg = 1<<12}, - {0x06059068, NULL, .sum = 0x42DE2F, .length = 196, - .hint_constant_reg = 1<<11}, - {0x0605906E, NULL, .sum = 0x40F2FD, .length = 193, - .hint_constant_reg = 1<<11}, - {0x060693AE, NULL, .sum = 0x452D32, .length = 237, - .hint_constant_reg = 1<<14}, - {0x0606B7E4, NULL, .sum = 0x5AFDCE, .length = 292, - .hint_constant_reg = 1<<10}, - {0x0606B898, NULL, .sum = 0x2FFF9D, .length = 155, - .hint_constant_reg = 1<<10 | 1<<12}, - {0x06080280, NULL, .sum = 0x22D6B8, .length = 134, - .hint_constant_reg = 1<<13}, - {0x0608DE80, NULL, .sum = 0x114129, .length = 53, - .hint_constant_reg = 1<<13}, - {0x060A03FE, NULL, .sum = 0x4D786E, .length = 246, - .hint_constant_reg = 1<<10 | 1<<14}, - -}; - -/*************************************************************************/ - -#endif // ENABLE_JIT - -/*************************************************************************/ -/************************** Interface function ***************************/ -/*************************************************************************/ - -/** - * saturn_optimize_sh2: Search for and return, if available, a native - * implementation of the SH-2 routine starting at the given address. - * If for_fold is nonzero, this function returns nonzero and NULL in - * *func_ret to indicate that the routine at the given address should not - * be folded. - * - * [Parameters] - * state: Processor state block pointer - * address: Address from which to translate - * fetch: Pointer corresponding to "address" from which opcodes can - * be fetched - * func_ret: Pointer to variable to receive address of native function - * implementing this routine if return value is nonzero - * for_fold: Nonzero if the callback is being called to look up a - * subroutine for folding, zero if being called for a - * full block translation - * [Return value] - * Length of translated block in instructions (nonzero) if a native - * function is returned, else zero - */ -unsigned int saturn_optimize_sh2(SH2State *state, uint32_t address, - const uint16_t *fetch, - SH2NativeFunctionPointer *func_ret, - int for_fold) -{ -#ifdef ENABLE_JIT - - unsigned int i; - for (i = 0; i < lenof(hand_tuned_table); i++) { - - if (hand_tuned_table[i].address != address) { - continue; - } - - unsigned int num_insns; - if (hand_tuned_table[i].detect) { - num_insns = hand_tuned_table[i].detect(state, address, fetch); - if (!num_insns) { - continue; - } - } else { - num_insns = hand_tuned_table[i].length; - const uint32_t sum = checksum_fast16(fetch, num_insns); - if (sum != hand_tuned_table[i].sum) { - continue; - } - } - - if (hand_tuned_table[i].execute == NULL) { - - if (for_fold) { - /* Tell the caller not to fold this function, because we - * want to apply our optimization hints (which we can't do - * while folding). */ - *func_ret = NULL; - return 1; - } - - uint32_t bitmask; - unsigned int bit; - - for (bitmask = hand_tuned_table[i].hint_constant_reg, bit = 0; - bitmask != 0; - bitmask &= ~(1< bf fetch[12] - && fetch[ 2] == 0xA008 // bra fetch[12] --> nop - && fetch[ 3] == 0x0009 // nop - && fetch[ 4] == 0x62D3 // mov r13, r2 - && fetch[ 5] == 0x32E7 // cmp/gt r14, r2 - && fetch[ 6] == 0x8F02 // bf/s fetch[10] --> bf/s fetch[-2] - && fetch[ 7] == 0x7D01 // add #1, r13 - && fetch[ 8] == 0xA008 // bra fetch[18] - && fetch[ 9] == 0xE000 // mov #0, r0 - && fetch[10] == 0xAFF2 // bra fetch[-2] - && fetch[11] == 0x0009 // nop - ? 12 : 0; -} - -static FASTCALL void BIOS_000025AC(SH2State *state) -{ - if (UNLIKELY(state->R[0])) { - state->SR &= ~SR_T; - state->PC += 2*12; - state->cycles += 5; - return; - } - - state->R[2] = state->R[13]; - state->SR &= ~SR_T; - state->SR |= (state->R[13] > state->R[14]) << SR_T_SHIFT; - if (UNLIKELY(state->R[13]++ > state->R[14])) { - state->R[0] = 0; - state->PC += 2*18; - state->cycles += 11; - return; - } - - if (LIKELY(state->R[13]+15 <= state->R[14])) { - state->R[13] += 15; - state->cycles += 15*76 + 15; - } else { - state->cycles += 15; - } - state->PR = state->PC; - state->PC = state->R[12]; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x2EFA: CD read loop */ - -static int BIOS_00002EFA_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - return fetch[0] == 0x6503 // mov r0, r5 - && fetch[1] == 0x3CB3 // cmp/ge r11, r12 - && fetch[2] == 0x8D06 // bt/s fetch[10] - && fetch[3] == 0x64C3 // mov r12, r4 - // fetch[4] == 0x7401 // add #1, r4 -- these two are swapped - // fetch[5] == 0x6352 // mov.l @r5, r3 -- in some BIOS versions - && fetch[6] == 0x2E32 // mov.l r3, @r14 - && fetch[7] == 0x34B3 // cmp/ge r11, r4 - && fetch[8] == 0x8FFA // bf/s fetch[4] - && fetch[9] == 0x7E04 // add #4, r14 - ? 10 : 0; -} - -static FASTCALL void BIOS_00002EFA(SH2State *state) -{ - uint8_t *page_base; - - if (UNLIKELY(state->R[0] != 0x25818000) - || UNLIKELY(!(page_base = direct_pages[state->R[14]>>19])) - ) { - state->R[5] = state->R[0]; - state->PC += 2; - state->cycles += 1; - return; - } - - state->R[5] = state->R[0]; - state->SR |= SR_T; // Always ends up set from here down - - int32_t count = state->R[11]; - int32_t i = state->R[12]; - int32_t left = count - i; - if (UNLIKELY(left <= 0)) { - state->R[4] = i; - state->PC += 2*10; - state->cycles += 5; - return; - } - - uint8_t *ptr = page_base + state->R[14]; - state->R[4] = count; - state->R[14] += left*4; - state->PC += 2*10; - state->cycles += 7*left + (4-1); - - /* Call the copy routine last to avoid unnecessary register saves and - * restores. */ - Cs2RapidCopyT2(ptr, left); -} - -/*-----------------------------------------------------------------------*/ - -/* 0x3BC6: CD status read routine */ - -static FASTCALL void BIOS_00003BC6(SH2State *state) -{ - /* With the current CS2 implementation, this all amounts to a simple - * read of registers CR1-CR4, but let's not depend on that behavior. */ - - state->R[0] = -3; // Default return value (error) - - unsigned int try; - for (try = 0; try < 100; try++, state->cycles += 67) { - const unsigned int CR1 = Cs2ReadWord(0x90018); - const unsigned int CR2 = Cs2ReadWord(0x9001C); - const unsigned int CR3 = Cs2ReadWord(0x90020); - const unsigned int CR4 = Cs2ReadWord(0x90024); - HRAM_STOREW(state->R[4], 0, CR1); - HRAM_STOREW(state->R[4], 2, CR2); - HRAM_STOREW(state->R[4], 4, CR3); - HRAM_STOREW(state->R[4], 6, CR4); - - const unsigned int CR1_test = Cs2ReadWord(0x90018); - const unsigned int CR2_test = Cs2ReadWord(0x9001C); - const unsigned int CR3_test = Cs2ReadWord(0x90020); - const unsigned int CR4_test = Cs2ReadWord(0x90024); - if (CR1_test==CR1 && CR2_test==CR2 && CR3_test==CR3 && CR4_test==CR4) { - state->R[0] = 0; - state->cycles += 65; - break; - } - } - - state->PC = state->PR; - state->cycles += 15 + 12; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x6001670: Sound RAM load loop (optimized to avoid slowdowns from ME - * cache issues, since it includes a read-back test) */ - -static FASTCALL void BIOS_06001670(SH2State *state) -{ - const uint32_t data = MappedMemoryReadLong(state->R[1]); - state->R[1] += 4; - MappedMemoryWriteLong(state->R[3], data); - state->R[3] += 4; - state->R[6]--; - if (state->R[6] != 0) { - state->cycles += 50; - } else { - state->PC = state->PR; - state->cycles += 52; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x6010D22: 3-D intro animation idle loop */ - -static int BIOS_06010D22_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - return (fetch[-2] & 0xF000) == 0xB000 // bsr 0x60101AC [only wastes time] - && fetch[-1] == 0xE41E // mov #30, r4 - && fetch[ 0] == 0xD011 // mov.l @(0x6010D68,pc), r0 - && fetch[ 1] == 0x6001 // mov.w @r0, r0 - && fetch[ 2] == 0x2008 // tst r0, r0 - && fetch[ 3] == 0x8BF9 // bf 0x6010D1E - ? 4 : 0; -} - -static FASTCALL void BIOS_06010D22(SH2State *state) -{ - const uint32_t address = HRAM_LOADL(state->PC & -4, 4 + 0x11*4); - state->R[0] = HRAM_LOADW(address, 0); - if (state->R[0]) { - state->SR &= ~SR_T; - state->cycles = state->cycle_limit; - } else { - state->SR |= SR_T; - state->PC += 8; - state->cycles += 4; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x60115A4, etc.: Routine with multiple JSRs and a looping recursive BSR - * (this helps cover the block switch overhead) */ - -static FASTCALL void BIOS_060115A4(SH2State *state) -{ - state->R[15] -= 12; - HRAM_STOREL(state->R[15], 8, state->R[14]); - HRAM_STOREL(state->R[15], 4, state->R[13]); - HRAM_STOREL(state->R[15], 0, state->PR); - state->R[14] = state->R[4]; - state->PR = state->PC + 9*2; - - state->PC = HRAM_LOADL((state->PC + 3*2) & -4, 4 + 0x24*4); - BIOS_0602E364(state); - - state->PC = HRAM_LOADL(state->R[14], 16); - state->cycles += 11; -} - -/*----------------------------------*/ - -static int BIOS_060115B6_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - const uint32_t jsr_address = HRAM_LOADL(state->PC & -4, 4 + 0x22*4); - return checksum_fast16(fetch, 5) == 0x3081A - && BIOS_0602E630_detect(state, jsr_address, - fetch + ((jsr_address - address) >> 1)) - ? 5 : 0; -} - -static FASTCALL void BIOS_060115B6(SH2State *state) -{ - state->R[4] = state->R[14]; - state->R[13] = 0; - state->PR = state->PC + 15*2; - state->PC = HRAM_LOADL(state->PC & -4, 4 + 0x22*4); - state->cycles += 7; - return BIOS_0602E630(state); -} - -/*----------------------------------*/ - -static int BIOS_060115D4_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - return checksum_fast16(fetch-10, 21) == 0x8E03C ? 11 : 0; -} - -static FASTCALL void BIOS_060115D4(SH2State *state) -{ - const uint32_t R14_68_address = HRAM_LOADL(state->R[14], 68); - if (state->R[13] < HRAM_LOADL(R14_68_address, 0)) { - state->R[4] = HRAM_LOADL(R14_68_address, 4 + 4*state->R[13]); - state->R[13]++; - state->PC -= 24*2; // Recursive call to 0x60115A4 (PR is already set) - state->cycles += 19; - } else { - state->PR = HRAM_LOADL(state->R[15], 0); - state->R[13] = HRAM_LOADL(state->R[15], 4); - state->R[14] = HRAM_LOADL(state->R[15], 8); - state->R[15] += 12; - state->PC = HRAM_LOADL((state->PC + 8*2) & -4, 4 + 0x17*4); - state->cycles += 12; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x602E364: Short but difficult-to-optimize data initialization routine */ - -static FASTCALL void BIOS_0602E364(SH2State *state) -{ - const uint32_t r2 = HRAM_LOADL(state->PC & -4, 0*2 + 4 + 0xF*4); - const uint32_t r5 = HRAM_LOADL(state->PC & -4, 2*2 + 4 + 0xF*4); - const uint32_t r0 = HRAM_LOADL(state->PC & -4, 4*2 + 4 + 0xF*4); - const uint32_t r3 = HRAM_LOADW(r2, 0) + 1; - HRAM_STOREW(r2, 0, r3); - const uint32_t r6 = HRAM_LOADL(r0, 0); - const uint32_t r5_new = r5 + r3*48; - HRAM_STOREL(r0, 0, r5_new); - - /* Help out the optimizer by telling it we can load multiple values - * at once. */ - const uint32_t *src = (const uint32_t *)HRAM_PTR(r6); - uint32_t *dest = (uint32_t *)HRAM_PTR(r5_new); - unsigned int i; - for (i = 0; i < 12; i += 4) { - const uint32_t a = src[i+0]; - const uint32_t b = src[i+1]; - const uint32_t c = src[i+2]; - const uint32_t d = src[i+3]; - dest[i+0] = a; - dest[i+1] = b; - dest[i+2] = c; - dest[i+3] = d; - } - - state->PC = state->PR; - state->cycles += 87; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x602E630: Coordinate transformation */ - -static int BIOS_0602E630_is_UE; - -static int BIOS_0602E630_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - if (address == 0x602E630 && checksum_fast16(fetch,612) == 0xA87EE4) { - BIOS_0602E630_is_UE = 0; - return 612; - } - if (address == 0x603A630 && checksum_fast16(fetch,600) == 0xA9F4CC) { - BIOS_0602E630_is_UE = 1; - return 600; - } - return 0; -} - -static FASTCALL void BIOS_0602E630(SH2State *state) -{ - int32_t counter; - - int16_t * const R12_ptr = - (int16_t *)HRAM_PTR(HRAM_LOADL((state->PC + 11*2) & -4, 4 + 0x7B*4)); - int32_t * const R13_ptr = - (int32_t *)HRAM_PTR(HRAM_LOADL((state->PC + 12*2) & -4, 4 + 0x7B*4)); - - const uint32_t M_R7 = HRAM_LOADL((state->PC + 24*2) & -4, 4 + 0x76*4); - const int32_t * const M = (const int32_t *)HRAM_PTR(HRAM_LOADL(M_R7, 0)); - - const uint32_t R5 = HRAM_LOADL(state->R[4], 56) + 4; - counter = (int16_t)HRAM_LOADW(R5, -4); - state->cycles += 30; - - if (counter > 0) { - - /* 0x602E66E */ - - state->cycles += 19 + (counter * /*minimum of*/ 110); - -#ifdef PSP -# define DO_MULT(dest_all,dest_z,index) \ - int32_t dest_all, dest_z; \ - do { \ - int32_t temp_x, temp_y, temp_z; \ - asm(".set push; .set noreorder\n" \ - "lw %[temp_z], %[idx]*16+8(%[M])\n" \ - "lw %[temp_x], %[idx]*16+0(%[M])\n" \ - "lw %[temp_y], %[idx]*16+4(%[M])\n" \ - "ror %[temp_z], %[temp_z], 16\n" \ - "mult %[temp_z], %[in_z]\n" \ - "ror %[temp_x], %[temp_x], 16\n" \ - "ror %[temp_y], %[temp_y], 16\n" \ - "mfhi %[temp_z]\n" \ - "mflo %[dst_z]\n" \ - "madd %[temp_x], %[in_x]\n" \ - "sll %[temp_z], %[temp_z], 16\n" \ - "srl %[dst_z], %[dst_z], 16\n" \ - "lw %[temp_x], %[idx]*16+12(%[M])\n" \ - "madd %[temp_y], %[in_y]\n" \ - "or %[dst_z], %[dst_z], %[temp_z]\n" \ - "ror %[temp_z], %[temp_x], 16\n" \ - "mfhi %[temp_x]\n" \ - "mflo %[temp_y]\n" \ - "sll %[temp_x], %[temp_x], 16\n" \ - "srl %[temp_y], %[temp_y], 16\n" \ - "or %[dst_all], %[temp_x], %[temp_y]\n" \ - "addu %[dst_all], %[dst_all], %[temp_z]\n" \ - ".set pop" \ - : [dst_all] "=r" (dest_all), [dst_z] "=&r" (dest_z), \ - [temp_x] "=&r" (temp_x), [temp_y] "=&r" (temp_y), \ - [temp_z] "=&r" (temp_z) \ - : [M] "r" (M), [idx] "i" (index), [in_x] "r" (in_x), \ - [in_y] "r" (in_y), [in_z] "r" (in_z) \ - : "hi", "lo" \ - ); \ - } while (0) -#else // !PSP -# define GET_M(i) ((int64_t)(int32_t)RAM_SWAPL(M[(i)])) -# define DO_MULT(dest_all,dest_z,index) \ - const int32_t dest_z = ((int64_t)in_z * GET_M((index)*4+2)) >> 16; \ - int32_t dest_all = (((int64_t)in_x * GET_M((index)*4+0) \ - + (int64_t)in_y * GET_M((index)*4+1) \ - + (int64_t)in_z * GET_M((index)*4+2)) >> 16) \ - + GET_M((index)*4+3); -#endif - - const uint32_t testflag = HRAM_LOADL(state->R[4], 20); - const int32_t *in = (const int32_t *)HRAM_PTR(R5); - int32_t *out = R13_ptr; - int16_t *coord_out = R12_ptr; - - do { - const int32_t in_x = RAM_SWAPL(in[0]); - const int32_t in_y = RAM_SWAPL(in[1]); - const int32_t in_z = RAM_SWAPL(in[2]); - - DO_MULT(out_z, zz, 2); - if (out_z < 0 && testflag) { - out_z += out_z >> 3; - } - out[ 2] = RAM_SWAPL(out_z); - out[14] = RAM_SWAPL(out_z - (zz<<1)); - - DO_MULT(out_x, zx, 0); - out[ 0] = RAM_SWAPL(out_x); - out[12] = RAM_SWAPL(out_x - (zx<<1)); - - DO_MULT(out_y, zy, 1); - out[ 1] = RAM_SWAPL(out_y); - out[13] = RAM_SWAPL(out_y - (zy<<1)); - - /* The result gets truncated to 16 bits here, so we don't need - * to worry about the 32->24 bit precision loss with floats. - * (There are only a few pixels out of place during the entire - * animation as a result of rounding error.) */ - const float coord_mult = 192.0f / out_z; - *coord_out++ = (int16_t)ifloorf(out_x * coord_mult); - *coord_out++ = (int16_t)ifloorf(out_y * coord_mult); - - in += 3; - out += 3; - counter -= 2; - } while (counter > 0); - -#undef GET_M -#undef DO_MULT - - } // if (counter > 0) - - /* 0x602E840 */ - - /* Offset for second-half local data accesses */ - const int UE_PC_offset = (BIOS_0602E630_is_UE ? -12*2 : 0); - - const uint32_t R11 = HRAM_LOADL(state->R[4], 64); - counter = (int16_t)HRAM_LOADW(R11, 0); - state->cycles += 19; - - if (counter > 0) { - -#ifdef PSP -# define DOT3_16(v,x,y,z) __extension__({ \ - int32_t __temp1, __temp2, __result; \ - asm(".set push; .set noreorder\n" \ - "lw %[temp1], 0(%[V])\n" \ - "lw %[temp2], 4(%[V])\n" \ - "ror %[temp1], %[temp1], 16\n" \ - "mult %[temp1], %[X]\n" \ - "lw %[temp1], 8(%[V])\n" \ - "ror %[temp2], %[temp2], 16\n" \ - "madd %[temp2], %[Y]\n" \ - "ror %[temp1], %[temp1], 16\n" \ - "madd %[temp1], %[Z]\n" \ - "mflo %[result]\n" \ - "mfhi %[temp1]\n" \ - "sra %[result], %[result], 16\n" \ - "ins %[result], %[temp1], 16, 16\n" \ - ".set pop" \ - : [temp1] "=&r" (__temp1), [temp2] "=&r" (__temp2), \ - [result] "=r" (__result) \ - : [V] "r" (v), [X] "r" (x), [Y] "r" (y), [Z] "r" (z) \ - : "hi", "lo" \ - ); \ - __result; \ -}) -# define DOT3_32(v,x,y,z) __extension__({ \ - int32_t __temp1, __temp2, __result; \ - asm(".set push; .set noreorder\n" \ - "lw %[temp1], 0(%[V])\n" \ - "lw %[temp2], 4(%[V])\n" \ - "ror %[temp1], %[temp1], 16\n" \ - "mult %[temp1], %[X]\n" \ - "lw %[temp1], 8(%[V])\n" \ - "ror %[temp2], %[temp2], 16\n" \ - "madd %[temp2], %[Y]\n" \ - "ror %[temp1], %[temp1], 16\n" \ - "madd %[temp1], %[Z]\n" \ - "mfhi %[result]\n" \ - ".set pop" \ - : [temp1] "=&r" (__temp1), [temp2] "=&r" (__temp2), \ - [result] "=r" (__result) \ - : [V] "r" (v), [X] "r" (x), [Y] "r" (y), [Z] "r" (z) \ - : "hi", "lo" \ - ); \ - __result; \ -}) -#else // !PSP -# define DOT3_16(v,x,y,z) \ - (((int64_t)(int32_t)RAM_SWAPL((v)[0]) * (int64_t)(int32_t)(x) \ - + (int64_t)(int32_t)RAM_SWAPL((v)[1]) * (int64_t)(int32_t)(y) \ - + (int64_t)(int32_t)RAM_SWAPL((v)[2]) * (int64_t)(int32_t)(z)) >> 16) -# define DOT3_32(v,x,y,z) \ - (((int64_t)(int32_t)RAM_SWAPL((v)[0]) * (int64_t)(int32_t)(x) \ - + (int64_t)(int32_t)RAM_SWAPL((v)[1]) * (int64_t)(int32_t)(y) \ - + (int64_t)(int32_t)RAM_SWAPL((v)[2]) * (int64_t)(int32_t)(z)) >> 32) -#endif - - state->cycles += 68 + 95*(counter-2); - - /* 0x602E850 */ - - const int32_t *in = (const int32_t *)(HRAM_PTR(R11) + 28); - const int32_t *coord_in = &R13_ptr[12]; - const uint32_t out_address = - HRAM_LOADL((state->PC + 264*2 + UE_PC_offset) & -4, 4 + 0xA2*4); - int32_t *out = (int32_t *)HRAM_PTR(out_address); - int16_t *coord_out = &R12_ptr[8]; - - const uint16_t *R6_ptr = - (const uint16_t *)(HRAM_PTR(HRAM_LOADL(state->R[4], 60)) + 4); - const uint32_t flag_address = - HRAM_LOADL((state->PC + 348*2 + UE_PC_offset) & -4, 4 + 0x79*4); - int16_t *flag = (int16_t *)HRAM_PTR(flag_address); - - { - const int32_t M_2 = RAM_SWAPL(M[ 2]); - const int32_t M_6 = RAM_SWAPL(M[ 6]); - const int32_t M_10 = RAM_SWAPL(M[10]); - - out[0] = RAM_SWAPL(-M_2); - out[1] = RAM_SWAPL(-M_6); - out[2] = RAM_SWAPL(-M_10); - const int32_t *in0_0 = - (const int32_t *)((uintptr_t)R13_ptr + R6_ptr[3]); - R6_ptr += 10; - const int32_t test_0 = DOT3_32(in0_0, -M_2, -M_6, -M_10); - *flag++ = (test_0 < 0); - out += 3; - counter--; - - out[0] = RAM_SWAPL(M_2); - out[1] = RAM_SWAPL(M_6); - out[2] = RAM_SWAPL(M_10); - const int32_t *in0_1 = - (const int32_t *)((uintptr_t)R13_ptr + R6_ptr[3]); - R6_ptr += 10; - const int32_t test_1 = DOT3_32(in0_1, M_2, M_6, M_10); - *flag++ = (test_1 < 0); - out += 3; - counter--; - } - - do { - const int32_t in_x = RAM_SWAPL(in[0]); - const int32_t in_y = RAM_SWAPL(in[1]); - const int32_t in_z = RAM_SWAPL(in[2]); - - const int32_t out_x = DOT3_16(&M[0], in_x, in_y, in_z); - const int32_t out_y = DOT3_16(&M[4], in_x, in_y, in_z); - const int32_t out_z = DOT3_16(&M[8], in_x, in_y, in_z); - - out[0] = RAM_SWAPL(out_x); - out[1] = RAM_SWAPL(out_y); - out[2] = RAM_SWAPL(out_z); - - const float coord_mult = 192.0f / (int32_t)RAM_SWAPL(coord_in[2]); - *coord_out++ = - (int16_t)ifloorf((int32_t)RAM_SWAPL(coord_in[0]) * coord_mult); - *coord_out++ = - (int16_t)ifloorf((int32_t)RAM_SWAPL(coord_in[1]) * coord_mult); - coord_in += 3; - - const int32_t *in0 = - (const int32_t *)((uintptr_t)R13_ptr + R6_ptr[3]); - R6_ptr += 10; - const int32_t test = DOT3_32(in0, out_x, out_y, out_z); - *flag++ = (test < 0); - - in += 3; - out += 3; - counter--; - } while (counter > 0); - -#undef DOT3_16 -#undef DOT3_32 - - } // if (counter > 0) - - /* 0x602E914 */ - /* Note: At this point, all GPRs except R9, R12, R13, and R15 are dead */ - - const int16_t *flag = (const int16_t *)HRAM_PTR( - HRAM_LOADL((state->PC + 572*2 + UE_PC_offset) & -4, 4 + 0x0F*4)); - const int32_t *R1_ptr = (const int32_t *)HRAM_PTR( - HRAM_LOADL((state->PC + 378*2 + UE_PC_offset) & -4, 4 + 0x6C*4)); - const uint16_t *R6_ptr = (const uint16_t *)HRAM_PTR( - HRAM_LOADL(state->R[4], 60)); - const int32_t *R7_ptr = (const int32_t *)HRAM_PTR( - HRAM_LOADL((state->PC + 371*2 + UE_PC_offset) & -4, 4 + 0x6D*4)); - const uint32_t R9 = HRAM_LOADL((state->PC + 9*2) & -4, 4 + 0x7A*4); - uint16_t *R10_ptr = (uint16_t *)HRAM_PTR( - HRAM_LOADL((state->PC + 370*2 + UE_PC_offset) & -4, 4 + 0x73*4)); - - const int32_t limit = *R6_ptr; - R6_ptr += 2; - state->cycles += 13; - - for (counter = 0; counter < limit; counter++, R7_ptr += 3, R6_ptr += 10) { - - /* 0x602EAA8 */ - - if (!flag[counter]) { - state->cycles += 15; - continue; - } - - /* 0x602E924 */ - -#ifdef PSP - int32_t R2; - { - int32_t temp1, temp2, temp3; - asm(".set push; .set noreorder\n" - "lw %[temp1], 0(%[R7_ptr])\n" - "lw %[temp2], 0(%[R1_ptr])\n" - "lw %[temp3], 4(%[R7_ptr])\n" - "ror %[temp1], %[temp1], 16\n" - "ror %[temp2], %[temp2], 16\n" - "mult %[temp1], %[temp2]\n" - "lw %[temp1], 4(%[R1_ptr])\n" - "lw %[temp2], 8(%[R7_ptr])\n" - "ror %[temp3], %[temp3], 16\n" - "ror %[temp1], %[temp1], 16\n" - "madd %[temp3], %[temp1]\n" - "lw %[temp3], 8(%[R1_ptr])\n" - "ror %[temp2], %[temp2], 16\n" - "ror %[temp3], %[temp3], 16\n" - "madd %[temp2], %[temp3]\n" - "mflo %[temp1]\n" - "mfhi %[temp2]\n" - "sra %[temp1], %[temp1], 16\n" - "addiu %[temp2], %[temp2], 1\n" - "ins %[temp1], %[temp2], 16, 16\n" - "sra %[temp1], %[temp1], 10\n" - "max %[temp1], %[temp1], $zero\n" - "min %[R2], %[temp1], %[cst_127]\n" - ".set pop" - : [R2] "=r" (R2), [temp1] "=&r" (temp1), - [temp2] "=&r" (temp2), [temp3] "=&r" (temp3) - : [R7_ptr] "r" (R7_ptr), [R1_ptr] "r" (R1_ptr), - [cst_127] "r" (127) - : "hi", "lo" - ); - } -#else // !PSP - const int32_t mac = - ((int64_t) (int32_t)RAM_SWAPL(R7_ptr[0]) * (int32_t)RAM_SWAPL(R1_ptr[0]) - + (int64_t) (int32_t)RAM_SWAPL(R7_ptr[1]) * (int32_t)RAM_SWAPL(R1_ptr[1]) - + (int64_t) (int32_t)RAM_SWAPL(R7_ptr[2]) * (int32_t)RAM_SWAPL(R1_ptr[2]) - ) >> 16; - const int32_t R2_temp = (mac + 0x10000) >> 10; - const int32_t R2 = R2_temp < 0 ? 0 : R2_temp > 127 ? 127 : R2_temp; -#endif - const uint32_t R2_tableaddr = RAM_SWAPL(*(const uint32_t *)&R6_ptr[8]); - const uint16_t *R2_table = (const uint16_t *)HRAM_PTR(R2_tableaddr); - - const uint32_t R9_address = HRAM_LOADL(R9, 0); - HRAM_STOREL(R9, 0, R9_address + 48); - HRAM_STOREW(R9_address, 0, *R6_ptr); - HRAM_STOREW(R9_address, 42, R2_table[R2]); - - uint32_t * const R9_data32 = (uint32_t *)(HRAM_PTR(R9_address) + 4); - int32_t R3; - switch (R6_ptr[1] & 0xFF) { - case 0x00: - R9_data32[0] = *(uint32_t *)&R12_ptr[ 0]; - R9_data32[1] = *(uint32_t *)&R12_ptr[ 2]; - R9_data32[2] = *(uint32_t *)&R12_ptr[ 4]; - R9_data32[3] = *(uint32_t *)&R12_ptr[ 6]; - R3 = RAM_SWAPL(R13_ptr[5]) + RAM_SWAPL(R13_ptr[11]); - break; - - case 0x30: - R9_data32[0] = *(uint32_t *)&R12_ptr[ 8]; - R9_data32[1] = *(uint32_t *)&R12_ptr[14]; - R9_data32[2] = *(uint32_t *)&R12_ptr[12]; - R9_data32[3] = *(uint32_t *)&R12_ptr[10]; - R3 = RAM_SWAPL(R13_ptr[17]) + RAM_SWAPL(R13_ptr[23]); - break; - - case 0x60: - R9_data32[0] = *(uint32_t *)&R12_ptr[ 0]; - R9_data32[1] = *(uint32_t *)&R12_ptr[ 8]; - R9_data32[2] = *(uint32_t *)&R12_ptr[10]; - R9_data32[3] = *(uint32_t *)&R12_ptr[ 2]; - R3 = RAM_SWAPL(R13_ptr[5]) + RAM_SWAPL(R13_ptr[14]); - break; - - case 0x90: - R9_data32[0] = *(uint32_t *)&R12_ptr[ 4]; - R9_data32[1] = *(uint32_t *)&R12_ptr[12]; - R9_data32[2] = *(uint32_t *)&R12_ptr[14]; - R9_data32[3] = *(uint32_t *)&R12_ptr[ 6]; - R3 = RAM_SWAPL(R13_ptr[8]) + RAM_SWAPL(R13_ptr[23]); - break; - - case 0xC0: - R9_data32[0] = *(uint32_t *)&R12_ptr[ 2]; - R9_data32[1] = *(uint32_t *)&R12_ptr[10]; - R9_data32[2] = *(uint32_t *)&R12_ptr[12]; - R9_data32[3] = *(uint32_t *)&R12_ptr[ 4]; - R3 = RAM_SWAPL(R13_ptr[5]) + RAM_SWAPL(R13_ptr[20]); - break; - - default: // case 0xF0 - R9_data32[0] = *(uint32_t *)&R12_ptr[ 0]; - R9_data32[1] = *(uint32_t *)&R12_ptr[ 6]; - R9_data32[2] = *(uint32_t *)&R12_ptr[14]; - R9_data32[3] = *(uint32_t *)&R12_ptr[ 8]; - R3 = RAM_SWAPL(R13_ptr[11]) + RAM_SWAPL(R13_ptr[14]); - break; - } - - if (!BIOS_0602E630_is_UE && R3 < -0x30000 && (R6_ptr[1] & 0xFF00)) { - R3 = -R3; - } - R3 >>= 1; - uint32_t *R3_buffer = (uint32_t *)HRAM_PTR( - HRAM_LOADL((state->PC + 558*2 + UE_PC_offset) & -4, 4 + 0x17*4)); - R3_buffer[(*R10_ptr)++] = RAM_SWAPL(R3); - - state->cycles += 39 + /*approximately*/ 54; - } - - /* 0x602EAB8 */ - - state->PC = state->PR; - state->cycles += 10; -} - -/*************************************************************************/ - -/**** Azel: Panzer Dragoon RPG (JP) optimizations ****/ - -/*-----------------------------------------------------------------------*/ - -/* Common color calculation logic used by several routines */ - -static uint32_t Azel_color_calc(const int16_t *local_ptr, - const int16_t *r4_ptr, const int16_t *r5_ptr, - int32_t r, int32_t g, int32_t b) -{ - int32_t dot = r4_ptr[0] * local_ptr[0] - + r4_ptr[1] * local_ptr[1] - + r4_ptr[2] * local_ptr[2]; - if (dot > 0) { - dot >>= 16; - b += dot * r5_ptr[0]; - g += dot * r5_ptr[1]; - r += dot * r5_ptr[2]; - } - return (bound(b, 0, 0x1F00) & 0x1F00) << 2 - | (bound(g, 0, 0x1F00) & 0x1F00) >> 3 - | (bound(r, 0, 0x1F00) ) >> 8; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x600614C: Idle loop with a JSR */ - -static int Azel_0600614C_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - return fetch[-2] == 0x4B0B // jsr @r11 - && fetch[-1] == 0x0009 // nop - && fetch[ 0] == 0x60E2 // mov.l @r14, r0 - && fetch[ 1] == 0x2008 // tst r0, r0 - && fetch[ 2] == 0x8BFA // bf fetch[-2] - && state->R[14] == 0x604BC80 - ? 3 : 0; -} - -static FASTCALL void Azel_0600614C(SH2State *state) -{ - /* Help out the optimizer by loading these early. */ - const int32_t cycle_limit = state->cycle_limit; - const uint32_t test = *(uint32_t *)HRAM_PTR(0x604BC80); - const uint32_t r3 = 0x604B68C; // @(0x38,pc=0x600FCB0) -#if defined(__mips__) && !defined(WORDS_BIGENDIAN) - /* Similar to the "volatile" in the 0x600C59C optimizer, we force this - * to be loaded during the load delay slots of "test". */ - const uint32_t r3_HI = (r3 + 0x8000) & 0xF0000; - uint32_t r3_test; - asm("lbu %0, %1(%2)" - : "=r" (r3_test) - : "i" (((r3 & 0xFFFFF) ^ 1) - r3_HI), "r" (HighWram + r3_HI)); -#else - const uint32_t r3_test = HRAM_LOADB(r3, 0); -#endif - - /* For a comparison against zero, we don't need to swap bytes. */ - if (LIKELY(test)) { - - state->cycles = cycle_limit; - - /* 0x600FCB0 almost always returns straight to us, so we implement - * the first part of it here. */ - if (UNLIKELY(r3_test != 0)) { - state->PR = state->PC; - state->PC = 0x600FCB0 + 4*2; - state->R[3] = r3; - } - - } else { - - state->PC += 2*3; - state->cycles += 3; - - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x60061F0: RBG0 parameter generation for sky/ground backgrounds. We - * also store the slope set here in a video tweak parameter, so the code - * doesn't have to re-derive it from the coefficients (which may be mangled - * by the "shimmering" effect added to water). */ - -static FASTCALL void Azel_060061F0(SH2State *state) -{ - int32_t r4 = state->R[4]; - int32_t r5 = state->R[5]; - int32_t delta = state->R[6]; - uint32_t counter = state->R[7]; - const uint32_t out_address = HRAM_LOADL(state->R[15], 0); - int32_t *out = (int32_t *)HRAM_PTR(out_address); - - extern float psp_video_tweaks_Azel_RBG0_slope; - extern float psp_video_tweaks_Azel_RBG0_first_recip; - - if (r4 < 0) { - r4 = -r4; - r5 = -r5; - delta = -delta; - } - - if (r4 != 0) { - psp_video_tweaks_Azel_RBG0_slope = (float)-delta / (float)r4; - } - - const float r4_scaled = r4 * 65536.0f; - const int32_t r4_test = r4 >> 14; // See below for why we use this. - - if (delta == 0) { - /* No horizon scaling is taking place. Note that r5 should be - * checked against zero here (and in similar cases below), but - * we're a bit more conservative in order to avoid FPU overflow - * errors on conversion to integer; since only the low 24 bits of - * the 16.16 fixed point result are significant, this isn't a - * problem in practice--it will only come up in cases where the - * horizon line almost exactly coincides with a screen line. */ - if (r5 > r4_test) { - const int32_t quotient = ifloorf(r4_scaled / (float)r5); - state->PC = state->PR; - state->cycles += 72 + (counter * 5); - for (; counter != 0; counter--, out++) { - *out = RAM_SWAPL(quotient); - } - } else { - state->PC = state->PR; - state->cycles += 30 + (counter * 5); - for (; counter != 0; counter--, out++) { - *out = -1; - } - } - return; - } - - const int32_t r5_final = r5 - (delta * (counter-1)); - - if (delta > 0 ? (r5 <= r4_test) : (r5_final <= r4_test)) { - /* The entire background layer is outside the horizon area. */ - state->PC = state->PR; - state->cycles += (delta > 0 ? 40 : 43) + (counter * 5); - for (; counter != 0; counter--, out++) { - *out = -1; - } - return; - } - - if (delta > 0 && r5_final <= r4_test) { - /* The bottom of the background layer is outside the horizon area. */ - const uint32_t partial_count = - MIN(counter - ((r5 - r4_test) / delta) + 1, counter); - state->cycles += 88 + (partial_count * 5); - counter -= partial_count; - int32_t *out_temp = out + counter; - uint32_t i; - for (i = partial_count; i != 0; i--, out_temp++) { - *out_temp = -1; - } - } else if (delta < 0 && r5 <= r4_test) { - /* The top of the background layer is outside the horizon area. */ - const uint32_t partial_count = - MIN((r5 - r4_test) / delta + 1, counter); - state->cycles += 86 + (partial_count * 5); - r5 -= delta * partial_count; - counter -= partial_count; - uint32_t i; - for (i = partial_count; i != 0; i--, out++) { - *out = -1; - } - } else { - /* The entire background layer is within the horizon area. */ - state->cycles += (delta > 0 ? 39 : 42); - } - - state->PC = state->PR; - state->cycles += 15 + (counter * 32) + (counter%2 ? 10 : 0); - - if (r4 != 0) { - psp_video_tweaks_Azel_RBG0_first_recip = (float)r5 / (float)r4; - } - for (; counter != 0; counter--, out++) { - *out = RAM_SWAPL(ifloorf(r4_scaled / (float)r5)); - r5 -= delta; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x600C4DC: Routine to register a function in the SSH2 call table. This - * could be optimized by the main code with a few hints if it had better - * flow analysis. */ - -static FASTCALL void Azel_0600C4DC(SH2State *state) -{ - const uint32_t base = 0x604B604; - const unsigned int index = HRAM_LOADW(base, 0); - const unsigned int next_index = (index + 1) & 7; - - if (HRAM_LOADL(base, 4 + next_index*16 + 0) != 0) { - MappedMemoryWriteByte(0xFFFFFE11, 0); - } - HRAM_STOREL(base, 4 + index*16 + 4, state->R[4]); - HRAM_STOREL(base, 4 + index*16 + 8, state->R[5]); - HRAM_STOREL(base, 4 + index*16 + 12, state->R[6]); - HRAM_STOREL(base, 4 + index*16 + 0, state->R[7]); - if (index == HRAM_LOADW(base, 2)) { - MappedMemoryWriteWord(0x21000000, 0); - } - HRAM_STOREW(base, 0, next_index); - - state->PC = state->PR; - state->cycles += 47; // Approximate -} - -/*-----------------------------------------------------------------------*/ - -/* 0x600C59C, etc.: SSH2 main loop (idle + function call) */ - -static NOINLINE void Azel_0600C5A4(SH2State *state); -static ALWAYS_INLINE void Azel_0600C5C0( - SH2State *state, const uint32_t *r13_ptr, int extra_cycles); - -/*----------------------------------*/ - -static FASTCALL void Azel_0600C59C(SH2State *state) -{ - int32_t test = (int8_t)(((SH2_struct *)(state->userdata))->onchip.FTCSR); - - /* Again, help out the optimizer. This "volatile" actually speeds - * things up, because it forces the compiler to load this during the - * load delay slots of "test", rather than delaying the load so far - * that the subsequent store to state->cycles ends up stalling. - * (Granted, this is properly an optimizer bug that ought to be fixed - * in GCC. But since GCC's scheduler is so complex it might as well - * be random chaos, what else can we do?) */ - int32_t cycle_limit = -#ifdef __mips__ - *(volatile int32_t *)& -#endif - state->cycle_limit; - - if (LIKELY(test >= 0)) { - state->cycles = cycle_limit; - } else { - state->PR = 0x600C5B4; // Make sure PR is set before 0x600C5C0. - /* We deliberately chain to a separate NOINLINE routine here to - * minimize register saves and restores in the common case above, - * since even setting up and tearing down a stack frame adds a - * significant percentage to the execution time of this function. */ - return Azel_0600C5A4(state); - } -} - -/*----------------------------------*/ - -static NOINLINE void Azel_0600C5A4(SH2State *state) -{ - MappedMemoryWriteByte(0xFFFFFE11, 0); - const unsigned int index = HRAM_LOADW(state->R[13], 2); - const uint32_t *r13_ptr = (const uint32_t *)HRAM_PTR(state->R[13]); - return Azel_0600C5C0(state, &r13_ptr[1 + index*4], 7); -} - -/*----------------------------------*/ - -static int Azel_0600C5B4_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - return checksum_fast16(fetch-6, 24) == 0x93C29 ? 24 : 0; -} - -static FASTCALL void Azel_0600C5B4(SH2State *state) -{ - const uint32_t r13 = state->R[13]; - uint32_t *r13_ptr = (uint32_t *)HRAM_PTR(r13); - unsigned int index = HRAM_LOADW(r13, 2); - r13_ptr[1 + index*4] = 0; - index = (index + 1) & 7; - HRAM_STOREW(r13, 2, index); - MappedMemoryWriteWord(0x21800000, 0); - return Azel_0600C5C0(state, &r13_ptr[1 + index*4], 6); -} - -/*----------------------------------*/ - -static ALWAYS_INLINE void Azel_0600C5C0( - SH2State *state, const uint32_t *r13_ptr, int extra_cycles) -{ - const uint32_t func_address = RAM_SWAPL(r13_ptr[0]); - if (func_address) { - state->R[4] = RAM_SWAPL(r13_ptr[1]); - state->R[5] = RAM_SWAPL(r13_ptr[2]); - state->R[6] = RAM_SWAPL(r13_ptr[3]); - /* PR is known to be correct (0x600C5B4) here. */ - state->PC = func_address; - state->cycles += extra_cycles + 19; - } else { - state->PC = 0x600C59C; - state->cycles = state->cycle_limit; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x600C5F8, 0x600C690: Cache flush routines (no-ops in emulation) */ - -static FASTCALL void Azel_0600C5F8(SH2State *state) -{ - state->R[0] = 0x604AEA8 + HRAM_LOADW(0x604B606, 0) * 48; - state->PC = state->PR; - state->cycles += 48; -} - -static FASTCALL void Azel_0600C690(SH2State *state) -{ - state->PC = state->PR; - state->cycles += 11 + (state->R[5] / 16) * 5; // Approximate -} - -/*-----------------------------------------------------------------------*/ - -/* 0x6010F24/0x6010F52: Bitmap copy loop (for movies) */ - -static int Azel_06010F24_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - return fetch[ 0] == 0x6693 // mov r9, r6 - && fetch[ 1] == 0x65D3 // mov r13, r5 - && fetch[ 2] == 0x4A0B // jsr @r10 [DMA copy routine] - && fetch[ 3] == 0x64E3 // mov r14, r4 - // fetch[ 4] == 0x53F1 // {mov.l @(4,r15), r3 [counter] | add r8, r14} - // fetch[ 5] == 0x3E8C // {add r8, r14 | mov.l @r15, r3 [counter]} - && fetch[ 6] == 0x73FF // add #-1, r3 - // fetch[ 7] == 0x2338 // {tst r3, r3 | mov.l r3, @r15} - // fetch[ 8] == 0x1F31 // {mov.l r3, @(4,r15) | tst r3, r3} - && fetch[ 9] == 0x8FF5 // bf/s fetch[0] - && fetch[10] == 0x3DCC // add r12, r13 - && state->R[13]>>20 == 0x25E - ? 11 : 0; -} - -static FASTCALL void Azel_06010F24(SH2State *state) -{ - const uint32_t src_addr = state->R[14]; - const uint32_t dest_addr = state->R[13]; - const uint32_t size = state->R[9]; - const uint32_t *src = (const uint32_t *)HRAM_PTR(src_addr); - uint32_t *dest = (uint32_t *)VDP2_PTR(dest_addr); - - uint32_t i; - for (i = 0; i < size; i += 16, src += 4, dest += 4) { - const uint32_t word0 = src[0]; - const uint32_t word1 = src[1]; - const uint32_t word2 = src[2]; - const uint32_t word3 = src[3]; - dest[0] = RAM_VDP_SWAPL(word0); - dest[1] = RAM_VDP_SWAPL(word1); - dest[2] = RAM_VDP_SWAPL(word2); - dest[3] = RAM_VDP_SWAPL(word3); - } - - state->R[14] = src_addr + state->R[8]; - state->R[13] = dest_addr + state->R[12]; - - /* Conveniently, the counter is always stored in R3 when we get here - * (it's first loaded when the loop is executed on the fall-in case) - * and the stack variables are never referenced once their respective - * loops complete, so we don't have to worry about which loop we're in. */ - unsigned int counter = state->R[3]; - counter--; - state->R[3] = counter; - - if (counter != 0) { - state->SR &= ~SR_T; - state->cycles += 290; - } else { - state->SR |= SR_T; - state->PC += 2*11; - state->cycles += 289; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x6014274: Calculation routine (possibly for the line scroll table?) */ - -static FASTCALL void Azel_06014274(SH2State *state) -{ - const int32_t * const sin_table = (const int32_t *)LRAM_PTR(0x20216660); - - int32_t *r4_ptr = (int32_t *)HRAM_PTR(state->R[4]); - - int32_t r9 = RAM_SWAPL(r4_ptr[6]); - r4_ptr[6] = RAM_SWAPL(r9 + RAM_SWAPL(r4_ptr[1])); - const int32_t r10 = RAM_SWAPL(r4_ptr[7]); - r4_ptr[7] = RAM_SWAPL(r10 + RAM_SWAPL(r4_ptr[4])); - const int32_t r11 = 176; - const int32_t r5 = RAM_SWAPL(r4_ptr[2]); - const int32_t r6 = RAM_SWAPL(r4_ptr[5]); - const int32_t r7 = RAM_SWAPL(r4_ptr[3]); - r4_ptr = (int32_t *)HRAM_PTR(RAM_SWAPL(r4_ptr[0])); - - unsigned int counter; - for (counter = 224; counter != 0; counter--) { - const int32_t r0 = ((int64_t)r7 * sin_table[r9>>16 & 0xFFF]) >> 16; - /* We drop 2 bits of precision here so we can use a 32/32bit - * integer divide instruction; it shouldn't make a difference in - * the visible result. */ - const int32_t r12 = ((r7 + r0) >> 2) + 0x4000; - const int32_t quotient = 0x40000000 / r12; - r4_ptr[1] = RAM_SWAPL((RAM_SWAPL(r4_ptr[1]) + r6) & 0xFFFFFF); - r4_ptr[2] = RAM_SWAPL(quotient); - r4_ptr[0] = RAM_SWAPL((0x10000 - quotient) * r11 + r10); - r4_ptr += 3; - r9 += r5; - } - - state->PC = state->PR; - state->cycles += 86 + 222*48 + 58; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x601E330: Input capture check */ - -static FASTCALL void Azel_0601E330(SH2State *state) -{ - int32_t test = (int8_t)(((SH2_struct *)(state->userdata))->onchip.FTCSR); - const uint32_t param = HRAM_LOADL(0x604AEA4, 0); - if (LIKELY(test >= 0)) { - state->R[5] = param; - state->R[6] = 0x604FCFC; - state->R[7] = 0x604BCB4; - state->PC = 0x601F1E4; - state->cycles += 21; - } else { - const uint32_t old_r4 = state->R[4]; - state->R[4] = param; - - /* 0x600C5D8 */ - const unsigned int index = HRAM_LOADW(0x604B604, 0); - state->R[5] = 0x604AEA8 + index*48; - state->PC = 0x6035AA0; - Azel_06035AA0(state); - - /* 0x601E3A6 */ - state->R[4] = old_r4; - state->R[5] = 0; - state->R[6] = 0; - state->R[7] = 0x601E314; - state->PC = 0x600C4DC; - state->cycles += 16 + 17 + 10; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x601E910, etc.: Various varieties of vertex manipulation routines and - * their subfunctions */ - -static void Azel_0601E910_common(SH2State *state, - int (*clipfunc)(SH2State *state, uint32_t r11, uint32_t r13)); -static void Azel_0601E9A4(SH2State *state, const uint32_t color_data, - int swapflag); -static int Azel_0601EB10(const int16_t *vertex_data, uint32_t color_data, - int base_r, int base_g, int base_b); - -static void Azel_0601EC20_common(SH2State *state, - int (*clipfunc)(SH2State *state, uint32_t r11, uint32_t r13)); -static void Azel_0601EC58(SH2State *state, int swapflag); -static int Azel_0601ED58(const int16_t *vertex_data, - int base_r, int base_g, int base_b); -static int Azel_0601EDDC(const int16_t *vertex_data, - int base_r, int base_g, int base_b); - -static void Azel_0601F2D6_common(SH2State *state, - int (*clipfunc)(SH2State *state, uint32_t r11, uint32_t r13)); -static void Azel_0601F49C(SH2State *state, int swapflag); -static int Azel_0601FA68(const int16_t *vertex_data, - int base_r, int base_g, int base_b); -static int Azel_0601FAEC(const int16_t *vertex_data, - int base_r, int base_g, int base_b); - -static int Azel_0601F58A(SH2State *state, uint32_t r11, uint32_t r13); -static int Azel_0601F5A6(SH2State *state, - const int16_t *r10_ptr, const int16_t *r11_ptr, - const int16_t *r12_ptr, const int16_t *r13_ptr); -static int Azel_0601F5D2(SH2State *state); - -static int Azel_0601F5EE(SH2State *state, uint32_t r11, uint32_t r13); - -static ALWAYS_INLINE int Azel_0601F762( - SH2State *state, const uint32_t * const r10_ptr, - const uint32_t * const r11_ptr, const uint32_t * const r12_ptr, - const uint32_t * const r13_ptr, uint32_t * const r14_ptr, - const uint32_t r4_0, const int swapflag); - -static int32_t Azel_0601F824(const int16_t *r6_ptr, uint32_t *r10_ptr, - uint32_t *r11_ptr, uint32_t *r12_ptr, - uint32_t *r13_ptr, uint32_t mask, - int (*clipfunc)(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr)); -static int Azel_0601F93A(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr); -static int Azel_0601F948(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr); -static ALWAYS_INLINE int Azel_0601F950(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr, - const int32_t r8_x, const int32_t x_lim, - int base_cycles); -static int Azel_0601F988(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr); -static int Azel_0601F996(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr); -static ALWAYS_INLINE int Azel_0601F99E(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr, - const int32_t r8_y, const int32_t y_lim, - int base_cycles); -static int Azel_0601F9D6(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr); - -/*----------------------------------*/ - -static FASTCALL void Azel_0601E910(SH2State *state) -{ - return Azel_0601E910_common(state, Azel_0601F58A); -} - -static FASTCALL void Azel_0601E95A(SH2State *state) -{ - return Azel_0601E910_common(state, Azel_0601F5EE); -} - -static FASTCALL void Azel_0601EC20(SH2State *state) -{ - return Azel_0601EC20_common(state, Azel_0601F58A); -} - -static FASTCALL void Azel_0601EC3C(SH2State *state) -{ - return Azel_0601EC20_common(state, Azel_0601F5EE); -} - -static FASTCALL void Azel_0601F2D6(SH2State *state) -{ - return Azel_0601F2D6_common(state, Azel_0601F58A); -} - -static FASTCALL void Azel_0601F2F2(SH2State *state) -{ - return Azel_0601F2D6_common(state, Azel_0601F5EE); -} - -/*----------------------------------*/ - -static void Azel_0601E910_common(SH2State *state, - int (*clipfunc)(SH2State *state, uint32_t r11, uint32_t r13)) -{ - const uint32_t saved_PR = state->PR; - - uint32_t color_data = HRAM_LOADL(state->R[15], 4); - uint32_t index = 0; - uint32_t r11 = LRAM_LOADL(state->R[4], 0); - uint32_t r13 = LRAM_LOADL(state->R[4], 4); - state->R[4] += 8; - while (r11 != r13) { - const int swapflag = (*clipfunc)(state, r11, r13); - const int clipped = (swapflag < 0); - if (LRAM_LOADL(color_data, 0) == index) { - if (clipped) { - state->cycles += 25; - } else { - Azel_0601E9A4(state, color_data + 4, swapflag); - state->cycles += 21; - } - color_data += 16; - } else { - if (clipped) { - state->cycles += 19; - } else { - Azel_0601F49C(state, swapflag); - state->cycles += 20; - } - } - index++; - r11 = LRAM_LOADL(state->R[4], 0); - r13 = LRAM_LOADL(state->R[4], 4); - state->R[4] += 8; - } - - state->PC = saved_PR; - state->cycles += 11; -} - -static void Azel_0601E9A4(SH2State *state, const uint32_t color_data, - int swapflag) -{ - static const uint16_t cycles_used[4][4] = - {{13,13,13,13},{312,319,321,319},{315,322,324,322},{309,317,319,317}}; - - const int16_t *quad_data = (const int16_t *)LRAM_PTR(state->R[4]); - const int quad_type = (quad_data[-6] >> 8) & 3; - uint32_t *gbr_ptr = (uint32_t *)HRAM_PTR(state->GBR); - - state->cycles += cycles_used[quad_type][swapflag]; - - gbr_ptr[0] = RAM_SWAPL(state->R[14] + 32); - - if (quad_type == 0) { - return; - } - - const uint32_t color_addr = RAM_SWAPL(gbr_ptr[4]); - int16_t *out = (int16_t *)VDP1_PTR(color_addr); - gbr_ptr[4] = RAM_SWAPL(color_addr + 8); - VDP1_STOREW(state->R[14], 28, color_addr >> 3); - - const int16_t *base_ptr = - (const int16_t *)(HRAM_PTR(0x601FCB0) + (state->R[1]>>7 & -8)); - const int base_r = base_ptr[0]; - const int base_g = base_ptr[1]; - const int base_b = base_ptr[2]; - int a, b, c, d; - - switch (quad_type) { - case 1: - a = Azel_0601EB10(quad_data, color_data+0, base_r, base_g, base_b); - b = Azel_0601EB10(quad_data, color_data+3, base_r, base_g, base_b); - c = Azel_0601EB10(quad_data, color_data+6, base_r, base_g, base_b); - d = Azel_0601EB10(quad_data, color_data+9, base_r, base_g, base_b); - state->R[4] += 8; - break; - - case 2: - a = Azel_0601EB10(quad_data+0, color_data+0, base_r, base_g, base_b); - b = Azel_0601EB10(quad_data+6, color_data+3, base_r, base_g, base_b); - c = Azel_0601EB10(quad_data+12,color_data+6, base_r, base_g, base_b); - d = Azel_0601EB10(quad_data+18,color_data+9, base_r, base_g, base_b); - state->R[4] += 48; - break; - - default: // case 3 - a = Azel_0601EB10(quad_data+0, color_data+0, base_r, base_g, base_b); - b = Azel_0601EB10(quad_data+3, color_data+3, base_r, base_g, base_b); - c = Azel_0601EB10(quad_data+6, color_data+6, base_r, base_g, base_b); - d = Azel_0601EB10(quad_data+9, color_data+9, base_r, base_g, base_b); - state->R[4] += 24; - break; - } // switch (quad_type) - - out[0 ^ swapflag] = VDP_SWAPW(a); - out[1 ^ swapflag] = VDP_SWAPW(b); - out[2 ^ swapflag] = VDP_SWAPW(c); - out[3 ^ swapflag] = VDP_SWAPW(d); -} - -static int Azel_0601EB10(const int16_t *vertex_data, uint32_t color_data, - int base_r, int base_g, int base_b) -{ - return Azel_color_calc((const int16_t *)HRAM_PTR(0x601FC94), - vertex_data, - (const int16_t *)HRAM_PTR(0x601FCA8), - base_r + ((int8_t)LRAM_LOADB(color_data,2) << 8), - base_g + ((int8_t)LRAM_LOADB(color_data,1) << 8), - base_b + ((int8_t)LRAM_LOADB(color_data,0) << 8)); -} - -/*----------------------------------*/ - -static void Azel_0601EC20_common(SH2State *state, - int (*clipfunc)(SH2State *state, uint32_t r11, uint32_t r13)) -{ - const uint32_t saved_PR = state->PR; - - uint32_t r11 = LRAM_LOADL(state->R[4], 0); - uint32_t r13 = LRAM_LOADL(state->R[4], 4); - state->R[4] += 8; - while (r11 != r13) { - const int swapflag = (*clipfunc)(state, r11, r13); - const int clipped = (swapflag < 0); - if (clipped) { - state->cycles += 12; - } else { - Azel_0601EC58(state, swapflag); - state->cycles += 13; - } - r11 = LRAM_LOADL(state->R[4], 0); - r13 = LRAM_LOADL(state->R[4], 4); - state->R[4] += 8; - } - - state->PC = saved_PR; - state->cycles += 11; -} - -static void Azel_0601EC58(SH2State *state, int swapflag) -{ - static const uint16_t cycles_used[4][4] = - {{10,10,10,10}, {98,98,98,98}, {285,291,293,291}, {266,272,274,272}}; - - const int16_t *quad_data = (const int16_t *)LRAM_PTR(state->R[4]); - const int quad_type = (quad_data[-6] >> 8) & 3; - uint32_t *gbr_ptr = (uint32_t *)HRAM_PTR(state->GBR); - - state->cycles += cycles_used[quad_type][swapflag]; - - gbr_ptr[0] = RAM_SWAPL(state->R[14] - 32); - - if (quad_type == 0) { - return; - } - - const uint32_t color_addr = RAM_SWAPL(gbr_ptr[4]); - int16_t *out = (int16_t *)VDP1_PTR(color_addr); - gbr_ptr[4] = RAM_SWAPL(color_addr - 8); - VDP1_STOREW(state->R[14], 28, color_addr >> 3); - - const int16_t *base_ptr = - (const int16_t *)(HRAM_PTR(0x601EF2C) + (state->R[1]>>7 & -8)); - const int base_r = base_ptr[0]; - const int base_g = base_ptr[1]; - const int base_b = base_ptr[2]; - int a, b, c, d; - - switch (quad_type) { - case 1: - a = b = c = d = Azel_0601ED58(quad_data, base_r, base_g, base_b); - state->R[4] += 8; - break; - - case 2: - a = Azel_0601EDDC(quad_data+ 0, base_r, base_g, base_b); - b = Azel_0601EDDC(quad_data+ 6, base_r, base_g, base_b); - c = Azel_0601EDDC(quad_data+12, base_r, base_g, base_b); - d = Azel_0601EDDC(quad_data+18, base_r, base_g, base_b); - state->R[4] += 48; - break; - - default: // case 3 - a = Azel_0601ED58(quad_data+0, base_r, base_g, base_b); - b = Azel_0601ED58(quad_data+3, base_r, base_g, base_b); - c = Azel_0601ED58(quad_data+6, base_r, base_g, base_b); - d = Azel_0601ED58(quad_data+9, base_r, base_g, base_b); - state->R[4] += 24; - break; - } // switch (quad_type) - - out[0 ^ swapflag] = VDP_SWAPW(a); - out[1 ^ swapflag] = VDP_SWAPW(b); - out[2 ^ swapflag] = VDP_SWAPW(c); - out[3 ^ swapflag] = VDP_SWAPW(d); -} - -static int Azel_0601ED58(const int16_t *vertex_data, - int base_r, int base_g, int base_b) -{ - return Azel_color_calc((const int16_t *)HRAM_PTR(0x601EF10), - vertex_data, - (const int16_t *)HRAM_PTR(0x601EF24), - base_r, base_g, base_b); -} - -static int Azel_0601EDDC(const int16_t *vertex_data, - int base_r, int base_g, int base_b) -{ - return Azel_color_calc((const int16_t *)HRAM_PTR(0x601EF10), - vertex_data, - (const int16_t *)HRAM_PTR(0x601EF24), - base_r + vertex_data[5], - base_g + vertex_data[4], - base_b + vertex_data[3]); -} - -/*----------------------------------*/ - -static void Azel_0601F2D6_common(SH2State *state, - int (*clipfunc)(SH2State *state, uint32_t r11, uint32_t r13)) -{ - const uint32_t saved_PR = state->PR; - - uint32_t r11 = LRAM_LOADL(state->R[4], 0); - uint32_t r13 = LRAM_LOADL(state->R[4], 4); - state->R[4] += 8; - while (r11 != r13) { - const int swapflag = (*clipfunc)(state, r11, r13); - const int clipped = (swapflag < 0); - if (clipped) { - state->cycles += 12; - } else { - Azel_0601F49C(state, swapflag); - state->cycles += 13; - } - r11 = LRAM_LOADL(state->R[4], 0); - r13 = LRAM_LOADL(state->R[4], 4); - state->R[4] += 8; - } - - state->PC = saved_PR; - state->cycles += 11; -} - -static void Azel_0601F49C(SH2State *state, int swapflag) -{ - static const uint16_t cycles_used[4][4] = - {{10,10,10,10}, {98,98,98,98}, {285,291,293,291}, {266,272,274,272}}; - - const int16_t *quad_data = (const int16_t *)LRAM_PTR(state->R[4]); - const int quad_type = (quad_data[-6] >> 8) & 3; - uint32_t *gbr_ptr = (uint32_t *)HRAM_PTR(state->GBR); - - state->cycles += cycles_used[quad_type][swapflag]; - - gbr_ptr[0] = RAM_SWAPL(state->R[14] + 32); - - if (quad_type == 0) { - return; - } - - const uint32_t color_addr = RAM_SWAPL(gbr_ptr[4]); - int16_t *out = (int16_t *)VDP1_PTR(color_addr); - gbr_ptr[4] = RAM_SWAPL(color_addr + 8); - VDP1_STOREW(state->R[14], 28, color_addr >> 3); - - const int16_t *base_ptr = - (const int16_t *)(HRAM_PTR(0x601FCB0) + (state->R[1]>>7 & -8)); - const int base_r = base_ptr[0]; - const int base_g = base_ptr[1]; - const int base_b = base_ptr[2]; - int a, b, c, d; - - switch (quad_type) { - case 1: - a = b = c = d = Azel_0601FA68(quad_data, base_r, base_g, base_b); - state->R[4] += 8; - break; - - case 2: - a = Azel_0601FAEC(quad_data+ 0, base_r, base_g, base_b); - b = Azel_0601FAEC(quad_data+ 6, base_r, base_g, base_b); - c = Azel_0601FAEC(quad_data+12, base_r, base_g, base_b); - d = Azel_0601FAEC(quad_data+18, base_r, base_g, base_b); - state->R[4] += 48; - break; - - default: // case 3 - a = Azel_0601FA68(quad_data+0, base_r, base_g, base_b); - b = Azel_0601FA68(quad_data+3, base_r, base_g, base_b); - c = Azel_0601FA68(quad_data+6, base_r, base_g, base_b); - d = Azel_0601FA68(quad_data+9, base_r, base_g, base_b); - state->R[4] += 24; - break; - } // switch (quad_type) - - out[0 ^ swapflag] = VDP_SWAPW(a); - out[1 ^ swapflag] = VDP_SWAPW(b); - out[2 ^ swapflag] = VDP_SWAPW(c); - out[3 ^ swapflag] = VDP_SWAPW(d); -} - -static int Azel_0601FA68(const int16_t *vertex_data, - int base_r, int base_g, int base_b) -{ - return Azel_color_calc((const int16_t *)HRAM_PTR(0x601FC94), - vertex_data, - (const int16_t *)HRAM_PTR(0x601FCA8), - base_r, base_g, base_b); -} - -static int Azel_0601FAEC(const int16_t *vertex_data, - int base_r, int base_g, int base_b) -{ - return Azel_color_calc((const int16_t *)HRAM_PTR(0x601FC94), - vertex_data, - (const int16_t *)HRAM_PTR(0x601FCA8), - base_r + vertex_data[5], - base_g + vertex_data[4], - base_b + vertex_data[3]); -} - -/*----------------------------------*/ - -static int Azel_0601F58A(SH2State *state, uint32_t r11, uint32_t r13) -{ - r11 <<= 3; - r13 <<= 3; - const uint32_t r7 = state->R[7]; - const int16_t *r10_ptr = (const int16_t *)HRAM_PTR(r7 + (r11 >> 16)); - const int16_t *r11_ptr = (const int16_t *)HRAM_PTR(r7 + (r11 & 0xFFFF)); - const int16_t *r12_ptr = (const int16_t *)HRAM_PTR(r7 + (r13 >> 16)); - const int16_t *r13_ptr = (const int16_t *)HRAM_PTR(r7 + (r13 & 0xFFFF)); - return Azel_0601F5A6(state, r10_ptr, r11_ptr, r12_ptr, r13_ptr); -} - -static int Azel_0601F5A6(SH2State *state, - const int16_t *r10_ptr, const int16_t *r11_ptr, - const int16_t *r12_ptr, const int16_t *r13_ptr) -{ - const int32_t a = (r13_ptr[1] - r11_ptr[1]) * (r12_ptr[0] - r10_ptr[0]); - const int32_t b = (r12_ptr[1] - r10_ptr[1]) * (r13_ptr[0] - r11_ptr[0]); - if (b > a) { - state->cycles += 35; - return Azel_0601F5D2(state); - } - - const int swapflag = 0; - - state->R[14] = HRAM_LOADL(state->GBR, 0); - uint32_t *r14_ptr = (uint32_t *)VDP1_PTR(state->R[14]); - - r14_ptr[3] = RAM_VDP_SWAPL(*(const uint32_t *)r10_ptr); - r14_ptr[4] = RAM_VDP_SWAPL(*(const uint32_t *)r11_ptr); - r14_ptr[5] = RAM_VDP_SWAPL(*(const uint32_t *)r12_ptr); - r14_ptr[6] = RAM_VDP_SWAPL(*(const uint32_t *)r13_ptr); - - const uint32_t r4_0 = LRAM_LOADL(state->R[4], 0); - - state->cycles += 49; - return Azel_0601F762(state, - (const uint32_t *)r10_ptr, - (const uint32_t *)r11_ptr, - (const uint32_t *)r12_ptr, - (const uint32_t *)r13_ptr, - r14_ptr, r4_0, swapflag); -} - -static int Azel_0601F5D2(SH2State *state) -{ - static const uint8_t r4ofs_cycles[8] = { - 12, 20, 60, 36, // R4 offset (polygon data size) - 10, 12, 15, 15, // Cycle count - }; - const unsigned int quad_type = (LRAM_LOADW(state->R[4], 0) >> 8) & 0x3; - state->R[4] += r4ofs_cycles[quad_type]; - state->cycles += r4ofs_cycles[quad_type+4]; - return -1; -} - -/*----------------------------------*/ - -static int Azel_0601F5EE(SH2State *state, uint32_t r11, uint32_t r13) -{ - uint32_t cycles = state->cycles; - - r11 <<= 5; - r13 <<= 5; - const uint32_t r7 = state->R[7]; - uint32_t *r10_ptr = (uint32_t *)HRAM_PTR(r7 + (r11 >> 16)); - uint32_t *r11_ptr = (uint32_t *)HRAM_PTR(r7 + (r11 & 0xFFFF)); - uint32_t *r12_ptr = (uint32_t *)HRAM_PTR(r7 + (r13 >> 16)); - uint32_t *r13_ptr = (uint32_t *)HRAM_PTR(r7 + (r13 & 0xFFFF)); - - if (r10_ptr[6] & r11_ptr[6] & r12_ptr[6] & r13_ptr[6]) { - state->cycles = cycles + 27; - return Azel_0601F5D2(state); - } - if ((r10_ptr[6] | r11_ptr[6] | r12_ptr[6] | r13_ptr[6]) & RAM_SWAPL(0x20)) { - state->cycles = cycles + 33; - return Azel_0601F5D2(state); - } - if (!(r10_ptr[6] | r11_ptr[6] | r12_ptr[6] | r13_ptr[6])) { - state->cycles = cycles + 35 - 14; - return Azel_0601F5A6(state, - (const int16_t *)r10_ptr, - (const int16_t *)r11_ptr, - (const int16_t *)r12_ptr, - (const int16_t *)r13_ptr); - } - - r10_ptr[7] = r10_ptr[6]; - r11_ptr[7] = r11_ptr[6]; - r12_ptr[7] = r12_ptr[6]; - r13_ptr[7] = r13_ptr[6]; - r10_ptr[4] = RAM_SWAPL((int32_t)((int16_t *)r10_ptr)[0]); - r10_ptr[5] = RAM_SWAPL((int32_t)((int16_t *)r10_ptr)[1]); - r11_ptr[4] = RAM_SWAPL((int32_t)((int16_t *)r11_ptr)[0]); - r11_ptr[5] = RAM_SWAPL((int32_t)((int16_t *)r11_ptr)[1]); - r12_ptr[4] = RAM_SWAPL((int32_t)((int16_t *)r12_ptr)[0]); - r12_ptr[5] = RAM_SWAPL((int32_t)((int16_t *)r12_ptr)[1]); - r13_ptr[4] = RAM_SWAPL((int32_t)((int16_t *)r13_ptr)[0]); - r13_ptr[5] = RAM_SWAPL((int32_t)((int16_t *)r13_ptr)[1]); - - const int16_t * const r6_ptr = (const int16_t *)HRAM_PTR(state->R[6]); - int32_t result = Azel_0601F824(r6_ptr, r10_ptr, r11_ptr, r12_ptr, r13_ptr, - 0x10, Azel_0601F9D6); - cycles += result & 0xFFFF; - if (result < 0) { - state->cycles = cycles + 61; - return Azel_0601F5D2(state); - } - - const int32_t r10_x = RAM_SWAPL(r10_ptr[4]); - const int32_t r11_x = RAM_SWAPL(r11_ptr[4]); - const int32_t r12_x = RAM_SWAPL(r12_ptr[4]); - const int32_t r13_x = RAM_SWAPL(r13_ptr[4]); - const int32_t r10_y = RAM_SWAPL(r10_ptr[5]); - const int32_t r11_y = RAM_SWAPL(r11_ptr[5]); - const int32_t r12_y = RAM_SWAPL(r12_ptr[5]); - const int32_t r13_y = RAM_SWAPL(r13_ptr[5]); - int32_t r0 = (r13_y - r11_y) * (r12_x - r10_x); - int32_t r2 = (r12_y - r10_y) * (r13_x - r11_x); - if (r2 > r0) { - state->cycles = cycles + 79; - return Azel_0601F5D2(state); - } - - result = Azel_0601F824(r6_ptr, r10_ptr, r11_ptr, r12_ptr, r13_ptr, - 0x1, Azel_0601F948); - cycles += result & 0xFFFF; - if (result < 0) { - state->cycles = cycles + 84; - return Azel_0601F5D2(state); - } - result = Azel_0601F824(r6_ptr, r10_ptr, r11_ptr, r12_ptr, r13_ptr, - 0x2, Azel_0601F93A); - cycles += result & 0xFFFF; - if (result < 0) { - state->cycles = cycles + 89; - return Azel_0601F5D2(state); - } - result = Azel_0601F824(r6_ptr, r10_ptr, r11_ptr, r12_ptr, r13_ptr, - 0x4, Azel_0601F996); - cycles += result & 0xFFFF; - if (result < 0) { - state->cycles = cycles + 94; - return Azel_0601F5D2(state); - } - result = Azel_0601F824(r6_ptr, r10_ptr, r11_ptr, r12_ptr, r13_ptr, - 0x8, Azel_0601F988); - cycles += result & 0xFFFF; - if (result < 0) { - state->cycles = cycles + 99; - return Azel_0601F5D2(state); - } - - int swapflag; - uint32_t r4_0 = LRAM_LOADL(state->R[4], 0); - if (r10_ptr[7]) { - if (r11_ptr[7]) { - if (r12_ptr[7]) { - if (r13_ptr[7]) { - swapflag = 0; - cycles += 116; - } else { - uint32_t *temp1, *temp2; - temp1 = r10_ptr; temp2 = r13_ptr; - r10_ptr = temp2; r13_ptr = temp1; - temp1 = r11_ptr; temp2 = r12_ptr; - r11_ptr = temp2; r12_ptr = temp1; - r4_0 ^= 0x20; - swapflag = 3; - cycles += 124; - } - } else { - uint32_t *temp1, *temp2; - temp1 = r10_ptr; temp2 = r12_ptr; - r10_ptr = temp2; r12_ptr = temp1; - temp1 = r11_ptr; temp2 = r13_ptr; - r11_ptr = temp2; r13_ptr = temp1; - r4_0 ^= 0x30; - swapflag = 2; - cycles += 123; - } - } else { - uint32_t *temp1, *temp2; - temp1 = r10_ptr; temp2 = r11_ptr; - r10_ptr = temp2; r11_ptr = temp1; - temp1 = r12_ptr; temp2 = r13_ptr; - r12_ptr = temp2; r13_ptr = temp1; - r4_0 ^= 0x10; - swapflag = 1; - cycles += 120; - } - } else { - swapflag = 0; - cycles += 105; - } - - state->R[14] = HRAM_LOADL(state->GBR, 0); - uint32_t *r14_ptr = (uint32_t *)VDP1_PTR(state->R[14]); - - const uint16_t *r10_ptr16 = (const uint16_t *)r10_ptr; - const uint16_t *r11_ptr16 = (const uint16_t *)r11_ptr; - const uint16_t *r12_ptr16 = (const uint16_t *)r12_ptr; - const uint16_t *r13_ptr16 = (const uint16_t *)r13_ptr; - r14_ptr[3] = VDP_SWAPL(r10_ptr16[9]<<16 | r10_ptr16[11]); - r14_ptr[4] = VDP_SWAPL(r11_ptr16[9]<<16 | r11_ptr16[11]); - r14_ptr[5] = VDP_SWAPL(r12_ptr16[9]<<16 | r12_ptr16[11]); - r14_ptr[6] = VDP_SWAPL(r13_ptr16[9]<<16 | r13_ptr16[11]); - - state->cycles = cycles + 24; - return Azel_0601F762(state, r10_ptr, r11_ptr, r12_ptr, r13_ptr, - r14_ptr, r4_0, swapflag); -} - -/*----------------------------------*/ - -static ALWAYS_INLINE int Azel_0601F762( - SH2State *state, const uint32_t * const r10_ptr, - const uint32_t * const r11_ptr, const uint32_t * const r12_ptr, - const uint32_t * const r13_ptr, uint32_t * const r14_ptr, - const uint32_t r4_0, const int swapflag) -{ - const uint32_t r4_1 = LRAM_LOADL(state->R[4], 4); - const uint32_t r4_2 = LRAM_LOADL(state->R[4], 8); - state->R[4] += 12; - - *(uint16_t *)&r14_ptr[0] = VDP_SWAPW(r4_0 | 0x1000); - r14_ptr[1] = VDP_SWAPL(r4_1); - r14_ptr[2] = VDP_SWAPL(r4_2); - - int32_t r1 = RAM_SWAPL(r10_ptr[1]); - int32_t r2 = RAM_SWAPL(r11_ptr[1]); - int32_t r3 = RAM_SWAPL(r12_ptr[1]); - int32_t r5 = RAM_SWAPL(r13_ptr[1]); - const uint32_t out_addr = HRAM_LOADL(state->GBR, 32); - uint16_t *out_ptr = (uint16_t *)HRAM_PTR(out_addr); - const int32_t mult = HRAM_LOADL(state->R[6], 52); - - switch (r4_0 >> 28) { - case 0: - r1 = MAX(MAX(r1, r2), MAX(r3, r5)); - state->cycles += 21; - l_601F7F4: - r1 = ((int64_t)r1 * (int64_t)mult) >> 32; - if (r1 <= 0) { - r1 = 1; - } - out_ptr[2] = r1; - out_ptr[3] = (uint16_t)(state->R[14] >> 3); - state->cycles += 15; - break; - - default: // case 1 - r1 = MIN(MIN(r1, r2), MIN(r3, r5)); - state->cycles += 21; - goto l_601F7F4; - - case 2: - r2 -= r1; - r3 -= r1; - r5 -= r1; - r2 += r3 + r5; - r1 += r2 >> 2; - state->cycles += 18; - goto l_601F7F4; - - case 3: - r2 -= r1; - r3 -= r1; - r5 -= r1; - r2 += r3 + r5; - r1 += r2 >> 2; - r1 = ((int64_t)r1 * (int64_t)mult) >> 32; - if (r1 <= 0) { - r1 = 1; - } - out_ptr[2] = 0x7FFF; - out_ptr[3] = (uint16_t)(state->R[14] >> 3); - state->cycles += 25; - break; - } // switch (r4_0 >> 28) - - /* 0x601F810 */ - - HRAM_STOREL(state->GBR, 32, out_addr + 8); - HRAM_STOREL(state->GBR, 12, HRAM_LOADL(state->GBR, 12) + 1); - HRAM_STOREL(state->GBR, 28, HRAM_LOADL(state->GBR, 28) + 1); - state->R[1] = r1; - state->cycles += 8 + 11; - return swapflag; -} - -/*----------------------------------*/ - -static int32_t Azel_0601F824(const int16_t *r6_ptr, uint32_t *r10_ptr, - uint32_t *r11_ptr, uint32_t *r12_ptr, - uint32_t *r13_ptr, uint32_t mask, - int (*clipfunc)(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr)) -{ - int32_t cycles = 0; - - /* We save a bit of time by byte-swapping just this value and loading - * the values to check directly from native memory. */ - mask = RAM_SWAPL(mask); - const uint32_t r10_check = r10_ptr[7] & mask; - const uint32_t r11_check = r11_ptr[7] & mask; - const uint32_t r12_check = r12_ptr[7] & mask; - const uint32_t r13_check = r13_ptr[7] & mask; - - if (r13_check) { - if (r12_check) { - cycles += 10; - if (r11_check) { - if (r10_check) { - cycles += 20; - return 0x80000000 | cycles; - } else { - cycles += (*clipfunc)(r11_ptr, r10_ptr, r6_ptr); - cycles += (*clipfunc)(r12_ptr, r10_ptr, r6_ptr); - cycles += (*clipfunc)(r13_ptr, r10_ptr, r6_ptr); - cycles += 27; - return cycles; - } - } else if (r10_check) { - cycles += (*clipfunc)(r10_ptr, r11_ptr, r6_ptr); - cycles += (*clipfunc)(r13_ptr, r11_ptr, r6_ptr); - cycles += (*clipfunc)(r12_ptr, r11_ptr, r6_ptr); - cycles += 28; - return cycles; - } else { - cycles += (*clipfunc)(r13_ptr, r10_ptr, r6_ptr); - cycles += (*clipfunc)(r12_ptr, r11_ptr, r6_ptr); - cycles += 24; - return cycles; - } - } else if (r11_check) { - if (r10_check) { - cycles += (*clipfunc)(r10_ptr, r12_ptr, r6_ptr); - cycles += (*clipfunc)(r13_ptr, r12_ptr, r6_ptr); - cycles += (*clipfunc)(r11_ptr, r12_ptr, r6_ptr); - cycles += 28; - return cycles; - } else { - cycles += 17; - return 0x80000000 | cycles; - } - } else if (r10_check) { - cycles += (*clipfunc)(r10_ptr, r11_ptr, r6_ptr); - cycles += (*clipfunc)(r13_ptr, r12_ptr, r6_ptr); - cycles += 25; - return cycles; - } else { - const int32_t r1 = RAM_SWAPL(r12_ptr[1]); - const int32_t r2 = RAM_SWAPL(r10_ptr[1]); - cycles += (r1 > r2) ? 23 : 21; - cycles += (*clipfunc)(r13_ptr, (r1 > r2) ? r12_ptr : r10_ptr, - r6_ptr); - return cycles; - } - - } else if (r12_check) { - if (r11_check) { - if (r10_check) { - cycles += (*clipfunc)(r11_ptr, r13_ptr, r6_ptr); - cycles += (*clipfunc)(r12_ptr, r13_ptr, r6_ptr); - cycles += (*clipfunc)(r10_ptr, r13_ptr, r6_ptr); - cycles += 28; - return cycles; - } else { - cycles += (*clipfunc)(r11_ptr, r10_ptr, r6_ptr); - cycles += (*clipfunc)(r12_ptr, r13_ptr, r6_ptr); - cycles += 24; - return cycles; - } - } else if (r10_check) { - cycles += 18; - return 0x80000000 | cycles; - } else { - const int32_t r1 = RAM_SWAPL(r13_ptr[1]); - const int32_t r2 = RAM_SWAPL(r11_ptr[1]); - cycles += (r1 > r2) ? 23 : 21; - cycles += (*clipfunc)(r12_ptr, (r1 > r2) ? r13_ptr : r11_ptr, - r6_ptr); - return cycles; - } - - } else if (r11_check) { - if (r10_check) { - cycles += (*clipfunc)(r10_ptr, r13_ptr, r6_ptr); - cycles += (*clipfunc)(r11_ptr, r12_ptr, r6_ptr); - cycles += 25; - return cycles; - } else { - const int32_t r1 = RAM_SWAPL(r10_ptr[1]); - const int32_t r2 = RAM_SWAPL(r12_ptr[1]); - cycles += (r1 > r2) ? 23 : 21; - cycles += (*clipfunc)(r11_ptr, (r1 > r2) ? r10_ptr : r12_ptr, - r6_ptr); - return cycles; - } - - } else if (r10_check) { - const int32_t r1 = RAM_SWAPL(r11_ptr[1]); - const int32_t r2 = RAM_SWAPL(r13_ptr[1]); - cycles += (r1 > r2) ? 24 : 22; - cycles += (*clipfunc)(r10_ptr, (r1 > r2) ? r11_ptr : r13_ptr, r6_ptr); - return cycles; - - } else { - cycles += 15; - return cycles; - } -} - -/*----------------------------------*/ - -static int Azel_0601F93A(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr) -{ - const int32_t r8_x = RAM_SWAPL(r8_ptr[4]); - const int32_t x_max = r6_ptr[3]; - if (r8_x <= x_max) { - return 8; - } - return Azel_0601F950(r8_ptr, r9_ptr, r6_ptr, r8_x, x_max, 6); -} - -static int Azel_0601F948(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr) -{ - const int32_t r8_x = RAM_SWAPL(r8_ptr[4]); - const int32_t x_min = r6_ptr[2]; - if (r8_x >= x_min) { - return 10; - } - return Azel_0601F950(r8_ptr, r9_ptr, r6_ptr, r8_x, x_min, 4); -} - -static ALWAYS_INLINE int Azel_0601F950(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr, - const int32_t r8_x, const int32_t x_lim, - int base_cycles) -{ - r8_ptr[4] = RAM_SWAPL(x_lim); - const int32_t dx_lim = x_lim - r8_x; - const int32_t dx_r9 = RAM_SWAPL(r9_ptr[4]) - r8_x; - int32_t frac8; - if (UNLIKELY(dx_r9 == 0)) { - frac8 = (dx_lim >= 0) ? 0xFF : 0; - } else { - frac8 = bound((dx_lim << 8) / dx_r9, 0, 255); - } - const int32_t r8_y = RAM_SWAPL(r8_ptr[5]); - const int32_t r9_y = RAM_SWAPL(r9_ptr[5]); - const int32_t new_r8_y = (int16_t)(r8_y + (((r9_y - r8_y) * frac8) >> 8)); - r8_ptr[5] = RAM_SWAPL(new_r8_y); - - return 29 + base_cycles; -} - -/*----------------------------------*/ - -static int Azel_0601F988(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr) -{ - const int32_t r8_y = RAM_SWAPL(r8_ptr[5]); - const int32_t y_max = r6_ptr[0]; - if (r8_y <= y_max) { - return 8; - } - return Azel_0601F99E(r8_ptr, r9_ptr, r6_ptr, r8_y, y_max, 6); -} - -static int Azel_0601F996(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr) -{ - const int32_t r8_y = RAM_SWAPL(r8_ptr[5]); - const int32_t y_min = r6_ptr[1]; - if (r8_y >= y_min) { - return 10; - } - return Azel_0601F99E(r8_ptr, r9_ptr, r6_ptr, r8_y, y_min, 4); -} - -static ALWAYS_INLINE int Azel_0601F99E(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr, - const int32_t r8_y, const int32_t y_lim, - int base_cycles) -{ - r8_ptr[5] = RAM_SWAPL(y_lim); - const int32_t dy_lim = y_lim - r8_y; - const int32_t dy_r9 = RAM_SWAPL(r9_ptr[5]) - r8_y; - int32_t frac8; - if (UNLIKELY(dy_r9 == 0)) { - frac8 = (dy_lim >= 0) ? 0xFF : 0; - } else { - frac8 = bound((dy_lim << 8) / dy_r9, 0, 255); - } - const int32_t r8_x = RAM_SWAPL(r8_ptr[4]); - const int32_t r9_x = RAM_SWAPL(r9_ptr[4]); - const int32_t new_r8_x = (int16_t)(r8_x + (((r9_x - r8_x) * frac8) >> 8)); - r8_ptr[4] = RAM_SWAPL(new_r8_x); - - return 29 + base_cycles; -} - -/*----------------------------------*/ - -static int Azel_0601F9D6(uint32_t *r8_ptr, uint32_t *r9_ptr, - const int16_t *r6_ptr) -{ - const int32_t *r6_ptr32 = (const int32_t *)r6_ptr; - int32_t r3 = RAM_SWAPL(r8_ptr[1]); - int32_t r0 = (RAM_SWAPL(r6_ptr32[4]) << 8) - r3; - int32_t r2 = RAM_SWAPL(r9_ptr[1]) - r3; - const float frac = (float)r0 / (float)r2; - r2 = RAM_SWAPL(r9_ptr[2]); - r0 = RAM_SWAPL(r8_ptr[2]); - r2 = r0 + (int32_t)((r2 - r0) * frac); - r3 = RAM_SWAPL(r9_ptr[3]); - r0 = RAM_SWAPL(r8_ptr[3]); - r3 = r0 + (int32_t)((r3 - r0) * frac); - const int32_t mult = RAM_SWAPL(r6_ptr32[12]); - r2 = ((int64_t)r2 * (int64_t)mult) >> 32; - r3 = ((int64_t)r3 * (int64_t)mult) >> 32; - r8_ptr[4] = RAM_SWAPL(r2); - r8_ptr[5] = RAM_SWAPL(r3); - - const uint32_t r1 = (r3 > r6_ptr[4]) << 3 - | (r3 < r6_ptr[5]) << 2 - | (r2 > r6_ptr[7]) << 1 - | (r2 < r6_ptr[6]) << 0; - r8_ptr[7] = RAM_SWAPL(r1); - - return 73; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x601EE60: Coordinate transformation routine whose second instruction is - * modified from 0x601F1{20,40}; we detect the change here and hint - * 0x601EE62 as a data pointer to avoid having to repeatedly translate the - * block. Incidentally, 0x601F1{20,40} are themselves called from (among - * other places) 0x601F1{50,5E,6C}, which _push and pop_ the _instruction - * word_. Good grief... */ - -static FASTCALL void Azel_0601EE60(SH2State *state) -{ - const uint16_t insn = HRAM_LOADW(0x601EE62, 0); - if (insn>>12 == 0xA) { // BRA instruction - state->R[0] = 0x601EF10; - state->MACL = state->MACH = 0; - state->PC += 6 + ((int32_t)(insn<<20) >> 19); - state->cycles += 4; - } else { - if (insn != 0x6103) { - DMSG("WARNING: Wrong instruction at 0x601EE62 (%04X)", insn); - } - const int32_t *M_ptr = - state->R[5] & 0x6000000 ? (int32_t *)HRAM_PTR(state->R[5]) - : (int32_t *)LRAM_PTR(state->R[5]); - const int32_t in_x = HRAM_LOADL(0x601EF18, 0); - const int32_t in_y = HRAM_LOADL(0x601EF18, 4); - const int32_t in_z = HRAM_LOADL(0x601EF18, 8); - int16_t out_x = (RAM_SWAPL(M_ptr[ 0]) * in_x - + RAM_SWAPL(M_ptr[ 4]) * in_y - + RAM_SWAPL(M_ptr[ 8]) * in_z) >> 16; - int16_t out_y = (RAM_SWAPL(M_ptr[ 1]) * in_x - + RAM_SWAPL(M_ptr[ 5]) * in_y - + RAM_SWAPL(M_ptr[ 9]) * in_z) >> 16; - int16_t out_z = (RAM_SWAPL(M_ptr[ 2]) * in_x - + RAM_SWAPL(M_ptr[ 6]) * in_y - + RAM_SWAPL(M_ptr[10]) * in_z) >> 16; - HRAM_STOREW(0x601EF10, 0, out_x); - HRAM_STOREW(0x601EF10, 2, out_y); - HRAM_STOREW(0x601EF10, 4, out_z); - state->PC = state->PR; - state->cycles += 58; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x601EEE8: Routine that writes a local data array in a loop; optimized - * to prevent JIT overwrite checks from flooding the blacklist array. An - * identical routine is located at 0x601FC6C; this code is used for both. */ - -static FASTCALL void Azel_0601EEE8(SH2State *state) -{ - const int r = (state->R[4]>> 0 & 0xFF) << 8; - const int g = (state->R[4]>> 8 & 0xFF) << 8; - const int b = (state->R[4]>>16 & 0xFF) << 8; - int16_t *out = (int16_t *)HRAM_PTR(((state->PC + 8*2) & -4) + 4 + 0xC*4); - int16_t *top = out + 32*4; - for (; out != top; out += 4) { - out[0] = r; - out[1] = g; - out[2] = b; - } - state->PC = state->PR; - state->cycles += 14 + 32*7; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x601F240, 0x601F24C: Calculation function */ - -static ALWAYS_INLINE void Azel_0601F24E(SH2State *state, int32_t r2); - -/*----------------------------------*/ - -static FASTCALL void Azel_0601F240(SH2State *state) -{ - const int32_t r2 = LRAM_LOADL(state->R[4], 0); - state->cycles += 8; - return Azel_0601F24E(state, - ((int64_t)r2 * (int64_t)(int32_t)state->R[8]) >> 16); -} - -static FASTCALL void Azel_0601F24C(SH2State *state) -{ - const int32_t r2 = LRAM_LOADL(state->R[4], 0); - return Azel_0601F24E(state, r2); -} - -static ALWAYS_INLINE void Azel_0601F24E(SH2State *state, int32_t r2) -{ - uint32_t r0; - int32_t r8, r9; - int32_t r1 = HRAM_LOADL(state->R[5], 44); - int32_t r3 = HRAM_LOADL(state->R[6], 20); - if (r1 - r2 >= r3) { - state->SR |= SR_T; - state->PC = state->PR; - state->cycles += 12; - return; - } - int32_t r10 = HRAM_LOADL(state->R[6], 16); - if (r1 + r2 < r10) { - state->SR |= SR_T; - state->PC = state->PR; - state->cycles += 17; - return; - } - r0 = (r1 + r2 >= r3) << 5 - | (r1 - r2 < r10) << 4; - -#if defined(__mips__) - int32_t temp; - asm(".set push; .set noreorder\n" - "lw %[r8], 36(%[r6])\n" - "lw %[r9], 32(%[r6])\n" - "lw %[r3], 28(%[r5])\n" - "ror %[r8], %[r8], 16\n" - "mult %[r8], %[r1]\n" - "ror %[r9], %[r9], 16\n" - "ror %[r3], %[r3], 16\n" - "mflo %[r8]\n" - "mfhi %[temp]\n" - "mult %[r9], %[r2]\n" - "srl %[r8], %[r8], 16\n" - "ins %[r8], %[temp], 16, 16\n" - "mflo %[r9]\n" - "mfhi %[temp]\n" - "srl %[r9], %[r9], 16\n" - "ins %[r9], %[temp], 16, 16\n" - ".set pop" - : [r3] "=&r" (r3), [r8] "=&r" (r8), [r9] "=&r" (r9), - [temp] "=&r" (temp) - : [r5] "r" (HRAM_PTR(state->R[5])), [r6] "r" (HRAM_PTR(state->R[6])), - [r1] "r" (r1), [r2] "r" (r2) - ); -#else - r3 = HRAM_LOADL(state->R[5], 28); - r8 = HRAM_LOADL(state->R[6], 36); - r9 = HRAM_LOADL(state->R[6], 32); - r8 = ((int64_t)r8 * (int64_t)r1) >> 16; - r9 = ((int64_t)r9 * (int64_t)r2) >> 16; -#endif - if (r8 + r9 < r3) { - state->SR |= SR_T; - state->PC = state->PR; - state->cycles += 41; - return; - } - if (r8 + r9 < -r3) { - state->SR |= SR_T; - state->PC = state->PR; - state->cycles += 44; - return; - } - r0 |= (r8 - r9 < r3) << 3 - | (r8 - r9 < -r3) << 2; - -#if defined(__mips__) - asm(".set push; .set noreorder\n" - "lw %[r8], 44(%[r6])\n" - "lw %[r9], 40(%[r6])\n" - "lw %[r3], 12(%[r5])\n" - "ror %[r8], %[r8], 16\n" - "mult %[r8], %[r1]\n" - "ror %[r9], %[r9], 16\n" - "ror %[r3], %[r3], 16\n" - "mflo %[r8]\n" - "mfhi %[temp]\n" - "mult %[r9], %[r2]\n" - "srl %[r8], %[r8], 16\n" - "ins %[r8], %[temp], 16, 16\n" - "mflo %[r9]\n" - "mfhi %[temp]\n" - "srl %[r9], %[r9], 16\n" - "ins %[r9], %[temp], 16, 16\n" - ".set pop" - : [r3] "=&r" (r3), [r8] "=&r" (r8), [r9] "=&r" (r9), - [temp] "=&r" (temp) - : [r5] "r" (HRAM_PTR(state->R[5])), [r6] "r" (HRAM_PTR(state->R[6])), - [r1] "r" (r1), [r2] "r" (r2) - ); -#else - r3 = HRAM_LOADL(state->R[5], 12); - r8 = HRAM_LOADL(state->R[6], 44); - r9 = HRAM_LOADL(state->R[6], 40); - r8 = ((int64_t)r8 * (int64_t)r1) >> 16; - r9 = ((int64_t)r9 * (int64_t)r2) >> 16; -#endif - if (r8 + r9 < r3) { - state->SR |= SR_T; - state->PC = state->PR; - state->cycles += 69; - return; - } - if (r8 + r9 < -r3) { - state->SR |= SR_T; - state->PC = state->PR; - state->cycles += 72; - return; - } - r0 |= (r8 - r9 < r3) << 1 - | (r8 - r9 < -r3) << 0; - - state->R[0] = r0; - state->SR &= ~SR_T; - state->PC = state->PR; - state->cycles += 76; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x601F30E: Coordinate transform routine */ - -static FASTCALL void Azel_0601F30E(SH2State *state) -{ - const int32_t *r4_ptr = state->R[4] & 0x06000000 - ? (const int32_t *)HRAM_PTR(state->R[4]) - : (const int32_t *)LRAM_PTR(state->R[4]); - const int32_t *r5_ptr = (const int32_t *)HRAM_PTR(state->R[5]); - const int32_t *r6_ptr = (const int32_t *)HRAM_PTR(state->R[6]); - - /* 0x601F38E */ - - const int32_t r6_x = RAM_SWAPL(r6_ptr[6]); - const int32_t M11 = (r6_x * (int32_t)RAM_SWAPL(r5_ptr[0])) >> 12; - const int32_t M12 = (r6_x * (int32_t)RAM_SWAPL(r5_ptr[1])) >> 12; - const int32_t M13 = (r6_x * (int32_t)RAM_SWAPL(r5_ptr[2])) >> 12; - const int32_t M14 = r6_x * (int32_t)RAM_SWAPL(r5_ptr[3]); - - const int32_t r6_y = -RAM_SWAPL(r6_ptr[7]); - const int32_t M21 = (r6_y * (int32_t)RAM_SWAPL(r5_ptr[4])) >> 12; - const int32_t M22 = (r6_y * (int32_t)RAM_SWAPL(r5_ptr[5])) >> 12; - const int32_t M23 = (r6_y * (int32_t)RAM_SWAPL(r5_ptr[6])) >> 12; - const int32_t M24 = r6_y * (int32_t)RAM_SWAPL(r5_ptr[7]); - - const int32_t M31 = (int32_t)RAM_SWAPL(r5_ptr[ 8]) >> 4; - const int32_t M32 = (int32_t)RAM_SWAPL(r5_ptr[ 9]) >> 4; - const int32_t M33 = (int32_t)RAM_SWAPL(r5_ptr[10]) >> 4; - const int32_t M34 = (int32_t)RAM_SWAPL(r5_ptr[11]) << 8; - - uint32_t counter = RAM_SWAPL(r4_ptr[1]); - const uint32_t in_address = RAM_SWAPL(r4_ptr[2]); - - state->cycles += 111; - - /* 0x601F314 */ - - state->cycles += 8 + 56*counter; - - const int16_t *in = in_address & 0x06000000 - ? (const int16_t *)HRAM_PTR(in_address) - : (const int16_t *)LRAM_PTR(in_address); - int16_t *out = (int16_t *)HRAM_PTR(state->R[7]); - - do { - const int32_t out_x = M11*in[0] + M12*in[1] + M13*in[2] + M14; - const int32_t out_y = M21*in[0] + M22*in[1] + M23*in[2] + M24; - const int32_t out_z = M31*in[0] + M32*in[1] + M33*in[2] + M34; - const float coord_mult = 256.0f / out_z; - out[0] = ifloorf(coord_mult * out_x); - out[1] = ifloorf(coord_mult * out_y); - *(int32_t *)&out[2] = RAM_SWAPL(out_z); - in += 3; - out += 4; - } while (--counter != 0); - - state->R[4] += 12; - state->PC = state->PR; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x601F3F4: Coordinate transform routine with boundary checks */ - -static FASTCALL void Azel_0601F3F4(SH2State *state) -{ - const int32_t *r4_ptr = state->R[4] & 0x06000000 - ? (const int32_t *)HRAM_PTR(state->R[4]) - : (const int32_t *)LRAM_PTR(state->R[4]); - const int32_t *r5_ptr = (const int32_t *)HRAM_PTR(state->R[5]); - const int32_t *r6_ptr = (const int32_t *)HRAM_PTR(state->R[6]); - - /* 0x601F38E */ - - const int32_t r6_x = RAM_SWAPL(r6_ptr[6]); - const int32_t M11 = (r6_x * (int32_t)RAM_SWAPL(r5_ptr[0])) >> 12; - const int32_t M12 = (r6_x * (int32_t)RAM_SWAPL(r5_ptr[1])) >> 12; - const int32_t M13 = (r6_x * (int32_t)RAM_SWAPL(r5_ptr[2])) >> 12; - const int32_t M14 = r6_x * (int32_t)RAM_SWAPL(r5_ptr[3]); - - const int32_t r6_y = -RAM_SWAPL(r6_ptr[7]); - const int32_t M21 = (r6_y * (int32_t)RAM_SWAPL(r5_ptr[4])) >> 12; - const int32_t M22 = (r6_y * (int32_t)RAM_SWAPL(r5_ptr[5])) >> 12; - const int32_t M23 = (r6_y * (int32_t)RAM_SWAPL(r5_ptr[6])) >> 12; - const int32_t M24 = r6_y * (int32_t)RAM_SWAPL(r5_ptr[7]); - - const int32_t M31 = (int32_t)RAM_SWAPL(r5_ptr[ 8]) >> 4; - const int32_t M32 = (int32_t)RAM_SWAPL(r5_ptr[ 9]) >> 4; - const int32_t M33 = (int32_t)RAM_SWAPL(r5_ptr[10]) >> 4; - const int32_t M34 = (int32_t)RAM_SWAPL(r5_ptr[11]) << 8; - - uint32_t counter = RAM_SWAPL(r4_ptr[1]); - const uint32_t in_address = RAM_SWAPL(r4_ptr[2]); - - state->cycles += 111; - - /* 0x601F3FA */ - - state->cycles += 7 + 63*counter; - - const int16_t *in = in_address & 0x06000000 - ? (const int16_t *)HRAM_PTR(in_address) - : (const int16_t *)LRAM_PTR(in_address); - int16_t *out = (int16_t *)HRAM_PTR(state->R[7]); - - do { - const int32_t out_x = M11*in[0] + M12*in[1] + M13*in[2] + M14; - const int32_t out_y = M21*in[0] + M22*in[1] + M23*in[2] + M24; - const int32_t out_z = M31*in[0] + M32*in[1] + M33*in[2] + M34; - *(int32_t *)&out[2] = RAM_SWAPL(out_z); - *(int32_t *)&out[4] = RAM_SWAPL(out_x); - *(int32_t *)&out[6] = RAM_SWAPL(out_y); - uint32_t clip_flags = (out_z >= RAM_SWAPL(r6_ptr[5]) << 8) << 5 - | (out_z < RAM_SWAPL(r6_ptr[4]) << 8) << 4; - if (!(clip_flags & 0x10)) { - const float coord_mult = 256.0f / out_z; - out[0] = ifloorf(coord_mult * out_x); - out[1] = ifloorf(coord_mult * out_y); - clip_flags |= (out[1] > ((const int16_t *)r6_ptr)[4]) << 3 - | (out[1] < ((const int16_t *)r6_ptr)[5]) << 2 - | (out[0] > ((const int16_t *)r6_ptr)[7]) << 1 - | (out[0] < ((const int16_t *)r6_ptr)[6]) << 0; - state->cycles += 19; - } - *(uint32_t *)&out[12] = RAM_SWAPL(clip_flags); - in += 3; - out += 16; - } while (--counter != 0); - - state->R[4] += 12; - state->PC = state->PR; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x601FB70: Entry to another self-modified routine like 0x601EE60 */ - -static FASTCALL void Azel_0601FB70(SH2State *state) -{ - const uint16_t insn = HRAM_LOADW(0x601FB72, 0); - if (insn>>12 == 0xA) { // BRA instruction - state->R[0] = 0x601FC94; - state->MACL = state->MACH = 0; - state->PC += 6 + ((int32_t)(insn<<20) >> 19); - state->cycles += 4; - } else { - if (insn != 0x6103) { - DMSG("WARNING: Wrong instruction at 0x601FB72 (%04X)", insn); - } - const int32_t *M_ptr = - state->R[5] & 0x6000000 ? (int32_t *)HRAM_PTR(state->R[5]) - : (int32_t *)LRAM_PTR(state->R[5]); - const int32_t in_x = HRAM_LOADL(0x601FC9C, 0); - const int32_t in_y = HRAM_LOADL(0x601FC9C, 4); - const int32_t in_z = HRAM_LOADL(0x601FC9C, 8); - int16_t out_x = (RAM_SWAPL(M_ptr[ 0]) * in_x - + RAM_SWAPL(M_ptr[ 4]) * in_y - + RAM_SWAPL(M_ptr[ 8]) * in_z) >> 16; - int16_t out_y = (RAM_SWAPL(M_ptr[ 1]) * in_x - + RAM_SWAPL(M_ptr[ 5]) * in_y - + RAM_SWAPL(M_ptr[ 9]) * in_z) >> 16; - int16_t out_z = (RAM_SWAPL(M_ptr[ 2]) * in_x - + RAM_SWAPL(M_ptr[ 6]) * in_y - + RAM_SWAPL(M_ptr[10]) * in_z) >> 16; - HRAM_STOREW(0x601FC94, 0, out_x); - HRAM_STOREW(0x601FC94, 2, out_y); - HRAM_STOREW(0x601FC94, 4, out_z); - state->PC = state->PR; - state->cycles += 58; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x6022E18: Short but difficult-to-optimize routine */ - -static FASTCALL void Azel_06022E18(SH2State *state) -{ - uint32_t cycles = state->cycles; - - int32_t counter = HRAM_LOADL(state->R[4], 4); - if (counter > 0) { - HRAM_STOREL(state->R[4], 4, counter-1); - state->R[0] = HRAM_LOADL(state->R[4], 8); - state->PC = state->PR; - state->cycles = cycles + 9; - return; - } - - uint32_t index = HRAM_LOADL(state->R[4], 0); - int32_t r0 = (int16_t)LRAM_LOADW(state->R[5], index*2); - const uint32_t limit = state->R[6]; - if (index != 0) { - HRAM_STOREL(state->R[4], 4, (r0 & 15) - 1); - r0 &= -16; - cycles += 5; - } else { - HRAM_STOREL(state->R[4], 4, 0); - r0 <<= 4; - } - HRAM_STOREL(state->R[4], 8, r0); - index++; - if (index >= limit) { - index = 0; - cycles++; - } - HRAM_STOREL(state->R[4], 0, index); - state->R[0] = r0; - state->PC = state->PR; - state->cycles = cycles + 21; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x6035xxx: Mathematical library routines */ - -static FASTCALL void Azel_06035530(SH2State *state) -{ - if (LIKELY(state->R[5] != 0)) { - state->R[0] = - ((int64_t)(int32_t)state->R[4] << 16) / (int32_t)state->R[5]; - state->cycles += 52; - } else { - state->R[0] = 0; - state->cycles += 7; - } - state->PC = state->PR; -} - -static FASTCALL void Azel_06035552(SH2State *state) -{ - if (LIKELY(state->R[6] != 0)) { - state->R[0] = - ((int64_t)(int32_t)state->R[4] * (int64_t)(int32_t)state->R[5]) - / (int32_t)state->R[6]; - } - state->cycles += 15; - state->PC = state->PR; -} - -static FASTCALL void Azel_0603556C(SH2State *state) -{ -#ifdef __mips__ // GCC's optimizer fails yet again... - - asm(".set push; .set noreorder\n" -# ifdef WORDS_BIGENDIAN // Just for completeness - "lh $v0, 18(%[state])\n" - "lh $v1, 22(%[state])\n" -# else - "lh $v0, 16(%[state])\n" - "lh $v1, 20(%[state])\n" -# endif - "lw $a1, 92(%[state])\n" - "lw $a2, 84(%[state])\n" - "mult $v0, $v1\n" - "lw $v1, 24(%[state])\n" - "addiu $a1, $a1, 15\n" - "sw $a1, 92(%[state])\n" - "sw $a2, 88(%[state])\n" - /* 1 cycle wasted */ - "mflo $v0\n" - "div $zero, $v0, $v1\n" // $zero needed to avoid the div-by-zero check - /* Up to 33 cycles wasted (sigh) */ - "lw $v0, 0(%[state])\n" - "bnezl $v1, 1f\n" - "mflo $v0\n" - "1:\n" - /* This is totally evil, but it works as long as GCC doesn't try to - * set up any stack frames on us, and it lets the routine fit in - * one cache line (barely). */ - "jr $ra\n" - "sw $v0, 0(%[state])\n" - ".set pop" - : "=m" (*state) - : [state] "r" (state) - : "v0", "v1", "a1", "a2", "hi", "lo" - ); - -#else // !__mips__ - - if (LIKELY(state->R[6] != 0)) { - state->R[0] = ((int16_t)state->R[4] * (int16_t)state->R[5]) - / (int32_t)state->R[6]; - } - state->cycles += 15; - state->PC = state->PR; - -#endif -} - -/*----------------------------------*/ - -static FASTCALL void Azel_06035A8C(SH2State *state) -{ - const uint32_t ptr = HRAM_LOADL(0x604AEA4, 0); - HRAM_STOREL(0x604AEA4, 0, ptr + 48); - state->R[4] = ptr; - state->R[5] = ptr + 48; - state->cycles += 9; - return Azel_06035AA0(state); -} - -static FASTCALL void Azel_06035A9C(SH2State *state) -{ - state->R[5] = HRAM_LOADL(0x604AEA4, 0); - state->cycles += 2; - return Azel_06035AA0(state); -} - -static FASTCALL void Azel_06035AA0(SH2State *state) -{ - const uint32_t *src = (const uint32_t *)HRAM_PTR(state->R[4]); - uint32_t *dest = (uint32_t *)HRAM_PTR(state->R[5]); - - const uint32_t *src_limit = &src[12]; - for (; src < src_limit; src += 4, dest += 4) { - const uint32_t word0 = src[0]; - const uint32_t word1 = src[1]; - const uint32_t word2 = src[2]; - const uint32_t word3 = src[3]; - dest[0] = word0; - dest[1] = word1; - dest[2] = word2; - dest[3] = word3; - } - - state->R[0] = state->R[5]; - state->PC = state->PR; - state->cycles += 27; -} - -/*----------------------------------*/ - -static ALWAYS_INLINE void Azel_06035B14_F00_common( - SH2State *state, const int32_t *vector, const int32_t *matrix, - int32_t *out_x_ptr, int32_t *out_y_ptr, int32_t *out_z_ptr); - -static FASTCALL void Azel_06035B14(SH2State *state) -{ - const int32_t *r4_ptr = state->R[4] & 0x06000000 - ? (const int32_t *)HRAM_PTR(state->R[4]) - : (const int32_t *)LRAM_PTR(state->R[4]); - int32_t *r5_ptr = (int32_t *)HRAM_PTR(HRAM_LOADL(0x604AEA4, 0)); - - state->PC = state->PR; - state->cycles += 56; - return Azel_06035B14_F00_common(state, r4_ptr, r5_ptr, - &r5_ptr[3], &r5_ptr[7], &r5_ptr[11]); -} - -static FASTCALL void Azel_06035F00(SH2State *state) -{ - const int32_t *r4_ptr = state->R[4] & 0x06000000 - ? (const int32_t *)HRAM_PTR(state->R[4]) - : (const int32_t *)LRAM_PTR(state->R[4]); - int32_t *r5_ptr = (int32_t *)HRAM_PTR(state->R[5]); - const int32_t *r6_ptr = (const int32_t *)HRAM_PTR(HRAM_LOADL(0x604AEA4, 0)); - - state->PC = state->PR; - state->cycles += 54; - return Azel_06035B14_F00_common(state, r4_ptr, r6_ptr, - &r5_ptr[0], &r5_ptr[1], &r5_ptr[2]); -} - -static FASTCALL void Azel_06035F04(SH2State *state) -{ - const int32_t *r4_ptr = state->R[4] & 0x06000000 - ? (const int32_t *)HRAM_PTR(state->R[4]) - : (const int32_t *)LRAM_PTR(state->R[4]); - int32_t *r5_ptr = (int32_t *)HRAM_PTR(state->R[5]); - const int32_t *r6_ptr = (const int32_t *)HRAM_PTR(state->R[6]); - - state->PC = state->PR; - state->cycles += 52; - return Azel_06035B14_F00_common(state, r4_ptr, r6_ptr, - &r5_ptr[0], &r5_ptr[1], &r5_ptr[2]); -} - -static ALWAYS_INLINE void Azel_06035B14_F00_common( - SH2State *state, const int32_t *vector, const int32_t *matrix, - int32_t *out_x_ptr, int32_t *out_y_ptr, int32_t *out_z_ptr) -{ -#ifdef PSP - - int32_t v_0, v_1, v_2, M_0, M_1, M_2, M_3, hi, lo; - asm(".set push; .set noreorder\n" - - "lw %[v_0], 0(%[vector])\n" - "lw %[M_0], 0(%[matrix])\n" - "lw %[v_1], 4(%[vector])\n" - "ror %[v_0], %[v_0], 16\n" - "ror %[M_0], %[M_0], 16\n" - "mult %[v_0], %[M_0]\n" - "lw %[M_1], 4(%[matrix])\n" - "ror %[v_1], %[v_1], 16\n" - "ror %[M_1], %[M_1], 16\n" - "madd %[v_1], %[M_1]\n" - "lw %[v_2], 8(%[vector])\n" - "lw %[M_2], 8(%[matrix])\n" - "lw %[M_3], 12(%[matrix])\n" - "ror %[v_2], %[v_2], 16\n" - "ror %[M_2], %[M_2], 16\n" - "madd %[v_2], %[M_2]\n" - "lw %[M_0], 16(%[matrix])\n" - "lw %[M_1], 20(%[matrix])\n" - "lw %[M_2], 24(%[matrix])\n" - "ror %[M_3], %[M_3], 16\n" - "ror %[M_0], %[M_0], 16\n" - "mfhi %[hi]\n" - "mflo %[lo]\n" - - "mult %[v_0], %[M_0]\n" - "ror %[M_1], %[M_1], 16\n" - "srl %[lo], %[lo], 16\n" - "ins %[lo], %[hi], 16, 16\n" - "madd %[v_1], %[M_1]\n" - "ror %[M_2], %[M_2], 16\n" - "addu %[lo], %[M_3], %[lo]\n" - "lw %[M_3], 28(%[matrix])\n" - "ror %[lo], %[lo], 16\n" - "sw %[lo], 0(%[out_x_ptr])\n" - "madd %[v_2], %[M_2]\n" - "lw %[M_0], 32(%[matrix])\n" - "lw %[M_1], 36(%[matrix])\n" - "lw %[M_2], 40(%[matrix])\n" - "ror %[M_3], %[M_3], 16\n" - "ror %[M_0], %[M_0], 16\n" - "mfhi %[hi]\n" - "mflo %[lo]\n" - - "mult %[v_0], %[M_0]\n" - "ror %[M_1], %[M_1], 16\n" - "srl %[lo], %[lo], 16\n" - "ins %[lo], %[hi], 16, 16\n" - "madd %[v_1], %[M_1]\n" - "ror %[M_2], %[M_2], 16\n" - "addu %[lo], %[M_3], %[lo]\n" - "lw %[M_3], 44(%[matrix])\n" - "ror %[lo], %[lo], 16\n" - "sw %[lo], 0(%[out_y_ptr])\n" - "madd %[v_2], %[M_2]\n" - "ror %[M_3], %[M_3], 16\n" - "mfhi %[hi]\n" - "mflo %[lo]\n" - "srl %[lo], %[lo], 16\n" - "ins %[lo], %[hi], 16, 16\n" - "addu %[lo], %[M_3], %[lo]\n" - "ror %[lo], %[lo], 16\n" - "sw %[lo], 0(%[out_z_ptr])\n" - - ".set pop" - : "=m" (*out_x_ptr), "=m" (*out_y_ptr), "=m" (*out_z_ptr), - [v_0] "=&r" (v_0), [v_1] "=&r" (v_1), [v_2] "=&r" (v_2), - [M_0] "=&r" (M_0), [M_1] "=&r" (M_1), [M_2] "=&r" (M_2), - [M_3] "=&r" (M_3), [hi] "=&r" (hi), [lo] "=&r" (lo) - : [vector] "r" (vector), [matrix] "r" (matrix), - [out_x_ptr] "r" (out_x_ptr), [out_y_ptr] "r" (out_y_ptr), - [out_z_ptr] "r" (out_z_ptr) - : "hi", "lo" - ); - -#else // !PSP - - const int32_t temp0 = - ((int64_t)RAM_SWAPL(vector[0]) * (int64_t)RAM_SWAPL(matrix[0]) - + (int64_t)RAM_SWAPL(vector[1]) * (int64_t)RAM_SWAPL(matrix[1]) - + (int64_t)RAM_SWAPL(vector[2]) * (int64_t)RAM_SWAPL(matrix[2]) - ) >> 16; - *out_x_ptr = RAM_SWAPL(RAM_SWAPL(matrix[3]) + temp0); - - const int32_t temp1 = - ((int64_t)RAM_SWAPL(vector[0]) * (int64_t)RAM_SWAPL(matrix[4]) - + (int64_t)RAM_SWAPL(vector[1]) * (int64_t)RAM_SWAPL(matrix[5]) - + (int64_t)RAM_SWAPL(vector[2]) * (int64_t)RAM_SWAPL(matrix[6]) - ) >> 16; - *out_y_ptr = RAM_SWAPL(RAM_SWAPL(matrix[7]) + temp1); - - const int32_t temp2 = - ((int64_t)RAM_SWAPL(vector[0]) * (int64_t)RAM_SWAPL(matrix[8]) - + (int64_t)RAM_SWAPL(vector[1]) * (int64_t)RAM_SWAPL(matrix[9]) - + (int64_t)RAM_SWAPL(vector[2]) * (int64_t)RAM_SWAPL(matrix[10]) - ) >> 16; - *out_z_ptr = RAM_SWAPL(RAM_SWAPL(matrix[11]) + temp2); - -#endif // PSP -} - -/*----------------------------------*/ - -static ALWAYS_INLINE void Azel_06035xxx_rotate_common( - int angle, int32_t *r5_ptr, unsigned int x_idx, unsigned int y_idx, - int invert); - -static FASTCALL void Azel_06035C18(SH2State *state) -{ - const int16_t *r4_ptr = state->R[4] & 0x06000000 - ? (const int16_t *)HRAM_PTR(state->R[4]) - : (const int16_t *)LRAM_PTR(state->R[4]); - const uint32_t r5 = HRAM_LOADL(0x604AEA4, 0); - int32_t *r5_ptr = r5 & 0x6000000 ? (int32_t *)HRAM_PTR(r5) - : (int32_t *)LRAM_PTR(r5); - - if (r4_ptr[4] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[4] & 0xFFF, r5_ptr, 0, 1, 0); - } - if (r4_ptr[2] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[2] & 0xFFF, r5_ptr, 0, 2, 1); - } - if (r4_ptr[0] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[0] & 0xFFF, r5_ptr, 1, 2, 0); - } - - state->PC = state->PR; - state->cycles += 290; -} - -static FASTCALL void Azel_06035C3C(SH2State *state) -{ - const int16_t *r4_ptr = state->R[4] & 0x06000000 - ? (const int16_t *)HRAM_PTR(state->R[4]) - : (const int16_t *)LRAM_PTR(state->R[4]); - const uint32_t r5 = HRAM_LOADL(0x604AEA4, 0); - int32_t *r5_ptr = r5 & 0x6000000 ? (int32_t *)HRAM_PTR(r5) - : (int32_t *)LRAM_PTR(r5); - - if (r4_ptr[2] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[2] & 0xFFF, r5_ptr, 0, 2, 1); - } - if (r4_ptr[0] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[0] & 0xFFF, r5_ptr, 1, 2, 0); - } - if (r4_ptr[4] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[4] & 0xFFF, r5_ptr, 0, 1, 0); - } - - state->PC = state->PR; - state->cycles += 290; -} - -static FASTCALL void Azel_06035C60(SH2State *state) -{ - const int16_t *r4_ptr = state->R[4] & 0x06000000 - ? (const int16_t *)HRAM_PTR(state->R[4]) - : (const int16_t *)LRAM_PTR(state->R[4]); - const uint32_t r5 = HRAM_LOADL(0x604AEA4, 0); - int32_t *r5_ptr = r5 & 0x6000000 ? (int32_t *)HRAM_PTR(r5) - : (int32_t *)LRAM_PTR(r5); - - if (r4_ptr[2] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[4] & 0xFFF, r5_ptr, 0, 1, 0); - } - if (r4_ptr[1] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[2] & 0xFFF, r5_ptr, 0, 2, 1); - } - if (r4_ptr[0] & 0xFFF) { - Azel_06035xxx_rotate_common(r4_ptr[0] & 0xFFF, r5_ptr, 1, 2, 0); - } - - state->PC = state->PR; - state->cycles += 290; -} - -static FASTCALL void Azel_06035C84(SH2State *state) -{ - state->R[5] = HRAM_LOADL(0x604AEA4, 0); - return Azel_06035C96(state); -} - -static FASTCALL void Azel_06035C90(SH2State *state) -{ - state->R[4] >>= 16; - state->R[5] = HRAM_LOADL(0x604AEA4, 0); - return Azel_06035C96(state); -} - -static FASTCALL void Azel_06035C96(SH2State *state) -{ - const int32_t angle = state->R[4] & 0xFFF; - int32_t *r5_ptr = - state->R[5] & 0x6000000 ? (int32_t *)HRAM_PTR(state->R[5]) - : (int32_t *)LRAM_PTR(state->R[5]); - Azel_06035xxx_rotate_common(angle, r5_ptr, 1, 2, 0); - state->PC = state->PR; - state->cycles += 88; -} - -static FASTCALL void Azel_06035D24(SH2State *state) -{ - state->R[5] = HRAM_LOADL(0x604AEA4, 0); - return Azel_06035D36(state); -} - -static FASTCALL void Azel_06035D30(SH2State *state) -{ - state->R[4] >>= 16; - state->R[5] = HRAM_LOADL(0x604AEA4, 0); - return Azel_06035D36(state); -} - -static FASTCALL void Azel_06035D36(SH2State *state) -{ - const int32_t angle = state->R[4] & 0xFFF; - int32_t *r5_ptr = - state->R[5] & 0x6000000 ? (int32_t *)HRAM_PTR(state->R[5]) - : (int32_t *)LRAM_PTR(state->R[5]); - Azel_06035xxx_rotate_common(angle, r5_ptr, 0, 2, 1); - state->PC = state->PR; - state->cycles += 96; -} - -static FASTCALL void Azel_06035DD4(SH2State *state) -{ - state->R[5] = HRAM_LOADL(0x604AEA4, 0); - return Azel_06035DE6(state); -} - -static FASTCALL void Azel_06035DE0(SH2State *state) -{ - state->R[4] >>= 16; - state->R[5] = HRAM_LOADL(0x604AEA4, 0); - return Azel_06035DE6(state); -} - -static FASTCALL void Azel_06035DE6(SH2State *state) -{ - const int32_t angle = state->R[4] & 0xFFF; - int32_t *r5_ptr = - state->R[5] & 0x6000000 ? (int32_t *)HRAM_PTR(state->R[5]) - : (int32_t *)LRAM_PTR(state->R[5]); - Azel_06035xxx_rotate_common(angle, r5_ptr, 0, 1, 0); - state->PC = state->PR; - state->cycles += 87; -} - -static ALWAYS_INLINE void Azel_06035xxx_rotate_common( - int angle, int32_t *r5_ptr, unsigned int x_idx, unsigned int y_idx, - int invert) -{ - const int32_t *sin_table = (const int32_t *)LRAM_PTR(0x216660); - const int32_t *cos_table = (const int32_t *)LRAM_PTR(0x217660); - const int32_t sin_angle = invert ? -RAM_SWAPL(sin_table[angle]) - : +RAM_SWAPL(sin_table[angle]); - const int32_t cos_angle = RAM_SWAPL(cos_table[angle]); - int32_t new_x, new_y; - -#ifdef PSP - - int32_t old_x, old_y; - - asm(".set push; .set noreorder\n" - - "lw %[old_x], 0+%[x_ofs](%[r5_ptr])\n" - "lw %[old_y], 0+%[y_ofs](%[r5_ptr])\n" - "ror %[old_x], %[old_x], 16\n" - "mult %[old_x], %[cos_angle]\n" - "ror %[old_y], %[old_y], 16\n" - "madd %[old_y], %[sin_angle]\n" - "mfhi %[new_y]\n" - "mflo %[new_x]\n" - "mult %[old_x], %[nsin_angle]\n" - "lw %[old_x], 16+%[x_ofs](%[r5_ptr])\n" - /* We want ROR(HI<<16 | LO>>16, 16), but that's equivalent - * to (HI & 0xFFFF) | (LO & 0xFFFF0000), which we can do - * with a single INS instruction. */ - "ins %[new_x], %[new_y], 0, 16\n" - "sw %[new_x], 0+%[x_ofs](%[r5_ptr])\n" - "ror %[old_x], %[old_x], 16\n" - "madd %[old_y], %[cos_angle]\n" - "lw %[old_y], 16+%[y_ofs](%[r5_ptr])\n" - "ror %[old_y], %[old_y], 16\n" - "mfhi %[new_x]\n" - "mflo %[new_y]\n" - - "mult %[old_x], %[cos_angle]\n" - "ins %[new_y], %[new_x], 0, 16\n" - "sw %[new_y], 0+%[y_ofs](%[r5_ptr])\n" - "madd %[old_y], %[sin_angle]\n" - "mfhi %[new_y]\n" - "mflo %[new_x]\n" - "mult %[old_x], %[nsin_angle]\n" - "lw %[old_x], 32+%[x_ofs](%[r5_ptr])\n" - "ins %[new_x], %[new_y], 0, 16\n" - "sw %[new_x], 16+%[x_ofs](%[r5_ptr])\n" - "ror %[old_x], %[old_x], 16\n" - "madd %[old_y], %[cos_angle]\n" - "lw %[old_y], 32+%[y_ofs](%[r5_ptr])\n" - "ror %[old_y], %[old_y], 16\n" - "mfhi %[new_x]\n" - "mflo %[new_y]\n" - - "mult %[old_x], %[cos_angle]\n" - "ins %[new_y], %[new_x], 0, 16\n" - "sw %[new_y], 16+%[y_ofs](%[r5_ptr])\n" - "madd %[old_y], %[sin_angle]\n" - "mfhi %[new_y]\n" - "mflo %[new_x]\n" - "mult %[old_x], %[nsin_angle]\n" - "ins %[new_x], %[new_y], 0, 16\n" - "sw %[new_x], 32+%[x_ofs](%[r5_ptr])\n" - "madd %[old_y], %[cos_angle]\n" - "mfhi %[new_x]\n" - "mflo %[new_y]\n" - "ins %[new_y], %[new_x], 0, 16\n" - "sw %[new_y], 32+%[y_ofs](%[r5_ptr])\n" - - ".set pop" - : "=m" (r5_ptr[0*4 + x_idx]), "=m" (r5_ptr[0*4 + y_idx]), - "=m" (r5_ptr[1*4 + x_idx]), "=m" (r5_ptr[1*4 + y_idx]), - "=m" (r5_ptr[2*4 + x_idx]), "=m" (r5_ptr[2*4 + y_idx]), - [new_x] "=&r" (new_x), [new_y] "=&r" (new_y), - [old_x] "=&r" (old_x), [old_y] "=&r" (old_y) - : [sin_angle] "r" (sin_angle), [cos_angle] "r" (cos_angle), - [nsin_angle] "r" (-sin_angle), [r5_ptr] "r" (r5_ptr), - [x_ofs] "i" (x_idx*4), [y_ofs] "i" (y_idx*4) - : "hi", "lo" - ); - -#else // !PSP - - #define DOT2(x1,y1,x2,y2) \ - (((int64_t)(x1) * (int64_t)(x2) + (int64_t)(y1) * (int64_t)(y2)) >> 16) - #define ROTATE(index) \ - new_x = DOT2(RAM_SWAPL(r5_ptr[index*4 + x_idx]), \ - RAM_SWAPL(r5_ptr[index*4 + y_idx]), \ - cos_angle, sin_angle); \ - new_y = DOT2(RAM_SWAPL(r5_ptr[index*4 + x_idx]), \ - RAM_SWAPL(r5_ptr[index*4 + y_idx]), \ - -sin_angle, cos_angle); \ - r5_ptr[index*4 + x_idx] = RAM_SWAPL(new_x); \ - r5_ptr[index*4 + y_idx] = RAM_SWAPL(new_y) - - ROTATE(0); - ROTATE(1); - ROTATE(2); - - #undef DOT2 - #undef ROTATE - -#endif -} - -/*----------------------------------*/ - -static ALWAYS_INLINE void Azel_06035Exx_scale_common( - int32_t scale, int32_t *r5_ptr); - -static FASTCALL void Azel_06035E70(SH2State *state) -{ - uint32_t r5 = HRAM_LOADL(0x604AEA4, 0); - int32_t *r5_ptr = r5 & 0x6000000 ? (int32_t *)HRAM_PTR(r5) - : (int32_t *)LRAM_PTR(r5); - Azel_06035Exx_scale_common(state->R[4], r5_ptr+0); - state->PC = state->PR; - state->cycles += 28; -} - -static FASTCALL void Azel_06035EA0(SH2State *state) -{ - uint32_t r5 = HRAM_LOADL(0x604AEA4, 0); - int32_t *r5_ptr = r5 & 0x6000000 ? (int32_t *)HRAM_PTR(r5) - : (int32_t *)LRAM_PTR(r5); - Azel_06035Exx_scale_common(state->R[4], r5_ptr+1); - state->PC = state->PR; - state->cycles += 28; -} - -static FASTCALL void Azel_06035ED0(SH2State *state) -{ - uint32_t r5 = HRAM_LOADL(0x604AEA4, 0); - int32_t *r5_ptr = r5 & 0x6000000 ? (int32_t *)HRAM_PTR(r5) - : (int32_t *)LRAM_PTR(r5); - Azel_06035Exx_scale_common(state->R[4], r5_ptr+2); - state->PC = state->PR; - state->cycles += 28; -} - -static ALWAYS_INLINE void Azel_06035Exx_scale_common( - int32_t scale, int32_t *r5_ptr) -{ -#ifdef PSP - - int32_t a, b, c, hi, lo; - - asm(".set push; .set noreorder\n" - - "lw %[a], 0(%[r5_ptr])\n" - "lw %[b], 16(%[r5_ptr])\n" - "lw %[c], 32(%[r5_ptr])\n" - "ror %[a], %[a], 16\n" - "mult %[a], %[scale]\n" - "ror %[b], %[b], 16\n" - "ror %[c], %[c], 16\n" - "mfhi %[hi]\n" - "mflo %[lo]\n" - "mult %[b], %[scale]\n" - // As with rotation, we take a shortcut for ROR(HI<<16 | LO>>16, 16). - "ins %[lo], %[hi], 0, 16\n" - "sw %[lo], 0(%[r5_ptr])\n" - "mfhi %[hi]\n" - "mflo %[lo]\n" - "mult %[c], %[scale]\n" - "ins %[lo], %[hi], 0, 16\n" - "sw %[lo], 16(%[r5_ptr])\n" - "mfhi %[hi]\n" - "mflo %[lo]\n" - "ins %[lo], %[hi], 0, 16\n" - "sw %[lo], 32(%[r5_ptr])\n" - - ".set pop" - : "=m" (r5_ptr[0]), "=m" (r5_ptr[4]), "=m" (r5_ptr[8]), - [a] "=&r" (a), [b] "=&r" (b), [c] "=&r" (c), - [hi] "=&r" (hi), [lo] "=&r" (lo) - : [scale] "r" (scale), [r5_ptr] "r" (r5_ptr) - : "hi", "lo" - ); - -#else // !PSP - - r5_ptr[0] = RAM_SWAPL(((int64_t)RAM_SWAPL(r5_ptr[0]) * scale) >> 16); - r5_ptr[4] = RAM_SWAPL(((int64_t)RAM_SWAPL(r5_ptr[4]) * scale) >> 16); - r5_ptr[8] = RAM_SWAPL(((int64_t)RAM_SWAPL(r5_ptr[8]) * scale) >> 16); - -#endif -} - -/*-----------------------------------------------------------------------*/ - -/* 0x60360F0: Delay routine (not automatically foldable due to the BF) */ - -static FASTCALL void Azel_060360F0(SH2State *state) -{ - state->PC = state->PR; - state->cycles += state->R[4]*4 + 1; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x603A22C: Wrapper for 0x603A242 that jumps in with a BRA */ - -static int Azel_0603A22C_detect(SH2State *state, uint32_t address, - const uint16_t *fetch) -{ - return fetch[0] == 0xA009 // bra 0x603A242 - && fetch[1] == 0xE700 // mov #0, r7 - ? 2 : 0; -} - -static FASTCALL void Azel_0603A22C(SH2State *state) -{ - state->R[7] = 0; - return Azel_0603A242(state); -} - -/*----------------------------------*/ - -/* 0x603A242: CD command execution routine */ - -static int Azel_0603A242_state = 0; -static int Azel_0603A242_cmd51_count = 0; // Count of sequential 0x51 commands - -static FASTCALL void Azel_0603A242(SH2State *state) -{ - if (Azel_0603A242_state == 0) { - const uint32_t r4 = state->R[4]; - uint16_t *ptr_6053278 = (uint16_t *)HRAM_PTR(0x6053278); - *ptr_6053278 |= Cs2ReadWord(0x90008); - if ((*ptr_6053278 & r4) != r4) { - state->R[0] = -1; - state->PC = state->PR; - state->cycles += 77; - return; - } - if (!(*ptr_6053278 & 1)) { - state->R[0] = -2; - state->PC = state->PR; - state->cycles += 82; - return; - } - - Cs2WriteWord(0x90008, ~(r4 | 1)); - *ptr_6053278 &= ~1; - const uint32_t r5 = state->R[5]; - uintptr_t r5_base = (uintptr_t)direct_pages[r5>>19]; - const uint16_t *r5_ptr = (const uint16_t *)(r5_base + r5); - Cs2WriteWord(0x90018, r5_ptr[0]); - Cs2WriteWord(0x9001C, r5_ptr[1]); - Cs2WriteWord(0x90020, r5_ptr[2]); - Cs2WriteWord(0x90024, r5_ptr[3]); - state->cycles += 88; - Azel_0603A242_state = 1; - if (r5_ptr[0]>>8 == 0x51) { - Azel_0603A242_cmd51_count++; - } else if (r5_ptr[0]>>8 != 0) { // Command 0x00 doesn't reset the count - Azel_0603A242_cmd51_count = 0; - } - return; - } - - if (Azel_0603A242_state == 1) { - uint32_t status = (uint16_t)Cs2ReadWord(0x90008); - if (status & 1) { - state->cycles += 23; - Azel_0603A242_state = 2; - } else { - /* Technically a timeout loop, but we assume no timeouts */ - state->cycles = state->cycle_limit; - } - return; - } - - if (Azel_0603A242_state == 2) { - const uint32_t r6 = state->R[6]; - uintptr_t r6_base = (uintptr_t)direct_pages[r6>>19]; - uint16_t *r6_ptr = (uint16_t *)(r6_base + r6); - const unsigned int CR1 = Cs2ReadWord(0x90018); - const unsigned int CR2 = Cs2ReadWord(0x9001C); - const unsigned int CR3 = Cs2ReadWord(0x90020); - const unsigned int CR4 = Cs2ReadWord(0x90024); - if (Azel_0603A242_cmd51_count >= 0 && CR4 == 0) { - /* We're probably waiting for a sector and it hasn't arrived - * yet, so consume enough cycles to get us to that next sector. - * But be careful we don't wait an extra sector if the current - * sector finished reading between executing the CS2 command - * and retrieving the delay period. */ - const unsigned int usec_left = Cs2GetTimeToNextSector(); - if (usec_left > 0 && usec_left < (1000000/(75*2))*9/10) { - uint32_t cycles_left = 0; - if (yabsys.CurSH2FreqType == CLKTYPE_26MHZ) { - cycles_left = (26847 * usec_left) / 1000; - } else { - cycles_left = (28637 * usec_left) / 1000; - } - state->cycles += cycles_left; - } - } - r6_ptr[0] = CR1; - r6_ptr[1] = CR2; - r6_ptr[2] = CR3; - r6_ptr[3] = CR4; - uint16_t *dest = (uint16_t *)HRAM_PTR(0x605329C); - *((uint8_t *)dest + 1) = CR1>>8; - if (state->R[7]) { - dest[2] = CR1<<8 | CR2>>8; - dest[3] = CR2<<8 | CR3>>8; - dest[4] = CR3 & 0xFF; - dest[5] = CR4; - } - state->R[0] = 0; -#if defined(TRACE) || defined(TRACE_STEALTH) || defined(TRACE_LITE) - state->R[1] = ~0xF0; - state->R[2] = 0; - state->R[3] = ~0xF0; - state->R[4] = state->R[15] - 12; - state->R[5] = 0x605329C; - state->SR &= ~SR_T; -#endif - state->PC = state->PR; - state->cycles += 121; - Azel_0603A242_state = 0; - return; - } -} - -/*-----------------------------------------------------------------------*/ - -/* 0x603ABE0: The sole purpose of this routine seems to be to copy the - * first sample in a streaming audio ring buffer over the last sample. - * I don't know whether this is to work around an idiosyncrasy of the real - * SCSP or what, but it causes glitches when using the ME because we try - * to read the sample from an uncached address after writing it to a - * cached address. In any case, the function (as applied to audio data) - * is meaningless for emulation, so we null it out entirely. */ - -static FASTCALL void Azel_0603ABE0(SH2State *state) -{ - if ((MappedMemoryReadLong(state->R[4]+0xA0) & 0x1FF00000) == 0x05A00000) { - state->PC = state->PR; - state->cycles += 23; - return; - } - /* It's not touching sound RAM, so it must be doing something else. - * Let it run normally. */ - state->R[0] = 0xEF; - state->PC += 2; - state->cycles++; -} - -/*-----------------------------------------------------------------------*/ - -/* 0x603DD6E: CD read routine (actually a generalized copy routine, but - * doesn't seem to be used for anything else) */ - -static FASTCALL void Azel_0603DD6E(SH2State *state) -{ - int32_t len = MappedMemoryReadLong(state->R[15]); - uint32_t dest = state->R[4]; - - if (UNLIKELY(state->R[5] != 1) - || UNLIKELY(state->R[6] != 0x25818000) - || UNLIKELY(state->R[7] != 0) - || UNLIKELY(len <= 0) - || UNLIKELY((len & 3) != 0) - ) { - state->SR &= ~SR_T; - state->SR |= (state->R[4] == 0) << SR_T_SHIFT; - state->PC += 2; - state->cycles += 1; - return; - } - - state->PC = state->PR; - state->cycles += 30 + len*2; - - const uint32_t dest_page = dest>>19; - uint8_t *dest_base; - - dest_base = direct_pages[dest_page]; - if (dest_base) { - Cs2RapidCopyT2(dest_base + dest, len/4); - sh2_write_notify(dest, len); - return; - } - - dest_base = byte_direct_pages[dest_page]; - if (dest_base) { - Cs2RapidCopyT1(dest_base + dest, len/4); - return; - } - - if ((dest & 0x1FF00000) == 0x05A00000) { - Cs2RapidCopyT2(SoundRam + (dest & 0x7FFFF), len/4); - M68KWriteNotify(dest & 0x7FFFF, len); - return; - } - - for (; len > 0; len -= 4, dest += 4) { - const uint32_t word = MappedMemoryReadLong(0x25818000); - MappedMemoryWriteLong(dest, word); - } -} - -/*************************************************************************/ - -#endif // ENABLE_JIT - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/satopt-sh2.h b/yabause/src/psp/satopt-sh2.h deleted file mode 100644 index 3969b1d315..0000000000 --- a/yabause/src/psp/satopt-sh2.h +++ /dev/null @@ -1,61 +0,0 @@ -/* src/psp/satopt-sh2.h: Saturn-specific SH-2 optimization header - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_SATOPT_SH2_H -#define PSP_SATOPT_SH2_H - -/*************************************************************************/ - -/** - * saturn_optimize_sh2: Search for and return, if available, a native - * implementation of the SH-2 routine starting at the given address. - * - * [Parameters] - * state: Processor state block pointer - * address: Address from which to translate - * fetch: Pointer corresponding to "address" from which opcodes can - * be fetched - * func_ret: Pointer to variable to receive address of native function - * implementing this routine if return value is nonzero - * for_fold: Nonzero if the callback is being called to look up a - * subroutine for folding, zero if being called for a - * full block translation - * [Return value] - * Length of translated block in instructions (nonzero) if optimized - * code was generated, else zero - */ -extern unsigned int saturn_optimize_sh2(SH2State *state, uint32_t address, - const uint16_t *fetch, - SH2NativeFunctionPointer *func_ret, - int for_fold); - -/*************************************************************************/ - -#endif // PSP_SATOPT_SH2_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/sh2-core.i b/yabause/src/psp/sh2-core.i deleted file mode 100644 index be25488277..0000000000 --- a/yabause/src/psp/sh2-core.i +++ /dev/null @@ -1,4008 +0,0 @@ -/* src/psp/sh2-core.i: SH-2 instruction decoding core for PSP - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* - * This file is intended to be #included as part of a source file that - * processes SH-2 instructions. It defines the function: - * static inline unsigned int decode_insn(...) - * which decodes one instruction, performs actions to implement the - * instruction, and returns the instruction's opcode. The parameter list - * is set by the caller using - * #define DECODE_INSN_PARAMS ... - * and should be "void" (without quotes) if no parameters are used. The - * caller may also #define DECODE_INSN_INLINE to any inline-related - * keyword, including ALWAYS_INLINE or NOINLINE; if not defined, no such - * keyword will be used. - * - * The following identifiers must be either defined as macros or passed to - * decode_insn() as parameters: - * uint32_t initial_PC; // Address of the first instruction in the - * // current block, if OPTIMIZE_IDLE is defined - * uint32_t state_reg; // RTL register holding the state block pointer - * uint32_t cur_PC; // Address of the instruction to be decoded - * uint16_t *fetch; // Pointer to instruction to decode (or NULL if - * // direct access is not possible) - * - * Each instruction is decoded into a series of "micro-ops", which should - * be defined as macros before this file is included. See sh2.c or - * sh2-interpret.c for the micro-ops used. - * - * Note that while the decoder generally attempts to maintain SSA (static - * single assignment) form for all registers, optimization of state block - * fields into long-lived registers requires that every path through - * conditional code assign the same register to a given state block field. - * Since a proper SSA implementation could require many SELECT operations - * and temporary registers, leading to inefficient code (the optimization - * of which would be too time-consuming), we intentionally break SSA form - * in such cases, conditionally reassigning new values to state block - * mirror registers. Such cases are noted throughout the code. - */ - -/*************************************************************************/ - -/* Local convenience macros for defining and loading SH-2 registers */ - -#define GET_REG(name,reg,field,mask) \ - DECLARE_REG(name); \ - if ((REG_GETKNOWN((reg)) & (mask)) == (mask)) { \ - ALLOC_REG(name); \ - MOVEI(name, REG_GETVALUE((reg)) & (mask)); \ - } else { \ - LOAD_STATE_ALLOC(name, field); \ - } -#define GET_R0 GET_REG(R0, REG_R(0), R[0], 0xFFFFFFFF) -#define GET_R0_W GET_REG(R0, REG_R(0), R[0], 0xFFFF) -#define GET_R0_B GET_REG(R0, REG_R(0), R[0], 0xFF) -#define GET_R15 GET_REG(R15, REG_R(15), R[15], 0xFFFFFFFF) -#define GET_Rn GET_REG(Rn, REG_R(n), R[n], 0xFFFFFFFF) -#define GET_Rm GET_REG(Rm, REG_R(m), R[m], 0xFFFFFFFF) -#define GET_Rm_W GET_REG(Rm, REG_R(m), R[m], 0xFFFF) -#define GET_Rm_B GET_REG(Rm, REG_R(m), R[m], 0xFF) -#define GET_GBR GET_REG(GBR, REG_GBR, GBR, 0xFFFFFFFF) -/* These are generally unknown, so don't waste time on checking them */ -#define GET_SR FLUSH_STATE_SR_T(); \ - DECLARE_REG(SR); LOAD_STATE_ALLOC(SR, SR) -#define GET_SR_T DECLARE_REG(T); LOAD_STATE_SR_T (T) -#define GET_VBR DECLARE_REG(VBR); LOAD_STATE_ALLOC(VBR, VBR) -#define GET_MACH DECLARE_REG(MACH); LOAD_STATE_ALLOC(MACH, MACH) -#define GET_MACL DECLARE_REG(MACL); LOAD_STATE_ALLOC(MACL, MACL) -#define GET_PR DECLARE_REG(PR); LOAD_STATE_ALLOC(PR, PR) - -/* MACH/MACL may be overwritten in the same register by the MAC.[WL] insns, - * so STS MAC uses these macros to force creation of a new register */ -#define GET_MACH_COPY DEFINE_REG(MACH); LOAD_STATE_COPY(MACH, MACH) -#define GET_MACL_COPY DEFINE_REG(MACL); LOAD_STATE_COPY(MACL, MACL) - -/* Versions used by load/store macros to retain the cached offset */ -#define GET_REG_KEEPOFS(name,field) \ - DECLARE_REG(name); LOAD_STATE_ALLOC_KEEPOFS(name, field) -#define GET_R0_KEEPOFS GET_REG_KEEPOFS(R0, R[0]) -#define GET_R15_KEEPOFS GET_REG_KEEPOFS(R15, R[15]) -#define GET_Rn_KEEPOFS GET_REG_KEEPOFS(Rn, R[n]) -#define GET_Rm_KEEPOFS GET_REG_KEEPOFS(Rm, R[m]) -#define GET_GBR_KEEPOFS GET_REG_KEEPOFS(GBR, GBR) - -/* Local convenience macro for moving a value from one SH-2 register to - * another. If the source uses a fixed RTL register (e.g. due to loop - * optimization) but the destination does not, the destination will end up - * sharing the source register, causing the destination's value to - * improperly change when the source is modified. Pass the relevant SH-2 - * register name (R[m], GBR, etc.) as the macro parameter. */ - -#define COPY_FROM_Rn(dest) \ - DECLARE_REG(value); \ - if (!STATE_CACHE_FIXED_REG_WRITABLE(dest)) { \ - STATE_CACHE_CLEAR_FIXED_REG(dest); \ - } \ - if (STATE_CACHE_FIXED_REG(R[n]) && !STATE_CACHE_FIXED_REG(dest)) { \ - ALLOC_REG(value); \ - LOAD_STATE_COPY(value, R[n]); \ - } else { \ - LOAD_STATE_ALLOC(value, R[n]); \ - } \ - if (offsetof(SH2State,SR) == offsetof(SH2State,dest)) { \ - RESET_STATE_SR_T(); \ - } \ - STORE_STATE(dest, value) - -#define COPY_TO_Rn(src) \ - DECLARE_REG(value); \ - if (offsetof(SH2State,SR) == offsetof(SH2State,src)) { \ - FLUSH_STATE_SR_T(); \ - } \ - if (!STATE_CACHE_FIXED_REG_WRITABLE(R[n])) { \ - STATE_CACHE_CLEAR_FIXED_REG(R[n]); \ - } \ - if (STATE_CACHE_FIXED_REG(src) && !STATE_CACHE_FIXED_REG(R[n])) { \ - ALLOC_REG(value); \ - LOAD_STATE_COPY(value, src); \ - } else { \ - LOAD_STATE_ALLOC(value, src); \ - } \ - STORE_STATE(R[n], value) - -/* Local convenience macro for creating result registers to be stored in a - * state block field */ - -#define DEFINE_RESULT_REG(name,field) \ - DECLARE_REG(name); \ - do { \ - name = STATE_CACHE_FIXED_REG(field); \ - if (name && !STATE_CACHE_FIXED_REG_WRITABLE(field)) { \ - STATE_CACHE_CLEAR_FIXED_REG(field); \ - name = 0; \ - } \ - if (!name) { \ - ALLOC_REG(name); \ - } \ - } while (0) - -/* Local convenience macros for storing values to SH-2 registers */ - -#define SET_R0(reg) STORE_STATE(R[0], (reg)) -#define SET_R15(reg) STORE_STATE(R[15],(reg)) -#define SET_Rn(reg) STORE_STATE(R[n], (reg)) -#define SET_Rm(reg) STORE_STATE(R[m], (reg)) -#define SET_SR(reg) RESET_STATE_SR_T(); STORE_STATE(SR, (reg)) -#define SET_SR_T(reg) STORE_STATE_SR_T ((reg)) -#define SET_GBR(reg) STORE_STATE(GBR, (reg)) -#define SET_VBR(reg) STORE_STATE(VBR, (reg)) -#define SET_MACH(reg) STORE_STATE(MACH, (reg)) -#define SET_MACL(reg) STORE_STATE(MACL, (reg)) -#define SET_PR(reg) STORE_STATE(PR, (reg)) -#define SET_PC(reg) STORE_STATE(PC, (reg)) - -/* Set PC to a known value */ -#define SET_PC_KNOWN(value) STORE_STATE_PC((value)) - -/* Local convenience macros for adding constants to SH-2 registers */ - -#define ADDI_R0(imm) ADDI_STATE(R[0], (imm), R0) -#define ADDI_R15(imm) ADDI_STATE(R[15], (imm), R15) -#define ADDI_Rn(imm) ADDI_STATE(R[n], (imm), Rn) -#define ADDI_Rm(imm) ADDI_STATE(R[m], (imm), Rm) -#define ADDI_R0_NOREG(imm) ADDI_STATE_NOREG(R[0], (imm)) -#define ADDI_R15_NOREG(imm) ADDI_STATE_NOREG(R[15], (imm)) -#define ADDI_Rn_NOREG(imm) ADDI_STATE_NOREG(R[n], (imm)) -#define ADDI_Rm_NOREG(imm) ADDI_STATE_NOREG(R[m], (imm)) - -/* Local convenience macro for updating the cycle count */ - -#define ADD_CYCLES() do { \ - if (cur_cycles > 0) { \ - ADDI_STATE_NOREG(cycles, cur_cycles); \ - cur_cycles = 0; \ - } \ -} while (0) - -/*-----------------------------------------------------------------------*/ - -/* Local convenience macros for loading or storing values with various - * addressing modes */ - -/* Increment/decrement amounts */ -#define INCDEC_B 1 -#define INCDEC_W 2 -#define INCDEC_L 4 - -/*----------------------------------*/ - -#define LOAD_Rm(size,dest) LOAD_disp_Rm(size, dest, 0) - -#define LOAD_disp_Rm(size,dest,offset) \ - if (REG_GETKNOWN(REG_R(m)) == 0xFFFFFFFF) { \ - SH2_LOAD_ABS_##size(dest, REG_GETVALUE(REG_R(m)) + (offset)); \ - } else { \ - SH2_LOAD_REG_##size(dest, m, (offset), 0); \ - } - -/* Only treat R0 as an offset if it's "small" -- otherwise we might end up - * treating a small value in Rm as a pointer */ -#define LOAD_R0_Rm(size,dest) \ - if (REG_GETKNOWN(REG_R(0)) == 0xFFFFFFFF \ - && REG_GETVALUE(REG_R(0)) + 0x8000 < 0x10000 \ - ) { \ - SH2_LOAD_REG_##size(dest, m, REG_GETVALUE(REG_R(0)), 0); \ - } else { \ - GET_R0_KEEPOFS; \ - GET_Rm_KEEPOFS; \ - DEFINE_REG(address); \ - ADD(address, R0, Rm); \ - const int32_t offset = STATE_CACHE_OFFSET(R[0]) \ - + STATE_CACHE_OFFSET(R[m]); \ - DECLARE_REG(offset_addr); \ - if (offset) { \ - ALLOC_REG(offset_addr); \ - ADDI(offset_addr, address, offset); \ - } else { \ - offset_addr = address; \ - } \ - SH2_LOAD_##size(dest, offset_addr); \ - } - -#define LOAD_Rm_inc(size,dest) \ - if (REG_GETKNOWN(REG_R(m)) == 0xFFFFFFFF) { \ - SH2_LOAD_ABS_##size(dest, REG_GETVALUE(REG_R(m))); \ - ADDI_Rm_NOREG(INCDEC_##size); \ - REG_SETVALUE(REG_R(m), REG_GETVALUE(REG_R(m)) + INCDEC_##size); \ - } else { \ - SH2_LOAD_REG_##size(dest, m, 0, 1); \ - REG_SETKNOWN(REG_R(m), 0); \ - } - -#define LOAD_Rn(size,dest) \ - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { \ - SH2_LOAD_ABS_##size(dest, REG_GETVALUE(REG_R(n))); \ - } else { \ - SH2_LOAD_REG_##size(dest, n, 0, 0); \ - } - -#define LOAD_Rn_inc(size,dest) \ - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { \ - SH2_LOAD_ABS_##size(dest, REG_GETVALUE(REG_R(n))); \ - ADDI_Rn_NOREG(INCDEC_##size); \ - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) + INCDEC_##size); \ - } else { \ - SH2_LOAD_REG_##size(dest, n, 0, 1); \ - REG_SETKNOWN(REG_R(n), 0); \ - } - -#define LOAD_disp_GBR(size,dest,offset) \ - GET_GBR_KEEPOFS; \ - const int32_t final_offset = STATE_CACHE_OFFSET(GBR) + (offset); \ - DECLARE_REG(address); \ - if (final_offset) { \ - ALLOC_REG(address); \ - ADDI(address, GBR, final_offset); \ - } else { \ - address = GBR; \ - } \ - SH2_LOAD_##size(dest, address) - -#define LOAD_R0_GBR(size,dest) \ - DECLARE_REG(address); \ - GET_GBR_KEEPOFS; \ - if (REG_GETKNOWN(REG_R(0)) == 0xFFFFFFFF) { \ - const int32_t offset = STATE_CACHE_OFFSET(GBR) \ - + REG_GETVALUE(REG_R(0)); \ - if (offset) { \ - ALLOC_REG(address); \ - ADDI(address, GBR, offset); \ - } else { \ - address = GBR; \ - } \ - } else { \ - GET_R0_KEEPOFS; \ - DEFINE_REG(temp); \ - ADD(temp, R0, GBR); \ - const int32_t offset = STATE_CACHE_OFFSET(GBR) \ - + STATE_CACHE_OFFSET(R[0]); \ - if (offset) { \ - ALLOC_REG(address); \ - ADDI(address, temp, offset); \ - } else { \ - address = temp; \ - } \ - } \ - SH2_LOAD_##size(dest, address) - -/*----------------------------------*/ - -#define STORE_Rn(size,value) STORE_disp_Rn(size, value, 0) - -#define STORE_disp_Rn(size,value,offset) \ - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { \ - SH2_STORE_ABS_##size(REG_GETVALUE(REG_R(n)) + (offset), value, \ - PTR_ISLOCAL(n)); \ - } else { \ - SH2_STORE_REG_##size(n, value, offset, 0); \ - } - -#define STORE_dec_Rn(size,value) \ - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { \ - ADDI_Rn_NOREG(-INCDEC_##size); \ - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) - INCDEC_##size); \ - SH2_STORE_ABS_##size(REG_GETVALUE(REG_R(n)), value, \ - PTR_ISLOCAL(n)); \ - } else { \ - REG_SETKNOWN(REG_R(n), 0); \ - SH2_STORE_REG_##size(n, value, 0, 1); \ - } - -#define STORE_R0_Rn(size,value) \ - if (REG_GETKNOWN(REG_R(0)) == 0xFFFFFFFF \ - && REG_GETVALUE(REG_R(0)) + 0x8000 < 0x10000 \ - ) { \ - SH2_STORE_REG_##size(n, value, REG_GETVALUE(REG_R(0)), 0); \ - } else { \ - GET_R0_KEEPOFS; \ - GET_Rn_KEEPOFS; \ - DEFINE_REG(address); \ - ADD(address, R0, Rn); \ - const int32_t offset = STATE_CACHE_OFFSET(R[0]) \ - + STATE_CACHE_OFFSET(R[n]); \ - DECLARE_REG(offset_addr); \ - if (offset) { \ - ALLOC_REG(offset_addr); \ - ADDI(offset_addr, address, offset); \ - } else { \ - offset_addr = address; \ - } \ - SH2_STORE_##size(offset_addr, value); \ - } - -#define STORE_disp_Rm(size,value,offset) \ - if (REG_GETKNOWN(REG_R(m)) == 0xFFFFFFFF) { \ - SH2_STORE_ABS_##size(REG_GETVALUE(REG_R(m)) + (offset), value, \ - PTR_ISLOCAL(n)); \ - } else { \ - SH2_STORE_REG_##size(m, value, offset, 0); \ - } - -#define STORE_disp_GBR(size,value,offset) \ - GET_GBR_KEEPOFS; \ - const int32_t final_offset = STATE_CACHE_OFFSET(GBR) + (offset); \ - DECLARE_REG(address); \ - if (final_offset) { \ - ALLOC_REG(address); \ - ADDI(address, GBR, final_offset); \ - } else { \ - address = GBR; \ - } \ - SH2_STORE_##size(address, value) - -/* @(R0,GBR) is only used in RMW instructions, so use the saved address */ -#define STORE_SAVED_R0_GBR(size,value) \ - SH2_STORE_##size(address, value) - -/*-----------------------------------------------------------------------*/ - -/* Local convenience macro to take a specified exception (immediate value), - * using the specified register as the return PC. */ - -#define TAKE_EXCEPTION(imm_index,PC_reg) do { \ - /* Push SR and PC */ \ - GET_R15_KEEPOFS; \ - GET_SR; \ - SH2_STORE_REG_L(15, SR, 0, 1); \ - SH2_STORE_REG_L(15, PC_reg, 0, 1); \ - if (REG_GETKNOWN(REG_R(15)) == 0xFFFFFFFF) { \ - REG_SETVALUE(REG_R(15), REG_GETVALUE(REG_R(15)) - 8); \ - } else { \ - REG_SETKNOWN(REG_R(15), 0); \ - } \ - /* Call the exception vector */ \ - DEFINE_REG(target); \ - SH2_LOAD_ABS_L(target, (imm_index) << 2); \ - SET_PC(target); \ - FLUSH_STATE_CACHE(); \ - JUMP(); \ -} while (0) - -/*-----------------------------------------------------------------------*/ - -#ifdef OPTIMIZE_SHIFT_SEQUENCES - -/* - * Local macro to retrieve the next opcode for use with shift optimization; - * the opcode is stored in the variable "next_opcode". If the next opcode - * in the instruction stream is a delayed branch which does not depend on - * the value of the register being shifted (Rn of the current instruction) - * or the T bit set by the shift (if a single-bit shift or rotate), then - * the instruction in the branch's delay slot is retrieved instead. If the - * next opcode cannot be retrieved, either because we've reached the end of - * the block or because we're interpreting, or if the instruction is not in - * directly-accessible memory, zero is stored in next_opcode. - */ - -# define GET_NEXT_OPCODE_FOR_SHIFT_CACHE \ - uint16_t next_opcode; \ - if (fetch && INSN_IS_AVAILABLE(1)) { \ - next_opcode = fetch[1]; \ - if (INSN_IS_AVAILABLE(2)) { \ - int use_delay = 0; \ - if ((next_opcode & 0xF0DF) == 0x0003 \ - || (next_opcode & 0xF0DF) == 0x400B) { \ - /* BSRF/BRAF Rn, JSR/JMP @Rn */ \ - use_delay = ((next_opcode>>8 & 0xF) != n); \ - } else if ((next_opcode & 0xFD00) == 0x8D00) { \ - /* BT/S, BF/S (allow only SHL[LR]#) */ \ - use_delay = ((opcode & 0xF00F) == 0x4008); \ - } else if ((next_opcode & 0xF0DF) == 0x000B \ - || (next_opcode & 0xE000) == 0xA000) { \ - /* RTS/RTE, BRA/BSR */ \ - use_delay = 1; \ - } \ - if (use_delay) { \ - next_opcode = fetch[2]; \ - } \ - } \ - } else { \ - next_opcode = 0; \ - } - -#endif // OPTIMIZE_SHIFT_SEQUENCES - -/*-----------------------------------------------------------------------*/ - -/* - * Debugging macro to print a line the first time an instruction is seen - * (enabled when DEBUG_DECODER_INSN_COVERAGE is defined by the including - * file). A full list of these can be generated with: - * - * grep -F 'DEBUG_PRINT_ONCE("' sh2-core.i | sed 's/^[^"]*"\([^"]*\).*$/\1/' - */ - -#ifdef DEBUG_DECODER_INSN_COVERAGE -# define DEBUG_PRINT_ONCE(insn) do { \ - static int seen = 0; \ - if (!seen) { \ - fprintf(stderr, "%s\n", insn); \ - seen = 1; \ - } \ -} while (0) -#else -# define DEBUG_PRINT_ONCE(insn) /*nothing*/ -#endif - -/*************************************************************************/ - -#ifndef DECODE_INSN_INLINE -# define DECODE_INSN_INLINE /*nothing*/ -#endif - -/** - * decode_insn: Decode a single SH-2 instruction. Implements - * translate_insn() using the shared decoder core. - * - * [Parameters] - * Defined by including file - * [Return value] - * Decoded SH-2 opcode, or value returned by micro-ops - */ -static DECODE_INSN_INLINE unsigned int decode_insn(DECODE_INSN_PARAMS) -{ - uint16_t opcode; - - /* Load the opcode to decode */ - - if (fetch) { - opcode = *fetch; - } else { - opcode = MappedMemoryReadWord(cur_PC); - } - - /* Perform any early processing required */ - - OPCODE_INIT(opcode); - - /* If tracing, trace the instruction (do this after OPCODE_INIT() so - * the JIT branch target label gets added before the trace call) */ - -#ifdef TRACE - DEFINE_REG(trace_PC); - MOVEI(trace_PC, cur_PC); - DEFINE_REG(trace_funcptr); - MOVEA(trace_funcptr, trace_insn_callback); - CALL_NORET(state_reg, trace_PC, trace_funcptr); -#endif - - /* Save and clear the delay flag (this needs to be done here, not at - * the end of the previous iteration, so (1) the translator knows not - * to interrupt the pair of instructions and (2) the delay flag can be - * accessed by OPCODE_INIT() if needed) */ - - const int in_delay = state->delay; - state->delay = 0; - - /* Clear the just-branched flag on every instruction, so - * fall-off-the-end is detected properly; we'll set it later if we - * branch after this instruction */ - - state->just_branched = 0; - - /* Record the number of cycles used by this instruction (any additional - * cycles necessary are added by the individual opcode handlers) */ - - int cur_cycles = 1; - - /**** The Big Honkin' Opcode Switch Begins Here ****/ - - /* Extract these early for convenience */ - const unsigned int n = opcode>>8 & 0xF; - const unsigned int m = opcode>>4 & 0xF; - - /* Note: Mnemonics listed here for some instructions differ slightly - * from the official Hitachi specs. Here, register Rn _always_ refers - * to the register specified by bits 8-11 of the opcode, and register - * Rm _always_ refers to the register specified by bits 4-7 of the - * opcode, regardless of the register's role (source or destination). */ - - switch (opcode>>12 & 0xF) { - - case 0x0: { - switch (opcode & 0xFF) { - - // $0xx2 - case 0x02: { // STC SR,Rn - DEBUG_PRINT_ONCE("STC SR,Rn"); - COPY_TO_Rn(SR); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - case 0x12: { // STC GBR,Rn - DEBUG_PRINT_ONCE("STC GBR,Rn"); - COPY_TO_Rn(GBR); - REG_SETKNOWN(REG_R(n), REG_GETKNOWN(REG_GBR)); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_GBR)); - PTR_CLEAR(n); - break; - } - case 0x22: { // STC VBR,Rn - DEBUG_PRINT_ONCE("STC VBR,Rn"); - COPY_TO_Rn(VBR); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - // $0xx3 - case 0x03: { // BSRF Rn - DEBUG_PRINT_ONCE("BSRF Rn"); - DEFINE_RESULT_REG(ret_addr, PR); - MOVEI(ret_addr, cur_PC + 4); - SET_PR(ret_addr); - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { - state->branch_type = SH2BRTYPE_STATIC; - state->branch_target = (cur_PC + 4) + REG_GETVALUE(REG_R(n)); - } else { - state->branch_type = SH2BRTYPE_DYNAMIC; - GET_Rn; - DEFINE_REG(target); - ADD(target, ret_addr, Rn); - state->branch_target_reg = target; - } - state->delay = 1; - cur_cycles += 1; - break; - } - case 0x23: { // BRAF Rn - DEBUG_PRINT_ONCE("BRAF Rn"); -#ifdef OPTIMIZE_VARIABLE_SHIFTS - if (fetch) { - unsigned int Rshift, count_max, Rcount, type; - const unsigned int num_insns = can_optimize_variable_shift( - fetch, cur_PC, &Rcount, &count_max, &Rshift, &type, NULL - ); - if (num_insns) { - state->varshift_target_PC = cur_PC + 2*num_insns; - state->varshift_type = type; - state->varshift_Rcount = Rcount; - state->varshift_max = count_max; - state->varshift_Rshift = Rshift; - } - } -#endif - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { - state->branch_type = SH2BRTYPE_STATIC; - state->branch_target = (cur_PC + 4) + REG_GETVALUE(REG_R(n)); - } else { - state->branch_type = SH2BRTYPE_DYNAMIC; - GET_Rn; - DEFINE_REG(target); - ADDI(target, Rn, cur_PC + 4); - state->branch_target_reg = target; - } - state->delay = 1; - cur_cycles += 1; - break; - } - - // $0xx4 - case 0x04: case 0x14: case 0x24: case 0x34: - case 0x44: case 0x54: case 0x64: case 0x74: - case 0x84: case 0x94: case 0xA4: case 0xB4: - case 0xC4: case 0xD4: case 0xE4: case 0xF4: { // MOV.B Rm,@(R0,Rn) - DEBUG_PRINT_ONCE("MOV.B Rm,@(R0,Rn)"); - GET_Rm_B; - STORE_R0_Rn(B, Rm); - break; - } - - // $0xx5 - case 0x05: case 0x15: case 0x25: case 0x35: - case 0x45: case 0x55: case 0x65: case 0x75: - case 0x85: case 0x95: case 0xA5: case 0xB5: - case 0xC5: case 0xD5: case 0xE5: case 0xF5: { // MOV.W Rm,@(R0,Rn) - DEBUG_PRINT_ONCE("MOV.W Rm,@(R0,Rn)"); - GET_Rm_W; - STORE_R0_Rn(W, Rm); - break; - } - - // $0xx6 - case 0x06: case 0x16: case 0x26: case 0x36: - case 0x46: case 0x56: case 0x66: case 0x76: - case 0x86: case 0x96: case 0xA6: case 0xB6: - case 0xC6: case 0xD6: case 0xE6: case 0xF6: { // MOV.L Rm,@(R0,Rn) - DEBUG_PRINT_ONCE("MOV.L Rm,@(R0,Rn)"); - GET_Rm; - STORE_R0_Rn(L, Rm); - break; - } - - // $0xx7 - case 0x07: case 0x17: case 0x27: case 0x37: - case 0x47: case 0x57: case 0x67: case 0x77: - case 0x87: case 0x97: case 0xA7: case 0xB7: - case 0xC7: case 0xD7: case 0xE7: case 0xF7: { // MUL.L Rm,Rn - DEBUG_PRINT_ONCE("MUL.L Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(result, MACL); - MUL(result, Rn, Rm); - SET_MACL(result); - CLEAR_MAC_IS_ZERO(); - cur_cycles += 1; // Minimum number of cycles - break; - } - - // $0xx8 - case 0x08: { // CLRT - DEBUG_PRINT_ONCE("CLRT"); - DEFINE_REG(zero); - MOVEI(zero, 0); - SET_SR_T(zero); - break; - } - case 0x18: { // SETT - DEBUG_PRINT_ONCE("SETT"); - DEFINE_REG(one); - MOVEI(one, 1); - SET_SR_T(one); - break; - } - case 0x28: { // CLRMAC - DEBUG_PRINT_ONCE("CLRMAC"); - DEFINE_RESULT_REG(MACH, MACH); - MOVEI(MACH, 0); - SET_MACH(MACH); - DEFINE_RESULT_REG(MACL, MACL); - MOVEI(MACL, 0); - SET_MACL(MACL); - SET_MAC_IS_ZERO(); - break; - } - - // $0xx9 - case 0x09: { // NOP - DEBUG_PRINT_ONCE("NOP"); - /* No operation */ - break; - } - case 0x19: { // DIV0U - DEBUG_PRINT_ONCE("DIV0U"); - GET_SR; - DEFINE_RESULT_REG(new_SR, SR); - ANDI(new_SR, SR, ~(SR_T | SR_Q | SR_M)); - SET_SR(new_SR); -#ifdef OPTIMIZE_DIVISION - int Rlo = -1, Rhi = -1, Rdiv = -1; // Register numbers - int div_bits = 0; // Number of bits of division to perform - int skip_first_rotcl = 0; // Is the 1st ROTCL skipped? (see below) - /* Don't try to optimize if the DIV0U is sitting in a - * branch delay slot; also, only optimize when we can do - * direct fetching (otherwise our read-aheads might have side - * effects). */ - if (LIKELY(!in_delay) && fetch) { - if ((fetch[1] & 0xF00F) == 0x3004 - && (fetch[2] & 0xF0FF) == 0x4024 - ) { - /* If the value of Rlo is zero, the first ROTCL may be - * omitted (since neither Rlo or SR.T would change). */ -#ifdef __GNUC__ // Avoid a warning if known value optimization is disabled - __attribute__((unused)) -#endif - const int rotcl_Rn = fetch[2]>>8 & 0xF; - if (REG_GETKNOWN(REG_R(rotcl_Rn)) == 0xFFFFFFFF - && REG_GETVALUE(REG_R(rotcl_Rn)) == 0 - ) { - skip_first_rotcl = 1; - } - } - div_bits = can_optimize_div0u(fetch, cur_PC, skip_first_rotcl, - &Rhi, &Rlo, &Rdiv); - } - if (div_bits > 0) { -# ifdef JIT_DEBUG_VERBOSE - DMSG("Optimizing unsigned division at 0x%08X", (int)cur_PC); -# endif - /* Set up optimization flags/data */ - const int is_32bit = (REG_GETKNOWN(Rhi) == 0xFFFFFFFF - && REG_GETVALUE(Rhi) == 0); - const int safe_division = - (optimization_flags & SH2_OPTIMIZE_ASSUME_SAFE_DIVISION); - state->division_target_PC = cur_PC + div_bits*4; - if (!safe_division) { - /* Flush cached data since we jump out from inside the - * runtime conditional. */ - ADD_CYCLES(); - FLUSH_STATE_CACHE(); - } else { - /* No need to flush data because we omit the - * unoptimized code entirely. */ - } - /* Load operands */ - DECLARE_REG(lo); - LOAD_STATE_ALLOC(lo, R[Rlo]); - DECLARE_REG(div); - LOAD_STATE_ALLOC(div, R[Rdiv]); - DECLARE_REG(hi); - LOAD_STATE_ALLOC(hi, R[Rhi]); - /* Define output registers (shared across all cases) */ - DEFINE_REG(quotient); - DEFINE_REG(remainder); - /* If the divide is less than 32 bits, save the low bits of - * the dividend. We don't shift the dividend right yet - * because we have to check Rhi first; the divide will - * still misbehave if Rhi >= div. */ - DECLARE_REG(lo_lowbits); - if (div_bits < 32) { - ALLOC_REG(lo_lowbits); - SLLI(lo_lowbits, lo, 32 - div_bits); - } else { // Not needed, but avoid a compiler warning - lo_lowbits = 0; - } - /* Allocate labels for use in non-optimized cases */ - CREATE_LABEL(div0u_not_safe); - CREATE_LABEL(div0u_not_32bit); - CREATE_LABEL(div0u_done); - if (!safe_division) { - GOTO_IF_Z(div0u_not_safe, div); - } - if (!is_32bit) { - GOTO_IF_NZ(div0u_not_32bit, hi); - } - /* Divide 32 bits by 32 bits, unsigned */ - if (div_bits < 32) { - /* Note: SSA violation */ - SRLI(lo, lo, 32 - div_bits); - } - DIVMODU(quotient, lo, div, remainder); - if (!is_32bit) { - GOTO_LABEL(div0u_done); - DEFINE_LABEL(div0u_not_32bit); - if (!safe_division) { - DEFINE_REG(test_safe); - SLTU(test_safe, hi, div); - GOTO_IF_Z(div0u_not_safe, test_safe); - } - if (div_bits < 32) { - /* Note: SSA violations */ - SRLI(lo, lo, 32 - div_bits); - BFINS(lo, lo, hi, div_bits, 32 - div_bits); - SRLI(hi, hi, 32 - div_bits); - } - /* - * Divide 64 bits by 32 bits, unsigned, when the - * quotient is known to fit in 32 bits. - * - * Here, we use the algorithm followed by GCC (among - * others), which is essentially to perform long - * division in base 2^16 with a normalized divisor, - * i.e. a divisor with the highest bit set. We divide - * the two-"digit" divisor into the upper three - * "digits" of the dividend, then append the final - * "digit" to the remainder and divide again. Since - * operands to a division instruction can only be 32 - * bits, i.e. 2 "digits", we process the divisor one - * "digit" at a time. - * - * To demonstrate, this is how it would work if a word - * consisted of two decimal digits (i.e. 0-99): - * _____ - * 59)5023 - * -50 Step 1: 50/5 = 10 (q1), 10*5 = 50 - * ---- - * 2 Step 2: Carry down the next digit - * Step 3: Is the remainder less than 10*9? - * +59 Step 3A: Yes, so add 59 and decrement q1 - * ---- (q1=9) - * 61 Step 3B: Is the remainder still less than 10*9? - * +59 Step 3C: Yes, so add 59 and decrement q1 again - * ---- (q1=8) (since the divisor is normalized, - * 120 we will never need to add it more - * than twice to avoid borrowing) - * -90 Step 4: Subtract 10*9 - * ---- - * 30 (Repeat steps 1-4) - * -30 Step 5: 30/5 = 6 (q0), 6*5 = 30 - * ---- - * 3 Step 6: Carry down the next (last) digit - * Step 7: Is the remainder less than 6*9? - * +59 Step 7A: Yes, so add 59 and decrement q0 - * ---- (q0=5) - * 62 Step 7B: Is the remainder still less than 6*9? - * Step 7C: No, so skip the add and decrement - * -54 Step 8: Subtract 6*9 - * ---- - * 8 Result: quotient 85, remainder 8 - */ - /* Normalize the divisor and dividend */ - DEFINE_REG(norm_shift); - CLZ(norm_shift, div); - DEFINE_REG(hi_norm_temp1); - SLL(hi_norm_temp1, hi, norm_shift); - DEFINE_REG(imm_32); - MOVEI(imm_32, 32); - DEFINE_REG(norm_invshift); - SUB(norm_invshift, imm_32, norm_shift); - DEFINE_REG(hi_norm_temp2); - SRL(hi_norm_temp2, lo, norm_invshift); - DEFINE_REG(hi_norm_temp3); - OR(hi_norm_temp3, hi_norm_temp1, hi_norm_temp2); - /* Need to SELECT here in case norm_shift==0, because - * shifting by 32 bits (norm_invshift) is undefined */ - DEFINE_REG(hi_norm); - SELECT(hi_norm, hi_norm_temp3, hi, norm_shift); - DEFINE_REG(lo_norm); - SLL(lo_norm, lo, norm_shift); - DEFINE_REG(div_norm); - SLL(div_norm, div, norm_shift); - /* Extract the upper and lower halfwords of the divisor */ - DEFINE_REG(div1); - SRLI(div1, div_norm, 16); - DEFINE_REG(div0); - ANDI(div0, div_norm, 0xFFFF); - /* Divide the upper 48 bits (steps 1-4) */ - DEFINE_REG(q1); - DEFINE_REG(mid_norm); - DIVMODU(q1, hi_norm, div1, mid_norm); // Step 1 - SLLI(mid_norm, mid_norm, 16); - DEFINE_REG(mid_norm_temp); - SRLI(mid_norm_temp, lo_norm, 16); - OR(mid_norm, mid_norm, mid_norm_temp); // Step 2 - DEFINE_REG(q1_div0); - MUL(q1_div0, q1, div0); - CREATE_LABEL(div0u_mid_done); - DEFINE_REG(mid_test1); - SLTU(mid_test1, mid_norm, q1_div0); // Step 3 - GOTO_IF_Z(div0u_mid_done, mid_test1); { - ADD(mid_norm, mid_norm, div_norm); // Step 3A - SUBI(q1, q1, 1); - /* If mid_norm < div_norm, then we overflowed and - * have a virtual 1 in bit position 32, so mid_norm - * must be greater than q1_div0 */ - DEFINE_REG(mid_test2a); - SLTU(mid_test2a, mid_norm, div_norm); // Step 3B - DEFINE_REG(mid_test2b); - SLTU(mid_test2b, mid_norm, q1_div0); - GOTO_IF_NZ(div0u_mid_done, mid_test2a); - GOTO_IF_Z(div0u_mid_done, mid_test2b); { - ADD(mid_norm, mid_norm, div_norm); // Step 3C - SUBI(q1, q1, 1); - } - } DEFINE_LABEL(div0u_mid_done); - SUB(mid_norm, mid_norm, q1_div0); // Step 4 - /* Divide the last 16 bits (steps 5-8) */ - DEFINE_REG(q0); - DEFINE_REG(rem_norm); - DIVMODU(q0, mid_norm, div1, rem_norm); // Step 5 - SLLI(rem_norm, rem_norm, 16); - DEFINE_REG(rem_norm_temp); - ANDI(rem_norm_temp, lo_norm, 0xFFFF); - OR(rem_norm, rem_norm, rem_norm_temp); // Step 6 - DEFINE_REG(q0_div0); - MUL(q0_div0, q0, div0); - CREATE_LABEL(div0u_lo_done); - DEFINE_REG(lo_test1); - SLTU(lo_test1, rem_norm, q0_div0); // Step 7 - GOTO_IF_Z(div0u_lo_done, lo_test1); { - ADD(rem_norm, rem_norm, div_norm); // Step 7A - SUBI(q0, q0, 1); - DEFINE_REG(lo_test2a); - SLTU(lo_test2a, rem_norm, div_norm); // Step 7B - DEFINE_REG(lo_test2b); - SLTU(lo_test2b, rem_norm, q0_div0); - GOTO_IF_NZ(div0u_lo_done, lo_test2a); - GOTO_IF_Z(div0u_lo_done, lo_test2b); { - ADD(rem_norm, rem_norm, div_norm); // Step 7C - SUBI(q0, q0, 1); - } - } DEFINE_LABEL(div0u_lo_done); - SUB(rem_norm, rem_norm, q0_div0); // Step 8 - /* Merge the two quotient halves */ - BFINS(quotient, q0, q1, 16, 16); - /* Un-normalize the remainder */ - SRL(remainder, rem_norm, norm_shift); - DEFINE_LABEL(div0u_done); - } // if (!is_32bit) - /* Process the division result */ - DEFINE_REG(new_T); - ANDI(new_T, quotient, 1); // Low bit to T flag - DEFINE_RESULT_REG(quo_out, R[Rlo]); - if (div_bits < 32) { - DEFINE_REG(quo_temp); - SRLI(quo_temp, quotient, 1); - OR(quo_out, quo_temp, lo_lowbits); - } else { - SRLI(quo_out, quotient, 1); - } - STORE_STATE(R[Rlo], quo_out); - REG_SETKNOWN(REG_R(Rlo), 0); - DEFINE_REG(temp0); - SUB(temp0, remainder, div); - DEFINE_REG(rem_out); - SELECT(rem_out, remainder, temp0, new_T); - STORE_STATE(R[Rhi], rem_out); - REG_SETKNOWN(REG_R(Rhi), 0); - DEFINE_REG(SR_temp); - OR(SR_temp, new_SR, new_T); - DEFINE_REG(new_Q); - XORI(new_Q, new_T, 1); - DEFINE_RESULT_REG(SR_out, SR); - BFINS(SR_out, SR_temp, new_Q, SR_Q_SHIFT, 1); - SET_SR(SR_out); - /* Skip over the step-by-step emulation */ - const unsigned int skipped_insns = - div_bits*2 - (skip_first_rotcl ? 1 : 0); - cur_cycles += skipped_insns; - if (!safe_division) { - ADD_CYCLES(); - SET_PC_KNOWN(cur_PC + (2 + skipped_insns*2)); - state->branch_target = cur_PC + (2 + skipped_insns*2); - FLUSH_STATE_CACHE(); - JUMP_STATIC(); - DEFINE_LABEL(div0u_not_safe); - } else { - INC_PC_BY(skipped_insns*2); - } - } // if (div_bits > 0) -#endif // OPTIMIZE_DIVISION - break; - } // DIV0U - case 0x29: { // MOVT Rn - DEBUG_PRINT_ONCE("MOVT Rn"); - GET_SR_T; - SET_Rn(T); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFE); - REG_SETVALUE(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - // $0xxA - case 0x0A: { // STS MACH,Rn - DEBUG_PRINT_ONCE("STS MACH,Rn"); - if (STATE_CACHE_FIXED_REG_WRITABLE(R[n])) { - COPY_TO_Rn(MACH); - } else { - /* Make sure Rn gets a copy of the register so it's not - * altered by subsequent MAC instructions */ - GET_MACH_COPY; - SET_Rn(MACH); - } - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - case 0x1A: { // STS MACL,Rn - DEBUG_PRINT_ONCE("STS MACL,Rn"); - if (STATE_CACHE_FIXED_REG_WRITABLE(R[n])) { - COPY_TO_Rn(MACL); - } else { - GET_MACL_COPY; - SET_Rn(MACL); - } - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - case 0x2A: { // STS PR,Rn - DEBUG_PRINT_ONCE("STS PR,Rn"); - COPY_TO_Rn(PR); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - // $0xxB - case 0x0B: { // RTS - DEBUG_PRINT_ONCE("RTS"); - /* We don't do anything if this is an RTS from a folded - * subroutine, since that's handled by our caller. */ - if (!state->folding_subroutine) { - state->branch_type = SH2BRTYPE_DYNAMIC; - GET_PR; - state->branch_target_reg = PR; - state->delay = 1; - } - cur_cycles += 1; - break; - } - case 0x1B: { // SLEEP - DEBUG_PRINT_ONCE("SLEEP"); - cur_cycles += 2; - ADD_CYCLES(); - FLUSH_STATE_CACHE(); - DEFINE_REG(check_interrupts_funcptr); - MOVEA(check_interrupts_funcptr, check_interrupts); - DEFINE_REG(result); - CALL(result, state_reg, 0, check_interrupts_funcptr); - CREATE_LABEL(sleep_intr); - GOTO_IF_NZ(sleep_intr, result); { - DEFINE_REG(imm_1); - MOVEI(imm_1, 1); - STORE_STATE_B(asleep, imm_1); - DEFINE_REG(cycle_limit); - LOAD_STATE(cycle_limit, cycle_limit); - STORE_STATE(cycles, cycle_limit); - } DEFINE_LABEL(sleep_intr); - RETURN(); - break; - } - case 0x2B: { // RTE - DEBUG_PRINT_ONCE("RTE"); - GET_R15_KEEPOFS; - DEFINE_REG(new_PC); - SH2_LOAD_REG_L(new_PC, 15, 0, 1); - DEFINE_REG(new_SR); - SH2_LOAD_REG_L(new_SR, 15, 0, 1); - if (REG_GETKNOWN(REG_R(15)) == 0xFFFFFFFF) { - REG_SETVALUE(REG_R(15), REG_GETVALUE(REG_R(15)) + 8); - } else { - REG_SETKNOWN(REG_R(15), 0); - } - REG_SETKNOWN(REG_R(15), REG_GETKNOWN(REG_R(15)) & 7); - state->branch_type = SH2BRTYPE_RTE; - state->branch_target_reg = new_PC; - DEFINE_RESULT_REG(new_SR_3F3, SR); - ANDI(new_SR_3F3, new_SR, 0x3F3); - SET_SR(new_SR_3F3); - DEFINE_REG(imm_1); - MOVEI(imm_1, 1); - state->delay = 1; - cur_cycles += 3; - break; - } - - // $0xxC - case 0x0C: case 0x1C: case 0x2C: case 0x3C: - case 0x4C: case 0x5C: case 0x6C: case 0x7C: - case 0x8C: case 0x9C: case 0xAC: case 0xBC: - case 0xCC: case 0xDC: case 0xEC: case 0xFC: { // MOV.B @(R0,Rm),Rn - DEBUG_PRINT_ONCE("MOV.B @(R0,Rm),Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_R0_Rm(B, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - // $0xxD - case 0x0D: case 0x1D: case 0x2D: case 0x3D: - case 0x4D: case 0x5D: case 0x6D: case 0x7D: - case 0x8D: case 0x9D: case 0xAD: case 0xBD: - case 0xCD: case 0xDD: case 0xED: case 0xFD: { // MOV.W @(R0,Rm),Rn - DEBUG_PRINT_ONCE("MOV.W @(R0,Rm),Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_R0_Rm(W, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - // $0xxE - case 0x0E: case 0x1E: case 0x2E: case 0x3E: - case 0x4E: case 0x5E: case 0x6E: case 0x7E: - case 0x8E: case 0x9E: case 0xAE: case 0xBE: - case 0xCE: case 0xDE: case 0xEE: case 0xFE: { // MOV.L @(R0,Rm),Rn - DEBUG_PRINT_ONCE("MOV.L @(R0,Rm),Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_R0_Rm(L, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - // $0xxF - case 0x0F: case 0x1F: case 0x2F: case 0x3F: - case 0x4F: case 0x5F: case 0x6F: case 0x7F: - case 0x8F: case 0x9F: case 0xAF: case 0xBF: - case 0xCF: case 0xDF: case 0xEF: case 0xFF: { // MAC.L @Rm+,@Rn+ - DEBUG_PRINT_ONCE("MAC.L @Rm+,@Rn+"); - - /* Load the values */ - DEFINE_REG(value_m); - LOAD_Rm_inc(L, value_m); - DEFINE_REG(value_n); - LOAD_Rn_inc(L, value_n); - - /* Do the actual multiplication and addition */ - if (MAC_IS_ZERO()) { - DEFINE_RESULT_REG(new_MACL, MACL); - DEFINE_RESULT_REG(new_MACH, MACH); - MULS_64(new_MACL, value_m, value_n, new_MACH); - SET_MACL(new_MACL); - SET_MACH(new_MACH); - } else { - GET_MACL; - GET_MACH; - MADDS_64(MACL, value_m, value_n, MACH); - SET_MACL(MACL); - SET_MACH(MACH); - } - - /* Perform saturation if the S flag of SR is set */ - if (!CAN_OMIT_MAC_S_CHECK) { - GET_SR; - DEFINE_REG(saturate); - ANDI(saturate, SR, SR_S); - CREATE_LABEL(macl_nosat); - GOTO_IF_Z(macl_nosat, saturate); { - GET_MACL; - GET_MACH; - DEFINE_REG(saturate_minus); - SLTSI(saturate_minus, MACH, -0x7FFF); - CREATE_LABEL(macl_sat_nominus); - GOTO_IF_Z(macl_sat_nominus, saturate_minus); { - DEFINE_REG(temp); - MOVEI(temp, -0x8000); - /* Note: SSA violations for state block optimization */ - MOVE(MACH, temp); - SET_MACH(MACH); - MOVEI(MACL, 0); - SET_MACL(MACL); - GOTO_LABEL(macl_nosat); - } DEFINE_LABEL(macl_sat_nominus); - DEFINE_REG(satplus_test); - SUBI(satplus_test, MACH, 0x8000); - DEFINE_REG(inv_saturate_plus); // Inverse value - SLTSI(inv_saturate_plus, satplus_test, 0); - GOTO_IF_NZ(macl_nosat, inv_saturate_plus); { - DEFINE_REG(temp1); - MOVEI(temp1, 0x7FFF); - /* Note: SSA violations for state block optimization */ - MOVE(MACH, temp1); - SET_MACH(MACH); - DEFINE_REG(temp2); - MOVEI(temp2, 0xFFFFFFFF); - MOVE(MACL, temp2); - SET_MACL(MACL); - } - } DEFINE_LABEL(macl_nosat); - } // if (!CAN_OMIT_MAC_S_CHECK) - - CLEAR_MAC_IS_ZERO(); - cur_cycles += 2; - break; - } // MAC.L - - default: - goto invalid; - } - break; - } // $0xxx - - case 0x1: { // MOV.L Rm,@(disp,Rn) - DEBUG_PRINT_ONCE("MOV.L Rm,@(disp,Rn)"); - const int disp = (opcode & 0xF) * 4; - GET_Rm; - STORE_disp_Rn(L, Rm, disp); - break; - } // $1xxx - - case 0x2: { - switch (opcode & 0xF) { - - case 0x0: { // MOV.B Rm,@Rn - DEBUG_PRINT_ONCE("MOV.B Rm,@Rn"); - GET_Rm_B; - STORE_Rn(B, Rm); - break; - } - - case 0x1: { // MOV.W Rm,@Rn - DEBUG_PRINT_ONCE("MOV.W Rm,@Rn"); - GET_Rm_W; - STORE_Rn(W, Rm); - break; - } - - case 0x2: { // MOV.L Rm,@Rn - DEBUG_PRINT_ONCE("MOV.L Rm,@Rn"); - GET_Rm; - STORE_Rn(L, Rm); - break; - } - - case 0x4: { // MOV.B Rm,@-Rn - DEBUG_PRINT_ONCE("MOV.B Rm,@-Rn"); - GET_Rm_B; - STORE_dec_Rn(B, Rm); - break; - } - - case 0x5: { // MOV.W Rm,@-Rn - DEBUG_PRINT_ONCE("MOV.W Rm,@-Rn"); - GET_Rm_W; - STORE_dec_Rn(W, Rm); - break; - } - - case 0x6: { // MOV.L Rm,@-Rn - DEBUG_PRINT_ONCE("MOV.L Rm,@-Rn"); - GET_Rm; - STORE_dec_Rn(L, Rm); - break; - } - - case 0x7: { // DIV0S Rm,Rn - DEBUG_PRINT_ONCE("DIV0S Rm,Rn"); - GET_Rm; - DEFINE_REG(new_M); - SRLI(new_M, Rm, 31); - GET_SR; - DEFINE_REG(SR_withM); - BFINS(SR_withM, SR, new_M, SR_M_SHIFT, 1); - GET_Rn; - DEFINE_REG(new_Q); - SRLI(new_Q, Rn, 31); - DEFINE_REG(SR_withQ); - BFINS(SR_withQ, SR_withM, new_Q, SR_Q_SHIFT, 1); - DEFINE_REG(new_T); - XOR(new_T, new_M, new_Q); - DEFINE_RESULT_REG(new_SR, SR); - BFINS(new_SR, SR_withQ, new_T, SR_T_SHIFT, 1); - SET_SR(new_SR); -#ifdef OPTIMIZE_DIVISION - int Rlo, Rhi = n, Rdiv = m; // Register numbers - const int can_optimize = !in_delay && fetch - && can_optimize_div0s(fetch+1, cur_PC+2, Rhi, &Rlo, Rdiv); - if (can_optimize) { -# ifdef JIT_DEBUG_VERBOSE - DMSG("Optimizing signed division at 0x%08X", (int)cur_PC); -# endif - const int safe_division = - (optimization_flags & SH2_OPTIMIZE_ASSUME_SAFE_DIVISION); - state->division_target_PC = cur_PC + 128; - if (!safe_division) { - /* Flush cached data since we jump out from inside the - * runtime conditional */ - ADD_CYCLES(); - FLUSH_STATE_CACHE(); - } else { - /* No need to flush data because we omit the - * unoptimzied code entirely */ - } - /* Load operands */ - DECLARE_REG(lo); - LOAD_STATE_ALLOC(lo, R[Rlo]); - DECLARE_REG(div); - LOAD_STATE_ALLOC(div, R[Rdiv]); - DECLARE_REG(hi); - LOAD_STATE_ALLOC(hi, R[Rhi]); - /* Define output registers (shared across all cases) */ - DEFINE_REG(quotient); - DEFINE_REG(remainder); - /* Allocate a label for use in non-optimized cases */ - CREATE_LABEL(div0s_not_safe); - if (!safe_division) { - /* Make sure the divisor is nonzero (we don't handle - * division by zero here because we'd have to carry lo - * down too far) */ - GOTO_IF_Z(div0s_not_safe, div); - /* Check that the 64-bit value is within the range of - * a signed 32-bit integer. The Hitachi docs suggest - * that 64/32 (or 32/16) signed division isn't - * supported, so don't bother trying to optimize that - * case. Besides, 64/32 division is a pain when you - * only have 32-bit registers (see DIV0U). */ - DEFINE_REG(test_safe); - SRAI(test_safe, lo, 31); // Either 0 or -1 - GOTO_IF_NE(div0s_not_safe, hi, test_safe); - } - /* Divide 32 bits by 32 bits, unsigned */ - DIVMODS(quotient, lo, div, remainder); - /* Process the division result depending on the dividend sign*/ - DEFINE_REG(M_bit); - SRLI(M_bit, div, 31); // Get divisor sign bit (M) - DEFINE_REG(lo_sign); - SRLI(lo_sign, lo, 31); // Get dividend sign bit - /* Note: SSA violations for state block optimization */ - DEFINE_RESULT_REG(quo_out, R[Rlo]); - DEFINE_RESULT_REG(rem_out, R[Rhi]); - DEFINE_RESULT_REG(final_SR, SR); - CREATE_LABEL(div0s_final); - CREATE_LABEL(div0s_neg_dividend); - GOTO_IF_NZ(div0s_neg_dividend, lo_sign); { - /* Positive dividend */ - DEFINE_REG(quo_adj); - SUB(quo_adj, quotient, M_bit); // Adjust quotient - DEFINE_REG(new_T2); - ANDI(new_T2, quo_adj, 1); // Get value of T - DEFINE_REG(new_SR_T); - BFINS(new_SR_T, new_SR, new_T2, SR_T_SHIFT, 1); - SRAI(quo_out, quo_adj, 1); // Set quotient>>1 - DEFINE_REG(temp_Q2); - XOR(temp_Q2, new_T2, M_bit); // Get value of Q - DEFINE_REG(new_Q2); - XORI(new_Q2, temp_Q2, 1); - BFINS(final_SR, new_SR_T, new_Q2, SR_Q_SHIFT, 1); - SET_SR(final_SR); - DEFINE_REG(zero); - MOVEI(zero, 0); - DEFINE_REG(neg_div); - SUB(neg_div, zero, div); // Get abs(divisor) - DEFINE_REG(abs_div); // (remember that M bit is - SELECT(abs_div, neg_div, div, M_bit); // divisor sign) - DEFINE_REG(rem_adj); - SUB(rem_adj, remainder, abs_div); // Adjust remainder - SELECT(rem_out, rem_adj, remainder, new_Q2); - GOTO_LABEL(div0s_final); - } DEFINE_LABEL(div0s_neg_dividend); { - /* Negative dividend */ - DEFINE_REG(M_adjtemp); - SLLI(M_adjtemp, M_bit, 1); // Adjust quotient - DEFINE_REG(M_adjtemp2); - SUBI(M_adjtemp2, M_adjtemp, 1); - DEFINE_REG(zero); - MOVEI(zero, 0); - DEFINE_REG(M_adj); - SELECT(M_adj, M_adjtemp2, zero, remainder); - DEFINE_REG(qtemp); - ADD(qtemp, quotient, M_adj); - DEFINE_REG(quo_adj); - SUB(quo_adj, qtemp, M_bit); - DEFINE_REG(new_T2); - ANDI(new_T2, quo_adj, 1); // Get value of T - DEFINE_REG(new_SR_T); - BFINS(new_SR_T, new_SR, new_T2, SR_T_SHIFT, 1); - SRAI(quo_out, quo_adj, 1); // Set quotient>>1 - DEFINE_REG(temp_Q2); - XOR(temp_Q2, new_T2, M_bit); // Get value of Q - DEFINE_REG(new_Q2); - XORI(new_Q2, temp_Q2, 1); - BFINS(final_SR, new_SR_T, new_Q2, SR_Q_SHIFT, 1); - SET_SR(final_SR); - DEFINE_REG(neg_div); - SUB(neg_div, zero, div); // Get abs(divisor) - DEFINE_REG(abs_div); - SELECT(abs_div, neg_div, div, M_bit); - DEFINE_REG(rem_Q_temp); - SUB(rem_Q_temp, remainder, abs_div); - DEFINE_REG(rem_Q); // Remainder if Q - SELECT(rem_Q, remainder, rem_Q_temp, remainder); - DEFINE_REG(rem_nQ_temp); - ADD(rem_nQ_temp, remainder, abs_div); - DEFINE_REG(rem_nQ); // Remainder if !Q - SELECT(rem_nQ, rem_nQ_temp, remainder, remainder); - SELECT(rem_out, rem_Q, rem_nQ, new_Q2); - } DEFINE_LABEL(div0s_final); - STORE_STATE(R[Rlo], quo_out); - REG_SETKNOWN(REG_R(Rlo), 0); - STORE_STATE(R[Rhi], rem_out); - REG_SETKNOWN(REG_R(Rhi), 0); - /* Skip over the step-by-step emulation */ - cur_cycles += 64; // 1 cycle was already added - if (!safe_division) { - ADD_CYCLES(); - SET_PC_KNOWN(cur_PC + 130); - state->branch_target = cur_PC + 130; - FLUSH_STATE_CACHE(); - JUMP_STATIC(); - DEFINE_LABEL(div0s_not_safe); - } else { - INC_PC_BY(128); // Incremented by another 2 below - } - } // if (can_optimize) -#endif // OPTIMIZE_DIVISION - break; - } // DIV0S - - case 0x8: { // TST Rm,Rn - DEBUG_PRINT_ONCE("TST Rm,Rn"); - GET_Rn; - /* TST Rn,Rn is a common idiom for checking the zeroness of Rn */ - DEFINE_REG(new_T); - if (m == n) { - SEQZ(new_T, Rn); - } else { - GET_Rm; - DEFINE_REG(result); - AND(result, Rn, Rm); - SEQZ(new_T, result); - } - SET_SR_T(new_T); - break; - } - - case 0x9: { // AND Rm,Rn - DEBUG_PRINT_ONCE("AND Rm,Rn"); - if (m == n) { - break; // AND Rn,Rn is a no-op - } - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - AND(result, Rn, Rm); - SET_Rn(result); - /* A bit in the result of an AND operation is known iff (1) the - * bit is known in both operands or (2) the bit is known to be - * 0 in one operand. */ - REG_SETKNOWN(REG_R(n), - (REG_GETKNOWN(REG_R(m)) & REG_GETKNOWN(REG_R(n))) - | (REG_GETKNOWN(REG_R(m)) & ~REG_GETVALUE(REG_R(m))) - | (REG_GETKNOWN(REG_R(n)) & ~REG_GETVALUE(REG_R(n)))); - REG_SETVALUE(REG_R(n), - REG_GETVALUE(REG_R(m)) & REG_GETVALUE(REG_R(n))); - PTR_CLEAR(n); - break; - } - - case 0xA: { // XOR Rm,Rn - DEBUG_PRINT_ONCE("XOR Rm,Rn"); - if (m == n) { // XOR Rn,Rn is a common idiom for clearing Rn - DEFINE_RESULT_REG(result, R[n]); - MOVEI(result, 0); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), 0); - } else { - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - XOR(result, Rn, Rm); - SET_Rn(result); - /* A bit in the result of an XOR operation is known iff the - * bit is known in both operands. */ - REG_SETKNOWN(REG_R(n), - REG_GETKNOWN(REG_R(m)) & REG_GETKNOWN(REG_R(n))); - REG_SETVALUE(REG_R(n), - REG_GETVALUE(REG_R(m)) ^ REG_GETVALUE(REG_R(n))); - } - PTR_CLEAR(n); - break; - } - - case 0xB: { // OR Rm,Rn - DEBUG_PRINT_ONCE("OR Rm,Rn"); - if (m == n) { - break; // OR Rn,Rn is a no-op - } - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - OR(result, Rn, Rm); - SET_Rn(result); - /* A bit in the result of an OR operation is known iff (1) the - * bit is known in both operands or (2) the bit is known to be - * 1 in one operand. */ - REG_SETKNOWN(REG_R(n), - (REG_GETKNOWN(REG_R(m)) & REG_GETKNOWN(REG_R(n))) - | (REG_GETKNOWN(REG_R(m)) & REG_GETVALUE(REG_R(m))) - | (REG_GETKNOWN(REG_R(n)) & REG_GETVALUE(REG_R(n)))); - REG_SETVALUE(REG_R(n), - REG_GETVALUE(REG_R(m)) | REG_GETVALUE(REG_R(n))); - PTR_CLEAR(n); - break; - } - - case 0xC: { // CMP/ST Rm,Rn - DEBUG_PRINT_ONCE("CMP/ST Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_REG(temp); - XOR(temp, Rn, Rm); - DEFINE_REG(byte3); - BFEXT(byte3, temp, 24, 8); - DEFINE_REG(cmp3); - SEQZ(cmp3, byte3); - DEFINE_REG(byte2); - BFEXT(byte2, temp, 16, 8); - DEFINE_REG(cmp2); - SEQZ(cmp2, byte2); - DEFINE_REG(cmp23); - OR(cmp23, cmp2, cmp3); - DEFINE_REG(byte1); - BFEXT(byte1, temp, 8, 8); - DEFINE_REG(cmp1); - SEQZ(cmp1, byte1); - DEFINE_REG(byte0); - ANDI(byte0, temp, 0xFF); - DEFINE_REG(cmp0); - SEQZ(cmp0, byte0); - DEFINE_REG(cmp01); - OR(cmp01, cmp0, cmp1); - DEFINE_REG(new_T); - OR(new_T, cmp01, cmp23); - SET_SR_T(new_T); - break; - } - - case 0xD: { // XTRCT Rm,Rn - DEBUG_PRINT_ONCE("XTRCT Rm,Rn"); - GET_Rn; - DEFINE_REG(shift_Rn); - SRLI(shift_Rn, Rn, 16); - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - BFINS(result, shift_Rn, Rm, 16, 16); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), REG_GETKNOWN(REG_R(m)) << 16 - | REG_GETKNOWN(REG_R(n)) >> 16); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(m)) << 16 - | REG_GETVALUE(REG_R(n)) >> 16); - PTR_CLEAR(n); - break; - } - - case 0xE: { // MULU.W Rm,Rn - DEBUG_PRINT_ONCE("MULU.W Rm,Rn"); - GET_Rn; - DEFINE_REG(ext_Rn); - ANDI(ext_Rn, Rn, 0xFFFF); - GET_Rm; - DEFINE_REG(ext_Rm); - ANDI(ext_Rm, Rm, 0xFFFF); - DEFINE_RESULT_REG(result, MACL); - MUL(result, ext_Rn, ext_Rm); - SET_MACL(result); - CLEAR_MAC_IS_ZERO(); - break; - } - - case 0xF: { // MULS.W Rm,Rn - DEBUG_PRINT_ONCE("MULS.W Rm,Rn"); - GET_Rn; - DEFINE_REG(temp_Rn); - SLLI(temp_Rn, Rn, 16); - DEFINE_REG(ext_Rn); - SRAI(ext_Rn, temp_Rn, 16); - GET_Rm; - DEFINE_REG(temp_Rm); - SLLI(temp_Rm, Rm, 16); - DEFINE_REG(ext_Rm); - SRAI(ext_Rm, temp_Rm, 16); - DEFINE_RESULT_REG(result, MACL); - MUL(result, ext_Rn, ext_Rm); - SET_MACL(result); - CLEAR_MAC_IS_ZERO(); - break; - } - - default: - goto invalid; - } - break; - } // $2xxx - - case 0x3: { - switch (opcode & 0xF) { - - case 0x0: { // CMP/EQ Rm,Rn - DEBUG_PRINT_ONCE("CMP/EQ Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_REG(test); - XOR(test, Rn, Rm); - DEFINE_REG(new_T); - SEQZ(new_T, test); - SET_SR_T(new_T); - break; - } - - case 0x2: { // CMP/HS Rm,Rn - DEBUG_PRINT_ONCE("CMP/HS Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_REG(test); - SLTU(test, Rn, Rm); - DEFINE_REG(new_T); - XORI(new_T, test, 1); - SET_SR_T(new_T); - break; - } - - case 0x3: { // CMP/GE Rm,Rn - DEBUG_PRINT_ONCE("CMP/GE Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_REG(test); - SLTS(test, Rn, Rm); - DEFINE_REG(new_T); - XORI(new_T, test, 1); - SET_SR_T(new_T); - break; - } - - case 0x4: { // DIV1 Rm,Rn - DEBUG_PRINT_ONCE("DIV1 Rm,Rn"); - GET_Rn; - DEFINE_REG(new_Q); - SRLI(new_Q, Rn, 31); - GET_SR; - DEFINE_REG(old_Q); - BFEXT(old_Q, SR, SR_Q_SHIFT, 1); - DEFINE_REG(old_T); - BFEXT(old_T, SR, SR_T_SHIFT, 1); - DEFINE_REG(temp_Rn); - SLLI(temp_Rn, Rn, 1); - DEFINE_REG(new_Rn); - OR(new_Rn, temp_Rn, old_T); - DEFINE_REG(M_bit); - BFEXT(M_bit, SR, SR_M_SHIFT, 1); - DEFINE_REG(M_xor_Q); - XOR(M_xor_Q, M_bit, old_Q); - GET_Rm; - DEFINE_REG(temp1); - /* Note: SSA violation for state block optimization */ - DEFINE_RESULT_REG(final_Rn, R[n]); - CREATE_LABEL(div1_MeqQ); - CREATE_LABEL(div1_continue); - GOTO_IF_Z(div1_MeqQ, M_xor_Q); { - ADD(final_Rn, new_Rn, Rm); - SLTU(temp1, final_Rn, new_Rn); - GOTO_LABEL(div1_continue); - } DEFINE_LABEL(div1_MeqQ); { - SUB(final_Rn, new_Rn, Rm); - SLTU(temp1, new_Rn, final_Rn); - } DEFINE_LABEL(div1_continue); - SET_Rn(final_Rn); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - DEFINE_REG(temp2); - XOR(temp2, temp1, M_bit); - DEFINE_REG(final_Q); - XOR(final_Q, new_Q, temp2); - DEFINE_REG(SR_withQ); - BFINS(SR_withQ, SR, final_Q, SR_Q_SHIFT, 1); - DEFINE_REG(new_T); - XOR(new_T, final_Q, M_bit); - DEFINE_REG(final_T); - XORI(final_T, new_T, 1); - DEFINE_RESULT_REG(final_SR, SR); - BFINS(final_SR, SR_withQ, final_T, SR_T_SHIFT, 1); - SET_SR(final_SR); -#ifdef OPTIMIZE_DIVISION - if (cur_PC == state->division_target_PC) { - /* Flush cached state block fields here so they don't get - * picked up on the optimized path */ - ADD_CYCLES(); - FLUSH_STATE_CACHE(); - state->division_target_PC = 0; - } -#endif - break; - } // DIV1 Rm,Rn - - case 0x5: { // DMULU.L Rm,Rn - DEBUG_PRINT_ONCE("DMULU.L Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(lo, MACL); - DEFINE_RESULT_REG(hi, MACH); - MULU_64(lo, Rn, Rm, hi); - SET_MACL(lo); - SET_MACH(hi); - CLEAR_MAC_IS_ZERO(); - cur_cycles += 1; // Minimum number of cycles - break; - } - - case 0x6: { // CMP/HI Rm,Rn - DEBUG_PRINT_ONCE("CMP/HI Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_REG(new_T); - SLTU(new_T, Rm, Rn); - SET_SR_T(new_T); - break; - } - - case 0x7: { // CMP/GT Rm,Rn - DEBUG_PRINT_ONCE("CMP/GT Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_REG(new_T); - SLTS(new_T, Rm, Rn); - SET_SR_T(new_T); - break; - } - - case 0x8: { // SUB Rm,Rn - DEBUG_PRINT_ONCE("SUB Rm,Rn"); - if (m == n) { // SUB Rn,Rn is an alternate way to clear Rn - DEFINE_RESULT_REG(result, R[n]); - MOVEI(result, 0); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), 0); - PTR_CLEAR(n); - } else if (REG_GETKNOWN(REG_R(m)) == 0xFFFFFFFF) { - /* Optimize subtraction a constants */ - const int32_t Rm_value = REG_GETVALUE(REG_R(m)); - ADDI_Rn_NOREG(-Rm_value); - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) - Rm_value); - } else { - REG_SETKNOWN(REG_R(n), 0); - } - if (PTR_CHECK(m)) { - /* Subtracting a pointer from anything does not leave - * a valid pointer. */ - PTR_CLEAR(n); - } - } else { - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - SUB(result, Rn, Rm); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - } - break; - } - - case 0xA: { // SUBC Rm,Rn - DEBUG_PRINT_ONCE("SUBC Rm,Rn"); - GET_SR_T; - if (m == n) { // SUBC Rn,Rn sets Rn to -(SR.T), and is - // commonly used in signed division - DEFINE_REG(zero); - MOVEI(zero, 0); - DEFINE_RESULT_REG(result, R[n]); - SUB(result, zero, T); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - /* T is unchanged */ - } else { - GET_Rn; - GET_Rm; - DEFINE_REG(temp); - SUB(temp, Rn, Rm); - DEFINE_REG(borrow1); - SLTU(borrow1, Rn, temp); - DEFINE_RESULT_REG(result, R[n]); - SUB(result, temp, T); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - DEFINE_REG(borrow2); - SLTU(borrow2, temp, result); - DEFINE_REG(new_T); - OR(new_T, borrow1, borrow2); - SET_SR_T(new_T); - } - break; - } - - case 0xB: { // SUBV Rm,Rn - DEBUG_PRINT_ONCE("SUBV Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - SUB(result, Rn, Rm); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - DEFINE_REG(temp0); - XOR(temp0, Rn, Rm); - DEFINE_REG(temp1); - XOR(temp1, Rn, result); - DEFINE_REG(temp2); - AND(temp2, temp0, temp1); - DEFINE_REG(new_T); - SRLI(new_T, temp2, 31); - SET_SR_T(new_T); - break; - } - - case 0xC: { // ADD Rm,Rn - DEBUG_PRINT_ONCE("ADD Rm,Rn"); - if (REG_GETKNOWN(REG_R(m)) == 0xFFFFFFFF) { - /* Optimize addition of a constant */ - const int32_t Rm_value = REG_GETVALUE(REG_R(m)); - ADDI_Rn_NOREG(Rm_value); - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) + Rm_value); - } else { - REG_SETKNOWN(REG_R(n), 0); - } - if (PTR_CHECK(m)) { - if (PTR_CHECK(n)) { - PTR_CLEAR(n); - } else { - PTR_COPY(m, n, 1); - } - } - } else if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { - /* Treat this like MOV Rm,Rn; ADD old_Rn,Rn and optimize - * as above */ - const int32_t old_Rn_value = REG_GETVALUE(REG_R(n)); - const int old_PTR_CHECK = PTR_CHECK(n); - COPY_TO_Rn(R[m]); - PTR_COPY(m, n, 0); - ADDI_Rn_NOREG(old_Rn_value); - REG_SETKNOWN(REG_R(n), 0); - if (old_PTR_CHECK) { - /* We lost the old pointer data in the PTR_COPY() above, - * so just give up and mark it as not a pointer. - * Hopefully this case won't be too common. */ - PTR_CLEAR(n); - } - } else { // Neither operand is a known constant - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - ADD(result, Rn, Rm); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - if (PTR_CHECK(m)) { - if (PTR_CHECK(n)) { - /* Adding a pointer to a pointer is invalid, so - * clear pointer info for the result register. */ - PTR_CLEAR(n); - } else { - /* ADD Rptr,Rn is equivalent to "MOV Rptr,Rn" - * followed by "ADD old_value_of_Rn,Rn", which we - * treat as a pointer result. */ - PTR_COPY(m, n, 1); - } - } - } - break; - } - - case 0xD: { // DMULS.L Rm,Rn - DEBUG_PRINT_ONCE("DMULS.L Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(lo, MACL); - DEFINE_RESULT_REG(hi, MACH); - MULS_64(lo, Rn, Rm, hi); - SET_MACL(lo); - SET_MACH(hi); - CLEAR_MAC_IS_ZERO(); - cur_cycles += 1; // Minimum number of cycles - break; - } - - case 0xE: { // ADDC Rm,Rn - DEBUG_PRINT_ONCE("ADDC Rm,Rn"); - GET_Rn; - GET_Rm; - GET_SR_T; - DEFINE_REG(temp); - ADD(temp, Rn, Rm); - DEFINE_REG(carry1); - SLTU(carry1, temp, Rn); - DEFINE_RESULT_REG(result, R[n]); - ADD(result, temp, T); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - DEFINE_REG(carry2); - SLTU(carry2, result, temp); - DEFINE_REG(new_T); - OR(new_T, carry1, carry2); - SET_SR_T(new_T); - break; - } - - case 0xF: { // ADDV Rm,Rn - DEBUG_PRINT_ONCE("ADDV Rm,Rn"); - GET_Rn; - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - ADD(result, Rn, Rm); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - DEFINE_REG(temp0); - XOR(temp0, Rn, Rm); - DEFINE_REG(temp1); - XORI(temp1, temp0, 1); - DEFINE_REG(temp2); - XOR(temp2, Rn, result); - DEFINE_REG(temp3); - AND(temp3, temp1, temp2); - DEFINE_REG(new_T); - SRLI(new_T, temp3, 31); - SET_SR_T(new_T); - break; - } - - default: - goto invalid; - } - break; - } // $3xxx - - case 0x4: { - switch (opcode & 0xFF) { - - // $4xx0 - case 0x00: // SHLL Rn - case 0x20: { // SHAL Rn - DEBUG_PRINT_ONCE("SH[AL]L Rn"); -#ifdef OPTIMIZE_SHIFT_SEQUENCES - if (!in_delay && CAN_CACHE_SHIFTS()) { - /* - * If the next instruction is either SHLL or SHAL on the - * same register, we can cache the 1-bit shift from this - * instruction and combine it with the next instruction. - * (We can't do so with multi-bit shifts after a single-bit - * shift, because the multi-bit shifts don't set the T bit - * in SR.) If the next instruction is a delayed branch and - * does not reference the shifted register, we check the - * delay slot as well. - * - * If _this_ instruction is in a delay slot, we don't try - * to optimize at all because the next instruction executed - * may not be the next one in the code stream. Note that - * we check state->branch_type rather than state->delay - * because the latter is cleared at the top of this routine. - */ - GET_NEXT_OPCODE_FOR_SHIFT_CACHE; - if ((next_opcode & 0xFFDF) == (opcode & 0xFFDF)) { - if (CACHED_SHIFT_COUNT() < 32) { - ADD_TO_SHIFT_CACHE(1); - } - break; - } - } - const unsigned int shift_count = CACHED_SHIFT_COUNT() + 1; -#else // !OPTIMIZE_SHIFT_SEQUENCES - const unsigned int shift_count = 1; -#endif - DEFINE_REG(new_T); - DEFINE_RESULT_REG(result, R[n]); - if (shift_count > 32) { - /* Completely shifted out (including T bit) */ - MOVEI(new_T, 0); - MOVEI(result, 0); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), 0); - } else { - GET_Rn; - BFEXT(new_T, Rn, 32 - shift_count, 1); - if (shift_count == 32) { - MOVEI(result, 0); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), 0); - } else { - SLLI(result, Rn, shift_count); - REG_SETKNOWN(REG_R(n), - REG_GETKNOWN(REG_R(n)) << shift_count - | 0xFFFFFFFFU >> (32-shift_count)); - REG_SETVALUE(REG_R(n), - REG_GETVALUE(REG_R(n)) << shift_count); - } - } - SET_SR_T(new_T); - SET_Rn(result); - PTR_CLEAR(n); - CLEAR_SHIFT_CACHE(); - break; - } // SHLL/SHAL - case 0x10: { // DT Rn - DEBUG_PRINT_ONCE("DT Rn"); - GET_Rn; - DEFINE_RESULT_REG(result, R[n]); -#ifdef OPTIMIZE_DELAY - if (fetch && INSN_IS_AVAILABLE(1) && fetch[1]==0x8BFD){ - /* It's a DT/BF loop, so eat as many iterations as we can. - * At most, we consume enough iterations to push us over - * the cycle limit. */ -# ifdef JIT_DEBUG_VERBOSE - DMSG("Found DT/BF delay loop at 0x%08X", (int)cur_PC); -# endif - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF - && REG_GETVALUE(REG_R(n)) > 0 // Just in case - && REG_GETVALUE(REG_R(n)) <= OPTIMIZE_DELAY_OMIT_MAX - ) { -# ifdef JIT_DEBUG_VERBOSE - DMSG("-- Known to be %u cycles, omitting loop", - REG_GETVALUE(REG_R(n))); -# endif - /* The iteration count is known and within the limit - * for omitting the loop code, so just clear the - * register and update the cycle count. */ - cur_cycles += REG_GETVALUE(REG_R(n)) * 4; - MOVEI(result, 0); - SET_Rn(result); - REG_SETVALUE(REG_R(n), 0); - PTR_CLEAR(n); - DEFINE_REG(new_T); - MOVEI(new_T, 1); - SET_SR_T(new_T); - INC_PC_BY(2); // Skip over the BF - break; - } - /* Calculate the maximum number of loop iterations we can - * consume with the remaining cycles, but always execute - * at least one iteration. */ - DEFINE_REG(imm_1); - MOVEI(imm_1, 1); - /* cycle_limit generally won't be preloaded here, and we - * don't want to carry a previous use too far (so as not to - * create an unnecessarily long-lived register for what's - * essentially a constant value), so we don't bother trying - * to reuse any previous register with LOAD_STATE_ALLOC(). - * However, we _should_ make use of a fixed register if one - * is available. */ - DECLARE_REG(cycle_limit); - cycle_limit = STATE_CACHE_FIXED_REG(cycle_limit); - if (!cycle_limit) { - ALLOC_REG(cycle_limit); - LOAD_STATE(cycle_limit, cycle_limit); - } - DEFINE_REG(temp); - ADDI(temp, cycle_limit, 4-1); // Round the result up - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DEFINE_REG(cycles_left); - SUB(cycles_left, temp, cycles); - DEFINE_REG(max_loops_temp); - SRAI(max_loops_temp, cycles_left, 2); // 4 cycles per loop - DEFINE_REG(max_loops_test); - SLTS(max_loops_test, max_loops_temp, imm_1); - DEFINE_REG(max_loops); - SELECT(max_loops, imm_1, max_loops_temp, max_loops_test); - /* Don't consume more iterations than are actually - * available. */ - DEFINE_REG(test); - SLTU(test, Rn, max_loops); - DEFINE_REG(num_loops_temp); - SELECT(num_loops_temp, Rn, max_loops, test); - /* Protect against the case of Rn == 0. That should never - * happen in practice (it would take over 10 minutes to - * complete the loop), but since we're optimizing out - * hundreds of cycles here, we can afford a single extra - * instruction to be safe. */ - DEFINE_REG(num_loops); - SELECT(num_loops, num_loops_temp, max_loops, Rn); - SUB(result, Rn, num_loops); - /* Update the cycle counter; since the final loop will have - * its cycles added separately, we subtract one loop's - * worth of cycles before adding. */ - DEFINE_REG(used_cycles_temp); - SLLI(used_cycles_temp, num_loops, 2); - DEFINE_REG(used_cycles); - SUBI(used_cycles, used_cycles_temp, 4); - DEFINE_REG(final_cycles); - ADD(final_cycles, cycles, used_cycles); - STORE_STATE(cycles, final_cycles); - } else // Not optimizable -#endif // OPTIMIZE_DELAY - SUBI(result, Rn, 1); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - DEFINE_REG(new_T); - SEQZ(new_T, result); - SET_SR_T(new_T); - break; - } // DT - - // $4xx1 - case 0x01: { // SHLR Rn - DEBUG_PRINT_ONCE("SHLR Rn"); -#ifdef OPTIMIZE_SHIFT_SEQUENCES - if (!in_delay && CAN_CACHE_SHIFTS()) { - GET_NEXT_OPCODE_FOR_SHIFT_CACHE; - if (next_opcode == opcode) { - if (CACHED_SHIFT_COUNT() < 32) { - ADD_TO_SHIFT_CACHE(1); - } - break; - } - } - const unsigned int shift_count = CACHED_SHIFT_COUNT() + 1; -#else // !OPTIMIZE_SHIFT_SEQUENCES - const unsigned int shift_count = 1; -#endif - DEFINE_REG(new_T); - DEFINE_RESULT_REG(result, R[n]); - if (shift_count > 32) { - MOVEI(new_T, 0); - MOVE(result, 0); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), 0); - } else { - GET_Rn; - BFEXT(new_T, Rn, shift_count - 1, 1); - if (shift_count == 32) { - MOVEI(result, 0); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), 0); - } else { - SRLI(result, Rn, shift_count); - REG_SETKNOWN(REG_R(n), - REG_GETKNOWN(REG_R(n)) >> shift_count - | 0xFFFFFFFF << (32-shift_count)); - REG_SETVALUE(REG_R(n), - REG_GETVALUE(REG_R(n)) >> shift_count); - } - } - SET_SR_T(new_T); - SET_Rn(result); - PTR_CLEAR(n); - CLEAR_SHIFT_CACHE(); - break; - } // SHLR Rn - case 0x11: { // CMP/PZ Rn - DEBUG_PRINT_ONCE("CMP/PZ Rn"); - GET_Rn; - DEFINE_REG(temp); - SLTZ(temp, Rn); - DEFINE_REG(new_T); - XORI(new_T, temp, 1); - SET_SR_T(new_T); - break; - } - case 0x21: { // SHAR Rn - DEBUG_PRINT_ONCE("SHAR Rn"); -#ifdef OPTIMIZE_SHIFT_SEQUENCES - if (!in_delay && CAN_CACHE_SHIFTS()) { - GET_NEXT_OPCODE_FOR_SHIFT_CACHE; - if (next_opcode == opcode) { - if (CACHED_SHIFT_COUNT() < 32) { - ADD_TO_SHIFT_CACHE(1); - } - break; - } - } - const unsigned int shift_count = CACHED_SHIFT_COUNT() + 1; -#else // !OPTIMIZE_SHIFT_SEQUENCES - const unsigned int shift_count = 1; -#endif - GET_Rn; - DEFINE_REG(new_T); - DEFINE_RESULT_REG(result, R[n]); - if (shift_count >= 32) { - SRAI(result, Rn, 31); - ANDI(new_T, result, 1); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), - (int32_t)REG_GETVALUE(REG_R(n)) >> 31); - } else { - BFEXT(new_T, Rn, shift_count - 1, 1); - SRAI(result, Rn, shift_count); - REG_SETKNOWN(REG_R(n), - REG_GETKNOWN(REG_R(n)) >> shift_count - | 0xFFFFFFFF << (32-shift_count)); - REG_SETVALUE(REG_R(n), - (int32_t)REG_GETVALUE(REG_R(n))>>shift_count); - } - SET_SR_T(new_T); - SET_Rn(result); - PTR_CLEAR(n); - CLEAR_SHIFT_CACHE(); - break; - } // SHAR Rn - - // $4xx2 - case 0x02: { // STS.L MACH,@-Rn - DEBUG_PRINT_ONCE("STS.L MACH,@-Rn"); - GET_MACH_COPY; - STORE_dec_Rn(L, MACH); - break; - } - case 0x12: { // STS.L MACL,@-Rn - DEBUG_PRINT_ONCE("STS.L MACL,@-Rn"); - GET_MACL_COPY; - STORE_dec_Rn(L, MACL); - break; - } - case 0x22: { // STS.L PR,@-Rn - DEBUG_PRINT_ONCE("STS.L PR,@-Rn"); - GET_PR; - STORE_dec_Rn(L, PR); - break; - } - - // $4xx3 - case 0x03: { // STC.L SR,@-Rn - DEBUG_PRINT_ONCE("STC.L SR,@-Rn"); - GET_SR; - STORE_dec_Rn(L, SR); - cur_cycles += 1; - break; - } - case 0x13: { // STC.L GBR,@-Rn - DEBUG_PRINT_ONCE("STC.L GBR,@-Rn"); - GET_GBR; - STORE_dec_Rn(L, GBR); - cur_cycles += 1; - break; - } - case 0x23: { // STC.L VBR,@-Rn - DEBUG_PRINT_ONCE("STC.L VBR,@-Rn"); - GET_VBR; - STORE_dec_Rn(L, VBR); - cur_cycles += 1; - break; - } - - // $4xx4 - case 0x04: { // ROTL Rn - DEBUG_PRINT_ONCE("ROTL Rn"); -#ifdef OPTIMIZE_SHIFT_SEQUENCES - if (!in_delay && CAN_CACHE_SHIFTS()) { - GET_NEXT_OPCODE_FOR_SHIFT_CACHE; - if (next_opcode == opcode) { - /* Don't worry about overflow; we only look at the - * lower 5 bits of the value */ - ADD_TO_SHIFT_CACHE(1); - break; - } - } - const unsigned int rotate_count = (CACHED_SHIFT_COUNT() + 1) & 31; -#else // !OPTIMIZE_SHIFT_SEQUENCES - const unsigned int rotate_count = 1; -#endif - GET_Rn; - DEFINE_REG(new_T); - BFEXT(new_T, Rn, (32 - rotate_count) & 31, 1); - SET_SR_T(new_T); - DEFINE_RESULT_REG(result, R[n]); - RORI(result, Rn, (32 - rotate_count) & 31); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), - REG_GETKNOWN(REG_R(n)) << rotate_count - | REG_GETKNOWN(REG_R(n)) >> (32 - rotate_count)); - REG_SETVALUE(REG_R(n), - REG_GETVALUE(REG_R(n)) << rotate_count - | REG_GETVALUE(REG_R(n)) >> (32 - rotate_count)); - PTR_CLEAR(n); - CLEAR_SHIFT_CACHE(); - break; - } - case 0x24: { // ROTCL Rn - DEBUG_PRINT_ONCE("ROTCL Rn"); - GET_SR_T; - GET_Rn; - DEFINE_REG(new_T); - SRLI(new_T, Rn, 31); - SET_SR_T(new_T); - DEFINE_REG(temp); - SLLI(temp, Rn, 1); - DEFINE_RESULT_REG(result, R[n]); - OR(result, temp, T); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), REG_GETKNOWN(REG_R(n)) << 1); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) << 1); - PTR_CLEAR(n); - break; - } - - // $4xx5 - case 0x05: { // ROTR Rn - DEBUG_PRINT_ONCE("ROTR Rn"); -#ifdef OPTIMIZE_SHIFT_SEQUENCES - if (!in_delay && CAN_CACHE_SHIFTS()) { - GET_NEXT_OPCODE_FOR_SHIFT_CACHE; - if (next_opcode == opcode) { - ADD_TO_SHIFT_CACHE(1); - break; - } - } - const unsigned int rotate_count = (CACHED_SHIFT_COUNT() + 1) & 31; -#else // !OPTIMIZE_SHIFT_SEQUENCES - const unsigned int rotate_count = 1; -#endif - GET_Rn; - DEFINE_REG(new_T); - BFEXT(new_T, Rn, (rotate_count + 31) & 31, 1); - SET_SR_T(new_T); - DEFINE_RESULT_REG(result, R[n]); - RORI(result, Rn, rotate_count); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), - REG_GETKNOWN(REG_R(n)) >> rotate_count - | REG_GETKNOWN(REG_R(n)) << (32 - rotate_count)); - REG_SETVALUE(REG_R(n), - REG_GETVALUE(REG_R(n)) >> rotate_count - | REG_GETVALUE(REG_R(n)) << (32 - rotate_count)); - PTR_CLEAR(n); - CLEAR_SHIFT_CACHE(); - break; - } - case 0x15: { // CMP/PL Rn - DEBUG_PRINT_ONCE("CMP/PL Rn"); - GET_Rn; - DEFINE_REG(zero); - MOVEI(zero, 0); - DEFINE_REG(new_T); - SLTS(new_T, zero, Rn); - SET_SR_T(new_T); - break; - } - case 0x25: { // ROTCR Rn - DEBUG_PRINT_ONCE("ROTCR Rn"); - GET_SR_T; - GET_Rn; - DEFINE_REG(new_T); - ANDI(new_T, Rn, 1); - SET_SR_T(new_T); - DEFINE_REG(temp); - SRLI(temp, Rn, 1); - DEFINE_RESULT_REG(result, R[n]); - BFINS(result, temp, T, 31, 1); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), REG_GETKNOWN(REG_R(n)) >> 1); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) >> 1); - PTR_CLEAR(n); - break; - } - - // $4xx6 - case 0x06: { // LDS.L @Rn+,MACH - DEBUG_PRINT_ONCE("LDS.L @Rn+,MACH"); - DEFINE_RESULT_REG(value, MACH); - LOAD_Rn_inc(L, value); - SET_MACH(value); - CLEAR_MAC_IS_ZERO(); - break; - } - case 0x16: { // LDS.L @Rn+,MACL - DEBUG_PRINT_ONCE("LDS.L @Rn+,MACL"); - DEFINE_RESULT_REG(value, MACL); - LOAD_Rn_inc(L, value); - SET_MACL(value); - CLEAR_MAC_IS_ZERO(); - break; - } - case 0x26: { // LDS.L @Rn+,PR - DEBUG_PRINT_ONCE("LDS.L @Rn+,PR"); - DEFINE_RESULT_REG(value, PR); - LOAD_Rn_inc(L, value); - SET_PR(value); - break; - } - - // $4xx7 - case 0x07: { // LDC.L @Rn+,SR - DEBUG_PRINT_ONCE("LDC.L @Rn+,SR"); - DEFINE_REG(value); - LOAD_Rn_inc(L, value); - DEFINE_RESULT_REG(new_SR, SR); - ANDI(new_SR, value, 0x3F3); - SET_SR(new_SR); - cur_cycles += 2; - state->need_interrupt_check = 1; - break; - } - case 0x17: { // LDC.L @Rn+,GBR - DEBUG_PRINT_ONCE("LDC.L @Rn+,GBR"); - DEFINE_RESULT_REG(value, GBR); - LOAD_Rn_inc(L, value); - SET_GBR(value); - REG_SETKNOWN(REG_GBR, 0); - cur_cycles += 2; - break; - } - case 0x27: { // LDC.L @Rn+,VBR - DEBUG_PRINT_ONCE("LDC.L @Rn+,VBR"); - DEFINE_RESULT_REG(value, VBR); - LOAD_Rn_inc(L, value); - SET_VBR(value); - cur_cycles += 2; - break; - } - - // $4xx8 - case 0x08: case 0x18: case 0x28: { - unsigned int this_count; - switch (opcode>>4 & 0xF) { - case 0x0: // SHLL2 Rn - DEBUG_PRINT_ONCE("SHLL2 Rn"); - this_count = 2; - break; - case 0x1: // SHLL8 Rn - DEBUG_PRINT_ONCE("SHLL8 Rn"); - this_count = 8; - break; - case 0x2: // SHLL16 Rn - DEBUG_PRINT_ONCE("SHLL16 Rn"); - this_count = 16; - break; - default: // Not needed, but avoid a compiler warning - this_count = 0; - break; - } -#ifdef OPTIMIZE_SHIFT_SEQUENCES - if (!in_delay && CAN_CACHE_SHIFTS()) { - /* For multi-bit shifts, we can accept any size shift in - * the same direction on the next instruction. */ - GET_NEXT_OPCODE_FOR_SHIFT_CACHE; - if (((next_opcode & 0xFFCF) == (opcode & 0xFFCF) - && ((next_opcode>>4 & 0xF) != 3)) //Watch out for invalids - || (next_opcode & 0xFFDF) == (opcode & 0xFF07) - ) { - if (CACHED_SHIFT_COUNT() < 32) { - ADD_TO_SHIFT_CACHE(this_count); - } - break; - } - } - const unsigned int shift_count = CACHED_SHIFT_COUNT() + this_count; -#else // !OPTIMIZE_SHIFT_SEQUENCES - const unsigned int shift_count = this_count; -#endif - DEFINE_RESULT_REG(result, R[n]); - if (shift_count >= 32) { - MOVEI(result, 0); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), 0); - } else { - GET_Rn; - SLLI(result, Rn, shift_count); - REG_SETKNOWN(REG_R(n), - REG_GETKNOWN(REG_R(n)) << shift_count - | 0xFFFFFFFFU >> (32-shift_count)); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) << shift_count); - } - SET_Rn(result); - PTR_CLEAR(n); - CLEAR_SHIFT_CACHE(); - break; - } // SHLLx Rn - - // $4xx9 - case 0x09: case 0x19: case 0x29: { - unsigned int this_count; - switch (opcode>>4 & 0xF) { - case 0x0: // SHLR2 Rn - DEBUG_PRINT_ONCE("SHLR2 Rn"); - this_count = 2; - break; - case 0x1: // SHLR8 Rn - DEBUG_PRINT_ONCE("SHLR8 Rn"); - this_count = 8; - break; - case 0x2: // SHLR16 Rn - DEBUG_PRINT_ONCE("SHLR16 Rn"); - this_count = 16; - break; - default: // Not needed, but avoid a compiler warning - this_count = 0; - break; - } -#ifdef OPTIMIZE_SHIFT_SEQUENCES - if (!in_delay && CAN_CACHE_SHIFTS()) { - /* We could theoretically cached SHLRn + SHAR by treating - * the SHAR as an SHLR instead (since the top bit will be - * zero following SHLRn), but since this would require - * extra logic for a case assumed to be extremely rare, - * we let it slide. */ - GET_NEXT_OPCODE_FOR_SHIFT_CACHE; - if (((next_opcode & 0xFFCF) == (opcode & 0xFFCF) - && ((next_opcode>>4 & 0xF) != 3)) //Watch out for invalids - || (next_opcode & 0xFFFF) == (opcode & 0xFF07) - ) { - if (CACHED_SHIFT_COUNT() < 32) { - ADD_TO_SHIFT_CACHE(this_count); - } - break; - } - } - const unsigned int shift_count = CACHED_SHIFT_COUNT() + this_count; -#else // !OPTIMIZE_SHIFT_SEQUENCES - const unsigned int shift_count = this_count; -#endif - DEFINE_RESULT_REG(result, R[n]); - if (shift_count >= 32) { - MOVEI(result, 0); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), 0); - } else { - GET_Rn; - SRLI(result, Rn, shift_count); - REG_SETKNOWN(REG_R(n), - REG_GETKNOWN(REG_R(n)) >> shift_count - | 0xFFFFFFFF << (32-shift_count)); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) >> shift_count); - } - SET_Rn(result); - PTR_CLEAR(n); - CLEAR_SHIFT_CACHE(); - break; - } // SHLRx Rn - - // $4xxA - case 0x0A: { // LDS Rn,MACH - DEBUG_PRINT_ONCE("LDS Rn,MACH"); - /* Make sure we load a _copy_ of Rn, so a subsequent overwrite - * of the register by a MADD instruction doesn't modify the - * value of Rn as well. */ - DEFINE_RESULT_REG(Rn, MACH); - LOAD_STATE_COPY(Rn, R[n]); - SET_MACH(Rn); - CLEAR_MAC_IS_ZERO(); - break; - } - case 0x1A: { // LDS Rn,MACL - DEBUG_PRINT_ONCE("LDS Rn,MACL"); - DEFINE_RESULT_REG(Rn, MACL); - LOAD_STATE_COPY(Rn, R[n]); - SET_MACL(Rn); - CLEAR_MAC_IS_ZERO(); - break; - } - case 0x2A: { // LDS Rn,PR - DEBUG_PRINT_ONCE("LDS Rn,PR"); - COPY_FROM_Rn(PR); - break; - } - - // $4xxB - case 0x0B: { // JSR @Rn - DEBUG_PRINT_ONCE("JSR @Rn"); - DEFINE_RESULT_REG(ret_addr, PR); - MOVEI(ret_addr, cur_PC + 4); - SET_PR(ret_addr); - if (BRANCH_IS_FOLDABLE_SUBROUTINE(cur_PC)) { - state->branch_type = SH2BRTYPE_FOLDED; - state->branch_target = BRANCH_FOLD_TARGET(cur_PC); - state->branch_fold_native = BRANCH_FOLD_NATIVE_FUNC(cur_PC); - } else if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { - state->branch_type = SH2BRTYPE_STATIC; - state->branch_target = REG_GETVALUE(REG_R(n)); - } else { - state->branch_type = SH2BRTYPE_DYNAMIC; - GET_Rn; - state->branch_target_reg = Rn; - } - state->delay = 1; - cur_cycles += 1; - break; - } - case 0x1B: { // TAS.B @Rn - DEBUG_PRINT_ONCE("TAS.B @Rn"); - DEFINE_REG(value); - LOAD_Rn(B, value); - DEFINE_REG(new_T); - SEQZ(new_T, value); - SET_SR_T(new_T); - DEFINE_REG(new_value); - ORI(new_value, value, 0x80); - STORE_Rn(B, new_value); - cur_cycles += 3; - break; - } - case 0x2B: { // JMP @Rn - DEBUG_PRINT_ONCE("JMP @Rn"); - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { - state->branch_type = SH2BRTYPE_STATIC; - state->branch_target = REG_GETVALUE(REG_R(n)); - } else { - state->branch_type = SH2BRTYPE_DYNAMIC; - GET_Rn; - state->branch_target_reg = Rn; - } - state->delay = 1; - cur_cycles += 1; - break; - } - - // $4xxE - case 0x0E: { // LDC Rn,SR - DEBUG_PRINT_ONCE("LDC Rn,SR"); - GET_Rn; - DEFINE_RESULT_REG(new_SR, SR); - ANDI(new_SR, Rn, 0x3F3); - SET_SR(new_SR); - state->need_interrupt_check = 1; - break; - } - case 0x1E: { // LDC Rn,GBR - DEBUG_PRINT_ONCE("LDC Rn,GBR"); - COPY_FROM_Rn(GBR); - REG_SETKNOWN(REG_GBR, REG_GETKNOWN(REG_R(n))); - REG_SETVALUE(REG_GBR, REG_GETVALUE(REG_R(n))); - break; - } - case 0x2E: { // LDC Rn,VBR - DEBUG_PRINT_ONCE("LDC Rn,VBR"); - COPY_FROM_Rn(VBR); - break; - } - - // $4xxF - case 0x0F: case 0x1F: case 0x2F: case 0x3F: - case 0x4F: case 0x5F: case 0x6F: case 0x7F: - case 0x8F: case 0x9F: case 0xAF: case 0xBF: - case 0xCF: case 0xDF: case 0xEF: case 0xFF: { // MAC.W @Rm+,@Rn+ - DEBUG_PRINT_ONCE("MAC.W @Rm+,@Rn+"); - - /* Load the values */ - DEFINE_REG(value_m); - LOAD_Rm_inc(W, value_m); - DEFINE_REG(value_n); - LOAD_Rn_inc(W, value_n); - - /* If we're saturating, we may need the old value of MACH/MACL */ - DECLARE_REG(old_MACH); - DECLARE_REG(old_MACL); - if (!CAN_OMIT_MAC_S_CHECK) { - ALLOC_REG(old_MACH); - LOAD_STATE_COPY(old_MACH, MACH); - ALLOC_REG(old_MACL); - LOAD_STATE_COPY(old_MACL, MACL); - } else { // Not needed, but avoid a compiler warning - old_MACH = 0; - old_MACL = 0; - } - - /* Do the actual multiplication and addition */ - if (MAC_IS_ZERO()) { - DEFINE_RESULT_REG(new_MACL, MACL); - DEFINE_RESULT_REG(new_MACH, MACH); - MULS_64(new_MACL, value_m, value_n, new_MACH); - SET_MACL(new_MACL); - SET_MACH(new_MACH); - } else { - GET_MACL; - GET_MACH; - MADDS_64(MACL, value_m, value_n, MACH); - SET_MACL(MACL); - SET_MACH(MACH); - } - - /* Perform saturation if the S flag of SR is set */ - if (!CAN_OMIT_MAC_S_CHECK) { - GET_SR; - DEFINE_REG(saturate); - ANDI(saturate, SR, SR_S); - CREATE_LABEL(macw_nosat); - GOTO_IF_Z(macw_nosat, saturate); { - GET_MACL; - GET_MACH; - DEFINE_REG(value_m_sign); - SLTZ(value_m_sign, value_m); - DEFINE_REG(value_n_sign); - SLTZ(value_n_sign, value_n); - DEFINE_REG(sum_sign); - SLTZ(sum_sign, MACL); // sum < 0 - DEFINE_REG(product_sign); - XOR(product_sign, value_m_sign, value_n_sign); // product < 0 - DEFINE_REG(MACL_sign); - SLTZ(MACL_sign, old_MACL); // MACL < 0 - DEFINE_REG(temp0); - XOR(temp0, product_sign, MACL_sign); - DEFINE_REG(temp1); - XORI(temp1, temp0, 1); // (product<0) == (MACL<0) - DEFINE_REG(temp2); - XOR(temp2, sum_sign, product_sign); // (sum<0) != (product<0) - DEFINE_REG(overflow); - AND(overflow, temp2, temp1); // Nonzero if overflow - DEFINE_REG(overflow_bit); - MOVEI(overflow_bit, 0); - CREATE_LABEL(macw_no_overflow); - GOTO_IF_Z(macw_no_overflow, overflow); { - DEFINE_REG(sat_neg); - MOVEI(sat_neg, 0x80000000); - DEFINE_REG(sat_pos); - NOT(sat_pos, sat_neg); - DEFINE_REG(saturated); - SELECT(saturated, sat_neg, sat_pos, product_sign); - /* Note: SSA violations for state block optimization */ - MOVE(MACL, saturated); - SET_MACL(MACL); - MOVEI(overflow_bit, 1); - } DEFINE_LABEL(macw_no_overflow); - OR(MACH, old_MACH, overflow_bit); - SET_MACH(MACH); - } DEFINE_LABEL(macw_nosat); - } // if (!CAN_OMIT_MAC_S_CHECK) - - CLEAR_MAC_IS_ZERO(); - cur_cycles += 2; - break; - } // MAC.W - - default: - goto invalid; - } - break; - } // $4xxx - - case 0x5: { // MOV.L @(disp,Rm),Rn - DEBUG_PRINT_ONCE("MOV.L @(disp,Rm),Rn"); - const int disp = (opcode & 0xF) * 4; - DEFINE_RESULT_REG(value, R[n]); - LOAD_disp_Rm(L, value, disp); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - if (REG_GETKNOWN(REG_R(m)) == 0xFFFFFFFF && PTR_ISLOCAL(m)) { - PTR_SET_SOURCE(n, REG_GETVALUE(REG_R(m)) + disp); - } - break; - } // $5xxx - - case 0x6: { - switch (opcode & 0xF) { - - case 0x0: { // MOV.B @Rm,Rn - DEBUG_PRINT_ONCE("MOV.B @Rm,Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_Rm(B, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - case 0x1: { // MOV.W @Rm,Rn - DEBUG_PRINT_ONCE("MOV.W @Rm,Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_Rm(W, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - case 0x2: { // MOV.L @Rm,Rn - DEBUG_PRINT_ONCE("MOV.L @Rm,Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_Rm(L, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - if (REG_GETKNOWN(REG_R(m)) == 0xFFFFFFFF && PTR_ISLOCAL(m)) { - PTR_SET_SOURCE(n, REG_GETVALUE(REG_R(m))); - } - break; - } - - case 0x3: { // MOV Rm,Rn - DEBUG_PRINT_ONCE("MOV Rm,Rn"); - if (state->pending_select && !in_delay) { - state->pending_select = 0; - GET_Rm; - GET_Rn; - DEFINE_RESULT_REG(selected, R[n]); - if (state->select_sense) { - /* If select_sense is nonzero, the branch was a BT or BT/S, - * meaning we _skip_ the new value if SR.T is set. */ - SELECT(selected, Rn, Rm, state->branch_cond_reg); - } else { - SELECT(selected, Rm, Rn, state->branch_cond_reg); - } - SET_Rn(selected); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - } else { - COPY_TO_Rn(R[m]); - REG_SETKNOWN(REG_R(n), REG_GETKNOWN(REG_R(m))); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(m))); - PTR_COPY(m, n, 0); - } - break; - } - - case 0x4: { // MOV.B @Rm+,Rn - DEBUG_PRINT_ONCE("MOV.B @Rm+,Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_Rm_inc(B, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - case 0x5: { // MOV.W @Rm+,Rn - DEBUG_PRINT_ONCE("MOV.W @Rm+,Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_Rm_inc(W, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - case 0x6: { // MOV.L @Rm+,Rn - DEBUG_PRINT_ONCE("MOV.L @Rm+,Rn"); - DEFINE_RESULT_REG(value, R[n]); - LOAD_Rm_inc(L, value); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - if (REG_GETKNOWN(REG_R(m)) == 0xFFFFFFFF && PTR_ISLOCAL(m)) { - PTR_SET_SOURCE(n, REG_GETVALUE(REG_R(m)) - 4); - } - break; - } - - case 0x7: { // NOT Rm,Rn - DEBUG_PRINT_ONCE("NOT Rm,Rn"); - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - NOT(result, Rm); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), REG_GETKNOWN(REG_R(m))); - REG_SETVALUE(REG_R(n), ~REG_GETVALUE(REG_R(m))); - PTR_CLEAR(n); - break; - } - - case 0x8: { // SWAP.B Rm,Rn - DEBUG_PRINT_ONCE("SWAP.B Rm,Rn"); - GET_Rm; - /* BSWAPH swaps both low and high halfwords, but we want to - * keep the high halfword unchanged */ - DEFINE_REG(temp); - BSWAPH(temp, Rm); - DEFINE_RESULT_REG(result, R[n]); - BFINS(result, Rm, temp, 0, 16); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), (REG_GETKNOWN(REG_R(m)) & 0xFFFF0000) - | (REG_GETKNOWN(REG_R(m)) & 0x0000FF00) >> 8 - | (REG_GETKNOWN(REG_R(m)) & 0x000000FF) << 8); - REG_SETVALUE(REG_R(n), (REG_GETVALUE(REG_R(m)) & 0xFFFF0000) - | (REG_GETVALUE(REG_R(m)) & 0x0000FF00) >> 8 - | (REG_GETVALUE(REG_R(m)) & 0x000000FF) << 8); - PTR_CLEAR(n); - break; - } - - case 0x9: { // SWAP.W Rm,Rn - DEBUG_PRINT_ONCE("SWAP.W Rm,Rn"); - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - HSWAPW(result, Rm); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), (REG_GETKNOWN(REG_R(m)) & 0xFFFF0000) >> 16 - | (REG_GETKNOWN(REG_R(m)) & 0x0000FFFF) << 16); - REG_SETVALUE(REG_R(n), (REG_GETVALUE(REG_R(m)) & 0xFFFF0000) >> 16 - | (REG_GETVALUE(REG_R(m)) & 0x0000FFFF) << 16); - PTR_CLEAR(n); - break; - } - - case 0xA: { // NEGC Rm,Rn - DEBUG_PRINT_ONCE("NEGC Rm,Rn"); - GET_SR_T; - GET_Rm; - DEFINE_REG(zero); - MOVEI(zero, 0); - DEFINE_REG(borrow); - SLTU(borrow, zero, Rm); - DEFINE_REG(new_T); - OR(new_T, borrow, T); - SET_SR_T(new_T); - DEFINE_REG(temp); - SUB(temp, zero, Rm); - DEFINE_RESULT_REG(result, R[n]); - SUB(result, temp, T); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - case 0xB: { // NEG Rm,Rn - DEBUG_PRINT_ONCE("NEG Rm,Rn"); - GET_Rm; - DEFINE_REG(zero); - MOVEI(zero, 0); - DEFINE_RESULT_REG(result, R[n]); - SUB(result, zero, Rm); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } - - case 0xC: { // EXTU.B Rm,Rn - DEBUG_PRINT_ONCE("EXTU.B Rm,Rn"); - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - ANDI(result, Rm, 0xFF); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), REG_GETKNOWN(REG_R(m)) | 0xFFFFFF00); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(m)) & 0x000000FF); - PTR_CLEAR(n); - break; - } - - case 0xD: { // EXTU.W Rm,Rn - DEBUG_PRINT_ONCE("EXTU.W Rm,Rn"); - GET_Rm; - DEFINE_RESULT_REG(result, R[n]); - ANDI(result, Rm, 0xFFFF); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), REG_GETKNOWN(REG_R(m)) | 0xFFFF0000); - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(m)) & 0x0000FFFF); - PTR_CLEAR(n); - break; - } - - case 0xE: { // EXTS.B Rm,Rn - DEBUG_PRINT_ONCE("EXTS.B Rm,Rn"); - GET_Rm; - DEFINE_REG(temp); - SLLI(temp, Rm, 24); - DEFINE_RESULT_REG(result, R[n]); - SRAI(result, temp, 24); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), - (int32_t)(REG_GETKNOWN(REG_R(m)) << 24) >> 24); - REG_SETVALUE(REG_R(n), - (int32_t)(REG_GETVALUE(REG_R(m)) << 24) >> 24); - PTR_CLEAR(n); - break; - } - - case 0xF: { // EXTS.W Rm,Rn - DEBUG_PRINT_ONCE("EXTS.W Rm,Rn"); - GET_Rm; - DEFINE_REG(temp); - SLLI(temp, Rm, 16); - DEFINE_RESULT_REG(result, R[n]); - SRAI(result, temp, 16); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), - (int32_t)(REG_GETKNOWN(REG_R(m)) << 16) >> 16); - REG_SETVALUE(REG_R(n), - (int32_t)(REG_GETVALUE(REG_R(m)) << 16) >> 16); - PTR_CLEAR(n); - break; - } - - default: // impossible, but included for consistency - goto invalid; - } - break; - } // $6xxx - - case 0x7: { // ADD #imm,Rn - DEBUG_PRINT_ONCE("ADD #imm,Rn"); - const int8_t imm = opcode & 0xFF; - if (state->pending_select && !in_delay) { - state->pending_select = 0; - GET_Rn; - DEFINE_REG(result); - ADDI(result, Rn, (int32_t)imm); - DEFINE_RESULT_REG(selected, R[n]); - if (state->select_sense) { - /* If select_sense is nonzero, the branch was a BT or BT/S, - * meaning we _skip_ the new value if SR.T is set. */ - SELECT(selected, Rn, result, state->branch_cond_reg); - } else { - SELECT(selected, result, Rn, state->branch_cond_reg); - } - SET_Rn(selected); - REG_SETKNOWN(REG_R(n), 0); - } else { - ADDI_Rn_NOREG((int32_t)imm); - if (REG_GETKNOWN(REG_R(n)) == 0xFFFFFFFF) { - REG_SETVALUE(REG_R(n), REG_GETVALUE(REG_R(n)) + (int32_t)imm); - } else { - REG_SETKNOWN(REG_R(n), 0); - } - } - break; - } // $7xxx - - case 0x8: { - switch (opcode>>8 & 0xF) { - - case 0x0: { // MOV.B R0,@(disp,Rm) - DEBUG_PRINT_ONCE("MOV.B R0,@(disp,Rm)"); - const int disp = opcode & 0xF; - GET_R0; - STORE_disp_Rm(B, R0, disp); - break; - } - - case 0x1: { // MOV.W R0,@(disp,Rm) - DEBUG_PRINT_ONCE("MOV.W R0,@(disp,Rm)"); - const int disp = (opcode & 0xF) * 2; - GET_R0; - STORE_disp_Rm(W, R0, disp); - break; - } - - case 0x4: { // MOV.B @(disp,Rm),R0 - DEBUG_PRINT_ONCE("MOV.B @(disp,Rm),R0"); - const int disp = opcode & 0xF; - DEFINE_RESULT_REG(value, R[0]); - LOAD_disp_Rm(B, value, disp); - SET_R0(value); - REG_SETKNOWN(REG_R(0), 0); - PTR_CLEAR(0); - break; - } - - case 0x5: { // MOV.W @(disp,Rm),R0 - DEBUG_PRINT_ONCE("MOV.W @(disp,Rm),R0"); - const int disp = (opcode & 0xF) * 2; - DEFINE_RESULT_REG(value, R[0]); - LOAD_disp_Rm(W, value, disp); - SET_R0(value); - REG_SETKNOWN(REG_R(0), 0); - PTR_CLEAR(0); - break; - } - - case 0x8: { // CMP/EQ #imm,R0 - DEBUG_PRINT_ONCE("CMP/EQ #imm,R0"); - const int8_t imm = opcode & 0xFF; - GET_R0; - DEFINE_REG(test); - SUBI(test, R0, (int32_t)imm); - DEFINE_REG(new_T); - SEQZ(new_T, test); - SET_SR_T(new_T); - break; - } - - case 0x9: { // BT label - DEBUG_PRINT_ONCE("BT label"); - GET_SR_T; - if (BRANCH_FALLS_THROUGH(cur_PC) || BRANCH_IS_SELECT(cur_PC)) { - /* We don't need to branch in the native code, and we don't - * need to update PC (because a later instruction will do - * so), but we do need to update the cycle counter - * appropriately. */ - ADD_CYCLES(); - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DEFINE_REG(inc_cycles); - ADDI(inc_cycles, cycles, BRANCH_IS_SELECT(cur_PC) ? 1 : 2); - DEFINE_RESULT_REG(new_cycles, cycles); - SELECT(new_cycles, inc_cycles, cycles, T); - STORE_STATE(cycles, new_cycles); - if (BRANCH_IS_SELECT(cur_PC)) { - state->pending_select = 1; - state->select_sense = 1; - state->branch_cond_reg = T; - } - break; - } - const int disp = ((int32_t)(opcode & 0xFF) << 24) >> 23; - state->branch_type = SH2BRTYPE_BT; - state->branch_targets_rts = BRANCH_TARGETS_RTS(cur_PC); - state->loop_to_jsr = BRANCH_IS_LOOP_TO_JSR(cur_PC); - state->branch_cycles = 2; - if (state->branch_targets_rts) { - GET_PR; - state->branch_target_reg = PR; - state->branch_cycles += 3; - } else if (BRANCH_IS_THREADED(cur_PC)) { - state->branch_target = BRANCH_THREAD_TARGET(cur_PC); - state->branch_cycles += BRANCH_THREAD_COUNT(cur_PC) * 3; - } else { - state->branch_target = (cur_PC + 4) + disp; - } - state->branch_cond_reg = T; - break; - } - - case 0xB: { // BF label - DEBUG_PRINT_ONCE("BF label"); - GET_SR_T; - if (BRANCH_FALLS_THROUGH(cur_PC) || BRANCH_IS_SELECT(cur_PC)) { - ADD_CYCLES(); - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DEFINE_REG(inc_cycles); - ADDI(inc_cycles, cycles, BRANCH_IS_SELECT(cur_PC) ? 1 : 2); - DEFINE_RESULT_REG(new_cycles, cycles); - SELECT(new_cycles, cycles, inc_cycles, T); - STORE_STATE(cycles, new_cycles); - if (BRANCH_IS_SELECT(cur_PC)) { - state->pending_select = 1; - state->select_sense = 0; - state->branch_cond_reg = T; - } - break; - } - const int disp = ((int32_t)(opcode & 0xFF) << 24) >> 23; - state->branch_type = SH2BRTYPE_BF; - state->branch_targets_rts = BRANCH_TARGETS_RTS(cur_PC); - state->loop_to_jsr = BRANCH_IS_LOOP_TO_JSR(cur_PC); - state->branch_cycles = 2; - if (state->branch_targets_rts) { - GET_PR; - state->branch_target_reg = PR; - state->branch_cycles += 3; - } else if (BRANCH_IS_THREADED(cur_PC)) { - state->branch_target = BRANCH_THREAD_TARGET(cur_PC); - state->branch_cycles += BRANCH_THREAD_COUNT(cur_PC) * 3; - } else { - state->branch_target = (cur_PC + 4) + disp; - } - state->branch_cond_reg = T; - break; - } - - case 0xD: { // BT/S label - DEBUG_PRINT_ONCE("BT/S label"); - GET_SR_T; - /* For delayed SELECT branches, the cycle count ends up the - * same whether the branch is taken or not, so we can skip all - * the cycle stuff. */ - if (BRANCH_FALLS_THROUGH(cur_PC)) { - ADD_CYCLES(); - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DEFINE_REG(inc_cycles); - ADDI(inc_cycles, cycles, 1); - DEFINE_RESULT_REG(new_cycles, cycles); - SELECT(new_cycles, inc_cycles, cycles, T); - STORE_STATE(cycles, new_cycles); - break; - } else if (BRANCH_IS_SELECT(cur_PC)) { - state->pending_select = 1; - state->select_sense = 1; - state->branch_cond_reg = T; - state->delay = 1; - break; - } - const int disp = ((int32_t)(opcode & 0xFF) << 24) >> 23; - state->branch_type = SH2BRTYPE_BT_S; - state->branch_targets_rts = BRANCH_TARGETS_RTS(cur_PC); - state->loop_to_jsr = BRANCH_IS_LOOP_TO_JSR(cur_PC); - state->branch_cycles = 1; - if (state->branch_targets_rts) { - GET_PR; - state->branch_target_reg = PR; - state->branch_cycles += 3; - } else if (BRANCH_IS_THREADED(cur_PC)) { - state->branch_target = BRANCH_THREAD_TARGET(cur_PC); - state->branch_cycles += BRANCH_THREAD_COUNT(cur_PC) * 3; - } else { - state->branch_target = (cur_PC + 4) + disp; - } - state->branch_cond_reg = T; - state->delay = 1; - /* Unlike the other delayed branch instructions, we don't add - * the extra cycle for conditional branches until we actually - * branch; this avoids having to add a variable number of - * cycles to the cycle counter and thus breaking compile-time - * accumulation of cycles with OPTIMIZE_CONSTANT_ADDS. */ - break; - } - - case 0xF: { // BF/S label - DEBUG_PRINT_ONCE("BF/S label"); - GET_SR_T; - if (BRANCH_FALLS_THROUGH(cur_PC)) { - ADD_CYCLES(); - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DEFINE_REG(inc_cycles); - ADDI(inc_cycles, cycles, 1); - DEFINE_RESULT_REG(new_cycles, cycles); - SELECT(new_cycles, inc_cycles, cycles, T); - STORE_STATE(cycles, new_cycles); - break; - } else if (BRANCH_IS_SELECT(cur_PC)) { - state->pending_select = 1; - state->select_sense = 0; - state->branch_cond_reg = T; - state->delay = 1; - break; - } - const int disp = ((int32_t)(opcode & 0xFF) << 24) >> 23; - state->branch_type = SH2BRTYPE_BF_S; - state->branch_targets_rts = BRANCH_TARGETS_RTS(cur_PC); - state->loop_to_jsr = BRANCH_IS_LOOP_TO_JSR(cur_PC); - state->branch_cycles = 1; - if (state->branch_targets_rts) { - GET_PR; - state->branch_target_reg = PR; - state->branch_cycles += 3; - } else if (BRANCH_IS_THREADED(cur_PC)) { - state->branch_target = BRANCH_THREAD_TARGET(cur_PC); - state->branch_cycles += BRANCH_THREAD_COUNT(cur_PC) * 3; - } else { - state->branch_target = (cur_PC + 4) + disp; - } - state->branch_cond_reg = T; - state->delay = 1; - break; - } - - default: - goto invalid; - } - break; - } // $8xxx - - case 0x9: { // MOV.W @(disp,PC),Rn - DEBUG_PRINT_ONCE("MOV.W @(disp,PC),Rn"); - const int disp = (opcode & 0xFF) * 2; - const uint32_t address = cur_PC + 4 + disp; - DEFINE_RESULT_REG(value, R[n]); - SH2_LOAD_ABS_W(value, address); - SET_Rn(value); - REG_SETKNOWN(REG_R(n), 0); - PTR_CLEAR(n); - break; - } // $9xxx - - case 0xA: { // BRA label - DEBUG_PRINT_ONCE("BRA label"); - if (BRANCH_FALLS_THROUGH(cur_PC)) { - cur_cycles += 1; - break; - } - if (BRANCH_TARGETS_RTS(cur_PC)) { - state->branch_type = SH2BRTYPE_DYNAMIC; - GET_PR; - state->branch_target_reg = PR; - cur_cycles += 3; - } else { - state->loop_to_jsr = BRANCH_IS_LOOP_TO_JSR(cur_PC); - const int disp = ((int32_t)(opcode & 0xFFF) << 20) >> 19; - state->branch_type = SH2BRTYPE_STATIC; - state->branch_target = (cur_PC + 4) + disp; - } - state->delay = 1; - cur_cycles += 1; - break; - } // $Axxx - - case 0xB: { // BSR label - DEBUG_PRINT_ONCE("BSR label"); - const int disp = ((int32_t)(opcode & 0xFFF) << 20) >> 19; - DEFINE_RESULT_REG(ret_addr, PR); - MOVEI(ret_addr, cur_PC + 4); - SET_PR(ret_addr); - if (BRANCH_IS_FOLDABLE_SUBROUTINE(cur_PC)) { - state->branch_type = SH2BRTYPE_FOLDED; - state->branch_target = BRANCH_FOLD_TARGET(cur_PC); - state->branch_fold_native = BRANCH_FOLD_NATIVE_FUNC(cur_PC); - } else { - state->branch_type = SH2BRTYPE_STATIC; - state->branch_target = (cur_PC + 4) + disp; - } - state->delay = 1; - cur_cycles += 1; - break; - } // $Bxxx - - case 0xC: { - const unsigned int imm = opcode & 0xFF; - switch (opcode>>8 & 0xF) { - - case 0x0: { // MOV.B R0,@(disp,GBR) - DEBUG_PRINT_ONCE("MOV.B R0,@(disp,GBR)"); - GET_R0; - STORE_disp_GBR(B, R0, imm); - break; - } - - case 0x1: { // MOV.W R0,@(disp,GBR) - DEBUG_PRINT_ONCE("MOV.W R0,@(disp,GBR)"); - GET_R0; - STORE_disp_GBR(W, R0, imm*2); - break; - } - - case 0x2: { // MOV.L R0,@(disp,GBR) - DEBUG_PRINT_ONCE("MOV.L R0,@(disp,GBR)"); - GET_R0; - STORE_disp_GBR(L, R0, imm*4); - break; - } - - case 0x3: { // TRAPA #imm - DEBUG_PRINT_ONCE("TRAPA #imm"); - cur_cycles += 7; - DEFINE_REG(PC); - MOVEI(PC, cur_PC + 2); - TAKE_EXCEPTION(imm, PC); - break; - } - - case 0x4: { // MOV.B @(disp,GBR),R0 - DEBUG_PRINT_ONCE("MOV.B @(disp,GBR),R0"); - DEFINE_RESULT_REG(value, R[0]); - LOAD_disp_GBR(B, value, imm); - SET_R0(value); - REG_SETKNOWN(REG_R(0), 0); - PTR_CLEAR(0); - break; - } - - case 0x5: { // MOV.W @(disp,GBR),R0 - DEBUG_PRINT_ONCE("MOV.W @(disp,GBR),R0"); - DEFINE_RESULT_REG(value, R[0]); - LOAD_disp_GBR(W, value, imm*2); - SET_R0(value); - REG_SETKNOWN(REG_R(0), 0); - PTR_CLEAR(0); - break; - } - - case 0x6: { // MOV.L @(disp,GBR),R0 - DEBUG_PRINT_ONCE("MOV.L @(disp,GBR),R0"); - DEFINE_RESULT_REG(value, R[0]); - LOAD_disp_GBR(L, value, imm*4); - SET_R0(value); - REG_SETKNOWN(REG_R(0), 0); - PTR_CLEAR(0); - break; - } - - case 0x7: { // MOVA @(disp,PC),R0 - DEBUG_PRINT_ONCE("MOVA @(disp,PC),R0"); - DEFINE_RESULT_REG(address, R[0]); - MOVEI(address, (cur_PC & ~3) + 4 + imm*4); - SET_R0(address); - REG_SETKNOWN(REG_R(0), 0xFFFFFFFF); - REG_SETVALUE(REG_R(0), (cur_PC & ~3) + 4 + imm*4); - /* Technically it's still a pointer, but the former value is - * gone (and we'll be using absolute loads/stores for this - * register anyway), so clear pointer status */ - PTR_CLEAR(0); - PTR_SETLOCAL(0); // Flag to pass to the load/store routines - break; - } - - case 0x8: { // TST #imm,R0 - DEBUG_PRINT_ONCE("TST #imm,R0"); - GET_R0; -#ifdef OPTIMIZE_VARIABLE_SHIFTS - if (LIKELY(!in_delay) && fetch) { - unsigned int count_reg, count_mask, shift_reg, shift_type; - const uint8_t *cycles_array; - const unsigned int num_insns = can_optimize_variable_shift( - fetch, cur_PC, &count_reg, &count_mask, &shift_reg, - &shift_type, &cycles_array - ); - if (num_insns) { -# ifdef JIT_DEBUG_VERBOSE - DMSG("Optimizing variable shift at 0x%08X", (int)cur_PC); -# endif - DECLARE_REG(Rshift); - LOAD_STATE_ALLOC(Rshift, R[shift_reg]); - DEFINE_REG(count); - ANDI(count, R0, count_mask); // count_reg is always 0 - DEFINE_REG(new_T); - DEFINE_RESULT_REG(result, R[shift_reg]); - if (shift_type == 0) { - SRLI(new_T, Rshift, 31); - SLL(result, Rshift, count); - } else { - ANDI(new_T, Rshift, 1); - SRL(result, Rshift, count); - } - STORE_STATE(R[shift_reg], result); - /* SR.T is only set if the shift count is odd */ - GET_SR_T; - DEFINE_REG(test); - ANDI(test, count, 1); - DEFINE_REG(final_T); - SELECT(final_T, new_T, T, test); - SET_SR_T(final_T); - DEFINE_REG(cycles_array_base); - MOVEA(cycles_array_base, ADDR_HI(cycles_array)); - DEFINE_REG(cycles_array_ptr); - ADD(cycles_array_ptr, cycles_array_base, count); - cur_cycles--; // Avoid double-counting this instruction - ADD_CYCLES(); - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DEFINE_REG(cycles_to_add); - LOAD_BU(cycles_to_add, cycles_array_ptr, - ADDR_LO(cycles_array)); - DEFINE_RESULT_REG(new_cycles, cycles); - ADD(new_cycles, cycles, cycles_to_add); - STORE_STATE(cycles, new_cycles); - INC_PC_BY((num_insns - 1) * 2); - break; - } - } -#endif - DEFINE_REG(test); - ANDI(test, R0, imm); - DEFINE_REG(new_T); - SEQZ(new_T, test); - SET_SR_T(new_T); - break; - } - - case 0x9: { // AND #imm,R0 - DEBUG_PRINT_ONCE("AND #imm,R0"); - GET_R0; - DEFINE_RESULT_REG(result, R[0]); - ANDI(result, R0, imm); - SET_R0(result); - REG_SETKNOWN(REG_R(0), REG_GETKNOWN(REG_R(0)) | ~imm); - REG_SETVALUE(REG_R(0), REG_GETVALUE(REG_R(0)) & imm); - break; - } - - case 0xA: { // XOR #imm,R0 - DEBUG_PRINT_ONCE("XOR #imm,R0"); - GET_R0; - DEFINE_RESULT_REG(result, R[0]); - XORI(result, R0, imm); - SET_R0(result); - REG_SETVALUE(REG_R(0), REG_GETVALUE(REG_R(0)) ^ imm); - break; - } - - case 0xB: { // OR #imm,R0 - DEBUG_PRINT_ONCE("OR #imm,R0"); - GET_R0; - DEFINE_RESULT_REG(result, R[0]); - ORI(result, R0, imm); - SET_R0(result); - REG_SETKNOWN(REG_R(0), REG_GETKNOWN(REG_R(0)) | imm); - REG_SETVALUE(REG_R(0), REG_GETVALUE(REG_R(0)) | imm); - break; - } - - case 0xC: { // TST.B #imm,@(R0,GBR) - DEBUG_PRINT_ONCE("TST.B #imm,@(R0,GBR)"); - DEFINE_REG(value); - LOAD_R0_GBR(B, value); - DEFINE_REG(test); - ANDI(test, value, imm); - DEFINE_REG(new_T); - SEQZ(new_T, test); - SET_SR_T(new_T); - break; - } - - case 0xD: { // AND.B #imm,@(R0,GBR) - DEBUG_PRINT_ONCE("AND.B #imm,@(R0,GBR)"); - DEFINE_REG(value); - LOAD_R0_GBR(B, value); - DEFINE_REG(result); - ANDI(result, value, imm); - STORE_SAVED_R0_GBR(B, result); - cur_cycles += 2; - break; - } - - case 0xE: { // XOR.B #imm,@(R0,GBR) - DEBUG_PRINT_ONCE("XOR.B #imm,@(R0,GBR)"); - DEFINE_REG(value); - LOAD_R0_GBR(B, value); - DEFINE_REG(result); - XORI(result, value, imm); - STORE_SAVED_R0_GBR(B, result); - cur_cycles += 2; - break; - } - - case 0xF: { // OR.B #imm,@(R0,GBR) - DEBUG_PRINT_ONCE("OR.B #imm,@(R0,GBR)"); - DEFINE_REG(value); - LOAD_R0_GBR(B, value); - DEFINE_REG(result); - ORI(result, value, imm); - STORE_SAVED_R0_GBR(B, result); - cur_cycles += 2; - break; - } - - default: // impossible, but included for consistency - goto invalid; - } - break; - - } // $Cxxx - - case 0xD: { // MOV.L @(disp,PC),Rn - DEBUG_PRINT_ONCE("MOV.L @(disp,PC),Rn"); - const int disp = (opcode & 0xFF) * 4; - const uint32_t address = (cur_PC & ~3) + 4 + disp; - DEFINE_RESULT_REG(value, R[n]); - SH2_LOAD_ABS_L(value, address); - REG_SETKNOWN(REG_R(n), 0); - SET_Rn(value); - PTR_CLEAR(n); - PTR_SET_SOURCE(n, address); - break; - } // $Dxxx - - case 0xE: { // MOV #imm,Rn - DEBUG_PRINT_ONCE("MOV #imm,Rn"); - const int8_t imm = opcode & 0xFF; - if (state->pending_select && !in_delay) { - state->pending_select = 0; - GET_Rn; - DEFINE_REG(result); - MOVEI(result, (int32_t)imm); - DEFINE_RESULT_REG(selected, R[n]); - if (state->select_sense) { - /* If select_sense is nonzero, the branch was a BT or BT/S, - * meaning we _skip_ the new value if SR.T is set. */ - SELECT(selected, Rn, result, state->branch_cond_reg); - } else { - SELECT(selected, result, Rn, state->branch_cond_reg); - } - SET_Rn(selected); - REG_SETKNOWN(REG_R(n), 0); - } else { - DEFINE_RESULT_REG(result, R[n]); - MOVEI(result, (int32_t)imm); - SET_Rn(result); - REG_SETKNOWN(REG_R(n), 0xFFFFFFFF); - REG_SETVALUE(REG_R(n), (int32_t)imm); - } - PTR_CLEAR(n); - break; - } // $Exxx - - case 0xF: { - goto invalid; - } // $Fxxx - - } - - /**** The Big Honkin' Opcode Switch Ends Here ****/ - - /* Update the PC and cycle count */ - - INC_PC(); - ADD_CYCLES(); - - /* Handle any pending branches */ - - if (UNLIKELY(state->branch_type != SH2BRTYPE_NONE && !state->delay)) { - - int is_idle = 0; - -#ifdef OPTIMIZE_IDLE - if ((state->branch_type == SH2BRTYPE_STATIC - || ((state->branch_type == SH2BRTYPE_BT - || state->branch_type == SH2BRTYPE_BF - || state->branch_type == SH2BRTYPE_BT_S - || state->branch_type == SH2BRTYPE_BF_S) - && !state->branch_targets_rts)) - && state->branch_target >= initial_PC - && state->branch_target < cur_PC - && (cur_PC - state->branch_target) / 2 <= OPTIMIZE_IDLE_MAX_INSNS - && fetch - ) { - const int num_insns = (cur_PC - state->branch_target) / 2; - is_idle = can_optimize_idle((fetch+1) - num_insns, - state->branch_target, num_insns); -# ifdef JIT_DEBUG_VERBOSE - if (is_idle) { - DMSG("Found idle loop at 0x%08X (%d instructions)", - (int)state->branch_target, num_insns); - } -# endif - } -#endif - - switch (state->branch_type) { - - case SH2BRTYPE_NONE: // Avoid a compiler warning - break; - - case SH2BRTYPE_STATIC: { - if (is_idle) { - /* See delay loop handling in DT for why we don't use - * LOAD_STATE_ALLOC here. */ - DECLARE_REG(cycle_limit); - cycle_limit = STATE_CACHE_FIXED_REG(cycle_limit); - if (!cycle_limit) { - ALLOC_REG(cycle_limit); - LOAD_STATE(cycle_limit, cycle_limit); - } - STORE_STATE(cycles, cycle_limit); - } - if (state->loop_to_jsr) { - /* Clear the flag now, or else it'll get picked up if the - * subroutine call is a BSR or the target register is known */ - state->loop_to_jsr = 0; - const uint32_t target = state->branch_target; - RECURSIVE_DECODE(target, 0); - RECURSIVE_DECODE(target+2, 1); - /* The flush/jump will be performed by the subroutine call */ - } else { - SET_PC_KNOWN(state->branch_target); - FLUSH_STATE_CACHE(); - JUMP_STATIC(); - } - state->just_branched = 1; - break; - } - - case SH2BRTYPE_DYNAMIC: { -#ifdef OPTIMIZE_VARIABLE_SHIFTS - /* We still have to jump normally if the branch register is - * outside the shift sequence, so create a label for that */ - CREATE_LABEL(label_do_varshift); - int doing_varshift = 0; - DECLARE_REG(Rcount); - if (state->varshift_target_PC) { - doing_varshift = 1; - DEFINE_REG(test); - LOAD_STATE_ALLOC(Rcount, R[state->varshift_Rcount]); - SLTUI(test, Rcount, - (state->varshift_target_PC + 1) - cur_PC); - GOTO_IF_NZ(label_do_varshift, test); - SAVE_STATE_CACHE(); - } else { // Not needed, but avoid a compiler warning - Rcount = 0; - } -#endif - if (is_idle) { - DECLARE_REG(cycle_limit); - cycle_limit = STATE_CACHE_FIXED_REG(cycle_limit); - if (!cycle_limit) { - ALLOC_REG(cycle_limit); - LOAD_STATE(cycle_limit, cycle_limit); - } - STORE_STATE(cycles, cycle_limit); - } - SET_PC(state->branch_target_reg); - FLUSH_STATE_CACHE(); - JUMP(); -#ifdef OPTIMIZE_VARIABLE_SHIFTS - if (doing_varshift) { - RESTORE_STATE_CACHE(); - DEFINE_LABEL(label_do_varshift); - /* A branch distance of zero means the maximum count */ - DEFINE_REG(count_2_max); - MOVEI(count_2_max, state->varshift_max * 2); - DEFINE_REG(count_2); - SUB(count_2, count_2_max, Rcount); - DEFINE_REG(count); - SRLI(count, count_2, 1); - DECLARE_REG(Rshift); - LOAD_STATE_ALLOC(Rshift, R[state->varshift_Rshift]); - DEFINE_RESULT_REG(new_Rshift, - R[state->varshift_Rshift]); - DEFINE_REG(new_T); - switch (state->varshift_type) { - case 0: { - DEFINE_REG(temp); - SUBI(temp, count, 1); - DEFINE_REG(temp2); - SLL(temp2, Rshift, temp); - SRLI(new_T, temp2, 31); - SLL(new_Rshift, Rshift, count); - break; - } - case 1: { - DEFINE_REG(temp); - SUBI(temp, count, 1); - DEFINE_REG(temp2); - SRL(temp2, Rshift, temp); - ANDI(new_T, temp2, 1); - SRL(new_Rshift, Rshift, count); - break; - } - case 2: { - DEFINE_REG(temp); - SUBI(temp, count, 1); - DEFINE_REG(temp2); - SRA(temp2, Rshift, temp); - ANDI(new_T, temp2, 1); - SRA(new_Rshift, Rshift, count); - break; - } - case 3: { - DEFINE_REG(imm_32); - MOVEI(imm_32, 32); - DEFINE_REG(right_count); - SUB(right_count, imm_32, count); - ROR(new_Rshift, Rshift, right_count); - ANDI(new_T, new_Rshift, 1); - break; - } - case 4: - ROR(new_Rshift, Rshift, count); - SRLI(new_T, new_Rshift, 31); - break; - default: - DMSG("Invalid shift type %u at 0x%X", - state->varshift_type, (unsigned int)cur_PC - 4); - MOVEI(new_T, 0); - break; - } - STORE_STATE(R[state->varshift_Rshift], new_Rshift); - GET_SR_T; - DEFINE_REG(final_T); - SELECT(final_T, new_T, T, count); - SET_SR_T(final_T); - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DEFINE_RESULT_REG(new_cycles, cycles); - ADD(new_cycles, cycles, count); - STORE_STATE(cycles, new_cycles); - INC_PC_BY(state->varshift_target_PC - cur_PC); - /* We fall through in this case, so don't set the - * just_branched flag */ - break; - } -#endif // OPTIMIZE_VARIABLE_SHIFTS - state->just_branched = 1; - break; - } // case SH2BRTYPE_DYNAMIC - - case SH2BRTYPE_RTE: { - SET_PC(state->branch_target_reg); - FLUSH_STATE_CACHE(); - DEFINE_REG(check_interrupts_funcptr); - MOVEA(check_interrupts_funcptr, check_interrupts); - CALL_NORET(state_reg, 0, check_interrupts_funcptr); - JUMP(); - break; - } // case SH2BRTYPE_RTE - - case SH2BRTYPE_BT: - case SH2BRTYPE_BF: - case SH2BRTYPE_BT_S: - case SH2BRTYPE_BF_S: { - DECLARE_REG(cycle_limit); - cycle_limit = STATE_CACHE_FIXED_REG(cycle_limit); - if (!cycle_limit) { - ALLOC_REG(cycle_limit); - LOAD_STATE(cycle_limit, cycle_limit); - } - DECLARE_REG(cycles); - LOAD_STATE_ALLOC_KEEPOFS(cycles, cycles); - if (STATE_CACHE_FIXED_REG(SR)) { - FLUSH_STATE_SR_T(); // Avoid needing to flush it twice - } - SAVE_STATE_CACHE(); - CREATE_LABEL(bt_bf_nobranch); - if (state->branch_type == SH2BRTYPE_BT - || state->branch_type == SH2BRTYPE_BT_S - ) { - GOTO_IF_Z(bt_bf_nobranch, state->branch_cond_reg); - } else { - GOTO_IF_NZ(bt_bf_nobranch, state->branch_cond_reg); - } - if (is_idle) { - STORE_STATE(cycles, cycle_limit); - } else { - DEFINE_RESULT_REG(new_cycles, cycles); - ADDI(new_cycles, cycles, - state->branch_cycles + STATE_CACHE_OFFSET(cycles)); - STORE_STATE(cycles, new_cycles); - } - if (state->branch_targets_rts) { - SET_PC(state->branch_target_reg); - FLUSH_STATE_CACHE(); - JUMP(); - } else if (state->loop_to_jsr) { - state->loop_to_jsr = 0; - const uint32_t target = state->branch_target; - RECURSIVE_DECODE(target, 0); - RECURSIVE_DECODE(target+2, 1); - } else { - SET_PC_KNOWN(state->branch_target); - WRITEBACK_STATE_CACHE(); // Avoid stores of fixed registers - JUMP_STATIC(); - } - DEFINE_LABEL(bt_bf_nobranch); - RESTORE_STATE_CACHE(); - /* We don't set state->just_branched here, because the code - * will fall through if the condition isn't met */ - break; - } // case SH2BRTYPE_B{T,F}{,_S} - - case SH2BRTYPE_FOLDED: { - /* Handle cleanup for this instruction first. */ - OPCODE_DONE(opcode); - /* Clear branch_type now (rather than at the end) so the - * recursive decode doesn't see it. */ - state->branch_type = SH2BRTYPE_NONE; - /* If it's a native implementation, just call it (but remember - * to update PC and flush the state block cache first). */ - if (state->branch_fold_native) { - SET_PC_KNOWN(state->branch_target); - FLUSH_STATE_CACHE(); - unsigned int i; - for (i = 0; i < 8; i++) { - PTR_CLEAR(i); - REG_SETKNOWN(REG_R(i), 0); - } - DEFINE_REG(funcptr_reg); - MOVEA(funcptr_reg, state->branch_fold_native); - CALL_NORET(state_reg, 0, funcptr_reg); - } else { - /* Fold in the contents of the called subroutine. We don't - * accept subroutines with branches in the first place, so - * we just recursively decode one instruction at a time - * until we reach RTS, then process the RTS manually, - * decode the delay slot, and start back up with the - * instruction after the BSR/JSR's delay slot. */ - state->folding_subroutine = 1; - uint32_t sub_PC = state->branch_target; - const uint16_t *sub_fetch = - BRANCH_FOLD_TARGET_FETCH(state->branch_target); - for (;;) { - uint16_t sub_opcode; - if (sub_fetch) { - sub_opcode = *sub_fetch++; - } else { - sub_opcode = MappedMemoryReadWord(sub_PC); - } - if (sub_opcode == 0x000B) { // RTS - break; - } - RECURSIVE_DECODE(sub_PC, 0); - sub_PC += 2; - } - RECURSIVE_DECODE(sub_PC, 0); - RECURSIVE_DECODE(sub_PC+2, 1); - state->folding_subroutine = 0; - DEFINE_REG(post_fold_PC); - MOVEI(post_fold_PC, cur_PC); - SET_PC(post_fold_PC); - } // if (state->branch_fold_native) - break; - } // case SH2BRTYPE_FOLDED - - } // switch (state->branch_type) - - state->branch_type = SH2BRTYPE_NONE; -#ifdef OPTIMIZE_VARIABLE_SHIFTS - state->varshift_target_PC = 0; -#endif - state->branch_targets_rts = 0; - state->loop_to_jsr = 0; - - } // if we need to branch - - /* Check for interrupts if necessary */ - - if (state->need_interrupt_check) { - state->need_interrupt_check = 0; - FLUSH_STATE_CACHE(); - DEFINE_REG(check_interrupts_funcptr); - MOVEA(check_interrupts_funcptr, check_interrupts); - DEFINE_REG(result); - CALL(result, state_reg, 0, check_interrupts_funcptr); - CREATE_LABEL(nointr); - GOTO_IF_Z(nointr, result); { - RETURN(); - } DEFINE_LABEL(nointr); - } - - /* Invalid opcode handler (jumped to on detection of an invalid opcode) */ - - if (0) { - invalid: - if (invalid_opcode_callback) { - (*invalid_opcode_callback)(state, cur_PC, opcode); - } - cur_cycles++; - DEFINE_REG(PC); - MOVEI(PC, cur_PC); - INC_PC(); // So we don't get stuck when translating - TAKE_EXCEPTION(state->delay ? 6 : 4, PC); - } - - /* All done; perform any cleanup requested and return the instruction's - * opcode to the caller. */ - - OPCODE_DONE(opcode); - return opcode; - -} // End of decode_insn() - -/*************************************************************************/ - -#undef GET_REG -#undef GET_R0 -#undef GET_R0_W -#undef GET_R0_B -#undef GET_R15 -#undef GET_Rn -#undef GET_Rm -#undef GET_Rm_W -#undef GET_Rm_B -#undef GET_SR -#undef GET_SR_T -#undef GET_GBR -#undef GET_VBR -#undef GET_MACH -#undef GET_MACL -#undef GET_PR -#undef GET_MACH_COPY -#undef GET_MACL_COPY -#undef GET_REG_KEEPOFS -#undef GET_R0_KEEPOFS -#undef GET_R15_KEEPOFS -#undef GET_Rn_KEEPOFS -#undef GET_Rm_KEEPOFS -#undef GET_GBR_KEEPOFS - -#undef COPY_FROM_Rn -#undef COPY_TO_Rn -#undef DEFINE_RESULT_REG - -#undef SET_R0 -#undef SET_R15 -#undef SET_Rn -#undef SET_Rm -#undef SET_SR -#undef SET_SR_T -#undef SET_GBR -#undef SET_VBR -#undef SET_MACH -#undef SET_MACL -#undef SET_PR -#undef SET_PC -#undef SET_PC_KNOWN - -#undef ADDI_R0 -#undef ADDI_R15 -#undef ADDI_Rn -#undef ADDI_Rm -#undef ADDI_R0_NOREG -#undef ADDI_R15_NOREG -#undef ADDI_Rn_NOREG -#undef ADDI_Rm_NOREG -#undef ADD_CYCLES - -#undef INCDEC_B -#undef INCDEC_W -#undef INCDEC_L -#undef LOAD_Rm -#undef LOAD_disp_Rm -#undef LOAD_R0_Rm -#undef LOAD_Rm_inc -#undef LOAD_Rn -#undef LOAD_Rn_inc -#undef LOAD_disp_GBR -#undef LOAD_R0_GBR -#undef STORE_Rn -#undef STORE_disp_Rn -#undef STORE_dec_Rn -#undef STORE_R0_Rn -#undef STORE_disp_Rm -#undef STORE_disp_GBR -#undef STORE_SAVED_R0_GBR - -#undef TAKE_EXCEPTION -#undef GET_NEXT_OPCODE_FOR_SHIFT_CACHE -#undef DEBUG_PRINT_ONCE - -/*************************************************************************/ - -/* - * Local variables: - * mode: c - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/sh2-internal.h b/yabause/src/psp/sh2-internal.h deleted file mode 100644 index 57e31a8fce..0000000000 --- a/yabause/src/psp/sh2-internal.h +++ /dev/null @@ -1,967 +0,0 @@ -/* src/psp/sh2-internal.h: SH-2 emulator internal definitions/declarations - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef SH2_INTERNAL_H -#define SH2_INTERNAL_H - -#ifndef SH2_H -# include "sh2.h" -#endif - -/*************************************************************************/ -/************************* Configuration options *************************/ -/*************************************************************************/ - -/*============ Compilation environment settings ============*/ - -/** - * LOG2_SIZEOF_PTR: The base-2 log of the size of a pointer value (i.e. - * sizeof(void *) == 1 << LOG2_SIZEOF_PTR). - */ -#define LOG2_SIZEOF_PTR (sizeof(void *) == 8 ? 3 : 2) - -/*============ General options ============*/ - -/** - * INTERRUPT_STACK_SIZE: Sets the maximum number of interrupts that can - * be stacked. Any interrupts occurring when the stack is full will be - * lost. - */ -#ifndef INTERRUPT_STACK_SIZE -# define INTERRUPT_STACK_SIZE 50 -#endif - -/** - * ENABLE_JIT: When defined, enables the use of dynamic recompilation. - */ -#define ENABLE_JIT - -/** - * JIT_ACCURATE_ACCESS_TIMING: When defined, checks the current cycle - * count against the cycle limit before each load or store operation to - * ensure that external accesses occur at the proper times, as compared to - * interpreted execution. This does not apply to accesses which can be - * proven to be to internal RAM or ROM ($[02]0[026]xxxxx). - */ -// #define JIT_ACCURATE_ACCESS_TIMING - -/** - * JIT_ACCURATE_LDC_SR_TIMING: When defined, prevents interrupts from - * being accepted during the instruction following an LDC ...,SR - * instruction, just like a real SH-2 processor. When not defined, accepts - * interrupts immediately following an LDC ...,SR instruction, which may - * provide better performance depending on the code being executed. - */ -// #define JIT_ACCURATE_LDC_SR_TIMING - -/** - * JIT_ALLOW_DISTANT_BRANCHES: When defined, the translator will scan - * forward past an unconditional branch for branch targets later in the - * SH-2 code and attempt to include them in the same block. Otherwise, - * only a branch targeting the instruction immediately following the - * branch's delay slot (or targeting the delay slot itself) will be - * considered as part of the same block. - */ -#define JIT_ALLOW_DISTANT_BRANCHES - -/** - * JIT_TABLE_SIZE: Specifies the size of the dynamic translation (JIT) - * routine table. The larger the table, the more translated code can be - * retained in memory, but the greater the cost of stores that overwrite - * previously-translated code. This should always be a prime number. - */ -#ifndef JIT_TABLE_SIZE -# define JIT_TABLE_SIZE 4001 -#endif - -/** - * JIT_DATA_LIMIT_DEFAULT: Specifies the default for the maximum total - * size of translated code, in bytes of native code. When this limit is - * reached, the least recently created translations will be purged from - * memory to make room for new translations. This limit can be changed - * dynamically with sh2_set_jit_data_limit(). - */ -#ifndef JIT_DATA_LIMIT_DEFAULT -# define JIT_DATA_LIMIT_DEFAULT 20000000 -#endif - -/** - * JIT_BRANCH_PREDICTION_SLOTS: Specifies the number of dynamic branch - * prediction slots to use for each block of translated code. A larger - * value increases the number of different branch targets which can be - * predicted without having to search for the code in the global - * translation table, but slows down processing of code with varying - * branch targets. Each slot also uses up 16 * JIT_TABLE_SIZE bytes of - * memory in the translation table (on a 32-bit system). - * - * A value of zero disables branch prediction entirely (including optimized - * static branch prediction). - */ -#ifndef JIT_BRANCH_PREDICTION_SLOTS -# define JIT_BRANCH_PREDICTION_SLOTS 3 -#endif - -/** - * JIT_BRANCH_PREDICTION_FLOAT: When defined, causes successfully - * predicted dynamic branches to "float" up the predicted branch table, so - * they can be found more quickly the next time the block is executed. - * Whether this helps or hurts performance depends on the particular code - * being executed; blocks called from a single location many times followed - * by a different single location many times will benefit, while blocks - * which are alternately called by two or more locations will suffer. - * - * This option has no effect (obviously) if the value of - * JIT_BRANCH_PREDICTION_SLOTS is 0 or 1. - */ -#define JIT_BRANCH_PREDICTION_FLOAT - -/** - * JIT_BRANCH_PREDICT_STATIC: When defined, optimizes static branches and - * block termination code to minimize the overhead of jumping from one - * block to another. - * - * This option is ignored if the value of JIT_BRANCH_PREDICTION_SLOTS is 0. - */ -// #define JIT_BRANCH_PREDICT_STATIC - -/** - * JIT_INSNS_PER_BLOCK: Specifies the maximum number of SH-2 instructions - * (or 16-bit words of local data) to translate in a single block. A - * larger value allows larger blocks of code to be translated as a single - * unit, potentially increasing execution speed at the cost of longer - * translation delays. - */ -#ifndef JIT_INSNS_PER_BLOCK -# define JIT_INSNS_PER_BLOCK 512 -#endif - -/** - * JIT_MAX_INSN_GAP: Specifies the maximum number of 16-bit words to skip - * between SH-2 instructions or local data before terminating the block. - * A larger value allows common paths through a block to be translated as a - * single unit and helps detection of local data that does not immediately - * follow the last translated instruction, but may result in some segments - * of code being translated multiple times. - * - * Setting this option to 0 is not recommended when using the runtime- - * selectable OPTIMIZE_LOCAL_ACCESSES optimization, since doing so prevents - * recognition of all local data in blocks that end on a non-32-bit-aligned - * address. - */ -#ifndef JIT_MAX_INSN_GAP -# define JIT_MAX_INSN_GAP 256 -#endif - -/** - * JIT_BTCACHE_SIZE: Specifies the size of the branch target cache. - * A larger cache increases the amount of SH-2 code that can be translated - * as a single block, but increases the time required to translate branch - * instructions. - */ -#ifndef JIT_BTCACHE_SIZE -# define JIT_BTCACHE_SIZE 256 -#endif - -/** - * JIT_UNRES_BRANCH_SIZE: Specifies the size of the unresolved branch - * table. A larger table size increases the complexity of SH-2 code that - * can be translated as a single block, but increases the time required to - * translate all instructions. - */ -#ifndef JIT_UNRES_BRANCH_SIZE -# define JIT_UNRES_BRANCH_SIZE 32 -#endif - -/** - * JIT_PAGE_BITS: Specifies the page size used for checking whether a - * store operation affects a previously-translated block, in powers of two - * (e.g. a value of 8 means a page size of 256 bytes). A larger page size - * decreases the amount of memory needed for the page tables, but increases - * the chance of an ordinary data write triggering an expensive check of - * translated blocks. - */ -#ifndef JIT_PAGE_BITS -# define JIT_PAGE_BITS 8 -#endif - -/** - * JIT_BLACKLIST_SIZE: Specifies the size of the blacklist used for - * tracking regions of memory that should not be translated due to runtime - * modifications by nearby code. A smaller blacklist size increases the - * speed of handling writes to such regions as well as the speed of code - * translation, but also increases the chance of thrashing on the table, - * which can significantly degrade performance. - */ -#ifndef JIT_BLACKLIST_SIZE -# define JIT_BLACKLIST_SIZE 10 -#endif - -/** - * JIT_BLACKLIST_EXPIRE: Specifies the time after which a blacklist entry - * will expire if it has not been written to. The unit is calls to - * jit_exec(), so the optimal value will need to be found through - * experimentation. - */ -#ifndef JIT_BLACKLIST_EXPIRE -# define JIT_BLACKLIST_EXPIRE 1000000 -#endif - -/** - * JIT_PURGE_TABLE_SIZE: Specifies the size of the purge table, which - * holds addresses of SH-2 code blocks whose translations have been purged - * from memory due to failure of optimization preconditions. A larger - * table size slows down the translation of code blocks as well as the - * handling of a purge operation. - * - * This value is also used for the size of the "pending blacklist" table, - * used to track addresses which cause jit_clear_write() faults many times - * in rapid succession so that they can be blacklisted to avoid repeated - * retranslation of the affected blocks. (This latter table is essentially - * the equivalent of the purge table for data accesses.) - */ -#ifndef JIT_PURGE_TABLE_SIZE -# define JIT_PURGE_TABLE_SIZE 16 -#endif - -/** - * JIT_PURGE_THRESHOLD: Specifies the number of purges on a single block - * after which all optimizations which require precondition checks are - * disabled for that block. This prevents blocks which take varying - * parameters (pointers to different memory regions, for example) from - * requiring a retranslation on potentially every call. This value must - * be greater than 1 (a value of 1 may cause incorrect operation). - * - * This value is also used for the blacklisting threshold of the pending - * blacklist table. - */ -#ifndef JIT_PURGE_THRESHOLD -# define JIT_PURGE_THRESHOLD 3 -#endif - -/** - * JIT_PURGE_EXPIRE: Specifies the time after which a purge table entry - * will expire. The unit is calls to jit_exec(), so the optimal value will - * need to be found through experimentation. - * - * This value is also used for the expiration time of entries in the - * pending blacklist table. - */ -#ifndef JIT_PURGE_EXPIRE -# define JIT_PURGE_EXPIRE 100000 -#endif - -/*============ Code generation options ============*/ - -/** - * JIT_USE_RTL_REGIMM: When defined, causes the JIT core to use the RTL - * register-immediate instructions (RTLOP_ADDI, etc.); when not defined, - * the JIT core will instead load immediate operands into registers which - * are then used with the register-register form of the instruction. - * - * For MIPS, the register-immediate instructions are a significant win. - */ -#define JIT_USE_RTL_REGIMM - -/** - * JIT_USE_RTL_BITFIELDS: When defined, causes the JIT core to use the RTL - * bitfield manipulation instructions (RTLOP_BFINS and RTLOP_BFEXT) where - * convenient; when not defined, appropriate combinations of AND, OR, - * and shifts will be used instead. - * - * This is generally a win on any architecture supporting bitfield - * manipulation instructions, including the MIPS Allegrex (PSP) - * architecture. - */ -#define JIT_USE_RTL_BITFIELDS - -/*============ Optimization options ============*/ - -/** - * OPTIMIZE_IDLE: When defined, attempts to find "idle loops", i.e. loops - * which continue indefinitely until some external event occurs, and modify - * their behavior to increase processing speed. Specifically, when an idle - * loop finishes an iteration and branches back to the beginning of the - * loop, the virtual processor will consume all pending execution cycles - * immediately rather than continue executing the loop until the requested - * number of cycles have passed. - * - * This optimization will slightly change execution timing as compared to - * real hardware, since the number of cycles per loop is ignored when - * consuming pending cycles. - */ -#define OPTIMIZE_IDLE - -/** - * OPTIMIZE_IDLE_MAX_INSNS: When OPTIMIZE_IDLE is defined, specifies the - * maximum number of instructions to consider when looking at a single - * potential idle loop. - */ -#ifndef OPTIMIZE_IDLE_MAX_INSNS -# define OPTIMIZE_IDLE_MAX_INSNS 8 -#endif - -/** - * OPTIMIZE_DELAY: When defined, modifies the behavior of delay loops of - * the form - * label: DT Rn - * BF label - * to increase their execution speed. - * - * This optimization alters trace output in TRACE and TRACE_STEALTH modes, - * but does not change TRACE_LITE trace output. - */ -#define OPTIMIZE_DELAY - -/** - * OPTIMIZE_DELAY_OMIT_MAX: Specifies the maximum number of iterations for - * omitting delay loops entirely from the translated code. - * - * When OPTIMIZE_DELAY is defined and a delay loop with a known number of - * iterations is found, if that known number of iterations is no greater - * than this value, the loop will be optimized out completely and replaced - * with code to consume the appropriate number of cycles (4 cycles per - * iteration) and clear the counter register to zero. - */ -#ifndef OPTIMIZE_DELAY_OMIT_MAX -# define OPTIMIZE_DELAY_OMIT_MAX 100 -#endif - -/** - * OPTIMIZE_DIVISION: When defined, attempts to find instruction sequences - * that perform division operations and replace them with native division - * instructions. This can achieve a speed increase of an order of - * magnitude or more with respect to the division operation. - * - * This optimization alters trace output in TRACE and TRACE_STEALTH modes, - * but does not change TRACE_LITE trace output. - */ -#define OPTIMIZE_DIVISION - -/** - * OPTIMIZE_SHIFT_SEQUENCES: When defined, replaces sequences of similar - * shift instructions with a single native shift instruction of the total - * count. The following replacements are performed: - * - * - Zero or more SHLL{2,8,16} Rn followed by one or more SH[AL]L Rn - * ==> SLLI(Rn,Rn,count) and set T - * - One or more SHLL{2,8,16} Rn _not_ followed by SH[AL]L Rn - * ==> SLLI(Rn,Rn,count) - * - * - Zero or more SHLR{2,8,16} Rn followed by one or more SHLR Rn - * ==> SRLI(Rn,Rn,count) and set T - * - One or more SHLR{2,8,16} Rn _not_ followed by SHLR Rn - * ==> SRLI(Rn,Rn,count) - * - * - One or more SHAR Rn ==> SRAI(Rn,Rn,count) - * - * - One or more ROTL Rn ==> RORI(Rn,Rn,(32-count)) - * - * - One or more ROTR Rn ==> RORI(Rn,Rn,count) - * - * This optimization alters trace output in TRACE and TRACE_STEALTH modes, - * but does not change TRACE_LITE trace output. - */ -#define OPTIMIZE_SHIFT_SEQUENCES - -/** - * OPTIMIZE_VARIABLE_SHIFTS: When defined, replaces instruction sequences - * that perform variable-count shifts with shorter equivalent sequences of - * RTL instructions, potentially allowing multiple branch instructions to - * be eliminated. - * - * This optimization alters trace output in TRACE and TRACE_STEALTH modes, - * and since it may eliminate branches, it may alter trace output in - * TRACE_LITE mode as well. - */ -#define OPTIMIZE_VARIABLE_SHIFTS - -/** - * OPTIMIZE_KNOWN_VALUES: When defined, tracks which bits of which - * registers have known values and, when possible, performs calculations - * using those values at translation time rather than runtime. - * - * This optimization can cause the timing of cycle count checks to change, - * and therefore alters trace output in all trace modes. - */ -#define OPTIMIZE_KNOWN_VALUES - -/** - * OPTIMIZE_BRANCH_FALLTHRU: When defined, checks for branches which - * branch to the next instruction to be translated and converts them to - * native no-ops. - * - * This optimization alters trace output in TRACE and TRACE_STEALTH modes, - * but does not change TRACE_LITE trace output. - */ -#define OPTIMIZE_BRANCH_FALLTHRU - -/** - * OPTIMIZE_BRANCH_THREAD: When defined, checks for conditional branches - * which branch to another conditional branch of the same sense and - * "threads" the branch through to the final target. This sort of branch - * chain can arise in long blocks of code due to the limited range of the - * conditional branch instructions (-128...+127 instructions). - * - * This optimization alters trace output in all trace modes. - */ -#define OPTIMIZE_BRANCH_THREAD - -/** - * OPTIMIZE_BRANCH_SELECT: When defined, checks for conditional branches - * whose only use is to choose between one of two values for a register, - * and converts such branches into native SELECT operations. - * - * This optimization alters trace output in TRACE mode. - */ -#define OPTIMIZE_BRANCH_SELECT - -/** - * OPTIMIZE_LOOP_TO_JSR: When defined, checks for backward branches that - * target a subroutine call (JSR, BSR, or BSRF) immediately preceding the - * beginning of the current block, and encodes the subroutine call along - * with its delay slot as part of the backward branch, avoiding the need - * to jump to a separate block just for the subroutine call. - * - * This optimization alters trace output in all trace modes. - */ -#define OPTIMIZE_LOOP_TO_JSR - -/** - * OPTIMIZE_STATE_BLOCK: When defined, attempts to minimize the number of - * state block accesses (loads and stores) by keeping live as long as - * possible each RTL register that holds a state block value. Values are - * flushed to memory when branching, and all cached values are cleared at - * branch targets. - */ -#define OPTIMIZE_STATE_BLOCK - -/** - * OPTIMIZE_CONSTANT_ADDS: When defined, accumulates constants added to or - * subtracted from a register, either immediate values in ADD #imm or - * offsets resulting from postincrement/predecrement memory accesses, and - * attempts to minimize the number of actual ADD instructions used to - * update the register in RTL code. - * - * This optimization relies on the following assumptions: - * - * - Offsets will not cause the final address to cross a page (2^19 byte) - * boundary. - * - * - Offsetted stores will not overwrite any code that a store to the - * non-offsetted address would not overwrite. - * - * If either of these assumptions are violated, the translated code will - * behave incorrectly and may crash the host program. - * - * Depends on OPTIMIZE_STATE_BLOCK; if OPTIMIZE_STATE_BLOCK is not defined, - * this optimization will not take place. - */ -#define OPTIMIZE_CONSTANT_ADDS - -/** - * OPTIMIZE_LOOP_REGISTERS: When defined, attempts to keep SH-2 registers - * and other state block fields used in a loop live in RTL registers for - * the duration of the loop, rather than reloading and flushing on each - * iteration. Registers which are only set within the loop (i.e., whose - * final value does not depend on the value of the register at the - * beginning of the loop) are not treated specially. - * - * Loops which include internal forward branches and other sufficiently - * complex loops will not be optimized. - * - * Depends on OPTIMIZE_STATE_BLOCK; if OPTIMIZE_STATE_BLOCK is not defined, - * this optimization will not take place. - */ -#define OPTIMIZE_LOOP_REGISTERS - -/** - * OPTIMIZE_LOOP_REGISTERS_MAX_REGS: Specifies the maximum number of RTL - * registers to keep live over a loop. Higher values minimize reload - * operations at the RTL generation level, but may increase reloads at the - * native code level due to register pressure. - */ -#ifndef OPTIMIZE_LOOP_REGISTERS_MAX_REGS -# define OPTIMIZE_LOOP_REGISTERS_MAX_REGS 12 -#endif - -/** - * OPTIMIZE_POINTERS_BLOCK_BREAK_THRESHOLD: Specifies the number of - * references to an unoptimizable pointer which will cause the block to be - * terminated immediately before the first access (thus providing another - * chance to optimize the pointer). A value of 1 will be treated as 2; a - * value of 0 disables this check entirely. - */ -#ifndef OPTIMIZE_POINTERS_BLOCK_BREAK_THRESHOLD -# define OPTIMIZE_POINTERS_BLOCK_BREAK_THRESHOLD 3 -#endif - -/** - * OPTIMIZE_FOLD_SUBROUTINES_MAX_LENGTH: Specifies the maximum number of - * instructions in a subroutine (excluding the terminating RTS and its - * delay slot) for the subroutine to qualify as foldable for the - * SH2_OPTIMIZE_FOLD_SUBROUTINES optimization. - */ -#ifndef OPTIMIZE_FOLD_SUBROUTINES_MAX_LENGTH -# define OPTIMIZE_FOLD_SUBROUTINES_MAX_LENGTH 16 -#endif - -/** - * JIT_OPTIMIZE_FLAGS: Specifies the optimizations that should be - * performed on the generated RTL code. See RTLOPT_* in rtl.h for details - * on the available flags. - */ -#ifndef JIT_OPTIMIZE_FLAGS -# define JIT_OPTIMIZE_FLAGS 0 // Optimization doesn't currently win us much -#endif - -/*============ Debugging options ============*/ - -/** - * TRACE: When defined, all instructions and all store operations are - * traced using the functions passed to sh2_trace_insn_callback() and - * sh2_trace_store[bwl]_callback(). - */ -// #define TRACE - -/** - * TRACE_STEALTH: When defined, all instructions and all store operations - * are traced in a way that does not affect the behavior of the generated - * code. Where TRACE inserts RTL instructions to flush cached values and - * call the relevant trace functions (thus updating memory more often than - * usual and potentially hiding bugs), TRACE_STEALTH inserts specially- - * coded NOP instructions that inform the RTL interpreter and native code - * translators about cached values and direct it to call the tracing - * functions itself, thus not affecting the behavior of the RTL code. - * (This requires significantly more overhead than regular tracing with the - * TRACE option.) Note that it is also necessary to define - * RTL_TRACE_STEALTH_FOR_SH2 in rtl-internal.h to enable support for this - * option. - * - * Due to optimization (such as clobbering of dead registers), - * TRACE_STEALTH is likely to not work correctly with native code. - * - * TRACE takes precedent over TRACE_STEALTH; if TRACE is defined, then - * TRACE_STEALTH is ignored and tracing code is added directly to the RTL - * code stream. - */ -// #define TRACE_STEALTH - -/** - * TRACE_LITE: When defined, traces instructions at the rate of one per - * call to sh2_run(). This allows the progress of execution to be - * monitored without the significant overhead imposed by inserting trace - * calls for every instruction in the code stream. - * - * TRACE and TRACE_STEALTH take precedence over TRACE_LITE; if either of - * the former two are defined, TRACE_LITE is ignored rather than causing a - * duplicate trace to be output at the beginning of an sh2_run() call. - */ -// #define TRACE_LITE - -/** - * TRACE_LITE_VERBOSE: When defined and when TRACE_LITE is also enabled, - * additionally traces once per call to jit_exec() (except the first in - * each sh2_run() call, to avoid a double trace). - */ -// #define TRACE_LITE_VERBOSE - -/** - * DEBUG_DECODER_INSN_COVERAGE: When defined, a debug line is printed the - * first time the SH-2 decoder encounters each instruction (specifically, - * each opcode pattern handled by a distinct code block). This can be used - * to check the coverage of test runs. - */ -// #define DEBUG_DECODER_INSN_COVERAGE - -/** - * JIT_DEBUG: When defined, debug messages are output in cases that may - * indicate a problem in the translation or optimization of SH-2 code. - */ -// #define JIT_DEBUG - -/** - * JIT_DEBUG_VERBOSE: When defined, additional debug messages are output - * in certain cases considered useful in fine-tuning the translation and - * optimization. - */ -// #define JIT_DEBUG_VERBOSE - -/** - * JIT_DEBUG_TRACE: When defined, a trace line is printed for each SH-2 - * instruction translated. This option is independent of the other trace - * options. - */ -// #define JIT_DEBUG_TRACE - -/** - * JIT_DEBUG_INSERT_PC: When defined, causes the native code generator to - * insert dummy instructions at the beginning of the code for each SH-2 - * instruction, indicating the SH-2 PC for that instruction. The dummy - * instructions are of the form: - * (RTL) - * nop 0x12345678 - * (MIPS) - * lui $zero, 0x1234 - * ori $zero, $zero, 0x5678 - * for SH-2 PC 0x12345678. - */ -// #define JIT_DEBUG_INSERT_PC - -/** - * JIT_DEBUG_INTERPRET_RTL: When defined, causes the JIT core to execute - * RTL instruction sequences directly rather than translating them into - * MIPS machine code. - * - * This is currently forced on when not compiling on PSP since the only - * available RTL->native translator at the moment is the MIPS translator. - */ -// #define JIT_DEBUG_INTERPRET_RTL - -/** - * JIT_PROFILE: When defined, counts the number of times each code block - * is executed and the time spent in execution. Every JIT_PROFILE_INTERVAL - * SH-2 clock cycles, the first JIT_PROFILE_TOP callees in terms of - * execution time and number of calls are printed. - */ -// #define JIT_PROFILE -#ifndef JIT_PROFILE_INTERVAL -# define JIT_PROFILE_INTERVAL 50000000 -#endif -#ifndef JIT_PROFILE_TOP -# define JIT_PROFILE_TOP 10 -#endif - -/** - * PSP_TIME_TRANSLATION: When defined, calculates the average amount of - * time required to translate a single SH-2 instruction. Only works on the - * PSP. - */ -// #define PSP_TIME_TRANSLATION - -/*************************************************************************/ - -/* Perform sanity checks on configuration options */ - -#if JIT_BRANCH_PREDICTION_SLOTS <= 0 -# undef JIT_BRANCH_PREDICT_STATIC -#endif - -#if JIT_PURGE_THRESHOLD < 2 -# undef JIT_PURGE_THRESHOLD -# define JIT_PURGE_THRESHOLD 2 -#endif - -#ifndef OPTIMIZE_STATE_BLOCK -# undef OPTIMIZE_CONSTANT_ADDS -# undef OPTIMIZE_LOOP_REGISTERS -#endif - -#if !defined(TRACE) || !defined(OPTIMIZE_DIVISION) -# undef TRACE_OPTIMIZED_DIVISION -#endif - -#ifdef TRACE -# undef TRACE_STEALTH -# undef TRACE_LITE -#endif - -#ifdef TRACE_STEALTH -# undef TRACE_LITE -#endif - -#ifndef TRACE_LITE -# undef TRACE_LITE_VERBOSE -#endif - -#ifndef PSP -# define JIT_DEBUG_INTERPRET_RTL -# undef PSP_TIME_TRANSLATION -#endif - -/*************************************************************************/ -/************** Internal-use data and function declarations **************/ -/*************************************************************************/ - -/******** sh2.c ********/ - -/* Bitmask indicating which optional optimizations are enabled */ -extern uint32_t optimization_flags; - -/* Callback function for manual/special-case optimization */ -extern SH2OptimizeCallback *manual_optimization_callback; - -/* Callback function for native CPU cache flushing */ -extern SH2CacheFlushCallback *cache_flush_callback; - -/* Callback function for invalid instructions */ -extern SH2InvalidOpcodeCallback *invalid_opcode_callback; - -/* Callback functions for tracing */ -extern SH2TraceInsnCallback *trace_insn_callback; -extern SH2TraceAccessCallback *trace_storeb_callback; -extern SH2TraceAccessCallback *trace_storew_callback; -extern SH2TraceAccessCallback *trace_storel_callback; - -#ifdef ENABLE_JIT -/* Page tables (exported for use in sh2-optimize.c) */ -extern uint8_t *direct_pages[0x2000]; -extern uint8_t *fetch_pages[0x2000]; -extern uint8_t *byte_direct_pages[0x2000]; -extern uint8_t *direct_jit_pages[0x2000]; -#endif - -/** - * check_interrupts: Check whether there are any pending interrupts, and - * service the highest-priority one if so. - * - * [Parameters] - * state: Processor state block - * [Return value] - * Nonzero if an interrupt was serviced, else zero - */ -extern FASTCALL int check_interrupts(SH2State *state); - -/******** sh2-interpret.c ********/ - -/** - * interpret_insn: Interpret and execute a single SH-2 instruction at the - * current PC. - * - * [Parameters] - * state: SH-2 processor state - * [Return value] - * None - */ -extern void interpret_insn(SH2State *state); - - -/******** sh2-opcodeinfo.c ********/ - -/** - * SH2_OPCODE_INFO_*: Flags used in the get_opcode_info() return value. - * "Rn" always refers to the register specified by bits 8-11 of the opcode, - * and "Rm" always refers to bits 4-7 of the opcode, regardless of the - * labeling used in the official Hitachi specs. - */ -#define SH2_OPCODE_INFO_USES_R0 (1<< 0) // Uses the value of R0 -#define SH2_OPCODE_INFO_USES_Rm (1<< 1) // Uses the value of Rm -#define SH2_OPCODE_INFO_USES_Rn (1<< 2) // Uses the value of Rn -#define SH2_OPCODE_INFO_USES_R15 (1<< 3) // Uses the value of R15 -#define SH2_OPCODE_INFO_SETS_R0 (1<< 4) // Sets the value of R0 - /* 1<< 5 is unused */ -#define SH2_OPCODE_INFO_SETS_Rn (1<< 6) // Sets the value of Rn -#define SH2_OPCODE_INFO_SETS_SR_T (1<< 7) // Sets the value of SR.T -#define SH2_OPCODE_INFO_ACCESSES_GBR (1<< 8) // Accesses memory through GBR -#define SH2_OPCODE_INFO_ACCESSES_Rm (1<< 9) // Accesses memory through Rm -#define SH2_OPCODE_INFO_ACCESSES_Rn (1<<10) // Accesses memory through Rn -#define SH2_OPCODE_INFO_ACCESSES_R15 (1<<11) // Accesses memory through R15 -#define SH2_OPCODE_INFO_ACCESSES_R0_GBR (1<<12) // Accesses memory thru R0+GBR -#define SH2_OPCODE_INFO_ACCESSES_R0_Rm (1<<13) // Accesses memory thru R0+Rm -#define SH2_OPCODE_INFO_ACCESSES_R0_Rn (1<<14) // Accesses memory thru R0+Rn -#define SH2_OPCODE_INFO_ACCESSES_PC (1<<15) // Accesses memory through PC -#define SH2_OPCODE_INFO_ACCESS_IS_STORE (1<<16) // Memory access is a store -#define SH2_OPCODE_INFO_ACCESS_IS_RMW (1<<17) // Read/modify/write operation -#define SH2_OPCODE_INFO_ACCESS_POSTINC (1<<18) // Postincrement access mode -#define SH2_OPCODE_INFO_ACCESS_PREDEC (1<<19) // Predecrement access mode -#define SH2_OPCODE_INFO_ACCESS_SIZE_B (1<<20) // Memory access is size 1 -#define SH2_OPCODE_INFO_ACCESS_SIZE_W (1<<21) // Memory access is size 2 -#define SH2_OPCODE_INFO_ACCESS_SIZE_L (1<<22) // Memory access is size 4 -#define SH2_OPCODE_INFO_ACCESS_SIZE_LL (1<<23) // Memory access is size 8 -#define SH2_OPCODE_INFO_ACCESS_DISP_4 (1<<24) // 4-bit displacement -#define SH2_OPCODE_INFO_ACCESS_DISP_8 (1<<25) // 8-bit displacement -#define SH2_OPCODE_INFO_BRANCH_UNCOND (1<<26) // Branches unconditionally -#define SH2_OPCODE_INFO_BRANCH_COND (1<<27) // Branches conditionally -#define SH2_OPCODE_INFO_BRANCH_DELAYED (1<<28) // Branches after a delay slot -#define SH2_OPCODE_INFO_VALID (1<<31) // Opcode is valid - -/** - * SH2_OPCODE_INFO_ACCESS_SIZE: Returns the size in bytes of an access - * performed by an instruction, given that instruction's get_opcode_info() - * value. - */ -#define SH2_OPCODE_INFO_ACCESS_SIZE(opcode_info) (((opcode_info) >> 20) & 0xF) - -/** - * init_opcode_info: Initialize the opcode_info[] table. Must be called - * before calling get_opcode_info(). - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void init_opcode_info(void); - -/** - * get_opcode_info: Return information about the given opcode. - * - * [Parameters] - * opcode: SH-2 opcode to obtain information about - * [Return value] - * - */ -#ifdef __GNUC__ -__attribute__((const)) -#endif -extern int32_t get_opcode_info(uint16_t opcode); - -/******** sh2-optimize.c ********/ - -#ifdef OPTIMIZE_IDLE - -/** - * can_optimize_idle: Return whether the given sequence of instructions - * forms an "idle loop", in which the processor remains in a constant state - * (or repeating sequence of states) indefinitely until a certain external - * event occurs, such as an interrupt or a change in the value of a memory- - * mapped register. If an idle loop is detected, also return information - * allowing the loop to be translated into a faster sequence of native - * instructions. - * - * The sequence of instructions is assumed to end with a branch instruction - * to the beginning of the sequence (possibly including a delay slot). - * - * [Parameters] - * insn_ptr: Pointer to first instruction - * PC: PC of first instruction - * count: Number of instructions to check - * [Return value] - * Nonzero if the given sequence of SH-2 instructions form an idle - * loop, else zero - */ -extern int can_optimize_idle(const uint16_t *insn_ptr, uint32_t PC, - unsigned int count); - -#endif // OPTIMIZE_IDLE - -#ifdef OPTIMIZE_DELAY - -/** - * can_optimize_delay: Return whether the given sequence of instructions - * forms a "delay loop", in which a counter register is repeatedly - * decremented with the DT instruction until it reaches zero. - * - * The sequence of instructions is assumed to end with a branch instruction - * to the beginning of the sequence (possibly including a delay slot). - * - * [Parameters] - * insn_ptr: Pointer to first instruction - * PC: PC of first instruction - * count: Number of instructions to check - * counter_ret: Pointer to variable to receive counter register index - * if a delay loop (unmodified if not a delay loop) - * [Return value] - * Number of clock cycles taken by the loop (nonzero) if the given - * sequence of SH-2 instructions form a delay loop, else zero - */ -extern int can_optimize_delay(const uint16_t *insn_ptr, uint32_t PC, - unsigned int count, unsigned int *counter_ret); - -#endif // OPTIMIZE_DELAY - -#ifdef OPTIMIZE_DIVISION - -/** - * can_optimize_div0u: Return whether a sequence of instructions starting - * from a DIV0U instruction can be optimized to a native divide operation. - * - * [Parameters] - * insn_ptr: Pointer to DIV0U instruction - * PC: PC of DIV0U instruction - * skip_first_rotcl: Nonzero if the first ROTCL instruction is known to - * be omitted (as may happen if the low word of - * the dividend is known to be zero) - * Rhi_ret: Pointer to variable to receive index of dividend high register - * Rlo_ret: Pointer to variable to receive index of dividend low register - * Rdiv_ret: Pointer to variable to receive index of divisor register - * [Return value] - * Number of bits of division performed by the instructions following - * the DIV0U instruction (1-32), or zero if the following instructions - * do not perform a division operation - */ -extern int can_optimize_div0u(const uint16_t *insn_ptr, uint32_t PC, - int skip_first_rotcl, - int *Rhi_ret, int *Rlo_ret, int *Rdiv_ret); - -/** - * can_optimize_div0s: Return whether a sequence of instructions starting - * from a DIV0S instruction can be optimized to a native divide operation. - * - * [Parameters] - * insn_ptr: Pointer to instruction following DIV0S instruction - * PC: PC of instruction following DIV0S instruction - * Rhi: Index of dividend high register - * Rlo_ret: Pointer to variable to receive index of dividend low register - * Rdiv: Index of divisor register - * [Return value] - * Nonzero if the next 64 SH-2 instructions form a 32-bit division - * operation, else zero - */ -extern int can_optimize_div0s(const uint16_t *insn_ptr, uint32_t PC, - int Rhi, int *Rlo_ret, int Rdiv); - -#endif // OPTIMIZE_DIVISION - -#ifdef OPTIMIZE_VARIABLE_SHIFTS - -/** - * can_optimize_variable_shift: Return whether a sequence of instructions - * can be optimized to a native variable-count shift operation. - * - * [Parameters] - * insn_ptr: Pointer to first instruction - * PC: PC of first instruction - * Rcount_ret: Pointer to variable to receive index of shift count register - * max_ret: Pointer to variable to receive maximum shift count - * Rshift_ret: Pointer to variable to receive index of target register - * type_ret: Pointer to variable to receive: - * 0 if a SHLL/SHAL sequence - * 1 if a SHLR sequence - * 2 if a SHAR sequence - * 3 if a ROTL sequence - * 4 if a ROTR sequence - * cycles_ret: Pointer to variable to receive pointer to an array of - * cycle counts indexed by shift count (unused for some - * types of sequences) - * [Return value] - * Number of instructions consumed (nonzero) if an optimizable sequence - * is found, else zero - */ -extern unsigned int can_optimize_variable_shift( - const uint16_t *insn_ptr, uint32_t PC, unsigned int *Rcount_ret, - unsigned int *max_ret, unsigned int *Rshift_ret, unsigned int *type_ret, - const uint8_t **cycles_ret); - -#endif // OPTIMIZE_VARIABLE_SHIFTS - -/*************************************************************************/ -/*************************************************************************/ - -#endif // SH2_INTERNAL_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/sh2-interpret.c b/yabause/src/psp/sh2-interpret.c deleted file mode 100644 index 6866075100..0000000000 --- a/yabause/src/psp/sh2-interpret.c +++ /dev/null @@ -1,498 +0,0 @@ -/* src/psp/sh2-interpret.c: Instruction interpreter for SH-2 emulator - (mostly for debugging) - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ -/*************************** Required headers ****************************/ -/*************************************************************************/ - -#include "common.h" - -#include "../sh2core.h" - -#include "sh2.h" -#include "sh2-internal.h" - -/*************************************************************************/ -/***************** SH-2 interpreted execution interface ******************/ -/*************************************************************************/ - -/* Declare a register identifier, but don't allocate a new register for it */ -#define DECLARE_REG(name) uintptr_t name - -/* Allocate a register for a declared identifier */ -#define ALLOC_REG(name) /*nothing*/ - -/* Define a new register (equivalent to DECLARE_REG followed by ALLOC_REG) */ -#define DEFINE_REG(name) uintptr_t name - -/* Register-register operations */ -#define MOVE(dest,src) ((dest) = (src)) -#define SELECT(dest,src1,src2,cond) ((dest) = (cond) ? (src1) : (src2)) -#define ADD(dest,src1,src2) ((dest) = (src1) + (intptr_t)(int32_t)(src2)) -#define SUB(dest,src1,src2) ((dest) = (src1) - (intptr_t)(int32_t)(src2)) -#define MUL(dest,src1,src2) ((dest) = (uint32_t)((src1) * (src2))) -#define MULU_64(dest,src1,src2,dest_hi) do { \ - (dest) = (uint32_t)((src1) * (src2)); \ - (dest_hi) = (uint64_t)((uint64_t)(uint32_t)(src1) \ - * (uint64_t)(uint32_t)(src2)) >> 32; \ -} while (0) -#define MULS_64(dest,src1,src2,dest_hi) do { \ - (dest) = (uint32_t)((src1) * (src2)); \ - (dest_hi) = (int64_t)((int64_t)(int32_t)(src1) \ - * (int64_t)(int32_t)(src2)) >> 32; \ -} while (0) -#define MADDU_64(dest,src1,src2,dest_hi) do { \ - uint64_t initial = (uint64_t)(uint32_t)(dest_hi) << 32 \ - | (uint64_t)(uint32_t)(dest); \ - uint64_t product = (uint64_t)(uint32_t)(src1) \ - * (uint64_t)(uint32_t)(src2); \ - uint64_t result = initial + product; \ - (dest) = (uint32_t)result; \ - (dest_hi) = (uint32_t)(result >> 32); \ -} while (0) -#define MADDS_64(dest,src1,src2,dest_hi) do { \ - uint64_t initial = (int64_t)(int32_t)(dest_hi) << 32 \ - | (int64_t)(uint32_t)(dest); \ - uint64_t product = (int64_t)(int32_t)(src1) \ - * (int64_t)(int32_t)(src2); \ - uint64_t result = initial + product; \ - (dest) = (uint32_t)result; \ - (dest_hi) = (uint32_t)(result >> 32); \ -} while (0) -#define DIVMODU(dest,src1,src2,rem) do { \ - if ((src2) != 0) { \ - (dest) = (uint32_t)(src1) / (uint32_t)(src2); \ - (rem) = (uint32_t)(src1) % (uint32_t)(src2); \ - } else { \ - /* Have to set these to avoid a compiler warning */ \ - (dest) = 0; \ - (rem) = 0; \ - } \ -} while (0) -#define DIVMODS(dest,src1,src2,rem) do { \ - if ((src2) != 0) { \ - (dest) = (int32_t)(src1) / (int32_t)(src2); \ - (rem) = (int32_t)(src1) % (int32_t)(src2); \ - } else { \ - /* Have to set these to avoid a compiler warning */ \ - (dest) = 0; \ - (rem) = 0; \ - } \ -} while (0) -#define AND(dest,src1,src2) ((dest) = (src1) & (intptr_t)(int32_t)(src2)) -#define OR(dest,src1,src2) ((dest) = (src1) | (uintptr_t)(uint32_t)(src2)) -#define XOR(dest,src1,src2) ((dest) = (src1) ^ (uintptr_t)(uint32_t)(src2)) -#define NOT(dest,src) ((dest) = (uint32_t)(~(src))) -#define SLL(dest,src1,src2) ((dest) = (uint32_t)((src1) << (src2))) -#define SRL(dest,src1,src2) ((dest) = (uint32_t)(src1) >> (src2)) -#define SRA(dest,src1,src2) ((dest) = (int32_t)(src1) >> (src2)) -#define ROR(dest,src1,src2) \ - ((dest) = (((src2) & 31) \ - ? (uint32_t)(src1) >> ((src2) & 31) \ - | (uint32_t)(src1) << (31-((src2) & 31)) \ - : (uint32_t)(src1))) -#ifdef __GNUC__ -# define CLZ(dest,src) ((dest) = __builtin_clz((src))) -#else -# define CLZ(dest,src) do { \ - uint32_t __temp = (src); \ - (dest) = 32; \ - while (__temp) { \ - __temp >>= 1; \ - (dest)--; \ - } \ -} while (0) -#endif // __GNUC__ -#define CLO(dest,src) do { \ - uint32_t __temp = (src); \ - (dest) = 0; \ - while ((int32_t)__temp < 0) {\ - __temp <<= 1; \ - (dest)++; \ - } \ -} while (0) -#define SLTU(dest,src1,src2) ((dest) = (uint32_t)(src1) < (uint32_t)(src2)) -#define SLTS(dest,src1,src2) ((dest) = (int32_t)(src1) < (int32_t)(src2)) -#define BSWAPH(dest,src) \ - ((dest) = ((uint32_t)(src) & 0xFF00FF00) >> 8 \ - | ((uint32_t)(src) & 0x00FF00FF) << 8) -#define BSWAPW(dest,src) \ - ((dest) = ((uint32_t)(src) & 0xFF000000) >> 24 \ - | ((uint32_t)(src) & 0x00FF0000) >> 8 \ - | ((uint32_t)(src) & 0x0000FF00) << 8 \ - | ((uint32_t)(src) & 0x000000FF) << 24) -#define HSWAPW(dest,src) \ - ((dest) = ((uint32_t)(src) & 0xFFFF0000) >> 16 \ - | ((uint32_t)(src) & 0x0000FFFF) << 16) - -/* Register-immediate operations */ -#define MOVEI(dest,imm) ((dest) = (imm)) -#define MOVEA(dest,addr) ((dest) = (uintptr_t)(addr)) -#define ADDI(dest,src,imm) ((dest) = (src) + (imm)) -#define SUBI(dest,src,imm) ((dest) = (src) - (imm)) -#define ANDI(dest,src,imm) ((dest) = (uint32_t)((src) & (imm))) -#define ORI(dest,src,imm) ((dest) = (uint32_t)((src) | (imm))) -#define XORI(dest,src,imm) ((dest) = (src) ^ (imm)) -#define SLLI(dest,src,imm) ((dest) = (uint32_t)((src) << (imm))) -#define SRLI(dest,src,imm) ((dest) = (uint32_t)(src) >> (imm)) -#define SRAI(dest,src,imm) ((dest) = (int32_t)(src) >> (imm)) -#define RORI(dest,src,imm) \ - ((dest) = (((imm) & 31) \ - ? (uint32_t)(src) >> ((imm) & 31) \ - | (uint32_t)(src) << (32-((imm) & 31)) \ - : (uint32_t)(src))) -#define SLTUI(dest,src,imm) ((dest) = (uint32_t)(src) < (uint32_t)(imm)) -#define SLTSI(dest,src,imm) ((dest) = (int32_t)(src) < (int32_t)(imm)) - -/* Bitfield operations */ -#define BFEXT(dest,src,start,count) \ - ((dest) = ((uint32_t)(src) >> (start)) & ((1 << (count)) - 1)) -#define BFINS(dest,src1,src2,start,count) \ - ((dest) = ((uint32_t)(src1) & ~(((1 << (count)) - 1) << (start))) \ - | (((uint32_t)(src2) & ((1 << (count)) - 1)) << (start))) - -/* Variants of SLT */ -#define SEQZ(dest,src) SLTUI((dest), (src), 1) -#define SLTZ(dest,src) SLTSI((dest), (src), 0) - -/* Load from or store to memory */ -#define LOAD_BU(dest,address,offset) \ - ((dest) = *(uint8_t *)((address)+(offset))) -#define LOAD_BS(dest,address,offset) \ - ((dest) = *(int8_t *)((address)+(offset))) -#define LOAD_HU(dest,address,offset) \ - ((dest) = *(uint16_t *)((address)+(offset))) -#define LOAD_HS(dest,address,offset) \ - ((dest) = *(int16_t *)((address)+(offset))) -#define LOAD_W(dest,address,offset) \ - ((dest) = *(uint32_t *)((address)+(offset))) -#define LOAD_PTR(dest,address,offset) \ - ((dest) = *(uintptr_t *)((address)+(offset))) -#define STORE_B(address,src,offset) \ - (*(uint8_t *)((address)+(offset)) = (src)) -#define STORE_H(address,src,offset) \ - (*(uint16_t *)((address)+(offset)) = (src)) -#define STORE_W(address,src,offset) \ - (*(uint32_t *)((address)+(offset)) = (src)) -#define STORE_PTR(address,src,offset) \ - (*(uintptr_t *)((address)+(offset)) = (src)) - -/* Load from, store to, or add constants to state block fields */ -#define LOAD_STATE(reg,field) ((reg) = state->field) -#define LOAD_STATE_PTR(reg,field) ((reg) = (uintptr_t)state->field) -#define LOAD_STATE_SR_T(reg) ((reg) = (state->SR & SR_T) >> SR_T_SHIFT) -#define STORE_STATE(field,reg) (state->field = (reg)) -#define STORE_STATE_PC(value) (state->PC = (value)) -#define STORE_STATE_B(field,reg) (state->field = (reg)) -#define STORE_STATE_PTR(field,reg) (state->field = (void *)(reg)) -#define STORE_STATE_SR_T(reg) (state->SR &= ~SR_T, \ - state->SR |= ((reg) & 1) << SR_T_SHIFT) -#define FLUSH_STATE_SR_T() /*nothing*/ -#define RESET_STATE_SR_T() /*nothing*/ -#define ADDI_STATE(field,imm,reg) (state->field = (reg) + (imm)) -#define ADDI_STATE_NOREG(field,imm) (state->field += (imm)) - -/* Load from a state block field, but don't change the state block cache */ -#define LOAD_STATE_COPY(name,field) LOAD_STATE(name,field) - -/* Allocate a new register and load it from the state block, or reuse an - * old register if appropriate */ -#define LOAD_STATE_ALLOC(name,field) ALLOC_REG(name); LOAD_STATE(name,field) - -/* Allocate a new register and load it from the state block, or reuse an - * old register (leaving any offset in the cache) if appropriate */ -#define LOAD_STATE_ALLOC_KEEPOFS(name,field) LOAD_STATE_ALLOC(name,field) - -/* Execute an SH-2 load or store operation (note that size desginations are - * SH-2 style B[yte]/W[ord]/L[ong] rather than RTL B[yte]/H[alfword]/W[ord], - * and all 8- and 16-bit loads are signed) */ - -#define SH2_LOAD_B(dest,address) \ - ((dest) = (int8_t)MappedMemoryReadByte((address))) -#define SH2_LOAD_W(dest,address) \ - ((dest) = (int16_t)MappedMemoryReadWord((address))) -#define SH2_LOAD_L(dest,address) \ - ((dest) = MappedMemoryReadLong((address))) - -#ifdef TRACE -# define LOG_STORE(address,src,type) ((*trace_store##type##_callback)((address), (src))) -#else -# define LOG_STORE(address,src,type) /*nothing*/ -#endif -#define SH2_STORE_B(address,src) do { \ - LOG_STORE((address), (src), b); \ - MappedMemoryWriteByte((address), (src)); \ -} while (0) -#define SH2_STORE_W(address,src) do { \ - LOG_STORE((address), (src), w); \ - MappedMemoryWriteWord((address), (src)); \ -} while (0) -#define SH2_STORE_L(address,src) do { \ - LOG_STORE((address), (src), l); \ - MappedMemoryWriteLong((address), (src)); \ -} while (0) - -/* Execute an SH-2 load or store to a known address */ -#define SH2_LOAD_ABS_B(dest,address) SH2_LOAD_B(dest,address) -#define SH2_LOAD_ABS_W(dest,address) SH2_LOAD_W(dest,address) -#define SH2_LOAD_ABS_L(dest,address) SH2_LOAD_L(dest,address) -#define SH2_STORE_ABS_B(address,src,islocal) SH2_STORE_B(address,src) -#define SH2_STORE_ABS_W(address,src,islocal) SH2_STORE_W(address,src) -#define SH2_STORE_ABS_L(address,src,islocal) SH2_STORE_L(address,src) - -/* Execute an SH-2 load or store through an SH-2 register */ -#define SH2_LOAD_REG_B(dest,sh2reg,offset,postinc) do { \ - SH2_LOAD_B(dest, state->R[sh2reg] + (offset)); \ - if (postinc) { \ - state->R[sh2reg] += 1; \ - } \ -} while (0) -#define SH2_LOAD_REG_W(dest,sh2reg,offset,postinc) do { \ - SH2_LOAD_W(dest, state->R[sh2reg] + (offset)); \ - if (postinc) { \ - state->R[sh2reg] += 2; \ - } \ -} while (0) -#define SH2_LOAD_REG_L(dest,sh2reg,offset,postinc) do { \ - SH2_LOAD_L(dest, state->R[sh2reg] + (offset)); \ - if (postinc) { \ - state->R[sh2reg] += 4; \ - } \ -} while (0) -#define SH2_STORE_REG_B(sh2reg,src,offset,predec) do { \ - if (predec) { \ - state->R[sh2reg] -= 1; \ - } \ - SH2_STORE_B(state->R[sh2reg] + (offset), src); \ -} while (0) -#define SH2_STORE_REG_W(sh2reg,src,offset,predec) do { \ - if (predec) { \ - state->R[sh2reg] -= 2; \ - } \ - SH2_STORE_W(state->R[sh2reg] + (offset), src); \ -} while (0) -#define SH2_STORE_REG_L(sh2reg,src,offset,predec) do { \ - if (predec) { \ - state->R[sh2reg] -= 4; \ - } \ - SH2_STORE_L(state->R[sh2reg] + (offset), src); \ -} while (0) - -/* Branches (within an SH-2 instruction's RTL code) */ -#define CREATE_LABEL(label) /*nothing*/ -#define DEFINE_LABEL(label) label: -#define GOTO_LABEL(label) goto label; -#define GOTO_IF_Z(label,reg) if ((reg) == 0) goto label; -#define GOTO_IF_NZ(label,reg) if ((reg) != 0) goto label; -#define GOTO_IF_E(label,reg1,reg2) if ((reg1) == (reg2)) goto label; -#define GOTO_IF_NE(label,reg1,reg2) if ((reg1) != (reg2)) goto label; - -/* Jumps (to other SH-2 instructions) */ -#define JUMP_STATIC() jumped = 1 -#define JUMP() jumped = 1 - -/* Call to a native subroutine */ -#define CALL(result,arg1,arg2,func) do { \ - FASTCALL uintptr_t (*__func)(uintptr_t,uintptr_t) = (void *)(uintptr_t)(func); \ - (result) = (*__func)((arg1), (arg2)); \ -} while (0) -#define CALL_NORET(arg1,arg2,func) do { \ - FASTCALL void (*__func)(uintptr_t,uintptr_t) = (void *)(uintptr_t)(func); \ - (*__func)((arg1), (arg2)); \ -} while (0) - -/* Return from the current block */ -#define RETURN() return 0 - -/*-----------------------------------------------------------------------*/ - -/* We don't have "registers", so alias state_reg directly to the pointer */ -#define state_reg ((uintptr_t)state) - -/* Access the state block directly for the PC */ -#define cur_PC (state->PC) - -/* No direct fetching */ -#define fetch ((uint16_t *)NULL) // uint16_t * to avoid compiler errors - -/* No pre- or post-decode processing needed */ -#define OPCODE_INIT(opcode) /*nothing*/ -#define OPCODE_DONE(opcode) /*nothing*/ - -/* cur_PC and REG_PC are the same thing, so only need to update one of them - * (but only do so for the default case if we didn't already set the PC via - * a jump) */ -#define INC_PC() do { \ - if (!jumped) { \ - cur_PC += 2; \ - } \ -} while (0) -#define INC_PC_BY(amount) (cur_PC += (amount)) - -/* Return whether the word at "offset" words from the current instruction - * is available for peephole optimization */ -#define INSN_IS_AVAILABLE(offset) 0 - -/* Return the "high" (pointer register) and "low" (load/store offset) parts - * of an address for generating optimal native load/store code */ -#define ADDR_HI(address) ((uintptr_t)address) -#define ADDR_LO(address) 0 - -/* Return whether the saturation check for MAC can be omitted */ -#define CAN_OMIT_MAC_S_CHECK 0 - -/* Get or set whether the MACL/MACH pair is known to be zero */ -#define MAC_IS_ZERO() 0 -#define SET_MAC_IS_ZERO() /*nothing*/ -#define CLEAR_MAC_IS_ZERO() /*nothing*/ - -/* Get, add to, or clear the cached shift count */ -#define CAN_CACHE_SHIFTS() 0 -#define CACHED_SHIFT_COUNT() 0 -#define ADD_TO_SHIFT_CACHE(n) /*nothing*/ -#define CLEAR_SHIFT_CACHE() /*nothing*/ - -/* Get or set register known bits and values */ -#define REG_GETKNOWN(reg) 0 -#define REG_GETVALUE(reg) 0 -#define REG_SETKNOWN(reg,value) /*nothing*/ -#define REG_SETVALUE(reg,value) /*nothing*/ - -/* Track pointer registers */ -#define PTR_ISLOCAL(reg) 0 -#define PTR_SETLOCAL(reg) /*nothing*/ -#define PTR_SET_SOURCE(reg,address) /*nothing*/ -#define PTR_CHECK(reg) 0 -#define PTR_COPY(reg,new,for_add) /*nothing*/ -#define PTR_CLEAR(reg) /*nothing*/ - -/* Save the current cache state */ -#define SAVE_STATE_CACHE() /*nothing*/ -/* Restore the saved cache state */ -#define RESTORE_STATE_CACHE() /*nothing*/ -/* Write back to the state block any cached, dirty state block values - * (but leave them dirty) */ -#define WRITEBACK_STATE_CACHE() /*nothing*/ -/* Flush all cached state block values */ -#define FLUSH_STATE_CACHE() /*nothing*/ -/* Return the cached offset for the given state block field, or 0 if none */ -#define STATE_CACHE_OFFSET(field) 0 -/* Return the fixed RTL register to use for the given state block field, - * or 0 if none */ -#define STATE_CACHE_FIXED_REG(field) 0 -/* Return whether the given state block field has a fixed RTL register that - * can be modified */ -#define STATE_CACHE_FIXED_REG_WRITABLE(field) 0 -/* Clear any fixed RTL register for the given state block field */ -#define STATE_CACHE_CLEAR_FIXED_REG(field) /*nothing*/ - -/* Check the status of a branch instruction */ -#define BRANCH_FALLS_THROUGH(addr) 0 -#define BRANCH_TARGETS_RTS(addr) 0 -#define BRANCH_IS_THREADED(addr) 0 -#define BRANCH_THREAD_TARGET(addr) 0 -#define BRANCH_THREAD_COUNT(addr) 0 -#define BRANCH_IS_SELECT(addr) 0 -#define BRANCH_IS_LOOP_TO_JSR(addr) 0 -#define BRANCH_IS_FOLDABLE_SUBROUTINE(addr) 0 -#define BRANCH_FOLD_TARGET(addr) 0 -#define BRANCH_FOLD_TARGET_FETCH(addr) NULL -#define BRANCH_FOLD_NATIVE_FUNC(addr) NULL - -/*************************************************************************/ - -/** - * decode_insn: Decode a single SH-2 instruction. Implements - * interpret_insn() using the shared decoder core. - * - * [Parameters] - * state: SH-2 processor state - * initial_PC: Equal to state->PC (used by OPTIMIZE_IDLE) - * jumped: Local register tracking whether a jump was performed - * [Return value] - * Decoded SH-2 opcode (not used) - */ -#define DECODE_INSN_INLINE NOINLINE -#define DECODE_INSN_PARAMS \ - SH2State *state, uint32_t initial_PC, int jumped -#define RECURSIVE_DECODE(address,is_last) do { \ - const uint32_t saved_PC = state->PC; \ - state->PC = (address); \ - interpret_insn(state); \ - state->PC = saved_PC; \ -} while (0) -#include "sh2-core.i" - -/*-----------------------------------------------------------------------*/ - -/** - * interpret_insn: Interpret and execute a single SH-2 instruction at the - * current PC. - * - * [Parameters] - * state: SH-2 processor state - * [Return value] - * None - */ -void interpret_insn(SH2State *state) -{ - /* Make sure we're not trying to execute from an odd address */ - if (UNLIKELY(state->PC & 1)) { - /* Push SR and PC */ - state->R[15] -= 4; - MappedMemoryWriteLong(state->R[15], state->SR); - state->R[15] -= 4; - MappedMemoryWriteLong(state->R[15], state->PC); - /* Jump to the instruction address error exception vector (9) */ - state->PC = MappedMemoryReadLong(9<<2); - } - - decode_insn(state, state->PC, 0); - - if (UNLIKELY(state->delay)) { - /* Don't treat the instruction after a not-taken conditional branch - * as a delay slot. (Note that when interpreting, the - * branch_cond_reg field holds the actual value of the condition.) */ - if (!(state->branch_type == SH2BRTYPE_BT_S && !state->branch_cond_reg) - && !(state->branch_type == SH2BRTYPE_BF_S && state->branch_cond_reg) - ) { - /* Make sure we interpret the delay slot immediately, so (1) we - * don't try to translate it as the beginning of a block and - * (2) we don't let any exceptions get in the way (SH7604 - * manual page 75, section 4.6.1: exceptions are not accepted - * when processing a delay slot). */ - decode_insn(state, state->PC, 0); - } - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/sh2-opcodeinfo.c b/yabause/src/psp/sh2-opcodeinfo.c deleted file mode 100644 index 61b497a544..0000000000 --- a/yabause/src/psp/sh2-opcodeinfo.c +++ /dev/null @@ -1,1088 +0,0 @@ -/* src/psp/sh2-opcodeinfo.c: Information table for SH-2 opcodes - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ -/*************************** Required headers ****************************/ -/*************************************************************************/ - -#include "common.h" - -#include "sh2.h" -#include "sh2-internal.h" - -/*************************************************************************/ -/************************ Opcode table definition ************************/ -/*************************************************************************/ - -/** - * opcode_info_low: Table of information bits for opcodes with the high - * bit clear; in all such instructions, the "n" field (bits 8-11) is an - * operand or part of an operand. Indexed by bits 0-7 and 12-14 of the - * opcode, i.e. ((opcode & 0x7000) >> 4 | (opcode & 0x00FF)). - */ -static int32_t opcode_info_low[0x800]; - -/** - * opcode_info_high: Table of information bits for opcodes in which the - * "n" field (bits 8-11) is part of the instruction code and the lower 8 - * bits are one or more operands. Indexed by bits 8-14 of the opcode. - */ -static int32_t opcode_info_high[0x80]; - -/*************************************************************************/ -/***************** Opcode table initialization routines ******************/ -/*************************************************************************/ - -/* Forward declarations */ - -static void init_0xxx(void); -static void init_1xxx(void); -static void init_2xxx(void); -static void init_3xxx(void); -static void init_4xxx(void); -static void init_5xxx(void); -static void init_6xxx(void); -static void init_7xxx(void); -static void init_8xxx(void); -static void init_9xxx(void); -static void init_Axxx(void); -static void init_Bxxx(void); -static void init_Cxxx(void); -static void init_Dxxx(void); -static void init_Exxx(void); - -/*************************************************************************/ - -/** - * init_opcode_info: Initialize the opcode_info[] table. Must be called - * before accessing the table. - * - * [Parameters] - * None - * [Return value] - * None - */ -void init_opcode_info(void) -{ - /* First clear the tables (rendering all opcodes invalid)... */ - memset(opcode_info_low, 0, sizeof(opcode_info_low)); - memset(opcode_info_high, 0, sizeof(opcode_info_high)); - - /* ... then fill in the tables by calling subroutines for each opcode - * group. */ - init_0xxx(); - init_1xxx(); - init_2xxx(); - init_3xxx(); - init_4xxx(); - init_5xxx(); - init_6xxx(); - init_7xxx(); - init_8xxx(); - init_9xxx(); - init_Axxx(); - init_Bxxx(); - init_Cxxx(); - init_Dxxx(); - init_Exxx(); - /* 0xFxxx is invalid */ -} - -/*************************************************************************/ - -/** - * init_xxxx: Initialize individual groups of opcodes. - * - * [Parameters] - * None - * [Return value] - * None - */ - -/*-----------------------------------------------------------------------*/ - -static void init_0xxx(void) -{ - unsigned int i; - - /* STC SR,Rn */ - opcode_info_low[0x002] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn; - /* STC GBR,Rn */ - opcode_info_low[0x012] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn; - /* STC VBR,Rn */ - opcode_info_low[0x022] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn; - - /* BSRF Rn */ - opcode_info_low[0x003] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - /* BRAF Rn */ - opcode_info_low[0x023] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - - /* MOV.* Rm,@(R0,Rn) */ - for (i = 0x000; i <= 0x0F0; i += 0x10) { - opcode_info_low[i|0x4] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_R0_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_B; - opcode_info_low[i|0x5] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_R0_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_W; - opcode_info_low[i|0x6] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_R0_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L; - } - - /* MUL.L Rm,Rn */ - for (i = 0x000; i <= 0x0F0; i += 0x10) { - opcode_info_low[i|0x7] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn; - } - - /* CLRT */ - opcode_info_low[0x008] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_SR_T; - /* SETT */ - opcode_info_low[0x018] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_SR_T; - /* CLRMAC */ - opcode_info_low[0x028] = SH2_OPCODE_INFO_VALID; - - /* NOP */ - opcode_info_low[0x009] = SH2_OPCODE_INFO_VALID; - /* DIV0U */ - opcode_info_low[0x019] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_SR_T; - /* MOVT Rn */ - opcode_info_low[0x029] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn; - - /* STS MACH,Rn */ - opcode_info_low[0x00A] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn; - /* STS MACL,Rn */ - opcode_info_low[0x01A] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn; - /* STS PR,Rn */ - opcode_info_low[0x02A] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn; - - /* RTS */ - opcode_info_low[0x00B] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - /* SLEEP */ - opcode_info_low[0x01B] = SH2_OPCODE_INFO_VALID; - /* RTE */ - opcode_info_low[0x02B] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R15 - | SH2_OPCODE_INFO_SETS_SR_T - | SH2_OPCODE_INFO_ACCESSES_R15 - | SH2_OPCODE_INFO_ACCESS_SIZE_LL - | SH2_OPCODE_INFO_ACCESS_POSTINC - | SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - - /* MOV.* @(R0,Rm),Rn */ - for (i = 0x000; i <= 0x0F0; i += 0x10) { - opcode_info_low[i|0xC] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_R0_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_B; - opcode_info_low[i|0xD] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_R0_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_W; - opcode_info_low[i|0xE] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_R0_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_L; - } - - /* MAC.L @Rm+,@Rn+ */ - for (i = 0x000; i <= 0x0F0; i += 0x10) { - opcode_info_low[i|0xF] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_POSTINC; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_1xxx(void) -{ - /* MOV.L Rm,@(disp,Rn) */ - unsigned int i; - for (i = 0x100; i <= 0x1FF; i++) { - opcode_info_low[i] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_DISP_4; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_2xxx(void) -{ - unsigned int i; - for (i = 0x200; i <= 0x2F0; i += 0x10) { - - /* MOV.* Rm,@Rn */ - opcode_info_low[i|0x0] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_B; - opcode_info_low[i|0x1] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_W; - opcode_info_low[i|0x2] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L; - - /* MOV.* Rm,@-Rn */ - opcode_info_low[i|0x4] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_B - | SH2_OPCODE_INFO_ACCESS_PREDEC; - opcode_info_low[i|0x5] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_W - | SH2_OPCODE_INFO_ACCESS_PREDEC; - opcode_info_low[i|0x6] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_PREDEC; - - /* DIV0S Rm,Rn */ - opcode_info_low[i|0x7] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* TST Rm,Rn */ - opcode_info_low[i|0x8] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* AND Rm,Rn */ - opcode_info_low[i|0x9] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - - /* XOR Rm,Rn */ - opcode_info_low[i|0xA] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - - /* OR Rm,Rn */ - opcode_info_low[i|0xB] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - - /* CMP/ST Rm,Rn */ - opcode_info_low[i|0xC] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* XTRCT Rm,Rn */ - opcode_info_low[i|0xD] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - - /* MULU.W Rm,Rn */ - opcode_info_low[i|0xE] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn; - - /* MULS.W Rm,Rn */ - opcode_info_low[i|0xF] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_3xxx(void) -{ - unsigned int i; - for (i = 0x300; i <= 0x3F0; i += 0x10) { - - /* CMP/EQ Rm,Rn */ - opcode_info_low[i|0x0] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* CMP/HS Rm,Rn */ - opcode_info_low[i|0x2] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* CMP/GE Rm,Rn */ - opcode_info_low[i|0x3] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* DIV1 Rm,Rn */ - opcode_info_low[i|0x4] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* DMULU.L Rm,Rn */ - opcode_info_low[i|0x5] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn; - - /* CMP/HI Rm,Rn */ - opcode_info_low[i|0x6] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* CMP/GT Rm,Rn */ - opcode_info_low[i|0x7] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* SUB Rm,Rn */ - opcode_info_low[i|0x8] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - - /* SUBC Rm,Rn */ - opcode_info_low[i|0xA] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* SUBV Rm,Rn */ - opcode_info_low[i|0xB] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* ADD Rm,Rn */ - opcode_info_low[i|0xC] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - - /* DMULS.L Rm,Rn */ - opcode_info_low[i|0xD] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn; - - /* ADDC Rm,Rn */ - opcode_info_low[i|0xE] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* ADDV Rm,Rn */ - opcode_info_low[i|0xF] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_4xxx(void) -{ - /* SHLL Rn */ - opcode_info_low[0x400] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - /* DT Rn */ - opcode_info_low[0x410] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - /* SHAL Rn */ - opcode_info_low[0x420] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* SHLR Rn */ - opcode_info_low[0x401] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - /* CMP/PZ Rn */ - opcode_info_low[0x411] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - /* SHAR Rn */ - opcode_info_low[0x421] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* STS.L MACH,@-Rn */ - opcode_info_low[0x402] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_PREDEC; - /* STS.L MACL,@-Rn */ - opcode_info_low[0x412] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_PREDEC; - /* STS.L PR,@-Rn */ - opcode_info_low[0x422] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_PREDEC; - - /* STC.L SR,@-Rn */ - opcode_info_low[0x403] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_PREDEC; - /* STC.L GBR,@-Rn */ - opcode_info_low[0x413] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_PREDEC; - /* STC.L VBR,@-Rn */ - opcode_info_low[0x423] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_PREDEC; - - /* ROTL Rn */ - opcode_info_low[0x404] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - /* ROTCL Rn */ - opcode_info_low[0x424] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* ROTR Rn */ - opcode_info_low[0x405] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - /* CMP/PL Rn */ - opcode_info_low[0x415] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - /* ROTCR Rn */ - opcode_info_low[0x425] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* LDS.L @Rn+,MACH */ - opcode_info_low[0x406] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_POSTINC; - /* LDS.L @Rn+,MACL */ - opcode_info_low[0x416] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_POSTINC; - /* LDS.L @Rn+,PR */ - opcode_info_low[0x426] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_POSTINC; - - /* LDC.L @Rn+,SR */ - opcode_info_low[0x407] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_POSTINC; - /* LDC.L @Rn+,GBR */ - opcode_info_low[0x417] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_POSTINC; - /* LDC.L @Rn+,VBR */ - opcode_info_low[0x427] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_POSTINC; - - /* SHLL2 Rn */ - opcode_info_low[0x408] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - /* SHLL8 Rn */ - opcode_info_low[0x418] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - /* SHLL16 Rn */ - opcode_info_low[0x428] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - - /* SHLR2 Rn */ - opcode_info_low[0x409] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - /* SHLR8 Rn */ - opcode_info_low[0x419] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - /* SHLR16 Rn */ - opcode_info_low[0x429] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - - /* LDS Rn,MACH */ - opcode_info_low[0x40A] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn; - /* LDS Rn,MACL */ - opcode_info_low[0x41A] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn; - /* LDS Rn,PR */ - opcode_info_low[0x42A] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn; - - /* JSR @Rn */ - opcode_info_low[0x40B] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - /* TAS.B @Rn */ - opcode_info_low[0x41B] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_IS_RMW - | SH2_OPCODE_INFO_ACCESS_SIZE_B; - /* JMP @Rn */ - opcode_info_low[0x42B] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - - /* LDC Rn,SR */ - opcode_info_low[0x40E] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - /* LDC Rn,GBR */ - opcode_info_low[0x41E] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn; - /* LDC Rn,VBR */ - opcode_info_low[0x42E] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn; - - /* MAC.W @Rm+,@Rn+ */ - unsigned int i; - for (i = 0x400; i <= 0x4F0; i += 0x10) { - opcode_info_low[i|0xF] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESSES_Rn - | SH2_OPCODE_INFO_ACCESS_SIZE_W - | SH2_OPCODE_INFO_ACCESS_POSTINC; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_5xxx(void) -{ - /* MOV.L @(disp,Rm),Rn */ - unsigned int i; - for (i = 0x500; i <= 0x5FF; i++) { - opcode_info_low[i] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_DISP_4; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_6xxx(void) -{ - unsigned int i; - for (i = 0x600; i <= 0x6F0; i += 0x10) { - - /* MOV.* @Rm,Rn */ - opcode_info_low[i|0x0] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_B; - opcode_info_low[i|0x1] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_W; - opcode_info_low[i|0x2] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_L; - - /* MOV Rm,Rn */ - opcode_info_low[i|0x3] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - - /* MOV.* @Rm+,Rn */ - opcode_info_low[i|0x4] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_B - | SH2_OPCODE_INFO_ACCESS_POSTINC; - opcode_info_low[i|0x5] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_W - | SH2_OPCODE_INFO_ACCESS_POSTINC; - opcode_info_low[i|0x6] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_POSTINC; - - /* NOT Rm,Rn */ - opcode_info_low[i|0x7] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - - /* SWAP.* Rm,Rn */ - opcode_info_low[i|0x8] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - opcode_info_low[i|0x9] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - - /* NEGC Rm,Rn */ - opcode_info_low[i|0xA] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_SETS_SR_T; - - /* NEG Rm,Rn */ - opcode_info_low[i|0xB] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - - /* EXTU.* Rm,Rn */ - opcode_info_low[i|0xC] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - opcode_info_low[i|0xD] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - - /* EXTS.* Rm,Rn */ - opcode_info_low[i|0xE] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - opcode_info_low[i|0xF] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_Rn; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_7xxx(void) -{ - /* ADD #imm,Rn */ - unsigned int i; - for (i = 0x700; i <= 0x7FF; i++) { - opcode_info_low[i] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rn - | SH2_OPCODE_INFO_SETS_Rn; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_8xxx(void) -{ - /* MOV.B R0,@(disp,Rm) */ - opcode_info_high[0x00] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_B - | SH2_OPCODE_INFO_ACCESS_DISP_4; - - /* MOV.W R0,@(disp,Rm) */ - opcode_info_high[0x01] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_W - | SH2_OPCODE_INFO_ACCESS_DISP_4; - - /* MOV.B @(disp,Rm),R0 */ - opcode_info_high[0x04] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_R0 - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_B - | SH2_OPCODE_INFO_ACCESS_DISP_4; - - /* MOV.W @(disp,Rm),R0 */ - opcode_info_high[0x05] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_Rm - | SH2_OPCODE_INFO_SETS_R0 - | SH2_OPCODE_INFO_ACCESSES_Rm - | SH2_OPCODE_INFO_ACCESS_SIZE_W - | SH2_OPCODE_INFO_ACCESS_DISP_4; - - /* CMP/EQ #imm,R0 */ - opcode_info_high[0x08] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_SETS_SR_T; - - /* BT label */ - opcode_info_high[0x09] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_BRANCH_COND; - - /* BF label */ - opcode_info_high[0x0B] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_BRANCH_COND; - - /* BT/S label */ - opcode_info_high[0x0D] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_BRANCH_COND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - - /* BF/S label */ - opcode_info_high[0x0F] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_BRANCH_COND - | SH2_OPCODE_INFO_BRANCH_DELAYED; -} - -/*-----------------------------------------------------------------------*/ - -static void init_9xxx(void) -{ - /* MOV.W @(disp,PC),Rn */ - unsigned int i; - for (i = 0x10; i <= 0x1F; i++) { - opcode_info_high[i] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_PC - | SH2_OPCODE_INFO_ACCESS_SIZE_W - | SH2_OPCODE_INFO_ACCESS_DISP_8; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_Axxx(void) -{ - /* BRA label */ - unsigned int i; - for (i = 0x20; i <= 0x2F; i++) { - opcode_info_high[i] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_Bxxx(void) -{ - /* BRA label */ - unsigned int i; - for (i = 0x30; i <= 0x3F; i++) { - opcode_info_high[i] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_DELAYED; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_Cxxx(void) -{ - /* MOV.B R0,@(disp,GBR) */ - opcode_info_high[0x40] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_ACCESSES_GBR - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_B - | SH2_OPCODE_INFO_ACCESS_DISP_8; - - /* MOV.W R0,@(disp,GBR) */ - opcode_info_high[0x41] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_ACCESSES_GBR - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_W - | SH2_OPCODE_INFO_ACCESS_DISP_8; - - /* MOV.L R0,@(disp,GBR) */ - opcode_info_high[0x42] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_ACCESSES_GBR - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_DISP_8; - - /* TRAPA #imm */ - opcode_info_high[0x43] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R15 - | SH2_OPCODE_INFO_ACCESSES_R15 - | SH2_OPCODE_INFO_ACCESS_IS_STORE - | SH2_OPCODE_INFO_ACCESS_SIZE_LL - | SH2_OPCODE_INFO_ACCESS_PREDEC - | SH2_OPCODE_INFO_BRANCH_UNCOND; - - /* MOV.B @(disp,GBR),R0 */ - opcode_info_high[0x44] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_R0 - | SH2_OPCODE_INFO_ACCESSES_GBR - | SH2_OPCODE_INFO_ACCESS_SIZE_B - | SH2_OPCODE_INFO_ACCESS_DISP_8; - - /* MOV.W @(disp,GBR),R0 */ - opcode_info_high[0x45] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_R0 - | SH2_OPCODE_INFO_ACCESSES_GBR - | SH2_OPCODE_INFO_ACCESS_SIZE_W - | SH2_OPCODE_INFO_ACCESS_DISP_8; - - /* MOV.L @(disp,GBR),R0 */ - opcode_info_high[0x46] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_R0 - | SH2_OPCODE_INFO_ACCESSES_GBR - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_DISP_8; - - /* MOVA @(disp,PC),R0 */ - opcode_info_high[0x47] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_R0; - - /* TST #imm,R0 */ - opcode_info_high[0x48] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_SETS_SR_T; - - /* AND #imm,R0 */ - opcode_info_high[0x49] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_SETS_R0; - - /* XOR #imm,R0 */ - opcode_info_high[0x4A] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_SETS_R0; - - /* OR #imm,R0 */ - opcode_info_high[0x4B] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_SETS_R0; - - /* TST.B #imm,@(R0,GBR) */ - opcode_info_high[0x4C] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_SETS_SR_T - | SH2_OPCODE_INFO_ACCESSES_R0_GBR - | SH2_OPCODE_INFO_ACCESS_SIZE_B; - - /* AND.B #imm,@(R0,GBR) */ - opcode_info_high[0x4D] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_ACCESSES_R0_GBR - | SH2_OPCODE_INFO_ACCESS_IS_RMW - | SH2_OPCODE_INFO_ACCESS_SIZE_B; - - /* XOR.B #imm,@(R0,GBR) */ - opcode_info_high[0x4E] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_ACCESSES_R0_GBR - | SH2_OPCODE_INFO_ACCESS_IS_RMW - | SH2_OPCODE_INFO_ACCESS_SIZE_B; - - /* OR.B #imm,@(R0,GBR) */ - opcode_info_high[0x4F] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_USES_R0 - | SH2_OPCODE_INFO_ACCESSES_R0_GBR - | SH2_OPCODE_INFO_ACCESS_IS_RMW - | SH2_OPCODE_INFO_ACCESS_SIZE_B; -} - -/*-----------------------------------------------------------------------*/ - -static void init_Dxxx(void) -{ - /* MOV.L @(disp,PC),Rn */ - unsigned int i; - for (i = 0x50; i <= 0x5F; i++) { - opcode_info_high[i] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn - | SH2_OPCODE_INFO_ACCESSES_PC - | SH2_OPCODE_INFO_ACCESS_SIZE_L - | SH2_OPCODE_INFO_ACCESS_DISP_8; - } -} - -/*-----------------------------------------------------------------------*/ - -static void init_Exxx(void) -{ - /* MOV #imm,Rn */ - unsigned int i; - for (i = 0x60; i <= 0x6F; i++) { - opcode_info_high[i] = SH2_OPCODE_INFO_VALID - | SH2_OPCODE_INFO_SETS_Rn; - } -} - -/*************************************************************************/ -/********************** Opcode table lookup routine **********************/ -/*************************************************************************/ - -/** - * get_opcode_info: Return information about the given opcode. - * - * [Parameters] - * opcode: SH-2 opcode to obtain information about - * [Return value] - * - */ -int32_t get_opcode_info(uint16_t opcode) -{ - if (opcode & 0x8000) { - return opcode_info_high[(opcode & 0x7F00) >> 8]; - } else { - return opcode_info_low[(opcode & 0x7000) >> 4 | (opcode & 0xFF)]; - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/sh2-optimize.c b/yabause/src/psp/sh2-optimize.c deleted file mode 100644 index 5763fe6ae5..0000000000 --- a/yabause/src/psp/sh2-optimize.c +++ /dev/null @@ -1,1185 +0,0 @@ -/* src/psp/sh2-optimize.c: Optimization routines for SH-2 emulator - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ -/*************************** Required headers ****************************/ -/*************************************************************************/ - -#include "common.h" - -#include "../core.h" - -#include "rtl.h" -#include "sh2.h" -#include "sh2-internal.h" - -#ifdef JIT_DEBUG_TRACE -# include "../sh2d.h" -#endif - -/*************************************************************************/ -/****************************** Common data ******************************/ -/*************************************************************************/ - -#ifdef OPTIMIZE_IDLE - -/* - * The table below is used by OPTIMIZE_IDLE to find the effects of a given - * SH-2 instruction on machine state. Instruction opcodes are listed - * hierarchically, starting with idle_table_main[], which is indexed by the - * top 4 bits of the opcode (bits 12-15). Each table entry is either a - * pointer to a subtable with a shift count indicating which 4 bits of the - * opcode are used to index the subtable, or an instruction definition - * indicating the effects of the given set of opcodes. - * - * Instruction definitions consist of "used" and "changed" bitmasks, - * indicating which registers are used (read) or changed (written) by the - * instruction, respectively. For example, the instruction ADD Rm,Rn uses - * both registers Rm and Rn and changes register Rn, so it is defined as: - * - * {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_Rn} - * - * IDLE_Rm and IDLE_Rn in this example are pseudo-register flags, and are - * interpreted to mean the registers specified by the "m" and "n" fields of - * the opcode (bits 4-7 and 8-11 respectively). There are also individual - * flags for each of the individually-alterable fields in the SR register - * (T, S, Q, and M); the I field can only be altered by writing SR as a - * whole, and is not used directly by any instruction in any case. - * - * Instructions marked as IDLE_BAD in the "changed" field can never be part - * of an idle loop, either because the opcode group itself is invalid, or - * because the instruction modifies machine state in a fashion which is - * either nonrepeatable (such as postincrement or predecrement memory - * accesses) or not trivially repeatable (such as subroutine calls). - * - * The table also includes an "extra_cycles" field, used to indicate - * instructions which require more than one clock cycle to complete. This - * information is not currently used, but is stored in case it becomes - * useful in the future for computing the duration of a loop. - */ - -/*-----------------------------------------------------------------------*/ - -/* Bit values for register bitmasks */ -#define IDLE_R(n) (1U << (n)) -#define IDLE_SR_T (1U << 16) -#define IDLE_SR_S (1U << 17) -#define IDLE_SR_Q (1U << 18) -#define IDLE_SR_M (1U << 19) -#define IDLE_SR_MQT (IDLE_SR_T | IDLE_SR_Q | IDLE_SR_M) -#define IDLE_SR (IDLE_SR_T | IDLE_SR_S | IDLE_SR_Q | IDLE_SR_M) -#define IDLE_GBR (1U << 20) -#define IDLE_VBR (1U << 21) -#define IDLE_PR (1U << 22) -#define IDLE_MACL (1U << 23) -#define IDLE_MACH (1U << 24) -#define IDLE_MAC (IDLE_MACL | IDLE_MACH) - -/* Value used in IdleInfo.changed field to indicate an instruction which - * can never be part of an idle loop */ -#define IDLE_BAD (1U << 31) - -/* Virtual bits used for the Rn (bits 8-11) and Rm (bits 4-7) fields of - * the instruction; e.g. IDLE_Rn translates to IDLE_R(opcode>>8 & 0xF) */ -#define IDLE_Rn (1U << 30) -#define IDLE_Rm (1U << 29) - -/* Table data structure; fields "used" and "changed" are ignored if - * "subtable" is non-NULL */ -typedef struct IdleInfo_ IdleInfo; -struct IdleInfo_ { - uint32_t used; // Bitmask of registers used by the instruction - uint32_t changed; // Bitmask of registers changed by the instruction - uint8_t extra_cycles; // Clock cycles used by instruction minus 1 - uint8_t next_shift; // Bit position of subtable index (0, 4, or 8) - const IdleInfo *subtable; // NULL if no subtable for this opcode -}; - -/*-----------------------------------------------------------------------*/ - -/* Opcode table for $0xx2 opcodes */ -static const IdleInfo idle_table_0xx2[16] = { - {.used = IDLE_SR, .changed = IDLE_Rn}, // STC SR,Rn - {.used = IDLE_GBR, .changed = IDLE_Rn}, // STC GBR,Rn - {.used = IDLE_VBR, .changed = IDLE_Rn}, // STC VBR,Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $0xx3 opcodes */ -static const IdleInfo idle_table_0xx3[16] = { - {.changed = IDLE_BAD}, // BSRF Rn - {.changed = IDLE_BAD}, // invalid - {.used = IDLE_Rn, .changed = 0, .extra_cycles = 1}, // BRAF Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $0xx8 opcodes */ -static const IdleInfo idle_table_0xx8[16] = { - {.used = 0, .changed = IDLE_SR_T}, // CLRT - {.used = 0, .changed = IDLE_SR_T}, // SETT - {.used = 0, .changed = IDLE_MAC}, // CLRMAC - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $0xx9 opcodes */ -static const IdleInfo idle_table_0xx9[16] = { - {.used = 0, .changed = 0}, // NOP - {.used = 0, .changed = IDLE_SR_MQT}, // DIV0U - {.used = IDLE_SR_T, .changed = IDLE_Rn}, // MOVT Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -static const IdleInfo idle_table_0xxA[16] = { - {.used = IDLE_MACH, .changed = IDLE_Rn}, // STS MACH,Rn - {.used = IDLE_MACL, .changed = IDLE_Rn}, // STS MACL,Rn - {.used = IDLE_PR, .changed = IDLE_Rn}, // STS PR,Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $0xxx opcodes */ -static const IdleInfo idle_table_0xxx[16] = { - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.next_shift = 4, .subtable = idle_table_0xx2}, - {.next_shift = 4, .subtable = idle_table_0xx3}, - - {.changed = IDLE_BAD}, // MOV.B Rm,@(R0,Rn) - {.changed = IDLE_BAD}, // MOV.W Rm,@(R0,Rn) - {.changed = IDLE_BAD}, // MOV.L Rm,@(R0,Rn) - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_MACL, .extra_cycles = 1}, // MUL.L Rm,Rn - - {.next_shift = 4, .subtable = idle_table_0xx8}, - {.next_shift = 4, .subtable = idle_table_0xx9}, - {.next_shift = 4, .subtable = idle_table_0xxA}, - {.changed = IDLE_BAD}, // RTS, SLEEP, RTE - - {.used = IDLE_R(0)|IDLE_Rm, .changed = IDLE_Rn}, // MOV.B @(R0,Rm),Rn - {.used = IDLE_R(0)|IDLE_Rm, .changed = IDLE_Rn}, // MOV.W @(R0,Rm),Rn - {.used = IDLE_R(0)|IDLE_Rm, .changed = IDLE_Rn}, // MOV.L @(R0,Rm),Rn - {.changed = IDLE_BAD}, // MAC.L @Rm+,@Rn+ -}; - -/*----------------------------------*/ - -/* Opcode table for $2xxx opcodes */ -static const IdleInfo idle_table_2xxx[16] = { - {.changed = IDLE_BAD}, // MOV.B Rm,@Rn - {.changed = IDLE_BAD}, // MOV.W Rm,@Rn - {.changed = IDLE_BAD}, // MOV.L Rm,@Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // MOV.B Rm,@-Rn - {.changed = IDLE_BAD}, // MOV.W Rm,@-Rn - {.changed = IDLE_BAD}, // MOV.L Rm,@-Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_SR_MQT}, // DIV0S Rm,Rn - - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_SR_T}, // TST Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_Rn}, // AND Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_Rn}, // XOR Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_Rn}, // OR Rm,Rn - - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_SR_T}, // CMP/ST Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_Rn}, // XTRCT Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_MACL}, // MULU.W Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_MACL}, // MULS.W Rm,Rn -}; - -/*----------------------------------*/ - -/* Opcode table for $3xxx opcodes */ -static const IdleInfo idle_table_3xxx[16] = { - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_SR_T}, // CMP/EQ Rm,Rn - {.changed = IDLE_BAD}, // invalid - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_SR_T}, // CMP/HS Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_SR_T}, // CMP/GE Rm,Rn - - {.changed = IDLE_BAD}, // DIV1 Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_MAC, .extra_cycles = 1}, // DMULU.L Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_SR_T}, // CMP/HI Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_SR_T}, // CMP/GT Rm,Rn - - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_Rn}, // SUB Rm,Rn - {.changed = IDLE_BAD}, // invalid - {.used = IDLE_Rm|IDLE_Rn|IDLE_SR_T, .changed = IDLE_Rn|IDLE_SR_T}, // SUBC Rm,Rn - {.used = IDLE_Rm|IDLE_Rn|IDLE_SR_T, .changed = IDLE_Rn|IDLE_SR_T}, // SUBV Rm,Rn - - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_Rn}, // ADD Rm,Rn - {.used = IDLE_Rm|IDLE_Rn, .changed = IDLE_MAC, .extra_cycles = 1}, // DMULS.L Rm,Rn - {.used = IDLE_Rm|IDLE_Rn|IDLE_SR_T, .changed = IDLE_Rn|IDLE_SR_T}, // ADDC Rm,Rn - {.used = IDLE_Rm|IDLE_Rn|IDLE_SR_T, .changed = IDLE_Rn|IDLE_SR_T}, // ADDV Rm,Rn -}; - -/*----------------------------------*/ - -/* Opcode table for $4xx0 opcodes */ -static const IdleInfo idle_table_4xx0[16] = { - {.used = IDLE_Rn, .changed = IDLE_Rn|IDLE_SR_T}, // SHLL Rn - {.used = IDLE_Rn, .changed = IDLE_Rn|IDLE_SR_T}, // DT Rn - {.used = IDLE_Rn, .changed = IDLE_Rn|IDLE_SR_T}, // SHAL Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xx1 opcodes */ -static const IdleInfo idle_table_4xx1[16] = { - {.used = IDLE_Rn, .changed = IDLE_Rn|IDLE_SR_T}, // SHLR Rn - {.used = IDLE_Rn, .changed = IDLE_SR_T}, // CMP/PZ Rn - {.used = IDLE_Rn, .changed = IDLE_Rn|IDLE_SR_T}, // SHAR Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xx4 opcodes */ -static const IdleInfo idle_table_4xx4[16] = { - {.used = IDLE_Rn, .changed = IDLE_Rn|IDLE_SR_T}, // ROTL Rn - {.changed = IDLE_BAD}, // invalid - {.used = IDLE_Rn|IDLE_SR_T, .changed = IDLE_Rn|IDLE_SR_T}, // ROTCL Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xx5 opcodes */ -static const IdleInfo idle_table_4xx5[16] = { - {.used = IDLE_Rn, .changed = IDLE_Rn|IDLE_SR_T}, // ROTR Rn - {.used = IDLE_Rn, .changed = IDLE_SR_T}, // CMP/PL Rn - {.used = IDLE_Rn|IDLE_SR_T, .changed = IDLE_Rn|IDLE_SR_T}, // ROTCR Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xx8 opcodes */ -static const IdleInfo idle_table_4xx8[16] = { - {.used = IDLE_Rn, .changed = IDLE_Rn}, // SHLL2 Rn - {.used = IDLE_Rn, .changed = IDLE_Rn}, // SHLL8 Rn - {.used = IDLE_Rn, .changed = IDLE_Rn}, // SHLL16 Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xx9 opcodes */ -static const IdleInfo idle_table_4xx9[16] = { - {.used = IDLE_Rn, .changed = IDLE_Rn}, // SHLR2 Rn - {.used = IDLE_Rn, .changed = IDLE_Rn}, // SHLR8 Rn - {.used = IDLE_Rn, .changed = IDLE_Rn}, // SHLR16 Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xxA opcodes */ -static const IdleInfo idle_table_4xxA[16] = { - {.used = IDLE_Rn, .changed = IDLE_MACH}, // LDS Rn,MACH - {.used = IDLE_Rn, .changed = IDLE_MACL}, // LDS Rn,MACL - {.used = IDLE_Rn, .changed = IDLE_PR}, // LDS Rn,PR - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xxB opcodes */ -static const IdleInfo idle_table_4xxB[16] = { - {.changed = IDLE_BAD}, // JSR @Rn - {.changed = IDLE_BAD}, // TAS @Rn - {.used = 0, .changed = 0, .extra_cycles = 1}, // JMP @Rn - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xxE opcodes */ -static const IdleInfo idle_table_4xxE[16] = { - {.used = IDLE_Rn, .changed = IDLE_SR}, // LDC Rn,SR - {.used = IDLE_Rn, .changed = IDLE_GBR}, // LDC Rn,GBR - {.used = IDLE_Rn, .changed = IDLE_VBR}, // LDC Rn,VBR - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid -}; - -/* Opcode table for $4xxx opcodes */ -static const IdleInfo idle_table_4xxx[16] = { - {.next_shift = 4, .subtable = idle_table_4xx0}, - {.next_shift = 4, .subtable = idle_table_4xx1}, - {.changed = IDLE_BAD}, // STSL ...,@-Rn - {.changed = IDLE_BAD}, // STCL ...,@-Rn - - {.next_shift = 4, .subtable = idle_table_4xx4}, - {.next_shift = 4, .subtable = idle_table_4xx5}, - {.changed = IDLE_BAD}, // LDSL @Rm+,... - {.changed = IDLE_BAD}, // LDCL @Rm+,... - - {.next_shift = 4, .subtable = idle_table_4xx8}, - {.next_shift = 4, .subtable = idle_table_4xx9}, - {.next_shift = 4, .subtable = idle_table_4xxA}, - {.next_shift = 4, .subtable = idle_table_4xxB}, - - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - {.next_shift = 4, .subtable = idle_table_4xxE}, - {.changed = IDLE_BAD}, // MAC.W @Rm+,@Rn+ -}; - -/*----------------------------------*/ - -/* Opcode table for $6xxx opcodes */ -static const IdleInfo idle_table_6xxx[16] = { - {.used = IDLE_Rm, .changed = IDLE_Rn}, // MOV.B @Rm,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // MOV.W @Rm,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // MOV.L @Rm,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // MOV Rm,Rn - - {.used = IDLE_Rm, .changed = IDLE_Rm|IDLE_Rn}, // MOV.B @Rm+,Rn - {.used = IDLE_Rm, .changed = IDLE_Rm|IDLE_Rn}, // MOV.W @Rm+,Rn - {.used = IDLE_Rm, .changed = IDLE_Rm|IDLE_Rn}, // MOV.L @Rm+,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // NOT Rm,Rn - - {.used = IDLE_Rm, .changed = IDLE_Rn}, // SWAP.B Rm,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // SWAP.W Rm,Rn - {.used = IDLE_Rm|IDLE_SR_T, .changed = IDLE_Rn|IDLE_SR_T}, // NEGC Rm,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // NEG Rm,Rn - - {.used = IDLE_Rm, .changed = IDLE_Rn}, // EXTU.B Rm,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // EXTU.W Rm,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // EXTS.B Rm,Rn - {.used = IDLE_Rm, .changed = IDLE_Rn}, // EXTS.W Rm,Rn -}; - -/*----------------------------------*/ - -/* Opcode table for $8xxx opcodes */ -static const IdleInfo idle_table_8xxx[16] = { - {.changed = IDLE_BAD}, // MOV.B R0,@(disp,Rm) - {.changed = IDLE_BAD}, // MOV.W R0,@(disp,Rm) - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.used = IDLE_Rm, .changed = IDLE_R(0)}, // MOV.B @(disp,Rm),R0 - {.used = IDLE_Rm, .changed = IDLE_R(0)}, // MOV.W @(disp,Rm),R0 - {.changed = IDLE_BAD}, // invalid - {.changed = IDLE_BAD}, // invalid - - {.used = IDLE_R(0), .changed = IDLE_SR_T}, // CMP/EQ #imm,R0 - {.used = IDLE_SR_T, .changed = 0, .extra_cycles = 2}, // BT label - {.changed = IDLE_BAD}, // invalid - {.used = IDLE_SR_T, .changed = 0, .extra_cycles = 2}, // BF label - - {.changed = IDLE_BAD}, // invalid - {.used = IDLE_SR_T, .changed = 0, .extra_cycles = 1}, // BT/S label - {.changed = IDLE_BAD}, // invalid - {.used = IDLE_SR_T, .changed = 0, .extra_cycles = 1}, // BF/S label -}; - -/*----------------------------------*/ - -/* Opcode table for $Cxxx opcodes */ -static const IdleInfo idle_table_Cxxx[16] = { - {.changed = IDLE_BAD}, // MOV.B R0,@(disp,GBR) - {.changed = IDLE_BAD}, // MOV.W R0,@(disp,GBR) - {.changed = IDLE_BAD}, // MOV.L R0,@(disp,GBR) - {.changed = IDLE_BAD}, // TRAPA #imm - - {.used = IDLE_GBR, .changed = IDLE_R(0)}, // MOV.B @(disp,GBR),R0 - {.used = IDLE_GBR, .changed = IDLE_R(0)}, // MOV.W @(disp,GBR),R0 - {.used = IDLE_GBR, .changed = IDLE_R(0)}, // MOV.L @(disp,GBR),R0 - {.used = 0, .changed = IDLE_R(0)}, // MOVA @(disp,PC),R0 - - {.used = IDLE_R(0), .changed = IDLE_SR_T}, // TST #imm,R0 - {.used = IDLE_R(0), .changed = IDLE_R(0)}, // AND #imm,R0 - {.used = IDLE_R(0), .changed = IDLE_R(0)}, // XOR #imm,R0 - {.used = IDLE_R(0), .changed = IDLE_R(0)}, // OR #imm,R0 - - {.used = IDLE_R(0)|IDLE_GBR, .changed = IDLE_SR_T}, // TST #imm,@(R0,GBR) - {.changed = IDLE_BAD}, // AND #imm,@(R0,GBR) - {.changed = IDLE_BAD}, // XOR #imm,@(R0,GBR) - {.changed = IDLE_BAD}, // OR #imm,@(R0,GBR) -}; - -/*----------------------------------*/ - -/* Main opcode table (for bits 12-15) */ -static const IdleInfo idle_table_main[16] = { - {.next_shift = 0, .subtable = idle_table_0xxx}, - {.changed = IDLE_BAD}, // MOV.L Rm,@(disp,Rn) - {.next_shift = 0, .subtable = idle_table_2xxx}, - {.next_shift = 0, .subtable = idle_table_3xxx}, - - {.next_shift = 0, .subtable = idle_table_4xxx}, - {.used = IDLE_Rm, .changed = IDLE_Rn}, // MOV.L @(disp,Rn),Rm - {.next_shift = 0, .subtable = idle_table_6xxx}, - {.changed = IDLE_BAD}, // ADD #imm,Rn - - {.next_shift = 8, .subtable = idle_table_8xxx}, - {.used = 0, .changed = IDLE_Rn}, // MOV.W @(disp,PC),Rn - {.used = 0, .changed = 0, .extra_cycles = 1}, // BRA label - {.changed = IDLE_BAD}, // BSR label - - {.next_shift = 8, .subtable = idle_table_Cxxx}, - {.used = 0, .changed = IDLE_Rn}, // MOV.L @(disp,PC),Rn - {.used = 0, .changed = IDLE_Rn}, // MOV #imm,Rn - {.changed = IDLE_BAD}, // invalid -}; - -/*-----------------------------------------------------------------------*/ - -#endif // OPTIMIZE_IDLE - -/*************************************************************************/ -/************************ Idle loop optimization *************************/ -/*************************************************************************/ - -#ifdef OPTIMIZE_IDLE - -/* - * A loop is "idle" if a single execution of the entire loop, starting from - * the first instruction of the loop and ending immediately before the next - * time the first instruction is executed, has no net effect on the state - * of the system after the first iteration of the loop. Each individual - * instruction may alter system state (and in fact, the program counter - * will change with each instruction executed), but provided that the - * external system state remains constant, the final result of executing N - * loops must be identical to the result of executing N-1 loops for N - * greater than 1. - * - * For example, a loop consisting solely of a branch to the same - * instruction: - * 0x1000: bra 0x1000 - * 0x1002: nop - * would naturally qualify, as would a loop reading from the same memory - * location (here, waiting for a memory address to read as zero): - * 0x1000: mov.l @r0, r1 - * 0x1002: tst r1, r1 - * 0x1004: bf 0x1000 - * - * On the flip side, a loop with a counter: - * 0x1000: dt r0 - * 0x1002: bf 0x1000 - * would _not_ qualify, because the state of the system changes with each - * iteration of the loop (though this particular loop can be optimized - * separately through OPTIMIZE_DELAY). Likewise, a loop containing a store - * to memory: - * 0x1000: mov.l r2, @r3 - * 0x1002: mov.l @r0, r1 - * 0x1004: tst r1, r1 - * 0x1006: bt 0x1000 - * would not qualify, because a store operation is assumed to change system - * state even if the value stored is the same. (Even for ordinary memory, - * in a multiprocessor system like the Saturn memory can be accessed by - * agents other than the processor, and an identical store operation may - * have differing effects from one iteration to the next.) - * - * To determine whether a loop is idle, we check whether all operations - * performed in the loop depend on constant values; in other words, no - * instruction in the loop may modify a register which is used as a source - * for that or an earlier instruction. (The contents of memory are assumed - * to be constant for this purpose, and any side effects of load - * instructions are ignored.) One result of this is that any loop with an - * ALU-type operation other than CMP cannot be considered idle, except as - * discussed below, even in cases where the loop does not in fact have a - * net change in state: - * 0x1000: mov.l @r0+, r1 - * 0x1002: cmp/pl @r1 - * 0x1004: bt 0x100A - * 0x1006: bra 0x1000 - * 0x1008: add #-4, r0 - * 0x100A: ... - * While admittedly somewhat contrived, this example has no net effect on - * system state because R0 is decremented at the end of each loop; but - * because R0 is used both in a postincrement memory access and as the - * target of an ADD, its value cannot be considered a constant, so the - * loop is not treated as idle. (A more sophisticated algorithm could - * track such changes in value and determine their cumulative effect, but - * in most cases the simplistic algorithm we use is sufficient.) - * - * As an exception to the above, if a register is modified before it is - * used by another instruction, the register becomes a "don't care" for - * the remainder of the loop. Thus a loop like: - * 0x1000: mov.b @r0, r1 - * 0x1002: add r2, r1 - * 0x1004: tst r1, r1 - * 0x1006: bt 0x1000 - * qualifies as an idle loop despite the "add" instruction writing to - * the same register it reads from. - */ - -/*-----------------------------------------------------------------------*/ - -/** - * can_optimize_idle: Return whether the given sequence of instructions - * forms an "idle loop", in which the processor remains in a constant state - * (or repeating sequence of states) indefinitely until a certain external - * event occurs, such as an interrupt or a change in the value of a memory- - * mapped register. If an idle loop is detected, also return information - * allowing the loop to be translated into a faster sequence of native - * instructions. - * - * The sequence of instructions is assumed to end with a branch instruction - * to the beginning of the sequence (possibly including a delay slot). - * - * [Parameters] - * insn_ptr: Pointer to first instruction - * PC: PC of first instruction - * count: Number of instructions to check - * [Return value] - * Nonzero if the given sequence of SH-2 instructions form an idle - * loop, else zero - */ -int can_optimize_idle(const uint16_t *insn_ptr, uint32_t PC, - unsigned int count) -{ - uint32_t used_regs; // Which registers have been used so far? - uint32_t dont_care; // Which registers are "don't cares"? - int can_optimize = 1; - unsigned int i; - - /* We detect failure by matching the changed-registers bitmask against - * used_regs; set the initial value so that non-idleable instructions - * are automatically rejected */ - used_regs = IDLE_BAD; - /* Initially, no registers are don't cares */ - dont_care = 0; - - for (i = 0; can_optimize && i < count; i++) { - const uint16_t opcode = *insn_ptr++; - - /* Find the entry for this opcode */ - int shift = 12; - const IdleInfo *table = idle_table_main; - while (table[opcode>>shift & 0xF].subtable) { - int newshift = table[opcode>>shift & 0xF].next_shift; - table = table[opcode>>shift & 0xF].subtable; - shift = newshift; - } - - /* Replace virtual Rn/Rm bits with real registers from opcode */ - uint32_t used = table[opcode>>shift & 0xF].used; - uint32_t changed = table[opcode>>shift & 0xF].changed; - if (used & IDLE_Rn) { - used &= ~IDLE_Rn; - used |= IDLE_R(opcode>>8 & 0xF); - } - if (used & IDLE_Rm) { - used &= ~IDLE_Rm; - used |= IDLE_R(opcode>>4 & 0xF); - } - if (changed & IDLE_Rn) { - changed &= ~IDLE_Rn; - changed |= IDLE_R(opcode>>8 & 0xF); - } - if (changed & IDLE_Rm) { - changed &= ~IDLE_Rm; - changed |= IDLE_R(opcode>>4 & 0xF); - } - - /* Add any registers used by this instruction to used_regs */ - used_regs |= used; - - /* Add any not-yet-used registers modified by this instruction to - * dont_care */ - dont_care |= changed & ~used_regs; - - /* See whether we can still treat this as an idle loop */ - if (changed & ~dont_care & used_regs) { - can_optimize = 0; - } - } - - return can_optimize; -} - -/*-----------------------------------------------------------------------*/ - -#endif // OPTIMIZE_IDLE - -/*************************************************************************/ -/************************* Division optimization *************************/ -/*************************************************************************/ - -#ifdef OPTIMIZE_DIVISION - -/* - * On the SH-2, unsigned 64bit/32bit division follows the sequence: - * DIV0U - * .arepeat 32 ;Repeat 32 times - * ROTCL Rlo - * DIV1 Rdiv,Rhi - * .aendr - * and finishes with the following state changes: - * M = 0 - * T = low bit of quotient - * Q = !T - * Rlo = high 31 bits of quotient in bits 0-30, with 0 in bit 31 - * Rhi = !Q ? remainder : (remainder - Rdiv) - * If the number of repetitions of ROTCL Rlo / DIV1 Rdiv,Rhi is less than - * 32, the result is equivalent to shifting the dividend right (32-N) bits - * where N is the repetition count, except that the low (32-N) bits of the - * dividend remain in the most-significant bits of Rlo. - * - * Signed 64bit/32bit division (where the dividend is a 32-bit signed value - * sign-extended to 64 bits) follows a sequence identical to unsigned - * division except for the first instruction: - * DIV0S Rdiv,Rhi - * .arepeat 32 ;Repeat 32 times - * ROTCL Rlo - * DIV1 Rdiv,Rhi - * .aendr - * and finishes with the following state changes: - * M = sign bit of divisor - * (if dividend >= 0) - * T = low bit of (quotient - M) - * Q = !(T ^ M) - * Rlo = high 31 bits of (quotient - M) in bits 0-30, - * sign-extended to 32 bits - * Rhi = !Q ? remainder : (remainder - abs(Rdiv)) - * (if dividend < 0) - * qtemp = quotient + (remainder ? (M ? 1 : -1) : 0) - * T = low bit of (qtemp - M) - * Q = !(T ^ M) - * Rlo = high 31 bits of (qtemp - M) in bits 0-30, - * sign-extended to 32 bits - * Rhi = !Q ? (remainder == 0 ? remainder : remainder + abs(Rdiv)) - * : (remainder != 0 ? remainder : remainder - abs(Rdiv)) - * - * In all cases, division by zero ends with: - * M = 0 - * T = 1 - * Q = 0 - * Rhi:Rlo = Rlo<<32 | x<<31 | (unsigned)(~Rhi)>>1 - * where x is 0 for unsigned division and the high bit of Rlo for signed - * division. - * - * Both of these sequences can thus be optimized significantly using native - * division instructions (at one point, a factor-of-18 reduction in - * execution speed was measured). - */ - -/*-----------------------------------------------------------------------*/ - -/** - * can_optimize_div0u: Return whether a sequence of instructions starting - * from a DIV0U instruction can be optimized to a native divide operation. - * - * [Parameters] - * insn_ptr: Pointer to DIV0U instruction - * PC: PC of DIV0U instruction - * skip_first_rotcl: Nonzero if the first ROTCL instruction is known to - * be omitted (as may happen if the low word of - * the dividend is known to be zero) - * Rhi_ret: Pointer to variable to receive index of dividend high register - * Rlo_ret: Pointer to variable to receive index of dividend low register - * Rdiv_ret: Pointer to variable to receive index of divisor register - * [Return value] - * Number of bits of division performed by the instructions following - * the DIV0U instruction (1-32), or zero if the following instructions - * do not perform a division operation - */ -int can_optimize_div0u(const uint16_t *insn_ptr, uint32_t PC, - int skip_first_rotcl, - int *Rhi_ret, int *Rlo_ret, int *Rdiv_ret) -{ - uint16_t opcode; // Opcode read from instruction stream - uint16_t rotcl_op = 0, div1_op = 0; // Expected opcodes - int nbits; // Number of bits divided so far - - if (!skip_first_rotcl) { - opcode = *++insn_ptr; - if ((opcode & 0xF0FF) != 0x4024) { // ROTCL Rlo -#ifdef JIT_DEBUG - DMSG("DIV0U optimization failed: PC+2 (0x%08X) is 0x%04X, not" - " ROTCL", PC+2, opcode); -#endif - return 0; - } - *Rlo_ret = opcode>>8 & 0xF; - rotcl_op = opcode; - } - - opcode = *++insn_ptr; - if ((opcode & 0xF00F) != 0x3004) { // DIV1 Rdiv,Rhi -#ifdef JIT_DEBUG - DMSG("DIV0U optimization failed: PC+%d (0x%08X) is 0x%04X, not DIV1", - skip_first_rotcl ? 2 : 4, PC + (skip_first_rotcl ? 2 : 4), - opcode); -#endif - return 0; - } - *Rhi_ret = opcode>>8 & 0xF; - *Rdiv_ret = opcode>>4 & 0xF; - div1_op = opcode; - - if (skip_first_rotcl) { - opcode = insn_ptr[1]; // Don't advance yet--we're just peeking - if ((opcode & 0xF0FF) != 0x4024) { -#ifdef JIT_DEBUG - DMSG("DIV0U optimization failed (with skip_first_rotcl):" - " PC+4 (0x%08X) is 0x%04X, not ROTCL", PC+4, opcode); -#endif - return 0; - } - *Rlo_ret = opcode>>8 & 0xF; - rotcl_op = opcode; - } - - for (nbits = 1; nbits < 32; nbits++) { - opcode = *++insn_ptr; - if (opcode != rotcl_op) { -#ifdef JIT_DEBUG_VERBOSE - DMSG("DIV0U optimization stopped at %d bits: PC+%d (0x%08X) is" - " 0x%04X, not ROTCL R%d", - nbits, (skip_first_rotcl ? 0 : 2) + 4*nbits, - PC + ((skip_first_rotcl ? 0 : 2) + 4*nbits), opcode, - *Rlo_ret); -#endif - break; - } - - opcode = *++insn_ptr; - if (opcode != div1_op) { -#ifdef JIT_DEBUG_VERBOSE - DMSG("DIV0U optimization stopped at %d bits: PC+%d (0x%08X) is" - " 0x%04X, not DIV1 R%d,R%d", - nbits, (skip_first_rotcl ? 2 : 4) + 4*nbits, - PC + ((skip_first_rotcl ? 2 : 4) + 4*nbits), opcode, - *Rdiv_ret, *Rhi_ret); -#endif - break; - } - } // for 32 bits - - return nbits; -} - -/*-----------------------------------------------------------------------*/ - -/** - * can_optimize_div0s: Return whether a sequence of instructions starting - * from a DIV0S instruction can be optimized to a native divide operation. - * - * [Parameters] - * insn_ptr: Pointer to instruction following DIV0S instruction - * PC: PC of instruction following DIV0S instruction - * Rhi: Index of dividend high register - * Rlo_ret: Pointer to variable to receive index of dividend low register - * Rdiv: Index of divisor register - * [Return value] - * Nonzero if the next 64 SH-2 instructions form a 32-bit division - * operation, else zero - */ -int can_optimize_div0s(const uint16_t *insn_ptr, uint32_t PC, - int Rhi, int *Rlo_ret, int Rdiv) -{ - uint16_t rotcl_op = 0, div1_op = 0x3004 | Rhi<<8 | Rdiv<<4; - int can_optimize = 1; - unsigned int i; - - for (i = 0; can_optimize && i < 64; i++) { - uint16_t nextop = *insn_ptr++; - - if (i%2 == 0) { // ROTCL Rlo - - if (i == 0) { - if ((nextop & 0xF0FF) == 0x4024) { - *Rlo_ret = nextop>>8 & 0xF; - rotcl_op = nextop; - } else { - /* Don't complain for the first instruction, since - * DIV0S seems to be put to uses other than division - * as well */ - can_optimize = 0; - } - } else { - if (UNLIKELY(nextop != rotcl_op)) { - DMSG("DIV0S optimization failed: PC+%d (0x%08X) is 0x%04X," - " not ROTCL R%d", 2 + 2*i, PC + 2*i, nextop, - *Rlo_ret); - can_optimize = 0; - } - } - - } else { // DIV1 Rdiv,Rhi - - if (UNLIKELY(nextop != div1_op)) { - DMSG("DIV0S optimization failed: PC+%d (0x%08X) is 0x%04X," - " not DIV1 R%d,R%d", 2 + 2*i, PC + 2*i, nextop, Rdiv, Rhi); - can_optimize = 0; - } - - } - } // for 64 instructions - - return can_optimize; -} - -#endif // OPTIMIZE_DIVISION - -/*************************************************************************/ -/********************** Variable shift optimization **********************/ -/*************************************************************************/ - -#ifdef OPTIMIZE_VARIABLE_SHIFTS - -/* - * The SH-2's repertoire of shift instructions is fairly limited compared - * to modern processors. While the SH-2 has a few multi-bit shift - * instructions (SHLL2, SHLR8, and the like), it cannot shift a register - * by an arbitrary constant, instead requiring a sequence of fixed-sized - * shifts to accomplish the task. More importantly, the SH-2 also cannot - * shift by a variable count specified in another register, meaning that - * programs must use conditional tests or loops instead. Since modern - * processors do have variable-count shift instructions, such tests or - * loops can be significantly shortened, eliminating branches that can - * hurt optimizability of the code. - * - * Currently, the following variable shift/rotate sequences is recognized: - * - * - TST #1, R0 - * BT .+4 - * SHL[LR] Rshift - * TST #2, R0 - * BT .+4 - * SHL[LR]2 Rshift - * TST #4, R0 - * BT .+6 - * SHL[LR]2 Rshift - * SHL[LR]2 Rshift - * [TST #8, R0 - * BT .+4 - * SHL[LR]8 Rshift - * [TST #16, R0 - * BT .+4 - * SHL[LR]16 Rshift]] - * - * - BRAF Rcount_adjusted [Rcount_adjusted = (maximum shift - Rcount) * 2] - * (delay slot) - * SHLL Rshift [or SHAL, SHLR, SHAR, ROTL, ROTR] - * SHLL Rshift - * ... - */ - -/*-----------------------------------------------------------------------*/ - -/** - * can_optimize_variable_shift: Return whether a sequence of instructions - * can be optimized to a native variable-count shift operation. - * - * [Parameters] - * insn_ptr: Pointer to first instruction - * PC: PC of first instruction - * Rcount_ret: Pointer to variable to receive index of shift count register - * max_ret: Pointer to variable to receive maximum shift count - * Rshift_ret: Pointer to variable to receive index of target register - * type_ret: Pointer to variable to receive: - * 0 if a SHLL/SHAL sequence - * 1 if a SHLR sequence - * 2 if a SHAR sequence - * 3 if a ROTL sequence - * 4 if a ROTR sequence - * cycles_ret: Pointer to variable to receive pointer to an array of - * cycle counts indexed by shift count (unused for some - * types of sequences) - * [Return value] - * Number of instructions consumed (nonzero) if an optimizable sequence - * is found, else zero - */ -unsigned int can_optimize_variable_shift( - const uint16_t *insn_ptr, uint32_t PC, unsigned int *Rcount_ret, - unsigned int *max_ret, unsigned int *Rshift_ret, unsigned int *type_ret, - const uint8_t **cycles_ret) -{ - if (insn_ptr[0] == 0xC801 // TST #1, R0 - && insn_ptr[1] == 0x8900 // BT .+4 - && (insn_ptr[2] & 0xF0FE) == 0x4000 // SHL[LR] Rshift - && insn_ptr[3] == 0xC802 // TST #2, R0 - && insn_ptr[4] == 0x8900 // BT .+4 - && insn_ptr[5] == (insn_ptr[2] | 0x0008) // SHL[LR]2 Rshift - && insn_ptr[6] == 0xC804 // TST #4, R0 - && insn_ptr[7] == 0x8901 // BT .+6 - && insn_ptr[8] == (insn_ptr[2] | 0x0008) // SHL[LR]2 Rshift - && insn_ptr[9] == (insn_ptr[2] | 0x0008) // SHL[LR]2 Rshift - ) { - *Rcount_ret = 0; - *Rshift_ret = insn_ptr[2]>>8 & 0xF; - *type_ret = (insn_ptr[2] & 1) ? 1 : 0; - if (insn_ptr[10] == 0xC808 // TST #8, R0 - && insn_ptr[11] == 0x8900 // BT .+4 - && insn_ptr[12] == (insn_ptr[2] | 0x0018) // SHL[LR]8 Rshift - ) { - if (insn_ptr[13] == 0xC810 // TST #16, R0 - && insn_ptr[14] == 0x8900 // BT .+4 - && insn_ptr[15] == (insn_ptr[2] | 0x0028) // SHL[LR]16 Rshift - ) { - *max_ret = 31; - static const uint8_t cycles_array[32] = - {20,19,19,18,20,19,19,18,19,18,18,17,19,18,18,17, - 19,18,18,17,19,18,18,17,18,17,17,16,18,17,17,16}; - *cycles_ret = cycles_array; - return 16; - } else { - *max_ret = 15; - static const uint8_t cycles_array[16] = - {16,15,15,14,16,15,15,14,15,14,14,13,15,14,14,13}; - *cycles_ret = cycles_array; - return 13; - } - } else { - *max_ret = 7; - static const uint8_t cycles_array[8] = {12,11,11,10,12,11,11,10}; - *cycles_ret = cycles_array; - return 10; - } - } - - if ((insn_ptr[0] & 0xF0FF) == 0x0023 // BRAF Rcount_adjusted - && ((insn_ptr[2] & 0xF0DE) == 0x4000 // SH[LA][LR] Rshift - || (insn_ptr[2] & 0xF0FE) == 0x4004) // ROT[LR] Rshift - ) { - unsigned int num_insns = 3; - while (num_insns < 2+32 && insn_ptr[num_insns] == insn_ptr[2]) { - num_insns++; - } - *Rcount_ret = insn_ptr[0]>>8 & 0xF; - *Rshift_ret = insn_ptr[2]>>8 & 0xF; - *max_ret = num_insns - 2; - switch (insn_ptr[2] & 0xFF) { - case 0x00: *type_ret = 0; break; - case 0x20: *type_ret = 0; break; - case 0x01: *type_ret = 1; break; - case 0x21: *type_ret = 2; break; - case 0x04: *type_ret = 3; break; - case 0x05: *type_ret = 4; break; - } - return num_insns; - } - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -#endif // OPTIMIZE_VARIABLE_SHIFTS - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/sh2.c b/yabause/src/psp/sh2.c deleted file mode 100644 index 2eafcf17ca..0000000000 --- a/yabause/src/psp/sh2.c +++ /dev/null @@ -1,7714 +0,0 @@ -/* src/psp/sh2.c: SH-2 emulator with dynamic translation support - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/*************************************************************************/ - -/* - * This SH-2 emulator is designed to execute SH-2 instructions by - * recompiling them into equivalent native machine code instructions, then - * executing that native code directly on the host CPU. - * - * The emulation loop (handled by sh2_run()) proceeds as follows: - * - * 1) If there is no current native block, sh2_run() calls jit_translate() - * to translate a block of SH-2 code beginning at the current PC. - * jit_translate() continues translating through the end of the block - * (determined heuristically) and returns the translated block to be - * executed. - * - * 3A) sh2_run() calls jit_exec(), which in turn calls the native code for - * the current, found, or created translated block. - * - * 3B) If translation failed for some reason, sh2_run() calls - * interpret_insn() to interpret and execute one instruction at the - * current PC, then starts over at step 1. If the failure occurred - * during RTL code generation (i.e., after the SH-2 block size was - * determined), the entire block is blacklisted to avoid repeatedly - * trying to translate the block at each subsequent address. - * - * 4) The translated code returns either when it reaches the end of the - * block, or when the number of cycles executed exceeds the requested - * cycle count. (For efficiency, cycle count checks are only performed - * before backward branches.) - * - * 5A) If the new PC at the end of the translated block is cached as the - * predicted branch target of the block, the current native block is - * set to that block. - * - * 5B) Otherwise, if a translated block exists for the new PC, it is cached - * as the predicted branch target and the current native block is set - * to that block. - * - * 5C) Otherwise, the current native block is cleared. - * - * During native code execution, if a write is made to a region of SH-2 - * memory containing translated blocks, all translated blocks containing - * that address are deleted by calling jit_clear_write(), so the modified - * code can be retranslated. - * - * If an external agent (such as DMA) modifies memory, sh2_write_notify() - * should be called to clear any translations in the affected area. In - * this case, the modified range is expanded to a multiple of - * 1< 0 - /* Predicted dynamic branch target(s) */ - BranchTargetInfo predicted[JIT_BRANCH_PREDICTION_SLOTS]; -#endif - -#ifdef JIT_BRANCH_PREDICT_STATIC - /* Predicted static branch target(s) */ - BranchTargetInfo *static_predict; // Dynamically-allocated array - uint32_t num_static_branches; // Number of entries in array -#endif - -#ifdef JIT_PROFILE - uint32_t call_count; // Number of calls made to this block - uint32_t cycle_count; // Number of SH-2 cycles spent in this block - uint64_t exec_time; // Time spent executing this block (when - // interpreting RTL, # of insns executed) -#endif -}; - -/* Hash function */ -#define JIT_HASH(addr) ((uint32_t)(addr) % JIT_TABLE_SIZE) - -/*-----------------------------------------------------------------------*/ - -/* Hash table of translated routines (shared between virtual processors) */ -static JitEntry jit_table[JIT_TABLE_SIZE]; // Record buffer -static JitEntry *jit_hashchain[JIT_TABLE_SIZE]; // Hash collision chains - -/* Head node for circular linked list of free entries */ -static JitEntry jit_freelist; - -/* Head node for circular linked list of active entries sorted by add - * timestamp; used to quickly find the oldest (least recently added) entry - * when we need to purge entries due to a full table or the data size limit */ -static JitEntry jit_lralist; - -/* Total size of translated data */ -static int32_t jit_total_data; // Signed to protect against underflow from bugs - -/* Size limit for translated data */ -static int32_t jit_data_limit = JIT_DATA_LIMIT_DEFAULT; - -/* Global timestamp for LRU expiration mechanism */ -static uint32_t jit_timestamp; - -/* Address from which data is being read */ -static uint32_t jit_PC; - -/* Flags indicating the status of each word in the current block - * (0: unknown, else a combination of WORD_INFO_* flags) */ -static uint8_t word_info[JIT_INSNS_PER_BLOCK]; -#define WORD_INFO_CODE (1<<0) // 1: this is a code word -#define WORD_INFO_FALLTHRU (1<<1) // 1: branch at this address jumps to the - // next translated instruction -#define WORD_INFO_BRA_RTS (1<<2) // 1: branch at this address jumps to a - // RTS/NOP pair -#define WORD_INFO_THREADED (1<<3) // 1: branch at this address jumps to - // another branch -#define WORD_INFO_SELECT (1<<4) // 1: branch at this address acts like - // a SELECT -#define WORD_INFO_LOOP_JSR (1<<5) // 1: branch at this address targets a - // JSR/BSR/BSRF + delay slot - // immediately preceding the block -#define WORD_INFO_FOLDABLE (1<<6) // 1: BSR/JSR at this address jumps to - // a foldable subroutine - -/* Branch target flag array (indicates which words in the current block - * are targeted by branches within the same block) */ -static uint32_t is_branch_target[(JIT_INSNS_PER_BLOCK+31)/32]; - -/* Subroutine call target array (used for subroutine folding) */ -static uint32_t subroutine_target[JIT_INSNS_PER_BLOCK]; - -/* Native implementation function pointers for folded subroutines */ -static SH2NativeFunctionPointer subroutine_native[JIT_INSNS_PER_BLOCK]; - -/* Threaded branch target array (indicates targets for branches marked with - * WORD_INFO_THREADED) */ -static uint32_t branch_thread_target[JIT_INSNS_PER_BLOCK]; - -/* Branch count for each threaded branch (for updating the cycle count) */ -static uint8_t branch_thread_count[JIT_INSNS_PER_BLOCK]; - -/* Branch target lookup table (indicates where in the native code each - * address is located) */ -static struct { - uint32_t sh2_address; // Address of SH-2 instruction - uint32_t rtl_label; // RTL label number corresponding to instruction -} btcache[JIT_BTCACHE_SIZE]; -static unsigned int btcache_index; // Where to store the next branch target - -/* Unresolved branch list (saves locations and targets of forward branches) */ -static struct { - uint32_t sh2_target; // Branch target (SH-2 address, 0 = unused entry) - uint32_t target_label; // RTL label number to be defined at branch target -} unres_branches[JIT_UNRES_BRANCH_SIZE]; - -/* JIT translation blacklist; note that ranges are always 16-bit aligned */ -static struct { - uint32_t start, end; // Zero in both fields indicates an empty entry - uint32_t timestamp; // jit_timestamp when region was last written to - uint32_t pad; // Pad entry size to 16 bytes -} blacklist[JIT_BLACKLIST_SIZE]; - -/* Table of addresses that may require blacklisting if they cause repeated - * faults (see jit_clear_write()); we use the purge table constants for - * this table because they are used for similar purposes */ -static struct { - uint32_t address; // Access address address (0 = unused) - uint32_t timestamp; // jit_timestamp when entry was added/updated - uint32_t count; // Number of jit_clear_write() faults on this block -} pending_blacklist[JIT_PURGE_TABLE_SIZE]; - -/* JIT purge table */ -static struct { - uint32_t address; // Block starting address (0 = unused) - uint32_t timestamp; // jit_timestamp when entry was added/updated - uint32_t count; // Number of purges on this block -} purge_table[JIT_PURGE_TABLE_SIZE]; - -/*----------------------------------*/ - -/* Should we ignore optimization hints? (Used when checking for - * optimizable subroutines to be folded.) */ -static uint8_t ignore_optimization_hints; - -/*----------------------------------*/ - -/* True if we can optimize out the MAC saturation check in this block - * (i.e. S was clear on entry and has not been modified) */ -static uint8_t can_optimize_mac_nosat; - -/* True if the current block contains any MAC instructions */ -static uint8_t block_contains_mac; - -/*----------------------------------*/ - -/* Bitmask of registers hinted as having constant values on block entry */ -static uint16_t is_constant_entry_reg; - -/*----------------------------------*/ - -#ifdef OPTIMIZE_KNOWN_VALUES - -/* Known state of registers (used for optimization when recompiling) */ -static uint32_t reg_knownbits[17];// 1 in a bit means that bit's value is known -static uint32_t reg_value[17]; // Value of known bits in each register -#define REG_R(n) (n) -#define REG_GBR 16 -/* PC is always constant when translating, and the remaining registers are - * generally unknown, so we don't waste time tracking them. */ - -#endif // OPTIMIZE_KNOWN_VALUES - -/*----------------------------------*/ - -/* Status of each register when viewed as a load/store address */ - -static struct { - - /* - * Status of the register: - * known == 0: Value is not a translation-time constant. - * known != 0: Value is within a known memory region. - * known > 0: Value has not significantly changed since the start - * of the block. - * known < 0: Value has been copied from another register - * pointing to a known memory region, or has been - * loaded from local data. - */ - int8_t known; - - /* - * Nonzero if this register is known to point to only data, and - * therefore the JIT overwrite checks can be skipped. - */ - uint8_t data_only; - - /* - * Type of memory pointed to by the register: - * 1: Arranged by 8-bit bytes. - * 2: Arranged by native 16-bit words. - */ - uint8_t type; - - /* - * For known == 0 && rtl_basereg != 0 && !data_only, nonzero if the - * direct_jit_pages[] entry for this pointer has already been checked, - * else zero. - */ - uint8_t checked_djp; - - /* - * Nonzero if the "check_offset" field is valid. - */ - uint8_t checked; - - /* - * Last offset at which a JIT check was performed. - */ - int16_t check_offset; - - /* - * RTL register containing the base pointer for direct memory access, - * to which the register's value is added to form a native address for - * loads and stores. - * - * For known == 0: - * - rtl_basereg==0 means the register has not yet been used as a - * pointer, or its value has changed since the last such use. - * - rtl_basereg!=0 means the register has already been used as a - * pointer. If the RTL register's value is nonzero, it is a - * native pointer through which accesses can be performed - * directly; if the value is zero, the access must go through - * the fallback functions. - * - * For known != 0: - * - rtl_basereg==0 means the access must go through the fallback - * functions. - * - rtl_basereg!=0 means the access can be performed directly; the - * RTL register holds the base address to be added to the register - * value. - */ - uint16_t rtl_basereg; - - /* - * RTL register containing a native pointer for direct memory access - * (equal to rtl_basereg plus the register's value), or zero if no - * such register has yet been created. Only used if known != 0. - */ - uint16_t rtl_ptrreg; - - /* - * Base pointer for JIT page bitmap. Only used for statically-known, - * 16-bit, non-data pointers (known > 0 && type == 2 && !data_only). - */ - uint8_t *djp_base; - - /* - * Source address if this register was loaded from local data. - */ - uint32_t source; - -} pointer_status[16]; - -/* Register holding the native address corresponding to the stack pointer - * (R15) when SH2_OPTIMIZE_STACK is defined */ -static uint16_t stack_pointer; - -/* Bitmask of general-purpose registers containing values which could be - * pointers (used at scanning time to determine which registers need to be - * checked against the constant memory region used in optimization) */ -static uint16_t pointer_regs; -/* Bitmask of registers which are actually used to access memory */ -static uint16_t pointer_used; - -/* Bitmask of general-purpose registers containing local data addresses */ -static uint16_t pointer_local; - -/* Bitmask of general-purpose registers hinted to contain data pointers */ -static uint16_t is_data_pointer_reg; - -/* Array of flags indicating instructions which load data pointers - * (optimization hint) */ -static uint32_t is_data_pointer_load[(JIT_INSNS_PER_BLOCK+31)/32]; - -/*----------------------------------*/ - -#ifdef OPTIMIZE_STATE_BLOCK - -/* Array indicating which SH-2 state block fields are cached in RTL - * registers; if the rtlreg field is nonzero, the field should be accessed - * through that RTL register rather than being loaded from the state block. - * Indexed by the word offset into SH2State, i.e. offsetof(SH2State,REG) / 4 - * The index for a given structure offset can be found by calling - * state_cache_index(offsetof(...)), which returns -1 if the given field - * cannot be cached. */ -static struct { - uint32_t rtlreg; // RTL register containing the SH-2 reg's current value - int16_t offset; // Accumulated offset from constant additions (always - // zero if !OPTIMIZE_CONSTANT_ADDS) - uint8_t fixed; // Nonzero if we should always use this RTL register - // for this state field (rather than allocating a - // new register for each operation) - uint8_t flush; // Nonzero if we should always flush this cache - // register to memory during cache writeback - // (rather than only when it's marked dirty) -} state_cache[25], - saved_state_cache[25]; // Saved cache state (used by SAVE_STATE_CACHE()) - -/* Flags indicating whether a state block field is dirty (needs to be - * flushed); each bit corresponds to a state_cache[] index */ -static uint32_t state_dirty, saved_state_dirty; - -/* Register containing current value of SR.T, or 0 if none */ -static uint32_t cached_SR_T, saved_cached_SR_T; - -/* Nonzero if SR.T is dirty */ -static uint8_t dirty_SR_T, saved_dirty_SR_T; - -/* Cached known value of state->PC (overrides state_cache if nonzero) */ -static uint32_t cached_PC, saved_cached_PC; - -/* Last value actually stored to state->PC */ -static uint32_t stored_PC, saved_stored_PC; - -/* Function to convert a state block offset to a state_cache[] index */ -#ifdef __GNUC__ -__attribute__((const)) -#endif -static inline int state_cache_index(const uint32_t offset) { - if (offset < 25*4) { - return offset / 4; - } else { - return -1; - } -} - -/* Function to convert a state_cache[] index to a state block offset */ -#ifdef __GNUC__ -__attribute__((const)) -#endif -static inline uint32_t state_cache_field(const int index) { - return index * 4; -} - -#endif // OPTIMIZE_STATE_BLOCK - -/*----------------------------------*/ - -#ifdef OPTIMIZE_LOOP_REGISTERS - -/* Is this block a loop that can be optimized? */ -static uint8_t can_optimize_loop; - -/* Bitmask of registers live in the loop (indexed by state cache index) */ -static uint32_t loop_live_registers; - -/* Bitmask of registers whose initial values are used in the loop, and which - * therefore must be loaded ahead of time (indexed by state cache index) */ -static uint32_t loop_load_registers; - -/* Bitmask of registers changed in the loop (indexed by state cache index) */ -static uint32_t loop_changed_registers; - -/* Bitmask of registers which contain invariant pointers, i.e. pointers - * which are unchanged (or only offset by predecrement/postincrement - * addressing or ADD #imm) throughout the body of a loop */ -static uint32_t loop_invariant_pointers; - -#endif // OPTIMIZE_LOOP_REGISTERS - -/*-----------------------------------------------------------------------*/ - -#endif // ENABLE_JIT - -/*************************************************************************/ - -/* Local function declarations */ - -#ifdef ENABLE_JIT // Through the function declarations - -static JitEntry *jit_find(uint32_t address); -static NOINLINE JitEntry *jit_find_noinline(uint32_t address); - -static NOINLINE JitEntry *jit_translate(SH2State *state, uint32_t address); - -#if defined(PSP) && !defined(JIT_DEBUG_INTERPRET_RTL) -__attribute__((unused)) // We use custom assembly in this case -#endif -static inline void jit_exec(SH2State *state, JitEntry *entry); - -static FASTCALL void jit_clear_write(SH2State *state, uint32_t address); -static void jit_clear_range(uint32_t address, uint32_t size); -static void jit_clear_all(void); -static void jit_blacklist_range(uint32_t start, uint32_t end); - -static FASTCALL void jit_mark_purged(uint32_t address); -static int jit_check_purged(uint32_t address); - -#if JIT_BRANCH_PREDICTION_SLOTS > 0 -static NOINLINE JitEntry *jit_predict_branch(BranchTargetInfo *predicted, - const uint32_t target); -#endif - -#ifdef JIT_PROFILE -static NOINLINE void jit_print_profile(void); -#endif - -static NOINLINE void clear_entry(JitEntry *entry); -static void clear_oldest_entry(void); - -static inline void flush_native_cache(void *start, uint32_t length); - -__attribute__((const)) static inline int timestamp_compare( - uint32_t reference, uint32_t a, uint32_t b); - -/*----------------------------------*/ - -static int translate_block(SH2State *state, JitEntry *entry); -static int setup_pointers(SH2State * const state, JitEntry * const entry, - const unsigned int state_reg, - const int skip_preconditions, - unsigned int * const invalidate_label_ptr); - -static int scan_block(SH2State *state, JitEntry *entry, uint32_t address); -static inline void optimize_pointers( - uint32_t start_address, uint32_t address, unsigned int opcode, - uint32_t opcode_info, uint8_t pointer_map[16]); -static inline void optimize_pointers_mac( - uint32_t address, unsigned int opcode, uint8_t pointer_map[16], - uint32_t last_clrmac, int *stop_ret, int *rollback_ret); -#ifdef OPTIMIZE_LOOP_REGISTERS -static inline void check_loop_registers( - unsigned int opcode, uint32_t opcode_info); -#endif -#ifdef OPTIMIZE_BRANCH_SELECT -static inline int optimize_branch_select( - uint32_t start_address, uint32_t address, const uint16_t *fetch, - unsigned int opcode, uint32_t target); -#endif -static int optimize_fold_subroutine( - SH2State *state, const uint32_t start_address, uint32_t address, - const uint32_t target, const uint16_t delay_slot, uint8_t pointer_map[16], - uint32_t local_constant[16], SH2NativeFunctionPointer *native_ret); - -static int translate_insn(SH2State *state, JitEntry *entry, - unsigned int state_reg, int recursing, int is_last); -#ifdef JIT_BRANCH_PREDICT_STATIC -static int add_static_branch_terminator(JitEntry *entry, - unsigned int state_reg, - uint32_t address, unsigned int index); -#endif -#if JIT_BRANCH_PREDICTION_SLOTS > 0 -static FASTCALL JitEntry *update_branch_target(BranchTargetInfo *bti, - uint32_t address); -#endif - -/*----------------------------------*/ - -static uint32_t btcache_lookup(uint32_t address); -static int record_unresolved_branch(const JitEntry *entry, uint32_t sh2_target, - unsigned int target_label); - -static int writeback_state_cache(const JitEntry *entry, unsigned int state_reg, - int flush_fixed); -static void clear_state_cache(int clear_fixed); - -#endif // ENABLE_JIT - -/*-----------------------------------------------------------------------*/ - -/* Dummy, do-nothing callback function used as a default trace callback - * so that the caller doesn't have to check for a NULL function pointer */ -static void dummy_callback(void) {} - -/*************************************************************************/ -/********************** External interface routines **********************/ -/*************************************************************************/ - -/** - * sh2_init: Initialize the SH-2 core. Must be called before creating any - * virtual processors. - * - * [Parameters] - * None - * [Return value] - * Nonzero on success, zero on error - */ -int sh2_init(void) -{ - /* Set up the opcode information tables */ - init_opcode_info(); - - /* Default to no optimizations; let the caller decide what to enable */ - optimization_flags = 0; - - /* Set the dummy callback function in the trace callback pointers */ - trace_insn_callback = (SH2TraceInsnCallback *)dummy_callback; - trace_storeb_callback = (SH2TraceAccessCallback *)dummy_callback; - trace_storew_callback = (SH2TraceAccessCallback *)dummy_callback; - trace_storel_callback = (SH2TraceAccessCallback *)dummy_callback; - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_set_optimizations, sh2_get_optimizations: Set or retrieve the - * bitmask of currently-enabled optional optimizations, as defined by the - * SH2_OPTIMIZE_* constants. - * - * [Parameters] - * flags: Bitmask of optimizations to enable (sh2_set_optimizations() only) - * [Return value] - * Bitmask of enabled optimizations (sh2_get_optimizations() only) - */ -void sh2_set_optimizations(uint32_t flags) -{ - if (flags != optimization_flags) { -#ifdef ENABLE_JIT - jit_clear_all(); -#endif - optimization_flags = flags; - if (!(optimization_flags & SH2_OPTIMIZE_LOCAL_ACCESSES)) { - optimization_flags &= ~SH2_OPTIMIZE_LOCAL_POINTERS; - } - if (!(optimization_flags & SH2_OPTIMIZE_POINTERS)) { - optimization_flags &= ~SH2_OPTIMIZE_LOCAL_POINTERS; - optimization_flags &= ~SH2_OPTIMIZE_POINTERS_MAC; - } - } -} - -uint32_t sh2_get_optimizations(void) -{ - return optimization_flags; -} - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_set_jit_data_limit: Set the limit on the total size of translated - * code, in bytes of native code (or bytes of RTL data when using the RTL - * interpreter). Does nothing if dynamic translation is disabled. - * - * [Parameters] - * limit: Total JIT data size limit - * [Return value] - * None - */ -void sh2_set_jit_data_limit(uint32_t limit) -{ -#ifdef ENABLE_JIT - jit_data_limit = limit; -#endif -} - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_set_manual_optimization_callback: Set a callback function to be - * called when beginning to analyze a new block of SH-2 code. If the - * function returns nonzero, it is assumed to have translated a block - * starting at the given address into an optimized RTL instruction stream, - * and the normal block analysis and translation is skipped. - * - * [Parameters] - * funcptr: Callback function pointer (NULL to unset a previously-set - * function) - * [Return value] - * None - */ -void sh2_set_manual_optimization_callback(SH2OptimizeCallback *funcptr) -{ - manual_optimization_callback = funcptr; -} - -/*----------------------------------*/ - -/** - * sh2_set_cache_flush_callback: Set a callback function to be called when - * a range of addresses should be flushed from the native CPU's caches. - * This is called in preparation for executing a newly-translated block of - * code, so the given range must be flushed from both data and instruction - * caches. - * - * [Parameters] - * funcptr: Callback function pointer (NULL to unset a previously-set - * function) - * [Return value] - * None - */ -void sh2_set_cache_flush_callback(SH2CacheFlushCallback *funcptr) -{ - cache_flush_callback = funcptr; -} - -/*----------------------------------*/ - -/** - * sh2_set_invalid_opcode_callback: Set a callback function to be called - * when the SH-2 decoder encounters an invalid instruction. - * - * [Parameters] - * funcptr: Callback function pointer (NULL to unset a previously-set - * function) - * [Return value] - * None - */ -void sh2_set_invalid_opcode_callback(SH2InvalidOpcodeCallback *funcptr) -{ - invalid_opcode_callback = funcptr; -} - -/*----------------------------------*/ - -/** - * sh2_set_trace_insn_callback: Set a callback function to be used for - * tracing instructions as they are executed. The function is only called - * if tracing is enabled in the SH-2 core. - * - * [Parameters] - * funcptr: Callback function pointer (NULL to unset a previously-set - * function) - * [Return value] - * None - */ -void sh2_set_trace_insn_callback(SH2TraceInsnCallback *funcptr) -{ - trace_insn_callback = - funcptr ? funcptr : (SH2TraceInsnCallback *)dummy_callback; -} - -/*----------------------------------*/ - -/** - * sh2_set_trace_store[bwl]_callback: Set a callback function to be used - * for tracing 1-, 2-, or 4-byte write accesses, respectively. The - * function is only called if tracing is enabled in the SH-2 core. - * - * [Parameters] - * funcptr: Callback function pointer (NULL to unset a previously-set - * function) - * [Return value] - * None - */ -void sh2_set_trace_storeb_callback(SH2TraceAccessCallback *funcptr) -{ - trace_storeb_callback = - funcptr ? funcptr : (SH2TraceAccessCallback *)dummy_callback; -} - -void sh2_set_trace_storew_callback(SH2TraceAccessCallback *funcptr) -{ - trace_storew_callback = - funcptr ? funcptr : (SH2TraceAccessCallback *)dummy_callback; -} - -void sh2_set_trace_storel_callback(SH2TraceAccessCallback *funcptr) -{ - trace_storel_callback = - funcptr ? funcptr : (SH2TraceAccessCallback *)dummy_callback; -} - - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_alloc_direct_write_buffer: Allocate a buffer which can be passed - * as the write_buffer parameter to sh2_set_direct_access(). The buffer - * should be freed with free() when no longer needed, but no earlier than - * calling sh2_destroy() for all active virtual processors. - * - * [Parameters] - * size: Size of SH-2 address region to be marked as directly accessible - * [Return value] - * Buffer pointer, or NULL on error - */ -void *sh2_alloc_direct_write_buffer(uint32_t size) -{ - const uint32_t bufsize = - (size + ((1<> JIT_PAGE_BITS; - void *buffer = calloc(bufsize, 1); - if (UNLIKELY(!buffer)) { - DMSG("Failed to get 0x%X-byte buffer for 0x%X-byte region", - bufsize, size); - return NULL; - } - return buffer; -} - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_set_direct_access: Mark a region of memory as being directly - * accessible. The data format of the memory region is assumed to be - * sequential 16-bit words in native order. - * - * As memory is internally divided into 512k (2^19) byte pages, both - * sh2_address and size must be aligned to a multiple of 2^19. - * - * Passing a NULL parameter for native_address causes the region to be - * marked as not directly accessible. - * - * [Parameters] - * sh2_address: Base address of region in SH-2 address space - * native_address: Pointer to memory block in native address space - * size: Size of memory block, in bytes - * readable: Nonzero if region is readable, zero if execute-only - * write_buffer: Buffer for checking writes to this region (allocated - * with sh2_alloc_direct_write_buffer()), or NULL to - * indicate that the region is read- or execute-only - * [Return value] - * None - */ -void sh2_set_direct_access(uint32_t sh2_address, void *native_address, - uint32_t size, int readable, void *write_buffer) -{ -#ifdef ENABLE_JIT - if (UNLIKELY(((sh2_address | size) & ((1<<19)-1)) != 0)) { - DMSG("sh2_address (0x%08X) and size (0x%X) must be aligned to a" - " 19-bit page", sh2_address, size); - return; - } - - const unsigned int first_page = sh2_address >> 19; - const unsigned int last_page = ((sh2_address + size) >> 19) - 1; - if (native_address) { - void * const target = - (void *)((uintptr_t)native_address - (first_page << 19)); - void * const jit_target = write_buffer - ? (void *)((uintptr_t)write_buffer - - (first_page << (19 - JIT_PAGE_BITS))) - : NULL; - unsigned int page; - for (page = first_page; page <= last_page; page++) { - fetch_pages[page] = target; - direct_pages[page] = readable ? target : NULL; - direct_jit_pages[page] = jit_target; - } - } else { - unsigned int page; - for (page = first_page; page <= last_page; page++) { - fetch_pages[page] = NULL; - direct_pages[page] = NULL; - direct_jit_pages[page] = NULL; - } - } -#endif // ENABLE_JIT -} - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_set_byte_direct_access: Mark a region of memory as being directly - * accessible in 8-bit units. - * - * As memory is internally divided into 512k (2^19) byte pages, both - * sh2_address and size must be aligned to a multiple of 2^19. - * - * Passing a NULL parameter for native_address causes the region to be - * marked as not directly accessible. - * - * [Parameters] - * sh2_address: Base address of region in SH-2 address space - * native_address: Pointer to memory block in native address space - * size: Size of memory block, in bytes - * [Return value] - * None - */ -void sh2_set_byte_direct_access(uint32_t sh2_address, void *native_address, - uint32_t size) -{ -#ifdef ENABLE_JIT - if (UNLIKELY(((sh2_address | size) & ((1<<19)-1)) != 0)) { - DMSG("sh2_address (0x%08X) and size (0x%X) must be aligned to a" - " 19-bit page", sh2_address, size); - return; - } - - const unsigned int first_page = sh2_address >> 19; - const unsigned int last_page = ((sh2_address + size) >> 19) - 1; - if (native_address) { - void * const target = - (void *)((uintptr_t)native_address - (first_page << 19)); - unsigned int page; - for (page = first_page; page <= last_page; page++) { - byte_direct_pages[page] = target; - } - } else { - unsigned int page; - for (page = first_page; page <= last_page; page++) { - byte_direct_pages[page] = NULL; - } - } -#endif // ENABLE_JIT -} - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_optimize_hint_data_pointer_load: Provide a hint to the optimizer - * that the load or ALU instruction at the given address loads a pointer to - * a 16-bit direct-access data region. If pointer optimization (the - * SH2_OPTIMIZE_POINTERS flag) is enabled, accesses through the register so - * loaded will automatically use direct access to SH-2 memory, and will - * bypass the code overwrite checks normally executed for store operations. - * If pointer optimization is disabled, this hint has no effect. - * - * The effect of calling this function from any context other than within - * the manual optimization callback, or of specifying an instruction other - * than MOVA which does not set the register specified by the Rn field of - * the opcode, is undefined. - * - * [Parameters] - * state: Processor state block pointer passed to callback function - * address: Address of load instruction to mark as loading a data pointer - * [Return value] - * None - */ -void sh2_optimize_hint_data_pointer_load(SH2State *state, uint32_t address) -{ - PRECOND(state != NULL, return); - PRECOND(state->translate_entry != NULL, return); - -#ifdef ENABLE_JIT - - if (ignore_optimization_hints) { - return; - } - if (!(optimization_flags & SH2_OPTIMIZE_POINTERS)) { - return; - } - - if (address >= state->translate_entry->sh2_start) { - const unsigned int insn_index = - (address - state->translate_entry->sh2_start) / 2; - if (insn_index < lenof(is_data_pointer_load) * 32) { - is_data_pointer_load[insn_index / 32] |= 1 << (insn_index % 32); - } - } - -#endif // ENABLE_JIT -} - -/*----------------------------------*/ - -/** - * sh2_optimize_hint_data_pointer_register: Provide a hint to the - * optimizer that the given general-purpose register (R0 through R15) - * contains a pointer to a direct-access data region at the start of the - * block, and the memory region pointed to will not change over the life - * of the block. If pointer optimization (the SH2_OPTIMIZE_POINTERS flag) - * is enabled, accesses through that register (as long as the register's - * value is unchanged) will automatically use direct access to SH-2 memory, - * and will bypass the code overwrite checks normally executed for store - * operations; furthermore, the register's value will not be verified for - * address validity at block start time, unlike dynamically-detected - * pointers which are verified each time the block is called. If pointer - * optimization is disabled, this hint has no effect. - * - * The effect of calling this function from any context other than within - * the manual optimization callback is undefined. - * - * [Parameters] - * state: Processor state block pointer passed to callback function - * regnum: General-purpose register to mark as containing a data pointer - * [Return value] - * None - */ -void sh2_optimize_hint_data_pointer_register(SH2State *state, - unsigned int regnum) -{ - PRECOND(state != NULL, return); - PRECOND(state->translate_entry != NULL, return); - PRECOND(regnum < 16, return); - -#ifdef ENABLE_JIT - - if (ignore_optimization_hints) { - return; - } - if (!(optimization_flags & SH2_OPTIMIZE_POINTERS)) { - return; - } - - is_data_pointer_reg |= 1 << regnum; - -#endif // ENABLE_JIT -} - -/*----------------------------------*/ - -/** - * sh2_optimize_hint_constant_register: Provide a hint to the optimizer - * that the given general-purpose register (R0 through R15) contains a - * value which will be constant at block entry for the life of the block. - * Instructions which use the register as a source operand may be optimized - * to use the constant value rather than loading the register, and if - * subroutine folding (the SH2_OPTIMIZE_FOLD_SUBROUTINES flag) is enabled, - * JSRs through that register will be considered for subroutine folding - * using the address contained in that register at translation time. - * - * The effect of calling this function from any context other than within - * the manual optimization callback is undefined. - * - * [Parameters] - * state: Processor state block pointer passed to callback function - * regnum: General-purpose register to mark as containing a data pointer - * [Return value] - * None - */ -void sh2_optimize_hint_constant_register(SH2State *state, unsigned int regnum) -{ - PRECOND(state != NULL, return); - PRECOND(state->translate_entry != NULL, return); - PRECOND(regnum < 16, return); - -#ifdef ENABLE_JIT - - if (ignore_optimization_hints) { - return; - } - - is_constant_entry_reg |= 1 << regnum; - -#endif // ENABLE_JIT -} - -/*************************************************************************/ - -/** - * sh2_create: Create a new virtual SH-2 processor. - * - * [Parameters] - * None - * [Return value] - * SH-2 processor state block (NULL on error) - */ -SH2State *sh2_create(void) -{ - SH2State *state; - - state = malloc(sizeof(*state)); - if (!state) { - DMSG("Out of memory allocating state block"); - goto error_return; - } - state->next = state_list; - state_list = state; - - /* Allocate interrupt stack */ - state->interrupt_stack = - malloc(sizeof(*state->interrupt_stack) * INTERRUPT_STACK_SIZE); - if (!state->interrupt_stack) { - DMSG("Out of memory allocating interrupt stack"); - goto error_free_state; - } - - return state; - - error_free_state: - free(state); - error_return: - return NULL; -} - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_destroy: Destroy a virtual SH-2 processor. - * - * [Parameters] - * state: SH-2 processor state block - * [Return value] - * None - */ -void sh2_destroy(SH2State *state) -{ - if (!state) { - return; - } - - SH2State **prev_ptr; - for (prev_ptr = &state_list; *prev_ptr; prev_ptr = &((*prev_ptr)->next)) { - if ((*prev_ptr) == state) { - break; - } - } - if (!*prev_ptr) { - DMSG("%p not found in state list", state); - return; - } - (*prev_ptr) = state->next; - - free(state->interrupt_stack); - free(state); -} - -/*-----------------------------------------------------------------------*/ - -/** - * sh2_reset: Reset a virtual SH-2 processor. - * - * [Parameters] - * state: SH-2 processor state block - * [Return value] - * None - */ -void sh2_reset(SH2State *state) -{ - state->delay = 0; - state->asleep = 0; - state->need_interrupt_check = 0; - state->interrupt_stack_top = 0; - state->current_entry = NULL; - state->branch_type = SH2BRTYPE_NONE; - state->folding_subroutine = 0; - state->pending_select = 0; - state->just_branched = 0; - state->cached_shift_count = 0; - state->varshift_target_PC = 0; - state->division_target_PC = 0; - -#ifdef ENABLE_JIT - memset(blacklist, 0, sizeof(blacklist)); - memset(pending_blacklist, 0, sizeof(pending_blacklist)); - memset(purge_table, 0, sizeof(purge_table)); - jit_clear_all(); - jit_timestamp = 0; -#endif -} - -/*************************************************************************/ - -/** - * sh2_run: Execute instructions for the given number of clock cycles. - * - * [Parameters] - * state: SH-2 processor state block - * cycles: Number of clock cycles to execute - * [Return value] - * None - */ -#ifdef PSP -__attribute__((aligned(64))) -#endif -void sh2_run(SH2State *state, uint32_t cycles) -{ - /* Update the JIT timestamp counter once per call */ - jit_timestamp++; - - /* Save this in the state block for use by translated code */ - state->cycle_limit = cycles; - - /* Check for interrupts before we start executing (this will wake up - * the processor if necessary) */ - if (UNLIKELY(check_interrupts(state))) { -#ifdef ENABLE_JIT - state->current_entry = jit_find(state->PC); -#endif - } - - /* If the processor is sleeping, consume all remaining cycles */ - if (UNLIKELY(state->asleep)) { - state->cycles = state->cycle_limit; - return; - } - - /* In TRACE_LITE (but not TRACE_LITE_VERBOSE) mode, trace a single - * instruction at the current PC before we start executing */ -#if defined(TRACE_LITE) && !defined(TRACE_LITE_VERBOSE) - (*trace_insn_callback)(state, state->PC); -#endif - - /* Load this for faster access during the loop */ - JitEntry *current_entry = state->current_entry; - - /* Loop until we've consumed the requested number of execution cycles. - * There's no need to check state->delay here, because it's handled - * either at translation time or by interpret_insn() call. */ - - const uint32_t cycle_limit = state->cycle_limit; - -#if !defined(ENABLE_JIT) - - while (state->cycles < cycle_limit) { - interpret_insn(state); - } - -#else // ENABLE_JIT - -# if defined(PSP) && !defined(JIT_DEBUG_INTERPRET_RTL) - - /* GCC's optimizer fails horribly on this loop, so we have no choice - * but to write it ourselves. */ - -# ifdef JIT_PROFILE - uint32_t start_cycles, start; // As in jit_exec() -# endif - - asm(".set push; .set noreorder\n" - - "lw $t0, %[cycles](%[state])\n" - "beqz %[current_entry], 5f\n" - "sltu $v0, $t0, %[cycle_limit]\n" - /* In the non-trace, non-profile case, this NOP aligns the top of - * the loop to a 64-byte (cache-line) boundary, so that the quick- - * predict critical path fits within a single cache line. This - * provides a noticeable (sometimes >5%) boost to performance. */ - "nop\n" - - // Loop top, quick restart point (jit_translate() call is at the end) - "1:\n" - "beqz $v0, 9f\n" - - // Resume point after block translation - "2:\n" -# ifdef TRACE_LITE_VERBOSE - "move $a0, %[state]\n" - "jalr %[trace_insn_callback]\n" - "lw $a1, %[PC](%[state])\n" -# endif - - // jit_exec(state, current_entry); -# ifdef JIT_PROFILE -# ifndef TRACE_LITE_VERBOSE - "nop\n" // Fill branch delay slot from above -# endif - "jal sceKernelGetSystemTimeLow\n" - "lw %[start_cycles], %[cycles](%[state])\n" - "move %[start], $v0\n" -# endif - - "lw $v0, %[native_code](%[current_entry])\n" - "li $v1, 1\n" - "sb $v1, %[running](%[current_entry])\n" - "jalr $v0\n" - "move $a0, %[state]\n" - -# ifdef JIT_PROFILE - "jal sceKernelGetSystemTimeLow\n" - "nop\n" - "lw $v1, %[cycles](%[state])\n" - "lw $a0, %[call_count](%[current_entry])\n" - "lw $a1, %[cycle_count](%[current_entry])\n" - "lw $a2, %[exec_time](%[current_entry])\n" - "lw $a3, %[exec_time]+4(%[current_entry])\n" - "addiu $a0, $a0, 1\n" - "subu $v1, $v1, %[start_cycles]\n" - "addu $a1, $a1, $v1\n" - "subu $v0, $v0, %[start]\n" - "addu $v0, $a2, $v0\n" - "sltu $v1, $v0, $a2\n" - "addu $a3, $a3, $v1\n" - "sw $a0, %[call_count](%[current_entry])\n" - "sw $a1, %[cycle_count](%[current_entry])\n" - "sw $v0, %[exec_time](%[current_entry])\n" - "sw $a3, %[exec_time]+4(%[current_entry])\n" -# endif - - // Preload data used below - "lbu $v0, %[must_clear](%[current_entry])\n" - "lw $t0, %[cycles](%[state])\n" -# if JIT_BRANCH_PREDICTION_SLOTS > 0 - "lw $a1, %[PC](%[state])\n" - "lw $t1, %[predicted_target](%[current_entry])\n" -# endif - - // Clear current_entry->running and check must_clear - "bnez $v0, 8f\n" - "sb $zero, %[running](%[current_entry])\n" - -# if JIT_BRANCH_PREDICTION_SLOTS > 0 - // Check for a quickly-predicted branch - "sltu $v0, $t0, %[cycle_limit]\n" - "beql $a1, $t1, 1b\n" - "lw %[current_entry], %[predicted_entry](%[current_entry])\n" - // Otherwise call jit_predict_branch() to get the next block - "jal %[jit_predict_branch]\n" - "addiu $a0, %[current_entry], %[predicted]\n" -# else - // Branch prediction is disabled, so just look up a block manually - "jal %[jit_find_noinline]\n" - "lw $a0, %[PC](%[state])\n" -# endif - // Loop back if we found a block, else translate it - "3:\n" - "lw $t0, %[cycles](%[state])\n" - "4:\n" - "move %[current_entry], $v0\n" - "bnez %[current_entry], 1b\n" - "sltu $v0, $t0, %[cycle_limit]\n" - - // Cycle check and jit_translate() call for not-found blocks - "5:\n" - "beqz $v0, 9f\n" - "move $a0, %[state]\n" - "6:\n" - "jal %[jit_translate]\n" - "lw $a1, %[PC](%[state])\n" - "bnez $v0, 2b\n" - "move %[current_entry], $v0\n" - - // interpret_insn() call for translation failure - "jal interpret_insn\n" - "move $a0, %[state]\n" - "jal %[jit_find_noinline]\n" - "lw $a0, %[PC](%[state])\n" - "b 4b\n" - "lw $t0, %[cycles](%[state])\n" - - // clear_entry() and jit_find_noinline() for purged blocks - "8:\n" - "jal %[clear_entry]\n" - "move $a0, %[current_entry]\n" - "jal %[jit_find_noinline]\n" - "lw $a0, %[PC](%[state])\n" - "b 4b\n" - "lw $t0, %[cycles](%[state])\n" - - // End of loop - "9:\n" - ".set pop" - : [current_entry] "=r" (current_entry), -# ifdef JIT_PROFILE - [start_cycles] "=&r" (start_cycles), - [start] "=&r" (start), -# endif - "=m" (*state) - : [state] "r" (state), [cycle_limit] "r" (cycle_limit), - "0" (current_entry), -# ifdef TRACE_LITE_VERBOSE - [trace_insn_callback] "r" (trace_insn_callback), -# endif - [PC] "i" (offsetof(SH2State,PC)), - [cycles] "i" (offsetof(SH2State,cycles)), - [native_code] "i" (offsetof(JitEntry,native_code)), - [running] "i" (offsetof(JitEntry,running)), - [must_clear] "i" (offsetof(JitEntry,must_clear)), -# if JIT_BRANCH_PREDICTION_SLOTS > 0 - [predicted] "i" (offsetof(JitEntry,predicted)), - [predicted_target] "i" (offsetof(JitEntry,predicted[0].target)), - [predicted_entry] "i" (offsetof(JitEntry,predicted[0].entry)), -# endif -# ifdef JIT_PROFILE - [call_count] "i" (offsetof(JitEntry,call_count)), - [cycle_count] "i" (offsetof(JitEntry,cycle_count)), - [exec_time] "i" (offsetof(JitEntry,exec_time)), -# endif -# if JIT_BRANCH_PREDICTION_SLOTS > 0 - [jit_predict_branch] "S" (jit_predict_branch), -# endif - [jit_translate] "S" (jit_translate), - [clear_entry] "S" (clear_entry), - [jit_find_noinline] "S" (jit_find_noinline) - : "v0", "v1", "a0", "a1", "a2", "a3", "t0", "t1", - "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "ra" - ); - -# else // !(PSP && !JIT_DEBUG_INTERPRET_RTL) - - while (state->cycles < cycle_limit) { - - /* If we don't have a current native code block, translate from - * the current address */ - if (UNLIKELY(!current_entry)) { - current_entry = jit_translate(state, state->PC); - } - - /* If we (now) have a native code block, execute from it */ - if (LIKELY(current_entry)) { - quick_restart:; - -# ifdef TRACE_LITE_VERBOSE - (*trace_insn_callback)(state, state->PC); -# endif - jit_exec(state, current_entry); - -# if JIT_BRANCH_PREDICTION_SLOTS > 0 - const uint32_t new_PC = state->PC; - BranchTargetInfo * const predicted = ¤t_entry->predicted[0]; - - if (UNLIKELY(current_entry->must_clear)) { - /* A purge was requested, so clear the just-executed entry */ - clear_entry(current_entry); - current_entry = jit_find_noinline(new_PC); - continue; - } - - /* Even if we're using multiple prediction slots, handle the - * first one specially for increased speed if it's a correct - * prediction; we make the safe (for all practical purposes) - * assumption that the target PC is not zero */ - if (new_PC == predicted->target) { - current_entry = predicted->entry; - if (LIKELY(state->cycles < cycle_limit)) { - goto quick_restart; - } - } else { - current_entry = jit_predict_branch(predicted, new_PC); - } -# else // branch prediction disabled - if (UNLIKELY(current_entry->must_clear)) { - clear_entry(current_entry); - } - current_entry = jit_find_noinline(state->PC); -# endif - - } else { // !current_entry - - /* We couldn't translate the code at this address, so interpret - * it instead */ - interpret_insn(state); - - } // if (current_entry) - - } // while (state->cycles < cycle_limit) - -# endif // PSP && !JIT_DEBUG_INTERPRET_RTL -#endif // ENABLE_JIT - - state->current_entry = current_entry; - -#if defined(ENABLE_JIT) && defined(JIT_PROFILE) - static int cycles_for_profile; - cycles_for_profile += state->cycle_limit; - if (cycles_for_profile >= JIT_PROFILE_INTERVAL) { - cycles_for_profile = 0; - jit_print_profile(); - } // if (cycles_for_profile >= JIT_PROFILE_INTERVAL) -#endif // ENABLE_JIT && JIT_PROFILE -} - -/*************************************************************************/ - -/** - * sh2_signal_interrupt: Signal an interrupt to a virtual SH-2 processor. - * The interrupt is ignored if another interrupt on the same vector has - * already been signalled. - * - * [Parameters] - * state: SH-2 processor state block - * vector: Interrupt vector (0-127) - * level: Interrupt level (0-15, or 16 for NMI) - * [Return value] - * None - */ -void sh2_signal_interrupt(SH2State *state, unsigned int vector, - unsigned int level) -{ - int i; - - if (UNLIKELY(state->interrupt_stack_top >= INTERRUPT_STACK_SIZE)) { - DMSG("WARNING: dropped interrupt <%u,%u> due to full stack", - vector, level); - DMSG("Interrupt stack:"); - for (i = state->interrupt_stack_top - 1; i >= 0; i--) { - DMSG(" <%3u,%2u>", state->interrupt_stack[i].vector, - state->interrupt_stack[i].level); - } - return; - } - - for (i = 0; i < state->interrupt_stack_top; i++) { - if (state->interrupt_stack[i].vector == vector) { - return; // This interrupt is already raised - } - } - - for (i = 0; i < state->interrupt_stack_top; i++) { - if (state->interrupt_stack[i].level > level) { - memmove(&state->interrupt_stack[i+1], &state->interrupt_stack[i], - sizeof(*state->interrupt_stack) - * (state->interrupt_stack_top - i)); - break; - } - } - state->interrupt_stack[i].level = level; - state->interrupt_stack[i].vector = vector; - state->interrupt_stack_top++; -} - -/*************************************************************************/ - -/** - * sh2_write_notify: Called when an external agent modifies memory. - * Used here to clear any JIT translations in the modified range. - * - * [Parameters] - * address: Beginning of address range to which data was written - * size: Size of address range to which data was written (in bytes) - * [Return value] - * None - */ -void sh2_write_notify(uint32_t address, uint32_t size) -{ -#ifdef ENABLE_JIT - jit_clear_range(address, size); -#endif -} - -/*************************************************************************/ -/******************** General-purpose local routines *********************/ -/*************************************************************************/ - -/** - * check_interrupts: Check whether there are any pending interrupts, and - * service the highest-priority one if so. - * - * [Parameters] - * state: Processor state block - * [Return value] - * Nonzero if an interrupt was serviced, else zero - * [Notes] - * This routine is exported for use by sh2-interpret.c. - */ -FASTCALL int check_interrupts(SH2State *state) -{ - if (state->interrupt_stack_top > 0) { - const int level = - state->interrupt_stack[state->interrupt_stack_top-1].level; - if (level > ((state->SR & SR_I) >> SR_I_SHIFT)) { - const int vector = - state->interrupt_stack[state->interrupt_stack_top-1].vector; - state->R[15] -= 4; -#if defined(TRACE) || defined(TRACE_STEALTH) - (*trace_storel_callback)(state->R[15], state->SR); -#endif - MappedMemoryWriteLong(state->R[15], state->SR); - state->R[15] -= 4; -#if defined(TRACE) || defined(TRACE_STEALTH) - (*trace_storel_callback)(state->R[15], state->PC); -#endif - MappedMemoryWriteLong(state->R[15], state->PC); - state->SR &= ~SR_I; - state->SR |= level << SR_I_SHIFT; - state->PC = MappedMemoryReadLong(state->VBR + (vector << 2)); - state->asleep = 0; - state->interrupt_stack_top--; - return 1; - } - } - return 0; -} - -/*************************************************************************/ -/**************** Dynamic translation management routines ****************/ -/*************************************************************************/ - -#ifdef ENABLE_JIT // Through the end of the file - -/*************************************************************************/ - -/** - * jit_find, jit_find_noinline: Find the translated block for a given - * address, if any. jit_find_noinline() is explicitly marked NOINLINE to - * minimize register pressure when called from sh2_run(). - * - * [Parameters] - * address: Start address in SH-2 address space - * [Return value] - * Translated block, or NULL if no such block exists - */ -static JitEntry *jit_find(uint32_t address) -{ - const int hashval = JIT_HASH(address); - JitEntry *entry = jit_hashchain[hashval]; - while (entry) { - if (entry->sh2_start == address) { - return entry; - } - entry = entry->next; - } - return NULL; -} - -static NOINLINE JitEntry *jit_find_noinline(uint32_t address) -{ - return jit_find(address); -} - -/*************************************************************************/ - -/** - * jit_translate: Dynamically translate a block of instructions starting - * at the given address. If a translation already exists for the given - * address, it is cleared. - * - * [Parameters] - * state: SH-2 processor state block - * address: Start address in SH-2 address space - * [Return value] - * Translated block, or NULL on error - */ -static NOINLINE JitEntry *jit_translate(SH2State *state, uint32_t address) -{ - JitEntry *entry; - int index; - -#ifdef PSP_TIME_TRANSLATION - static uint32_t total, count; - const uint32_t a = sceKernelGetSystemTimeLow(); -#endif - - /* Update the timestamp on every call */ - jit_timestamp++; - - /* First check for untranslatable addresses */ - if (UNLIKELY(address == 0)) { - /* We use address 0 to indicate an unused entry, so we can't - * translate from address 0. But this should never happen except - * in pathological cases (or unhandled exceptions), so just punt - * and let the interpreter handle it. */ - return NULL; - } - if (UNLIKELY(address & 1)) { - /* Odd addresses are invalid, so we can't translate them in the - * first place. */ - return NULL; - } - if (UNLIKELY(!fetch_pages[address >> 19])) { - /* Don't try to translate anything from non-directly-accessible - * memory, since we can't track changes to such memory. */ - return NULL; - } - - /* Check whether the starting address is blacklisted */ - for (index = 0; index < lenof(blacklist); index++) { - uint32_t age = jit_timestamp - blacklist[index].timestamp; - if (age >= JIT_BLACKLIST_EXPIRE) { - /* Entry expired, so clear it */ - blacklist[index].start = blacklist[index].end = 0; - continue; - } - if (blacklist[index].start <= address - && address <= blacklist[index].end) { - return NULL; - } - } - - /* Clear out any existing translation; if we've reached the data size - * limit, also evict old entries until we're back under the limit */ - if ((entry = jit_find(address)) != NULL) { - clear_entry(entry); - } - if (UNLIKELY(jit_total_data >= jit_data_limit)) { -#ifdef JIT_DEBUG - DMSG("JIT data size over limit (%u >= %u), clearing entries", - jit_total_data, jit_data_limit); -#endif - while (jit_total_data >= jit_data_limit) { - clear_oldest_entry(); - } - } - - /* Obtain a free entry for this block */ - if (jit_freelist.next == &jit_freelist) { - /* No free entries, so clear the oldest one and use it */ -#ifdef JIT_DEBUG - DMSG("No free slots for code at 0x%08X, clearing oldest", address); -#endif - clear_oldest_entry(); - if (UNLIKELY(jit_freelist.next == &jit_freelist)) { // paranoia - DMSG("BUG: failed to update free list"); - return 0; - } - } - entry = jit_freelist.next; - jit_freelist.next = entry->next; - jit_freelist.next->prev = &jit_freelist; - - /* Store the entry pointer in the state block, for reference by other - * functions */ - state->translate_entry = entry; - - /* Initialize the new entry */ - entry->rtl = rtl_create_block(); - if (!entry->rtl) { - DMSG("No memory for code at 0x%08X", address); - goto fail; - } - const int hashval = JIT_HASH(address); - entry->next = jit_hashchain[hashval]; - if (entry->next) { - entry->next->prev = entry; - } - jit_hashchain[hashval] = entry; - entry->prev = NULL; - entry->lra_next = &jit_lralist; - entry->lra_prev = jit_lralist.lra_prev; - entry->lra_next->lra_prev = entry; - entry->lra_prev->lra_next = entry; - entry->pred_ref_head.next = &entry->pred_ref_head; - entry->pred_ref_head.prev = &entry->pred_ref_head; - entry->sh2_start = address; - entry->sh2_end = 0; - entry->native_code = NULL; - entry->native_length = 0; - entry->timestamp = jit_timestamp; - entry->running = 0; - entry->must_clear = 0; -#if JIT_BRANCH_PREDICTION_SLOTS > 0 - for (index = 0; index < JIT_BRANCH_PREDICTION_SLOTS; index++) { - entry->predicted[index].target = 0; - entry->predicted[index].entry = NULL; - entry->predicted[index].next = NULL; - entry->predicted[index].prev = NULL; - } -#endif -#ifdef JIT_BRANCH_PREDICT_STATIC - entry->static_predict = NULL; - entry->num_static_branches = 0; -#endif -#ifdef JIT_PROFILE - entry->call_count = 0; - entry->cycle_count = 0; - entry->exec_time = 0; -#endif - - /* Perform the SH-2 -> RTL translation */ - if (UNLIKELY(!translate_block(state, entry))) { - DMSG("Failed to translate block at 0x%08X", address); - /* If we found a valid end address for the block, blacklist the - * entire block so we don't waste time trying to translate from - * every successive instruction. Otherwise, just blacklist the - * first address in case we come back here again. */ - if (entry->sh2_end) { - jit_blacklist_range(address, entry->sh2_end); - } else { - jit_blacklist_range(address, address+1); - } - goto clear_and_fail; - } - - /* Translate from RTL to native code */ -#ifndef JIT_DEBUG_INTERPRET_RTL - if (UNLIKELY(!rtl_translate_block(entry->rtl, &entry->native_code, - &entry->native_length))) { - DMSG("Failed to translate block at 0x%08X", entry->sh2_start); - goto clear_and_fail; - } - /* Make sure the new code isn't masked by cached data */ - flush_native_cache(entry->native_code, entry->native_length); - rtl_destroy_block(entry->rtl); - entry->rtl = NULL; -#endif - - /* Update JIT management data */ - uint8_t *jit_base = direct_jit_pages[entry->sh2_start >> 19]; - if (jit_base) { - for (index = entry->sh2_start >> JIT_PAGE_BITS; - index <= entry->sh2_end >> JIT_PAGE_BITS; - index++ - ) { - JIT_PAGE_SET(jit_base, index); - } - } -#ifdef JIT_DEBUG_INTERPRET_RTL - /* Guesstimate how much memory was used (including the insn-to-unit LUT - * later allocated by rtl_execute_block()); we assume average ratios of - * 5:8 insns:regs, and 1:8 insns:units (we don't bother with labels - * since they only require 2 bytes each and are generally less than 10% - * of insns). */ - entry->native_length = ((sizeof(RTLInsn)+2) - + sizeof(RTLRegister)*5/8 - + sizeof(RTLUnit)/8) * entry->rtl->insns_size - + sizeof(RTLBlock); -#endif - jit_total_data += entry->native_length; - -#ifdef PSP_TIME_TRANSLATION - const uint32_t b = sceKernelGetSystemTimeLow(); - total += b-a; - count += ((current_entry->sh2_end + 1) - current_entry->sh2_start) / 2; - DMSG("%u/%u = %.3f us/insn", total, count, (float)total/count); -#endif - - /* All done */ - state->translate_entry = NULL; - return entry; - - /* Error handling */ - clear_and_fail: - clear_entry(entry); - fail: - state->translate_entry = NULL; - return NULL; -} - -/*************************************************************************/ - -/** - * jit_clear_write: Clear any translation which includes the given - * address. Intended to be called from within translated code. - * - * [Parameters] - * state: Processor state block - * address: Address to which data was written - * [Return value] - * None - */ -static FASTCALL void jit_clear_write(SH2State *state, uint32_t address) -{ - int index; - - /* If it's a blacklisted address, we don't need to do anything (since - * the address couldn't have been translated); just update the entry's - * write timestamp and return */ - for (index = 0; index < lenof(blacklist); index++) { - if (blacklist[index].start <= address - && address <= blacklist[index].end) { - blacklist[index].timestamp = jit_timestamp; - return; - } - } - -#ifdef JIT_DEBUG - DMSG("WARNING: jit_clear_write(0x%08X) from PC %08X", address, state->PC); -#endif - - /* Clear any translations on the affected page */ - uint8_t * const jit_base = direct_jit_pages[address >> 19]; - const uint32_t page = address >> JIT_PAGE_BITS; - const uint32_t page_start = address & -(1 << JIT_PAGE_BITS); - const uint32_t page_end = page_start + ((1 << JIT_PAGE_BITS) - 1); - JIT_PAGE_CLEAR(jit_base, page); - int found_entry = 0; // Flag: Did we find a block on this page? - int do_blacklist = 0; // Flag: Blacklist this address? - for (index = 0; index < JIT_TABLE_SIZE; index++) { - if (jit_table[index].sh2_start == 0) { - continue; - } - if (jit_table[index].sh2_start <= page_end - && jit_table[index].sh2_end >= page_start - ) { - found_entry = 1; - if (UNLIKELY(jit_table[index].running)) { - jit_table[index].must_clear = 1; - do_blacklist = 1; - } else { - clear_entry(&jit_table[index]); - } - } - } - - /* If we fault on the same address multiple times in rapid succession, - * blacklist the address even if it wasn't in a running block. (We - * don't blacklist this case on the first fault because it could just - * be overwriting a block of memory with new code.) */ - if (found_entry && !do_blacklist) { - int empty = -1; - unsigned int oldest = 0; - for (index = 0; index < lenof(pending_blacklist); index++) { - if (pending_blacklist[index].address == address) { - if (jit_timestamp - pending_blacklist[index].timestamp - > JIT_PURGE_EXPIRE - ) { - pending_blacklist[index].count = 0; - } - break; - } else if (pending_blacklist[index].address != 0) { - if (pending_blacklist[index].timestamp - < pending_blacklist[oldest].timestamp - ) { - oldest = index; - } - } else if (empty < 0) { - empty = index; - } - } - if (index >= lenof(pending_blacklist)) { - if (empty >= 0) { - index = empty; - } else { - index = oldest; - } - pending_blacklist[index].address = address; - pending_blacklist[index].count = 0; - } - pending_blacklist[index].timestamp = jit_timestamp; - pending_blacklist[index].count++; - if (pending_blacklist[index].count >= JIT_PURGE_THRESHOLD) { -#ifdef JIT_DEBUG - DMSG("Blacklisting 0x%08X due to repeated faults",address); -#endif - do_blacklist = 1; - } - } - - /* Blacklist this address if appropriate. We always keep the blacklist - * entries 16-bit-aligned; since we don't pass the write size in, we - * assume the write is 32-bit-sized if on a 32-bit-aligned address, and - * 16-bit-sized otherwise. */ - if (do_blacklist) { - const uint32_t start = address & ~1; - const uint32_t end = (address & ~3) + 3; - jit_blacklist_range(start, end); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * jit_clear_range: Clear any translation on any page touched by the given - * range of addresses. Intended to be called when an external agent - * modifies memory. - * - * [Parameters] - * address: Beginning of address range to which data was written - * size: Size of address range to which data was written (in bytes) - * [Return value] - * None - */ -static void jit_clear_range(uint32_t address, uint32_t size) -{ - const uint32_t first_page = address >> JIT_PAGE_BITS; - const uint32_t last_page = (address + size - 1) >> JIT_PAGE_BITS; - const uint32_t page_start = first_page << JIT_PAGE_BITS; - const uint32_t page_end = ((last_page+1) << JIT_PAGE_BITS) - 1; - - int page; - for (page = first_page; page <= last_page; page++) { - if (direct_jit_pages[page >> (19-JIT_PAGE_BITS)]) { - JIT_PAGE_CLEAR(direct_jit_pages[page >> (19-JIT_PAGE_BITS)], page); - } - } - - int index; - for (index = 0; index < JIT_TABLE_SIZE; index++) { - if (jit_table[index].sh2_start == 0) { - continue; - } - if (jit_table[index].sh2_start <= page_end - && jit_table[index].sh2_end >= page_start - ) { - clear_entry(&jit_table[index]); - } - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * jit_clear_all: Clear all translations. Intended to be used when - * initializing/resetting the processor or when a change in optimization - * options invalidates existing translations. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void jit_clear_all(void) -{ - int index; - - /* Clear all JIT bitmaps */ - for (index = 0; index < lenof(direct_jit_pages); index++) { - if (direct_jit_pages[index]) { - uintptr_t address = (uintptr_t)direct_jit_pages[index]; - address += index << (19 - JIT_PAGE_BITS); - memset((void *)address, 0, (1<<19) >> JIT_PAGE_BITS); - } - } - - /* Clear all entry data (don't call clear_entry() to avoid wasting time - * updating management data for every single entry) */ - for (index = 0; index < JIT_TABLE_SIZE; index++) { - if (jit_table[index].sh2_start) { - free(jit_table[index].native_code); - jit_table[index].native_code = NULL; - rtl_destroy_block(jit_table[index].rtl); - jit_table[index].rtl = NULL; -#ifdef JIT_BRANCH_PREDICT_STATIC - free(jit_table[index].static_predict); - jit_table[index].static_predict = NULL; -#endif - jit_table[index].sh2_start = 0; - } - jit_table[index].timestamp = 0; - } - for (index = 0; index < JIT_TABLE_SIZE; index++) { - jit_hashchain[index] = NULL; - } - - /* Put every entry in the free list */ - jit_freelist.next = &jit_table[0]; - jit_table[0].prev = &jit_freelist; - for (index = 1; index < JIT_TABLE_SIZE; index++) { - jit_table[index-1].next = &jit_table[index]; - jit_table[index].prev = &jit_table[index-1]; - } - jit_table[JIT_TABLE_SIZE-1].next = &jit_freelist; - jit_freelist.prev = &jit_table[JIT_TABLE_SIZE-1]; - - /* Clear other management data */ - jit_lralist.lra_next = &jit_lralist; - jit_lralist.lra_prev = &jit_lralist; - jit_total_data = 0; - SH2State *state; - for (state = state_list; state; state = state->next) { - state->current_entry = NULL; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * jit_blacklist_range: Add the specified range to the JIT blacklist. - * - * [Parameters] - * start: First byte in range to blacklist - * end: Last byte in range to blacklist - * [Return value] - * None - */ -static void jit_blacklist_range(uint32_t start, uint32_t end) -{ - unsigned int index; - - /* Merge this to the beginning or end of another entry if possible */ - for (index = 0; index < lenof(blacklist); index++) { - if (blacklist[index].start == end+1) { - blacklist[index].start = start; - /* See if there's another one we can join to this one */ - unsigned int index2; - for (index2 = 0; index2 < lenof(blacklist); index2++) { - if (start == blacklist[index2].end+1) { - blacklist[index].start = blacklist[index2].start; - blacklist[index2].start = blacklist[index2].end = 0; - break; - } - } - goto entry_added; - } else if (blacklist[index].end+1 == start) { - blacklist[index].end = end; - unsigned int index2; - for (index2 = 0; index2 < lenof(blacklist); index2++) { - if (end+1 == blacklist[index2].start) { - blacklist[index].end = blacklist[index2].end; - blacklist[index2].start = blacklist[index2].end = 0; - break; - } - } - goto entry_added; - } - } - - /* We didn't find an entry to merge this into, so allocate a new one */ - for (index = 0; index < lenof(blacklist); index++) { - if (!blacklist[index].start && !blacklist[index].end) { - break; - } - } - - /* If the table is full, purge the oldest entry */ - if (index >= lenof(blacklist)) { - unsigned int oldest = 0; - for (index = 1; index < lenof(blacklist); index++) { - if (timestamp_compare(jit_timestamp, - blacklist[index].timestamp, - blacklist[oldest].timestamp) < 0) { - oldest = index; - } - } -#ifdef JIT_DEBUG - DMSG("Blacklist full, purging entry %d (0x%X-0x%X)", - oldest, blacklist[oldest].start, blacklist[oldest].end); -#endif - index = oldest; - } - - /* Fill in the new entry */ - blacklist[index].start = start; - blacklist[index].end = end; - entry_added: - blacklist[index].timestamp = jit_timestamp; -} - -/*************************************************************************/ - -/** - * jit_mark_purged: Mark the given block as purged due to precondition - * failure. - * - * [Parameters] - * address: Block starting address - * [Return value] - * None - */ -static FASTCALL void jit_mark_purged(uint32_t address) -{ - unsigned int i; - unsigned int oldest = 0; // Oldest entry (which will be overwritten) - unsigned int oldest_age = 0; // Age of purge_table[oldest] - -#ifdef JIT_DEBUG - DMSG("WARNING: Purging block 0x%08X", address); -#endif - - for (i = 0; i < lenof(purge_table); i++) { - const uint32_t age = jit_timestamp - purge_table[i].timestamp; - if (!purge_table[i].address) { - /* Empty entry, so treat it as the oldest one for overwriting */ - oldest = i; - oldest_age = JIT_PURGE_EXPIRE; - } else if (age >= JIT_PURGE_EXPIRE) { - /* Entry has expired, so clear it out */ - purge_table[i].address = 0; - oldest = i; - oldest_age = JIT_PURGE_EXPIRE; - } else if (purge_table[i].address == address) { - /* If this block is already in the list (and not expired), - * increment its purge counter and stop immediately */ - purge_table[i].timestamp = jit_timestamp; - purge_table[i].count++; - return; - } else if (age > oldest_age) { - /* If this is the oldest entry in the table, we'll overwrite it */ - oldest = i; - oldest_age = age; - } - } - - /* We didn't find the entry in the table, so overwrite the oldest slot - * (which may be an empty slot) with this block's information */ - purge_table[oldest].address = address; - purge_table[oldest].timestamp = jit_timestamp; - purge_table[oldest].count = 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * jit_check_purged: Check whether the given block has been purged often - * enough to require disabling optimizations with preconditions. - * - * [Parameters] - * address: Block starting address - * [Return value] - * Nonzero if relevant optimizations should be disabled, else zero - */ -static int jit_check_purged(uint32_t address) -{ - unsigned int i; - - for (i = 0; i < lenof(purge_table); i++) { - if (purge_table[i].address == address) { - const uint32_t age = jit_timestamp - purge_table[i].timestamp; - if (age >= JIT_PURGE_EXPIRE) { - purge_table[i].address = 0; - return 0; - } else { - return purge_table[i].count >= JIT_PURGE_THRESHOLD; - } - } - } - - return 0; -} - -/*************************************************************************/ - -#if JIT_BRANCH_PREDICTION_SLOTS > 0 - -/** - * jit_predict_branch: Attempt to predict a branch to "target" using the - * prediction array "predicted", and update the prediction table as - * appropriate. Helper function for sh2_run(), called after the first - * prediction table entry has been checked. - * - * [Parameters] - * target: Target SH-2 address - * predicted: JitEntry.predicted array from current translated block - * [Return value] - * Translated block for target address, or NULL if none was found - */ -static NOINLINE JitEntry *jit_predict_branch(BranchTargetInfo *predicted, - const uint32_t target) -{ -# if JIT_BRANCH_PREDICTION_SLOTS > 1 - /* First see if it's in any slot other than the first */ - unsigned int i; - for (i = 1; i < JIT_BRANCH_PREDICTION_SLOTS; i++) { - if (predicted[i].target != 0 && target == predicted[i].target) { - JitEntry *result = predicted[i].entry; -# ifdef JIT_BRANCH_PREDICTION_FLOAT - /* Shift it up to the previous slot so we can find it faster next - * time. If we have any code that alternates between two branch - * targets, we're going to take a major performance hit... */ - BranchTargetInfo *this_next = predicted[i].next; - BranchTargetInfo *this_prev = predicted[i].prev; - uint32_t this_target = predicted[i].target; - JitEntry *this_entry = predicted[i].entry; - predicted[i].target = predicted[i-1].target; - predicted[i].entry = predicted[i-1].entry; - if (predicted[i].entry) { - predicted[i].next = predicted[i-1].next; - predicted[i].prev = predicted[i-1].prev; - predicted[i].next->prev = &predicted[i]; - predicted[i].prev->next = &predicted[i]; - } - predicted[i-1].next = this_next; - predicted[i-1].prev = this_prev; - predicted[i-1].target = this_target; - predicted[i-1].entry = this_entry; - this_next->prev = &predicted[i-1]; - this_prev->next = &predicted[i-1]; -# endif // JIT_BRANCH_PREDICTION_FLOAT - return result; - } - } - /* Update the first empty slot, or the last slot if none are empty */ - for (i = 0; i < JIT_BRANCH_PREDICTION_SLOTS-1; i++) { - if (predicted[i].target == 0) { - break; - } - } - return update_branch_target(&predicted[i], target); -# else // JIT_BRANCH_PREDICTION_SLOTS == 1 - return update_branch_target(predicted, target); -# endif -} - -#endif // JIT_BRANCH_PREDICTION_SLOTS > 0 - -/*************************************************************************/ - -#ifdef JIT_PROFILE - -/** - * jit_print_profile: Print profiling statistics for translated code. - * - * [Parameters] - * None - * [Return value] - * None - */ -static NOINLINE void jit_print_profile(void) -{ - int top[JIT_PROFILE_TOP]; - unsigned int i; - - printf("\n"); - - printf("================= Top callees by time: =================\n"); - memset(top, -1, sizeof(top)); - for (i = 0; i < lenof(jit_table); i++) { - if (!jit_table[i].sh2_start) { - continue; - } - unsigned int j; - for (j = 0; j < lenof(top); j++) { - if (top[j] < 0 - || jit_table[i].exec_time > jit_table[top[j]].exec_time - ) { - unsigned int k; - for (k = lenof(top)-1; k > j; k--) { - top[k] = top[k-1]; - } - top[j] = i; - break; - } - } - } - printf( -# ifdef JIT_DEBUG_INTERPRET_RTL - "RTL insns" -# else - "Exec time" -# endif - " SH2 cyc. Native/SH2 # calls Block addr\n"); - printf("--------- -------- ---------- ------- ----------\n"); - for (i = 0; i < lenof(top) && top[i] >= 0; i++) { - printf("%9lld %10d %12.3f %9d 0x%08X\n", - (unsigned long long)jit_table[top[i]].exec_time, - jit_table[top[i]].cycle_count, - (double)jit_table[top[i]].exec_time - / (double)jit_table[top[i]].cycle_count, - jit_table[top[i]].call_count, - jit_table[top[i]].sh2_start); - } - printf("========================================================\n"); - - - printf("============== Top callees by call count: ==============\n"); - memset(top, -1, sizeof(top)); - for (i = 0; i < lenof(jit_table); i++) { - if (!jit_table[i].sh2_start) { - continue; - } - unsigned int j; - for (j = 0; j < lenof(top); j++) { - if (top[j] < 0 - || jit_table[i].call_count > jit_table[top[j]].call_count - ) { - unsigned int k; - for (k = lenof(top)-1; k > j; k--) { - top[k] = top[k-1]; - } - top[j] = i; - break; - } - } - } - printf( -# ifdef JIT_DEBUG_INTERPRET_RTL - "RTL insns" -# else - "Exec time" -# endif - " SH2 cyc. Native/SH2 # calls Block addr\n"); - printf("--------- -------- ---------- ------- ----------\n"); - for (i = 0; i < lenof(top) && top[i] >= 0; i++) { - printf("%9lld %10d %12.3f %9d 0x%08X\n", - (unsigned long long)jit_table[top[i]].exec_time, - jit_table[top[i]].cycle_count, - (double)jit_table[top[i]].exec_time - / (double)jit_table[top[i]].cycle_count, - jit_table[top[i]].call_count, - jit_table[top[i]].sh2_start); - } - printf("========================================================\n"); - - for (i = 0; i < lenof(jit_table); i++) { - jit_table[i].call_count = 0; - jit_table[i].cycle_count = 0; - jit_table[i].exec_time = 0; - } - -} - -#endif // JIT_PROFILE - -/*************************************************************************/ -/***************** Dynamic translation utility routines ******************/ -/*************************************************************************/ - -/** - * clear_entry: Clear a specific entry from the JIT table, freeing the - * native code buffer and unlinking the entry from its references. - * - * [Parameters] - * entry: JitEntry structure pointer - * [Return value] - * None - */ -static NOINLINE void clear_entry(JitEntry *entry) -{ - PRECOND(entry != NULL, return); - - /* Make sure the non-active processor isn't trying to use this entry - * (if so, clear it out) */ - SH2State *state; - for (state = state_list; state; state = state->next) { - if (state->current_entry == entry) { - state->current_entry = NULL; - } - } - - /* Free the native code, if any */ - jit_total_data -= entry->native_length; - free(entry->native_code); - entry->native_code = NULL; - - /* Free the RTL block, if any */ - rtl_destroy_block(entry->rtl); - entry->rtl = NULL; - - /* Clear the entry from the predicted branch target of any entries - * referencing it */ - BranchTargetInfo *referrer, *next; - for (referrer = entry->pred_ref_head.next; - referrer != &entry->pred_ref_head; - referrer = next - ) { - next = referrer->next; - referrer->target = 0; - referrer->entry = NULL; - referrer->next = NULL; - referrer->prev = NULL; - } - entry->pred_ref_head.next = &entry->pred_ref_head; - entry->pred_ref_head.prev = &entry->pred_ref_head; - - /* Remove this entry from the reference list of any branch it predicts */ -#if JIT_BRANCH_PREDICTION_SLOTS > 0 - unsigned int i; - for (i = 0; i < JIT_BRANCH_PREDICTION_SLOTS; i++) { - if (entry->predicted[i].entry) { - entry->predicted[i].next->prev = entry->predicted[i].prev; - entry->predicted[i].prev->next = entry->predicted[i].next; - } - } -#endif -#ifdef JIT_BRANCH_PREDICT_STATIC - for (i = 0; i < entry->num_static_branches; i++) { - if (entry->static_predict[i].entry) { - entry->static_predict[i].next->prev = entry->static_predict[i].prev; - entry->static_predict[i].prev->next = entry->static_predict[i].next; - } - } - free(entry->static_predict); - entry->static_predict = NULL; - jit_total_data -= - entry->num_static_branches * sizeof(*entry->static_predict); -#endif - - /* Clear the entry from the hash chain and LRA list */ - if (entry->next) { - entry->next->prev = entry->prev; - } - if (entry->prev) { - entry->prev->next = entry->next; - } else { - jit_hashchain[JIT_HASH(entry->sh2_start)] = entry->next; - } - entry->lra_next->lra_prev = entry->lra_prev; - entry->lra_prev->lra_next = entry->lra_next; - - /* Mark the entry as free */ - entry->sh2_start = 0; - - /* Insert the entry into the free list */ - entry->next = jit_freelist.next; - entry->prev = &jit_freelist; - entry->next->prev = entry; - jit_freelist.next = entry; -} - -/*-----------------------------------------------------------------------*/ - -/** - * clear_oldest_entry: Clear the oldest entry from the JIT table. - * - * [Parameters] - * None - * [Return value] - * None - */ -static void clear_oldest_entry(void) -{ - JitEntry *oldest = jit_lralist.lra_next; - if (LIKELY(oldest != &jit_lralist)) { -#ifdef JIT_DEBUG - DMSG("Clearing oldest entry 0x%08X (age %u)", - oldest->sh2_start, jit_timestamp - oldest->timestamp); -#endif - clear_entry(oldest); - } else { -#ifdef JIT_DEBUG - DMSG("Tried to clear oldest entry from an empty table!"); -#endif - /* We don't call this function unless there's something we need to - * clear out, so if we come here, our internal tables may be - * corrupt. Reset everything to be safe. */ - jit_total_data = 0; - } -} - -/*************************************************************************/ - -/** - * flush_native_cache: Flush a range of addresses from the native CPU's - * caches. - * - * [Parameters] - * start: Pointer to start of range - * length: Length of range in bytes - * [Return value] - * None - */ -static inline void flush_native_cache(void *start, uint32_t length) -{ - if (cache_flush_callback) { - (*cache_flush_callback)(start, length); - } -} - -/*************************************************************************/ - -/** - * timestamp_compare: Compare two timestamps. - * - * [Parameters] - * a, b: Timestamps to compare - * reference: Reference timestamp by which the comparison is made - * [Return value] - * -1 if a < b (i.e. "a is older than b") - * 0 if a == b - * 1 if a > b - */ -__attribute__((const)) static inline int timestamp_compare( - uint32_t reference, uint32_t a, uint32_t b) -{ - const uint32_t age_a = reference - a; - const uint32_t age_b = reference - b; - return age_a > age_b ? -1 : - age_a < age_b ? 1 : 0; -} - -/*************************************************************************/ -/****************** Macros for SH-2 -> RTL translation *******************/ -/*************************************************************************/ - -/* Constants used in SH-2 memory access operations */ -#define SH2_ACCESS_TYPE_B 0 // 1-byte access (signed for loads) -#define SH2_ACCESS_TYPE_W 1 // 2-byte access (signed for loads) -#define SH2_ACCESS_TYPE_L 2 // 4-byte access - -/* Return the "high" (pointer register) and "low" (load/store offset) parts - * of an address for generating optimal native load/store code */ -#ifdef __mips__ -# define ADDR_HI(address) (((uintptr_t)(address) + 0x8000) & 0xFFFF0000) -# define ADDR_LO(address) ((int16_t)((uintptr_t)(address) & 0xFFFF)) -#else -# define ADDR_HI(address) ((uintptr_t)address) -# define ADDR_LO(address) 0 -#endif - -/*-----------------------------------------------------------------------*/ - -/* Basic macro to pass a failure (zero) return value up the call chain */ -#define ASSERT(expr) do { \ - if (UNLIKELY(!(expr))) { \ - return 0; \ - } \ -} while (0) - -/* Basic macro to append an RTL instruction, aborting on error */ -#define APPEND(opcode,dest,src1,src2,other) \ - ASSERT(rtl_add_insn(entry->rtl, RTLOP_##opcode, \ - (dest), (src1), (src2), (other))); - -/*-----------------------------------------------------------------------*/ - -/* Declare a register identifier, but don't allocate a new register for it */ -#define DECLARE_REG(name) uint32_t name - -/* Allocate a register for a declared identifier */ -#define ALLOC_REG(name) ASSERT(name = rtl_alloc_register(entry->rtl)) - -/* Define a new register (equivalent to DECLARE_REG followed by ALLOC_REG) */ -#define DEFINE_REG(name) \ - const uint32_t name = rtl_alloc_register(entry->rtl); \ - if (UNLIKELY(!name)) { \ - return 0; \ - } - -/*-----------------------------------------------------------------------*/ - -/* Register-register operations */ - -#define MOVE(dest,src) APPEND(MOVE, (dest), (src), 0, 0) -#define SELECT(dest,src1,src2,cond) \ - APPEND(SELECT, (dest), (src1), (src2), (cond)) -#define ADD(dest,src1,src2) APPEND(ADD, (dest), (src1), (src2), 0) -#define SUB(dest,src1,src2) APPEND(SUB, (dest), (src1), (src2), 0) -#define MUL(dest,src1,src2) APPEND(MULU, (dest), (src1), (src2), 0) -#define MULU_64(dest,src1,src2,dest_hi) \ - APPEND(MULU, (dest), (src1), (src2), (dest_hi)) -#define MULS_64(dest,src1,src2,dest_hi) \ - APPEND(MULS, (dest), (src1), (src2), (dest_hi)) -#define MADDU_64(dest,src1,src2,dest_hi) \ - APPEND(MADDU, (dest), (src1), (src2), (dest_hi)) -#define MADDS_64(dest,src1,src2,dest_hi) \ - APPEND(MADDS, (dest), (src1), (src2), (dest_hi)) -#define DIVMODU(dest,src1,src2,rem) \ - APPEND(DIVMODU, (dest), (src1), (src2), (rem)) -#define DIVMODS(dest,src1,src2,rem) \ - APPEND(DIVMODS, (dest), (src1), (src2), (rem)) -#define AND(dest,src1,src2) APPEND(AND, (dest), (src1), (src2), 0) -#define OR(dest,src1,src2) APPEND(OR, (dest), (src1), (src2), 0) -#define XOR(dest,src1,src2) APPEND(XOR, (dest), (src1), (src2), 0) -#define NOT(dest,src) APPEND(NOT, (dest), (src), 0, 0) -#define SLL(dest,src1,src2) APPEND(SLL, (dest), (src1), (src2), 0) -#define SRL(dest,src1,src2) APPEND(SRL, (dest), (src1), (src2), 0) -#define SRA(dest,src1,src2) APPEND(SRA, (dest), (src1), (src2), 0) -#define ROR(dest,src1,src2) APPEND(SRL, (dest), (src1), (src2), 0) -#define CLZ(dest,src) APPEND(CLZ, (dest), (src), 0, 0) -#define CLO(dest,src) APPEND(CLO, (dest), (src), 0, 0) -#define SLTU(dest,src1,src2) APPEND(SLTU, (dest), (src1), (src2), 0) -#define SLTS(dest,src1,src2) APPEND(SLTS, (dest), (src1), (src2), 0) -#define BSWAPH(dest,src) APPEND(BSWAPH, (dest), (src), 0, 0) -#define BSWAPW(dest,src) APPEND(BSWAPW, (dest), (src), 0, 0) -#define HSWAPW(dest,src) APPEND(HSWAPW, (dest), (src), 0, 0) - -/*----------------------------------*/ - -/* Register-immediate operations */ - -#define MOVEI(dest,imm) APPEND(LOAD_IMM, (dest), (imm), 0, 0) -#define MOVEA(dest,addr) APPEND(LOAD_ADDR, (dest), \ - (uintptr_t)(addr), 0, 0) -#ifdef JIT_USE_RTL_REGIMM -# define IMMOP(op,dest,src,imm) APPEND(op##I, (dest), (src), (imm), 0) -#else -# define IMMOP(op,dest,src,imm) do { DEFINE_REG(__immreg); \ - APPEND(LOAD_IMM, __immreg, (imm), 0, 0); \ - APPEND(op, (dest), (src), __immreg, 0); \ - } while (0) -#endif -#define ADDI(dest,src,imm) IMMOP(ADD, (dest), (src), (imm)) -#define SUBI(dest,src,imm) IMMOP(ADD, (dest), (src), -(imm)) -#define ANDI(dest,src,imm) IMMOP(AND, (dest), (src), (imm)) -#define ORI(dest,src,imm) IMMOP(OR, (dest), (src), (imm)) -#define XORI(dest,src,imm) IMMOP(XOR, (dest), (src), (imm)) -#define SLLI(dest,src,imm) IMMOP(SLL, (dest), (src), (imm)) -#define SRLI(dest,src,imm) IMMOP(SRL, (dest), (src), (imm)) -#define SRAI(dest,src,imm) IMMOP(SRA, (dest), (src), (imm)) -#define RORI(dest,src,imm) IMMOP(ROR, (dest), (src), (imm)) -#define SLTUI(dest,src,imm) IMMOP(SLTU, (dest), (src), (imm)) -#define SLTSI(dest,src,imm) IMMOP(SLTS, (dest), (src), (imm)) - -/*----------------------------------*/ - -/* Bitfield instructions */ - -#ifdef JIT_USE_RTL_BITFIELDS -# define BFOP(op,dest,src1,src2,start,count) \ - APPEND(BF##op, (dest), (src1), (src2), (start) | (count)<<8) -# define BFEXT(dest,src,start,count) \ - BFOP(EXT, (dest), (src), 0, (start), (count)) -# define BFINS(dest,src1,src2,start,count) \ - BFOP(INS, (dest), (src1), (src2), (start), (count)) -#else -# define BFEXT(dest,src,start,count) do { \ - const uint32_t __dest = (dest); \ - const uint32_t __src = (src); \ - const int __start = (start); \ - const int __count = (count); \ - if (__start == 0) { \ - if (__count == 32) { \ - MOVE(__dest, __src); \ - } else { \ - ANDI(__dest, __src, (1U<<__count) - 1); \ - } \ - } else if (__start + __count == 32) { \ - SRLI(__dest, __src, __start); \ - } else { \ - DEFINE_REG(__temp); \ - SRLI(__temp, __src, (start)); \ - ANDI(__dest, __temp, (1U<<__count) - 1); \ - } \ -} while (0) -# define BFINS(dest,src1,src2,start,count) do { \ - const uint32_t __dest = (dest); \ - const uint32_t __src1 = (src1); \ - const uint32_t __src2 = (src2); \ - const int __start = (start); \ - const int __count = (count); \ - if (__start == 0 && __count == 32) { \ - MOVE(__dest, __src2); \ - } else { \ - const uint32_t __mask = (1U<<__count) - 1; \ - DEFINE_REG(__out2); \ - if (__start == 0) { \ - ANDI(__out2, __src2, __mask); \ - } else { \ - DEFINE_REG(__temp); \ - ANDI(__temp, __src2, __mask); \ - SLLI(__out2, __temp, __start); \ - } \ - DEFINE_REG(__out1); \ - ANDI(__out1, __src1, ~(__mask << __start)); \ - OR(__dest, __out1, __out2); \ - } \ -} while (0) -#endif - -/*----------------------------------*/ - -/* Variants of SLT */ - -#define SEQZ(dest,src) SLTUI((dest), (src), 1) -#define SLTZ(dest,src) SLTSI((dest), (src), 0) - -/*----------------------------------*/ - -/* Load from or store to memory */ - -#define LOAD_BU(dest,address,offset) \ - APPEND(LOAD_BU, (dest), (address), 0, (offset)) -#define LOAD_BS(dest,address,offset) \ - APPEND(LOAD_BS, (dest), (address), 0, (offset)) -#define LOAD_HU(dest,address,offset) \ - APPEND(LOAD_HU, (dest), (address), 0, (offset)) -#define LOAD_HS(dest,address,offset) \ - APPEND(LOAD_HS, (dest), (address), 0, (offset)) -#define LOAD_W(dest,address,offset) \ - APPEND(LOAD_W, (dest), (address), 0, (offset)) -#define LOAD_PTR(dest,address,offset) \ - APPEND(LOAD_PTR, (dest), (address), 0, (offset)) -#define STORE_B(address,src,offset) \ - APPEND(STORE_B, (address), (src), 0, (offset)) -#define STORE_H(address,src,offset) \ - APPEND(STORE_H, (address), (src), 0, (offset)) -#define STORE_W(address,src,offset) \ - APPEND(STORE_W, (address), (src), 0, (offset)) -#define STORE_PTR(address,src,offset) \ - APPEND(STORE_PTR, (address), (src), 0, (offset)) - -/*----------------------------------*/ - -/* Load from, store to, or add constants to state block fields */ - -/* Loads */ - -#define LOAD_STATE(reg,field) \ - ASSERT(__LOAD_STATE(entry, state_reg, (reg), offsetof(SH2State,field))) -static inline int __LOAD_STATE(const JitEntry * const entry, - const uint32_t state_reg, - const uint32_t reg, const uint32_t offset) -{ -#ifdef OPTIMIZE_STATE_BLOCK - const int index = state_cache_index(offset); - if (index >= 0) { - if (state_cache[index].rtlreg) { - if (reg == state_cache[index].rtlreg) { - if (state_cache[index].offset) { - ADDI(state_cache[index].rtlreg, state_cache[index].rtlreg, - state_cache[index].offset); - if (index == 15 && stack_pointer) { - ADDI(stack_pointer, stack_pointer, - state_cache[index].offset); - } - state_cache[index].offset = 0; - } - } else { - if (state_cache[index].offset) { - ADDI(reg, state_cache[index].rtlreg, - state_cache[index].offset); - } else { - MOVE(reg, state_cache[index].rtlreg); - } - } - } else { - LOAD_W(reg, state_reg, offset); - } - if (!state_cache[index].fixed - && !(index == 15 && (optimization_flags & SH2_OPTIMIZE_STACK) - && state_cache[index].rtlreg != 0) - ) { - state_cache[index].rtlreg = reg; - state_cache[index].offset = 0; - } - if (index < 16) { - /* We changed the stored value, so we have to generate a new - * direct pointer on the next access. */ - pointer_status[index].rtl_ptrreg = 0; - } - return 1; - } -#endif - LOAD_W(reg, state_reg, offset); - return 1; -} - -/* Load from a state block field, but don't change the state block cache */ -#define LOAD_STATE_COPY(reg,field) \ - ASSERT(__LOAD_STATE_COPY(entry, state_reg, (reg), offsetof(SH2State,field))) -static inline int __LOAD_STATE_COPY(const JitEntry * const entry, - const uint32_t state_reg, - const uint32_t reg, const uint32_t offset) -{ -#ifdef OPTIMIZE_STATE_BLOCK - const int index = state_cache_index(offset); - if (index >= 0 && state_cache[index].rtlreg) { - PRECOND(reg != state_cache[index].rtlreg, return 0); - if (state_cache[index].offset) { - ADDI(reg, state_cache[index].rtlreg, state_cache[index].offset); - } else { - MOVE(reg, state_cache[index].rtlreg); - } - return 1; - } -#endif - LOAD_W(reg, state_reg, offset); - return 1; -} - -/* Allocate a new register and load it from the state block, or reuse an - * old register if appropriate and if the register is not offsetted. Note - * that a register obtained from this macro MUST NOT be reassigned, since - * it may be shared; if reassignment is necessary, use DEFINE_REG() and - * LOAD_STATE() instead. (The MAC.* instructions are exceptions to this - * rule, since all other users of MACH/MACL use LOAD_STATE_COPY() to avoid - * aliasing the register.) */ -#define LOAD_STATE_ALLOC(reg,field) \ - ASSERT(reg = __LOAD_STATE_ALLOC(entry, state_reg, \ - offsetof(SH2State,field))) -static inline uint32_t __LOAD_STATE_ALLOC(const JitEntry * const entry, - const uint32_t state_reg, - const uint32_t offset) -{ -#ifdef OPTIMIZE_STATE_BLOCK - const int index = state_cache_index(offset); - if (index >= 0 && state_cache[index].rtlreg != 0) { - if (state_cache[index].offset == 0) { - return state_cache[index].rtlreg; - } else if (state_cache[index].fixed) { - ADDI(state_cache[index].rtlreg, state_cache[index].rtlreg, - state_cache[index].offset); - if (index == 15 && stack_pointer) { - ADDI(stack_pointer, stack_pointer, state_cache[index].offset); - } - state_cache[index].offset = 0; - return state_cache[index].rtlreg; - } - } -#endif - DEFINE_REG(reg); - ASSERT(__LOAD_STATE(entry, state_reg, reg, offset)); - return reg; -} - -/* Allocate a new register and load it from the state block, or reuse an - * old register (leaving any offset in the cache) if appropriate. As with - * LOAD_STATE_ALLOC(), a register obtained from this macro MUST NOT be - * reassigned. */ -#define LOAD_STATE_ALLOC_KEEPOFS(reg,field) \ - ASSERT(reg = __LOAD_STATE_ALLOC_KEEPOFS(entry, state_reg, \ - offsetof(SH2State,field))) -static inline uint32_t __LOAD_STATE_ALLOC_KEEPOFS(const JitEntry * const entry, - const uint32_t state_reg, - const uint32_t offset) -{ -#ifdef OPTIMIZE_STATE_BLOCK - const int index = state_cache_index(offset); - if (index >= 0 && state_cache[index].rtlreg != 0) { - return state_cache[index].rtlreg; - } -#endif - DEFINE_REG(reg); - ASSERT(__LOAD_STATE(entry, state_reg, reg, offset)); - return reg; -} - -#define LOAD_STATE_PTR(reg,field) \ - LOAD_PTR((reg), state_reg, offsetof(SH2State,field)) - -#define LOAD_STATE_SR_T(reg) \ - ASSERT(reg = __LOAD_STATE_SR_T(entry, state_reg)) -static inline uint32_t __LOAD_STATE_SR_T(const JitEntry * const entry, - const uint32_t state_reg) -{ -#ifdef OPTIMIZE_STATE_BLOCK - if (cached_SR_T) { - return cached_SR_T; - } -#endif - DECLARE_REG(temp); - LOAD_STATE_ALLOC(temp, SR); - DEFINE_REG(reg); - ANDI(reg, temp, SR_T); -#ifdef OPTIMIZE_STATE_BLOCK - cached_SR_T = reg; -#endif - return reg; -} - -/* Stores */ - -#define STORE_STATE(field,reg) \ - ASSERT(__STORE_STATE(entry, state_reg, offsetof(SH2State,field), (reg))) -static inline int __STORE_STATE(const JitEntry * const entry, - const uint32_t state_reg, - const uint16_t offset, const uint32_t reg) -{ - if (offset == offsetof(SH2State,R[15]) - && (optimization_flags & SH2_OPTIMIZE_STACK) - ) { -#ifdef JIT_DEBUG_VERBOSE - if (pointer_status[15].known) { - DMSG("WARNING: Reassigning stack pointer in OPTIMIZE_STACK mode"); - } -#endif - DEFINE_REG(page); - SRLI(page, reg, 19); - DEFINE_REG(pageofs); - SLLI(pageofs, page, LOG2_SIZEOF_PTR); - DEFINE_REG(dp_base); - MOVEA(dp_base, ADDR_HI(direct_pages)); - DEFINE_REG(dp_ptr); - ADD(dp_ptr, dp_base, pageofs); - if (!pointer_status[15].known) { - DEFINE_REG(base); - pointer_status[15].known = 1; - pointer_status[15].type = 2; - pointer_status[15].data_only = 1; - pointer_status[15].rtl_basereg = base; - pointer_status[15].rtl_ptrreg = 0; // stack_pointer is used instead - DEFINE_REG(new_sp); - stack_pointer = new_sp; - } - PRECOND(pointer_status[15].rtl_basereg != 0, return 0); - LOAD_PTR(pointer_status[15].rtl_basereg, dp_ptr, - ADDR_LO(direct_pages)); - PRECOND(stack_pointer != 0, return 0); - ADD(stack_pointer, pointer_status[15].rtl_basereg, reg); - } -#ifdef OPTIMIZE_STATE_BLOCK - const int index = state_cache_index(offset); - if (index >= 0) { - if (state_cache[index].fixed) { - if (reg != state_cache[index].rtlreg) { - MOVE(state_cache[index].rtlreg, reg); - } - } else { - state_cache[index].rtlreg = reg; - } - if (index < 16) { - pointer_status[index].rtl_ptrreg = 0; - } - state_cache[index].offset = 0; - if (index == state_cache_index(offsetof(SH2State,PC))) { - cached_PC = 0; - stored_PC = 0; - } - state_dirty |= 1 << index; -# ifdef TRACE_STEALTH - if (index < 23) { - APPEND(NOP, 0, 0xB0000000 | index<<16 | state_cache[index].rtlreg, - 0, 0); - } -# endif - return 1; - } -#endif - STORE_W(state_reg, reg, offset); - return 1; -} - -#define STORE_STATE_PC(value) \ - ASSERT(__STORE_STATE_PC(entry, state_reg, (value))) -static inline int __STORE_STATE_PC(const JitEntry * const entry, - const uint32_t state_reg, - const uint32_t value) -{ -#ifdef OPTIMIZE_STATE_BLOCK - const int index_PC = state_cache_index(offsetof(SH2State,PC)); - if (!state_cache[index_PC].fixed && value != 0) { - if (stored_PC == value) { - /* state->PC is already correct, so just clear the cache */ - if (state_cache[index_PC].rtlreg) { -# ifdef TRACE_STEALTH - APPEND(NOP, 0, 0xB0000000 | index_PC<<16, 0, 0); -# endif - } - cached_PC = 0; - state_cache[index_PC].rtlreg = 0; - state_dirty &= ~(1<> 16), 0, 0); - APPEND(NOP, 0, 0xBC000000 | index_PC<<16 | (value & 0xFFFF), 0, 0); - APPEND(NOP, 0, 0xB0000000 | index_PC<<16, 0, 0); -# endif - cached_PC = value; - state_dirty |= 1<= 0 - && (state_cache[index].rtlreg || !state_cache[index].fixed) - ) { - if (!state_cache[index].rtlreg) { - DEFINE_REG(rtlreg); - LOAD_W(rtlreg, state_reg, offset); - state_cache[index].rtlreg = rtlreg; - state_cache[index].offset = 0; - } - const int32_t new_offset = (int32_t)state_cache[index].offset + imm; - if ((uint32_t)(new_offset + 0x8000) < 0x10000) { - state_cache[index].offset = new_offset; - } else { - if (state_cache[index].fixed) { - ADDI(state_cache[index].rtlreg, state_cache[index].rtlreg, - new_offset); - } else { - DEFINE_REG(newreg); - ADDI(newreg, state_cache[index].rtlreg, new_offset); - state_cache[index].rtlreg = newreg; - if (index < 16) { - pointer_status[index].rtl_ptrreg = 0; - } - } - state_cache[index].offset = 0; - } - state_dirty |= 1 << index; -# ifdef TRACE_STEALTH - if (index < 23) { - uint32_t temp = state_cache[index].offset; - APPEND(NOP, 0, 0xB8000000 | index<<16 | (temp>>16 & 0xFFFF), 0, 0); - APPEND(NOP, 0, 0xBC000000 | index<<16 | (temp>> 0 & 0xFFFF), 0, 0); - APPEND(NOP, 0, 0xB0000000 | index<<16 | state_cache[index].rtlreg, - 0, 0); - } -# endif - return 1; - } -#endif - if (!cur_reg) { - ASSERT(cur_reg = __LOAD_STATE_ALLOC(entry, state_reg, offset)); - } - DEFINE_REG(result); - ADDI(result, cur_reg, imm); - STORE_W(state_reg, result, offset); - if (offset == offsetof(SH2State,R[15]) - && (optimization_flags & SH2_OPTIMIZE_STACK) - && stack_pointer - ) { - ADDI(stack_pointer, stack_pointer, imm); - } - return 1; -} - -/*----------------------------------*/ - -/* Execute an SH-2 load or store operation (note that size desginations are - * SH-2 style B[yte]/W[ord]/L[ong] rather than RTL B[yte]/H[alfword]/W[ord], - * and all 8- and 16-bit loads are signed) */ - -#define SH2_LOAD_B(dest,address) \ - do_load(entry, (dest), (address), SH2_ACCESS_TYPE_B) -#define SH2_LOAD_W(dest,address) \ - do_load(entry, (dest), (address), SH2_ACCESS_TYPE_W) -#define SH2_LOAD_L(dest,address) \ - do_load(entry, (dest), (address), SH2_ACCESS_TYPE_L) -#define SH2_STORE_B(address,src) \ - do_store(entry, (address), (src), SH2_ACCESS_TYPE_B, state_reg) -#define SH2_STORE_W(address,src) \ - do_store(entry, (address), (src), SH2_ACCESS_TYPE_W, state_reg) -#define SH2_STORE_L(address,src) \ - do_store(entry, (address), (src), SH2_ACCESS_TYPE_L, state_reg) - -/*----------------------------------*/ - -/* Execute an SH-2 load or store to a known address */ - -#define SH2_LOAD_ABS_B(dest,address) \ - do_load_abs(entry, (dest), (address), SH2_ACCESS_TYPE_B) -#define SH2_LOAD_ABS_W(dest,address) \ - do_load_abs(entry, (dest), (address), SH2_ACCESS_TYPE_W) -#define SH2_LOAD_ABS_L(dest,address) \ - do_load_abs(entry, (dest), (address), SH2_ACCESS_TYPE_L) -#define SH2_STORE_ABS_B(address,src,islocal) \ - do_store_abs(entry, (address), (src), SH2_ACCESS_TYPE_B, state_reg, \ - (islocal)) -#define SH2_STORE_ABS_W(address,src,islocal) \ - do_store_abs(entry, (address), (src), SH2_ACCESS_TYPE_W, state_reg, \ - (islocal)) -#define SH2_STORE_ABS_L(address,src,islocal) \ - do_store_abs(entry, (address), (src), SH2_ACCESS_TYPE_L, state_reg, \ - (islocal)) - -/*----------------------------------*/ - -/* Execute an SH-2 load or store through an SH-2 register */ - -#define SH2_LOAD_REG_B(dest,sh2reg,offset,postinc) \ - do_load_reg(entry, (dest), (sh2reg), (offset), SH2_ACCESS_TYPE_B, \ - (postinc), state, state_reg) -#define SH2_LOAD_REG_W(dest,sh2reg,offset,postinc) \ - do_load_reg(entry, (dest), (sh2reg), (offset), SH2_ACCESS_TYPE_W, \ - (postinc), state, state_reg) -#define SH2_LOAD_REG_L(dest,sh2reg,offset,postinc) \ - do_load_reg(entry, (dest), (sh2reg), (offset), SH2_ACCESS_TYPE_L, \ - (postinc), state, state_reg) -#define SH2_STORE_REG_B(sh2reg,src,offset,predec) \ - do_store_reg(entry, (sh2reg), (src), (offset), SH2_ACCESS_TYPE_B, \ - (predec), state, state_reg) -#define SH2_STORE_REG_W(sh2reg,src,offset,predec) \ - do_store_reg(entry, (sh2reg), (src), (offset), SH2_ACCESS_TYPE_W, \ - (predec), state, state_reg) -#define SH2_STORE_REG_L(sh2reg,src,offset,predec) \ - do_store_reg(entry, (sh2reg), (src), (offset), SH2_ACCESS_TYPE_L, \ - (predec), state, state_reg) - -/*----------------------------------*/ - -/* Branches (within an SH-2 instruction's RTL code) */ - -#define CREATE_LABEL(label) \ - const uint32_t label = rtl_alloc_label(entry->rtl); \ - if (UNLIKELY(!label)) { \ - return 0; \ - } -#define DEFINE_LABEL(label) APPEND(LABEL, 0, 0, 0, (label)) -#define GOTO_LABEL(label) APPEND(GOTO, 0, 0, 0, (label)) -#define GOTO_IF_Z(label,reg) APPEND(GOTO_IF_Z, 0, (reg), 0, (label)) -#define GOTO_IF_NZ(label,reg) APPEND(GOTO_IF_NZ, 0, (reg), 0, (label)) -#define GOTO_IF_E(label,reg1,reg2) \ - APPEND(GOTO_IF_E, 0, (reg1), (reg2), (label)) -#define GOTO_IF_NE(label,reg1,reg2) \ - APPEND(GOTO_IF_NE, 0, (reg1), (reg2), (label)) - -/*----------------------------------*/ - -/* Jumps (to other SH-2 instructions) */ - -#define JUMP_STATIC() \ - ASSERT(branch_static(state, entry, state_reg)) -#define JUMP() RETURN() - -/* Call to a native subroutine */ -#define CALL(result,arg1,arg2,func) \ - APPEND(CALL, (result), (arg1), (arg2), (func)) -#define CALL_NORET(arg1,arg2,func) \ - APPEND(CALL, 0, (arg1), (arg2), (func)) - -/* Return from the current block */ -#define RETURN() APPEND(RETURN, 0, 0, 0, 0) - -/* Chain to a different native routine */ -#define RETURN_TO(addr) APPEND(RETURN_TO, 0, 0, 0, addr) - -/*-----------------------------------------------------------------------*/ - -/* Use global variables for the PC and cycle count; the initial PC can be - * taken from the JitEntry structure */ -#define initial_PC (entry->sh2_start) -#define cur_PC jit_PC - -/* Pre- and post-decode processing is implemented by separate functions - * defined below */ -#define OPCODE_INIT(opcode) \ - ASSERT(opcode_init(state, entry, state_reg, (opcode), recursing)) -#define OPCODE_DONE(opcode) \ - ASSERT(opcode_done(state, entry, state_reg, (opcode), recursing)) - - -/* Need to update both jit_PC and state->PC */ -#define INC_PC() do { \ - jit_PC += 2; \ - STORE_STATE_PC(jit_PC); \ -} while (0) -#ifdef JIT_DEBUG_TRACE -/* Make sure we trace instructions even if eliminated by optimization */ -# define INC_PC_BY(amount) do { \ - const unsigned int __amount = (amount); \ - unsigned int __i; \ - for (__i = 0; __i < __amount; __i += 2) { \ - jit_PC += 2; \ - char tracebuf[100]; \ - const unsigned int __opcode = MappedMemoryReadWord(jit_PC); \ - SH2Disasm(jit_PC, __opcode, 0, tracebuf); \ - fprintf(stderr, "%08X: %04X %s\n", jit_PC, __opcode, tracebuf+12); \ - } \ - STORE_STATE_PC(jit_PC); \ -} while (0) -#else // !JIT_DEBUG_TRACE -# define INC_PC_BY(amount) do { \ - jit_PC += (amount); \ - STORE_STATE_PC(jit_PC); \ -} while (0) -#endif - -/* Return whether the word at "offset" words from the current instruction - * is available for peephole optimization */ -#define INSN_IS_AVAILABLE(offset) \ - (recursing ? !is_last : \ - jit_PC + (offset)*2 <= entry->sh2_end \ - && (word_info[(jit_PC - entry->sh2_start)/2 + (offset)] & WORD_INFO_CODE)\ - && !(is_branch_target[((jit_PC - entry->sh2_start) / 2 + (offset)) / 32] \ - & (1 << (((jit_PC - entry->sh2_start) / 2 + (offset)) % 32)))) - -/*----------------------------------*/ - -/* Return whether the saturation check for MAC can be omitted */ -#define CAN_OMIT_MAC_S_CHECK (can_optimize_mac_nosat) - -/* Get or set whether the MACL/MACH pair is known to be zero */ -#define MAC_IS_ZERO() (state->mac_is_zero) -#define SET_MAC_IS_ZERO() (state->mac_is_zero = 1) -#define CLEAR_MAC_IS_ZERO() (state->mac_is_zero = 0) - -/*----------------------------------*/ - -/* Get, add to, or clear the cached shift count */ -#define CAN_CACHE_SHIFTS() 1 -#define CACHED_SHIFT_COUNT() (state->cached_shift_count) -#define ADD_TO_SHIFT_CACHE(n) (state->cached_shift_count += (n)) -#define CLEAR_SHIFT_CACHE() (state->cached_shift_count = 0) - -/*----------------------------------*/ - -/* Get or set register known bits and values */ -#ifdef OPTIMIZE_KNOWN_VALUES -# define REG_GETKNOWN(reg) reg_knownbits[(reg)] -# define REG_GETVALUE(reg) reg_value[(reg)] -# define REG_SETKNOWN(reg,known) (reg_knownbits[(reg)] = (known)) -# define REG_SETVALUE(reg,value) (reg_value[(reg)] = (value)) -# define REG_RESETKNOWN() do { \ - unsigned int __i; \ - for (__i = 0; __i < lenof(reg_knownbits); __i++) { \ - reg_knownbits[__i] = 0; \ - } \ -} while (0) -#else -# define REG_GETKNOWN(reg) 0 -# define REG_GETVALUE(reg) 0 -# define REG_SETKNOWN(reg,value) /*nothing*/ -# define REG_SETVALUE(reg,value) /*nothing*/ -# define REG_RESETKNOWN() /*nothing*/ -#endif - -/*----------------------------------*/ - -/* Track pointer registers */ - -/* Check or set the local-pointer flag for a GPR (used to skip JIT overwrite - * checks in do_store_abs()); flag is cleared by PTR_CLEAR() */ -#define PTR_ISLOCAL(reg) (pointer_local & 1<<(reg)) -#define PTR_SETLOCAL(reg) do { \ - if (optimization_flags & SH2_OPTIMIZE_LOCAL_POINTERS) { \ - pointer_local |= 1<<(reg); \ - } \ -} while (0) - -/* Mark a GPR as having taken its value from the given local address */ -#define PTR_SET_SOURCE(reg,address) do { \ - if (optimization_flags & SH2_OPTIMIZE_LOCAL_POINTERS) { \ - pointer_status[(reg)].source = (address); \ - } \ -} while (0) - -/* Return whether the given register is a known pointer */ -#define PTR_CHECK(reg) (pointer_status[(reg)].known != 0 \ - || pointer_status[(reg)].rtl_basereg != 0) - -/* Copy pointer status for a MOVE Rm,Rn or ADD Rm,Rn instruction */ -#define PTR_COPY(reg,new,for_add) do { \ - const unsigned int __reg = (reg); \ - const unsigned int __new = (new); \ - pointer_status[__new] = pointer_status[__reg]; \ - if (pointer_status[__reg].known) { \ - pointer_status[__new].known = -1; \ - } \ - if (for_add) { \ - pointer_status[__new].rtl_ptrreg = 0; \ - } \ - if (PTR_ISLOCAL(__reg)) { \ - pointer_local |= 1<<__new; \ - } else { \ - pointer_local &= ~(1<<__new); \ - } \ -} while (0) - -/* Clear pointer status on a register modification */ -#define PTR_CLEAR(reg) do { \ - const unsigned int __reg = (reg); \ - if (__reg != 15 || !(optimization_flags & SH2_OPTIMIZE_STACK)) { \ - pointer_status[__reg].known = 0; \ - pointer_status[__reg].rtl_basereg = 0; \ - pointer_status[__reg].rtl_ptrreg = 0; \ - pointer_status[__reg].source = 0; \ - pointer_local &= ~(1<<__reg); \ - } \ -} while (0) - -/*----------------------------------*/ - -/* Processor state block caching */ - -/* Save the current cache state */ -#define SAVE_STATE_CACHE() do { \ - memcpy(saved_state_cache, state_cache, sizeof(state_cache));\ - saved_state_dirty = state_dirty; \ - saved_cached_SR_T = cached_SR_T; \ - saved_dirty_SR_T = dirty_SR_T; \ - saved_cached_PC = cached_PC; \ - saved_stored_PC = stored_PC; \ -} while (0) - -/* Restore the saved cache state */ -#define RESTORE_STATE_CACHE() do { \ - RESTORE_STATE_CACHE_APPEND_STEALTH_NOPS(); \ - memcpy(state_cache, saved_state_cache, sizeof(state_cache));\ - state_dirty = saved_state_dirty; \ - cached_SR_T = saved_cached_SR_T; \ - dirty_SR_T = saved_dirty_SR_T; \ - cached_PC = saved_cached_PC; \ - stored_PC = saved_stored_PC; \ -} while (0) -#ifdef TRACE_STEALTH -# define RESTORE_STATE_CACHE_APPEND_STEALTH_NOPS() do { \ - unsigned int __i; \ - for (__i = 0; __i < 23; __i++) { \ - if (__i == 22 && saved_cached_PC != 0) { \ - APPEND(NOP, 0, 0xB8160000 | (saved_cached_PC>>16 & 0xFFFF), 0, 0);\ - APPEND(NOP, 0, 0xBC160000 | (saved_cached_PC>> 0 & 0xFFFF), 0, 0);\ - APPEND(NOP, 0, 0xB0160000, 0, 0); \ - } else if ((saved_state_dirty & (1<<__i)) \ - && (!(state_dirty & (1<<__i)) \ - || saved_state_cache[__i].rtlreg != state_cache[__i].rtlreg \ - || saved_state_cache[__i].offset != state_cache[__i].offset) \ - ) { \ - uint32_t __temp = saved_state_cache[__i].offset; \ - if (__temp) { \ - APPEND(NOP, 0, 0xB8000000 | __i<<16 | (__temp>>16 & 0xFFFF), 0, 0); \ - APPEND(NOP, 0, 0xBC000000 | __i<<16 | (__temp>> 0 & 0xFFFF), 0, 0); \ - } \ - APPEND(NOP, 0, 0xB0000000 | __i<<16 | saved_state_cache[__i].rtlreg, 0, 0); \ - } else if (!(saved_state_dirty & (1<<__i)) && (state_dirty & (1<<__i))) { \ - APPEND(NOP, 0, 0xB0000000 | __i<<16, 0, 0); \ - } \ - } \ - if (saved_dirty_SR_T && (!dirty_SR_T || saved_cached_SR_T != cached_SR_T)) { \ - APPEND(NOP, 0, 0xB0900000 | saved_cached_SR_T, 0, 0); \ - } else if (!saved_dirty_SR_T && dirty_SR_T) { \ - APPEND(NOP, 0, 0xB0900000, 0, 0); \ - } \ -} while (0) -#else -# define RESTORE_STATE_CACHE_APPEND_STEALTH_NOPS() /*nothing*/ -#endif - -#ifndef OPTIMIZE_STATE_BLOCK -# undef SAVE_STATE_CACHE -# undef RESTORE_STATE_CACHE -# define SAVE_STATE_CACHE() /*nothing*/ -# define RESTORE_STATE_CACHE() /*nothing*/ -#endif - -/* Write back to the state block any cached, dirty state block values - * (but leave them dirty) */ -#define WRITEBACK_STATE_CACHE() \ - ASSERT(writeback_state_cache(entry, state_reg, 0)); - -/* Flush any cached state block values */ -#define FLUSH_STATE_CACHE() do { \ - ASSERT(writeback_state_cache(entry, state_reg, 1)); \ - clear_state_cache(0); \ -} while (0) - -/* Return the cached offset for the given state block field, or 0 if none */ -#ifdef OPTIMIZE_CONSTANT_ADDS -# define STATE_CACHE_OFFSET(field) \ - (state_cache_index(offsetof(SH2State,field)) >= 0 \ - ? state_cache[state_cache_index(offsetof(SH2State,field))].offset \ - : 0) -#else -# define STATE_CACHE_OFFSET(field) 0 -#endif - -/* Return the fixed RTL register to use for the given state block field, - * or 0 if none */ -#ifdef OPTIMIZE_STATE_BLOCK -# define STATE_CACHE_FIXED_REG(field) \ - (state_cache_index(offsetof(SH2State,field)) >= 0 \ - && state_cache[state_cache_index(offsetof(SH2State,field))].fixed \ - ? state_cache[state_cache_index(offsetof(SH2State,field))].rtlreg \ - : 0) -#else -# define STATE_CACHE_FIXED_REG(field) 0 -#endif - -/* Return whether the given state block field has a fixed RTL register that - * can be modified */ -#ifdef OPTIMIZE_STATE_BLOCK -# define STATE_CACHE_FIXED_REG_WRITABLE(field) \ - (state_cache_index(offsetof(SH2State,field)) >= 0 \ - ? state_cache[state_cache_index(offsetof(SH2State,field))].fixed \ - && state_cache[state_cache_index(offsetof(SH2State,field))].flush \ - : 0) -#else -# define STATE_CACHE_FIXED_REG_WRITABLE(field) 0 -#endif - -/* Clear any fixed RTL register for the given state block field */ -#ifdef OPTIMIZE_STATE_BLOCK -# define STATE_CACHE_CLEAR_FIXED_REG(field) do { \ - if (state_cache_index(offsetof(SH2State,field)) >= 0) { \ - state_cache[state_cache_index(offsetof(SH2State,field))].fixed = 0; \ - state_cache[state_cache_index(offsetof(SH2State,field))].flush = 0; \ - } \ -} while (0) -#else -# define STATE_CACHE_CLEAR_FIXED_REG(field) /*nothing*/ -#endif - -/*----------------------------------*/ - -/* Check the status of a branch instruction */ - -#define BRANCH_FALLS_THROUGH(addr) \ - ((addr) >= entry->sh2_start && (addr) <= entry->sh2_end \ - ? word_info[((addr) - entry->sh2_start) / 2] & WORD_INFO_FALLTHRU \ - : 0) -#define BRANCH_TARGETS_RTS(addr) \ - ((addr) >= entry->sh2_start && (addr) <= entry->sh2_end \ - ? word_info[((addr) - entry->sh2_start) / 2] & WORD_INFO_BRA_RTS \ - : 0) - -#define BRANCH_IS_THREADED(addr) \ - ((addr) >= entry->sh2_start && (addr) <= entry->sh2_end \ - ? word_info[((addr) - entry->sh2_start) / 2] & WORD_INFO_THREADED \ - : 0) - -#define BRANCH_THREAD_TARGET(addr) \ - (branch_thread_target[((addr) - entry->sh2_start) / 2]) - -#define BRANCH_THREAD_COUNT(addr) \ - (branch_thread_count[((addr) - entry->sh2_start) / 2]) - -#define BRANCH_IS_SELECT(addr) \ - ((addr) >= entry->sh2_start && (addr) <= entry->sh2_end \ - ? word_info[((addr) - entry->sh2_start) / 2] & WORD_INFO_SELECT \ - : 0) - -#define BRANCH_IS_LOOP_TO_JSR(addr) \ - ((addr) >= entry->sh2_start && (addr) <= entry->sh2_end \ - ? word_info[((addr) - entry->sh2_start) / 2] & WORD_INFO_LOOP_JSR \ - : 0) - -#define BRANCH_IS_FOLDABLE_SUBROUTINE(addr) \ - ((addr) >= entry->sh2_start && (addr) <= entry->sh2_end \ - ? word_info[((addr) - entry->sh2_start) / 2] & WORD_INFO_FOLDABLE \ - : 0) - -#define BRANCH_FOLD_TARGET(addr) \ - (subroutine_target[((addr) - entry->sh2_start) / 2]) - -#define BRANCH_FOLD_TARGET_FETCH(addr) \ - ((const uint16_t *)((uintptr_t)fetch_pages[(addr) >> 19] + (addr))) - -#define BRANCH_FOLD_NATIVE_FUNC(addr) \ - (subroutine_native[((addr) - entry->sh2_start) / 2]) - -/*************************************************************************/ -/************* Helper functions for SH-2 -> RTL translation **************/ -/*************************************************************************/ - -/** - * do_load_common: Generate code for an SH-2 memory load operation common - * to both generic loads and register loads from variable addresses. - * - * [Parameters] - * entry: Block being translated - * dest: RTL register into which value is to be loaded - * address: RTL register holding load address - * offset: Offset to be added to address - * type: Access type (SH2_ACCESS_TYPE_*) - * page_ptr: RTL register holding base pointer for memory page or NULL - * [Return value] - * Nonzero on success, zero on error - */ -static int do_load_common(const JitEntry *entry, uint32_t dest, - uint32_t address, int32_t offset, - unsigned int type, uint32_t page_ptr) -{ - CREATE_LABEL(label_fallback); - CREATE_LABEL(label_done); - - DEFINE_REG(final_ptr); // Move this up to help MIPS delay slot optimization - if (offset < -0x8000 || offset > 0x7FFF) { - /* Memory offsets must be within the range [-0x8000,0x7FFF], so if - * we fall outside that range, add the offset to the address - * separately */ - DEFINE_REG(offset_addr); - ADDI(offset_addr, address, offset); - offset = 0; - ADD(final_ptr, page_ptr, offset_addr); - } else { - ADD(final_ptr, page_ptr, address); - } - - GOTO_IF_Z(label_fallback, page_ptr); { - /* We can access the data directly */ - // FIXME: all the code here assumes little-endian; this won't work - // if we port to a big-endian machine - switch (type) { - case SH2_ACCESS_TYPE_B: { - DEFINE_REG(real_ptr); - int32_t real_offset; - if (offset & 1) { - /* Can't use an immediate offset because we don't know - * whether the source address is odd, so we can't predict - * the effect of the XOR */ - DEFINE_REG(offset_ptr); - ADDI(offset_ptr, final_ptr, offset); - XORI(real_ptr, offset_ptr, 1); - real_offset = 0; - } else { - XORI(real_ptr, final_ptr, 1); - real_offset = offset; - } - LOAD_BS(dest, real_ptr, real_offset); - break; - } - case SH2_ACCESS_TYPE_W: { - LOAD_HS(dest, final_ptr, offset); - break; - } - case SH2_ACCESS_TYPE_L: { - DEFINE_REG(swapped); - LOAD_W(swapped, final_ptr, offset); - HSWAPW(dest, swapped); - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - GOTO_LABEL(label_done); - - } DEFINE_LABEL(label_fallback); { - /* Not direct access, so call the fallback routine */ - DECLARE_REG(real_address); - if (offset) { - ALLOC_REG(real_address); - ADDI(real_address, address, offset); - } else { - real_address = address; - } - DEFINE_REG(fallback); - switch (type) { - case SH2_ACCESS_TYPE_B: { - MOVEA(fallback, MappedMemoryReadByte); - DEFINE_REG(retval); - CALL(retval, real_address, 0, fallback); - DEFINE_REG(tempdest); - SLLI(tempdest, retval, 24); - SRAI(dest, tempdest, 24); - break; - } - case SH2_ACCESS_TYPE_W: { - MOVEA(fallback, MappedMemoryReadWord); - DEFINE_REG(retval); - CALL(retval, real_address, 0, fallback); - DEFINE_REG(tempdest); - SLLI(tempdest, retval, 16); - SRAI(dest, tempdest, 16); - break; - } - case SH2_ACCESS_TYPE_L: { - MOVEA(fallback, MappedMemoryReadLong); - CALL(dest, real_address, 0, fallback); - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - - } DEFINE_LABEL(label_done); - - return 1; -} - -/*----------------------------------*/ - -/** - * do_load: Generate code for an SH-2 memory load operation. - * - * [Parameters] - * entry: Block being translated - * dest: RTL register into which value is to be loaded - * address: RTL register holding load address - * type: Access type (SH2_ACCESS_TYPE_*) - * [Return value] - * Nonzero on success, zero on error - */ -static int do_load(const JitEntry *entry, uint32_t dest, uint32_t address, - unsigned int type) -{ - DEFINE_REG(page); - SRLI(page, address, 19); - DEFINE_REG(dp_base); - MOVEA(dp_base, ADDR_HI(direct_pages)); - DEFINE_REG(temp); - SLLI(temp, page, LOG2_SIZEOF_PTR); - DEFINE_REG(dp_ptr); - ADD(dp_ptr, dp_base, temp); - DEFINE_REG(page_ptr); - LOAD_PTR(page_ptr, dp_ptr, ADDR_LO(direct_pages)); - - return do_load_common(entry, dest, address, 0, type, page_ptr); -} - -/*----------------------------------*/ - -/** - * do_load_abs: Generate optimized code for an SH-2 memory load operation - * from a known address. - * - * [Parameters] - * entry: Block being translated - * dest: RTL register into which value is to be loaded - * address: Load address (in SH-2 address space) - * type: Access type (SH2_ACCESS_TYPE_*) - * [Return value] - * Nonzero on success, zero on error - */ -static int do_load_abs(const JitEntry *entry, uint32_t dest, uint32_t address, - unsigned int type) -{ - const uint32_t page = address >> 19; - - if (direct_pages[page]) { - - const uintptr_t real_address = - (uintptr_t)direct_pages[page] + address; - DEFINE_REG(addr_reg); - switch (type) { - case SH2_ACCESS_TYPE_B: { - MOVEA(addr_reg, ADDR_HI(real_address ^ 1)); - LOAD_BS(dest, addr_reg, ADDR_LO(real_address ^ 1)); - break; - } - case SH2_ACCESS_TYPE_W: { - MOVEA(addr_reg, ADDR_HI(real_address)); - LOAD_HS(dest, addr_reg, ADDR_LO(real_address)); - break; - } - case SH2_ACCESS_TYPE_L: { - MOVEA(addr_reg, ADDR_HI(real_address)); - DEFINE_REG(swapped); - LOAD_W(swapped, addr_reg, ADDR_LO(real_address)); - HSWAPW(dest, swapped); - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - - } else { - - DEFINE_REG(addr_reg); - MOVEA(addr_reg, address); - DEFINE_REG(fallback); - switch (type) { - case SH2_ACCESS_TYPE_B: { - MOVEA(fallback, MappedMemoryReadByte); - DEFINE_REG(retval); - CALL(retval, addr_reg, 0, fallback); - DEFINE_REG(temp); - SLLI(temp, retval, 24); - SRAI(dest, temp, 24); - break; - } - case SH2_ACCESS_TYPE_W: { - MOVEA(fallback, MappedMemoryReadWord); - DEFINE_REG(retval); - CALL(retval, addr_reg, 0, fallback); - DEFINE_REG(temp); - SLLI(temp, retval, 16); - SRAI(dest, temp, 16); - break; - } - case SH2_ACCESS_TYPE_L: { - MOVEA(fallback, MappedMemoryReadLong); - CALL(dest, addr_reg, 0, fallback); - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - - } - - return 1; -} - -/*----------------------------------*/ - -/** - * do_load_reg: Generate optimized code for an SH-2 memory load operation - * through an SH-2 register. - * - * [Parameters] - * entry: Block being translated - * dest: RTL register into which value is to be loaded - * sh2reg: SH-2 register holding load address (0-15) - * offset: Offset to be added to address - * type: Access type (SH2_ACCESS_TYPE_*) - * postinc: Nonzero if a postincrement access, else zero - * state: SH-2 state block pointer - * state_reg: RTL register holding state block pointer - * [Return value] - * Nonzero on success, zero on error - */ -static int do_load_reg(const JitEntry *entry, uint32_t dest, - unsigned int sh2reg, int32_t offset, unsigned int type, - int postinc, const SH2State *state, - uint32_t state_reg) -{ - const int postinc_size = - !postinc ? 0 : - type==SH2_ACCESS_TYPE_L ? 4 : type==SH2_ACCESS_TYPE_W ? 2 : 1; - -#ifdef OPTIMIZE_STATE_BLOCK - offset += state_cache[state_cache_index(offsetof(SH2State,R[sh2reg]))].offset; -#endif - - if (!pointer_status[sh2reg].known && pointer_status[sh2reg].source != 0) { - const uint32_t address = - MappedMemoryReadLong(pointer_status[sh2reg].source); - pointer_status[sh2reg].known = -1; // Only tentatively known - pointer_status[sh2reg].data_only = 0; - if ((address & 0xDFF00000) == 0x00200000 - || (address & 0xDE000000) == 0x06000000 - ) { - pointer_status[sh2reg].type = 2; - DEFINE_REG(basereg); - MOVEA(basereg, direct_pages[address>>19]); - pointer_status[sh2reg].rtl_basereg = basereg; - } else if ((address & 0xDFF80000) == 0x05C00000 - || (address & 0xDFF00000) == 0x05E00000 - ) { - pointer_status[sh2reg].type = 1; - DEFINE_REG(basereg); - MOVEA(basereg, byte_direct_pages[address>>19]); - pointer_status[sh2reg].rtl_basereg = basereg; - } else { - pointer_status[sh2reg].rtl_basereg = 0; - } - pointer_status[sh2reg].rtl_ptrreg = 0; - } - - if (pointer_status[sh2reg].known) { - - DECLARE_REG(address); - LOAD_STATE_ALLOC_KEEPOFS(address, R[sh2reg]); - - if (pointer_status[sh2reg].rtl_basereg) { - - DECLARE_REG(ptr); - if (sh2reg == 15 && stack_pointer) { - if (offset < -0x8000 || offset > 0x7FFF) { - ALLOC_REG(ptr); - ADDI(ptr, stack_pointer, offset); - offset = 0; - } else { - ptr = stack_pointer; - } - } else { - if (offset < -0x8000 || offset > 0x7FFF) { - DEFINE_REG(offset_addr); - ADDI(offset_addr, address, offset); - offset = 0; - ALLOC_REG(ptr); - ADD(ptr, pointer_status[sh2reg].rtl_basereg, offset_addr); - } else if (pointer_status[sh2reg].rtl_ptrreg) { - ptr = pointer_status[sh2reg].rtl_ptrreg; - } else { - ALLOC_REG(ptr); - ADD(ptr, pointer_status[sh2reg].rtl_basereg, address); - pointer_status[sh2reg].rtl_ptrreg = ptr; - } - } - switch (type) { - case SH2_ACCESS_TYPE_B: { - DECLARE_REG(real_ptr); - int32_t real_offset; - if (sh2reg == 15 && (optimization_flags & SH2_OPTIMIZE_STACK)){ - /* Assume the stack is 32-bit aligned, so we can apply - * the XOR directly to the offset */ - real_ptr = ptr; - real_offset = offset ^ 1; - } else if (pointer_status[sh2reg].type == 1) { - /* No need to modify address for byte-ordered memory */ - real_ptr = ptr; - real_offset = offset; - } else if (offset & 1) { - DEFINE_REG(offset_ptr); - ADDI(offset_ptr, ptr, offset); - ALLOC_REG(real_ptr); - XORI(real_ptr, offset_ptr, 1); - real_offset = 0; - } else { - ALLOC_REG(real_ptr); - XORI(real_ptr, ptr, 1); - real_offset = offset; - } - LOAD_BS(dest, real_ptr, real_offset); - break; - } - case SH2_ACCESS_TYPE_W: { - if (pointer_status[sh2reg].type == 1) { - DEFINE_REG(swapped); - LOAD_HU(swapped, ptr, offset); - DEFINE_REG(temp); - BSWAPH(temp, swapped); - DEFINE_REG(temp2); - SLLI(temp2, temp, 16); - SRAI(dest, temp2, 16); - } else { - LOAD_HS(dest, ptr, offset); - } - break; - } - case SH2_ACCESS_TYPE_L: { - DEFINE_REG(swapped); - LOAD_W(swapped, ptr, offset); - if (pointer_status[sh2reg].type == 1) { - BSWAPW(dest, swapped); - } else { - HSWAPW(dest, swapped); - } - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - - } else { // !pointer_status[sh2reg].rtl_basereg - - DECLARE_REG(offset_addr); - if (offset) { - ALLOC_REG(offset_addr); - ADDI(offset_addr, address, offset); - } else { - offset_addr = address; - } - DEFINE_REG(fallback); - switch (type) { - case SH2_ACCESS_TYPE_B: { - MOVEA(fallback, MappedMemoryReadByte); - DEFINE_REG(retval); - CALL(retval, offset_addr, 0, fallback); - DEFINE_REG(temp); - SLLI(temp, retval, 24); - SRAI(dest, temp, 24); - break; - } - case SH2_ACCESS_TYPE_W: { - MOVEA(fallback, MappedMemoryReadWord); - DEFINE_REG(retval); - CALL(retval, offset_addr, 0, fallback); - DEFINE_REG(temp); - SLLI(temp, retval, 16); - SRAI(dest, temp, 16); - break; - } - case SH2_ACCESS_TYPE_L: { - MOVEA(fallback, MappedMemoryReadLong); - CALL(dest, offset_addr, 0, fallback); - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - - } // if (pointer_status[sh2reg].rtl_basereg) - - } else { // !pointer_status[sh2reg].known - - DECLARE_REG(address); - LOAD_STATE_ALLOC_KEEPOFS(address, R[sh2reg]); - if (optimization_flags & SH2_OPTIMIZE_POINTERS) { - if (!pointer_status[sh2reg].rtl_basereg) { - DEFINE_REG(page); - SRLI(page, address, 19); - DEFINE_REG(dp_base); - MOVEA(dp_base, ADDR_HI(direct_pages)); - DEFINE_REG(table_offset); - SLLI(table_offset, page, LOG2_SIZEOF_PTR); - DEFINE_REG(dp_ptr); - ADD(dp_ptr, dp_base, table_offset); - DEFINE_REG(basereg); - LOAD_PTR(basereg, dp_ptr, ADDR_LO(direct_pages)); - pointer_status[sh2reg].rtl_basereg = basereg; - pointer_status[sh2reg].rtl_ptrreg = 0; - pointer_status[sh2reg].checked_djp = 0; - } - ASSERT(do_load_common(entry, dest, address, offset, type, - pointer_status[sh2reg].rtl_basereg)); - } else { - DECLARE_REG(offset_addr); - if (offset) { - ALLOC_REG(offset_addr); - ADDI(offset_addr, address, offset); - } else { - offset_addr = address; - } - ASSERT(do_load(entry, dest, offset_addr, type)); - } - - } - - if (postinc_size) { - ADDI_STATE_NOREG(R[sh2reg], postinc_size); - } - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * log_store: Helper function for do_store() and friends to log a store - * operation. Does nothing if no relevant tracing option is enabled. - * - * [Parameters] - * entry: Block being translated - * address: Register holding SH-2 store address, or store address itself - * src: Register holding value to store - * offset: Offset to be added to address - * type: Access type (SH2_ACCESS_TYPE_[BWL] only) - * is_abs: Nonzero if "address" is the actual store address - * [Return value] - * Nonzero on success, zero on error - */ -static inline int log_store(const JitEntry *entry, uint32_t address, - uint32_t src, int32_t offset, int type, int abs) -{ -#if defined(TRACE) - - static SH2TraceAccessCallback ** const logfunc_ptrs[] = { - [SH2_ACCESS_TYPE_B] = &trace_storeb_callback, - [SH2_ACCESS_TYPE_W] = &trace_storew_callback, - [SH2_ACCESS_TYPE_L] = &trace_storel_callback, - }; - DEFINE_REG(funcptr); - DECLARE_REG(addr_param); - if (abs) { - ALLOC_REG(addr_param); - MOVEI(addr_param, address + offset); - } else if (offset) { - ALLOC_REG(addr_param); - ADDI(addr_param, address, offset); - } else { - addr_param = address; - } - MOVEA(funcptr, *logfunc_ptrs[type]); - CALL_NORET(addr_param, src, funcptr); - -#elif defined(TRACE_STEALTH) - - static const unsigned int storecode[] = { - [SH2_ACCESS_TYPE_B] = 1, - [SH2_ACCESS_TYPE_W] = 2, - [SH2_ACCESS_TYPE_L] = 4, - }; - APPEND(NOP, 0, 0xC0000000 | storecode[type], 0, 0); - if (abs) { - address += offset; - APPEND(NOP, 0, 0xD8000000 | ((address >> 16) & 0xFFFF), 0, 0); - APPEND(NOP, 0, 0xDC000000 | (address & 0xFFFF), 0, 0); - } else { - APPEND(NOP, 0, 0xD0000000 | address, 0, 0); - APPEND(NOP, 0, 0xD4000000 | ((offset >> 16) & 0xFFFF), 0, 0); - APPEND(NOP, 0, 0xD6000000 | (offset & 0xFFFF), 0, 0); - } - APPEND(NOP, 0, 0xE0000000 | src, 0, 0); - -#endif - - return 1; -} - -/*----------------------------------*/ - -/** - * do_store_common: Generate code for an SH-2 memory store operation common - * to both generic loads and register loads from variable addresses. - * - * [Parameters] - * entry: Block being translated - * address: RTL register holding store address - * src: RTL register holding value to be stored - * offset: Offset to be added to address - * type: Access type (SH2_ACCESS_TYPE_[BWL] only) - * state_reg: RTL register holding state block pointer - * page_ptr: RTL register holding base pointer for memory page or NULL - * djppage_ptr: RTL register holding base pointer for JIT flag table, or - * zero to skip JIT write check - * [Return value] - * Nonzero on success, zero on error - */ -static int do_store_common(const JitEntry *entry, uint32_t address, - uint32_t src, int32_t offset, unsigned int type, - uint32_t state_reg, uint32_t page_ptr, - uint32_t djppage_ptr) -{ - CREATE_LABEL(label_fallback); - CREATE_LABEL(label_done); - - DEFINE_REG(final_ptr); // Move this up to help MIPS delay slot optimization - int32_t final_offset; - if (offset < -0x8000 || offset > 0x7FFF) { - DEFINE_REG(offset_addr); - ADDI(offset_addr, address, offset); - ADD(final_ptr, page_ptr, offset_addr); - final_offset = 0; - } else { - ADD(final_ptr, page_ptr, address); - final_offset = offset; - } - - GOTO_IF_Z(label_fallback, page_ptr); { - /* We can write data directly */ - - switch (type) { - case SH2_ACCESS_TYPE_B: { - DEFINE_REG(real_ptr); - int32_t real_offset; - if (final_offset & 1) { - DEFINE_REG(offset_ptr); - ADDI(offset_ptr, final_ptr, final_offset); - XORI(real_ptr, offset_ptr, 1); - real_offset = 0; - } else { - XORI(real_ptr, final_ptr, 1); - real_offset = final_offset; - } - STORE_B(real_ptr, src, real_offset); - break; - } - case SH2_ACCESS_TYPE_W: { - STORE_H(final_ptr, src, final_offset); - break; - } - case SH2_ACCESS_TYPE_L: { - DEFINE_REG(swapped); - HSWAPW(swapped, src); - STORE_W(final_ptr, swapped, final_offset); - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - - /* Check for modified translations and clear if needed */ - if (djppage_ptr) { - /* Look up the appropriate byte in the table */ - DEFINE_REG(byteofs); - SRLI(byteofs, address, JIT_PAGE_BITS); - DEFINE_REG(byteaddr); - ADD(byteaddr, djppage_ptr, byteofs); - DEFINE_REG(test); - LOAD_BU(test, byteaddr, 0); - /* Does the JIT page contain translations? */ - GOTO_IF_Z(label_done, test); { - /* Clear translations from the JIT page */ - DEFINE_REG(jcw_ptr); - MOVEA(jcw_ptr, jit_clear_write); - CALL_NORET(state_reg, address, jcw_ptr); - } DEFINE_LABEL(label_done); - } - - } DEFINE_LABEL(label_fallback); { - /* Not direct access, so call the fallback routine */ - - DECLARE_REG(real_address); - if (final_offset) { - ALLOC_REG(real_address); - ADDI(real_address, address, final_offset); - } else { - real_address = address; - } - void *funcptr; - switch (type) { - case SH2_ACCESS_TYPE_B: funcptr = MappedMemoryWriteByte; break; - case SH2_ACCESS_TYPE_W: funcptr = MappedMemoryWriteWord; break; - case SH2_ACCESS_TYPE_L: funcptr = MappedMemoryWriteLong; break; - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - DEFINE_REG(fallback); - MOVEA(fallback, funcptr); - CALL_NORET(real_address, src, fallback); - /* No need to check translations if not direct-access */ - - } DEFINE_LABEL(label_done); - - return 1; -} - -/*----------------------------------*/ - -/** - * do_store: Generate code for an SH-2 memory store operation. - * - * [Parameters] - * entry: Block being translated - * address: RTL register holding store address - * src: RTL register holding value to be stored - * type: Access type (SH2_ACCESS_TYPE_[BWL] only) - * state_reg: RTL register holding state block pointer - * [Return value] - * Nonzero on success, zero on error - */ -static int do_store(const JitEntry *entry, uint32_t address, uint32_t src, - unsigned int type, uint32_t state_reg) -{ - CREATE_LABEL(label_fallback); - CREATE_LABEL(label_done); - - /* Log the store if appropriate */ - log_store(entry, address, src, 0, type, 0); - - /* Look up the direct access pointer */ - DEFINE_REG(page); - SRLI(page, address, 19); - DEFINE_REG(table_offset); - SLLI(table_offset, page, LOG2_SIZEOF_PTR); - DEFINE_REG(dp_base); - MOVEA(dp_base, ADDR_HI(direct_pages)); - DEFINE_REG(dp_ptr); - ADD(dp_ptr, dp_base, table_offset); - DEFINE_REG(page_ptr_temp); - LOAD_PTR(page_ptr_temp, dp_ptr, ADDR_LO(direct_pages)); - /* Also check direct_jit_pages[] to make sure it's writable */ - DEFINE_REG(djp_base); - MOVEA(djp_base, ADDR_HI(direct_jit_pages)); - DEFINE_REG(djp_ptr); - ADD(djp_ptr, djp_base, table_offset); - DEFINE_REG(djppage_ptr); - LOAD_PTR(djppage_ptr, djp_ptr, ADDR_LO(direct_jit_pages)); - /* Select to zero if the direct_jit_pages[] entry is zero */ - DEFINE_REG(page_ptr); - SELECT(page_ptr, page_ptr_temp, djppage_ptr, djppage_ptr); - - /* Actually perform the store */ - return do_store_common(entry, address, src, 0, type, state_reg, - page_ptr, djppage_ptr); -} - -/*----------------------------------*/ - -/** - * do_store_abs: Generate optimized code for an SH-2 memory store - * operation to a known address. - * - * [Parameters] - * entry: Block being translated - * address: Store address - * src: RTL register holding value to be stored - * type: Access type (SH2_ACCESS_TYPE_[BWL] only) - * state_reg: RTL register holding state block pointer - * islocal: Nonzero if the address points to local data, else zero - * [Return value] - * Nonzero on success, zero on error - */ -static int do_store_abs(const JitEntry *entry, uint32_t address, uint32_t src, - unsigned int type, uint32_t state_reg, int islocal) -{ - if (!(optimization_flags & SH2_OPTIMIZE_LOCAL_ACCESSES)) { - islocal = 0; // Prevent optimization - } - - log_store(entry, address, src, 0, type, 1); - - const uint32_t page = address >> 19; - - if ((address & 0x1FF00000) != 0 && direct_pages[page]) { - - const uintptr_t real_address = - (uintptr_t)direct_pages[page] + address; - DEFINE_REG(addr_reg); - switch (type) { - case SH2_ACCESS_TYPE_B: { - MOVEA(addr_reg, ADDR_HI(real_address ^ 1)); - STORE_B(addr_reg, src, ADDR_LO(real_address ^ 1)); - break; - } - case SH2_ACCESS_TYPE_W: { - MOVEA(addr_reg, ADDR_HI(real_address)); - STORE_H(addr_reg, src, ADDR_LO(real_address)); - break; - } - case SH2_ACCESS_TYPE_L: { - MOVEA(addr_reg, ADDR_HI(real_address)); - DEFINE_REG(swapped); - HSWAPW(swapped, src); - STORE_W(addr_reg, swapped, ADDR_LO(real_address)); - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } -#ifdef JIT_DEBUG_VERBOSE - if (islocal) { - fprintf(stderr, "[OLA] %08X: store to local address 0x%08X\n", - jit_PC, address); - } -#endif - if (!islocal && direct_jit_pages[page]) { - CREATE_LABEL(label_done); - /* Look up the appropriate bit in the direct_jit_pages table */ - const uintptr_t byteaddr_val = (uintptr_t)direct_jit_pages[page] - + (address >> JIT_PAGE_BITS); - DEFINE_REG(byteaddr); - MOVEA(byteaddr, ADDR_HI(byteaddr_val)); - DEFINE_REG(test); - LOAD_BU(test, byteaddr, ADDR_LO(byteaddr_val)); - /* Does the JIT page contain translations? */ - GOTO_IF_Z(label_done, test); { - /* Clear translations from the JIT page */ - DEFINE_REG(sh2_addr_reg); - MOVEI(sh2_addr_reg, address); - DEFINE_REG(jcw_ptr); - MOVEA(jcw_ptr, jit_clear_write); - CALL_NORET(state_reg, sh2_addr_reg, jcw_ptr); - } DEFINE_LABEL(label_done); - } - - } else { - - void *funcptr; - switch (type) { - case SH2_ACCESS_TYPE_B: funcptr = MappedMemoryWriteByte; break; - case SH2_ACCESS_TYPE_W: funcptr = MappedMemoryWriteWord; break; - case SH2_ACCESS_TYPE_L: funcptr = MappedMemoryWriteLong; break; - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - DEFINE_REG(addr_reg); - MOVEI(addr_reg, address); - DEFINE_REG(fallback); - MOVEA(fallback, funcptr); - CALL_NORET(addr_reg, src, fallback); - - } - - return 1; -} - -/*----------------------------------*/ - -/** - * do_store_reg: Generate optimized code for an SH-2 memory store - * operation through an SH-2 register. - * - * [Parameters] - * entry: Block being translated - * sh2reg: SH-2 register holding store address - * src: RTL register holding value to be stored - * offset: Offset to be added to address - * type: Access type (SH2_ACCESS_TYPE_[BWL] only) - * predec: Nonzero if a predecrement access, else zero - * state: SH-2 state block pointer - * state_reg: RTL register holding state block pointer - * [Return value] - * Nonzero on success, zero on error - */ -static int do_store_reg(const JitEntry *entry, unsigned int sh2reg, - uint32_t src, int32_t offset, unsigned int type, - int predec, const SH2State *state, uint32_t state_reg) -{ - /* Half of a JIT page, in bytes (used when deciding whether to perform - * a check for overwrites of translated code) */ - const int32_t half_jit_page = (1U << JIT_PAGE_BITS) / 2; - - const int predec_size = - !predec ? 0 : - type==SH2_ACCESS_TYPE_L ? 4 : - type==SH2_ACCESS_TYPE_W ? 2 : 1; - if (predec_size) { - ADDI_STATE_NOREG(R[sh2reg], -predec_size); - } - -#ifdef OPTIMIZE_STATE_BLOCK - offset += state_cache[state_cache_index(offsetof(SH2State,R[sh2reg]))].offset; -#endif - - if (!pointer_status[sh2reg].known && pointer_status[sh2reg].source != 0) { - const uint32_t address = - MappedMemoryReadLong(pointer_status[sh2reg].source); - pointer_status[sh2reg].known = -1; // Only tentatively known - pointer_status[sh2reg].data_only = 0; - pointer_status[sh2reg].checked = 0; - if ((address & 0xDFF00000) == 0x00200000 - || (address & 0xDE000000) == 0x06000000 - ) { - pointer_status[sh2reg].type = 2; - DEFINE_REG(basereg); - MOVEA(basereg, direct_pages[address>>19]); - pointer_status[sh2reg].rtl_basereg = basereg; - } else if ((address & 0xDFF80000) == 0x05C00000 - || (address & 0xDFF00000) == 0x05E00000 - ) { - pointer_status[sh2reg].type = 1; - DEFINE_REG(basereg); - MOVEA(basereg, byte_direct_pages[address>>19]); - pointer_status[sh2reg].rtl_basereg = basereg; - } else { - pointer_status[sh2reg].rtl_basereg = 0; - } - pointer_status[sh2reg].rtl_ptrreg = 0; - } - - DECLARE_REG(address); - LOAD_STATE_ALLOC_KEEPOFS(address, R[sh2reg]); - - if (pointer_status[sh2reg].known) { - - log_store(entry, address, src, offset, type, 0); - - if (pointer_status[sh2reg].rtl_basereg) { - - DECLARE_REG(ptr); - int32_t ptr_offset; - if (sh2reg == 15 && stack_pointer) { - if (offset < -0x8000 || offset > 0x7FFF) { - ALLOC_REG(ptr); - ADDI(ptr, stack_pointer, offset); - ptr_offset = 0; - } else { - ptr_offset = offset; - ptr = stack_pointer; - } - } else { - if (offset < -0x8000 || offset > 0x7FFF) { - DEFINE_REG(offset_addr); - ADDI(offset_addr, address, offset); - ptr_offset = 0; - ALLOC_REG(ptr); - ADD(ptr, pointer_status[sh2reg].rtl_basereg, offset_addr); - } else { - ptr_offset = offset; - if (pointer_status[sh2reg].rtl_ptrreg) { - ptr = pointer_status[sh2reg].rtl_ptrreg; - } else { - ALLOC_REG(ptr); - ADD(ptr, pointer_status[sh2reg].rtl_basereg, address); - pointer_status[sh2reg].rtl_ptrreg = ptr; - } - } - } - switch (type) { - case SH2_ACCESS_TYPE_B: { - DECLARE_REG(real_ptr); - int32_t real_offset; - if (sh2reg == 15 && (optimization_flags & SH2_OPTIMIZE_STACK)){ - real_ptr = ptr; - real_offset = ptr_offset ^ 1; - } else if (pointer_status[sh2reg].type == 1) { - real_ptr = ptr; - real_offset = ptr_offset; - } else if (offset & 1) { - DEFINE_REG(offset_ptr); - ADDI(offset_ptr, ptr, ptr_offset); - ALLOC_REG(real_ptr); - XORI(real_ptr, offset_ptr, 1); - real_offset = 0; - } else { - ALLOC_REG(real_ptr); - XORI(real_ptr, ptr, 1); - real_offset = ptr_offset; - } - STORE_B(real_ptr, src, real_offset); - break; - } - case SH2_ACCESS_TYPE_W: { - if (pointer_status[sh2reg].type == 1) { - DEFINE_REG(swapped); - BSWAPH(swapped, src); - STORE_H(ptr, swapped, ptr_offset); - } else { - STORE_H(ptr, src, ptr_offset); - } - break; - } - case SH2_ACCESS_TYPE_L: { - DEFINE_REG(swapped); - if (pointer_status[sh2reg].type == 1) { - BSWAPW(swapped, src); - } else { - HSWAPW(swapped, src); - } - STORE_W(ptr, swapped, ptr_offset); - break; - } - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - - /* See if we need to check for overwrites of translated code */ - int need_jit_check = 1; - if (sh2reg == 15 && (optimization_flags & SH2_OPTIMIZE_STACK)) { - need_jit_check = 0; - } else if (pointer_status[sh2reg].data_only) { - need_jit_check = 0; - } else if (pointer_status[sh2reg].type != 2) { - need_jit_check = 0; - } else if (pointer_status[sh2reg].checked - && offset - pointer_status[sh2reg].check_offset > -half_jit_page - && offset - pointer_status[sh2reg].check_offset < half_jit_page - ) { - need_jit_check = 0; - } - - if (need_jit_check) { - /* Obtain the address for checking. If the store offset is - * small, use an offset of zero for checking to save an - * instruction */ - DECLARE_REG(jit_address); - int32_t jit_offset; - if (offset > -half_jit_page && offset < half_jit_page) { - jit_address = address; - jit_offset = 0; - } else { - ALLOC_REG(jit_address); - ADDI(jit_address, address, offset); - jit_offset = offset; - } - /* Load the JIT bitmap address */ - CREATE_LABEL(label_done); - DEFINE_REG(djppage_ptr); - int djppage_ofs; - if (pointer_status[sh2reg].known > 0) { - MOVEA(djppage_ptr, - ADDR_HI(pointer_status[sh2reg].djp_base)); - djppage_ofs = ADDR_LO(pointer_status[sh2reg].djp_base); - } else { - DEFINE_REG(temp1); - SRLI(temp1, jit_address, 19); - DEFINE_REG(djp_offset); - SLLI(djp_offset, temp1, LOG2_SIZEOF_PTR); - DEFINE_REG(djp_base); - MOVEA(djp_base, ADDR_HI(direct_jit_pages)); - DEFINE_REG(djp_ptr); - ADD(djp_ptr, djp_base, djp_offset); - LOAD_PTR(djppage_ptr, djp_ptr, ADDR_LO(direct_jit_pages)); - GOTO_IF_Z(label_done, djppage_ptr); - djppage_ofs = 0; - } - /* Look up the appropriate bit in the table */ - DEFINE_REG(byteofs); - SRLI(byteofs, address, JIT_PAGE_BITS); - DEFINE_REG(byteaddr); - ADD(byteaddr, djppage_ptr, byteofs); - DEFINE_REG(test); - LOAD_BU(test, byteaddr, djppage_ofs); - /* Does the JIT page contain translations? */ - GOTO_IF_Z(label_done, test); { - /* Clear translations from the JIT page */ - DEFINE_REG(jcw_ptr); - MOVEA(jcw_ptr, jit_clear_write); - CALL_NORET(state_reg, address, jcw_ptr); - } DEFINE_LABEL(label_done); - /* Mark this register checked for translation overwrites */ - pointer_status[sh2reg].checked = 1; - pointer_status[sh2reg].check_offset = jit_offset; - } // if not an optimized stack access - - } else { // !pointer_status[sh2reg].rtl_basereg - - DECLARE_REG(offset_addr); - if (offset) { - ALLOC_REG(offset_addr); - ADDI(offset_addr, address, offset); - } else { - offset_addr = address; - } - void *funcptr; - switch (type) { - case SH2_ACCESS_TYPE_B: funcptr = MappedMemoryWriteByte; break; - case SH2_ACCESS_TYPE_W: funcptr = MappedMemoryWriteWord; break; - case SH2_ACCESS_TYPE_L: funcptr = MappedMemoryWriteLong; break; - default: - DMSG("0x%08X: BUG: invalid access type %u", jit_PC, type); - return 0; - } - DEFINE_REG(fallback); - MOVEA(fallback, funcptr); - CALL_NORET(offset_addr, src, fallback); - - } // if (pointer_status[sh2reg].rtl_basereg) - - } else { // !pointer_status[sh2reg].known - - if (optimization_flags & SH2_OPTIMIZE_POINTERS) { - log_store(entry, address, src, offset, type, 0); - DECLARE_REG(djppage_ptr); - if (!pointer_status[sh2reg].rtl_basereg) { - DEFINE_REG(page); - SRLI(page, address, 19); - DEFINE_REG(dp_base); - MOVEA(dp_base, ADDR_HI(direct_pages)); - DEFINE_REG(table_offset); - SLLI(table_offset, page, LOG2_SIZEOF_PTR); - DEFINE_REG(dp_ptr); - ADD(dp_ptr, dp_base, table_offset); - DEFINE_REG(page_ptr); - LOAD_PTR(page_ptr, dp_ptr, ADDR_LO(direct_pages)); - /* Also check direct_jit_pages[] to make sure it's writable */ - DEFINE_REG(djp_base); - MOVEA(djp_base, ADDR_HI(direct_jit_pages)); - DEFINE_REG(djp_ptr); - if (offset > -half_jit_page && offset < half_jit_page) { - /* Check at an offset of zero for efficiency */ - ADD(djp_ptr, djp_base, table_offset); - pointer_status[sh2reg].check_offset = 0; - } else { - DEFINE_REG(djp_address); - ADDI(djp_address, address, offset); - DEFINE_REG(djp_page); - SRLI(djp_page, djp_address, 19); - DEFINE_REG(djp_table_offset); - SLLI(djp_table_offset, djp_page, LOG2_SIZEOF_PTR); - ADD(djp_ptr, djp_base, djp_table_offset); - pointer_status[sh2reg].check_offset = offset; - } - ALLOC_REG(djppage_ptr); - LOAD_PTR(djppage_ptr, djp_ptr, ADDR_LO(direct_jit_pages)); - pointer_status[sh2reg].checked = 1; - /* Select to zero if the direct_jit_pages[] entry is zero */ - DEFINE_REG(basereg); - SELECT(basereg, page_ptr, djppage_ptr, djppage_ptr); - pointer_status[sh2reg].rtl_basereg = basereg; - pointer_status[sh2reg].rtl_ptrreg = 0; - pointer_status[sh2reg].checked_djp = 1; - } else if (!pointer_status[sh2reg].checked_djp) { - /* This register was first used in a load, so we don't yet - * know whether it's writable; check the direct_jit_pages[] - * entry as above */ - DEFINE_REG(page); - SRLI(page, address, 19); - DEFINE_REG(dp_base); - MOVEA(dp_base, ADDR_HI(direct_pages)); - DEFINE_REG(table_offset); - SLLI(table_offset, page, LOG2_SIZEOF_PTR); - DECLARE_REG(basereg); - basereg = pointer_status[sh2reg].rtl_basereg; - DEFINE_REG(djp_base); - MOVEA(djp_base, ADDR_HI(direct_jit_pages)); - DEFINE_REG(djp_ptr); - if (offset > -half_jit_page && offset < half_jit_page) { - ADD(djp_ptr, djp_base, table_offset); - pointer_status[sh2reg].check_offset = 0; - } else { - DEFINE_REG(djp_address); - ADDI(djp_address, address, offset); - DEFINE_REG(djp_page); - SRLI(djp_page, djp_address, 19); - DEFINE_REG(djp_table_offset); - SLLI(djp_table_offset, djp_page, LOG2_SIZEOF_PTR); - ADD(djp_ptr, djp_base, djp_table_offset); - pointer_status[sh2reg].check_offset = offset; - } - ALLOC_REG(djppage_ptr); - LOAD_PTR(djppage_ptr, djp_ptr, ADDR_LO(direct_jit_pages)); - pointer_status[sh2reg].checked = 1; - SELECT(basereg, basereg, djppage_ptr, djppage_ptr); - pointer_status[sh2reg].checked_djp = 1; - } else if (!pointer_status[sh2reg].checked - || offset - pointer_status[sh2reg].check_offset <= -half_jit_page - || offset - pointer_status[sh2reg].check_offset >= half_jit_page - ) { - /* Pointer has not been checked or the last check was at - * least half a JIT page away, so check for JIT overwrites */ - DEFINE_REG(djp_base); - MOVEA(djp_base, ADDR_HI(direct_jit_pages)); - DEFINE_REG(djp_address); - ADDI(djp_address, address, offset); - DEFINE_REG(djp_page); - SRLI(djp_page, djp_address, 19); - DEFINE_REG(djp_table_offset); - SLLI(djp_table_offset, djp_page, LOG2_SIZEOF_PTR); - DEFINE_REG(djp_ptr); - ADD(djp_ptr, djp_base, djp_table_offset); - ALLOC_REG(djppage_ptr); - LOAD_PTR(djppage_ptr, djp_ptr, ADDR_LO(direct_jit_pages)); - pointer_status[sh2reg].checked = 1; - pointer_status[sh2reg].check_offset = offset; - } else { - /* We recently checked for JIT overwrites here, so no need - * to do so again */ - djppage_ptr = 0; - } - ASSERT(do_store_common(entry, address, src, offset, type, state_reg, - pointer_status[sh2reg].rtl_basereg, - djppage_ptr)); - } else { - DECLARE_REG(offset_addr); - if (offset) { - ALLOC_REG(offset_addr); - ADDI(offset_addr, address, offset); - } else { - offset_addr = address; - } - ASSERT(do_store(entry, offset_addr, src, type, state_reg)); - } - - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * check_cycles: Add RTL code to commit cycles cached in "cur_cycles", - * check whether we've hit the cycle limit, and terminate execution if so. - * - * [Parameters] - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * [Return value] - * Nonzero on success, zero on error - */ -#if defined(__GNUC__) && !defined(JIT_ACCURATE_ACCESS_TIMING) -__attribute__((unused)) -#endif -static int check_cycles(const JitEntry *entry, uint32_t state_reg) -{ - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DECLARE_REG(cycle_limit); - LOAD_STATE_ALLOC(cycle_limit, cycle_limit); - DEFINE_REG(test); - SLTS(test, cycles, cycle_limit); - CREATE_LABEL(no_interrupt); - GOTO_IF_NZ(no_interrupt, test); { - SAVE_STATE_CACHE(); - FLUSH_STATE_CACHE(); - RETURN(); - RESTORE_STATE_CACHE(); - } DEFINE_LABEL(no_interrupt); - - return 1; -} - -/*----------------------------------*/ - -/** - * check_cycles_and_goto: Add RTL code to commit cycles and check the - * cycle count, jumping to the specified label if the cycle count has not - * reached the limit and terminating execution otherwise. - * - * [Parameters] - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * label: Target label for jump - * [Return value] - * Nonzero on success, zero on error - */ -static int check_cycles_and_goto(const JitEntry *entry, uint32_t state_reg, - uint32_t label) -{ - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DECLARE_REG(cycle_limit); - LOAD_STATE_ALLOC(cycle_limit, cycle_limit); - DEFINE_REG(test); - SLTS(test, cycles, cycle_limit); - GOTO_IF_NZ(label, test); - FLUSH_STATE_CACHE(); - RETURN(); - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * branch_static: Generate code to branch to a static address. The - * address is assumed to be stored in state->branch_target. - * Implements the JUMP_STATIC() macro used by the decoding core. - * - * [Parameters] - * state: Processor state block - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * [Return value] - * Nonzero on success, zero on failure - */ -static int branch_static(SH2State *state, JitEntry *entry, uint32_t state_reg) -{ - if ((state->branch_target < jit_PC - && state->branch_target != entry->sh2_start) - || state->branch_target > entry->sh2_end - ) { - FLUSH_STATE_CACHE(); - RETURN(); - return 1; - } - - uint32_t target_label = btcache_lookup(state->branch_target); - if (!target_label) { -#ifdef JIT_DEBUG_VERBOSE - DMSG("Unresolved branch from %08X to %08X", jit_PC - 2, - (int)state->branch_target); -#endif - target_label = rtl_alloc_label(entry->rtl); - if (UNLIKELY(!target_label)) { -#ifdef JIT_DEBUG - DMSG("Failed to allocate label for unresolved branch at 0x%08X", - jit_PC); -#endif - FLUSH_STATE_CACHE(); - RETURN(); - return 1; - } - if (!record_unresolved_branch(entry, state->branch_target, - target_label)) { - return 0; - } - unsigned int index = (state->branch_target - entry->sh2_start) / 2; - is_branch_target[index/32] |= 1 << (index % 32); - } - - if (state->branch_target < jit_PC) { - check_cycles_and_goto(entry, state_reg, target_label); - } else { - APPEND(GOTO, 0, 0, 0, target_label); - } - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opcode_init: Perform pre-decode processing for an instruction. - * Implements the OPCODE_INIT() macro used by the decoding core. - * - * [Parameters] - * state: Processor state block - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * opcode: SH-2 opcode of instruction being decoded - * recursing: Nonzero if this is a recursive decode, else zero - * [Return value] - * Nonzero on success, zero on failure - */ -static int opcode_init(SH2State *state, JitEntry *entry, uint32_t state_reg, - unsigned int opcode, int recursing) -{ - unsigned int index; - - /* - * (1) If translation tracing is enabled, print a trace line for the - * instruction. - */ -#ifdef JIT_DEBUG_TRACE - char tracebuf[100]; - SH2Disasm(jit_PC, opcode, 0, tracebuf); - fprintf(stderr, "%08X: %04X %s\n", jit_PC, opcode, tracebuf+12); -#endif - - /* - * (2) In JIT_ACCURATE_ACCESS_TIMING mode, determine whether the - * instruction performs a load or store that might not be to - * ROM/RAM, and check the cycle count if so. (This is done before - * the branch target for optimization reasons, since a cycle check - * or unconditional interrupt/termination is always performed on a - * branch.) - */ -#if defined(JIT_ACCURATE_ACCESS_TIMING) - const unsigned int n = opcode>>8 & 0xF; - const unsigned int m = opcode>>4 & 0xF; - int is_pointer; - uint32_t knownbits = 0, value = 0; - if ((opcode & 0xF00E) == 0x0004 || (opcode & 0xF00F) == 0x0006) { - is_pointer = 0; -# ifdef OPTIMIZE_KNOWN_VALUES - knownbits = reg_knownbits[REG_R(0)] & reg_knownbits[REG_R(n)]; - value = reg_value [REG_R(0)] & reg_value [REG_R(n)]; -# endif - } else if (opcode == 0x002B || (opcode & 0xFF00) == 0xC300) { - is_pointer = PTR_CHECK(15); -# ifdef OPTIMIZE_KNOWN_VALUES - knownbits = reg_knownbits[REG_R(15)]; - value = reg_value [REG_R(15)]; -# endif - } else if ((opcode & 0xF00E) == 0x000C || (opcode & 0xF00F) == 0x000E) { - is_pointer = 0; -# ifdef OPTIMIZE_KNOWN_VALUES - knownbits = reg_knownbits[REG_R(0)] & reg_knownbits[REG_R(m)]; - value = reg_value [REG_R(0)] & reg_value [REG_R(m)]; -# endif - } else if ((opcode & 0xB00F) == 0x000F) { - is_pointer = PTR_CHECK(n) && PTR_CHECK(m); -# ifdef OPTIMIZE_KNOWN_VALUES - knownbits = reg_knownbits[REG_R(n)] & reg_knownbits[REG_R(m)]; - value = reg_value [REG_R(n)] & reg_value [REG_R(m)]; -# endif - } else if ((opcode & 0xF000) == 0x1000 - || (opcode & 0xF00A) == 0x2000 || (opcode & 0xF00B) == 0x2002 - || (opcode & 0xF00A) == 0x4002 || (opcode & 0xF0FF) == 0x401B) { - is_pointer = PTR_CHECK(n); -# ifdef OPTIMIZE_KNOWN_VALUES - knownbits = reg_knownbits[REG_R(n)]; - value = reg_value [REG_R(n)]; -# endif - } else if ((opcode & 0xF000) == 0x5000 - || (opcode & 0xF00A) == 0x6000 || (opcode & 0xF00B) == 0x6002 - || (opcode & 0xFA00) == 0x8000) { - is_pointer = PTR_CHECK(m); -# ifdef OPTIMIZE_KNOWN_VALUES - knownbits = reg_knownbits[REG_R(m)]; - value = reg_value [REG_R(m)]; -# endif - } else if ((opcode & 0xB000) == 0x9000) { - is_pointer = 0; - knownbits = 0xFFFFFFFF; - value = jit_PC; - } else if ((opcode & 0xFA00) == 0xC000 || (opcode & 0xFB00) == 0xC200) { - is_pointer = 0; -# ifdef OPTIMIZE_KNOWN_VALUES - knownbits = reg_knownbits[REG_GBR]; - value = reg_value [REG_GBR]; -# endif - } else if ((opcode & 0xFC00) == 0xCC00) { - is_pointer = 0; -# ifdef OPTIMIZE_KNOWN_VALUES - knownbits = reg_knownbits[REG_GBR] & reg_knownbits[REG_R(0)]; - value = reg_value [REG_GBR] & reg_value [REG_R(0)]; -# endif - } else { - is_pointer = 1; // i.e. no need to check - } - if (!is_pointer - && ((knownbits & 0xFFF00000) != 0xFFF00000 - || ((value & 0xDFF00000) != 0x00200000 // Don't bother with $Axxxxxxx - && (value & 0xDFF00000) != 0x06000000)) - ) { - /* Exceptions are not accepted when processing a delay slot (SH7604 - * manual page 75, section 4.6.1). For BT/S and BF/S, we have to - * check whether we would actually branch or not to know whether - * the following instruction is considered to be in a delay slot. */ - if (!state->delay) { - check_cycles(entry, state_reg); - } else { // It's a delayed-branch instruction - if (state->branch_type == SH2BRTYPE_BT_S - || state->branch_type == SH2BRTYPE_BF_S - ) { - CREATE_LABEL(no_branch); - if (state->branch_type == SH2BRTYPE_BT_S) { - GOTO_IF_NZ(no_branch, state->branch_cond_reg); - } else { - GOTO_IF_Z(no_branch, state->branch_cond_reg); - } - check_cycles(entry, state_reg); - DEFINE_LABEL(no_branch); - } - } - } -#endif // JIT_ACCURATE_ACCESS_TIMING - - /* - * (4) If this is not a recursive decode and the current address is the - * target of a static branch, reset all known register values and - * pointer base registers, flush the state block register cache, - * and commit pending cycles; then add a label to serve as the - * branch target. - */ - int cached_label = 0; - index = (jit_PC - initial_PC) / 2; - if (!recursing && (is_branch_target[index/32] & (1 << (index % 32)))) { - CLEAR_MAC_IS_ZERO(); -#ifdef JIT_DEBUG - if (UNLIKELY(CACHED_SHIFT_COUNT() != 0)) { - DMSG("0x%08X: WARNING: Shift count (%u) cached over a branch" - " target!", jit_PC, CACHED_SHIFT_COUNT()); - } -#endif - REG_RESETKNOWN(); - unsigned int reg; - for (reg = 0; reg < lenof(pointer_status); reg++) { - /* Known registers were checked at the start of the block, so - * there's no risk of them being undefined due to jumping over - * the code that loads them. However, if a register has been - * copied, the copy may have occurred on a different code - * branch, so mark it as unknown in that case. */ - if (pointer_status[reg].known <= 0) { - pointer_status[reg].known = 0; - pointer_status[reg].rtl_basereg = 0; - pointer_status[reg].source = 0; - } - /* Always reset this to avoid having too many long-lived - * registers (see setup_pointers()); we'll regenerate it as - * needed. */ - pointer_status[reg].rtl_ptrreg = 0; - } - pointer_local = 0; // Known registers never appear here - ASSERT(writeback_state_cache(entry, state_reg, 0)); - clear_state_cache(0); - btcache[btcache_index].sh2_address = jit_PC; - btcache[btcache_index].rtl_label = rtl_alloc_label(entry->rtl); - if (UNLIKELY(!btcache[btcache_index].rtl_label)) { - DMSG("Failed to generate label for branch target at 0x%08X", - jit_PC); - return 0; - } else { - DEFINE_LABEL(btcache[btcache_index].rtl_label); - btcache_index++; - if (UNLIKELY(btcache_index >= lenof(btcache))) { - btcache_index = 0; - } - cached_label = 1; - } - } - - /* - * (5) If this is not a recursive decode and there are any pending - * static branches to the current address, resolve them by defining - * the RTL label they branch to. (However, do _not_ define a label - * if this instruction is in a delay slot, because the RTL code - * implementing the branch will be appended after this instruction, - * which would cause incorrect behavior for other code branching to - * this instruction.) - */ - if (!recursing && !state->delay) { - for (index = 0; index < lenof(unres_branches); index++) { - if (unres_branches[index].sh2_target == jit_PC) { - const uint32_t label = unres_branches[index].target_label; - APPEND(LABEL, 0, 0, 0, label); - unres_branches[index].sh2_target = 0; - if (!cached_label) { - /* Probably won't need it, but cache anyway just in case */ - btcache[btcache_index].sh2_address = jit_PC; - btcache[btcache_index].rtl_label = label; - btcache_index++; - if (UNLIKELY(btcache_index >= lenof(btcache))) { - btcache_index = 0; - } - cached_label = 1; - } - } - } - } - - /* - * (6) If this is not a recursive decode and this instruction is hinted - * as loading a data pointer, set a flag so that we will generate - * RTL to load the base pointer after the instruction completes; - * otherwise, clear the flag. (Note that the hint flag will never - * be set if pointer optimization is disabled, so we don't need to - * check again here.) - */ - index = (jit_PC - initial_PC) / 2; - if (!recursing && (is_data_pointer_load[index/32] & (1 << (index % 32)))) { - state->make_Rn_data_pointer = 1; - } else { - state->make_Rn_data_pointer = 0; - } - - /* - * (7) If enabled, insert a dummy instruction indicating the current - * SH-2 PC. Do this after the label so the instruction isn't - * optimized away as part of a dead code block following a branch. - */ -#ifdef JIT_DEBUG_INSERT_PC - APPEND(NOP, 0, jit_PC, 0, 0); -#endif - - /* - * (8) If TRACE_STEALTH is enabled, insert coded NOPs to inform the - * RTL interpreter of cached values and direct it to trace the - * instruction. - */ -#ifdef TRACE_STEALTH - APPEND(NOP, 0, 0x80000000 | jit_PC, 0, 0); - if (state->pending_select && !state->delay) { - APPEND(NOP, 0, 0x9F000000 | (!state->select_sense) << 16 - | state->branch_cond_reg, 0, 0); - } -# ifdef OPTIMIZE_STATE_BLOCK - APPEND(NOP, 0, 0x98000000 | STATE_CACHE_OFFSET(cycles), 0, 0); - APPEND(NOP, 0, 0x90000000 | state_cache[state_cache_index(offsetof(SH2State,cycles))].rtlreg, 0, 0); -# else - APPEND(NOP, 0, 0x98000000, 0, 0); - APPEND(NOP, 0, 0x90000000, 0, 0); -# endif -#endif - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opcode_done: Perform post-decode processing for an instruction. - * Implements the OPCODE_DONE() macro used by the decoding core. - * - * [Parameters] - * state: Processor state block - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * opcode: SH-2 opcode of instruction being decoded - * recursing: Nonzero if this is a recursive decode, else zero - * [Return value] - * Nonzero on success, zero on failure - */ -static int opcode_done(SH2State *state, JitEntry *entry, uint32_t state_reg, - unsigned int opcode, int recursing) -{ - /* - * (1) If this instruction is hinted as loading a data pointer, - * generate RTL to set up a base pointer register for the SH-2 - * register identified by the Rn field of this instruction (or R0, - * if the instruction is MOVA @(disp,PC),R0). - */ - if (state->make_Rn_data_pointer) { - const unsigned int n = - ((opcode & 0xFF00) == 0xC700) ? 0 : opcode>>8 & 0xF; - - DECLARE_REG(Rn); - LOAD_STATE_ALLOC_KEEPOFS(Rn, R[n]); - DEFINE_REG(page); - SRLI(page, Rn, 19); - DEFINE_REG(dp_base); - MOVEA(dp_base, ADDR_HI(direct_pages)); - DEFINE_REG(table_offset); - SLLI(table_offset, page, LOG2_SIZEOF_PTR); - DEFINE_REG(dp_ptr); - ADD(dp_ptr, dp_base, table_offset); - DEFINE_REG(page_ptr); - LOAD_PTR(page_ptr, dp_ptr, ADDR_LO(direct_pages)); - pointer_status[n].known = -1; - pointer_status[n].type = 2; - pointer_status[n].data_only = 1; - pointer_status[n].rtl_basereg = page_ptr; - } - - /* - * (2) If tracing, write all cached SH-2 registers back to the state - * block so traces show the correct values at each instruction. - */ -#ifdef TRACE - ASSERT(writeback_state_cache(entry, state_reg, 1)); -#endif - - return 1; -} - -/*************************************************************************/ -/***************** SH-2 -> RTL translation main routines *****************/ -/*************************************************************************/ - -/** - * translate_block: Translate a block of SH-2 instructions beginning at - * the address in entry->sh2_start into RTL code. On success, the RTL - * block in entry->rtl is finalized. - * - * [Parameters] - * state: SH-2 processor state - * entry: Block being translated - * [Return value] - * Nonzero on success, zero on error - */ -static int translate_block(SH2State *state, JitEntry *entry) -{ - const uint16_t *fetch_base = - (const uint16_t *)fetch_pages[entry->sh2_start >> 19]; - PRECOND(fetch_base != NULL, return 0); - - unsigned int index; - - /* Clear out translation state. */ - - memset(is_branch_target, 0, sizeof(is_branch_target)); - for (index = 0; index < lenof(btcache); index++) { - btcache[index].sh2_address = 0; - } - btcache_index = 0; - for (index = 0; index < lenof(unres_branches); index++) { - unres_branches[index].sh2_target = 0; - } -#ifdef OPTIMIZE_KNOWN_VALUES - for (index = 0; index < lenof(reg_knownbits); index++) { - reg_knownbits[index] = 0; - reg_value[index] = 0; - } -#endif - ignore_optimization_hints = 0; - is_constant_entry_reg = 0; - memset(pointer_status, 0, sizeof(pointer_status)); - stack_pointer = 0; - pointer_local = 0; - is_data_pointer_reg = 0; - memset(is_data_pointer_load, 0, sizeof(is_data_pointer_load)); -#ifdef OPTIMIZE_STATE_BLOCK - clear_state_cache(1); // Should always be clear here, but just in case - stored_PC = entry->sh2_start; // So loops can skip the store if optimized -#endif - state->branch_type = SH2BRTYPE_NONE; - state->branch_target = 0; - state->branch_target_reg = 0; - state->branch_fold_native = 0; - state->branch_cond_reg = 0; - state->branch_cycles = 0; - state->branch_targets_rts = 0; - state->loop_to_jsr = 0; - state->folding_subroutine = 0; - state->pending_select = 0; - state->select_sense = 0; - state->just_branched = 0; - state->need_interrupt_check = 0; - state->mac_is_zero = 0; - state->cached_shift_count = 0; - state->varshift_target_PC = 0; - state->varshift_type = 0; - state->varshift_Rcount = 0; - state->varshift_max = 0; - state->varshift_Rshift = 0; - state->division_target_PC = 0; - state->div_data.Rquo = 0; - state->div_data.Rrem = 0; - state->div_data.quo = 0; - state->div_data.rem = 0; - state->div_data.SR = 0; - - /* If a manual optimization callback has been provided, check for a - * match at this address, and use the optimized translation if found. - * (This must be done after clearing state, because the callback may - * set optimization hints and return zero.) */ - - if (manual_optimization_callback) { - const uint16_t *fetch = - (const uint16_t *)((uintptr_t)fetch_base + entry->sh2_start); - SH2NativeFunctionPointer hand_tuned_function; - const unsigned int hand_tuned_len = - (*manual_optimization_callback)(state, entry->sh2_start, - fetch, &hand_tuned_function, 0); - if (hand_tuned_len > 0) { -#ifdef JIT_DEBUG_VERBOSE - DMSG("Using hand-tuned code for 0x%08X + %u insns", - entry->sh2_start, hand_tuned_len); -#endif - DEFINE_REG(state_reg); - APPEND(LOAD_PARAM, state_reg, 0, 0, 0); - DEFINE_REG(funcptr_reg); - MOVEA(funcptr_reg, hand_tuned_function); - CALL_NORET(state_reg, 0, funcptr_reg); - RETURN(); - ASSERT(rtl_finalize_block(entry->rtl)); - entry->sh2_end = entry->sh2_start + hand_tuned_len*2 - 1; - return 1; - } - } - - /* If any registers were marked as constant on entry, load their - * values into the known-constant array. */ - -#ifdef OPTIMIZE_KNOWN_VALUES - if (is_constant_entry_reg) { - for (index = 0; index < 16; index++) { - if (is_constant_entry_reg & (1<R[index]; - } - } - } -#endif - - /* Check whether saturation code can potentially be optimized out of - * MAC instructions. */ - - can_optimize_mac_nosat = (optimization_flags & SH2_OPTIMIZE_MAC_NOSAT) - && !(state->SR & SR_S); - - /* Mark which registers are currently valid pointers. Note that we - * currently can't detect ROM pointers, because the pointer analysis - * logic would treat "offset + unknown pointer" as "ROM pointer + - * unknown offset". */ - - pointer_regs = 0; - if (optimization_flags & SH2_OPTIMIZE_POINTERS) { - for (index = 0; index < 16; index++) { - if ((state->R[index] & 0xDFF00000) == 0x00200000 - || (state->R[index] & 0xDE000000) == 0x06000000 - || (state->R[index] & 0xDFF80000) == 0x05C00000 - || (state->R[index] & 0xDFF00000) == 0x05E00000 - ) { - pointer_regs |= 1 << index; - } - } - } - - /* Scan through the SH-2 code to find the end of the block and - * determine what parts of it are translatable code, and to perform - * pre-translation checks for various optimizations. */ - - unsigned int block_len = scan_block(state, entry, entry->sh2_start); - if (!block_len) { - DMSG("Failed to find any translatable instructions at 0x%08X", - entry->sh2_start); - return 0; - } - entry->sh2_end = entry->sh2_start + block_len*2 - 1; - - /* Preload the state block pointer (first function argument) into an - * RTL register, and mark it as a unique pointer. */ - - DEFINE_REG(state_reg); - APPEND(LOAD_PARAM, state_reg, 0, 0, 0); - ASSERT(rtl_register_set_unique_pointer(entry->rtl, state_reg)); - - /* If we have an optimizable loop, prepare RTL registers for all SH-2 - * registers live in the loop as well as the cycle count and limit, up - * to the maximum configured. */ - -#ifdef OPTIMIZE_LOOP_REGISTERS - if (can_optimize_loop) { - loop_live_registers |= - 1<sh2_start, loop_live_registers, - loop_load_registers, loop_changed_registers, - loop_invariant_pointers); -# endif - unsigned int regs_fixed = 0; - for (index = 0; index < lenof(state_cache); index++) { - if (loop_live_registers & 1<= OPTIMIZE_LOOP_REGISTERS_MAX_REGS) { -# ifdef JIT_DEBUG_VERBOSE - DMSG("Out of fixed registers (%u), skipping some", - regs_fixed); -# endif - break; - } - ALLOC_REG(state_cache[index].rtlreg); - state_cache[index].offset = 0; - state_cache[index].fixed = 1; - state_cache[index].flush = - (loop_changed_registers & 1<sh2_start); - - /* If the block contains MACs and the S flag is known not to change - * from block entry to the last MAC, add a check to ensure S is still - * clear at runtime and retranslate the block if not. */ - // FIXME: We assume that in a loop, if S is left clear through the - // last MAC in the loop, it won't be set before the end of the loop - // body. If anybody actually does that, they should be dragged out - // into the street and shot. - - if (!skip_preconditions && can_optimize_mac_nosat && block_contains_mac) { - if (!invalidate_label) { - ASSERT(invalidate_label = rtl_alloc_label(entry->rtl)); - } - DECLARE_REG(SR); - LOAD_STATE_ALLOC(SR, SR); - DEFINE_REG(S); - ANDI(S, SR, SR_S); - GOTO_IF_NZ(invalidate_label, S); - } - - /* If we're optimizing a loop, initialize pointer status and preload - * pointer base addresses before the block-top label. In this case, we - * ignore any pointers which are not loop invariants and look them up - * at runtime instead. */ - // FIXME: I wonder if we have to load the stack pointer dynamically? - // (e.g. if the same code is executed by both MSH2 and SSH2, and SSH2 - // uses $002xxxxx instead of $060xxxxx) - -#ifdef OPTIMIZE_LOOP_REGISTERS - if (can_optimize_loop) { - pointer_used &= loop_invariant_pointers; - ASSERT(setup_pointers(state, entry, state_reg, skip_preconditions, - &invalidate_label)); - } -#endif - - /* Add a label for the special case of branching back to the beginning - * of the block (backward branches normally terminate execution of the - * block). When we're not optimizing loops, this has to be added - * _before_ precondition checks on pointer values so changes in those - * values are properly detected when the code loops back. */ - - CREATE_LABEL(block_start_label); - DEFINE_LABEL(block_start_label); - btcache[btcache_index].sh2_address = entry->sh2_start; - btcache[btcache_index].rtl_label = block_start_label; - btcache_index++; - - /* If we're not optimizing a loop, initialize pointer status and - * preload pointer base addresses after the block-top label. */ - -#ifdef OPTIMIZE_LOOP_REGISTERS - if (!can_optimize_loop) -#endif - ASSERT(setup_pointers(state, entry, state_reg, skip_preconditions, - &invalidate_label)); - - /* Perform the actual translation of SH-2 instructions to RTL code. */ - -#ifdef JIT_DEBUG_VERBOSE - DMSG("Starting translation at %08X", entry->sh2_start); -#endif - jit_PC = entry->sh2_start; - uint32_t next_code_address = jit_PC; // For the fall-off-the-end case - while (jit_PC <= entry->sh2_end) { - index = (jit_PC - entry->sh2_start) / 2; - if (word_info[index] & WORD_INFO_CODE) { - if (UNLIKELY(!translate_insn(state, entry, state_reg, 0, 0))) { - DMSG("Failed to translate instruction at 0x%08X", - entry->sh2_start + index*2); - return 0; - } - next_code_address = jit_PC; - } else { - /* It's not code, so just skip the word */ - jit_PC += 2; - } - } -#ifdef JIT_DEBUG_VERBOSE - DMSG("Translation ended at %08X", jit_PC-2); -#endif - - /* If static branch prediction is enabled, count the number of static - * branches to be predicted and allocate memory for the prediction - * data. The memory used by this data will be included in the total - * data size of the translated block. Otherwise, just define a flag - * indicating whether we need to append a RETURN to terminate the - * block. */ - -#ifdef JIT_BRANCH_PREDICT_STATIC - entry->num_static_branches = state->just_branched ? 0 : 1; - for (index = 0; index < lenof(unres_branches); index++) { - if (unres_branches[index].sh2_target != 0) { - entry->num_static_branches++; - } - } - if (entry->num_static_branches > 0) { - const uint32_t static_predict_size = - entry->num_static_branches * sizeof(BranchTargetInfo); - entry->static_predict = calloc(static_predict_size, 1); - if (UNLIKELY(!entry->static_predict)) { - DMSG("No memory for %u static branch predictions", - entry->num_static_branches); - return 0; - } - jit_total_data += static_predict_size; - } - int branch_num = 0; -#else // !JIT_BRANCH_PREDICT_STATIC - int need_return = 0; -#endif - - /* Flush the state block cache and terminate the code if it can fall - * off the end of the block. */ - - if (!state->just_branched) { - ASSERT(writeback_state_cache(entry, state_reg, 1)); - clear_state_cache(0); -#ifdef JIT_BRANCH_PREDICT_STATIC - ASSERT(add_static_branch_terminator( - entry, state_reg, next_code_address, branch_num++)); -#else - need_return = 1; -#endif - } - - /* Add fallback termination code for unresolved static branches. */ - - for (index = 0; index < lenof(unres_branches); index++) { - if (unres_branches[index].sh2_target != 0) { -#ifdef JIT_DEBUG_VERBOSE - DMSG("FAILED to resolve branch to %08X", - unres_branches[index].sh2_target); -#endif - DEFINE_LABEL(unres_branches[index].target_label); -#ifdef JIT_BRANCH_PREDICT_STATIC - ASSERT(add_static_branch_terminator( - entry, state_reg, unres_branches[index].sh2_target, - branch_num++)); -#else - need_return = 1; -#endif - } - } - - /* If static branch prediction is disabled, add a RETURN if needed for - * falling off the end of the block or terminating unresolved static - * branches. */ - -#ifndef JIT_BRANCH_PREDICT_STATIC - if (need_return) { - RETURN(); - } -#endif - - /* If necessary, add fallback code to invalidate the block if a - * precondition check fails. */ - - if (invalidate_label) { - DEFINE_LABEL(invalidate_label); - DEFINE_REG(imm_sh2_start); - MOVEI(imm_sh2_start, entry->sh2_start); - DEFINE_REG(addr_mark_purged); - MOVEA(addr_mark_purged, jit_mark_purged); - CALL_NORET(imm_sh2_start, 0, addr_mark_purged); - DEFINE_REG(imm_1); - MOVEI(imm_1, 1); - DEFINE_REG(addr_must_clear); - MOVEA(addr_must_clear, &entry->must_clear); - STORE_B(addr_must_clear, imm_1, 0); - RETURN(); - } - - /* Close out the translated block. */ - - if (UNLIKELY(!rtl_finalize_block(entry->rtl))) { - DMSG("Failed to finalize block at 0x%08X", entry->sh2_start); - return 0; - } - if (JIT_OPTIMIZE_FLAGS) { - if (UNLIKELY(!rtl_optimize_block(entry->rtl, JIT_OPTIMIZE_FLAGS))) { -#ifdef JIT_DEBUG - DMSG("Failed to optimize block at 0x%08X", entry->sh2_start); -#endif - /* Block is still usable, so keep going */ - } - } - - /* Clear everything from the cache, including any fixed registers. */ - - clear_state_cache(1); - - /* All done, return success. */ - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * setup_pointers: Initialize the pointer_status[] array and load any - * necessary pointer base registers. Helper function for translate_block(). - * - * [Parameters] - * state: SH-2 processor state - * entry: Block being translated - * skip_preconditions: Nonzero if preconditions should be skipped - * invalidate_label_ptr: Pointer to variable holding label index to - * jump to when the block should be invalidated - * [Return value] - * Nonzero on success, zero on error - */ -static int setup_pointers(SH2State * const state, JitEntry * const entry, - const unsigned int state_reg, - const int skip_preconditions, - unsigned int * const invalidate_label_ptr) -{ - unsigned int index; - - for (index = 0; index < lenof(pointer_status); index++) { - if ((pointer_used & 1<R[index]; - const unsigned int addr_shift = - ((reg_address & 0x0F000000) == 0x05000000) ? 19 : 20; - if (!(index == 15 && (optimization_flags & SH2_OPTIMIZE_STACK)) - && !(is_data_pointer_reg & 1<rtl)); - } - DECLARE_REG(regval); - LOAD_STATE_ALLOC(regval, R[index]); - DEFINE_REG(highbits); - SRLI(highbits, regval, addr_shift); - DEFINE_REG(test); - XORI(test, highbits, reg_address >> addr_shift); - GOTO_IF_NZ(*invalidate_label_ptr, test); - } - pointer_status[index].type = - ((reg_address & 0x0F000000) == 0x05000000) ? 1 : 2; - DEFINE_REG(basereg); - if (pointer_status[index].type == 1) { - MOVEA(basereg, byte_direct_pages[reg_address>>19]); - } else { - MOVEA(basereg, direct_pages[reg_address>>19]); - } - pointer_status[index].rtl_basereg = basereg; - /* We don't immediately load a direct pointer in order to - * minimize the number of long-lived registers (one base - * register instead of lots of direct pointer registers); - * the direct pointer will be created as needed and - * discarded at branch points. */ - pointer_status[index].rtl_ptrreg = 0; - pointer_status[index].djp_base = - direct_jit_pages[reg_address>>19]; - if (index == 15 && (optimization_flags & SH2_OPTIMIZE_STACK)) { - DECLARE_REG(regval); - LOAD_STATE_ALLOC(regval, R[index]); - DEFINE_REG(ptrreg); - ADD(ptrreg, basereg, regval); - stack_pointer = ptrreg; - } - } else { - /* Used as a pointer, but not pointing to a directly- - * accessible memory region, so we'll call the fallback - * functions for accesses through this register. But first - * make sure it really isn't pointing to a memory region - * that can contain code, or else we could overwrite an - * already-translated routine and not notice. */ - if (!*invalidate_label_ptr) { - ASSERT(*invalidate_label_ptr = - rtl_alloc_label(entry->rtl)); - } - DECLARE_REG(regval); - LOAD_STATE_ALLOC(regval, R[index]); - DEFINE_REG(page); - SRLI(page, regval, 19); - DEFINE_REG(page_ofs); - SLLI(page_ofs, page, LOG2_SIZEOF_PTR); - DEFINE_REG(djp_base); - MOVEA(djp_base, ADDR_HI(direct_jit_pages)); - DEFINE_REG(djp_ptr); - ADD(djp_ptr, djp_base, page_ofs); - DEFINE_REG(test); - LOAD_PTR(test, djp_ptr, ADDR_LO(direct_jit_pages)); - GOTO_IF_NZ(*invalidate_label_ptr, test); - pointer_status[index].rtl_basereg = 0; - pointer_status[index].rtl_ptrreg = 0; - } - } else { - pointer_status[index].known = 0; - pointer_status[index].rtl_basereg = 0; - pointer_status[index].rtl_ptrreg = 0; - } - } - - return 1; -} - -/*************************************************************************/ - -/** - * scan_block: Scan through a block of SH-2 code, finding the length of - * the block, recording whether each word in the block is code or data, and - * recording all addresses targeted by branches in the is_branch_target[] - * array. - * - * [Parameters] - * state: Processor state block pointer - * entry: Translated block data structure - * address: Start of block in SH-2 address space - * [Return value] - * Length of block, in instructions - * [Side effects] - * - Fills in word_info[], is_branch_target[], branch_thread_target[], - * and branch_thread_count[] - * - Clears can_optimize_mac_nosat if an unoptimizable MAC is found - * - Sets or clears block_contains_mac appropriately - * - Sets pointer_used to the set of registers used as pointers - * - If OPTIMIZE_LOOP_REGISTERS is defined, sets can_optimize_loop, - * loop_live_registers, loop_load_registers, loop_changed_registers, - * and loop_invariant_pointers appropriately - */ -static int scan_block(SH2State *state, JitEntry *entry, uint32_t address) -{ - const uint32_t start_address = address; // Save the block's start address - - const uint16_t *fetch_base = (const uint16_t *)fetch_pages[address >> 19]; - PRECOND(fetch_base != NULL, return 0); - const uint16_t *fetch = - (const uint16_t *)((uintptr_t)fetch_base + address); - - unsigned int index; - - memset(word_info, 0, sizeof(word_info)); - - /* If we just encountered a branch instruction that branched to an - * address we haven't seen before, remember the branch and target - * addresses so we can mark the branch as fall-through if we don't - * translate anything in between. */ - unsigned int fallthru_target = 0; // Target word_info[] index (0 = none) - unsigned int fallthru_source = 0; // Location of branch (word_info[] index) - - /* Remember whether we've seen something write to SR (we don't clear - * the can-optimize flag unless we see a MAC instruction _after_ a - * write to SR, since the SR write could just be restoring it at the - * end of the subroutine) */ - int sr_was_changed = 0; - /* We haven't seen a MAC instruction yet */ - block_contains_mac = 0; - - /* Remember the last CLRMAC we saw, as well as relevant state - * information at the point of that CLRMAC, so we can roll back if we - * later find an unoptimizable MAC instruction. */ - int last_clrmac = -1; // Word index (negative = none seen) - uint32_t last_clrmac_pointer_used = 0; - uint8_t last_clrmac_comn = 0; // can_optimize_mac_nosat - uint8_t last_clrmac_bcm = 0; // block_contains_mac - - /* Map current register contents to registers at the block entry point, - * so we can track pointer values through MOV instructions. A value of - * 31 is inserted for registers which have been overwritten with other - * values (so we don't attempt to mark the original register indices as - * "used"); a value of 30 indicates that the register is known to be a - * pointer (either by being loaded with a MOVA instruction or from an - * optimization hint) but does not derive from a specific register. */ - uint8_t pointer_map[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; - /* Clear the current set of registers used as pointers. */ - pointer_used = 0; - - /* Track which registers have values loaded via MOV @(disp,PC) for - * subroutine folding. A value of 1 (an impossible target address) - * indicates that the register has not been so loaded. We assume that - * any PC-relative load subsequently used in a JSR is a constant. */ - uint32_t local_constant[16] = {1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1}; - for (index = 0; index < 16; index++) { - if (is_constant_entry_reg & (1<R[index]; - } - } - /* We also need to remember the state of each register at every branch - * target; if a particular instruction can be reached from multiple - * sources or does not fall through from the preceding instruction, the - * contents of registers will need to be updated appropriately. */ - static uint32_t local_constant_per_insn[JIT_INSNS_PER_BLOCK][16]; - int is_local_branch = 0; - unsigned int local_branch_target_index = 0; - int local_branch_is_new = 0; - -#ifdef OPTIMIZE_LOOP_REGISTERS - /* Initialize loop optimization tracking state; also keep track of - * whether we've seen a backward branch to the beginning of the block - * and the loop register state at the time of that branch. */ - can_optimize_loop = 1; - loop_live_registers = 0; - loop_load_registers = 0; - loop_changed_registers = 0; - loop_invariant_pointers = 0xFFFF; - int is_loop = 0; - int saw_branch_target = 0; - int at_loop_branch = 0; - uint32_t final_live_registers = 0; - uint32_t final_load_registers = 0; - uint32_t final_changed_registers = 0; - uint32_t final_invariant_pointers = 0; - - /* Remember which registers had been set before the first forward - * branch encountered in the loop. Any registers set by subsequent - * instructions will be added to the preload set even if their initial - * values are not used as source operands within the loop, so the - * corresponding RTL registers have the proper values even if the code - * jumps out from the middle of the loop. */ - uint32_t loop_noload_registers = 0; - int loop_noload_registers_set = 0; - int at_branch = 0; -#endif - - - /* Find the maximum length of this block: either JIT_INSNS_PER_BLOCK or - * the number of instruction words before the next blacklisted region, - * whichever is smaller. */ - - unsigned int max_len = JIT_INSNS_PER_BLOCK; - for (index = 0; index < lenof(blacklist); index++) { - if (blacklist[index].start >= start_address - && blacklist[index].start < (start_address + max_len*2) - ) { - max_len = (blacklist[index].start - start_address) / 2; - } - } - if (UNLIKELY(max_len < 2)) { - DMSG("No translatable block at 0x%X (max_len=%u)", - start_address, max_len); - return 0; - } - - int block_len = 0; - int end_block = 0; - int end_block_next = 0; // For use with LDC ...,SR - int delay = 0; - int at_uncond_branch = 0; - for (; !end_block || delay; address += 2, fetch++, block_len++) { - - /* Save whether or not this is a delay slot, then clear "delay". */ - - const int now_in_delay = delay; - delay = 0; - - /* Move the delayed block-end flag (set when an LDC ...,SR - * instruction is detected) to end_block; if it's set, we'll end - * the block after this instruction. */ - - end_block = end_block_next; - end_block_next = 0; - - /* Get the opcode. */ - - const unsigned int opcode = *fetch; - - /* Retrieve information about the opcode. */ - - const uint32_t opcode_info = get_opcode_info(opcode); - - /* Check whether the opcode is valid, and abort if not. Don't - * include the invalid instruction in the block; if we get there - * and it's still invalid, we'll interpret it (but who knows, maybe - * it'll be modified in the meantime). */ - - if (!(opcode_info & SH2_OPCODE_INFO_VALID)) { - goto abort_scan; - } - - /* Mark this word as code. */ - - word_info[block_len] = WORD_INFO_CODE; - - /* If we're not in a delay slot, check whether we just fell through - * from a branch, and clear the fall-through variables. */ - - int at_fallthru = 0; - const uint32_t saved_fallthru_source = fallthru_source; - const uint32_t saved_fallthru_target = fallthru_target; - if (!now_in_delay && fallthru_target) { - if (block_len == fallthru_target) { -#ifdef JIT_DEBUG_VERBOSE - DMSG("Continuing at %08X from fall-through branch at %08X", - address, start_address + fallthru_source*2); -#endif - /* We don't actually update the word_info[] table until we - * have successfully scanned this instruction. If we - * marked the branch as fall-through here but later decided - * to terminate the block for optimization reasons (e.g. - * unoptimizable pointers) before this instruction, the - * generated RTL would incorrectly set the PC to the - * instruction following the branch instead of the branch - * target. */ - at_fallthru = 1; - } - fallthru_target = fallthru_source = 0; - } - - /* If this is a branch target, update the local constant list used - * by subroutine folding. */ - - if (is_branch_target[block_len/32] & (1 << (block_len%32))) { - unsigned int reg; - for (reg = 0; reg < 16; reg++) { - local_constant[reg] = local_constant_per_insn[block_len][reg]; - } - } - - /* Check for MAC.[WL] optimizations. */ - - if (optimization_flags & SH2_OPTIMIZE_MAC_NOSAT) { - if ((opcode & 0xF0FF) == 0x4007 || (opcode & 0xF0FF) == 0x400E) { - sr_was_changed = 1; - } else if ((opcode & 0xB00F) == 0x000F) { - block_contains_mac = 1; - if (sr_was_changed) { - can_optimize_mac_nosat = 0; // Oh well, tough luck - } - } - } - - /* Record pointer accesses and register modifications for pointer - * optimization. */ - - if (optimization_flags & SH2_OPTIMIZE_POINTERS) { - - optimize_pointers(start_address, address, opcode, opcode_info, - pointer_map); - - /* If we're looking at a MAC instruction beyond the beginning - * of the block, and at least one of the source registers to - * the MAC is an unknown pointer, terminate the block before - * this instruction (or before a preceding CLRMAC if there was - * a recent one) so we can translate the MAC with maximum - * optimization. But don't check this if we're in a delay - * slot, since the delay slot isn't necessarily part of the - * following code stream (and interrupting a block between a - * branch and its delay slot will wreak havoc with processor - * state). */ - if ((optimization_flags & SH2_OPTIMIZE_POINTERS_MAC) - && block_len > 0 - && !now_in_delay - ) { - if ((opcode & 0xB00F) == 0x000F) { - int stop = 0, rollback = 0; - optimize_pointers_mac( - address, opcode, pointer_map, - last_clrmac<0 ? 0 : start_address + last_clrmac*2, - &stop, &rollback - ); - if (stop) { - if (rollback) { - block_len = last_clrmac; - pointer_used = last_clrmac_pointer_used; - can_optimize_mac_nosat = last_clrmac_comn; - block_contains_mac = last_clrmac_bcm; - } - goto abort_scan; - } - } else if (opcode == 0x0028) { - /* Remember this CLRMAC so we can terminate before it - * if we find a MAC with unoptimizable memory accesses */ - last_clrmac = block_len; - last_clrmac_pointer_used = pointer_used; - last_clrmac_comn = can_optimize_mac_nosat; - last_clrmac_bcm = block_contains_mac; - } - } // if ((opt_flags & SH2_OPTIMIZE_POINTERS_MAC) && etc.) - -#if OPTIMIZE_POINTERS_BLOCK_BREAK_THRESHOLD > 0 - /* If this instruction accesses through a non-optimizable - * pointer, and there are more accesses to the same pointer in - * subsequent instructions, terminate the block before this - * instruction. (Again, don't do this if we're in a delay - * slot.) */ - int pointer_reg = -1; - if (opcode_info & SH2_OPCODE_INFO_ACCESSES_Rn) { - pointer_reg = opcode>>8 & 0xF; - } else if (opcode_info & SH2_OPCODE_INFO_ACCESSES_Rm) { - pointer_reg = opcode>>4 & 0xF; - } - /* First make sure this isn't an instruction that overwrites - * the same register it uses as a pointer. */ - if (((opcode_info & SH2_OPCODE_INFO_SETS_R0) && pointer_reg == 0) - || ((opcode_info & SH2_OPCODE_INFO_SETS_Rn) - && pointer_reg == (opcode>>8 & 0xF)) - ) { - pointer_reg = -1; - } - if (pointer_reg >= 0 - && pointer_map[pointer_reg] == 31 - && !now_in_delay - ) { - unsigned int accesses = 1; - int i; - for (i = 1; i < max_len - block_len; i++) { - const unsigned int opcode2 = fetch[i]; - const unsigned int n = opcode2>>8 & 0xF; - const unsigned int m = opcode2>>8 & 0xF; - const uint32_t info2 = get_opcode_info(opcode2); - int access_reg = -1; - if (info2 & SH2_OPCODE_INFO_ACCESSES_Rn) { - access_reg = n; - } else if (opcode_info & SH2_OPCODE_INFO_ACCESSES_Rm) { - access_reg = m; - } - if (access_reg == pointer_reg) { - accesses++; - if (accesses >= OPTIMIZE_POINTERS_BLOCK_BREAK_THRESHOLD) { -# ifdef JIT_DEBUG_VERBOSE - DMSG("Breaking block from %08X at %08X due to" - " unoptimizable pointer in r%d\n", - start_address, address, pointer_reg); -# endif - goto abort_scan; - } - } - if (((info2 & SH2_OPCODE_INFO_SETS_R0) && pointer_reg == 0) - || ((info2 & SH2_OPCODE_INFO_SETS_Rn) && pointer_reg == n) - || (info2 & (SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_COND)) - ) { - /* The pointer register was overwritten, or a - * branch interrupted the block, so stop checking. - * (We stop even for conditional branches, so we - * don't break a block for the first access when - * that access is immediately followed by a check. */ - break; - } - } - } // if (pointer_reg >= 0 && etc.) -#endif // OPTIMIZE_POINTERS_BLOCK_BREAK_THRESHOLD > 0 - - } // if (optimization_flags & SH2_OPTIMIZE_POINTERS) - -#ifdef OPTIMIZE_LOOP_REGISTERS - - /* If this address is a branch target and we're within a loop, the - * loop is too complex to optimize. Of course, we won't know - * whether we're in a loop until we see a branch back to the top, - * so just track that we saw a branch target for now. */ - - if (is_branch_target[block_len/32] & (1 << (block_len%32))) { - saw_branch_target = 1; - } - - /* If this is a potential loop, check for changes to register state. */ - - if (can_optimize_loop) { - check_loop_registers(opcode, opcode_info); - } - -#endif // OPTIMIZE_LOOP_REGISTERS - - /* If the instruction is a static branch within the potential range - * of this block, record the target; also check for optimizations. */ - - if ((opcode & 0xF900) == 0x8900 // B[TF]{,_S} - || (opcode & 0xF000) == 0xA000 // BRA - ) { - int32_t disp; - if ((opcode & 0xF000) == 0xA000) { - disp = opcode & 0xFFF; - disp <<= 20; // Sign-extend - disp >>= 19; // And double - } else { - disp = opcode & 0xFF; - disp <<= 24; - disp >>= 23; - } - uint32_t target = (address + 4) + disp; - -#ifdef OPTIMIZE_BRANCH_THREAD - /* If this is a conditional branch, check whether the target is - * another conditional branch of the same sense, either without - * a delay slot or with a NOP in the delay slot; if so, then - * thread the branch through to the final target. But don't - * thread if this branch has a delay slot whose instruction - * modifies SR.T. */ - if ((opcode & 0xF900) == 0x8900 - && target >= start_address - && target <= start_address + max_len*2 - && (!(opcode & 0x0400) - || !(get_opcode_info(fetch[1]) & SH2_OPCODE_INFO_SETS_SR_T)) - ) { - branch_thread_count[block_len] = 0; - unsigned int target_insn0 = fetch[2+(disp/2)+0]; - unsigned int target_insn1 = fetch[2+(disp/2)+1]; - while ((target_insn0 & 0xFF00) == (opcode & 0xFB00) // B[TF] - || ((target_insn0 & 0xFF00) - == ((opcode & 0xFB00) | 0x0400) // B[TF]/S - && target_insn1 == 0x0009) // NOP - ) { - disp = ((int32_t)target_insn0 << 24) >> 23; - target = target + 4 + disp; -#ifdef JIT_DEBUG_VERBOSE - DMSG("Threading branch from 0x%08X through to 0x%08X", - address, target); -#endif - word_info[block_len] |= WORD_INFO_THREADED; - branch_thread_target[block_len] = target; - branch_thread_count[block_len]++; // Assume no overflow - disp = target - (address + 4); - if (target < start_address - || target >= start_address + max_len*2 - ) { - break; - } - target_insn0 = fetch[2+(disp/2)+0]; - target_insn1 = fetch[2+(disp/2)+1]; - } - } -#endif // OPTIMIZE_BRANCH_THREAD - -#ifdef OPTIMIZE_BRANCH_SELECT - /* If this is a conditional branch, check whether the branch - * acts like an RTL SELECT instruction. To be treated like a - * SELECT, the branch must skip exactly one instruction which - * is not targeted by any other branch and which supports being - * used as a SELECT source in the SH-2 decoder (sh2-core.i). */ - if (target < start_address + max_len*2) { - if (optimize_branch_select(start_address, address, fetch, - opcode, target)) { - goto skip_branch_target_check; - } - } -#endif // OPTIMIZE_BRANCH_SELECT - - /* If enabled, check whether this branch targets a RTS/NOP pair. - * We allow this check even if the target is out of range of - * the block, on the assumption that they are part of the same - * routine. */ - if (optimization_flags & SH2_OPTIMIZE_BRANCH_TO_RTS) { - unsigned int target_insn0 = fetch[2+(disp/2)+0]; - unsigned int target_insn1 = fetch[2+(disp/2)+1]; - if (target_insn0 == 0x000B // RTS - && target_insn1 == 0x0009 // NOP - ) { - word_info[block_len] |= WORD_INFO_BRA_RTS; - goto skip_branch_target_check; - } - } - -#ifdef OPTIMIZE_LOOP_REGISTERS - /* If this is a backward branch to the beginning of the block, - * mark the block as a loop and save loop state after the - * branch's delay slot (if any). But if we've seen a branch - * target before (or at) this instruction, then the loop is too - * complex to optimize, so clear the relevant flag. */ - if (target == start_address) { - if (saw_branch_target) { - can_optimize_loop = 0; - } else { - is_loop = 1; - at_loop_branch = 1; - } - } -#endif - -#ifdef OPTIMIZE_LOOP_TO_JSR - /* If this is a backward branch to two instructions before - * the beginning of the block, record whether the targeted - * instruction is a subroutine call (JSR, BSR, or BSRF). - * In this case, also mark the following instruction as a - * branch target, because we're effectively flipping the - * sense of the branch and skipping the call and delay slot - * on the opposite condition. (If we don't do this, side - * effects of the delay slot such as generating a native - * pointer register for an SH-2 pointer won't be forgotten in - * the fall-through case, causing the fall-through code to use - * uninitialized registers and potentially crash.) */ - if (target == start_address - 4) { - unsigned int target_insn = fetch[2+(disp/2)]; - if ((target_insn & 0xF0FF) == 0x400B // JSR @Rn - || (target_insn & 0xF000) == 0xB000 // BSR label - || (target_insn & 0xF0FF) == 0x0003 // BSRF Rn - ) { - word_info[block_len] |= WORD_INFO_LOOP_JSR; - uint32_t false_target; - if (opcode_info & SH2_OPCODE_INFO_BRANCH_DELAYED) { - false_target = address+2; - } else { - false_target = address+4; - } - const uint32_t target_index = - (false_target - start_address) / 2; - is_local_branch = 1; - local_branch_target_index = target_index; - const uint32_t flag = 1 << (target_index % 32); - local_branch_is_new = !(is_branch_target[index/32] & flag); - is_branch_target[target_index/32] |= flag; - /* We don't set the OPTIMIZE_BRANCH_FALLTHRU variables - * because the branch itself does _not_ fall through; - * this branch target handling is only a hack to avoid - * overoptimization. */ - } - } -#endif - - /* Only record the branch in the lookup table if it's a forward - * branch. We allow backward branches to the beginning of the - * block (index == 0), but we don't add them to the table - * because they're handled specially--we insert a label before - * any precondition checks instead of adding one when we - * translate the instruction itself. */ - if (target > address) { - const uint32_t target_index = (target - start_address) / 2; - if (target_index < lenof(is_branch_target)*32) { - is_local_branch = 1; - local_branch_target_index = target_index; - const uint32_t flag = 1 << (target_index % 32); - if (is_branch_target[target_index/32] & flag) { - /* There's already another branch targeting the - * same instruction. After processing any delay - * slot, we'll need to clear any constants from - * the target's local constant table which differ - * from the current known register values. */ - local_branch_is_new = 0; - } else { - /* This is the first time we've seen this target; - * remember it in case we can fall through. */ -#ifdef OPTIMIZE_BRANCH_FALLTHRU - fallthru_target = target_index; - fallthru_source = block_len; -#endif - local_branch_is_new = 1; - } - is_branch_target[target_index/32] |= flag; - } - } - skip_branch_target_check:; // From branch optimization above - } - - /* If this is a BSR or a JSR to a known target, see whether it can - * be folded into the current block. */ - - if (optimization_flags & SH2_OPTIMIZE_FOLD_SUBROUTINES) { - - /* First check for PC-relative loads so we can track JSR - * target addresses. */ - if ((opcode & 0xB000) == 0x9000) { - const unsigned int n = opcode>>8 & 0xF; - const unsigned int disp = opcode & 0xFF; - if (opcode & 0x4000) { // MOV.L - const unsigned int offset = (address&2 ? 1 : 2) + 2*disp; - local_constant[n] = fetch[offset]<<16 | fetch[offset+1]; - } else { // MOV.W - const unsigned int offset = 2 + disp; - local_constant[n] = fetch[offset]; - } - } else { - if (opcode_info & SH2_OPCODE_INFO_SETS_R0) { - local_constant[0] = 1; - } - if (opcode_info & SH2_OPCODE_INFO_SETS_Rn) { - local_constant[opcode>>8 & 0xF] = 1; - } - if (opcode_info & (SH2_OPCODE_INFO_ACCESS_POSTINC - | SH2_OPCODE_INFO_ACCESS_PREDEC)) { - if (opcode_info & SH2_OPCODE_INFO_ACCESSES_Rm) { - local_constant[opcode>>4 & 0xF] = 1; - } - if (opcode_info & SH2_OPCODE_INFO_ACCESSES_Rn) { - local_constant[opcode>>8 & 0xF] = 1; - } - if (opcode_info & SH2_OPCODE_INFO_ACCESSES_R15) { - local_constant[15] = 1; - } - } - } - - /* Now see if this is an optimizable call. */ - uint32_t target = 1; // 1 = not a subroutine call or unknown target - if ((opcode & 0xF000) == 0xB000) { // BSR label - int32_t disp = opcode & 0xFFF; - disp <<= 20; // Sign-extend - disp >>= 19; // And double - target = (address + 4) + disp; - } else if ((opcode & 0xF0FF) == 0x400B) { // JSR @Rn - const unsigned int n = opcode>>8 & 0xF; - if (local_constant[n]) { - target = local_constant[n]; - } - } - if (target != 1 - && optimize_fold_subroutine(state, start_address, address, - target, fetch[1], - pointer_map, local_constant, - &subroutine_native[block_len]) - ) { - word_info[block_len] |= WORD_INFO_FOLDABLE; - subroutine_target[block_len] = target; -#ifdef OPTIMIZE_LOOP_REGISTERS - /* Subroutine folding and loop optimization don't currently - * play together well, so disable loop optimization if we - * fold a subroutine into the current block. (FIXME: this - * is a loss if the loop has already ended; better to just - * not fold and break the block instead in that case?) */ - is_loop = 0; - can_optimize_loop = 0; -#endif - } - - } // if (optimization_flags & SH2_OPTIMIZE_FOLD_SUBROUTINES) - - /* Check whether this is an instruction with a delay slot. */ - - delay = ((opcode_info & SH2_OPCODE_INFO_BRANCH_DELAYED) != 0); - - /* Check whether this is an unconditional branch or similar - * instruction; when we get past its delay slot (if applicable), - * we'll check whether to end the block. */ - - at_uncond_branch |= - (((opcode_info & SH2_OPCODE_INFO_BRANCH_UNCOND) - && !(word_info[block_len] & WORD_INFO_FOLDABLE)) - || opcode == 0x001B); // SLEEP - - /* If we have a pending local branch, update the local constant - * table as appropriate. */ - - if (is_local_branch && !delay) { - is_local_branch = 0; - unsigned int reg; - if (local_branch_is_new) { - for (reg = 0; reg < 16; reg++) { - local_constant_per_insn[local_branch_target_index][reg] - = local_constant[reg]; - } - } else { - for (reg = 0; reg < 16; reg++) { - if (local_constant_per_insn[local_branch_target_index][reg] != local_constant[reg]) { - local_constant_per_insn[local_branch_target_index][reg] = 1; - } - } - } - } - - /* If we have a pending branch and we're past its delay slot - * (if applicable), update loop optimization state. */ - -#ifdef OPTIMIZE_LOOP_REGISTERS - at_branch |= - at_uncond_branch || (opcode_info & SH2_OPCODE_INFO_BRANCH_COND); - if (at_branch && !delay) { - at_branch = 0; - if (at_loop_branch) { - final_live_registers = loop_live_registers; - final_load_registers = loop_load_registers; - final_changed_registers = loop_changed_registers; - unsigned int reg; - for (reg = 0; reg < 16; reg++) { - if (pointer_map[reg] != reg) { - loop_invariant_pointers &= ~(1 << reg); - } - } - final_invariant_pointers = loop_invariant_pointers; - at_loop_branch = 0; - } -# if !defined(TRACE) && !defined(TRACE_STEALTH) && !defined(TRACE_LITE) - /* If this is a branch back to the beginning of the loop from - * the middle, followed by more loop body code, then any - * registers first set below this branch will still have the - * proper value on exit from the loop, assuming an exception - * handler interrupting the loop doesn't try to alter or rely - * on the loop's state. But this will cause traces (including - * TRACE_LITE) to report invalid register contents if the - * early branch is taken and stops due to the cycle limit - * before the register has been set at least once, so if we're - * tracing, we make an exception to our "don't change behavior - * with TRACE_STEALTH/TRACE_LITE" rule and set the noload - * register set here. If we're _not_ tracing, we omit this - * "else" and let the noload registers continue to accumulate. */ - else -# endif - if (!loop_noload_registers_set) { - loop_noload_registers = loop_changed_registers; - loop_noload_registers_set = 1; - } - } // if (at_branch && !delay) -#endif // OPTIMIZE_LOOP_REGISTERS - - /* If this is an instruction that loads SR (LDC ...,SR), terminate - * the block after the next instruction (since the SH-2 ignores - * interrupts between LDC and the following instruction--SH7604 - * manual page 76, section 4.6.2) to allow any potentially unmasked - * interrupts to be recognized. While the other LD[CS]/ST[CS] - * instructions also ignore interrupts for the following - * instruction, we don't terminate the block for them anyway, so - * we don't worry about them here. */ - - if ((opcode & 0xF0FF) == 0x4007 || (opcode & 0xF0FF) == 0x400E) { -#ifdef JIT_ACCURATE_LDC_SR_TIMING - if (block_len+1 >= max_len) { - /* We'll hit the block size limit after this instruction, - * so terminate the block _before_ the LDC and include it - * in the next block. If the following instruction is in a - * blacklisted address, we'll end up interpreting the LDC, - * which is fine too. */ - goto abort_scan; - } else { - end_block_next = 1; - } -#else - end_block = 1; -#endif - } - - /* If this instruction is the target of a preceding fall-through - * branch, update the word_info[] and is_branch_target[] tables - * to reflect that. - * - * IMPORTANT: Once this code is executed, it is CRITICAL that this - * instruction be included in the scanned block, or incorrect code - * will result! See the earlier code that sets at_fallthru for an - * explanation. */ - - if (at_fallthru) { -#ifdef JIT_DEBUG_VERBOSE - DMSG("Marking branch at 0x%08X as fall-through", - start_address + saved_fallthru_source*2); -#endif - word_info[saved_fallthru_source] |= WORD_INFO_FALLTHRU; - /* Also clear the branch target flag so we don't set a label - * (which would break the basic unit and cause an optimization - * barrier). */ - const uint32_t flag = 1 << (saved_fallthru_target % 32); - is_branch_target[saved_fallthru_target/32] &= ~flag; - } - - /* If we have a pending unconditional branch and we're past its - * delay slot (if applicable), check whether there are any branch - * targets beyond this address which could be part of the same - * block (i.e. are within the instruction limit as well as - * JIT_MAX_INSN_GAP). If there are, we'll continue translating at - * the first such address; otherwise we'll end the block here. - * (In !JIT_ALLOW_DISTANT_BRANCHES mode, we always stop unless the - * next instruction is a branch target.) */ - - if (at_uncond_branch && !delay && !end_block) { - at_uncond_branch = 0; - index = block_len + 1; - - /* If variable shift optimization is enabled, allow a BRAF - * followed by one or more shift/rotate instructions to fall - * through to the instruction following the shift sequence. */ -#ifdef OPTIMIZE_VARIABLE_SHIFTS - if ((fetch[-1] & 0xF0FF) == 0x0023) { // BRAF - unsigned int next_opcode = fetch[1]; - if ((next_opcode & 0xF0DE) == 0x4000 // SH[LA][LR] - || (next_opcode & 0xF0FE) == 0x4004 // ROT[LR] - ) { - const unsigned int shift_opcode = next_opcode; - do { - address += 2; - fetch++; - block_len++; - next_opcode = fetch[1]; - } while (next_opcode == shift_opcode); - } - } else -#endif - - if (!(is_branch_target[index/32] & (1 << (index % 32)))) { - end_block = 1; -#ifdef JIT_ALLOW_DISTANT_BRANCHES - /* See below for why the "-1" on max_len */ - const uint32_t gap_limit = block_len + JIT_MAX_INSN_GAP; - const uint32_t index_limit = (max_len-1 < gap_limit - ? max_len-1 : gap_limit); - const uint32_t address_limit = - start_address + (index_limit * 2); - const uint32_t first_valid = - (now_in_delay ? address : address+2); - index = (first_valid - start_address) / 2; - /* Search for a non-empty word, then find the first bit set - * in that word */ - uint32_t mask = 0xFFFFFFFF << (index % 32); - index /= 32; - for (; index < lenof(is_branch_target); index++) { - if (is_branch_target[index] & mask) { - break; - } - mask = 0xFFFFFFFF; - } - if (index < lenof(is_branch_target)) { - mask &= is_branch_target[index]; - index *= 32; - while (!(mask & 1)) { - mask >>= 1; - index++; - } - const uint32_t first_target = start_address + index*2; - if (first_target < address_limit) { - int skip_bytes = first_target - (address+2); - if (skip_bytes > 0) { - address += skip_bytes; - fetch += skip_bytes / 2; - block_len += skip_bytes / 2; - } - end_block = 0; - } - } -#endif - } // if next insn is not a branch target - } // if (at_uncond_branch && !delay && !end_block) - - /* Check whether we've hit the instruction limit. To avoid the - * potential for problems arising from an instruction with a delay - * slot crossing the limit, we stop one instruction early; if this - * instruction had a delay slot, the delay slot will still fall - * within the limit. (We could also explicitly check against - * (max_len+delay), but this way is both simpler and marginally - * faster.) However, if we're stopping after the following - * instruction due to an LDC SR, don't break early here. */ - - if (!end_block && !end_block_next && block_len+2 >= max_len) { -#ifdef JIT_DEBUG - DMSG("WARNING: Terminating block 0x%08X after 0x%08X due to" - " instruction limit (%d insns) or blacklist", - start_address, delay ? address+2 : address, max_len); -#endif - end_block = 1; - } - -#ifdef OPTIMIZE_VARIABLE_SHIFTS - - /* If this opcode begins a variable shift instruction sequence, - * skip the remaining instructions in the sequence. (Normally we - * don't alter scanning behavior for optimizations, but since - * variable shift sequences involve branches, we want to avoid - * marking the following instruction as a branch target--thus - * creating an optimization barrier--when the branches will be - * eliminated anyway.) However, we skip sequences starting with - * BRAF, since we handle them separately. */ - - if (!now_in_delay && (opcode & 0xF0FF) != 0x0023) { - unsigned int count_reg, count_max, shift_reg, type; - const uint8_t *cycles; - const unsigned int num_insns = - can_optimize_variable_shift(fetch, address, &count_reg, - &count_max, &shift_reg, &type, - &cycles); - if (num_insns) { - block_len += num_insns - 1; - fetch += num_insns - 1; - address += (num_insns - 1) * 2; - } - } - -#endif - - } // for (; !end_block || delay; address += 2, fetch++, block_len++) - - abort_scan: - - /* Record the final set of entry registers used as pointers. */ - - pointer_used &= 0xFFFF; - -#ifdef OPTIMIZE_LOOP_REGISTERS - /* If this block is a loop, update loop_*_registers with the values - * found at the end of the loop body, so we don't unnecessarily fix - * SH-2 registers that aren't used in the body of the loop; also add - * registers changed after any non-loop branch to the set of registers - * that must be preloaded. Otherwise, there's no point in attempting - * loop optimization, so clear the flag. */ - - if (is_loop) { - loop_live_registers = final_live_registers; - loop_load_registers = final_load_registers; - loop_changed_registers = final_changed_registers; - loop_invariant_pointers = final_invariant_pointers; - if (loop_noload_registers_set) { - loop_load_registers |= - (loop_changed_registers & ~loop_noload_registers); - } - } else { - can_optimize_loop = 0; - } -#endif - - /* All done! */ - return block_len; -} - -/*-----------------------------------------------------------------------*/ - -/** - * optimize_pointers: Check the current instruction to determine whether - * it accesses memory through a pointer register or modifies a register - * assumed to be a pointer. Helper function for scan_block(). - * - * [Parameters] - * start_address: Start address of block, or 1 for subroutine fold checks - * address: Address of current instruction - * opcode: Opcode of current instruction - * opcode_info: Information about current instruction - * pointer_map: pointer_map[] array pointer from scan_block() - * [Return value] - * None - */ -static inline void optimize_pointers( - uint32_t start_address, uint32_t address, unsigned int opcode, - uint32_t opcode_info, uint8_t pointer_map[16]) -{ - const unsigned int index = (address - start_address) / 2; - if (start_address != 1 - && (is_data_pointer_load[index/32] & (1 << (index % 32))) - ) { - - if ((opcode & 0xFF00) == 0xC700) { // MOVA - pointer_map[0] = 30; -#ifdef JIT_DEBUG_VERBOSE - DMSG("%08X marked as data pointer load for R0", address); -#endif - } else { - const unsigned int n = opcode>>8 & 0xF; - pointer_map[n] = 30; -#ifdef JIT_DEBUG - if (!(opcode_info & SH2_OPCODE_INFO_SETS_Rn)) { - DMSG("WARNING: %08X marked as data pointer load but does not" - " set Rn!", address); -# ifdef JIT_DEBUG_VERBOSE - } else { - DMSG("%08X marked as data pointer load for R%u", address, n); -# endif - } -#endif - } - - } else if ((opcode & 0xF00F) == 0x6003) { // MOV Rm,Rn - - const unsigned int n = opcode>>8 & 0xF; - const unsigned int m = opcode>>4 & 0xF; - pointer_map[n] = pointer_map[m]; - - } else if ((opcode & 0xFF00) == 0xC700) { // MOVA @(disp,PC),R0 - - pointer_map[0] = 30; - - } else if ((opcode & 0xF000) == 0x7000) { // ADD #imm,Rn - - /* This only modifies Rn by a small, fixed amount, so assume the - * pointer is still valid and don't clear pointer_map[n]. */ - - } else if ((opcode & 0xF00F) == 0x3008) { // SUB Rm,Rn - - const unsigned int m = opcode>>4 & 0xF; - const unsigned int n = opcode>>8 & 0xF; - if (pointer_map[m] == 31) { - /* If we're subtracting a non-pointer from a pointer, assume - * it's a pointer adjustment that leaves the pointer in Rn - * valid. (If Rn is already not a pointer, we don't need to - * do anything in the first place.) */ - } else { - pointer_map[n] = 31; - } - - } else if ((opcode & 0xF00F) == 0x300C) { // ADD Rm,Rn - - const unsigned int m = opcode>>4 & 0xF; - const unsigned int n = opcode>>8 & 0xF; - if (pointer_map[m] == 31) { - /* Like SUB Rm,Rn, we ignore ADD Rm,Rn where Rm is not a - * pointer on the assumption that it's a pointer adjustment. */ - } else if (pointer_map[n] == 31) { - /* Addition is commutative, unlike subtraction, so we could - * also have the case where Rm is a pointer and Rn is an - * adjustment, leaving a pointer value in Rn. Treat this case - * like MOV Rm,Rn where Rm is a pointer. */ - pointer_map[n] = pointer_map[m]; - } else { - pointer_map[n] = 31; - } - - } else { - - const unsigned int m = opcode>>4 & 0xF; - const unsigned int n = opcode>>8 & 0xF; - - if (opcode_info & SH2_OPCODE_INFO_SETS_R0) { - pointer_map[0] = 31; - } - if (opcode_info & SH2_OPCODE_INFO_ACCESSES_Rm) { - pointer_used |= 1 << pointer_map[m]; - } else if (opcode_info & SH2_OPCODE_INFO_ACCESSES_R0_Rm) { - if (pointer_map[0] == 30 - || (pointer_map[0] != 31 && (pointer_regs & 1<>8 & 0xF; - const int m = opcode>>4 & 0xF; - if (pointer_map[n] == 31 - || (pointer_map[n] != 30 && !(pointer_regs & (1<>8 & 0xF; - const unsigned int Rm = opcode>>4 & 0xF; - /* And other register indices */ - const unsigned int R0 = 0; - const unsigned int R15 = 15; - const unsigned int SR = state_cache_index(offsetof(SH2State,SR)); - const unsigned int GBR = state_cache_index(offsetof(SH2State,GBR)); - const unsigned int VBR = state_cache_index(offsetof(SH2State,VBR)); - const unsigned int MACH= state_cache_index(offsetof(SH2State,MACH)); - const unsigned int MACL= state_cache_index(offsetof(SH2State,MACL)); - const unsigned int PR = state_cache_index(offsetof(SH2State,PR)); - #define SR_GBR_VBR(x) ((x)==0 ? SR : (x)==1 ? GBR : VBR) - #define MACH_MACL_PR(x) ((x)==0 ? MACH : (x)==1 ? MACL : PR) - - if ((opcode & 0xF00F) == 0x0002) { // STC ...,Rn - this_used = 1<> 9) & 3]; -# endif - const uint32_t skip_index = ((target-2) - start_address) / 2; - if (!(is_branch_target[skip_index/32] & (1<<(skip_index%32)))) { - const unsigned int skipped_insn = fetch[(opcode & 0x400) ? 2 : 1]; - if ((skipped_insn & 0xF00F) == 0x6003 // MOV Rm,Rn - || (skipped_insn & 0xF000) == 0x7000 // ADD #imm,Rn - || (skipped_insn & 0xF000) == 0xE000 // MOV #imm,Rn - ) { - word_info[(address - start_address) / 2] |= WORD_INFO_SELECT; -# ifdef JIT_DEBUG_VERBOSE - DMSG("Converted %s to SELECT at %08X", mnemonic, address); -# endif - return 1; -# ifdef JIT_DEBUG_VERBOSE - } else { - DMSG("Failed to convert %s to SELECT at %08X (skipped opcode" - " is %04X)", mnemonic, address, skipped_insn); -# endif - } -# ifdef JIT_DEBUG_VERBOSE - } else { - DMSG("Failed to convert %s to SELECT at %08X (skipped instruction" - " at %08X is a branch target)", mnemonic, address, target-2); -# endif - } - } - return 0; -} - -#endif // OPTIMIZE_BRANCH_SELECT - -/*-----------------------------------------------------------------------*/ - -/** - * optimize_fold_subroutine: Determine whether the code sequence starting - * at the SH-2 address "target" qualifies as a foldable subroutine. If so, - * update the pointer_map[] array with any changes as a result of the - * subroutine. - * - * [Parameters] - * state: Processor state block pointer - * start_address: Start address of block - * address: Address of subroutine call - * target: Target address of subroutine call - * delay_slot: Instruction word in delay slot of subroutine call - * pointer_map: pointer_map[] array pointer from scan_block() - * local_constant: local_constant[] array pointer from scan_block() - * native_ret: Pointer to variable to receive native implementation - * function address if the routine is to be folded - * using a native implementation, NULL if the routine - * is to be folded by translating instructions - * [Return value] - * Nonzero if subroutine is foldable, else zero - */ -static int optimize_fold_subroutine( - SH2State *state, const uint32_t start_address, uint32_t address, - const uint32_t target, const uint16_t delay_slot, uint8_t pointer_map[16], - uint32_t local_constant[16], SH2NativeFunctionPointer *native_ret) -{ - const uint16_t *fetch_base = (const uint16_t *)fetch_pages[target >> 19]; - if (fetch_base == NULL) { - return 0; // Unfetchable, therefore unoptimizable - } - const uint16_t *fetch = - (const uint16_t *)((uintptr_t)fetch_base + target); - const uint16_t * const start = fetch; - const uint16_t * const limit = - fetch + OPTIMIZE_FOLD_SUBROUTINES_MAX_LENGTH + 2; - - /* First see if there's a native implementation which we can call. */ - - if (manual_optimization_callback) { - ignore_optimization_hints = 1; - const unsigned int hand_tuned_len = - (*manual_optimization_callback)(state, target, fetch, - native_ret, 1); - ignore_optimization_hints = 0; - if (hand_tuned_len > 0) { - if (*native_ret == NULL) { - return 0; // Folding was refused by the callback. - } -#ifdef JIT_DEBUG_VERBOSE - DMSG("Using hand-tuned code to fold subroutine at 0x%08X", target); -#endif - /* We assume all of R0-R7 have been destroyed. */ - unsigned int reg; - for (reg = 0; reg < 8; reg++) { - pointer_map[reg] = 31; - local_constant[reg] = 1; - } - return 1; - } - } - - /* Make a local copy of optimization state data, so we can revert if - * we discover that the subroutine can't be optimized. */ - - uint8_t saved_pointer_map[16]; - memcpy(saved_pointer_map, pointer_map, 16); - const uint16_t saved_pointer_used = pointer_used; - - /* Scan the delay slot, then each instruction in the subroutine. - * Branches (or similar instructions) are not permitted in delay - * slots, so we assume the instruction is a simple one. */ - - if (optimization_flags & SH2_OPTIMIZE_POINTERS) { - optimize_pointers(start_address, address+2, delay_slot, - get_opcode_info(delay_slot), pointer_map); - } - - for (address = target; - !(fetch >= start+2 && fetch[-2] == 0x000B); - address += 2, fetch++ - ) { - if (fetch > limit) { - goto fail; // Subroutine is too long - } - const uint16_t opcode = *fetch; - const uint32_t opcode_info = get_opcode_info(opcode); - if (opcode == 0x000B) { // RTS - /* Ignore; we'll catch it after the delay slot */ - } else if (opcode_info & (SH2_OPCODE_INFO_BRANCH_UNCOND - | SH2_OPCODE_INFO_BRANCH_COND)) { - goto fail; // Branches break optimization - } else if ((optimization_flags & SH2_OPTIMIZE_POINTERS_MAC) - && (opcode & 0xB00F) == 0x000F) { // MAC.[WL] - const int n = opcode>>8 & 0xF; - const int m = opcode>>4 & 0xF; - if (pointer_map[n] == 31 - || (pointer_map[n] != 30 && !(pointer_regs & (1<running = 1; - -#ifdef JIT_PROFILE - const uint32_t start_cycles = state->cycles; -#endif - -#ifdef JIT_DEBUG_INTERPRET_RTL - -# ifdef JIT_PROFILE - entry->exec_time += -# endif - rtl_execute_block(entry->rtl, state); - -#else // !JIT_DEBUG_INTERPRET_RTL - - const void (*native_code)(SH2State *state) = entry->native_code; - -# ifdef JIT_PROFILE - /* For systems that have an efficient way to measure execution time - * (such as a performance counter register), we could use that to - * update entry->exec_time. On the PSP, the MIPS Count register is - * only accessible in kernel mode, so we're stuck with using a syscall - * to a kernel routine that costs hundreds of cycles (where a short - * block of code may finish in as few as 10 cycles), and we can't even - * get a cycle-accurate count. Oh well... it's better than nothing. */ -# if defined(PSP) - const uint32_t start = sceKernelGetSystemTimeLow(); -# endif -# endif - (*native_code)(state); -# ifdef JIT_PROFILE -# if defined(PSP) - entry->exec_time += sceKernelGetSystemTimeLow() - start; -# else - entry->exec_time++; // Default is to just count each call as 1 time unit -# endif -# endif - -#endif // JIT_DEBUG_INTERPRET_RTL - -#ifdef JIT_PROFILE - entry->call_count++; - entry->cycle_count += state->cycles - start_cycles; -#endif - - entry->running = 0; -} - -/*************************************************************************/ - -/** - * decode_insn: Decode a single SH-2 instruction. Implements - * translate_insn() using the shared decoder core. - * - * [Parameters] - * fetch: Pointer to instruction to decode - * state: SH-2 processor state - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * recursing: Nonzero if this is a recursive decode, else zero - * is_last: Nonzero if this is the last instruction of a recursive - * decode, else zero - * [Return value] - * Decoded SH-2 opcode (nonzero) on success, zero on error - * [Notes] - * Since the opcode 0x0000 is invalid and scan_block() prevents invalid - * opcodes from being included in a block to be translated, the return - * value of this routine will always be nonzero on success. - */ - -#define DECODE_INSN_INLINE inline -#define DECODE_INSN_PARAMS \ - const uint16_t *fetch, SH2State *state, JitEntry *entry, \ - const unsigned int state_reg, const int recursing, const int is_last - -#ifdef TRACE -# define TRACE_WRITEBACK_FOR_RECURSIVE_DECODE \ - ASSERT(writeback_state_cache(entry, state_reg, 1)) -#else -# define TRACE_WRITEBACK_FOR_RECURSIVE_DECODE /*nothing*/ -#endif -#define RECURSIVE_DECODE(address,is_last) do { \ - const uint32_t saved_PC = jit_PC; \ - jit_PC = (address); \ - if (UNLIKELY(!translate_insn(state, entry, state_reg, 1, (is_last)))) { \ - return 0; \ - } \ - TRACE_WRITEBACK_FOR_RECURSIVE_DECODE; \ - jit_PC = saved_PC; \ -} while (0) - -#include "sh2-core.i" - -/*-----------------------------------------------------------------------*/ - -/** - * translate_insn: Translate a single SH-2 instruction at the current - * translation address into one or more equivalent RTL instructions. - * - * [Parameters] - * state: SH-2 processor state - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * recursing: Nonzero if this is a recursive decode (for inserting - * copies of instructions from other locations), else zero - * is_last: Nonzero if this is the last instruction in a recursively - * decoded sequence, else zero - * [Return value] - * Nonzero on success, zero on error - */ -static int translate_insn(SH2State *state, JitEntry *entry, - unsigned int state_reg, int recursing, int is_last) -{ - /* Get a fetch pointer for the current PC */ - const uint16_t *fetch_base = (const uint16_t *)fetch_pages[cur_PC >> 19]; - PRECOND(fetch_base != NULL, return 0); - const uint16_t *fetch = (const uint16_t *)((uintptr_t)fetch_base + cur_PC); - - /* Process the instruction */ - const unsigned int opcode = - decode_insn(fetch, state, entry, state_reg, recursing, is_last); - if (UNLIKELY(!opcode)) { - return 0; - } - - return 1; -} - -/*************************************************************************/ - -#ifdef JIT_BRANCH_PREDICT_STATIC - -/** - * add_static_branch_terminator: Add a terminator for a static branch when - * using static branch prediction. Code will be added to retrieve or look - * up the target address and branch to it if possible. - * - * [Parameters] - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * address: Branch target address (in SH-2 address space) - * index: entry->static_predict[] index to use for static prediction - * [Return value] - * Nonzero on success, zero on failure - */ -static int add_static_branch_terminator(JitEntry *entry, - unsigned int state_reg, - uint32_t address, unsigned int index) -{ - CREATE_LABEL(label_not_predicted); - CREATE_LABEL(label_return); - - /* Load the address of the BranchTargetInfo we're using */ - DEFINE_REG(bti); - MOVEA(bti, &entry->static_predict[index]); - - /* Load relevant values early to mitigate load stalls (very MIPSy) */ - DEFINE_REG(predicted_entry); - LOAD_PTR(predicted_entry, bti, offsetof(BranchTargetInfo,entry)); - DECLARE_REG(cycles); - LOAD_STATE_ALLOC(cycles, cycles); - DECLARE_REG(cycle_limit); - LOAD_STATE_ALLOC(cycle_limit, cycle_limit); - DEFINE_REG(native_target); - LOAD_PTR(native_target, bti, offsetof(BranchTargetInfo,native_target)); - DEFINE_REG(can_continue); - SLTS(can_continue, cycles, cycle_limit); - - /* If we already have a prediction, jump to it (or return if we're out - * of cycles) */ - GOTO_IF_Z(label_not_predicted, predicted_entry); - STORE_STATE_PTR(current_entry, predicted_entry); - GOTO_IF_Z(label_return, can_continue); - RETURN_TO(native_target); - - /* Look up the translated block for this address, then return. For - * simplicity (and to keep code size down), we don't try too hard to - * optimize this case; we'll make up the time in future runs */ - DEFINE_LABEL(label_not_predicted); - DEFINE_REG(addr_reg); - MOVEI(addr_reg, address); - DEFINE_REG(ptr_update_branch_target); - MOVEA(ptr_update_branch_target, update_branch_target); - DEFINE_REG(new_entry); - CALL(new_entry, bti, addr_reg, ptr_update_branch_target); - STORE_STATE_PTR(current_entry, new_entry); - GOTO_IF_Z(label_return, new_entry); - DEFINE_REG(new_target); -#ifdef JIT_DEBUG_INTERPRET_RTL - LOAD_PTR(new_target, new_entry, offsetof(JitEntry,rtl)); -#else - LOAD_PTR(new_target, new_entry, offsetof(JitEntry,native_code)); -#endif - STORE_PTR(bti, new_target, offsetof(BranchTargetInfo,native_target)); - - DEFINE_LABEL(label_return); - RETURN(); - - clear_state_cache(0); - return 1; -} - -#endif // JIT_BRANCH_PREDICT_STATIC - -/*************************************************************************/ - -#if JIT_BRANCH_PREDICTION_SLOTS > 0 - -/** - * update_branch_target: Find the translated block, if any, corresponding - * to the given address and update the given branch target structure with - * the found block. - * - * [Parameters] - * bti: BranchTargetInfo structure to update - * address: Branch target address - * [Return value] - * Translated block found, or NULL if none was found - */ -static FASTCALL JitEntry *update_branch_target(BranchTargetInfo *bti, - uint32_t address) -{ - JitEntry *new_entry = jit_find(address); - if (new_entry) { - if (bti->entry) { - bti->next->prev = bti->prev; - bti->prev->next = bti->next; - } - bti->target = address; - bti->entry = new_entry; - bti->next = new_entry->pred_ref_head.next; - bti->prev = &new_entry->pred_ref_head; - bti->next->prev = bti; - bti->prev->next = bti; - } - return new_entry; -} - -#endif // JIT_BRANCH_PREDICTION_SLOTS > 0 - -/*************************************************************************/ -/************************ Other utility routines *************************/ -/*************************************************************************/ - -/** - * btcache_lookup: Search the branch target cache for the given SH-2 - * address. - * - * [Parameters] - * address: SH-2 address to search for - * [Return value] - * Corresponding RTL label, or zero if the address could not be found - */ -static uint32_t btcache_lookup(uint32_t address) -{ - /* Search backwards from the current instruction so we can handle short - * loops quickly; note that btcache_index is now pointing to where the - * _next_ instruction will go */ - const int current = (btcache_index + (lenof(btcache)-1)) % lenof(btcache); - int index = current; - do { - if (btcache[index].sh2_address == address) { - return btcache[index].rtl_label; - } - index--; - if (UNLIKELY(index < 0)) { - index = lenof(btcache) - 1; - } - } while (index != current); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * record_unresolved_branch: Record the given branch target and native - * offset in an empty slot in the unresolved branch table. If there are - * no empty slots, purge the oldest (lowest native offset) entry. - * - * [Parameters] - * entry: Block being translated - * sh2_target: Branch target address in SH2 address space - * target_label: RTL label number to be defined at branch target - * [Return value] - * Nonzero on success, zero on error - */ -static int record_unresolved_branch(const JitEntry *entry, uint32_t sh2_target, - unsigned int target_label) -{ - PRECOND(entry != NULL, return 0); - - int oldest = 0; - int i; - for (i = 0; i < lenof(unres_branches); i++) { - if (unres_branches[i].sh2_target == 0) { - oldest = i; - break; - } else if (unres_branches[i].target_label - < unres_branches[oldest].target_label) { - oldest = i; - } - } - if (UNLIKELY(unres_branches[oldest].sh2_target != 0)) { -#ifdef JIT_DEBUG - DMSG("WARNING: Unresolved branch table full, dropping branch to PC" - " 0x%08X (RTL label %u)", unres_branches[oldest].sh2_target, - unres_branches[oldest].target_label); -#endif - /* Add a JUMP fallback for this entry in the middle of the code - * stream, since we have nowhere else to put it; use a temporary - * label to branch past it in the normal code flow */ - DEFINE_REG(temp_reg); - CREATE_LABEL(temp_label); - GOTO_LABEL(temp_label); - DEFINE_LABEL(unres_branches[oldest].target_label); - RETURN(); - DEFINE_LABEL(temp_label); - } - unres_branches[oldest].sh2_target = sh2_target; - unres_branches[oldest].target_label = target_label; - return 1; -} - -/*************************************************************************/ - -/** - * writeback_state_cache: Write all cached state block values to memory. - * Does nothing (and returns success) if OPTIMIZE_STATE_BLOCK is not - * defined. - * - * [Parameters] - * entry: Block being translated - * state_reg: RTL register holding state block pointer - * flush_fixed: Nonzero to flush dirty fixed-register fields to memory - * [Return value] - * Nonzero on success, zero on error - */ -static int writeback_state_cache(const JitEntry *entry, unsigned int state_reg, - int flush_fixed) -{ - PRECOND(entry != NULL, return 0); - -#ifdef OPTIMIZE_STATE_BLOCK - - if (dirty_SR_T) { - const int index_SR = state_cache_index(offsetof(SH2State,SR)); - DECLARE_REG(old_SR); - if (state_cache[index_SR].rtlreg) { - old_SR = state_cache[index_SR].rtlreg; - } else { - ALLOC_REG(old_SR); - LOAD_W(old_SR, state_reg, offsetof(SH2State,SR)); - } - DECLARE_REG(new_SR); - if (state_cache[index_SR].fixed) { - new_SR = old_SR; - } else { - ALLOC_REG(new_SR); - } - BFINS(new_SR, old_SR, cached_SR_T, SR_T_SHIFT, 1); - state_cache[index_SR].rtlreg = new_SR; - state_dirty |= 1 << index_SR; - dirty_SR_T = 0; - } - - unsigned int index; - for (index = 0; index < lenof(state_cache); index++) { - if ((state_dirty & (1 << index)) - || (flush_fixed && state_cache[index].flush) - ) { - DECLARE_REG(rtlreg); - if (index == state_cache_index(offsetof(SH2State,PC)) - && cached_PC != 0 - ) { - ALLOC_REG(rtlreg); - MOVEI(rtlreg, cached_PC); - cached_PC = 0; - state_cache[index].rtlreg = rtlreg; - state_cache[index].offset = 0; - } else if (state_cache[index].offset != 0) { - if (state_cache[index].fixed) { - rtlreg = state_cache[index].rtlreg; - } else { - ALLOC_REG(rtlreg); - } - ADDI(rtlreg, state_cache[index].rtlreg, - state_cache[index].offset); - state_cache[index].rtlreg = rtlreg; - if (index < 16) { - pointer_status[index].rtl_ptrreg = 0; - } - if (index == 15 && stack_pointer) { - ADDI(stack_pointer, stack_pointer, - state_cache[index].offset); - } - state_cache[index].offset = 0; - } else { - rtlreg = state_cache[index].rtlreg; - } - if (!state_cache[index].fixed || flush_fixed) { - STORE_W(state_reg, rtlreg, state_cache_field(index)); - state_dirty &= ~(1 << index); - if (index == state_cache_index(offsetof(SH2State,PC))) { - stored_PC = 0; - } -# ifdef TRACE_STEALTH - if (index < 23) { - APPEND(NOP, 0, 0xB0000000 | index<<16, 0, 0); - } -# endif - } - } - } - -#endif // OPTIMIZE_STATE_BLOCK - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * clear_state_cache: Clear all cached state block registers. Does - * nothing if OPTIMIZE_STATE_BLOCK is not defined. - * - * [Parameters] - * clear_fixed: Nonzero to clear fixed registers from the cache as well, - * zero to leave them in the cache - * [Return value] - * None - */ -static void clear_state_cache(int clear_fixed) -{ -#ifdef OPTIMIZE_STATE_BLOCK - if (clear_fixed) { -# ifdef JIT_DEBUG - if (UNLIKELY(state_dirty) || UNLIKELY(dirty_SR_T)) { - DMSG("WARNING: Clearing dirty state fields! (dirty=%08X SR_T=%d)", - state_dirty, dirty_SR_T); - } -# endif - memset(state_cache, 0, sizeof(state_cache)); - state_dirty = 0; - } else { - unsigned int index; -# ifdef JIT_DEBUG - uint32_t nonfixed = 0; - for (index = 0; index < lenof(state_cache); index++) { - if (!state_cache[index].fixed) { - nonfixed |= 1<>3 & 7) >= 5 ? 0 : (CMDCOLR&0x7FF)<<16) \ - | ((CMDPMOD>>3 & 15) << 27) | 0x80000000) -#define HASHKEY_TEXTURE_TILE(tilesize,address,pixfmt,color_base,color_ofs,transparent) \ - (tilesize>>4 | (address>>3 & ~1) \ - | (pixfmt >= 3 ? 0 : ((color_ofs|color_base)&0x7FF)<<16) \ - | (pixfmt<<27) | (transparent<<30)) -#define HASH_TEXTURE(key) ((key) % TEXCACHE_HASH_SIZE) - -/*************************************************************************/ - -/* Local routine declarations */ - -static TexInfo *alloc_texture(uint32_t key, uint32_t hash, int persistent); -static TexInfo *find_texture(uint32_t key, unsigned int *hash_ret); -static void load_texture(const TexInfo *tex); -static void *alloc_pixdata(uint32_t size); -static void *alloc_vram(uint32_t size); - -/* Force GCC to inline the texture/CLUT caching functions, to save the - * expense of register save/restore and optimize constant cases - * (particularly for tile loading). */ - -__attribute__((always_inline)) static inline int cache_sprite( - TexInfo *tex, uint16_t CMDSRCA, uint16_t CMDPMOD, uint16_t CMDCOLR, - uint16_t pixel_mask, unsigned int width, unsigned int height, int rofs, - int gofs, int bofs, int persistent); -__attribute__((always_inline)) static inline int cache_tile( - TexInfo *tex, uint32_t address, unsigned int width, unsigned int height, - unsigned int stride, int array, int pixfmt, int transparent, - uint16_t color_base, uint16_t color_ofs, int rofs, int gofs, int bofs, - int persistent); - -__attribute__((always_inline)) static inline int alloc_texture_pixels( - TexInfo *tex, unsigned int width, unsigned int height, unsigned int psm, - int persistent); - -__attribute__((always_inline)) static inline int gen_clut( - TexInfo *tex, unsigned int size, uint32_t color_base, uint8_t color_ofs, - int rofs, int gofs, int bofs, int transparent, int endcodes, - int can_shadow, int persistent); -__attribute__((always_inline)) static inline int gen_clut_t4ind( - TexInfo *tex, const uint8_t *color_lut, uint16_t pixel_mask, - int rofs, int gofs, int bofs, int transparent, int endcodes, - int persistent); - -__attribute__((always_inline)) static inline int cache_texture_t4( - TexInfo *tex, const uint8_t *src, - unsigned int width, unsigned int height, unsigned int stride); -__attribute__((always_inline)) static inline int cache_texture_t8( - TexInfo *tex, const uint8_t *src, uint8_t pixmask, - unsigned int width, unsigned int height, unsigned int stride); -__attribute__((always_inline)) static inline int cache_texture_t16( - TexInfo *tex, const uint8_t *src, uint32_t color_base, - unsigned int width, unsigned int height, unsigned int stride, - int rofs, int gofs, int bofs, int transparent); -__attribute__((always_inline)) static inline int cache_texture_16( - TexInfo *tex, const uint8_t *src, - unsigned int width, unsigned int height, unsigned int stride, - int rofs, int gofs, int bofs, int transparent); -__attribute__((always_inline)) static inline int cache_texture_32( - TexInfo *tex, const uint8_t *src, - unsigned int width, unsigned int height, unsigned int stride, - int rofs, int gofs, int bofs, int transparent); - -/*************************************************************************/ -/************************** Interface routines ***************************/ -/*************************************************************************/ - -/** - * texcache_reset: Reset the texture cache, including all persistent - * textures. - * - * [Parameters] - * None - * [Return value] - * None - */ -void texcache_reset(void) -{ - memset(tex_table_persistent, 0, sizeof(tex_table_persistent)); - memset(tex_table_transient, 0, sizeof(tex_table_transient)); - tex_buffer_nextfree_persistent = 0; - tex_buffer_nextfree_transient = lenof(tex_buffer) - 1; - pixdata_cache_next_alloc = 0; - - unsigned int i; - for (i = 0; i < lenof(clut_cache); i++) { - unsigned int j; - for (j = 0; j < lenof(clut_cache[i]); j++) { - clut_cache[i][j].size = 0; - } - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * texcache_clean: Clean all transient textures from the texture cache. - * Persistent textures are not affected. - * - * [Parameters] - * None - * [Return value] - * None - */ -void texcache_clean(void) -{ - memset(tex_table_transient, 0, sizeof(tex_table_transient)); - tex_buffer_nextfree_transient = lenof(tex_buffer) - 1; - - unsigned int i; - for (i = 0; i < lenof(clut_cache); i++) { - unsigned int j; - for (j = 0; j < lenof(clut_cache[i]); j++) { - clut_cache[i][j].size = 0; - } - } -} - -/*************************************************************************/ - -/** - * texcache_cache_sprite: Cache the given sprite texture if it has not - * been cached already. Returns a texture key for later use in loading the - * texture. The texture width must be a multiple of 8. - * - * [Parameters] - * cmd: VDP1 command structure - * pixel_mask: Mask to apply to paletted pixel data - * width, height: Size of texture (in pixels) - * persistent: Nonzero to cache this texture persistently across - * frames, zero to cache the texture for this frame only - * [Return value] - * Texture key (zero on error) - */ -uint32_t texcache_cache_sprite(const vdp1cmd_struct *cmd, - uint16_t pixel_mask, - unsigned int width, unsigned int height, - int persistent) -{ - const uint32_t tex_key = - HASHKEY_TEXTURE_SPRITE(cmd->CMDSRCA, cmd->CMDPMOD, cmd->CMDCOLR); - uint32_t tex_hash; - TexInfo *tex = find_texture(tex_key, &tex_hash); - - if (tex) { - /* Already cached, so just generate a CLUT if needed and return the - * texture key. */ - if (tex->clut_dynamic) { - const int transparent = !(cmd->CMDPMOD & 0x40); - const int endcodes = !(cmd->CMDPMOD & 0x80); - const uint32_t color_base = (Vdp2Regs->CRAOFB & 0x0070) << 4; - switch (cmd->CMDPMOD>>3 & 7) { - case 0: - gen_clut(tex, 16, (color_base + cmd->CMDCOLR) & 0x7F0, - cmd->CMDCOLR & 0x00F, vdp1_rofs, vdp1_gofs, vdp1_bofs, - transparent, endcodes, - ((cmd->CMDCOLR | 0xF) & pixel_mask) == pixel_mask, 0); - break; - case 1: - gen_clut_t4ind(tex, Vdp1Ram + (cmd->CMDCOLR << 3), pixel_mask, - vdp1_rofs, vdp1_gofs, vdp1_bofs, - transparent, endcodes, 0); - break; - case 2: - gen_clut(tex, 64, (color_base + cmd->CMDCOLR) & 0x7C0, - cmd->CMDCOLR & 0x03F, vdp1_rofs, vdp1_gofs, vdp1_bofs, - transparent, endcodes, - ((cmd->CMDCOLR | 0x3F) & pixel_mask) == pixel_mask, 0); - break; - case 3: - gen_clut(tex, 128, - (color_base + cmd->CMDCOLR) & 0x780, - cmd->CMDCOLR & 0x07F, vdp1_rofs, vdp1_gofs, vdp1_bofs, - transparent, endcodes, - ((cmd->CMDCOLR | 0x7F) & pixel_mask) == pixel_mask, 0); - break; - case 4: - gen_clut(tex, 256, (color_base + cmd->CMDCOLR) & 0x700, - cmd->CMDCOLR & 0x0FF, vdp1_rofs, vdp1_gofs, vdp1_bofs, - transparent, endcodes, - ((cmd->CMDCOLR | 0xFF) & pixel_mask) == pixel_mask, 0); - break; - } - } - return tex_key; - } // if (tex) - - tex = alloc_texture(tex_key, tex_hash, persistent); - if (UNLIKELY(!tex)) { - DMSG("Texture buffer full, can't cache"); - return 0; - } - if (UNLIKELY(!cache_sprite(tex, cmd->CMDSRCA, cmd->CMDPMOD, cmd->CMDCOLR, - pixel_mask, width, height, - vdp1_rofs, vdp1_gofs, vdp1_bofs, persistent))) { - if (persistent) { - tex_table_persistent[tex_hash] = tex->next; - tex_buffer_nextfree_persistent--; - return texcache_cache_sprite(cmd, pixel_mask, width, height, 0); - } else { - return 0; - } - } - - return tex_key; -} - -/*-----------------------------------------------------------------------*/ - -/** - * texcache_load_sprite: Load the sprite texture indicated by the given - * texture key. - * - * [Parameters] - * key: Texture key returned by texcache_cache_sprite - * [Return value] - * None - */ -void texcache_load_sprite(uint32_t key) -{ - TexInfo *tex = find_texture(key, NULL); - if (UNLIKELY(!tex)) { - DMSG("No texture found for key %08X", (int)key); - return; - } - - load_texture(tex); -} - -/*-----------------------------------------------------------------------*/ - -/** - * texcache_load_tile: Load the specified 8x8 or 16x16 tile texture into - * the GE registers for drawing, first caching the texture if necessary. - * - * [Parameters] - * tilesize: Pixel size (width and height) of tile, either 8 or 16 - * address: Tile data address within VDP2 RAM - * pixfmt: Tile pixel format - * transparent: Nonzero if index 0 or alpha 0 should be transparent - * color_base: Color table base (for indexed formats) - * color_ofs: Color table offset (for indexed formats) - * rofs, gofs, bofs: Color offset values for texture - * persistent: Nonzero to cache this texture persistently across - * frames, zero to cache the texture for this - * frame only - * [Return value] - * None - */ -void texcache_load_tile(int tilesize, uint32_t address, - int pixfmt, int transparent, - uint16_t color_base, uint16_t color_ofs, - int rofs, int gofs, int bofs, int persistent) -{ - const uint32_t tex_key = - HASHKEY_TEXTURE_TILE(tilesize, address, pixfmt, color_base, - color_ofs, transparent); - uint32_t tex_hash; - TexInfo *tex = find_texture(tex_key, &tex_hash); - - if (tex) { - if (tex->clut_dynamic) { - if (pixfmt == 0) { - gen_clut(tex, 16, - (color_base + color_ofs) & 0x7F0, color_ofs & 0x00F, - rofs, gofs, bofs, transparent, 0, 0, 0); - } else { // pixfmt == 1 - gen_clut(tex, 256, - (color_base + color_ofs) & 0x700, color_ofs & 0x0FF, - rofs, gofs, bofs, transparent, 0, 0, 0); - } - } - } else { // !tex - tex = alloc_texture(tex_key, tex_hash, persistent); - if (UNLIKELY(!tex)) { - DMSG("Texture buffer full, can't cache"); - return; - } - int ok; - if (tilesize == 16) { - ok = cache_tile(tex, address, 16, 16, 8, 2, pixfmt, - transparent, color_base, color_ofs, - rofs, gofs, bofs, persistent); - } else { - ok = cache_tile(tex, address, 8, 8, 8, 1, pixfmt, - transparent, color_base, color_ofs, - rofs, gofs, bofs, persistent); - } - if (UNLIKELY(!ok)) { - if (persistent) { - tex_table_persistent[tex_hash] = tex->next; - tex_buffer_nextfree_persistent--; - return texcache_load_tile(tilesize, address, pixfmt, - transparent, color_base, color_ofs, - rofs, gofs, bofs, 0); - } else { - return; - } - } - } // if (tex) - - /* Load the texture data (and color table, if appropriate). */ - load_texture(tex); -} - -/*-----------------------------------------------------------------------*/ - -/** - * texcache_load_bitmap: Load the specified bitmap texture into the GE - * registers for drawing, first caching the texture if necessary. The - * texture width must be a multiple of 8. - * - * [Parameters] - * address: Bitmap data address within VDP2 RAM - * width, height: Size of texture (in pixels) - * stride: Line size of source data (in pixels) - * pixfmt: Bitmap pixel format - * transparent: Nonzero if index 0 or alpha 0 should be transparent - * color_base: Color table base (for indexed formats) - * color_ofs: Color table offset (for indexed formats) - * rofs, gofs, bofs: Color offset values for texture - * persistent: Nonzero to cache this texture persistently across - * frames, zero to cache the texture for this - * frame only - * [Return value] - * None - */ -void texcache_load_bitmap(uint32_t address, unsigned int width, - unsigned int height, unsigned int stride, - int pixfmt, int transparent, - uint16_t color_base, uint16_t color_ofs, - int rofs, int gofs, int bofs, int persistent) -{ - const uint32_t tex_key = - HASHKEY_TEXTURE_TILE(8, address, pixfmt, color_base, - color_ofs, transparent); - uint32_t tex_hash; - TexInfo *tex = find_texture(tex_key, &tex_hash); - - if (tex) { - if (tex->clut_dynamic) { - if (pixfmt == 0) { - gen_clut(tex, 16, - (color_base + color_ofs) & 0x7F0, color_ofs & 0x00F, - rofs, gofs, bofs, transparent, 0, 0, 0); - } else { // pixfmt == 1 - gen_clut(tex, 256, - (color_base + color_ofs) & 0x700, color_ofs & 0x0FF, - rofs, gofs, bofs, transparent, 0, 0, 0); - } - } - } else { // !tex - tex = alloc_texture(tex_key, tex_hash, persistent); - if (UNLIKELY(!tex)) { - DMSG("Texture buffer full, can't cache"); - return; - } - if (UNLIKELY(!cache_tile(tex, address, width, height, stride, 1, - pixfmt, transparent, color_base, color_ofs, - rofs, gofs, bofs, persistent))) { - if (persistent) { - tex_table_persistent[tex_hash] = tex->next; - tex_buffer_nextfree_persistent--; - return texcache_load_bitmap(address, width, height, stride, - pixfmt, transparent, color_base, - color_ofs, rofs, gofs, bofs, 0); - } else { - return; - } - } - } // if (!tex) - - /* Load the texture data (and color table, if appropriate). */ - load_texture(tex); -} - -/*************************************************************************/ -/**************************** Local routines *****************************/ -/*************************************************************************/ - -/** - * alloc_texture: Allocate a new texture entry and insert it into the hash - * table. The entry's data fields (other than those for hash table - * management) are _not_ initialized. - * - * [Parameters] - * key: Hash key for texture - * hash: Hash index for texture (== HASH_TEXTURE(key), passed in - * separately so precomputed values can be reused) - * persistent: Nonzero if a persistent texture, zero if a transient texture - * [Return value] - * Allocated texture entry, or NULL on failure (table full) - */ -static TexInfo *alloc_texture(uint32_t key, uint32_t hash, int persistent) -{ - if (persistent) { - if (UNLIKELY(tex_buffer_nextfree_persistent > tex_buffer_nextfree_transient)) { - return NULL; - } - TexInfo *tex = &tex_buffer[tex_buffer_nextfree_persistent++]; - tex->next = tex_table_persistent[hash]; - tex_table_persistent[hash] = tex; - tex->key = key; - return tex; - } else { - if (UNLIKELY(tex_buffer_nextfree_transient < tex_buffer_nextfree_persistent)) { - return NULL; - } - TexInfo *tex = &tex_buffer[tex_buffer_nextfree_transient--]; - tex->next = tex_table_transient[hash]; - tex_table_transient[hash] = tex; - tex->key = key; - return tex; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * find_texture: Return the texture corresponding to the given texture - * key, or NULL if no such texture is cached. - * - * [Parameters] - * key: Texture hash key - * hash_ret: Pointer to variable to receive hash index, or NULL if unneeded - * [Return value] - * Cached texture, or NULL if none - */ -static TexInfo *find_texture(uint32_t key, unsigned int *hash_ret) -{ - const uint32_t hash = HASH_TEXTURE(key); - if (hash_ret) { - *hash_ret = hash; - } - - TexInfo *tex; - for (tex = tex_table_persistent[hash]; tex != NULL; tex = tex->next) { - if (tex->key == key) { - return tex; - } - } - for (tex = tex_table_transient[hash]; tex != NULL; tex = tex->next) { - if (tex->key == key) { - return tex; - } - } - return NULL; -} - -/*-----------------------------------------------------------------------*/ - -/** - * load_texture: Load the given texture into the GE texture registers. - * - * [Parameters] - * tex: Texture to load - * [Return value] - * None - */ -static void load_texture(const TexInfo *tex) -{ - if (tex->clut_address) { - guClutMode(GU_PSM_8888, 0, tex->clut_size-1, 0); - guClutLoad(tex->clut_size/8, tex->clut_address); - } - guTexFlush(); - guTexMode(tex->pixfmt, 0, 0, /*swizzled*/ 1); - guTexImage(0, tex->width, tex->height, tex->stride, tex->vram_address); -} - -/*************************************************************************/ - -/** - * alloc_pixdata: Allocate memory from the persistent pixel data cache - * buffer, returning a pointer to the area in the uncached address region - * (0x4nnnnnnn). - * - * [Parameters] - * size: Amount of memory to allocate, in bytes - * [Return value] - * Pointer to allocated memory, or NULL on failure (out of memory) - */ -static void *alloc_pixdata(uint32_t size) -{ - if (UNLIKELY(pixdata_cache_next_alloc + size > sizeof(pixdata_cache))) { - return NULL; - } - void *ptr = &pixdata_cache[pixdata_cache_next_alloc]; - pixdata_cache_next_alloc += (size + 63) & -64; - return (void *)((uint32_t)ptr | 0x40000000); -} - -/*-----------------------------------------------------------------------*/ - -/** - * alloc_vram: Allocate memory from the spare VRAM area, returning a - * pointer to the area in the uncached address region (0x4nnnnnnn). - * - * [Parameters] - * size: Amount of memory to allocate, in bytes - * [Return value] - * Pointer to allocated memory, or NULL on failure (out of memory) - */ -static void *alloc_vram(uint32_t size) -{ - void *ptr = display_alloc_vram(size); - if (UNLIKELY(!ptr)) { - return NULL; - } - return (void *)((uint32_t)ptr | 0x40000000); -} - -/*************************************************************************/ - -/** - * cache_sprite: Cache a texture from sprite (VDP1) memory. Implements - * caching code for texcache_cache_sprite(). - * - * [Parameters] - * tex: TexInfo structure for caching texture - * CMDSRCA, CMDPMOD, CMDCOLR: Values of like-named fields in VDP1 command - * pixel_mask: Mask to apply to paletted pixel data - * width, height: Size of texture (in pixels) - * rofs, gofs, bofs: Color offset values for texture - * persistent: Nonzero if a persistent texture, zero if a - * transient texture - * [Return value] - * Nonzero on success, zero on error - */ -static inline int cache_sprite( - TexInfo *tex, uint16_t CMDSRCA, uint16_t CMDPMOD, uint16_t CMDCOLR, - uint16_t pixel_mask, unsigned int width, unsigned int height, int rofs, - int gofs, int bofs, int persistent) -{ - const uint32_t address = CMDSRCA << 3; - const int pixfmt = CMDPMOD>>3 & 7; - const int transparent = !(CMDPMOD & 0x40); - const int endcodes = !(CMDPMOD & 0x80); - uint32_t color_base = (Vdp2Regs->CRAOFB & 0x0070) << 4; - - if (UNLIKELY(address + (pixfmt<=1 ? width/2 : pixfmt<=4 ? width : width*2) * height > 0x80000)) { - DMSG("%dx%d texture at 0x%X extends past end of VDP1 RAM" - " and will be incorrectly drawn", width, height, address); - } - - const uint8_t *src = Vdp1Ram + address; - switch (pixfmt) { - case 0: - tex->clut_dynamic = persistent; - CMDCOLR &= pixel_mask; - return gen_clut(tex, 16, - (color_base + CMDCOLR) & 0x7F0, CMDCOLR & 0x00F, - rofs, gofs, bofs, transparent, endcodes, - ((CMDCOLR | 0xF) & pixel_mask) == pixel_mask, 0) - && alloc_texture_pixels(tex, width, height, GU_PSM_T4, persistent) - && cache_texture_t4(tex, src, width, height, width); - case 1: { - const int clut_persistent = - persistent && (int16_t)T1ReadWord(Vdp1Ram, CMDCOLR<<3) < 0; - tex->clut_dynamic = persistent && !clut_persistent; - return gen_clut_t4ind(tex, Vdp1Ram + (CMDCOLR << 3), pixel_mask, - rofs, gofs, bofs, transparent, endcodes, - clut_persistent) - && alloc_texture_pixels(tex, width, height, GU_PSM_T4, persistent) - && cache_texture_t4(tex, src, width, height, width); - } - case 2: - tex->clut_dynamic = persistent; - return gen_clut(tex, 64, - (color_base + CMDCOLR) & 0x7C0, CMDCOLR & 0x03F, - rofs, gofs, bofs, transparent, endcodes, - ((CMDCOLR | 0x3F) & pixel_mask) == pixel_mask, 0) - && alloc_texture_pixels(tex, width, height, GU_PSM_T8, persistent) - && cache_texture_t8(tex, src, 0x3F, width, height, width); - case 3: - tex->clut_dynamic = persistent; - return gen_clut(tex, 128, - (color_base + CMDCOLR) & 0x780, CMDCOLR & 0x07F, - rofs, gofs, bofs, transparent, endcodes, - ((CMDCOLR | 0x7F) & pixel_mask) == pixel_mask, 0) - && alloc_texture_pixels(tex, width, height, GU_PSM_T8, persistent) - && cache_texture_t8(tex, src, 0x7F, width, height, width); - case 4: - tex->clut_dynamic = persistent; - return gen_clut(tex, 256, - (color_base + CMDCOLR) & 0x700, CMDCOLR & 0x0FF, - rofs, gofs, bofs, transparent, endcodes, - ((CMDCOLR | 0xFF) & pixel_mask) == pixel_mask, 0) - && alloc_texture_pixels(tex, width, height, GU_PSM_T8, persistent) - && cache_texture_t8(tex, src, 0xFF, width, height, width); - default: - DMSG("unsupported pixel mode %d, assuming 16-bit", pixfmt); - /* Fall through to... */ - case 5: - tex->clut_dynamic = 0; - return alloc_texture_pixels(tex, width, height, GU_PSM_8888, persistent) - && cache_texture_16(tex, src, width, height, width, - rofs, gofs, bofs, transparent); - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * cache_tile: Cache a texture from tile (VDP2) memory. Implements common - * code for texcache_load_tile() and texcache_load_bitmap(). - * - * [Parameters] - * tex: TexInfo structure for caching texture - * address: Bitmap data address within VDP2 RAM - * width, height: Size of texture (in pixels) - * stride: Line size of source data (in pixels) - * array: Number of VDP2 cells across and down texture - * (2 for 16x16 tiles, 1 otherwise) - * pixfmt: Bitmap pixel format - * transparent: Nonzero if index 0 or alpha 0 should be transparent - * color_base: Color table base (for indexed formats) - * color_ofs: Color table offset (for indexed formats) - * rofs, gofs, bofs: Color offset values for texture - * persistent: Nonzero if a persistent texture, zero if a - * transient texture - * [Return value] - * Nonzero on success, zero on error - */ -static inline int cache_tile( - TexInfo *tex, uint32_t address, unsigned int width, unsigned int height, - unsigned int stride, int array, int pixfmt, int transparent, - uint16_t color_base, uint16_t color_ofs, int rofs, int gofs, int bofs, - int persistent) -{ - if (UNLIKELY(address + (pixfmt==0 ? width/2 : pixfmt==1 ? width*1 : pixfmt<=3 ? width*2 : width*4) * height > 0x80000)) { - DMSG("%dx%d texture at 0x%X extends past end of VDP2 RAM" - " and will be incorrectly drawn", width, height, address); - } - - if (pixfmt == 0) { - tex->clut_dynamic = persistent; - if (!gen_clut(tex, 16, - (color_base + color_ofs) & 0x7F0, color_ofs & 0x00F, - rofs, gofs, bofs, transparent, 0, 0, 0)) { - return 0; - } - } else if (pixfmt == 1) { - tex->clut_dynamic = persistent; - if (!gen_clut(tex, 256, - (color_base + color_ofs) & 0x700, color_ofs & 0x0FF, - rofs, gofs, bofs, transparent, 0, 0, 0)) { - return 0; - } - } else { - tex->clut_dynamic = 0; - } - - const uint8_t *src = Vdp2Ram + address; - - if (array == 2) { - - switch (pixfmt) { - - case 0: { - if (!alloc_texture_pixels(tex, 16, 16, GU_PSM_T4, persistent)) { - return 0; - } - void * const saved_vram_address = tex->vram_address; - - /* Fake out the texture_cache_X() functions so they don't try - * to draw boundary pixels. */ - tex->width = tex->height = 8; - - unsigned int i; - for (i = 0; i < 4; i++, src += 32) { - tex->vram_address = (void *)((uintptr_t)saved_vram_address - + (i%2 ? 4 : 0) - + (i/2 ? 128 : 0)); - if (!cache_texture_t4(tex, src, 8, 8, 8)) { - return 0; - } - } - - tex->width = tex->height = 16; - tex->vram_address = saved_vram_address; - return 1; - } // case 0 - - case 1: { - if (!alloc_texture_pixels(tex, 16, 16, GU_PSM_T8, persistent)) { - return 0; - } - void * const saved_vram_address = tex->vram_address; - tex->width = tex->height = 8; - unsigned int i; - for (i = 0; i < 4; i++, src += 64) { - tex->vram_address = (void *)((uintptr_t)saved_vram_address - + (i%2 ? 8 : 0) - + (i/2 ? 128 : 0)); - if (!cache_texture_t8(tex, src, 0xFF, 8, 8, 8)) { - return 0; - } - } - tex->width = tex->height = 16; - tex->vram_address = saved_vram_address; - return 1; - } // case 1 - - case 2: { - if (!alloc_texture_pixels(tex, 16, 16, GU_PSM_8888, persistent)) { - return 0; - } - void * const saved_vram_address = tex->vram_address; - tex->width = tex->height = 8; - const uint32_t tilesize = (pixfmt < 4) ? 128 : 256; - unsigned int i; - for (i = 0; i < 4; i++, src += tilesize) { - tex->vram_address = (void *)((uintptr_t)saved_vram_address - + (i%2 ? 32 : 0) - + (i/2 ? 512 : 0)); - if (!cache_texture_t16(tex, src, color_base, 8, 8, 8, - rofs, gofs, bofs, transparent)) { - return 0; - } - } - tex->width = tex->height = 16; - tex->vram_address = saved_vram_address; - return 1; - } // case 2 - - case 3: { - if (!alloc_texture_pixels(tex, 16, 16, GU_PSM_8888, persistent)) { - return 0; - } - void * const saved_vram_address = tex->vram_address; - tex->width = tex->height = 8; - const uint32_t tilesize = (pixfmt < 4) ? 128 : 256; - unsigned int i; - for (i = 0; i < 4; i++, src += tilesize) { - tex->vram_address = (void *)((uintptr_t)saved_vram_address - + (i%2 ? 32 : 0) - + (i/2 ? 512 : 0)); - if (!cache_texture_16(tex, src, 8, 8, 8, - rofs, gofs, bofs, transparent)) { - return 0; - } - } - tex->width = tex->height = 16; - tex->vram_address = saved_vram_address; - return 1; - } // case 3 - - case 4: { - if (!alloc_texture_pixels(tex, 16, 16, GU_PSM_8888, persistent)) { - return 0; - } - void * const saved_vram_address = tex->vram_address; - tex->width = tex->height = 8; - const uint32_t tilesize = (pixfmt < 4) ? 128 : 256; - unsigned int i; - for (i = 0; i < 4; i++, src += tilesize) { - tex->vram_address = (void *)((uintptr_t)saved_vram_address - + (i%2 ? 32 : 0) - + (i/2 ? 512 : 0)); - if (!cache_texture_32(tex, src, 8, 8, 8, - rofs, gofs, bofs, transparent)) { - return 0; - } - } - tex->width = tex->height = 16; - tex->vram_address = saved_vram_address; - return 1; - } // case 4 - - default: - DMSG("Invalid tile pixel format %d", pixfmt); - return 0; - - } // switch (pixfmt) - - } else { // array == 1 - - switch (pixfmt) { - case 0: - return alloc_texture_pixels(tex, width, height, GU_PSM_T4, - persistent) - && cache_texture_t4(tex, src, width, height, stride); - case 1: - return alloc_texture_pixels(tex, width, height, GU_PSM_T8, - persistent) - && cache_texture_t8(tex, src, 0xFF, width, height, stride); - case 2: - return alloc_texture_pixels(tex, width, height, GU_PSM_8888, - persistent) - && cache_texture_t16(tex, src, color_base, width, height, - stride, rofs, gofs, bofs, transparent); - case 3: - return alloc_texture_pixels(tex, width, height, GU_PSM_8888, - persistent) - && cache_texture_16(tex, src, width, height, stride, - rofs, gofs, bofs, transparent); - case 4: - return alloc_texture_pixels(tex, width, height, GU_PSM_8888, - persistent) - && cache_texture_32(tex, src, width, height, stride, - rofs, gofs, bofs, transparent); - default: - DMSG("Invalid tile pixel format %d", pixfmt); - return 0; - } - - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/** - * alloc_texture_pixels: Allocate memory for a texture's pixel data, and - * fill in the vram_address, width, height, stride, and pixfmt fields of - * the TexInfo structure. - * - * [Parameters] - * tex: TexInfo structure for texture - * width: Texture width in pixels - * height: Texture height in pixels - * psm: Native texture pixel format (GU_PSM_*) - * persistent: Nonzero if a persistent texture, zero if a transient texture - * [Return value] - * Nonzero on success, zero on error - */ -static inline int alloc_texture_pixels( - TexInfo *tex, unsigned int width, unsigned int height, unsigned int psm, - int persistent) -{ - /* Calculate the power-of-2 sizes we need for registering the texture - * with the GE. */ - unsigned int texwidth = 1 << (32 - __builtin_clz(width-1)); - unsigned int texheight = 1 << (32 - __builtin_clz(height-1)); - - /* If the texture width or height aren't powers of 2, we add an extra - * 1-pixel border on the right and bottom edges to avoid graphics - * glitches resulting from the GE trying to read one pixel beyond the - * edge of the texture data. */ - unsigned int outwidth = width + (width != texwidth ? 1 : 0); - unsigned int outheight = height + (height != texheight ? 1 : 0); - - unsigned int stride, linebytes; - if (psm == GU_PSM_T4) { - stride = (outwidth+31) & -32; - linebytes = stride/2; - } else if (psm == GU_PSM_T8) { - stride = (outwidth+15) & -16; - linebytes = stride; - } else { // Must be GU_PSM_8888, since we don't use any others - stride = (outwidth+3) & -4; - linebytes = stride*4; - } - - const unsigned int size = linebytes * ((outheight+7) & -8); - if (persistent) { - tex->vram_address = alloc_pixdata(size); - } else { - tex->vram_address = alloc_vram(size); - } - if (UNLIKELY(!tex->vram_address)) { - DMSG("%s buffer full, can't cache", - persistent ? "Persistent cache" : "DRAM"); - return 0; - } - - tex->width = texwidth; - tex->height = texheight; - tex->stride = stride; - tex->pixfmt = psm; - return 1; -} - -/*************************************************************************/ -/*************************************************************************/ - -/** - * gen_clut: Generate a color lookup table for a 4-bit or 8-bit indexed - * texture. - * - * [Parameters] - * tex: TexInfo structure for color table - * size: Number of color entries to generate - * color_base: Base color index - * color_ofs: Color index offset ORed together with pixel - * rofs, gofs, bofs: Color offset values for texture - * transparent: Nonzero if pixel value 0 should be transparent - * endcodes: Nonzero if pixel value 0b11...11 should be transparent - * can_shadow: Nonzero if pixel value 0b11...10 is a shadow pixel - * persistent: Nonzero if a persistent texture, zero if a - * transient texture - * [Return value] - * Nonzero on success, zero on error - */ -static inline int gen_clut( - TexInfo *tex, unsigned int size, uint32_t color_base, uint8_t color_ofs, - int rofs, int gofs, int bofs, int transparent, int endcodes, - int can_shadow, int persistent) -{ - tex->clut_size = size; - - if (!endcodes && !transparent && !can_shadow && !color_ofs - && !rofs && !gofs && !bofs - ) { - /* There are no changes to apply to the palette, so just use the - * global CLUT directly. */ - tex->clut_address = &global_clut_32[color_base + color_ofs]; - return 1; - } - - const uint32_t color_set = (rofs & 0x1FF) << 0 - | (gofs & 0x1FF) << 9 - | (bofs & 0x1FF) << 18 - | (transparent ? 1<<27 : 0) - | (endcodes ? 1<<28 : 0); - const unsigned int cache_slot = color_base >> 4; - unsigned int cache_entry; - for (cache_entry = 0; cache_entry < CLUT_ENTRIES; cache_entry++) { - if (clut_cache[cache_slot][cache_entry].size == 0) { - /* This entry is empty, so we'll generate a palette and store - * it here. */ - clut_cache[cache_slot][cache_entry].size = size; - clut_cache[cache_slot][cache_entry].color_ofs = color_ofs; - clut_cache[cache_slot][cache_entry].color_set = color_set; - break; - } else if (clut_cache[cache_slot][cache_entry].size == size - && clut_cache[cache_slot][cache_entry].color_ofs == color_ofs - && clut_cache[cache_slot][cache_entry].color_set == color_set){ - /* Found a match, so return it. */ - tex->clut_address = - clut_cache[cache_slot][cache_entry].clut_address; - return 1; - } - } - if (UNLIKELY(cache_entry >= CLUT_ENTRIES)) { - DMSG("Warning: no free entries for CLUT cache slot 0x%02X", cache_slot); - } - - if (persistent) { - tex->clut_address = alloc_pixdata(size*4); - } else { - tex->clut_address = alloc_vram(size*4); - } - if (UNLIKELY(!tex->clut_address)) { - DMSG("%s buffer full, can't cache CLUT", - persistent ? "Persistent cache" : "VRAM"); - return 0; - } - if (cache_entry < CLUT_ENTRIES) { - clut_cache[cache_slot][cache_entry].clut_address = tex->clut_address; - } - - uint32_t *dest = (uint32_t *)tex->clut_address; - int i; - - /* Apply the color offset values to transparent or shadow pixels as - * well; this prevents dark rims around interpolated textures when - * positive color offsets are applied. */ - const uint32_t transparent_rgb = (rofs>0 ? rofs<< 0 : 0) - | (gofs>0 ? gofs<< 8 : 0) - | (bofs>0 ? bofs<<16 : 0); - - if (transparent) { - *dest++ = 0x00<<24 | transparent_rgb; - i = 1; - } else { - i = 0; - } - - const uint32_t *clut_32 = &global_clut_32[color_base]; - if (rofs | gofs | bofs) { - for (; i < size; i++, dest++) { - uint32_t color = clut_32[i | color_ofs]; - *dest = adjust_color_32_32(color, rofs, gofs, bofs); - } - } else { - for (; i < size; i++, dest++) { - *dest = clut_32[i | color_ofs]; - } - } - - if (endcodes) { - dest[-1] = 0x00<<24 | transparent_rgb; - } - - if (can_shadow) { - dest[-1] = 0x80<<24 | transparent_rgb; - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * gen_clut_t4ind: Generate a color lookup table for a 4-bit indirect - * indexed texture. - * - * [Parameters] - * tex: TexInfo structure for color table - * color_lut: Pointer to VDP1 color lookup table - * pixel_mask: Mask to apply to palette indices in lookup table - * rofs, gofs, bofs: Color offset values for texture - * transparent: Nonzero if pixel value 0 should be transparent - * endcodes: Nonzero if pixel value 0b11...11 should be transparent - * persistent: Nonzero if a persistent texture, zero if a - * transient texture - * [Return value] - * Nonzero on success, zero on error - */ -static inline int gen_clut_t4ind( - TexInfo *tex, const uint8_t *color_lut, uint16_t pixel_mask, - int rofs, int gofs, int bofs, int transparent, int endcodes, - int persistent) -{ - tex->clut_size = 16; - - if (persistent) { - tex->clut_address = alloc_pixdata(16*4); - } else { - tex->clut_address = alloc_vram(16*4); - } - if (UNLIKELY(!tex->clut_address)) { - DMSG("%s buffer full, can't cache CLUT", - persistent ? "Persistent cache" : "VRAM"); - return 0; - } - - const uint16_t *src = (const uint16_t *)color_lut; - uint32_t *dest = (uint32_t *)tex->clut_address; - const uint32_t *clut_32 = global_clut_32; - - if (rofs | gofs | bofs) { - - const uint32_t transparent_rgb = (rofs>0 ? rofs<< 0 : 0) - | (gofs>0 ? gofs<< 8 : 0) - | (bofs>0 ? bofs<<16 : 0); - const uint16_t *top; - if (endcodes) { - dest[15] = 0x00<<24 | transparent_rgb; - top = src + 15; - } else { - top = src + 16; - } - if (transparent) { - src++; - *dest++ = 0x00<<24 | transparent_rgb; - } - - for (; src < top; src++, dest++) { - uint16_t color16 = BSWAP16(*src); - if (color16 & 0x8000) { - *dest = adjust_color_16_32(color16, rofs, gofs, bofs); - } else { - color16 &= pixel_mask; - if (color16 == pixel_mask - 1) { - *dest = 0x80<<24 | transparent_rgb; - } else { - *dest = adjust_color_32_32(clut_32[color16], - rofs, gofs, bofs); - } - } - } - - } else { // No color offset - - const uint16_t *top; - if (endcodes) { - dest[15] = 0x00000000; - top = src + 15; - } else { - top = src + 16; - } - if (transparent) { - src++; - *dest++ = 0x00000000; - } - - for (; src < top; src++, dest++) { - uint16_t color16 = BSWAP16(*src); - if (color16 & 0x8000) { - *dest = 0xFF000000 | (color16 & 0x7C00) << 9 - | (color16 & 0x03E0) << 6 - | (color16 & 0x001F) << 3; - } else { - color16 &= pixel_mask; - if (color16 == pixel_mask - 1) { - *dest = 0x80000000; - } else { - *dest = clut_32[color16]; - } - } - } - - } - - return 1; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * A note about the texture caching routines-- - * - * While the texture caching logic is divided into five separate caching - * routines (one for each pixel type: 4/8/16-bit indexed and 16/32-bit - * direct color), each with multiple branches conditioned on the texture - * parameters, all of them follow the same basic flow: - * - * for (each row of 16-byte-by-8-line swizzled blocks) { - * for (each swizzled block in the row) { - * for (each of 8 lines in the block) { - * read enough input pixels for 16 output bytes - * convert and store pixels into the output buffer - * } - * } - * if (width is not a power of 2) { - * copy rightmost column one pixel to the right - * } - * } - * if (height is not a power of 2) { - * copy bottommost row one pixel down - * } - * - * The reason for all the repetition is to help the compiler optimize - * specific common cases, particularly for tile caching in which case the - * size parameters are all a constant 8 or 16. - */ - -/*************************************************************************/ - -/** - * cache_texture_t4: Cache a 4-bit indexed texture. - * - * [Parameters] - * tex: TexInfo structure for texture - * src: Pointer to VDP1/VDP2 texture data - * width, height: Size of texture (in pixels) - * stride: Line size of source data (in pixels) - * [Return value] - * Nonzero on success, zero on error - */ -static inline int cache_texture_t4( - TexInfo *tex, const uint8_t *src, - unsigned int width, unsigned int height, unsigned int stride) -{ - const int outwidth = width + (width == tex->width ? 0 : 1); - const int outheight = height + (height == tex->height ? 0 : 1); - - /* Cache the value of this locally so we don't have to load it on - * every loop. */ - const unsigned int tex_stride = tex->stride; - - uint8_t *dest = (uint8_t *)tex->vram_address; - - if (tex_stride == 32) { - - if (width == 8) { - uint8_t *dest_top = dest + (height * 16); - for (; dest != dest_top; src += stride/2, dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - ((uint32_t *)dest)[0] = ((src_word0 & 0x0F0F0F0F) << 4) - | ((src_word0 >> 4) & 0x0F0F0F0F); - } - } else if (width == 16) { - uint8_t *dest_top = dest + (height * 16); - for (; dest != dest_top; src += stride/2, dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - const uint32_t src_word1 = ((const uint32_t *)src)[1]; - ((uint32_t *)dest)[0] = ((src_word0 & 0x0F0F0F0F) << 4) - | ((src_word0 >> 4) & 0x0F0F0F0F); - ((uint32_t *)dest)[1] = ((src_word1 & 0x0F0F0F0F) << 4) - | ((src_word1 >> 4) & 0x0F0F0F0F); - } - } else { - uint8_t *dest_top = dest + (height * 16); - for (; dest != dest_top; src += stride/2, dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - const uint32_t src_word1 = ((const uint32_t *)src)[1]; - const uint32_t src_word2 = ((const uint32_t *)src)[2]; - const uint32_t src_word3 = ((const uint32_t *)src)[3]; - ((uint32_t *)dest)[0] = ((src_word0 & 0x0F0F0F0F) << 4) - | ((src_word0 >> 4) & 0x0F0F0F0F); - ((uint32_t *)dest)[1] = ((src_word1 & 0x0F0F0F0F) << 4) - | ((src_word1 >> 4) & 0x0F0F0F0F); - ((uint32_t *)dest)[2] = ((src_word2 & 0x0F0F0F0F) << 4) - | ((src_word2 >> 4) & 0x0F0F0F0F); - ((uint32_t *)dest)[3] = ((src_word3 & 0x0F0F0F0F) << 4) - | ((src_word3 >> 4) & 0x0F0F0F0F); - if (width != 32) { - dest[width/2] = dest[width/2-1] >> 4; // Copy last pixel - } - } - } - - if (outheight > height) { // Copy last line - ((uint32_t *)dest)[0] = ((uint32_t *)dest)[-4]; - ((uint32_t *)dest)[1] = ((uint32_t *)dest)[-3]; - ((uint32_t *)dest)[2] = ((uint32_t *)dest)[-2]; - ((uint32_t *)dest)[3] = ((uint32_t *)dest)[-1]; - } - - } else { // tex_stride > 32 - - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*4 - tex_stride/2) { - uint8_t *dest_top = dest + tex_stride*4; - for (; dest != dest_top; src += 16) { - const uint8_t *line_src = src; - uint8_t *line_end = dest + 128; - for (; dest != line_end; line_src += stride/2, dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)line_src)[0]; - const uint32_t src_word1 = ((const uint32_t *)line_src)[1]; - const uint32_t src_word2 = ((const uint32_t *)line_src)[2]; - const uint32_t src_word3 = ((const uint32_t *)line_src)[3]; - ((uint32_t *)dest)[0] = ((src_word0 & 0x0F0F0F0F) << 4) - | ((src_word0 >> 4) & 0x0F0F0F0F); - ((uint32_t *)dest)[1] = ((src_word1 & 0x0F0F0F0F) << 4) - | ((src_word1 >> 4) & 0x0F0F0F0F); - ((uint32_t *)dest)[2] = ((src_word2 & 0x0F0F0F0F) << 4) - | ((src_word2 >> 4) & 0x0F0F0F0F); - ((uint32_t *)dest)[3] = ((src_word3 & 0x0F0F0F0F) << 4) - | ((src_word3 >> 4) & 0x0F0F0F0F); - } - } - if (outwidth > width) { - uint8_t *eol_ptr = dest - 128 + ((width/2) & 15); - const int eol_ofs = (width & 31) ? -1 : -128 + 15; - uint8_t *eol_top = eol_ptr + 128; - for (; eol_ptr != eol_top; eol_ptr += 16) { - *eol_ptr = eol_ptr[eol_ofs] >> 4; - } - } - } - - if (outheight > height) { - if ((height & 7) != 0) { - dest = dest - tex_stride*4 + (height & 7)*16; - src = dest - 16; - } else { - src = dest - tex_stride*4 + 7*16; - } - uint8_t *dest_top = dest + tex_stride*4; - for (; dest < dest_top; src += 128, dest += 128) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - const uint32_t src_word1 = ((const uint32_t *)src)[1]; - const uint32_t src_word2 = ((const uint32_t *)src)[2]; - const uint32_t src_word3 = ((const uint32_t *)src)[3]; - ((uint32_t *)dest)[0] = src_word0; - ((uint32_t *)dest)[1] = src_word1; - ((uint32_t *)dest)[2] = src_word2; - ((uint32_t *)dest)[3] = src_word3; - } - } - - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * cache_texture_t8: Cache an 8-bit indexed texture. - * - * [Parameters] - * tex: TexInfo structure for texture - * src: Pointer to VDP1/VDP2 texture data - * pixmask: Pixel data mask - * width, height: Size of texture (in pixels) - * stride: Line size of source data (in pixels) - * [Return value] - * Nonzero on success, zero on error - */ -static inline int cache_texture_t8( - TexInfo *tex, const uint8_t *src, uint8_t pixmask, - unsigned int width, unsigned int height, unsigned int stride) -{ - const int outwidth = width + (width == tex->width ? 0 : 1); - const int outheight = height + (height == tex->height ? 0 : 1); - - const unsigned int tex_stride = tex->stride; - uint8_t *dest = (uint8_t *)tex->vram_address; - - if (pixmask != 0xFF) { - - const uint32_t pixmask32 = pixmask * 0x01010101; - if (stride == 8) { - unsigned int y; - for (y = 0; y < height; y++, src += 8, dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - const uint32_t src_word1 = ((const uint32_t *)src)[1]; - ((uint32_t *)dest)[0] = src_word0 & pixmask32; - ((uint32_t *)dest)[1] = src_word1 & pixmask32; - } - } else if (stride == 16) { - uint8_t *dest_top = dest + (height * stride); - for (; dest != dest_top; dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - const uint32_t src_word1 = ((const uint32_t *)src)[1]; - const uint32_t src_word2 = ((const uint32_t *)src)[2]; - const uint32_t src_word3 = ((const uint32_t *)src)[3]; - ((uint32_t *)dest)[0] = src_word0 & pixmask32; - ((uint32_t *)dest)[1] = src_word1 & pixmask32; - ((uint32_t *)dest)[2] = src_word2 & pixmask32; - ((uint32_t *)dest)[3] = src_word3 & pixmask32; - } - } else { // stride > 16 - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*8 - tex_stride) { - uint8_t *dest_top = dest + tex_stride*8; - for (; dest != dest_top; src += 16) { - const uint8_t *line_src = src; - uint8_t *line_end = dest + 128; - for (; dest != line_end; line_src += stride, dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)line_src)[0]; - const uint32_t src_word1 = ((const uint32_t *)line_src)[1]; - const uint32_t src_word2 = ((const uint32_t *)line_src)[2]; - const uint32_t src_word3 = ((const uint32_t *)line_src)[3]; - ((uint32_t *)dest)[0] = src_word0 & pixmask32; - ((uint32_t *)dest)[1] = src_word1 & pixmask32; - ((uint32_t *)dest)[2] = src_word2 & pixmask32; - ((uint32_t *)dest)[3] = src_word3 & pixmask32; - } - } - if (outwidth > width) { - uint8_t *eol_ptr = dest - 128 + (width & 15); - const int eol_ofs = (width & 15) ? -1 : -128 + 15; - uint8_t *eol_top = eol_ptr + 128; - for (; eol_ptr != eol_top; eol_ptr += 16) { - *eol_ptr = eol_ptr[eol_ofs]; - } - } - } - } - - } else { // pixmask == 0xFF - - if (stride == 8) { - unsigned int y; - for (y = 0; y < height; y++, src += 8, dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - const uint32_t src_word1 = ((const uint32_t *)src)[1]; - ((uint32_t *)dest)[0] = src_word0; - ((uint32_t *)dest)[1] = src_word1; - } - } else if (stride == 16) { - uint8_t *dest_top = dest + (height * stride); - for (; dest != dest_top; dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - const uint32_t src_word1 = ((const uint32_t *)src)[1]; - const uint32_t src_word2 = ((const uint32_t *)src)[2]; - const uint32_t src_word3 = ((const uint32_t *)src)[3]; - ((uint32_t *)dest)[0] = src_word0; - ((uint32_t *)dest)[1] = src_word1; - ((uint32_t *)dest)[2] = src_word2; - ((uint32_t *)dest)[3] = src_word3; - } - } else { // stride > 16 - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*8 - tex_stride) { - uint8_t *dest_top = dest + tex_stride*8; - for (; dest != dest_top; src += 16) { - const uint8_t *line_src = src; - uint8_t *line_end = dest + 128; - for (; dest != line_end; line_src += stride, dest += 16) { - const uint32_t src_word0 = ((const uint32_t *)line_src)[0]; - const uint32_t src_word1 = ((const uint32_t *)line_src)[1]; - const uint32_t src_word2 = ((const uint32_t *)line_src)[2]; - const uint32_t src_word3 = ((const uint32_t *)line_src)[3]; - ((uint32_t *)dest)[0] = src_word0; - ((uint32_t *)dest)[1] = src_word1; - ((uint32_t *)dest)[2] = src_word2; - ((uint32_t *)dest)[3] = src_word3; - } - } - if (outwidth > width) { - uint8_t *eol_ptr = dest - 128 + (width & 15); - const int eol_ofs = (width & 15) ? -1 : -128 + 15; - uint8_t *eol_top = eol_ptr + 128; - for (; eol_ptr != eol_top; eol_ptr += 16) { - *eol_ptr = eol_ptr[eol_ofs]; - } - } - } - } - - } // if (pixmask != 0xFF) - - if (outheight > height) { - if (tex_stride == 16) { - ((uint32_t *)dest)[0] = ((uint32_t *)dest)[-4]; - ((uint32_t *)dest)[1] = ((uint32_t *)dest)[-3]; - ((uint32_t *)dest)[2] = ((uint32_t *)dest)[-2]; - ((uint32_t *)dest)[3] = ((uint32_t *)dest)[-1]; - } else { - if ((height & 7) != 0) { - dest = dest - tex_stride*8 + (height & 7)*16; - src = dest - 16; - } else { - src = dest - tex_stride*8 + 7*16; - } - uint8_t *dest_top = dest + tex_stride*8; - for (; dest < dest_top; src += 128, dest += 128) { - const uint32_t src_word0 = ((const uint32_t *)src)[0]; - const uint32_t src_word1 = ((const uint32_t *)src)[1]; - const uint32_t src_word2 = ((const uint32_t *)src)[2]; - const uint32_t src_word3 = ((const uint32_t *)src)[3]; - ((uint32_t *)dest)[0] = src_word0; - ((uint32_t *)dest)[1] = src_word1; - ((uint32_t *)dest)[2] = src_word2; - ((uint32_t *)dest)[3] = src_word3; - } - } - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * cache_texture_t16: Cache a 16-bit indexed texture. - * - * [Parameters] - * tex: TexInfo structure for texture - * src: Pointer to VDP1/VDP2 texture data - * color_base: Base color index - * width, height: Size of texture (in pixels) - * stride: Line size of source data (in pixels) - * rofs, gofs, bofs: Color offset values for texture - * transparent: Nonzero if pixel value 0 should be transparent - * [Return value] - * Nonzero on success, zero on error - */ -static inline int cache_texture_t16( - TexInfo *tex, const uint8_t *src, uint32_t color_base, - unsigned int width, unsigned int height, unsigned int stride, - int rofs, int gofs, int bofs, int transparent) -{ - const int outwidth = width + (width == tex->width ? 0 : 1); - const int outheight = height + (height == tex->height ? 0 : 1); - - const unsigned int tex_stride = tex->stride; - uint32_t *dest = (uint32_t *)tex->vram_address; - const uint32_t *clut_32 = &global_clut_32[color_base]; - - if (rofs | gofs | bofs) { - - const uint32_t transparent_pixel = 0x00000000 - | (rofs>0 ? rofs<< 0 : 0) - | (gofs>0 ? gofs<< 8 : 0) - | (bofs>0 ? bofs<<16 : 0); - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*16 - width*2, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 8) { - const uint16_t *line_src = (const uint16_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const uint16_t pixel0 = BSWAP16(line_src[0]); - const uint16_t pixel1 = BSWAP16(line_src[1]); - const uint16_t pixel2 = BSWAP16(line_src[2]); - const uint16_t pixel3 = BSWAP16(line_src[3]); - dest[0] = (transparent && !pixel0) ? transparent_pixel - : adjust_color_32_32(clut_32[pixel0 & 0x7FF], - rofs, gofs, bofs); - dest[1] = (transparent && !pixel1) ? transparent_pixel - : adjust_color_32_32(clut_32[pixel1 & 0x7FF], - rofs, gofs, bofs); - dest[2] = (transparent && !pixel2) ? transparent_pixel - : adjust_color_32_32(clut_32[pixel2 & 0x7FF], - rofs, gofs, bofs); - dest[3] = (transparent && !pixel3) ? transparent_pixel - : adjust_color_32_32(clut_32[pixel3 & 0x7FF], - rofs, gofs, bofs); - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } else if (transparent) { - - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*16 - width*2, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 8) { - const uint16_t *line_src = (const uint16_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const uint16_t pixel0 = BSWAP16(line_src[0]); - const uint16_t pixel1 = BSWAP16(line_src[1]); - const uint16_t pixel2 = BSWAP16(line_src[2]); - const uint16_t pixel3 = BSWAP16(line_src[3]); - dest[0] = (pixel0 == 0) ? 0 : clut_32[pixel0 & 0x7FF]; - dest[1] = (pixel1 == 0) ? 0 : clut_32[pixel1 & 0x7FF]; - dest[2] = (pixel2 == 0) ? 0 : clut_32[pixel2 & 0x7FF]; - dest[3] = (pixel3 == 0) ? 0 : clut_32[pixel3 & 0x7FF]; - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } else { // !(rofs | gofs | bofs) && !transparent - - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*16 - width*2, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 8) { - const uint16_t *line_src = (const uint16_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const uint16_t pixel0 = BSWAP16(line_src[0]); - const uint16_t pixel1 = BSWAP16(line_src[1]); - const uint16_t pixel2 = BSWAP16(line_src[2]); - const uint16_t pixel3 = BSWAP16(line_src[3]); - dest[0] = clut_32[pixel0 & 0x7FF]; - dest[1] = clut_32[pixel1 & 0x7FF]; - dest[2] = clut_32[pixel2 & 0x7FF]; - dest[3] = clut_32[pixel3 & 0x7FF]; - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } // if (rofs | gofs | bofs) - - if (outheight > height) { - const uint32_t *src32; - if ((height & 7) != 0) { - dest = dest - tex_stride*8 + (height & 7)*4; - src32 = dest - 4; - } else { - src32 = dest - tex_stride*8 + 7*4; - } - uint32_t *dest_top = dest + tex_stride; - for (; dest < dest_top; src32 += 32, dest += 32) { - const uint32_t pixel0 = src32[0]; - const uint32_t pixel1 = src32[1]; - const uint32_t pixel2 = src32[2]; - const uint32_t pixel3 = src32[3]; - dest[0] = pixel0; - dest[1] = pixel1; - dest[2] = pixel2; - dest[3] = pixel3; - } - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * cache_texture_16: Cache a 16-bit ARGB1555 texture. - * - * [Parameters] - * tex: TexInfo structure for texture - * src: Pointer to VDP1/VDP2 texture data - * width, height: Size of texture (in pixels) - * stride: Line size of source data (in pixels) - * rofs, gofs, bofs: Color offset values for texture - * transparent: Nonzero if alpha-0 pixels should be transparent - * [Return value] - * Nonzero on success, zero on error - */ -static inline int cache_texture_16( - TexInfo *tex, const uint8_t *src, - unsigned int width, unsigned int height, unsigned int stride, - int rofs, int gofs, int bofs, int transparent) -{ - const int outwidth = width + (width == tex->width ? 0 : 1); - const int outheight = height + (height == tex->height ? 0 : 1); - - const unsigned int tex_stride = tex->stride; - uint32_t *dest = (uint32_t *)tex->vram_address; - - if (rofs | gofs | bofs) { - - const uint32_t transparent_pixel = 0x00000000 - | (rofs>0 ? rofs<< 0 : 0) - | (gofs>0 ? gofs<< 8 : 0) - | (bofs>0 ? bofs<<16 : 0); - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*16 - width*2, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 8) { - /* We load these as signed values to simplify checking the - * high (transparency) bit. */ - const int16_t *line_src = (const int16_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const int16_t pixel0 = BSWAP16(line_src[0]); - const int16_t pixel1 = BSWAP16(line_src[1]); - const int16_t pixel2 = BSWAP16(line_src[2]); - const int16_t pixel3 = BSWAP16(line_src[3]); - dest[0] = (transparent && !(pixel0<0)) ? transparent_pixel - : adjust_color_16_32(pixel0, rofs, gofs, bofs); - dest[1] = (transparent && !(pixel1<0)) ? transparent_pixel - : adjust_color_16_32(pixel1, rofs, gofs, bofs); - dest[2] = (transparent && !(pixel2<0)) ? transparent_pixel - : adjust_color_16_32(pixel2, rofs, gofs, bofs); - dest[3] = (transparent && !(pixel3<0)) ? transparent_pixel - : adjust_color_16_32(pixel3, rofs, gofs, bofs); - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } else if (transparent) { - - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*16 - width*2, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 8) { - const int16_t *line_src = (const int16_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const int16_t pixel0 = BSWAP16(line_src[0]); - const int16_t pixel1 = BSWAP16(line_src[1]); - const int16_t pixel2 = BSWAP16(line_src[2]); - const int16_t pixel3 = BSWAP16(line_src[3]); - dest[0] = (pixel0 >= 0) ? 0 - : 0xFF000000 | (pixel0 & 0x7C00) << 9 - | (pixel0 & 0x03E0) << 6 - | (pixel0 & 0x001F) << 3; - dest[1] = (pixel1 >= 0) ? 0 - : 0xFF000000 | (pixel1 & 0x7C00) << 9 - | (pixel1 & 0x03E0) << 6 - | (pixel1 & 0x001F) << 3; - dest[2] = (pixel2 >= 0) ? 0 - : 0xFF000000 | (pixel2 & 0x7C00) << 9 - | (pixel2 & 0x03E0) << 6 - | (pixel2 & 0x001F) << 3; - dest[3] = (pixel3 >= 0) ? 0 - : 0xFF000000 | (pixel3 & 0x7C00) << 9 - | (pixel3 & 0x03E0) << 6 - | (pixel3 & 0x001F) << 3; - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } else { // !(rofs | gofs | bofs) && !transparent - - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*16 - width*2, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 8) { - const int16_t *line_src = (const int16_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const int16_t pixel0 = BSWAP16(line_src[0]); - const int16_t pixel1 = BSWAP16(line_src[1]); - const int16_t pixel2 = BSWAP16(line_src[2]); - const int16_t pixel3 = BSWAP16(line_src[3]); - dest[0] = 0xFF000000 | (pixel0 & 0x7C00) << 9 - | (pixel0 & 0x03E0) << 6 - | (pixel0 & 0x001F) << 3; - dest[1] = 0xFF000000 | (pixel1 & 0x7C00) << 9 - | (pixel1 & 0x03E0) << 6 - | (pixel1 & 0x001F) << 3; - dest[2] = 0xFF000000 | (pixel2 & 0x7C00) << 9 - | (pixel2 & 0x03E0) << 6 - | (pixel2 & 0x001F) << 3; - dest[3] = 0xFF000000 | (pixel3 & 0x7C00) << 9 - | (pixel3 & 0x03E0) << 6 - | (pixel3 & 0x001F) << 3; - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } // if (rofs | gofs | bofs) - - if (outheight > height) { - const uint32_t *src32; - if ((height & 7) != 0) { - dest = dest - tex_stride*8 + (height & 7)*4; - src32 = dest - 4; - } else { - src32 = dest - tex_stride*8 + 7*4; - } - uint32_t *dest_top = dest + tex_stride; - for (; dest < dest_top; src32 += 32, dest += 32) { - const uint32_t pixel0 = src32[0]; - const uint32_t pixel1 = src32[1]; - const uint32_t pixel2 = src32[2]; - const uint32_t pixel3 = src32[3]; - dest[0] = pixel0; - dest[1] = pixel1; - dest[2] = pixel2; - dest[3] = pixel3; - } - } - - return 1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * cache_texture_32: Cache a 32-bit ARGB1888 texture. - * - * [Parameters] - * tex: TexInfo structure for texture - * src: Pointer to VDP1/VDP2 texture data - * width, height: Size of texture (in pixels) - * stride: Line size of source data (in pixels) - * rofs, gofs, bofs: Color offset values for texture - * transparent: Nonzero if alpha-0 pixels should be transparent - * [Return value] - * Nonzero on success, zero on error - */ -static inline int cache_texture_32( - TexInfo *tex, const uint8_t *src, - unsigned int width, unsigned int height, unsigned int stride, - int rofs, int gofs, int bofs, int transparent) -{ - const int outwidth = width + (width == tex->width ? 0 : 1); - const int outheight = height + (height == tex->height ? 0 : 1); - - const unsigned int tex_stride = tex->stride; - uint32_t *dest = (uint32_t *)tex->vram_address; - - if (rofs | gofs | bofs) { - - const uint32_t transparent_pixel = 0x00000000 - | (rofs>0 ? rofs<< 0 : 0) - | (gofs>0 ? gofs<< 8 : 0) - | (bofs>0 ? bofs<<16 : 0); - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*32 - width*4, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 16) { - const int32_t *line_src = (const int32_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const int32_t pixel0 = BSWAP32(line_src[0]); - const int32_t pixel1 = BSWAP32(line_src[1]); - const int32_t pixel2 = BSWAP32(line_src[2]); - const int32_t pixel3 = BSWAP32(line_src[3]); - dest[0] = (transparent && !(pixel0<0)) ? transparent_pixel - : adjust_color_32_32(pixel0, rofs, gofs, bofs); - dest[1] = (transparent && !(pixel1<0)) ? transparent_pixel - : adjust_color_32_32(pixel1, rofs, gofs, bofs); - dest[2] = (transparent && !(pixel2<0)) ? transparent_pixel - : adjust_color_32_32(pixel2, rofs, gofs, bofs); - dest[3] = (transparent && !(pixel3<0)) ? transparent_pixel - : adjust_color_32_32(pixel3, rofs, gofs, bofs); - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } else if (transparent) { - - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*32 - width*4, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 16) { - const int32_t *line_src = (const int32_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const int32_t pixel0 = BSWAP32(line_src[0]); - const int32_t pixel1 = BSWAP32(line_src[1]); - const int32_t pixel2 = BSWAP32(line_src[2]); - const int32_t pixel3 = BSWAP32(line_src[3]); - dest[0] = (pixel0 >= 0) ? 0 : 0xFF000000 | pixel0; - dest[1] = (pixel1 >= 0) ? 0 : 0xFF000000 | pixel1; - dest[2] = (pixel2 >= 0) ? 0 : 0xFF000000 | pixel2; - dest[3] = (pixel3 >= 0) ? 0 : 0xFF000000 | pixel3; - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } else { // !(rofs | gofs | bofs) && !transparent - - unsigned int y; - for (y = 0; y < height; y += 8, src += stride*32 - width*4, dest += (tex_stride - width)*8) { - uint32_t *dest_top = dest + width*8; - for (; dest != dest_top; src += 16) { - const int32_t *line_src = (const int32_t *)src; - uint32_t *line_end = dest + 32; - for (; dest != line_end; line_src += stride, dest += 4) { - const int32_t pixel0 = BSWAP32(line_src[0]); - const int32_t pixel1 = BSWAP32(line_src[1]); - const int32_t pixel2 = BSWAP32(line_src[2]); - const int32_t pixel3 = BSWAP32(line_src[3]); - dest[0] = 0xFF000000 | pixel0; - dest[1] = 0xFF000000 | pixel1; - dest[2] = 0xFF000000 | pixel2; - dest[3] = 0xFF000000 | pixel3; - } - } - if (outwidth > width) { - int line; - for (line = 0; line < 8; line++) { - dest[line*4] = dest[line*4-32]; - } - } - } - - } // if (rofs | gofs | bofs) - - if (outheight > height) { - const uint32_t *src32; - if ((height & 7) != 0) { - dest = dest - tex_stride*8 + (height & 7)*4; - src32 = dest - 4; - } else { - src32 = dest - tex_stride*8 + 7*4; - } - uint32_t *dest_top = dest + tex_stride; - for (; dest < dest_top; src32 += 32, dest += 32) { - const uint32_t pixel0 = src32[0]; - const uint32_t pixel1 = src32[1]; - const uint32_t pixel2 = src32[2]; - const uint32_t pixel3 = src32[3]; - dest[0] = pixel0; - dest[1] = pixel1; - dest[2] = pixel2; - dest[3] = pixel3; - } - } - - return 1; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/texcache.h b/yabause/src/psp/texcache.h deleted file mode 100644 index c21bda8f37..0000000000 --- a/yabause/src/psp/texcache.h +++ /dev/null @@ -1,141 +0,0 @@ -/* src/psp/texcache.h: PSP texture cache management header - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_TEXCACHE_H -#define PSP_TEXCACHE_H - -#include "../vdp1.h" - -/*************************************************************************/ - -/** - * texcache_reset: Reset the texture cache, including all persistent - * textures. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void texcache_reset(void); - -/** - * texcache_clean: Clean all transient textures from the texture cache. - * Persistent textures are not affected. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void texcache_clean(void); - -/** - * texcache_cache_sprite: Cache the given sprite texture if it has not - * been cached already. Returns a texture key for later use in loading the - * texture. The texture width must be a multiple of 8. - * - * [Parameters] - * cmd: VDP1 command structure - * pixel_mask: Mask to apply to paletted pixel data - * width, height: Size of texture (in pixels) - * persistent: Nonzero to cache this texture persistently across - * frames, zero to cache the texture for this frame only - * [Return value] - * Texture key (zero on error) - */ -extern uint32_t texcache_cache_sprite(const vdp1cmd_struct *cmd, - uint16_t pixel_mask, - unsigned int width, unsigned int height, - int persistent); - -/** - * texcache_load_sprite: Load the sprite texture indicated by the given - * texture key. - * - * [Parameters] - * key: Texture key returned by texcache_cache_sprite - * [Return value] - * None - */ -extern void texcache_load_sprite(uint32_t key); - -/** - * texcache_load_tile: Load the specified 8x8 or 16x16 tile texture into - * the GE registers for drawing, first caching the texture if necessary. - * - * [Parameters] - * tilesize: Pixel size (width and height) of tile, either 8 or 16 - * address: Tile data address within VDP2 RAM - * pixfmt: Tile pixel format - * transparent: Nonzero if index 0 or alpha 0 should be transparent - * color_base: Color table base (for indexed formats) - * color_ofs: Color table offset (for indexed formats) - * rofs, gofs, bofs: Color offset values for texture - * persistent: Nonzero to cache this texture persistently across - * frames, zero to cache the texture for this - * frame only - * [Return value] - * None - */ -extern void texcache_load_tile(int tilesize, uint32_t address, - int pixfmt, int transparent, - uint16_t color_base, uint16_t color_ofs, - int rofs, int gofs, int bofs, int persistent); - -/** - * texcache_load_bitmap: Load the specified bitmap texture into the GE - * registers for drawing, first caching the texture if necessary. The - * texture width must be a multiple of 8. - * - * [Parameters] - * address: Bitmap data address within VDP2 RAM - * width, height: Size of texture (in pixels) - * stride: Line size of source data (in pixels) - * pixfmt: Bitmap pixel format - * transparent: Nonzero if index 0 or alpha 0 should be transparent - * color_base: Color table base (for indexed formats) - * color_ofs: Color table offset (for indexed formats) - * rofs, gofs, bofs: Color offset values for texture - * persistent: Nonzero to cache this texture persistently across - * frames, zero to cache the texture for this - * frame only - * [Return value] - * None - */ -extern void texcache_load_bitmap(uint32_t address, unsigned int width, - unsigned int height, unsigned int stride, - int pixfmt, int transparent, - uint16_t color_base, uint16_t color_ofs, - int rofs, int gofs, int bof, int persistent); - -/*************************************************************************/ - -#endif // PSP_TEXCACHE_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/threads.c b/yabause/src/psp/threads.c deleted file mode 100644 index 71c7042121..0000000000 --- a/yabause/src/psp/threads.c +++ /dev/null @@ -1,227 +0,0 @@ -/* src/psp/threads.c: Yabause thread management routines - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" -#include "config.h" -#include "me.h" -#include "me-utility.h" -#include "sys.h" - -#include "../threads.h" - -/*************************************************************************/ - -/* Thread handle and setup data for each Yabause subthread */ -static struct { - int32_t handle; - const char * const name; - int priority; - uint32_t stack_size; -} thread_data[YAB_NUM_THREADS] = { - [YAB_THREAD_SCSP] = {.name = "YabauseScspThread", - .priority = THREADPRI_MAIN, - .stack_size = 16384}, // FIXME: could be smaller? -}; - -/*************************************************************************/ -/************************** Interface routines ***************************/ -/*************************************************************************/ - -/** - * YabThreadStart: Start a new thread for the given function. Only one - * thread will be started for each thread ID (YAB_THREAD_*). - * - * [Parameters] - * id: Yabause subthread ID (YAB_THREAD_*) - * func: Function to execute - * [Return value] - * Zero on success, negative on error - */ -int YabThreadStart(unsigned int id, void (*func)(void)) -{ - if (thread_data[id].handle) { - fprintf(stderr, "YabThreadStart: thread %u is already started!\n", id); - return -1; - } - - if (id == YAB_THREAD_SCSP) { // We run the SCSP on the ME - if (!me_available || !config_get_use_me()) { - DMSG("ME not available or disabled by user"); - return -1; - } - sceKernelDcacheWritebackAll(); -#ifdef PSP_DEBUG - meExceptionSetFatal(1); -#endif - int32_t res; - if ((res = meStart()) < 0) { - DMSG("meStart(): %s", psp_strerror(res)); - return -1; - } else if ((res = meWait()) < 0) { - DMSG("meWait(): %s", psp_strerror(res)); - return -1; - } else if ((res = meCall((void *)func, NULL)) < 0) { - DMSG("Failed to start thread %d (%s) on ME: %s", - id, thread_data[id].name, psp_strerror(res)); - return -1; - } - /* Attempting to suspend the PSP will currently cause a crash, - * so prevent suspending entirely. (This is documented in the - * README.PSP file.) */ - scePowerLock(0); - thread_data[id].handle = 1; // Anything nonzero will do - } else { - int32_t res = sys_start_thread(thread_data[id].name, func, - thread_data[id].priority, - thread_data[id].stack_size, 0, NULL); - if (res < 0) { - DMSG("Failed to start thread %d (%s): %s", - id, thread_data[id].name, psp_strerror(res)); - return -1; - } - thread_data[id].handle = res; - } - - return 0; -} - -/*************************************************************************/ - -/** - * YabThreadWait: Wait for the given ID's thread to terminate. Returns - * immediately if no thread has been started on the given ID. - * - * [Parameters] - * id: Yabause subthread ID (YAB_THREAD_*) - * [Return value] - * None - */ -void YabThreadWait(unsigned int id) -{ - if (!thread_data[id].handle) { - return; // Thread wasn't running in the first place - } - - if (id == YAB_THREAD_SCSP) { - sceKernelDcacheWritebackInvalidateAll(); - int32_t res; - if ((res = meWait()) < 0) { - DMSG("meWait(): %s", psp_strerror(res)); - } - } else { - int32_t res; - if ((res = sceKernelWaitThreadEnd(thread_data[id].handle, NULL)) < 0) { - DMSG("WaitThreadEnd(%d): %s", id, psp_strerror(res)); - } - if ((res = sceKernelDeleteThread(thread_data[id].handle)) < 0) { - DMSG("DeleteThread(%d): %s", id, psp_strerror(res)); - } - } - - thread_data[id].handle = 0; -} - -/*************************************************************************/ - -/** - * YabThreadYield: Yield CPU execution to another thread. - * - * [Parameters] - * None - * [Return value] - * None - */ -void YabThreadYield(void) -{ - if (meUtilityIsME()) { - /* On the ME, there's no other thread to yield to, but we do flush - * the cache to ensure the SC can see our updates. */ - meUtilityDcacheWritebackInvalidateAll(); - } else { -#ifdef PSP_DEBUG - if (thread_data[YAB_THREAD_SCSP].handle) { - /* ME is running, so check for ME exceptions */ - (void) mePoll(); - } -#endif - sceKernelDelayThread(0); - } -} - -/*************************************************************************/ - -/** - * YabThreadSleep: Put the current thread to sleep. - * - * [Parameters] - * None - * [Return value] - * None - */ -void YabThreadSleep(void) -{ - if (meUtilityIsME()) { - /* Used in place of YabThreadYield() when the SCSP thread has - * nothing to do; there's no real point in sleeping on the ME, but - * flush the data cache as in Yield(). */ - meUtilityDcacheWritebackInvalidateAll(); - } else { - sceKernelSleepThread(); - } -} - -/*************************************************************************/ - -/** - * YabThreadWake: Wake up the given thread if it is asleep. - * - * [Parameters] - * id: Yabause subthread ID (YAB_THREAD_*) - * [Return value] - * None - */ -void YabThreadWake(unsigned int id) -{ - if (!thread_data[id].handle) { - return; // Thread is not running - } - - if (id == YAB_THREAD_SCSP) { -#ifdef PSP_DEBUG - /* Check for ME exceptions */ - (void) mePoll(); -#endif - } else { - sceKernelWakeupThread(thread_data[id].handle); - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/timing.c b/yabause/src/psp/timing.c deleted file mode 100644 index 270aded1f2..0000000000 --- a/yabause/src/psp/timing.c +++ /dev/null @@ -1,145 +0,0 @@ -/* src/psp/timing.c: Emulation timing logic for PSP - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "timing.h" - -/*************************************************************************/ -/****************************** Local data *******************************/ -/*************************************************************************/ - -/* Length of a single frame in microseconds (32.32 fixed point). */ -#define FRAME_TIME (((1001000LL << 32) + 30) / 60) - -/* Minimum elapsed time since the beginning of the previous frame before - * we consider this the start of a new frame. This is slightly less than - * the actual frame length to account for slight discrepancies in hardware - * timing. */ -#define MIN_WAIT (FRAME_TIME * 9/10) - -/* Microsecond timestamp at the beginning of the previous frame - * (32.32 fixed point). */ -static int64_t last_frame_time; - -/* Flag indicating that the next frame should be synched to real time. - * This is set on the call to timing_init() and also each call to - * timing_sync(), and can be cleared during a frame by a call to - * timing_skip_next_sync(). If the flag is clear on entry to timing_sync(), - * the sync is skipped and the last frame time is incremented by FRAME_TIME - * regardless of the current time. This flag is typically cleared by - * psp-video.c during skipped output frames to let several emulated frames - * execute at once. */ -static int sync_next_frame; - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * timing_init: Initialize the timing functionality at program start. - * Should be called as late as possible in the initialization sequence - * (as close to the start of emulation as possible). - * - * [Parameters] - * None - * [Return value] - * None - */ -void timing_init(void) -{ - sync_next_frame = 1; - sceDisplayWaitVblankStart(); - last_frame_time = (int64_t)sceKernelGetSystemTimeLow() << 32; -} - -/*-----------------------------------------------------------------------*/ - -/** - * timing_sync: Wait until at least one frame has passed since the - * beginning of the previous frame. However, if timing_skip_next_sync() - * was called after the previous call to timing_sync() or timing_init(), - * this function returns immediately, and the next timing_sync() call will - * wait one extra frame past the last synchronization point. (For example, - * calling timing_skip_next_sync() every second frame will cause the - * immediately subsequent timing_sync() to return immediately, and the - * timing_sync() after that to wait until two frames' time has passed since - * the call to timing_sync() preceding the timing_skip_next_sync() call.) - * - * [Parameters] - * None - * [Return value] - * None - */ -void timing_sync(void) -{ - if (sync_next_frame) { - int waited = 0; - int64_t now; - while (now = (int64_t)sceKernelGetSystemTimeLow() << 32, - now - last_frame_time < MIN_WAIT) - { - sceDisplayWaitVblankStart(); - waited = 1; - } - /* Keep the timer aligned as closely as possible to the actual - * vertical blank for smoother timing. */ - if (waited) { - last_frame_time = now; - } else { - do { - last_frame_time += FRAME_TIME; - } while (now - last_frame_time > FRAME_TIME/2); - } - } else { - last_frame_time += FRAME_TIME; - sync_next_frame = 1; - } -} - -/*************************************************************************/ - -/** - * timing_skip_next_sync: Called during a frame to indicate that the - * next call to timing_sync() should not perform a sync. See the - * timing_sync() documentation for details. - * - * [Parameters] - * None - * [Return value] - * None - */ -void timing_skip_next_sync(void) -{ - sync_next_frame = 0; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/timing.h b/yabause/src/psp/timing.h deleted file mode 100644 index f2df7bba76..0000000000 --- a/yabause/src/psp/timing.h +++ /dev/null @@ -1,80 +0,0 @@ -/* src/psp/timing.h: Header for emulation timing logic - Copyright 2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef PSP_TIMING_H -#define PSP_TIMING_H - -/*************************************************************************/ - -/** - * timing_init: Initialize the timing functionality at program start. - * Should be called as late as possible in the initialization sequence - * (as close to the start of emulation as possible). - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void timing_init(void); - -/** - * timing_sync: Wait until at least one frame has passed since the - * beginning of the previous frame. However, if timing_skip_next_sync() - * was called after the previous call to timing_sync() or timing_init(), - * this function returns immediately, and the next timing_sync() call will - * wait one extra frame past the last synchronization point. (For example, - * calling timing_skip_next_sync() every second frame will cause the - * immediately subsequent timing_sync() to return immediately, and the - * timing_sync() after that to wait until two frames' time has passed since - * the call to timing_sync() preceding the timing_skip_next_sync() call.) - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void timing_sync(void); - -/** - * timing_skip_next_sync: Called during a frame to indicate that the - * next call to timing_sync() should not perform a sync. See the - * timing_sync() documentation for details. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void timing_skip_next_sync(void); - -/*************************************************************************/ - -#endif // PSP_TIMING_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/psp/yui.c b/yabause/src/psp/yui.c deleted file mode 100644 index b0eb5fc09f..0000000000 --- a/yabause/src/psp/yui.c +++ /dev/null @@ -1,147 +0,0 @@ -/* src/psp/yui.c: Yabause core interface routines - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "common.h" - -#include "../vidsoft.h" -#include "../yui.h" - -#include "display.h" -#include "menu.h" - -/*************************************************************************/ -/******************** Yabause core interface routines ********************/ -/*************************************************************************/ - -/** - * YuiErrorMsg: Report an error to the user. - * - * [Parameters] - * string: Error message string - * [Return value] - * None - */ -void YuiErrorMsg(const char *string) -{ - PRECOND(string != NULL, return); - -#ifdef PSP_DEBUG - fprintf(stderr, "%s", string); -#endif - - /* Drop any leading/trailing newlines, and convert internal newlines to - * spaces, before passing the message to the menu screen */ - while (*string == '\r' || *string == '\n') { - string++; - } - char buf[100]; - snprintf(buf, sizeof(buf), "%s", string); - int i; - for (i = strlen(buf)-1; i >= 0; i--) { - if (buf[i] == '\r' || buf[i] == '\n') { - buf[i] = 0; - } else { - break; - } - } - for (i = 0; buf[i]; i++) { - if (buf[i] == '\r' || buf[i] == '\n') { - buf[i] = ' '; - } - } - menu_set_error(buf); -} - -/*************************************************************************/ - -/** - * YuiSwapBuffers: Swap the front and back display buffers. Called by the - * software renderer. - * - * [Parameters] - * None - * [Return value] - * None - */ -void YuiSwapBuffers(void) -{ - if (!dispbuffer) { - return; - } - - /* Calculate display size (shrink interlaced/hi-res displays by half) */ - int width_in, height_in, width_out, height_out; - VIDCore->GetGlSize(&width_in, &height_in); - if (width_in <= DISPLAY_WIDTH) { - width_out = width_in; - } else { - width_out = width_in / 2; - } - if (height_in <= DISPLAY_HEIGHT) { - height_out = height_in; - } else { - height_out = height_in / 2; - } - int x = (DISPLAY_WIDTH - width_out) / 2; - int y = (DISPLAY_HEIGHT - height_out) / 2; - - /* Make sure all video buffer data is flushed to memory and cleared - * from the cache */ - sceKernelDcacheWritebackInvalidateRange(dispbuffer, - width_in * height_in * 4); - - /* Blit the data to the screen */ - display_begin_frame(); - if (width_out == width_in && height_out == height_in) { - display_blit(dispbuffer, width_in, height_in, width_in, x, y); - } else { - /* The PSP can't draw textures larger than 512x512, so if we're - * drawing a high-resolution buffer, split it in half. The height - * will never be greater than 512, so we don't need to check for a - * vertical split. */ - if (width_in > 512) { - const uint32_t *dispbuffer32 = (const uint32_t *)dispbuffer; - display_blit_scaled(dispbuffer32, width_in/2, height_in, - width_in, x, y, width_out/2, height_out); - dispbuffer32 += width_in/2; - x += width_out/2; - display_blit_scaled(dispbuffer32, width_in/2, height_in, - width_in, x, y, width_out/2, height_out); - } else { - display_blit_scaled(dispbuffer, width_in, height_in, width_in, - x, y, width_out, height_out); - } - } - display_end_frame(); - sceDisplayWaitVblankStart(); -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68-const.h b/yabause/src/q68/q68-const.h deleted file mode 100644 index 9de141f175..0000000000 --- a/yabause/src/q68/q68-const.h +++ /dev/null @@ -1,217 +0,0 @@ -/* src/q68/q68-const.h: Constants used in MC68000 emulation - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef Q68_CONST_H -#define Q68_CONST_H - -/*************************************************************************/ - -/* Configuration constants */ - -/* Maximum size in bytes of a 68k code block for translation */ -#ifndef Q68_JIT_MAX_BLOCK_SIZE -# define Q68_JIT_MAX_BLOCK_SIZE 4096 -#endif - -/* Size of pages used in checking for writes to already-translated code - * (1 page = 1<SR >> SR_I0_SHIFT) & 7) -#define SR_SET_I(state,val) ((state)->SR &= ~(7 << SR_I0_SHIFT), \ - (state)->SR |= ((val) & 7) << SR_I0_SHIFT) - -/*-----------------------------------------------------------------------*/ - -/* Exception numbers */ - -#define EX_INITIAL_SP 0 -#define EX_INITIAL_PC 1 -#define EX_BUS_ERROR 2 -#define EX_ADDRESS_ERROR 3 -#define EX_ILLEGAL_INSTRUCTION 4 -#define EX_DIVIDE_BY_ZERO 5 -#define EX_CHK 6 -#define EX_TRAPV 7 -#define EX_PRIVILEGE_VIOLATION 8 -#define EX_TRACE 9 -#define EX_LINE_1010 10 -#define EX_LINE_1111 11 - -#define EX_SPURIOUS_INTERRUPT 24 -#define EX_LEVEL_1_INTERRUPT 25 -#define EX_LEVEL_2_INTERRUPT 26 -#define EX_LEVEL_3_INTERRUPT 27 -#define EX_LEVEL_4_INTERRUPT 28 -#define EX_LEVEL_5_INTERRUPT 29 -#define EX_LEVEL_6_INTERRUPT 30 -#define EX_LEVEL_7_INTERRUPT 31 -#define EX_TRAP 32 // 16 vectors (EX_TRAP+0 .. EX_TRAP+15) - -/*-----------------------------------------------------------------------*/ - -/* Bits in the fault status word for bus/address error exceptions */ - -#define FAULT_STATUS_IN (1<<3) // Instruction/Not (0 = instruction, 1 = not) -#define FAULT_STATUS_IN_INSN (0) -#define FAULT_STATUS_IN_DATA (FAULT_STATUS_IN) - -#define FAULT_STATUS_RW (1<<4) // Read/Write (0 = write, 1 = read) -#define FAULT_STATUS_RW_READ (FAULT_STATUS_RW) -#define FAULT_STATUS_RW_WRITE (0) - -/*-----------------------------------------------------------------------*/ - -/* Condition codes for conditional instructions */ - -#define COND_T 0 -#define COND_F 1 -#define COND_HI 2 -#define COND_LS 3 -#define COND_CC 4 // also HS -#define COND_CS 5 // also LO -#define COND_NE 6 -#define COND_EQ 7 -#define COND_VC 8 -#define COND_VS 9 -#define COND_PL 10 -#define COND_MI 11 -#define COND_GE 12 -#define COND_LT 13 -#define COND_GT 14 -#define COND_LE 15 - -/*-----------------------------------------------------------------------*/ - -/* Size codes in opcode bits 6-7 */ - -#define SIZE_B 0 -#define SIZE_W 1 -#define SIZE_L 2 - -/* Macro to convert size codes to equivalent byte counts */ -#define SIZE_TO_BYTES(size) ((size) + 1 + ((size) == SIZE_L)) - -/*-----------------------------------------------------------------------*/ - -/* Effective address modes */ - -#define EA_DATA_REG 0 // Data Register Direct -#define EA_ADDRESS_REG 1 // Address Register Direct -#define EA_INDIRECT 2 // Address Register Indirect -#define EA_POSTINCREMENT 3 // Address Register Indirect with Postincrement -#define EA_PREDECREMENT 4 // Address Register Indirect with Predecrement -#define EA_DISPLACEMENT 5 // Address Register Indirect with Displacement -#define EA_INDEX 6 // Address Register Indirect with Index -#define EA_MISC 7 - -#define EA_MISC_ABSOLUTE_W 0 // Absolute Short -#define EA_MISC_ABSOLUTE_L 1 // Absolute Long -#define EA_MISC_PCREL 2 // Program Counter Indirect with Displacement -#define EA_MISC_PCREL_INDEX 3 // Program Counter Indirect with Index -#define EA_MISC_IMMEDIATE 4 // Immediate - -/* Macros to retrieve the mode and register number from an opcode */ -#define EA_MODE(opcode) ((opcode)>>3 & 7) -#define EA_REG(opcode) ((opcode)>>0 & 7) - -/*************************************************************************/ -/*************************************************************************/ - -#endif // Q68_CONST_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68-core.c b/yabause/src/q68/q68-core.c deleted file mode 100644 index b3dc4a8bd7..0000000000 --- a/yabause/src/q68/q68-core.c +++ /dev/null @@ -1,2563 +0,0 @@ -/* src/q68/q68-core.c: Q68 execution core - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include - -#include "q68.h" -#include "q68-const.h" -#include "q68-internal.h" - -/* Define this to export two tables of counters: - * uint32_t q68_ops[128]; // Corresponds to opcode_table[] - * uint32_t q68_4xxx_ops[32]; // Corresponds to opcode_4xxx_table[] - * Each entry will be incremented each time the corresponding function is - * called. */ -// #define COUNT_OPCODES - -/*************************************************************************/ - -/* - * The following table maps each 68000 instruction to its implementing - * function in this file: - * - * || Instruction | Func. || Instruction | Func. || Instruction | Func. || - * ++-------------+--------++-------------+--------++-------------+--------++ - * || ABCD | op_BCD || EOR | op_alu || NOT | op4alu || - * || ADD | op_alu || EORI | op_imm || OR | op_alu || - * || ADDA | op_alu || EORI to CCR | op_imm || ORI | op_imm || - * || ADDI | op_imm || EORI to SR | op_imm || ORI to CCR | op_imm || - * || ADDQ | opADSQ || EXG | op_EXG || ORI to SR | op_imm || - * || ADDX | opADSX || EXT | op_EXT || PEA | op_PEA || - * || AND | op_alu || ILLEGAL | op_TAS || RESET | op4E7x || - * || ANDI | op_imm || JMP | opjump || ROL | opshft || - * || ANDI to CCR | op_imm || JSR | opjump || ROR | opshft || - * || ANDI to SR | op_imm || LEA | op_LEA || ROXL | opshft || - * || ASL | opshft || LINK | opLINK || ROXR | opshft || - * || ASR | opshft || LSL | opshft || RTE | op4E7x || - * || Bcc | op_Bcc || LSR | opshft || RTR | op4E7x || - * || BCHG | op_bit || MOVE | opMOVE || RTS | op4E7x || - * || BCLR | op_bit || MOVEA | opMOVE || SBCD | op_BCD || - * || BRA | op_Bcc || MOVE to CCR | opMVSR || Scc | op_Scc || - * || BSET | op_bit || MOVE from SR| opMVSR || STOP | op4E7x || - * || BSR | op_Bcc || MOVE to SR | opMVSR || SUB | op_alu || - * || BTST | op_bit || MOVE USP | opMUSP || SUBA | op_alu || - * || CHK | op_CHK || MOVEM | (*1) || SUBI | op_imm || - * || CLR | op4alu || MOVEP | opMOVP || SUBQ | opADSQ || - * || CMP | op_alu || MOVEQ | opMOVQ || SUBX | opADSX || - * || CMPA | op_alu || MULS | op_MUL || SWAP | opSWAP || - * || CMPI | op_imm || MULU | op_MUL || TAS | op_TAS || - * || CMPM | opCMPM || NBCD | opNBCD || TRAP | opTRAP || - * || DBcc | opDBcc || NEG | op4alu || TRAPV | op4E7x || - * || DIVS | op_DIV || NEGX | op4alu || TST | op4alu || - * || DIVU | op_DIV || NOP | op4E7X || UNLK | opUNLK || - * - * (*1) MOVEM is implemented by two instructions, op_STM (MOVEM reglist,mem) - * and op_LDM (MOVEM mem,reglist). - * - * Cycle counts were taken from: - * http://linas.org/mirrors/www.nvg.ntnu.no/2002.09.16/amiga/MC680x0_Sections/mc68000timing.HTML - */ - -/*************************************************************************/ - -/* Forward declarations for helper functions and instruction implementations */ - -static void set_SR(Q68State *state, uint16_t value); -static inline void check_interrupt(Q68State *state); -static int take_exception(Q68State *state, uint8_t num); -static inline int op_ill(Q68State *state, uint32_t opcode); - -static int ea_resolve(Q68State *state, uint32_t opcode, int size, - int access_type); -/* Note: Allowing these to be inlined actually slows down the code by ~0.5% - * (at least on x86). FIXME: how about PSP? */ -static NOINLINE uint32_t ea_get(Q68State *state, uint32_t opcode, int size, - int is_rmw, int *cycles_ret); -static NOINLINE void ea_set(Q68State *state, uint32_t opcode, int size, - uint32_t data); - -static int op_imm(Q68State *state, uint32_t opcode); -static int op_bit(Q68State *state, uint32_t opcode); -static int opMOVE(Q68State *state, uint32_t opcode); -static int op4xxx(Q68State *state, uint32_t opcode); -static int op_CHK(Q68State *state, uint32_t opcode); -static int op_LEA(Q68State *state, uint32_t opcode); -static int opADSQ(Q68State *state, uint32_t opcode); -static int op_Scc(Q68State *state, uint32_t opcode); -static int opDBcc(Q68State *state, uint32_t opcode); -static int op_Bcc(Q68State *state, uint32_t opcode); -static int opMOVQ(Q68State *state, uint32_t opcode); -static int op_alu(Q68State *state, uint32_t opcode); -static int op_DIV(Q68State *state, uint32_t opcode); -static int opAxxx(Q68State *state, uint32_t opcode); -static int op_MUL(Q68State *state, uint32_t opcode); -static int opshft(Q68State *state, uint32_t opcode); -static int opFxxx(Q68State *state, uint32_t opcode); - -static int op4alu(Q68State *state, uint32_t opcode); -static int opMVSR(Q68State *state, uint32_t opcode); -static int opNBCD(Q68State *state, uint32_t opcode); -static int op_PEA(Q68State *state, uint32_t opcode); -static int opSWAP(Q68State *state, uint32_t opcode); -static int op_TAS(Q68State *state, uint32_t opcode); -static int op_EXT(Q68State *state, uint32_t opcode); -static int op_STM(Q68State *state, uint32_t opcode); -static int op_LDM(Q68State *state, uint32_t opcode); -static int opmisc(Q68State *state, uint32_t opcode); -static int opTRAP(Q68State *state, uint32_t opcode); -static int opLINK(Q68State *state, uint32_t opcode); -static int opUNLK(Q68State *state, uint32_t opcode); -static int opMUSP(Q68State *state, uint32_t opcode); -static int op4E7x(Q68State *state, uint32_t opcode); -static int opjump(Q68State *state, uint32_t opcode); - -static int opMOVP(Q68State *state, uint32_t opcode); -static int opADSX(Q68State *state, uint32_t opcode); -static int op_BCD(Q68State *state, uint32_t opcode); -static int opCMPM(Q68State *state, uint32_t opcode); -static int op_EXG(Q68State *state, uint32_t opcode); - -/*-----------------------------------------------------------------------*/ - -/* Main table of instruction implemenation functions; table index is bits - * 15-12 and 8-6 of the opcode (ABCD ...E FG.. .... -> 0ABC DEFG). */ -static OpcodeFunc * const opcode_table[128] = { - op_imm, op_imm, op_imm, op_imm, op_bit, op_bit, op_bit, op_bit, // 00 - opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, // 10 - opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, // 20 - opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, // 30 - - op4xxx, op4xxx, op4xxx, op4xxx, op_ill, op_ill, op_CHK, op_LEA, // 40 - opADSQ, opADSQ, opADSQ, op_Scc, opADSQ, opADSQ, opADSQ, op_Scc, // 50 - op_Bcc, op_Bcc, op_Bcc, op_Bcc, op_Bcc, op_Bcc, op_Bcc, op_Bcc, // 60 - opMOVQ, opMOVQ, opMOVQ, opMOVQ, op_ill, op_ill, op_ill, op_ill, // 70 - - op_alu, op_alu, op_alu, op_DIV, op_alu, op_alu, op_alu, op_DIV, // 80 - op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, // 90 - opAxxx, opAxxx, opAxxx, opAxxx, opAxxx, opAxxx, opAxxx, opAxxx, // A0 - op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, // B0 - - op_alu, op_alu, op_alu, op_MUL, op_alu, op_alu, op_alu, op_MUL, // C0 - op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, // D0 - opshft, opshft, opshft, opshft, opshft, opshft, opshft, opshft, // E0 - opFxxx, opFxxx, opFxxx, opFxxx, opFxxx, opFxxx, opFxxx, opFxxx, // F0 -}; - -/* Subtable for instructions in the $4xxx (miscellaneous) group; table index - * is bits 11-9 and 7-6 of the opcode (1000 ABC0 DE.. .... -> 000A BCDE). */ -static OpcodeFunc * const opcode_4xxx_table[32] = { - op4alu, op4alu, op4alu, opMVSR, // 40xx - op4alu, op4alu, op4alu, op_ill, // 42xx - op4alu, op4alu, op4alu, opMVSR, // 44xx - op4alu, op4alu, op4alu, opMVSR, // 46xx - opNBCD, op_PEA, op_STM, op_STM, // 48xx - op4alu, op4alu, op4alu, op_TAS, // 4Axx - op_ill, op_ill, op_LDM, op_LDM, // 4Cxx - op_ill, opmisc, opjump, opjump, // 4Exx -}; - -/* Sub-subtable for instructions in the $4E40-$4E7F range, used by opmisc(); - * index is bits 5-3 of the opcode. */ -static OpcodeFunc * const opcode_4E4x_table[8] = { - opTRAP, opTRAP, opLINK, opUNLK, - opMUSP, opMUSP, op4E7x, op_ill, -}; - -#ifdef COUNT_OPCODES -/* Counters for opcode groups. */ -uint32_t q68_ops[128], q68_4xxx_ops[32]; -#endif - -/*************************************************************************/ -/************************** Interface functions **************************/ -/*************************************************************************/ - -/** - * q68_reset: Reset the virtual processor. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -void q68_reset(Q68State *state) -{ - int i; - for (i = 0; i < 8; i++) { - state->D[i] = 0; - state->A[i] = 0; - } - state->PC = 0; - state->SR = SR_S; - SR_SET_I(state, 7); - state->USP = 0; - state->SSP = 0; - state->current_PC = 0; - state->ea_addr = 0; - state->exception = 0; - state->fault_addr = 0; - state->fault_opcode = 0; - state->fault_status = 0; - state->jit_running = NULL; -#ifdef Q68_USE_JIT - q68_jit_reset(state); -#endif -#ifdef Q68_TRACE - q68_trace_init(state); -#endif - - state->A[7] = READU32(state, 0x000000); - state->PC = READU32(state, 0x000004); - state->halted = 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_run: Execute instructions for the given number of clock cycles. - * - * [Parameters] - * state: Processor state block - * cycles: Number of clock cycles to execute - * [Return value] - * Number of clock cycles executed (may be greater than "cycles") - */ -int q68_run(Q68State *state, int cycles) -{ - /* Check for pending interrupts */ - check_interrupt(state); - - /* Run the virtual processor */ - state->cycles = 0; - while (state->cycles < cycles) { - if (UNLIKELY(state->halted)) { - /* If we're halted, consume all remaining cycles */ - state->cycles = cycles; - break; - } - if (UNLIKELY(state->exception)) { - int exception = state->exception; - state->exception = 0; - state->cycles += take_exception(state, exception); - if (state->cycles >= cycles) { - break; - } - } -#ifdef Q68_USE_JIT - if (!state->jit_running) { - state->jit_running = q68_jit_find(state, state->PC); - if (UNLIKELY(!state->jit_running)) { - state->jit_running = q68_jit_translate(state, state->PC); - } - } - if (state->jit_running) { - q68_jit_run(state, cycles, &state->jit_running); - } else { -#endif -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (UNLIKELY(state->PC & 1)) { - state->fault_addr = state->PC; - state->fault_status = FAULT_STATUS_IN_INSN - | FAULT_STATUS_RW_READ; - state->cycles += take_exception(state, EX_ADDRESS_ERROR); - continue; - } -#endif -#ifdef Q68_TRACE - q68_trace(); -#endif - const unsigned int opcode = IFETCH(state); - state->current_PC = state->PC; -#ifndef Q68_DISABLE_ADDRESS_ERROR - state->fault_opcode = opcode; -#endif - const unsigned int index = (opcode>>9 & 0x78) | (opcode>>6 & 0x07); -#ifdef COUNT_OPCODES - q68_ops[index]++; -#endif - state->cycles += (*opcode_table[index])(state, opcode); -#ifdef Q68_USE_JIT - } -#endif - } // while (state->cycles < cycles && !state->halted) - -#ifdef Q68_TRACE - q68_trace_add_cycles(state->cycles); -#endif - - return state->cycles; -} - -/*************************************************************************/ -/************************** Instruction helpers **************************/ -/*************************************************************************/ - -/** - * set_SR: Set the processor's status register, performing any necessary - * additional actions (such as switching user/supervisor stacks). - * - * [Parameters] - * state: Processor state block - * value: New SR value - * [Return value] - * None - */ -static void set_SR(Q68State *state, uint16_t value) -{ - const uint16_t old_value = state->SR; - state->SR = value; - if ((old_value ^ value) & SR_S) { - if (value & SR_S) { // Switched to supervisor mode - state->USP = state->A[7]; - state->A[7] = state->SSP; - } else { // Switched to user mode - state->SSP = state->A[7]; - state->A[7] = state->USP; - } - } - check_interrupt(state); -} - -/*************************************************************************/ - -/** - * check_interrupt: Check whether an unmasked interrupt is pending, and - * raise the appropriate exception if so. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -static inline void check_interrupt(Q68State *state) -{ - const int irq = state->irq & 7; // Just to be safe - if (UNLIKELY(irq > SR_GET_I(state) - || irq == 7 // Level 7 is the non-maskable interrupt - )) { - if (state->halted != Q68_HALTED_DOUBLE_FAULT) { - state->irq = 0; - state->halted = 0; - state->exception = EX_LEVEL_1_INTERRUPT + (irq-1); - } - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * take_exception: Take an exception. - * - * [Parameters] - * state: Processor state block - * num: Exception number - * [Return value] - * Clock cycles used - */ -static int take_exception(Q68State *state, uint8_t num) -{ - static const int exception_cycles[256] = { - [EX_BUS_ERROR ] = 50, - [EX_ADDRESS_ERROR ] = 50, - [EX_ILLEGAL_INSTRUCTION ] = 34, - [EX_DIVIDE_BY_ZERO ] = 42, - [EX_CHK ] = 44, - [EX_TRAPV ] = 34, - [EX_PRIVILEGE_VIOLATION ] = 34, - [EX_TRACE ] = 34, - [EX_LINE_1010 ] = 34, // These two are assumed to be - [EX_LINE_1111 ] = 34, // equal to ILLEGAL_INSTRUCTION - [EX_SPURIOUS_INTERRUPT ] = 44, - [EX_LEVEL_1_INTERRUPT ] = 44, - [EX_LEVEL_2_INTERRUPT ] = 44, - [EX_LEVEL_3_INTERRUPT ] = 44, - [EX_LEVEL_4_INTERRUPT ] = 44, - [EX_LEVEL_5_INTERRUPT ] = 44, - [EX_LEVEL_6_INTERRUPT ] = 44, - [EX_LEVEL_7_INTERRUPT ] = 44, - [EX_TRAP+ 0 ] = 38, - [EX_TRAP+ 1 ] = 38, - [EX_TRAP+ 2 ] = 38, - [EX_TRAP+ 3 ] = 38, - [EX_TRAP+ 4 ] = 38, - [EX_TRAP+ 5 ] = 38, - [EX_TRAP+ 6 ] = 38, - [EX_TRAP+ 7 ] = 38, - [EX_TRAP+ 8 ] = 38, - [EX_TRAP+ 9 ] = 38, - [EX_TRAP+10 ] = 38, - [EX_TRAP+11 ] = 38, - [EX_TRAP+12 ] = 38, - [EX_TRAP+13 ] = 38, - [EX_TRAP+14 ] = 38, - [EX_TRAP+15 ] = 38, - }; - - /* Clear this out ahead of time in case we hit a double fault */ - state->jit_running = NULL; - - if (!(state->SR & SR_S)) { - state->USP = state->A[7]; - state->A[7] = state->SSP; - } -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->halted = Q68_HALTED_DOUBLE_FAULT; // Oops! - return 0; - } -#endif - PUSH32(state, state->PC); - PUSH16(state, state->SR); - if (num == EX_BUS_ERROR || num == EX_ADDRESS_ERROR) { - PUSH16(state, state->fault_opcode); - PUSH32(state, state->fault_addr); - PUSH16(state, state->fault_status); - } - state->SR |= SR_S; - if (num >= EX_LEVEL_1_INTERRUPT && num <= EX_LEVEL_7_INTERRUPT) { - SR_SET_I(state, (num - EX_LEVEL_1_INTERRUPT) + 1); - } - state->PC = READU32(state, num*4); -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->PC & 1) { - /* FIXME: Does a real 68000 double fault here or just take an - * address error exception? */ - state->halted = Q68_HALTED_DOUBLE_FAULT; - return 0; - } -#endif - return exception_cycles[num]; -} - -/*************************************************************************/ - -/** - * op_ill: Handle a generic illegal opcode. - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * [Return value] - * Clock cycles used - */ -static inline int op_ill(Q68State *state, uint32_t opcode) -{ - state->exception = EX_ILLEGAL_INSTRUCTION; - return 0; -} - -/*************************************************************************/ -/*************************************************************************/ - -/** - * ea_resolve: Resolve the address for the memory-reference EA indicated - * by opcode[5:0], storing it in state->ea_addr. Behavior is undefined if - * the EA is a direct register reference. - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * size: Access size (SIZE_*) - * access_type: Access type (ACCESS_*) - * [Return value] - * Clock cycles used (negative indicates an illegal EA) - */ -static int ea_resolve(Q68State *state, uint32_t opcode, int size, - int access_type) -{ - const unsigned int mode = EA_MODE(opcode); - const unsigned int reg = EA_REG(opcode); - const unsigned int bytes = SIZE_TO_BYTES(size); - - static const int base_cycles[8] = {0, 0, 4, 4, 6, 8, 10, 0}; - int cycles = base_cycles[mode] + (size==SIZE_L ? 4 : 0); - - switch (mode) { - case EA_INDIRECT: - state->ea_addr = state->A[reg]; - break; - case EA_POSTINCREMENT: - state->ea_addr = state->A[reg]; - state->A[reg] += bytes; - if (bytes == 1 && reg == 7) { // A7 must stay even - state->A[reg] += 1; - } - break; - case EA_PREDECREMENT: - if (access_type == ACCESS_WRITE) { - /* 2-cycle penalty not applied to write-only accesses - * (MOVE and MOVEM) */ - cycles -= 2; - } - state->A[reg] -= bytes; - if (bytes == 1 && reg == 7) { // A7 must stay even - state->A[reg] -= 1; - } - state->ea_addr = state->A[reg]; - break; - case EA_DISPLACEMENT: - state->ea_addr = state->A[reg] + (int16_t)IFETCH(state); - break; - case EA_INDEX: { - const uint16_t ext = IFETCH(state); - const unsigned int ireg = ext >> 12; // 0..15 - const int32_t index = (ext & 0x0800) ? (int32_t)state->DA[ireg] - : (int16_t)state->DA[ireg]; - const int32_t disp = (int32_t)((int8_t)ext); - state->ea_addr = state->A[reg] + index + disp; - break; - } - default: /* case EA_MISC */ - switch (reg) { - case EA_MISC_ABSOLUTE_W: - cycles += 8; - state->ea_addr = (int16_t)IFETCH(state); - break; - case EA_MISC_ABSOLUTE_L: - cycles += 12; - state->ea_addr = IFETCH(state) << 16; - state->ea_addr |= (uint16_t)IFETCH(state); - break; - case EA_MISC_PCREL: - if (access_type != ACCESS_READ) { - return -1; - } else { - cycles += 8; - state->ea_addr = state->current_PC + (int16_t)IFETCH(state); - } - break; - case EA_MISC_PCREL_INDEX: - if (access_type != ACCESS_READ) { - return -1; - } else { - cycles += 10; - const uint16_t ext = IFETCH(state); - const unsigned int ireg = ext >> 12; // 0..15 - const int32_t index = (ext & 0x0800) ? (int32_t)state->DA[ireg] - : (int16_t)state->DA[ireg]; - const int32_t disp = (int32_t)((int8_t)ext); - state->ea_addr = state->current_PC + index + disp; - } - break; - case EA_MISC_IMMEDIATE: - if (access_type != ACCESS_READ) { - return -1; - } else { - cycles += 4; - state->ea_addr = state->PC; - if (size == SIZE_B) { - state->ea_addr++; // Point at the lower byte - } - state->PC += (size==SIZE_L ? 4 : 2); - } - break; - default: - return -1; - } - } - return cycles; -} - -/*-----------------------------------------------------------------------*/ - -/** - * ea_get: Read an unsigned value from the EA indicated by opcode[5:0]. - * - * If the EA selector is invalid for the access size and mode, an illegal - * instruction exception is raised. If the EA is a memory reference, the - * size is word or long, and the address is odd, an address error - * exception is raised. In either case, the error is indicated by a - * negative value returned in *cycles_ret. - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * size: Access size (SIZE_*) - * is_rmw: Nonzero if the operand will be modified and written back - * cycles_ret: Pointer to variable to receive clock cycles used - * (negative indicates that an exception occurred) - * [Return value] - * Value read (undefined if an exception occurs) - */ -static uint32_t ea_get(Q68State *state, uint32_t opcode, int size, - int is_rmw, int *cycles_ret) -{ - const unsigned int reg = EA_REG(opcode); - switch (EA_MODE(opcode)) { - case EA_DATA_REG: - *cycles_ret = 0; - return size==SIZE_B ? (uint8_t) state->D[reg] : - size==SIZE_W ? (uint16_t)state->D[reg] : state->D[reg]; - case EA_ADDRESS_REG: - if (size == SIZE_B) { - /* An.b not permitted */ - state->exception = EX_ILLEGAL_INSTRUCTION; - *cycles_ret = -1; - return 0; - } else { - *cycles_ret = 0; - return size==SIZE_W ? (uint16_t)state->A[reg] : state->A[reg]; - } - default: { - *cycles_ret = ea_resolve(state, opcode, size, - is_rmw ? ACCESS_MODIFY : ACCESS_READ); - if (*cycles_ret < 0) { - state->exception = EX_ILLEGAL_INSTRUCTION; - return 0; - } - if (size == SIZE_B) { - return READU8(state, state->ea_addr); - } else { -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->ea_addr & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->ea_addr; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_READ; - *cycles_ret = -1; - return 0; - } -#endif - return size==SIZE_W ? READU16(state, state->ea_addr) - : READU32(state, state->ea_addr); - } - } - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * ea_set: Update a value at the EA indicated by opcode[5:0]. If the - * EA is a memory reference, uses the previously resolved address in - * state->ea_addr rather than resolving the address again. Behavior is - * undefined if the previous ea_resolve() or ea_get() failed (or if no - * previous call was made). - * - * If the EA is a memory reference, the size is word or long, and the - * address is odd, an address error exception is raised instead. - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * size: Access size (SIZE_*) - * data: Value to store - * [Return value] - * None - */ -static void ea_set(Q68State *state, uint32_t opcode, int size, uint32_t data) -{ - const unsigned int reg = EA_REG(opcode); - switch (EA_MODE(opcode)) { - case EA_DATA_REG: - switch (size) { - case SIZE_B: *(BYTE_OFS + (uint8_t *)&state->D[reg]) = data; break; - case SIZE_W: *(WORD_OFS + (uint16_t *)&state->D[reg]) = data; break; - default: state->D[reg] = data; break; - } - return; - case EA_ADDRESS_REG: - if (size == SIZE_W) { - state->A[reg] = (int16_t)data; // Sign-extended for address regs - } else { // must be SIZE_L - state->A[reg] = data; - } - return; - default: { - if (size == SIZE_B) { - WRITE8(state, state->ea_addr, data); - } else { -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->ea_addr & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->ea_addr; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_WRITE; - return; - } else -#endif - if (size == SIZE_W) { - WRITE16(state, state->ea_addr, data); - } else { - WRITE32(state, state->ea_addr, data); - } - } - return; - } - } -} - -/*************************************************************************/ -/*********************** Major instruction groups ************************/ -/*************************************************************************/ - -/** - * op_imm: Immediate instructions (format 0000 xxx0 xxxx xxxx). - */ -static int op_imm(Q68State *state, uint32_t opcode) -{ - /* Check for bit-twiddling and illegal opcodes first */ - enum {OR = 0, AND, SUB, ADD, _BIT, EOR, CMP, _ILL} aluop; - aluop = opcode>>9 & 7; - if (aluop == _BIT) { - return op_bit(state, opcode); - } else if (aluop == _ILL) { - return op_ill(state, opcode); - } - - /* Get the instruction size */ - INSN_GET_SIZE; - if (size == 3) { - return op_ill(state, opcode); - } - const int bytes = SIZE_TO_BYTES(size); - const int shift = bytes*8 - 1; - const uint32_t valuemask = ~(~1 << shift); - - /* Fetch the immediate value */ - uint32_t imm = (uint16_t)IFETCH(state); - if (size == SIZE_B) { - imm &= 0xFF; - } else if (size == SIZE_L) { - imm = imm<<16 | (uint16_t)IFETCH(state); - } - - /* Fetch the EA operand (which may be SR or CCR) */ - int use_SR; - int cycles; - uint32_t ea_val; - if ((aluop==OR || aluop==AND || aluop==EOR) && (opcode & 0x3F) == 0x3C) { - /* xxxI #imm,SR (or CCR) use the otherwise-invalid form of an - * immediate value destination */ - if (size == SIZE_W && !(state->SR & SR_S)) { - state->exception = EX_PRIVILEGE_VIOLATION; - return 0; - } - use_SR = 1; - cycles = 8; // Total instruction time is 20 cycles - switch (size) { - case SIZE_B: ea_val = state->SR & 0xFF; break; - case SIZE_W: ea_val = state->SR; break; - default: return op_ill(state, opcode); - } - } else { - use_SR = 0; - ea_val = ea_get(state, opcode, size, 1, &cycles); - if (cycles < 0) { - return 0; - } - } - - /* Perform the operation */ - uint32_t result; - if (aluop == ADD || aluop == SUB) { - INSN_CLEAR_XCC(); - } else { - INSN_CLEAR_CC(); - } - switch (aluop) { - case OR: result = ea_val | imm; - break; - case AND: result = ea_val & imm; - break; - case EOR: result = ea_val ^ imm; - break; - case CMP: if (size == SIZE_L) { // CMPI takes less time in most cases - if (EA_MODE(opcode) != EA_DATA_REG) { - cycles -= 8; - } else { - cycles -= 2; - } - } else { - if (EA_MODE(opcode) != EA_DATA_REG) { - cycles -= 4; - } - } - /* fall through to... */ - case SUB: { result = (ea_val - imm) & valuemask; - if (((imm ^ ea_val) & (result ^ ea_val)) >> shift) { - state->SR |= SR_V; - } - if ((int)((imm >> shift) - (ea_val >> shift) - + (result >> shift)) > 0) { - state->SR |= SR_C; - if (aluop != CMP) { - state->SR |= SR_X; - } - } - break; - } - default: // case ADD - result = (ea_val + imm) & valuemask; - if (((ea_val ^ result) & (imm ^ result)) >> shift) { - state->SR |= SR_V; - } - if ((int)((ea_val >> shift) + (imm >> shift) - - (result >> shift)) > 0) { - state->SR |= SR_X | SR_C; - } - break; - } - INSN_SETNZ_SHIFT(result); - - /* Update the EA operand (if not CMPI) */ - if (aluop != CMP) { - if (use_SR) { - if (size == SIZE_W) { - set_SR(state, result); - } else { - state->SR &= 0xFF00; - state->SR |= result; - } - } else { - ea_set(state, opcode, size, result); - } - } - - /* All done */ - return (size==SIZE_L ? 16 : 8) - + (EA_MODE(opcode) == EA_DATA_REG ? 0 : 4) + cycles; -} - -/*************************************************************************/ - -/** - * op_bit: Bit-twiddling instructions (formats 0000 rrr1 xxxx xxxx and - * 0000 1000 xxxx xxxx). - */ -static int op_bit(Q68State *state, uint32_t opcode) -{ - /* Check early for MOVEP (coded as BTST/BCHG/BCLR/BSET Dn,An) */ - if (EA_MODE(opcode) == EA_ADDRESS_REG) { - if (opcode & 0x0100) { - return opMOVP(state, opcode); - } else { - return op_ill(state, opcode); - } - } - - enum {BTST = 0, BCHG = 1, BCLR = 2, BSET = 3} op = opcode>>6 & 3; - int cycles; - - /* Get the bit number to operate on */ - unsigned int bitnum; - if (opcode & 0x0100) { - /* Bit number in register */ - INSN_GET_REG; - bitnum = state->D[reg]; - cycles = 0; - } else { - bitnum = IFETCH(state); - cycles = 4; - } - - /* EA operand is 32 bits when coming from a register, 8 when from memory */ - int size; - switch (EA_MODE(opcode)) { - case EA_DATA_REG: - size = SIZE_L; - bitnum %= 32; - break; - default: - size = SIZE_B; - bitnum %= 8; - break; - } - int cycles_tmp; - uint32_t value = ea_get(state, opcode, size, 1, &cycles_tmp); - if (cycles_tmp < 0) { - return 0; - } - cycles += cycles_tmp; - if (size == SIZE_L && (op == BCLR || op == BTST)) { - cycles += 2; - } - - /* Perform the operation */ - if ((value >> bitnum) & 1) { - state->SR &= ~SR_Z; - } else { - state->SR |= SR_Z; - } - switch (op) { - case BTST: /* Nothing to do */ break; - case BCHG: value ^= 1 << bitnum; break; - case BCLR: value &= ~(1 << bitnum); break; - case BSET: value |= 1 << bitnum; break; - } - - /* Update EA operand (if not BTST) */ - if (op != BTST) { - ea_set(state, opcode, size, value); - } - - /* Return cycle count; note that the times for BCHG.L, BCLR.L, and - * BSET.L are maximums (though how they vary is undocumented) */ - return (op==BTST ? 4 : 8) + cycles; -} - -/*************************************************************************/ - -/** - * opMOVE: MOVE.[bwl] instruction (format {01,10,11}xx xxxx xxxx xxxx). - */ -static int opMOVE(Q68State *state, uint32_t opcode) -{ - const int size = (opcode>>12==1 ? SIZE_B : opcode>>12==2 ? SIZE_L : SIZE_W); - - int cycles_src; - const uint32_t data = ea_get(state, opcode, size, 0, &cycles_src); - if (cycles_src < 0) { - return 0; - } - - /* Rearrange the opcode bits so we can pass the destination EA to - * ea_resolve() */ - const uint32_t dummy_opcode = (opcode>>9 & 7) | (opcode>>3 & 0x38); - int cycles_dest; - if (EA_MODE(dummy_opcode) <= EA_ADDRESS_REG) { - cycles_dest = 0; - } else { - cycles_dest = ea_resolve(state, dummy_opcode, size, ACCESS_WRITE); - if (cycles_dest < 0) { - return op_ill(state, opcode); - } - } - - /* Update condition codes if the target is not an address register */ - if (EA_MODE(dummy_opcode) != EA_ADDRESS_REG) { - INSN_CLEAR_CC(); - INSN_SETNZ(size==SIZE_B ? (int8_t)data : - size==SIZE_W ? (int16_t)data : (int32_t)data); - } - - /* Update the destination EA and return */ - ea_set(state, dummy_opcode, size, data); - return 4 + cycles_src + cycles_dest; -} - -/*************************************************************************/ - -/** - * op4xxx: Miscellaneous instructions (format 0100 xxx0 xxxx xxxx). - */ -static int op4xxx(Q68State *state, uint32_t opcode) -{ - const unsigned int index = (opcode>>7 & 0x1C) | (opcode>>6 & 3); -#ifdef COUNT_OPCODES - q68_4xxx_ops[index]++; -#endif - return (*opcode_4xxx_table[index])(state, opcode); -} - -/*************************************************************************/ - -/** - * op_CHK: CHK instruction (format 0100 rrr1 10xx xxxx). - */ -static int op_CHK(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - int size = SIZE_W; // Bit 7 == 0 indicates long mode on the 68020 - - int cycles; - int32_t upper; // Yes, it's signed - if (EA_MODE(opcode) == EA_ADDRESS_REG) { - return op_ill(state, opcode); - } - upper = ea_get(state, opcode, size, 0, &cycles); - if (cycles < 0) { - return 0; - } - if (size == SIZE_W) { - upper = (int32_t)(int16_t)upper; - } - - int32_t value; - if (size == SIZE_W) { - value = (int32_t)(int16_t)state->D[reg]; - } else { - value = (int32_t)state->D[reg]; - } - if (value < 0) { - state->SR |= SR_N; - state->exception = EX_CHK; - return cycles; - } else if (value > upper) { - state->SR &= ~SR_N; - state->exception = EX_CHK; - return cycles; - } - - return 10 + cycles; -} - -/*************************************************************************/ - -/** - * op_LEA: LEA instruction (format 0100 rrr1 11xx xxxx). - */ -static int op_LEA(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - - /* Register, predecrement, postincrement, immediate modes are illegal */ - if (EA_MODE(opcode) == EA_DATA_REG - || EA_MODE(opcode) == EA_ADDRESS_REG - || EA_MODE(opcode) == EA_POSTINCREMENT - || EA_MODE(opcode) == EA_PREDECREMENT - || (EA_MODE(opcode) == EA_MISC && EA_REG(opcode) == EA_MISC_IMMEDIATE) - ) { - return op_ill(state, opcode); - } - - int cycles = ea_resolve(state, opcode, SIZE_W, ACCESS_READ); - if (cycles < 0) { - return op_ill(state, opcode); - } - if (cycles % 4 == 2) { // d(An,ix) and d(PC,ix) take 2 extra cycles - cycles += 2; - } - state->A[reg] = state->ea_addr; - return cycles; -} - -/*************************************************************************/ - -/** - * opADSQ: ADDQ and SUBQ instructions (format 0101 iiix xxxx xxxx). - */ -static int opADSQ(Q68State *state, uint32_t opcode) -{ - const int is_sub = opcode & 0x0100; - INSN_GET_COUNT; - INSN_GET_SIZE; - if (EA_MODE(opcode) == EA_ADDRESS_REG && size == 1) { - size = 2; // ADDQ.W #imm,An is equivalent to ADDQ.L #imm,An - } - const int bytes = SIZE_TO_BYTES(size); - const int shift = bytes*8 - 1; - const uint32_t valuemask = ~(~1 << shift); - int cycles; - uint32_t data = ea_get(state, opcode, size, 1, &cycles); - if (cycles < 0) { - return 0; - } - - uint32_t result; - if (is_sub) { - result = data - count; - } else { - result = data + count; - } - result &= valuemask; - if (EA_MODE(opcode) != EA_ADDRESS_REG) { - INSN_CLEAR_XCC(); - INSN_SETNZ_SHIFT(result); - if ((is_sub ? ~result & data : result & ~data) >> shift) { - state->SR |= SR_V; - } - if ((is_sub ? result & ~data : ~result & data) >> shift) { - state->SR |= SR_X | SR_C; - } - } - - ea_set(state, opcode, size, result); - return (size==SIZE_L || EA_MODE(opcode) == EA_ADDRESS_REG ? 8 : 4) - + (EA_MODE(opcode) >= EA_INDIRECT ? 4 : 0) + cycles; -} - -/*************************************************************************/ - -/** - * op_Scc: Scc instruction (format 0101 cccc 11xx xxxx). - */ -static int op_Scc(Q68State *state, uint32_t opcode) -{ - if (EA_MODE(opcode) == EA_ADDRESS_REG) { - /* DBcc Dn,disp is coded as Scc An with an extension word */ - return opDBcc(state, opcode); - } - - INSN_GET_COND; - const int is_true = INSN_COND_TRUE(cond); - /* From the cycle counts, it looks like this is a standard read/write - * access rather than a write-only access */ - int cycles; - if (EA_MODE(opcode) == EA_DATA_REG) { - cycles = 0; - } else { - cycles = ea_resolve(state, opcode, SIZE_B, ACCESS_MODIFY); - if (cycles < 0) { - return op_ill(state, opcode); - } - } - ea_set(state, opcode, SIZE_B, is_true ? 0xFF : 0x00); - if (EA_MODE(opcode) == EA_DATA_REG) { - /* Scc Dn is a special case */ - return is_true ? 6 : 4; - } else { - return 8 + cycles; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * op_DBcc: DBcc instruction (format 0101 cccc 1100 1xxx). - */ -static int opDBcc(Q68State *state, uint32_t opcode) -{ - INSN_GET_COND; - const int is_true = INSN_COND_TRUE(cond); - INSN_GET_REG0; - INSN_GET_IMM16; - if (is_true) { - return 12; - } else if (--(*(WORD_OFS + (int16_t *)&state->D[reg0])) == -1) { - return 14; - } else { - state->PC = state->current_PC + imm16; - return 10; - } -} - -/*************************************************************************/ - -/** - * op_Bcc: Conditional branch instructions (format 0110 cccc dddd dddd). - */ -static int op_Bcc(Q68State *state, uint32_t opcode) -{ - INSN_GET_COND; - INSN_GET_DISP8; - int cycles = 0; - if (disp == 0) { - disp = (int16_t)IFETCH(state); - cycles = 4; - } - if (cond == COND_F) { - /* BF is really BSR */ -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->A[7]; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_WRITE; - return 0; - } -#endif - PUSH32(state, state->PC); - state->PC = state->current_PC + disp; - return 18; - } else if (INSN_COND_TRUE(cond)) { - state->PC = state->current_PC + disp; - return 10; - } else { - return 8 + cycles; - } -} - -/*************************************************************************/ - -/** - * opMOVQ: MOVEQ instruction (format 0111 rrr0 iiii iiii). - */ -static int opMOVQ(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_IMM8; - state->D[reg] = imm8; - INSN_CLEAR_CC(); - INSN_SETNZ(imm8); - return 4; -} - -/*************************************************************************/ - -/** - * op_alu: Non-immediate ALU instructions (format 1ooo rrrx xxxx xxxx for - * ooo = 000, 001, 011, 100, 101). - */ -static int op_alu(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_SIZE; - - /* Pass off special and invalid instructions early */ - if (size != 3) { - if ((opcode & 0xB130) == 0x9100) { - /* ADDX/SUBX are coded as ADD/SUB.* Dn, */ - return opADSX(state, opcode); - } - if ((opcode & 0xB1F0) == 0x8100) { - /* ABCD/SBCD are coded as AND/OR.b Dn, */ - return op_BCD(state, opcode); - } - if ((opcode & 0xF130) == 0xC100) { - /* EXG is coded as AND.[wl] Dn, */ - return op_EXG(state, opcode); - } - if ((opcode & 0xF130) == 0x8100) { - /* OR.[wl] Dn, is invalid on the 68000 (later PACK/UNPK) */ - return op_ill(state, opcode); - } - if ((opcode & 0xF138) == 0xB108 && (opcode>>6 & 3) != 3) { - /* CMPM is coded as EOR.* Dn, */ - return opCMPM(state, opcode); - } - } - - const int bytes = SIZE_TO_BYTES(size); - const int shift = bytes*8 - 1; - const uint32_t valuemask = ~(~1 << shift); - int ea_dest = opcode & 0x100; - int areg_dest = 0; // For ADDA/SUBA/CMPA - enum {OR, AND, EOR, CMP, SUB, ADD} aluop; - - /* Find the instruction for the opcode group */ - switch (opcode>>12) { - case 0x8: aluop = OR; break; - case 0x9: aluop = SUB; break; - case 0xB: aluop = (((opcode>>6)+1) & 7) <= 4 ? CMP : EOR; break; - case 0xC: aluop = AND; break; - default: aluop = ADD; break; // case 0xD - } - - /* Handle the special formats of ADDA/SUBA/CMPA */ - if ((aluop == ADD || aluop == SUB || aluop == CMP) && size == 3) { - size = ea_dest ? SIZE_L : SIZE_W; - ea_dest = 0; - areg_dest = 1; - } - - /* Retrieve the register and EA values */ - uint32_t reg_val = areg_dest ? state->A[reg] : (state->D[reg] & valuemask); - int cycles; - uint32_t ea_val = ea_get(state, opcode, size, ea_dest, &cycles); - if (cycles < 0) { - return 0; - } - if (size == SIZE_L || areg_dest) { - cycles += 4; - } - if (ea_dest) { - cycles += 4; - } else if ((aluop == CMP && areg_dest) - || (size == SIZE_L - && (EA_MODE(opcode) <= EA_ADDRESS_REG - || (EA_MODE(opcode) == EA_MISC - && EA_REG(opcode) == EA_MISC_IMMEDIATE)))) { - cycles -= 2; - } - - /* Perform the actual computation */ - uint32_t result; - if (!areg_dest || aluop == CMP) { - if (aluop == ADD || aluop == SUB) { - INSN_CLEAR_XCC(); - } else { - INSN_CLEAR_CC(); - } - } - switch (aluop) { - case OR: result = reg_val | ea_val; - break; - case AND: result = reg_val & ea_val; - break; - case EOR: result = reg_val ^ ea_val; - break; - case CMP: /* fall through to... */ - case SUB: { uint32_t src, dest; - if (areg_dest) { - /* CMPA/SUBA keep all 32 bits, and SUBA doesn't - * touch flags */ - src = ea_val; - dest = reg_val; - result = reg_val - ea_val; - if (aluop == SUB) { - break; - } - } else { - if (ea_dest) { - src = reg_val; - dest = ea_val; - } else { - src = ea_val; - dest = reg_val; - } - result = (dest - src) & valuemask; - } - if (((src ^ dest) & (result ^ dest)) >> shift) { - state->SR |= SR_V; - } - if ((int)((src >> shift) - (dest >> shift) - + (result >> shift)) > 0) { - state->SR |= SR_C; - if (aluop != CMP) { - state->SR |= SR_X; - } - } - break; - } - default: // case ADD - if (areg_dest) { - /* ADDA keeps all 32 bits and doesn't touch flags */ - result = reg_val + ea_val; - break; - } - result = (reg_val + ea_val) & valuemask; - if (((reg_val ^ result) & (ea_val ^ result)) >> shift) { - state->SR |= SR_V; - } - if ((int)((reg_val >> shift) + (ea_val >> shift) - - (result >> shift)) > 0) { - state->SR |= SR_X | SR_C; - } - break; - } // switch (aluop) - if (!areg_dest || aluop == CMP) { - INSN_SETNZ_SHIFT(result); - } - - /* Store the result in the proper place (if the instruction is not CMP) */ - if (aluop != CMP) { - if (ea_dest) { - ea_set(state, opcode, size, result); - } else if (areg_dest) { - state->A[reg] = result; - } else if (size == SIZE_B) { - *(BYTE_OFS + (uint8_t *)&state->D[reg]) = result; - } else if (size == SIZE_W) { - *(WORD_OFS + (uint16_t *)&state->D[reg]) = result; - } else { // size == SIZE_L - state->D[reg] = result; - } - } - - return 4 + cycles; -} - -/*************************************************************************/ - -/** - * op_DIV: DIVU and DIVS instructions (format 1000 rrrx 11xx xxxx). - */ -static int op_DIV(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - const int sign = opcode & (1<<8); - - state->SR &= ~SR_C; // Always cleared, even on exception - - int cycles; - const uint16_t divisor = ea_get(state, opcode, SIZE_W, 0, &cycles); - if (cycles < 0) { - return 0; - } - if (divisor == 0) { - state->exception = EX_DIVIDE_BY_ZERO; - return cycles; - } - - int32_t quotient, remainder; - if (sign) { - quotient = (int32_t)state->D[reg] / (int16_t)divisor; - remainder = (int32_t)state->D[reg] % (int16_t)divisor; - if (quotient < -0x8000 || quotient > 0x7FFF) { - state->SR |= SR_V; - } else { - state->SR &= ~SR_V; - } - } else { - quotient = state->D[reg] / divisor; - remainder = state->D[reg] % divisor; - if (quotient & 0xFFFF0000) { - state->SR |= SR_V; - } else { - state->SR &= ~SR_V; - } - } - - if (!(state->SR & SR_V)) { - state->D[reg] = (quotient & 0xFFFF) | (remainder << 16); - if (quotient & 0x8000) { - state->SR |= SR_N; - } else { - state->SR &= ~SR_N; - } - if (quotient == 0) { - state->SR |= SR_Z; - } else { - state->SR &= ~SR_Z; - } - } - /* The 68000 docs say that the timing difference between best and - * worst cases is less than 10%, so we just return the worst case */ - return (sign ? 158 : 140) + cycles; -} - -/*************************************************************************/ - -/** - * opAxxx: $Axxx illegal instruction set (format 1010 xxxx xxxx xxxx). - */ -static int opAxxx(Q68State *state, uint32_t opcode) -{ - state->exception = EX_LINE_1010; - return 0; -} - -/*************************************************************************/ - -/** - * op_MUL: MULU and MULS instructions (format 1100 rrrx 11xx xxxx). - */ -static int op_MUL(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - const int sign = opcode & (1<<8); - - int cycles; - const uint16_t data = ea_get(state, opcode, SIZE_W, 0, &cycles); - if (cycles < 0) { - return 0; - } - - if (sign) { - state->D[reg] = (int16_t)state->D[reg] * (int16_t)data; - } else { - state->D[reg] = (uint16_t)state->D[reg] * data; - } - INSN_CLEAR_CC(); - INSN_SETNZ(state->D[reg]); - - /* Precise timing varies with the effective address; the algorithm is - * implemented below for reference, but for typical usage it's probably - * not important to be exact */ -#ifdef MUL_PRECISE_TIMING // not normally defined - if (sign) { - uint32_t temp; - for (temp = (uint32_t)data << 1; temp != 0; temp >>= 1) { - if ((temp & 3) == 1 || (temp & 3) == 2) { - cycles += 2; - } - } - } else { - unsigned int temp; - for (temp = data; temp != 0; temp >>= 1) { - if (temp & 1) { - cycles += 2; - } - } - } - return 38 + cycles; -#else // !MUL_PRECISE_TIMING - return 54 + cycles; -#endif -} - -/*************************************************************************/ - -/** - * opshft: Shift and rotate instructions (format 1110 xxxx xxxx xxxx). - */ -static int opshft(Q68State *state, uint32_t opcode) -{ - const int is_left = opcode & 0x0100; - INSN_GET_SIZE; - INSN_GET_COUNT; - INSN_GET_REG0; - int is_memory; - int type; // Shift/rotate type (0=ASL/ASR, 1=LSL/LSR, ...) - uint32_t data; - int cycles; - - if (size == 3) { - /* Memory shift/rotate */ - is_memory = 1; - if ((opcode & 0x0800) || EA_MODE(opcode) <= EA_ADDRESS_REG) { - return op_ill(state, opcode); - } - size = SIZE_W; - type = opcode>>9 & 3; - count = 1; - data = ea_get(state, opcode, size, 1, &cycles); - if (cycles < 0) { - return 0; - } - } else { - /* Register shift/rotate */ - is_memory = 0; - type = opcode>>3 & 3; - if (opcode & 0x0020) { - INSN_GET_REG; - count = state->D[reg] & 63; - } - data = size==SIZE_B ? (uint8_t) state->D[reg0] : - size==SIZE_W ? (uint16_t)state->D[reg0] : state->D[reg0]; - cycles = 0; - } - cycles += count*2; - - INSN_CLEAR_CC(); - if (count > 0) { - const int nbits = (size==SIZE_B ? 8 : size==SIZE_W ? 16 : 32); - switch (type) { - case 0: // ASL/ASR - state->SR &= ~SR_X; - if (is_left) { - int V = 0, C; - /* Have to shift bit by bit to detect overflow */ - for (; count > 0; count--) { - C = (data >> (nbits-1)) & 1; - data <<= 1; - V |= (C ^ (data >> (nbits-1))) & 1; - } - if (V) { - state->SR |= SR_V; - } - if (C) { - state->SR |= SR_X | SR_C; - } - } else { - if (size == SIZE_B) { // Sign extend if necessary - data = (int8_t)data; - } else if (size == SIZE_W) { - data = (int16_t)data; - } - if (count > nbits) { - count = 32; // Some systems break with a shift count >32 - } - data = (int32_t)data >> (count-1); - if (data & 1) { - state->SR |= SR_X | SR_C; - } - data = (int32_t)data >> 1; - } - break; - case 1: // LSL/LSR - state->SR &= ~SR_X; - if (count > nbits) { - data = 0; - } else if (is_left) { - data <<= count-1; - if ((data >> (nbits-1)) & 1) { - state->SR |= SR_X | SR_C; - } - data <<= 1; - } else { - data = (int32_t)data >> (count-1); - if (data & 1) { - state->SR |= SR_X | SR_C; - } - data = (int32_t)data >> 1; - } - break; - case 2: { // ROXL/ROXR - uint32_t X = (state->SR >> SR_X_SHIFT) & 1; - state->SR &= ~SR_X; - if (is_left) { - for (; count > 0; count--) { - const int new_X = (data >> (nbits-1)) & 1; - data = (data << 1) | X; - X = new_X; - } - } else { - for (; count > 0; count--) { - const int new_X = data & 1; - data = (data >> 1) | (X << (nbits-1)); - X = new_X; - } - } - if (X) { - state->SR |= SR_C | SR_X; - } - break; - } - default: { // (case 3) ROL/ROR - count %= nbits; - if (is_left) { - data = (data << count) | (data >> (nbits - count)); - if ((data >> (nbits-1)) & 1) { - state->SR |= SR_C; - } - data <<= 1; - } else { - data = (data >> count) | (data << (nbits - count)); - if (data & 1) { - state->SR |= SR_C; - } - data = (int32_t)data >> 1; - } - break; - } - } // switch (type) - } else { // count == 0 - if (type == 2 && (state->SR & SR_X)) { - state->SR |= SR_C; - } - } - INSN_SETNZ(size==SIZE_B ? (int8_t) data : - size==SIZE_W ? (int16_t)data : data); - - if (is_memory) { - ea_set(state, opcode, size, data); - } else { - switch (size) { - case SIZE_B: *(BYTE_OFS + (uint8_t *)&state->D[reg0]) = data; break; - case SIZE_W: *(WORD_OFS + (uint16_t *)&state->D[reg0]) = data; break; - default: state->D[reg0] = data; break; - } - } - return (size==SIZE_L ? 8 : 6) + cycles; -} - -/*************************************************************************/ - -/** - * opFxxx: $Fxxx illegal instruction set (format 1111 xxxx xxxx xxxx). - */ -static int opFxxx(Q68State *state, uint32_t opcode) -{ - state->exception = EX_LINE_1111; - return 0; -} - -/*************************************************************************/ -/*********************** $4xxx group instructions ************************/ -/*************************************************************************/ - -/** - * op4alu: Single-operand ALU instructions in the $4xxx opcode range - * (format 0100 ooo0 ssxx xxxx for ooo = 000, 001, 010, 011, 101). - */ -static int op4alu(Q68State *state, uint32_t opcode) -{ - INSN_GET_SIZE; - const int bytes = SIZE_TO_BYTES(size); - const int shift = bytes*8 - 1; - const uint32_t valuemask = ~(~1 << shift); - enum {NEGX = 0, CLR = 1, NEG = 2, NOT = 3, TST = 5} aluop; - aluop = opcode>>9 & 7; - - if (EA_MODE(opcode) == EA_ADDRESS_REG) { // Address registers not allowed - return op_ill(state, opcode); - } - - /* Retrieve the EA value */ - int cycles; - uint32_t value = ea_get(state, opcode, size, 1, &cycles); - if (cycles < 0) { - return 0; - } - if (aluop != TST) { - if (EA_MODE(opcode) == EA_DATA_REG) { - if (size == SIZE_L) { - cycles += 2; - } - } else { - cycles += (size == SIZE_L) ? 8 : 4; - } - } - - /* Perform the actual computation */ - uint32_t result; - if (aluop == NEGX) { - state->SR &= ~(SR_N | SR_V | SR_C); // Z is never set, only cleared - } else { - INSN_CLEAR_CC(); - } - switch (aluop) { - case NEGX: { int X = (state->SR >> SR_X_SHIFT) & 1; - result = (0 - value - X) & valuemask; - if (result != 0) { - state->SR &= ~SR_Z; - } - goto NEG_common; - } - case NEG: result = (0 - value) & valuemask; - if (result == 0) { - state->SR |= SR_Z; - } else { - state->SR &= ~SR_Z; - } - NEG_common: - if (result >> shift) { - state->SR |= SR_N; - } - if ((value & result) >> shift) { - state->SR |= SR_V; - } - if ((value | result) != 0) { - state->SR |= SR_X | SR_C; - } else { - state->SR &= ~SR_X; - } - break; - case CLR: result = 0; - state->SR |= SR_Z; - break; - case NOT: result = ~value & valuemask; - INSN_SETNZ_SHIFT(result); - break; - default: // case TST - result = value; // Avoid a compiler warning - INSN_SETNZ_SHIFT(value); - break; - } // switch (aluop) - - /* Store the result in the proper place (if the instruction is not TST) */ - if (aluop != TST) { - ea_set(state, opcode, size, result); - } - - return 4 + cycles; -} - -/*************************************************************************/ - -/** - * opMVSR: MOVE to/from SR/CCR instructions (format 0100 0xx0 11xx xxxx). - */ -static int opMVSR(Q68State *state, uint32_t opcode) -{ - int is_CCR; - int ea_dest; - int cycles; - switch (opcode>>9 & 3) { - case 0: // MOVE SR, - is_CCR = 0; - ea_dest = 1; - cycles = (EA_MODE(opcode) == EA_DATA_REG) ? 6 : 8; - break; - case 1: // Undefined (MOVE CCR, on 68010) - return op_ill(state, opcode); - case 2: // MOVE ,CCR - is_CCR = 1; - ea_dest = 0; - cycles = 12; - break; - default: // MOVE ,SR (case 3) - if (!(state->SR & SR_S)) { - state->exception = EX_PRIVILEGE_VIOLATION; - return 0; - } - is_CCR = 0; - ea_dest = 0; - cycles = 12; - break; - } - - if (EA_MODE(opcode) == EA_ADDRESS_REG) { // Address registers not allowed - return op_ill(state, opcode); - } - - /* Motorola docs say the address is read before being written, even - * for the SR, format; also, the access size is a word even for - * CCR operations. */ - int cycles_tmp; - uint16_t value = ea_get(state, opcode, SIZE_W, ea_dest, &cycles_tmp); - if (cycles_tmp < 0) { - return 0; - } - cycles += cycles_tmp; - - if (ea_dest) { - uint16_t value = state->SR; - if (is_CCR) { - value &= 0x00FF; - } - ea_set(state, opcode, SIZE_W, value); - } else { - if (!is_CCR) { - set_SR(state, value); - } - } - return cycles; -} - -/*************************************************************************/ - -/** - * opNBCD: NBCD instruction (format 0100 1000 00xx xxxx). - */ -static int opNBCD(Q68State *state, uint32_t opcode) -{ - if (EA_MODE(opcode) == EA_ADDRESS_REG) { // Address registers not allowed - return op_ill(state, opcode); - } - - int cycles; - int value = ea_get(state, opcode, SIZE_B, 1, &cycles); - if (cycles < 0) { - return 0; - } - - int result; - int X = (state->SR >> SR_X_SHIFT) & 1; - state->SR &= ~(SR_X | SR_C); // Z is never set, only cleared - /* Slightly convoluted to match what a real 68000 does (see SBCD) */ - int res_low = 0 - (value & 0x0F) - X; - int borrow = 0; - if (res_low < 0) { - res_low += 10; - borrow = 1<<4; - } - int res_high = 0 - (value & 0xF0) - borrow; - if (res_high < 0) { - res_high += 10<<4; - state->SR |= SR_X | SR_C; - } - result = res_high + res_low; - if (result < 0) { - state->SR |= SR_X | SR_C; - } - result &= 0xFF; - if (result != 0) { - state->SR &= ~SR_Z; - } - - ea_set(state, opcode, SIZE_B, result); - return (EA_MODE(opcode) == EA_DATA_REG ? 6 : 8) + cycles; -} - -/*************************************************************************/ - -/** - * op_PEA: PEA instruction (format 0100 1000 01xx xxxx). - */ -static int op_PEA(Q68State *state, uint32_t opcode) -{ - /* SWAP is coded as PEA Dn */ - if (EA_MODE(opcode) == EA_DATA_REG) { - return opSWAP(state, opcode); - } - - if (EA_MODE(opcode) == EA_DATA_REG - || EA_MODE(opcode) == EA_ADDRESS_REG - || EA_MODE(opcode) == EA_POSTINCREMENT - || EA_MODE(opcode) == EA_PREDECREMENT - || (EA_MODE(opcode) == EA_MISC && EA_REG(opcode) == EA_MISC_IMMEDIATE) - ) { - return op_ill(state, opcode); - } - - int cycles = ea_resolve(state, opcode, SIZE_W, ACCESS_READ); - if (cycles < 0) { - return op_ill(state, opcode); - } - if (cycles % 4 == 2) { // d(An,ix) and d(PC,ix) take 2 extra cycles - cycles += 2; - } -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->A[7]; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_WRITE; - return 0; - } -#endif - PUSH32(state, state->ea_addr); - return 8 + cycles; -} - -/*************************************************************************/ - -/** - * opSWAP: SWAP instruction (format 0100 1000 0100 0rrr). - */ -static int opSWAP(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG0; - state->D[reg0] = state->D[reg0]>>16 | state->D[reg0]<<16; - INSN_CLEAR_CC(); - INSN_SETNZ(state->D[reg0]); - return 4; -} - -/*************************************************************************/ - -/** - * op_TAS: TAS instruction (format 0100 1010 11xx xxxx). Also covers the - * ILLEGAL instruction (format 0100 1010 1111 1100). - */ -static int op_TAS(Q68State *state, uint32_t opcode) -{ - if (EA_MODE(opcode) == EA_ADDRESS_REG) { // Address registers not allowed - return op_ill(state, opcode); - } - - int cycles; - int8_t value = ea_get(state, opcode, SIZE_B, 1, &cycles); - if (cycles < 0) { - /* Note that the ILLEGAL instruction is coded as TAS #imm, so it - * will be rejected as unwriteable by ea_get() */ - return 0; - } - - INSN_CLEAR_CC(); - INSN_SETNZ(value); - ea_set(state, opcode, SIZE_B, value | 0x80); - return (EA_MODE(opcode) == EA_DATA_REG ? 4 : 10) + cycles; -} - -/*************************************************************************/ - -/** - * op_EXT: EXT instruction (format 0100 1000 1s00 0rrr). - */ -static int op_EXT(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG0; - INSN_CLEAR_CC(); - if (opcode & 0x0040) { - int16_t value = (int16_t)state->D[reg0]; - state->D[reg0] = (int32_t)value; - INSN_SETNZ(value); - } else { - int8_t value = (int16_t)state->D[reg0]; - *(WORD_OFS + (int16_t *)&state->D[reg0]) = (int16_t)value; - INSN_SETNZ(value); - } - return 4; -} - -/*************************************************************************/ - -/** - * op_STM: MOVEM reglist, (i.e. STore Multiple) instruction (format - * 0100 1000 1sxx xxxx). - */ -static int op_STM(Q68State *state, uint32_t opcode) -{ - /* EXT.* is coded as MOVEM.* reglist,Dn */ - if (EA_MODE(opcode) == EA_DATA_REG) { - return op_EXT(state, opcode); - } - - unsigned int regmask = IFETCH(state); - int size = (opcode & 0x0040) ? SIZE_L : SIZE_W; - if (EA_MODE(opcode) <= EA_ADDRESS_REG - || EA_MODE(opcode) == EA_POSTINCREMENT // Not allowed for store - ) { - return op_ill(state, opcode); - } - - /* Avoid modifying the register during address resolution */ - uint16_t safe_ea; - if (EA_MODE(opcode) == EA_PREDECREMENT) { - safe_ea = EA_INDIRECT<<3 | EA_REG(opcode); - } else { - safe_ea = opcode; - } - int cycles = ea_resolve(state, safe_ea, SIZE_W, ACCESS_WRITE); - if (cycles < 0) { - return op_ill(state, opcode); - } -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->ea_addr & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->ea_addr; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_WRITE; - return 0; - } -#endif - - if (EA_MODE(opcode) == EA_PREDECREMENT) { - /* Register order is reversed in predecrement mode */ - int reg; - for (reg = 15; reg >= 0; reg--, regmask >>= 1) { - if (regmask & 1) { - if (size == SIZE_W) { - state->ea_addr -= 2; - WRITE16(state, state->ea_addr, state->DA[reg]); - cycles += 4; - } else { - state->ea_addr -= 4; - WRITE32(state, state->ea_addr, state->DA[reg]); - cycles += 8; - } - } - } - state->A[EA_REG(opcode)] = state->ea_addr; - } else { - int reg; - for (reg = 0; reg < 16; reg++, regmask >>= 1) { - if (regmask & 1) { - if (size == SIZE_W) { - WRITE16(state, state->ea_addr, state->DA[reg]); - state->ea_addr += 2; - cycles += 4; - } else { - WRITE32(state, state->ea_addr, state->DA[reg]); - state->ea_addr += 4; - cycles += 8; - } - } - } - } - - return 4 + cycles; -} - -/*-----------------------------------------------------------------------*/ - -/** - * op_LDM: MOVEM ,reglist (i.e. LoaD Multiple) instruction (format - * 0100 1100 1sxx xxxx). - */ -static int op_LDM(Q68State *state, uint32_t opcode) -{ - unsigned int regmask = IFETCH(state); - int size = (opcode & 0x0040) ? SIZE_L : SIZE_W; - if (EA_MODE(opcode) <= EA_ADDRESS_REG - || EA_MODE(opcode) == EA_PREDECREMENT // Not allowed for load - ) { - return op_ill(state, opcode); - } - - /* Avoid modifying the register during address resolution */ - uint16_t safe_ea; - if (EA_MODE(opcode) == EA_POSTINCREMENT) { - safe_ea = EA_INDIRECT<<3 | EA_REG(opcode); - } else { - safe_ea = opcode; - } - int cycles = ea_resolve(state, safe_ea, SIZE_W, ACCESS_READ); - if (cycles < 0) { - return op_ill(state, opcode); - } -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->ea_addr & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->ea_addr; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_READ; - return 0; - } -#endif - - int reg; - for (reg = 0; reg < 16; reg++, regmask >>= 1) { - if (regmask & 1) { - if (size == SIZE_W) { - int16_t value = READS16(state, state->ea_addr); - if (reg < 8) { - *(WORD_OFS + (uint16_t *)&state->D[reg]) = value; - } else { - state->A[reg-8] = (int32_t)value; - } - state->ea_addr += 2; - cycles += 4; - } else { - state->DA[reg] = READU32(state, state->ea_addr); - state->ea_addr += 4; - cycles += 8; - } - } - } - if (EA_MODE(opcode) == EA_POSTINCREMENT) { - state->A[EA_REG(opcode)] = state->ea_addr; - } - - return 8 + cycles; -} - -/*************************************************************************/ - -/** - * opmisc: $4xxx-group misc. instructions (format 0100 1110 01xx xxxx). - */ -static int opmisc(Q68State *state, uint32_t opcode) -{ - const unsigned int index = (opcode>>3 & 7); - return (*opcode_4E4x_table[index])(state, opcode); -} - -/*-----------------------------------------------------------------------*/ - -/** - * opTRAP: TRAP #n instruction (format 0100 1110 0100 nnnn). - */ -static int opTRAP(Q68State *state, uint32_t opcode) -{ - state->exception = EX_TRAP + (opcode & 0x000F); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opLINK: LINK instruction (format 0100 1110 0101 0rrr). - */ -static int opLINK(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG0; - int16_t disp = IFETCH(state); -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->A[7]; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_WRITE; - return 0; - } -#endif - PUSH32(state, state->A[reg0]); - state->A[reg0] = state->A[7]; - state->A[7] += disp; - return 16; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opUNLK: UNLK instruction (format 0100 1110 0101 1rrr). - */ -static int opUNLK(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG0; - /* FIXME: What happens if A7 is used as the register? I.e. does the - * postincrement happen before or after the value is written to - * the destination register? The Motorola docs could be read - * both ways, so going by the literal operation sequence here. */ - state->A[7] = state->A[reg0]; -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->A[7]; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_READ; - return 0; - } -#endif - state->A[reg0] = READU32(state, state->A[7]); - state->A[7] += 4; - return 12; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opMUSP: MOVE An,USP and MOVE USP,An instructions (format - * 0100 1110 0110 xrrr). - */ -static int opMUSP(Q68State *state, uint32_t opcode) -{ - if (!(state->SR & SR_S)) { - state->exception = EX_PRIVILEGE_VIOLATION; - return 0; - } - - INSN_GET_REG0; - if (opcode & 0x0008) { - state->USP = state->A[reg0]; - } else { - state->A[reg0] = state->USP; - } - return 4; -} - -/*-----------------------------------------------------------------------*/ - -/** - * op4E7x: Instructions with opcodes $4E70-$4E77 that don't fit anywhere - * else. - */ -static int op4E7x(Q68State *state, uint32_t opcode) -{ - switch (opcode & 7) { - case 0: // $4E70 RESET - if (!(state->SR & SR_S)) { - state->exception = EX_PRIVILEGE_VIOLATION; - return 0; - } - return 132; - case 1: // $4E71 NOP - return 4; - case 2: // $4E72 STOP - if (!(state->SR & SR_S)) { - state->exception = EX_PRIVILEGE_VIOLATION; - return 0; - } - state->halted = 1; - set_SR(state, IFETCH(state)); - return 4; - case 3: { // $4E73 RTE - if (!(state->SR & SR_S)) { - state->exception = EX_PRIVILEGE_VIOLATION; - return 0; - } -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->A[7]; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_READ; - return 0; - } -#endif - uint16_t new_SR = POP16(state); - state->PC = POP32(state); - set_SR(state, new_SR); - return 20; - } - case 5: // $4E75 RTS -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->A[7]; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_READ; - return 0; - } -#endif - state->PC = POP32(state); - return 16; - case 6: // $4E76 TRAPV - if (state->SR & SR_V) { - state->exception = EX_TRAPV; - return 0; - } - return 4; - case 7: { // $4E77 RTR -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->A[7]; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_READ; - return 0; - } -#endif - state->SR &= 0xFF00; - state->SR |= POP16(state) & 0x00FF; - state->PC = POP32(state); - return 20; - } - default: // $4E74 RTD is 68010 only - return op_ill(state, opcode); - } -} - -/*************************************************************************/ - -/** - * opjump: JSR and JMP instructions (format 0100 1110 1xxx xxxx). - */ -static int opjump(Q68State *state, uint32_t opcode) -{ - int is_jsr = ~opcode & 0x0040; - - /* JMP is essentially identical to LEA PC, and has the same - * constraints. JSR is equivalent to MOVE.L PC,-(A7) followed by a - * JMP to the address. Both use a separate timing table, however. */ - - int cycles; - switch (EA_MODE(opcode)) { - case EA_INDIRECT: - cycles = 8; - break; - case EA_DISPLACEMENT: - cycles = 10; - break; - case EA_INDEX: - cycles = 14; - break; - case EA_MISC: - switch (EA_REG(opcode)) { - case EA_MISC_ABSOLUTE_W: - cycles = 10; - break; - case EA_MISC_ABSOLUTE_L: - cycles = 12; - break; - case EA_MISC_PCREL: - cycles = 10; - break; - case EA_MISC_PCREL_INDEX: - cycles = 14; - break; - default: - return op_ill(state, opcode); - } - break; - default: - return op_ill(state, opcode); - } - - ea_resolve(state, opcode, SIZE_W, ACCESS_READ); // cannot fail - if (is_jsr) { -#ifndef Q68_DISABLE_ADDRESS_ERROR - if (state->A[7] & 1) { - state->exception = EX_ADDRESS_ERROR; - state->fault_addr = state->A[7]; - state->fault_status = FAULT_STATUS_IN_DATA - | FAULT_STATUS_RW_WRITE; - return 0; - } -#endif - cycles += 8; - PUSH32(state, state->PC); - } - state->PC = state->ea_addr; - return cycles; -} - -/*************************************************************************/ -/******************* Other miscellaneous instructions ********************/ -/*************************************************************************/ - -/** - * opMOVP: MOVEP instruction (0000 rrr1 xx00 1rrr). - */ -static int opMOVP(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_REG0; - int to_memory = opcode & 0x0080; - int is_long = opcode & 0x0040; - int16_t disp = IFETCH(state); - uint32_t addr = state->A[reg0] + disp; - - if (to_memory) { - uint32_t data = state->D[reg]; - if (is_long) { - WRITE8(state, addr+0, data>>24); - WRITE8(state, addr+2, data>>16); - WRITE8(state, addr+4, data>> 8); - WRITE8(state, addr+6, data>> 0); - } else { - WRITE8(state, addr+0, data>> 8); - WRITE8(state, addr+2, data>> 0); - } - } else { - uint32_t data; - if (is_long) { - data = READU8(state, addr+0) << 24; - data |= READU8(state, addr+2) << 16; - data |= READU8(state, addr+4) << 8; - data |= READU8(state, addr+6) << 0; - } else { - data = READU8(state, addr+0) << 8; - data |= READU8(state, addr+2) << 0; - } - state->D[reg] = data; - } - - return is_long ? 24 : 16; -} - -/*************************************************************************/ - -/** - * opADSX: ADDX/SUBX instructions (1x01 rrr1 ss00 xrrr). - */ -static int opADSX(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_SIZE; - INSN_GET_REG0; - const int is_add = opcode & 0x4000; - const int is_memory = opcode & 0x0008; - const int bytes = SIZE_TO_BYTES(size); - const int shift = bytes*8 - 1; - const uint32_t valuemask = ~(~1 << shift); - - const uint16_t src_ea = - (is_memory ? EA_PREDECREMENT : EA_DATA_REG) << 3 | reg0; - const uint16_t dest_ea = - (is_memory ? EA_PREDECREMENT : EA_DATA_REG) << 3 | reg; - int dummy; - uint32_t src = ea_get(state, src_ea, size, 0, &dummy); - uint32_t dest = ea_get(state, dest_ea, size, 1, &dummy); - - uint32_t result; - int X = (state->SR >> SR_X_SHIFT) & 1; - state->SR &= ~(SR_X | SR_N | SR_V | SR_C); // Z is never set, only cleared - if (is_add) { - result = (dest + src + X) & valuemask; - if (((src ^ result) & (dest ^ result)) >> shift) { - state->SR |= SR_V; - } - if ((int)((src >> shift) + (dest >> shift) - (result >> shift)) > 0) { - state->SR |= SR_X | SR_C; - } - } else { - result = (dest - src - X) & valuemask; - if (((src ^ dest) & (result ^ dest)) >> shift) { - state->SR |= SR_V; - } - if ((int)((src >> shift) - (dest >> shift) + (result >> shift)) > 0) { - state->SR |= SR_X | SR_C; - } - } - if (result >> shift) { - state->SR |= SR_N; - } - if (result != 0) { - state->SR &= ~SR_Z; - } - - ea_set(state, dest_ea, size, result); - return (is_memory ? (size==SIZE_L ? 30 : 18) : (size==SIZE_L ? 8 : 4)); -} - -/*-----------------------------------------------------------------------*/ - -/** - * op_BCD: ABCD/SBCD instructions (1x00 rrr1 0000 xrrr). - */ -static int op_BCD(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_REG0; - const int is_add = opcode & 0x4000; - const int is_memory = opcode & 0x0008; - - const uint16_t src_ea = - (is_memory ? EA_PREDECREMENT : EA_DATA_REG) << 3 | reg0; - const uint16_t dest_ea = - (is_memory ? EA_PREDECREMENT : EA_DATA_REG) << 3 | reg; - int dummy; - uint8_t src = ea_get(state, src_ea, SIZE_B, 0, &dummy); - uint8_t dest = ea_get(state, dest_ea, SIZE_B, 1, &dummy); - - int result; - int X = (state->SR >> SR_X_SHIFT) & 1; - state->SR &= ~(SR_X | SR_C); // Z is never set, only cleared - if (is_add) { - result = (dest & 0x0F) + (src & 0x0F) + X; - if (result >= 10) { - /* This seems to be correct w.r.t. a real 68000 and invalid data - * (e.g. 0x0F + 0x0F): it only checks for a carry of 1 */ - result += 6; - } - result += (dest & 0xF0) + (src & 0xF0); - if (result >= 10<<4) { - result -= 10<<4; - state->SR |= SR_X | SR_C; - } - } else { - /* Slightly convoluted to match what a real 68000 does */ - int res_low = (dest & 0x0F) - (src & 0x0F) - X; - int borrow = 0; - if (res_low < 0) { - res_low += 10; - borrow = 1<<4; - } - int res_high = (dest & 0xF0) - (src & 0xF0) - borrow; - if (res_high < 0) { - res_high += 10<<4; - state->SR |= SR_X | SR_C; - } - result = res_high + res_low; - if (result < 0) { - state->SR |= SR_X | SR_C; - } - } - result &= 0xFF; - if (result != 0) { - state->SR &= ~SR_Z; - } - - ea_set(state, dest_ea, SIZE_B, result); - return is_memory ? 18 : 6; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opCMPM: CMPM instructions (1011 rrr1 ss00 1rrr). - */ -static int opCMPM(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_SIZE; - INSN_GET_REG0; - const int bytes = SIZE_TO_BYTES(size); - const int shift = bytes*8 - 1; - const uint32_t valuemask = ~(~1 << shift); - - const uint16_t src_ea = EA_POSTINCREMENT<<3 | reg0; - const uint16_t dest_ea = EA_POSTINCREMENT<<3 | reg; - int dummy; - uint32_t src = ea_get(state, src_ea, size, 0, &dummy); - uint32_t dest = ea_get(state, dest_ea, size, 0, &dummy); - - uint32_t result = (dest - src) & valuemask; - INSN_CLEAR_XCC(); - INSN_SETNZ_SHIFT(result); - if (((src ^ dest) & (result ^ dest)) >> shift) { - state->SR |= SR_V; - } - if ((int)((src >> shift) - (dest >> shift) + (result >> shift)) > 0) { - state->SR |= SR_C; - } - - return size==SIZE_L ? 20 : 12; -} - -/*************************************************************************/ - -/** - * op_EXG: EXG instruction (1100 rrr1 xx00 1rrr). - */ -static int op_EXG(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_REG0; - const int mode = opcode & 0xF8; - - if (mode == 0x40) { - const uint32_t tmp = state->D[reg]; - state->D[reg] = state->D[reg0]; - state->D[reg0] = tmp; - } else if (mode == 0x48) { - const uint32_t tmp = state->A[reg]; - state->A[reg] = state->A[reg0]; - state->A[reg0] = tmp; - } else if (mode == 0x88) { - const uint32_t tmp = state->D[reg]; - state->D[reg] = state->A[reg0]; - state->A[reg0] = tmp; - } else { - return op_ill(state, opcode); - } - return 6; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68-disasm.c b/yabause/src/q68/q68-disasm.c deleted file mode 100644 index 9aab2ffcf4..0000000000 --- a/yabause/src/q68/q68-disasm.c +++ /dev/null @@ -1,836 +0,0 @@ -/* src/q68/q68-disasm.c: MC68000 disassembly routines - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include - -#include "q68.h" -#include "q68-const.h" -#include "q68-internal.h" - -/*************************************************************************/ -/********************** 68k instruction disassembly **********************/ -/*************************************************************************/ - -/* Disassembly table. The first entry matching a given instruction is used. */ - -static const struct { - uint16_t mask, test; // Entry matches when (opcode & mask) == test - const char *format; // Instruction format -} instructions[] = { - - /* ALU immediate */ - - {0xFFFF, 0x003C, "ORI.B #,CCR"}, - {0xFFC0, 0x0000, "ORI.B #,"}, - {0xFFFF, 0x007C, "ORI.W #,SR"}, - {0xFFC0, 0x0040, "ORI.W #,"}, - {0xFFC0, 0x0080, "ORI.L #,"}, - {0xFFFF, 0x023C, "ANDI.B #,CCR"}, - {0xFFC0, 0x0200, "ANDI.B #,"}, - {0xFFFF, 0x027C, "ANDI.W #,SR"}, - {0xFFC0, 0x0240, "ANDI.W #,"}, - {0xFFC0, 0x0280, "ANDI.L #,"}, - {0xFFC0, 0x0400, "SUBI.B #,"}, - {0xFFC0, 0x0440, "SUBI.W #,"}, - {0xFFC0, 0x0480, "SUBI.L #,"}, - {0xFFC0, 0x0600, "ADDI.B #,"}, - {0xFFC0, 0x0640, "ADDI.W #,"}, - {0xFFC0, 0x0680, "ADDI.L #,"}, - {0xFFFF, 0x0A3C, "EORI.B #,CCR"}, - {0xFFC0, 0x0A00, "EORI.B #,"}, - {0xFFFF, 0x0A7C, "EORI.W #,SR"}, - {0xFFC0, 0x0A40, "EORI.W #,"}, - {0xFFC0, 0x0A80, "EORI.L #,"}, - {0xFFC0, 0x0C00, "CMPI.B #,"}, - {0xFFC0, 0x0C40, "CMPI.W #,"}, - {0xFFC0, 0x0C80, "CMPI.L #,"}, - - /* Bit twiddling and MOVEP */ - - {0xF1F8, 0x0108, "MOVEP.W (A),D"}, - {0xF1F8, 0x0148, "MOVEP.L (A),D"}, - {0xF1F8, 0x0188, "MOVEP.W D,(A)"}, - {0xF1F8, 0x01C8, "MOVEP.L D,(A)"}, - {0xFFC0, 0x0800, "BTST #,"}, - {0xFFC0, 0x0840, "BCHG #,"}, - {0xFFC0, 0x0880, "BCLR #,"}, - {0xFFC0, 0x08C0, "BSET #,"}, - {0xF1C0, 0x0100, "BTST D,"}, - {0xF1C0, 0x0140, "BCHG D,"}, - {0xF1C0, 0x0180, "BCLR D,"}, - {0xF1C0, 0x01C0, "BSET D,"}, - - /* MOVE */ - - {0xF1C0, 0x1040, "MOVEA.B ,A"}, - {0xF000, 0x1000, "MOVE.B ,"}, - {0xF1C0, 0x2040, "MOVEA.L ,A"}, - {0xF000, 0x2000, "MOVE.L ,"}, - {0xF1C0, 0x3040, "MOVEA.W ,A"}, - {0xF000, 0x3000, "MOVE.W ,"}, - - /* Miscellaneous */ - - {0xFFC0, 0x4000, "NEGX.B "}, - {0xFFC0, 0x4040, "NEGX.W "}, - {0xFFC0, 0x4080, "NEGX.L "}, - {0xFFC0, 0x40C0, "MOVE.W SR,"}, - - {0xFFC0, 0x4200, "CLR.B "}, - {0xFFC0, 0x4240, "CLR.W "}, - {0xFFC0, 0x4280, "CLR.L "}, - {0xFFC0, 0x42C0, "???"}, - - {0xFFC0, 0x4400, "NEG.B "}, - {0xFFC0, 0x4440, "NEG.W "}, - {0xFFC0, 0x4480, "NEG.L "}, - {0xFFC0, 0x44C0, "MOVE.W CCR,"}, - - {0xFFC0, 0x4600, "NOT.B "}, - {0xFFC0, 0x4640, "NOT.W "}, - {0xFFC0, 0x4680, "NOT.L "}, - {0xFFC0, 0x46C0, "MOVE.W ,SR"}, - - {0xFFF8, 0x4808, "???"}, - {0xFFC0, 0x4800, "NBCD.B "}, - {0xFFF8, 0x4840, "SWAP.W D"}, - {0xFFF8, 0x4848, "???"}, - {0xFFC0, 0x4840, "PEA.L "}, - {0xFFF8, 0x4880, "EXT.W D"}, - {0xFFF8, 0x48A0, "MOVEM.W ,-(A)"}, - {0xFFC0, 0x4880, "MOVEM.W ,"}, - {0xFFF8, 0x48C0, "EXT.L D"}, - {0xFFF8, 0x48E0, "MOVEM.L ,-(A)"}, - {0xFFC0, 0x48C0, "MOVEM.L ,"}, - - {0xFFC0, 0x4A00, "TST.B "}, - {0xFFC0, 0x4A40, "TST.W "}, - {0xFFC0, 0x4A80, "TST.L "}, - {0xFFFF, 0x4AFC, "ILLEGAL"}, - {0xFFC0, 0x4AC0, "TAS "}, - - {0xFFC0, 0x4C80, "MOVEM.W ,"}, - {0xFFC0, 0x4CC0, "MOVEM.L ,"}, - - {0xFFF0, 0x4E40, "TRAP #"}, - {0xFFF8, 0x4E50, "LINK #,A"}, - {0xFFF8, 0x4E58, "UNLK A"}, - {0xFFF8, 0x4E60, "MOVE USP,A"}, - {0xFFF8, 0x4E68, "MOVE A,USP"}, - {0xFFFF, 0x4E70, "RESET"}, - {0xFFFF, 0x4E71, "NOP"}, - {0xFFFF, 0x4E72, "STOP"}, - {0xFFFF, 0x4E73, "RTE"}, - {0xFFFF, 0x4E75, "RTS"}, - {0xFFFF, 0x4E76, "TRAPV"}, - {0xFFFF, 0x4E77, "RTR"}, - {0xFFC0, 0x4E80, "JSR "}, - {0xFFC0, 0x4EC0, "JMP "}, - - {0xF1C0, 0x4180, "CHK.W D,"}, - {0xF1C0, 0x41C0, "LEA.L ,A"}, - - /* ADDQ/SUBQ/Scc/DBcc */ - - {0xF1C0, 0x5000, "ADDQ.B #,"}, - {0xF1C0, 0x5040, "ADDQ.W #,"}, - {0xF1C0, 0x5080, "ADDQ.L #,"}, - {0xF1C0, 0x5100, "SUBQ.B #,"}, - {0xF1C0, 0x5140, "SUBQ.W #,"}, - {0xF1C0, 0x5180, "SUBQ.L #,"}, - {0xFFF8, 0x50C8, "DBT D,"}, - {0xFFC0, 0x50C0, "ST.B "}, - {0xFFF8, 0x51C8, "DBRA D,"}, - {0xFFC0, 0x51C0, "SF.B "}, - {0xFFF8, 0x52C8, "DBHI D,"}, - {0xFFC0, 0x52C0, "SHI.B "}, - {0xFFF8, 0x53C8, "DBLS D,"}, - {0xFFC0, 0x53C0, "SLS.B "}, - {0xFFF8, 0x54C8, "DBCC D,"}, - {0xFFC0, 0x54C0, "SCC.B "}, - {0xFFF8, 0x55C8, "DBCS D,"}, - {0xFFC0, 0x55C0, "SCS.B "}, - {0xFFF8, 0x56C8, "DBNE D,"}, - {0xFFC0, 0x56C0, "SNE.B "}, - {0xFFF8, 0x57C8, "DBEQ D,"}, - {0xFFC0, 0x57C0, "SEQ.B "}, - {0xFFF8, 0x58C8, "DBVC D,"}, - {0xFFC0, 0x58C0, "SVC.B "}, - {0xFFF8, 0x59C8, "DBVS D,"}, - {0xFFC0, 0x59C0, "SVS.B "}, - {0xFFF8, 0x5AC8, "DBPL D,"}, - {0xFFC0, 0x5AC0, "SPL.B "}, - {0xFFF8, 0x5BC8, "DBMI D,"}, - {0xFFC0, 0x5BC0, "SMI.B "}, - {0xFFF8, 0x5CC8, "DBLT D,"}, - {0xFFC0, 0x5CC0, "SLT.B "}, - {0xFFF8, 0x5DC8, "DBGE D,"}, - {0xFFC0, 0x5DC0, "SGE.B "}, - {0xFFF8, 0x5EC8, "DBLE D,"}, - {0xFFC0, 0x5EC0, "SLE.B "}, - {0xFFF8, 0x5FC8, "DBGT D,"}, - {0xFFC0, 0x5FC0, "SGT.B "}, - - /* BRA/BSR/Bcc */ - - {0xFFFF, 0x6000, "BRA.W "}, - {0xFF00, 0x6000, "BRA.S "}, - {0xFFFF, 0x6100, "BSR.W "}, - {0xFF00, 0x6100, "BSR.S "}, - {0xFFFF, 0x6200, "BHI.W "}, - {0xFF00, 0x6200, "BHI.S "}, - {0xFFFF, 0x6300, "BLS.W "}, - {0xFF00, 0x6300, "BLS.S "}, - {0xFFFF, 0x6400, "BCC.W "}, - {0xFF00, 0x6400, "BCC.S "}, - {0xFFFF, 0x6500, "BCS.W "}, - {0xFF00, 0x6500, "BCS.S "}, - {0xFFFF, 0x6600, "BNE.W "}, - {0xFF00, 0x6600, "BNE.S "}, - {0xFFFF, 0x6700, "BEQ.W "}, - {0xFF00, 0x6700, "BEQ.S "}, - {0xFFFF, 0x6800, "BVC.W "}, - {0xFF00, 0x6800, "BVC.S "}, - {0xFFFF, 0x6900, "BVS.W "}, - {0xFF00, 0x6900, "BVS.S "}, - {0xFFFF, 0x6A00, "BPL.W "}, - {0xFF00, 0x6A00, "BPL.S "}, - {0xFFFF, 0x6B00, "BMI.W "}, - {0xFF00, 0x6B00, "BMI.S "}, - {0xFFFF, 0x6C00, "BLT.W "}, - {0xFF00, 0x6C00, "BLT.S "}, - {0xFFFF, 0x6D00, "BGE.W "}, - {0xFF00, 0x6D00, "BGE.S "}, - {0xFFFF, 0x6E00, "BLE.W "}, - {0xFF00, 0x6E00, "BLE.S "}, - {0xFFFF, 0x6F00, "BGT.W "}, - {0xFF00, 0x6F00, "BGT.S "}, - - /* MOVEQ */ - - {0xF100, 0x7000, "MOVEQ #,D"}, - - /* ALU non-immediate,ABCD/SBCD etc. */ - - {0xF1F8, 0x8100, "SBCD.B D,D"}, - {0xF1F8, 0x8108, "SBCD.B -(A),-(A)"}, - {0xF1F0, 0x8140, "???"}, - {0xF1F0, 0x8180, "???"}, - {0xF1C0, 0x8000, "OR.B ,D"}, - {0xF1C0, 0x8040, "OR.W ,D"}, - {0xF1C0, 0x8080, "OR.L ,D"}, - {0xF1C0, 0x80C0, "DIVU ,D"}, - {0xF1C0, 0x8100, "OR.B D,"}, - {0xF1C0, 0x8140, "OR.W D,"}, - {0xF1C0, 0x8180, "OR.L D,"}, - {0xF1C0, 0x81C0, "DIVS ,D"}, - - {0xF1F8, 0x9100, "SUBX.B D,D"}, - {0xF1F8, 0x9108, "SUBX.B -(A),-(A)"}, - {0xF1F8, 0x9140, "SUBX.W D,D"}, - {0xF1F8, 0x9148, "SUBX.W -(A),-(A)"}, - {0xF1F8, 0x9180, "SUBX.L D,D"}, - {0xF1F8, 0x9188, "SUBX.L -(A),-(A)"}, - {0xF1C0, 0x9000, "SUB.B ,D"}, - {0xF1C0, 0x9040, "SUB.W ,D"}, - {0xF1C0, 0x9080, "SUB.L ,D"}, - {0xF1C0, 0x90C0, "SUBA.W ,A"}, - {0xF1C0, 0x9100, "SUB.B D,"}, - {0xF1C0, 0x9140, "SUB.W D,"}, - {0xF1C0, 0x9180, "SUB.L D,"}, - {0xF1C0, 0x91C0, "SUBA.L ,A"}, - - {0xF1F8, 0xB108, "CMPM.B -(A),-(A)"}, - {0xF1F8, 0xB148, "CMPM.W -(A),-(A)"}, - {0xF1F8, 0xB188, "CMPM.L -(A),-(A)"}, - {0xF1C0, 0xB000, "CMP.B ,D"}, - {0xF1C0, 0xB040, "CMP.W ,D"}, - {0xF1C0, 0xB080, "CMP.L ,D"}, - {0xF1C0, 0xB0C0, "CMPA.W ,A"}, - {0xF1C0, 0xB100, "CMP.B D,"}, - {0xF1C0, 0xB140, "CMP.W D,"}, - {0xF1C0, 0xB180, "CMP.L D,"}, - {0xF1C0, 0xB1C0, "CMPA.L ,A"}, - - {0xF1F8, 0xC100, "ABCD.B D,D"}, - {0xF1F8, 0xC108, "ABCD.B -(A),-(A)"}, - {0xF1F8, 0xC140, "EXG.L D,D"}, - {0xF1F8, 0xC148, "EXG.L A,A"}, - {0xF1F8, 0xC180, "???"}, - {0xF1F8, 0xC188, "EXG.L A,D"}, - {0xF1C0, 0xC000, "AND.B ,D"}, - {0xF1C0, 0xC040, "AND.W ,D"}, - {0xF1C0, 0xC080, "AND.L ,D"}, - {0xF1C0, 0xC0C0, "MULU ,D"}, - {0xF1C0, 0xC100, "AND.B D,"}, - {0xF1C0, 0xC140, "AND.W D,"}, - {0xF1C0, 0xC180, "AND.L D,"}, - {0xF1C0, 0xC1C0, "MULS ,D"}, - - {0xF1F8, 0xD100, "ADDX.B D,D"}, - {0xF1F8, 0xD108, "ADDX.B -(A),-(A)"}, - {0xF1F8, 0xD140, "ADDX.W D,D"}, - {0xF1F8, 0xD148, "ADDX.W -(A),-(A)"}, - {0xF1F8, 0xD180, "ADDX.L D,D"}, - {0xF1F8, 0xD188, "ADDX.L -(A),-(A)"}, - {0xF1C0, 0xD000, "ADD.B ,D"}, - {0xF1C0, 0xD040, "ADD.W ,D"}, - {0xF1C0, 0xD080, "ADD.L ,D"}, - {0xF1C0, 0xD0C0, "ADDA.W ,A"}, - {0xF1C0, 0xD100, "ADD.B D,"}, - {0xF1C0, 0xD140, "ADD.W D,"}, - {0xF1C0, 0xD180, "ADD.L D,"}, - {0xF1C0, 0xD1C0, "ADDA.L ,A"}, - - /* Shift/rotate instructions */ - - {0xF1F8, 0xE000, "ASR.B #,D"}, - {0xF1F8, 0xE008, "LSR.B #,D"}, - {0xF1F8, 0xE010, "ROXR.B #,D"}, - {0xF1F8, 0xE018, "ROR.B #,D"}, - {0xF1F8, 0xE020, "ASR.B D,D"}, - {0xF1F8, 0xE028, "LSR.B D,D"}, - {0xF1F8, 0xE030, "ROXR.B D,D"}, - {0xF1F8, 0xE038, "ROR.B D,D"}, - - {0xF1F8, 0xE040, "ASR.W #,D"}, - {0xF1F8, 0xE048, "LSR.W #,D"}, - {0xF1F8, 0xE050, "ROXR.W #,D"}, - {0xF1F8, 0xE058, "ROR.W #,D"}, - {0xF1F8, 0xE060, "ASR.W D,D"}, - {0xF1F8, 0xE068, "LSR.W D,D"}, - {0xF1F8, 0xE070, "ROXR.W D,D"}, - {0xF1F8, 0xE078, "ROR.W D,D"}, - - {0xF1F8, 0xE080, "ASR.L #,D"}, - {0xF1F8, 0xE088, "LSR.L #,D"}, - {0xF1F8, 0xE090, "ROXR.L #,D"}, - {0xF1F8, 0xE098, "ROR.L #,D"}, - {0xF1F8, 0xE0A0, "ASR.L D,D"}, - {0xF1F8, 0xE0A8, "LSR.L D,D"}, - {0xF1F8, 0xE0B0, "ROXR.L D,D"}, - {0xF1F8, 0xE0B8, "ROR.L D,D"}, - - {0xF1F8, 0xE100, "ASL.B #,D"}, - {0xF1F8, 0xE108, "LSL.B #,D"}, - {0xF1F8, 0xE110, "ROXL.B #,D"}, - {0xF1F8, 0xE118, "ROL.B #,D"}, - {0xF1F8, 0xE120, "ASL.B D,D"}, - {0xF1F8, 0xE128, "LSL.B D,D"}, - {0xF1F8, 0xE130, "ROXL.B D,D"}, - {0xF1F8, 0xE138, "ROL.B D,D"}, - - {0xF1F8, 0xE140, "ASL.W #,D"}, - {0xF1F8, 0xE148, "LSL.W #,D"}, - {0xF1F8, 0xE150, "ROXL.W #,D"}, - {0xF1F8, 0xE158, "ROL.W #,D"}, - {0xF1F8, 0xE160, "ASL.W D,D"}, - {0xF1F8, 0xE168, "LSL.W D,D"}, - {0xF1F8, 0xE170, "ROXL.W D,D"}, - {0xF1F8, 0xE178, "ROL.W D,D"}, - - {0xF1F8, 0xE180, "ASL.L #,D"}, - {0xF1F8, 0xE188, "LSL.L #,D"}, - {0xF1F8, 0xE190, "ROXL.L #,D"}, - {0xF1F8, 0xE198, "ROL.L #,D"}, - {0xF1F8, 0xE1A0, "ASL.L D,D"}, - {0xF1F8, 0xE1A8, "LSL.L D,D"}, - {0xF1F8, 0xE1B0, "ROXL.L D,D"}, - {0xF1F8, 0xE1B8, "ROL.L D,D"}, - - {0xFFC0, 0xE0C0, "ASR.W "}, - {0xFFC0, 0xE1C0, "ASL.W "}, - {0xFFC0, 0xE2C0, "LSR.W "}, - {0xFFC0, 0xE3C0, "LSL.W "}, - {0xFFC0, 0xE4C0, "ROXR.W "}, - {0xFFC0, 0xE5C0, "ROXL.W "}, - {0xFFC0, 0xE6C0, "ROR.W "}, - {0xFFC0, 0xE7C0, "ROL.W "}, -}; - -/*************************************************************************/ - -/** - * q68_disassemble: Disassembles the instruction at the given address. - * Returns "???" if the address or opcode is invalid. - * - * [Parameters] - * state: Processor state block - * address: Address of instruction to disassemble - * nwords_ret: Pointer to variable to receive length in words of the - * instruction (NULL permitted) - * [Return value] - * String containined disassembled instruction - * [Notes] - * The returned string is only valid until the next call to this function. - */ -const char *q68_disassemble(Q68State *state, uint32_t address, - int *nwords_ret) -{ - const uint32_t base_address = address; - static char outbuf[1000]; - - if (address % 2 != 0) { // Odd addresses are invalid - if (nwords_ret) { - *nwords_ret = 1; - } - return "???"; - } - - uint16_t opcode = READU16(state, address); - address += 2; - const char *format = NULL; - int i; - for (i = 0; i < lenof(instructions); i++) { - if ((opcode & instructions[i].mask) == instructions[i].test) { - format = instructions[i].format; - break; - } - } - if (!format) { - if (nwords_ret) { - *nwords_ret = 1; - } - return "???"; - } - - int outlen = 0; -#define APPEND_CHAR(ch) do { \ - if (outlen < sizeof(outbuf)-1) { \ - outbuf[outlen++] = (ch); \ - outbuf[outlen] = 0; \ - } \ -} while (0) -#define APPEND(fmt,...) do { \ - outlen += snprintf(&outbuf[outlen], sizeof(outbuf)-outlen, \ - fmt , ## __VA_ARGS__); \ - if (outlen > sizeof(outbuf)-1) { \ - outlen = sizeof(outbuf)-1; \ - } \ -} while (0) - - int inpos = 0; - while (format[inpos] != 0) { - if (format[inpos] == '<') { - char tagbuf[100]; - int end = inpos+1; - for (; format[end] != 0 && format[end] != '>'; end++) { - if (end - (inpos+1) >= sizeof(tagbuf)) { - break; - } - } - memcpy(tagbuf, &format[inpos+1], end - (inpos+1)); - tagbuf[end - (inpos+1)] = 0; - if (format[end] != 0) { - end++; - } - inpos = end; - if (strncmp(tagbuf,"ea",2) == 0) { - int mode, reg; - char size; // 'b', 'w', or 'l' - if (strncmp(tagbuf,"ea2",3) == 0) { // 2nd EA of MOVE insns - mode = opcode>>6 & 7; - reg = opcode>>9 & 7; - size = tagbuf[4]; - } else { - mode = opcode>>3 & 7; - reg = opcode>>0 & 7; - size = tagbuf[3]; - } - switch (mode) { - case 0: - APPEND("D%d", reg); - break; - case 1: - APPEND("A%d", reg); - break; - case 2: - APPEND("(A%d)", reg); - break; - case 3: - APPEND("(A%d)+", reg); - break; - case 4: - APPEND("-(A%d)", reg); - break; - case 5: { - int16_t disp = READS16(state, address); - address += 2; - APPEND("%d(A%d)", disp, reg); - break; - } - case 6: { - uint16_t ext = READU16(state, address); - address += 2; - const int iregtype = ext>>15; - const int ireg = ext>>12 & 7; - const int iregsize = ext>>11; - const int8_t disp = ext & 0xFF; - APPEND("%d(A%d,%c%d.%c)", disp, reg, - iregtype ? 'A' : 'D', ireg, iregsize ? 'l' : 'w'); - break; - } - case 7: - switch (reg) { - case 0: { - const uint16_t abs = READU16(state, address); - address += 2; - APPEND("($%X).w", abs); - break; - } - case 1: { - const uint32_t abs = READU32(state, address); - address += 4; - APPEND("($%X).l", abs); - break; - } - case 2: { - int16_t disp = READS16(state, address); - address += 2; - APPEND("$%X(PC)", (base_address+2) + disp); - break; - } - case 3: { - uint16_t ext = READU16(state, address); - address += 2; - const int iregtype = ext>>15; - const int ireg = ext>>12 & 7; - const int iregsize = ext>>11; - const int8_t disp = ext & 0xFF; - APPEND("$%X(PC,%c%d.%c)", (base_address+2) + disp, - iregtype ? 'A' : 'D', ireg, iregsize ? 'l' : 'w'); - break; - } - case 4: { - uint32_t imm; - if (size == 'l') { - imm = READU32(state, address); - address += 4; - } else { - imm = READU16(state, address); - address += 2; - } - APPEND("#%s%X", imm<10 ? "" : "$", imm); - break; - } - default: - APPEND("???"); - break; - } - } - } else if (strcmp(tagbuf,"reg") == 0) { - APPEND("%d", opcode>>9 & 7); - } else if (strcmp(tagbuf,"reg0") == 0) { - APPEND("%d", opcode>>0 & 7); - } else if (strcmp(tagbuf,"count") == 0) { - APPEND("%d", opcode>>9 & 7 ?: 8); - } else if (strcmp(tagbuf,"trap") == 0) { - APPEND("%d", opcode>>0 & 15); - } else if (strcmp(tagbuf,"quick8") == 0) { - APPEND("%d", (int8_t)(opcode & 0xFF)); - } else if (strncmp(tagbuf,"imm8",4) == 0) { - uint8_t imm8 = READU16(state, address); // Upper 8 bits ignored - imm8 &= 0xFF; - address += 2; - if (tagbuf[4] == 'd') { - APPEND("%d", imm8); - } else if (tagbuf[4] == 'x') { - APPEND("$%02X", imm8); - } else { - APPEND("%s%X", imm8<10 ? "" : "$", imm8); - } - } else if (strncmp(tagbuf,"imm16",5) == 0) { - uint16_t imm16 = READU16(state, address); - address += 2; - if (tagbuf[5] == 'd') { - APPEND("%d", imm16); - } else if (tagbuf[5] == 'x') { - APPEND("$%04X", imm16); - } else { - APPEND("%s%X", imm16<10 ? "" : "$", imm16); - } - } else if (strcmp(tagbuf,"pcrel8") == 0) { - int8_t disp8 = opcode & 0xFF; - APPEND("$%X", (base_address+2) + disp8); - } else if (strcmp(tagbuf,"pcrel16") == 0) { - int16_t disp16 = READS16(state, address); - address += 2; - APPEND("$%X", (base_address+2) + disp16); - } else if (strcmp(tagbuf,"reglist") == 0 - || strcmp(tagbuf,"tsilger") == 0) { - uint16_t reglist = READU16(state, address); - address += 2; - if (strcmp(tagbuf,"tsilger") == 0) { // "reglist" backwards - /* Predecrement-mode register list, so flip it around */ - uint16_t temp = reglist; - reglist = 0; - while (temp) { - reglist <<= 1; - if (temp & 1) { - reglist |= 1; - } - temp >>= 1; - } - } - char listbuf[3*16]; // Buffer for generating register list - unsigned int listlen = 0; // strlen(listbuf) - unsigned int last = 0; // State of the previous bit - unsigned int regnum = 0; // Current register number (0-15) - while (reglist) { - if (reglist & 1) { - if (last) { - if (listlen >= 3 && listbuf[listlen-3] == '-') { - listlen -= 2; - } else { - listbuf[listlen++] = '-'; - } - } else { - if (listlen > 0) { - listbuf[listlen++] = '/'; - } - } - listbuf[listlen++] = regnum<8 ? 'D' : 'A'; - listbuf[listlen++] = '0' + (regnum % 8); - } - last = reglist & 1; - regnum++; - reglist >>= 1; - } - listbuf[listlen] = 0; - APPEND("%s", listbuf); - } else { - APPEND("<%s>", tagbuf); - } - } else { - APPEND_CHAR(format[inpos]); - inpos++; - } - } - - if (nwords_ret) { - *nwords_ret = (address - base_address) / 2; - } - return outbuf; -} - -/*************************************************************************/ -/*********************** Execution tracing support ***********************/ -/*************************************************************************/ - -/* Processor state block to use in tracing */ -static Q68State *state; - -/* File pointer for trace output */ -static FILE *logfile; - -/* Cycle accumulator */ -static uint64_t total_cycles; - -/* Range of cycles to trace */ -static const uint64_t trace_start = 000000000ULL; // First cycle to trace -static const uint64_t trace_stop = 600000000ULL; // Last cycle to trace + 1 - -/*-----------------------------------------------------------------------*/ - -/** - * q68_trace_init: Initialize the tracing code. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -void q68_trace_init(Q68State *state_) -{ - state = state_; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_trace_add_cycles: Add the given number of cycles to the global - * accumulator. - * - * [Parameters] - * cycles: Number of cycles to add - * [Return value] - * None - */ -extern void q68_trace_add_cycles(int32_t cycles) -{ - total_cycles += cycles; -} - -/*-----------------------------------------------------------------------*/ - -#ifdef PSP -/** - * HEXIT: Helper routine for q68_trace() to print a value in hexadecimal. - * See q68_trace() for why we don't just use printf(). - */ -static inline void HEXIT(char * const ptr, uint32_t val, int ndigits) -{ - while (ndigits-- > 0) { - const int digit = val & 0xF; - val >>= 4; - ptr[ndigits] = (digit>9 ? digit+7+'0' : digit+'0'); - } -} -#endif - -/*----------------------------------*/ - -/** - * q68_trace: Output a trace for the instruction at the current PC. - * - * [Parameters] - * None - * [Return value] - * None - */ -void q68_trace(void) -{ - const uint64_t cycles = total_cycles + state->cycles; - - if (cycles < trace_start) { - - /* Before first instruction: do nothing */ - - } else if (cycles >= trace_stop) { - - /* After last instruction: close log file if it's open */ - if (logfile) { -#ifdef __linux__ - pclose(logfile); -#else - fclose(logfile); -#endif - logfile = NULL; - } - - } else { - - if (!logfile) { -#ifdef __linux__ - logfile = popen("gzip -3 >q68.log.gz", "w"); -#else - logfile = fopen("q68.log", "w"); -#endif - if (UNLIKELY(!logfile)) { - perror("Failed to open trace logfile"); - return; - } - setvbuf(logfile, NULL, _IOFBF, 65536); - } - - int nwords = 1, i; - const char *disassembled = q68_disassemble(state, state->PC, &nwords); - -#ifdef PSP // because the cleaner fprintf() version is just too slow - int dislen = strlen(disassembled); - static char buf1[] = - "......: .... .... .... .......................... SR=.... ..... [..........]\n"; - static char buf2[] = - " D: ........ ........ ........ ........ ........ ........ ........ ........\n" - " A: ........ ........ ........ ........ ........ ........ ........ ........\n"; - - if (nwords > 3) { // We can only fit 3 words on the line - nwords = 3; - } - HEXIT(&buf1[0], state->PC, 6); - for (i = 0; i < nwords; i++) { - HEXIT(&buf1[8+5*i], READU16(state, state->PC+2*i), 4); - } - if (i < 3) { - memset(&buf1[8+5*i], ' ', 4+5*(2-i)); - } - if (dislen > 26) { // Pathologically long text needs special handling - fprintf(logfile, "%.22s %-26s SR=%04X %c%c%c%c%c [%10lld]\n", - buf1, disassembled, (int)state->SR, - state->SR & SR_X ? 'X' : '.', state->SR & SR_N ? 'N' : '.', - state->SR & SR_Z ? 'Z' : '.', state->SR & SR_V ? 'V' : '.', - state->SR & SR_C ? 'C' : '.', (unsigned long long)cycles); - } else { - memcpy(&buf1[24], disassembled, dislen); - if (dislen < 26) { - memset(&buf1[24+dislen], ' ', 26-dislen); - } - HEXIT(&buf1[55], state->SR, 4); - buf1[60] = state->SR & SR_X ? 'X' : '.'; - buf1[61] = state->SR & SR_N ? 'N' : '.'; - buf1[62] = state->SR & SR_Z ? 'Z' : '.'; - buf1[63] = state->SR & SR_V ? 'V' : '.'; - buf1[64] = state->SR & SR_C ? 'C' : '.'; - snprintf(&buf1[68], sizeof(buf1)-68, "%10lld]\n", - (unsigned long long)cycles); - fwrite(buf1, 1, strlen(buf1), logfile); - } - for (i = 0; i < 8; i++) { - HEXIT(&buf2[ 7+9*i], state->D[i], 8); - HEXIT(&buf2[86+9*i], state->A[i], 8); - } - fwrite(buf2, 1, sizeof(buf2)-1, logfile); -#else // !PSP - char hexbuf[100]; - int hexlen = 0; - - if (nwords > 3) { // We can only fit 3 words on the line - nwords = 3; - } - for (i = 0; i < nwords && hexlen < sizeof(hexbuf)-5; i++) { - hexlen += snprintf(hexbuf+hexlen, sizeof(hexbuf)-hexlen, - "%s%04X", hexlen==0 ? "" : " ", - (int)READU16(state, state->PC+2*i)); - } - - fprintf(logfile, "%06X: %-14s %-26s SR=%04X %c%c%c%c%c [%10llu]\n" - " D: %08X %08X %08X %08X %08X %08X %08X %08X\n" - " A: %08X %08X %08X %08X %08X %08X %08X %08X\n", - (int)state->PC, hexbuf, disassembled, (int)state->SR, - state->SR & SR_X ? 'X' : '.', state->SR & SR_N ? 'N' : '.', - state->SR & SR_Z ? 'Z' : '.', state->SR & SR_V ? 'V' : '.', - state->SR & SR_C ? 'C' : '.', (unsigned long long)cycles, - (int)state->D[0], (int)state->D[1], (int)state->D[2], - (int)state->D[3], (int)state->D[4], (int)state->D[5], - (int)state->D[6], (int)state->D[7], - (int)state->A[0], (int)state->A[1], (int)state->A[2], - (int)state->A[3], (int)state->A[4], (int)state->A[5], - (int)state->A[6], (int)state->A[7] - ); -#endif // PSP - - } // current_cycles >= trace_start && current_cycles < trace_stop -} - -/*************************************************************************/ -/*************************************************************************/ - - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68-internal.h b/yabause/src/q68/q68-internal.h deleted file mode 100644 index 48db390df7..0000000000 --- a/yabause/src/q68/q68-internal.h +++ /dev/null @@ -1,644 +0,0 @@ -/* src/q68/q68-internal.h: Internal declarations/definitions used by Q68 - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef Q68_INTERNAL_H -#define Q68_INTERNAL_H - -#ifndef Q68_CONST_H -# include "q68-const.h" -#endif - -/*************************************************************************/ -/******************** Defines controlling compilation ********************/ -/*************************************************************************/ - -/** - * Q68_USE_JIT: When defined, enables the use of dynamic translation. - * Defining this on a CPU without dynamic translation support will result - * in a compilation error. - * - * See q68-jit.h for additional settings specific to dynamic translation. - */ -// #define Q68_USE_JIT - -/** - * Q68_JIT_OPTIMIZE_FLAGS: When defined, allows the dynamic translator to - * skip setting the condition flags (XNZVC) after an instruction when it - * can prove that doing so will have no effect on program execution (e.g. - * because the following instruction overwrites the flags). This will - * cause an instruction-by-instruction execution trace to differ from an - * actual 68000, though the program behavior will remain unchanged - * (barring any bugs in the optimization). - */ -#define Q68_JIT_OPTIMIZE_FLAGS - -/** - * Q68_JIT_LOOSE_TIMING: When defined, allows the dynamic translator to - * take some leeway in checking execution timing, such that instructions - * may continue to be executed even after the cycle limit has been reached. - * This allows the translated code to execute more quickly, but will - * slightly alter the timing of responses to external events such as - * interrupts. - */ -#define Q68_JIT_LOOSE_TIMING - -/** - * Q68_OPTIMIZE_IDLE: When defined, optimizes certain idle loops to - * improve performance in JIT mode. Enabling this option slightly alters - * execution timing. - */ -#define Q68_OPTIMIZE_IDLE - -/** - * Q68_JIT_VERBOSE: When defined, outputs some status messages considered - * useful in debugging or optimizing the JIT core. - */ -// #define Q68_JIT_VERBOSE - -/** - * Q68_DISABLE_ADDRESS_ERROR: When defined, disables the generation of - * address error exceptions for unaligned word/longword accesses. The - * behavior for such an access will depend on how the host system handles - * unaligned accesses, and may include the host program itself crashing. - */ -// #define Q68_DISABLE_ADDRESS_ERROR - -/** - * Q68_TRACE: When defined, the execution of every instruction will be - * traced to the file "q68.log" in the current directory. (On Linux, the - * trace will be written in compressed form to "q68.log.gz".) - */ -// #define Q68_TRACE - -/*************************************************************************/ -/************************* Generic helper macros *************************/ -/*************************************************************************/ - -/* Offset of a byte and word within a native long */ -#ifdef WORDS_BIGENDIAN -# define BYTE_OFS 3 -# define WORD_OFS 1 -#else -# define BYTE_OFS 0 -# define WORD_OFS 0 -#endif - -/* Return the length of an array */ -#define lenof(a) (sizeof((a)) / sizeof(*(a))) - -/* Compiler attribute to mark functions as not to be inlined */ -#ifdef __GNUC__ -# define NOINLINE __attribute__((noinline)) -#else -# define NOINLINE /*nothing*/ -#endif - -/* Macro to tell the compiler that a certain condition is likely or - * unlikely to occur */ -#ifdef __GNUC__ -# define LIKELY(x) (__builtin_expect(!!(x), 1)) -# define UNLIKELY(x) (__builtin_expect(!!(x), 0)) -#else -# define LIKELY(x) (x) -# define UNLIKELY(x) (x) -#endif - -/* Debug/error message macro. DMSG("message",...) prints to stderr a line - * in the form: - * func_name(file:line): message - * printf()-style format tokens and arguments are allowed, and no newline - * is required at the end. The format string must be a literal string - * constant. */ -#define DMSG(msg,...) \ - fprintf(stderr, "%s(%s:%d): " msg "\n", __FUNCTION__, __FILE__, __LINE__ \ - , ## __VA_ARGS__) - -/*************************************************************************/ -/******************* Processor state block definition ********************/ -/*************************************************************************/ - -typedef struct Q68JitEntry_ Q68JitEntry; // For JIT code -typedef struct Q68JitBlacklist_ Q68JitBlacklist; // For JIT code - -struct Q68State_ { - - /**** Data directly reflecting the current CPU state ****/ - - /* Registers */ - union { - struct { - uint32_t D[8]; - uint32_t A[8]; - }; - uint32_t DA[16]; // For fast accessing (A0 = D8, A1 = D9, etc.) - }; - uint32_t PC; - uint32_t SR; - uint32_t USP, SSP; - - /* "Current PC" for this instruction (address of opcode + 2) */ - uint32_t current_PC; - - /* Effective address used by the current instruction */ - uint32_t ea_addr; - - /* Pending exception, to be taken after the current instruction has - * been processed (zero if none) */ - unsigned int exception; - /* Auxiliary exception data used for a bus error or address error */ - uint32_t fault_addr; - uint16_t fault_opcode; - uint16_t fault_status; - - /* Nonzero if virtual processor is halted (due to either a STOP - * instruction or a double fault); see Q68_HALTED_* */ - unsigned int halted; - - /* Current interrupt request level */ - unsigned int irq; - - /* Number of clock cycles executed so far */ - uint32_t cycles; - - /**** Environment settings ****/ - - /* Native memory allocation functions */ - void *(*malloc_func)(size_t size); - void *(*realloc_func)(void *ptr, size_t size); - void (*free_func)(void *ptr); - - /* 68k memory read/write functions */ - Q68ReadFunc *readb_func, *readw_func; - Q68WriteFunc *writeb_func, *writew_func; - - /* Native cache flushing function (for JIT) */ - void (*jit_flush)(void); - - /**** JIT-related data ****/ - - /* Currently executing JIT block (NULL = none) */ - Q68JitEntry *jit_running; - - /* Nonzero if JIT routine needs to abort because the underlying 68000 - * code was modified (e.g. by a self-modifying routine) */ - unsigned int jit_abort; - - /* Hash table of translated code segments, hashed by 68000 start address */ - Q68JitEntry *jit_table; // Record buffer - Q68JitEntry **jit_hashchain; // Hash collision chains - - /* Total size of translated data */ - int32_t jit_total_data; // Signed to protect against its going negative - - /* Internal timestamp used by JIT LRU logic */ - uint32_t jit_timestamp; - - /* List of self-modifying blocks not to be translated (zero in both - * address fields indicates a free entry) */ - struct { - uint32_t m68k_start; // Code start address in 68000 address space - uint32_t m68k_end; // Code end address in 68000 address space - uint32_t timestamp; // Time this entry was added - } jit_blacklist[Q68_JIT_BLACKLIST_SIZE]; - - /* Nonzero if the current PC is inside a blacklisted block */ - unsigned int jit_in_blist; - - /* When jit_in_blacklist != 0, indicates the relevant jit_blacklist[] - * array entry index */ - unsigned int jit_blist_num; - - /* Call stack for efficient handling of subroutine calls */ - unsigned int jit_callstack_top; // Index of next entry to write - struct { - uint32_t return_PC; // PC on return from subroutine (0 = free) - Q68JitEntry *return_entry; // JIT block containing native code - void *return_native; // Native address to jump to - } jit_callstack[Q68_JIT_CALLSTACK_SIZE]; - - /* Buffer for tracking translated code blocks */ - uint8_t jit_pages[1<<(24-(Q68_JIT_PAGE_BITS+3))]; - -}; - -/*-----------------------------------------------------------------------*/ - -/* Constants used in the Q68State.halted field */ - -enum { - Q68_HALTED_NONE = 0, // Processor is running normally - Q68_HALTED_STOP, // Processor halted because of a STOP instruction - Q68_HALTED_DOUBLE_FAULT, // Processor halted because of a double fault -}; - -/*-----------------------------------------------------------------------*/ - -/* Macros for accessing Q68State.jit_pages[] (page is assumed to be valid) */ - -#define JIT_PAGE_SET(state,page) \ - ((state)->jit_pages[(page)>>3] |= 1<<((page)&7)) -#define JIT_PAGE_CLEAR(state,page) \ - ((state)->jit_pages[(page)>>3] &= ~(1<<((page)&7))) -#define JIT_PAGE_TEST(state,page) \ - ((state)->jit_pages[(page)>>3] & 1<<((page)&7)) - -/*************************************************************************/ -/************************ JIT interface functions ************************/ -/*************************************************************************/ - -/** - * q68_jit_init: Allocate memory for JIT data. Must be called before any - * other JIT function. - * - * [Parameters] - * state: Processor state block - * [Return value] - * Nonzero on success, zero on error - */ -extern int q68_jit_init(Q68State *state); - -/** - * q68_jit_reset: Reset the dynamic translation state, clearing out all - * previously stored data. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -extern void q68_jit_reset(Q68State *state); - -/** - * q68_jit_cleanup: Destroy all JIT-related data. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -extern void q68_jit_cleanup(Q68State *state); - -/** - * q68_jit_translate: Dynamically translate a block of instructions - * starting at the given address. If a translation already exists for the - * given address, it is cleared. - * - * [Parameters] - * state: Processor state block - * address: Start address in 68000 address space - * [Return value] - * Translated block to be passed to q68_jit_run(), or NULL on error - */ -extern Q68JitEntry *q68_jit_translate(Q68State *state, uint32_t address); - -/** - * q68_jit_find: Find the translated block for a given address, if any. - * - * [Parameters] - * state: Processor state block - * address: Start address in 68000 address space - * [Return value] - * Translated block to be passed to q68_jit_run(), or NULL if no such - * block exists - */ -extern Q68JitEntry *q68_jit_find(Q68State *state, uint32_t address); - -/** - * q68_jit_run: Run translated 68000 code. - * - * [Parameters] - * state: Processor state block - * cycle_limit: Clock cycle limit on execution (code will stop when - * state->cycles >= cycles) - * address_ptr: Pointer to translated block to execute; will be cleared - * to NULL on return if the end of the block was reached - * [Return value] - * None - */ -extern void q68_jit_run(Q68State *state, uint32_t cycle_limit, - Q68JitEntry **entry_ptr); - -/** - * q68_jit_clear: Clear any translation beginning at the given address. - * - * [Parameters] - * state: Processor state block - * address: Start address in 68000 address space - * [Return value] - * None - */ -extern void q68_jit_clear(Q68State *state, uint32_t address); - -/** - * q68_jit_clear_page: Clear any translation which occurs in the JIT page - * containing the given address. Intended for use on writes from external - * sources. - * - * [Parameters] - * state: Processor state block - * address: Address to which data was written - * [Return value] - * None - */ -extern void q68_jit_clear_page(Q68State *state, uint32_t address); - -/** - * q68_jit_clear_write: Clear any translation which includes the given - * address, and (if there is at least one such translation) blacklist the - * address from being translated. - * - * [Parameters] - * state: Processor state block - * address: Address to which data was written - * size: Size of data written - * [Return value] - * None - */ -extern void q68_jit_clear_write(Q68State *state, uint32_t address, uint32_t size); - -/*************************************************************************/ -/************************ Internal-use constants *************************/ -/*************************************************************************/ - -/* Effective address types for ea_type() */ -enum { - EA_xREG, // Data/address register - EA_MEM, // Memory reference - EA_IMM, // Immediate value -}; - -/* Effective address access types for ea_resolve() */ -enum { - ACCESS_READ = 0, - ACCESS_WRITE, - ACCESS_MODIFY, // For the read access of a read-write operation -}; - -/*************************************************************************/ -/*************** Opcode implementation function prototype ****************/ -/*************************************************************************/ - -/** - * OpcodeFunc: Type of a function implementing one or a group of - * instructions. - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * [Return value] - * Clock cycles used - */ -typedef int OpcodeFunc(Q68State *state, uint32_t opcode); - -/*************************************************************************/ -/******************* Memory access functions (inline) ********************/ -/*************************************************************************/ - -/** - * READ[SU]{8,16,32}: Read a value from memory. - * - * [Parameters] - * state: Processor state block - * addr: Address to read or write - * [Return value] - * Value read - */ - -static inline int32_t READS8(Q68State *state, uint32_t addr) { - return (int8_t) state->readb_func(addr & 0xFFFFFF); -} -static inline uint32_t READU8(Q68State *state, uint32_t addr) { - return state->readb_func(addr & 0xFFFFFF); -} - -static inline int32_t READS16(Q68State *state, uint32_t addr) { - return (int16_t) state->readw_func(addr & 0xFFFFFF); -} -static inline uint32_t READU16(Q68State *state, uint32_t addr) { - return state->readw_func(addr & 0xFFFFFF); -} - -static inline int32_t READS32(Q68State *state, uint32_t addr) { - addr &= 0xFFFFFF; - int32_t value = (int32_t) state->readw_func(addr) << 16; - addr += 2; - addr &= 0xFFFFFF; - value |= state->readw_func(addr); - return value; -} -static inline uint32_t READU32(Q68State *state, uint32_t addr) { - addr &= 0xFFFFFF; - uint32_t value = state->readw_func(addr) << 16; - addr += 2; - addr &= 0xFFFFFF; - value |= state->readw_func(addr); - return value; -} - -/*-----------------------------------------------------------------------*/ - -/** - * WRITE{8,16,32}: Write a value to memory. - * - * [Parameters] - * state: Processor state block - * addr: Address to read or write - * data: Value to write - * [Return value] - * None - */ - -static inline void WRITE8(Q68State *state, uint32_t addr, uint8_t data) { - addr &= 0xFFFFFF; -#ifdef Q68_USE_JIT - if (UNLIKELY(JIT_PAGE_TEST(state, addr >> Q68_JIT_PAGE_BITS))) { - q68_jit_clear_write(state, addr, 1); - } -#endif - state->writeb_func(addr, data); -} - -static inline void WRITE16(Q68State *state, uint32_t addr, uint16_t data) { - addr &= 0xFFFFFF; -#ifdef Q68_USE_JIT - if (UNLIKELY(JIT_PAGE_TEST(state, addr >> Q68_JIT_PAGE_BITS))) { - q68_jit_clear_write(state, addr, 2); - } -#endif - state->writew_func(addr, data); -} - -static inline void WRITE32(Q68State *state, uint32_t addr, uint32_t data) { - WRITE16(state, addr, data>>16); - WRITE16(state, addr+2, data); -} - -/*-----------------------------------------------------------------------*/ - -/** - * IFETCH: Retrieve and return the 16-bit word at the PC, incrementing the - * PC by 2. - * - * [Parameters] - * state: Processor state block - * [Return value] - * 16-bit value read - */ - -static inline uint32_t IFETCH(Q68State *state) { - uint32_t data = READU16(state, state->PC); - state->PC += 2; - return data; -} - -/*-----------------------------------------------------------------------*/ - -/** - * PUSH{16,32}, POP{16,32}: Push values onto or pop them off the stack. - * - * [Parameters] - * state: Processor state block - * data: Value to push (PUSH only) - * [Return value] - * Value popped (unsigned, POP only) - */ - -static inline void PUSH16(Q68State *state, uint16_t data) { - state->A[7] -= 2; - WRITE16(state, state->A[7], data); -} -static inline void PUSH32(Q68State *state, uint32_t data) { - state->A[7] -= 4; - WRITE32(state, state->A[7], data); -} - -static inline uint32_t POP16(Q68State *state) { - const uint32_t data = READU16(state, state->A[7]); - state->A[7] += 2; - return data; -} -static inline uint32_t POP32(Q68State *state) { - const uint32_t data = READU32(state, state->A[7]); - state->A[7] += 4; - return data; -} - -/*************************************************************************/ -/******************* Instruction implementation macros *******************/ -/*************************************************************************/ - -/* INSN_GET_REG: uint32_t reg = opcode[11:9] */ -#define INSN_GET_REG \ - uint32_t reg = (opcode>>9) & 7 - -/* INSN_GET_COUNT: uint32_t count = opcode[11:9] || 8 */ -#define INSN_GET_COUNT \ - uint32_t count = (opcode>>9) & 7 ?: 8 - -/* INSN_GET_COND: uint32_t cond = opcode[11:8] */ -#define INSN_GET_COND \ - uint32_t cond = (opcode>>8) & 15 - -/* INSN_GET_SIZE: uint32_t size = opcode[7:6] */ -#define INSN_GET_SIZE \ - uint32_t size = (opcode>>6) & 3 - -/* INSN_GET_REG0: uint32_t reg0 = opcode[2:0] */ -#define INSN_GET_REG0 \ - uint32_t reg0 = opcode & 7 - -/* INSN_GET_IMM8: const int32_t imm8 = SIGN_EXTEND(opcode[7:0]) */ -#define INSN_GET_IMM8 \ - const int32_t imm8 = (int32_t)(int8_t)opcode - -/* INSN_GET_IMM16: const int32_t imm16 = *++PC; */ -#define INSN_GET_IMM16 \ - const int32_t imm16 = (int16_t)IFETCH(state) - -/* INSN_GET_DISP8: int32_t disp = SIGN_EXTEND(opcode[7:0]) */ -#define INSN_GET_DISP8 \ - int32_t disp = (int32_t)(int8_t)opcode - -/*-----------------------------------------------------------------------*/ - -/* INSN_COND_TRUE: Evaluate whether the given condition code is satisfied. */ -#define INSN_COND_TRUE(cond) __extension__({ \ - const unsigned int __cond = (cond); \ - const unsigned int group = __cond >> 1; \ - const unsigned int onoff = __cond & 1; \ - (group==COND_LS>>1 ? (state->SR & SR_C) >> SR_C_SHIFT \ - | (state->SR & SR_Z) >> SR_Z_SHIFT : \ - group==COND_CS>>1 ? (state->SR & SR_C) >> SR_C_SHIFT : \ - group==COND_EQ>>1 ? (state->SR & SR_Z) >> SR_Z_SHIFT : \ - group==COND_VS>>1 ? (state->SR & SR_V) >> SR_V_SHIFT : \ - group==COND_MI>>1 ? (state->SR & SR_N) >> SR_N_SHIFT : \ - group==COND_LT>>1 ? (state->SR & SR_N) >> SR_N_SHIFT \ - ^ (state->SR & SR_V) >> SR_V_SHIFT : \ - group==COND_LE>>1 ? (state->SR & SR_Z) >> SR_Z_SHIFT \ - | ((state->SR & SR_N) >> SR_N_SHIFT \ - ^ (state->SR & SR_V) >> SR_V_SHIFT) : \ - 0 /* COND_T or COND_F */ \ - ) == onoff; \ -}) - -/*-----------------------------------------------------------------------*/ - -/* INSN_CLEAR_XCC, INSN_CLEAR_CC: Clear all condition codes, or all except - * the X flag. */ -#define INSN_CLEAR_XCC() (state->SR &= ~(SR_X|SR_N|SR_Z|SR_V|SR_C)) -#define INSN_CLEAR_CC() (state->SR &= ~( SR_N|SR_Z|SR_V|SR_C)) - - -/* INSN_SETNZ: Set the N and Z flags according to the given 32-bit result. - * Assumes the flags are currently cleared. */ -#define INSN_SETNZ(result) do { \ - const int32_t __result = (result); \ - if (__result < 0) { \ - state->SR |= SR_N; \ - } else if (__result == 0) { \ - state->SR |= SR_Z; \ - } \ -} while (0) - -/* INSN_SETNZ_SHIFT: Like INSN_SETNZ, but assumes the presence of a "shift" - * variable containing the number of bits of "result" less one. */ -#define INSN_SETNZ_SHIFT(result) do { \ - const int32_t __result = (result); \ - if (__result >> shift) { \ - state->SR |= SR_N; \ - } else if (__result == 0) { \ - state->SR |= SR_Z; \ - } \ -} while (0) - -/*************************************************************************/ -/*************************************************************************/ - -#endif // Q68_INTERNAL_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68-jit-psp.S b/yabause/src/q68/q68-jit-psp.S deleted file mode 100644 index b6a7204320..0000000000 --- a/yabause/src/q68/q68-jit-psp.S +++ /dev/null @@ -1,2876 +0,0 @@ -/* src/q68/q68-jit-psp.S: PSP dynamic translation implementation for Q68 - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "q68-const.h" - -.set noreorder -.set nomips16 - -#define s8 fp // since binutils doesn't seem to recognize $s8 on its own - -/*************************************************************************/ - -/* - * Register and stack usage is as follows: - * - * $v0 -- result; temporary used by macros; (on return) address to resume - * execution at, or NULL to terminate execution - * $v1 -- temporary - * $a0 -- temporary - * $a1 -- temporary - * $a2 -- temporary - * $a3 -- temporary - * $t0 -- temporary (not used by macros) - * $t1 -- temporary (not used by macros) - * $t2 -- temporary (not used by macros) - * $t3 -- temporary (not used by macros) - * $t4 -- temporary (not used by macros) - * $t5 -- not used - * $t6 -- not used - * $t7 -- operand 2 - * $t8 -- not used - * $t9 -- indirect function call pointer - * $s0 -- Q68State structure pointer - * $s1 -- cycles to execute - * $s2 -- cumulative cycle count - * $s3 -- operand 1; persistent temporary - * $s4 -- PC mirror register - * $s5 -- SR mirror register - * $s6 -- effective address (used instead of state->ea_addr); persistent - * temporary - * $s7 -- value of Q68State.jit_abort - * $s8 -- not used (not saved by JIT_CALL()) - * - * 0($sp) -- temporary (used by READ/WRITE macros to hold addresses) - * 4($sp) -- temporary (used by READ/WRITE macros to hold values) - * 8($sp) -- unused - * 12($sp) -- saved $ra - */ - -/*************************************************************************/ - -/* Label/size/parameter definition macros */ -#define DEFLABEL(name) .globl JIT_PSP_##name; \ - .type JIT_PSP_##name, @function; \ - JIT_PSP_##name: -#define DEFSIZE(name) .globl JIT_PSPSIZE_##name; \ - .type JIT_PSPSIZE_##name, @object; \ - JIT_PSPSIZE_##name: .int . - JIT_PSP_##name -#define DEFPARAM(name,param,label,offset) \ - .globl JIT_PSPPARAM_##name##_##param; \ - .type JIT_PSPPARAM_##name##_##param, @object; \ - JIT_PSPPARAM_##name##_##param: .int label - JIT_PSP_##name + (offset) - -/* Q68State structure offsets */ -Q68State_D = 0 -Q68State_A = 32 -Q68State_PC = 64 -Q68State_SR = 68 -Q68State_USP = 72 -Q68State_SSP = 76 -Q68State_current_PC = 80 -Q68State_ea_addr = 84 -Q68State_exception = 88 -Q68State_fault_addr = 92 -Q68State_fault_opcode = 96 -Q68State_fault_status = 98 -Q68State_halted = 100 -Q68State_irq = 104 -Q68State_cycles = 108 -Q68State_malloc_func = 112 -Q68State_realloc_func = 116 -Q68State_free_func = 120 -Q68State_readb_func = 124 -Q68State_readw_func = 128 -Q68State_writeb_func = 132 -Q68State_writew_func = 136 -Q68State_jit_flush = 140 -Q68State_jit_running = 144 -Q68State_jit_abort = 148 -Q68State_jit_table = 152 -Q68State_jit_hashchain = 156 -Q68State_jit_total_data = 160 -Q68State_jit_timestamp = 164 -Q68State_jit_blacklist = 168 -Q68State_jit_in_blist = Q68State_jit_blacklist + (12 * Q68_JIT_BLACKLIST_SIZE) -Q68State_jit_blist_num = Q68State_jit_in_blist + 4 -Q68State_jit_callstack_top = Q68State_jit_blist_num + 4 -Q68State_jit_callstack = Q68State_jit_callstack_top + 4 -Q68State_jit_pages = Q68State_jit_callstack + (12 * Q68_JIT_CALLSTACK_SIZE) - -/*************************************************************************/ - -/* Shorthand for referencing Q68State fields */ - -#define D0 Q68State_D+0*4($s0) -#define D1 Q68State_D+1*4($s0) -#define D2 Q68State_D+2*4($s0) -#define D3 Q68State_D+3*4($s0) -#define D4 Q68State_D+4*4($s0) -#define D5 Q68State_D+5*4($s0) -#define D6 Q68State_D+6*4($s0) -#define D7 Q68State_D+7*4($s0) - -#define A0 Q68State_A+0*4($s0) -#define A1 Q68State_A+1*4($s0) -#define A2 Q68State_A+2*4($s0) -#define A3 Q68State_A+3*4($s0) -#define A4 Q68State_A+4*4($s0) -#define A5 Q68State_A+5*4($s0) -#define A6 Q68State_A+6*4($s0) -#define A7 Q68State_A+7*4($s0) - -#define PC Q68State_PC($s0) -#define SR Q68State_SR($s0) -#define USP Q68State_USP($s0) -#define SSP Q68State_SSP($s0) - -/*************************************************************************/ - -/* LOAD_DELAY_NOP is used to indicate where a pipeline stall will occur - * due to a dependency on data loaded by a previous instruction. It - * doesn't actually expand to anything, but can be used as a hint for - * optimization. */ - -#define LOAD_DELAY_NOP /*nothing*/ - -/*************************************************************************/ -/************************** Convenience macros ***************************/ -/*************************************************************************/ - -/** - * seqz: seqz rd,rs is a clearer substitute for sltiu rd,rs,1 and sets rd - * to 1 if rs is zero, 0 otherwise. - */ -.macro seqz rd, rs - sltiu \rd, \rs, 1 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * snez: sgtz rd,rs is a clearer substitute for sltu rd,zero,rs and sets - * rd to 1 if rs is positive, 0 otherwise. - */ -.macro snez rd, rs - sltu \rd, $zero, \rs -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * sgtz: sgtz rd,rs is a clearer substitute for slt rd,zero,rs and sets - * rd to 1 if rs is positive, 0 otherwise. - */ -.macro sgtz rd, rs - slt \rd, $zero, \rs -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * sltz: sltz rd,rs is a clearer substitute for slti rd,rs,0 and sets rd - * to 1 if rs is negative, 0 otherwise. - */ -.macro sltz rd, rs - slti \rd, \rs, 0 -.endm - -/*************************************************************************/ - -/** - * SETUP: Perform setup required before executing translated code. - */ -.macro SETUP - addiu $sp, $sp, -16 - lw $s5, Q68State_SR($s0) - lw $s4, Q68State_PC($s0) - sw $ra, 12($sp) - move $s7, $zero -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * TERMINATE: Terminate execution of the current block. The emulator will - * resume execution at the address in state->PC. - */ -.macro TERMINATE - lw $ra, 12($sp) - sw $s4, Q68State_PC($s0) - sw $s5, Q68State_SR($s0) - move $v0, $zero - jr $ra - addiu $sp, $sp, 16 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * TERMINATE_CONTINUE: Terminate execution of the current block, returning - * the address of the following native instruction. - */ -.macro TERMINATE_CONTINUE - sw $s4, Q68State_PC($s0) - jal TERMINATE_CONTINUE_get_pc - sw $s5, Q68State_SR($s0) - jr $ra - addiu $sp, $sp, 16 - SETUP -.endm - -/* Helper subroutine to get the PC */ -TERMINATE_CONTINUE_get_pc: - addiu $v0, $ra, 8 // Size of "jr ra; addiu $sp, $sp, 16" - jr $ra - lw $ra, 12($sp) // Preload the saved $ra to avoid a load stall - -/*************************************************************************/ - -/** - * READ{8,16,32}: Read a value from memory. The address to read from is - * taken from $s6; the value read is returned zero-extended in \return. - */ -.macro READ8 return - lw $t9, Q68State_readb_func($s0) - ext $a0, $s6, 0, 24 // Mask off top 8 bits - LOAD_DELAY_NOP - jalr $t9 - nop - andi \return, $v0, 0xFF -.endm - -.macro READ16 return - lw $t9, Q68State_readw_func($s0) - ext $a0, $s6, 0, 24 - LOAD_DELAY_NOP - jalr $t9 - nop - andi \return, $v0, 0xFFFF -.endm - -.macro READ32 return - lw $t9, Q68State_readw_func($s0) - ext $a0, $s6, 0, 24 - LOAD_DELAY_NOP - jalr $t9 // Read high word - sw $a0, 0($sp) - lw $a0, 0($sp) - sll $v0, $v0, 16 - lw $t9, Q68State_readw_func($s0) - sw $v0, 4($sp) - addiu $a0, $a0, 2 - jalr $t9 // Read low word - ext $a0, $a0, 0, 24 // Just in case we're reading from $FFFFFE - lw $v1, 4($sp) - andi $v0, $v0, 0xFFFF - LOAD_DELAY_NOP - or \return, $v0, $v1 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * WRITE_CHECK_JIT: Check whether a write of size \nbytes (*bytes*, not - * bits) to the address in $s6 would clobber a page containing already- - * translated blocks, and clear those translations if so. All caller-saved - * registers are destroyed. - * - * Note that this macro uses local label 4. - */ -.macro WRITE_CHECK_JIT nbytes - srl $a0, $s6, Q68_JIT_PAGE_BITS+3 - addu $a0, $a0, $s0 - lbu $v0, Q68State_jit_pages($a0) - ext $a1, $s6, Q68_JIT_PAGE_BITS, 3 - li $v1, 1 - beqz $v0, 4f - sllv $v1, $v1, $a1 - and $v0, $v0, $v1 - beqz $v0, 4f - move $a1, $s6 - li $a2, \nbytes - jal q68_jit_clear_write - move $a0, $s0 - lw $s7, Q68State_jit_abort($s0) -4: -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * WRITE{8,16,32}: Write a value to memory. The address must be stored in - * $s6, and the value to write in $v0. Note that a 32-bit write spanning - * two JIT pages that clobbers the first word of a translated routine - * beginning on the second page will not be detected. - */ -.macro WRITE8 - sw $v0, 4($sp) - WRITE_CHECK_JIT 1 - lw $t9, Q68State_writeb_func($s0) - lw $a1, 4($sp) - LOAD_DELAY_NOP - jalr $t9 - ext $a0, $s6, 0, 24 -.endm - -.macro WRITE16 - sw $v0, 4($sp) - WRITE_CHECK_JIT 2 - lw $t9, Q68State_writew_func($s0) - lw $a1, 4($sp) - LOAD_DELAY_NOP - jalr $t9 - ext $a0, $s6, 0, 24 -.endm - -.macro WRITE32 - sw $v0, 4($sp) - WRITE_CHECK_JIT 4 - lw $t9, Q68State_writew_func($s0) - lw $a1, 4($sp) - ext $a0, $s6, 0, 24 - jalr $t9 // Write high word - srl $a1, $a1, 16 - lw $t9, Q68State_writew_func($s0) - lhu $a1, 4($sp) // Keep only the low 16 bits of the value - addiu $a0, $s6, 2 - jalr $t9 // Write low word - ext $a0, $a0, 0, 24 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * {PUSH,POP}{16,32}: Push or pop values onto or off of the stack. For - * POP, the value popped is zero-extended and returned in \return. - * - * For pushes, it is assumed that the push does not clobber any - * JIT-translated code. - */ -.macro PUSH16 value - lw $a0, A7 - lw $t9, Q68State_writew_func($s0) - move $a1, \value - addiu $a0, $a0, -2 - sw $a0, A7 - jalr $t9 - ext $a0, $a0, 0, 24 -.endm - -.macro PUSH32 value - lw $a0, A7 - lw $t9, Q68State_writew_func($s0) - sw \value, 4($sp) - addiu $a0, $a0, -4 - sw $a0, A7 - ext $a0, $a0, 0, 24 - jalr $t9 // Write high word - srl $a1, \value, 16 - lw $a0, A7 - lw $t9, Q68State_writew_func($s0) - lhu $a1, 4($sp) // Keep only the low 16 bits of \value - addiu $a0, $a0, 2 - jalr $t9 // Write low word - ext $a0, $a0, 0, 24 -.endm - -.macro POP16 return - lw $a0, A7 - lw $t9, Q68State_readw_func($s0) - LOAD_DELAY_NOP - addiu $v0, $a0, 2 - sw $v0, A7 - jalr $t9 - ext $a0, $a0, 0, 24 - andi \return, $v0, 0xFFFF -.endm - -.macro POP32 return - lw $a0, A7 - lw $t9, Q68State_readw_func($s0) - LOAD_DELAY_NOP - addiu $v0, $a0, 4 - sw $v0, A7 - jalr $t9 // Read high word - ext $a0, $a0, 0, 24 - lw $a0, A7 - sll $v0, $v0, 16 - lw $t9, Q68State_readw_func($s0) - sw $v0, 4($sp) - addiu $a0, $a0, -2 // Since it was already incremented by 4 - jalr $t9 // Read low word - ext $a0, $a0, 0, 24 - lw $v1, 4($sp) - andi $v0, $v0, 0xFFFF - LOAD_DELAY_NOP - or \return, $v0, $v1 -.endm - -/*************************************************************************/ - -/** - * SETCC_NZ_[BWL]: Set the N and Z condition codes according to \value. - */ -.macro SETCC_NZ_B value - ext $v1, \value, 7, 1 - ins $s5, $v1, SR_N_SHIFT, 1 - andi $v1, \value, 0xFF - seqz $v1, $v1 - ins $s5, $v1, SR_Z_SHIFT, 1 -.endm - -.macro SETCC_NZ_W value - ext $v1, \value, 15, 1 - ins $s5, $v1, SR_N_SHIFT, 1 - andi $v1, \value, 0xFFFF - seqz $v1, $v1 - ins $s5, $v1, SR_Z_SHIFT, 1 -.endm - -.macro SETCC_NZ_L value - ext $v1, \value, 31, 1 - ins $s5, $v1, SR_N_SHIFT, 1 - seqz $v1, \value - ins $s5, $v1, SR_Z_SHIFT, 1 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_NZ00_[BWL]: Set the N and Z condition codes according to \value, - * and clear the V and C condition codes. - */ -.macro SETCC_NZ00_B value - SETCC_NZ_B \value - ins $s5, $zero, 0, 2 -.endm - -.macro SETCC_NZ00_W value - SETCC_NZ_W \value - ins $s5, $zero, 0, 2 -.endm - -.macro SETCC_NZ00_L value - SETCC_NZ_L \value - ins $s5, $zero, 0, 2 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_XNZVC_ADD: Set the condition codes for an ADD operation based on - * the values in the op1, op2, and result registers. - */ -.macro SETCC_XNZVC_ADD nbits - .if \nbits == 8 - SETCC_NZ_B $v0 - .else - .if \nbits == 16 - SETCC_NZ_W $v0 - .else - SETCC_NZ_L $v0 - .endif - .endif - xor $a0, $s3, $v0 - xor $a1, $t7, $v0 - and $v1, $a0, $a1 - ext $v1, $v1, \nbits-1, 1 - ins $s5, $v1, SR_V_SHIFT, 1 - ext $a0, $s3, \nbits-1, 1 - ext $a1, $t7, \nbits-1, 1 - ext $v1, $v0, \nbits-1, 1 - addu $a0, $a0, $a1 - subu $v1, $a0, $v1 - sgtz $v1, $v1 - ins $s5, $v1, SR_C_SHIFT, 1 - ins $s5, $v1, SR_X_SHIFT, 1 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_XNZVC_ADDX: Set the condition codes for an ADDX operation based - * on the values in the op1, op2, and result registers. - */ -.macro SETCC_XNZVC_ADDX nbits - // Z is only cleared (never set) by ADDX etc., so we can't use SETNZ - ext $v1, $v0, \nbits-1, 1 - ins $s5, $v1, SR_N_SHIFT, 1 - .if \nbits < 32 - ext $v1, $v0, 0, \nbits - snez $v1, $v1 - .else - snez $v1, $v0 - .endif - sll $v1, $v1, SR_Z_SHIFT - not $v1, $v1 - and $s5, $s5, $v1 - xor $a0, $s3, $v0 - xor $a1, $t7, $v0 - and $v1, $a0, $a1 - ext $v1, $v1, \nbits-1, 1 - ins $s5, $v1, SR_V_SHIFT, 1 - ext $a0, $s3, \nbits-1, 1 - ext $a1, $t7, \nbits-1, 1 - ext $v1, $v0, \nbits-1, 1 - addu $a0, $a0, $a1 - subu $v1, $a0, $v1 - sgtz $v1, $v1 - ins $s5, $v1, SR_C_SHIFT, 1 - ins $s5, $v1, SR_X_SHIFT, 1 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_NZVC_SUB, SETCC_XNZVC_SUB: Set the condition codes for a SUB - * operation (excluding or including the X flag) based on the values in the - * op1, op2, and result registers. - */ -.macro SETCC_NZVC_SUB nbits - .if \nbits == 8 - SETCC_NZ_B $v0 - .else - .if \nbits == 16 - SETCC_NZ_W $v0 - .else - SETCC_NZ_L $v0 - .endif - .endif - xor $a0, $s3, $t7 - xor $a1, $v0, $t7 - and $v1, $a0, $a1 - ext $v1, $v1, \nbits-1, 1 - ins $s5, $v1, SR_V_SHIFT, 1 - ext $a0, $s3, \nbits-1, 1 - ext $a1, $t7, \nbits-1, 1 - ext $v1, $v0, \nbits-1, 1 - subu $a0, $a0, $a1 - addu $v1, $a0, $v1 - sgtz $v1, $v1 - ins $s5, $v1, SR_C_SHIFT, 1 -.endm - -.macro SETCC_XNZVC_SUB nbits - SETCC_NZVC_SUB \nbits - ins $s5, $v1, SR_X_SHIFT, 1 -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_XNZVC_SUBX: Set the condition codes for a SUBX operation based on - * the values in the op1, op2, and result registers. - */ -.macro SETCC_XNZVC_SUBX nbits - ext $v1, $v0, \nbits-1, 1 - ins $s5, $v1, SR_N_SHIFT, 1 - .if \nbits < 32 - ext $v1, $v0, 0, \nbits - snez $v1, $v1 - .else - snez $v1, $v0 - .endif - sll $v1, $v1, SR_Z_SHIFT - not $v1, $v1 - and $s5, $s5, $v1 - xor $a0, $s3, $t7 - xor $a1, $v0, $t7 - and $v1, $a0, $a1 - ext $v1, $v1, \nbits-1, 1 - ins $s5, $v1, SR_V_SHIFT, 1 - ext $a0, $s3, \nbits-1, 1 - ext $a1, $t7, \nbits-1, 1 - ext $v1, $v0, \nbits-1, 1 - subu $a0, $a0, $a1 - addu $v1, $a0, $v1 - sgtz $v1, $v1 - ins $s5, $v1, SR_C_SHIFT, 1 - ins $s5, $v1, SR_X_SHIFT, 1 -.endm - -/*************************************************************************/ -/*************************** Local subroutines ***************************/ -/*************************************************************************/ - -/** - * UPDATE_SR: Set the status register according to the value in $v0. - */ -UPDATE_SR: - lw $a0, Q68State_irq($s0) // Load early for IRQ check below - xor $v1, $s5, $v0 - andi $v1, $v1, SR_S // Change in S bit? - beqz $v1, 1f - andi $s5, $v0, 0xFFFF // Zero-extend value into SR mirror register - andi $v1, $v0, SR_S // Which way did it change? - beqz $v1, 0f - lw $a0, A7 - lw $a1, SSP // Into supervisor mode - LOAD_DELAY_NOP - sw $a0, USP - j 1f - sw $a1, A7 -0: lw $a1, USP // Out of supervisor mode - sw $a0, SSP - LOAD_DELAY_NOP - sw $a1, A7 -1: andi $v1, $a0, 7 - slti $a1, $v1, 7 // Check for a pending NMI - beqz $a1, 2f - ext $v0, $v0, SR_I0_SHIFT, 3 - slt $v0, $v0, $v1 // Check for a pending unmasked interrupt - beqz $v0, 3f -2: addiu $a0, $v1, EX_LEVEL_1_INTERRUPT-1 // In a delay slot, but okay - sw $a0, Q68State_exception($s0) - sw $zero, Q68State_irq($s0) - TERMINATE -3: jr $ra - nop - -/*************************************************************************/ -/**************************** Meta-operations ****************************/ -/*************************************************************************/ - -/** - * PROLOGUE: Any prologue necessary at the beginning of the code stream. - */ -DEFLABEL(PROLOGUE) -_PROLOGUE_TOP: - /* Include various exceptional termination code here, so we can - * conditionally branch to it (meaning we can skip the branch in - * 1-2 cycles) instead of having to inverse-branch around an - * unconditional jump (costing 3-4 cycles). */ - b 0f - nop -_PROLOGUE_TERMINATE: // Generic termination (used for CHECK_ABORT) -1: TERMINATE -_PROLOGUE_EXCEPTION: // Exception raised (exception number in $a0) - b 1b - sw $a0, Q68State_exception($s0) -_PROLOGUE_ADDRESS_ERROR_EA: // EA address error (opcode in $a2, status in $a3) - li $v1, EX_ADDRESS_ERROR - sw $v1, Q68State_exception($s0) - sw $s6, Q68State_fault_addr($s0) - sh $a2, Q68State_fault_opcode($s0) - b 1b - sh $a3, Q68State_fault_status($s0) -_PROLOGUE_ADDRESS_ERROR_SP: // Stack address error (address in $a1, - // opcode in $a2, status in $a3) - li $a0, EX_ADDRESS_ERROR - sw $a0, Q68State_exception($s0) - sw $v1, Q68State_fault_addr($s0) - sh $a2, Q68State_fault_opcode($s0) - b 1b - sh $a3, Q68State_fault_status($s0) -0: // Actual setup starts here - SETUP -DEFSIZE(PROLOGUE) - - -/* Offset definitions used for branching to termination code; "branchofs" - * is the offset in _instructions_ (not bytes) from the beginning of the - * named fragment */ -#define DEFOFS(name,branchofs) \ - .globl JIT_PSPOFS_##name; \ - .type JIT_PSPOFS_##name, @object; \ - JIT_PSPOFS_##name: .int _PROLOGUE_##name - _PROLOGUE_TOP - 4*branchofs -DEFOFS(TERMINATE, 0) -DEFOFS(EXCEPTION, 0) -DEFOFS(ADDRESS_ERROR_EA, 2) -DEFOFS(ADDRESS_ERROR_SP, 4) - -/*-----------------------------------------------------------------------*/ - -/** - * EPILOGUE: Any epilogue necessary at the end of the code stream. - */ -DEFLABEL(EPILOGUE) - TERMINATE -DEFSIZE(EPILOGUE) - -/*************************************************************************/ - -/** - * TRACE: Trace the current instruction. - */ -DEFLABEL(TRACE) - lw $s3, Q68State_cycles($s0) - addu $t0, $s3, $s2 - sw $t0, Q68State_cycles($s0) - sw $s4, Q68State_PC($s0) - jal q68_trace - sw $s5, Q68State_SR($s0) - sw $s3, Q68State_cycles($s0) -DEFSIZE(TRACE) - -/*************************************************************************/ - -/** - * ADD_CYCLES: Add the specified number of clock cycles to the cycle count. - * - * [Parameters] - * cycles: Number of clock cycles to add - */ -DEFLABEL(ADD_CYCLES) - addiu $s2, $s2, 1 -9: -DEFSIZE(ADD_CYCLES) -DEFPARAM(ADD_CYCLES, cycles, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_CYCLES: Check whether the clock cycle limit has been reached, and - * interrupt execution if so. - */ -DEFLABEL(CHECK_CYCLES) - slt $v0, $s2, $s1 - bnez $v0, 2f - sw $s4, Q68State_PC($s0) // Can't have JAL in a delay slot - jal CHECK_CYCLES_get_pc // (got to keep up their reputation) - sw $s5, Q68State_SR($s0) -0: jr $ra - addiu $sp, $sp, 16 -1: SETUP -2: -DEFSIZE(CHECK_CYCLES) - -/* Helper subroutine to get the PC (as with TERMINATE_CONTINUE) */ -CHECK_CYCLES_get_pc: - addiu $v0, $ra, 1b-0b - jr $ra - lw $ra, 12($sp) // Preload the saved $ra to avoid a load stall - -/*************************************************************************/ - -/** - * ADVANCE_PC: Add the specified value to the current program counter. - * - * [Parameters] - * value: Amount to add - */ -DEFLABEL(ADVANCE_PC) - addiu $s4, $s4, 1 -9: -DEFSIZE(ADVANCE_PC) -DEFPARAM(ADVANCE_PC, value, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * ADVANCE_PC_CHECK_ABORT: Add the specified value to the current program - * counter, then check the jit_abort flag and abort if necessary. - * - * [Parameters] - * value: Amount to add - * disp_4: (JIT_PSPOFS_TERMINATE - native offset of this fragment) / 4 - */ -DEFLABEL(ADVANCE_PC_CHECK_ABORT) - bnez $s7, .+0x1234 -8: addiu $s4, $s4, 1 -9: -DEFSIZE(ADVANCE_PC_CHECK_ABORT) -DEFPARAM(ADVANCE_PC_CHECK_ABORT, value, 9b, -4) -DEFPARAM(ADVANCE_PC_CHECK_ABORT, disp_4, 8b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_ABORT: Check the jit_abort flag and abort if necessary. - * - * [Parameters] - * disp_4: (JIT_PSPOFS_TERMINATE - native offset of this fragment) / 4 - */ -DEFLABEL(CHECK_ABORT) - bnez $s7, .+0x1234 -9: nop -DEFSIZE(CHECK_ABORT) -DEFPARAM(CHECK_ABORT, disp_4, 9b, -4) - -/*************************************************************************/ - -/** - * EXCEPTION: Raise the specified exception. - * - * [Parameters] - * num: Exception number - * disp_4: (JIT_PSPOFS_EXCEPTION - native offset of this fragment) / 4 - */ -DEFLABEL(EXCEPTION) - b .+0x1234 -8: addiu $a0, $zero, 1 -9: -DEFSIZE(EXCEPTION) -DEFPARAM(EXCEPTION, num, 9b, -4) -DEFPARAM(EXCEPTION, disp_4, 8b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_ALIGNED_EA: Check whether the previously resolved effective - * address is word-aligned (bit 0 is clear), and raise an address error - * exception if not. - * - * [Parameters] - * opcode: Instruction opcode - * status: Status word for address error exception - * disp_4: (JIT_PSPOFS_ADDRESS_ERROR_EA - * - native offset of this fragment) / 4 - */ -DEFLABEL(CHECK_ALIGNED_EA) - andi $v1, $s6, 1 - ori $a2, $zero, 0x1234 -7: bnezl $v1, .+0x1234 -8: ori $a3, $zero, 0x1234 -9: -DEFSIZE(CHECK_ALIGNED_EA) -DEFPARAM(CHECK_ALIGNED_EA, opcode, 7b, -4) -DEFPARAM(CHECK_ALIGNED_EA, status, 9b, -4) -DEFPARAM(CHECK_ALIGNED_EA, disp_4, 8b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_ALIGNED_SP: Check whether the current stack pointer (register A7) - * is word-aligned (bit 0 is clear), and raise an address error exception - * if not. Destroys $v1 and $a0-$a3. - * - * [Parameters] - * opcode: Instruction opcode - * status: Status word for address error exception - * disp_4: (JIT_PSPOFS_ADDRESS_ERROR_SP - * - native offset of this fragment) / 4 - */ -DEFLABEL(CHECK_ALIGNED_SP) - lw $a1, A7 - ori $a2, $zero, 0x1234 -7: LOAD_DELAY_NOP - andi $v1, $a1, 1 - bnez $v1, .+0x1234 -8: ori $a3, $zero, 0x1234 -9: -DEFSIZE(CHECK_ALIGNED_SP) -DEFPARAM(CHECK_ALIGNED_SP, opcode, 7b, -4) -DEFPARAM(CHECK_ALIGNED_SP, status, 9b, -4) -DEFPARAM(CHECK_ALIGNED_SP, disp_4, 8b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_SUPER: Check whether the processor is in supervisor mode, and - * raise a privilege violation exception if not. - * - * [Parameters] - * disp_4: (JIT_PSPOFS_EXCEPTION - native offset of this fragment) / 4 - */ -DEFLABEL(CHECK_SUPER) - andi $v0, $s5, SR_S - beqzl $v0, .+0x1234 -9: li $a0, EX_PRIVILEGE_VIOLATION -DEFSIZE(CHECK_SUPER) -DEFPARAM(CHECK_SUPER, disp_4, 9b, -4) - -/*************************************************************************/ -/********************* Effective address resolution **********************/ -/*************************************************************************/ - -/** - * RESOLVE_INDIRECT: Resolve an address register indirect reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - */ -DEFLABEL(RESOLVE_INDIRECT) - lw $s6, 1($s0) -9: -DEFSIZE(RESOLVE_INDIRECT) -DEFPARAM(RESOLVE_INDIRECT, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_POSTINC: Resolve an address register postincrement reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - * size: Size in bytes of the reference - */ -DEFLABEL(RESOLVE_POSTINC) - lw $s6, 1($s0) -7: LOAD_DELAY_NOP - LOAD_DELAY_NOP - addiu $v0, $s6, 1 -8: sw $v0, 1($s0) -9: -DEFSIZE(RESOLVE_POSTINC) -DEFPARAM(RESOLVE_POSTINC, reg4, 7b, -4) -DEFPARAM(RESOLVE_POSTINC, size, 8b, -4) -DEFPARAM(RESOLVE_POSTINC, reg4_b, 9b, -4) // same as reg4 - -/* For byte-sized (A7)+, make sure A7 stays even */ -DEFLABEL(RESOLVE_POSTINC_A7_B) - lw $s6, A7 - LOAD_DELAY_NOP - LOAD_DELAY_NOP - addiu $s6, $s6, 1 - addiu $v0, $s6, 1 - sw $v0, A7 -DEFSIZE(RESOLVE_POSTINC_A7_B) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_PREDEC: Resolve an address register predecrement reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - * nsize: Size in bytes of the reference, negated - */ -DEFLABEL(RESOLVE_PREDEC) - lw $s6, 1($s0) -7: LOAD_DELAY_NOP - LOAD_DELAY_NOP - addiu $s6, $s6, -1 -8: sw $s6, 1($s0) -9: -DEFSIZE(RESOLVE_PREDEC) -DEFPARAM(RESOLVE_PREDEC, reg4, 7b, -4) -DEFPARAM(RESOLVE_PREDEC, nsize, 8b, -4) -DEFPARAM(RESOLVE_PREDEC, reg4_b, 9b, -4) // same as reg4 - -/* For byte-sized -(A7), make sure A7 stays even */ -DEFLABEL(RESOLVE_PREDEC_A7_B) - lw $s6, 1($s0) - LOAD_DELAY_NOP - LOAD_DELAY_NOP - addiu $s6, $s6, -1 - addiu $v0, $s6, -1 - sw $v0, A7 -DEFSIZE(RESOLVE_PREDEC_A7_B) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_DISP: Resolve an address register indirect with displacement - * reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - * disp: Displacement - */ -DEFLABEL(RESOLVE_DISP) - lw $s6, 1($s0) -8: LOAD_DELAY_NOP - LOAD_DELAY_NOP - addiu $s6, $s6, 1 -9: -DEFSIZE(RESOLVE_DISP) -DEFPARAM(RESOLVE_DISP, reg4, 8b, -4) -DEFPARAM(RESOLVE_DISP, disp, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_INDEX_[WL]: Resolve an address register indirect with index - * reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - * ireg4: Index register number * 4 - * disp: Displacement - */ -DEFLABEL(RESOLVE_INDEX_W) - lw $s6, 1($s0) -7: lh $v0, 1($s0) -8: LOAD_DELAY_NOP - addi $s6, $s6, 1 -9: add $s6, $s6, $v0 -DEFSIZE(RESOLVE_INDEX_W) -DEFPARAM(RESOLVE_INDEX_W, reg4, 7b, -4) -DEFPARAM(RESOLVE_INDEX_W, ireg4, 8b, -4) -DEFPARAM(RESOLVE_INDEX_W, disp, 9b, -4) - -DEFLABEL(RESOLVE_INDEX_L) - lw $s6, 1($s0) -7: lw $v0, 1($s0) -8: LOAD_DELAY_NOP - addi $s6, $s6, 1 -9: add $s6, $s6, $v0 -DEFSIZE(RESOLVE_INDEX_L) -DEFPARAM(RESOLVE_INDEX_L, reg4, 7b, -4) -DEFPARAM(RESOLVE_INDEX_L, ireg4, 8b, -4) -DEFPARAM(RESOLVE_INDEX_L, disp, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_ABSOLUTE: Resolve an absolute short, absolute long, or - * PC-relative reference. - * - * [Parameters] - * addr_hi: Absolute address, high 16 bits - * addr_lo: Absolute address, low 16 bits - */ -DEFLABEL(RESOLVE_ABSOLUTE) - lui $s6, 0x1234 -8: ori $s6, $s6, 0x5678 -9: -DEFSIZE(RESOLVE_ABSOLUTE) -DEFPARAM(RESOLVE_ABSOLUTE, addr_hi, 8b, -4) -DEFPARAM(RESOLVE_ABSOLUTE, addr_lo, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_ABS_INDEX_[WL]: Resolve a PC-relative with index reference. - * - * [Parameters] - * ireg4: Index register number * 4 - * addr_hi: Absolute address, high 16 bits - * addr_lo: Absolute address, low 16 bits - */ -DEFLABEL(RESOLVE_ABS_INDEX_W) - lh $v0, 1($s0) -7: lui $s6, 0x1234 -8: ori $s6, $s6, 0x5678 -9: addu $s6, $s6, $v0 -DEFSIZE(RESOLVE_ABS_INDEX_W) -DEFPARAM(RESOLVE_ABS_INDEX_W, ireg4, 7b, -4) -DEFPARAM(RESOLVE_ABS_INDEX_W, addr_hi, 8b, -4) -DEFPARAM(RESOLVE_ABS_INDEX_W, addr_lo, 9b, -4) - -DEFLABEL(RESOLVE_ABS_INDEX_L) - lh $v0, 1($s0) -7: lui $s6, 0x1234 -8: ori $s6, $s6, 0x5678 -9: addu $s6, $s6, $v0 -DEFSIZE(RESOLVE_ABS_INDEX_L) -DEFPARAM(RESOLVE_ABS_INDEX_L, ireg4, 7b, -4) -DEFPARAM(RESOLVE_ABS_INDEX_L, addr_hi, 8b, -4) -DEFPARAM(RESOLVE_ABS_INDEX_L, addr_lo, 9b, -4) - -/*************************************************************************/ -/*************************** Operand retrieval ***************************/ -/*************************************************************************/ - -/** - * GET_OP1_REGISTER: Get the current value of the given register as - * operand 1. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(GET_OP1_REGISTER) - lw $s3, 1($s0) -9: -DEFSIZE(GET_OP1_REGISTER) -DEFPARAM(GET_OP1_REGISTER, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * GET_OP1_EA_[BWL]: Get the value pointed to by the previously resolved - * effective address as operand 1. - */ -DEFLABEL(GET_OP1_EA_B) - READ8 $s3 -DEFSIZE(GET_OP1_EA_B) - -DEFLABEL(GET_OP1_EA_W) - READ16 $s3 -DEFSIZE(GET_OP1_EA_W) - -DEFLABEL(GET_OP1_EA_L) - READ32 $s3 -DEFSIZE(GET_OP1_EA_L) - -/*-----------------------------------------------------------------------*/ - -/** - * GET_OP1_IMMED_{16S,16U,16HI,32}: Get an immediate value as operand 1. - * - * [Parameters] - * value_hi: High 16 bits of immediate value - * value_lo: Low 16 bits of immediate value (signed for 16S, else unsigned) - */ -DEFLABEL(GET_OP1_IMMED_16S) - addiu $s3, $zero, 1 -9: -DEFSIZE(GET_OP1_IMMED_16S) -DEFPARAM(GET_OP1_IMMED_16S, value_lo, 9b, -4) - -DEFLABEL(GET_OP1_IMMED_16U) - ori $s3, $zero, 1 -9: -DEFSIZE(GET_OP1_IMMED_16U) -DEFPARAM(GET_OP1_IMMED_16U, value_lo, 9b, -4) - -DEFLABEL(GET_OP1_IMMED_16HI) - lui $s3, 1 -9: -DEFSIZE(GET_OP1_IMMED_16HI) -DEFPARAM(GET_OP1_IMMED_16HI, value_hi, 9b, -4) - -DEFLABEL(GET_OP1_IMMED_32) - lui $s3, 1 -8: ori $s3, $s3, 1 -9: -DEFSIZE(GET_OP1_IMMED_32) -DEFPARAM(GET_OP1_IMMED_32, value_hi, 8b, -4) -DEFPARAM(GET_OP1_IMMED_32, value_lo, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * GET_OP1_CCR: Get the current value of CCR as operand 1. - */ -DEFLABEL(GET_OP1_CCR) - andi $s3, $s5, 0xFF -DEFSIZE(GET_OP1_CCR) - -/*-----------------------------------------------------------------------*/ - -/** - * GET_OP1_SR: Get the current value of SR as operand 1. - */ -DEFLABEL(GET_OP1_SR) - move $s3, $s5 -DEFSIZE(GET_OP1_SR) - -/*************************************************************************/ - -/** - * GET_OP2_*: Get the same things as above as operand 2. - */ -DEFLABEL(GET_OP2_REGISTER) - lw $t7, 1($s0) -9: -DEFSIZE(GET_OP2_REGISTER) -DEFPARAM(GET_OP2_REGISTER, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(GET_OP2_EA_B) - READ8 $t7 -DEFSIZE(GET_OP2_EA_B) - -DEFLABEL(GET_OP2_EA_W) - READ16 $t7 -DEFSIZE(GET_OP2_EA_W) - -DEFLABEL(GET_OP2_EA_L) - READ32 $t7 -DEFSIZE(GET_OP2_EA_L) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(GET_OP2_IMMED_16S) - addiu $t7, $zero, 1 -9: -DEFSIZE(GET_OP2_IMMED_16S) -DEFPARAM(GET_OP2_IMMED_16S, value_lo, 9b, -4) - -DEFLABEL(GET_OP2_IMMED_16U) - ori $t7, $zero, 1 -9: -DEFSIZE(GET_OP2_IMMED_16U) -DEFPARAM(GET_OP2_IMMED_16U, value_lo, 9b, -4) - -DEFLABEL(GET_OP2_IMMED_16HI) - lui $t7, 1 -9: -DEFSIZE(GET_OP2_IMMED_16HI) -DEFPARAM(GET_OP2_IMMED_16HI, value_hi, 9b, -4) - -DEFLABEL(GET_OP2_IMMED_32) - lui $t7, 1 -8: ori $t7, $t7, 1 -9: -DEFSIZE(GET_OP2_IMMED_32) -DEFPARAM(GET_OP2_IMMED_32, value_hi, 8b, -4) -DEFPARAM(GET_OP2_IMMED_32, value_lo, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(GET_OP2_CCR) - andi $t7, $s5, 0xFF -DEFSIZE(GET_OP2_CCR) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(GET_OP2_SR) - move $t7, $s5 -DEFSIZE(GET_OP2_SR) - -/*************************************************************************/ -/**************************** Result storing *****************************/ -/*************************************************************************/ - -/** - * SET_REGISTER_[BWL]: Set the value of the given register to the result - * value. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(SET_REGISTER_B) - sb $v0, 1($s0) -9: -DEFSIZE(SET_REGISTER_B) -DEFPARAM(SET_REGISTER_B, reg4, 9b, -4) - -DEFLABEL(SET_REGISTER_W) - sh $v0, 1($s0) -9: -DEFSIZE(SET_REGISTER_W) -DEFPARAM(SET_REGISTER_W, reg4, 9b, -4) - -DEFLABEL(SET_REGISTER_L) - sw $v0, 1($s0) -9: -DEFSIZE(SET_REGISTER_L) -DEFPARAM(SET_REGISTER_L, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * SET_AREG_W: Set the value of the given address register to the - * sign-extended result value. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(SET_AREG_W) - seh $v1, $v0 - sw $v1, 1($s0) -9: -DEFSIZE(SET_AREG_W) -DEFPARAM(SET_AREG_W, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * SET_EA_[BWL]: Set the value pointed to by the previously resolved - * effective address to the result value. - */ -DEFLABEL(SET_EA_B) - WRITE8 -DEFSIZE(SET_EA_B) - -DEFLABEL(SET_EA_W) - WRITE16 -DEFSIZE(SET_EA_W) - -DEFLABEL(SET_EA_L) - WRITE32 -DEFSIZE(SET_EA_L) - -/*-----------------------------------------------------------------------*/ - -/** - * SET_CCR: Set the condition codes from the result value. - */ -DEFLABEL(SET_CCR) - ins $s5, $v0, 0, 8 -DEFSIZE(SET_CCR) - -/*-----------------------------------------------------------------------*/ - -/** - * SET_SR: Set the status register from the result value. - */ -DEFLABEL(SET_SR) - jal UPDATE_SR - nop -DEFSIZE(SET_SR) - -/*************************************************************************/ -/*************************** Stack operations ****************************/ -/*************************************************************************/ - -/** - * PUSH_L: Push the 32-bit value of operand 1 onto the stack. - */ -DEFLABEL(PUSH_L) - PUSH32 $s3 -DEFSIZE(PUSH_L) - -/*-----------------------------------------------------------------------*/ - -/** - * POP_L: Pop a 32-bit value off the stack into the result register. - */ -DEFLABEL(POP_L) - POP32 $v0 -DEFSIZE(POP_L) - -/*************************************************************************/ -/************************ Condition code setting *************************/ -/*************************************************************************/ - -/** - * SETCC_ADD_[BWL]: Set the condition codes for the result of an ADD - * instruction stored in the result register. - */ -DEFLABEL(SETCC_ADD_B) - SETCC_XNZVC_ADD 8 -DEFSIZE(SETCC_ADD_B) - -DEFLABEL(SETCC_ADD_W) - SETCC_XNZVC_ADD 16 -DEFSIZE(SETCC_ADD_W) - -DEFLABEL(SETCC_ADD_L) - SETCC_XNZVC_ADD 32 -DEFSIZE(SETCC_ADD_L) - -/*************************************************************************/ - -/** - * SETCC_ADDX_[BWL]: Set the condition codes for the result of an ADDX - * instruction stored in the result register. - */ -DEFLABEL(SETCC_ADDX_B) - SETCC_XNZVC_ADDX 8 -DEFSIZE(SETCC_ADDX_B) - -DEFLABEL(SETCC_ADDX_W) - SETCC_XNZVC_ADDX 16 -DEFSIZE(SETCC_ADDX_W) - -DEFLABEL(SETCC_ADDX_L) - SETCC_XNZVC_ADDX 32 -DEFSIZE(SETCC_ADDX_L) - -/*************************************************************************/ - -/** - * SETCC_SUB_[BWL]: Set the condition codes for the result of a SUB - * instruction stored in the result register. - */ -DEFLABEL(SETCC_SUB_B) - SETCC_XNZVC_SUB 8 -DEFSIZE(SETCC_SUB_B) - -DEFLABEL(SETCC_SUB_W) - SETCC_XNZVC_SUB 16 -DEFSIZE(SETCC_SUB_W) - -DEFLABEL(SETCC_SUB_L) - SETCC_XNZVC_SUB 32 -DEFSIZE(SETCC_SUB_L) - -/*************************************************************************/ - -/** - * SETCC_SUBX_[BWL]: Set the condition codes for the result of a SUBX - * instruction stored in the result register. - */ -DEFLABEL(SETCC_SUBX_B) - SETCC_XNZVC_SUBX 8 -DEFSIZE(SETCC_SUBX_B) - -DEFLABEL(SETCC_SUBX_W) - SETCC_XNZVC_SUBX 16 -DEFSIZE(SETCC_SUBX_W) - -DEFLABEL(SETCC_SUBX_L) - SETCC_XNZVC_SUBX 32 -DEFSIZE(SETCC_SUBX_L) - -/*************************************************************************/ - -/** - * SETCC_CMP_[BWL]: Set the condition codes for the result of a CMP - * instruction stored in the result register. The X flag is unmodified. - */ -DEFLABEL(SETCC_CMP_B) - SETCC_NZVC_SUB 8 -DEFSIZE(SETCC_CMP_B) - -DEFLABEL(SETCC_CMP_W) - SETCC_NZVC_SUB 16 -DEFSIZE(SETCC_CMP_W) - -DEFLABEL(SETCC_CMP_L) - SETCC_NZVC_SUB 32 -DEFSIZE(SETCC_CMP_L) - -/*************************************************************************/ - -/** - * SETCC_LOGIC_[BWL]: Set the condition codes for the result of a logical - * instruction (MOVE, AND, OR, EOR) stored in the result register. The X - * flag is unmodified. - */ -DEFLABEL(SETCC_LOGIC_B) - SETCC_NZ00_B $v0 -DEFSIZE(SETCC_LOGIC_B) - -DEFLABEL(SETCC_LOGIC_W) - SETCC_NZ00_W $v0 -DEFSIZE(SETCC_LOGIC_W) - -DEFLABEL(SETCC_LOGIC_L) - SETCC_NZ00_L $v0 -DEFSIZE(SETCC_LOGIC_L) - -/*************************************************************************/ -/*************************** Condition testing ***************************/ -/*************************************************************************/ - -/** - * TEST_*: Check whether a condition is true (based on the current - * condition codes) and set $v1 based on the result (nonzero = true). - */ - -DEFLABEL(TEST_T) - li $v1, 1 -DEFSIZE(TEST_T) - -DEFLABEL(TEST_F) - li $v1, 0 -DEFSIZE(TEST_F) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_HI) - ext $v1, $s5, SR_Z_SHIFT, 1 - ext $a0, $s5, SR_C_SHIFT, 1 - or $v1, $v1, $a0 - xori $v1, $v1, 1 -DEFSIZE(TEST_HI) - -DEFLABEL(TEST_LS) - ext $v1, $s5, SR_Z_SHIFT, 1 - ext $a0, $s5, SR_C_SHIFT, 1 - or $v1, $v1, $a0 -DEFSIZE(TEST_LS) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_CC) - ext $v1, $s5, SR_C_SHIFT, 1 - xori $v1, $v1, 1 -DEFSIZE(TEST_CC) - -DEFLABEL(TEST_CS) - ext $v1, $s5, SR_C_SHIFT, 1 -DEFSIZE(TEST_CS) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_NE) - ext $v1, $s5, SR_Z_SHIFT, 1 - xori $v1, $v1, 1 -DEFSIZE(TEST_NE) - -DEFLABEL(TEST_EQ) - ext $v1, $s5, SR_Z_SHIFT, 1 -DEFSIZE(TEST_EQ) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_VC) - ext $v1, $s5, SR_V_SHIFT, 1 - xori $v1, $v1, 1 -DEFSIZE(TEST_VC) - -DEFLABEL(TEST_VS) - ext $v1, $s5, SR_V_SHIFT, 1 -DEFSIZE(TEST_VS) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_PL) - ext $v1, $s5, SR_N_SHIFT, 1 - xori $v1, $v1, 1 -DEFSIZE(TEST_PL) - -DEFLABEL(TEST_MI) - ext $v1, $s5, SR_N_SHIFT, 1 -DEFSIZE(TEST_MI) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_GE) - ext $v1, $s5, SR_N_SHIFT, 1 - ext $a0, $s5, SR_V_SHIFT, 1 - xor $v1, $v1, $a0 - xori $v1, $v1, 1 -DEFSIZE(TEST_GE) - -DEFLABEL(TEST_LT) - ext $v1, $s5, SR_N_SHIFT, 1 - ext $a0, $s5, SR_V_SHIFT, 1 - xor $v1, $v1, $a0 -DEFSIZE(TEST_LT) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_GT) - ext $v1, $s5, SR_N_SHIFT, 1 - ext $a0, $s5, SR_V_SHIFT, 1 - ext $a1, $s5, SR_Z_SHIFT, 1 - xor $v1, $v1, $a0 - or $v1, $v1, $a1 - xori $v1, $v1, 1 -DEFSIZE(TEST_GT) - -DEFLABEL(TEST_LE) - ext $v1, $s5, SR_N_SHIFT, 1 - ext $a0, $s5, SR_V_SHIFT, 1 - ext $a1, $s5, SR_Z_SHIFT, 1 - xor $v1, $v1, $a0 - or $v1, $v1, $a1 -DEFSIZE(TEST_LE) - -/*************************************************************************/ -/**************************** ALU operations *****************************/ -/*************************************************************************/ - -/** - * MOVE_[BWL]: Evaluate op1, setting the result value for the MOVE - * instruction. - */ -DEFLABEL(MOVE_B) - move $v0, $s3 -DEFSIZE(MOVE_B) - -DEFLABEL(MOVE_W) - move $v0, $s3 -DEFSIZE(MOVE_W) - -DEFLABEL(MOVE_L) - move $v0, $s3 -DEFSIZE(MOVE_L) - -/*************************************************************************/ - -/** - * ADD_[BWL]: Evaluate op2 + op1. - */ -DEFLABEL(ADD_B) - addu $v0, $t7, $s3 -DEFSIZE(ADD_B) - -DEFLABEL(ADD_W) - addu $v0, $t7, $s3 -DEFSIZE(ADD_W) - -DEFLABEL(ADD_L) - addu $v0, $t7, $s3 -DEFSIZE(ADD_L) - -/*-----------------------------------------------------------------------*/ - -/** - * ADDA_W: Sign-extend op1 to 32 bits, then evaluate op2 + op1. - */ -DEFLABEL(ADDA_W) - seh $v1, $s3 - addu $v0, $t7, $v1 -DEFSIZE(ADDA_W) - -/*-----------------------------------------------------------------------*/ - -/** - * ADDX_[BWL]: Evaluate op2 + op1 + X. - */ -DEFLABEL(ADDX_B) - ext $v1, $s5, SR_X_SHIFT, 1 - addu $v0, $t7, $s3 - addu $v0, $v0, $v1 -DEFSIZE(ADDX_B) - -DEFLABEL(ADDX_W) - ext $v1, $s5, SR_X_SHIFT, 1 - addu $v0, $t7, $s3 - addu $v0, $v0, $v1 -DEFSIZE(ADDX_W) - -DEFLABEL(ADDX_L) - ext $v1, $s5, SR_X_SHIFT, 1 - addu $v0, $t7, $s3 - addu $v0, $v0, $v1 -DEFSIZE(ADDX_L) - -/*************************************************************************/ - -/** - * SUB_[BWL]: Evaluate op2 - op1. - */ -DEFLABEL(SUB_B) - subu $v0, $t7, $s3 -DEFSIZE(SUB_B) - -DEFLABEL(SUB_W) - subu $v0, $t7, $s3 -DEFSIZE(SUB_W) - -DEFLABEL(SUB_L) - subu $v0, $t7, $s3 -DEFSIZE(SUB_L) - -/*-----------------------------------------------------------------------*/ - -/** - * SUBA_W: Sign-extend op1 to 32 bits, then evaluate op2 - op1. - */ -DEFLABEL(SUBA_W) - seh $v1, $s3 - subu $v0, $t7, $v1 -DEFSIZE(SUBA_W) - -/*-----------------------------------------------------------------------*/ - -/** - * SUBX_[BWL]: Evaluate op2 - op1 - X. - */ -DEFLABEL(SUBX_B) - ext $v1, $s5, SR_X_SHIFT, 1 - subu $v0, $t7, $s3 - subu $v0, $v0, $v1 -DEFSIZE(SUBX_B) - -DEFLABEL(SUBX_W) - ext $v1, $s5, SR_X_SHIFT, 1 - subu $v0, $t7, $s3 - subu $v0, $v0, $v1 -DEFSIZE(SUBX_W) - -DEFLABEL(SUBX_L) - ext $v1, $s5, SR_X_SHIFT, 1 - subu $v0, $t7, $s3 - subu $v0, $v0, $v1 -DEFSIZE(SUBX_L) - -/*************************************************************************/ - -/** - * MUL[SU]_W: Evaluate op2 * op1 in signed or unsigned context. - */ -DEFLABEL(MULS_W) - seh $v0, $t7 - seh $v1, $s3 - mul $v0, $v1 - mflo $v0 -DEFSIZE(MULS_W) - -DEFLABEL(MULU_W) - andi $v0, $t7, 0xFFFF - andi $v1, $s3, 0xFFFF - multu $v0, $v1 - mflo $v0 -DEFSIZE(MULU_W) - -/*************************************************************************/ - -/** - * DIV[SU]_W: Evaluate op2 / op1 in signed or unsigned context, setting - * the condition codes appropriately. The quotient is stored in the low - * 16 bits, the remainder in the high 16 bits of the result value. On - * overflow, op2 is copied to the result. - */ -DEFLABEL(DIVS_W) - seh $v1, $s3 - /* MIPS doesn't raise an exception on divide-by-zero, so let the - * divider unit do its thing while we check for a zero divisor */ - div $t7, $v1 - bnez $v1, 0f - // The C flag is always cleared, so do it here in the delay slot - ins $s5, $zero, SR_C_SHIFT, 1 - li $a0, EX_DIVIDE_BY_ZERO - sw $a0, Q68State_exception($s0) - TERMINATE -0: mflo $v0 - mfhi $a3 - li $a0, 0x8000 // Overflow check - addu $a0, $v0, $a0 - srl $a0, $a0, 16 - beqz $a0, 1f - sll $a3, $a3, 16 - li $a0, 1 - ins $s5, $a0, SR_V_SHIFT, 1 - j 2f - move $v0, $t7 -1: andi $v0, $v0, 0xFFFF // Need to clear upper bits in case it's negative - SETCC_NZ_W $v0 - ins $s5, $zero, SR_V_SHIFT, 1 - or $v0, $v0, $a3 -2: -DEFSIZE(DIVS_W) - -DEFLABEL(DIVU_W) - andi $v1, $s3, 0xFFFF - divu $t7, $v1 - bnez $v1, 0f - ins $s5, $zero, SR_C_SHIFT, 1 - li $a0, EX_DIVIDE_BY_ZERO - sw $a0, Q68State_exception($s0) - TERMINATE -0: mflo $v0 - mfhi $a3 - srl $a0, $v0, 16 // Overflow check (easier for unsigned quotients) - beqz $a0, 1f - sll $a3, $a3, 16 - li $a0, 1 - ins $s5, $a0, SR_V_SHIFT, 1 - j 2f - move $v0, $t7 -1: SETCC_NZ_W $v0 - ins $s5, $zero, SR_V_SHIFT, 1 - or $v0, $v0, $a3 -2: -DEFSIZE(DIVU_W) - -/*************************************************************************/ - -/** - * AND_[BWL]: Evaluate op2 & op1. - */ -DEFLABEL(AND_B) - and $v0, $t7, $s3 -DEFSIZE(AND_B) - -DEFLABEL(AND_W) - and $v0, $t7, $s3 -DEFSIZE(AND_W) - -DEFLABEL(AND_L) - and $v0, $t7, $s3 -DEFSIZE(AND_L) - -/*************************************************************************/ - -/** - * OR_[BWL]: Evaluate op2 | op1. - */ -DEFLABEL(OR_B) - or $v0, $t7, $s3 -DEFSIZE(OR_B) - -DEFLABEL(OR_W) - or $v0, $t7, $s3 -DEFSIZE(OR_W) - -DEFLABEL(OR_L) - or $v0, $t7, $s3 -DEFSIZE(OR_L) - -/*************************************************************************/ - -/** - * EOR_[BWL]: Evaluate op2 ^ op1. - */ -DEFLABEL(EOR_B) - xor $v0, $t7, $s3 -DEFSIZE(EOR_B) - -DEFLABEL(EOR_W) - xor $v0, $t7, $s3 -DEFSIZE(EOR_W) - -DEFLABEL(EOR_L) - xor $v0, $t7, $s3 -DEFSIZE(EOR_L) - -/*************************************************************************/ - -/** - * EXT_[WL]: Sign-extend op1 from 8 to 16 or from 16 to 32 bits. - */ -DEFLABEL(EXT_W) - seb $v0, $s3 -DEFSIZE(EXT_W) - -DEFLABEL(EXT_L) - seh $v0, $s3 -DEFSIZE(EXT_L) - -/*************************************************************************/ - -/** - * SWAP: Swap the upper and lower 16-bit halves of op1, placing the result - * in the result register. - */ -DEFLABEL(SWAP) - srl $v0, $s3, 16 - ins $v0, $s3, 16, 16 -DEFSIZE(SWAP) - -/*************************************************************************/ -/**************************** BCD operations *****************************/ -/*************************************************************************/ - -/** - * ABCD: Evaluate op2 + op1 + X, treating the operands as binary-coded - * decimal values. - */ -DEFLABEL(ABCD) - ext $t2, $s5, SR_X_SHIFT, 1 - andi $t0, $t7, 0xF - andi $t1, $s3, 0xF - addu $t3, $t0, $t1 - addu $t3, $t3, $t2 - sltiu $v1, $t3, 10 - beqzl $v1, 0f - addiu $t3, $t3, 6 // Skipped if no carry from the units place -0: andi $t0, $t7, 0xF0 - andi $t1, $s3, 0xF0 - addu $t2, $t0, $t1 - addu $v0, $t2, $t3 - sltiu $v1, $v0, 10<<4 - bnezl $v1, 1f - move $a3, $zero // Executed if no carry from the tens place - addiu $v0, $v0, -(10<<4) - li $a3, 1 -1: ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 - andi $v1, $v0, 0xFF - snez $v1, $v1 - sll $v1, $v1, SR_Z_SHIFT - not $v1, $v1 - and $s5, $s5, $v1 -DEFSIZE(ABCD) - -/*************************************************************************/ - -/** - * SBCD: Evaluate op2 - op1 - X, treating the operands as binary-coded - * decimal values. - */ -DEFLABEL(SBCD) - ext $t2, $s5, SR_X_SHIFT, 1 - andi $t0, $t7, 0xF - andi $t1, $s3, 0xF - subu $t3, $t0, $t1 - subu $t3, $t3, $t2 - sltz $v1, $t3 - bnezl $v1, 0f - move $t2, $zero // Executed if no borrow from the units place - addiu $t3, $t3, 10 - li $t2, 1<<4 -0: andi $t0, $t7, 0xF0 - andi $t1, $s3, 0xF0 - subu $t4, $t0, $t1 - subu $t4, $t4, $t2 - sltz $v1, $t4 - bnezl $v1, 1f - move $a3, $zero // Executed if no carry from the tens place - addiu $v0, $v0, 10<<4 - li $a3, 1 -1: addu $v0, $t3, $t4 - sltz $v1, $v0 - or $a3, $a3, $v1 - ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 - andi $v1, $v0, 0xFF - snez $v1, $v1 - sll $v1, $v1, SR_Z_SHIFT - not $v1, $v1 - and $s5, $s5, $v1 -DEFSIZE(SBCD) - -/*************************************************************************/ -/*********************** Bit-twiddling operations ************************/ -/*************************************************************************/ - -/** - * BTST_[BL]: Evaluate op2 & (1 << op1). The value (1 << op1), where the - * high bits of op1 have been masked to zero, is left in $t0 for use by a - * subsequent BCHG/BCLR/BSET operation. - */ -DEFLABEL(BTST_B) - andi $a0, $s3, 7 - li $t0, 1 - sllv $t0, $t0, $a0 - and $v1, $t7, $t0 - seqz $v1, $v1 - ins $s5, $v1, SR_Z_SHIFT, 1 -DEFSIZE(BTST_B) - -DEFLABEL(BTST_L) - andi $a0, $s3, 31 - li $t0, 1 - sllv $t0, $t0, $a0 - and $v1, $t7, $t0 - seqz $v1, $v1 - ins $s5, $v1, SR_Z_SHIFT, 1 -DEFSIZE(BTST_L) - -/*************************************************************************/ - -/** - * BCHG: Evaluate op2 ^ (1 << op1), where (1 << op1) has already been - * stored in $t0. - */ -DEFLABEL(BCHG) - xor $v0, $t7, $t0 -DEFSIZE(BCHG) - -/*-----------------------------------------------------------------------*/ - -/** - * BCLR: Evaluate op2 & ~(1 << op1), where (1 << op1) has already been - * stored in $t0. - */ -DEFLABEL(BCLR) - not $v1, $t0 - and $v0, $t7, $v1 -DEFSIZE(BCLR) - -/*-----------------------------------------------------------------------*/ - -/** - * BSET: Evaluate op2 | (1 << op1), where (1 << op1) has already been - * stored in $t0. - */ -DEFLABEL(BSET) - or $v0, $t7, $t0 -DEFSIZE(BSET) - -/*************************************************************************/ -/************************ Shift/rotate operations ************************/ -/*************************************************************************/ - -/** - * ASL_[BWL]: Evaluate (signed) op2 << op1. - */ -.macro DEF_ASL nbits - andi $s3, $s3, 0x3F - sll $v1, $s3, 1 // Add 2 clock cycles per shift - add $s2, $s2, $v1 - ins $s5, $zero, SR_C_SHIFT, 2 // Clear V and C - beqz $s3, 1f - move $v0, $t7 - // Have to shift bit by bit to detect overflow -0: ext $a3, $v0, \nbits-1, 1 - ext $v1, $v0, \nbits-2, 1 - sll $v0, $v0, 1 - addiu $s3, $s3, -1 - xor $v1, $v1, $a3 - sll $v1, $v1, SR_V_SHIFT - bnez $s3, 0b - or $s5, $s5, $v1 - ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 -1: -.endm - -DEFLABEL(ASL_B) - DEF_ASL 8 - SETCC_NZ_B $v0 -DEFSIZE(ASL_B) - -DEFLABEL(ASL_W) - DEF_ASL 16 - SETCC_NZ_W $v0 -DEFSIZE(ASL_W) - -DEFLABEL(ASL_L) - DEF_ASL 32 - SETCC_NZ_L $v0 -DEFSIZE(ASL_L) - -/*-----------------------------------------------------------------------*/ - -/** - * ASR_[BWL]: Evaluate (signed) op2 >> op1. - */ -.macro DEF_ASR nbits - andi $s3, $s3, 0x3F - sll $v1, $s3, 1 - add $s2, $s2, $v1 - ins $s5, $zero, SR_C_SHIFT, 2 // Clear V and C - beqz $s3, 3f - move $v0, $t7 - sltiu $v1, $s3, \nbits - bnez $v1, 2f - nop -1: // count >= nbits - sra $v0, $t7, \nbits-1 - andi $a3, $v0, 1 - ins $s5, $a3, SR_C_SHIFT, 1 - j 3f - ins $s5, $a3, SR_X_SHIFT, 1 -2: // count != 0 && count < nbits - addiu $v1, $s3, -1 - srav $v0, $t7, $v1 - andi $a3, $v0, 1 - ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 - sra $v0, $v0, 1 -3: // All cases -.endm - -DEFLABEL(ASR_B) - seb $t7 - DEF_ASR 8 - SETCC_NZ_B $v0 -DEFSIZE(ASR_B) - -DEFLABEL(ASR_W) - seh $t7 - DEF_ASR 16 - SETCC_NZ_W $v0 -DEFSIZE(ASR_W) - -DEFLABEL(ASR_L) - DEF_ASR 32 - SETCC_NZ_L $v0 -DEFSIZE(ASR_L) - -/*************************************************************************/ - -/** - * LSL_[BWL]: Evaluate (unsigned) op2 << op1. - */ -.macro DEF_LSL nbits - andi $s3, $s3, 0x3F - sll $v1, $s3, 1 - add $s2, $s2, $v1 - ins $s5, $zero, SR_C_SHIFT, 2 // Clear V and C - beqz $s3, 3f - move $v0, $t7 - li $a0, \nbits - sltu $v1, $s3, $a0 - bnez $v1, 2f - sltu $v1, $a0, $s3 - bnez $v1, 1f - nop -0: // count == nbits - ins $s5, $t7, SR_C_SHIFT, 1 - ins $s5, $t7, SR_X_SHIFT, 1 - j 3f - move $v0, $zero -1: // count > nbits - ins $s5, $zero, SR_X_SHIFT, 1 - j 3f - move $v0, $zero -2: // count != 0 && count < nbits - addiu $v1, $s3, -1 - sllv $v0, $t7, $v1 - ext $a3, $v0, \nbits-1, 1 - ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 - sll $v0, $v0, 1 -3: // All cases -.endm - -DEFLABEL(LSL_B) - DEF_LSL 8 - SETCC_NZ_B $v0 -DEFSIZE(LSL_B) - -DEFLABEL(LSL_W) - DEF_LSL 16 - SETCC_NZ_W $v0 -DEFSIZE(LSL_W) - -DEFLABEL(LSL_L) - DEF_LSL 32 - SETCC_NZ_L $v0 -DEFSIZE(LSL_L) - -/*-----------------------------------------------------------------------*/ - -/** - * LSR_[BWL]: Evaluate (unsigned) op2 >> op1. - */ -.macro DEF_LSR nbits - andi $s3, $s3, 0x3F - sll $v1, $s3, 1 - add $s2, $s2, $v1 - ins $s5, $zero, SR_C_SHIFT, 2 // Clear V and C - beqz $s3, 3f - move $v0, $t7 - li $a0, \nbits - sltu $v1, $s3, $a0 - bnez $v1, 2f - sltu $v1, $a0, $s3 - bnez $v1, 1f - nop -0: // count == nbits - ext $a3, $t7, \nbits-1, 1 - ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 - j 3f - move $v0, $zero -1: // count > nbits - ins $s5, $zero, SR_X_SHIFT, 1 - j 3f - move $v0, $zero -2: // count != 0 && count < nbits - addiu $v1, $s3, -1 - srlv $v0, $t7, $v1 - andi $a3, $v0, 1 - ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 - srl $v0, $v0, 1 -3: // All cases -.endm - -DEFLABEL(LSR_B) - andi $t7, $t7, 0xFF - DEF_LSR 8 - SETCC_NZ_B $v0 -DEFSIZE(LSR_B) - -DEFLABEL(LSR_W) - andi $t7, $t7, 0xFFFF - DEF_LSR 16 - SETCC_NZ_W $v0 -DEFSIZE(LSR_W) - -DEFLABEL(LSR_L) - DEF_LSR 32 - SETCC_NZ_L $v0 -DEFSIZE(LSR_L) - -/*************************************************************************/ - -/** - * ROXL_[BWL]: Evaluate op2 ROXL op1. - */ -.macro DEF_ROXL nbits - andi $s3, $s3, 0x3F - sll $v1, $s3, 1 - add $s2, $s2, $v1 - ext $a3, $s5, SR_X_SHIFT, 1 - ins $s5, $a3, SR_C_SHIFT, 2 // Clear V while setting C - beqz $s3, 1f - move $v0, $t7 -0: sll $v1, $v0, 1 - ext $a0, $v0, \nbits-1, 1 - or $v0, $v1, $a3 - addiu $s3, $s3, -1 - bnez $s3, 0b - move $a3, $a0 - ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 -1: -.endm - -DEFLABEL(ROXL_B) - DEF_ROXL 8 - SETCC_NZ_B $v0 -DEFSIZE(ROXL_B) - -DEFLABEL(ROXL_W) - DEF_ROXL 16 - SETCC_NZ_W $v0 -DEFSIZE(ROXL_W) - -DEFLABEL(ROXL_L) - DEF_ROXL 32 - SETCC_NZ_L $v0 -DEFSIZE(ROXL_L) - -/*-----------------------------------------------------------------------*/ - -/** - * ROXR_[BWL]: Evaluate op2 ROXR op1. - */ -.macro DEF_ROXR nbits - andi $s3, $s3, 0x3F - sll $v1, $s3, 1 - add $s2, $s2, $v1 - ext $a3, $s5, SR_X_SHIFT, 1 - ins $s5, $a3, SR_C_SHIFT, 2 // Clear V while setting C - beqz $s3, 1f - move $v0, $t7 -0: srl $v1, $v0, 1 - ins $v1, $a3, \nbits-1, 1 - andi $a3, $v0, 1 - addiu $s3, $s3, -1 - bnez $s3, 0b - move $v0, $v1 - ins $s5, $a3, SR_C_SHIFT, 1 - ins $s5, $a3, SR_X_SHIFT, 1 -1: -.endm - -DEFLABEL(ROXR_B) - DEF_ROXR 8 - SETCC_NZ_B $v0 -DEFSIZE(ROXR_B) - -DEFLABEL(ROXR_W) - DEF_ROXR 16 - SETCC_NZ_W $v0 -DEFSIZE(ROXR_W) - -DEFLABEL(ROXR_L) - DEF_ROXR 32 - SETCC_NZ_L $v0 -DEFSIZE(ROXR_L) - -/*************************************************************************/ - -/** - * ROL_[BWL]: Evaluate op2 ROL op1. - */ -.macro DEF_ROL nbits - andi $s3, $s3, 0x3F - sll $v1, $s3, 1 - add $s2, $s2, $v1 - ins $s5, $zero, SR_C_SHIFT, 2 // Clear V and C - beqz $s3, 3f - move $v0, $t7 - andi $s3, $s3, \nbits-1 - bnez $s3, 2f -1: // count != 0 && count % nbits == 0 - andi $a3, $t7, 1 // Branch delay slot from above (this is safe) - j 3f - ins $s5, $a3, SR_C_SHIFT, 1 -2: // count % nbits != 0 - li $v1, \nbits - sub $v1, $v1, $s3 - sllv $a0, $t7, $s3 - srlv $t0, $t7, $v1 - or $v0, $a0, $t0 - andi $a3, $t7, 1 - ins $s5, $a3, SR_C_SHIFT, 1 -3: // All cases -.endm - -DEFLABEL(ROL_B) - andi $t7, $t7, 0xFF - DEF_ROL 8 - SETCC_NZ_B $v0 -DEFSIZE(ROL_B) - -DEFLABEL(ROL_W) - andi $t7, $t7, 0xFFFF - DEF_ROL 16 - SETCC_NZ_W $v0 -DEFSIZE(ROL_W) - -DEFLABEL(ROL_L) - DEF_ROL 32 - SETCC_NZ_L $v0 -DEFSIZE(ROL_L) - -/*-----------------------------------------------------------------------*/ - -/** - * ROR_[BWL]: Evaluate op2 ROR op1. - */ -.macro DEF_ROR nbits - andi $s3, $s3, 0x3F - sll $v1, $s3, 1 - add $s2, $s2, $v1 - ins $s5, $zero, SR_C_SHIFT, 2 // Clear V and C - beqz $s3, 3f - move $v0, $t7 - andi $s3, $s3, \nbits-1 - bnez $s3, 2f -1: // count != 0 && count % nbits == 0 - ext $a3, $t7, \nbits-1, 1 // Branch delay slot from above (safe) - j 3f - ins $s5, $a3, SR_C_SHIFT, 1 -2: // count % nbits != 0 - li $v1, \nbits - sub $v1, $v1, $s3 - srlv $a0, $t7, $s3 - sllv $t0, $t7, $v1 - or $v0, $a0, $t0 - ext $a3, $t7, \nbits-1, 1 - ins $s5, $a3, SR_C_SHIFT, 1 -3: // All cases -.endm - -DEFLABEL(ROR_B) - andi $t7, $t7, 0xFF - DEF_ROR 8 - SETCC_NZ_B $v0 -DEFSIZE(ROR_B) - -DEFLABEL(ROR_W) - andi $t7, $t7, 0xFFFF - DEF_ROR 16 - SETCC_NZ_W $v0 -DEFSIZE(ROR_W) - -DEFLABEL(ROR_L) - DEF_ROR 32 - SETCC_NZ_L $v0 -DEFSIZE(ROR_L) - -/*************************************************************************/ -/******************* Conditional and branch operations *******************/ -/*************************************************************************/ - -/** - * Scc: Set the lower 8 bits of the result value to 0xFF if the condition - * is true, 0x00 if false. - */ -DEFLABEL(Scc) - negu $v0, $v1 -DEFSIZE(Scc) - -/*-----------------------------------------------------------------------*/ - -/** - * ADD_CYCLES_Scc_Dn: Add the appropriate number of clock cycles for an - * Scc Dn instruction to the cycle count. - */ -DEFLABEL(ADD_CYCLES_Scc_Dn) - andi $v1, $v0, 2 - addiu $v1, $v1, 4 - addu $s2, $s2, $v1 -DEFSIZE(ADD_CYCLES_Scc_Dn) - -/*************************************************************************/ - -/** - * DBcc: Jump to the specified target address unless the condition is true - * or the lower 16 bits of the given data register, after being decremented, - * are equal to -1. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7) - * target_hi: High 16 bits of target address - * target_lo: Low 16 bits of target address - */ -DEFLABEL(DBcc) - lhu $v0, 1($s0) -6: bnezl $v1, 0f - addiu $s2, $s2, 12 - addiu $v1, $v0, -1 - sh $v1, 1($s0) -7: beqzl $v0, 0f - addiu $s2, $s2, 14 - addiu $s2, $s2, 10 - lui $v0, 0x1234 -8: ori $s4, $v0, 0x5678 -9: TERMINATE -0: -DEFSIZE(DBcc) -DEFPARAM(DBcc, reg4, 6b, -4) -DEFPARAM(DBcc, reg4_b, 7b, -4) // same as reg4 -DEFPARAM(DBcc, target_hi, 8b, -4) -DEFPARAM(DBcc, target_lo, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * DBcc_native: Implement DBcc using a jump within the native code. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7) - * target_hi: High 16 bits of target 68000 address - * target_lo: Low 16 bits of target 68000 address - * native_disp_4_4: (Native displacement from end of this fragment + 4) / 4 - */ -DEFLABEL(DBcc_native) - lhu $v0, 1($s0) -6: bnezl $v1, 0f - addiu $s2, $s2, 12 - addiu $v1, $v0, -1 - sh $v1, 1($s0) -7: beqzl $v0, 0f - addiu $s2, $s2, 14 - addiu $s2, $s2, 10 - lui $v0, 0x1234 -8: ori $s4, $v0, 0x5678 -9: b .+0x1234 -5: nop -0: -DEFSIZE(DBcc_native) -DEFPARAM(DBcc_native, reg4, 6b, -4) -DEFPARAM(DBcc_native, reg4_b, 7b, -4) // same as reg4 -DEFPARAM(DBcc_native, target_hi, 8b, -4) -DEFPARAM(DBcc_native, target_lo, 9b, -4) -DEFPARAM(DBcc_native, native_disp_4_4, 5b, -4) - -/*************************************************************************/ - -/** - * Bcc_common: Jump to the specified target address if the condition is - * true. Used for both interpreted jumps (by branching to TERMINATE) and - * native jumps. - * - * [Parameters] - * target_hi: High 16 bits of target 68000 address - * target_lo: Low 16 bits of target 68000 address - * disp_4: Native displacement / 4 (either JIT_PSPOFS_TERMINATE or - * target address minus address of "nop" following branch) - */ -DEFLABEL(Bcc_common) - beqz $v1, 0f - lui $v0, 0x1234 // In the delay slot, but not a problem -8: ori $s4, $v0, 0x5678 -9: addiu $s2, $s2, 10 - b .+0x1234 -5: nop -0: -DEFSIZE(Bcc_common) -DEFPARAM(Bcc_common, target_hi, 8b, -4) -DEFPARAM(Bcc_common, target_lo, 9b, -4) -DEFPARAM(Bcc_common, disp_4, 5b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * BSR: Push the address of the next instruction onto the stack, then jump - * to the specified target address. - * - * [Parameters] - * return_addr_hi: High 16 bits of return address to push onto the stack - * return_addr_lo: High 16 bits of return address to push onto the stack - * target_hi: High 16 bits of target address - * target_lo: Low 16 bits of target address - */ -DEFLABEL(BSR) - lui $v0, 0x1234 -6: ori $v0, $v0, 0x5678 -7: PUSH32 $v0 - lui $v0, 0x1234 -8: ori $s4, $v0, 0x5678 -9: ori $s2, $s2, 0x8000 // Indicate that this is a BSR/JSR termination - TERMINATE_CONTINUE -DEFSIZE(BSR) -DEFPARAM(BSR, return_addr_hi, 6b, -4) -DEFPARAM(BSR, return_addr_lo, 7b, -4) -DEFPARAM(BSR, target_hi, 8b, -4) -DEFPARAM(BSR, target_lo, 9b, -4) - -/*************************************************************************/ - -/** - * JMP: Jump to the previously resolved effective address. - */ -DEFLABEL(JMP) - move $s4, $s6 - TERMINATE -DEFSIZE(JMP) - -/*-----------------------------------------------------------------------*/ - -/** - * JSR: Push the address of the next instruction onto the stack, then jump - * to the previously resolved effective address. - * - * [Parameters] - * return_addr_hi: High 16 bits of return address to push onto the stack - * return_addr_lo: High 16 bits of return address to push onto the stack - */ -DEFLABEL(JSR) - lui $v0, 0x1234 -8: ori $v0, $v0, 0x5678 -9: PUSH32 $v0 - move $s4, $s6 - ori $s2, $s2, 0x8000 // Indicate that this is a BSR/JSR termination - TERMINATE_CONTINUE -DEFSIZE(JSR) -DEFPARAM(JSR, return_addr_hi, 8b, -4) -DEFPARAM(JSR, return_addr_lo, 9b, -4) - -/*************************************************************************/ -/*********************** MOVEM-related operations ************************/ -/*************************************************************************/ - -/** - * STORE_DEC_[WL]: Decrement state->ea_addr, then store the specified - * register to the resulting location. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(STORE_DEC_W) - lw $v0, 1($s0) -9: addiu $s6, $s6, -2 - LOAD_DELAY_NOP - WRITE16 -DEFSIZE(STORE_DEC_W) -DEFPARAM(STORE_DEC_W, reg4, 9b, -4) - -DEFLABEL(STORE_DEC_L) - lw $v0, 1($s0) -9: addiu $s6, $s6, -4 - LOAD_DELAY_NOP - WRITE32 -DEFSIZE(STORE_DEC_L) -DEFPARAM(STORE_DEC_L, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * STORE_INC_[WL]: Store the specified register to the location indicated - * by state->ea_addr, then increment state->ea_addr. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(STORE_INC_W) - lw $v0, 1($s0) -9: LOAD_DELAY_NOP - LOAD_DELAY_NOP - WRITE16 - addiu $s6, $s6, 2 -DEFSIZE(STORE_INC_W) -DEFPARAM(STORE_INC_W, reg4, 9b, -4) - -DEFLABEL(STORE_INC_L) - lw $v0, 1($s0) -9: LOAD_DELAY_NOP - LOAD_DELAY_NOP - WRITE32 - addiu $s6, $s6, 4 -DEFSIZE(STORE_INC_L) -DEFPARAM(STORE_INC_L, reg4, 9b, -4) - -/*************************************************************************/ - -/** - * LOAD_INC_[WL]: Load the specified register from the location indicated - * by state->ea_addr, then increment state->ea_addr. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(LOAD_INC_W) - READ16 $v0 - sh $v0, 1($s0) -9: addiu $s6, $s6, 2 -DEFSIZE(LOAD_INC_W) -DEFPARAM(LOAD_INC_W, reg4, 9b, -4) - -DEFLABEL(LOAD_INC_L) - READ32 $v0 - sw $v0, 1($s0) -9: addiu $s6, $s6, 4 -DEFSIZE(LOAD_INC_L) -DEFPARAM(LOAD_INC_L, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * LOADA_INC_W: Load the specified address register from the location - * indicated by state->ea_addr, sign-extending the 16-bit value to 32 bits, - * then increment state->ea_addr. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(LOADA_INC_W) - READ16 $v0 - seh $v0, $v0 - sh $v0, 1($s0) -9: addiu $s6, $s6, 2 -DEFSIZE(LOADA_INC_W) -DEFPARAM(LOADA_INC_W, reg4, 9b, -4) - -/*************************************************************************/ - -/** - * MOVEM_WRITEBACK: Store the address in state->ea_addr to the specified - * address register. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(MOVEM_WRITEBACK) - sw $s6, 1($s0) -9: -DEFSIZE(MOVEM_WRITEBACK) -DEFPARAM(MOVEM_WRITEBACK, reg4, 9b, -4) - -/*************************************************************************/ -/*********************** Miscellaneous operations ************************/ -/*************************************************************************/ - -/** - * CHK_W: Raise a CHK exception if op1 < 0 or op1 > op2, treating both - * operands as signed 16-bit values. - */ -DEFLABEL(CHK_W) - seh $s3, $s3 - seh $t7, $t7 - bltzl $s3, 0f - ori $s5, $s5, SR_N - slt $v1, $t7, $s3 - beqz $v1, 1f - nop - ins $s5, $zero, SR_N_SHIFT, 1 -0: li $a0, EX_CHK - sw $a0, Q68State_exception($s0) - TERMINATE -1: -DEFSIZE(CHK_W) - -/*************************************************************************/ - -/** - * LEA: Store the previously resolved effective address in the specified - * address register. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(LEA) - sw $s6, 1($s0) -9: -DEFSIZE(LEA) -DEFPARAM(LEA, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * PEA: Push the previously resolved effective address onto the stack. - */ -DEFLABEL(PEA) - PUSH32 $s6 -DEFSIZE(PEA) - -/*************************************************************************/ - -/** - * TAS: Test the 8-bit value of op1, setting the condition codes - * appropriately, then calculate op1 | 0x80. - */ -DEFLABEL(TAS) - SETCC_NZ00_B $s3 - ori $v0, $s3, 0x80 -DEFSIZE(TAS) - -/*************************************************************************/ - -/** - * MOVE_FROM_USP: Copy the user stack pointer to the specified register. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(MOVE_FROM_USP) - lw $v0, USP - LOAD_DELAY_NOP - LOAD_DELAY_NOP - sw $v0, 1($s0) -9: -DEFSIZE(MOVE_FROM_USP) -DEFPARAM(MOVE_FROM_USP, reg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * MOVE_TO_USP: Copy the specified register to the user stack pointer. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(MOVE_TO_USP) - lw $v0, 1($s0) -9: LOAD_DELAY_NOP - LOAD_DELAY_NOP - sw $v0, USP -DEFSIZE(MOVE_TO_USP) -DEFPARAM(MOVE_TO_USP, reg4, 9b, -4) - -/*************************************************************************/ - -/** - * STOP: Halt the processor. - * - * [Parameters] - * newSR: Value to load into SR - */ -DEFLABEL(STOP) - li $v0, 1 - sw $v0, Q68State_halted($s0) - jal UPDATE_SR - ori $v0, $zero, 0x1234 -9: -DEFSIZE(STOP) -DEFPARAM(STOP, newSR, 9b, -4) - -/*************************************************************************/ - -/** - * TRAPV: Raise a TRAPV exception if the overflow flag is set. - */ -DEFLABEL(TRAPV) - ext $v1, $s5, SR_V_SHIFT, 1 - beqz $v1, 0f - li $a0, EX_TRAPV // In the delay slot, but that's okay - sw $a0, Q68State_exception($s0) - TERMINATE -0: -DEFSIZE(TRAPV) - -/*************************************************************************/ - -/** - * RTS: Pop the PC from the stack. - */ -DEFLABEL(RTS) - POP32 $s4 - ori $s2, $s2, 0xC000 // Indicate that this is an RTS/RTR termination - TERMINATE -DEFSIZE(RTS) - -/*-----------------------------------------------------------------------*/ - -/** - * RTR: Pop the condition codes and PC from the stack. - */ -DEFLABEL(RTR) - POP16 $v0 - ins $s5, $v0, 0, 8 - POP32 $s4 - ori $s2, $s2, 0xC000 // Indicate that this is an RTS/RTR termination - TERMINATE -DEFSIZE(RTR) - -/*-----------------------------------------------------------------------*/ - -/** - * RTE: Pop the status register and PC from the stack. - */ -DEFLABEL(RTE) - POP16 $s3 // Borrow op1, since POP32 will destroy temporary registers - POP32 $s4 - jal UPDATE_SR - move $v0, $s3 - TERMINATE -DEFSIZE(RTE) - -/*************************************************************************/ - -/** - * MOVEP_READ_[WL]: Read a value from memory, skipping every other byte. - * - * [Parameters] - * areg4: Register number * 4 of base address register (32-60 = A0-A7) - * disp: Displacement from base address register - * dreg4: Register number * 4 of data reg. to receive data (0-28 = D0-D7) - */ -DEFLABEL(MOVEP_READ_W) - lw $s6, 1($s0) -7: LOAD_DELAY_NOP - LOAD_DELAY_NOP - addiu $s6, $s6, 1 -8: READ8 $v0 // Byte 1 - addiu $s6, $s6, 2 - ins $s3, $v0, 8, 8 - READ8 $v0 // Byte 0 - ins $s3, $v0, 0, 8 - sh $s3, 1($s0) -9: -DEFSIZE(MOVEP_READ_W) -DEFPARAM(MOVEP_READ_W, areg4, 7b, -4) -DEFPARAM(MOVEP_READ_W, disp, 8b, -4) -DEFPARAM(MOVEP_READ_W, dreg4, 9b, -4) - -DEFLABEL(MOVEP_READ_L) - lw $s6, 1($s0) -7: LOAD_DELAY_NOP - LOAD_DELAY_NOP - addiu $s6, $s6, 1 -8: READ8 $v0 // Byte 3 - addiu $s6, $s6, 2 - ins $s3, $v0, 24, 8 - READ8 $v0 // Byte 2 - addiu $s6, $s6, 2 - ins $s3, $v0, 16, 8 - READ8 $v0 // Byte 1 - addiu $s6, $s6, 2 - ins $s3, $v0, 8, 8 - READ8 $v0 // Byte 0 - ins $s3, $v0, 0, 8 - sh $s3, 1($s0) -9: -DEFSIZE(MOVEP_READ_L) -DEFPARAM(MOVEP_READ_L, areg4, 7b, -4) -DEFPARAM(MOVEP_READ_L, disp, 8b, -4) -DEFPARAM(MOVEP_READ_L, dreg4, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * MOVEP_WRITE_[WL]: Write a value to memory, skipping every other byte. - * - * [Parameters] - * areg4: Register number * 4 of base address register (32-60 = A0-A7) - * disp: Displacement from base address register - * dreg4: Register number * 4 of data reg. containing data (0-28 = D0-D7) - */ -DEFLABEL(MOVEP_WRITE_W) - lw $s6, 1($s0) -7: lw $s3, 1($s0) -9: LOAD_DELAY_NOP - addiu $s6, $s6, 1 -8: ext $v0, $s3, 8, 8 - WRITE8 // Byte 1 - addiu $s6, $s6, 2 - ext $v0, $s3, 0, 8 - WRITE8 // Byte 0 -DEFSIZE(MOVEP_WRITE_W) -DEFPARAM(MOVEP_WRITE_W, areg4, 7b, -4) -DEFPARAM(MOVEP_WRITE_W, disp, 8b, -4) -DEFPARAM(MOVEP_WRITE_W, dreg4, 9b, -4) - -DEFLABEL(MOVEP_WRITE_L) - lw $s6, 1($s0) -7: lw $s3, 1($s0) -9: LOAD_DELAY_NOP - addiu $s6, $s6, 1 -8: ext $v0, $s3, 24, 8 - WRITE8 // Byte 3 - addiu $s6, $s6, 2 - ext $v0, $s3, 16, 8 - WRITE8 // Byte 2 - addiu $s6, $s6, 2 - ext $v0, $s3, 8, 8 - WRITE8 // Byte 1 - addiu $s6, $s6, 2 - ext $v0, $s3, 0, 8 - WRITE8 // Byte 0 -DEFSIZE(MOVEP_WRITE_L) -DEFPARAM(MOVEP_WRITE_L, areg4, 7b, -4) -DEFPARAM(MOVEP_WRITE_L, disp, 8b, -4) -DEFPARAM(MOVEP_WRITE_L, dreg4, 9b, -4) - -/*************************************************************************/ - -/** - * EXG: Exchange the values of two registers. - * - * [Parameters] - * reg1_4: Register number * 4 of first register (0-60 = D0-A7) - * reg2_4: Register number * 4 of second register (0-60 = D0-A7) - */ -DEFLABEL(EXG) - addiu $a0, $s0, 1 -8: lw $v0, 0($a0) - addiu $a1, $s0, 1 -9: lw $v1, 0($a1) - sw $v0, 0($a1) - LOAD_DELAY_NOP - sw $v1, 0($a0) -DEFSIZE(EXG) -DEFPARAM(EXG, reg1_4, 8b, -1) -DEFPARAM(EXG, reg2_4, 9b, -1) - -/*************************************************************************/ -/*************************************************************************/ diff --git a/yabause/src/q68/q68-jit-psp.h b/yabause/src/q68/q68-jit-psp.h deleted file mode 100644 index be580cddbe..0000000000 --- a/yabause/src/q68/q68-jit-psp.h +++ /dev/null @@ -1,593 +0,0 @@ -/* src/q68/q68-jit-psp.h: PSP dynamic translation header for Q68 - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef Q68_JIT_PSP_H -#define Q68_JIT_PSP_H - -#include - -/*************************************************************************/ - -/** - * JIT_CALL: Run translated code from the given (native) address for the - * given number of cycles. - * - * [Parameters] - * state: Processor state block - * cycles: Number of clock cycles to execute - * address_ptr: Pointer to address of native code to execute; must be - * updated on return with the next address to execute - * or NULL if the end of the block was reached - * [Return value] - * Number of clock cycles actually executed - */ -static inline int JIT_CALL(Q68State *state, int cycles, void **address_ptr) -{ - register Q68State *__state asm("s0") = state; - register int __cycles asm("s1") = cycles; - register int __cycles_out asm("s2"); - register void * __address asm("v0") = *address_ptr; - asm(".set push; .set noreorder\n" - "jalr %[address]\n" - "move $s2, $zero\n" - ".set pop" - : "=r" (__cycles), [address] "=r" (__address), "=r" (__cycles_out) - : "r" (__state), "0" (__cycles), "1" (__address) - : "at", "v1", "a0", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", - "t5", "t6", "t7", "t8", "t9", "s3", "s4", "s5", "s6", "s7", "ra", - "memory" - ); - *address_ptr = __address; - return __cycles_out; -} - -/*************************************************************************/ - -/** - * JIT_FIXUP_BRANCH: Modify a branch instruction at the given offset to - * jump to the given target. - * - * [Parameters] - * entry: Block being translated - * offset: Offset within entry->native_code of branch instruction - * (as returned in *branch_offset EMIT parameter) - * target: Target offset within entry->native_code - * [Return value] - * None - */ -static inline void JIT_FIXUP_BRANCH(Q68JitEntry *entry, uint32_t offset, - uint32_t target) -{ - int32_t disp_4 = (target - (offset + 4)) / 4; - if (disp_4 >= -32768 && disp_4 <= 32767) { - *(int16_t *)((uint8_t *)entry->native_code + offset) = disp_4; - } -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * The remaining macros are all used to insert a specific operation into - * the native code stream. For simplicity, we define the actual code for - * each operation in a separate assembly file, and use memcpy() to copy - * from the assembled code to the output code stream. The GEN_EMIT macro - * below is used to generate each of the JIT_EMIT_* functions; each - * function JIT_EMIT_xxx copies JIT_PSPSIZE_xxx bytes from JIT_PSP_xxx to - * the code stream, expanding the code buffer if necessary. - */ - -/* Sub-macros: */ -#define GEN_NAMESIZE(name) \ - extern const uint8_t JIT_PSP_##name[]; \ - extern const uint32_t JIT_PSPSIZE_##name; -#define GEN_PARAM(name,param) \ - extern const uint32_t JIT_PSPPARAM_##name##_##param; -#define GEN_FUNC_TOP(name) \ - if (UNLIKELY(entry->native_size - entry->native_length \ - < JIT_PSPSIZE_##name)) { \ - if (!expand_buffer(entry)) { \ - return; \ - } \ - } \ - if (JIT_PSPSIZE_##name > 0) { \ - memcpy((uint8_t *)entry->native_code + entry->native_length, \ - JIT_PSP_##name, JIT_PSPSIZE_##name); \ - } -#define GEN_COPY_PARAM(name,type,param) \ - *(type *)((uint8_t *)entry->native_code + entry->native_length \ - + JIT_PSPPARAM_##name##_##param) = param; -#define GEN_FUNC_BOTTOM(name) \ - entry->native_length += JIT_PSPSIZE_##name; - - -#define GEN_EMIT(name) \ - GEN_NAMESIZE(name) \ - static void JIT_EMIT_##name(Q68JitEntry *entry) { \ - GEN_FUNC_TOP(name) \ - GEN_FUNC_BOTTOM(name) \ - } - -#define GEN_EMIT_1(name,type1,param1) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_FUNC_BOTTOM(name) \ - } - -#define GEN_EMIT_2(name,type1,param1,type2,param2) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - GEN_PARAM(name,param2) \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - type2 param2) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_COPY_PARAM(name, type2, param2) \ - GEN_FUNC_BOTTOM(name) \ - } - -#define GEN_EMIT_3(name,type1,param1,type2,param2,type3,param3) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - GEN_PARAM(name,param2) \ - GEN_PARAM(name,param3) \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - type2 param2, type3 param3) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_COPY_PARAM(name, type2, param2) \ - GEN_COPY_PARAM(name, type3, param3) \ - GEN_FUNC_BOTTOM(name) \ - } - -#define GEN_EMIT_4(name,type1,param1,type2,param2,type3,param3,type4,param4) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - GEN_PARAM(name,param2) \ - GEN_PARAM(name,param3) \ - GEN_PARAM(name,param4) \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - type2 param2, type3 param3, type4 param4) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_COPY_PARAM(name, type2, param2) \ - GEN_COPY_PARAM(name, type3, param3) \ - GEN_COPY_PARAM(name, type4, param4) \ - GEN_FUNC_BOTTOM(name) \ - } - -#define GEN_EMIT_5(name,type1,param1,type2,param2,type3,param3,type4,param4,type5,param5) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - GEN_PARAM(name,param2) \ - GEN_PARAM(name,param3) \ - GEN_PARAM(name,param4) \ - GEN_PARAM(name,param5) \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - type2 param2, type3 param3, \ - type4 param4, type5 param5) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_COPY_PARAM(name, type2, param2) \ - GEN_COPY_PARAM(name, type3, param3) \ - GEN_COPY_PARAM(name, type4, param4) \ - GEN_COPY_PARAM(name, type5, param5) \ - GEN_FUNC_BOTTOM(name) \ - } - - -/* These versions include a hidden "disp_4" parameter, and pass the value of - * disp_4_formula for that parameter. */ - -#define GEN_EMIT_disp(name,disp_4_formula) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,disp_4) \ - static void __real_JIT_EMIT_##name(Q68JitEntry *entry, int16_t disp_4) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, int16_t, disp_4) \ - GEN_FUNC_BOTTOM(name) \ - } \ - static void JIT_EMIT_##name(Q68JitEntry *entry) { \ - __real_JIT_EMIT_##name(entry, (disp_4_formula)); \ - } - -#define GEN_EMIT_1_disp(name,type1,param1,disp_4_formula) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - GEN_PARAM(name,disp_4) \ - static void __real_JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - int16_t disp_4) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_COPY_PARAM(name, int16_t, disp_4) \ - GEN_FUNC_BOTTOM(name) \ - } \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1) { \ - __real_JIT_EMIT_##name(entry, param1, (disp_4_formula)); \ - } - -#define GEN_EMIT_2_disp(name,type1,param1,type2,param2,disp_4_formula) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - GEN_PARAM(name,param2) \ - GEN_PARAM(name,disp_4) \ - static void __real_JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - type2 param2, int16_t disp_4) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_COPY_PARAM(name, type2, param2) \ - GEN_COPY_PARAM(name, int16_t, disp_4) \ - GEN_FUNC_BOTTOM(name) \ - } \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - type2 param2) { \ - __real_JIT_EMIT_##name(entry, param1, param2, (disp_4_formula)); \ - } - -/*-----------------------------------------------------------------------*/ - -/* Code prologue and epilogue */ -GEN_EMIT(PROLOGUE) -extern const int JIT_PSPOFS_TERMINATE; -extern const int JIT_PSPOFS_EXCEPTION; -extern const int JIT_PSPOFS_ADDRESS_ERROR_EA; -extern const int JIT_PSPOFS_ADDRESS_ERROR_SP; -GEN_EMIT(EPILOGUE) - -#ifdef Q68_TRACE -/* Trace the current instruction */ -GEN_EMIT(TRACE) -#endif - -/* Add the specified number of cycles to the cycle counter */ -GEN_EMIT_1(ADD_CYCLES, int16_t, cycles) - -/* Check the cycle limit and interrupt execution if necessary */ -GEN_EMIT(CHECK_CYCLES) - -/* Add the specified amount to the program counter and/or check whether - * to abort */ -GEN_EMIT_1(ADVANCE_PC, int16_t, value) -GEN_EMIT_1_disp(ADVANCE_PC_CHECK_ABORT, int16_t, value, - (JIT_PSPOFS_TERMINATE - (entry->native_length + 4)) / 4) -GEN_EMIT_disp(CHECK_ABORT, - (JIT_PSPOFS_TERMINATE - (entry->native_length + 4)) / 4) - -/* Exception raising */ -GEN_EMIT_1_disp(EXCEPTION, int16_t, num, - (JIT_PSPOFS_EXCEPTION - (entry->native_length + 4)) / 4) -GEN_EMIT_2_disp(CHECK_ALIGNED_EA, uint16_t, opcode, uint16_t, status, - (JIT_PSPOFS_ADDRESS_ERROR_EA - (entry->native_length + 4)) / 4) -GEN_EMIT_2_disp(CHECK_ALIGNED_SP, uint16_t, opcode, uint16_t, status, - (JIT_PSPOFS_ADDRESS_ERROR_SP - entry->native_length) / 4) -GEN_EMIT_disp(CHECK_SUPER, - (JIT_PSPOFS_EXCEPTION - (entry->native_length + 4)) / 4) - -/*-----------------------------------------------------------------------*/ - -/* Resolve an effective address */ -GEN_EMIT_1(RESOLVE_INDIRECT, int16_t, reg4) -GEN_EMIT_3(RESOLVE_POSTINC, int16_t, reg4, int16_t, size, int16_t, reg4_b) -#define JIT_EMIT_RESOLVE_POSTINC(entry,reg4,size) do { \ - int16_t __reg4 = (reg4); \ - JIT_EMIT_RESOLVE_POSTINC((entry), __reg4, (size), __reg4); \ -} while (0) -GEN_EMIT(RESOLVE_POSTINC_A7_B) -GEN_EMIT_3(RESOLVE_PREDEC, int16_t, reg4, int16_t, nsize, int16_t, reg4_b) -#define JIT_EMIT_RESOLVE_PREDEC(entry,reg4,size) do { \ - int16_t __reg4 = (reg4); \ - JIT_EMIT_RESOLVE_PREDEC((entry), __reg4, -(size), __reg4); \ -} while (0) -GEN_EMIT(RESOLVE_PREDEC_A7_B) -GEN_EMIT_2(RESOLVE_DISP, int16_t, reg4, int16_t, disp) -GEN_EMIT_3(RESOLVE_INDEX_W, int16_t, reg4, int16_t, ireg4, int16_t, disp) -GEN_EMIT_3(RESOLVE_INDEX_L, int16_t, reg4, int16_t, ireg4, int16_t, disp) -GEN_EMIT_2(RESOLVE_ABSOLUTE, uint16_t, addr_hi, uint16_t, addr_lo) -#define JIT_EMIT_RESOLVE_ABSOLUTE(entry,addr) do { \ - uint32_t __addr = (addr); \ - JIT_EMIT_RESOLVE_ABSOLUTE((entry), __addr>>16, __addr & 0xFFFF); \ -} while (0) -GEN_EMIT_3(RESOLVE_ABS_INDEX_W, int16_t, ireg4, uint16_t, addr_hi, - uint16_t, addr_lo) -#define JIT_EMIT_RESOLVE_ABS_INDEX_W(entry,addr,ireg4) do { \ - uint32_t __addr = (addr); \ - JIT_EMIT_RESOLVE_ABS_INDEX_W((entry), (ireg4), __addr>>16, \ - (addr) & 0xFFFF); \ -} while (0) -GEN_EMIT_3(RESOLVE_ABS_INDEX_L, int16_t, ireg4, uint16_t, addr_hi, - uint16_t, addr_lo) -#define JIT_EMIT_RESOLVE_ABS_INDEX_L(entry,addr,ireg4) do { \ - uint32_t __addr = (addr); \ - JIT_EMIT_RESOLVE_ABS_INDEX_L((entry), (ireg4), __addr>>16, \ - __addr & 0xFFFF); \ -} while (0) - -/* Retrieve various things as operand 1 */ -GEN_EMIT_1(GET_OP1_REGISTER, int16_t, reg4) -GEN_EMIT(GET_OP1_EA_B) -GEN_EMIT(GET_OP1_EA_W) -GEN_EMIT(GET_OP1_EA_L) -GEN_EMIT_1(GET_OP1_IMMED_16S, int16_t, value_lo) -GEN_EMIT_1(GET_OP1_IMMED_16U, uint16_t, value_lo) -GEN_EMIT_1(GET_OP1_IMMED_16HI, uint16_t, value_hi) -GEN_EMIT_2(GET_OP1_IMMED_32, uint16_t, value_hi, uint16_t, value_lo) -#define JIT_EMIT_GET_OP1_IMMEDIATE(entry,value) do { \ - Q68JitEntry * const __entry = (entry); \ - const int32_t __value = (value); \ - if (value >= -32768 && value <= 32767) { \ - JIT_EMIT_GET_OP1_IMMED_16S(__entry, __value); \ - } else if (value >= 0 && value <= 65535) { \ - JIT_EMIT_GET_OP1_IMMED_16U(__entry, __value); \ - } else if ((value & 0xFFFF) == 0) { \ - JIT_EMIT_GET_OP1_IMMED_16HI(__entry, __value>>16); \ - } else { \ - JIT_EMIT_GET_OP1_IMMED_32(__entry, __value>>16, __value & 0xFFFF); \ - } \ -} while (0) -GEN_EMIT(GET_OP1_CCR) -GEN_EMIT(GET_OP1_SR) - -/* Retrieve various things as operand 2 */ -GEN_EMIT_1(GET_OP2_REGISTER, int16_t, reg4) -GEN_EMIT(GET_OP2_EA_B) -GEN_EMIT(GET_OP2_EA_W) -GEN_EMIT(GET_OP2_EA_L) -GEN_EMIT_1(GET_OP2_IMMED_16S, int16_t, value_lo) -GEN_EMIT_1(GET_OP2_IMMED_16U, uint16_t, value_lo) -GEN_EMIT_1(GET_OP2_IMMED_16HI, uint16_t, value_hi) -GEN_EMIT_2(GET_OP2_IMMED_32, uint16_t, value_hi, uint16_t, value_lo) -#define JIT_EMIT_GET_OP2_IMMEDIATE(entry,value) do { \ - Q68JitEntry * const __entry = (entry); \ - const int32_t __value = (value); \ - if (value >= -32768 && value <= 32767) { \ - JIT_EMIT_GET_OP2_IMMED_16S(__entry, __value); \ - } else if (value >= 0 && value <= 65535) { \ - JIT_EMIT_GET_OP2_IMMED_16U(__entry, __value); \ - } else if ((value & 0xFFFF) == 0) { \ - JIT_EMIT_GET_OP2_IMMED_16HI(__entry, __value>>16); \ - } else { \ - JIT_EMIT_GET_OP2_IMMED_32(__entry, __value>>16, __value & 0xFFFF); \ - } \ -} while (0) -GEN_EMIT(GET_OP2_CCR) -GEN_EMIT(GET_OP2_SR) - -/* Update various things from result */ -GEN_EMIT_1(SET_REGISTER_B, int16_t, reg4) -GEN_EMIT_1(SET_REGISTER_W, int16_t, reg4) -GEN_EMIT_1(SET_REGISTER_L, int16_t, reg4) -GEN_EMIT_1(SET_AREG_W, int16_t, reg4) -GEN_EMIT(SET_EA_B) -GEN_EMIT(SET_EA_W) -GEN_EMIT(SET_EA_L) -GEN_EMIT(SET_CCR) -GEN_EMIT(SET_SR) - -/* Stack operations */ -GEN_EMIT(PUSH_L) -GEN_EMIT(POP_L) - -/* Condition code setting */ -GEN_EMIT(SETCC_ADD_B) -GEN_EMIT(SETCC_ADD_W) -GEN_EMIT(SETCC_ADD_L) -GEN_EMIT(SETCC_ADDX_B) -GEN_EMIT(SETCC_ADDX_W) -GEN_EMIT(SETCC_ADDX_L) -GEN_EMIT(SETCC_SUB_B) -GEN_EMIT(SETCC_SUB_W) -GEN_EMIT(SETCC_SUB_L) -GEN_EMIT(SETCC_SUBX_B) -GEN_EMIT(SETCC_SUBX_W) -GEN_EMIT(SETCC_SUBX_L) -GEN_EMIT(SETCC_CMP_B) -GEN_EMIT(SETCC_CMP_W) -GEN_EMIT(SETCC_CMP_L) -GEN_EMIT(SETCC_LOGIC_B) -GEN_EMIT(SETCC_LOGIC_W) -GEN_EMIT(SETCC_LOGIC_L) - -/* Condition testing */ -GEN_EMIT(TEST_T) -GEN_EMIT(TEST_F) -GEN_EMIT(TEST_HI) -GEN_EMIT(TEST_LS) -GEN_EMIT(TEST_CC) -GEN_EMIT(TEST_CS) -GEN_EMIT(TEST_NE) -GEN_EMIT(TEST_EQ) -GEN_EMIT(TEST_VC) -GEN_EMIT(TEST_VS) -GEN_EMIT(TEST_PL) -GEN_EMIT(TEST_MI) -GEN_EMIT(TEST_GE) -GEN_EMIT(TEST_LT) -GEN_EMIT(TEST_GT) -GEN_EMIT(TEST_LE) - -/* ALU operations */ -GEN_EMIT(MOVE_B) -GEN_EMIT(MOVE_W) -GEN_EMIT(MOVE_L) -GEN_EMIT(ADD_B) -GEN_EMIT(ADD_W) -GEN_EMIT(ADD_L) -GEN_EMIT(ADDA_W) -GEN_EMIT(ADDX_B) -GEN_EMIT(ADDX_W) -GEN_EMIT(ADDX_L) -GEN_EMIT(SUB_B) -GEN_EMIT(SUB_W) -GEN_EMIT(SUB_L) -GEN_EMIT(SUBA_W) -GEN_EMIT(SUBX_B) -GEN_EMIT(SUBX_W) -GEN_EMIT(SUBX_L) -GEN_EMIT(MULS_W) -GEN_EMIT(MULU_W) -GEN_EMIT(DIVS_W) -GEN_EMIT(DIVU_W) -GEN_EMIT(AND_B) -GEN_EMIT(AND_W) -GEN_EMIT(AND_L) -GEN_EMIT(OR_B) -GEN_EMIT(OR_W) -GEN_EMIT(OR_L) -GEN_EMIT(EOR_B) -GEN_EMIT(EOR_W) -GEN_EMIT(EOR_L) -GEN_EMIT(EXT_W) -GEN_EMIT(EXT_L) -GEN_EMIT(SWAP) - -/* BCD operations */ -GEN_EMIT(ABCD) -GEN_EMIT(SBCD) - -/* Bit-twiddling operations */ -GEN_EMIT(BTST_B) -GEN_EMIT(BTST_L) -GEN_EMIT(BCHG) -GEN_EMIT(BCLR) -GEN_EMIT(BSET) - -/* Shift/rotate operations */ -GEN_EMIT(ASL_B) -GEN_EMIT(ASL_W) -GEN_EMIT(ASL_L) -GEN_EMIT(ASR_B) -GEN_EMIT(ASR_W) -GEN_EMIT(ASR_L) -GEN_EMIT(LSL_B) -GEN_EMIT(LSL_W) -GEN_EMIT(LSL_L) -GEN_EMIT(LSR_B) -GEN_EMIT(LSR_W) -GEN_EMIT(LSR_L) -GEN_EMIT(ROXL_B) -GEN_EMIT(ROXL_W) -GEN_EMIT(ROXL_L) -GEN_EMIT(ROXR_B) -GEN_EMIT(ROXR_W) -GEN_EMIT(ROXR_L) -GEN_EMIT(ROL_B) -GEN_EMIT(ROL_W) -GEN_EMIT(ROL_L) -GEN_EMIT(ROR_B) -GEN_EMIT(ROR_W) -GEN_EMIT(ROR_L) - -/* Conditional and branch operations ("branch_offset" parameter receives - * the native offset of the branch to update when resolving, or -1 if not - * supported) */ -GEN_EMIT(Scc) -GEN_EMIT(ADD_CYCLES_Scc_Dn) -GEN_EMIT_4(DBcc, int16_t, reg4, int16_t, reg4_b, uint16_t, target_hi, - uint16_t, target_lo) -#define JIT_EMIT_DBcc(entry,reg4,target) do { \ - int16_t __reg4 = (reg4); \ - uint32_t __target = (target); \ - JIT_EMIT_DBcc((entry), __reg4, __reg4, __target>>16, __target & 0xFFFF); \ -} while (0) -GEN_EMIT_5(DBcc_native, int16_t, reg4, int16_t, reg4_b, uint16_t, target_hi, - uint16_t, target_lo, int16_t, native_disp_4_4) -#define JIT_EMIT_DBcc_native(entry,reg4,target,offset) do { \ - Q68JitEntry *__entry = (entry); \ - int16_t __reg4 = (reg4); \ - uint32_t __target = (target); \ - int32_t __fragment_end = __entry->native_length + JIT_PSPSIZE_DBcc_native; \ - JIT_EMIT_DBcc_native(__entry, __reg4, __reg4, \ - __target>>16, __target & 0xFFFF, \ - ((offset) - __fragment_end + 4) / 4); \ -} while (0) -GEN_EMIT_3(Bcc_common, uint16_t, target_hi, uint16_t, target_lo, int16_t, disp_4) -static void JIT_EMIT_Bcc(Q68JitEntry *entry, uint32_t target, - int32_t *branch_offset) { - *branch_offset = entry->native_length + JIT_PSPPARAM_Bcc_common_disp_4; - int32_t disp_4 = (JIT_PSPOFS_TERMINATE - (*branch_offset + 4)) / 4; - JIT_EMIT_Bcc_common(entry, target>>16, target & 0xFFFF, disp_4); -} -static void JIT_EMIT_Bcc_native(Q68JitEntry *entry, uint32_t target, - int32_t offset) { - uint32_t branch_offset = - entry->native_length + JIT_PSPPARAM_Bcc_common_disp_4; - int32_t disp_4 = (offset - (branch_offset + 4)) / 4; - /* Displacement is assumed to be within range (+/-128k) */ - JIT_EMIT_Bcc_common(entry, target>>16, target & 0xFFFF, disp_4); -} -GEN_EMIT_4(BSR, uint16_t, return_addr_hi, uint16_t, return_addr_lo, - uint16_t, target_hi, uint16_t, target_lo) -#define JIT_EMIT_BSR(entry,return_addr,target) do { \ - uint32_t __return_addr = (return_addr); \ - uint32_t __target = (target); \ - JIT_EMIT_BSR((entry), __return_addr>>16, __return_addr & 0xFFFF, \ - __target>>16, __target & 0xFFFF); \ -} while (0) -GEN_EMIT(JMP) -GEN_EMIT_2(JSR, uint16_t, return_addr_hi, uint16_t, return_addr_lo) -#define JIT_EMIT_JSR(entry,return_addr) do { \ - uint32_t __return_addr = (return_addr); \ - JIT_EMIT_JSR((entry), __return_addr>>16, __return_addr & 0xFFFF); \ -} while (0) - -/* MOVEM-related operations */ -GEN_EMIT_1(STORE_DEC_W, int16_t, reg4) -GEN_EMIT_1(STORE_DEC_L, int16_t, reg4) -GEN_EMIT_1(STORE_INC_W, int16_t, reg4) -GEN_EMIT_1(STORE_INC_L, int16_t, reg4) -GEN_EMIT_1(LOAD_INC_W, int16_t, reg4) -GEN_EMIT_1(LOAD_INC_L, int16_t, reg4) -GEN_EMIT_1(LOADA_INC_W, int16_t, reg4) -GEN_EMIT_1(MOVEM_WRITEBACK, int16_t, reg4) - -/* Miscellaneous operations */ -GEN_EMIT(CHK_W) -GEN_EMIT_1(LEA, int16_t, reg4) -GEN_EMIT(PEA) -GEN_EMIT(TAS) -GEN_EMIT_1(MOVE_FROM_USP, int16_t, reg4) -GEN_EMIT_1(MOVE_TO_USP, int16_t, reg4) -GEN_EMIT_1(STOP, uint16_t, newSR) -GEN_EMIT(TRAPV) -GEN_EMIT(RTS) -GEN_EMIT(RTR) -GEN_EMIT(RTE) -GEN_EMIT_3(MOVEP_READ_W, int16_t, areg4, int16_t, disp, int16_t, dreg4) -GEN_EMIT_3(MOVEP_READ_L, int16_t, areg4, int16_t, disp, int16_t, dreg4) -GEN_EMIT_3(MOVEP_WRITE_W, int16_t, areg4, int16_t, disp, int16_t, dreg4) -GEN_EMIT_3(MOVEP_WRITE_L, int16_t, areg4, int16_t, disp, int16_t, dreg4) -GEN_EMIT_2(EXG, int16_t, reg1_4, int16_t, reg2_4) - -/*************************************************************************/ - -#endif // Q68_JIT_PSP_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68-jit-x86.S b/yabause/src/q68/q68-jit-x86.S deleted file mode 100644 index d6331dbf20..0000000000 --- a/yabause/src/q68/q68-jit-x86.S +++ /dev/null @@ -1,2800 +0,0 @@ -/* src/q68/q68-jit-x86.S: x86 (32/64-bit) dynamic translation implementation - for Q68 - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "q68-const.h" - -/*************************************************************************/ - -/* - * Register usage on x86 and x64 is as follows (for x86, read %rXX as %eXX): - * - * %rax -- result, temporary - * %rbx -- Q68State structure pointer - * %rcx -- temporary - * %rdx -- operand 2 - * %rsi -- cumulative cycle count - * %rdi -- operand 1, (on termination) pointer to next address to execute - * - * Additionally, the cycle limit is pushed onto the stack at the start of - * execution. - */ - -/*************************************************************************/ - -/* Define handy macros so we can use the same source on both x86 and x64 */ - -#ifdef CPU_X64 - -/* External routine calling macros (indirect calls only) */ -.macro CALL1 address, arg1 - push %rsi - push %rdi - mov \arg1, %rdi - call \address - pop %rdi - pop %rsi -.endm -.macro CALL2 address, arg1, arg2 - push %rsi - push %rdi - mov \arg1, %rdi - mov \arg2, %rsi - call \address - pop %rdi - pop %rsi -.endm - -/* Label/size/parameter definition macros */ -#define DEFLABEL(name) .globl JIT_X64_##name; JIT_X64_##name: -#define DEFSIZE(name) .globl JIT_X64SIZE_##name; \ - JIT_X64SIZE_##name: .int . - JIT_X64_##name -#define DEFPARAM(name,param,label,offset) \ - .globl JIT_X64PARAM_##name##_##param; \ - JIT_X64PARAM_##name##_##param: \ - .int label - JIT_X64_##name + (offset) - -/* Q68State structure offsets */ -Q68State_D = 0 -Q68State_A = 32 -Q68State_PC = 64 -Q68State_SR = 68 -Q68State_USP = 72 -Q68State_SSP = 76 -Q68State_current_PC = 80 -Q68State_ea_addr = 84 -Q68State_exception = 88 -Q68State_fault_addr = 92 -Q68State_fault_opcode = 96 -Q68State_fault_status = 98 -Q68State_halted = 100 -Q68State_irq = 104 -Q68State_cycles = 108 -Q68State_malloc_func = 112 -Q68State_realloc_func = 120 -Q68State_free_func = 128 -Q68State_readb_func = 136 -Q68State_readw_func = 144 -Q68State_writeb_func = 152 -Q68State_writew_func = 160 -Q68State_jit_flush = 168 -Q68State_jit_running = 176 -Q68State_jit_abort = 184 -Q68State_jit_table = 192 -Q68State_jit_hashchain = 200 -Q68State_jit_total_data = 208 -Q68State_jit_timestamp = 212 -Q68State_jit_blacklist = 216 -Q68State_jit_in_blist = Q68State_jit_blacklist + (12 * Q68_JIT_BLACKLIST_SIZE) -Q68State_jit_blist_num = Q68State_jit_in_blist + 4 -Q68State_jit_callstack_top = Q68State_jit_blist_num + 4 -Q68State_jit_callstack = (Q68State_jit_callstack_top + 7) & ~7 -Q68State_jit_pages = Q68State_jit_callstack + (24 * Q68_JIT_CALLSTACK_SIZE) - -#else // CPU_X86 - -/* Register name translation macros (we don't handle any 64-bit data except - * when protected by #ifdef CPU_X64, so this is safe) */ -#define rax eax -#define rbx ebx -#define rcx ecx -#define rdx edx -#define rsp esp -#define rbp ebp -#define rsi esi -#define rdi edi - -/* External routine calling macros (indirect calls only) */ -.macro CALL1 address, arg1 - push \arg1 - call \address - pop %rcx -.endm -.macro CALL2 address, arg1, arg2 - push \arg2 - push \arg1 - call \address - pop %rcx - pop %rcx -.endm - -/* Label/size/parameter definition macros */ -#define DEFLABEL(name) .globl JIT_X86_##name; JIT_X86_##name: -#define DEFSIZE(name) .globl JIT_X86SIZE_##name; \ - JIT_X86SIZE_##name: .int . - JIT_X86_##name -#define DEFPARAM(name,param,label,offset) \ - .globl JIT_X86PARAM_##name##_##param; \ - JIT_X86PARAM_##name##_##param: \ - .int label - JIT_X86_##name + (offset) - -/* Q68State structure offsets */ -Q68State_D = 0 -Q68State_A = 32 -Q68State_PC = 64 -Q68State_SR = 68 -Q68State_USP = 72 -Q68State_SSP = 76 -Q68State_current_PC = 80 -Q68State_ea_addr = 84 -Q68State_exception = 88 -Q68State_fault_addr = 92 -Q68State_fault_opcode = 96 -Q68State_fault_status = 98 -Q68State_halted = 100 -Q68State_irq = 104 -Q68State_cycles = 108 -Q68State_malloc_func = 112 -Q68State_realloc_func = 116 -Q68State_free_func = 120 -Q68State_readb_func = 124 -Q68State_readw_func = 128 -Q68State_writeb_func = 132 -Q68State_writew_func = 136 -Q68State_jit_flush = 140 -Q68State_jit_running = 144 -Q68State_jit_abort = 148 -Q68State_jit_table = 152 -Q68State_jit_hashchain = 156 -Q68State_jit_total_data = 160 -Q68State_jit_timestamp = 164 -Q68State_jit_blacklist = 168 -Q68State_jit_in_blist = Q68State_jit_blacklist + (12 * Q68_JIT_BLACKLIST_SIZE) -Q68State_jit_blist_num = Q68State_jit_in_blist + 4 -Q68State_jit_callstack_top = Q68State_jit_blist_num + 4 -Q68State_jit_callstack = Q68State_jit_callstack_top + 4 -Q68State_jit_pages = Q68State_jit_callstack + (12 * Q68_JIT_CALLSTACK_SIZE) - -#endif // X64/X86 - -/*************************************************************************/ - -/* Shorthand for referencing Q68State fields */ - -#define D0 Q68State_D+0*4(%rbx) -#define D1 Q68State_D+1*4(%rbx) -#define D2 Q68State_D+2*4(%rbx) -#define D3 Q68State_D+3*4(%rbx) -#define D4 Q68State_D+4*4(%rbx) -#define D5 Q68State_D+5*4(%rbx) -#define D6 Q68State_D+6*4(%rbx) -#define D7 Q68State_D+7*4(%rbx) - -#define A0 Q68State_A+0*4(%rbx) -#define A1 Q68State_A+1*4(%rbx) -#define A2 Q68State_A+2*4(%rbx) -#define A3 Q68State_A+3*4(%rbx) -#define A4 Q68State_A+4*4(%rbx) -#define A5 Q68State_A+5*4(%rbx) -#define A6 Q68State_A+6*4(%rbx) -#define A7 Q68State_A+7*4(%rbx) - -#define PC Q68State_PC(%rbx) -#define SR Q68State_SR(%rbx) -#define USP Q68State_USP(%rbx) -#define SSP Q68State_SSP(%rbx) - -/*************************************************************************/ -/************************** Convenience macros ***************************/ -/*************************************************************************/ - -/** - * READ{8,16,32}: Read a value from memory. The value read is returned - * zero-extended in %eax; the address parameter is destroyed. %rdx may not - * be used as a parameter. - */ -.macro READ8 address - and $0x00FFFFFF, \address - mov Q68State_readb_func(%rbx), %rdx - CALL1 *%rdx, \address - movzx %al, %eax -.endm - -.macro READ16 address - and $0x00FFFFFF, \address - mov Q68State_readw_func(%rbx), %rdx - CALL1 *%rdx, \address - movzx %ax, %eax -.endm - -.macro READ32 address - and $0x00FFFFFF, \address - mov Q68State_readw_func(%rbx), %rdx -#ifdef CPU_X64 - push %rdi - mov \address, %rdi - call *%rdx - push %rax - add $2, %rdi - and $0x00FFFFFF, %rdi - mov Q68State_readw_func(%rbx), %rdx - call *%rdx - pop %rcx - pop %rdi -#else - push \address - call *%rdx - xchg %rax, (%rsp) - addl $2, %rax - push %rax - mov Q68State_readw_func(%rbx), %rdx - call *%rdx - pop %rcx - pop %rcx -#endif - shl $16, %ecx - or %ecx, %eax -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * WRITE_CHECK_JIT: Check whether a write of size \nbytes (*bytes*, not - * bits) to \address would clobber a page containing already-translated - * blocks, and clear those translations if so. The value of \address is - * preserved, but all other caller-saved registers are destroyed. - * - * Note that this macro uses local label 4. - */ -.macro WRITE_CHECK_JIT address, nbytes - push \address - mov \address, %rdx - shr $Q68_JIT_PAGE_BITS+3, %rdx - mov \address, %rcx - shr $Q68_JIT_PAGE_BITS, %rcx - and $7, %cl - mov $1, %al - shl %cl, %al - test %al, Q68State_jit_pages(%rbx,%rdx,1) - jz 4f - /* Have to use an indirect call because the offset for the call - * instruction will change based on where this code is copied */ - mov (%rsp), \address -#ifdef CPU_X64 - mov $q68_jit_clear_write, %r8 - mov $\nbytes, %edx - CALL2 *%r8, %rbx, \address -#else - mov $q68_jit_clear_write, %edx - pushl $\nbytes - CALL2 *%edx, %ebx, \address - pop %ecx -#endif -4: pop \address -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * WRITE{8,16,32}: Write a value to memory. %rdx may not be used as a - * parameter; the address parameter is destroyed. - */ -.macro WRITE8 address, value - and $0x00FFFFFF, \address - push \value - WRITE_CHECK_JIT \address, 1 - pop \value - mov Q68State_writeb_func(%rbx), %rdx - CALL2 *%rdx, \address, \value -.endm - -.macro WRITE16 address, value - and $0x00FFFFFF, \address - push \value - WRITE_CHECK_JIT \address, 2 - pop \value - mov Q68State_writew_func(%rbx), %rdx - CALL2 *%rdx, \address, \value -.endm - -.macro WRITE32 address, value - push \value - push \address - shr $16, \value - WRITE16 \address, \value - pop \address - pop \value - add $2, \address - WRITE16 \address, \value -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * {PUSH,POP}{16,32}: Push or pop values onto or off of the stack. For - * POP, the value popped is zero-extended and returned in %rax; for PUSH, - * register %rax is destroyed before storing. %rdx may not be used as a - * parameter. - */ -.macro PUSH16 value - mov A7, %eax - sub $2, %eax - mov %eax, A7 - WRITE16 %rax, \value -.endm - -.macro PUSH32 value - mov A7, %eax - sub $4, %eax - mov %eax, A7 - WRITE32 %rax, \value -.endm - -.macro POP16 - mov A7, %eax - add $2, A7 - READ16 %rax -.endm - -.macro POP32 - mov A7, %eax - add $4, A7 - READ32 %rax -.endm - -/*************************************************************************/ - -/** - * LDC_FROM_X: Set the x86 carry flag (CF) based on the value of the - * 68000 extend flag (X). The byte register passed in \temp is destroyed. - */ -.macro LDC_FROM_X temp - mov SR, \temp - shr $5, \temp -.endm - -/*************************************************************************/ - -/** - * SETCC_NZ: Set the N and Z condition codes according to the x86 flag bits. - */ -.macro SETCC_NZ - sets %cl - setz %dl - andb $~(SR_N|SR_Z), SR - shl $SR_N_SHIFT, %cl - shl $SR_Z_SHIFT, %dl - or %cl, %dl - or %dl, SR -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_NZ00: Set the N and Z condition codes according to the x86 flag - * bits, and clear the V and C condition codes. - */ -.macro SETCC_NZ00 - sets %cl - setz %dl - andb $~(SR_N|SR_Z|SR_V|SR_C), SR - shl $SR_N_SHIFT, %cl - shl $SR_Z_SHIFT, %dl - or %cl, %dl - or %dl, SR -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_NZVC: Set the N, Z, V, and C condition codes according to the x86 - * flag bits. - */ -.macro SETCC_NZVC - sets %cl - setz %dl - seto %ch - setc %dh - andb $~(SR_N|SR_Z|SR_V|SR_C), SR - shl $SR_N_SHIFT, %cl - shl $SR_Z_SHIFT, %dl - shl $SR_V_SHIFT, %ch - //shl $SR_C_SHIFT, %dh // SR_C_SHIFT is zero, so skip the shift - or %ch, %cl - or %dh, %dl - or %cl, %dl - or %dl, SR -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_XNZVC: Set the N, Z, V, and C condition codes according to the - * x86 flag bits, and sets the X condition code equal to C. - */ -.macro SETCC_XNZVC - sets %cl - setz %dl - seto %ch - setc %dh - andb $~(SR_X|SR_N|SR_Z|SR_V|SR_C), SR - shl $SR_N_SHIFT, %cl - shl $SR_Z_SHIFT, %dl - shl $SR_V_SHIFT, %ch - //shl $SR_C_SHIFT, %dh // SR_C_SHIFT is zero, so skip the shift - or %ch, %cl - or %dh, %dl - shl $(SR_X_SHIFT - SR_C_SHIFT), %dh - or %dh, %dl - or %cl, %dl - or %dl, SR -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * SETCC_XNVC_Z: Set the N, V, and C condition codes according to the x86 - * flag bits; clears the Z condition code if the x86 Z flag is clear, and - * sets the X condition code equal to C. - */ -.macro SETCC_XNVC_Z - sets %cl - setnz %dl - seto %ch - setc %dh - andb $~(SR_X|SR_N|SR_V|SR_C), SR - shl $SR_N_SHIFT, %cl - shl $SR_Z_SHIFT, %dl - shl $SR_V_SHIFT, %ch - //shl $SR_C_SHIFT, %dh // SR_C_SHIFT is zero, so skip the shift - or %ch, %cl - or %dh, %cl - shl $(SR_X_SHIFT - SR_C_SHIFT), %dh - or %dh, %cl - or %cl, SR - not %dl - and %dl, SR -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * UPDATE_SR: Set the status register and condition codes according to - * the value in %ax. - * - * Note that this macro uses local labels 0, 1, 2, and 3. - */ -.macro UPDATE_SR value - movzwl %ax, %ecx - xor SR, %eax - mov %ecx, SR - test $SR_S, %eax // Change in S bit? - jz 1f - test $SR_S, %ecx // Which way did it change? - jz 0f - mov A7, %eax // Into supervisor mode - mov %eax, USP - mov SSP, %eax - mov %eax, A7 - jmp 1f -0: mov A7, %eax // Out of supervisor mode - mov %eax, SSP - mov USP, %eax - mov %eax, A7 -1: mov Q68State_irq(%rbx), %al - and $7, %al - cmp $7, %al - je 2f - and $7, %ch - cmp %al, %ch - jae 3f -2: movzx %al, %eax - add $EX_LEVEL_1_INTERRUPT-1, %eax - mov %eax, Q68State_exception(%rbx) - movl $0, Q68State_irq(%rbx) - TERMINATE -3: -.endm - -/*************************************************************************/ - -/** - * SETUP: Perform setup required before executing translated code. - */ -.macro SETUP - push %rsi - xor %esi, %esi -.endm - -/*-----------------------------------------------------------------------*/ - -/** - * TERMINATE: Terminate execution of the current block. The emulator will - * resume execution at the address in state->PC. - */ -.macro TERMINATE - pop %rax - xor %rdi, %rdi - ret -.endm - -/*************************************************************************/ -/**************************** Meta-operations ****************************/ -/*************************************************************************/ - -/** - * PROLOGUE: Any prologue necessary at the beginning of the code stream. - */ -DEFLABEL(PROLOGUE) - SETUP -DEFSIZE(PROLOGUE) - -/*-----------------------------------------------------------------------*/ - -/** - * EPILOGUE: Any epilogue necessary at the end of the code stream. - */ -DEFLABEL(EPILOGUE) - TERMINATE -DEFSIZE(EPILOGUE) - -/*************************************************************************/ - -/** - * TRACE: Trace the current instruction. - */ -DEFLABEL(TRACE) - mov Q68State_cycles(%rbx), %eax - push %rax - add %esi, %eax - mov %eax, Q68State_cycles(%rbx) -#ifdef CPU_X64 - push %rsi - push %rdi -#endif - mov $q68_trace, %rdx - call *%rdx -#ifdef CPU_X64 - pop %rdi - pop %rsi -#endif - pop %rax - mov %eax, Q68State_cycles(%rbx) -DEFSIZE(TRACE) - -/*************************************************************************/ - -/** - * ADD_CYCLES: Add the specified number of clock cycles to the cycle count. - * - * [Parameters] - * cycles: Number of clock cycles to add - */ -DEFLABEL(ADD_CYCLES) - add $0x12345678, %esi -9: -DEFSIZE(ADD_CYCLES) -DEFPARAM(ADD_CYCLES, cycles, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_CYCLES: Check whether the clock cycle limit has been reached, and - * interrupt execution if so. - */ -DEFLABEL(CHECK_CYCLES) - cmp %esi, (%rsp) - ja 4f - pop %rax - call 1f -0: jmp 2f -1: mov (%rsp), %rdi - ret -2: add $3f-0b, %rdi - ret -3: SETUP -4: -DEFSIZE(CHECK_CYCLES) - -/*************************************************************************/ - -/** - * ADVANCE_PC: Add the specified value to the current program counter. - * - * [Parameters] - * value: Amount to add - */ -DEFLABEL(ADVANCE_PC) - addl $0x12345678, PC -9: -DEFSIZE(ADVANCE_PC) -DEFPARAM(ADVANCE_PC, value, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * ADVANCE_PC_CHECK_ABORT: Add the specified value to the current program - * counter, then check the jit_abort flag and abort if necessary. - * - * [Parameters] - * value: Amount to add - */ -DEFLABEL(ADVANCE_PC_CHECK_ABORT) - addl $0x12345678, PC -9: testb $1, Q68State_jit_abort(%rbx) - jz 0f - TERMINATE -0: -DEFSIZE(ADVANCE_PC_CHECK_ABORT) -DEFPARAM(ADVANCE_PC_CHECK_ABORT, value, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_ABORT: Check the jit_abort flag and abort if necessary. - */ -DEFLABEL(CHECK_ABORT) - testb $1, Q68State_jit_abort(%rbx) - jz 0f - TERMINATE -0: -DEFSIZE(CHECK_ABORT) - -/*************************************************************************/ - -/** - * EXCEPTION: Raise the specified exception. - * - * [Parameters] - * num: Exception number - */ -DEFLABEL(EXCEPTION) - movl $0x12345678, Q68State_exception(%rbx) -9: TERMINATE -DEFSIZE(EXCEPTION) -DEFPARAM(EXCEPTION, num, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_ALIGNED_EA: Check whether the previously resolved effective - * address is word-aligned (bit 0 is clear), and raise an address error - * exception if not. - * - * [Parameters] - * opcode: Instruction opcode - * status: Status word for address error exception - */ -DEFLABEL(CHECK_ALIGNED_EA) - testl $1, Q68State_ea_addr(%rbx) - jz 0f - movl $EX_ADDRESS_ERROR, Q68State_exception(%rbx) - mov Q68State_ea_addr(%rbx), %eax - mov %eax, Q68State_fault_addr(%rbx) - movw $0x1234, Q68State_fault_opcode(%rbx) -8: movw $0x1234, Q68State_fault_status(%rbx) -9: TERMINATE -0: -DEFSIZE(CHECK_ALIGNED_EA) -DEFPARAM(CHECK_ALIGNED_EA, opcode, 8b, -2) -DEFPARAM(CHECK_ALIGNED_EA, status, 9b, -2) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_ALIGNED_SP: Check whether the current stack pointer (register A7) - * is word-aligned (bit 0 is clear), and raise an address error exception - * if not. - * - * [Parameters] - * opcode: Instruction opcode - * status: Status word for address error exception - */ -DEFLABEL(CHECK_ALIGNED_SP) - testl $1, A7 - jz 0f - movl $EX_ADDRESS_ERROR, Q68State_exception(%rbx) - mov A7, %eax - mov %eax, Q68State_fault_addr(%rbx) - movw $0x1234, Q68State_fault_opcode(%rbx) -8: movw $0x1234, Q68State_fault_status(%rbx) -9: TERMINATE -0: -DEFSIZE(CHECK_ALIGNED_SP) -DEFPARAM(CHECK_ALIGNED_SP, opcode, 8b, -2) -DEFPARAM(CHECK_ALIGNED_SP, status, 9b, -2) - -/*-----------------------------------------------------------------------*/ - -/** - * CHECK_SUPER: Check whether the processor is in supervisor mode, and - * raise a privilege violation exception if not. - */ -DEFLABEL(CHECK_SUPER) - testl $SR_S, SR - jnz 0f - movl $EX_PRIVILEGE_VIOLATION, Q68State_exception(%rbx) - TERMINATE -0: -DEFSIZE(CHECK_SUPER) - -/*************************************************************************/ -/********************* Effective address resolution **********************/ -/*************************************************************************/ - -/** - * RESOLVE_INDIRECT: Resolve an address register indirect reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - */ -DEFLABEL(RESOLVE_INDIRECT) - mov 1(%rbx), %eax -9: mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_INDIRECT) -DEFPARAM(RESOLVE_INDIRECT, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_POSTINC: Resolve an address register postincrement reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - * size: Size in bytes of the reference - */ -DEFLABEL(RESOLVE_POSTINC) - lea 1(%rbx), %rcx -8: mov (%rcx), %eax - add $1, (%rcx) -9: mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_POSTINC) -DEFPARAM(RESOLVE_POSTINC, reg4, 8b, -1) -DEFPARAM(RESOLVE_POSTINC, size, 9b, -1) - -/* For byte-sized (A7)+, make sure A7 stays even */ -DEFLABEL(RESOLVE_POSTINC_A7_B) - mov A7, %ecx - lea 1(%ecx), %eax - add $2, A7 - mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_POSTINC_A7_B) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_PREDEC: Resolve an address register predecrement reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - * size: Size in bytes of the reference - */ -DEFLABEL(RESOLVE_PREDEC) - lea 1(%rbx), %rcx -8: sub $1, (%rcx) -9: mov (%rcx), %eax - mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_PREDEC) -DEFPARAM(RESOLVE_PREDEC, reg4, 8b, -1) -DEFPARAM(RESOLVE_PREDEC, size, 9b, -1) - -/* For byte-sized -(A7), make sure A7 stays even */ -DEFLABEL(RESOLVE_PREDEC_A7_B) - mov A7, %ecx - lea -1(%ecx), %eax - sub $2, A7 - mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_PREDEC_A7_B) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_DISP: Resolve an address register indirect with displacement - * reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - * disp: Displacement - */ -DEFLABEL(RESOLVE_DISP) - mov 1(%rbx), %eax -8: add $0x12345678, %eax -9: mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_DISP) -DEFPARAM(RESOLVE_DISP, reg4, 8b, -1) -DEFPARAM(RESOLVE_DISP, disp, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_INDEX_[WL]: Resolve an address register indirect with index - * reference. - * - * [Parameters] - * reg4: (8+n)*4 for register An - * ireg4: Index register number * 4 - * disp: Displacement - */ -DEFLABEL(RESOLVE_INDEX_W) - mov 1(%rbx), %eax -7: mov 1(%rbx), %ecx -8: movsx %cx, %ecx - lea 1(%eax, %ecx), %eax -9: mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_INDEX_W) -DEFPARAM(RESOLVE_INDEX_W, reg4, 7b, -1) -DEFPARAM(RESOLVE_INDEX_W, ireg4, 8b, -1) -DEFPARAM(RESOLVE_INDEX_W, disp, 9b, -1) - -DEFLABEL(RESOLVE_INDEX_L) - mov 1(%rbx), %eax -7: mov 1(%rbx), %ecx -8: lea 1(%eax, %ecx), %eax -9: mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_INDEX_L) -DEFPARAM(RESOLVE_INDEX_L, reg4, 7b, -1) -DEFPARAM(RESOLVE_INDEX_L, ireg4, 8b, -1) -DEFPARAM(RESOLVE_INDEX_L, disp, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_ABSOLUTE: Resolve an absolute short, absolute long, or - * PC-relative reference. - * - * [Parameters] - * addr: Absolute address - */ -DEFLABEL(RESOLVE_ABSOLUTE) - mov $0x12345678, %eax -9: mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_ABSOLUTE) -DEFPARAM(RESOLVE_ABSOLUTE, addr, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * RESOLVE_ABS_INDEX_[WL]: Resolve a PC-relative with index reference. - * - * [Parameters] - * addr: Absolute address - * ireg4: Index register number * 4 - */ -DEFLABEL(RESOLVE_ABS_INDEX_W) - mov $0x12345678, %eax -8: movswl 1(%rbx), %ecx -9: add %ecx, %eax - mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_ABS_INDEX_W) -DEFPARAM(RESOLVE_ABS_INDEX_W, addr, 8b, -4) -DEFPARAM(RESOLVE_ABS_INDEX_W, ireg4, 9b, -1) - -DEFLABEL(RESOLVE_ABS_INDEX_L) - mov $0x12345678, %eax -8: add 1(%rbx), %ecx -9: mov %eax, Q68State_ea_addr(%rbx) -DEFSIZE(RESOLVE_ABS_INDEX_L) -DEFPARAM(RESOLVE_ABS_INDEX_L, addr, 8b, -4) -DEFPARAM(RESOLVE_ABS_INDEX_L, ireg4, 9b, -1) - -/*************************************************************************/ -/*************************** Operand retrieval ***************************/ -/*************************************************************************/ - -/** - * GET_OP1_REGISTER: Get the current value of the given register as - * operand 1. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(GET_OP1_REGISTER) - mov 1(%rbx), %edi -9: -DEFSIZE(GET_OP1_REGISTER) -DEFPARAM(GET_OP1_REGISTER, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * GET_OP1_EA_[BWL]: Get the value pointed to by the previously resolved - * effective address as operand 1. - */ -DEFLABEL(GET_OP1_EA_B) - mov Q68State_ea_addr(%rbx), %eax - READ8 %rax - movzx %al, %edi -DEFSIZE(GET_OP1_EA_B) - -DEFLABEL(GET_OP1_EA_W) - mov Q68State_ea_addr(%rbx), %eax - READ16 %rax - movzx %ax, %edi -DEFSIZE(GET_OP1_EA_W) - -DEFLABEL(GET_OP1_EA_L) - mov Q68State_ea_addr(%rbx), %eax - READ32 %rax - mov %eax, %edi -DEFSIZE(GET_OP1_EA_L) - -/*-----------------------------------------------------------------------*/ - -/** - * GET_OP1_IMMEDIATE: Get an immediate value as operand 1. - * - * [Parameters] - * value: Immediate value - */ -DEFLABEL(GET_OP1_IMMEDIATE) - mov $0x12345678, %edi -9: -DEFSIZE(GET_OP1_IMMEDIATE) -DEFPARAM(GET_OP1_IMMEDIATE, value, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * GET_OP1_CCR: Get the current value of CCR as operand 1. - */ -DEFLABEL(GET_OP1_CCR) - movzbl SR, %edi -DEFSIZE(GET_OP1_CCR) - -/*-----------------------------------------------------------------------*/ - -/** - * GET_OP1_SR: Get the current value of SR as operand 1. - */ -DEFLABEL(GET_OP1_SR) - mov SR, %edi -DEFSIZE(GET_OP1_SR) - -/*************************************************************************/ - -/** - * GET_OP2_*: Get the same things as above as operand 2. - */ -DEFLABEL(GET_OP2_REGISTER) - mov 1(%rbx), %edx -9: -DEFSIZE(GET_OP2_REGISTER) -DEFPARAM(GET_OP2_REGISTER, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(GET_OP2_EA_B) - mov Q68State_ea_addr(%rbx), %eax - READ8 %rax - movzx %al, %edx -DEFSIZE(GET_OP2_EA_B) - -DEFLABEL(GET_OP2_EA_W) - mov Q68State_ea_addr(%rbx), %eax - READ16 %rax - movzx %ax, %edx -DEFSIZE(GET_OP2_EA_W) - -DEFLABEL(GET_OP2_EA_L) - mov Q68State_ea_addr(%rbx), %eax - READ32 %rax - mov %eax, %edx -DEFSIZE(GET_OP2_EA_L) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(GET_OP2_IMMEDIATE) - mov $0x12345678, %edx -9: -DEFSIZE(GET_OP2_IMMEDIATE) -DEFPARAM(GET_OP2_IMMEDIATE, value, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(GET_OP2_CCR) - movzbl SR, %edx -DEFSIZE(GET_OP2_CCR) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(GET_OP2_SR) - mov SR, %edx -DEFSIZE(GET_OP2_SR) - -/*************************************************************************/ -/**************************** Result storing *****************************/ -/*************************************************************************/ - -/** - * SET_REGISTER_[BWL]: Set the value of the given register to the result - * value. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(SET_REGISTER_B) - mov %al, 1(%rbx) -9: -DEFSIZE(SET_REGISTER_B) -DEFPARAM(SET_REGISTER_B, reg4, 9b, -1) - -DEFLABEL(SET_REGISTER_W) - mov %ax, 1(%rbx) -9: -DEFSIZE(SET_REGISTER_W) -DEFPARAM(SET_REGISTER_W, reg4, 9b, -1) - -DEFLABEL(SET_REGISTER_L) - mov %eax, 1(%rbx) -9: -DEFSIZE(SET_REGISTER_L) -DEFPARAM(SET_REGISTER_L, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * SET_AREG_W: Set the value of the given address register to the - * sign-extended result value. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(SET_AREG_W) - cwde - mov %eax, 1(%rbx) -9: -DEFSIZE(SET_AREG_W) -DEFPARAM(SET_AREG_W, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * SET_EA_[BWL]: Set the value pointed to by the previously resolved - * effective address to the result value. - */ -DEFLABEL(SET_EA_B) - mov Q68State_ea_addr(%rbx), %ecx - WRITE8 %rcx, %rax -DEFSIZE(SET_EA_B) - -DEFLABEL(SET_EA_W) - mov Q68State_ea_addr(%rbx), %ecx - WRITE16 %rcx, %rax -DEFSIZE(SET_EA_W) - -DEFLABEL(SET_EA_L) - mov Q68State_ea_addr(%rbx), %ecx - WRITE32 %rcx, %rax -DEFSIZE(SET_EA_L) - -/*-----------------------------------------------------------------------*/ - -/** - * SET_CCR: Set the condition codes from the result value. - */ -DEFLABEL(SET_CCR) - mov %al, SR // Update low byte only -DEFSIZE(SET_CCR) - -/*-----------------------------------------------------------------------*/ - -/** - * SET_SR: Set the status register from the result value. - */ -DEFLABEL(SET_SR) - UPDATE_SR -DEFSIZE(SET_SR) - -/*************************************************************************/ -/*************************** Stack operations ****************************/ -/*************************************************************************/ - -/** - * PUSH_L: Push the 32-bit value of operand 1 onto the stack. - */ -DEFLABEL(PUSH_L) - PUSH32 %rdi -DEFSIZE(PUSH_L) - -/*-----------------------------------------------------------------------*/ - -/** - * POP_L: Pop a 32-bit value off the stack into the result register. - */ -DEFLABEL(POP_L) - POP32 -DEFSIZE(POP_L) - -/*************************************************************************/ -/************************ Condition code setting *************************/ -/*************************************************************************/ - -/** - * SETCC_ADD_[BWL]: Set the condition codes for the result of an ADD - * instruction stored in the result register. - */ -DEFLABEL(SETCC_ADD_B) - SETCC_XNZVC -DEFSIZE(SETCC_ADD_B) - -DEFLABEL(SETCC_ADD_W) - SETCC_XNZVC -DEFSIZE(SETCC_ADD_W) - -DEFLABEL(SETCC_ADD_L) - SETCC_XNZVC -DEFSIZE(SETCC_ADD_L) - -/*************************************************************************/ - -/** - * SETCC_ADDX_[BWL]: Set the condition codes for the result of an ADDX - * instruction stored in the result register. - */ -DEFLABEL(SETCC_ADDX_B) - SETCC_XNVC_Z -DEFSIZE(SETCC_ADDX_B) - -DEFLABEL(SETCC_ADDX_W) - SETCC_XNVC_Z -DEFSIZE(SETCC_ADDX_W) - -DEFLABEL(SETCC_ADDX_L) - SETCC_XNVC_Z -DEFSIZE(SETCC_ADDX_L) - -/*************************************************************************/ - -/** - * SETCC_SUB_[BWL]: Set the condition codes for the result of a SUB - * instruction stored in the result register. - */ -DEFLABEL(SETCC_SUB_B) - SETCC_XNZVC -DEFSIZE(SETCC_SUB_B) - -DEFLABEL(SETCC_SUB_W) - SETCC_XNZVC -DEFSIZE(SETCC_SUB_W) - -DEFLABEL(SETCC_SUB_L) - SETCC_XNZVC -DEFSIZE(SETCC_SUB_L) - -/*************************************************************************/ - -/** - * SETCC_SUBX_[BWL]: Set the condition codes for the result of a SUBX - * instruction stored in the result register. - */ -DEFLABEL(SETCC_SUBX_B) - SETCC_XNVC_Z -DEFSIZE(SETCC_SUBX_B) - -DEFLABEL(SETCC_SUBX_W) - SETCC_XNVC_Z -DEFSIZE(SETCC_SUBX_W) - -DEFLABEL(SETCC_SUBX_L) - SETCC_XNVC_Z -DEFSIZE(SETCC_SUBX_L) - -/*************************************************************************/ - -/** - * SETCC_CMP_[BWL]: Set the condition codes for the result of a CMP - * instruction stored in the result register. The X flag is unmodified. - */ -DEFLABEL(SETCC_CMP_B) - SETCC_NZVC -DEFSIZE(SETCC_CMP_B) - -DEFLABEL(SETCC_CMP_W) - SETCC_NZVC -DEFSIZE(SETCC_CMP_W) - -DEFLABEL(SETCC_CMP_L) - SETCC_NZVC -DEFSIZE(SETCC_CMP_L) - -/*************************************************************************/ - -/** - * SETCC_LOGIC_[BWL]: Set the condition codes for the result of a logical - * instruction (MOVE, AND, OR, EOR) stored in the result register. The X - * flag is unmodified. - */ -DEFLABEL(SETCC_LOGIC_B) - SETCC_NZ00 -DEFSIZE(SETCC_LOGIC_B) - -DEFLABEL(SETCC_LOGIC_W) - SETCC_NZ00 -DEFSIZE(SETCC_LOGIC_W) - -DEFLABEL(SETCC_LOGIC_L) - SETCC_NZ00 -DEFSIZE(SETCC_LOGIC_L) - -/*************************************************************************/ -/*************************** Condition testing ***************************/ -/*************************************************************************/ - -/** - * TEST_*: Check whether a condition is true (based on the current - * condition codes) and set %al based on the result (nonzero = true). - */ - -DEFLABEL(TEST_T) - mov $1, %al -DEFSIZE(TEST_T) - -DEFLABEL(TEST_F) - mov $0, %al -DEFSIZE(TEST_F) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_HI) - mov SR, %al - mov %al, %cl - shr $SR_Z_SHIFT, %cl - or %cl, %al - and $1, %al - xor $1, %al -DEFSIZE(TEST_HI) - -DEFLABEL(TEST_LS) - mov SR, %al - mov %al, %cl - shr $SR_Z_SHIFT, %cl - or %cl, %al - and $1, %al -DEFSIZE(TEST_LS) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_CC) - mov SR, %al - and $1, %al - xor $1, %al -DEFSIZE(TEST_CC) - -DEFLABEL(TEST_CS) - mov SR, %al - and $1, %al -DEFSIZE(TEST_CS) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_NE) - mov SR, %al - shr $SR_Z_SHIFT, %al - and $1, %al - xor $1, %al -DEFSIZE(TEST_NE) - -DEFLABEL(TEST_EQ) - mov SR, %al - shr $SR_Z_SHIFT, %al - and $1, %al -DEFSIZE(TEST_EQ) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_VC) - mov SR, %al - shr $SR_V_SHIFT, %al - and $1, %al - xor $1, %al -DEFSIZE(TEST_VC) - -DEFLABEL(TEST_VS) - mov SR, %al - shr $SR_V_SHIFT, %al - and $1, %al -DEFSIZE(TEST_VS) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_PL) - mov SR, %al - shr $SR_N_SHIFT, %al - and $1, %al - xor $1, %al -DEFSIZE(TEST_PL) - -DEFLABEL(TEST_MI) - mov SR, %al - shr $SR_N_SHIFT, %al - and $1, %al -DEFSIZE(TEST_MI) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_GE) - mov SR, %al - mov %al, %cl - shr $SR_N_SHIFT, %al - shr $SR_V_SHIFT, %cl - xor %cl, %al - and $1, %al - xor $1, %al -DEFSIZE(TEST_GE) - -DEFLABEL(TEST_LT) - mov SR, %al - mov %al, %cl - shr $SR_N_SHIFT, %al - shr $SR_V_SHIFT, %cl - xor %cl, %al - and $1, %al -DEFSIZE(TEST_LT) - -/*-----------------------------------------------------------------------*/ - -DEFLABEL(TEST_GT) - mov SR, %al - push %rax - mov %al, %cl - shr $SR_N_SHIFT, %al - shr $SR_V_SHIFT, %cl - xor %al, %cl - pop %rax - shr $SR_Z_SHIFT, %al - or %cl, %al - and $1, %al - xor $1, %al -DEFSIZE(TEST_GT) - -DEFLABEL(TEST_LE) - mov SR, %al - push %rax - mov %al, %cl - shr $SR_N_SHIFT, %al - shr $SR_V_SHIFT, %cl - xor %al, %cl - pop %rax - shr $SR_Z_SHIFT, %al - or %cl, %al - and $1, %al -DEFSIZE(TEST_LE) - -/*************************************************************************/ -/**************************** ALU operations *****************************/ -/*************************************************************************/ - -/** - * MOVE_[BWL]: Evaluate op1, setting the result value for the MOVE - * instruction. - */ -DEFLABEL(MOVE_B) - mov %edi, %eax - test %al, %al -DEFSIZE(MOVE_B) - -DEFLABEL(MOVE_W) - mov %edi, %eax - test %ax, %ax -DEFSIZE(MOVE_W) - -DEFLABEL(MOVE_L) - mov %edi, %eax - test %eax, %eax -DEFSIZE(MOVE_L) - -/*************************************************************************/ - -/** - * ADD_[BWL]: Evaluate op2 + op1. - */ -DEFLABEL(ADD_B) - mov %edi, %eax - add %dl, %al -DEFSIZE(ADD_B) - -DEFLABEL(ADD_W) - mov %edi, %eax - add %dx, %ax -DEFSIZE(ADD_W) - -DEFLABEL(ADD_L) - mov %edi, %eax - add %edx, %eax -DEFSIZE(ADD_L) - -/*-----------------------------------------------------------------------*/ - -/** - * ADDA_W: Sign-extend op1 to 32 bits, then evaluate op2 + op1. - */ -DEFLABEL(ADDA_W) - movsx %di, %edi - mov %edi, %eax - add %edx, %eax -DEFSIZE(ADDA_W) - -/*-----------------------------------------------------------------------*/ - -/** - * ADDX_[BWL]: Evaluate op2 + op1 + X. - */ -DEFLABEL(ADDX_B) - LDC_FROM_X %al - mov %edi, %eax - adc %dl, %al -DEFSIZE(ADDX_B) - -DEFLABEL(ADDX_W) - LDC_FROM_X %al - mov %edi, %eax - adc %dx, %ax -DEFSIZE(ADDX_W) - -DEFLABEL(ADDX_L) - LDC_FROM_X %al - mov %edi, %eax - adc %edx, %eax -DEFSIZE(ADDX_L) - -/*************************************************************************/ - -/** - * SUB_[BWL]: Evaluate op2 - op1. - */ -DEFLABEL(SUB_B) - mov %edi, %eax - xchg %edx, %eax - sub %dl, %al -DEFSIZE(SUB_B) - -DEFLABEL(SUB_W) - mov %edi, %eax - xchg %edx, %eax - sub %dx, %ax -DEFSIZE(SUB_W) - -DEFLABEL(SUB_L) - mov %edi, %eax - xchg %edx, %eax - sub %edx, %eax -DEFSIZE(SUB_L) - -/*-----------------------------------------------------------------------*/ - -/** - * SUBA_W: Sign-extend op1 to 32 bits, then evaluate op2 - op1. - */ -DEFLABEL(SUBA_W) - movsx %di, %edi - mov %edi, %eax - xchg %edx, %eax - sub %edx, %eax -DEFSIZE(SUBA_W) - -/*-----------------------------------------------------------------------*/ - -/** - * SUBX_[BWL]: Evaluate op2 - op1 - X. - */ -DEFLABEL(SUBX_B) - LDC_FROM_X %al - mov %edi, %eax - xchg %edx, %eax - sbb %dl, %al -DEFSIZE(SUBX_B) - -DEFLABEL(SUBX_W) - LDC_FROM_X %al - mov %edi, %eax - xchg %edx, %eax - sbb %dx, %ax -DEFSIZE(SUBX_W) - -DEFLABEL(SUBX_L) - LDC_FROM_X %al - mov %edi, %eax - xchg %edx, %eax - sbb %edx, %eax -DEFSIZE(SUBX_L) - -/*************************************************************************/ - -/** - * MUL[SU]_W: Evaluate op2 * op1 in signed or unsigned context. - */ -DEFLABEL(MULS_W) - movsx %di, %eax - movsx %dx, %edx - imul %edx - test %eax, %eax -DEFSIZE(MULS_W) - -DEFLABEL(MULU_W) - movzx %di, %eax - movzx %dx, %edx - mul %edx - test %eax, %eax -DEFSIZE(MULU_W) - -/*************************************************************************/ - -/** - * DIV[SU]_W: Evaluate op2 / op1 in signed or unsigned context, setting - * the condition codes appropriately. The quotient is stored in the low - * 16 bits, the remainder in the high 16 bits of the result value. On - * overflow, op2 is copied to the result. - */ -DEFLABEL(DIVS_W) - andb $~SR_C, SR - test %di, %di - jnz 0f - movl $EX_DIVIDE_BY_ZERO, Q68State_exception(%rbx) - TERMINATE -0: push %rdx // Save op2 (register value) so we can restore it as the - // result on overflow - mov %edx, %eax - cdq - movsx %di, %edi - idiv %edi - lea 0x8000(%eax), %ecx - test $0xFFFF0000, %ecx - jz 1f - pop %rax - orb $SR_V, SR - jmp 2f -1: pop %rcx - shl $16, %edx - or %edx, %eax - test %ax, %ax - SETCC_NZ - andb $~SR_V, SR -2: -DEFSIZE(DIVS_W) - -DEFLABEL(DIVU_W) - andb $~SR_C, SR - test %di, %di - jnz 0f - movl $EX_DIVIDE_BY_ZERO, Q68State_exception(%rbx) - TERMINATE -0: push %rdx // Save op2 (register value) so we can restore it as the - // result on overflow - mov %edx, %eax - xor %edx, %edx - movsx %di, %edi - div %edi - test $0xFFFF0000, %eax - jz 1f - pop %rax - orb $SR_V, SR - jmp 2f -1: pop %rcx - shl $16, %edx - or %edx, %eax - test %ax, %ax - SETCC_NZ - andb $~SR_V, SR -2: -DEFSIZE(DIVU_W) - -/*************************************************************************/ - -/** - * AND_[BWL]: Evaluate op2 & op1. - */ -DEFLABEL(AND_B) - mov %edi, %eax - and %dl, %al -DEFSIZE(AND_B) - -DEFLABEL(AND_W) - mov %edi, %eax - and %dx, %ax -DEFSIZE(AND_W) - -DEFLABEL(AND_L) - mov %edi, %eax - and %edx, %eax -DEFSIZE(AND_L) - -/*************************************************************************/ - -/** - * OR_[BWL]: Evaluate op2 | op1. - */ -DEFLABEL(OR_B) - mov %edi, %eax - or %dl, %al -DEFSIZE(OR_B) - -DEFLABEL(OR_W) - mov %edi, %eax - or %dx, %ax -DEFSIZE(OR_W) - -DEFLABEL(OR_L) - mov %edi, %eax - or %edx, %eax -DEFSIZE(OR_L) - -/*************************************************************************/ - -/** - * EOR_[BWL]: Evaluate op2 ^ op1. - */ -DEFLABEL(EOR_B) - mov %edi, %eax - xor %dl, %al -DEFSIZE(EOR_B) - -DEFLABEL(EOR_W) - mov %edi, %eax - xor %dx, %ax -DEFSIZE(EOR_W) - -DEFLABEL(EOR_L) - mov %edi, %eax - xor %edx, %eax -DEFSIZE(EOR_L) - -/*************************************************************************/ - -/** - * EXT_[WL]: Sign-extend op1 from 8 to 16 or from 16 to 32 bits. - */ -DEFLABEL(EXT_W) - mov %edi, %eax - movsx %al, %ax - test %ax, %ax -DEFSIZE(EXT_W) - -DEFLABEL(EXT_L) - movsx %di, %eax - test %eax, %eax -DEFSIZE(EXT_L) - -/*************************************************************************/ - -/** - * SWAP: Swap the upper and lower 16-bit halves of op1, placing the result - * in the result register. - */ -DEFLABEL(SWAP) - mov %edi, %eax - rol $16, %eax - test %eax, %eax -DEFSIZE(SWAP) - -/*************************************************************************/ -/**************************** BCD operations *****************************/ -/*************************************************************************/ - -/** - * ABCD: Evaluate op2 + op1 + X, treating the operands as binary-coded - * decimal values. - */ -DEFLABEL(ABCD) - mov %edi, %ecx - mov %edx, %eax - and $0x0F, %ecx - and $0x0F, %eax - add %ecx, %eax - mov SR, %ecx - shr $SR_X_SHIFT, %ecx - and $1, %ecx - add %ecx, %eax - cmp $10, %eax - jb 0f - add $6, %eax -0: and $0xF0, %edi - and $0xF0, %edx - add %edi, %edx - add %edx, %eax - xor %ecx, %ecx - cmp $10<<4, %eax - jb 1f - sub $10<<4, %eax - mov $1, %cl -1: mov %cl, %dl - //shl $SR_C_SHIFT, %cl // Shift count is 0, so omitted - shl $SR_X_SHIFT, %dl - or %cl, %dl - andb $~(SR_X|SR_C), SR - or %dl, SR - test %al, %al - setnz %cl - shl $SR_Z_SHIFT, %cl - not %cl - and %cl, SR -DEFSIZE(ABCD) - -/*************************************************************************/ - -/** - * SBCD: Evaluate op2 - op1 - X, treating the operands as binary-coded - * decimal values. - */ -DEFLABEL(SBCD) - mov %edi, %ecx - mov %edx, %eax - and $0x0F, %ecx - and $0x0F, %eax - sub %ecx, %eax - mov SR, %ecx - shr $SR_X_SHIFT, %ecx - and $1, %ecx - sub %ecx, %eax - xor %ecx, %ecx - test %eax, %eax - jns 0f - add $10, %eax - add $16, %ecx -0: and $0xF0, %edi - and $0xF0, %edx - sub %ecx, %edx - xor %ecx, %ecx - sub %edi, %edx - jns 1f - add $10<<4, %eax - mov $1, %cl -1: add %edx, %eax - jns 2f - mov $1, %cl -2: mov %cl, %dl - //shl $SR_C_SHIFT, %cl // Shift count is 0, so omitted - shl $SR_X_SHIFT, %dl - or %cl, %dl - andb $~(SR_X|SR_C), SR - or %dl, SR - test %al, %al - setnz %cl - shl $SR_Z_SHIFT, %cl - not %cl - and %cl, SR -DEFSIZE(SBCD) - -/*************************************************************************/ -/*********************** Bit-twiddling operations ************************/ -/*************************************************************************/ - -/** - * BTST_[BL]: Evaluate op2 & (1 << op1). The value (1 << op1), where the - * high bits of op1 have been masked to zero, is left in %edi for use by a - * subsequent BCHG/BCLR/BSET operation. - */ -DEFLABEL(BTST_B) - mov %edi, %ecx - and $7, %ecx - mov $1, %edi - shl %cl, %edi - test %edi, %edx - setz %cl - shl $SR_Z_SHIFT, %cl - and $~SR_Z, SR - or %cl, SR -DEFSIZE(BTST_B) - -DEFLABEL(BTST_L) - mov %edi, %ecx - and $31, %ecx - mov $1, %edi - shl %cl, %edi - test %edi, %edx - setz %cl - shl $SR_Z_SHIFT, %cl - and $~SR_Z, SR - or %cl, SR -DEFSIZE(BTST_L) - -/*************************************************************************/ - -/** - * BCHG: Evaluate op2 ^ (1 << op1), where (1 << op1) has already been - * stored in %edi. - */ -DEFLABEL(BCHG) - mov %edx, %eax - xor %edi, %eax -DEFSIZE(BCHG) - -/*-----------------------------------------------------------------------*/ - -/** - * BCLR: Evaluate op2 & ~(1 << op1), where (1 << op1) has already been - * stored in %edi. - */ -DEFLABEL(BCLR) - mov %edx, %eax - not %edi - and %edi, %eax -DEFSIZE(BCLR) - -/*-----------------------------------------------------------------------*/ - -/** - * BSET: Evaluate op2 | (1 << op1), where (1 << op1) has already been - * stored in %edi. - */ -DEFLABEL(BSET) - mov %edx, %eax - or %edi, %eax -DEFSIZE(BSET) - -/*************************************************************************/ -/************************ Shift/rotate operations ************************/ -/*************************************************************************/ - -/** - * SETCC_XC_SHIFT: Set the X and C flags for a shift or rotate instruction. - * The value to set (0 or 1) is passed in %dl; %dh is destroyed. Assumes - * that the X and C flags have already been cleared. - */ -.macro SETCC_XC_SHIFT - mov %dl, %dh - shl $SR_X_SHIFT, %dh - //shl $SR_C_SHIFT, %dl // Shift count is 0, so omitted - or %dh, %dl - or %dl, SR -.endm - -/*************************************************************************/ - -/** - * ASL_[BWL]: Evaluate (signed) op2 << op1. - */ -.macro DEF_ASL nbits, reg - mov %edi, %ecx - mov %edx, %eax - and $0x3F, %ecx - add %ecx, %esi - add %ecx, %esi - andb $~(SR_V|SR_C), SR - test %ecx, %ecx - jz 1f - andb $~SR_X, SR - // Have to shift bit by bit to detect overflow -0: sal $1, \reg - setc %dl - seto %dh - shl $SR_V_SHIFT, %dh - or %dh, SR - loop 0b - SETCC_XC_SHIFT -1: test \reg, \reg - SETCC_NZ -.endm - -DEFLABEL(ASL_B) - DEF_ASL 8, %al -DEFSIZE(ASL_B) - -DEFLABEL(ASL_W) - DEF_ASL 16, %ax -DEFSIZE(ASL_W) - -DEFLABEL(ASL_L) - DEF_ASL 32, %eax -DEFSIZE(ASL_L) - -/*-----------------------------------------------------------------------*/ - -/** - * ASR_[BWL]: Evaluate (signed) op2 >> op1. - */ -.macro DEF_ASR nbits, reg - mov %edi, %ecx - mov %edx, %eax - and $0x3F, %ecx - add %ecx, %esi - add %ecx, %esi - andb $~(SR_V|SR_C), SR - test %ecx, %ecx - jz 4f - andb $~SR_X, SR - cmp $\nbits, %ecx - jb 2f -1: // count >= nbits - sar $\nbits-1, \reg - mov %al, %dl - and $1, %dl - jmp 3f -2: // 0 < count < nbits - sar %cl, \reg - setc %dl -3: // count != 0 - SETCC_XC_SHIFT -4: // All cases - test \reg, \reg - SETCC_NZ -.endm - -DEFLABEL(ASR_B) - DEF_ASR 8, %al -DEFSIZE(ASR_B) - -DEFLABEL(ASR_W) - DEF_ASR 16, %ax -DEFSIZE(ASR_W) - -DEFLABEL(ASR_L) - DEF_ASR 32, %eax -DEFSIZE(ASR_L) - -/*************************************************************************/ - -/** - * LSL_[BWL]: Evaluate (unsigned) op2 << op1. - */ -.macro DEF_LSL nbits, reg - mov %edi, %ecx - mov %edx, %eax - and $0x3F, %ecx - add %ecx, %esi - add %ecx, %esi - andb $~(SR_V|SR_C), SR - test %ecx, %ecx - jz 4f - andb $~SR_X, SR - cmp $\nbits, %ecx - jb 2f - ja 1f -0: // count == nbits - and $1, %al - mov %al, %dl - xor \reg, \reg - jmp 3f -1: // count > nbits - xor \reg, \reg - jmp 4f -2: // 0 < count < nbits - sal %cl, \reg - setc %dl -3: // 0 < count <= nbits - SETCC_XC_SHIFT -4: // All cases - test \reg, \reg - SETCC_NZ -.endm - -DEFLABEL(LSL_B) - DEF_LSL 8, %al -DEFSIZE(LSL_B) - -DEFLABEL(LSL_W) - DEF_LSL 16, %ax -DEFSIZE(LSL_W) - -DEFLABEL(LSL_L) - DEF_LSL 32, %eax -DEFSIZE(LSL_L) - -/*-----------------------------------------------------------------------*/ - -/** - * LSR_[BWL]: Evaluate (unsigned) op2 >> op1. - */ -.macro DEF_LSR nbits, reg - mov %edi, %ecx - mov %edx, %eax - and $0x3F, %ecx - add %ecx, %esi - add %ecx, %esi - andb $~(SR_V|SR_C), SR - test %ecx, %ecx - jz 4f - andb $~SR_X, SR - cmp $\nbits, %ecx - jb 2f - ja 1f -0: // count == nbits - shl $1, \reg - setc %dl - xor \reg, \reg - jmp 3f -1: // count > nbits - xor \reg, \reg - jmp 4f -2: // 0 < count < nbits - shr %cl, \reg - setc %dl -3: // 0 < count <= nbits - SETCC_XC_SHIFT -4: // All cases - test \reg, \reg - SETCC_NZ -.endm - -DEFLABEL(LSR_B) - DEF_LSR 8, %al -DEFSIZE(LSR_B) - -DEFLABEL(LSR_W) - DEF_LSR 16, %ax -DEFSIZE(LSR_W) - -DEFLABEL(LSR_L) - DEF_LSR 32, %eax -DEFSIZE(LSR_L) - -/*************************************************************************/ - -/** - * ROXL_[BWL]: Evaluate op2 ROXL op1. - */ -.macro DEF_ROXL nbits, reg - mov %edi, %ecx - mov %edx, %eax - and $0x3F, %ecx - add %ecx, %esi - add %ecx, %esi - andb $~(SR_V|SR_C), SR - test %ecx, %ecx - jnz 0f - mov SR, %dl - shr $SR_X_SHIFT, %dl - and $1, %dl - jmp 2f -0: LDC_FROM_X %dl -1: rcl \reg - loop 1b - setc %dl - andb $~SR_X, SR -2: SETCC_XC_SHIFT - test \reg, \reg - SETCC_NZ -.endm - -DEFLABEL(ROXL_B) - DEF_ROXL 8, %al -DEFSIZE(ROXL_B) - -DEFLABEL(ROXL_W) - DEF_ROXL 16, %ax -DEFSIZE(ROXL_W) - -DEFLABEL(ROXL_L) - DEF_ROXL 32, %eax -DEFSIZE(ROXL_L) - -/*-----------------------------------------------------------------------*/ - -/** - * ROXR_[BWL]: Evaluate op2 ROXR op1. - */ -.macro DEF_ROXR nbits, reg - mov %edi, %ecx - mov %edx, %eax - and $0x3F, %ecx - add %ecx, %esi - add %ecx, %esi - andb $~(SR_V|SR_C), SR - test %ecx, %ecx - jnz 0f - mov SR, %dl - shr $SR_X_SHIFT, %dl - and $1, %dl - jmp 2f -0: LDC_FROM_X %dl -1: rcr \reg - loop 1b - setc %dl - andb $~SR_X, SR -2: SETCC_XC_SHIFT - test \reg, \reg - SETCC_NZ -.endm - -DEFLABEL(ROXR_B) - DEF_ROXR 8, %al -DEFSIZE(ROXR_B) - -DEFLABEL(ROXR_W) - DEF_ROXR 16, %ax -DEFSIZE(ROXR_W) - -DEFLABEL(ROXR_L) - DEF_ROXR 32, %eax -DEFSIZE(ROXR_L) - -/*************************************************************************/ - -/** - * ROL_[BWL]: Evaluate op2 ROL op1. - */ -.macro DEF_ROL nbits, reg - mov %edi, %ecx - mov %edx, %eax - and $0x3F, %ecx - add %ecx, %esi - add %ecx, %esi - andb $~(SR_V|SR_C), SR - test %ecx, %ecx - jz 3f - and $\nbits-1, %ecx - jnz 2f -1: // count != 0 && count % nbits == 0 - mov %al, %dl - and $1, %dl - //shl $SR_C_SHIFT, %dl // Shift count is 0, so omitted - or %dl, SR - jmp 3f -2: // count % nbits != 0 - rol %cl, \reg - setc %dl - //shl $SR_C_SHIFT, %dl // Shift count is 0, so omitted - or %dl, SR -3: // All cases - test \reg, \reg - SETCC_NZ -.endm - -DEFLABEL(ROL_B) - DEF_ROL 8, %al -DEFSIZE(ROL_B) - -DEFLABEL(ROL_W) - DEF_ROL 16, %ax -DEFSIZE(ROL_W) - -DEFLABEL(ROL_L) - DEF_ROL 32, %eax -DEFSIZE(ROL_L) - -/*-----------------------------------------------------------------------*/ - -/** - * ROR_[BWL]: Evaluate op2 ROR op1. - */ -.macro DEF_ROR nbits, reg - mov %edi, %ecx - mov %edx, %eax - and $0x3F, %ecx - add %ecx, %esi - add %ecx, %esi - andb $~(SR_V|SR_C), SR - test %ecx, %ecx - jz 3f - and $\nbits-1, %ecx - jnz 2f -1: // count != 0 && count % nbits == 0 - mov %eax, %edx - shr $\nbits-1, %edx - and $1, %dl - //shl $SR_C_SHIFT, %dl // Shift count is 0, so omitted - or %dl, SR - jmp 3f -2: // count % nbits != 0 - ror %cl, \reg - setc %dl - //shl $SR_C_SHIFT, %dl // Shift count is 0, so omitted - or %dl, SR -3: // All cases - test \reg, \reg - SETCC_NZ -.endm - -DEFLABEL(ROR_B) - DEF_ROR 8, %al -DEFSIZE(ROR_B) - -DEFLABEL(ROR_W) - DEF_ROR 16, %ax -DEFSIZE(ROR_W) - -DEFLABEL(ROR_L) - DEF_ROR 32, %eax -DEFSIZE(ROR_L) - -/*************************************************************************/ -/******************* Conditional and branch operations *******************/ -/*************************************************************************/ - -/** - * Scc: Set the lower 8 bits of the result value to 0xFF if the condition - * is true, 0x00 if false. - */ -DEFLABEL(Scc) - neg %al -DEFSIZE(Scc) - -/*-----------------------------------------------------------------------*/ - -/** - * ADD_CYCLES_Scc_Dn: Add the appropriate number of clock cycles for an - * Scc Dn instruction to the cycle count. - */ -DEFLABEL(ADD_CYCLES_Scc_Dn) - movzx %al, %ecx - and $2, %ecx - add $4, %ecx - add %ecx, %esi -DEFSIZE(ADD_CYCLES_Scc_Dn) - -/*************************************************************************/ - -/** - * DBcc: Jump to the specified target address unless the condition is true - * or the lower 16 bits of the given data register, after being decremented, - * are equal to -1. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7) - * target: Target address - */ -DEFLABEL(DBcc) - test %al, %al - jz 0f - add $12, %esi - jmp 2f -0: lea 1(%rbx), %rcx -8: subw $1, (%rcx) - mov (%rcx), %ax - cmp $-1, %ax - jne 1f - add $14, %esi - jmp 2f -1: add $10, %esi - mov $0x12345678, %eax -9: mov %eax, PC - TERMINATE -2: -DEFSIZE(DBcc) -DEFPARAM(DBcc, reg4, 8b, -1) -DEFPARAM(DBcc, target, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * DBcc_native: Implement DBcc using a jump within the native code. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7) - * target: Target 68000 address - * native_disp: Target native displacement from end of this fragment - */ -DEFLABEL(DBcc_native) - test %al, %al - jz 0f - add $12, %esi - jmp 2f -0: lea 1(%rbx), %rcx -8: subw $1, (%rcx) - mov (%rcx), %ax - cmp $-1, %ax - jne 1f - add $14, %esi - jmp 2f -1: add $10, %esi - mov $0x12345678, %eax -9: mov %eax, PC - jmp .+0x12345678 -2: -DEFSIZE(DBcc_native) -DEFPARAM(DBcc_native, reg4, 8b, -1) -DEFPARAM(DBcc_native, target, 9b, -4) -DEFPARAM(DBcc_native, native_disp, 2b, -4) - -/*************************************************************************/ - -/** - * Bcc: Jump to the specified target address if the condition is true. - * - * [Parameters] - * target: Target address - */ -DEFLABEL(Bcc) - test %al, %al - jz 0f - mov $0x12345678, %eax -9: mov %eax, PC - add $10, %esi - TERMINATE -0: -DEFSIZE(Bcc) -DEFPARAM(Bcc, target, 9b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * Bcc_native: Implement Bcc using a jump within the native code. - * - * [Parameters] - * target: Target 68000 address - * native_disp: Target native displacement from end of this fragment - */ -DEFLABEL(Bcc_native) - test %al, %al - jz 0f - mov $0x12345678, %eax -9: mov %eax, PC - add $10, %esi - jmp .+0x12345678 -0: -DEFSIZE(Bcc_native) -DEFPARAM(Bcc_native, target, 9b, -4) -DEFPARAM(Bcc_native, native_disp, 0b, -4) - -/*-----------------------------------------------------------------------*/ - -/** - * BSR: Push the address of the next instruction onto the stack, then jump - * to the specified target address. - * - * [Parameters] - * return_addr: Return address to push onto the stack - * target: Target address - */ -DEFLABEL(BSR) - mov $0x12345678, %ecx -8: PUSH32 %rcx - mov $0x12345678, %eax -9: mov %eax, PC - TERMINATE -DEFSIZE(BSR) -DEFPARAM(BSR, return_addr, 8b, -4) -DEFPARAM(BSR, target, 9b, -4) - -/*************************************************************************/ - -/** - * JMP: Jump to the previously resolved effective address. - */ -DEFLABEL(JMP) - mov Q68State_ea_addr(%rbx), %eax - mov %eax, PC - TERMINATE -DEFSIZE(JMP) - -/*-----------------------------------------------------------------------*/ - -/** - * JSR: Push the address of the next instruction onto the stack, then jump - * to the previously resolved effective address. - * - * [Parameters] - * return_addr: Return address to push onto the stack - */ -DEFLABEL(JSR) - mov $0x12345678, %ecx -9: PUSH32 %rcx - mov Q68State_ea_addr(%rbx), %eax - mov %eax, PC - TERMINATE -DEFSIZE(JSR) -DEFPARAM(JSR, return_addr, 9b, -4) - -/*************************************************************************/ -/*********************** MOVEM-related operations ************************/ -/*************************************************************************/ - -/** - * STORE_DEC_[WL]: Decrement state->ea_addr, then store the specified - * register to the resulting location. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(STORE_DEC_W) - mov Q68State_ea_addr(%rbx), %ecx - sub $2, %ecx - mov %ecx, Q68State_ea_addr(%rbx) - mov 1(%rbx), %eax -9: WRITE16 %rcx, %rax -DEFSIZE(STORE_DEC_W) -DEFPARAM(STORE_DEC_W, reg4, 9b, -1) - -DEFLABEL(STORE_DEC_L) - mov Q68State_ea_addr(%rbx), %ecx - sub $4, %ecx - mov %ecx, Q68State_ea_addr(%rbx) - mov 1(%rbx), %eax -9: WRITE32 %rcx, %rax -DEFSIZE(STORE_DEC_L) -DEFPARAM(STORE_DEC_L, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * STORE_INC_[WL]: Store the specified register to the location indicated - * by state->ea_addr, then increment state->ea_addr. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(STORE_INC_W) - mov Q68State_ea_addr(%rbx), %ecx - mov 1(%rbx), %eax -9: WRITE16 %rcx, %rax - add $2, Q68State_ea_addr(%rbx) -DEFSIZE(STORE_INC_W) -DEFPARAM(STORE_INC_W, reg4, 9b, -1) - -DEFLABEL(STORE_INC_L) - mov Q68State_ea_addr(%rbx), %ecx - mov 1(%rbx), %eax -9: WRITE32 %rcx, %rax - add $4, Q68State_ea_addr(%rbx) -DEFSIZE(STORE_INC_L) -DEFPARAM(STORE_INC_L, reg4, 9b, -1) - -/*************************************************************************/ - -/** - * LOAD_INC_[WL]: Load the specified register from the location indicated - * by state->ea_addr, then increment state->ea_addr. - * - * [Parameters] - * reg4: Register number * 4 (0-28: D0-D7, 32-60: A0-A7) - */ -DEFLABEL(LOAD_INC_W) - mov Q68State_ea_addr(%rbx), %ecx - READ16 %rcx - mov %ax, 1(%rbx) -9: add $2, Q68State_ea_addr(%rbx) -DEFSIZE(LOAD_INC_W) -DEFPARAM(LOAD_INC_W, reg4, 9b, -1) - -DEFLABEL(LOAD_INC_L) - mov Q68State_ea_addr(%rbx), %ecx - READ32 %rcx - mov %eax, 1(%rbx) -9: add $4, Q68State_ea_addr(%rbx) -DEFSIZE(LOAD_INC_L) -DEFPARAM(LOAD_INC_L, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * LOADA_INC_W: Load the specified address register from the location - * indicated by state->ea_addr, sign-extending the 16-bit value to 32 bits, - * then increment state->ea_addr. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(LOADA_INC_W) - mov Q68State_ea_addr(%rbx), %ecx - READ16 %rcx - cwde - mov %eax, 1(%rbx) -9: add $2, Q68State_ea_addr(%rbx) -DEFSIZE(LOADA_INC_W) -DEFPARAM(LOADA_INC_W, reg4, 9b, -1) - -/*************************************************************************/ - -/** - * MOVEM_WRITEBACK: Store the address in state->ea_addr to the specified - * address register. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(MOVEM_WRITEBACK) - mov Q68State_ea_addr(%rbx), %ecx - mov %ecx, 1(%rbx) -9: -DEFSIZE(MOVEM_WRITEBACK) -DEFPARAM(MOVEM_WRITEBACK, reg4, 9b, -1) - -/*************************************************************************/ -/*********************** Miscellaneous operations ************************/ -/*************************************************************************/ - -/** - * CHK_W: Raise a CHK exception if op1 < 0 or op1 > op2, treating both - * operands as signed 16-bit values. - */ -DEFLABEL(CHK_W) - test %di, %di - jns 0f - orb $SR_N, SR - jmp 1f -0: cmp %dx, %di - jle 2f - andb $~SR_N, SR -1: movl $EX_CHK, Q68State_exception(%rbx) - TERMINATE -2: -DEFSIZE(CHK_W) - -/*************************************************************************/ - -/** - * LEA: Store the previously resolved effective address in the specified - * address register. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(LEA) - mov Q68State_ea_addr(%rbx), %eax - mov %eax, 1(%rbx) -9: -DEFSIZE(LEA) -DEFPARAM(LEA, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * PEA: Push the previously resolved effective address onto the stack. - */ -DEFLABEL(PEA) - mov Q68State_ea_addr(%rbx), %ecx - PUSH32 %rcx -DEFSIZE(PEA) - -/*************************************************************************/ - -/** - * TAS: Test the 8-bit value of op1, setting the condition codes - * appropriately, then calculate op1 | 0x80. - */ -DEFLABEL(TAS) - mov %edi, %eax - test %al, %al - SETCC_NZ00 - or $0x80, %al -DEFSIZE(TAS) - -/*************************************************************************/ - -/** - * MOVE_FROM_USP: Copy the user stack pointer to the specified register. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(MOVE_FROM_USP) - mov USP, %eax - mov %eax, 1(%rbx) -9: -DEFSIZE(MOVE_FROM_USP) -DEFPARAM(MOVE_FROM_USP, reg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * MOVE_TO_USP: Copy the specified register to the user stack pointer. - * - * [Parameters] - * reg4: Register number * 4 (32-60: A0-A7) - */ -DEFLABEL(MOVE_TO_USP) - mov 1(%rbx), %eax -9: mov %eax, USP -DEFSIZE(MOVE_TO_USP) -DEFPARAM(MOVE_TO_USP, reg4, 9b, -1) - -/*************************************************************************/ - -/** - * STOP: Halt the processor. - * - * [Parameters] - * newSR: Value to load into SR - */ -DEFLABEL(STOP) - movl $1, Q68State_halted(%rbx) - mov $0x1234, %ax -9: UPDATE_SR -DEFSIZE(STOP) -DEFPARAM(STOP, newSR, 9b, -2) - -/*************************************************************************/ - -/** - * TRAPV: Raise a TRAPV exception if the overflow flag is set. - */ -DEFLABEL(TRAPV) - testb $SR_V, SR - jz 0f - movl $EX_TRAPV, Q68State_exception(%rbx) - TERMINATE -0: -DEFSIZE(TRAPV) - -/*************************************************************************/ - -/** - * RTS: Pop the PC from the stack. - */ -DEFLABEL(RTS) - POP32 - mov %eax, PC - TERMINATE -DEFSIZE(RTS) - -/*-----------------------------------------------------------------------*/ - -/** - * RTR: Pop the condition codes and PC from the stack. - */ -DEFLABEL(RTR) - POP16 - mov %al, SR // Update low byte only - POP32 - mov %eax, PC - TERMINATE -DEFSIZE(RTR) - -/*-----------------------------------------------------------------------*/ - -/** - * RTE: Pop the status register and PC from the stack. - */ -DEFLABEL(RTE) - POP16 - push %rax - POP32 - mov %eax, PC - pop %rax - UPDATE_SR - TERMINATE -DEFSIZE(RTE) - -/*************************************************************************/ - -/** - * MOVEP_READ_[WL]: Read a value from memory, skipping every other byte. - * - * [Parameters] - * areg4: Register number * 4 of base address register (32-60 = A0-A7) - * disp: Displacement from base address register - * dreg4: Register number * 4 of data reg. to receive data (0-28 = D0-D7) - */ -DEFLABEL(MOVEP_READ_W) - mov 1(%rbx), %ecx -7: add $0x12345678, %ecx -8: push %rcx - READ8 %rcx // Byte 1 - movzx %al, %edi - shl $8, %edi - pop %rcx - add $2, %ecx - READ8 %rcx // Byte 0 - movzx %al, %eax - or %eax, %edi - mov %di, 1(%rbx) -9: -DEFSIZE(MOVEP_READ_W) -DEFPARAM(MOVEP_READ_W, areg4, 7b, -1) -DEFPARAM(MOVEP_READ_W, disp, 8b, -4) -DEFPARAM(MOVEP_READ_W, dreg4, 9b, -1) - -DEFLABEL(MOVEP_READ_L) - mov 1(%rbx), %ecx -7: add $0x12345678, %ecx -8: push %rcx - READ8 %rcx // Byte 3 - movzx %al, %edi - shl $24, %edi - mov (%rsp), %ecx - add $2, %ecx - READ8 %rcx // Byte 2 - movzx %al, %eax - shl $16, %eax - or %eax, %edi - mov (%rsp), %ecx - add $4, %ecx - READ8 %rcx // Byte 1 - movzx %al, %eax - shl $8, %eax - or %eax, %edi - pop %rcx - add $6, %ecx - READ8 %rcx // Byte 0 - movzx %al, %eax - or %eax, %edi - mov %di, 1(%rbx) -9: -DEFSIZE(MOVEP_READ_L) -DEFPARAM(MOVEP_READ_L, areg4, 7b, -1) -DEFPARAM(MOVEP_READ_L, disp, 8b, -4) -DEFPARAM(MOVEP_READ_L, dreg4, 9b, -1) - -/*-----------------------------------------------------------------------*/ - -/** - * MOVEP_WRITE_[WL]: Write a value to memory, skipping every other byte. - * - * [Parameters] - * areg4: Register number * 4 of base address register (32-60 = A0-A7) - * disp: Displacement from base address register - * dreg4: Register number * 4 of data reg. containing data (0-28 = D0-D7) - */ -DEFLABEL(MOVEP_WRITE_W) - mov 1(%rbx), %ecx -7: add $0x12345678, %ecx -8: mov 1(%rbx), %eax -9: push %rcx - push %rax - shr $8, %eax - WRITE8 %rcx, %rax // Byte 1 - pop %rax - pop %rcx - add $2, %ecx - WRITE8 %rcx, %rax // Byte 0 -DEFSIZE(MOVEP_WRITE_W) -DEFPARAM(MOVEP_WRITE_W, areg4, 7b, -1) -DEFPARAM(MOVEP_WRITE_W, disp, 8b, -4) -DEFPARAM(MOVEP_WRITE_W, dreg4, 9b, -1) - -DEFLABEL(MOVEP_WRITE_L) - mov 1(%rbx), %ecx -7: add $0x12345678, %ecx -8: mov 1(%rbx), %eax -9: push %rcx - push %rax - shr $24, %eax - WRITE8 %rcx, %rax // Byte 3 - pop %rax - mov (%rsp), %ecx - add $2, %ecx - push %rax - shr $16, %eax - WRITE8 %rcx, %rax // Byte 2 - pop %rax - mov (%rsp), %ecx - add $4, %ecx - push %rax - shr $8, %eax - WRITE8 %rcx, %rax // Byte 1 - pop %rax - pop %rcx - add $6, %ecx - WRITE8 %rcx, %rax // Byte 0 -DEFSIZE(MOVEP_WRITE_L) -DEFPARAM(MOVEP_WRITE_L, areg4, 7b, -1) -DEFPARAM(MOVEP_WRITE_L, disp, 8b, -4) -DEFPARAM(MOVEP_WRITE_L, dreg4, 9b, -1) - -/*************************************************************************/ - -/** - * EXG: Exchange the values of two registers. - * - * [Parameters] - * reg1_4: Register number * 4 of first register (0-60 = D0-A7) - * reg2_4: Register number * 4 of second register (0-60 = D0-A7) - */ -DEFLABEL(EXG) - lea 1(%rbx), %ecx -8: lea 1(%rbx), %edx -9: mov (%rcx), %eax - mov (%rdx), %edi - mov %eax, (%rdx) - mov %edi, (%rcx) -DEFSIZE(EXG) -DEFPARAM(EXG, reg1_4, 8b, -1) -DEFPARAM(EXG, reg2_4, 9b, -1) - -/*************************************************************************/ -/*************************************************************************/ diff --git a/yabause/src/q68/q68-jit-x86.h b/yabause/src/q68/q68-jit-x86.h deleted file mode 100644 index 1fef4589c2..0000000000 --- a/yabause/src/q68/q68-jit-x86.h +++ /dev/null @@ -1,453 +0,0 @@ -/* src/q68/q68-jit-x86.h: x86 (32/64-bit) dynamic translation header for Q68 - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef Q68_JIT_X86_H -#define Q68_JIT_X86_H - -/*************************************************************************/ - -/** - * JIT_CALL: Run translated code from the given (native) address for the - * given number of cycles. - * - * [Parameters] - * state: Processor state block - * cycles: Number of clock cycles to execute - * address_ptr: Pointer to address of native code to execute; must be - * updated on return with the next address to execute - * or NULL if the end of the block was reached - * [Return value] - * Number of clock cycles actually executed - */ -static inline int JIT_CALL(Q68State *state, int cycles, void **address_ptr) -{ - asm( -#ifdef CPU_X64 - /* GCC doesn't know we're actually calling a function here, so make - * sure we don't accidentally overwrite the x64 redzone */ - "sub $128, %%rsp; call *%[address]; add $128, %%rsp" -#else - /* x86 doesn't have a redzone, so we can just do a direct call */ - "call *%[address]" -#endif - : [cycles] "=S" (cycles), [address] "=D" (*address_ptr) - : [state] "b" (state), "0" (cycles), "1" (*address_ptr) -#ifdef CPU_X64 - : "rax", "rcx", "rdx", "r8", "r9", "r10", "r11" -#else - : "eax", "ecx", "edx" -#endif - , "memory" - ); - return cycles; -} - -/*************************************************************************/ - -/** - * JIT_FIXUP_BRANCH: Modify a branch instruction at the given offset to - * jump to the given target. - * - * [Parameters] - * entry: Block being translated - * offset: Offset within entry->native_code of branch instruction - * (as returned in *branch_offset EMIT parameter) - * target: Target offset within entry->native_code - * [Return value] - * None - */ -static inline void JIT_FIXUP_BRANCH(Q68JitEntry *entry, uint32_t offset, - uint32_t target) -{ - /* Not supported on x86/x64 */ -} - -/*************************************************************************/ - -/* - * The remaining macros are all used to insert a specific operation into - * the native code stream. For simplicity, we define the actual code for - * each operation in a separate assembly file, and use memcpy() to copy - * from the assembled code to the output code stream. The GEN_EMIT macro - * below is used to generate each of the JIT_EMIT_* functions; each - * function JIT_EMIT_xxx copies JIT_X86SIZE_xxx bytes from JIT_X86_xxx to - * the code stream, expanding the code buffer if necessary. - */ - -/* Sub-macros (platform-dependent): */ - -#ifdef CPU_X64 - -#define GEN_NAMESIZE(name) \ - extern const uint8_t JIT_X64_##name[]; \ - extern const uint32_t JIT_X64SIZE_##name; -#define GEN_PARAM(name,param) \ - extern const uint32_t JIT_X64PARAM_##name##_##param; -#define GEN_FUNC_TOP(name) \ - if (UNLIKELY(entry->native_size - entry->native_length \ - < JIT_X64SIZE_##name)) { \ - if (!expand_buffer(entry)) { \ - return; \ - } \ - } \ - if (JIT_X64SIZE_##name > 0) { \ - memcpy((uint8_t *)entry->native_code + entry->native_length, \ - JIT_X64_##name, JIT_X64SIZE_##name); \ - } -#define GEN_COPY_PARAM(name,type,param) \ - *(type *)((uint8_t *)entry->native_code + entry->native_length \ - + JIT_X64PARAM_##name##_##param) = param; -#define GEN_FUNC_BOTTOM(name) \ - entry->native_length += JIT_X64SIZE_##name; - -#else // CPU_X86 - -#define GEN_NAMESIZE(name) \ - extern const uint8_t JIT_X86_##name[]; \ - extern const uint32_t JIT_X86SIZE_##name; -#define GEN_PARAM(name,param) \ - extern const uint32_t JIT_X86PARAM_##name##_##param; -#define GEN_FUNC_TOP(name) \ - if (UNLIKELY(entry->native_size - entry->native_length \ - < JIT_X86SIZE_##name)) { \ - if (!expand_buffer(entry)) { \ - return; \ - } \ - } \ - if (JIT_X86SIZE_##name > 0) { \ - memcpy((uint8_t *)entry->native_code + entry->native_length, \ - JIT_X86_##name, JIT_X86SIZE_##name); \ - } -#define GEN_COPY_PARAM(name,type,param) \ - *(type *)((uint8_t *)entry->native_code + entry->native_length \ - + JIT_X86PARAM_##name##_##param) = param; -#define GEN_FUNC_BOTTOM(name) \ - entry->native_length += JIT_X86SIZE_##name; - -#endif // X64/X86 - -#define GEN_EMIT(name) \ - GEN_NAMESIZE(name) \ - static void JIT_EMIT_##name(Q68JitEntry *entry) { \ - GEN_FUNC_TOP(name) \ - GEN_FUNC_BOTTOM(name) \ - } - -#define GEN_EMIT_1(name,type1,param1) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_FUNC_BOTTOM(name) \ - } - -#define GEN_EMIT_2(name,type1,param1,type2,param2) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - GEN_PARAM(name,param2) \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - type2 param2) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_COPY_PARAM(name, type2, param2) \ - GEN_FUNC_BOTTOM(name) \ - } - -#define GEN_EMIT_3(name,type1,param1,type2,param2,type3,param3) \ - GEN_NAMESIZE(name) \ - GEN_PARAM(name,param1) \ - GEN_PARAM(name,param2) \ - GEN_PARAM(name,param3) \ - static void JIT_EMIT_##name(Q68JitEntry *entry, type1 param1, \ - type2 param2, type3 param3) { \ - GEN_FUNC_TOP(name) \ - GEN_COPY_PARAM(name, type1, param1) \ - GEN_COPY_PARAM(name, type2, param2) \ - GEN_COPY_PARAM(name, type3, param3) \ - GEN_FUNC_BOTTOM(name) \ - } - -/*-----------------------------------------------------------------------*/ - -/* Code prologue and epilogue */ -GEN_EMIT(PROLOGUE) -GEN_EMIT(EPILOGUE) - -#ifdef Q68_TRACE -/* Trace the current instruction */ -GEN_EMIT(TRACE) -#endif - -/* Add the specified number of cycles to the cycle counter */ -GEN_EMIT_1(ADD_CYCLES, int32_t, cycles) - -/* Check the cycle limit and interrupt execution if necessary */ -GEN_EMIT(CHECK_CYCLES) - -/* Add the specified amount to the program counter and/or check whether - * to abort */ -GEN_EMIT_1(ADVANCE_PC, int32_t, value) -GEN_EMIT_1(ADVANCE_PC_CHECK_ABORT, int32_t, value) -GEN_EMIT(CHECK_ABORT) - -/* Exception raising */ -GEN_EMIT_1(EXCEPTION, uint32_t, num) -GEN_EMIT_2(CHECK_ALIGNED_EA, uint16_t, opcode, uint16_t, status) -GEN_EMIT_2(CHECK_ALIGNED_SP, uint16_t, opcode, uint16_t, status) -GEN_EMIT(CHECK_SUPER) - -/*-----------------------------------------------------------------------*/ - -/* Resolve an effective address */ -GEN_EMIT_1(RESOLVE_INDIRECT, uint8_t, reg4) -GEN_EMIT_2(RESOLVE_POSTINC, uint8_t, reg4, uint8_t, size) -GEN_EMIT(RESOLVE_POSTINC_A7_B) -GEN_EMIT_2(RESOLVE_PREDEC, uint8_t, reg4, uint8_t, size) -GEN_EMIT(RESOLVE_PREDEC_A7_B) -GEN_EMIT_2(RESOLVE_DISP, uint8_t, reg4, uint32_t, disp) -GEN_EMIT_3(RESOLVE_INDEX_W, uint8_t, reg4, uint8_t, ireg4, uint8_t, disp) -GEN_EMIT_3(RESOLVE_INDEX_L, uint8_t, reg4, uint8_t, ireg4, uint8_t, disp) -GEN_EMIT_1(RESOLVE_ABSOLUTE, uint32_t, addr) -GEN_EMIT_2(RESOLVE_ABS_INDEX_W, uint32_t, addr, uint8_t, ireg4) -GEN_EMIT_2(RESOLVE_ABS_INDEX_L, uint32_t, addr, uint8_t, ireg4) - -/* Retrieve various things as operand 1 */ -GEN_EMIT_1(GET_OP1_REGISTER, uint8_t, reg4) -GEN_EMIT(GET_OP1_EA_B) -GEN_EMIT(GET_OP1_EA_W) -GEN_EMIT(GET_OP1_EA_L) -GEN_EMIT_1(GET_OP1_IMMEDIATE, uint32_t, value) -GEN_EMIT(GET_OP1_CCR) -GEN_EMIT(GET_OP1_SR) - -/* Retrieve various things as operand 2 */ -GEN_EMIT_1(GET_OP2_REGISTER, uint8_t, reg4) -GEN_EMIT(GET_OP2_EA_B) -GEN_EMIT(GET_OP2_EA_W) -GEN_EMIT(GET_OP2_EA_L) -GEN_EMIT_1(GET_OP2_IMMEDIATE, uint32_t, value) -GEN_EMIT(GET_OP2_CCR) -GEN_EMIT(GET_OP2_SR) - -/* Update various things from result */ -GEN_EMIT_1(SET_REGISTER_B, uint8_t, reg4) -GEN_EMIT_1(SET_REGISTER_W, uint8_t, reg4) -GEN_EMIT_1(SET_REGISTER_L, uint8_t, reg4) -GEN_EMIT_1(SET_AREG_W, uint8_t, reg4) -GEN_EMIT(SET_EA_B) -GEN_EMIT(SET_EA_W) -GEN_EMIT(SET_EA_L) -GEN_EMIT(SET_CCR) -GEN_EMIT(SET_SR) - -/* Stack operations */ -GEN_EMIT(PUSH_L) -GEN_EMIT(POP_L) - -/* Condition code setting */ -GEN_EMIT(SETCC_ADD_B) -GEN_EMIT(SETCC_ADD_W) -GEN_EMIT(SETCC_ADD_L) -GEN_EMIT(SETCC_ADDX_B) -GEN_EMIT(SETCC_ADDX_W) -GEN_EMIT(SETCC_ADDX_L) -GEN_EMIT(SETCC_SUB_B) -GEN_EMIT(SETCC_SUB_W) -GEN_EMIT(SETCC_SUB_L) -GEN_EMIT(SETCC_SUBX_B) -GEN_EMIT(SETCC_SUBX_W) -GEN_EMIT(SETCC_SUBX_L) -GEN_EMIT(SETCC_CMP_B) -GEN_EMIT(SETCC_CMP_W) -GEN_EMIT(SETCC_CMP_L) -GEN_EMIT(SETCC_LOGIC_B) -GEN_EMIT(SETCC_LOGIC_W) -GEN_EMIT(SETCC_LOGIC_L) - -/* Condition testing */ -GEN_EMIT(TEST_T) -GEN_EMIT(TEST_F) -GEN_EMIT(TEST_HI) -GEN_EMIT(TEST_LS) -GEN_EMIT(TEST_CC) -GEN_EMIT(TEST_CS) -GEN_EMIT(TEST_NE) -GEN_EMIT(TEST_EQ) -GEN_EMIT(TEST_VC) -GEN_EMIT(TEST_VS) -GEN_EMIT(TEST_PL) -GEN_EMIT(TEST_MI) -GEN_EMIT(TEST_GE) -GEN_EMIT(TEST_LT) -GEN_EMIT(TEST_GT) -GEN_EMIT(TEST_LE) - -/* ALU operations */ -GEN_EMIT(MOVE_B) -GEN_EMIT(MOVE_W) -GEN_EMIT(MOVE_L) -GEN_EMIT(ADD_B) -GEN_EMIT(ADD_W) -GEN_EMIT(ADD_L) -GEN_EMIT(ADDA_W) -GEN_EMIT(ADDX_B) -GEN_EMIT(ADDX_W) -GEN_EMIT(ADDX_L) -GEN_EMIT(SUB_B) -GEN_EMIT(SUB_W) -GEN_EMIT(SUB_L) -GEN_EMIT(SUBA_W) -GEN_EMIT(SUBX_B) -GEN_EMIT(SUBX_W) -GEN_EMIT(SUBX_L) -GEN_EMIT(MULS_W) -GEN_EMIT(MULU_W) -GEN_EMIT(DIVS_W) -GEN_EMIT(DIVU_W) -GEN_EMIT(AND_B) -GEN_EMIT(AND_W) -GEN_EMIT(AND_L) -GEN_EMIT(OR_B) -GEN_EMIT(OR_W) -GEN_EMIT(OR_L) -GEN_EMIT(EOR_B) -GEN_EMIT(EOR_W) -GEN_EMIT(EOR_L) -GEN_EMIT(EXT_W) -GEN_EMIT(EXT_L) -GEN_EMIT(SWAP) - -/* BCD operations */ -GEN_EMIT(ABCD) -GEN_EMIT(SBCD) - -/* Bit-twiddling operations */ -GEN_EMIT(BTST_B) -GEN_EMIT(BTST_L) -GEN_EMIT(BCHG) -GEN_EMIT(BCLR) -GEN_EMIT(BSET) - -/* Shift/rotate operations */ -GEN_EMIT(ASL_B) -GEN_EMIT(ASL_W) -GEN_EMIT(ASL_L) -GEN_EMIT(ASR_B) -GEN_EMIT(ASR_W) -GEN_EMIT(ASR_L) -GEN_EMIT(LSL_B) -GEN_EMIT(LSL_W) -GEN_EMIT(LSL_L) -GEN_EMIT(LSR_B) -GEN_EMIT(LSR_W) -GEN_EMIT(LSR_L) -GEN_EMIT(ROXL_B) -GEN_EMIT(ROXL_W) -GEN_EMIT(ROXL_L) -GEN_EMIT(ROXR_B) -GEN_EMIT(ROXR_W) -GEN_EMIT(ROXR_L) -GEN_EMIT(ROL_B) -GEN_EMIT(ROL_W) -GEN_EMIT(ROL_L) -GEN_EMIT(ROR_B) -GEN_EMIT(ROR_W) -GEN_EMIT(ROR_L) - -/* Conditional and branch operations ("branch_offset" parameter receives - * the native offset of the branch to update when resolving, or -1 if not - * supported) */ -GEN_EMIT(Scc) -GEN_EMIT(ADD_CYCLES_Scc_Dn) -GEN_EMIT_2(DBcc, uint8_t, reg4, int32_t, target) -GEN_EMIT_3(DBcc_native, uint8_t, reg4, int32_t, target, int32_t, native_disp) -#ifdef CPU_X64 -# define SIZE_DBcc_native JIT_X64SIZE_DBcc_native -#else -# define SIZE_DBcc_native JIT_X86SIZE_DBcc_native -#endif -#define JIT_EMIT_DBcc_native(entry,reg4,target,offset) do { \ - Q68JitEntry *__entry = (entry); \ - int32_t __fragment_end = __entry->native_length + SIZE_DBcc_native; \ - JIT_EMIT_DBcc_native(__entry, (reg4), (target), \ - (offset) - __fragment_end); \ -} while (0) -GEN_EMIT_1(Bcc, int32_t, target) -#define JIT_EMIT_Bcc(entry,target,branch_offset) do { \ - JIT_EMIT_Bcc((entry), (target)); \ - *(branch_offset) = -1; \ -} while (0) -GEN_EMIT_2(Bcc_native, int32_t, target, int32_t, native_disp) -#ifdef CPU_X64 -# define SIZE_Bcc_native JIT_X64SIZE_Bcc_native -#else -# define SIZE_Bcc_native JIT_X86SIZE_Bcc_native -#endif -#define JIT_EMIT_Bcc_native(entry,target,native) do { \ - Q68JitEntry *__entry = (entry); \ - int32_t __fragment_end = __entry->native_length + SIZE_Bcc_native; \ - JIT_EMIT_Bcc_native(__entry, (target), (offset) - __fragment_end); \ -} while (0) -GEN_EMIT_2(BSR, uint32_t, return_addr, int32_t, target) -GEN_EMIT(JMP) -GEN_EMIT_1(JSR, uint32_t, return_addr) - -/* MOVEM-related operations */ -GEN_EMIT_1(STORE_DEC_W, uint8_t, reg4) -GEN_EMIT_1(STORE_DEC_L, uint8_t, reg4) -GEN_EMIT_1(STORE_INC_W, uint8_t, reg4) -GEN_EMIT_1(STORE_INC_L, uint8_t, reg4) -GEN_EMIT_1(LOAD_INC_W, uint8_t, reg4) -GEN_EMIT_1(LOAD_INC_L, uint8_t, reg4) -GEN_EMIT_1(LOADA_INC_W, uint8_t, reg4) -GEN_EMIT_1(MOVEM_WRITEBACK, uint8_t, reg4) - -/* Miscellaneous operations */ -GEN_EMIT(CHK_W) -GEN_EMIT_1(LEA, uint8_t, reg4) -GEN_EMIT(PEA) -GEN_EMIT(TAS) -GEN_EMIT_1(MOVE_FROM_USP, uint8_t, reg4) -GEN_EMIT_1(MOVE_TO_USP, uint8_t, reg4) -GEN_EMIT_1(STOP, uint16_t, newSR) -GEN_EMIT(TRAPV) -GEN_EMIT(RTS) -GEN_EMIT(RTR) -GEN_EMIT(RTE) -GEN_EMIT_3(MOVEP_READ_W, uint8_t, areg4, int32_t, disp, uint8_t, dreg4) -GEN_EMIT_3(MOVEP_READ_L, uint8_t, areg4, int32_t, disp, uint8_t, dreg4) -GEN_EMIT_3(MOVEP_WRITE_W, uint8_t, areg4, int32_t, disp, uint8_t, dreg4) -GEN_EMIT_3(MOVEP_WRITE_L, uint8_t, areg4, int32_t, disp, uint8_t, dreg4) -GEN_EMIT_2(EXG, uint8_t, reg1_4, uint8_t, reg2_4) - -/*************************************************************************/ - -#endif // Q68_JIT_X86_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68-jit.c b/yabause/src/q68/q68-jit.c deleted file mode 100644 index a1c2348e3b..0000000000 --- a/yabause/src/q68/q68-jit.c +++ /dev/null @@ -1,3722 +0,0 @@ -/* src/q68/q68-jit.c: Dynamic translation support for Q68 - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include - -#include "q68.h" -#include "q68-const.h" -#include "q68-internal.h" -#include "q68-jit.h" - -/*************************************************************************/ - -/* - * Dynamic translation of 68000 instructions into native code is performed - * as follows: - * - * 1) The emulation core (q68-core.c) calls q68_jit_find() on the current - * PC to check whether there is a translated block starting at that - * address. - * - * 2) If no translated block exists, the emulation core calls - * q68_jit_translate() to translate a block beginning at the current - * PC. q68_jit_translate() continues translating through the end of - * the block of code (determined heuristically) and returns the - * translated block to be passed to q68_jit_run(). - * - * 3) If a translated block exists or was just created, the emulation core - * calls q68_jit_run() to begin execution of the translated code. - * - * 4) The translated code returns either when it reaches the end of the - * block, or when the number of cycles executed exceeds the requested - * cycle count. (For efficiency, cycle count checks are only performed - * before branching instructions: BRA, BSR, Bcc, DBcc, JMP, JSR, RTS, - * RTE, RTR, TRAP, STOP.) - * - * 5) If the translated code returns before the end of the block, the core - * continues to call q68_jit_run() until the end of the block is - * reached. - * - * 6) If a write is made to a region of memory containing one or more - * translated blocks, the core deletes the translations by calling - * q68_jit_clear_page() so the modified code can be retranslated. - * Writes originating in the translated code itself (i.e. self-modifying - * code) are handled by the native code calling q68_jit_clear_write() - * when detecting a write to a page containing translations. - * - * The amount of translated code which can be stored at one time is - * dependent upon two factors: the size of the hash table (set by the - * Q68_JIT_TABLE_SIZE define in q68-const.h) and the maximum translated - * data size (set by the Q68_JIT_DATA_LIMIT define). If either the hash - * table becomes full or the data size limit is reached, any subsequent - * translation will cause the oldest existing translation to be deleted, - * where "oldest" is defined as "last executed the greatest number of - * q68_jit_run() calls ago". Note that the data size limit is checked only - * when beginning a translation, so the total data size at the end of a - * translation may slightly exceed the specified limit. - * - * ======================================================================== - * - * Native code is generated through calls to JIT_EMIT_*() routines. - * Typically, these routines will copy a pre-assembled code fragment to the - * native code buffer, then patch that code fragment with values specific - * to the instruction being translated (such as register numbers or branch - * targets). The general sequence of operations emitted is as follows: - * - * JIT_EMIT_RESOLVE_* -- resolves an effective address to a 68000 - * memory location - * JIT_EMIT_GET_OP1_* -- loads the first operand for an instruction - * JIT_EMIT_GET_OP2_* -- loads the second operand for an instruction - * JIT_EMIT_TEST_* -- tests the state of condition codes - * JIT_EMIT_(insn) -- executes the instruction itself - * JIT_EMIT_SETCC_* -- updates the 68000 condition codes - * JIT_EMIT_SET_* -- stores the result of the instruction - * JIT_EMIT_ADD_CYCLES -- increments the count of clock cycles executed(*) - * JIT_EMIT_ADVANCE_PC -- increments the program counter register(*) - * - * (*) In some cases, particularly when the instruction may cause execution - * of the block to terminate, these operations will occur earlier in - * the sequence. The code generator takes responsibility for ensuring - * that such updates happen in the proper order. - * - * The code generator guarantees that the following invariants hold: - * - * - No operations which could result in a 68000 memory access will be - * generated between loading of the second operand (JIT_EMIT_GET_OP2_*) - * and execution of the instruction. - * - * - A JIT_EMIT_TEST_* operation will always be followed immediately by - * the instruction which uses the operation (such as JIT_EMIT_Scc). - * - * - A JIT_EMIT_SETCC_* operation will always immediately follow the - * operation which produced the result it is testing. - * - * The machine-dependent implementations must obey the following rules: - * - * - Each write to memory must be preceded by a check for translated code - * at the target address (by checking state->jit_pages[]) and a call to - * q68_jit_clear_write() if any translations are found. - * (Implementations may violate this rule in circumstances considered - * unlikely, at the risk of incorrect behavior if such circumstances - * actually occur; for example, the PSP implementation does not check - * for a longword write overlapping the end of a JIT page, and does not - * check writes from the MOVEM instruction.) - * - * - Any instruction which modifies the program counter (Bcc, etc.) must - * terminate execution of the native code block, _except for_ the - * following instructions: - * JMP, RTE, RTR, RTS - * - * - Any instruction which raises an exception must do so by storing the - * appropriate exception number in state->exception and terminating - * execution of the native code block. - * - * - It is the responsibility of the native code to check for a pending - * unmasked interrupt when modifying the status register. - * - * The BSR/JSR and RTS/RTR instructions may make use of a call stack - * provided by the JIT core to allow native code to quickly return to the - * point at which a subroutine call took place. The BSR and JSR - * implementations should, when they terminate execution, return a pointer - * to the following native code (as for termination in CHECK_CYCLES), and - * should set bit 15 of the cycle count returned from JIT_CALL(); - * q68_jit_run() will detect this as a subroutine call, and save the native - * code pointer returned before switching to the subroutine block. The RTS - * and RTR implementations should set bits 15 and 14 of the cycle count - * they return, which will cause q68_jit_run() to search the call stack - * from top to bottom for an entry matching the new 68000 PC; if one is - * found, the corresponding code will be immediately executed, bypassing - * the ordinary block search and execution process (steps 1 through 3 - * above). - * - * See the q68-jit-*.[hS] files for implementation details. - * - * ======================================================================== - * - * The JIT code generator includes a primitive optimization step (if the - * Q68_JIT_OPTIMIZE_FLAGS preprocessor symbol is defined) which omits the - * generation of code to set the 68000 condition flags (X, N, Z, V, and C) - * when unnecessary for correct execution. Specifically, the translator - * checks both the current and the following instruction to determine if - * there are any condition flags which are: - * - set by the current instruction, AND - * - used as input by the following instruction OR - * - NOT set by the following instruction - * If there are no such flags, then it is impossible for the flag values - * set by the current instruction to have any effect on program flow, so - * the native code to set the condition codes can be safely omitted. - * - * The above logic is contained in the cc_needed() routine (and its helper - * routine cc_info()). For each instruction that can set the condition - * flags, the translation routine first calls cc_needed() to determine - * whether the condition flags need to be set or not. If cc_needed() - * returns zero, then there are no flags whose output is required, and the - * relevant JIT_EMIT_SETCC_* operation will be skipped. - * - * In the interests of speed and code clarity, the helper routine cc_info() - * does not check the validity of the opcode passed to it; as a result, it - * may return invalid flag information for some invalid opcodes. If such - * an invalid opcode actually occurs in the instruction stream, the CCR - * register may therefore contain an incorrect value when control is - * transferred to the illegal instruction exception handler. In situations - * where this can cause undesired behavior, this optimization should be - * disabled. - * - * When Q68_JIT_OPTIMIZE_FLAGS is not defined, the definitions of - * cc_needed() and cc_info() are omitted, and cc_needed() is instead - * defined at the preprocessor level to return 1; this has the effect of - * always emitting code to set the condition flags. - */ - -/*************************************************************************/ - -/* For the PSP, we need to avoid local data here sharing a cache line with - * data in other files due to the lack of SC/ME cache coherency */ -#ifdef PSP -static __attribute__((aligned(64),used)) int dummy_top; -#endif - -/*----------------------------------*/ - -/* Entry into which translated code is currently being stored (set by - * q68_jit_translate(), used by opcode translation functions) */ -static Q68JitEntry *current_entry; - -/* Address from which data is being read */ -static uint32_t jit_PC; - -/* Flag indicating whether the PC was updated by an instruction (e.g. jumps) */ -static int PC_updated; - -/* Branch target lookup table (indicates where in the native code each - * address is located) */ -static struct { - uint32_t m68k_address; // Address of 68000 instruction - uint32_t native_offset; // Byte offset into current_entry->native_code -} btcache[Q68_JIT_BTCACHE_SIZE]; -static unsigned int btcache_index; // Where to store the next instruction - -/* Unresolved branch list (saves locations and targets of forward branches) */ -static struct { - uint32_t m68k_target; // Branch target (68000 address) - uint32_t native_offset; // Offset of native branch instruction to update -} unres_branches[Q68_JIT_UNRES_BRANCH_SIZE]; - -/*----------------------------------*/ - -#ifdef PSP // As above -static __attribute__((aligned(64),used)) int dummy_bottom; -#endif - -/*-----------------------------------------------------------------------*/ - -/* Redefine IFETCH to reference jit_PC */ - -static inline uint32_t jit_IFETCH(Q68State *state) { - uint32_t data = READU16(state, jit_PC); - jit_PC += 2; - return data; -} -#define IFETCH jit_IFETCH - -/*************************************************************************/ - -/* - * Forward declarations for helper functions and instruction implementations. - * These are set up identically to q68-core.c so that bugfixes or other - * changes to one can be easily ported to the other. - * - * Note that the return value of OpcodeFunc is taken to be the end-of-block - * flag as returned from q68_jit_translate(), not the number of clock cycles - * taken by the instruction. - */ - -static int translate_insn(Q68State *state, Q68JitEntry *entry); -static void clear_entry(Q68State *state, Q68JitEntry *entry); -static void clear_oldest_entry(Q68State *state); -static int expand_buffer(Q68JitEntry *entry); -static int32_t btcache_lookup(uint32_t address); -static void record_unresolved_branch(uint32_t m68k_target, - uint32_t native_offset); -static inline void JIT_EMIT_TEST_cc(int cond, Q68JitEntry *entry); -static void advance_PC(Q68State *state); -static int raise_exception(Q68State *state, uint8_t num); -static inline int op_ill(Q68State *state, uint32_t opcode); - -#ifdef Q68_JIT_OPTIMIZE_FLAGS -static unsigned int cc_needed(Q68State *state, uint16_t opcode); -# ifdef __GNUC__ -__attribute__((const)) -# endif -static unsigned int cc_info(uint16_t opcode); -#else -# define cc_needed(state,opcode) 1 -#endif - -static int ea_resolve(Q68State *state, uint32_t opcode, int size, - int access_type); -static void ea_get(Q68State *state, uint32_t opcode, int size, - int is_rmw, int *cycles_ret, int op_num); -static void ea_set(Q68State *state, uint32_t opcode, int size); - -static int op_imm(Q68State *state, uint32_t opcode); -static int op_bit(Q68State *state, uint32_t opcode); -static int opMOVE(Q68State *state, uint32_t opcode); -static int op4xxx(Q68State *state, uint32_t opcode); -static int op_CHK(Q68State *state, uint32_t opcode); -static int op_LEA(Q68State *state, uint32_t opcode); -static int opADSQ(Q68State *state, uint32_t opcode); -static int op_Scc(Q68State *state, uint32_t opcode); -static int opDBcc(Q68State *state, uint32_t opcode); -static int op_Bcc(Q68State *state, uint32_t opcode); -static int opMOVQ(Q68State *state, uint32_t opcode); -static int op_alu(Q68State *state, uint32_t opcode); -static int op_DIV(Q68State *state, uint32_t opcode); -static int opAxxx(Q68State *state, uint32_t opcode); -static int op_MUL(Q68State *state, uint32_t opcode); -static int opshft(Q68State *state, uint32_t opcode); -static int opFxxx(Q68State *state, uint32_t opcode); - -static int op4alu(Q68State *state, uint32_t opcode); -static int opMVSR(Q68State *state, uint32_t opcode); -static int opNBCD(Q68State *state, uint32_t opcode); -static int op_PEA(Q68State *state, uint32_t opcode); -static int opSWAP(Q68State *state, uint32_t opcode); -static int op_TAS(Q68State *state, uint32_t opcode); -static int op_EXT(Q68State *state, uint32_t opcode); -static int op_STM(Q68State *state, uint32_t opcode); -static int op_LDM(Q68State *state, uint32_t opcode); -static int opmisc(Q68State *state, uint32_t opcode); -static int opTRAP(Q68State *state, uint32_t opcode); -static int opLINK(Q68State *state, uint32_t opcode); -static int opUNLK(Q68State *state, uint32_t opcode); -static int opMUSP(Q68State *state, uint32_t opcode); -static int op4E7x(Q68State *state, uint32_t opcode); -static int opjump(Q68State *state, uint32_t opcode); - -static int opMOVP(Q68State *state, uint32_t opcode); -static int opADSX(Q68State *state, uint32_t opcode); -static int op_BCD(Q68State *state, uint32_t opcode); -static int opCMPM(Q68State *state, uint32_t opcode); -static int op_EXG(Q68State *state, uint32_t opcode); - -/*-----------------------------------------------------------------------*/ - -/* Main table of instruction implemenation functions; table index is bits - * 15-12 and 8-6 of the opcode (ABCD ...E FG.. .... -> 0ABC DEFG). */ -static OpcodeFunc * const opcode_table[128] = { - op_imm, op_imm, op_imm, op_imm, op_bit, op_bit, op_bit, op_bit, // 00 - opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, // 10 - opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, // 20 - opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, opMOVE, // 30 - - op4xxx, op4xxx, op4xxx, op4xxx, op_ill, op_ill, op_CHK, op_LEA, // 40 - opADSQ, opADSQ, opADSQ, op_Scc, opADSQ, opADSQ, opADSQ, op_Scc, // 50 - op_Bcc, op_Bcc, op_Bcc, op_Bcc, op_Bcc, op_Bcc, op_Bcc, op_Bcc, // 60 - opMOVQ, opMOVQ, opMOVQ, opMOVQ, op_ill, op_ill, op_ill, op_ill, // 70 - - op_alu, op_alu, op_alu, op_DIV, op_alu, op_alu, op_alu, op_DIV, // 80 - op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, // 90 - opAxxx, opAxxx, opAxxx, opAxxx, opAxxx, opAxxx, opAxxx, opAxxx, // A0 - op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, // B0 - - op_alu, op_alu, op_alu, op_MUL, op_alu, op_alu, op_alu, op_MUL, // C0 - op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, op_alu, // D0 - opshft, opshft, opshft, opshft, opshft, opshft, opshft, opshft, // E0 - opFxxx, opFxxx, opFxxx, opFxxx, opFxxx, opFxxx, opFxxx, opFxxx, // F0 -}; - -/* Subtable for instructions in the $4xxx (miscellaneous) group; table index - * is bits 11-9 and 7-6 of the opcode (1000 ABC0 DE.. .... -> 000A BCDE). */ -static OpcodeFunc * const opcode_4xxx_table[32] = { - op4alu, op4alu, op4alu, opMVSR, // 40xx - op4alu, op4alu, op4alu, op_ill, // 42xx - op4alu, op4alu, op4alu, opMVSR, // 44xx - op4alu, op4alu, op4alu, opMVSR, // 46xx - opNBCD, op_PEA, op_STM, op_STM, // 48xx - op4alu, op4alu, op4alu, op_TAS, // 4Axx - op_ill, op_ill, op_LDM, op_LDM, // 4Cxx - op_ill, opmisc, opjump, opjump, // 4Exx -}; - -/* Sub-subtable for instructions in the $4E40-$4E7F range, used by opmisc(); - * index is bits 5-3 of the opcode. */ -static OpcodeFunc * const opcode_4E4x_table[8] = { - opTRAP, opTRAP, opLINK, opUNLK, - opMUSP, opMUSP, op4E7x, op_ill, -}; - -/*************************************************************************/ - -/* Include the header appropriate to the platform (make sure to do this - * after the local function declarations) */ - -#if defined(CPU_X86) || defined(CPU_X64) -# include "q68-jit-x86.h" -#elif defined(CPU_PSP) -# include "q68-jit-psp.h" -#else -# error Dynamic translation is not supported on this platform -#endif - -/*************************************************************************/ -/********************** External interface routines **********************/ -/*************************************************************************/ - -/** - * q68_jit_init: Allocate memory for JIT data. Must be called before any - * other JIT function. - * - * [Parameters] - * state: Processor state block - * [Return value] - * Nonzero on success, zero on error - */ -int q68_jit_init(Q68State *state) -{ - state->jit_table = - state->malloc_func(sizeof(*state->jit_table) * Q68_JIT_TABLE_SIZE); - if (!state->jit_table) { - DMSG("No memory for JIT table"); - goto error_return; - } - state->jit_hashchain = - state->malloc_func(sizeof(*state->jit_hashchain) * Q68_JIT_TABLE_SIZE); - if (!state->jit_hashchain) { - DMSG("No memory for JIT hash chain table"); - goto error_free_jit_table; - } - - /* Make sure all entries are marked as unused (so we don't try to free - * invalid pointers in q68_jit_reset()) */ - int i; - for (i = 0; i < Q68_JIT_TABLE_SIZE; i++) { - state->jit_table[i].m68k_start = 0; - } - - /* Make sure page table is clear (so writes before processor reset - * don't trigger JIT clearing */ - memset(state->jit_pages, 0, sizeof(state->jit_pages)); - - /* Default to no cache flush function */ - state->jit_flush = NULL; - -#ifdef Q68_DISABLE_ADDRESS_ERROR - /* Hack to avoid compiler warnings about unused functions */ - if (0) { - JIT_EMIT_CHECK_ALIGNED_EA(&state->jit_table[0], 0, 0); - JIT_EMIT_CHECK_ALIGNED_SP(&state->jit_table[0], 0, 0); - } -#endif - - return 1; - - error_free_jit_table: - state->free_func(state->jit_table); - state->jit_table = NULL; - error_return: - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_jit_reset: Reset the dynamic translation state, clearing out all - * previously stored data. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -void q68_jit_reset(Q68State *state) -{ - int index; - - state->jit_abort = 0; - for (index = 0; index < Q68_JIT_TABLE_SIZE; index++) { - if (state->jit_table[index].m68k_start) { - clear_entry(state, &state->jit_table[index]); - } - } - for (index = 0; index < Q68_JIT_TABLE_SIZE; index++) { - state->jit_hashchain[index] = NULL; - } - state->jit_total_data = 0; - state->jit_timestamp = 0; - for (index = 0; index < Q68_JIT_BLACKLIST_SIZE; index++) { - state->jit_blacklist[index].m68k_start = 0; - state->jit_blacklist[index].m68k_end = 0; - } - state->jit_in_blist = 0; - state->jit_blist_num = 0; - state->jit_callstack_top = 0; - memset(state->jit_pages, 0, sizeof(state->jit_pages)); -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_jit_cleanup: Destroy all JIT-related data. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -void q68_jit_cleanup(Q68State *state) -{ - q68_jit_reset(state); - state->free_func(state->jit_hashchain); - state->jit_hashchain = NULL; - state->free_func(state->jit_table); - state->jit_table = NULL; -} - -/*************************************************************************/ - -/** - * q68_jit_translate: Dynamically translate a block of instructions - * starting at the given address. If a translation already exists for the - * given address, it is cleared. - * - * [Parameters] - * state: Processor state block - * address: Start address in 68000 address space - * [Return value] - * Translated block to be passed to q68_jit_run(), or NULL on error - */ -Q68JitEntry *q68_jit_translate(Q68State *state, uint32_t address) -{ - int index; - - if (address == 0) { - /* We use address 0 to indicate an unused entry, so we can't - * translate from address 0. But this should never happen except - * in pathological cases (or unhandled exceptions), so just punt - * and let the interpreter handle it */ - return NULL; - } - if (address & 1) { - /* Odd addresses are invalid, so we can't translate them in the - * first place */ - return NULL; - } - address &= 0xFFFFFF; - - /* Check whether we're trying to translate a blacklisted address. */ - - if (state->jit_in_blist) { - index = state->jit_blist_num; - /* See whether we've exited the blacklisted block */ - if (address >= state->jit_blacklist[index].m68k_start - && address <= state->jit_blacklist[index].m68k_end - ) { - return NULL; - } - state->jit_in_blist = 0; - } // We might have entered another blacklisted block, so no "else" here - - if (!state->jit_in_blist) { - /* See if we're in a blacklisted block, and skip its translation - * if so */ - for (index = 0; index < Q68_JIT_BLACKLIST_SIZE; index++) { - if (address >= state->jit_blacklist[index].m68k_start - && address <= state->jit_blacklist[index].m68k_end - ) { - uint32_t dt = state->jit_timestamp - - state->jit_blacklist[index].timestamp; - if (dt < Q68_JIT_BLACKLIST_TIMEOUT) { - state->jit_in_blist = 1; - state->jit_blist_num = index; - return NULL; - } else { - /* Entry expired, so clear it */ - state->jit_blacklist[index].m68k_start = 0; - state->jit_blacklist[index].m68k_end = 0; - } - } - } - } - - /* Clear out any existing translation, then search for an empty slot in - * the hash table. If we've reached the data size limit, first evict - * old entries until we're back under the limit. */ - q68_jit_clear(state, address); - while (state->jit_total_data >= Q68_JIT_DATA_LIMIT) { - clear_oldest_entry(state); - } - const int hashval = JIT_HASH(address); - index = hashval; - int oldest = index; - while (state->jit_table[index].m68k_start != 0) { - if (TIMESTAMP_COMPARE(state->jit_timestamp, - state->jit_table[index].timestamp, - state->jit_table[oldest].timestamp) < 0) { - oldest = index; - } - index++; - /* Using an if here is faster than taking the remainder with % */ - if (UNLIKELY(index >= Q68_JIT_TABLE_SIZE)) { - index = 0; - } - if (UNLIKELY(index == hashval)) { - /* Out of entries, so clear the oldest one and use it */ -#ifdef Q68_JIT_VERBOSE - DMSG("No free slots for code at $%06X, clearing oldest ($%06X)", - (int)address, (int)state->jit_table[oldest].m68k_start); -#endif - clear_entry(state, &state->jit_table[oldest]); - index = oldest; - } - } - current_entry = &state->jit_table[index]; - - /* Initialize the new entry */ - - current_entry->native_code = state->malloc_func(Q68_JIT_BLOCK_EXPAND_SIZE); - if (!current_entry->native_code) { - DMSG("No memory for code at $%06X", address); - current_entry = NULL; - return NULL; - } - current_entry->next = state->jit_hashchain[hashval]; - if (state->jit_hashchain[hashval]) { - state->jit_hashchain[hashval]->prev = current_entry; - } - state->jit_hashchain[hashval] = current_entry; - current_entry->prev = NULL; - current_entry->state = state; - current_entry->m68k_start = address; - current_entry->native_size = Q68_JIT_BLOCK_EXPAND_SIZE; - current_entry->native_length = 0; - current_entry->exec_address = NULL; - current_entry->timestamp = state->jit_timestamp; - current_entry->must_clear = 0; - JIT_EMIT_PROLOGUE(current_entry); - - /* Clear out the branch target cache and unresolved branch list */ - for (index = 0; index < lenof(btcache); index++) { - btcache[index].m68k_address = 0; - } - btcache_index = 0; - for (index = 0; index < lenof(unres_branches); index++) { - unres_branches[index].m68k_target = 0; - } - - /* Translate a block of 68000 code */ - - jit_PC = address; - const uint32_t limit = address + Q68_JIT_MAX_BLOCK_SIZE; - int done = 0; - while (!done && jit_PC < limit) { - /* Make sure we haven't entered a blacklisted block */ - for (index = 0; index < Q68_JIT_BLACKLIST_SIZE; index++) { - if (UNLIKELY(address >= state->jit_blacklist[index].m68k_start - && address <= state->jit_blacklist[index].m68k_end) - ) { - const uint32_t age = state->jit_timestamp - - state->jit_blacklist[index].timestamp; - if (age < Q68_JIT_BLACKLIST_TIMEOUT) { - done = 1; - break; - } else { - /* Entry expired, so clear it */ - state->jit_blacklist[index].m68k_start = 0; - state->jit_blacklist[index].m68k_end = 0; - } - } - } - if (LIKELY(!done)) { - done = translate_insn(state, current_entry); - } - } - - /* Close out the translated block */ - - JIT_EMIT_EPILOGUE(current_entry); - current_entry->m68k_end = jit_PC - 1; - for (index = current_entry->m68k_start >> Q68_JIT_PAGE_BITS; - index <= current_entry->m68k_end >> Q68_JIT_PAGE_BITS; - index++ - ) { - JIT_PAGE_SET(state, index); - } - void *newptr = state->realloc_func(current_entry->native_code, - current_entry->native_length); - if (newptr) { - current_entry->native_code = newptr; - current_entry->native_size = current_entry->native_length; - } - state->jit_total_data += current_entry->native_size; - /* Prepare the block for execution so it can be immediately passed to - * q68_jit_run() (see q68_jit_find() for why we do it here) */ - current_entry->exec_address = current_entry->native_code; - - Q68JitEntry *retval = current_entry; - current_entry = NULL; - if (state->jit_flush) { - state->jit_flush(); - } - return retval; -} - -/*************************************************************************/ - -/** - * q68_jit_find: Find the translated block for a given address, if any. - * - * [Parameters] - * state: Processor state block - * address: Start address in 68000 address space - * [Return value] - * Translated block to be passed to q68_jit_run(), or NULL if no such - * block exists - */ -Q68JitEntry *q68_jit_find(Q68State *state, uint32_t address) -{ - const int hashval = JIT_HASH(address); - Q68JitEntry *entry = state->jit_hashchain[hashval]; - while (entry) { - if (entry->m68k_start == address) { - /* Prepare the block for execution. We set exec_address here - * both to avoid overhead in q68_jit_run(), and because - * exec_address could be non-NULL if (for example) the native - * code stopped due to reaching the cycle limit and the core - * then serviced an interrupt. */ - entry->exec_address = entry->native_code; - return entry; - } - entry = entry->next; - } - return NULL; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_jit_run: Run translated 68000 code. - * - * [Parameters] - * state: Processor state block - * cycle_limit: Clock cycle limit on execution (code will stop when - * state->cycles >= cycles) - * address_ptr: Pointer to translated block to execute; will be cleared - * to NULL on return if the end of the block was reached - * [Return value] - * None - */ -void q68_jit_run(Q68State *state, uint32_t cycle_limit, - Q68JitEntry **entry_ptr) -{ - Q68JitEntry *entry = *entry_ptr; - - again: - entry->timestamp = state->jit_timestamp; - state->jit_timestamp++; - entry->running = 1; - int cycles = JIT_CALL(state, cycle_limit - state->cycles, - &entry->exec_address); - entry->running = 0; - state->jit_abort = 0; - state->cycles += cycles & 0x3FFF; - - if (UNLIKELY(entry->must_clear)) { - clear_entry(state, entry); - entry = NULL; - } else if (cycles & 0x8000) { // BSR/JSR/RTS/RTR - if (cycles & 0x4000) { // RTS/RTR - entry = NULL; - unsigned int top = state->jit_callstack_top; - unsigned int i; - for (i = Q68_JIT_CALLSTACK_SIZE; i > 0; i--) { - top = (top + Q68_JIT_CALLSTACK_SIZE-1) % Q68_JIT_CALLSTACK_SIZE; - if (state->jit_callstack[top].return_PC == state->PC) { - entry = state->jit_callstack[top].return_entry; - entry->exec_address = - state->jit_callstack[top].return_native; - state->jit_callstack_top = top; - if (state->cycles < cycle_limit) { - goto again; - } else { - break; - } - } - } - } else { // BSR/JSR - const unsigned int top = state->jit_callstack_top; - const uint32_t return_PC = READU32(state, state->A[7]); - state->jit_callstack[top].return_PC = return_PC; - state->jit_callstack[top].return_entry = entry; - state->jit_callstack[top].return_native = entry->exec_address; - state->jit_callstack_top = (top+1) % Q68_JIT_CALLSTACK_SIZE; - entry = NULL; - } - } else if (!entry->exec_address) { - entry = NULL; - } - - /* If we finished a block, we still have cycles to go, there's no - * exception pending, and there's already a translated block at the - * next PC, jump right to it so we don't incur the extra overhead of - * returning to the caller */ - if (!entry && state->cycles < cycle_limit && !state->exception) { - entry = q68_jit_find(state, state->PC); - if (entry) { - goto again; - } - } - - *entry_ptr = entry; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_jit_clear: Clear any translation beginning at the given address. - * - * [Parameters] - * state: Processor state block - * address: Start address in 68000 address space - * [Return value] - * None - */ -void q68_jit_clear(Q68State *state, uint32_t address) -{ - const int hashval = JIT_HASH(address); - Q68JitEntry *entry = state->jit_hashchain[hashval]; - while (entry) { - if (entry->m68k_start == address) { - clear_entry(state, entry); - return; - } - entry = entry->next; - } -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_jit_clear_page: Clear any translation which occurs in the JIT page - * containing the given address. Intended for use on writes from external - * sources. - * - * [Parameters] - * state: Processor state block - * address: Address to which data was written - * [Return value] - * None - */ -void q68_jit_clear_page(Q68State *state, uint32_t address) -{ - const uint32_t page = address >> Q68_JIT_PAGE_BITS; -#ifdef Q68_JIT_VERBOSE - DMSG("WARNING: jit_clear_page($%06X)", page << Q68_JIT_PAGE_BITS); -#endif - - int index; - for (index = 0; index < Q68_JIT_TABLE_SIZE; index++) { - if (state->jit_table[index].m68k_start != 0 - && state->jit_table[index].m68k_start >> Q68_JIT_PAGE_BITS <= page - && state->jit_table[index].m68k_end >> Q68_JIT_PAGE_BITS >= page - ) { - if (UNLIKELY(state->jit_table[index].running)) { - state->jit_table[index].must_clear = 1; - state->jit_abort = 1; - } else { - clear_entry(state, &state->jit_table[index]); - } - } - } - - JIT_PAGE_CLEAR(state, page); -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_jit_clear_write: Clear any translation which includes the given - * address, and (if there is at least one such translation) blacklist the - * address from being translated. - * - * [Parameters] - * state: Processor state block - * address: Address to which data was written - * size: Size of data written - * [Return value] - * None - */ -void q68_jit_clear_write(Q68State *state, uint32_t address, uint32_t size) -{ - int index; - - /* If the address is in a blacklisted block, we don't need to do - * anything (but update the timestamp to extend its timeout) */ - for (index = 0; index < Q68_JIT_BLACKLIST_SIZE; index++) { - if (address >= state->jit_blacklist[index].m68k_start - && address <= state->jit_blacklist[index].m68k_end - ) { - state->jit_blacklist[index].timestamp = state->jit_timestamp; - return; - } - } - - /* Clear the translations-exist flag now; we'll set it later if we - * find a translation on the page that we don't clear */ - const uint32_t page = address >> Q68_JIT_PAGE_BITS; - const uint32_t page_start = page << Q68_JIT_PAGE_BITS; - const uint32_t page_end = ((page+1) << Q68_JIT_PAGE_BITS) - 1; - JIT_PAGE_CLEAR(state, page); - - /* Clear any translations affected by the address, and determine - * the range to be blacklisted. We default to assuming the address is - * the last byte/word of the longest possible instruction (10 bytes: - * MOVE.L #$12345678, ($12345678).l), but do not extend backwards past - * the beginning of a block. */ - int found = 0; - uint32_t start = address + size, end = address + (size-1); -#ifdef Q68_JIT_VERBOSE - DMSG("WARNING: jit_clear_write($%06X,%d)", (int)address, (int)size); -#endif - for (index = 0; index < Q68_JIT_TABLE_SIZE; index++) { - if (state->jit_table[index].m68k_start == 0) { - continue; - } - if (state->jit_table[index].m68k_start < address + size - && state->jit_table[index].m68k_end >= address) { - found = 1; - if (start > state->jit_table[index].m68k_start) { - /* Use the earliest start address of those we see */ - start = state->jit_table[index].m68k_start; - } - if (UNLIKELY(state->jit_table[index].running)) { - state->jit_table[index].must_clear = 1; - state->jit_abort = 1; - } else { - clear_entry(state, &state->jit_table[index]); - } - } else if (state->jit_table[index].m68k_start <= page_start - && state->jit_table[index].m68k_end >= page_end) { - /* No need to clear this one, so set the page bit again */ - JIT_PAGE_SET(state, page); - } - } - if (!found || start < (address & ~1) - 8) { - start = (address & ~1) - 8; - } - - /* Add the blacklist entry */ -#ifdef Q68_JIT_VERBOSE - DMSG("Blacklisting $%06X...$%06X", (int)start, (int)end); -#endif - /* First see if this overlaps with another entry */ - found = 0; - for (index = 0; index < Q68_JIT_BLACKLIST_SIZE; index++) { - if (state->jit_blacklist[index].m68k_start <= end - && state->jit_blacklist[index].m68k_end >= start) { -#ifdef Q68_JIT_VERBOSE - DMSG("(Merging with $%06X...%06X)", - (int)state->jit_blacklist[index].m68k_start, - (int)state->jit_blacklist[index].m68k_end); -#endif - if (start > state->jit_blacklist[index].m68k_start) { - start = state->jit_blacklist[index].m68k_start; - } - if (end < state->jit_blacklist[index].m68k_end) { - end = state->jit_blacklist[index].m68k_end; - } - found = 1; - break; - } - } - /* Otherwise, add this as a new entry; if there are no free slots, - * evict the oldest entry */ - if (!found) { - int oldest = 0; - for (index = 0; index < Q68_JIT_BLACKLIST_SIZE; index++) { - if (state->jit_blacklist[index].m68k_start == 0) { - found = 1; - break; - } else if (TIMESTAMP_COMPARE(state->jit_timestamp, - state->jit_blacklist[index].timestamp, - state->jit_blacklist[oldest].timestamp) < 0) { - oldest = index; - } - } - if (!found) { - index = oldest; - } - } - state->jit_blacklist[index].m68k_start = start; - state->jit_blacklist[index].m68k_end = end; - state->jit_blacklist[index].timestamp = state->jit_timestamp; -} - -/*************************************************************************/ -/************************ Local helper functions *************************/ -/*************************************************************************/ - -/** - * translate_insn: Translate a single 68000 instruction. - * - * [Parameters] - * state: Processor state block - * entry: Q68JitEntry structure pointer - * [Return value] - * Nonzero if the instruction marks the end of the block, else zero - */ -static int translate_insn(Q68State *state, Q68JitEntry *entry) -{ - /* See if there are any branches to this address we can update */ - int i; - for (i = 0; i < lenof(unres_branches); i++) { - if (unres_branches[i].m68k_target == jit_PC) { - JIT_FIXUP_BRANCH(entry, unres_branches[i].native_offset, - current_entry->native_length); - unres_branches[i].m68k_target = 0; - } - } - - /* Update the branch target cache with this address */ - btcache[btcache_index].m68k_address = jit_PC; - btcache[btcache_index].native_offset = current_entry->native_length; - btcache_index = (btcache_index + 1) % lenof(btcache); - - /* Fetch the next instruction */ - const unsigned int opcode = IFETCH(state); - state->current_PC = jit_PC; - - /* Emit a cycle count check if appropriate */ -#ifdef Q68_JIT_LOOSE_TIMING - if ((opcode & 0xFF00) == 0x6100 // Bcc - || (opcode & 0xF0F8) == 0x50C8 // DBcc - || (opcode & 0xFFF0) == 0x4E40 // TRAP - || (opcode & 0xFF80) == 0x4E80 // JSR/JMP - || opcode == 0x4E72 // STOP - || opcode == 0x4E73 // RTE - || opcode == 0x4E75 // RTS - || opcode == 0x4E77 // RTR -# ifdef Q68_M68K_TESTER // Define when linking with m68k-tester - || opcode == 0x7100 // m68k-tester abort opcode -# endif - ) { -#endif - JIT_EMIT_CHECK_CYCLES(current_entry); -#ifdef Q68_JIT_LOOSE_TIMING - } -#endif - - /* Add a trace call if we're tracing */ -#ifdef Q68_TRACE - JIT_EMIT_TRACE(current_entry); -#endif - - /* Translate the instruction itself and update the 68000 PC */ - PC_updated = 0; - const unsigned int index = (opcode>>9 & 0x78) | (opcode>>6 & 0x07); - int done = (*opcode_table[index])(state, opcode); - /* Only update the PC if the function didn't do so itself (see e.g. - * op_imm() to SR), but check the jit_abort flag unless we're - * terminating anyway */ - if (!done) { - if (!PC_updated) { - const int32_t advance = jit_PC - (state->current_PC - 2); - JIT_EMIT_ADVANCE_PC_CHECK_ABORT(current_entry, advance); - } else { - JIT_EMIT_CHECK_ABORT(current_entry); - } - } else { - if (!PC_updated) { - advance_PC(state); - } - } - - return done; -} - -/*************************************************************************/ - -/** - * clear_entry: Clear a specific entry from the JIT table, freeing the - * native code buffer and unlinking the entry from its references. - * - * [Parameters] - * state: Processor state block - * entry: Q68JitEntry structure pointer - * [Return value] - * None - */ -static void clear_entry(Q68State *state, Q68JitEntry *entry) -{ - /* Clear the entry out of the call stack first */ - int i; - for (i = 0; i < Q68_JIT_CALLSTACK_SIZE; i++) { - if (state->jit_callstack[i].return_entry == entry) { - state->jit_callstack[i].return_PC = 0; - } - } - - /* Free the native code */ - state->jit_total_data -= entry->native_size; - state->free_func(entry->native_code); - entry->native_code = NULL; - - /* Clear the entry from the table and hash chain */ - if (entry->next) { - entry->next->prev = entry->prev; - } - if (entry->prev) { - entry->prev->next = entry->next; - } else { - state->jit_hashchain[JIT_HASH(entry->m68k_start)] = entry->next; - } - - /* Mark the entry as free */ - entry->m68k_start = 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * clear_oldest_entry: Clear the oldest entry from the JIT table. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -static void clear_oldest_entry(Q68State *state) -{ - int oldest = -1; - int index; - for (index = 0; index < Q68_JIT_TABLE_SIZE; index++) { - if (state->jit_table[index].m68k_start == 0) { - continue; - } - if (oldest < 0 - || TIMESTAMP_COMPARE(state->jit_timestamp, - state->jit_table[index].timestamp, - state->jit_table[oldest].timestamp) < 0) { - oldest = index; - } - } - if (LIKELY(oldest >= 0)) { - clear_entry(state, &state->jit_table[oldest]); - } else { - DMSG("Tried to clear oldest entry from an empty table!"); - /* Set the total size to zero, just in case something weird happened */ - state->jit_total_data = 0; - } -} - -/*************************************************************************/ - -/** - * expand_buffer: Expands the native code buffer in the given JIT entry by - * Q68_JIT_BLOCK_EXPAND_SIZE. - * - * [Parameters] - * entry: Q68JitEntry structure pointer - * [Return value] - * Nonzero on success, zero on failure (out of memory) - */ -static int expand_buffer(Q68JitEntry *entry) -{ - const uint32_t newsize = entry->native_size + Q68_JIT_BLOCK_EXPAND_SIZE; - void *newptr = entry->state->realloc_func(entry->native_code, newsize); - if (!newptr) { - DMSG("Out of memory"); - return 0; - } - entry->native_code = newptr; - entry->native_size = newsize; - return 1; -} - -/*************************************************************************/ - -/** - * btcache_lookup: Search the branch target cache for the given 68000 - * address. - * - * [Parameters] - * address: 68000 address to search for - * [Return value] - * Corresponding byte offset into current_entry->native_code, or -1 if - * the address could not be found - */ -static int32_t btcache_lookup(uint32_t address) -{ - /* Search backwards from the current instruction so we can handle short - * loops quickly; note that btcache_index is now pointing to where the - * _next_ instruction will go */ - const int current = (btcache_index + (lenof(btcache)-1)) % lenof(btcache); - int index = current; - do { - if (btcache[index].m68k_address == address) { - return btcache[index].native_offset; - } - index = (index + (lenof(btcache)-1)) % lenof(btcache); - } while (index != current); - return -1; -} - -/*-----------------------------------------------------------------------*/ - -/** - * record_unresolved_branch: Record the given branch target and native - * offset in an empty slot in the unresolved branch table. If there are - * no empty slots, purge the oldest (lowest native offset) entry. - * - * [Parameters] - * m68k_target: Branch target address in 68000 address space - * native_offset: Offset of branch to update in native code - * [Return value] - * None - */ -static void record_unresolved_branch(uint32_t m68k_target, - uint32_t native_offset) -{ - int oldest = 0; - int i; - for (i = 0; i < lenof(unres_branches); i++) { - if (unres_branches[i].m68k_target == 0) { - oldest = i; - break; - } else if (unres_branches[i].native_offset - < unres_branches[oldest].native_offset) { - oldest = i; - } - } - unres_branches[oldest].m68k_target = m68k_target; - unres_branches[oldest].native_offset = native_offset; -} - -/*************************************************************************/ - -/** - * JIT_EMIT_TEST_cc: Emit the appropriate TEST_* operation depending on - * the specified condition. - * - * [Parameters] - * cond: Condition code - * entry: Q68JitEntry structure pointer - */ -static inline void JIT_EMIT_TEST_cc(int cond, Q68JitEntry *entry) -{ - switch ((cond)) { - case COND_T: JIT_EMIT_TEST_T (entry); break; - case COND_F: JIT_EMIT_TEST_F (entry); break; - case COND_HI: JIT_EMIT_TEST_HI(entry); break; - case COND_LS: JIT_EMIT_TEST_LS(entry); break; - case COND_CC: JIT_EMIT_TEST_CC(entry); break; - case COND_CS: JIT_EMIT_TEST_CS(entry); break; - case COND_NE: JIT_EMIT_TEST_NE(entry); break; - case COND_EQ: JIT_EMIT_TEST_EQ(entry); break; - case COND_VC: JIT_EMIT_TEST_VC(entry); break; - case COND_VS: JIT_EMIT_TEST_VS(entry); break; - case COND_PL: JIT_EMIT_TEST_PL(entry); break; - case COND_MI: JIT_EMIT_TEST_MI(entry); break; - case COND_GE: JIT_EMIT_TEST_GE(entry); break; - case COND_LT: JIT_EMIT_TEST_LT(entry); break; - case COND_GT: JIT_EMIT_TEST_GT(entry); break; - case COND_LE: JIT_EMIT_TEST_LE(entry); break; - } -} - -/*************************************************************************/ - -/** - * advance_PC: Emit JIT code to advance the PC to the location indicated - * by jit_PC, and set the PC_updated flag so that the PC is not advanced - * again after the current instruction has been processed. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -static void advance_PC(Q68State *state) -{ - JIT_EMIT_ADVANCE_PC(current_entry, jit_PC - (state->current_PC - 2)); - PC_updated = 1; -} - -/*************************************************************************/ - -/** - * raise_exception: Emit JIT code to raise an exception. - * - * [Parameters] - * state: Processor state block - * num: Exception number - * [Return value] - * Nonzero (end translated block) - */ -static int raise_exception(Q68State *state, uint8_t num) -{ - JIT_EMIT_EXCEPTION(current_entry, num); - return 1; -} - -/*************************************************************************/ - -/** - * op_ill: Emit JIT code to handle a generic illegal opcode. - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * [Return value] - * Nonzero (end translated block) - */ -static inline int op_ill(Q68State *state, uint32_t opcode) -{ - return raise_exception(state, EX_ILLEGAL_INSTRUCTION); -} - -/*************************************************************************/ -/*************************************************************************/ - -#ifdef Q68_JIT_OPTIMIZE_FLAGS - -/** - * cc_needed: Return whether any condition code outputs are required from - * the current instruction, based on the instruction located at jit_PC. - * - * This routine assumes that the current and following instructions are - * valid ones; certain illegal forms of instructions may be incorrectly - * treated as valid and thus cause an incorrect result. - * - * [Parameters] - * state: Processor state block - * opcode: Opcode of the instruction currently being processed - * [Return value] - * Nonzero if condition code outputs are required, zero otherwise - */ -static unsigned int cc_needed(Q68State *state, uint16_t opcode) -{ - const uint16_t next_opcode = READU16(state, jit_PC); - const unsigned int this_output = cc_info(opcode) & 0x1F; - const unsigned int next_input = (cc_info(next_opcode) >> 8) & 0x1F; - const unsigned int next_output = cc_info(next_opcode) & 0x1F; - /* A condition code output from this instruction is known to be - * unneeded if the following instruction (1) does not use that - * condition code as input and (2) also outputs to the same condition - * code. We want to know whether there are any condition codes in the - * current instruction's output set for which these conditions are - * _not_ fulfilled. */ - return this_output & ~(~next_input & next_output); -} - -/*************************************************************************/ - -/** - * cc_info: Return a bitmask of which condition codes are used and which - * are modified by the given opcode. - * - * [Parameters] - * opcode: Opcode to check - * [Return value] - * Bits 12-8: Which of XNZVC are used as input by the given opcode - * Bits 4-0: Which of XNZVC are modified by the given opcode - */ -static unsigned int cc_info(uint16_t opcode) -{ - const unsigned int INPUT_XNZVC = 0x1F00; - const unsigned int INPUT_XZ = 0x1400; - const unsigned int INPUT_X = 0x1000; - const unsigned int INPUT_N = 0x0800; - const unsigned int INPUT_V = 0x0200; - const unsigned int INPUT_NONE = 0x0000; - const unsigned int OUTPUT_XNZVC = 0x001F; - const unsigned int OUTPUT_XZC = 0x0015; - const unsigned int OUTPUT_NZVC = 0x000F; - const unsigned int OUTPUT_N = 0x0008; - const unsigned int OUTPUT_Z = 0x0004; - const unsigned int OUTPUT_NONE = 0x0000; - static const unsigned int cond_inputs[] = { - [COND_T ] = 0x0000, - [COND_F ] = 0x0000, - [COND_HI] = 0x0500, - [COND_LS] = 0x0500, - [COND_CC] = 0x0100, - [COND_CS] = 0x0100, - [COND_NE] = 0x0400, - [COND_EQ] = 0x0400, - [COND_VC] = 0x0200, - [COND_VS] = 0x0200, - [COND_PL] = 0x0800, - [COND_MI] = 0x0800, - [COND_GE] = 0x0A00, - [COND_LT] = 0x0A00, - [COND_GT] = 0x0E00, - [COND_LE] = 0x0E00, - }; - - switch (opcode>>12) { - - case 0x0: - if (opcode & 0x100) { - if ((opcode>>3 & 7) == 1) { // MOVEP - return INPUT_NONE | OUTPUT_NONE; - } else { // BTST, etc. (dynamic) - return INPUT_NONE | OUTPUT_Z; - } - } else if ((opcode>>6 & 3) == 3) { // Illegal (size==3) - return 0; - } else { - switch (opcode>>9 & 7) { - case 0: // ORI - if ((opcode & 0xBF) == 0x3C) { // ORI to CCR/SR - return INPUT_XNZVC | OUTPUT_XNZVC; - } else { - return INPUT_NONE | OUTPUT_NZVC; - } - case 1: // ANDI - if ((opcode & 0xBF) == 0x3C) { // ANDI to CCR/SR - return INPUT_XNZVC | OUTPUT_XNZVC; - } else { - return INPUT_NONE | OUTPUT_NZVC; - } - case 2: // SUBI - return INPUT_NONE | OUTPUT_XNZVC; - case 3: // ADDI - return INPUT_NONE | OUTPUT_XNZVC; - case 4: // BTST, etc. (static) - return INPUT_NONE | OUTPUT_Z; - case 5: // EORI - if ((opcode & 0xBF) == 0x3C) { // EORI to CCR/SR - return INPUT_XNZVC | OUTPUT_XNZVC; - } else { - return INPUT_NONE | OUTPUT_NZVC; - } - case 6: // CMPI - return INPUT_NONE | OUTPUT_NZVC; - case 7: // Illegal - return 0; - } - } - - case 0x1: - case 0x2: - case 0x3: - if ((opcode>>6 & 7) == 1) { // MOVEA.[LW] - return INPUT_NONE | OUTPUT_NONE; - } else { // MOVE.[BLW] - return INPUT_NONE | OUTPUT_NZVC; - } - - case 0x4: - if (opcode & 0x0100) { - switch (opcode>>6 & 3) { - case 0: // Illegal - case 1: // Illegal - return 0; - case 2: // CHK - /* N is unmodified if no exception occurs, so treat as input */ - return INPUT_N | OUTPUT_N; - case 3: // LEA - return INPUT_NONE | OUTPUT_NONE; - } - } else { - switch (opcode & 0x0EC0) { - case 0x0000: // NEGX.B - case 0x0040: // NEGX.W - case 0x0080: // NEGX.L - return INPUT_XZ | OUTPUT_XNZVC; - case 0x00C0: // MOVE from SR - return INPUT_XNZVC | OUTPUT_NONE; - case 0x0200: // CLR.B - case 0x0240: // CLR.W - case 0x0280: // CLR.L - return INPUT_NONE | OUTPUT_NZVC; - case 0x02C0: // Illegal - return 0; - case 0x0400: // NEG.B - case 0x0440: // NEG.W - case 0x0480: // NEG.L - return INPUT_NONE | OUTPUT_XNZVC; - case 0x04C0: // MOVE to CCR - return INPUT_NONE | OUTPUT_XNZVC; - case 0x0600: // NOT.B - case 0x0640: // NOT.W - case 0x0680: // NOT.L - return INPUT_NONE | OUTPUT_NZVC; - case 0x06C0: // MOVE to SR - return INPUT_NONE | OUTPUT_XNZVC; - case 0x0800: // NBCD - return INPUT_XZ | OUTPUT_XZC; - case 0x0840: // PEA - if ((opcode>>3 & 7) == 0) { // SWAP.L - return INPUT_NONE | OUTPUT_NZVC; - } else { - return INPUT_NONE | OUTPUT_NONE; - } - case 0x0880: // MOVEM.W reglist, - case 0x08C0: // MOVEM.L reglist, - if ((opcode>>3 & 7) == 0) { // EXT.* - return INPUT_NONE | OUTPUT_NZVC; - } else { - return INPUT_NONE | OUTPUT_NONE; - } - case 0x0A00: // TST.B - case 0x0A40: // TST.W - case 0x0A80: // TST.L - case 0x0AC0: // TAS - return INPUT_NONE | OUTPUT_NZVC; - case 0x0C00: // TST.B - return 0; - case 0x0C40: // Miscellaneous - switch (opcode>>3 & 7) { - case 0: // TRAP #0-7 - case 1: // TRAP #8-15 - case 2: // LINK - case 3: // UNLK - case 4: // MOVE from USP - case 5: // MOVE to USP - return INPUT_NONE | OUTPUT_NONE; - case 6: // Miscellaneous - switch (opcode & 7) { - case 0: // RESET - case 1: // NOP - return INPUT_NONE | OUTPUT_NONE; - case 2: // STOP - case 3: // RTE - return INPUT_NONE | OUTPUT_XNZVC; - case 4: // Illegal - return 0; - case 5: // RTS - return INPUT_NONE | OUTPUT_NONE; - case 6: // TRAPV - return INPUT_V | OUTPUT_NONE; - case 7: // RTR - return INPUT_NONE | OUTPUT_XNZVC; - } - case 7: // Illegal - return 0; - } - case 0x0C80: // MOVEM.W ,reglist - case 0x0CC0: // MOVEM.L ,reglist - return INPUT_NONE | OUTPUT_NONE; - case 0x0E00: // Illegal - case 0x0E40: // Illegal - return 0; - case 0x0E80: // JSR - case 0x0EC0: // JMP - return INPUT_NONE | OUTPUT_NONE; - } - } - - case 0x5: - if ((opcode>>6 & 3) == 3) { // Scc/DBcc - return cond_inputs[opcode>>8 & 0xF] | OUTPUT_NONE; - } else { // ADDQ/SUBQ - if ((opcode>>3 & 7) == 1) { // Address register target - return INPUT_NONE | OUTPUT_NONE; - } else { // Other target - return INPUT_NONE | OUTPUT_XNZVC; - } - } - - case 0x6: - /* Bcc/BSR */ - return cond_inputs[opcode>>8 & 0xF] | OUTPUT_NONE; - - case 0x7: - if (opcode & 0x0100) { // Illegal - return 0; - } else { // MOVEQ - return INPUT_NONE | OUTPUT_NZVC; - } - - case 0x8: - if ((opcode>>6 & 3) == 3) { // MULS/MULU - return INPUT_NONE | OUTPUT_NZVC; - } else if ((opcode & 0x01F0) == 0x0100) { // SBCD - return INPUT_XZ | OUTPUT_XZC; - } else { // OR - return INPUT_NONE | OUTPUT_NZVC; - } - - case 0x9: - if ((opcode>>6 & 3) == 3) { // SUBA - return INPUT_NONE | OUTPUT_NONE; - } else if ((opcode & 0x0130) == 0x0100) { // SUBX - return INPUT_XZ | OUTPUT_XNZVC; - } else { // SUB - return INPUT_NONE | OUTPUT_XNZVC; - } - - case 0xA: - /* Nothing here */ - return 0; - - case 0xB: - /* CMP/CMPA/CMPM/EOR */ - return INPUT_NONE | OUTPUT_NZVC; - - case 0xC: - if ((opcode>>6 & 3) == 3) { // DIVS/DIVD - return INPUT_NONE | OUTPUT_NZVC; - } else if ((opcode & 0x01F0) == 0x0100) { // ABCD - return INPUT_XZ | OUTPUT_XZC; - } else if ((opcode & 0x0130) == 0x0100) { // EXG - return INPUT_NONE | OUTPUT_NONE; - } else { // AND - return INPUT_NONE | OUTPUT_NZVC; - } - - case 0xD: - if ((opcode>>6 & 3) == 3) { // ADDA - return INPUT_NONE | OUTPUT_NONE; - } else if ((opcode & 0x0130) == 0x0100) { // ADDX - return INPUT_XZ | OUTPUT_XNZVC; - } else { // ADD - return INPUT_NONE | OUTPUT_XNZVC; - } - - case 0xE: - /* Shift/rotate */ - return INPUT_X | OUTPUT_XNZVC; - - case 0xF: - /* Nothing here */ - return 0; - - } // switch (opcode>>12) - - return 0; // Should be unreachable, but just for safety -} - -#endif // Q68_JIT_OPTIMIZE_FLAGS - -/*************************************************************************/ -/*************************************************************************/ - -/** - * ea_resolve: Emit JIT code to resolve the address for the - * memory-reference EA indicated by opcode[5:0] and store it in - * state->ea_addr. Behavior is undefined if the EA is a direct register - * reference. - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * size: Access size (SIZE_*) - * access_type: Access type (ACCESS_*) - * [Return value] - * Clock cycles used (negative indicates an illegal EA) - */ -static int ea_resolve(Q68State *state, uint32_t opcode, int size, - int access_type) -{ - const unsigned int mode = EA_MODE(opcode); - const unsigned int reg = EA_REG(opcode); - const unsigned int bytes = SIZE_TO_BYTES(size); - - static const int base_cycles[8] = {0, 0, 4, 4, 6, 8, 10, 0}; - int cycles = base_cycles[mode] + (size==SIZE_L ? 4 : 0); - - switch (mode) { - case EA_INDIRECT: - JIT_EMIT_RESOLVE_INDIRECT(current_entry, (8+reg)*4); - break; - case EA_POSTINCREMENT: - if (bytes == 1 && reg == 7) { // A7 must stay even - JIT_EMIT_RESOLVE_POSTINC_A7_B(current_entry); - } else { - JIT_EMIT_RESOLVE_POSTINC(current_entry, (8+reg)*4, bytes); - } - break; - case EA_PREDECREMENT: - if (access_type == ACCESS_WRITE) { - /* 2-cycle penalty not applied to write-only accesses - * (MOVE and MOVEM) */ - cycles -= 2; - } - if (bytes == 1 && reg == 7) { // A7 must stay even - JIT_EMIT_RESOLVE_PREDEC_A7_B(current_entry); - } else { - JIT_EMIT_RESOLVE_PREDEC(current_entry, (8+reg)*4, bytes); - } - break; - case EA_DISPLACEMENT: - JIT_EMIT_RESOLVE_DISP(current_entry, (8+reg)*4, (int16_t)IFETCH(state)); - break; - case EA_INDEX: { - const uint16_t ext = IFETCH(state); - const unsigned int ireg = ext >> 12; // 0..15 - const int8_t disp = (int8_t)ext; - if (ext & 0x0800) { - JIT_EMIT_RESOLVE_INDEX_L(current_entry, (8+reg)*4, ireg*4, disp); - } else { - JIT_EMIT_RESOLVE_INDEX_W(current_entry, (8+reg)*4, ireg*4, disp); - } - break; - } - default: /* case EA_MISC */ - switch (reg) { - case EA_MISC_ABSOLUTE_W: - cycles += 8; - JIT_EMIT_RESOLVE_ABSOLUTE(current_entry, (int16_t)IFETCH(state)); - break; - case EA_MISC_ABSOLUTE_L: { - cycles += 12; - uint32_t addr = IFETCH(state) << 16; - addr |= (uint16_t)IFETCH(state); - JIT_EMIT_RESOLVE_ABSOLUTE(current_entry, addr); - break; - } - case EA_MISC_PCREL: - if (access_type != ACCESS_READ) { - return -1; - } else { - cycles += 8; - JIT_EMIT_RESOLVE_ABSOLUTE( - current_entry, state->current_PC + (int16_t)IFETCH(state) - ); - } - break; - case EA_MISC_PCREL_INDEX: - if (access_type != ACCESS_READ) { - return -1; - } else { - cycles += 10; - const uint16_t ext = IFETCH(state); - const unsigned int ireg = ext >> 12; // 0..15 - const int32_t disp = (int32_t)((int8_t)ext); - if (ext & 0x0800) { - JIT_EMIT_RESOLVE_ABS_INDEX_L( - current_entry, state->current_PC + disp, ireg*4 - ); - } else { - JIT_EMIT_RESOLVE_ABS_INDEX_W( - current_entry, state->current_PC + disp, ireg*4 - ); - } - } - break; - default: - return -1; - } - } - return cycles; -} - -/*-----------------------------------------------------------------------*/ - -/** - * ea_get: Emit JIT code to read an unsigned value from the EA indicated - * by opcode[5:0] and use it as either the first or the second operand to - * an operation, as specified by the op_num parameter. - * - * If the EA selector is invalid for the access size and mode, an illegal - * instruction exception is raised, and the error is indicated by a - * negative value returned in *cycles_ret. - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * size: Access size (SIZE_*) - * is_rmw: Nonzero if the operand will be modified and written back - * cycles_ret: Pointer to variable to receive clock cycles used - * (negative indicates an illegal EA) - * op_num: Which operand to read the value into (1 or 2) - * [Return value] - * None - */ -static void ea_get(Q68State *state, uint32_t opcode, int size, - int is_rmw, int *cycles_ret, int op_num) -{ - switch (EA_MODE(opcode)) { - - case EA_DATA_REG: - *cycles_ret = 0; - if (op_num == 1) { - JIT_EMIT_GET_OP1_REGISTER(current_entry, EA_REG(opcode) * 4); - } else { - JIT_EMIT_GET_OP2_REGISTER(current_entry, EA_REG(opcode) * 4); - } - break; - - case EA_ADDRESS_REG: - *cycles_ret = 0; - if (size == SIZE_B) { - /* An.b not permitted */ - raise_exception(state, EX_ILLEGAL_INSTRUCTION); - *cycles_ret = -1; - return; - } else { - if (op_num == 1) { - JIT_EMIT_GET_OP1_REGISTER(current_entry, - (8 + EA_REG(opcode)) * 4); - } else { - JIT_EMIT_GET_OP2_REGISTER(current_entry, - (8 + EA_REG(opcode)) * 4); - } - } - break; - - case EA_MISC: - if (EA_REG(opcode) == EA_MISC_IMMEDIATE) { - if (is_rmw) { - raise_exception(state, EX_ILLEGAL_INSTRUCTION); - *cycles_ret = -1; - return; - } else { - *cycles_ret = (size==SIZE_L ? 8 : 4); - uint32_t val; - val = IFETCH(state); - if (size == SIZE_B) { - val &= 0xFF; - } else if (size == SIZE_L) { - val <<= 16; - val |= (uint16_t)IFETCH(state); - } - if (op_num == 1) { - JIT_EMIT_GET_OP1_IMMEDIATE(current_entry, val); - } else { - JIT_EMIT_GET_OP1_IMMEDIATE(current_entry, val); - } - } - break; - } - /* else fall through */ - - default: - *cycles_ret = ea_resolve(state, opcode, size, - is_rmw ? ACCESS_MODIFY : ACCESS_READ); - if (*cycles_ret < 0) { - raise_exception(state, EX_ILLEGAL_INSTRUCTION); - return; - } - if (size == SIZE_B) { - if (op_num == 1) { - JIT_EMIT_GET_OP1_EA_B(current_entry); - } else { - JIT_EMIT_GET_OP2_EA_B(current_entry); - } - } else if (size == SIZE_W) { -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_EA( - current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_READ - ); -#endif - if (op_num == 1) { - JIT_EMIT_GET_OP1_EA_W(current_entry); - } else { - JIT_EMIT_GET_OP2_EA_W(current_entry); - } - } else { // size == SIZE_L -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_EA( - current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_READ - ); -#endif - if (op_num == 1) { - JIT_EMIT_GET_OP1_EA_L(current_entry); - } else { - JIT_EMIT_GET_OP2_EA_L(current_entry); - } - } - break; - - } // switch (EA_MODE(opcode)) -} - -/*-----------------------------------------------------------------------*/ - -/** - * ea_set: Emit JIT code to update a value at the EA indicated by - * opcode[5:0]. If the EA is a memory reference, uses the previously - * resolved address in state->ea_addr rather than resolving the address - * again. Behavior is undefined if the previous ea_resolve() or ea_get() - * failed (or if no previous call was made). - * - * [Parameters] - * state: Processor state block - * opcode: Instruction opcode - * size: Access size (SIZE_*) - * [Return value] - * None - */ -static void ea_set(Q68State *state, uint32_t opcode, int size) -{ - switch (EA_MODE(opcode)) { - case EA_DATA_REG: - if (size == SIZE_B) { - JIT_EMIT_SET_REGISTER_B(current_entry, EA_REG(opcode) * 4); - } else if (size == SIZE_W) { - JIT_EMIT_SET_REGISTER_W(current_entry, EA_REG(opcode) * 4); - } else { // size == SIZE_L - JIT_EMIT_SET_REGISTER_L(current_entry, EA_REG(opcode) * 4); - } - return; - case EA_ADDRESS_REG: - if (size == SIZE_W) { - JIT_EMIT_SET_AREG_W(current_entry, (8 + EA_REG(opcode)) * 4); - } else { // size == SIZE_L - JIT_EMIT_SET_REGISTER_L(current_entry, (8 + EA_REG(opcode)) * 4); - } - return; - default: { - if (size == SIZE_B) { - JIT_EMIT_SET_EA_B(current_entry); - } else if (size == SIZE_W) { -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_EA( - current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_WRITE - ); -#endif - JIT_EMIT_SET_EA_W(current_entry); - } else { // size == SIZE_L -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_EA( - current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_WRITE - ); -#endif - JIT_EMIT_SET_EA_L(current_entry); - } - return; - } - } -} - -/*************************************************************************/ -/*********************** Major instruction groups ************************/ -/*************************************************************************/ - -/** - * op_imm: Immediate instructions (format 0000 xxx0 xxxx xxxx). - */ -static int op_imm(Q68State *state, uint32_t opcode) -{ - /* Check for bit-twiddling and illegal opcodes first */ - enum {OR = 0, AND, SUB, ADD, _BIT, EOR, CMP, _ILL} aluop; - aluop = opcode>>9 & 7; - if (aluop == _BIT) { - return op_bit(state, opcode); - } else if (aluop == _ILL) { - return op_ill(state, opcode); - } - - /* Get the instruction size */ - INSN_GET_SIZE; - if (size == 3) { - return op_ill(state, opcode); - } - - /* Fetch the immediate value */ - int cycles_dummy; - ea_get(state, EA_MISC<<3 | EA_MISC_IMMEDIATE, size, 0, &cycles_dummy, 1); - - /* Fetch the EA operand (which may be SR or CCR) */ - int use_SR; - int cycles; - if ((aluop==OR || aluop==AND || aluop==EOR) && (opcode & 0x3F) == 0x3C) { - /* xxxI #imm,SR (or CCR) use the otherwise-invalid form of an - * immediate value destination */ - use_SR = 1; - cycles = 8; // Total instruction time is 20 cycles - switch (size) { - case SIZE_B: - JIT_EMIT_GET_OP2_CCR(current_entry); - break; - case SIZE_W: - JIT_EMIT_CHECK_SUPER(current_entry); - JIT_EMIT_GET_OP2_SR(current_entry); - break; - default: - return op_ill(state, opcode); - } - } else { - use_SR = 0; - ea_get(state, opcode, size, 1, &cycles, 2); - if (cycles < 0) { - return 1; - } - } - - /* Check whether we need to output condition codes */ - const int do_cc = cc_needed(state, opcode); - - /* Perform the operation */ - switch (aluop) { - case OR: if (size == SIZE_B) { - JIT_EMIT_OR_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_OR_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_OR_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - case AND: if (size == SIZE_B) { - JIT_EMIT_AND_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_AND_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_AND_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - case EOR: if (size == SIZE_B) { - JIT_EMIT_EOR_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_EOR_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_EOR_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - case CMP: if (size == SIZE_L) { // CMPI takes less time in most cases - if (EA_MODE(opcode) != EA_DATA_REG) { - cycles -= 8; - } else { - cycles -= 2; - } - } else { - if (EA_MODE(opcode) != EA_DATA_REG) { - cycles -= 4; - } - } - if (size == SIZE_B) { - JIT_EMIT_SUB_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUB_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUB_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_L(current_entry); - } - break; - case SUB: if (size == SIZE_B) { - JIT_EMIT_SUB_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUB_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUB_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_L(current_entry); - } - break; - default: // case ADD - if (size == SIZE_B) { - JIT_EMIT_ADD_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ADD_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ADD_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_L(current_entry); - } - break; - } - - /* Update the cycle counter (and PC) before writing the result, in case - * a change to SR triggers an interrupt */ - cycles += (size==SIZE_L ? 16 : 8); - cycles += (EA_MODE(opcode) == EA_DATA_REG ? 0 : 4); - JIT_EMIT_ADD_CYCLES(current_entry, cycles); - advance_PC(state); - - /* Update the EA operand (if not CMPI) */ - if (aluop != CMP) { - if (use_SR) { - if (size == SIZE_B) { - JIT_EMIT_SET_CCR(current_entry); - } else { - JIT_EMIT_SET_SR(current_entry); - } - } else { - ea_set(state, opcode, size); - } - } - - /* All done */ - return 0; -} - -/*************************************************************************/ - -/** - * op_bit: Bit-twiddling instructions (formats 0000 rrr1 xxxx xxxx and - * 0000 1000 xxxx xxxx). - */ -static int op_bit(Q68State *state, uint32_t opcode) -{ - /* Check early for MOVEP (coded as BTST/BCHG/BCLR/BSET Dn,An) */ - if (EA_MODE(opcode) == EA_ADDRESS_REG) { - if (opcode & 0x0100) { - return opMOVP(state, opcode); - } else { - return op_ill(state, opcode); - } - } - - enum {BTST = 0, BCHG = 1, BCLR = 2, BSET = 3} op = opcode>>6 & 3; - int cycles; - - /* Get the bit number to operate on */ - if (opcode & 0x0100) { - /* Bit number in register */ - INSN_GET_REG; - JIT_EMIT_GET_OP1_REGISTER(current_entry, reg*4); - cycles = 0; - } else { - unsigned int bitnum = IFETCH(state); - JIT_EMIT_GET_OP1_IMMEDIATE(current_entry, bitnum); - cycles = 4; - } - - /* EA operand is 32 bits when coming from a register, 8 when from memory */ - int size = (EA_MODE(opcode)==EA_DATA_REG ? SIZE_L : SIZE_B); - int cycles_tmp; - ea_get(state, opcode, size, 1, &cycles_tmp, 2); - if (cycles_tmp < 0) { - return 1; - } - cycles += cycles_tmp; - if (size == SIZE_L && (op == BCLR || op == BTST)) { - cycles += 2; - } - - /* Perform the operation: first test the bit, then (for non-BTST cases) - * twiddle it as appropriate. All size-related checking is performed - * in BTST, so the remaining operations are unsized. */ - if (size == SIZE_B) { - JIT_EMIT_BTST_B(current_entry); - } else { // size == SIZE_L - JIT_EMIT_BTST_L(current_entry); - } - switch (op) { - default: break; // case BTST: nothing to do - case BCHG: JIT_EMIT_BCHG(current_entry); break; - case BCLR: JIT_EMIT_BCLR(current_entry); break; - case BSET: JIT_EMIT_BSET(current_entry); break; - } - - /* Update EA operand (but not for BTST) */ - if (op != BTST) { - ea_set(state, opcode, size); - } - - /* Update cycle counter; note that the times for BCHG.L, BCLR.L, and - * BSET.L are maximums (though how they vary is undocumented) */ - JIT_EMIT_ADD_CYCLES(current_entry, (op==BTST ? 4 : 8) + cycles); - - return 0; -} - -/*************************************************************************/ - -/** - * opMOVE: MOVE.[bwl] instruction (format {01,10,11}xx xxxx xxxx xxxx). - */ -static int opMOVE(Q68State *state, uint32_t opcode) -{ - const int size = (opcode>>12==1 ? SIZE_B : opcode>>12==2 ? SIZE_L : SIZE_W); - - int cycles_src; - ea_get(state, opcode, size, 0, &cycles_src, 1); - if (cycles_src < 0) { - return 1; - } - - /* Rearrange the opcode bits so we can pass the destination EA to - * ea_resolve() */ - const uint32_t dummy_opcode = (opcode>>9 & 7) | (opcode>>3 & 0x38); - int cycles_dest; - if (EA_MODE(dummy_opcode) <= EA_ADDRESS_REG) { - cycles_dest = 0; - } else { - cycles_dest = ea_resolve(state, dummy_opcode, size, ACCESS_WRITE); - if (cycles_dest < 0) { - return op_ill(state, opcode); - } - } - - /* Copy the operand to the result and set flags (if needed) */ - const int do_cc = cc_needed(state, opcode); - if (EA_MODE(dummy_opcode) == EA_ADDRESS_REG) { - if (size == SIZE_W) { - JIT_EMIT_EXT_L(current_entry); - } else { // size == SIZE_L - JIT_EMIT_MOVE_L(current_entry); - } - } else { - if (size == SIZE_B) { - JIT_EMIT_MOVE_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_MOVE_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_MOVE_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - } - - /* Update the destination EA and cycle count */ - ea_set(state, dummy_opcode, size); - JIT_EMIT_ADD_CYCLES(current_entry, 4 + cycles_src + cycles_dest); - - return 0; -} - -/*************************************************************************/ - -/** - * op4xxx: Miscellaneous instructions (format 0100 xxx0 xxxx xxxx). - */ -static int op4xxx(Q68State *state, uint32_t opcode) -{ - const unsigned int index = (opcode>>7 & 0x1C) | (opcode>>6 & 3); - return (*opcode_4xxx_table[index])(state, opcode); -} - -/*************************************************************************/ - -/** - * op_CHK: CHK instruction (format 0100 rrr1 10xx xxxx). - */ -static int op_CHK(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - JIT_EMIT_GET_OP1_REGISTER(current_entry, reg*4); - - int cycles; - if (EA_MODE(opcode) == EA_ADDRESS_REG) { - return op_ill(state, opcode); - } - ea_get(state, opcode, SIZE_W, 0, &cycles, 2); - if (cycles < 0) { - return 1; - } - - JIT_EMIT_ADD_CYCLES(current_entry, 10 + cycles); - /* The JIT code takes care of adding the extra 34 cycles of exception - * processing if necessary */ - JIT_EMIT_CHK_W(current_entry); - return 0; -} - -/*************************************************************************/ - -/** - * op_LEA: LEA instruction (format 0100 rrr1 11xx xxxx). - */ -static int op_LEA(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - - /* Register, predecrement, postincrement, immediate modes are illegal */ - if (EA_MODE(opcode) == EA_DATA_REG - || EA_MODE(opcode) == EA_ADDRESS_REG - || EA_MODE(opcode) == EA_POSTINCREMENT - || EA_MODE(opcode) == EA_PREDECREMENT - || (EA_MODE(opcode) == EA_MISC && EA_REG(opcode) == EA_MISC_IMMEDIATE) - ) { - return op_ill(state, opcode); - } - - int cycles = ea_resolve(state, opcode, SIZE_W, ACCESS_READ); - if (cycles < 0) { - return op_ill(state, opcode); - } - if (cycles % 4 == 2) { // d(An,ix) and d(PC,ix) take 2 extra cycles - cycles += 2; - } - - JIT_EMIT_LEA(current_entry, (8+reg)*4); - JIT_EMIT_ADD_CYCLES(current_entry, cycles); - return 0; -} - -/*************************************************************************/ - -/** - * opADSQ: ADDQ and SUBQ instructions (format 0101 iiix xxxx xxxx). - */ -static int opADSQ(Q68State *state, uint32_t opcode) -{ - const int is_sub = opcode & 0x0100; - INSN_GET_COUNT; - INSN_GET_SIZE; - if (EA_MODE(opcode) == EA_ADDRESS_REG && size == 1) { - size = 2; // ADDQ.W #imm,An is equivalent to ADDQ.L #imm,An - } - - JIT_EMIT_GET_OP1_IMMEDIATE(current_entry, count); - - int cycles; - ea_get(state, opcode, size, 1, &cycles, 2); - if (cycles < 0) { - return 1; - } - - const int do_cc = cc_needed(state, opcode); - if (is_sub) { - if (EA_MODE(opcode) == EA_ADDRESS_REG) { - JIT_EMIT_SUB_L(current_entry); - } else { - if (size == SIZE_B) { - JIT_EMIT_SUB_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUB_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUB_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_L(current_entry); - } - } - } else { - if (EA_MODE(opcode) == EA_ADDRESS_REG) { - JIT_EMIT_ADD_L(current_entry); - } else { - if (size == SIZE_B) { - JIT_EMIT_ADD_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ADD_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ADD_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_L(current_entry); - } - } - } - - ea_set(state, opcode, size); - - cycles += (size==SIZE_L || EA_MODE(opcode) == EA_ADDRESS_REG ? 8 : 4); - cycles += (EA_MODE(opcode) >= EA_INDIRECT ? 4 : 0); - JIT_EMIT_ADD_CYCLES(current_entry, cycles); - return 0; -} - -/*************************************************************************/ - -/** - * op_Scc: Scc instruction (format 0101 cccc 11xx xxxx). - */ -static int op_Scc(Q68State *state, uint32_t opcode) -{ - if (EA_MODE(opcode) == EA_ADDRESS_REG) { - /* DBcc Dn,disp is coded as Scc An with an extension word */ - return opDBcc(state, opcode); - } - - INSN_GET_COND; - /* From the cycle counts, it looks like this is a standard read/write - * access rather than a write-only access */ - int cycles; - if (EA_MODE(opcode) == EA_DATA_REG) { - cycles = 0; - } else { - cycles = ea_resolve(state, opcode, SIZE_B, ACCESS_MODIFY); - if (cycles < 0) { - return op_ill(state, opcode); - } - } - JIT_EMIT_TEST_cc(cond, current_entry); - JIT_EMIT_Scc(current_entry); - if (EA_MODE(opcode) == EA_DATA_REG) { - /* Scc Dn is a special case */ - JIT_EMIT_ADD_CYCLES_Scc_Dn(current_entry); - } else { - JIT_EMIT_ADD_CYCLES(current_entry, 8 + cycles); - } - ea_set(state, opcode, SIZE_B); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * op_DBcc: DBcc instruction (format 0101 cccc 1100 1xxx). - */ -static int opDBcc(Q68State *state, uint32_t opcode) -{ - INSN_GET_COND; - INSN_GET_REG0; - INSN_GET_IMM16; - uint32_t target = state->current_PC + imm16; - int32_t offset = btcache_lookup(target); - JIT_EMIT_TEST_cc(cond, current_entry); - if (offset >= 0) { - JIT_EMIT_DBcc_native(current_entry, reg0*4, target, offset); - } else { - JIT_EMIT_DBcc(current_entry, reg0*4, target); - } - return 0; -} - -/*************************************************************************/ - -/** - * op_Bcc: Conditional branch instructions (format 0110 cccc dddd dddd). - */ -static int op_Bcc(Q68State *state, uint32_t opcode) -{ - INSN_GET_COND; - INSN_GET_DISP8; - int cycles = 0; - if (disp == 0) { - disp = (int16_t)IFETCH(state); - cycles = 4; - } - uint32_t target = state->current_PC + disp; - if (cond == COND_F) { - /* BF is really BSR */ -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_SP(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_WRITE); -#endif - JIT_EMIT_ADD_CYCLES(current_entry, 18); - advance_PC(state); - JIT_EMIT_BSR(current_entry, jit_PC, target); - return 0; - } else { - int32_t offset; -#ifdef Q68_OPTIMIZE_IDLE - /* FIXME: Temporary hack to improve PSP performance */ - if (target == 0x1066 - && ((cond == COND_EQ && state->current_PC - 2 == 0x001092) - || (cond == COND_PL && state->current_PC - 2 == 0x0010B4)) - ) { - /* BIOS intro animation */ - JIT_EMIT_ADD_CYCLES(current_entry, - 468); // Length of one loop when idle - } else if (target == 0x10BC - && ((cond == COND_PL && state->current_PC - 2 == 0x001122) - || (cond == COND_T && state->current_PC - 2 == 0x00116A)) - ) { - /* Azel: Panzer Dragoon RPG (JP) */ - JIT_EMIT_ADD_CYCLES(current_entry, - 178*4); // Assuming a cycle_limit of 768 - } -#endif - if (target < state->current_PC) { - offset = btcache_lookup(target); - } else { - offset = -1; // Forward jumps can't be in the cache - } - JIT_EMIT_TEST_cc(cond, current_entry); - if (offset >= 0) { - JIT_EMIT_Bcc_native(current_entry, target, offset); - } else { - int32_t branch_offset; - JIT_EMIT_Bcc(current_entry, target, &branch_offset); - if (target >= state->current_PC && branch_offset >= 0) { - record_unresolved_branch(target, branch_offset); - } - } - JIT_EMIT_ADD_CYCLES(current_entry, 8 + cycles); - return 0; - } -} - -/*************************************************************************/ - -/** - * opMOVQ: MOVEQ instruction (format 0111 rrr0 iiii iiii). - */ -static int opMOVQ(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_IMM8; - JIT_EMIT_GET_OP1_IMMEDIATE(current_entry, imm8); - const int do_cc = cc_needed(state, opcode); - JIT_EMIT_MOVE_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - JIT_EMIT_SET_REGISTER_L(current_entry, reg*4); - JIT_EMIT_ADD_CYCLES(current_entry, 4); - return 0; -} - -/*************************************************************************/ - -/** - * op_alu: Non-immediate ALU instructions (format 1ooo rrrx xxxx xxxx for - * ooo = 000, 001, 011, 100, 101). - */ -static int op_alu(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_SIZE; - - /* Pass off special and invalid instructions early */ - if (size != 3) { - if ((opcode & 0xB130) == 0x9100) { - /* ADDX/SUBX are coded as ADD/SUB.* Dn, */ - return opADSX(state, opcode); - } - if ((opcode & 0xB1F0) == 0x8100) { - /* ABCD/SBCD are coded as AND/OR.b Dn, */ - return op_BCD(state, opcode); - } - if ((opcode & 0xF130) == 0xC100) { - /* EXG is coded as AND.[wl] Dn, */ - return op_EXG(state, opcode); - } - if ((opcode & 0xF130) == 0x8100) { - /* OR.[wl] Dn, is invalid on the 68000 (later PACK/UNPK) */ - return op_ill(state, opcode); - } - if ((opcode & 0xF138) == 0xB108 && (opcode>>6 & 3) != 3) { - /* CMPM is coded as EOR.* Dn, */ - return opCMPM(state, opcode); - } - } - - int ea_dest = opcode & 0x100; - int areg_dest = 0; // For ADDA/SUBA/CMPA - enum {OR, AND, EOR, CMP, SUB, ADD} aluop; - - /* Find the instruction for the opcode group */ - switch (opcode>>12) { - case 0x8: aluop = OR; break; - case 0x9: aluop = SUB; break; - case 0xB: aluop = (((opcode>>6)+1) & 7) <= 4 ? CMP : EOR; break; - case 0xC: aluop = AND; break; - default: aluop = ADD; break; // case 0xD - } - - /* Handle the special formats of ADDA/SUBA/CMPA */ - if ((aluop == ADD || aluop == SUB || aluop == CMP) && size == 3) { - size = ea_dest ? SIZE_L : SIZE_W; - ea_dest = 0; - areg_dest = 1; - } - - /* Retrieve the register and EA values; make sure to load operand 1 - * first, since operand 2 may be destroyed by memory operations */ - int cycles; - if (ea_dest) { - JIT_EMIT_GET_OP1_REGISTER(current_entry, reg*4); - ea_get(state, opcode, size, ea_dest, &cycles, 2); - } else { - ea_get(state, opcode, size, ea_dest, &cycles, 1); - if (areg_dest) { - JIT_EMIT_GET_OP2_REGISTER(current_entry, (8+reg)*4); - } else { - JIT_EMIT_GET_OP2_REGISTER(current_entry, reg*4); - } - } - if (cycles < 0) { - return 1; - } - if (size == SIZE_L || areg_dest) { - cycles += 4; - } - if (ea_dest) { - cycles += 4; - } else if ((aluop == CMP && areg_dest) - || (size == SIZE_L - && (EA_MODE(opcode) <= EA_ADDRESS_REG - || (EA_MODE(opcode) == EA_MISC - && EA_REG(opcode) == EA_MISC_IMMEDIATE)))) { - cycles -= 2; - } - - /* Perform the actual computation */ - const int do_cc = cc_needed(state, opcode); - switch (aluop) { - case OR: if (size == SIZE_B) { - JIT_EMIT_OR_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_OR_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_OR_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - case AND: if (size == SIZE_B) { - JIT_EMIT_AND_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_AND_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_AND_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - case EOR: if (size == SIZE_B) { - JIT_EMIT_EOR_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_EOR_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_EOR_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - case CMP: if (areg_dest && size == SIZE_W) { - JIT_EMIT_SUBA_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_W(current_entry); - } else if (size == SIZE_B) { - JIT_EMIT_SUB_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUB_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUB_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_L(current_entry); - } - break; - case SUB: if (areg_dest && size == SIZE_W) { - JIT_EMIT_SUBA_W(current_entry); - } else if (areg_dest && size == SIZE_L) { - JIT_EMIT_SUB_L(current_entry); - } else if (size == SIZE_B) { - JIT_EMIT_SUB_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUB_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUB_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_L(current_entry); - } - break; - default: // case ADD - if (areg_dest && size == SIZE_W) { - JIT_EMIT_ADDA_W(current_entry); - } else if (areg_dest && size == SIZE_L) { - JIT_EMIT_ADD_L(current_entry); - } else if (size == SIZE_B) { - JIT_EMIT_ADD_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ADD_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ADD_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADD_L(current_entry); - } - break; - } // switch (aluop) - - /* Store the result in the proper place (if the instruction is not CMP) */ - if (aluop != CMP) { - if (ea_dest) { - ea_set(state, opcode, size); - } else if (areg_dest) { - JIT_EMIT_SET_REGISTER_L(current_entry, (8+reg)*4); - } else if (size == SIZE_B) { - JIT_EMIT_SET_REGISTER_B(current_entry, reg*4); - } else if (size == SIZE_W) { - JIT_EMIT_SET_REGISTER_W(current_entry, reg*4); - } else { // size == SIZE_L - JIT_EMIT_SET_REGISTER_L(current_entry, reg*4); - } - } - - JIT_EMIT_ADD_CYCLES(current_entry, 4 + cycles); - return 0; -} - -/*************************************************************************/ - -/** - * op_DIV: DIVU and DIVS instructions (format 1000 rrrx 11xx xxxx). - */ -static int op_DIV(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - const int sign = opcode & (1<<8); - - int cycles; - ea_get(state, opcode, SIZE_W, 0, &cycles, 1); - if (cycles < 0) { - return 1; - } - JIT_EMIT_GET_OP2_REGISTER(current_entry, reg*4); - /* Add the EA cycles now, in case a divide-by-zero exception occurs */ - JIT_EMIT_ADD_CYCLES(current_entry, cycles); - - if (sign) { - JIT_EMIT_DIVS_W(current_entry); - } else { - JIT_EMIT_DIVU_W(current_entry); - } - JIT_EMIT_SET_REGISTER_L(current_entry, reg*4); - - /* The 68000 docs say that the timing difference between best and - * worst cases is less than 10%, so we just return the worst case */ - JIT_EMIT_ADD_CYCLES(current_entry, sign ? 158 : 140); - return 0; -} - -/*************************************************************************/ - -/** - * opAxxx: $Axxx illegal instruction set (format 1010 xxxx xxxx xxxx). - */ -static int opAxxx(Q68State *state, uint32_t opcode) -{ - return raise_exception(state, EX_LINE_1010); -} - -/*************************************************************************/ - -/** - * op_MUL: MULU and MULS instructions (format 1100 rrrx 11xx xxxx). - */ -static int op_MUL(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - const int sign = opcode & (1<<8); - - int cycles; - ea_get(state, opcode, SIZE_W, 0, &cycles, 1); - if (cycles < 0) { - return 1; - } - JIT_EMIT_GET_OP2_REGISTER(current_entry, reg*4); - - const int do_cc = cc_needed(state, opcode); - if (sign) { - JIT_EMIT_MULS_W(current_entry); - } else { - JIT_EMIT_MULU_W(current_entry); - } - /* 16*16 -> 32 multiplication can't produce carry or overflow, so we - * can treat it like a logical operation for setting condition codes */ - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - JIT_EMIT_SET_REGISTER_L(current_entry, reg*4); - - JIT_EMIT_ADD_CYCLES(current_entry, 54 + cycles); - return 0; -} - -/*************************************************************************/ - -/** - * opshft: Shift and rotate instructions (format 1110 xxxx xxxx xxxx). - */ -static int opshft(Q68State *state, uint32_t opcode) -{ - const int is_left = opcode & 0x0100; - INSN_GET_SIZE; - INSN_GET_COUNT; - INSN_GET_REG0; - int is_memory; - int type; // Shift/rotate type (0=ASL/ASR, 1=LSL/LSR, ...) - int cycles; - - if (size == 3) { - /* Memory shift/rotate */ - is_memory = 1; - if ((opcode & 0x0800) || EA_MODE(opcode) <= EA_ADDRESS_REG) { - return op_ill(state, opcode); - } - size = SIZE_W; - type = opcode>>9 & 3; - JIT_EMIT_GET_OP1_IMMEDIATE(current_entry, 1); - ea_get(state, opcode, size, 1, &cycles, 2); - if (cycles < 0) { - return 1; - } - } else { - /* Register shift/rotate */ - is_memory = 0; - type = opcode>>3 & 3; - if (opcode & 0x0020) { - INSN_GET_REG; - JIT_EMIT_GET_OP1_REGISTER(current_entry, reg*4); - } else { - JIT_EMIT_GET_OP1_IMMEDIATE(current_entry, count); - } - JIT_EMIT_GET_OP2_REGISTER(current_entry, reg0*4); - cycles = 0; - } - - switch (type) { - case 0: // ASL/ASR - if (is_left) { - if (size == SIZE_B) { - JIT_EMIT_ASL_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ASL_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ASL_L(current_entry); - } - } else { - if (size == SIZE_B) { - JIT_EMIT_ASR_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ASR_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ASR_L(current_entry); - } - } - break; - case 1: // LSL/LSR - if (is_left) { - if (size == SIZE_B) { - JIT_EMIT_LSL_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_LSL_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_LSL_L(current_entry); - } - } else { - if (size == SIZE_B) { - JIT_EMIT_LSR_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_LSR_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_LSR_L(current_entry); - } - } - break; - case 2: // ROXL/ROXR - if (is_left) { - if (size == SIZE_B) { - JIT_EMIT_ROXL_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ROXL_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ROXL_L(current_entry); - } - } else { - if (size == SIZE_B) { - JIT_EMIT_ROXR_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ROXR_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ROXR_L(current_entry); - } - } - break; - case 3: // ROL/ROR - if (is_left) { - if (size == SIZE_B) { - JIT_EMIT_ROL_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ROL_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ROL_L(current_entry); - } - } else { - if (size == SIZE_B) { - JIT_EMIT_ROR_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ROR_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ROR_L(current_entry); - } - } - break; - } // switch (type) - - if (is_memory) { - ea_set(state, opcode, size); - } else if (size == SIZE_B) { - JIT_EMIT_SET_REGISTER_B(current_entry, reg0*4); - } else if (size == SIZE_W) { - JIT_EMIT_SET_REGISTER_W(current_entry, reg0*4); - } else { // size == SIZE_L - JIT_EMIT_SET_REGISTER_L(current_entry, reg0*4); - } - - /* Cycles based on count are added in the shift/rotate processing */ - JIT_EMIT_ADD_CYCLES(current_entry, (size==SIZE_L ? 8 : 6) + cycles); - return 0; -} - -/*************************************************************************/ - -/** - * opFxxx: $Fxxx illegal instruction set (format 1111 xxxx xxxx xxxx). - */ -static int opFxxx(Q68State *state, uint32_t opcode) -{ - return raise_exception(state, EX_LINE_1111); -} - -/*************************************************************************/ -/*********************** $4xxx group instructions ************************/ -/*************************************************************************/ - -/** - * op4alu: Single-operand ALU instructions in the $4xxx opcode range - * (format 0100 ooo0 ssxx xxxx for ooo = 000, 001, 010, 011, 101). - */ -static int op4alu(Q68State *state, uint32_t opcode) -{ - INSN_GET_SIZE; - enum {NEGX = 0, CLR = 1, NEG = 2, NOT = 3, TST = 5} aluop; - aluop = opcode>>9 & 7; - - if (EA_MODE(opcode) == EA_ADDRESS_REG) { // Address registers not allowed - return op_ill(state, opcode); - } - - /* Retrieve the EA value */ - int cycles; - ea_get(state, opcode, size, 1, &cycles, 1); - if (cycles < 0) { - return 1; - } - if (aluop != TST) { - if (EA_MODE(opcode) == EA_DATA_REG) { - if (size == SIZE_L) { - cycles += 2; - } - } else { - cycles += (size == SIZE_L) ? 8 : 4; - } - } - - /* Perform the actual computation */ - /* For simplicity, use the 2-argument operations with 0 or ~0 as the - * second operand: - * -n = 0 - n - * 0 = 0 & n - * ~n = ~0 ^ n - * n = 0 | n - */ - JIT_EMIT_GET_OP2_IMMEDIATE(current_entry, aluop==NOT ? ~(uint32_t)0 : 0); - const int do_cc = cc_needed(state, opcode); - switch (aluop) { - case NEGX:if (size == SIZE_B) { - JIT_EMIT_SUBX_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUBX_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUBX_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUBX_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUBX_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUBX_L(current_entry); - } - break; - case NEG: if (size == SIZE_B) { - JIT_EMIT_SUB_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUB_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUB_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUB_L(current_entry); - } - break; - case CLR: if (size == SIZE_B) { - JIT_EMIT_AND_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_AND_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_AND_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - case NOT: if (size == SIZE_B) { - JIT_EMIT_EOR_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_EOR_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_EOR_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - default: // case TST - if (size == SIZE_B) { - JIT_EMIT_OR_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_OR_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_OR_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - } - break; - } // switch (aluop) - - /* Store the result in the proper place (if the instruction is not TST) */ - if (aluop != TST) { - ea_set(state, opcode, size); - } - - JIT_EMIT_ADD_CYCLES(current_entry, 4 + cycles); - return 0; -} - -/*************************************************************************/ - -/** - * opMVSR: MOVE to/from SR/CCR instructions (format 0100 0xx0 11xx xxxx). - */ -static int opMVSR(Q68State *state, uint32_t opcode) -{ - int is_CCR; - int ea_dest; - int cycles; - switch (opcode>>9 & 3) { - case 0: // MOVE SR, - is_CCR = 0; - ea_dest = 1; - cycles = (EA_MODE(opcode) == EA_DATA_REG) ? 6 : 8; - break; - case 1: // Undefined (MOVE CCR, on 68010) - return op_ill(state, opcode); - case 2: // MOVE ,CCR - is_CCR = 1; - ea_dest = 0; - cycles = 12; - break; - default: // MOVE ,SR (case 3) - JIT_EMIT_CHECK_SUPER(current_entry); - is_CCR = 0; - ea_dest = 0; - cycles = 12; - break; - } - - if (EA_MODE(opcode) == EA_ADDRESS_REG) { // Address registers not allowed - return op_ill(state, opcode); - } - - /* Motorola docs say the address is read before being written, even - * for the SR, format; also, the access size is a word even for - * CCR operations. */ - int cycles_tmp; - ea_get(state, opcode, SIZE_W, ea_dest, &cycles_tmp, 1); - if (cycles_tmp < 0) { - return 1; - } - cycles += cycles_tmp; - - /* Update the cycle counter (and PC) before writing the result, in case - * a change to SR triggers an interrupt */ - JIT_EMIT_ADD_CYCLES(current_entry, cycles); - advance_PC(state); - - if (ea_dest) { - if (is_CCR) { - JIT_EMIT_GET_OP1_CCR(current_entry); - } else { - JIT_EMIT_GET_OP1_SR(current_entry); - } - JIT_EMIT_MOVE_W(current_entry); - ea_set(state, opcode, SIZE_W); - } else { - JIT_EMIT_MOVE_W(current_entry); - /* No need to set condition codes--we're about to overwrite them */ - if (is_CCR) { - JIT_EMIT_SET_CCR(current_entry); - } else { - JIT_EMIT_SET_SR(current_entry); - } - } - - return 0; -} - -/*************************************************************************/ - -/** - * opNBCD: NBCD instruction (format 0100 1000 00xx xxxx). - */ -static int opNBCD(Q68State *state, uint32_t opcode) -{ - if (EA_MODE(opcode) == EA_ADDRESS_REG) { // Address registers not allowed - return op_ill(state, opcode); - } - - int cycles; - ea_get(state, opcode, SIZE_B, 1, &cycles, 1); - if (cycles < 0) { - return 1; - } - - /* Treat it as something like SBCD ,#0 for simplicity */ - JIT_EMIT_GET_OP2_IMMEDIATE(current_entry, 0); - JIT_EMIT_SBCD(current_entry); - - ea_set(state, opcode, SIZE_B); - JIT_EMIT_ADD_CYCLES(current_entry, - (EA_MODE(opcode) == EA_DATA_REG ? 6 : 8) + cycles); - return 0; -} - -/*************************************************************************/ - -/** - * op_PEA: PEA instruction (format 0100 1000 01xx xxxx). - */ -static int op_PEA(Q68State *state, uint32_t opcode) -{ - /* SWAP is coded as PEA Dn */ - if (EA_MODE(opcode) == EA_DATA_REG) { - return opSWAP(state, opcode); - } - - if (EA_MODE(opcode) == EA_DATA_REG - || EA_MODE(opcode) == EA_ADDRESS_REG - || EA_MODE(opcode) == EA_POSTINCREMENT - || EA_MODE(opcode) == EA_PREDECREMENT - || (EA_MODE(opcode) == EA_MISC && EA_REG(opcode) == EA_MISC_IMMEDIATE) - ) { - return op_ill(state, opcode); - } - - int cycles = ea_resolve(state, opcode, SIZE_W, ACCESS_READ); - if (cycles < 0) { - return op_ill(state, opcode); - } - if (cycles % 4 == 2) { // d(An,ix) and d(PC,ix) take 2 extra cycles - cycles += 2; - } - -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_SP(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_WRITE); -#endif - JIT_EMIT_PEA(current_entry); - JIT_EMIT_ADD_CYCLES(current_entry, 8 + cycles); - return 0; -} - -/*************************************************************************/ - -/** - * opSWAP: SWAP instruction (format 0100 1000 0100 0rrr). - */ -static int opSWAP(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG0; - JIT_EMIT_GET_OP1_REGISTER(current_entry, reg0*4); - const int do_cc = cc_needed(state, opcode); - JIT_EMIT_SWAP(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - JIT_EMIT_SET_REGISTER_L(current_entry, reg0*4); - JIT_EMIT_ADD_CYCLES(current_entry, 4); - return 0; -} - -/*************************************************************************/ - -/** - * op_TAS: TAS instruction (format 0100 1010 11xx xxxx). Also covers the - * ILLEGAL instruction (format 0100 1010 1111 1100). - */ -static int op_TAS(Q68State *state, uint32_t opcode) -{ - if (EA_MODE(opcode) == EA_ADDRESS_REG) { // Address registers not allowed - return op_ill(state, opcode); - } - - int cycles; - ea_get(state, opcode, SIZE_B, 1, &cycles, 1); - if (cycles < 0) { - /* Note that the ILLEGAL instruction is coded as TAS #imm, so it - * will be rejected as unwriteable by ea_get() */ - return 1; - } - JIT_EMIT_TAS(current_entry); - ea_set(state, opcode, SIZE_B); - JIT_EMIT_ADD_CYCLES(current_entry, - (EA_MODE(opcode) == EA_DATA_REG ? 4 : 10) + cycles); - return 0; -} - -/*************************************************************************/ - -/** - * op_EXT: EXT instruction (format 0100 1000 1s00 0rrr). - */ -static int op_EXT(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG0; - JIT_EMIT_GET_OP1_REGISTER(current_entry, reg0*4); - const int do_cc = cc_needed(state, opcode); - if (opcode & 0x0040) { - JIT_EMIT_EXT_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_L(current_entry); - JIT_EMIT_SET_REGISTER_L(current_entry, reg0*4); - } else { - JIT_EMIT_EXT_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_LOGIC_W(current_entry); - JIT_EMIT_SET_REGISTER_W(current_entry, reg0*4); - } - JIT_EMIT_ADD_CYCLES(current_entry, 4); - return 0; -} - -/*************************************************************************/ - -/** - * op_STM: MOVEM reglist, (i.e. STore Multiple) instruction (format - * 0100 1000 1sxx xxxx). - */ -static int op_STM(Q68State *state, uint32_t opcode) -{ - /* EXT.* is coded as MOVEM.* reglist,Dn */ - if (EA_MODE(opcode) == EA_DATA_REG) { - return op_EXT(state, opcode); - } - - unsigned int regmask = IFETCH(state); - int size = (opcode & 0x0040) ? SIZE_L : SIZE_W; - if (EA_MODE(opcode) <= EA_ADDRESS_REG - || EA_MODE(opcode) == EA_POSTINCREMENT // Not allowed for store - ) { - return op_ill(state, opcode); - } - - /* Avoid modifying the register during address resolution */ - uint16_t safe_ea; - if (EA_MODE(opcode) == EA_PREDECREMENT) { - safe_ea = EA_INDIRECT<<3 | EA_REG(opcode); - } else { - safe_ea = opcode; - } - int cycles = ea_resolve(state, safe_ea, SIZE_W, ACCESS_WRITE); - if (cycles < 0) { - return op_ill(state, opcode); - } - if (regmask != 0) { // FIXME: does a real 68000 choke even if regmask==0? -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_EA(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_WRITE); -#endif - } - - if (EA_MODE(opcode) == EA_PREDECREMENT) { - /* Register order is reversed in predecrement mode */ - int reg; - for (reg = 15; reg >= 0; reg--, regmask >>= 1) { - if (regmask & 1) { - if (size == SIZE_W) { - JIT_EMIT_STORE_DEC_W(current_entry, reg*4); - cycles += 4; - } else { - JIT_EMIT_STORE_DEC_L(current_entry, reg*4); - cycles += 8; - } - } - } - JIT_EMIT_MOVEM_WRITEBACK(current_entry, (8 + EA_REG(opcode)) * 4); - } else { - int reg; - for (reg = 0; reg < 16; reg++, regmask >>= 1) { - if (regmask & 1) { - if (size == SIZE_W) { - JIT_EMIT_STORE_INC_W(current_entry, reg*4); - cycles += 4; - } else { - JIT_EMIT_STORE_INC_L(current_entry, reg*4); - cycles += 8; - } - } - } - } - - JIT_EMIT_ADD_CYCLES(current_entry, 4 + cycles); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * op_LDM: MOVEM ,reglist (i.e. LoaD Multiple) instruction (format - * 0100 1100 1sxx xxxx). - */ -static int op_LDM(Q68State *state, uint32_t opcode) -{ - unsigned int regmask = IFETCH(state); - int size = (opcode & 0x0040) ? SIZE_L : SIZE_W; - if (EA_MODE(opcode) <= EA_ADDRESS_REG - || EA_MODE(opcode) == EA_PREDECREMENT // Not allowed for load - ) { - return op_ill(state, opcode); - } - - /* Avoid modifying the register during address resolution */ - uint16_t safe_ea; - if (EA_MODE(opcode) == EA_POSTINCREMENT) { - safe_ea = EA_INDIRECT<<3 | EA_REG(opcode); - } else { - safe_ea = opcode; - } - int cycles = ea_resolve(state, safe_ea, SIZE_W, ACCESS_READ); - if (cycles < 0) { - return op_ill(state, opcode); - } - if (regmask != 0) { // FIXME: does a real 68000 choke even if regmask==0? -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_EA(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_READ); -#endif - } - - int reg; - for (reg = 0; reg < 16; reg++, regmask >>= 1) { - if (regmask & 1) { - if (size == SIZE_W) { - if (reg < 8) { - JIT_EMIT_LOAD_INC_W(current_entry, reg*4); - } else { - JIT_EMIT_LOADA_INC_W(current_entry, reg*4); - } - cycles += 4; - } else { - JIT_EMIT_LOAD_INC_L(current_entry, reg*4); - cycles += 8; - } - } - } - if (EA_MODE(opcode) == EA_POSTINCREMENT) { - JIT_EMIT_MOVEM_WRITEBACK(current_entry, (8 + EA_REG(opcode)) * 4); - } - - JIT_EMIT_ADD_CYCLES(current_entry, 8 + cycles); - return 0; -} - -/*************************************************************************/ - -/** - * opmisc: $4xxx-group misc. instructions (format 0100 1110 01xx xxxx). - */ -static int opmisc(Q68State *state, uint32_t opcode) -{ - const unsigned int index = (opcode>>3 & 7); - return (*opcode_4E4x_table[index])(state, opcode); -} - -/*-----------------------------------------------------------------------*/ - -/** - * opTRAP: TRAP #n instruction (format 0100 1110 0100 nnnn). - */ -static int opTRAP(Q68State *state, uint32_t opcode) -{ - return raise_exception(state, EX_TRAP + (opcode & 0x000F)); -} - -/*-----------------------------------------------------------------------*/ - -/** - * opLINK: LINK instruction (format 0100 1110 0101 0rrr). - */ -static int opLINK(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG0; - int16_t disp = IFETCH(state); -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_SP(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_WRITE); -#endif - JIT_EMIT_GET_OP1_REGISTER(current_entry, (8+reg0)*4); - JIT_EMIT_PUSH_L(current_entry); - JIT_EMIT_GET_OP1_REGISTER(current_entry, (8+7)*4); - JIT_EMIT_MOVE_L(current_entry); - JIT_EMIT_SET_REGISTER_L(current_entry, (8+reg0)*4); - JIT_EMIT_GET_OP2_IMMEDIATE(current_entry, disp); - JIT_EMIT_ADD_L(current_entry); - JIT_EMIT_SET_REGISTER_L(current_entry, (8+7)*4); - JIT_EMIT_ADD_CYCLES(current_entry, 16); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opUNLK: UNLK instruction (format 0100 1110 0101 1rrr). - */ -static int opUNLK(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG0; - JIT_EMIT_GET_OP1_REGISTER(current_entry, (8+reg0)*4); - JIT_EMIT_MOVE_L(current_entry); - JIT_EMIT_SET_REGISTER_L(current_entry, (8+7)*4); -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_SP(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_READ); -#endif - JIT_EMIT_POP_L(current_entry); - JIT_EMIT_SET_REGISTER_L(current_entry, (8+reg0)*4); - JIT_EMIT_ADD_CYCLES(current_entry, 12); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opMUSP: MOVE An,USP and MOVE USP,An instructions (format - * 0100 1110 0110 xrrr). - */ -static int opMUSP(Q68State *state, uint32_t opcode) -{ - JIT_EMIT_CHECK_SUPER(current_entry); - INSN_GET_REG0; - if (opcode & 0x0008) { - JIT_EMIT_MOVE_TO_USP(current_entry, reg0*4); - } else { - JIT_EMIT_MOVE_FROM_USP(current_entry, reg0*4); - } - JIT_EMIT_ADD_CYCLES(current_entry, 4); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * op4E7x: Instructions with opcodes $4E70-$4E77 that don't fit anywhere - * else. - */ -static int op4E7x(Q68State *state, uint32_t opcode) -{ - switch (opcode & 7) { - case 0: // $4E70 RESET - JIT_EMIT_CHECK_SUPER(current_entry); - JIT_EMIT_ADD_CYCLES(current_entry, 132); - return 0; - case 1: // $4E71 NOP - JIT_EMIT_ADD_CYCLES(current_entry, 4); - return 0; - case 2: // $4E72 STOP - JIT_EMIT_CHECK_SUPER(current_entry); - JIT_EMIT_ADD_CYCLES(current_entry, 4); - advance_PC(state); - JIT_EMIT_STOP(current_entry, IFETCH(state)); - return 1; - case 3: { // $4E73 RTE - JIT_EMIT_CHECK_SUPER(current_entry); -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_SP(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_READ); -#endif - JIT_EMIT_ADD_CYCLES(current_entry, 20); - JIT_EMIT_RTE(current_entry); - PC_updated = 1; - return 1; - } - case 5: // $4E75 RTS -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_SP(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_READ); -#endif - JIT_EMIT_ADD_CYCLES(current_entry, 16); - JIT_EMIT_RTS(current_entry); - PC_updated = 1; - return 1; - case 6: // $4E76 TRAPV - JIT_EMIT_TRAPV(current_entry); - JIT_EMIT_ADD_CYCLES(current_entry, 4); - return 0; - case 7: { // $4E77 RTR -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_SP(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_READ); -#endif - JIT_EMIT_ADD_CYCLES(current_entry, 20); - JIT_EMIT_RTR(current_entry); - PC_updated = 1; - return 1; - } - default: // $4E74 RTD is 68010 only - return op_ill(state, opcode); - } -} - -/*************************************************************************/ - -/** - * opjump: JSR and JMP instructions (format 0100 1110 1xxx xxxx). - */ -static int opjump(Q68State *state, uint32_t opcode) -{ - int is_jsr = ~opcode & 0x0040; - - /* JMP is essentially identical to LEA PC, and has the same - * constraints. JSR is equivalent to MOVE.L PC,-(A7) followed by a - * JMP to the address. Both use a separate timing table, however. */ - - int cycles; - switch (EA_MODE(opcode)) { - case EA_INDIRECT: - cycles = 8; - break; - case EA_DISPLACEMENT: - cycles = 10; - break; - case EA_INDEX: - cycles = 14; - break; - case EA_MISC: - switch (EA_REG(opcode)) { - case EA_MISC_ABSOLUTE_W: - cycles = 10; - break; - case EA_MISC_ABSOLUTE_L: - cycles = 12; - break; - case EA_MISC_PCREL: - cycles = 10; - break; - case EA_MISC_PCREL_INDEX: - cycles = 14; - break; - default: - return op_ill(state, opcode); - } - break; - default: - return op_ill(state, opcode); - } - if (is_jsr) { - cycles += 8; - } - JIT_EMIT_ADD_CYCLES(current_entry, cycles); - advance_PC(state); - - ea_resolve(state, opcode, SIZE_W, ACCESS_READ); // cannot fail - if (is_jsr) { -#ifndef Q68_DISABLE_ADDRESS_ERROR - JIT_EMIT_CHECK_ALIGNED_SP(current_entry, opcode, - FAULT_STATUS_IN_DATA | FAULT_STATUS_RW_WRITE); -#endif - JIT_EMIT_JSR(current_entry, jit_PC); - return 0; - } else { - JIT_EMIT_JMP(current_entry); - return 1; - } -} - -/*************************************************************************/ -/******************* Other miscellaneous instructions ********************/ -/*************************************************************************/ - -/** - * opMOVP: MOVEP instruction (0000 rrr1 xx00 1rrr). - */ -static int opMOVP(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_REG0; - int to_memory = opcode & 0x0080; - int is_long = opcode & 0x0040; - int16_t disp = IFETCH(state); - - if (to_memory) { - if (is_long) { - JIT_EMIT_MOVEP_WRITE_L(current_entry, reg0*4, disp, reg*4); - } else { - JIT_EMIT_MOVEP_WRITE_W(current_entry, reg0*4, disp, reg*4); - } - } else { - if (is_long) { - JIT_EMIT_MOVEP_READ_L(current_entry, reg0*4, disp, reg*4); - } else { - JIT_EMIT_MOVEP_READ_W(current_entry, reg0*4, disp, reg*4); - } - } - - JIT_EMIT_ADD_CYCLES(current_entry, is_long ? 24 : 16); - return 0; -} - -/*************************************************************************/ - -/** - * opADSX: ADDX/SUBX instructions (1x01 rrr1 ss00 xrrr). - */ -static int opADSX(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_SIZE; - INSN_GET_REG0; - const int is_add = opcode & 0x4000; - const int is_memory = opcode & 0x0008; - - const uint16_t src_ea = - (is_memory ? EA_PREDECREMENT : EA_DATA_REG) << 3 | reg0; - const uint16_t dest_ea = - (is_memory ? EA_PREDECREMENT : EA_DATA_REG) << 3 | reg; - int dummy; - ea_get(state, src_ea, size, 0, &dummy, 1); - ea_get(state, dest_ea, size, 1, &dummy, 2); - - const int do_cc = cc_needed(state, opcode); - if (is_add) { - if (size == SIZE_B) { - JIT_EMIT_ADDX_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADDX_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_ADDX_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADDX_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_ADDX_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_ADDX_L(current_entry); - } - } else { - if (size == SIZE_B) { - JIT_EMIT_SUBX_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUBX_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUBX_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUBX_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUBX_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_SUBX_L(current_entry); - } - } - - ea_set(state, dest_ea, size); - JIT_EMIT_ADD_CYCLES(current_entry, (is_memory ? (size==SIZE_L ? 30 : 18) - : (size==SIZE_L ? 8 : 4))); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * op_BCD: ABCD/SBCD instructions (1x00 rrr1 0000 xrrr). - */ -static int op_BCD(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_REG0; - const int is_add = opcode & 0x4000; - const int is_memory = opcode & 0x0008; - - const uint16_t src_ea = - (is_memory ? EA_PREDECREMENT : EA_DATA_REG) << 3 | reg0; - const uint16_t dest_ea = - (is_memory ? EA_PREDECREMENT : EA_DATA_REG) << 3 | reg; - int dummy; - ea_get(state, src_ea, SIZE_B, 0, &dummy, 1); - ea_get(state, dest_ea, SIZE_B, 1, &dummy, 2); - - if (is_add) { - JIT_EMIT_ABCD(current_entry); - } else { - JIT_EMIT_SBCD(current_entry); - } - - ea_set(state, dest_ea, SIZE_B); - JIT_EMIT_ADD_CYCLES(current_entry, is_memory ? 18 : 6); - return 0; -} - -/*-----------------------------------------------------------------------*/ - -/** - * opCMPM: CMPM instructions (1011 rrr1 ss00 1rrr). - */ -static int opCMPM(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_SIZE; - INSN_GET_REG0; - - const uint16_t src_ea = EA_POSTINCREMENT<<3 | reg0; - const uint16_t dest_ea = EA_POSTINCREMENT<<3 | reg; - int dummy; - ea_get(state, src_ea, size, 0, &dummy, 1); - ea_get(state, dest_ea, size, 0, &dummy, 2); - - const int do_cc = cc_needed(state, opcode); // Just for consistency - if (size == SIZE_B) { - JIT_EMIT_SUB_B(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_B(current_entry); - } else if (size == SIZE_W) { - JIT_EMIT_SUB_W(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_W(current_entry); - } else { // size == SIZE_L - JIT_EMIT_SUB_L(current_entry); - if (do_cc) JIT_EMIT_SETCC_CMP_L(current_entry); - } - - JIT_EMIT_ADD_CYCLES(current_entry, SIZE_L ? 20 : 12); - return 0; -} - -/*************************************************************************/ - -/** - * op_EXG: EXG instruction (1100 rrr1 xx00 1rrr). - */ -static int op_EXG(Q68State *state, uint32_t opcode) -{ - INSN_GET_REG; - INSN_GET_REG0; - const int mode = opcode & 0xF8; - - if (mode == 0x40) { - JIT_EMIT_EXG(current_entry, reg*4, reg0*4); - } else if (mode == 0x48) { - JIT_EMIT_EXG(current_entry, (8+reg)*4, (8+reg0)*4); - } else if (mode == 0x88) { - JIT_EMIT_EXG(current_entry, reg*4, (8+reg0)*4); - } else { - return op_ill(state, opcode); - } - JIT_EMIT_ADD_CYCLES(current_entry, 6); - return 0; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68-jit.h b/yabause/src/q68/q68-jit.h deleted file mode 100644 index e57885bf3f..0000000000 --- a/yabause/src/q68/q68-jit.h +++ /dev/null @@ -1,81 +0,0 @@ -/* src/q68/q68-jit.h: Dynamic translation header for Q68 - Copyright 2009 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef Q68_JIT_H -#define Q68_JIT_H - -/*************************************************************************/ - -/* Info structure for translated code blocks */ -struct Q68JitEntry_ { - Q68JitEntry *next, *prev; // Hash table collision chain pointers - Q68State *state; // Associated processor state block - uint32_t m68k_start; // Code start address in 68000 address space - // (zero indicates a free entry) - uint32_t m68k_end; // Code end address in 68000 address space - OpcodeFunc *native_code; // Pointer to native code - uint32_t native_length; // Length of native code (bytes) - uint32_t native_size; // Size of native code buffer (bytes) - void *exec_address; // Next execution address (NULL if not started) - uint32_t timestamp; // Time this entry was added - uint8_t running; // Nonzero if entry is currently running - uint8_t must_clear; // Nonzero if entry must be cleared on completion -}; - -/* Hash function */ -#define JIT_HASH(addr) ((uint32_t)(addr) % Q68_JIT_TABLE_SIZE) - -/*************************************************************************/ - -/** - * TIMESTAMP_COMPARE: Compare two timestamps. - * - * [Parameters] - * a, b: Timestamps to compare - * reference: Reference timestamp by which the comparison is made - * [Return value] - * -1 if a < b (i.e. "a is older than b") - * 0 if a == b - * 1 if a > b - */ -#ifdef __GNUC__ -__attribute__((const)) -#endif -static inline int TIMESTAMP_COMPARE(uint32_t reference, uint32_t a, uint32_t b) -{ - const uint32_t age_a = reference - a; - const uint32_t age_b = reference - b; - return age_a > age_b ? -1 : - age_a < age_b ? 1 : 0; -} - -/*************************************************************************/ - -#endif // Q68_JIT_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68.c b/yabause/src/q68/q68.c deleted file mode 100644 index 53125b8160..0000000000 --- a/yabause/src/q68/q68.c +++ /dev/null @@ -1,324 +0,0 @@ -/* src/q68/q68.c: Quick-and-dirty MC68000 emulator with dynamic - translation support - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include - -#include "q68.h" -#include "q68-internal.h" - -/*************************************************************************/ - -/* - * The source code for Q68 is divided into the following files: - * - * q68.c (this file) -- Main interface function definitions - * q68.h -------------- Interface definition (users should include this header) - * q68-const.h -------- 68000-related constants (status register bits, etc.) - * q68-core.c --------- Processor execution core - * q68-disasm.c ------- 68000 instruction disassembly and tracing support - * (for debugging) - * q68-internal.h ----- General definitions and declarations for internal use - * q68-jit.c ---------- Dynamic ("just-in-time") translation support - * q68-jit.h ---------- Declarations used only by the JIT code - * q68-jit-psp.[hS] --- JIT implementation for the PSP's Allegrex processor - * q68-jit-x86.[hS] --- JIT implementation for the Intel x86 architecture - * (both 32-bit and 64-bit environments supported) - */ - -/*************************************************************************/ -/*************************************************************************/ - -/** - * q68_create: Create a new virtual processor. The virtual processor is - * created uninitialized; before starting the processor, the caller must - * set the IRQ level and read/write callbacks, then call q68_reset(). - * - * [Parameters] - * None - * [Return value] - * Processor state block on success, NULL on error - */ -Q68State *q68_create(void) -{ - return q68_create_ex(malloc, realloc, free); -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_create_ex: Create a new virtual processor, using the specified - * functions for all memory allocation. - * - * [Parameters] - * malloc_func: Function for allocating a memory block - * realloc_func: Function for adjusting the size of a memory block - * free_func: Function for freeing a memory block - * [Return value] - * Processor state block on success, NULL on error - */ -Q68State *q68_create_ex(void *(*malloc_func)(size_t size), - void *(*realloc_func)(void *ptr, size_t size), - void (*free_func)(void *ptr)) -{ - Q68State *state; - - state = (*malloc_func)(sizeof(*state)); - if (!state) { - return NULL; - } - state->malloc_func = malloc_func; - state->realloc_func = realloc_func; - state->free_func = free_func; - -#ifdef Q68_USE_JIT - if (!q68_jit_init(state)) { - state->free_func(state); - return NULL; - } -#endif - - state->halted = Q68_HALTED_DOUBLE_FAULT; // Let's initialize this, at least - return state; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_destroy: Free all resources used by a virtual processor. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -void q68_destroy(Q68State *state) -{ -#ifdef Q68_USE_JIT - q68_jit_cleanup(state); -#endif - state->free_func(state); -} - -/*************************************************************************/ - -/** - * q68_set_irq: Set the interrupt request (IRQ) input to the processor. - * - * [Parameters] - * state: Processor state block - * irq: IRQ level (0-7) - * [Return value] - * None - */ -void q68_set_irq(Q68State *state, int irq) -{ - state->irq = irq & 7; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_set_{readb,readw,writeb,writew}_func: Set the read/write callback - * functions called by the virtual processor on memory accesses. - * - * For the read functions, only the lower 8 (readb) or 16 (readw) bits of - * the return value are used; the function does not need to sign-extend or - * zero-extend the value. Similarly, the value passed to the write - * functions will only have the low 8 (writeb) or 16 (writew) bits valid, - * and the function should ignore the upper bits of the value. - * - * For the word access functions (readw and writew), the address is - * guaranteed to be even, so the function does not need to check for this - * itself. (However, see the Q68_DISABLE_ADDRESS_ERROR configuration - * option in q68-internal.h.) - * - * [Parameters] - * state: Processor state block - * func: Callback function to set - * [Return value] - * None - */ -void q68_set_readb_func(Q68State *state, Q68ReadFunc func) -{ - state->readb_func = func; -} - -void q68_set_readw_func(Q68State *state, Q68ReadFunc func) -{ - state->readw_func = func; -} - -void q68_set_writeb_func(Q68State *state, Q68WriteFunc func) -{ - state->writeb_func = func; -} - -void q68_set_writew_func(Q68State *state, Q68WriteFunc func) -{ - state->writew_func = func; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_set_jit_flush_func: Set a function to be used to flush the native - * CPU's caches after a block of 68k code has been translated into native - * code. If not set, no cache flushing is performed. This function has no - * effect if dynamic translation is not enabled. - * - * [Parameters] - * state: Processor state block - * flush_func: Function for flushing the native CPU's caches (NULL if none) - * [Return value] - * None - */ -void q68_set_jit_flush_func(Q68State *state, void (*flush_func)(void)) -{ - state->jit_flush = flush_func; -} - -/*************************************************************************/ - -/** - * q68_get_{dreg,areg,pc,sr,usp,ssp}: Return the current value of the - * specified register. - * - * [Parameters] - * state: Processor state block - * num: Register number (q68_get_dreg() and q68_get_areg() only) - * [Return value] - * Register value - */ -uint32_t q68_get_dreg(const Q68State *state, int num) -{ - return state->D[num]; -} - -uint32_t q68_get_areg(const Q68State *state, int num) -{ - return state->A[num]; -} - -uint32_t q68_get_pc(const Q68State *state) -{ - return state->PC; -} - -uint16_t q68_get_sr(const Q68State *state) -{ - return state->SR; -} - -uint32_t q68_get_usp(const Q68State *state) -{ - return state->USP; -} - -uint32_t q68_get_ssp(const Q68State *state) -{ - return state->SSP; -} - -/*-----------------------------------------------------------------------*/ - -/** - * q68_set_{dreg,areg,pc,sr,usp,ssp}: Set the value of the specified - * register. - * - * [Parameters] - * state: Processor state block - * num: Register number (q68_set_dreg() and q68_set_areg() only) - * value: Value to set - * [Return value] - * None - */ -void q68_set_dreg(Q68State *state, int num, uint32_t value) -{ - state->D[num] = value; -} - -void q68_set_areg(Q68State *state, int num, uint32_t value) -{ - state->A[num] = value; -} - -void q68_set_pc(Q68State *state, uint32_t value) -{ - state->PC = value; -} - -void q68_set_sr(Q68State *state, uint16_t value) -{ - state->SR = value; -} - -void q68_set_usp(Q68State *state, uint32_t value) -{ - state->USP = value; -} - -void q68_set_ssp(Q68State *state, uint32_t value) -{ - state->SSP = value; -} - -/*************************************************************************/ - -/** - * q68_touch_memory: Clear any cached translations covering the given - * address range. Users should call this function whenever 68000-accessible - * memory is modified by an external agent. - * - * [Parameters] - * state: Processor state block - * address: 68000 address of modified data - * size: Size of modified data (in bytes) - * [Return value] - * None - */ -void q68_touch_memory(Q68State *state, uint32_t address, uint32_t size) -{ -#ifdef Q68_USE_JIT - const uint32_t first_page = address >> Q68_JIT_PAGE_BITS; - const uint32_t last_page = (address + (size-1)) >> Q68_JIT_PAGE_BITS; - uint32_t page; - for (page = first_page; page <= last_page; page++) { - if (UNLIKELY(JIT_PAGE_TEST(state, page))) { - q68_jit_clear_page(state, page << Q68_JIT_PAGE_BITS); - } - } -#endif -} - -/*************************************************************************/ -/*************************************************************************/ - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/q68/q68.h b/yabause/src/q68/q68.h deleted file mode 100644 index fa4af2c254..0000000000 --- a/yabause/src/q68/q68.h +++ /dev/null @@ -1,295 +0,0 @@ -/* src/q68/q68.h: Q68 main header - Copyright 2009-2010 Andrew Church - - This file is part of Yabause. - - Yabause is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - Yabause is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Yabause; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef Q68_H -#define Q68_H - -#include -#include - -/*************************************************************************/ -/****************** Exported definitions and data types ******************/ -/*************************************************************************/ - -/* Memory read/write function types. The size of the operation is not - * specified here, but is rather determined by which callback the function - * is assigned to. */ - -/** - * Q68ReadFunc: Read data from memory. - * - * [Parameters] - * address: Address to read from - * [Return value] - * Value read (zero-extended to 32 bits) - */ -typedef uint32_t Q68ReadFunc(uint32_t address); - -/** - * Q68WriteFunc: Write data to memory. - * - * [Parameters] - * address: Address to write to - * data: Value to write - * [Return value] - * None - */ -typedef void Q68WriteFunc(uint32_t address, uint32_t data); - -/*************************************************************************/ - -/* Virtual processor state (opaque) */ - -typedef struct Q68State_ Q68State; - -/*************************************************************************/ -/************************** Emulator interface ***************************/ -/*************************************************************************/ - -/** - * q68_create: Create a new virtual processor. The virtual processor is - * created uninitialized; before starting the processor, the caller must - * set the IRQ level and read/write callbacks, then call q68_reset(). - * - * [Parameters] - * None - * [Return value] - * Processor state block on success, NULL on error - */ -extern Q68State *q68_create(void); - -/** - * q68_create_ex: Create a new virtual processor, using the specified - * functions for all memory allocation. - * - * [Parameters] - * malloc_func: Function for allocating a memory block - * realloc_func: Function for adjusting the size of a memory block - * free_func: Function for freeing a memory block - * [Return value] - * Processor state block on success, NULL on error - */ -extern Q68State *q68_create_ex(void *(*malloc_func)(size_t size), - void *(*realloc_func)(void *ptr, size_t size), - void (*free_func)(void *ptr)); - -/** - * q68_destroy: Free all resources used by a virtual processor. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -extern void q68_destroy(Q68State *state); - -/*----------------------------------*/ - -/** - * q68_set_irq: Set the interrupt request (IRQ) input to the processor. - * - * [Parameters] - * state: Processor state block - * irq: IRQ level (0-7) - * [Return value] - * None - */ -extern void q68_set_irq(Q68State *state, int irq); - -/** - * q68_set_{readb,readw,writeb,writew}_func: Set the read/write callback - * functions called by the virtual processor on memory accesses. - * - * For the read functions, only the lower 8 (readb) or 16 (readw) bits of - * the return value are used; the function does not need to sign-extend or - * zero-extend the value. Similarly, the value passed to the write - * functions will only have the low 8 (writeb) or 16 (writew) bits valid, - * and the function should ignore the upper bits of the value. - * - * For the word access functions (readw and writew), the address is - * guaranteed to be even, so the function does not need to check for this - * itself. (However, see the Q68_DISABLE_ADDRESS_ERROR configuration - * option in q68-internal.h.) - * - * [Parameters] - * state: Processor state block - * func: Callback function to set - * [Return value] - * None - */ -extern void q68_set_readb_func(Q68State *state, Q68ReadFunc func); -extern void q68_set_readw_func(Q68State *state, Q68ReadFunc func); -extern void q68_set_writeb_func(Q68State *state, Q68WriteFunc func); -extern void q68_set_writew_func(Q68State *state, Q68WriteFunc func); - -/** - * q68_set_jit_flush_func: Set a function to be used to flush the native - * CPU's caches after a block of 68k code has been translated into native - * code. If not set, no cache flushing is performed. This function has no - * effect if dynamic translation is not enabled. - * - * [Parameters] - * state: Processor state block - * flush_func: Function for flushing the native CPU's caches (NULL if none) - * [Return value] - * None - */ -extern void q68_set_jit_flush_func(Q68State *state, void (*flush_func)(void)); - -/*----------------------------------*/ - -/** - * q68_get_{dreg,areg,pc,sr,usp,ssp}: Return the current value of the - * specified register. - * - * [Parameters] - * state: Processor state block - * num: Register number (q68_get_dreg() and q68_get_areg() only) - * [Return value] - * Register value - */ -extern uint32_t q68_get_dreg(const Q68State *state, int num); -extern uint32_t q68_get_areg(const Q68State *state, int num); -extern uint32_t q68_get_pc(const Q68State *state); -extern uint16_t q68_get_sr(const Q68State *state); -extern uint32_t q68_get_usp(const Q68State *state); -extern uint32_t q68_get_ssp(const Q68State *state); - -/** - * q68_set_{dreg,areg,pc,sr,usp,ssp}: Set the value of the specified - * register. - * - * [Parameters] - * state: Processor state block - * num: Register number (q68_set_dreg() and q68_set_areg() only) - * value: Value to set - * [Return value] - * None - */ -extern void q68_set_dreg(Q68State *state, int num, uint32_t value); -extern void q68_set_areg(Q68State *state, int num, uint32_t value); -extern void q68_set_pc(Q68State *state, uint32_t value); -extern void q68_set_sr(Q68State *state, uint16_t value); -extern void q68_set_usp(Q68State *state, uint32_t value); -extern void q68_set_ssp(Q68State *state, uint32_t value); - -/*----------------------------------*/ - -/** - * q68_touch_memory: Clear any cached translations covering the given - * address range. Users should call this function whenever 68000-accessible - * memory is modified by an external agent. - * - * [Parameters] - * state: Processor state block - * address: 68000 address of modified data - * size: Size of modified data (in bytes) - * [Return value] - * None - */ -extern void q68_touch_memory(Q68State *state, uint32_t address, uint32_t size); - -/*-----------------------------------------------------------------------*/ - -/** - * q68_reset: Reset the virtual processor. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -extern void q68_reset(Q68State *state); - -/** - * q68_run: Execute instructions for the given number of clock cycles. - * - * [Parameters] - * state: Processor state block - * cycles: Number of clock cycles to execute - * [Return value] - * Number of clock cycles executed (may be greater than "cycles") - */ -extern int q68_run(Q68State *state, int cycles); - -/*-----------------------------------------------------------------------*/ - -/** - * q68_disassemble: Disassemble the instruction at the given address. - * Returns "???" if the address or opcode is invalid. - * - * [Parameters] - * state: Processor state block - * address: Address of instruction to disassemble - * [Return value] - * String containined disassembled instruction - * [Notes] - * The returned string is only valid until the next call to this function. - */ -extern const char *q68_disassemble(Q68State *state, uint32_t address, - int *nwords_ret); - -/*----------------------------------*/ - -/** - * q68_trace_init: Initialize the tracing code. - * - * [Parameters] - * state: Processor state block - * [Return value] - * None - */ -extern void q68_trace_init(Q68State *state_); - -/** - * q68_trace_add_cycles: Add the given number of cycles to the global - * accumulator. - * - * [Parameters] - * cycles: Number of cycles to add - * [Return value] - * None - */ -extern void q68_trace_add_cycles(int32_t cycles); - -/** - * q68_trace: Output a trace for the instruction at the current PC. - * - * [Parameters] - * None - * [Return value] - * None - */ -extern void q68_trace(void); - -/*************************************************************************/ -/*************************************************************************/ - -#endif // Q68_H - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/yabause/src/qt/Arguments.cpp b/yabause/src/qt/Arguments.cpp deleted file mode 100644 index f92a757ea2..0000000000 --- a/yabause/src/qt/Arguments.cpp +++ /dev/null @@ -1,209 +0,0 @@ -#include "Arguments.h" -#include "VolatileSettings.h" -#include "QtYabause.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace Arguments -{ - - void autoframeskip(const QString& param); - void autoload(const QString& param); - void autostart(const QString& param); - void binary(const QString& param); - void bios(const QString& param); - void cdrom(const QString& param); - void fullscreen(const QString& param); - void help(const QString& param); - void iso(const QString& param); - void nobios(const QString& param); - void nosound(const QString& param); - void version(const QString& param); - - struct Option - { - const char * shortname; - const char * longname; - const char * parameter; - const char * description; - unsigned short priority; - void (*callback)(const QString& param); - }; - - static Option LAST_OPTION = { NULL, NULL, NULL, NULL, 0 }; - - static Option availableOptions[] = - { - { NULL, "--autoframeskip=", "0|1", "Enable or disable auto frame skipping / limiting.", 2, autoframeskip }, - { NULL, "--autoload=", "", "Automatically start emulation and load a save state.",1, autoload }, - { "-a", "--autostart", NULL, "Automatically start emulation.", 1, autostart }, - { NULL, "--binary=", "[:ADDRESS]", "Use a binary file.", 1, binary }, - { "-b", "--bios=", "", "Choose a bios file.", 3, bios }, - { "-c", "--cdrom=", "", "Choose the cdrom device.", 4, cdrom }, - { "-f", "--fullscreen", NULL, "Start the emulator in fullscreen.", 5, fullscreen }, - { "-h", "--help", NULL, "Show this help and exit.", 0, help }, - { "-i", "--iso=", "", "Choose a dump file.", 4, iso }, - { "-nb", "--no-bios", NULL, "Use the emulated bios", 3, nobios }, - { "-ns", "--no-sound", NULL, "Turns sound off.", 6, nosound }, - { "-v", "--version", NULL, "Show version and exit.", 0, version }, - LAST_OPTION - }; - - void parse() - { - QVector